Index: autobuild_for_customer =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/autobuild_for_customer,v retrieving revision 1.1 retrieving revision 1.6 diff -u -r1.1 -r1.6 --- autobuild_for_customer 22 Jul 2004 19:48:47 -0000 1.1 +++ autobuild_for_customer 30 Dec 2004 22:01:53 -0000 1.6 @@ -14,14 +14,18 @@ make oldconfig make dep make zImage - mkdir autobuilt_customer/"$1" - cp vmlin* autobuilt_customer/"$1" - ls -lah autobuilt_customer/"$1" + make modules + mkdir -p /tmp/autobuilt_customer/"$1" + INSTALL_MOD_PATH=/tmp/autobuilt_customer/"$1" make modules_install + cp vmlin* /tmp/autobuilt_customer/"$1" + cp arch/arm/boot/zImage /tmp/autobuilt_customer/"$1" + ls -lah /tmp/autobuilt_customer/"$1" } -rm -rf autobuilt_customer -mkdir autobuilt_customer +rm -rf /tmp/autobuilt_customer +mkdir /tmp/autobuilt_customer -build_a_config ep9312 +build_a_config ts7200 +build_a_config ts7250 echo "Done" Index: autobuild_for_customer_9301 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/autobuild_for_customer_9301,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- autobuild_for_customer_9301 22 Jul 2004 19:48:47 -0000 1.1 +++ autobuild_for_customer_9301 4 Aug 2004 01:33:00 -0000 1.2 @@ -14,7 +14,6 @@ make oldconfig make dep make zImage - make bzImage mkdir autobuilt_customer/"$1" cp vmlin* autobuilt_customer/"$1" ls -lah autobuilt_customer/"$1" @@ -23,6 +22,6 @@ rm -rf autobuilt_customer mkdir autobuilt_customer -build_a_config ep9301_nfs +build_a_config ep9301 echo "Done" Index: CREDITS =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/CREDITS,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- CREDITS 22 Jul 2004 19:48:47 -0000 1.1 +++ CREDITS 4 Aug 2004 01:33:00 -0000 1.2 @@ -83,13 +83,13 @@ S: USA N: Erik Andersen -E: andersee@debian.org -W: http://www.xmission.com/~andersen -P: 1024/FC4CFFED 78 3C 6A 19 FA 5D 92 5A FB AC 7B A5 A5 E1 FF 8E +E: andersen@codepoet.org +W: http://www.codepoet.org/ +P: 1024D/30D39057 1BC4 2742 E885 E4DE 9301 0C82 5F9B 643E 30D3 9057 D: Maintainer of ide-cd and Uniform CD-ROM driver, D: ATAPI CD-Changer support, Major 2.1.x CD-ROM update. -S: 4538 South Carnegie Tech Street -S: Salt Lake City, Utah 84120 +S: 352 North 525 East +S: Springville, Utah 84663 S: USA N: Michael Ang @@ -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<<. @@ -850,8 +848,8 @@ W: http://www.pi.se/blox/ D: Extended support for loadable modules D: D-Link pocket adapter drivers -S: Grevgatan 11 -S: S-114 53 Stockholm +S: Brevia 1043 +S: S-114 79 Stockholm S: Sweden N: Michael Engel @@ -1240,14 +1238,13 @@ N: Christoph Hellwig E: hch@infradead.org -E: hch@sgi.com D: all kinds of driver, filesystem & core kernel hacking D: freevxfs driver D: sysvfs maintainer D: chief codingstyle nitpicker -S: Auweg 38 -S: 85748 Garching -S: Germany +S: Ampferstr. 50 / 4 +S: 6020 Innsbruck +S: Austria N: Richard Henderson E: rth@twiddle.net @@ -1348,7 +1345,10 @@ N: Marcel Holtmann E: marcel@holtmann.org W: http://www.holtmann.org -D: Author of the Linux Bluetooth Subsystem PC Card drivers +D: Maintainer of the Linux Bluetooth Subsystem +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 @@ -1860,6 +1872,12 @@ S: Niwot, Colorado 80503 S: USA +N: Pete Popov +E: pete_popov@yahoo.com +D: Linux/MIPS AMD/Alchemy Port and mips hacking and debugging +S: San Jose, CA 95134 +S: USA + N: Robert M. Love E: rml@tech9.net E: rml@ufl.edu @@ -1929,7 +1947,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 +2166,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 @@ -2185,6 +2214,15 @@ E: wolfgang@iksw-muees.de D: Auerswald USB driver +N: Paul Mundt +E: lethal@linux-sh.org +P: 1024D/917167DC 563C FC60 83BB A3EE D816 E60D D4AF AD78 9171 67DC +D: Linux/SH and Linux/sh64 +D: Occasional MIPS hacker +D: fbdev hacker +S: Hamilton, Ontario +S: Canada + N: Ian A. Murdock E: imurdock@gnu.ai.mit.edu D: Creator of Debian distribution @@ -2559,6 +2597,13 @@ S: Tucson, Arizona S: USA +N: Luca Risolia +E: luca.risolia@studio.unibo.it +D: V4L driver for W996[87]CF JPEG USB Dual Mode Camera Chips +S: Via Liberta' 41-A +S: Osio Sotto, 24046, Bergamo +S: Italy + N: William E. Roadcap E: roadcapw@cfw.com W: http://www.cfw.com/~roadcapw @@ -2624,6 +2669,7 @@ N: Aristeu Sergio Rozanski Filho E: aris@conectiva.com.br D: Support for EtherExpress 10 ISA (i82595) in eepro driver +D: User level driver support for input S: Conectiva S.A. S: R. Tocantins, 89 - Cristo Rei S: 80050-430 - Curitiba - Paraná @@ -2687,6 +2733,14 @@ E: gt8134b@prism.gatech.edu D: Dosemu +N: Duncan Sands +E: duncan.sands@free.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. @@ -2936,12 +2990,11 @@ S: USA N: Marcelo W. Tosatti -E: marcelo@conectiva.com.br -W: http://bazar.conectiva.com.br/~marcelo/ +E: marcelo.tosatti@cyclades.com D: Miscellaneous kernel hacker (mostly VM/MM work) -S: Conectiva S.A. -S: R. Tocantins, 89 - Cristo Rei -S: 80050-430 - Curitiba - Paraná +D: 2.4 maintainer +S: Av Cristovao Colombo, 462. Floresta. +S: Porto Alegre S: Brazil N: Stefan Traby @@ -3062,7 +3115,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 +3124,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 +3380,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, Keio University +S: Jeunet Palace Kawasaki #1-201, 10-2, Furukawa-cho, Saiwai-ku +S: Kawasaki, Kanagawa 212-0025 +S: Japan + N: Eric Youngdale E: eric@andante.org W: http://www.andante.org @@ -3390,4 +3454,4 @@ # alphabetically. Leonard used to be very proud of being the # last entry, and he'll get positively pissed if he can't even # be second-to-last. (and this file really _is_ supposed to be -# in alphabetic order) +# in alphabetic order) Index: MAINTAINERS =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/MAINTAINERS,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- MAINTAINERS 22 Jul 2004 19:48:47 -0000 1.1 +++ MAINTAINERS 4 Aug 2004 01:33:00 -0000 1.2 @@ -73,17 +73,11 @@ 3C359 NETWORK DRIVER P: Mike Phillips M: mikep@linuxtr.net -L: linux-net@vger.rutgers.edu +L: linux-net@vger.kernel.org L: linux-tr@linuxtr.net 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 @@ -169,10 +163,10 @@ S: Supported ACPI -P: Andy Grover -M: andrew.grover@intel.com +P: Len Brown +M: len.brown@intel.com L: acpi-devel@lists.sourceforge.net -W: http://sf.net/projects/acpi/ +W: http://acpi.sourceforge.net/ S: Maintained AD1816 SOUND DRIVER @@ -206,6 +200,21 @@ L: linux-scsi@vger.kernel.org S: Maintained +ALCATEL SPEEDTOUCH USB DRIVER +P: Duncan Sands +M: duncan.sands@free.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 @@ -247,6 +256,8 @@ ARM/STRONGARM110 PORT P: Russell King M: rmk@arm.linux.org.uk +P: Vincent Sanders +M: vince@arm.linux.org.uk L: linux-arm-kernel@lists.arm.linux.org.uk W: http://www.arm.linux.org.uk/ S: Maintained @@ -257,6 +268,16 @@ L: linux-net@vger.kernel.org S: Maintained +ASUS ACPI EXTRAS DRIVER +P: Karol Kozimor +M: sziwan@users.sourceforge.net +P: Julien Lerouge +M: julien.lerouge@free.fr +L: acpi4asus-user@lists.sourceforge.net +W: http://sourceforge.net/projects/acpi4asus +W: http://julien.lerouge.free.fr +S: Maintained + ATM P: Chas Williams M: chas@cmf.nrl.navy.mil @@ -302,18 +323,89 @@ L: linux-kernel@vger.kernel.org S: Maintained -BLUETOOTH SUBSYSTEM (BlueZ) +BLUETOOTH SUBSYSTEM +P: Marcel Holtmann +M: marcel@holtmann.org +P: Maxim Krasnyansky +M: maxk@qualcomm.com +L: bluez-devel@lists.sf.net +W: http://bluez.sf.net +S: Maintained + +BLUETOOTH RFCOMM LAYER +P: Marcel Holtmann +M: marcel@holtmann.org +P: Maxim Krasnyansky +M: maxk@qualcomm.com +W: http://bluez.sf.net +S: Maintained + +BLUETOOTH BNEP LAYER +P: Marcel Holtmann +M: marcel@holtmann.org +P: Maxim Krasnyansky +M: maxk@qualcomm.com +W: http://bluez.sf.net +S: Maintained + +BLUETOOTH CMTP LAYER +P: Marcel Holtmann +M: marcel@holtmann.org +W: http://www.holtmann.org/linux/bluetooth/ +S: Maintained + +BLUETOOTH HCI USB DRIVER +P: Marcel Holtmann +M: marcel@holtmann.org +P: Maxim Krasnyansky +M: maxk@qualcomm.com +W: http://bluez.sf.net +S: Maintained + +BLUETOOTH HCI UART DRIVER +P: Marcel Holtmann +M: marcel@holtmann.org P: Maxim Krasnyansky M: maxk@qualcomm.com W: http://bluez.sf.net S: Maintained -BLUETOOTH SUBSYSTEM (PC Card Drivers) +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 @@ -351,26 +443,30 @@ W: http://www.coda.cs.cmu.edu/ S: Maintained -HP (was COMPAQ) FIBRE CHANNEL 64-bit/66MHz PCI non-intelligent HBA -P: Stephen Cameron -M: arrays@hp.com -M: steve.cameron@hp.com -L: cpqfc-discuss@lists.sourceforge.net +HP FIBRE CHANNEL 64-bit/66MHz PCI non-intelligent HBA +P: Chase Maupin +M: chase.maupin@hp.com +L: iss_storagedev@hp.com S: Odd Fixes -HP (was COMPAQ) SMART2 RAID DRIVER -P: Stephen Cameron -M: arrays@hp.com -M: steve.cameron@hp.com -L: cpqarray-discuss@lists.sourceforge.net +HP OMNIBOOK 600 C/CT POP-UP MOUSE DRIVER +P: Grant Grundler +M: grundler@parisc-linux.org +L: omnibook@zurich.ai.mit.edu +S: Maintained + + +HP SMART2 RAID DRIVER +P: Francis Wiran +M: francis.wiran@hp.com +L: iss_storagedev@hp.com S: Odd Fixes -HP (was COMPAQ) SMART CISS RAID DRIVER -P: Stephen Cameron -M: arrays@hp.com -M: steve.cameron@hp.com -L: cciss-discuss@lists.sourceforge.net -S: Supported +HP SMART CISS RAID DRIVER +P: Mike Miller, Michael Ni +M: mike.miller@hp.com +L: iss_storagedev@hp.com +S: Supported COMPUTONE INTELLIPORT MULTIPORT CARD P: Michael H. Warfield @@ -381,8 +477,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 +526,23 @@ 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 +MARVELL YUKON / SYSKONNECT DRIVER +P: Mirko Lindner +M: mlindner@syskonnect.de +P: Ralph Roesler +M: rroesler@syskonnect.de +W: http://www.syskonnect.com +S: Supported +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 @@ -592,7 +705,7 @@ ETHERNET BRIDGE P: Stephen Hemminger M: shemminger@osdl.org -L: bridge@math.leidenuniv.nl +L: bridge@osdl.org W: http://bridge.sourceforge.net/ S: Maintained @@ -676,8 +789,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 @@ -712,13 +825,11 @@ W: http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi S: Maintained -I2C DRIVERS -P: Simon Vogl -M: simon@tk.uni-linz.ac.at -P: Frodo Looijaard -M: frodol@dds.nl -L: linux-i2c@pelican.tk.uni-linz.ac.at -W: http://www.tk.uni-linz.ac.at/~simon/private/i2c +I2C SUBSYSTEM +P: Jean Delvare +M: khali@linux-fr.org +L: sensors@stimpy.netroedge.com +W: http://www.lm-sensors.nu/ S: Maintained i386 BOOT CODE @@ -825,7 +936,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 @@ -862,10 +973,15 @@ IOC3 DRIVER P: Ralf Baechle -M: ralf@oss.sgi.com +M: ralf@linux-mips.org L: linux-mips@linux-mips.org S: Maintained +IOC4 IDE DRIVER +P: Jeremy Higdon +M: jeremy@sgi.com +S: Maintained + IP MASQUERADING: P: Juanjo Ciarlante M: jjciarla@raiz.uncu.edu.ar @@ -967,8 +1083,8 @@ P: Andrew Stanley-Jones M: asj@lanmedia.com W: http://www.lanmedia.com/ -S: Supported - +S: Orphan + LAPB module P: Henner Eisen M: eis@baty.hanse.de @@ -1052,6 +1168,13 @@ M: zab@zabbo.net S: Odd Fixes +MARVELL MV64340 ETHERNET DRIVER +P: Manish Lachwani +M: Manish_Lachwani@pmc-sierra.com +L: linux-mips@linux-mips.org +L: netdev@oss.sgi.com +S: Supported + MATROX FRAMEBUFFER DRIVER P: Petr Vandrovec M: vandrove@vc.cvut.cz @@ -1073,7 +1196,7 @@ MIPS P: Ralf Baechle -M: ralf@gnu.org +M: ralf@linux-mips.org W: http://oss.sgi.com/mips/mips-howto.html L: linux-mips@linux-mips.org S: Maintained @@ -1136,7 +1259,7 @@ L: linux-scsi@vger.kernel.org S: Maintained -NETFILTER/IPTABLES +NETFILTER/IPTABLES/IPCHAINS P: Rusty Russell P: Marc Boucher P: James Morris @@ -1183,6 +1306,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 @@ -1245,8 +1370,8 @@ ONSTREAM SCSI TAPE DRIVER P: Willem Riede M: osst@riede.org -L: osst@linux1.onstream.nl -L: linux-scsi@vger.rutgers.edu +L: osst-users@lists.sourceforge.net +L: linux-scsi@vger.kernel.org S: Maintained OPL3-SA2, SA3, and SAx DRIVER @@ -1333,9 +1458,9 @@ PERMEDIA 3 FRAMEBUFFER DRIVER P: Romain Dolbeau -M: dolbeau@irisa.fr +M: dolbeau@caps-entreprise.com L: linux-fbdev-devel@lists.sourceforge.net -W: http://www.irisa.fr/prive/dolbeau/pm3fb/pm3fb.html +W: http://www.caps-entreprise.com/private/dolbeau/pm3fb/pm3fb.html S: Maintained PHILIPS NINO PALM PC @@ -1364,9 +1489,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 +1525,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,10 +1624,16 @@ 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 +SCTP PROTOCOL +P: Sridhar Samudrala +M: sri@us.ibm.com +L: lksctp-developers@lists.sourceforge.net +S: Supported + SCx200 CPU SUPPORT P: Christer Weinigel M: christer@weinigel.se @@ -1569,11 +1700,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 @@ -1588,8 +1714,10 @@ S: Maintained SPARC (sparc32): +P: Keith M. Wesolowski +M: wesolows@foobazco.org L: sparclinux@vger.kernel.org -S: Unmaintained - please send patches to mailing list +S: Maintained SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER P: Roger Wolff @@ -1631,19 +1759,33 @@ 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 +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 @@ -1654,12 +1796,6 @@ L: linux-video@atrey.karlin.mff.cuni.cz S: Maintained -SYSKONNECT DRIVER -P: Mirko Lindner -M: mlindner@syskonnect.de -W: http://www.syskonnect.com -S: Supported - SYSV FILESYSTEM P: Christoph Hellwig M: hch@infradead.org @@ -1706,6 +1842,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 +1925,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 @@ -1933,8 +2075,8 @@ S: Maintained USB SUBSYSTEM -P: Greg Kroah-Hartman -M: greg@kroah.com +P: Pete Zaitcev +M: zaitcev@redhat.com L: linux-usb-users@lists.sourceforge.net L: linux-usb-devel@lists.sourceforge.net W: http://www.linux-usb.org @@ -1954,6 +2096,13 @@ L: linux-usb-devel@lists.sourceforge.net S: Maintained +USB W9968CF DRIVER +P: Luca Risolia +M: luca.risolia@studio.unibo.it +L: linux-usb-devel@lists.sourceforge.net +W: http://go.lamarinapunto.com +S: Maintained + VFAT FILESYSTEM: P: Gordon Chaffee M: chaffee@cs.berkeley.edu @@ -1963,7 +2112,6 @@ VIA 82Cxxx AUDIO DRIVER P: Jeff Garzik -L: linux-via@gtf.org S: Odd fixes VIA RHINE NETWORK DRIVER @@ -1971,6 +2119,11 @@ M: rl@hellgate.ch S: Maintained +VIA-IRCC IRDA DRIVER +P: Jens David +M: dg1kjd@afthd.tu-darmstadt.de +S: Maintained + USB DIAMOND RIO500 DRIVER P: Cesar Miquel M: miquel@df.uba.ar @@ -2008,6 +2161,14 @@ L: linux-x25@vger.kernel.org S: Maintained +XFS FILESYSTEM +P: Silicon Graphics Inc +M: owner-xfs@oss.sgi.com +M: nathans@sgi.com +L: linux-xfs@oss.sgi.com +W: http://oss.sgi.com/projects/xfs +S: Supported + X86 3-LEVEL PAGING (PAE) SUPPORT P: Ingo Molnar M: mingo@redhat.com @@ -2032,12 +2193,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 Index: Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Makefile,v retrieving revision 1.1 retrieving revision 1.19 diff -u -r1.1 -r1.19 --- Makefile 22 Jul 2004 19:48:47 -0000 1.1 +++ Makefile 23 May 2006 17:16:43 -0000 1.19 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 -SUBLEVEL = 21 -EXTRAVERSION =-rmk1-cirrus-1-2-1 +SUBLEVEL = 26 +EXTRAVERSION =-ts11 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) @@ -17,10 +17,8 @@ FINDHPATH = $(HPATH)/asm $(HPATH)/linux $(HPATH)/scsi $(HPATH)/net $(HPATH)/math-emu HOSTCC = gcc -HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer - -CROSS_COMPILE = arm-unknown-linux-gnu- - +HOSTCFLAGS = -Wall -Wstrict-prototypes -Os -fomit-frame-pointer +CROSS_COMPILE = $(shell cd $(TOPDIR)/../../tools/crosstool/arm-9tdmi-linux-gnu/gcc-3.3.4-glibc-2.3.2/bin/ && pwd)/arm-9tdmi-linux-gnu- # # Include the make variables (CC, etc...) # @@ -40,10 +38,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 +126,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-$(CONFIG_I2C) += drivers/i2c/i2c.o DRIVERS-$(CONFIG_L3) += drivers/l3/l3.o @@ -165,6 +166,7 @@ DRIVERS-$(CONFIG_SOUND) += drivers/sound/sounddrivers.o DRIVERS-$(CONFIG_PCI) += drivers/pci/driver.o DRIVERS-$(CONFIG_MTD) += drivers/mtd/mtdlink.o +DRIVERS-$(CONFIG_MTD2K) += drivers/mtd2k/mtdlink.o DRIVERS-$(CONFIG_PCMCIA) += drivers/pcmcia/pcmcia.o DRIVERS-$(CONFIG_NET_PCMCIA) += drivers/net/pcmcia/pcmcia_net.o DRIVERS-$(CONFIG_NET_WIRELESS) += drivers/net/wireless/wireless_net.o @@ -176,12 +178,12 @@ DRIVERS-$(CONFIG_PPC32) += drivers/macintosh/macintosh.o DRIVERS-$(CONFIG_MAC) += drivers/macintosh/macintosh.o DRIVERS-$(CONFIG_ISAPNP) += drivers/pnp/pnp.o -DRIVERS-$(CONFIG_SGI_IP22) += drivers/sgi/sgi.a DRIVERS-$(CONFIG_VT) += drivers/video/video.o DRIVERS-$(CONFIG_PARIDE) += drivers/block/paride/paride.a DRIVERS-$(CONFIG_HAMRADIO) += drivers/net/hamradio/hamradio.o DRIVERS-$(CONFIG_TC) += drivers/tc/tc.a DRIVERS-$(CONFIG_USB) += drivers/usb/usbdrv.o +DRIVERS-$(CONFIG_USB_GADGET) += drivers/usb/gadget/built-in.o DRIVERS-y +=drivers/media/media.o DRIVERS-$(CONFIG_INPUT) += drivers/input/inputdrv.o DRIVERS-$(CONFIG_HIL) += drivers/hil/hil.o @@ -193,6 +195,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-$(CONFIG_PLD) += drivers/pld/pld.o DRIVERS-$(CONFIG_ARCH_AT91RM9200) += drivers/at91/at91drv.o @@ -221,9 +224,11 @@ drivers/scsi/aic7xxx/aicasm/aicdb.h \ drivers/scsi/aic7xxx/aicasm/y.tab.h \ drivers/scsi/53c700_d.h \ + drivers/tc/lk201-map.c \ net/khttpd/make_times_h \ net/khttpd/times.h \ - submenu* + submenu* \ + drivers/ieee1394/oui.c # directories removed with 'make clean' CLEAN_DIRS = \ modules @@ -231,6 +236,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 \ @@ -297,7 +303,7 @@ mkdir include/linux/modules; \ fi -oldconfig: symlinks +oldconfig: symlinks include/linux/version.h $(CONFIG_SHELL) scripts/Configure -d arch/$(ARCH)/config.in xconfig: symlinks @@ -494,7 +500,7 @@ ifdef CONFIG_MODVERSIONS $(MAKE) update-modverfile endif - scripts/mkdep -- `find $(FINDHPATH) \( -name SCCS -o -name .svn \) -prune -o -follow -name \*.h ! -name modversions.h -print` > .hdepend + (find $(FINDHPATH) \( -name SCCS -o -name .svn \) -prune -o -follow -name \*.h ! -name modversions.h -print | xargs -r scripts/mkdep -- ) > .hdepend scripts/mkdep -- init/*.c > .depend ifdef CONFIG_MODVERSIONS @@ -571,5 +577,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 Index: README =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/README,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- README 22 Jul 2004 19:48:47 -0000 1.1 +++ README 4 Aug 2004 01:33:00 -0000 1.2 @@ -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 Index: Rules.make =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Rules.make,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Rules.make 22 Jul 2004 19:48:47 -0000 1.1 +++ Rules.make 4 Aug 2004 01:33:00 -0000 1.2 @@ -96,12 +96,12 @@ $(O_TARGET): $(obj-y) rm -f $@ ifneq "$(strip $(obj-y))" "" - $(LD) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(obj-y), $^) + $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(obj-y), $^) else $(AR) rcs $@ endif @ ( \ - echo 'ifeq ($(strip $(subst $(comma),:,$(EXTRA_LDFLAGS) $(obj-y))),$$(strip $$(subst $$(comma),:,$$(EXTRA_LDFLAGS) $$(obj-y))))' ; \ + echo 'ifeq ($(strip $(subst $(comma),:,$(LDFLAGS) $(EXTRA_LDFLAGS) $(obj-y))),$$(strip $$(subst $$(comma),:,$$(LDFLAGS) $$(EXTRA_LDFLAGS) $$(obj-y))))' ; \ echo 'FILES_FLAGS_UP_TO_DATE += $@' ; \ echo 'endif' \ ) > $(dir $@)/.$(notdir $@).flags Index: arch/alpha/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/Makefile 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/alpha/Makefile 4 Aug 2004 01:25:35 -0000 1.2 @@ -131,3 +131,6 @@ bootpfile: @$(MAKEBOOT) bootpfile + +bootpzfile: + @$(MAKEBOOT) bootpzfile Index: arch/alpha/config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/config.in 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/alpha/config.in 4 Aug 2004 01:25:35 -0000 1.2 @@ -43,6 +43,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 \ @@ -158,6 +159,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 @@ -217,7 +228,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 @@ -235,7 +246,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 @@ -251,13 +262,15 @@ 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 if [ "$CONFIG_SMP" = "y" ]; then define_bool CONFIG_HAVE_DEC_LOCK y + int 'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32 fi if [ "$CONFIG_ALPHA_GENERIC" = "y" -o "$CONFIG_ALPHA_SRM" = "y" ]; then @@ -329,7 +342,6 @@ int ' Maximum IDE interfaces' MAX_HWIFS 4 source drivers/ide/Config.in else - define_bool CONFIG_BLK_DEV_IDE_MODES n define_bool CONFIG_BLK_DEV_HD n fi endmenu @@ -356,7 +368,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 @@ -428,7 +440,16 @@ mainmenu_option next_comment comment 'Kernel hacking' -bool 'Legacy kernel start address' CONFIG_ALPHA_LEGACY_START_ADDRESS +if [ "$CONFIG_ALPHA_TITAN" = "y" -o "$CONFIG_ALPHA_WILDFIRE" = "y" -o \ + "$CONFIG_ALPHA_MARVEL" = "y" ]; then + define_bool CONFIG_ALPHA_LEGACY_START_ADDRESS n +else + if [ "$CONFIG_ALPHA_GENERIC" = "y" ]; then + bool 'Legacy kernel start address' CONFIG_ALPHA_LEGACY_START_ADDRESS + else + define_bool CONFIG_ALPHA_LEGACY_START_ADDRESS y + fi +fi bool 'Kernel debugging' CONFIG_DEBUG_KERNEL if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then @@ -442,6 +463,9 @@ define_tristate CONFIG_MATHEMU y fi +int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 + endmenu +source crypto/Config.in source lib/Config.in Index: arch/alpha/defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/defconfig 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/alpha/defconfig 4 Aug 2004 01:25:36 -0000 1.2 @@ -270,7 +270,6 @@ 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 Index: arch/alpha/boot/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/boot/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/boot/Makefile 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/alpha/boot/Makefile 4 Aug 2004 01:25:36 -0000 1.2 @@ -7,6 +7,21 @@ # # Copyright (C) 1994 by Linus Torvalds # +# Creating a compressed kernel image (arch/alpha/boot/vmlinux.gz) +# is done via: +# +# make boot +# +# Creating a BOOTP image (arch/alpha/boot/bootpfile or bootpzfile) +# is done via: +# +# make bootpfile # using an uncompressed kernel +# make bootpzfile # using a compressed kernel +# +# Adding an INITRD image to a BOOTP file (arch/alpha/boot/bootpzfile) +# can be done, e.g, via: +# +# INITRD=`pwd`/initrd.img make bootpzfile LINKFLAGS = -static -T bootloader.lds #-N -relax @@ -17,6 +32,7 @@ OBJECTS = head.o main.o BPOBJECTS = head.o bootp.o +BPZOBJECTS = head.o bootpz.o misc.o TARGETS = vmlinux.gz tools/objstrip # also needed by aboot & milo VMLINUX = $(TOPDIR)/vmlinux OBJSTRIP = tools/objstrip @@ -41,6 +57,12 @@ cat $(INITRD) >> bootpfile endif +bootpzfile: tools/bootpzh vmlinux.nh.gz + cat tools/bootpzh vmlinux.nh.gz > bootpzfile +ifdef INITRD + cat $(INITRD) >> bootpzfile +endif + srmboot: bootdevice bootimage dd if=bootimage of=$(BOOTDEV) bs=512 seek=1 skip=1 tools/mkbb $(BOOTDEV) tools/lxboot @@ -48,16 +70,31 @@ bootdevice: @test "$(BOOTDEV)" != "" || (echo You must specify BOOTDEV ; exit -1) -vmlinux.gz: vmlinux - gzip -fv9 vmlinux +vmlinux.gz: $(TOPDIR)/vmlinux + gzip -fv9c $(TOPDIR)/vmlinux > vmlinux.gz + +vmlinux.nh.gz: vmlinux.nh + gzip -fv9c vmlinux.nh > vmlinux.nh.gz main.o: ksize.h bootp.o: ksize.h +bootpz.o: kzsize.h + ksize.h: vmlinux.nh dummy echo "#define KERNEL_SIZE `ls -l vmlinux.nh | awk '{print $$5}'`" > $@T ifdef INITRD + [ ! \( -f $(INITRD) \) ] || exit 1 + echo "#define INITRD_IMAGE_SIZE `ls -l $(INITRD) | awk '{print $$5}'`" >> $@T +endif + cmp -s $@T $@ || mv -f $@T $@ + rm -f $@T + +kzsize.h: vmlinux.nh.gz dummy + echo "#define KERNEL_SIZE `ls -l vmlinux.nh | awk '{print $$5}'`" > $@T + echo "#define KERNEL_Z_SIZE `ls -l vmlinux.nh.gz | awk '{print $$5}'`" >> $@T +ifdef INITRD [ -f $(INITRD) ] || exit 1 echo "#define INITRD_IMAGE_SIZE `ls -l $(INITRD) | awk '{print $$5}'`" >> $@T endif @@ -67,7 +104,7 @@ vmlinux.nh: $(VMLINUX) $(OBJSTRIP) $(OBJSTRIP) -v $(VMLINUX) vmlinux.nh -vmlinux: $(TOPDIR)/vmlinux +vmlinux: $(VMLINUX) $(STRIP) -o vmlinux $(VMLINUX) tools/lxboot: $(OBJSTRIP) bootloader @@ -79,6 +116,9 @@ tools/bootph: bootpheader $(OBJSTRIP) $(OBJSTRIP) -vb bootpheader tools/bootph +tools/bootpzh: bootpzheader $(OBJSTRIP) + $(OBJSTRIP) -vb bootpzheader tools/bootpzh + $(OBJSTRIP): $(OBJSTRIP).c $(HOSTCC) $(HOSTCFLAGS) -I$(HPATH) $(OBJSTRIP).c -o $(OBJSTRIP) @@ -91,6 +131,11 @@ bootpheader: $(BPOBJECTS) $(LD) $(LINKFLAGS) $(BPOBJECTS) $(LIBS) -o bootpheader +bootpzheader: $(BPZOBJECTS) + $(LD) $(LINKFLAGS) $(BPZOBJECTS) $(LIBS) -o bootpzheader + +misc.o: misc.c $(TOPDIR)/lib/inflate.c + clean: rm -f $(TARGETS) bootloader bootimage bootpfile bootpheader rm -f tools/mkbb tools/bootlx tools/lxboot tools/bootph Index: arch/alpha/boot/tools/objstrip.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/boot/tools/objstrip.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/boot/tools/objstrip.c 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/alpha/boot/tools/objstrip.c 4 Aug 2004 01:25:36 -0000 1.2 @@ -27,7 +27,6 @@ #include #include #ifdef __ELF__ -# include # include #endif Index: arch/alpha/kernel/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/kernel/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/kernel/Makefile 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/alpha/kernel/Makefile 4 Aug 2004 01:25:36 -0000 1.2 @@ -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 @@ -38,15 +37,20 @@ ifdef CONFIG_ALPHA_GENERIC obj-y += core_apecs.o core_cia.o core_irongate.o core_lca.o core_mcpcia.o \ - core_polaris.o core_t2.o core_tsunami.o core_titan.o \ - core_wildfire.o core_marvel.o \ + core_polaris.o core_t2.o core_tsunami.o \ sys_alcor.o sys_cabriolet.o sys_dp264.o sys_eb64p.o sys_eiger.o \ - sys_jensen.o sys_miata.o sys_mikasa.o sys_nautilus.o sys_titan.o \ + sys_jensen.o sys_miata.o sys_mikasa.o sys_nautilus.o \ sys_noritake.o sys_rawhide.o sys_ruffian.o sys_rx164.o \ 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 + +ifndef CONFIG_ALPHA_LEGACY_START_ADDRESS +obj-y += core_titan.o core_wildfire.o core_marvel.o \ + sys_titan.o sys_wildfire.o sys_marvel.o \ + err_titan.o err_marvel.o + +endif else @@ -93,7 +97,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 +114,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 Index: arch/alpha/kernel/core_cia.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/kernel/core_cia.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/kernel/core_cia.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/alpha/kernel/core_cia.c 4 Aug 2004 01:25:36 -0000 1.2 @@ -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 Index: arch/alpha/kernel/core_lca.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/kernel/core_lca.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/kernel/core_lca.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/alpha/kernel/core_lca.c 4 Aug 2004 01:25:36 -0000 1.2 @@ -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; } /* Index: arch/alpha/kernel/core_t2.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/kernel/core_t2.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/kernel/core_t2.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/alpha/kernel/core_t2.c 4 Aug 2004 01:25:36 -0000 1.2 @@ -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)); } Index: arch/alpha/kernel/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/kernel/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/kernel/irq.c 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/alpha/kernel/irq.c 4 Aug 2004 01:25:36 -0000 1.2 @@ -214,7 +214,7 @@ if (!shared) { desc->depth = 0; - desc->status &= ~IRQ_DISABLED; + desc->status &= ~(IRQ_DISABLED | IRQ_INPROGRESS); desc->handler->startup(irq); } spin_unlock_irqrestore(&desc->lock,flags); Index: arch/alpha/kernel/pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/kernel/pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/kernel/pci.c 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/alpha/kernel/pci.c 4 Aug 2004 01:25:36 -0000 1.2 @@ -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. */ Index: arch/alpha/kernel/pci_impl.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/kernel/pci_impl.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/kernel/pci_impl.h 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/alpha/kernel/pci_impl.h 4 Aug 2004 01:25:36 -0000 1.2 @@ -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; Index: arch/alpha/kernel/process.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/kernel/process.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/kernel/process.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/alpha/kernel/process.c 4 Aug 2004 01:25:36 -0000 1.2 @@ -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); } Index: arch/alpha/kernel/proto.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/kernel/proto.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/kernel/proto.h 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/alpha/kernel/proto.h 4 Aug 2004 01:25:36 -0000 1.2 @@ -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); Index: arch/alpha/kernel/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/kernel/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/kernel/setup.c 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/alpha/kernel/setup.c 4 Aug 2004 01:25:36 -0000 1.2 @@ -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; @@ -582,6 +583,35 @@ var_name, alpha_mv.vector_name, (alpha_using_srm ? "SRM" : "MILO")); + printk("Major Options: " +#ifdef CONFIG_SMP + "SMP " +#endif +#ifdef CONFIG_ALPHA_EV56 + "EV56 " +#endif +#ifdef CONFIG_ALPHA_EV67 + "EV67 " +#endif +#ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS + "LEGACY_START " +#endif + +#ifdef CONFIG_DISCONTIGMEM + "DISCONTIGMEM " +#ifdef CONFIG_NUMA + "NUMA " +#endif +#endif + +#ifdef CONFIG_DEBUG_SPINLOCK + "DEBUG_SPINLOCK " +#endif +#ifdef CONFIG_MAGIC_SYSRQ + "MAGIC_SYSRQ " +#endif + "\n"); + printk("Command line: %s\n", command_line); /* @@ -720,7 +750,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 +759,7 @@ &alphabook1_mv, &rawhide_mv, NULL, /* K2 */ - NULL, /* Lynx */ + &lynx_mv, /* Lynx */ &xl_mv, NULL, /* EB164 -- see variation. */ NULL, /* Noritake -- see below. */ @@ -915,6 +945,7 @@ &eiger_mv, &jensen_mv, &lx164_mv, + &lynx_mv, &miata_mv, &mikasa_mv, &mikasa_primo_mv, Index: arch/alpha/kernel/sys_alcor.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/kernel/sys_alcor.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/kernel/sys_alcor.c 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/alpha/kernel/sys_alcor.c 4 Aug 2004 01:25:36 -0000 1.2 @@ -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, Index: arch/alpha/kernel/sys_miata.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/kernel/sys_miata.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/kernel/sys_miata.c 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/alpha/kernel/sys_miata.c 4 Aug 2004 01:25:36 -0000 1.2 @@ -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 } Index: arch/alpha/kernel/sys_nautilus.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/kernel/sys_nautilus.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/kernel/sys_nautilus.c 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/alpha/kernel/sys_nautilus.c 4 Aug 2004 01:25:37 -0000 1.2 @@ -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; } } @@ -219,11 +226,13 @@ if (request_resource(&iomem_resource, bus->resource[1]) < 0) printk(KERN_ERR "Failed to request MEM on hose 0\n"); - if (pci_mem < memtop && pci_mem > alpha_mv.min_mem_address) { + if (pci_mem < memtop) + memtop = pci_mem; + if (memtop > alpha_mv.min_mem_address) { free_reserved_mem(__va(alpha_mv.min_mem_address), - __va(pci_mem)); + __va(memtop)); printk("nautilus_init_pci: %ldk freed\n", - (pci_mem - alpha_mv.min_mem_address) >> 10); + (memtop - alpha_mv.min_mem_address) >> 10); } if ((IRONGATE0->dev_vendor >> 16) > 0x7006) /* Albacore? */ Index: arch/alpha/kernel/sys_noritake.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/kernel/sys_noritake.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/kernel/sys_noritake.c 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/alpha/kernel/sys_noritake.c 4 Aug 2004 01:25:37 -0000 1.2 @@ -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, }; Index: arch/alpha/kernel/sys_sable.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/kernel/sys_sable.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/kernel/sys_sable.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/alpha/kernel/sys_sable.c 4 Aug 2004 01:25:37 -0000 1.2 @@ -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 */ Index: arch/alpha/kernel/sys_sio.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/kernel/sys_sio.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/kernel/sys_sio.c 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/alpha/kernel/sys_sio.c 4 Aug 2004 01:25:37 -0000 1.2 @@ -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, Index: arch/alpha/lib/ev6-stxncpy.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/lib/ev6-stxncpy.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/lib/ev6-stxncpy.S 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/alpha/lib/ev6-stxncpy.S 4 Aug 2004 01:25:37 -0000 1.2 @@ -360,12 +360,12 @@ 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 : + cmpbge zero, t12, t3 # E : cmoveq a2, t5, t8 # E : Latency=2, extra map slot nop # E : keep with cmoveq andnot t8, t3, t8 # E : (stall) @@ -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) Index: arch/alpha/lib/stxncpy.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/lib/stxncpy.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/lib/stxncpy.S 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/alpha/lib/stxncpy.S 4 Aug 2004 01:25:37 -0000 1.2 @@ -313,11 +313,11 @@ 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 : + cmpbge zero, t12, t3 # e0 : cmoveq a2, t5, t8 # .. e1 : andnot t8, t3, t8 # e0 : beq t8, $u_head # .. e1 (zdb) @@ -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 : Index: arch/alpha/mm/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/alpha/mm/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/alpha/mm/init.c 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/alpha/mm/init.c 4 Aug 2004 01:25:37 -0000 1.2 @@ -234,7 +234,8 @@ /* Allocate one PGD and one PMD. In the case of SRM, we'll need these to actually remap the console. There is an assumption here that only one of each is needed, and this allows for 8MB. - Currently (late 1999), big consoles are still under 4MB. + On systems with larger consoles, additional pages will be + allocated as needed during the mapping process. In the case of not SRM, but not CONFIG_ALPHA_LARGE_VMALLOC, we need to allocate the PGD we use for vmalloc before we start @@ -261,6 +262,15 @@ unsigned long paddr = crb->map[i].pa; crb->map[i].va = vaddr; for (j = 0; j < crb->map[i].count; ++j) { + /* Newer console's (especially on larger + systems) may require more pages of + PTEs. Grab additional pages as needed. */ + if (pmd != pmd_offset(pgd, vaddr)) { + memset(kernel_end, 0, PAGE_SIZE); + pmd = pmd_offset(pgd, vaddr); + pmd_set(pmd, (pte_t *)kernel_end); + kernel_end += PAGE_SIZE; + } set_pte(pte_offset(pmd, vaddr), mk_pte_phys(paddr, PAGE_KERNEL)); paddr += PAGE_SIZE; Index: arch/arm/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/Makefile,v retrieving revision 1.1 retrieving revision 1.4 diff -u -r1.1 -r1.4 --- arch/arm/Makefile 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/Makefile 23 Aug 2004 15:50:06 -0000 1.4 @@ -50,9 +50,9 @@ 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 -Uarm -CFLAGS +=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Uarm -AFLAGS +=$(apcs-y) $(arch-y) -mno-fpu -msoft-float +CFLAGS_BOOT :=$(apcs-y) $(arch-y) $(tune-y) -msoft-float -Uarm +CFLAGS +=$(apcs-y) $(arch-y) $(tune-y) -msoft-float -Uarm +AFLAGS +=$(apcs-y) $(arch-y) -msoft-float ifeq ($(CONFIG_CPU_26),y) PROCESSOR := armo @@ -217,6 +217,11 @@ endif endif +ifeq ($(findstring m,$(CONFIG_USB_OHCI_SA1111) $(CONFIG_USB_OHCI_AT91) $(CONFIG_USB_OHCI_EP93XX)),m) + SUBDIRS +=arch/arm/common + CORE_FILES +=arch/arm/common/nopci.o +endif + ifeq ($(findstring y,$(CONFIG_USB_OHCI_SA1111) $(CONFIG_USB_OHCI_AT91) $(CONFIG_USB_OHCI_EP93XX)),y) SUBDIRS +=arch/arm/common CORE_FILES +=arch/arm/common/nopci.o Index: arch/arm/config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/config.in,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- arch/arm/config.in 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/config.in 9 Feb 2006 22:58:57 -0000 1.3 @@ -33,26 +33,26 @@ comment 'System Type' choice 'ARM system type' \ - "Anakin CONFIG_ARCH_ANAKIN \ - Archimedes/A5000 CONFIG_ARCH_ARCA5K \ - Cirrus-CL-PS7500FE CONFIG_ARCH_CLPS7500 \ - CLPS711x/EP721x-based CONFIG_ARCH_CLPS711X \ - Co-EBSA285 CONFIG_ARCH_CO285 \ - EBSA-110 CONFIG_ARCH_EBSA110 \ - 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 \ + "Anakin CONFIG_ARCH_ANAKIN \ + Archimedes/A5000 CONFIG_ARCH_ARCA5K \ + Cirrus-CL-PS7500FE CONFIG_ARCH_CLPS7500 \ + CLPS711x/EP721x-based CONFIG_ARCH_CLPS711X \ + Co-EBSA285 CONFIG_ARCH_CO285 \ + EBSA-110 CONFIG_ARCH_EBSA110 \ + 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 \ EP9301 CONFIG_ARCH_EP9301 \ EP9312 CONFIG_ARCH_EP9312 \ EP9315 CONFIG_ARCH_EP9315 \ - RiscPC CONFIG_ARCH_RPC \ - RiscStation CONFIG_ARCH_RISCSTATION \ - SA1100-based CONFIG_ARCH_SA1100 \ - Shark CONFIG_ARCH_SHARK \ - AT91RM9200-based CONFIG_ARCH_AT91RM9200 " RiscPC + RiscPC CONFIG_ARCH_RPC \ + 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' @@ -147,6 +147,7 @@ mainmenu_option next_comment comment 'AT91RM9200 Implementations' dep_bool ' Atmel AT91RM9200 Development Board' CONFIG_ARCH_AT91RM9200DK $CONFIG_ARCH_AT91RM9200 +dep_bool ' Cogent CSB337' CONFIG_MACH_CSB337 $CONFIG_ARCH_AT91RM9200 endmenu mainmenu_option next_comment @@ -192,6 +193,12 @@ define_bool CONFIG_ARCH_ACORN n fi +if [ "$CONFIG_ARCH_CAMELOT" = "y" ]; then + define_bool CONFIG_PLD y +else + define_bool CONFIG_PLD n +fi + ##################################################################### # Footbridge support if [ "$CONFIG_ARCH_CO285" = "y" -o \ @@ -340,7 +347,7 @@ define_bool CONFIG_CPU_ARM920T y else if [ "$CONFIG_ARCH_INTEGRATOR" = "y" -o \ - "$CONFIG_ARCH_OMAHA" = "y" ]; then + "$CONFIG_ARCH_OMAHA" = "y" ]; then bool 'Support ARM920T processor' CONFIG_CPU_ARM920T else define_bool CONFIG_CPU_ARM920T n @@ -351,26 +358,42 @@ # ARM922T if [ "$CONFIG_ARCH_CAMELOT" = "y" ]; then define_bool CONFIG_CPU_ARM922T y - define_bool CONFIG_PLD y else - define_bool CONFIG_CPU_ARM922T n - define_bool CONFIG_PLD n + if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then + bool 'Support ARM922T(Excalibur) processor' CONFIG_ARM922T + else + define_bool CONFIG_CPU_ARM922T n + fi fi # ARM926T if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then - bool 'Support ARM926T processor' CONFIG_CPU_ARM926T + bool 'Support ARM926TEJ-S processor' CONFIG_CPU_ARM926T else define_bool CONFIG_CPU_ARM926T n fi # ARM1020 if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then - bool 'Support ARM1020 processor' CONFIG_CPU_ARM1020 + bool 'Support ARM1020T (Rev0) processor' CONFIG_CPU_ARM1020 else define_bool CONFIG_CPU_ARM1020 n fi +# ARM1020E +if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then + bool 'Support ARM1020E (Rev1) processor' CONFIG_CPU_ARM1020E +else + define_bool CONFIG_CPU_ARM1020E n +fi + +# ARM1022 +if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then + bool 'Support ARM1022 processor' CONFIG_CPU_ARM1020E +else + define_bool CONFIG_CPU_ARM1022 n +fi + # ARM1026EJ-S if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then bool 'Support ARM1026EJ-S processor' CONFIG_CPU_ARM1026 @@ -412,7 +435,7 @@ "$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_L7200" = "y" -o "$CONFIG_ARCH_ANAKIN" = "y" -o \ "$CONFIG_ARCH_CAMELOT" = "y" -o "$CONFIG_ARCH_MX1ADS" = "y" -o \ "$CONFIG_ARCH_EP9301" = "y" -o "$CONFIG_ARCH_EP9312" = "y" -o \ "$CONFIG_ARCH_EP9315" = "y" -o \ @@ -426,25 +449,29 @@ 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 + "$CONFIG_CPU_ARM1020" = "y" -o "$CONFIG_CPU_ARM1020E" = "y" -o \ + "$CONFIG_CPU_ARM1022" = "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_ARM1020E" = "y" -o "$CONFIG_CPU_ARM1022" = "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 + if [ "$CONFIG_CPU_DCACHE_DISABLE" = "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_ARM1020E" = "y" -o "$CONFIG_CPU_ARM1022" = "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 +if [ "$CONFIG_CPU_ARM1020" = "y" -o "$CONFIG_CPU_ARM1020E" = "y" -o \ + "$CONFIG_CPU_ARM1026" = "y" -o "$CONFIG_CPU_ARM1022" = "y" ]; then bool 'Disable branch prediction' CONFIG_CPU_BPREDICT_DISABLE fi @@ -541,8 +568,8 @@ 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 + "ELF CONFIG_KCORE_ELF \ + A.OUT CONFIG_KCORE_AOUT" ELF tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC @@ -559,18 +586,20 @@ "$CONFIG_ARCH_SA1100" = "y" -o \ "$CONFIG_ARCH_INTEGRATOR" = "y" -o \ "$CONFIG_ARCH_CDB89712" = "y" -o \ - "$CONFIG_ARCH_P720T" = "y" -o \ - "$CONFIG_ARCH_OMAHA" = "y" ]; then + "$CONFIG_ARCH_P720T" = "y" -o \ + "$CONFIG_ARCH_OMAHA" = "y" -o \ + "$CONFIG_ARCH_AT91RM9200" = "y" ]; then bool 'Timer and CPU usage LEDs' CONFIG_LEDS if [ "$CONFIG_LEDS" = "y" ]; then if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \ - "$CONFIG_ARCH_EBSA285" = "y" -o \ - "$CONFIG_ARCH_SHARK" = "y" -o \ - "$CONFIG_ARCH_CO285" = "y" -o \ - "$CONFIG_ARCH_SA1100" = "y" -o \ + "$CONFIG_ARCH_EBSA285" = "y" -o \ + "$CONFIG_ARCH_SHARK" = "y" -o \ + "$CONFIG_ARCH_CO285" = "y" -o \ + "$CONFIG_ARCH_SA1100" = "y" -o \ "$CONFIG_ARCH_INTEGRATOR" = "y" -o \ - "$CONFIG_ARCH_P720T" = "y" -o \ - "$CONFIG_ARCH_OMAHA" = "y" ]; then + "$CONFIG_ARCH_P720T" = "y" -o \ + "$CONFIG_ARCH_OMAHA" = "y" -o \ + "$CONFIG_ARCH_AT91RM9200" = "y" ]; then bool ' Timer LED' CONFIG_LEDS_TIMER bool ' CPU usage LED' CONFIG_LEDS_CPU fi @@ -593,7 +622,10 @@ source drivers/parport/Config.in if [ "$CONFIG_ALIGNMENT_TRAP" = "y" ]; then - source drivers/mtd/Config.in + source drivers/mtd2k/Config.in + if [ "$CONFIG_MTD2K" = "n" ]; then + source drivers/mtd/Config.in + fi else define_bool CONFIG_MTD n fi @@ -631,7 +663,6 @@ 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 @@ -709,7 +740,7 @@ "$CONFIG_ARCH_CLPS7500" = "y" -o \ "$CONFIG_ARCH_P720T" = "y" -o \ "$CONFIG_ARCH_ANAKIN" = "y" -o \ - "$CONFIG_ARCH_MX1ADS" = "y" ]; then + "$CONFIG_ARCH_MX1ADS" = "y" ]; then define_bool CONFIG_PC_KEYMAP y fi if [ "$CONFIG_ARCH_ACORN" != "y" -a "$CONFIG_ARCH_EBSA110" != "y" -a "$CONFIG_ARCH_RISCSTATION" != "y" ]; then Index: arch/arm/defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/defconfig 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/defconfig 4 Aug 2004 01:25:37 -0000 1.2 @@ -303,7 +303,6 @@ # 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 # Index: arch/arm/boot/compressed/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/boot/compressed/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/boot/compressed/head.S 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/boot/compressed/head.S 4 Aug 2004 01:25:37 -0000 1.2 @@ -40,6 +40,14 @@ .macro writeb, rb strb \rb, [r3, #0x3f8 << 2] .endm +#elif defined(CONFIG_ARCH_RISCSTATION) + .macro loadsp, rb + mov \rb, #0x03000000 + orr \rb, \rb, #0x00010000 + .endm + .macro writeb, rb + strb \rb, [r3, #0x3f8 << 2] + .endm #elif defined(CONFIG_ARCH_INTEGRATOR) .macro loadsp, rb mov \rb, #0x16000000 @@ -396,6 +404,20 @@ mcr p15, 0, r0, c1, c0, 0 @ load control register mov pc, r12 +__arm7_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, #0x7d + mcr p15, 0, r0, c1, c0, 0 @ load control register + mov pc, r12 + + /* * All code following this line is relocatable. It is relocated by * the above code to the end of the decompressed kernel image and @@ -480,9 +502,9 @@ .word 0x41007000 @ ARM7/710 .word 0xfff8fe00 + b __arm7_cache_on b __arm7_cache_off - b __arm7_cache_off - mov pc, lr + b __armv3_cache_flush .word 0x41807200 @ ARM720T (writethrough) .word 0xffffff00 @@ -490,14 +512,14 @@ b __armv4_cache_off mov pc, lr - .word 0x41129200 @ ARM920T - .word 0xff00fff0 + .word 0x41009200 @ ARM920T, ARM922T, ARM926TEJ-S + .word 0xff00ff90 b __armv4_cache_on b __armv4_cache_off b __armv4_cache_flush - .word 0x41029220 @ ARM922T - .word 0xff00fff0 + .word 0x4100a200 @ ARM1020T/E, ARM1022E, ARM1026TEJ-S + .word 0xff00ff90 b __armv4_cache_on b __armv4_cache_off b __armv4_cache_flush Index: arch/arm/boot/compressed/misc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/boot/compressed/misc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/boot/compressed/misc.c 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/boot/compressed/misc.c 21 Oct 2005 17:54:15 -0000 1.2 @@ -265,7 +265,7 @@ bytes_out += (ulg)outcnt; output_ptr += (ulg)outcnt; outcnt = 0; - puts("."); + // puts("."); } static void error(char *x) @@ -293,9 +293,11 @@ arch_decomp_setup(); makecrc(); - puts("Uncompressing Linux..."); + // These puts() messages can't be quieted by any other means and some + // people don't appreciate it if they want to run console-less --JO + // puts("Uncompressing Linux..."); gunzip(); - puts(" done, booting the kernel.\n"); + // puts(" done, booting the kernel.\n"); return output_ptr; } #else @@ -307,9 +309,9 @@ output_data = output_buffer; makecrc(); - puts("Uncompressing Linux..."); + // puts("Uncompressing Linux..."); gunzip(); - puts("done.\n"); + // puts("done.\n"); return 0; } #endif Index: arch/arm/def-configs/a5k =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/a5k,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/a5k 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/a5k 4 Aug 2004 01:25:37 -0000 1.2 @@ -287,7 +287,6 @@ # 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 # # SCSI support Index: arch/arm/def-configs/accelent_sa =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/accelent_sa,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/accelent_sa 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/accelent_sa 4 Aug 2004 01:25:37 -0000 1.2 @@ -506,7 +506,6 @@ # 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 # Index: arch/arm/def-configs/adsagc =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/adsagc,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/adsagc 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/adsagc 4 Aug 2004 01:25:37 -0000 1.2 @@ -535,7 +535,6 @@ # 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 Index: arch/arm/def-configs/adsbitsy =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/adsbitsy,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/adsbitsy 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/adsbitsy 4 Aug 2004 01:25:37 -0000 1.2 @@ -535,7 +535,6 @@ # 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 Index: arch/arm/def-configs/adsbitsyplus =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/adsbitsyplus,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/adsbitsyplus 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/adsbitsyplus 4 Aug 2004 01:25:37 -0000 1.2 @@ -535,7 +535,6 @@ # 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 Index: arch/arm/def-configs/anakin =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/anakin,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/anakin 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/anakin 4 Aug 2004 01:25:37 -0000 1.2 @@ -259,7 +259,6 @@ # 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 # Index: arch/arm/def-configs/assabet =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/assabet,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/assabet 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/assabet 4 Aug 2004 01:25:37 -0000 1.2 @@ -493,7 +493,6 @@ # 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 Index: arch/arm/def-configs/at91rm9200dk =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/at91rm9200dk,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/at91rm9200dk 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/at91rm9200dk 4 Aug 2004 01:25:37 -0000 1.2 @@ -111,6 +111,7 @@ # AT91RM9200 Implementations # CONFIG_ARCH_AT91RM9200DK=y +# CONFIG_MACH_CSB337 is not set # # CLPS711X/EP721X Implementations @@ -125,6 +126,7 @@ # CONFIG_ARCH_EP7211 is not set # CONFIG_ARCH_EP7212 is not set # CONFIG_ARCH_ACORN is not set +# CONFIG_PLD is not set # CONFIG_FOOTBRIDGE is not set # CONFIG_FOOTBRIDGE_HOST is not set # CONFIG_FOOTBRIDGE_ADDIN is not set @@ -135,9 +137,10 @@ # 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_ARM1020E is not set +# CONFIG_CPU_ARM1022 is not set # CONFIG_CPU_ARM1026 is not set # CONFIG_CPU_SA110 is not set # CONFIG_CPU_SA1100 is not set @@ -146,6 +149,7 @@ # CONFIG_ARM_THUMB is not set # CONFIG_CPU_ICACHE_DISABLE is not set # CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set # CONFIG_DISCONTIGMEM is not set # @@ -164,6 +168,7 @@ # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set # CONFIG_FPE_FASTFPE is not set CONFIG_KCORE_ELF=y # CONFIG_KCORE_AOUT is not set @@ -173,6 +178,9 @@ # 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_LEDS=y +CONFIG_LEDS_TIMER=y +# CONFIG_LEDS_CPU is not set CONFIG_ALIGNMENT_TRAP=y # @@ -204,6 +212,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 @@ -230,7 +239,9 @@ # CONFIG_MTD_AUTCPU12 is not set # CONFIG_MTD_EDB7312 is not set # CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_CEIVA is not set # CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set # # Self-contained MTD device drivers @@ -250,9 +261,9 @@ # 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 +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_AT91_SMARTMEDIA is not set # # Plug and Play configuration @@ -269,6 +280,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set @@ -276,6 +288,7 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_STATS is not set # # Multi-device support (RAID and LVM) @@ -312,6 +325,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set # CONFIG_IPX is not set @@ -382,10 +401,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 @@ -426,7 +447,6 @@ # 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 # @@ -456,6 +476,8 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set +# CONFIG_INPUT_MX1TS is not set # # Character devices @@ -503,6 +525,7 @@ # CONFIG_I2C=y # CONFIG_I2C_ALGOBIT is not set +# CONFIG_SCx200_ACB is not set # CONFIG_I2C_ALGOPCF is not set CONFIG_I2C_AT91=y CONFIG_I2C_CHARDEV=y @@ -529,6 +552,11 @@ # # CONFIG_INPUT_GAMEPORT 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 @@ -537,12 +565,14 @@ CONFIG_WATCHDOG_NOWAYOUT=y # 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_21285_WATCHDOG is not set # CONFIG_977_WATCHDOG is not set # CONFIG_SA1100_WATCHDOG is not set +# CONFIG_EPXA_WATCHDOG is not set # CONFIG_OMAHA_WATCHDOG is not set CONFIG_AT91_WATCHDOG=y # CONFIG_EUROTECH_WDT is not set @@ -552,11 +582,16 @@ # 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_AMD7XX_TCO is not set +# CONFIG_SCx200 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_AT91_RTC=y @@ -569,6 +604,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -580,6 +619,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 @@ -589,6 +629,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 @@ -606,6 +649,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 @@ -625,6 +671,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -633,9 +684,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 @@ -649,7 +702,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 @@ -675,16 +727,18 @@ # 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_SL811HS_ALT is not set +# CONFIG_USB_SL811HS 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_MIDI is not set # CONFIG_USB_STORAGE is not set # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_DATAFAB is not set @@ -693,6 +747,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 @@ -701,7 +756,10 @@ # 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 # CONFIG_USB_DC2XX is not set # CONFIG_USB_MDC800 is not set # CONFIG_USB_SCANNER is not set @@ -719,35 +777,16 @@ # 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_TIGL is not set # CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set + +# +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set # # Bluetooth support @@ -771,3 +810,10 @@ CONFIG_DEBUG_LL=y # CONFIG_DEBUG_DC21285_PORT is not set # CONFIG_DEBUG_CLPS711X_UART2 is not set + +# +# Library routines +# +CONFIG_CRC32=y +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set Index: arch/arm/def-configs/badge4 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/badge4,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/badge4 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/badge4 4 Aug 2004 01:25:37 -0000 1.2 @@ -527,7 +527,6 @@ # 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 Index: arch/arm/def-configs/brutus =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/brutus,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/brutus 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/brutus 4 Aug 2004 01:25:37 -0000 1.2 @@ -123,7 +123,6 @@ # 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 # Index: arch/arm/def-configs/cep =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/cep,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/cep 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/cep 4 Aug 2004 01:25:37 -0000 1.2 @@ -303,7 +303,6 @@ # 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 # Index: arch/arm/def-configs/cerfcube =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/cerfcube,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/cerfcube 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/cerfcube 4 Aug 2004 01:25:37 -0000 1.2 @@ -474,7 +474,6 @@ # 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 Index: arch/arm/def-configs/cerfpda =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/cerfpda,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/cerfpda 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/cerfpda 4 Aug 2004 01:25:37 -0000 1.2 @@ -504,7 +504,6 @@ # 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 Index: arch/arm/def-configs/cerfpod =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/cerfpod,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/cerfpod 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/cerfpod 4 Aug 2004 01:25:37 -0000 1.2 @@ -475,7 +475,6 @@ # 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 Index: arch/arm/def-configs/clps7500 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/clps7500,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/clps7500 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/clps7500 4 Aug 2004 01:25:37 -0000 1.2 @@ -298,7 +298,6 @@ # 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 # Index: arch/arm/def-configs/ebsa110 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/ebsa110,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/ebsa110 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/ebsa110 4 Aug 2004 01:25:37 -0000 1.2 @@ -387,7 +387,6 @@ # 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 # Index: arch/arm/def-configs/edb7211 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/edb7211,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/edb7211 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/edb7211 4 Aug 2004 01:25:37 -0000 1.2 @@ -225,7 +225,6 @@ # 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 # Index: arch/arm/def-configs/ep9301 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/ep9301,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/ep9301 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/ep9301 4 Aug 2004 01:25:37 -0000 1.2 @@ -586,7 +586,7 @@ # # Sound # -CONFIG_SOUND=n +CONFIG_SOUND=y # CONFIG_SOUND_ALI5455 is not set # CONFIG_SOUND_BT878 is not set # CONFIG_SOUND_CMPCI is not set @@ -608,7 +608,7 @@ # CONFIG_SOUND_MSNDPIN is not set # CONFIG_SOUND_VIA82CXXX is not set # CONFIG_MIDI_VIA82CXXX is not set -# CONFIG_SOUND_OSS=y +CONFIG_SOUND_OSS=y # CONFIG_SOUND_TRACEINIT is not set # CONFIG_SOUND_DMAP is not set # CONFIG_SOUND_AD1816 is not set @@ -619,8 +619,8 @@ # CONFIG_SOUND_CS4232 is not set # CONFIG_SOUND_EP93XX_NONE is not set # CONFIG_SOUND_EP93XX_AC97 is not set -# CONFIG_SOUND_EP93XX_I2S=y -# CONFIG_CODEC_CS4271=y +CONFIG_SOUND_EP93XX_I2S=y +CONFIG_CODEC_CS4271=y # CONFIG_CODEC_CS4228A is not set # CONFIG_SOUND_SSCAPE is not set # CONFIG_SOUND_GUS is not set Index: arch/arm/def-configs/ep9301_nfs =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/ep9301_nfs,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/ep9301_nfs 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/ep9301_nfs 4 Aug 2004 01:25:37 -0000 1.2 @@ -182,7 +182,7 @@ # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set # CONFIG_ARTHUR is not set -CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.231:/nfsroot-arm ip=dhcp" +CONFIG_CMDLINE="root=/dev/nfs nfsroot=: ip=dhcp" # CONFIG_ALIGNMENT_TRAP is not set # @@ -364,36 +364,9 @@ # # ATA/ATAPI/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_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES 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 -# 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_EP93XX is not set -CONFIG_BLK_DEV_TSCF=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 @@ -464,8 +437,7 @@ # CONFIG_SERIAL_8250_HUB6 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=1024 +# CONFIG_UNIX98_PTYS is not set # # I2C support @@ -566,7 +538,7 @@ CONFIG_DEVFS_FS=y CONFIG_DEVFS_MOUNT=y # 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=y @@ -614,7 +586,68 @@ # # Sound # -# CONFIG_SOUND 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_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=y +# CONFIG_SOUND_TRACEINIT is not set +# CONFIG_SOUND_DMAP is not set +# CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_AD1889 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_EP93XX_NONE is not set +# CONFIG_SOUND_EP93XX_AC97 is not set +CONFIG_SOUND_EP93XX_I2S=y +CONFIG_CODEC_CS4271=y +# CONFIG_CODEC_CS4228A 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_KAHLUA 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 Index: arch/arm/def-configs/epxa10db =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/epxa10db,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/epxa10db 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/epxa10db 4 Aug 2004 01:25:37 -0000 1.2 @@ -422,7 +422,6 @@ # 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 # Index: arch/arm/def-configs/epxa1db =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/epxa1db,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/epxa1db 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/epxa1db 4 Aug 2004 01:25:37 -0000 1.2 @@ -404,7 +404,6 @@ # 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 # Index: arch/arm/def-configs/flexanet =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/flexanet,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/flexanet 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/flexanet 4 Aug 2004 01:25:37 -0000 1.2 @@ -479,7 +479,6 @@ # 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 Index: arch/arm/def-configs/footbridge =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/footbridge,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/footbridge 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/footbridge 4 Aug 2004 01:25:37 -0000 1.2 @@ -437,7 +437,6 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # # SCSI support Index: arch/arm/def-configs/fortunet =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/fortunet,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/fortunet 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/fortunet 4 Aug 2004 01:25:38 -0000 1.2 @@ -295,7 +295,6 @@ # 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 # Index: arch/arm/def-configs/freebird =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/freebird,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/freebird 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/freebird 4 Aug 2004 01:25:38 -0000 1.2 @@ -384,7 +384,6 @@ # 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 # # SCSI support Index: arch/arm/def-configs/freebird_new =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/freebird_new,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/freebird_new 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/freebird_new 4 Aug 2004 01:25:38 -0000 1.2 @@ -398,7 +398,6 @@ # 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 # # SCSI support Index: arch/arm/def-configs/frodo =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/frodo,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/frodo 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/frodo 4 Aug 2004 01:25:38 -0000 1.2 @@ -462,7 +462,6 @@ # 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 Index: arch/arm/def-configs/graphicsclient =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/graphicsclient,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/graphicsclient 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/graphicsclient 4 Aug 2004 01:25:38 -0000 1.2 @@ -533,7 +533,6 @@ # 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 Index: arch/arm/def-configs/graphicsmaster =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/graphicsmaster,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/graphicsmaster 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/graphicsmaster 4 Aug 2004 01:25:38 -0000 1.2 @@ -535,7 +535,6 @@ # 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 Index: arch/arm/def-configs/h3600 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/h3600,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/h3600 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/h3600 4 Aug 2004 01:25:38 -0000 1.2 @@ -482,7 +482,6 @@ # 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 Index: arch/arm/def-configs/huw_webpanel =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/huw_webpanel,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/huw_webpanel 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/huw_webpanel 4 Aug 2004 01:25:38 -0000 1.2 @@ -227,7 +227,6 @@ # 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 # Index: arch/arm/def-configs/integrator =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/integrator,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/integrator 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/integrator 4 Aug 2004 01:25:38 -0000 1.2 @@ -410,7 +410,6 @@ # 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 # Index: arch/arm/def-configs/jornada720 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/jornada720,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/jornada720 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/jornada720 4 Aug 2004 01:25:38 -0000 1.2 @@ -482,7 +482,6 @@ # 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 Index: arch/arm/def-configs/lart =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/lart,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/lart 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/lart 4 Aug 2004 01:25:38 -0000 1.2 @@ -484,7 +484,6 @@ # 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 Index: arch/arm/def-configs/lusl7200 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/lusl7200,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/lusl7200 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/lusl7200 4 Aug 2004 01:25:38 -0000 1.2 @@ -161,7 +161,6 @@ # 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 # Index: arch/arm/def-configs/nanoengine =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/nanoengine,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/nanoengine 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/nanoengine 4 Aug 2004 01:25:38 -0000 1.2 @@ -413,7 +413,6 @@ # 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 # Index: arch/arm/def-configs/neponset =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/neponset,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/neponset 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/neponset 4 Aug 2004 01:25:38 -0000 1.2 @@ -455,7 +455,6 @@ # 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 Index: arch/arm/def-configs/omaha =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/omaha,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/omaha 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/omaha 4 Aug 2004 01:25:38 -0000 1.2 @@ -358,7 +358,6 @@ # 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 Index: arch/arm/def-configs/omnimeter =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/omnimeter,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/omnimeter 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/omnimeter 4 Aug 2004 01:25:38 -0000 1.2 @@ -314,7 +314,6 @@ # 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 # # SCSI support Index: arch/arm/def-configs/pangolin =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/pangolin,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/pangolin 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/pangolin 4 Aug 2004 01:25:38 -0000 1.2 @@ -434,7 +434,6 @@ # 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 # # SCSI support Index: arch/arm/def-configs/pfs168_mqtft =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/pfs168_mqtft,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/pfs168_mqtft 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/pfs168_mqtft 4 Aug 2004 01:25:38 -0000 1.2 @@ -458,7 +458,6 @@ # 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 # # SCSI support Index: arch/arm/def-configs/pfs168_mqvga =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/pfs168_mqvga,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/pfs168_mqvga 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/pfs168_mqvga 4 Aug 2004 01:25:38 -0000 1.2 @@ -458,7 +458,6 @@ # 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 # # SCSI support Index: arch/arm/def-configs/pfs168_sastn =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/pfs168_sastn,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/pfs168_sastn 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/pfs168_sastn 4 Aug 2004 01:25:38 -0000 1.2 @@ -459,7 +459,6 @@ # 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 # # SCSI support Index: arch/arm/def-configs/pfs168_satft =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/pfs168_satft,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/pfs168_satft 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/pfs168_satft 4 Aug 2004 01:25:38 -0000 1.2 @@ -458,7 +458,6 @@ # 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 # # SCSI support Index: arch/arm/def-configs/pleb =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/pleb,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/pleb 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/pleb 4 Aug 2004 01:25:38 -0000 1.2 @@ -331,7 +331,6 @@ # 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 # Index: arch/arm/def-configs/riscstation =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/riscstation,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/riscstation 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/riscstation 4 Aug 2004 01:25:38 -0000 1.2 @@ -372,7 +372,6 @@ # 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 Index: arch/arm/def-configs/rpc =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/rpc,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/rpc 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/rpc 4 Aug 2004 01:25:38 -0000 1.2 @@ -412,7 +412,6 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # # SCSI support Index: arch/arm/def-configs/shannon =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/shannon,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/shannon 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/shannon 4 Aug 2004 01:25:38 -0000 1.2 @@ -387,7 +387,6 @@ # 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 # Index: arch/arm/def-configs/shark =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/shark,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/shark 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/shark 4 Aug 2004 01:25:38 -0000 1.2 @@ -391,7 +391,6 @@ # 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 Index: arch/arm/def-configs/system3 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/system3,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/system3 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/def-configs/system3 4 Aug 2004 01:25:38 -0000 1.2 @@ -496,7 +496,6 @@ # 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 Index: arch/arm/def-configs/ts7200 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/ts7200,v retrieving revision 1.1 retrieving revision 1.22 diff -u -r1.1 -r1.22 --- arch/arm/def-configs/ts7200 23 Jul 2004 01:56:20 -0000 1.1 +++ arch/arm/def-configs/ts7200 6 Jun 2006 21:06:18 -0000 1.22 @@ -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 @@ -51,6 +51,10 @@ # # Archimedes/A5000 Implementations # + +# +# Archimedes/A5000 Implementations (select only ONE) +# # CONFIG_ARCH_ARC is not set # CONFIG_ARCH_A5K is not set @@ -114,6 +118,7 @@ # AT91RM9200 Implementations # # CONFIG_ARCH_AT91RM9200DK is not set +# CONFIG_MACH_CSB337 is not set # # CLPS711X/EP721X Implementations @@ -128,6 +133,7 @@ # CONFIG_ARCH_EP7211 is not set # CONFIG_ARCH_EP7212 is not set # CONFIG_ARCH_ACORN is not set +# CONFIG_PLD is not set # CONFIG_FOOTBRIDGE is not set # CONFIG_FOOTBRIDGE_HOST is not set # CONFIG_FOOTBRIDGE_ADDIN is not set @@ -135,7 +141,11 @@ # # EP9301 Options # -CONFIG_EP93XX_DMA=y +# CONFIG_EP93XX_DMA is not set + +# +# Processor Type +# CONFIG_CPU_32=y # CONFIG_CPU_26 is not set # CONFIG_CPU_ARM610 is not set @@ -143,17 +153,23 @@ # 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_ARM1020E is not set +# CONFIG_CPU_ARM1022 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 + +# +# Processor Features +# # CONFIG_ARM_THUMB is not set # CONFIG_CPU_ICACHE_DISABLE is not set # CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set CONFIG_DISCONTIGMEM=y # CONFIG_MMU_TABLE_DUMP is not set @@ -178,6 +194,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_NWFPE_XP is not set # CONFIG_FPE_FASTFPE is not set @@ -188,7 +208,7 @@ # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set # CONFIG_ARTHUR is not set -CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.231:/nfsroot-arm ip=dhcp" +CONFIG_CMDLINE="root=/dev/mtdblock1 console=ttyAM0,115200" CONFIG_ALIGNMENT_TRAP=y # @@ -197,6 +217,11 @@ # CONFIG_PARPORT is not set # +# Memory Technology Devices (MTD) for 2k NAND flash +# +# CONFIG_MTD2K is not set + +# # Memory Technology Devices (MTD) # CONFIG_MTD=y @@ -206,10 +231,15 @@ # 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 +# CONFIG_INFTL is not set # # RAM/ROM/Flash chip drivers @@ -217,10 +247,25 @@ 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_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +# CONFIG_MTD_CFI_I2 is not set +# 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_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set @@ -232,20 +277,24 @@ # # Mapping drivers for chip access # +# CONFIG_MTD_COMPLEX_MAPPINGS is not set # 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_TS7XXX=y +# CONFIG_MTD_LUBBOCK is not set +# CONFIG_MTD_IXP425 is not set +# CONFIG_MTD_EPXA10DB 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_H720X is not set # CONFIG_MTD_IMPA7 is not set # CONFIG_MTD_CEIVA is not set +# CONFIG_MTD_NOR_TOTO is not set +CONFIG_MTD_TS7XXX=y # CONFIG_MTD_PCI is not set # CONFIG_MTD_PCMCIA is not set @@ -256,15 +305,28 @@ # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_MTDRAM is not set # CONFIG_MTD_BLKMTD is not set -# CONFIG_MTD_DOC1000 is not set + +# +# Disk-On-Chip Device Drivers +# # CONFIG_MTD_DOC2000 is not set # CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set # CONFIG_MTD_DOCPROBE is not set +# CONFIG_MTD_DOCECC is not set # # NAND Flash Device Drivers # -# CONFIG_MTD_NAND is not set +CONFIG_MTD_NAND=m +CONFIG_MTD_NAND_VERIFY_WRITE=y +# CONFIG_MTD_NAND_SPIA is not set +# CONFIG_MTD_NAND_TOTO is not set +# CONFIG_MTD_NAND_AUTCPU12 is not set +# CONFIG_MTD_NAND_EDB7312 is not set +CONFIG_MTD_NAND_TS7250=m +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_DISKONCHIP is not set # # Plug and Play configuration @@ -275,19 +337,20 @@ # # Block devices # +# CONFIG_BLK_DEV_SDCARD is not set # 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_CISS_MONITOR_THREAD 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_LOOP=m # CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=12288 -CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set # CONFIG_BLK_STATS is not set # @@ -305,10 +368,11 @@ # # Networking options # -# CONFIG_PACKET is not set +CONFIG_PACKET=m +# CONFIG_PACKET_MMAP is not set # CONFIG_NETLINK_DEV is not set # CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set +CONFIG_FILTER=y CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -325,8 +389,17 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set -# CONFIG_VLAN_8021Q is not set +CONFIG_VLAN_8021Q=m + +# +# +# # CONFIG_IPX is not set # CONFIG_ATALK is not set @@ -367,7 +440,7 @@ # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set +CONFIG_TUN=m # CONFIG_ETHERTAP is not set # @@ -376,6 +449,9 @@ CONFIG_NET_ETHERNET=y # CONFIG_ARM_AM79C961A is not set # CONFIG_ARM_CIRRUS is not set +CONFIG_CS89x0=m +# CONFIG_OPENETH is not set +# CONFIG_NE2000 is not set CONFIG_EP93XX_ETHERNET=y # CONFIG_SUNLANCE is not set # CONFIG_SUNBMAC is not set @@ -405,13 +481,35 @@ # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set -# CONFIG_PPP is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPPOE=m # 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 +CONFIG_WLAN_NG=y + +# +# Wireless USB cards +# +CONFIG_USB_ATMEL=m +PRISM2_USB=m +CONFIG_NET_WIRELESS=y # # Token Ring devices @@ -434,7 +532,51 @@ # # IrDA (infrared) support # -# CONFIG_IRDA is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +# CONFIG_IRLAN is not set +# CONFIG_IRNET is not set +# CONFIG_IRCOMM is not set +# 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 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_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +# CONFIG_VLSI_FIR is not set +# CONFIG_VIA_IRCC_FIR is not set +# CONFIG_EP93XX_IRDA is not set # # ATA/ATAPI/MFM/RLL support @@ -445,6 +587,10 @@ # 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 @@ -456,6 +602,10 @@ # 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 @@ -464,22 +614,30 @@ # 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_MEDLEY is not set # CONFIG_BLK_DEV_ATARAID_SII 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 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 @@ -502,6 +660,7 @@ # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set @@ -544,19 +703,35 @@ # # Input core support # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT=m +CONFIG_INPUT_KEYBDEV=m +CONFIG_INPUT_MOUSEDEV=m +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_UINPUT is not set # CONFIG_INPUT_MX1TS is not set # # Character devices # -# CONFIG_VT is not set -# CONFIG_SERIAL is not set -# CONFIG_SERIAL_EXTENDED is not set +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +CONFIG_EP93XX_VT=y +# CONFIG_EP93XX_KBD_SPI is not set +CONFIG_EP93XX_KBD_USB=y +# CONFIG_JNS200_SERIAL is not set +# CONFIG_SERIAL9BIT is not set +CONFIG_TS7KVSERIAL=m +CONFIG_SERIAL_EXTENDED=y +CONFIG_SERIAL_MANY_PORTS=y +CONFIG_SERIAL_SHARE_IRQ=y +# CONFIG_SERIAL_DETECT_IRQ is not set +# CONFIG_SERIAL_MULTIPORT is not set +# CONFIG_HUB6 is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -565,6 +740,11 @@ # CONFIG_SERIAL_ANAKIN is not set # CONFIG_SERIAL_ANAKIN_CONSOLE is not set # CONFIG_SERIAL_AMBA is not set +CONFIG_SERIAL_TSUART=m +# CONFIG_SERIAL_TSUART7260 is not set +# CONFIG_SERIAL_TSUART73 is not set +# CONFIG_SERIAL_TSUART940 is not set +CONFIG_SERIAL_TSUART3BAT=m CONFIG_SERIAL_EP93XX=y # CONFIG_SERIAL_AMBA is not set CONFIG_SERIAL_AMBA_CONSOLE=y @@ -605,6 +785,10 @@ # 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 @@ -618,6 +802,36 @@ # 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 @@ -629,10 +843,12 @@ # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200 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_RTC=y +CONFIG_TS_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -642,6 +858,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -653,6 +873,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 @@ -662,6 +883,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 @@ -676,7 +898,17 @@ # CONFIG_JFFS_FS is not set CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 -# CONFIG_CRAMFS is not set +# CONFIG_JFFS2_FS_NAND is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_LZO is not set +# CONFIG_JFFS2_LZARI is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +# CONFIG_JFFS2_PROC is not set +CONFIG_CRAMFS=m # CONFIG_TMPFS is not set CONFIG_RAMFS=y # CONFIG_ISO9660_FS is not set @@ -704,6 +936,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -712,6 +949,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 @@ -730,6 +968,8 @@ # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set # CONFIG_ZISOFS_FS is not set +CONFIG_YAFFS_FS=m +# CONFIG_YAFFS2_FS is not set # # Partition Types @@ -782,6 +1022,48 @@ # CONFIG_NLS_UTF8 is not set # +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_FB_TS7KV=m +# CONFIG_FB_TS7300 is not set +# CONFIG_FB_ACORN is not set +# CONFIG_FB_EP93XX is not set +# CONFIG_FB_ANAKIN is not set +# CONFIG_FB_CLPS711X is not set +# CONFIG_FB_SA1100 is not set +# CONFIG_FB_DBMX1 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FBCON_ADVANCED is not set +# 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=m +# 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 is not set @@ -800,50 +1082,91 @@ # CONFIG_USB=m # CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# CONFIG_USB_DEVICEFS=y # 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 is not set # CONFIG_USB_OHCI_SA1111 is not set +# CONFIG_USB_SL811HS_ALT is not set +# CONFIG_USB_SL811HS is not set CONFIG_USB_OHCI_EP93XX=m + +# +# USB Device Class drivers +# # CONFIG_USB_AUDIO is not set # CONFIG_USB_EMI26 is not set -# CONFIG_USB_BLUETOOTH is not set + +# +# USB Bluetooth can only be used with disabled Bluetooth subsystem +# # CONFIG_USB_MIDI is not set CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set CONFIG_USB_STORAGE_DATAFAB=y CONFIG_USB_STORAGE_FREECOM=y -CONFIG_USB_STORAGE_ISD200=y +# CONFIG_USB_STORAGE_ISD200 is not set CONFIG_USB_STORAGE_DPCM=y CONFIG_USB_STORAGE_HP8200e=y CONFIG_USB_STORAGE_SDDR09=y CONFIG_USB_STORAGE_SDDR55=y CONFIG_USB_STORAGE_JUMPSHOT=y -# CONFIG_USB_ACM is not set +CONFIG_USB_ACM=m # CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# CONFIG_USB_HID=m -# CONFIG_USB_HIDINPUT is not set -CONFIG_USB_HIDDEV=y +CONFIG_USB_HIDINPUT=y +# 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=m CONFIG_USB_RTL8150=m CONFIG_USB_KAWETH=m CONFIG_USB_CATC=m CONFIG_USB_CDCETHER=m CONFIG_USB_USBNET=m + +# +# USB port drivers +# # CONFIG_USB_USS720 is not set # @@ -883,6 +1206,10 @@ # 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 @@ -890,9 +1217,37 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # -# CONFIG_BLUEZ is not set +CONFIG_BLUEZ=m +CONFIG_BLUEZ_L2CAP=m +CONFIG_BLUEZ_SCO=m +CONFIG_BLUEZ_RFCOMM=m +CONFIG_BLUEZ_RFCOMM_TTY=y +CONFIG_BLUEZ_BNEP=m +# CONFIG_BLUEZ_BNEP_MC_FILTER is not set +# CONFIG_BLUEZ_BNEP_PROTO_FILTER is not set + +# +# Bluetooth device drivers +# +CONFIG_BLUEZ_HCIUSB=m +CONFIG_BLUEZ_HCIUSB_SCO=y +CONFIG_BLUEZ_HCIUART=m +CONFIG_BLUEZ_HCIUART_H4=y +CONFIG_BLUEZ_HCIUART_BCSP=y +CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y +CONFIG_BLUEZ_HCIBFUSB=m +# CONFIG_BLUEZ_HCIDTL1 is not set +# CONFIG_BLUEZ_HCIBT3C is not set +# CONFIG_BLUEZ_HCIBLUECARD is not set +# CONFIG_BLUEZ_HCIBTUART is not set +CONFIG_BLUEZ_HCIVHCI=m # # Kernel hacking @@ -915,5 +1270,8 @@ # # Library routines # +# CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y +# CONFIG_REED_SOLOMON is not set +CONFIG_FW_LOADER=m Index: arch/arm/def-configs/ts7250 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/ts7250,v retrieving revision 1.1 retrieving revision 1.6 diff -u -r1.1 -r1.6 --- arch/arm/def-configs/ts7250 16 Nov 2004 17:17:28 -0000 1.1 +++ arch/arm/def-configs/ts7250 27 Apr 2006 20:55:24 -0000 1.6 @@ -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 @@ -51,6 +51,10 @@ # # Archimedes/A5000 Implementations # + +# +# Archimedes/A5000 Implementations (select only ONE) +# # CONFIG_ARCH_ARC is not set # CONFIG_ARCH_A5K is not set @@ -137,7 +141,11 @@ # # EP9301 Options # -CONFIG_EP93XX_DMA=y +# CONFIG_EP93XX_DMA is not set + +# +# Processor Type +# CONFIG_CPU_32=y # CONFIG_CPU_26 is not set # CONFIG_CPU_ARM610 is not set @@ -154,6 +162,10 @@ # CONFIG_CPU_SA1100 is not set # CONFIG_CPU_32v3 is not set CONFIG_CPU_32v4=y + +# +# Processor Features +# # CONFIG_ARM_THUMB is not set # CONFIG_CPU_ICACHE_DISABLE is not set # CONFIG_CPU_DCACHE_DISABLE is not set @@ -182,6 +194,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_NWFPE_XP is not set # CONFIG_FPE_FASTFPE is not set @@ -201,6 +217,11 @@ # CONFIG_PARPORT is not set # +# Memory Technology Devices (MTD) for 2k NAND flash +# +# CONFIG_MTD2K is not set + +# # Memory Technology Devices (MTD) # CONFIG_MTD=y @@ -210,6 +231,10 @@ # 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 @@ -280,6 +305,10 @@ # 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_DOC2000 is not set # CONFIG_MTD_DOC2001 is not set # CONFIG_MTD_DOC2001PLUS is not set @@ -308,6 +337,7 @@ # # Block devices # +# CONFIG_BLK_DEV_TS_SD is not set # CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set @@ -367,6 +397,10 @@ # CONFIG_IP_SCTP is not set # CONFIG_ATM is not set CONFIG_VLAN_8021Q=m + +# +# +# # CONFIG_IPX is not set # CONFIG_ATALK is not set @@ -417,6 +451,8 @@ # CONFIG_ARM_AM79C961A is not set # CONFIG_ARM_CIRRUS is not set CONFIG_CS89x0=m +# CONFIG_OPENETH is not set +# CONFIG_NE2000 is not set CONFIG_EP93XX_ETHERNET=y # CONFIG_SUNLANCE is not set # CONFIG_SUNBMAC is not set @@ -467,7 +503,13 @@ # CONFIG_AIRONET4500_NONCS is not set # CONFIG_AIRONET4500_PROC is not set # CONFIG_HERMES is not set +CONFIG_WLAN_NG=y + +# +# Wireless USB cards +# CONFIG_USB_ATMEL=m +PRISM2_USB=m CONFIG_NET_WIRELESS=y # @@ -492,10 +534,18 @@ # IrDA (infrared) support # CONFIG_IRDA=m + +# +# IrDA protocols +# # CONFIG_IRLAN is not set # CONFIG_IRNET is not set # CONFIG_IRCOMM is not set # 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 @@ -503,9 +553,21 @@ # # 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 @@ -527,12 +589,20 @@ # 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 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 @@ -598,9 +668,11 @@ # # Input core support # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT=m +CONFIG_INPUT_KEYBDEV=m +CONFIG_INPUT_MOUSEDEV=m +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_UINPUT is not set @@ -609,9 +681,16 @@ # # Character devices # -# CONFIG_VT is not set +CONFIG_VT=y +CONFIG_VT_CONSOLE=y CONFIG_SERIAL=y CONFIG_SERIAL_CONSOLE=y +CONFIG_EP93XX_VT=y +# CONFIG_EP93XX_KBD_SPI is not set +CONFIG_EP93XX_KBD_USB=y +# CONFIG_JNS200_SERIAL is not set +# CONFIG_SERIAL9BIT is not set +CONFIG_TS7KVSERIAL=m CONFIG_SERIAL_EXTENDED=y CONFIG_SERIAL_MANY_PORTS=y CONFIG_SERIAL_SHARE_IRQ=y @@ -626,6 +705,8 @@ # CONFIG_SERIAL_ANAKIN is not set # CONFIG_SERIAL_ANAKIN_CONSOLE is not set # CONFIG_SERIAL_AMBA is not set +# CONFIG_SERIAL_TSUART is not set +# CONFIG_SERIAL_TSUART73 is not set CONFIG_SERIAL_EP93XX=y # CONFIG_SERIAL_AMBA is not set CONFIG_SERIAL_AMBA_CONSOLE=y @@ -666,6 +747,10 @@ # 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 @@ -679,6 +764,36 @@ # 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 @@ -805,6 +920,7 @@ # CONFIG_NCPFS_EXTRAS is not set # CONFIG_ZISOFS_FS is not set CONFIG_YAFFS_FS=y +# CONFIG_YAFFS2_FS is not set # # Partition Types @@ -857,6 +973,48 @@ # CONFIG_NLS_UTF8 is not set # +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_FB_TS7KV=m +# CONFIG_FB_TS7300 is not set +# CONFIG_FB_ACORN is not set +# CONFIG_FB_EP93XX is not set +# CONFIG_FB_ANAKIN is not set +# CONFIG_FB_CLPS711X is not set +# CONFIG_FB_SA1100 is not set +# CONFIG_FB_DBMX1 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FBCON_ADVANCED is not set +# 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=m +# 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 is not set @@ -875,8 +1033,16 @@ # CONFIG_USB=m # CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# CONFIG_USB_DEVICEFS=y # 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 @@ -885,8 +1051,16 @@ # CONFIG_USB_SL811HS_ALT is not set # CONFIG_USB_SL811HS is not set CONFIG_USB_OHCI_EP93XX=m + +# +# USB Device Class drivers +# # CONFIG_USB_AUDIO is not set # CONFIG_USB_EMI26 is not set + +# +# USB Bluetooth can only be used with disabled Bluetooth subsystem +# # CONFIG_USB_MIDI is not set CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set @@ -900,26 +1074,50 @@ CONFIG_USB_STORAGE_JUMPSHOT=y CONFIG_USB_ACM=m # CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# CONFIG_USB_HID=m -# CONFIG_USB_HIDINPUT is not set -CONFIG_USB_HIDDEV=y +CONFIG_USB_HIDINPUT=y +# 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=m CONFIG_USB_RTL8150=m CONFIG_USB_KAWETH=m CONFIG_USB_CATC=m CONFIG_USB_CDCETHER=m CONFIG_USB_USBNET=m + +# +# USB port drivers +# # CONFIG_USB_USS720 is not set # @@ -959,6 +1157,10 @@ # 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 Index: arch/arm/def-configs/ts7250_2k =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/ts7250_2k,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- arch/arm/def-configs/ts7250_2k 2 Mar 2006 20:55:24 -0000 1.1 +++ arch/arm/def-configs/ts7250_2k 6 Jun 2006 21:17:52 -0000 1.3 @@ -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 @@ -51,6 +51,10 @@ # # Archimedes/A5000 Implementations # + +# +# Archimedes/A5000 Implementations (select only ONE) +# # CONFIG_ARCH_ARC is not set # CONFIG_ARCH_A5K is not set @@ -138,6 +142,10 @@ # EP9301 Options # # CONFIG_EP93XX_DMA is not set + +# +# Processor Type +# CONFIG_CPU_32=y # CONFIG_CPU_26 is not set # CONFIG_CPU_ARM610 is not set @@ -154,6 +162,10 @@ # CONFIG_CPU_SA1100 is not set # CONFIG_CPU_32v3 is not set CONFIG_CPU_32v4=y + +# +# Processor Features +# # CONFIG_ARM_THUMB is not set # CONFIG_CPU_ICACHE_DISABLE is not set # CONFIG_CPU_DCACHE_DISABLE is not set @@ -182,6 +194,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_NWFPE_XP is not set # CONFIG_FPE_FASTFPE is not set @@ -210,6 +226,10 @@ # 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 @@ -280,6 +300,10 @@ # 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_DOC2000 is not set # CONFIG_MTD_DOC2001 is not set # CONFIG_MTD_DOC2001PLUS is not set @@ -308,7 +332,7 @@ # # Block devices # -# CONFIG_BLK_DEV_TS_SD is not set +# CONFIG_BLK_DEV_SDCARD is not set # CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set @@ -368,6 +392,10 @@ # CONFIG_IP_SCTP is not set # CONFIG_ATM is not set CONFIG_VLAN_8021Q=m + +# +# +# # CONFIG_IPX is not set # CONFIG_ATALK is not set @@ -471,6 +499,10 @@ # CONFIG_AIRONET4500_PROC is not set # CONFIG_HERMES is not set CONFIG_WLAN_NG=y + +# +# Wireless USB cards +# CONFIG_USB_ATMEL=m PRISM2_USB=m CONFIG_NET_WIRELESS=y @@ -497,10 +529,18 @@ # IrDA (infrared) support # CONFIG_IRDA=m + +# +# IrDA protocols +# # CONFIG_IRLAN is not set # CONFIG_IRNET is not set # CONFIG_IRCOMM is not set # 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 @@ -508,9 +548,21 @@ # # 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 @@ -532,12 +584,20 @@ # 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 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 @@ -641,6 +701,10 @@ # CONFIG_SERIAL_ANAKIN_CONSOLE is not set # CONFIG_SERIAL_AMBA is not set # CONFIG_SERIAL_TSUART is not set +CONFIG_SERIAL_TSUART7260=m +# CONFIG_SERIAL_TSUART73 is not set +# CONFIG_SERIAL_TSUART940 is not set +CONFIG_SERIAL_TSUART3BAT=m CONFIG_SERIAL_EP93XX=y # CONFIG_SERIAL_AMBA is not set CONFIG_SERIAL_AMBA_CONSOLE=y @@ -681,6 +745,10 @@ # 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 @@ -701,6 +769,10 @@ # 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 @@ -909,6 +981,7 @@ CONFIG_FB=y CONFIG_DUMMY_CONSOLE=y CONFIG_FB_TS7KV=m +# CONFIG_FB_TS7300 is not set # CONFIG_FB_ACORN is not set # CONFIG_FB_EP93XX is not set # CONFIG_FB_ANAKIN is not set @@ -958,8 +1031,16 @@ # CONFIG_USB=m # CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# CONFIG_USB_DEVICEFS=y # 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 @@ -968,8 +1049,16 @@ # CONFIG_USB_SL811HS_ALT is not set # CONFIG_USB_SL811HS is not set CONFIG_USB_OHCI_EP93XX=m + +# +# USB Device Class drivers +# # CONFIG_USB_AUDIO is not set # CONFIG_USB_EMI26 is not set + +# +# USB Bluetooth can only be used with disabled Bluetooth subsystem +# # CONFIG_USB_MIDI is not set CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set @@ -983,6 +1072,10 @@ CONFIG_USB_STORAGE_JUMPSHOT=y CONFIG_USB_ACM=m # CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# CONFIG_USB_HID=m CONFIG_USB_HIDINPUT=y # CONFIG_USB_HIDDEV is not set @@ -992,17 +1085,37 @@ # 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=m CONFIG_USB_RTL8150=m CONFIG_USB_KAWETH=m CONFIG_USB_CATC=m CONFIG_USB_CDCETHER=m CONFIG_USB_USBNET=m + +# +# USB port drivers +# # CONFIG_USB_USS720 is not set # @@ -1042,6 +1155,10 @@ # 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 Index: arch/arm/def-configs/ts7260 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/ts7260,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- arch/arm/def-configs/ts7260 2 Mar 2006 20:55:55 -0000 1.1 +++ arch/arm/def-configs/ts7260 5 Jun 2006 23:55:11 -0000 1.3 @@ -706,6 +706,10 @@ # CONFIG_SERIAL_ANAKIN_CONSOLE is not set # CONFIG_SERIAL_AMBA is not set CONFIG_SERIAL_TSUART=m +CONFIG_SERIAL_TSUART7260=m +# CONFIG_SERIAL_TSUART73 is not set +# CONFIG_SERIAL_TSUART940 is not set +CONFIG_SERIAL_TSUART3BAT=m CONFIG_SERIAL_EP93XX=y # CONFIG_SERIAL_AMBA is not set CONFIG_SERIAL_AMBA_CONSOLE=y @@ -982,6 +986,7 @@ CONFIG_FB=y CONFIG_DUMMY_CONSOLE=y CONFIG_FB_TS7KV=m +# CONFIG_FB_TS7300 is not set # CONFIG_FB_ACORN is not set # CONFIG_FB_EP93XX is not set # CONFIG_FB_ANAKIN is not set Index: arch/arm/def-configs/ts7300 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/ts7300,v retrieving revision 1.1 retrieving revision 1.4 diff -u -r1.1 -r1.4 --- arch/arm/def-configs/ts7300 30 Mar 2006 18:08:51 -0000 1.1 +++ arch/arm/def-configs/ts7300 5 Jun 2006 23:55:12 -0000 1.4 @@ -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 @@ -51,6 +51,10 @@ # # Archimedes/A5000 Implementations # + +# +# Archimedes/A5000 Implementations (select only ONE) +# # CONFIG_ARCH_ARC is not set # CONFIG_ARCH_A5K is not set @@ -138,6 +142,10 @@ # EP9301 Options # # CONFIG_EP93XX_DMA is not set + +# +# Processor Type +# CONFIG_CPU_32=y # CONFIG_CPU_26 is not set # CONFIG_CPU_ARM610 is not set @@ -154,6 +162,10 @@ # CONFIG_CPU_SA1100 is not set # CONFIG_CPU_32v3 is not set CONFIG_CPU_32v4=y + +# +# Processor Features +# # CONFIG_ARM_THUMB is not set # CONFIG_CPU_ICACHE_DISABLE is not set # CONFIG_CPU_DCACHE_DISABLE is not set @@ -182,6 +194,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_NWFPE_XP is not set # CONFIG_FPE_FASTFPE is not set @@ -192,7 +208,7 @@ # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set # CONFIG_ARTHUR is not set -CONFIG_CMDLINE="root=/dev/mtdblock1 console=ttyAM0,115200" +CONFIG_CMDLINE="root=/dev/ram0 init=/linuxrc console=ttyAM0,115200 printk=4 loops=499712" CONFIG_ALIGNMENT_TRAP=y # @@ -219,7 +235,7 @@ # # Block devices # -CONFIG_BLK_DEV_SDCARD=m +# CONFIG_BLK_DEV_TS_SD is not set # CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set @@ -279,6 +295,10 @@ # CONFIG_IP_SCTP is not set # CONFIG_ATM is not set CONFIG_VLAN_8021Q=m + +# +# +# # CONFIG_IPX is not set # CONFIG_ATALK is not set @@ -382,6 +402,10 @@ # CONFIG_AIRONET4500_PROC is not set # CONFIG_HERMES is not set CONFIG_WLAN_NG=y + +# +# Wireless USB cards +# CONFIG_USB_ATMEL=m PRISM2_USB=m CONFIG_NET_WIRELESS=y @@ -408,10 +432,18 @@ # IrDA (infrared) support # CONFIG_IRDA=m + +# +# IrDA protocols +# # CONFIG_IRLAN is not set # CONFIG_IRNET is not set # CONFIG_IRCOMM is not set # 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 @@ -419,9 +451,21 @@ # # 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 @@ -443,12 +487,20 @@ # 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 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 @@ -552,7 +604,10 @@ # CONFIG_SERIAL_ANAKIN_CONSOLE is not set # CONFIG_SERIAL_AMBA is not set CONFIG_SERIAL_TSUART=m +# CONFIG_SERIAL_TSUART7260 is not set CONFIG_SERIAL_TSUART73=m +# CONFIG_SERIAL_TSUART940 is not set +CONFIG_SERIAL_TSUART3BAT=m CONFIG_SERIAL_EP93XX=y # CONFIG_SERIAL_AMBA is not set CONFIG_SERIAL_AMBA_CONSOLE=y @@ -593,6 +648,10 @@ # 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 @@ -613,6 +672,10 @@ # 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 @@ -871,8 +934,16 @@ # CONFIG_USB=m # CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# CONFIG_USB_DEVICEFS=y # 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 @@ -881,8 +952,16 @@ # CONFIG_USB_SL811HS_ALT is not set # CONFIG_USB_SL811HS is not set CONFIG_USB_OHCI_EP93XX=m + +# +# USB Device Class drivers +# # CONFIG_USB_AUDIO is not set # CONFIG_USB_EMI26 is not set + +# +# USB Bluetooth can only be used with disabled Bluetooth subsystem +# # CONFIG_USB_MIDI is not set CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set @@ -896,6 +975,10 @@ CONFIG_USB_STORAGE_JUMPSHOT=y CONFIG_USB_ACM=m # CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# CONFIG_USB_HID=m CONFIG_USB_HIDINPUT=y # CONFIG_USB_HIDDEV is not set @@ -905,17 +988,37 @@ # 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=m CONFIG_USB_RTL8150=m CONFIG_USB_KAWETH=m CONFIG_USB_CATC=m CONFIG_USB_CDCETHER=m CONFIG_USB_USBNET=m + +# +# USB port drivers +# # CONFIG_USB_USS720 is not set # @@ -955,6 +1058,10 @@ # 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 Index: arch/arm/def-configs/ts7400 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/def-configs/ts7400,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/def-configs/ts7400 13 Nov 2006 18:25:29 -0000 1.1 +++ arch/arm/def-configs/ts7400 13 Dec 2006 18:45:10 -0000 1.2 @@ -641,7 +641,7 @@ # CONFIG_SERIAL_AMBA is not set CONFIG_SERIAL_TSUART=y # CONFIG_SERIAL_TSUART7260 is not set -CONFIG_SERIAL_TSUART73=y +# CONFIG_SERIAL_TSUART73=y # CONFIG_SERIAL_TSUART940 is not set # CONFIG_SERIAL_TSUART3BAT is not set # CONFIG_SERIAL_TSUART4PAC is not set Index: arch/arm/kernel/calls.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/kernel/calls.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/kernel/calls.S 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/kernel/calls.S 4 Aug 2004 01:25:38 -0000 1.2 @@ -115,7 +115,7 @@ .long SYMBOL_NAME(sys_ni_syscall) /* was sys_profil */ .long SYMBOL_NAME(sys_statfs) /* 100 */ .long SYMBOL_NAME(sys_fstatfs) - .long SYMBOL_NAME(sys_ni_syscall) + .long SYMBOL_NAME(sys_ni_syscall) /* 101 was sys_ioperm */ .long SYMBOL_NAME(sys_socketcall) .long SYMBOL_NAME(sys_syslog) .long SYMBOL_NAME(sys_setitimer) @@ -126,7 +126,7 @@ .long SYMBOL_NAME(sys_ni_syscall) /* was sys_uname */ /* 110 */ .long SYMBOL_NAME(sys_ni_syscall) /* was sys_iopl */ .long SYMBOL_NAME(sys_vhangup) - .long SYMBOL_NAME(sys_ni_syscall) + .long SYMBOL_NAME(sys_ni_syscall) /* 112 was sys_idle */ .long SYMBOL_NAME(sys_syscall) /* call a syscall */ .long SYMBOL_NAME(sys_wait4) /* 115 */ .long SYMBOL_NAME(sys_swapoff) @@ -137,7 +137,7 @@ /* 120 */ .long SYMBOL_NAME(sys_clone_wapper) .long SYMBOL_NAME(sys_setdomainname) .long SYMBOL_NAME(sys_newuname) - .long SYMBOL_NAME(sys_ni_syscall) + .long SYMBOL_NAME(sys_ni_syscall) /* 123 was sys_modify_ldt */ .long SYMBOL_NAME(sys_adjtimex) /* 125 */ .long SYMBOL_NAME(sys_mprotect) .long SYMBOL_NAME(sys_sigprocmask) @@ -180,7 +180,7 @@ .long SYMBOL_NAME(sys_arm_mremap) .long SYMBOL_NAME(sys_setresuid16) /* 165 */ .long SYMBOL_NAME(sys_getresuid16) - .long SYMBOL_NAME(sys_ni_syscall) + .long SYMBOL_NAME(sys_ni_syscall) /* 166 was sys_vm86 */ .long SYMBOL_NAME(sys_query_module) .long SYMBOL_NAME(sys_poll) .long SYMBOL_NAME(sys_nfsservctl) Index: arch/arm/kernel/dma-rpc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/kernel/dma-rpc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/kernel/dma-rpc.c 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/kernel/dma-rpc.c 4 Aug 2004 01:25:38 -0000 1.2 @@ -26,19 +26,6 @@ #include #include -#if 0 -typedef enum { - dma_size_8 = 1, - dma_size_16 = 2, - dma_size_32 = 4, - dma_size_128 = 16 -} dma_size_t; - -typedef struct { - dma_size_t transfersize; -} dma_t; -#endif - #define TRANSFER_SIZE 2 #define CURA (0) @@ -48,10 +35,6 @@ #define CR (IOMD_IO0CR - IOMD_IO0CURA) #define ST (IOMD_IO0ST - IOMD_IO0CURA) -#define state_prog_a 0 -#define state_wait_a 1 -#define state_wait_b 2 - static void iomd_get_next_sg(struct scatterlist *sg, dma_t *dma) { unsigned long end, offset, flags = 0; @@ -65,7 +48,7 @@ if (end > PAGE_SIZE) end = PAGE_SIZE; - if (offset + (int) TRANSFER_SIZE > end) + if (offset + TRANSFER_SIZE >= end) flags |= DMA_END_L; sg->length = end - TRANSFER_SIZE; @@ -103,27 +86,31 @@ if (!(status & DMA_ST_INT)) return; - if (status & DMA_ST_OFL && !dma->sg) - break; - - iomd_get_next_sg(&dma->cur_sg, dma); + if ((dma->state ^ status) & DMA_ST_AB) + 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); + dma->state = DMA_ST_AB; 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); + dma->state = 0; break; } + + if (status & DMA_ST_OFL && + dma->cur_sg.length == (DMA_END_S|DMA_END_L)) + break; } while (1); - iomd_writeb(0, base + CR); + dma->state = ~DMA_ST_AB; disable_irq(irq); } @@ -158,6 +145,7 @@ } iomd_writeb(DMA_CR_C, dma_base + CR); + dma->state = DMA_ST_AB; } if (dma->dma_mode == DMA_MODE_READ) @@ -171,13 +159,11 @@ { unsigned long dma_base = dma->dma_base; unsigned long flags; - unsigned int ctrl; local_irq_save(flags); - ctrl = iomd_readb(dma_base + CR); - if (ctrl & DMA_CR_E) + if (dma->state != ~DMA_ST_AB) disable_irq(dma->dma_irq); - iomd_writeb(ctrl & ~DMA_CR_E, dma_base + CR); + iomd_writeb(0, dma_base + CR); local_irq_restore(flags); } Index: arch/arm/kernel/entry-armv.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/kernel/entry-armv.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/kernel/entry-armv.S 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/kernel/entry-armv.S 4 Aug 2004 01:25:38 -0000 1.2 @@ -717,12 +717,11 @@ mrs r9, cpsr @ Enable interrupts if they were tst r3, #I_BIT biceq r9, r9, #I_BIT @ previously - mov r0, r2 @ *** remove once everyones in sync /* * This routine must not corrupt r9 */ #ifdef MULTI_CPU - ldr r4, .LCprocfns @ pass r0, r3 to + ldr r4, .LCprocfns @ pass r2, r3 to mov lr, pc @ processor code ldr pc, [r4] @ call processor specific code #else @@ -828,9 +827,8 @@ stmdb r5, {sp, lr}^ alignment_trap r7, r7, __temp_abt zero_fp - mov r0, r2 @ remove once everyones in sync #ifdef MULTI_CPU - ldr r4, .LCprocfns @ pass r0, r3 to + ldr r4, .LCprocfns @ pass r2, r3 to mov lr, pc @ processor code ldr pc, [r4] @ call processor specific code #else @@ -880,7 +878,8 @@ adrsvc al, r9, ret_from_exception @ r9 = normal FP return adrsvc al, lr, fpundefinstr @ lr = undefined instr return -call_fpe: get_current_task r10 +call_fpe: enable_irq r10 + get_current_task r10 mov r8, #1 strb r8, [r10, #TSK_USED_MATH] @ set current->used_math ldr r4, .LCfp Index: arch/arm/kernel/entry-armv.S.2 =================================================================== RCS file: arch/arm/kernel/entry-armv.S.2 diff -N arch/arm/kernel/entry-armv.S.2 --- arch/arm/kernel/entry-armv.S.2 22 Jul 2004 19:48:58 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1189 +0,0 @@ -/* - * linux/arch/arm/kernel/entry-armv.S - * - * Copyright (C) 1996,1997,1998 Russell King. - * ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Low-level vector interface routines - * - * Note: there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes - * it to save wrong values... Be aware! - */ -#include -#include "entry-header.S" - - -#ifdef IOC_BASE -/* IOC / IOMD based hardware */ -#include - - .equ ioc_base_high, IOC_BASE & 0xff000000 - .equ ioc_base_low, IOC_BASE & 0x00ff0000 - .macro disable_fiq - mov r12, #ioc_base_high - .if ioc_base_low - orr r12, r12, #ioc_base_low - .endif - strb r12, [r12, #0x38] @ Disable FIQ register - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - mov r4, #ioc_base_high @ point at IOC - .if ioc_base_low - orr r4, r4, #ioc_base_low - .endif - ldrb \irqstat, [r4, #IOMD_IRQREQB] @ get high priority first - ldr \base, =irq_prio_h - teq \irqstat, #0 -#ifdef IOMD_BASE - ldreqb \irqstat, [r4, #IOMD_DMAREQ] @ get dma - addeq \base, \base, #256 @ irq_prio_h table size - teqeq \irqstat, #0 - bne 2406f -#endif - ldreqb \irqstat, [r4, #IOMD_IRQREQA] @ get low priority - addeq \base, \base, #256 @ irq_prio_d table size - teqeq \irqstat, #0 -#ifdef IOMD_IRQREQC - ldreqb \irqstat, [r4, #IOMD_IRQREQC] - addeq \base, \base, #256 @ irq_prio_l table size - teqeq \irqstat, #0 -#endif -#ifdef IOMD_IRQREQD - ldreqb \irqstat, [r4, #IOMD_IRQREQD] - addeq \base, \base, #256 @ irq_prio_lc table size - teqeq \irqstat, #0 -#endif -2406: ldrneb \irqnr, [\base, \irqstat] @ get IRQ number - .endm - -/* - * Interrupt table (incorporates priority). Please note that we - * rely on the order of these tables (see above code). - */ - .macro irq_prio_table -irq_prio_h: .byte 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 -#ifdef IOMD_BASE -irq_prio_d: .byte 0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 - .byte 20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 - .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 - .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 - .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 - .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 - .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 - .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 - .byte 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 - .byte 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 - .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 - .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 - .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 - .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 - .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 - .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 -#endif -irq_prio_l: .byte 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 - .byte 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 - .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 - .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 - .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3 - .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3 - .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 - .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 - .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 - .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 - .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 - .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 - .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 - .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 - .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 - .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 -#ifdef IOMD_IRQREQC -irq_prio_lc: .byte 24,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27 - .byte 28,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27 - .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 - .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 - .byte 30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27 - .byte 30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27 - .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 - .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 - .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 - .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 - .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 - .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 - .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 - .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 - .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 - .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 -#endif -#ifdef IOMD_IRQREQD -irq_prio_ld: .byte 40,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43 - .byte 44,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43 - .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45 - .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45 - .byte 46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43 - .byte 46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43 - .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45 - .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45 - .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 - .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 - .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 - .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 - .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 - .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 - .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 - .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 -#endif - .endm - -#elif defined(CONFIG_ARCH_EBSA110) - -#define IRQ_STAT 0xff000000 /* read */ - - .macro disable_fiq - .endm - - .macro get_irqnr_and_base, irqnr, stat, base, tmp - mov \base, #IRQ_STAT - ldrb \stat, [\base] @ get interrupts - mov \irqnr, #0 - tst \stat, #15 - addeq \irqnr, \irqnr, #4 - moveq \stat, \stat, lsr #4 - tst \stat, #3 - addeq \irqnr, \irqnr, #2 - moveq \stat, \stat, lsr #2 - tst \stat, #1 - addeq \irqnr, \irqnr, #1 - moveq \stat, \stat, lsr #1 - tst \stat, #1 @ bit 0 should be set - .endm - - .macro irq_prio_table - .endm - -#elif defined(CONFIG_ARCH_SHARK) - - .macro disable_fiq - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - mov r4, #0xe0000000 - - mov \irqstat, #0x0C - 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 - and \irqnr, \irqnr, #7 - teq \irqnr, #2 - bne 44f -43: mov \irqstat, #0x0C - 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 - and \irqnr, \irqnr, #7 - add \irqnr, \irqnr, #8 -44: teq \irqstat, #0 - .endm - - .macro irq_prio_table - .endm - -#elif defined(CONFIG_FOOTBRIDGE) -#include - - .macro disable_fiq - .endm - - .equ dc21285_high, ARMCSR_BASE & 0xff000000 - .equ dc21285_low, ARMCSR_BASE & 0x00ffffff - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - mov r4, #dc21285_high - .if dc21285_low - orr r4, r4, #dc21285_low - .endif - ldr \irqstat, [r4, #0x180] @ get interrupts - - mov \irqnr, #IRQ_SDRAMPARITY - tst \irqstat, #IRQ_MASK_SDRAMPARITY - bne 1001f - - tst \irqstat, #IRQ_MASK_UART_RX - movne \irqnr, #IRQ_CONRX - bne 1001f - - tst \irqstat, #IRQ_MASK_DMA1 - movne \irqnr, #IRQ_DMA1 - bne 1001f - - tst \irqstat, #IRQ_MASK_DMA2 - movne \irqnr, #IRQ_DMA2 - bne 1001f - - tst \irqstat, #IRQ_MASK_IN0 - movne \irqnr, #IRQ_IN0 - bne 1001f - - tst \irqstat, #IRQ_MASK_IN1 - movne \irqnr, #IRQ_IN1 - bne 1001f - - tst \irqstat, #IRQ_MASK_IN2 - movne \irqnr, #IRQ_IN2 - bne 1001f - - tst \irqstat, #IRQ_MASK_IN3 - movne \irqnr, #IRQ_IN3 - bne 1001f - - tst \irqstat, #IRQ_MASK_PCI - movne \irqnr, #IRQ_PCI - bne 1001f - - tst \irqstat, #IRQ_MASK_DOORBELLHOST - movne \irqnr, #IRQ_DOORBELLHOST - bne 1001f - - tst \irqstat, #IRQ_MASK_I2OINPOST - movne \irqnr, #IRQ_I2OINPOST - bne 1001f - - tst \irqstat, #IRQ_MASK_TIMER1 - movne \irqnr, #IRQ_TIMER1 - bne 1001f - - tst \irqstat, #IRQ_MASK_TIMER2 - movne \irqnr, #IRQ_TIMER2 - bne 1001f - - tst \irqstat, #IRQ_MASK_TIMER3 - movne \irqnr, #IRQ_TIMER3 - bne 1001f - - tst \irqstat, #IRQ_MASK_UART_TX - movne \irqnr, #IRQ_CONTX - bne 1001f - - tst \irqstat, #IRQ_MASK_PCI_ABORT - movne \irqnr, #IRQ_PCI_ABORT - bne 1001f - - tst \irqstat, #IRQ_MASK_PCI_SERR - movne \irqnr, #IRQ_PCI_SERR - bne 1001f - - tst \irqstat, #IRQ_MASK_DISCARD_TIMER - movne \irqnr, #IRQ_DISCARD_TIMER - bne 1001f - - tst \irqstat, #IRQ_MASK_PCI_DPERR - movne \irqnr, #IRQ_PCI_DPERR - bne 1001f - - tst \irqstat, #IRQ_MASK_PCI_PERR - movne \irqnr, #IRQ_PCI_PERR -1001: - .endm - - .macro irq_prio_table - .endm - -#elif defined(CONFIG_ARCH_NEXUSPCI) - - .macro disable_fiq - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - ldr \irqstat, =INTCONT_BASE - ldr \base, =soft_irq_mask - ldr \irqstat, [\irqstat] @ get interrupts - ldr \base, [\base] - mov \irqnr, #0 - and \irqstat, \irqstat, \base @ mask out disabled ones -1001: tst \irqstat, #1 - addeq \irqnr, \irqnr, #1 - moveq \irqstat, \irqstat, lsr #1 - tsteq \irqnr, #32 - beq 1001b - teq \irqnr, #32 - .endm - - .macro irq_prio_table - .ltorg - .bss -ENTRY(soft_irq_mask) - .word 0 - .text - .endm - -#elif defined(CONFIG_ARCH_TBOX) - - .macro disable_fiq - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - ldr \irqstat, =0xffff7000 - ldr \irqstat, [\irqstat] @ get interrupts - ldr \base, =soft_irq_mask - ldr \base, [\base] - mov \irqnr, #0 - and \irqstat, \irqstat, \base @ mask out disabled ones -1001: tst \irqstat, #1 - addeq \irqnr, \irqnr, #1 - moveq \irqstat, \irqstat, lsr #1 - tsteq \irqnr, #32 - beq 1001b - teq \irqnr, #32 - .endm - - .macro irq_prio_table - .ltorg - .bss -ENTRY(soft_irq_mask) - .word 0 - .text - .endm - -#elif defined(CONFIG_ARCH_SA1100) - - .macro disable_fiq - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - mov r4, #0xfa000000 @ ICIP = 0xfa050000 - add r4, r4, #0x00050000 - ldr \irqstat, [r4] @ get irqs - ldr \irqnr, [r4, #4] @ ICMR = 0xfa050004 - ands \irqstat, \irqstat, \irqnr - mov \irqnr, #0 - beq 1001f - tst \irqstat, #0xff - moveq \irqstat, \irqstat, lsr #8 - addeq \irqnr, \irqnr, #8 - tsteq \irqstat, #0xff - moveq \irqstat, \irqstat, lsr #8 - addeq \irqnr, \irqnr, #8 - tsteq \irqstat, #0xff - moveq \irqstat, \irqstat, lsr #8 - addeq \irqnr, \irqnr, #8 - tst \irqstat, #0x0f - moveq \irqstat, \irqstat, lsr #4 - addeq \irqnr, \irqnr, #4 - tst \irqstat, #0x03 - moveq \irqstat, \irqstat, lsr #2 - addeq \irqnr, \irqnr, #2 - tst \irqstat, #0x01 - addeqs \irqnr, \irqnr, #1 -1001: - .endm - - .macro irq_prio_table - .endm - -#elif defined(CONFIG_ARCH_L7200) -#include - - .equ irq_base_addr, IO_BASE_2 - - .macro disable_fiq - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - mov \irqstat, #irq_base_addr @ Virt addr IRQ regs - add \irqstat, \irqstat, #0x00001000 @ Status reg - ldr \irqstat, [\irqstat, #0] @ get interrupts - mov \irqnr, #0 -1001: tst \irqstat, #1 - addeq \irqnr, \irqnr, #1 - moveq \irqstat, \irqstat, lsr #1 - tsteq \irqnr, #32 - beq 1001b - teq \irqnr, #32 - .endm - - .macro irq_prio_table - .endm - -#elif defined(CONFIG_ARCH_INTEGRATOR) - - .macro disable_fiq - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp -/* FIXME: should not be using soo many LDRs here */ - ldr \irqnr, =IO_ADDRESS(INTEGRATOR_IC_BASE) - ldr \irqstat, [\irqnr, #IRQ_STATUS] @ get masked status - ldr \irqnr, =IO_ADDRESS(INTEGRATOR_HDR_BASE) - ldr \irqnr, [\irqnr, #(INTEGRATOR_HDR_IC_OFFSET+IRQ_STATUS)] - orr \irqstat, \irqstat, \irqnr, lsl #INTEGRATOR_CM_INT0 - - mov \irqnr, #0 -1001: tst \irqstat, #1 - bne 1002f - add \irqnr, \irqnr, #1 - mov \irqstat, \irqstat, lsr #1 - cmp \irqnr, #22 - bcc 1001b -1002: /* EQ will be set if we reach 22 */ - .endm - - .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 - .endm -#define AITC_NIVECSR 0x40 - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - ldr \irqstat, =IO_ADDRESS(MX1ADS_AITC_BASE) - @ Load offset & priority of the highest priority - @ interrupt pending. - ldr \irqnr, [\irqstat, #AITC_NIVECSR] - @ Shift off the priority leaving the offset or - @ "interrupt number" - mov \irqnr, \irqnr, lsr #16 - ldr \irqstat, =1 @ dummy compare - ldr \base, =0xFFFF // invalid interrupt - cmp \irqnr, \base - bne 1001f - ldr \irqstat, =0 -1001: - tst \irqstat, #1 @ to make the condition code = TRUE - .endm - - .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 - - .macro disable_fiq - .endm - -#if (INTSR2 - INTSR1) != (INTMR2 - INTMR1) -#error INTSR stride != INTMR stride -#endif - - .macro get_irqnr_and_base, irqnr, stat, base, mask - mov \base, #CLPS7111_BASE - ldr \stat, [\base, #INTSR1] - ldr \mask, [\base, #INTMR1] - mov \irqnr, #4 - mov \mask, \mask, lsl #16 - and \stat, \stat, \mask, lsr #16 - movs \stat, \stat, lsr #4 - bne 1001f - - add \base, \base, #INTSR2 - INTSR1 - ldr \stat, [\base, #INTSR1] - ldr \mask, [\base, #INTMR1] - mov \irqnr, #16 - mov \mask, \mask, lsl #16 - and \stat, \stat, \mask, lsr #16 - -1001: tst \stat, #255 - addeq \irqnr, \irqnr, #8 - moveq \stat, \stat, lsr #8 - tst \stat, #15 - addeq \irqnr, \irqnr, #4 - moveq \stat, \stat, lsr #4 - tst \stat, #3 - addeq \irqnr, \irqnr, #2 - moveq \stat, \stat, lsr #2 - tst \stat, #1 - addeq \irqnr, \irqnr, #1 - moveq \stat, \stat, lsr #1 - tst \stat, #1 @ bit 0 should be set - .endm - - .macro irq_prio_table - .endm - -#elif defined (CONFIG_ARCH_CAMELOT) -#include -#undef IRQ_MODE /* same name defined in asm/proc/ptrace.h */ -#include - - .macro disable_fiq - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - - ldr \irqstat, =INT_ID(IO_ADDRESS(EXC_INT_CTRL00_BASE)) - ldr \irqnr,[\irqstat] - cmp \irqnr,#0 - subne \irqnr,\irqnr,#1 - - - .endm - - .macro irq_prio_table - .endm - -#elif defined(CONFIG_ARCH_ANAKIN) - - .macro disable_fiq - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - mov \base, #IO_BASE - mov \irqstat, #INTERRUPT_CONTROLLER - ldr \tmp, =anakin_irq_mask - ldr \irqstat, [\base, \irqstat] - ldr \tmp, [\tmp] - ands \irqstat, \irqstat, \tmp - ldrne \tmp, =anakin_active_irqs - strne \irqstat, [\tmp] - movne \irqnr, #IRQ_ANAKIN - .endm - - .macro irq_prio_table - .ltorg - .bss -ENTRY(anakin_irq_mask) - .word 0 -ENTRY(anakin_active_irqs) - .space 4 - .text - .endm - -#else -#error Unknown architecture -#endif - -/* - * Invalid mode handlers - */ -__pabt_invalid: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go - stmia sp, {r0 - lr} @ Save XXX r0 - lr - ldr r4, .LCabt - mov r1, #BAD_PREFETCH - b 1f - -__dabt_invalid: sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - lr} @ Save SVC r0 - lr [lr *should* be intact] - ldr r4, .LCabt - mov r1, #BAD_DATA - b 1f - -__irq_invalid: sub sp, sp, #S_FRAME_SIZE @ Allocate space on stack for frame - stmfd sp, {r0 - lr} @ Save r0 - lr - ldr r4, .LCirq - mov r1, #BAD_IRQ - b 1f - -__und_invalid: sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - lr} - ldr r4, .LCund - mov r1, #BAD_UNDEFINSTR @ int reason - -1: zero_fp - ldmia r4, {r5 - r7} @ Get XXX pc, cpsr, old_r0 - add r4, sp, #S_PC - stmia r4, {r5 - r7} @ Save XXX pc, cpsr, old_r0 - mov r0, sp - and r2, r6, #31 @ int mode - b SYMBOL_NAME(bad_mode) - -/* 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 - * operation. This is a hack to allow some basic userland binaries - * to run so that the emulator module proper can be loaded. --philb - */ -fpe_not_present: - mov pc, lr - -/* - * SVC mode handlers - */ - .align 5 -__dabt_svc: sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} @ save r0 - r12 - ldr r2, .LCabt - add r0, sp, #S_FRAME_SIZE - ldmia r2, {r2 - r4} @ get pc, cpsr - add r5, sp, #S_SP - mov r1, lr - stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro - mrs r9, cpsr @ Enable interrupts if they were - tst r3, #I_BIT - biceq r9, r9, #I_BIT @ previously - mov r0, r2 @ *** remove once everyones in sync -/* - * This routine must not corrupt r9 - */ -#ifdef MULTI_CPU - ldr r4, .LCprocfns @ pass r0, r3 to - mov lr, pc @ processor code - ldr pc, [r4] @ call processor specific code -#else - bl cpu_data_abort -#endif - msr cpsr_c, r9 - mov r2, sp - bl SYMBOL_NAME(do_DataAbort) - mov r0, #I_BIT | MODE_SVC - msr cpsr_c, r0 - ldr r0, [sp, #S_PSR] - msr spsr, r0 - ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr - - .align 5 -__irq_svc: sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} @ save r0 - r12 - ldr r7, .LCirq - add r5, sp, #S_FRAME_SIZE - ldmia r7, {r7 - r9} - add r4, sp, #S_SP - mov r6, lr - stmia r4, {r5, r6, r7, r8, r9} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro - tst sp, #0x1000 - streq sp, [sp, -sp] -1: get_irqnr_and_base r0, r6, r5, lr - movne r1, sp - @ - @ routine called with r0 = irq number, r1 = struct pt_regs * - @ - adrsvc ne, lr, 1b - 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 - ldr r7, .LCund - mov r6, lr - ldmia r7, {r7 - r9} - add r5, sp, #S_FRAME_SIZE - add r4, sp, #S_SP - stmia r4, {r5 - r9} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro - tst sp, #0x1000 - streq sp, [sp, -sp] - - adrsvc al, r9, 1f @ r9 = normal FP return - bl call_fpe @ lr = undefined instr return - - mov r0, r5 @ unsigned long pc - mov r1, sp @ struct pt_regs *regs - bl SYMBOL_NAME(do_undefinstr) - -1: mov r0, #I_BIT | MODE_SVC - msr cpsr_c, r0 - ldr lr, [sp, #S_PSR] @ Get SVC cpsr - msr spsr, lr - ldmia sp, {r0 - pc}^ @ Restore SVC registers - - .align 5 -__pabt_svc: sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} @ save r0 - r12 - ldr r2, .LCabt - add r0, sp, #S_FRAME_SIZE - ldmia r2, {r2 - r4} @ get pc, cpsr - add r5, sp, #S_SP - mov r1, lr - stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro - tst sp, #0x1000 - streq sp, [sp, -sp] - mrs r9, cpsr @ Enable interrupts if they were - tst r3, #I_BIT - biceq r9, r9, #I_BIT @ previously - msr cpsr_c, r9 - mov r0, r2 @ address (pc) - mov r1, sp @ regs - bl SYMBOL_NAME(do_PrefetchAbort) @ call abort handler - mov r0, #I_BIT | MODE_SVC - msr cpsr_c, r0 - ldr r0, [sp, #S_PSR] - msr spsr, r0 - ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr - - .align 5 -.LCirq: .word __temp_irq -.LCund: .word __temp_und -.LCabt: .word __temp_abt -#ifdef MULTI_CPU -.LCprocfns: .word SYMBOL_NAME(processor) -#endif -.LCfp: .word SYMBOL_NAME(fp_enter) - - irq_prio_table - -/* - * User mode handlers - */ - .align 5 -__dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go - stmia sp, {r0 - r12} @ save r0 - r12 - ldr r7, .LCabt - add r5, sp, #S_PC - ldmia r7, {r2 - r4} @ Get USR pc, cpsr - stmia r5, {r2 - r4} @ Save USR pc, cpsr, old_r0 - stmdb r5, {sp, lr}^ - alignment_trap r7, r7, __temp_abt - zero_fp - tst sp, #0x1000 - streq sp, [sp, -sp] - mov r0, r2 @ remove once everyones in sync -#ifdef MULTI_CPU - ldr r4, .LCprocfns @ pass r0, r3 to - mov lr, pc @ processor code - ldr pc, [r4] @ call processor specific code -#else - bl cpu_data_abort -#endif - mov r2, #MODE_SVC - msr cpsr_c, r2 @ Enable interrupts - mov r2, sp - adrsvc al, lr, ret_from_exception - b SYMBOL_NAME(do_DataAbort) - - .align 5 -__irq_usr: sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} @ save r0 - r12 - ldr r4, .LCirq - add r8, sp, #S_PC - ldmia r4, {r5 - r7} @ get saved PC, SPSR - stmia r8, {r5 - r7} @ save pc, psr, old_r0 - stmdb r8, {sp, lr}^ - alignment_trap r4, r7, __temp_irq - zero_fp - tst sp, #0x1000 - streq sp, [sp, -sp] -1: get_irqnr_and_base r0, r6, r5, lr - movne r1, sp - adrsvc ne, lr, 1b - @ - @ routine called with r0 = irq number, r1 = struct pt_regs * - @ - 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 - ldr r4, .LCund - add r8, sp, #S_PC - ldmia r4, {r5 - r7} - stmia r8, {r5 - r7} @ Save USR pc, cpsr, old_r0 - stmdb r8, {sp, lr}^ @ Save user sp, lr - alignment_trap r4, r7, __temp_und - zero_fp - tst sp, #0x1000 - streq sp, [sp, -sp] - 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 - -call_fpe: get_current_task r10 - mov r8, #1 - strb r8, [r10, #TSK_USED_MATH] @ set current->used_math - ldr r4, .LCfp - add r10, r10, #TSS_FPESAVE @ r10 = workspace - ldr pc, [r4] @ Call FP module USR entry point - -fpundefinstr: mov r0, #MODE_SVC - msr cpsr_c, r0 @ Enable interrupts - mov r0, lr - mov r1, sp - adrsvc al, lr, ret_from_exception - b SYMBOL_NAME(do_undefinstr) - - .align 5 -__pabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go - stmia sp, {r0 - r12} @ Save r0 - r12 - ldr r4, .LCabt - add r8, sp, #S_PC - ldmia r4, {r5 - r7} @ Get USR pc, cpsr - stmia r8, {r5 - r7} @ Save USR pc, cpsr, old_r0 - stmdb r8, {sp, lr}^ @ Save sp_usr lr_usr - alignment_trap r4, r7, __temp_abt - zero_fp - tst sp, #0x1000 - streq sp, [sp, -sp] - mov r0, #MODE_SVC - msr cpsr_c, r0 @ Enable interrupts - mov r0, r5 @ address (pc) - mov r1, sp @ regs - bl SYMBOL_NAME(do_PrefetchAbort) @ call abort handler - /* fall through */ -/* - * This is the return code to user mode for abort handlers - */ -ENTRY(ret_from_exception) - disable_irq r1 - mov why, #0 - get_current_task tsk - b ret_to_user - - .data -ENTRY(fp_enter) - .word fpe_not_present - .text -/* - * Register switch for ARMv3 and ARMv4 processors - * r0 = previous, r1 = next, return previous. - * previous and next are guaranteed not to be the same. - */ -ENTRY(__switch_to) - stmfd sp!, {r4 - sl, fp, lr} @ Store most regs on stack - mrs ip, cpsr - str ip, [sp, #-4]! @ Save cpsr_SVC - str sp, [r0, #TSS_SAVE] @ Save sp_SVC - tst sp, #0x1000 - streq sp, [sp, -sp] - ldr sp, [r1, #TSS_SAVE] @ Get saved sp_SVC - tst sp, #0x1000 - streq sp, [sp, -sp] - ldr r2, [r1, #TSS_DOMAIN] - ldr ip, [sp], #4 - mcr p15, 0, r2, c3, c0 @ Set domain register - msr spsr, ip @ Save tasks CPSR into SPSR for this return - ldmfd sp!, {r4 - sl, fp, pc}^ @ Load all regs saved previously - - .section ".text.init",#alloc,#execinstr -/* - * Vector stubs. NOTE that we only align 'vector_IRQ' to a cache line boundary, - * and we rely on each stub being exactly 48 (1.5 cache lines) in size. This - * means that we only ever load two cache lines for this code, or one if we're - * lucky. We also copy this code to 0x200 so that we can use branches in the - * vectors, rather than ldr's. - */ - .align 5 -__stubs_start: -/* - * Interrupt dispatcher - * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC - */ -vector_IRQ: @ - @ save mode specific registers - @ - ldr r13, .LCsirq - sub lr, lr, #4 - str lr, [r13] @ save lr_IRQ - mrs lr, spsr - str lr, [r13, #4] @ save spsr_IRQ - @ - @ now branch to the relevent MODE handling routine - @ - 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 - ldr lr, [pc, lr, lsl #2] - movs pc, lr @ Changes mode and branches - -.LCtab_irq: .word __irq_usr @ 0 (USR_26 / USR_32) - .word __irq_invalid @ 1 (FIQ_26 / FIQ_32) - .word __irq_invalid @ 2 (IRQ_26 / IRQ_32) - .word __irq_svc @ 3 (SVC_26 / SVC_32) - .word __irq_invalid @ 4 - .word __irq_invalid @ 5 - .word __irq_invalid @ 6 - .word __irq_invalid @ 7 - .word __irq_invalid @ 8 - .word __irq_invalid @ 9 - .word __irq_invalid @ a - .word __irq_invalid @ b - .word __irq_invalid @ c - .word __irq_invalid @ d - .word __irq_invalid @ e - .word __irq_invalid @ f - - .align 5 - -/* - * Data abort dispatcher - dispatches it to the correct handler for the processor mode - * Enter in ABT mode, spsr = USR CPSR, lr = USR PC - */ -vector_data: @ - @ save mode specific registers - @ - ldr r13, .LCsabt - sub lr, lr, #8 - str lr, [r13] - mrs lr, spsr - str lr, [r13, #4] - @ - @ now branch to the relevent MODE handling routine - @ - 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 - ldr lr, [pc, lr, lsl #2] - movs pc, lr @ Changes mode and branches - -.LCtab_dabt: .word __dabt_usr @ 0 (USR_26 / USR_32) - .word __dabt_invalid @ 1 (FIQ_26 / FIQ_32) - .word __dabt_invalid @ 2 (IRQ_26 / IRQ_32) - .word __dabt_svc @ 3 (SVC_26 / SVC_32) - .word __dabt_invalid @ 4 - .word __dabt_invalid @ 5 - .word __dabt_invalid @ 6 - .word __dabt_invalid @ 7 - .word __dabt_invalid @ 8 - .word __dabt_invalid @ 9 - .word __dabt_invalid @ a - .word __dabt_invalid @ b - .word __dabt_invalid @ c - .word __dabt_invalid @ d - .word __dabt_invalid @ e - .word __dabt_invalid @ f - - .align 5 - -/* - * Prefetch abort dispatcher - dispatches it to the correct handler for the processor mode - * Enter in ABT mode, spsr = USR CPSR, lr = USR PC - */ -vector_prefetch: - @ - @ save mode specific registers - @ - ldr r13, .LCsabt - sub lr, lr, #4 - str lr, [r13] @ save lr_ABT - mrs lr, spsr - str lr, [r13, #4] @ save spsr_ABT - @ - @ now branch to the relevent MODE handling routine - @ - 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 - ldr lr, [pc, lr, lsl #2] - movs pc, lr - -.LCtab_pabt: .word __pabt_usr @ 0 (USR_26 / USR_32) - .word __pabt_invalid @ 1 (FIQ_26 / FIQ_32) - .word __pabt_invalid @ 2 (IRQ_26 / IRQ_32) - .word __pabt_svc @ 3 (SVC_26 / SVC_32) - .word __pabt_invalid @ 4 - .word __pabt_invalid @ 5 - .word __pabt_invalid @ 6 - .word __pabt_invalid @ 7 - .word __pabt_invalid @ 8 - .word __pabt_invalid @ 9 - .word __pabt_invalid @ a - .word __pabt_invalid @ b - .word __pabt_invalid @ c - .word __pabt_invalid @ d - .word __pabt_invalid @ e - .word __pabt_invalid @ f - - .align 5 - -/* - * Undef instr entry dispatcher - dispatches it to the correct handler for the processor mode - * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC - */ -vector_undefinstr: - @ - @ save mode specific registers - @ - ldr r13, .LCsund - str lr, [r13] @ save lr_UND - mrs lr, spsr - str lr, [r13, #4] @ save spsr_UND - @ - @ now branch to the relevent MODE handling routine - @ - 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 - ldr lr, [pc, lr, lsl #2] - movs pc, lr @ Changes mode and branches - -.LCtab_und: .word __und_usr @ 0 (USR_26 / USR_32) - .word __und_invalid @ 1 (FIQ_26 / FIQ_32) - .word __und_invalid @ 2 (IRQ_26 / IRQ_32) - .word __und_svc @ 3 (SVC_26 / SVC_32) - .word __und_invalid @ 4 - .word __und_invalid @ 5 - .word __und_invalid @ 6 - .word __und_invalid @ 7 - .word __und_invalid @ 8 - .word __und_invalid @ 9 - .word __und_invalid @ a - .word __und_invalid @ b - .word __und_invalid @ c - .word __und_invalid @ d - .word __und_invalid @ e - .word __und_invalid @ f - - .align 5 - -/*============================================================================= - * Undefined FIQs - *----------------------------------------------------------------------------- - * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC - * MUST PRESERVE SVC SPSR, but need to switch to SVC mode to show our msg. - * Basically to switch modes, we *HAVE* to clobber one register... brain - * damage alert! I don't think that we can execute any code in here in any - * other mode than FIQ... Ok you can switch to another mode, but you can't - * get out of that mode without clobbering one register. - */ -vector_FIQ: disable_fiq - subs pc, lr, #4 - -/*============================================================================= - * Address exception handler - *----------------------------------------------------------------------------- - * These aren't too critical. - * (they're not supposed to happen, and won't happen in 32-bit data mode). - */ - -vector_addrexcptn: - b vector_addrexcptn - -/* - * We group all the following data together to optimise - * for CPUs with separate I & D caches. - */ - .align 5 - -.LCvswi: .word vector_swi - -.LCsirq: .word __temp_irq -.LCsund: .word __temp_und -.LCsabt: .word __temp_abt - -__stubs_end: - - .equ __real_stubs_start, .LCvectors + 0x200 - -.LCvectors: swi SYS_ERROR0 - b __real_stubs_start + (vector_undefinstr - __stubs_start) - ldr pc, __real_stubs_start + (.LCvswi - __stubs_start) - b __real_stubs_start + (vector_prefetch - __stubs_start) - b __real_stubs_start + (vector_data - __stubs_start) - b __real_stubs_start + (vector_addrexcptn - __stubs_start) - b __real_stubs_start + (vector_IRQ - __stubs_start) - b __real_stubs_start + (vector_FIQ - __stubs_start) - -ENTRY(__trap_init) - stmfd sp!, {r4 - r6, lr} - - adr r1, .LCvectors @ set up the vectors - ldmia r1, {r1, r2, r3, r4, r5, r6, ip, lr} - stmia r0, {r1, r2, r3, r4, r5, r6, ip, lr} - - add r2, r0, #0x200 - adr r0, __stubs_start @ copy stubs to 0x200 - adr r1, __stubs_end -1: ldr r3, [r0], #4 - str r3, [r2], #4 - cmp r0, r1 - blt 1b - LOADREGS(fd, sp!, {r4 - r6, pc}) - - .data - -/* - * Do not reorder these, and do not insert extra data between... - */ - -__temp_irq: .word 0 @ saved lr_irq - .word 0 @ saved spsr_irq - .word -1 @ old_r0 -__temp_und: .word 0 @ Saved lr_und - .word 0 @ Saved spsr_und - .word -1 @ old_r0 -__temp_abt: .word 0 @ Saved lr_abt - .word 0 @ Saved spsr_abt - .word -1 @ old_r0 - - .globl SYMBOL_NAME(cr_alignment) - .globl SYMBOL_NAME(cr_no_alignment) -SYMBOL_NAME(cr_alignment): - .space 4 -SYMBOL_NAME(cr_no_alignment): - .space 4 Index: arch/arm/kernel/fiq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/kernel/fiq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/kernel/fiq.c 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/kernel/fiq.c 4 Aug 2004 01:25:38 -0000 1.2 @@ -122,23 +122,23 @@ register unsigned long tmp, tmp2; __asm__ volatile ( #ifdef CONFIG_CPU_26 - "mov %0, pc - bic %1, %0, #0x3 - orr %1, %1, %3 - teqp %1, #0 @ select FIQ mode - mov r0, r0 - ldmia %2, {r8 - r14} - teqp %0, #0 @ return to SVC mode - mov r0, r0" + "mov %0, pc \n" + "bic %1, %0, #0x3 \n" + "orr %1, %1, %3 \n" + "teqp %1, #0 @ select FIQ mode \n" + "mov r0, r0 \n" + "ldmia %2, {r8 - r14} \n" + "teqp %0, #0 @ return to SVC mode \n" + "mov r0, r0 \n" #endif #ifdef CONFIG_CPU_32 - "mrs %0, cpsr - mov %1, %3 - msr cpsr_c, %1 @ select FIQ mode - mov r0, r0 - ldmia %2, {r8 - r14} - msr cpsr_c, %0 @ return to SVC mode - mov r0, r0" + "mrs %0, cpsr \n" + "mov %1, %3 \n" + "msr cpsr_c, %1 @ select FIQ mode \n" + "mov r0, r0 \n" + "ldmia %2, {r8 - r14} \n" + "msr cpsr_c, %0 @ return to SVC mode \n" + "mov r0, r0 \n" #endif : "=&r" (tmp), "=&r" (tmp2) : "r" (®s->ARM_r8), "I" (I_BIT | F_BIT | FIQ_MODE) @@ -154,23 +154,23 @@ register unsigned long tmp, tmp2; __asm__ volatile ( #ifdef CONFIG_CPU_26 - "mov %0, pc - bic %1, %0, #0x3 - orr %1, %1, %3 - teqp %1, #0 @ select FIQ mode - mov r0, r0 - stmia %2, {r8 - r14} - teqp %0, #0 @ return to SVC mode - mov r0, r0" + "mov %0, pc \n" + "bic %1, %0, #0x3 \n" + "orr %1, %1, %3 \n" + "teqp %1, #0 @ select FIQ mode \n" + "mov r0, r0 \n" + "stmia %2, {r8 - r14} \n" + "teqp %0, #0 @ return to SVC mode \n" + "mov r0, r0 \n" #endif #ifdef CONFIG_CPU_32 - "mrs %0, cpsr - mov %1, %3 - msr cpsr_c, %1 @ select FIQ mode - mov r0, r0 - stmia %2, {r8 - r14} - msr cpsr_c, %0 @ return to SVC mode - mov r0, r0" + "mrs %0, cpsr \n" + "mov %1, %3 \n" + "msr cpsr_c, %1 @ select FIQ mode \n" + "mov r0, r0 \n" + "stmia %2, {r8 - r14} \n" + "msr cpsr_c, %0 @ return to SVC mode \n" + "mov r0, r0 \n" #endif : "=&r" (tmp), "=&r" (tmp2) : "r" (®s->ARM_r8), "I" (I_BIT | F_BIT | FIQ_MODE) Index: arch/arm/kernel/head-armv.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/kernel/head-armv.S,v retrieving revision 1.1 retrieving revision 1.4 diff -u -r1.1 -r1.4 --- arch/arm/kernel/head-armv.S 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/kernel/head-armv.S 7 Jul 2006 18:10:43 -0000 1.4 @@ -1,7 +1,7 @@ /* * linux/arch/arm/kernel/head-armv.S * - * Copyright (C) 1994-1999 Russell King + * Copyright (C) 1994-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 @@ -184,63 +184,6 @@ mov32 r13, 0x10000 /* End of code for bootloader */ - - /* - * do a write to CLKSET1 to set up the clocks. - * Then do 5 nops to flush the pipe because we're supposed to. - */ - mov32 r0, SYSCON_BASE - mov32 r1, CLKSET1_VALUE - str r1, [r0, #0x20] - nop - nop - nop - nop - nop - - /* - * Program up PLL2 - */ - mov32 r0, SYSCON_BASE - mov32 r1, CLKSET2_VALUE - str r1, [r0, #0x24] - - /* - * Do a 1 mSec delay for PLL2 to stabilize using TC4. - * Enable the TC4 - */ - mov32 r0, TIMERS_BASE - mov32 r1, 0x00000100 - str r1, [r0, #0x64] - - /* - * Get current timer value, add 1000 (uSec) to it. - */ - mov32 r0, TIMER4VALUELOW - ldr r1, [r0] - mov32 r2, 1000 - add r1, r1, r2 - - /* - * Get current timer value, loop until greater than r1 - */ -1: ldr r2, [r0] - cmp r2, r1 - blt 1b - - /* - * Pointer to the Syscon base - */ - mov32 r0, SYSCON_BASE - - /* - * Setup the UARTBAUD bit in the PWRCNT register. This - * enables the 14.7456MHz clock to the UARTs. Everything - * else in this register (DMA, USB, IRDA) is zeroed. - */ - mov32 r1, 0x20000000 - str r1, [r0, #0x04] - #endif /* * TODO - RedBoot does not set 'r1' with our architecture @@ -290,18 +233,16 @@ */ .type __ret, %function __ret: ldr lr, __switch_data - #if defined(CONFIG_ARCH_EP9301) || defined(CONFIG_ARCH_EP9312) || defined(CONFIG_ARCH_EP9315) - /* - * Put us in Async mode - */ - orr r0, r0, #0xC0000000 -#endif - - mcr p15, 0, r0, c1, c0 - mrc p15, 0, r0, c1, c0, 0 @ read it back. - mov r0, r0 - mov r0, r0 + /* + * Put us in Async mode + */ + orr r0, r0, #0xC0000000 + #endif + mcr p15, 0, r0, c1, c0, 0 + mrc p15, 0, r3, c0, c0, 0 + mov r3, r3 + mov r3, r3 mov pc, lr /* @@ -349,6 +290,11 @@ */ __create_page_tables: pgtbl r4, r5 @ page table address +#if defined(CONFIG_CPU_DCACHE_DISABLE) + bic r8, r8, #0x00c @ clear B, C +#elif defined(CONFIG_CPU_DCACHE_WRITETHROUGH) + bic r8, r8, #0x004 @ clear B +#endif /* * Clear the 16K level 1 swapper page table Index: arch/arm/kernel/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/kernel/irq.c,v retrieving revision 1.1 retrieving revision 1.4 diff -u -r1.1 -r1.4 --- arch/arm/kernel/irq.c 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/kernel/irq.c 13 Jan 2009 19:28:09 -0000 1.4 @@ -30,13 +30,34 @@ #include #include #include +#include +#include +#include #include +#include #include #include +#include +#include + #include /* pick up fixup_irq definition */ +static struct proc_dir_entry *root_irq_dir; + +#undef MAX_NAMELEN + +#define MAX_NAMELEN 10 + +struct irq_proc { + unsigned long irq; + wait_queue_head_t q; + atomic_t count; + char devname[TASK_COMM_LEN]; +}; + + /* * Maximum IRQ count. Currently, this is arbitary. However, it should * not be set too low to prevent false triggering. Conversely, if it @@ -104,12 +125,10 @@ struct irqdesc *desc = irq_desc + irq; unsigned long flags; - spin_lock_irqsave(&irq_controller_lock, flags); - + spin_lock_irqsave(&irq_controller_lock, flags); if (!desc->disable_depth) { - // printk("enable_irq(%u) unbalanced from %p\n", irq, - // __builtin_return_address(0)); - //The IRQ has been enabled. just do nothing. + printk("enable_irq(%u) unbalanced from %p\n", irq, + __builtin_return_address(0)); } else if (!--desc->disable_depth) { desc->probing = 0; desc->unmask(irq); @@ -314,6 +333,8 @@ { irq = fixup_irq(irq); + if (irq == 22) + outl((1<<3), GPIO_FEOI); /* * Some hardware gives randomly wrong interrupts. Rather * than crashing, do something sensible. @@ -662,8 +683,180 @@ return irq_found; } +static void irq_proc_irq_handler(int irq, void *vidp, struct pt_regs *regs) +{ + struct irq_proc *idp = (struct irq_proc *)vidp; + + BUG_ON(idp->irq != irq); + disable_irq_nosync(irq); + atomic_inc(&idp->count); + wake_up(&idp->q); + return ; +} + + +static int irq_proc_open(struct inode *inop, struct file *filp) +{ + struct irq_proc *ip; + struct proc_dir_entry *ent = PDE(inop); + int error; + + ip = kmalloc(sizeof *ip, GFP_KERNEL); + if (ip == NULL) + return -ENOMEM; + + memset(ip, 0, sizeof(*ip)); + strcpy(ip->devname, current->comm); + init_waitqueue_head(&ip->q); + atomic_set(&ip->count, 0); + ip->irq = (unsigned long)ent->data; + + error = request_irq(ip->irq, + irq_proc_irq_handler, + SA_INTERRUPT, + ip->devname, + ip); + if (error < 0) { + kfree(ip); + return error; + } + filp->private_data = (void *)ip; + + return 0; +} + +static int irq_proc_release(struct inode *inop, struct file *filp) +{ + struct irq_proc *ip = (struct irq_proc *)filp->private_data; + + free_irq(ip->irq, ip); + filp->private_data = NULL; + kfree(ip); + return 0; +} + +static unsigned int irq_proc_poll(struct file *filp, struct poll_table_struct *wait) +{ + struct irq_proc *ip = (struct irq_proc *)filp->private_data; + +//EWD: we get a warning for the following line(irq_desc_t vs irq_desc) + irq_desc_t *idp = irq_desc + ip->irq; + + if (atomic_read(&ip->count) > 0) + return POLLIN | POLLRDNORM; /* readable */ + + /* if interrupts disabled and we don't have one to process... */ + if (idp->status & IRQ_DISABLED) + enable_irq(ip->irq); + + poll_wait(filp, &ip->q, wait); + + if (atomic_read(&ip->count) > 0) + return POLLIN | POLLRDNORM; /* readable */ + + return 0; +} + + +/* + * Signal to userspace an interrupt has occured. + */ +static ssize_t irq_proc_read(struct file *filp, char /*__user*/ *bufp, size_t len, loff_t *ppos) +{ + struct irq_proc *ip = (struct irq_proc *)filp->private_data; +//EWD: we get a warning for the following line(irq_desc_t vs irq_desc) + irq_desc_t *idp = irq_desc + ip->irq; + int pending; + + DECLARE_WAIT_QUEUE_HEAD(queue); + DECLARE_WAITQUEUE(wait, current); + + if (len < sizeof(int)) + return -EINVAL; + + pending = atomic_read(&ip->count); + if (pending == 0) { + if (idp->status & IRQ_DISABLED) + enable_irq(ip->irq); + if (filp->f_flags & O_NONBLOCK) + return -EWOULDBLOCK; + } + + while (pending == 0) { + add_wait_queue(&queue, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + pending = atomic_read(&ip->count); + if (pending == 0) + schedule(); + remove_wait_queue(&queue, &wait); + if (signal_pending(current)) + return -ERESTARTSYS; + set_current_state(TASK_RUNNING); + } + + if (copy_to_user(bufp, &pending, sizeof pending)) + return -EFAULT; + + *ppos += sizeof pending; + + atomic_sub(pending, &ip->count); + return sizeof pending; +} + + +static struct file_operations irq_proc_file_operations = { + .read = irq_proc_read, + .open = irq_proc_open, + .release = irq_proc_release, + .poll = irq_proc_poll, +}; + +#define MAX_NAMELEN 10 +void register_irq_proc(unsigned int irq) +{ + struct proc_dir_entry *entry; + char name [MAX_NAMELEN]; + + if (!root_irq_dir) + return; + + memset(name, 0, MAX_NAMELEN); + sprintf(name, "%d", irq); + + if (!irq_desc[irq].dir) { + /* create /proc/irq/1234 */ + irq_desc[irq].dir = proc_mkdir(name, root_irq_dir); + + /* + * Create handles for user-mode interrupt handlers + * if the kernel hasn't already grabbed the IRQ + */ + entry = create_proc_entry("irq", 0600, irq_desc[irq].dir); + if (entry) { + entry->data = (void *)(unsigned long)irq; + entry->read_proc = NULL; + entry->write_proc = NULL; + entry->proc_fops = &irq_proc_file_operations; + } + } +} + + void __init init_irq_proc(void) { + int i; + + /* create /proc/irq */ + root_irq_dir = proc_mkdir("irq", NULL); + if (!root_irq_dir) + return; + + /* + * Create entries for all existing IRQs. + */ + for (i = 0; i < NR_IRQS; i++) + register_irq_proc(i); } void __init init_IRQ(void) Index: arch/arm/kernel/isa.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/kernel/isa.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/kernel/isa.c 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/kernel/isa.c 4 Aug 2004 01:25:38 -0000 1.2 @@ -38,7 +38,7 @@ static struct ctl_table_header *isa_sysctl_header; -static ctl_table ctl_isa[2] = {{BUS_ISA, "isa", NULL, 0, 0555, ctl_isa_vars}, +static ctl_table ctl_isa[2] = {{CTL_BUS_ISA, "isa", NULL, 0, 0555, ctl_isa_vars}, {0}}; static ctl_table ctl_bus[2] = {{CTL_BUS, "bus", NULL, 0, 0555, ctl_isa}, {0}}; Index: arch/arm/kernel/ptrace.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/kernel/ptrace.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/kernel/ptrace.c 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/kernel/ptrace.c 4 Aug 2004 01:25:38 -0000 1.2 @@ -725,11 +725,8 @@ goto out_tsk; } ret = -ESRCH; - if (!(child->ptrace & PT_PTRACED)) - goto out_tsk; - if (child->state != TASK_STOPPED && request != PTRACE_KILL) - goto out_tsk; - if (child->p_pptr != current) + ret = ptrace_check_attach(child, request == PTRACE_KILL); + if (ret) goto out_tsk; ret = do_ptrace(request, child, addr, data); Index: arch/arm/lib/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/lib/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/lib/Makefile 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/lib/Makefile 4 Aug 2004 01:25:39 -0000 1.2 @@ -15,7 +15,7 @@ strnlen_user.o strchr.o strrchr.o testchangebit.o \ testclearbit.o testsetbit.o uaccess.o getuser.o \ putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ - ucmpdi2.o udivdi3.o lib1funcs.o + ucmpdi2.o udivdi3.o lib1funcs.o div64.o obj-m := obj-n := Index: arch/arm/lib/putuser.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/lib/putuser.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/lib/putuser.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/lib/putuser.S 4 Aug 2004 01:25:39 -0000 1.2 @@ -30,11 +30,11 @@ .global __put_user_1 __put_user_1: - bic r2, sp, #0x1f00 - bic r2, r2, #0x00ff - ldr r2, [r2, #TSK_ADDR_LIMIT] - sub r2, r2, #1 - cmp r0, r2 + bic ip, sp, #0x1f00 + bic ip, ip, #0x00ff + ldr ip, [ip, #TSK_ADDR_LIMIT] + sub ip, ip, #1 + cmp r0, ip 1: strlsbt r1, [r0] movls r0, #0 movls pc, lr @@ -42,11 +42,11 @@ .global __put_user_2 __put_user_2: - bic r2, sp, #0x1f00 - bic r2, r2, #0x00ff - ldr r2, [r2, #TSK_ADDR_LIMIT] - sub r2, r2, #2 - cmp r0, r2 + bic ip, sp, #0x1f00 + bic ip, ip, #0x00ff + ldr ip, [ip, #TSK_ADDR_LIMIT] + sub ip, ip, #2 + cmp r0, ip 2: strlsbt r1, [r0], #1 movls r1, r1, lsr #8 3: strlsbt r1, [r0] @@ -56,11 +56,11 @@ .global __put_user_4 __put_user_4: - bic r2, sp, #0x1f00 - bic r2, r2, #0x00ff - ldr r2, [r2, #TSK_ADDR_LIMIT] - sub r2, r2, #4 - cmp r0, r2 + bic ip, sp, #0x1f00 + bic ip, ip, #0x00ff + ldr ip, [ip, #TSK_ADDR_LIMIT] + sub ip, ip, #4 + cmp r0, ip 4: strlst r1, [r0] movls r0, #0 movls pc, lr Index: arch/arm/mach-at91rm9200/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mach-at91rm9200/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mach-at91rm9200/Makefile 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/mach-at91rm9200/Makefile 4 Aug 2004 01:25:39 -0000 1.2 @@ -18,4 +18,8 @@ export-objs := +# LEDs support +leds-$(CONFIG_ARCH_AT91RM9200DK) += dk-leds.o +obj-$(CONFIG_LEDS) += $(leds-y) + include $(TOPDIR)/Rules.make Index: arch/arm/mach-ep93xx/arch.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mach-ep93xx/arch.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mach-ep93xx/arch.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/arm/mach-ep93xx/arch.c 4 Aug 2004 01:25:39 -0000 1.2 @@ -44,7 +44,7 @@ #ifdef CONFIG_ARCH_EP9301 MACHINE_START(EP9301, "ep9301") - MAINTAINER("Cirrus Logic") + MAINTAINER("Cirrus Logic; Technologic Systems") BOOT_MEM( SDRAM_START, 0x80000000, 0x80000000 ) BOOT_PARAMS( SDRAM_START + 0x00000100 ) MAPIO(ep93xx_map_io) Index: arch/arm/mach-ep93xx/dma_ep93xx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mach-ep93xx/dma_ep93xx.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- arch/arm/mach-ep93xx/dma_ep93xx.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/arm/mach-ep93xx/dma_ep93xx.c 21 Feb 2007 16:59:36 -0000 1.3 @@ -1,3533 +1,3600 @@ -/****************************************************************************** - * arch/arm/mach-ep9312/dma_ep93xx.c - * - * Support functions for the ep93xx internal DMA channels. - * (see also Documentation/arm/ep93xx/dma.txt) - * - * Copyright (C) 2003 Cirrus Logic - * - * A large portion of this file is based on the dma api implemented by - * Nicolas Pitre, dma-sa1100.c, copyrighted 2000. - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - ****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include "dma_ep93xx.h" - -/***************************************************************************** - * - * Debugging macros - * - ****************************************************************************/ -#undef DEBUG -/*#define DEBUG 1 */ -#ifdef DEBUG -#define DPRINTK( x... ) printk( ##x ) -#else -#define DPRINTK( x... ) -#endif - -/***************************************************************************** - * - * static global variables - * - ****************************************************************************/ -ep93xx_dma_t dma_chan[MAX_EP93XX_DMA_CHANNELS]; - -/* - * Maximum physical DMA buffer size - */ -#define MAX_DMA_SIZE 0xffff -#define MAX_DMA_ORDER 12 - -/* - * lock used to protect the list of dma channels while searching for a free - * channel during dma_request. - */ -static spinlock_t dma_list_lock; - -/***************************************************************************** - * - * Internal DMA processing functions. - * - ****************************************************************************/ -/***************************************************************************** - * - * get_dma_channel_from_handle() - * - * If Handle is valid, returns the DMA channel # (0 to 9 for channels 1-10) - * If Handle is not valid, returns -1. - * - ****************************************************************************/ -static int -dma_get_channel_from_handle(int handle) -{ - int channel; - - /* - * Get the DMA channel # from the handle. - */ - channel = ((int)handle & DMA_HANDLE_SPECIFIER_MASK) >> 28; - - /* - * See if this is a valid handle. - */ - if(dma_chan[channel].last_valid_handle != (int)handle) - { - DPRINTK("DMA ERROR - invalid handle 0x%x \n", handle); - /* - * Fail, invalid handle - */ - return(-1); - } - - /* - * See if this instance is still open - */ - if(!dma_chan[channel].ref_count ) - { - /* - * Fail, instance closed - */ - return(-1); - } - - return(channel); -} - -/***************************************************************************** - * - * dma_m2m_irq_handler - * - * TODO: need to add support for M2M interrupt handling!!! - * - ****************************************************************************/ -static void -dma_m2m_irq_handler(int irq, void *dev_id, struct pt_regs *regs) -{ - ep93xx_dma_t *dma = (ep93xx_dma_t *)dev_id; - //go DMAM2M volatile * dma_regs = (DMAM2M *)dma->reg_base; - unsigned int M2M_reg_base = dma->reg_base; - ep93xx_dma_dev_t dma_int = UNDEF_INT; - unsigned int read_back, loop, uiCONTROL, uiINTERRUPT; - - /* - * Determine what kind of dma interrupt this is. - */ - //go if(dma_regs->INTERRUPT.Field.STALLINT) - //go else if(dma_regs->INTERRUPT.Field.NFBINT) - //go else if(dma_regs->INTERRUPT.Field.DONEINT) - - if( inl(M2M_reg_base+M2M_OFFSET_INTERRUPT) & INTERRUPT_M2M_STALLINT ) - dma_int = STALL; - else if( inl(M2M_reg_base+M2M_OFFSET_INTERRUPT) & INTERRUPT_M2M_NFBINT ) - dma_int = NFB; - else if( inl(M2M_reg_base+M2M_OFFSET_INTERRUPT) & INTERRUPT_M2M_DONEINT ) - dma_int = DONE; - - DPRINTK("IRQ: b=%#x st=%#x\n", (int)dma->current_buffer->source, dma_int); - - /* - * Stall Interrupt: The Channel is stalled, meaning nothing is - * programmed to transfer right now. So, we're back to the - * beginnning. If there's a buffer to transfer, program it into - * max and base 0 registers. - */ - if(dma_int == STALL) - { - DPRINTK("1 "); - - if(dma->total_buffers) - { - /* - * The current_buffer has already been tranfered, so add the - * byte count to the total_bytes field. - */ - dma->total_bytes = dma->total_bytes + - dma->buffer_queue[dma->current_buffer].size; - - /* - * Mark the current_buffer as used. - */ - dma->buffer_queue[dma->current_buffer].used = TRUE; - - /* - * Increment the used buffer counter - */ - dma->used_buffers++; - - DPRINTK("#%d", dma->current_buffer); - - /* - * Increment the current_buffer - */ - dma->current_buffer = (dma->current_buffer + 1) % - MAX_EP93XX_DMA_BUFFERS; - - /* - * check if there's a new buffer to transfer. - */ - if(dma->new_buffers && dma->xfer_enable) - { - /* - * We have a new buffer to transfer so program in the buffer - * values. Since a STALL interrupt was triggered, we - * program the buffer descriptor 0 - * - * Set the SAR_BASE/DAR_BASE/BCR registers with values from the - * next buffer in the queue. - */ - //go dma_regs->SAR_BASE0.Field.SAR_BASE0 = - //go dma->buffer_queue[dma->current_buffer].source; - outl( dma->buffer_queue[dma->current_buffer].source, - M2M_reg_base + M2M_OFFSET_SAR_BASE0 ); - - //go dma_regs->DAR_BASE0.Field.DAR_BASE0 = - //go dma->buffer_queue[dma->current_buffer].dest; - outl( dma->buffer_queue[dma->current_buffer].dest, - M2M_reg_base + M2M_OFFSET_DAR_BASE0 ); - - //go dma_regs->BCR0.Field.BCR0 = - //go dma->buffer_queue[dma->current_buffer].size; - outl( dma->buffer_queue[dma->current_buffer].size, - M2M_reg_base + M2M_OFFSET_BCR0 ); - - /* - * Decrement the new buffer counter - */ - dma->new_buffers--; - - /* - * If there's a second new buffer, we program the second - * buffer descriptor. - */ - if(dma->new_buffers) - { - DPRINTK("A "); - - /* - * Set the SAR_BASE/DAR_BASE/BCR registers with values from the - * next buffer in the queue. - */ - //go dma_regs->SAR_BASE1.Field.SAR_BASE1 = - //go dma->buffer_queue[(dma->current_buffer + 1) % - //go MAX_EP93XX_DMA_BUFFERS].source; - - outl( dma->buffer_queue[(dma->current_buffer + 1) % - MAX_EP93XX_DMA_BUFFERS].source, - M2M_reg_base+M2M_OFFSET_SAR_BASE1 ); - - //go dma_regs->DAR_BASE0.Field.DAR_BASE0 = - //go dma->buffer_queue[(dma->current_buffer + 1) % - //go MAX_EP93XX_DMA_BUFFERS].dest; - - outl( dma->buffer_queue[(dma->current_buffer + 1) % - MAX_EP93XX_DMA_BUFFERS].dest, - M2M_reg_base+M2M_OFFSET_DAR_BASE0 ); - - //go dma_regs->BCR0.Field.BCR0 = - //go dma->buffer_queue[(dma->current_buffer + 1) % - //go MAX_EP93XX_DMA_BUFFERS].size; - - outl( dma->buffer_queue[(dma->current_buffer + 1) % - MAX_EP93XX_DMA_BUFFERS].size, - M2M_reg_base+M2M_OFFSET_BCR0 ); - - /* - * Decrement the new buffer counter - */ - dma->new_buffers--; - - /* - * Enable the NFB Interrupt. - */ - //go dma_regs->CONTROL.Field.NFBINTEN = 1; - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - uiCONTROL |= CONTROL_M2M_NFBINTEN; - outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); - } - } - /* - * Read my lips. No new buffers. - */ - else - { - DPRINTK("2 \n"); - /* - * There's a chance we setup both buffer descriptors, but - * didn't service the NFB quickly enough, causing the channel - * to transfer both buffers, then enter the stall state. - * So, we need to be able to process the second buffer. - */ - if((dma->used_buffers + dma->new_buffers) < dma->total_buffers) - { - DPRINTK("3 "); - - /* - * The current_buffer has already been tranfered, so add the - * byte count to the total_bytes field. - */ - dma->total_bytes = dma->total_bytes + - dma->buffer_queue[dma->current_buffer].size; - - /* - * Mark the current_buffer as used. - */ - dma->buffer_queue[dma->current_buffer].used = TRUE; - - /* - * Increment the used buffer counter - */ - dma->used_buffers++; - - DPRINTK("#%d", dma->current_buffer); - - /* - * Increment the current buffer pointer. - */ - dma->current_buffer = (dma->current_buffer + 1) % - MAX_EP93XX_DMA_BUFFERS; - - } - - /* - * No new buffers to transfer, so disable the channel. - */ - //go dma_regs->CONTROL.Field.ENABLE = 0; - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - uiCONTROL &= ~CONTROL_M2M_ENABLE; - outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); - - /* - * Indicate that this channel is in the pause by starvation - * state by setting the pause bit to true. - */ - dma->pause = TRUE; - - DPRINTK("End of stall handling. \n"); - DPRINTK("STATUS - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_STATUS) ); - DPRINTK("CONTROL - 0x%x \n", inl(M2M_reg_base+M2M_CONTROL.Value) ); - DPRINTK("REMAIN - 0x%x \n", inl(M2M_reg_base+M2M_REMAIN.Value) ); - DPRINTK("PPALLOC - 0x%x \n", inl(M2M_reg_base+M2M_PPALLOC.Value) ); - DPRINTK("BASE0 - 0x%x \n", inl(M2M_reg_base+M2M_BASE0.Value) ); - DPRINTK("MAXCNT0 - 0x%x \n", inl(M2M_reg_base+M2M_MAXCNT0.Value) ); - DPRINTK("CURRENT0 - 0x%x \n", inl(M2M_reg_base+M2M_CURRENT0.Value) ); - DPRINTK("BASE1 - 0x%x \n", inl(M2M_reg_base+M2M_BASE1.Value) ); - DPRINTK("MAXCNT1 - 0x%x \n", inl(M2M_reg_base+M2M_MAXCNT1.Value) ); - DPRINTK("CURRENT1 - 0x%x \n", inl(M2M_reg_base+M2M_CURRENT1.Value) ); - - DPRINTK("Buffer buf_id source size last used \n"); - for(loop = 0; loop < 32; loop ++) - { - DPRINTK("%d 0x%x 0x%x 0x%x %d %d \n", - loop, dma->buffer_queue[loop].buf_id, dma->buffer_queue[loop].source, - dma->buffer_queue[loop].size, - dma->buffer_queue[loop].last, dma->buffer_queue[loop].used); - } - DPRINTK("pause 0x%x 0x%x 0x%x %d %d \n", - dma->pause_buf.buf_id, dma->pause_buf.source, dma->pause_buf.size, - dma->pause_buf.last, dma->pause_buf.used); - - DPRINTK("Pause - %d \n", dma->pause); - DPRINTK("xfer_enable - %d \n", dma->xfer_enable); - DPRINTK("total bytes - 0x%x \n", dma->total_bytes); - DPRINTK("total buffer - %d \n", dma->total_buffers); - DPRINTK("new buffers - %d \n", dma->new_buffers); - DPRINTK("current buffer - %d \n", dma->current_buffer); - DPRINTK("last buffer - %d \n", dma->last_buffer); - DPRINTK("used buffers - %d \n", dma->used_buffers); - DPRINTK("callback addr - 0x%x \n", dma->callback); - } - } - /* - * Total number of buffers in the queue is 0. - */ - else - { - /* - * No buffers to transfer, or old buffers to mark as used, - * so Disable the channel - */ - //go dma_regs->CONTROL.Field.ENABLE = 0; - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - uiCONTROL &= ~CONTROL_M2M_ENABLE; - outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); - - /* - * Must read the control register back after a write. - */ - //go read_back = dma_regs->CONTROL.Value; - read_back = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - - /* - * Indicate that this channel is in the pause by - * starvation state by setting the pause bit to true. - */ - dma->pause = TRUE; - } - } - /* - * Next Frame Buffer Interrupt. If there's a new buffer program it - * Check if this is the last buffer in the transfer, - * and if it is, disable the NFB int to prevent being - * interrupted for another buffer when we know there won't be - * another. - */ - if(dma_int == NFB) - { - DPRINTK("5 "); - - if(dma->total_buffers) - { - DPRINTK("6 "); - /* - * The iCurrentBuffer has already been transfered. so add the - * byte count from the current buffer to the total byte count. - */ - dma->total_bytes = dma->total_bytes + - dma->buffer_queue[dma->current_buffer].size; - - /* - * Mark the Current Buffer as used. - */ - dma->buffer_queue[dma->current_buffer].used = TRUE; - - /* - * Increment the used buffer counter - */ - dma->used_buffers++; - - DPRINTK("#%d", dma->current_buffer); - - if((dma->buffer_queue[ - (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].last) || - (dma->new_buffers == 0) || (dma->xfer_enable == FALSE)) - { - DPRINTK("7 "); - - /* - * This is the last Buffer in this transaction, so disable - * the NFB interrupt. We shouldn't get an NFB int when the - * FSM moves to the ON state where it would typically get the - * NFB int indicating a new buffer can be programmed. - * Instead, once in the ON state, the DMA will just proceed - * to complet the transfer of the current buffer, move the - * FSB directly to the STALL state where a STALL interrupt - * will be generated. - */ - //go dma_regs->CONTROL.Field.NFBINTEN = 0; - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - uiCONTROL &= ~CONTROL_M2M_NFBINTEN ; - outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); - - /* - * The current buffer has been transferred, so increment - * the current buffer counter to reflect this. - */ - dma->current_buffer = (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS; - - DPRINTK("End of NFB handling. \n"); - DPRINTK("STATUS - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_STATUS) ); - DPRINTK("CONTROL - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_CONTROL) ); - DPRINTK("REMAIN - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_REMAIN) ); - DPRINTK("PPALLOC - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_PPALLOC) ); - DPRINTK("BASE0 - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_BASE0) ); - DPRINTK("MAXCNT0 - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_MAXCNT0) ); - DPRINTK("CURRENT0 - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_CURRENT0) ); - DPRINTK("BASE1 - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_BASE1) ); - DPRINTK("MAXCNT1 - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_MAXCNT1) ); - DPRINTK("CURRENT1 - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_CURRENT1) ); - - DPRINTK("Buffer buf_id source size last used \n"); - for(loop = 0; loop < 32; loop ++) - { - DPRINTK("%d 0x%x 0x%x 0x%x %d %d \n", - loop, dma->buffer_queue[loop].buf_id, dma->buffer_queue[loop].source, - dma->buffer_queue[loop].size, - dma->buffer_queue[loop].last, dma->buffer_queue[loop].used); - } - DPRINTK("pause 0x%x 0x%x 0x%x %d %d \n", - dma->pause_buf.buf_id, dma->pause_buf.source, dma->pause_buf.size, - dma->pause_buf.last, dma->pause_buf.used); - - DPRINTK("Pause - %d \n", dma->pause); - DPRINTK("xfer_enable - %d \n", dma->xfer_enable); - DPRINTK("total bytes - 0x%x \n", dma->total_bytes); - DPRINTK("total buffer - %d \n", dma->total_buffers); - DPRINTK("new buffers - %d \n", dma->new_buffers); - DPRINTK("current buffer - %d \n", dma->current_buffer); - DPRINTK("last buffer - %d \n", dma->last_buffer); - DPRINTK("used buffers - %d \n", dma->used_buffers); - DPRINTK("callback addr - 0x%x \n", dma->callback); - - } - else if(dma->new_buffers) - { - DPRINTK("8 "); - /* - * we have a new buffer, so increment the current buffer to - * point to the next buffer, which is already programmed into - * the DMA. Next time around, it'll be pointing to the - * current buffer. - */ - dma->current_buffer = (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS; - - /* - * we know we have a new buffer to program as the next - * buffer, so check which set of SAR_BASE/DAR_BASE/BCR registers - * to program. - */ - //go if(dma_regs->STATUS.Field.NB) - if( inl(M2M_reg_base+M2M_OFFSET_STATUS) & STATUS_M2M_NB ) - { - /* - * Set the SAR_BASE1/DAR_BASE1/BCR1 registers with values from the - * next buffer in the queue. - */ - //go dma_regs->SAR_BASE1.Field.SAR_BASE1 = dma->buffer_queue[ - //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source; - - outl( dma->buffer_queue[(dma->current_buffer + 1) % - MAX_EP93XX_DMA_BUFFERS].source, - M2M_reg_base+M2M_OFFSET_SAR_BASE1 ); - - //go dma_regs->DAR_BASE1.Field.DAR_BASE1 = dma->buffer_queue[ - //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].dest; - - outl( dma->buffer_queue[(dma->current_buffer + 1) % - MAX_EP93XX_DMA_BUFFERS].dest, - M2M_reg_base+M2M_OFFSET_DAR_BASE1 ); - - //go dma_regs->BCR1.Field.BCR1 = dma->buffer_queue[ - //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size; - - outl( dma->buffer_queue[(dma->current_buffer + 1) % - MAX_EP93XX_DMA_BUFFERS].size, - M2M_reg_base+M2M_OFFSET_BCR1 ); - } - else - { - /* - * Set the SAR_BASE0/DAR_BASE0/BCR0 registers with values from the - * next buffer in the queue. - */ - //go dma_regs->SAR_BASE0.Field.SAR_BASE0 = dma->buffer_queue[ - //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source; - - outl( dma->buffer_queue[(dma->current_buffer + 1) % - MAX_EP93XX_DMA_BUFFERS].source, - M2M_reg_base+M2M_OFFSET_SAR_BASE0 ); - - //go dma_regs->DAR_BASE0.Field.DAR_BASE0 = dma->buffer_queue[ - //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].dest; - - outl( dma->buffer_queue[(dma->current_buffer + 1) % - MAX_EP93XX_DMA_BUFFERS].dest, - M2M_reg_base+M2M_OFFSET_DAR_BASE0 ); - - //go dma_regs->BCR0.Field.BCR0 = dma->buffer_queue[ - //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size; - - outl( dma->buffer_queue[(dma->current_buffer + 1) % - MAX_EP93XX_DMA_BUFFERS].size, - M2M_reg_base+M2M_OFFSET_BCR0 ); - } - - /* - * Decrement the new buffers counter - */ - dma->new_buffers--; - } - } - /* - * Total number of buffers is 0 - really we should never get here, - * but just in case. - */ - else - { - DPRINTK("9 \n"); - - /* - * No new buffers to transfer, so Disable the channel - */ - //go dma_regs->CONTROL.Field.ENABLE = 0; - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - uiCONTROL &= ~CONTROL_M2M_ENABLE; - outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); - - /* - * Indicate that the channel is paused by starvation. - */ - dma->pause = 1; - } - } - - /* - * Done interrupt generated, indicating that the transfer is complete. - */ - if(dma_int == DONE) - { - /* - * Clear the interrupt. - */ - //go dma_regs->INTERRUPT.Field.DONEINT = 0; - uiINTERRUPT = inl(M2M_reg_base+M2M_OFFSET_INTERRUPT); - uiINTERRUPT &= ~INTERRUPT_M2M_DONEINT; - outl( uiINTERRUPT, M2M_reg_base+M2M_OFFSET_INTERRUPT ); - - /* - * Disable the channel. - */ - //go dma_regs->CONTROL.Field.ENABLE = 0; - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - uiCONTROL &= ~CONTROL_M2M_ENABLE; - outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); - - /* - * Indicate that we're in the stopped mode. - */ - dma->pause = 1; - dma->xfer_enable = 0; - } - - /* - * Make sure the interrupt was valid, and if it was, then check - * if a callback function was installed for this DMA channel. If a - * callback was installed call it. - */ - if((dma_int != UNDEF_INT) && dma->callback) - { - dma->callback(dma_int, dma->device, dma->user_data); - } -} - -/***************************************************************************** - * - * dma_m2p_irq_handler - * - * - * - ****************************************************************************/ -static void -dma_m2p_irq_handler(int irq, void *dev_id, struct pt_regs *regs) -{ - ep93xx_dma_t *dma = (ep93xx_dma_t *) dev_id; - //go DMAM2P volatile * dma_regs = (DMAM2P *)dma->reg_base; - unsigned int M2P_reg_base = dma->reg_base; - unsigned int read_back; - ep93xx_dma_dev_t dma_int = UNDEF_INT; - unsigned int loop, uiCONTROL, uiINTERRUPT; - - /* - * Determine what kind of dma interrupt this is. - */ - //go if(dma_regs->INTERRUPT.Field.STALLINT) - //go else if(dma_regs->INTERRUPT.Field.NFBINT) - //go else if(dma_regs->INTERRUPT.Field.CHERRORINT) - - if( inl(M2P_reg_base+M2P_OFFSET_INTERRUPT) & INTERRUPT_M2P_STALLINT ) - dma_int = STALL; - else if( inl(M2P_reg_base+M2P_OFFSET_INTERRUPT) & INTERRUPT_M2P_NFBINT ) - dma_int = NFB; - else if( inl(M2P_reg_base+M2P_OFFSET_INTERRUPT) & INTERRUPT_M2P_CHERRORINT ) - dma_int = CHERROR; - - /* - * Stall Interrupt: The Channel is stalled, meaning nothing is - * programmed to transfer right now. So, we're back to the - * beginnning. If there's a buffer to transfer, program it into - * max and base 0 registers. - */ - if(dma_int == STALL) - { - DPRINTK("1 "); - - if(dma->total_buffers) - { - /* - * The current_buffer has already been tranfered, so add the - * byte count to the total_bytes field. - */ - dma->total_bytes = dma->total_bytes + - dma->buffer_queue[dma->current_buffer].size; - - /* - * Mark the current_buffer as used. - */ - dma->buffer_queue[dma->current_buffer].used = TRUE; - - /* - * Increment the used buffer counter - */ - dma->used_buffers++; - - DPRINTK("#%d", dma->current_buffer); - - /* - * Increment the current_buffer - */ - dma->current_buffer = (dma->current_buffer + 1) % - MAX_EP93XX_DMA_BUFFERS; - - /* - * check if there's a new buffer to transfer. - */ - if(dma->new_buffers && dma->xfer_enable) - { - /* - * We have a new buffer to transfer so program in the buffer - * values. Since a STALL interrupt was triggered, we - * program the base0 and maxcnt0 - * - * Set the MAXCNT0 register with the buffer size - */ - //go dma_regs->MAXCNT0.Field.MAXCNT0 = - //go dma->buffer_queue[dma->current_buffer].size; - outl( dma->buffer_queue[dma->current_buffer].size, - M2P_reg_base+M2P_OFFSET_MAXCNT0 ); - - /* - * Set the BASE0 register with the buffer base address - */ - //go dma_regs->BASE0.Field.BASE0 = - //go dma->buffer_queue[dma->current_buffer].source; - outl( dma->buffer_queue[dma->current_buffer].source, - M2P_reg_base+M2P_OFFSET_BASE0 ); - - /* - * Decrement the new buffer counter - */ - dma->new_buffers--; - - if(dma->new_buffers) - { - DPRINTK("A "); - /* - * Set the MAXCNT1 register with the buffer size - */ - //go dma_regs->MAXCNT1.Field.MAXCNT1 = - //go dma->buffer_queue[(dma->current_buffer + 1) % - //go MAX_EP93XX_DMA_BUFFERS].size; - outl( dma->buffer_queue[(dma->current_buffer + 1) % - MAX_EP93XX_DMA_BUFFERS].size, - M2P_reg_base+M2P_OFFSET_MAXCNT1 ); - - /* - * Set the BASE1 register with the buffer base address - */ - //go dma_regs->BASE1.Field.BASE1 = - //go dma->buffer_queue[dma->current_buffer + 1 % - //go MAX_EP93XX_DMA_BUFFERS].source; - outl( dma->buffer_queue[dma->current_buffer + 1 % - MAX_EP93XX_DMA_BUFFERS].source, - M2P_reg_base+M2P_OFFSET_BASE1 ); - - /* - * Decrement the new buffer counter - */ - dma->new_buffers--; - - /* - * Enable the NFB Interrupt. - */ - //go dma_regs->CONTROL.Field.NFBINTEN = 1; - uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); - uiCONTROL |= CONTROL_M2P_NFBINTEN; - outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); - } - } - /* - * No new buffers. - */ - else - { - DPRINTK("2 \n"); - /* - * There's a chance we setup both buffer descriptors, but - * didn't service the NFB quickly enough, causing the channel - * to transfer both buffers, then enter the stall state. - * So, we need to be able to process the second buffer. - */ - if((dma->used_buffers + dma->new_buffers) < dma->total_buffers) - { - DPRINTK("3 "); - - /* - * The current_buffer has already been tranfered, so add the - * byte count to the total_bytes field. - */ - dma->total_bytes = dma->total_bytes + - dma->buffer_queue[dma->current_buffer].size; - - /* - * Mark the current_buffer as used. - */ - dma->buffer_queue[dma->current_buffer].used = TRUE; - - /* - * Increment the used buffer counter - */ - dma->used_buffers++; - - DPRINTK("#%d", dma->current_buffer); - - /* - * Increment the current buffer pointer. - */ - dma->current_buffer = (dma->current_buffer + 1) % - MAX_EP93XX_DMA_BUFFERS; - - } - - /* - * No new buffers to transfer, so disable the channel. - */ - //go dma_regs->CONTROL.Field.ENABLE = 0; - uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); - uiCONTROL &= ~CONTROL_M2P_ENABLE; - outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); - - /* - * Indicate that this channel is in the pause by starvation - * state by setting the pause bit to true. - */ - dma->pause = TRUE; - - DPRINTK("STATUS - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_STATUS) ); - DPRINTK("CONTROL - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CONTROL) ); - DPRINTK("REMAIN - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_REMAIN) ); - DPRINTK("PPALLOC - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_PPALLOC) ); - DPRINTK("BASE0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE0) ); - DPRINTK("MAXCNT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT0) ); - DPRINTK("CURRENT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT0) ); - DPRINTK("BASE1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE1) ); - DPRINTK("MAXCNT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT1) ); - DPRINTK("CURRENT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT1) ); - - DPRINTK("Buffer buf_id source size last used \n"); - for(loop = 0; loop < 32; loop ++) - { - DPRINTK("%d 0x%x 0x%x 0x%x %d %d \n", - loop, dma->buffer_queue[loop].buf_id, dma->buffer_queue[loop].source, - dma->buffer_queue[loop].size, - dma->buffer_queue[loop].last, dma->buffer_queue[loop].used); - } - DPRINTK("pause 0x%x 0x%x 0x%x %d %d \n", - dma->pause_buf.buf_id, dma->pause_buf.source, dma->pause_buf.size, - dma->pause_buf.last, dma->pause_buf.used); - - DPRINTK("Pause - %d \n", dma->pause); - DPRINTK("xfer_enable - %d \n", dma->xfer_enable); - DPRINTK("total bytes - 0x%x \n", dma->total_bytes); - DPRINTK("total buffer - %d \n", dma->total_buffers); - DPRINTK("new buffers - %d \n", dma->new_buffers); - DPRINTK("current buffer - %d \n", dma->current_buffer); - DPRINTK("last buffer - %d \n", dma->last_buffer); - DPRINTK("used buffers - %d \n", dma->used_buffers); - DPRINTK("callback addr - 0x%x \n", dma->callback); - } - } - /* - * Total number of buffers in the queue is 0. - */ - else - { - /* - * No buffers to transfer, or old buffers to mark as used, - * so Disable the channel - */ - //go dma_regs->CONTROL.Field.ENABLE = 0; - uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); - uiCONTROL &= ~CONTROL_M2P_ENABLE; - outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); - - /* - * Must read the control register back after a write. - */ - //go read_back = dma_regs->CONTROL.Value; - read_back = inl(M2P_reg_base+M2P_OFFSET_CONTROL); - - /* - * Indicate that this channel is in the pause by - * starvation state by setting the pause bit to true. - */ - dma->pause = TRUE; - } - } - /* - * Next Frame Buffer Interrupt. If there's a new buffer program it - * Check if this is the last buffer in the transfer, - * and if it is, disable the NFB int to prevent being - * interrupted for another buffer when we know there won't be - * another. - */ - if(dma_int == NFB) - { - DPRINTK("5 "); - - if(dma->total_buffers) - { - DPRINTK("6 "); - /* - * The iCurrentBuffer has already been transfered. so add the - * byte count from the current buffer to the total byte count. - */ - dma->total_bytes = dma->total_bytes + - dma->buffer_queue[dma->current_buffer].size; - - /* - * Mark the Current Buffer as used. - */ - dma->buffer_queue[dma->current_buffer].used = TRUE; - - /* - * Increment the used buffer counter - */ - dma->used_buffers++; - - DPRINTK("#%d", dma->current_buffer); - - - if((dma->buffer_queue[ - (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].last) || - (dma->new_buffers == 0) || (dma->xfer_enable == FALSE)) - { - DPRINTK("7 "); - - /* - * This is the last Buffer in this transaction, so disable - * the NFB interrupt. We shouldn't get an NFB int when the - * FSM moves to the ON state where it would typically get the - * NFB int indicating a new buffer can be programmed. - * Instead, once in the ON state, the DMA will just proceed - * to complet the transfer of the current buffer, move the - * FSB directly to the STALL state where a STALL interrupt - * will be generated. - */ - //go dma_regs->CONTROL.Field.NFBINTEN = 0; - uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); - uiCONTROL &= ~CONTROL_M2P_NFBINTEN; - outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); - - /* - * The current buffer has been transferred, so increment - * the current buffer counter to reflect this. - */ - dma->current_buffer = (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS; - - DPRINTK("End of NFB handling. \n"); - DPRINTK("STATUS - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_STATUS) ); - DPRINTK("CONTROL - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CONTROL) ); - DPRINTK("REMAIN - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_REMAIN) ); - DPRINTK("PPALLOC - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_PPALLOC) ); - DPRINTK("BASE0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE0) ); - DPRINTK("MAXCNT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT0) ); - DPRINTK("CURRENT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT0) ); - DPRINTK("BASE1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE1) ); - DPRINTK("MAXCNT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT1) ); - DPRINTK("CURRENT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT1) ); - - DPRINTK("Buffer buf_id source size last used \n"); - for(loop = 0; loop < 32; loop ++) - { - DPRINTK("%d 0x%x 0x%x 0x%x %d %d \n", - loop, dma->buffer_queue[loop].buf_id, dma->buffer_queue[loop].source, - dma->buffer_queue[loop].size, - dma->buffer_queue[loop].last, dma->buffer_queue[loop].used); - } - DPRINTK("pause 0x%x 0x%x 0x%x %d %d \n", - dma->pause_buf.buf_id, dma->pause_buf.source, dma->pause_buf.size, - dma->pause_buf.last, dma->pause_buf.used); - - DPRINTK("Pause - %d \n", dma->pause); - DPRINTK("xfer_enable - %d \n", dma->xfer_enable); - DPRINTK("total bytes - 0x%x \n", dma->total_bytes); - DPRINTK("total buffer - %d \n", dma->total_buffers); - DPRINTK("new buffers - %d \n", dma->new_buffers); - DPRINTK("current buffer - %d \n", dma->current_buffer); - DPRINTK("last buffer - %d \n", dma->last_buffer); - DPRINTK("used buffers - %d \n", dma->used_buffers); - DPRINTK("callback addr - 0x%x \n", dma->callback); - - } - else if(dma->new_buffers) - { - DPRINTK("8 "); - /* - * we have a new buffer, so increment the current buffer to - * point to the next buffer, which is already programmed into - * the DMA. Next time around, it'll be pointing to the - * current buffer. - */ - dma->current_buffer = (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS; - - /* - * we know we have a new buffer to program as the next - * buffer, so check which set of MAXCNT and BASE registers - * to program. - */ - //go if(dma_regs->STATUS.Field.NEXTBUFFER) - if( inl(M2P_reg_base+M2P_OFFSET_STATUS) & STATUS_M2P_NEXTBUFFER ) - { - /* - * Set the MAXCNT1 register with the buffer size - */ - //go dma_regs->MAXCNT1.Field.MAXCNT1 = dma->buffer_queue[ - //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size; - outl( dma->buffer_queue[ - (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size, - M2P_reg_base+M2P_OFFSET_MAXCNT1 ); - - /* - * Set the BASE1 register with the buffer base address - */ - //go dma_regs->BASE1.Field.BASE1 = dma->buffer_queue[ - //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source; - outl( dma->buffer_queue[ - (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source, - M2P_reg_base+M2P_OFFSET_BASE1 ); - } - else - { - /* - * Set the MAXCNT0 register with the buffer size - */ - //go dma_regs->MAXCNT0.Field.MAXCNT0 = dma->buffer_queue[ - //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size; - outl( dma->buffer_queue[ - (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size, - M2P_reg_base+M2P_OFFSET_MAXCNT0 ); - - /* - * Set the BASE0 register with the buffer base address - */ - //go dma_regs->BASE0.Field.BASE0 = dma->buffer_queue[ - //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source; - outl( dma->buffer_queue[ - (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source, - M2P_reg_base+M2P_OFFSET_BASE0 ); - } - - /* - * Decrement the new buffers counter - */ - dma->new_buffers--; - } - } - /* - * Total number of buffers is 0 - really we should never get here, - * but just in case. - */ - else - { - DPRINTK("9 \n"); - - /* - * No new buffers to transfer, so Disable the channel - */ - //go dma_regs->CONTROL.Field.ENABLE = 0; - uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); - uiCONTROL &= ~CONTROL_M2P_ENABLE; - outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); - } - } - /* - * Channel Error Interrupt, or perhipheral interrupt, specific to the - * memory to/from peripheral channels. - */ - if(dma_int == CHERROR) - { - /* - * just clear the interrupt, it's really up to the peripheral - * driver to determine if any further action is necessary. - */ - //go dma_regs->INTERRUPT.Field.CHERRORINT = 0; - uiINTERRUPT = inl(M2P_reg_base+M2P_OFFSET_INTERRUPT); - uiINTERRUPT &= ~INTERRUPT_M2P_CHERRORINT; - outl( uiINTERRUPT, M2P_reg_base+M2P_OFFSET_INTERRUPT ); - } - - - /* - * Make sure the interrupt was valid, and if it was, then check - * if a callback function was installed for this DMA channel. If a - * callback was installed call it. - */ - if((dma_int != UNDEF_INT) && dma->callback) - { - dma->callback(dma_int, dma->device, dma->user_data); - } -} - -/***************************************************************************** - * - * ep9312_dma_open_m2p(int device) - * - * Description: This function will attempt to open a M2P/P2M DMA channel. - * If the open is successful, the channel number is returned, - * otherwise a negative number is returned. - * - * Parameters: - * device: device for which the dma channel is requested. - * - ****************************************************************************/ -static int -dma_open_m2p(int device) -{ - int channel = -1; - unsigned int loop; - //go DMAM2P * regs; - unsigned int M2P_reg_base; - unsigned int uiPWRCNT; - - DPRINTK("DMA Open M2P with hw dev %d\n", device); - - - /* - * Lock the dma channel list. - */ - spin_lock(dma_list_lock); - DPRINTK("1\n"); - /* - * Verify that the device requesting DMA isn't already using a DMA channel - */ - if (device >= 10) - { - loop = 1; // Rx transfer requested - } - else - { - loop = 0; // Tx transfer requested - } - - for(; loop < 10; loop = loop + 2) - { - /* - * Before checking for a matching device, check that the - * channel is in use, otherwise the device field is - * invalid. - */ - if(dma_chan[loop].ref_count) - { - if(device == dma_chan[loop].device) - { - DPRINTK("DMA Open M2P - Error\n"); - /* - * Fail. - */ - return(-1); - } - } - } - - /* - * Get a DMA channel instance for the given hardware device. - * If this is a TX look for even numbered channels, else look for - * odd numbered channels - */ - if(device >= 10) - { - loop = 1; /* Rx transfer requested */ - } - else - { - loop = 0; /* Tx transfer requested */ - } - - for(; loop < 10; loop = loop + 2) - { - if(!dma_chan[loop].ref_count) - { - /* - * Capture the channel and increment the reference count. - */ - channel = loop; - dma_chan[channel].ref_count++; - break; - } - } - - /* - * Unlock the dma channel list. - */ - spin_unlock(dma_list_lock); - - /* - * See if we got a valid channel. - */ - if(channel < 0) - { - /* - * Fail. - */ - return(-1); - } - - /* - * Point regs to the correct dma channel register base. - */ - //go regs = (DMAM2P *)(dma_chan[channel].reg_base); - M2P_reg_base = dma_chan[channel].reg_base; - - /* - * Turn on the clock for the specified DMA channel - * TODO: need to use the correct register name for the - * power control register. - */ - uiPWRCNT = inl(SYSCON_PWRCNT); - switch(channel) - { - case 0: - { - uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH0; - break; - } - - case 1: - { - uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH1; - break; - } - - case 2: - { - uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH2; - break; - } - - case 3: - { - uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH3; - break; - } - - case 4: - { - uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH4; - break; - } - - case 5: - { - uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH5; - break; - } - - case 6: - { - uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH6; - break; - } - - case 7: - { - uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH7; - break; - } - case 8: - { - uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH8; - break; - } - case 9: - { - uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH9; - break; - } - - default: - { - return(-1); - } - } - outl( uiPWRCNT, SYSCON_PWRCNT ); - - /*DPRINTK("DMA Open - power control: 0x%x \n", inl(SYSCON_PWRCNT) ); */ - - /* - * Clear out the control register before any further setup. - */ - //go regs->CONTROL.Value = 0; - outl( 0, M2P_reg_base+M2P_OFFSET_CONTROL ); - - /* - * Setup the peripheral port value in the DMA channel registers. - */ - if(device < 10) - { - //go regs->PPALLOC.Value = (unsigned int)device; - outl( (unsigned int)device, M2P_reg_base+M2P_OFFSET_PPALLOC ); - } - else - { - //go regs->PPALLOC.Value = (unsigned int)(device - 10); - outl( (unsigned int)(device - 10), M2P_reg_base+M2P_OFFSET_PPALLOC ); - } - - /* - * Let's hold on to the value of the Hw device for comparison later. - */ - dma_chan[channel].device = device; - - /* - * Success. - */ - return(channel); -} - -/***************************************************************************** - * - * dma_open_m2m(int device) - * - * Description: This function will attempt to open a M2M DMA channel. - * If the open is successful, the channel number is returned, - * otherwise a negative number is returned. - * - * Parameters: - * device: device for which the dma channel is requested. - * - ****************************************************************************/ -static int -dma_open_m2m(int device) -{ - int channel = -1; - unsigned int loop; - //go DMAM2M * regs; - unsigned int M2M_reg_base; - unsigned int uiPWRCNT, uiCONTROL; - - DPRINTK("DMA Open M2M with hw dev %d\n", device); - - - /* - * Lock the dma channel list. - */ - spin_lock(dma_list_lock); - DPRINTK("1\n"); - - /* - * Check if this device is already allocated a channel. - * TODO: can one M2M device be allocated multiple channels? - */ - for(loop = DMA_MEMORY; loop < UNDEF; loop++) - { - /* - * Before checking for a matching device, check that the - * channel is in use, otherwise the device field is - * invalid. - */ - if(dma_chan[loop].ref_count) - { - if(device == dma_chan[loop].device) - { - DPRINTK("Error - dma_open_m2m - already allocated channel\n"); - - /* - * Fail. - */ - return(-1); - } - } - } - - /* - * Get a DMA channel instance for the given hardware device. - */ - for(loop = 10; loop < 12; loop++) - { - if(!dma_chan[loop].ref_count) - { - /* - * Capture the channel and increment the reference count. - */ - channel = loop; - dma_chan[channel].ref_count++; - break; - } - } - - /* - * Unlock the dma channel list. - */ - spin_unlock(dma_list_lock); - - /* - * See if we got a valid channel. - */ - if(channel < 0) - { - /* - * Fail. - */ - return(-1); - } - - /* - * Point regs to the correct dma channel register base. - */ - // regs = (DMAM2M *)(dma_chan[channel].reg_base); - M2M_reg_base = dma_chan[channel].reg_base; - - /* - * Turn on the clock for the specified DMA channel - * TODO: need to use the correct register name for the - * power control register. - */ - uiPWRCNT = inl(SYSCON_PWRCNT); - switch(channel) - { - case 10: - { - uiPWRCNT |= SYSCON_PWRCNT_DMA_M2MCH0; - break; - } - - case 11: - { - uiPWRCNT |= SYSCON_PWRCNT_DMA_M2MCH1; - break; - } - - default: - { - return(-1); - } - } - outl( uiPWRCNT, SYSCON_PWRCNT ); - - DPRINTK("DMA Open - power control: 0x%x \n", inl(SYSCON_PWRCNT) ); - - /* - * Clear out the control register before any further setup. - */ - //go regs->CONTROL.Value = 0; - outl( 0, M2M_reg_base+M2M_OFFSET_CONTROL ); - - /* - * Setup the transfer mode and the request source selection within - * the DMA M2M channel registers. - */ - switch(device) - { - case DMA_MEMORY: - { - //go regs->CONTROL.Field.TM = 0; - //go regs->CONTROL.Field.RSS = 0; - - // Clear TM field, set RSS field to 0 - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - uiCONTROL &= ~(CONTROL_M2M_TM_MASK | CONTROL_M2M_RSS_MASK); - outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); - - break; - } - - case DMA_IDE: - { - //go regs->CONTROL.Field.RSS = 3; - //go regs->CONTROL.Field.NO_HDSK = 1; - //go regs->CONTROL.Field.PW = 01; - - // Set RSS field to 3, Set NO_HDSK, Set PW field to 1 - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_PW_MASK); - uiCONTROL |= (3<CONTROL.Field.TM = 2; - //go regs->CONTROL.Field.RSS = 1; - //go regs->CONTROL.Field.NO_HDSK = 1; - - // Set RSS field to 1, Set NO_HDSK, Set TM field to 2 - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_TM_MASK); - uiCONTROL |= (1<CONTROL.Field.TM = 1; - //go regs->CONTROL.Field.RSS = 2; - //go regs->CONTROL.Field.NO_HDSK = 1; - - // Set RSS field to 2, Set NO_HDSK, Set TM field to 1 - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_TM_MASK); - uiCONTROL |= (2<CONTROL.Field.TM = 1; - //go regs->CONTROL.Field.RSS = 0; - - // Set TM field to 2, set RSS field to 0 - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_TM_MASK); - uiCONTROL |= 1<CONTROL.Field.TM = 2; - //go regs->CONTROL.Field.RSS = 0; - - // Set TM field to 2, set RSS field to 0 - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_TM_MASK); - uiCONTROL |= 2<pause || (!dma->pause && dma->xfer_enable)) - { - /* - * DMA channel is not paused, so we can't configure it. - */ - DPRINTK("DMA channel not paused, so can't configure! \n"); - return(-1); - } - - /* - * Mask interrupts. - */ - local_irq_save(flags); - - /* - * Setup a pointer into the dma channel's register set. - */ - //go regs = (DMAM2M *)dma->reg_base; - M2M_reg_base = dma->reg_base; - - /* - * By default we enable the stall interrupt. - */ - //go regs->CONTROL.Field.STALLINTEN = 1; - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - uiCONTROL |= CONTROL_M2M_STALLINTEN; - outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); - - /* - * By default we enable the done interrupt. - */ - //go regs->CONTROL.Field.DONEINTEN = 1; - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - uiCONTROL |= CONTROL_M2M_DONEINTEN; - outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); - - /* - * Set up the transfer control fields based on values passed in - * the flags_m2m field. - */ - //go regs->CONTROL.Field.DAH = flags_m2m & DESTINATION_HOLD; - //go regs->CONTROL.Field.SAH = flags_m2m & SOURCE_HOLD; - //go regs->CONTROL.Field.TM = flags_m2m & TRANSFER_MODE_MASK; - //go regs->CONTROL.Field.PWSC = flags_m2m & WAIT_STATES_MASK; - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - - if( flags_m2m & DESTINATION_HOLD ) - uiCONTROL |= CONTROL_M2M_DAH; - else - uiCONTROL &= ~CONTROL_M2M_DAH; - - if( flags_m2m & SOURCE_HOLD ) - uiCONTROL |= CONTROL_M2M_SAH; - else - uiCONTROL &= ~CONTROL_M2M_SAH; - - uiCONTROL &= ~CONTROL_M2M_TM_MASK; - uiCONTROL |= ((flags_m2m & TRANSFER_MODE_MASK)<callback = callback; - - /* - * Save the user data in the the dma instance for this channel. - */ - dma->user_data = user_data; - - /* - * Put the dma instance into the pause state by setting the - * pause bit to true. - */ - dma->pause = TRUE; - - local_irq_restore(flags); - - /* - * Success. - */ - return(0); -} - -/***************************************************************************** - * - * int dma_start(int handle, unsigned int channels, unsigned int * handles) - * - * Description: Initiate a transfer on up to 3 channels. - * - * handle: handle for the channel to initiate transfer on. - * channels: number of channels to initiate transfers on. - * handles: pointer to an array of handles, one for each channel which - * is to be started. - * - ****************************************************************************/ -static int -dma_start_m2m(int channel, ep93xx_dma_t * dma) -{ - unsigned int flags; - //go DMAM2M * regs = (DMAM2M *)dma->reg_base; - unsigned int M2M_reg_base = dma->reg_base; - unsigned int uiCONTROL; - - /* - * Make sure the channel has at least one buffer in the queue. - */ - if(dma->new_buffers < 1) - { - DPRINTK("DMA Start: Channel starved.\n"); - - /* - * This channel does not have enough buffers queued up, - * so enter the pause by starvation state. - */ - dma->xfer_enable = TRUE; - dma->pause = TRUE; - - /* - * Success. - */ - return(0); - } - - /* - * Mask interrupts while we get this started. - */ - local_irq_save(flags); - - /* - * Set up one or both buffer descriptors with values from the next one or - * two buffers in the queue. By default enable the next frame buffer - * interrupt on the channel. - */ - //go regs->CONTROL.Field.NFBINTEN = 1; - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - uiCONTROL |= CONTROL_M2M_NFBINTEN; - outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); - - /* - * Update the dma channel instance transfer state. - */ - dma->xfer_enable = TRUE; - dma->pause = FALSE; - - /* - * Decrement the new buffers counter. - */ - dma->new_buffers--; - - /* - * Program up the first buffer descriptor with a sourc and destination - * and a byte count. - */ - //go regs->SAR_BASE0.Field.SAR_BASE0 = dma->buffer_queue[dma->current_buffer].source; - outl( dma->buffer_queue[dma->current_buffer].source, - M2M_reg_base+M2M_OFFSET_SAR_BASE0 ); - - //go regs->DAR_BASE0.Field.DAR_BASE0 = dma->buffer_queue[dma->current_buffer].dest; - outl( dma->buffer_queue[dma->current_buffer].dest, - M2M_reg_base+M2M_OFFSET_DAR_BASE0 ); - - //go regs->BCR0.Field.BCR0 = dma->buffer_queue[dma->current_buffer].size; - outl( dma->buffer_queue[dma->current_buffer].size, - M2M_reg_base+M2M_OFFSET_BCR0 ); - - /* - * Now we enable the channel. This initiates the transfer. - */ - //go regs->CONTROL.Field.ENABLE = 1; - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - uiCONTROL |= CONTROL_M2M_ENABLE; - outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); - - /* - * Before restoring irqs set up the second buffer descriptor - * with a second buffer if we have a second buffer. - */ - if(dma->new_buffers) - { - //go regs->SAR_BASE1.Field.SAR_BASE1 = dma->buffer_queue[ - //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source; - outl( dma->buffer_queue[(dma->current_buffer + 1) % - MAX_EP93XX_DMA_BUFFERS].source, - M2M_reg_base+M2M_OFFSET_SAR_BASE1 ); - - //go regs->DAR_BASE1.Field.DAR_BASE1 = dma->buffer_queue[ - //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].dest; - outl( dma->buffer_queue[(dma->current_buffer + 1) % - MAX_EP93XX_DMA_BUFFERS].dest, - M2M_reg_base+M2M_OFFSET_DAR_BASE1 ); - - //go regs->BCR1.Field.BCR1 = dma->buffer_queue[ - //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size; - outl( dma->buffer_queue[(dma->current_buffer + 1) % - MAX_EP93XX_DMA_BUFFERS].size, - M2M_reg_base+M2M_OFFSET_BCR1 ); - } - - /* - * If this is a memory to memory transfer, we need to s/w trigger the - * transfer by setting the start bit within the control register. - */ - if(dma->device == DMA_MEMORY) - { - //go regs->CONTROL.Field.START = 1; - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - uiCONTROL |= CONTROL_M2M_START; - outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); - } - - -/* - DPRINTK("DMA - It's been started!!"); - DPRINTK("STATUS - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_STATUS) ); - DPRINTK("CONTROL - 0x%x \n", inl(M2M_reg_base+M2M_CONTROL.Value) ); - DPRINTK("REMAIN - 0x%x \n", inl(M2M_reg_base+M2M_REMAIN.Value) ); - DPRINTK("PPALLOC - 0x%x \n", inl(M2M_reg_base+M2M_PPALLOC.Value) ); - DPRINTK("BASE0 - 0x%x \n", inl(M2M_reg_base+M2M_BASE0.Value) ); - DPRINTK("MAXCNT0 - 0x%x \n", inl(M2M_reg_base+M2M_MAXCNT0.Value) ); - DPRINTK("CURRENT0 - 0x%x \n", inl(M2M_reg_base+M2M_CURRENT0.Value) ); - DPRINTK("BASE1 - 0x%x \n", inl(M2M_reg_base+M2M_BASE1.Value) ); - DPRINTK("MAXCNT1 - 0x%x \n", inl(M2M_reg_base+M2M_MAXCNT1.Value) ); - DPRINTK("CURRENT1 - 0x%x \n", inl(M2M_reg_base+M2M_CURRENT1.Value) ); - - DPRINTK("Pause - %d \n", dma_pointers[0]->pause); - DPRINTK("xfer_enable - %d \n", dma_pointers[0]->xfer_enable); - DPRINTK("total bytes - 0x%x \n", dma_pointers[0]->total_bytes); - DPRINTK("total buffer - %d \n", dma_pointers[0]->total_buffers); - DPRINTK("new buffers - %d \n", dma_pointers[0]->new_buffers); - DPRINTK("current buffer - %d \n", dma_pointers[0]->current_buffer); - DPRINTK("last buffer - %d \n", dma_pointers[0]->last_buffer); - DPRINTK("used buffers - %d \n", dma_pointers[0]->used_buffers); -*/ - /* - * Unmask irqs - */ - local_irq_restore(flags); - - /* - * Success. - */ - return(0); -} - -/***************************************************************************** - * - * DMA interface functions - * - ****************************************************************************/ - -/***************************************************************************** - * - * int dma_init(int handle, unsigned int flags_m2p, unsigned int flags_m2m, - * dma_callback callback, unsigned int user_data) - * - * Description: Configure the DMA channel and install a callback function. - * - * handle: Handle unique the each instance of the dma interface, used - * to verify this call. - * flags_m2p Flags used to configure an M2P/P2M dma channel and determine - * if a callback function and user_data information are included - * in this call. This field should be NULL if handle represents - * an M2M channel. - * flags_m2m Flags used to configure an M2M dma channel and determine - * if a callback function and user_data information are included - * in this call. This field should be NULL if handle represents - * an M2P/P2M channel. - * callback function pointer which is called near the end of the - * dma channel's irq handler. - * user_data defined by the calling driver. - * - ****************************************************************************/ -int -ep93xx_dma_config(int handle, unsigned int flags_m2p, unsigned int flags_m2m, - dma_callback callback, unsigned int user_data) -{ - int channel; - ep93xx_dma_t * dma; - //go DMAM2P * dma_regs; - int flags; - unsigned int M2P_reg_base, uiCONTROL; - - /* - * Get the DMA hw channel # from the handle. - */ - channel = dma_get_channel_from_handle(handle); - - /* - * See if this is a valid handle. - */ - if(channel < 0) - { - printk(KERN_ERR - "DMA Config: Invalid dma handle.\n"); - - /* - * Fail. - */ - return(-EINVAL); - } - - DPRINTK("DMA Config \n"); - - dma = &dma_chan[channel]; - - local_irq_save(flags); - - /* - * Check if the channel is currently transferring. - */ - if(dma->xfer_enable) - { - local_irq_restore(flags); - - /* - * Already transferring, invalid command. - */ - return(-EINVAL); - } - - - /* - * Check if this is an m2m function. - */ - if(channel >= 10) - { - local_irq_restore(flags); - - /* - * Call another function to handle m2m config. - */ - return(dma_config_m2m(dma, flags_m2m, callback, user_data)); - } - - /* - * Setup a pointer into the dma channel's register set. - */ - //go dma_regs = (DMAM2P *)dma->reg_base; - M2P_reg_base = dma->reg_base; - - /* - * By default we enable the stall interrupt. - */ - //go dma_regs->CONTROL.Field.STALLINTEN = 1; - uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); - uiCONTROL |= CONTROL_M2P_STALLINTEN; - outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); - - /* - * Configure the channel for an error from the peripheral. - */ - //go dma_regs->CONTROL.Field.CHERRORINTEN = - //go flags_m2p && CHANNEL_ERROR_INT_ENABLE; - uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); - if( flags_m2p && CHANNEL_ERROR_INT_ENABLE ) - uiCONTROL |= CONTROL_M2P_CHERRORINTEN; - else - uiCONTROL &= ~CONTROL_M2P_CHERRORINTEN; - outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); - - - //go dma_regs->CONTROL.Field.ABRT = flags_m2p && ABORT; - uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); - if( flags_m2p && ABORT ) - uiCONTROL |= CONTROL_M2P_ABRT; - else - uiCONTROL &= ~CONTROL_M2P_ABRT; - outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); - - - //go dma_regs->CONTROL.Field.ICE = flags_m2p && IGNORE_CHANNEL_ERROR; - uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); - if( flags_m2p && IGNORE_CHANNEL_ERROR ) - uiCONTROL |= CONTROL_M2P_ICE; - else - uiCONTROL &= ~CONTROL_M2P_ICE; - outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); - - /* - * Save the callback function in the dma instance for this channel. - */ - dma->callback = callback; - - /* - * Save the user data in the the dma instance for this channel. - */ - dma->user_data = user_data; - - /* - * Put the dma instance into the pause state by setting the - * pause bit to true. - */ - dma->pause = TRUE; - - local_irq_restore(flags); - - /* - * Success. - */ - return(0); -} - -/***************************************************************************** - * - * int dma_start(int handle, unsigned int channels, unsigned int * handles) - * - * Description: Initiate a transfer on up to 3 channels. - * - * handle: handle for the channel to initiate transfer on. - * channels: number of channels to initiate transfers on. - * handles: pointer to an array of handles, one for each channel which - * is to be started. - * - ****************************************************************************/ -int -ep93xx_dma_start(int handle, unsigned int channels, unsigned int * handles) -{ - ep93xx_dma_t * dma_pointers[3]; - //go DMAM2P * regs[3]; - unsigned int M2P_reg_bases[3]; - unsigned int loop, flags, uiCONTROL; - int channel; - - /* - * Get the DMA hw channel # from the handle. - */ - channel = dma_get_channel_from_handle(handle); - - /* - * See if this is a valid handle. - */ - if(channel < 0) - { - printk(KERN_ERR "DMA Start: Invalid dma handle.\n"); - - /* - * Fail. - */ - return(-EINVAL); - } - - if(channels < 1) - { - printk(KERN_ERR "DMA Start: Invalid parameter.\n"); - - return(-EINVAL); - } - - DPRINTK("DMA Start \n"); - - /* - * Mask off registers. - */ - local_irq_save(flags); - - /* - * Check if this is a start multiple. - */ - if(channels > 1) - { -#if 0 - for(loop = 0; loop < channels; loop++) - { - /* - * Get the DMA hw channel # from the handle. - */ - channel = dma_get_channel_from_handle(handle); - - /* - * See if this is a valid handle. - */ - if(channel < 0) - { - printk(KERN_ERR "DMA Start: Invalid dma handle.\n"); - - /* - * Fail. - */ - return(-EINVAL); - } - - /* - * Check if this channel is already started. - */ - if(dma_chan[channel].xfer_enable) - { - printk(KERN_ERR - "DMA Start: Invalid command for channel %d.\n", channel); - - /* - * This channel is already transferring, so return an error. - */ - return(-EINVAL); - } - - /* - * Make sure the channel has at least two buffers in the queue. - */ - if(dma_chan[channel].new_buffers < 2) - { - printk(KERN_ERR - "DMA Start: Invalid command for channel %d.\n", channel); - - /* - * This channel does not have enough buffers queued up, - * so return an error. - */ - return(-EINVAL); - } - - /* - * Set up a pointer into the dma instance data for this channel. - */ - dma_pointers[loop] = &dma_chan[channel]; - - /* - * Set up a pointer to the register set for this channel. - */ - //go regs[loop] = (DMAM2P *)dma_pointers[loop]->reg_base; - M2P_reg_bases[loop] = dma_pointers[loop]->reg_base; - - } -#endif - DPRINTK("DMA ERROR: Start, multiple start not supported yet \n"); - return(-1); - } - /* - * Only one channel - */ - else - { - /* - * Check if this channel is already transferring. - */ - if(dma_chan[channel].xfer_enable && !dma_chan[channel].pause) - { - printk(KERN_ERR - "DMA Start: Invalid command for channel %d.\n", channel); - DPRINTK("DMA Start: Invalid command for channel %d.\n", channel); - - - /* - * This channel is already transferring, so return an error. - */ - return(-EINVAL); - } - - /* - * If this is an M2M channel, call a different function. - */ - if(channel >= 10) - { - /* - * Call the m2m start function. Only start one channel. - */ - return(dma_start_m2m(channel, &dma_chan[channel])); - } - - /* - * Make sure the channel has at least one buffer in the queue. - */ - if(dma_chan[channel].new_buffers < 1) - { - DPRINTK("DMA Start: Channel starved.\n"); - - /* - * This channel does not have enough buffers queued up, - * so enter the pause by starvation state. - */ - dma_chan[channel].xfer_enable = TRUE; - dma_chan[channel].pause = TRUE; - - /* - * Success. - */ - return(0); - } - - /* - * Set up a dma instance pointer for this dma channel. - */ - dma_pointers[0] = &dma_chan[channel]; - - /* - * Set up a pointer to the register set for this channel. - */ - //go regs[0] = (DMAM2P *)dma_pointers[0]->reg_base; - M2P_reg_bases[0] = dma_pointers[0]->reg_base; - } - - /* - * Setup both MAXCNT registers with values from the next two buffers - * in the queue, and enable the next frame buffer interrupt on the channel. - */ - for(loop = 0; loop < channels; loop++) - { - /* - * By default we enable the next frame buffer interrupt. - */ - //go regs[loop]->CONTROL.Field.NFBINTEN = 1; - uiCONTROL = inl(M2P_reg_bases[loop]+M2P_OFFSET_CONTROL); - uiCONTROL |= CONTROL_M2P_NFBINTEN; - outl( uiCONTROL, M2P_reg_bases[loop]+M2P_OFFSET_CONTROL ); - - /* - * Check if we need to restore a paused transfer. - * TODO: should check if buf_id == -1 or not. - */ - if(dma_pointers[loop]->pause_buf.buf_id != -1) - { - //go regs[loop]->MAXCNT0.Field.MAXCNT0 = - //go dma_pointers[loop]->pause_buf.size; - outl( dma_pointers[loop]->pause_buf.size, - M2P_reg_bases[loop]+M2P_OFFSET_MAXCNT0 ); - } - else - { - //go regs[loop]->MAXCNT0.Field.MAXCNT0 = - //go dma_pointers[loop]->buffer_queue[dma_pointers[loop]->current_buffer].size; - outl( dma_pointers[loop]->buffer_queue[dma_pointers[loop]->current_buffer].size, - M2P_reg_bases[loop]+M2P_OFFSET_MAXCNT0 ); - } - } - - for(loop = 0; loop < channels; loop++) - { - /* - * Enable the specified dma channels. - */ - //go regs[loop]->CONTROL.Field.ENABLE = 1; - uiCONTROL = inl(M2P_reg_bases[loop]+M2P_OFFSET_CONTROL); - uiCONTROL |= CONTROL_M2P_ENABLE; - outl( uiCONTROL, M2P_reg_bases[loop]+M2P_OFFSET_CONTROL ); - - /* - * Update the dma channel instance transfer state. - */ - dma_pointers[loop]->xfer_enable = TRUE; - dma_pointers[loop]->pause = FALSE; - - if(dma_pointers[loop]->pause_buf.buf_id == -1) - { - dma_pointers[loop]->new_buffers--; - } - } - - /* - * Program up the BASE0 registers for all specified channels, this - * will initiate transfers on all specified channels. - */ - for(loop = 0; loop < channels; loop++) - { - /* - * Check if we need to restore a paused transfer. - */ - if(dma_pointers[loop]->pause_buf.buf_id != -1) - { - //go regs[loop]->BASE0.Field.BASE0 = dma_pointers[loop]->pause_buf.source; - outl( dma_pointers[loop]->pause_buf.source, - M2P_reg_bases[loop]+M2P_OFFSET_BASE0 ); - - /* - * Set the pause buffer to NULL - */ - dma_pointers[loop]->pause_buf.buf_id = -1; - dma_pointers[loop]->pause_buf.size = 0; - } - else - { - //go regs[loop]->BASE0.Field.BASE0 = - //go dma_pointers[loop]->buffer_queue[ - //go dma_pointers[loop]->current_buffer].source; - outl( dma_pointers[loop]->buffer_queue[ - dma_pointers[loop]->current_buffer].source, - M2P_reg_bases[loop]+M2P_OFFSET_BASE0 ); - } - } - - /* - * Before restoring irqs setup the second MAXCNT/BASE - * register with a second buffer. - */ - for(loop = 0; loop < channels; loop++) - { - if(dma_pointers[loop]->new_buffers) - { - //go regs[loop]->MAXCNT1.Field.MAXCNT1 = - //go dma_pointers[loop]->buffer_queue[ - //go (dma_pointers[loop]->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size; - outl( dma_pointers[loop]->buffer_queue[ - (dma_pointers[loop]->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size, - M2P_reg_bases[loop]+M2P_OFFSET_MAXCNT1 ); - - //go regs[loop]->BASE1.Field.BASE1 = - //go dma_pointers[loop]->buffer_queue[ - //go (dma_pointers[loop]->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source; - outl( dma_pointers[loop]->buffer_queue[ - (dma_pointers[loop]->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source, - M2P_reg_bases[loop]+M2P_OFFSET_BASE1 ); - } - } - -/* - DPRINTK("DMA - It's been started!!"); - DPRINTK("STATUS - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_STATUS) ); - DPRINTK("CONTROL - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CONTROL) ); - DPRINTK("REMAIN - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_REMAIN) ); - DPRINTK("PPALLOC - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_PPALLOC) ); - DPRINTK("BASE0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE0) ); - DPRINTK("MAXCNT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT0) ); - DPRINTK("CURRENT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT0) ); - DPRINTK("BASE1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE1) ); - DPRINTK("MAXCNT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT1) ); - DPRINTK("CURRENT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT1) ); - - DPRINTK("Pause - %d \n", dma_pointers[0]->pause); - DPRINTK("xfer_enable - %d \n", dma_pointers[0]->xfer_enable); - DPRINTK("total bytes - 0x%x \n", dma_pointers[0]->total_bytes); - DPRINTK("total buffer - %d \n", dma_pointers[0]->total_buffers); - DPRINTK("new buffers - %d \n", dma_pointers[0]->new_buffers); - DPRINTK("current buffer - %d \n", dma_pointers[0]->current_buffer); - DPRINTK("last buffer - %d \n", dma_pointers[0]->last_buffer); - DPRINTK("used buffers - %d \n", dma_pointers[0]->used_buffers); -*/ - /* - * Unmask irqs - */ - local_irq_restore(flags); - - /* - * Success. - */ - return(0); -} - -/***************************************************************************** - * - * int ep93xx_dma_add_buffer(int handle, unsigned int * address, - * unsigned int size, unsigned int last) - * - * Description: Add a buffer entry to the DMA buffer queue. - * - * handle: handle for the channel to add this buffer to. - * address: Pointer to an integer which is the start address of the - * buffer which is to be added to the queue. - * size: size of the buffer in bytes. - * last: 1 if this is the last buffer in this stream, 0 otherwise. - * - ****************************************************************************/ -int -ep93xx_dma_add_buffer(int handle, unsigned int source, unsigned int dest, - unsigned int size, unsigned int last, - unsigned int buf_id) -{ - unsigned int flags; - ep93xx_dma_t * dma; - int channel; - - /* - * Get the DMA hw channel # from the handle. - */ - channel = dma_get_channel_from_handle(handle); - - /* - * See if this is a valid handle. - */ - if(channel < 0) - { - printk(KERN_ERR - "DMA Add Buffer: Invalid dma handle.\n"); - - /* - * Fail. - */ - return(-EINVAL); - } - - /* - * Get a pointer to the dma instance. - */ - dma = &dma_chan[channel]; - - /* - * Mask interrupts and hold on to the original state. - */ - local_irq_save(flags); - - /* - * If the buffer queue is full, last_buffer is the same as current_buffer and - * we're not tranfering, or last_buffer is pointing to a used buffer, then exit. - * TODO: do I need to do any more checks? - */ - if(dma->total_buffers >= MAX_EP93XX_DMA_BUFFERS) - { - /* - * Restore the state of the irqs - */ - local_irq_restore(flags); - - /* - * Fail. - */ - return(-1); - } - - /* - * Add this buffer to the queue - */ - dma->buffer_queue[dma->last_buffer].source = source; - dma->buffer_queue[dma->last_buffer].dest = dest; - dma->buffer_queue[dma->last_buffer].size = size; - dma->buffer_queue[dma->last_buffer].last = last; - dma->buffer_queue[dma->last_buffer].buf_id = buf_id; - - /* - * Reset the used field of the buffer structure. - */ - dma->buffer_queue[dma->last_buffer].used = FALSE; - - /* - * Increment the End Item Pointer. - */ - dma->last_buffer = (dma->last_buffer + 1) % MAX_EP93XX_DMA_BUFFERS; - - /* - * Increment the new buffers counter and the total buffers counter - */ - dma->new_buffers++; - dma->total_buffers++; - - /* - * restore the interrupt state. - */ - local_irq_restore(flags); - - /* - * Check if the channel was starved into a stopped state. - */ - if(dma->pause && dma->xfer_enable) - { - if(dma->new_buffers >= 1) - { - DPRINTK("DMA - calling start from add after starve. \n"); - - /* - * The channel was starved into a stopped state, and we've got - * 2 new buffers, so start tranferring again. - */ - ep93xx_dma_start(handle, 1, 0); - } - } - - /* - * Success. - */ - return(0); -} - -/***************************************************************************** - * - * int ep93xx_dma_remove_buffer(int handle, unsigned int * address, - * unsigned int * size) - * - * Description: Remove a buffer entry from the DMA buffer queue. If - * buffer was removed successfully, return 0, otherwise - * return -1. - * - * handle: handle for the channel to remove a buffer from. - * address: Pointer to an integer which is filled in with the start - * address of the removed buffer. - * size: Pointer to an integer which is filled in with the size in - * bytes of the removed buffer. - * - ****************************************************************************/ -int -ep93xx_dma_remove_buffer(int handle, unsigned int * buf_id) -{ - unsigned int test; - unsigned int loop; - int return_val = -1; - unsigned int flags; - ep93xx_dma_t *dma; - int channel; - - /* - * Get the DMA hw channel # from the handle. - */ - channel = dma_get_channel_from_handle(handle); - - /* - * See if this is a valid handle. - */ - if(channel < 0) - { - printk(KERN_ERR - "DMA Remove Buffer: Invalid dma handle.\n"); - - /* - * Fail. - */ - return(-EINVAL); - } - - dma = &dma_chan[channel]; - - /* - * Mask interrupts and hold on to the original state. - */ - local_irq_save(flags); - - /* - * Make sure there are used buffers to be returned. - */ - if(dma->used_buffers) - { - test = dma->last_buffer; - - for(loop = 0; loop < MAX_EP93XX_DMA_BUFFERS; loop++) - { - if(dma->buffer_queue[test].used && (dma->buffer_queue[test].buf_id != -1)) - { - /*DPRINTK("buffer %d used \n", test); */ - - /* - * This is a used buffer, fill in the buf_id pointer - * with the buf_id for this buffer. - */ - *buf_id = dma->buffer_queue[test].buf_id; - - /* - * Reset this buffer structure - */ - dma->buffer_queue[test].buf_id = -1; - - /* - * Decrement the used buffer counter, and the total buffer counter. - */ - dma->used_buffers--; - dma->total_buffers--; - - /* - * Successful removal of a buffer, so set the return - * value to 0, then exit this loop. - */ - return_val = 0; - break; - } - - /* - * This buffer isn't used, let's see if the next one is. - */ - test = (test + 1) % MAX_EP93XX_DMA_BUFFERS; - } - } - - /* - * Restore interrupts. - */ - local_irq_restore(flags); - - /* - * Success. - */ - return(return_val); -} - -/***************************************************************************** - * - * int ep93xx_dma_pause(int handle, unsigned int channels, - * unsigned int * handles) - * - * Description: Disable any ongoing transfer for the given channel, retaining - * the state of the current buffer transaction so that upon - * resume, the dma will continue where it left off. - * - * handle: Handle for the channel to be paused. If this is a pause for - * for multiple channels, handle is a valid handle for one of - * the channels to be paused. - * channels: number of channel to pause transfers on. - * handles: Pointer to an array of handles, one for each channel which - * to be paused. If this pause is intended only for one - * channel, this field should be set to NULL. - * - ****************************************************************************/ -int -ep93xx_dma_pause(int handle, unsigned int channels, unsigned int * handles) -{ - unsigned int flags; - ep93xx_dma_t * dma; - int channel; - //go DMAM2P * regs_m2p; - //go DMAM2M * regs_m2m; - unsigned int M2M_reg_base, M2P_reg_base; - - - /* - * Get the DMA hw channel # from the handle. - */ - channel = dma_get_channel_from_handle(handle); - - /* - * See if this is a valid handle. - */ - if(channel < 0) - { - printk(KERN_ERR - "DMA Pause: Invalid dma handle.\n"); - - /* - * Fail. - */ - return(-EINVAL); - } - - DPRINTK("DMA %d: pause \n", channel); - - /* - * Set up a pointer to the dma instance data. - */ - dma = &dma_chan[channel]; - - /* - * Set a pointer to the dma channel registers. - */ - if(channel < 10) - { - //go regs_m2p = dma->reg_base; - M2P_reg_base = dma->reg_base; - } - else - { - //go regs_m2m = dma->reg_base; - M2M_reg_base = dma->reg_base; - } - - /* - * Mask interrupts and hold on to the original state. - */ - local_irq_save(flags); - - /* - * Check if we're already paused. - */ - if(dma->pause) - { - /* - * We're paused, but are we stopped? - */ - if(dma->xfer_enable) - { - /* - * Put the channel in the stopped state. - */ - dma->xfer_enable = FALSE; - } - - DPRINTK("DMA Pause - already paused."); - } - else - { - /* - * Put the channel into the stopped state. - */ - dma->xfer_enable = FALSE; - dma->pause = TRUE; - } - - /* - * restore interrupts. - */ - local_irq_restore(flags); - - /* - * Already paused, so exit. - */ - return(0); - -#if 0 - - /* - * Disable this DMA channel. - */ - if(channel < 10) - { - /* - * Before disabling the channel, get the current state. - */ - //go state = regs_m2p->STATUS.Field.CURRENT; - state = inl(M2P_reg_base+M2P_OFFSET_STATUS) & STATUS_M2P_CURRENT_MASK; - - //go nfb = regs_m2p->STATUS.Field.NEXTBUFFER; - nfb = inl(M2P_reg_base+M2P_OFFSET_STATUS) & STATUS_M2P_NEXTBUFFER; - - /* - * Disable the channel - */ - //go regs_m2p->CONTROL.Field.ENABLE = 0; - uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); - uiCONTROL &= ~CONTROL_M2P_ENABLE; - outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); - } - else - { - //go regs_m2m->CONTROL.Field.ENABLE = 0; - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - uiCONTROL &= ~CONTROL_M2M_ENABLE; - outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); - } - - /* - local_irq_restore(flags); - - mdelay(1); - i2s->i2s_tx0_EN.Value = 0; - - local_irq_save(flags); - */ - - - - /* - * Indicate that the channel stopped transferring, and set the - * pause field. - */ - dma->xfer_enable = FALSE; - dma->pause = TRUE; - - /* - * Save the state of the buffer being transferred. - */ - if(channel < 10) - { - if(state == 2) - { - if(nfb) - { - /* - * Active buffer descriptor is 0 - */ - //go dma->pause_buf.source = regs_m2p->CURRENT0.Field.CURRENT0; - dma->pause_buf.source = - inl( M2P_reg_base+M2P_OFFSET_CURRENT0 ); - - /* - * state is now the buffer descriptor index. - */ - state = 0; - } - else - { - /* - * Active buffer descriptor is 1 - */ - //go dma->pause_buf.source = regs_m2p->CURRENT1.Field.CURRENT1; - dma->pause_buf.source = - inl( M2P_reg_base+M2P_OFFSET_CURRENT1 ); - - /* - * state is now the buffer descriptor index. - */ - state = 1; - } - } - else if(state == 3) - { - if(nfb) - { - /* - * Active buffer descriptor is 1 - */ - //go dma->pause_buf.source = regs_m2p->CURRENT1.Field.CURRENT1; - dma->pause_buf.source = - inl( M2P_reg_base+M2P_OFFSET_CURRENT1 ); - - /* - * state is now the buffer descriptor index. - */ - state = 1; - } - else - { - /* - * Active buffer descriptor is 0 - */ - //go dma->pause_buf.source = regs_m2p->CURRENT0.Field.CURRENT0; - dma->pause_buf.source = - inl( M2P_reg_base+M2P_OFFSET_CURRENT0 ); - - /* - * state is now the buffer descriptor index. - */ - state = 0; - } - } - - /* - * Active buffer descriptor is 0 - */ - //go dma->pause_buf.size = regs_m2p->REMAIN.Field.REMAIN; - dma->pause_buf.size = - inl( M2P_reg_base+M2P_OFFSET_REMAIN ) & M2P_MASK_REMAIN; - - /* - * Set the pause buffer buf_id field to 1 to indicate that this - * buffer has valid data. - */ - dma->pause_buf.buf_id = 1; - - /* - * Reset the nfb variable, it now represents whether or not we need - * to sync up the dma channel instance. - */ - nfb = 0; - - /* - * Check if the active buffer is the current buffer. the channel - * may have started transferring the next buffer, which would mean - * we have to sync up the dma instance data. - */ - //go if(((state == 0) && (dma->buffer_queue[dma->current_buffer].source != - //go regs_m2p->BASE0.Field.BASE0)) || - //go ((state == 1) && (dma->buffer_queue[dma->current_buffer].source != - //go regs_m2p->BASE1.Field.BASE1))) - - if(((state == 0) && (dma->buffer_queue[dma->current_buffer].source != - (inl(M2P_reg_base+M2P_OFFSET_BASE0) & M2P_MASK_BASE0))) || - ((state == 1) && (dma->buffer_queue[dma->current_buffer].source != - (inl(M2P_reg_base+M2P_OFFSET_BASE1) & M2P_MASK_BASE1)))) - { - DPRINTK("Need to sync up \n"); - /* - * We need to sync up the dma channel instance data. - */ - nfb = 1; - } - - if(nfb) - { - /* - * The current buffer is already used at this point. - */ - dma->buffer_queue[dma->current_buffer].used = TRUE; - - /* - * increment the number of used buffers. - */ - dma->used_buffers++; - - DPRINTK("#%d", dma->current_buffer); - - - /* - * Increment the current buffer position. - */ - dma->current_buffer = (dma->current_buffer + 1) % - MAX_EP93XX_DMA_BUFFERS; - } - } - /* - * Memory to memory channel. - */ - else - { - } - - DPRINTK("STATUS - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_STATUS) ); - DPRINTK("CONTROL - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CONTROL) ); - DPRINTK("REMAIN - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_REMAIN) ); - DPRINTK("PPALLOC - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_PPALLOC) ); - DPRINTK("BASE0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE0) ); - DPRINTK("MAXCNT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT0) ); - DPRINTK("CURRENT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT0) ); - DPRINTK("BASE1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE1) ); - DPRINTK("MAXCNT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT1) ); - DPRINTK("CURRENT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT1) ); - - DPRINTK("Buffer buf_id source size last used \n"); - for(loop = 0; loop < 32; loop ++) - { - DPRINTK("%d 0x%x 0x%x 0x%x %d %d \n", - loop, dma->buffer_queue[loop].buf_id, dma->buffer_queue[loop].source, dma->buffer_queue[loop].size, - dma->buffer_queue[loop].last, dma->buffer_queue[loop].used); - } - DPRINTK("pause 0x%x 0x%x 0x%x %d %d \n", - dma->pause_buf.buf_id, dma->pause_buf.source, dma->pause_buf.size, - dma->pause_buf.last, dma->pause_buf.used); - - DPRINTK("Pause - %d \n", dma->pause); - DPRINTK("xfer_enable - %d \n", dma->xfer_enable); - DPRINTK("total bytes - 0x%x \n", dma->total_bytes); - DPRINTK("total buffer - %d \n", dma->total_buffers); - DPRINTK("new buffers - %d \n", dma->new_buffers); - DPRINTK("current buffer - %d \n", dma->current_buffer); - DPRINTK("last buffer - %d \n", dma->last_buffer); - DPRINTK("used buffers - %d \n", dma->used_buffers); - DPRINTK("nfb - %d \n", nfb); - DPRINTK("state - %d \n", state); - - - - - /* - * restore interrupts. - */ - local_irq_restore(flags); - - - /* - * Success. - */ - return(0); -#endif -} - -/***************************************************************************** - * - * void ep93xx_dma_flush(int handle) - * - * Description: Flushes all queued buffers and transfers in progress - * for the given channel. Return the buffer entries - * to the calling function. - * - * handle: handle for the channel for which the flush is intended. - * - ****************************************************************************/ -int -ep93xx_dma_flush(int handle) -{ - unsigned int loop, flags; - ep93xx_dma_t * dma; - int channel; - //go DMAM2P * dma_regs; - unsigned int M2P_reg_base; - - /* - * Get the DMA hw channel # from the handle. - */ - channel = dma_get_channel_from_handle(handle); - - /* - * See if this is a valid handle. - */ - if(channel < 0) - { - printk(KERN_ERR - "DMA Flush: Invalid dma handle.\n"); - - /* - * Fail. - */ - return(-EINVAL); - } - - DPRINTK("DMA %d: flush \n", channel); - - /* - * Set up a pointer to the dma instance data for this channel - */ - dma = &dma_chan[channel]; - - /* - * Mask interrupts and hold on to the original state. - */ - local_irq_save(flags); - - for(loop = 0; loop < MAX_EP93XX_DMA_BUFFERS; loop++) - { - dma->buffer_queue[loop].buf_id = -1; - } - - /* - * Set the Current and Last item to zero. - */ - dma->current_buffer = 0; - dma->last_buffer = 0; - - /* - * Reset the Buffer counters - */ - dma->used_buffers = 0; - dma->new_buffers = 0; - dma->total_buffers = 0; - - /* - * reset the Total bytes counter. - */ - dma->total_bytes = 0; - - //go dma_regs = (DMAM2P *)(dma_chan[channel].reg_base); - M2P_reg_base = dma_chan[channel].reg_base; - - /* - * restore interrupts. - */ - local_irq_restore(flags); - - /* - * Success. - */ - return(0); -} - -/***************************************************************************** - * - * int ep93xx_dma_queue_full(int handle) - * - * Description: Query to determine if the DMA queue of buffers for - * a given channel is full. - * 0 = queue is full - * 1 = queue is not full - * - * handle: handle for the channel to query. - * - ****************************************************************************/ -int -ep93xx_dma_queue_full(int handle) -{ - int list_full = 0; - unsigned int flags; - int channel; - - /* - * Get the DMA hw channel # from the handle. - */ - channel = dma_get_channel_from_handle(handle); - - /* - * See if this is a valid handle. - */ - if(channel < 0) - { - printk(KERN_ERR - "DMA Queue Full: Invalid dma handle.\n"); - - /* - * Fail. - */ - return(-EINVAL); - } - - DPRINTK("DMA %d: queue full \n", channel); - - /* - * Mask interrupts and hold on to the original state. - */ - local_irq_save(flags); - - /* - * If the last item is equal to the used item then - * the queue is full. - */ - if(dma_chan[channel].total_buffers < MAX_EP93XX_DMA_BUFFERS) - { - list_full = FALSE; - } - else - { - list_full = TRUE; - } - - /* - * restore interrupts. - */ - local_irq_restore(flags); - - return(list_full); -} - -/***************************************************************************** - * - * int ep93xx_dma_get_position(int handle, unsigned int * buf_id, - unsigned int * total) - * - * Description: Takes two integer pointers and fills them with the start - * and current address of the buffer currently transferring - * on the specified DMA channel. - * - * handle: handle for the channel to query. - * buf_id: pointer which is filled in with the buffer id for the - * current buffer transferring on the dma channel. - * buffer being transferred. - * total : pointer which is filled in with the total bytes - * transferred on the channel. - ****************************************************************************/ -int -ep93xx_dma_get_position(int handle, unsigned int * buf_id, - unsigned int * total) -{ - int channel; - ep93xx_dma_t * dma; - - /* - * Get the DMA hw channel # from the handle. - */ - channel = dma_get_channel_from_handle(handle); - - /* - * See if this is a valid handle. - */ - if(channel < 0) - { - printk(KERN_ERR "DMA Get Position: Invalid dma handle.\n"); - - /* - * Fail. - */ - return(-EINVAL); - } - - dma = &dma_chan[channel]; - - /* - * TODO: should irqs be disabled here? - */ - - *buf_id = dma->buffer_queue[dma->current_buffer].buf_id; - - *total = dma->total_bytes; - - DPRINTK("DMA buf_id %d, total %d\n", *buf_id, *total); - - /* - * Success. - */ - return(0); -} - -/***************************************************************************** - * - * int ep93xx_dma_get_total(int handle) - * - * Description: Returns the total number of bytes transferred on the - * specified channel since the channel was requested. - * - * handle: handle for the channel to query. - * - ****************************************************************************/ -int -ep93xx_dma_get_total(int handle) -{ - int channel; - - /* - * Get the DMA hw channel # from the handle. - */ - channel = dma_get_channel_from_handle(handle); - - /* - * See if this is a valid handle. - */ - if(channel < 0) - { - printk(KERN_ERR "DMA Get Total: Invalid dma handle.\n"); - - /* - * Fail. - */ - return(-EINVAL); - } - - DPRINTK("DMA %d: total: %d \n", channel, dma_chan[channel].total_bytes); - - /* - * Return the total number of bytes transferred on this channel since - * it was requested. - */ - return(dma_chan[channel].total_bytes); -} - -/***************************************************************************** - * ep93xx_dma_request - * - * Description: This function will allocate a DMA channel for a particular - * hardware peripheral. Before initiating a transfer on the allocated - * channel, the channel must be set up and buffers have to queued up. - * - * handle: pointer to an integer which is filled in with a unique - * handle for this instance of the dma interface. - * device_id string with the device name, primarily used by /proc. - * device hardware device ID for which the requested dma channel will - * transfer data. - * - ****************************************************************************/ -int -ep93xx_dma_request(int * handle, const char *device_id, - ep93xx_dma_dev_t device) -{ - ep93xx_dma_t *dma = NULL; - int channel, error = 0; - unsigned int loop; - //go DMAM2P * dma_regs; - unsigned int M2P_reg_base; - - /* - * Check if the device requesting a DMA channel is a valid device. - */ - if((device >= UNDEF) || (device < 0)) - { - /* - * Invalid device, so return an error. - */ - return(-ENODEV); - } - - /* - * We've got a valid hardware device requesting a DMA channel. - * Now check if the device should open an M2P or M2M channel - */ - if(device < 20) - { - channel = dma_open_m2p(device); - } - else - { - channel = dma_open_m2m(device); - } - - /* - * Check if we successfully opened a DMA channel - */ - if(channel < 0) - { - printk(KERN_ERR - "%s: Could not open dma channel for this device.\n", - device_id); - - /* - * Fail. - */ - return(-EBUSY); - } - - dma = &dma_chan[channel]; - - /* - * Request the appropriate IRQ for the specified channel - */ - if(channel < 10) - { - error = request_irq(dma->irq, dma_m2p_irq_handler, SA_INTERRUPT, - device_id, (void *) dma); - } - else - { - error = request_irq(dma->irq, dma_m2m_irq_handler, SA_INTERRUPT, - device_id, (void *) dma); - } - - /* - * Check for any errors during the irq request - */ - if(error) - { - printk(KERN_ERR - "%s: unable to request IRQ %d for DMA channel\n", - device_id, dma->irq); - /* - * Fail. - */ - return(error); - } - - /* - * Generate a valid handle and exit. - * - * Increment the last valid handle. - * Check for wraparound (unlikely, but we like to be complete). - */ - dma->last_valid_handle++; - - if( (dma->last_valid_handle & DMA_HANDLE_SPECIFIER_MASK) != - (channel << 28) ) - { - /* - * If we wrapped around start over. - */ - dma->last_valid_handle = (channel << 28) + 1; - } - - /* - * Fill in the handle pointer with a valid handle for - * this dma channel instance. - */ - *handle = dma->last_valid_handle; - - DPRINTK("Handle for channel %d: 0x%x\n", channel, *handle); - - /* - * Save the device ID and device name. - */ - dma->device = device; - dma->device_id = device_id; - - /* - * Init all fields within the dma instance. - */ - for(loop = 0; loop < MAX_EP93XX_DMA_BUFFERS; loop++) - { - dma->buffer_queue[loop].buf_id = -1; - } - - /* - * Initialize all buffer queue variables. - */ - dma->current_buffer = 0; - dma->last_buffer = 0; - - dma->new_buffers = 0; - dma->used_buffers = 0; - dma->total_buffers = 0; - - /* - * Initialize the total bytes variable - */ - dma->total_bytes = 0; - - /* - * Initialize the transfer and pause state variables to 0. - */ - dma->xfer_enable = 0; - - dma->pause = 0; - - /* - * Initialize the pause buffer structure. - */ - dma->pause_buf.buf_id = -1; - - /* - * Initialize the callback function and user data fields. - */ - dma->callback = NULL; - - /* - * User data used as a parameter for the Callback function. The user - * sets up the data and sends it with the callback function. - */ - dma->user_data = 0; - - //go dma_regs = (DMAM2P *)dma_chan[channel].reg_base; - M2P_reg_base = dma_chan[channel].reg_base; - - /* - * Debugging message. - */ - DPRINTK("Successfully requested dma channel %d\n", channel); - DPRINTK("STATUS - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_STATUS) ); - DPRINTK("CONTROL - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CONTROL) ); - DPRINTK("REMAIN - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_REMAIN) ); - DPRINTK("PPALLOC - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_PPALLOC) ); - DPRINTK("BASE0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE0) ); - DPRINTK("MAXCNT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT0) ); - DPRINTK("CURRENT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT0) ); - DPRINTK("BASE1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE1) ); - DPRINTK("MAXCNT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT1) ); - DPRINTK("CURRENT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT1) ); - - DPRINTK("Buffer source size last used \n"); - for(loop = 0; loop < 5; loop ++) - { - DPRINTK("%d 0x%x 0x%x %d %d \n", - loop, dma->buffer_queue[loop].source, dma->buffer_queue[loop].size, - dma->buffer_queue[loop].last, dma->buffer_queue[loop].used); - } - DPRINTK("pause 0x%x 0x%x %d %d \n", - dma->pause_buf.source, dma->pause_buf.size, - dma->pause_buf.last, dma->pause_buf.used); - - DPRINTK("Pause - %d \n", dma->pause); - DPRINTK("xfer_enable - %d \n", dma->xfer_enable); - DPRINTK("total bytes - 0x%x \n", dma->total_bytes); - DPRINTK("total buffer - %d \n", dma->total_buffers); - DPRINTK("new buffers - %d \n", dma->new_buffers); - DPRINTK("current buffer - %d \n", dma->current_buffer); - DPRINTK("last buffer - %d \n", dma->last_buffer); - DPRINTK("used buffers - %d \n", dma->used_buffers); - - DPRINTK("CURRENT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT1) ); - DPRINTK("VIC0IRQSTATUS - 0x%x, VIC0INTENABLE - 0x%x \n", - *(unsigned int *)(VIC0IRQSTATUS), - *(unsigned int *)(VIC0INTENABLE)); - - /* - * Success. - */ - return(0); -} - -/***************************************************************************** - * - * ep93xx_dma_free - * - * Description: This function will free the dma channel for future requests. - * - * handle: handle for the channel to be freed. - * - ****************************************************************************/ -int -ep93xx_dma_free(int handle) -{ - ep93xx_dma_t *dma; - //go DMAM2P * regs_m2p; - //go DMAM2M * regs_m2m; - unsigned int M2M_reg_base, M2P_reg_base, uiCONTROL; - int channel; - - /* - * Get the DMA hw channel # from the handle. - */ - channel = dma_get_channel_from_handle(handle); - - /* - * See if this is a valid handle. - */ - if(channel < 0) - { - printk(KERN_ERR "DMA Free: Invalid dma handle.\n"); - - /* - * Fail. - */ - return(-EINVAL); - } - - /* - * Get a pointer to the dma instance. - */ - dma = &dma_chan[channel]; - - /* - * Disable the dma channel - */ - if(channel < 10) - { - /* - * M2P channel - */ - //go regs_m2p = dma->reg_base; - M2P_reg_base = dma->reg_base; - - //go regs_m2p->CONTROL.Field.ENABLE = 0; - uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); - uiCONTROL &= ~CONTROL_M2P_ENABLE; - outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); - } - else - { - /* - * M2M channel - */ - //go regs_m2m = dma->reg_base; - M2M_reg_base = dma->reg_base; - - //go regs_m2m->CONTROL.Field.ENABLE = 0; - uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); - uiCONTROL &= ~CONTROL_M2M_ENABLE; - outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); - } - - /* - * Free the interrupt servicing this dma channel - */ - free_irq(dma->irq, (void *) dma); - - /* - * Decrement the reference count for this instance of the dma interface - */ - dma->ref_count--; - - /* - * Set the transfer and pause state variables to 0 - * (unititialized state). - */ - dma->xfer_enable = 0; - dma->pause = 0; - - /* - * Debugging message. - */ - DPRINTK("Successfully freed dma channel %d\n", channel); - - /* - * Success. - */ - return(0); -} - -/***************************************************************************** - * - * ep93xx_dma_init(void) - * - * Description: This function is called during system initialization to - * setup the interrupt number and register set base address for each DMA - * channel. - * - ****************************************************************************/ -static int __init -ep93xx_dma_init(void) -{ - int channel; - - /* - * Init some values in each dma instance. - */ - for(channel = 0; channel < MAX_EP93XX_DMA_CHANNELS; channel++) - { - /* - * IRQ for the specified dma channel. - */ - dma_chan[channel].irq = IRQ_DMAM2P0 + channel; - - /* - * Initial value of the dma channel handle. - */ - dma_chan[channel].last_valid_handle = channel << 28; - - /* - * Give the instance a pointer to the dma channel register - * base. - */ - if(channel < 10) - { - dma_chan[channel].reg_base = DMAM2PChannelBase[channel]; - } - else - { - dma_chan[channel].reg_base = DMAM2MChannelBase[channel - 10]; - } - - /* - * Initialize the reference count for this channel. - */ - dma_chan[channel].ref_count = 0; - } - - DPRINTK("DMA Interface intitialization complete\n"); - - /* - * Success - */ - return 0; -} - -__initcall(ep93xx_dma_init); - - +/****************************************************************************** + * arch/arm/mach-ep9312/dma_ep93xx.c + * + * Support functions for the ep93xx internal DMA channels. + * (see also Documentation/arm/ep93xx/dma.txt) + * + * Copyright (C) 2003 Cirrus Logic + * + * A large portion of this file is based on the dma api implemented by + * Nicolas Pitre, dma-sa1100.c, copyrighted 2000. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "dma_ep93xx.h" + +/***************************************************************************** + * + * Debugging macros + * + ****************************************************************************/ +#undef DEBUG +/*#define DEBUG 1 */ +#ifdef DEBUG +#define DPRINTK( x... ) printk( ##x ) +#else +#define DPRINTK( x... ) +#endif + +/***************************************************************************** + * + * static global variables + * + ****************************************************************************/ +ep93xx_dma_t dma_chan[MAX_EP93XX_DMA_CHANNELS]; + +/* + * Maximum physical DMA buffer size + */ +#define MAX_DMA_SIZE 0xffff +#define MAX_DMA_ORDER 12 + +/* + * lock used to protect the list of dma channels while searching for a free + * channel during dma_request. + */ +static spinlock_t dma_list_lock; + +/***************************************************************************** + * + * Internal DMA processing functions. + * + ****************************************************************************/ +/***************************************************************************** + * + * get_dma_channel_from_handle() + * + * If Handle is valid, returns the DMA channel # (0 to 9 for channels 1-10) + * If Handle is not valid, returns -1. + * + ****************************************************************************/ +static int +dma_get_channel_from_handle(int handle) +{ + int channel; + + /* + * Get the DMA channel # from the handle. + */ + channel = ((int)handle & DMA_HANDLE_SPECIFIER_MASK) >> 28; + + /* + * See if this is a valid handle. + */ + if(dma_chan[channel].last_valid_handle != (int)handle) + { + DPRINTK("DMA ERROR - invalid handle 0x%x \n", handle); + /* + * Fail, invalid handle + */ + return(-1); + } + + /* + * See if this instance is still open + */ + if(!dma_chan[channel].ref_count ) + { + /* + * Fail, instance closed + */ + return(-1); + } + + return(channel); +} + +/***************************************************************************** + * + * dma_m2m_irq_handler + * + * TODO: need to add support for M2M interrupt handling!!! + * + ****************************************************************************/ +static void +dma_m2m_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + ep93xx_dma_t *dma = (ep93xx_dma_t *)dev_id; + //go DMAM2M volatile * dma_regs = (DMAM2M *)dma->reg_base; + unsigned int M2M_reg_base = dma->reg_base; + ep93xx_dma_dev_t dma_int = UNDEF_INT; + unsigned int read_back, loop, uiCONTROL, uiINTERRUPT; + + /* + * Determine what kind of dma interrupt this is. + */ + //go if(dma_regs->INTERRUPT.Field.STALLINT) + //go else if(dma_regs->INTERRUPT.Field.NFBINT) + //go else if(dma_regs->INTERRUPT.Field.DONEINT) + + if( inl(M2M_reg_base+M2M_OFFSET_INTERRUPT) & INTERRUPT_M2M_STALLINT ) + dma_int = STALL; + else if( inl(M2M_reg_base+M2M_OFFSET_INTERRUPT) & INTERRUPT_M2M_NFBINT ) + dma_int = NFB; + else if( inl(M2M_reg_base+M2M_OFFSET_INTERRUPT) & INTERRUPT_M2M_DONEINT ) + dma_int = DONE; + + DPRINTK("IRQ: b=%#x st=%#x\n", (int)dma->current_buffer->source, dma_int); + + /* + * Stall Interrupt: The Channel is stalled, meaning nothing is + * programmed to transfer right now. So, we're back to the + * beginnning. If there's a buffer to transfer, program it into + * max and base 0 registers. + */ + if(dma_int == STALL) + { + DPRINTK("1 "); + + if(dma->total_buffers) + { + /* + * The current_buffer has already been tranfered, so add the + * byte count to the total_bytes field. + */ + dma->total_bytes = dma->total_bytes + + dma->buffer_queue[dma->current_buffer].size; + + /* + * Mark the current_buffer as used. + */ + dma->buffer_queue[dma->current_buffer].used = TRUE; + + /* + * Increment the used buffer counter + */ + dma->used_buffers++; + + DPRINTK("#%d", dma->current_buffer); + + /* + * Increment the current_buffer + */ + dma->current_buffer = (dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS; + + /* + * check if there's a new buffer to transfer. + */ + if(dma->new_buffers && dma->xfer_enable) + { + /* + * We have a new buffer to transfer so program in the buffer + * values. Since a STALL interrupt was triggered, we + * program the buffer descriptor 0 + * + * Set the SAR_BASE/DAR_BASE/BCR registers with values from the + * next buffer in the queue. + */ + //go dma_regs->SAR_BASE0.Field.SAR_BASE0 = + //go dma->buffer_queue[dma->current_buffer].source; + outl( dma->buffer_queue[dma->current_buffer].source, + M2M_reg_base + M2M_OFFSET_SAR_BASE0 ); + + //go dma_regs->DAR_BASE0.Field.DAR_BASE0 = + //go dma->buffer_queue[dma->current_buffer].dest; + outl( dma->buffer_queue[dma->current_buffer].dest, + M2M_reg_base + M2M_OFFSET_DAR_BASE0 ); + + //go dma_regs->BCR0.Field.BCR0 = + //go dma->buffer_queue[dma->current_buffer].size; + outl( dma->buffer_queue[dma->current_buffer].size, + M2M_reg_base + M2M_OFFSET_BCR0 ); + + /* + * Decrement the new buffer counter + */ + dma->new_buffers--; + + /* + * If there's a second new buffer, we program the second + * buffer descriptor. + */ + if(dma->new_buffers) + { + DPRINTK("A "); + + /* + * Set the SAR_BASE/DAR_BASE/BCR registers with values from the + * next buffer in the queue. + */ + //go dma_regs->SAR_BASE1.Field.SAR_BASE1 = + //go dma->buffer_queue[(dma->current_buffer + 1) % + //go MAX_EP93XX_DMA_BUFFERS].source; + + outl( dma->buffer_queue[(dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS].source, + M2M_reg_base+M2M_OFFSET_SAR_BASE1 ); + + //go dma_regs->DAR_BASE0.Field.DAR_BASE0 = + //go dma->buffer_queue[(dma->current_buffer + 1) % + //go MAX_EP93XX_DMA_BUFFERS].dest; + + outl( dma->buffer_queue[(dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS].dest, + M2M_reg_base+M2M_OFFSET_DAR_BASE0 ); + + //go dma_regs->BCR0.Field.BCR0 = + //go dma->buffer_queue[(dma->current_buffer + 1) % + //go MAX_EP93XX_DMA_BUFFERS].size; + + outl( dma->buffer_queue[(dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS].size, + M2M_reg_base+M2M_OFFSET_BCR0 ); + + /* + * Decrement the new buffer counter + */ + dma->new_buffers--; + + /* + * Enable the NFB Interrupt. + */ + //go dma_regs->CONTROL.Field.NFBINTEN = 1; + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + uiCONTROL |= CONTROL_M2M_NFBINTEN; + outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); + } + } + /* + * Read my lips. No new buffers. + */ + else + { + DPRINTK("2 \n"); + /* + * There's a chance we setup both buffer descriptors, but + * didn't service the NFB quickly enough, causing the channel + * to transfer both buffers, then enter the stall state. + * So, we need to be able to process the second buffer. + */ + if((dma->used_buffers + dma->new_buffers) < dma->total_buffers) + { + DPRINTK("3 "); + + /* + * The current_buffer has already been tranfered, so add the + * byte count to the total_bytes field. + */ + dma->total_bytes = dma->total_bytes + + dma->buffer_queue[dma->current_buffer].size; + + /* + * Mark the current_buffer as used. + */ + dma->buffer_queue[dma->current_buffer].used = TRUE; + + /* + * Increment the used buffer counter + */ + dma->used_buffers++; + + DPRINTK("#%d", dma->current_buffer); + + /* + * Increment the current buffer pointer. + */ + dma->current_buffer = (dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS; + + } + + /* + * No new buffers to transfer, so disable the channel. + */ + //go dma_regs->CONTROL.Field.ENABLE = 0; + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2M_ENABLE; + outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); + + /* + * Indicate that this channel is in the pause by starvation + * state by setting the pause bit to true. + */ + dma->pause = TRUE; + + DPRINTK("End of stall handling. \n"); + DPRINTK("STATUS - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_STATUS) ); + DPRINTK("CONTROL - 0x%x \n", inl(M2M_reg_base+M2M_CONTROL.Value) ); + DPRINTK("REMAIN - 0x%x \n", inl(M2M_reg_base+M2M_REMAIN.Value) ); + DPRINTK("PPALLOC - 0x%x \n", inl(M2M_reg_base+M2M_PPALLOC.Value) ); + DPRINTK("BASE0 - 0x%x \n", inl(M2M_reg_base+M2M_BASE0.Value) ); + DPRINTK("MAXCNT0 - 0x%x \n", inl(M2M_reg_base+M2M_MAXCNT0.Value) ); + DPRINTK("CURRENT0 - 0x%x \n", inl(M2M_reg_base+M2M_CURRENT0.Value) ); + DPRINTK("BASE1 - 0x%x \n", inl(M2M_reg_base+M2M_BASE1.Value) ); + DPRINTK("MAXCNT1 - 0x%x \n", inl(M2M_reg_base+M2M_MAXCNT1.Value) ); + DPRINTK("CURRENT1 - 0x%x \n", inl(M2M_reg_base+M2M_CURRENT1.Value) ); + + DPRINTK("Buffer buf_id source size last used \n"); + for(loop = 0; loop < 32; loop ++) + { + DPRINTK("%d 0x%x 0x%x 0x%x %d %d \n", + loop, dma->buffer_queue[loop].buf_id, dma->buffer_queue[loop].source, + dma->buffer_queue[loop].size, + dma->buffer_queue[loop].last, dma->buffer_queue[loop].used); + } + DPRINTK("pause 0x%x 0x%x 0x%x %d %d \n", + dma->pause_buf.buf_id, dma->pause_buf.source, dma->pause_buf.size, + dma->pause_buf.last, dma->pause_buf.used); + + DPRINTK("Pause - %d \n", dma->pause); + DPRINTK("xfer_enable - %d \n", dma->xfer_enable); + DPRINTK("total bytes - 0x%x \n", dma->total_bytes); + DPRINTK("total buffer - %d \n", dma->total_buffers); + DPRINTK("new buffers - %d \n", dma->new_buffers); + DPRINTK("current buffer - %d \n", dma->current_buffer); + DPRINTK("last buffer - %d \n", dma->last_buffer); + DPRINTK("used buffers - %d \n", dma->used_buffers); + DPRINTK("callback addr - 0x%x \n", dma->callback); + } + } + /* + * Total number of buffers in the queue is 0. + */ + else + { + /* + * No buffers to transfer, or old buffers to mark as used, + * so Disable the channel + */ + //go dma_regs->CONTROL.Field.ENABLE = 0; + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2M_ENABLE; + outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); + + /* + * Must read the control register back after a write. + */ + //go read_back = dma_regs->CONTROL.Value; + read_back = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + + /* + * Indicate that this channel is in the pause by + * starvation state by setting the pause bit to true. + */ + dma->pause = TRUE; + } + } + /* + * Next Frame Buffer Interrupt. If there's a new buffer program it + * Check if this is the last buffer in the transfer, + * and if it is, disable the NFB int to prevent being + * interrupted for another buffer when we know there won't be + * another. + */ + if(dma_int == NFB) + { + DPRINTK("5 "); + + if(dma->total_buffers) + { + DPRINTK("6 "); + /* + * The iCurrentBuffer has already been transfered. so add the + * byte count from the current buffer to the total byte count. + */ + dma->total_bytes = dma->total_bytes + + dma->buffer_queue[dma->current_buffer].size; + + /* + * Mark the Current Buffer as used. + */ + dma->buffer_queue[dma->current_buffer].used = TRUE; + + /* + * Increment the used buffer counter + */ + dma->used_buffers++; + + DPRINTK("#%d", dma->current_buffer); + + if((dma->buffer_queue[ + (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].last) || + (dma->new_buffers == 0) || (dma->xfer_enable == FALSE)) + { + DPRINTK("7 "); + + /* + * This is the last Buffer in this transaction, so disable + * the NFB interrupt. We shouldn't get an NFB int when the + * FSM moves to the ON state where it would typically get the + * NFB int indicating a new buffer can be programmed. + * Instead, once in the ON state, the DMA will just proceed + * to complet the transfer of the current buffer, move the + * FSB directly to the STALL state where a STALL interrupt + * will be generated. + */ + //go dma_regs->CONTROL.Field.NFBINTEN = 0; + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2M_NFBINTEN ; + outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); + + /* + * The current buffer has been transferred, so increment + * the current buffer counter to reflect this. + */ + dma->current_buffer = (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS; + + DPRINTK("End of NFB handling. \n"); + DPRINTK("STATUS - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_STATUS) ); + DPRINTK("CONTROL - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_CONTROL) ); + DPRINTK("REMAIN - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_REMAIN) ); + DPRINTK("PPALLOC - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_PPALLOC) ); + DPRINTK("BASE0 - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_BASE0) ); + DPRINTK("MAXCNT0 - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_MAXCNT0) ); + DPRINTK("CURRENT0 - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_CURRENT0) ); + DPRINTK("BASE1 - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_BASE1) ); + DPRINTK("MAXCNT1 - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_MAXCNT1) ); + DPRINTK("CURRENT1 - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_CURRENT1) ); + + DPRINTK("Buffer buf_id source size last used \n"); + for(loop = 0; loop < 32; loop ++) + { + DPRINTK("%d 0x%x 0x%x 0x%x %d %d \n", + loop, dma->buffer_queue[loop].buf_id, dma->buffer_queue[loop].source, + dma->buffer_queue[loop].size, + dma->buffer_queue[loop].last, dma->buffer_queue[loop].used); + } + DPRINTK("pause 0x%x 0x%x 0x%x %d %d \n", + dma->pause_buf.buf_id, dma->pause_buf.source, dma->pause_buf.size, + dma->pause_buf.last, dma->pause_buf.used); + + DPRINTK("Pause - %d \n", dma->pause); + DPRINTK("xfer_enable - %d \n", dma->xfer_enable); + DPRINTK("total bytes - 0x%x \n", dma->total_bytes); + DPRINTK("total buffer - %d \n", dma->total_buffers); + DPRINTK("new buffers - %d \n", dma->new_buffers); + DPRINTK("current buffer - %d \n", dma->current_buffer); + DPRINTK("last buffer - %d \n", dma->last_buffer); + DPRINTK("used buffers - %d \n", dma->used_buffers); + DPRINTK("callback addr - 0x%x \n", dma->callback); + + } + else if(dma->new_buffers) + { + DPRINTK("8 "); + /* + * we have a new buffer, so increment the current buffer to + * point to the next buffer, which is already programmed into + * the DMA. Next time around, it'll be pointing to the + * current buffer. + */ + dma->current_buffer = (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS; + + /* + * we know we have a new buffer to program as the next + * buffer, so check which set of SAR_BASE/DAR_BASE/BCR registers + * to program. + */ + //go if(dma_regs->STATUS.Field.NB) + if( inl(M2M_reg_base+M2M_OFFSET_STATUS) & STATUS_M2M_NB ) + { + /* + * Set the SAR_BASE1/DAR_BASE1/BCR1 registers with values from the + * next buffer in the queue. + */ + //go dma_regs->SAR_BASE1.Field.SAR_BASE1 = dma->buffer_queue[ + //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source; + + outl( dma->buffer_queue[(dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS].source, + M2M_reg_base+M2M_OFFSET_SAR_BASE1 ); + + //go dma_regs->DAR_BASE1.Field.DAR_BASE1 = dma->buffer_queue[ + //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].dest; + + outl( dma->buffer_queue[(dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS].dest, + M2M_reg_base+M2M_OFFSET_DAR_BASE1 ); + + //go dma_regs->BCR1.Field.BCR1 = dma->buffer_queue[ + //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size; + + outl( dma->buffer_queue[(dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS].size, + M2M_reg_base+M2M_OFFSET_BCR1 ); + } + else + { + /* + * Set the SAR_BASE0/DAR_BASE0/BCR0 registers with values from the + * next buffer in the queue. + */ + //go dma_regs->SAR_BASE0.Field.SAR_BASE0 = dma->buffer_queue[ + //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source; + + outl( dma->buffer_queue[(dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS].source, + M2M_reg_base+M2M_OFFSET_SAR_BASE0 ); + + //go dma_regs->DAR_BASE0.Field.DAR_BASE0 = dma->buffer_queue[ + //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].dest; + + outl( dma->buffer_queue[(dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS].dest, + M2M_reg_base+M2M_OFFSET_DAR_BASE0 ); + + //go dma_regs->BCR0.Field.BCR0 = dma->buffer_queue[ + //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size; + + outl( dma->buffer_queue[(dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS].size, + M2M_reg_base+M2M_OFFSET_BCR0 ); + } + + /* + * Decrement the new buffers counter + */ + dma->new_buffers--; + } + } + /* + * Total number of buffers is 0 - really we should never get here, + * but just in case. + */ + else + { + DPRINTK("9 \n"); + + /* + * No new buffers to transfer, so Disable the channel + */ + //go dma_regs->CONTROL.Field.ENABLE = 0; + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2M_ENABLE; + outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); + + /* + * Indicate that the channel is paused by starvation. + */ + dma->pause = 1; + } + } + + /* + * Done interrupt generated, indicating that the transfer is complete. + */ + if(dma_int == DONE) + { + /* + * Clear the interrupt. + */ + //go dma_regs->INTERRUPT.Field.DONEINT = 0; + uiINTERRUPT = inl(M2M_reg_base+M2M_OFFSET_INTERRUPT); + uiINTERRUPT &= ~INTERRUPT_M2M_DONEINT; + outl( uiINTERRUPT, M2M_reg_base+M2M_OFFSET_INTERRUPT ); + + /* + * Disable the channel. + */ + //go dma_regs->CONTROL.Field.ENABLE = 0; + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2M_ENABLE; + outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); + + /* + * Indicate that we're in the stopped mode. + */ + dma->pause = 1; + dma->xfer_enable = 0; + } + + /* + * Make sure the interrupt was valid, and if it was, then check + * if a callback function was installed for this DMA channel. If a + * callback was installed call it. + */ + if((dma_int != UNDEF_INT) && dma->callback) + { + dma->callback(dma_int, dma->device, dma->user_data); + } +} + +/***************************************************************************** + * + * dma_m2p_irq_handler + * + * + * + ****************************************************************************/ +static void +dma_m2p_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + ep93xx_dma_t *dma = (ep93xx_dma_t *) dev_id; + //go DMAM2P volatile * dma_regs = (DMAM2P *)dma->reg_base; + unsigned int M2P_reg_base = dma->reg_base; + unsigned int read_back; + ep93xx_dma_dev_t dma_int = UNDEF_INT; + unsigned int loop, uiCONTROL, uiINTERRUPT; + + /* + * Determine what kind of dma interrupt this is. + */ + //go if(dma_regs->INTERRUPT.Field.STALLINT) + //go else if(dma_regs->INTERRUPT.Field.NFBINT) + //go else if(dma_regs->INTERRUPT.Field.CHERRORINT) + + if( inl(M2P_reg_base+M2P_OFFSET_INTERRUPT) & INTERRUPT_M2P_STALLINT ) + dma_int = STALL; + else if( inl(M2P_reg_base+M2P_OFFSET_INTERRUPT) & INTERRUPT_M2P_NFBINT ) + dma_int = NFB; + else if( inl(M2P_reg_base+M2P_OFFSET_INTERRUPT) & INTERRUPT_M2P_CHERRORINT ) + dma_int = CHERROR; + + /* + * Stall Interrupt: The Channel is stalled, meaning nothing is + * programmed to transfer right now. So, we're back to the + * beginnning. If there's a buffer to transfer, program it into + * max and base 0 registers. + */ + if(dma_int == STALL) + { + DPRINTK("1 "); + + if(dma->total_buffers) + { + /* + * The current_buffer has already been tranfered, so add the + * byte count to the total_bytes field. + */ + dma->total_bytes = dma->total_bytes + + dma->buffer_queue[dma->current_buffer].size; + + /* + * Mark the current_buffer as used. + */ + dma->buffer_queue[dma->current_buffer].used = TRUE; + + /* + * Increment the used buffer counter + */ + dma->used_buffers++; + + DPRINTK("#%d", dma->current_buffer); + + /* + * Increment the current_buffer + */ + dma->current_buffer = (dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS; + + /* + * check if there's a new buffer to transfer. + */ + if(dma->new_buffers && dma->xfer_enable) + { + /* + * We have a new buffer to transfer so program in the buffer + * values. Since a STALL interrupt was triggered, we + * program the base0 and maxcnt0 + * + * Set the MAXCNT0 register with the buffer size + */ + //go dma_regs->MAXCNT0.Field.MAXCNT0 = + //go dma->buffer_queue[dma->current_buffer].size; + outl( dma->buffer_queue[dma->current_buffer].size, + M2P_reg_base+M2P_OFFSET_MAXCNT0 ); + + /* + * Set the BASE0 register with the buffer base address + */ + //go dma_regs->BASE0.Field.BASE0 = + //go dma->buffer_queue[dma->current_buffer].source; + outl( dma->buffer_queue[dma->current_buffer].source, + M2P_reg_base+M2P_OFFSET_BASE0 ); + + /* + * Decrement the new buffer counter + */ + dma->new_buffers--; + + if(dma->new_buffers) + { + DPRINTK("A "); + /* + * Set the MAXCNT1 register with the buffer size + */ + //go dma_regs->MAXCNT1.Field.MAXCNT1 = + //go dma->buffer_queue[(dma->current_buffer + 1) % + //go MAX_EP93XX_DMA_BUFFERS].size; + outl( dma->buffer_queue[(dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS].size, + M2P_reg_base+M2P_OFFSET_MAXCNT1 ); + + /* + * Set the BASE1 register with the buffer base address + */ + //go dma_regs->BASE1.Field.BASE1 = + //go dma->buffer_queue[dma->current_buffer + 1 % + //go MAX_EP93XX_DMA_BUFFERS].source; + outl( dma->buffer_queue[dma->current_buffer + 1 % + MAX_EP93XX_DMA_BUFFERS].source, + M2P_reg_base+M2P_OFFSET_BASE1 ); + + /* + * Decrement the new buffer counter + */ + dma->new_buffers--; + + /* + * Enable the NFB Interrupt. + */ + //go dma_regs->CONTROL.Field.NFBINTEN = 1; + uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); + uiCONTROL |= CONTROL_M2P_NFBINTEN; + outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); + } + } + /* + * No new buffers. + */ + else + { + DPRINTK("2 \n"); + /* + * There's a chance we setup both buffer descriptors, but + * didn't service the NFB quickly enough, causing the channel + * to transfer both buffers, then enter the stall state. + * So, we need to be able to process the second buffer. + */ + if((dma->used_buffers + dma->new_buffers) < dma->total_buffers) + { + DPRINTK("3 "); + + /* + * The current_buffer has already been tranfered, so add the + * byte count to the total_bytes field. + */ + dma->total_bytes = dma->total_bytes + + dma->buffer_queue[dma->current_buffer].size; + + /* + * Mark the current_buffer as used. + */ + dma->buffer_queue[dma->current_buffer].used = TRUE; + + /* + * Increment the used buffer counter + */ + dma->used_buffers++; + + DPRINTK("#%d", dma->current_buffer); + + /* + * Increment the current buffer pointer. + */ + dma->current_buffer = (dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS; + + } + + /* + * No new buffers to transfer, so disable the channel. + */ + //go dma_regs->CONTROL.Field.ENABLE = 0; + uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2P_ENABLE; + outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); + + /* + * Indicate that this channel is in the pause by starvation + * state by setting the pause bit to true. + */ + dma->pause = TRUE; + + DPRINTK("STATUS - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_STATUS) ); + DPRINTK("CONTROL - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CONTROL) ); + DPRINTK("REMAIN - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_REMAIN) ); + DPRINTK("PPALLOC - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_PPALLOC) ); + DPRINTK("BASE0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE0) ); + DPRINTK("MAXCNT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT0) ); + DPRINTK("CURRENT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT0) ); + DPRINTK("BASE1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE1) ); + DPRINTK("MAXCNT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT1) ); + DPRINTK("CURRENT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT1) ); + + DPRINTK("Buffer buf_id source size last used \n"); + for(loop = 0; loop < 32; loop ++) + { + DPRINTK("%d 0x%x 0x%x 0x%x %d %d \n", + loop, dma->buffer_queue[loop].buf_id, dma->buffer_queue[loop].source, + dma->buffer_queue[loop].size, + dma->buffer_queue[loop].last, dma->buffer_queue[loop].used); + } + DPRINTK("pause 0x%x 0x%x 0x%x %d %d \n", + dma->pause_buf.buf_id, dma->pause_buf.source, dma->pause_buf.size, + dma->pause_buf.last, dma->pause_buf.used); + + DPRINTK("Pause - %d \n", dma->pause); + DPRINTK("xfer_enable - %d \n", dma->xfer_enable); + DPRINTK("total bytes - 0x%x \n", dma->total_bytes); + DPRINTK("total buffer - %d \n", dma->total_buffers); + DPRINTK("new buffers - %d \n", dma->new_buffers); + DPRINTK("current buffer - %d \n", dma->current_buffer); + DPRINTK("last buffer - %d \n", dma->last_buffer); + DPRINTK("used buffers - %d \n", dma->used_buffers); + DPRINTK("callback addr - 0x%x \n", dma->callback); + } + } + /* + * Total number of buffers in the queue is 0. + */ + else + { + /* + * No buffers to transfer, or old buffers to mark as used, + * so Disable the channel + */ + //go dma_regs->CONTROL.Field.ENABLE = 0; + uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2P_ENABLE; + outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); + + /* + * Must read the control register back after a write. + */ + //go read_back = dma_regs->CONTROL.Value; + read_back = inl(M2P_reg_base+M2P_OFFSET_CONTROL); + + /* + * Indicate that this channel is in the pause by + * starvation state by setting the pause bit to true. + */ + dma->pause = TRUE; + } + } + /* + * Next Frame Buffer Interrupt. If there's a new buffer program it + * Check if this is the last buffer in the transfer, + * and if it is, disable the NFB int to prevent being + * interrupted for another buffer when we know there won't be + * another. + */ + if(dma_int == NFB) + { + DPRINTK("5 "); + + if(dma->total_buffers) + { + DPRINTK("6 "); + /* + * The iCurrentBuffer has already been transfered. so add the + * byte count from the current buffer to the total byte count. + */ + dma->total_bytes = dma->total_bytes + + dma->buffer_queue[dma->current_buffer].size; + + /* + * Mark the Current Buffer as used. + */ + dma->buffer_queue[dma->current_buffer].used = TRUE; + + /* + * Increment the used buffer counter + */ + dma->used_buffers++; + + DPRINTK("#%d", dma->current_buffer); + + + if((dma->buffer_queue[ + (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].last) || + (dma->new_buffers == 0) || (dma->xfer_enable == FALSE)) + { + DPRINTK("7 "); + + /* + * This is the last Buffer in this transaction, so disable + * the NFB interrupt. We shouldn't get an NFB int when the + * FSM moves to the ON state where it would typically get the + * NFB int indicating a new buffer can be programmed. + * Instead, once in the ON state, the DMA will just proceed + * to complet the transfer of the current buffer, move the + * FSB directly to the STALL state where a STALL interrupt + * will be generated. + */ + //go dma_regs->CONTROL.Field.NFBINTEN = 0; + uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2P_NFBINTEN; + outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); + + /* + * The current buffer has been transferred, so increment + * the current buffer counter to reflect this. + */ + dma->current_buffer = (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS; + + DPRINTK("End of NFB handling. \n"); + DPRINTK("STATUS - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_STATUS) ); + DPRINTK("CONTROL - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CONTROL) ); + DPRINTK("REMAIN - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_REMAIN) ); + DPRINTK("PPALLOC - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_PPALLOC) ); + DPRINTK("BASE0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE0) ); + DPRINTK("MAXCNT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT0) ); + DPRINTK("CURRENT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT0) ); + DPRINTK("BASE1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE1) ); + DPRINTK("MAXCNT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT1) ); + DPRINTK("CURRENT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT1) ); + + DPRINTK("Buffer buf_id source size last used \n"); + for(loop = 0; loop < 32; loop ++) + { + DPRINTK("%d 0x%x 0x%x 0x%x %d %d \n", + loop, dma->buffer_queue[loop].buf_id, dma->buffer_queue[loop].source, + dma->buffer_queue[loop].size, + dma->buffer_queue[loop].last, dma->buffer_queue[loop].used); + } + DPRINTK("pause 0x%x 0x%x 0x%x %d %d \n", + dma->pause_buf.buf_id, dma->pause_buf.source, dma->pause_buf.size, + dma->pause_buf.last, dma->pause_buf.used); + + DPRINTK("Pause - %d \n", dma->pause); + DPRINTK("xfer_enable - %d \n", dma->xfer_enable); + DPRINTK("total bytes - 0x%x \n", dma->total_bytes); + DPRINTK("total buffer - %d \n", dma->total_buffers); + DPRINTK("new buffers - %d \n", dma->new_buffers); + DPRINTK("current buffer - %d \n", dma->current_buffer); + DPRINTK("last buffer - %d \n", dma->last_buffer); + DPRINTK("used buffers - %d \n", dma->used_buffers); + DPRINTK("callback addr - 0x%x \n", dma->callback); + + } + else if(dma->new_buffers) + { + DPRINTK("8 "); + /* + * we have a new buffer, so increment the current buffer to + * point to the next buffer, which is already programmed into + * the DMA. Next time around, it'll be pointing to the + * current buffer. + */ + dma->current_buffer = (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS; + + /* + * we know we have a new buffer to program as the next + * buffer, so check which set of MAXCNT and BASE registers + * to program. + */ + //go if(dma_regs->STATUS.Field.NEXTBUFFER) + if( inl(M2P_reg_base+M2P_OFFSET_STATUS) & STATUS_M2P_NEXTBUFFER ) + { + /* + * Set the MAXCNT1 register with the buffer size + */ + //go dma_regs->MAXCNT1.Field.MAXCNT1 = dma->buffer_queue[ + //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size; + outl( dma->buffer_queue[ + (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size, + M2P_reg_base+M2P_OFFSET_MAXCNT1 ); + + /* + * Set the BASE1 register with the buffer base address + */ + //go dma_regs->BASE1.Field.BASE1 = dma->buffer_queue[ + //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source; + outl( dma->buffer_queue[ + (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source, + M2P_reg_base+M2P_OFFSET_BASE1 ); + } + else + { + /* + * Set the MAXCNT0 register with the buffer size + */ + //go dma_regs->MAXCNT0.Field.MAXCNT0 = dma->buffer_queue[ + //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size; + outl( dma->buffer_queue[ + (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size, + M2P_reg_base+M2P_OFFSET_MAXCNT0 ); + + /* + * Set the BASE0 register with the buffer base address + */ + //go dma_regs->BASE0.Field.BASE0 = dma->buffer_queue[ + //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source; + outl( dma->buffer_queue[ + (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source, + M2P_reg_base+M2P_OFFSET_BASE0 ); + } + + /* + * Decrement the new buffers counter + */ + dma->new_buffers--; + } + } + /* + * Total number of buffers is 0 - really we should never get here, + * but just in case. + */ + else + { + DPRINTK("9 \n"); + + /* + * No new buffers to transfer, so Disable the channel + */ + //go dma_regs->CONTROL.Field.ENABLE = 0; + uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2P_ENABLE; + outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); + } + } + /* + * Channel Error Interrupt, or perhipheral interrupt, specific to the + * memory to/from peripheral channels. + */ + if(dma_int == CHERROR) + { + /* + * just clear the interrupt, it's really up to the peripheral + * driver to determine if any further action is necessary. + */ + //go dma_regs->INTERRUPT.Field.CHERRORINT = 0; + uiINTERRUPT = inl(M2P_reg_base+M2P_OFFSET_INTERRUPT); + uiINTERRUPT &= ~INTERRUPT_M2P_CHERRORINT; + outl( uiINTERRUPT, M2P_reg_base+M2P_OFFSET_INTERRUPT ); + } + + + /* + * Make sure the interrupt was valid, and if it was, then check + * if a callback function was installed for this DMA channel. If a + * callback was installed call it. + */ + if((dma_int != UNDEF_INT) && dma->callback) + { + dma->callback(dma_int, dma->device, dma->user_data); + } +} + +/***************************************************************************** + * + * ep9312_dma_open_m2p(int device) + * + * Description: This function will attempt to open a M2P/P2M DMA channel. + * If the open is successful, the channel number is returned, + * otherwise a negative number is returned. + * + * Parameters: + * device: device for which the dma channel is requested. + * + ****************************************************************************/ +static int +dma_open_m2p(int device) +{ + int channel = -1; + unsigned int loop; + //go DMAM2P * regs; + unsigned int M2P_reg_base; + unsigned int uiPWRCNT; + + DPRINTK("DMA Open M2P with hw dev %d\n", device); + + + /* + * Lock the dma channel list. + */ + spin_lock(dma_list_lock); + DPRINTK("1\n"); + /* + * Verify that the device requesting DMA isn't already using a DMA channel + */ + if (device >= 10) + { + loop = 1; // Rx transfer requested + } + else + { + loop = 0; // Tx transfer requested + } + + for(; loop < 10; loop = loop + 2) + { + /* + * Before checking for a matching device, check that the + * channel is in use, otherwise the device field is + * invalid. + */ + if(dma_chan[loop].ref_count) + { + if(device == dma_chan[loop].device) + { + DPRINTK("DMA Open M2P - Error\n"); + /* + * Fail. + */ + return(-1); + } + } + } + + /* + * Get a DMA channel instance for the given hardware device. + * If this is a TX look for even numbered channels, else look for + * odd numbered channels + */ + if(device >= 10) + { + loop = 1; /* Rx transfer requested */ + } + else + { + loop = 0; /* Tx transfer requested */ + } + + for(; loop < 10; loop = loop + 2) + { + if(!dma_chan[loop].ref_count) + { + /* + * Capture the channel and increment the reference count. + */ + channel = loop; + dma_chan[channel].ref_count++; + break; + } + } + + /* + * Unlock the dma channel list. + */ + spin_unlock(dma_list_lock); + + /* + * See if we got a valid channel. + */ + if(channel < 0) + { + /* + * Fail. + */ + return(-1); + } + + /* + * Point regs to the correct dma channel register base. + */ + //go regs = (DMAM2P *)(dma_chan[channel].reg_base); + M2P_reg_base = dma_chan[channel].reg_base; + + /* + * Turn on the clock for the specified DMA channel + * TODO: need to use the correct register name for the + * power control register. + */ + uiPWRCNT = inl(SYSCON_PWRCNT); + switch(channel) + { + case 0: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH0; + break; + } + + case 1: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH1; + break; + } + + case 2: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH2; + break; + } + + case 3: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH3; + break; + } + + case 4: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH4; + break; + } + + case 5: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH5; + break; + } + + case 6: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH6; + break; + } + + case 7: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH7; + break; + } + case 8: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH8; + break; + } + case 9: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH9; + break; + } + + default: + { + return(-1); + } + } + outl( uiPWRCNT, SYSCON_PWRCNT ); + + /*DPRINTK("DMA Open - power control: 0x%x \n", inl(SYSCON_PWRCNT) ); */ + + /* + * Clear out the control register before any further setup. + */ + //go regs->CONTROL.Value = 0; + outl( 0, M2P_reg_base+M2P_OFFSET_CONTROL ); + + /* + * Setup the peripheral port value in the DMA channel registers. + */ + if(device < 10) + { + //go regs->PPALLOC.Value = (unsigned int)device; + outl( (unsigned int)device, M2P_reg_base+M2P_OFFSET_PPALLOC ); + } + else + { + //go regs->PPALLOC.Value = (unsigned int)(device - 10); + outl( (unsigned int)(device - 10), M2P_reg_base+M2P_OFFSET_PPALLOC ); + } + + /* + * Let's hold on to the value of the Hw device for comparison later. + */ + dma_chan[channel].device = device; + + /* + * Success. + */ + return(channel); +} + +/***************************************************************************** + * + * dma_open_m2m(int device) + * + * Description: This function will attempt to open a M2M DMA channel. + * If the open is successful, the channel number is returned, + * otherwise a negative number is returned. + * + * Parameters: + * device: device for which the dma channel is requested. + * + ****************************************************************************/ +static int +dma_open_m2m(int device) +{ + int channel = -1; + unsigned int loop; + //go DMAM2M * regs; + unsigned int M2M_reg_base; + unsigned int uiPWRCNT, uiCONTROL; + + DPRINTK("DMA Open M2M with hw dev %d\n", device); + + + /* + * Lock the dma channel list. + */ + spin_lock(dma_list_lock); + DPRINTK("1\n"); + + /* + * Check if this device is already allocated a channel. + * TODO: can one M2M device be allocated multiple channels? + */ + for(loop = DMA_MEMORY; loop < UNDEF; loop++) + { + /* + * Before checking for a matching device, check that the + * channel is in use, otherwise the device field is + * invalid. + */ + if(dma_chan[loop].ref_count) + { + if(device == dma_chan[loop].device) + { + DPRINTK("Error - dma_open_m2m - already allocated channel\n"); + + /* + * Fail. + */ + return(-1); + } + } + } + + /* + * Get a DMA channel instance for the given hardware device. + */ + for(loop = 10; loop < 12; loop++) + { + if(!dma_chan[loop].ref_count) + { + /* + * Capture the channel and increment the reference count. + */ + channel = loop; + dma_chan[channel].ref_count++; + break; + } + } + + /* + * Unlock the dma channel list. + */ + spin_unlock(dma_list_lock); + + /* + * See if we got a valid channel. + */ + if(channel < 0) + { + /* + * Fail. + */ + return(-1); + } + + /* + * Point regs to the correct dma channel register base. + */ + // regs = (DMAM2M *)(dma_chan[channel].reg_base); + M2M_reg_base = dma_chan[channel].reg_base; + + /* + * Turn on the clock for the specified DMA channel + * TODO: need to use the correct register name for the + * power control register. + */ + uiPWRCNT = inl(SYSCON_PWRCNT); + switch(channel) + { + case 10: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2MCH0; + break; + } + + case 11: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2MCH1; + break; + } + + default: + { + return(-1); + } + } + outl( uiPWRCNT, SYSCON_PWRCNT ); + + DPRINTK("DMA Open - power control: 0x%x \n", inl(SYSCON_PWRCNT) ); + + /* + * Clear out the control register before any further setup. + */ + //go regs->CONTROL.Value = 0; + outl( 0, M2M_reg_base+M2M_OFFSET_CONTROL ); + + /* + * Setup the transfer mode and the request source selection within + * the DMA M2M channel registers. + */ + switch(device) + { + case DMA_MEMORY: + { + //go regs->CONTROL.Field.TM = 0; + //go regs->CONTROL.Field.RSS = 0; + + // Clear TM field, set RSS field to 0 + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + uiCONTROL &= ~(CONTROL_M2M_TM_MASK | CONTROL_M2M_RSS_MASK); + outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); + + break; + } + + case DMA_IDE: + { + //go regs->CONTROL.Field.RSS = 3; + //go regs->CONTROL.Field.NO_HDSK = 1; + //go regs->CONTROL.Field.PW = 01; + + // Set RSS field to 3, Set NO_HDSK, Set PW field to 1 + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_PW_MASK); + uiCONTROL |= (3<CONTROL.Field.TM = 2; + //go regs->CONTROL.Field.RSS = 1; + //go regs->CONTROL.Field.NO_HDSK = 1; + + // Set RSS field to 1, Set NO_HDSK, Set TM field to 2 + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_TM_MASK); + uiCONTROL |= (1<CONTROL.Field.TM = 1; + //go regs->CONTROL.Field.RSS = 2; + //go regs->CONTROL.Field.NO_HDSK = 1; + + // Set RSS field to 2, Set NO_HDSK, Set TM field to 1 + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_TM_MASK); + uiCONTROL |= (2<CONTROL.Field.TM = 1; + //go regs->CONTROL.Field.RSS = 0; + + // Set TM field to 2, set RSS field to 0 + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_TM_MASK); + uiCONTROL |= 1<CONTROL.Field.TM = 2; + //go regs->CONTROL.Field.RSS = 0; + + // Set TM field to 2, set RSS field to 0 + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_TM_MASK); + uiCONTROL |= 2<pause || (!dma->pause && dma->xfer_enable)) + { + /* + * DMA channel is not paused, so we can't configure it. + */ + DPRINTK("DMA channel not paused, so can't configure! \n"); + return(-1); + } + + /* + * Mask interrupts. + */ + local_irq_save(flags); + + /* + * Setup a pointer into the dma channel's register set. + */ + //go regs = (DMAM2M *)dma->reg_base; + M2M_reg_base = dma->reg_base; + + /* + * By default we enable the stall interrupt. + */ + //go regs->CONTROL.Field.STALLINTEN = 1; + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + uiCONTROL |= CONTROL_M2M_STALLINTEN; + outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); + + /* + * By default we enable the done interrupt. + */ + //go regs->CONTROL.Field.DONEINTEN = 1; + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + uiCONTROL |= CONTROL_M2M_DONEINTEN; + outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); + + /* + * Set up the transfer control fields based on values passed in + * the flags_m2m field. + */ + //go regs->CONTROL.Field.DAH = flags_m2m & DESTINATION_HOLD; + //go regs->CONTROL.Field.SAH = flags_m2m & SOURCE_HOLD; + //go regs->CONTROL.Field.TM = flags_m2m & TRANSFER_MODE_MASK; + //go regs->CONTROL.Field.PWSC = flags_m2m & WAIT_STATES_MASK; + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + + if( flags_m2m & DESTINATION_HOLD ) + uiCONTROL |= CONTROL_M2M_DAH; + else + uiCONTROL &= ~CONTROL_M2M_DAH; + + if( flags_m2m & SOURCE_HOLD ) + uiCONTROL |= CONTROL_M2M_SAH; + else + uiCONTROL &= ~CONTROL_M2M_SAH; + + uiCONTROL &= ~CONTROL_M2M_TM_MASK; + uiCONTROL |= ((flags_m2m & TRANSFER_MODE_MASK)<callback = callback; + + /* + * Save the user data in the the dma instance for this channel. + */ + dma->user_data = user_data; + + /* + * Put the dma instance into the pause state by setting the + * pause bit to true. + */ + dma->pause = TRUE; + + local_irq_restore(flags); + + /* + * Success. + */ + return(0); +} + +/***************************************************************************** + * + * int dma_start(int handle, unsigned int channels, unsigned int * handles) + * + * Description: Initiate a transfer on up to 3 channels. + * + * handle: handle for the channel to initiate transfer on. + * channels: number of channels to initiate transfers on. + * handles: pointer to an array of handles, one for each channel which + * is to be started. + * + ****************************************************************************/ +static int +dma_start_m2m(int channel, ep93xx_dma_t * dma) +{ + unsigned int flags; + //go DMAM2M * regs = (DMAM2M *)dma->reg_base; + unsigned int M2M_reg_base = dma->reg_base; + unsigned int uiCONTROL; + + /* + * Make sure the channel has at least one buffer in the queue. + */ + if(dma->new_buffers < 1) + { + DPRINTK("DMA Start: Channel starved.\n"); + + /* + * This channel does not have enough buffers queued up, + * so enter the pause by starvation state. + */ + dma->xfer_enable = TRUE; + dma->pause = TRUE; + + /* + * Success. + */ + return(0); + } + + /* + * Mask interrupts while we get this started. + */ + local_irq_save(flags); + + /* + * Set up one or both buffer descriptors with values from the next one or + * two buffers in the queue. By default enable the next frame buffer + * interrupt on the channel. + */ + //go regs->CONTROL.Field.NFBINTEN = 1; + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + uiCONTROL |= CONTROL_M2M_NFBINTEN; + outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); + + /* + * Update the dma channel instance transfer state. + */ + dma->xfer_enable = TRUE; + dma->pause = FALSE; + + /* + * Decrement the new buffers counter. + */ + dma->new_buffers--; + + /* + * Program up the first buffer descriptor with a sourc and destination + * and a byte count. + */ + //go regs->SAR_BASE0.Field.SAR_BASE0 = dma->buffer_queue[dma->current_buffer].source; + outl( dma->buffer_queue[dma->current_buffer].source, + M2M_reg_base+M2M_OFFSET_SAR_BASE0 ); + + //go regs->DAR_BASE0.Field.DAR_BASE0 = dma->buffer_queue[dma->current_buffer].dest; + outl( dma->buffer_queue[dma->current_buffer].dest, + M2M_reg_base+M2M_OFFSET_DAR_BASE0 ); + + //go regs->BCR0.Field.BCR0 = dma->buffer_queue[dma->current_buffer].size; + outl( dma->buffer_queue[dma->current_buffer].size, + M2M_reg_base+M2M_OFFSET_BCR0 ); + + /* + * Now we enable the channel. This initiates the transfer. + */ + //go regs->CONTROL.Field.ENABLE = 1; + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + uiCONTROL |= CONTROL_M2M_ENABLE; + outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); + + /* + * Before restoring irqs set up the second buffer descriptor + * with a second buffer if we have a second buffer. + */ + if(dma->new_buffers) + { + //go regs->SAR_BASE1.Field.SAR_BASE1 = dma->buffer_queue[ + //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source; + outl( dma->buffer_queue[(dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS].source, + M2M_reg_base+M2M_OFFSET_SAR_BASE1 ); + + //go regs->DAR_BASE1.Field.DAR_BASE1 = dma->buffer_queue[ + //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].dest; + outl( dma->buffer_queue[(dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS].dest, + M2M_reg_base+M2M_OFFSET_DAR_BASE1 ); + + //go regs->BCR1.Field.BCR1 = dma->buffer_queue[ + //go (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size; + outl( dma->buffer_queue[(dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS].size, + M2M_reg_base+M2M_OFFSET_BCR1 ); + } + + /* + * If this is a memory to memory transfer, we need to s/w trigger the + * transfer by setting the start bit within the control register. + */ + if(dma->device == DMA_MEMORY) + { + //go regs->CONTROL.Field.START = 1; + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + uiCONTROL |= CONTROL_M2M_START; + outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); + } + + +/* + DPRINTK("DMA - It's been started!!"); + DPRINTK("STATUS - 0x%x \n", inl(M2M_reg_base+M2M_OFFSET_STATUS) ); + DPRINTK("CONTROL - 0x%x \n", inl(M2M_reg_base+M2M_CONTROL.Value) ); + DPRINTK("REMAIN - 0x%x \n", inl(M2M_reg_base+M2M_REMAIN.Value) ); + DPRINTK("PPALLOC - 0x%x \n", inl(M2M_reg_base+M2M_PPALLOC.Value) ); + DPRINTK("BASE0 - 0x%x \n", inl(M2M_reg_base+M2M_BASE0.Value) ); + DPRINTK("MAXCNT0 - 0x%x \n", inl(M2M_reg_base+M2M_MAXCNT0.Value) ); + DPRINTK("CURRENT0 - 0x%x \n", inl(M2M_reg_base+M2M_CURRENT0.Value) ); + DPRINTK("BASE1 - 0x%x \n", inl(M2M_reg_base+M2M_BASE1.Value) ); + DPRINTK("MAXCNT1 - 0x%x \n", inl(M2M_reg_base+M2M_MAXCNT1.Value) ); + DPRINTK("CURRENT1 - 0x%x \n", inl(M2M_reg_base+M2M_CURRENT1.Value) ); + + DPRINTK("Pause - %d \n", dma_pointers[0]->pause); + DPRINTK("xfer_enable - %d \n", dma_pointers[0]->xfer_enable); + DPRINTK("total bytes - 0x%x \n", dma_pointers[0]->total_bytes); + DPRINTK("total buffer - %d \n", dma_pointers[0]->total_buffers); + DPRINTK("new buffers - %d \n", dma_pointers[0]->new_buffers); + DPRINTK("current buffer - %d \n", dma_pointers[0]->current_buffer); + DPRINTK("last buffer - %d \n", dma_pointers[0]->last_buffer); + DPRINTK("used buffers - %d \n", dma_pointers[0]->used_buffers); +*/ + /* + * Unmask irqs + */ + local_irq_restore(flags); + + /* + * Success. + */ + return(0); +} + +/***************************************************************************** + * + * DMA interface functions + * + ****************************************************************************/ + +/***************************************************************************** + * + * int dma_init(int handle, unsigned int flags_m2p, unsigned int flags_m2m, + * dma_callback callback, unsigned int user_data) + * + * Description: Configure the DMA channel and install a callback function. + * + * handle: Handle unique the each instance of the dma interface, used + * to verify this call. + * flags_m2p Flags used to configure an M2P/P2M dma channel and determine + * if a callback function and user_data information are included + * in this call. This field should be NULL if handle represents + * an M2M channel. + * flags_m2m Flags used to configure an M2M dma channel and determine + * if a callback function and user_data information are included + * in this call. This field should be NULL if handle represents + * an M2P/P2M channel. + * callback function pointer which is called near the end of the + * dma channel's irq handler. + * user_data defined by the calling driver. + * + ****************************************************************************/ +int +ep93xx_dma_config(int handle, unsigned int flags_m2p, unsigned int flags_m2m, + dma_callback callback, unsigned int user_data) +{ + int channel; + ep93xx_dma_t * dma; + //go DMAM2P * dma_regs; + int flags; + unsigned int M2P_reg_base, uiCONTROL; + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if(channel < 0) + { + printk(KERN_ERR + "DMA Config: Invalid dma handle.\n"); + + /* + * Fail. + */ + return(-EINVAL); + } + + DPRINTK("DMA Config \n"); + + dma = &dma_chan[channel]; + + local_irq_save(flags); + + /* + * Check if the channel is currently transferring. + */ + if(dma->xfer_enable) + { + local_irq_restore(flags); + + printk("channel is currently transferring\n"); + /* + * Already transferring, invalid command. + */ + return(-EINVAL); + } + + + /* + * Check if this is an m2m function. + */ + if(channel >= 10) + { + local_irq_restore(flags); + + /* + * Call another function to handle m2m config. + */ + return(dma_config_m2m(dma, flags_m2m, callback, user_data)); + } + + /* + * Setup a pointer into the dma channel's register set. + */ + //go dma_regs = (DMAM2P *)dma->reg_base; + M2P_reg_base = dma->reg_base; + + /* + * By default we enable the stall interrupt. + */ + //go dma_regs->CONTROL.Field.STALLINTEN = 1; + uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); + uiCONTROL |= CONTROL_M2P_STALLINTEN; + outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); + + /* + * Configure the channel for an error from the peripheral. + */ + //go dma_regs->CONTROL.Field.CHERRORINTEN = + //go flags_m2p && CHANNEL_ERROR_INT_ENABLE; + uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); + if( flags_m2p && CHANNEL_ERROR_INT_ENABLE ) + uiCONTROL |= CONTROL_M2P_CHERRORINTEN; + else + uiCONTROL &= ~CONTROL_M2P_CHERRORINTEN; + outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); + + + //go dma_regs->CONTROL.Field.ABRT = flags_m2p && CHANNEL_ABORT; + uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); + if( flags_m2p && CHANNEL_ABORT ) + uiCONTROL |= CONTROL_M2P_ABRT; + else + uiCONTROL &= ~CONTROL_M2P_ABRT; + outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); + + + //go dma_regs->CONTROL.Field.ICE = flags_m2p && IGNORE_CHANNEL_ERROR; + uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); + if( flags_m2p && IGNORE_CHANNEL_ERROR ) + uiCONTROL |= CONTROL_M2P_ICE; + else + uiCONTROL &= ~CONTROL_M2P_ICE; + outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); + + /* + * Save the callback function in the dma instance for this channel. + */ + dma->callback = callback; + + /* + * Save the user data in the the dma instance for this channel. + */ + dma->user_data = user_data; + + /* + * Put the dma instance into the pause state by setting the + * pause bit to true. + */ + dma->pause = TRUE; + + local_irq_restore(flags); + + /* + * Success. + */ + return(0); +} + +/***************************************************************************** + * + * int dma_start(int handle, unsigned int channels, unsigned int * handles) + * + * Description: Initiate a transfer on up to 3 channels. + * + * handle: handle for the channel to initiate transfer on. + * channels: number of channels to initiate transfers on. + * handles: pointer to an array of handles, one for each channel which + * is to be started. + * + ****************************************************************************/ +int +ep93xx_dma_start(int handle, unsigned int channels, unsigned int * handles) +{ + ep93xx_dma_t * dma_pointers[3]; + //go DMAM2P * regs[3]; + unsigned int M2P_reg_bases[3]; + unsigned int loop, flags, uiCONTROL; + int channel; + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if(channel < 0) + { + printk(KERN_ERR "DMA Start: Invalid dma handle.\n"); + + /* + * Fail. + */ + return(-EINVAL); + } + + if(channels < 1) + { + printk(KERN_ERR "DMA Start: Invalid parameter.\n"); + + return(-EINVAL); + } + + DPRINTK("DMA Start \n"); + + /* + * Mask off registers. + */ + local_irq_save(flags); + + /* + * Check if this is a start multiple. + */ + if(channels > 1) + { +#if 0 + for(loop = 0; loop < channels; loop++) + { + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if(channel < 0) + { + printk(KERN_ERR "DMA Start: Invalid dma handle.\n"); + + /* + * Fail. + */ + return(-EINVAL); + } + + /* + * Check if this channel is already started. + */ + if(dma_chan[channel].xfer_enable) + { + printk(KERN_ERR + "DMA Start: Invalid command for channel %d.\n", channel); + + /* + * This channel is already transferring, so return an error. + */ + return(-EINVAL); + } + + /* + * Make sure the channel has at least two buffers in the queue. + */ + if(dma_chan[channel].new_buffers < 2) + { + printk(KERN_ERR + "DMA Start: Invalid command for channel %d.\n", channel); + + /* + * This channel does not have enough buffers queued up, + * so return an error. + */ + return(-EINVAL); + } + + /* + * Set up a pointer into the dma instance data for this channel. + */ + dma_pointers[loop] = &dma_chan[channel]; + + /* + * Set up a pointer to the register set for this channel. + */ + //go regs[loop] = (DMAM2P *)dma_pointers[loop]->reg_base; + M2P_reg_bases[loop] = dma_pointers[loop]->reg_base; + + } +#endif + DPRINTK("DMA ERROR: Start, multiple start not supported yet \n"); + return(-1); + } + /* + * Only one channel + */ + else + { + /* + * Check if this channel is already transferring. + */ + if(dma_chan[channel].xfer_enable && !dma_chan[channel].pause) + { + printk(KERN_ERR + "DMA Start: Invalid command for channel %d.\n", channel); + DPRINTK("DMA Start: Invalid command for channel %d.\n", channel); + + + /* + * This channel is already transferring, so return an error. + */ + return(-EINVAL); + } + + /* + * If this is an M2M channel, call a different function. + */ + if(channel >= 10) + { + /* + * Call the m2m start function. Only start one channel. + */ + return(dma_start_m2m(channel, &dma_chan[channel])); + } + + /* + * Make sure the channel has at least one buffer in the queue. + */ + if(dma_chan[channel].new_buffers < 1) + { + DPRINTK("DMA Start: Channel starved.\n"); + + /* + * This channel does not have enough buffers queued up, + * so enter the pause by starvation state. + */ + dma_chan[channel].xfer_enable = TRUE; + dma_chan[channel].pause = TRUE; + + /* + * Success. + */ + return(0); + } + + /* + * Set up a dma instance pointer for this dma channel. + */ + dma_pointers[0] = &dma_chan[channel]; + + /* + * Set up a pointer to the register set for this channel. + */ + //go regs[0] = (DMAM2P *)dma_pointers[0]->reg_base; + M2P_reg_bases[0] = dma_pointers[0]->reg_base; + } + + /* + * Setup both MAXCNT registers with values from the next two buffers + * in the queue, and enable the next frame buffer interrupt on the channel. + */ + for(loop = 0; loop < channels; loop++) + { + /* + * By default we enable the next frame buffer interrupt. + */ + //go regs[loop]->CONTROL.Field.NFBINTEN = 1; + uiCONTROL = inl(M2P_reg_bases[loop]+M2P_OFFSET_CONTROL); + uiCONTROL |= CONTROL_M2P_NFBINTEN; + outl( uiCONTROL, M2P_reg_bases[loop]+M2P_OFFSET_CONTROL ); + + /* + * Check if we need to restore a paused transfer. + * TODO: should check if buf_id == -1 or not. + */ + if(dma_pointers[loop]->pause_buf.buf_id != -1) + { + //go regs[loop]->MAXCNT0.Field.MAXCNT0 = + //go dma_pointers[loop]->pause_buf.size; + outl( dma_pointers[loop]->pause_buf.size, + M2P_reg_bases[loop]+M2P_OFFSET_MAXCNT0 ); + } + else + { + //go regs[loop]->MAXCNT0.Field.MAXCNT0 = + //go dma_pointers[loop]->buffer_queue[dma_pointers[loop]->current_buffer].size; + outl( dma_pointers[loop]->buffer_queue[dma_pointers[loop]->current_buffer].size, + M2P_reg_bases[loop]+M2P_OFFSET_MAXCNT0 ); + } + } + + for(loop = 0; loop < channels; loop++) + { + /* + * Enable the specified dma channels. + */ + //go regs[loop]->CONTROL.Field.ENABLE = 1; + uiCONTROL = inl(M2P_reg_bases[loop]+M2P_OFFSET_CONTROL); + uiCONTROL |= CONTROL_M2P_ENABLE; + outl( uiCONTROL, M2P_reg_bases[loop]+M2P_OFFSET_CONTROL ); + + /* + * Update the dma channel instance transfer state. + */ + dma_pointers[loop]->xfer_enable = TRUE; + dma_pointers[loop]->pause = FALSE; + + if(dma_pointers[loop]->pause_buf.buf_id == -1) + { + dma_pointers[loop]->new_buffers--; + } + } + + /* + * Program up the BASE0 registers for all specified channels, this + * will initiate transfers on all specified channels. + */ + for(loop = 0; loop < channels; loop++) + { + /* + * Check if we need to restore a paused transfer. + */ + if(dma_pointers[loop]->pause_buf.buf_id != -1) + { + //go regs[loop]->BASE0.Field.BASE0 = dma_pointers[loop]->pause_buf.source; + outl( dma_pointers[loop]->pause_buf.source, + M2P_reg_bases[loop]+M2P_OFFSET_BASE0 ); + + /* + * Set the pause buffer to NULL + */ + dma_pointers[loop]->pause_buf.buf_id = -1; + dma_pointers[loop]->pause_buf.size = 0; + } + else + { + //go regs[loop]->BASE0.Field.BASE0 = + //go dma_pointers[loop]->buffer_queue[ + //go dma_pointers[loop]->current_buffer].source; + outl( dma_pointers[loop]->buffer_queue[ + dma_pointers[loop]->current_buffer].source, + M2P_reg_bases[loop]+M2P_OFFSET_BASE0 ); + } + } + + /* + * Before restoring irqs setup the second MAXCNT/BASE + * register with a second buffer. + */ + for(loop = 0; loop < channels; loop++) + { + if(dma_pointers[loop]->new_buffers) + { + //go regs[loop]->MAXCNT1.Field.MAXCNT1 = + //go dma_pointers[loop]->buffer_queue[ + //go (dma_pointers[loop]->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size; + outl( dma_pointers[loop]->buffer_queue[ + (dma_pointers[loop]->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size, + M2P_reg_bases[loop]+M2P_OFFSET_MAXCNT1 ); + + //go regs[loop]->BASE1.Field.BASE1 = + //go dma_pointers[loop]->buffer_queue[ + //go (dma_pointers[loop]->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source; + outl( dma_pointers[loop]->buffer_queue[ + (dma_pointers[loop]->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source, + M2P_reg_bases[loop]+M2P_OFFSET_BASE1 ); + } + } + +/* + DPRINTK("DMA - It's been started!!"); + DPRINTK("STATUS - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_STATUS) ); + DPRINTK("CONTROL - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CONTROL) ); + DPRINTK("REMAIN - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_REMAIN) ); + DPRINTK("PPALLOC - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_PPALLOC) ); + DPRINTK("BASE0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE0) ); + DPRINTK("MAXCNT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT0) ); + DPRINTK("CURRENT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT0) ); + DPRINTK("BASE1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE1) ); + DPRINTK("MAXCNT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT1) ); + DPRINTK("CURRENT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT1) ); + + DPRINTK("Pause - %d \n", dma_pointers[0]->pause); + DPRINTK("xfer_enable - %d \n", dma_pointers[0]->xfer_enable); + DPRINTK("total bytes - 0x%x \n", dma_pointers[0]->total_bytes); + DPRINTK("total buffer - %d \n", dma_pointers[0]->total_buffers); + DPRINTK("new buffers - %d \n", dma_pointers[0]->new_buffers); + DPRINTK("current buffer - %d \n", dma_pointers[0]->current_buffer); + DPRINTK("last buffer - %d \n", dma_pointers[0]->last_buffer); + DPRINTK("used buffers - %d \n", dma_pointers[0]->used_buffers); +*/ + /* + * Unmask irqs + */ + local_irq_restore(flags); + + /* + * Success. + */ + return(0); +} + +/***************************************************************************** + * + * int ep93xx_dma_add_buffer(int handle, unsigned int * address, + * unsigned int size, unsigned int last) + * + * Description: Add a buffer entry to the DMA buffer queue. + * + * handle: handle for the channel to add this buffer to. + * address: Pointer to an integer which is the start address of the + * buffer which is to be added to the queue. + * size: size of the buffer in bytes. + * last: 1 if this is the last buffer in this stream, 0 otherwise. + * + ****************************************************************************/ +int +ep93xx_dma_add_buffer(int handle, unsigned int source, unsigned int dest, + unsigned int size, unsigned int last, + unsigned int buf_id) +{ + unsigned int flags; + ep93xx_dma_t * dma; + int channel; + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if(channel < 0) + { + printk(KERN_ERR + "DMA Add Buffer: Invalid dma handle.\n"); + + /* + * Fail. + */ + return(-EINVAL); + } + + /* + * Get a pointer to the dma instance. + */ + dma = &dma_chan[channel]; + + /* + * Mask interrupts and hold on to the original state. + */ + local_irq_save(flags); + + /* + * If the buffer queue is full, last_buffer is the same as current_buffer and + * we're not tranfering, or last_buffer is pointing to a used buffer, then exit. + * TODO: do I need to do any more checks? + */ + if(dma->total_buffers >= MAX_EP93XX_DMA_BUFFERS) + { + /* + * Restore the state of the irqs + */ + local_irq_restore(flags); + + /* + * Fail. + */ + return(-1); + } + + /* + * Add this buffer to the queue + */ + dma->buffer_queue[dma->last_buffer].source = source; + dma->buffer_queue[dma->last_buffer].dest = dest; + dma->buffer_queue[dma->last_buffer].size = size; + dma->buffer_queue[dma->last_buffer].last = last; + dma->buffer_queue[dma->last_buffer].buf_id = buf_id; + + /* + * Reset the used field of the buffer structure. + */ + dma->buffer_queue[dma->last_buffer].used = FALSE; + + /* + * Increment the End Item Pointer. + */ + dma->last_buffer = (dma->last_buffer + 1) % MAX_EP93XX_DMA_BUFFERS; + + /* + * Increment the new buffers counter and the total buffers counter + */ + dma->new_buffers++; + dma->total_buffers++; + + /* + * restore the interrupt state. + */ + local_irq_restore(flags); + + /* + * Check if the channel was starved into a stopped state. + */ + if(dma->pause && dma->xfer_enable) + { + if(dma->new_buffers >= 1) + { + DPRINTK("DMA - calling start from add after starve. \n"); + + /* + * The channel was starved into a stopped state, and we've got + * 2 new buffers, so start tranferring again. + */ + ep93xx_dma_start(handle, 1, 0); + } + } + + /* + * Success. + */ + return(0); +} + +/***************************************************************************** + * + * int ep93xx_dma_remove_buffer(int handle, unsigned int * address, + * unsigned int * size) + * + * Description: Remove a buffer entry from the DMA buffer queue. If + * buffer was removed successfully, return 0, otherwise + * return -1. + * + * handle: handle for the channel to remove a buffer from. + * address: Pointer to an integer which is filled in with the start + * address of the removed buffer. + * size: Pointer to an integer which is filled in with the size in + * bytes of the removed buffer. + * + ****************************************************************************/ +int +ep93xx_dma_remove_buffer(int handle, unsigned int * buf_id) +{ + unsigned int test; + unsigned int loop; + int return_val = -1; + unsigned int flags; + ep93xx_dma_t *dma; + int channel; + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if(channel < 0) + { + printk(KERN_ERR + "DMA Remove Buffer: Invalid dma handle.\n"); + + /* + * Fail. + */ + return(-EINVAL); + } + + dma = &dma_chan[channel]; + + /* + * Mask interrupts and hold on to the original state. + */ + local_irq_save(flags); + + /* + * Make sure there are used buffers to be returned. + */ + if(dma->used_buffers) + { + test = dma->last_buffer; + + for(loop = 0; loop < MAX_EP93XX_DMA_BUFFERS; loop++) + { + if(dma->buffer_queue[test].used && (dma->buffer_queue[test].buf_id != -1)) + { + /*DPRINTK("buffer %d used \n", test); */ + + /* + * This is a used buffer, fill in the buf_id pointer + * with the buf_id for this buffer. + */ + *buf_id = dma->buffer_queue[test].buf_id; + + /* + * Reset this buffer structure + */ + dma->buffer_queue[test].buf_id = -1; + + /* + * Decrement the used buffer counter, and the total buffer counter. + */ + dma->used_buffers--; + dma->total_buffers--; + + /* + * Successful removal of a buffer, so set the return + * value to 0, then exit this loop. + */ + return_val = 0; + break; + } + + /* + * This buffer isn't used, let's see if the next one is. + */ + test = (test + 1) % MAX_EP93XX_DMA_BUFFERS; + } + } + + /* + * Restore interrupts. + */ + local_irq_restore(flags); + + /* + * Success. + */ + return(return_val); +} + +/***************************************************************************** + * + * int ep93xx_dma_pause(int handle, unsigned int channels, + * unsigned int * handles) + * + * Description: Disable any ongoing transfer for the given channel, retaining + * the state of the current buffer transaction so that upon + * resume, the dma will continue where it left off. + * + * handle: Handle for the channel to be paused. If this is a pause for + * for multiple channels, handle is a valid handle for one of + * the channels to be paused. + * channels: number of channel to pause transfers on. + * handles: Pointer to an array of handles, one for each channel which + * to be paused. If this pause is intended only for one + * channel, this field should be set to NULL. + * + ****************************************************************************/ +int +ep93xx_dma_pause(int handle, unsigned int channels, unsigned int * handles) +{ + unsigned int flags; + ep93xx_dma_t * dma; + int channel; + //go DMAM2P * regs_m2p; + //go DMAM2M * regs_m2m; + unsigned int M2M_reg_base, M2P_reg_base; + + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if(channel < 0) + { + printk(KERN_ERR + "DMA Pause: Invalid dma handle.\n"); + + /* + * Fail. + */ + return(-EINVAL); + } + + DPRINTK("DMA %d: pause \n", channel); + + /* + * Set up a pointer to the dma instance data. + */ + dma = &dma_chan[channel]; + + /* + * Set a pointer to the dma channel registers. + */ + if(channel < 10) + { + //go regs_m2p = dma->reg_base; + M2P_reg_base = dma->reg_base; + } + else + { + //go regs_m2m = dma->reg_base; + M2M_reg_base = dma->reg_base; + } + + /* + * Mask interrupts and hold on to the original state. + */ + local_irq_save(flags); + + /* + * Check if we're already paused. + */ + if(dma->pause) + { + /* + * We're paused, but are we stopped? + */ + if(dma->xfer_enable) + { + /* + * Put the channel in the stopped state. + */ + dma->xfer_enable = FALSE; + } + + DPRINTK("DMA Pause - already paused."); + } + else + { + /* + * Put the channel into the stopped state. + */ + dma->xfer_enable = FALSE; + dma->pause = TRUE; + } + + /* + * restore interrupts. + */ + local_irq_restore(flags); + + /* + * Already paused, so exit. + */ + return(0); + +#if 0 + + /* + * Disable this DMA channel. + */ + if(channel < 10) + { + /* + * Before disabling the channel, get the current state. + */ + //go state = regs_m2p->STATUS.Field.CURRENT; + state = inl(M2P_reg_base+M2P_OFFSET_STATUS) & STATUS_M2P_CURRENT_MASK; + + //go nfb = regs_m2p->STATUS.Field.NEXTBUFFER; + nfb = inl(M2P_reg_base+M2P_OFFSET_STATUS) & STATUS_M2P_NEXTBUFFER; + + /* + * Disable the channel + */ + //go regs_m2p->CONTROL.Field.ENABLE = 0; + uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2P_ENABLE; + outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); + } + else + { + //go regs_m2m->CONTROL.Field.ENABLE = 0; + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2M_ENABLE; + outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); + } + + /* + local_irq_restore(flags); + + mdelay(1); + i2s->i2s_tx0_EN.Value = 0; + + local_irq_save(flags); + */ + + + + /* + * Indicate that the channel stopped transferring, and set the + * pause field. + */ + dma->xfer_enable = FALSE; + dma->pause = TRUE; + + /* + * Save the state of the buffer being transferred. + */ + if(channel < 10) + { + if(state == 2) + { + if(nfb) + { + /* + * Active buffer descriptor is 0 + */ + //go dma->pause_buf.source = regs_m2p->CURRENT0.Field.CURRENT0; + dma->pause_buf.source = + inl( M2P_reg_base+M2P_OFFSET_CURRENT0 ); + + /* + * state is now the buffer descriptor index. + */ + state = 0; + } + else + { + /* + * Active buffer descriptor is 1 + */ + //go dma->pause_buf.source = regs_m2p->CURRENT1.Field.CURRENT1; + dma->pause_buf.source = + inl( M2P_reg_base+M2P_OFFSET_CURRENT1 ); + + /* + * state is now the buffer descriptor index. + */ + state = 1; + } + } + else if(state == 3) + { + if(nfb) + { + /* + * Active buffer descriptor is 1 + */ + //go dma->pause_buf.source = regs_m2p->CURRENT1.Field.CURRENT1; + dma->pause_buf.source = + inl( M2P_reg_base+M2P_OFFSET_CURRENT1 ); + + /* + * state is now the buffer descriptor index. + */ + state = 1; + } + else + { + /* + * Active buffer descriptor is 0 + */ + //go dma->pause_buf.source = regs_m2p->CURRENT0.Field.CURRENT0; + dma->pause_buf.source = + inl( M2P_reg_base+M2P_OFFSET_CURRENT0 ); + + /* + * state is now the buffer descriptor index. + */ + state = 0; + } + } + + /* + * Active buffer descriptor is 0 + */ + //go dma->pause_buf.size = regs_m2p->REMAIN.Field.REMAIN; + dma->pause_buf.size = + inl( M2P_reg_base+M2P_OFFSET_REMAIN ) & M2P_MASK_REMAIN; + + /* + * Set the pause buffer buf_id field to 1 to indicate that this + * buffer has valid data. + */ + dma->pause_buf.buf_id = 1; + + /* + * Reset the nfb variable, it now represents whether or not we need + * to sync up the dma channel instance. + */ + nfb = 0; + + /* + * Check if the active buffer is the current buffer. the channel + * may have started transferring the next buffer, which would mean + * we have to sync up the dma instance data. + */ + //go if(((state == 0) && (dma->buffer_queue[dma->current_buffer].source != + //go regs_m2p->BASE0.Field.BASE0)) || + //go ((state == 1) && (dma->buffer_queue[dma->current_buffer].source != + //go regs_m2p->BASE1.Field.BASE1))) + + if(((state == 0) && (dma->buffer_queue[dma->current_buffer].source != + (inl(M2P_reg_base+M2P_OFFSET_BASE0) & M2P_MASK_BASE0))) || + ((state == 1) && (dma->buffer_queue[dma->current_buffer].source != + (inl(M2P_reg_base+M2P_OFFSET_BASE1) & M2P_MASK_BASE1)))) + { + DPRINTK("Need to sync up \n"); + /* + * We need to sync up the dma channel instance data. + */ + nfb = 1; + } + + if(nfb) + { + /* + * The current buffer is already used at this point. + */ + dma->buffer_queue[dma->current_buffer].used = TRUE; + + /* + * increment the number of used buffers. + */ + dma->used_buffers++; + + DPRINTK("#%d", dma->current_buffer); + + + /* + * Increment the current buffer position. + */ + dma->current_buffer = (dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS; + } + } + /* + * Memory to memory channel. + */ + else + { + } + + DPRINTK("STATUS - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_STATUS) ); + DPRINTK("CONTROL - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CONTROL) ); + DPRINTK("REMAIN - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_REMAIN) ); + DPRINTK("PPALLOC - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_PPALLOC) ); + DPRINTK("BASE0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE0) ); + DPRINTK("MAXCNT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT0) ); + DPRINTK("CURRENT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT0) ); + DPRINTK("BASE1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE1) ); + DPRINTK("MAXCNT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT1) ); + DPRINTK("CURRENT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT1) ); + + DPRINTK("Buffer buf_id source size last used \n"); + for(loop = 0; loop < 32; loop ++) + { + DPRINTK("%d 0x%x 0x%x 0x%x %d %d \n", + loop, dma->buffer_queue[loop].buf_id, dma->buffer_queue[loop].source, dma->buffer_queue[loop].size, + dma->buffer_queue[loop].last, dma->buffer_queue[loop].used); + } + DPRINTK("pause 0x%x 0x%x 0x%x %d %d \n", + dma->pause_buf.buf_id, dma->pause_buf.source, dma->pause_buf.size, + dma->pause_buf.last, dma->pause_buf.used); + + DPRINTK("Pause - %d \n", dma->pause); + DPRINTK("xfer_enable - %d \n", dma->xfer_enable); + DPRINTK("total bytes - 0x%x \n", dma->total_bytes); + DPRINTK("total buffer - %d \n", dma->total_buffers); + DPRINTK("new buffers - %d \n", dma->new_buffers); + DPRINTK("current buffer - %d \n", dma->current_buffer); + DPRINTK("last buffer - %d \n", dma->last_buffer); + DPRINTK("used buffers - %d \n", dma->used_buffers); + DPRINTK("nfb - %d \n", nfb); + DPRINTK("state - %d \n", state); + + + + + /* + * restore interrupts. + */ + local_irq_restore(flags); + + + /* + * Success. + */ + return(0); +#endif +} + +/***************************************************************************** + * + * void ep93xx_dma_flush(int handle) + * + * Description: Flushes all queued buffers and transfers in progress + * for the given channel. Return the buffer entries + * to the calling function. + * + * handle: handle for the channel for which the flush is intended. + * + ****************************************************************************/ +int +ep93xx_dma_flush(int handle) +{ + unsigned int loop, flags; + ep93xx_dma_t * dma; + int channel; + //go DMAM2P * dma_regs; + unsigned int M2P_reg_base; + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if(channel < 0) + { + printk(KERN_ERR + "DMA Flush: Invalid dma handle.\n"); + + /* + * Fail. + */ + return(-EINVAL); + } + + DPRINTK("DMA %d: flush \n", channel); + + /* + * Set up a pointer to the dma instance data for this channel + */ + dma = &dma_chan[channel]; + + /* + * Mask interrupts and hold on to the original state. + */ + local_irq_save(flags); + + for(loop = 0; loop < MAX_EP93XX_DMA_BUFFERS; loop++) + { + dma->buffer_queue[loop].buf_id = -1; + } + + /* + * Set the Current and Last item to zero. + */ + dma->current_buffer = 0; + dma->last_buffer = 0; + + /* + * Reset the Buffer counters + */ + dma->used_buffers = 0; + dma->new_buffers = 0; + dma->total_buffers = 0; + + /* + * reset the Total bytes counter. + */ + dma->total_bytes = 0; + + //go dma_regs = (DMAM2P *)(dma_chan[channel].reg_base); + M2P_reg_base = dma_chan[channel].reg_base; + + /* + * restore interrupts. + */ + local_irq_restore(flags); + + /* + * Success. + */ + return(0); +} + +/***************************************************************************** + * + * int ep93xx_dma_queue_full(int handle) + * + * Description: Query to determine if the DMA queue of buffers for + * a given channel is full. + * 0 = queue is full + * 1 = queue is not full + * + * handle: handle for the channel to query. + * + ****************************************************************************/ +int +ep93xx_dma_queue_full(int handle) +{ + int list_full = 0; + unsigned int flags; + int channel; + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if(channel < 0) + { + printk(KERN_ERR + "DMA Queue Full: Invalid dma handle.\n"); + + /* + * Fail. + */ + return(-EINVAL); + } + + DPRINTK("DMA %d: queue full \n", channel); + + /* + * Mask interrupts and hold on to the original state. + */ + local_irq_save(flags); + + /* + * If the last item is equal to the used item then + * the queue is full. + */ + if(dma_chan[channel].total_buffers < MAX_EP93XX_DMA_BUFFERS) + { + list_full = FALSE; + } + else + { + list_full = TRUE; + } + + /* + * restore interrupts. + */ + local_irq_restore(flags); + + return(list_full); +} + +/***************************************************************************** + * + * int ep93xx_dma_get_position(int handle, unsigned int * buf_id, + unsigned int * total, unsigned int * current_frac) + * + * Description: Takes two integer pointers and fills them with the start + * and current address of the buffer currently transferring + * on the specified DMA channel. + * + * handle: handle for the channel to query. + * buf_id: pointer which is filled in with the buffer id for the + * current buffer transferring on the dma channel. + * buffer being transferred. + * total : pointer which is filled in with the total bytes + * transferred on the channel. + ****************************************************************************/ +int +ep93xx_dma_get_position(int handle, unsigned int * buf_id, + unsigned int * total, unsigned int * current_frac) +{ + int channel; + ep93xx_dma_t * dma; + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if(channel < 0) + { + printk(KERN_ERR "DMA Get Position: Invalid dma handle.\n"); + + /* + * Fail. + */ + return(-EINVAL); + } + + dma = &dma_chan[channel]; + + /* + * TODO: should irqs be disabled here? + */ + + *buf_id = dma->buffer_queue[dma->current_buffer].buf_id; + + *total = dma->total_bytes; + + DPRINTK("DMA buf_id %d, total %d\n", *buf_id, *total); + + /* + * Success. + */ + return(0); +} + +/***************************************************************************** + * + * int ep93xx_dma_get_total(int handle) + * + * Description: Returns the total number of bytes transferred on the + * specified channel since the channel was requested. + * + * handle: handle for the channel to query. + * + ****************************************************************************/ +int +ep93xx_dma_get_total(int handle) +{ + int channel; + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if(channel < 0) + { + printk(KERN_ERR "DMA Get Total: Invalid dma handle.\n"); + + /* + * Fail. + */ + return(-EINVAL); + } + + DPRINTK("DMA %d: total: %d \n", channel, dma_chan[channel].total_bytes); + + /* + * Return the total number of bytes transferred on this channel since + * it was requested. + */ + return(dma_chan[channel].total_bytes); +} + +/***************************************************************************** + * + * int ep93xx_dma_is_done(int handle) + * + * Description: Determines if the specified channel is done + * transferring the requested data. + * + * handle: handle for the channel to query. + * + ****************************************************************************/ +int +ep93xx_dma_is_done(int handle) +{ + ep93xx_dma_t *dma; + int channel; + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if (channel < 0) { + printk(KERN_ERR "ep93xx_dma_is_done: Invalid dma handle.\n"); + return(-EINVAL); + } + + /* + * Get a pointer to the DMA channel state structure. + */ + dma = &dma_chan[channel]; + + /* + * See if there are any buffers remaining to be provided to the HW. + */ + if (dma->new_buffers) + return 0; + + /* + * See if this is a M2P or M2M channel. + */ + if (channel < 10) { + /* + * If the bytes remaining register of the HW is not zero, then + * there is more work to be done. + */ + if (inl(dma->reg_base + M2P_OFFSET_REMAIN) != 0) + return 0; + } else { + /* + * If either byte count register in the HW is not zero, then there + * is more work to be done. + */ + if ((inl(dma->reg_base + M2M_OFFSET_BCR0) != 0) || + (inl(dma->reg_base + M2M_OFFSET_BCR1) != 0)) + return 0; + } + + /* + * The DMA is complete. + */ + return 1; +} + +/***************************************************************************** + * ep93xx_dma_request + * + * Description: This function will allocate a DMA channel for a particular + * hardware peripheral. Before initiating a transfer on the allocated + * channel, the channel must be set up and buffers have to queued up. + * + * handle: pointer to an integer which is filled in with a unique + * handle for this instance of the dma interface. + * device_id string with the device name, primarily used by /proc. + * device hardware device ID for which the requested dma channel will + * transfer data. + * + ****************************************************************************/ +int +ep93xx_dma_request(int * handle, const char *device_id, + ep93xx_dma_dev_t device) +{ + ep93xx_dma_t *dma = NULL; + int channel, error = 0; + unsigned int loop; + //go DMAM2P * dma_regs; + unsigned int M2P_reg_base; + + /* + * Check if the device requesting a DMA channel is a valid device. + */ + if((device >= UNDEF) || (device < 0)) + { + /* + * Invalid device, so return an error. + */ + return(-ENODEV); + } + + /* + * We've got a valid hardware device requesting a DMA channel. + * Now check if the device should open an M2P or M2M channel + */ + if(device < 20) + { + channel = dma_open_m2p(device); + } + else + { + channel = dma_open_m2m(device); + } + + /* + * Check if we successfully opened a DMA channel + */ + if(channel < 0) + { + printk(KERN_ERR + "%s: Could not open dma channel for this device.\n", + device_id); + + /* + * Fail. + */ + return(-EBUSY); + } + + dma = &dma_chan[channel]; + + /* + * Request the appropriate IRQ for the specified channel + */ + if(channel < 10) + { + error = request_irq(dma->irq, dma_m2p_irq_handler, SA_INTERRUPT, + device_id, (void *) dma); + } + else + { + error = request_irq(dma->irq, dma_m2m_irq_handler, SA_INTERRUPT, + device_id, (void *) dma); + } + + /* + * Check for any errors during the irq request + */ + if(error) + { + printk(KERN_ERR + "%s: unable to request IRQ %d for DMA channel\n", + device_id, dma->irq); + /* + * Fail. + */ + return(error); + } + + /* + * Generate a valid handle and exit. + * + * Increment the last valid handle. + * Check for wraparound (unlikely, but we like to be complete). + */ + dma->last_valid_handle++; + + if( (dma->last_valid_handle & DMA_HANDLE_SPECIFIER_MASK) != + (channel << 28) ) + { + /* + * If we wrapped around start over. + */ + dma->last_valid_handle = (channel << 28) + 1; + } + + /* + * Fill in the handle pointer with a valid handle for + * this dma channel instance. + */ + *handle = dma->last_valid_handle; + + DPRINTK("Handle for channel %d: 0x%x\n", channel, *handle); + + /* + * Save the device ID and device name. + */ + dma->device = device; + dma->device_id = device_id; + + /* + * Init all fields within the dma instance. + */ + for(loop = 0; loop < MAX_EP93XX_DMA_BUFFERS; loop++) + { + dma->buffer_queue[loop].buf_id = -1; + } + + /* + * Initialize all buffer queue variables. + */ + dma->current_buffer = 0; + dma->last_buffer = 0; + + dma->new_buffers = 0; + dma->used_buffers = 0; + dma->total_buffers = 0; + + /* + * Initialize the total bytes variable + */ + dma->total_bytes = 0; + + /* + * Initialize the transfer and pause state variables to 0. + */ + dma->xfer_enable = 0; + + dma->pause = 0; + + /* + * Initialize the pause buffer structure. + */ + dma->pause_buf.buf_id = -1; + + /* + * Initialize the callback function and user data fields. + */ + dma->callback = NULL; + + /* + * User data used as a parameter for the Callback function. The user + * sets up the data and sends it with the callback function. + */ + dma->user_data = 0; + + //go dma_regs = (DMAM2P *)dma_chan[channel].reg_base; + M2P_reg_base = dma_chan[channel].reg_base; + + /* + * Debugging message. + */ + DPRINTK("Successfully requested dma channel %d\n", channel); + DPRINTK("STATUS - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_STATUS) ); + DPRINTK("CONTROL - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CONTROL) ); + DPRINTK("REMAIN - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_REMAIN) ); + DPRINTK("PPALLOC - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_PPALLOC) ); + DPRINTK("BASE0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE0) ); + DPRINTK("MAXCNT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT0) ); + DPRINTK("CURRENT0 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT0) ); + DPRINTK("BASE1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_BASE1) ); + DPRINTK("MAXCNT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_MAXCNT1) ); + DPRINTK("CURRENT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT1) ); + + DPRINTK("Buffer source size last used \n"); + for(loop = 0; loop < 5; loop ++) + { + DPRINTK("%d 0x%x 0x%x %d %d \n", + loop, dma->buffer_queue[loop].source, dma->buffer_queue[loop].size, + dma->buffer_queue[loop].last, dma->buffer_queue[loop].used); + } + DPRINTK("pause 0x%x 0x%x %d %d \n", + dma->pause_buf.source, dma->pause_buf.size, + dma->pause_buf.last, dma->pause_buf.used); + + DPRINTK("Pause - %d \n", dma->pause); + DPRINTK("xfer_enable - %d \n", dma->xfer_enable); + DPRINTK("total bytes - 0x%x \n", dma->total_bytes); + DPRINTK("total buffer - %d \n", dma->total_buffers); + DPRINTK("new buffers - %d \n", dma->new_buffers); + DPRINTK("current buffer - %d \n", dma->current_buffer); + DPRINTK("last buffer - %d \n", dma->last_buffer); + DPRINTK("used buffers - %d \n", dma->used_buffers); + + DPRINTK("CURRENT1 - 0x%x \n", inl(M2P_reg_base+M2P_OFFSET_CURRENT1) ); + DPRINTK("VIC0IRQSTATUS - 0x%x, VIC0INTENABLE - 0x%x \n", + *(unsigned int *)(VIC0IRQSTATUS), + *(unsigned int *)(VIC0INTENABLE)); + + /* + * Success. + */ + return(0); +} + +/***************************************************************************** + * + * ep93xx_dma_free + * + * Description: This function will free the dma channel for future requests. + * + * handle: handle for the channel to be freed. + * + ****************************************************************************/ +int +ep93xx_dma_free(int handle) +{ + ep93xx_dma_t *dma; + //go DMAM2P * regs_m2p; + //go DMAM2M * regs_m2m; + unsigned int M2M_reg_base, M2P_reg_base, uiCONTROL; + int channel; + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if(channel < 0) + { + printk(KERN_ERR "DMA Free: Invalid dma handle.\n"); + + /* + * Fail. + */ + return(-EINVAL); + } + + /* + * Get a pointer to the dma instance. + */ + dma = &dma_chan[channel]; + + /* + * Disable the dma channel + */ + if(channel < 10) + { + /* + * M2P channel + */ + //go regs_m2p = dma->reg_base; + M2P_reg_base = dma->reg_base; + + //go regs_m2p->CONTROL.Field.ENABLE = 0; + uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2P_ENABLE; + outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL ); + } + else + { + /* + * M2M channel + */ + //go regs_m2m = dma->reg_base; + M2M_reg_base = dma->reg_base; + + //go regs_m2m->CONTROL.Field.ENABLE = 0; + uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2M_ENABLE; + outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL ); + } + + /* + * Free the interrupt servicing this dma channel + */ + free_irq(dma->irq, (void *) dma); + + /* + * Decrement the reference count for this instance of the dma interface + */ + dma->ref_count--; + + /* + * Set the transfer and pause state variables to 0 + * (unititialized state). + */ + dma->xfer_enable = 0; + dma->pause = 0; + + /* + * Debugging message. + */ + DPRINTK("Successfully freed dma channel %d\n", channel); + + /* + * Success. + */ + return(0); +} + +/***************************************************************************** + * + * ep93xx_dma_init(void) + * + * Description: This function is called during system initialization to + * setup the interrupt number and register set base address for each DMA + * channel. + * + ****************************************************************************/ +static int __init +ep93xx_dma_init(void) +{ + int channel; + + /* + * Init some values in each dma instance. + */ + for(channel = 0; channel < MAX_EP93XX_DMA_CHANNELS; channel++) + { + /* + * IRQ for the specified dma channel. + */ + dma_chan[channel].irq = IRQ_DMAM2P0 + channel; + + /* + * Initial value of the dma channel handle. + */ + dma_chan[channel].last_valid_handle = channel << 28; + + /* + * Give the instance a pointer to the dma channel register + * base. + */ + if(channel < 10) + { + dma_chan[channel].reg_base = DMAM2PChannelBase[channel]; + } + else + { + dma_chan[channel].reg_base = DMAM2MChannelBase[channel - 10]; + } + + /* + * Initialize the reference count for this channel. + */ + dma_chan[channel].ref_count = 0; + } + + DPRINTK("DMA Interface intitialization complete\n"); + + /* + * Success + */ + return 0; +} + +__initcall(ep93xx_dma_init); + + Index: arch/arm/mach-ep93xx/dma_ep93xx.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mach-ep93xx/dma_ep93xx.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mach-ep93xx/dma_ep93xx.h 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/arm/mach-ep93xx/dma_ep93xx.h 29 Sep 2006 22:25:11 -0000 1.2 @@ -1,195 +1,195 @@ -/***************************************************************************** - * - * arch/arm/mach-ep93xx/dma_ep93xx.h - * - * DESCRIPTION: 93XX DMA controller API private defintions. - * - * Copyright Cirrus Logic Corporation, 2003. 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 - * - ****************************************************************************/ -#ifndef _EP93XX_DMA_H_ -#define _EP93XX_DMA_H_ - -#define MAX_EP93XX_DMA_BUFFERS 32 - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef NULL -#define NULL 0 -#endif - -/***************************************************************************** - * - * DMA buffer structure type. - * - ****************************************************************************/ -typedef struct ep93xx_dma_buffer_s -{ - unsigned int source; /* buffer physical source address. */ - unsigned int dest; /* buffer physical destination address, */ - /* only used with the 2 M2M channels. */ - unsigned int size; /* buffer size in bytes */ - unsigned int last; /* 1 if this is the last buffer */ - /* in this transaction. If 1, */ - /* disable the NFBint so we aren't */ - /* interrupted for another buffer */ - /* when we know there won't be another. */ - unsigned int used; /* This field is set to 1 by the DMA */ - /* interface after the buffer is transferred*/ - int buf_id; /* unique identifyer specified by the */ - /* the driver which requested the dma */ -} ep93xx_dma_buffer_t; - -typedef ep93xx_dma_buffer_t * ep93xx_dma_buffer_p; - -/***************************************************************************** - * - * Instance definition for the DMA interface. - * - ****************************************************************************/ -typedef struct ep7312_dma_s -{ - /* - * This 1 when the instance is in use, and 0 when it's not. - */ - unsigned int ref_count; - - /* - * This is the last valid handle for this instance. When giving out a - * new handle this will be incremented and given out. - */ - int last_valid_handle; - - /* - * device specifies one of the 20 DMA hardware ports this - * DMA channel will service. - */ - ep93xx_dma_dev_t device; - - /* - * DMABufferQueue is the queue of buffer structure pointers which the - * dma channel will use to setup transfers. - */ - ep93xx_dma_buffer_t buffer_queue[MAX_EP93XX_DMA_BUFFERS]; - - /* - * currnt_buffer : This is the buffer currently being transfered on - * this channel. - * last_buffer : This is the last buffer for this transfer. - * Note: current_buffer + 1 is already programmed into the dma - * channel as the next buffer to transfer. Don't write - * over either entry. - */ - int current_buffer; - int last_buffer; - - /* - * The following 3 fields are buffer counters. - * - * iNewBuffers: Buffers in the queue which have not been transfered. - * iUsedBuffers: Buffers in the queue which have have been tranferred, - * and are waiting to be returned. - * iTotalBuffers: Total number of buffers in the queue. - */ - int new_buffers; - int used_buffers; - int total_buffers; - - /* - * uiTotalBytes has the total bytes transfered on the channel since the - * last flush. This value does not include the bytes tranfered in the - * current buffer. A byte count is only added after a complete buffer - * is tranfered. - */ - unsigned int total_bytes; - - /* - * Interrupt number for this channel - */ - unsigned int irq; - - /* - * Indicates whether or not the channel is currently enabled to transfer - * data. - */ - unsigned int xfer_enable; - - /* - * pause indicates if the dma channel was paused by calling the pause - * ioctl. - */ - unsigned int pause; - - /* - * buffer structure used during a pause to capture the current - * address and remaining bytes for the buffer actively being transferred - * on the channel. This buffer will be used to reprogram the dma - * channel upon a resume. - */ - ep93xx_dma_buffer_t pause_buf; - - /* - * DMACallback is a function pointer which the calling application can - * use install a function to. this fuction can be used to notify the - * calling application of an interrupt. - */ - dma_callback callback; - - /* - * User data used as a parameter for the Callback function. The user - * sets up the data and sends it with the callback function. - */ - unsigned int user_data; - - /* - * A string representation of the device attached to the channel. - */ - const char * device_id; - - /* - * The register base address for this dma channel. - */ - unsigned int reg_base; - -} ep93xx_dma_t; - -/***************************************************************************** - * - * DMA macros - * - ****************************************************************************/ -#define DMA_HANDLE_SPECIFIER_MASK 0xF0000000 -#define DMA_CH0_HANDLE_SPECIFIER 0x00000000 -#define DMA_CH1_HANDLE_SPECIFIER 0x10000000 -#define DMA_CH2_HANDLE_SPECIFIER 0x20000000 -#define DMA_CH3_HANDLE_SPECIFIER 0x30000000 -#define DMA_CH4_HANDLE_SPECIFIER 0x40000000 -#define DMA_CH5_HANDLE_SPECIFIER 0x50000000 -#define DMA_CH6_HANDLE_SPECIFIER 0x60000000 -#define DMA_CH7_HANDLE_SPECIFIER 0x70000000 -#define DMA_CH8_HANDLE_SPECIFIER 0x80000000 -#define DMA_CH9_HANDLE_SPECIFIER 0x90000000 -#define DMA_CH10_HANDLE_SPECIFIER 0xA0000000 -#define DMA_CH11_HANDLE_SPECIFIER 0xB0000000 - -#endif // _DMADRV_H_ +/***************************************************************************** + * + * arch/arm/mach-ep93xx/dma_ep93xx.h + * + * DESCRIPTION: 93XX DMA controller API private defintions. + * + * Copyright Cirrus Logic Corporation, 2003. 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 + * + ****************************************************************************/ +#ifndef _EP93XX_DMA_H_ +#define _EP93XX_DMA_H_ + +#define MAX_EP93XX_DMA_BUFFERS 32 + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL 0 +#endif + +/***************************************************************************** + * + * DMA buffer structure type. + * + ****************************************************************************/ +typedef struct ep93xx_dma_buffer_s +{ + unsigned int source; /* buffer physical source address. */ + unsigned int dest; /* buffer physical destination address, */ + /* only used with the 2 M2M channels. */ + unsigned int size; /* buffer size in bytes */ + unsigned int last; /* 1 if this is the last buffer */ + /* in this transaction. If 1, */ + /* disable the NFBint so we aren't */ + /* interrupted for another buffer */ + /* when we know there won't be another. */ + unsigned int used; /* This field is set to 1 by the DMA */ + /* interface after the buffer is transferred*/ + int buf_id; /* unique identifyer specified by the */ + /* the driver which requested the dma */ +} ep93xx_dma_buffer_t; + +typedef ep93xx_dma_buffer_t * ep93xx_dma_buffer_p; + +/***************************************************************************** + * + * Instance definition for the DMA interface. + * + ****************************************************************************/ +typedef struct ep9312_dma_s +{ + /* + * This 1 when the instance is in use, and 0 when it's not. + */ + unsigned int ref_count; + + /* + * This is the last valid handle for this instance. When giving out a + * new handle this will be incremented and given out. + */ + int last_valid_handle; + + /* + * device specifies one of the 20 DMA hardware ports this + * DMA channel will service. + */ + ep93xx_dma_dev_t device; + + /* + * DMABufferQueue is the queue of buffer structure pointers which the + * dma channel will use to setup transfers. + */ + ep93xx_dma_buffer_t buffer_queue[MAX_EP93XX_DMA_BUFFERS]; + + /* + * currnt_buffer : This is the buffer currently being transfered on + * this channel. + * last_buffer : This is the last buffer for this transfer. + * Note: current_buffer + 1 is already programmed into the dma + * channel as the next buffer to transfer. Don't write + * over either entry. + */ + int current_buffer; + int last_buffer; + + /* + * The following 3 fields are buffer counters. + * + * iNewBuffers: Buffers in the queue which have not been transfered. + * iUsedBuffers: Buffers in the queue which have have been tranferred, + * and are waiting to be returned. + * iTotalBuffers: Total number of buffers in the queue. + */ + int new_buffers; + int used_buffers; + int total_buffers; + + /* + * uiTotalBytes has the total bytes transfered on the channel since the + * last flush. This value does not include the bytes tranfered in the + * current buffer. A byte count is only added after a complete buffer + * is tranfered. + */ + unsigned int total_bytes; + + /* + * Interrupt number for this channel + */ + unsigned int irq; + + /* + * Indicates whether or not the channel is currently enabled to transfer + * data. + */ + unsigned int xfer_enable; + + /* + * pause indicates if the dma channel was paused by calling the pause + * ioctl. + */ + unsigned int pause; + + /* + * buffer structure used during a pause to capture the current + * address and remaining bytes for the buffer actively being transferred + * on the channel. This buffer will be used to reprogram the dma + * channel upon a resume. + */ + ep93xx_dma_buffer_t pause_buf; + + /* + * DMACallback is a function pointer which the calling application can + * use install a function to. this fuction can be used to notify the + * calling application of an interrupt. + */ + dma_callback callback; + + /* + * User data used as a parameter for the Callback function. The user + * sets up the data and sends it with the callback function. + */ + unsigned int user_data; + + /* + * A string representation of the device attached to the channel. + */ + const char * device_id; + + /* + * The register base address for this dma channel. + */ + unsigned int reg_base; + +} ep93xx_dma_t; + +/***************************************************************************** + * + * DMA macros + * + ****************************************************************************/ +#define DMA_HANDLE_SPECIFIER_MASK 0xF0000000 +#define DMA_CH0_HANDLE_SPECIFIER 0x00000000 +#define DMA_CH1_HANDLE_SPECIFIER 0x10000000 +#define DMA_CH2_HANDLE_SPECIFIER 0x20000000 +#define DMA_CH3_HANDLE_SPECIFIER 0x30000000 +#define DMA_CH4_HANDLE_SPECIFIER 0x40000000 +#define DMA_CH5_HANDLE_SPECIFIER 0x50000000 +#define DMA_CH6_HANDLE_SPECIFIER 0x60000000 +#define DMA_CH7_HANDLE_SPECIFIER 0x70000000 +#define DMA_CH8_HANDLE_SPECIFIER 0x80000000 +#define DMA_CH9_HANDLE_SPECIFIER 0x90000000 +#define DMA_CH10_HANDLE_SPECIFIER 0xA0000000 +#define DMA_CH11_HANDLE_SPECIFIER 0xB0000000 + +#endif // _DMADRV_H_ Index: arch/arm/mach-ep93xx/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mach-ep93xx/irq.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- arch/arm/mach-ep93xx/irq.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/arm/mach-ep93xx/irq.c 30 Jun 2005 22:11:52 -0000 1.3 @@ -78,6 +78,14 @@ { unsigned int i; + /* High level sensitive GPIO interrupt on Port F bit 2 */ + outl(inl(GPIO_PFDDR) & ~(1<<3), GPIO_PFDDR); /* high-Z intr pin */ + outl(inl(GPIO_FDB) & ~(1<<3), GPIO_FDB); /* no debounce */ + outl(inl(GPIO_INTTYPE1) | (1<<3), GPIO_INTTYPE1); /* edge sensitive */ + outl(inl(GPIO_INTTYPE2) | (1<<3), GPIO_INTTYPE2); /* high sensitive */ + outl(1<<3, GPIO_FEOI); /* clear edge */ + outl(inl(GPIO_INTEN) | (1<<3), GPIO_INTEN); /* enable */ + /* * Interrupt bits 0 and 1 are unused */ Index: arch/arm/mach-ep93xx/mm.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mach-ep93xx/mm.c,v retrieving revision 1.1 retrieving revision 1.13 diff -u -r1.1 -r1.13 --- arch/arm/mach-ep93xx/mm.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/arm/mach-ep93xx/mm.c 24 Jan 2007 00:36:06 -0000 1.13 @@ -41,7 +41,6 @@ * 8080 0000 - 809f ffff = APB peripherals (2 Meg) * 8900 0000 - 82ff ffff = TS-7XXX 8bit isa io/mem * 8b00 0000 - 86ff ffff = TS-7XXX 16bit isa io/mem - * a000 0000 - b000 0000 = PCMCIA space */ static struct map_desc ep93xx_io_desc[] __initdata = { @@ -49,23 +48,24 @@ // Virtual Address Physical Addresss Size in Bytes Domain R W C B Last { IO_ADDRESS(EP93XX_AHB_BASE), EP93XX_AHB_BASE, SZ_8M , DOMAIN_IO, 0, 1, 0, 0 }, { IO_ADDRESS(EP93XX_APB_BASE), EP93XX_APB_BASE, SZ_2M , DOMAIN_IO, 0, 1, 0, 0 }, - { PCMCIA_BASE_VIRT, PCMCIA_BASE_PHYS, PCMCIA_SIZE , DOMAIN_IO, 0, 1, 0, 0 }, - { IO_ADDRESS(TS7XXX_IO8_BASE), TS7XXX_IO8_BASE_PHYS, SZ_32M , DOMAIN_IO, 0, 1, 0, 0 }, - { IO_ADDRESS(TS7XXX_IO16_BASE), TS7XXX_IO16_BASE_PHYS, SZ_32M , DOMAIN_IO, 0, 1, 0, 0 }, - { IO_ADDRESS(TS7XXX_FLASH_BASE), TS7XXX_FLASH_BASE_PHYS, SZ_16M , DOMAIN_IO, 0, 1, 0, 0 }, + { IO_ADDRESS(TS7XXX_IO8_BASE), TS7XXX_IO8_BASE_PHYS, SZ_64M , DOMAIN_IO, 0, 1, 0, 0 }, + { IO_ADDRESS(TS7XXX_IO16_BASE), TS7XXX_IO16_BASE_PHYS, SZ_64M , DOMAIN_IO, 0, 1, 0, 0 }, + { IO_ADDRESS(TS7XXX_FLASH_BASE), TS7XXX_FLASH_BASE_PHYS, SZ_16M, DOMAIN_IO, 0, 1, 0, 0 }, + { IO_ADDRESS(TS7XXX_FLASH2_BASE), TS7XXX_FLASH2_BASE_PHYS, SZ_16M, DOMAIN_IO, 0, 1, 0, 0 }, + { IO_ADDRESS(TS7XXX_FLASH3_BASE), TS7XXX_FLASH3_BASE_PHYS, SZ_16M, DOMAIN_IO, 0, 1, 0, 0 }, LAST_DESC }; void __init ep93xx_map_io(void) { - unsigned int *smc; + extern int console_loglevel; + unsigned char stat; iotable_init(ep93xx_io_desc); - - smc = IO_ADDRESS(SMCBCR1); - *smc = 0x0000ffef; - smc = IO_ADDRESS(SMCBCR2); - *smc = 0x1000ffef; -// smc = IO_ADDRESS(SMCBCR6); -// *smc = 0x18002122; +// stat = inb(TS7XXX_STATUS); +// if ((stat & 0x1) != 0x1) console_loglevel = 4; + if (!inb(TS7XXX_STATUS2) & 0x4) outw(0x4, TS7XXX_ENIO); + outw(0x5, TS7XXX_WATCHDOG_FEED); + outw(0x0, TS7XXX_WATCHDOG_CTRL); + outl(0x20000000, SYSCON_PWRCNT); } Index: arch/arm/mach-integrator/cpu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mach-integrator/cpu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mach-integrator/cpu.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/arm/mach-integrator/cpu.c 4 Aug 2004 01:25:39 -0000 1.2 @@ -3,7 +3,7 @@ * * Copyright (C) 2001 Deep Blue Solutions Ltd. * - * $Id: cpu.c,v 1.1 2004/07/22 19:48:59 joff Exp $ + * $Id: cpu.c,v 1.2 2004/08/04 01:25:39 joff 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 Index: arch/arm/mach-mx1ads/cpu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mach-mx1ads/cpu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mach-mx1ads/cpu.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/arm/mach-mx1ads/cpu.c 4 Aug 2004 01:25:39 -0000 1.2 @@ -3,7 +3,7 @@ * * Copyright (C) 2001 Deep Blue Solutions Ltd. * - * $Id: cpu.c,v 1.1 2004/07/22 19:48:59 joff Exp $ + * $Id: cpu.c,v 1.2 2004/08/04 01:25:39 joff 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 Index: arch/arm/mach-sa1100/cpu-sa1110.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mach-sa1100/cpu-sa1110.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mach-sa1100/cpu-sa1110.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/arm/mach-sa1100/cpu-sa1110.c 4 Aug 2004 01:25:39 -0000 1.2 @@ -3,7 +3,7 @@ * * Copyright (C) 2001 Russell King * - * $Id: cpu-sa1110.c,v 1.1 2004/07/22 19:48:59 joff Exp $ + * $Id: cpu-sa1110.c,v 1.2 2004/08/04 01:25:39 joff 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 Index: arch/arm/mach-sa1100/leds-system3.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mach-sa1100/leds-system3.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mach-sa1100/leds-system3.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/arm/mach-sa1100/leds-system3.c 4 Aug 2004 01:25:39 -0000 1.2 @@ -5,15 +5,15 @@ * * Original (leds-footbridge.c) by Russell King * - * $Id: leds-system3.c,v 1.1 2004/07/22 19:48:59 joff Exp $ + * $Id: leds-system3.c,v 1.2 2004/08/04 01:25:39 joff 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 * published by the Free Software Foundation. * * $Log: leds-system3.c,v $ - * Revision 1.1 2004/07/22 19:48:59 joff - * Initial revision + * Revision 1.2 2004/08/04 01:25:39 joff + * merging 2.4.26-vrs1 * * Revision 1.1.6.1 2001/12/04 15:19:26 seletz * - merged from linux_2_4_13_ac5_rmk2 Index: arch/arm/mach-sa1100/pm.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mach-sa1100/pm.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mach-sa1100/pm.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/arm/mach-sa1100/pm.c 4 Aug 2004 01:25:39 -0000 1.2 @@ -21,6 +21,8 @@ * * 2002-05-27: Nicolas Pitre Killed sleep.h and the kmalloced save array. * Storage is local on the stack now. + * 2003-06-25: Jeff Corrall + * Saved the GPIO levels for resume after sleep. */ #include #include @@ -70,13 +72,20 @@ int pm_do_suspend(void) { unsigned long sleep_save[SLEEP_SAVE_SIZE]; + unsigned long sleep_save_gpsr; + unsigned long sleep_save_gpcr; + unsigned long delta; cli(); leds_event(led_stop); /* preserve current time */ - RCNR = xtime.tv_sec; + delta = xtime.tv_sec - RCNR; + + /* save the current state of the GPIO output pins */ + sleep_save_gpsr = GPDR & GPLR; + sleep_save_gpcr = GPDR & ~GPLR; /* save vital registers */ SAVE(OSCR); @@ -121,6 +130,10 @@ printk(KERN_DEBUG "*** made it back from resume\n"); #endif + /* restore GPIO output state before enabling the pins */ + GPSR = sleep_save_gpsr; + GPCR = sleep_save_gpcr; + /* restore registers */ RESTORE(GPDR); RESTORE(GRER); @@ -151,7 +164,7 @@ RESTORE(ICMR); /* restore current time */ - xtime.tv_sec = RCNR; + xtime.tv_sec = RCNR + delta; leds_event(led_start); Index: arch/arm/mach-sa1100/system3.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mach-sa1100/system3.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mach-sa1100/system3.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/arm/mach-sa1100/system3.c 4 Aug 2004 01:25:39 -0000 1.2 @@ -3,7 +3,7 @@ * * Copyright (C) 2001 Stefan Eletzhofer * - * $Id: system3.c,v 1.1 2004/07/22 19:48:59 joff Exp $ + * $Id: system3.c,v 1.2 2004/08/04 01:25:39 joff Exp $ * * This file contains all PT Sytsem 3 tweaks. Based on original work from * Nicolas Pitre's assabet fixes @@ -13,8 +13,8 @@ * published by the Free Software Foundation. * * $Log: system3.c,v $ - * Revision 1.1 2004/07/22 19:48:59 joff - * Initial revision + * Revision 1.2 2004/08/04 01:25:39 joff + * merging 2.4.26-vrs1 * * Revision 1.1.6.1 2001/12/04 17:28:06 seletz * - merged from previous branch Index: arch/arm/mm/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mm/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mm/Makefile 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/mm/Makefile 4 Aug 2004 01:25:39 -0000 1.2 @@ -39,6 +39,8 @@ p-$(CONFIG_CPU_ARM925T) += proc-arm925.o p-$(CONFIG_CPU_ARM926T) += proc-arm926.o p-$(CONFIG_CPU_ARM1020) += proc-arm1020.o +p-$(CONFIG_CPU_ARM1020E) += proc-arm1020E.o +p-$(CONFIG_CPU_ARM1022) += proc-arm1022.o p-$(CONFIG_CPU_ARM1026) += proc-arm1026.o p-$(CONFIG_CPU_SA110) += proc-sa110.o p-$(CONFIG_CPU_SA1100) += proc-sa110.o Index: arch/arm/mm/alignment.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mm/alignment.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mm/alignment.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/mm/alignment.c 4 Aug 2004 01:25:39 -0000 1.2 @@ -32,7 +32,7 @@ /* * 32-bit misaligned trap handler (c) 1998 San Mehat (CCC) -July 1998 - * /proc/sys/debug/alignment, modified and integrated into + * /proc/cpu/alignment, modified and integrated into * Linux 2.1 by Russell King * * Speed optimisations and better fault handling by Russell King. Index: arch/arm/mm/discontig.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mm/discontig.c,v retrieving revision 1.1 retrieving revision 1.5 diff -u -r1.1 -r1.5 --- arch/arm/mm/discontig.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/mm/discontig.c 27 Apr 2006 23:21:14 -0000 1.5 @@ -15,7 +15,7 @@ #include #include -#if NR_NODES > 8 +#if NR_NODES > 24 #error Fix Me Please #endif @@ -46,6 +46,54 @@ #if NR_NODES > 7 { bdata: &node_bootmem_data[7] }, #endif +#if NR_NODES > 8 + { bdata: &node_bootmem_data[8] }, +#endif +#if NR_NODES > 9 + { bdata: &node_bootmem_data[9] }, +#endif +#if NR_NODES > 10 + { bdata: &node_bootmem_data[10] }, +#endif +#if NR_NODES > 11 + { bdata: &node_bootmem_data[11] }, +#endif +#if NR_NODES > 12 + { bdata: &node_bootmem_data[12] }, +#endif +#if NR_NODES > 13 + { bdata: &node_bootmem_data[13] }, +#endif +#if NR_NODES > 14 + { bdata: &node_bootmem_data[14] }, +#endif +#if NR_NODES > 15 + { bdata: &node_bootmem_data[15] }, +#endif +#if NR_NODES > 16 + { bdata: &node_bootmem_data[16] }, +#endif +#if NR_NODES > 17 + { bdata: &node_bootmem_data[17] }, +#endif +#if NR_NODES > 18 + { bdata: &node_bootmem_data[18] }, +#endif +#if NR_NODES > 19 + { bdata: &node_bootmem_data[19] }, +#endif +#if NR_NODES > 20 + { bdata: &node_bootmem_data[20] }, +#endif +#if NR_NODES > 21 + { bdata: &node_bootmem_data[21] }, +#endif +#if NR_NODES > 22 + { bdata: &node_bootmem_data[22] }, +#endif +#if NR_NODES > 23 + { bdata: &node_bootmem_data[23] }, +#endif }; EXPORT_SYMBOL(discontig_node_data); Index: arch/arm/mm/fault-armv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mm/fault-armv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mm/fault-armv.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/mm/fault-armv.c 4 Aug 2004 01:25:39 -0000 1.2 @@ -18,6 +18,7 @@ #include #include +#include #include "fault.h" @@ -100,6 +101,8 @@ do_translation_fault(addr, 0, regs); } +static unsigned long shared_pte_mask = L_PTE_CACHEABLE; + /* * We take the easy way out of this problem - we make the * PTE uncacheable. However, we leave the write buffer on. @@ -130,9 +133,9 @@ * If this page isn't present, or is already setup to * fault (ie, is old), we can safely ignore any issues. */ - if (pte_present(entry) && pte_val(entry) & L_PTE_CACHEABLE) { + if (pte_present(entry) && pte_val(entry) & shared_pte_mask) { flush_cache_page(vma, address); - pte_val(entry) &= ~L_PTE_CACHEABLE; + pte_val(entry) &= ~shared_pte_mask; set_pte(pte, entry); flush_tlb_page(vma, address); ret = 1; @@ -157,9 +160,11 @@ { struct vm_area_struct *mpnt; struct mm_struct *mm = vma->vm_mm; - unsigned long pgoff = (addr - vma->vm_start) >> PAGE_SHIFT; + unsigned long pgoff; int aliases = 0; + pgoff = vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT); + /* * If we have any shared mappings that are in the same mm * space, then we need to handle them specially to maintain @@ -171,7 +176,7 @@ /* * If this VMA is not in our MM, we can ignore it. - * Note that we intentionally don't mask out the VMA + * Note that we intentionally mask out the VMA * that we are fixing up. */ if (mpnt->vm_mm != mm || mpnt == vma) @@ -232,3 +237,75 @@ make_coherent(vma, addr, page, dirty); } } + +/* + * Check whether the write buffer has physical address aliasing + * issues. If it has, we need to avoid them for the case where + * we have several shared mappings of the same object in user + * space. + */ +static int __init check_writebuffer(unsigned long *p1, unsigned long *p2) +{ + register unsigned long zero = 0, one = 1, val; + + mb(); + *p1 = one; + mb(); + *p2 = zero; + mb(); + val = *p1; + mb(); + return val != zero; +} + +static inline void *map_page(struct page *page) +{ + void *map; + + map = __ioremap(page_to_phys(page), PAGE_SIZE, L_PTE_BUFFERABLE); + if (map) + get_page(page); + return map; +} + +static inline void unmap_page(void *map) +{ + iounmap(map); +} + +void __init check_writebuffer_bugs(void) +{ + struct page *page; + const char *reason; + unsigned long v = 1; + + printk(KERN_INFO "CPU: Testing write buffer: "); + + page = alloc_page(GFP_KERNEL); + if (page) { + unsigned long *p1, *p2; + + p1 = map_page(page); + p2 = map_page(page); + + if (p1 && p2) { + v = check_writebuffer(p1, p2); + reason = "enabling work-around"; + } else { + reason = "unable to map memory\n"; + } + + unmap_page(p1); + unmap_page(p2); + put_page(page); + } else { + reason = "unable to grab page\n"; + } + + if (v) { + printk("FAIL - %s\n", reason); + shared_pte_mask |= L_PTE_BUFFERABLE; + } else { + printk("pass\n"); + } +} Index: arch/arm/mm/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mm/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mm/init.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/mm/init.c 10 Jan 2005 22:45:19 -0000 1.2 @@ -615,11 +615,13 @@ high_memory = (void *)__va(meminfo.end); max_mapnr = virt_to_page(high_memory) - mem_map; +#if 0 /* * We may have non-contiguous memory. */ if (meminfo.nr_banks != 1) create_memmap_holes(&meminfo); +#endif /* this will put all unused low memory onto the freelists */ for (node = 0; node < numnodes; node++) { Index: arch/arm/mm/ioremap.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mm/ioremap.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mm/ioremap.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/mm/ioremap.c 4 Aug 2004 01:25:39 -0000 1.2 @@ -144,7 +144,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.. Index: arch/arm/mm/mm-armo.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mm/mm-armo.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mm/mm-armo.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/mm/mm-armo.c 4 Aug 2004 01:25:39 -0000 1.2 @@ -104,6 +104,7 @@ no_pte: spin_unlock(&mm->page_table_lock); pmd_free(new_pmd); + check_pgt_cache(); free_pgd_slow(new_pgd); return NULL; Index: arch/arm/mm/mm-armv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mm/mm-armv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mm/mm-armv.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/mm/mm-armv.c 4 Aug 2004 01:25:39 -0000 1.2 @@ -122,6 +122,7 @@ no_pte: spin_unlock(&mm->page_table_lock); pmd_free(new_pmd); + check_pgt_cache(); free_pages((unsigned long)new_pgd, 2); return NULL; @@ -156,6 +157,7 @@ pmd_clear(pmd); pte_free(pte); pmd_free(pmd); + check_pgt_cache(); free: free_pages((unsigned long) pgd, 2); } Index: arch/arm/mm/proc-arm1020.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mm/proc-arm1020.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mm/proc-arm1020.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/mm/proc-arm1020.S 4 Aug 2004 01:25:39 -0000 1.2 @@ -743,12 +743,12 @@ .type cpu_arch_name, #object cpu_arch_name: - .asciz "armv4" + .asciz "armv5t" .size cpu_arch_name, . - cpu_arch_name .type cpu_elf_name, #object cpu_elf_name: - .asciz "v4" + .asciz "v5" .size cpu_elf_name, . - cpu_elf_name .align @@ -756,9 +756,9 @@ .type __arm1020_proc_info,#object __arm1020_proc_info: - .long 0x4100a200 - .long 0xff00fff0 - .long 0x00000c02 @ mmuflags + .long 0x4104a200 @ ARM 1020T (Architecture v5T) + .long 0xff0ffff0 + .long 0x00000c0e @ mmuflags b __arm1020_setup .long cpu_arch_name .long cpu_elf_name Index: arch/arm/mm/proc-arm1026.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mm/proc-arm1026.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mm/proc-arm1026.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/mm/proc-arm1026.S 4 Aug 2004 01:25:39 -0000 1.2 @@ -73,14 +73,17 @@ .align 5 ENTRY(cpu_arm1026_data_abort) mrc p15, 0, r1, c5, c0, 0 @ get FSR - bic r1, r1, #1 << 11 | 1 << 10 - and r2, r1, #0b1101 @ Check for translation error - teq r1, r2, #0b1101 - orrne r1, r1, #1 << 11 @ set write bit - - and r3, r3, #255 mrc p15, 0, r0, c6, c0, 0 @ get FAR - + bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR + tst r3, #PSR_J_BIT @ Java? + orrne r1, r1, #1 << 11 @ always assume write + movne pc, lr + tst r3, #PSR_T_BIT + ldrneh r3, [r2] @ read aborted thumb instruction + ldreq r3, [r2] @ read aborted ARM instruction + movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit 20 + tst r3, #1 << 20 @ check write + orreq r1, r1, #1 << 11 mov pc, lr /* @@ -256,7 +259,7 @@ */ .align 5 ENTRY(cpu_arm1026_dcache_invalidate_range) -#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH tst r0, #DCACHELINESIZE - 1 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry tst r1, #DCACHELINESIZE - 1 @@ -281,7 +284,7 @@ */ .align 5 ENTRY(cpu_arm1026_dcache_clean_range) -#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH bic r0, r0, #DCACHELINESIZE - 1 sub r3, r1, r0 cmp r3, #MAX_AREA_SIZE @@ -311,7 +314,7 @@ */ .align 5 ENTRY(cpu_arm1026_dcache_clean_page) -#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH mov r1, #PAGESIZE 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry add r0, r0, #DCACHELINESIZE @@ -332,7 +335,7 @@ */ .align 5 ENTRY(cpu_arm1026_dcache_clean_entry) -#ifndef CONFIG_CPU_ARM1026_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 @@ -475,7 +478,7 @@ biceq r1, r1, #4 @ clear bufferable bit #endif str r1, [r0] -#ifndef CONFIG_CPU_ARM1026_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 @@ -636,12 +639,12 @@ .type cpu_arch_name, #object cpu_arch_name: - .asciz "armv5EJ" + .asciz "armv5tej" .size cpu_arch_name, . - cpu_arch_name .type cpu_elf_name, #object cpu_elf_name: - .asciz "v5EJ" + .asciz "v5" .size cpu_elf_name, . - cpu_elf_name .align Index: arch/arm/mm/proc-arm720.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mm/proc-arm720.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mm/proc-arm720.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/mm/proc-arm720.S 4 Aug 2004 01:25:39 -0000 1.2 @@ -159,7 +159,7 @@ ENTRY(cpu_arm720_data_abort) tst r3, #PSR_T_BIT bne .data_thumb_abort - ldr r4, [r0] @ read instruction causing problem + ldr r4, [r2] @ read instruction causing problem and r2, r4, #15 << 24 add pc, pc, r2, lsr #22 @ Now branch to the relevent processing routine movs pc, lr @@ -270,7 +270,7 @@ b Ldata_saver7 .data_thumb_abort: - ldrh r4, [r0] @ read instruction + ldrh r4, [r2] @ read instruction tst r4, #1 << 11 orrne r4, r4, #1 << 20 and r2, r4, #15 << 12 @@ -318,8 +318,8 @@ and r0, r0, #15 @ number of regs to transfer ldr r7, [sp, #13 << 2] tst r4, #1 << 11 - addne r7, r7, r0, lsl #2 @ increment SP if PUSH - subeq r7, r7, r0, lsr #2 @ decrement SP if POP + addeq r7, r7, r0, lsl #2 @ increment SP if PUSH + subne r7, r7, r0, lsl #2 @ decrement SP if POP str r7, [sp, #13 << 2] b Ldata_simple @@ -336,7 +336,7 @@ and r0, r0, #15 @ number of regs to transfer and r5, r4, #7 << 8 ldr r7, [sp, r5, lsr #6] - sub r7, r7, r0, lsr #2 @ always decrement + sub r7, r7, r0, lsl #2 @ always decrement str r7, [sp, r5, lsr #6] b Ldata_simple Index: arch/arm/mm/proc-arm920.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mm/proc-arm920.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mm/proc-arm920.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/mm/proc-arm920.S 4 Aug 2004 01:25:39 -0000 1.2 @@ -256,14 +256,12 @@ */ .align 5 ENTRY(cpu_arm920_dcache_invalidate_range) -#ifndef CONFIG_CPU_ARM920_WRITETHROUGH +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH tst r0, #DCACHELINESIZE - 1 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry - mcrne p15, 0, r2, c7, c10, 4 @ drain WB tst r1, #DCACHELINESIZE - 1 mcrne p15, 0, r1, c7, c10, 1 @ clean D entry - mcrne p15, 0, r2, c7, c10, 4 @ drain WB -#endif +#endif @ clean D entry bic r0, r0, #DCACHELINESIZE - 1 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry add r0, r0, #DCACHELINESIZE @@ -283,18 +281,17 @@ */ .align 5 ENTRY(cpu_arm920_dcache_clean_range) - mov r2, #0 @ For SBZs & invalidate_all_r2 - @ But are SBZs mandatory? -#ifndef CONFIG_CPU_ARM920_WRITETHROUGH +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH bic r0, r0, #DCACHELINESIZE - 1 sub r1, r1, r0 cmp r1, #MAX_AREA_SIZE + mov r2, #0 bhi cpu_arm920_cache_clean_invalidate_all_r2 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry add r0, r0, #DCACHELINESIZE subs r1, r1, #DCACHELINESIZE - bpl 1b + bcs 1b #endif mcr p15, 0, r2, c7, c10, 4 @ drain WB mov pc, lr @@ -314,7 +311,7 @@ */ .align 5 ENTRY(cpu_arm920_dcache_clean_page) -#ifndef CONFIG_CPU_ARM920_WRITETHROUGH +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH mov r1, #PAGESIZE 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry add r0, r0, #DCACHELINESIZE @@ -323,7 +320,6 @@ subs r1, r1, #2 * DCACHELINESIZE bne 1b #endif - mcr p15, 0, r1, c7, c10, 4 @ drain WB mov pc, lr /* @@ -336,7 +332,7 @@ */ .align 5 ENTRY(cpu_arm920_dcache_clean_entry) -#ifndef CONFIG_CPU_ARM920_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 @@ -368,12 +364,14 @@ bic r0, r0, #ICACHELINESIZE - 1 @ Safety check sub r1, r1, r0 cmp r1, #MAX_AREA_SIZE - bhi cpu_arm920_cache_clean_invalidate_all + bhi cpu_arm920_cache_clean_invalidate_all_r2 + 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 - bpl 1b + bcs 1b + mov r0, #0 mcr p15, 0, r0, c7, c10, 4 @ drain WB mov pc, lr @@ -406,13 +404,17 @@ */ .align 5 ENTRY(cpu_arm920_tlb_invalidate_range) - bic r0, r0, #(PAGESIZE - 1) & 0x00ff - bic r0, r0, #(PAGESIZE - 1) & 0xff00 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 + + mov r3, #PAGESIZE + sub r3, r3, #1 + bic r0, r0, 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 @@ -450,7 +452,7 @@ ENTRY(cpu_arm920_set_pgd) mov ip, #0 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH - mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D cache + mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache #else @ && 'Clean & Invalidate whole DCache' @ && Re-written to use Index Ops. @@ -506,7 +508,7 @@ bic r2, r2, #3 orr r2, r2, #HPTE_TYPE_SMALL - tst r1, #LPTE_USER @ User or Exec? + tst r1, #LPTE_USER @ User? orrne r2, r2, #HPTE_AP_READ tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty? @@ -634,19 +636,13 @@ .size cpu_elf_name, . - cpu_elf_name .align -#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH -# define MMU_FLAGS 0x00000c1a -#else -# define MMU_FLAGS 0x00000c1e -#endif - .section ".proc.info", #alloc, #execinstr .type __arm920_proc_info,#object __arm920_proc_info: .long 0x41009200 .long 0xff00fff0 - .long MMU_FLAGS @ mmuflags + .long 0x00000c1e @ mmuflags b __arm920_setup .long cpu_arch_name .long cpu_elf_name Index: arch/arm/mm/proc-arm922.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mm/proc-arm922.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mm/proc-arm922.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/mm/proc-arm922.S 4 Aug 2004 01:25:39 -0000 1.2 @@ -252,7 +252,7 @@ */ .align 5 ENTRY(cpu_arm922_dcache_invalidate_range) -#ifndef CONFIG_CPU_ARM922_WRITETHROUGH +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH tst r0, #DCACHELINESIZE - 1 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry tst r1, #DCACHELINESIZE - 1 @@ -278,7 +278,7 @@ */ .align 5 ENTRY(cpu_arm922_dcache_clean_range) -#ifndef CONFIG_CPU_ARM922_WRITETHROUGH +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH bic r0, r0, #DCACHELINESIZE - 1 sub r1, r1, r0 cmp r1, #MAX_AREA_SIZE @@ -311,7 +311,7 @@ */ .align 5 ENTRY(cpu_arm922_dcache_clean_page) -#ifndef CONFIG_CPU_ARM922_WRITETHROUGH +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH mov r1, #PAGESIZE 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry add r0, r0, #DCACHELINESIZE @@ -332,7 +332,7 @@ */ .align 5 ENTRY(cpu_arm922_dcache_clean_entry) -#ifndef CONFIG_CPU_ARM922_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 Index: arch/arm/mm/proc-arm926.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mm/proc-arm926.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mm/proc-arm926.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/mm/proc-arm926.S 4 Aug 2004 01:25:39 -0000 1.2 @@ -259,7 +259,7 @@ */ .align 5 ENTRY(cpu_arm926_dcache_invalidate_range) -#ifndef CONFIG_CPU_ARM926_WRITETHROUGH +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH tst r0, #DCACHELINESIZE - 1 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry tst r1, #DCACHELINESIZE - 1 @@ -284,7 +284,7 @@ */ .align 5 ENTRY(cpu_arm926_dcache_clean_range) -#ifndef CONFIG_CPU_ARM926_WRITETHROUGH +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH bic r0, r0, #DCACHELINESIZE - 1 sub r3, r1, r0 cmp r3, #MAX_AREA_SIZE @@ -314,7 +314,7 @@ */ .align 5 ENTRY(cpu_arm926_dcache_clean_page) -#ifndef CONFIG_CPU_ARM926_WRITETHROUGH +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH mov r1, #PAGESIZE 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry add r0, r0, #DCACHELINESIZE @@ -335,7 +335,7 @@ */ .align 5 ENTRY(cpu_arm926_dcache_clean_entry) -#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 @@ -478,7 +478,7 @@ biceq r1, r1, #4 @ clear bufferable bit #endif str r1, [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 Index: arch/arm/mm/proc-sa110.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/mm/proc-sa110.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/mm/proc-sa110.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/arm/mm/proc-sa110.S 4 Aug 2004 01:25:39 -0000 1.2 @@ -86,12 +86,12 @@ .align 5 ENTRY(cpu_sa110_data_abort) ENTRY(cpu_sa1100_data_abort) - mrc p15, 0, r3, c5, c0, 0 @ get FSR + mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR - ldr r1, [r2] @ read aborted instruction - and r3, r3, #255 - tst r1, r1, lsr #21 @ C = bit 20 - sbc r1, r1, r1 @ r1 = C - 1 + ldr r3, [r2] @ read aborted instruction + bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR + tst r3, #1 << 20 @ check write + orreq r1, r1, #1 << 11 mov pc, lr /* Index: arch/arm/tools/mach-types =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/arm/tools/mach-types,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/arm/tools/mach-types 22 Jul 2004 19:48:58 -0000 1.1 +++ arch/arm/tools/mach-types 4 Aug 2004 01:25:39 -0000 1.2 @@ -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: Wed Jul 16 16:34:00 2003 +# Last update: Mon Apr 19 21:11:35 2004 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -202,7 +202,7 @@ fester SA1100_FESTER FESTER 191 gpi ARCH_GPI GPI 192 smdk2410 ARCH_SMDK2410 SMDK2410 193 -premium ARCH_PREMIUM PREMIUM 194 +i519 ARCH_I519 I519 194 nexio SA1100_NEXIO NEXIO 195 bitbox SA1100_BITBOX BITBOX 196 g200 SA1100_G200 G200 197 @@ -228,7 +228,7 @@ arnold SA1100_ARNOLD ARNOLD 217 psiboard SA1100_PSIBOARD PSIBOARD 218 jz8028 ARCH_JZ8028 JZ8028 219 -h5400 ARCH_IPAQ3 IPAQ3 220 +h5400 ARCH_H5400 H5400 220 forte SA1100_FORTE FORTE 221 acam SA1100_ACAM ACAM 222 abox SA1100_ABOX ABOX 223 @@ -259,7 +259,7 @@ stork_egg ARCH_STORK_EGG STORK_EGG 248 wismo SA1100_WISMO WISMO 249 ezlinx ARCH_EZLINX EZLINX 250 -at91rm9200 ARCH_AT91 AT91 251 +at91rm9200 ARCH_AT91RM9200 AT91RM9200 251 orion ARCH_ORION ORION 252 neptune ARCH_NEPTUNE NEPTUNE 253 hackkit SA1100_HACKKIT HACKKIT 254 @@ -295,7 +295,7 @@ adsbitsyplus SA1100_ADSBITSYPLUS ADSBITSYPLUS 284 adsagc SA1100_ADSAGC ADSAGC 285 stp7312 ARCH_STP7312 STP7312 286 -nx_phnx ARCH_PXA255 PXA255 287 +nx_phnx MACH_NX_PHNX NX_PHNX 287 wep_ep250 ARCH_WEP_EP250 WEP_EP250 288 inhandelf3 ARCH_INHANDELF3 INHANDELF3 289 adi_coyote ARCH_ADI_COYOTE ADI_COYOTE 290 @@ -363,6 +363,168 @@ ixrd425 ARCH_IXRD425 IXRD425 352 iq80315 ARCH_IQ80315 IQ80315 353 nmp7312 ARCH_NMP7312 NMP7312 354 -ep9301 ARCH_EP9301 EP9301 355 -ep9312 ARCH_EP9312 EP9312 356 -ep9315 ARCH_EP9315 EP9315 357 +cx861xx ARCH_CX861XX CX861XX 355 +enp2611 ARCH_ENP2611 ENP2611 356 +xda SA1100_XDA XDA 357 +csir_ims ARCH_CSIR_IMS CSIR_IMS 358 +ixp421_dnaeeth ARCH_IXP421_DNAEETH IXP421_DNAEETH 359 +pocketserv9200 ARCH_POCKETSERV9200 POCKETSERV9200 360 +toto ARCH_TOTO TOTO 361 +s3c2440 ARCH_S3C2440 S3C2440 362 +ks8695p ARCH_KS8695P KS8695P 363 +se4000 ARCH_SE4000 SE4000 364 +quadriceps ARCH_QUADRICEPS QUADRICEPS 365 +bronco ARCH_BRONCO BRONCO 366 +esl_wireless_tab ARCH_ESL_WIRELESS_TABLETESL_WIRELESS_TABLET 367 +esl_sofcomp ARCH_ESL_SOFCOMP ESL_SOFCOMP 368 +s5c7375 ARCH_S5C7375 S5C7375 369 +spearhead ARCH_SPEARHEAD SPEARHEAD 370 +pantera ARCH_PANTERA PANTERA 371 +prayoglite ARCH_PRAYOGLITE PRAYOGLITE 372 +gumstik ARCH_GUMSTIK GUMSTIK 373 +rcube ARCH_RCUBE RCUBE 374 +rea_olv ARCH_REA_OLV REA_OLV 375 +pxa_iphone ARCH_PXA_IPHONE PXA_IPHONE 376 +s3c3410 ARCH_S3C3410 S3C3410 377 +espd_4510b ARCH_ESPD_4510B ESPD_4510B 378 +mp1x ARCH_MP1X MP1X 379 +at91rm9200tb ARCH_AT91RM9200TB AT91RM9200TB 380 +adsvgx ARCH_ADSVGX ADSVGX 381 +omap_h2 ARCH_OMAP_H2 OMAP_H2 382 +pelee ARCH_PELEE PELEE 383 +e740 MACH_E740 E740 384 +iq80331 ARCH_IQ80331 IQ80331 385 +versatile_pb ARCH_VERSATILE_PB VERSATILE_PB 387 +kev7a400 MACH_KEV7A400 KEV7A400 388 +lpd7a400 MACH_LPD7A400 LPD7A400 389 +lpd7a404 MACH_LPD7A404 LPD7A404 390 +fujitsu_camelot ARCH_FUJITSU_CAMELOT FUJITSU_CAMELOT 391 +janus2m ARCH_JANUS2M JANUS2M 392 +embtf MACH_EMBTF EMBTF 393 +hpm MACH_HPM HPM 394 +smdk2410tk MACH_SMDK2410TK SMDK2410TK 395 +smdk2410aj MACH_SMDK2410AJ SMDK2410AJ 396 +streetracer MACH_STREETRACER STREETRACER 397 +eframe MACH_EFRAME EFRAME 398 +csb337 MACH_CSB337 CSB337 399 +pxa_lark MACH_PXA_LARK PXA_LARK 400 +pxa_pnp2110 MACH_PNP2110 PNP2110 401 +tcc72x MACH_TCC72X TCC72X 402 +altair MACH_ALTAIR ALTAIR 403 +kc3 MACH_KC3 KC3 404 +sinteftd MACH_SINTEFTD SINTEFTD 405 +mainstone MACH_MAINSTONE MAINSTONE 406 +aday4x MACH_ADAY4X ADAY4X 407 +lite300 MACH_LITE300 LITE300 408 +s5c7376 MACH_S5C7376 S5C7376 409 +mt02 MACH_MT02 MT02 410 +mport3s MACH_MPORT3S MPORT3S 411 +ra_alpha MACH_RA_ALPHA RA_ALPHA 412 +xcep MACH_XCEP XCEP 413 +arcom_mercury MACH_ARCOM_MERCURY ARCOM_MERCURY 414 +stargate MACH_STARGATE STARGATE 415 +armadilloj MACH_ARMADILLOJ ARMADILLOJ 416 +elroy_jack MACH_ELROY_JACK ELROY_JACK 417 +backend MACH_BACKEND BACKEND 418 +s5linbox MACH_S5LINBOX S5LINBOX 419 +nomadik MACH_NOMADIK NOMADIK 420 +ia_cpu_9200 MACH_IA_CPU_9200 IA_CPU_9200 421 +at91_bja1 MACH_AT91_BJA1 AT91_BJA1 422 +corgi MACH_CORGI CORGI 423 +poodle MACH_POODLE POODLE 424 +ten MACH_TEN TEN 425 +roverp5p MACH_ROVERP5P ROVERP5P 426 +sc2700 MACH_SC2700 SC2700 427 +ex_eagle MACH_EX_EAGLE EX_EAGLE 428 +nx_pxa12 MACH_NX_PXA12 NX_PXA12 429 +nx_pxa5 MACH_NX_PXA5 NX_PXA5 430 +blackboard2 MACH_BLACKBOARD2 BLACKBOARD2 431 +i819 MACH_I819 I819 432 +ixmb995e MACH_IXMB995E IXMB995E 433 +skyrider MACH_SKYRIDER SKYRIDER 434 +skyhawk MACH_SKYHAWK SKYHAWK 435 +enterprise MACH_ENTERPRISE ENTERPRISE 436 +dep2410 MACH_DEP2410 DEP2410 437 +armcore MACH_ARMCORE ARMCORE 438 +hobbit MACH_HOBBIT HOBBIT 439 +h7210 MACH_H7210 H7210 440 +pxa_netdcu5 MACH_PXA_NETDCU5 PXA_NETDCU5 441 +acc MACH_ACC ACC 442 +esl_sarva MACH_ESL_SARVA ESL_SARVA 443 +xm250 MACH_XM250 XM250 444 +t6tc1xb MACH_T6TC1XB T6TC1XB 445 +ess710 MACH_ESS710 ESS710 446 +mx3ads MACH_MX3ADS MX3ADS 447 +himalaya MACH_HIMALAYA HIMALAYA 448 +bolfenk MACH_BOLFENK BOLFENK 449 +at91rm9200kr MACH_AT91RM9200KR AT91RM9200KR 450 +edb9312 MACH_EDB9312 EDB9312 451 +omap_generic MACH_OMAP_GENERIC OMAP_GENERIC 452 +aximx3 MACH_AXIMX3 AXIMX3 453 +eb67xdip MACH_EB67XDIP EB67XDIP 454 +webtxs MACH_WEBTXS WEBTXS 455 +hawk MACH_HAWK HAWK 456 +ccat91sbc001 MACH_CCAT91SBC001 CCAT91SBC001 457 +expresso MACH_EXPRESSO EXPRESSO 458 +h4000 MACH_H4000 H4000 459 +dino MACH_DINO DINO 460 +ml675k MACH_ML675K ML675K 461 +edb9301 MACH_EDB9301 EDB9301 462 +edb9315 MACH_EDB9315 EDB9315 463 +reciva_tt MACH_RECIVA_TT RECIVA_TT 464 +cstcb01 MACH_CSTCB01 CSTCB01 465 +cstcb1 MACH_CSTCB1 CSTCB1 466 +shadwell MACH_SHADWELL SHADWELL 467 +goepel263 MACH_GOEPEL263 GOEPEL263 468 +acq100 MACH_ACQ100 ACQ100 469 +mx1fs2 MACH_MX1FS2 MX1FS2 470 +hiptop_g1 MACH_HIPTOP_G1 HIPTOP_G1 471 +sparky MACH_SPARKY SPARKY 472 +ns9750 MACH_NS9750 NS9750 473 +phoenix MACH_PHOENIX PHOENIX 474 +vr1000 MACH_VR1000 VR1000 475 +deisterpxa MACH_DEISTERPXA DEISTERPXA 476 +bcm1160 MACH_BCM1160 BCM1160 477 +pcm022 MACH_PCM022 PCM022 478 +adsgcx MACH_ADSGCX ADSGCX 479 +dreadnaught MACH_DREADNAUGHT DREADNAUGHT 480 +dm320 MACH_DM320 DM320 481 +markov MACH_MARKOV MARKOV 482 +cos7a400 MACH_COS7A400 COS7A400 483 +milano MACH_MILANO MILANO 484 +ue9328 MACH_UE9328 UE9328 485 +uex255 MACH_UEX255 UEX255 486 +ue2410 MACH_UE2410 UE2410 487 +a620 MACH_A620 A620 488 +ocelot MACH_OCELOT OCELOT 489 +cheetah MACH_CHEETAH CHEETAH 490 +omap_perseus2 MACH_OMAP_PERSEUS2 OMAP_PERSEUS2 491 +zvue MACH_ZVUE ZVUE 492 +roverp1 MACH_ROVERP1 ROVERP1 493 +asidial2 MACH_ASIDIAL2 ASIDIAL2 494 +s3c24a0 MACH_S3C24A0 S3C24A0 495 +e800 MACH_E800 E800 496 +e750 MACH_E750 E750 497 +s3c5500 MACH_S3C5500 S3C5500 498 +smdk5500 MACH_SMDK5500 SMDK5500 499 +signalsync MACH_SIGNALSYNC SIGNALSYNC 500 +nbc MACH_NBC NBC 501 +er4525 MACH_ER4525 ER4525 502 +netbookpro MACH_NETBOOKPRO NETBOOKPRO 503 +hw90200 MACH_HW90200 HW90200 504 +condor MACH_CONDOR CONDOR 505 +cup MACH_CUP CUP 506 +kite MACH_KITE KITE 507 +scb9328 MACH_SCB9328 SCB9328 508 +omap_h3 MACH_OMAP_H3 OMAP_H3 509 +omap_h4 MACH_OMAP_H4 OMAP_H4 510 +n10 MACH_N10 N10 511 +montajade MACH_MONTAJADE MONTAJADE 512 +sg560 MACH_SG560 SG560 513 +dp1000 MACH_DP1000 DP1000 514 +omap_osk MACH_OMAP_OSK OMAP_OSK 515 +rg100v3 MACH_RG100V3 RG100V3 516 +mx2ads MACH_MX2ADS MX2ADS 517 +ep9301 ARCH_EP9301 EP9301 518 +ep9312 ARCH_EP9312 EP9312 519 +ep9315 ARCH_EP9315 EP9315 520 Index: arch/cris/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/Makefile 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/cris/Makefile 4 Aug 2004 01:25:39 -0000 1.2 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.1 2004/07/22 19:49:08 joff 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) Index: arch/cris/README.mm =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/README.mm,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/README.mm 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/cris/README.mm 4 Aug 2004 01:25:39 -0000 1.2 @@ -3,8 +3,8 @@ HISTORY: $Log: README.mm,v $ -Revision 1.1 2004/07/22 19:49:08 joff -Initial revision +Revision 1.2 2004/08/04 01:25:39 joff +merging 2.4.26-vrs1 Revision 1.1 2000/07/10 16:25:21 bjornw Initial revision Index: arch/cris/config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/config.in 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/cris/config.in 4 Aug 2004 01:25:39 -0000 1.2 @@ -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 @@ -173,7 +184,6 @@ 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 @@ -199,7 +209,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 +268,11 @@ #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 +int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 + +source crypto/Config.in source lib/Config.in endmenu Index: arch/cris/defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/defconfig 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/cris/defconfig 4 Aug 2004 01:25:39 -0000 1.2 @@ -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 @@ -278,7 +282,6 @@ # 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 # # SCSI support Index: arch/cris/boot/compressed/README =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/boot/compressed/README,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/boot/compressed/README 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/boot/compressed/README 4 Aug 2004 01:25:39 -0000 1.2 @@ -1,6 +1,5 @@ Creation of the self-extracting compressed kernel image (vmlinuz) ----------------------------------------------------------------- -$Id: README,v 1.1 2004/07/22 19:49:09 joff Exp $ This can be slightly confusing because it's a process with many steps. Index: arch/cris/boot/compressed/misc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/boot/compressed/misc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/boot/compressed/misc.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/boot/compressed/misc.c 4 Aug 2004 01:25:39 -0000 1.2 @@ -1,19 +1,17 @@ /* * misc.c * - * $Id: misc.c,v 1.1 2004/07/22 19:49:09 joff 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; Index: arch/cris/boot/rescue/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/boot/rescue/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/boot/rescue/head.S 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/boot/rescue/head.S 4 Aug 2004 01:25:39 -0000 1.2 @@ -1,5 +1,4 @@ -/* $Id: head.S,v 1.1 2004/07/22 19:49:09 joff 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 Index: arch/cris/boot/rescue/kimagerescue.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/boot/rescue/kimagerescue.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/boot/rescue/kimagerescue.S 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/boot/rescue/kimagerescue.S 4 Aug 2004 01:25:39 -0000 1.2 @@ -1,5 +1,4 @@ -/* $Id: kimagerescue.S,v 1.1 2004/07/22 19:49:09 joff 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 Index: arch/cris/boot/rescue/testrescue.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/boot/rescue/testrescue.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/boot/rescue/testrescue.S 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/boot/rescue/testrescue.S 4 Aug 2004 01:25:39 -0000 1.2 @@ -1,9 +1,8 @@ -/* $Id: testrescue.S,v 1.1 2004/07/22 19:49:09 joff 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 - - Index: arch/cris/drivers/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/Config.in 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/Config.in 4 Aug 2004 01:25:39 -0000 1.2 @@ -11,7 +11,10 @@ "LED_on_when_link CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK \ LED_on_when_activity CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY" \ LED_on_when_activity - + choice 'Network LED behavior on no connection' \ + "RED_LED_on_no_connection CONFIG_ETRAX_NETWORK_RED_ON_NO_CONNECTION \ + LED_OFF_on_no_connection CONFIG_ETRAX_NETWORK_OFF_ON_NO_CONNECTION" \ + LED_OFF_on_no_connection else define_bool CONFIG_NET_ETHERNET n fi @@ -23,15 +26,27 @@ 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 0 + fi bool ' Serial port 0 enabled' CONFIG_ETRAX_SERIAL_PORT0 if [ "$CONFIG_ETRAX_SERIAL_PORT0" = "y" ]; then + choice 'Ser0 DMA out assignment' \ + "NO_DMA_OUT CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_OUT \ + DMA6_OUT CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT" \ + DMA6_OUT + choice 'Ser0 DMA in assignment' \ + "NO_DMA_IN CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_IN \ + DMA7_IN CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN" \ + 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 +82,14 @@ bool ' Serial port 1 enabled' CONFIG_ETRAX_SERIAL_PORT1 if [ "$CONFIG_ETRAX_SERIAL_PORT1" = "y" ]; then + choice 'Ser1 DMA out assignment' \ + "NO_DMA_OUT CONFIG_ETRAX_SERIAL_PORT1_NO_DMA_OUT \ + DMA8_OUT CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT" \ + DMA8_OUT + choice 'Ser1 DMA in assignment' \ + "NO_DMA_IN CONFIG_ETRAX_SERIAL_PORT1_NO_DMA_IN \ + DMA9_IN CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN" \ + 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 +129,14 @@ fi bool ' Serial port 2 enabled' CONFIG_ETRAX_SERIAL_PORT2 if [ "$CONFIG_ETRAX_SERIAL_PORT2" = "y" ]; then + choice 'Ser2 DMA out assignment' \ + "NO_DMA_OUT CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_OUT \ + DMA2_OUT CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT" \ + DMA2_OUT + choice 'Ser2 DMA in assignment' \ + "NO_DMA_IN CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_IN \ + DMA3_IN CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN" \ + 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 +170,14 @@ fi bool ' Serial port 3 enabled' CONFIG_ETRAX_SERIAL_PORT3 if [ "$CONFIG_ETRAX_SERIAL_PORT3" = "y" ]; then + choice 'Ser3 DMA out assignment' \ + "NO_DMA_OUT CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_OUT \ + DMA4_OUT CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT" \ + DMA4_OUT + choice 'Ser3 DMA in assignment' \ + "NO_DMA_IN CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_IN \ + DMA5_IN CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN" \ + 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 \ @@ -182,13 +221,13 @@ bool 'Synchronous serial port support' CONFIG_ETRAX_SYNCHRONOUS_SERIAL if [ "$CONFIG_ETRAX_SYNCHRONOUS_SERIAL" = "y" ]; then - bool ' Synchronous serial port 0 enabled' CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0 + bool ' Synchronous serial port 0 enabled (sser1)' CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0 if [ "$CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0" = "y" ]; then - bool ' Synchronous serial port 0 uses DMA' CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA + bool ' Synchronous serial port 0 uses DMA 8,9' CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA fi - bool ' Synchronous serial port 1 enabled' CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1 + bool ' Synchronous serial port 1 enabled (sser3)' CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1 if [ "$CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1" = "y" ]; then - bool ' Synchronous serial port 1 uses DMA' CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA + bool ' Synchronous serial port 1 uses DMA 4,5' CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA fi fi @@ -241,17 +280,28 @@ # here we define the CONFIG_'s necessary to enable MTD support # for the flash define_bool CONFIG_MTD y - - define_bool CONFIG_MTD_CFI y - define_bool CONFIG_MTD_CFI_AMDSTD y - - define_bool CONFIG_MTD_OBSOLETE_CHIPS y - define_bool CONFIG_MTD_AMDSTD y - + define_bool CONFIG_MTD_PARTITIONS y define_bool CONFIG_MTD_CHAR y define_bool CONFIG_MTD_BLOCK y - define_bool CONFIG_MTD_PARTITIONS y - define_bool CONFIG_MTD_CONCAT y + + if [ "$CONFIG_MTD_CFI" = "n" ] && [ "$CONFIG_MTD_AMDSTD" = "n" ] && \ + [ "$CONFIG_MTD_MTDRAM" = "n" ]; then + # Bad initial configuration, make axisflashmap work by enabling + # all drivers it may need. + + define_bool CONFIG_MTD_CFI y + define_bool CONFIG_MTD_CFI_AMDSTD y + + define_bool CONFIG_MTD_OBSOLETE_CHIPS y + define_bool CONFIG_MTD_AMDSTD y + + define_bool CONFIG_MTD_CONCAT y + + define_bool CONFIG_MTD_MTDRAM y + define_int CONFIG_MTDRAM_TOTAL_SIZE 0 + define_int CONFIG_MTDRAM_ERASE_SIZE 64 + define_int CONFIG_MTDRAM_ABS_POS 0 + fi fi bool 'I2C support' CONFIG_ETRAX_I2C @@ -303,6 +353,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 Index: arch/cris/drivers/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/Makefile 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/Makefile 4 Aug 2004 01:25:39 -0000 1.2 @@ -4,6 +4,8 @@ O_TARGET := drivers.o +export-objs := axisflashmap.o + obj-y := obj-$(CONFIG_ETRAX_VIRTEX_FPGA) += virtex.o Index: arch/cris/drivers/axisflashmap.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/axisflashmap.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/axisflashmap.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/axisflashmap.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -11,8 +11,17 @@ * partition split defined below. * * $Log: axisflashmap.c,v $ - * Revision 1.1 2004/07/22 19:49:09 joff - * Initial revision + * Revision 1.2 2004/08/04 01:25:40 joff + * merging 2.4.26-vrs1 + * + * Revision 1.31 2003/11/14 16:55:27 jonashg + * Made it possible to RAM boot without any flash drivers present. + * + * Revision 1.30 2003/09/29 06:37:18 mikaelp + * Exported master mtd device as axisflash_mtd. + * + * 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. @@ -142,6 +151,9 @@ /* From head.S */ extern unsigned long romfs_start, romfs_length, romfs_in_flash; +/* The master mtd for the entire flash. */ +struct mtd_info* axisflash_mtd = NULL; + /* Map driver functions. */ static __u8 flash_read8(struct map_info *map, unsigned long ofs) @@ -303,7 +315,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,28 +400,31 @@ struct mtd_info *mymtd; int err = 0; int pidx = 0; - struct partitiontable_head *ptable_head; + struct partitiontable_head *ptable_head = NULL; 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 * be identified. Make sure that's understood. */ - panic("axisflashmap found no flash chip!\n"); + printk(KERN_INFO "axisflashmap: Found no flash chip.\n"); + } else { + printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n", + mymtd->name, mymtd->size); + axisflash_mtd = mymtd; } - printk("%s: 0x%08x bytes of flash memory.\n", - mymtd->name, mymtd->size); - - mymtd->module = THIS_MODULE; - - ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR + - CONFIG_ETRAX_PTABLE_SECTOR + PARTITION_TABLE_OFFSET); + if (mymtd) { + mymtd->module = THIS_MODULE; + ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR + + CONFIG_ETRAX_PTABLE_SECTOR + + PARTITION_TABLE_OFFSET); + } pidx++; /* First partition is always set to the default. */ - if ((ptable_head->magic == PARTITION_TABLE_MAGIC) + if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC) && (ptable_head->size < (MAX_PARTITIONS * sizeof(struct partitiontable_entry) + PARTITIONTABLE_END_MARKER_SIZE)) @@ -443,7 +459,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); @@ -475,22 +491,25 @@ 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"); - err = add_mtd_partitions(mymtd, axis_default_partitions, - NUM_DEFAULT_PARTITIONS); - } else { - err = add_mtd_partitions(mymtd, axis_partitions, pidx); - } + if (mymtd) { + if (use_default_ptable) { + printk(KERN_INFO " Using default partition table.\n"); + err = add_mtd_partitions(mymtd, axis_default_partitions, + NUM_DEFAULT_PARTITIONS); + } else { + err = add_mtd_partitions(mymtd, axis_partitions, pidx); + } - if (err) { - panic("axisflashmap could not add MTD partitions!\n"); + if (err) { + panic("axisflashmap could not add MTD partitions!\n"); + } } if (!romfs_in_flash) { @@ -511,7 +530,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, @@ -528,3 +547,5 @@ /* This adds the above to the kernels init-call chain. */ module_init(init_axis_flash); + +EXPORT_SYMBOL(axisflash_mtd); Index: arch/cris/drivers/ds1302.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/ds1302.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/ds1302.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/ds1302.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -4,11 +4,24 @@ *! *! 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.1 2004/07/22 19:49:09 joff -*! Initial revision +*! Revision 1.2 2004/08/04 01:25:40 joff +*! merging 2.4.26-vrs1 +*! +*! 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 @@ -98,7 +111,7 @@ *! *! (C) Copyright 1999, 2000, 2001 Axis Communications AB, LUND, SWEDEN *! -*! $Id: ds1302.c,v 1.1 2004/07/22 19:49:09 joff Exp $ +*! $Id: ds1302.c,v 1.2 2004/08/04 01:25:40 joff Exp $ *! *!***************************************************************************/ @@ -266,12 +279,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 @@ -325,6 +349,7 @@ { struct rtc_time rtc_tm; + memset(&rtc_tm, 0, sizeof (struct rtc_time)); get_rtc_time(&rtc_tm); if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time))) return -EFAULT; @@ -408,20 +433,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); /* @@ -429,13 +467,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); } @@ -469,11 +504,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, @@ -483,12 +517,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; } @@ -521,9 +553,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 } @@ -536,5 +571,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; } Index: arch/cris/drivers/eeprom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/eeprom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/eeprom.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/eeprom.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -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,8 +20,20 @@ *! in the spin-lock. *! *! $Log: eeprom.c,v $ -*! Revision 1.1 2004/07/22 19:49:09 joff -*! Initial revision +*! Revision 1.2 2004/08/04 01:25:40 joff +*! merging 2.4.26-vrs1 +*! +*! 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. @@ -206,7 +218,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. */ @@ -496,7 +508,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; @@ -522,7 +534,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 */ @@ -605,7 +617,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 */ @@ -743,7 +755,7 @@ static int eeprom_address(unsigned long addr) { - int i, j; + int i; unsigned char page, offset; page = (unsigned char) (addr >> 8); @@ -798,7 +810,7 @@ return 1; } -/* Reads from current adress. */ +/* Reads from current address. */ static int read_from_eeprom(char * buf, int count) { Index: arch/cris/drivers/ethernet.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/ethernet.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/ethernet.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/ethernet.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ethernet.c,v 1.1 2004/07/22 19:49:09 joff Exp $ +/* $Id: ethernet.c,v 1.2 2004/08/04 01:25:40 joff Exp $ * * e100net.c: A network driver for the ETRAX 100LX network controller. * @@ -7,12 +7,68 @@ * The outline of this driver comes from skeleton.c. * * $Log: ethernet.c,v $ - * Revision 1.1 2004/07/22 19:49:09 joff - * Initial revision + * Revision 1.2 2004/08/04 01:25:40 joff + * merging 2.4.26-vrs1 * - * 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.48 2003/12/03 13:44:39 starvik + * Use hardware pad for short packets. This prevents information leakage + * reported by Nessus. + * + * Revision 1.47 2003/11/25 15:12:38 anderstj + * Make sure the LED always is inititated. + * + * Revision 1.46 2003/08/28 14:35:29 jonasw + * Added support for TDK 2120C and fixed led when not connected + * + * Revision 1.45 2003/08/21 07:22:25 matsfg + * Optional behaviour on networkled when no connection. + * + * 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 @@ -223,6 +279,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 { @@ -243,10 +309,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 @@ -260,9 +333,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 */ @@ -306,11 +383,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; @@ -340,6 +418,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); @@ -352,11 +431,26 @@ 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 2120 */ + {0x039C, tdk_check_speed, tdk_check_duplex}, /* TDK 2120C */ + {0x0000, generic_check_speed, generic_check_duplex} /* Generic, must be last */ +}; + #define tx_done(dev) (*R_DMA_CH0_CMD == 0) /* @@ -372,11 +466,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 */ @@ -471,7 +566,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; @@ -479,8 +573,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; } @@ -511,8 +608,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]); @@ -535,12 +631,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); @@ -639,7 +729,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) | @@ -668,6 +759,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. */ @@ -687,10 +786,38 @@ 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) { + static int led_initiated = 0; unsigned long data; int old_speed = current_speed; @@ -698,12 +825,13 @@ 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) + if ((old_speed != current_speed) || !led_initiated) { + led_initiated = 1; e100_set_network_leds(NO_NETWORK_ACTIVITY); + } /* Reinitialize the timer. */ speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL; @@ -764,29 +892,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. */ @@ -794,13 +914,72 @@ 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) @@ -810,7 +989,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); @@ -831,7 +1010,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); @@ -891,7 +1070,7 @@ } static void -e100_reset_tranceiver(void) +e100_reset_transceiver(void) { unsigned short cmd; unsigned short data; @@ -899,7 +1078,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); @@ -931,9 +1110,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) @@ -963,7 +1142,6 @@ e100_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *np = (struct net_local *)dev->priv; - int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned char *buf = skb->data; #ifdef ETHDEBUG @@ -975,15 +1153,12 @@ dev->trans_start = jiffies; - e100_hardware_send_packet(buf, length); + e100_hardware_send_packet(buf, skb->len); myNextTxDesc = phys_to_virt(myNextTxDesc->descr.next); /* 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); } @@ -1004,6 +1179,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 */ @@ -1047,9 +1227,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 @@ -1186,14 +1370,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) | @@ -1224,6 +1404,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; } @@ -1236,7 +1419,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); @@ -1255,7 +1438,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. */ @@ -1288,7 +1471,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; @@ -1331,7 +1514,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.2 $", 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; @@ -1460,7 +1643,7 @@ hash_ix &= 0x3f; - if (hash_ix > 32) { + if (hash_ix >= 32) { hi_bits |= (1 << (hash_ix-32)); } else { @@ -1529,7 +1712,11 @@ if (!current_speed) { /* Make LED red, link is down */ +#if defined(CONFIG_ETRAX_NETWORK_RED_ON_NO_CONNECTION) LED_NETWORK_SET(LED_RED); +#else + LED_NETWORK_SET(LED_OFF); +#endif } else if (light_leds) { if (current_speed == 10) { @@ -1558,4 +1745,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); Index: arch/cris/drivers/gpio.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/gpio.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/gpio.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/gpio.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: gpio.c,v 1.1 2004/07/22 19:49:09 joff Exp $ +/* $Id: gpio.c,v 1.2 2004/08/04 01:25:40 joff Exp $ * * Etrax general port I/O device * @@ -9,8 +9,24 @@ * Johan Adolfsson (read/set directions, write, port G) * * $Log: gpio.c,v $ - * Revision 1.1 2004/07/22 19:49:09 joff - * Initial revision + * Revision 1.2 2004/08/04 01:25:40 joff + * merging 2.4.26-vrs1 + * + * 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 @@ -172,6 +188,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) @@ -241,13 +258,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) @@ -296,12 +319,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(); } @@ -440,7 +466,7 @@ p = p->next; } gpio_some_alarms = 0; - + return 0; } @@ -462,6 +488,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; @@ -486,16 +513,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; @@ -511,7 +539,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 */ @@ -535,15 +564,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; @@ -608,6 +638,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 */ @@ -827,9 +871,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); } @@ -838,7 +884,6 @@ static __init int gpio_init(void) { - extern void init_ioremap(void); int res; #if defined (CONFIG_ETRAX_CSP0_LEDS) int i; @@ -853,8 +898,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); @@ -868,7 +912,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 @@ -876,11 +921,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; Index: arch/cris/drivers/i2c.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/i2c.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/i2c.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/i2c.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -11,9 +11,28 @@ *! 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.1 2004/07/22 19:49:09 joff -*! Initial revision +*! Revision 1.2 2004/08/04 01:25:40 joff +*! merging 2.4.26-vrs1 +*! +*! 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 @@ -56,7 +75,7 @@ *! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN *! *!***************************************************************************/ -/* $Id: i2c.c,v 1.1 2004/07/22 19:49:09 joff Exp $ */ +/* $Id: i2c.c,v 1.2 2004/08/04 01:25:40 joff Exp $ */ /****************** INCLUDE FILES SECTION ***********************************/ #include @@ -136,7 +155,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)) @@ -166,7 +185,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 */ @@ -302,6 +322,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; } @@ -363,6 +389,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 */ @@ -420,6 +453,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 @@ -549,9 +613,10 @@ */ b = i2c_inbyte(); /* - * send Ack + * last received byte needs to be nacked + * instead of acked */ - i2c_sendack(); + i2c_sendnack(); /* * end sequence */ @@ -626,7 +691,7 @@ release: i2c_release, }; -static int __init +int __init i2c_init(void) { int res; @@ -656,7 +721,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; } Index: arch/cris/drivers/i2c.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/i2c.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/i2c.h 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/i2c.h 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,6 +1,8 @@ -/* $Id: i2c.h,v 1.1 2004/07/22 19:49:09 joff 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); - - - Index: arch/cris/drivers/ide.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/ide.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/ide.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/ide.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ide.c,v 1.1 2004/07/22 19:49:09 joff Exp $ +/* $Id: ide.c,v 1.2 2004/08/04 01:25:40 joff 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,8 +8,21 @@ * Mikael Starvik (pio setup stuff) * * $Log: ide.c,v $ - * Revision 1.1 2004/07/22 19:49:09 joff - * Initial revision + * Revision 1.2 2004/08/04 01:25:40 joff + * merging 2.4.26-vrs1 + * + * 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 @@ -154,6 +167,8 @@ static volatile unsigned long *reset_addr; #endif +static int e100_read_command = 0; + #define LOWDB(x) #define D(x) @@ -189,14 +204,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; @@ -240,7 +250,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) @@ -295,9 +305,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") @@ -312,8 +328,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); */ @@ -377,8 +391,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 */ @@ -403,11 +424,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 @@ -621,7 +640,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 @@ -658,32 +677,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; @@ -818,8 +811,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; @@ -836,7 +829,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 @@ -851,59 +844,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 */ @@ -920,8 +873,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 */ @@ -971,8 +931,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 */ @@ -997,14 +964,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); } Index: arch/cris/drivers/parport.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/parport.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/parport.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/parport.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,13 +1,13 @@ -/* $Id: parport.c,v 1.1 2004/07/22 19:49:09 joff 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 Index: arch/cris/drivers/pcf8563.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/pcf8563.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/pcf8563.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/pcf8563.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -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.1 2004/07/22 19:49:09 joff 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.1 $" - -/* 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.2 $" /* 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,114 @@ switch (cmd) { case RTC_RD_TIME: - { - struct rtc_time tm; + { + struct rtc_time tm; - get_rtc_time(&tm); + memset(&tm, 0, sizeof (struct rtc_time)); + 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; Index: arch/cris/drivers/serial.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/serial.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/serial.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/serial.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,14 +1,112 @@ -/* $Id: serial.c,v 1.1 2004/07/22 19:49:09 joff Exp $ +/* $Id: serial.c,v 1.2 2004/08/04 01:25:40 joff 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.1 2004/07/22 19:49:09 joff - * Initial revision + * Revision 1.2 2004/08/04 01:25:40 joff + * merging 2.4.26-vrs1 + * + * Revision 1.58 2003/08/29 17:32:50 johana + * Fixed CMSPAR (Mark/Space) support. CMSPAR|PARODD = Mark(1) parity. + * + * Revision 1.57 2003/08/26 16:53:06 johana + * Merged in change_branch--johana to get non DMA support etc. + * + * Revision 1.56 2003/07/10 13:18:03 pkj + * Corrected a copy-paste error. + * + * Revision 1.55 2003/07/10 11:00:46 starvik + * Moved all the latest stuff to a branch until it is stable + * + * Revision 1.50.2.2 2003/07/28 09:59:39 johana + * Clear tr_running so next write really starts transmission. + * + * Revision 1.50.2.1 2003/07/10 10:59:54 starvik + * Moved all the latest stuff to a branch until it is stable + * + * 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 @@ -209,7 +307,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 @@ -360,7 +458,7 @@ * */ -static char *serial_version = "$Revision: 1.1 $"; +static char *serial_version = "$Revision: 1.2 $"; #include #include @@ -395,7 +493,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" @@ -409,6 +507,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 @@ -417,8 +520,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; @@ -439,7 +545,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 @@ -447,14 +553,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 @@ -464,21 +634,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 */ @@ -487,6 +659,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 @@ -522,60 +695,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 - 0 + .dma_in_enabled = 0 #endif +#else + .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 + .dma_in_enabled = 0 +#endif #else - 0 + .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 - 0 + .dma_out_enabled = 0, +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN + .dma_in_enabled = 1, +#else + .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 + .dma_in_enabled = 0 +#endif #else - 0 + .enabled = 0, + .dma_out_enabled = 0, + .dma_in_enabled = 0 #endif } /* ttyS3 */ #endif @@ -630,7 +905,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)? \ @@ -649,6 +924,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) || \ @@ -656,6 +1150,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) \ @@ -841,7 +1336,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 @@ -940,6 +1434,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; } /* @@ -983,7 +1480,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 */ } @@ -1039,9 +1536,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 @@ -1115,6 +1616,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); } @@ -1124,6 +1626,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); } @@ -1135,6 +1638,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; } @@ -1144,9 +1648,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. */ @@ -1157,6 +1795,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)); } @@ -1169,10 +1808,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 @@ -1186,7 +1865,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, @@ -1226,7 +1908,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 @@ -1248,8 +1930,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 ) { @@ -1270,6 +1956,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 ) { @@ -1277,6 +1966,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); } @@ -1311,6 +2003,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); @@ -1328,7 +2022,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; @@ -1336,11 +2030,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, @@ -1362,7 +2056,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; } @@ -1378,6 +2072,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; @@ -1395,6 +2091,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; @@ -1414,17 +2117,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) @@ -1438,15 +2141,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(); \ @@ -1457,7 +2162,7 @@ start_one_shot_timer(&fast_timers[info->line], \ flush_timeout_function, \ (unsigned long)info, \ - info->char_time_usec*4, \ + (usec), \ string); \ } \ else { \ @@ -1465,8 +2170,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 @@ -1511,18 +2218,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; } @@ -1532,7 +2248,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; } @@ -1545,7 +2262,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); @@ -1582,8 +2299,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; @@ -1594,7 +2319,7 @@ } static _INLINE_ void -receive_chars(struct e100_serial *info) +receive_chars_dma(struct e100_serial *info) { struct tty_struct *tty; unsigned char rstat; @@ -1626,7 +2351,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 @@ -1661,7 +2389,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); @@ -1694,20 +2422,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 + } } @@ -1752,25 +2480,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 */ @@ -1798,18 +2526,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) @@ -1849,7 +2577,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); } @@ -1863,7 +2591,8 @@ struct etrax_recv_buffer *buffer; unsigned int length; unsigned long flags; - + int max_flip_size; + if (!info->first_recv_buffer) return; @@ -1876,12 +2605,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 + } + + if (max_flip_size > TTY_FLIPBUF_SIZE) + max_flip_size = TTY_FLIPBUF_SIZE; - while ((buffer = info->first_recv_buffer) && length < 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); @@ -1889,7 +2652,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); @@ -1904,10 +2668,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 @@ -1918,12 +2703,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 @@ -1963,7 +2755,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 */ @@ -1991,7 +2783,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); } @@ -2020,7 +2812,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. @@ -2057,7 +2849,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. @@ -2069,15 +2861,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. + */ + + 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 void _INLINE_ handle_ser_interrupt(struct e100_serial *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; @@ -2087,7 +3023,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. @@ -2116,15 +3053,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; @@ -2148,7 +3092,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 { @@ -2158,38 +3102,196 @@ } #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); + info->tr_running = 0; + 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 @@ -2291,25 +3393,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); @@ -2324,8 +3441,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); @@ -2334,9 +3453,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 */ @@ -2345,10 +3465,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 */ @@ -2377,20 +3497,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 */ @@ -2438,7 +3566,7 @@ { unsigned int cflag; unsigned long xoff; - + unsigned long flags; /* first some safety checks */ if (!info->tty || !info->tty->termios) @@ -2447,17 +3575,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) | @@ -2487,14 +3678,20 @@ info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable); } + if (cflag & CMSPAR) { + /* enable stick parity, PARODD mean Mark which matches ETRAX */ + 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 odd parity */ + /* set odd parity (or Mark if CMSPAR) */ 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); } @@ -2510,10 +3707,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); @@ -2546,8 +3745,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; @@ -2561,7 +3760,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 @@ -2571,6 +3770,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 @@ -2638,6 +3840,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 && @@ -2647,7 +3850,7 @@ } return ret; -} /* raw_write() */ +} /* rs_raw_write() */ static int rs_write(struct tty_struct * tty, int from_user, @@ -2669,7 +3872,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) { @@ -2679,7 +3882,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) @@ -2707,7 +3910,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 */ @@ -2763,20 +3966,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); } /* @@ -2791,50 +4007,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); } /* @@ -2862,8 +4077,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; @@ -2900,9 +4117,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; @@ -3101,18 +4320,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); } @@ -3255,6 +4476,7 @@ change_speed(info); + /* Handle turning off CRTSCTS */ if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) { tty->hw_stopped = 0; @@ -3304,12 +4526,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; } @@ -3343,7 +4566,7 @@ #ifndef CONFIG_SVINTO_SIM e100_disable_rx(info); - e100_disable_rxdma_irq(info); + e100_disable_rx_irq(info); if (info->flags & ASYNC_INITIALIZED) { /* @@ -3679,6 +4902,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; } @@ -3686,11 +4915,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); @@ -3719,11 +4949,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); @@ -3747,12 +5005,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++) { @@ -3767,6 +5027,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) @@ -3780,7 +5056,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" */ } @@ -3797,7 +5074,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; @@ -3871,12 +5148,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; @@ -3923,41 +5203,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 */ Index: arch/cris/drivers/serial.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/serial.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/serial.h 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/serial.h 4 Aug 2004 01:25:40 -0000 1.2 @@ -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 */ Index: arch/cris/drivers/sync_serial.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/sync_serial.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/sync_serial.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/sync_serial.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,14 +1,14 @@ /* * 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 * - * Copyright (c) 2001 Axis Communications AB + * Copyright (c) 2001-2003 Axis Communications AB * - * Author: Mikael Starvik + * Author: Mikael Starvik, Johan Adolfsson * */ #include @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -29,27 +30,28 @@ #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. */ +/* Three DMA descriptors are linked together. Each DMA descriptor is */ +/* responsible for port->bufchunk of a common buffer. */ /* */ -/* ------------------------------ */ -/* | ---------- ---------- | */ -/* --> | Descr1 |-->| Descr2 |--- */ -/* ---------- ---------- */ -/* | | */ -/* v v */ -/* ----------------------------- */ -/* | BUFFER | */ -/* ----------------------------- */ -/* | | */ +/* +---------------------------------------------+ */ +/* | +----------+ +----------+ +----------+ | */ +/* +-> | Descr[0] |-->| Descr[1] |-->| Descr[2] |-+ */ +/* +----------+ +----------+ +----------+ */ +/* | | | */ +/* v v v */ +/* +-------------------------------------+ */ +/* | BUFFER | */ +/* +-------------------------------------+ */ +/* |<- data_avail ->| */ /* readp writep */ /* */ /* If the application keeps up the pace readp will be right after writep.*/ /* If the application can't keep the pace we have to throw away data. */ /* The idea is that readp should be ready with the data pointed out by */ -/* Descr1 when the DMA has filled in Descr2. Otherwise we will discard */ +/* Descr[i] when the DMA has filled in Descr[i+1]. */ +/* Otherwise we will discard */ /* the rest of the data pointed out by Descr1 and set readp to the start */ /* of Descr2 */ @@ -57,14 +59,22 @@ /* IN_BUFFER_SIZE should be a multiple of 6 to make sure that 24 bit */ /* words can be handled */ - +#define NUM_IN_DESCR 3 #define IN_BUFFER_SIZE 12288 #define OUT_BUFFER_SIZE 4096 #define DEFAULT_FRAME_RATE 0 #define DEFAULT_WORD_RATE 7 +/* NOTE: Enabling some debug will likely cause overrun or underrun, + * especially if manual mode is use. + */ #define DEBUG(x) +#define DEBUGREAD(x) +#define DEBUGWRITE(x) +#define DEBUGPOLL(x) +#define DEBUGRXINT(x) +#define DEBUGTXINT(x) /* Define some macros to access ETRAX 100 registers */ #define SETF(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \ @@ -75,97 +85,126 @@ typedef struct sync_port { /* Etrax registers and bits*/ - volatile unsigned * const status; + const volatile unsigned * const status; volatile unsigned * const ctrl_data; volatile unsigned * const output_dma_first; volatile unsigned char * const output_dma_cmd; volatile unsigned char * const output_dma_clr_irq; volatile unsigned * const input_dma_first; volatile unsigned char * const input_dma_cmd; + volatile unsigned * const input_dma_descr; + /* 8*4 */ volatile unsigned char * const input_dma_clr_irq; volatile unsigned * const data_out; - volatile unsigned * const data_in; - char data_avail_bit; /* In R_IRQ_MASK1_RD */ - char transmitter_ready_bit; /* In R_IRQ_MASK1_RD */ - char ready_irq_bit; /* In R_IRQ_MASK1_SET and R_IRQ_MASK1_CLR */ + const volatile unsigned * const data_in; + char data_avail_bit; /* In R_IRQ_MASK1_RD/SET/CLR */ + char transmitter_ready_bit; /* In R_IRQ_MASK1_RD/SET/CLR */ char input_dma_descr_bit; /* In R_IRQ_MASK2_RD */ - char output_dma_bit; /* In R_IRQ_MASK2_RD */ - int enabled; /* 1 if port is enabled */ - int use_dma; /* 1 if port uses dma */ - int port_nbr; /* Port 0 or 1 */ - unsigned ctrl_data_shadow; /* Register shadow */ + char output_dma_bit; /* In R_IRQ_MASK2_RD */ + /* End of fields initialised in array */ + char started; /* 1 if port has been started */ + char port_nbr; /* Port 0 or 1 */ char busy; /* 1 if port is busy */ - wait_queue_head_t out_wait_q; - wait_queue_head_t in_wait_q; + + char enabled; /* 1 if port is enabled */ + char use_dma; /* 1 if port uses dma */ + char cur_in_descr; + char tr_running; + + unsigned int ctrl_data_shadow; /* Register shadow */ + volatile unsigned int out_count; /* Remaining bytes for current transfer */ + unsigned char* outp; /* Current position in out_buffer */ + /* 16*4 */ + volatile unsigned char* volatile readp; /* Next byte to be read by application */ + volatile unsigned char* volatile writep; /* Next byte to be written by etrax */ + unsigned int in_buffer_size; + unsigned int inbufchunk; struct etrax_dma_descr out_descr; - struct etrax_dma_descr in_descr1; - struct etrax_dma_descr in_descr2; - char out_buffer[OUT_BUFFER_SIZE]; - int out_count; /* Remaining bytes for current transfer */ - char* outp; /* Current position in out_buffer */ - char in_buffer[IN_BUFFER_SIZE]; - volatile char* readp; /* Next byte to be read by application */ - volatile char* writep; /* Next byte to be written by etrax */ - int started; /* 1 if port has been started */ + struct etrax_dma_descr in_descr[NUM_IN_DESCR]; + unsigned char out_buffer[OUT_BUFFER_SIZE]; + unsigned char in_buffer[IN_BUFFER_SIZE]; + + wait_queue_head_t out_wait_q; + wait_queue_head_t in_wait_q; } sync_port; static int etrax_sync_serial_init(void); static void initialize_port(int portnbr); +static inline int sync_data_avail(struct sync_port *port); + static int sync_serial_open(struct inode *, struct file*); static int sync_serial_release(struct inode*, struct file*); +static unsigned int sync_serial_poll(struct file *filp, poll_table *wait); + static int sync_serial_ioctl(struct inode*, struct file*, unsigned int cmd, unsigned long arg); static ssize_t sync_serial_write(struct file * file, const char * buf, size_t count, loff_t *ppos); -static ssize_t sync_serial_manual_write(struct file * file, const char * buf, - size_t count, loff_t *ppos); static ssize_t sync_serial_read(struct file *file, char *buf, size_t count, loff_t *ppos); + +#if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \ + defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \ + (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \ + defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)) +#define SYNC_SER_DMA +#endif + static void send_word(sync_port* port); static void start_dma(struct sync_port *port, const char* data, int count); static void start_dma_in(sync_port* port); +#ifdef SYNC_SER_DMA static void tr_interrupt(int irq, void *dev_id, struct pt_regs * regs); static void rx_interrupt(int irq, void *dev_id, struct pt_regs * regs); +#endif +#if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \ + !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \ + (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \ + !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)) +#define SYNC_SER_MANUAL +#endif +#ifdef SYNC_SER_MANUAL static void manual_interrupt(int irq, void *dev_id, struct pt_regs * regs); +#endif /* The ports */ static struct sync_port ports[]= { { - R_SYNC_SERIAL1_STATUS, /* status */ - R_SYNC_SERIAL1_CTRL, /* ctrl_data */ - R_DMA_CH8_FIRST, /* output_dma_first */ - R_DMA_CH8_CMD, /* output_dma_cmd */ - R_DMA_CH8_CLR_INTR, /* output_dma_clr_irq */ - R_DMA_CH9_FIRST, /* input_dma_first */ - R_DMA_CH9_CMD, /* input_dma_cmd */ - R_DMA_CH9_CLR_INTR, /* input_dma_clr_irq */ - R_SYNC_SERIAL1_TR_DATA, /* data_out */ - R_SYNC_SERIAL1_REC_DATA,/* data in */ - IO_BITNR(R_IRQ_MASK1_RD, ser1_data), /* data_avail_bit */ - IO_BITNR(R_IRQ_MASK1_RD, ser1_ready), /* transmitter_ready_bit */ - IO_BITNR(R_IRQ_MASK1_SET, ser1_ready), /* ready_irq_bit */ - IO_BITNR(R_IRQ_MASK2_RD, dma9_descr), /* input_dma_descr_bit */ - IO_BITNR(R_IRQ_MASK2_RD, dma8_eop), /* output_dma_bit */ + .status = R_SYNC_SERIAL1_STATUS, + .ctrl_data = R_SYNC_SERIAL1_CTRL, + .output_dma_first = R_DMA_CH8_FIRST, + .output_dma_cmd = R_DMA_CH8_CMD, + .output_dma_clr_irq = R_DMA_CH8_CLR_INTR, + .input_dma_first = R_DMA_CH9_FIRST, + .input_dma_cmd = R_DMA_CH9_CMD, + .input_dma_descr = R_DMA_CH9_DESCR, + .input_dma_clr_irq = R_DMA_CH9_CLR_INTR, + .data_out = R_SYNC_SERIAL1_TR_DATA, + .data_in = R_SYNC_SERIAL1_REC_DATA, + .data_avail_bit = IO_BITNR(R_IRQ_MASK1_RD, ser1_data), + .transmitter_ready_bit = IO_BITNR(R_IRQ_MASK1_RD, ser1_ready), + .input_dma_descr_bit = IO_BITNR(R_IRQ_MASK2_RD, dma9_descr), + .output_dma_bit = IO_BITNR(R_IRQ_MASK2_RD, dma8_eop), }, { - R_SYNC_SERIAL3_STATUS, /* status */ - R_SYNC_SERIAL3_CTRL, /* ctrl_data */ - R_DMA_CH4_FIRST, /* output_dma_first */ - R_DMA_CH4_CMD, /* output_dma_cmd */ - R_DMA_CH4_CLR_INTR, /* output_dma_clr_irq */ - R_DMA_CH5_FIRST, /* input_dma_first */ - R_DMA_CH5_CMD, /* input_dma_cmd */ - R_DMA_CH5_CLR_INTR, /* input_dma_clr_irq */ - R_SYNC_SERIAL3_TR_DATA, /* data_out */ - R_SYNC_SERIAL3_REC_DATA,/* data in */ - IO_BITNR(R_IRQ_MASK1_RD, ser3_data), /* data_avail_bit */ - IO_BITNR(R_IRQ_MASK1_RD, ser3_ready), /* transmitter_ready_bit */ - IO_BITNR(R_IRQ_MASK1_SET, ser3_ready), /* ready_irq_bit */ - IO_BITNR(R_IRQ_MASK2_RD, dma5_descr), /* input_dma_descr_bit */ - IO_BITNR(R_IRQ_MASK2_RD, dma4_eop), /* output_dma_bit */ + .status = R_SYNC_SERIAL3_STATUS, + .ctrl_data = R_SYNC_SERIAL3_CTRL, + .output_dma_first = R_DMA_CH4_FIRST, + .output_dma_cmd = R_DMA_CH4_CMD, + .output_dma_clr_irq = R_DMA_CH4_CLR_INTR, + .input_dma_first = R_DMA_CH5_FIRST, + .input_dma_cmd = R_DMA_CH5_CMD, + .input_dma_descr = R_DMA_CH5_DESCR, + .input_dma_clr_irq = R_DMA_CH5_CLR_INTR, + .data_out = R_SYNC_SERIAL3_TR_DATA, + .data_in = R_SYNC_SERIAL3_REC_DATA, + .data_avail_bit = IO_BITNR(R_IRQ_MASK1_RD, ser3_data), + .transmitter_ready_bit = IO_BITNR(R_IRQ_MASK1_RD, ser3_ready), + .input_dma_descr_bit = IO_BITNR(R_IRQ_MASK2_RD, dma5_descr), + .output_dma_bit = IO_BITNR(R_IRQ_MASK2_RD, dma4_eop), } }; @@ -176,12 +215,13 @@ #define NUMBER_OF_PORTS (sizeof(ports)/sizeof(sync_port)) static struct file_operations sync_serial_fops = { - owner: THIS_MODULE, - write: sync_serial_write, - read: sync_serial_read, - ioctl: sync_serial_ioctl, - open: sync_serial_open, - release: sync_serial_release + .owner = THIS_MODULE, + .write = sync_serial_write, + .read = sync_serial_read, + .poll = sync_serial_poll, + .ioctl = sync_serial_ioctl, + .open = sync_serial_open, + .release = sync_serial_release }; static int __init etrax_sync_serial_init(void) @@ -238,9 +278,9 @@ ports[1].use_dma = 1; initialize_port(1); if(request_irq(20, tr_interrupt, 0, "synchronous serial 3 dma tr", &ports[1])) - panic("Can't allocate sync serial port 1 IRQ"); + panic("Can't allocate sync serial port 3 IRQ"); if(request_irq(21, rx_interrupt, 0, "synchronous serial 3 dma rx", &ports[1])) - panic("Can't allocate sync serial port 1 IRQ"); + panic("Can't allocate sync serial port 3 IRQ"); RESET_DMA(4); WAIT_DMA(4); RESET_DMA(5); WAIT_DMA(5); *R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do) | @@ -254,9 +294,9 @@ #else ports[1].use_dma = 0; initialize_port(1); - if (ports[0].use_dma) /* Port 0 uses dma, we must manual allocate IRQ */ + if (!ports[0].enabled || 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 @@ -282,7 +322,7 @@ return 0; } -static void initialize_port(int portnbr) +static void __init initialize_port(int portnbr) { struct sync_port* port = &ports[portnbr]; @@ -290,13 +330,21 @@ port->started = 0; port->port_nbr = portnbr; - port->busy = 0; + port->busy = 0; + port->cur_in_descr = 0; + port->tr_running = 0; + + port->out_count = 0; + port->outp = port->out_buffer; + port->readp = port->in_buffer; port->writep = port->in_buffer; + port->in_buffer_size = IN_BUFFER_SIZE; + port->inbufchunk = port->in_buffer_size/NUM_IN_DESCR; init_waitqueue_head(&port->out_wait_q); init_waitqueue_head(&port->in_wait_q); - + port->ctrl_data_shadow = IO_STATE(R_SYNC_SERIAL1_CTRL, tr_baud, c115k2Hz) | IO_STATE(R_SYNC_SERIAL1_CTRL, mode, master_output) | @@ -329,9 +377,53 @@ *port->ctrl_data = port->ctrl_data_shadow; } +static inline int sync_data_avail(struct sync_port *port) +{ + int avail; + unsigned char *start; + unsigned char *end; + + start = (unsigned char*)port->readp; /* cast away volatile */ + end = (unsigned char*)port->writep; /* cast away volatile */ + /* 0123456789 0123456789 + * ----- - ----- + * ^rp ^wp ^wp ^rp + */ + + if (end >= start) + avail = end - start; + else + avail = port->in_buffer_size - (start - end); + return avail; +} + +static inline int sync_data_avail_to_end(struct sync_port *port) +{ + int avail; + unsigned char *start; + unsigned char *end; + + start = (unsigned char*)port->readp; /* cast away volatile */ + end = (unsigned char*)port->writep; /* cast away volatile */ + /* 0123456789 0123456789 + * ----- ----- + * ^rp ^wp ^wp ^rp + */ + + if (end >= start) + avail = end - start; + else + avail = port->in_buffer + port->in_buffer_size - start; + return avail; +} + + static int sync_serial_open(struct inode *inode, struct file *file) { int dev = MINOR(inode->i_rdev); + sync_port* port; + int mode; + DEBUG(printk("Open sync serial port %d\n", dev)); if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) @@ -339,33 +431,87 @@ DEBUG(printk("Invalid minor %d\n", dev)); return -ENODEV; } - if (ports[dev].busy) + port = &ports[dev]; + /* Allow open this device twice (assuming one reader and one writer) */ + if (port->busy == 2) { DEBUG(printk("Device is busy.. \n")); return -EBUSY; } - ports[dev].busy = 1; + port->busy++; + /* Start port if we use it as input */ + mode = IO_EXTRACT(R_SYNC_SERIAL1_CTRL, mode, port->ctrl_data_shadow); + if (mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, master_input) || + mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, slave_input) || + mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, master_bidir) || + mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, slave_bidir)) { + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt, running); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable, enable); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable, enable); + port->started = 1; + *port->ctrl_data = port->ctrl_data_shadow; + if (!port->use_dma) + *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; + DEBUG(printk("sser%d rec started\n", dev)); + } return 0; } static int sync_serial_release(struct inode *inode, struct file *file) { int dev = MINOR(inode->i_rdev); + sync_port* port; + if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { DEBUG(printk("Invalid minor %d\n", dev)); return -ENODEV; } - ports[dev].busy = 0; + port = &ports[dev]; + if (port->busy) + port->busy--; + if (!port->busy) + *R_IRQ_MASK1_CLR = ((1 << port->data_avail_bit) | + (1 << port->transmitter_ready_bit)); + return 0; } + + +static unsigned int sync_serial_poll(struct file *file, poll_table *wait) +{ + int dev = MINOR(file->f_dentry->d_inode->i_rdev); + unsigned int mask = 0; + sync_port* port; + DEBUGPOLL( static unsigned int prev_mask = 0; ); + + port = &ports[dev]; + poll_wait(file, &port->out_wait_q, wait); + poll_wait(file, &port->in_wait_q, wait); + /* Some room to write */ + if (port->out_count < OUT_BUFFER_SIZE) + mask |= POLLOUT | POLLWRNORM; + /* At least an inbufchunk of data */ + if (sync_data_avail(port) >= port->inbufchunk) + mask |= POLLIN | POLLRDNORM; + + DEBUGPOLL(if (mask != prev_mask) + printk("sync_serial_poll: mask 0x%08X %s %s\n", mask, + mask&POLLOUT?"POLLOUT":"", mask&POLLIN?"POLLIN":""); + prev_mask = mask; + ); + return mask; +} + static int sync_serial_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int return_val = 0; + unsigned long flags; + int dev = MINOR(file->f_dentry->d_inode->i_rdev); - sync_port* port; + sync_port* port; if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { @@ -374,197 +520,199 @@ } port = &ports[dev]; + save_flags(flags); + cli(); /* Disable port while changing config */ if (dev) { - RESET_DMA(4); WAIT_DMA(4); - *R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do) | - IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do); + if (port->use_dma) { + RESET_DMA(4); WAIT_DMA(4); + *R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do) | + IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do); + } SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async); } else { - RESET_DMA(8); WAIT_DMA(8); - *R_DMA_CH8_CLR_INTR = IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop, do) | - IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr, do); + if (port->use_dma) { + RESET_DMA(8); WAIT_DMA(8); + *R_DMA_CH8_CLR_INTR = IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop, do) | + IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr, do); + } SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async); } *R_GEN_CONFIG_II = gen_config_ii_shadow; + restore_flags(flags); switch(cmd) { - case SSP_SPEED: - if (GET_SPEED(arg) == CODEC) - { - if (dev) - SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, codec); - else - SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, codec); - - SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, prescaler, GET_FREQ(arg)); - SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, frame_rate, GET_FRAME_RATE(arg)); - SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, word_rate, GET_WORD_RATE(arg)); - } + case SSP_SPEED: + if (GET_SPEED(arg) == CODEC) + { + if (dev) + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, codec); else - { - SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_baud, GET_SPEED(arg)); - if (dev) - SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, baudrate); - else - SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, baudrate); - } - break; - case SSP_MODE: - if (arg > 5) - return -EINVAL; - if (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT) - *R_IRQ_MASK1_CLR = 1 << port->data_avail_bit; + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, codec); + + SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, prescaler, GET_FREQ(arg)); + SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, frame_rate, GET_FRAME_RATE(arg)); + SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, word_rate, GET_WORD_RATE(arg)); + } + else + { + SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_baud, GET_SPEED(arg)); + if (dev) + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, baudrate); else - *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; - SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, arg); - break; - case SSP_FRAME_SYNC: - if (arg & NORMAL_SYNC) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, normal); - else if (arg & EARLY_SYNC) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, early); - - if (arg & BIT_SYNC) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, bit); - else if (arg & WORD_SYNC) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word); - else if (arg & EXTENDED_SYNC) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, extended); - - if (arg & SYNC_ON) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on); - else if (arg & SYNC_OFF) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, off); - - if (arg & WORD_SIZE_8) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit); - else if (arg & WORD_SIZE_12) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size12bit); - else if (arg & WORD_SIZE_16) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size16bit); - else if (arg & WORD_SIZE_24) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size24bit); - else if (arg & WORD_SIZE_32) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size32bit); - - if (arg & BIT_ORDER_MSB) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb); - else if (arg & BIT_ORDER_LSB) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, lsb); - - if (arg & FLOW_CONTROL_ENABLE) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, enabled); - else if (arg & FLOW_CONTROL_DISABLE) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled); - - if (arg & CLOCK_NOT_GATED) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, normal); - else if (arg & CLOCK_GATED) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, gated); - - break; - case SSP_IPOLARITY: - if (arg & CLOCK_NORMAL) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg); - else if (arg & CLOCK_INVERT) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, pos); - - if (arg & FRAME_NORMAL) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, normal); - else if (arg & FRAME_INVERT) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted); - - if (arg & STATUS_NORMAL) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, normal); - else if (arg & STATUS_INVERT) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, inverted); - break; - case SSP_OPOLARITY: - if (arg & CLOCK_NORMAL) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, normal); - else if (arg & CLOCK_INVERT) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted); - - if (arg & FRAME_NORMAL) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, normal); - else if (arg & FRAME_INVERT) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted); - - if (arg & STATUS_NORMAL) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, normal); - else if (arg & STATUS_INVERT) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, inverted); - break; - case SSP_SPI: - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled); - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb); - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit); - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on); - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word); + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, baudrate); + } + break; + case SSP_MODE: + if (arg > 5) + return -EINVAL; + if (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT) + *R_IRQ_MASK1_CLR = 1 << port->data_avail_bit; + else if (!port->use_dma) + *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; + SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, arg); + break; + case SSP_FRAME_SYNC: + if (arg & NORMAL_SYNC) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, normal); - if (arg & SPI_SLAVE) - { - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted); - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg); - SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, SLAVE_INPUT); - } - else - { - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted); - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted); - SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, MASTER_OUTPUT); + else if (arg & EARLY_SYNC) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, early); + + if (arg & BIT_SYNC) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, bit); + else if (arg & WORD_SYNC) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word); + else if (arg & EXTENDED_SYNC) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, extended); + + if (arg & SYNC_ON) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on); + else if (arg & SYNC_OFF) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, off); + + if (arg & WORD_SIZE_8) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit); + else if (arg & WORD_SIZE_12) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size12bit); + else if (arg & WORD_SIZE_16) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size16bit); + else if (arg & WORD_SIZE_24) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size24bit); + else if (arg & WORD_SIZE_32) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size32bit); + + if (arg & BIT_ORDER_MSB) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb); + else if (arg & BIT_ORDER_LSB) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, lsb); + + if (arg & FLOW_CONTROL_ENABLE) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, enabled); + else if (arg & FLOW_CONTROL_DISABLE) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled); + + if (arg & CLOCK_NOT_GATED) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, normal); + else if (arg & CLOCK_GATED) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, gated); + + break; + case SSP_IPOLARITY: + /* NOTE!! negedge is considered NORMAL */ + if (arg & CLOCK_NORMAL) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg); + else if (arg & CLOCK_INVERT) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, pos); + + if (arg & FRAME_NORMAL) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, normal); + else if (arg & FRAME_INVERT) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted); + + if (arg & STATUS_NORMAL) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, normal); + else if (arg & STATUS_INVERT) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, inverted); + break; + case SSP_OPOLARITY: + if (arg & CLOCK_NORMAL) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, normal); + else if (arg & CLOCK_INVERT) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted); + + if (arg & FRAME_NORMAL) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, normal); + else if (arg & FRAME_INVERT) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted); + + if (arg & STATUS_NORMAL) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, normal); + else if (arg & STATUS_INVERT) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, inverted); + break; + case SSP_SPI: + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, normal); + if (arg & SPI_SLAVE) + { + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg); + SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, SLAVE_INPUT); + } + else + { + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted); + SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, MASTER_OUTPUT); + } + break; + case SSP_INBUFCHUNK: + if (arg > port->in_buffer_size/NUM_IN_DESCR) + return -EINVAL; + port->inbufchunk = arg; + /* Make sure in_buffer_size is a multiple of inbufchunk */ + port->in_buffer_size = (port->in_buffer_size/port->inbufchunk) * port->inbufchunk; + DEBUG(printk("inbufchunk %i in_buffer_size: %i\n", port->inbufchunk, port->in_buffer_size)); + if (port->use_dma) { + if (port->port_nbr == 0) { + RESET_DMA(9); + WAIT_DMA(9); + } else { + RESET_DMA(5); + WAIT_DMA(5); } - break; - default: - return_val = -1; + start_dma_in(port); + } + break; + default: + return_val = -1; } + /* Make sure we write the config without interruption */ + save_flags(flags); + cli(); /* Set config and enable port */ *port->ctrl_data = port->ctrl_data_shadow; + nop(); nop(); nop(); nop(); *R_SYNC_SERIAL_PRESCALE = sync_serial_prescale_shadow; + nop(); nop(); nop(); nop(); if (dev) SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, sync); else SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, sync); *R_GEN_CONFIG_II = gen_config_ii_shadow; + restore_flags(flags); return return_val; } -static ssize_t sync_serial_manual_write(struct file * file, const char * buf, - size_t count, loff_t *ppos) -{ - int dev = MINOR(file->f_dentry->d_inode->i_rdev); - DECLARE_WAITQUEUE(wait, current); - sync_port* port; - - if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) - { - DEBUG(printk("Invalid minor %d\n", dev)); - return -ENODEV; - } - - port = &ports[dev]; - copy_from_user(port->out_buffer, buf, count); - port->outp = port->out_buffer; - port->out_count = count; - add_wait_queue(&port->out_wait_q, &wait); - set_current_state(TASK_INTERRUPTIBLE); - send_word(port); /* Start sender by sending first word */ - *R_IRQ_MASK1_SET = 1 << port->ready_irq_bit; /* transmitter ready IRQ on */ - schedule(); - set_current_state(TASK_RUNNING); - remove_wait_queue(&port->out_wait_q, &wait); - if (signal_pending(current)) - { - return -EINTR; - } - return count; -} static ssize_t sync_serial_write(struct file * file, const char * buf, size_t count, loff_t *ppos) @@ -572,6 +720,11 @@ int dev = MINOR(file->f_dentry->d_inode->i_rdev); DECLARE_WAITQUEUE(wait, current); sync_port *port; + unsigned long flags; + unsigned long c, c1; + unsigned long free_outp; + unsigned long outp; + unsigned long out_buffer; if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { @@ -580,9 +733,52 @@ } port = &ports[dev]; - DEBUG(printk("Write dev %d count %d\n", port->port_nbr, count)); + DEBUGWRITE(printk("W d%d c %lu (%d/%d)\n", port->port_nbr, count, port->out_count, OUT_BUFFER_SIZE)); + /* Space to end of buffer */ + /* + * out_buffer 012345<- c ->OUT_BUFFER_SIZE + * outp^ +out_count + ^free_outp + * out_buffer 45<- c ->0123OUT_BUFFER_SIZE + * +out_count outp^ + * free_outp + * + */ - count = count > OUT_BUFFER_SIZE ? OUT_BUFFER_SIZE : count; + /* Read variables that may be updated by interrupts */ + save_flags(flags); + cli(); + count = count > OUT_BUFFER_SIZE - port->out_count ? OUT_BUFFER_SIZE - port->out_count : count; + outp = (unsigned long)port->outp; + free_outp = outp + port->out_count; + restore_flags(flags); + out_buffer = (unsigned long)port->out_buffer; + + /* Find out where and how much to write */ + if (free_outp >= out_buffer + OUT_BUFFER_SIZE) + free_outp -= OUT_BUFFER_SIZE; + if (free_outp >= outp) + c = out_buffer + OUT_BUFFER_SIZE - free_outp; + else + c = outp - free_outp; + if (c > count) + c = count; + +// DEBUGWRITE(printk("w op %08lX fop %08lX c %lu\n", outp, free_outp, c)); + if (copy_from_user((void*)free_outp, buf, c)) + return -EFAULT; + + if (c != count) { + buf += c; + c1 = count - c; + DEBUGWRITE(printk("w2 fi %lu c %lu c1 %lu\n", free_outp-out_buffer, c, c1)); + if (copy_from_user((void*)out_buffer, buf, c1)) + return -EFAULT; + } + save_flags(flags); + cli(); + port->out_count += count; + restore_flags(flags); /* Make sure transmitter/receiver is running */ if (!port->started) @@ -595,15 +791,42 @@ *port->ctrl_data = port->ctrl_data_shadow; - if (!port->use_dma) - { - return sync_serial_manual_write(file, buf, count, ppos); + if (file->f_flags & O_NONBLOCK) { + save_flags(flags); + cli(); + if (!port->tr_running) { + if (!port->use_dma) { + /* Start sender by writing data */ + send_word(port); + /* and enable transmitter ready IRQ */ + *R_IRQ_MASK1_SET = 1 << port->transmitter_ready_bit; + } else { + start_dma(port, (unsigned char* volatile )port->outp, c); + } + } + restore_flags(flags); + DEBUGWRITE(printk("w d%d c %lu NB\n", + port->port_nbr, count)); + return count; } - - copy_from_user(port->out_buffer, buf, count); + + /* Sleep until all sent */ + add_wait_queue(&port->out_wait_q, &wait); set_current_state(TASK_INTERRUPTIBLE); - start_dma(port, buf, count); + save_flags(flags); + cli(); + if (!port->tr_running) { + if (!port->use_dma) { + /* Start sender by writing data */ + send_word(port); + /* and enable transmitter ready IRQ */ + *R_IRQ_MASK1_SET = 1 << port->transmitter_ready_bit; + } else { + start_dma(port, port->outp, c); + } + } + restore_flags(flags); schedule(); set_current_state(TASK_RUNNING); remove_wait_queue(&port->out_wait_q, &wait); @@ -611,6 +834,7 @@ { return -EINTR; } + DEBUGWRITE(printk("w d%d c %lu\n", port->port_nbr, count)); return count; } @@ -620,8 +844,8 @@ int dev = MINOR(file->f_dentry->d_inode->i_rdev); int avail; sync_port *port; - char* start; - char* end; + unsigned char* start; + unsigned char* end; unsigned long flags; if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) @@ -631,7 +855,7 @@ } port = &ports[dev]; - DEBUG(printk("Read dev %d count %d\n", dev, count)); + DEBUGREAD(printk("R%d c %d ri %lu wi %lu /%lu\n", dev, count, port->readp - port->in_buffer, port->writep - port->in_buffer, port->in_buffer_size)); if (!port->started) { @@ -640,11 +864,17 @@ SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable, enable); port->started = 1; } - *port->ctrl_data = port->ctrl_data_shadow; + /* Calculate number of available bytes */ - while (port->readp == port->writep) /* No data */ + /* Save pointers to avoid that they are modified by interrupt */ + save_flags(flags); + cli(); + start = (unsigned char*)port->readp; /* cast away volatile */ + end = (unsigned char*)port->writep; /* cast away volatile */ + restore_flags(flags); + while (start == end) /* No data */ { if (file->f_flags & O_NONBLOCK) return -EAGAIN; @@ -653,127 +883,137 @@ { return -EINTR; } + save_flags(flags); + cli(); + start = (unsigned char*)port->readp; /* cast away volatile */ + end = (unsigned char*)port->writep; /* cast away volatile */ + restore_flags(flags); } - - /* Save pointers to avoid that they are modified by interrupt */ - start = port->readp; - end = port->writep; /* Lazy read, never return wrapped data. */ if (end > start) avail = end - start; else - avail = port->in_buffer + IN_BUFFER_SIZE - start; + avail = port->in_buffer + port->in_buffer_size - start; count = count > avail ? avail : count; - copy_to_user(buf, start, count); + if (copy_to_user(buf, start, count)) + return -EFAULT; /* Disable interrupts while updating readp */ save_flags(flags); cli(); port->readp += count; - if (port->readp == port->in_buffer + IN_BUFFER_SIZE) /* Wrap? */ + if (port->readp >= port->in_buffer + port->in_buffer_size) /* Wrap? */ port->readp = port->in_buffer; restore_flags(flags); - - DEBUG(printk("%d bytes read\n", count)); + DEBUGREAD(printk("r %d\n", count)); return count; } static void send_word(sync_port* port) { - switch(port->ctrl_data_shadow & IO_MASK(R_SYNC_SERIAL1_CTRL, wordsize)) + switch(IO_EXTRACT(R_SYNC_SERIAL1_CTRL, wordsize, port->ctrl_data_shadow)) { - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit): - port->out_count--; - *port->data_out = *port->outp++; - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit): - { - int data = (*port->outp++) << 8; - data |= *port->outp++; - port->out_count-=2; - *port->data_out = data; - } - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit): - port->out_count-=2; - *port->data_out = *(unsigned short *)port->outp; - port->outp+=2; - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit): - port->out_count-=3; - *port->data_out = *(unsigned int *)port->outp; - port->outp+=3; - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit): - port->out_count-=4; - *port->data_out = *(unsigned int *)port->outp; - port->outp+=4; - break; + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit): + port->out_count--; + *port->data_out = *port->outp++; + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) + port->outp = port->out_buffer; + break; + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit): + { + int data = (*port->outp++) << 8; + data |= *port->outp++; + port->out_count-=2; + *port->data_out = data; + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) + port->outp = port->out_buffer; + } + break; + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit): + port->out_count-=2; + *port->data_out = *(unsigned short *)port->outp; + port->outp+=2; + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) + port->outp = port->out_buffer; + break; + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit): + port->out_count-=3; + *port->data_out = *(unsigned int *)port->outp; + port->outp+=3; + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) + port->outp = port->out_buffer; + break; + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit): + port->out_count-=4; + *port->data_out = *(unsigned int *)port->outp; + port->outp+=4; + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) + port->outp = port->out_buffer; + break; } } + static void start_dma(struct sync_port* port, const char* data, int count) { + port->tr_running = 1; port->out_descr.hw_len = 0; port->out_descr.next = 0; - port->out_descr.ctrl = d_eol | d_eop | d_wait; + port->out_descr.ctrl = d_eol | d_eop; /* No d_wait to avoid glitches */ port->out_descr.sw_len = count; - port->out_descr.buf = virt_to_phys(port->out_buffer); + port->out_descr.buf = virt_to_phys((char*)data); port->out_descr.status = 0; *port->output_dma_first = virt_to_phys(&port->out_descr); *port->output_dma_cmd = IO_STATE(R_DMA_CH0_CMD, cmd, start); + DEBUGTXINT(printk("dma %08lX c %d\n", (unsigned long)data, count)); } static void start_dma_in(sync_port* port) { - if (port->writep > port->in_buffer + IN_BUFFER_SIZE) + int i; + unsigned long buf; + port->cur_in_descr = 0; + port->writep = port->in_buffer; + + if (port->writep > port->in_buffer + port->in_buffer_size) { panic("Offset too large in sync serial driver\n"); return; } - port->in_descr1.hw_len = 0; - port->in_descr1.ctrl = d_int; - port->in_descr1.status = 0; - port->in_descr1.next = virt_to_phys(&port->in_descr2); - port->in_descr2.hw_len = 0; - port->in_descr2.next = virt_to_phys(&port->in_descr1); - port->in_descr2.ctrl = d_int; - port->in_descr2.status = 0; - - /* Find out which descriptor to start */ - if (port->writep >= port->in_buffer + IN_BUFFER_SIZE/2) - { - /* Start descriptor 2 */ - port->in_descr1.sw_len = IN_BUFFER_SIZE/2; /* All data available in 1 */ - port->in_descr1.buf = virt_to_phys(port->in_buffer); - port->in_descr2.sw_len = port->in_buffer + IN_BUFFER_SIZE - port->writep; - port->in_descr2.buf = virt_to_phys(port->writep); - *port->input_dma_first = virt_to_phys(&port->in_descr2); - } - else - { - /* Start descriptor 1 */ - port->in_descr1.sw_len = port->in_buffer + IN_BUFFER_SIZE/2 - port->writep; - port->in_descr1.buf = virt_to_phys(port->writep); - port->in_descr2.sw_len = IN_BUFFER_SIZE/2; - port->in_descr2.buf = virt_to_phys(port->in_buffer + IN_BUFFER_SIZE / 2); - *port->input_dma_first = virt_to_phys(&port->in_descr1); - } + buf = virt_to_phys(port->in_buffer); + for (i = 0; i < NUM_IN_DESCR; i++) { + port->in_descr[i].sw_len = port->inbufchunk; + port->in_descr[i].ctrl = d_int; + port->in_descr[i].next = virt_to_phys(&port->in_descr[i+1]); + port->in_descr[i].buf = buf; + port->in_descr[i].hw_len = 0; + port->in_descr[i].status = 0; + port->in_descr[i].fifo_len = 0; + buf += port->inbufchunk; + prepare_rx_descriptor(&port->in_descr[i]); + } + /* Link the last descriptor to the first */ + port->in_descr[i-1].next = virt_to_phys(&port->in_descr[0]); + *port->input_dma_first = virt_to_phys(&port->in_descr[(int)port->cur_in_descr]); *port->input_dma_cmd = IO_STATE(R_DMA_CH0_CMD, cmd, start); } +#ifdef SYNC_SER_DMA static void tr_interrupt(int irq, void *dev_id, struct pt_regs * regs) { unsigned long ireg = *R_IRQ_MASK2_RD; int i; + struct etrax_dma_descr *descr; + unsigned int sentl; + for (i = 0; i < NUMBER_OF_PORTS; i++) { sync_port *port = &ports[i]; - if (!port->enabled) + if (!port->enabled || !port->use_dma ) continue; if (ireg & (1 << port->output_dma_bit)) /* IRQ active for the port? */ @@ -782,54 +1022,89 @@ *port->output_dma_clr_irq = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do) | IO_STATE(R_DMA_CH0_CLR_INTR, clr_descr, do); + + descr = &port->out_descr; + if (!(descr->status & d_stop)) { + sentl = descr->sw_len; + } else + /* otherwise we find the amount of data sent here */ + sentl = descr->hw_len; + port->out_count -= sentl; + port->outp += sentl; + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) + port->outp = port->out_buffer; + if (port->out_count) { + int c; + c = port->out_buffer + OUT_BUFFER_SIZE - port->outp; + if (c > port->out_count) + c = port->out_count; + DEBUGTXINT(printk("tx_int DMAWRITE %i %i\n", sentl, c)); + start_dma(port, port->outp, c); + } else { + DEBUGTXINT(printk("tx_int DMA stop %i\n", sentl)); + port->tr_running = 0; + } wake_up_interruptible(&port->out_wait_q); /* wake up the waiting process */ } } -} +} /* tr_interrupt */ static void rx_interrupt(int irq, void *dev_id, struct pt_regs * regs) { unsigned long ireg = *R_IRQ_MASK2_RD; - int i; + int i; for (i = 0; i < NUMBER_OF_PORTS; i++) { sync_port *port = &ports[i]; - if (!port->enabled) + if (!port->enabled || !port->use_dma ) continue; if (ireg & (1 << port->input_dma_descr_bit)) /* Descriptor interrupt */ { + struct etrax_dma_descr *descr; + unsigned recvl; + unsigned long oldbuf, buf; + /* DMA has reached end of descriptor */ *port->input_dma_clr_irq = IO_STATE(R_DMA_CH0_CLR_INTR, clr_descr, do); - - /* Find out which descriptor that is ready */ - if (port->writep >= port->in_buffer + IN_BUFFER_SIZE/2) - { - /* Descr 2 was ready. Restart DMA at descriptor 1 */ - port->writep = port->in_buffer; - - /* Throw away data? */ - if (port->readp < port->in_buffer + IN_BUFFER_SIZE/2) - port->readp = port->in_buffer + IN_BUFFER_SIZE/2; - } - else - { - /* Descr 1 was ready. Restart DMA at descriptor 2 */ - port->writep = port->in_buffer + IN_BUFFER_SIZE/2; - - /* Throw away data? */ - if (port->readp >= port->in_buffer + IN_BUFFER_SIZE/2) - port->readp = port->in_buffer; + + descr = &port->in_descr[(int)port->cur_in_descr]; + if (descr == phys_to_virt(*port->input_dma_descr)) + printk("sser: desc = *input_dma_descr\n"); + + if (!(descr->status & d_eop)) { + recvl = descr->sw_len; + } else { + /* otherwise we find the amount of data received here */ + recvl = descr->hw_len; } - start_dma_in(port); + port->writep += recvl; + if (port->writep >= port->in_buffer+ port->in_buffer_size) + port->writep = port->in_buffer; + descr->sw_len = port->inbufchunk; + /* Reset the status information */ + descr->status = 0; + /* Change the buf pointer to new position */ + oldbuf = descr->buf; + + descr->buf += NUM_IN_DESCR * port->inbufchunk; + buf = virt_to_phys(port->in_buffer); + if (descr->buf >= buf + port->in_buffer_size) + descr->buf -= port->in_buffer_size; + DEBUGRXINT(printk("rx_int descr %i %X recvl: %i writep %lu obuf %lu %08lX buf 0x%08lX\n", port->cur_in_descr, (unsigned long) (*port->input_dma_descr), recvl, (unsigned long)(port->writep - port->in_buffer), oldbuf, oldbuf, (unsigned long)descr->buf)); + if (++port->cur_in_descr == NUM_IN_DESCR) + port->cur_in_descr = 0; + wake_up_interruptible(&port->in_wait_q); /* wake up the waiting process */ } } -} +} /* rx_interrupt */ +#endif /* SYNC_SER_DMA */ +#ifdef SYNC_SER_MANUAL static void manual_interrupt(int irq, void *dev_id, struct pt_regs * regs) { int i; @@ -838,7 +1113,7 @@ { sync_port* port = &ports[i]; - if (!port->enabled) + if (!port->enabled || port->use_dma) { continue; } @@ -848,34 +1123,42 @@ /* Read data */ switch(port->ctrl_data_shadow & IO_MASK(R_SYNC_SERIAL1_CTRL, wordsize)) { - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit): - *port->writep++ = *(volatile char *)port->data_in; - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit): - { - int data = *(unsigned short *)port->data_in; - *port->writep = (data & 0x0ff0) >> 4; - *(port->writep + 1) = data & 0x0f; - port->writep+=2; - } + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit): + *port->writep++ = *(volatile char *)port->data_in; + break; + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit): + { + int data = *(unsigned short *)port->data_in; + *port->writep = (data & 0x0ff0) >> 4; + *(port->writep + 1) = data & 0x0f; + port->writep+=2; + } + break; + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit): + *(unsigned short*)port->writep = *(volatile unsigned short *)port->data_in; + port->writep+=2; + break; + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit): + *(unsigned int*)port->writep = *port->data_in; + port->writep+=3; + break; + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit): + *(unsigned int*)port->writep = *port->data_in; + port->writep+=4; break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit): - *(unsigned short*)port->writep = *(volatile unsigned short *)port->data_in; - port->writep+=2; - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit): - *(unsigned int*)port->writep = *port->data_in; - port->writep+=3; - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit): - *(unsigned int*)port->writep = *port->data_in; - port->writep+=4; - break; } - if (port->writep >= port->in_buffer + IN_BUFFER_SIZE) /* Wrap? */ + if (port->writep >= port->in_buffer + port->in_buffer_size) /* Wrap? */ port->writep = port->in_buffer; - wake_up_interruptible(&port->in_wait_q); /* Wake up application */ + if (port->writep == port->readp) { + /* receive buffer overrun, discard oldest data + */ + port->readp++; + if (port->readp >= port->in_buffer + port->in_buffer_size) /* Wrap? */ + port->readp = port->in_buffer; + } + if (sync_data_avail(port) >= port->inbufchunk) + wake_up_interruptible(&port->in_wait_q); /* Wake up application */ } if (*R_IRQ_MASK1_RD & (1 << port->transmitter_ready_bit)) /* Transmitter ready? */ @@ -884,11 +1167,12 @@ send_word(port); else /* transmission finished */ { - *R_IRQ_MASK1_CLR = 1 << port->ready_irq_bit; /* Turn off IRQ */ + *R_IRQ_MASK1_CLR = 1 << port->transmitter_ready_bit; /* Turn off IRQ */ wake_up_interruptible(&port->out_wait_q); /* Wake up application */ } } } } +#endif module_init(etrax_sync_serial_init); Index: arch/cris/drivers/usb-host.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/usb-host.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/usb-host.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/usb-host.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -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.1 2004/07/22 19:49:09 joff 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.1 $"; +static const char *usb_hcd_version = "$Revision: 1.2 $"; #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_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_ep(format, arg...) do {} while (0) +#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(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; + } -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); + 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,1002 @@ 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)) { + __u32 r_usb_ept_data; + + warn("error in rx desc->status, epid %d, first urb = 0x%lx", + epid, (unsigned long)urb); + __dump_in_desc(myNextRxDesc); + + *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); + nop(); + r_usb_ept_data = *R_USB_EPT_DATA; + warn("R_USB_EPT_DATA for epid %d = 0x%x", epid, r_usb_ept_data); + warn("R_USB_STATUS = 0x%x", *R_USB_STATUS); + + 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 +2190,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 +3255,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 +3270,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 +3317,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 +3346,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 +3357,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 +3368,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 +3406,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 +3432,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 +3447,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 +3462,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 +3630,10 @@ data, wLength); if (len > 0) { OK(min(leni, len)); - } else + } else { stat = -EPIPE; + } + } break; @@ -2309,33 +3658,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 +3722,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 +3780,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 +3838,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 +3891,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 +3936,8 @@ free_dma(USB_RX_DMA_NBR); usb_deregister_bus(etrax_usb_bus); + /* FIXME: call kmem_cache_destroy here? */ + DBFEXIT; } Index: arch/cris/drivers/usb-host.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/usb-host.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/usb-host.h 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/usb-host.h 4 Aug 2004 01:25:40 -0000 1.2 @@ -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 ------------------------------------------------------------------------- */ Index: arch/cris/drivers/virtex.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/virtex.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/virtex.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/virtex.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -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,8 +31,11 @@ *! *! Jul 19 2002 Stefan Lundberg Initial version. *! $Log: virtex.c,v $ -*! Revision 1.1 2004/07/22 19:49:09 joff -*! Initial revision +*! Revision 1.2 2004/08/04 01:25:40 joff +*! merging 2.4.26-vrs1 +*! +*! 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 @@ -43,7 +46,7 @@ *! (C) Copyright 2002 Axis Communications AB, LUND, SWEDEN *! *!***************************************************************************/ -/* $Id: virtex.c,v 1.1 2004/07/22 19:49:09 joff Exp $ */ +/* $Id: virtex.c,v 1.2 2004/08/04 01:25:40 joff Exp $ */ /****************** INCLUDE FILES SECTION ***********************************/ #include @@ -130,14 +133,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); @@ -307,6 +316,7 @@ } if(copy_from_user(ptr, buf, count)) { printk("copy_from_user failed\n"); + kfree(ptr); return -EFAULT; } @@ -342,7 +352,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))); @@ -350,12 +360,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: Index: arch/cris/drivers/virtex.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/virtex.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/virtex.h 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/virtex.h 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,7 +1,2 @@ -/* $Id: virtex.h,v 1.1 2004/07/22 19:49:09 joff Exp $ */ - int virtex_writereg(unsigned short theReg, unsigned short theValue); unsigned short virtex_readreg(unsigned short theReg); - - - Index: arch/cris/drivers/examples/kiobuftest.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/examples/kiobuftest.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/examples/kiobuftest.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/examples/kiobuftest.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -4,21 +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.1 2004/07/22 19:49:09 joff - * Initial revision - * - * 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 * */ @@ -35,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; + + /* + * 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; + } - 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. - */ + /* + * 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; } @@ -100,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; } @@ -108,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); Index: arch/cris/drivers/lpslave/bintocarr.pl =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/lpslave/bintocarr.pl,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/lpslave/bintocarr.pl 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/lpslave/bintocarr.pl 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,5 +1,5 @@ #!/usr/bin/perl -w -# $Id: bintocarr.pl,v 1.1 2004/07/22 19:49:09 joff 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"; - Index: arch/cris/drivers/lpslave/e100lpslave.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/lpslave/e100lpslave.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/lpslave/e100lpslave.S 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/lpslave/e100lpslave.S 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,12 +1,11 @@ - ;; $Id: e100lpslave.S,v 1.1 2004/07/22 19:49:09 joff 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 Index: arch/cris/drivers/lpslave/e100lpslavenet.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/drivers/lpslave/e100lpslavenet.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/drivers/lpslave/e100lpslavenet.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/drivers/lpslave/e100lpslavenet.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: e100lpslavenet.c,v 1.1 2004/07/22 19:49:09 joff Exp $ +/* $Id: e100lpslavenet.c,v 1.2 2004/08/04 01:25:40 joff Exp $ * * e100lpslavenet.c: A network driver for the ETRAX 100LX slave controller. * @@ -7,8 +7,8 @@ * The outline of this driver comes from skeleton.c. * * $Log: e100lpslavenet.c,v $ - * Revision 1.1 2004/07/22 19:49:09 joff - * Initial revision + * Revision 1.2 2004/08/04 01:25:40 joff + * merging 2.4.26-vrs1 * * Revision 1.5 2002/04/22 11:47:24 johana * Fix according to 2.4.19-pre7. time_after/time_before and Index: arch/cris/kernel/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/kernel/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/kernel/Makefile 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/kernel/Makefile 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,4 +1,3 @@ -# $Id: Makefile,v 1.1 2004/07/22 19:49:09 joff 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: Index: arch/cris/kernel/debugport.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/kernel/debugport.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/kernel/debugport.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/kernel/debugport.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -12,8 +12,19 @@ * init_etrax_debug() * * $Log: debugport.c,v $ - * Revision 1.1 2004/07/22 19:49:09 joff - * Initial revision + * Revision 1.2 2004/08/04 01:25:40 joff + * merging 2.4.26-vrs1 + * + * 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) @@ -34,6 +45,7 @@ #include #include #include +#include #include #include @@ -97,6 +109,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. @@ -106,8 +120,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 */ @@ -129,6 +146,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. @@ -137,37 +185,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); } Index: arch/cris/kernel/entry.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/kernel/entry.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/kernel/entry.S 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/kernel/entry.S 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.1 2004/07/22 19:49:09 joff Exp $ +/* $Id: entry.S,v 1.2 2004/08/04 01:25:40 joff Exp $ * * linux/arch/cris/entry.S * @@ -7,8 +7,14 @@ * Authors: Bjorn Wesen (bjornw@axis.com) * * $Log: entry.S,v $ - * Revision 1.1 2004/07/22 19:49:09 joff - * Initial revision + * Revision 1.2 2004/08/04 01:25:40 joff + * merging 2.4.26-vrs1 + * + * 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 @@ -361,6 +367,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 @@ -452,6 +464,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 Index: arch/cris/kernel/fasttimer.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/kernel/fasttimer.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/kernel/fasttimer.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/kernel/fasttimer.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,12 +1,18 @@ -/* $Id: fasttimer.c,v 1.1 2004/07/22 19:49:09 joff Exp $ +/* $Id: fasttimer.c,v 1.2 2004/08/04 01:25:40 joff 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.1 2004/07/22 19:49:09 joff - * Initial revision + * Revision 1.2 2004/08/04 01:25:40 joff + * merging 2.4.26-vrs1 + * + * 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 @@ -66,7 +72,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 @@ -121,7 +127,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 @@ -316,7 +322,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; } @@ -382,11 +389,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; @@ -773,7 +775,7 @@ cli(); if (t->next != nextt) { - printk("timer removed!\n"); + printk(KERN_WARNING "timer removed!\n"); } t = nextt; } @@ -954,7 +956,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++) @@ -974,7 +976,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 Index: arch/cris/kernel/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/kernel/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/kernel/head.S 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/kernel/head.S 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: head.S,v 1.1 2004/07/22 19:49:09 joff Exp $ +/* $Id: head.S,v 1.2 2004/08/04 01:25:40 joff Exp $ * * Head of the kernel - alter with care * @@ -7,8 +7,17 @@ * Authors: Bjorn Wesen (bjornw@axis.com) * * $Log: head.S,v $ - * Revision 1.1 2004/07/22 19:49:09 joff - * Initial revision + * Revision 1.2 2004/08/04 01:25:40 joff + * merging 2.4.26-vrs1 + * + * 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... @@ -314,7 +323,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 @@ -546,14 +555,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) \ @@ -564,19 +583,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 @@ -843,5 +872,5 @@ swapper_pg_dir = 0xc0002000 #endif - .section ".data.init" + .section ".data.init", "aw" #include "../lib/hw_settings.S" Index: arch/cris/kernel/hexify.c =================================================================== RCS file: arch/cris/kernel/hexify.c diff -N arch/cris/kernel/hexify.c --- arch/cris/kernel/hexify.c 22 Jul 2004 19:49:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,31 +0,0 @@ -#include - - -void main() -{ - int c; - int comma=0; - int count=0; - while((c=getchar())!=EOF) - { - unsigned char x=c; - if(comma) - printf(","); - else - comma=1; - if(count==8) - { - count=0; - printf("\n"); - } - if(count==0) - printf("\t"); - printf("0x%02X",c); - count++; - } - if(count) - printf("\n"); - exit(0); -} - - Index: arch/cris/kernel/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/kernel/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/kernel/irq.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/kernel/irq.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,8 +1,7 @@ -/* $Id: irq.c,v 1.1 2004/07/22 19:49:09 joff 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) Index: arch/cris/kernel/kgdb.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/kernel/kgdb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/kernel/kgdb.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/kernel/kgdb.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -18,8 +18,11 @@ *! Jul 21 1999 Bjorn Wesen eLinux port *! *! $Log: kgdb.c,v $ -*! Revision 1.1 2004/07/22 19:49:09 joff -*! Initial revision +*! Revision 1.2 2004/08/04 01:25:40 joff +*! merging 2.4.26-vrs1 +*! +*! 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 @@ -61,7 +64,7 @@ *! *!--------------------------------------------------------------------------- *! -*! $Id: kgdb.c,v 1.1 2004/07/22 19:49:09 joff Exp $ +*! $Id: kgdb.c,v 1.2 2004/08/04 01:25:40 joff Exp $ *! *! (C) Copyright 1999, Axis Communications AB, LUND, SWEDEN *! @@ -155,7 +158,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. * */ @@ -1489,7 +1492,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 Index: arch/cris/kernel/ksyms.c =================================================================== RCS file: arch/cris/kernel/ksyms.c diff -N arch/cris/kernel/ksyms.c --- arch/cris/kernel/ksyms.c 22 Jul 2004 19:49:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,90 +0,0 @@ -#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 __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(strncat); -EXPORT_SYMBOL(strncmp); -EXPORT_SYMBOL(strncpy); - -/* Math functions */ -EXPORT_SYMBOL(__Udiv); -EXPORT_SYMBOL(__Umod); -EXPORT_SYMBOL(__ashrdi3); - -/* Memory functions */ -EXPORT_SYMBOL(__ioremap); -EXPORT_SYMBOL(iounmap); - -/* Semaphore functions */ -EXPORT_SYMBOL(__up); -EXPORT_SYMBOL(__down); - -/* 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); - - Index: arch/cris/kernel/process.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/kernel/process.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/kernel/process.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/kernel/process.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.1 2004/07/22 19:49:09 joff Exp $ +/* $Id: process.c,v 1.2 2004/08/04 01:25:40 joff Exp $ * * linux/arch/cris/kernel/process.c * @@ -8,8 +8,11 @@ * Authors: Bjorn Wesen (bjornw@axis.com) * * $Log: process.c,v $ - * Revision 1.1 2004/07/22 19:49:09 joff - * Initial revision + * Revision 1.2 2004/08/04 01:25:40 joff + * merging 2.4.26-vrs1 + * + * 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 @@ -117,7 +120,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) { @@ -128,19 +141,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(); } } @@ -194,6 +230,8 @@ void machine_power_off(void) { + if (pm_power_off) + pm_power_off(); } /* Index: arch/cris/kernel/ptrace.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/kernel/ptrace.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/kernel/ptrace.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/kernel/ptrace.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -8,8 +8,12 @@ * Authors: Bjorn Wesen * * $Log: ptrace.c,v $ - * Revision 1.1 2004/07/22 19:49:09 joff - * Initial revision + * Revision 1.2 2004/08/04 01:25:40 joff + * merging 2.4.26-vrs1 + * + * Revision 1.9 2003/10/01 11:34:23 aurer + * * Allow PTRACE_PEEKUSR and PTRACE_POKEUSR to access USP. + * * Removed nonsensical comment about ptrace behavior. * * Revision 1.8 2001/11/12 18:26:21 pkj * Fixed compiler warnings. @@ -99,14 +103,6 @@ /* Todo - pending singlesteps? */ } -/* Note that this implementation of ptrace behaves differently from vanilla - * ptrace. Contrary to what the man page says, in the PTRACE_PEEKTEXT, - * PTRACE_PEEKDATA, and PTRACE_PEEKUSER requests the data variable is not - * ignored. Instead, the data variable is expected to point at a location - * (in user space) where the result of the ptrace call is written (instead of - * being returned). - */ - asmlinkage int sys_ptrace(long request, long pid, long addr, long data) { struct task_struct *child; @@ -166,17 +162,13 @@ /* read the word at location addr in the USER area. */ case PTRACE_PEEKUSR: { unsigned long tmp; - + ret = -EIO; - if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) + if ((addr & 3) || addr < 0 || addr > PT_MAX << 2) break; - - tmp = 0; /* Default return condition */ - ret = -EIO; - if (addr < sizeof(struct pt_regs)) { - tmp = get_reg(child, addr >> 2); - ret = put_user(tmp, (unsigned long *)data); - } + + tmp = get_reg(child, addr >> 2); + ret = put_user(tmp, (unsigned long *)data); break; } @@ -191,23 +183,21 @@ case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ ret = -EIO; - if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) + if ((addr & 3) || addr < 0 || addr > PT_MAX << 2) break; - if (addr < sizeof(struct pt_regs)) { - addr >>= 2; + addr >>= 2; - if (addr == PT_DCCR) { + if (addr == PT_DCCR) { /* don't allow the tracing process to change stuff like * interrupt enable, kernel/user bit, dma enables etc. */ - data &= DCCR_MASK; - data |= get_reg(child, PT_DCCR) & ~DCCR_MASK; - } - if (put_reg(child, addr, data)) - break; - ret = 0; + data &= DCCR_MASK; + data |= get_reg(child, PT_DCCR) & ~DCCR_MASK; } + if (put_reg(child, addr, data)) + break; + ret = 0; break; case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ Index: arch/cris/kernel/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/kernel/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/kernel/setup.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/kernel/setup.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,9 +1,8 @@ -/* $Id: setup.c,v 1.1 2004/07/22 19:49:09 joff 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"); } Index: arch/cris/kernel/shadows.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/kernel/shadows.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/kernel/shadows.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/kernel/shadows.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,6 +1,5 @@ -/* $Id: shadows.c,v 1.1 2004/07/22 19:49:09 joff 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 */ Index: arch/cris/kernel/signal.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/kernel/signal.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/kernel/signal.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/kernel/signal.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -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; Index: arch/cris/kernel/sys_cris.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/kernel/sys_cris.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/kernel/sys_cris.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/kernel/sys_cris.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,5 +1,4 @@ -/* $Id: sys_cris.c,v 1.1 2004/07/22 19:49:09 joff Exp $ - * +/* * linux/arch/cris/kernel/sys_cris.c * * This file contains various random system calls that @@ -110,7 +109,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: { @@ -164,7 +166,7 @@ return sys_shmctl (first, second, (struct shmid_ds *) ptr); default: - return -EINVAL; + return -ENOSYS; } } Index: arch/cris/kernel/time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/kernel/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/kernel/time.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/kernel/time.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,9 +1,8 @@ -/* $Id: time.c,v 1.1 2004/07/22 19:49:09 joff 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_DEBUG "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_DEBUG + "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 Index: arch/cris/kernel/traps.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/kernel/traps.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/kernel/traps.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/cris/kernel/traps.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,12 +1,11 @@ -/* $Id: traps.c,v 1.1 2004/07/22 19:49:09 joff 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; Index: arch/cris/lib/checksum.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/lib/checksum.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/lib/checksum.S 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/cris/lib/checksum.S 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,6 +1,6 @@ -/* $Id: checksum.S,v 1.1 2004/07/22 19:49:08 joff 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) */ Index: arch/cris/lib/checksumcopy.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/lib/checksumcopy.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/lib/checksumcopy.S 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/cris/lib/checksumcopy.S 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,9 +1,9 @@ -/* $Id: checksumcopy.S,v 1.1 2004/07/22 19:49:08 joff 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) */ Index: arch/cris/lib/dmacopy.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/lib/dmacopy.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/lib/dmacopy.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/cris/lib/dmacopy.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,5 +1,4 @@ -/* $Id: dmacopy.c,v 1.1 2004/07/22 19:49:08 joff 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")); } - - - Index: arch/cris/lib/dram_init.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/lib/dram_init.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/lib/dram_init.S 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/cris/lib/dram_init.S 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: dram_init.S,v 1.1 2004/07/22 19:49:08 joff Exp $ +/* $Id: dram_init.S,v 1.2 2004/08/04 01:25:40 joff Exp $ * * DRAM/SDRAM initialization - alter with care * This file is intended to be included from other assembler files @@ -11,8 +11,15 @@ * Authors: Mikael Starvik (starvik@axis.com) * * $Log: dram_init.S,v $ - * Revision 1.1 2004/07/22 19:49:08 joff - * Initial revision + * Revision 1.2 2004/08/04 01:25:40 joff + * merging 2.4.26-vrs1 + * + * Revision 1.15 2003/09/22 09:22:22 starvik + * Decompresser is linked to 0x407xxxxx and sdram commands are at 0x000xxxxx + * so we need to mask off 12 bits. + * + * 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 @@ -149,9 +156,9 @@ ; Issue initialization command sequence move.d _sdram_commands_start, $r2 - and.d 0x00ffffff, $r2 ; Make sure commands are read from flash + and.d 0x000fffff, $r2 ; Make sure commands are read from flash move.d _sdram_commands_end, $r3 - and.d 0x00ffffff, $r2 + and.d 0x000fffff, $r3 1: clear.d $r4 move.b [$r2+], $r4 lslq 9, $r4 ; Command starts at bit 9 Index: arch/cris/lib/hw_settings.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/lib/hw_settings.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/lib/hw_settings.S 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/cris/lib/hw_settings.S 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,13 +1,11 @@ /* - * $Id: hw_settings.S,v 1.1 2004/07/22 19:49:08 joff 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 Index: arch/cris/lib/old_checksum.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/lib/old_checksum.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/lib/old_checksum.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/cris/lib/old_checksum.c 4 Aug 2004 01:25:40 -0000 1.2 @@ -1,5 +1,4 @@ -/* $Id: old_checksum.c,v 1.1 2004/07/22 19:49:08 joff 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. Index: arch/cris/mm/extable.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/mm/extable.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/mm/extable.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/cris/mm/extable.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -2,8 +2,8 @@ * linux/arch/cris/mm/extable.c * * $Log: extable.c,v $ - * Revision 1.1 2004/07/22 19:49:08 joff - * Initial revision + * Revision 1.2 2004/08/04 01:25:41 joff + * merging 2.4.26-vrs1 * * Revision 1.4 2002/03/19 15:21:10 bjornw * Fixed warning Index: arch/cris/mm/fault.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/mm/fault.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/mm/fault.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/cris/mm/fault.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -6,8 +6,15 @@ * Authors: Bjorn Wesen * * $Log: fault.c,v $ - * Revision 1.1 2004/07/22 19:49:08 joff - * Initial revision + * Revision 1.2 2004/08/04 01:25:41 joff + * merging 2.4.26-vrs1 + * + * Revision 1.23 2003/10/16 05:32:32 starvik + * Only read TLB_SELECT if DEBUG + * + * 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 @@ -71,6 +78,7 @@ * */ +#include #include #include #include @@ -117,8 +125,9 @@ void handle_mmu_bus_fault(struct pt_regs *regs) { - int cause, select; + int cause; #ifdef DEBUG + int select; int index; int page_id; int acc, inv; @@ -129,12 +138,15 @@ 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; address = cause & PAGE_MASK; /* get faulting address */ #ifdef DEBUG + select = *R_TLB_SELECT; page_id = IO_EXTRACT(R_MMU_CAUSE, page_id, cause); acc = IO_EXTRACT(R_MMU_CAUSE, acc_excp, cause); inv = IO_EXTRACT(R_MMU_CAUSE, inv_excp, cause); Index: arch/cris/mm/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/mm/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/mm/init.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/cris/mm/init.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -7,8 +7,17 @@ * Authors: Bjorn Wesen (bjornw@axis.com) * * $Log: init.c,v $ - * Revision 1.1 2004/07/22 19:49:08 joff - * Initial revision + * Revision 1.2 2004/08/04 01:25:41 joff + * merging 2.4.26-vrs1 + * + * 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 @@ -116,6 +125,7 @@ #include #include #include +#include #include #include @@ -211,7 +221,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 */ @@ -407,7 +417,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), @@ -428,47 +439,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 @@ -484,7 +488,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; } @@ -527,7 +531,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 Index: arch/cris/mm/ioremap.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/cris/mm/ioremap.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/cris/mm/ioremap.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/cris/mm/ioremap.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -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.. Index: arch/i386/config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/config.in 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/i386/config.in 4 Aug 2004 01:25:41 -0000 1.2 @@ -202,6 +202,10 @@ tristate '/dev/cpu/*/msr - Model-specific register support' CONFIG_X86_MSR tristate '/dev/cpu/*/cpuid - CPU information support' CONFIG_X86_CPUID +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate 'BIOS Enhanced Disk Drive calls determine boot disk (EXPERIMENTAL)' CONFIG_EDD +fi + choice 'High Memory Support' \ "off CONFIG_NOHIGHMEM \ 4GB CONFIG_HIGHMEM4G \ @@ -232,6 +236,7 @@ define_bool CONFIG_X86_IO_APIC y fi else + int 'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32 bool 'Multi-node NUMA system support' CONFIG_X86_NUMA if [ "$CONFIG_X86_NUMA" = "y" ]; then #Platform Choices @@ -324,17 +329,10 @@ tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC +bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER 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 @@ -346,6 +344,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 @@ -372,7 +372,6 @@ 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 @@ -400,7 +399,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 @@ -483,6 +482,9 @@ bool ' Compile the kernel with frame pointers' CONFIG_FRAME_POINTER fi +int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 + endmenu +source crypto/Config.in source lib/Config.in Index: arch/i386/defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/defconfig 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/i386/defconfig 4 Aug 2004 01:25:41 -0000 1.2 @@ -2,7 +2,6 @@ # Automatically generated make config: don't edit # CONFIG_X86=y -CONFIG_ISA=y # CONFIG_SBUS is not set CONFIG_UID16=y @@ -31,12 +30,14 @@ # CONFIG_MPENTIUM4 is not set # CONFIG_MK6 is not set # CONFIG_MK7 is not set +# CONFIG_MK8 is not set # CONFIG_MELAN is not set # CONFIG_MCRUSOE is not set # CONFIG_MWINCHIPC6 is not set # CONFIG_MWINCHIP2 is not set # CONFIG_MWINCHIP3D is not set # CONFIG_MCYRIXIII is not set +# CONFIG_MVIAC3_2 is not set CONFIG_X86_WP_WORKS_OK=y CONFIG_X86_INVLPG=y CONFIG_X86_CMPXCHG=y @@ -46,10 +47,11 @@ # CONFIG_RWSEM_GENERIC_SPINLOCK is not set CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_X86_L1_CACHE_SHIFT=5 -CONFIG_X86_TSC=y +CONFIG_X86_HAS_TSC=y CONFIG_X86_GOOD_APIC=y CONFIG_X86_PGE=y CONFIG_X86_USE_PPRO_CHECKSUM=y +CONFIG_X86_F00F_WORKS_OK=y CONFIG_X86_MCE=y # CONFIG_TOSHIBA is not set # CONFIG_I8K is not set @@ -59,10 +61,14 @@ CONFIG_NOHIGHMEM=y # CONFIG_HIGHMEM4G is not set # CONFIG_HIGHMEM64G is not set +# CONFIG_HIGHMEM is not set # CONFIG_MATH_EMULATION is not set # CONFIG_MTRR is not set CONFIG_SMP=y -# CONFIG_MULTIQUAD is not set +CONFIG_NR_CPUS=32 +# CONFIG_X86_NUMA is not set +# CONFIG_X86_TSC_DISABLE is not set +CONFIG_X86_TSC=y CONFIG_HAVE_DEC_LOCK=y # @@ -77,6 +83,7 @@ CONFIG_PCI_GOANY=y CONFIG_PCI_BIOS=y CONFIG_PCI_DIRECT=y +CONFIG_ISA=y CONFIG_PCI_NAMES=y # CONFIG_EISA is not set # CONFIG_MCA is not set @@ -98,7 +105,6 @@ # CONFIG_HOTPLUG_PCI_COMPAQ is not set # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set # CONFIG_HOTPLUG_PCI_IBM is not set -# CONFIG_HOTPLUG_PCI_ACPI is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y @@ -107,10 +113,17 @@ CONFIG_BINFMT_AOUT=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=y +# CONFIG_OOM_KILLER is not set CONFIG_PM=y # CONFIG_APM is not set # +# ACPI Support +# +# CONFIG_ACPI is not set +CONFIG_ACPI_BOOT=y + +# # Memory Technology Devices (MTD) # # CONFIG_MTD is not set @@ -135,12 +148,14 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD 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) @@ -222,15 +237,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 is not set CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDETAPE is not set @@ -244,8 +250,8 @@ CONFIG_BLK_DEV_CMD640=y # CONFIG_BLK_DEV_CMD640_ENHANCED is not set # CONFIG_BLK_DEV_ISAPNP is not set -CONFIG_BLK_DEV_RZ1000=y 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_OFFBOARD is not set @@ -254,30 +260,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=y -CONFIG_PIIX_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=y +# 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 @@ -286,10 +291,10 @@ 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 @@ -324,12 +329,14 @@ # 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 # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -369,6 +376,7 @@ # 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 # # PCMCIA SCSI adapter support @@ -428,16 +436,19 @@ # 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 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 @@ -449,10 +460,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 @@ -464,10 +476,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 @@ -541,6 +555,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -582,13 +597,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 is not set +# CONFIG_SCx200_GPIO is not set # CONFIG_AMD_RNG is not set # CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_DTLK is not set @@ -604,9 +628,16 @@ CONFIG_AGP_I810=y CONFIG_AGP_VIA=y CONFIG_AGP_AMD=y +# CONFIG_AGP_AMD_K8 is not set CONFIG_AGP_SIS=y CONFIG_AGP_ALI=y # CONFIG_AGP_SWORKS is not set +# CONFIG_AGP_NVIDIA is not set +# CONFIG_AGP_ATI is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# CONFIG_DRM=y # CONFIG_DRM_OLD is not set @@ -615,10 +646,12 @@ # CONFIG_DRM_NEW=y CONFIG_DRM_TDFX=y +# CONFIG_DRM_GAMMA is not set # CONFIG_DRM_R128 is not set CONFIG_DRM_RADEON=y CONFIG_DRM_I810=y CONFIG_DRM_I810_XFREE_41=y +# CONFIG_DRM_I830 is not set # CONFIG_DRM_MGA is not set # CONFIG_DRM_SIS is not set @@ -626,7 +659,9 @@ # PCMCIA character devices # # CONFIG_PCMCIA_SERIAL_CS is not set +# CONFIG_SYNCLINK_CS is not set # CONFIG_MWAVE is not set +# CONFIG_OBMOUSE is not set # # Multimedia devices @@ -637,6 +672,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set CONFIG_AUTOFS4_FS=y # CONFIG_REISERFS_FS is not set @@ -646,6 +682,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 @@ -663,6 +702,9 @@ CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -682,6 +724,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -690,9 +737,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 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 @@ -706,7 +755,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 @@ -726,6 +774,7 @@ # 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 @@ -737,6 +786,7 @@ # 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 @@ -747,6 +797,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -759,7 +811,6 @@ # # CONFIG_USB_DEVICEFS is not set # CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_LONG_TIMEOUT is not set # # USB Host Controller Drivers @@ -767,13 +818,15 @@ # CONFIG_USB_EHCI_HCD is not set CONFIG_USB_UHCI_ALT=y # CONFIG_USB_OHCI is not set +# CONFIG_USB_SL811HS_ALT is not set +# CONFIG_USB_SL811HS is not set # # 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 @@ -782,6 +835,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 @@ -798,7 +852,10 @@ # 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 @@ -836,39 +893,20 @@ # 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 + +# +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set # # Bluetooth support @@ -879,3 +917,16 @@ # Kernel hacking # # CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_CRC32=y +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set Index: arch/i386/boot/bootsect.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/boot/bootsect.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/boot/bootsect.S 22 Jul 2004 19:49:03 -0000 1.1 +++ arch/i386/boot/bootsect.S 4 Aug 2004 01:25:41 -0000 1.2 @@ -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 Index: arch/i386/boot/setup.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/boot/setup.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/boot/setup.S 22 Jul 2004 19:49:03 -0000 1.1 +++ arch/i386/boot/setup.S 4 Aug 2004 01:25:41 -0000 1.2 @@ -45,6 +45,12 @@ * New A20 code ported from SYSLINUX by H. Peter Anvin. AMD Elan bugfixes * by Robert Schwebel, December 2001 * + * BIOS Enhanced Disk Drive support + * by Matt Domsch October 2002 + * conformant to T13 Committee www.t13.org + * projects 1572D, 1484D, 1386D, 1226DT + * disk signature read by Matt Domsch + * and Andrew Wilks September 2003 */ #include @@ -53,6 +59,7 @@ #include #include #include +#include #include /* Signature words to ensure LILO loaded us right */ @@ -543,6 +550,89 @@ done_apm_bios: #endif +#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) +# Read the first sector of device 80h and store the 4-byte signature + movl $0xFFFFFFFF, %eax + movl %eax, (DISK80_SIG_BUFFER) # assume failure + movb $READ_SECTORS, %ah + movb $1, %al # read 1 sector + movb $0x80, %dl # from device 80 + movb $0, %dh # at head 0 + movw $1, %cx # cylinder 0, sector 0 + pushw %es + pushw %ds + popw %es + movw $EDDBUF, %bx + int $0x13 + jc disk_sig_done + movl (EDDBUF+MBR_SIG_OFFSET), %eax + movl %eax, (DISK80_SIG_BUFFER) # store success +disk_sig_done: + popw %es + +# Do the BIOS Enhanced Disk Drive calls +# This consists of two calls: +# int 13h ah=41h "Check Extensions Present" +# int 13h ah=48h "Get Device Parameters" +# +# A buffer of size EDDMAXNR*(EDDEXTSIZE+EDDPARMSIZE) is reserved for our use +# in the empty_zero_page at EDDBUF. The first four bytes of which are +# used to store the device number, interface support map and version +# results from fn41. The following 74 bytes are used to store +# the results from fn48. Starting from device 80h, fn41, then fn48 +# are called and their results stored in EDDBUF+n*(EDDEXTSIZE+EDDPARMIZE). +# Then the pointer is incremented to store the data for the next call. +# This repeats until either a device doesn't exist, or until EDDMAXNR +# devices have been stored. +# The one tricky part is that ds:si always points four bytes into +# the structure, and the fn41 results are stored at offsets +# from there. This removes the need to increment the pointer for +# every store, and leaves it ready for the fn48 call. +# A second one-byte buffer, EDDNR, in the empty_zero_page stores +# the number of BIOS devices which exist, up to EDDMAXNR. +# In setup.c, copy_edd() stores both empty_zero_page buffers away +# for later use, as they would get overwritten otherwise. +# This code is sensitive to the size of the structs in edd.h +edd_start: + # %ds points to the bootsector + # result buffer for fn48 + movw $EDDBUF+EDDEXTSIZE, %si # in ds:si, fn41 results + # kept just before that + movb $0, (EDDNR) # zero value at EDDNR + movb $0x80, %dl # BIOS device 0x80 + +edd_check_ext: + movb $CHECKEXTENSIONSPRESENT, %ah # Function 41 + movw $EDDMAGIC1, %bx # magic + int $0x13 # make the call + jc edd_done # no more BIOS devices + + cmpw $EDDMAGIC2, %bx # is magic right? + jne edd_next # nope, next... + + movb %dl, %ds:-4(%si) # store device number + movb %ah, %ds:-3(%si) # store version + movw %cx, %ds:-2(%si) # store extensions + incb (EDDNR) # note that we stored something + +edd_get_device_params: + movw $EDDPARMSIZE, %ds:(%si) # put size + movb $GETDEVICEPARAMETERS, %ah # Function 48 + int $0x13 # make the call + # Don't check for fail return + # it doesn't matter. + movw %si, %ax # increment si + addw $EDDPARMSIZE+EDDEXTSIZE, %ax + movw %ax, %si + +edd_next: + incb %dl # increment to next device + cmpb $EDDMAXNR, (EDDNR) # Out of space? + jb edd_check_ext # keep looping + +edd_done: +#endif + # Now we want to move to protected mode ... cmpw $0, %cs:realmode_swtch jz rmodeswtch_normal Index: arch/i386/boot/compressed/misc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/boot/compressed/misc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/boot/compressed/misc.c 22 Jul 2004 19:49:03 -0000 1.1 +++ arch/i386/boot/compressed/misc.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -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; Index: arch/i386/boot/tools/build.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/boot/tools/build.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/boot/tools/build.c 22 Jul 2004 19:49:03 -0000 1.1 +++ arch/i386/boot/tools/build.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: build.c,v 1.1 2004/07/22 19:49:03 joff Exp $ + * $Id: build.c,v 1.2 2004/08/04 01:25:41 joff Exp $ * * Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 1997 Martin Mares Index: arch/i386/kernel/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/Makefile 22 Jul 2004 19:49:03 -0000 1.1 +++ arch/i386/kernel/Makefile 4 Aug 2004 01:25:41 -0000 1.2 @@ -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_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 +obj-$(CONFIG_EDD) += edd.o include $(TOPDIR)/Rules.make Index: arch/i386/kernel/acpitable.c =================================================================== RCS file: arch/i386/kernel/acpitable.c diff -N arch/i386/kernel/acpitable.c --- arch/i386/kernel/acpitable.c 22 Jul 2004 19:49:08 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,554 +0,0 @@ -/* - * acpitable.c - IA32-specific ACPI boot-time initialization (Revision: 1) - * - * 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 - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * $Id: acpitable.c,v 1.1 2004/07/22 19:49:08 joff Exp $ - */ -#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]; - - -static unsigned char __init -acpi_checksum(void *buffer, int length) -{ - int i; - unsigned char *bytebuffer; - unsigned char sum = 0; - - if (!buffer || length <= 0) - return 0; - - bytebuffer = (unsigned char *) buffer; - - for (i = 0; i < length; i++) - sum += *(bytebuffer++); - - return sum; -} - -static void __init -acpi_print_table_header(acpi_table_header * header) -{ - if (!header) - return; - - printk(KERN_INFO "ACPI table found: %.4s v%d [%.6s %.8s %d.%d]\n", - header->signature, header->revision, header->oem_id, - header->oem_table_id, header->oem_revision >> 16, - header->oem_revision & 0xffff); - - return; -} - -/******************************************************************************* - * - * FUNCTION: acpi_tb_scan_memory_for_rsdp - * - * PARAMETERS: address - Starting pointer for search - * length - Maximum length to search - * - * RETURN: Pointer to the RSDP if found and valid, otherwise NULL. - * - * DESCRIPTION: Search a block of memory for the RSDP signature - * - ******************************************************************************/ - -static void *__init -acpi_tb_scan_memory_for_rsdp(void *address, int length) -{ - u32 offset; - - if (length <= 0) - return NULL; - - /* Search from given start addr for the requested length */ - - offset = 0; - - while (offset < length) { - /* The signature must match and the checksum must be correct */ - if (strncmp(address, RSDP_SIG, sizeof(RSDP_SIG) - 1) == 0 && - acpi_checksum(address, RSDP_CHECKSUM_LENGTH) == 0) { - /* If so, we have found the RSDP */ - printk(KERN_INFO "ACPI: RSDP located at physical address %p\n", - address); - return address; - } - offset += RSDP_SCAN_STEP; - address += RSDP_SCAN_STEP; - } - - /* Searched entire block, no RSDP was found */ - printk(KERN_INFO "ACPI: Searched entire block, no RSDP was found.\n"); - return NULL; -} - -/******************************************************************************* - * - * FUNCTION: acpi_find_root_pointer - * - * PARAMETERS: none - * - * RETURN: physical address of the RSDP - * - * 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 - * BIOS Data Area or between E0000 and FFFFF (ACPI 1.0 section - * 5.2.2; assertion #421). - * - ******************************************************************************/ - -static struct acpi_table_rsdp * __init -acpi_find_root_pointer(void) -{ - struct acpi_table_rsdp * rsdp; - - /* - * Physical address is given - */ - /* - * Region 1) Search EBDA (low memory) paragraphs - */ - rsdp = acpi_tb_scan_memory_for_rsdp(__va(LO_RSDP_WINDOW_BASE), - LO_RSDP_WINDOW_SIZE); - - if (rsdp) - return rsdp; - - /* - * Region 2) Search upper memory: 16-byte boundaries in E0000h-F0000h - */ - rsdp = acpi_tb_scan_memory_for_rsdp(__va(HI_RSDP_WINDOW_BASE), - HI_RSDP_WINDOW_SIZE); - - - - if (rsdp) - return rsdp; - - printk(KERN_ERR "ACPI: System description tables not found\n"); - return NULL; -} - - -/* - * 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. - */ -static __init char * -__va_range(unsigned long phys, unsigned long size) -{ - unsigned long base, offset, mapped_size; - int idx; - - offset = phys & (PAGE_SIZE - 1); - mapped_size = PAGE_SIZE - offset; - set_fixmap(FIX_IO_APIC_BASE_END, phys); - base = fix_to_virt(FIX_IO_APIC_BASE_END); - dprintk("__va_range(0x%lx, 0x%lx): idx=%d mapped at %lx\n", phys, size, - FIX_IO_APIC_BASE_END, base); - - /* - * Most cases can be covered by the below. - */ - idx = FIX_IO_APIC_BASE_END; - while (mapped_size < size) { - if (--idx < FIX_IO_APIC_BASE_0) - return 0; /* cannot handle this */ - phys += PAGE_SIZE; - set_fixmap(idx, phys); - mapped_size += PAGE_SIZE; - } - - return ((unsigned char *) base + offset); -} - -static int __init acpi_tables_init(void) -{ - int result = -ENODEV; - acpi_table_header *header = NULL; - struct acpi_table_rsdp *rsdp = NULL; - struct acpi_table_rsdt *rsdt = NULL; - struct acpi_table_rsdt saved_rsdt; - int tables = 0; - int type = 0; - int i = 0; - - - rsdp = (struct acpi_table_rsdp *) acpi_find_root_pointer(); - - if (!rsdp) - return -ENODEV; - - printk(KERN_INFO "%.8s v%d [%.6s]\n", rsdp->signature, rsdp->revision, - rsdp->oem_id); - - if (strncmp(rsdp->signature, RSDP_SIG,strlen(RSDP_SIG))) { - printk(KERN_WARNING "RSDP table signature incorrect\n"); - return -EINVAL; - } - - rsdt = (struct acpi_table_rsdt *) - __va_range(rsdp->rsdt_address, sizeof(struct acpi_table_rsdt)); - - if (!rsdt) { - printk(KERN_WARNING "ACPI: Invalid root system description tables (RSDT)\n"); - return -ENODEV; - } - - header = & rsdt->header; - acpi_print_table_header(header); - - if (strncmp(header->signature, RSDT_SIG, strlen(RSDT_SIG))) { - printk(KERN_WARNING "ACPI: RSDT signature incorrect\n"); - return -ENODEV; - } - - /* - * The number of tables is computed by taking the - * size of all entries (header size minus total - * size of RSDT) divided by the size of each entry - * (4-byte table pointers). - */ - tables = (header->length - sizeof(acpi_table_header)) / 4; - - memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt)); - - if (saved_rsdt.header.length > sizeof(saved_rsdt)) { - printk(KERN_WARNING "ACPI: Too big length in RSDT: %d\n", saved_rsdt.header.length); - return -ENODEV; - } - - for (i = 0; i < tables; i++) { - /* Map in header, then map in full table length. */ - header = (acpi_table_header *) - __va_range(saved_rsdt.entry[i], - sizeof(acpi_table_header)); - if (!header) - break; - header = (acpi_table_header *) - __va_range(saved_rsdt.entry[i], header->length); - if (!header) - break; - - acpi_print_table_header(header); - - if (acpi_checksum(header,header->length)) { - printk(KERN_WARNING "ACPI %s has invalid checksum\n", - acpi_table_signatures[i]); - continue; - } - - for (type = 0; type < ACPI_TABLE_COUNT; type++) - if (!strncmp((char *) &header->signature, - acpi_table_signatures[type],strlen(acpi_table_signatures[type]))) - break; - - if (type >= ACPI_TABLE_COUNT) { - printk(KERN_WARNING "ACPI: Unsupported table %.4s\n", - header->signature); - continue; - } - - - if (!acpi_boot_ops[type]) - continue; - - result = acpi_boot_ops[type] (header, - (unsigned long) saved_rsdt. - entry[i]); - } - - return result; -} - -static int total_cpus __initdata = 0; -int have_acpi_tables; - -extern void __init MP_processor_info(struct mpc_config_processor *); - -static void __init -acpi_parse_lapic(struct acpi_table_lapic *local_apic) -{ - struct mpc_config_processor proc_entry; - int ix = 0; - - if (!local_apic) - return; - - printk(KERN_INFO "LAPIC (acpi_id[0x%04x] id[0x%x] enabled[%d])\n", - local_apic->acpi_id, local_apic->id, local_apic->flags.enabled); - - printk(KERN_INFO "CPU %d (0x%02x00)", total_cpus, local_apic->id); - - if (local_apic->flags.enabled) { - printk(" enabled"); - ix = local_apic->id; - if (ix >= MAX_APICS) { - printk(KERN_WARNING - "Processor #%d INVALID - (Max ID: %d).\n", ix, - MAX_APICS); - return; - } - /* - * Fill in the info we want to save. Not concerned about - * the processor ID. Processor features aren't present in - * the table. - */ - proc_entry.mpc_type = MP_PROCESSOR; - proc_entry.mpc_apicid = local_apic->id; - proc_entry.mpc_cpuflag = CPU_ENABLED; - if (proc_entry.mpc_apicid == boot_cpu_physical_apicid) { - printk(" (BSP)"); - proc_entry.mpc_cpuflag |= CPU_BOOTPROCESSOR; - } - proc_entry.mpc_cpufeature = - (boot_cpu_data.x86 << 8) | - (boot_cpu_data.x86_model << 4) | - boot_cpu_data.x86_mask; - proc_entry.mpc_featureflag = boot_cpu_data.x86_capability[0]; - proc_entry.mpc_reserved[0] = 0; - proc_entry.mpc_reserved[1] = 0; - proc_entry.mpc_apicver = 0x10; /* integrated APIC */ - MP_processor_info(&proc_entry); - } else { - printk(" disabled"); - } - printk("\n"); - - total_cpus++; - return; -} - -static void __init -acpi_parse_ioapic(struct acpi_table_ioapic *ioapic) -{ - - if (!ioapic) - return; - - printk(KERN_INFO - "IOAPIC (id[0x%x] address[0x%x] global_irq_base[0x%x])\n", - ioapic->id, ioapic->address, ioapic->global_irq_base); - - if (nr_ioapics >= MAX_IO_APICS) { - printk(KERN_WARNING - "Max # of I/O APICs (%d) exceeded (found %d).\n", - MAX_IO_APICS, nr_ioapics); -/* panic("Recompile kernel with bigger MAX_IO_APICS!\n"); */ - } -} - - -/* Interrupt source overrides inform the machine about exceptions - to the normal "PIC" mode interrupt routing */ - -static void __init -acpi_parse_int_src_ovr(struct acpi_table_int_src_ovr *intsrc) -{ - if (!intsrc) - return; - - printk(KERN_INFO - "INT_SRC_OVR (bus[%d] irq[0x%x] global_irq[0x%x] polarity[0x%x] trigger[0x%x])\n", - intsrc->bus, intsrc->bus_irq, intsrc->global_irq, - intsrc->flags.polarity, intsrc->flags.trigger); -} - -/* - * At this point, we look at the interrupt assignment entries in the MPS - * table. - */ - -static void __init acpi_parse_nmi_src(struct acpi_table_nmi_src *nmisrc) -{ - if (!nmisrc) - return; - - printk(KERN_INFO - "NMI_SRC (polarity[0x%x] trigger[0x%x] global_irq[0x%x])\n", - nmisrc->flags.polarity, nmisrc->flags.trigger, - nmisrc->global_irq); - -} -static void __init -acpi_parse_lapic_nmi(struct acpi_table_lapic_nmi *localnmi) -{ - if (!localnmi) - return; - - printk(KERN_INFO - "LAPIC_NMI (acpi_id[0x%04x] polarity[0x%x] trigger[0x%x] lint[0x%x])\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) -{ - if (!lapic_addr_ovr) - return; - - printk(KERN_INFO "LAPIC_ADDR_OVR (address[0x%lx])\n", - (unsigned long) lapic_addr_ovr->address); - -} - -static void __init -acpi_parse_plat_int_src(struct acpi_table_plat_int_src *plintsrc) -{ - if (!plintsrc) - return; - - printk(KERN_INFO - "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", - plintsrc->flags.polarity, plintsrc->flags.trigger, - plintsrc->type, plintsrc->id, plintsrc->eid, - plintsrc->iosapic_vector, plintsrc->global_irq); -} -static int __init -acpi_parse_madt(acpi_table_header * header, unsigned long phys) -{ - - struct acpi_table_madt *madt; - acpi_madt_entry_header *entry_header; - int table_size; - - madt = (struct acpi_table_madt *) __va_range(phys, header->length); - - if (!madt) - return -EINVAL; - - table_size = (int) (header->length - sizeof(*madt)); - entry_header = - (acpi_madt_entry_header *) ((void *) madt + sizeof(*madt)); - - while (entry_header && (table_size > 0)) { - switch (entry_header->type) { - case ACPI_MADT_LAPIC: - acpi_parse_lapic((struct acpi_table_lapic *) - entry_header); - break; - case ACPI_MADT_IOAPIC: - acpi_parse_ioapic((struct acpi_table_ioapic *) - entry_header); - break; - case ACPI_MADT_INT_SRC_OVR: - acpi_parse_int_src_ovr((struct acpi_table_int_src_ovr *) - entry_header); - break; - case ACPI_MADT_NMI_SRC: - acpi_parse_nmi_src((struct acpi_table_nmi_src *) - entry_header); - break; - case ACPI_MADT_LAPIC_NMI: - acpi_parse_lapic_nmi((struct acpi_table_lapic_nmi *) - entry_header); - break; - case ACPI_MADT_LAPIC_ADDR_OVR: - acpi_parse_lapic_addr_ovr((struct - acpi_table_lapic_addr_ovr *) - entry_header); - break; - case ACPI_MADT_PLAT_INT_SRC: - acpi_parse_plat_int_src((struct acpi_table_plat_int_src - *) entry_header); - break; - default: - printk(KERN_WARNING - "Unsupported MADT entry type 0x%x\n", - entry_header->type); - break; - } - table_size -= entry_header->length; - entry_header = - (acpi_madt_entry_header *) ((void *) entry_header + - entry_header->length); - } - - if (!total_cpus) { - printk("ACPI: No Processors found in the APCI table.\n"); - return -EINVAL; - } - - printk(KERN_INFO "%d CPUs total\n", total_cpus); - - if (madt->lapic_address) - mp_lapic_addr = madt->lapic_address; - else - mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; - - printk(KERN_INFO "Local APIC address %x\n", madt->lapic_address); - - 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) -{ - - memset(&acpi_boot_ops, 0, sizeof(acpi_boot_ops)); - acpi_boot_ops[ACPI_APIC] = acpi_parse_madt; - - /* - * 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"); - } -} Index: arch/i386/kernel/acpitable.h =================================================================== RCS file: arch/i386/kernel/acpitable.h diff -N arch/i386/kernel/acpitable.h --- arch/i386/kernel/acpitable.h 22 Jul 2004 19:49:08 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,260 +0,0 @@ -/* - * acpitable.c - IA32-specific ACPI boot-time initialization (Revision: 1) - * - * 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 - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * $Id: acpitable.h,v 1.1 2004/07/22 19:49:08 joff Exp $ - */ - -/* - * The following codes are cut&pasted from drivers/acpi. Part of the code - * there can be not updated or delivered yet. - * To avoid conflicts when CONFIG_ACPI is defined, the following codes are - * modified so that they are self-contained in this file. - * -- jun - */ - -#ifndef _HEADER_ACPITABLE_H_ -#define _HEADER_ACPITABLE_H_ - -#define dprintk printk -typedef unsigned int ACPI_TBLPTR; - -typedef struct { /* ACPI common table header */ - 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 */ - char oem_id[6]; /* OEM identification */ - char oem_table_id[8]; /* OEM table identification */ - u32 oem_revision; /* OEM revision number */ - char asl_compiler_id[4]; /* ASL compiler vendor ID */ - u32 asl_compiler_revision; /* ASL compiler revision number */ -} acpi_table_header __attribute__ ((packed));; - -enum { - ACPI_APIC = 0, - ACPI_BOOT, - ACPI_DBGP, - ACPI_DSDT, - ACPI_ECDT, - ACPI_ETDT, - ACPI_FACP, - ACPI_FACS, - ACPI_OEMX, - ACPI_PSDT, - ACPI_SBST, - ACPI_SLIT, - ACPI_SPCR, - ACPI_SRAT, - ACPI_SSDT, - ACPI_SPMI, - ACPI_XSDT, - ACPI_TABLE_COUNT -}; - -static char *acpi_table_signatures[ACPI_TABLE_COUNT] = { - "APIC", - "BOOT", - "DBGP", - "DSDT", - "ECDT", - "ETDT", - "FACP", - "FACS", - "OEM", - "PSDT", - "SBST", - "SLIT", - "SPCR", - "SRAT", - "SSDT", - "SPMI", - "XSDT" -}; - -struct acpi_table_madt { - acpi_table_header header; - u32 lapic_address; - struct { - u32 pcat_compat:1; - u32 reserved:31; - } flags __attribute__ ((packed)); -} __attribute__ ((packed));; - -enum { - ACPI_MADT_LAPIC = 0, - ACPI_MADT_IOAPIC, - ACPI_MADT_INT_SRC_OVR, - ACPI_MADT_NMI_SRC, - ACPI_MADT_LAPIC_NMI, - ACPI_MADT_LAPIC_ADDR_OVR, - ACPI_MADT_IOSAPIC, - ACPI_MADT_LSAPIC, - ACPI_MADT_PLAT_INT_SRC, - ACPI_MADT_ENTRY_COUNT -}; - -#define RSDP_SIG "RSD PTR " -#define RSDT_SIG "RSDT" - -#define ACPI_DEBUG_PRINT(pl) - -#define ACPI_MEMORY_MODE 0x01 -#define ACPI_LOGICAL_ADDRESSING 0x00 -#define ACPI_PHYSICAL_ADDRESSING 0x01 - -#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 -#define RSDP_CHECKSUM_LENGTH 20 - -typedef int (*acpi_table_handler) (acpi_table_header * header, unsigned long); - -struct acpi_table_rsdp { - char signature[8]; - u8 checksum; - char oem_id[6]; - u8 revision; - u32 rsdt_address; -} __attribute__ ((packed)); - -struct acpi_table_rsdt { - acpi_table_header header; - u32 entry[ACPI_TABLE_COUNT]; -} __attribute__ ((packed)); - -typedef struct { - u8 type; - u8 length; -} acpi_madt_entry_header __attribute__ ((packed)); - -typedef struct { - u16 polarity:2; - u16 trigger:2; - u16 reserved:12; -} acpi_madt_int_flags __attribute__ ((packed)); - -struct acpi_table_lapic { - acpi_madt_entry_header header; - u8 acpi_id; - u8 id; - struct { - u32 enabled:1; - u32 reserved:31; - } flags __attribute__ ((packed)); -} __attribute__ ((packed)); - -struct acpi_table_ioapic { - acpi_madt_entry_header header; - u8 id; - u8 reserved; - u32 address; - u32 global_irq_base; -} __attribute__ ((packed)); - -struct acpi_table_int_src_ovr { - acpi_madt_entry_header header; - u8 bus; - u8 bus_irq; - u32 global_irq; - acpi_madt_int_flags flags; -} __attribute__ ((packed)); - -struct acpi_table_nmi_src { - acpi_madt_entry_header header; - acpi_madt_int_flags flags; - u32 global_irq; -} __attribute__ ((packed)); - -struct acpi_table_lapic_nmi { - acpi_madt_entry_header header; - u8 acpi_id; - acpi_madt_int_flags flags; - u8 lint; -} __attribute__ ((packed)); - -struct acpi_table_lapic_addr_ovr { - acpi_madt_entry_header header; - u8 reserved[2]; - u64 address; -} __attribute__ ((packed)); - -struct acpi_table_iosapic { - acpi_madt_entry_header header; - u8 id; - u8 reserved; - u32 global_irq_base; - u64 address; -} __attribute__ ((packed)); - -struct acpi_table_lsapic { - acpi_madt_entry_header header; - u8 acpi_id; - u8 id; - u8 eid; - u8 reserved[3]; - struct { - u32 enabled:1; - u32 reserved:31; - } flags; -} __attribute__ ((packed)); - -struct acpi_table_plat_int_src { - acpi_madt_entry_header header; - acpi_madt_int_flags flags; - u8 type; - u8 id; - u8 eid; - u8 iosapic_vector; - u32 global_irq; - u32 reserved; -} __attribute__ ((packed)); - -/* - * 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_pointer; - u64 physical_address; - u32 aml_length; - u32 length; - u32 count; - u16 table_id; - u8 type; - u8 allocation; - u8 loaded_into_namespace; - -} acpi_table_desc __attribute__ ((packed));; - -#endif Index: arch/i386/kernel/apic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/apic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/apic.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/i386/kernel/apic.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -38,6 +38,8 @@ int prof_old_multiplier[NR_CPUS] = { 1, }; int prof_counter[NR_CPUS] = { 1, }; +static int enabled_via_apicbase; + int get_maxlvt(void) { unsigned int v, ver, maxlvt; @@ -142,6 +144,13 @@ value = apic_read(APIC_SPIV); value &= ~APIC_SPIV_APIC_ENABLED; apic_write_around(APIC_SPIV, value); + + if (enabled_via_apicbase) { + unsigned int l, h; + rdmsr(MSR_IA32_APICBASE, l, h); + l &= ~MSR_IA32_APICBASE_ENABLE; + wrmsr(MSR_IA32_APICBASE, l, h); + } } /* @@ -464,7 +473,6 @@ static void apic_pm_suspend(void *data) { - unsigned int l, h; unsigned long flags; if (apic_pm_state.perfctr_pmdev) @@ -484,9 +492,6 @@ __save_flags(flags); __cli(); disable_local_APIC(); - rdmsr(MSR_IA32_APICBASE, l, h); - l &= ~MSR_IA32_APICBASE_ENABLE; - wrmsr(MSR_IA32_APICBASE, l, h); __restore_flags(flags); } @@ -497,10 +502,18 @@ __save_flags(flags); __cli(); + + /* + * Make sure the APICBASE points to the right address + * + * FIXME! This will be wrong if we ever support suspend on + * SMP! We'll need to do this as part of the CPU restore! + */ rdmsr(MSR_IA32_APICBASE, l, h); l &= ~MSR_IA32_APICBASE_BASE; - l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE; + l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; wrmsr(MSR_IA32_APICBASE, l, h); + apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED); apic_write(APIC_ID, apic_pm_state.apic_id); apic_write(APIC_DFR, apic_pm_state.apic_dfr); @@ -593,7 +606,26 @@ * Detect and enable local APICs on non-SMP boards. * Original code written by Keir Fraser. */ -int dont_enable_local_apic __initdata = 0; + +/* + * Knob to control our willingness to enable the local APIC. + */ +int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ + +static int __init lapic_disable(char *str) +{ + enable_local_apic = -1; + clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); + return 0; +} +__setup("nolapic", lapic_disable); + +static int __init lapic_enable(char *str) +{ + enable_local_apic = 1; + return 0; +} +__setup("lapic", lapic_enable); static int __init detect_init_APIC (void) { @@ -601,7 +633,7 @@ extern void get_cpu_vendor(struct cpuinfo_x86*); /* Disabled by DMI scan or kernel option? */ - if (dont_enable_local_apic) + if (enable_local_apic < 0) return -1; /* Workaround for us being called before identify_cpu(). */ @@ -616,7 +648,7 @@ 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 == 15 && (cpu_has_apic || enable_local_apic > 0)) || (boot_cpu_data.x86 == 5 && cpu_has_apic)) break; goto no_apic; @@ -636,6 +668,7 @@ l &= ~MSR_IA32_APICBASE_BASE; l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE; wrmsr(MSR_IA32_APICBASE, l, h); + enabled_via_apicbase = 1; } } /* @@ -649,6 +682,12 @@ } set_bit(X86_FEATURE_APIC, &boot_cpu_data.x86_capability); mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; + + /* The BIOS may have set up the APIC at some other address */ + rdmsr(MSR_IA32_APICBASE, l, h); + if (l & MSR_IA32_APICBASE_ENABLE) + mp_lapic_addr = l & MSR_IA32_APICBASE_BASE; + if (nmi_watchdog != NMI_NONE) nmi_watchdog = NMI_LOCAL_APIC; @@ -928,14 +967,8 @@ static unsigned int calibration_result; -int dont_use_local_apic_timer __initdata = 0; - void __init setup_APIC_clocks (void) { - /* Disabled by DMI scan or kernel option? */ - if (dont_use_local_apic_timer) - return; - printk("Using local APIC timer interrupts.\n"); using_apic_timer = 1; @@ -1152,6 +1185,9 @@ */ int __init APIC_init_uniprocessor (void) { + if (enable_local_apic < 0) + clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); + if (!smp_found_config && !cpu_has_apic) return -1; Index: arch/i386/kernel/apm.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/apm.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/apm.c 22 Jul 2004 19:49:03 -0000 1.1 +++ arch/i386/kernel/apm.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -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; } Index: arch/i386/kernel/cpuid.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/cpuid.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/cpuid.c 22 Jul 2004 19:49:03 -0000 1.1 +++ arch/i386/kernel/cpuid.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -1,4 +1,4 @@ -#ident "$Id: cpuid.c,v 1.1 2004/07/22 19:49:03 joff Exp $" +#ident "$Id: cpuid.c,v 1.2 2004/08/04 01:25:41 joff Exp $" /* ----------------------------------------------------------------------- * * * Copyright 2000 H. Peter Anvin - All Rights Reserved Index: arch/i386/kernel/dmi_scan.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/dmi_scan.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/dmi_scan.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/i386/kernel/dmi_scan.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -23,8 +24,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,57 +301,46 @@ return 0; } -/* - * Some machines, usually laptops, can't handle an enabled local APIC. - * The symptoms include hangs or reboots when suspending or resuming, - * attaching or detaching the power cord, or entering BIOS setup screens - * through magic key sequences. - */ -static int __init local_apic_kills_bios(struct dmi_blacklist *d) +static __init int apm_is_horked_d850md(struct dmi_blacklist *d) { -#ifdef CONFIG_X86_LOCAL_APIC - extern int dont_enable_local_apic; - if (!dont_enable_local_apic) { - dont_enable_local_apic = 1; - printk(KERN_WARNING "%s with broken BIOS detected. " - "Refusing to enable the local APIC.\n", - d->ident); + 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"); } -#endif return 0; } -/* - * The Microstar 6163-2 (a.k.a Pro) mainboard will hang shortly after - * resumes, and also at what appears to be asynchronous APM events, - * if the local APIC is enabled. +/* + * Some APM bioses hang on APM idle calls */ -static int __init apm_kills_local_apic(struct dmi_blacklist *d) + +static __init int apm_likes_to_melt(struct dmi_blacklist *d) { -#ifdef CONFIG_X86_LOCAL_APIC - extern int dont_enable_local_apic; - if (apm_info.bios.version && !dont_enable_local_apic) { - dont_enable_local_apic = 1; - printk(KERN_WARNING "%s with broken BIOS detected. " - "Refusing to enable the local APIC.\n", - d->ident); + if (apm_info.forbid_idle == 0) + { + apm_info.forbid_idle = 1; + printk(KERN_INFO "%s machine detected. Disabling APM idle calls.\n", d->ident); } -#endif return 0; } /* - * The Intel AL440LX mainboard will hang randomly if the local APIC - * timer is running and the APM BIOS hasn't been disabled. + * Some machines, usually laptops, can't handle an enabled local APIC. + * The symptoms include hangs or reboots when suspending or resuming, + * attaching or detaching the power cord, or entering BIOS setup screens + * through magic key sequences. */ -static int __init apm_kills_local_apic_timer(struct dmi_blacklist *d) +static int __init local_apic_kills_bios(struct dmi_blacklist *d) { #ifdef CONFIG_X86_LOCAL_APIC - extern int dont_use_local_apic_timer; - if (apm_info.bios.version && !dont_use_local_apic_timer) { - dont_use_local_apic_timer = 1; + extern int enable_local_apic; + if (enable_local_apic == 0) { + enable_local_apic = -1; printk(KERN_WARNING "%s with broken BIOS detected. " - "The local APIC timer will not be used.\n", + "Refusing to enable the local APIC.\n", d->ident); } #endif @@ -408,30 +401,13 @@ } /* - * The Intel 440GX hall of shame. - * - * On many (all we have checked) of these boxes the $PIRQ table is wrong. - * The MP1.4 table is right however and so SMP kernels tend to work. + * ASUS K7V-RM has broken ACPI table defining sleep modes */ - -extern int skip_ioapic_setup; -extern int broken_440gx_bios; -extern unsigned int pci_probe; -static __init int broken_pirq(struct dmi_blacklist *d) -{ - printk(KERN_INFO " *** Possibly defective BIOS detected (irqtable)\n"); - printk(KERN_INFO " *** Many BIOSes matching this signature have incorrect IRQ routing tables.\n"); - printk(KERN_INFO " *** If you see IRQ problems, in paticular SCSI resets and hangs at boot\n"); - 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; -#endif -#ifdef CONFIG_PCI - broken_440gx_bios = 1; - pci_probe |= PCI_BIOS_IRQ_SCAN; -#endif - + +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 +459,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 +480,49 @@ return 0; } + +#ifdef CONFIG_ACPI_BOOT +extern int acpi_force; + +static __init __attribute__((unused)) int dmi_disable_acpi(struct dmi_blacklist *d) +{ + if (!acpi_force) { + printk(KERN_NOTICE "%s detected: acpi off\n",d->ident); + disable_acpi(); + } 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); + disable_acpi(); + acpi_ht = 1; + } else { + printk(KERN_NOTICE + "Warning: acpi=force overrules DMI blacklist: acpi=ht\n"); + } + return 0; +} +#endif /* CONFIG_ACPI_BOOT */ + +#ifdef CONFIG_ACPI_PCI +static __init int disable_acpi_pci(struct dmi_blacklist *d) +{ + printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", d->ident); + acpi_noirq_set(); + return 0; +} +#endif /* CONFIG_ACPI_PCI */ + /* * Process the DMI blacklists */ @@ -508,17 +539,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 +600,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 +616,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 +631,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 +659,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 +769,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", { @@ -712,56 +796,17 @@ NO_MATCH, NO_MATCH } }, - { apm_kills_local_apic, "Microstar 6163", { - MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), - MATCH(DMI_BOARD_NAME, "MS-6163"), - NO_MATCH, NO_MATCH } }, - - { apm_kills_local_apic_timer, "Intel AL440LX", { - MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), - MATCH(DMI_BOARD_NAME, "AL440LX"), - NO_MATCH, NO_MATCH } }, - - /* Problem Intel 440GX bioses */ - - { broken_pirq, "SABR1 Bios", { /* Bad $PIR */ - MATCH(DMI_BIOS_VENDOR, "Intel Corporation"), - MATCH(DMI_BIOS_VERSION,"SABR1"), - 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.0120.P12"), - NO_MATCH, NO_MATCH - } }, - { broken_pirq, "l44GX Bios", { /* Bad $PIR */ - MATCH(DMI_BIOS_VENDOR, "Intel Corporation"), - MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0125.P13"), - NO_MATCH, NO_MATCH - } }, - { broken_pirq, "l44GX Bios", { /* Bad $PIR */ - MATCH(DMI_BIOS_VENDOR, "Intel Corporation"), - MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0066.P07.9906041405"), - NO_MATCH, NO_MATCH - } }, - - /* Intel in disgiuse - In this case they can't hide and they don't run - too well either... */ - { broken_pirq, "Dell PowerEdge 8450", { /* Bad $PIR */ - MATCH(DMI_PRODUCT_NAME, "Dell PowerEdge 8450"), - NO_MATCH, 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 } }, + { 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 + } }, + { print_if_true, KERN_WARNING "IBM T23 - BIOS 1.03b+ and controller firmware 1.02+ may be needed for Linux APM.", { MATCH(DMI_SYS_VENDOR, "IBM"), MATCH(DMI_BIOS_VERSION, "1AET38WW (1.01b)"), @@ -774,7 +819,6 @@ MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook Model GE"), MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736") } }, - /* * Generic per vendor APM settings @@ -785,6 +829,114 @@ 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 + */ + + { dmi_disable_acpi, "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, "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 }}, + +#endif /* CONFIG_ACPI_BOOT */ +#ifdef CONFIG_ACPI_PCI + /* + * Boxes that need ACPI PCI IRQ routing disabled + */ + + { disable_acpi_pci, "ASUS A7V", { + MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"), + MATCH(DMI_BOARD_NAME, ""), + /* newer BIOS, Revision 1011, does work */ + MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"), + NO_MATCH }}, +#endif /* CONFIG_ACPI_PCI */ + { NULL, } }; @@ -794,11 +946,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"); + disable_acpi(); + } + } + } +#endif + d=&dmi_blacklist[0]; while(d->callback) { @@ -829,8 +1004,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 +1052,7 @@ int err = dmi_iterate(dmi_decode); if(err == 0) dmi_check_blacklist(); + else + printk(KERN_INFO "DMI not present.\n"); } + Index: arch/i386/kernel/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/head.S 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/i386/kernel/head.S 4 Aug 2004 01:25:41 -0000 1.2 @@ -34,7 +34,7 @@ #define X86_HARD_MATH CPU_PARAMS+6 #define X86_CPUID CPU_PARAMS+8 #define X86_CAPABILITY CPU_PARAMS+12 -#define X86_VENDOR_ID CPU_PARAMS+28 +#define X86_VENDOR_ID CPU_PARAMS+36 /* tied to NCAPINTS in cpufeature.h */ /* * swapper_pg_dir is the main page directory, address 0x00101000 @@ -113,7 +113,7 @@ popfl jmp checkCPUtype 1: -#endif CONFIG_SMP +#endif /* CONFIG_SMP */ /* * Clear BSS first so that there are no surprises... Index: arch/i386/kernel/i386_ksyms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/i386_ksyms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/i386_ksyms.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/i386/kernel/i386_ksyms.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -28,6 +28,7 @@ #include #include #include +#include extern void dump_thread(struct pt_regs *, struct user *); extern spinlock_t rtc_lock; @@ -145,6 +146,10 @@ /* TLB flushing */ EXPORT_SYMBOL(flush_tlb_page); + +/* HT support */ +EXPORT_SYMBOL(smp_num_siblings); +EXPORT_SYMBOL(cpu_sibling_map); #endif #ifdef CONFIG_X86_IO_APIC @@ -180,3 +185,9 @@ #ifdef CONFIG_MULTIQUAD EXPORT_SYMBOL(xquad_portio); #endif + +#ifdef CONFIG_EDD_MODULE +EXPORT_SYMBOL(edd); +EXPORT_SYMBOL(eddnr); +EXPORT_SYMBOL(edd_disk80_sig); +#endif Index: arch/i386/kernel/i387.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/i387.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/i387.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/i386/kernel/i387.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -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 ) Index: arch/i386/kernel/io_apic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/io_apic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/io_apic.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/i386/kernel/io_apic.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -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; \ @@ -167,6 +169,14 @@ { struct IO_APIC_route_entry entry; unsigned long flags; + + /* Check delivery_mode to be sure we're not clearing an SMI pin */ + spin_lock_irqsave(&ioapic_lock, flags); + *(((int*)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin); + *(((int*)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin); + spin_unlock_irqrestore(&ioapic_lock, flags); + if (entry.delivery_mode == dest_SMI) + return; /* * Disable it in the IO-APIC irq-routing table: @@ -750,6 +760,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 +781,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 +820,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" @@ -1316,9 +1347,35 @@ 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; + + /* pick a single cpu for clustered xapics */ + if(clustered_apic_mode == CLUSTERED_APIC_XAPIC){ + int cpu = ffs(mask)-1; + mask = cpu_to_physical_apicid(cpu); + } + /* * Only the first 8 bits are valid. */ @@ -1657,13 +1714,185 @@ 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(); + if (!acpi_ioapic) + setup_ioapic_ids_from_mpc(); sync_Arb_IDs(); setup_IO_APIC_irqs(); init_IO_APIC_traps(); check_timer(); - print_IO_APIC(); + if (!acpi_ioapic) + 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; + + /* + * IRQs < 16 are already in the irq_2_pin[] map + */ + if (irq >= 16) + 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*/ Index: arch/i386/kernel/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/irq.c 22 Jul 2004 19:49:03 -0000 1.1 +++ arch/i386/kernel/irq.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -131,55 +132,55 @@ * Generic, controller-independent functions: */ -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { int i, j; struct irqaction * action; - char *p = buf; - p += sprintf(p, " "); + seq_printf(p, " "); for (j=0; jtypename); - p += sprintf(p, " %s", action->name); + seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) - p += sprintf(p, ", %s", action->name); - *p++ = '\n'; + seq_printf(p, ", %s", action->name); + seq_putc(p,'\n'); } - p += sprintf(p, "NMI: "); + seq_printf(p, "NMI: "); for (j = 0; j < smp_num_cpus; j++) - p += sprintf(p, "%10u ", + seq_printf(p, "%10u ", nmi_count(cpu_logical_map(j))); - p += sprintf(p, "\n"); + seq_printf(p, "\n"); #if CONFIG_X86_LOCAL_APIC - p += sprintf(p, "LOC: "); + seq_printf(p, "LOC: "); for (j = 0; j < smp_num_cpus; j++) - p += sprintf(p, "%10u ", + seq_printf(p, "%10u ", apic_timer_irqs[cpu_logical_map(j)]); - p += sprintf(p, "\n"); + seq_printf(p, "\n"); #endif - p += sprintf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); + seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); #ifdef CONFIG_X86_IO_APIC #ifdef APIC_MISMATCH_DEBUG - p += sprintf(p, "MIS: %10u\n", atomic_read(&irq_mis_count)); + seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count)); #endif #endif - return p - buf; + + return 0; } @@ -1035,7 +1036,7 @@ if (!shared) { desc->depth = 0; - desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING); + desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS); desc->handler->startup(irq); } spin_unlock_irqrestore(&desc->lock,flags); Index: arch/i386/kernel/ldt.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/ldt.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/ldt.c 22 Jul 2004 19:49:03 -0000 1.1 +++ arch/i386/kernel/ldt.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -12,37 +12,139 @@ #include #include #include +#include #include #include #include #include +#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */ +static void flush_ldt(void *mm) +{ + if (current->active_mm) + load_LDT(¤t->active_mm->context); +} +#endif + +static int alloc_ldt(mm_context_t *pc, int mincount, int reload) +{ + void *oldldt; + void *newldt; + int oldsize; + + if (mincount <= pc->size) + return 0; + oldsize = pc->size; + mincount = (mincount+511)&(~511); + if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE) + newldt = vmalloc(mincount*LDT_ENTRY_SIZE); + else + newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL); + + if (!newldt) + return -ENOMEM; + + if (oldsize) + memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE); + + oldldt = pc->ldt; + memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE); + wmb(); + pc->ldt = newldt; + pc->size = mincount; + if (reload) { + load_LDT(pc); +#ifdef CONFIG_SMP + if (current->mm->cpu_vm_mask != (1< PAGE_SIZE) + vfree(oldldt); + else + kfree(oldldt); + } + return 0; +} + +static inline int copy_ldt(mm_context_t *new, mm_context_t *old) +{ + int err = alloc_ldt(new, old->size, 0); + if (err < 0) { + printk(KERN_WARNING "ldt allocation failed\n"); + new->size = 0; + return err; + } + memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE); + return 0; +} + +/* + * we do not have to muck with descriptors here, that is + * done in switch_mm() as needed. + */ +int init_new_context(struct task_struct *tsk, struct mm_struct *mm) +{ + struct mm_struct * old_mm; + int retval = 0; + + init_MUTEX(&mm->context.sem); + mm->context.size = 0; + old_mm = current->mm; + if (old_mm && old_mm->context.size > 0) { + down(&old_mm->context.sem); + retval = copy_ldt(&mm->context, &old_mm->context); + up(&old_mm->context.sem); + } + return retval; +} + /* - * read_ldt() is not really atomic - this is not a problem since - * synchronization of reads and writes done to the LDT has to be - * assured by user-space anyway. Writes are atomic, to protect - * the security checks done on new descriptors. + * No need to lock the MM as we are the last user + * Do not touch the ldt register, we are already + * in the next thread. */ +void destroy_context(struct mm_struct *mm) +{ + if (mm->context.size) { + if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE) + vfree(mm->context.ldt); + else + kfree(mm->context.ldt); + mm->context.size = 0; + } +} + static int read_ldt(void * ptr, unsigned long bytecount) { int err; unsigned long size; struct mm_struct * mm = current->mm; - err = 0; - if (!mm->context.segments) - goto out; + if (!mm->context.size) + return 0; + if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES) + bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES; - size = LDT_ENTRIES*LDT_ENTRY_SIZE; + down(&mm->context.sem); + size = mm->context.size*LDT_ENTRY_SIZE; if (size > bytecount) size = bytecount; - err = size; - if (copy_to_user(ptr, mm->context.segments, size)) + err = 0; + if (copy_to_user(ptr, mm->context.ldt, size)) err = -EFAULT; -out: - return err; + up(&mm->context.sem); + if (err < 0) + return err; + if (size != bytecount) { + /* zero-fill the rest */ + clear_user(ptr+size, bytecount-size); + } + return bytecount; } static int read_default_ldt(void * ptr, unsigned long bytecount) @@ -53,7 +155,7 @@ err = 0; address = &default_ldt[0]; - size = sizeof(struct desc_struct); + size = 5*sizeof(struct desc_struct); if (size > bytecount) size = bytecount; @@ -88,24 +190,14 @@ goto out; } - /* - * the GDT index of the LDT is allocated dynamically, and is - * limited by MAX_LDT_DESCRIPTORS. - */ - down_write(&mm->mmap_sem); - if (!mm->context.segments) { - void * segments = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE); - error = -ENOMEM; - if (!segments) + down(&mm->context.sem); + if (ldt_info.entry_number >= mm->context.size) { + error = alloc_ldt(¤t->mm->context, ldt_info.entry_number+1, 1); + if (error < 0) goto out_unlock; - memset(segments, 0, LDT_ENTRIES*LDT_ENTRY_SIZE); - wmb(); - mm->context.segments = segments; - mm->context.cpuvalid = 1UL << smp_processor_id(); - load_LDT(mm); } - lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.segments); + lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.ldt); /* Allow LDTs to be cleared by the user. */ if (ldt_info.base_addr == 0 && ldt_info.limit == 0) { @@ -143,7 +235,7 @@ error = 0; out_unlock: - up_write(&mm->mmap_sem); + up(&mm->context.sem); out: return error; } Index: arch/i386/kernel/microcode.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/microcode.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/microcode.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/i386/kernel/microcode.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -1,7 +1,7 @@ /* * Intel CPU Microcode Update driver for Linux * - * Copyright (C) 2000 Tigran Aivazian + * Copyright (C) 2000-2004 Tigran Aivazian * * This driver allows to upgrade microcode on Intel processors * belonging to IA-32 family - PentiumPro, Pentium II, @@ -57,8 +57,20 @@ * nature of implementation. * 1.11 22 Mar 2002 Tigran Aivazian * Fix the panic when writing zero-length microcode chunk. + * 1.12 29 Sep 2003 Nitin Kamble , + * Jun Nakajima + * Support for the microcode updates in the new format. + * 1.13 10 Oct 2003 Tigran Aivazian + * Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl + * because we no longer hold a copy of applied microcode + * in kernel memory. + * 1.14 23 Feb 2004 Tigran Aivazian + * Restored devfs regular file entry point which was + * accidentally removed when back-porting changes from the 2.6 + * version of the driver. */ + #include #include #include @@ -67,341 +79,449 @@ #include #include #include +#include #include #include #include - -static spinlock_t microcode_update_lock = SPIN_LOCK_UNLOCKED; - -#define MICROCODE_VERSION "1.11" - MODULE_DESCRIPTION("Intel CPU (IA-32) microcode update driver"); MODULE_AUTHOR("Tigran Aivazian "); MODULE_LICENSE("GPL"); -EXPORT_NO_SYMBOLS; - -#define MICRO_DEBUG 0 +#define MICROCODE_VERSION "1.14" +#define MICRO_DEBUG 0 #if MICRO_DEBUG -#define printf(x...) printk(##x) +#define dprintk(x...) printk(KERN_INFO x) #else -#define printf(x...) +#define dprintk(x...) #endif -/* VFS interface */ -static int microcode_open(struct inode *, struct file *); -static ssize_t microcode_read(struct file *, char *, size_t, loff_t *); -static ssize_t microcode_write(struct file *, const char *, size_t, loff_t *); -static int microcode_ioctl(struct inode *, struct file *, unsigned int, unsigned long); - -static int do_microcode_update(void); -static void do_update_one(void *); - -/* read()/write()/ioctl() are serialized on this */ -static DECLARE_RWSEM(microcode_rwsem); - -static struct microcode *microcode; /* array of 2048byte microcode blocks */ -static unsigned int microcode_num; /* number of chunks in microcode */ -static char *mc_applied; /* array of applied microcode blocks */ -static unsigned int mc_fsize; /* file size of /dev/cpu/microcode */ +#define DEFAULT_UCODE_DATASIZE (2000) /* 2000 bytes */ +#define MC_HEADER_SIZE (sizeof (microcode_header_t)) /* 48 bytes */ +#define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) /* 2048 bytes */ +#define EXT_HEADER_SIZE (sizeof (struct extended_sigtable)) /* 20 bytes */ +#define EXT_SIGNATURE_SIZE (sizeof (struct extended_signature)) /* 12 bytes */ +#define DWSIZE (sizeof (u32)) +#define get_totalsize(mc) \ + (((microcode_t *)mc)->hdr.totalsize ? \ + ((microcode_t *)mc)->hdr.totalsize : DEFAULT_UCODE_TOTALSIZE) +#define get_datasize(mc) \ + (((microcode_t *)mc)->hdr.datasize ? \ + ((microcode_t *)mc)->hdr.datasize : DEFAULT_UCODE_DATASIZE) +#define sigmatch(s1, s2, p1, p2) (((s1) == (s2)) && ((p1) & (p2))) +#define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE) -/* we share file_operations between misc and devfs mechanisms */ -static struct file_operations microcode_fops = { - owner: THIS_MODULE, - read: microcode_read, - write: microcode_write, - ioctl: microcode_ioctl, - open: microcode_open, -}; +/* serialize access to the physical write to MSR 0x79 */ +static spinlock_t microcode_update_lock = SPIN_LOCK_UNLOCKED; -static struct miscdevice microcode_dev = { - minor: MICROCODE_MINOR, - name: "microcode", - fops: µcode_fops, -}; +/* no concurrent ->write()s are allowed on /dev/cpu/microcode */ +static DECLARE_MUTEX(microcode_sem); -static devfs_handle_t devfs_handle; +static void *user_buffer; /* user area microcode data buffer */ +static unsigned int user_buffer_size; /* it's size */ -static int __init microcode_init(void) +typedef enum mc_error_code { + MC_SUCCESS = 0, + MC_NOTFOUND = 1, + MC_MARKED = 2, + MC_ALLOCATED = 3, +} mc_error_code_t; + +static struct ucode_cpu_info { + unsigned int sig; + unsigned int pf; + unsigned int rev; + unsigned int cksum; + mc_error_code_t err; + microcode_t *mc; +} ucode_cpu_info[NR_CPUS]; + +static int microcode_open (struct inode *unused1, struct file *unused2) { - int error; + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; +} - error = misc_register(µcode_dev); - if (error) - printk(KERN_WARNING - "microcode: can't misc_register on minor=%d\n", - MICROCODE_MINOR); +static void collect_cpu_info (void *unused) +{ + int cpu_num = smp_processor_id(); + struct cpuinfo_x86 *c = cpu_data + cpu_num; + struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; + unsigned int val[2]; - devfs_handle = devfs_register(NULL, "cpu/microcode", - DEVFS_FL_DEFAULT, 0, 0, S_IFREG | S_IRUSR | S_IWUSR, - µcode_fops, NULL); - if (devfs_handle == NULL && error) { - printk(KERN_ERR "microcode: failed to devfs_register()\n"); + uci->sig = uci->pf = uci->rev = uci->cksum = 0; + uci->err = MC_NOTFOUND; + uci->mc = NULL; + + if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || + cpu_has(c, X86_FEATURE_IA64)) { + printk(KERN_ERR "microcode: CPU%d not a capable Intel processor\n", cpu_num); + return; + } else { + uci->sig = cpuid_eax(0x00000001); + + if ((c->x86_model >= 5) || (c->x86 > 6)) { + /* get processor flags from MSR 0x17 */ + rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); + uci->pf = 1 << ((val[1] >> 18) & 7); + } + } + + wrmsr(MSR_IA32_UCODE_REV, 0, 0); + __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx"); + /* get the current revision from MSR 0x8B */ + rdmsr(MSR_IA32_UCODE_REV, val[0], uci->rev); + dprintk("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n", + uci->sig, uci->pf, uci->rev); +} + +static inline void mark_microcode_update (int cpu_num, microcode_header_t *mc_header, int sig, int pf, int cksum) +{ + struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; + + dprintk("Microcode Found.\n"); + dprintk(" Header Revision 0x%x\n", mc_header->hdrver); + dprintk(" Loader Revision 0x%x\n", mc_header->ldrver); + dprintk(" Revision 0x%x \n", mc_header->rev); + dprintk(" Date %x/%x/%x\n", + ((mc_header->date >> 24 ) & 0xff), + ((mc_header->date >> 16 ) & 0xff), + (mc_header->date & 0xFFFF)); + dprintk(" Signature 0x%x\n", sig); + dprintk(" Type 0x%x Family 0x%x Model 0x%x Stepping 0x%x\n", + ((sig >> 12) & 0x3), + ((sig >> 8) & 0xf), + ((sig >> 4) & 0xf), + ((sig & 0xf))); + dprintk(" Processor Flags 0x%x\n", pf); + dprintk(" Checksum 0x%x\n", cksum); + + if (mc_header->rev < uci->rev) { + printk(KERN_ERR "microcode: CPU%d not 'upgrading' to earlier revision" + " 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev); + goto out; + } else if (mc_header->rev == uci->rev) { + /* notify the caller of success on this cpu */ + uci->err = MC_SUCCESS; + printk(KERN_ERR "microcode: CPU%d already at revision" + " 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev); goto out; } - error = 0; - printk(KERN_INFO - "IA-32 Microcode Update Driver: v%s \n", - MICROCODE_VERSION); + dprintk("microcode: CPU%d found a matching microcode update with " + " revision 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev); + uci->cksum = cksum; + uci->pf = pf; /* keep the original mc pf for cksum calculation */ + uci->err = MC_MARKED; /* found the match */ out: - return error; + return; } -static void __exit microcode_exit(void) +static int find_matching_ucodes (void) { - misc_deregister(µcode_dev); - devfs_unregister(devfs_handle); - if (mc_applied) - kfree(mc_applied); - printk(KERN_INFO "IA-32 Microcode Update Driver v%s unregistered\n", - MICROCODE_VERSION); -} + int cursor = 0; + int error = 0; -module_init(microcode_init) -module_exit(microcode_exit) + while (cursor + MC_HEADER_SIZE < user_buffer_size) { + microcode_header_t mc_header; + void *newmc = NULL; + int i, sum, cpu_num, allocated_flag, total_size, data_size, ext_table_size; + + if (copy_from_user(&mc_header, user_buffer + cursor, MC_HEADER_SIZE)) { + printk(KERN_ERR "microcode: error! Can not read user data\n"); + error = -EFAULT; + goto out; + } -static int microcode_open(struct inode *unused1, struct file *unused2) -{ - return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; -} + total_size = get_totalsize(&mc_header); + if ((cursor + total_size > user_buffer_size) || (total_size < DEFAULT_UCODE_TOTALSIZE)) { + printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); + error = -EINVAL; + goto out; + } -/* - * update_req[cpu].err is set to 1 if update failed on 'cpu', 0 otherwise - * if err==0, microcode[update_req[cpu].slot] points to applied block of microcode - */ -struct update_req { - int err; - int slot; -} update_req[NR_CPUS]; + data_size = get_datasize(&mc_header); + if ((data_size + MC_HEADER_SIZE > total_size) || (data_size < DEFAULT_UCODE_DATASIZE)) { + printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); + error = -EINVAL; + goto out; + } -static int do_microcode_update(void) -{ - int i, error = 0, err; - struct microcode *m; + if (mc_header.ldrver != 1 || mc_header.hdrver != 1) { + printk(KERN_ERR "microcode: error! Unknown microcode update format\n"); + error = -EINVAL; + goto out; + } + + for (cpu_num = 0; cpu_num < smp_num_cpus; cpu_num++) { + struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; + if (uci->err != MC_NOTFOUND) /* already found a match or not an online cpu*/ + continue; - if (smp_call_function(do_update_one, NULL, 1, 1) != 0) { - printk(KERN_ERR "microcode: IPI timeout, giving up\n"); - return -EIO; - } - do_update_one(NULL); + if (sigmatch(mc_header.sig, uci->sig, mc_header.pf, uci->pf)) + mark_microcode_update(cpu_num, &mc_header, mc_header.sig, mc_header.pf, mc_header.cksum); + } + + ext_table_size = total_size - (MC_HEADER_SIZE + data_size); + if (ext_table_size) { + struct extended_sigtable ext_header; + struct extended_signature ext_sig; + int ext_sigcount; + + if ((ext_table_size < EXT_HEADER_SIZE) + || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) { + printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); + error = -EINVAL; + goto out; + } + if (copy_from_user(&ext_header, user_buffer + cursor + + MC_HEADER_SIZE + data_size, EXT_HEADER_SIZE)) { + printk(KERN_ERR "microcode: error! Can not read user data\n"); + error = -EFAULT; + goto out; + } + if (ext_table_size != exttable_size(&ext_header)) { + printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); + error = -EFAULT; + goto out; + } - for (i=0; ierr != MC_NOTFOUND) /* already found a match or not an online cpu*/ + continue; + if (sigmatch(ext_sig.sig, uci->sig, ext_sig.pf, uci->pf)) { + mark_microcode_update(cpu_num, &mc_header, ext_sig.sig, ext_sig.pf, ext_sig.cksum); + } + } + } } - } + /* now check if any cpu has matched */ + for (cpu_num = 0, allocated_flag = 0, sum = 0; cpu_num < smp_num_cpus; cpu_num++) { + if (ucode_cpu_info[cpu_num].err == MC_MARKED) { + struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; + if (!allocated_flag) { + allocated_flag = 1; + newmc = vmalloc(total_size); + if (!newmc) { + printk(KERN_ERR "microcode: error! Can not allocate memory\n"); + error = -ENOMEM; + goto out; + } + if (copy_from_user(newmc + MC_HEADER_SIZE, + user_buffer + cursor + MC_HEADER_SIZE, + total_size - MC_HEADER_SIZE)) { + printk(KERN_ERR "microcode: error! Can not read user data\n"); + vfree(newmc); + error = -EFAULT; + goto out; + } + memcpy(newmc, &mc_header, MC_HEADER_SIZE); + /* check extended table checksum */ + if (ext_table_size) { + int * ext_tablep; + int ext_table_sum = 0; + i = ext_table_size / DWSIZE; + ext_tablep = (((void *) newmc) + MC_HEADER_SIZE + data_size); + while (i--) ext_table_sum += ext_tablep[i]; + if (ext_table_sum) { + printk(KERN_WARNING "microcode: aborting, bad extended signature table checksum\n"); + vfree(newmc); + error = -EINVAL; + goto out; + } + } + + /* calculate the checksum */ + i = (MC_HEADER_SIZE + data_size) / DWSIZE; + while (i--) sum += ((int *)newmc)[i]; + sum -= (mc_header.sig + mc_header.pf + mc_header.cksum); + } + ucode_cpu_info[cpu_num].mc = newmc; + ucode_cpu_info[cpu_num].err = MC_ALLOCATED; /* mc updated */ + if (sum + uci->sig + uci->pf + uci->cksum != 0) { + printk(KERN_ERR "microcode: CPU%d aborting, bad checksum\n", cpu_num); + error = -EINVAL; + goto out; + } + } + } + cursor += total_size; /* goto the next update patch */ + } /* end of while */ +out: return error; } -static void do_update_one(void *unused) +static void do_update_one (void * unused) { - int cpu_num = smp_processor_id(); - struct cpuinfo_x86 *c = cpu_data + cpu_num; - struct update_req *req = update_req + cpu_num; - unsigned int pf = 0, val[2], rev, sig; unsigned long flags; - int i; - - req->err = 1; /* assume update will fail on this cpu */ + unsigned int val[2]; + int cpu_num = smp_processor_id(); + struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; - if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || - test_bit(X86_FEATURE_IA64, &c->x86_capability)){ - printk(KERN_ERR "microcode: CPU%d not a capable Intel processor\n", cpu_num); + if (uci->mc == NULL) { + printk(KERN_INFO "microcode: No suitable data for cpu %d\n", cpu_num); return; } - sig = c->x86_mask + (c->x86_model<<4) + (c->x86<<8); + /* serialize access to the physical write to MSR 0x79 */ + spin_lock_irqsave(µcode_update_lock, flags); - if ((c->x86_model >= 5) || (c->x86 > 6)) { - /* get processor flags from MSR 0x17 */ - rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); - pf = 1 << ((val[1] >> 18) & 7); - } - - for (i=0; i> 24 ) & 0xff), - ((microcode[i].date >> 16 ) & 0xff), - (microcode[i].date & 0xFFFF)); - printf(" Type %x Family %x Model %x Stepping %x\n", - ((microcode[i].sig >> 12) & 0x3), - ((microcode[i].sig >> 8) & 0xf), - ((microcode[i].sig >> 4) & 0xf), - ((microcode[i].sig & 0xf))); - printf(" Checksum %x\n",microcode[i].cksum); - printf(" Loader Revision %x\n",microcode[i].ldrver); - printf(" Processor Flags %x\n\n",microcode[i].pf); - - req->slot = i; - - /* serialize access to update decision */ - spin_lock_irqsave(µcode_update_lock, flags); - - /* trick, to work even if there was no prior update by the BIOS */ - wrmsr(MSR_IA32_UCODE_REV, 0, 0); - __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx"); + /* write microcode via MSR 0x79 */ + wrmsr(MSR_IA32_UCODE_WRITE, (unsigned int)(uci->mc->bits), 0); + wrmsr(MSR_IA32_UCODE_REV, 0, 0); + + __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx"); + /* get the current revision from MSR 0x8B */ + rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); + + /* notify the caller of success on this cpu */ + uci->err = MC_SUCCESS; + spin_unlock_irqrestore(µcode_update_lock, flags); + printk(KERN_INFO "microcode: CPU%d updated from revision " + "0x%x to 0x%x, date = %08x \n", + cpu_num, uci->rev, val[1], uci->mc->hdr.date); + return; +} - /* get current (on-cpu) revision into rev (ignore val[0]) */ - rdmsr(MSR_IA32_UCODE_REV, val[0], rev); - - if (microcode[i].rev < rev) { - spin_unlock_irqrestore(µcode_update_lock, flags); - printk(KERN_ERR - "microcode: CPU%d not 'upgrading' to earlier revision" - " %d (current=%d)\n", cpu_num, microcode[i].rev, rev); - return; - } else if (microcode[i].rev == rev) { - /* notify the caller of success on this cpu */ - req->err = 0; - spin_unlock_irqrestore(µcode_update_lock, flags); - printk(KERN_ERR - "microcode: CPU%d already at revision" - " %d (current=%d)\n", cpu_num, microcode[i].rev, rev); - return; - } +static int do_microcode_update (void) +{ + int i, error; - /* Verify the checksum */ - while (--sump >= (unsigned int *)m) - sum += *sump; - if (sum != 0) { - req->err = 1; - spin_unlock_irqrestore(µcode_update_lock, flags); - printk(KERN_ERR "microcode: CPU%d aborting, " - "bad checksum\n", cpu_num); - return; - } - - /* write microcode via MSR 0x79 */ - wrmsr(MSR_IA32_UCODE_WRITE, (unsigned int)(m->bits), 0); + if (smp_call_function(collect_cpu_info, NULL, 1, 1) != 0) { + printk(KERN_ERR "microcode: Error! Could not run on all processors\n"); + error = -EIO; + goto out; + } + collect_cpu_info(NULL); - /* serialize */ - __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx"); + if ((error = find_matching_ucodes())) { + printk(KERN_ERR "microcode: Error in the microcode data\n"); + goto out_free; + } - /* get the current revision from MSR 0x8B */ - rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); + if (smp_call_function(do_update_one, NULL, 1, 1) != 0) { + printk(KERN_ERR "microcode: Error! Could not run on all processors\n"); + error = -EIO; + } + do_update_one(NULL); - /* notify the caller of success on this cpu */ - req->err = 0; - spin_unlock_irqrestore(µcode_update_lock, flags); - printk(KERN_INFO "microcode: CPU%d updated from revision " - "%d to %d, date=%08x\n", - cpu_num, rev, val[1], microcode[i].date); - return; +out_free: + for (i = 0; i < smp_num_cpus; i++) { + if (ucode_cpu_info[i].mc) { + int j; + void *tmp = ucode_cpu_info[i].mc; + vfree(tmp); + for (j = i; j < smp_num_cpus; j++) { + if (ucode_cpu_info[j].mc == tmp) + ucode_cpu_info[j].mc = NULL; + } } - - printk(KERN_ERR - "microcode: CPU%d no microcode found! (sig=%x, pflags=%d)\n", - cpu_num, sig, pf); -} - - -static ssize_t microcode_read(struct file *file, char *buf, size_t len, loff_t *ppos) -{ - ssize_t ret = 0; - - down_read(µcode_rwsem); - if (*ppos >= mc_fsize) - goto out; - if (*ppos + len > mc_fsize) - len = mc_fsize - *ppos; - ret = -EFAULT; - if (copy_to_user(buf, mc_applied + *ppos, len)) - goto out; - *ppos += len; - ret = len; + } out: - up_read(µcode_rwsem); - return ret; + return error; } -static ssize_t microcode_write(struct file *file, const char *buf, size_t len, loff_t *ppos) +static ssize_t microcode_write (struct file *file, const char *buf, size_t len, loff_t *ppos) { ssize_t ret; - if (!len || len % sizeof(struct microcode) != 0) { - printk(KERN_ERR "microcode: can only write in N*%d bytes units\n", - sizeof(struct microcode)); + if (len < DEFAULT_UCODE_TOTALSIZE) { + printk(KERN_ERR "microcode: not enough data\n"); return -EINVAL; } + if ((len >> PAGE_SHIFT) > num_physpages) { printk(KERN_ERR "microcode: too much data (max %ld pages)\n", num_physpages); return -EINVAL; } - down_write(µcode_rwsem); - if (!mc_applied) { - mc_applied = kmalloc(smp_num_cpus*sizeof(struct microcode), - GFP_KERNEL); - if (!mc_applied) { - up_write(µcode_rwsem); - printk(KERN_ERR "microcode: out of memory for saved microcode\n"); - return -ENOMEM; - } - } - - microcode_num = len/sizeof(struct microcode); - microcode = vmalloc(len); - if (!microcode) { - ret = -ENOMEM; - goto out_unlock; - } - - if (copy_from_user(microcode, buf, len)) { - ret = -EFAULT; - goto out_fsize; - } - - if(do_microcode_update()) { - ret = -EIO; - goto out_fsize; - } else { - mc_fsize = smp_num_cpus * sizeof(struct microcode); + + down(µcode_sem); + + user_buffer = (void *) buf; + user_buffer_size = (int) len; + + ret = do_microcode_update(); + if (!ret) ret = (ssize_t)len; - } -out_fsize: - devfs_set_file_size(devfs_handle, mc_fsize); - vfree(microcode); -out_unlock: - up_write(µcode_rwsem); + + up(µcode_sem); + return ret; } -static int microcode_ioctl(struct inode *inode, struct file *file, +static int microcode_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - switch(cmd) { + switch (cmd) { + /* + * XXX: will be removed after microcode_ctl + * is updated to ignore failure of this ioctl() + */ case MICROCODE_IOCFREE: - down_write(µcode_rwsem); - if (mc_applied) { - int bytes = smp_num_cpus * sizeof(struct microcode); - - devfs_set_file_size(devfs_handle, 0); - kfree(mc_applied); - mc_applied = NULL; - printk(KERN_INFO "microcode: freed %d bytes\n", bytes); - mc_fsize = 0; - up_write(µcode_rwsem); - return 0; - } - up_write(µcode_rwsem); - return -ENODATA; - + return 0; default: - printk(KERN_ERR "microcode: unknown ioctl cmd=%d\n", cmd); return -EINVAL; } return -EINVAL; } + +/* shared between misc device and devfs regular file */ +static struct file_operations microcode_fops = { + .owner = THIS_MODULE, + .write = microcode_write, + .ioctl = microcode_ioctl, + .open = microcode_open, +}; + +static struct miscdevice microcode_dev = { + .minor = MICROCODE_MINOR, + .name = "microcode", + .fops = µcode_fops, +}; + +static devfs_handle_t devfs_handle; + +static int __init microcode_init (void) +{ + int error; + + error = misc_register(µcode_dev); + if (error) + printk(KERN_ERR + "microcode: can't misc_register on minor=%d\n", + MICROCODE_MINOR); + devfs_handle = devfs_register(NULL, "cpu/microcode", + DEVFS_FL_DEFAULT, 0, 0, S_IFREG | S_IRUSR | S_IWUSR, + µcode_fops, NULL); + if (devfs_handle == NULL && error) { + printk(KERN_ERR "microcode: failed to devfs_register()\n"); + goto out; + } + error = 0; + printk(KERN_INFO + "IA-32 Microcode Update Driver: v" + MICROCODE_VERSION " \n"); +out: + return error; +} + +static void __exit microcode_exit (void) +{ + misc_deregister(µcode_dev); + devfs_unregister(devfs_handle); + printk(KERN_INFO "IA-32 Microcode Update Driver v" + MICROCODE_VERSION " unregistered\n"); +} + +module_init(microcode_init) +module_exit(microcode_exit) Index: arch/i386/kernel/mpparse.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/mpparse.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/mpparse.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/i386/kernel/mpparse.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -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,13 +25,18 @@ #include #include +#include #include #include #include #include +#include /* Have we found an MP table */ int smp_found_config; +#ifdef CONFIG_SMP +extern unsigned int max_cpus; +#endif /* * Various Linux-internal data structures created from the @@ -137,12 +144,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 @@ -231,6 +232,19 @@ boot_cpu_logical_apicid = logical_apicid; } +#ifdef CONFIG_SMP + if (num_processors >= NR_CPUS) { + printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached." + " Processor ignored.\n", NR_CPUS); + return; + } + if (num_processors >= max_cpus) { + printk(KERN_WARNING "WARNING: maxcpus limit of %i reached." + " Processor ignored.\n", max_cpus); + return; + } +#endif + num_processors++; if (m->mpc_apicid > MAX_APICS) { @@ -447,10 +461,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 +532,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 +545,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); @@ -584,10 +598,6 @@ ++mpc_record; } - if (clustered_apic_mode){ - phys_cpu_present_map = logical_cpu_present_map; - } - printk("Enabling APIC mode: "); if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ) @@ -685,6 +695,24 @@ struct mpc_config_lintsrc lintsrc; int linttypes[2] = { mp_ExtINT, mp_NMI }; int i; + struct { + int mp_bus_id_to_type[MAX_MP_BUSSES]; + int mp_bus_id_to_node[MAX_MP_BUSSES]; + int mp_bus_id_to_local[MAX_MP_BUSSES]; + int mp_bus_id_to_pci_bus[MAX_MP_BUSSES]; + struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; + } *bus_data; + + bus_data = alloc_bootmem(sizeof(*bus_data)); + if (!bus_data) + panic("SMP mptable: out of memory!\n"); + mp_bus_id_to_type = bus_data->mp_bus_id_to_type; + mp_bus_id_to_node = bus_data->mp_bus_id_to_node; + mp_bus_id_to_local = bus_data->mp_bus_id_to_local; + mp_bus_id_to_pci_bus = bus_data->mp_bus_id_to_pci_bus; + mp_irqs = bus_data->mp_irqs; + for (i = 0; i < MAX_MP_BUSSES; ++i) + mp_bus_id_to_pci_bus[i] = -1; /* * local APIC has default address @@ -761,7 +789,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 +797,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 +968,360 @@ #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; + + /* + * mp_register_lapic_address() which is called before the + * current function does the fixmap of FIX_APIC_BASE. + * Read in the correct APIC version from there + */ + processor.mpc_apicver = apic_read(APIC_LVR); + + 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) && (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_srcbus == intsrc.mpc_srcbus) + && (mp_irqs[i].mpc_srcbusirq == intsrc.mpc_srcbusirq)) { + 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 = mp_INT; + 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"); + } +} + +extern FADT_DESCRIPTOR acpi_fadt; + +#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) { + entry->irq = irq; /*we still need to set entry's 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); + } + + print_IO_APIC(); + + return; +} + +#endif /*CONFIG_ACPI_PCI*/ + +#endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/ + +#endif /*CONFIG_ACPI*/ Index: arch/i386/kernel/msr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/msr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/msr.c 22 Jul 2004 19:49:03 -0000 1.1 +++ arch/i386/kernel/msr.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -1,4 +1,4 @@ -#ident "$Id: msr.c,v 1.1 2004/07/22 19:49:03 joff Exp $" +#ident "$Id: msr.c,v 1.2 2004/08/04 01:25:41 joff Exp $" /* ----------------------------------------------------------------------- * * * Copyright 2000 H. Peter Anvin - All Rights Reserved Index: arch/i386/kernel/pci-i386.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/pci-i386.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/pci-i386.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/i386/kernel/pci-i386.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -295,6 +295,17 @@ } } +void __init pcibios_set_cacheline_size(void) +{ + struct cpuinfo_x86 *c = &boot_cpu_data; + + pci_cache_line_size = 32 >> 2; + if (c->x86 >= 6 && c->x86_vendor == X86_VENDOR_AMD) + pci_cache_line_size = 64 >> 2; /* K7 & K8 */ + else if (c->x86 > 6 && c->x86_vendor == X86_VENDOR_INTEL) + pci_cache_line_size = 128 >> 2; /* P4 */ +} + void __init pcibios_resource_survey(void) { DBG("PCI: Allocating resources\n"); Index: arch/i386/kernel/pci-i386.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/pci-i386.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/pci-i386.h 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/i386/kernel/pci-i386.h 4 Aug 2004 01:25:41 -0000 1.2 @@ -27,8 +27,10 @@ /* pci-i386.c */ extern unsigned int pcibios_max_latency; +extern u8 pci_cache_line_size; void pcibios_resource_survey(void); +void pcibios_set_cacheline_size(void); int pcibios_enable_resources(struct pci_dev *, int); /* pci-pc.c */ Index: arch/i386/kernel/pci-irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/pci-irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/pci-irq.c 22 Jul 2004 19:49:03 -0000 1.1 +++ arch/i386/kernel/pci-irq.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -23,7 +23,6 @@ #define PIRQ_VERSION 0x0100 int broken_hp_bios_irq9; -int broken_440gx_bios; static struct irq_routing_table *pirq_table; @@ -46,6 +45,11 @@ int (*set)(struct pci_dev *router, struct pci_dev *dev, int pirq, int new); }; +struct irq_router_handler { + u16 vendor; + int (*probe)(struct irq_router *r, struct pci_dev *router, u16 device); +}; + /* * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. */ @@ -116,7 +120,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 +200,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; } @@ -256,111 +261,221 @@ } /* - * PIRQ routing for SiS 85C503 router used in several SiS chipsets - * According to the SiS 5595 datasheet (preliminary V1.0, 12/24/1997) - * the related registers work as follows: - * - * general: one byte per re-routable IRQ, + * PIRQ routing for SiS 85C503 router used in several SiS chipsets. + * We have to deal with the following issues here: + * - vendors have different ideas about the meaning of link values + * - some onboard devices (integrated in the chipset) have special + * links and are thus routed differently (i.e. not via PCI INTA-INTD) + * - different revision of the router have a different layout for + * the routing registers, particularly for the onchip devices + * + * For all routing registers the common thing is we have one byte + * per routeable link which is defined as: * bit 7 IRQ mapping enabled (0) or disabled (1) - * bits [6:4] reserved + * bits [6:4] reserved (sometimes used for onchip devices) * bits [3:0] IRQ to map to * allowed: 3-7, 9-12, 14-15 * reserved: 0, 1, 2, 8, 13 * - * individual registers in device config space: + * The config-space registers located at 0x41/0x42/0x43/0x44 are + * always used to route the normal PCI INT A/B/C/D respectively. + * Apparently there are systems implementing PCI routing table using + * link values 0x01-0x04 and others using 0x41-0x44 for PCI INTA..D. + * We try our best to handle both link mappings. + * + * Currently (2003-05-21) it appears most SiS chipsets follow the + * definition of routing registers from the SiS-5595 southbridge. + * According to the SiS 5595 datasheets the revision id's of the + * router (ISA-bridge) should be 0x01 or 0xb0. * - * 0x41/0x42/0x43/0x44: PCI INT A/B/C/D - bits as in general case + * Furthermore we've also seen lspci dumps with revision 0x00 and 0xb1. + * Looks like these are used in a number of SiS 5xx/6xx/7xx chipsets. + * They seem to work with the current routing code. However there is + * some concern because of the two USB-OHCI HCs (original SiS 5595 + * had only one). YMMV. * - * 0x61: IDEIRQ: bits as in general case - but: - * bits [6:5] must be written 01 - * bit 4 channel-select primary (0), secondary (1) + * Onchip routing for router rev-id 0x01/0xb0 and probably 0x00/0xb1: * - * 0x62: USBIRQ: bits as in general case - but: - * bit 4 OHCI function disabled (0), enabled (1) + * 0x61: IDEIRQ: + * bits [6:5] must be written 01 + * bit 4 channel-select primary (0), secondary (1) + * + * 0x62: USBIRQ: + * bit 6 OHCI function disabled (0), enabled (1) * - * 0x6a: ACPI/SCI IRQ - bits as in general case + * 0x6a: ACPI/SCI IRQ: bits 4-6 reserved + * + * 0x7e: Data Acq. Module IRQ - bits 4-6 reserved + * + * We support USBIRQ (in addition to INTA-INTD) and keep the + * IDE, ACPI and DAQ routing untouched as set by the BIOS. + * + * Currently the only reported exception is the new SiS 65x chipset + * which includes the SiS 69x southbridge. Here we have the 85C503 + * router revision 0x04 and there are changes in the register layout + * mostly related to the different USB HCs with USB 2.0 support. * - * 0x7e: Data Acq. Module IRQ - bits as in general case + * Onchip routing for router rev-id 0x04 (try-and-error observation) * - * Apparently there are systems implementing PCI routing table using both - * link values 0x01-0x04 and 0x41-0x44 for PCI INTA..D, but register offsets - * like 0x62 as link values for USBIRQ e.g. So there is no simple - * "register = offset + pirq" relation. - * Currently we support PCI INTA..D and USBIRQ and try our best to handle - * both link mappings. - * IDE/ACPI/DAQ mapping is currently unsupported (left untouched as set by BIOS). + * 0x60/0x61/0x62/0x63: 1xEHCI and 3xOHCI (companion) USB-HCs + * bit 6-4 are probably unused, not like 5595 */ -static int pirq_sis_get(struct pci_dev *router, struct pci_dev *dev, int pirq) +#define PIRQ_SIS_IRQ_MASK 0x0f +#define PIRQ_SIS_IRQ_DISABLE 0x80 +#define PIRQ_SIS_USB_ENABLE 0x40 +#define PIRQ_SIS_DETECT_REGISTER 0x40 + +/* return value: + * -1 on error + * 0 for PCI INTA-INTD + * 0 or enable bit mask to check or set for onchip functions + */ +static inline int pirq_sis5595_onchip(int pirq, int *reg) { - u8 x; - int reg = pirq; + int ret = -1; + *reg = pirq; switch(pirq) { - case 0x01: - case 0x02: - case 0x03: - case 0x04: - reg += 0x40; - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x62: - pci_read_config_byte(router, reg, &x); - if (reg != 0x62) - break; - if (!(x & 0x40)) - return 0; - break; - case 0x61: - case 0x6a: - case 0x7e: - printk(KERN_INFO "SiS pirq: advanced IDE/ACPI/DAQ mapping not yet implemented\n"); - return 0; - default: - printk(KERN_INFO "SiS router pirq escape (%d)\n", pirq); - return 0; + case 0x01: + case 0x02: + case 0x03: + case 0x04: + *reg += 0x40; + case 0x41: + case 0x42: + case 0x43: + case 0x44: + ret = 0; + break; + + case 0x62: + ret = PIRQ_SIS_USB_ENABLE; /* documented for 5595 */ + break; + + case 0x61: + case 0x6a: + case 0x7e: + printk(KERN_INFO "SiS pirq: IDE/ACPI/DAQ mapping not implemented: (%u)\n", + (unsigned) pirq); + /* fall thru */ + default: + printk(KERN_INFO "SiS router unknown request: (%u)\n", + (unsigned) pirq); + break; + } + return ret; +} + +/* return value: + * -1 on error + * 0 for PCI INTA-INTD + * 0 or enable bit mask to check or set for onchip functions + */ +static inline int pirq_sis96x_onchip(int pirq, int *reg) +{ + int ret = -1; + + *reg = pirq; + switch(pirq) { + case 0x01: + case 0x02: + case 0x03: + case 0x04: + *reg += 0x40; + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x60: + case 0x61: + case 0x62: + case 0x63: + ret = 0; + break; + + default: + printk(KERN_INFO "SiS router unknown request: (%u)\n", + (unsigned) pirq); + break; } - return (x & 0x80) ? 0 : (x & 0x0f); + return ret; +} + + +static int pirq_sis5595_get(struct pci_dev *router, struct pci_dev *dev, int pirq) +{ + u8 x; + int reg, check; + + check = pirq_sis5595_onchip(pirq, ®); + if (check < 0) + return 0; + + pci_read_config_byte(router, reg, &x); + if (check != 0 && !(x & check)) + return 0; + + return (x & PIRQ_SIS_IRQ_DISABLE) ? 0 : (x & PIRQ_SIS_IRQ_MASK); } -static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) +static int pirq_sis96x_get(struct pci_dev *router, struct pci_dev *dev, int pirq) { u8 x; - int reg = pirq; + int reg, check; + + check = pirq_sis96x_onchip(pirq, ®); + if (check < 0) + return 0; + + pci_read_config_byte(router, reg, &x); + if (check != 0 && !(x & check)) + return 0; + + return (x & PIRQ_SIS_IRQ_DISABLE) ? 0 : (x & PIRQ_SIS_IRQ_MASK); +} + +static int pirq_sis5595_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) +{ + u8 x; + int reg, set; + + set = pirq_sis5595_onchip(pirq, ®); + if (set < 0) + return 0; + + x = (irq & PIRQ_SIS_IRQ_MASK); + if (x == 0) + x = PIRQ_SIS_IRQ_DISABLE; + else + x |= set; - switch(pirq) { - case 0x01: - case 0x02: - case 0x03: - case 0x04: - reg += 0x40; - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x62: - x = (irq&0x0f) ? (irq&0x0f) : 0x80; - if (reg != 0x62) - break; - /* always mark OHCI enabled, as nothing else knows about this */ - x |= 0x40; - break; - case 0x61: - case 0x6a: - case 0x7e: - printk(KERN_INFO "advanced SiS pirq mapping not yet implemented\n"); - return 0; - default: - printk(KERN_INFO "SiS router pirq escape (%d)\n", pirq); - return 0; - } pci_write_config_byte(router, reg, x); return 1; } +static int pirq_sis96x_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) +{ + u8 x; + int reg, set; + + set = pirq_sis96x_onchip(pirq, ®); + if (set < 0) + return 0; + + x = (irq & PIRQ_SIS_IRQ_MASK); + if (x == 0) + x = PIRQ_SIS_IRQ_DISABLE; + else + x |= set; + + pci_write_config_byte(router, reg, x); + + return 1; +} + + /* * VLSI: nibble offset 0x74 - educated guess due to routing table and * config space of VLSI 82C534 PCI-bridge/router (1004:0102) @@ -453,94 +568,265 @@ return pcibios_set_irq_routing(bridge, pin, irq); } -static struct irq_router pirq_bios_router = - { "BIOS", 0, 0, NULL, pirq_bios_set }; - #endif -static struct irq_router pirq_routers[] = { - { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0, pirq_piix_get, pirq_piix_set }, - { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, pirq_piix_get, pirq_piix_set }, - { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, pirq_piix_get, pirq_piix_set }, - { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX, pirq_piix_get, pirq_piix_set }, - { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_0, pirq_piix_get, pirq_piix_set }, - { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, pirq_piix_get, pirq_piix_set }, - { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, pirq_piix_get, pirq_piix_set }, - { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, pirq_piix_get, pirq_piix_set }, - { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10, pirq_piix_get, pirq_piix_set }, - { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, pirq_piix_get, pirq_piix_set }, - { "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 }, - - { "ALI", PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pirq_ali_get, pirq_ali_set }, - - { "ITE", PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8330G_0, pirq_ite_get, pirq_ite_set }, - - { "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, pirq_via_get, pirq_via_set }, - { "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596, pirq_via_get, pirq_via_set }, - { "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, pirq_via_get, pirq_via_set }, - - { "OPTI", PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C700, pirq_opti_get, pirq_opti_set }, - - { "NatSemi", PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, pirq_cyrix_get, pirq_cyrix_set }, - { "SIS", PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, pirq_sis_get, pirq_sis_set }, - { "VLSI 82C534", PCI_VENDOR_ID_VLSI, PCI_DEVICE_ID_VLSI_82C534, pirq_vlsi_get, pirq_vlsi_set }, - { "ServerWorks", PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4, - pirq_serverworks_get, pirq_serverworks_set }, - { "ServerWorks", PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5, - pirq_serverworks_get, pirq_serverworks_set }, - { "AMD756 VIPER", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_740B, - pirq_amd756_get, pirq_amd756_set }, - { "AMD766", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7413, - pirq_amd756_get, pirq_amd756_set }, - { "AMD768", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7443, - pirq_amd756_get, pirq_amd756_set }, - { "default", 0, 0, NULL, NULL } -}; +static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + /* We must not touch 440GX even if we have tables. 440GX has + different IRQ routing weirdness */ + if(pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0, NULL) || + pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2, NULL)) + return 0; + switch(device) + { + case PCI_DEVICE_ID_INTEL_82371FB_0: + case PCI_DEVICE_ID_INTEL_82371SB_0: + case PCI_DEVICE_ID_INTEL_82371AB_0: + case PCI_DEVICE_ID_INTEL_82371MX: + case PCI_DEVICE_ID_INTEL_82443MX_0: + case PCI_DEVICE_ID_INTEL_82801AA_0: + case PCI_DEVICE_ID_INTEL_82801AB_0: + case PCI_DEVICE_ID_INTEL_82801BA_0: + case PCI_DEVICE_ID_INTEL_82801BA_10: + case PCI_DEVICE_ID_INTEL_82801CA_0: + case PCI_DEVICE_ID_INTEL_82801CA_12: + case PCI_DEVICE_ID_INTEL_82801DB_0: + case PCI_DEVICE_ID_INTEL_82801E_0: + case PCI_DEVICE_ID_INTEL_82801EB_0: + case PCI_DEVICE_ID_INTEL_ESB_0: + case PCI_DEVICE_ID_INTEL_ICH6_0: + r->name = "PIIX/ICH"; + r->get = pirq_piix_get; + r->set = pirq_piix_set; + return 1; + } + return 0; +} -static struct irq_router *pirq_router; +static __init int via_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + /* FIXME: We should move some of the quirk fixup stuff here */ + switch(device) + { + case PCI_DEVICE_ID_VIA_82C586_0: + case PCI_DEVICE_ID_VIA_82C596: + case PCI_DEVICE_ID_VIA_82C686: + case PCI_DEVICE_ID_VIA_8231: + /* FIXME: add new ones for 8233/5 */ + r->name = "VIA"; + r->get = pirq_via_get; + r->set = pirq_via_set; + return 1; + } + return 0; +} + +static __init int vlsi_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + switch(device) + { + case PCI_DEVICE_ID_VLSI_82C534: + r->name = "VLSI 82C534"; + r->get = pirq_vlsi_get; + r->set = pirq_vlsi_set; + return 1; + } + return 0; +} + + +static __init int serverworks_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + switch(device) + { + case PCI_DEVICE_ID_SERVERWORKS_OSB4: + case PCI_DEVICE_ID_SERVERWORKS_CSB5: + r->name = "ServerWorks"; + r->get = pirq_serverworks_get; + r->set = pirq_serverworks_set; + return 1; + } + return 0; +} + +static __init int sis_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + u8 reg; + u16 devid; + + if (device != PCI_DEVICE_ID_SI_503) + return 0; + + /* + * In case of SiS south bridge, we need to detect the two + * kinds of routing tables we have seen so far (5595 and 96x). + * Since the maintain the same device ID, we need to do poke + * the PCI configuration space to find the router type we are + * dealing with. + */ + + /* + * Factoid: writing bit6 of register 0x40 of the router config space + * will make the SB to show up 0x096x inside the device id. Note, + * we need to restore register 0x40 after the device id poke. + */ + + pci_read_config_byte(router, PIRQ_SIS_DETECT_REGISTER, ®); + pci_write_config_byte(router, PIRQ_SIS_DETECT_REGISTER, reg | (1 << 6)); + pci_read_config_word(router, PCI_DEVICE_ID, &devid); + pci_write_config_byte(router, PIRQ_SIS_DETECT_REGISTER, reg); + + if ((devid & 0xfff0) == 0x0960) { + r->name = "SIS96x"; + r->get = pirq_sis96x_get; + r->set = pirq_sis96x_set; + DBG("PCI: Detecting SiS router at %02x:%02x : SiS096x detected\n", + rt->rtr_bus, rt->rtr_devfn); + } else { + r->name = "SIS5595"; + r->get = pirq_sis5595_get; + r->set = pirq_sis5595_set; + DBG("PCI: Detecting SiS router at %02x:%02x : SiS5595 detected\n", + rt->rtr_bus, rt->rtr_devfn); + } + return 1; +} + +static __init int cyrix_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + switch(device) + { + case PCI_DEVICE_ID_CYRIX_5520: + r->name = "NatSemi"; + r->get = pirq_cyrix_get; + r->set = pirq_cyrix_set; + return 1; + } + return 0; +} + +static __init int opti_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + switch(device) + { + case PCI_DEVICE_ID_OPTI_82C700: + r->name = "OPTI"; + r->get = pirq_opti_get; + r->set = pirq_opti_set; + return 1; + } + return 0; +} + +static __init int ite_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + switch(device) + { + case PCI_DEVICE_ID_ITE_IT8330G_0: + r->name = "ITE"; + r->get = pirq_ite_get; + r->set = pirq_ite_set; + return 1; + } + return 0; +} + +static __init int ali_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + switch(device) + { + case PCI_DEVICE_ID_AL_M1533: + r->name = "ALI"; + r->get = pirq_ali_get; + r->set = pirq_ali_set; + return 1; + /* Should add 156x some day */ + } + return 0; +} + +static __init int amd_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + switch(device) + { + case PCI_DEVICE_ID_AMD_VIPER_740B: + r->name = "AMD756"; + break; + case PCI_DEVICE_ID_AMD_VIPER_7413: + r->name = "AMD766"; + break; + case PCI_DEVICE_ID_AMD_VIPER_7443: + r->name = "AMD768"; + break; + default: + return 0; + } + r->get = pirq_amd756_get; + r->set = pirq_amd756_set; + return 1; +} + +static __initdata struct irq_router_handler pirq_routers[] = { + { PCI_VENDOR_ID_INTEL, intel_router_probe }, + { PCI_VENDOR_ID_AL, ali_router_probe }, + { PCI_VENDOR_ID_ITE, ite_router_probe }, + { PCI_VENDOR_ID_VIA, via_router_probe }, + { PCI_VENDOR_ID_OPTI, opti_router_probe }, + { PCI_VENDOR_ID_SI, sis_router_probe }, + { PCI_VENDOR_ID_CYRIX, cyrix_router_probe }, + { PCI_VENDOR_ID_VLSI, vlsi_router_probe }, + { PCI_VENDOR_ID_SERVERWORKS, serverworks_router_probe }, + { PCI_VENDOR_ID_AMD, amd_router_probe }, + /* Someone with docs needs to add the ATI Radeon IGP */ + { 0, NULL } +}; +static struct irq_router pirq_router; static struct pci_dev *pirq_router_dev; -static void __init pirq_find_router(void) +/* + * FIXME: should we have an option to say "generic for + * chipset" ? + */ + +static void __init pirq_find_router(struct irq_router *r) { struct irq_routing_table *rt = pirq_table; - struct irq_router *r; + struct irq_router_handler *h; #ifdef CONFIG_PCI_BIOS if (!rt->signature) { printk(KERN_INFO "PCI: Using BIOS for IRQ routing\n"); - pirq_router = &pirq_bios_router; + r->set = pirq_bios_set; + r->name = "BIOS"; return; } #endif + /* Default unless a driver reloads it */ + r->name = "default"; + r->get = NULL; + r->set = NULL; + DBG("PCI: Attempting to find IRQ router for %04x:%04x\n", rt->rtr_vendor, rt->rtr_device); - /* fall back to default router if nothing else found */ - pirq_router = &pirq_routers[ARRAY_SIZE(pirq_routers) - 1]; - pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn); if (!pirq_router_dev) { DBG("PCI: Interrupt router not found at %02x:%02x\n", rt->rtr_bus, rt->rtr_devfn); return; } - for(r=pirq_routers; r->vendor; r++) { - /* Exact match against router table entry? Use it! */ - if (r->vendor == rt->rtr_vendor && r->device == rt->rtr_device) { - pirq_router = r; + for( h = pirq_routers; h->vendor; h++) { + /* First look for a router match */ + if (rt->rtr_vendor == h->vendor && h->probe(r, pirq_router_dev, rt->rtr_device)) + break; + /* Fall back to a device match */ + if (pirq_router_dev->vendor == h->vendor && h->probe(r, pirq_router_dev, pirq_router_dev->device)) break; - } - /* Match against router device entry? Use it as a fallback */ - if (r->vendor == pirq_router_dev->vendor && r->device == pirq_router_dev->device) { - pirq_router = r; - } } printk(KERN_INFO "PCI: Using IRQ router %s [%04x/%04x] at %s\n", - pirq_router->name, + pirq_router.name, pirq_router_dev->vendor, pirq_router_dev->device, pirq_router_dev->slot_name); @@ -569,7 +855,7 @@ int i, pirq, newirq; int irq = 0; u32 mask; - struct irq_router *r = pirq_router; + struct irq_router *r = &pirq_router; struct pci_dev *dev2; char *msg = NULL; @@ -682,17 +968,14 @@ void __init pcibios_irq_init(void) { DBG("PCI: IRQ init\n"); - if (broken_440gx_bios) - pirq_table = NULL; - else - pirq_table = pirq_find_routing_table(); + pirq_table = pirq_find_routing_table(); #ifdef CONFIG_PCI_BIOS if (!pirq_table && (pci_probe & PCI_BIOS_IRQ_SCAN)) pirq_table = pcibios_get_irq_routing_table(); #endif if (pirq_table) { pirq_peer_trick(); - pirq_find_router(); + pirq_find_router(&pirq_router); if (pirq_table->exclusive_irqs) { int i; for (i=0; i<16; i++) Index: arch/i386/kernel/pci-pc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/pci-pc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/pci-pc.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/i386/kernel/pci-pc.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -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]) @@ -1013,7 +1016,8 @@ "xor %%ah, %%ah\n" "1:" : "=a" (ret), - "=b" (map) + "=b" (map), + "+m" (opt) : "0" (PCIBIOS_GET_ROUTING_OPTIONS), "1" (0), "D" ((long) &opt), @@ -1353,6 +1357,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) { @@ -1405,8 +1426,22 @@ return; } + pcibios_set_cacheline_size(); + 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_noirq && !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 +1451,6 @@ } } - pcibios_irq_init(); - pcibios_fixup_peer_bridges(); - pcibios_fixup_irqs(); pcibios_resource_survey(); #ifdef CONFIG_PCI_BIOS @@ -1470,6 +1502,9 @@ } else if (!strncmp(str, "lastbus=", 8)) { pcibios_last_bus = simple_strtol(str+8, NULL, 0); return NULL; + } else if (!strncmp(str, "noacpi", 6)) { + acpi_noirq_set(); + return NULL; } return str; } @@ -1485,6 +1520,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; } Index: arch/i386/kernel/pci-visws.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/pci-visws.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/pci-visws.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/i386/kernel/pci-visws.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -119,6 +119,7 @@ { unsigned int sec_bus = li_pcib_read16(LI_PCI_BUSNUM) & 0xff; + pcibios_set_cacheline_size(); printk("PCI: Probing PCI hardware on host buses 00 and %02x\n", sec_bus); pci_scan_bus(0, &visws_pci_ops, NULL); pci_scan_bus(sec_bus, &visws_pci_ops, NULL); Index: arch/i386/kernel/process.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/process.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/process.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/i386/kernel/process.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -44,9 +44,11 @@ #include #include #include +#include #ifdef CONFIG_MATH_EMULATION #include #endif +#include #include @@ -151,7 +153,6 @@ __setup("idle=", idle_setup); -static long no_idt[2]; static int reboot_mode; int reboot_thru_bios; @@ -222,7 +223,8 @@ unsigned long long * base __attribute__ ((packed)); } real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries }, -real_mode_idt = { 0x3ff, 0 }; +real_mode_idt = { 0x3ff, 0 }, +no_idt = { 0, 0 }; /* This is 16-bit protected mode code to disable paging and the cache, switch to real mode and jump to the BIOS reset code. @@ -253,7 +255,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 */ }; @@ -376,7 +378,7 @@ if its not, default to the BSP */ if ((reboot_cpu == -1) || (reboot_cpu > (NR_CPUS -1)) || - !(phys_cpu_present_map & (1<context.segments; - - /* - * free the LDT - */ - if (ldt) { - mm->context.segments = NULL; - clear_LDT(); - vfree(ldt); - } -} - -/* * Create a kernel thread */ int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) @@ -535,45 +528,19 @@ void release_thread(struct task_struct *dead_task) { if (dead_task->mm) { - void * ldt = dead_task->mm->context.segments; - // temporary debugging check - if (ldt) { - printk("WARNING: dead process %8s still has LDT? <%p>\n", - dead_task->comm, ldt); + if (dead_task->mm->context.size) { + printk("WARNING: dead process %8s still has LDT? <%p/%d>\n", + dead_task->comm, + dead_task->mm->context.ldt, + dead_task->mm->context.size); BUG(); } } - release_x86_irqs(dead_task); } /* - * we do not have to muck with descriptors here, that is - * done in switch_mm() as needed. - */ -void copy_segments(struct task_struct *p, struct mm_struct *new_mm) -{ - struct mm_struct * old_mm; - void *old_ldt, *ldt; - - ldt = NULL; - old_mm = current->mm; - if (old_mm && (old_ldt = old_mm->context.segments) != NULL) { - /* - * Completely new LDT, we initialize it from the parent: - */ - ldt = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE); - if (!ldt) - printk(KERN_WARNING "ldt allocation failed\n"); - else - memcpy(ldt, old_ldt, LDT_ENTRIES*LDT_ENTRY_SIZE); - } - new_mm->context.segments = ldt; - new_mm->context.cpuvalid = ~0UL; /* valid on all CPU's - they can't have stale data */ -} - -/* * Save a segment. */ #define savesegment(seg,value) \ Index: arch/i386/kernel/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/setup.c 22 Jul 2004 19:49:03 -0000 1.1 +++ arch/i386/kernel/setup.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -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 @@ -118,6 +120,8 @@ #include #include #include +#include +#include /* * Machine setup.. */ @@ -126,6 +130,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 +175,22 @@ 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 = 0; +#else + int acpi_disabled = 1; +#endif +EXPORT_SYMBOL(acpi_disabled); + +#ifdef CONFIG_ACPI_BOOT +extern int __initdata acpi_ht; +int acpi_force __initdata = 0; +extern acpi_interrupt_flags acpi_sci_flags; +#endif + +extern int blk_nohighio; /* * This is set up by the setup-routine at boot-time @@ -196,6 +212,9 @@ #define KERNEL_START (*(unsigned long *) (PARAM+0x214)) #define INITRD_START (*(unsigned long *) (PARAM+0x218)) #define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c)) +#define DISK80_SIGNATURE_BUFFER (*(unsigned int*) (PARAM+DISK80_SIG_BUFFER)) +#define EDD_NR (*(unsigned char *) (PARAM+EDDNR)) +#define EDD_BUF ((struct edd_info *) (PARAM+EDDBUF)) #define COMMAND_LINE ((char *) (PARAM+2048)) #define COMMAND_LINE_SIZE 256 @@ -700,6 +719,25 @@ return 0; } +#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) +unsigned char eddnr; +struct edd_info edd[EDDMAXNR]; +unsigned int edd_disk80_sig; +/** + * copy_edd() - Copy the BIOS EDD information + * from empty_zero_page into a safe place. + * + */ +static inline void copy_edd(void) +{ + eddnr = EDD_NR; + memcpy(edd, EDD_BUF, sizeof(edd)); + edd_disk80_sig = DISK80_SIGNATURE_BUFFER; +} +#else +static inline void copy_edd(void) {} +#endif + /* * Do NOT EVER look at the BIOS memory size location. * It does not work on many machines. @@ -782,23 +820,73 @@ 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; } } } +#ifdef CONFIG_SMP + /* + * If the BIOS enumerates physical processors before logical, + * maxcpus=N at enumeration-time can be used to disable HT. + */ + else if (!memcmp(from, "maxcpus=", 8)) { + extern unsigned int max_cpus; - /* "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); + max_cpus = simple_strtoul(from + 8, NULL, 0); + } +#endif + +#ifdef CONFIG_ACPI_BOOT + /* "acpi=off" disables both ACPI table parsing and interpreter */ + else if (!memcmp(from, "acpi=off", 8)) { + disable_acpi(); + } + + /* 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)) { + if (!acpi_force) + disable_acpi(); + acpi_ht = 1; + } + + /* acpi=strict disables out-of-spec workarounds */ + else if (!memcmp(from, "acpi=strict", 11)) { + acpi_strict = 1; + } + + else if (!memcmp(from, "pci=noacpi", 10)) { + acpi_noirq_set(); } - /* "acpismp=force" forces parsing and use of the ACPI SMP table */ - else if (!memcmp(from, "acpismp=force", 13)) - enable_acpi_smp_table = 1; + /* disable IO-APIC */ + else if (!memcmp(from, "noapic", 6)) + disable_ioapic_setup(); + else if (!memcmp(from, "acpi_sci=edge", 13)) + acpi_sci_flags.trigger = 1; + else if (!memcmp(from, "acpi_sci=level", 14)) + acpi_sci_flags.trigger = 3; + else if (!memcmp(from, "acpi_sci=high", 13)) + acpi_sci_flags.polarity = 1; + else if (!memcmp(from, "acpi_sci=low", 12)) + acpi_sci_flags.polarity = 3; + +#endif /* * highmem=size forces highmem to be exactly 'size' bytes. * This works even on boxes that have no highmem otherwise. @@ -1007,10 +1095,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 +1136,6 @@ { unsigned long low_mem_size; int i; - probe_roms(); for (i = 0; i < e820.nr_map; i++) { struct resource *res; @@ -1112,6 +1204,7 @@ rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0); #endif setup_memory_region(); + copy_edd(); if (!MOUNT_ROOT_RDONLY) root_mountflags &= ~MS_RDONLY; @@ -1130,22 +1223,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 +1231,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 +1256,6 @@ conswitchp = &dummy_con; #endif #endif - dmi_scan_machine(); } static int cachesize_override __initdata = -1; @@ -1946,6 +2030,37 @@ #endif +static void __init init_c3(struct cpuinfo_x86 *c) +{ + u32 lo, hi; + + /* Test for Centaur Extended Feature Flags presence */ + if (cpuid_eax(0xC0000000) >= 0xC0000001) { + /* store Centaur Extended Feature Flags as + * word 5 of the CPU capability bit array + */ + c->x86_capability[5] = cpuid_edx(0xC0000001); + } + + switch (c->x86_model) { + case 6 ... 8: /* Cyrix III family */ + rdmsr (MSR_VIA_FCR, lo, hi); + lo |= (1<<1 | 1<<7); /* Report CX8 & enable PGE */ + wrmsr (MSR_VIA_FCR, lo, hi); + + set_bit(X86_FEATURE_CX8, c->x86_capability); + set_bit(X86_FEATURE_3DNOW, c->x86_capability); + + /* fall through */ + + case 9: /* Nehemiah */ + default: + get_model_name(c); + display_cacheinfo(c); + break; + } +} + static void __init init_centaur(struct cpuinfo_x86 *c) { enum { @@ -2084,23 +2199,7 @@ break; case 6: - switch (c->x86_model) { - case 6 ... 8: /* Cyrix III family */ - rdmsr (MSR_VIA_FCR, lo, hi); - lo |= (1<<1 | 1<<7); /* Report CX8 & enable PGE */ - wrmsr (MSR_VIA_FCR, lo, hi); - - set_bit(X86_FEATURE_CX8, &c->x86_capability); - set_bit(X86_FEATURE_3DNOW, &c->x86_capability); - - /* fall through */ - - case 9: /* Nehemiah */ - default: - get_model_name(c); - display_cacheinfo(c); - break; - } + init_c3(c); break; } } @@ -2224,6 +2323,8 @@ { 0x23, LVL_3, 1024 }, { 0x25, LVL_3, 2048 }, { 0x29, LVL_3, 4096 }, + { 0x2c, LVL_1_DATA, 32 }, + { 0x30, LVL_1_INST, 32 }, { 0x39, LVL_2, 128 }, { 0x3b, LVL_2, 128 }, { 0x3C, LVL_2, 256 }, @@ -2246,6 +2347,8 @@ { 0x83, LVL_2, 512 }, { 0x84, LVL_2, 1024 }, { 0x85, LVL_2, 2048 }, + { 0x86, LVL_2, 512 }, + { 0x87, LVL_2, 1024 }, { 0x00, 0, 0} }; @@ -2387,7 +2490,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; @@ -2735,10 +2838,16 @@ /* Intel-defined flags: level 0x00000001 */ if ( c->cpuid_level >= 0x00000001 ) { - cpuid(0x00000001, &tfms, &junk, &junk, - &c->x86_capability[0]); + u32 capability, excap; + cpuid(0x00000001, &tfms, &junk, &excap, &capability); + c->x86_capability[0] = capability; + c->x86_capability[4] = excap; c->x86 = (tfms >> 8) & 15; c->x86_model = (tfms >> 4) & 15; + if (c->x86 == 0xf) { + c->x86 += (tfms >> 20) & 0xff; + c->x86_model += ((tfms >> 16) & 0xF) << 4; + } c->x86_mask = tfms & 15; } else { /* Have CPUID level 0 only - unheard of */ @@ -2942,12 +3051,12 @@ "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov", "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx", - "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL, + "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe", /* AMD-defined */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, "mmxext", NULL, + NULL, NULL, NULL, "mp", NULL, NULL, "mmxext", NULL, NULL, NULL, NULL, NULL, NULL, "lm", "3dnowext", "3dnow", /* Transmeta-defined */ @@ -2957,7 +3066,20 @@ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* Other (Linux-defined) */ - "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr", NULL, NULL, NULL, NULL, + "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr", + 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, + + /* Intel-defined (#2) */ + "pni", NULL, NULL, "monitor", "ds_cpl", NULL, NULL, "tm2", + "est", NULL, "cid", NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* VIA/Cyrix/Centaur-defined */ + NULL, NULL, "xstore", 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, @@ -3096,7 +3218,7 @@ set_tss_desc(nr,t); gdt_table[__TSS(nr)].b &= 0xfffffdff; load_TR(nr); - load_LDT(&init_mm); + load_LDT(&init_mm.context); /* * Clear all 6 debug registers: Index: arch/i386/kernel/smpboot.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/smpboot.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/smpboot.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/i386/kernel/smpboot.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -51,7 +51,7 @@ static int smp_b_stepping; /* Setup configured maximum number of CPUs to activate */ -static int max_cpus = -1; +unsigned int max_cpus = NR_CPUS; /* Total count of live CPUs */ int smp_num_cpus = 1; @@ -77,10 +77,6 @@ * * Command-line option of "nosmp" or "maxcpus=0" will disable SMP * activation entirely (the MPS table probe still happens, though). - * - * Command-line option of "maxcpus=", where is an integer - * greater than 0, limits the maximum number of CPUs activated in - * SMP mode to . */ static int __init nosmp(char *str) @@ -91,14 +87,6 @@ __setup("nosmp", nosmp); -static int __init maxcpus(char *str) -{ - get_option(&str, &max_cpus); - return 1; -} - -__setup("maxcpus=", maxcpus); - /* * Trampoline 80x86 program as an array. */ @@ -1034,7 +1022,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; @@ -1106,17 +1094,19 @@ */ Dprintk("CPU present map: %lx\n", phys_cpu_present_map); - for (bit = 0; bit < NR_CPUS; bit++) { + for (bit = 0; bit < BITS_PER_LONG; bit++) { apicid = cpu_present_to_apicid(bit); + + /* don't try to boot BAD_APICID */ + if (apicid == BAD_APICID) + continue; /* * Don't even attempt to start the boot CPU! */ if (apicid == boot_cpu_apicid) continue; - if (!(phys_cpu_present_map & (1ul << bit))) - continue; - if ((max_cpus >= 0) && (max_cpus <= cpucount+1)) + if (!(phys_cpu_present_map & apicid_to_phys_cpu_present(apicid))) continue; do_boot_cpu(apicid); @@ -1125,7 +1115,8 @@ * Make sure we unmap all failed CPUs */ if ((boot_apicid_to_cpu(apicid) == -1) && - (phys_cpu_present_map & (1ul << bit))) + (phys_cpu_present_map & + apicid_to_phys_cpu_present(apicid))) printk("CPU #%d/0x%02x not responding - cannot use it.\n", bit, apicid); } Index: arch/i386/kernel/sys_i386.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/sys_i386.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/sys_i386.c 22 Jul 2004 19:49:03 -0000 1.1 +++ arch/i386/kernel/sys_i386.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -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; } } Index: arch/i386/kernel/time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/time.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/i386/kernel/time.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -279,6 +279,7 @@ static inline void mark_timeoffset_cyclone(void) { int count; + unsigned long lost; unsigned long delta = last_cyclone_timer; spin_lock(&i8253_lock); /* quickly read the cyclone timer */ @@ -293,11 +294,12 @@ spin_unlock(&i8253_lock); /*lost tick compensation*/ - delta = last_cyclone_timer - delta; - if(delta > loops_per_jiffy+2000){ - delta = (delta/loops_per_jiffy)-1; - jiffies += delta; - } + delta = last_cyclone_timer - delta; + delta /= (CYCLONE_TIMER_FREQ/1000000); + delta += delay_at_last_interrupt; + lost = delta/(1000000/HZ); + if (lost >= 2) + jiffies += lost-1; count = ((LATCH-1) - count) * TICK_SIZE; delay_at_last_interrupt = (count + LATCH/2) / LATCH; @@ -430,7 +432,6 @@ const int use_cyclone = 0; static void mark_timeoffset_cyclone(void) {} -static unsigned long do_gettimeoffset_cyclone(void) {return 0;} static void init_cyclone_clock(void) {} void __cyclone_delay(unsigned long loops) {} #endif /* CONFIG_X86_SUMMIT */ Index: arch/i386/kernel/vm86.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/kernel/vm86.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/kernel/vm86.c 22 Jul 2004 19:49:08 -0000 1.1 +++ arch/i386/kernel/vm86.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -362,6 +362,9 @@ if (VEFLAGS & VIF_MASK) flags |= IF_MASK; + else + flags &= ~IF_MASK; + flags |= IOPL_MASK; return flags | (VEFLAGS & current->thread.v86mask); } Index: arch/i386/math-emu/fpu_system.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/math-emu/fpu_system.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/math-emu/fpu_system.h 22 Jul 2004 19:49:03 -0000 1.1 +++ arch/i386/math-emu/fpu_system.h 4 Aug 2004 01:25:41 -0000 1.2 @@ -20,7 +20,7 @@ of the stack frame of math_emulate() */ #define SETUP_DATA_AREA(arg) FPU_info = (struct info *) &arg -#define LDT_DESCRIPTOR(s) (((struct desc_struct *)current->mm->context.segments)[(s) >> 3]) +#define LDT_DESCRIPTOR(s) (((struct desc_struct *)current->mm->context.ldt)[(s) >> 3]) #define SEG_D_SIZE(x) ((x).b & (3 << 21)) #define SEG_G_BIT(x) ((x).b & (1 << 23)) #define SEG_GRANULARITY(x) (((x).b & (1 << 23)) ? 4096 : 1) Index: arch/i386/math-emu/fpu_trig.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/math-emu/fpu_trig.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/math-emu/fpu_trig.c 22 Jul 2004 19:49:03 -0000 1.1 +++ arch/i386/math-emu/fpu_trig.c 4 Aug 2004 01:25:41 -0000 1.2 @@ -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; Index: arch/i386/math-emu/poly.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/math-emu/poly.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/math-emu/poly.h 22 Jul 2004 19:49:03 -0000 1.1 +++ arch/i386/math-emu/poly.h 4 Aug 2004 01:25:42 -0000 1.2 @@ -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"); } Index: arch/i386/mm/fault.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/mm/fault.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/mm/fault.c 22 Jul 2004 19:49:03 -0000 1.1 +++ arch/i386/mm/fault.c 4 Aug 2004 01:25:42 -0000 1.2 @@ -270,7 +270,8 @@ /* User mode accesses just cause a SIGSEGV */ if (error_code & 4) { tsk->thread.cr2 = address; - tsk->thread.error_code = error_code; + /* Kernel addresses are always protection faults */ + tsk->thread.error_code = error_code | (address >= TASK_SIZE); tsk->thread.trap_no = 14; info.si_signo = SIGSEGV; info.si_errno = 0; Index: arch/i386/mm/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/mm/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/mm/init.c 22 Jul 2004 19:49:03 -0000 1.1 +++ arch/i386/mm/init.c 4 Aug 2004 01:25:42 -0000 1.2 @@ -510,7 +510,15 @@ if (!mem_map) BUG(); - +#ifdef CONFIG_HIGHMEM + /* check that fixmap and pkmap do not overlap */ + if (PKMAP_BASE+LAST_PKMAP*PAGE_SIZE >= FIXADDR_START) { + printk(KERN_ERR "fixmap and kmap areas overlap - this will crash\n"); + printk(KERN_ERR "pkstart: %lxh pkend: %lxh fixstart %lxh\n", + PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE, FIXADDR_START); + BUG(); + } +#endif set_max_mapnr_init(); high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); Index: arch/i386/mm/ioremap.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/i386/mm/ioremap.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/i386/mm/ioremap.c 22 Jul 2004 19:49:03 -0000 1.1 +++ arch/i386/mm/ioremap.c 4 Aug 2004 01:25:42 -0000 1.2 @@ -140,7 +140,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.. Index: arch/ia64/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/Makefile 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/ia64/Makefile 4 Aug 2004 01:25:42 -0000 1.2 @@ -17,13 +17,31 @@ AFLAGS_KERNEL := -mconstant-gp EXTRA = -CFLAGS := $(CFLAGS) -pipe $(EXTRA) -ffixed-r13 -mfixed-range=f10-f15,f32-f127 \ +CFLAGS := $(CFLAGS) -pipe $(EXTRA) -ffixed-r13 -mfixed-range=f12-f15,f32-f127 \ -falign-functions=32 # -ffunction-sections CFLAGS_KERNEL := -mconstant-gp GCC_VERSION=$(shell $(CC) -v 2>&1 | fgrep 'gcc version' | cut -f3 -d' ' | cut -f1 -d'.') +CHECK_GAS_FOR_HINT=arch/ia64/scripts/check_gas_for_hint.o +MAKE_GAS_HINT_TEST=arch/ia64/scripts/make_gas_hint_test + +ifneq (, $(shell ls $(CHECK_GAS_FOR_HINT))) +$(shell rm $(CHECK_GAS_FOR_HINT)) +endif + +CHECK_GAS_CMD:=($(CC) $(MAKE_GAS_HINT_TEST).c -o $(MAKE_GAS_HINT_TEST) && $(MAKE_GAS_HINT_TEST) | $(CC) -c -o $(CHECK_GAS_FOR_HINT) -x assembler -; rm -f $(MAKE_GAS_HINT_TEST))>&/dev/null +$(shell $(CHECK_GAS_CMD)) +ifneq (, $(shell ls $(CHECK_GAS_FOR_HINT))) +#Newer version of binutil is detected and "hint" instruction is in the kernel +$(warning Warning: Found binutils that supports hint instruction) +FLAGS := $(AFLAGS) -DGAS_HAS_HINT_INSN +CFLAGS := $(CFLAGS) -DGAS_HAS_HINT_INSN +else +$(warning Warning: Please use binutil version 2.14.90.0.4.1 or higher to get the support of hint instruction in kernel.) +endif + ifneq ($(GCC_VERSION),2) CFLAGS += -frename-registers --param max-inline-insns=5000 endif @@ -44,9 +62,11 @@ ifdef CONFIG_IA64_HP_SIM SUBDIRS := arch/$(ARCH)/hp \ + arch/$(ARCH)/drivers \ $(SUBDIRS) CORE_FILES := arch/$(ARCH)/hp/hp.o \ $(CORE_FILES) + DRIVERS += arch/$(ARCH)/drivers/drivers.o endif ifdef CONFIG_IA64_HP_ZX1 @@ -132,8 +152,11 @@ archclean: @$(MAKEBOOT) clean +check: vmlinux + arch/ia64/scripts/unwcheck.sh vmlinux + archmrproper: - rm -f arch/$(ARCH)/vmlinux.lds + rm -f arch/$(ARCH)/vmlinux.lds vmlinux-tmp vmlinux.gz @$(MAKE) -C arch/$(ARCH)/tools mrproper archdep: Index: arch/ia64/config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/config.in 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/ia64/config.in 4 Aug 2004 01:25:42 -0000 1.2 @@ -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 define_bool CONFIG_GENERIC_ISA_DMA y choice 'IA-64 processor type' \ @@ -34,10 +34,9 @@ choice 'IA-64 system type' \ "generic CONFIG_IA64_GENERIC \ DIG-compliant CONFIG_IA64_DIG \ - HP-simulator CONFIG_IA64_HP_SIM \ - HP-zx1 CONFIG_IA64_HP_ZX1 \ - SGI-SN1 CONFIG_IA64_SGI_SN1 \ - SGI-SN2 CONFIG_IA64_SGI_SN2" generic + HP CONFIG_IA64_HP_ZX1 \ + SGI-SN2 CONFIG_IA64_SGI_SN2 \ + Ski-simulator CONFIG_IA64_HP_SIM" generic if [ "$CONFIG_ITANIUM" = "y" ]; then choice 'Kernel page size' \ @@ -55,11 +54,7 @@ if [ "$CONFIG_ITANIUM" = "y" ]; then define_bool CONFIG_IA64_BRL_EMU y bool ' Enable Itanium B-step specific code' CONFIG_ITANIUM_BSTEP_SPECIFIC - if [ "$CONFIG_IA64_SGI_SN1" = "y" ]; then - define_int CONFIG_IA64_L1_CACHE_SHIFT 7 # align cache-sensitive data to 128 bytes - else - define_int CONFIG_IA64_L1_CACHE_SHIFT 6 # align cache-sensitive data to 64 bytes - fi + define_int CONFIG_IA64_L1_CACHE_SHIFT 6 # align cache-sensitive data to 64 bytes fi if [ "$CONFIG_MCKINLEY" = "y" ]; then @@ -67,17 +62,20 @@ fi if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_DIG" = "y" -o "$CONFIG_IA64_HP_ZX1" = "y" ]; then + bool ' Enable NUMA support' CONFIG_NUMA + if [ "$CONFIG_NUMA" = "y" ]; then + define_bool CONFIG_DISCONTIGMEM y + fi bool ' Enable IA-64 Machine Check Abort' CONFIG_IA64_MCA define_bool CONFIG_PM y fi -if [ "$CONFIG_IA64_SGI_SN1" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ]; then +if [ "$CONFIG_IA64_SGI_SN2" = "y" ]; then define_bool CONFIG_IA64_SGI_SN y bool ' Enable extra debugging code' CONFIG_IA64_SGI_SN_DEBUG bool ' Enable SGI Medusa Simulator Support' CONFIG_IA64_SGI_SN_SIM - bool ' Enable autotest (llsc). Option to run cache test instead of booting' \ - CONFIG_IA64_SGI_AUTOTEST bool ' Enable protocol mode for the L1 console' CONFIG_SERIAL_SGI_L1_PROTOCOL + define_bool CONFIG_HWGFS_FS y define_bool CONFIG_DISCONTIGMEM y define_bool CONFIG_IA64_MCA y define_bool CONFIG_NUMA y @@ -87,8 +85,37 @@ define_bool CONFIG_KCORE_ELF y # On IA-64, we always want an ELF /proc/kcore. +define_int CONFIG_FORCE_MAX_ZONEORDER 19 + +if [ "$CONFIG_HUGETLB_PAGE" = "y" ]; then + if [ "$CONFIG_MCKINLEY" = "y" ]; then + choice ' IA-64 Huge TLB Page Size' \ + "4GB CONFIG_HUGETLB_PAGE_SIZE_4GB \ + 1GB CONFIG_HUGETLB_PAGE_SIZE_1GB \ + 256MB CONFIG_HUGETLB_PAGE_SIZE_256MB \ + 64MB CONFIG_HUGETLB_PAGE_SIZE_64MB \ + 16MB CONFIG_HUGETLB_PAGE_SIZE_16MB \ + 4MB CONFIG_HUGETLB_PAGE_SIZE_4MB \ + 1MB CONFIG_HUGETLB_PAGE_SIZE_1MB \ + 256KB CONFIG_HUGETLB_PAGE_SIZE_256KB" 16MB + else + choice ' IA-64 Huge TLB Page Size' \ + "256MB CONFIG_HUGETLB_PAGE_SIZE_256MB \ + 64MB CONFIG_HUGETLB_PAGE_SIZE_64MB \ + 16MB CONFIG_HUGETLB_PAGE_SIZE_16MB \ + 4MB CONFIG_HUGETLB_PAGE_SIZE_4MB \ + 1MB CONFIG_HUGETLB_PAGE_SIZE_1MB \ + 256KB CONFIG_HUGETLB_PAGE_SIZE_256KB" 16MB + fi +fi + +bool 'Use PAL_HALT_LIGHT in idle loop' CONFIG_IA64_PAL_IDLE bool 'SMP support' CONFIG_SMP -tristate 'Support running of Linux/x86 binaries' CONFIG_IA32_SUPPORT +if [ "$CONFIG_SMP" = "y" ]; then + int 'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32 +fi + +bool 'Support running of Linux/x86 binaries' CONFIG_IA32_SUPPORT bool 'Performance monitor support' CONFIG_PERFMON tristate '/proc/pal support' CONFIG_IA64_PALINFO tristate '/proc/efi/vars support' CONFIG_EFI_VARS @@ -145,7 +172,6 @@ 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 @@ -180,7 +206,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 @@ -243,6 +269,7 @@ source drivers/usb/Config.in + source crypto/Config.in source lib/Config.in if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then @@ -290,4 +317,6 @@ bool ' Turn on irq debug checks (slow!)' CONFIG_IA64_DEBUG_IRQ fi +int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 + endmenu Index: arch/ia64/defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/defconfig 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/ia64/defconfig 4 Aug 2004 01:25:42 -0000 1.2 @@ -22,15 +22,14 @@ # 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 # CONFIG_IA64_DIG is not set # CONFIG_IA64_HP_SIM is not set # CONFIG_IA64_HP_ZX1 is not set -# CONFIG_IA64_SGI_SN1 is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set @@ -38,10 +37,20 @@ CONFIG_IA64_BRL_EMU=y # CONFIG_ITANIUM_BSTEP_SPECIFIC is not set CONFIG_IA64_L1_CACHE_SHIFT=6 +# CONFIG_NUMA is not set CONFIG_IA64_MCA=y CONFIG_PM=y CONFIG_KCORE_ELF=y +CONFIG_FORCE_MAX_ZONEORDER=19 +# 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_IA64_PAL_IDLE is not set CONFIG_SMP=y +CONFIG_NR_CPUS=32 CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y @@ -103,6 +112,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -157,6 +172,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y @@ -243,13 +259,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,16 +273,15 @@ # 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 # 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 +# CONFIG_BLK_DEV_SGIIOC4 is not set # CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set @@ -276,7 +291,6 @@ # CONFIG_IDEDMA_AUTO is not set # 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 @@ -322,11 +336,16 @@ CONFIG_AIC7XXX_RESET_DELAY_MS=15000 # 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_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_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -359,7 +378,6 @@ # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y -# CONFIG_SCSI_QLOGIC_QLA2100 is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set @@ -403,6 +421,7 @@ # 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 @@ -430,7 +449,6 @@ # 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 @@ -442,6 +460,7 @@ # CONFIG_ACENIC is not set # CONFIG_DL2K is not set CONFIG_E1000=y +# CONFIG_E1000_NAPI is not set # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set @@ -574,7 +593,9 @@ # # CONFIG_WATCHDOG is not set # CONFIG_SCx200_GPIO is not set +# CONFIG_FETCHOP is not set # CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -592,12 +613,17 @@ # CONFIG_AGP_I810 is not set # CONFIG_AGP_VIA is not set # CONFIG_AGP_AMD is not set -# CONFIG_AGP_AMD_8151 is not set +# CONFIG_AGP_AMD_K8 is not set # CONFIG_AGP_SIS is not set # CONFIG_AGP_ALI is not set # CONFIG_AGP_SWORKS is not set CONFIG_AGP_I460=y CONFIG_AGP_HP_ZX1=y +# CONFIG_AGP_ATI is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# CONFIG_DRM=y # CONFIG_DRM_OLD is not set @@ -606,6 +632,7 @@ # CONFIG_DRM_NEW=y # CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set CONFIG_DRM_R128=y CONFIG_DRM_RADEON=y # CONFIG_DRM_I810 is not set @@ -628,6 +655,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 @@ -652,6 +680,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 @@ -661,6 +690,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 @@ -677,6 +707,8 @@ # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set CONFIG_RAMFS=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -710,6 +742,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=y CONFIG_NFSD_V3=y @@ -830,6 +863,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -879,6 +914,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 # @@ -899,6 +935,7 @@ # CONFIG_USB_PWC is not set # CONFIG_USB_SE401 is not set # CONFIG_USB_STV680 is not set +# CONFIG_USB_W9968CF is not set # CONFIG_USB_VICAM is not set # CONFIG_USB_DSBR is not set # CONFIG_USB_DABUSB is not set @@ -910,6 +947,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 @@ -933,8 +971,19 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET 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 @@ -967,3 +1016,4 @@ # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_IA64_DEBUG_CMPXCHG is not set # CONFIG_IA64_DEBUG_IRQ is not set +CONFIG_LOG_BUF_SHIFT=0 Index: arch/ia64/vmlinux.lds.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/vmlinux.lds.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/vmlinux.lds.S 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/ia64/vmlinux.lds.S 4 Aug 2004 01:25:42 -0000 1.2 @@ -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 = .; Index: arch/ia64/configs/dig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/configs/dig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/configs/dig 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/configs/dig 4 Aug 2004 01:25:42 -0000 1.2 @@ -22,15 +22,14 @@ # 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 CONFIG_IA64_DIG=y # CONFIG_IA64_HP_SIM is not set # CONFIG_IA64_HP_ZX1 is not set -# CONFIG_IA64_SGI_SN1 is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set @@ -38,10 +37,20 @@ CONFIG_IA64_BRL_EMU=y # CONFIG_ITANIUM_BSTEP_SPECIFIC is not set CONFIG_IA64_L1_CACHE_SHIFT=6 +# CONFIG_NUMA is not set CONFIG_IA64_MCA=y CONFIG_PM=y CONFIG_KCORE_ELF=y +CONFIG_FORCE_MAX_ZONEORDER=19 +# 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_IA64_PAL_IDLE is not set CONFIG_SMP=y +CONFIG_NR_CPUS=32 CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y @@ -103,6 +112,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -157,6 +172,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y @@ -243,7 +259,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,13 +273,11 @@ # 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 # 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 @@ -276,7 +290,6 @@ # CONFIG_IDEDMA_AUTO is not set # 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 @@ -322,11 +335,16 @@ CONFIG_AIC7XXX_RESET_DELAY_MS=15000 # 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_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_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -354,7 +372,6 @@ # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y -# CONFIG_SCSI_QLOGIC_QLA2100 is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set @@ -398,6 +415,7 @@ # 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 @@ -425,7 +443,6 @@ # 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 @@ -437,6 +454,7 @@ # CONFIG_ACENIC is not set # CONFIG_DL2K is not set CONFIG_E1000=y +# CONFIG_E1000_NAPI is not set # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set @@ -570,6 +588,7 @@ # CONFIG_WATCHDOG is not set # CONFIG_SCx200_GPIO is not set # CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -587,12 +606,17 @@ # CONFIG_AGP_I810 is not set # CONFIG_AGP_VIA is not set # CONFIG_AGP_AMD is not set -# CONFIG_AGP_AMD_8151 is not set +# CONFIG_AGP_AMD_K8 is not set # CONFIG_AGP_SIS is not set # CONFIG_AGP_ALI is not set # CONFIG_AGP_SWORKS is not set CONFIG_AGP_I460=y CONFIG_AGP_HP_ZX1=y +# CONFIG_AGP_ATI is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# CONFIG_DRM=y # CONFIG_DRM_OLD is not set @@ -601,6 +625,7 @@ # CONFIG_DRM_NEW=y # CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set CONFIG_DRM_R128=y CONFIG_DRM_RADEON=y # CONFIG_DRM_I810 is not set @@ -623,6 +648,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 @@ -647,6 +673,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 @@ -656,6 +683,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 @@ -672,6 +700,8 @@ # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set CONFIG_RAMFS=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -705,6 +735,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=y CONFIG_NFSD_V3=y @@ -825,6 +856,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -874,6 +907,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 # @@ -894,6 +928,7 @@ # CONFIG_USB_PWC is not set # CONFIG_USB_SE401 is not set # CONFIG_USB_STV680 is not set +# CONFIG_USB_W9968CF is not set # CONFIG_USB_VICAM is not set # CONFIG_USB_DSBR is not set # CONFIG_USB_DABUSB is not set @@ -905,6 +940,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 @@ -928,8 +964,19 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET 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 @@ -944,3 +991,4 @@ CONFIG_IA64_GRANULE_16MB=y # CONFIG_IA64_GRANULE_64MB is not set # CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=0 Index: arch/ia64/configs/generic =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/configs/generic,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/configs/generic 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/configs/generic 4 Aug 2004 01:25:42 -0000 1.2 @@ -22,15 +22,14 @@ # 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 # CONFIG_IA64_DIG is not set # CONFIG_IA64_HP_SIM is not set # CONFIG_IA64_HP_ZX1 is not set -# CONFIG_IA64_SGI_SN1 is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set @@ -38,10 +37,20 @@ CONFIG_IA64_BRL_EMU=y # CONFIG_ITANIUM_BSTEP_SPECIFIC is not set CONFIG_IA64_L1_CACHE_SHIFT=6 +# CONFIG_NUMA is not set CONFIG_IA64_MCA=y CONFIG_PM=y CONFIG_KCORE_ELF=y +CONFIG_FORCE_MAX_ZONEORDER=19 +# 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_IA64_PAL_IDLE is not set CONFIG_SMP=y +CONFIG_NR_CPUS=32 CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y @@ -103,6 +112,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -157,6 +172,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y @@ -243,13 +259,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,16 +273,15 @@ # 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 # 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 +# CONFIG_BLK_DEV_SGIIOC4 is not set # CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set @@ -276,7 +291,6 @@ # CONFIG_IDEDMA_AUTO is not set # 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 @@ -322,11 +336,16 @@ CONFIG_AIC7XXX_RESET_DELAY_MS=15000 # 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_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_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -359,7 +378,6 @@ # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y -# CONFIG_SCSI_QLOGIC_QLA2100 is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set @@ -403,6 +421,7 @@ # 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 @@ -430,7 +449,6 @@ # 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 @@ -442,6 +460,7 @@ # CONFIG_ACENIC is not set # CONFIG_DL2K is not set CONFIG_E1000=y +# CONFIG_E1000_NAPI is not set # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set @@ -574,7 +593,9 @@ # # CONFIG_WATCHDOG is not set # CONFIG_SCx200_GPIO is not set +# CONFIG_FETCHOP is not set # CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -592,12 +613,17 @@ # CONFIG_AGP_I810 is not set # CONFIG_AGP_VIA is not set # CONFIG_AGP_AMD is not set -# CONFIG_AGP_AMD_8151 is not set +# CONFIG_AGP_AMD_K8 is not set # CONFIG_AGP_SIS is not set # CONFIG_AGP_ALI is not set # CONFIG_AGP_SWORKS is not set CONFIG_AGP_I460=y CONFIG_AGP_HP_ZX1=y +# CONFIG_AGP_ATI is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# CONFIG_DRM=y # CONFIG_DRM_OLD is not set @@ -606,6 +632,7 @@ # CONFIG_DRM_NEW=y # CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set CONFIG_DRM_R128=y CONFIG_DRM_RADEON=y # CONFIG_DRM_I810 is not set @@ -628,6 +655,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 @@ -652,6 +680,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 @@ -661,6 +690,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 @@ -677,6 +707,8 @@ # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set CONFIG_RAMFS=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -710,6 +742,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=y CONFIG_NFSD_V3=y @@ -830,6 +863,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -879,6 +914,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 # @@ -899,6 +935,7 @@ # CONFIG_USB_PWC is not set # CONFIG_USB_SE401 is not set # CONFIG_USB_STV680 is not set +# CONFIG_USB_W9968CF is not set # CONFIG_USB_VICAM is not set # CONFIG_USB_DSBR is not set # CONFIG_USB_DABUSB is not set @@ -910,6 +947,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 @@ -933,8 +971,19 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET 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 @@ -967,3 +1016,4 @@ # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_IA64_DEBUG_CMPXCHG is not set # CONFIG_IA64_DEBUG_IRQ is not set +CONFIG_LOG_BUF_SHIFT=0 Index: arch/ia64/configs/ski =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/configs/ski,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/configs/ski 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/configs/ski 4 Aug 2004 01:25:42 -0000 1.2 @@ -22,15 +22,14 @@ # 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 # CONFIG_IA64_DIG is not set CONFIG_IA64_HP_SIM=y # CONFIG_IA64_HP_ZX1 is not set -# CONFIG_IA64_SGI_SN1 is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set @@ -39,7 +38,16 @@ # 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_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_IA64_PAL_IDLE=y CONFIG_SMP=y +CONFIG_NR_CPUS=32 CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y @@ -71,6 +79,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -144,16 +158,15 @@ # 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=253 -CONFIG_AIC7XXX_RESET_DELAY_MS=15000 -# CONFIG_AIC7XXX_PROBE_EISA_VL is not set -# CONFIG_AIC7XXX_BUILD_FIRMWARE 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_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set @@ -245,6 +258,7 @@ # CONFIG_WATCHDOG is not set # CONFIG_SCx200_GPIO is not set # CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -258,6 +272,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -274,6 +292,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 @@ -301,6 +320,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 @@ -310,6 +330,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 @@ -326,6 +347,8 @@ # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set CONFIG_RAMFS=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -359,6 +382,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=y CONFIG_NFSD_V3=y @@ -466,3 +490,4 @@ # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_IA64_DEBUG_CMPXCHG is not set # CONFIG_IA64_DEBUG_IRQ is not set +CONFIG_LOG_BUF_SHIFT=0 Index: arch/ia64/configs/zx1 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/configs/zx1,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/configs/zx1 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/configs/zx1 4 Aug 2004 01:25:42 -0000 1.2 @@ -22,25 +22,36 @@ # 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 # CONFIG_IA64_DIG is not set # CONFIG_IA64_HP_SIM is not set CONFIG_IA64_HP_ZX1=y -# CONFIG_IA64_SGI_SN1 is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set CONFIG_IA64_PAGE_SIZE_16KB=y # CONFIG_IA64_PAGE_SIZE_64KB is not set CONFIG_IA64_L1_CACHE_SHIFT=7 +# CONFIG_NUMA is not set CONFIG_IA64_MCA=y CONFIG_PM=y CONFIG_KCORE_ELF=y +CONFIG_FORCE_MAX_ZONEORDER=19 +# 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_IA64_PAL_IDLE=y CONFIG_SMP=y +CONFIG_NR_CPUS=32 CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y @@ -102,6 +113,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -156,6 +173,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y @@ -242,7 +260,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,13 +274,11 @@ # 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 # 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 @@ -275,7 +291,6 @@ # CONFIG_IDEDMA_AUTO is not set # 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 @@ -321,11 +336,16 @@ CONFIG_AIC7XXX_RESET_DELAY_MS=15000 # 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_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_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -353,7 +373,6 @@ # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y -# CONFIG_SCSI_QLOGIC_QLA2100 is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set @@ -397,6 +416,7 @@ # 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 @@ -424,7 +444,6 @@ # 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 @@ -436,6 +455,7 @@ # CONFIG_ACENIC is not set # CONFIG_DL2K is not set CONFIG_E1000=y +# CONFIG_E1000_NAPI is not set # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set @@ -569,6 +589,7 @@ # CONFIG_WATCHDOG is not set # CONFIG_SCx200_GPIO is not set # CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -586,12 +607,17 @@ # CONFIG_AGP_I810 is not set # CONFIG_AGP_VIA is not set # CONFIG_AGP_AMD is not set -# CONFIG_AGP_AMD_8151 is not set +# CONFIG_AGP_AMD_K8 is not set # CONFIG_AGP_SIS is not set # CONFIG_AGP_ALI is not set # CONFIG_AGP_SWORKS is not set CONFIG_AGP_I460=y CONFIG_AGP_HP_ZX1=y +# CONFIG_AGP_ATI is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# CONFIG_DRM=y # CONFIG_DRM_OLD is not set @@ -600,6 +626,7 @@ # CONFIG_DRM_NEW=y # CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set CONFIG_DRM_R128=y CONFIG_DRM_RADEON=y # CONFIG_DRM_I810 is not set @@ -622,6 +649,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 @@ -646,6 +674,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 @@ -655,6 +684,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 @@ -671,6 +701,8 @@ # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set CONFIG_RAMFS=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -704,6 +736,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=y CONFIG_NFSD_V3=y @@ -824,6 +857,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -873,6 +908,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 # @@ -893,6 +929,7 @@ # CONFIG_USB_PWC is not set # CONFIG_USB_SE401 is not set # CONFIG_USB_STV680 is not set +# CONFIG_USB_W9968CF is not set # CONFIG_USB_VICAM is not set # CONFIG_USB_DSBR is not set # CONFIG_USB_DABUSB is not set @@ -904,6 +941,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 @@ -927,8 +965,19 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET 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 @@ -954,3 +1003,4 @@ # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_IA64_DEBUG_CMPXCHG is not set # CONFIG_IA64_DEBUG_IRQ is not set +CONFIG_LOG_BUF_SHIFT=0 Index: arch/ia64/dig/machvec.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/dig/machvec.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/dig/machvec.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/dig/machvec.c 4 Aug 2004 01:25:42 -0000 1.2 @@ -1,2 +1,3 @@ -#define MACHVEC_PLATFORM_NAME dig +#define MACHVEC_PLATFORM_NAME dig +#define MACHVEC_PLATFORM_HEADER #include Index: arch/ia64/dig/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/dig/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/dig/setup.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/dig/setup.c 4 Aug 2004 01:25:42 -0000 1.2 @@ -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; Index: arch/ia64/hp/common/sba_iommu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/hp/common/sba_iommu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/hp/common/sba_iommu.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/ia64/hp/common/sba_iommu.c 4 Aug 2004 01:25:42 -0000 1.2 @@ -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-2004 Alex Williamson +** (c) Copyright 2002-2003 Grant Grundler +** (c) Copyright 2002-2004 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,17 +30,26 @@ #include #include #include +#include #include #include #include /* ia64_get_itc() */ #include #include /* PAGE_OFFSET */ +#include /* wmb() */ +#include /* hweight64() */ #define PFX "IOC: " /* +** Enabling timing search of the pdir resource map. Output in /proc. +** Disabled by default to optimize performance. +*/ +#undef PDIR_SEARCH_TIMING + +/* ** This option allows cards capable of 64bit DMA to bypass the IOMMU. If ** not defined, all DMA will be 32bit and go through the TLB. */ @@ -118,7 +128,7 @@ #endif /* -** The number of pdir entries to "free" before issueing +** The number of pdir entries to "free" before issuing ** a read to PCOM register to flush out PCOM writes. ** Interacts with allocation granularity (ie 4 or 8 entries ** allocated and free'd/purged at a time might make this @@ -130,6 +140,7 @@ #define ZX1_IOC_ID ((PCI_DEVICE_ID_HP_ZX1_IOC << 16) | PCI_VENDOR_ID_HP) #define REO_IOC_ID ((PCI_DEVICE_ID_HP_REO_IOC << 16) | PCI_VENDOR_ID_HP) +#define SX1000_IOC_ID ((PCI_DEVICE_ID_HP_SX1000_IOC << 16) | PCI_VENDOR_ID_HP) #define ZX1_IOC_OFFSET 0x1000 /* ACPI reports SBA, we want IOC */ @@ -145,21 +156,18 @@ #define ZX1_SBA_IOMMU_COOKIE 0x0000badbadc0ffeeUL /* -** IOC supports 4/8/16/64KB page sizes (see TCNFG register) -** It's safer (avoid memory corruption) to keep DMA page mappings -** equivalently sized to VM PAGE_SIZE. +** The zx1 IOC supports 4/8/16/64KB page sizes (see TCNFG register) ** -** We really can't avoid generating a new mapping for each -** page since the Virtual Coherence Index has to be generated -** and updated for each page. +** Some IOCs (sx1000) can run at the above pages sizes, but are +** really only supported using the IOC at a 4k page size. ** -** IOVP_SIZE could only be greater than PAGE_SIZE if we are +** iovp_size could only be greater than PAGE_SIZE if we are ** confident the drivers really only touch the next physical ** page iff that driver instance owns it. */ -#define IOVP_SIZE PAGE_SIZE -#define IOVP_SHIFT PAGE_SHIFT -#define IOVP_MASK PAGE_MASK +static unsigned long iovp_size; +static unsigned long iovp_shift; +static unsigned long iovp_mask; struct ioc { void *ioc_hpa; /* I/O MMU base address */ @@ -183,24 +191,10 @@ } saved[DELAYED_RESOURCE_CNT]; #endif -#ifdef CONFIG_PROC_FS +#ifdef PDIR_SEARCH_TIMING #define SBA_SEARCH_SAMPLE 0x100 unsigned long avg_search[SBA_SEARCH_SAMPLE]; unsigned long avg_idx; /* current index into avg_search */ - unsigned long used_pages; - unsigned long msingle_calls; - unsigned long msingle_pages; - unsigned long msg_calls; - unsigned long msg_pages; - unsigned long usingle_calls; - unsigned long usingle_pages; - unsigned long usg_calls; - unsigned long usg_pages; -#ifdef ALLOW_IOV_BYPASS - unsigned long msingle_bypass; - unsigned long usingle_bypass; - unsigned long msg_bypass; -#endif #endif /* Stuff we don't need in performance path */ @@ -217,14 +211,22 @@ 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) +#ifdef CONFIG_PCI +# define GET_IOC(dev) ((struct ioc *) PCI_CONTROLLER(dev)->iommu) +#else +# define GET_IOC(dev) NULL +#endif /* ** DMA_CHUNK_SIZE is used by the SCSI mid-layer to break up @@ -233,7 +235,7 @@ ** rather than the HW. I/O MMU allocation alogorithms can be ** faster with smaller size is (to some degree). */ -#define DMA_CHUNK_SIZE (BITS_PER_LONG*PAGE_SIZE) +#define DMA_CHUNK_SIZE (BITS_PER_LONG*iovp_size) #define ROUNDUP(x,y) ((x + ((y)-1)) & ~((y)-1)) @@ -282,24 +284,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 +362,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,17 +399,37 @@ #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_IOVP(ioc,iova) (((iova) & ioc->hint_mask_pdir) & ~(ioc->ibase)) +#define SBA_IOVA(ioc,iovp,offset,hint_reg) ((ioc->ibase) | (iovp) | (offset)) +#define SBA_IOVP(ioc,iova) ((iova) & ~(ioc->ibase)) + +#define PDIR_ENTRY_SIZE sizeof(u64) -/* FIXME : review these macros to verify correctness and usage */ -#define PDIR_INDEX(iovp) ((iovp)>>IOVP_SHIFT) +#define PDIR_INDEX(iovp) ((iovp)>>iovp_shift) #define RESMAP_MASK(n) ~(~0UL << (n)) #define RESMAP_IDX_MASK (sizeof(unsigned long) - 1) /** + * For most cases the normal get_order is sufficient, however it limits us + * to PAGE_SIZE being the minimum mapping alignment and TC flush granularity. + * It only incurs about 1 clock cycle to use this one with the static variable + * and makes the code more intuitive. + */ +static SBA_INLINE int +get_iovp_order (unsigned long size) +{ + long double d = size - 1; + long order; + + __asm__ ("getf.exp %0=%1" : "=r"(order) : "f"(d)); + order = order - iovp_shift - 0xffff + 1; + if (order < 0) + order = 0; + return order; +} + +/** * sba_search_bitmap - find free space in IO PDIR resource bitmap * @ioc: IO MMU structure which owns the pdir we are interested in. * @bits_wanted: number of entries we need. @@ -445,7 +467,7 @@ ** We need the alignment to invalidate I/O TLB using ** SBA HW features in the unmap path. */ - unsigned long o = 1 << get_order(bits_wanted << PAGE_SHIFT); + unsigned long o = 1 << get_iovp_order(bits_wanted << iovp_shift); uint bitshiftcnt = ROUNDUP(ioc->res_bitshift, o); unsigned long mask; @@ -501,16 +523,15 @@ static int sba_alloc_range(struct ioc *ioc, size_t size) { - unsigned int pages_needed = size >> IOVP_SHIFT; -#ifdef CONFIG_PROC_FS + unsigned int pages_needed = size >> iovp_shift; +#ifdef PDIR_SEARCH_TIMING unsigned long itc_start = ia64_get_itc(); #endif unsigned long pide; ASSERT(pages_needed); - ASSERT((pages_needed * IOVP_SIZE) <= DMA_CHUNK_SIZE); ASSERT(pages_needed <= BITS_PER_LONG); - ASSERT(0 == (size & ~IOVP_MASK)); + ASSERT(0 == (size & ~iovp_mask)); /* ** "seek and ye shall find"...praying never hurts either... @@ -520,12 +541,13 @@ 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 /* verify the first enable bit is clear */ - if(0x00 != ((u8 *) ioc->pdir_base)[pide*sizeof(u64) + 7]) { + if(0x00 != ((u8 *) ioc->pdir_base)[pide*PDIR_ENTRY_SIZE + 7]) { sba_dump_pdir_entry(ioc, "sba_search_bitmap() botched it?", pide); } #endif @@ -535,17 +557,9 @@ (uint) ((unsigned long) ioc->res_hint - (unsigned long) ioc->res_map), ioc->res_bitshift ); -#ifdef CONFIG_PROC_FS - { - unsigned long itc_end = ia64_get_itc(); - unsigned long tmp = itc_end - itc_start; - /* check for roll over */ - itc_start = (itc_end < itc_start) ? -(tmp) : (tmp); - } - ioc->avg_search[ioc->avg_idx++] = itc_start; +#ifdef PDIR_SEARCH_TIMING + ioc->avg_search[ioc->avg_idx++] = ia64_get_itc() - itc_start; ioc->avg_idx &= SBA_SEARCH_SAMPLE - 1; - - ioc->used_pages += pages_needed; #endif return (pide); @@ -568,7 +582,7 @@ unsigned int ridx = pide >> 3; /* convert bit to byte address */ unsigned long *res_ptr = (unsigned long *) &((ioc)->res_map[ridx & ~RESMAP_IDX_MASK]); - int bits_not_wanted = size >> IOVP_SHIFT; + int bits_not_wanted = size >> iovp_shift; /* 3-bits "bit" address plus 2 (or 3) bits for "byte" == bit in word */ unsigned long m = RESMAP_MASK(bits_not_wanted) << (pide & (BITS_PER_LONG - 1)); @@ -577,13 +591,9 @@ __FUNCTION__, (uint) iova, size, bits_not_wanted, m, pide, res_ptr, *res_ptr); -#ifdef CONFIG_PROC_FS - ioc->used_pages -= bits_not_wanted; -#endif - ASSERT(m != 0); ASSERT(bits_not_wanted); - ASSERT((bits_not_wanted * IOVP_SIZE) <= DMA_CHUNK_SIZE); + ASSERT((bits_not_wanted * iovp_size) <= DMA_CHUNK_SIZE); ASSERT(bits_not_wanted <= BITS_PER_LONG); ASSERT((*res_ptr & m) == m); /* verify same bits are set */ *res_ptr &= ~m; @@ -625,7 +635,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) @@ -680,7 +691,7 @@ /* Must be non-zero and rounded up */ ASSERT(byte_cnt > 0); - ASSERT(0 == (byte_cnt & ~IOVP_MASK)); + ASSERT(0 == (byte_cnt & ~iovp_mask)); #ifdef ASSERT_PDIR_SANITY /* Assert first pdir entry is set */ @@ -689,11 +700,11 @@ } #endif - if (byte_cnt <= IOVP_SIZE) + if (byte_cnt <= iovp_size) { ASSERT(off < ioc->pdir_size); - iovp |= IOVP_SHIFT; /* set "size" field for PCOM */ + iovp |= iovp_shift; /* set "size" field for PCOM */ #ifndef FULL_VALID_PDIR /* @@ -709,10 +720,10 @@ ** 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; + u32 t = get_iovp_order(byte_cnt) + iovp_shift; iovp |= t; ASSERT(t <= 31); /* 2GB! Max value of "size" field */ @@ -724,10 +735,10 @@ /* 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; + byte_cnt -= iovp_size; } while (byte_cnt > 0); } @@ -739,15 +750,15 @@ * @dev: instance of PCI owned by the driver that's asking. * @addr: driver buffer to map. * @size: number of bytes to map in driver buffer. - * @direction: R/W or both. + * @dir: R/W or both. * * See Documentation/DMA-mapping.txt */ dma_addr_t -sba_map_single(struct pci_dev *dev, void *addr, size_t size, int direction) +sba_map_single(struct pci_dev *dev, void *addr, size_t size, int dir) { struct ioc *ioc; - unsigned long flags; + unsigned long flags; dma_addr_t iovp; dma_addr_t offset; u64 *pdir_start; @@ -768,11 +779,6 @@ ** Device is bit capable of DMA'ing to the buffer... ** just return the PCI address of ptr */ -#ifdef CONFIG_PROC_FS - spin_lock_irqsave(&ioc->res_lock, flags); - ioc->msingle_bypass++; - spin_unlock_irqrestore(&ioc->res_lock, flags); -#endif DBG_BYPASS("sba_map_single() bypass mask/addr: 0x%lx/0x%lx\n", dev->dma_mask, pci_addr); return pci_addr; @@ -783,10 +789,10 @@ ASSERT(size <= DMA_CHUNK_SIZE); /* save offset bits */ - offset = ((dma_addr_t) (long) addr) & ~IOVP_MASK; + offset = ((dma_addr_t) (long) addr) & ~iovp_mask; - /* round up to nearest IOVP_SIZE */ - size = (size + offset + ~IOVP_MASK) & IOVP_MASK; + /* round up to nearest iovp_size */ + size = (size + offset + ~iovp_mask) & iovp_mask; spin_lock_irqsave(&ioc->res_lock, flags); #ifdef ASSERT_PDIR_SANITY @@ -794,12 +800,8 @@ panic("Sanity check failed"); #endif -#ifdef CONFIG_PROC_FS - ioc->msingle_calls++; - ioc->msingle_pages += size >> IOVP_SHIFT; -#endif pide = sba_alloc_range(ioc, size); - iovp = (dma_addr_t) pide << IOVP_SHIFT; + iovp = (dma_addr_t) pide << iovp_shift; DBG_RUN("%s() 0x%p -> 0x%lx\n", __FUNCTION__, addr, (long) iovp | offset); @@ -812,10 +814,13 @@ DBG_RUN(" pdir 0x%p %lx\n", pdir_start, *pdir_start); - addr += IOVP_SIZE; - size -= IOVP_SIZE; + addr += iovp_size; + 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()"); @@ -829,18 +834,17 @@ * @dev: instance of PCI owned by the driver that's asking. * @iova: IOVA of driver buffer previously mapped. * @size: number of bytes mapped in driver buffer. - * @direction: R/W or both. + * @dir: R/W or both. * * See Documentation/DMA-mapping.txt */ -void sba_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size, - int direction) +void sba_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size, int dir) { struct ioc *ioc; #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); @@ -851,35 +855,26 @@ /* ** Address does not fall w/in IOVA, must be bypassing */ -#ifdef CONFIG_PROC_FS - spin_lock_irqsave(&ioc->res_lock, flags); - ioc->usingle_bypass++; - spin_unlock_irqrestore(&ioc->res_lock, flags); -#endif DBG_BYPASS("sba_unmap_single() bypass addr: 0x%lx\n", iova); #ifdef ENABLE_MARK_CLEAN - if (direction == PCI_DMA_FROMDEVICE) { + if (dir == PCI_DMA_FROMDEVICE) { mark_clean(phys_to_virt(iova), size); } #endif return; } #endif - offset = iova & ~IOVP_MASK; + offset = iova & ~iovp_mask; DBG_RUN("%s() iovp 0x%lx/%x\n", __FUNCTION__, (long) iova, size); iova ^= offset; /* clear offset bits */ size += offset; - size = ROUNDUP(size, IOVP_SIZE); + size = ROUNDUP(size, iovp_size); spin_lock_irqsave(&ioc->res_lock, flags); -#ifdef CONFIG_PROC_FS - ioc->usingle_calls++; - ioc->usingle_pages += size >> IOVP_SHIFT; -#endif #if DELAYED_RESOURCE_CNT > 0 d = &(ioc->saved[ioc->saved_cnt]); @@ -901,12 +896,12 @@ READ_REG(ioc->ioc_hpa+IOC_PCOM); /* flush purges */ #endif /* DELAYED_RESOURCE_CNT == 0 */ #ifdef ENABLE_MARK_CLEAN - if (direction == PCI_DMA_FROMDEVICE) { + if (dir == PCI_DMA_FROMDEVICE) { u32 iovp = (u32) SBA_IOVP(ioc,iova); int off = PDIR_INDEX(iovp); void *addr; - if (size <= IOVP_SIZE) { + if (size <= iovp_size) { addr = phys_to_virt(ioc->pdir_base[off] & ~0xE000000000000FFFULL); mark_clean(addr, size); @@ -916,9 +911,9 @@ do { addr = phys_to_virt(ioc->pdir_base[off] & ~0xE000000000000FFFULL); - mark_clean(addr, min(byte_cnt, IOVP_SIZE)); + mark_clean(addr, min(byte_cnt, iovp_size)); off++; - byte_cnt -= IOVP_SIZE; + byte_cnt -= iovp_size; } while (byte_cnt > 0); } @@ -932,61 +927,57 @@ ** 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"); */ } /** - * sba_alloc_consistent - allocate/map shared mem for DMA - * @hwdev: instance of PCI owned by the driver that's asking. + * sba_alloc_coherent - allocate/map shared mem for DMA + * @dev: instance of PCI owned by the driver that's asking. * @size: number of bytes mapped in driver buffer. * @dma_handle: IOVA of new buffer. * * See Documentation/DMA-mapping.txt */ void * -sba_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle) +sba_alloc_coherent (struct pci_dev *dev, size_t size, dma_addr_t *dma_handle) { struct ioc *ioc; - void *ret; + void *addr; - if (!hwdev) { - /* only support PCI */ - *dma_handle = 0; - return 0; - } + if (!dev) + return NULL; /* only support PCI */ - ret = (void *) __get_free_pages(GFP_ATOMIC, get_order(size)); + addr = (void *) __get_free_pages(GFP_ATOMIC, get_order(size)); + if (!addr) + return NULL; - if (ret) { - memset(ret, 0, size); - /* - * REVISIT: if sba_map_single starts needing more - * than dma_mask from the device, this needs to be - * updated. - */ - ioc = GET_IOC(hwdev); - *dma_handle = sba_map_single(ioc->sac_only_dev, ret, size, 0); - } + /* + * REVISIT: if sba_map_single starts needing more than dma_mask from the + * device, this needs to be updated. + */ + ioc = GET_IOC(dev); + ASSERT(ioc); + *dma_handle = sba_map_single(ioc->sac_only_dev, addr, size, 0); - return ret; + memset(addr, 0, size); + return addr; } /** - * sba_free_consistent - free/unmap shared mem for DMA - * @hwdev: instance of PCI owned by the driver that's asking. + * sba_free_coherent - free/unmap shared mem for DMA + * @dev: instance of PCI owned by the driver that's asking. * @size: number of bytes mapped in driver buffer. * @vaddr: virtual address IOVA of "consistent" buffer. * @dma_handler: IO virtual address of "consistent" buffer. * * See Documentation/DMA-mapping.txt */ -void sba_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, - dma_addr_t dma_handle) +void sba_free_coherent (struct pci_dev *dev, size_t size, void *vaddr, dma_addr_t dma_handle) { - sba_unmap_single(hwdev, dma_handle, size, 0); + sba_unmap_single(dev, dma_handle, size, 0); free_pages((unsigned long) vaddr, get_order(size)); } @@ -1044,11 +1035,11 @@ */ if (startsg->dma_address & PIDE_FLAG) { u32 pide = startsg->dma_address & ~PIDE_FLAG; - dma_offset = (unsigned long) pide & ~IOVP_MASK; + dma_offset = (unsigned long) pide & ~iovp_mask; startsg->dma_address = 0; dma_sg++; dma_sg->dma_address = pide | ioc->ibase; - pdirp = &(ioc->pdir_base[pide >> IOVP_SHIFT]); + pdirp = &(ioc->pdir_base[pide >> iovp_shift]); n_mappings++; } @@ -1065,19 +1056,19 @@ dma_sg->dma_length += cnt; cnt += dma_offset; dma_offset=0; /* only want offset on first chunk */ - cnt = ROUNDUP(cnt, IOVP_SIZE); -#ifdef CONFIG_PROC_FS - ioc->msg_pages += cnt >> IOVP_SHIFT; -#endif + cnt = ROUNDUP(cnt, iovp_size); do { sba_io_pdir_entry(pdirp, vaddr); - vaddr += IOVP_SIZE; - cnt -= IOVP_SIZE; + vaddr += iovp_size; + cnt -= iovp_size; pdirp++; } while (cnt > 0); } startsg++; } + /* force pdir update */ + wmb(); + #ifdef DEBUG_LARGE_SG_ENTRIES dump_run_sg = 0; #endif @@ -1087,12 +1078,12 @@ /* ** Two address ranges are DMA contiguous *iff* "end of prev" and -** "start of next" are both on a page boundry. +** "start of next" are both on an IOV page boundary. ** ** (shift left is a quick trick to mask off upper bits) */ #define DMA_CONTIG(__X, __Y) \ - (((((unsigned long) __X) | ((unsigned long) __Y)) << (BITS_PER_LONG - PAGE_SHIFT)) == 0UL) + (((((unsigned long) __X) | ((unsigned long) __Y)) << (BITS_PER_LONG - iovp_shift)) == 0UL) /** @@ -1105,7 +1096,7 @@ * in the DMA stream. Allocates PDIR entries but does not fill them. * Returns the number of DMA chunks. * - * Doing the fill seperate from the coalescing/allocation keeps the + * Doing the fill separate from the coalescing/allocation keeps the * code simpler. Future enhancement could make one pass through * the sglist do both. */ @@ -1122,7 +1113,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 @@ -1130,7 +1121,7 @@ dma_sg = vcontig_sg = startsg; dma_len = vcontig_len = vcontig_end = startsg->length; vcontig_end += vaddr; - dma_offset = vaddr & ~IOVP_MASK; + dma_offset = vaddr & ~iovp_mask; /* PARANOID: clear entries */ startsg->dma_address = startsg->dma_length = 0; @@ -1155,7 +1146,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; /* @@ -1173,7 +1165,7 @@ } #ifdef DEBUG_LARGE_SG_ENTRIES - dump_run_sg = (vcontig_len > IOVP_SIZE); + dump_run_sg = (vcontig_len > iovp_size); #endif /* @@ -1212,10 +1204,10 @@ ** Allocate space for DMA stream. */ vcontig_sg->dma_length = vcontig_len; - dma_len = (dma_len + dma_offset + ~IOVP_MASK) & IOVP_MASK; + dma_len = (dma_len + dma_offset + ~iovp_mask) & iovp_mask; ASSERT(dma_len <= DMA_CHUNK_SIZE); - dma_sg->dma_address = (dma_addr_t) (PIDE_FLAG - | (sba_alloc_range(ioc, dma_len) << IOVP_SHIFT) + dma_sg->dma_address = (dma_addr_t) (PIDE_FLAG + | (sba_alloc_range(ioc, dma_len) << iovp_shift) | dma_offset); n_mappings++; } @@ -1229,12 +1221,11 @@ * @dev: instance of PCI owned by the driver that's asking. * @sglist: array of buffer/length pairs * @nents: number of entries in list - * @direction: R/W or both. + * @dir: R/W or both. * * 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 dir) { struct ioc *ioc; int coalesced, filled = 0; @@ -1253,26 +1244,14 @@ sg->dma_length = sg->length; sg->dma_address = virt_to_phys(sba_sg_address(sg)); } -#ifdef CONFIG_PROC_FS - spin_lock_irqsave(&ioc->res_lock, flags); - ioc->msg_bypass++; - spin_unlock_irqrestore(&ioc->res_lock, flags); -#endif return filled; } #endif /* Fast path single entry scatterlists. */ if (nents == 1) { sglist->dma_length = sglist->length; - sglist->dma_address = sba_map_single(dev, - sba_sg_address(sglist), - sglist->length, direction); -#ifdef CONFIG_PROC_FS - /* - ** Should probably do some stats counting, but trying to - ** be precise quickly starts wasting CPU time. - */ -#endif + sglist->dma_address = sba_map_single(dev, sba_sg_address(sglist), sglist->length, + dir); return 1; } @@ -1286,10 +1265,6 @@ } #endif -#ifdef CONFIG_PROC_FS - ioc->msg_calls++; -#endif - /* ** First coalesce the chunks and allocate I/O pdir space ** @@ -1299,13 +1274,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); @@ -1332,12 +1307,11 @@ * @dev: instance of PCI owned by the driver that's asking. * @sglist: array of buffer/length pairs * @nents: number of entries in list - * @direction: R/W or both. + * @dir: R/W or both. * * See Documentation/DMA-mapping.txt */ -void sba_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, - int direction) +void sba_unmap_sg (struct pci_dev *dev, struct scatterlist *sglist, int nents, int dir) { struct ioc *ioc; #ifdef ASSERT_PDIR_SANITY @@ -1350,10 +1324,6 @@ ioc = GET_IOC(dev); ASSERT(ioc); -#ifdef CONFIG_PROC_FS - ioc->usg_calls++; -#endif - #ifdef ASSERT_PDIR_SANITY spin_lock_irqsave(&ioc->res_lock, flags); sba_check_pdir(ioc,"Check before sba_unmap_sg()"); @@ -1362,17 +1332,7 @@ while (nents && sglist->dma_length) { - sba_unmap_single(dev, sglist->dma_address, - sglist->dma_length, direction); -#ifdef CONFIG_PROC_FS - /* - ** This leaves inconsistent data in the stats, but we can't - ** tell which sg lists were mapped by map_single and which - ** 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; -#endif + sba_unmap_single(dev, sglist->dma_address, sglist->dma_length, dir); sglist++; nents--; } @@ -1387,12 +1347,6 @@ } -int -sba_dma_supported (struct pci_dev *dev, u64 mask) -{ - return 1; -} - /************************************************************** * * Initialization and claim @@ -1402,10 +1356,9 @@ static void __init ioc_iova_init(struct ioc *ioc) { - u32 iova_space_mask; - int iov_order, tcnfg; + int tcnfg; int agp_found = 0; - struct pci_dev *device; + struct pci_dev *device = NULL; #ifdef FULL_VALID_PDIR unsigned long index; #endif @@ -1416,36 +1369,27 @@ ** IBASE and IMASK registers. */ ioc->ibase = READ_REG(ioc->ioc_hpa + IOC_IBASE) & ~0x1UL; - ioc->iov_size = ~(READ_REG(ioc->ioc_hpa + IOC_IMASK) & 0xFFFFFFFFUL) + 1; + ioc->imask = READ_REG(ioc->ioc_hpa + IOC_IMASK) | 0xFFFFFFFF00000000UL; - 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); - } + ioc->iov_size = ~ioc->imask + 1; - 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; + DBG_INIT("%s() hpa %p IOV base 0x%lx mask 0x%lx (%dMB)\n", + __FUNCTION__, ioc->ioc_hpa, ioc->ibase, ioc->imask, + ioc->iov_size >> 20); + + switch (iovp_size) { + case 4*1024: tcnfg = 0; break; + case 8*1024: tcnfg = 1; break; + case 16*1024: tcnfg = 2; break; + case 64*1024: tcnfg = 3; break; + default: + panic(PFX "Unsupported IOTLB page size %ldK", + iovp_size >> 10); + break; } + WRITE_REG(tcnfg, ioc->ioc_hpa + IOC_TCNFG); - /* - ** iov_order is always based on a 1GB IOVA space since we want to - ** turn on the other half for AGP GART. - */ - 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); - - /* FIXME : DMA HINTs not used */ - ioc->hint_shift_pdir = iov_order + PAGE_SHIFT; - ioc->hint_mask_pdir = ~(0x3 << (iov_order + PAGE_SHIFT)); - + ioc->pdir_size = (ioc->iov_size / iovp_size) * PDIR_ENTRY_SIZE; ioc->pdir_base = (void *) __get_free_pages(GFP_KERNEL, get_order(ioc->pdir_size)); if (!ioc->pdir_base) @@ -1453,61 +1397,12 @@ memset(ioc->pdir_base, 0, ioc->pdir_size); - DBG_INIT("%s() pdir %p size %x hint_shift_pdir %x hint_mask_pdir %lx\n", - __FUNCTION__, ioc->pdir_base, ioc->pdir_size, - ioc->hint_shift_pdir, ioc->hint_mask_pdir); + DBG_INIT("%s() IOV page size %ldK pdir %p size %x\n", __FUNCTION__, + iovp_size >> 10, ioc->pdir_base, ioc->pdir_size); - ASSERT((((unsigned long) ioc->pdir_base) & PAGE_MASK) == (unsigned long) ioc->pdir_base); + ASSERT(ALIGN((unsigned long) ioc->pdir_base, 4*1024) == (unsigned long) ioc->pdir_base); WRITE_REG(virt_to_phys(ioc->pdir_base), ioc->ioc_hpa + IOC_PDIR_BASE); - DBG_INIT(" base %p\n", ioc->pdir_base); - - /* build IMASK for IOC and Elroy */ - iova_space_mask = 0xffffffff; - iova_space_mask <<= (iov_order + PAGE_SHIFT); - ioc->imask = iova_space_mask; - - DBG_INIT("%s() IOV base 0x%lx mask 0x%0lx\n", - __FUNCTION__, ioc->ibase, ioc->imask); - - /* - ** FIXME: Hint registers are programmed with default hint - ** values during boot, so hints should be sane even if we - ** can't reprogram them the way drivers want. - */ - WRITE_REG(ioc->imask, ioc->ioc_hpa + IOC_IMASK); - - /* - ** Setting the upper bits makes checking for bypass addresses - ** a little faster later on. - */ - ioc->imask |= 0xFFFFFFFF00000000UL; - - /* Set I/O PDIR Page size to system page size */ - switch (PAGE_SHIFT) { - case 12: tcnfg = 0; break; /* 4K */ - case 13: tcnfg = 1; break; /* 8K */ - case 14: tcnfg = 2; break; /* 16K */ - case 16: tcnfg = 3; break; /* 64K */ - default: - panic(PFX "Unsupported system page size %d", - 1 << PAGE_SHIFT); - break; - } - WRITE_REG(tcnfg, ioc->ioc_hpa + IOC_TCNFG); - - /* - ** Program the IOC's ibase and enable IOVA translation - ** Bit zero == enable bit. - */ - WRITE_REG(ioc->ibase | 1, ioc->ioc_hpa + IOC_IBASE); - - /* - ** Clear I/O TLB of any possible entries. - ** (Yes. This is a bit paranoid...but so what) - */ - WRITE_REG(ioc->ibase | (iov_order+PAGE_SHIFT), ioc->ioc_hpa + IOC_PCOM); - /* ** If an AGP device is present, only use half of the IOV space ** for PCI DMA. Unfortunately we can't know ahead of time @@ -1516,11 +1411,12 @@ ** We program the next pdir index after we stop w/ a key for ** the GART code to handshake on. */ - pci_for_each_dev(device) + while ((device = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device)) != NULL) 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__); + printk(KERN_INFO PFX "reserving %dMb of IOVA space at 0x%lx for agpgart\n", + ioc->iov_size/2 >> 20, ioc->ibase + ioc->iov_size/2); ioc->pdir_size /= 2; ((u64 *)ioc->pdir_base)[PDIR_INDEX(ioc->iov_size/2)] = ZX1_SBA_IOMMU_COOKIE; } @@ -1532,26 +1428,34 @@ 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); + for (index = 0 ; index < (ioc->pdir_size / PDIR_ENTRY_SIZE) ; index++) + ((u64 *)ioc->pdir_base)[index] = (0x80000000000000FF | prefetch_spill_page); #endif + + /* Clear I/O TLB of any possible entries */ + WRITE_REG(ioc->ibase | (get_iovp_order(ioc->iov_size) + iovp_shift), ioc->ioc_hpa + IOC_PCOM); + READ_REG(ioc->ioc_hpa + IOC_PCOM); + + /* Enable IOVA translation */ + WRITE_REG(ioc->ibase | 1, ioc->ioc_hpa + IOC_IBASE); + READ_REG(ioc->ioc_hpa + IOC_IBASE); } static void __init @@ -1560,7 +1464,7 @@ spin_lock_init(&ioc->res_lock); /* resource map size dictated by pdir_size */ - ioc->res_size = ioc->pdir_size / sizeof(u64); /* entries */ + ioc->res_size = ioc->pdir_size / PDIR_ENTRY_SIZE; /* entries */ ioc->res_size >>= 3; /* convert bit count to byte count */ DBG_INIT("%s() res_size 0x%x\n", __FUNCTION__, ioc->res_size); @@ -1581,7 +1485,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 / PDIR_ENTRY_SIZE) - 1] = (0x80000000000000FF + | prefetch_spill_page); #endif DBG_INIT("%s() res_map %x %p\n", __FUNCTION__, @@ -1595,7 +1500,7 @@ struct pci_controller *controller = NULL; /* - * pci_alloc_consistent() must return a DMA address which is + * pci_alloc_coherent() must return a DMA address which is * SAC (single address cycle) addressable, so allocate a * pseudo-device to enforce that. */ @@ -1622,6 +1527,23 @@ panic(PFX "IOC 2.0 or later required for IOMMU support\n"); ioc->dma_mask = 0xFFFFFFFFFFUL; + + if (!iovp_shift) { + /* 64k is max iommu page size */ + iovp_shift = min(PAGE_SHIFT, 16); + iovp_size = (1 << iovp_shift); + iovp_mask = ~(iovp_size - 1); + } +} + +static void __init +ioc_sx1000_init(struct ioc *ioc) +{ + if (!iovp_shift) { + iovp_shift = 12; /* 4K for now */ + iovp_size = (1 << iovp_shift); + iovp_mask = ~(iovp_size - 1); + } } typedef void (initfunc)(struct ioc *); @@ -1634,7 +1556,8 @@ static struct ioc_iommu ioc_iommu_info[] __initdata = { { ZX1_IOC_ID, "zx1", ioc_zx1_init }, - { REO_IOC_ID, "REO" }, + { REO_IOC_ID, "REO", ioc_sx1000_init }, + { SX1000_IOC_ID, "sx1000", ioc_sx1000_init }, }; static struct ioc * __init @@ -1659,6 +1582,11 @@ ioc->rev = READ_REG(ioc->ioc_hpa + IOC_FCLASS) & 0xFFUL; ioc->dma_mask = 0xFFFFFFFFFFFFFFFFUL; /* conservative */ + if (iovp_shift) { + iovp_size = (1 << iovp_shift); + iovp_mask = ~(iovp_size - 1); + } + for (info = ioc_iommu_info; info < ioc_iommu_info + ARRAY_SIZE(ioc_iommu_info); info++) { if (ioc->func_id == info->func_id) { ioc->name = info->name; @@ -1666,13 +1594,14 @@ (info->init)(ioc); } } + DBG_INIT("%s: PAGE_SIZE %ldK, iovp_size %ldK\n", __FUNCTION__, + PAGE_SIZE >> 10, iovp_size >> 10); if (!ioc->name) { ioc->name = kmalloc(24, GFP_KERNEL); if (ioc->name) - sprintf(ioc->name, "Unknown (%04x:%04x)", - ioc->func_id & 0xFFFF, - (ioc->func_id >> 16) & 0xFFFF); + sprintf((char *) ioc->name, "Unknown (%04x:%04x)", + ioc->func_id & 0xFFFF, (ioc->func_id >> 16) & 0xFFFF); else ioc->name = "Unknown"; } @@ -1701,119 +1630,120 @@ **************************************************************************/ #ifdef CONFIG_PROC_FS -static int -sba_proc_info_one(char *buf, struct ioc *ioc) +static void * +ioc_start(struct seq_file *s, loff_t *pos) { - int total_pages = (int) (ioc->res_size << 3); /* 8 bits per byte */ - unsigned long i = 0, avg = 0, min, max; + struct ioc *ioc; + loff_t n = *pos; - sprintf(buf, "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, - (int) ((ioc->res_size << 3) * sizeof(u64)), /* 8 bits/byte */ - total_pages); - - sprintf(buf, "%sIO PDIR entries : %ld free %ld used (%d%%)\n", buf, - 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 */ - - min = max = ioc->avg_search[0]; - for (i = 0; i < SBA_SEARCH_SAMPLE; i++) { - avg += ioc->avg_search[i]; - if (ioc->avg_search[i] > max) max = ioc->avg_search[i]; - 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); - - sprintf(buf, "%spci_map_single(): %12ld calls %12ld pages (avg %d/1000)\n", - buf, 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); -#endif + for (ioc = ioc_list; ioc; ioc = ioc->next) + if (!n--) + return ioc; - sprintf(buf, "%spci_unmap_single: %12ld calls %12ld pages (avg %d/1000)\n", - buf, 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); -#endif + return NULL; +} - sprintf(buf, "%spci_map_sg() : %12ld calls %12ld pages (avg %d/1000)\n", - buf, 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); -#endif +static void * +ioc_next(struct seq_file *s, void *v, loff_t *pos) +{ + struct ioc *ioc = v; - sprintf(buf, "%spci_unmap_sg() : %12ld calls %12ld pages (avg %d/1000)\n", - buf, ioc->usg_calls, ioc->usg_pages, - (int) ((ioc->usg_pages * 1000)/ioc->usg_calls)); + ++*pos; + return ioc->next; +} - return strlen(buf); +static void +ioc_stop(struct seq_file *s, void *v) +{ } static int -sba_proc_info(char *buf, char **start, off_t offset, int len) +ioc_show(struct seq_file *s, void *v) { - struct ioc *ioc; - char *base = buf; + struct ioc *ioc = v; + unsigned long *res_ptr = (unsigned long *)ioc->res_map; + int i, used = 0; - for (ioc = ioc_list; ioc; ioc = ioc->next) { - buf += sba_proc_info_one(buf, ioc); - } + seq_printf(s, "Hewlett Packard %s IOC rev %d.%d\n", + ioc->name, ((ioc->rev >> 4) & 0xF), (ioc->rev & 0xF)); + seq_printf(s, "IOVA size : %d MB\n", ioc->iov_size/(1024*1024)); + seq_printf(s, "IOVA page size : %ld kb\n", iovp_size/1024); - return strlen(base); -} + for (i = 0; i < (ioc->res_size / sizeof(unsigned long)); ++i, ++res_ptr) + used += hweight64(*res_ptr); -static int -sba_resource_map_one(char *buf, struct ioc *ioc) -{ - unsigned int *res_ptr = (unsigned int *)ioc->res_map; - int i; + seq_printf(s, "PDIR size : %d entries\n", ioc->res_size << 3); + seq_printf(s, "PDIR used : %d entries\n", used); - 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); +#ifdef PDIR_SEARCH_TIMING + { + unsigned long i = 0, avg = 0, min, max; + min = max = ioc->avg_search[0]; + for (i = 0; i < SBA_SEARCH_SAMPLE; i++) { + avg += ioc->avg_search[i]; + if (ioc->avg_search[i] > max) max = ioc->avg_search[i]; + if (ioc->avg_search[i] < min) min = ioc->avg_search[i]; + } + avg /= SBA_SEARCH_SAMPLE; + seq_printf(s, "Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", + min, avg, max); } - strcat(buf, "\n"); - - return strlen(buf); +#endif +#ifndef ALLOW_IOV_BYPASS + seq_printf(s, "IOVA bypass disabled\n"); +#endif + return 0; } +static struct seq_operations ioc_seq_ops = { + .start = ioc_start, + .next = ioc_next, + .stop = ioc_stop, + .show = ioc_show +}; + static int -sba_resource_map(char *buf, char **start, off_t offset, int len) +ioc_open(struct inode *inode, struct file *file) { - struct ioc *ioc; - char *base = buf; + return seq_open(file, &ioc_seq_ops); +} - for (ioc = ioc_list; ioc; ioc = ioc->next) { - buf += sba_resource_map_one(buf, ioc); - } +static struct file_operations ioc_fops = { + .open = ioc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release +}; - return strlen(base); +static void __init +ioc_proc_init(void) +{ + struct proc_dir_entry *dir, *entry; + + dir = proc_mkdir("bus/mckinley", 0); + if (!dir) + return; + + entry = create_proc_entry(ioc_list->name, 0, dir); + if (entry) + entry->proc_fops = &ioc_fops; } #endif -void -sba_enable_device(struct pci_dev *dev) +static void +sba_connect_bus(struct pci_bus *bus) { acpi_handle handle, parent; acpi_status status; struct ioc *ioc; - handle = PCI_CONTROLLER(dev)->acpi_handle; + if (!PCI_CONTROLLER(bus)) + panic(PFX "no sysdata on bus %d!\n", bus->number); + + if (PCI_CONTROLLER(bus)->iommu) + return; + + handle = PCI_CONTROLLER(bus)->acpi_handle; if (!handle) return; @@ -1825,7 +1755,7 @@ do { for (ioc = ioc_list; ioc; ioc = ioc->next) if (ioc->handle == handle) { - PCI_CONTROLLER(dev)->iommu = ioc; + PCI_CONTROLLER(bus)->iommu = ioc; return; } @@ -1833,40 +1763,38 @@ handle = parent; } while (ACPI_SUCCESS(status)); - printk("No IOC for %s in ACPI\n", dev->slot_name); + printk(KERN_WARNING "No IOC for PCI Bus %04x:%02x in ACPI\n", PCI_SEGMENT(bus), bus->number); } +extern acpi_status acpi_hp_csr_space (acpi_handle obj, u64 *csr_base, u64 *csr_length); + static int __init acpi_sba_ioc_add(struct acpi_device *device) { struct ioc *ioc; acpi_status status; u64 hpa, length; + struct acpi_buffer buffer; + struct 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); + buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; + status = acpi_get_object_info(device->handle, &buffer); if (ACPI_FAILURE(status)) return 1; + dev_info = buffer.pointer; + + /* + * 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.value, 7) == 0) + hpa += ZX1_IOC_OFFSET; + ACPI_MEM_FREE(dev_info); + ioc = ioc_init(hpa, device->handle); if (!ioc) return 1; @@ -1875,41 +1803,30 @@ } static struct acpi_driver acpi_sba_ioc_driver = { - name: "IOC IOMMU Driver", - ids: "HWP0001", - ops: { - add: acpi_sba_ioc_add, - }, -}; - -static struct acpi_driver acpi_ioc_driver = { - name: "IOC IOMMU Driver", - ids: "HWP0004", - ops: { - add: acpi_ioc_add, - }, + .name = "IOC IOMMU Driver", + .ids = "HWP0001,HWP0004", + .ops = { + .add = acpi_sba_ioc_add, + }, }; void __init -ioc_acpi_init(void) +sba_init(void) { acpi_bus_register_driver(&acpi_sba_ioc_driver); - acpi_bus_register_driver(&acpi_ioc_driver); -} + if (!ioc_list) + return; -void __init -sba_init(void) -{ - ioc_acpi_init(); +#ifdef CONFIG_PCI + { + struct pci_bus *b = NULL; + pci_for_each_bus(b) + sba_connect_bus(b); + } +#endif #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,13 +1837,43 @@ 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); +static int __init +sba_page_override(char *str) +{ + unsigned long page_size; + + page_size = memparse(str, &str); + switch (page_size) { + case 4096: + case 8192: + case 16384: + case 65536: + iovp_shift = ffs(page_size) - 1; + break; + default: + printk("%s: unknown/unsupported iommu page size %ld\n", + __FUNCTION__, page_size); + } + + return 1; +} + +__setup("sbapagesize=",sba_page_override); + EXPORT_SYMBOL(sba_init); EXPORT_SYMBOL(sba_map_single); EXPORT_SYMBOL(sba_unmap_single); EXPORT_SYMBOL(sba_map_sg); EXPORT_SYMBOL(sba_unmap_sg); EXPORT_SYMBOL(sba_dma_supported); -EXPORT_SYMBOL(sba_alloc_consistent); -EXPORT_SYMBOL(sba_free_consistent); +EXPORT_SYMBOL(sba_alloc_coherent); +EXPORT_SYMBOL(sba_free_coherent); Index: arch/ia64/hp/sim/hpsim_console.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/hp/sim/hpsim_console.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/hp/sim/hpsim_console.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/ia64/hp/sim/hpsim_console.c 4 Aug 2004 01:25:42 -0000 1.2 @@ -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 Index: arch/ia64/hp/sim/hpsim_irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/hp/sim/hpsim_irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/hp/sim/hpsim_irq.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/ia64/hp/sim/hpsim_irq.c 4 Aug 2004 01:25:42 -0000 1.2 @@ -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 Index: arch/ia64/hp/sim/hpsim_machvec.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/hp/sim/hpsim_machvec.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/hp/sim/hpsim_machvec.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/ia64/hp/sim/hpsim_machvec.c 4 Aug 2004 01:25:42 -0000 1.2 @@ -1,2 +1,3 @@ -#define MACHVEC_PLATFORM_NAME hpsim +#define MACHVEC_PLATFORM_NAME hpsim +#define MACHVEC_PLATFORM_HEADER #include Index: arch/ia64/hp/zx1/hpzx1_machvec.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/hp/zx1/hpzx1_machvec.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/hp/zx1/hpzx1_machvec.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/ia64/hp/zx1/hpzx1_machvec.c 4 Aug 2004 01:25:42 -0000 1.2 @@ -1,2 +1,3 @@ -#define MACHVEC_PLATFORM_NAME hpzx1 +#define MACHVEC_PLATFORM_NAME hp +#define MACHVEC_PLATFORM_HEADER #include Index: arch/ia64/hp/zx1/hpzx1_misc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/hp/zx1/hpzx1_misc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/hp/zx1/hpzx1_misc.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/ia64/hp/zx1/hpzx1_misc.c 4 Aug 2004 01:25:42 -0000 1.2 @@ -17,7 +17,7 @@ #include #include -#define PFX "hpzx1: " +#define PFX static int hpzx1_devices; @@ -50,7 +50,14 @@ fake_dev->sizing = 0; \ return PCIBIOS_SUCCESSFUL; \ } \ - *value = read##sz(fake_dev->mapped_csrs + where); \ + switch (where & ~0x7) { \ + case 0x48: /* initiates config cycles */ \ + case 0x78: /* elroy suspend mode register */ \ + *value = 0; \ + break; \ + default: \ + *value = read##sz(fake_dev->mapped_csrs + where); \ + } \ if (where == PCI_COMMAND) \ *value |= PCI_COMMAND_MEMORY; /* SBA omits this */ \ return PCIBIOS_SUCCESSFUL; \ @@ -68,8 +75,14 @@ if (value == (u##bits) ~0) \ fake_dev->sizing = 1; \ return PCIBIOS_SUCCESSFUL; \ - } else \ - write##sz(value, fake_dev->mapped_csrs + where); \ + } \ + switch (where & ~0x7) { \ + case 0x48: /* initiates config cycles */ \ + case 0x78: /* elroy suspend mode register */ \ + break; \ + default: \ + write##sz(value, fake_dev->mapped_csrs + where); \ + } \ return PCIBIOS_SUCCESSFUL; \ } @@ -210,7 +223,7 @@ { u64 csr_base = 0, csr_length = 0; acpi_status status; - NATIVE_UINT busnum; + acpi_native_uint busnum; char *name = context; char fullname[32]; Index: arch/ia64/ia32/binfmt_elf32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/ia32/binfmt_elf32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/ia32/binfmt_elf32.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/ia32/binfmt_elf32.c 4 Aug 2004 01:25:42 -0000 1.2 @@ -44,7 +44,7 @@ static void elf32_set_personality (void); -#define ELF_PLAT_INIT(_r) ia64_elf32_init(_r) +#define ELF_PLAT_INIT(_r, load_addr) ia64_elf32_init(_r) #define setup_arg_pages(bprm) ia32_setup_arg_pages(bprm) #define elf_map elf32_map @@ -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 Index: arch/ia64/ia32/ia32_entry.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/ia32/ia32_entry.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/ia32/ia32_entry.S 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/ia32/ia32_entry.S 4 Aug 2004 01:25:42 -0000 1.2 @@ -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] @@ -131,6 +138,19 @@ ;; st8 [r2]=r3 // initialize return code to -ENOSYS br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch syscall args + // Need to reload arguments (they may be changed by the tracing process) + adds r2=IA64_PT_REGS_R9_OFFSET+16,sp // r2 = &pt_regs.r9 + adds r3=IA64_PT_REGS_R13_OFFSET+16,sp // r3 = &pt_regs.r13 + ;; + ld4 r33=[r2],8 // r9 == ecx + ld4 r37=[r3],16 // r13 == ebp + ;; + ld4 r34=[r2],8 // r10 == edx + ld4 r36=[r3],8 // r15 == edi + ;; + ld4 r32=[r2],8 // r11 == ebx + ld4 r35=[r3],8 // r14 == esi + ;; .ret2: br.call.sptk.few rp=b6 // do the syscall .ia32_strace_check_retval: cmp.lt p6,p0=r8,r0 // syscall failed? Index: arch/ia64/ia32/ia32_ioctl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/ia32/ia32_ioctl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/ia32/ia32_ioctl.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/ia32/ia32_ioctl.c 4 Aug 2004 01:25:42 -0000 1.2 @@ -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; } Index: arch/ia64/ia32/ia32_signal.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/ia32/ia32_signal.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/ia32/ia32_signal.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/ia32/ia32_signal.c 4 Aug 2004 01:25:42 -0000 1.2 @@ -171,8 +171,10 @@ * datasel ar.fdr(32:47) * * _st[(0+TOS)%8] f8 - * _st[(1+TOS)%8] f9 (f8, f9 from ptregs) - * : : : (f10..f15 from live reg) + * _st[(1+TOS)%8] f9 + * _st[(2+TOS)%8] f10 + * _st[(3+TOS)%8] f11 (f8..f11 from ptregs) + * : : : (f12..f15 from live reg) * : : : * _st[(7+TOS)%8] f15 TOS=sw.top(bits11:13) * @@ -254,8 +256,8 @@ __put_user( 0, &save->magic); //#define X86_FXSR_MAGIC 0x0000 /* - * save f8 and f9 from pt_regs - * save f10..f15 from live register set + * save f8..f11 from pt_regs + * save f12..f15 from live register set */ /* * Find the location where f8 has to go in fp reg stack. This depends on @@ -270,11 +272,11 @@ copy_to_user(&save->_st[(0+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32)); ia64f2ia32f(fpregp, &ptp->f9); copy_to_user(&save->_st[(1+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32)); - - __stfe(fpregp, 10); + ia64f2ia32f(fpregp, &ptp->f10); copy_to_user(&save->_st[(2+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32)); - __stfe(fpregp, 11); + ia64f2ia32f(fpregp, &ptp->f11); copy_to_user(&save->_st[(3+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32)); + __stfe(fpregp, 12); copy_to_user(&save->_st[(4+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32)); __stfe(fpregp, 13); @@ -386,8 +388,8 @@ asm volatile ( "mov ar.fdr=%0;" :: "r"(fdr)); /* - * restore f8, f9 onto pt_regs - * restore f10..f15 onto live registers + * restore f8..f11 onto pt_regs + * restore f12..f15 onto live registers */ /* * Find the location where f8 has to go in fp reg stack. This depends on @@ -403,11 +405,11 @@ ia32f2ia64f(&ptp->f8, fpregp); copy_from_user(fpregp, &save->_st[(1+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32)); ia32f2ia64f(&ptp->f9, fpregp); - copy_from_user(fpregp, &save->_st[(2+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32)); - __ldfe(10, fpregp); + ia32f2ia64f(&ptp->f10, fpregp); copy_from_user(fpregp, &save->_st[(3+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32)); - __ldfe(11, fpregp); + ia32f2ia64f(&ptp->f11, fpregp); + copy_from_user(fpregp, &save->_st[(4+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32)); __ldfe(12, fpregp); copy_from_user(fpregp, &save->_st[(5+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32)); @@ -613,7 +615,7 @@ return -EFAULT; } set_fs(KERNEL_DS); - ret = sys_rt_sigtimedwait(&s, &info, &t, sigsetsize); + ret = sys_rt_sigtimedwait(&s, uinfo ? &info : NULL, uts ? &t : NULL, sigsetsize); set_fs(old_fs); if (ret >= 0 && uinfo) { if (copy_siginfo_to_user32(uinfo, &info)) @@ -739,11 +741,11 @@ #define COPY(ia64x, ia32x) err |= __get_user(regs->ia64x, &sc->ia32x) -#define copyseg_gs(tmp) (regs->r16 |= (unsigned long) tmp << 48) -#define copyseg_fs(tmp) (regs->r16 |= (unsigned long) tmp << 32) +#define copyseg_gs(tmp) (regs->r16 |= (unsigned long) (tmp) << 48) +#define copyseg_fs(tmp) (regs->r16 |= (unsigned long) (tmp) << 32) #define copyseg_cs(tmp) (regs->r17 |= tmp) -#define copyseg_ss(tmp) (regs->r17 |= (unsigned long) tmp << 16) -#define copyseg_es(tmp) (regs->r16 |= (unsigned long) tmp << 16) +#define copyseg_ss(tmp) (regs->r17 |= (unsigned long) (tmp) << 16) +#define copyseg_es(tmp) (regs->r16 |= (unsigned long) (tmp) << 16) #define copyseg_ds(tmp) (regs->r16 |= tmp) #define COPY_SEG(seg) \ Index: arch/ia64/ia32/ia32_support.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/ia32/ia32_support.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/ia32/ia32_support.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/ia32/ia32_support.c 4 Aug 2004 01:25:42 -0000 1.2 @@ -60,30 +60,26 @@ regs->r27 = load_desc(regs->r16 >> 0); /* DSD */ regs->r28 = load_desc(regs->r16 >> 32); /* FSD */ regs->r29 = load_desc(regs->r16 >> 48); /* GSD */ - task->thread.csd = load_desc(regs->r17 >> 0); /* CSD */ - task->thread.ssd = load_desc(regs->r17 >> 16); /* SSD */ + regs->ar_csd = load_desc(regs->r17 >> 0); /* CSD */ + regs->ar_ssd = load_desc(regs->r17 >> 16); /* SSD */ } void ia32_save_state (struct task_struct *t) { - unsigned long eflag, fsr, fcr, fir, fdr, csd, ssd; + unsigned long eflag, fsr, fcr, fir, fdr; asm ("mov %0=ar.eflag;" "mov %1=ar.fsr;" "mov %2=ar.fcr;" "mov %3=ar.fir;" "mov %4=ar.fdr;" - "mov %5=ar.csd;" - "mov %6=ar.ssd;" - : "=r"(eflag), "=r"(fsr), "=r"(fcr), "=r"(fir), "=r"(fdr), "=r"(csd), "=r"(ssd)); + : "=r"(eflag), "=r"(fsr), "=r"(fcr), "=r"(fir), "=r"(fdr)); t->thread.eflag = eflag; t->thread.fsr = fsr; t->thread.fcr = fcr; t->thread.fir = fir; t->thread.fdr = fdr; - t->thread.csd = csd; - t->thread.ssd = ssd; ia64_set_kr(IA64_KR_IO_BASE, t->thread.old_iob); ia64_set_kr(IA64_KR_TSSD, t->thread.old_k1); } @@ -91,7 +87,7 @@ void ia32_load_state (struct task_struct *t) { - unsigned long eflag, fsr, fcr, fir, fdr, csd, ssd, tssd; + unsigned long eflag, fsr, fcr, fir, fdr, tssd; struct pt_regs *regs = ia64_task_regs(t); int nr = smp_processor_id(); /* LDT and TSS depend on CPU number: */ @@ -100,8 +96,6 @@ fcr = t->thread.fcr; fir = t->thread.fir; fdr = t->thread.fdr; - csd = t->thread.csd; - ssd = t->thread.ssd; tssd = load_desc(_TSS(nr)); /* TSSD */ asm volatile ("mov ar.eflag=%0;" @@ -109,9 +103,7 @@ "mov ar.fcr=%2;" "mov ar.fir=%3;" "mov ar.fdr=%4;" - "mov ar.csd=%5;" - "mov ar.ssd=%6;" - :: "r"(eflag), "r"(fsr), "r"(fcr), "r"(fir), "r"(fdr), "r"(csd), "r"(ssd)); + :: "r"(eflag), "r"(fsr), "r"(fcr), "r"(fir), "r"(fdr)); current->thread.old_iob = ia64_get_kr(IA64_KR_IO_BASE); current->thread.old_k1 = ia64_get_kr(IA64_KR_TSSD); ia64_set_kr(IA64_KR_IO_BASE, IA32_IOBASE); Index: arch/ia64/ia32/sys_ia32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/ia32/sys_ia32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/ia32/sys_ia32.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/ia32/sys_ia32.c 4 Aug 2004 01:25:43 -0000 1.2 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,7 @@ #define OFFSET4K(a) ((a) & 0xfff) #define PAGE_START(addr) ((addr) & PAGE_MASK) #define PAGE_OFF(addr) ((addr) & ~PAGE_MASK) +#define MINSIGSTKSZ_IA32 2048 extern asmlinkage long sys_execve (char *, char **, char **, struct pt_regs *); extern asmlinkage long sys_mprotect (unsigned long, size_t, unsigned long); @@ -165,9 +167,9 @@ current->thread.map_base = old_map_base; current->thread.task_size = old_task_size; set_fs(USER_DS); /* establish new task-size as the address-limit */ - out: - kfree(av); } + out: + kfree(av); return r; } @@ -200,13 +202,18 @@ asmlinkage long sys32_newstat (char *filename, struct stat32 *statbuf) { + char *name; int ret; struct stat s; mm_segment_t old_fs = get_fs(); + name = getname(filename); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs(KERNEL_DS); - ret = sys_newstat(filename, &s); + ret = sys_newstat(name, &s); set_fs(old_fs); + putname(name); if (putstat(statbuf, &s)) return -EFAULT; return ret; @@ -217,13 +224,18 @@ asmlinkage long sys32_newlstat (char *filename, struct stat32 *statbuf) { + char *name; mm_segment_t old_fs = get_fs(); struct stat s; int ret; + name = getname(filename); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs(KERNEL_DS); - ret = sys_newlstat(filename, &s); + ret = sys_newlstat(name, &s); set_fs(old_fs); + putname(name); if (putstat(statbuf, &s)) return -EFAULT; return ret; @@ -250,9 +262,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 +286,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 +330,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 +341,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 +475,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 +579,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 +608,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); } @@ -676,13 +709,18 @@ asmlinkage long sys32_statfs (const char *path, struct statfs32 *buf) { + const char *name; int ret; struct statfs s; mm_segment_t old_fs = get_fs(); + name = getname(path); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs(KERNEL_DS); - ret = sys_statfs(path, &s); + ret = sys_statfs(name, &s); set_fs(old_fs); + putname(name); if (put_statfs(buf, &s)) return -EFAULT; return ret; @@ -1230,8 +1268,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 +2123,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; @@ -2167,6 +2205,10 @@ else fourth.__pad = (void *)A(pad); switch (third) { + default: + err = -EINVAL; + break; + case IPC_INFO: case IPC_RMID: case IPC_SET: @@ -2234,7 +2276,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 +2318,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 +2356,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 +2450,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 +2502,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; @@ -2590,7 +2632,7 @@ return shmctl32(first, second, (void *)AA(ptr)); default: - return -EINVAL; + return -ENOSYS; } return -EINVAL; } @@ -2862,12 +2904,16 @@ ia64f2ia32f(f, &ptp->f9); break; case 2: + ia64f2ia32f(f, &ptp->f10); + break; case 3: + ia64f2ia32f(f, &ptp->f11); + break; case 4: case 5: case 6: case 7: - ia64f2ia32f(f, &swp->f10 + (regno - 2)); + ia64f2ia32f(f, &swp->f12 + (regno - 4)); break; } copy_to_user(reg, f, sizeof(*reg)); @@ -2888,12 +2934,16 @@ copy_from_user(&ptp->f9, reg, sizeof(*reg)); break; case 2: + copy_from_user(&ptp->f10, reg, sizeof(*reg)); + break; case 3: + copy_from_user(&ptp->f11, reg, sizeof(*reg)); + break; case 4: case 5: case 6: case 7: - copy_from_user(&swp->f10 + (regno - 2), reg, sizeof(*reg)); + copy_from_user(&swp->f12 + (regno - 4), reg, sizeof(*reg)); break; } return; @@ -2924,7 +2974,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 +3007,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 +3126,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; + goto out_tsk; } - ret = -ESRCH; - if (!(child->ptrace & PT_PTRACED)) - goto out; - if (child->state != TASK_STOPPED) { - if (request != PTRACE_KILL) - goto out; - } - 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 +3152,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 +3232,8 @@ break; } + out_tsk: + free_task_struct(child); out: unlock_kernel(); return ret; @@ -3355,10 +3404,18 @@ return -EFAULT; uss.ss_sp = (void *) (long) buf32.ss_sp; uss.ss_flags = buf32.ss_flags; - uss.ss_size = buf32.ss_size; + /* MINSIGSTKSZ is different for ia32 vs ia64. We lie here to pass the + check and set it to the user requested value later */ + if ((buf32.ss_flags != SS_DISABLE) && (buf32.ss_size < MINSIGSTKSZ_IA32)) { + ret = -ENOMEM; + goto out; + } + uss.ss_size = MINSIGSTKSZ; set_fs(KERNEL_DS); ret = do_sigaltstack(uss32 ? &uss : NULL, &uoss, pt->r12); + current->sas_ss_size = buf32.ss_size; set_fs(old_fs); +out: if (ret < 0) return(ret); if (uoss32) { @@ -3407,6 +3464,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 +3502,9 @@ return -EFAULT; return ret; +#else + return -ENOSYS; +#endif } asmlinkage long @@ -3591,9 +3652,11 @@ return -EFAULT; old_fs = get_fs(); set_fs(KERNEL_DS); - ret = sys_fcntl(fd, cmd, (unsigned long) &f); + ret = sys_fcntl(fd, (cmd == F_GETLK64) ? F_GETLK : + ((cmd == F_SETLK64) ? F_SETLK : F_SETLKW), + (unsigned long) &f); set_fs(old_fs); - if (cmd == F_GETLK && ia32_put_flock(&f, arg)) + if (cmd == F_GETLK64 && ia32_put_flock(&f, arg)) return -EFAULT; break; @@ -3650,13 +3713,18 @@ asmlinkage long sys32_stat64 (char *filename, struct stat64 *statbuf) { + char *name; mm_segment_t old_fs = get_fs(); struct stat s; long ret; + name = getname(filename); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs(KERNEL_DS); - ret = sys_newstat(filename, &s); + ret = sys_newstat(name, &s); set_fs(old_fs); + putname(name); if (putstat64(statbuf, &s)) return -EFAULT; return ret; @@ -3665,13 +3733,18 @@ asmlinkage long sys32_lstat64 (char *filename, struct stat64 *statbuf) { + char *name; mm_segment_t old_fs = get_fs(); struct stat s; long ret; + name = getname(filename); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs(KERNEL_DS); - ret = sys_newlstat(filename, &s); + ret = sys_newlstat(name, &s); set_fs(old_fs); + putname(name); if (putstat64(statbuf, &s)) return -EFAULT; return ret; @@ -3707,21 +3780,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 +3832,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 +3881,7 @@ return result; } -struct dqblk32 { +struct user_dqblk32 { __u32 dqb_bhardlimit; __u32 dqb_bsoftlimit; __u32 dqb_curblocks; @@ -3795,43 +3893,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; Index: arch/ia64/kernel/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/Makefile 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/Makefile 4 Aug 2004 01:25:43 -0000 1.2 @@ -11,12 +11,13 @@ O_TARGET := kernel.o -export-objs := ia64_ksyms.o +export-objs := ia64_ksyms.o unwind.o obj-y := acpi.o entry.o gate.o efi.o efi_stub.o ia64_ksyms.o irq.o irq_ia64.o irq_lsapic.o ivt.o \ machvec.o pal.o process.o perfmon.o ptrace.o sal.o salinfo.o semaphore.o setup.o \ signal.o sys_ia64.o traps.o time.o unaligned.o unwind.o obj-$(CONFIG_IA64_GENERIC) += iosapic.o +obj-$(CONFIG_IA64_SGI_SN2) += iosapic.o obj-$(CONFIG_IA64_HP_ZX1) += iosapic.o obj-$(CONFIG_IA64_DIG) += iosapic.o obj-$(CONFIG_IA64_PALINFO) += palinfo.o Index: arch/ia64/kernel/acpi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/acpi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/acpi.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/acpi.c 4 Aug 2004 01:25:43 -0000 1.2 @@ -3,11 +3,14 @@ * * 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 * Copyright (C) 2001 Paul Diefenbaugh + * Copyright (C) 2001 Jenna Hall + * Copyright (C) 2001 Takayoshi Kochi + * Copyright (C) 2002 Erich Focht * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * @@ -38,11 +41,14 @@ #include #include #include +#include +#include #include #include #include #include #include +#include #define PREFIX "ACPI: " @@ -51,6 +57,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,25 +76,28 @@ 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"; } if (!strcmp(hdr->oem_id, "HP")) { - return "hpzx1"; + return "hp"; + } + else if (!strcmp(hdr->oem_id, "SGI")) { + return "sn2"; } return "dig"; @@ -95,9 +105,7 @@ # if defined (CONFIG_IA64_HP_SIM) return "hpsim"; # elif defined (CONFIG_IA64_HP_ZX1) - return "hpzx1"; -# elif defined (CONFIG_IA64_SGI_SN1) - return "sn1"; + return "hp"; # elif defined (CONFIG_IA64_SGI_SN2) return "sn2"; # elif defined (CONFIG_IA64_DIG) @@ -110,165 +118,87 @@ #ifdef CONFIG_ACPI -static acpi_resource * -acpi_get_crs_next (acpi_buffer *buf, int *offset) -{ - acpi_resource *res; - - if (*offset >= buf->length) - return NULL; - - 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; - } -} +struct acpi_vendor_descriptor { + u8 guid_id; + efi_guid_t guid; +}; + +struct acpi_vendor_info { + struct acpi_vendor_descriptor *descriptor; + u8 *data; + u32 length; +}; -static void -acpi_get_crs_addr (acpi_buffer *buf, int type, u64 *base, u64 *length, u64 *tra) +acpi_status +acpi_vendor_resource_match (struct acpi_resource *resource, void *context) { - 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; - } - } + struct acpi_vendor_info *info = (struct acpi_vendor_info *) context; + struct acpi_resource_vendor *vendor; + struct acpi_vendor_descriptor *descriptor; + u32 length; + + if (resource->id != ACPI_RSTYPE_VENDOR) + return AE_OK; + + vendor = (struct 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 }; - - *base = 0; - *length = 0; - *tra = 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; - } + struct acpi_vendor_info info; - acpi_get_crs_addr(&buf, type, base, length, tra); + info.descriptor = id; + info.data = 0; - 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) +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; + u8 *data; + u32 length; - *csr_base = 0; - *csr_length = 0; + status = acpi_find_vendor_resource(obj, &hp_ccsr_descriptor, &data, &length); - 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; - } + if (ACPI_FAILURE(status) || length != 16) + return AE_NOT_FOUND; - 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(csr_base, data, sizeof(*csr_base)); + memcpy(csr_length, data + 8, sizeof(*csr_length)); + acpi_os_free(data); - 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 @@ -276,7 +206,9 @@ #define ACPI_MAX_PLATFORM_INTERRUPTS 256 /* Array to record platform interrupt vectors for generic interrupt routing. */ -int platform_intr_list[ACPI_MAX_PLATFORM_INTERRUPTS] = { [0 ... ACPI_MAX_PLATFORM_INTERRUPTS - 1] = -1 }; +int platform_intr_list[ACPI_MAX_PLATFORM_INTERRUPTS] = { + [0 ... ACPI_MAX_PLATFORM_INTERRUPTS - 1] = -1 +}; enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC; @@ -290,11 +222,10 @@ int vector = -1; if (int_type < ACPI_MAX_PLATFORM_INTERRUPTS) { - /* correctable platform error interrupt */ + /* corrected 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; } @@ -329,7 +260,6 @@ iounmap((void *) ipi_base_addr); ipi_base_addr = (unsigned long) ioremap(lapic->address, 0); } - return 0; } @@ -338,7 +268,6 @@ acpi_parse_lsapic (acpi_table_entry_header *header) { struct acpi_table_lsapic *lsapic; - int phys_id; lsapic = (struct acpi_table_lsapic *) header; if (!lsapic) @@ -346,30 +275,21 @@ acpi_table_print_madt_entry(header); - phys_id = (lsapic->id << 8) | lsapic->eid; - - if (total_cpus == NR_CPUS) { - printk(KERN_ERR PREFIX "Ignoring CPU (0x%04x) (NR_CPUS == %d)\n", - phys_id, NR_CPUS); - return 0; - } + printk(KERN_INFO "CPU %d (0x%04x)", total_cpus, (lsapic->id << 8) | lsapic->eid); - printk("CPU %d (0x%04x)", total_cpus, phys_id); - - if (lsapic->flags.enabled) { - available_cpus++; + if (!lsapic->flags.enabled) + printk(" disabled"); + else if (available_cpus >= NR_CPUS) + printk(" ignored (increase NR_CPUS)"); + else { printk(" enabled"); #ifdef CONFIG_SMP - smp_boot_data.cpu_phys_id[total_cpus] = phys_id; - if (hard_smp_processor_id() == smp_boot_data.cpu_phys_id[total_cpus]) + smp_boot_data.cpu_phys_id[available_cpus] = (lsapic->id << 8) | lsapic->eid; + if (hard_smp_processor_id() + == (unsigned int) smp_boot_data.cpu_phys_id[available_cpus]) printk(" (BSP)"); #endif - } - else { - printk(" disabled"); -#ifdef CONFIG_SMP - smp_boot_data.cpu_phys_id[total_cpus] = -1; -#endif + ++available_cpus; } printk("\n"); @@ -391,46 +311,11 @@ acpi_table_print_madt_entry(header); /* TBD: Support lapic_nmi entries */ - return 0; } 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 +326,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 +338,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 +350,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 +359,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 +383,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; } @@ -532,7 +401,6 @@ acpi_table_print_madt_entry(header); /* TBD: Support nimsrc entries */ - return 0; } @@ -546,7 +414,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 */ @@ -558,23 +432,209 @@ } +#ifdef CONFIG_ACPI_NUMA + +#define PXM_FLAG_LEN ((MAX_PXM_DOMAINS + 1)/32) + +static int __initdata srat_num_cpus; /* number of cpus */ +static u32 __initdata pxm_flag[PXM_FLAG_LEN]; +#define pxm_bit_set(bit) (set_bit(bit,(void *)pxm_flag)) +#define pxm_bit_test(bit) (test_bit(bit,(void *)pxm_flag)) +/* maps to convert between proximity domain and logical node ID */ +int __initdata pxm_to_nid_map[MAX_PXM_DOMAINS]; +int __initdata nid_to_pxm_map[NR_NODES]; +struct acpi_table_slit __initdata *slit_table; + +/* + * ACPI 2.0 SLIT (System Locality Information Table) + * http://devresource.hp.com/devresource/Docs/TechPapers/IA64/slit.pdf + */ +void __init +acpi_numa_slit_init (struct acpi_table_slit *slit) +{ + u32 len; + + len = sizeof(struct acpi_table_header) + 8 + + slit->localities * slit->localities; + if (slit->header.length != len) { + printk("KERN_INFO ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n", + len, slit->header.length); + memset(numa_slit, 10, sizeof(numa_slit)); + return; + } + slit_table = slit; +} + +void __init +acpi_numa_processor_affinity_init (struct acpi_table_processor_affinity *pa) +{ + /* record this node in proximity bitmap */ + pxm_bit_set(pa->proximity_domain); + + node_cpuid[srat_num_cpus].phys_id = (pa->apic_id << 8) | (pa->lsapic_eid); + /* nid should be overridden as logical node id later */ + node_cpuid[srat_num_cpus].nid = pa->proximity_domain; + srat_num_cpus++; +} + +void __init +acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma) +{ + unsigned long paddr, size, hole_size, min_hole_size; + u8 pxm; + struct node_memblk_s *p, *q, *pend; + + pxm = ma->proximity_domain; + + /* fill node memory chunk structure */ + paddr = ma->base_addr_hi; + paddr = (paddr << 32) | ma->base_addr_lo; + size = ma->length_hi; + size = (size << 32) | ma->length_lo; + + if (num_memblks >= NR_MEMBLKS) { + printk(KERN_ERR "Too many mem chunks in SRAT. Ignoring %ld MBytes at %lx\n", + size/(1024*1024), paddr); + return; + } + + /* Ignore disabled entries */ + if (!ma->flags.enabled) + return; + + /* + * When the chunk is not the first one in the node, check distance + * from the other chunks. When the hole is too huge ignore the chunk. + * This restriction should be removed when multiple chunks per node + * is supported. + */ + pend = &node_memblk[num_memblks]; + min_hole_size = 0; + for (p = &node_memblk[0]; p < pend; p++) { + if (p->nid != pxm) + continue; + if (p->start_paddr < paddr) + hole_size = paddr - (p->start_paddr + p->size); + else + hole_size = p->start_paddr - (paddr + size); + + if (!min_hole_size || hole_size < min_hole_size) + min_hole_size = hole_size; + } + +#if 0 /* test */ + if (min_hole_size) { + if (min_hole_size > size) { + printk(KERN_ERR "Too huge memory hole. Ignoring %ld MBytes at %lx\n", + size/(1024*1024), paddr); + return; + } + } +#endif + + /* record this node in proximity bitmap */ + pxm_bit_set(pxm); + + /* Insertion sort based on base address */ + pend = &node_memblk[num_memblks]; + for (p = &node_memblk[0]; p < pend; p++) { + if (paddr < p->start_paddr) + break; + } + if (p < pend) { + for (q = pend; q >= p; q--) + *(q + 1) = *q; + } + p->start_paddr = paddr; + p->size = size; + p->nid = pxm; + num_memblks++; +} + +void __init +acpi_numa_arch_fixup(void) +{ + int i, j, node_from, node_to; + + if (srat_num_cpus == 0) { + node_cpuid[0].phys_id = hard_smp_processor_id(); + return; + } + + /* calculate total number of nodes in system from PXM bitmap */ + numnodes = 0; /* init total nodes in system */ + + memset(pxm_to_nid_map, -1, sizeof(pxm_to_nid_map)); + memset(nid_to_pxm_map, -1, sizeof(nid_to_pxm_map)); + for (i = 0; i < MAX_PXM_DOMAINS; i++) { + if (pxm_bit_test(i)) { + pxm_to_nid_map[i] = numnodes; + nid_to_pxm_map[numnodes++] = i; + } + } + + /* set logical node id in memory chunk structure */ + for (i = 0; i < num_memblks; i++) + node_memblk[i].nid = pxm_to_nid_map[node_memblk[i].nid]; + + /* assign memory bank numbers for each chunk on each node */ + for (i = 0; i < numnodes; i++) { + int bank; + + bank = 0; + for (j = 0; j < num_memblks; j++) + if (node_memblk[j].nid == i) + node_memblk[j].bank = bank++; + } + + /* set logical node id in cpu structure */ + for (i = 0; i < srat_num_cpus; i++) + node_cpuid[i].nid = pxm_to_nid_map[node_cpuid[i].nid]; + + printk(KERN_INFO "Number of logical nodes in system = %d\n", numnodes); + printk(KERN_INFO "Number of memory chunks in system = %d\n", num_memblks); + + if (!slit_table) return; + memset(numa_slit, -1, sizeof(numa_slit)); + for (i=0; ilocalities; i++) { + if (!pxm_bit_test(i)) + continue; + node_from = pxm_to_nid_map[i]; + for (j=0; jlocalities; j++) { + if (!pxm_bit_test(j)) + continue; + node_to = pxm_to_nid_map[j]; + node_distance(node_from, node_to) = + slit_table->entry[i*slit_table->localities + j]; + } + } + +#ifdef SLIT_DEBUG + printk(KERN_DEBUG "ACPI 2.0 SLIT locality table:\n"); + for (i = 0; i < numnodes; i++) { + for (j = 0; j < numnodes; j++) + printk(KERN_DEBUG "%03d ", node_distance(i,j)); + printk("\n"); + } +#endif +} +#endif /* CONFIG_ACPI_NUMA */ + static int __init acpi_parse_fadt (unsigned long phys_addr, unsigned long size) { struct acpi_table_header *fadt_header; - fadt_descriptor_rev2 *fadt; - u32 sci_irq, gsi_base; - char *iosapic_address; + struct fadt_descriptor_rev2 *fadt; + u32 sci_irq; if (!phys_addr || !size) return -EINVAL; fadt_header = (struct acpi_table_header *) __va(phys_addr); - if (fadt_header->revision != 3) return -ENODEV; /* Only deal with ACPI 2.0 FADT */ - fadt = (fadt_descriptor_rev2 *) fadt_header; + fadt = (struct fadt_descriptor_rev2 *) fadt_header; if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER)) acpi_kbd_controller_present = 0; @@ -587,9 +647,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; } @@ -603,20 +661,13 @@ rsdp_phys = __pa(efi.acpi20); else if (efi.acpi) printk(KERN_WARNING PREFIX "v1.0/r0.71 tables no longer supported\n"); - return rsdp_phys; } int __init -acpi_boot_init (char *cmdline) +acpi_boot_init (void) { - int result; - - /* Initialize the ACPI boot-time table parser */ - result = acpi_table_init(cmdline); - if (result) - return result; /* * MADT @@ -633,64 +684,76 @@ /* Local APIC */ - if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, - acpi_parse_lapic_addr_ovr) < 0) + if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr) < 0) printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); - if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, - acpi_parse_lsapic) < 1) + if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_parse_lsapic) < 1) printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n"); - if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, - acpi_parse_lapic_nmi) < 0) + if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi) < 0) printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); /* I/O APIC */ - if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC, - acpi_parse_iosapic) < 1) - printk(KERN_ERR PREFIX "Error parsing MADT - no IOAPIC entries\n"); + if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC, acpi_parse_iosapic) < 1) + printk(KERN_ERR PREFIX "Error parsing MADT - no IOSAPIC entries\n"); /* System-Level Interrupt Routing */ - if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC, - acpi_parse_plat_int_src) < 0) + if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC, acpi_parse_plat_int_src) < 0) printk(KERN_ERR PREFIX "Error parsing platform interrupt source entry\n"); - if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, - acpi_parse_int_src_ovr) < 0) + if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr) < 0) printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); - if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC, - acpi_parse_nmi_src) < 0) + if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src) < 0) printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); -skip_madt: + skip_madt: /* - * The FADT table contains an SCI_INT line, by which the system + * FADT says whether a legacy keyboard controller is present. + * The FADT also contains an SCI_INT line, by which the system * gets interrupts such as power and sleep buttons. If it's not * on a Legacy interrupt, it needs to be setup. */ - if (acpi_table_parse(ACPI_FACP, acpi_parse_fadt) < 1) + if (acpi_table_parse(ACPI_FADT, acpi_parse_fadt) < 1) printk(KERN_ERR PREFIX "Can't find FADT\n"); #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"); + printk(KERN_INFO "CPU 0 (0x%04x)", hard_smp_processor_id()); + smp_boot_data.cpu_phys_id[available_cpus] = hard_smp_processor_id(); available_cpus = 1; /* We've got at least one of these, no? */ } - smp_boot_data.cpu_count = total_cpus; + smp_boot_data.cpu_count = available_cpus; + + smp_build_cpu_map(); +# ifdef CONFIG_NUMA + /* If the platform did not have an SRAT table, initialize the + * node_cpuid table from the smp_boot_data array. All cpus + * will be on node 0. + */ + if (srat_num_cpus == 0) { + int cpu, i=1; + for (cpu=0; cpucpl; 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; Index: arch/ia64/kernel/efi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/efi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/efi.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/efi.c 4 Aug 2004 01:25:43 -0000 1.2 @@ -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 * @@ -30,6 +30,7 @@ #include #include #include +#include #define EFI_DEBUG 0 @@ -46,7 +47,7 @@ * prior to creating their own entries under /proc/efi. */ #ifdef CONFIG_PROC_FS -struct proc_dir_entry *efi_dir = NULL; +struct proc_dir_entry *efi_dir; #endif static unsigned long mem_limit = ~0UL; @@ -297,9 +298,9 @@ u64 start; u64 end; } prev, curr; - void *efi_map_start, *efi_map_end, *p, *q, *r; + void *efi_map_start, *efi_map_end, *p, *q; efi_memory_desc_t *md, *check_md; - u64 efi_desc_size, start, end, granule_addr, first_non_wb_addr = 0; + u64 efi_desc_size, start, end, granule_addr, last_granule_addr, first_non_wb_addr = 0; efi_map_start = __va(ia64_boot_param->efi_memmap); efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; @@ -312,41 +313,34 @@ if (!(md->attribute & EFI_MEMORY_WB)) continue; - if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > first_non_wb_addr) { - /* - * Search for the next run of contiguous WB memory. Start search - * at first granule boundary covered by md. - */ - granule_addr = ((md->phys_addr + IA64_GRANULE_SIZE - 1) - & -IA64_GRANULE_SIZE); - first_non_wb_addr = granule_addr; - for (q = p; q < efi_map_end; q += efi_desc_size) { - check_md = q; - - if (check_md->attribute & EFI_MEMORY_WB) - trim_bottom(md, granule_addr); - - if (check_md->phys_addr < granule_addr) - continue; + /* + * granule_addr is the base of md's first granule. + * [granule_addr - first_non_wb_addr) is guaranteed to + * be contiguous WB memory. + */ + granule_addr = md->phys_addr & ~(IA64_GRANULE_SIZE - 1); + first_non_wb_addr = max(first_non_wb_addr, granule_addr); - if (!(check_md->attribute & EFI_MEMORY_WB)) - break; /* hit a non-WB region; stop search */ + if (first_non_wb_addr < md->phys_addr) { + trim_bottom(md, granule_addr + IA64_GRANULE_SIZE); + granule_addr = md->phys_addr & ~(IA64_GRANULE_SIZE - 1); + first_non_wb_addr = max(first_non_wb_addr, granule_addr); + } - if (check_md->phys_addr != first_non_wb_addr) - break; /* hit a memory hole; stop search */ + for (q = p; q < efi_map_end; q += efi_desc_size) { + check_md = q; + if ((check_md->attribute & EFI_MEMORY_WB) && + (check_md->phys_addr == first_non_wb_addr)) first_non_wb_addr += check_md->num_pages << EFI_PAGE_SHIFT; - } - /* round it down to the previous granule-boundary: */ - first_non_wb_addr &= -IA64_GRANULE_SIZE; - - if (!(first_non_wb_addr > granule_addr)) - continue; /* couldn't find enough contiguous memory */ - - for (r = p; r < q; r += efi_desc_size) - trim_top(r, first_non_wb_addr); + else + break; /* non-WB or hole */ } + last_granule_addr = first_non_wb_addr & ~(IA64_GRANULE_SIZE - 1); + if (last_granule_addr < md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) + trim_top(md, last_granule_addr); + if (is_available_memory(md)) { if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > mem_limit) { if (md->phys_addr > mem_limit) @@ -365,7 +359,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 */ @@ -402,6 +396,9 @@ int pal_code_count = 0; u64 mask, psr; u64 vaddr; +#ifdef CONFIG_IA64_MCA + int cpu; +#endif efi_map_start = __va(ia64_boot_param->efi_memmap); efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; @@ -437,7 +434,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,10 +443,12 @@ 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", +#if EFI_DEBUG + 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); +#endif /* * Cannot write to CRx with PSR.ic=1 @@ -458,6 +458,14 @@ pte_val(mk_pte_phys(md->phys_addr, PAGE_KERNEL)), IA64_GRANULE_SHIFT); ia64_set_psr(psr); /* restore psr */ ia64_srlz_i(); + +#ifdef CONFIG_IA64_MCA + cpu = smp_processor_id(); + + /* insert this TR into our list for MCA recovery purposes */ + ia64_mca_tlb_list[cpu].pal_base=vaddr & mask; + ia64_mca_tlb_list[cpu].pal_paddr= pte_val(mk_pte_phys(md->phys_addr, PAGE_KERNEL)); +#endif } } @@ -488,7 +496,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 +508,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 +523,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 +615,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 +625,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 +637,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; } @@ -687,8 +695,7 @@ for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { md = p; - if ((md->phys_addr <= phys_addr) && (phys_addr <= - (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1))) + if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) return md->type; } return 0; @@ -708,8 +715,7 @@ for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { md = p; - if ((md->phys_addr <= phys_addr) && (phys_addr <= - (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1))) + if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) return md->attribute; } return 0; Index: arch/ia64/kernel/efi_stub.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/efi_stub.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/efi_stub.S 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/efi_stub.S 4 Aug 2004 01:25:43 -0000 1.2 @@ -62,7 +62,7 @@ mov b6=r2 ;; andcm r16=loc3,r16 // get psr with IT, DT, and RT bits cleared - br.call.sptk.many rp=ia64_switch_mode + br.call.sptk.many rp=ia64_switch_mode_phys .ret0: mov out4=in5 mov out0=in1 mov out1=in2 @@ -73,7 +73,7 @@ br.call.sptk.many rp=b6 // call the EFI function .ret1: mov ar.rsc=0 // put RSE in enforced lazy, LE mode mov r16=loc3 - br.call.sptk.many rp=ia64_switch_mode // return to virtual mode + br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode .ret2: mov ar.rsc=loc4 // restore RSE configuration mov ar.pfs=loc1 mov rp=loc0 Index: arch/ia64/kernel/efivars.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/efivars.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/efivars.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/efivars.c 4 Aug 2004 01:25:43 -0000 1.2 @@ -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,9 +109,17 @@ 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; +static struct proc_dir_entry *efi_vars_dir; #define efivar_entry(n) list_entry(n, efivar_entry_t, list) @@ -127,8 +138,7 @@ static inline unsigned long utf8_strsize(efi_char16_t *data, unsigned long maxlength) { - return utf8_strlen(data, maxlength/sizeof(efi_char16_t)) * - sizeof(efi_char16_t); + return utf8_strlen(data, maxlength/sizeof(efi_char16_t)) * sizeof(efi_char16_t); } @@ -150,6 +160,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 +168,13 @@ 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; + efivar_entry_t *new_efivar; + + short_name = kmalloc(short_name_size+1, GFP_KERNEL); + new_efivar = kmalloc(sizeof(efivar_entry_t), GFP_KERNEL); - 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); if (!short_name || !new_efivar) { if (short_name) kfree(short_name); if (new_efivar) kfree(new_efivar); @@ -178,7 +189,7 @@ /* Convert Unicode to normal chars (assume top bits are 0), ala UTF-8 */ - for (i=0; ientry = 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; } @@ -278,7 +288,7 @@ } if (copy_from_user(var_data, buffer, size)) { MOD_DEC_USE_COUNT; - kfree(var_data); + kfree(var_data); return -EFAULT; } @@ -326,6 +336,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 +348,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) - efi_dir = proc_mkdir("efi", NULL); - - efi_vars_dir = proc_mkdir("vars", 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_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 +470,6 @@ } while (status != EFI_NOT_FOUND); kfree(variable_name); - spin_unlock(&efivars_lock); return 0; } @@ -409,16 +480,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); Index: arch/ia64/kernel/entry.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/entry.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/entry.S 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/entry.S 4 Aug 2004 01:25:43 -0000 1.2 @@ -3,6 +3,9 @@ * * Kernel entry points. * + * Copyright (C) 2002-2003 + * Suresh Siddha + * Fenghua Yu * Copyright (C) 1998-2002 Hewlett-Packard Co * David Mosberger-Tang * Copyright (C) 1999 VA Linux Systems @@ -48,7 +51,10 @@ ENTRY(ia64_execve) .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(3) alloc loc1=ar.pfs,3,2,4,0 - mov loc0=rp + /* Leave from kernel and restore all pt_regs to correspending registers. This is special + * because ia32 application needs scratch registers after return from execve. + */ + movl loc0=ia64_ret_from_execve_syscall .body mov out0=in0 // filename ;; // stop bit between alloc and call @@ -72,19 +78,18 @@ * this executes in less than 20 cycles even on Itanium, so it's not worth * optimizing for...). */ - mov r4=0; mov f2=f0; mov b1=r0 - mov r5=0; mov f3=f0; mov b2=r0 - mov r6=0; mov f4=f0; mov b3=r0 - mov r7=0; mov f5=f0; mov b4=r0 - mov ar.unat=0; mov f10=f0; mov b5=r0 - ldf.fill f11=[sp]; ldf.fill f12=[sp]; mov f13=f0 - ldf.fill f14=[sp]; ldf.fill f15=[sp]; mov f16=f0 - ldf.fill f17=[sp]; ldf.fill f18=[sp]; mov f19=f0 - ldf.fill f20=[sp]; ldf.fill f21=[sp]; mov f22=f0 - ldf.fill f23=[sp]; ldf.fill f24=[sp]; mov f25=f0 - ldf.fill f26=[sp]; ldf.fill f27=[sp]; mov f28=f0 - ldf.fill f29=[sp]; ldf.fill f30=[sp]; mov f31=f0 - mov ar.lc=0 + mov ar.unat=0; mov ar.lc=0; + mov r4=0; mov f2=f0; mov b1=r0 + mov r5=0; mov f3=f0; mov b2=r0 + mov r6=0; mov f4=f0; mov b3=r0 + mov r7=0; mov f5=f0; mov b4=r0 + ldf.fill f12=[sp]; mov f13=f0; mov b5=r0 + ldf.fill f14=[sp]; ldf.fill f15=[sp]; mov f16=f0 + ldf.fill f17=[sp]; ldf.fill f18=[sp]; mov f19=f0 + ldf.fill f20=[sp]; ldf.fill f21=[sp]; mov f22=f0 + ldf.fill f23=[sp]; ldf.fill f24=[sp]; mov f25=f0 + ldf.fill f26=[sp]; ldf.fill f27=[sp]; mov f28=f0 + ldf.fill f29=[sp]; ldf.fill f30=[sp]; mov f31=f0 br.ret.sptk.many rp END(ia64_execve) @@ -161,7 +166,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 @@ -251,8 +256,6 @@ st8 [r14]=r21,16 // save b0 st8 [r15]=r22,16 // save b1 mov r25=b4 - stf.spill [r2]=f10,32 - stf.spill [r3]=f11,32 mov r26=b5 ;; st8 [r14]=r23,16 // save b2 @@ -351,9 +354,6 @@ ldf.fill f4=[r14],32 ldf.fill f5=[r15],32 ;; - ldf.fill f10=[r14],32 - ldf.fill f11=[r15],32 - ;; ldf.fill f12=[r14],32 ldf.fill f13=[r15],32 ;; @@ -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? @@ -468,7 +475,7 @@ .mem.offset 8,0; st8.spill [r3]=r10 // clear error indication in slot for r10 ia64_strace_leave_kernel: br.call.sptk.many rp=invoke_syscall_trace // give parent a chance to catch return value -.rety: br.cond.sptk ia64_leave_kernel +.rety: br.cond.sptk ia64_leave_syscall strace_error: ld8 r3=[r2] // load pt_regs.r8 @@ -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 ;; @@ -514,12 +528,186 @@ (p7) br.cond.spnt handle_syscall_error // handle potential syscall failure END(ia64_ret_from_syscall) // fall through +/* + * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't + * need to switch to bank 0 and doesn't restore the scratch registers. + * To avoid leaking kernel bits, the scratch registers are set to + * the following known-to-be-safe values: + * + * r1: restored (global pointer) + * r2: cleared + * r3: cleared + * r8-r11: restored (syscall return value(s)) + * r12: restored (user-level stack pointer) + * r13: restored (user-level thread pointer) + * r14: cleared + * r15: restored (syscall #) + * r16-r19: cleared + * r20: user-level ar.fpsr + * r21: user-level b0 + * r22: cleared + * r23: user-level ar.bspstore + * r24: user-level ar.rnat + * r25: user-level ar.unat + * r26: user-level ar.pfs + * r27: user-level ar.rsc + * r28: user-level ip + * r29: user-level psr + * r30: user-level cfm + * r31: user-level pr + * f6-f11: cleared + * pr: restored (user-level pr) + * b0: restored (user-level rp) + * b6: cleared + * b7: cleared + * ar.unat: restored (user-level ar.unat) + * ar.pfs: restored (user-level ar.pfs) + * ar.rsc: restored (user-level ar.rsc) + * ar.rnat: restored (user-level ar.rnat) + * ar.bspstore: restored (user-level ar.bspstore) + * ar.fpsr: restored (user-level ar.fpsr) + * ar.ccv: cleared + * ar.csd: cleared + * ar.ssd: cleared + */ +GLOBAL_ENTRY(ia64_leave_syscall) + PT_REGS_UNWIND_INFO(0) + lfetch.fault [sp] + movl r14=.restart1 + ;; + mov.ret.sptk rp=r14,.restart1 + cmp.eq pLvSys,p0=r0,r0 // pLvSys=1: leave from syscall +.restart1: + // need_resched and signals atomic test +(pUser) rsm psr.i + adds r17=IA64_TASK_NEED_RESCHED_OFFSET,r13 + adds r18=IA64_TASK_SIGPENDING_OFFSET,r13 +#ifdef CONFIG_PERFMON + adds r19=IA64_TASK_PFM_OVFL_BLOCK_RESET_OFFSET,r13 +#endif + ;; +#ifdef CONFIG_PERFMON +(pUser) ld8 r19=[r19] // load current->thread.pfm_ovfl_block_reset +#endif +(pUser) ld8 r17=[r17] // load current->need_resched +(pUser) ld4 r18=[r18] // load current->sigpending + ;; +#ifdef CONFIG_PERFMON +(pUser) cmp.ne.unc p9,p0=r19,r0 // current->thread.pfm_ovfl_block_reset != 0? +#endif +(pUser) cmp.ne.unc p7,p0=r17,r0 // current->need_resched != 0? +(pUser) cmp.ne.unc p8,p0=r18,r0 // current->sigpending != 0? + ;; +#ifdef CONFIG_PERFMON +(p9) br.call.spnt.many b7=pfm_ovfl_block_reset +#endif +#if __GNUC__ < 3 +(p7) br.call.spnt.many b7=invoke_schedule +#else +(p7) br.call.spnt.many b7=schedule +#endif +(p8) br.call.spnt.many rp=handle_signal_delivery // check & deliver pending signals (once) + + mov ar.csd=r0 + mov ar.ssd=r0 + adds r16=PT(LOADRS)+16,r12 + adds r17=PT(AR_BSPSTORE)+16, r12 + mov f6=f0 // clear f6 + ;; + ld8 r19=[r16],PT(R8)-PT(LOADRS) // load ar.rsc value for "loadrs" + ld8 r23=[r17],PT(R9)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage) + mov r22=r0 // clear r22 + ;; + // start restoring the state saved on the kernel stack (struct pt_regs): + ld8.fill r8=[r16],16 + ld8.fill r9=[r17],16 + mov f7=f0 // clear f7 + ;; + ld8.fill r10=[r16],16 + ld8.fill r11=[r17],16 + mov f8=f0 // clear f8 + ;; + ld8 r29=[r16],16 // load cr.ipsr + ld8 r28=[r17],16 // load cr.iip + mov b7=r0 // clear b7 + ;; + ld8 r30=[r16],16 // load cr.ifs + ld8 r25=[r17],16 // load ar.unat + cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs + ;; + rsm psr.i | psr.ic // initiate turning off of interrupt and interruption collection + invala // invalidate ALAT + mov f9=f0 // clear f9 + ;; + ld8 r26=[r16],16 // load ar.pfs + ld8 r27=[r17],PT(PR)-PT(AR_RSC)// load ar.rsc + mov f10=f0 // clear f10 + ;; + ld8 r24=[r16],PT(B0)-PT(AR_RNAT)// load ar.rnat (may be garbage) + ld8 r31=[r17],PT(R1)-PT(PR) // load predicates + mov f11=f0 // clear f11 + ;; + ld8 r21=[r16],PT(R12)-PT(B0)// load b0 + ld8.fill r1=[r17],16 // load r1 + mov r3=r0 // clear r3 + ;; + ld8.fill r12=[r16],16 + ld8.fill r13=[r17],16 + mov r2=r0 // clear r2 + ;; + ld8 r20=[r16] // ar.fpsr + ld8.fill r15=[r17] // load r15 + adds r18=16,r16 + ;; + mov r16=ar.bsp // get existing backing store pointer + movl r17=PERCPU_ADDR+IA64_CPU_PHYS_STACKED_SIZE_P8_OFFSET + srlz.i // ensure interruption collection is off + mov ar.ccv=r0 // clear ar.ccv + mov b6=r0 // clear b6 + ;; + ld4 r17=[r17] // r17 = cpu_data->phys_stacked_size_p8 + mov r14=r0 // clear r14 +(pKern) br.cond.dpnt skip_rbs_switch + /* + * Restore user backing store. + * + * NOTE: alloc, loadrs, and cover can't be predicated. + */ + cover // add current frame into dirty partition + shr.u r18=r19,16 // get byte size of existing "dirty" partition + ;; + mov r19=ar.bsp // get new backing store pointer + sub r16=r16,r18 // krbs = old bsp - size of dirty partition + cmp.ne p9,p0=r0,r0 // clear p9 to skip restore of cr.ifs + ;; + sub r19=r19,r16 // calculate total byte size of dirty partition + add r18=64,r18 // don't force in0-in7 into memory... + ;; + shl r19=r19,16 // shift size of dirty partition into loadrs position + br.few dont_preserve_current_frame + ;; +END(ia64_leave_syscall) + +GLOBAL_ENTRY(ia64_ret_from_execve_syscall) + PT_REGS_UNWIND_INFO(0) + cmp.ge p6,p7=r8,r0 // syscall executed successfully? + adds r2=PT(R8)+16,sp // r2 = &pt_regs.r8 + adds r3=PT(R10)+16,sp // r3 = &pt_regs.r10 + ;; + .mem.offset 0,0 +(p6) st8.spill [r2]=r8 // store return value in slot for r8 and set unat bit + .mem.offset 8,0 +(p6) st8.spill [r3]=r0 // clear error indication in slot for r10 and set unat bit +(p7) br.cond.spnt handle_syscall_error // handle potential syscall failure +END(ia64_ret_from_execve_syscall) + // fall through GLOBAL_ENTRY(ia64_leave_kernel) PT_REGS_UNWIND_INFO(0) lfetch.fault [sp] movl r14=.restart ;; mov.ret.sptk rp=r14,.restart + cmp.eq p0,pLvSys=r0,r0 // pLvSys=0: leave from kernel .restart: // need_resched and signals atomic test (pUser) rsm psr.i @@ -550,18 +738,35 @@ (p7) br.call.spnt.many b7=schedule #endif (p8) br.call.spnt.many rp=handle_signal_delivery // check & deliver pending signals (once) + + adds r20=PT(CR_IPSR)+16,r12 + adds r21=PT(PR)+16,r12 ;; -.ret9: adds r2=PT(R8)+16,r12 - adds r3=PT(R9)+16,r12 + lfetch.fault.excl [r20] + lfetch.fault.excl [r21] + adds r2=PT(B6)+16,r12 + adds r3=PT(R16)+16,r12 + mov r29=PT(R24)-PT(B6) + mov r30=PT(B7)-PT(R24) ;; // start restoring the state saved on the kernel stack (struct pt_regs): - ld8.fill r8=[r2],16 - ld8.fill r9=[r3],16 + ld8 r28=[r2],r29 // b6 + ld8.fill r16=[r3],128 + mov r31=PT(AR_CSD)-PT(AR_CCV) + ;; + ld8.fill r24=[r2],r30 + ld8 r15=[r3],r31 + ;; + ld8 r29=[r2],16 // b7 + ld8 r30=[r3],16 // ar.csd + ;; + ld8 r31=[r2],16 // ar.ssd + ld8.fill r8=[r3],16 ;; - ld8.fill r10=[r2],16 - ld8.fill r11=[r3],16 + ld8.fill r9=[r2],16 + ld8.fill r10=[r3],PT(R17)-PT(R10) ;; - ld8.fill r16=[r2],16 + ld8.fill r11=[r2],PT(R18)-PT(R11) ld8.fill r17=[r3],16 ;; ld8.fill r18=[r2],16 @@ -569,82 +774,78 @@ ;; ld8.fill r20=[r2],16 ld8.fill r21=[r3],16 - ;; - ld8.fill r22=[r2],16 - ld8.fill r23=[r3],16 - ;; - ld8.fill r24=[r2],16 - ld8.fill r25=[r3],16 - ;; - ld8.fill r26=[r2],16 - ld8.fill r27=[r3],16 - ;; - ld8.fill r28=[r2],16 - ld8.fill r29=[r3],16 - ;; - ld8.fill r30=[r2],16 - ld8.fill r31=[r3],16 + mov ar.csd=r30 + mov ar.ssd=r31 ;; rsm psr.i | psr.ic // initiate turning off of interrupt and interruption collection invala // invalidate ALAT ;; - ld8 r1=[r2],16 // ar.ccv - ld8 r13=[r3],16 // ar.fpsr + ld8.fill r22=[r2],24 + ld8.fill r23=[r3],24 + mov b6=r28 + ;; + ld8.fill r25=[r2],16 + ld8.fill r26=[r3],16 + mov b7=r29 ;; - ld8 r14=[r2],16 // b0 - ld8 r15=[r3],16+8 // b7 + ld8.fill r27=[r2],16 + ld8.fill r28=[r3],16 ;; - ldf.fill f6=[r2],32 - ldf.fill f7=[r3],32 + ld8.fill r29=[r2],16 + ld8.fill r30=[r3],24 ;; - ldf.fill f8=[r2],32 - ldf.fill f9=[r3],32 + ld8.fill r31=[r2],32 + ldf.fill f6=[r3],32 ;; - mov ar.ccv=r1 - mov ar.fpsr=r13 - mov b0=r14 + ldf.fill f7=[r2],32 + ldf.fill f8=[r3],32 ;; srlz.i // ensure interruption collection is off - mov b7=r15 + mov ar.ccv=r15 ;; + ldf.fill f9=[r2],32 + ldf.fill f10=[r3],32 bsw.0 // switch back to bank 0 ;; - adds r16=16,r12 - adds r17=24,r12 + ldf.fill f11=[r2] + adds r16=PT(CR_IPSR)+16,r12 + adds r17=PT(CR_IIP)+16,r12 ;; - ld8 rCRIPSR=[r16],16 // load cr.ipsr - ld8 rCRIIP=[r17],16 // load cr.iip + ld8 r29=[r16],16 // load cr.ipsr + ld8 r28=[r17],16 // load cr.iip ;; - ld8 rCRIFS=[r16],16 // load cr.ifs - ld8 rARUNAT=[r17],16 // load ar.unat + ld8 r30=[r16],16 // load cr.ifs + ld8 r25=[r17],16 // load ar.unat cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs ;; - ld8 rARPFS=[r16],16 // load ar.pfs - ld8 rARRSC=[r17],16 // load ar.rsc + ld8 r26=[r16],16 // load ar.pfs + ld8 r27=[r17],16 // load ar.rsc ;; - ld8 rARRNAT=[r16],16 // load ar.rnat (may be garbage) - ld8 rARBSPSTORE=[r17],16 // load ar.bspstore (may be garbage) + ld8 r24=[r16],16 // load ar.rnat (may be garbage) + ld8 r23=[r17],16 // load ar.bspstore (may be garbage) ;; - ld8 rARPR=[r16],16 // load predicates - ld8 rB6=[r17],16 // load b6 + ld8 r31=[r16],16 // load predicates + ld8 r21=[r17],16 // load b0 ;; ld8 r19=[r16],16 // load ar.rsc value for "loadrs" ld8.fill r1=[r17],16 // load r1 ;; - ld8.fill r2=[r16],16 - ld8.fill r3=[r17],16 - ;; ld8.fill r12=[r16],16 ld8.fill r13=[r17],16 ;; + ld8 r20=[r16],16 + ld8.fill r15=[r17],16 + ;; ld8.fill r14=[r16] - ld8.fill r15=[r17] - shr.u r18=r19,16 // get byte size of existing "dirty" partition + ld8.fill r2=[r17],16 + adds r18=16,r16 ;; mov r16=ar.bsp // get existing backing store pointer movl r17=PERCPU_ADDR+IA64_CPU_PHYS_STACKED_SIZE_P8_OFFSET ;; + ld8.fill r3=[r18] ld4 r17=[r17] // r17 = cpu_data->phys_stacked_size_p8 + shr.u r18=r19,16 // get byte size of existing "dirty" partition (pKern) br.cond.dpnt skip_rbs_switch /* * Restore user backing store. @@ -652,7 +853,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 +879,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 @@ -716,7 +905,7 @@ }{ .mib mov loc3=0 mov loc4=0 -(pRecurse) br.call.sptk.many b6=rse_clear_invalid +(pRecurse) br.call.sptk.many b0=rse_clear_invalid }{ .mfi // cycle 2 mov loc5=0 @@ -725,7 +914,7 @@ }{ .mib mov loc6=0 mov loc7=0 -(pReturn) br.ret.sptk.many b6 +(pReturn) br.ret.sptk.many b0 } #else /* !CONFIG_ITANIUM */ alloc loc0=ar.pfs,2,Nregs-2,2,0 @@ -737,17 +926,17 @@ ;; mov loc3=0 mov loc4=0 - mov loc9=0 mov loc5=0 mov loc6=0 -(pRecurse) br.call.sptk.many b6=rse_clear_invalid - ;; mov loc7=0 +(pRecurse) br.call.sptk.many b0=rse_clear_invalid + ;; 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 -(pReturn) br.ret.sptk.many b6 +(pReturn) br.ret.sptk.many b0 #endif /* !CONFIG_ITANIUM */ # undef pRecurse # undef pReturn @@ -757,17 +946,22 @@ loadrs ;; skip_rbs_switch: - mov b6=rB6 - mov ar.pfs=rARPFS -(pUser) mov ar.bspstore=rARBSPSTORE -(p9) mov cr.ifs=rCRIFS - mov cr.ipsr=rCRIPSR - mov cr.iip=rCRIIP - ;; -(pUser) mov ar.rnat=rARRNAT // must happen with RSE in lazy mode - mov ar.rsc=rARRSC - mov ar.unat=rARUNAT - mov pr=rARPR,-1 +(pLvSys)mov r19=r0 // clear r19 for leave_syscall, no-op otherwise + mov b0=r21 + mov ar.pfs=r26 +(pUser) mov ar.bspstore=r23 +(p9) mov cr.ifs=r30 +(pLvSys)mov r16=r0 // clear r16 for leave_syscall, no-op otherwise + mov cr.ipsr=r29 + mov ar.fpsr=r20 +(pLvSys)mov r17=r0 // clear r17 for leave_syscall, no-op otherwise + mov cr.iip=r28 + ;; +(pUser) mov ar.rnat=r24 // must happen with RSE in lazy mode +(pLvSys)mov r18=r0 // clear r18 for leave_syscall, no-op otherwise + mov ar.rsc=r27 + mov ar.unat=r25 + mov pr=r31,-1 rfi END(ia64_leave_kernel) @@ -793,7 +987,7 @@ ;; .mem.offset 0,0; st8.spill [r2]=r9 // store errno in pt_regs.r8 and set unat bit .mem.offset 8,0; st8.spill [r3]=r10 // store error indication in pt_regs.r10 and set unat bit - br.cond.sptk ia64_leave_kernel + br.cond.sptk ia64_leave_syscall END(handle_syscall_error) /* @@ -848,13 +1042,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 +1070,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 @@ -902,6 +1098,22 @@ .body cmp.eq pNonSys,pSys=r0,r0 // sigreturn isn't a normal syscall... ;; + /* After signal handler, live registers f6-f11 are restored to the previous + * executing context values for synchronized signals(from exceptions); or they + * are cleared to 0 for asynchronized signals(from syscalls). These live registers + * will be put into pt_regs to return back to user space. + */ + adds r16=PT(F6)+32,sp + adds r17=PT(F7)+32,sp + ;; + stf.spill [r16]=f6,32 + stf.spill [r17]=f7,32 + ;; + stf.spill [r16]=f8,32 + stf.spill [r17]=f9,32 + ;; + stf.spill [r16]=f10 + stf.spill [r17]=f11 adds out0=16,sp // out0 = &sigscratch br.call.sptk.many rp=ia64_rt_sigreturn .ret19: .restore sp 0 @@ -915,17 +1127,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) // Index: arch/ia64/kernel/entry.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/entry.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/entry.h 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/entry.h 4 Aug 2004 01:25:43 -0000 1.2 @@ -4,6 +4,7 @@ * Preserved registers that are shared between code in ivt.S and entry.S. Be * careful not to step on these! */ +#define pLvSys p1 /* set 1 if leave from syscall; otherwise, set 0*/ #define pKern p2 /* will leave_kernel return to kernel-mode? */ #define pUser p3 /* will leave_kernel return to user-mode? */ #define pSys p4 /* are we processing a (synchronous) system call? */ @@ -13,7 +14,7 @@ #define SW(f) (IA64_SWITCH_STACK_##f##_OFFSET) #define PT_REGS_SAVES(off) \ - .unwabi @svr4, 'i'; \ + .unwabi 3, 'i'; \ .fframe IA64_PT_REGS_SIZE+16+(off); \ .spillsp rp, PT(CR_IIP)+16+(off); \ .spillsp ar.pfs, PT(CR_IFS)+16+(off); \ Index: arch/ia64/kernel/gate.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/gate.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/gate.S 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/gate.S 4 Aug 2004 01:25:43 -0000 1.2 @@ -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 @@ -84,14 +88,12 @@ ld8 r15=[base1] // get address of new RBS base (or NULL) cover // push args in interrupted frame onto backing store ;; - cmp.ne p8,p0=r15,r0 // do we need to switch the rbs? + cmp.ne p1,p0=r15,r0 // do we need to switch rbs? (note: pr is saved by kernel) mov.m r9=ar.bsp // fetch ar.bsp - .spillsp.p p8, ar.rnat, RNAT_OFF+SIGCONTEXT_OFF -(p8) br.cond.spnt setup_rbs // yup -> (clobbers r14, r15, and r16) + .spillsp.p p1, ar.rnat, RNAT_OFF+SIGCONTEXT_OFF +(p1) br.cond.spnt setup_rbs // yup -> (clobbers p8, r14-r16, and r18-r20) 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,9 +130,8 @@ 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) + cmp.ne p1,p0=r14,r15 // do we need to restore the rbs? +(p1) br.cond.spnt restore_rbs // yup -> (clobbers r14-r18, f6 & f7) ;; back_from_restore_rbs: adds base0=(FR6_OFF+SIGCONTEXT_OFF),sp @@ -156,36 +152,43 @@ 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 ;; - .save ar.rnat, r16 - mov r16=ar.rnat // save RNaT before switching backing store area + .save ar.rnat, r19 + mov r19=ar.rnat // save RNaT before switching backing store area adds r14=(RNAT_OFF+SIGCONTEXT_OFF),sp + mov r18=ar.bspstore mov ar.bspstore=r15 // switch over to new register backing store area ;; - .spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF - st8 [r14]=r16 // save sc_ar_rnat - adds r14=(LOADRS_OFF+SIGCONTEXT_OFF),sp + .spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF + st8 [r14]=r19 // save sc_ar_rnat + .body mov.m r16=ar.bsp // sc_loadrs <- (new bsp - new bspstore) << 16 + adds r14=(LOADRS_OFF+SIGCONTEXT_OFF),sp ;; invala sub r15=r16,r15 + extr.u r20=r18,3,6 ;; + mov ar.rsc=0xf // set RSE into eager mode, pl 3 + cmp.eq p8,p0=63,r20 shl r15=r15,16 ;; st8 [r14]=r15 // save sc_loadrs - mov ar.rsc=0xf // set RSE into eager mode, pl 3 +(p8) st8 [r18]=r19 // if bspstore points at RNaT slot, store RNaT there now + .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: Index: arch/ia64/kernel/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/head.S 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/head.S 4 Aug 2004 01:25:43 -0000 1.2 @@ -5,7 +5,7 @@ * to set up the kernel's global pointer and jump to the kernel * entry point. * - * Copyright (C) 1998-2001 Hewlett-Packard Co + * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co * David Mosberger-Tang * Stephane Eranian * Copyright (C) 1999 VA Linux Systems @@ -15,6 +15,7 @@ * Copyright (C) 1999 Don Dugger * Copyright (C) 2002 Fenghua Yu * -Optimize __ia64_save_fpu() and __ia64_load_fpu() for Itanium 2. + * Copyright (C) 2003 Silicon Graphics, Inc. */ #include @@ -65,17 +66,29 @@ * that maps the kernel's text and data: */ rsm psr.i | psr.ic - mov r16=((ia64_rid(IA64_REGION_ID_KERNEL, PAGE_OFFSET) << 8) | (IA64_GRANULE_SHIFT << 2)) ;; srlz.i + ;; + mov r20=((ia64_rid(IA64_REGION_ID_KERNEL, (7<<61)) << 8) | (IA64_GRANULE_SHIFT << 2)) + movl r21=(7<<61) + ;; + mov rr[r21]=r20 + ;; + /* + * Now pin mappings into the TLB for kernel text and data + */ mov r18=KERNEL_TR_PAGE_SHIFT<<2 movl r17=KERNEL_START ;; - mov rr[r17]=r16 mov cr.itir=r18 mov cr.ifa=r17 mov r16=IA64_TR_KERNEL - movl r18=((1 << KERNEL_TR_PAGE_SHIFT) | PAGE_KERNEL) + mov r3=ip + movl r18=PAGE_KERNEL + ;; + dep r2=0,r3,0,KERNEL_TR_PAGE_SHIFT + ;; + or r18=r2,r18 ;; srlz.i ;; @@ -134,28 +147,63 @@ movl r3=cpucount ;; ld4 r3=[r3] // r3 <- smp_processor_id() - movl r2=init_tasks - ;; - shladd r2=r3,3,r2 - ;; - ld8 r2=[r2] #else mov r3=0 - movl r2=init_task_union - ;; #endif + ;; cmp4.ne isAP,isBP=r3,r0 - ;; // RAW on r2 - extr r3=r2,0,61 // r3 == phys addr of task struct - mov r16=KERNEL_TR_PAGE_NUM + + /* + * Make task struct pointer in init_tasks an identity mapped pointer. + * The value that is compiled into the array may not be identity mapped. + */ + movl r18=init_tasks + ;; + shladd r18=r3,3,r18 + ;; + ld8 r8=[r18] + ;; + tpa r3=r8 // r3 == phys addr of task struct + ;; + dep r2=-1,r3,61,3 // IMVA of task + ;; + st8 [r18]=r2 // and save it back in init_tasks[thiscpu] + + // load mapping for stack (virtaddr in r2, physaddr in r3) + // load dtr[2] only if the va for current (r2) isn't covered by the dtr[0] + shr.u r18=r2,KERNEL_TR_PAGE_SHIFT /* va of current in units of kernel-pages */ + movl r17=KERNEL_START>>KERNEL_TR_PAGE_SHIFT /* va of kernel-start in units of kernel-pages */ + ;; + cmp.eq p0,p6=r17,r18 + rsm psr.ic + movl r17=PAGE_KERNEL + ;; + srlz.d + dep r18=0,r3,0,12 + ;; + or r18=r17,r18 + ;; + mov r17=rr[r2] + shr.u r16=r3,IA64_GRANULE_SHIFT + ;; + dep r17=0,r17,8,24 + ;; + mov cr.itir=r17 + mov cr.ifa=r2 + + mov r19=IA64_TR_CURRENT_STACK + ;; +(p6) itr.d dtr[r19]=r18 + ;; + ssm psr.ic + srlz.d ;; // load the "current" pointer (r13) and ar.k6 with the current task - mov r13=r2 mov IA64_KR(CURRENT)=r3 // Physical address - - // initialize k4 to a safe value (64-128MB is mapped by TR_KERNEL) mov IA64_KR(CURRENT_STACK)=r16 + mov r13=r2 + /* * Reserve space at the top of the stack for "struct pt_regs". Kernel threads * don't store interesting values in that structure, but the space still needs @@ -670,14 +718,14 @@ END(__ia64_init_fpu) /* - * Switch execution mode from virtual to physical or vice versa. + * Switch execution mode from virtual to physical * * Inputs: * r16 = new psr to establish * * Note: RSE must already be in enforced lazy mode */ -GLOBAL_ENTRY(ia64_switch_mode) +GLOBAL_ENTRY(ia64_switch_mode_phys) { alloc r2=ar.pfs,0,0,0,0 rsm psr.i | psr.ic // disable interrupts and interrupt collection @@ -687,35 +735,86 @@ { flushrs // must be first insn in group srlz.i - shr.u r19=r15,61 // r19 <- top 3 bits of current IP } ;; mov cr.ipsr=r16 // set new PSR - add r3=1f-ia64_switch_mode,r15 - xor r15=0x7,r19 // flip the region bits + add r3=1f-ia64_switch_mode_phys,r15 mov r17=ar.bsp mov r14=rp // get return address into a general register + ;; - // switch RSE backing store: + // going to physical mode, use tpa to translate virt->phys + tpa r17=r17 + tpa r3=r3 + tpa sp=sp + tpa r14=r14 ;; - dep r17=r15,r17,61,3 // make ar.bsp physical or virtual + mov r18=ar.rnat // save ar.rnat - ;; mov ar.bspstore=r17 // this steps on ar.rnat - dep r3=r15,r3,61,3 // make rfi return address physical or virtual + mov cr.iip=r3 + mov cr.ifs=r0 + ;; + mov ar.rnat=r18 // restore ar.rnat + rfi // must be last insn in group + ;; +1: mov rp=r14 + br.ret.sptk.many rp +END(ia64_switch_mode_phys) + +/* + * Switch execution mode from physical to virtual + * + * Inputs: + * r16 = new psr to establish + * + * Note: RSE must already be in enforced lazy mode + */ +GLOBAL_ENTRY(ia64_switch_mode_virt) + { + alloc r2=ar.pfs,0,0,0,0 + rsm psr.i | psr.ic // disable interrupts and interrupt collection + mov r15=ip + } + ;; + { + flushrs // must be first insn in group + srlz.i + } ;; + mov cr.ipsr=r16 // set new PSR + add r3=1f-ia64_switch_mode_virt,r15 + + mov r17=ar.bsp + mov r14=rp // get return address into a general register + ;; + + // going to virtual + // - for code addresses, set upper bits of addr to KERNEL_START + // - for stack addresses, set upper 3 bits to 0xe.... Dont change any of the + // lower bits since we want it to stay identity mapped + movl r18=KERNEL_START + dep r3=0,r3,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT + dep r14=0,r14,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT + dep r17=-1,r17,61,3 + dep sp=-1,sp,61,3 + ;; + or r3=r3,r18 + or r14=r14,r18 + ;; + + mov r18=ar.rnat // save ar.rnat + mov ar.bspstore=r17 // this steps on ar.rnat mov cr.iip=r3 mov cr.ifs=r0 - dep sp=r15,sp,61,3 // make stack pointer physical or virtual ;; mov ar.rnat=r18 // restore ar.rnat - dep r14=r15,r14,61,3 // make function return address physical or virtual rfi // must be last insn in group ;; 1: mov rp=r14 br.ret.sptk.many rp -END(ia64_switch_mode) +END(ia64_switch_mode_virt) #ifdef CONFIG_IA64_BRL_EMU @@ -782,6 +881,9 @@ ;; // delay a little... .wait: sub tmp=tmp,timeout +#ifdef GAS_HAS_HINT_INSN + hint @pause +#endif or delay=0xf,delay // make sure delay is non-zero (otherwise we get stuck with 0) ;; cmp.lt p15,p0=tmp,r0 Index: arch/ia64/kernel/ia64_ksyms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/ia64_ksyms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/ia64_ksyms.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/ia64_ksyms.c 4 Aug 2004 01:25:43 -0000 1.2 @@ -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); @@ -165,3 +169,9 @@ EXPORT_SYMBOL(pfm_install_alternate_syswide_subsystem); EXPORT_SYMBOL(pfm_remove_alternate_syswide_subsystem); #endif + +#ifdef CONFIG_ACPI +#include +extern acpi_status acpi_hp_csr_space(acpi_handle, u64 *, u64 *); +EXPORT_SYMBOL(acpi_hp_csr_space); +#endif Index: arch/ia64/kernel/iosapic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/iosapic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/iosapic.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/iosapic.c 4 Aug 2004 01:25:43 -0000 1.2 @@ -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; @@ -540,21 +530,20 @@ delivery = IOSAPIC_INIT; break; case ACPI_INTERRUPT_CPEI: - vector = IA64_PCE_VECTOR; + vector = IA64_CPE_VECTOR; 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; } Index: arch/ia64/kernel/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/irq.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/irq.c 4 Aug 2004 01:25:43 -0000 1.2 @@ -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; } Index: arch/ia64/kernel/irq_ia64.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/irq_ia64.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/irq_ia64.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/irq_ia64.c 4 Aug 2004 01:25:43 -0000 1.2 @@ -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 Index: arch/ia64/kernel/irq_lsapic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/irq_lsapic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/irq_lsapic.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/irq_lsapic.c 4 Aug 2004 01:25:43 -0000 1.2 @@ -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 }; Index: arch/ia64/kernel/ivt.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/ivt.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/ivt.S 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/ivt.S 4 Aug 2004 01:25:43 -0000 1.2 @@ -1,6 +1,10 @@ /* * arch/ia64/kernel/ivt.S * + * Copyright (C) 2002-2003 Intel Co + * Suresh Siddha + * Kenneth Chen + * Fenghua Yu * Copyright (C) 1998-2001 Hewlett-Packard Co * Stephane Eranian * David Mosberger @@ -114,6 +118,10 @@ * - the faulting virtual address has no L1, L2, or L3 mapping */ mov r16=cr.ifa // get address that caused the TLB miss +#ifdef CONFIG_HUGETLB_PAGE + movl r18=PAGE_SHIFT + mov r25=cr.itir +#endif ;; rsm psr.dt // use physical addressing for data mov r31=pr // save the predicate registers @@ -121,8 +129,18 @@ shl r21=r16,3 // shift bit 60 into sign bit shr.u r17=r16,61 // get the region number into r17 ;; + shr r22=r21,3 +#ifdef CONFIG_HUGETLB_PAGE + extr.u r26=r25,2,6 + ;; + cmp.eq p8,p0=HPAGE_SHIFT,r26 + ;; +(p8) dep r25=r18,r25,2,6 +(p8) shr r22=r22,HPAGE_SHIFT-PAGE_SHIFT +#endif + ;; cmp.eq p6,p7=5,r17 // is IFA pointing into to region 5? - shr.u r18=r16,PGDIR_SHIFT // get bits 33-63 of the faulting address + shr.u r18=r22,PGDIR_SHIFT // get bits 33-63 of the faulting address ;; (p7) dep r17=r17,r19,(PAGE_SHIFT-3),3 // put region number bits in place srlz.d // ensure "rsm psr.dt" has taken effect @@ -133,7 +151,7 @@ (p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=PTA + IFA(33,42)*8 (p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8) cmp.eq p7,p6=0,r21 // unused address bits all zeroes? - shr.u r18=r16,PMD_SHIFT // shift L2 index into position + shr.u r18=r22,PMD_SHIFT // shift L2 index into position ;; ld8 r17=[r17] // fetch the L1 entry (may be 0) ;; @@ -141,7 +159,7 @@ dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry ;; (p7) ld8 r20=[r17] // fetch the L2 entry (may be 0) - shr.u r19=r16,PAGE_SHIFT // shift L3 index into position + shr.u r19=r22,PAGE_SHIFT // shift L3 index into position ;; (p7) cmp.eq.or.andcm p6,p7=r20,r0 // was L2 entry NULL? dep r21=r19,r20,3,(PAGE_SHIFT-3) // compute address of L3 page table entry @@ -160,6 +178,10 @@ (p6) br.cond.spnt.many page_fault // handle bad address/page not present (page fault) mov cr.ifa=r22 +#ifdef CONFIG_HUGETLB_PAGE +(p8) mov cr.itir=r25 // change to default page-size for VHPT +#endif + /* * Now compute and insert the TLB entry for the virtual page table. We never * execute in a page table page so there is no need to set the exception deferral @@ -621,6 +643,23 @@ ///////////////////////////////////////////////////////////////////////////////////////// // 0x2c00 Entry 11 (size 64 bundles) Break instruction (33) ENTRY(break_fault) + +/* System call entry/exit only saves/restores part of pt_regs, i.e. no scratch registers + * are saved/restored except r15 which contains syscall number and needs to be saved in the + * entry. This optimization is based on the assumption that applications only call glibc + * system call interface which doesn't use scratch registers after break into kernel. + * Registers saved/restored during system call entry/exit are listed as follows: + * + * Registers to be saved & restored: + * CR registers: cr_ipsr, cr_iip, cr_ifs + * AR registers: ar_unat, ar_pfs, ar_rsc, ar_rnat, ar_bspstore, ar_fpsr + * others: pr, b0, loadrs, r1, r12, r13, r15 + * Registers to be restored only: + * r8~r11: output value from the system call. + * + * During system call exit, scratch registers (including r15) are modified/cleared to + * prevent leaking bits from kernel to user level. + */ DBG_FAULT(11) mov r16=cr.iim mov r17=__IA64_BREAK_SYSCALL @@ -629,22 +668,25 @@ cmp.eq p0,p7=r16,r17 // is this a system call? (p7 <- false, if so) (p7) br.cond.spnt non_syscall - SAVE_MIN // uses r31; defines r2: - - ssm psr.ic | PSR_DEFAULT_BITS + mov r21=ar.fpsr; + mov r29=cr.ipsr; + mov r20=r1; + mov r25=ar.unat; + mov r27=ar.rsc; + mov r26=ar.pfs; + mov r28=cr.iip; + mov r1=IA64_KR(CURRENT); /* r1 = current (physical) */ + ;; + invala; + extr.u r16=r29,32,2; /* extract psr.cpl */ + ;; + cmp.eq pKern,pUser=r0,r16; /* are we in kernel mode already? (psr.cpl==0) */ + /* switch from user to kernel RBS: */ + ;; + mov r30=r0 + MINSTATE_START_SAVE_MIN_VIRT + br.call.sptk.many b7=ia64_syscall_setup ;; - srlz.i // guarantee that interruption collection is on - cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0 - ;; -(p15) ssm psr.i // restore psr.i - adds r8=(IA64_PT_REGS_R8_OFFSET-IA64_PT_REGS_R16_OFFSET),r2 - ;; - stf8 [r8]=f1 // ensure pt_regs.r8 != 0 (see handle_syscall_error) - adds r3=8,r2 // set up second base pointer for SAVE_REST - ;; - SAVE_REST - br.call.sptk.many rp=demine_args // clear NaT bits in (potential) syscall args - mov r3=255 adds r15=-1024,r15 // r15 contains the syscall number---subtract 1024 adds r2=IA64_TASK_PTRACE_OFFSET,r13 // r2 = ¤t->ptrace @@ -664,8 +706,8 @@ // arrange things so we skip over break instruction when returning: - adds r16=16,sp // get pointer to cr_ipsr - adds r17=24,sp // get pointer to cr_iip + adds r16=PT(CR_IPSR)+16,sp // get pointer to cr_ipsr + adds r17=PT(CR_IIP)+16,sp // get pointer to cr_iip ;; ld8 r18=[r16] // fetch cr_ipsr tbit.z p8,p0=r2,PT_TRACESYS_BIT // (current->ptrace & PF_TRACESYS) == 0? @@ -685,38 +727,11 @@ st8 [r16]=r18 // store new value for cr.isr (p8) br.call.sptk.many b6=b6 // ignore this return addr + br.cond.sptk ia64_trace_syscall // NOT REACHED END(break_fault) -ENTRY(demine_args) - alloc r2=ar.pfs,8,0,0,0 - tnat.nz p8,p0=in0 - tnat.nz p9,p0=in1 - ;; -(p8) mov in0=-1 - tnat.nz p10,p0=in2 - tnat.nz p11,p0=in3 - -(p9) mov in1=-1 - tnat.nz p12,p0=in4 - tnat.nz p13,p0=in5 - ;; -(p10) mov in2=-1 - tnat.nz p14,p0=in6 - tnat.nz p15,p0=in7 - -(p11) mov in3=-1 - tnat.nz p8,p0=r15 // demining r15 is not a must, but it is safer - -(p12) mov in4=-1 -(p13) mov in5=-1 - ;; -(p14) mov in6=-1 -(p15) mov in7=-1 -(p8) mov r15=-1 - br.ret.sptk.many rp -END(demine_args) .align 1024 ///////////////////////////////////////////////////////////////////////////////////////// @@ -725,7 +740,6 @@ DBG_FAULT(12) mov r31=pr // prepare to save predicates ;; - SAVE_MIN_WITH_COVER // uses r31; defines r2 and r3 ssm psr.ic | PSR_DEFAULT_BITS ;; @@ -757,6 +771,125 @@ DBG_FAULT(14) FAULT(14) + /* + * There is no particular reason for this code to be here, other than that + * there happens to be space here that would go unused otherwise. If this + * fault ever gets "unreserved", simply moved the following code to a more + * suitable spot... + * + * ia64_syscall_setup() is a separate subroutine so that it can + * allocate stacked registers so it can safely demine any + * potential NaT values from the input registers. + * + * On entry: + * - executing on bank 0 or bank 1 register set (doesn't matter) + * - r1: stack pointer + * - r2: current task pointer + * - r3: preserved + * - r12: original contents (sp to be saved) + * - r13: original contents (tp to be saved) + * - r15: original contents (syscall # to be saved) + * - r18: saved bsp (after switching to kernel stack) + * - r20: saved r1 (gp) + * - r21: saved ar.fpsr + * - r22: kernel's register backing store base (krbs_base) + * - r23: saved ar.bspstore + * - r24: saved ar.rnat + * - r25: saved ar.unat + * - r26: saved ar.pfs + * - r27: saved ar.rsc + * - r28: saved cr.iip + * - r29: saved cr.ipsr + * - r31: saved pr + * - b0: original contents (to be saved) + * On exit: + * - executing on bank 1 registers + * - psr.ic enabled, interrupts restored + * - r1: kernel's gp + * - r3: preserved (same as on entry) + * - r12: points to kernel stack + * - r13: points to current task + * - p15: TRUE if interrupts need to be re-enabled + * - ar.fpsr: set to kernel settings + */ +ENTRY(ia64_syscall_setup) + alloc r19=ar.pfs,8,0,0,0 + tnat.nz p8,p0=in0 + add r16=PT(CR_IPSR),r1 /* initialize first base pointer */ + ;; + st8 [r16]=r29,16; /* save cr.ipsr */ + adds r17=PT(CR_IIP),r1; /* initialize second base pointer */ + ;; +(p8) mov in0=-1 + tnat.nz p9,p0=in1 + st8 [r17]=r28,16; /* save cr.iip */ + mov r28=b0; +(pKern) mov r18=r0; /* make sure r18 isn't NaT */ + ;; +(p9) mov in1=-1 + tnat.nz p10,p0=in2 + st8 [r16]=r30,16; /* save cr.ifs */ + st8 [r17]=r25,16; /* save ar.unat */ +(pUser) sub r18=r18,r22; /* r18=RSE.ndirty*8 */ + ;; + st8 [r16]=r26,16; /* save ar.pfs */ + st8 [r17]=r27,16; /* save ar.rsc */ + tbit.nz p15,p0=r29,IA64_PSR_I_BIT + ;; /* avoid RAW on r16 & r17 */ +(p10) mov in2=-1 + nop.f 0 + tnat.nz p11,p0=in3 +(pKern) adds r16=16,r16; /* skip over ar_rnat field */ +(pKern) adds r17=16,r17; /* skip over ar_bspstore field */ + shl r18=r18,16; /* compute ar.rsc to be used for "loadrs" */ + ;; +(p11) mov in3=-1 + tnat.nz p12,p0=in4 +(pUser) st8 [r16]=r24,16; /* save ar.rnat */ +(pUser) st8 [r17]=r23,16; /* save ar.bspstore */ + ;; +(p12) mov in4=-1 + tnat.nz p13,p0=in5 + st8 [r16]=r31,16; /* save predicates */ + st8 [r17]=r28,16; /* save b0 */ + dep r14=-1,r0,61,3; + ;; + st8 [r16]=r18,16; /* save ar.rsc value for "loadrs" */ + st8.spill [r17]=r20,16; /* save original r1 */ + adds r2=IA64_PT_REGS_R16_OFFSET,r1; + ;; +(p13) mov in5=-1 + tnat.nz p14,p0=in6 +.mem.offset 0,0; st8.spill [r16]=r12,16; +.mem.offset 8,0; st8.spill [r17]=r13,16; + cmp.eq pNonSys,pSys=r0,r0 /* initialize pSys=0, pNonSys=1 */ + ;; +(p14) mov in6=-1 + tnat.nz p8,p0=in7 +.mem.offset 0,0; st8 [r16]=r21,16; /* ar.fpsr */ +.mem.offset 8,0; st8.spill [r17]=r15,16; + adds r12=-16,r1; /* switch to kernel memory stack (with 16 bytes of scratch) */ + ;; + mov r13=IA64_KR(CURRENT); /* establish `current' */ + movl r1=__gp; /* establish kernel global pointer */ + ;; + MINSTATE_END_SAVE_MIN_VIRT + + tnat.nz p9,p0=r15 +(p8) mov in7=-1 + ssm psr.ic | PSR_DEFAULT_BITS + movl r17=FPSR_DEFAULT + adds r8=(IA64_PT_REGS_R8_OFFSET-IA64_PT_REGS_R16_OFFSET),r2 + ;; + srlz.i // guarantee that interruption collection is on + cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0 +(p9) mov r15=-1 +(p15) ssm psr.i // restore psr.i + mov.m ar.fpsr=r17 + stf8 [r8]=f1 // ensure pt_regs.r8 != 0 (see handle_syscall_error) + br.ret.sptk.many b7 +END(ia64_syscall_setup) + .align 1024 ///////////////////////////////////////////////////////////////////////////////////////// // 0x3c00 Entry 15 (size 64 bundles) Reserved @@ -808,90 +941,6 @@ DBG_FAULT(16) FAULT(16) -#ifdef CONFIG_IA32_SUPPORT - - /* - * There is no particular reason for this code to be here, other than that - * there happens to be space here that would go unused otherwise. If this - * fault ever gets "unreserved", simply moved the following code to a more - * suitable spot... - */ - - // IA32 interrupt entry point - -ENTRY(dispatch_to_ia32_handler) - SAVE_MIN - ;; - mov r14=cr.isr - ssm psr.ic | PSR_DEFAULT_BITS - ;; - srlz.i // guarantee that interruption collection is on - ;; -(p15) ssm psr.i - adds r3=8,r2 // Base pointer for SAVE_REST - ;; - SAVE_REST - ;; - mov r15=0x80 - shr r14=r14,16 // Get interrupt number - ;; - cmp.ne p6,p0=r14,r15 -(p6) br.call.dpnt.many b6=non_ia32_syscall - - adds r14=IA64_PT_REGS_R8_OFFSET + 16,sp // 16 byte hole per SW conventions - adds r15=IA64_PT_REGS_R1_OFFSET + 16,sp - ;; - cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0 - st8 [r15]=r8 // save original EAX in r1 (IA32 procs don't use the GP) - ;; - alloc r15=ar.pfs,0,0,6,0 // must first in an insn group - ;; - ld4 r8=[r14],8 // r8 == eax (syscall number) - mov r15=230 // number of entries in ia32 system call table - ;; - cmp.ltu.unc p6,p7=r8,r15 - ld4 out1=[r14],8 // r9 == ecx - ;; - ld4 out2=[r14],8 // r10 == edx - ;; - ld4 out0=[r14] // r11 == ebx - adds r14=(IA64_PT_REGS_R8_OFFSET-(8*3)) + 16,sp - ;; - ld4 out5=[r14],8 // r13 == ebp - ;; - ld4 out3=[r14],8 // r14 == esi - adds r2=IA64_TASK_PTRACE_OFFSET,r13 // r2 = ¤t->ptrace - ;; - ld4 out4=[r14] // r15 == edi - movl r16=ia32_syscall_table - ;; -(p6) shladd r16=r8,3,r16 // force ni_syscall if not valid syscall number - ld8 r2=[r2] // r2 = current->ptrace - ;; - ld8 r16=[r16] - tbit.z p8,p0=r2,PT_TRACESYS_BIT // (current->ptrace & PT_TRACESYS) == 0? - ;; - mov b6=r16 - movl r15=ia32_ret_from_syscall - ;; - mov rp=r15 -(p8) br.call.sptk.many b6=b6 - br.cond.sptk ia32_trace_syscall - -non_ia32_syscall: - alloc r15=ar.pfs,0,0,2,0 - mov out0=r14 // interrupt # - add out1=16,sp // pointer to pt_regs - ;; // avoid WAW on CFM - br.call.sptk.many rp=ia32_bad_interrupt -.ret1: movl r15=ia64_leave_kernel - ;; - mov rp=r15 - br.ret.sptk.many rp -END(dispatch_to_ia32_handler) - -#endif /* CONFIG_IA32_SUPPORT */ - .align 1024 ///////////////////////////////////////////////////////////////////////////////////////// // 0x4400 Entry 17 (size 64 bundles) Reserved @@ -1415,3 +1464,89 @@ // 0x7f00 Entry 67 (size 16 bundles) Reserved DBG_FAULT(67) FAULT(67) + +#ifdef CONFIG_IA32_SUPPORT + + /* + * There is no particular reason for this code to be here, other than that + * there happens to be space here that would go unused otherwise. If this + * fault ever gets "unreserved", simply moved the following code to a more + * suitable spot... + */ + + // IA32 interrupt entry point + +ENTRY(dispatch_to_ia32_handler) + SAVE_MIN + ;; + mov r14=cr.isr + ssm psr.ic | PSR_DEFAULT_BITS + ;; + srlz.i // guarantee that interruption collection is on + ;; +(p15) ssm psr.i + adds r3=8,r2 // Base pointer for SAVE_REST + ;; + SAVE_REST + ;; + mov r15=0x80 + shr r14=r14,16 // Get interrupt number + ;; + cmp.ne p6,p0=r14,r15 +(p6) br.call.dpnt.many b6=non_ia32_syscall + + adds r14=IA64_PT_REGS_R8_OFFSET + 16,sp // 16 byte hole per SW conventions + adds r15=IA64_PT_REGS_R1_OFFSET + 16,sp + ;; + cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0 + ld8 r8=[r14] // get r8 + ;; + st8 [r15]=r8 // save original EAX in r1 (IA32 procs don't use the GP) + ;; + alloc r15=ar.pfs,0,0,6,0 // must first in an insn group + ;; + ld4 r8=[r14],8 // r8 == eax (syscall number) + mov r15=230 // number of entries in ia32 system call table + ;; + cmp.ltu.unc p6,p7=r8,r15 + ld4 out1=[r14],8 // r9 == ecx + ;; + ld4 out2=[r14],8 // r10 == edx + ;; + ld4 out0=[r14] // r11 == ebx + adds r14=(IA64_PT_REGS_R13_OFFSET) + 16,sp + ;; + ld4 out5=[r14],PT(R14)-PT(R13) // r13 == ebp + ;; + ld4 out3=[r14],PT(R15)-PT(R14) // r14 == esi + adds r2=IA64_TASK_PTRACE_OFFSET,r13 // r2 = ¤t->ptrace + ;; + ld4 out4=[r14] // r15 == edi + movl r16=ia32_syscall_table + ;; +(p6) shladd r16=r8,3,r16 // force ni_syscall if not valid syscall number + ld8 r2=[r2] // r2 = current->ptrace + ;; + ld8 r16=[r16] + tbit.z p8,p0=r2,PT_TRACESYS_BIT // (current->ptrace & PT_TRACESYS) == 0? + ;; + mov b6=r16 + movl r15=ia32_ret_from_syscall + ;; + mov rp=r15 +(p8) br.call.sptk.many b6=b6 + br.cond.sptk ia32_trace_syscall + +non_ia32_syscall: + alloc r15=ar.pfs,0,0,2,0 + mov out0=r14 // interrupt # + add out1=16,sp // pointer to pt_regs + ;; // avoid WAW on CFM + br.call.sptk.many rp=ia32_bad_interrupt +.ret1: movl r15=ia64_leave_kernel + ;; + mov rp=r15 + br.ret.sptk.many rp +END(dispatch_to_ia32_handler) + +#endif /* CONFIG_IA32_SUPPORT */ Index: arch/ia64/kernel/machvec.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/machvec.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/machvec.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/machvec.c 4 Aug 2004 01:25:43 -0000 1.2 @@ -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 */ Index: arch/ia64/kernel/mca.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/mca.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/mca.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/mca.c 4 Aug 2004 01:25:43 -0000 1.2 @@ -3,7 +3,10 @@ * Purpose: Generic MCA handling layer * * Updated for latest kernel - * Copyright (C) 2002 Dell Computer Corporation + * Copyright (C) 2003 Hewlett-Packard Co + * David Mosberger-Tang + * + * Copyright (C) 2002 Dell Inc. * Copyright (C) Matt Domsch (Matt_Domsch@dell.com) * * Copyright (C) 2002 Intel @@ -15,9 +18,10 @@ * Copyright (C) 2000 Intel * Copyright (C) Chuck Fleckenstein (cfleck@co.intel.com) * - * Copyright (C) 1999 Silicon Graphics, Inc. + * Copyright (C) 1999, 2004 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 @@ -32,6 +36,18 @@ * SAL 3.0 spec. * 00/03/29 C. Fleckenstein Fixed PAL/SAL update issues, began MCA bug fixes, logging issues, * added min save state dump, added INIT handler. + * + * 2003-12-08 Keith Owens + * smp_call_function() must not be called from interrupt context (can + * deadlock on tasklist_lock). Use keventd to call smp_call_function(). + * + * 2004-02-01 Keith Owens + * Avoid deadlock when using printk() for MCA and INIT records. + * Delete all record printing code, moved to salinfo_decode in user space. + * Mark variables and functions static where possible. + * Delete dead variables and functions. + * Reorder to remove the need for forward declarations and to consolidate + * related code. */ #include #include @@ -45,7 +61,10 @@ #include #include #include +#include +#include +#include #include #include #include @@ -56,169 +75,404 @@ #include #include -#undef MCA_PRT_XTRA_DATA +#if defined(IA64_MCA_DEBUG_INFO) +# define IA64_MCA_DEBUG(fmt...) printk(fmt) +#else +# define IA64_MCA_DEBUG(fmt...) +#endif + +extern void show_stack(struct task_struct *); typedef struct ia64_fptr { unsigned long fp; unsigned long gp; } ia64_fptr_t; -ia64_mc_info_t ia64_mc_info; +/* Used by mca_asm.S */ ia64_mca_sal_to_os_state_t ia64_sal_to_os_handoff_state; ia64_mca_os_to_sal_state_t ia64_os_to_sal_handoff_state; u64 ia64_mca_proc_state_dump[512]; 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_mca_sal_data_area[1356]; -u64 ia64_tlb_functional; -u64 ia64_os_mca_recovery_successful; -/* TODO: need to assign min-state structure to UC memory */ -u64 ia64_mca_min_state_save_info[MIN_STATE_AREA_SIZE] __attribute__((aligned(512))); -static void ia64_mca_wakeup_ipi_wait(void); -static void ia64_mca_wakeup(int cpu); -static void ia64_mca_wakeup_all(void); -static void ia64_log_init(int); +u64 ia64_init_stack[INIT_TASK_SIZE/8] __attribute__((aligned(16))); +u64 ia64_mca_serialize; + +/* In mca_asm.S */ extern void ia64_monarch_init_handler (void); extern void ia64_slave_init_handler (void); -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" -}; -static struct irqaction mca_rdzv_irqaction = { - handler: ia64_mca_rendez_int_handler, - flags: SA_INTERRUPT, - name: "mca_rdzv" -}; +static ia64_mc_info_t ia64_mc_info; -static struct irqaction mca_wkup_irqaction = { - handler: ia64_mca_wakeup_int_handler, - flags: SA_INTERRUPT, - name: "mca_wkup" -}; +extern struct hw_interrupt_type irq_type_iosapic_level; -static struct irqaction mca_cpe_irqaction = { - handler: ia64_mca_cpe_int_handler, - flags: SA_INTERRUPT, - name: "cpe_hndlr" -}; +struct ia64_mca_tlb_info ia64_mca_tlb_list[NR_CPUS]; #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; +/* + * This variable tells whether we are currently in polling mode. + * 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; + +/* + * Clearing this variable prevents CPE polling from getting activated + * in mca_late_init. Use it if your system doesn't provide a CPEI, + * but encounters problems retrieving CPE logs. This should only be + * necessary for debugging. + */ +static int cpe_poll_enabled = 1; + +extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe); + +static struct tq_struct cmc_disable_tq, cmc_enable_tq; + +/* + * IA64_MCA log support + */ +#define IA64_MAX_LOGS 2 /* Double-buffering for nested MCAs */ +#define IA64_MAX_LOG_TYPES 4 /* MCA, INIT, CMC, CPE */ + +typedef struct ia64_state_log_s +{ + 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; + +static ia64_state_log_t ia64_state_log[IA64_MAX_LOG_TYPES]; + +#define IA64_LOG_ALLOCATE(it, size) \ + {ia64_state_log[it].isl_log[IA64_LOG_CURR_INDEX(it)] = \ + (ia64_err_rec_t *)alloc_bootmem(size); \ + ia64_state_log[it].isl_log[IA64_LOG_NEXT_INDEX(it)] = \ + (ia64_err_rec_t *)alloc_bootmem(size);} +#define IA64_LOG_LOCK_INIT(it) spin_lock_init(&ia64_state_log[it].isl_lock) +#define IA64_LOG_LOCK(it) spin_lock_irqsave(&ia64_state_log[it].isl_lock, s) +#define IA64_LOG_UNLOCK(it) spin_unlock_irqrestore(&ia64_state_log[it].isl_lock,s) +#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_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_log_init + * Reset the OS ia64 log buffer + * Inputs : info_type (SAL_INFO_TYPE_{MCA,INIT,CMC,CPE}) + * Outputs : None + */ +static void +ia64_log_init(int sal_info_type) +{ + u64 max_size = 0; + + IA64_LOG_NEXT_INDEX(sal_info_type) = 0; + IA64_LOG_LOCK_INIT(sal_info_type); + + // SAL will tell us the maximum size of any error record of this type + max_size = ia64_sal_get_state_info_size(sal_info_type); + if (!max_size) + /* alloc_bootmem() doesn't like zero-sized allocations! */ + return; + + // set up OS data structures to hold error info + IA64_LOG_ALLOCATE(sal_info_type, max_size); + memset(IA64_LOG_CURR_BUFFER(sal_info_type), 0, max_size); + memset(IA64_LOG_NEXT_BUFFER(sal_info_type), 0, max_size); +} + +/* + * ia64_log_get + * + * Get the current MCA log from SAL and copy it into the OS log buffer. + * + * Inputs : info_type (SAL_INFO_TYPE_{MCA,INIT,CMC,CPE}) + * irq_safe whether you can use printk at this point + * Outputs : size (total record length) + * *buffer (ptr to error record) + * + */ +static u64 +ia64_log_get(int sal_info_type, u8 **buffer, int irq_safe) +{ + sal_log_record_header_t *log_buffer; + u64 total_len = 0; + int s; + + IA64_LOG_LOCK(sal_info_type); + + /* Get the process state information */ + log_buffer = IA64_LOG_NEXT_BUFFER(sal_info_type); + + total_len = ia64_sal_get_state_info(sal_info_type, (u64 *)log_buffer); + + if (total_len) { + IA64_LOG_INDEX_INC(sal_info_type); + IA64_LOG_UNLOCK(sal_info_type); + if (irq_safe) { + IA64_MCA_DEBUG("%s: SAL error record type %d retrieved. " + "Record length = %ld\n", __FUNCTION__, sal_info_type, total_len); + } + *buffer = (u8 *) log_buffer; + return total_len; + } else { + IA64_LOG_UNLOCK(sal_info_type); + return 0; + } +} /* * 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 + * and wakes up any processes waiting for error records. * * Inputs : sal_info_type (Type of error record MCA/CMC/CPE/INIT) - * Outputs : platform error status */ -int -ia64_mca_log_sal_error_record(int sal_info_type, int called_from_init) +static void +ia64_mca_log_sal_error_record(int sal_info_type) { - int platform_err = 0; + u8 *buffer; + u64 size; + int irq_safe = sal_info_type != SAL_INFO_TYPE_MCA && sal_info_type != SAL_INFO_TYPE_INIT; + static const char * const rec_name[] = { "MCA", "INIT", "CMC", "CPE" }; - /* Get the MCA error record */ - if (!ia64_log_get(sal_info_type, (prfunc_t)printk)) - return platform_err; // no record retrieved + size = ia64_log_get(sal_info_type, &buffer, irq_safe); + if (!size) + return; - /* TODO: - * 1. analyze error logs to determine recoverability - * 2. perform error recovery procedures, if applicable - * 3. set ia64_os_mca_recovery_successful flag, if applicable - */ + salinfo_log_wakeup(sal_info_type, buffer, size, irq_safe); - 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); + if (irq_safe) + printk(KERN_INFO "CPU %d: SAL log contains %s error record\n", + smp_processor_id(), + sal_info_type < ARRAY_SIZE(rec_name) ? rec_name[sal_info_type] : "UNKNOWN"); - return platform_err; + /* Clear logs from corrected errors in case there's no user-level logger */ + if (sal_info_type == SAL_INFO_TYPE_CPE || sal_info_type == SAL_INFO_TYPE_CMC) + ia64_sal_clear_state_info(sal_info_type); } /* * platform dependent error handling */ #ifndef PLATFORM_MCA_HANDLERS -void -mca_handler_platform (void) -{ - -} -void +static 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("%s: received interrupt. CPU:%d vector = %#x\n", + __FUNCTION__, smp_processor_id(), cpe_irq); + + /* SAL spec states this should run w/ interrupts enabled */ + local_irq_enable(); /* Get the CMC error record and log it */ - ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CPE, 0); + ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CPE); } -/* - * 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. - */ -void -init_handler_platform (struct pt_regs *regs) +#define print_symbol(fmt, addr) printk(fmt, "(no symbol)"); + +static void +show_min_state (pal_min_state_area_t *minstate) { - /* if a kernel debugger is available call it here else just dump the registers */ + u64 iip = minstate->pmsa_iip + ((struct ia64_psr *)(&minstate->pmsa_ipsr))->ri; + u64 xip = minstate->pmsa_xip + ((struct ia64_psr *)(&minstate->pmsa_xpsr))->ri; - show_regs(regs); /* dump the state info */ - while (1); /* hang city if no debugger */ + 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]); } -/* - * ia64_mca_init_platform - * - * External entry for platform specific MCA initialization. - * - * Inputs - * None - * - * Outputs - * None - */ -void -ia64_mca_init_platform (void) +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); } -/* - * 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. - * - * Inputs : None - * - * Outputs : None - */ -void -ia64_mca_check_errors (void) +static void +init_handler_platform (pal_min_state_area_t *ms, + 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 */ + /* - * If there is an MCA error record pending, get it and log it. + * 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. */ - ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA, 1); + printk("Delaying for 5 seconds...\n"); + udelay(5*1000000); + show_min_state(ms); + + printk("Backtrace of current task (pid %d, %s)\n", current->pid, current->comm); + fetch_min_state(ms, pt, sw); + unw_init_from_interruption(&info, current, pt, sw); + ia64_do_show_stack(&info, NULL); + +#ifdef CONFIG_SMP + /* read_trylock() would be handy... */ + if (!tasklist_lock.write_lock) + read_lock(&tasklist_lock); +#endif + { + struct task_struct *t; + for_each_task(t) { + if (t == current) + continue; + + printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm); + show_stack(t); + } + } +#ifdef CONFIG_SMP + if (!tasklist_lock.write_lock) + read_unlock(&tasklist_lock); +#endif + + printk("\nINIT dump complete. Please reboot now.\n"); + while (1); /* hang city if no debugger */ } +#ifdef CONFIG_ACPI /* * ia64_mca_register_cpev * @@ -234,73 +488,22 @@ 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 " - "Platform Error interrupt vector with SAL.\n"); + 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 "Failed to register Corrected Platform " + "Error interrupt vector with SAL (status %ld)\n", isrv.status); return; } - IA64_MCA_DEBUG("ia64_mca_platform_init: corrected platform error " - "vector %#x setup and enabled\n", cpev); + IA64_MCA_DEBUG("%s: corrected platform error " + "vector %#x setup and enabled\n", __FUNCTION__, cpev); } +#endif /* CONFIG_ACPI */ #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) -{ - int i, max = MIN_STATE_AREA_SIZE; - 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;ifp); - /* - * XXX - disable SAL checksum by setting size to 0; should be - * __pa(ia64_os_mca_dispatch_end) - __pa(ia64_os_mca_dispatch); - */ - ia64_mc_info.imi_mca_handler_size = 0; - - /* Register the os mca handler with SAL */ - if ((rc = ia64_sal_set_vectors(SAL_VECTOR_OS_MCA, - ia64_mc_info.imi_mca_handler, - mca_hldlr_ptr->gp, - ia64_mc_info.imi_mca_handler_size, - 0, 0, 0))) - { - printk("ia64_mca_init: Failed to register os mca handler with SAL. rc = %ld\n", - rc); - return; - } - - IA64_MCA_DEBUG("ia64_mca_init: registered os mca handler with SAL at 0x%lx, gp = 0x%lx\n", - ia64_mc_info.imi_mca_handler, mca_hldlr_ptr->gp); - - /* - * XXX - disable SAL checksum by setting size to 0, should be - * IA64_INIT_HANDLER_SIZE - */ - ia64_mc_info.imi_monarch_init_handler = __pa(mon_init_ptr->fp); - ia64_mc_info.imi_monarch_init_handler_size = 0; - ia64_mc_info.imi_slave_init_handler = __pa(slave_init_ptr->fp); - ia64_mc_info.imi_slave_init_handler_size = 0; - - IA64_MCA_DEBUG("ia64_mca_init: os init handler at %lx\n", - ia64_mc_info.imi_monarch_init_handler); - - /* Register the os init handler with SAL */ - if ((rc = ia64_sal_set_vectors(SAL_VECTOR_OS_INIT, - ia64_mc_info.imi_monarch_init_handler, - __pa(ia64_get_gp()), - ia64_mc_info.imi_monarch_init_handler_size, - ia64_mc_info.imi_slave_init_handler, - __pa(ia64_get_gp()), - ia64_mc_info.imi_slave_init_handler_size))) - { - printk("ia64_mca_init: Failed to register m/s init handlers with SAL. rc = %ld\n", - rc); - return; - } - - IA64_MCA_DEBUG("ia64_mca_init: registered os init handler with SAL\n"); - - /* - * Configure the CMCI vector and handler. Interrupts for CMC are - * per-processor, so AP CMC interrupts are setup in smp_callin() (smpboot.c). - */ - register_percpu_irq(IA64_CMC_VECTOR, &cmci_irqaction); - ia64_mca_cmc_vector_setup(); /* Setup vector on BSP & enable */ - - /* Setup the MCA rendezvous interrupt vector */ - register_percpu_irq(IA64_MCA_RENDEZ_VECTOR, &mca_rdzv_irqaction); - - /* Setup the MCA wakeup interrupt vector */ - register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction); - - /* Setup the CPE interrupt vector */ - { - irq_desc_t *desc; - unsigned int irq; - int cpev = acpi_request_vector(ACPI_INTERRUPT_CPEI); - - if (cpev >= 0) { - for (irq = 0; irq < NR_IRQS; ++irq) - if (irq_to_vector(irq) == cpev) { - desc = irq_desc(irq); - desc->status |= IRQ_PER_CPU; - desc->handler = &irq_type_iosapic_level; - setup_irq(irq, &mca_cpe_irqaction); - } - ia64_mca_register_cpev(cpev); - } - } - - /* Initialize the areas set aside by the OS to buffer the - * platform/processor error states for MCA/INIT/CMC - * handling. - */ - ia64_log_init(SAL_INFO_TYPE_MCA); - ia64_log_init(SAL_INFO_TYPE_INIT); - ia64_log_init(SAL_INFO_TYPE_CMC); - ia64_log_init(SAL_INFO_TYPE_CPE); - -#if defined(MCA_TEST) - mca_test(); -#endif /* #if defined(MCA_TEST) */ - - printk("Mca related initialization done\n"); - - /* commented out because this is done elsewhere */ -#if 0 - /* Do post-failure MCA error logging */ - ia64_mca_check_errors(); -#endif -} - -/* - * ia64_mca_wakeup_ipi_wait - * - * Wait for the inter-cpu interrupt to be sent by the - * monarch processor once it is done with handling the - * MCA. - * - * Inputs : None - * Outputs : None - */ -void -ia64_mca_wakeup_ipi_wait(void) +static void +ia64_mca_wakeup_ipi_wait(void) { int irr_num = (IA64_MCA_WAKEUP_VECTOR >> 6); int irr_bit = (IA64_MCA_WAKEUP_VECTOR & 0x3f); @@ -587,7 +650,7 @@ irr = ia64_get_irr3(); break; } - } while (!(irr & (1 << irr_bit))) ; + } while (!(irr & (1UL << irr_bit))) ; } /* @@ -599,7 +662,7 @@ * Inputs : cpuid * Outputs : None */ -void +static void ia64_mca_wakeup(int cpu) { platform_send_ipi(cpu, IA64_MCA_WAKEUP_VECTOR, IA64_IPI_DM_INT, 0); @@ -615,15 +678,18 @@ * Inputs : None * Outputs : None */ -void +static void ia64_mca_wakeup_all(void) { int cpu; /* Clear the Rendez checkin flag for all cpus */ - for(cpu = 0; cpu < smp_num_cpus; cpu++) + for(cpu = 0; cpu < NR_CPUS; cpu++) { + if (!cpu_online(cpu)) + continue; if (ia64_mc_info.imi_rendez_checkin[cpu] == IA64_MCA_RENDEZ_CHECKIN_DONE) ia64_mca_wakeup(cpu); + } } @@ -637,16 +703,15 @@ * Inputs : None * Outputs : None */ -void +static void ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs) { - int flags, cpu = 0; + unsigned long flags; + int cpu = smp_processor_id(); + /* Mask all interrupts */ - save_and_cli(flags); + local_irq_save(flags); -#ifdef CONFIG_SMP - cpu = cpu_logical_id(hard_smp_processor_id()); -#endif ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE; /* Register with the SAL monarch that the slave has * reached SAL @@ -660,10 +725,9 @@ ia64_mca_wakeup_ipi_wait(); /* Enable all interrupts */ - restore_flags(flags); + local_irq_restore(flags); } - /* * ia64_mca_wakeup_int_handler * @@ -679,10 +743,9 @@ * Outputs : None * */ -void +static void ia64_mca_wakeup_int_handler(int wakeup_irq, void *arg, struct pt_regs *ptregs) { - } /* @@ -699,9 +762,10 @@ * Outputs : None */ -void -ia64_return_to_sal_check(void) +static void +ia64_return_to_sal_check(int recover) { + /* Copy over some relevant stuff from the sal_to_os_mca_handoff * so that it can be used at the time of os_mca_to_sal_handoff */ @@ -711,15 +775,17 @@ ia64_os_to_sal_handoff_state.imots_sal_check_ra = ia64_sal_to_os_handoff_state.imsto_sal_check_ra; - /* Cold Boot for uncorrectable MCA */ - ia64_os_to_sal_handoff_state.imots_os_status = IA64_MCA_COLD_BOOT; + if (recover) + ia64_os_to_sal_handoff_state.imots_os_status = IA64_MCA_CORRECTED; + else + ia64_os_to_sal_handoff_state.imots_os_status = IA64_MCA_COLD_BOOT; /* Default = tell SAL to return to same context */ ia64_os_to_sal_handoff_state.imots_context = IA64_MCA_SAME_CONTEXT; - /* Register pointer to new min state values */ ia64_os_to_sal_handoff_state.imots_new_min_state = - (pal_min_state_area_t *)ia64_mca_min_state_save_info; + (u64 *)ia64_sal_to_os_handoff_state.pal_min_state; + } /* @@ -741,16 +807,12 @@ void ia64_mca_ucmc_handler(void) { - int platform_err = 0; + pal_processor_state_info_t *psp = (pal_processor_state_info_t *) + &ia64_sal_to_os_handoff_state.proc_state_param; + int recover = psp->tc && !(psp->cc || psp->bc || psp->rc || psp->uc); /* Get the MCA error record and log it */ - platform_err = ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA, 0); - - /* - * Do Platform-specific mca error handling if required. - */ - if (platform_err) - mca_handler_platform(); + ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA); /* * Wakeup all the processors which are spinning in the rendezvous @@ -759,7 +821,7 @@ ia64_mca_wakeup_all(); /* Return to SAL */ - ia64_return_to_sal_check(); + ia64_return_to_sal_check(recover); } /* @@ -777,104 +839,189 @@ * Outputs * None */ -void +static void ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs) { - IA64_MCA_DEBUG("ia64_mca_cmc_int_handler: received interrupt vector = %#x on CPU %d\n", - cmc_irq, smp_processor_id()); + static unsigned long cmc_history[CMC_HISTORY_LENGTH]; + static int index; + static spinlock_t cmc_history_lock = SPIN_LOCK_UNLOCKED; + + IA64_MCA_DEBUG("%s: received interrupt vector = %#x on CPU %d\n", + __FUNCTION__, cmc_irq, smp_processor_id()); + + /* SAL spec states this should run w/ interrupts enabled */ + local_irq_enable(); /* Get the CMC error record and log it */ - ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CMC, 0); + ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CMC); + + spin_lock(&cmc_history_lock); + if (!cmc_polling_enabled) { + int i, count = 1; /* we know 1 happened now */ + unsigned long now = jiffies; + + for (i = 0; i < CMC_HISTORY_LENGTH; i++) { + if (now - cmc_history[i] <= HZ) + count++; + } + + IA64_MCA_DEBUG(KERN_INFO "CMC threshold %d/%d\n", count, CMC_HISTORY_LENGTH); + if (count >= CMC_HISTORY_LENGTH) { + + cmc_polling_enabled = 1; + spin_unlock(&cmc_history_lock); + schedule_task(&cmc_disable_tq); + + /* + * 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 "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); } /* - * IA64_MCA log support + * ia64_mca_cmc_int_caller + * + * Triggered by sw interrupt from CMC polling routine. Calls + * real interrupt handler and either triggers a sw interrupt + * on the next cpu or does cleanup at the end. + * + * Inputs + * interrupt number + * client data arg ptr + * saved registers ptr + * Outputs + * None */ -#define IA64_MAX_LOGS 2 /* Double-buffering for nested MCAs */ -#define IA64_MAX_LOG_TYPES 4 /* MCA, INIT, CMC, CPE */ - -typedef struct ia64_state_log_s +static void +ia64_mca_cmc_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs) { - spinlock_t isl_lock; - int isl_index; - ia64_err_rec_t *isl_log[IA64_MAX_LOGS]; /* need space to store header + error log */ -} ia64_state_log_t; + static int start_count = -1; + unsigned int cpuid; -static ia64_state_log_t ia64_state_log[IA64_MAX_LOG_TYPES]; + cpuid = smp_processor_id(); -#define IA64_LOG_ALLOCATE(it, size) \ - {ia64_state_log[it].isl_log[IA64_LOG_CURR_INDEX(it)] = \ - (ia64_err_rec_t *)alloc_bootmem(size); \ - ia64_state_log[it].isl_log[IA64_LOG_NEXT_INDEX(it)] = \ - (ia64_err_rec_t *)alloc_bootmem(size);} -#define IA64_LOG_LOCK_INIT(it) spin_lock_init(&ia64_state_log[it].isl_lock) -#define IA64_LOG_LOCK(it) spin_lock_irqsave(&ia64_state_log[it].isl_lock, s) -#define IA64_LOG_UNLOCK(it) spin_unlock_irqrestore(&ia64_state_log[it].isl_lock,s) -#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 -#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)])) + /* If first cpu, update count */ + if (start_count == -1) + start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CMC); + + ia64_mca_cmc_int_handler(cpe_irq, arg, ptregs); + + for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++); + + if (cpuid < NR_CPUS) { + platform_send_ipi(cpuid, IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0); + } else { + /* If no log record, switch out of polling mode */ + if (start_count == IA64_LOG_COUNT(SAL_INFO_TYPE_CMC)) { + + printk(KERN_WARNING "Returning to interrupt driven CMC handler\n"); + schedule_task(&cmc_enable_tq); + cmc_polling_enabled = 0; + + } else { + + mod_timer(&cmc_poll_timer, jiffies + CMC_POLL_INTERVAL); + } + + start_count = -1; + } +} /* - * ia64_mca_cpe_poll + * ia64_mca_cmc_poll * - * Poll for Corrected Platform Errors (CPEs), dynamically adjust - * polling interval based on occurance of an event. + * Poll for Corrected Machine Checks (CMCs) * * Inputs : dummy(unused) * Outputs : None * */ static void -ia64_mca_cpe_poll (unsigned long dummy) +ia64_mca_cmc_poll (unsigned long dummy) +{ + /* Trigger a CMC interrupt cascade */ + platform_send_ipi(__ffs(cpu_online_map), IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0); +} + +/* + * ia64_mca_cpe_int_caller + * + * Triggered by sw interrupt from CPE polling routine. Calls + * real interrupt handler and either triggers a sw interrupt + * on the next cpu or does cleanup at the end. + * + * Inputs + * interrupt number + * client data arg ptr + * saved registers ptr + * Outputs + * None + */ +static void +ia64_mca_cpe_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs) { - int start_index; + static int start_count = -1; static int poll_time = MAX_CPE_POLL_INTERVAL; + unsigned int cpuid; - start_index = IA64_LOG_CURR_INDEX(SAL_INFO_TYPE_CPE); + cpuid = smp_processor_id(); - /* Call the interrupt handler */ - ia64_mca_cpe_int_handler(0, NULL, NULL); + /* If first cpu, update count */ + if (start_count == -1) + start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CPE); - /* - * If a log was recorded, increase our polling frequency, - * otherwise, backoff. - */ - if (start_index != IA64_LOG_CURR_INDEX(SAL_INFO_TYPE_CPE)) { - poll_time = max(MIN_CPE_POLL_INTERVAL, poll_time/2); + ia64_mca_cpe_int_handler(cpe_irq, arg, ptregs); + + for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++); + + if (cpuid < NR_CPUS) { + platform_send_ipi(cpuid, IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0); } else { - poll_time = min(MAX_CPE_POLL_INTERVAL, poll_time * 2); + /* + * If a log was recorded, increase our polling frequency, + * otherwise, backoff. + */ + 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); + } + start_count = -1; + mod_timer(&cpe_poll_timer, jiffies + poll_time); } - mod_timer(&cpe_poll_timer, jiffies + poll_time); } /* - * ia64_mca_late_init + * ia64_mca_cpe_poll * - * Opportunity to setup things that require initialization later - * than ia64_mca_init. Setup a timer to poll for CPEs if the - * platform doesn't support an interrupt driven mechanism. + * Poll for Corrected Platform Errors (CPEs), trigger interrupt + * on first cpu, from there it will trickle through all the cpus. + * + * Inputs : dummy(unused) + * Outputs : None * - * Inputs : None - * Outputs : Status */ -static int __init -ia64_mca_late_init(void) +static void +ia64_mca_cpe_poll (unsigned long dummy) { - 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); - } - return 0; + /* Trigger a CPE interrupt cascade */ + platform_send_ipi(__ffs(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0); } -module_init(ia64_mca_late_init); - /* * C portion of the OS INIT handler * @@ -888,1103 +1035,278 @@ * */ 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; + pal_min_state_area_t *ms; - printk("Entered OS INIT handler\n"); + oops_in_progress = 1; /* avoid deadlock in printk, but it makes recovery dodgy */ - /* Get the INIT processor log */ - if (!ia64_log_get(SAL_INFO_TYPE_INIT, (prfunc_t)printk)) - return; // no record retrieved - -#ifdef IA64_DUMP_ALL_PROC_INFO - ia64_log_print(SAL_INFO_TYPE_INIT, (prfunc_t)printk); -#endif + printk(KERN_INFO "Entered OS INIT handler. PSP=%lx\n", + ia64_sal_to_os_handoff_state.proc_state_param); /* - * get pointer to min state save area - * + * Address of minstate area provided by PAL is physical, + * uncacheable (bit 63 set). Convert to Linux virtual + * address in region 6. */ - 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); + ms = (pal_min_state_area_t *)(ia64_sal_to_os_handoff_state.pal_min_state | (6ul<<61)); - init_handler_platform(regs); /* call platform specific routines */ + init_handler_platform(ms, pt, sw); /* call platform specific routines */ } -/* - * ia64_log_prt_guid - * - * Print a formatted GUID. - * - * Inputs : p_guid (ptr to the GUID) - * prfunc (print function) - * Outputs : None - * - */ -void -ia64_log_prt_guid (efi_guid_t *p_guid, prfunc_t prfunc) +static int __init +ia64_mca_disable_cpe_polling(char *str) { - char out[40]; - printk(KERN_DEBUG "GUID = %s\n", efi_guid_unparse(p_guid, out)); + cpe_poll_enabled = 0; + return 1; } -static void -ia64_log_hexdump(unsigned char *p, unsigned long n_ch, prfunc_t prfunc) -{ - int i, j; +__setup("disable_cpe_poll", ia64_mca_disable_cpe_polling); - if (!p) - return; +static struct irqaction cmci_irqaction = { + .handler = ia64_mca_cmc_int_handler, + .flags = SA_INTERRUPT, + .name = "cmc_hndlr" +}; - for (i = 0; i < n_ch;) { - prfunc("%p ", (void *)p); - for (j = 0; (j < 16) && (i < n_ch); i++, j++, p++) { - prfunc("%02x ", *p); - } - prfunc("\n"); - } -} +static struct irqaction cmcp_irqaction = { + .handler = ia64_mca_cmc_int_caller, + .flags = SA_INTERRUPT, + .name = "cmc_poll" +}; -#ifdef MCA_PRT_XTRA_DATA // for test only @FVL +static struct irqaction mca_rdzv_irqaction = { + .handler = ia64_mca_rendez_int_handler, + .flags = SA_INTERRUPT, + .name = "mca_rdzv" +}; -static void -ia64_log_prt_record_header (sal_log_record_header_t *rh, prfunc_t prfunc) -{ - prfunc("SAL RECORD HEADER: Record buffer = %p, header size = %ld\n", - (void *)rh, sizeof(sal_log_record_header_t)); - ia64_log_hexdump((unsigned char *)rh, sizeof(sal_log_record_header_t), - (prfunc_t)prfunc); - prfunc("Total record length = %d\n", rh->len); - ia64_log_prt_guid(&rh->platform_guid, prfunc); - prfunc("End of SAL RECORD HEADER\n"); -} +static struct irqaction mca_wkup_irqaction = { + .handler = ia64_mca_wakeup_int_handler, + .flags = SA_INTERRUPT, + .name = "mca_wkup" +}; -static void -ia64_log_prt_section_header (sal_log_section_hdr_t *sh, prfunc_t prfunc) -{ - prfunc("SAL SECTION HEADER: Record buffer = %p, header size = %ld\n", - (void *)sh, sizeof(sal_log_section_hdr_t)); - ia64_log_hexdump((unsigned char *)sh, sizeof(sal_log_section_hdr_t), - (prfunc_t)prfunc); - prfunc("Length of section & header = %d\n", sh->len); - ia64_log_prt_guid(&sh->guid, prfunc); - prfunc("End of SAL SECTION HEADER\n"); -} -#endif // MCA_PRT_XTRA_DATA for test only @FVL - -/* - * ia64_log_init - * Reset the OS ia64 log buffer - * Inputs : info_type (SAL_INFO_TYPE_{MCA,INIT,CMC,CPE}) - * Outputs : None - */ -void -ia64_log_init(int sal_info_type) -{ - u64 max_size = 0; - - IA64_LOG_NEXT_INDEX(sal_info_type) = 0; - IA64_LOG_LOCK_INIT(sal_info_type); - - // SAL will tell us the maximum size of any error record of this type - max_size = ia64_sal_get_state_info_size(sal_info_type); +#ifdef CONFIG_ACPI +static struct irqaction mca_cpe_irqaction = { + .handler = ia64_mca_cpe_int_handler, + .flags = SA_INTERRUPT, + .name = "cpe_hndlr" +}; - // set up OS data structures to hold error info - IA64_LOG_ALLOCATE(sal_info_type, max_size); - memset(IA64_LOG_CURR_BUFFER(sal_info_type), 0, max_size); - memset(IA64_LOG_NEXT_BUFFER(sal_info_type), 0, max_size); -} +static struct irqaction mca_cpep_irqaction = { + .handler = ia64_mca_cpe_int_caller, + .flags = SA_INTERRUPT, + .name = "cpe_poll" +}; +#endif /* CONFIG_ACPI */ /* - * ia64_log_get + * ia64_mca_init * - * Get the current MCA log from SAL and copy it into the OS log buffer. + * Do all the system level mca specific initialization. * - * Inputs : info_type (SAL_INFO_TYPE_{MCA,INIT,CMC,CPE}) - * prfunc (fn ptr of log output function) - * Outputs : size (total record length) + * 1. Register spinloop and wakeup request interrupt vectors * - */ -u64 -ia64_log_get(int sal_info_type, prfunc_t prfunc) -{ - sal_log_record_header_t *log_buffer; - u64 total_len = 0; - int s; - - IA64_LOG_LOCK(sal_info_type); - - /* Get the process state information */ - log_buffer = IA64_LOG_NEXT_BUFFER(sal_info_type); - - total_len = ia64_sal_get_state_info(sal_info_type, (u64 *)log_buffer); - - if (total_len) { - IA64_LOG_INDEX_INC(sal_info_type); - IA64_LOG_UNLOCK(sal_info_type); - IA64_MCA_DEBUG("ia64_log_get: SAL error record type %d retrieved. " - "Record length = %ld\n", sal_info_type, total_len); - return total_len; - } else { - IA64_LOG_UNLOCK(sal_info_type); - return 0; - } -} - -/* - * ia64_log_prt_oem_data + * 2. Register OS_MCA handler entry point * - * Print OEM specific data if included. + * 3. Register OS_INIT handler entry point * - * Inputs : header_len (length passed in section header) - * sect_len (default length of section type) - * p_data (ptr to data) - * prfunc (print function) - * Outputs : None + * 4. Initialize MCA/CMC/INIT related log buffers maintained by the OS. * - */ -void -ia64_log_prt_oem_data (int header_len, int sect_len, u8 *p_data, prfunc_t prfunc) -{ - int oem_data_len, i; - - if ((oem_data_len = header_len - sect_len) > 0) { - prfunc(" OEM Specific Data:"); - for (i = 0; i < oem_data_len; i++, p_data++) - prfunc(" %02x", *p_data); - } - prfunc("\n"); -} - -/* - * ia64_log_rec_header_print + * Note that this initialization is done very early before some kernel + * services are available. * - * Log info from the SAL error record header. + * Inputs : None * - * Inputs : lh * (ptr to SAL log error record header) - * prfunc (fn ptr of log output function to use) * Outputs : None */ -void -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); -} - -/* - * ia64_log_processor_regs_print - * Print the contents of the saved processor register(s) in the format - * [] - * - * Inputs : regs (Register save buffer) - * reg_num (# of registers) - * reg_class (application/banked/control/bank1_general) - * reg_prefix (ar/br/cr/b1_gr) - * Outputs : None - * - */ -void -ia64_log_processor_regs_print(u64 *regs, - int reg_num, - char *reg_class, - char *reg_prefix, - prfunc_t prfunc) -{ - int i; - - prfunc("+%s Registers\n", reg_class); - for (i = 0; i < reg_num; i++) - prfunc("+ %s[%d] 0x%lx\n", reg_prefix, i, regs[i]); -} - -/* - * ia64_log_processor_fp_regs_print - * Print the contents of the saved floating page register(s) in the format - * [] - * - * Inputs: ia64_fpreg (Register save buffer) - * reg_num (# of registers) - * reg_class (application/banked/control/bank1_general) - * reg_prefix (ar/br/cr/b1_gr) - * Outputs: None - * - */ -void -ia64_log_processor_fp_regs_print (struct ia64_fpreg *regs, - int reg_num, - char *reg_class, - char *reg_prefix, - prfunc_t prfunc) +void __init +ia64_mca_init(void) { + ia64_fptr_t *mon_init_ptr = (ia64_fptr_t *)ia64_monarch_init_handler; + ia64_fptr_t *slave_init_ptr = (ia64_fptr_t *)ia64_slave_init_handler; + ia64_fptr_t *mca_hldlr_ptr = (ia64_fptr_t *)ia64_os_mca_dispatch; int i; + s64 rc; + struct ia64_sal_retval isrv; + u64 timeout = IA64_MCA_RENDEZ_TIMEOUT; /* platform specific */ - prfunc("+%s Registers\n", reg_class); - for (i = 0; i < reg_num; i++) - prfunc("+ %s[%d] 0x%lx%016lx\n", reg_prefix, i, regs[i].u.bits[1], - regs[i].u.bits[0]); -} - -static char *pal_mesi_state[] = { - "Invalid", - "Shared", - "Exclusive", - "Modified", - "Reserved1", - "Reserved2", - "Reserved3", - "Reserved4" -}; - -static char *pal_cache_op[] = { - "Unknown", - "Move in", - "Cast out", - "Coherency check", - "Internal", - "Instruction fetch", - "Implicit Writeback", - "Reserved" -}; - -/* - * ia64_log_cache_check_info_print - * Display the machine check information related to cache error(s). - * Inputs: i (Multiple errors are logged, i - index of logged error) - * cc_info * (Ptr to cache check info logged by the PAL and later - * captured by the SAL) - * prfunc (fn ptr of print function to be used for output) - * Outputs: None - */ -void -ia64_log_cache_check_info_print (int i, - sal_log_mod_error_info_t *cache_check_info, - prfunc_t prfunc) -{ - pal_cache_check_info_t *info; - u64 target_addr; - - if (!cache_check_info->valid.check_info) { - IA64_MCA_DEBUG("ia64_mca_log_print: invalid cache_check_info[%d]\n",i); - return; /* If check info data not valid, skip it */ - } - - info = (pal_cache_check_info_t *)&cache_check_info->check_info; - target_addr = cache_check_info->target_identifier; - - prfunc("+ Cache check info[%d]\n+", i); - prfunc(" Level: L%d,",info->level); - if (info->mv) - prfunc(" Mesi: %s,",pal_mesi_state[info->mesi]); - prfunc(" Index: %d,", info->index); - if (info->ic) - prfunc(" Cache: Instruction,"); - if (info->dc) - prfunc(" Cache: Data,"); - if (info->tl) - prfunc(" Line: Tag,"); - if (info->dl) - prfunc(" Line: Data,"); - prfunc(" Operation: %s,", pal_cache_op[info->op]); - if (info->wv) - prfunc(" Way: %d,", info->way); - if (cache_check_info->valid.target_identifier) - /* Hope target address is saved in target_identifier */ - if (info->tv) - prfunc(" Target Addr: 0x%lx,", target_addr); - if (info->mc) - prfunc(" MC: Corrected"); - prfunc("\n"); -} - -/* - * ia64_log_tlb_check_info_print - * Display the machine check information related to tlb error(s). - * Inputs: i (Multiple errors are logged, i - index of logged error) - * tlb_info * (Ptr to machine check info logged by the PAL and later - * captured by the SAL) - * prfunc (fn ptr of print function to be used for output) - * Outputs: None - */ -void -ia64_log_tlb_check_info_print (int i, - sal_log_mod_error_info_t *tlb_check_info, - prfunc_t prfunc) - -{ - pal_tlb_check_info_t *info; - - if (!tlb_check_info->valid.check_info) { - IA64_MCA_DEBUG("ia64_mca_log_print: invalid tlb_check_info[%d]\n", i); - return; /* If check info data not valid, skip it */ - } - - info = (pal_tlb_check_info_t *)&tlb_check_info->check_info; - - prfunc("+ TLB Check Info [%d]\n+", i); - if (info->itc) - prfunc(" Failure: Instruction Translation Cache"); - if (info->dtc) - prfunc(" Failure: Data Translation Cache"); - if (info->itr) { - prfunc(" Failure: Instruction Translation Register"); - prfunc(" ,Slot: %d", info->tr_slot); - } - if (info->dtr) { - prfunc(" Failure: Data Translation Register"); - prfunc(" ,Slot: %d", info->tr_slot); - } - if (info->mc) - prfunc(" ,MC: Corrected"); - prfunc("\n"); -} - -/* - * ia64_log_bus_check_info_print - * Display the machine check information related to bus error(s). - * Inputs: i (Multiple errors are logged, i - index of logged error) - * bus_info * (Ptr to machine check info logged by the PAL and later - * captured by the SAL) - * prfunc (fn ptr of print function to be used for output) - * Outputs: None - */ -void -ia64_log_bus_check_info_print (int i, - sal_log_mod_error_info_t *bus_check_info, - prfunc_t prfunc) -{ - pal_bus_check_info_t *info; - u64 req_addr; /* Address of the requestor of the transaction */ - u64 resp_addr; /* Address of the responder of the transaction */ - u64 targ_addr; /* Address where the data was to be delivered to */ - /* or obtained from */ - - if (!bus_check_info->valid.check_info) { - IA64_MCA_DEBUG("ia64_mca_log_print: invalid bus_check_info[%d]\n", i); - return; /* If check info data not valid, skip it */ - } + IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__); - info = (pal_bus_check_info_t *)&bus_check_info->check_info; - req_addr = bus_check_info->requestor_identifier; - resp_addr = bus_check_info->responder_identifier; - targ_addr = bus_check_info->target_identifier; - - prfunc("+ BUS Check Info [%d]\n+", i); - prfunc(" Status Info: %d", info->bsi); - prfunc(" ,Severity: %d", info->sev); - prfunc(" ,Transaction Type: %d", info->type); - prfunc(" ,Transaction Size: %d", info->size); - if (info->cc) - prfunc(" ,Cache-cache-transfer"); - if (info->ib) - prfunc(" ,Error: Internal"); - if (info->eb) - prfunc(" ,Error: External"); - if (info->mc) - prfunc(" ,MC: Corrected"); - if (info->tv) - prfunc(" ,Target Address: 0x%lx", targ_addr); - if (info->rq) - prfunc(" ,Requestor Address: 0x%lx", req_addr); - if (info->tv) - prfunc(" ,Responder Address: 0x%lx", resp_addr); - prfunc("\n"); -} + INIT_TQUEUE(&cmc_disable_tq, ia64_mca_cmc_vector_disable_keventd, NULL); + INIT_TQUEUE(&cmc_enable_tq, ia64_mca_cmc_vector_enable_keventd, NULL); -/* - * ia64_log_mem_dev_err_info_print - * - * Format and log the platform memory device error record section data. - * - * Inputs: mem_dev_err_info * (Ptr to memory device error record section - * returned by SAL) - * prfunc (fn ptr of print function to be used for output) - * Outputs: None - */ -void -ia64_log_mem_dev_err_info_print (sal_log_mem_dev_err_info_t *mdei, - prfunc_t prfunc) -{ - prfunc("+ Mem Error Detail: "); + /* Clear the Rendez checkin flag for all cpus */ + for(i = 0 ; i < NR_CPUS; i++) + ia64_mc_info.imi_rendez_checkin[i] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; - if (mdei->valid.error_status) - prfunc(" Error Status: %#lx,", mdei->error_status); - if (mdei->valid.physical_addr) - prfunc(" Physical Address: %#lx,", mdei->physical_addr); - if (mdei->valid.addr_mask) - prfunc(" Address Mask: %#lx,", mdei->addr_mask); - if (mdei->valid.node) - prfunc(" Node: %d,", mdei->node); - if (mdei->valid.card) - prfunc(" Card: %d,", mdei->card); - if (mdei->valid.module) - prfunc(" Module: %d,", mdei->module); - if (mdei->valid.bank) - prfunc(" Bank: %d,", mdei->bank); - if (mdei->valid.device) - prfunc(" Device: %d,", mdei->device); - if (mdei->valid.row) - prfunc(" Row: %d,", mdei->row); - if (mdei->valid.column) - prfunc(" Column: %d,", mdei->column); - if (mdei->valid.bit_position) - prfunc(" Bit Position: %d,", mdei->bit_position); - if (mdei->valid.target_id) - prfunc(" ,Target Address: %#lx,", mdei->target_id); - if (mdei->valid.requestor_id) - prfunc(" ,Requestor Address: %#lx,", mdei->requestor_id); - if (mdei->valid.responder_id) - prfunc(" ,Responder Address: %#lx,", mdei->responder_id); - if (mdei->valid.bus_spec_data) - prfunc(" Bus Specific Data: %#lx,", mdei->bus_spec_data); - prfunc("\n"); - - if (mdei->valid.oem_id) { - u8 *p_data = &(mdei->oem_id[0]); - int i; - - prfunc(" OEM Memory Controller ID:"); - for (i = 0; i < 16; i++, p_data++) - prfunc(" %02x", *p_data); - prfunc("\n"); - } + /* + * Register the rendezvous spinloop and wakeup mechanism with SAL + */ - if (mdei->valid.oem_data) { - platform_mem_dev_err_print((int)mdei->header.len, - (int)sizeof(sal_log_mem_dev_err_info_t) - 1, - &(mdei->oem_data[0]), prfunc); + /* Register the rendezvous interrupt vector with SAL */ + while (1) { + isrv = ia64_sal_mc_set_params(SAL_MC_PARAM_RENDEZ_INT, + SAL_MC_PARAM_MECHANISM_INT, + IA64_MCA_RENDEZ_VECTOR, + timeout, + SAL_MC_PARAM_RZ_ALWAYS); + rc = isrv.status; + if (rc == 0) + break; + if (rc == -2) { + printk(KERN_INFO "Increasing MCA rendezvous timeout from " + "%ld to %ld milliseconds\n", timeout, isrv.v0); + timeout = isrv.v0; + continue; + } + printk(KERN_ERR "Failed to register rendezvous interrupt " + "with SAL (status %ld)\n", rc); + return; } -} - -/* - * ia64_log_sel_dev_err_info_print - * - * Format and log the platform SEL device error record section data. - * - * Inputs: sel_dev_err_info * (Ptr to the SEL device error record section - * returned by SAL) - * prfunc (fn ptr of print function to be used for output) - * Outputs: None - */ -void -ia64_log_sel_dev_err_info_print (sal_log_sel_dev_err_info_t *sdei, - prfunc_t prfunc) -{ - int i; - - prfunc("+ SEL Device Error Detail: "); - if (sdei->valid.record_id) - prfunc(" Record ID: %#x", sdei->record_id); - if (sdei->valid.record_type) - prfunc(" Record Type: %#x", sdei->record_type); - prfunc(" Time Stamp: "); - for (i = 0; i < 4; i++) - prfunc("%1d", sdei->timestamp[i]); - if (sdei->valid.generator_id) - prfunc(" Generator ID: %#x", sdei->generator_id); - if (sdei->valid.evm_rev) - prfunc(" Message Format Version: %#x", sdei->evm_rev); - if (sdei->valid.sensor_type) - prfunc(" Sensor Type: %#x", sdei->sensor_type); - if (sdei->valid.sensor_num) - prfunc(" Sensor Number: %#x", sdei->sensor_num); - if (sdei->valid.event_dir) - prfunc(" Event Direction Type: %#x", sdei->event_dir); - if (sdei->valid.event_data1) - prfunc(" Data1: %#x", sdei->event_data1); - if (sdei->valid.event_data2) - prfunc(" Data2: %#x", sdei->event_data2); - if (sdei->valid.event_data3) - prfunc(" Data3: %#x", sdei->event_data3); - prfunc("\n"); - -} - -/* - * ia64_log_pci_bus_err_info_print - * - * Format and log the platform PCI bus error record section data. - * - * Inputs: pci_bus_err_info * (Ptr to the PCI bus error record section - * returned by SAL) - * prfunc (fn ptr of print function to be used for output) - * Outputs: None - */ -void -ia64_log_pci_bus_err_info_print (sal_log_pci_bus_err_info_t *pbei, - prfunc_t prfunc) -{ - prfunc("+ PCI Bus Error Detail: "); - - if (pbei->valid.err_status) - prfunc(" Error Status: %#lx", pbei->err_status); - if (pbei->valid.err_type) - prfunc(" Error Type: %#x", pbei->err_type); - if (pbei->valid.bus_id) - prfunc(" Bus ID: %#x", pbei->bus_id); - if (pbei->valid.bus_address) - prfunc(" Bus Address: %#lx", pbei->bus_address); - if (pbei->valid.bus_data) - prfunc(" Bus Data: %#lx", pbei->bus_data); - if (pbei->valid.bus_cmd) - prfunc(" Bus Command: %#lx", pbei->bus_cmd); - if (pbei->valid.requestor_id) - prfunc(" Requestor ID: %#lx", pbei->requestor_id); - if (pbei->valid.responder_id) - prfunc(" Responder ID: %#lx", pbei->responder_id); - if (pbei->valid.target_id) - prfunc(" Target ID: %#lx", pbei->target_id); - if (pbei->valid.oem_data) - prfunc("\n"); - - if (pbei->valid.oem_data) { - platform_pci_bus_err_print((int)pbei->header.len, - (int)sizeof(sal_log_pci_bus_err_info_t) - 1, - &(pbei->oem_data[0]), prfunc); + /* Register the wakeup interrupt vector with SAL */ + isrv = ia64_sal_mc_set_params(SAL_MC_PARAM_RENDEZ_WAKEUP, + SAL_MC_PARAM_MECHANISM_INT, + IA64_MCA_WAKEUP_VECTOR, + 0, 0); + rc = isrv.status; + if (rc) { + printk(KERN_ERR "Failed to register wakeup interrupt with SAL " + "(status %ld)\n", rc); + return; } -} -/* - * ia64_log_smbios_dev_err_info_print - * - * Format and log the platform SMBIOS device error record section data. - * - * Inputs: smbios_dev_err_info * (Ptr to the SMBIOS device error record - * section returned by SAL) - * prfunc (fn ptr of print function to be used for output) - * Outputs: None - */ -void -ia64_log_smbios_dev_err_info_print (sal_log_smbios_dev_err_info_t *sdei, - prfunc_t prfunc) -{ - u8 i; - - prfunc("+ SMBIOS Device Error Detail: "); + IA64_MCA_DEBUG("%s: registered MCA rendezvous spinloop and wakeup mech.\n", __FUNCTION__); - if (sdei->valid.event_type) - prfunc(" Event Type: %#x", sdei->event_type); - if (sdei->valid.time_stamp) { - prfunc(" Time Stamp: "); - for (i = 0; i < 6; i++) - prfunc("%d", sdei->time_stamp[i]); - } - if ((sdei->valid.data) && (sdei->valid.length)) { - prfunc(" Data: "); - for (i = 0; i < sdei->length; i++) - prfunc(" %02x", sdei->data[i]); - } - prfunc("\n"); -} + ia64_mc_info.imi_mca_handler = ia64_tpa(mca_hldlr_ptr->fp); + /* + * XXX - disable SAL checksum by setting size to 0; should be + * ia64_tpa(ia64_os_mca_dispatch_end) - ia64_tpa(ia64_os_mca_dispatch); + */ + ia64_mc_info.imi_mca_handler_size = 0; -/* - * ia64_log_pci_comp_err_info_print - * - * Format and log the platform PCI component error record section data. - * - * Inputs: pci_comp_err_info * (Ptr to the PCI component error record section - * returned by SAL) - * prfunc (fn ptr of print function to be used for output) - * Outputs: None - */ -void -ia64_log_pci_comp_err_info_print(sal_log_pci_comp_err_info_t *pcei, - prfunc_t prfunc) -{ - u32 n_mem_regs, n_io_regs; - u64 i, n_pci_data; - u64 *p_reg_data; - u8 *p_oem_data; - - prfunc("+ PCI Component Error Detail: "); - - if (pcei->valid.err_status) - prfunc(" Error Status: %#lx\n", pcei->err_status); - if (pcei->valid.comp_info) - prfunc(" Component Info: Vendor Id = %#x, Device Id = %#x," - " Class Code = %#x, Seg/Bus/Dev/Func = %d/%d/%d/%d\n", - pcei->comp_info.vendor_id, pcei->comp_info.device_id, - pcei->comp_info.class_code, pcei->comp_info.seg_num, - pcei->comp_info.bus_num, pcei->comp_info.dev_num, - pcei->comp_info.func_num); - - n_mem_regs = (pcei->valid.num_mem_regs) ? pcei->num_mem_regs : 0; - n_io_regs = (pcei->valid.num_io_regs) ? pcei->num_io_regs : 0; - p_reg_data = &(pcei->reg_data_pairs[0]); - p_oem_data = (u8 *)p_reg_data + - (n_mem_regs + n_io_regs) * 2 * sizeof(u64); - n_pci_data = p_oem_data - (u8 *)pcei; - - if (n_pci_data > pcei->header.len) { - prfunc(" Invalid PCI Component Error Record format: length = %ld, " - " Size PCI Data = %d, Num Mem-Map/IO-Map Regs = %ld/%ld\n", - pcei->header.len, n_pci_data, n_mem_regs, n_io_regs); + /* Register the os mca handler with SAL */ + if ((rc = ia64_sal_set_vectors(SAL_VECTOR_OS_MCA, + ia64_mc_info.imi_mca_handler, + ia64_tpa(mca_hldlr_ptr->gp), + ia64_mc_info.imi_mca_handler_size, + 0, 0, 0))) + { + printk(KERN_ERR "Failed to register OS MCA handler with SAL " + "(status %ld)\n", rc); return; } - if (n_mem_regs) { - prfunc(" Memory Mapped Registers\n Address \tValue\n"); - for (i = 0; i < pcei->num_mem_regs; i++) { - prfunc(" %#lx %#lx\n", p_reg_data[0], p_reg_data[1]); - p_reg_data += 2; - } - } - if (n_io_regs) { - prfunc(" I/O Mapped Registers\n Address \tValue\n"); - for (i = 0; i < pcei->num_io_regs; i++) { - prfunc(" %#lx %#lx\n", p_reg_data[0], p_reg_data[1]); - p_reg_data += 2; - } - } - if (pcei->valid.oem_data) { - platform_pci_comp_err_print((int)pcei->header.len, n_pci_data, - p_oem_data, prfunc); - prfunc("\n"); - } -} - -/* - * ia64_log_plat_specific_err_info_print - * - * Format and log the platform specifie error record section data. - * - * Inputs: sel_dev_err_info * (Ptr to the platform specific error record - * section returned by SAL) - * prfunc (fn ptr of print function to be used for output) - * Outputs: None - */ -void -ia64_log_plat_specific_err_info_print (sal_log_plat_specific_err_info_t *psei, - prfunc_t prfunc) -{ - prfunc("+ Platform Specific Error Detail: "); + IA64_MCA_DEBUG("%s: registered OS MCA handler with SAL at 0x%lx, gp = 0x%lx\n", __FUNCTION__, + ia64_mc_info.imi_mca_handler, ia64_tpa(mca_hldlr_ptr->gp)); - if (psei->valid.err_status) - prfunc(" Error Status: %#lx", psei->err_status); - if (psei->valid.guid) { - prfunc(" GUID: "); - ia64_log_prt_guid(&psei->guid, prfunc); - } - if (psei->valid.oem_data) { - platform_plat_specific_err_print((int)psei->header.len, - (int)sizeof(sal_log_plat_specific_err_info_t) - 1, - &(psei->oem_data[0]), prfunc); - } - prfunc("\n"); -} + /* + * XXX - disable SAL checksum by setting size to 0, should be + * size of the actual init handler in mca_asm.S. + */ + ia64_mc_info.imi_monarch_init_handler = ia64_tpa(mon_init_ptr->fp); + ia64_mc_info.imi_monarch_init_handler_size = 0; + ia64_mc_info.imi_slave_init_handler = ia64_tpa(slave_init_ptr->fp); + ia64_mc_info.imi_slave_init_handler_size = 0; -/* - * ia64_log_host_ctlr_err_info_print - * - * Format and log the platform host controller error record section data. - * - * Inputs: host_ctlr_err_info * (Ptr to the host controller error record - * section returned by SAL) - * prfunc (fn ptr of print function to be used for output) - * Outputs: None - */ -void -ia64_log_host_ctlr_err_info_print (sal_log_host_ctlr_err_info_t *hcei, - prfunc_t prfunc) -{ - prfunc("+ Host Controller Error Detail: "); + IA64_MCA_DEBUG("%s: OS INIT handler at %lx\n", __FUNCTION__, + ia64_mc_info.imi_monarch_init_handler); - if (hcei->valid.err_status) - prfunc(" Error Status: %#lx", hcei->err_status); - if (hcei->valid.requestor_id) - prfunc(" Requestor ID: %#lx", hcei->requestor_id); - if (hcei->valid.responder_id) - prfunc(" Responder ID: %#lx", hcei->responder_id); - if (hcei->valid.target_id) - prfunc(" Target ID: %#lx", hcei->target_id); - if (hcei->valid.bus_spec_data) - prfunc(" Bus Specific Data: %#lx", hcei->bus_spec_data); - if (hcei->valid.oem_data) { - platform_host_ctlr_err_print((int)hcei->header.len, - (int)sizeof(sal_log_host_ctlr_err_info_t) - 1, - &(hcei->oem_data[0]), prfunc); + /* Register the os init handler with SAL */ + if ((rc = ia64_sal_set_vectors(SAL_VECTOR_OS_INIT, + ia64_mc_info.imi_monarch_init_handler, + ia64_tpa(ia64_get_gp()), + ia64_mc_info.imi_monarch_init_handler_size, + ia64_mc_info.imi_slave_init_handler, + ia64_tpa(ia64_get_gp()), + ia64_mc_info.imi_slave_init_handler_size))) + { + printk(KERN_ERR "Failed to register m/s INIT handlers with SAL " + "(status %ld)\n", rc); + return; } - prfunc("\n"); -} -/* - * ia64_log_plat_bus_err_info_print - * - * Format and log the platform bus error record section data. - * - * Inputs: plat_bus_err_info * (Ptr to the platform bus error record section - * returned by SAL) - * prfunc (fn ptr of print function to be used for output) - * Outputs: None - */ -void -ia64_log_plat_bus_err_info_print (sal_log_plat_bus_err_info_t *pbei, - prfunc_t prfunc) -{ - prfunc("+ Platform Bus Error Detail: "); + IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __FUNCTION__); - if (pbei->valid.err_status) - prfunc(" Error Status: %#lx", pbei->err_status); - if (pbei->valid.requestor_id) - prfunc(" Requestor ID: %#lx", pbei->requestor_id); - if (pbei->valid.responder_id) - prfunc(" Responder ID: %#lx", pbei->responder_id); - if (pbei->valid.target_id) - prfunc(" Target ID: %#lx", pbei->target_id); - if (pbei->valid.bus_spec_data) - prfunc(" Bus Specific Data: %#lx", pbei->bus_spec_data); - if (pbei->valid.oem_data) { - platform_plat_bus_err_print((int)pbei->header.len, - (int)sizeof(sal_log_plat_bus_err_info_t) - 1, - &(pbei->oem_data[0]), prfunc); - } - prfunc("\n"); -} + /* + * Configure the CMCI/P vector and handler. Interrupts for CMC are + * per-processor, so AP CMC interrupts are setup in smp_callin() (smpboot.c). + */ + register_percpu_irq(IA64_CMC_VECTOR, &cmci_irqaction); + register_percpu_irq(IA64_CMCP_VECTOR, &cmcp_irqaction); + ia64_mca_cmc_vector_setup(); /* Setup vector on BSP & enable */ -/* - * ia64_log_proc_dev_err_info_print - * - * Display the processor device error record. - * - * Inputs: sal_log_processor_info_t * (Ptr to processor device error record - * section body). - * prfunc (fn ptr of print function to be used - * for output). - * Outputs: None - */ -void -ia64_log_proc_dev_err_info_print (sal_log_processor_info_t *slpi, - prfunc_t prfunc) -{ -#ifdef MCA_PRT_XTRA_DATA - size_t d_len = slpi->header.len - sizeof(sal_log_section_hdr_t); -#endif - sal_processor_static_info_t *spsi; - int i; - sal_log_mod_error_info_t *p_data; + /* Setup the MCA rendezvous interrupt vector */ + register_percpu_irq(IA64_MCA_RENDEZ_VECTOR, &mca_rdzv_irqaction); - prfunc("+Processor Device Error Info Section\n"); + /* Setup the MCA wakeup interrupt vector */ + register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction); -#ifdef MCA_PRT_XTRA_DATA // for test only @FVL +#ifdef CONFIG_ACPI + /* Setup the CPE interrupt vector */ { - char *p_data = (char *)&slpi->valid; + irq_desc_t *desc; + unsigned int irq; + int cpev = acpi_request_vector(ACPI_INTERRUPT_CPEI); - prfunc("SAL_PROC_DEV_ERR SECTION DATA: Data buffer = %p, " - "Data size = %ld\n", (void *)p_data, d_len); - ia64_log_hexdump(p_data, d_len, prfunc); - prfunc("End of SAL_PROC_DEV_ERR SECTION DATA\n"); + if (cpev >= 0) { + for (irq = 0; irq < NR_IRQS; ++irq) + if (irq_to_vector(irq) == cpev) { + desc = irq_desc(irq); + desc->status |= IRQ_PER_CPU; + desc->handler = &irq_type_iosapic_level; + setup_irq(irq, &mca_cpe_irqaction); + } + ia64_mca_register_cpev(cpev); + } } -#endif // MCA_PRT_XTRA_DATA for test only @FVL - - if (slpi->valid.proc_error_map) - prfunc(" Processor Error Map: %#lx\n", slpi->proc_error_map); - - if (slpi->valid.proc_state_param) - prfunc(" Processor State Param: %#lx\n", slpi->proc_state_parameter); - - if (slpi->valid.proc_cr_lid) - prfunc(" Processor LID: %#lx\n", slpi->proc_cr_lid); +#endif - /* - * Note: March 2001 SAL spec states that if the number of elements in any - * of the MOD_ERROR_INFO_STRUCT arrays is zero, the entire array is - * absent. Also, current implementations only allocate space for number of - * elements used. So we walk the data pointer from here on. + /* Initialize the areas set aside by the OS to buffer the + * platform/processor error states for MCA/INIT/CMC + * handling. */ - p_data = &slpi->cache_check_info[0]; - - /* Print the cache check information if any*/ - for (i = 0 ; i < slpi->valid.num_cache_check; i++, p_data++) - ia64_log_cache_check_info_print(i, p_data, prfunc); - - /* Print the tlb check information if any*/ - for (i = 0 ; i < slpi->valid.num_tlb_check; i++, p_data++) - ia64_log_tlb_check_info_print(i, p_data, prfunc); - - /* Print the bus check information if any*/ - for (i = 0 ; i < slpi->valid.num_bus_check; i++, p_data++) - ia64_log_bus_check_info_print(i, p_data, prfunc); - - /* Print the reg file check information if any*/ - for (i = 0 ; i < slpi->valid.num_reg_file_check; i++, p_data++) - ia64_log_hexdump((u8 *)p_data, sizeof(sal_log_mod_error_info_t), - prfunc); /* Just hex dump for now */ - - /* Print the ms check information if any*/ - for (i = 0 ; i < slpi->valid.num_ms_check; i++, p_data++) - ia64_log_hexdump((u8 *)p_data, sizeof(sal_log_mod_error_info_t), - prfunc); /* Just hex dump for now */ - - /* Print CPUID registers if any*/ - if (slpi->valid.cpuid_info) { - u64 *p = (u64 *)p_data; - - prfunc(" CPUID Regs: %#lx %#lx %#lx %#lx\n", p[0], p[1], p[2], p[3]); - p_data++; - } + ia64_log_init(SAL_INFO_TYPE_MCA); + ia64_log_init(SAL_INFO_TYPE_INIT); + ia64_log_init(SAL_INFO_TYPE_CMC); + ia64_log_init(SAL_INFO_TYPE_CPE); - /* Print processor static info if any */ - if (slpi->valid.psi_static_struct) { - spsi = (sal_processor_static_info_t *)p_data; - - /* copy interrupted context PAL min-state info */ - ia64_process_min_state_save(&spsi->min_state_area); - - /* Print branch register contents if valid */ - if (spsi->valid.br) - ia64_log_processor_regs_print(spsi->br, 8, "Branch", "br", - prfunc); - - /* Print control register contents if valid */ - if (spsi->valid.cr) - ia64_log_processor_regs_print(spsi->cr, 128, "Control", "cr", - prfunc); - - /* Print application register contents if valid */ - if (spsi->valid.ar) - ia64_log_processor_regs_print(spsi->ar, 128, "Application", - "ar", prfunc); - - /* Print region register contents if valid */ - if (spsi->valid.rr) - ia64_log_processor_regs_print(spsi->rr, 8, "Region", "rr", - prfunc); - - /* Print floating-point register contents if valid */ - if (spsi->valid.fr) - ia64_log_processor_fp_regs_print(spsi->fr, 128, "Floating-point", "fr", - prfunc); - } + printk(KERN_INFO "MCA related initialization done\n"); } /* - * ia64_log_processor_info_print + * ia64_mca_late_init * - * Display the processor-specific information logged by PAL as a part - * of MCA or INIT or CMC. + * Opportunity to setup things that require initialization later + * than ia64_mca_init. Setup a timer to poll for CPEs if the + * platform doesn't support an interrupt driven mechanism. * - * Inputs : lh (Pointer of the sal log header which specifies the - * format of SAL state info as specified by the SAL spec). - * prfunc (fn ptr of print function to be used for output). - * Outputs : None + * Inputs : None + * Outputs : Status */ -void -ia64_log_processor_info_print(sal_log_record_header_t *lh, prfunc_t prfunc) +static int __init +ia64_mca_late_init(void) { - sal_log_section_hdr_t *slsh; - int n_sects; - int ercd_pos; + init_timer(&cmc_poll_timer); + cmc_poll_timer.function = ia64_mca_cmc_poll; - if (!lh) - return; + /* Reset to the correct state */ + cmc_polling_enabled = 0; -#ifdef MCA_PRT_XTRA_DATA // for test only @FVL - ia64_log_prt_record_header(lh, prfunc); -#endif // MCA_PRT_XTRA_DATA for test only @FVL - - if ((ercd_pos = sizeof(sal_log_record_header_t)) >= lh->len) { - IA64_MCA_DEBUG("ia64_mca_log_print: " - "truncated SAL CMC error record. len = %d\n", - lh->len); - return; - } - - /* Print record header info */ - ia64_log_rec_header_print(lh, prfunc); - - for (n_sects = 0; (ercd_pos < lh->len); n_sects++, ercd_pos += slsh->len) { - /* point to next section header */ - slsh = (sal_log_section_hdr_t *)((char *)lh + ercd_pos); - -#ifdef MCA_PRT_XTRA_DATA // for test only @FVL - ia64_log_prt_section_header(slsh, prfunc); -#endif // MCA_PRT_XTRA_DATA for test only @FVL - - if (verify_guid(&slsh->guid, &(SAL_PROC_DEV_ERR_SECT_GUID))) { - IA64_MCA_DEBUG("ia64_mca_log_print: unsupported record section\n"); - continue; - } + init_timer(&cpe_poll_timer); + cpe_poll_timer.function = ia64_mca_cpe_poll; - /* - * Now process processor device error record section - */ - ia64_log_proc_dev_err_info_print((sal_log_processor_info_t *)slsh, - printk); - } - - IA64_MCA_DEBUG("ia64_mca_log_print: " - "found %d sections in SAL CMC error record. len = %d\n", - n_sects, lh->len); - if (!n_sects) { - prfunc("No Processor Device Error Info Section found\n"); - return; - } -} - -/* - * ia64_log_platform_info_print - * - * Format and Log the SAL Platform Error Record. - * - * Inputs : lh (Pointer to the sal error record header with format - * specified by the SAL spec). - * prfunc (fn ptr of log output function to use) - * Outputs : platform error status - */ -int -ia64_log_platform_info_print (sal_log_record_header_t *lh, prfunc_t prfunc) -{ - sal_log_section_hdr_t *slsh; - int n_sects; - int ercd_pos; - int platform_err = 0; - - if (!lh) - return platform_err; - -#ifdef MCA_PRT_XTRA_DATA // for test only @FVL - ia64_log_prt_record_header(lh, prfunc); -#endif // MCA_PRT_XTRA_DATA for test only @FVL - - if ((ercd_pos = sizeof(sal_log_record_header_t)) >= lh->len) { - IA64_MCA_DEBUG("ia64_mca_log_print: " - "truncated SAL error record. len = %d\n", - lh->len); - return platform_err; - } - - /* Print record header info */ - ia64_log_rec_header_print(lh, prfunc); - - for (n_sects = 0; (ercd_pos < lh->len); n_sects++, ercd_pos += slsh->len) { - /* point to next section header */ - slsh = (sal_log_section_hdr_t *)((char *)lh + ercd_pos); - -#ifdef MCA_PRT_XTRA_DATA // for test only @FVL - ia64_log_prt_section_header(slsh, prfunc); - - if (efi_guidcmp(slsh->guid, SAL_PROC_DEV_ERR_SECT_GUID) != 0) { - size_t d_len = slsh->len - sizeof(sal_log_section_hdr_t); - char *p_data = (char *)&((sal_log_mem_dev_err_info_t *)slsh)->valid; - - prfunc("Start of Platform Err Data Section: Data buffer = %p, " - "Data size = %ld\n", (void *)p_data, d_len); - ia64_log_hexdump(p_data, d_len, prfunc); - prfunc("End of Platform Err Data Section\n"); - } -#endif // MCA_PRT_XTRA_DATA for test only @FVL - - /* - * Now process CPE error record section - */ - if (efi_guidcmp(slsh->guid, SAL_PROC_DEV_ERR_SECT_GUID) == 0) { - ia64_log_proc_dev_err_info_print((sal_log_processor_info_t *)slsh, - prfunc); - } else if (efi_guidcmp(slsh->guid, SAL_PLAT_MEM_DEV_ERR_SECT_GUID) == 0) { - platform_err = 1; - prfunc("+Platform Memory Device Error Info Section\n"); - ia64_log_mem_dev_err_info_print((sal_log_mem_dev_err_info_t *)slsh, - prfunc); - } else if (efi_guidcmp(slsh->guid, SAL_PLAT_SEL_DEV_ERR_SECT_GUID) == 0) { - platform_err = 1; - prfunc("+Platform SEL Device Error Info Section\n"); - ia64_log_sel_dev_err_info_print((sal_log_sel_dev_err_info_t *)slsh, - prfunc); - } else if (efi_guidcmp(slsh->guid, SAL_PLAT_PCI_BUS_ERR_SECT_GUID) == 0) { - platform_err = 1; - prfunc("+Platform PCI Bus Error Info Section\n"); - ia64_log_pci_bus_err_info_print((sal_log_pci_bus_err_info_t *)slsh, - prfunc); - } else if (efi_guidcmp(slsh->guid, SAL_PLAT_SMBIOS_DEV_ERR_SECT_GUID) == 0) { - platform_err = 1; - prfunc("+Platform SMBIOS Device Error Info Section\n"); - ia64_log_smbios_dev_err_info_print((sal_log_smbios_dev_err_info_t *)slsh, - prfunc); - } else if (efi_guidcmp(slsh->guid, SAL_PLAT_PCI_COMP_ERR_SECT_GUID) == 0) { - platform_err = 1; - prfunc("+Platform PCI Component Error Info Section\n"); - ia64_log_pci_comp_err_info_print((sal_log_pci_comp_err_info_t *)slsh, - prfunc); - } else if (efi_guidcmp(slsh->guid, SAL_PLAT_SPECIFIC_ERR_SECT_GUID) == 0) { - platform_err = 1; - prfunc("+Platform Specific Error Info Section\n"); - ia64_log_plat_specific_err_info_print((sal_log_plat_specific_err_info_t *) - slsh, - prfunc); - } else if (efi_guidcmp(slsh->guid, SAL_PLAT_HOST_CTLR_ERR_SECT_GUID) == 0) { - platform_err = 1; - prfunc("+Platform Host Controller Error Info Section\n"); - ia64_log_host_ctlr_err_info_print((sal_log_host_ctlr_err_info_t *)slsh, - prfunc); - } else if (efi_guidcmp(slsh->guid, SAL_PLAT_BUS_ERR_SECT_GUID) == 0) { - platform_err = 1; - prfunc("+Platform Bus Error Info Section\n"); - ia64_log_plat_bus_err_info_print((sal_log_plat_bus_err_info_t *)slsh, - prfunc); - } else { - IA64_MCA_DEBUG("ia64_mca_log_print: unsupported record section\n"); - continue; - } +#ifdef CONFIG_ACPI + /* If platform doesn't support CPEI, get the timer going. */ + if (acpi_request_vector(ACPI_INTERRUPT_CPEI) < 0 && cpe_poll_enabled) { + register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction); + ia64_mca_cpe_poll(0UL); } +#endif - IA64_MCA_DEBUG("ia64_mca_log_print: found %d sections in SAL error record. len = %d\n", - n_sects, lh->len); - if (!n_sects) { - prfunc("No Platform Error Info Sections found\n"); - return platform_err; - } - return platform_err; + return 0; } -/* - * ia64_log_print - * - * Displays the contents of the OS error log information - * - * Inputs : info_type (SAL_INFO_TYPE_{MCA,INIT,CMC,CPE}) - * prfunc (fn ptr of log output function to use) - * Outputs : platform error status - */ -int -ia64_log_print(int sal_info_type, prfunc_t prfunc) -{ - int platform_err = 0; - - 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"); - break; - case SAL_INFO_TYPE_INIT: - prfunc("+MCA INIT ERROR LOG (UNIMPLEMENTED)\n"); - break; - case SAL_INFO_TYPE_CMC: - prfunc("+BEGIN HARDWARE ERROR STATE AT CMC\n"); - ia64_log_processor_info_print(IA64_LOG_CURR_BUFFER(sal_info_type), prfunc); - prfunc("+END HARDWARE ERROR STATE AT CMC\n"); - break; - case SAL_INFO_TYPE_CPE: - prfunc("+BEGIN HARDWARE ERROR STATE AT CPE\n"); - ia64_log_platform_info_print(IA64_LOG_CURR_BUFFER(sal_info_type), prfunc); - prfunc("+END HARDWARE ERROR STATE AT CPE\n"); - break; - default: - prfunc("+MCA UNKNOWN ERROR LOG (UNIMPLEMENTED)\n"); - break; - } - return platform_err; -} +module_init(ia64_mca_late_init); Index: arch/ia64/kernel/mca_asm.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/mca_asm.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/mca_asm.S 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/mca_asm.S 4 Aug 2004 01:25:43 -0000 1.2 @@ -14,6 +14,7 @@ // 3. Move stack ptr 16 bytes to conform to C calling convention // #include +#include #include #include @@ -22,20 +23,15 @@ #include /* - * When we get an machine check, the kernel stack pointer is no longer + * When we get a machine check, the kernel stack pointer is no longer * valid, so we need to set a new stack pointer. */ #define MINSTATE_PHYS /* Make sure stack access is physical for MINSTATE */ /* - * Needed for ia64_sal call - */ -#define SAL_GET_STATE_INFO 0x01000001 - -/* * Needed for return context to SAL */ -#define IA64_MCA_SAME_CONTEXT 0x0 +#define IA64_MCA_SAME_CONTEXT 0 #define IA64_MCA_COLD_BOOT -2 #include "minstate.h" @@ -57,7 +53,9 @@ st8 [_tmp]=r9,0x08;; \ st8 [_tmp]=r10,0x08;; \ st8 [_tmp]=r11,0x08;; \ - st8 [_tmp]=r12,0x08 + st8 [_tmp]=r12,0x08;; \ + st8 [_tmp]=r17,0x08;; \ + st8 [_tmp]=r18,0x08 /* * OS_MCA_TO_SAL_HANDOFF_STATE (SAL 3.0 spec) @@ -70,21 +68,36 @@ * returns ptr to SAL rtn save loc in _tmp */ #define OS_MCA_TO_SAL_HANDOFF_STATE_RESTORE(_tmp) \ -(p6) movl _tmp=ia64_sal_to_os_handoff_state;; \ -(p7) movl _tmp=ia64_os_to_sal_handoff_state;; \ + movl _tmp=ia64_os_to_sal_handoff_state;; \ DATA_VA_TO_PA(_tmp);; \ -(p6) movl r8=IA64_MCA_COLD_BOOT; \ -(p6) movl r10=IA64_MCA_SAME_CONTEXT; \ -(p6) add _tmp=0x18,_tmp;; \ -(p6) ld8 r9=[_tmp],0x10; \ -(p6) movl r22=ia64_mca_min_state_save_info;; \ -(p7) ld8 r8=[_tmp],0x08;; \ -(p7) ld8 r9=[_tmp],0x08;; \ -(p7) ld8 r10=[_tmp],0x08;; \ -(p7) ld8 r22=[_tmp],0x08;; \ - DATA_VA_TO_PA(r22) + ld8 r8=[_tmp],0x08;; \ + ld8 r9=[_tmp],0x08;; \ + ld8 r10=[_tmp],0x08;; \ + ld8 r22=[_tmp],0x08;; // now _tmp is pointing to SAL rtn save location +/* + * COLD_BOOT_HANDOFF_STATE() sets ia64_mca_os_to_sal_state + * imots_os_status=IA64_MCA_COLD_BOOT + * imots_sal_gp=SAL GP + * imots_context=IA64_MCA_SAME_CONTEXT + * imots_new_min_state=Min state save area pointer + * imots_sal_check_ra=Return address to location within SAL_CHECK + * + */ +#define COLD_BOOT_HANDOFF_STATE(sal_to_os_handoff,os_to_sal_handoff,tmp)\ + movl tmp=IA64_MCA_COLD_BOOT; \ + movl sal_to_os_handoff=__pa(ia64_sal_to_os_handoff_state); \ + movl os_to_sal_handoff=__pa(ia64_os_to_sal_handoff_state);; \ + st8 [os_to_sal_handoff]=tmp,8;; \ + ld8 tmp=[sal_to_os_handoff],48;; \ + st8 [os_to_sal_handoff]=tmp,8;; \ + movl tmp=IA64_MCA_SAME_CONTEXT;; \ + st8 [os_to_sal_handoff]=tmp,8;; \ + ld8 tmp=[sal_to_os_handoff],-8;; \ + st8 [os_to_sal_handoff]=tmp,8;; \ + ld8 tmp=[sal_to_os_handoff];; \ + st8 [os_to_sal_handoff]=tmp;; .global ia64_os_mca_dispatch .global ia64_os_mca_dispatch_end @@ -95,21 +108,20 @@ .global ia64_mca_stackframe .global ia64_mca_bspstore .global ia64_init_stack - .global ia64_mca_sal_data_area - .global ia64_tlb_functional - .global ia64_mca_min_state_save_info .text .align 16 ia64_os_mca_dispatch: -#if defined(MCA_TEST) - // Pretend that we are in interrupt context - mov r2=psr - dep r2=0, r2, PSR_IC, 2; - mov psr.l = r2 -#endif /* #if defined(MCA_TEST) */ + // Serialize all MCA processing + movl r2=ia64_mca_serialize + mov r3=1;; + DATA_VA_TO_PA(r2);; +ia64_os_mca_spin: + xchg8 r4=[r2],r3;; + cmp.ne p6,p0=r4,r0 +(p6) br ia64_os_mca_spin // Save the SAL to OS MCA handoff state as defined // by SAL SPEC 3.0 @@ -126,6 +138,182 @@ ia64_os_mca_done_dump: + movl r16=__pa(ia64_sal_to_os_handoff_state)+56 + ;; + ld8 r18=[r16] // Get processor state parameter on existing PALE_CHECK. + ;; + tbit.nz p6,p7=r18,60 +(p7) br.spnt done_tlb_purge_and_reload + + // The following code purges TC and TR entries. Then reload all TC entries. + // Purge percpu data TC entries. +begin_tlb_purge_and_reload: + mov r16=cr.lid + movl r17=__pa(ia64_mca_tlb_list) // Physical address of ia64_mca_tlb_list + mov r19=0 + mov r20=NR_CPUS + ;; +1: cmp.eq p6,p7=r19,r20 +(p6) br.spnt.few err + ld8 r18=[r17],IA64_MCA_TLB_INFO_SIZE + ;; + add r19=1,r19 + cmp.eq p6,p7=r18,r16 +(p7) br.sptk.few 1b + ;; + adds r17=-IA64_MCA_TLB_INFO_SIZE,r17 + ;; + mov r23=r17 // save current ia64_mca_percpu_info addr pointer. + adds r17=16,r17 + ;; + ld8 r18=[r17],8 // r18=ptce_base + ;; + ld4 r19=[r17],4 // r19=ptce_count[0] + ;; + ld4 r20=[r17],4 // r20=ptce_count[1] + ;; + ld4 r21=[r17],4 // r21=ptce_stride[0] + mov r24=0 + ;; + ld4 r22=[r17],4 // r22=ptce_stride[1] + adds r20=-1,r20 + ;; +2: + cmp.ltu p6,p7=r24,r19 +(p7) br.cond.dpnt.few 4f + mov ar.lc=r20 +3: + ptc.e r18 + ;; + add r18=r22,r18 + br.cloop.sptk.few 3b + ;; + add r18=r21,r18 + add r24=1,r24 + ;; + br.sptk.few 2b +4: + srlz.i // srlz.i implies srlz.d + ;; + + // Now purge addresses formerly mapped by TR registers + // 1. Purge ITR&DTR for kernel. + movl r16=KERNEL_START + mov r18=KERNEL_TR_PAGE_SHIFT<<2 + ;; + ptr.i r16, r18 + ptr.d r16, r18 + ;; + srlz.i + ;; + srlz.d + ;; + // 2. Purge DTR for PERCPU data. + movl r16=PERCPU_ADDR + mov r18=PAGE_SHIFT<<2 + ;; + ptr.d r16,r18 + ;; + srlz.d + ;; + // 3. Purge ITR for PAL code. + adds r17=48,r23 + ;; + ld8 r16=[r17] + mov r18=IA64_GRANULE_SHIFT<<2 + ;; + ptr.i r16,r18 + ;; + srlz.i + ;; + // 4. Purge DTR for stack. + mov r16=IA64_KR(CURRENT_STACK) + ;; + shl r16=r16,IA64_GRANULE_SHIFT + movl r19=PAGE_OFFSET + ;; + add r16=r19,r16 + mov r18=IA64_GRANULE_SHIFT<<2 + ;; + ptr.d r16,r18 + ;; + srlz.i + ;; + // Finally reload the TR registers. + // 1. Reload DTR/ITR registers for kernel. + mov r18=KERNEL_TR_PAGE_SHIFT<<2 + movl r17=KERNEL_START + ;; + mov cr.itir=r18 + mov cr.ifa=r17 + mov r16=IA64_TR_KERNEL + movl r18=((1 << KERNEL_TR_PAGE_SHIFT) | PAGE_KERNEL) + ;; + itr.i itr[r16]=r18 + ;; + itr.d dtr[r16]=r18 + ;; + srlz.i + srlz.d + ;; + // 2. Reload DTR register for PERCPU data. + adds r17=8,r23 + movl r16=PERCPU_ADDR // vaddr + movl r18=PAGE_SHIFT<<2 + ;; + mov cr.itir=r18 + mov cr.ifa=r16 + ;; + ld8 r18=[r17] // pte + mov r16=IA64_TR_PERCPU_DATA; + ;; + itr.d dtr[r16]=r18 + ;; + srlz.d + ;; + // 3. Reload ITR for PAL code. + adds r17=40,r23 + ;; + ld8 r18=[r17],8 // pte + ;; + ld8 r16=[r17] // vaddr + mov r19=IA64_GRANULE_SHIFT<<2 + ;; + mov cr.itir=r19 + mov cr.ifa=r16 + mov r20=IA64_TR_PALCODE + ;; + itr.i itr[r20]=r18 + ;; + srlz.i + ;; + // 4. Reload DTR for stack. + mov r16=IA64_KR(CURRENT_STACK) + ;; + shl r16=r16,IA64_GRANULE_SHIFT + movl r19=PAGE_OFFSET + ;; + add r18=r19,r16 + movl r20=PAGE_KERNEL + ;; + add r16=r20,r16 + mov r19=IA64_GRANULE_SHIFT<<2 + ;; + mov cr.itir=r19 + mov cr.ifa=r18 + mov r20=IA64_TR_CURRENT_STACK + ;; + itr.d dtr[r20]=r16 + ;; + srlz.d + ;; + br.sptk.many done_tlb_purge_and_reload +err: + COLD_BOOT_HANDOFF_STATE(r20,r21,r22) + br.sptk.many ia64_os_mca_done_restore + +done_tlb_purge_and_reload: + // Setup new stack frame for OS_MCA handling movl r2=ia64_mca_bspstore;; // local bspstore area location in r2 DATA_VA_TO_PA(r2);; @@ -139,17 +327,11 @@ // (C calling convention) DATA_VA_TO_PA(r12);; - // Check to see if the MCA resulted from a TLB error -begin_tlb_error_check: - br ia64_os_mca_tlb_error_check;; - -done_tlb_error_check: - - // If TLB is functional, enter virtual mode from physical mode + // Enter virtual mode from physical mode VIRTUAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_begin, r4) ia64_os_mca_virtual_begin: - // call our handler + // Call virtual mode handler movl r2=ia64_mca_ucmc_handler;; mov b6=r2;; br.call.sptk.many b0=b6;; @@ -158,13 +340,6 @@ PHYSICAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_end, r4) ia64_os_mca_virtual_end: -#if defined(MCA_TEST) - // Pretend that we are in interrupt context - mov r2=psr;; - dep r2=0, r2, PSR_IC, 2;; - mov psr.l = r2;; -#endif /* #if defined(MCA_TEST) */ - // restore the original stack frame here movl r2=ia64_mca_stackframe // restore stack frame from memory at r2 ;; @@ -180,14 +355,16 @@ br ia64_os_mca_proc_state_restore;; ia64_os_mca_done_restore: - movl r3=ia64_tlb_functional;; - DATA_VA_TO_PA(r3);; - ld8 r3=[r3];; - cmp.eq p6,p7=r0,r3;; OS_MCA_TO_SAL_HANDOFF_STATE_RESTORE(r2);; // branch back to SALE_CHECK ld8 r3=[r2];; mov b0=r3;; // SAL_CHECK return address + + // release lock + movl r3=ia64_mca_serialize;; + DATA_VA_TO_PA(r3);; + st8.rel [r3]=r0 + br b0 ;; ia64_os_mca_dispatch_end: @@ -265,15 +442,15 @@ add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2 // duplicate r2 in r4 - mov r3=cr0 // cr.dcr - mov r5=cr1 // cr.itm - mov r7=cr2;; // cr.iva + mov r3=cr.dcr + mov r5=cr.itm + mov r7=cr.iva;; st8 [r2]=r3,8*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; // 48 byte rements - mov r3=cr8;; // cr.pta + mov r3=cr.pta;; st8 [r2]=r3,8*8;; // 64 byte rements // if PSR.ic=0, reading interruption registers causes an illegal operation fault @@ -286,23 +463,23 @@ add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2 // duplicate r2 in r6 - mov r3=cr16 // cr.ipsr - mov r5=cr17 // cr.isr - mov r7=r0;; // cr.ida => cr18 (reserved) + mov r3=cr.ipsr + mov r5=cr.isr + mov r7=r0;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=cr19 // cr.iip - mov r5=cr20 // cr.idtr - mov r7=cr21;; // cr.iitr + mov r3=cr.iip + mov r5=cr.ifa + mov r7=cr.itir;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=cr22 // cr.iipa - mov r5=cr23 // cr.ifs - mov r7=cr24;; // cr.iim + mov r3=cr.iipa + mov r5=cr.ifs + mov r7=cr.iim;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; @@ -311,104 +488,101 @@ st8 [r2]=r3,160;; // 160 byte rement SkipIntrRegs: - st8 [r2]=r0,168 // another 168 byte . - - mov r3=cr66;; // cr.lid - st8 [r2]=r3,40 // 40 byte rement - - mov r3=cr71;; // cr.ivr - st8 [r2]=r3,8 + st8 [r2]=r0,152;; // another 152 byte . - mov r3=cr72;; // cr.tpr - st8 [r2]=r3,24 // 24 byte increment + add r4=8,r2 // duplicate r2 in r4 + add r6=2*8,r2 // duplicate r2 in r6 - mov r3=r0;; // cr.eoi => cr75 - st8 [r2]=r3,168 // 168 byte inc. - - mov r3=r0;; // cr.irr0 => cr96 - st8 [r2]=r3,16 // 16 byte inc. - - mov r3=r0;; // cr.irr1 => cr98 - st8 [r2]=r3,16 // 16 byte inc. - - mov r3=r0;; // cr.irr2 => cr100 - st8 [r2]=r3,16 // 16 byte inc - - mov r3=r0;; // cr.irr3 => cr100 - st8 [r2]=r3,16 // 16b inc. - - mov r3=r0;; // cr.itv => cr114 - st8 [r2]=r3,16 // 16 byte inc. + mov r3=cr.lid +// mov r5=cr.ivr // cr.ivr, don't read it + mov r7=cr.tpr;; + st8 [r2]=r3,3*8 + st8 [r4]=r5,3*8 + st8 [r6]=r7,3*8;; - mov r3=r0;; // cr.pmv => cr116 - st8 [r2]=r3,8 + mov r3=r0 // cr.eoi => cr67 + mov r5=r0 // cr.irr0 => cr68 + mov r7=r0;; // cr.irr1 => cr69 + st8 [r2]=r3,3*8 + st8 [r4]=r5,3*8 + st8 [r6]=r7,3*8;; - mov r3=r0;; // cr.lrr0 => cr117 - st8 [r2]=r3,8 + mov r3=r0 // cr.irr2 => cr70 + mov r5=r0 // cr.irr3 => cr71 + mov r7=cr.itv;; + st8 [r2]=r3,3*8 + st8 [r4]=r5,3*8 + st8 [r6]=r7,3*8;; - mov r3=r0;; // cr.lrr1 => cr118 - st8 [r2]=r3,8 + mov r3=cr.pmv + mov r5=cr.cmcv;; + st8 [r2]=r3,7*8 + st8 [r4]=r5,7*8;; + + mov r3=r0 // cr.lrr0 => cr80 + mov r5=r0;; // cr.lrr1 => cr81 + st8 [r2]=r3,23*8 + st8 [r4]=r5,23*8;; - mov r3=r0;; // cr.cmcv => cr119 - st8 [r2]=r3,8*10;; + adds r2=25*8,r2;; cSaveARs: // save ARs add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2 // duplicate r2 in r6 - mov r3=ar0 // ar.kro - mov r5=ar1 // ar.kr1 - mov r7=ar2;; // ar.kr2 + mov r3=ar.k0 + mov r5=ar.k1 + mov r7=ar.k2;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=ar3 // ar.kr3 - mov r5=ar4 // ar.kr4 - mov r7=ar5;; // ar.kr5 + mov r3=ar.k3 + mov r5=ar.k4 + mov r7=ar.k5;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=ar6 // ar.kr6 - mov r5=ar7 // ar.kr7 + mov r3=ar.k6 + mov r5=ar.k7 mov r7=r0;; // ar.kr8 st8 [r2]=r3,10*8 st8 [r4]=r5,10*8 st8 [r6]=r7,10*8;; // rement by 72 bytes - mov r3=ar16 // ar.rsc - mov ar16=r0 // put RSE in enforced lazy mode - mov r5=ar17 // ar.bsp + mov r3=ar.rsc + mov ar.rsc=r0 // put RSE in enforced lazy mode + mov r5=ar.bsp ;; - mov r7=ar18;; // ar.bspstore + mov r7=ar.bspstore;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=ar19;; // ar.rnat + mov r3=ar.rnat;; st8 [r2]=r3,8*13 // increment by 13x8 bytes - mov r3=ar32;; // ar.ccv + mov r3=ar.ccv;; st8 [r2]=r3,8*4 - mov r3=ar36;; // ar.unat + mov r3=ar.unat;; st8 [r2]=r3,8*4 - mov r3=ar40;; // ar.fpsr + mov r3=ar.fpsr;; st8 [r2]=r3,8*4 - mov r3=ar44;; // ar.itc + mov r3=ar.itc;; st8 [r2]=r3,160 // 160 - mov r3=ar64;; // ar.pfs + mov r3=ar.pfs;; st8 [r2]=r3,8 - mov r3=ar65;; // ar.lc + mov r3=ar.lc;; st8 [r2]=r3,8 - mov r3=ar66;; // ar.ec + mov r3=ar.ec;; st8 [r2]=r3 add r2=8*62,r2 //padding @@ -417,7 +591,8 @@ movl r4=0x00;; cStRR: - mov r3=rr[r4];; + dep.z r5=r4,61,3;; + mov r3=rr[r5];; st8 [r2]=r3,8 add r4=1,r4 br.cloop.sptk.few cStRR @@ -501,12 +676,12 @@ ld8 r3=[r2],8*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; // 48 byte increments - mov cr0=r3 // cr.dcr - mov cr1=r5 // cr.itm - mov cr2=r7;; // cr.iva + mov cr.dcr=r3 + mov cr.itm=r5 + mov cr.iva=r7;; ld8 r3=[r2],8*8;; // 64 byte increments -// mov cr8=r3 // cr.pta +// mov cr.pta=r3 // if PSR.ic=1, reading interruption registers causes an illegal operation fault @@ -523,64 +698,66 @@ ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov cr16=r3 // cr.ipsr - mov cr17=r5 // cr.isr is read only -// mov cr18=r7;; // cr.ida (reserved - don't restore) + mov cr.ipsr=r3 +// mov cr.isr=r5 // cr.isr is read only ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov cr19=r3 // cr.iip - mov cr20=r5 // cr.idtr - mov cr21=r7;; // cr.iitr + mov cr.iip=r3 + mov cr.ifa=r5 + mov cr.itir=r7;; ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov cr22=r3 // cr.iipa - mov cr23=r5 // cr.ifs - mov cr24=r7 // cr.iim + mov cr.iipa=r3 + mov cr.ifs=r5 + mov cr.iim=r7 ld8 r3=[r2],160;; // 160 byte increment - mov cr25=r3 // cr.iha + mov cr.iha=r3 rSkipIntrRegs: - ld8 r3=[r2],168;; // another 168 byte inc. - - ld8 r3=[r2],40;; // 40 byte increment - mov cr66=r3 // cr.lid - - ld8 r3=[r2],8;; -// mov cr71=r3 // cr.ivr is read only - ld8 r3=[r2],24;; // 24 byte increment - mov cr72=r3 // cr.tpr - - ld8 r3=[r2],168;; // 168 byte inc. -// mov cr75=r3 // cr.eoi - - ld8 r3=[r2],16;; // 16 byte inc. -// mov cr96=r3 // cr.irr0 is read only + ld8 r3=[r2],152;; // another 152 byte inc. - ld8 r3=[r2],16;; // 16 byte inc. -// mov cr98=r3 // cr.irr1 is read only + add r4=8,r2 // duplicate r2 in r4 + add r6=2*8,r2;; // duplicate r2 in r6 - ld8 r3=[r2],16;; // 16 byte inc -// mov cr100=r3 // cr.irr2 is read only + ld8 r3=[r2],8*3 + ld8 r5=[r4],8*3 + ld8 r7=[r6],8*3;; + mov cr.lid=r3 +// mov cr.ivr=r5 // cr.ivr is read only + mov cr.tpr=r7;; + + ld8 r3=[r2],8*3 + ld8 r5=[r4],8*3 + ld8 r7=[r6],8*3;; +// mov cr.eoi=r3 +// mov cr.irr0=r5 // cr.irr0 is read only +// mov cr.irr1=r7;; // cr.irr1 is read only + + ld8 r3=[r2],8*3 + ld8 r5=[r4],8*3 + ld8 r7=[r6],8*3;; +// mov cr.irr2=r3 // cr.irr2 is read only +// mov cr.irr3=r5 // cr.irr3 is read only + mov cr.itv=r7;; + + ld8 r3=[r2],8*7 + ld8 r5=[r4],8*7;; + mov cr.pmv=r3 + mov cr.cmcv=r5;; + + ld8 r3=[r2],8*23 + ld8 r5=[r4],8*23;; + adds r2=8*23,r2 + adds r4=8*23,r4;; +// mov cr.lrr0=r3 +// mov cr.lrr1=r5 - ld8 r3=[r2],16;; // 16b inc. -// mov cr102=r3 // cr.irr3 is read only - - ld8 r3=[r2],16;; // 16 byte inc. -// mov cr114=r3 // cr.itv - - ld8 r3=[r2],8;; -// mov cr116=r3 // cr.pmv - ld8 r3=[r2],8;; -// mov cr117=r3 // cr.lrr0 - ld8 r3=[r2],8;; -// mov cr118=r3 // cr.lrr1 - ld8 r3=[r2],8*10;; -// mov cr119=r3 // cr.cmcv + adds r2=8*2,r2;; restore_ARs: add r4=8,r2 // duplicate r2 in r4 @@ -589,67 +766,67 @@ ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov ar0=r3 // ar.kro - mov ar1=r5 // ar.kr1 - mov ar2=r7;; // ar.kr2 + mov ar.k0=r3 + mov ar.k1=r5 + mov ar.k2=r7;; ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov ar3=r3 // ar.kr3 - mov ar4=r5 // ar.kr4 - mov ar5=r7;; // ar.kr5 + mov ar.k3=r3 + mov ar.k4=r5 + mov ar.k5=r7;; ld8 r3=[r2],10*8 ld8 r5=[r4],10*8 ld8 r7=[r6],10*8;; - mov ar6=r3 // ar.kr6 - mov ar7=r5 // ar.kr7 -// mov ar8=r6 // ar.kr8 + mov ar.k6=r3 + mov ar.k7=r5 ;; ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; -// mov ar16=r3 // ar.rsc -// mov ar17=r5 // ar.bsp is read only - mov ar16=r0 // make sure that RSE is in enforced lazy mode +// mov ar.rsc=r3 +// mov ar.bsp=r5 // ar.bsp is read only + mov ar.rsc=r0 // make sure that RSE is in enforced lazy mode ;; - mov ar18=r7;; // ar.bspstore + mov ar.bspstore=r7;; ld8 r9=[r2],8*13;; - mov ar19=r9 // ar.rnat + mov ar.rnat=r9 - mov ar16=r3 // ar.rsc + mov ar.rsc=r3 ld8 r3=[r2],8*4;; - mov ar32=r3 // ar.ccv + mov ar.ccv=r3 ld8 r3=[r2],8*4;; - mov ar36=r3 // ar.unat + mov ar.unat=r3 ld8 r3=[r2],8*4;; - mov ar40=r3 // ar.fpsr + mov ar.fpsr=r3 ld8 r3=[r2],160;; // 160 -// mov ar44=r3 // ar.itc +// mov ar.itc=r3 ld8 r3=[r2],8;; - mov ar64=r3 // ar.pfs + mov ar.pfs=r3 ld8 r3=[r2],8;; - mov ar65=r3 // ar.lc + mov ar.lc=r3 ld8 r3=[r2];; - mov ar66=r3 // ar.ec + mov ar.ec=r3 add r2=8*62,r2;; // padding restore_RRs: mov r5=ar.lc mov ar.lc=0x08-1 - movl r4=0x00 + movl r4=0x00;; cStRRr: + dep.z r7=r4,61,3 ld8 r3=[r2],8;; -// mov rr[r4]=r3 // what are its access previledges? + mov rr[r7]=r3 // what are its access previledges? add r4=1,r4 br.cloop.sptk.few cStRRr ;; @@ -660,79 +837,6 @@ //EndStub////////////////////////////////////////////////////////////////////// -//++ -// Name: -// ia64_os_mca_tlb_error_check() -// -// Stub Description: -// -// This stub checks to see if the MCA resulted from a TLB error -// -//-- - -ia64_os_mca_tlb_error_check: - - // Retrieve sal data structure for uncorrected MCA - - // Make the ia64_sal_get_state_info() call - movl r4=ia64_mca_sal_data_area;; - movl r7=ia64_sal;; - mov r6=r1 // save gp - DATA_VA_TO_PA(r4) // convert to physical address - DATA_VA_TO_PA(r7);; // convert to physical address - ld8 r7=[r7] // get addr of pdesc from ia64_sal - movl r3=SAL_GET_STATE_INFO;; - DATA_VA_TO_PA(r7);; // convert to physical address - ld8 r8=[r7],8;; // get pdesc function pointer - dep r8=0,r8,61,3;; // convert SAL VA to PA - ld8 r1=[r7];; // set new (ia64_sal) gp - dep r1=0,r1,61,3;; // convert SAL VA to PA - mov b6=r8 - - alloc r5=ar.pfs,8,0,8,0;; // allocate stack frame for SAL call - mov out0=r3 // which SAL proc to call - mov out1=r0 // error type == MCA - mov out2=r0 // null arg - mov out3=r4 // data copy area - mov out4=r0 // null arg - mov out5=r0 // null arg - mov out6=r0 // null arg - mov out7=r0;; // null arg - - br.call.sptk.few b0=b6;; - - mov r1=r6 // restore gp - mov ar.pfs=r5;; // restore ar.pfs - - movl r6=ia64_tlb_functional;; - DATA_VA_TO_PA(r6) // needed later - - cmp.eq p6,p7=r0,r8;; // check SAL call return address -(p7) st8 [r6]=r0 // clear tlb_functional flag -(p7) br tlb_failure // error; return to SAL - - // examine processor error log for type of error - add r4=40+24,r4;; // parse past record header (length=40) - // and section header (length=24) - ld4 r4=[r4] // get valid field of processor log - mov r5=0xf00;; - and r5=r4,r5;; // read bits 8-11 of valid field - // to determine if we have a TLB error - movl r3=0x1 - cmp.eq p6,p7=r0,r5;; - // if no TLB failure, set tlb_functional flag -(p6) st8 [r6]=r3 - // else clear flag -(p7) st8 [r6]=r0 - - // if no TLB failure, continue with normal virtual mode logging -(p6) br done_tlb_error_check - // else no point in entering virtual mode for logging -tlb_failure: - br ia64_os_mca_virtual_end - -//EndStub////////////////////////////////////////////////////////////////////// - // ok, the issue here is that we need to save state information so // it can be useable by the kernel debugger and show regs routines. @@ -766,8 +870,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 +900,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: Index: arch/ia64/kernel/minstate.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/minstate.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/minstate.h 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/minstate.h 4 Aug 2004 01:25:43 -0000 1.2 @@ -3,43 +3,25 @@ #include "entry.h" /* - * A couple of convenience macros that make writing and reading - * SAVE_MIN and SAVE_REST easier. - */ -#define rARPR r31 -#define rCRIFS r30 -#define rCRIPSR r29 -#define rCRIIP r28 -#define rARRSC r27 -#define rARPFS r26 -#define rARUNAT r25 -#define rARRNAT r24 -#define rARBSPSTORE r23 -#define rKRBS r22 -#define rB6 r21 -#define rR1 r20 - -/* - * Here start the source dependent macros. - */ - -/* - * For ivt.s we want to access the stack virtually so we dont have to disable translation + * For ivt.s we want to access the stack virtually so we don't have to disable translation * on interrupts. + * + * On entry: + * r1: pointer to current task (ar.k6) */ #define MINSTATE_START_SAVE_MIN_VIRT \ dep r1=-1,r1,61,3; /* r1 = current (virtual) */ \ (pUser) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \ ;; \ -(pUser) addl rKRBS=IA64_RBS_OFFSET,r1; /* compute base of RBS */ \ -(pUser) mov rARRNAT=ar.rnat; \ +(pUser) addl r22=IA64_RBS_OFFSET,r1; /* compute base of RBS */ \ +(pUser) mov r24=ar.rnat; \ (pKern) mov r1=sp; /* get sp */ \ ;; \ (pUser) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1; /* compute base of memory stack */ \ -(pUser) mov rARBSPSTORE=ar.bspstore; /* save ar.bspstore */ \ +(pUser) mov r23=ar.bspstore; /* save ar.bspstore */ \ ;; \ (pKern) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \ -(pUser) mov ar.bspstore=rKRBS; /* switch to kernel RBS */ \ +(pUser) mov ar.bspstore=r22; /* switch to kernel RBS */ \ ;; \ (pUser) mov r18=ar.bsp; \ (pUser) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */ \ @@ -51,21 +33,21 @@ /* * For mca_asm.S we want to access the stack physically since the state is saved before we - * go virtual and dont want to destroy the iip or ipsr. + * go virtual and don't want to destroy the iip or ipsr. */ #define MINSTATE_START_SAVE_MIN_PHYS \ (pKern) movl sp=ia64_init_stack+IA64_STK_OFFSET-IA64_PT_REGS_SIZE; \ (pUser) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \ -(pUser) addl rKRBS=IA64_RBS_OFFSET,r1; /* compute base of register backing store */ \ +(pUser) addl r22=IA64_RBS_OFFSET,r1; /* compute base of register backing store */ \ ;; \ -(pUser) mov rARRNAT=ar.rnat; \ +(pUser) mov r24=ar.rnat; \ (pKern) dep r1=0,sp,61,3; /* compute physical addr of sp */ \ (pUser) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1; /* compute base of memory stack */ \ -(pUser) mov rARBSPSTORE=ar.bspstore; /* save ar.bspstore */ \ -(pUser) dep rKRBS=-1,rKRBS,61,3; /* compute kernel virtual addr of RBS */\ +(pUser) mov r23=ar.bspstore; /* save ar.bspstore */ \ +(pUser) dep r22=-1,r22,61,3; /* compute kernel virtual addr of RBS */\ ;; \ (pKern) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \ -(pUser) mov ar.bspstore=rKRBS; /* switch to kernel RBS */ \ +(pUser) mov ar.bspstore=r22; /* switch to kernel RBS */ \ ;; \ (pUser) mov r18=ar.bsp; \ (pUser) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */ \ @@ -96,143 +78,168 @@ * * Upon exit, the state is as follows: * psr.ic: off - * r2 = points to &pt_regs.r16 + * r2 = points to &pt_regs.r16 + * r8 = contents of ar.ccv + * r9 = contents of ar.csd + * r10 = contents of ar.ssd + * r11 = FPSR_DEFAULT * r12 = kernel sp (kernel virtual address) * r13 = points to current task_struct (kernel virtual address) * p15 = TRUE if psr.i is set in cr.ipsr - * predicate registers (other than p2, p3, and p15), b6, r3, r8, r9, r10, r11, r14, r15: + * predicate registers (other than p2, p3, and p15), b6, r3, r14, r15: * preserved * * Note that psr.ic is NOT turned on by this macro. This is so that * we can pass interruption state as arguments to a handler. */ -#define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA) \ - mov rARRSC=ar.rsc; \ - mov rARPFS=ar.pfs; \ - mov rR1=r1; \ - mov rARUNAT=ar.unat; \ - mov rCRIPSR=cr.ipsr; \ - mov rB6=b6; /* rB6 = branch reg 6 */ \ - mov rCRIIP=cr.iip; \ - mov r1=IA64_KR(CURRENT); /* r1 = current (physical) */ \ - COVER; \ - ;; \ - invala; \ - extr.u r16=rCRIPSR,32,2; /* extract psr.cpl */ \ - ;; \ - cmp.eq pKern,pUser=r0,r16; /* are we in kernel mode already? (psr.cpl==0) */ \ - /* switch from user to kernel RBS: */ \ - ;; \ - SAVE_IFS; \ - MINSTATE_START_SAVE_MIN \ - ;; \ - mov r16=r1; /* initialize first base pointer */ \ - adds r17=8,r1; /* initialize second base pointer */ \ - ;; \ - st8 [r16]=rCRIPSR,16; /* save cr.ipsr */ \ - st8 [r17]=rCRIIP,16; /* save cr.iip */ \ -(pKern) mov r18=r0; /* make sure r18 isn't NaT */ \ - ;; \ - st8 [r16]=rCRIFS,16; /* save cr.ifs */ \ - st8 [r17]=rARUNAT,16; /* save ar.unat */ \ -(pUser) sub r18=r18,rKRBS; /* r18=RSE.ndirty*8 */ \ - ;; \ - st8 [r16]=rARPFS,16; /* save ar.pfs */ \ - st8 [r17]=rARRSC,16; /* save ar.rsc */ \ - tbit.nz p15,p0=rCRIPSR,IA64_PSR_I_BIT \ - ;; /* avoid RAW on r16 & r17 */ \ -(pKern) adds r16=16,r16; /* skip over ar_rnat field */ \ -(pKern) adds r17=16,r17; /* skip over ar_bspstore field */ \ -(pUser) st8 [r16]=rARRNAT,16; /* save ar.rnat */ \ -(pUser) st8 [r17]=rARBSPSTORE,16; /* save ar.bspstore */ \ - ;; \ - st8 [r16]=rARPR,16; /* save predicates */ \ - st8 [r17]=rB6,16; /* save b6 */ \ - shl r18=r18,16; /* compute ar.rsc to be used for "loadrs" */ \ - ;; \ - st8 [r16]=r18,16; /* save ar.rsc value for "loadrs" */ \ - st8.spill [r17]=rR1,16; /* save original r1 */ \ - ;; \ -.mem.offset 0,0; st8.spill [r16]=r2,16; \ -.mem.offset 8,0; st8.spill [r17]=r3,16; \ - adds r2=IA64_PT_REGS_R16_OFFSET,r1; \ - ;; \ -.mem.offset 0,0; st8.spill [r16]=r12,16; \ -.mem.offset 8,0; st8.spill [r17]=r13,16; \ - cmp.eq pNonSys,pSys=r0,r0 /* initialize pSys=0, pNonSys=1 */ \ - ;; \ -.mem.offset 0,0; st8.spill [r16]=r14,16; \ -.mem.offset 8,0; st8.spill [r17]=r15,16; \ - dep r14=-1,r0,61,3; \ - ;; \ -.mem.offset 0,0; st8.spill [r16]=r8,16; \ -.mem.offset 8,0; st8.spill [r17]=r9,16; \ - adds r12=-16,r1; /* switch to kernel memory stack (with 16 bytes of scratch) */ \ - ;; \ -.mem.offset 0,0; st8.spill [r16]=r10,16; \ -.mem.offset 8,0; st8.spill [r17]=r11,16; \ - mov r13=IA64_KR(CURRENT); /* establish `current' */ \ - ;; \ - EXTRA; \ - movl r1=__gp; /* establish kernel global pointer */ \ - ;; \ +#define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA) \ + mov r29=cr.ipsr; \ + mov r17=IA64_KR(CURRENT); /* r1 = current (physical) */ \ + mov r20=r1; \ + mov r27=ar.rsc; \ + mov r25=ar.unat; \ + mov r26=ar.pfs; \ + mov r21=ar.fpsr; \ + mov r28=cr.iip; \ + COVER; \ + ;; \ + invala; \ + extr.u r16=r29,32,2; /* extract psr.cpl */ \ + ;; \ + cmp.eq pKern,pUser=r0,r16; /* are we in kernel mode already? (psr.cpl==0) */ \ + mov r1=r17; \ + /* switch from user to kernel RBS: */ \ + ;; \ + SAVE_IFS; \ + MINSTATE_START_SAVE_MIN \ + adds r17=2*L1_CACHE_BYTES,r1; /* really: biggest cache-line size */ \ + adds r16=PT(CR_IPSR),r1; \ + ;; \ + lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES; \ + st8 [r16]=r29; /* save cr.ipsr */ \ + ;; \ + lfetch.fault.excl.nt1 [r17]; \ + ;; \ + adds r16=PT(R8),r1; /* initialize first base pointer */ \ + adds r17=PT(R9),r1; /* initialize second base pointer */ \ + ;; \ +.mem.offset 0,0; st8.spill [r16]=r8,16; \ +.mem.offset 8,0; st8.spill [r17]=r9,16; \ + ;; \ +.mem.offset 0,0; st8.spill [r16]=r10,24; \ +.mem.offset 8,0; st8.spill [r17]=r11,32; \ + ;; \ + st8 [r16]=r28,8; /* save cr.iip */ \ + mov r28=b0; /* rCRIIP=branch reg b0 */ \ +(pKern) mov r18=r0; /* make sure r18 isn't NaT */ \ + mov r8=ar.ccv; \ + mov r9=ar.csd; \ + mov r10=ar.ssd; \ + movl r11=FPSR_DEFAULT; /* L-unit */ \ + ;; \ + st8 [r16]=r30,16; /* save cr.ifs */ \ + st8 [r17]=r25,16; /* save ar.unat */ \ +(pUser) sub r18=r18,r22; /* r18=RSE.ndirty*8 */ \ + ;; \ + st8 [r16]=r26,16; /* save ar.pfs */ \ + st8 [r17]=r27,16; /* save ar.rsc */ \ + tbit.nz p15,p0=r29,IA64_PSR_I_BIT \ + ;; /* avoid RAW on r16 & r17 */ \ +(pKern) adds r16=16,r16; /* skip over ar_rnat field */ \ +(pKern) adds r17=16,r17; /* skip over ar_bspstore field */ \ +(pUser) st8 [r16]=r24,16; /* save ar.rnat */ \ +(pUser) st8 [r17]=r23,16; /* save ar.bspstore */ \ + ;; \ + st8 [r16]=r31,16; /* save predicates */ \ + st8 [r17]=r28,16; /* save b0 */ \ + shl r18=r18,16; /* compute ar.rsc to be used for "loadrs" */ \ + ;; \ + st8 [r16]=r18,16; /* save ar.rsc value for "loadrs" */ \ + st8.spill [r17]=r20,16; /* save original r1 */ \ + ;; \ +.mem.offset 0,0; st8.spill [r16]=r12,16; \ +.mem.offset 8,0; st8.spill [r17]=r13,16; \ + cmp.eq pNonSys,pSys=r0,r0 /* initialize pSys=0, pNonSys=1 */ \ + ;; \ +.mem.offset 0,0; st8 [r16]=r21,PT(R14)-PT(AR_FPSR); /* ar.fpsr */ \ +.mem.offset 8,0; st8.spill [r17]=r15,PT(R3)-PT(R15); \ + adds r12=-16,r1; /* switch to kernel memory stack (with 16 bytes of scratch) */ \ + ;; \ + mov r13=IA64_KR(CURRENT); /* establish `current' */ \ +.mem.offset 0,0; st8.spill [r16]=r14,8; \ + dep r14=-1,r0,61,3; \ + ;; \ +.mem.offset 0,0; st8.spill [r16]=r2,16; \ +.mem.offset 8,0; st8.spill [r17]=r3,16; \ + adds r2=IA64_PT_REGS_R16_OFFSET,r1; \ + ;; \ + EXTRA; \ + movl r1=__gp; /* establish kernel global pointer */ \ + ;; \ MINSTATE_END_SAVE_MIN /* - * SAVE_REST saves the remainder of pt_regs (with psr.ic on). This - * macro guarantees to preserve all predicate registers, r8, r9, r10, - * r11, r14, and r15. + * SAVE_REST saves the remainder of pt_regs (with psr.ic on). * * Assumed state upon entry: * psr.ic: on * r2: points to &pt_regs.r16 * r3: points to &pt_regs.r17 + * r8: contents of ar.ccv + * r9: contents of ar.csd + * r10: contents of ar.ssd + * r11: FPSR_DEFAULT + * + * Registers r14 and r15 are guaranteed not to be touched by SAVE_REST. */ #define SAVE_REST \ -.mem.offset 0,0; st8.spill [r2]=r16,16; \ -.mem.offset 8,0; st8.spill [r3]=r17,16; \ - ;; \ -.mem.offset 0,0; st8.spill [r2]=r18,16; \ -.mem.offset 8,0; st8.spill [r3]=r19,16; \ +.mem.offset 0,0; st8.spill [r2]=r16,16; \ +.mem.offset 8,0; st8.spill [r3]=r17,16; \ ;; \ - mov r16=ar.ccv; /* M-unit */ \ - movl r18=FPSR_DEFAULT /* L-unit */ \ +.mem.offset 0,0; st8.spill [r2]=r18,16; \ +.mem.offset 8,0; st8.spill [r3]=r19,16; \ ;; \ - mov r17=ar.fpsr; /* M-unit */ \ - mov ar.fpsr=r18; /* M-unit */ \ +.mem.offset 0,0; st8.spill [r2]=r20,16; \ +.mem.offset 8,0; st8.spill [r3]=r21,16; \ + mov r18=b6; \ ;; \ -.mem.offset 0,0; st8.spill [r2]=r20,16; \ -.mem.offset 8,0; st8.spill [r3]=r21,16; \ - mov r18=b0; \ - ;; \ -.mem.offset 0,0; st8.spill [r2]=r22,16; \ -.mem.offset 8,0; st8.spill [r3]=r23,16; \ +.mem.offset 0,0; st8.spill [r2]=r22,16; \ +.mem.offset 8,0; st8.spill [r3]=r23,16; \ mov r19=b7; \ ;; \ -.mem.offset 0,0; st8.spill [r2]=r24,16; \ -.mem.offset 8,0; st8.spill [r3]=r25,16; \ - ;; \ -.mem.offset 0,0; st8.spill [r2]=r26,16; \ -.mem.offset 8,0; st8.spill [r3]=r27,16; \ +.mem.offset 0,0; st8.spill [r2]=r24,16; \ +.mem.offset 8,0; st8.spill [r3]=r25,16; \ ;; \ -.mem.offset 0,0; st8.spill [r2]=r28,16; \ -.mem.offset 8,0; st8.spill [r3]=r29,16; \ +.mem.offset 0,0; st8.spill [r2]=r26,16; \ +.mem.offset 8,0; st8.spill [r3]=r27,16; \ ;; \ -.mem.offset 0,0; st8.spill [r2]=r30,16; \ -.mem.offset 8,0; st8.spill [r3]=r31,16; \ +.mem.offset 0,0; st8.spill [r2]=r28,16; \ +.mem.offset 8,0; st8.spill [r3]=r29,16; \ ;; \ - st8 [r2]=r16,16; /* ar.ccv */ \ - st8 [r3]=r17,16; /* ar.fpsr */ \ +.mem.offset 0,0; st8.spill [r2]=r30,16; \ +.mem.offset 8,0; st8.spill [r3]=r31,32; \ ;; \ - st8 [r2]=r18,16; /* b0 */ \ - st8 [r3]=r19,16+8; /* b7 */ \ + mov ar.fpsr=r11; /* M-unit */ \ + st8 [r2]=r8,8; /* ar.ccv */ \ + adds r24=PT(B6)-PT(F7),r3; \ ;; \ stf.spill [r2]=f6,32; \ stf.spill [r3]=f7,32; \ ;; \ stf.spill [r2]=f8,32; \ - stf.spill [r3]=f9,32 + stf.spill [r3]=f9,32; \ + ;; \ + stf.spill [r2]=f10; \ + stf.spill [r3]=f11; \ + adds r25=PT(B7)-PT(F11),r3; \ + ;; \ + st8 [r24]=r18,16; /* b6 */ \ + st8 [r25]=r19,16; /* b7 */ \ + ;; \ + st8 [r24]=r9; /* ar.csd */ \ + st8 [r25]=r10; /* ar.ssd */ \ + ;; -#define SAVE_MIN_WITH_COVER DO_SAVE_MIN(cover, mov rCRIFS=cr.ifs,) -#define SAVE_MIN_WITH_COVER_R19 DO_SAVE_MIN(cover, mov rCRIFS=cr.ifs, mov r15=r19) -#define SAVE_MIN DO_SAVE_MIN( , mov rCRIFS=r0, ) +#define SAVE_MIN_WITH_COVER DO_SAVE_MIN(cover, mov r30=cr.ifs,) +#define SAVE_MIN_WITH_COVER_R19 DO_SAVE_MIN(cover, mov r30=cr.ifs, mov r15=r19) +#define SAVE_MIN DO_SAVE_MIN( , mov r30=r0, ) Index: arch/ia64/kernel/pal.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/pal.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/pal.S 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/pal.S 4 Aug 2004 01:25:43 -0000 1.2 @@ -164,7 +164,7 @@ ;; mov loc4=ar.rsc // save RSE configuration dep.z loc2=loc2,0,61 // convert pal entry point to physical - dep.z r8=r8,0,61 // convert rp to physical + tpa r8=r8 // convert rp to physical ;; mov b7 = loc2 // install target to branch reg mov ar.rsc=0 // put RSE in enforced lazy, LE mode @@ -174,13 +174,13 @@ or loc3=loc3,r17 // add in psr the bits to set ;; andcm r16=loc3,r16 // removes bits to clear from psr - br.call.sptk.many rp=ia64_switch_mode + br.call.sptk.many rp=ia64_switch_mode_phys .ret1: mov rp = r8 // install return address (physical) br.cond.sptk.many b7 1: mov ar.rsc=0 // put RSE in enforced lazy, LE mode mov r16=loc3 // r16= original psr - br.call.sptk.many rp=ia64_switch_mode // return to virtual mode + br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode .ret2: mov psr.l = loc3 // restore init PSR @@ -228,13 +228,13 @@ mov b7 = loc2 // install target to branch reg ;; andcm r16=loc3,r16 // removes bits to clear from psr - br.call.sptk.many rp=ia64_switch_mode + br.call.sptk.many rp=ia64_switch_mode_phys .ret6: br.call.sptk.many rp=b7 // now make the call .ret7: mov ar.rsc=0 // put RSE in enforced lazy, LE mode mov r16=loc3 // r16= original psr - br.call.sptk.many rp=ia64_switch_mode // return to virtual mode + br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode .ret8: mov psr.l = loc3 // restore init PSR mov ar.pfs = loc1 Index: arch/ia64/kernel/palinfo.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/palinfo.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/palinfo.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/palinfo.c 4 Aug 2004 01:25:43 -0000 1.2 @@ -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 { @@ -99,28 +91,17 @@ "eager loads and stores" }; -#define RSE_HINTS_COUNT (sizeof(rse_hints)/sizeof(const char *)) +#define RSE_HINTS_COUNT ARRAY_SIZE(rse_hints) -/* - * 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 */ }; /* @@ -211,15 +192,15 @@ for (i=0; i < 8 ; i++ ) { if (halt_info[i].pal_power_mgmt_info_s.im == 1) { - p += sprintf(p, "Power level %d:\n" \ - "\tentry_latency : %d cycles\n" \ - "\texit_latency : %d cycles\n" \ - "\tpower consumption : %d mW\n" \ - "\tCache+TLB coherency : %s\n", i, - halt_info[i].pal_power_mgmt_info_s.entry_latency, - halt_info[i].pal_power_mgmt_info_s.exit_latency, - halt_info[i].pal_power_mgmt_info_s.power_consumption, - halt_info[i].pal_power_mgmt_info_s.co ? "Yes" : "No"); + p += sprintf(p, "Power level %d:\n" + "\tentry_latency : %d cycles\n" + "\texit_latency : %d cycles\n" + "\tpower consumption : %d mW\n" + "\tCache+TLB coherency : %s\n", i, + halt_info[i].pal_power_mgmt_info_s.entry_latency, + halt_info[i].pal_power_mgmt_info_s.exit_latency, + halt_info[i].pal_power_mgmt_info_s.power_consumption, + halt_info[i].pal_power_mgmt_info_s.co ? "Yes" : "No"); } else { p += sprintf(p,"Power level %d: not implemented\n",i); } @@ -231,20 +212,17 @@ cache_info(char *page) { char *p = page; - u64 levels, unique_caches; + u64 i, levels, unique_caches; pal_cache_config_info_t cci; - int i,j, k; + int 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++) { @@ -254,48 +232,50 @@ if ((status=ia64_pal_cache_config_info(i,j, &cci)) != 0) { continue; } - p += sprintf(p, "%s Cache level %d:\n" \ - "\tSize : %ld bytes\n" \ - "\tAttributes : ", - cache_types[j+cci.pcci_unified], i+1, - cci.pcci_cache_size); + p += sprintf(p, + "%s Cache level %lu:\n" + "\tSize : %lu bytes\n" + "\tAttributes : ", + cache_types[j+cci.pcci_unified], i+1, + cci.pcci_cache_size); if (cci.pcci_unified) p += sprintf(p, "Unified "); p += sprintf(p, "%s\n", cache_mattrib[cci.pcci_cache_attr]); - p += sprintf(p, "\tAssociativity : %d\n" \ - "\tLine size : %d bytes\n" \ - "\tStride : %d bytes\n", - cci.pcci_assoc, - 1<>=1; } p += sprintf(p, "\n\tLoad hints : "); for(k=0; k < 8; k++ ) { - if ( cci.pcci_ld_hints & 0x1) p += sprintf(p, "[%s]", cache_ld_hints[k]); + if (cci.pcci_ld_hints & 0x1) + p += sprintf(p, "[%s]", cache_ld_hints[k]); cci.pcci_ld_hints >>=1; } - p += sprintf(p, "\n\tAlias boundary : %d byte(s)\n" \ - "\tTag LSB : %d\n" \ - "\tTag MSB : %d\n", - 1<0 ; j--) { @@ -392,15 +380,14 @@ continue; } - p += sprintf(p, "\n%s Translation Cache Level %d:\n" \ - "\tHash sets : %d\n" \ - "\tAssociativity : %d\n" \ - "\tNumber of entries : %d\n" \ - "\tFlags : ", - cache_types[j+tc_info.tc_unified], i+1, - tc_info.tc_num_sets, - tc_info.tc_associativity, - tc_info.tc_num_entries); + p += sprintf(p, + "\n%s Translation Cache Level %d:\n" + "\tHash sets : %d\n" + "\tAssociativity : %d\n" + "\tNumber of entries : %d\n" + "\tFlags : ", + cache_types[j+tc_info.tc_unified], i+1, tc_info.tc_num_sets, + tc_info.tc_associativity, tc_info.tc_num_entries); if (tc_info.tc_pf) p += sprintf(p, "PreferredPageSizeOptimized "); if (tc_info.tc_unified) p += sprintf(p, "Unified "); @@ -449,17 +436,18 @@ if (ia64_pal_rse_info(&phys_stacked, &hints) != 0) return 0; - p += sprintf(p, "RSE stacked physical registers : %ld\n" \ - "RSE load/store hints : %ld (%s)\n", - phys_stacked, - hints.ph_data, - hints.ph_data < RSE_HINTS_COUNT ? rse_hints[hints.ph_data]: "(\?\?)"); - - if (ia64_pal_debug_info(&iregs, &dregs)) return 0; - - p += sprintf(p, "Instruction debug register pairs : %ld\n" \ - "Data debug register pairs : %ld\n", - iregs, dregs); + p += sprintf(p, + "RSE stacked physical registers : %ld\n" + "RSE load/store hints : %ld (%s)\n", + phys_stacked, hints.ph_data, + hints.ph_data < RSE_HINTS_COUNT ? rse_hints[hints.ph_data]: "(\?\?)"); + + if (ia64_pal_debug_info(&iregs, &dregs)) + return 0; + + p += sprintf(p, + "Instruction debug register pairs : %ld\n" + "Data debug register pairs : %ld\n", iregs, dregs); return p - page; } @@ -576,26 +564,21 @@ */ if (ia64_pal_version(&min_ver, &cur_ver) != 0) return 0; - p += sprintf(p, "PAL_vendor : 0x%02x (min=0x%02x)\n" \ - "PAL_A : %x.%x.%x (min=%x.%x.%x)\n" \ - "PAL_B : %x.%x.%x (min=%x.%x.%x)\n", - cur_ver.pal_version_s.pv_pal_vendor, - min_ver.pal_version_s.pv_pal_vendor, - - cur_ver.pal_version_s.pv_pal_a_model>>4, - cur_ver.pal_version_s.pv_pal_a_model&0xf, - cur_ver.pal_version_s.pv_pal_a_rev, - min_ver.pal_version_s.pv_pal_a_model>>4, - min_ver.pal_version_s.pv_pal_a_model&0xf, - min_ver.pal_version_s.pv_pal_a_rev, - - cur_ver.pal_version_s.pv_pal_b_model>>4, - cur_ver.pal_version_s.pv_pal_b_model&0xf, - cur_ver.pal_version_s.pv_pal_b_rev, - min_ver.pal_version_s.pv_pal_b_model>>4, - min_ver.pal_version_s.pv_pal_b_model&0xf, - min_ver.pal_version_s.pv_pal_b_rev); - + p += sprintf(p, + "PAL_vendor : 0x%02x (min=0x%02x)\n" + "PAL_A : %x.%x.%x (min=%x.%x.%x)\n" + "PAL_B : %x.%x.%x (min=%x.%x.%x)\n", + cur_ver.pal_version_s.pv_pal_vendor, min_ver.pal_version_s.pv_pal_vendor, + + cur_ver.pal_version_s.pv_pal_a_model>>4, + cur_ver.pal_version_s.pv_pal_a_model&0xf, cur_ver.pal_version_s.pv_pal_a_rev, + min_ver.pal_version_s.pv_pal_a_model>>4, + min_ver.pal_version_s.pv_pal_a_model&0xf, min_ver.pal_version_s.pv_pal_a_rev, + + cur_ver.pal_version_s.pv_pal_b_model>>4, + cur_ver.pal_version_s.pv_pal_b_model&0xf, cur_ver.pal_version_s.pv_pal_b_rev, + min_ver.pal_version_s.pv_pal_b_model>>4, + min_ver.pal_version_s.pv_pal_b_model&0xf, min_ver.pal_version_s.pv_pal_b_rev); return p - page; } @@ -608,26 +591,20 @@ if (ia64_pal_perf_mon_info(pm_buffer, &pm_info) != 0) return 0; - p += sprintf(p, "PMC/PMD pairs : %d\n" \ - "Counter width : %d bits\n" \ - "Cycle event number : %d\n" \ - "Retired event number : %d\n" \ - "Implemented PMC : ", - pm_info.pal_perf_mon_info_s.generic, - pm_info.pal_perf_mon_info_s.width, - pm_info.pal_perf_mon_info_s.cycles, - pm_info.pal_perf_mon_info_s.retired); + p += sprintf(p, + "PMC/PMD pairs : %d\n" + "Counter width : %d bits\n" + "Cycle event number : %d\n" + "Retired event number : %d\n" + "Implemented PMC : ", + pm_info.pal_perf_mon_info_s.generic, pm_info.pal_perf_mon_info_s.width, + pm_info.pal_perf_mon_info_s.cycles, pm_info.pal_perf_mon_info_s.retired); p = bitregister_process(p, pm_buffer, 256); - p += sprintf(p, "\nImplemented PMD : "); - p = bitregister_process(p, pm_buffer+4, 256); - p += sprintf(p, "\nCycles count capable : "); - p = bitregister_process(p, pm_buffer+8, 256); - p += sprintf(p, "\nRetired bundles count capable : "); #ifdef CONFIG_ITANIUM @@ -659,12 +636,11 @@ if (ia64_pal_freq_ratios(&proc, &bus, &itc) != 0) return 0; - p += sprintf(p, "Processor/Clock ratio : %ld/%ld\n" \ - "Bus/Clock ratio : %ld/%ld\n" \ - "ITC/Clock ratio : %ld/%ld\n", - proc.num, proc.den, - bus.num, bus.den, - itc.num, itc.den); + p += sprintf(p, + "Processor/Clock ratio : %ld/%ld\n" + "Bus/Clock ratio : %ld/%ld\n" + "ITC/Clock ratio : %ld/%ld\n", + proc.num, proc.den, bus.num, bus.den, itc.num, itc.den); return p - page; } @@ -678,7 +654,7 @@ u64 tr_buffer[4]; pal_vm_info_1_u_t vm_info_1; pal_vm_info_2_u_t vm_info_2; - int i, j; + u64 i, j; u64 max[3], pgm; struct ifa_reg { u64 valid:1; @@ -712,8 +688,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 +700,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[%lu:%lu]=%ld\n", + i, j, status); continue; } @@ -737,34 +714,29 @@ rid_reg = (struct rid_reg *)&tr_buffer[3]; pgm = -1 << (itir_reg->ps - 12); - p += sprintf(p, "%cTR%d: av=%d pv=%d dv=%d mv=%d\n" \ - "\tppn : 0x%lx\n" \ - "\tvpn : 0x%lx\n" \ - "\tps : ", - - "ID"[i], - j, - tr_valid.pal_tr_valid_s.access_rights_valid, - tr_valid.pal_tr_valid_s.priv_level_valid, - tr_valid.pal_tr_valid_s.dirty_bit_valid, - tr_valid.pal_tr_valid_s.mem_attr_valid, - (gr_reg->ppn & pgm)<< 12, - (ifa_reg->vpn & pgm)<< 12); + p += sprintf(p, + "%cTR%lu: av=%d pv=%d dv=%d mv=%d\n" + "\tppn : 0x%lx\n" + "\tvpn : 0x%lx\n" + "\tps : ", + "ID"[i], j, + tr_valid.pal_tr_valid_s.access_rights_valid, + tr_valid.pal_tr_valid_s.priv_level_valid, + tr_valid.pal_tr_valid_s.dirty_bit_valid, + tr_valid.pal_tr_valid_s.mem_attr_valid, + (gr_reg->ppn & pgm)<< 12, (ifa_reg->vpn & pgm)<< 12); p = bitvector_process(p, 1<< itir_reg->ps); - p += sprintf(p, "\n\tpl : %d\n" \ - "\tar : %d\n" \ - "\trid : %x\n" \ - "\tp : %d\n" \ - "\tma : %d\n" \ - "\td : %d\n", - gr_reg->pl, - gr_reg->ar, - rid_reg->rid, - gr_reg->p, - gr_reg->ma, - gr_reg->d); + p += sprintf(p, + "\n\tpl : %d\n" + "\tar : %d\n" + "\trid : %x\n" + "\tp : %d\n" + "\tma : %d\n" + "\td : %d\n", + gr_reg->pl, gr_reg->ar, rid_reg->rid, gr_reg->p, gr_reg->ma, + gr_reg->d); } } return p - page; @@ -788,7 +760,7 @@ { "tr_info", tr_info, } }; -#define NR_PALINFO_ENTRIES (sizeof(palinfo_entries)/sizeof(palinfo_entry_t)) +#define NR_PALINFO_ENTRIES (int) ARRAY_SIZE(palinfo_entries) /* * this array is used to keep track of the proc entries we create. This is @@ -843,7 +815,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 +842,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 +852,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 +910,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 +920,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; } Index: arch/ia64/kernel/pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/pci.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/pci.c 4 Aug 2004 01:25:43 -0000 1.2 @@ -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,11 +228,14 @@ res->end = end; res->flags = flags; - request_resource(root, res); + if (request_resource(root, res)) + return -EBUSY; + + return 0; } static u64 -add_io_space (acpi_resource_address64 *addr) +add_io_space (struct acpi_resource_address64 *addr) { u64 offset; int sparse = 0; @@ -263,10 +266,10 @@ } static acpi_status -count_window (acpi_resource *resource, void *data) +count_window (struct acpi_resource *resource, void *data) { unsigned int *windows = (unsigned int *) data; - acpi_resource_address64 addr; + struct acpi_resource_address64 addr; acpi_status status; status = acpi_resource_to_address64(resource, &addr); @@ -284,17 +287,20 @@ }; static acpi_status -add_window (acpi_resource *res, void *data) +add_window (struct acpi_resource *res, void *data) { struct pci_root_info *info = (struct pci_root_info *) data; struct pci_window *window; - acpi_resource_address64 addr; + struct acpi_resource_address64 addr; acpi_status status; unsigned long flags, offset = 0; struct resource *root; status = acpi_resource_to_address64(res, &addr); if (ACPI_SUCCESS(status)) { + if (!addr.address_length) + return AE_OK; + if (addr.resource_type == ACPI_MEMORY_RANGE) { flags = IORESOURCE_MEM; root = &iomem_resource; @@ -314,8 +320,11 @@ 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 +338,6 @@ unsigned int windows = 0; char *name; - acpi_root_bridges++; - controller = alloc_pci_controller(seg); if (!controller) goto out1; @@ -379,27 +386,10 @@ void __init pcibios_init (void) { -# define PCI_BUSES_TO_SCAN 256 - int i = 0; - struct pci_controller *controller; - -#ifdef CONFIG_IA64_MCA - ia64_mca_check_errors(); /* For post-failure MCA error logging */ -#endif - pcibios_config_init(); 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; @@ -525,8 +515,6 @@ if (ret < 0) return ret; - platform_pci_enable_device(dev); - printk(KERN_INFO "PCI: Found IRQ %d for device %s\n", dev->irq, dev->slot_name); return 0; @@ -576,9 +564,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; +} Index: arch/ia64/kernel/perfmon.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/perfmon.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/perfmon.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/perfmon.c 4 Aug 2004 01:25:43 -0000 1.2 @@ -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,9 @@ * 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); +#ifndef CONFIG_SMP +static unsigned long pfm_lazy_save_regs (struct task_struct *ta); #endif -static void pfm_lazy_save_regs (struct task_struct *ta); #if defined(CONFIG_ITANIUM) #include "perfmon_itanium.h" @@ -465,13 +474,13 @@ static inline void pfm_clear_psr_up(void) { - __asm__ __volatile__ ("rum psr.up;; srlz.i;;"::: "memory"); + __asm__ __volatile__ ("rsm psr.up;; srlz.i;;"::: "memory"); } static inline void pfm_set_psr_up(void) { - __asm__ __volatile__ ("sum psr.up;; srlz.i;;"::: "memory"); + __asm__ __volatile__ ("ssm psr.up;; srlz.i;;"::: "memory"); } static inline unsigned long @@ -504,6 +513,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 +672,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 +737,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 +748,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 +773,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 +794,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 +952,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 +1070,7 @@ pfm_sessions.pfs_sys_use_dbregs, is_syswide, cpu_mask)); - + if (is_syswide) { m = cpu_mask; n = 0; @@ -1005,7 +1084,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 +1105,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 +1197,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 +1346,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 +1360,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 +1382,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 +1488,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 +1510,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 +1523,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(cnum) && 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 +1598,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 +1719,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 +1728,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 +1763,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 +1777,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 +1807,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 +1932,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 +2170,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 +2178,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 +2193,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 +2458,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 +2479,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 +2505,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 +2550,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 +2724,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 +2740,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 +2781,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 +2831,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 +2845,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 +2866,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 +2932,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 +2952,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 +2992,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 +3005,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 +3019,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 +3058,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 +3122,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 +3146,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 +3177,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 +3186,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 +3277,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 +3305,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 +3565,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 +3867,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 +3918,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 +3942,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,10 +4010,13 @@ /* 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)); + /* + * downgrade parent: once means only first child! + */ + ctx->ctx_fl_inherit = PFM_FL_INHERIT_NONE; } /* * task is not yet visible in the tasklist, so we do @@ -3978,7 +4053,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 +4089,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 +4117,6 @@ DBprintk(("setting PM_VALID for [%d]\n", task->pid)); thread->flags |= IA64_THREAD_PM_VALID; } - return 0; } @@ -4171,7 +4260,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 +4420,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 +4458,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 +4483,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 +4501,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; } /* Index: arch/ia64/kernel/perfmon_mckinley.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/perfmon_mckinley.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/perfmon_mckinley.h 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/perfmon_mckinley.h 4 Aug 2004 01:25:43 -0000 1.2 @@ -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; Index: arch/ia64/kernel/process.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/process.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/process.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/process.c 4 Aug 2004 01:25:43 -0000 1.2 @@ -1,7 +1,7 @@ /* * Architecture-specific setup. * - * Copyright (C) 1998-2002 Hewlett-Packard Co + * Copyright (C) 1998-2003 Hewlett-Packard Co * David Mosberger-Tang */ #define __KERNEL_SYSCALLS__ /* see */ @@ -33,12 +33,15 @@ #include #endif -static void -do_show_stack (struct unw_frame_info *info, void *arg) +#define print_symbol(fmt, addr) printk(fmt, "(no symbol)"); + +void +ia64_do_show_stack (struct unw_frame_info *info, void *arg) { unsigned long ip, sp, bsp; + char buf[128]; /* don't make it so big that it overflows the stack! */ - printk("\nCall Trace: "); + printk("\nCall Trace:\n"); do { unw_get_ip(info, &ip); if (ip == 0) @@ -46,46 +49,49 @@ 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" + " sp=%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); -} - -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); } } void +show_trace_task (struct task_struct *task) +{ + show_stack(task); +} + +void show_regs (struct pt_regs *regs) { unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri; - printk("\nPid: %d, comm: %20s\n", current->pid, current->comm); + printk("\nPid: %d, CPU %d, comm: %20s\n", current->pid, smp_processor_id(), current->comm); printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s\n", regs->cr_ipsr, regs->cr_ifs, ip, print_tainted()); + print_symbol("ip is at %s\n", ip); printk("unat: %016lx pfs : %016lx rsc : %016lx\n", regs->ar_unat, regs->ar_pfs, regs->ar_rsc); printk("rnat: %016lx bsps: %016lx pr : %016lx\n", regs->ar_rnat, regs->ar_bspstore, regs->pr); printk("ldrs: %016lx ccv : %016lx fpsr: %016lx\n", regs->loadrs, regs->ar_ccv, regs->ar_fpsr); + printk("csd : %016lx ssd : %016lx\n", regs->ar_csd, regs->ar_ssd); printk("b0 : %016lx b6 : %016lx b7 : %016lx\n", regs->b0, regs->b6, regs->b7); printk("f6 : %05lx%016lx f7 : %05lx%016lx\n", regs->f6.u.bits[1], regs->f6.u.bits[0], @@ -93,6 +99,9 @@ printk("f8 : %05lx%016lx f9 : %05lx%016lx\n", regs->f8.u.bits[1], regs->f8.u.bits[0], regs->f9.u.bits[1], regs->f9.u.bits[0]); + printk("f10 : %05lx%016lx f11 : %05lx%016lx\n", + regs->f10.u.bits[1], regs->f10.u.bits[0], + regs->f11.u.bits[1], regs->f11.u.bits[0]); printk("r1 : %016lx r2 : %016lx r3 : %016lx\n", regs->r1, regs->r2, regs->r3); printk("r8 : %016lx r9 : %016lx r10 : %016lx\n", regs->r8, regs->r9, regs->r10); @@ -119,19 +128,35 @@ } } if (!user_mode(regs)) - show_stack(0); + show_stack(NULL); +} + +/* + * We use this if we don't have any better idle routine.. + */ +void +default_idle (void) +{ +#ifdef CONFIG_IA64_PAL_IDLE + if (!current->need_resched) + safe_halt(); +#endif } void __attribute__((noreturn)) cpu_idle (void *unused) { - /* endless idle loop with no priority at all */ init_idle(); current->nice = 20; current->counter = -100; + /* endless idle loop with no priority at all */ while (1) { + void (*idle)(void) = pm_idle; + if (!idle) + idle = default_idle; + #ifdef CONFIG_SMP if (!current->need_resched) min_xtp(); @@ -141,7 +166,7 @@ #ifdef CONFIG_IA64_SGI_SN snidle(); #endif - continue; + (*idle)(); } #ifdef CONFIG_IA64_SGI_SN @@ -153,8 +178,6 @@ #endif schedule(); check_pgt_cache(); - if (pm_idle) - (*pm_idle)(); } } @@ -331,6 +354,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 @@ -423,6 +447,8 @@ dst[52] = pt->ar_pfs; /* UNW_AR_PFS is == to pt->cr_ifs for interrupt frames */ unw_get_ar(info, UNW_AR_LC, &dst[53]); unw_get_ar(info, UNW_AR_EC, &dst[54]); + unw_get_ar(info, UNW_AR_CSD, &dst[55]); + unw_get_ar(info, UNW_AR_SSD, &dst[56]); } void @@ -492,6 +518,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 +541,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 +579,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) Index: arch/ia64/kernel/ptrace.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/ptrace.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/ptrace.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/ptrace.c 4 Aug 2004 01:25:43 -0000 1.2 @@ -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,9 +25,11 @@ #include #include #ifdef CONFIG_PERFMON -# include +#include #endif +#define offsetof(type,field) ((unsigned long) &((type *) 0)->field) + /* * Bits in the PSR that we allow ptrace() to change: * be, up, ac, mfl, mfh (the user mask; five bits total) @@ -61,12 +63,25 @@ ({ \ unsigned long bit = ia64_unat_pos(&pt->r##first); \ unsigned long mask = ((1UL << (last - first + 1)) - 1) << first; \ - (ia64_rotl(unat, first) >> bit) & mask; \ + unsigned long dist; \ + if (bit < first) \ + dist = 64 + bit - first; \ + else \ + dist = bit - first; \ + ia64_rotr(unat, dist) & mask; \ }) unsigned long val; - val = GET_BITS( 1, 3, scratch_unat); - val |= GET_BITS(12, 15, scratch_unat); + /* + * Registers that are stored consecutively in struct pt_regs can be handled in + * parallel. If the register order in struct_pt_regs changes, this code MUST be + * updated. + */ + val = GET_BITS( 1, 1, scratch_unat); + val |= GET_BITS( 2, 3, scratch_unat); + val |= GET_BITS(12, 13, scratch_unat); + val |= GET_BITS(14, 14, scratch_unat); + val |= GET_BITS(15, 15, scratch_unat); val |= GET_BITS( 8, 11, scratch_unat); val |= GET_BITS(16, 31, scratch_unat); return val; @@ -82,16 +97,29 @@ unsigned long ia64_put_scratch_nat_bits (struct pt_regs *pt, unsigned long nat) { +# define PUT_BITS(first, last, nat) \ + ({ \ + unsigned long bit = ia64_unat_pos(&pt->r##first); \ + unsigned long mask = ((1UL << (last - first + 1)) - 1) << first; \ + long dist; \ + if (bit < first) \ + dist = 64 + bit - first; \ + else \ + dist = bit - first; \ + ia64_rotl(nat & mask, dist); \ + }) unsigned long scratch_unat; -# define PUT_BITS(first, last, nat) \ - ({ \ - unsigned long bit = ia64_unat_pos(&pt->r##first); \ - unsigned long mask = ((1UL << (last - first + 1)) - 1) << bit; \ - (ia64_rotr(nat, first) << bit) & mask; \ - }) - scratch_unat = PUT_BITS( 1, 3, nat); - scratch_unat |= PUT_BITS(12, 15, nat); + /* + * Registers that are stored consecutively in struct pt_regs can be handled in + * parallel. If the register order in struct_pt_regs changes, this code MUST be + * updated. + */ + scratch_unat = PUT_BITS( 1, 1, nat); + scratch_unat |= PUT_BITS( 2, 3, nat); + scratch_unat |= PUT_BITS(12, 13, nat); + scratch_unat |= PUT_BITS(14, 14, nat); + scratch_unat |= PUT_BITS(15, 15, nat); scratch_unat |= PUT_BITS( 8, 11, nat); scratch_unat |= PUT_BITS(16, 31, nat); @@ -198,20 +226,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 +256,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 +283,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 +333,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 +388,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 +439,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 +647,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 +673,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; } @@ -657,9 +718,12 @@ else ia64_flush_fph(child); ptr = (unsigned long *) ((unsigned long) &child->thread.fph + addr); - } else if (addr >= PT_F10 && addr < PT_F15 + 16) { + } else if ((addr >= PT_F10) && (addr < PT_F11 + 16)) { + /* scratch registers untouched by kernel (saved in pt_regs) */ + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, f10) + addr - PT_F10); + } else if (addr >= PT_F12 && addr < PT_F15 + 16) { /* scratch registers untouched by kernel (saved in switch_stack) */ - ptr = (unsigned long *) ((long) sw + addr - PT_NAT_BITS); + ptr = (unsigned long *) ((long) sw + (addr - PT_NAT_BITS - 32)); } else if (addr < PT_AR_LC + 8) { /* preserved state: */ unsigned long nat_bits, scratch_unat, dummy = 0; @@ -701,7 +765,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; } @@ -793,22 +859,69 @@ else return ia64_peek(child, sw, urbs_end, rnat_addr, data); - case PT_R1: case PT_R2: case PT_R3: + case PT_R1: + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r1)); + break; + + case PT_R2: case PT_R3: + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r2) + addr - PT_R2); + break; case PT_R8: case PT_R9: case PT_R10: case PT_R11: - case PT_R12: case PT_R13: case PT_R14: case PT_R15: + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r8)+ addr - PT_R8); + break; + case PT_R12: case PT_R13: + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r12)+ addr - PT_R12); + break; + case PT_R14: + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r14)); + break; + case PT_R15: + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r15)); + break; case PT_R16: case PT_R17: case PT_R18: case PT_R19: case PT_R20: case PT_R21: case PT_R22: case PT_R23: case PT_R24: case PT_R25: case PT_R26: case PT_R27: case PT_R28: case PT_R29: case PT_R30: case PT_R31: - case PT_B0: case PT_B6: case PT_B7: + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r16) + addr - PT_R16); + break; + case PT_B0: + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, b0)); + break; + case PT_B6: + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, b6)); + break; + case PT_B7: + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, b7)); + break; case PT_F6: case PT_F6+8: case PT_F7: case PT_F7+8: case PT_F8: case PT_F8+8: case PT_F9: case PT_F9+8: + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, f6) + addr - PT_F6); + break; case PT_AR_BSPSTORE: - case PT_AR_RSC: case PT_AR_UNAT: case PT_AR_PFS: - case PT_AR_CCV: case PT_AR_FPSR: case PT_CR_IIP: case PT_PR: - /* scratch register */ - ptr = (unsigned long *) ((long) pt + addr - PT_CR_IPSR); + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_bspstore)); + break; + case PT_AR_RSC: + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_rsc)); + break; + case PT_AR_UNAT: + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_unat)); + break; + case PT_AR_PFS: + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_pfs)); break; + case PT_AR_CCV: + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_ccv)); + break; + case PT_AR_FPSR: + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_fpsr)); + break; + case PT_CR_IIP: + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, cr_iip)); + break; + case PT_PR: + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, pr)); + break; + /* scratch register */ default: /* disallow accessing anything else... */ @@ -816,6 +929,8 @@ addr); return -1; } + } else if (addr <= PT_AR_SSD) { + ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_csd) + addr - PT_AR_CSD); } else { /* access debug registers */ @@ -846,8 +961,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)) { @@ -923,7 +1037,8 @@ /* gr1-gr3 */ - retval |= __copy_to_user(&ppr->gr[1], &pt->r1, sizeof(long) * 3); + retval |= __copy_to_user(&ppr->gr[1], &pt->r1, sizeof(long)); + retval |= __copy_to_user(&ppr->gr[2], &pt->r2, sizeof(long) *2); /* gr4-gr7 */ @@ -937,7 +1052,9 @@ /* gr12-gr15 */ - retval |= __copy_to_user(&ppr->gr[12], &pt->r12, sizeof(long) * 4); + retval |= __copy_to_user(&ppr->gr[12], &pt->r12, sizeof(long) * 2); + retval |= __copy_to_user(&ppr->gr[14], &pt->r14, sizeof(long)); + retval |= __copy_to_user(&ppr->gr[15], &pt->r15, sizeof(long)); /* gr16-gr31 */ @@ -965,13 +1082,13 @@ retval |= access_fr(&info, i, 1, (unsigned long *) &ppr->fr[i] + 1, 0); } - /* fr6-fr9 */ + /* fr6-fr11 */ - retval |= __copy_to_user(&ppr->fr[6], &pt->f6, sizeof(struct ia64_fpreg) * 4); + retval |= __copy_to_user(&ppr->fr[6], &pt->f6, sizeof(struct ia64_fpreg) * 6); - /* fp scratch regs(10-15) */ + /* fp scratch regs(12-15) */ - retval |= __copy_to_user(&ppr->fr[10], &sw->f10, sizeof(struct ia64_fpreg) * 6); + retval |= __copy_to_user(&ppr->fr[12], &sw->f12, sizeof(struct ia64_fpreg) * 4); /* fr16-fr31 */ @@ -1048,7 +1165,8 @@ /* gr1-gr3 */ - retval |= __copy_from_user(&pt->r1, &ppr->gr[1], sizeof(long) * 3); + retval |= __copy_from_user(&pt->r1, &ppr->gr[1], sizeof(long)); + retval |= __copy_from_user(&pt->r2, &ppr->gr[2], sizeof(long) * 2); /* gr4-gr7 */ @@ -1066,7 +1184,9 @@ /* gr12-gr15 */ - retval |= __copy_from_user(&pt->r12, &ppr->gr[12], sizeof(long) * 4); + retval |= __copy_from_user(&pt->r12, &ppr->gr[12], sizeof(long) * 2); + retval |= __copy_from_user(&pt->r14, &ppr->gr[14], sizeof(long)); + retval |= __copy_from_user(&pt->r15, &ppr->gr[15], sizeof(long)); /* gr16-gr31 */ @@ -1094,13 +1214,13 @@ retval |= access_fr(&info, i, 1, (unsigned long *) &ppr->fr[i] + 1, 1); } - /* fr6-fr9 */ + /* fr6-fr11 */ - retval |= __copy_from_user(&pt->f6, &ppr->fr[6], sizeof(ppr->fr[6]) * 4); + retval |= __copy_from_user(&pt->f6, &ppr->fr[6], sizeof(ppr->fr[6]) * 6); - /* fp scratch regs(10-15) */ + /* fp scratch regs(12-15) */ - retval |= __copy_from_user(&sw->f10, &ppr->fr[10], sizeof(ppr->fr[10]) * 6); + retval |= __copy_from_user(&sw->f12, &ppr->fr[12], sizeof(ppr->fr[12]) * 4); /* fr16-fr31 */ @@ -1344,10 +1464,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); Index: arch/ia64/kernel/sal.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/sal.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/sal.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/sal.c 4 Aug 2004 01:25:43 -0000 1.2 @@ -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 "); Index: arch/ia64/kernel/salinfo.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/salinfo.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/salinfo.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/salinfo.c 4 Aug 2004 01:25:43 -0000 1.2 @@ -3,17 +3,39 @@ * * Creates entries in /proc/sal for various system features. * - * Copyright (c) 2001 Silicon Graphics, Inc. All rights reserved. + * Copyright (c) 2003 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 + * Oct 23 2003 kaos@sgi.com + * Replace IPI with set_cpus_allowed() to read a record from the required cpu. + * Redesign salinfo log processing to separate interrupt and user space + * contexts. + * Cache the record across multi-block reads from user space. + * Support > 64 cpus. + * Delete module_exit and MOD_INC/DEC_COUNT, salinfo cannot be a module. + * + * Jan 28 2004 kaos@sgi.com + * Periodically check for outstanding MCA or INIT records. + * + * Feb 21 2004 kaos@sgi.com + * Copy record contents rather than relying on the mca.c buffers, to cope with + * interrupts arriving in mca.c faster than salinfo.c can process them. */ #include #include #include +#include +#include +#include +#include +#include #include +#include MODULE_AUTHOR("Jesse Barnes "); MODULE_DESCRIPTION("/proc interface to IA-64 SAL features"); @@ -38,41 +60,571 @@ { "itc_drift", IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT, }, }; -#define NR_SALINFO_ENTRIES (sizeof(salinfo_entries)/sizeof(salinfo_entry_t)) +#define NR_SALINFO_ENTRIES ARRAY_SIZE(salinfo_entries) -/* - * One for each feature and one more for the directory entry... +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 */ + +/* Allow build with or without large SSI support */ +#ifdef CPU_MASK_NONE +#define SCA(x, y) set_cpus_allowed((x), &(y)) +#else +#define cpumask_t unsigned long +#define SCA(x, y) set_cpus_allowed((x), (y)) +#endif + +/* Some records we get ourselves, some are accessed as saved data in buffers + * that are owned by mca.c. + */ +struct salinfo_data_saved { + u8* buffer; + u64 size; + u64 id; + int cpu; + int kmalloced :1; /* buffer was kmalloc'ed */ +}; + +/* State transitions. Actions are :- + * Write "read " to the data file. + * Write "clear " to the data file. + * Write "oemdata to the data file. + * Read from the data file. + * Close the data file. + * + * Start state is NO_DATA. + * + * NO_DATA + * write "read " -> NO_DATA or LOG_RECORD. + * write "clear " -> NO_DATA or LOG_RECORD. + * write "oemdata -> return -EINVAL. + * read data -> return EOF. + * close -> unchanged. Free record areas. + * + * LOG_RECORD + * write "read " -> NO_DATA or LOG_RECORD. + * write "clear " -> NO_DATA or LOG_RECORD. + * write "oemdata -> format the oem data, goto OEMDATA. + * read data -> return the INIT/MCA/CMC/CPE record. + * close -> unchanged. Keep record areas. + * + * OEMDATA + * write "read " -> NO_DATA or LOG_RECORD. + * write "clear " -> NO_DATA or LOG_RECORD. + * write "oemdata -> format the oem data, goto OEMDATA. + * read data -> return the formatted oemdata. + * close -> unchanged. Keep record areas. + * + * Closing the data file does not change the state. This allows shell scripts + * to manipulate salinfo data, each shell redirection opens the file, does one + * action then closes it again. The record areas are only freed at close when + * the state is NO_DATA. + */ +enum salinfo_state { + STATE_NO_DATA, + STATE_LOG_RECORD, + STATE_OEMDATA, +}; + +struct salinfo_data { + volatile cpumask_t cpu_event; /* which cpus have outstanding events */ + struct semaphore sem; /* count of cpus with outstanding events (bits set in cpu_event) */ + u8 *log_buffer; + u64 log_size; + u8 *oemdata; /* decoded oem data */ + u64 oemdata_size; + int open; /* single-open to prevent races */ + u8 type; + u8 saved_num; /* using a saved record? */ + enum salinfo_state state :8; /* processing state */ + u8 padding; + int cpu_check; /* next CPU to check */ + struct salinfo_data_saved data_saved[5];/* save last 5 records from mca.c, must be < 255 */ +}; + +static struct salinfo_data salinfo_data[ARRAY_SIZE(salinfo_log_name)]; + +static spinlock_t data_lock, data_saved_lock; + +/** salinfo_platform_oemdata - optional callback to decode oemdata from an error + * record. + * @sect_header: pointer to the start of the section to decode. + * @oemdata: returns vmalloc area containing the decded output. + * @oemdata_size: returns length of decoded output (strlen). + * + * Description: If user space asks for oem data to be decoded by the kernel + * and/or prom and the platform has set salinfo_platform_oemdata to the address + * of a platform specific routine then call that routine. salinfo_platform_oemdata + * vmalloc's and formats its output area, returning the address of the text + * and its strlen. Returns 0 for success, -ve for error. The callback is + * invoked on the cpu that generated the error record. */ -static struct proc_dir_entry *salinfo_proc_entries[NR_SALINFO_ENTRIES + 1]; +int (*salinfo_platform_oemdata)(const u8 *sect_header, u8 **oemdata, u64 *oemdata_size); + +struct salinfo_platform_oemdata_parms { + const u8 *efi_guid; + u8 **oemdata; + u64 *oemdata_size; + int ret; +}; + +static void +salinfo_platform_oemdata_cpu(void *context) +{ + struct salinfo_platform_oemdata_parms *parms = context; + parms->ret = salinfo_platform_oemdata(parms->efi_guid, parms->oemdata, parms->oemdata_size); +} + +static void +shift1_data_saved (struct salinfo_data *data, int shift) +{ + if (data->data_saved[shift].kmalloced) + kfree(data->data_saved[shift].buffer); + memcpy(data->data_saved+shift, data->data_saved+shift+1, + (ARRAY_SIZE(data->data_saved) - (shift+1)) * sizeof(data->data_saved[0])); + memset(data->data_saved + ARRAY_SIZE(data->data_saved) - 1, 0, + sizeof(data->data_saved[0])); +} + +/* This routine is invoked in interrupt context. Note: mca.c enables + * interrupts before calling this code for CMC/CPE. MCA and INIT events are + * not irq safe, do not call any routines that use spinlocks, they may deadlock. + * MCA and INIT records are recorded, a timer event will look for any + * outstanding events and wake up the user space code. + * + * The buffer passed from mca.c points to the output from ia64_log_get. This is + * a persistent buffer but its contents can change between the interrupt and + * when user space processes the record. Save the record id to identify + * changes. + */ +void +salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe) +{ + struct salinfo_data *data = salinfo_data + type; + struct salinfo_data_saved *data_saved; + unsigned long flags = 0; + int i; + int saved_size = ARRAY_SIZE(data->data_saved); + + BUG_ON(type >= ARRAY_SIZE(salinfo_log_name)); + + if (irqsafe) + spin_lock_irqsave(&data_saved_lock, flags); + for (i = 0, data_saved = data->data_saved; i < saved_size; ++i, ++data_saved) { + if (!data_saved->buffer) + break; + } + if (i == saved_size) { + if (!data->saved_num) { + shift1_data_saved(data, 0); + data_saved = data->data_saved + saved_size - 1; + } else + data_saved = NULL; + } + if (data_saved) { + data_saved->cpu = smp_processor_id(); + data_saved->id = ((sal_log_record_header_t *)buffer)->id; + data_saved->size = size; + if (irqsafe && (data_saved->buffer = kmalloc(size, GFP_ATOMIC))) { + memcpy(data_saved->buffer, buffer, size); + data_saved->kmalloced = 1; + } else { + data_saved->buffer = buffer; + data_saved->kmalloced = 0; + } + } + if (irqsafe) + spin_unlock_irqrestore(&data_saved_lock, flags); + + if (!test_and_set_bit(smp_processor_id(), &data->cpu_event)) { + if (irqsafe) + up(&data->sem); + } +} + +/* Check for outstanding MCA/INIT records every 5 minutes (arbitrary) */ +#define SALINFO_TIMER_DELAY (5*60*HZ) +static struct timer_list salinfo_timer; + +static void +salinfo_timeout_check(struct salinfo_data *data) +{ + int i; + if (!data->open) + return; + for (i = 0; i < NR_CPUS; ++i) { + if (test_bit(i, &data->cpu_event)) { + /* double up() is not a problem, user space will see no + * records for the additional "events". + */ + up(&data->sem); + } + } +} + +static void +salinfo_timeout (unsigned long arg) +{ + salinfo_timeout_check(salinfo_data + SAL_INFO_TYPE_MCA); + salinfo_timeout_check(salinfo_data + SAL_INFO_TYPE_INIT); + salinfo_timer.expires = jiffies + SALINFO_TIMER_DELAY; + add_timer(&salinfo_timer); +} + +static int +salinfo_event_open(struct inode *inode, struct file *file) +{ + if (!capable(CAP_SYS_ADMIN)) + 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 = PDE(inode); + struct salinfo_data *data = entry->data; + char cmd[32]; + size_t size; + int i, n, cpu = -1; + +retry: + if (down_trylock(&data->sem)) { + if (file->f_flags & O_NONBLOCK) + return -EAGAIN; + if (down_interruptible(&data->sem)) + return -ERESTARTSYS; + } + + n = data->cpu_check; + for (i = 0; i < NR_CPUS; i++) { + if (test_bit(n, &data->cpu_event)) { + cpu = n; + break; + } + if (++n == NR_CPUS) + n = 0; + } + + if (cpu == -1) + goto retry; + + /* events are sticky until the user says "clear" */ + up(&data->sem); + + /* for next read, start checking at next CPU */ + data->cpu_check = cpu; + if (++data->cpu_check == NR_CPUS) + data->cpu_check = 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 = PDE(inode); + struct salinfo_data *data = entry->data; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + spin_lock(&data_lock); + if (data->open) { + spin_unlock(&data_lock); + return -EBUSY; + } + data->open = 1; + spin_unlock(&data_lock); + + if (data->state == STATE_NO_DATA && + !(data->log_buffer = vmalloc(ia64_sal_get_state_info_size(data->type)))) { + data->open = 0; + return -ENOMEM; + } + + return 0; +} + +static int +salinfo_log_release(struct inode *inode, struct file *file) +{ + struct proc_dir_entry *entry = PDE(inode); + struct salinfo_data *data = entry->data; + + if (data->state == STATE_NO_DATA) { + vfree(data->log_buffer); + vfree(data->oemdata); + data->log_buffer = NULL; + data->oemdata = NULL; + } + 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) +{ + cpumask_t save_cpus_allowed, new_cpus_allowed; + memcpy(&save_cpus_allowed, ¤t->cpus_allowed, sizeof(save_cpus_allowed)); + memset(&new_cpus_allowed, 0, sizeof(new_cpus_allowed)); + set_bit(cpu, &new_cpus_allowed); + SCA(current, new_cpus_allowed); + (*fn)(arg); + SCA(current, save_cpus_allowed); +} + +static void +salinfo_log_read_cpu(void *context) +{ + struct salinfo_data *data = context; + data->log_size = ia64_sal_get_state_info(data->type, (u64 *) data->log_buffer); + if (data->type == SAL_INFO_TYPE_CPE || data->type == SAL_INFO_TYPE_CMC) + ia64_sal_clear_state_info(data->type); +} + +static void +salinfo_log_new_read(int cpu, struct salinfo_data *data) +{ + struct salinfo_data_saved *data_saved; + unsigned long flags; + int i; + int saved_size = ARRAY_SIZE(data->data_saved); + + data->saved_num = 0; + spin_lock_irqsave(&data_saved_lock, flags); +retry: + for (i = 0, data_saved = data->data_saved; i < saved_size; ++i, ++data_saved) { + if (data_saved->buffer && data_saved->cpu == cpu) { + sal_log_record_header_t *rh = (sal_log_record_header_t *)(data_saved->buffer); + data->log_size = data_saved->size; + memcpy(data->log_buffer, rh, data->log_size); + barrier(); /* id check must not be moved */ + if (rh->id == data_saved->id) { + data->saved_num = i+1; + break; + } + /* saved record changed by mca.c since interrupt, discard it */ + shift1_data_saved(data, i); + goto retry; + } + } + spin_unlock_irqrestore(&data_saved_lock, flags); + + if (!data->saved_num) + call_on_cpu(cpu, salinfo_log_read_cpu, data); + data->state = data->log_size ? STATE_LOG_RECORD : STATE_NO_DATA; +} + +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 = PDE(inode); + struct salinfo_data *data = entry->data; + void *saldata; + size_t size; + u8 *buf; + u64 bufsize; + + if (data->state == STATE_LOG_RECORD) { + buf = data->log_buffer; + bufsize = data->log_size; + } else if (data->state == STATE_OEMDATA) { + buf = data->oemdata; + bufsize = data->oemdata_size; + } else { + buf = NULL; + bufsize = 0; + } + if (*ppos >= bufsize) + return 0; + + saldata = buf + file->f_pos; + size = bufsize - file->f_pos; + if (size > count) + size = count; + if (copy_to_user(buffer, saldata, size)) + return -EFAULT; + + *ppos += size; + return size; +} + +static void +salinfo_log_clear_cpu(void *context) +{ + struct salinfo_data *data = context; + ia64_sal_clear_state_info(data->type); +} + +static int +salinfo_log_clear(struct salinfo_data *data, int cpu) +{ + data->state = STATE_NO_DATA; + if (!test_bit(cpu, &data->cpu_event)) + return 0; + down(&data->sem); + clear_bit(cpu, &data->cpu_event); + if (data->saved_num) { + unsigned long flags; + spin_lock_irqsave(&data_saved_lock, flags); + shift1_data_saved(data, data->saved_num - 1 ); + data->saved_num = 0; + spin_unlock_irqrestore(&data_saved_lock, flags); + } + /* ia64_mca_log_sal_error_record or salinfo_log_read_cpu already cleared + * CPE and CMC errors + */ + if (data->type != SAL_INFO_TYPE_CPE && data->type != SAL_INFO_TYPE_CMC) + call_on_cpu(cpu, salinfo_log_clear_cpu, data); + /* clearing a record may make a new record visible */ + salinfo_log_new_read(cpu, data); + if (data->state == STATE_LOG_RECORD && + !test_and_set_bit(cpu, &data->cpu_event)) + up(&data->sem); + return 0; +} + +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 = PDE(inode); + struct salinfo_data *data = entry->data; + char cmd[32]; + size_t size; + u32 offset; + 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) { + salinfo_log_new_read(cpu, data); + } else if (sscanf(cmd, "clear %d", &cpu) == 1) { + int ret; + if ((ret = salinfo_log_clear(data, cpu))) + count = ret; + } else if (sscanf(cmd, "oemdata %d %d", &cpu, &offset) == 2) { + if (data->state != STATE_LOG_RECORD && data->state != STATE_OEMDATA) + return -EINVAL; + if (offset > data->log_size - sizeof(efi_guid_t)) + return -EINVAL; + data->state = STATE_OEMDATA; + if (salinfo_platform_oemdata) { + struct salinfo_platform_oemdata_parms parms = { + .efi_guid = data->log_buffer + offset, + .oemdata = &data->oemdata, + .oemdata_size = &data->oemdata_size + }; + call_on_cpu(cpu, salinfo_platform_oemdata_cpu, &parms); + if (parms.ret) + count = parms.ret; + } else + data->oemdata_size = 0; + } else + return -EINVAL; + + 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_data *data; + int i, j, online; 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); } - *sdir++ = salinfo_dir; - - return 0; -} -static void __exit -salinfo_exit(void) -{ - int i = 0; + for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) { + data = salinfo_data + i; + data->type = i; + sema_init(&data->sem, 0); + dir = proc_mkdir(salinfo_log_name[i], salinfo_dir); + if (!dir) + continue; + + entry = create_proc_entry("event", S_IRUSR, dir); + if (!entry) + continue; + entry->data = data; + entry->proc_fops = &salinfo_event_fops; + *sdir++ = entry; + + entry = create_proc_entry("data", S_IRUSR | S_IWUSR, dir); + if (!entry) + continue; + entry->data = data; + entry->proc_fops = &salinfo_data_fops; + *sdir++ = entry; + + /* we missed any events before now */ + online = 0; + for (j = 0; j < NR_CPUS; j++) + if (cpu_online(j)) { + set_bit(j, &data->cpu_event); + ++online; + } + sema_init(&data->sem, online); - for (i = 0; i < NR_SALINFO_ENTRIES ; i++) { - if (salinfo_proc_entries[i]) - remove_proc_entry (salinfo_proc_entries[i]->name, NULL); + *sdir++ = dir; } + + *sdir++ = salinfo_dir; + + init_timer(&salinfo_timer); + salinfo_timer.expires = jiffies + SALINFO_TIMER_DELAY; + salinfo_timer.function = &salinfo_timeout; + add_timer(&salinfo_timer); + + return 0; } /* @@ -84,8 +636,6 @@ { int len = 0; - MOD_INC_USE_COUNT; - len = sprintf(page, (sal_platform_features & (unsigned long)data) ? "1\n" : "0\n"); if (len <= off+count) *eof = 1; @@ -96,10 +646,7 @@ if (len>count) len = count; if (len<0) len = 0; - MOD_DEC_USE_COUNT; - return len; } module_init(salinfo_init); -module_exit(salinfo_exit); Index: arch/ia64/kernel/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/setup.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/setup.c 4 Aug 2004 01:25:43 -0000 1.2 @@ -32,6 +32,10 @@ #include #include +#ifdef CONFIG_BLK_DEV_RAM +# include +#endif + #include #include #include @@ -39,7 +43,10 @@ #include #include #include +#include +#include #include +#include #ifdef CONFIG_BLK_DEV_RAM # include @@ -55,9 +62,10 @@ extern char _end; #ifdef CONFIG_NUMA - struct cpuinfo_ia64 *boot_cpu_data; + struct cpuinfo_ia64 *_cpu_data[NR_CPUS]; #else struct cpuinfo_ia64 _cpu_data[NR_CPUS] __attribute__ ((section ("__special_page_section"))); + mmu_gather_t mmu_gathers[NR_CPUS]; #endif unsigned long ia64_cycles_per_usec; @@ -97,6 +105,7 @@ static struct rsvd_region rsvd_region[IA64_MAX_RSVD_REGIONS + 1]; static int num_rsvd_regions; +#ifndef CONFIG_DISCONTIGMEM static unsigned long bootmap_start; /* physical address where the bootmem map is located */ static int @@ -109,23 +118,79 @@ *max_pfn = pfn; return 0; } +#endif /* !CONFIG_DISCONTIGMEM */ #define IGNORE_PFN0 1 /* XXX fix me: ignore pfn 0 until TLB miss handler is updated... */ +#ifdef CONFIG_DISCONTIGMEM /* - * Free available memory based on the primitive map created from - * the boot parameters. This routine does not assume the incoming - * segments are sorted. + * efi_memmap_walk() knows nothing about layout of memory across nodes. Find + * out to which node a block of memory belongs. Ignore memory that we cannot + * identify, and split blocks that run across multiple nodes. + * + * Take this opportunity to round the start address up and the end address + * down to page boundaries. */ +void +call_pernode_memory (unsigned long start, unsigned long end, void *arg) +{ + unsigned long rs, re; + void (*func)(unsigned long, unsigned long, int); + int i; + + start = PAGE_ALIGN(start); + end &= PAGE_MASK; + if (start >= end) + return; + + func = arg; + + if (!num_memblks) { + /* this machine doesn't have SRAT, */ + /* so call func with nid=0, bank=0 */ + if (start < end) + (*func)(start, end, 0); + return; + } + + for (i = 0; i < num_memblks; i++) { + rs = MAX(__pa(start), node_memblk[i].start_paddr); + re = MIN(__pa(end), node_memblk[i].start_paddr+node_memblk[i].size); + + if (rs < re) + (*func)((unsigned long)__va(rs), (unsigned long)__va(re), node_memblk[i].nid); + if ((unsigned long)__va(re) == end) + break; + } +} + +#else /* CONFIG_DISCONTIGMEM */ + static int free_available_memory (unsigned long start, unsigned long end, void *arg) { + free_bootmem(__pa(start), end - start); + return 0; +} +#endif /* CONFIG_DISCONTIGMEM */ + +/* + * Filter incoming memory segments based on the primitive map created from + * the boot parameters. Segments contained in the map are removed from the + * memory ranges. A caller-specified function is called with the memory + * ranges that remain after filtering. + * This routine does not assume the incoming segments are sorted. + */ +int +filter_rsvd_memory (unsigned long start, unsigned long end, void *arg) +{ unsigned long range_start, range_end, prev_start; + void (*func)(unsigned long, unsigned long, int); int i; #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; } @@ -134,13 +199,18 @@ * lowest possible address(walker uses virtual) */ prev_start = PAGE_OFFSET; + func = arg; for (i = 0; i < num_rsvd_regions; ++i) { range_start = MAX(start, prev_start); range_end = MIN(end, rsvd_region[i].start); if (range_start < range_end) - free_bootmem(__pa(range_start), range_end - range_start); +#ifdef CONFIG_DISCONTIGMEM + call_pernode_memory(range_start, range_end, func); +#else + (*func)(range_start, range_end, 0); +#endif /* nothing more available in this segment */ if (range_end == end) return 0; @@ -152,6 +222,7 @@ } +#ifndef CONFIG_DISCONTIGMEM /* * Find a place to put the bootmap and return its starting address in bootmap_start. * This address must be page-aligned. @@ -190,6 +261,7 @@ } return 0; } +#endif /* CONFIG_DISCONTIGMEM */ static void sort_regions (struct rsvd_region *rsvd_region, int max) @@ -233,8 +305,8 @@ + strlen(__va(ia64_boot_param->command_line)) + 1); n++; - rsvd_region[n].start = KERNEL_START; - rsvd_region[n].end = KERNEL_END; + rsvd_region[n].start = ia64_imva(KERNEL_START); + rsvd_region[n].end = ia64_imva(KERNEL_END); n++; #ifdef CONFIG_BLK_DEV_INITRD @@ -254,6 +326,14 @@ sort_regions(rsvd_region, num_rsvd_regions); +#ifdef CONFIG_DISCONTIGMEM + { + extern void discontig_mem_init(void); + bootmap_size = max_pfn = 0; /* stop gcc warnings */ + discontig_mem_init(); + } +#else /* !CONFIG_DISCONTIGMEM */ + /* first find highest page frame number */ max_pfn = 0; efi_memmap_walk(find_max_pfn, &max_pfn); @@ -270,15 +350,16 @@ bootmap_size = init_bootmem(bootmap_start >> PAGE_SHIFT, max_pfn); /* Free all available memory, then mark bootmem-map as being in use. */ - efi_memmap_walk(free_available_memory, 0); + efi_memmap_walk(filter_rsvd_memory, free_available_memory); reserve_bootmem(bootmap_start, bootmap_size); +#endif /* !CONFIG_DISCONTIGMEM */ #ifdef CONFIG_BLK_DEV_INITRD if (ia64_boot_param->initrd_start) { 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 @@ -298,6 +379,19 @@ efi_init(); +#ifdef CONFIG_ACPI_BOOT + /* Initialize the ACPI boot-time table parser */ + acpi_table_init(); + +# ifdef CONFIG_ACPI_NUMA + acpi_numa_init(); +# endif +#else +# ifdef CONFIG_SMP + smp_build_cpu_map(); /* happens, e.g., with the Ski simulator */ +# endif +#endif /* CONFIG_APCI_BOOT */ + iomem_resource.end = ~0UL; /* FIXME probably belongs elsewhere */ find_memory(); @@ -335,8 +429,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); @@ -352,7 +447,7 @@ cpu_init(); /* initialize the bootstrap CPU */ #ifdef CONFIG_ACPI_BOOT - acpi_boot_init(*cmdline_p); + acpi_boot_init(); #endif #ifdef CONFIG_SERIAL_HCDP if (efi.hcdp) { @@ -445,6 +540,8 @@ c->itc_freq / 1000000, c->itc_freq % 1000000, lpj*HZ/500000, (lpj*HZ/5000) % 100); return 0; +#undef lpj +#undef cpu } static void * @@ -470,10 +567,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 +623,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)); @@ -545,7 +642,7 @@ unsigned int max_ctx; struct cpuinfo_ia64 *my_cpu_data; #ifdef CONFIG_NUMA - int cpu, order; + int cpu; /* * If NUMA is configured, the cpu_data array is not preallocated. The boot cpu @@ -554,30 +651,17 @@ * is required because some boot code references all cpu_data structures * before the cpus are actually started. */ - if (!boot_cpu_data) { - my_cpu_data = alloc_bootmem_pages_node(NODE_DATA(numa_node_id()), - sizeof(struct cpuinfo_ia64)); - boot_cpu_data = my_cpu_data; - my_cpu_data->cpu_data[0] = my_cpu_data; - for (cpu = 1; cpu < NR_CPUS; ++cpu) - my_cpu_data->cpu_data[cpu] - = alloc_bootmem_pages_node(NODE_DATA(numa_node_id()), - sizeof(struct cpuinfo_ia64)); - for (cpu = 1; cpu < NR_CPUS; ++cpu) - memcpy(my_cpu_data->cpu_data[cpu]->cpu_data, - my_cpu_data->cpu_data, sizeof(my_cpu_data->cpu_data)); - } else { - order = get_order(sizeof(struct cpuinfo_ia64)); - my_cpu_data = page_address(alloc_pages_node(numa_node_id(), GFP_KERNEL, order)); - memcpy(my_cpu_data, boot_cpu_data->cpu_data[smp_processor_id()], - sizeof(struct cpuinfo_ia64)); - __free_pages(virt_to_page(boot_cpu_data->cpu_data[smp_processor_id()]), - order); - for (cpu = 0; cpu < NR_CPUS; ++cpu) - boot_cpu_data->cpu_data[cpu]->cpu_data[smp_processor_id()] = my_cpu_data; - } + for (cpu=0; cpu < NR_CPUS; cpu++) + if (node_cpuid[cpu].phys_id == hard_smp_processor_id()) + break; + my_cpu_data = _cpu_data[cpu]; + my_cpu_data->node_data->active_cpu_count++; + + for (cpu=0; cpucpu_data[smp_processor_id()] = my_cpu_data; #else my_cpu_data = cpu_data(smp_processor_id()); + my_cpu_data->mmu_gathers = &mmu_gathers[smp_processor_id()]; #endif /* @@ -609,6 +693,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 +705,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 +732,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 +742,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; Index: arch/ia64/kernel/sigframe.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/sigframe.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/sigframe.h 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/sigframe.h 4 Aug 2004 01:25:43 -0000 1.2 @@ -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; }; Index: arch/ia64/kernel/signal.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/signal.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/signal.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/signal.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -115,18 +115,28 @@ err |= __get_user(cfm, &sc->sc_cfm); err |= __get_user(um, &sc->sc_um); /* user mask */ err |= __get_user(scr->pt.ar_rsc, &sc->sc_ar_rsc); - err |= __get_user(scr->pt.ar_ccv, &sc->sc_ar_ccv); err |= __get_user(scr->pt.ar_unat, &sc->sc_ar_unat); err |= __get_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr); err |= __get_user(scr->pt.ar_pfs, &sc->sc_ar_pfs); err |= __get_user(scr->pt.pr, &sc->sc_pr); /* predicates */ err |= __get_user(scr->pt.b0, &sc->sc_br[0]); /* b0 (rp) */ - err |= __get_user(scr->pt.b6, &sc->sc_br[6]); /* b6 */ - err |= __get_user(scr->pt.b7, &sc->sc_br[7]); /* b7 */ - err |= __copy_from_user(&scr->pt.r1, &sc->sc_gr[1], 3*8); /* r1-r3 */ + err |= __copy_from_user(&scr->pt.r1, &sc->sc_gr[1], 8); /* r1 */ err |= __copy_from_user(&scr->pt.r8, &sc->sc_gr[8], 4*8); /* r8-r11 */ - err |= __copy_from_user(&scr->pt.r12, &sc->sc_gr[12], 4*8); /* r12-r15 */ - err |= __copy_from_user(&scr->pt.r16, &sc->sc_gr[16], 16*8); /* r16-r31 */ + err |= __copy_from_user(&scr->pt.r12, &sc->sc_gr[12], 2*8); /* r12-r13 */ + err |= __copy_from_user(&scr->pt.r15, &sc->sc_gr[15], 8); /* r15 */ + + if ((flags & IA64_SC_FLAG_IN_SYSCALL)==0) + { + // Only get user sig context when not in syscall. + err |= __get_user(scr->pt.ar_ccv, &sc->sc_ar_ccv); + err |= __get_user(scr->pt.ar_csd, &sc->sc_ar25); /* ar.csd */ + err |= __get_user(scr->pt.ar_ssd, &sc->sc_ar26); /* ar.ssd */ + err |= __get_user(scr->pt.b6, &sc->sc_br[6]); /* b6 */ + err |= __get_user(scr->pt.b7, &sc->sc_br[7]); /* b7 */ + err |= __copy_from_user(&scr->pt.r2, &sc->sc_gr[2], 2*8); /* r2-r3 */ + err |= __copy_from_user(&scr->pt.r14, &sc->sc_gr[14], 8); /* r14 */ + err |= __copy_from_user(&scr->pt.r16, &sc->sc_gr[16], 16*8); /* r16-r31 */ + } scr->pt.cr_ifs = cfm | (1UL << 63); @@ -142,8 +152,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 +330,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,42 +340,60 @@ 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; __copy_to_user(&sc->sc_fr[32], current->thread.fph, 96*16); } - /* - * Note: sw->ar_unat is UNDEFINED unless the process is being - * PTRACED. However, this is OK because the NaT bits of the - * preserved registers (r4-r7) are never being looked at by - * the signal handler (registers r4-r7 are used instead). - */ nat = ia64_get_scratch_nat_bits(&scr->pt, scr->scratch_unat); err = __put_user(flags, &sc->sc_flags); 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); err |= __put_user(scr->pt.ar_unat, &sc->sc_ar_unat); /* ar.unat */ err |= __put_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr); /* ar.fpsr */ err |= __put_user(scr->pt.ar_pfs, &sc->sc_ar_pfs); err |= __put_user(scr->pt.pr, &sc->sc_pr); /* predicates */ err |= __put_user(scr->pt.b0, &sc->sc_br[0]); /* b0 (rp) */ - err |= __put_user(scr->pt.b6, &sc->sc_br[6]); /* b6 */ - err |= __put_user(scr->pt.b7, &sc->sc_br[7]); /* b7 */ - - err |= __copy_to_user(&sc->sc_gr[1], &scr->pt.r1, 3*8); /* r1-r3 */ + err |= __copy_to_user(&sc->sc_gr[1], &scr->pt.r1, 8); /* r1 */ err |= __copy_to_user(&sc->sc_gr[8], &scr->pt.r8, 4*8); /* r8-r11 */ - err |= __copy_to_user(&sc->sc_gr[12], &scr->pt.r12, 4*8); /* r12-r15 */ - err |= __copy_to_user(&sc->sc_gr[16], &scr->pt.r16, 16*8); /* r16-r31 */ - + err |= __copy_to_user(&sc->sc_gr[12], &scr->pt.r12, 2*8); /* r12-r13 */ + err |= __copy_to_user(&sc->sc_gr[15], &scr->pt.r15, 8); /* r15 */ err |= __put_user(scr->pt.cr_iip + ia64_psr(&scr->pt)->ri, &sc->sc_ip); + + if (flags & IA64_SC_FLAG_IN_SYSCALL) + { + // Clear scratch registers in sig context for asynchronized signal. + err |= __clear_user(&sc->sc_ar_ccv, 8); + err |= __clear_user(&sc->sc_ar25,8); /* ar.csd */ + err |= __clear_user(&sc->sc_ar26,8); /* ar.ssd */ + err |= __clear_user(&sc->sc_br[6],8); /* b6 */ + err |= __clear_user(&sc->sc_br[7],8); /* b7 */ + + err |= __clear_user(&sc->sc_gr[2], 2*8); /* r2-r3 */ + err |= __clear_user(&sc->sc_gr[14],8); /* r14 */ + err |= __clear_user(&sc->sc_gr[16],16*8); /* r16-r31 */ + } else + { + // Copy scratch registers in sig context from pt_regs for synchronized signal. + err |= __put_user(scr->pt.ar_ccv, &sc->sc_ar_ccv); + err |= __put_user(scr->pt.ar_csd, &sc->sc_ar25); /* ar.csd */ + err |= __put_user(scr->pt.ar_ssd, &sc->sc_ar26); /* ar.ssd */ + err |= __put_user(scr->pt.b6, &sc->sc_br[6]); /* b6 */ + err |= __put_user(scr->pt.b7, &sc->sc_br[7]); /* b7 */ + + err |= __copy_to_user(&sc->sc_gr[2], &scr->pt.r2, 2*8); /* r2-r3 */ + err |= __copy_to_user(&sc->sc_gr[14], &scr->pt.r14, 8); /* r14 */ + err |= __copy_to_user(&sc->sc_gr[16], &scr->pt.r16, 16*8); /* r16-r31 */ + } return err; } @@ -422,6 +455,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 Index: arch/ia64/kernel/smpboot.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/smpboot.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/smpboot.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/smpboot.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -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); } /* @@ -319,6 +320,7 @@ { int cpuid, phys_id; extern void ia64_init_itm(void); + extern void ia64_cpu_local_tick(void); #ifdef CONFIG_PERFMON extern void pfm_init_percpu(void); @@ -328,19 +330,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(); @@ -352,7 +349,6 @@ #ifdef CONFIG_IA64_MCA ia64_mca_cmc_vector_setup(); /* Setup vector on AP & enable */ - ia64_mca_check_errors(); /* For post-failure MCA error logging */ #endif #ifdef CONFIG_PERFMON @@ -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(). @@ -567,11 +576,35 @@ /* Tell SAL where to drop the AP's. */ ap_startup = (struct fptr *) start_ap; sal_ret = ia64_sal_set_vectors(SAL_VECTOR_OS_BOOT_RENDEZ, - __pa(ap_startup->fp), __pa(ap_startup->gp), 0, 0, 0, 0); + ia64_tpa(ap_startup->fp), ia64_tpa(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; } } + +/* + * Initialize the logical CPU number to SAPICID mapping + */ +void __init +smp_build_cpu_map (void) +{ + int sapicid, cpu, i; + int boot_cpu_id = hard_smp_processor_id(); + + for (cpu = 0; cpu < NR_CPUS; cpu++) + ia64_cpu_to_sapicid[cpu] = -1; + + ia64_cpu_to_sapicid[0] = boot_cpu_id; + + for (cpu = 1, i = 0; i < smp_boot_data.cpu_count; i++) { + sapicid = smp_boot_data.cpu_phys_id[i]; + if (sapicid == boot_cpu_id) + continue; + ia64_cpu_to_sapicid[cpu] = sapicid; + cpu++; + } +} + Index: arch/ia64/kernel/sys_ia64.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/sys_ia64.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/sys_ia64.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/sys_ia64.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -29,6 +30,10 @@ if (len > RGN_MAP_LIMIT) return -ENOMEM; +#ifdef CONFIG_HUGETLB_PAGE + if (rgn_index(addr)==REGION_HPAGE) + addr = 0; +#endif if (!addr) addr = TASK_UNMAPPED_BASE; @@ -56,16 +61,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 +82,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 +92,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 +149,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 +226,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; } Index: arch/ia64/kernel/time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/time.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/time.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -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; @@ -95,7 +93,6 @@ * it! */ tv->tv_usec -= gettimeoffset(); - tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ); while (tv->tv_usec < 0) { tv->tv_usec += 1000000; @@ -154,7 +151,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 +240,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 +266,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 +282,9 @@ } static struct irqaction timer_irqaction = { - handler: timer_interrupt, - flags: SA_INTERRUPT, - name: "timer" + .handler = timer_interrupt, + .flags = SA_INTERRUPT, + .name = "timer" }; void __init Index: arch/ia64/kernel/traps.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/traps.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/traps.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/traps.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -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()) { @@ -221,10 +221,6 @@ unsigned long arg4, unsigned long arg5, unsigned long arg6, unsigned long arg7, unsigned long stack) { - struct pt_regs *regs = (struct pt_regs *) &stack; - - printk("%s(%d): \n", current->comm, current->pid, - regs->r15, arg0, arg1, arg2, arg3); return -ENOSYS; } @@ -245,17 +241,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; @@ -273,7 +269,6 @@ fp_emulate (int fp_fault, void *bundle, long *ipsr, long *fpsr, long *isr, long *pr, long *ifs, struct pt_regs *regs) { - struct ia64_fpreg f6_11[6]; fp_state_t fp_state; fpswa_ret_t ret; @@ -288,11 +283,8 @@ * pointer to point to these registers. */ fp_state.bitmask_low64 = 0xfc0; /* bit6..bit11 */ - f6_11[0] = regs->f6; f6_11[1] = regs->f7; - f6_11[2] = regs->f8; f6_11[3] = regs->f9; - __asm__ ("stf.spill %0=f10%P0" : "=m"(f6_11[4])); - __asm__ ("stf.spill %0=f11%P0" : "=m"(f6_11[5])); - fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) f6_11; + + fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) ®s->f6; /* * unsigned long (*EFI_FPSWA) ( * unsigned long trap_type, @@ -308,10 +300,7 @@ (unsigned long *) ipsr, (unsigned long *) fpsr, (unsigned long *) isr, (unsigned long *) pr, (unsigned long *) ifs, &fp_state); - regs->f6 = f6_11[0]; regs->f7 = f6_11[1]; - regs->f8 = f6_11[2]; regs->f9 = f6_11[3]; - __asm__ ("ldf.fill f10=%0%P0" :: "m"(f6_11[4])); - __asm__ ("ldf.fill f11=%0%P0" :: "m"(f6_11[5])); + return ret.status; } @@ -335,10 +324,11 @@ if (jiffies - last_time > 5*HZ) fpu_swa_count = 0; - if ((++fpu_swa_count < 5) && !(current->thread.flags & IA64_THREAD_FPEMU_NOPRINT)) { + if ((fpu_swa_count < 4) && !(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); + ++fpu_swa_count; + 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 +338,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? */ @@ -361,6 +351,10 @@ siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri); if (isr & 0x11) { siginfo.si_code = FPE_FLTINV; + } else if (isr & 0x22) { + /* denormal operand gets the same si_code as underflow + * see arch/i386/kernel/traps.c:math_error() */ + siginfo.si_code = FPE_FLTUND; } else if (isr & 0x44) { siginfo.si_code = FPE_FLTDIV; } @@ -371,7 +365,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 +463,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 +481,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 +585,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 +596,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; Index: arch/ia64/kernel/unaligned.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/unaligned.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/unaligned.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/unaligned.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -217,8 +217,9 @@ RSW(f2), RSW(f3), RSW(f4), RSW(f5), RPT(f6), RPT(f7), RPT(f8), RPT(f9), + RPT(f10), RPT(f11), - RSW(f10), RSW(f11), RSW(f12), RSW(f13), RSW(f14), + RSW(f12), RSW(f13), RSW(f14), RSW(f15), RSW(f16), RSW(f17), RSW(f18), RSW(f19), RSW(f20), RSW(f21), RSW(f22), RSW(f23), RSW(f24), RSW(f25), RSW(f26), RSW(f27), RSW(f28), RSW(f29), Index: arch/ia64/kernel/unwind.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/unwind.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/unwind.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/unwind.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -1,6 +1,8 @@ /* - * Copyright (C) 1999-2002 Hewlett-Packard Co + * Copyright (C) 1999-2003 Hewlett-Packard Co * David Mosberger-Tang + * Copyright (C) 2003 Fenghua Yu + * - Change pt_regs_off() to make it less dependant on pt_regs structure. */ /* * This file implements call frame unwind support for the Linux @@ -24,7 +26,9 @@ * o if both the unw.lock spinlock and a script's read-write lock must be * acquired, then the read-write lock must be acquired first. */ +#include #include +#include #include #include #include @@ -51,18 +55,18 @@ #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; +# 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__) +# 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 @@ -70,7 +74,7 @@ # define STAT(x...) #endif -#define alloc_reg_state() kmalloc(sizeof(struct unw_state_record), GFP_ATOMIC) +#define alloc_reg_state() kmalloc(sizeof(struct unw_reg_state), GFP_ATOMIC) #define free_reg_state(usr) kfree(usr) #define alloc_labeled_state() kmalloc(sizeof(struct unw_labeled_state), GFP_ATOMIC) #define free_labeled_state(usr) kfree(usr) @@ -78,8 +82,6 @@ typedef unsigned long unw_word; typedef unsigned char unw_hash_index_t; -#define struct_offset(str,fld) ((char *)&((str *)NULL)->fld - (char *) 0) - static struct { spinlock_t lock; /* spinlock for unwind data */ @@ -98,6 +100,8 @@ /* index into unw_frame_info for preserved register i */ unsigned short preg_index[UNW_NUM_REGS]; + short pt_regs_offsets[32]; + /* unwind table for the kernel: */ struct unw_table kernel_table; @@ -111,7 +115,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,58 +144,89 @@ } 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: { - 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, - struct_offset(struct unw_frame_info, bspstore_loc)/8, - struct_offset(struct unw_frame_info, pfs_loc)/8, - struct_offset(struct unw_frame_info, rnat_loc)/8, - struct_offset(struct unw_frame_info, psp)/8, - struct_offset(struct unw_frame_info, rp_loc)/8, - struct_offset(struct unw_frame_info, r4)/8, - struct_offset(struct unw_frame_info, r5)/8, - struct_offset(struct unw_frame_info, r6)/8, - struct_offset(struct unw_frame_info, r7)/8, - struct_offset(struct unw_frame_info, unat_loc)/8, - struct_offset(struct unw_frame_info, pr_loc)/8, - struct_offset(struct unw_frame_info, lc_loc)/8, - struct_offset(struct unw_frame_info, fpsr_loc)/8, - struct_offset(struct unw_frame_info, b1_loc)/8, - struct_offset(struct unw_frame_info, b2_loc)/8, - struct_offset(struct unw_frame_info, b3_loc)/8, - struct_offset(struct unw_frame_info, b4_loc)/8, - struct_offset(struct unw_frame_info, b5_loc)/8, - struct_offset(struct unw_frame_info, f2_loc)/8, - struct_offset(struct unw_frame_info, f3_loc)/8, - struct_offset(struct unw_frame_info, f4_loc)/8, - struct_offset(struct unw_frame_info, f5_loc)/8, - struct_offset(struct unw_frame_info, fr_loc[16 - 16])/8, - struct_offset(struct unw_frame_info, fr_loc[17 - 16])/8, - struct_offset(struct unw_frame_info, fr_loc[18 - 16])/8, - struct_offset(struct unw_frame_info, fr_loc[19 - 16])/8, - struct_offset(struct unw_frame_info, fr_loc[20 - 16])/8, - struct_offset(struct unw_frame_info, fr_loc[21 - 16])/8, - struct_offset(struct unw_frame_info, fr_loc[22 - 16])/8, - struct_offset(struct unw_frame_info, fr_loc[23 - 16])/8, - struct_offset(struct unw_frame_info, fr_loc[24 - 16])/8, - struct_offset(struct unw_frame_info, fr_loc[25 - 16])/8, - struct_offset(struct unw_frame_info, fr_loc[26 - 16])/8, - struct_offset(struct unw_frame_info, fr_loc[27 - 16])/8, - struct_offset(struct unw_frame_info, fr_loc[28 - 16])/8, - struct_offset(struct unw_frame_info, fr_loc[29 - 16])/8, - struct_offset(struct unw_frame_info, fr_loc[30 - 16])/8, - struct_offset(struct unw_frame_info, fr_loc[31 - 16])/8, + .preg_index = { + offsetof(struct unw_frame_info, pri_unat_loc)/8, /* PRI_UNAT_GR */ + offsetof(struct unw_frame_info, pri_unat_loc)/8, /* PRI_UNAT_MEM */ + offsetof(struct unw_frame_info, bsp_loc)/8, + offsetof(struct unw_frame_info, bspstore_loc)/8, + offsetof(struct unw_frame_info, pfs_loc)/8, + offsetof(struct unw_frame_info, rnat_loc)/8, + offsetof(struct unw_frame_info, psp)/8, + offsetof(struct unw_frame_info, rp_loc)/8, + offsetof(struct unw_frame_info, r4)/8, + offsetof(struct unw_frame_info, r5)/8, + offsetof(struct unw_frame_info, r6)/8, + offsetof(struct unw_frame_info, r7)/8, + offsetof(struct unw_frame_info, unat_loc)/8, + offsetof(struct unw_frame_info, pr_loc)/8, + offsetof(struct unw_frame_info, lc_loc)/8, + offsetof(struct unw_frame_info, fpsr_loc)/8, + offsetof(struct unw_frame_info, b1_loc)/8, + offsetof(struct unw_frame_info, b2_loc)/8, + offsetof(struct unw_frame_info, b3_loc)/8, + offsetof(struct unw_frame_info, b4_loc)/8, + offsetof(struct unw_frame_info, b5_loc)/8, + offsetof(struct unw_frame_info, f2_loc)/8, + offsetof(struct unw_frame_info, f3_loc)/8, + offsetof(struct unw_frame_info, f4_loc)/8, + offsetof(struct unw_frame_info, f5_loc)/8, + offsetof(struct unw_frame_info, fr_loc[16 - 16])/8, + offsetof(struct unw_frame_info, fr_loc[17 - 16])/8, + offsetof(struct unw_frame_info, fr_loc[18 - 16])/8, + offsetof(struct unw_frame_info, fr_loc[19 - 16])/8, + offsetof(struct unw_frame_info, fr_loc[20 - 16])/8, + offsetof(struct unw_frame_info, fr_loc[21 - 16])/8, + offsetof(struct unw_frame_info, fr_loc[22 - 16])/8, + offsetof(struct unw_frame_info, fr_loc[23 - 16])/8, + offsetof(struct unw_frame_info, fr_loc[24 - 16])/8, + offsetof(struct unw_frame_info, fr_loc[25 - 16])/8, + offsetof(struct unw_frame_info, fr_loc[26 - 16])/8, + offsetof(struct unw_frame_info, fr_loc[27 - 16])/8, + offsetof(struct unw_frame_info, fr_loc[28 - 16])/8, + offsetof(struct unw_frame_info, fr_loc[29 - 16])/8, + offsetof(struct unw_frame_info, fr_loc[30 - 16])/8, + offsetof(struct unw_frame_info, fr_loc[31 - 16])/8, + }, + .pt_regs_offsets = { + [0] = -1, + offsetof(struct pt_regs, r1), + offsetof(struct pt_regs, r2), + offsetof(struct pt_regs, r3), + [4] = -1, [5] = -1, [6] = -1, [7] = -1, + offsetof(struct pt_regs, r8), + offsetof(struct pt_regs, r9), + offsetof(struct pt_regs, r10), + offsetof(struct pt_regs, r11), + offsetof(struct pt_regs, r12), + offsetof(struct pt_regs, r13), + offsetof(struct pt_regs, r14), + offsetof(struct pt_regs, r15), + offsetof(struct pt_regs, r16), + offsetof(struct pt_regs, r17), + offsetof(struct pt_regs, r18), + offsetof(struct pt_regs, r19), + offsetof(struct pt_regs, r20), + offsetof(struct pt_regs, r21), + offsetof(struct pt_regs, r22), + offsetof(struct pt_regs, r23), + offsetof(struct pt_regs, r24), + offsetof(struct pt_regs, r25), + offsetof(struct pt_regs, r26), + offsetof(struct pt_regs, r27), + offsetof(struct pt_regs, r28), + offsetof(struct pt_regs, r29), + offsetof(struct pt_regs, r30), + offsetof(struct pt_regs, r31), }, - 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", @@ -203,7 +238,6 @@ #endif }; - /* Unwind accessors. */ /* @@ -212,19 +246,31 @@ static inline unsigned long pt_regs_off (unsigned long reg) { - unsigned long off =0; + short off = -1; - if (reg >= 1 && reg <= 3) - off = struct_offset(struct pt_regs, r1) + 8*(reg - 1); - else if (reg <= 11) - off = struct_offset(struct pt_regs, r8) + 8*(reg - 8); - else if (reg <= 15) - off = struct_offset(struct pt_regs, r12) + 8*(reg - 12); - else if (reg <= 31) - off = struct_offset(struct pt_regs, r16) + 8*(reg - 16); - else - dprintk("unwind: bad scratch reg r%lu\n", reg); - return off; + if (reg < ARRAY_SIZE(unw.pt_regs_offsets)) + off = unw.pt_regs_offsets[reg]; + + if (off < 0) { + UNW_DPRINT(0, "unwind.%s: bad scratch reg r%lu\n", __FUNCTION__, reg); + off = 0; + } + return (unsigned long) 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 @@ -235,7 +281,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 +332,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 +351,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 +366,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) @@ -341,6 +392,7 @@ } return 0; } +EXPORT_SYMBOL(unw_access_gr); int unw_access_br (struct unw_frame_info *info, int regnum, unsigned long *val, int write) @@ -348,15 +400,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 +414,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) @@ -375,6 +424,7 @@ *val = *addr; return 0; } +EXPORT_SYMBOL(unw_access_br); int unw_access_fr (struct unw_frame_info *info, int regnum, struct ia64_fpreg *val, int write) @@ -383,24 +433,22 @@ 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 <= 11) { + pt = get_scratch_regs(info); addr = &pt->f6 + (regnum - 6); + } else - addr = &info->sw->f10 + (regnum - 10); + addr = &info->sw->f12 + (regnum - 12); } else if (regnum <= 31) { addr = info->fr_loc[regnum - 16]; if (!addr) @@ -421,6 +469,7 @@ *val = *addr; return 0; } +EXPORT_SYMBOL(unw_access_fr); int unw_access_ar (struct unw_frame_info *info, int regnum, unsigned long *val, int write) @@ -428,11 +477,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 +531,28 @@ 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; + case UNW_AR_CSD: + pt = get_scratch_regs(info); + addr = &pt->ar_csd; + break; + + case UNW_AR_SSD: + pt = get_scratch_regs(info); + addr = &pt->ar_ssd; + 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; } @@ -505,6 +562,7 @@ *val = *addr; return 0; } +EXPORT_SYMBOL(unw_access_ar); int unw_access_pr (struct unw_frame_info *info, unsigned long *val, int write) @@ -521,6 +579,7 @@ *val = *addr; return 0; } +EXPORT_SYMBOL(unw_access_pr); /* Routines to manipulate the state stack. */ @@ -532,7 +591,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 +604,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 +620,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 +671,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 +711,7 @@ return; } } - dprintk("unwind: excess spill!\n"); + UNW_DPRINT(0, "unwind.%s: excess spill!\n", __FUNCTION__); } static inline void @@ -666,7 +725,7 @@ * First, resolve implicit register save locations (see Section "11.4.2.3 Rules * for Using Unwind Descriptors", rule 3): */ - for (i = 0; i < (int) sizeof(unw.save_order)/sizeof(unw.save_order[0]); ++i) { + for (i = 0; i < (int) ARRAY_SIZE(unw.save_order); ++i) { reg = sr->curr.reg + unw.save_order[i]; if (reg->where == UNW_WHERE_GR_SAVE) { reg->where = UNW_WHERE_GR; @@ -682,7 +741,7 @@ */ if (sr->imask) { unsigned char kind, mask = 0, *cp = sr->imask; - unsigned long t; + int t; static const unsigned char limit[3] = { UNW_REG_F31, UNW_REG_R7, UNW_REG_B5 }; @@ -720,7 +779,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 +791,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 +825,13 @@ static inline void desc_abi (unsigned char abi, unsigned char context, struct unw_state_record *sr) { - if (abi == 0 && context == 'i') + if (abi == 3 && 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 +1014,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 +1024,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 +1118,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: @@ -1112,9 +1176,10 @@ static inline unw_hash_index_t hash (unsigned long ip) { -# define magic 0x9e3779b97f4a7c16 /* based on (sqrt(5)/2-1)*2^64 */ +# define hashmagic 0x9e3779b97f4a7c16 /* based on (sqrt(5)/2-1)*2^64 */ - return (ip >> 4)*magic >> (64 - UNW_LOG_HASH_SIZE); + return (ip >> 4)*hashmagic >> (64 - UNW_LOG_HASH_SIZE); +#undef hashmagic } static inline long @@ -1135,6 +1200,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; @@ -1190,13 +1258,18 @@ spin_unlock(&unw.lock); /* - * XXX We'll deadlock here if we interrupt a thread that is - * holding a read lock on script->lock. A try_write_lock() - * might be mighty handy here... Alternatively, we could - * disable interrupts whenever we hold a read-lock, but that - * seems silly. + * We'd deadlock here if we interrupted a thread that is holding a read lock on + * script->lock. Thus, if the write_trylock() fails, we simply bail out. The + * alternative would be to disable interrupts whenever we hold a read-lock, but + * that seems silly. + */ + /* Kludge: 2.4 has down_write_trylock on semaphores but not write_trylock on + * spinlocks, even though they are both in 2.6 and are identical. Pretend + * that script lock is a rw_semaphore so we can use the only 2.4 code that + * avoids a deadlock. KAO. */ - write_lock(&script->lock); + if (!down_write_trylock((struct rw_semaphore *)(&script->lock))) + return NULL; spin_lock(&unw.lock); { @@ -1259,8 +1332,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 +1374,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,23 +1412,24 @@ } 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; case UNW_WHERE_FR: if (rval <= 5) - val = unw.preg_index[UNW_REG_F2 + (rval - 1)]; + val = unw.preg_index[UNW_REG_F2 + (rval - 2)]; 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); - if (rval <= 9) - val += struct_offset(struct pt_regs, f6) + 16*(rval - 6); + opc = UNW_INSN_MOVE_SCRATCH; + if (rval <= 11) + val = offsetof(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 +1437,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 = offsetof(struct pt_regs, b0); else if (rval == 6) - val += struct_offset(struct pt_regs, b6); + val = offsetof(struct pt_regs, b6); else - val += struct_offset(struct pt_regs, b7); + val = offsetof(struct pt_regs, b7); } break; @@ -1382,7 +1456,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 +1530,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 +1551,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 +1600,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 @@ -1561,7 +1643,7 @@ && sr.curr.reg[UNW_REG_PSP].val != 0) { /* new psp is sp plus frame size */ insn.opc = UNW_INSN_ADD; - insn.dst = struct_offset(struct unw_frame_info, psp)/8; + insn.dst = offsetof(struct unw_frame_info, psp)/8; insn.val = sr.curr.reg[UNW_REG_PSP].val; /* frame size */ script_emit(script, insn); } @@ -1641,6 +1723,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 +1758,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 @@ -1684,14 +1777,13 @@ lazy_init: off = unw.sw_off[val]; s[val] = (unsigned long) state->sw + off; - if (off >= struct_offset(struct switch_stack, r4) - && off <= struct_offset(struct switch_stack, r7)) + if (off >= offsetof(struct switch_stack, r4) && off <= offsetof(struct switch_stack, r7)) /* * We're initializing a general register: init NaT info, too. Note that * the offset is a multiple of 8 which gives us the 3 bits needed for * the type field. */ - s[val+1] = (struct_offset(struct switch_stack, ar_unat) - off) | UNW_NAT_MEMSTK; + s[val+1] = (offsetof(struct switch_stack, ar_unat) - off) | UNW_NAT_MEMSTK; goto redo; } @@ -1703,7 +1795,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 +1805,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 +1840,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 +1852,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 +1869,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 + offsetof(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 +1888,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; } @@ -1812,6 +1911,7 @@ STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); return retval; } +EXPORT_SYMBOL(unw_unwind); int unw_unwind_to_user (struct unw_frame_info *info) @@ -1821,7 +1921,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 +1933,26 @@ 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; } +EXPORT_SYMBOL(unw_unwind_to_user); -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 +1963,6 @@ rbstop = rbslimit; stklimit = (unsigned long) t + IA64_STK_OFFSET; - stktop = (unsigned long) sw - 16; if (stktop <= rbstop) stktop = rbstop; @@ -1872,15 +1972,58 @@ 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) t, 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; + info->unat_loc = &pt->ar_unat; + info->pfs_loc = &pt->ar_pfs; + 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", + __FUNCTION__, 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", + __FUNCTION__, 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,8 +2031,10 @@ { 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); } +EXPORT_SYMBOL(unw_init_from_blocked_task); static void init_unwind_table (struct unw_table *table, const char *name, unsigned long segment_base, @@ -1915,7 +2060,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 +2091,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 +2111,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 +2164,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; Index: arch/ia64/kernel/unwind_i.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/kernel/unwind_i.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/kernel/unwind_i.h 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/kernel/unwind_i.h 4 Aug 2004 01:25:44 -0000 1.2 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2002 Hewlett-Packard Co + * Copyright (C) 2000, 2002-2003 Hewlett-Packard Co * David Mosberger-Tang * * Kernel unwind support. @@ -45,12 +45,6 @@ /* personality routine and language-specific data follow behind descriptors */ }; -struct unw_table_entry { - u64 start_offset; - u64 end_offset; - u64 info_offset; -}; - struct unw_table { struct unw_table *next; /* must be first member! */ const char *name; @@ -137,7 +131,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 { @@ -147,7 +142,7 @@ }; /* - * Preserved general static registers (r2-r5) give rise to two script + * Preserved general static registers (r4-r7) give rise to two script * instructions; everything else yields at most one instruction; at * the end of the script, the psp gets popped, accounting for one more * instruction. Index: arch/ia64/lib/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/lib/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/lib/Makefile 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/lib/Makefile 4 Aug 2004 01:25:44 -0000 1.2 @@ -18,6 +18,7 @@ obj-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o obj-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o +obj-$(CONFIG_MD_RAID5) += xor.o IGNORE_FLAGS_OBJS = __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o Index: arch/ia64/lib/idiv64.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/lib/idiv64.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/lib/idiv64.S 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/lib/idiv64.S 4 Aug 2004 01:25:44 -0000 1.2 @@ -37,57 +37,44 @@ #define NAME PASTE(PASTE(__,SGN),PASTE(OP,di3)) GLOBAL_ENTRY(NAME) - .prologue .regstk 2,0,0,0 // Transfer inputs to FP registers. setf.sig f8 = in0 setf.sig f9 = in1 ;; - .fframe 16 - .save.f 0x20 - stf.spill [sp] = f17,-16 - // Convert the inputs to FP, to avoid FP software-assist faults. INT_TO_FP(f8, f8) - ;; - - .save.f 0x10 - stf.spill [sp] = f16 - .body INT_TO_FP(f9, f9) ;; - frcpa.s1 f17, p6 = f8, f9 // y0 = frcpa(b) + frcpa.s1 f11, p6 = f8, f9 // y0 = frcpa(b) ;; -(p6) fmpy.s1 f7 = f8, f17 // q0 = a*y0 -(p6) fnma.s1 f6 = f9, f17, f1 // e0 = -b*y0 + 1 +(p6) fmpy.s1 f7 = f8, f11 // q0 = a*y0 +(p6) fnma.s1 f6 = f9, f11, f1 // e0 = -b*y0 + 1 ;; -(p6) fma.s1 f16 = f7, f6, f7 // q1 = q0*e0 + q0 +(p6) fma.s1 f10 = f7, f6, f7 // q1 = q0*e0 + q0 (p6) fmpy.s1 f7 = f6, f6 // e1 = e0*e0 ;; #ifdef MODULO sub in1 = r0, in1 // in1 = -b #endif -(p6) fma.s1 f16 = f16, f7, f16 // q2 = q1*e1 + q1 -(p6) fma.s1 f6 = f17, f6, f17 // y1 = y0*e0 + y0 +(p6) fma.s1 f10 = f10, f7, f10 // q2 = q1*e1 + q1 +(p6) fma.s1 f6 = f11, f6, f11 // y1 = y0*e0 + y0 ;; (p6) fma.s1 f6 = f6, f7, f6 // y2 = y1*e1 + y1 -(p6) fnma.s1 f7 = f9, f16, f8 // r = -b*q2 + a +(p6) fnma.s1 f7 = f9, f10, f8 // r = -b*q2 + a ;; #ifdef MODULO setf.sig f8 = in0 // f8 = a setf.sig f9 = in1 // f9 = -b #endif -(p6) fma.s1 f17 = f7, f6, f16 // q3 = r*y2 + q2 +(p6) fma.s1 f11 = f7, f6, f10 // q3 = r*y2 + q2 ;; - .restore sp - ldf.fill f16 = [sp], 16 - FP_TO_INT(f17, f17) // q = trunc(q3) + FP_TO_INT(f11, f11) // q = trunc(q3) ;; #ifdef MODULO - xma.l f17 = f17, f9, f8 // r = q*(-b) + a + xma.l f11 = f11, f9, f8 // r = q*(-b) + a ;; #endif - getf.sig r8 = f17 // transfer result to result register - ldf.fill f17 = [sp] + getf.sig r8 = f11 // transfer result to result register br.ret.sptk.many rp END(NAME) Index: arch/ia64/lib/memcpy_mck.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/lib/memcpy_mck.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/lib/memcpy_mck.S 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/lib/memcpy_mck.S 4 Aug 2004 01:25:44 -0000 1.2 @@ -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: Index: arch/ia64/lib/memset.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/lib/memset.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/lib/memset.S 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/lib/memset.S 4 Aug 2004 01:25:44 -0000 1.2 @@ -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 Index: arch/ia64/lib/swiotlb.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/lib/swiotlb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/lib/swiotlb.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/lib/swiotlb.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -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); } Index: arch/ia64/mm/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/mm/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/mm/Makefile 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/ia64/mm/Makefile 4 Aug 2004 01:25:44 -0000 1.2 @@ -12,5 +12,8 @@ export-objs := init.o obj-y := init.o fault.o tlb.o extable.o +obj-$(CONFIG_NUMA) += numa.o +obj-$(CONFIG_DISCONTIGMEM) += discontig.o +obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o include $(TOPDIR)/Rules.make Index: arch/ia64/mm/extable.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/mm/extable.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/mm/extable.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/ia64/mm/extable.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -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; } Index: arch/ia64/mm/fault.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/mm/fault.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/mm/fault.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/ia64/mm/fault.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -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; Index: arch/ia64/mm/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/mm/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/mm/init.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/ia64/mm/init.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -16,29 +16,32 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include #include -#include - -mmu_gather_t mmu_gathers[NR_CPUS]; +#include /* References to section boundaries: */ extern char _stext, _etext, _edata, __init_begin, __init_end; extern void ia64_tlb_init (void); +extern int filter_rsvd_memory (unsigned long, unsigned long, void *); +/* Note - may be changed by platform_setup */ unsigned long MAX_DMA_ADDRESS = PAGE_OFFSET + 0x100000000UL; #define LARGE_GAP 0x40000000 /* Use virtual mem map if a hole is > than this */ -static unsigned long totalram_pages; +static unsigned long totalram_pages, reserved_pages; +struct page *zero_page_memmap_ptr; /* map entry for zero page */ unsigned long vmalloc_end = VMALLOC_END_INIT; @@ -63,6 +66,16 @@ return freed; } +inline void +ia64_set_rbs_bot (void) +{ + unsigned long stack_size = current->rlim[RLIMIT_STACK].rlim_max & -16; + + if (stack_size > MAX_USER_STACK_SIZE) + stack_size = MAX_USER_STACK_SIZE; + current->thread.rbs_bot = STACK_TOP - stack_size; +} + /* * This performs some platform-dependent address space initialization. * On IA-64, we want to setup the VM area for the register backing @@ -74,6 +87,8 @@ { struct vm_area_struct *vma; + ia64_set_rbs_bot(); + /* * If we're out of memory and kmem_cache_alloc() returns NULL, we simply ignore * the problem. When the process attempts to write to the register backing store @@ -82,7 +97,7 @@ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (vma) { vma->vm_mm = current->mm; - vma->vm_start = IA64_RBS_BOT; + vma->vm_start = current->thread.rbs_bot & PAGE_MASK; vma->vm_end = vma->vm_start + PAGE_SIZE; vma->vm_page_prot = PAGE_COPY; vma->vm_flags = VM_READ|VM_WRITE|VM_MAYREAD|VM_MAYWRITE|VM_GROWSUP; @@ -110,10 +125,11 @@ void free_initmem (void) { - unsigned long addr; + unsigned long addr, eaddr; - addr = (unsigned long) &__init_begin; - for (; addr < (unsigned long) &__init_end; addr += PAGE_SIZE) { + addr = (unsigned long) ia64_imva(&__init_begin); + eaddr = (unsigned long) ia64_imva(&__init_end); + for (; addr < eaddr; addr += PAGE_SIZE) { clear_bit(PG_reserved, &virt_to_page((void *)addr)->flags); set_page_count(virt_to_page((void *)addr), 1); free_page(addr); @@ -189,58 +205,39 @@ void show_mem(void) { - int i, total = 0, reserved = 0; - int shared = 0, cached = 0; + int i, reserved; + int shared, cached; + pg_data_t *pgdat; + char *tchar = (numnodes > 1) ? "\t" : ""; printk("Mem-info:\n"); show_free_areas(); -#ifdef CONFIG_DISCONTIGMEM - { - pg_data_t *pgdat = pgdat_list; - - printk("Free swap: %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); - do { - printk("Node ID: %d\n", pgdat->node_id); - for(i = 0; i < pgdat->node_size; i++) { - if (PageReserved(pgdat->node_mem_map+i)) - reserved++; - else if (PageSwapCache(pgdat->node_mem_map+i)) - cached++; - else if (page_count(pgdat->node_mem_map + i)) - shared += page_count(pgdat->node_mem_map + i) - 1; - } - printk("\t%d pages of RAM\n", pgdat->node_size); - printk("\t%d reserved pages\n", reserved); - printk("\t%d pages shared\n", shared); - printk("\t%d pages swap cached\n", cached); - pgdat = pgdat->node_next; - } while (pgdat); - printk("Total of %ld pages in page table cache\n", pgtable_cache_size); - show_buffers(); - printk("%d free buffer pages\n", nr_free_buffer_pages()); - } -#else /* !CONFIG_DISCONTIGMEM */ printk("Free swap: %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); - i = max_mapnr; - while (i-- > 0) { - if (!VALID_PAGE(mem_map + i)) - continue; - 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; + for_each_pgdat(pgdat) { + reserved=0; + cached=0; + shared=0; + if (numnodes > 1) + printk("Node ID: %d\n", pgdat->node_id); + for(i = 0; i < pgdat->node_size; i++) { + if (!VALID_PAGE(pgdat->node_mem_map+i)) + continue; + if (PageReserved(pgdat->node_mem_map+i)) + reserved++; + else if (PageSwapCache(pgdat->node_mem_map+i)) + cached++; + else if (page_count(pgdat->node_mem_map + i)) + shared += page_count(pgdat->node_mem_map + i) - 1; + } + printk("%s%ld pages of RAM\n", tchar, pgdat->node_size); + printk("%s%d reserved pages\n", tchar, reserved); + printk("%s%d pages shared\n", tchar, shared); + printk("%s%d pages swap cached\n", tchar, cached); } - 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); - printk("%ld pages in page table cache\n", pgtable_cache_size); + printk("Total of %ld pages in page table cache\n", pgtable_cache_size); show_buffers(); -#endif /* !CONFIG_DISCONTIGMEM */ + printk("%d free buffer pages\n", nr_free_buffer_pages()); } /* @@ -255,7 +252,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()! */ @@ -285,6 +282,10 @@ { unsigned long psr, rid, pta, impl_va_bits; extern void __init tlb_init (void); +#ifdef CONFIG_IA64_MCA + int cpu; +#endif + #ifdef CONFIG_DISABLE_VHPT # define VHPT_ENABLE_BIT 0 #else @@ -355,13 +356,31 @@ ia64_set_pta(pta | (0 << 8) | (vmlpt_bits << 2) | VHPT_ENABLE_BIT); ia64_tlb_init(); + +#ifdef CONFIG_IA64_MCA + cpu = smp_processor_id(); + + /* mca handler uses cr.lid as key to pick the right entry */ + ia64_mca_tlb_list[cpu].cr_lid = ia64_get_lid(); + + /* insert this percpu data information into our list for MCA recovery purposes */ + ia64_mca_tlb_list[cpu].percpu_paddr = pte_val(mk_pte_phys(__pa(my_cpu_data), PAGE_KERNEL)); + /* Also save per-cpu tlb flush recipe for use in physical mode mca handler */ + ia64_mca_tlb_list[cpu].ptce_base = local_cpu_data->ptce_base; + ia64_mca_tlb_list[cpu].ptce_count[0] = local_cpu_data->ptce_count[0]; + ia64_mca_tlb_list[cpu].ptce_count[1] = local_cpu_data->ptce_count[1]; + ia64_mca_tlb_list[cpu].ptce_stride[0] = local_cpu_data->ptce_stride[0]; + ia64_mca_tlb_list[cpu].ptce_stride[1] = local_cpu_data->ptce_stride[1]; +#endif } static int create_mem_map_page_table (u64 start, u64 end, void *arg) { - unsigned long address, start_page, end_page; + unsigned long address, start_page, end_page, next_blk_page; + unsigned long blk_start; struct page *map_start, *map_end; + int node=0; pgd_t *pgd; pmd_t *pmd; pte_t *pte; @@ -374,18 +393,35 @@ start_page = (unsigned long) map_start & PAGE_MASK; end_page = PAGE_ALIGN((unsigned long) map_end); + /* force the first iteration to get node id */ + blk_start = start; + next_blk_page = 0; + for (address = start_page; address < end_page; address += PAGE_SIZE) { + + /* if we went across a node boundary, get new nid */ + if (address >= next_blk_page) { + struct page *map_next_blk; + + node = paddr_to_nid(__pa(blk_start)); + + /* get end addr of this memblk as next blk_start */ + blk_start = (unsigned long) __va(min(end, memblk_endpaddr(__pa(blk_start)))); + map_next_blk = vmem_map + MAP_NR_DENSE(blk_start); + next_blk_page = PAGE_ALIGN((unsigned long) map_next_blk); + } + pgd = pgd_offset_k(address); if (pgd_none(*pgd)) - pgd_populate(&init_mm, pgd, alloc_bootmem_pages(PAGE_SIZE)); + pgd_populate(&init_mm, pgd, alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE)); pmd = pmd_offset(pgd, address); if (pmd_none(*pmd)) - pmd_populate(&init_mm, pmd, alloc_bootmem_pages(PAGE_SIZE)); + pmd_populate(&init_mm, pmd, alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE)); pte = pte_offset(pmd, address); if (pte_none(*pte)) - set_pte(pte, mk_pte_phys(__pa(alloc_bootmem_pages(PAGE_SIZE)), + set_pte(pte, mk_pte_phys(__pa(alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE)), PAGE_KERNEL)); } return 0; @@ -399,6 +435,14 @@ int highmem; }; +struct memmap_count_callback_data { + int node; + unsigned long num_physpages; + unsigned long num_dma_physpages; + unsigned long min_pfn; + unsigned long max_pfn; +} cdata; + static int virtual_memmap_init (u64 start, u64 end, void *arg) { @@ -454,17 +498,7 @@ efi_memmap_walk(virtual_memmap_init, &args); } - return page_to_phys(end); -} - -static int -count_dma_pages (u64 start, u64 end, void *arg) -{ - unsigned long *count = arg; - - if (end <= MAX_DMA_ADDRESS) - *count += (end - start) >> PAGE_SHIFT; - return 0; + return page_to_phys(end-1) + PAGE_SIZE;; } int @@ -472,19 +506,31 @@ { char byte; - return __get_user(byte, (char *) page) == 0; + return (__get_user(byte, (char *) page) == 0) + && (__get_user(byte, (char *) (page + 1) - 1) == 0); } +#define GRANULEROUNDDOWN(n) ((n) & ~(IA64_GRANULE_SIZE-1)) +#define GRANULEROUNDUP(n) (((n)+IA64_GRANULE_SIZE-1) & ~(IA64_GRANULE_SIZE-1)) +#define ORDERROUNDDOWN(n) ((n) & ~((PAGE_SIZE<> PAGE_SHIFT; + start = __pa(start); + end = __pa(end); + if (node == cdata.node) { + cdata.num_physpages += (end - start) >> PAGE_SHIFT; + if (start <= __pa(MAX_DMA_ADDRESS)) + cdata.num_dma_physpages += (min(end, __pa(MAX_DMA_ADDRESS)) - start) >> PAGE_SHIFT; + start = GRANULEROUNDDOWN(__pa(start)); + start = ORDERROUNDDOWN(start); + end = GRANULEROUNDUP(__pa(end)); + cdata.max_pfn = max(cdata.max_pfn, end >> PAGE_SHIFT); + cdata.min_pfn = min(cdata.min_pfn, start >> PAGE_SHIFT); + } return 0; } -#ifndef CONFIG_DISCONTIGMEM static int find_largest_hole(u64 start, u64 end, void *arg) { @@ -498,7 +544,6 @@ last_end = end; return 0; } -#endif /* * Set up the page tables. @@ -509,73 +554,76 @@ unsigned long max_dma; unsigned long zones_size[MAX_NR_ZONES]; unsigned long zholes_size[MAX_NR_ZONES]; -#ifndef CONFIG_DISCONTIGMEM unsigned long max_gap; -#endif + int node; /* initialize mem_map[] */ - memset(zones_size, 0, sizeof(zones_size)); - memset(zholes_size, 0, sizeof(zholes_size)); - - num_physpages = 0; - efi_memmap_walk(count_pages, &num_physpages); - - num_dma_physpages = 0; - efi_memmap_walk(count_dma_pages, &num_dma_physpages); - max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT; - - if (max_low_pfn < max_dma) { - zones_size[ZONE_DMA] = max_low_pfn; - zholes_size[ZONE_DMA] = max_low_pfn - num_dma_physpages; - } else { - zones_size[ZONE_DMA] = max_dma; - zholes_size[ZONE_DMA] = max_dma - num_dma_physpages; - if (num_physpages > num_dma_physpages) { - zones_size[ZONE_NORMAL] = max_low_pfn - max_dma; - zholes_size[ZONE_NORMAL] = (max_low_pfn - max_dma) - - (num_physpages - num_dma_physpages); - } - } - -#ifdef CONFIG_DISCONTIGMEM - free_area_init_node(0, NULL, NULL, zones_size, 0, zholes_size); -#else max_gap = 0; efi_memmap_walk(find_largest_hole, (u64 *)&max_gap); - if (max_gap < LARGE_GAP) { - vmem_map = (struct page *)0; - free_area_init_node(0, NULL, NULL, zones_size, 0, zholes_size); + for (node=0; node < numnodes; node++) { + memset(zones_size, 0, sizeof(zones_size)); + memset(zholes_size, 0, sizeof(zholes_size)); + memset(&cdata, 0, sizeof(cdata)); + + cdata.node = node; + cdata.min_pfn = ~0; + + efi_memmap_walk(filter_rsvd_memory, count_pages); + num_dma_physpages += cdata.num_dma_physpages; + num_physpages += cdata.num_physpages; + + if (cdata.min_pfn >= max_dma) { + zones_size[ZONE_NORMAL] = cdata.max_pfn - cdata.min_pfn; + zholes_size[ZONE_NORMAL] = cdata.max_pfn - cdata.min_pfn - cdata.num_physpages; + } else if (cdata.max_pfn < max_dma) { + zones_size[ZONE_DMA] = cdata.max_pfn - cdata.min_pfn; + zholes_size[ZONE_DMA] = cdata.max_pfn - cdata.min_pfn - cdata.num_dma_physpages; + } else { + zones_size[ZONE_DMA] = max_dma - cdata.min_pfn; + zholes_size[ZONE_DMA] = zones_size[ZONE_DMA] - cdata.num_dma_physpages; + zones_size[ZONE_NORMAL] = cdata.max_pfn - max_dma; + zholes_size[ZONE_NORMAL] = zones_size[ZONE_NORMAL] - (cdata.num_physpages - cdata.num_dma_physpages); + } + + if (numnodes == 1 && max_gap < LARGE_GAP) { + vmem_map = (struct page *)0; + zones_size[ZONE_DMA] += cdata.min_pfn; + zholes_size[ZONE_DMA] += cdata.min_pfn; + free_area_init_core(0, NODE_DATA(node), &mem_map, zones_size, 0, zholes_size, NULL); + } else { + + /* allocate virtual mem_map */ + + if (node == 0) { + unsigned long map_size; + map_size = PAGE_ALIGN(max_low_pfn*sizeof(struct page)); + vmalloc_end -= map_size; + mem_map = vmem_map = (struct page *) vmalloc_end; + efi_memmap_walk(create_mem_map_page_table, 0); + printk(KERN_INFO "Virtual mem_map starts at 0x%p\n", mem_map); + } + + free_area_init_node(node, NODE_DATA(node), vmem_map+cdata.min_pfn, zones_size, + cdata.min_pfn< * * 08/02/00 A. Mallick @@ -16,28 +16,21 @@ #include #include +#include #include #include #include -#include -#define SUPPORTED_PGBITS ( \ - 1 << _PAGE_SIZE_256M | \ - 1 << _PAGE_SIZE_64M | \ - 1 << _PAGE_SIZE_16M | \ - 1 << _PAGE_SIZE_4M | \ - 1 << _PAGE_SIZE_1M | \ - 1 << _PAGE_SIZE_256K | \ - 1 << _PAGE_SIZE_64K | \ - 1 << _PAGE_SIZE_16K | \ - 1 << _PAGE_SIZE_8K | \ - 1 << _PAGE_SIZE_4K ) +static struct { + unsigned long mask; /* mask of supported purge page-sizes */ + unsigned long max_bits; /* log2() of largest supported purge page-size */ +} purge; 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 +41,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 +70,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 (cpu_online(i) && (i != smp_processor_id())) + cpu_data(i)->need_tlb_flush = 1; + local_flush_tlb_all(); } void @@ -141,22 +142,10 @@ } nbits = ia64_fls(size + 0xfff); - if (((1UL << nbits) & SUPPORTED_PGBITS) == 0) { - if (nbits > _PAGE_SIZE_256M) - nbits = _PAGE_SIZE_256M; - else - /* - * Some page sizes are not implemented in the - * IA-64 arch, so if we get asked to clear an - * unsupported page size, round up to the - * nearest page size. Note that we depend on - * the fact that if page size N is not - * implemented, 2*N _is_ implemented. - */ - ++nbits; - if (((1UL << nbits) & SUPPORTED_PGBITS) == 0) - panic("flush_tlb_range: BUG: nbits=%lu\n", nbits); - } + while (unlikely (((1UL << nbits) & purge.mask) == 0) && (nbits < purge.max_bits)) + ++nbits; + if (nbits > purge.max_bits) + nbits = purge.max_bits; start &= ~((1UL << nbits) - 1); # ifdef CONFIG_SMP @@ -177,6 +166,15 @@ ia64_tlb_init (void) { ia64_ptce_info_t ptce_info; + unsigned long tr_pgbits; + long status; + + if ((status = ia64_pal_vm_page_size(&tr_pgbits, &purge.mask)) != 0) { + printk(KERN_ERR "PAL_VM_PAGE_SIZE failed with status=%ld;" + "defaulting to architected purge page-sizes.\n", status); + purge.mask = 0x115557000; + } + purge.max_bits = ia64_fls(purge.mask); ia64_get_ptce(&ptce_info); local_cpu_data->ptce_base = ptce_info.base; Index: arch/ia64/sn/fakeprom/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/fakeprom/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/fakeprom/Makefile 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/fakeprom/Makefile 4 Aug 2004 01:25:44 -0000 1.2 @@ -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 Index: arch/ia64/sn/fakeprom/README =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/fakeprom/README,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/fakeprom/README 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/fakeprom/README 4 Aug 2004 01:25:44 -0000 1.2 @@ -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 Index: arch/ia64/sn/fakeprom/fpmem.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/fakeprom/fpmem.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/fakeprom/fpmem.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/fakeprom/fpmem.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -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,12 +13,62 @@ * 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 */ + +/* + * Sometimes it is useful to build a fake prom with a memmap that matches another + * platform. There are restrictions on how successful you will be, but here + * are the instructions for what I have used in the past & had good luck: + * + * - compile a kernel for the target platform (like zx1) with the following + * set: + * #define EFI_DEBUG 1 # in arch/ia64/kernel/efi.c + * #define SRAT_DEBUG # in drivers/acpi/numa.c + * + * - this causes the kernel to dump the memmap & SRAT during boot. + * + * - copy the console output to a file. + * + * - run the following script with the file as input: + * + * #!/bin/sh + * + * awk ' + * /^mem/ { + * printf "\t{%s, %sUL, %sUL, %sUL},\n", $4, $7, $11, $12 + * } + * /SRAT Memory/ { + * if (srat != 1) print "SRAT" + * srat = 1 + * for (i=1; i<=0;i++) + * printf "%4d |%s|\n", i, $i + * printf "\t{%s, %sUL, %sUL, %sUL},\n", $4, $6, $8, $13 + * } + * BEGIN { + * FS="[ \[\)\(\t:=,-]" + * } ' + * + * - this converts the memmap & SRAT info into C code array initilization statements. + * + * - copy & paste the initialization statements into the arrays below. Look for + * comments "PASTE xxx HERE". In general, on the MEMMAP is present on most other + * systems. If you have an SRAT, you may need to hack the number of nodes in fw-emu. + * Good luck... + * + * - set "#define FAKE_MEMMAP 1 + * + * - When running medusa, make sure you set the node1_memory_config to cover the + * amount of memory that you are going to use. Also note that you can run the + * kernel in "alias" space (starts at phy adr 0). This is kinda tricky, though + */ + + #include #include +#include #include "fpmem.h" /* @@ -53,10 +103,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,12 +124,12 @@ return sn_config->cpus; } -/* For SN1, get the index th nasid */ +/* For SN, get the index th nasid */ int -GetNasid(int index) +GetNasid(int cnode) { - return sn_memmap[index].nasid ; + return sn_memmap[cnode].nasid ; } node_memmap_t @@ -97,6 +144,21 @@ return sn_memmap[cnode].cpuconfig & (1UL<type = type; md->phys_addr = paddr; md->virt_addr = 0; md->num_pages = numbytes >> 12; - md->attribute = EFI_MEMORY_WB; + md->attribute = attr; +} + + +//#define FAKE_MEMMAP 1 +#ifdef FAKE_MEMMAP + +#define OFF 0x3000000000UL +struct { + unsigned long type; + unsigned long attr; + unsigned long start; + unsigned long end; +} mdx[] = { + /* PASTE SRAT HERE */ +}; + +struct srat { + unsigned long start; + unsigned long len; + unsigned long type; + unsigned long pxm; +} srat[] = { + + /* PASTE SRAT HERE */ + +}; + + + +void * +build_memory_srat(struct acpi_table_memory_affinity *ptr) +{ + int i; + int n = sizeof(srat)/sizeof(struct srat); + + for (i=0; iheader.type = ACPI_SRAT_MEMORY_AFFINITY; + ptr->header.length = sizeof(struct acpi_table_memory_affinity); + ptr->proximity_domain = srat[i].pxm; + ptr->base_addr_lo = srat[i].start & 0xffffffff; + ptr->length_lo = srat[i].len & 0xffffffff; + ptr->base_addr_hi = srat[i].start >> 32; + ptr->length_hi = srat[i].len >> 32; + ptr->memory_type = ACPI_ADDRESS_RANGE_MEMORY; + ptr->flags.enabled = 1; + ptr++; + } + return ptr; } int build_efi_memmap(void *md, int mdsize) { + int i; + + for (i=0; iheader.type = ACPI_SRAT_MEMORY_AFFINITY; + ptr->header.length = sizeof(struct acpi_table_memory_affinity); + ptr->proximity_domain = PROXIMITY_DOMAIN(nasid); + ptr->base_addr_lo = 0; + ptr->length_lo = 0; +#if defined(SGI_SN2) + ptr->base_addr_hi = (nasid<<6) | (3<<4); + ptr->length_hi = (MD_BANKSIZE*MD_BANKS_PER_NODE)>>32; +#endif + ptr->memory_type = ACPI_ADDRESS_RANGE_MEMORY; + ptr->flags.enabled = 1; + ptr++; + } + return ptr; +} + + +int +build_efi_memmap(void *md, int mdsize) +{ int numnodes = GetNumNodes() ; int cnode,bank ; int nasid ; node_memmap_t membank_info ; - int bsize; int count = 0 ; long paddr, hole, numbytes; @@ -192,19 +323,10 @@ 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,57 +24,40 @@ #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 */ b0dou :1, /* 3 bank 0 is 2-sided */ - ena0 :1, /* 4 bank 0 enabled */ - r0 :3, /* 5-7 reserved */ + hack0 :4, /* 4-7 bank 0 hack */ b1size :3, /* 8-10 bank 1 size */ b1dou :1, /* 11 bank 1 is 2-sided */ - ena1 :1, /* 12 bank 1 enabled */ - r1 :3, /* 13-15 reserved */ + hack1 :4, /* 12-15 bank 1 hack */ b2size :3, /* 16-18 bank 2 size */ b2dou :1, /* 19 bank 1 is 2-sided */ - ena2 :1, /* 20 bank 2 enabled */ - r2 :3, /* 21-23 reserved */ + hack2 :4, /* 20-23 bank 2 hack */ b3size :3, /* 24-26 bank 3 size */ b3dou :1, /* 27 bank 3 is 2-sided */ - ena3 :1, /* 28 bank 3 enabled */ - r3 :3; /* 29-31 reserved */ + hack3 :4; /* 28-31 bank 3 hack */ } node_memmap_t ; +#define PROXIMITY_DOMAIN(nasid) (((nasid)>>1) & 255) #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) + +#define MAX_SN_NODES 256 +#define MAX_LSAPICS 512 +#define MAX_CPUS_NODE 4 +#define MAX_CPUS (MAX_CPUS_NODE*MAX_SN_NODES) +#define CPUS_PER_FSB 2 +#define CPUS_PER_FSB_MASK (CPUS_PER_FSB-1) +#define MAX_NASID 2048 + #endif +#define FPROM_BUG() do {while (1);} while (0) + typedef struct sn_memmap_s { short nasid ; @@ -89,7 +72,9 @@ sn_memmap_t memmap[1]; /* start of array */ } sn_config_t; +struct acpi_table_memory_affinity; +extern long base_nasid; extern void build_init(unsigned long); extern int build_efi_memmap(void *, int); @@ -97,3 +82,5 @@ extern int GetNumCpus(void); extern int IsCpuPresent(int, int); extern int GetNasid(int); +extern void* build_memory_srat(struct acpi_table_memory_affinity *); +extern void GetLogicalCpu(int, int *, int *); Index: arch/ia64/sn/fakeprom/fprom.lds =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/fakeprom/fprom.lds,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/fakeprom/fprom.lds 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/fakeprom/fprom.lds 4 Aug 2004 01:25:44 -0000 1.2 @@ -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 Index: arch/ia64/sn/fakeprom/fpromasm.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/fakeprom/fpromasm.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/fakeprom/fpromasm.S 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/fakeprom/fpromasm.S 4 Aug 2004 01:25:44 -0000 1.2 @@ -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 @@ -258,9 +253,10 @@ // Note: should verify that the interrupt we got was really the ap_wakeup // interrupt but this should not be an issue on medusa slave: - nop.i 0x8beef // Medusa - put cpu to sleep til interrupt occurs mov r8=cr.irr0;; // Check for interrupt pending. cmp.eq p6,p0=r8,r0 + ;; +(p6) nop.i 0x8beef // Medusa - put cpu to sleep til interrupt occurs (p6) br.cond.sptk slave;; mov r8=cr.ivr;; // Got one. Must read ivr to accept it @@ -324,10 +320,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 @@ -369,6 +362,13 @@ st8 [r3]=r2 ;; +1: cmp.eq p6,p7=34,r28 /* PAL_VM_PAGE_SIZE */ +(p7) br.cond.sptk.few 1f + movl r8=0 /* status = 0 */ + movl r9=0x015557000 /* insertable page sizes */ + movl r10=0x115557000 /* purgeable page sizes */ + movl r11=0 + 1: cmp.eq p6,p7=19,r28 /* PAL_RSE_INFO */ (p7) br.cond.sptk.few 1f movl r8=0 /* status = 0 */ Index: arch/ia64/sn/fakeprom/fw-emu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/fakeprom/fw-emu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/fakeprom/fw-emu.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/fakeprom/fw-emu.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -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,11 +42,13 @@ #include #include #include -#ifdef CONFIG_IA64_SGI_SN2 +#ifdef SGI_SN2 #include #include #endif #include +#include +#include #include "fpmem.h" #define RSDP_NAME "RSDP" @@ -66,14 +68,12 @@ #define BOOT_SIG "BOOT" /* Boot table */ #define ACPI_SRAT_REVISION 1 #define ACPI_SLIT_REVISION 1 +#define ACPI_FADT_REVISION 3 +#define ACPI_DSDT_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 #define MB (1024*1024UL) @@ -84,27 +84,13 @@ #define ABS(i) ((i) > 0 ? (i) : -(i)) #define ALIGN8(p) (((long)(p) +7) & ~7) -#define FPROM_BUG() do {while (1);} while (0) -#define MAX_SN_NODES 128 -#define MAX_LSAPICS 512 -#define MAX_CPUS 512 -#define MAX_CPUS_NODE 4 -#define CPUS_PER_NODE 4 -#define CPUS_PER_FSB 2 -#define CPUS_PER_FSB_MASK (CPUS_PER_FSB-1) - #define NUM_EFI_DESCS 2 #define RSDP_CHECKSUM_LENGTH 20 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 +110,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 @@ -136,11 +120,10 @@ */ long base_nasid; long num_cpus; -long bsp_entry_pc=0; +long bsp_entry_pc; long num_nodes; -long app_entry_pc; -int bsp_lid; func_ptr_t ap_entry; +char nasid_present[MAX_NASID]; extern void pal_emulator(void); @@ -151,8 +134,11 @@ + sizeof(struct ia64_sal_systab) + sizeof(struct ia64_sal_desc_entry_point) + sizeof(struct ia64_sal_desc_ap_wakeup) + + sizeof(struct ia64_sal_desc_platform_feature) + sizeof(struct acpi20_table_rsdp) + sizeof(struct acpi_table_xsdt) + + sizeof(struct acpi_table_header) /* dummy DSDT */ + + sizeof(struct fadt_descriptor_rev2) + sizeof(struct acpi_table_slit) + MAX_SN_NODES*MAX_SN_NODES+8 + sizeof(struct acpi_table_madt) @@ -207,7 +193,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) @@ -252,7 +238,11 @@ if (index == SAL_FREQ_BASE) { switch (in1) { case SAL_FREQ_BASE_PLATFORM: - r9 = 500000000; + /* slow down the clock on large systems to reduce the interrupt rate */ + if (num_cpus < 32) + r9 = 500000000UL; + else + r9 = 5000000000UL; break; case SAL_FREQ_BASE_INTERVAL_TIMER: @@ -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(); @@ -456,7 +446,7 @@ } int -nasid_present(int nasid) +is_nasid_present(int nasid) { int cnode; for (cnode=0; cnodehdr.signature = EFI_SYSTEM_TABLE_SIGNATURE; @@ -610,7 +598,9 @@ acpi_xsdt->entry[0] = __fwtab_pa(base_nasid, acpi_madt); acpi_xsdt->entry[1] = __fwtab_pa(base_nasid, acpi_slit); acpi_xsdt->entry[2] = __fwtab_pa(base_nasid, acpi_srat); - acpi_checksum(&acpi_xsdt->header, sizeof(struct acpi_table_xsdt) + 16); + acpi_xsdt->entry[3] = __fwtab_pa(base_nasid, acpi_fadt); + acpi_xsdt->entry[4] = __fwtab_pa(base_nasid, acpi_dsdt); + acpi_checksum(&acpi_xsdt->header, sizeof(struct acpi_table_xsdt) + 32); /* Set up the APIC table */ acpi_table_initx(&acpi_madt->header, APIC_SIG, 4, 1, 1); @@ -624,12 +614,9 @@ 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); + lsapic20->id = (cpu<<4) | (nasid>>8); #endif lsapic20 = (struct acpi_table_lsapic*) ((long)lsapic20+sizeof(struct acpi_table_lsapic)); } @@ -639,26 +626,10 @@ /* Set up the SRAT table */ acpi_table_initx(&acpi_srat->header, SRAT_SIG, 4, ACPI_SRAT_REVISION, 1); ptr = acpi_srat+1; - for (cnode=0; cnodeheader.type = ACPI_SRAT_MEMORY_AFFINITY; - srat_memory_affinity->header.length = sizeof(struct acpi_table_memory_affinity); - 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 - srat_memory_affinity->base_addr_hi = (nasid<<6) | (3<<4); - srat_memory_affinity->length_hi = SN2_NODE_SIZE>>32; -#endif - srat_memory_affinity->memory_type = ACPI_ADDRESS_RANGE_MEMORY; - srat_memory_affinity->flags.enabled = 1; - } + ptr = build_memory_srat(ptr); + + /* Build processor SRAT */ for (cnode=0; cnodeheader.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); + srat_cpu_affinity->apic_id = (cpu<<4) | (nasid>>8); #endif } } acpi_checksum(&acpi_srat->header, (char*)ptr - (char*)acpi_srat); + acpi_table_initx(acpi_dsdt, DSDT_SIG, 4, ACPI_DSDT_REVISION, 1); + acpi_checksum(acpi_dsdt, sizeof(*acpi_dsdt)); + + /* Set up the FADT table */ + acpi_table_initx((struct acpi_table_header *)&acpi_fadt->header, FADT_SIG, 4, ACPI_FADT_REVISION, 1); + /* + * We don't have legacy PC keyboard support etc. + */ + acpi_fadt->iapc_boot_arch = 0; + acpi_fadt->Xdsdt = (u64)__fwtab_pa(base_nasid, acpi_dsdt); + acpi_checksum((struct acpi_table_header *)&acpi_fadt->header, + sizeof(*acpi_fadt)); /* Set up the SLIT table */ acpi_table_initx(&acpi_slit->header, SLIT_SIG, 4, ACPI_SLIT_REVISION, 1); @@ -689,8 +669,10 @@ memset(cp, 255, acpi_slit->localities*acpi_slit->localities); for (i=0; i<=max_nasid; i++) + nasid_present[i] = is_nasid_present(i); + for (i=0; i<=max_nasid; i++) for (j=0; j<=max_nasid; j++) - if (nasid_present(i) && nasid_present(j)) + if (nasid_present[i] && nasid_present[j]) *(cp+PROXIMITY_DOMAIN(i)*acpi_slit->localities+PROXIMITY_DOMAIN(j)) = 10 + MIN(254, 5*ABS(i-j)); cp = acpi_slit->entry + acpi_slit->localities*acpi_slit->localities; @@ -702,12 +684,12 @@ sal_systab->size = sizeof(*sal_systab); sal_systab->sal_rev_minor = 1; sal_systab->sal_rev_major = 0; - sal_systab->entry_count = 3; + sal_systab->entry_count = 4; sal_systab->sal_b_rev_major = 0x1; /* set the SN SAL rev to */ 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; @@ -751,6 +733,10 @@ sal_apwake->mechanism = IA64_SAL_AP_EXTERNAL_INT; sal_apwake->vector = 18; + /* Setup the SAL feature descriptor */ + sal_feature->type = SAL_DESC_PLATFORM_FEATURE; + sal_feature->feature_mask = IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT; + for (checksum=0, cp=(char*)sal_systab; cp < (char *)efi_memmap; ++cp) checksum += *cp; sal_systab->checksum = -checksum; @@ -775,24 +761,4 @@ bp->console_info.orig_x = 0; bp->console_info.orig_y = 24; bp->fpswa = 0; - - /* - * Now pick the BSP & store it LID value in - * a global variable. Note if BSP is greater than last cpu, - * pick the last cpu. - */ - for (cnode=0; cnode 0) - continue; - return; - } - } } Index: arch/ia64/sn/fakeprom/klgraph_init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/fakeprom/klgraph_init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/fakeprom/klgraph_init.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/fakeprom/klgraph_init.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -1,10 +1,10 @@ -/* $Id: klgraph_init.c,v 1.1 2004/07/22 19:49:10 joff Exp $ +/* $Id: klgraph_init.c,v 1.2 2004/08/04 01:25:44 joff 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) 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); } - Index: arch/ia64/sn/fakeprom/main.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/fakeprom/main.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/fakeprom/main.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/fakeprom/main.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -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. */ @@ -12,106 +12,60 @@ #include #include #include +#include +#include "fpmem.h" extern void klgraph_init(void); -void bedrock_init(int); -void synergy_init(int, int); -void sys_fw_init (const char *args, int arglen, int bsp); - -volatile int bootmaster=0; /* Used to pick bootmaster */ -volatile int nasidmaster[128]={0}; /* Used to pick node/synergy masters */ -int init_done=0; -extern int bsp_lid; - -#define get_bit(b,p) (((*p)>>(b))&1) +void sys_fw_init (const char *args, int arglen); int fmain(int lid, int bsp) { - int syn, nasid, cpu; + int nasid, cpu, mynasid, mycpu, bootmaster; /* - * First lets figure out who we are. This is done from the - * LID passed to us. + * * Pass the parameter base address to the build_efi_xxx routines. */ - -#ifdef CONFIG_IA64_SGI_SN1 - nasid = (lid>>24); - syn = (lid>>17)&1; - cpu = (lid>>16)&1; +#if defined(SGI_SN2) + build_init(0x3000000000UL | ((long)base_nasid<<38)); +#endif /* - * Now pick a synergy master to initialize synergy registers. + * First lets figure out who we are. This is done from the + * LID passed to us. */ - 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 - + mynasid = (lid>>16)&0xfff; + mycpu = (lid>>28)&3; + /* - * Now pick a nasid master to initialize Bedrock registers. + * Determine if THIS cpu is the bootmaster. The parameter + * is the logical cpu of the bootmaster. Cpus are numbered + * low-to-high nasid/lid. */ - if (test_and_set_bit(8, &nasidmaster[nasid]) == 0) { - bedrock_init(nasid); - test_and_set_bit(9, &nasidmaster[nasid]); - } else - while (get_bit(9, &nasidmaster[nasid]) == 0); + GetLogicalCpu(bsp, &nasid, &cpu); + bootmaster = (mynasid == nasid) && (mycpu == cpu); - /* - * Now pick a BSP & finish init. + * Initialize SAL & EFI tables. + * Note: non-bootmaster cpus will return to the slave loop + * in fpromasm.S. They spin there until they receive an + * external interrupt from the master cpu. */ - if (test_and_set_bit(0, &bootmaster) == 0) { - sys_fw_init(0, 0, bsp); - test_and_set_bit(1, &bootmaster); - } else - while (get_bit(1, &bootmaster) == 0); - - return (lid == bsp_lid); -} - - -void -bedrock_init(int nasid) -{ - nasid = nasid; /* to quiet gcc */ + if (bootmaster) { #if 0 - /* - * Undef if you need fprom to generate a 1 node klgraph - * information .. only works for 1 node for nasid 0. - */ - klgraph_init(); + /* + * Undef if you need fprom to generate a 1 node klgraph + * information .. only works for 1 node for nasid 0. + */ + klgraph_init(); #endif -} - - -void -synergy_init(int nasid, int syn) -{ - long *base; - long off; - - /* - * Enable all FSB flashed interrupts. - * I'd really like defines for this...... - */ - base = (long*)0x80000e0000000000LL; /* base of synergy regs */ - for (off = 0x2a0; off < 0x2e0; off+=8) /* offset for VEC_MASK_{0-3}_A/B */ - *(base+off/8) = -1LL; + sys_fw_init(0, 0); + } - /* - * Set the NASID in the FSB_CONFIG register. - */ - base = (long*)0x80000e0000000450LL; - *base = (long)((nasid<<16)|(syn<<9)); + return (bootmaster); } + /* Why isnt there a bcopy/memcpy in lib64.a */ void* Index: arch/ia64/sn/fakeprom/runsim =================================================================== RCS file: arch/ia64/sn/fakeprom/runsim diff -N arch/ia64/sn/fakeprom/runsim --- arch/ia64/sn/fakeprom/runsim 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: arch/ia64/sn/io/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/Makefile 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/ia64/sn/io/Makefile 4 Aug 2004 01:21:33 -0000 1.2 @@ -3,31 +3,35 @@ # 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 +export-objs := snia_if.o + +obj-y := sgi_if.o xswitch.o cdl.o io.o snia_if.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-y += sn2 machvec drivers platform_init -subdir-$(CONFIG_IA64_SGI_SN1) += sn1 -subdir-$(CONFIG_IA64_SGI_SN2) += sn2 +ifdef CONFIG_HWGFS_FS +subdir-$(CONFIG_HWGFS_FS) += hwgfs +else +subdir-$(CONFIG_DEVFS_FS) += hwgdfs +endif include $(TOPDIR)/Rules.make Index: arch/ia64/sn/io/alenlist.c =================================================================== RCS file: arch/ia64/sn/io/alenlist.c diff -N arch/ia64/sn/io/alenlist.c --- arch/ia64/sn/io/alenlist.c 22 Jul 2004 19:49:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,899 +0,0 @@ -/* $Id: alenlist.c,v 1.1 2004/07/22 19:49:09 joff 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. - */ - -/* 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 */ Index: arch/ia64/sn/io/ate_utils.c =================================================================== RCS file: arch/ia64/sn/io/ate_utils.c diff -N arch/ia64/sn/io/ate_utils.c --- arch/ia64/sn/io/ate_utils.c 22 Jul 2004 19:49:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,205 +0,0 @@ -/* $Id: ate_utils.c,v 1.1 2004/07/22 19:49:09 joff 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)); */ -} Index: arch/ia64/sn/io/cdl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/cdl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/cdl.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/ia64/sn/io/cdl.c 4 Aug 2004 01:21:33 -0000 1.2 @@ -1,10 +1,10 @@ -/* $Id: cdl.c,v 1.1 2004/07/22 19:49:09 joff Exp $ +/* $Id: cdl.c,v 1.2 2004/08/04 01:21:33 joff 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) 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; -} - Index: arch/ia64/sn/io/eeprom.c =================================================================== RCS file: arch/ia64/sn/io/eeprom.c diff -N arch/ia64/sn/io/eeprom.c --- arch/ia64/sn/io/eeprom.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; - } -} Index: arch/ia64/sn/io/efi-rtc.c =================================================================== RCS file: arch/ia64/sn/io/efi-rtc.c diff -N arch/ia64/sn/io/efi-rtc.c --- arch/ia64/sn/io/efi-rtc.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); Index: arch/ia64/sn/io/hcl.c =================================================================== RCS file: arch/ia64/sn/io/hcl.c diff -N arch/ia64/sn/io/hcl.c --- arch/ia64/sn/io/hcl.c 22 Jul 2004 19:49:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1531 +0,0 @@ -/* $Id: hcl.c,v 1.1 2004/07/22 19:49:09 joff 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. - * - * 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); Index: arch/ia64/sn/io/hcl_util.c =================================================================== RCS file: arch/ia64/sn/io/hcl_util.c diff -N arch/ia64/sn/io/hcl_util.c --- arch/ia64/sn/io/hcl_util.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,200 +0,0 @@ -/* $Id: hcl_util.c,v 1.1 2004/07/22 19:49:10 joff 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 - -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)); -} - - Index: arch/ia64/sn/io/hubdev.c =================================================================== RCS file: arch/ia64/sn/io/hubdev.c diff -N arch/ia64/sn/io/hubdev.c --- arch/ia64/sn/io/hubdev.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,132 +0,0 @@ -/* $Id: hubdev.c,v 1.1 2004/07/22 19:49:10 joff 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 - -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 */ Index: arch/ia64/sn/io/hubspc.c =================================================================== RCS file: arch/ia64/sn/io/hubspc.c diff -N arch/ia64/sn/io/hubspc.c --- arch/ia64/sn/io/hubspc.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,251 +0,0 @@ -/* $Id: hubspc.c,v 1.1 2004/07/22 19:49:10 joff 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. - */ - -/* - * 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); - -} Index: arch/ia64/sn/io/ifconfig_bus.c =================================================================== RCS file: arch/ia64/sn/io/ifconfig_bus.c diff -N arch/ia64/sn/io/ifconfig_bus.c --- arch/ia64/sn/io/ifconfig_bus.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,345 +0,0 @@ -/* $Id: ifconfig_bus.c,v 1.1 2004/07/22 19:49:10 joff 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_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); - -} Index: arch/ia64/sn/io/ifconfig_net.c =================================================================== RCS file: arch/ia64/sn/io/ifconfig_net.c diff -N arch/ia64/sn/io/ifconfig_net.c --- arch/ia64/sn/io/ifconfig_net.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,298 +0,0 @@ -/* $Id: ifconfig_net.c,v 1.1 2004/07/22 19:49:10 joff 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); - -} Index: arch/ia64/sn/io/invent.c =================================================================== RCS file: arch/ia64/sn/io/invent.c diff -N arch/ia64/sn/io/invent.c --- arch/ia64/sn/io/invent.c 22 Jul 2004 19:49:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,224 +0,0 @@ -/* $Id: invent.c,v 1.1 2004/07/22 19:49:09 joff 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. - */ - -/* - * 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); -} Index: arch/ia64/sn/io/io.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/io.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/io.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/ia64/sn/io/io.c 4 Aug 2004 01:21:33 -0000 1.2 @@ -1,10 +1,10 @@ -/* $Id: io.c,v 1.1 2004/07/22 19:49:09 joff Exp $ +/* $Id: io.c,v 1.2 2004/08/04 01:21:33 joff 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) 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; @@ -92,7 +86,7 @@ } hub_set_piomode(nasid, HUB_PIO_CONVEYOR); - mutex_spinlock_init(&hubinfo->h_bwlock); + spin_lock_init(&hubinfo->h_bwlock); /* * If this lock can be acquired from interrupts or bh's, add SV_INTS or SV_BHS, * respectively, to the flags here. @@ -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,13 +117,12 @@ { 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; nasid_t nasid; volatile hubreg_t junk; - unsigned long s; caddr_t kvaddr; #ifdef PIOMAP_UNC_ACC_SPACE uint64_t addr; @@ -177,7 +170,7 @@ */ tryagain: free_bw_index = -1; - s = mutex_spinlock(&hubinfo->h_bwlock); + spin_lock(&hubinfo->h_bwlock); for (bigwin=0; bigwin < HUB_NUM_BIG_WINDOW; bigwin++) { bw_piomap = hubinfo_bwin_piomap_get(hubinfo, bigwin); @@ -197,7 +190,7 @@ if ( xtalk_addr == bw_piomap->hpio_xtalk_info.xp_xtalk_addr && widget == bw_piomap->hpio_xtalk_info.xp_target) { bw_piomap->hpio_holdcnt++; - mutex_spinunlock(&hubinfo->h_bwlock, s); + spin_unlock(&hubinfo->h_bwlock); return(bw_piomap); } } @@ -271,7 +264,7 @@ bw_piomap->hpio_flags |= HUB_PIOMAP_IS_VALID; done: - mutex_spinunlock(&hubinfo->h_bwlock, s); + spin_unlock(&hubinfo->h_bwlock); return(bw_piomap); } @@ -288,10 +281,9 @@ 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; /* * Small windows are permanently mapped to corresponding widgets, @@ -307,7 +299,7 @@ hubinfo_get(hubv, &hubinfo); nasid = hubinfo->h_nasid; - s = mutex_spinlock(&hubinfo->h_bwlock); + spin_lock(&hubinfo->h_bwlock); /* * If this is the last hold on this mapping, free it. @@ -325,7 +317,7 @@ (void)sv_signal(&hubinfo->h_bwwait); } - mutex_spinunlock(&hubinfo->h_bwlock, s); + spin_unlock(&hubinfo->h_bwlock); } /* @@ -371,7 +363,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 +371,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 +408,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 +416,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; @@ -446,7 +438,7 @@ hub_dmamap_free(hub_dmamap_t hub_dmamap) { hub_dmamap->hdma_flags &= ~HUB_DMAMAP_IS_VALID; - kern_free(hub_dmamap); + kfree(hub_dmamap); } /* @@ -460,31 +452,23 @@ 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); if (dmamap->hdma_flags & HUB_DMAMAP_USED) { /* If the map is FIXED, re-use is OK. */ if (!(dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) { + char name[MAXDEVNAME]; vhdl = dmamap->hdma_xtalk_info.xd_dev; -#if defined(SUPPORT_PRINTING_V_FORMAT) - printk(KERN_WARNING "%v: hub_dmamap_addr re-uses dmamap.\n",vhdl); -#else - printk(KERN_WARNING "%p: hub_dmamap_addr re-uses dmamap.\n", (void *)vhdl); -#endif + printk(KERN_WARNING "%s: hub_dmamap_addr re-uses dmamap.\n", vertex_to_name(vhdl, name, MAXDEVNAME)); } } else { dmamap->hdma_flags |= HUB_DMAMAP_USED; } /* 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,19 +482,16 @@ 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); if (hub_dmamap->hdma_flags & HUB_DMAMAP_USED) { /* If the map is FIXED, re-use is OK. */ if (!(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) { + char name[MAXDEVNAME]; vhdl = hub_dmamap->hdma_xtalk_info.xd_dev; -#if defined(SUPPORT_PRINTING_V_FORMAT) - printk(KERN_WARNING "%v: hub_dmamap_list re-uses dmamap\n",vhdl); -#else - printk(KERN_WARNING "%p: hub_dmamap_list re-uses dmamap\n", (void *)vhdl); -#endif + printk(KERN_WARNING "%s: hub_dmamap_list re-uses dmamap\n", vertex_to_name(vhdl, name, MAXDEVNAME)); } } else { hub_dmamap->hdma_flags |= HUB_DMAMAP_USED; @@ -527,19 +508,16 @@ 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; } else { /* If the map is FIXED, re-done is OK. */ if (!(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) { + char name[MAXDEVNAME]; vhdl = hub_dmamap->hdma_xtalk_info.xd_dev; -#if defined(SUPPORT_PRINTING_V_FORMAT) - printk(KERN_WARNING "%v: hub_dmamap_done already done with dmamap\n",vhdl); -#else - printk(KERN_WARNING "%p: hub_dmamap_done already done with dmamap\n", (void *)vhdl); -#endif + printk(KERN_WARNING "%s: hub_dmamap_done already done with dmamap\n", vertex_to_name(vhdl, name, MAXDEVNAME)); } } } @@ -549,18 +527,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 +543,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 +562,7 @@ /*ARGSUSED*/ void -hub_dmaaddr_drain( devfs_handle_t vhdl, +hub_dmaaddr_drain( vertex_hdl_t vhdl, paddr_t addr, size_t bytes) { @@ -598,13 +571,25 @@ /*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 */ } +int +hub_dma_enabled(vertex_hdl_t xconn_vhdl) +{ + return(0); +} + +int +hub_error_devenable(vertex_hdl_t xconn_vhdl, int devnum, int error_code) +{ + return(0); +} + /* CONFIGURATION MANAGEMENT */ @@ -612,10 +597,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 +607,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 +649,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 +659,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 +717,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 +748,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 +775,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,9 +804,84 @@ (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, }; +/* + * per_ice_init + * + * This code is executed once for each Ice chip. + */ +void +per_ice_init(cnodeid_t cnode) +{ + + /* Initialize error interrupts for this ice. */ + printk("per_ice_init: We need to init ice here ....!\n"); + /* ice_error_init(cnode); */ + +} +/* + * 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); +} + + Index: arch/ia64/sn/io/klconflib.c =================================================================== RCS file: arch/ia64/sn/io/klconflib.c diff -N arch/ia64/sn/io/klconflib.c --- arch/ia64/sn/io/klconflib.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1046 +0,0 @@ -/* $Id: klconflib.c,v 1.1 2004/07/22 19:49:10 joff 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 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 */ - - Index: arch/ia64/sn/io/klgraph.c =================================================================== RCS file: arch/ia64/sn/io/klgraph.c diff -N arch/ia64/sn/io/klgraph.c --- arch/ia64/sn/io/klgraph.c 22 Jul 2004 19:49:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,795 +0,0 @@ -/* $Id: klgraph.c,v 1.1 2004/07/22 19:49:09 joff 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. - */ - -/* - * 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(); - -} Index: arch/ia64/sn/io/klgraph_hack.c =================================================================== RCS file: arch/ia64/sn/io/klgraph_hack.c diff -N arch/ia64/sn/io/klgraph_hack.c --- arch/ia64/sn/io/klgraph_hack.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,341 +0,0 @@ -/* $Id: klgraph_hack.c,v 1.1 2004/07/22 19:49:10 joff 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. - */ - - -/* - * 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 */ Index: arch/ia64/sn/io/l1.c =================================================================== RCS file: arch/ia64/sn/io/l1.c diff -N arch/ia64/sn/io/l1.c --- arch/ia64/sn/io/l1.c 22 Jul 2004 19:49:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,3143 +0,0 @@ -/* $Id: l1.c,v 1.1 2004/07/22 19:49:09 joff 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 - -#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 */ Index: arch/ia64/sn/io/l1_command.c =================================================================== RCS file: arch/ia64/sn/io/l1_command.c diff -N arch/ia64/sn/io/l1_command.c --- arch/ia64/sn/io/l1_command.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1378 +0,0 @@ -/* $Id: l1_command.c,v 1.1 2004/07/22 19:49:10 joff 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 - 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; -} Index: arch/ia64/sn/io/labelcl.c =================================================================== RCS file: arch/ia64/sn/io/labelcl.c diff -N arch/ia64/sn/io/labelcl.c --- arch/ia64/sn/io/labelcl.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); -} Index: arch/ia64/sn/io/ml_SN_init.c =================================================================== RCS file: arch/ia64/sn/io/ml_SN_init.c diff -N arch/ia64/sn/io/ml_SN_init.c --- arch/ia64/sn/io/ml_SN_init.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,235 +0,0 @@ -/* $Id: ml_SN_init.c,v 1.1 2004/07/22 19:49:10 joff 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 - -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; - } -} Index: arch/ia64/sn/io/ml_iograph.c =================================================================== RCS file: arch/ia64/sn/io/ml_iograph.c diff -N arch/ia64/sn/io/ml_iograph.c --- arch/ia64/sn/io/ml_iograph.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1570 +0,0 @@ -/* $Id: ml_iograph.c,v 1.1 2004/07/22 19:49:10 joff 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 -#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)); - -} Index: arch/ia64/sn/io/module.c =================================================================== RCS file: arch/ia64/sn/io/module.c diff -N arch/ia64/sn/io/module.c --- arch/ia64/sn/io/module.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,312 +0,0 @@ -/* $Id: module.c,v 1.1 2004/07/22 19:49:10 joff 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 - - -/* #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; -} Index: arch/ia64/sn/io/pci.c =================================================================== RCS file: arch/ia64/sn/io/pci.c diff -N arch/ia64/sn/io/pci.c --- arch/ia64/sn/io/pci.c 22 Jul 2004 19:49:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 */ Index: arch/ia64/sn/io/pci_bus_cvlink.c =================================================================== RCS file: arch/ia64/sn/io/pci_bus_cvlink.c diff -N arch/ia64/sn/io/pci_bus_cvlink.c --- arch/ia64/sn/io/pci_bus_cvlink.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,743 +0,0 @@ -/* $Id: pci_bus_cvlink.c,v 1.1 2004/07/22 19:49:10 joff 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 -#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); -} Index: arch/ia64/sn/io/pci_dma.c =================================================================== RCS file: arch/ia64/sn/io/pci_dma.c diff -N arch/ia64/sn/io/pci_dma.c --- arch/ia64/sn/io/pci_dma.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); - Index: arch/ia64/sn/io/pciba.c =================================================================== RCS file: arch/ia64/sn/io/pciba.c diff -N arch/ia64/sn/io/pciba.c --- arch/ia64/sn/io/pciba.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); -} Index: arch/ia64/sn/io/pciio.c =================================================================== RCS file: arch/ia64/sn/io/pciio.c diff -N arch/ia64/sn/io/pciio.c --- arch/ia64/sn/io/pciio.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1511 +0,0 @@ -/* $Id: pciio.c,v 1.1 2004/07/22 19:49:10 joff 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 -#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)); -} - Index: arch/ia64/sn/io/sgi_if.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sgi_if.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sgi_if.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sgi_if.c 4 Aug 2004 01:21:33 -0000 1.2 @@ -1,10 +1,10 @@ -/* $Id: sgi_if.c,v 1.1 2004/07/22 19:49:10 joff Exp $ +/* $Id: sgi_if.c,v 1.2 2004/08/04 01:21:33 joff 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) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -20,14 +20,12 @@ #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) +snia_kmem_zalloc(size_t size) { void *ptr = kmalloc(size, GFP_KERNEL); if ( ptr ) - BZERO(ptr, size); + memset(ptr, 0, size); return(ptr); } @@ -37,100 +35,16 @@ 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 .. */ void * -snia_kmem_alloc_node(register size_t size, register int flags, cnodeid_t node) +snia_kmem_alloc_node(register size_t size, cnodeid_t node) { /* someday will Allocate on node 'node' */ return(kmalloc(size, GFP_KERNEL)); } -void * -snia_kmem_zalloc_node(register size_t size, register int flags, cnodeid_t node) -{ - void *ptr = kmalloc(size, GFP_KERNEL); - if ( ptr ) - BZERO(ptr, size); - return(ptr); -} - - -#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 Index: arch/ia64/sn/io/sgi_io_init.c =================================================================== RCS file: arch/ia64/sn/io/sgi_io_init.c diff -N arch/ia64/sn/io/sgi_io_init.c --- arch/ia64/sn/io/sgi_io_init.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,336 +0,0 @@ -/* $Id: sgi_io_init.c,v 1.1 2004/07/22 19:49:10 joff 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 - -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 - -} Index: arch/ia64/sn/io/sgi_io_sim.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sgi_io_sim.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sgi_io_sim.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sgi_io_sim.c 4 Aug 2004 01:21:33 -0000 1.2 @@ -1,10 +1,10 @@ -/* $Id: sgi_io_sim.c,v 1.1 2004/07/22 19:49:10 joff Exp $ +/* $Id: sgi_io_sim.c,v 1.2 2004/08/04 01:21:33 joff 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) 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"); - -} Index: arch/ia64/sn/io/stubs.c =================================================================== RCS file: arch/ia64/sn/io/stubs.c diff -N arch/ia64/sn/io/stubs.c --- arch/ia64/sn/io/stubs.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,139 +0,0 @@ -/* $Id: stubs.c,v 1.1 2004/07/22 19:49:10 joff 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 - -/****** - ****** 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); -} Index: arch/ia64/sn/io/xbow.c =================================================================== RCS file: arch/ia64/sn/io/xbow.c diff -N arch/ia64/sn/io/xbow.c --- arch/ia64/sn/io/xbow.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1325 +0,0 @@ -/* $Id: xbow.c,v 1.1 2004/07/22 19:49:10 joff 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-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); -} Index: arch/ia64/sn/io/xswitch.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/xswitch.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/xswitch.c 22 Jul 2004 19:49:09 -0000 1.1 +++ arch/ia64/sn/io/xswitch.c 4 Aug 2004 01:21:33 -0000 1.2 @@ -1,10 +1,10 @@ -/* $Id: xswitch.c,v 1.1 2004/07/22 19:49:09 joff Exp $ +/* $Id: xswitch.c,v 1.2 2004/08/04 01:21:33 joff 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) 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); -} Index: arch/ia64/sn/io/xtalk.c =================================================================== RCS file: arch/ia64/sn/io/xtalk.c diff -N arch/ia64/sn/io/xtalk.c --- arch/ia64/sn/io/xtalk.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1024 +0,0 @@ -/* $Id: xtalk.c,v 1.1 2004/07/22 19:49:10 joff 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-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); -} Index: arch/ia64/sn/io/sn1/Makefile =================================================================== RCS file: arch/ia64/sn/io/sn1/Makefile diff -N arch/ia64/sn/io/sn1/Makefile --- arch/ia64/sn/io/sn1/Makefile 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: arch/ia64/sn/io/sn1/eeprom.c =================================================================== RCS file: arch/ia64/sn/io/sn1/eeprom.c diff -N arch/ia64/sn/io/sn1/eeprom.c --- arch/ia64/sn/io/sn1/eeprom.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; - } -} Index: arch/ia64/sn/io/sn1/efi-rtc.c =================================================================== RCS file: arch/ia64/sn/io/sn1/efi-rtc.c diff -N arch/ia64/sn/io/sn1/efi-rtc.c --- arch/ia64/sn/io/sn1/efi-rtc.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); Index: arch/ia64/sn/io/sn1/hub_intr.c =================================================================== RCS file: arch/ia64/sn/io/sn1/hub_intr.c diff -N arch/ia64/sn/io/sn1/hub_intr.c --- arch/ia64/sn/io/sn1/hub_intr.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,307 +0,0 @@ -/* $Id: hub_intr.c,v 1.1 2004/07/22 19:49:10 joff 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)); -} Index: arch/ia64/sn/io/sn1/hubcounters.c =================================================================== RCS file: arch/ia64/sn/io/sn1/hubcounters.c diff -N arch/ia64/sn/io/sn1/hubcounters.c --- arch/ia64/sn/io/sn1/hubcounters.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,282 +0,0 @@ -/* $Id: hubcounters.c,v 1.1 2004/07/22 19:49:10 joff 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; -} Index: arch/ia64/sn/io/sn1/huberror.c =================================================================== RCS file: arch/ia64/sn/io/sn1/huberror.c diff -N arch/ia64/sn/io/sn1/huberror.c --- arch/ia64/sn/io/sn1/huberror.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,228 +0,0 @@ -/* $Id: huberror.c,v 1.1 2004/07/22 19:49:10 joff 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"); -} Index: arch/ia64/sn/io/sn1/ip37.c =================================================================== RCS file: arch/ia64/sn/io/sn1/ip37.c diff -N arch/ia64/sn/io/sn1/ip37.c --- arch/ia64/sn/io/sn1/ip37.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); -} Index: arch/ia64/sn/io/sn1/klconflib.c =================================================================== RCS file: arch/ia64/sn/io/sn1/klconflib.c diff -N arch/ia64/sn/io/sn1/klconflib.c --- arch/ia64/sn/io/sn1/klconflib.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,979 +0,0 @@ -/* $Id: klconflib.c,v 1.1 2004/07/22 19:49:10 joff 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 - -#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; -} - Index: arch/ia64/sn/io/sn1/klgraph.c =================================================================== RCS file: arch/ia64/sn/io/sn1/klgraph.c diff -N arch/ia64/sn/io/sn1/klgraph.c --- arch/ia64/sn/io/sn1/klgraph.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,940 +0,0 @@ -/* $Id: klgraph.c,v 1.1 2004/07/22 19:49:10 joff 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. - */ - -/* - * 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(); - -} Index: arch/ia64/sn/io/sn1/l1.c =================================================================== RCS file: arch/ia64/sn/io/sn1/l1.c diff -N arch/ia64/sn/io/sn1/l1.c --- arch/ia64/sn/io/sn1/l1.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,3124 +0,0 @@ -/* $Id: l1.c,v 1.1 2004/07/22 19:49:10 joff 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 */ Index: arch/ia64/sn/io/sn1/l1_command.c =================================================================== RCS file: arch/ia64/sn/io/sn1/l1_command.c diff -N arch/ia64/sn/io/sn1/l1_command.c --- arch/ia64/sn/io/sn1/l1_command.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1409 +0,0 @@ -/* $Id: l1_command.c,v 1.1 2004/07/22 19:49:10 joff 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; -} Index: arch/ia64/sn/io/sn1/mem_refcnt.c =================================================================== RCS file: arch/ia64/sn/io/sn1/mem_refcnt.c diff -N arch/ia64/sn/io/sn1/mem_refcnt.c --- arch/ia64/sn/io/sn1/mem_refcnt.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,220 +0,0 @@ -/* $Id: mem_refcnt.c,v 1.1 2004/07/22 19:49:10 joff 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; -} Index: arch/ia64/sn/io/sn1/ml_SN_init.c =================================================================== RCS file: arch/ia64/sn/io/sn1/ml_SN_init.c diff -N arch/ia64/sn/io/sn1/ml_SN_init.c --- arch/ia64/sn/io/sn1/ml_SN_init.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,211 +0,0 @@ -/* $Id: ml_SN_init.c,v 1.1 2004/07/22 19:49:10 joff 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 - -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; - } -} Index: arch/ia64/sn/io/sn1/ml_SN_intr.c =================================================================== RCS file: arch/ia64/sn/io/sn1/ml_SN_intr.c diff -N arch/ia64/sn/io/sn1/ml_SN_intr.c --- arch/ia64/sn/io/sn1/ml_SN_intr.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1154 +0,0 @@ -/* $Id: ml_SN_intr.c,v 1.1 2004/07/22 19:49:10 joff 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"); - } - } -} - Index: arch/ia64/sn/io/sn1/ml_iograph.c =================================================================== RCS file: arch/ia64/sn/io/sn1/ml_iograph.c diff -N arch/ia64/sn/io/sn1/ml_iograph.c --- arch/ia64/sn/io/sn1/ml_iograph.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1505 +0,0 @@ -/* $Id: ml_iograph.c,v 1.1 2004/07/22 19:49:10 joff 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 - -/* #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)); - -} Index: arch/ia64/sn/io/sn1/module.c =================================================================== RCS file: arch/ia64/sn/io/sn1/module.c diff -N arch/ia64/sn/io/sn1/module.c --- arch/ia64/sn/io/sn1/module.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,311 +0,0 @@ -/* $Id: module.c,v 1.1 2004/07/22 19:49:10 joff 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 - - -/* #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; -} Index: arch/ia64/sn/io/sn1/pci_bus_cvlink.c =================================================================== RCS file: arch/ia64/sn/io/sn1/pci_bus_cvlink.c diff -N arch/ia64/sn/io/sn1/pci_bus_cvlink.c --- arch/ia64/sn/io/sn1/pci_bus_cvlink.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,696 +0,0 @@ -/* $Id: pci_bus_cvlink.c,v 1.1 2004/07/22 19:49:10 joff 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 -#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); -} Index: arch/ia64/sn/io/sn1/pcibr.c =================================================================== RCS file: arch/ia64/sn/io/sn1/pcibr.c diff -N arch/ia64/sn/io/sn1/pcibr.c --- arch/ia64/sn/io/sn1/pcibr.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); -} Index: arch/ia64/sn/io/sn1/pciio.c =================================================================== RCS file: arch/ia64/sn/io/sn1/pciio.c diff -N arch/ia64/sn/io/sn1/pciio.c --- arch/ia64/sn/io/sn1/pciio.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1681 +0,0 @@ -/* $Id: pciio.c,v 1.1 2004/07/22 19:49:10 joff 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)); -} - Index: arch/ia64/sn/io/sn1/sgi_io_init.c =================================================================== RCS file: arch/ia64/sn/io/sn1/sgi_io_init.c diff -N arch/ia64/sn/io/sn1/sgi_io_init.c --- arch/ia64/sn/io/sn1/sgi_io_init.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,324 +0,0 @@ -/* $Id: sgi_io_init.c,v 1.1 2004/07/22 19:49:10 joff 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 - -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(); - -} Index: arch/ia64/sn/io/sn1/xbow.c =================================================================== RCS file: arch/ia64/sn/io/sn1/xbow.c diff -N arch/ia64/sn/io/sn1/xbow.c --- arch/ia64/sn/io/sn1/xbow.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1086 +0,0 @@ -/* $Id: xbow.c,v 1.1 2004/07/22 19:49:10 joff 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); -} Index: arch/ia64/sn/io/sn1/xtalk.c =================================================================== RCS file: arch/ia64/sn/io/sn1/xtalk.c diff -N arch/ia64/sn/io/sn1/xtalk.c --- arch/ia64/sn/io/sn1/xtalk.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1003 +0,0 @@ -/* $Id: xtalk.c,v 1.1 2004/07/22 19:49:10 joff 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)); -} Index: arch/ia64/sn/io/sn2/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/Makefile 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/Makefile 4 Aug 2004 01:21:34 -0000 1.2 @@ -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. @@ -11,17 +11,14 @@ O_TARGET := snio.o -export-objs := pciio.o - 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 ioc4/ioc4_if.o -subdir-y += pcibr +obj-$(CONFIG_KDB) += kdba_io.o -obj-$(CONFIG_SHUB_1_0_SPECIFIC) += efi-rtc.o +subdir-y += pcibr ioc4 include $(TOPDIR)/Rules.make Index: arch/ia64/sn/io/sn2/bte_error.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/bte_error.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/bte_error.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/bte_error.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -1,10 +1,35 @@ -/* $Id: bte_error.c,v 1.1 2004/07/22 19:49:10 joff 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); +} Index: arch/ia64/sn/io/sn2/efi-rtc.c =================================================================== RCS file: arch/ia64/sn/io/sn2/efi-rtc.c diff -N arch/ia64/sn/io/sn2/efi-rtc.c --- arch/ia64/sn/io/sn2/efi-rtc.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); Index: arch/ia64/sn/io/sn2/geo_op.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/geo_op.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/geo_op.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/geo_op.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -1,10 +1,10 @@ -/* $Id: geo_op.c,v 1.1 2004/07/22 19:49:10 joff Exp $ +/* $Id: geo_op.c,v 1.2 2004/08/04 01:21:34 joff 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) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. */ /* Index: arch/ia64/sn/io/sn2/klconflib.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/klconflib.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/klconflib.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/klconflib.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -1,10 +1,10 @@ -/* $Id: klconflib.c,v 1.1 2004/07/22 19:49:10 joff Exp $ +/* $Id: klconflib.c,v 1.2 2004/08/04 01:21:34 joff 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) 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%#=vo2345"; 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,22 @@ 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_OPUSBRICK) + board_name = EDGE_LBL_OPUSBRICK; + else if (brd->brd_type == KLTYPE_CGBRICK) + board_name = EDGE_LBL_CGBRICK; else board_name = EDGE_LBL_IOBRICK; break; @@ -360,23 +295,6 @@ sprintf(path, EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d/%s", buffer, geo_slab(brd->brd_geoid), board_name); } -/* - * 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 geo_module(brd->brd_geoid); -} - - #define MHZ 1000000 @@ -486,7 +404,13 @@ strcpy(serial_number,""); switch(KLCLASS(board->brd_type)) { case KLCLASS_CPU: { /* Node board */ - klhub_t *hub; + klhub_t *hub; + + if (board->brd_type == KLTYPE_TIO) { + printk("*****board_serial_number_get: Need to support TIO.*****\n"); + strcpy(serial_number,""); + return(0); + } /* Get the hub component information */ hub = (klhub_t *)find_first_component(board, @@ -623,185 +547,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 +559,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) { Index: arch/ia64/sn/io/sn2/klgraph.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/klgraph.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/klgraph.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/klgraph.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -1,10 +1,10 @@ -/* $Id: klgraph.c,v 1.1 2004/07/22 19:49:10 joff Exp $ +/* $Id: klgraph.c,v 1.2 2004/08/04 01:21:34 joff 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) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. */ /* @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -42,7 +41,8 @@ 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); +extern int is_specified(char *); /* @@ -55,7 +55,7 @@ { invent_generic_t *invent; - invent = kern_malloc(size); + invent = kmalloc(size, GFP_KERNEL); if (!invent) return NULL; invent->ig_module = NODE_MODULEID(cnode); @@ -69,7 +69,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 +118,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 +153,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 +177,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,16 +206,46 @@ /* ARGSUSED */ void -klhwg_add_hub(devfs_handle_t node_vertex, klhub_t *hub, cnodeid_t cnode) +klhwg_add_ice(vertex_hdl_t node_vertex, klhub_t *hub, cnodeid_t cnode) +{ + vertex_hdl_t myicev; + vertex_hdl_t ice_mon; + int rc; + extern struct file_operations shub_mon_fops; + + (void) hwgraph_path_add(node_vertex, EDGE_LBL_ICE, &myicev); + + HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, myicev, NULL, "Created path for ice vertex for TIO node.\n")); + + rc = device_master_set(myicev, node_vertex); + if (rc) + panic("klhwg_add_ice: Unable to create ice vertex.\n"); + + ice_mon = hwgraph_register(myicev, EDGE_LBL_PERFMON, + 0, DEVFS_FL_AUTO_DEVNUM, + 0, 0, + S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, + &shub_mon_fops, (void *)(long)cnode); +} + +/* ARGSUSED */ +void +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; GRPRINTF(("klhwg_add_hub: adding %s\n", EDGE_LBL_HUB)); (void) hwgraph_path_add(node_vertex, EDGE_LBL_HUB, &myhubv); + + HWGRAPH_DEBUG((__FILE__, __FUNCTION__,__LINE__, myhubv, NULL, "Created path for hub vertex for Shub node.\n")); + rc = device_master_set(myhubv, node_vertex); + if (rc) + panic("klhwg_add_hub: Unable to create hub vertex.\n"); + hub_mon = hwgraph_register(myhubv, EDGE_LBL_PERFMON, 0, DEVFS_FL_AUTO_DEVNUM, 0, 0, @@ -234,9 +255,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; @@ -247,6 +268,8 @@ 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); + HWGRAPH_DEBUG((__FILE__, __FUNCTION__,__LINE__, my_cpu, NULL, "Created path for disabled cpu slice.\n")); + mark_cpuvertex_as_cpu(my_cpu, cpu_id); device_master_set(my_cpu, node_vertex); @@ -257,9 +280,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; @@ -274,6 +297,9 @@ GRPRINTF(("klhwg_add_cpu: adding %s to vertex 0x%p\n", name, node_vertex)); (void) hwgraph_path_add(node_vertex, name, &my_cpu); + + HWGRAPH_DEBUG((__FILE__, __FUNCTION__,__LINE__, my_cpu, NULL, "Created path for active cpu slice.\n")); + mark_cpuvertex_as_cpu(my_cpu, cpu_id); device_master_set(my_cpu, node_vertex); @@ -281,6 +307,7 @@ 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); + HWGRAPH_DEBUG((__FILE__, __FUNCTION__,__LINE__, cpu_dir, my_cpu, "Created % from vhdl1 to vhdl2.\n", name)); } klhwg_cpu_invent_info(my_cpu, cnode, cpu); @@ -288,6 +315,41 @@ void +klhwg_add_coretalk(cnodeid_t cnode, nasid_t tio_nasid) +{ + lboard_t *brd; + vertex_hdl_t coretalk_v, icev; + /*REFERENCED*/ + graph_error_t err; + + if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(tio_nasid), KLTYPE_IOBRICK_XBOW)) == NULL) + return; + + if (KL_CONFIG_DUPLICATE_BOARD(brd)) + return; + + icev = cnodeid_to_vertex(cnode); + + err = hwgraph_path_add(icev, EDGE_LBL_CORETALK, &coretalk_v); + if (err != GRAPH_SUCCESS) { + if (err == GRAPH_DUP) + printk(KERN_WARNING "klhwg_add_coretalk: Check for " + "working routers and router links!"); + + panic("klhwg_add_coretalkk: Failed to add " + "edge: vertex 0x%p to vertex 0x%p," + "error %d\n", + (void *)icev, (void *)coretalk_v, err); + } + + HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, coretalk_v, NULL, "Created coretalk path for TIO node.\n")); + + NODEPDA(cnode)->xbow_vhdl = coretalk_v; + +} + + +void klhwg_add_xbow(cnodeid_t cnode, nasid_t nasid) { lboard_t *brd; @@ -295,7 +357,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; @@ -305,9 +367,6 @@ 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; @@ -336,11 +395,14 @@ printk(KERN_WARNING "klhwg_add_xbow: Check for " "working routers and router links!"); - PRINT_PANIC("klhwg_add_xbow: Failed to add " + panic("klhwg_add_xbow: Failed to add " "edge: vertex 0x%p to vertex 0x%p," "error %d\n", (void *)hubv, (void *)xbow_v, err); } + + HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, xbow_v, NULL, "Created path for xtalk.\n")); + xswitch_vertex_init(xbow_v); NODEPDA(hub_cnode)->xbow_vhdl = xbow_v; @@ -355,20 +417,77 @@ hub_nasid; } - GRPRINTF(("klhwg_add_xbow: adding port nasid %d %s to vertex 0x%p\n", - hub_nasid, EDGE_LBL_XTALK, hubv)); } } /* ARGSUSED */ void -klhwg_add_node(devfs_handle_t hwgraph_root, cnodeid_t cnode, gda_t *gdap) +klhwg_add_tionode(vertex_hdl_t hwgraph_root, cnodeid_t cnode) +{ + nasid_t tio_nasid; + lboard_t *brd; + klhub_t *hub; + vertex_hdl_t node_vertex = NULL; + char path_buffer[100]; + int rv; + char *s; + int board_disabled = 0; + + tio_nasid = COMPACT_TO_NASID_NODEID(cnode); + brd = find_lboard((lboard_t *)KL_CONFIG_INFO(tio_nasid), KLTYPE_TIO); + ASSERT(brd); + + /* Generate a hardware graph path for this board. */ + board_to_path(brd, path_buffer); + rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex); + if (rv != GRAPH_SUCCESS) + panic("TIO Node vertex creation failed. " + "Path == %s", path_buffer); + + HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, node_vertex, NULL, "Created path for TIO node.\n")); + 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 * numionodes); + + 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)->geoid = brd->brd_geoid; + NODEPDA(cnode)->module = module_lookup(geo_module(brd->brd_geoid)); + } + + if(!board_disabled) + klhwg_add_ice(node_vertex, hub, cnode); + +} + + +/* ARGSUSED */ +void +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; @@ -377,25 +496,18 @@ 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; + vertex_hdl_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); + panic("Node vertex creation failed. Path == %s", path_buffer); + HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, node_vertex, NULL, "Created path for SHUB node.\n")); hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB); ASSERT(hub); if(hub->hub_info.flags & KLINFO_ENABLE) @@ -437,13 +549,15 @@ rv = hwgraph_path_add(node_vertex, EDGE_LBL_CPU, &cpu_dir); if (rv != GRAPH_SUCCESS) panic("klhwg_add_node: Cannot create CPU directory\n"); + HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, cpu_dir, NULL, "Created cpu directiry on SHUB node.\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)) + 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,84 +580,65 @@ /* 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; 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_geoid)); /* 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 " + panic("Router vertex creation " "failed. Path == %s", path_buffer); - GRPRINTF(("klhwg_add_all_routers: get next board from 0x%p\n", - brd)); + HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, node_vertex, NULL, "Created router path.\n")); + /* 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, +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; - 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; } @@ -560,7 +655,7 @@ /* 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", + panic("klhwg_connect_one_router: %d cmpts on router\n", brd->brd_numcompts); return; } @@ -594,15 +689,12 @@ 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); + 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, @@ -611,15 +703,17 @@ } if (rc != GRAPH_SUCCESS && !is_specified(arg_maxnodes)) - PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p error 0x%x\n", + panic("Can't create edge: %s/%s to vertex 0x%p error 0x%x\n", path_buffer, dest_path, (void *)dest_hndl, rc); + + HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, router_hndl, dest_hndl, "Created edge %s from vhdl1 to vhdl2.\n", dest_path)); } } void -klhwg_connect_routers(devfs_handle_t hwgraph_root) +klhwg_connect_routers(vertex_hdl_t hwgraph_root) { nasid_t nasid; cnodeid_t cnode; @@ -652,28 +746,30 @@ 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; int port; - for (cnode = 0; cnode < numnodes; cnode++) { + for (cnode = 0; cnode < numionodes; 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); + if (!(nasid & 1)) { + brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA); + ASSERT(brd); + } else { + brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_TIO); + ASSERT(brd); + } hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB); ASSERT(hub); @@ -690,10 +786,7 @@ /* 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); @@ -709,7 +802,7 @@ 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); + panic("Can't find board: %s", dest_path); } else { char buf[1024]; @@ -718,13 +811,18 @@ path_buffer, dest_path)); rc = hwgraph_path_add(hub_hndl, EDGE_LBL_INTERCONNECT, &hub_hndl); + + HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, hub_hndl, NULL, "Created link path.\n")); + sprintf(buf,"%s/%s",path_buffer,EDGE_LBL_INTERCONNECT); rc = hwgraph_traverse(hwgraph_root, buf, &hub_hndl); sprintf(buf,"%d",port); rc = hwgraph_edge_add(hub_hndl, dest_hndl, buf); + HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, hub_hndl, dest_hndl, "Created edge %s from vhdl1 to vhdl2.\n", buf)); + if (rc != GRAPH_SUCCESS) - PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n", + panic("Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n", path_buffer, dest_path, (void *)dest_hndl, rc); } @@ -796,12 +894,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]; @@ -816,7 +914,8 @@ rc = hwgraph_path_add(hwgraph_root, name, &module_vhdl); ASSERT(rc == GRAPH_SUCCESS); - rc = rc; + rc = rc; /* Shut the compiler up */ + HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, module_vhdl, NULL, "Created module path.\n")); hwgraph_fastinfo_set(module_vhdl, (arbitrary_info_t) modules[cm]); @@ -826,29 +925,38 @@ buffer); rc = hwgraph_path_add(hwgraph_root, name, &vhdl); - ASSERT_ALWAYS(rc == GRAPH_SUCCESS); - rc = rc; + ASSERT_ALWAYS(rc == GRAPH_SUCCESS); + rc = rc; /* Shut the compiler up */ + HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, vhdl, NULL, "Created L1 path.\n")); hwgraph_info_add_LBL(vhdl, INFO_LBL_ELSC, - (arbitrary_info_t) (__psint_t) 1); + (arbitrary_info_t) (int64_t) 1); } } 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 = numnodes; cnode < numionodes; cnode++) { + klhwg_add_tionode(hwgraph_root, cnode); } for (cnode = 0; cnode < numnodes; cnode++) { klhwg_add_xbow(cnode, cnodeid_to_nasid(cnode)); } + for (cnode = numnodes; cnode < numionodes; cnode++) { + klhwg_add_coretalk(cnode, cnodeid_to_nasid(cnode)); + } + /* * As for router hardware inventory information, we set this * up in router.c. Index: arch/ia64/sn/io/sn2/l1.c =================================================================== RCS file: arch/ia64/sn/io/sn2/l1.c diff -N arch/ia64/sn/io/sn2/l1.c --- arch/ia64/sn/io/sn2/l1.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,239 +0,0 @@ -/* $Id: l1.c,v 1.1 2004/07/22 19:49:10 joff 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 - - -#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)); -} Index: arch/ia64/sn/io/sn2/l1_command.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/l1_command.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/l1_command.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/l1_command.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -1,10 +1,10 @@ -/* $Id: l1_command.c,v 1.1 2004/07/22 19:49:10 joff Exp $ +/* $Id: l1_command.c,v 1.2 2004/08/04 01:21:34 joff 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) 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,23 @@ 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; - *brick_type = toupper(*brick_type); - + *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; 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,12 +107,20 @@ 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_OPUS: + brick_type = MODULE_OPUSBRICK; 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; + case L1_BRICKTYPE_CHI_CG: + brick_type = MODULE_CGBRICK; break; } ret = RBT_TO_MODULE(rack, bay, brick_type); @@ -167,8 +152,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 +164,48 @@ { 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"); + + case L1_BRICKTYPE_X: + return(EDGE_LBL_XBRICK); - 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_I: + return(EDGE_LBL_IBRICK); - io_moduleid = peer_iobrick_module_get(sc, rack, bay); + case L1_BRICKTYPE_P: + return(EDGE_LBL_PBRICK); + + case L1_BRICKTYPE_PX: + return(EDGE_LBL_PXBRICK); + + case L1_BRICKTYPE_OPUS: + return(EDGE_LBL_OPUSBRICK); + + case L1_BRICKTYPE_IX: + return(EDGE_LBL_IXBRICK); + + case L1_BRICKTYPE_C: + return("Cbrick"); + + case L1_BRICKTYPE_R: + return("Rbrick"); + + case L1_BRICKTYPE_CHI_CG: + return(EDGE_LBL_CGBRICK); } -#endif /* PIC_LATER */ - io_moduleid = iobrick_module_get(nasid); - return io_moduleid; } + Index: arch/ia64/sn/io/sn2/ml_SN_init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/ml_SN_init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/ml_SN_init.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/ml_SN_init.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -1,10 +1,10 @@ -/* $Id: ml_SN_init.c,v 1.1 2004/07/22 19:49:10 joff Exp $ +/* $Id: ml_SN_init.c,v 1.2 2004/08/04 01:21:34 joff 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) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -19,68 +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 */ -nasid_t master_baseio_nasid = INVALID_NASID; /* This is the master base I/O nasid */ - - -/* - * mlreset(void) - * 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) -{ - /* - * 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(); -} - - /* XXX - Move the meat of this to intr.c ? */ /* * Set up the platform-dependent fields in the nodepda. @@ -99,11 +43,9 @@ 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; /* @@ -120,17 +62,22 @@ npda->npda_rip_last = &npda->npda_rip_first; npda->geoid.any.type = GEO_TYPE_INVALID; - mutex_init_locked(&npda->xbow_sema); /* init it locked? */ + init_MUTEX_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 +init_platform_hubinfo(nodepda_t **nodepdaindr) { + cnodeid_t cnode; + hubinfo_t hubinfo; + nodepda_t *npda; + + for (cnode = 0; cnode < numionodes; cnode++) { + npda = nodepdaindr[cnode]; + hubinfo = (hubinfo_t)npda->pdinfo; + hubinfo->h_nasid = COMPACT_TO_NASID_NODEID(cnode); + /* For TIO the following returns -1 */ + hubinfo->h_widgetid = hub_widget_id(hubinfo->h_nasid); + } } void Index: arch/ia64/sn/io/sn2/ml_SN_intr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/ml_SN_intr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/ml_SN_intr.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/ml_SN_intr.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -1,10 +1,10 @@ -/* $Id: ml_SN_intr.c,v 1.1 2004/07/22 19:49:10 joff Exp $ +/* $Id: ml_SN_intr.c,v 1.2 2004/08/04 01:21:34 joff 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) 1992-1997, 2000-2003 Silicon Graphics, Inc. All Rights Reserved. */ /* @@ -13,7 +13,7 @@ * handle interrupts on an IPXX board. */ -#ident "$Revision: 1.1 $" +#ident "$Revision: 1.2 $" #include #include @@ -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 = cpu; + 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,20 +352,21 @@ // 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; + static cnodeid_t last_node = 0; /* SN2 + pcibr addressing limitation */ /* Due to this limitation, all interrupts from a given bridge must go to the name node.*/ @@ -397,8 +414,9 @@ 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", + return CPU_NONE; + } else { + printk("Cannot target interrupt to closest node (0x%x) 0x%p\n", master_node_get(dev), (void *)owner_dev); } @@ -406,9 +424,10 @@ // Do a stupid round-robin assignment of the node. { - static cnodeid_t last_node = -1; + int i; + if (last_node >= numnodes) last_node = 0; - for (candidate_node = last_node + 1; candidate_node != last_node; candidate_node++) { + for (i = 0, candidate_node = last_node; i < numnodes; candidate_node++,i++) { if (candidate_node == numnodes) candidate_node = 0; cpuid = intr_bit_reserve_test(CPU_NONE, 0, @@ -419,6 +438,7 @@ name, resp_bit); if (cpuid != CPU_NONE) { + last_node = candidate_node + 1; return cpuid; } } Index: arch/ia64/sn/io/sn2/ml_iograph.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/ml_iograph.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/ml_iograph.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/ml_iograph.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -1,10 +1,10 @@ -/* $Id: ml_iograph.c,v 1.1 2004/07/22 19:49:10 joff Exp $ +/* $Id: ml_iograph.c,v 1.2 2004/08/04 01:21:34 joff 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) 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, @@ -52,20 +49,20 @@ * xswitch vertex is created. */ typedef struct xswitch_vol_s { - mutex_t xswitch_volunteer_mutex; + struct semaphore 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; - extern void * snia_kmem_zalloc(size_t size, int flag); - xvolinfo = snia_kmem_zalloc(sizeof(struct xswitch_vol_s), GFP_KERNEL); - mutex_init(&xvolinfo->xswitch_volunteer_mutex); + xvolinfo = snia_kmem_zalloc(sizeof(struct xswitch_vol_s)); + init_MUTEX(&xvolinfo->xswitch_volunteer_mutex); rc = hwgraph_info_add_LBL(xswitch, INFO_LBL_XSWITCH_VOL, (arbitrary_info_t)xvolinfo); @@ -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, @@ -111,7 +108,7 @@ return; } - mutex_lock(&xvolinfo->xswitch_volunteer_mutex); + down(&xvolinfo->xswitch_volunteer_mutex); ASSERT(xvolinfo->xswitch_volunteer_count < NUM_XSWITCH_VOLUNTEER); xvolinfo->xswitch_volunteer[xvolinfo->xswitch_volunteer_count] = master; xvolinfo->xswitch_volunteer_count++; @@ -129,7 +126,7 @@ xvolinfo->xswitch_volunteer[1] = hubv; } } - mutex_unlock(&xvolinfo->xswitch_volunteer_mutex); + up(&xvolinfo->xswitch_volunteer_mutex); } extern int xbow_port_io_enabled(nasid_t nasid, int widgetnum); @@ -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; @@ -196,16 +193,16 @@ * hub that owned it in the prom. */ if (is_master_baseio_nasid_widget(nasid, widgetnum)) { - extern nasid_t get_master_baseio_nasid(void); + extern nasid_t snia_get_master_baseio_nasid(void); for (i=0; ixswitch_volunteer[i]; hubinfo_get(hubv, &hubinfo); nasid = hubinfo->h_nasid; - if (nasid == get_master_baseio_nasid()) + if (nasid == snia_get_master_baseio_nasid()) goto do_assignment; } - PRINT_PANIC("Nasid == %d, console nasid == %d", - nasid, get_master_baseio_nasid()); + panic("Nasid == %d, console nasid == %d", + nasid, snia_get_master_baseio_nasid()); } /* @@ -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; } } @@ -252,46 +237,12 @@ } /* - * 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) +io_init_done(cnodeid_t cnodeid,cpuid_t c) { /* Let boot processor know that we're done. */ } @@ -307,7 +258,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 +302,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 +325,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,12 +377,13 @@ char name[4]; lboard_t dummy; + /* * 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) { + + if (xswitch_info_master_assignment_get(xswitch_info, widgetnum) != hubv) { return; } @@ -470,12 +421,17 @@ 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_CGBRICK) ? EDGE_LBL_CGBRICK : + (board->brd_type == KLTYPE_OPUSBRICK) ? EDGE_LBL_OPUSBRICK : + (board->brd_type == KLTYPE_XBRICK) ? EDGE_LBL_XBRICK : "?brick", EDGE_LBL_XTALK, widgetnum); DBG("io_xswitch_widget_init: path= %s\n", pathname); @@ -514,37 +470,49 @@ 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 ( isupper(MODULE_GET_BTCHAR(io_module)) ) { + bt = tolower(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)); + DBG("io_xswitch_widget_init: FROM path '%s'\n", pathname); + from = hwgraph_path_to_vertex(pathname); ASSERT_ALWAYS(from); - sprintf(pathname, "/dev/hw/" EDGE_LBL_MODULE "/%s/" - EDGE_LBL_SLAB "/%d/" - "%cbrick", - buffer, geo_slab(board->brd_geoid), bt); + sprintf(pathname, EDGE_LBL_HW "/" EDGE_LBL_MODULE "/%s/" + EDGE_LBL_SLAB "/%d/" + "%s", + buffer, geo_slab(board->brd_geoid), brick_name); + DBG("io_xswitch_widget_init: TO path '%s'\n", pathname); to = hwgraph_path_to_vertex(pathname); ASSERT_ALWAYS(to); rc = hwgraph_edge_add(from, to, @@ -566,26 +534,15 @@ 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); - for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; - widgetnum++) { - io_xswitch_widget_init(xswitchv, - cnodeid_to_vertex(cnode), - widgetnum, aa); + for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) { + io_xswitch_widget_init(xswitchv, cnodeid_to_vertex(cnode), widgetnum); } - /* - * Wait for parallel attach threads, if any, to complete. - */ - async_attach_waitall(aa); - async_attach_free(aa); } /* @@ -595,11 +552,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 +595,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 +616,14 @@ 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); + cpuid_t c = 0; npdap = NODEPDA(cnodeid); @@ -693,23 +639,6 @@ 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 */ @@ -833,7 +762,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 @@ -854,12 +783,15 @@ * 5) Initialize all xwidgets on the xswitch */ + DBG("call volunteer_for_widgets\n"); + 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; + DBG("call volunteer_for_widgets again\n"); volunteer_for_widgets(switchv, peer_npdap->node_vertex); } @@ -867,13 +799,13 @@ /* Signal that we're done */ if (peer_sema) { - mutex_unlock(peer_sema); + up(peer_sema); } } else { /* Wait 'til master is done assigning widgets. */ - mutex_lock(&npdap->xbow_sema); + down(&npdap->xbow_sema); } #ifdef PROBE_TEST @@ -915,231 +847,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 +878,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 @@ -1227,7 +930,7 @@ else DBG("none found!\n"); - DELAY(15000000); + udelay(15000000); //prom_reboot(); panic("FIXME: devnamefromarcs: should call prom_reboot here.\n"); /* NOTREACHED */ @@ -1300,6 +1003,34 @@ } }, +/* OPUSbrick widget number to PCI bus number map */ + { MODULE_OPUSBRICK, /* OPUSbrick type */ + /* PCI Bus # Widget # */ + { 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0 - 0x7 */ + 0, /* 0x8 */ + 0, /* 0x9 */ + 0, 0, /* 0xa - 0xb */ + 0, /* 0xc */ + 0, /* 0xd */ + 0, /* 0xe */ + 1 /* 0xf */ + } + }, + +/* 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 # */ @@ -1312,6 +1043,19 @@ 0, /* 0xe */ 0 /* 0xf */ } + }, +/* CG brick widget number to PCI bus number map */ + { MODULE_CGBRICK, /* CG brick */ + /* PCI Bus # Widget # */ + { 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0 - 0x7 */ + 0, /* 0x8 */ + 0, /* 0x9 */ + 0, 1, /* 0xa - 0xb */ + 0, /* 0xc */ + 0, /* 0xd */ + 0, /* 0xe */ + 0 /* 0xf */ + } } }; @@ -1335,61 +1079,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)); - -} Index: arch/ia64/sn/io/sn2/module.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/module.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/module.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/module.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -1,10 +1,10 @@ -/* $Id: module.c,v 1.1 2004/07/22 19:49:10 joff Exp $ +/* $Id: module.c,v 1.2 2004/08/04 01:21:34 joff 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) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -129,21 +128,26 @@ int i; char buffer[16]; moduleid_t moduleid; + slabid_t slab_number; memset(buffer, 0, 16); moduleid = geo_module(geoid); format_module_id(buffer, moduleid, MODULE_FORMAT_BRIEF); - DPRINTF("module_add_node: moduleid=%s node=%d\n", buffer, cnodeid); + DPRINTF("module_add_node: moduleid=%s node=%d ", buffer, cnodeid); if ((m = module_lookup(moduleid)) == 0) { m = kmalloc(sizeof (module_t), GFP_KERNEL); - memset(m, 0 , sizeof(module_t)); ASSERT_ALWAYS(m); + memset(m, 0 , sizeof(module_t)); + + for (slab_number = 0; slab_number <= MAX_SLABS; slab_number++) { + m->nodes[slab_number] = -1; + } m->id = moduleid; spin_lock_init(&m->lock); - mutex_init_locked(&m->thdcnt); + init_MUTEX_LOCKED(&m->thdcnt); /* Insert in sorted order by module number */ @@ -154,16 +158,23 @@ nummodules++; } - m->nodes[m->nodecnt] = cnodeid; - m->geoid[m->nodecnt] = geoid; - m->nodecnt++; + /* + * Save this information in the correct slab number of the node in the + * module. + */ + slab_number = geo_slab(geoid); + DPRINTF("slab number added 0x%x\n", slab_number); + + if (m->nodes[slab_number] != -1) + panic("module_add_node .. slab previously found\n"); - DPRINTF("module_add_node: module %s now has %d nodes\n", buffer, m->nodecnt); + m->nodes[slab_number] = cnodeid; + m->geoid[slab_number] = geoid; return m; } -int module_probe_snum(module_t *m, nasid_t nasid) +int module_probe_snum(module_t *m, nasid_t host_nasid, nasid_t nasid) { lboard_t *board; klmod_serial_num_t *comp; @@ -173,7 +184,7 @@ /* * record brick serial number */ - board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA); + board = find_lboard((lboard_t *) KL_CONFIG_INFO(host_nasid), KLTYPE_SNIA); if (! board || KL_CONFIG_DUPLICATE_BOARD(board)) { @@ -245,36 +256,47 @@ nserial = 0; + /* + * First pass just scan for compute node boards KLTYPE_SNIA. + * We do not support memoryless compute nodes. + */ 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_geoid, node); + HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, NULL, NULL, "Found Shub lboard 0x%lx nasid 0x%x cnode 0x%x \n", (unsigned long)board, (int)nasid, (int)node)); - if (! m->snum_valid && module_probe_snum(m, nasid)) + m = module_add_node(board->brd_geoid, node); + if (! m->snum_valid && module_probe_snum(m, nasid, 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"); -} + /* + * Second scan, look for TIO's board hosted by compute nodes. + */ + for (node = numnodes; node < numionodes; node++) { + nasid_t tio_nasid; + cnodeid_t tio_node; + char serial_number[16]; -int -get_kmod_info(cmoduleid_t cmod, module_info_t *mod_info) -{ - if (cmod < 0 || cmod >= nummodules) - return -EINVAL; + tio_nasid = COMPACT_TO_NASID_NODEID(node); + board = find_lboard((lboard_t *) KL_CONFIG_INFO(tio_nasid), KLTYPE_TIO); + ASSERT(board); + tio_node = NASID_TO_COMPACT_NODEID(tio_nasid); - mod_info->mod_num = modules[cmod]->id; + HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, NULL, NULL, "Found TIO lboard 0x%lx tio nasid %d tio cnode %d\n", (unsigned long)board, (int)tio_nasid, (int)tio_node)); - ia64_sn_sys_serial_get(mod_info->serial_str); - - mod_info->serial_num = ia64_sn_partition_serial_get(); + m = module_add_node(board->brd_geoid, tio_node); - return 0; + /* + * Get and initialize the serial number of TIO. + */ + 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; + nserial++; + } + } } Index: arch/ia64/sn/io/sn2/pci_bus_cvlink.c =================================================================== RCS file: arch/ia64/sn/io/sn2/pci_bus_cvlink.c diff -N arch/ia64/sn/io/sn2/pci_bus_cvlink.c --- arch/ia64/sn/io/sn2/pci_bus_cvlink.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,811 +0,0 @@ -/* $Id: pci_bus_cvlink.c,v 1.1 2004/07/22 19:49:10 joff 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 -#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); -} Index: arch/ia64/sn/io/sn2/pciio.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/pciio.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/pciio.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/pciio.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -1,14 +1,12 @@ -/* $Id: pciio.c,v 1.1 2004/07/22 19:49:10 joff Exp $ +/* $Id: pciio.c,v 1.2 2004/08/04 01:21:34 joff 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) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. */ -#define USRPCI 0 - #include #include #include @@ -30,108 +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) -{ - int ret = 0; - volatile void *new_addr; - - switch (len) { - case 4: - new_addr = (void *) addr; - 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; - extern nasid_t master_baseio_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_baseio_nasid; - } - } - return console_nasid; -} - -nasid_t -get_master_baseio_nasid(void) -{ - extern nasid_t master_baseio_nasid; - 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 ) { - master_baseio_wid = WIDGETID_GET(KL_CONFIG_CH_CONS_INFO(master_baseio_nasid)->memory_base); - } - } - return master_baseio_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 @@ -153,101 +57,9 @@ */ #if !defined(DEV_FUNC) -static pciio_provider_t *pciio_to_provider_fns(devfs_handle_t dev); +extern 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); -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, intr_func_t, intr_arg_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 * @@ -260,8 +72,8 @@ #if !defined(DEV_FUNC) -static pciio_provider_t * -pciio_to_provider_fns(devfs_handle_t dev) +pciio_provider_t * +pciio_to_provider_fns(vertex_hdl_t dev) { pciio_info_t card_info; pciio_provider_t *provider_fns; @@ -281,13 +93,10 @@ } } - 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 - + if (provider_fns == NULL) { + char devname[MAXDEVNAME]; + panic("%s: provider_fns == NULL", vertex_to_name(dev, devname, MAXDEVNAME)); + } return provider_fns; } @@ -316,7 +125,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 +163,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 +175,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,20 +219,20 @@ } 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 */ size_t align) { /* Alignment needed */ - if (align < NBPP) - align = NBPP; + if (align < PAGE_SIZE) + align = PAGE_SIZE; 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_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 +249,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 +274,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 +282,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 +292,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 +343,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 +367,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 +414,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 +453,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 +489,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 +517,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 +544,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 +565,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,61 +575,17 @@ * 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); } /* - * 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, +pciio_config_get(vertex_hdl_t dev, unsigned reg, unsigned size) { @@ -923,7 +615,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,80 +645,15 @@ * 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); } -/* - * 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) +pciio_info_chk(vertex_hdl_t pciio) { arbitrary_info_t ainfo = 0; @@ -1035,7 +662,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 +678,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,37 +702,20 @@ (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); } + 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 +vertex_hdl_t pciio_info_master_get(pciio_info_t pciio_info) { return (pciio_info->c_master); @@ -1124,102 +733,22 @@ 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) +pciio_attach(vertex_hdl_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 + char devname[MAXDEVNAME]; + printk("%s: pciio_attach\n", vertex_to_name(pciio, devname, MAXDEVNAME)); #endif return 0; } @@ -1228,7 +757,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 +766,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 +778,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; @@ -1257,121 +786,17 @@ 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, + 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; @@ -1393,17 +818,17 @@ /* 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)); + memset((char *)pciio_info, 0, 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 +854,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 +885,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 +903,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 +922,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; + return(0); } /* - * 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 @@ -1609,94 +950,46 @@ * 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), GFP_KERNEL); + + if (start > 0) { + status = allocate_resource( root_resource, new_res, + size, start /* Min start addr. */, + (start + size) - 1, 1, + NULL, NULL); + } else { + if (size > align) + align = size; + status = allocate_resource( root_resource, new_res, + size, align /* Min start addr. */, + root_resource->end, align, + NULL, NULL); + } - /* 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 (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 +999,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 +1027,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 +1045,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 +1062,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); } @@ -1773,105 +1072,3 @@ { return(0); } - - -/* - * 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); - - /* - * If the device is not a PIC, we always want the PCIIO_BYTE_STREAM to be - * set. Otherwise, it must not be set. This applies to SN1 and SN2. - */ - return DEV_FUNC(dev, dmatrans_addr) - (dev, dev_desc, paddr, byte_count, (IS_PIC_DEVICE(pci_dev)) ? (flags & ~PCIIO_BYTE_STREAM) : flags | PCIIO_BYTE_STREAM); -} - -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); - - /* - * If the device is not a PIC, we always want the PCIIO_BYTE_STREAM to be - * set. Otherwise, it must not be set. This applies to SN1 and SN2. - */ - return (pciio_dmamap_t) DEV_FUNC(dev, dmamap_alloc) - (dev, dev_desc, byte_count_max, (IS_PIC_DEVICE(pci_dev)) ? (flags & ~PCIIO_BYTE_STREAM) : flags | PCIIO_BYTE_STREAM); -} - -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)); -} - Index: arch/ia64/sn/io/sn2/pic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/pic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/pic.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/pic.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -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 @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -27,51 +28,203 @@ #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); + + +/* + * 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; +} + +/* + * 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) +{ + 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); -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); + return 1; + } + printk("pic_bus1_widget_info_dup: " + "cannot get INFO_LBL_XWIDGET from 0x%lx\n", (uint64_t)conn_v); + return 0; +} -void -pic_init(void) +/* + * 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) { - PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INIT, NULL, "pic_init()\n")); + 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, hubv; + 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 = hwgraph_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; - xwidget_driver_register(PIC_WIDGET_PART_NUM_BUS0, - PIC_WIDGET_MFGR_NUM, - "pic_", - 0); + hubv = cnodeid_to_vertex(xbow_peer); + ASSERT(hubv != GRAPH_VERTEX_NONE); + device_master_set(peer_conn_v, hubv); + xtalk_provider_register(hubv, &hub_provider); + xtalk_provider_startup(hubv); + 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; + int brick_type; + int iobrick_type_get_nasid(nasid_t nasid); + 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 +237,19 @@ * the Bridge registers themselves. */ /* FIXME: what should the hwgraph path look like ? */ - rc = hwgraph_path_add(conn_v, 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); - ASSERT(rc == GRAPH_SUCCESS); -#endif + brick_type = iobrick_type_get_nasid(NASID_GET(bridge0)); + if ( brick_type == MODULE_CGBRICK ) { + rc = hwgraph_path_add(conn_v0, EDGE_LBL_AGP_0, &pcibr_vhdl0); + ASSERT(rc == GRAPH_SUCCESS); + rc = hwgraph_path_add(conn_v1, EDGE_LBL_AGP_1, &pcibr_vhdl1); + ASSERT(rc == GRAPH_SUCCESS); + } + else { + rc = hwgraph_path_add(conn_v0, EDGE_LBL_PCIX_0, &pcibr_vhdl0); + ASSERT(rc == GRAPH_SUCCESS); + rc = hwgraph_path_add(conn_v1, EDGE_LBL_PCIX_1, &pcibr_vhdl1); + ASSERT(rc == GRAPH_SUCCESS); + } PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v, "pic_attach: pcibr_vhdl0=%v, pcibr_vhdl1=%v\n", @@ -97,27 +257,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 +295,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, @@ -162,9 +310,7 @@ (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, Index: arch/ia64/sn/io/sn2/sgi_io_init.c =================================================================== RCS file: arch/ia64/sn/io/sn2/sgi_io_init.c diff -N arch/ia64/sn/io/sn2/sgi_io_init.c --- arch/ia64/sn/io/sn2/sgi_io_init.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,230 +0,0 @@ -/* $Id: sgi_io_init.c,v 1.1 2004/07/22 19:49:10 joff 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 - -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); -} Index: arch/ia64/sn/io/sn2/shub.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/shub.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/shub.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/shub.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -1,13 +1,13 @@ -/* $Id: shub.c,v 1.1 2004/07/22 19:49:10 joff Exp $ +/* $Id: shub.c,v 1.2 2004/08/04 01:21:34 joff 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) 1992-1997, 2000-2003 Silicon Graphics, Inc. All Rights Reserved. */ -#ident "$Revision: 1.1 $" +#ident "$Revision: 1.2 $" #include #include @@ -15,7 +15,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -34,44 +36,18 @@ #include #include -/* - * Shub WAR for Xbridge Little Endian problem: - * Xbridge has to run in BIG ENDIAN even with Shub. - */ - - -/* - * io_sh_swapper: Turn on Shub byte swapping. - * All data destined to and from Shub to XIO are byte-swapped. - */ -void -io_sh_swapper(nasid_t nasid, int onoff) -{ - ii_iwc_u_t ii_iwc; - - ii_iwc.ii_iwc_regval = REMOTE_HUB_L(nasid, IIO_IWC); - - ii_iwc.ii_iwc_fld_s.i_dma_byte_swap = onoff; - REMOTE_HUB_S(nasid, IIO_IWC, ii_iwc.ii_iwc_regval); - ii_iwc.ii_iwc_regval = REMOTE_HUB_L(nasid, IIO_IWC); - -} +#define SHUB_NUM_ECF_REGISTERS 8 /* - * io_get_sh_swapper: Return current Swap mode. - * 1 = Swap on, 0 = Swap off. + * A backport of the 2.5 scheduler is used by many vendors of 2.4-based + * distributions. + * We can only guess its presence by the lack of the SCHED_YIELD flag. + * If the heuristic doesn't work, change this define by hand. */ -int -io_get_sh_swapper(nasid_t nasid) -{ - ii_iwc_u_t ii_iwc; - - ii_iwc.ii_iwc_regval = REMOTE_HUB_L(nasid, IIO_IWC); - return(ii_iwc.ii_iwc_fld_s.i_dma_byte_swap); - -} +#ifndef SCHED_YIELD +#define __HAVE_NEW_SCHEDULER 1 +#endif -#define SHUB_NUM_ECF_REGISTERS 8 static uint32_t shub_perf_counts[SHUB_NUM_ECF_REGISTERS]; @@ -97,6 +73,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 +102,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 +174,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 < 0 || cnode >= numnodes) return -ENODEV; - cnode = (cnodeid_t)hwgraph_fastinfo_get(d); switch (cmd) { case SNDRV_SHUB_CONFIGURE: @@ -231,3 +226,260 @@ 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(); + +#ifdef __HAVE_NEW_SCHEDULER + set_user_nice(tsk, 19); +#else + tsk->nice = 19; +#endif + 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); Index: arch/ia64/sn/io/sn2/shub_intr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/shub_intr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/shub_intr.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/shub_intr.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -1,10 +1,10 @@ -/* $Id: shub_intr.c,v 1.1 2004/07/22 19:49:10 joff Exp $ +/* $Id: shub_intr.c,v 1.2 2004/08/04 01:21:34 joff 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) 1992-1997, 2000-2003 Silicon Graphics, Inc. All Rights Reserved. */ #include @@ -27,27 +27,34 @@ #include #include #include +#include +#include +#include /* ARGSUSED */ void -hub_intr_init(devfs_handle_t hubv) +hub_intr_init(vertex_hdl_t hubv) { } 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; + + if (!(nasid & 1)) { + 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; + } else { + /* ICE does not have widget id. */ + return(-1); + } } 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; @@ -79,7 +86,7 @@ xtalk_addr = SH_II_INT0 | ((unsigned long)nasid << 36) | (1UL << 47); } - intr_hdl = snia_kmem_alloc_node(sizeof(struct hub_intr_s), KM_NOSLEEP, cnode); + intr_hdl = snia_kmem_alloc_node(sizeof(struct hub_intr_s), cnode); ASSERT_ALWAYS(intr_hdl); xtalk_info = &intr_hdl->i_xtalk_info; @@ -101,17 +108,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)); } @@ -189,17 +196,56 @@ intr_hdl->i_flags &= ~HUB_INTR_IS_CONNECTED; } - -/* - * Return a hwgraph vertex that represents the CPU currently - * targeted by an interrupt. +/* + * Redirect an interrupt to another cpu. */ -devfs_handle_t -hub_intr_cpu_get(hub_intr_t intr_hdl) -{ - cpuid_t cpuid = intr_hdl->i_cpuid; - ASSERT(cpuid != CPU_NONE); +void +sn_shub_redirect_intr(pcibr_intr_t intr, unsigned long cpu) { + unsigned long bit; + int cpuphys, slice; + nasid_t nasid; + unsigned long xtalk_addr; + bridge_t *bridge = intr->bi_soft->bs_base; + picreg_t int_enable; + picreg_t host_addr; + int irq; - return(cpuid_to_vertex(cpuid)); + cpuphys = cpu_physical_id(cpu); + slice = cpu_physical_id_to_slice(cpuphys); + nasid = cpu_physical_id_to_nasid(cpuphys); + + if (slice) { + xtalk_addr = SH_II_INT1 | ((unsigned long)nasid << 36) | (1UL << 47); + } else { + xtalk_addr = SH_II_INT0 | ((unsigned long)nasid << 36) | (1UL << 47); + } + + for (bit = 0; bit < 8; bit++) { + if (intr->bi_ibits & (1 << bit) ) { + /* Disable interrupts. */ + int_enable = bridge->p_int_enable_64; + int_enable &= ~bit; + bridge->p_int_enable_64 = int_enable; + /* Reset Host address (Interrupt destination) */ + host_addr = bridge->p_int_addr_64[bit]; + host_addr &= ~((1UL << 48) - 1); + host_addr |= xtalk_addr; + bridge->p_int_addr_64[bit] = host_addr; + /* Enable interrupt */ + int_enable |= bit; + bridge->p_int_enable_64 = int_enable; + /* Force an interrupt, just in case. */ + bridge->b_force_pin[bit].intr = 1; + } + } + irq = intr->bi_irq; + if (pdacpu(cpu).sn_first_irq == 0 || pdacpu(cpu).sn_first_irq > irq) { + pdacpu(cpu).sn_first_irq = irq; + } + if (pdacpu(cpu).sn_last_irq < irq) { + pdacpu(cpu).sn_last_irq = irq; + } + intr->bi_cpu = (int)cpu; } + Index: arch/ia64/sn/io/sn2/shuberror.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/shuberror.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/shuberror.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/shuberror.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -1,18 +1,20 @@ -/* $Id: shuberror.c,v 1.1 2004/07/22 19:49:10 joff Exp $ +/* $Id: shuberror.c,v 1.2 2004/08/04 01:21:34 joff 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) 1992 - 1997, 2000,2002-2003 Silicon Graphics, Inc. All rights reserved. */ #include #include #include +#include #include #include +#include #include #include #include @@ -27,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -34,26 +37,22 @@ 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) { int i; - hubreg_t idsr; /* * Make sure spurious write response errors are cleared @@ -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); } /* @@ -276,7 +299,7 @@ * Wait till hub indicates it's done. */ while (REMOTE_HUB_L(hinfo->h_nasid, IIO_ICDR) & IIO_ICDR_PND) - us_delay(1); + udelay(1); } @@ -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; Index: arch/ia64/sn/io/sn2/shubio.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/shubio.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/shubio.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/shubio.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -1,10 +1,10 @@ -/* $Id: shubio.c,v 1.1 2004/07/22 19:49:10 joff Exp $ +/* $Id: shubio.c,v 1.2 2004/08/04 01:21:34 joff 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) 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. @@ -309,8 +310,7 @@ if (!is_widget_pio_enabled(ioerror)) { if (error_state_get(hub_v) == ERROR_STATE_ACTION) - ioerror_dump("No outbound widget" - " access - ", + snia_ioerror_dump("No outbound widget access - ", error_code, mode, ioerror); return(IOERROR_HANDLED); } @@ -351,8 +351,7 @@ if (!is_widget_pio_enabled(ioerror)) { if (error_state_get(hub_v) == ERROR_STATE_ACTION) - ioerror_dump("No outbound widget" - " access - ", + snia_ioerror_dump("No outbound widget access - ", error_code, mode, ioerror); return(IOERROR_HANDLED); } @@ -428,11 +427,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 +448,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 +473,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; + int replace = 1; /* 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); @@ -501,7 +495,7 @@ * for this vertex. */ if (v_error_state_get(v,old_state) != GRAPH_SUCCESS) - replace = B_FALSE; + replace = 0; if (v_error_state_set(v,new_state,replace) != GRAPH_SUCCESS) { return(ERROR_RETURN_CODE_CANNOT_SET_STATE); Index: arch/ia64/sn/io/sn2/xbow.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/xbow.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/xbow.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/xbow.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -1,16 +1,19 @@ -/* $Id: xbow.c,v 1.1 2004/07/22 19:49:10 joff Exp $ +/* $Id: xbow.c,v 1.2 2004/08/04 01:21:34 joff 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) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved. */ #include #include +#include #include +#include #include +#include #include #include #include @@ -18,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -27,6 +29,8 @@ /* #define XBOW_DEBUG 1 */ /* #define DEBUG_ERROR 1 */ +#define kdebug 0 + /* * Files needed to get the device driver entry points @@ -44,8 +48,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 +61,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 +91,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 +120,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 +163,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 +199,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 +260,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 +284,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]" @@ -329,12 +314,12 @@ #endif /* XBRIDGE_REGS_SIM */ rev = XWIDGET_PART_REV_NUM(id); - mutex_spinlock_init(&soft->xbow_perf_lock); + spin_lock_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); + spin_lock_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 */ @@ -350,6 +335,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 +350,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,131 +422,6 @@ 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. @@ -585,6 +443,10 @@ IS_PIC_XBOW(xbow->xb_wid_id) && port==0xf) { return 1; } + else if ( IS_PIC_XBOW(xbow->xb_wid_id) && port==0xb ) { + /* for opus the present bit doesn't work on port 0xb */ + return 1; + } return xbow->xb_link(port).link_aux_status & XB_AUX_STAT_PRESENT; } } @@ -605,12 +467,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 +522,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 +532,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 +689,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 +741,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 @@ -957,7 +775,7 @@ XEM_ADD_VAR(wid_err_upper); XEM_ADD_VAR(wid_err_lower); XEM_ADD_VAR(wid_err_addr); - PRINT_PANIC("XIO Bus Error"); + panic("XIO Bus Error"); } } @@ -987,8 +805,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; @@ -1110,8 +928,9 @@ if (XBOW_WAR_ENABLED(PV854827, xbow->xb_wid_id) && IS_PIC_XBOW(xbow->xb_wid_id) && (port==0xf)) ; - else - if (!(link_aux_status & XB_AUX_STAT_PRESENT)) { + else if (IS_PIC_XBOW(xbow->xb_wid_id) && (port==0xb)) + ; /* WAR for opus this is missing on 0xb */ + else if (!(link_aux_status & XB_AUX_STAT_PRESENT)) { /* nobody connected. */ if (mode == MODE_DEVPROBE) return IOERROR_HANDLED; @@ -1240,20 +1059,19 @@ } 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; 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); + spin_lock(&xbow_soft->xbow_perf_lock); perf_reg.xb_counter_val = *(xbowreg_t *) xbow_perf->xp_perf_reg; @@ -1263,12 +1081,12 @@ ((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); + spin_unlock(&xbow_soft->xbow_perf_lock); } } 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,14 +1095,13 @@ } 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; 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; @@ -1297,10 +1114,10 @@ if ((counter < 0) || (counter >= XBOW_PERF_COUNTERS)) return -1; - s = mutex_spinlock(&xbow_soft->xbow_perf_lock); + spin_lock(&xbow_soft->xbow_perf_lock); if ((xbow_perf + counter)->xp_mode && mode) { - mutex_spinunlock(&xbow_soft->xbow_perf_lock, s); + spin_unlock(&xbow_soft->xbow_perf_lock); return -1; } for (i = 0; i < XBOW_PERF_COUNTERS; i++) { @@ -1308,7 +1125,7 @@ continue; if (((xbow_perf + i)->xp_link == link) && ((xbow_perf + i)->xp_mode)) { - mutex_spinunlock(&xbow_soft->xbow_perf_lock, s); + spin_unlock(&xbow_soft->xbow_perf_lock); return -1; } } @@ -1326,12 +1143,12 @@ *(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); + spin_unlock(&xbow_soft->xbow_perf_lock); return 0; } 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 +1157,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 +1165,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 +1199,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 +1214,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,22 +1224,17 @@ 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; xbow_t *xbow; xbowreg_t ctrl; xbwX_stat_t stat; - unsigned itick; + unsigned long itick; unsigned dtick; - static int ticks_per_ms = 0; + static long ticks_to_wait = HZ / 1000; - 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); @@ -1430,7 +1242,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); @@ -1448,61 +1260,21 @@ */ ctrl = xbow->xb_link(port).link_control; xbow->xb_link(port).link_reset = 0; - itick = get_timestamp(); + itick = jiffies; while (1) { stat.linkstatus = xbow->xb_link(port).link_status; if (stat.link_alive) break; - dtick = get_timestamp() - itick; - if (dtick > ticks_per_ms) { + dtick = jiffies - itick; + if (dtick > ticks_to_wait) { return -1; /* never came out of reset */ } - DELAY(2); /* don't beat on link_status */ + udelay(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) @@ -1562,7 +1334,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, @@ -1571,7 +1343,6 @@ 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; @@ -1585,7 +1356,7 @@ ASSERT(XBOW_WIDGET_IS_VALID(src_wid)); ASSERT(XBOW_WIDGET_IS_VALID(dest_wid)); - s = mutex_spinlock(&soft->xbow_bw_alloc_lock); + spin_lock(&soft->xbow_bw_alloc_lock); /* Get pointer to the correct register */ xreg = XBOW_PRIO_ARBREG_PTR(soft->base, dest_wid, src_wid); @@ -1636,7 +1407,7 @@ error = 1; } - mutex_spinunlock(&soft->xbow_bw_alloc_lock, s); + spin_unlock(&soft->xbow_bw_alloc_lock); return (error); } Index: arch/ia64/sn/io/sn2/xtalk.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/xtalk.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/xtalk.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/xtalk.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -1,10 +1,10 @@ -/* $Id: xtalk.c,v 1.1 2004/07/22 19:49:10 joff Exp $ +/* $Id: xtalk.c,v 1.2 2004/08/04 01:21:34 joff 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) 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 */ @@ -313,7 +310,7 @@ unsigned flags) { #if DEBUG - PRINT_PANIC("null_xtalk_early_piotrans_addr"); + panic("null_xtalk_early_piotrans_addr"); #endif return NULL; } @@ -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,15 +551,15 @@ #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); + snia_ioerror_dump("xtalk", error_code, mode, ioerror); return IOERROR_UNHANDLED; } 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,19 +919,16 @@ 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)); + memset((void *)widget_info, 0, sizeof(widget_info)); DEL(widget_info); return(0); } 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; Index: arch/ia64/sn/io/sn2/pcibr/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/pcibr/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/pcibr/Makefile 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/pcibr/Makefile 4 Aug 2004 01:21:34 -0000 1.2 @@ -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 Index: arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -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 @@ -100,102 +86,36 @@ int num_entries, entry; 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. * The read following the write is required for the Bridge war */ - 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 */ - } - } - splx(s); + bridge->b_wid_control; /* inval addr bug war */ num_entries = ATE_NUM_ENTRIES(largest_working_size); @@ -229,32 +149,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 +305,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 +366,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; } } } @@ -445,25 +379,9 @@ int ate_count, bridge_ate_t ate) { - if (IS_PIC_SOFT(pcibr_soft) ) { - while (ate_count-- > 0) { - *ate_ptr++ = ate; - ate += IOPGSIZE; - } - } - else { - if (io_get_sh_swapper(NASID_GET(ate_ptr))) { - while (ate_count-- > 0) { - *ate_ptr++ = __swab64(ate); - ate += IOPGSIZE; - } - } - else { - while (ate_count-- > 0) { - *ate_ptr++ = ate; - ate += IOPGSIZE; - } - } + while (ate_count-- > 0) { + *ate_ptr++ = ate; + ate += IOPGSIZE; } } @@ -505,19 +423,7 @@ for (slot = pcibr_soft->bs_min_slot; slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) { if ((cmd_reg = cmd_regs[slot]) & PCI_CMD_BUS_MASTER) { - if ( IS_PIC_SOFT(pcibr_soft) ) { - pcibr_slot_config_set(bridge, slot, PCI_CFG_COMMAND/4, cmd_reg); - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - bridge->b_type0_cfg_dev[slot].l[PCI_CFG_COMMAND / 4] = __swab32(cmd_reg); - } - else { -// BUG(); /* Does this really work if called when io_get_sh_swapper = 0? */ -// bridge->b_type0_cfg_dev[slot].l[PCI_CFG_COMMAND / 4] = cmd_reg; - pcibr_slot_config_set(bridge, slot, PCI_CFG_COMMAND/4, cmd_reg); - } - } + pcibr_slot_config_set(bridge, slot, PCI_CFG_COMMAND/4, cmd_reg); } } pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_BUSY; Index: arch/ia64/sn/io/sn2/pcibr/pcibr_config.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/pcibr/pcibr_config.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/pcibr/pcibr_config.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -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; + } } Index: arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -4,13 +4,19 @@ * 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 +#if 0 +#include +#include +#endif #include +#include #include #include #include @@ -18,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -27,17 +34,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 +73,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 +89,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 +125,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 +138,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 +163,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 +217,46 @@ 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_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); - -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); +int pcibr_reset(vertex_hdl_t); +pciio_endian_t pcibr_endian_set(vertex_hdl_t, pciio_endian_t, pciio_endian_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 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 @@ -547,17 +506,6 @@ slotp->bss_device = new; bridge->b_wid_tflush; /* wait until Bridge PIO complete */ } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_SET32((&bridge->b_device[slot].reg)) = __swab32(new); - slotp->bss_device = new; - BRIDGE_REG_GET32((&bridge->b_wid_tflush)); /* wait until Bridge PIO complete */ - } else { - bridge->b_device[slot].reg = new; - slotp->bss_device = new; - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - } - } pcibr_unlock(pcibr_soft, s); #ifdef PIC_LATER @@ -592,203 +540,57 @@ pcibr_unlock(pcibr_soft, s); } -/* - * flush write gather buffer for slot - */ -static 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; - - if ( IS_PIC_SOFT(pcibr_soft) ) { - wrf = bridge->b_wr_req_buf[slot].reg; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - wrf = BRIDGE_REG_GET32((&bridge->b_wr_req_buf[slot].reg)); - } else { - wrf = bridge->b_wr_req_buf[slot].reg; - } - } - pcibr_unlock(pcibr_soft, s); -} /* ===================================================================== * Bridge (pcibr) "Device Driver" entry points */ -/* - * 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; - - /* - * 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; -} +static int pcibr_mmap(struct file * file, struct vm_area_struct * vma); +struct file_operations pcibr_fops = { + .owner = THIS_MODULE, + .mmap = pcibr_mmap, +}; /* 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 +614,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 +639,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 +692,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 +772,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 +823,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,40 +874,45 @@ * 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")); - if (GRAPH_SUCCESS != hwgraph_vertex_name_get(f_c, dst, MAXDEVNAME)) + 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) + if (xp == NULL) { return 0; - widgetnum = atoi(xp+7); - if (widgetnum < XBOW_PORT_8 || widgetnum > XBOW_PORT_F) + } + widgetnum = simple_strtoul(xp+7, NULL, 0); + if (widgetnum < XBOW_PORT_8 || widgetnum > XBOW_PORT_F) { return 0; + } /* remove "/pci/direct" from path */ cp = strstr(dst, "/" EDGE_LBL_PCI "/" EDGE_LBL_DIRECT); - if (cp == NULL) + if (cp == NULL) { return 0; + } *cp = (char)NULL; /* get the vertex for the widget */ - if (GRAPH_SUCCESS != hwgraph_traverse(NULL, dp, &svtx)) + if (GRAPH_SUCCESS != hwgraph_traverse(NULL, dp, &svtx)) { return 0; + } *xp = (char)NULL; /* remove "/xtalk/..." from path */ @@ -1145,11 +940,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 +975,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,39 +988,28 @@ 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; - bridgereg_t int_enable_32; + uint64_t int_enable; picreg_t int_enable_64; unsigned rrb_fixed = 0; - int spl_level; - #if PCI_FBBE int fast_back_to_back_enable; #endif 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); /* @@ -1250,7 +1034,7 @@ NEW(pcibr_soft); if (ret_softp) *ret_softp = pcibr_soft; - BZERO(pcibr_soft, sizeof *pcibr_soft); + memset(pcibr_soft, 0, sizeof *pcibr_soft); pcibr_soft_set(pcibr_vhdl, pcibr_soft); pcibr_soft->bs_conn = xconn_vhdl; pcibr_soft->bs_vhdl = pcibr_vhdl; @@ -1261,13 +1045,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 +1145,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 +1154,28 @@ if (pcibr_soft->bs_bricktype > 0) { switch (pcibr_soft->bs_bricktype) { case MODULE_PXBRICK: + case MODULE_IXBRICK: + case MODULE_OPUSBRICK: 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; @@ -1411,6 +1202,13 @@ pcibr_soft->bs_last_slot = 6; } break; + + case MODULE_CGBRICK: + pcibr_soft->bs_first_slot = 0; + pcibr_soft->bs_last_slot = 0; + pcibr_soft->bs_last_reset = 0; + break; + default: break; } @@ -1491,8 +1289,6 @@ if (busnum == 0) { xwidget_error_register(xconn_vhdl, pcibr_error_handler_wrapper, pcibr_soft); } - } else { - xwidget_error_register(xconn_vhdl, pcibr_error_handler, pcibr_soft); } /* @@ -1546,8 +1342,6 @@ */ if (IS_PIC_SOFT(pcibr_soft)) bridge->b_int_device = (uint32_t) 0x006db6db; - else - bridge->b_int_device = (uint32_t) 0xffffffff; { bridgereg_t dirmap; @@ -1559,11 +1353,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 +1371,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; @@ -1615,7 +1380,7 @@ * for the lowest hunk of memory. */ xbase = xtalk_dmatrans_addr(xconn_vhdl, 0, - paddr, _PAGESZ, 0); + paddr, PAGE_SIZE, 0); if (xbase != XIO_NOWHERE) { if (XIO_PACKED(xbase)) { @@ -1645,24 +1410,18 @@ * 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 if (IS_PIC_SOFT(pcibr_soft)) { bridge->p_wid_control_64 &= ~BRIDGE_CTRL_PAGE_SIZE; - } else { - bridge->b_wid_control &= ~BRIDGE_CTRL_PAGE_SIZE; - } + } #elif IOPGSIZE == 16384 if (IS_PIC_SOFT(pcibr_soft)) { bridge->p_wid_control_64 |= BRIDGE_CTRL_PAGE_SIZE; - } else { - 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++) { @@ -1697,18 +1456,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 +1525,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 +1547,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 +1566,10 @@ if (IS_PIC_SOFT(pcibr_soft)) { int_enable_64 = bridge->p_int_enable_64 | BRIDGE_ISR_ERRORS; int_enable = (uint64_t)int_enable_64; - } 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)0x7ffffeff7ffffeff; #endif + } #if BRIDGE_ERROR_INTR_WAR @@ -1849,24 +1606,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. @@ -1890,8 +1629,6 @@ if (IS_PIC_SOFT(pcibr_soft)) { bridge->p_int_enable_64 = (picreg_t)int_enable; - } else { - bridge->b_int_enable = (bridgereg_t)int_enable; } bridge->b_int_mode = 0; /* do not send "clear interrupt" packets */ @@ -1918,16 +1655,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 +1673,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 +1686,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), GFP_KERNEL); + 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 = PAGE_SIZE; + 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), GFP_KERNEL); + 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,25 +1800,6 @@ */ if (pcibr_soft->bs_bricktype > 0) { switch (pcibr_soft->bs_bricktype) { - case MODULE_PXBRICK: - /* - * If the IO9 is in the PXBrick (bus1, slot1) allocate - * RRBs to all the devices - */ - if ((pcibr_widget_to_bus(pcibr_vhdl) == 1) && - (pcibr_soft->bs_slot[0].bss_vendor_id == 0x10A9) && - (pcibr_soft->bs_slot[0].bss_device_id == 0x100A)) { - do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 4); - do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 4); - do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 4); - do_pcibr_rrb_autoalloc(pcibr_soft, 3, VCHAN0, 4); - } else { - 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); @@ -2098,14 +1815,31 @@ do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 1); } break; - } /* switch */ - } + case MODULE_PXBRICK: + case MODULE_IXBRICK: + case MODULE_OPUSBRICK: + /* + * If the IO9 is in the PXBrick (bus1, slot1) allocate + * RRBs to all the devices + */ + if ((pcibr_widget_to_bus(pcibr_vhdl) == 1) && + (pcibr_soft->bs_slot[0].bss_vendor_id == 0x10A9) && + (pcibr_soft->bs_slot[0].bss_device_id == 0x100A)) { + do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 4); + do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 4); + do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 4); + do_pcibr_rrb_autoalloc(pcibr_soft, 3, VCHAN0, 4); + } else { + do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 4); + do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 4); + } + break; -#ifdef LATER - if (strstr(nicinfo, XTALK_PCI_PART_NUM)) { - do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8); + case MODULE_CGBRICK: + do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 8); + break; + } /* switch */ } -#endif } /* OK Special RRB allocations are done. */ for (slot = pcibr_soft->bs_min_slot; @@ -2113,78 +1847,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 +1859,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; @@ -2217,8 +1881,6 @@ /* Disable the interrupts from the bridge */ if (IS_PIC_SOFT(pcibr_soft)) { bridge->p_int_enable_64 = 0; - } else { - bridge->b_int_enable = 0; } pcibr_unlock(pcibr_soft, s); @@ -2232,18 +1894,8 @@ 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. */ @@ -2265,9 +1917,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; @@ -2293,23 +1945,12 @@ 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 = PCIBR_INFO_SLOT_GET_INT(pciio_info); - pcibr_device_write_gather_flush(pcibr_soft, slot); - return 0; -} - /* ===================================================================== * PIO MANAGEMENT */ 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 +1964,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 */ @@ -2517,24 +2160,11 @@ pcibr_soft->bs_slot[win].bss_device = devreg; bridge->b_wid_tflush; /* wait until Bridge PIO complete */ } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_SET32((&bridge->b_device[win].reg)) = __swab32(devreg); - pcibr_soft->bs_slot[win].bss_device = devreg; - BRIDGE_REG_GET32((&bridge->b_wid_tflush)); /* wait until Bridge PIO complete */ - } else { - bridge->b_device[win].reg = devreg; - pcibr_soft->bs_slot[win].bss_device = devreg; - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - } - } #ifdef PCI_LATER 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 +2250,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 @@ -2689,22 +2347,6 @@ if (octl != nctl) /* make the change if any */ bridge->b_wid_control = nctl; } - else { - picreg_t octl, nctl; - if (io_get_sh_swapper(NASID_GET(bridge))) { - octl = BRIDGE_REG_GET32((&bridge->b_wid_control)); - nctl = bst ? octl | swb : octl & ~swb; - - if (octl != nctl) /* make the change if any */ - BRIDGE_REG_SET32((&bridge->b_wid_control)) = __swab32(nctl); - } else { - 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 (pcibr_debug_mask & PCIBR_DEBUG_PIOMAP) { @@ -2725,7 +2367,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 +2379,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 +2509,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 +2519,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 +2550,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, @@ -2927,7 +2569,7 @@ /* * Check for proper alignment */ - ASSERT(alignment >= NBPP); + ASSERT(alignment >= PAGE_SIZE); ASSERT((alignment & (alignment - 1)) == 0); align_mask = alignment - 1; @@ -3010,7 +2652,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 +2803,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 +2858,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 +2908,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. @@ -3363,7 +3005,7 @@ !IS_XBRIDGE_OR_PIC_SOFT(pcibr_soft)) { bridge_t *bridge = pcibr_soft->bs_base; volatile unsigned *cmd_regp; - unsigned cmd_reg; + unsigned cmd_reg = 0; unsigned long s; pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_SSRAM; @@ -3374,13 +3016,6 @@ if ( IS_PIC_SOFT(pcibr_soft) ) { cmd_reg = pcibr_slot_config_get(bridge, slot, PCI_CFG_COMMAND/4); } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_SET32((&cmd_reg)) = __swab32(*cmd_regp); - } else { - cmd_reg = pcibr_slot_config_get(bridge, slot, PCI_CFG_COMMAND/4); - } - } 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); @@ -3454,6 +3089,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 +3122,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 +3164,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. @@ -3609,13 +3268,6 @@ 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_addr (PMU) : wanted paddr " "[0x%x..0x%x] returning PCI 0x%x\n", @@ -3644,243 +3296,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 +3332,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 +3343,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 +3351,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 +3564,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 +3571,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 +3610,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 +3692,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) { @@ -4518,17 +3726,6 @@ pcibr_soft->bs_slot[pciio_slot].bss_device = devreg; bridge->b_wid_tflush; /* wait until Bridge PIO complete */ } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_SET32((&bridge->b_device[pciio_slot].reg)) = __swab32(devreg); - pcibr_soft->bs_slot[pciio_slot].bss_device = devreg; - BRIDGE_REG_GET32((&bridge->b_wid_tflush));/* wait until Bridge PIO complete */ - } else { - 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); @@ -4542,105 +3739,6 @@ 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; - - if ( IS_PIC_SOFT(pcibr_soft) ) { - 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 */ - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_SET32((&bridge->b_device[pciio_slot].reg)) = __swab32(devreg); - pcibr_soft->bs_slot[pciio_slot].bss_device = devreg; - BRIDGE_REG_GET32((&bridge->b_wid_tflush));/* wait until Bridge PIO complete */ - } else { - 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 = PCIBR_INFO_SLOT_GET_INT(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 @@ -4653,7 +3751,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); @@ -4709,17 +3807,6 @@ pcibr_soft->bs_slot[pciio_slot].bss_device = devreg; bridge->b_wid_tflush; /* wait until Bridge PIO complete */ } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_SET32((&bridge->b_device[pciio_slot].reg)) = __swab32(devreg); - pcibr_soft->bs_slot[pciio_slot].bss_device = devreg; - BRIDGE_REG_GET32((&bridge->b_wid_tflush));/* wait until Bridge PIO complete */ - } else { - 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); #ifdef PIC_LATER @@ -4792,10 +3879,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, @@ -4809,28 +3894,19 @@ (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, -#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_device_unregister_f *) 0, (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 +3933,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 +3941,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 +3948,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 +3986,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; +} Index: arch/ia64/sn/io/sn2/pcibr/pcibr_error.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/pcibr/pcibr_error.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/pcibr/pcibr_error.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -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,8 @@ #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[] = +#if defined(FORCE_ERRORS) +static struct reg_values space_v[] = { {PCIIO_SPACE_NONE, "none"}, {PCIIO_SPACE_ROM, "ROM"}, @@ -189,13 +120,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"}, @@ -217,15 +148,16 @@ {BRIDGE_DEV_OFF_MASK, BRIDGE_DEV_OFF_ADDR_SHFT, "DEV_OFF", "%x"}, {0} }; +#endif /* FORCE_ERRORS */ -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 +211,7 @@ /* * display memory directory state */ -void +static void pcibr_show_dir_state(paddr_t paddr, char *prefix) { #ifdef LATER @@ -428,7 +360,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 +523,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 +650,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; @@ -764,7 +665,7 @@ entry = pcibr_list; while (1) { if (entry == NULL) { - PRINT_PANIC("pcibr_error_intr_handler:\tmy parameter (0x%p) is not a pcibr_soft!", arg); + panic("pcibr_error_intr_handler:\tmy parameter (0x%p) is not a pcibr_soft!", arg); } if ((intr_arg_t) entry->bl_soft == arg) break; @@ -806,10 +707,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 +744,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 +903,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 +917,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 +936,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"); + 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"); + 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 +975,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 +994,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,8 +1081,10 @@ { int retval = IOERROR_HANDLED; - devfs_handle_t pcibr_vhdl = pcibr_soft->bs_vhdl; + vertex_hdl_t pcibr_vhdl = pcibr_soft->bs_vhdl; +#if defined(FORCE_ERRORS) bridge_t *bridge = pcibr_soft->bs_base; +#endif iopaddr_t bad_xaddr; @@ -1761,9 +1418,6 @@ } #if defined(FORCE_ERRORS) if (0) { -#elif !DEBUG - if (kdebug) { -#endif /* * Dump raw data from Bridge/PCI layer. */ @@ -1791,9 +1445,8 @@ BEM_ADD_REG(device); } } -#if !DEBUG || defined(FORCE_ERRORS) } -#endif +#endif /* FORCE_ERRORS */ /* * Since error could not be handled at lower level, @@ -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; -} Index: arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -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); Index: arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c =================================================================== RCS file: arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c diff -N arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c --- arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 */ Index: arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -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 @@ -97,7 +103,7 @@ pcibr_intr_wrap_t wrap; if (cbuf->ib_in == cbuf->ib_out) - PRINT_PANIC( "pcibr intr circular buffer empty, cbuf=0x%p, ib_in=ib_out=%d\n", + panic( "pcibr intr circular buffer empty, cbuf=0x%p, ib_in=ib_out=%d\n", (void *)cbuf, cbuf->ib_out); wrap = cbuf->ib_cbuf[cbuf->ib_out++]; @@ -112,26 +118,121 @@ pcibr_wrap_put(pcibr_intr_wrap_t wrap, pcibr_intr_cbuf_t cbuf) { int in; - int s; /* * Multiple CPUs could be executing this code simultaneously * if a handler has registered multiple interrupt lines and * the interrupts are directed to different CPUs. */ - s = mutex_spinlock(&cbuf->ib_lock); + spin_lock(&cbuf->ib_lock); in = (cbuf->ib_in + 1) % IBUFSIZE; if (in == cbuf->ib_out) - PRINT_PANIC( "pcibr intr circular buffer full, cbuf=0x%p, ib_in=%d\n", + panic( "pcibr intr circular buffer full, cbuf=0x%p, ib_in=%d\n", (void *)cbuf, cbuf->ib_in); cbuf->ib_cbuf[cbuf->ib_in] = wrap; cbuf->ib_in = in; - mutex_spinunlock(&cbuf->ib_lock, s); + spin_unlock(&cbuf->ib_lock); return; } /* + * 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 +265,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; @@ -248,7 +340,7 @@ pcibr_intr->bi_mustruncpu = CPU_NONE; pcibr_intr->bi_ibuf.ib_in = 0; pcibr_intr->bi_ibuf.ib_out = 0; - mutex_spinlock_init(&pcibr_intr->bi_ibuf.ib_lock); + spin_lock_init(&pcibr_intr->bi_ibuf.ib_lock); pcibr_int_bits = pcibr_soft->bs_intr_bits((pciio_info_t)pcibr_info, lines, PCIBR_NUM_SLOTS(pcibr_soft)); @@ -498,25 +590,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 +667,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 +783,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 +791,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; @@ -772,7 +856,7 @@ 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"); + panic("PCI Bridge interrupt targetting error\n"); } } @@ -780,9 +864,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 +923,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 +1038,7 @@ * interrupt to avoid a potential deadlock situation. */ if (wrap->iw_hdlrcnt == 0) { - pcibr_force_interrupt(wrap); + pcibr_force_interrupt((pcibr_intr_t) wrap); } } Index: arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -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); @@ -523,14 +407,6 @@ while (*wrb_flush) ; } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - while (BRIDGE_REG_GET32((wrb_flush))); - } else { - while (*wrb_flush) - ; - } - } return(0); } @@ -546,7 +422,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 +629,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 +678,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 +692,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 +733,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 +771,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); Index: arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c 4 Aug 2004 01:21:34 -0000 1.2 @@ -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 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -28,55 +29,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 .... */ @@ -99,6 +89,8 @@ int max_readcount_to_bufsize[MAX_READCNT_TABLE] = {512, 1024, 2048, 4096 }; +#define COPYOUT(a, b, c) copy_to_user(b,a,c) + /*========================================================================== * BRIDGE PCI SLOT RELATED IOCTLs */ @@ -111,7 +103,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 +119,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 +157,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 +181,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 +266,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 +277,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,10 +323,8 @@ 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); + slotp = snia_kmem_zalloc(sizeof(*slotp)); if (slotp == NULL) { return(ENOMEM); } @@ -368,11 +344,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 +426,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 +452,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 +500,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 +511,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 +534,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 +553,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 +581,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 +630,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 +683,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 +701,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 +717,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 +725,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 +787,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 +838,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 +864,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 +872,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 +884,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 +909,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 +920,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 +940,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 +1076,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 +1129,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 +1155,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 +1188,24 @@ continue; /* already allocated */ } + align = (win) ? size : align_slot; + + if (align < PAGE_SIZE) + align = PAGE_SIZE; /* 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 +1219,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 +1233,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 +1261,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 +1287,7 @@ } pcibr_info->f_rbase = base; pcibr_info->f_rsize = size; - + /* * if necessary, update the board's * command register to enable decoding @@ -1449,7 +1301,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 +1315,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 +1323,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 +1335,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 +1377,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 +1386,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 +1455,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 +1488,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 +1504,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 +1569,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 +1577,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 +1652,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 +1691,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 +1700,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 +1729,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. @@ -1960,7 +1742,6 @@ { int rv; picreg_t p_old_enable = (picreg_t)0, p_new_enable; - extern int badaddr_val(volatile void *, int, volatile void *); p_old_enable = bridge->p_int_enable_64; p_new_enable = p_old_enable & ~(BRIDGE_IMR_PCI_MST_TIMEOUT | PIC_ISR_PCIX_MTOUT); @@ -1973,7 +1754,7 @@ bridge->p_int_rst_stat_64 = (BRIDGE_IRR_PCI_GRP_CLR | PIC_PCIX_GRP_CLR); (void) bridge->b_wid_tflush; /* flushbus */ } - rv = badaddr_val((void *) cfg, 4, valp); + rv = snia_badaddr_val((void *) cfg, 4, valp); if (bridge->p_err_int_view_64 & (BRIDGE_ISR_PCI_MST_TIMEOUT | PIC_ISR_PCIX_MTOUT)) { bridge->p_int_rst_stat_64 = BRIDGE_IRR_MULTI_CLR; rv = 1; /* unoccupied slot */ @@ -1984,57 +1765,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 +1776,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 +1806,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 +1869,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 +1914,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; Index: arch/ia64/sn/kernel/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/kernel/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/kernel/Makefile 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/kernel/Makefile 4 Aug 2004 01:25:44 -0000 1.2 @@ -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,14 @@ 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 = bte.o idle.o irq.o mca.o probe.o setup.o \ + sn_ivt.o sn2/sn2.o sv.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 Index: arch/ia64/sn/kernel/bte.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/kernel/bte.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/kernel/bte.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/kernel/bte.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -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(ia64_tpa(bte->most_rcnt_na))))); + HUB_S(BTEREG_NOTIF_ADDR, (TO_PHYS(ia64_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), + ia64_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); + ia64_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]); + } } Index: arch/ia64/sn/kernel/bte_regr_test.c =================================================================== RCS file: arch/ia64/sn/kernel/bte_regr_test.c diff -N arch/ia64/sn/kernel/bte_regr_test.c --- arch/ia64/sn/kernel/bte_regr_test.c 22 Jul 2004 19:49:11 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); Index: arch/ia64/sn/kernel/iomv.c =================================================================== RCS file: arch/ia64/sn/kernel/iomv.c diff -N arch/ia64/sn/kernel/iomv.c --- arch/ia64/sn/kernel/iomv.c 22 Jul 2004 19:49:11 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); Index: arch/ia64/sn/kernel/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/kernel/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/kernel/irq.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/kernel/irq.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -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,30 @@ #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; + +struct pcibr_intr_list_t { + struct pcibr_intr_list_t *next; + pcibr_intr_t intr; +}; + +static struct pcibr_intr_list_t **pcibr_intr_list; @@ -88,49 +101,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<intr; + + if (intr == NULL) + return; + + if (IS_PIC_SOFT(intr->bi_soft) ) { + sn_shub_redirect_intr(intr, cpu); + // Defer TIO for now. + // } else if (IS_TIO_SOFT(intr->bi_soft) { + // sn_tio_redirect_intr(intr, cpu); + } else { + return; + } + (void) set_irq_affinity_info(irq, cpu_physical_id(cpu), redir); } -struct hw_interrupt_type irq_type_iosapic_level = { +struct hw_interrupt_type irq_type_sn = { "SN hub", sn_startup_irq, sn_shutdown_irq, @@ -204,21 +187,17 @@ }; -#define irq_type_sn irq_type_iosapic_level -struct irq_desc *_sn_irq_desc[NR_CPUS]; - struct irq_desc * sn_irq_desc(unsigned int irq) { - int cpu = irq >> 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 +205,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 +234,176 @@ 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 intr_test_reg_struct intr_test_registered[NR_IRQS]; +void +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 = intr->bi_cpu; + + 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 == 0 || 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 -intr_test_handle_timer(unsigned long data) { +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 */ Index: arch/ia64/sn/kernel/llsc4.c =================================================================== RCS file: arch/ia64/sn/kernel/llsc4.c diff -N arch/ia64/sn/kernel/llsc4.c --- arch/ia64/sn/kernel/llsc4.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); - Index: arch/ia64/sn/kernel/machvec.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/kernel/machvec.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/kernel/machvec.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/sn/kernel/machvec.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -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 Index: arch/ia64/sn/kernel/mca.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/kernel/mca.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/kernel/mca.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/kernel/mca.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -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 @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include #include @@ -53,6 +55,41 @@ struct timer_list sn_cpei_timer; void sn_init_cpei_timer(void); +/* Printing oemdata from mca uses data that is not passed through SAL, it is + * global. Only one user at a time. + */ +static DECLARE_MUTEX(sn_oemdata_mutex); +static u8 **sn_oemdata; +static u64 *sn_oemdata_size, sn_oemdata_bufsize; + +/* Called as the "printk" routine via sn_platform_plat_specific_err_print, + * ia64_sn_plat_specific_err_print through SAL to print_hook. It only handles + * a print of '"%s", buf'. buf is appended to sn_oemdata, resizing as required. + */ +static int +sn_oemdata_print(const char *fmt, ...) +{ + va_list args; + char *buf; + int len; + va_start(args, fmt); + buf = va_arg(args, char *); + va_end(args); + len = strlen(buf); + while (*sn_oemdata_size + len + 1 > sn_oemdata_bufsize) { + u8 *newbuf = vmalloc(sn_oemdata_bufsize += 1000); + if (!newbuf) { + printk(KERN_ERR "%s: unable to extend sn_oemdata\n", __FUNCTION__); + return 0; + } + memcpy(newbuf, *sn_oemdata, *sn_oemdata_size); + vfree(*sn_oemdata); + *sn_oemdata = newbuf; + } + memcpy(*sn_oemdata + *sn_oemdata_size, buf, len + 1); + *sn_oemdata_size += len; + return len; +} /* * print_hook @@ -86,25 +123,11 @@ newline = (p != 0); va_end(args); - printk("%s", buf); + sn_oemdata_print("%s", buf); /* args must be '"%s", buf' */ return len; } - -/* - * ia64_sn2_platform_plat_specific_err_print - * - * Called by the MCA handler to log platform-specific errors. - */ -void -ia64_sn2_platform_plat_specific_err_print(int header_len, int sect_len, u8 *p_data, prfunc_t prfunc) -{ - ia64_sn_plat_specific_err_print(print_hook, p_data - sect_len); -} - - - static void sn_cpei_handler(int irq, void *devid, struct pt_regs *regs) { @@ -123,9 +146,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 @@ -135,26 +156,41 @@ add_timer(&sn_cpei_timer); } +static int +sn_platform_plat_specific_err_print(const u8 *sect_header, u8 **oemdata, u64 *oemdata_size) +{ + sal_log_plat_specific_err_info_t *psei = (sal_log_plat_specific_err_info_t *)sect_header; + if (!psei->valid.oem_data) + return 0; + down(&sn_oemdata_mutex); + sn_oemdata = oemdata; + sn_oemdata_size = oemdata_size; + ia64_sn_plat_specific_err_print(print_hook, (char *)psei); + up(&sn_oemdata_mutex); + return 0; +} +/* Callback when userspace salinfo wants to decode oem data via the platform + * kernel and/or prom. + */ +int sn_salinfo_platform_oemdata(const u8 *sect_header, u8 **oemdata, u64 *oemdata_size) +{ + efi_guid_t guid = *(efi_guid_t *)sect_header; + *oemdata_size = 0; + sn_oemdata_bufsize = 0; + vfree(*oemdata); + *oemdata = NULL; + if (efi_guidcmp(guid, SAL_PLAT_SPECIFIC_ERR_SECT_GUID) == 0) + return sn_platform_plat_specific_err_print(sect_header, oemdata, oemdata_size); + return 0; +} +static int __init sn_salinfo_init(void) +{ + salinfo_platform_oemdata = &sn_salinfo_platform_oemdata; + return 0; +} -#ifdef ajmtestceintr - -struct timer_list sn_ce_timer; - -void -sn_ce_timer_handler(long dummy) { - unsigned long *pi_ce_error_inject_reg = 0xc00000092fffff00; +module_init(sn_salinfo_init) - *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 */ Index: arch/ia64/sn/kernel/misctest.c =================================================================== RCS file: arch/ia64/sn/kernel/misctest.c diff -N arch/ia64/sn/kernel/misctest.c --- arch/ia64/sn/kernel/misctest.c 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; - -} Index: arch/ia64/sn/kernel/probe.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/kernel/probe.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/kernel/probe.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/sn/kernel/probe.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -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 Index: arch/ia64/sn/kernel/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/kernel/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/kernel/setup.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/kernel/setup.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -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 @@ -56,8 +56,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -69,21 +71,32 @@ #include #include #include - -#ifdef CONFIG_IA64_SGI_SN2 #include -#endif + +#define pxm_to_nasid(pxm) (((pxm)<<1) | (get_nasid() & ~0x1ff)) + +#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 init_platform_hubinfo(nodepda_t **nodepdaindr); +extern void (*ia64_mark_idle)(int); +extern void (*ia64_platform_timer_extras)(void); +extern void sn_timer_interrupt_extras(void); +extern void snidle(int); +extern unsigned char acpi_kbd_controller_present; 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]; + +int numionodes; /* * 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 +105,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 +139,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 +166,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 +189,118 @@ } 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; +} + +/* + * SN2 requires very slightly different alternate data-TLB miss handle than what + * the mainline linux kernel provides. At some point this approach could be used + * to allow the use of the low-memory thrown away on other platforms when VGA is + * present. + * + * On SN2 we want to load small TCs for granule-0 (and aliases of) faulting + * addresses. The details of this are more sublte than at which they first + * appear. + */ +static void __init +sn2_replace_ivt(void) +{ + extern unsigned char alt_dtlb_miss[], ia64_ivt_page_fault[]; + extern unsigned char sn2_alt_dtlb_miss[], sn2_alt_dtlb_miss_end[]; + extern unsigned char sn2_alt_dtlb_miss_patch1[]; + + unsigned char *s, *d; + u64 *p; + u64 len = (u64)sn2_alt_dtlb_miss_end - (u64)sn2_alt_dtlb_miss; + u64 broffs = (ia64_ivt_page_fault - alt_dtlb_miss) - (sn2_alt_dtlb_miss_patch1 - sn2_alt_dtlb_miss); + u64 psr; + int i; + + /* printk(KERN_DEBUG "Replacing alternate data-TLB miss handler.\n"); */ + + /* Check the code isn't too large */ + if (len > 1024) { + printk(KERN_ERR "SGI: Specific alt_dtlb_misse too large! Not replacing\n"); + return; + } + + /* check the offset is sane (should always be) */ + if ((broffs>>4) + (1<<20) >= (1<<21)) { + printk(KERN_ERR "SGI: IVT patch ivt offset %ld invalid! Not replacing!\n", broffs); + return; + } + + /* 2nd half of bundle to patch (has slot 2) */ + p = (u64*)sn2_alt_dtlb_miss_patch1 + 1; + /* patch the offset into slot 2 (imm20b + s) */ + *p = (*p & ~(0x8fffff000000000)) | ((broffs & 0x1000000) << 35) | ((broffs & 0x0fffff0) << 32); + + /* don't want any interrupts when doing this */ + psr = ia64_clear_ic(); + + /* copy over the existing code, flush i-cache as required */ + d = alt_dtlb_miss; + s = sn2_alt_dtlb_miss; + for (i=0; ithread.flags |= IA64_THREAD_FPEMU_NOPRINT; + ia64_platform_timer_extras = &sn_timer_interrupt_extras; + + sn_timer_init(); } /** @@ -324,6 +436,7 @@ sn_init_pdas(char **cmdline_p) { cnodeid_t cnode; + void scan_for_ionodes(void); /* * Make sure that the PDA fits entirely in the same page as the @@ -332,25 +445,33 @@ 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; cnodepernode_pdaindr, nodepdaindr, sizeof(nodepdaindr)); @@ -361,8 +482,16 @@ */ for (cnode = 0; cnode < numnodes; cnode++) { init_platform_nodepda(nodepdaindr[cnode], cnode); + spin_lock_init(&nodepdaindr[cnode]->bist_lock); bte_init_node (nodepdaindr[cnode], cnode); } + + /* + * Handle TIO differently .. we do not do BTE init .. + */ + for (cnode = numnodes; cnode < numionodes; cnode++) { + init_platform_nodepda(nodepdaindr[cnode], cnode); + } } /** @@ -381,7 +510,8 @@ int cpuphyid; int nasid; int slice; - int cnode; + int cnode, i; + static int wars_have_been_checked = 0; /* * The boot cpu makes this call again after platform initialization is @@ -402,38 +532,44 @@ memset(&pda, 0, sizeof(pda)); pda.p_nodepda = nodepdaindr[cnode]; pda.led_address = (typeof(pda.led_address)) (LED0 + (slice<active_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 +578,33 @@ 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. +/* + * Scan klconfig for TIO's. Add the TIO nasids to the + * physical_node_map and the pda and increment numionodes. */ -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); +scan_for_ionodes() { + int nasid = 0; + lboard_t *brd; + + /* Scan all compute nodes. */ + for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid +=2) { + /* if there's no nasid, don't try to read the klconfig on the node */ + if (physical_node_map[nasid] == -1) continue; + brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_TIO); + while (brd) { + pda.cnodeid_to_nasid_table[numionodes] = brd->brd_nasid; + physical_node_map[brd->brd_nasid] = numionodes++; + brd = KLCF_NEXT(brd); + brd = find_lboard(brd, KLTYPE_TIO); } } -} - -#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 Index: arch/ia64/sn/kernel/sn_asm.S =================================================================== RCS file: arch/ia64/sn/kernel/sn_asm.S diff -N arch/ia64/sn/kernel/sn_asm.S --- arch/ia64/sn/kernel/sn_asm.S 22 Jul 2004 19:49:11 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: arch/ia64/sn/kernel/sn_ksyms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/kernel/sn_ksyms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/kernel/sn_ksyms.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/sn/kernel/sn_ksyms.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -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,25 @@ 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); Index: arch/ia64/sn/kernel/sv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/kernel/sv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/kernel/sv.c 22 Jul 2004 19:49:10 -0000 1.1 +++ arch/ia64/sn/kernel/sv.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -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 Index: arch/ia64/sn/kernel/sn1/Makefile =================================================================== RCS file: arch/ia64/sn/kernel/sn1/Makefile diff -N arch/ia64/sn/kernel/sn1/Makefile --- arch/ia64/sn/kernel/sn1/Makefile 22 Jul 2004 19:49:11 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: arch/ia64/sn/kernel/sn1/cache.c =================================================================== RCS file: arch/ia64/sn/kernel/sn1/cache.c diff -N arch/ia64/sn/kernel/sn1/cache.c --- arch/ia64/sn/kernel/sn1/cache.c 22 Jul 2004 19:49:11 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); -} Index: arch/ia64/sn/kernel/sn1/sn1_smp.c =================================================================== RCS file: arch/ia64/sn/kernel/sn1/sn1_smp.c diff -N arch/ia64/sn/kernel/sn1/sn1_smp.c --- arch/ia64/sn/kernel/sn1/sn1_smp.c 22 Jul 2004 19:49:11 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 */ Index: arch/ia64/sn/kernel/sn1/synergy.c =================================================================== RCS file: arch/ia64/sn/kernel/sn1/synergy.c diff -N arch/ia64/sn/kernel/sn1/synergy.c --- arch/ia64/sn/kernel/sn1/synergy.c 22 Jul 2004 19:49:11 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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++; -} Index: arch/ia64/sn/kernel/sn2/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/kernel/sn2/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/kernel/sn2/Makefile 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/sn/kernel/sn2/Makefile 4 Aug 2004 01:25:44 -0000 1.2 @@ -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 timer_interrupt.o include $(TOPDIR)/Rules.make Index: arch/ia64/sn/kernel/sn2/cache.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/kernel/sn2/cache.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/kernel/sn2/cache.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/sn/kernel/sn2/cache.c 4 Aug 2004 01:25:44 -0000 1.2 @@ -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. * */ @@ -23,7 +23,18 @@ void sn_flush_all_caches(long flush_addr, long bytes) { + /* + * The following double call to flush_icache_range has + * the following effect which is required: + * + * The first flush_icache_range ensures the fc() address + * is visible on the FSB. The NUMA controller however has + * not necessarily forwarded the fc() request to all other + * NUMA controllers. The second call will stall + * at the associated fc() instruction until the first + * has been forwarded to all other NUMA controllers. + */ flush_icache_range(flush_addr, flush_addr+bytes); + flush_icache_range(flush_addr, flush_addr+bytes); + mb(); } - - Index: arch/ia64/sn/kernel/sn2/iomv.c =================================================================== RCS file: arch/ia64/sn/kernel/sn2/iomv.c diff -N arch/ia64/sn/kernel/sn2/iomv.c --- arch/ia64/sn/kernel/sn2/iomv.c 22 Jul 2004 19:49:11 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); -} Index: arch/ia64/sn/kernel/sn2/ptc_deadlock.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/kernel/sn2/ptc_deadlock.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/kernel/sn2/ptc_deadlock.S 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/sn/kernel/sn2/ptc_deadlock.S 4 Aug 2004 01:25:45 -0000 1.2 @@ -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 Index: arch/ia64/sn/kernel/sn2/sn2_smp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/kernel/sn2/sn2_smp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/kernel/sn2/sn2_smp.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/sn/kernel/sn2/sn2_smp.c 4 Aug 2004 01:25:45 -0000 1.2 @@ -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); Index: arch/ia64/sn/kernel/sn2/sn_proc_fs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/sn/kernel/sn2/sn_proc_fs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/sn/kernel/sn2/sn_proc_fs.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/sn/kernel/sn2/sn_proc_fs.c 4 Aug 2004 01:25:45 -0000 1.2 @@ -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,10 +31,12 @@ * http://oss.sgi.com/projects/GenInfo/NoticeExplan */ #include +#include #ifdef CONFIG_PROC_FS #include #include +#include static int partition_id_read_proc(char *page, char **start, off_t off, @@ -43,7 +45,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 +98,153 @@ } } +// 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; + } +} + +#define SHUB_MAX_VERSION 3 +static struct proc_dir_entry **proc_entries; +static char* shub_revision[SHUB_MAX_VERSION+1] = { + "unknown", + "1.0", + "1.1", + "1.2" +}; + +static int +read_shub_info_entry(char* page, char **start, off_t off, int count, int *eof, + void* data) { + unsigned long id; + int rev; + int nasid = (long) data; /* Data contains NASID of this node */ + int len = 0; + + id = REMOTE_HUB_L(nasid, SH_SHUB_ID); + rev = (id & SH_SHUB_ID_REVISION_MASK) >> SH_SHUB_ID_REVISION_SHFT; + len += sprintf(&page[len], "type : SHub\n"); + len += sprintf(&page[len], "revision : %s\n", + (rev <= SHUB_MAX_VERSION) ? shub_revision[rev] : "unknown"); + len += sprintf(&page[len], "nasid : %d\n", nasid); + + return len; +} + +static void +register_sn_nodes(void) { + struct proc_dir_entry **entp; + cnodeid_t cnodeid; + nasid_t nasid; + char name[11]; + + if (!sgi_proc_dir) { + sgi_proc_dir = proc_mkdir("sgi_sn", 0); + } + + proc_entries = kmalloc(numnodes * sizeof(struct proc_dir_entry *), + GFP_KERNEL); + + for (cnodeid = 0, entp = proc_entries; + cnodeid < numnodes; + cnodeid++, entp++) { + sprintf(name, "node%d", cnodeid); + *entp = proc_mkdir(name, sgi_proc_dir); + nasid = cnodeid_to_nasid(cnodeid); + create_proc_read_entry( + "hubinfo", 0, *entp, read_shub_info_entry, + (void*) (long) nasid); + } +} + +void +register_sn_procfs(void) { + register_sn_partition_id(); + register_sn_serial_numbers(); + register_sn_force_interrupt(); + register_sn_linkstats(); + register_sn_nodes(); +} + #endif /* CONFIG_PROC_FS */ Index: arch/ia64/sn/tools/make_textsym =================================================================== RCS file: arch/ia64/sn/tools/make_textsym diff -N arch/ia64/sn/tools/make_textsym --- arch/ia64/sn/tools/make_textsym 22 Jul 2004 19:49:10 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: arch/ia64/tools/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/tools/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/tools/Makefile 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/tools/Makefile 4 Aug 2004 01:25:45 -0000 1.2 @@ -5,6 +5,7 @@ all: mrproper: clean + rm -f $(TARGET) clean: rm -f print_offsets.s print_offsets offsets.h @@ -33,7 +34,7 @@ comma := , -print_offsets: print_offsets.c FORCE_RECOMPILE +print_offsets: emptyoffsets print_offsets.c FORCE_RECOMPILE $(CC) $(CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) print_offsets.c -o $@ FORCE_RECOMPILE: @@ -43,9 +44,20 @@ offsets.h: print_offsets.s $(AWK) -f print_offsets.awk $^ > $@ -print_offsets.s: print_offsets.c +print_offsets.s: emptyoffsets print_offsets.c $(CC) $(CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -S print_offsets.c -o $@ endif +# +# The TARGET offsets.h is included by ptrace.h, which is included by +# print_offsets.c, so can't compile print_offsets.c to create offsets.h +# until we already have offsets.h. Break the chicken-and-egg cycle by +# creating a dummy offsets.h with sufficient define's to bootstrap +# the first compilation of print_offsets.c. +# + +emptyoffsets: + test -f ${TARGET} || echo '#define IA64_TASK_THREAD_OFFSET 0' > ${TARGET} + .PHONY: all modules modules_install Index: arch/ia64/tools/print_offsets.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ia64/tools/print_offsets.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ia64/tools/print_offsets.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/ia64/tools/print_offsets.c 4 Aug 2004 01:25:45 -0000 1.2 @@ -1,6 +1,7 @@ /* * Utility to generate asm-ia64/offsets.h. * + * Copyright (C) 2002-2003 Fenghua Yu * Copyright (C) 1999-2001 Hewlett-Packard Co * David Mosberger-Tang * @@ -10,7 +11,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 @@ -20,6 +21,7 @@ #include #include #include +#include #include "../kernel/sigframe.h" @@ -63,6 +65,14 @@ #endif { "IA64_TASK_PID_OFFSET", offsetof (struct task_struct, pid) }, { "IA64_TASK_MM_OFFSET", offsetof (struct task_struct, mm) }, + { "IA64_PT_REGS_B6_OFFSET", offsetof (struct pt_regs, b6) }, + { "IA64_PT_REGS_B7_OFFSET", offsetof (struct pt_regs, b7) }, + { "IA64_PT_REGS_AR_CSD_OFFSET", offsetof (struct pt_regs, ar_csd) }, + { "IA64_PT_REGS_AR_SSD_OFFSET", offsetof (struct pt_regs, ar_ssd) }, + { "IA64_PT_REGS_R8_OFFSET", offsetof (struct pt_regs, r8) }, + { "IA64_PT_REGS_R9_OFFSET", offsetof (struct pt_regs, r9) }, + { "IA64_PT_REGS_R10_OFFSET", offsetof (struct pt_regs, r10) }, + { "IA64_PT_REGS_R11_OFFSET", offsetof (struct pt_regs, r11) }, { "IA64_PT_REGS_CR_IPSR_OFFSET", offsetof (struct pt_regs, cr_ipsr) }, { "IA64_PT_REGS_CR_IIP_OFFSET", offsetof (struct pt_regs, cr_iip) }, { "IA64_PT_REGS_CR_IFS_OFFSET", offsetof (struct pt_regs, cr_ifs) }, @@ -72,19 +82,16 @@ { "IA64_PT_REGS_AR_RNAT_OFFSET", offsetof (struct pt_regs, ar_rnat) }, { "IA64_PT_REGS_AR_BSPSTORE_OFFSET",offsetof (struct pt_regs, ar_bspstore) }, { "IA64_PT_REGS_PR_OFFSET", offsetof (struct pt_regs, pr) }, - { "IA64_PT_REGS_B6_OFFSET", offsetof (struct pt_regs, b6) }, + { "IA64_PT_REGS_B0_OFFSET", offsetof (struct pt_regs, b0) }, { "IA64_PT_REGS_LOADRS_OFFSET", offsetof (struct pt_regs, loadrs) }, { "IA64_PT_REGS_R1_OFFSET", offsetof (struct pt_regs, r1) }, - { "IA64_PT_REGS_R2_OFFSET", offsetof (struct pt_regs, r2) }, - { "IA64_PT_REGS_R3_OFFSET", offsetof (struct pt_regs, r3) }, { "IA64_PT_REGS_R12_OFFSET", offsetof (struct pt_regs, r12) }, { "IA64_PT_REGS_R13_OFFSET", offsetof (struct pt_regs, r13) }, - { "IA64_PT_REGS_R14_OFFSET", offsetof (struct pt_regs, r14) }, + { "IA64_PT_REGS_AR_FPSR_OFFSET", offsetof (struct pt_regs, ar_fpsr) }, { "IA64_PT_REGS_R15_OFFSET", offsetof (struct pt_regs, r15) }, - { "IA64_PT_REGS_R8_OFFSET", offsetof (struct pt_regs, r8) }, - { "IA64_PT_REGS_R9_OFFSET", offsetof (struct pt_regs, r9) }, - { "IA64_PT_REGS_R10_OFFSET", offsetof (struct pt_regs, r10) }, - { "IA64_PT_REGS_R11_OFFSET", offsetof (struct pt_regs, r11) }, + { "IA64_PT_REGS_R14_OFFSET", offsetof (struct pt_regs, r14) }, + { "IA64_PT_REGS_R2_OFFSET", offsetof (struct pt_regs, r2) }, + { "IA64_PT_REGS_R3_OFFSET", offsetof (struct pt_regs, r3) }, { "IA64_PT_REGS_R16_OFFSET", offsetof (struct pt_regs, r16) }, { "IA64_PT_REGS_R17_OFFSET", offsetof (struct pt_regs, r17) }, { "IA64_PT_REGS_R18_OFFSET", offsetof (struct pt_regs, r18) }, @@ -102,21 +109,18 @@ { "IA64_PT_REGS_R30_OFFSET", offsetof (struct pt_regs, r30) }, { "IA64_PT_REGS_R31_OFFSET", offsetof (struct pt_regs, r31) }, { "IA64_PT_REGS_AR_CCV_OFFSET", offsetof (struct pt_regs, ar_ccv) }, - { "IA64_PT_REGS_AR_FPSR_OFFSET", offsetof (struct pt_regs, ar_fpsr) }, - { "IA64_PT_REGS_B0_OFFSET", offsetof (struct pt_regs, b0) }, - { "IA64_PT_REGS_B7_OFFSET", offsetof (struct pt_regs, b7) }, { "IA64_PT_REGS_F6_OFFSET", offsetof (struct pt_regs, f6) }, { "IA64_PT_REGS_F7_OFFSET", offsetof (struct pt_regs, f7) }, { "IA64_PT_REGS_F8_OFFSET", offsetof (struct pt_regs, f8) }, { "IA64_PT_REGS_F9_OFFSET", offsetof (struct pt_regs, f9) }, + { "IA64_PT_REGS_F10_OFFSET", offsetof (struct pt_regs, f10) }, + { "IA64_PT_REGS_F11_OFFSET", offsetof (struct pt_regs, f11) }, { "IA64_SWITCH_STACK_CALLER_UNAT_OFFSET", offsetof (struct switch_stack, caller_unat) }, { "IA64_SWITCH_STACK_AR_FPSR_OFFSET", offsetof (struct switch_stack, ar_fpsr) }, { "IA64_SWITCH_STACK_F2_OFFSET", offsetof (struct switch_stack, f2) }, { "IA64_SWITCH_STACK_F3_OFFSET", offsetof (struct switch_stack, f3) }, { "IA64_SWITCH_STACK_F4_OFFSET", offsetof (struct switch_stack, f4) }, { "IA64_SWITCH_STACK_F5_OFFSET", offsetof (struct switch_stack, f5) }, - { "IA64_SWITCH_STACK_F10_OFFSET", offsetof (struct switch_stack, f10) }, - { "IA64_SWITCH_STACK_F11_OFFSET", offsetof (struct switch_stack, f11) }, { "IA64_SWITCH_STACK_F12_OFFSET", offsetof (struct switch_stack, f12) }, { "IA64_SWITCH_STACK_F13_OFFSET", offsetof (struct switch_stack, f13) }, { "IA64_SWITCH_STACK_F14_OFFSET", offsetof (struct switch_stack, f14) }, @@ -176,6 +180,7 @@ { "IA64_CPU_IRQ_COUNT_OFFSET", offsetof (struct cpuinfo_ia64, irq_stat.f.irq_count) }, { "IA64_CPU_BH_COUNT_OFFSET", offsetof (struct cpuinfo_ia64, irq_stat.f.bh_count) }, { "IA64_CPU_PHYS_STACKED_SIZE_P8_OFFSET",offsetof (struct cpuinfo_ia64, phys_stacked_size_p8)}, + { "IA64_MCA_TLB_INFO_SIZE", sizeof (struct ia64_mca_tlb_info) }, }; static const char *tabs = "\t\t\t\t\t\t\t\t\t\t"; Index: arch/m68k/config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/config.in 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/m68k/config.in 4 Aug 2004 01:25:45 -0000 1.2 @@ -186,7 +186,6 @@ 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 @@ -228,7 +227,7 @@ if [ "$CONFIG_AMIGA" = "y" ]; then dep_tristate 'A3000 WD33C93A support' CONFIG_A3000_SCSI $CONFIG_SCSI if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'A4000T SCSI support (EXPERIMENTAL)' CONFIG_A4000T_SCSI + bool 'Amiga NCR53c710 SCSI support (EXPERIMENTAL)' CONFIG_SCSI_AMIGA7XX fi fi if [ "$CONFIG_ZORRO" = "y" ]; then @@ -240,12 +239,8 @@ dep_tristate 'Blizzard 1230IV/1260 SCSI support' CONFIG_BLZ1230_SCSI $CONFIG_SCSI dep_tristate 'Fastlane SCSI support' CONFIG_FASTLANE_SCSI $CONFIG_SCSI if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'A4091 SCSI support (EXPERIMENTAL)' CONFIG_A4091_SCSI - bool 'WarpEngine SCSI support (EXPERIMENTAL)' CONFIG_WARPENGINE_SCSI - bool 'Blizzard PowerUP 603e+ SCSI (EXPERIMENTAL)' CONFIG_BLZ603EPLUS_SCSI dep_tristate 'BSC Oktagon SCSI support (EXPERIMENTAL)' CONFIG_OKTAGON_SCSI $CONFIG_SCSI # bool 'Cyberstorm Mk III SCSI support (EXPERIMENTAL)' CONFIG_CYBERSTORMIII_SCSI -# bool 'GVP Turbo 040/060 SCSI support (EXPERIMENTAL)' CONFIG_GVP_TURBO_SCSI fi fi if [ "$CONFIG_ATARI" = "y" ]; then @@ -321,9 +316,9 @@ tristate ' EQL (serial line load balancing) support' CONFIG_EQUALIZER if [ "$CONFIG_ZORRO" = "y" ]; then tristate ' Ariadne support' CONFIG_ARIADNE - tristate ' Ariadne II support' CONFIG_ARIADNE2 tristate ' A2065 support' CONFIG_A2065 tristate ' Hydra support' CONFIG_HYDRA + tristate ' Zorro NS8390-based Ethernet support' CONFIG_ZORRO8390 fi if [ "$CONFIG_AMIGA_PCMCIA" = "y" ]; then tristate ' PCMCIA NE2000 support' CONFIG_APNE @@ -514,14 +509,10 @@ bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT bool ' Software Watchdog' CONFIG_SOFT_WATCHDOG fi -if [ "$CONFIG_ATARI" = "y" ]; then - bool 'Enhanced Real Time Clock Support' CONFIG_RTC +if [ "$CONFIG_SUN3" = "y" ]; then + define_bool CONFIG_GEN_RTC y else - if [ "$CONFIG_SUN3" = "y" ]; then - define_bool CONFIG_GEN_RTC y - else - tristate 'Generic /dev/rtc emulation' CONFIG_GEN_RTC - fi + tristate 'Generic /dev/rtc emulation' CONFIG_GEN_RTC fi if [ "$CONFIG_GEN_RTC" != "n" ]; then bool ' Extended RTC operation' CONFIG_GEN_RTC_X @@ -561,6 +552,9 @@ bool ' Verbose BUG() reporting' CONFIG_DEBUG_BUGVERBOSE fi +int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 + endmenu +source crypto/Config.in source lib/Config.in Index: arch/m68k/defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/defconfig 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/m68k/defconfig 4 Aug 2004 01:25:45 -0000 1.2 @@ -124,7 +124,6 @@ # 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 # @@ -177,7 +176,7 @@ # CONFIG_PPP is not set # CONFIG_EQUALIZER is not set # CONFIG_ARIADNE is not set -# CONFIG_ARIADNE2 is not set +# CONFIG_ZORRO8390 is not set # CONFIG_A2065 is not set # CONFIG_HYDRA is not set Index: arch/m68k/amiga/config.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/amiga/config.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/amiga/config.c 22 Jul 2004 19:49:12 -0000 1.1 +++ arch/m68k/amiga/config.c 4 Aug 2004 01:25:45 -0000 1.2 @@ -877,7 +877,7 @@ savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res); savekmsg->magic1 = SAVEKMSG_MAGIC1; savekmsg->magic2 = SAVEKMSG_MAGIC2; - savekmsg->magicptr = virt_to_phys(savekmsg); + savekmsg->magicptr = ZTWO_PADDR(savekmsg); savekmsg->size = 0; } Index: arch/m68k/apollo/config.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/apollo/config.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/apollo/config.c 22 Jul 2004 19:49:12 -0000 1.1 +++ arch/m68k/apollo/config.c 4 Aug 2004 01:25:45 -0000 1.2 @@ -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; Index: arch/m68k/apollo/dn_ints.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/apollo/dn_ints.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/apollo/dn_ints.c 22 Jul 2004 19:49:12 -0000 1.1 +++ arch/m68k/apollo/dn_ints.c 4 Aug 2004 01:25:45 -0000 1.2 @@ -43,7 +43,7 @@ int dn_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) { if((irq<0) || (irq>15)) { - printk("Trying to request illegal IRQ\n"); + printk("Trying to request invalid IRQ\n"); return -ENXIO; } @@ -69,7 +69,7 @@ void dn_free_irq(unsigned int irq, void *dev_id) { if((irq<0) || (irq>15)) { - printk("Trying to free illegal IRQ\n"); + printk("Trying to free invalid IRQ\n"); return ; } Index: arch/m68k/atari/time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/atari/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/atari/time.c 22 Jul 2004 19:49:12 -0000 1.1 +++ arch/m68k/atari/time.c 4 Aug 2004 01:25:45 -0000 1.2 @@ -16,7 +16,7 @@ #include #include -#include +#include void __init atari_sched_init(void (*timer_routine)(int, void *, struct pt_regs *)) Index: arch/m68k/bvme6000/rtc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/bvme6000/rtc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/bvme6000/rtc.c 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/m68k/bvme6000/rtc.c 4 Aug 2004 01:25:45 -0000 1.2 @@ -54,6 +54,7 @@ /* Ensure clock and real-time-mode-register are accessible */ msr = rtc->msr & 0xc0; rtc->msr = 0x40; + memset(&wtime, 0, sizeof(struct rtc_time)); do { wtime.tm_sec = BCD2BIN(rtc->bcd_sec); wtime.tm_min = BCD2BIN(rtc->bcd_min); Index: arch/m68k/kernel/m68k_ksyms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/kernel/m68k_ksyms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/kernel/m68k_ksyms.c 22 Jul 2004 19:49:12 -0000 1.1 +++ arch/m68k/kernel/m68k_ksyms.c 4 Aug 2004 01:25:45 -0000 1.2 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include asmlinkage long long __ashldi3 (long long, int); asmlinkage long long __ashrdi3 (long long, int); @@ -44,10 +46,12 @@ 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); +#ifndef mm_cachebits +EXPORT_SYMBOL(mm_cachebits); +#endif #endif /* !CONFIG_SUN3 */ EXPORT_SYMBOL(m68k_debug_device); EXPORT_SYMBOL(mach_hwclk); @@ -66,6 +70,8 @@ #ifdef CONFIG_VME EXPORT_SYMBOL(vme_brdtype); #endif +EXPORT_SYMBOL(hwreg_present); +EXPORT_SYMBOL(hwreg_write); /* Networking helper routines. */ EXPORT_SYMBOL(csum_partial_copy); Index: arch/m68k/kernel/ptrace.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/kernel/ptrace.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/kernel/ptrace.c 22 Jul 2004 19:49:12 -0000 1.1 +++ arch/m68k/kernel/ptrace.c 4 Aug 2004 01:25:45 -0000 1.2 @@ -133,14 +133,9 @@ 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 != current) + + ret = ptrace_check_attach(child, request == PTRACE_KILL); + if (ret < 0) goto out_tsk; switch (request) { Index: arch/m68k/kernel/traps.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/kernel/traps.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/kernel/traps.c 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/m68k/kernel/traps.c 4 Aug 2004 01:25:45 -0000 1.2 @@ -446,7 +446,7 @@ /* sun3 version of bus_error030 */ -extern inline void bus_error030 (struct frame *fp) +static inline void bus_error030(struct frame *fp) { unsigned char buserr_type = sun3_get_buserr (); unsigned long addr, errorcode; @@ -574,12 +574,9 @@ unsigned short mmusr; unsigned long addr, errorcode; unsigned short ssw = fp->un.fmtb.ssw; - int user_space_fault = 1; #if DEBUG unsigned long desc; -#endif -#if DEBUG printk ("pid = %x ", current->pid); printk ("SSW=%#06x ", ssw); @@ -596,128 +593,116 @@ space_names[ssw & DFC], fp->ptregs.pc); #endif - if (fp->ptregs.sr & PS_S) { - /* kernel fault must be a data fault to user space */ - if (! ((ssw & DF) && ((ssw & DFC) == USER_DATA))) { - /* instruction fault or kernel data fault! */ - if (ssw & (FC | FB)) - printk ("Instruction fault at %#010lx\n", - fp->ptregs.pc); - if (ssw & DF) { - printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n", - ssw & RW ? "read" : "write", - fp->un.fmtb.daddr, - space_names[ssw & DFC], fp->ptregs.pc); - } - printk ("BAD KERNEL BUSERR\n"); - die_if_kernel("Oops",&fp->ptregs,0); - force_sig(SIGKILL, current); - return; - } - } else { - /* user fault */ - if (!(ssw & (FC | FB)) && !(ssw & DF)) - /* not an instruction fault or data fault! BAD */ - panic ("USER BUSERR w/o instruction or data fault"); - user_space_fault = 1; -#if DEBUG - printk("User space bus-error\n"); -#endif - } - /* ++andreas: If a data fault and an instruction fault happen at the same time map in both pages. */ /* First handle the data fault, if any. */ - if (ssw & DF) - { - addr = fp->un.fmtb.daddr; + if (ssw & DF) { + addr = fp->un.fmtb.daddr; - mmusr = MMU_I; - if (user_space_fault) { #if DEBUG - asm volatile ("ptestr #1,%2@,#7,%0\n\t" - "pmove %/psr,%1@" - : "=a&" (desc) - : "a" (&temp), "a" (addr)); + asm volatile ("ptestr %3,%2@,#7,%0\n\t" + "pmove %%psr,%1@" + : "=a&" (desc) + : "a" (&temp), "a" (addr), "d" (ssw)); #else - asm volatile ("ptestr #1,%1@,#7\n\t" - "pmove %/psr,%0@" - : : "a" (&temp), "a" (addr)); -#endif - mmusr = temp; - } - -#if DEBUG - printk ("mmusr is %#x for addr %#lx in task %p\n", - mmusr, addr, current); - printk ("descriptor address is %#lx, contents %#lx\n", - __va(desc), *(unsigned long *)__va(desc)); + asm volatile ("ptestr %2,%1@,#7\n\t" + "pmove %%psr,%0@" + : : "a" (&temp), "a" (addr), "d" (ssw)); #endif + mmusr = temp; - errorcode = (mmusr & MMU_I) ? 0 : 1; - if (!(ssw & RW) || (ssw & RM)) - errorcode |= 2; - - if (mmusr & (MMU_I | MMU_WP)) { - /* Don't try to do anything further if an exception was - handled. */ - if (do_page_fault (&fp->ptregs, addr, errorcode) < 0) +#if DEBUG + printk("mmusr is %#x for addr %#lx in task %p\n", + mmusr, addr, current); + printk("descriptor address is %#lx, contents %#lx\n", + __va(desc), *(unsigned long *)__va(desc)); +#endif + + errorcode = (mmusr & MMU_I) ? 0 : 1; + if (!(ssw & RW) || (ssw & RM)) + errorcode |= 2; + + if (mmusr & (MMU_I | MMU_WP)) { + if (ssw & 4) { + printk("Data %s fault at %#010lx in %s (pc=%#lx)\n", + ssw & RW ? "read" : "write", + fp->un.fmtb.daddr, + space_names[ssw & DFC], fp->ptregs.pc); + goto buserr; + } + /* Don't try to do anything further if an exception was + handled. */ + if (do_page_fault (&fp->ptregs, addr, errorcode) < 0) + return; + } else if (!(mmusr & MMU_I)) { + /* propably a 020 cas fault */ + if (!(ssw & RM)) + printk("unexpected bus error (%#x,%#x)\n", ssw, mmusr); + } else if (mmusr & (MMU_B|MMU_L|MMU_S)) { + printk("invalid %s access at %#lx from pc %#lx\n", + !(ssw & RW) ? "write" : "read", addr, + fp->ptregs.pc); + die_if_kernel("Oops",&fp->ptregs,mmusr); + force_sig(SIGSEGV, current); return; - } else if (mmusr & (MMU_B|MMU_L|MMU_S)) { - printk ("invalid %s access at %#lx from pc %#lx\n", - !(ssw & RW) ? "write" : "read", addr, - fp->ptregs.pc); - die_if_kernel("Oops",&fp->ptregs,mmusr); - force_sig(SIGSEGV, current); - return; - } else { + } else { #if 0 - static volatile long tlong; + static volatile long tlong; #endif - printk ("weird %s access at %#lx from pc %#lx (ssw is %#x)\n", - !(ssw & RW) ? "write" : "read", addr, - fp->ptregs.pc, ssw); - asm volatile ("ptestr #1,%1@,#0\n\t" - "pmove %/psr,%0@" - : /* no outputs */ - : "a" (&temp), "a" (addr)); - mmusr = temp; + printk("weird %s access at %#lx from pc %#lx (ssw is %#x)\n", + !(ssw & RW) ? "write" : "read", addr, + fp->ptregs.pc, ssw); + asm volatile ("ptestr #1,%1@,#0\n\t" + "pmove %%psr,%0@" + : /* no outputs */ + : "a" (&temp), "a" (addr)); + mmusr = temp; - printk ("level 0 mmusr is %#x\n", mmusr); + printk ("level 0 mmusr is %#x\n", mmusr); #if 0 - asm volatile ("pmove %/tt0,%0@" - : /* no outputs */ - : "a" (&tlong)); - printk ("tt0 is %#lx, ", tlong); - asm volatile ("pmove %/tt1,%0@" - : /* no outputs */ - : "a" (&tlong)); - printk ("tt1 is %#lx\n", tlong); + asm volatile ("pmove %%tt0,%0@" + : /* no outputs */ + : "a" (&tlong)); + printk("tt0 is %#lx, ", tlong); + asm volatile ("pmove %%tt1,%0@" + : /* no outputs */ + : "a" (&tlong)); + printk("tt1 is %#lx\n", tlong); #endif #if DEBUG - printk("Unknown SIGSEGV - 1\n"); + printk("Unknown SIGSEGV - 1\n"); #endif - die_if_kernel("Oops",&fp->ptregs,mmusr); - force_sig(SIGSEGV, current); - return; - } - - /* setup an ATC entry for the access about to be retried */ - if (!(ssw & RW)) - asm volatile ("ploadw %1,%0@" : /* no outputs */ - : "a" (addr), "d" (ssw)); - else - asm volatile ("ploadr %1,%0@" : /* no outputs */ - : "a" (addr), "d" (ssw)); - } + die_if_kernel("Oops",&fp->ptregs,mmusr); + force_sig(SIGSEGV, current); + return; + } + + /* setup an ATC entry for the access about to be retried */ + if (!(ssw & RW) || (ssw & RM)) + asm volatile ("ploadw %1,%0@" : /* no outputs */ + : "a" (addr), "d" (ssw)); + else + asm volatile ("ploadr %1,%0@" : /* no outputs */ + : "a" (addr), "d" (ssw)); + } /* Now handle the instruction fault. */ if (!(ssw & (FC|FB))) return; + if (fp->ptregs.sr & PS_S) { + printk("Instruction fault at %#010lx\n", + fp->ptregs.pc); + buserr: + printk ("BAD KERNEL BUSERR\n"); + die_if_kernel("Oops",&fp->ptregs,0); + force_sig(SIGKILL, current); + return; + } + /* get the fault address */ if (fp->ptregs.format == 10) addr = fp->ptregs.pc + 4; @@ -731,21 +716,18 @@ should still create the ATC entry. */ goto create_atc_entry; - mmusr = MMU_I; - if (user_space_fault) { #if DEBUG - asm volatile ("ptestr #1,%2@,#7,%0\n\t" - "pmove %/psr,%1@" - : "=a&" (desc) - : "a" (&temp), "a" (addr)); + asm volatile ("ptestr #1,%2@,#7,%0\n\t" + "pmove %%psr,%1@" + : "=a&" (desc) + : "a" (&temp), "a" (addr)); #else - asm volatile ("ptestr #1,%1@,#7\n\t" - "pmove %/psr,%0@" - : : "a" (&temp), "a" (addr)); + asm volatile ("ptestr #1,%1@,#7\n\t" + "pmove %%psr,%0@" + : : "a" (&temp), "a" (addr)); #endif - mmusr = temp; - } - + mmusr = temp; + #ifdef DEBUG printk ("mmusr is %#x for addr %#lx in task %p\n", mmusr, addr, current); Index: arch/m68k/mac/baboon.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/mac/baboon.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/mac/baboon.c 22 Jul 2004 19:49:12 -0000 1.1 +++ arch/m68k/mac/baboon.c 4 Aug 2004 01:25:45 -0000 1.2 @@ -19,8 +19,8 @@ #include #include -/* #define DEBUG_BABOON /**/ -/* #define DEBUG_IRQS /**/ +/* #define DEBUG_BABOON */ +/* #define DEBUG_IRQS */ int baboon_present,baboon_active; volatile struct baboon *baboon; Index: arch/m68k/mac/config.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/mac/config.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/mac/config.c 22 Jul 2004 19:49:12 -0000 1.1 +++ arch/m68k/mac/config.c 4 Aug 2004 01:25:45 -0000 1.2 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -91,7 +92,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 +203,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 +219,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 Index: arch/m68k/mac/mac_ksyms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/mac/mac_ksyms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/mac/mac_ksyms.c 22 Jul 2004 19:49:12 -0000 1.1 +++ arch/m68k/mac/mac_ksyms.c 4 Aug 2004 01:25:45 -0000 1.2 @@ -1,8 +1,7 @@ #include -#include -#include - -/* Says whether we're using A/UX interrupts or not */ -extern int via_alt_mapping; +#include +#include +#include EXPORT_SYMBOL(via_alt_mapping); +EXPORT_SYMBOL(macintosh_config); Index: arch/m68k/mac/misc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/mac/misc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/mac/misc.c 22 Jul 2004 19:49:12 -0000 1.1 +++ arch/m68k/mac/misc.c 4 Aug 2004 01:25:45 -0000 1.2 @@ -39,6 +39,7 @@ extern struct mac_booter_data mac_bi_data; static void (*rom_reset)(void); +#ifdef CONFIG_ADB /* * Return the current time as the number of seconds since January 1, 1904. */ @@ -103,6 +104,7 @@ (offset >> 8) & 0xFF, offset & 0xFF, data); } +#endif /* CONFIG_ADB */ /* * VIA PRAM/RTC access routines @@ -357,7 +359,11 @@ macintosh_config->adb_type == MAC_ADB_PB1 || macintosh_config->adb_type == MAC_ADB_PB2 || macintosh_config->adb_type == MAC_ADB_CUDA) { +#ifdef CONFIG_ADB func = adb_read_pram; +#else + return; +#endif } else { func = via_read_pram; } @@ -375,7 +381,11 @@ macintosh_config->adb_type == MAC_ADB_PB1 || macintosh_config->adb_type == MAC_ADB_PB2 || macintosh_config->adb_type == MAC_ADB_CUDA) { +#ifdef CONFIG_ADB func = adb_write_pram; +#else + return; +#endif } else { func = via_write_pram; } @@ -602,12 +612,16 @@ if (!op) { /* read */ if (macintosh_config->adb_type == MAC_ADB_II) { now = via_read_time(); - } else if ((macintosh_config->adb_type == MAC_ADB_IISI) || + } else +#ifdef CONFIG_ADB + if ((macintosh_config->adb_type == MAC_ADB_IISI) || (macintosh_config->adb_type == MAC_ADB_PB1) || (macintosh_config->adb_type == MAC_ADB_PB2) || (macintosh_config->adb_type == MAC_ADB_CUDA)) { now = adb_read_time(); - } else if (macintosh_config->adb_type == MAC_ADB_IOP) { + } else +#endif + if (macintosh_config->adb_type == MAC_ADB_IOP) { now = via_read_time(); } else { now = 0; Index: arch/m68k/math-emu/fp_emu.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/math-emu/fp_emu.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/math-emu/fp_emu.h 22 Jul 2004 19:49:12 -0000 1.1 +++ arch/m68k/math-emu/fp_emu.h 4 Aug 2004 01:25:45 -0000 1.2 @@ -115,6 +115,15 @@ __res; \ }) +#define fp_conv_long2ext(dest, src) ({ \ + register struct fp_ext *__dest asm ("a0") = dest; \ + register int __src asm ("d0") = src; \ + \ + asm volatile ("jsr fp_conv_ext2long" \ + : : "d" (__src), "a" (__dest) \ + : "a1", "d1", "d2", "memory"); \ +}) + #else /* __ASSEMBLY__ */ /* Index: arch/m68k/math-emu/fp_log.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/math-emu/fp_log.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/math-emu/fp_log.c 22 Jul 2004 19:49:12 -0000 1.1 +++ arch/m68k/math-emu/fp_log.c 4 Aug 2004 01:25:45 -0000 1.2 @@ -17,10 +17,22 @@ #include "fp_emu.h" +static const struct fp_ext fp_one = +{ + 0, 0, 0x3fff, { 0 } +}; + +extern struct fp_ext *fp_fadd(struct fp_ext *dest, const struct fp_ext *src); +extern struct fp_ext *fp_fdiv(struct fp_ext *dest, const struct fp_ext *src); +extern struct fp_ext *fp_fmul(struct fp_ext *dest, const struct fp_ext *src); + struct fp_ext * fp_fsqrt(struct fp_ext *dest, struct fp_ext *src) { - uprint("fsqrt\n"); + struct fp_ext tmp, src2; + int i, exp; + + dprint(PINSTR, "fsqrt\n"); fp_monadic_check(dest, src); @@ -34,6 +46,56 @@ if (IS_INF(dest)) return dest; + /* + * sqrt(m) * 2^(p) , if e = 2*p + * sqrt(m*2^e) = + * sqrt(2*m) * 2^(p) , if e = 2*p + 1 + * + * So we use the last bit of the exponent to decide wether to + * use the m or 2*m. + * + * Since only the fractional part of the mantissa is stored and + * the integer part is assumed to be one, we place a 1 or 2 into + * the fixed point representation. + */ + exp = dest->exp; + dest->exp = 0x3FFF; + if (!(exp & 1)) /* lowest bit of exponent is set */ + dest->exp++; + fp_copy_ext(&src2, dest); + + /* + * The taylor row arround a for sqrt(x) is: + * sqrt(x) = sqrt(a) + 1/(2*sqrt(a))*(x-a) + R + * With a=1 this gives: + * sqrt(x) = 1 + 1/2*(x-1) + * = 1/2*(1+x) + */ + fp_fadd(dest, &fp_one); + dest->exp--; /* * 1/2 */ + + /* + * We now apply the newton rule to the function + * f(x) := x^2 - r + * which has a null point on x = sqrt(r). + * + * It gives: + * x' := x - f(x)/f'(x) + * = x - (x^2 -r)/(2*x) + * = x - (x - r/x)/2 + * = (2*x - x + r/x)/2 + * = (x + r/x)/2 + */ + for (i = 0; i < 9; i++) { + fp_copy_ext(&tmp, &src2); + + fp_fdiv(&tmp, dest); + fp_fadd(dest, &tmp); + dest->exp--; + } + + dest->exp += (exp - 0x3FFF) / 2; + return dest; } @@ -123,20 +185,39 @@ struct fp_ext * fp_fgetexp(struct fp_ext *dest, struct fp_ext *src) { - uprint("fgetexp\n"); + dprint(PINSTR, "fgetexp\n"); fp_monadic_check(dest, src); + if (IS_INF(dest)) { + fp_set_nan(dest); + return dest; + } + if (IS_ZERO(dest)) + return dest; + + fp_conv_long2ext(dest, (int)dest->exp - 0x3FFF); + + fp_normalize_ext(dest); + return dest; } struct fp_ext * fp_fgetman(struct fp_ext *dest, struct fp_ext *src) { - uprint("fgetman\n"); + dprint(PINSTR, "fgetman\n"); fp_monadic_check(dest, src); + if (IS_ZERO(dest)) + return dest; + + if (IS_INF(dest)) + return dest; + + dest->exp = 0x3FFF; + return dest; } Index: arch/m68k/math-emu/multi_arith.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/math-emu/multi_arith.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/math-emu/multi_arith.h 22 Jul 2004 19:49:12 -0000 1.1 +++ arch/m68k/math-emu/multi_arith.h 4 Aug 2004 01:25:45 -0000 1.2 @@ -38,17 +38,14 @@ /* Convenience functions to stuff various integer values into int128s */ -extern inline void zero128(int128 a) +static inline void zero128(int128 a) { a[LSW128] = a[NLSW128] = a[NMSW128] = a[MSW128] = 0; } /* Human-readable word order in the arguments */ -extern inline void set128(unsigned int i3, - unsigned int i2, - unsigned int i1, - unsigned int i0, - int128 a) +static inline void set128(unsigned int i3, unsigned int i2, unsigned int i1, + unsigned int i0, int128 a) { a[LSW128] = i0; a[NLSW128] = i1; @@ -57,21 +54,19 @@ } /* Convenience functions (for testing as well) */ -extern inline void int64_to_128(unsigned long long src, - int128 dest) +static inline void int64_to_128(unsigned long long src, int128 dest) { dest[LSW128] = (unsigned int) src; dest[NLSW128] = src >> 32; dest[NMSW128] = dest[MSW128] = 0; } -extern inline void int128_to_64(const int128 src, - unsigned long long *dest) +static inline void int128_to_64(const int128 src, unsigned long long *dest) { *dest = src[LSW128] | (long long) src[NLSW128] << 32; } -extern inline void put_i128(const int128 a) +static inline void put_i128(const int128 a) { printk("%08x %08x %08x %08x\n", a[MSW128], a[NMSW128], a[NLSW128], a[LSW128]); @@ -82,7 +77,7 @@ Note that these are only good for 0 < count < 32. */ -extern inline void _lsl128(unsigned int count, int128 a) +static inline void _lsl128(unsigned int count, int128 a) { a[MSW128] = (a[MSW128] << count) | (a[NMSW128] >> (32 - count)); a[NMSW128] = (a[NMSW128] << count) | (a[NLSW128] >> (32 - count)); @@ -90,7 +85,7 @@ a[LSW128] <<= count; } -extern inline void _lsr128(unsigned int count, int128 a) +static inline void _lsr128(unsigned int count, int128 a) { a[LSW128] = (a[LSW128] >> count) | (a[NLSW128] << (32 - count)); a[NLSW128] = (a[NLSW128] >> count) | (a[NMSW128] << (32 - count)); @@ -100,7 +95,7 @@ /* Should be faster, one would hope */ -extern inline void lslone128(int128 a) +static inline void lslone128(int128 a) { asm volatile ("lsl.l #1,%0\n" "roxl.l #1,%1\n" @@ -118,7 +113,7 @@ "3"(a[MSW128])); } -extern inline void lsrone128(int128 a) +static inline void lsrone128(int128 a) { asm volatile ("lsr.l #1,%0\n" "roxr.l #1,%1\n" @@ -140,7 +135,7 @@ These bit-shift to a multiple of 32, then move whole longwords. */ -extern inline void lsl128(unsigned int count, int128 a) +static inline void lsl128(unsigned int count, int128 a) { int wordcount, i; @@ -159,7 +154,7 @@ } } -extern inline void lsr128(unsigned int count, int128 a) +static inline void lsr128(unsigned int count, int128 a) { int wordcount, i; @@ -177,18 +172,18 @@ } } -extern inline int orl128(int a, int128 b) +static inline int orl128(int a, int128 b) { b[LSW128] |= a; } -extern inline int btsthi128(const int128 a) +static inline int btsthi128(const int128 a) { return a[MSW128] & 0x80000000; } /* test bits (numbered from 0 = LSB) up to and including "top" */ -extern inline int bftestlo128(int top, const int128 a) +static inline int bftestlo128(int top, const int128 a) { int r = 0; @@ -206,7 +201,7 @@ /* Aargh. We need these because GCC is broken */ /* FIXME: do them in assembly, for goodness' sake! */ -extern inline void mask64(int pos, unsigned long long *mask) +static inline void mask64(int pos, unsigned long long *mask) { *mask = 0; @@ -218,7 +213,7 @@ HI_WORD(*mask) = (1 << (pos - 32)) - 1; } -extern inline void bset64(int pos, unsigned long long *dest) +static inline void bset64(int pos, unsigned long long *dest) { /* This conditional will be optimized away. Thanks, GCC! */ if (pos < 32) @@ -229,7 +224,7 @@ (HI_WORD(*dest)):"id"(pos - 32)); } -extern inline int btst64(int pos, unsigned long long dest) +static inline int btst64(int pos, unsigned long long dest) { if (pos < 32) return (0 != (LO_WORD(dest) & (1 << pos))); @@ -237,7 +232,7 @@ return (0 != (HI_WORD(dest) & (1 << (pos - 32)))); } -extern inline void lsl64(int count, unsigned long long *dest) +static inline void lsl64(int count, unsigned long long *dest) { if (count < 32) { HI_WORD(*dest) = (HI_WORD(*dest) << count) @@ -250,7 +245,7 @@ LO_WORD(*dest) = 0; } -extern inline void lsr64(int count, unsigned long long *dest) +static inline void lsr64(int count, unsigned long long *dest) { if (count < 32) { LO_WORD(*dest) = (LO_WORD(*dest) >> count) @@ -264,7 +259,7 @@ } #endif -extern inline void fp_denormalize(struct fp_ext *reg, unsigned int cnt) +static inline void fp_denormalize(struct fp_ext *reg, unsigned int cnt) { reg->exp += cnt; @@ -306,7 +301,7 @@ } } -extern inline int fp_overnormalize(struct fp_ext *reg) +static inline int fp_overnormalize(struct fp_ext *reg) { int shift; @@ -324,7 +319,7 @@ return shift; } -extern inline int fp_addmant(struct fp_ext *dest, struct fp_ext *src) +static inline int fp_addmant(struct fp_ext *dest, struct fp_ext *src) { int carry; @@ -340,7 +335,7 @@ return carry; } -extern inline int fp_addcarry(struct fp_ext *reg) +static inline int fp_addcarry(struct fp_ext *reg) { if (++reg->exp == 0x7fff) { if (reg->mant.m64) @@ -357,7 +352,8 @@ return 1; } -extern inline void fp_submant(struct fp_ext *dest, struct fp_ext *src1, struct fp_ext *src2) +static inline void fp_submant(struct fp_ext *dest, struct fp_ext *src1, + struct fp_ext *src2) { /* we assume here, gcc only insert move and a clr instr */ asm volatile ("sub.b %1,%0" : "=d,g" (dest->lowmant) @@ -407,7 +403,8 @@ carry; \ }) -extern inline void fp_multiplymant(union fp_mant128 *dest, struct fp_ext *src1, struct fp_ext *src2) +static inline void fp_multiplymant(union fp_mant128 *dest, struct fp_ext *src1, + struct fp_ext *src2) { union fp_mant64 temp; @@ -421,7 +418,8 @@ fp_addx96(dest, temp); } -extern inline void fp_dividemant(union fp_mant128 *dest, struct fp_ext *src, struct fp_ext *div) +static inline void fp_dividemant(union fp_mant128 *dest, struct fp_ext *src, + struct fp_ext *div) { union fp_mant128 tmp; union fp_mant64 tmp64; @@ -484,7 +482,7 @@ } #if 0 -extern inline unsigned int fp_fls128(union fp_mant128 *src) +static inline unsigned int fp_fls128(union fp_mant128 *src) { unsigned long data; unsigned int res, off; @@ -504,7 +502,7 @@ return res + off; } -extern inline void fp_shiftmant128(union fp_mant128 *src, int shift) +static inline void fp_shiftmant128(union fp_mant128 *src, int shift) { unsigned long sticky; @@ -594,7 +592,8 @@ } #endif -extern inline void fp_putmant128(struct fp_ext *dest, union fp_mant128 *src, int shift) +static inline void fp_putmant128(struct fp_ext *dest, union fp_mant128 *src, + int shift) { unsigned long tmp; @@ -639,7 +638,7 @@ } #if 0 /* old code... */ -extern inline int fls(unsigned int a) +static inline int fls(unsigned int a) { int r; @@ -649,7 +648,7 @@ } /* fls = "find last set" (cf. ffs(3)) */ -extern inline int fls128(const int128 a) +static inline int fls128(const int128 a) { if (a[MSW128]) return fls(a[MSW128]); @@ -668,12 +667,12 @@ return -1; } -extern inline int zerop128(const int128 a) +static inline int zerop128(const int128 a) { return !(a[LSW128] | a[NLSW128] | a[NMSW128] | a[MSW128]); } -extern inline int nonzerop128(const int128 a) +static inline int nonzerop128(const int128 a) { return (a[LSW128] | a[NLSW128] | a[NMSW128] | a[MSW128]); } @@ -681,7 +680,7 @@ /* Addition and subtraction */ /* Do these in "pure" assembly, because "extended" asm is unmanageable here */ -extern inline void add128(const int128 a, int128 b) +static inline void add128(const int128 a, int128 b) { /* rotating carry flags */ unsigned int carry[2]; @@ -699,7 +698,7 @@ } /* Note: assembler semantics: "b -= a" */ -extern inline void sub128(const int128 a, int128 b) +static inline void sub128(const int128 a, int128 b) { /* rotating borrow flags */ unsigned int borrow[2]; @@ -717,9 +716,7 @@ } /* Poor man's 64-bit expanding multiply */ -extern inline void mul64(unsigned long long a, - unsigned long long b, - int128 c) +static inline void mul64(unsigned long long a, unsigned long long b, int128 c) { unsigned long long acc; int128 acc128; @@ -756,7 +753,7 @@ } /* Note: unsigned */ -extern inline int cmp128(int128 a, int128 b) +static inline int cmp128(int128 a, int128 b) { if (a[MSW128] < b[MSW128]) return -1; Index: arch/m68k/mm/kmap.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/mm/kmap.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/mm/kmap.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/m68k/mm/kmap.c 4 Aug 2004 01:25:45 -0000 1.2 @@ -71,7 +71,7 @@ addr = tmp->size + (unsigned long)tmp->addr; } area->addr = (void *)addr; - area->size = size + IO_SIZE; + area->size = size + IO_SIZE; /* leave a gap between */ area->next = *p; *p = area; return area; @@ -87,7 +87,10 @@ for (p = &iolist ; (tmp = *p) ; p = &tmp->next) { if (tmp->addr == addr) { *p = tmp->next; - __iounmap(tmp->addr, tmp->size); + if ( tmp->size > IO_SIZE ) + __iounmap(tmp->addr, tmp->size - IO_SIZE); + else + printk("free_io_area: Invalid I/O area size %lu\n", tmp->size); kfree(tmp); return; } Index: arch/m68k/mm/memory.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/mm/memory.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/mm/memory.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/m68k/mm/memory.c 4 Aug 2004 01:25:45 -0000 1.2 @@ -19,76 +19,10 @@ #include #include #include -#include #include -#ifdef CONFIG_AMIGA -#include -#endif struct pgtable_cache_struct quicklists; -void __bad_pte(pmd_t *pmd) -{ - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); - pmd_set(pmd, BAD_PAGETABLE); -} - -void __bad_pmd(pgd_t *pgd) -{ - printk("Bad pgd in pmd_alloc: %08lx\n", pgd_val(*pgd)); - pgd_set(pgd, (pmd_t *)BAD_PAGETABLE); -} - -#if 0 -pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset) -{ - pte_t *pte; - - pte = (pte_t *) __get_free_page(GFP_KERNEL); - if (pmd_none(*pmd)) { - if (pte) { - clear_page(pte); - __flush_page_to_ram((unsigned long)pte); - flush_tlb_kernel_page((unsigned long)pte); - nocache_page((unsigned long)pte); - pmd_set(pmd, pte); - return pte + offset; - } - pmd_set(pmd, BAD_PAGETABLE); - return NULL; - } - free_page((unsigned long)pte); - if (pmd_bad(*pmd)) { - __bad_pte(pmd); - return NULL; - } - return (pte_t *)__pmd_page(*pmd) + offset; -} -#endif - -#if 0 -pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset) -{ - pmd_t *pmd; - - pmd = get_pointer_table(); - if (pgd_none(*pgd)) { - if (pmd) { - pgd_set(pgd, pmd); - return pmd + offset; - } - pgd_set(pgd, (pmd_t *)BAD_PAGETABLE); - return NULL; - } - free_pointer_table(pmd); - if (pgd_bad(*pgd)) { - __bad_pmd(pgd); - return NULL; - } - return (pmd_t *)__pgd_page(*pgd) + offset; -} -#endif - /* ++andreas: {get,free}_pointer_table rewritten to use unused fields from struct page instead of separately kmalloced struct. Stolen from arch/sparc/mm/srmmu.c ... */ @@ -196,34 +130,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 +159,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 +187,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 Index: arch/m68k/mm/motorola.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/mm/motorola.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/mm/motorola.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/m68k/mm/motorola.c 4 Aug 2004 01:25:45 -0000 1.2 @@ -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 Index: arch/m68k/mvme16x/rtc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/mvme16x/rtc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/mvme16x/rtc.c 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/m68k/mvme16x/rtc.c 4 Aug 2004 01:25:46 -0000 1.2 @@ -52,6 +52,7 @@ cli(); /* Ensure clock and real-time-mode-register are accessible */ rtc->ctrl = RTC_READ; + memset(&wtime, 0, sizeof(struct rtc_time)); wtime.tm_sec = BCD2BIN(rtc->bcd_sec); wtime.tm_min = BCD2BIN(rtc->bcd_min); wtime.tm_hour = BCD2BIN(rtc->bcd_hr); Index: arch/m68k/q40/q40ints.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/q40/q40ints.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/q40/q40ints.c 22 Jul 2004 19:49:11 -0000 1.1 +++ arch/m68k/q40/q40ints.c 4 Aug 2004 01:25:46 -0000 1.2 @@ -124,7 +124,6 @@ case 11: printk("warning IRQ 10 and 11 not distinguishable\n"); irq=10; - default: } if (irqpc, fp->d0, fp->orig_d0, fp->d1, fp->d2); + printk("\tIIRQ_REG = %x, EIRQ_REG = %x\n",master_inb(IIRQ_REG),master_inb(EIRQ_REG)); } /* @@ -313,7 +313,6 @@ unsigned mir, mer; int irq,i; - repeat: mir=master_inb(IIRQ_REG); if (mir&Q40_IRQ_FRAME_MASK) { irq_tab[Q40_IRQ_FRAME].count++; @@ -373,7 +372,6 @@ /*printk("reenabling irq %d\n",irq); */ #endif } -// used to do 'goto repeat;' her, this delayed bh processing too long return; } } @@ -382,6 +380,7 @@ } iirq: mir=master_inb(IIRQ_REG); + /* should test whether keyboard irq is really enabled, doing it in defhand */ if (mir&Q40_IRQ_KEYB_MASK) { irq_tab[Q40_IRQ_KEYBOARD].count++; irq_tab[Q40_IRQ_KEYBOARD].handler(Q40_IRQ_KEYBOARD,irq_tab[Q40_IRQ_KEYBOARD].dev_id,fp); @@ -408,7 +407,9 @@ static void q40_defhand (int irq, void *dev_id, struct pt_regs *fp) { - printk ("Unknown q40 interrupt 0x%02x\n", irq); + if (irq!=Q40_IRQ_KEYBOARD) + printk ("Unknown q40 interrupt %d\n", irq); + else master_outb(-1,KEYBOARD_UNLOCK_REG); } static void sys_default_handler(int lev, void *dev_id, struct pt_regs *regs) { Index: arch/m68k/sun3/idprom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/sun3/idprom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/sun3/idprom.c 22 Jul 2004 19:49:12 -0000 1.1 +++ arch/m68k/sun3/idprom.c 4 Aug 2004 01:25:46 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: idprom.c,v 1.1 2004/07/22 19:49:12 joff Exp $ +/* $Id: idprom.c,v 1.2 2004/08/04 01:25:46 joff Exp $ * idprom.c: Routines to load the idprom into kernel addresses and * interpret the data contained within. * Index: arch/m68k/sun3/prom/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/sun3/prom/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/sun3/prom/Makefile 22 Jul 2004 19:49:12 -0000 1.1 +++ arch/m68k/sun3/prom/Makefile 4 Aug 2004 01:25:46 -0000 1.2 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.1 2004/07/22 19:49:12 joff Exp $ +# $Id: Makefile,v 1.2 2004/08/04 01:25:46 joff Exp $ # Makefile for the Sun Boot PROM interface library under # Linux. # Index: arch/m68k/sun3/prom/console.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/sun3/prom/console.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/sun3/prom/console.c 22 Jul 2004 19:49:12 -0000 1.1 +++ arch/m68k/sun3/prom/console.c 4 Aug 2004 01:25:46 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: console.c,v 1.1 2004/07/22 19:49:12 joff Exp $ +/* $Id: console.c,v 1.2 2004/08/04 01:25:46 joff Exp $ * console.c: Routines that deal with sending and receiving IO * to/from the current console device using the PROM. * Index: arch/m68k/sun3/prom/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/sun3/prom/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/sun3/prom/init.c 22 Jul 2004 19:49:12 -0000 1.1 +++ arch/m68k/sun3/prom/init.c 4 Aug 2004 01:25:46 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.1 2004/07/22 19:49:12 joff Exp $ +/* $Id: init.c,v 1.2 2004/08/04 01:25:46 joff Exp $ * init.c: Initialize internal variables used by the PROM * library functions. * Index: arch/m68k/sun3/prom/misc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/sun3/prom/misc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/sun3/prom/misc.c 22 Jul 2004 19:49:12 -0000 1.1 +++ arch/m68k/sun3/prom/misc.c 4 Aug 2004 01:25:46 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.1 2004/07/22 19:49:12 joff Exp $ +/* $Id: misc.c,v 1.2 2004/08/04 01:25:46 joff Exp $ * misc.c: Miscellaneous prom functions that don't belong * anywhere else. * Index: arch/m68k/sun3/prom/printf.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/m68k/sun3/prom/printf.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/m68k/sun3/prom/printf.c 22 Jul 2004 19:49:12 -0000 1.1 +++ arch/m68k/sun3/prom/printf.c 4 Aug 2004 01:25:46 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: printf.c,v 1.1 2004/07/22 19:49:12 joff Exp $ +/* $Id: printf.c,v 1.2 2004/08/04 01:25:46 joff Exp $ * printf.c: Internal prom library printf facility. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/mips/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/Makefile 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/Makefile 4 Aug 2004 01:25:46 -0000 1.2 @@ -5,7 +5,7 @@ # # Copyright (C) 1994, 1995, 1996 by Ralf Baechle # DECStation modifications by Paul M. Antoine, 1996 -# Copyright (C) 2002 Maciej W. Rozycki +# Copyright (C) 2002, 2003 Maciej W. Rozycki # # 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 @@ -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,58 +43,124 @@ # GCCFLAGS := -I $(TOPDIR)/include/asm/gcc GCCFLAGS += -G 0 -mno-abicalls -fno-pic -pipe +GCCFLAGS += $(call check_gcc, -finline-limit=100000,) LINKFLAGS += -G 0 -static # -N MODFLAGS += -mlong-calls -ifdef CONFIG_REMOTE_DEBUG +ifdef CONFIG_DEBUG_INFO GCCFLAGS += -g +ifdef CONFIG_SB1XXX_CORELIS +GCCFLAGS += -mno-sched-prolog -fno-omit-frame-pointer +endif endif # +# Use: $(call set_gccflags,,,,,) +# +# , -- preferred CPU and ISA designations (may require +# recent tools) +# , -- fallback CPU and ISA designations (have to work +# with up to the oldest supported tools) +# -- an ISA designation used as an ABI selector for +# gcc versions that do not support "-mabi=32" +# (depending on the CPU type, either "mips1" or +# "mips2") +# +set_gccflags = $(shell \ +while :; do \ + cpu=$(1); isa=-$(2); \ + for gcc_opt in -march= -mcpu=; do \ + $(CC) $$gcc_opt$$cpu $$isa -S -o /dev/null \ + -xc /dev/null > /dev/null 2>&1 && \ + break 2; \ + done; \ + cpu=$(3); isa=-$(4); \ + for gcc_opt in -march= -mcpu=; do \ + $(CC) $$gcc_opt$$cpu $$isa -S -o /dev/null \ + -xc /dev/null > /dev/null 2>&1 && \ + break 2; \ + done; \ + break; \ +done; \ +gcc_abi=-mabi=32; gcc_cpu=$$cpu; \ +if $(CC) $$gcc_abi -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then \ + gcc_isa=$$isa; \ +else \ + gcc_abi=; gcc_isa=-$(5); \ +fi; \ +gas_abi=-Wa,-32; gas_cpu=$$cpu; gas_isa=-Wa,$$isa; \ +while :; do \ + for gas_opt in -Wa,-march= -Wa,-mcpu=; do \ + $(CC) $$gas_abi $$gas_opt$$cpu $$gas_isa -Wa,-Z -c \ + -o /dev/null -xassembler /dev/null > /dev/null 2>&1 && \ + break 2; \ + done; \ + gas_abi=; gas_opt=; gas_cpu=; gas_isa=; \ + break; \ +done; \ +echo $$gcc_abi $$gcc_opt$$gcc_cpu $$gcc_isa $$gas_abi $$gas_opt$$gas_cpu $$gas_isa) + +# # CPU-dependent compiler/assembler options for optimization. # ifdef CONFIG_CPU_R3000 -GCCFLAGS += -mcpu=r3000 -mips1 +GCCFLAGS += $(call set_gccflags,r3000,mips1,r3000,mips1,mips1) endif ifdef CONFIG_CPU_TX39XX -GCCFLAGS += -mcpu=r3000 -mips1 +GCCFLAGS += $(call set_gccflags,r3900,mips1,r3000,mips1,mips1) endif ifdef CONFIG_CPU_R6000 -GCCFLAGS += -mcpu=r6000 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,r6000,mips2,r6000,mips2,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_R4300 -GCCFLAGS += -mcpu=r4300 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,r4300,mips3,r4300,mips3,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_VR41XX -GCCFLAGS += -mcpu=r4600 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,r4100,mips3,r4600,mips3,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_R4X00 -GCCFLAGS += -mcpu=r4600 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,r4600,mips3,r4600,mips3,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_TX49XX -GCCFLAGS += -mcpu=r4600 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,r4600,mips3,r4600,mips3,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_MIPS32 -GCCFLAGS += -mcpu=r4600 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,mips32,mips32,r4600,mips3,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_MIPS64 -GCCFLAGS += -mcpu=r4600 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,mips64,mips64,r4600,mips3,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_R5000 -GCCFLAGS += -mcpu=r5000 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,r5000,mips4,r5000,mips4,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_R5432 -GCCFLAGS += -mcpu=r5000 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,r5400,mips4,r5000,mips4,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_NEVADA -# Cannot use -mmad with currently recommended tools -GCCFLAGS += -mcpu=r5000 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,rm5200,mips4,r5000,mips4,mips2) \ + -Wa,--trap +#GCCFLAGS += $(call check_gcc,-mmad,) endif ifdef CONFIG_CPU_RM7000 -GCCFLAGS += -mcpu=r5000 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,rm7000,mips4,r5000,mips4,mips2) \ + -Wa,--trap +endif +ifdef CONFIG_CPU_RM9000 +GCCFLAGS += $(call set_gccflags,rm9000,mips4,r5000,mips4,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_SB1 -GCCFLAGS += -mcpu=sb1 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,sb1,mips64,r5000,mips4,mips2) \ + -Wa,--trap ifdef CONFIG_SB1_PASS_1_WORKAROUNDS MODFLAGS += -msb1-pass1-workarounds endif @@ -97,6 +168,7 @@ AFLAGS += $(GCCFLAGS) CFLAGS += $(GCCFLAGS) +LDFLAGS += -m $(ld-emul) # @@ -161,6 +233,88 @@ 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_HYDROGEN3 +LIBS += arch/mips/au1000/hydrogen3/hydrogen3.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/hydrogen3 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_MIPS_PB1550 +LIBS += arch/mips/au1000/pb1550/pb1550.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/pb1550 arch/mips/au1000/common +LOADADDR += 0x80100000 +endif + + +# +# Cogent CSB250 +# +ifdef CONFIG_COGENT_CSB250 +LIBS += arch/mips/au1000/csb250/csb250.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/csb250 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 +355,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 +365,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 +453,27 @@ 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_MOMENCO_JAGUAR_ATX +LIBS += arch/mips/momentum/jaguar_atx/jaguar_atx.o +SUBDIRS += arch/mips/momentum/jaguar_atx +ifdef CONFIG_JAGUAR_DMALOW +LOADADDR := 0x88000000 +else +LOADADDR := 0x80100000 +endif +endif + +# # NEC DDB Vrc-5074 # ifdef CONFIG_DDB5074 @@ -328,6 +502,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 +523,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 +534,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 +619,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: +# +# 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 # @@ -413,14 +654,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 +673,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,25 +714,33 @@ 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 @$(MAKEBOOT) $@ +vmlinux.srec: vmlinux + @$(MAKEBOOT) $@ + archclean: @$(MAKEBOOT) clean 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: Index: arch/mips/config-shared.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/config-shared.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/config-shared.in 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/config-shared.in 4 Aug 2004 01:25:46 -0000 1.2 @@ -14,19 +14,36 @@ 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 Alchemy Hydrogen3 board' CONFIG_MIPS_HYDROGEN3 $CONFIG_MIPS32 +dep_bool 'Support for Alchemy PB1550 board' CONFIG_MIPS_PB1550 $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 Cogent CSB250 board' CONFIG_COGENT_CSB250 $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 +55,33 @@ 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 +if [ "$CONFIG_IBM_WORKPAD" = "y" ]; then + tristate ' NEC VRC4171 support' CONFIG_VRC4171 +fi +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 +bool 'Support for Momentum Jaguar-ATX boards' CONFIG_MOMENCO_JAGUAR_ATX +bool 'Support PMC-Sierra Yosemite board' CONFIG_PMC_YOSEMITE +if [ "$CONFIG_PMC_YOSEMITE" = "y" ]; then + bool ' Hypertransport Support for PMC-Sierra Yosemite' CONFIG_HYPERTRANSPORT +fi 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 +90,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 +102,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 +110,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' \ + "BCM1250 CONFIG_SIBYTE_SB1250 \ + BCM1120 CONFIG_SIBYTE_BCM1120 \ + BCM1125 CONFIG_SIBYTE_BCM1125 \ + BCM1125H 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 +183,52 @@ int ' Memory size (in megabytes)' CONFIG_SIBYTE_STANDALONE_RAM_SIZE 32 fi + bool ' Support for Bus Watcher statistics' CONFIG_SIBYTE_BUS_WATCHER + if [ "$CONFIG_SIBYTE_TBPROF" = "n" ]; then + dep_bool ' Capture bus trace before bus error' CONFIG_SIBYTE_BW_TRACE $CONFIG_SIBYTE_BUS_WATCHER + fi + 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 @@ -119,7 +239,6 @@ # # Select some configuration options automatically based on user selections. # - if [ "$CONFIG_ACER_PICA_61" = "y" ]; then define_bool CONFIG_ARC32 y define_bool CONFIG_I8259 y @@ -127,73 +246,180 @@ 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_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_NEW_TIME_C 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_NEW_TIME_C 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_NEW_TIME_C 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_NEW_TIME_C 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_NEW_TIME_C 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 + define_bool CONFIG_NEW_TIME_C 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_OLD_TIME_C 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_NEW_TIME_C 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_NEW_TIME_C 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_HYDROGEN3" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1100 y + define_bool CONFIG_NEW_TIME_C 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_NEW_TIME_C 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_NEW_TIME_C 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_COGENT_CSB250" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1500 y + 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_NONCOHERENT_IO y + define_bool CONFIG_PC_KEYB y +fi +if [ "$CONFIG_MIPS_PB1550" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1550 y + 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_NONCOHERENT_IO n + define_bool CONFIG_PC_KEYB y fi if [ "$CONFIG_MIPS_COBALT" = "y" ]; then + define_bool CONFIG_BOOT_ELF32 y 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 define_bool CONFIG_PCI y - define_bool CONFIG_ISA n define_bool CONFIG_MIPS_GT64120 y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_OLD_TIME_C y fi if [ "$CONFIG_MIPS_EV96100" = "y" ]; then 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 +428,32 @@ 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_NONCOHERENT_IO y + define_bool CONFIG_ISA 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 +462,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,17 +492,20 @@ 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 @@ -268,19 +513,45 @@ if [ "$CONFIG_MOMENCO_OCELOT" = "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_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 + define_bool CONFIG_BOOT_ELF32 y +fi +if [ "$CONFIG_MOMENCO_JAGUAR_ATX" = "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 + define_bool CONFIG_BOOT_ELF32 y +fi + +if [ "$CONFIG_PMC_YOSEMITE" = "y" ]; then + 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 + define_bool CONFIG_BOOT_ELF32 y + define_bool CONFIG_HIGHMEM y + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_NONCOHERENT_IO y +fi + if [ "$CONFIG_DDB5074" = "y" ]; then define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y define_bool CONFIG_I8259 y @@ -290,7 +561,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 +568,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 +579,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,13 +595,9 @@ 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 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 @@ -344,83 +605,105 @@ 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_NONCOHERENT_IO y + 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_NONCOHERENT_IO y + 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_NONCOHERENT_IO y + 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 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 @@ -452,14 +735,21 @@ R8000 CONFIG_CPU_R8000 \ R10000 CONFIG_CPU_R10000 \ RM7000 CONFIG_CPU_RM7000 \ + RM9000 CONFIG_CPU_RM9000 \ SB1 CONFIG_CPU_SB1" R4x00 -if [ "$CONFIG_CPU_R5000" = "y" ]; then - define_bool CONFIG_BOARD_SCACHE y +if [ "$CONFIG_CPU_R3000" = "n" -a "$CONFIG_CPU_TX39XX" = "n" -a \ + "$CONFIG_EXPERIMENTAL" = "y" ]; then + choice 'Kernel page size' \ + "4KB CONFIG_PAGE_SIZE_4KB \ + 16KB CONFIG_PAGE_SIZE_16KB \ + 64KB CONFIG_PAGE_SIZE_64KB" 4KB +else + define_bool CONFIG_PAGE_SIZE_4KB 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 @@ -473,19 +763,25 @@ fi if [ "$CONFIG_CPU_RM7000" = "y" ]; then + define_bool CONFIG_BOARD_SCACHE y define_bool CONFIG_CPU_HAS_PREFETCH y + define_bool CONFIG_RM7000_CPU_SCACHE y +fi +if [ "$CONFIG_CPU_RM9000" = "y" ]; then + define_bool CONFIG_BOARD_SCACHE y + define_bool CONFIG_CPU_HAS_PREFETCH y + define_bool CONFIG_RM7000_CPU_SCACHE y 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,15 +790,14 @@ # 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 if [ "$CONFIG_CPU_R4X00" = "y" -o \ "$CONFIG_CPU_R5000" = "y" -o \ "$CONFIG_CPU_RM7000" = "y" -o \ + "$CONFIG_CPU_RM9000" = "y" -o \ "$CONFIG_CPU_R10000" = "y" -o \ "$CONFIG_CPU_SB1" = "y" -o \ "$CONFIG_CPU_MIPS32" = "y" -o \ @@ -547,24 +842,55 @@ 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 -fi - -if [ "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then - bool 'DS1742 BRAM/RTC support' CONFIG_RTC_DS1742 + 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_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 @@ -575,28 +901,24 @@ bool 'ARC console support' CONFIG_ARC_CONSOLE fi -if [ "$CONFIG_SGI_IP22" = "y" ]; then - dep_bool 'Indigo-2 (IP22) EISA bus support' CONFIG_IP22_EISA $CONFIG_EXPERIMENTAL -fi +bool 'Networking support' CONFIG_NET -if [ "$CONFIG_IP22_EISA" = "y" ]; then - define_bool CONFIG_EISA y - bool ' ISA bus support' CONFIG_ISA +if [ "$CONFIG_SGI_IP22" = "y" -o "$CONFIG_MIPS_MAGNUM_4000" = "y" -o \ + "$CONFIG_OLIVETTI_M700" = "y" -o "$CONFIG_SNI_RM200_PCI" = "y" ]; then + bool 'EISA bus support' CONFIG_EISA fi -bool 'Networking support' CONFIG_NET - if [ "$CONFIG_PCI" != "y" ]; then define_bool CONFIG_PCI n fi source drivers/pci/Config.in +if [ "$CONFIG_EISA" = "y" -a "$CONFIG_ISA" != "y" ]; then + define_bool CONFIG_ISA y +fi if [ "$CONFIG_ISA" != "y" ]; then define_bool CONFIG_ISA n - define_bool CONFIG_EISA n -else - define_bool CONFIG_EISA y fi dep_bool 'TURBOchannel support' CONFIG_TC $CONFIG_DECSTATION @@ -623,11 +945,21 @@ 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 +bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER -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 +973,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 @@ -660,7 +995,6 @@ 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 @@ -675,7 +1009,11 @@ fi endmenu -if [ "$CONFIG_PCI" = "y" ]; then +source drivers/message/fusion/Config.in + +source drivers/ieee1394/Config.in + +if [ "$CONFIG_PCI" = "y" -a "$CONFIG_MIPS32" = "y" ]; then source drivers/message/i2o/Config.in fi @@ -686,7 +1024,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 +1065,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 +1073,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 +1096,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 +1104,33 @@ 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_KGDB" = "y" ]; then + define_bool CONFIG_DEBUG_INFO y +else + bool 'Debugging symbols' CONFIG_DEBUG_INFO +fi +if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then + dep_bool 'Compile for Corelis Debugger' CONFIG_SB1XXX_CORELIS $CONFIG_DEBUG_INFO 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 +else + if [ "$CONFIG_MIPS32" = "y" ]; then + int 'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32 + else + if [ "$CONFIG_MIPS64" = "y" ]; then + int 'Maximum number of CPUs (2-64)' CONFIG_NR_CPUS 64 + fi + fi fi + +int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 + endmenu +source crypto/Config.in source lib/Config.in Index: arch/mips/defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig 4 Aug 2004 01:25:46 -0000 1.2 @@ -21,17 +21,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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 +50,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,28 +62,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 # @@ -90,8 +104,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -104,13 +121,11 @@ # # 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 +# CONFIG_EISA is not set # 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 @@ -125,9 +140,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -154,6 +171,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set @@ -198,6 +216,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -243,7 +267,6 @@ # 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 # @@ -282,12 +305,14 @@ # 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_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set @@ -310,9 +335,19 @@ # 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 # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# # Network device support # CONFIG_NETDEVICES=y @@ -354,6 +389,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 @@ -403,6 +439,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -443,6 +480,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 +493,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,15 +504,21 @@ # 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=y +# CONFIG_INDYDOG is not set # CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200 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_DS1286=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -479,19 +528,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set -# CONFIG_DRM is not set # -# SGI Character devices +# Direct Rendering Manager (XFree86 DRI support) # -CONFIG_SGI_NEWPORT_CONSOLE=y -CONFIG_FONT_8x16=y -CONFIG_DUMMY_CONSOLE=y +# 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 @@ -501,11 +548,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,12 +584,17 @@ # 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 # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -550,6 +603,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 +653,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,20 +666,43 @@ # # Sound # -# CONFIG_SOUND 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 +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # -# SGI devices +# USB support # -CONFIG_SGI_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set -CONFIG_SGI_DS1286=y -# CONFIG_SGI_NEWPORT_GFX is not set +# CONFIG_USB is not set # -# USB support +# Support for USB gadgets # -# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set # # Bluetooth support @@ -633,12 +713,22 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips/defconfig-atlas =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-atlas,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-atlas 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-atlas 4 Aug 2004 01:25:46 -0000 1.2 @@ -19,17 +19,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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 +48,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,21 +60,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 # @@ -81,7 +101,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set # CONFIG_64BIT_PHYS_ADDR is not set @@ -96,11 +120,9 @@ # # 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 -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -115,9 +137,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -144,6 +168,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y @@ -189,6 +214,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -234,7 +265,6 @@ # 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 # @@ -271,12 +301,14 @@ # 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_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -313,9 +345,24 @@ # 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 # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# # I2O device support # # CONFIG_I2O is not set @@ -357,14 +404,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 +431,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 +449,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 @@ -448,6 +499,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -484,13 +536,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 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 @@ -500,12 +561,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # 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 @@ -515,6 +581,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,6 +623,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -564,6 +636,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 @@ -621,6 +694,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -629,14 +707,22 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips/defconfig-capcella =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-capcella,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-capcella 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-capcella 4 Aug 2004 01:25:46 -0000 1.2 @@ -21,17 +21,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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 +50,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,22 +62,20 @@ # 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 CONFIG_NONCOHERENT_IO=y -# CONFIG_ISA is not set CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_PCI_AUTO=y @@ -89,7 +101,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set @@ -103,7 +119,6 @@ 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 @@ -118,9 +133,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -147,6 +164,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set @@ -191,6 +209,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -250,15 +274,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 +287,14 @@ # 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_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 @@ -288,6 +302,20 @@ # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# # I2O device support # # CONFIG_I2O is not set @@ -329,14 +357,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 +384,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 +402,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 @@ -420,6 +452,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -430,6 +463,7 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_VR41XX_KIU is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -457,6 +491,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 +504,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,15 +515,19 @@ # 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 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 @@ -493,12 +537,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # 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 @@ -508,6 +557,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 @@ -549,6 +599,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -557,6 +612,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 @@ -624,6 +680,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -632,14 +693,22 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips/defconfig-cobalt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-cobalt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-cobalt 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-cobalt 4 Aug 2004 01:25:46 -0000 1.2 @@ -19,17 +19,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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 +48,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,18 +60,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_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 @@ -80,8 +97,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y @@ -95,7 +115,6 @@ 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 @@ -110,9 +129,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -139,6 +160,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y @@ -179,6 +201,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -238,15 +266,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 +279,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 +289,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 @@ -302,10 +320,10 @@ # CONFIG_IDEDMA_AUTO is not set # 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 @@ -313,6 +331,20 @@ # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# # I2O device support # # CONFIG_I2O is not set @@ -354,8 +386,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 +398,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 +415,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 +433,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 @@ -447,6 +483,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -483,13 +520,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 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,12 +545,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # 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 @@ -514,6 +565,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 @@ -555,6 +607,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -563,6 +620,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 @@ -619,6 +677,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -627,14 +690,22 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips/defconfig-ddb5476 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-ddb5476,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-ddb5476 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-ddb5476 4 Aug 2004 01:25:46 -0000 1.2 @@ -19,17 +19,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set CONFIG_DDB5476=y # CONFIG_DDB5477 is not set @@ -46,10 +60,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 +74,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 @@ -85,7 +101,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y @@ -98,7 +118,6 @@ CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_NET=y # CONFIG_PCI_NAMES is not set -CONFIG_EISA=y # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -113,9 +132,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -142,6 +163,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set @@ -185,6 +207,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -244,15 +272,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 +285,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 +295,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 +325,10 @@ # 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 +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -318,6 +336,20 @@ # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# # I2O device support # # CONFIG_I2O is not set @@ -361,9 +393,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 +406,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 +423,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 +441,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 @@ -460,6 +496,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -501,13 +538,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 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 @@ -517,12 +563,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # 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 @@ -532,6 +583,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 @@ -573,6 +625,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -581,6 +638,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,12 +690,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=y # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set # CONFIG_FB_E1356 is not set +# CONFIG_FB_IT8181 is not set # CONFIG_FB_VIRTUAL is not set # CONFIG_FBCON_ADVANCED is not set CONFIG_FBCON_CFB8=y @@ -659,6 +719,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -667,14 +732,22 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips/defconfig-ddb5477 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-ddb5477,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-ddb5477 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-ddb5477 4 Aug 2004 01:25:46 -0000 1.2 @@ -19,17 +19,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set CONFIG_DDB5477=y @@ -47,22 +61,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 @@ -84,7 +100,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y @@ -98,7 +118,6 @@ 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 @@ -113,9 +132,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -142,6 +163,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set @@ -185,6 +207,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -230,7 +258,6 @@ # 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 # @@ -239,6 +266,20 @@ # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# # I2O device support # # CONFIG_I2O is not set @@ -280,8 +321,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 +333,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 +350,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 +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 @@ -373,6 +418,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -409,13 +455,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 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,12 +480,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # 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 @@ -440,6 +500,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 @@ -481,6 +542,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -489,6 +555,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 @@ -548,6 +615,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -555,6 +624,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -563,14 +637,22 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips/defconfig-decstation =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-decstation,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-decstation 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-decstation 4 Aug 2004 01:25:46 -0000 1.2 @@ -21,17 +21,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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 +50,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,16 +62,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 @@ -79,7 +98,9 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set @@ -93,7 +114,6 @@ 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 @@ -108,9 +128,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -137,6 +159,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set @@ -180,6 +203,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -225,7 +254,6 @@ # 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 # @@ -263,12 +291,14 @@ # 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_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set @@ -291,9 +321,19 @@ # 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 # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# # Network device support # CONFIG_NETDEVICES=y @@ -335,6 +375,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 @@ -384,15 +425,41 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # 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 +487,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 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 @@ -436,21 +512,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set -# CONFIG_DRM is not set # -# DECStation Character devices +# Direct Rendering Manager (XFree86 DRI support) # -CONFIG_SERIAL=y -# CONFIG_DZ is not set -CONFIG_ZS=y -CONFIG_SERIAL_CONSOLE=y -# CONFIG_RTC 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 @@ -460,6 +532,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 @@ -501,6 +574,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -509,6 +587,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 @@ -565,6 +644,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -573,14 +657,22 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips/defconfig-eagle =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-eagle,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-eagle 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-eagle 4 Aug 2004 01:25:46 -0000 1.2 @@ -21,17 +21,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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,30 +50,33 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE 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 CONFIG_NONCOHERENT_IO=y -# CONFIG_ISA is not set CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_PCI_AUTO=y @@ -88,7 +102,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set @@ -102,13 +120,27 @@ 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=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 +149,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -129,6 +163,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 +186,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 +205,22 @@ # 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_HYDIII is not set +# CONFIG_MTD_MIRAGE 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 @@ -215,6 +258,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set @@ -259,6 +303,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -303,9 +353,42 @@ # # 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_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 @@ -313,6 +396,20 @@ # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# # I2O device support # # CONFIG_I2O is not set @@ -354,14 +451,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 +478,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 +496,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 +524,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 @@ -445,6 +562,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -455,6 +573,7 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_VR41XX_KIU is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -486,6 +605,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 +618,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,15 +629,19 @@ # 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 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 @@ -522,12 +651,23 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # 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 +677,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 +722,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -589,6 +735,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 +800,115 @@ # # 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 + +# +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set # # Bluetooth support @@ -664,14 +919,23 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set # # Library routines # +# CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y +# CONFIG_FW_LOADER is not set Index: arch/mips/defconfig-ev64120 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-ev64120,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-ev64120 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-ev64120 4 Aug 2004 01:25:46 -0000 1.2 @@ -21,11 +21,20 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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 +45,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 +54,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -52,16 +66,18 @@ # 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_ISA is not set CONFIG_MIPS_GT64120=y CONFIG_NONCOHERENT_IO=y CONFIG_OLD_TIME_C=y @@ -85,8 +101,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -99,11 +118,9 @@ # # 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 -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -118,9 +135,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -147,6 +166,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set @@ -189,6 +209,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -234,7 +260,6 @@ # 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 # @@ -243,6 +268,20 @@ # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# # I2O device support # # CONFIG_I2O is not set @@ -284,14 +323,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 +350,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 +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 @@ -382,6 +425,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -418,11 +462,19 @@ # 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 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,12 +486,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # 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 @@ -449,6 +506,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 @@ -490,6 +548,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -498,6 +561,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 @@ -540,6 +604,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -548,14 +617,22 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips/defconfig-ev96100 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-ev96100,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-ev96100 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-ev96100 4 Aug 2004 01:25:46 -0000 1.2 @@ -21,17 +21,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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 +50,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,21 +62,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_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 # @@ -83,8 +101,14 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set CONFIG_CPU_RM7000=y +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y CONFIG_CPU_HAS_PREFETCH=y +CONFIG_RM7000_CPU_SCACHE=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -97,11 +121,9 @@ # # 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 -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -116,9 +138,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -145,6 +169,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set @@ -187,6 +212,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -232,7 +263,6 @@ # 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 # @@ -241,6 +271,20 @@ # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# # I2O device support # # CONFIG_I2O is not set @@ -283,8 +327,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 +339,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 +356,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 +374,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 @@ -376,6 +424,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -412,11 +461,19 @@ # 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 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 @@ -428,12 +485,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # 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 @@ -443,6 +505,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 @@ -484,6 +547,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -492,6 +560,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 @@ -534,6 +603,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -542,14 +616,22 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips/defconfig-hp-lj =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-hp-lj,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-hp-lj 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-hp-lj 4 Aug 2004 01:25:46 -0000 1.2 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,101 +11,213 @@ 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE 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_RM9000 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_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB 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 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_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 +# CONFIG_OOM_KILLER 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_HYDIII is not set +# CONFIG_MTD_MIRAGE 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 +225,28 @@ # 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_CISS_MONITOR_THREAD 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 +263,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 +273,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 @@ -160,6 +283,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -168,6 +297,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 +319,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Telephony Support # # CONFIG_PHONE is not set @@ -194,81 +333,98 @@ # # 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=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_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=y +# CONFIG_SCSI is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set # -# SCSI support type (disk, tape, CD-ROM) +# IEEE 1394 (FireWire) support (EXPERIMENTAL) # -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_IEEE1394 is not set # # I2O device support @@ -311,16 +467,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 +493,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 +510,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 +527,19 @@ # # 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_TMD_HERMES is not set +# CONFIG_PCI_HERMES is not set +CONFIG_NET_WIRELESS=y # # Token Ring devices @@ -393,9 +570,14 @@ # 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 +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -405,8 +587,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 +613,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_INTEL_RNG is not set +# CONFIG_SCx200 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 @@ -449,18 +638,18 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set -# CONFIG_DRM is not set # -# Multimedia devices +# Direct Rendering Manager (XFree86 DRI support) # -# CONFIG_VIDEO_DEV is not set +# CONFIG_DRM 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 +658,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 +669,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 +691,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 @@ -505,6 +701,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -512,12 +713,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 +733,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 +743,11 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Sound # # CONFIG_SOUND is not set @@ -550,119 +758,35 @@ # CONFIG_USB is not set # -# USB Controllers +# Support for USB gadgets # -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set +# CONFIG_USB_GADGET 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_DEBUG_INFO is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # -# 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 Index: arch/mips/defconfig-ip22 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-ip22,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-ip22 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-ip22 4 Aug 2004 01:25:46 -0000 1.2 @@ -21,17 +21,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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 +50,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,28 +62,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 # @@ -90,8 +104,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -104,13 +121,11 @@ # # 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 +# CONFIG_EISA is not set # 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 @@ -125,9 +140,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -154,6 +171,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set @@ -198,6 +216,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -243,7 +267,6 @@ # 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 # @@ -282,12 +305,14 @@ # 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_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set @@ -310,9 +335,19 @@ # 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 # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# # Network device support # CONFIG_NETDEVICES=y @@ -354,6 +389,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 @@ -403,6 +439,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -443,6 +480,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 +493,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,15 +504,21 @@ # 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=y +# CONFIG_INDYDOG is not set # CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200 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_DS1286=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -479,19 +528,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set -# CONFIG_DRM is not set # -# SGI Character devices +# Direct Rendering Manager (XFree86 DRI support) # -CONFIG_SGI_NEWPORT_CONSOLE=y -CONFIG_FONT_8x16=y -CONFIG_DUMMY_CONSOLE=y +# 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 @@ -501,11 +548,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,12 +584,17 @@ # 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 # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -550,6 +603,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 +653,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,20 +666,43 @@ # # Sound # -# CONFIG_SOUND 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 +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # -# SGI devices +# USB support # -CONFIG_SGI_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set -CONFIG_SGI_DS1286=y -# CONFIG_SGI_NEWPORT_GFX is not set +# CONFIG_USB is not set # -# USB support +# Support for USB gadgets # -# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set # # Bluetooth support @@ -633,12 +713,22 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips/defconfig-it8172 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-it8172,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-it8172 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-it8172 4 Aug 2004 01:25:46 -0000 1.2 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,40 +11,69 @@ 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE 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 +81,64 @@ 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_RM9000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB 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_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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -110,7 +146,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 +168,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 +186,18 @@ 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_HYDIII is not set +# CONFIG_MTD_MIRAGE 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 +226,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 +239,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_CISS_MONITOR_THREAD 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) @@ -225,6 +284,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -233,6 +298,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 +320,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Telephony Support # # CONFIG_PHONE is not set @@ -273,20 +348,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,61 +362,52 @@ # 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 -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 @@ -356,6 +415,20 @@ # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# # I2O device support # # CONFIG_I2O is not set @@ -397,17 +470,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 +495,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 +512,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 +560,14 @@ # 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 +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -523,14 +608,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_INTEL_RNG is not set +# CONFIG_SCx200 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 @@ -540,18 +633,18 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_ITE_GPIO is not set # -# Multimedia devices +# Direct Rendering Manager (XFree86 DRI support) # -# CONFIG_VIDEO_DEV is not set +# CONFIG_DRM is not set +# CONFIG_ITE_GPIO 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 +654,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 +670,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 @@ -597,6 +696,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -605,9 +709,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 +727,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 +737,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 +757,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 @@ -659,6 +770,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -666,123 +779,35 @@ # 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) +# Support for USB gadgets # +# CONFIG_USB_GADGET is not set # -# 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_DEBUG_INFO is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # -# 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 Index: arch/mips/defconfig-ivr =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-ivr,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-ivr 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-ivr 4 Aug 2004 01:25:47 -0000 1.2 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -20,31 +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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE 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 +79,37 @@ 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_RM9000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB 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 @@ -88,7 +118,6 @@ 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 @@ -102,8 +131,12 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -130,12 +163,14 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD 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) @@ -172,6 +207,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -231,15 +272,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 +285,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 +295,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 @@ -297,10 +327,10 @@ 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 @@ -308,6 +338,20 @@ # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# # I2O device support # # CONFIG_I2O is not set @@ -349,17 +393,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 +418,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 +435,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 +483,18 @@ # 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 +# CONFIG_INPUT_UINPUT is not set + +# # Character devices # CONFIG_VT=y @@ -493,13 +555,22 @@ # 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 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 @@ -509,17 +580,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set -# CONFIG_DRM is not set # -# Multimedia devices +# Direct Rendering Manager (XFree86 DRI support) # -# CONFIG_VIDEO_DEV 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 @@ -529,6 +600,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 +620,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 @@ -565,6 +642,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -573,9 +655,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 +673,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 +683,11 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Console drivers # # CONFIG_VGA_CONSOLE is not set @@ -626,7 +714,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 +729,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 +742,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 +753,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 +782,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,62 +795,46 @@ # 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 +# Support for USB gadgets # -# CONFIG_BLUEZ is not set +# CONFIG_USB_GADGET is not set # -# Input core support +# Bluetooth 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 +# CONFIG_BLUEZ 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips/defconfig-jmr3927 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-jmr3927,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-jmr3927 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-jmr3927 4 Aug 2004 01:25:47 -0000 1.2 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,99 +11,131 @@ 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE 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_RM9000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set +CONFIG_PAGE_SIZE_4KB=y # 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_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_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -115,6 +148,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 +161,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_CISS_MONITOR_THREAD 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) @@ -163,6 +206,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -171,6 +220,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 +242,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Telephony Support # # CONFIG_PHONE is not set @@ -198,7 +257,6 @@ # 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 # @@ -207,6 +265,20 @@ # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# # I2O device support # # CONFIG_I2O is not set @@ -248,15 +320,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 +343,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 +361,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 +409,14 @@ # 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 +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -350,6 +435,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 +444,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 +474,23 @@ # 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 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_DS1742=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -404,17 +500,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set -# CONFIG_DRM is not set # -# Multimedia devices +# Direct Rendering Manager (XFree86 DRI support) # -# CONFIG_VIDEO_DEV 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 @@ -424,6 +520,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 +536,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 @@ -460,6 +562,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -468,9 +575,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 +593,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 +603,11 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Console drivers # # CONFIG_VGA_CONSOLE is not set @@ -508,15 +621,20 @@ # 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_IT8181 is not set # CONFIG_FB_VIRTUAL is not set CONFIG_FBCON_ADVANCED=y CONFIG_FBCON_MFB=y @@ -551,121 +669,35 @@ # 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 +# Support for USB gadgets # -# 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_GADGET is not set # -# USB Human Interface Devices (HID) +# Bluetooth support # +# CONFIG_BLUEZ is not set # -# 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_DEBUG_INFO is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # -# 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 Index: arch/mips/defconfig-malta =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-malta,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-malta 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-malta 4 Aug 2004 01:25:47 -0000 1.2 @@ -13,23 +13,36 @@ # # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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 +50,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,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 @@ -57,11 +76,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 @@ -84,7 +106,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set # CONFIG_64BIT_PHYS_ADDR is not set @@ -101,7 +127,6 @@ 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 @@ -116,9 +141,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -145,6 +172,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set @@ -178,8 +206,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 @@ -188,6 +216,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -233,7 +267,6 @@ # 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 # @@ -270,12 +303,14 @@ # 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_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -306,9 +341,24 @@ # 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 # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# # I2O device support # # CONFIG_I2O is not set @@ -350,14 +400,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 +427,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 +445,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 @@ -441,6 +495,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -477,13 +532,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 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 @@ -493,12 +557,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # 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 is not set # CONFIG_REISERFS_FS is not set @@ -508,6 +577,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 @@ -549,6 +619,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -556,13 +631,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 @@ -599,6 +676,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -607,14 +689,22 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips/defconfig-nino =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-nino,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-nino 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-nino 4 Aug 2004 01:25:47 -0000 1.2 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,95 +11,129 @@ 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE 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_RM9000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set +CONFIG_PAGE_SIZE_4KB=y # 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_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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -111,6 +146,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 +159,16 @@ # 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_CISS_MONITOR_THREAD 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 @@ -162,6 +207,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -170,6 +221,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 +243,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Telephony Support # # CONFIG_PHONE is not set @@ -197,7 +258,6 @@ # 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 # @@ -206,13 +266,13 @@ # CONFIG_SCSI is not set # -# I2O device support +# Fusion MPT 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 +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set # # Network device support @@ -235,9 +295,14 @@ # 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 +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -257,6 +322,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 +331,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 +360,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_INTEL_RNG is not set +# CONFIG_SCx200 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 @@ -310,17 +385,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set -# CONFIG_DRM is not set # -# Multimedia devices +# Direct Rendering Manager (XFree86 DRI support) # -# CONFIG_VIDEO_DEV 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 @@ -330,6 +405,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 +421,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 @@ -366,6 +447,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -374,9 +460,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 +478,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 +488,11 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Console drivers # # CONFIG_VGA_CONSOLE is not set @@ -412,14 +504,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 +539,35 @@ # 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 +# Support for USB gadgets # -# 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_GADGET is not set # -# USB Human Interface Devices (HID) +# Bluetooth support # +# CONFIG_BLUEZ is not set # -# 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_DEBUG_INFO is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # -# 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 Index: arch/mips/defconfig-ocelot =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-ocelot,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-ocelot 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-ocelot 4 Aug 2004 01:25:47 -0000 1.2 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,102 +11,216 @@ 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE 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_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_RM9000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y CONFIG_CPU_HAS_PREFETCH=y +CONFIG_RM7000_CPU_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_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_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_OOM_KILLER 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_HYDIII is not set +# CONFIG_MTD_MIRAGE 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 +228,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 +241,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_CISS_MONITOR_THREAD 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) @@ -160,6 +285,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -168,6 +299,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 +321,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Telephony Support # # CONFIG_PHONE is not set @@ -195,7 +336,6 @@ # 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 # @@ -204,6 +344,20 @@ # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# # I2O device support # # CONFIG_I2O is not set @@ -245,15 +399,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 +422,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 +439,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 +487,14 @@ # 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 +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -365,12 +531,19 @@ # 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 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 @@ -382,17 +555,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set -# CONFIG_DRM is not set # -# Multimedia devices +# Direct Rendering Manager (XFree86 DRI support) # -# CONFIG_VIDEO_DEV 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 @@ -402,6 +575,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 +591,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 @@ -438,6 +617,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -446,9 +630,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 +648,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 +658,11 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Sound # # CONFIG_SOUND is not set @@ -483,123 +673,35 @@ # 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 +# Support for USB gadgets # +# CONFIG_USB_GADGET is not set # -# 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_DEBUG_INFO is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # -# 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 Index: arch/mips/defconfig-osprey =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-osprey,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-osprey 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-osprey 4 Aug 2004 01:25:47 -0000 1.2 @@ -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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE 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 +84,31 @@ # # 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_RM9000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB 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 @@ -89,7 +117,6 @@ 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 @@ -103,8 +130,12 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -131,12 +162,14 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD 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) @@ -173,6 +206,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -215,11 +254,26 @@ # CONFIG_PHONE_IXJ_PCMCIA is not set # +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_HD is not set + +# # SCSI support # # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# # Network device support # CONFIG_NETDEVICES=y @@ -256,10 +310,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,14 +358,30 @@ # 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 +# CONFIG_INPUT_UINPUT 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_VR41XX_KIU is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -337,13 +409,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 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 @@ -353,17 +434,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set -# CONFIG_DRM is not set # -# Multimedia devices +# Direct Rendering Manager (XFree86 DRI support) # -# CONFIG_VIDEO_DEV 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 @@ -373,6 +454,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 +474,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 @@ -409,6 +496,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -417,9 +509,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 +527,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 +537,11 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Console drivers # # CONFIG_VGA_CONSOLE is not set @@ -465,25 +563,35 @@ # CONFIG_USB is not set # -# Bluetooth support +# Support for USB gadgets # -# CONFIG_BLUEZ is not set +# CONFIG_USB_GADGET is not set # -# Input core support +# Bluetooth 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 +# CONFIG_BLUEZ 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips/defconfig-pb1000 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-pb1000,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-pb1000 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-pb1000 4 Aug 2004 01:25:47 -0000 1.2 @@ -21,18 +21,29 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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 +51,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -49,22 +63,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_AU1000=y +CONFIG_NEW_TIME_C=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 @@ -84,14 +103,18 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set 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 # @@ -101,7 +124,6 @@ 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 @@ -115,8 +137,10 @@ # 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 # # PCI Hotplug Support @@ -124,7 +148,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,8 +156,11 @@ # 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_OOM_KILLER is not set # CONFIG_PM is not set # @@ -145,6 +171,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 +190,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 +206,22 @@ 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_HYDIII is not set +# CONFIG_MTD_MIRAGE 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 @@ -224,6 +259,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set @@ -267,6 +303,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -326,15 +368,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 +381,14 @@ # 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_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 @@ -364,6 +396,20 @@ # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# # I2O device support # # CONFIG_I2O is not set @@ -392,7 +438,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 +464,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,11 +553,13 @@ # 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 +# CONFIG_VIA_IRCC_FIR is not set # # ISDN subsystem @@ -519,11 +569,14 @@ # # 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 +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -552,10 +605,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,22 +630,53 @@ # 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 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 @@ -600,6 +686,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -607,13 +697,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 +714,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 @@ -665,6 +757,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -673,6 +770,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 +822,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 @@ -733,6 +832,7 @@ CONFIG_PB1000_CRT=y # CONFIG_PB1000_NTSC is not set # CONFIG_PB1000_TFT is not set +# CONFIG_FB_IT8181 is not set # CONFIG_FB_VIRTUAL is not set CONFIG_FBCON_ADVANCED=y # CONFIG_FBCON_MFB is not set @@ -776,7 +876,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 @@ -784,11 +884,115 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # 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 + +# +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set # # Bluetooth support @@ -799,14 +1003,23 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set # # Library routines # +# CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y +# CONFIG_FW_LOADER is not set Index: arch/mips/defconfig-pb1100 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-pb1100,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-pb1100 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-pb1100 4 Aug 2004 01:25:47 -0000 1.2 @@ -21,17 +21,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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 +50,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,23 +62,28 @@ # 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_NEW_TIME_C=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 @@ -84,14 +103,18 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set 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 # @@ -101,30 +124,12 @@ 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_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,8 +138,11 @@ # 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_OOM_KILLER is not set # CONFIG_PM is not set # @@ -145,6 +153,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 +172,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 +187,25 @@ # 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_HYDIII is not set +# CONFIG_MTD_MIRAGE 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 @@ -224,6 +243,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y @@ -252,7 +272,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 @@ -277,8 +297,19 @@ # CONFIG_IP_NF_ARPTABLES is not set # CONFIG_IP_NF_COMPAT_IPCHAINS is not set # CONFIG_IP_NF_COMPAT_IPFWADM is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -338,16 +369,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 +382,14 @@ # 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_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 @@ -376,6 +397,20 @@ # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# # I2O device support # # CONFIG_I2O is not set @@ -404,7 +439,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 +465,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 +500,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,11 +545,13 @@ # 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 # CONFIG_ALI_FIR is not set # CONFIG_VLSI_FIR is not set +# CONFIG_VIA_IRCC_FIR is not set # # ISDN subsystem @@ -538,11 +561,14 @@ # # 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 +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -571,10 +597,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,22 +622,53 @@ # 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 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 @@ -619,20 +678,19 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set -# CONFIG_DRM is not set # -# PCMCIA character devices +# Direct Rendering Manager (XFree86 DRI support) # -# 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_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=m CONFIG_AUTOFS4_FS=m CONFIG_REISERFS_FS=m @@ -642,6 +700,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 @@ -686,6 +745,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -694,6 +758,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 +853,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_AU1100 is not set +CONFIG_FB_AU1100=y +# CONFIG_FB_IT8181 is not set # CONFIG_FB_VIRTUAL is not set CONFIG_FBCON_ADVANCED=y # CONFIG_FBCON_MFB is not set @@ -838,7 +905,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 @@ -846,11 +913,115 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # 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 + +# +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set # # Bluetooth support @@ -861,14 +1032,22 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set # # Library routines # +# CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m Index: arch/mips/defconfig-pb1500 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-pb1500,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-pb1500 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-pb1500 4 Aug 2004 01:25:47 -0000 1.2 @@ -21,17 +21,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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 +50,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,22 +62,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_AU1500=y +CONFIG_NEW_TIME_C=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 @@ -83,14 +101,18 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB 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 # @@ -100,7 +122,6 @@ 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 @@ -114,7 +135,10 @@ # 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 # # PCI Hotplug Support @@ -122,7 +146,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,8 +154,11 @@ # 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_OOM_KILLER is not set # CONFIG_PM is not set # @@ -143,6 +169,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 +188,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 +204,24 @@ # 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_HYDIII is not set +# CONFIG_MTD_MIRAGE 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 @@ -224,6 +259,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y @@ -277,8 +313,19 @@ # CONFIG_IP_NF_ARPTABLES is not set # CONFIG_IP_NF_COMPAT_IPCHAINS is not set # CONFIG_IP_NF_COMPAT_IPFWADM is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -338,15 +385,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 +398,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 +408,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 @@ -402,10 +439,10 @@ 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 @@ -413,6 +450,20 @@ # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# # I2O device support # # CONFIG_I2O is not set @@ -441,7 +492,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 +507,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 +534,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 +552,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 @@ -571,6 +627,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -599,10 +656,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,13 +712,22 @@ # 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 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 @@ -669,6 +737,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -676,13 +748,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 +765,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 @@ -736,6 +810,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -744,6 +823,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 +918,16 @@ # 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_IT8181 is not set # CONFIG_FB_VIRTUAL is not set CONFIG_FBCON_ADVANCED=y # CONFIG_FBCON_MFB is not set @@ -887,7 +971,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 @@ -895,6 +979,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -907,7 +993,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 +1030,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 +1061,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 @@ -997,6 +1085,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -1005,14 +1098,23 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set # # Library routines # +# CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m +# CONFIG_FW_LOADER is not set Index: arch/mips/defconfig-rm200 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-rm200,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-rm200 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-rm200 4 Aug 2004 01:25:47 -0000 1.2 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -20,38 +21,63 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE 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 +87,32 @@ # # 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_RM9000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB 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 @@ -88,8 +120,8 @@ CONFIG_CPU_LITTLE_ENDIAN=y # CONFIG_ARC_CONSOLE is not set CONFIG_NET=y -# CONFIG_PCI_NAMES is not set CONFIG_EISA=y +# CONFIG_PCI_NAMES is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -103,8 +135,12 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -131,12 +167,14 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD 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) @@ -170,6 +208,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -215,7 +259,6 @@ # 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 # @@ -224,6 +267,20 @@ # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# # I2O device support # # CONFIG_I2O is not set @@ -259,6 +316,16 @@ # 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 +# CONFIG_INPUT_UINPUT is not set + +# # Character devices # CONFIG_VT=y @@ -293,11 +360,19 @@ # 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 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 @@ -309,17 +384,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set -# CONFIG_DRM is not set # -# Multimedia devices +# Direct Rendering Manager (XFree86 DRI support) # -# CONFIG_VIDEO_DEV 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 @@ -329,6 +404,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 +424,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 @@ -365,6 +446,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -373,9 +459,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 +477,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 +496,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 @@ -434,23 +527,35 @@ # CONFIG_USB is not set # -# Bluetooth support +# Support for USB gadgets # -# CONFIG_BLUEZ is not set +# CONFIG_USB_GADGET is not set # -# Input core support +# Bluetooth 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 +# CONFIG_BLUEZ 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips/defconfig-sb1250-swarm =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-sb1250-swarm,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-sb1250-swarm 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-sb1250-swarm 4 Aug 2004 01:25:47 -0000 1.2 @@ -21,17 +21,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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 +50,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,27 +62,45 @@ # 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_BW_TRACE 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 @@ -90,15 +122,15 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 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_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB 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,11 +144,9 @@ # # 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 -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -131,9 +161,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -160,6 +192,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set @@ -183,8 +216,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 @@ -199,6 +233,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -243,9 +283,42 @@ # # 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_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 @@ -253,6 +326,15 @@ # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# # Network device support # CONFIG_NETDEVICES=y @@ -294,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 @@ -343,6 +426,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -370,12 +454,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 +487,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 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 @@ -419,12 +512,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # 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 @@ -434,6 +532,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 @@ -475,6 +574,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -483,6 +587,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 @@ -526,6 +631,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -534,11 +644,23 @@ # 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_DEBUG_INFO is not set +# CONFIG_SB1XXX_CORELIS is not set # CONFIG_MAGIC_SYSRQ is not set +CONFIG_NR_CPUS=32 +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips/defconfig-sead =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/defconfig-sead,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/defconfig-sead 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/defconfig-sead 4 Aug 2004 01:25:48 -0000 1.2 @@ -19,17 +19,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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,9 @@ 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,16 +60,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 @@ -79,7 +96,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set # CONFIG_64BIT_PHYS_ADDR is not set @@ -96,7 +117,6 @@ # CONFIG_NET is not set # 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 @@ -111,9 +131,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -140,6 +162,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y @@ -152,7 +175,7 @@ # # MIPS initrd options # -CONFIG_EMBEDDED_RAMDISK=y +# CONFIG_EMBEDDED_RAMDISK is not set # # Multi-device support (RAID and LVM) @@ -177,7 +200,6 @@ # 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 # @@ -186,6 +208,15 @@ # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# # Amateur Radio support # # CONFIG_HAMRADIO is not set @@ -198,6 +229,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -233,13 +265,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 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 @@ -249,12 +290,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # 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 @@ -264,6 +310,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 @@ -305,6 +352,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # CONFIG_NCPFS_NLS is not set # CONFIG_SMB_FS is not set # CONFIG_ZISOFS_FS is not set @@ -347,17 +399,30 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips/ld.script.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ld.script.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ld.script.in 22 Jul 2004 19:49:13 -0000 1.1 +++ arch/mips/ld.script.in 4 Aug 2004 01:25:48 -0000 1.2 @@ -49,9 +49,6 @@ . = ALIGN(4096); /* Align double page for init_task_union */ __init_end = .; - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - . = ALIGN(32); .data.cacheline_aligned : { *(.data.cacheline_aligned) } @@ -81,8 +78,8 @@ . = ALIGN(4096); __rd_start = .; *(.initrd) - __rd_end = .; . = ALIGN(4096); + __rd_end = .; CONSTRUCTORS } Index: arch/mips/algor/README =================================================================== RCS file: arch/mips/algor/README diff -N arch/mips/algor/README --- arch/mips/algor/README 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: arch/mips/arc/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/arc/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/arc/Makefile 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/arc/Makefile 4 Aug 2004 01:25:48 -0000 1.2 @@ -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 Index: arch/mips/arc/arc_con.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/arc/arc_con.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/arc/arc_con.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/arc/arc_con.c 4 Aug 2004 01:25:48 -0000 1.2 @@ -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, }; /* Index: arch/mips/arc/cmdline.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/arc/cmdline.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/arc/cmdline.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/arc/cmdline.c 4 Aug 2004 01:25:48 -0000 1.2 @@ -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 } Index: arch/mips/arc/console.c =================================================================== RCS file: arch/mips/arc/console.c diff -N arch/mips/arc/console.c --- arch/mips/arc/console.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); -} Index: arch/mips/arc/identify.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/arc/identify.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/arc/identify.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/arc/identify.c 4 Aug 2004 01:25:48 -0000 1.2 @@ -32,7 +32,7 @@ { "SGI-IP22", "SGI Indy", MACH_GROUP_SGI, - MACH_SGI_INDY, + MACH_SGI_IP22, PROM_FLAG_ARCS }, { "SGI-IP27", "SGI Origin", @@ -44,11 +44,6 @@ MACH_GROUP_SGI, MACH_SGI_IP28, PROM_FLAG_ARCS - }, { "SGI-IP32", - "SGI IP32", - MACH_GROUP_SGI, - MACH_SGI_IP32, - PROM_FLAG_ARCS }, { "Microsoft-Jazz", "Jazz MIPS_Magnum_4000", MACH_GROUP_JAZZ, @@ -63,7 +58,7 @@ "SNI RM200_PCI", MACH_GROUP_SNI_RM, MACH_SNI_RM200_PCI, - 0 + PROM_FLAG_DONT_FREE_TEMP } }; Index: arch/mips/arc/memory.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/arc/memory.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/arc/memory.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/arc/memory.c 4 Aug 2004 01:25:48 -0000 1.2 @@ -26,6 +26,12 @@ #undef DEBUG +/* + * For ARC firmware memory functions the unit of meassuring memory is always + * a 4k page of memory + */ +#define ARC_PAGE_SHIFT 12 + struct linux_mdesc * __init ArcGetMemoryDescriptor(struct linux_mdesc *Current) { return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current); @@ -127,20 +133,23 @@ unsigned long base, size; long type; - base = p->base << PAGE_SHIFT; - size = p->pages << PAGE_SHIFT; + base = p->base << ARC_PAGE_SHIFT; + size = p->pages << ARC_PAGE_SHIFT; type = prom_memtype_classify(p->type); add_memory_region(base, size, type); } } -void __init prom_free_prom_memory (void) +void __init prom_free_prom_memory(void) { unsigned long freed = 0; unsigned long addr; int i; + if (prom_flags & PROM_FLAG_DONT_FREE_TEMP) + return 0; + for (i = 0; i < boot_mem_map.nr_map; i++) { if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) continue; Index: arch/mips/au1000/common/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/au1000/common/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/au1000/common/Makefile 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/au1000/common/Makefile 4 Aug 2004 01:25:48 -0000 1.2 @@ -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 sleeper.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 Index: arch/mips/au1000/common/clocks.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/au1000/common/clocks.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/au1000/common/clocks.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/au1000/common/clocks.c 4 Aug 2004 01:25:48 -0000 1.2 @@ -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); Index: arch/mips/au1000/common/dbg_io.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/au1000/common/dbg_io.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/au1000/common/dbg_io.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/au1000/common/dbg_io.c 4 Aug 2004 01:25:48 -0000 1.2 @@ -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); } Index: arch/mips/au1000/common/dma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/au1000/common/dma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/au1000/common/dma.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/au1000/common/dma.c 4 Aug 2004 01:25:48 -0000 1.2 @@ -40,7 +40,7 @@ #include #include - +#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1100) /* * A note on resource allocation: @@ -95,7 +95,6 @@ {I2S_DATA, DMA_DR | DMA_DW32 | DMA_NC} }; - int au1000_dma_read_proc(char *buf, char **start, off_t fpos, int length, int *eof, void *data) { @@ -198,7 +197,6 @@ return i; } - void free_au1000_dma(unsigned int dmanr) { struct dma_chan *chan = get_dma_chan(dmanr); @@ -215,3 +213,4 @@ chan->irq_dev = NULL; chan->dev_id = -1; } +#endif // AU1000 AU1500 AU1100 Index: arch/mips/au1000/common/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/au1000/common/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/au1000/common/irq.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/au1000/common/irq.c 4 Aug 2004 01:25:48 -0000 1.2 @@ -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 @@ -87,16 +81,18 @@ static inline void mask_and_ack_level_irq(unsigned int irq_nr); static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr); static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr); +static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr); 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); +void (*board_init_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) { @@ -114,6 +110,11 @@ au_writel(1<<(irq_nr-32), IC1_CFG1SET); au_writel(1<<(irq_nr-32), IC1_CFG0CLR); break; + case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ + au_writel(1<<(irq_nr-32), IC1_CFG2CLR); + au_writel(1<<(irq_nr-32), IC1_CFG1SET); + au_writel(1<<(irq_nr-32), IC1_CFG0SET); + break; case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ au_writel(1<<(irq_nr-32), IC1_CFG2SET); au_writel(1<<(irq_nr-32), IC1_CFG1CLR); @@ -156,6 +157,11 @@ au_writel(1< AU1000_LAST_INTC0_INT) { + au_writel(1<<(irq_nr-32), IC1_FALLINGCLR); + au_writel(1<<(irq_nr-32), IC1_RISINGCLR); + au_writel(1<<(irq_nr-32), IC1_MASKCLR); + } + else { + au_writel(1<im_irq, imp->im_type, imp->im_request); - case AU1000_SSI0_INT: - case AU1000_SSI1_INT: -#endif - case AU1000_DMA_INT_BASE: - case AU1000_DMA_INT_BASE+1: - case AU1000_DMA_INT_BASE+2: - case AU1000_DMA_INT_BASE+3: - case AU1000_DMA_INT_BASE+4: - case AU1000_DMA_INT_BASE+5: - case AU1000_DMA_INT_BASE+6: - case AU1000_DMA_INT_BASE+7: + switch (imp->im_type) { - case AU1000_IRDA_TX_INT: - case AU1000_IRDA_RX_INT: + case INTC_INT_HIGH_LEVEL: + irq_desc[imp->im_irq].handler = &level_irq_type; + break; - 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_LOW_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_RISE_EDGE: + irq_desc[imp->im_irq].handler = &rise_edge_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_FALL_EDGE: + irq_desc[imp->im_irq].handler = &fall_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; + case INTC_INT_RISE_AND_FALL_EDGE: + irq_desc[imp->im_irq].handler = &either_edge_irq_type; + break; + + default: + panic("Unknown au1xxx irq map"); + break; } + imp++; } - set_cp0_status(ALLINTS); -#ifdef CONFIG_REMOTE_DEBUG + set_c0_status(ALLINTS); + + /* Board specific IRQ initialization. + */ + if (board_init_irq) + (*board_init_irq)(); + +#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 +491,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 +509,33 @@ return; } - for (i=0; i<32; i++) { - if ((intc0_req0 & (1< + #include #include #include #include -#include #include #include @@ -49,13 +48,12 @@ # define DPRINTK(fmt, args...) #endif -extern void au1k_wait(void); static void calibrate_delay(void); -extern void set_au1000_speed(unsigned int new_freq); -extern unsigned int get_au1000_speed(void); -extern unsigned long get_au1000_uart_baud_base(void); -extern void set_au1000_uart_baud_base(unsigned long new_baud_base); +extern void set_au1x00_speed(unsigned int new_freq); +extern unsigned int get_au1x00_speed(void); +extern unsigned long get_au1x00_uart_baud_base(void); +extern void set_au1x00_uart_baud_base(unsigned long new_baud_base); extern unsigned long save_local_and_disable(int controller); extern void restore_local_and_enable(int controller, unsigned long mask); extern void local_enable_irq(unsigned int irq_nr); @@ -67,6 +65,143 @@ #ifdef CONFIG_PM +static spinlock_t pm_lock = SPIN_LOCK_UNLOCKED; + +/* We need to save/restore a bunch of core registers that are + * either volatile or reset to some state across a processor sleep. + * If reading a register doesn't provide a proper result for a + * later restore, we have to provide a function for loading that + * register and save a copy. + * + * We only have to save/restore registers that aren't otherwise + * done as part of a driver pm_* function. + */ +static uint sleep_aux_pll_cntrl; +static uint sleep_cpu_pll_cntrl; +static uint sleep_pin_function; +static uint sleep_uart0_inten; +static uint sleep_uart0_fifoctl; +static uint sleep_uart0_linectl; +static uint sleep_uart0_clkdiv; +static uint sleep_uart0_enable; +static uint sleep_usbhost_enable; +static uint sleep_usbdev_enable; +static uint sleep_static_memctlr[4][3]; + +/* Define this to cause the value you write to /proc/sys/pm/sleep to + * set the TOY timer for the amount of time you want to sleep. + * This is done mainly for testing, but may be useful in other cases. + * The value is number of 32KHz ticks to sleep. + */ +#define SLEEP_TEST_TIMEOUT 1 +#ifdef SLEEP_TEST_TIMEOUT +static int sleep_ticks; +void wakeup_counter0_set(int ticks); +#endif + +static void +save_core_regs(void) +{ + extern void save_au1xxx_intctl(void); + extern void pm_eth0_shutdown(void); + + /* Do the serial ports.....these really should be a pm_* + * registered function by the driver......but of course the + * standard serial driver doesn't understand our Au1xxx + * unique registers. + */ + sleep_uart0_inten = au_readl(UART0_ADDR + UART_IER); + sleep_uart0_fifoctl = au_readl(UART0_ADDR + UART_FCR); + sleep_uart0_linectl = au_readl(UART0_ADDR + UART_LCR); + sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK); + sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL); + + /* Shutdown USB host/device. + */ + sleep_usbhost_enable = au_readl(USB_HOST_CONFIG); + + /* There appears to be some undocumented reset register.... + */ + au_writel(0, 0xb0100004); au_sync(); + au_writel(0, USB_HOST_CONFIG); au_sync(); + + sleep_usbdev_enable = au_readl(USBD_ENABLE); + au_writel(0, USBD_ENABLE); au_sync(); + + /* Save interrupt controller state. + */ + save_au1xxx_intctl(); + + /* Clocks and PLLs. + */ + sleep_aux_pll_cntrl = au_readl(SYS_AUXPLL); + + /* We don't really need to do this one, but unless we + * write it again it won't have a valid value if we + * happen to read it. + */ + sleep_cpu_pll_cntrl = au_readl(SYS_CPUPLL); + + sleep_pin_function = au_readl(SYS_PINFUNC); + + /* Save the static memory controller configuration. + */ + sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0); + sleep_static_memctlr[0][1] = au_readl(MEM_STTIME0); + sleep_static_memctlr[0][2] = au_readl(MEM_STADDR0); + sleep_static_memctlr[1][0] = au_readl(MEM_STCFG1); + sleep_static_memctlr[1][1] = au_readl(MEM_STTIME1); + sleep_static_memctlr[1][2] = au_readl(MEM_STADDR1); + sleep_static_memctlr[2][0] = au_readl(MEM_STCFG2); + sleep_static_memctlr[2][1] = au_readl(MEM_STTIME2); + sleep_static_memctlr[2][2] = au_readl(MEM_STADDR2); + sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3); + sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3); + sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3); +} + +static void +restore_core_regs(void) +{ + extern void restore_au1xxx_intctl(void); + extern void wakeup_counter0_adjust(void); + + au_writel(sleep_aux_pll_cntrl, SYS_AUXPLL); au_sync(); + au_writel(sleep_cpu_pll_cntrl, SYS_CPUPLL); au_sync(); + au_writel(sleep_pin_function, SYS_PINFUNC); au_sync(); + + /* Restore the static memory controller configuration. + */ + au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); + au_writel(sleep_static_memctlr[0][1], MEM_STTIME0); + au_writel(sleep_static_memctlr[0][2], MEM_STADDR0); + au_writel(sleep_static_memctlr[1][0], MEM_STCFG1); + au_writel(sleep_static_memctlr[1][1], MEM_STTIME1); + au_writel(sleep_static_memctlr[1][2], MEM_STADDR1); + au_writel(sleep_static_memctlr[2][0], MEM_STCFG2); + au_writel(sleep_static_memctlr[2][1], MEM_STTIME2); + au_writel(sleep_static_memctlr[2][2], MEM_STADDR2); + au_writel(sleep_static_memctlr[3][0], MEM_STCFG3); + au_writel(sleep_static_memctlr[3][1], MEM_STTIME3); + au_writel(sleep_static_memctlr[3][2], MEM_STADDR3); + + /* Enable the UART if it was enabled before sleep. + * I guess I should define module control bits........ + */ + if (sleep_uart0_enable & 0x02) { + au_writel(0, UART0_ADDR + UART_MOD_CNTRL); au_sync(); + au_writel(1, UART0_ADDR + UART_MOD_CNTRL); au_sync(); + au_writel(3, UART0_ADDR + UART_MOD_CNTRL); au_sync(); + au_writel(sleep_uart0_inten, UART0_ADDR + UART_IER); au_sync(); + au_writel(sleep_uart0_fifoctl, UART0_ADDR + UART_FCR); au_sync(); + au_writel(sleep_uart0_linectl, UART0_ADDR + UART_LCR); au_sync(); + au_writel(sleep_uart0_clkdiv, UART0_ADDR + UART_CLK); au_sync(); + } + + restore_au1xxx_intctl(); + wakeup_counter0_adjust(); +} + unsigned long suspend_mode; void wakeup_from_suspend(void) @@ -77,34 +212,49 @@ int au_sleep(void) { unsigned long wakeup, flags; - save_and_cli(flags); + extern void save_and_sleep(void); + + spin_lock_irqsave(&pm_lock,flags); + + save_core_regs(); flush_cache_all(); - /* pin 6 is gpio */ + + /** The code below is all system dependent and we should probably + ** have a function call out of here to set this up. You need + ** to configure the GPIO or timer interrupts that will bring + ** you out of sleep. + ** For testing, the TOY counter wakeup is useful. + **/ + +#if 0 au_writel(au_readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD); /* gpio 6 can cause a wake up event */ wakeup = au_readl(SYS_WAKEMSK); wakeup &= ~(1 << 8); /* turn off match20 wakeup */ wakeup |= 1 << 6; /* turn on gpio 6 wakeup */ - au_writel(wakeup, SYS_WAKEMSK); - +#else + /* For testing, allow match20 to wake us up. + */ +#ifdef SLEEP_TEST_TIMEOUT + wakeup_counter0_set(sleep_ticks); +#endif + wakeup = 1 << 8; /* turn on match20 wakeup */ + wakeup = 0; +#endif au_writel(1, SYS_WAKESRC); /* clear cause */ - au_writel(1, SYS_SLPPWR); /* prepare to sleep */ + au_sync(); + au_writel(wakeup, SYS_WAKEMSK); + au_sync(); - __asm__("la $4, 1f\n\t" - "lui $5, 0xb190\n\t" - "ori $5, 0x18\n\t" - "sw $4, 0($5)\n\t" - "li $4, 1\n\t" - "lui $5, 0xb190\n\t" - "ori $5, 0x7c\n\t" - "sw $4, 0($5)\n\t" "sync\n\t" "1:\t\n\t" "nop\n\t"); + save_and_sleep(); /* 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); + restore_core_regs(); + spin_unlock_irqrestore(&pm_lock, flags); return 0; } @@ -112,11 +262,27 @@ void *buffer, size_t * len) { int retval = 0; +#ifdef SLEEP_TEST_TIMEOUT +#define TMPBUFLEN2 16 + char buf[TMPBUFLEN2], *p; +#endif if (!write) { *len = 0; } else { +#ifdef SLEEP_TEST_TIMEOUT + if (*len > TMPBUFLEN2 - 1) { + return -EFAULT; + } + if (copy_from_user(buf, buffer, *len)) { + return -EFAULT; + } + buf[*len] = 0; + p = buf; + sleep_ticks = simple_strtoul(p, &p, 0); +#endif retval = pm_send_all(PM_SUSPEND, (void *) 2); + if (retval) return retval; @@ -130,6 +296,7 @@ void *buffer, size_t * len) { int retval = 0; + void au1k_wait(void); if (!write) { *len = 0; @@ -158,41 +325,41 @@ 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; } - old_baud_base = get_au1000_uart_baud_base(); - old_cpu_freq = get_au1000_speed(); + old_baud_base = get_au1x00_uart_baud_base(); + old_cpu_freq = get_au1x00_speed(); new_cpu_freq = pll * 12 * 1000000; new_baud_base = (new_cpu_freq / 4) / 16; - set_au1000_speed(new_cpu_freq); - set_au1000_uart_baud_base(new_baud_base); + set_au1x00_speed(new_cpu_freq); + set_au1x00_uart_baud_base(new_baud_base); old_refresh = au_readl(MEM_SDREFCFG) & 0x1ffffff; new_refresh = @@ -247,7 +414,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); @@ -322,5 +489,4 @@ loops_per_jiffy &= ~loopbit; } } - #endif /* CONFIG_PM */ Index: arch/mips/au1000/common/prom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/au1000/common/prom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/au1000/common/prom.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/au1000/common/prom.c 4 Aug 2004 01:25:48 -0000 1.2 @@ -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); Index: arch/mips/au1000/common/puts.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/au1000/common/puts.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/au1000/common/puts.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/au1000/common/puts.c 4 Aug 2004 01:25:48 -0000 1.2 @@ -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 Index: arch/mips/au1000/common/reset.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/au1000/common/reset.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/au1000/common/reset.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/au1000/common/reset.c 4 Aug 2004 01:25:48 -0000 1.2 @@ -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) @@ -54,6 +54,10 @@ au_writel(0x00, 0xb017fffc); /* usbh_enable */ au_writel(0x00, 0xb0200058); /* usbd_enable */ au_writel(0x00, 0xb0300040); /* ir_enable */ + au_writel(0x00, 0xb4004104); /* mac dma */ + au_writel(0x00, 0xb4004114); /* mac dma */ + au_writel(0x00, 0xb4004124); /* mac dma */ + au_writel(0x00, 0xb4004134); /* mac dma */ au_writel(0x00, 0xb0520000); /* macen0 */ au_writel(0x00, 0xb0520004); /* macen1 */ au_writel(0x00, 0xb1000008); /* i2s_enable */ @@ -66,6 +70,8 @@ au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */ au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */ au_writel(0x00, 0xb1900028); /* sys_clksrc */ + au_writel(0x10, 0xb1900060); /* sys_cpupll */ + au_writel(0x00, 0xb1900064); /* sys_auxpll */ au_writel(0x00, 0xb1900100); /* sys_pininputen */ break; case 0x01000000: /* Au1500 */ @@ -74,6 +80,10 @@ asm("sync"); au_writel(0x00, 0xb017fffc); /* usbh_enable */ au_writel(0x00, 0xb0200058); /* usbd_enable */ + au_writel(0x00, 0xb4004104); /* mac dma */ + au_writel(0x00, 0xb4004114); /* mac dma */ + au_writel(0x00, 0xb4004124); /* mac dma */ + au_writel(0x00, 0xb4004134); /* mac dma */ au_writel(0x00, 0xb1520000); /* macen0 */ au_writel(0x00, 0xb1520004); /* macen1 */ au_writel(0x00, 0xb1100100); /* uart0_enable */ @@ -81,6 +91,8 @@ au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */ au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */ au_writel(0x00, 0xb1900028); /* sys_clksrc */ + au_writel(0x10, 0xb1900060); /* sys_cpupll */ + au_writel(0x00, 0xb1900064); /* sys_auxpll */ au_writel(0x00, 0xb1900100); /* sys_pininputen */ break; case 0x02000000: /* Au1100 */ @@ -90,6 +102,10 @@ au_writel(0x00, 0xb017fffc); /* usbh_enable */ au_writel(0x00, 0xb0200058); /* usbd_enable */ au_writel(0x00, 0xb0300040); /* ir_enable */ + au_writel(0x00, 0xb4004104); /* mac dma */ + au_writel(0x00, 0xb4004114); /* mac dma */ + au_writel(0x00, 0xb4004124); /* mac dma */ + au_writel(0x00, 0xb4004134); /* mac dma */ au_writel(0x00, 0xb0520000); /* macen0 */ au_writel(0x00, 0xb1000008); /* i2s_enable */ au_writel(0x00, 0xb1100100); /* uart0_enable */ @@ -100,6 +116,8 @@ au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */ au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */ au_writel(0x00, 0xb1900028); /* sys_clksrc */ + au_writel(0x10, 0xb1900060); /* sys_cpupll */ + au_writel(0x00, 0xb1900064); /* sys_auxpll */ au_writel(0x00, 0xb1900100); /* sys_pininputen */ break; @@ -107,10 +125,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)); } Index: arch/mips/au1000/common/serial.c =================================================================== RCS file: arch/mips/au1000/common/serial.c diff -N arch/mips/au1000/common/serial.c --- arch/mips/au1000/common/serial.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: -*/ Index: arch/mips/au1000/common/time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/au1000/common/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/au1000/common/time.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/au1000/common/time.c 4 Aug 2004 01:25:48 -0000 1.2 @@ -25,6 +25,11 @@ * * Setting up the clock on the MIPS boards. * + * Update. Always configure the kernel with CONFIG_NEW_TIME_C. This + * will use the user interface gettimeofday() functions from the + * arch/mips/kernel/time.c, and we provide the clock interrupt processing + * and the timer offset compute functions. If CONFIG_PM is selected, + * we also ensure the 32KHz timer is available. -- Dan */ #include @@ -44,15 +49,20 @@ #include #include -extern void startup_match20_interrupt(void); +#if !defined(CONFIG_NEW_TIME_C) +#error "Alchemy processors need CONFIG_NEW_TIME_C defined" +#endif +extern void startup_match20_interrupt(void); +extern void do_softirq(void); extern volatile unsigned long wall_jiffies; unsigned long missed_heart_beats = 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 rwlock_t xtime_lock; -unsigned int mips_counter_frequency = 0; +int no_au1xxx_32khz; +void (*au1k_wait_ptr)(void); /* Cycle counter value at the previous timer interrupt.. */ static unsigned int timerhi = 0, timerlo = 0; @@ -63,9 +73,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); } /* @@ -83,17 +95,11 @@ irq_enter(cpu, irq); kstat.irqs[cpu][irq]++; -#ifdef CONFIG_PM - printk(KERN_ERR "Unexpected CP0 interrupt\n"); - regs->cp0_status &= ~IE_IRQ5; /* disable CP0 interrupt */ - return; -#endif - if (r4k_offset == 0) goto null; do { - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); timerhi += (count < timerlo); /* Wrap around */ timerlo = count; @@ -102,7 +108,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); @@ -158,108 +164,141 @@ do_timer(regs); /* increment jiffies by one */ } } -#endif -/* - * Figure out the r4k offset, the amount to increment the compare - * register for each time tick. - * Use the Programmable Counter 1 to do this. +/* When we wakeup from sleep, we have to "catch up" on all of the + * timer ticks we have missed. */ -unsigned long cal_r4koff(void) +void +wakeup_counter0_adjust(void) { - unsigned long count; - unsigned long cpu_speed; - unsigned long start, end; - unsigned long counter; - int trim_divide = 16; - unsigned long flags; + unsigned long pc0; + int time_elapsed; - save_and_cli(flags); + pc0 = au_readl(SYS_TOYREAD); + if (pc0 < last_match20) { + /* counter overflowed */ + time_elapsed = (0xffffffff - last_match20) + pc0; + } + else { + time_elapsed = pc0 - last_match20; + } - counter = au_readl(SYS_COUNTER_CNTRL); - au_writel(counter | SYS_CNTRL_EN1, SYS_COUNTER_CNTRL); + while (time_elapsed > 0) { + time_elapsed -= MATCH20_INC; + last_match20 += MATCH20_INC; + } - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S); - au_writel(trim_divide-1, SYS_RTCTRIM); /* RTC now ticks at 32.768/16 kHz */ - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S); - - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S); - au_writel (0, SYS_TOYWRITE); - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S); - - start = au_readl(SYS_RTCREAD); - start += 2; - /* wait for the beginning of a new tick */ - while (au_readl(SYS_RTCREAD) < start); - - /* Start r4k counter. */ - write_32bit_cp0_register(CP0_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); - cpu_speed = count * 2; - mips_counter_frequency = count; - set_au1000_uart_baud_base(((cpu_speed) / 4) / 16); - restore_flags(flags); - return (cpu_speed / HZ); -} + last_pc0 = pc0; + au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); + au_sync(); +} -void __init time_init(void) +/* This is just for debugging to set the timer for a sleep delay. +*/ +void +wakeup_counter0_set(int ticks) { - unsigned int est_freq; + unsigned long pc0; - printk("calculating r4koff... "); - r4k_offset = cal_r4koff(); - printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset); + pc0 = au_readl(SYS_TOYREAD); + last_pc0 = pc0; + au_writel(last_match20 + (MATCH20_INC * ticks), SYS_TOYMATCH2); + au_sync(); +} +#endif - //est_freq = 2*r4k_offset*HZ; - est_freq = r4k_offset*HZ; - est_freq += 5000; /* round */ - 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); +/* I haven't found anyone that doesn't use a 12 MHz source clock, + * but just in case..... + */ +#ifdef CONFIG_AU1000_SRC_CLK +#define AU1000_SRC_CLK CONFIG_AU1000_SRC_CLK +#else +#define AU1000_SRC_CLK 12000000 +#endif - write_32bit_cp0_register(CP0_COMPARE, r4k_cur); +/* + * We read the real processor speed from the PLL. This is important + * because it is more accurate than computing it from the 32KHz + * counter, if it exists. If we don't have an accurate processor + * speed, all of the peripherals that derive their clocks based on + * this advertised speed will introduce error and sometimes not work + * properly. This function is futher convoluted to still allow configurations + * to do that in case they have really, really old silicon with a + * write-only PLL register, that we need the 32KHz when power management + * "wait" is enabled, and we need to detect if the 32KHz isn't present + * but requested......got it? :-) -- Dan + */ +unsigned long cal_r4koff(void) +{ + unsigned long count; + unsigned long cpu_speed; + unsigned long flags; + unsigned long counter; - /* no RTC on the pb1000 */ - xtime.tv_sec = 0; - xtime.tv_usec = 0; + spin_lock_irqsave(&time_lock, flags); -#ifdef CONFIG_PM - /* - * setup counter 0, since it keeps ticking after a - * 'wait' instruction has been executed. The CP0 timer and - * counter 1 do NOT continue running after 'wait' - * - * It's too early to call request_irq() here, so we handle - * counter 0 interrupt as a special irq and it doesn't show - * up under /proc/interrupts. - */ - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); - au_writel(0, SYS_TOYWRITE); - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); + /* Power management cares if we don't have a 32KHz counter. + */ + no_au1xxx_32khz = 0; + counter = au_readl(SYS_COUNTER_CNTRL); + if (counter & SYS_CNTRL_E0) { + int trim_divide = 16; - au_writel(au_readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK); - au_writel(~0, SYS_WAKESRC); - au_sync(); - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); + au_writel(counter | SYS_CNTRL_EN1, SYS_COUNTER_CNTRL); - /* setup match20 to interrupt once every 10ms */ - last_pc0 = last_match20 = au_readl(SYS_TOYREAD); - au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); - au_sync(); - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); - startup_match20_interrupt(); -#endif + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S); + /* RTC now ticks at 32.768/16 kHz */ + au_writel(trim_divide-1, SYS_RTCTRIM); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S); + + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S); + au_writel (0, SYS_TOYWRITE); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S); + +#if defined(CONFIG_AU1000_USE32K) + { + unsigned long start, end; + + start = au_readl(SYS_RTCREAD); + start += 2; + /* wait for the beginning of a new tick + */ + while (au_readl(SYS_RTCREAD) < start); + + /* Start r4k counter. + */ + write_c0_count(0); + + /* Wait 0.5 seconds. + */ + end = start + (32768 / trim_divide)/2; - //set_cp0_status(ALLINTS); - au_sync(); + while (end > au_readl(SYS_RTCREAD)); + + count = read_c0_count(); + cpu_speed = count * 2; + } +#else + cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * + AU1000_SRC_CLK; + count = cpu_speed / 2; +#endif + } + else { + /* The 32KHz oscillator isn't running, so assume there + * isn't one and grab the processor speed from the PLL. + * NOTE: some old silicon doesn't allow reading the PLL. + */ + cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK; + count = cpu_speed / 2; + no_au1xxx_32khz = 1; + } + mips_hpt_frequency = count; + // Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) + set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16)); + spin_unlock_irqrestore(&time_lock, flags); + return (cpu_speed / HZ); } /* This is for machines which generate the exact clock. */ @@ -275,29 +314,8 @@ return r0; } - -static unsigned long do_fast_gettimeoffset(void) +static unsigned long do_fast_cp0_gettimeoffset(void) { -#ifdef CONFIG_PM - unsigned long pc0; - unsigned long offset; - - pc0 = au_readl(SYS_TOYREAD); - if (pc0 < last_pc0) { - offset = 0xffffffff - last_pc0 + pc0; - printk("offset over: %x\n", (unsigned)offset); - } - else { - offset = (unsigned long)(((pc0 - last_pc0) * 305) / 10); - } - if ((pc0-last_pc0) > 2*MATCH20_INC) { - printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n", - (unsigned)offset, (unsigned)last_pc0, - (unsigned)last_match20, (unsigned)pc0); - } - au_sync(); - return offset; -#else u32 count; unsigned long res, tmp; unsigned long r0; @@ -326,7 +344,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; @@ -338,60 +356,118 @@ "r" (quotient)); /* - * Due to possible jiffies inconsistencies, we need to check + * 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; -#endif } -void do_gettimeofday(struct timeval *tv) +#ifdef CONFIG_PM +static unsigned long do_fast_pm_gettimeoffset(void) { - unsigned int flags; - - read_lock_irqsave (&xtime_lock, flags); - *tv = xtime; - tv->tv_usec += do_fast_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); + unsigned long pc0; + unsigned long offset; - if (tv->tv_usec >= 1000000) { - tv->tv_usec -= 1000000; - tv->tv_sec++; + pc0 = au_readl(SYS_TOYREAD); + au_sync(); + offset = pc0 - last_pc0; + if (offset > 2*MATCH20_INC) { + printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n", + (unsigned)offset, (unsigned)last_pc0, + (unsigned)last_match20, (unsigned)pc0); } + offset = (unsigned long)((offset * 305) / 10); + return offset; } +#endif -void do_settimeofday(struct timeval *tv) +void __init au1xxx_timer_setup(void) { - write_lock_irq (&xtime_lock); + unsigned int est_freq; + extern unsigned long (*do_gettimeoffset)(void); + extern void au1k_wait(void); + + printk("calculating r4koff... "); + r4k_offset = cal_r4koff(); + printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset); + + //est_freq = 2*r4k_offset*HZ; + est_freq = r4k_offset*HZ; + est_freq += 5000; /* round */ + est_freq -= est_freq%10000; + printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, + (est_freq%1000000)*100/1000000); + set_au1x00_speed(est_freq); + set_au1x00_lcd_clock(); // program the LCD clock + + r4k_cur = (read_c0_count() + r4k_offset); + write_c0_compare(r4k_cur); + + /* no RTC on the pb1000 */ + xtime.tv_sec = 0; + xtime.tv_usec = 0; - /* 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! +#ifdef CONFIG_PM + /* + * setup counter 0, since it keeps ticking after a + * 'wait' instruction has been executed. The CP0 timer and + * counter 1 do NOT continue running after 'wait' + * + * It's too early to call request_irq() here, so we handle + * counter 0 interrupt as a special irq and it doesn't show + * up under /proc/interrupts. + * + * Check to ensure we really have a 32KHz oscillator before + * we do this. */ - tv->tv_usec -= do_fast_gettimeoffset(); + if (no_au1xxx_32khz) { + unsigned int c0_status; + + printk("WARNING: no 32KHz clock found.\n"); + do_gettimeoffset = do_fast_cp0_gettimeoffset; - if (tv->tv_usec < 0) { - tv->tv_usec += 1000000; - tv->tv_sec--; + /* Ensure we get CPO_COUNTER interrupts. + */ + c0_status = read_c0_status(); + c0_status |= IE_IRQ5; + write_c0_status(c0_status); + } + else { + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); + au_writel(0, SYS_TOYWRITE); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); + + au_writel(au_readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK); + au_writel(~0, SYS_WAKESRC); + au_sync(); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); + + /* setup match20 to interrupt once every 10ms */ + last_pc0 = last_match20 = au_readl(SYS_TOYREAD); + au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); + au_sync(); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); + startup_match20_interrupt(); + + do_gettimeoffset = do_fast_pm_gettimeoffset; + + /* We can use the real 'wait' instruction. + */ + au1k_wait_ptr = au1k_wait; } - xtime = *tv; - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; +#else + /* We have to do this here instead of in timer_init because + * the generic code in arch/mips/kernel/time.c will write + * over our function pointer. + */ + do_gettimeoffset = do_fast_cp0_gettimeoffset; +#endif +} - write_unlock_irq (&xtime_lock); +void __init au1xxx_time_init(void) +{ } Index: arch/mips/au1000/common/usbdev.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/au1000/common/usbdev.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/au1000/common/usbdev.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/au1000/common/usbdev.c 4 Aug 2004 01:25:48 -0000 1.2 @@ -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; Index: arch/mips/au1000/pb1000/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/au1000/pb1000/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/au1000/pb1000/Makefile 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/au1000/pb1000/Makefile 4 Aug 2004 01:25:48 -0000 1.2 @@ -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 Index: arch/mips/au1000/pb1000/pci_fixup.c =================================================================== RCS file: arch/mips/au1000/pb1000/pci_fixup.c diff -N arch/mips/au1000/pb1000/pci_fixup.c --- arch/mips/au1000/pb1000/pci_fixup.c 22 Jul 2004 19:49:16 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: arch/mips/au1000/pb1000/pci_ops.c =================================================================== RCS file: arch/mips/au1000/pb1000/pci_ops.c diff -N arch/mips/au1000/pb1000/pci_ops.c --- arch/mips/au1000/pb1000/pci_ops.c 22 Jul 2004 19:49:16 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 */ Index: arch/mips/au1000/pb1000/setup.c =================================================================== RCS file: arch/mips/au1000/pb1000/setup.c diff -N arch/mips/au1000/pb1000/setup.c --- arch/mips/au1000/pb1000/setup.c 22 Jul 2004 19:49:16 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; - } -} Index: arch/mips/au1000/pb1100/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/au1000/pb1100/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/au1000/pb1100/Makefile 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/au1000/pb1100/Makefile 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 Index: arch/mips/au1000/pb1100/pci_fixup.c =================================================================== RCS file: arch/mips/au1000/pb1100/pci_fixup.c diff -N arch/mips/au1000/pb1100/pci_fixup.c --- arch/mips/au1000/pb1100/pci_fixup.c 22 Jul 2004 19:49:16 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: arch/mips/au1000/pb1100/pci_ops.c =================================================================== RCS file: arch/mips/au1000/pb1100/pci_ops.c diff -N arch/mips/au1000/pb1100/pci_ops.c --- arch/mips/au1000/pb1100/pci_ops.c 22 Jul 2004 19:49:16 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 */ Index: arch/mips/au1000/pb1100/setup.c =================================================================== RCS file: arch/mips/au1000/pb1100/setup.c diff -N arch/mips/au1000/pb1100/setup.c --- arch/mips/au1000/pb1100/setup.c 22 Jul 2004 19:49:16 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 -} Index: arch/mips/au1000/pb1500/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/au1000/pb1500/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/au1000/pb1500/Makefile 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/au1000/pb1500/Makefile 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 Index: arch/mips/au1000/pb1500/pci_fixup.c =================================================================== RCS file: arch/mips/au1000/pb1500/pci_fixup.c diff -N arch/mips/au1000/pb1500/pci_fixup.c --- arch/mips/au1000/pb1500/pci_fixup.c 22 Jul 2004 19:49:16 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: arch/mips/au1000/pb1500/pci_ops.c =================================================================== RCS file: arch/mips/au1000/pb1500/pci_ops.c diff -N arch/mips/au1000/pb1500/pci_ops.c --- arch/mips/au1000/pb1500/pci_ops.c 22 Jul 2004 19:49:16 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 */ Index: arch/mips/au1000/pb1500/setup.c =================================================================== RCS file: arch/mips/au1000/pb1500/setup.c diff -N arch/mips/au1000/pb1500/setup.c --- arch/mips/au1000/pb1500/setup.c 22 Jul 2004 19:49:16 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 -} Index: arch/mips/baget/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/baget/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/baget/Makefile 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/baget/Makefile 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 Index: arch/mips/baget/baget.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/baget/baget.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/baget/baget.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/baget/baget.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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; Index: arch/mips/baget/bagetIRQ.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/baget/bagetIRQ.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/baget/bagetIRQ.S 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/baget/bagetIRQ.S 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 Index: arch/mips/baget/balo.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/baget/balo.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/baget/balo.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/baget/balo.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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(); Index: arch/mips/baget/balo_supp.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/baget/balo_supp.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/baget/balo_supp.S 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/baget/balo_supp.S 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 Index: arch/mips/baget/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/baget/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/baget/irq.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/baget/irq.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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"); } Index: arch/mips/baget/ld.script.balo =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/baget/ld.script.balo,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/baget/ld.script.balo 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/baget/ld.script.balo 4 Aug 2004 01:25:49 -0000 1.2 @@ -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) Index: arch/mips/baget/print.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/baget/print.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/baget/print.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/baget/print.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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); } Index: arch/mips/baget/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/baget/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/baget/setup.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/baget/setup.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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"); Index: arch/mips/baget/time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/baget/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/baget/time.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/baget/time.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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) Index: arch/mips/baget/vacserial.c =================================================================== RCS file: arch/mips/baget/vacserial.c diff -N arch/mips/baget/vacserial.c --- arch/mips/baget/vacserial.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 */ Index: arch/mips/baget/wbflush.c =================================================================== RCS file: arch/mips/baget/wbflush.c diff -N arch/mips/baget/wbflush.c --- arch/mips/baget/wbflush.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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) -{ -} Index: arch/mips/baget/prom/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/baget/prom/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/baget/prom/init.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/baget/prom/init.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 Index: arch/mips/boot/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/boot/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/boot/Makefile 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/boot/Makefile 4 Aug 2004 01:25:49 -0000 1.2 @@ -24,7 +24,7 @@ drop-sections = .reginfo .mdebug strip-flags = $(addprefix --remove-section=,$(drop-sections)) -all: vmlinux.ecoff addinitrd +all: vmlinux.ecoff vmlinux.srec addinitrd vmlinux.ecoff: $(CONFIGURE) elf2ecoff $(TOPDIR)/vmlinux ./elf2ecoff $(TOPDIR)/vmlinux vmlinux.ecoff $(E2EFLAGS) @@ -32,6 +32,9 @@ elf2ecoff: elf2ecoff.c $(HOSTCC) -o $@ $^ +vmlinux.srec: $(CONFIGURE) $(TOPDIR)/vmlinux + $(OBJCOPY) -S -O srec $(strip-flags) $(TOPDIR)/vmlinux vmlinux.srec + addinitrd: addinitrd.c $(HOSTCC) -o $@ $^ @@ -40,10 +43,12 @@ clean: rm -f vmlinux.ecoff + rm -f vmlinux.srec rm -f zImage zImage.tmp mrproper: rm -f vmlinux.ecoff + rm -f vmlinux.srec rm -f addinitrd rm -f elf2ecoff Index: arch/mips/boot/elf2ecoff.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/boot/elf2ecoff.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/boot/elf2ecoff.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/boot/elf2ecoff.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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) { Index: arch/mips/cobalt/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/cobalt/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/cobalt/Makefile 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/cobalt/Makefile 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 Index: arch/mips/cobalt/int-handler.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/cobalt/int-handler.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/cobalt/int-handler.S 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/cobalt/int-handler.S 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 Index: arch/mips/cobalt/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/cobalt/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/cobalt/irq.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/cobalt/irq.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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(); Index: arch/mips/cobalt/pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/cobalt/pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/cobalt/pci.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/cobalt/pci.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 */ Index: arch/mips/cobalt/promcon.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/cobalt/promcon.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/cobalt/promcon.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/cobalt/promcon.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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) Index: arch/mips/cobalt/reset.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/cobalt/reset.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/cobalt/reset.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/cobalt/reset.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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" : Index: arch/mips/cobalt/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/cobalt/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/cobalt/setup.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/cobalt/setup.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 Index: arch/mips/cobalt/via.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/cobalt/via.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/cobalt/via.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/cobalt/via.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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"); Index: arch/mips/ddb5074/Makefile =================================================================== RCS file: arch/mips/ddb5074/Makefile diff -N arch/mips/ddb5074/Makefile --- arch/mips/ddb5074/Makefile 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: arch/mips/ddb5074/int-handler.S =================================================================== RCS file: arch/mips/ddb5074/int-handler.S diff -N arch/mips/ddb5074/int-handler.S --- arch/mips/ddb5074/int-handler.S 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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) Index: arch/mips/ddb5074/irq.c =================================================================== RCS file: arch/mips/ddb5074/irq.c diff -N arch/mips/ddb5074/irq.c --- arch/mips/ddb5074/irq.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); -} Index: arch/mips/ddb5074/nile4.c =================================================================== RCS file: arch/mips/ddb5074/nile4.c diff -N arch/mips/ddb5074/nile4.c --- arch/mips/ddb5074/nile4.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: arch/mips/ddb5074/pci.c =================================================================== RCS file: arch/mips/ddb5074/pci.c diff -N arch/mips/ddb5074/pci.c --- arch/mips/ddb5074/pci.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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[] = { }; Index: arch/mips/ddb5074/prom.c =================================================================== RCS file: arch/mips/ddb5074/prom.c diff -N arch/mips/ddb5074/prom.c --- arch/mips/ddb5074/prom.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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) -{ -} Index: arch/mips/ddb5074/setup.c =================================================================== RCS file: arch/mips/ddb5074/setup.c diff -N arch/mips/ddb5074/setup.c --- arch/mips/ddb5074/setup.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); - } -} Index: arch/mips/ddb5074/time.c =================================================================== RCS file: arch/mips/ddb5074/time.c diff -N arch/mips/ddb5074/time.c --- arch/mips/ddb5074/time.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 -}; Index: arch/mips/ddb5xxx/common/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/common/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/common/irq.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/common/irq.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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); Index: arch/mips/ddb5xxx/ddb5074/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/ddb5074/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/ddb5074/irq.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/ddb5074/irq.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 :-) */ Index: arch/mips/ddb5xxx/ddb5074/nile4_pic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/ddb5074/nile4_pic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/ddb5074/nile4_pic.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/ddb5074/nile4_pic.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -260,7 +260,7 @@ } -#if defined(CONFIG_LL_DEBUG) +#if defined(CONFIG_RUNTIME_DEBUG) void nile4_dump_irq_status(void) { printk(KERN_DEBUG " Index: arch/mips/ddb5xxx/ddb5074/pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/ddb5074/pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/ddb5074/pci.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/ddb5074/pci.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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); } } } - Index: arch/mips/ddb5xxx/ddb5074/pci_ops.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/ddb5074/pci_ops.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/ddb5074/pci_ops.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/ddb5074/pci_ops.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 Index: arch/mips/ddb5xxx/ddb5074/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/ddb5074/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/ddb5074/setup.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/ddb5074/setup.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -31,15 +31,11 @@ #include -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB 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 kbd_ops std_kbd_ops; extern struct rtc_ops ddb_rtc_ops; @@ -81,10 +77,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 +88,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); } Index: arch/mips/ddb5xxx/ddb5476/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/ddb5476/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/ddb5476/Makefile 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/ddb5476/Makefile 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 Index: arch/mips/ddb5xxx/ddb5476/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/ddb5476/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/ddb5476/irq.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/ddb5476/irq.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -14,6 +14,7 @@ #include #include +#include #include #include Index: arch/mips/ddb5xxx/ddb5476/nile4_pic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/ddb5476/nile4_pic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/ddb5476/nile4_pic.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/ddb5476/nile4_pic.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 " Index: arch/mips/ddb5xxx/ddb5476/pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/ddb5476/pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/ddb5476/pci.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/ddb5476/pci.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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; Index: arch/mips/ddb5xxx/ddb5476/pci_ops.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/ddb5476/pci_ops.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/ddb5476/pci_ops.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/ddb5476/pci_ops.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 Index: arch/mips/ddb5xxx/ddb5476/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/ddb5476/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/ddb5476/setup.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/ddb5476/setup.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 @@ -84,7 +84,7 @@ static void __init ddb_time_init(void) { #if defined(USE_CPU_COUNTER_TIMER) - mips_counter_frequency = CPU_COUNTER_FREQUENCY; + mips_hpt_frequency = CPU_COUNTER_FREQUENCY; #endif /* we have ds1396 RTC chip */ @@ -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); Index: arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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; Index: arch/mips/ddb5xxx/ddb5477/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/ddb5477/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/ddb5477/Makefile 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/ddb5477/Makefile 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 Index: arch/mips/ddb5xxx/ddb5477/debug.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/ddb5477/debug.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/ddb5477/debug.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/ddb5477/debug.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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}, Index: arch/mips/ddb5xxx/ddb5477/int-handler.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/ddb5477/int-handler.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/ddb5477/int-handler.S 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/ddb5477/int-handler.S 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 Index: arch/mips/ddb5xxx/ddb5477/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/ddb5477/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/ddb5477/irq.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/ddb5477/irq.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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."); Index: arch/mips/ddb5xxx/ddb5477/pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/ddb5477/pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/ddb5477/pci.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/ddb5477/pci.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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); } } Index: arch/mips/ddb5xxx/ddb5477/pci_ops.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/ddb5477/pci_ops.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/ddb5477/pci_ops.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/ddb5477/pci_ops.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -299,4 +299,3 @@ iopci_write_config_word, iopci_write_config_dword }; - Index: arch/mips/ddb5xxx/ddb5477/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ddb5xxx/ddb5477/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ddb5xxx/ddb5477/setup.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ddb5xxx/ddb5477/setup.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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); @@ -142,11 +138,11 @@ bus_frequency = detect_bus_frequency(rtc_base); } - /* 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)) + /* mips_hpt_frequency is 1/2 of the cpu core freq */ + 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; + mips_hpt_frequency = bus_frequency*(i+4)/4; } extern int setup_irq(unsigned int irq, struct irqaction *irqaction); @@ -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); Index: arch/mips/dec/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/dec/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/dec/Makefile 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/dec/Makefile 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 Index: arch/mips/dec/int-handler.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/dec/int-handler.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/dec/int-handler.S 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/dec/int-handler.S 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 Index: arch/mips/dec/ioasic-irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/dec/ioasic-irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/dec/ioasic-irq.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/dec/ioasic-irq.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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++) { Index: arch/mips/dec/kn02-irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/dec/kn02-irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/dec/kn02-irq.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/dec/kn02-irq.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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; Index: arch/mips/dec/promcon.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/dec/promcon.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/dec/promcon.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/dec/promcon.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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, }; /* Index: arch/mips/dec/reset.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/dec/reset.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/dec/reset.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/dec/reset.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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) { Index: arch/mips/dec/rtc-dec.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/dec/rtc-dec.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/dec/rtc-dec.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/dec/rtc-dec.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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); Index: arch/mips/dec/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/dec/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/dec/setup.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/dec/setup.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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,13 @@ extern asmlinkage void decstation_handle_int(void); +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +spinlock_t ioasic_ssr_lock; + volatile u32 *ioasic_base; unsigned long dec_kn_slot_size; @@ -75,53 +84,66 @@ [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) { +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + board_be_init = dec_be_init; board_time_init = dec_time_init; + board_timer_setup = dec_timer_setup; wbflush_setup(); @@ -152,7 +174,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 +197,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 +208,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 +251,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 +274,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 +285,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 +326,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 +349,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 +360,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 +423,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 +446,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 +457,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 +524,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 +547,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 +558,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 +608,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 +621,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 +644,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 +655,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 +722,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 +741,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 +752,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); Index: arch/mips/dec/time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/dec/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/dec/time.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/dec/time.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -2,278 +2,93 @@ * 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 - -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 +122,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 +133,54 @@ 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 int dec_timer_state(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); + return (CMOS_READ(RTC_REG_C) & RTC_PF) != 0; } -static void r4k_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static void dec_timer_ack(void) { - unsigned int count; + CMOS_READ(RTC_REG_C); /* Ack the RTC interrupt. */ +} +static unsigned int dec_ioasic_hpt_read(void) +{ /* - * 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; - } + return ioasic_read(IO_REG_FCTR); +} - timer_interrupt(irq, dev_id, regs); +static void dec_ioasic_hpt_init(unsigned int count) +{ + ioasic_write(IO_REG_FCTR, ioasic_read(IO_REG_FCTR) - count); } -static void ioasic_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) + +void __init dec_time_init(void) { - unsigned int count; + rtc_get_time = dec_rtc_get_time; + rtc_set_mmss = dec_rtc_set_mmss; - /* - * 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; + mips_timer_state = dec_timer_state; + 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; } - timer_interrupt(irq, dev_id, regs); + /* Set up the rate of periodic DS1287 interrupts. */ + CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - LOG_2_HZ), RTC_REG_A); } -struct irqaction irq0 = {timer_interrupt, SA_INTERRUPT, 0, - "timer", NULL, NULL}; - -void __init time_init(void) +void __init dec_timer_setup(struct irqaction *irq) { - unsigned int year, mon, day, hour, min, sec, real_year; - 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); - } - /* - * 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; + setup_irq(dec_interrupt[DEC_IRQ_RTC], irq); - 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); + /* Enable periodic DS1287 interrupts. */ + CMOS_WRITE(CMOS_READ(RTC_REG_B) | RTC_PIE, RTC_REG_B); } Index: arch/mips/dec/wbflush.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/dec/wbflush.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/dec/wbflush.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/dec/wbflush.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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; Index: arch/mips/dec/prom/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/dec/prom/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/dec/prom/Makefile 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/dec/prom/Makefile 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 Index: arch/mips/dec/prom/cmdline.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/dec/prom/cmdline.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/dec/prom/cmdline.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/dec/prom/cmdline.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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 - } - Index: arch/mips/dec/prom/identify.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/dec/prom/identify.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/dec/prom/identify.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/dec/prom/identify.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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]); +} Index: arch/mips/dec/prom/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/dec/prom/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/dec/prom/init.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/dec/prom/init.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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; } - Index: arch/mips/dec/prom/locore.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/dec/prom/locore.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/dec/prom/locore.S 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/dec/prom/locore.S 4 Aug 2004 01:25:49 -0000 1.2 @@ -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) Index: arch/mips/dec/prom/memory.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/dec/prom/memory.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/dec/prom/memory.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/dec/prom/memory.c 4 Aug 2004 01:25:49 -0000 1.2 @@ -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(); Index: arch/mips/dec/prom/prom.h =================================================================== RCS file: arch/mips/dec/prom/prom.h diff -N arch/mips/dec/prom/prom.h --- arch/mips/dec/prom/prom.h 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 */ - Index: arch/mips/galileo-boards/ev64120/Makefile =================================================================== RCS file: arch/mips/galileo-boards/ev64120/Makefile diff -N arch/mips/galileo-boards/ev64120/Makefile --- arch/mips/galileo-boards/ev64120/Makefile 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: arch/mips/galileo-boards/ev64120/cntmr.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/cntmr.c diff -N arch/mips/galileo-boards/ev64120/cntmr.c --- arch/mips/galileo-boards/ev64120/cntmr.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; - } - } -} Index: arch/mips/galileo-boards/ev64120/dma.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/dma.c diff -N arch/mips/galileo-boards/ev64120/dma.c --- arch/mips/galileo-boards/ev64120/dma.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; -} Index: arch/mips/galileo-boards/ev64120/i2o.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/i2o.c diff -N arch/mips/galileo-boards/ev64120/i2o.c --- arch/mips/galileo-boards/ev64120/i2o.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); Index: arch/mips/galileo-boards/ev64120/int-handler.S =================================================================== RCS file: arch/mips/galileo-boards/ev64120/int-handler.S diff -N arch/mips/galileo-boards/ev64120/int-handler.S --- arch/mips/galileo-boards/ev64120/int-handler.S 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: arch/mips/galileo-boards/ev64120/irq-handler.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/irq-handler.c diff -N arch/mips/galileo-boards/ev64120/irq-handler.c --- arch/mips/galileo-boards/ev64120/irq-handler.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 -} Index: arch/mips/galileo-boards/ev64120/irq.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/irq.c diff -N arch/mips/galileo-boards/ev64120/irq.c --- arch/mips/galileo-boards/ev64120/irq.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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(); -} Index: arch/mips/galileo-boards/ev64120/pci_bios.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/pci_bios.c diff -N arch/mips/galileo-boards/ev64120/pci_bios.c --- arch/mips/galileo-boards/ev64120/pci_bios.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 */ Index: arch/mips/galileo-boards/ev64120/promcon.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/promcon.c diff -N arch/mips/galileo-boards/ev64120/promcon.c --- arch/mips/galileo-boards/ev64120/promcon.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); -} Index: arch/mips/galileo-boards/ev64120/reset.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/reset.c diff -N arch/mips/galileo-boards/ev64120/reset.c --- arch/mips/galileo-boards/ev64120/reset.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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(); -} Index: arch/mips/galileo-boards/ev64120/serialGT.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/serialGT.c diff -N arch/mips/galileo-boards/ev64120/serialGT.c --- arch/mips/galileo-boards/ev64120/serialGT.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); -} Index: arch/mips/galileo-boards/ev64120/setup.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/setup.c diff -N arch/mips/galileo-boards/ev64120/setup.c --- arch/mips/galileo-boards/ev64120/setup.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); -} Index: arch/mips/galileo-boards/ev64120/compressed/Makefile =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/Makefile diff -N arch/mips/galileo-boards/ev64120/compressed/Makefile --- arch/mips/galileo-boards/ev64120/compressed/Makefile 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,177 +0,0 @@ -# ============================================================= -# -# linux/arch/mips/galileo/compressed/Makefile -# -# By RidgeRun Inc. -# -# Description: -# Create a system containing a copy of the compressed vmlinux kernel. -# The system knows how to decompress the contained kernel and then -# jump to it resulting in a linux kernel boot. -# -# The system comes in three forms: -# -# 1. - ramsys - -# to be loaded into ram then run. When run -# it decompresses the kernel housed in its internal -# data structures and then jumps to the image which -# results in a linux kernel boot. -# -# 2. - flashsys - -# to be loaded into ram so that it can be -# burned into the onboard flash. Then the board jumpers -# can be switched so that the next power cycle caused -# the system in flash to run which then proceeds as -# described by #1 above. -# Note: burner.srec is the utility that will allow -# the user to get this image into flash. -# -# 3. - flashsys2 - -# to be loaded into ram so that it can be -# burned into the onboard flash. Then on each power -# cycle when the standard PMON prompt is presented -# the user can type `call 0xbf000000` to invoke -# the system in flash which then proceeds as -# described by #1 above. -# Note: burner.srec is the utility that will allow -# the user to get this image into flash. -# -# 4. - burner.srec - -# related to #2 and #3 above. -# -# ============================================================= - -USE_STANDARD_AS_RULE := true - -all: ramsys.srec \ - flashsys.srec \ - flashsys2.srec \ - burner.srec - -SYSTEM = $(TOPDIR)/vmlinux - -CFLAGS_2 = -DCONSOLE_SERIAL -DDELIMITERLINES -DGALILEO_PORT \ - -DANSIESC -DELF_IMAGE -DELF_IMAGE -DDOWNLOAD_PROTO_TFTP \ - -DEVB64120A -D__MIPSEB__ -DINCLUDE_EEPRO100 \ - -DINCLUDE_GETH0 -DNOPRINTK -DPROM -DCOMPRESSEDVMLINUX - -sbdreset_evb64120A.o: - $(CC) $(CFLAGS) $(CFLAGS_2) -c sbdreset_evb64120A.S -o $*.o -memory.o: - $(CC) $(CFLAGS) $(CFLAGS_2) -c memory.c -o $*.o -pci.o: - $(CC) $(CFLAGS) $(CFLAGS_2) -c pci.c -o $*.o -pci_etherboot.o: - $(CC) $(CFLAGS) $(CFLAGS_2) -c pci_etherboot.c -o $*.o -load.o: - $(CC) $(CFLAGS) $(CFLAGS_2) -c load.c -o $*.o -flashdrv.o: - $(CC) $(CFLAGS) $(CFLAGS_2) -c flashdrv.c -o $*.o - -gz2asm: gz2asm.c - g++ -o gz2asm gz2asm.c - -doit: doit.c - gcc -o doit doit.c - -piggy.gz: $(SYSTEM) - rm -f piggy piggy.gz - $(OBJCOPY) -S -O binary $(SYSTEM) piggy - gzip -f -9 < piggy > piggy.gz - -piggy.S: doit fixit piggy.gz - ./doit < piggy.gz > piggy.S; . ./fixit piggy.S - -OBJECTS_ramsys = head.o misc.o piggy.o ../serialGT.o -OBJECTS_flashsys = sbdreset_evb64120A.o evb64120A_Setup.o pci_etherboot.o memory.o pci.o head.o misc.o piggy.o ../serialGT.o -OBJECTS_flashsys2 = xfer.o head.o misc.o piggy.o ../serialGT.o -OBJECTS_burner = burner.o load.o flashdrv.o - -ramsys.srec : $(OBJECTS_ramsys) ld.script.gal - @# Note: this image is intended to run out of ram. No flash involved. - $(LD) -T ld.script.gal -o ramsys $(OBJECTS_ramsys) - $(NM) ramsys | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System_ramsys.map - $(OBJCOPY) -O srec ramsys ramsys.srec - cp ramsys.srec $(TOPDIR)/. - -flashsys.srec : $(OBJECTS_flashsys) ld.sys.big.Flash - @# Note1: Use the burn utility to get this image into flash. - @# Note2: This image is intended to run out of flash as invoked - @# directly at powerup when EVB64120A jumpers are configured to - @# bypass the onboard eprom. - @# Assumes that 0xBFC00000 is the bootup run address (normal MIPS). - @# And assumes that EVB64120A jumber J11 is added to the board and jumber - @# J20 is moved from the 2&3 position to the 1&2 position instead. Without - @# the jumper settings the system will execute at address 0xBFC00000, - @# as normal, yet that address will map to the onboard eeprom instead - @# of the onboard flash. - @# - $(LD) -T ld.sys.big.Flash -o flashsys $(OBJECTS_flashsys) - $(NM) flashsys | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | sort > System_flashsys.map - @# - @# Next, Create the image that we want to place in the flash part. - $(OBJCOPY) -S -g --strip-unneeded \ - --adjust-section-vma=.text+0x3f820000 \ - --adjust-section-vma=.rodata+0x3f820000 \ - --adjust-section-vma=.reginfo+0x3f820000 \ - --adjust-section-vma=.data+0x3f820000 \ - --remove-section=.bss \ - --remove-section=.scommon \ - --remove-section=.note \ - --remove-section=.comment \ - flashsys flashsys.temp - @# - @# Next, change the addresses so that when we download to - @# to the board's ram it will land starting at address 0xA0300000 - @# because this is where we have choosen to have the image temporarily sit - @# while we subsequently burn it (using some method not revealed here) into - @# the board's flash. After the burn the system can be setup (via jumpers) - @# to boot this image directory from the flash part. - $(OBJCOPY) -O srec --adjust-vma=0xe0700000 flashsys.temp flashsys.srec - cp flashsys.srec $(TOPDIR)/. - -flashsys2.srec : $(OBJECTS_flashsys2) ld.sys.big.Flash2 - @# Note1: Use the burn utility to get this image into flash. - @# Note2: This image is intended to be run out of flash as invoked - @# manually from the standard PMON running in eprom. This means that - @# the image will be set to run from location 0xBF000000 which is the - @# location the flash is mapped to when the board jumpers are set to - @# the standard location such that the board boots out of onboard - @# eprom. From the PMON prompt the user can type `call 0xbf000000` - @# to transfer control to the image we are constructing here. - @# - $(LD) -T ld.sys.big.Flash2 -o flashsys2 $(OBJECTS_flashsys2) - $(NM) flashsys2 | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | sort > System_flashsys2.map - @# - @# Next, Create the image that we want to place in the flash part. - $(OBJCOPY) -S -g --strip-unneeded \ - --adjust-section-vma=.text+0x3ec20000 \ - --adjust-section-vma=.rodata+0x3ec20000 \ - --adjust-section-vma=.reginfo+0x3ec20000 \ - --adjust-section-vma=.data+0x3ec20000 \ - --remove-section=.bss \ - --remove-section=.scommon \ - --remove-section=.note \ - --remove-section=.comment \ - flashsys2 flashsys2.temp - @# - @# Next, change the addresses so that when we download to - @# to the board's ram it will land starting at address 0xA0300000 - @# because this is where we have choosen to have the image temporarily sit - @# while we subsequently burn it (using some method not revealed here) into - @# the board's flash. After the burn a user will then be able to type - @# `call 0xbf000000` at the PMON prompt (following a power cycle) to invoke - @# the linux kernel. - $(OBJCOPY) -O srec --adjust-vma=0xe1300000 flashsys2.temp flashsys2.srec - cp flashsys2.srec $(TOPDIR)/. - -burner.srec : $(OBJECTS_burner) ld.sys.big.burner - @# This utility can be used to burn the flashsys.srec or flashsys2.srec - @# into the EVB64120A's on board flash part (1Meg minimum). - $(LD) -T ld.sys.big.burner -o burner $(OBJECTS_burner) - $(NM) burner | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System_burner.map - $(OBJCOPY) -O srec burner burner.srec - cp burner.srec $(TOPDIR)/. - -clean: - rm -f doit piggy.S piggy.gz piggy burner *.o ramsys* flashsys* System*.map *.srec Index: arch/mips/galileo-boards/ev64120/compressed/README =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/README diff -N arch/mips/galileo-boards/ev64120/compressed/README --- arch/mips/galileo-boards/ev64120/compressed/README 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,131 +0,0 @@ -+------------------------------------------------+ -| $TOPDIR/arch/mips/galileo/compressed/README | -| | -| By RidgeRun Inc, | -| Aug, 2000 | -+------------------------------------------------+ - -Description: -============ - It is intended that this makefile be wired in to run as - part of a top level linux build. For example, at the - time of this writing, if the user types "make gboot" at - the top level then in addition to building vmlinux the - build system's makefiles will descend into this - directory and build the "all:" target of this - Makefile. This will have the result of compressing the - vmlinux system and producing four separate systems. The - following snippet is pulled from this directory's - Makefile and describes each system. - - Four systems are availalbe for download to the EVB64120A - board. - - 1. - ramsys - - To be loaded into ram then run. When run - it decompresses the "vmlinux" kernel housed in its internal - data structures and then jumps to the image which - results in a linux kernel boot. - - 2. - flashsys - - To be loaded into ram so that it can be - burned into the onboard flash. Then the board jumpers - can be switched so that the next power cycle caused - the system in flash to run which then proceeds as - described by #1 above. - Note: burner.srec is the utility that will allow - the user to get this image into flash. - - 3. - flashsys2 - - To be loaded into ram so that it can be - burned into the onboard flash. Then on each power - cycle when the standard PMON prompt is presented - the user can type `call 0xbf000000` to invoke - the system in flash which then proceeds as - described by #1 above. - Note: burner.srec is the utility that will allow - the user to get this image into flash. - - 4. - burner.srec - - Related to #2 and #3 above. - -Example: Running from Ram -========================== - - In this scenario the compressed system is downloaded - into ram and run directly from there. No flash is involved - in this scenario. Naturally, the download must be repeated - on every power cycle. - - 1. At the PMON prompt type `load` - 2. Assuming you have your host connected to /dev/ttyS0 - type the following command in a host shell window. - `cat ramsys.srec > /dev/ttyS0` - 3. When the download completes type the following - at the PMON prompt: `g` - - -Example: Running from flash: Scenario #1 -======================================== - - In this scenario vmlinux runs out of flash code - automatically on every power up. This means that - standard PMON code (of eprom) never runs. - - 1. Place the boot jumpers in the Boot-from-eprom - state. This is the normal state and how the jumpers - are found when booting PMON. - - Jumper settings. J11 - Removed - J20 - Moved from the 1&2 position to - the 2&3 position instead - - 2. Use PMON to "load" the burner.srec image and then - run it. This utility will prompt you to download - the image that you want burned into the flash - part. - - 3. Send the flashsys.srec image to the running burner - utility. The utililty will indicate when the burn - process has completed. - - 4. Now switch off power and change the jumpers to - the boot-from-flash position. The next power cycle - will run the flash based system automatically. - - Jumper settings. J11 - Added. - J20 - Moved from the 2&3 position to - the 1&2 position instead - -Example: Running from flash: Scenario #2 -======================================== - - In this scenario vmlinux runs out of flash only if the - PMON user decides to jump there by issuing a command to - PMON. Every power cycle would continue to bring up PMON - and a user will have to reissue the jump command to - force control transfer to the flash system. - - 1. Insure that the boot jumpers are in the Boot-from-eprom - state. This is the normal state and how the jumpers - are found when booting PMON. - - Jumper settings. J11 - Removed - J20 - Moved from the 1&2 position to - the 2&3 position instead - - 2. Use PMON to "load" the burner.srec image and then - run it. This utility will prompt you to download - the image that you want burned into the flash - part. - - 3. Send the flashsys2.srec image to the running burner - utility. The utililty will indicate when the burn - process has completed. - - 4. Now that the image is in flash the user can invoke - the following PMON command whenever a vmlinux - boot is desired: - - call 0xbf000000 - Index: arch/mips/galileo-boards/ev64120/compressed/burner.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/burner.c diff -N arch/mips/galileo-boards/ev64120/compressed/burner.c --- arch/mips/galileo-boards/ev64120/compressed/burner.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,230 +0,0 @@ -/* - * arch/mips/galileo/compressed/burner.c - * - * By RidgeRun Inc (Leveraged from Galileo's main.c, misc.c, etc). - * - * Burn image from ram to flash - * For use with Galileo EVB64120A MIPS eval board. - */ -#include -#include -#include -#include - -#define IMAGEOFFSET 0x00300000 - -static void burn_image_from_memory(void); -static char *sprintf(char *buf, const char *fmt, ...); -static void printf(const char *fmt, ...); - -unsigned int FlashSize; - -/****************************** - Routine: - Description: - ******************************/ -int main(void) -{ - printf("\n"); - printf("\n"); - printf("\n"); - printf("\n"); - printf(" +--------------------+\n"); - printf(" | |\n"); - printf(" | Flash Burn Utility |\n"); - printf(" | |\n"); - printf(" +--------------------+\n"); - printf("\n"); - printf("Please send your *.srec image to the parallel port\n"); - printf("\n"); - printf("Note: The *.srec image should be setup to\n"); - printf(" load into address 0xa0300000 where\n"); - printf(" it will then be transferred to flash\n"); - printf("\n"); - - SET_REG_BITS(0x468, BIT20); // Set Flash to be 16 bit wide - FlashSize = flashInit(0xbf000000, 2, X16); - - galileo_dl(); // read in the users *.srec image. - burn_image_from_memory(); // put it in flash. - - printf("\n"); - printf("\n"); - printf("+---------------+\n"); - printf("| Done |\n"); - printf("|(please reboot)|\n"); - printf("+---------------+\n"); - printf("\n"); - - while (1) { - } - return 0; -} - -/****************************** - Routine: - Description: - ******************************/ -static void burn_image_from_memory(void) -{ - unsigned int count, delta, temp, temp1; - unsigned int to_sector, last_sector; - - /* Find how many sectors needed to be erased */ - to_sector = flashInWhichSector(FlashSize - 4); // skranz, modified. - if (to_sector == 0xffffffff) { - printf - ("Flash Burning Error - Flash too small - Cannot burn image\n"); // skranz, modified. - return; - } - - /* Which is the last sector */ - last_sector = flashInWhichSector(FlashSize - 4); - delta = 0; - printf("\nErasing first %d sectors\n", to_sector); - for (count = 0; count < to_sector + 1; count++) { - printf("Erasing sector %d\n", count); - flashEraseSector(count); - } - printf("flash region size = %d\n", FlashSize); // skranz, added - printf("Sdram IMAGEOFFSET = %d\n", IMAGEOFFSET); // skranz, added - - printf("Burning from Sdram to %d mark; full burn.\n", FlashSize); - for (count = 0; count < (FlashSize - delta); count = count + 4) { - flashWriteWord(count, - *(unsigned int *) ((count | NONE_CACHEABLE) - + IMAGEOFFSET)); // skranz, modified. - temp = flashReadWord(count); - temp1 = *(unsigned int *) ((count | NONE_CACHEABLE) + IMAGEOFFSET); // skranz, modified. - if (((unsigned int) temp) != ((unsigned int) temp1)) { - printf - ("Burning error at address %X : flash(%X) sdram(%X)\n", - count, flashReadWord(count), - *(unsigned int *) ((count | NONE_CACHEABLE) + IMAGEOFFSET)); // skranz, modified. - printf("Aborting Prematurally.\n"); - break; - } - } - printf("Finished burning Image\n"); -} - -/****************************** - Routine: - Description: - Formats: - %X - 4 byte ASCII (8 hex digits) - %x - 2 byte ASCII (4 hex digits) - %b - 1 byte ASCII (2 hex digits) - %d - decimal (also %i) - %c - ASCII char - %s - ASCII string - %I - Internet address in x.x.x.x notation - ******************************/ -static char hex[] = "0123456789ABCDEF"; -static char *do_printf(char *buf, const char *fmt, const int *dp) -{ - register char *p; - char tmp[16]; - while (*fmt) { - if (*fmt == '%') { /* switch() uses more space */ - fmt++; - - if (*fmt == 'X') { - const long *lp = (const long *) dp; - register long h = *lp++; - dp = (const int *) lp; - *(buf++) = hex[(h >> 28) & 0x0F]; - *(buf++) = hex[(h >> 24) & 0x0F]; - *(buf++) = hex[(h >> 20) & 0x0F]; - *(buf++) = hex[(h >> 16) & 0x0F]; - *(buf++) = hex[(h >> 12) & 0x0F]; - *(buf++) = hex[(h >> 8) & 0x0F]; - *(buf++) = hex[(h >> 4) & 0x0F]; - *(buf++) = hex[h & 0x0F]; - } - if (*fmt == 'x') { - register int h = *(dp++); - *(buf++) = hex[(h >> 12) & 0x0F]; - *(buf++) = hex[(h >> 8) & 0x0F]; - *(buf++) = hex[(h >> 4) & 0x0F]; - *(buf++) = hex[h & 0x0F]; - } - if (*fmt == 'b') { - register int h = *(dp++); - *(buf++) = hex[(h >> 4) & 0x0F]; - *(buf++) = hex[h & 0x0F]; - } - if ((*fmt == 'd') || (*fmt == 'i')) { - register int dec = *(dp++); - p = tmp; - if (dec < 0) { - *(buf++) = '-'; - dec = -dec; - } - do { - *(p++) = '0' + (dec % 10); - dec = dec / 10; - } while (dec); - while ((--p) >= tmp) - *(buf++) = *p; - } - if (*fmt == 'I') { - union { - long l; - unsigned char c[4]; - } u; - const long *lp = (const long *) dp; - u.l = *lp++; - dp = (const int *) lp; - buf = sprintf(buf, "%d.%d.%d.%d", - u.c[0], u.c[1], u.c[2], - u.c[3]); - } - if (*fmt == 'c') - *(buf++) = *(dp++); - if (*fmt == 's') { - p = (char *) *dp++; - while (*p) - *(buf++) = *p++; - } - } else - *(buf++) = *fmt; - fmt++; - } - *buf = 0; - return (buf); -} - -/****************************** - Routine: - Description: - ******************************/ -static char *sprintf(char *buf, const char *fmt, ...) -{ - return do_printf(buf, fmt, ((const int *) &fmt) + 1); -} - -/****************************** - Routine: - Description: - ******************************/ -void putchar(int c) -{ - if (c == '\n') { - serial_putc('\r'); - } - serial_putc(c); -} - -/****************************** - Routine: - Description: - ******************************/ -static void printf(const char *fmt, ...) -{ - char buf[256], *p; - p = buf; - do_printf(buf, fmt, ((const int *) &fmt) + 1); - while (*p) - putchar(*p++); -} Index: arch/mips/galileo-boards/ev64120/compressed/doit.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/doit.c diff -N arch/mips/galileo-boards/ev64120/compressed/doit.c --- arch/mips/galileo-boards/ev64120/compressed/doit.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,75 +0,0 @@ -/* - * By RidgeRun Inc. - * - * The input to this program is intended to be - * a compressed linux kernel. The output of this - * program is then a constructed *.S file which - * defines a large data structure -- the contents - * of which represent the compressed kernel which - * can subsequently be used in a program designed - * to access that struture for decompression at - * runtime and then subsequent kernel bootup. - * - * Example Usage: - * ./doit < piggy.gz > piggy.S - * - */ - -#include - -void printval(int i) -{ - int tth, th, h, t, d; - - if (i > 99999) { - printf("Error - printval outofbounds\n"); - return; - } - - tth = 0; - th = 0; - //tth = (i) / 10000; - //th = (i - (tth * 10000)) / 1000; - h = (i - ((tth * 10000) + (th * 1000))) / 100; - t = (i - ((tth * 10000) + (th * 1000) + (h * 100))) / 10; - d = (i - ((tth * 10000) + (th * 1000) + (h * 100) + (t * 10))); - //putchar(tth + '0'); - //putchar(th + '0'); - putchar(h + '0'); - putchar(t + '0'); - putchar(d + '0'); -} - -main(int argc, char **argv) -{ - int val; - int size = 0; - unsigned char c; - - printf("gcc2_compiled.:\n"); - printf("__gnu_compiled_c:\n"); - printf("\t.globl linux_compressed_start\n"); - printf("\t.text\n"); - printf("\t.align 2\n"); - printf("\t.type linux_compressed_start,@object\n"); - printf("linux_compressed_start:\n"); - - - val = getchar(); - while (val != EOF) { - size++; - c = (unsigned char) (val & 0x00ff); - printf("\t.byte "); - printval((int) c); - printf("\n"); - val = getchar(); - } - printf("\t.size linux_compressed_start,%d\n", size); - printf("\t.globl linux_compressed_size\n"); - printf("\t.text\n"); - printf("\t.align 2\n"); - printf("\t.type linux_compressed_size,@object\n"); - printf("\t.size linux_compressed_size,4\n"); - printf("linux_compressed_size:\n"); - printf("\t.word %d\n", size); -} Index: arch/mips/galileo-boards/ev64120/compressed/etherboot.h =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/etherboot.h diff -N arch/mips/galileo-boards/ev64120/compressed/etherboot.h --- arch/mips/galileo-boards/ev64120/compressed/etherboot.h 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,566 +0,0 @@ -/************************************************************************** -ETHERBOOT - BOOTP/TFTP Bootstrap Program - -Author: Martin Renters - Date: Dec/93 - -**************************************************************************/ - -#include "osdep.h" - -/* These could be customised for different languages perhaps */ -#define ASK_PROMPT "Boot from (N)etwork or from (L)ocal? " -#define ANS_NETWORK 'N' -#define ANS_LOCAL 'L' -#ifndef ANS_DEFAULT /* in case left out in Makefile */ -#define ANS_DEFAULT ANS_NETWORK -#endif - -#define TAGGED_IMAGE /* eventually optional */ -#if !defined(TAGGED_IMAGE) && !defined(AOUT_IMAGE) && !defined(ELF_IMAGE) -#define TAGGED_IMAGE /* choose at least one */ -#endif - -#define ESC 0x1B - -#ifndef DEFAULT_BOOTFILE -#define DEFAULT_BOOTFILE "/tftpboot/kernel" -#endif - -/* Clean up console settings... mainly CONSOLE_CRT and CONSOLE_SERIAL are used - * in the sources (except start.S and serial.S which cannot include - * etherboot.h). At least one of the CONSOLE_xxx has to be set, and - * CONSOLE_DUAL sets both CONSOLE_CRT and CONSOLE_SERIAL. If none is set, - * CONSOLE_CRT is assumed. */ -#ifdef CONSOLE_DUAL -#undef CONSOLE_CRT -#define CONSOLE_CRT -#undef CONSOLE_SERIAL -#define CONSOLE_SERIAL -#endif -#if defined(CONSOLE_CRT) && defined(CONSOLE_SERIAL) -#undef CONSOLE_DUAL -#define CONSOLE_DUAL -#endif -#if !defined(CONSOLE_CRT) && !defined(CONSOLE_SERIAL) -#define CONSOLE_CRT -#endif - -#ifndef DOWNLOAD_PROTO_NFS -#undef DOWNLOAD_PROTO_TFTP -#define DOWNLOAD_PROTO_TFTP /* default booting protocol */ -#endif - -#ifdef DOWNLOAD_PROTO_TFTP -#define download(fname,loader) tftp((fname),(loader)) -#endif -#ifdef DOWNLOAD_PROTO_NFS -#define download(fname,loader) nfs((fname),(loader)) -#endif - -#ifndef MAX_TFTP_RETRIES -#define MAX_TFTP_RETRIES 20 -#endif - -#ifndef MAX_BOOTP_RETRIES -#define MAX_BOOTP_RETRIES 20 -#endif - -#ifndef MAX_BOOTP_EXTLEN -#if (RELOC < 0x94000) -/* Force internal buffer (if external buffer would overlap with our code...) */ -#undef INTERNAL_BOOTP_DATA -#define INTERNAL_BOOTP_DATA -#endif -/* sizeof(struct bootp_t) == 0x240 */ -#if defined(INTERNAL_BOOTP_DATA) || (RELOC >= 0x94240) -#define MAX_BOOTP_EXTLEN 1024 -#else -#define MAX_BOOTP_EXTLEN (1024-sizeof(struct bootp_t)) -#endif -#endif - -#ifndef MAX_ARP_RETRIES -#define MAX_ARP_RETRIES 20 -#endif - -#ifndef MAX_RPC_RETRIES -#define MAX_RPC_RETRIES 20 -#endif - -#define TICKS_PER_SEC 18 - -/* Inter-packet retry in ticks */ -#define TIMEOUT (10*TICKS_PER_SEC) - -/* These settings have sense only if compiled with -DCONGESTED */ -/* total retransmission timeout in ticks */ -#define TFTP_TIMEOUT (30*TICKS_PER_SEC) -/* packet retransmission timeout in ticks */ -#define TFTP_REXMT (3*TICKS_PER_SEC) - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#define TRUE 1 -#define FALSE 0 - -#define ETHER_ADDR_SIZE 6 /* Size of Ethernet address */ -#define ETHER_HDR_SIZE 14 /* Size of ethernet header */ -#define ETH_MIN_PACKET 64 -#define ETH_MAX_PACKET 1518 - -#define VENDOR_NONE 0 -#define VENDOR_WD 1 -#define VENDOR_NOVELL 2 -#define VENDOR_3COM 3 -#define VENDOR_3C509 4 -#define VENDOR_CS89x0 5 - -#define FLAG_PIO 0x01 -#define FLAG_16BIT 0x02 -#define FLAG_790 0x04 - -#define ARP_CLIENT 0 -#define ARP_SERVER 1 -#define ARP_GATEWAY 2 -#define ARP_ROOTSERVER 3 -#define ARP_SWAPSERVER 4 -#define MAX_ARP ARP_SWAPSERVER+1 - -#define RARP_REQUEST 3 -#define RARP_REPLY 4 - -#define IP 0x0800 -#define ARP 0x0806 -#define RARP 0x8035 - -#define BOOTP_SERVER 67 -#define BOOTP_CLIENT 68 -#define TFTP_PORT 69 -#define SUNRPC_PORT 111 - -#define IP_UDP 17 -/* Same after going through htonl */ -#define IP_BROADCAST 0xFFFFFFFF - -#define ARP_REQUEST 1 -#define ARP_REPLY 2 - -#define BOOTP_REQUEST 1 -#define BOOTP_REPLY 2 - -#define TAG_LEN(p) (*((p)+1)) -#define RFC1533_COOKIE 99, 130, 83, 99 -#define RFC1533_PAD 0 -#define RFC1533_NETMASK 1 -#define RFC1533_TIMEOFFSET 2 -#define RFC1533_GATEWAY 3 -#define RFC1533_TIMESERVER 4 -#define RFC1533_IEN116NS 5 -#define RFC1533_DNS 6 -#define RFC1533_LOGSERVER 7 -#define RFC1533_COOKIESERVER 8 -#define RFC1533_LPRSERVER 9 -#define RFC1533_IMPRESSSERVER 10 -#define RFC1533_RESOURCESERVER 11 -#define RFC1533_HOSTNAME 12 -#define RFC1533_BOOTFILESIZE 13 -#define RFC1533_MERITDUMPFILE 14 -#define RFC1533_DOMAINNAME 15 -#define RFC1533_SWAPSERVER 16 -#define RFC1533_ROOTPATH 17 -#define RFC1533_EXTENSIONPATH 18 -#define RFC1533_IPFORWARDING 19 -#define RFC1533_IPSOURCEROUTING 20 -#define RFC1533_IPPOLICYFILTER 21 -#define RFC1533_IPMAXREASSEMBLY 22 -#define RFC1533_IPTTL 23 -#define RFC1533_IPMTU 24 -#define RFC1533_IPMTUPLATEAU 25 -#define RFC1533_INTMTU 26 -#define RFC1533_INTLOCALSUBNETS 27 -#define RFC1533_INTBROADCAST 28 -#define RFC1533_INTICMPDISCOVER 29 -#define RFC1533_INTICMPRESPOND 30 -#define RFC1533_INTROUTEDISCOVER 31 -#define RFC1533_INTROUTESOLICIT 32 -#define RFC1533_INTSTATICROUTES 33 -#define RFC1533_LLTRAILERENCAP 34 -#define RFC1533_LLARPCACHETMO 35 -#define RFC1533_LLETHERNETENCAP 36 -#define RFC1533_TCPTTL 37 -#define RFC1533_TCPKEEPALIVETMO 38 -#define RFC1533_TCPKEEPALIVEGB 39 -#define RFC1533_NISDOMAIN 40 -#define RFC1533_NISSERVER 41 -#define RFC1533_NTPSERVER 42 -#define RFC1533_VENDOR 43 -#define RFC1533_NBNS 44 -#define RFC1533_NBDD 45 -#define RFC1533_NBNT 46 -#define RFC1533_NBSCOPE 47 -#define RFC1533_XFS 48 -#define RFC1533_XDM 49 -#ifndef NO_DHCP_SUPPORT -#define RFC2132_REQ_ADDR 50 -#define RFC2132_MSG_TYPE 53 -#define RFC2132_SRV_ID 54 -#define RFC2132_PARAM_LIST 55 -#define RFC2132_MAX_SIZE 57 - -#define DHCPDISCOVER 1 -#define DHCPOFFER 2 -#define DHCPREQUEST 3 -#define DHCPACK 5 -#endif /* NO_DHCP_SUPPORT */ - -#define RFC1533_VENDOR_MAJOR 0 -#define RFC1533_VENDOR_MINOR 0 - -#define RFC1533_VENDOR_MAGIC 128 -#define RFC1533_VENDOR_ADDPARM 129 -#ifdef IMAGE_FREEBSD -#define RFC1533_VENDOR_HOWTO 132 -#endif -#define RFC1533_VENDOR_MNUOPTS 160 -#define RFC1533_VENDOR_SELECTION 176 -#define RFC1533_VENDOR_MOTD 184 -#define RFC1533_VENDOR_NUMOFMOTD 8 -#define RFC1533_VENDOR_IMG 192 -#define RFC1533_VENDOR_NUMOFIMG 16 - -#define RFC1533_END 255 -#define BOOTP_VENDOR_LEN 64 -#ifndef NO_DHCP_SUPPORT -#define DHCP_OPT_LEN 312 -#endif /* NO_DHCP_SUPPORT */ - -#define TFTP_DEFAULTSIZE_PACKET 512 -#define TFTP_MAX_PACKET 1432 /* 512 */ - -#define TFTP_RRQ 1 -#define TFTP_WRQ 2 -#define TFTP_DATA 3 -#define TFTP_ACK 4 -#define TFTP_ERROR 5 -#define TFTP_OACK 6 - -#define TFTP_CODE_EOF 1 -#define TFTP_CODE_MORE 2 -#define TFTP_CODE_ERROR 3 -#define TFTP_CODE_BOOT 4 -#define TFTP_CODE_CFG 5 - -#define AWAIT_ARP 0 -#define AWAIT_BOOTP 1 -#define AWAIT_TFTP 2 -#define AWAIT_RARP 3 -#define AWAIT_RPC 4 -#define AWAIT_QDRAIN 5 /* drain queue, process ARP requests */ - -typedef struct { - unsigned long s_addr; -} in_addr; - -struct arptable_t { - in_addr ipaddr; - unsigned char node[6]; -}; - -/* - * A pity sipaddr and tipaddr are not longword aligned or we could use - * in_addr. No, I don't want to use #pragma packed. - */ -struct arprequest { - unsigned short hwtype; - unsigned short protocol; - char hwlen; - char protolen; - unsigned short opcode; - char shwaddr[6]; - char sipaddr[4]; - char thwaddr[6]; - char tipaddr[4]; -}; - -struct iphdr { - char verhdrlen; - char service; - unsigned short len; - unsigned short ident; - unsigned short frags; - char ttl; - char protocol; - unsigned short chksum; - in_addr src; - in_addr dest; -}; - -struct udphdr { - unsigned short src; - unsigned short dest; - unsigned short len; - unsigned short chksum; -}; - -struct bootp_t { - struct iphdr ip; - struct udphdr udp; - char bp_op; - char bp_htype; - char bp_hlen; - char bp_hops; - unsigned long bp_xid; - unsigned short bp_secs; - unsigned short unused; - in_addr bp_ciaddr; - in_addr bp_yiaddr; - in_addr bp_siaddr; - in_addr bp_giaddr; - char bp_hwaddr[16]; - char bp_sname[64]; - char bp_file[128]; -#ifdef NO_DHCP_SUPPORT - char bp_vend[BOOTP_VENDOR_LEN]; -#else - char bp_vend[DHCP_OPT_LEN]; -#endif /* NO_DHCP_SUPPORT */ -}; - -struct bootpd_t { - struct bootp_t bootp_reply; - unsigned char bootp_extension[MAX_BOOTP_EXTLEN]; -}; - -struct tftp_t { - struct iphdr ip; - struct udphdr udp; - unsigned short opcode; - union { - char rrq[TFTP_DEFAULTSIZE_PACKET]; - struct { - unsigned short block; - char download[TFTP_MAX_PACKET]; - } data; - struct { - unsigned short block; - } ack; - struct { - unsigned short errcode; - char errmsg[TFTP_DEFAULTSIZE_PACKET]; - } err; - struct { - char data[TFTP_DEFAULTSIZE_PACKET + 2]; - } oack; - } u; -}; - -#define TFTP_MIN_PACKET (sizeof(struct iphdr) + sizeof(struct udphdr) + 4) - -struct rpc_t { - struct iphdr ip; - struct udphdr udp; - union { - char data[300]; /* longest RPC call must fit!!!! */ - struct { - long id; - long type; - long rpcvers; - long prog; - long vers; - long proc; - long data[1]; - } call; - struct { - long id; - long type; - long rstatus; - long verifier; - long v2; - long astatus; - long data[1]; - } reply; - } u; -}; - -#define PROG_PORTMAP 100000 -#define PROG_NFS 100003 -#define PROG_MOUNT 100005 - -#define MSG_CALL 0 -#define MSG_REPLY 1 - -#define PORTMAP_GETPORT 3 - -#define MOUNT_ADDENTRY 1 -#define MOUNT_UMOUNTALL 4 - -#define NFS_LOOKUP 4 -#define NFS_READ 6 - -#define NFS_FHSIZE 32 - -#define NFSERR_PERM 1 -#define NFSERR_NOENT 2 -#define NFSERR_ACCES 13 - -/* Block size used for NFS read accesses. A RPC reply packet (including all - * headers) must fit within a single Ethernet frame to avoid fragmentation. - * Chosen to be a power of two, as most NFS servers are optimized for this. */ -#define NFS_READ_SIZE 1024 - -#define FLOPPY_BOOT_LOCATION 0x7c00 - -#define ROM_INFO_LOCATION 0x7dfa -/* at end of floppy boot block */ - -struct rom_info { - unsigned short rom_segment; - unsigned short rom_length; -}; - -/*************************************************************************** -External prototypes -***************************************************************************/ -/* main.c */ -extern void print_bytes P((unsigned char *bytes, int len)); -extern void load P((void)); -extern int load_linux P((int root_mount_port, int swap_mount_port, - int root_nfs_port, char *kernel_handle)); -extern int downloadkernel P((unsigned char *, int, int, int)); -extern int tftp -P((const char *name, int (*)(unsigned char *, int, int, int))); -extern void rpc_init(void); -extern int nfs -P((const char *name, int (*)(unsigned char *, int, int, int))); -extern void nfs_umountall P((int)); -extern int bootp P((void)); -extern int rarp P((void)); -extern int udp_transmit P((unsigned long destip, unsigned int srcsock, - unsigned int destsock, int len, - const void *buf)); - -extern int await_reply P((int type, int ival, void *ptr, int timeout)); -extern int decode_rfc1533 P((unsigned char *, int, int, int)); -extern unsigned short ipchksum P((unsigned short *, int len)); -extern void rfc951_sleep P((int)); -extern void cleanup_net P((void)); -extern void cleanup P((void)); - -/* config.c */ -extern void print_config(void); -extern void eth_reset(void); -extern int eth_probe(void); -extern int eth_poll(void); -extern void eth_transmit(const char *d, unsigned int t, unsigned int s, - const void *p); -extern void eth_disable(void); - -/* bootmenu.c */ -extern int execute P((char *string)); -extern void bootmenu P((int)); -extern void show_motd P((void)); -extern void parse_menuopts P((char *, int)); -extern int getoptvalue P((char **, int *, int *)); -extern void selectImage P((char **)); - -/* osloader.c */ -#if defined(AOUT_IMAGE) || defined(ELF_IMAGE) -extern int howto; -#endif -extern int os_download P((unsigned int, unsigned char *, unsigned int)); - -/* misc.c */ -extern void twiddle P((void)); -extern void sleep P((int secs)); -extern int strcasecmp P((char *a, char *b)); -extern char *substr P((char *a, char *b)); -extern int getdec P((char **)); -extern void printf P((const char *, ...)); -extern char *sprintf P((char *, const char *, ...)); -extern int inet_aton P((char *p, in_addr * i)); -extern void gateA20_set P((void)); -extern void gateA20_unset P((void)); -extern void putchar P((int)); -extern int getchar P((void)); -extern int iskey P((void)); - -/* start*.S */ -extern int getc P((void)); -extern void putc P((int)); -extern int ischar P((void)); -extern int getshift P((void)); -extern unsigned int memsize P((void)); -extern unsigned short basememsize P((void)); -extern void disk_init P((void)); -extern unsigned int disk_read P((int drv, int c, int h, int s, char *buf)); -extern void xstart P((unsigned long, unsigned long, char *)); -extern unsigned long currticks P((void)); -extern int setjmp P((void *jmpbuf)); -extern void longjmp P((void *jmpbuf, int where)); -extern void exit P((int status)); -extern void slowdownio P((void)); - -/* serial.S */ -extern int serial_getc P((void)); -extern void serial_putc P((int)); -extern int serial_ischar P((void)); -extern int serial_init P((void)); - -/* ansiesc.c */ -extern void ansi_reset P((void)); -extern void enable_cursor P((int)); -extern void handleansi P((unsigned char)); - -/* md5.c */ -extern void md5_put P((unsigned int ch)); -extern void md5_done P((unsigned char *buf)); - -/* floppy.c */ -extern int bootdisk P((int dev, int part)); - -/*************************************************************************** -External variables -***************************************************************************/ -/* main.c */ -extern const char *kernel; -extern char kernel_buf[128]; -extern struct rom_info rom; -extern int hostnamelen; -extern unsigned long netmask; -extern int jmp_bootmenu[10]; -extern struct arptable_t arptable[MAX_ARP]; -#ifdef IMAGE_MENU -extern char *motd[RFC1533_VENDOR_NUMOFMOTD]; -extern int menutmo, menudefault; -extern unsigned char *defparams; -extern int defparams_max; -#endif -#if defined(ETHERBOOT32) && !defined(INTERNAL_BOOTP_DATA) -#define BOOTP_DATA_ADDR ((struct bootpd_t *)0x93C00) -#else -extern struct bootpd_t bootp_data; -#define BOOTP_DATA_ADDR (&bootp_data) -#endif -extern unsigned char *end_of_rfc1533; -#ifdef IMAGE_FREEBSD -extern int freebsd_howto; -#endif - -/* config.c */ -extern struct nic nic; - -/* bootmenu.c */ - -/* osloader.c */ - -/* created by linker */ -extern char _start[], _edata[], _end[]; - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ Index: arch/mips/galileo-boards/ev64120/compressed/evb64120A_Setup.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/evb64120A_Setup.c diff -N arch/mips/galileo-boards/ev64120/compressed/evb64120A_Setup.c --- arch/mips/galileo-boards/ev64120/compressed/evb64120A_Setup.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,197 +0,0 @@ -/* - * arch/mips/galileo/compressed/evb64120A_memSetup.c - * - * By RidgeRun Inc, (Leveraged from Galileo's sbd.c) - * - * Xfer an image from flash to ram. - * For use with Galileo EVB64120A MIPS eval board. - */ -#include "ns16550.h" -#include -#include -#include - -void XferToRam(void); -bool mapMemoryBanks0and1(unsigned int bank0Base, unsigned int bank0Length, - unsigned int bank1Base, unsigned int bank1Length); -bool mapMemoryBanks2and3(unsigned int bank2Base, unsigned int bank2Length, - unsigned int bank3Base, unsigned int bank3Length); -bool mapDevices0_1and2MemorySpace(unsigned int device0Base, - unsigned int device0Length, - unsigned int device1Base, - unsigned int device1Length, - unsigned int device2Base, - unsigned int device2Length); - -#define RUNNINGFROMFLASH -#include "./xfer.c" - -/****************************** - Routine: - Description: - ******************************/ -unsigned int readWord(unsigned int addr) -{ - unsigned int tmp; - tmp = *(unsigned int *) (addr | NONE_CACHEABLE); - return WORDSWAP(tmp); -} - -/****************************** - Routine: - Description: - ******************************/ -void writeWord(unsigned int addr, unsigned int data) -{ - *((unsigned int *) (addr | NONE_CACHEABLE)) = WORDSWAP(data); -} - -/****************************** - Routine: - Description: - ******************************/ -unsigned int GetExtendedMemorySize(void) -{ - unsigned int address, data = 0x11223344, type; - unsigned int bank1_ef = false, bank2_ef = false, bank3_ef = false; - unsigned int bank0_size, bank2_size, bank3_size, total_size = 0; - - mapMemoryBanks0and1(0, 0x800000, 0x800000, 0x800000); - mapMemoryBanks2and3(0x1000000, 0x800000, 0x1800000, 0x800000); - type = readWord(0x14000810); - switch (type) { - case 16: - bank0_size = 0x1000000; - break; - case 64: - bank0_size = 0x4000000; - break; - case 128: - bank0_size = 0x8000000; - break; - case 256: - bank0_size = 0x10000000; - break; - default: - bank0_size = 0x1000000; - break; - } - - type = readWord(0x14000814); - switch (type) { - case 16: - bank2_size = 0x1000000; - bank3_size = 0x1000000; - break; - case 64: - bank2_size = 0x4000000; - bank3_size = 0x4000000; - break; - case 128: - bank2_size = 0x8000000; - bank3_size = 0x8000000; - break; - case 256: - bank2_size = 0x10000000; - bank3_size = 0x10000000; - break; - default: - bank2_size = 0x1000000; - bank3_size = 0x1000000; - break; - } - - /* Check which banks exist */ - /* Bank 1 */ - for (address = 0xffff00; address < 0x1000000; address += 4) - writeWord(address, data); - for (address = 0xffff00; address < 0x1000000; address += 4) { - if (readWord(address) != data) - break; - } - if (address == 0x1000000) - bank1_ef = true; - // Bank 2 - for (address = 0x17fff00; address < 0x1800000; address += 4) - writeWord(address, data); - for (address = 0x17fff00; address < 0x1800000; address += 4) { - if (readWord(address) != data) - break; - } - if (address == 0x1800000) - bank2_ef = true; - else - bank2_size = 0x0; - // Bank 3 - for (address = 0x1ffff00; address < 0x2000000; address += 4) - writeWord(address, data); - for (address = 0x1ffff00; address < 0x2000000; address += 4) { - if (readWord(address) != data) - break; - } - if (address == 0x2000000) - bank3_ef = true; - - // Reconfig the system with the new bank0 (and maybe bank1) size. - if (bank0_size == 0x10000000) - bank1_ef = false; - if (bank1_ef == true) { - mapMemoryBanks0and1(0, bank0_size, bank0_size, bank0_size); - // Fix the PCI bars - pci0MapMemoryBanks0_1(0, bank0_size * 2); - pci1MapMemoryBanks0_1(0, bank0_size * 2); - total_size += bank0_size * 2; - } else { - mapMemoryBanks0and1(0, bank0_size, bank0_size, 0); - // Fix the PCI bars - pci0MapMemoryBanks0_1(0, bank0_size); - pci1MapMemoryBanks0_1(0, bank0_size); - total_size += bank0_size; - } - if (total_size == 0x10000000) { - bank2_ef = false; - bank3_ef = false; - } else { - if ((total_size + bank2_size) > 0x10000000) { - bank2_size = 0x10000000 - total_size; - bank3_ef = false; - } else { - if (bank3_size + total_size + bank2_size > - 0x10000000) { - bank3_size = - 0x10000000 - (total_size + bank2_size); - } - } - } - if (bank2_ef == true) { - if (bank3_ef == true) { - mapMemoryBanks2and3(total_size, bank2_size, - total_size + bank2_size, - bank3_size); - // Fix the PCI bars - pci0MapMemoryBanks2_3(total_size, - bank2_size + bank3_size); - pci1MapMemoryBanks2_3(total_size, - bank2_size + bank3_size); - total_size += (bank2_size + bank3_size); - } else { - mapMemoryBanks2and3(total_size, bank2_size, - total_size + bank2_size, 0); - // Fix the PCI bars - pci0MapMemoryBanks2_3(total_size, bank2_size); - pci1MapMemoryBanks2_3(total_size, bank2_size); - total_size += bank2_size; - } - } else { - mapMemoryBanks2and3(total_size, 0, total_size, 0); - pci0MapMemoryBanks2_3(total_size, 0); - pci1MapMemoryBanks2_3(total_size, 0); - } - /* Reorganize the devices memory map */ - mapDevices0_1and2MemorySpace(0x1c000000, 0x800000, 0x1a000000, - 0xc00000, 0x1d000000, 0x800000); - - XferToRam(); - return 0; // Not that we'll ever get to this line of code, but - // it does satisfy a compiler warning. -} Index: arch/mips/galileo-boards/ev64120/compressed/fixit =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/fixit diff -N arch/mips/galileo-boards/ev64120/compressed/fixit --- arch/mips/galileo-boards/ev64120/compressed/fixit 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,17 +0,0 @@ -#!/bin/ksh - -# By RidgeRun Inc. -# -# The input to this script is -# intended to be a *.S file which -# was previously created by the doit -# program. That program constructs -# a *.S file which has a defined data -# table containing values with leading -# zeroes. To satisfy our assembler those -# leading zeroes need to be stripped off -# and that is the purpose of this script. - -echo "Removing leading zeros" -sed -e "s/ 0\(.\)/ \1/g" $1 | sed -e "s/ 0\(.\)/ \1/g" > $1.new -mv $1.new $1 Index: arch/mips/galileo-boards/ev64120/compressed/flashdrv.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/flashdrv.c diff -N arch/mips/galileo-boards/ev64120/compressed/flashdrv.c --- arch/mips/galileo-boards/ev64120/compressed/flashdrv.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1560 +0,0 @@ -/* flashdrv.c - FLASH memory functions and definitions*/ - -/* Copyright Galileo Technology. */ - -/* -DESCRIPTION -This flash driver gives the user a convenient interface to FLASH memory located -on the user`s board, it supports various layout configurations such as: -1. One pure 8 bit device (Such as AMD`s AM29LV040B). -2. 1,2,4 or 8 devices 16 bit wide configured to operate in 8 bit mode. -3. 1,2 or 4 devices each 16 bit wide. -Before using the driver you must call the initialization function at least once -or when ever you are changing the FLASH base address. -The list bellow contains the supported FLASH memory devices, new devices can be -added easily in the future. -*/ - -/*includes*/ -#ifdef __linux__ -#include -#else -#include "flashdrv.h" -#endif -/* locals */ - -#ifdef __MIPSEB__ // skranz, add -#define BE // skranz, add -#endif // skranz, add - -/****************************************************************************** -* Those two tables contain the supported flash devices information needed by -* the driver: -* The first table "flashParametrs" starts with 10 shared fields -* (currently 6 are reserved): -* index 0 => Pointer to an entry in the second table list -* index 1 => baseAddress - Flash memory device base address. -* index 2 => width - 1, 2, 4 or 8 Bytes. -* index 3 => mode - PURE8, X8 or X16 flash configuration (for X16 devices only) -* The second table (flashTypes) contains: -* Entry`s structure: -* Manufacture ID,Device ID,number of sectors,list of sector`s sizes -* (in Kbytes starting with sector number 0). -* The end of the list is pointed with a zero. -******************************************************************************/ -unsigned int flashParametrs[10]; /* 0 Entry pointer */ - /* 0 Base address */ - /* 0 Width */ - /* 0 Mode */ - /* 0,0,0,0,0,0, spare entries. */ -unsigned int flashTypes[] = { - - /* 0 */ AMD_FLASH, AM29F400BB, 11, 16, 8, 8, 32, 64, 64, 64, 64, - 64, 64, 64, - /* 1 */ AMD_FLASH, AM29F400BT, 11, 64, 64, 64, 64, 64, 64, 64, 32, - 8, 8, 16, - /* 2 */ ST_FLASH, M29W040, 8, 64, 64, 64, 64, 64, 64, 64, 64, - /* 3 */ AMD_FLASH, AM29LV040B, 8, 64, 64, 64, 64, 64, 64, 64, 64, - /* 4 */ AMD_FLASH, AM29LV800BT, 19, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, - 64, 64, 64, 64, 64, 32, 8, 8, 16, - /* 5 */ INTEL_FLASH, I28F320J3A, 32, 128, 128, 128, 128, 128, 128, - 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, - /* 6 */ INTEL_FLASH, I28F640J3A, 64, 128, 128, 128, 128, 128, 128, - 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, - /* 7 */ INTEL_FLASH, I28F128J3A, 128, 128, 128, 128, 128, 128, 128, - 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - /* 8 */ AMD_FLASH, AM29LV400BB, 11, 16, 8, 8, 32, 64, 64, 64, 64, - 64, 64, 64, - /* 9 */ AMD_FLASH, AM29LV400BT, 11, 64, 64, 64, 64, 64, 64, 64, 32, - 8, 8, 16, - /* 10 */ INTEL_FLASH, I28F320B3_T, 71, 64, 64, 64, 64, 64, 64, 64, - 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 8, 8, 8, 8, 8, 8, 8, 8, - /* 11 */ INTEL_FLASH, I28F320B3_B, 71, 8, 8, 8, 8, 8, 8, 8, 8, 64, - 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - /* 12 */ INTEL_FLASH, I28F160B3_B, 39, 8, 8, 8, 8, 8, 8, 8, 8, 64, - 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - /* 13 */ INTEL_FLASH, I28F160B3_T, 39, 64, 64, 64, 64, 64, 64, 64, - 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 8, 8, 8, 8, 8, 8, 8, 8, - - 0 /* End of list indicator */ -}; - -/******************************************************************** -* flashInit - Initializes the FLASH memory driver`s parameters, this function -* must be called at least once before using the FLASH memory. -* If you are changing the FLASH base address call this function -* again. -* -* INPUTS: unsigned int flashBaseAddress - The flash base Address. -* unsigned int flashWidth - Flash bus width in Bytes: 1,2,4 or 8. -* flashMode - PURE8, X8 or X16. -* RETURNS: Flash Size, zero when operation (flashInit) failed. -*********************************************************************/ -unsigned int flashInit(unsigned int flashBaseAddress, - unsigned int flashWidth, FLASHmode flashMode) -{ - unsigned short mfrId = 0; - unsigned short devId = 0xffff; - unsigned int FirstAddr, SecondAddr, ThirdAddr; - unsigned int pArray = 0; - unsigned int counter; - unsigned int flashSize = 0; - - /* update the list with relevant parametrs */ - flashParametrs[0] = 0; /* Default initialization */ - flashParametrs[1] = flashBaseAddress; - flashParametrs[2] = flashWidth; - flashParametrs[3] = flashMode; - /* Get the FLASH`s ID */ - switch (FLASH_WIDTH) { - case 1: - /* AMD or ST ?? * */ - if (flashMode == PURE8) { /* Boot Flash */ - FirstAddr = 0x5555; - SecondAddr = 0x2aaa; - ThirdAddr = 0x5555; - } else { /* X16 device configured to 8bit Mode */ - - FirstAddr = 0xaaaa; - SecondAddr = 0x5555; - ThirdAddr = 0xaaaa; - } - flashReset(); - WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xAA); - WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55); - WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0x90); - READ_CHAR(FLASH_BASE_ADDRESS + 0x0, &mfrId); - if (mfrId == AMD_FLASH || mfrId == ST_FLASH) { - flashReset(); - WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xAA); - WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55); - WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0x90); - READ_CHAR(FLASH_BASE_ADDRESS + 0x1, &devId); - break; - } - /* Micron or Intel ?? * */ - WRITE_CHAR(FLASH_BASE_ADDRESS, 0xff); /* Read Array */ - /* Flash reset for Intel/Micron */ - WRITE_CHAR(FLASH_BASE_ADDRESS, 0x90); /* IDENTIFY Device */ - READ_CHAR(FLASH_BASE_ADDRESS + 0x0, &mfrId); /*Address for ManufactureID */ - if (mfrId == INTEL_FLASH || mfrId == MICRON_FLASH) { - WRITE_CHAR(FLASH_BASE_ADDRESS, 0xff); /* Read Array */ - /*Flash reset for Intel/Micron */ - WRITE_CHAR(FLASH_BASE_ADDRESS, 0x90); /* IDENTIFY Device */ - READ_CHAR(FLASH_BASE_ADDRESS + 0x1, &devId); /*Address for DeviceID */ - } - break; - case 2: - case 4: - case 8: - /* AMD or ST ??? */ - flashReset(); - WRITE_SHORT(FLASH_BASE_ADDRESS + 0x5555 * FLASH_WIDTH, - 0xaa); - WRITE_SHORT(FLASH_BASE_ADDRESS + 0x2aaa * FLASH_WIDTH, - 0x55); - WRITE_SHORT(FLASH_BASE_ADDRESS + 0x5555 * FLASH_WIDTH, - 0x90); - READ_SHORT(FLASH_BASE_ADDRESS, &mfrId); - flashReset(); - /* Read the device ID */ - if (mfrId == AMD_FLASH || mfrId == ST_FLASH) { - WRITE_SHORT(FLASH_BASE_ADDRESS + - 0x5555 * FLASH_WIDTH, 0xaa); - WRITE_SHORT(FLASH_BASE_ADDRESS + - 0x2aaa * FLASH_WIDTH, 0x55); - WRITE_SHORT(FLASH_BASE_ADDRESS + - 0x5555 * FLASH_WIDTH, 0x90); - READ_SHORT(FLASH_BASE_ADDRESS + 0x1 * FLASH_WIDTH, - &devId); - break; - } - /* Micron or Intel ?? * */ - WRITE_WORD(FLASH_BASE_ADDRESS, 0x00ff00ff); - WRITE_WORD(FLASH_BASE_ADDRESS, 0x00900090); - if ((FLASH_WIDTH == 4) || (FLASH_WIDTH == 8)) { /* 32 or 64 bit */ - READ_SHORT(FLASH_BASE_ADDRESS, &mfrId); - } else { /* FLASH_WIDTH = 2 */ - - READ_SHORT(FLASH_BASE_ADDRESS, &mfrId); - } - if ((mfrId == INTEL_FLASH) || (mfrId == MICRON_FLASH)) { - /* Flash reset for Intel/Micron */ - flashReset(); - WRITE_WORD(FLASH_BASE_ADDRESS, 0x00ff00ff); - WRITE_WORD(FLASH_BASE_ADDRESS, 0x00900090); - READ_SHORT(FLASH_BASE_ADDRESS + 0x1 * FLASH_WIDTH, - &devId); - } - break; - - } - /* Try to locate the device in the supported flashes list (FLASH_TYPE). - according to the keys: - 1) mfrId - manufactor ID. - 2) devId - device ID. - */ - - while (true) { - if (flashTypes[pArray] == 0) { - flashReset(); - return 0; /* Device not in the list */ - } - if ((flashTypes[pArray] == mfrId) && - (flashTypes[pArray + 1] == devId)) { - POINTER_TO_FLASH = pArray; - for (counter = 0; - counter < flashTypes[NUMBER_OF_SECTORS]; - counter++) { - flashSize = - flashSize + - flashTypes[FIRST_SECTOR_SIZE + - counter]; - } - if (FLASH_MODE != PURE8) { - flashReset(); - return (flashSize * _1K * - (FLASH_WIDTH / (FLASH_MODE / 8))); - } else { - flashReset(); - return (flashSize * _1K * FLASH_WIDTH); - } - } - pArray += (3 + flashTypes[pArray + 2]); /* Move to next entry */ - } -} - -/******************************************************************** -* flashReset - Resets the Flash memory (FLASH`s internal protocol reset). -* -* INTPUTS: N/A -* OUTPUT: N/A -*********************************************************************/ -void flashReset() -{ - unsigned char ucData; - unsigned short usData; - unsigned int uiData; - - if ((flashTypes[POINTER_TO_FLASH] == AMD_FLASH) || - (flashTypes[POINTER_TO_FLASH]) == ST_FLASH) { - if (FLASH_MODE == X16) { - ucData = 0xf0; - usData = 0xf0; - uiData = 0x00f000f0; - } else { /* case of PURE8 or X8 */ - - ucData = 0xf0; - usData = 0xf0f0; - uiData = 0xf0f0f0f0; - } - } else { - if (FLASH_MODE == X16) { - ucData = 0xff; - usData = 0xff; - uiData = 0x00ff00ff; - } else { /* case of PURE8 or X8 */ - - ucData = 0xff; - usData = 0xffff; - uiData = 0xffffffff; - } - } - switch (FLASH_WIDTH) { - case 1: - WRITE_CHAR(FLASH_BASE_ADDRESS, ucData); - break; - case 2: - WRITE_SHORT(FLASH_BASE_ADDRESS, usData); - break; - case 4: - WRITE_WORD(FLASH_BASE_ADDRESS, uiData); - break; - case 8: - WRITE_WORD(FLASH_BASE_ADDRESS, uiData); - WRITE_WORD(FLASH_BASE_ADDRESS + 0x4, uiData); - break; - } -} - -/******************************************************************** -* flashErase - The function erases the WHOLE flash memory. -* -* -* RETURNS: true on success,false on failure -*********************************************************************/ -bool flashErase() -{ - unsigned int totalFlashSize; - unsigned int address; - unsigned int readData; - unsigned int nextSector; - - flashReset(); - totalFlashSize = flashGetSize(); - /* scan all flash memory space. */ - address = 0; - while (address < totalFlashSize) { - readData = flashReadWord(address); - if (readData != 0xffffffff) { /* offset with dirty data. */ - flashEraseSector(flashInWhichSector(address)); - nextSector = flashInWhichSector(address) + 1; - if (nextSector < flashTypes[NUMBER_OF_SECTORS]) - /* jump to next sector. */ - address = flashGetSectorOffset(nextSector); - else - /* end of erasing. */ - address = totalFlashSize; - } else - address += 4; - } - return true; -} - -/******************************************************************** -* flashEraseSector - The function erases a specific sector in the flash memory. -* -* INPUTS: Sector number. -* RETURNS: true on success,false on failure. -*********************************************************************/ -bool flashEraseSector(unsigned int sectorNumber) -{ - volatile unsigned int spin; - unsigned int regValue; - unsigned int sectorBaseAddress = 0; - unsigned int i; - unsigned int data20, dataD0, data70; - unsigned int dataPoll; - unsigned int FirstAddr, SecondAddr, ThirdAddr, FourthAddr, - FifthAddr; - unsigned int FirstData, SecondData, ThirdData; - unsigned int FourthData, FifthData, SixthData; - - /* calculate the sector base Address according to the following parametrs: - 1: FLASH_WIDTH - 2: the size of each sector which it detailed in the table */ - - /* checking the if the sectorNumber is legal. */ - if (sectorNumber > flashTypes[NUMBER_OF_SECTORS] - 1) - return false; - /* now the calculation begining of the sector Address */ - for (i = 0; i < sectorNumber; i++) { - sectorBaseAddress = - sectorBaseAddress + flashTypes[FIRST_SECTOR_SIZE + i]; - } - /* In case of X8 wide the address should be */ - if (FLASH_MODE == PURE8) - sectorBaseAddress = _1K * sectorBaseAddress; - if (FLASH_MODE == X8) - sectorBaseAddress = _1K * sectorBaseAddress; - /* In case of X16 wide the address should be */ - if (FLASH_MODE == X16) - sectorBaseAddress = _1K * sectorBaseAddress / 2; - flashReset(); - if ((flashTypes[POINTER_TO_FLASH] == AMD_FLASH) || \ - (flashTypes[POINTER_TO_FLASH] == ST_FLASH)) { - switch (FLASH_WIDTH) { - case 1: - if (FLASH_MODE == PURE8) { /* Boot Flash PURE8 */ - FirstAddr = 0x5555; - SecondAddr = 0x2aaa; - ThirdAddr = 0x5555; - FourthAddr = 0x5555; - FifthAddr = 0x2aaa; - } else { - FirstAddr = 0xaaaa; - SecondAddr = 0x5555; - ThirdAddr = 0xaaaa; - FourthAddr = 0xaaaa; - FifthAddr = 0x5555; - } - WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xAA); - WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55); - WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0x80); - WRITE_CHAR(FLASH_BASE_ADDRESS + FourthAddr, 0xAA); - WRITE_CHAR(FLASH_BASE_ADDRESS + FifthAddr, 0x55); - WRITE_CHAR( - (FLASH_BASE_ADDRESS + - (sectorBaseAddress & 0xffffff00)), - 0x30); - /* Poll on the flash */ - do { - READ_CHAR(FLASH_BASE_ADDRESS + - sectorBaseAddress, ®Value); - } while ((regValue & 0x80) != 0x80); - - break; - case 2: - if (FLASH_MODE == X16) { - FirstData = 0xaa; /* Data for the First Cycle */ - SecondData = 0x55; /* Data for the Second Cycle */ - ThirdData = 0x80; /* Data for the Third Cycle */ - FourthData = 0xaa; /* Data for the Fourth Cycle */ - FifthData = 0x55; /* Data for the Fifth Cycle */ - SixthData = 0x30; /* Data for the Sixth Cycle */ - FirstAddr = 0x5555; /* Address for the First Cycle */ - SecondAddr = 0x2aaa; /* Address for the Second Cycle */ - ThirdAddr = 0x5555; /* Address for the Third Cycle */ - FourthAddr = 0x5555; /* Address for the Fourth Cycle */ - FifthAddr = 0x2aaa; /* Address for the Fifth Cycle */ - } else { /* (FLASH_MODE = 8) */ - - FirstData = 0xaaaa; /* Data for the First Cycle */ - SecondData = 0x5555; /* Data for the Second Cycle */ - ThirdData = 0x8080; /* Data for the Third Cycle */ - FourthData = 0xaaaa; /* Data for the Fourth Cycle */ - FifthData = 0x5555; /* Data for the Fifth Cycle */ - SixthData = 0x3030; /* Data for the Sixth Cycle */ - FirstAddr = 0xaaaa; /* Address for the First Cycle */ - SecondAddr = 0x5555; /* Address for the Second Cycle */ - ThirdAddr = 0xaaaa; /* Address for the Third Cycle */ - FourthAddr = 0xaaaa; /* Address for the Fourth Cycle */ - FifthAddr = 0x5555; /* Address for the Fifth Cycle */ - } - WRITE_SHORT(FLASH_BASE_ADDRESS + - FirstAddr * FLASH_WIDTH, FirstData); - WRITE_SHORT(FLASH_BASE_ADDRESS + - SecondAddr * FLASH_WIDTH, SecondData); - WRITE_SHORT(FLASH_BASE_ADDRESS + - ThirdAddr * FLASH_WIDTH, ThirdData); - WRITE_SHORT(FLASH_BASE_ADDRESS + - FourthAddr * FLASH_WIDTH, FourthData); - WRITE_SHORT(FLASH_BASE_ADDRESS + - FifthAddr * FLASH_WIDTH, FifthData); - WRITE_SHORT(FLASH_BASE_ADDRESS + - (sectorBaseAddress & 0xffffff00) * - FLASH_WIDTH, SixthData); - /* Poll on the flash */ - if (FLASH_MODE == X16) { /* 1 device of 16 bit */ - dataPoll = 0x0080; - } else { /* (FLASH_MODE = 8) ==> 2 devices , 8 bit each => 16bit */ - - dataPoll = 0x8080; - } - do { - READ_SHORT(FLASH_BASE_ADDRESS + - sectorBaseAddress * FLASH_WIDTH, - ®Value); - for (spin = 0; spin < 100; spin++) { - } // skranz, added spin loop. - } while ((regValue & dataPoll) != dataPoll); - break; - case 4: - if (FLASH_MODE == X16) { - FirstData = 0x00aa00aa; /* Data for the First Cycle */ - SecondData = 0x00550055; /* Data for the Second Cycle */ - ThirdData = 0x00800080; /* Data for the Third Cycle */ - FourthData = 0x00aa00aa; /* Data for the Fourth Cycle */ - FifthData = 0x00550055; /* Data for the Fifth Cycle */ - SixthData = 0x00300030; /* Data for the Sixth Cycle */ - FirstAddr = 0x5555; /* Address for the First Cycle */ - SecondAddr = 0x2aaa; /* Address for the Second Cycle */ - ThirdAddr = 0x5555; /* Address for the Third Cycle */ - FourthAddr = 0x5555; /* Address for the Fourth Cycle */ - FifthAddr = 0x2aaa; /* Address for the Fifth Cycle */ - } else { /* if (FLASH_MODE == 8) */ - - FirstData = 0xaaaaaaaa; /* Data for the First Cycle */ - SecondData = 0x55555555; /* Data for the Second Cycle */ - ThirdData = 0x80808080; /* Data for the Third Cycle */ - FourthData = 0xAAAAAAAA; /* Data for the Fourth Cycle */ - FifthData = 0x55555555; /* Data for the Fifth Cycle */ - SixthData = 0x30303030; /* Data for the Sixth Cycle */ - FirstAddr = 0xaaaa; /* Address for the First Cycle */ - SecondAddr = 0x5555; /* Address for the Second Cycle */ - ThirdAddr = 0xaaaa; /* Address for the Third Cycle */ - FourthAddr = 0xaaaa; /* Address for the Fourth Cycle */ - FifthAddr = 0x5555; /* Address for the Fifth Cycle */ - } - WRITE_WORD(FLASH_BASE_ADDRESS + - FirstAddr * FLASH_WIDTH, FirstData); - WRITE_WORD(FLASH_BASE_ADDRESS + - SecondAddr * FLASH_WIDTH, SecondData); - WRITE_WORD(FLASH_BASE_ADDRESS + - ThirdAddr * FLASH_WIDTH, ThirdData); - WRITE_WORD(FLASH_BASE_ADDRESS + - FourthAddr * FLASH_WIDTH, FourthData); - WRITE_WORD(FLASH_BASE_ADDRESS + - FifthAddr * FLASH_WIDTH, FifthData); - WRITE_WORD(FLASH_BASE_ADDRESS + - (sectorBaseAddress & 0xffffff00) * - FLASH_WIDTH, SixthData); - /* Poll on the flash */ - if (FLASH_MODE == X16) { /* 4 devices , 16 bit each => 64bit */ - dataPoll = 0x00800080; - } else { /* (FLASH_MODE = 8) ==> 8 devices , 8 bit each => 64bit */ - - dataPoll = 0x80808080; - } - do { - READ_WORD(FLASH_BASE_ADDRESS + - sectorBaseAddress * FLASH_WIDTH, - ®Value); - } while ((regValue & dataPoll) != dataPoll); - break; - case 8: /* In case of 64bit width the transformation is 1->8 */ - if (FLASH_MODE == X16) { - FirstData = 0x00aa00aa; /* Data for the First Cycle */ - SecondData = 0x00550055; /* Data for the Second Cycle */ - ThirdData = 0x00800080; /* Data for the Third Cycle */ - FourthData = 0x00aa00aa; /* Data for the Fourth Cycle */ - FifthData = 0x00550055; /* Data for the Fifth Cycle */ - SixthData = 0x00300030; /* Data for the Sixth Cycle */ - FirstAddr = 0x5555; /* Address for the First Cycle */ - SecondAddr = 0x2aaa; /* Address for the Second Cycle */ - ThirdAddr = 0x5555; /* Address for the Third Cycle */ - FourthAddr = 0x5555; /* Address for the Fourth Cycle */ - FifthAddr = 0x2aaa; /* Address for the Fifth Cycle */ - } else { /* (FLASH_MODE = 8 */ - - FirstData = 0xaaaaaaaa; /* Data for the First Cycle */ - SecondData = 0x55555555; /* Data for the Second Cycle */ - ThirdData = 0x80808080; /* Data for the Third Cycle */ - FourthData = 0xAAAAAAAA; /* Data for the Fourth Cycle */ - FifthData = 0x55555555; /* Data for the Fifth Cycle */ - SixthData = 0x30303030; /* Data for the Sixth Cycle */ - FirstAddr = 0xaaaa; /* Address for the First Cycle */ - SecondAddr = 0x5555; /* Address for the Second Cycle */ - ThirdAddr = 0xaaaa; /* Address for the Third Cycle */ - FourthAddr = 0xaaaa; /* Address for the Fourth Cycle */ - FifthAddr = 0x5555; /* Address for the Fifth Cycle */ - } - WRITE_WORD(FLASH_BASE_ADDRESS + - FirstAddr * FLASH_WIDTH, FirstData); - WRITE_WORD(FLASH_BASE_ADDRESS + - SecondAddr * FLASH_WIDTH, SecondData); - WRITE_WORD(FLASH_BASE_ADDRESS + - ThirdAddr * FLASH_WIDTH, ThirdData); - WRITE_WORD(FLASH_BASE_ADDRESS + - FourthAddr * FLASH_WIDTH, FourthData); - WRITE_WORD(FLASH_BASE_ADDRESS + - FifthAddr * FLASH_WIDTH, FifthData); - WRITE_WORD(FLASH_BASE_ADDRESS + - (sectorBaseAddress & 0xffffff00) * - FLASH_WIDTH, SixthData); - WRITE_WORD(FLASH_BASE_ADDRESS + - FirstAddr * FLASH_WIDTH + 4, FirstData); - WRITE_WORD(FLASH_BASE_ADDRESS + - SecondAddr * FLASH_WIDTH + 4, - SecondData); - WRITE_WORD(FLASH_BASE_ADDRESS + - ThirdAddr * FLASH_WIDTH + 4, ThirdData); - WRITE_WORD(FLASH_BASE_ADDRESS + - FourthAddr * FLASH_WIDTH + 4, - FourthData); - WRITE_WORD(FLASH_BASE_ADDRESS + - FifthAddr * FLASH_WIDTH + 4, FifthData); - WRITE_WORD(FLASH_BASE_ADDRESS + - (sectorBaseAddress & 0xffffff00) - * FLASH_WIDTH + 4, SixthData); - /* Poll on the flash */ - if (FLASH_MODE == X16) { /* 4 devices , 16 bit each => 64bit */ - dataPoll = 0x00800080; - } else { /* (FLASH_MODE = 8) ==> 8 devices , 8 bit each => 64bit */ - - dataPoll = 0x80808080; - } - do { - READ_WORD(FLASH_BASE_ADDRESS + - sectorBaseAddress * FLASH_WIDTH, - ®Value); - } while ((regValue & dataPoll) != dataPoll); - do { - READ_WORD(FLASH_BASE_ADDRESS + - sectorBaseAddress * FLASH_WIDTH + - 4, ®Value); - } while ((regValue & dataPoll) != dataPoll); - break; - default: - return false; - } - } /* End of 'flash erase sector' for AMD/ST */ - else { /* Intel/Micron */ - - switch (FLASH_WIDTH) { - case 1: - WRITE_CHAR(FLASH_BASE_ADDRESS, 0x20); - WRITE_CHAR( - (FLASH_BASE_ADDRESS + - (sectorBaseAddress & 0xffffff00)), - 0xd0); - /* Poll on the flash */ - while (true) { - WRITE_CHAR(FLASH_BASE_ADDRESS, 0x70); - READ_CHAR(FLASH_BASE_ADDRESS, ®Value); - if ((regValue & 0x80) == 0x80) - break; - } - break; - case 2: - if (FLASH_MODE == X16) { /* 1 device 16 bit. */ - data20 = 0x0020;; - dataD0 = 0x00d0;; - } else { /* (FLASH_MODE = 8) ==> 2 devices , 8 bit each => 16bit */ - - data20 = 0x2020; - dataD0 = 0xd0d0; - } - WRITE_SHORT(FLASH_BASE_ADDRESS, data20); - WRITE_SHORT( - (FLASH_BASE_ADDRESS + - ((sectorBaseAddress * 2) & - 0xffffff00)), dataD0); - /* Poll on the flash */ - if (FLASH_MODE == X16) { - dataPoll = 0x0080; - data70 = 0x0070; - } else { /* (FLASH_MODE = 8) */ - - dataPoll = 0x8080; - data70 = 0x7070; - } - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS + - sectorBaseAddress * 2, data70); - READ_SHORT(FLASH_BASE_ADDRESS + - sectorBaseAddress * 2, - ®Value); - if ((regValue & 0x0080) == 0x0080) - break; - } - break; - case 4: - if (FLASH_MODE == X16) { /* 2 devices , 16 bit each => 32bit */ - data20 = 0x00200020; - dataD0 = 0x00d000d0; - } else { /* (FLASH_MODE = 8) ==> 4 devices , 8 bit each => 32bit */ - - data20 = 0x20202020; - dataD0 = 0xd0d0d0d0; - } - WRITE_WORD(FLASH_BASE_ADDRESS, data20); - WRITE_WORD( - (FLASH_BASE_ADDRESS + - ((sectorBaseAddress * 4) & - 0xffffff00)), dataD0); - /* Poll on the flash */ - if (FLASH_MODE == X16) { - dataPoll = 0x0080; - data70 = 0x0070; - } else { /* (FLASH_MODE = 8) */ - - dataPoll = 0x8080; - data70 = 0x7070; - } - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS, data70); - READ_SHORT(FLASH_BASE_ADDRESS, ®Value); - if ((regValue & dataPoll) == dataPoll) - break; - } - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS + 2, - data70); - READ_SHORT(FLASH_BASE_ADDRESS + 2, - ®Value); - if ((regValue & dataPoll) == dataPoll) - break; - } - break; - case 8: - if (FLASH_MODE == X16) { /* 4 devices , 16 bit each => 64bit */ - data20 = 0x00200020; - dataD0 = 0x00d000d0; - } else { /* (FLASH_MODE = 8) ==> 8 devices , 8 bit each => 64bit */ - - data20 = 0x20202020; - dataD0 = 0xd0d0d0d0; - } - WRITE_WORD(FLASH_BASE_ADDRESS, data20); - WRITE_WORD( - (FLASH_BASE_ADDRESS + - ((sectorBaseAddress * 8) & - 0xffffff00)), dataD0); - WRITE_WORD(FLASH_BASE_ADDRESS + 4, data20); - WRITE_WORD( - (FLASH_BASE_ADDRESS + - ((sectorBaseAddress * 8) & 0xffffff00 + - 4)), dataD0); - /* Poll on the flash */ - if (FLASH_MODE == X16) { - dataPoll = 0x0080; - data70 = 0x0070; - } else { /* (FLASH_MODE = 8) */ - - dataPoll = 0x8080; - data70 = 0x7070; - } - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS + - sectorBaseAddress * 8, data70); - READ_SHORT(FLASH_BASE_ADDRESS + - sectorBaseAddress * 8, - ®Value); - if ((regValue & dataPoll) == dataPoll) - break; - } - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS + 2, - data70); - READ_SHORT(FLASH_BASE_ADDRESS + 2, - ®Value); - if ((regValue & dataPoll) == dataPoll) - break; - } - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS + 4, - data70); - READ_SHORT(FLASH_BASE_ADDRESS + 4, - ®Value); - if ((regValue & dataPoll) == dataPoll) - break; - } - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS + 6, - data70); - READ_SHORT(FLASH_BASE_ADDRESS + 6, - ®Value); - if ((regValue & dataPoll) == dataPoll) - break; - } - break; - default: - return false; - } - } - flashReset(); - return true; -} - -/******************************************************************** -* flashWriteWord - Write 32Bit to the FLASH memory at the given offset from the -* FLASH base address. -* address 0 = 0x00000000 !! -* Attention!!! data "0" cannot be programed back to -* "1" (only by first performing an earase operation). -* The function takes care of Big/Little endian conversion -* -* INPUTS: offset - The offset from the flash`s base address. -* data - The data that should be written. -* RETURNS: true on success,false on failure -*********************************************************************/ -bool flashWriteWord(unsigned int offset, unsigned int data) -{ - unsigned char c, rc; - unsigned short s, rs; - register unsigned int rw; - register unsigned int regValue; - register unsigned int FirstAddr, SecondAddr, ThirdAddr; - register unsigned int FirstData, SecondData, ThirdData; - register unsigned int data10, data20, data70, data80; - - if ((flashTypes[POINTER_TO_FLASH] == AMD_FLASH) || \ - (flashTypes[POINTER_TO_FLASH] == ST_FLASH)) { - switch (FLASH_WIDTH) { - case 1: /* Split the 32 bit write into four 8bit Writings */ - if (FLASH_MODE == PURE8) { /* Boot Flash */ - FirstAddr = 0x5555; - SecondAddr = 0x2aaa; - ThirdAddr = 0x5555; - } else { - FirstAddr = 0xaaaa; - SecondAddr = 0x5555; - ThirdAddr = 0xaaaa; - } - WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa); - WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55); - WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0); -#ifdef BE - c = (data >> 24); -#else - c = data; -#endif - WRITE_CHAR(FLASH_BASE_ADDRESS + offset, c); - /* Writing first Byte */ - while (true) { - READ_CHAR(FLASH_BASE_ADDRESS + offset, - &rc); - if ((rc & 0x80) == (c & 0x80)) /* DQ7 =? DATA */ - break; /* DQ7 = DATA */ - if ((rc & 0x20) == 0x20) { /* DQ5 =? '1' */ - READ_CHAR(FLASH_BASE_ADDRESS + - offset, &rc); - if ((rc & 0x80) == (c & 0x80)) - break; /* DQ7 = DATA */ - else - return false; /* DQ7 != DATA */ - } - } - WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa); - WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55); - WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0); -#ifdef BE - c = (data >> 16); -#else - c = (data >> 8); -#endif - WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 1, c); - /* Writing second Byte */ - while (true) { - READ_CHAR(FLASH_BASE_ADDRESS + offset + 1, - &rc); - if ((rc & 0x80) == (c & 0x80)) /* DQ7 =? DATA */ - break; /* DQ7 = DATA */ - if ((rc & 0x20) == 0x20) { /* DQ5 =? '1' */ - READ_CHAR(FLASH_BASE_ADDRESS + - offset + 1, &rc); - if ((rc & 0x80) == (c & 0x80)) - break; /* DQ7 = DATA */ - else - return false; /* DQ7 != DATA */ - } - } - WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa); - WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55); - WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0); -#ifdef BE - c = (data >> 8); -#else - c = (data >> 16); -#endif - WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 2, c); - /* Writing third Byte */ - while (true) { - READ_CHAR(FLASH_BASE_ADDRESS + offset + 2, - &rc); - if ((rc & 0x80) == (c & 0x80)) /* DQ7 =? DATA */ - break; /* DQ7 = DATA */ - if ((rc & 0x20) == 0x20) { /* DQ5 =? '1' */ - READ_CHAR(FLASH_BASE_ADDRESS + - offset + 2, &rc); - if ((rc & 0x80) == (c & 0x80)) - break; /* DQ7 = DATA */ - else - return false; /* DQ7 != DATA */ - } - } - WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa); - WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55); - WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0); -#ifdef BE - c = data; -#else - c = (data >> 24); -#endif - WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 3, c); - /* Writing fourth Byte */ - while (true) { - READ_CHAR(FLASH_BASE_ADDRESS + offset + 3, - &rc); - if ((rc & 0x80) == (c & 0x80)) /* DQ7 =? DATA */ - break; /* DQ7 = DATA */ - if ((rc & 0x20) == 0x20) { /* DQ5 =? '1' */ - READ_CHAR(FLASH_BASE_ADDRESS + - offset + 3, &rc); - if ((rc & 0x80) == (c & 0x80)) - break; /* DQ7 = DATA */ - else - return false; /* DQ7 != DATA */ - } - } - break; - case 2: /* Split the 32 bit write into two 8/16 bit Writings - (16bit width). */ - if (FLASH_MODE == X16) { - FirstData = 0xaa; /* Data for the First Cycle */ - SecondData = 0x55; /* Data for the Second Cycle */ - ThirdData = 0xa0; /* Data for the Third Cycle */ - FirstAddr = 0x5555; /* Address for the First Cycle */ - SecondAddr = 0x2aaa; /* Address for the Second Cycle */ - ThirdAddr = 0x5555; /* Address for the Third Cycle */ - } else { /* if (FLASH_MODE == 8) */ - - FirstData = 0xaaaa; /* Data for the First Cycle */ - SecondData = 0x5555; /* Data for the Second Cycle */ - ThirdData = 0xa0a0; /* Data for the Third Cycle */ - FirstAddr = 0xaaaa; /* Address for the First Cycle */ - SecondAddr = 0x5555; /* Address for the Second Cycle */ - ThirdAddr = 0xaaaa; /* Address for the Third Cycle */ - } - WRITE_SHORT(FLASH_BASE_ADDRESS + - FirstAddr * FLASH_WIDTH, FirstData); - WRITE_SHORT(FLASH_BASE_ADDRESS + - SecondAddr * FLASH_WIDTH, SecondData); - WRITE_SHORT(FLASH_BASE_ADDRESS + - ThirdAddr * FLASH_WIDTH, ThirdData); -#ifdef BE - s = (data >> 16); -#else - s = data; -#endif - WRITE_SHORT(FLASH_BASE_ADDRESS + offset, s); - /* Writing Two Bytes */ - if (FLASH_MODE == X16) { - data80 = 0x80;; - data20 = 0x20;; - } else { /* if (FLASH_MODE == 8) */ - - data80 = 0x8080; - data20 = 0x2020; - } - while (true) { - READ_SHORT(FLASH_BASE_ADDRESS + offset, - &rs); - if ((rs & data80) == (s & data80)) /* DQ7 =? DATA */ - break; /* DQ7 = DATA */ - if ((rs & data20) == data20) { /* DQ5 =? DATA */ - READ_SHORT(FLASH_BASE_ADDRESS + - offset, &rs); - if ((rs & data80) == (s & data80)) - break; /* DQ7 = DATA */ - else { - flashReset(); - return false; /* DQ7 != DATA */ - } - } - } - WRITE_SHORT(FLASH_BASE_ADDRESS + - FirstAddr * FLASH_WIDTH, FirstData); - WRITE_SHORT(FLASH_BASE_ADDRESS + - SecondAddr * FLASH_WIDTH, SecondData); - WRITE_SHORT(FLASH_BASE_ADDRESS + - ThirdAddr * FLASH_WIDTH, ThirdData); -#ifdef BE - s = data; -#else - s = (data >> 16); -#endif - WRITE_SHORT(FLASH_BASE_ADDRESS + offset + 2, s); - /* Writing Two Bytes */ - while (true) { - READ_SHORT(FLASH_BASE_ADDRESS + offset + 2, - &rs); - if ((rs & data80) == (s & data80)) /* DQ7 =? DATA */ - break; /* DQ7 = DATA */ - if ((rs & data20) == data20) { /* DQ5 =? '1' */ - READ_SHORT(FLASH_BASE_ADDRESS + - offset + 2, &rs); - if ((rs & data80) == (s & data80)) - break; /* DQ7 = DATA */ - else { - flashReset(); - return false; /* DQ7 != DATA */ - } - } - } - return true; - case 4: - case 8: - if (FLASH_MODE == X16) { - FirstData = 0x00aa00aa; - SecondData = 0x00550055; - ThirdData = 0x00a000a0; - FirstAddr = 0x5555; - SecondAddr = 0x2aaa; - ThirdAddr = 0x5555; - } else { /* (FLASH_MODE == 8) */ - - FirstData = 0xaaaaaaaa; /* Data for the First Cycle */ - SecondData = 0x55555555; /* Data for the Second Cycle */ - ThirdData = 0xa0a0a0a0; /* Data for the Third Cycle */ - FirstAddr = 0xaaaaaaaa; /* Address for the First Cycle */ - SecondAddr = 0x55555555; /* Address for the Second Cycle */ - ThirdAddr = 0xaaaaaaaa; /* Address for the Third Cycle */ - } - WRITE_WORD(FLASH_BASE_ADDRESS + FirstAddr * - FLASH_WIDTH + offset % FLASH_WIDTH, - FirstData); - WRITE_WORD(FLASH_BASE_ADDRESS + - SecondAddr * FLASH_WIDTH + - offset % FLASH_WIDTH, SecondData); - WRITE_WORD(FLASH_BASE_ADDRESS + - ThirdAddr * FLASH_WIDTH + - offset % FLASH_WIDTH, ThirdData); - /* writting the word. */ - WRITE_WORD(FLASH_BASE_ADDRESS + offset, data); - /* preparing the polling patterns. */ - if (FLASH_MODE == X16) { - data80 = 0x00800080; - data20 = 0x00200020; - } else { /* (FLASH_MODE == 8) */ - - data80 = 0x80808080; - data20 = 0x20202020; - } - while (true) { /* polling loop. */ - rw = READWORD(FLASH_BASE_ADDRESS + offset); - /* DQ7 =? DATA */ - if ((rw & data80) == (data & data80)) - break; /* DQ7 = DATA */ - if ((rw & data20) == data20) { /* DQ5 =? '1' */ - rw = - READWORD(FLASH_BASE_ADDRESS + - offset); - if ((rw & data80) == - (data & data80)) break; /* DQ7 = DATA */ - else - return false; /* DQ7 != DATA */ - } - } - return true; - default: - return false; /* case of invalid flash Width. */ - } - } else { /* Intel/Micron */ - - switch (FLASH_WIDTH) { - case 1: - /* Writing First Byte */ - WRITE_CHAR(FLASH_BASE_ADDRESS, 0x10); -#ifdef BE - c = (data >> 24); -#else - c = data; -#endif - WRITE_CHAR(FLASH_BASE_ADDRESS + offset, c); - while (true) { - /* Reading STATUS Register */ - WRITE_CHAR(FLASH_BASE_ADDRESS, 0x70); - regValue = READCHAR(FLASH_BASE_ADDRESS); - if ((regValue & 0x80) == 0x80) - break; /* Case of Write-Operation had Ended */ - } - /* Reading STATUS Register for Writing Verification */ - WRITE_CHAR(FLASH_BASE_ADDRESS, 0x70); - regValue = READCHAR(FLASH_BASE_ADDRESS); - if ((regValue & 0x10) == 0x10) - return false; /* Write failure */ - - /* Writing Second Byte */ - WRITE_CHAR(FLASH_BASE_ADDRESS + 1, 0x10); -#ifdef BE - c = (data >> 16); -#else - c = (data >> 8); -#endif - WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 1, c); - while (true) { - /* Reading STATUS Register */ - WRITE_CHAR(FLASH_BASE_ADDRESS + 1, 0x70); - regValue = - READCHAR(FLASH_BASE_ADDRESS + 1); - if ((regValue & 0x80) == 0x80) - break; /* Write operation ended */ - } - /* Reading STATUS Register for Writing verification */ - WRITE_CHAR(FLASH_BASE_ADDRESS + 1, 0x70); - regValue = READCHAR(FLASH_BASE_ADDRESS + 1); - if ((regValue & 0x10) == 0x10) - return false; /* Write failure */ - - /* Writing Third Byte */ - WRITE_CHAR(FLASH_BASE_ADDRESS + 2, 0x10); -#ifdef BE - c = (data >> 8); -#else - c = (data >> 16); -#endif - WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 2, c); - while (true) { - /* Reading STATUS Register */ - WRITE_CHAR(FLASH_BASE_ADDRESS + 2, 0x70); - regValue = - READCHAR(FLASH_BASE_ADDRESS + 2); - if ((regValue & 0x80) == 0x80) - break; /* Write operation ended */ - } - /* Reading STATUS Register for Writing Verification */ - WRITE_CHAR(FLASH_BASE_ADDRESS + 2, 0x70); - regValue = READCHAR(FLASH_BASE_ADDRESS + 2); - if ((regValue & 0x10) == 0x10) - return false; /* Write failure */ - - /* Writing Fourth Byte */ - WRITE_CHAR(FLASH_BASE_ADDRESS + 3, 0x10); -#ifdef BE - c = data; -#else - c = (data >> 24); -#endif - WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 3, c); - while (true) { - /* Reading STATUS Register */ - WRITE_CHAR(FLASH_BASE_ADDRESS + 3, 0x70); - regValue = - READCHAR(FLASH_BASE_ADDRESS + 3); - if ((regValue & 0x80) == 0x80) - break; /* Write operation ended */ - } - /* Reading STATUS Register for Writing Verification */ - WRITE_CHAR(FLASH_BASE_ADDRESS + 3, 0x70); - regValue = READCHAR(FLASH_BASE_ADDRESS + 3); - if ((regValue & 0x10) == 0x10) - return false; /* Write failure */ - flashReset(); - return true; - case 2: - if (FLASH_MODE == X16) { /* Case of one X16 bit device */ - FirstData = 0x0010; /* Data for the First Cycle */ - } else { /* if (FLASH_MODE == 8) ==> Case of two X8 bit devices */ - - FirstData = 0x1010; /* Data for the First Cycle */ - } - /* Writing First two Bytes */ - WRITE_SHORT(FLASH_BASE_ADDRESS, FirstData); -#ifdef BE - s = (data >> 16); -#else - s = data; -#endif - WRITE_SHORT(FLASH_BASE_ADDRESS + offset, s); - if (FLASH_MODE == X16) { - data70 = 0x0070; - data80 = 0x0080; - data10 = 0x0010; - } else { /* case of (FLASH_MODE == X8) */ - - data70 = 0x7070; - data80 = 0x8080; - data10 = 0x1010; - } - /* polling on writing action => when done break. */ - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS, data70); - regValue = READSHORT(FLASH_BASE_ADDRESS); - if ((regValue & data80) == data80) - break; - } - /* Reading STATUS Register for Writing Verification */ - WRITE_CHAR(FLASH_BASE_ADDRESS, data70); - regValue = READCHAR(FLASH_BASE_ADDRESS); - if ((regValue & data10) == data10) - return false; /* Write failure */ - /* Writing Last two Bytes */ - WRITE_SHORT(FLASH_BASE_ADDRESS + 2, FirstData); -#ifdef BE - s = data; -#else - s = (data >> 16); -#endif - WRITE_SHORT(FLASH_BASE_ADDRESS + offset + 2, s); - /* polling on writing action => when done break. */ - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS + 2, - data70); - regValue = - READSHORT(FLASH_BASE_ADDRESS + 2); - if ((regValue & data80) == data80) - break; - } - /* Reading STATUS Register for Writing Verification */ - WRITE_CHAR(FLASH_BASE_ADDRESS, data70); - regValue = READCHAR(FLASH_BASE_ADDRESS); - if ((regValue & data10) == data10) - return false; /* Write failure */ - flashReset(); - return true; - case 4: - case 8: - if (FLASH_MODE == X16) { /* Case of one X16 bit device */ - FirstData = 0x00100010; /* Data for the First Cycle */ - } else { /* (FLASH_MODE == 8) ==> Case of two X8 bit devices */ - - FirstData = 0x10101010; /* Data for the First Cycle */ - } - /* Writing First two Bytes */ - WRITE_WORD(FLASH_BASE_ADDRESS + - offset % FLASH_WIDTH, FirstData); -#ifdef BE - s = (data >> 16); -#else - s = data; -#endif - /* writing the 32-bit data to flash. */ - WRITE_WORD(FLASH_BASE_ADDRESS + offset, data); - if (FLASH_MODE == X16) { - data70 = 0x0070; - data80 = 0x0080; - data10 = 0x0010; - } else { /* (FLASH_MODE == 8) */ - - data70 = 0x7070; - data80 = 0x8080; - data10 = 0x1010; - } - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS + - offset % FLASH_WIDTH, data70); - regValue = READSHORT(FLASH_BASE_ADDRESS); - if ((regValue & data80) == data80) - break; - } - /* Reading STATUS Register for Writing Verification */ - WRITE_CHAR(FLASH_BASE_ADDRESS, data70); - regValue = READCHAR(FLASH_BASE_ADDRESS); - if ((regValue & data10) == data10) - return false; /* Write failure */ - - /* Writing Last two Bytes */ -#ifdef BE - s = data; -#else - s = (data >> 16); -#endif - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS + - offset % FLASH_WIDTH + 2, - data70); - regValue = - READSHORT(FLASH_BASE_ADDRESS + - offset % FLASH_WIDTH + 2); - if ((regValue & data80) == data80) - break; - } - /* Reading STATUS Register for Writing Verification */ - WRITE_CHAR(FLASH_BASE_ADDRESS, data70); - regValue = READCHAR(FLASH_BASE_ADDRESS); - if ((regValue & data10) == data10) - return false; /* Write failure */ - - flashReset(); - return true; - default: - flashReset(); - return false; - } - } - flashReset(); - return true; -} - -/******************************************************************** -* flashReadWord - Read 32Bit from the FLASH memory at a given offset -* from the FLASH base address. -* address 0 = 0x00000000 !! -* The function takes care of Big/Little endian conversion -* INPUTS: offset,the offset from the flash`s base address -* RETURNS: data -*********************************************************************/ -unsigned int flashReadWord(unsigned int offset) -{ - unsigned int regValue; - flashReset(); - READ_WORD(FLASH_BASE_ADDRESS + offset, ®Value); - return regValue; -} - -/******************************************************************** -* flashInWhichSector - Returns the sector`s number at which offset is at. -* -* INPUTS: Offset -* RETURNS: Sector number,or 0xffffffff in case the address is out of range or -* flash wasn't initialize. -*********************************************************************/ -unsigned int flashInWhichSector(unsigned int offset) -{ - unsigned int sectorNumber, numberOfDevices; - unsigned int accMemory = 0; - - if ((FLASH_MODE == PURE8) || (FLASH_MODE == X8)) { - numberOfDevices = FLASH_WIDTH; - } else { /* X16 mode */ - - numberOfDevices = FLASH_WIDTH / 2; - } - for (sectorNumber = 0; - sectorNumber < flashTypes[NUMBER_OF_SECTORS]; sectorNumber++) { - accMemory = - accMemory + flashTypes[FIRST_SECTOR_SIZE + - sectorNumber]; - if (offset < accMemory * numberOfDevices * 1024) - return sectorNumber; - } - return 0xffffffff; -} - -/******************************************************************** -* flashGetSectorSize - When given a Valid sector Number returns its Size. -* -* INPUTS: unsigned int sectorNumber. -* RETURNS: Sector size. (if Sector number isn't valid or flash wasn't -* initialize return 0.) -*********************************************************************/ -unsigned int flashGetSectorSize(unsigned int sectorNumber) -{ - if (sectorNumber >= flashTypes[NUMBER_OF_SECTORS]) - return 0; - else { - if (FLASH_MODE != PURE8) - return (flashTypes - [FIRST_SECTOR_SIZE + - sectorNumber] * _1K * (FLASH_WIDTH * 8 / - FLASH_MODE)); - else /* in case of PUR8 */ - return (flashTypes - [FIRST_SECTOR_SIZE + - sectorNumber] * _1K * FLASH_WIDTH); - } -} - -/******************************************************************** -* getFlashSize - Return Total flash size. -* -* INPUTS: N/A. -* RETURNS: Flash size. (If flash wasn't initialize return 0) -*********************************************************************/ -unsigned int flashGetSize() -{ - unsigned int sectorNum; - unsigned int totalSize = 0; - - if (POINTER_TO_FLASH == 0) - return 0; /* case of flash not initialize */ - for (sectorNum = 0; sectorNum < flashTypes[NUMBER_OF_SECTORS]; - sectorNum++) { - totalSize += flashGetSectorSize(sectorNum); - } - return (totalSize); - -} - -/******************************************************************** -* flashGetSectorOffset - Returns sector base address. -* -* INPUTS: unsigned int sectorNum. -* RETURNS: Sector Base Address. -*********************************************************************/ -unsigned int flashGetSectorOffset(unsigned int sectorNum) -{ - unsigned int i; - unsigned int sectorBaseAddress = 0; - unsigned int numOfDevices; - - if (sectorNum > (flashParametrs[NUMBER_OF_SECTORS] - 1)) - return 0xffffffff; - for (i = 0; i < sectorNum; i++) { - sectorBaseAddress = - sectorBaseAddress + flashTypes[FIRST_SECTOR_SIZE + i]; - } - if (FLASH_MODE == X16) - numOfDevices = FLASH_WIDTH * 8 / FLASH_MODE; - else - numOfDevices = FLASH_WIDTH; - return (_1K * sectorBaseAddress * numOfDevices); - -} - -/******************************************************************** -* flashWriteBlock - Write block of chars to flash. -* -* INPUTS: unsigned int offset - flash destination address. -* unsigned int numOfByte - block size. -* unsigned char * blockAddress - block source address. -* RETURNS: Number of Bytes written. -*********************************************************************/ -unsigned int flashWriteBlock(unsigned int offset, unsigned int numOfByte, - unsigned char *blockAddress) -{ - register unsigned int flashWrite; - register unsigned int align; - register unsigned int num; - register unsigned int i; - - if ((offset + numOfByte) > flashGetSize()) - numOfByte = flashGetSize() - offset; /* getting to flash boundary. */ - num = numOfByte; - align = offset % 4; /* alignment toward flash. */ - /* writes chars until the offset toward flash will be align. */ - for (i = align; (i < 4) && (numOfByte > 0) && (align != 0); i++) { - flashWriteChar(offset, blockAddress[0]); - numOfByte--; - offset++; - blockAddress++; - } - while (numOfByte > 3) { -#ifdef LE - flashWrite = blockAddress[0] | (blockAddress[1] << 8) | - (blockAddress[2] << 16) | (blockAddress[3] << 24); -#else - flashWrite = blockAddress[3] | (blockAddress[2] << 8) | - (blockAddress[1] << 16) | (blockAddress[0] << 24); -#endif - if (flashWrite != 0xffffffff) /* for optimization. */ - flashWriteWord(offset, flashWrite); - numOfByte -= 4; - blockAddress += 4; - offset += 4; - } - while (numOfByte > 0) { - flashWriteChar(offset, blockAddress[0]); - numOfByte--; - blockAddress++; - offset++; - } - return num; -} - -/******************************************************************** -* flashReadBlock - Read block of chars from flash. -* -* INPUTS: unsigned int offset - flash source address. -* unsigned int numOfByte - block size. -* unsigned char * blockAddress - block destination address. -* RETURNS: Number of Bytes written. -*********************************************************************/ -unsigned int flashReadBlock(unsigned int offset, unsigned int numOfByte, - unsigned char *blockAddress) -{ - unsigned int i; - for (i = 0; i < numOfByte; i++) { - blockAddress[i] = flashReadChar(offset + i); - } - return numOfByte; -} - -/******************************************************************** -* flashReadChar - read one charecter form given flash offset. -* -* INPUTS: unsigned int offset - required offset to be read from. -* RETURNS: read charecter. -*********************************************************************/ -unsigned char flashReadChar(unsigned int offset) -{ - unsigned char regValue; - - flashReset(); - READ_CHAR(FLASH_BASE_ADDRESS + offset, ®Value); - return regValue; -} - -/******************************************************************** -* flashReadShort - read 16bit form given flash offset. -* -* INPUTS: unsigned int offset - required offset to be read from. -* RETURNS: 16bit data. -*********************************************************************/ -unsigned short flashReadShort(unsigned int offset) -{ - unsigned short regValue; - - flashReset(); - READ_SHORT(FLASH_BASE_ADDRESS + offset, ®Value); - return regValue; -} - -/******************************************************************** -* flashWriteShort - write 16bit data to a given flash offset. -* It reads the whole word 32bit wide, modify the short -* and write back the word. -* -* INPUTS: unsigned int offset - required offset to be write to. -* unsigned short sdata - data to be written. -* RETURNS: true if writting successesed false otherwise. -*********************************************************************/ -bool flashWriteShort(unsigned int offset, unsigned short sdata) -{ - unsigned int align; - unsigned int flashWrite; - unsigned int flashRead; - - align = offset % 4; - if ((align == 1) || (align == 3)) - return false; /* offset misaligned. */ - flashRead = flashReadWord(offset - align); - if (align == 0) -#ifdef BE - flashWrite = (flashRead & 0x0000ffff) | (sdata << 16); -#else - flashWrite = (flashRead & 0xffff0000) | sdata; -#endif - else /* (align == 2) */ -#ifdef BE - flashWrite = (flashRead & 0xffff0000) | sdata; -#else - flashWrite = (flashRead & 0x0000ffff) | (sdata << 16); -#endif - flashWriteWord(offset - align, flashWrite); - return true; - -} - -/******************************************************************** -* flashWriteChar - write one charecter (8 bit) to a given flash offset. -* It reads the whole word 32bit wide, modify the charecter -* and write back the word. -* -* INPUTS: unsigned int offset - required offset to be write to. -* unsigned short sdata - data to be written. -* RETURNS: true if writting successed. -*********************************************************************/ -bool flashWriteChar(unsigned int offset, unsigned char cdata) -{ - unsigned int align; - unsigned int flashWrite; - unsigned int flashRead; - - align = offset % 4; - flashRead = flashReadWord(offset - align); -#ifdef BE - flashWrite = (flashRead & ~(0xff000000 >> (8 * align))) | - (cdata << (8 * (3 - align))); -#else - flashWrite = (flashRead & ~(0xff000000 << (8 * align))) | - (cdata << (8 * align)); -#endif - flashWriteWord(offset - align, flashWrite); - return true; -} - -/******************************************************************** -* flashGetNumOfSectors - write one charecter (8 bit) to a given flash offset. -* It reads the whole word 32bit wide, modify the -* charecter and write back the word. -* -* INPUTS: N/A. -* RETURNS: Number of sectors. -*********************************************************************/ -unsigned int flashGetNumOfSectors(void) -{ - return (flashTypes[NUMBER_OF_SECTORS]); -} Index: arch/mips/galileo-boards/ev64120/compressed/galileo_port.h =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/galileo_port.h diff -N arch/mips/galileo-boards/ev64120/compressed/galileo_port.h --- arch/mips/galileo-boards/ev64120/compressed/galileo_port.h 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,8 +0,0 @@ -#define GFP_KERNEL 0 -#define GFP_ATOMIC 1 -#define KERN_ERR "" - -void *kmalloc(unsigned int, int); -void *memset(void *, char, unsigned int); -int memcmp(char *, char *, unsigned int); -void *memcpy(void *to, const void *from, unsigned int); Index: arch/mips/galileo-boards/ev64120/compressed/gt64011.h =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/gt64011.h diff -N arch/mips/galileo-boards/ev64120/compressed/gt64011.h --- arch/mips/galileo-boards/ev64120/compressed/gt64011.h 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,279 +0,0 @@ -/* - * gt64011.h: Galileo PCI system controller - * Copyright (c) 1998 Algorithmics Ltd - */ - -#ifdef __ASSEMBLY__ - -/* offsets from base register */ -#define GT64011(x) (x) - -/* device is littleendian, so data may need to be swapped */ -#ifdef GALILEO_PORT -#define htoll(x) ((((x) & 0x00ff) << 24) | \ - (((x) & 0xff00) << 8) | \ - (((x) >> 8) & 0xff00) | \ - (((x) >> 24) & 0x00ff)) -/*#define ltohl(x) htoll(x)*/ -#else -#define htoll(x) (x) -/* #define ltohl(x) (x) */ -#endif - -#else /* !__ASSEMBLY__ */ - -/* offsets from base pointer, this construct allows optimisation */ -static char *const _gt64011p = (char *) PA_TO_KVA1(GT64011_BASE); - -#define GT64011(x) *(volatile unsigned long *)(_gt64011p + (x)) - -/* device is littleendian, so data may need to be swapped */ -#ifdef GALILEO_PORT -#define htoll(x) ({ \ - unsigned int v = (unsigned int)(x); \ - v = (((v & 0x00ff) << 24) | \ - ((v & 0xff00) << 8) | \ - ((v >> 8) & 0xff00) | \ - ((v >> 24) & 0x00ff)); \ - v; \ - }) -#define ltohl(x) htoll(x) - -#else -asjdsajd -#define htoll(x) (x) -#define ltohl(x) (x) -#endif -#endif /* __ASSEMBLY__ */ -/* CPU configuration */ -#define GT_CPU_CFG GT64011(0x000) -#define GT_CPU_CFG_WriteMode (1<<11) -#define GT_CPU_CFG_Endianess (1<<12) -/* Processor Address Space */ -#define GT_PAS_RAS10LO GT64011(0x008) -#define GT_PAS_RAS10HI GT64011(0x010) -#define GT_PAS_RAS32LO GT64011(0x018) -#define GT_PAS_RAS32HI GT64011(0x020) -#define GT_PAS_CS20LO GT64011(0x028) -#define GT_PAS_CS20HI GT64011(0x030) -#define GT_PAS_CS3BOOTLO GT64011(0x038) -#define GT_PAS_CS3BOOTHI GT64011(0x040) -#define GT_PAS_PCIIOLO GT64011(0x048) -#define GT_PAS_PCIIOHI GT64011(0x050) -#define GT_PAS_PCIMEMLO GT64011(0x058) -#define GT_PAS_PCIMEMHI GT64011(0x060) -#define GT_PAS_INTDEC GT64011(0x068) -#define GT_PAS_BUSERRLO GT64011(0x070) -#define GT_PAS_PCIMEM1LO GT64011(0x080) -#define GT_PAS_PCIMEM1HI GT64011(0x088) -#define GT_PAS_LOMASK_Low 0x7ff -#define GT_PAS_LOSHIFT_Low 0 -#define GT_PAS_HIMASK_High 0x07f -#define GT_PAS_HISHIFT_High 0 -/* DRAM and Device Address Space */ -#define GT_DDAS_RAS0LO GT64011(0x400) -#define GT_DDAS_RAS0HI GT64011(0x404) -#define GT_DDAS_RAS1LO GT64011(0x408) -#define GT_DDAS_RAS1HI GT64011(0x40c) -#define GT_DDAS_RAS2LO GT64011(0x410) -#define GT_DDAS_RAS2HI GT64011(0x414) -#define GT_DDAS_RAS3LO GT64011(0x418) -#define GT_DDAS_RAS3HI GT64011(0x41c) -#define GT_DDAS_CS0LO GT64011(0x420) -#define GT_DDAS_CS0HI GT64011(0x424) -#define GT_DDAS_CS1LO GT64011(0x428) -#define GT_DDAS_CS1HI GT64011(0x42c) -#define GT_DDAS_CS2LO GT64011(0x430) -#define GT_DDAS_CS2HI GT64011(0x434) -#define GT_DDAS_CS3LO GT64011(0x438) -#define GT_DDAS_CS3HI GT64011(0x43c) -#define GT_DDAS_BOOTCSLO GT64011(0x440) -#define GT_DDAS_BOOTCSHI GT64011(0x444) -#define GT_DDAS_ERROR GT64011(0x470) -#define GT_DDAS_LOMASK_Low 0xff -#define GT_DDAS_LOSHIFT_Low 0 -#define GT_DDAS_HIMASK_High 0xff -#define GT_DDAS_HISHIFT_High 0 -/* DRAM Configuration */ -#define GT_DRAM_CFG GT64011(0x448) -#define GT_DRAM_CFG_RefIntCntMASK 0x00003fff -#define GT_DRAM_CFG_RefIntCntSHIFT 0 -#define GT_DRAM_CFG_RefIntCnt(x) (((x)< -#include - - .text -NESTED(startup, 16, sp) - .set noreorder - - jal decompress_kernel - nop - - jal kernel_location_start+0x584 - nop - - END(startup) Index: arch/mips/galileo-boards/ev64120/compressed/ld.script.gal =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/ld.script.gal diff -N arch/mips/galileo-boards/ev64120/compressed/ld.script.gal --- arch/mips/galileo-boards/ev64120/compressed/ld.script.gal 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,19 +0,0 @@ -OUTPUT_FORMAT("elf32-bigmips") -OUTPUT_ARCH(mips) -ENTRY(startup) -SECTIONS -{ - kernel_location_start = 0x80100000; - . = 0x80400000; - .text : { - *(.text) - } - .bss : { - *(.bss) - } - .data :{ - *(.data) - } - malloc_start = .; -} - Index: arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash diff -N arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash --- arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,29 +0,0 @@ -OUTPUT_FORMAT("elf32-bigmips") -OUTPUT_ARCH(mips) -ENTRY(sbdreset) - -SECTIONS -{ - . = 0xBFC00000; - .got : {*(.got)} - .reset : { - sbdreset = ABSOLUTE(.); - sbdreset_evb64120A.o - evb64120A_Setup.o /* <-- Note: contains xfer.c contents as well.. */ - pci_etherboot.o - memory.o - pci.o - } - kernel_location_start = 0x80100000; - . = 0x80400000; - .text : { - *(.text) - } - .bss : { - *(.bss) - } - .data :{ - *(.data) - } - malloc_start = .; -} Index: arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2 =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2 diff -N arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2 --- arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,24 +0,0 @@ -OUTPUT_FORMAT("elf32-bigmips") -OUTPUT_ARCH(mips) -ENTRY(XferToRam) - -SECTIONS -{ - . = 0xBF000000; - .got : {*(.got)} - .reset : { - xfer.o - } - kernel_location_start = 0x80100000; - . = 0x80400000; - .text : { - *(.text) - } - .bss : { - *(.bss) - } - .data :{ - *(.data) - } - malloc_start = .; -} Index: arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.burner =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.burner diff -N arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.burner --- arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.burner 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,11 +0,0 @@ -OUTPUT_FORMAT("elf32-bigmips") -OUTPUT_ARCH(mips) -ENTRY(main) - -SECTIONS -{ - . = 0xA0400000; - .text : {*(.text)} - .data : {*(.data)} - .bss : {*(.bss)} -} Index: arch/mips/galileo-boards/ev64120/compressed/load.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/load.c diff -N arch/mips/galileo-boards/ev64120/compressed/load.c --- arch/mips/galileo-boards/ev64120/compressed/load.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,244 +0,0 @@ - -/* control character used for download */ -#define ETX CNTRL('c') -#define ACK CNTRL('f') -#define NAK CNTRL('u') -#define XON CNTRL('q') -#define XOFF CNTRL('s') - -unsigned int csum; -unsigned int dl_entry; - -static const unsigned char hextab[256] = { - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, - 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, - 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, - 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, -}; - - -unsigned char ascii_to_bin(unsigned char c) -{ - return hextab[c]; -} - -unsigned char read_char_direct(void) -{ - unsigned char c, *cp; - cp = (unsigned char *) 0xbd000020; - while (1) { - if (*(cp + 0x14) & 0x01) { - c = (volatile unsigned char) *cp; - return c; - } - cp++; - cp--; - } -} - -unsigned char get_pair(void) -{ - unsigned char byte; - - byte = ascii_to_bin(read_char_direct()) << 4; - byte |= ascii_to_bin(read_char_direct()); - csum += byte; - return (byte); -} - - -void serial_putc(int ch) -{ - unsigned long temp; - for (temp = 0; temp < 1000; temp++) { - } - *(char *) 0xbd000020 = (char) ch; -} - - -int inline serial_getc(void) -{ - return read_char_direct(); -} - -int serial_ischar(void) -{ - - unsigned char c, *cp; - unsigned count; - cp = (unsigned char *) 0xbd000020; - count = 0; - while (count != 100) { - if (*(cp + 0x14) & 0x01) { - c = (volatile unsigned char) *cp; - return c; - } - cp++; - cp--; - count++; - } - return 0; -} - -int serial_init(void) -{ - return 0; -} - - -int galileo_dl(void) -{ -#define display_char '.' -#define display_error 'E' -#define display_error_bad_7 '7' -#define display_error_unknown 'U' -#define display_error_length 'L' - - register int length, address, save_csum; - int i, first, done, eof, reccount, type, client_pc; - int src, dbl_length; - unsigned char *buffptr, databuff[258], tempo; - register int display_counter, chunks, leftovers, putter, - bytes_per_chunk; - display_counter = 0; - bytes_per_chunk = 16; - csum = 0; - - reccount = 1; - for (first = 1, done = 0; !done; first = 0, reccount++) { - while (read_char_direct() != 'S') - continue; - csum = 0; - type = read_char_direct(); - length = get_pair(); - if (length < 0 || length >= 256) { - *(char *) 0xbd000020 = display_error_length; - // *(char*)0xbd00000c = display_error_length; - return 0; - } - length--; - switch (type) { - case '0': - while (length-- > 0) - get_pair(); - break; - case '3': - address = 0; - for (i = 0; i < 4; i++) { - address <<= 8; - address |= get_pair(); - length--; - } - if (address == -1) { - eof = 1; - continue; - } - buffptr = &databuff[0]; - dbl_length = length << 1; - chunks = dbl_length / bytes_per_chunk; - leftovers = dbl_length % bytes_per_chunk; - putter = bytes_per_chunk >> 1; - while (chunks--) { - for (i = 0; i < bytes_per_chunk; i++) - databuff[i] = read_char_direct(); - src = i = 0; - while (i++ < putter) { - tempo = - (ascii_to_bin(databuff[src++]) - << 4) | - ascii_to_bin(databuff[src++]); - csum += tempo; - *(char *) address++ = tempo; - } - } - if (leftovers) { - putter = leftovers / 2; - for (i = 0; i < leftovers; i++) - databuff[i] = read_char_direct(); - src = i = 0; - while (i++ < putter) { - tempo = - (ascii_to_bin(databuff[src++]) - << 4) | - ascii_to_bin(databuff[src++]); - csum += tempo; - *(char *) address++ = tempo; - } - } - break; - - case '7': - address = 0; - for (i = 0; i < 4; i++) { - address <<= 8; - address |= get_pair(); - length--; - } - if (address == -1) { - eof = 1; - continue; - } - client_pc = address; - if (length) { - *(char *) 0xbd000020 = display_error_bad_7; - // *(char*)0xbd00000c = display_error_bad_7; - } - - done = 1; - break; - - default: - *(char *) 0xbd000020 = display_error_unknown; - // *(char*)0xbd00000c = display_error_unknown; - - break; - } - save_csum = (~csum) & 0xff; - if ((csum = get_pair()) < 0) { - eof = 1; - continue; - } - if (csum != save_csum) { - *(char *) 0xbd000020 = display_error; - // *(char*)0xbd00000c = display_error; - } else { - - if (display_counter % 50 == 0) { - *(char *) 0xbd000020 = display_char; - display_counter = 0; - } - display_counter++; - - } - } - --reccount; - dl_entry = client_pc; - return dl_entry; /* Success */ -} Index: arch/mips/galileo-boards/ev64120/compressed/meminit.S =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/meminit.S diff -N arch/mips/galileo-boards/ev64120/compressed/meminit.S --- arch/mips/galileo-boards/ev64120/compressed/meminit.S 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,187 +0,0 @@ -/* - * Define BUSWIDTH to usually be real buswidth X 2 (i.e assuming - * 2-way interleaving). This is so that the test pattern and - * inverted pattern are written to the same bank of memory, which - * prevents us reading back data sitting in the dram buffers and - * getting a false match. - */ - -#ifndef BUSWIDTH -# if #cpu(r3000) || #cpu(r4300) || #cpu(r4650) -# define BUSWIDTH 8 /* 32 bit memory, bank interleaved */ -# elif #cpu(r4000) -# define BUSWIDTH 16 /* 64 bit memory, bank interleaved */ -# endif -#endif - -#ifndef RAM_BASE -#define RAM_BASE KSEG1_BASE -#endif - -#ifndef MEMSTART -#define MEMSTART 0x0 /* start of physical memory */ -#endif - -#ifndef MEMINCR -# define MEMINCR 0x10000 /* work up in 64Kb increments */ -#endif - -SLEAF(size_mem) - mfc0 t8,C0_STATUS -#if #cpu(r4000) - /* disable cache and memory parity checking */ - or t0,t8,SR_DE - mtc0 t0,C0_STATUS -#endif - - li t0,RAM_BASE+MEMSTART # start at bottom of phys mem - move t1,t0 # remember start address - li t2,0xaa55aa55 # pattern - not t3,t2 # ~pattern - - move t7,k0 - la t4,.fail # bus error exception catcher - addu k0,t4,s8 # RELOC - - /* fill first 64Kb with zero (for cache init) */ - move t4,t0 - li t5,0x10000 -1: sw zero,0(t4) - sw zero,4(t4) - sw zero,8(t4) - sw zero,12(t4) - subu t5,16 - addu t4,16 - bnez t5,1b - -.loop: - addu t0,MEMINCR - move t4,t0 - - /* store pattern in bank 0, line 0 */ - sw t2,0(t4) - addu t4,4 - -#if BUSWIDTH > 4 - /* fill remainder of line with zeros */ - li t5,BUSWIDTH-4 -1: sw zero,0(t4) - subu t5,4 - addu t4,4 - bnez t5,1b -#endif - - /* store inverse pattern in bank 0, line 1 */ - sw t3,0(t4) - addu t4,4 - -#if BUSWIDTH > 4 - /* fill remainder of line with zeros */ - li t5,BUSWIDTH-4 -1: sw zero,0(t4) - subu t5,4 - addu t4,4 - bnez t5,1b -#endif - - /* defeat write buffering */ -#if #cpu(r4000) - sync -#else - lw zero,-4(t4) -#endif - - lw t4,0(t0) # read first word of line - lw t5,0(t1) # read start of memory (should be zero) - bne t4,t2,.fail # this line wrong? - beq t5,zero,.loop # start of mem overwritten? - -.fail: - move k0,t7 # clear exception catcher - - /* restore Status register */ - mtc0 t8,C0_STATUS - - /* return top of memory offset (normally == size) */ - subu v0,t0,RAM_BASE - j ra -END(size_mem) - - -/* - * We must often initialise memory so that it has good parity/ecc, - * and this must be done before the caches are used. - */ - -/* - clear_mem (size) - - clear memory from RAM_BASE+MEMSTART to RAM_BASE+MEMSTART+size - clear_mem_range (size, start) - - clear memory from start to start+size -*/ - -SLEAF(clear_mem) - li a1,RAM_BASE+MEMSTART # start at bottom of phys mem -clear_mem_range: - beqz a0,9f - addu a0,a1 # end of memory - - /* XXX should run cached, but caches may not be initialised yet */ - .set noreorder -#if __mips >= 3 -1: sd zero,0(a1) - sd zero,8(a1) - sd zero,16(a1) - sd zero,24(a1) - sd zero,32(a1) - sd zero,40(a1) - sd zero,48(a1) - addu a1,64 - bne a1,a0,1b - sd zero,-8(a1) # BDSLOT -#else -1: sw zero,0(a1) - sw zero,4(a1) - sw zero,8(a1) - sw zero,12(a1) - sw zero,16(a1) - sw zero,20(a1) - sw zero,24(a1) - sw zero,28(a1) - sw zero,32(a1) - sw zero,36(a1) - sw zero,40(a1) - sw zero,44(a1) - sw zero,48(a1) - sw zero,52(a1) - sw zero,56(a1) - addu a1,64 - bne a1,a0,1b - sw zero,-4(a1) # BDSLOT -#endif - .set reorder - -9: j ra -END(clear_mem) - - -SLEAF(init_tlb) - /* initialise tlb */ - mtc0 zero,C0_TLBLO0 /* tlblo0 = invalid */ - mtc0 zero,C0_TLBLO1 /* tlblo1 = invalid */ - mtc0 zero,C0_PGMASK - li t8,K1BASE /* tlbhi = impossible vpn */ - li t9,(NTLBENTRIES-1) /* index */ - - .set noreorder - nop -1: mtc0 t8,C0_TLBHI - mtc0 t9,C0_INX - addu t8,0x2000 /* inc vpn */ - tlbwi - bnez t9,1b - subu t9,1 # BDSLOT - .set reorder - - j ra -END(init_tlb) Index: arch/mips/galileo-boards/ev64120/compressed/memory.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/memory.c diff -N arch/mips/galileo-boards/ev64120/compressed/memory.c --- arch/mips/galileo-boards/ev64120/compressed/memory.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,593 +0,0 @@ -/* Memory.c - Memory mappings and remapping functions */ - -/* Copyright - Galileo technology. */ - -/* -DESCRIPTION -This file contains function which gives the user the ability to remap the -SDRAM memory and devices windows, please pay attention to overlapping windows -since the function do not take care of that for you. -When remapping the SDRAM or devices memory space pay attention to the PCI -mappings and make sure to coordinate between the two interfaces!!! -*/ - -/* includes */ - -#ifdef __linux__ -#include -#include -#else -#include "Core.h" -#include "Memory.h" -#endif - -/******************************************************************** -* getMemoryBankBaseAddress - Extract the base address of a memory bank -* - If the memory bank size is 0 then this base address has no meaning !!! -* -* INPUTS: MEMORY_BANK bank - SDRAM Bank number. -* OUTPUT: N/A -* RETURNS: Memory bank base address. -*********************************************************************/ -unsigned int getMemoryBankBaseAddress(MEMORY_BANK bank) -{ - unsigned int base, regBase; - GT_REG_READ((SCS_1_0_LOW_DECODE_ADDRESS + (bank / 2) * 0x10), - &base); - base = base << 21; - GT_REG_READ((SCS_0_LOW_DECODE_ADDRESS + bank * 8), ®Base); - base = base | (regBase << 20); - return base; -} - -/******************************************************************** -* getDeviceBaseAddress - Extract the base address of a device. -* - If the device size is 0 then this base address has no meaning!!! -* -* INPUT: DEVICE device - Bank number. -* OUTPUT: N/A -* RETURNS: Device base address. -*********************************************************************/ -unsigned int getDeviceBaseAddress(DEVICE device) -{ - unsigned int base, regBase; - GT_REG_READ((CS_2_0_LOW_DECODE_ADDRESS + (device / 3) * 0x10), - &base); - base = base << 21; - GT_REG_READ((CS_0_LOW_DECODE_ADDRESS + device * 0x8), ®Base); - base = base | (regBase << 20); - return base; -} - -/******************************************************************** -* getMemoryBankSize - Extract the size of a memory bank. -* -* INPUT: MEMORY_BANK bank - Bank number -* OUTPUT: N/A -* RETURNS: Memory bank size. -*********************************************************************/ -unsigned int getMemoryBankSize(MEMORY_BANK bank) -{ - unsigned int size, base, value; - base = getMemoryBankBaseAddress(bank); - GT_REG_READ((SCS_0_HIGH_DECODE_ADDRESS + bank * 8), &size); - size = ((size + 1) << 20) - (base & 0x0fffffff); - GT_REG_READ((SCS_0_HIGH_DECODE_ADDRESS + bank * 8), &value); - if (value == 0) - return 0; - else - return size; -} - -/******************************************************************** -* getDeviceSize - Extract the size of a device memory space -* -* INPUT: DEVICE device - Device number -* OUTPUT: N/A -* RETURNS: Size of a device memory space. -*********************************************************************/ -unsigned int getDeviceSize(DEVICE device) -{ - unsigned int size, base, value; - base = getDeviceBaseAddress(device); - GT_REG_READ((CS_0_HIGH_DECODE_ADDRESS + device * 8), &size); - size = ((size + 1) << 20) - (base & 0x0fffffff); - GT_REG_READ((CS_0_HIGH_DECODE_ADDRESS + device * 8), &value); - if ((value + 1) == 0) - return 0; - else - return size; -} - -/******************************************************************** -* getDeviceWidth - A device can be with: 1,2,4 or 8 Bytes data width. -* The width is determine in registers: 'Device Parameters' -* registers (0x45c, 0x460, 0x464, 0x468, 0x46c - for each device. -* at bits: [21:20]. -* -* INPUT: DEVICE device - Device number -* OUTPUT: N/A -* RETURNS: Device width in Bytes (1,2,4, or 8), 0 if error had occurred. -*********************************************************************/ -unsigned int getDeviceWidth(DEVICE device) -{ - unsigned int width; - unsigned int regValue; - - GT_REG_READ(DEVICE_BANK0PARAMETERS + device * 4, ®Value); - width = (regValue & 0x00300000) >> 20; - switch (width) { - case 0: - return 1; - case 1: - return 2; - case 2: - return 4; - case 3: - return 8; - default: - return 0; - } -} - -/******************************************************************** -* mapMemoryBanks0and1 - Sets new bases and boundaries for memory banks 0 and 1 -* - Pay attention to the PCI mappings and make sure to -* coordinate between the two interfaces!!! -* - It is the programmer`s responsibility to make sure -* there are no conflicts with other memory spaces!!! -* - If a bank needs to be closed , give it a 0 length -* -* -* INPUTS: unsigned int bank0Base - required bank 0 base address. -* unsigned int bank0Length - required bank 0 size. -* unsigned int bank1Base - required bank 1 base address. -* unsigned int bank1Length - required bank 1 size. -* RETURNS: true on success, false on failure or if one of the parameters is -* erroneous. -*********************************************************************/ -bool mapMemoryBanks0and1(unsigned int bank0Base, unsigned int bank0Length, - unsigned int bank1Base, unsigned int bank1Length) -{ - unsigned int mainBank0Top = bank0Base + bank0Length; - unsigned int mainBank1Top = bank1Base + bank1Length; - unsigned int memBank0Base, bank0Top; - unsigned int memBank1Base, bank1Top; - - if (bank0Base <= bank1Base) { - if ((bank0Base + bank0Length) > bank1Base) - return false; - } else { - if ((bank1Base + bank1Length) > bank0Base) - return false; - } - - if (bank0Length == 0) - mainBank0Top++; - if (bank1Length == 0) - mainBank1Top++; - - memBank0Base = ((unsigned int) (bank0Base & 0x0fffffff)) >> 20; - bank0Top = ((unsigned int) (mainBank0Top & 0x0fffffff)) >> 20; - memBank1Base = ((unsigned int) (bank1Base & 0x0fffffff)) >> 20; - bank1Top = ((unsigned int) (mainBank1Top & 0x0fffffff)) >> 20; - - if (mainBank1Top > mainBank0Top) { - bank0Base >>= 21; - mainBank0Top = - ((unsigned int) (mainBank1Top & 0x0fffffff)) >> 21; - } else { - bank0Base = bank1Base >> 21; - mainBank0Top = - ((unsigned int) (mainBank0Top & 0x0fffffff)) >> 21; - } - GT_REG_WRITE(SCS_1_0_LOW_DECODE_ADDRESS, bank0Base); - if ((bank0Length + bank1Length) != 0) { - GT_REG_WRITE(SCS_1_0_HIGH_DECODE_ADDRESS, - mainBank0Top - 1); - } else { - GT_REG_WRITE(SCS_1_0_HIGH_DECODE_ADDRESS, 0x0); - } - if (bank1Length != 0) { - GT_REG_WRITE(SCS_1_HIGH_DECODE_ADDRESS, bank1Top - 1); - } else { - GT_REG_WRITE(SCS_1_HIGH_DECODE_ADDRESS, 0x0); - } - GT_REG_WRITE(SCS_1_LOW_DECODE_ADDRESS, memBank1Base); - if (bank0Length != 0) { - GT_REG_WRITE(SCS_0_HIGH_DECODE_ADDRESS, bank0Top - 1); - } else { - GT_REG_WRITE(SCS_0_HIGH_DECODE_ADDRESS, 0x0); - } - GT_REG_WRITE(SCS_0_LOW_DECODE_ADDRESS, memBank0Base); - return true; -} - -/******************************************************************** -* mapMemoryBanks2and3 - Sets new bases and boundaries for memory banks 2 and 3 -* - Pay attention to the PCI mappings and make sure to -* coordinate between the two interfaces!!! -* - It`s the programmer`s responsibility to make sure there -* are no conflicts with other memory spaces!!! -* - If a bank needs to be closed , give it a 0 length. -* -* -* INPUTS: unsigned int bank2Base - required bank 2 base address. -* unsigned int bank2Length - required bank 2 size. -* unsigned int bank3Base - required bank 3 base address. -* unsigned int bank3Length - required bank 3 size. -* RETURNS: true on success, false on failure or if one of the parameters is -* erroneous. -*********************************************************************/ -bool mapMemoryBanks2and3(unsigned int bank2Base, unsigned int bank2Length, - unsigned int bank3Base, unsigned int bank3Length) -{ - unsigned int mainBank2Top = - (unsigned int) (bank2Base + bank2Length); - unsigned int mainBank3Top = - (unsigned int) (bank3Base + bank3Length); - unsigned int memBank2Base, bank2Top; - unsigned int memBank3Base, bank3Top; - - if (bank2Base <= bank3Base) { - if ((bank2Base + bank2Length) > bank3Base) - return false; - } else { - if ((bank3Base + bank3Length) > bank2Base) - return false; - } - if (bank2Length == 0) - mainBank2Top++; - if (bank3Length == 0) - mainBank3Top++; - - memBank2Base = ((unsigned int) (bank2Base & 0x0fffffff)) >> 20; - bank2Top = ((unsigned int) (mainBank2Top & 0x0fffffff)) >> 20; - memBank3Base = ((unsigned int) (bank3Base & 0x0fffffff)) >> 20; - bank3Top = ((unsigned int) (mainBank3Top & 0x0fffffff)) >> 20; - - if (mainBank3Top > mainBank2Top) { - bank2Base >>= 21; - mainBank2Top = - ((unsigned int) (mainBank3Top & 0x0fffffff)) >> 21; - } else { - bank2Base = bank3Base >> 21; - mainBank2Top = - ((unsigned int) (mainBank2Top & 0x0fffffff)) >> 21; - } - GT_REG_WRITE(SCS_3_2_LOW_DECODE_ADDRESS, bank2Base); - if ((bank2Length + bank3Length) != 0) { - GT_REG_WRITE(SCS_3_2_HIGH_DECODE_ADDRESS, - mainBank2Top - 1); - } else { - GT_REG_WRITE(SCS_3_2_HIGH_DECODE_ADDRESS, 0x0); - } - if (bank3Length != 0) { - GT_REG_WRITE(SCS_3_HIGH_DECODE_ADDRESS, bank3Top - 1); - } else { - GT_REG_WRITE(SCS_3_HIGH_DECODE_ADDRESS, 0x0); - } - GT_REG_WRITE(SCS_3_LOW_DECODE_ADDRESS, memBank3Base); - if (bank2Length != 0) { - GT_REG_WRITE(SCS_2_HIGH_DECODE_ADDRESS, bank2Top - 1); - } else { - GT_REG_WRITE(SCS_2_HIGH_DECODE_ADDRESS, 0x0); - } - GT_REG_WRITE(SCS_2_LOW_DECODE_ADDRESS, memBank2Base); - return true; -} - -/******************************************************************** -* mapDevices0_1and2MemorySpace - Sets new bases and boundaries for devices 0,1 -* and 2 -* - Pay attention to the PCI mappings and make sure to -* coordinate between the two interfaces!!! -* - It`s the programmer`s responsibility to make sure there -* are no conflicts with other memory spaces!!! -* - If a device needs to be closed , give it a 0 length -* -* -* INPUTS: unsigned int device0Base - required cs_0 base address. -* unsigned int device0Length - required cs_0 size. -* unsigned int device1Base - required cs_1 base address. -* unsigned int device1Length - required cs_0 size. -* unsigned int device2Base - required cs_2 base address. -* unsigned int device2Length - required cs_2 size. -* RETURNS: true on success, false on failure or if one of the parameters is -* erroneous. -*********************************************************************/ -bool mapDevices0_1and2MemorySpace(unsigned int device0Base, - unsigned int device0Length, - unsigned int device1Base, - unsigned int device1Length, - unsigned int device2Base, - unsigned int device2Length) -{ - unsigned int deviceBank0Top = - (unsigned int) (device0Base + device0Length); - unsigned int deviceBank1Top = - (unsigned int) (device1Base + device1Length); - unsigned int deviceBank2Top = - (unsigned int) (device2Base + device2Length); - unsigned int device0BaseTemp = 0, device0TopTemp = 0; - unsigned int bank0Base, bank0Top; - unsigned int bank1Base, bank1Top; - unsigned int bank2Base, bank2Top; - bank0Base = ((unsigned int) (device0Base & 0x0fffffff)) >> 20; - bank0Top = ((unsigned int) (deviceBank0Top & 0x0fffffff)) >> 20; - bank1Base = ((unsigned int) (device1Base & 0x0fffffff)) >> 20; - bank1Top = ((unsigned int) (deviceBank1Top & 0x0fffffff)) >> 20; - bank2Base = ((unsigned int) (device2Base & 0x0fffffff)) >> 20; - bank2Top = ((unsigned int) (deviceBank2Top & 0x0fffffff)) >> 20; - - if (device0Length == 0) - deviceBank0Top++; - if (device1Length == 0) - deviceBank1Top++; - if (device2Length == 0) - deviceBank2Top++; - - if (device0Base <= device1Base && device0Base <= device2Base) { - if ((device0Base + device0Length) > device1Base || \ - (device0Base + device0Length) > device2Base) - return false; - if (device1Base <= device2Base) { - if ((device1Base + device1Length) > device2Base) - return false; - } else { - if ((device2Base + device2Length) > device1Base) - return false; - } - } - - if (device1Base <= device0Base && device1Base <= device2Base) { - if ((device1Base + device1Length) > device0Base || - (device1Base + device1Length) > device2Base) - return false; - if (device0Base <= device2Base) { - if ((device0Base + device0Length) > device2Base) - return false; - } else { - if ((device2Base + device2Length) > device0Base) - return false; - } - } - - if (device2Base <= device1Base && device2Base <= device0Base) { - if ((device2Base + device2Length) > device1Base || - (device2Base + device2Length) > device0Base) - return false; - if (device0Base <= device1Base) { - if ((device0Base + device0Length) > device1Base) - return false; - } else { - if ((device1Base + device1Length) > device0Base) - return false; - } - } - - if ((deviceBank2Top > deviceBank1Top) && (deviceBank1Top > - deviceBank0Top)) { - device0BaseTemp = device0Base >> 21; - device0TopTemp = - ((unsigned int) (deviceBank2Top & 0x0fffffff)) >> 21; - } - if ((deviceBank2Top > deviceBank0Top) - && (deviceBank0Top > deviceBank1Top)) { - device0BaseTemp = device1Base >> 21; - device0TopTemp = - ((unsigned int) (deviceBank2Top & 0x0fffffff)) >> 21; - } - if ((deviceBank1Top > deviceBank2Top) - && (deviceBank2Top > deviceBank0Top)) { - device0BaseTemp = device0Base >> 21; - device0TopTemp = - ((unsigned int) (deviceBank1Top & 0x0fffffff)) >> 21; - } - if ((deviceBank1Top > deviceBank0Top) - && (deviceBank0Top > deviceBank2Top)) { - device0BaseTemp = device2Base >> 21; - device0TopTemp = - ((unsigned int) (deviceBank1Top & 0x0fffffff)) >> 21; - } - if ((deviceBank0Top > deviceBank2Top) - && (deviceBank2Top > deviceBank1Top)) { - device0BaseTemp = device1Base >> 21; - device0TopTemp = - ((unsigned int) (deviceBank0Top & 0x0fffffff)) >> 21; - } - if ((deviceBank0Top > deviceBank1Top) - && (deviceBank1Top > deviceBank2Top)) { - device0BaseTemp = device2Base >> 21; - device0TopTemp = - ((unsigned int) (deviceBank0Top & 0x0fffffff)) >> 21; - } - GT_REG_WRITE(CS_2_0_LOW_DECODE_ADDRESS, device0BaseTemp); - if ((device0Length + device1Length + device2Length) != 0) { - GT_REG_WRITE(CS_2_0_HIGH_DECODE_ADDRESS, - device0TopTemp - 1); - } else { - GT_REG_WRITE(CS_2_0_HIGH_DECODE_ADDRESS, 0x0); - } - GT_REG_WRITE(CS_0_LOW_DECODE_ADDRESS, bank0Base); - if (device0Length != 0) { - GT_REG_WRITE(CS_0_HIGH_DECODE_ADDRESS, bank0Top - 1); - } else { - GT_REG_WRITE(CS_0_HIGH_DECODE_ADDRESS, 0x0); - } - GT_REG_WRITE(CS_1_LOW_DECODE_ADDRESS, bank1Base); - if (device1Length != 0) { - GT_REG_WRITE(CS_1_HIGH_DECODE_ADDRESS, bank1Top - 1); - } else { - GT_REG_WRITE(CS_1_HIGH_DECODE_ADDRESS, 0x0); - } - GT_REG_WRITE(CS_2_LOW_DECODE_ADDRESS, bank2Base); - if (device2Length != 0) { - GT_REG_WRITE(CS_2_HIGH_DECODE_ADDRESS, bank2Top - 1); - } else { - GT_REG_WRITE(CS_2_HIGH_DECODE_ADDRESS, 0x0); - } - return true; -} - -/******************************************************************** -* mapDevices3andBootMemorySpace - Sets new bases and boundaries for devices: -* 3 and boot -* - Pay attention to the PCI mappings and make sure to -* coordinate between the two interfaces!!! -* - It is the programmer`s responsibility to make sure -* there are no conflicts with other memory spaces!!! -* - If a device needs to be closed , give it a 0 length. -* -* INPUTS: base and length of device 3and boot -* RETURNS: true on success, false on failure -*********************************************************************/ -bool mapDevices3andBootMemorySpace(unsigned int device3Base, - unsigned int device3Length, - unsigned int bootDeviceBase, - unsigned int bootDeviceLength) -{ - unsigned int deviceBank3Top = - (unsigned int) (device3Base + device3Length); - unsigned int deviceBankBootTop = - (unsigned int) (bootDeviceBase + bootDeviceLength); - unsigned int bank3Base, bank3Top; - unsigned int bank4Base, bank4Top; - unsigned int Device1Base, Device1Top; - - bank3Top = ((unsigned int) (deviceBank3Top & 0x0fffffff)) >> 20; - bank4Top = ((unsigned int) (deviceBankBootTop & 0x0fffffff)) >> 20; - bank3Base = ((unsigned int) (device3Base & 0x0fffffff)) >> 20; - bank4Base = ((unsigned int) (bootDeviceBase & 0x0fffffff)) >> 20; - - if (device3Base <= bootDeviceBase) { - if (deviceBank3Top > bootDeviceBase) - return false; - } else { - if (deviceBankBootTop > device3Base) - return false; - } - - if (deviceBankBootTop > deviceBank3Top) { - Device1Base = device3Base >> 21; - Device1Top = - ((unsigned int) (deviceBankBootTop & 0x0fffffff)) >> - 21; - } else { - Device1Base = bootDeviceBase >> 21; - Device1Top = - ((unsigned int) (deviceBank3Top & 0x0fffffff)) >> 21; - } - GT_REG_WRITE(CS_3_BOOTCS_LOW_DECODE_ADDRESS, Device1Base); - if ((device3Length + bootDeviceLength) != 0) { - GT_REG_WRITE(CS_3_BOOTCS_HIGH_DECODE_ADDRESS, - Device1Top - 1); - } else { - GT_REG_WRITE(CS_3_BOOTCS_HIGH_DECODE_ADDRESS, 0x0); - } - GT_REG_WRITE(CS_3_LOW_DECODE_ADDRESS, bank3Base); - if (device3Length != 0) { - GT_REG_WRITE(CS_3_HIGH_DECODE_ADDRESS, bank3Top - 1); - } else { - GT_REG_WRITE(CS_3_HIGH_DECODE_ADDRESS, 0x0); - } - GT_REG_WRITE(BOOTCS_LOW_DECODE_ADDRESS, bank4Base); - if (bootDeviceLength != 0) { - GT_REG_WRITE(BOOTCS_HIGH_DECODE_ADDRESS, bank4Top - 1); - } else { - GT_REG_WRITE(BOOTCS_HIGH_DECODE_ADDRESS, 0x0); - } - return true; -} - -/******************************************************************** -* modifyDeviceParameters - This function can be used to modify a device`s -* parameters. -* - Be advised to check the spec before modifying them. -* Inputs: -* Returns: false if one of the parameters is erroneous,true otherwise. -*********************************************************************/ -bool modifyDeviceParameters(DEVICE device, unsigned int turnOff, - unsigned int accToFirst, - unsigned int accToNext, unsigned int aleToWr, - unsigned int wrActive, unsigned int wrHigh, - unsigned int width, bool paritySupport) -{ - unsigned int data, oldValue; - - if ((turnOff > 0x7 && turnOff != DONT_MODIFY) - || (accToFirst > 0xf && accToFirst != DONT_MODIFY) - || (accToNext > 0xf && accToNext != DONT_MODIFY) - || (aleToWr > 0x7 && aleToWr != DONT_MODIFY) - || (wrActive > 0x7 && wrActive != DONT_MODIFY) - || (wrHigh > 0x7 && wrHigh != DONT_MODIFY)) { - return false; - } - - GT_REG_READ((DEVICE_BANK0PARAMETERS + device * 4), &oldValue); - if (turnOff == DONT_MODIFY) - turnOff = oldValue & 0x00000007; - else - turnOff = turnOff; - - if (accToFirst == DONT_MODIFY) - accToFirst = oldValue & 0x00000078; - else - accToFirst = accToFirst << 3; - - if (accToNext == DONT_MODIFY) - accToNext = oldValue & 0x00000780; - else - accToNext = accToNext << 7; - - if (aleToWr == DONT_MODIFY) - aleToWr = oldValue & 0x00003800; - else - aleToWr = aleToWr << 11; - - if (wrActive == DONT_MODIFY) - wrActive = oldValue & 0x0001c000; - else - wrActive = wrActive << 14; - - if (wrHigh == DONT_MODIFY) - wrHigh = oldValue & 0x000e0000; - else - wrHigh = wrHigh << 17; - - data = - turnOff | accToFirst | accToNext | aleToWr | wrActive | wrHigh; - switch (width) { - case _8BIT: - break; - case _16BIT: - data = data | _16BIT; - break; - case _32BIT: - data = data | _32BIT; - break; - case _64BIT: - data = data | _64BIT; - break; - default: - return false; - } - if (paritySupport == true) - data = data | PARITY_SUPPORT; - GT_REG_WRITE(DEVICE_BANK0PARAMETERS + device * 4, data); - return true; -} - -/******************************************************************** -* remapAddress - This fubction used for address remapping -* Inputs: - regOffset: remap register -* remapHeader : remapped address -* Returns: false if one of the parameters is erroneous,true otherwise. -*********************************************************************/ -bool remapAddress(unsigned int remapReg, unsigned int remapValue) -{ - unsigned int valueForReg; - valueForReg = (remapValue & 0xffe00000) >> 21; - GT_REG_WRITE(remapReg, valueForReg); - return true; -} Index: arch/mips/galileo-boards/ev64120/compressed/misc.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/misc.c diff -N arch/mips/galileo-boards/ev64120/compressed/misc.c --- arch/mips/galileo-boards/ev64120/compressed/misc.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,313 +0,0 @@ -/* - * arch/mips/galileo/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 - * puts by Nick Holloway 1993, better puts by Martin Mares 1995 - * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 - * - * Modified by RidgeRun Inc. - */ - -#include -#include -/* - * gzip declarations - */ - -#define OF(args) args -#define STATIC static - -#define channel 1 - -#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 */ - -void variable_init(); -static void puts(const char *); - -void int2hex(int i) -{ - int tth, th, h, t, d; - - if (i > 99999) { - serial_putc(channel, "Error - int2hex outofbounds"); - return; - } - - tth = (i) / 10000; - th = (i - (tth * 10000)) / 1000; - h = (i - ((tth * 10000) + (th * 1000))) / 100; - t = (i - ((tth * 10000) + (th * 1000) + (h * 100))) / 10; - d = (i - ((tth * 10000) + (th * 1000) + (h * 100) + (t * 10))); - serial_putc(channel, tth + '0'); - serial_putc(channel, th + '0'); - serial_putc(channel, h + '0'); - serial_putc(channel, t + '0'); - serial_putc(channel, d + '0'); -} - -int checksum; -int byte_count; -static unsigned char *input_data; - -static int printCnt = 0; - -int get_byte() -{ - unsigned char c = (inptr < insize ? inbuf[inptr++] : fill_inbuf()); - byte_count++; - checksum += c; - - // if (printCnt++ < 150) - // { - // puts("\n"); - // puts("byte count = "); - // int2hex(byte_count & 0xff); - // puts(" byte val = "); - // int2hex(c); - // puts(" checksum = "); - // int2hex(checksum & 0xff); - // puts("\n"); - // } - return c; -} - -/* 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 **); - -/* - * This is set up by the setup-routine at boot-time - */ - - -#define STACK_SIZE (4096) -long user_stack[STACK_SIZE]; -long *stack_start = &user_stack[STACK_SIZE]; - -extern int linux_compressed_start; -extern int linux_compressed_size; -extern int malloc_start; - -static int input_len; - -static long bytes_out = 0; -extern int kernel_location_start; -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 unsigned long free_mem_ptr; -static unsigned long free_mem_end_ptr; - -#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; -} - -static void puts(const char *s) -{ - while (*s) { - if (*s == 10) - serial_putc(channel, 13); - serial_putc(channel, *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; -} - -check_mem() -{ - int i; - - puts("\ncplens = "); - for (i = 0; i < 10; i++) { - int2hex(cplens[i]); - puts(" "); - } - puts("\ncplext = "); - for (i = 0; i < 10; i++) { - int2hex(cplext[i]); - puts(" "); - } - puts("\nborder = "); - for (i = 0; i < 10; i++) { - int2hex(border[i]); - puts(" "); - } - puts("\n"); -} - -static void error(char *x) -{ - check_mem(); - puts("\n\n"); - puts(x); - puts("byte_count = "); - int2hex(byte_count); - puts("\n"); - puts("\n\n -- System halted"); - while (1); /* Halt */ -} - -void variable_init() -{ - byte_count = 0; - checksum = 0; - input_data = (unsigned char *) &linux_compressed_start; - input_len = linux_compressed_size; - output_data = &kernel_location_start; - free_mem_ptr = (long) &malloc_start; - free_mem_end_ptr = (long) ((char *) &malloc_start + 0x400000); -} - -int decompress_kernel() -{ - //check_mem(); - - variable_init(); - - makecrc(); - puts("Uncompressing Linux... \n"); - gunzip(); // ...see inflate.c - puts("Ok, booting the kernel.\n"); - return 0; -} Index: arch/mips/galileo-boards/ev64120/compressed/ns16550.h =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/ns16550.h diff -N arch/mips/galileo-boards/ev64120/compressed/ns16550.h --- arch/mips/galileo-boards/ev64120/compressed/ns16550.h 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,126 +0,0 @@ -/* NS16550 UART registers */ - -#ifndef NS16550H -#define NS16550H - -#define UART_BASE 0xbd000000 -#define NS16550_CHANA PHYS_TO_K1(UART_BASE + 0x20) -#define NS16550_CHANB PHYS_TO_K1(UART_BASE) - -#ifndef NS16550_HZ -#define NS16550_HZ 3686400 -#endif - -#ifdef __ASSEMBLY__ - -#ifndef NSREG -#define NSREG(x) ((x)*4) -#endif - -#define DATA NSREG(0) /* data register (R/W) */ -#define IER NSREG(1) /* interrupt enable (W) */ -#define IIR NSREG(2) /* interrupt identification (R) */ -#define FIFO IIR /* 16550 fifo control (W) */ -#define CFCR NSREG(3) /* line control register (R/W) */ -#define MCR NSREG(4) /* modem control register (R/W) */ -#define LSR NSREG(5) /* line status register (R/W) */ -#define MSR NSREG(6) /* modem status register (R/W) */ -#define SCR NSREG(7) /* scratch register (R/W) */ - -#else - -#ifndef nsreg -#if #endian(little) -#define nsreg(x) unsigned :24; unsigned char x; -#else -/*#define nsreg(x) unsigned char x; unsigned :24;*/ -#define nsreg(x) unsigned int x:8;unsigned int :24; -#endif -#endif - -typedef struct { - nsreg(data); /* data register (R/W) */ - nsreg(ier); /* interrupt enable (W) */ - nsreg(iir); /* interrupt identification (R) */ -#define fifo iir /* 16550 fifo control (W) */ - nsreg(cfcr); /* line control register (R/W) */ - nsreg(mcr); /* modem control register (R/W) */ - nsreg(lsr); /* line status register (R/W) */ - nsreg(msr); /* modem status register (R/W) */ - nsreg(scr); /* scratch register (R/W) */ -} ns16550dev; -#endif - - -/* 16 bit baud rate divisor (lower byte in dca_data, upper in dca_ier) */ -#define BRTC(x) (NS16550_HZ / (16*(x))) - -/* interrupt enable register */ -#define IER_ERXRDY 0x1 /* int on rx ready */ -#define IER_ETXRDY 0x2 /* int on tx ready */ -#define IER_ERLS 0x4 /* int on line status change */ -#define IER_EMSC 0x8 /* int on modem status change */ - -/* interrupt identification register */ -#define IIR_IMASK 0xf /* mask */ -#define IIR_RXTOUT 0xc /* receive timeout */ -#define IIR_RLS 0x6 /* receive line status */ -#define IIR_RXRDY 0x4 /* receive ready */ -#define IIR_TXRDY 0x2 /* transmit ready */ -#define IIR_NOPEND 0x1 /* nothing */ -#define IIR_MLSC 0x0 /* modem status */ -#define IIR_FIFO_MASK 0xc0 /* set if FIFOs are enabled */ - -/* fifo control register */ -#define FIFO_ENABLE 0x01 /* enable fifo */ -#define FIFO_RCV_RST 0x02 /* reset receive fifo */ -#define FIFO_XMT_RST 0x04 /* reset transmit fifo */ -#define FIFO_DMA_MODE 0x08 /* enable dma mode */ -#define FIFO_TRIGGER_1 0x00 /* trigger at 1 char */ -#define FIFO_TRIGGER_4 0x40 /* trigger at 4 chars */ -#define FIFO_TRIGGER_8 0x80 /* trigger at 8 chars */ -#define FIFO_TRIGGER_14 0xc0 /* trigger at 14 chars */ - -/* character format control register */ -#define CFCR_DLAB 0x80 /* divisor latch */ -#define CFCR_SBREAK 0x40 /* send break */ -#define CFCR_PZERO 0x30 /* zero parity */ -#define CFCR_PONE 0x20 /* one parity */ -#define CFCR_PEVEN 0x10 /* even parity */ -#define CFCR_PODD 0x00 /* odd parity */ -#define CFCR_PENAB 0x08 /* parity enable */ -#define CFCR_STOPB 0x04 /* 2 stop bits */ -#define CFCR_8BITS 0x03 /* 8 data bits */ -#define CFCR_7BITS 0x02 /* 7 data bits */ -#define CFCR_6BITS 0x01 /* 6 data bits */ -#define CFCR_5BITS 0x00 /* 5 data bits */ - -/* modem control register */ -#define MCR_LOOPBACK 0x10 /* loopback */ -#define MCR_IENABLE 0x08 /* output 2 = int enable */ -#define MCR_DRS 0x04 /* output 1 = xxx */ -#define MCR_RTS 0x02 /* enable RTS */ -#define MCR_DTR 0x01 /* enable DTR */ - -/* line status register */ -#define LSR_RCV_FIFO 0x80 /* error in receive fifo */ -#define LSR_TSRE 0x40 /* transmitter empty */ -#define LSR_TXRDY 0x20 /* transmitter ready */ -#define LSR_BI 0x10 /* break detected */ -#define LSR_FE 0x08 /* framing error */ -#define LSR_PE 0x04 /* parity error */ -#define LSR_OE 0x02 /* overrun error */ -#define LSR_RXRDY 0x01 /* receiver ready */ -#define LSR_RCV_MASK 0x1f - -/* modem status register */ -#define MSR_DCD 0x80 /* DCD active */ -#define MSR_RI 0x40 /* RI active */ -#define MSR_DSR 0x20 /* DSR active */ -#define MSR_CTS 0x10 /* CTS active */ -#define MSR_DDCD 0x08 /* DCD changed */ -#define MSR_TERI 0x04 /* RI changed */ -#define MSR_DDSR 0x02 /* DSR changed */ -#define MSR_DCTS 0x01 /* CTS changed */ - -#endif Index: arch/mips/galileo-boards/ev64120/compressed/osdep.h =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/osdep.h diff -N arch/mips/galileo-boards/ev64120/compressed/osdep.h --- arch/mips/galileo-boards/ev64120/compressed/osdep.h 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,36 +0,0 @@ -#ifndef __OSDEP_H__ -#define __OSDEP_H__ - -/* - * This program is free software; you can redistribute 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. - */ - -#if defined(__linux__) || defined(__FreeBSD__) || defined (__MIPSEB__) -#define ETHERBOOT32 -#define ntohl(x) (x) -#define htonl(x) (x) -#define ntohs(x) (x) -#define htons(x) (x) - -#endif - - - - -/* ANSI prototyping macro */ -#ifdef __STDC__ -#define P(x) x -#else -#define P(x) () -#endif - -#endif - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ Index: arch/mips/galileo-boards/ev64120/compressed/pci.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/pci.c diff -N arch/mips/galileo-boards/ev64120/compressed/pci.c --- arch/mips/galileo-boards/ev64120/compressed/pci.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1336 +0,0 @@ -/* PCI.c - PCI functions */ - -/* Copyright - Galileo technology. */ - -#ifdef __linux__ -#include -#include -#ifndef PROM -#include -#endif - -#undef PCI_DEBUG - -#ifdef PCI_DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -#else -#include "core.h" -#include "pci.h" -#include -#endif - -/******************************************************************** -* pci0ScanDevices - This function scan PCI0 bus, if found any device on -* this bus it interrogate the Device for the information -* it can discover. -* The fields with all information are the following: -* char type[20]; -* unsigned int deviceNum; -* unsigned int venID; -* unsigned int deviceID; -* unsigned int bar0Base; -* unsigned int bar0Size; -* unsigned int bar1Base; -* unsigned int bar1Size; -* unsigned int bar2Base; -* unsigned int bar2Size; -* unsigned int bar3Base; -* unsigned int bar3Size; -* unsigned int bar4Base; -* unsigned int bar4Size; -* unsigned int bar5Base; -* unsigned int bar5Size; -* -* Inputs: PCI0_DEVICE* pci0Detect - Pointer to an array of STRUCT PCI0_DEVICE. -* unsigned int numberOfElment - The PCI0_DEVICE Array length. -* Output: None. -*********************************************************************/ - -void pci0ScanDevices(PCI_DEVICE * pci0Detect, unsigned int numberOfElment) -{ - PCI_DEVICE *pci0ArrayPointer = pci0Detect; - unsigned int id; /* PCI Configuration register 0x0. */ - unsigned int device; /* device`s Counter. */ - unsigned int classCode; /* PCI Configuration register 0x8 */ - unsigned int arrayCounter = 0; - unsigned int memBaseAddress; - unsigned int memSize; - unsigned int c18RegValue; - - PCI0_MASTER_ENABLE(SELF); - /* According to PCI REV 2.1 MAX agents on the bus are -21- */ - for (device = 6; device < 8; device++) { - id = pci0ReadConfigReg(PCI_0DEVICE_AND_VENDOR_ID, device); - GT_REG_READ(INTERRUPT_CAUSE_REGISTER, &c18RegValue); - /* Clearing bit 18 of in the Cause Register 0xc18 by writting 0. */ - GT_REG_WRITE(INTERRUPT_CAUSE_REGISTER, - c18RegValue & 0xfffbffff); - if ((id != 0xffffffff) && !(c18RegValue & 0x40000)) { - classCode = - pci0ReadConfigReg - (PCI_0CLASS_CODE_AND_REVISION_ID, device); - pci0ArrayPointer->deviceNum = device; - pci0ArrayPointer->venID = (id & 0xffff); - pci0ArrayPointer->deviceID = - ((id & 0xffff0000) >> 16); - DBG("\nrr: venID %x devID %x\n", - pci0ArrayPointer->venID, - pci0ArrayPointer->deviceID); - DBG("rr: device found %x\n", - pci0ArrayPointer->deviceNum); - /* BAR0 parameters */ - memBaseAddress = pci0ReadConfigReg(BAR0, device); - pci0ArrayPointer->bar0Type = memBaseAddress & 1; - pci0ArrayPointer->bar0Base = - memBaseAddress & 0xfffff000; - pci0WriteConfigReg(BAR0, device, 0xffffffff); - memSize = pci0ReadConfigReg(BAR0, device); - if (memSize == 0) { /* case of an empty BAR */ - pci0ArrayPointer->bar0Size = 0; - } else { - if (pci0ArrayPointer->bar0Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci0ArrayPointer->bar0Size = memSize; - } - DBG("rr: device BAR0 size %x\n", memSize); - DBG("rr: device BAR0 address %x\n", - memBaseAddress); - pci0WriteConfigReg(BAR0, device, memBaseAddress); - /* BAR1 parameters */ - memBaseAddress = pci0ReadConfigReg(BAR1, device); - pci0ArrayPointer->bar1Type = memBaseAddress & 1; - pci0ArrayPointer->bar1Base = - memBaseAddress & 0xfffff000; - pci0WriteConfigReg(BAR1, device, 0xffffffff); - memSize = pci0ReadConfigReg(BAR1, device); - if (memSize == 0) { /* case of an empty BAR */ - pci0ArrayPointer->bar1Size = 0; - } else { - if (pci0ArrayPointer->bar1Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci0ArrayPointer->bar1Size = memSize; - } - DBG("rr: device BAR1 size %x\n", memSize); - DBG("rr: device BAR1 address %x\n", - memBaseAddress); - pci0WriteConfigReg(BAR1, device, memBaseAddress); - /* BAR2 parameters */ - memBaseAddress = pci0ReadConfigReg(BAR2, device); - pci0ArrayPointer->bar2Type = memBaseAddress & 1; - pci0ArrayPointer->bar2Base = - memBaseAddress & 0xfffff000; - pci0WriteConfigReg(BAR2, device, 0xffffffff); - memSize = pci0ReadConfigReg(BAR2, device); - if (memSize == 0) { /* case of an empty BAR */ - pci0ArrayPointer->bar2Size = 0; - } else { - if (pci0ArrayPointer->bar2Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci0ArrayPointer->bar2Size = memSize; - } - DBG("rr: device BAR2 size %x\n", memSize); - DBG("rr: device BAR2 address %x\n", - memBaseAddress); - pci0WriteConfigReg(BAR2, device, memBaseAddress); - /* BAR3 parameters */ - memBaseAddress = pci0ReadConfigReg(BAR3, device); - pci0ArrayPointer->bar3Type = memBaseAddress & 1; - pci0ArrayPointer->bar3Base = - memBaseAddress & 0xfffff000; - pci0WriteConfigReg(BAR3, device, 0xffffffff); - memSize = pci0ReadConfigReg(BAR3, device); - if (memSize == 0) { /* case of an empty BAR */ - pci0ArrayPointer->bar3Size = 0; - } else { - if (pci0ArrayPointer->bar3Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci0ArrayPointer->bar3Size = memSize; - } - DBG("rr: device BAR3 size %x\n", memSize); - DBG("rr: device BAR3 address %x\n", - memBaseAddress); - pci0WriteConfigReg(BAR3, device, memBaseAddress); - /* BAR4 parameters */ - memBaseAddress = pci0ReadConfigReg(BAR4, device); - pci0ArrayPointer->bar4Type = memBaseAddress & 1; - pci0ArrayPointer->bar4Base = - memBaseAddress & 0xfffff000; - pci0WriteConfigReg(BAR4, device, 0xffffffff); - memSize = pci0ReadConfigReg(BAR4, device); - if (memSize == 0) { /* case of an empty BAR */ - pci0ArrayPointer->bar4Size = 0; - } else { - if (pci0ArrayPointer->bar4Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci0ArrayPointer->bar4Size = memSize; - } - DBG("rr: device BAR4 size %x\n", memSize); - DBG("rr: device BAR4 address %x\n", - memBaseAddress); - pci0WriteConfigReg(BAR4, device, memBaseAddress); - /* BAR5 parameters */ - memBaseAddress = pci0ReadConfigReg(BAR5, device); - pci0ArrayPointer->bar5Type = memBaseAddress & 1; - pci0ArrayPointer->bar5Base = - memBaseAddress & 0xfffff000; - pci0WriteConfigReg(BAR5, device, 0xffffffff); - memSize = pci0ReadConfigReg(BAR5, device); - if (memSize == 0) { /* case of an empty BAR */ - pci0ArrayPointer->bar5Size = 0; - } else { - if (pci0ArrayPointer->bar5Type == 1) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci0ArrayPointer->bar5Size = memSize; - } - DBG("rr: device BAR5 size %x\n", memSize); - DBG("rr: device BAR5 address %x\n", - memBaseAddress); - pci0WriteConfigReg(BAR5, device, memBaseAddress); - /* End of BARs Detection. */ - - classCode = ((classCode & 0xff000000) >> 24); - switch (classCode) { - case 0x0: - strcpy(pci0ArrayPointer->type, - "Old generation device"); - break; - case 0x1: - strcpy(pci0ArrayPointer->type, - "Mass storage controller"); - break; - case 0x2: - strcpy(pci0ArrayPointer->type, - "Network controller"); - break; - case 0x3: - strcpy(pci0ArrayPointer->type, - "Display controller"); - break; - case 0x4: - strcpy(pci0ArrayPointer->type, - "Multimedia device"); - break; - case 0x5: - strcpy(pci0ArrayPointer->type, - "Memory controller"); - break; - case 0x6: - strcpy(pci0ArrayPointer->type, - "Bridge Device"); - break; - case 0x7: - strcpy(pci0ArrayPointer->type, - "Simple Communication controllers"); - break; - case 0x8: - strcpy(pci0ArrayPointer->type, - "Base system peripherals"); - break; - case 0x9: - strcpy(pci0ArrayPointer->type, - "Input Devices"); - break; - case 0xa: - strcpy(pci0ArrayPointer->type, - "Docking stations"); - break; - case 0xb: - strcpy(pci0ArrayPointer->type, - "Processors"); - break; - case 0xc: - strcpy(pci0ArrayPointer->type, - "Serial bus controllers"); - break; - case 0xd: - strcpy(pci0ArrayPointer->type, - "Wireless controllers"); - break; - case 0xe: - strcpy(pci0ArrayPointer->type, - "Intelligent I/O controllers"); - break; - case 0xf: - strcpy(pci0ArrayPointer->type, - "Satellite communication controllers"); - break; - case 0x10: - strcpy(pci0ArrayPointer->type, - "Encryption/Decryption controllers"); - break; - case 0x11: - strcpy(pci0ArrayPointer->type, - "Data acquisition and signal processing controllers"); - break; - default: - break; - - } - arrayCounter++; /* point to the next element in the Array. */ - if (arrayCounter == numberOfElment) - return; /* When the Array is fully used, return. */ - /* Else, points to next free Element. */ - pci0ArrayPointer = &pci0Detect[arrayCounter]; - } - } - pci0ArrayPointer->deviceNum = 0; /* 0 => End of List */ -} - - -/******************************************************************** -* pci1ScanDevices - This function scan PCI1 bus, if found any device on -* this bus it interrogate the Device for the information -* it can discover. -* The fields with all information are the following: -* char type[20]; -* unsigned int deviceNum; -* unsigned int venID; -* unsigned int deviceID; -* unsigned int bar0Base; -* unsigned int bar0Size; -* unsigned int bar1Base; -* unsigned int bar1Size; -* unsigned int bar2Base; -* unsigned int bar2Size; -* unsigned int bar3Base; -* unsigned int bar3Size; -* unsigned int bar4Base; -* unsigned int bar4Size; -* unsigned int bar5Base; -* unsigned int bar5Size; -* -* Inputs: Pointer to an array of STRUCT PCI1_DEVICE. -* Output: None. -*********************************************************************/ - -void pci1ScanDevices(PCI_DEVICE * pci1Detect, unsigned int numberOfElment) -{ - PCI_DEVICE *pci1ArrayPointer = pci1Detect; - unsigned int id; /* PCI Configuration register 0x0. */ - unsigned int device; /* device`s Counter. */ - unsigned int classCode; /* PCI Configuration register 0x8 */ - unsigned int arrayCounter = 0; - unsigned int memBaseAddress; - unsigned int memSize; - unsigned int c98RegValue; - - PCI1_MASTER_ENABLE(SELF); - /* According to PCI REV 2.1 MAX agents on the bus are -21- */ - for (device = 1; device < 22; device++) { - id = pci1ReadConfigReg(PCI_0DEVICE_AND_VENDOR_ID, device); - GT_REG_READ(HIGH_INTERRUPT_CAUSE_REGISTER, &c98RegValue); - /* Clearing bit 18 of in the High Cause Register 0xc98 */ - GT_REG_WRITE(HIGH_INTERRUPT_CAUSE_REGISTER, - c98RegValue & 0xfffbffff); - if ((id != 0xffffffff) && !(c98RegValue & 0x40000)) { - classCode = - pci1ReadConfigReg - (PCI_0CLASS_CODE_AND_REVISION_ID, device); - pci1ArrayPointer->deviceNum = device; - pci1ArrayPointer->venID = (id & 0xffff); - pci1ArrayPointer->deviceID = - ((id & 0xffff0000) >> 16); - - /* BAR0 parameters */ - memBaseAddress = pci1ReadConfigReg(BAR0, device); - pci1ArrayPointer->bar0Type = memBaseAddress & 1; - pci1ArrayPointer->bar0Base = - memBaseAddress & 0xfffff000; - pci1WriteConfigReg(BAR0, device, 0xffffffff); - memSize = pci1ReadConfigReg(BAR0, device); - if (memSize == 0) { /* case of an empty BAR */ - pci1ArrayPointer->bar0Size = 0; - } else { - if (pci1ArrayPointer->bar0Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci1ArrayPointer->bar0Size = memSize; - } - pci1WriteConfigReg(BAR0, device, memBaseAddress); - /* BAR1 parameters */ - memBaseAddress = pci1ReadConfigReg(BAR1, device); - pci1ArrayPointer->bar1Type = memBaseAddress & 1; - pci1ArrayPointer->bar1Base = - memBaseAddress & 0xfffff000; - pci1WriteConfigReg(BAR1, device, 0xffffffff); - memSize = pci1ReadConfigReg(BAR1, device); - if (memSize == 0) { /* case of an empty BAR */ - pci1ArrayPointer->bar1Size = 0; - } else { - if (pci1ArrayPointer->bar1Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci1ArrayPointer->bar1Size = memSize; - } - pci1WriteConfigReg(BAR1, device, memBaseAddress); - /* BAR2 parameters */ - memBaseAddress = pci1ReadConfigReg(BAR2, device); - pci1ArrayPointer->bar2Type = memBaseAddress & 1; - pci1ArrayPointer->bar2Base = - memBaseAddress & 0xfffff000; - pci1WriteConfigReg(BAR2, device, 0xffffffff); - memSize = pci1ReadConfigReg(BAR2, device); - if (memSize == 0) { /* case of an empty BAR */ - pci1ArrayPointer->bar2Size = 0; - } else { - if (pci1ArrayPointer->bar2Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci1ArrayPointer->bar2Size = memSize; - } - pci1WriteConfigReg(BAR2, device, memBaseAddress); - /* BAR3 parameters */ - memBaseAddress = pci1ReadConfigReg(BAR3, device); - pci1ArrayPointer->bar3Type = memBaseAddress & 1; - pci1ArrayPointer->bar3Base = - memBaseAddress & 0xfffff000; - pci1WriteConfigReg(BAR3, device, 0xffffffff); - memSize = pci1ReadConfigReg(BAR3, device); - if (memSize == 0) { /* case of an empty BAR */ - pci1ArrayPointer->bar3Size = 0; - } else { - if (pci1ArrayPointer->bar3Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci1ArrayPointer->bar3Size = memSize; - } - pci1WriteConfigReg(BAR3, device, memBaseAddress); - /* BAR4 parameters */ - memBaseAddress = pci1ReadConfigReg(BAR4, device); - pci1ArrayPointer->bar4Type = memBaseAddress & 1; - pci1ArrayPointer->bar4Base = - memBaseAddress & 0xfffff000; - pci1WriteConfigReg(BAR4, device, 0xffffffff); - memSize = pci1ReadConfigReg(BAR4, device); - if (memSize == 0) { /* case of an empty BAR */ - pci1ArrayPointer->bar4Size = 0; - } else { - if (pci1ArrayPointer->bar4Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci1ArrayPointer->bar4Size = memSize; - } - pci1WriteConfigReg(BAR4, device, memBaseAddress); - /* BAR5 parameters */ - memBaseAddress = pci1ReadConfigReg(BAR5, device); - pci1ArrayPointer->bar5Type = memBaseAddress & 1; - pci1ArrayPointer->bar5Base = - memBaseAddress & 0xfffff000; - pci1WriteConfigReg(BAR5, device, 0xffffffff); - memSize = pci1ReadConfigReg(BAR5, device); - if (memSize == 0) { /* case of an empty BAR */ - pci1ArrayPointer->bar5Size = 0; - } else { - if (pci1ArrayPointer->bar5Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci1ArrayPointer->bar5Size = memSize; - } - pci1WriteConfigReg(BAR5, device, memBaseAddress); - /* End of BARs Detection. */ - - classCode = ((classCode & 0xff000000) >> 24); - switch (classCode) { - case 0x0: - strcpy(pci1ArrayPointer->type, - "Old generation device"); - break; - case 0x1: - strcpy(pci1ArrayPointer->type, - "Mass storage controller"); - break; - case 0x2: - strcpy(pci1ArrayPointer->type, - "Network controller"); - break; - case 0x3: - strcpy(pci1ArrayPointer->type, - "Display controller"); - break; - case 0x4: - strcpy(pci1ArrayPointer->type, - "Multimedia device"); - break; - case 0x5: - strcpy(pci1ArrayPointer->type, - "Memory controller"); - break; - case 0x6: - strcpy(pci1ArrayPointer->type, - "Bridge Device"); - break; - case 0x7: - strcpy(pci1ArrayPointer->type, - "Simple Communication controllers"); - break; - case 0x8: - strcpy(pci1ArrayPointer->type, - "Base system peripherals"); - break; - case 0x9: - strcpy(pci1ArrayPointer->type, - "Input Devices"); - break; - case 0xa: - strcpy(pci1ArrayPointer->type, - "Docking stations"); - break; - case 0xb: - strcpy(pci1ArrayPointer->type, - "Processors"); - break; - case 0xc: - strcpy(pci1ArrayPointer->type, - "Serial bus controllers"); - break; - case 0xd: - strcpy(pci1ArrayPointer->type, - "Wireless controllers"); - break; - case 0xe: - strcpy(pci1ArrayPointer->type, - "Intelligent I/O controllers"); - break; - case 0xf: - strcpy(pci1ArrayPointer->type, - "Satellite communication controllers"); - break; - case 0x10: - strcpy(pci1ArrayPointer->type, - "Encryption/Decryption controllers"); - break; - case 0x11: - strcpy(pci1ArrayPointer->type, - "Data acquisition and signal processing controllers"); - break; - } - arrayCounter++; /* point to the next element in the Array. */ - if (arrayCounter == numberOfElment) - return; /* When the Array is fully used, return. */ - /* Else, points to next free Element. */ - pci1ArrayPointer = &pci1Detect[arrayCounter]; - } - } - pci1ArrayPointer->deviceNum = 0; /* 0 => End of List */ -} - -/******************************************************************** -* pci0WriteConfigReg - 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 -* -*********************************************************************/ - -void pci0WriteConfigReg(unsigned int regOffset, unsigned int pciDevNum, - unsigned int data) -{ - unsigned int DataForRegCf8; - unsigned int functionNum; - - functionNum = regOffset & 0x00000700; - pciDevNum = pciDevNum << 11; - regOffset = regOffset & 0x0fffffff; - DataForRegCf8 = (regOffset | pciDevNum | functionNum) | BIT31; - GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS, DataForRegCf8); - if (pciDevNum == SELF) { /* This board */ - GT_REG_WRITE(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER, - data); - } else { /* configuration Transaction over the pci. */ - - /* The PCI is working in LE Mode So it swap the Data. */ - GT_REG_WRITE(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER, - WORDSWAP(data)); - } -} - -/******************************************************************** -* pci1WriteConfigReg - Write to a PCI configuration register -* - Make sure the GT is configured as a master before writing -* to 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 -* -*********************************************************************/ - -void pci1WriteConfigReg(unsigned int regOffset, unsigned int pciDevNum, - unsigned int data) -{ - unsigned int DataForRegCf8; - unsigned int functionNum; - - functionNum = regOffset & 0x00000700; - pciDevNum = pciDevNum << 11; - regOffset = regOffset & 0x0fffffff; - if (pciDevNum == 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 = - (regOffset | pciDevNum | functionNum | 0x80) | BIT31; - GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS, DataForRegCf8); - } else { - DataForRegCf8 = - (regOffset | pciDevNum | functionNum) | BIT31; - GT_REG_WRITE(PCI_1CONFIGURATION_ADDRESS, DataForRegCf8); - } - if (pciDevNum == SELF) { /* This board */ - GT_REG_WRITE(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER, - data); - } else { - GT_REG_WRITE(PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER, - WORDSWAP(data)); - } -} - -/******************************************************************** -* pci0ReadConfigReg - Read from a PCI0 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 -* -*********************************************************************/ - -unsigned int pci0ReadConfigReg(unsigned int regOffset, - unsigned int pciDevNum) -{ - unsigned int DataForRegCf8; - unsigned int data; - unsigned int functionNum; - - functionNum = regOffset & 0x00000700; - pciDevNum = pciDevNum << 11; - regOffset = regOffset & 0x0fffffff; - DataForRegCf8 = (regOffset | pciDevNum | functionNum) | BIT31; - GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS, DataForRegCf8); - if (pciDevNum == SELF) { /* This board */ - GT_REG_READ(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER, - &data); - return data; - } else { /* The PCI is working in LE Mode So it swap the Data. */ - - GT_REG_READ(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER, - &data); - return WORDSWAP(data); - } -} - -/******************************************************************** -* pci1ReadConfigReg - Read from a PCI1 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 -* -*********************************************************************/ - -unsigned int pci1ReadConfigReg(unsigned int regOffset, - unsigned int pciDevNum) -{ - unsigned int DataForRegCf8; - unsigned int data; - unsigned int functionNum; - - functionNum = regOffset & 0x00000700; - pciDevNum = pciDevNum << 11; - regOffset = regOffset & 0x0fffffff; - if (pciDevNum == 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 = - (regOffset | pciDevNum | functionNum | 0x80) | BIT31; - GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS, DataForRegCf8); - } else { - DataForRegCf8 = - (regOffset | pciDevNum | functionNum) | BIT31; - GT_REG_WRITE(PCI_1CONFIGURATION_ADDRESS, DataForRegCf8); - } - if (pciDevNum == SELF) { /* This board */ - GT_REG_READ(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER, - &data); - return data; - } else { - GT_REG_READ(PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER, - &data); - return WORDSWAP(data); - } -} - -/******************************************************************** -* pci0MapIOspace - Maps PCI0 IO space for the master. -* Inputs: base and length of pci0Io -*********************************************************************/ - -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_REG_WRITE(PCI_0I_O_LOW_DECODE_ADDRESS, pci0IoBase); - GT_REG_WRITE(PCI_0I_O_HIGH_DECODE_ADDRESS, pci0IoTop); -} - -/******************************************************************** -* pci1MapIOspace - Maps PCI1 IO space for the master. -* Inputs: base and length of pci1Io -*********************************************************************/ - -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_REG_WRITE(PCI_1I_O_LOW_DECODE_ADDRESS, pci1IoBase); - GT_REG_WRITE(PCI_1I_O_HIGH_DECODE_ADDRESS, pci1IoTop); -} - -/******************************************************************** -* pci0MapMemory0space - Maps PCI0 memory0 space for the master. -* Inputs: base and length of pci0Mem0 -*********************************************************************/ - - -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_REG_WRITE(PCI_0MEMORY0_LOW_DECODE_ADDRESS, pci0Mem0Base); - GT_REG_WRITE(PCI_0MEMORY0_HIGH_DECODE_ADDRESS, pci0Mem0Top); -} - -/******************************************************************** -* pci1MapMemory0space - Maps PCI1 memory0 space for the master. -* Inputs: base and length of pci1Mem0 -*********************************************************************/ - -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_REG_WRITE(PCI_1MEMORY0_LOW_DECODE_ADDRESS, pci1Mem0Base); - GT_REG_WRITE(PCI_1MEMORY0_HIGH_DECODE_ADDRESS, pci1Mem0Top); -} - -/******************************************************************** -* pci0MapMemory1space - Maps PCI0 memory1 space for the master. -* Inputs: base and length of pci0Mem1 -*********************************************************************/ - -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_REG_WRITE(PCI_0MEMORY1_LOW_DECODE_ADDRESS, pci0Mem1Base); - GT_REG_WRITE(PCI_0MEMORY1_HIGH_DECODE_ADDRESS, pci0Mem1Top); -#ifndef PROM - DBG(KERN_INFO "pci0Mem1Base %x\n", pci0Mem1Base); - DBG(KERN_INFO "pci0Mem1Top %x\n", pci0Mem1Top); - GT_REG_READ(PCI_0MEMORY0_ADDRESS_REMAP, &pci0Mem1Base); - DBG(KERN_INFO "Mem 0/0 remap %x\n", pci0Mem1Base); - GT_REG_READ(PCI_0MEMORY1_ADDRESS_REMAP, &pci0Mem1Base); - DBG(KERN_INFO "Mem 0/1 remap %x\n", pci0Mem1Base); - GT_REG_WRITE(PCI_0MEMORY1_ADDRESS_REMAP, 0x500); - GT_REG_READ(PCI_0MEMORY1_ADDRESS_REMAP, &pci0Mem1Base); - DBG(KERN_INFO "Mem 0/1 remapped %x\n", pci0Mem1Base); -#endif -} - -/******************************************************************** -* pci1MapMemory1space - Maps PCI1 memory1 space for the master. -* Inputs: base and length of pci1Mem1 -*********************************************************************/ - -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_REG_WRITE(PCI_1MEMORY1_LOW_DECODE_ADDRESS, pci1Mem1Base); - GT_REG_WRITE(PCI_1MEMORY1_HIGH_DECODE_ADDRESS, pci1Mem1Top); -} - -/******************************************************************** -* pci0GetIOspaceBase - Return PCI0 IO Base Address. -* Inputs: N/A -* Returns: PCI0 IO Base Address. -*********************************************************************/ - -unsigned int pci0GetIOspaceBase() -{ - unsigned int base; - GT_REG_READ(PCI_0I_O_LOW_DECODE_ADDRESS, &base); - base = base << 21; - return base; -} - -/******************************************************************** -* pci0GetIOspaceSize - Return PCI0 IO Bar Size. -* Inputs: N/A -* Returns: PCI0 IO Bar Size. -*********************************************************************/ - -unsigned int pci0GetIOspaceSize() -{ - unsigned int top, base, size; - GT_REG_READ(PCI_0I_O_LOW_DECODE_ADDRESS, &base); - base = base << 21; - GT_REG_READ(PCI_0I_O_HIGH_DECODE_ADDRESS, &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. -*********************************************************************/ - -unsigned int pci0GetMemory0Base() -{ - unsigned int base; - GT_REG_READ(PCI_0MEMORY0_LOW_DECODE_ADDRESS, &base); - base = base << 21; - return base; -} - -/******************************************************************** -* pci0GetMemory0Size - Return PCI0 Memory 0 Bar Size. -* Inputs: N/A -* Returns: PCI0 Memory 0 Bar Size. -*********************************************************************/ - -unsigned int pci0GetMemory0Size() -{ - unsigned int top, base, size; - GT_REG_READ(PCI_0MEMORY0_LOW_DECODE_ADDRESS, &base); - base = base << 21; - GT_REG_READ(PCI_0MEMORY0_HIGH_DECODE_ADDRESS, &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. -*********************************************************************/ - -unsigned int pci0GetMemory1Base() -{ - unsigned int base; - GT_REG_READ(PCI_0MEMORY1_LOW_DECODE_ADDRESS, &base); - base = base << 21; - return base; -} - -/******************************************************************** -* pci0GetMemory1Size - Return PCI0 Memory 1 Bar Size. -* Inputs: N/A -* Returns: PCI0 Memory 1 Bar Size. -*********************************************************************/ - -unsigned int pci0GetMemory1Size() -{ - unsigned int top, base, size; - GT_REG_READ(PCI_0MEMORY1_LOW_DECODE_ADDRESS, &base); - base = base << 21; - GT_REG_READ(PCI_0MEMORY1_HIGH_DECODE_ADDRESS, &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. -*********************************************************************/ - -unsigned int pci1GetIOspaceBase() -{ - unsigned int base; - GT_REG_READ(PCI_1I_O_LOW_DECODE_ADDRESS, &base); - base = base << 21; - return base; -} - -/******************************************************************** -* pci1GetIOspaceSize - Return PCI1 IO Bar Size. -* Inputs: N/A -* Returns: PCI1 IO Bar Size. -*********************************************************************/ - -unsigned int pci1GetIOspaceSize() -{ - unsigned int top, base, size; - GT_REG_READ(PCI_1I_O_LOW_DECODE_ADDRESS, &base); - base = base << 21; - GT_REG_READ(PCI_1I_O_HIGH_DECODE_ADDRESS, &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. -*********************************************************************/ - -unsigned int pci1GetMemory0Base() -{ - unsigned int base; - GT_REG_READ(PCI_1MEMORY0_LOW_DECODE_ADDRESS, &base); - base = base << 21; - return base; -} - -/******************************************************************** -* pci1GetMemory0Size - Return PCI1 Memory 0 Bar Size. -* Inputs: N/A -* Returns: PCI1 Memory 0 Bar Size. -*********************************************************************/ - -unsigned int pci1GetMemory0Size() -{ - unsigned int top, base, size; - GT_REG_READ(PCI_1MEMORY1_LOW_DECODE_ADDRESS, &base); - base = base << 21; - GT_REG_READ(PCI_1MEMORY1_HIGH_DECODE_ADDRESS, &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. -*********************************************************************/ - -unsigned int pci1GetMemory1Base() -{ - unsigned int base; - GT_REG_READ(PCI_1MEMORY1_LOW_DECODE_ADDRESS, &base); - base = base << 21; - return base; -} - -/******************************************************************** -* pci1GetMemory1Size - Return PCI1 Memory 1 Bar Size. -* Inputs: N/A -* Returns: PCI1 Memory 1 Bar Size. -*********************************************************************/ - -unsigned int pci1GetMemory1Size() -{ - unsigned int top, base, size; - GT_REG_READ(PCI_1MEMORY1_LOW_DECODE_ADDRESS, &base); - base = base << 21; - GT_REG_READ(PCI_1MEMORY1_HIGH_DECODE_ADDRESS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/******************************************************************** -* pci0MapInternalRegSpace - Maps the internal registers memory space for the -* slave. -* Stays the same for all GT devices Disco include -* Inputs: base of pci0 internal register -*********************************************************************/ - -void pci0MapInternalRegSpace(unsigned int pci0InternalBase) -{ - pci0InternalBase = pci0InternalBase & 0xfffff000; - pci0InternalBase = - pci0InternalBase | - (pci0ReadConfigReg - (PCI_0INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS, - SELF) & 0x00000fff); - pci0WriteConfigReg - (PCI_0INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS, SELF, - pci0InternalBase); -} - -/******************************************************************** -* pci1MapInternalRegSpace - Maps the internal registers memory space for the -* slave. -* Stays the same for all GT devices Disco include -* Inputs: base of pci1 internal register -*********************************************************************/ - -void pci1MapInternalRegSpace(unsigned int pci1InternalBase) -{ - pci1InternalBase = pci1InternalBase & 0xfffff000; - pci1InternalBase = - pci1InternalBase | - (pci1ReadConfigReg - (PCI_0INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS, - SELF) & 0x00000fff); - pci1WriteConfigReg - (PCI_0INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS, SELF, - pci1InternalBase); -} - -/******************************************************************** -* pci0MapInternalRegIOSpace - Maps the internal registers IO space for the -* slave. -* Stays the same for all GT devices Disco include -* Inputs: base of pci0 internal io register -*********************************************************************/ - -void pci0MapInternalRegIOSpace(unsigned int pci0InternalBase) -{ - pci0InternalBase = pci0InternalBase & 0xfffff000; - pci0InternalBase = - pci0InternalBase | - (pci0ReadConfigReg - (PCI_0INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS, - 0) & 0x00000fff); - pci0WriteConfigReg(PCI_0INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS, - SELF, pci0InternalBase); -} - -/******************************************************************** -* pci0MapInternalRegIOSpace - Maps the internal registers IO space for the -* slave. -* Stays the same for all GT devices Disco include -* Inputs: base of pci1 internal io register -*********************************************************************/ - -void pci1MapInternalRegIOSpace(unsigned int pci1InternalBase) -{ - pci1InternalBase = pci1InternalBase & 0xfffff000; - pci1InternalBase = - pci1InternalBase | - (pci1ReadConfigReg - (PCI_0INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS, - SELF) & 0x00000fff); - pci1WriteConfigReg(PCI_0INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS, - SELF, pci1InternalBase); -} - -/******************************************************************** -* pci0MapMemoryBanks0_1 - Maps PCI0 memory banks 0 and 1 for the slave. -* for Discovery we need two function: SCS0 & SCS1 -* (instead of SCS[1:0]) -* Inputs: base and size of pci0 dram -*********************************************************************/ - - -void pci0MapMemoryBanks0_1(unsigned int pci0Dram0_1Base, - unsigned int pci0Dram0_1Size) -{ - pci0Dram0_1Base = pci0Dram0_1Base & 0xfffff000; - pci0Dram0_1Base = - pci0Dram0_1Base | - (pci0ReadConfigReg(PCI_0SCS_1_0_BASE_ADDRESS, SELF) & - 0x00000fff); - pci0WriteConfigReg(PCI_0SCS_1_0_BASE_ADDRESS, SELF, - pci0Dram0_1Base); - /* swapped Bar */ - pci0WriteConfigReg(PCI_0SWAPPED_SCS_1_0_BASE_ADDRESS, SELF, - pci0Dram0_1Base); - if (pci0Dram0_1Size == 0) - pci0Dram0_1Size++; - GT_REG_WRITE(PCI_0SCS_1_0_BANK_SIZE, pci0Dram0_1Size - 1); -} - -/******************************************************************** -* pci1MapMemoryBanks0_1 - Maps PCI1 memory banks 0 and 1 for the slave. -* for Discovery we need two function: SCS0 & SCS1 -* (instead of SCS[1:0]) -* Inputs: base and size of pci1 dram -*********************************************************************/ - -void pci1MapMemoryBanks0_1(unsigned int pci1Dram0_1Base, - unsigned int pci1Dram0_1Size) -{ - pci1Dram0_1Base = pci1Dram0_1Base & 0xfffff000; - pci1Dram0_1Base = - pci1Dram0_1Base | - (pci1ReadConfigReg(PCI_0SCS_1_0_BASE_ADDRESS, SELF) & - 0x00000fff); - pci1WriteConfigReg(PCI_0SCS_1_0_BASE_ADDRESS, SELF, - pci1Dram0_1Base); - /* swapped Bar */ - pci1WriteConfigReg(PCI_0SWAPPED_SCS_1_0_BASE_ADDRESS, SELF, - pci1Dram0_1Base); - if (pci1Dram0_1Size == 0) - pci1Dram0_1Size++; - GT_REG_WRITE(PCI_1SCS_1_0_BANK_SIZE, pci1Dram0_1Size - 1); -} - -/******************************************************************** -* pci0MapMemoryBanks2_3 - Maps PCI0 memory banks 2 and 3 for the slave. -* for Discovery we need two function: SCS2 & SCS3 -* (instead of SCS[3:2]) -* Inputs: base and size of pci0 dram -*********************************************************************/ - -void pci0MapMemoryBanks2_3(unsigned int pci0Dram2_3Base, - unsigned int pci0Dram2_3Size) -{ - pci0Dram2_3Base = pci0Dram2_3Base & 0xfffff000; - pci0Dram2_3Base = - pci0Dram2_3Base | - (pci0ReadConfigReg(PCI_0SCS_3_2_BASE_ADDRESS, SELF) & - 0x00000fff); - pci0WriteConfigReg(PCI_0SCS_3_2_BASE_ADDRESS, SELF, - pci0Dram2_3Base); - /* swapped Bar */ - pci0WriteConfigReg(PCI_0SWAPPED_SCS_3_2_BASE_ADDRESS, SELF, - pci0Dram2_3Base); - if (pci0Dram2_3Size == 0) - pci0Dram2_3Size++; - GT_REG_WRITE(PCI_0SCS_3_2_BANK_SIZE, pci0Dram2_3Size - 1); -} - -/******************************************************************** -* pci1MapMemoryBanks2_3 - Maps PCI1 memory banks 2 and 3 for the slave. -* for Discovery we need two function: SCS2 & SCS3 -* (instead of SCS[3:2]) -* Inputs: base and size of pci1 dram -*********************************************************************/ - -void pci1MapMemoryBanks2_3(unsigned int pci1Dram2_3Base, - unsigned int pci1Dram2_3Size) -{ - pci1Dram2_3Base = pci1Dram2_3Base & 0xfffff000; - pci1Dram2_3Base = - pci1Dram2_3Base | - (pci1ReadConfigReg(PCI_0SCS_3_2_BASE_ADDRESS, SELF) & - 0x00000fff); - pci1WriteConfigReg(PCI_0SCS_3_2_BASE_ADDRESS, SELF, - pci1Dram2_3Base); - /* swapped Bar */ - pci1WriteConfigReg(PCI_0SWAPPED_SCS_3_2_BASE_ADDRESS, SELF, - pci1Dram2_3Base); - if (pci1Dram2_3Size == 0) - pci1Dram2_3Size++; - GT_REG_WRITE(PCI_1SCS_3_2_BANK_SIZE, pci1Dram2_3Size - 1); -} - -/******************************************************************** -* pci0MapDevices0_1and2MemorySpace - Maps PCI0 devices 0,1 and 2 memory spaces -* for the slave. -* For the Discovery there are 3 separate -* fucnction's -* Inputs: base and lengthof pci0 devises012 -*********************************************************************/ - - -void pci0MapDevices0_1and2MemorySpace(unsigned int pci0Dev012Base, - unsigned int pci0Dev012Length) -{ - pci0Dev012Base = pci0Dev012Base & 0xfffff000; - pci0Dev012Base = - pci0Dev012Base | - (pci0ReadConfigReg(PCI_0CS_2_0_BASE_ADDRESS, SELF) & - 0x00000fff); - pci0WriteConfigReg(PCI_0CS_2_0_BASE_ADDRESS, SELF, pci0Dev012Base); - if (pci0Dev012Length == 0) - pci0Dev012Length++; - GT_REG_WRITE(PCI_0CS_2_0_BANK_SIZE, pci0Dev012Length - 1); -} - -/******************************************************************** -* pci1MapDevices0_1and2MemorySpace - Maps PCI1 devices 0,1 and 2 memory spaces -* for the slave. -* For the Discovery there are 3 separate -* fucnction's -* Inputs: base and lengthof pci1 devises012 -*********************************************************************/ - -void pci1MapDevices0_1and2MemorySpace(unsigned int pci1Dev012Base, - unsigned int pci1Dev012Length) -{ - pci1Dev012Base = pci1Dev012Base & 0xfffff000; - pci1Dev012Base = - pci1Dev012Base | - (pci1ReadConfigReg(PCI_0CS_2_0_BASE_ADDRESS, SELF) & - 0x00000fff); - pci1WriteConfigReg(PCI_0CS_2_0_BASE_ADDRESS, SELF, pci1Dev012Base); - if (pci1Dev012Length == 0) - pci1Dev012Length++; - GT_REG_WRITE(PCI_1CS_2_0_BANK_SIZE, pci1Dev012Length - 1); -} - -/******************************************************************** -* pci0MapDevices3andBootMemorySpace - Maps PCI0 devices 3 and boot memory -* spaces for the slave. -* For the Discovery there are 2 separate -* fucnction's -* Inputs: base and length of pci0 device3/ boot -*********************************************************************/ - -void pci0MapDevices3andBootMemorySpace(unsigned int pci0Dev3andBootBase, - unsigned int pci0Dev3andBootLength) -{ - pci0Dev3andBootBase = pci0Dev3andBootBase & 0xfffff000; - pci0Dev3andBootBase = - pci0Dev3andBootBase | - (pci0ReadConfigReg(PCI_0CS_3_BOOTCS_BASE_ADDRESS, SELF) & - 0x00000fff); - pci0WriteConfigReg(PCI_0CS_3_BOOTCS_BASE_ADDRESS, SELF, - pci0Dev3andBootBase); - /* swapped Bar */ - pci0WriteConfigReg(PCI_0SWAPPED_CS_3_BOOTCS_BASE_ADDRESS, SELF, - pci0Dev3andBootBase); - if (pci0Dev3andBootLength == 0) - pci0Dev3andBootLength++; - GT_REG_WRITE(PCI_0CS_3_BOOTCS_BANK_SIZE, - pci0Dev3andBootLength - 1); -} - -/******************************************************************** -* pci1MapDevices3andBootMemorySpace - Maps PCI1 devices 3 and boot memory -* spaces for the slave. -* For the Discovery there are 2 separate -* fucnction's -* Inputs: base and length of pci1 device3/ boot -*********************************************************************/ - -void pci1MapDevices3andBootMemorySpace(unsigned int pci1Dev3andBootBase, - unsigned int pci1Dev3andBootLength) -{ - pci1Dev3andBootBase = pci1Dev3andBootBase & 0xfffff000; - pci1Dev3andBootBase = - pci1Dev3andBootBase | - (pci1ReadConfigReg(PCI_0CS_3_BOOTCS_BASE_ADDRESS, SELF) & - 0x00000fff); - pci1WriteConfigReg(PCI_0CS_3_BOOTCS_BASE_ADDRESS, SELF, - pci1Dev3andBootBase); - /* swapped Bar */ - pci1WriteConfigReg(PCI_0SWAPPED_CS_3_BOOTCS_BASE_ADDRESS, SELF, - pci1Dev3andBootBase); - if (pci1Dev3andBootLength == 0) - pci1Dev3andBootLength++; - GT_REG_WRITE(PCI_1CS_3_BOOTCS_BANK_SIZE, - pci1Dev3andBootLength - 1); -} Index: arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c diff -N arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c --- arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,318 +0,0 @@ -/* - * This program is free software; you can redistribute 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 "etherboot.h" -#include "pci_etherboot.h" -#include "galileo_port.h" - -#define MAX_PCI_DEVS 10 -PCI_DEVICE pci0_devices[MAX_PCI_DEVS]; -PCI_DEVICE pci1_devices[MAX_PCI_DEVS]; - -static int pci_range_ck(unsigned char bus, unsigned char dev) -{ - if ((bus == 0) && (dev >= 0) && (dev < 30)) - return 0; // Bus/Device Number OK - - return -1; // Bus/Device Number not OK -} - -/******************************************************************** - * pcibios_(read/write)_config_(byte/word/dword) - * - *Inputs : - *bus - bus number - *dev - device number - *offset - register offset in the configuration space - *val - value to be written / read - * - *Outputs : - *Sucees/Failure - *********************************************************************/ -#define PCI_CFG_DATA ((volatile unsigned long *)0xb4000cfc) -#define PCI_CFG_CTRL ((volatile unsigned long *)0xb4000cf8) - -#define PCI_CFG_SET(dev,fun,off) \ - ((*PCI_CFG_CTRL) = cpu_to_le32((0x80000000 | ((dev)<<11) | ((fun)<<8) | (off)))) - -int pcibios_read_config_dword(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned int *val) -{ - - if (offset & 0x3) { - return PCIBIOS_BAD_REGISTER_NUMBER; - } - if (pci_range_ck(bus, dev)) { - *val = 0xFFFFFFFF; - return PCIBIOS_DEVICE_NOT_FOUND; - } - PCI_CFG_SET(dev, 0, offset); - if (dev != 0) { - *val = *PCI_CFG_DATA; - } else { - *val = cpu_to_le32(*PCI_CFG_DATA); - } - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_read_config_word(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned short *val) -{ - if (offset & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (pci_range_ck(bus, dev)) { - *val = 0xffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - PCI_CFG_SET(dev, 0, (offset & ~0x3)); - if (dev != 0) { - *val = *PCI_CFG_DATA >> ((offset & 3) * 8); - } else { - *val = cpu_to_le32(*PCI_CFG_DATA) >> ((offset & 3) * 8); - } - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_read_config_byte(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned char *val) -{ - if (pci_range_ck(bus, dev)) { - *val = 0xff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - PCI_CFG_SET(dev, 0, (offset & ~0x3)); - if (dev != 0) { - *val = *PCI_CFG_DATA >> ((offset & 3) * 8); - } else { - *val = cpu_to_le32(*PCI_CFG_DATA >> ((offset & 3) * 8)); - } - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_write_config_dword(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned int val) -{ - if (offset & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - PCI_CFG_SET(dev, 0, offset); - if (dev != 0) { - *PCI_CFG_DATA = val; - } else { - *PCI_CFG_DATA = cpu_to_le32(val); - } - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_write_config_word(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned short val) -{ - unsigned long tmp; - - if (offset & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - PCI_CFG_SET(dev, 0, (offset & ~0x3)); - if (dev != 0) { - tmp = *PCI_CFG_DATA; - } else { - tmp = cpu_to_le32(*PCI_CFG_DATA); - } - tmp &= ~(0xffff << ((offset & 0x3) * 8)); - tmp |= (val << ((offset & 0x3) * 8)); - if (dev != 0) { - *PCI_CFG_DATA = tmp; - } else { - *PCI_CFG_DATA = cpu_to_le32(tmp); - } - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_write_config_byte(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned char val) -{ - unsigned long tmp; - - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - PCI_CFG_SET(dev, 0, (offset & ~0x3)); - if (dev != 0) { - tmp = *PCI_CFG_DATA; - } else { - tmp = cpu_to_le32(*PCI_CFG_DATA); - } - tmp &= ~(0xff << ((offset & 0x3) * 8)); - tmp |= (val << ((offset & 0x3) * 8)); - *PCI_CFG_DATA = cpu_to_le32(tmp); - return PCIBIOS_SUCCESSFUL; -} - - -/******************************************************************** - * eth_pci_init - Fill pci_devi - * - *Inputs : - *bus - bus number - *dev - device number - *offset - register offset in the configuration space - *val - value to be written / read - * - *Outputs : - *Sucees/Failure - *********************************************************************/ -void eth_pci_init(struct pci_device *pcidev) -{ - int i, count; - pcibios_write_config_word(0, 0, 4, 0x7); - pcibios_write_config_dword(0, 8, BAR0, 0x12000000); - pcibios_write_config_dword(0, 8, BAR1, 0x10000001); - pcibios_write_config_dword(0, 8, BAR2, 0x12100000); - strcpy(pci0_devices[0].type, "Network Controller"); - pci0_devices[0].deviceNum = 8; - pci0_devices[0].venID = 0x8086; - pci0_devices[0].deviceID = 0x1229; - - pci0_devices[0].bar0Base = 0x12000000; - pci0_devices[0].bar0Size = 0x00001000; - pci0_devices[0].bar0Type = 0; - pci0_devices[0].bar1Base = 0x10000000; - pci0_devices[0].bar1Size = 0x40; - pci0_devices[0].bar1Type = 1; - pci0_devices[0].bar2Base = 0x12100000; - pci0_devices[0].bar2Size = 0x00100000; - pci0_devices[0].bar2Type = 0; - for (i = 0; pcidev[i].vendor != 0; i++) { - /* Look for device in PCI0 first */ - for (count = 0; count < MAX_PCI_DEVS; count++) { - if ((pci0_devices[count].type[0] != 0) - && ((unsigned short) pci0_devices[count]. - venID == (unsigned short) pcidev[i].vendor) - && ((unsigned short) pci0_devices[count]. - deviceID == - (unsigned short) pcidev[i].dev_id)) { - if ((pci0_devices[count].bar0Type == 1) - && (pci0_devices[count].bar0Size != 0)) - pcidev[i].ioaddr = - pci0_devices[count].bar0Base; - if ((pci0_devices[count].bar1Type == 1) - && (pci0_devices[count].bar1Size != 0)) - pcidev[i].ioaddr = - pci0_devices[count].bar1Base; - if ((pci0_devices[count].bar2Type == 1) - && (pci0_devices[count].bar2Size != 0)) - pcidev[i].ioaddr = - pci0_devices[count].bar2Base; - if ((pci0_devices[count].bar3Type == 1) - && (pci0_devices[count].bar3Size != 0)) - pcidev[i].ioaddr = - pci0_devices[count].bar3Base; - if ((pci0_devices[count].bar4Type == 1) - && (pci0_devices[count].bar4Size != 0)) - pcidev[i].ioaddr = - pci0_devices[count].bar4Base; - if ((pci0_devices[count].bar5Type == 1) - && (pci0_devices[count].bar5Size != 0)) - pcidev[i].ioaddr = - pci0_devices[count].bar5Base; - - if ((pci0_devices[count].bar0Type == 0) - && (pci0_devices[count].bar0Size != 0)) - pcidev[i].membase = - pci0_devices[count].bar0Base; - if ((pci0_devices[count].bar1Type == 0) - && (pci0_devices[count].bar1Size != 0)) - pcidev[i].membase = - pci0_devices[count].bar1Base; - if ((pci0_devices[count].bar2Type == 0) - && (pci0_devices[count].bar2Size != 0)) - pcidev[i].membase = - pci0_devices[count].bar2Base; - if ((pci0_devices[count].bar3Type == 0) - && (pci0_devices[count].bar3Size != 0)) - pcidev[i].membase = - pci0_devices[count].bar3Base; - if ((pci0_devices[count].bar4Type == 0) - && (pci0_devices[count].bar4Size != 0)) - pcidev[i].membase = - pci0_devices[count].bar4Base; - if ((pci0_devices[count].bar5Type == 0) - && (pci0_devices[count].bar5Size != 0)) - pcidev[i].membase = - pci0_devices[count].bar5Base; - pcidev[i].bus = 0; - pcidev[i].devfn = - pci0_devices[count].deviceNum; - } -#ifdef CONFIG_EVB_PCI1 - if ((pci1_devices[count].type[0] != 0) - && (pci1_devices[count].venID == - pcidev[i].vendor) - && (pci1_devices[count].deviceID == - pcidev[i].dev_id)) { - if ((pci1_devices[count].bar0Type == 1) - && (pci1_devices[count].bar0Size != 0)) - pcidev[i].ioaddr = - pci1_devices[count].bar0Base; - if ((pci1_devices[count].bar1Type == 1) - && (pci1_devices[count].bar1Size != 0)) - pcidev[i].ioaddr = - pci1_devices[count].bar1Base; - if ((pci1_devices[count].bar2Type == 1) - && (pci1_devices[count].bar2Size != 0)) - pcidev[i].ioaddr = - pci1_devices[count].bar2Base; - if ((pci1_devices[count].bar3Type == 1) - && (pci1_devices[count].bar3Size != 0)) - pcidev[i].ioaddr = - pci1_devices[count].bar3Base; - if ((pci1_devices[count].bar4Type == 1) - && (pci1_devices[count].bar4Size != 0)) - pcidev[i].ioaddr = - pci1_devices[count].bar4Base; - if ((pci1_devices[count].bar5Type == 1) - && (pci1_devices[count].bar5Size != 0)) - pcidev[i].ioaddr = - pci1_devices[count].bar5Base; - - if ((pci1_devices[count].bar0Type == 0) - && (pci1_devices[count].bar0Size != 0)) - pcidev[i].membase = - pci1_devices[count].bar0Base; - if ((pci1_devices[count].bar1Type == 0) - && (pci1_devices[count].bar1Size != 0)) - pcidev[i].membase = - pci1_devices[count].bar1Base; - if ((pci1_devices[count].bar2Type == 0) - && (pci1_devices[count].bar2Size != 0)) - pcidev[i].membase = - pci1_devices[count].bar2Base; - if ((pci1_devices[count].bar3Type == 0) - && (pci1_devices[count].bar3Size != 0)) - pcidev[i].membase = - pci1_devices[count].bar3Base; - if ((pci1_devices[count].bar4Type == 0) - && (pci1_devices[count].bar4Size != 0)) - pcidev[i].membase = - pci1_devices[count].bar4Base; - if ((pci1_devices[count].bar5Type == 0) - && (pci1_devices[count].bar5Size != 0)) - pcidev[i].membase = - pci1_devices[count].bar5Base; - - pcidev[i].bus = 1; - pcidev[i].devfn = - pci1_devices[count].deviceNum; - } -#endif - } - } -} Index: arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.h =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.h diff -N arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.h --- arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.h 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,144 +0,0 @@ -#ifndef PCI_H -#define PCI_H - -/* -** Support for NE2000 PCI clones added David Monro June 1997 -** Generalised for other PCI NICs by Ken Yap July 1997 -** -** Most of this is taken from: -** -** /usr/src/linux/drivers/pci/pci.c -** /usr/src/linux/include/linux/pci.h -** /usr/src/linux/arch/i386/bios32.c -** /usr/src/linux/include/linux/bios32.h -** /usr/src/linux/drivers/net/ne.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, or (at - * your option) any later version. - */ - -#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */ -#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */ -#define PCI_LATENCY_TIMER 0x0d /* 8 bits */ - - -#define PCI_VENDOR_ID 0x00 /* 16 bits */ -#define PCI_DEVICE_ID 0x02 /* 16 bits */ -#define PCI_COMMAND 0x04 /* 16 bits */ - -#define PCI_CLASS_CODE 0x0b /* 8 bits */ -#define PCI_SUBCLASS_CODE 0x0a /* 8 bits */ -#define PCI_HEADER_TYPE 0x0e /* 8 bits */ - -#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */ -#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits */ -#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits */ -#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */ -#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */ -#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */ - -#ifndef PCI_BASE_ADDRESS_IO_MASK -#define PCI_BASE_ADDRESS_IO_MASK (~0x03) -#endif -#define PCI_BASE_ADDRESS_SPACE_IO 0x01 -#define PCI_ROM_ADDRESS 0x30 /* 32 bits */ -#define PCI_ROM_ADDRESS_ENABLE 0x01 /* Write 1 to enable ROM, - bits 31..11 are address, - 10..2 are reserved */ - -#define PCI_FUNC(devfn) ((devfn) & 0x07) - -#define BIOS32_SIGNATURE (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24)) - -/* PCI signature: "PCI " */ -#define PCI_SIGNATURE (('P' << 0) + ('C' << 8) + ('I' << 16) + (' ' << 24)) - -/* PCI service signature: "$PCI" */ -#define PCI_SERVICE (('$' << 0) + ('P' << 8) + ('C' << 16) + ('I' << 24)) - -#define KERN_CODE_SEG 0x8 /* This _MUST_ match start.S */ - -#define PCI_VENDOR_ID_REALTEK 0x10ec -#define PCI_DEVICE_ID_REALTEK_8029 0x8029 -#define PCI_DEVICE_ID_REALTEK_8139 0x8139 -#define PCI_VENDOR_ID_WINBOND2 0x1050 -#define PCI_DEVICE_ID_WINBOND2_89C940 0x0940 -#define PCI_VENDOR_ID_COMPEX 0x11f6 -#define PCI_DEVICE_ID_COMPEX_RL2000 0x1401 -#define PCI_VENDOR_ID_KTI 0x8e2e -#define PCI_DEVICE_ID_KTI_ET32P2 0x3000 -#define PCI_VENDOR_ID_NETVIN 0x4a14 -#define PCI_DEVICE_ID_NETVIN_NV5000SC 0x5000 -#define PCI_VENDOR_ID_3COM 0x10b7 -#define PCI_DEVICE_ID_3COM_3C900TPO 0x9000 -#define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001 -#define PCI_DEVICE_ID_3COM_3C905TX 0x9050 -#define PCI_DEVICE_ID_3COM_3C905T4 0x9051 -#define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055 -#define PCI_DEVICE_ID_3COM_3C905C_TXM 0x9200 -#define PCI_VENDOR_ID_INTEL 0x8086 -#define PCI_DEVICE_ID_INTEL_82557 0x1229 -#define PCI_VENDOR_ID_AMD 0x1022 -#define PCI_DEVICE_ID_AMD_LANCE 0x2000 -#define PCI_VENDOR_ID_SMC_1211 0x1113 -#define PCI_DEVICE_ID_SMC_1211 0x1211 -#define PCI_VENDOR_ID_DEC 0x1011 -#define PCI_DEVICE_ID_DEC_TULIP 0x0002 -#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009 -#define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014 -#define PCI_DEVICE_ID_DEC_21142 0x0019 -#define PCI_VENDOR_ID_SMC 0x10B8 -#ifndef PCI_DEVICE_ID_SMC_EPIC100 -# define PCI_DEVICE_ID_SMC_EPIC100 0x0005 -#endif -#define PCI_VENDOR_ID_MACRONIX 0x10d9 -#define PCI_DEVICE_ID_MX987x5 0x0531 -#define PCI_VENDOR_ID_LINKSYS 0x11AD -#define PCI_DEVICE_ID_LC82C115 0xC115 -#define PCI_VENDOR_ID_VIATEC 0x1106 -#define PCI_DEVICE_ID_VIA_RHINE_I 0x3043 -#define PCI_DEVICE_ID_VIA_86C100A 0x6100 -#define PCI_VENDOR_ID_DAVICOM 0x1282 -#define PCI_DEVICE_ID_DM9102 0x9102 - -struct pci_device { - unsigned short vendor, dev_id; - const char *name; - unsigned int membase; - unsigned int ioaddr; - unsigned short devfn; - unsigned short bus; -}; - -extern void eth_pci_init(struct pci_device *); -int pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned char *val); -int pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned short *val); -int pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned int *val); -int pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned char val); -int pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned short val); -int pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned int val); - -/* - * Error values that may be returned by the PCI bios. - */ -#define PCIBIOS_SUCCESSFUL 0x00 -#define PCIBIOS_FUNC_NOT_SUPPORTED 0x81 -#define PCIBIOS_BAD_VENDOR_ID 0x83 -#define PCIBIOS_DEVICE_NOT_FOUND 0x86 -#define PCIBIOS_BAD_REGISTER_NUMBER 0x87 -#define PCIBIOS_SET_FAILED 0x88 -#define PCIBIOS_BUFFER_TOO_SMALL 0x89 - - - -#endif /* PCI_H */ Index: arch/mips/galileo-boards/ev64120/compressed/sbd.h =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/sbd.h diff -N arch/mips/galileo-boards/ev64120/compressed/sbd.h --- arch/mips/galileo-boards/ev64120/compressed/sbd.h 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,52 +0,0 @@ -/* - * sbd.h: cpu board definitions for Galileo-9 - * Copyright (c) 1997 Algorithmics Ltd - */ - -#ifndef MHZ -/* fastest possible pipeline clock */ -#define MHZ 150 -#endif - -/* FIXME These timings are completely fictional */ -#define RAMCYCLE 60 /* 60ns dram cycle */ -#define ROMCYCLE 750 /* ~750ns rom cycle */ -#define CACHECYCLE (1000/MHZ) /* internal clock */ -#define CYCLETIME CACHECYCLE -#define CACHEMISS (CYCLETIME * 6) - -/* - * rough scaling factors for 2 instruction DELAY loop to get 1ms and 1us delays - */ -#define ASMDELAY(ns,icycle) \ - (((ns) + (icycle)) / ((icycle) * 2)) - -#define CACHEUS ASMDELAY(1000, CACHECYCLE) -#define RAMUS ASMDELAY(1000, CACHEMISS+RAMCYCLE) -#define ROMUS ASMDELAY(1000, CACHEMISS+ROMCYCLE) -#define CACHEMS ASMDELAY(1000000, CACHECYCLE) -#define RAMMS ASMDELAY(1000000, CACHEMISS+RAMCYCLE) -#define ROMMS ASMDELAY(1000000, CACHEMISS+ROMCYCLE) - -#ifndef __ASSEMBLY__ -#define nsdelay(ns) mips_cycle (ASMDELAY (ns, CACHECYCLE)) -#define usdelay(us) mips_cycle (ASMDELAY ((us)*1000, CACHECYCLE)) -#endif - -#define DRAM_BASE 0x00000000 -#define PCI_IO_BASE 0x10000000 -#define PCI_IO_SIZE 0x02000000 -#define PCI_MEM_BASE 0x12000000 -#define PCI_MEM_SIZE 0x02000000 -#define GT64011_BASE 0x14000000 -#define DUART_BASE 0x1d000000 -#define FLASH_BASE 0x1f000000 -#define PROM_BASE 0x1fc00000 - - -#define LOCAL_MEM DRAM_BASE -#define LOCAL_MEM_SIZE (128*1024*1024) /* SDRAM size (16MB) */ - -#define BOOTPROM_BASE PROM_BASE - -#define DUART_CLOCK 3686400 Index: arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S diff -N arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S --- arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1049 +0,0 @@ -/* - * Copyright 1997 Algorithmics Ltd - * All Rights Reserved - * - * gal9/sbdreset.sx -- low level board dependent routines - */ - -#ifdef EVB64120A - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "sbd.h" - - -#include "gt64011.h" -#include "ns16550.h" - -#ifdef GALILEO_PORT // miniBios crack -#define C0_CONFIG CP0_CONFIG -#define C0_STATUS CP0_STATUS -#define C0_TLBLO0 CP0_ENTRYLO0 -#define C0_TLBLO1 CP0_ENTRYLO1 -#define C0_PGMASK CP0_PAGEMASK -#define C0_TLBHI CP0_ENTRYHI -#define C0_INX CP0_INDEX -#define NTLBENTRIES 48 - - -#define CFG_IB CONF_IB -#define CFG_DB CONF_DB -#define CFG_C_NONCOHERENT CONF_CM_CACHABLE_NONCOHERENT -#define C0_SR CP0_STATUS -#define SR_DE ST0_DE - - - #define SLEAF(x) LEAF(x) - #define SEND(x) END(x) - #define XLEAF(x) LEAF(x) - #define SBD_DISPLAY(a,b,c,d,e) ; - -#define K0BASE 0x80000000 -#define K0SIZE 0x20000000 -#define K1BASE 0xa0000000 -#define K1SIZE 0x20000000 -#define K2BASE 0xc0000000 - -#define PHYS_TO_K0(pa) ((pa)|K0BASE) -#define PHYS_TO_K1(pa) ((pa)|K1BASE) -#define K0_TO_PHYS(va) ((va)&(K0SIZE-1)) -#define K1_TO_PHYS(va) ((va)&(K1SIZE-1)) -#define K0_TO_K1(va) ((va)|K1SIZE) -#define K1_TO_K0(va) ((va)&~K1SIZE) - -#define PA_TO_KVA0(pa) PHYS_TO_K0(pa) -#define PA_TO_KVA1(pa) PHYS_TO_K1(pa) -#define KVA_TO_PA(pa) K1_TO_PHYS(pa) -#define KSEG0_BASE K0BASE -#define KSEG1_BASE K1BASE - - -#endif - -#define MB 0x100000 - -#define MemTypeNone 0x8000 -#define MemRasMask 0x0f00 -#define MemRasShift 8 -#define MemCasMask 0x000f -#define MemCasShift 0 - -#define rasave s0 -#define p64011 s1 -#define bank0 s2 -#define bank1 s3 -#define bank2 s4 -#define bank3 s5 -#define memtop s6 -#define membase s7 - -/*#if #endian(big) */ -#ifdef __MIPSEB__ - -#define HTOLL(sr,tr) \ - .set noat ; \ - srl AT,sr,24 ; \ - srl tr,sr,8 ; \ - and tr,0xff00 ; \ - or AT,tr ; \ - and tr,sr,0xff00 ; \ - sll tr,8 ; \ - or AT,tr ; \ - sll tr,sr,24 ; \ - or sr,AT,tr ; \ - .set at -#else -#define HTOLL(sr,tr) -#endif - -#undef DBGSBD - -#ifdef DBGSBD -#define DBG(s) \ - .rdata ; \ -88: .asciiz s ; \ - .text ; \ - la a0, 88b ; \ - jal _dbgmsg - -LEAF(_dbgmsg) - .set noat - li AT,PHYS_TO_K1(NS16550_CHANB) -waitrdy: - lbu v1,LSR(AT) - .set noreorder; nop; nop; nop; nop; nop; nop; nop; nop; .set reorder - and v1,LSR_TXRDY - beqz v1,waitrdy - - lbu v1,(a0) - addu a0,1 - beqz v1,9f - sb v1,DATA(AT) - .set noreorder; nop; nop; nop; nop; nop; nop; nop; nop; .set reorder - b waitrdy -9: j ra - .set at -END(_dbgmsg) - -LEAF(_dbghex) - li a1,PHYS_TO_K1(NS16550_CHANB) - li t0,8 -1: - lbu t1,LSR(a1) - .set noreorder; nop; nop; nop; nop; nop; nop; nop; nop; .set reorder - and t1,LSR_TXRDY - beqz t1,1b - - srl t1,a0,28 - addu t1,'0' - ble t1,'9',2f - addu t1,'a'-'0'-10 -2: sb t1,DATA(a1) - .set noreorder; nop; nop; nop; nop; nop; nop; nop; nop; .set reorder - - sll a0,4 - sub t0,1 - bnez t0,1b - - j ra - .set at -END(_dbghex) - - .rdata -initb_str: - .byte 9,0x40 /* Reset CH B */ - .byte 1,0x00 /* Interrupt disabled */ - .byte 3,0xc1 /* 8 bits/char rx enable */ - .byte 4,0x44 /* x16 clk mode 1 stop bit */ - .byte 5,0x6a /* tx 8/bit RTS & tx enable */ - .byte 9,0x0a /* MIE Master int enab. and NV No Vector */ - .byte 11,0x50 /* Select BR gen. out for both rx and ts */ - .byte 0,0x10 - .byte 0,0x10 - .byte 14,0x01 /* enable baud rate gen. */ - .byte 15,0x00 /* known state for reg 15 */ - - .byte 14,0x00 /* disable baud rate gen. */ - .byte 12,0x0a /* 0x0a = 9600 baud time const. - lower 8 bits */ - .byte 13,0x00 /* 9600 buad time const. - upper 8 bits */ - .byte 14,0x01 /* enable baud rate gen. */ - .byte 0xff - - .text - -SLEAF(_dbginit) - /* - li v0,PHYS_TO_K1(NS16550_CHANB) - la a0,initb_str - or a0,K1BASE -1: lbu t0,0(a0) - beq t0,0xff,1f - sb t0,LSR(v0) - .set noreorder; nop; nop; nop; nop; nop; nop; nop; nop; .set reorder - addu a0,1 - b 1b - */ - jal init_ns16550_chan_b # Debug channel - j ra -SEND(_dbginit) -#else -#define DBG(s) -#endif - -LEAF(sbdreset) - move rasave,ra - - /* if launched by ITROM, leave Config alone */ -#ifndef ITBASE - /* set config register for 32b/32b cachelines, kseg0 cacheable */ - mfc0 t1,C0_CONFIG - and t1,~0x3f # set bits 5..0 only - or t1,CFG_IB | CFG_DB | CFG_C_NONCOHERENT - mtc0 t1,C0_CONFIG -#endif - - /* Initialize stack pointer to 6MB address */ - li sp,0xa0600000 - - - /* - * slight amount of kludgery here to stop RAM resident - * program from overwriting itself... - */ -// li v1,0x1fc00000 /* check return address is in ROM */ -// and v0,ra,v1 -// bne v0,v1,.noinit - - /* table driven hardware register initialization */ - la a0, reginittab - or a0, K1BASE /* force to kseg1 */ - -1: lw v0,0(a0) - lw v1,4(a0) - addu a0,8 - beqz v0,8f - - sw v1,0(v0) - b 1b -8: - -#ifdef DBGSBD - jal init_ns16550_chan_b # was - _dbginit - DBG("sbdreset\r\n") -#endif -#define DEVICE_BANK0PARAMETERS 0x45C -#define DEVICE_BANK1PARAMETERS 0x460 -#define DEVICE_BANK2PARAMETERS 0x464 -#define DEVICE_BANK3PARAMETERS 0x468 -#define DEVICE_BOOT_BANK_PARAMETERS 0x46C -#define GT_INTERNAL_REG_BASE 0xb4000000 - - li p64011, PA_TO_KVA1(GT64011_BASE) - - li v0,0xb400046c /* Boot Device */ - lw t0,0(v0) - and t0,0x00003000 /* Keep the correct boot size */ - or t0,htoll(0x3847de70) - sw t0,0(v0) - - li v0,0xb4000468 /* CS3 Device - 16 bit FLASH memory */ - li t0,htoll(0x3859e6e8) - sw t0,0(v0) - - - li v0,0xb4000c84 /* PCI 1 timeout register */ - li t0,htoll(0xffff) - sw t0,0(v0) - - - li v0,0xb4000c3c /* Enable I/O response on PCI0 */ - li t0,htoll(0x7) - sw t0,0(v0) - - li v0,0xb4000cbc /* Enable I/O response on PCI1 */ - li t0,htoll(0x7) - sw t0,0(v0) - - /* GT-64120 Initialization */ - - li p64011, PA_TO_KVA1(GT64011_BASE) - - /*********************************************************************/ - /************************* SDRAM initializing ************************/ - /******************************* START *******************************/ - - - /* SDRAM banks 0,1,2,3 parameters */ - li t0,htoll(0x01908200) /* - Standard Monitor: Interleave enabled */ - li v0,0xb4000448 /* - Registered SDRAM (Bit 23) */ - sw t0,0(v0) /* - Duplicate Dadr11,BankSel1 and Dadr12 */ - /* - Cas latency: 2 Cycles */ - /* - Flow Through enable: One sample */ - /* - SRAS - precharge time: 3 Cycles */ - /* - No ECC */ - /* - No ByPass */ - /* - Burst length: 8 */ - - /* Detect whether we have a 16,64,128 or 256 Mbit SDRAM on DIMM0 */ - /* Set bank0`s range to: 0 - 0x10000000 (256 MByte) */ -_DIMM0: - li v0,0xb4000008 - li t0,htoll(0x0) - sw t0,0(v0) - - li v0,0xb4000010 - li t0,htoll(0x7f) - sw t0,0(v0) - - /* Close banks 2 and 3 */ - li v0,0xb4000018 - li t0,htoll(0x7ff) - sw t0,0(v0) - li v0,0xb4000020 - li t0,htoll(0x00) - sw t0,0(v0) - - /* Extend bank0 to 0x10000000 and Close bank1,2 and 3 */ - DBG("Extend bank0 to 0x10000000 and Close bank1,2 and 3...\r\n") - li v0,0xb4000400 - li t0,htoll(0x0) - sw t0,0(v0) - li v0,0xb4000404 - li t0,htoll(0xff) - sw t0,0(v0) - li v0,0xb4000408 - li t0,htoll(0xff) - sw t0,0(v0) - li v0,0xb400040c - li t0,htoll(0x00) - sw t0,0(v0) - li v0,0xb4000410 - li t0,htoll(0xff) - sw t0,0(v0) - li v0,0xb4000414 - li t0,htoll(0x00) - sw t0,0(v0) - li v0,0xb4000418 - li t0,htoll(0xff) - sw t0,0(v0) - li v0,0xb400041c - li t0,htoll(0x00) - sw t0,0(v0) - - /* Configure bank0 to 256 Mbit */ - DBG("Configure bank0 to 256 Mbit...\r\n") - li v0,0xb400044c - li t0,htoll(0x00004c69) - sw t0,0(v0) - - /* Config the SDRAM banks decode system */ - li v0,0xb400047c - li t0,htoll(2) - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x3) - sw t0,0(v0) - - li v0,0xa0000000 - li t0,0 - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x0) - sw t0,0(v0) - - /* Write to address 0x2000000 and check if 0x00000000 is being written too */ - DBG("Write to address 0x2000000 and check if 0x00000000 is being written too...\r\n") - li v0,0xa0000000 - li t1,0xa0000010 - li t0,htoll(0x0) -1: sw t0,0(v0) - addu v0,4 - bne t1,v0,1b - - /* The address should activate Dadr12 */ - li v0,0xa2000000 - li t0,0x11111111 - sw t0,0(v0) - li v0,0xa0000010 - li t1,0xa0000100 - li t0,0x22222222 -2: sw t0,0(v0) - addu v0,4 - bne t1,v0,2b - - DBG("Check address 0x00000000 for duplications...\r\n") - li t0,0xa0000000 - li v0,0x11111111 - lw t0,(t0) - bne t0,v0,_256MBIT - - /* Write to address 0x1000 and check if 0x00000000 is being written too */ - DBG("Write to address 0x1000 and check if 0x00000000 is being written too...\r\n") - li v0,0xa0000000 - li t1,0xa0000010 - li t0,htoll(0x0) -1: sw t0,0(v0) - addu v0,4 - bne t1,v0,1b - - /* The address should activate bank select1*/ - li v0,0xa0001000 - li t0,0x11111111 - sw t0,0(v0) - li v0,0xa0000010 - li t1,0xa0000100 - li t0,0x22222222 -2: sw t0,0(v0) - addu v0,4 - bne t1,v0,2b - - DBG("Check address 0x00000000 for duplications...\r\n") - li t0,0xa0000000 - li v0,0x11111111 - lw t0,(t0) - beq t0,v0,_16MBIT - - /* Write to address 0x8000000 and check if 0x00000000 is being written too */ - DBG("Write to address 0x8000000 and check if 0x00000000 is being written too...\r\n") - li v0,0xa0000000 - li t1,0xa0000010 - li t0,htoll(0x0) -1: sw t0,0(v0) - addu v0,4 - bne t1,v0,1b - - /* The address should activate Dadr9 which on the column cycle is in active with 64 Mbit - device */ - li v0,0xa8000000 - li t0,0x11111111 - sw t0,0(v0) - li v0,0xa0000010 - li t1,0xa0000100 - li t0,0x22222222 -2: sw t0,0(v0) - addu v0,4 - bne t1,v0,2b - - DBG("Check address 0x00000000 for duplications...\r\n") - li t0,0xa0000000 - li v0,0x11111111 - lw t0,(t0) - beq t0,v0,_64MBIT - b _128MBIT - -_16MBIT: - DBG("16 Mbit SDRAM detected...\r\n") - /* In 16 Mbit SDRAM we must use 2 way bank interleaving!!! */ - li v0,0xb4000810 - li t0,htoll(16) - sw t0,0(v0) - li t1,htoll(0x00000449) - b _DIMM1 - -_64MBIT: - DBG("64 Mbit SDRAM detected...\r\n") - /* In 64 Mbit SDRAM we must use 4 way bank interleaving!!! */ - li v0,0xb4000810 - li t0,htoll(64) - sw t0,0(v0) - li t1,htoll(0x00000c69) - b _DIMM1 - -_128MBIT: - DBG("128 Mbit SDRAM detected...\r\n") - /* In 128 Mbit SDRAM we must use 4 way bank interleaving!!! */ - li v0,0xb4000810 - li t0,htoll(128) - sw t0,0(v0) - li t1,htoll(0x00000c69) - b _DIMM1 - -_256MBIT: - DBG("256 Mbit SDRAM detected...\r\n") - /* In 256 Mbit SDRAM we must use 4 way bank interleaving!!! */ - li v0,0xb4000810 - li t0,htoll(256) - sw t0,0(v0) - li t1,htoll(0x00004c69) - b _DIMM1 - -_DIMM1: - li v0,0xb400044c - sw t1,0(v0) # Bank0 - sw t1,4(v0) # Bank1 - - /* Detect whether we have a 16,64,128 or 256 Mbit SDRAM on DIMM1 */ - /* Close banks 0 and 1 */ - li v0,0xb4000008 - li t0,htoll(0xff) - sw t0,0(v0) - - li v0,0xb4000010 - li t0,htoll(0x0) - sw t0,0(v0) - - /* Set bank2`s range to: 0 - 0x10000000 (256 MByte) */ - li v0,0xb4000018 - li t0,htoll(0x0) - sw t0,0(v0) - li v0,0xb4000020 - li t0,htoll(0x7f) - sw t0,0(v0) - - /* Extend bank2 to 0x10000000 and Close bank0,1 and 3 */ - DBG("Extend bank2 to 0x10000000 and Close banks 0,1 and 3...\r\n") - li v0,0xb4000400 - li t0,htoll(0xff) - sw t0,0(v0) - li v0,0xb4000404 - li t0,htoll(0x00) - sw t0,0(v0) - li v0,0xb4000408 - li t0,htoll(0xff) - sw t0,0(v0) - li v0,0xb400040c - li t0,htoll(0x00) - sw t0,0(v0) - li v0,0xb4000410 - li t0,htoll(0x00) - sw t0,0(v0) - li v0,0xb4000414 - li t0,htoll(0xff) - sw t0,0(v0) - li v0,0xb4000418 - li t0,htoll(0xff) - sw t0,0(v0) - li v0,0xb400041c - li t0,htoll(0x00) - sw t0,0(v0) - - /* Configure bank2 to 256 Mbit */ - DBG("Configure bank2 to 256 Mbit...\r\n") - li v0,0xb4000454 - li t0,htoll(0x00004c69) - sw t0,0(v0) - - /* Config the SDRAM banks decode system */ - li v0,0xb400047c - li t0,htoll(2) - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x3) - sw t0,0(v0) - - li v0,0xa0000000 - li t0,0 - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x0) - sw t0,0(v0) - - /* Write to address 0x2000000 and check if 0x00000000 is being written too */ - DBG("Write to address 0x2000000 and check if 0x00000000 is being written too...\r\n") - li v0,0xa0000000 - li t1,0xa0000010 - li t0,htoll(0x0) -1: sw t0,0(v0) - addu v0,4 - bne t1,v0,1b - - /* The address should activate Dadr12 */ - li v0,0xa2000000 - li t0,0x11111111 - sw t0,0(v0) - li v0,0xa0000010 - li t1,0xa0000100 - li t0,0x22222222 -2: sw t0,0(v0) - addu v0,4 - bne t1,v0,2b - - DBG("Check address 0x00000000 for duplications...\r\n") - li t0,0xa0000000 - li v0,0x11111111 - lw t0,(t0) - bne t0,v0,_256MBIT2 - - /* Write to address 0x1000 and check if 0x00000000 is being written too */ - DBG("Write to address 0x1000 and check if 0x00000000 is being written too...\r\n") - li v0,0xa0000000 - li t1,0xa0000010 - li t0,htoll(0x0) -1: sw t0,0(v0) - addu v0,4 - bne t1,v0,1b - - /* The address should activate bank select1*/ - li v0,0xa0001000 - li t0,0x11111111 - sw t0,0(v0) - li v0,0xa0000010 - li t1,0xa0000100 - li t0,0x22222222 -2: sw t0,0(v0) - addu v0,4 - bne t1,v0,2b - - DBG("Check address 0x00000000 for duplications...\r\n") - li t0,0xa0000000 - li v0,0x11111111 - lw t0,(t0) - beq t0,v0,_16MBIT2 - - /* Write to address 0x8000000 and check if 0x00000000 is being written too */ - DBG("Write to address 0x8000000 and check if 0x00000000 is being written too...\r\n") - li v0,0xa0000000 - li t1,0xa0000010 - li t0,htoll(0x0) -1: sw t0,0(v0) - addu v0,4 - bne t1,v0,1b - - /* The address should activate Dadr9 which on the column cycle is in active with 64 Mbit - device */ - li v0,0xa8000000 - li t0,0x11111111 - sw t0,0(v0) - li v0,0xa0000010 - li t1,0xa0000100 - li t0,0x22222222 -2: sw t0,0(v0) - addu v0,4 - bne t1,v0,2b - - DBG("Check address 0x00000000 for duplications...\r\n") - li t0,0xa0000000 - li v0,0x11111111 - lw t0,(t0) - beq t0,v0,_64MBIT2 - b _128MBIT2 - -_16MBIT2: - DBG("16 Mbit SDRAM detected...\r\n") - /* In 16 Mbit SDRAM we must use 2 way bank interleaving!!! */ - li v0,0xb4000814 - li t0,htoll(16) - sw t0,0(v0) - li t1,htoll(0x00000449) - b _INIT_SDRAM - -_64MBIT2: - DBG("64 Mbit SDRAM detected...\r\n") - /* In 64 Mbit SDRAM we must use 4 way bank interleaving!!! */ - li v0,0xb4000814 - li t0,htoll(64) - sw t0,0(v0) - li t1,htoll(0x00000c69) - b _INIT_SDRAM - -_128MBIT2: - DBG("128 Mbit SDRAM detected...\r\n") - /* In 128 Mbit SDRAM we must use 4 way bank interleaving!!! */ - li v0,0xb4000814 - li t0,htoll(128) - sw t0,0(v0) - li t1,htoll(0x00000c69) - b _INIT_SDRAM - -_256MBIT2: - DBG("256 Mbit SDRAM detected...\r\n") - /* In 256 Mbit SDRAM we must use 4 way bank interleaving!!! */ - li v0,0xb4000814 - li t0,htoll(256) - sw t0,0(v0) - li t1,htoll(0x00004c69) - b _INIT_SDRAM - -_INIT_SDRAM: - /* Restore defaults */ - DBG("Restoring defaults...\r\n") - li v0,0xb4000404 - li t0,htoll(0x07) - sw t0,0(v0) - li v0,0xb4000408 - li t0,htoll(0x08) - sw t0,0(v0) - li v0,0xb400040c - li t0,htoll(0x0f) - sw t0,0(v0) - li v0,0xb4000410 - li t0,htoll(0x10) - sw t0,0(v0) - li v0,0xb4000414 - li t0,htoll(0x17) - sw t0,0(v0) - li v0,0xb4000418 - li t0,htoll(0x18) - sw t0,0(v0) - li v0,0xb400041c - li t0,htoll(0x1f) - sw t0,0(v0) - li v0,0xb4000010 - li t0,htoll(0x07) - sw t0,0(v0) - li v0,0xb4000018 - li t0,htoll(0x008) - sw t0,0(v0) - li v0,0xb4000020 - li t0,htoll(0x0f) - sw t0,0(v0) - - li v0,0xb400044c - sw t1,8(v0) # Bank2 - sw t1,12(v0) # Bank3 - - li v0,0xb4000474 - li t0,htoll(0x3) - sw t0,0(v0) - - li v0,0xa0000000 - li t0,0 - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x0) - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x3) - sw t0,0(v0) - - li v0,0xa0800000 - li t0,0 - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x0) - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x3) - sw t0,0(v0) - - li v0,0xa1000000 - li t0,0 - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x0) - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x3) - sw t0,0(v0) - - li v0,0xa1800000 - li t0,0 - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x0) - sw t0,0(v0) - - /*********************************************************************/ - /************************* SDRAM initializing ************************/ - /******************************* END *********************************/ - - li p64011, PA_TO_KVA1(GT64011_BASE) - - li t0,htoll(0x00000000) /* RAS[1:0] low decode address */ - sw t0,0x008(p64011) - - li t0,htoll(0x00000007) /* RAS[1:0] high decode address */ - sw t0,0x010(p64011) - - li t0,htoll(0x00000000) /* RAS[0] Low decode address */ - sw t0,0x400(p64011) - - li t0,htoll(0x0000000f) /* RAS[0] High decode address */ - sw t0,0x404(p64011) - - li t0,htoll(0x00000008) /* RAS[3:2] low decode address */ - sw t0,0x018(p64011) - - li t0,htoll(0x0000000f) /* RAS[3:2] high decode address */ - sw t0,0x020(p64011) - - li t0,htoll(0x0000000f) /* RAS[1] Low Decode Address */ - sw t0,0x408(p64011) - - li t0,htoll(0x00000008) /* RAS[1] High Decode Address */ - sw t0,0x40c(p64011) - - li t0,htoll(0x00000010) /* RAS[2] Low Decode Address */ - sw t0,0x410(p64011) - - li t0,htoll(0x00000017) /* RAS[2] High Decode Address */ - sw t0,0x414(p64011) - - li t0,htoll(0x00000018) /* RAS[3] Low Decode Address */ - sw t0,0x418(p64011) - - li t0,htoll(0x0000001f) /* RAS[3] High Decode Address <<<<<< 1*/ - sw t0,0x41c(p64011) - -#ifdef DBGSBD -#define DREG(str,rname) \ - DBG(str); \ - DBG(":\t") ; \ - lw a0,rname(p64011) ; \ - HTOLL(a0,t0) ; \ - jal _dbghex ; \ - DBG("\r\n") - - DBG("GT-64120 settings:\r\n") - DREG("DRAMPAR_BANK0 (44c)",GT_DRAMPAR_BANK0) - DREG("DRAMPAR_BANK1 (450)",GT_DRAMPAR_BANK1) - DREG("DRAMPAR_BANK2 (454)",GT_DRAMPAR_BANK2) - DREG("DRAMPAR_BANK3 (458)",GT_DRAMPAR_BANK3) - DREG("PAS_RAS10LO (008)",GT_PAS_RAS10LO) - DREG("PAS_RAS10HI (010)",GT_PAS_RAS10HI) - DREG("PAS_RAS32LO (018)",GT_PAS_RAS32LO) - DREG("PAS_RAS32HI (020)",GT_PAS_RAS32HI) - DREG("DDAS_RAS0LO (400)",GT_DDAS_RAS0LO) - DREG("DDAS_RAS0HI (404)",GT_DDAS_RAS0HI) - DREG("DDAS_RAS1LO (408)",GT_DDAS_RAS1LO) - DREG("DDAS_RAS1HI (40c)",GT_DDAS_RAS1HI) - DREG("DDAS_RAS2LO (410)",GT_DDAS_RAS2LO) - DREG("DDAS_RAS2HI (414)",GT_DDAS_RAS2HI) - DREG("DDAS_RAS3LO (418)",GT_DDAS_RAS3LO) - DREG("DDAS_RAS3HI (41c)",GT_DDAS_RAS3HI) - DREG("GT_DRAM_CFG (448)",GT_DRAM_CFG) - DREG("GT_DEVPAR_BANK0 (45c)",GT_DEVPAR_BANK0) - DREG("GT_DEVPAR_BANK1 (460)",GT_DEVPAR_BANK1) - DREG("GT_DEVPAR_BANK2 (464)",GT_DEVPAR_BANK2) - DREG("GT_DEVPAR_BANK3 (468)",GT_DEVPAR_BANK3) - DREG("GT_IPCI_TOR (c04)",GT_IPCI_TOR) -#endif - - /* we can now initialise the caches for a fast clear_mem */ - SBD_DISPLAY ('C','A','C','H',CHKPNT_CACH) - DBG("init_cache\r\n") -// jal mips_init_cache - -.noinit: - - /* initialise tlb */ - SBD_DISPLAY ('I','T','L','B', CHKPNT_ITLB) - DBG("init_tlb\r\n") -// bal init_tlb - -// DBG("sbdreset completed\r\n") -// move ra,rasave - j GetExtendedMemorySize - nop - -END(sbdreset) - -LEAF(_sbd_memfail) - SBD_DISPLAY ('!','M','E','M',CHKPNT_0MEM) -1: b 1b - j ra -END(_sbd_memfail) - - .rdata -RefreshBits: - .word htoll(GT_DRAMPAR_Refresh512) - .word htoll(GT_DRAMPAR_Refresh1024) - .word htoll(GT_DRAMPAR_Refresh2048) - .word htoll(GT_DRAMPAR_Refresh4096) - .text - -/* DRAM: */ -#define GT_DRAM_CFG_INIT \ - GT_DRAM_CFG_RefIntCnt(160) | \ - GT_DRAM_CFG_StagRefOn | \ - GT_DRAM_CFG_ADSFunctDRAM | \ - GT_DRAM_CFG_DRAMLatchActive - -/* serial port: widest timings even 8 bit bus, latch enabled no parity */ -#define GT_DEVPAR_SERIALINIT \ - GT_DEVPAR_TurnOff(7) | \ - GT_DEVPAR_AccToFirst(15) | \ - GT_DEVPAR_AccToNext(15) | \ - GT_DEVPAR_ADStoWr(7) | \ - GT_DEVPAR_WrActive(7) | \ - GT_DEVPAR_WrHigh(7) | \ - GT_DEVPAR_DevWidth8 | \ - GT_DEVPAR_DevLocEven | \ - GT_DEVPAR_LatchFunctTransparent | \ - GT_DEVPAR_ParityDisable | \ - GT_DEVPAR_Reserved - -/* PCI: */ -#define GT_IPCI_TOR_INIT \ - GT_IPCI_TOR_Timeout0(255) | \ - GT_IPCI_TOR_Timeout1(255) | \ - GT_IPCI_TOR_RetryCtr(0) - -#define INIT(addr,val) \ - .word addr, val -#define GTINIT(addr,val) \ - INIT(PHYS_TO_K1(GT64011_BASE+(addr)), htoll(val)) - - .rdata -reginittab: - - /* disable ras1:0 and ras3:2 decodes */ - GTINIT(GT_PAS_RAS10LO, GT_PAS_LOMASK_Low); - GTINIT(GT_PAS_RAS10HI, 0); - GTINIT(GT_PAS_RAS32LO, GT_PAS_LOMASK_Low); - GTINIT(GT_PAS_RAS32HI, 0); - - /* disable RAS[0123] */ - GTINIT(GT_DDAS_RAS0LO, GT_DDAS_LOMASK_Low) - GTINIT(GT_DDAS_RAS0HI, 0); - GTINIT(GT_DDAS_RAS1LO, GT_DDAS_LOMASK_Low) - GTINIT(GT_DDAS_RAS1HI, 0); - GTINIT(GT_DDAS_RAS2LO, GT_DDAS_LOMASK_Low) - GTINIT(GT_DDAS_RAS2HI, 0); - GTINIT(GT_DDAS_RAS3LO, GT_DDAS_LOMASK_Low) - GTINIT(GT_DDAS_RAS3HI, 0); - - /* 0x45c, 0x460, 0x464, 0x468 */ - /*GTINIT(GT_DEVPAR_BANK0, GT_DEVPAR_SERIALINIT)*/ - GTINIT(GT_DEVPAR_BANK0, 0x3847de60) - GTINIT(GT_DEVPAR_BANK1, 0x146fffff) - GTINIT(GT_DEVPAR_BANK2, 0x144fffff) - GTINIT(GT_DEVPAR_BANK3, 0x167fffff) - - GTINIT(GT_IPCI_TOR, GT_IPCI_TOR_INIT) - INIT(0,0) - .text - - .globl sbddelay - -LEAF(sbdberrenb) - mfc0 v0,C0_SR - li t0,SR_DE - bnez a0,1f - or t1,v0,t0 # disable cache/parity errors (SR_DE = 1) - b 2f -1: not t1,t0 # enable cache/parity errors (SR_DE = 0) - and t1,v0 -2: mtc0 t1,C0_SR - and v0,t0 # get old SR_DE bit - xor v0,t0 # and invert to make it an enable bit - j ra -END(sbdberrenb) - - -LEAF(sbdberrcnt) - move v0,zero - j ra -END(sbdberrcnt) - - .lcomm wbfltmp,4 - -LEAF(wbflush) -//XLEAF(mips_wbflush) - sync - la t0,wbfltmp - or t0,K1BASE - lw zero,0(t0) - j ra -END(wbflush) - - -LEAF(sbddelay) - li t1,CACHEUS - and t0,ra,0x20000000 - beqz t0,1f - li t1,ROMUS -1: mul a0,t1 - subu a0,15 # approx number of loops so far - - .set noreorder - .set nomacro - nop -2: bgtz a0,2b - subu a0,1 - .set macro - .set reorder - - j ra -END(sbddelay) - -#include "meminit.S" - - -LEAF(mips_cycle) - .set noreorder - .set nomacro -1: bgtz a0,1b - subu a0,1 - .set macro - .set reorder - j ra -END(mips_cycle) - -LEAF(init_ns16550_chan_b) - # enable 16550 fifo if it is there - li a0,NS16550_CHANB - li t0,FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4 - sb t0,FIFO(a0) - - /* convert baud rate in a1 into register value */ - li t2,NS16550_HZ/(16*115200) # brtc = CLK/16/speed - - li t0,CFCR_DLAB # select brtc divisor - sb t0,CFCR(a0) - sb t2,DATA(a0) # store divisor lsb - srl t2,8 - sb t2,IER(a0) # store divisor msb - - li t0,CFCR_8BITS # set 8N1 mode - sb t0,CFCR(a0) - - li t0,MCR_DTR|MCR_RTS # Galileo |MCR_IENABLE # enable DTR & RTS - sb t0,MCR(a0) - li t0,0 # Galileo IER_ERXRDY # enable receive interrupt(!) - sb t0,IER(a0) - - move v0,zero # indicate success - j ra - -END(init_ns16550_chan_b) - -LEAF(init_ns16550_chan_a) - # enable 16550 fifo if it is there - li a0,NS16550_CHANA - li t0,FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4 - sb t0,FIFO(a0) - - /* convert baud rate in a1 into register value */ - li t2,NS16550_HZ/(16*9600) # brtc = CLK/16/speed - - li t0,CFCR_DLAB # select brtc divisor - sb t0,CFCR(a0) - sb t2,DATA(a0) # store divisor lsb - srl t2,8 - sb t2,IER(a0) # store divisor msb - - li t0,CFCR_8BITS # set 8N1 mode - sb t0,CFCR(a0) - - li t0,MCR_DTR|MCR_RTS # Galileo |MCR_IENABLE # enable DTR & RTS - sb t0,MCR(a0) - li t0,0 # Galileo IER_ERXRDY # enable receive interrupt(!) - sb t0,IER(a0) - - move v0,zero # indicate success - j ra - -END(init_ns16550_chan_a) - -#endif /* EVB64120A */ Index: arch/mips/galileo-boards/ev64120/compressed/xfer.c =================================================================== RCS file: arch/mips/galileo-boards/ev64120/compressed/xfer.c diff -N arch/mips/galileo-boards/ev64120/compressed/xfer.c --- arch/mips/galileo-boards/ev64120/compressed/xfer.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,114 +0,0 @@ -/* - * arch/mips/galileo/compressed/xfer.c - * - * By RidgeRun Inc, - * - * Xfer an image from flash to ram. - * For use with Galileo EVB64120A MIPS eval board. - */ - -#include "linux/serial_reg.h" - -#define port 0xbd000000 -#define inb(addr) (*(volatile unsigned char *) ((unsigned long)(addr))) -#define outb(b,addr) (*(volatile unsigned char *) ((unsigned long)(addr)) = (b)) - -#ifdef RUNNINGFROMFLASH -// This is where our image of interest is mapped to -// when the jumbers are set for booting out of flash. -// (flash part starts at address 0xbfC00000) -#define srcAddr 0xbfC20000 -#else -// This is where our image of interest is mapped to -// when the jumbers are set for booting out of eprom. -// (flash part starts at address 0xbf000000) -#define srcAddr 0xbf020000 -#endif - -static int PortAddress(unsigned int channel, unsigned char reg); -static void inline cons_hook(void); -static void print_message(const char *string); - -/****************************** - Routine: - Description: - ******************************/ -void XferToRam(void) -{ - unsigned int temp; - void (*entry_point) (void); - - cons_hook(); - - print_message("Copying image from Flash to Ram.\n"); - for (temp = 0; temp < (0x100000 - 0x20000); temp = temp + 4) { - *(volatile unsigned int *) (temp + 0xa0400000) = - *(volatile unsigned int *) (temp + srcAddr); - if (*(volatile unsigned int *) (temp + 0xa0400000) != - *(volatile unsigned int *) (temp + srcAddr)) { - print_message - ("Error!: copy verification failed.\n"); - break; - } - } - - print_message("Now jumping to the code just xferred to ram.\n"); - entry_point = (void *) 0x80400000; - entry_point(); -} - -/****************************** - Routine: - Description: - ******************************/ -static int PortAddress(unsigned int channel, unsigned char reg) -{ - unsigned int channelOffset = 0x20; - unsigned int regDelta = 4; - return (port + (channel * channelOffset) + (reg * regDelta)); -} - -/****************************** - Routine: - Description: - ******************************/ -static void cons_hook(void) -{ - register int comstat; - unsigned temp; - unsigned int channel = 1; // Channel 1 is the main serial - // connector of the EVB64120A. Channel 0 - // is the secondary serial port (typically - // the unsoldered connector of the board). - - temp = *(unsigned int *) 0xb4000464; - *(unsigned int *) 0xb4000464 = 0xffff4f14; - - // Set Baud Rate, baud=115K - outb(0x83, PortAddress(channel, UART_LCR)); - outb(0x00, PortAddress(channel, UART_DLM)); - outb(0x02, PortAddress(channel, UART_DLL)); - outb(0x03, PortAddress(channel, UART_LCR)); - - comstat = inb(PortAddress(channel, UART_LSR)); - comstat = inb(PortAddress(channel, UART_RX)); - outb(0x00, PortAddress(channel, UART_IER)); -} - -/****************************** - Routine: - Description: - ******************************/ -static void print_message(const char *string) -{ - register int count, loop; - /* Display Opening Message */ - for (count = 0; string[count]; count++) { - if (string[count] == '\n') { - *(char *) 0xbd000020 = '\r'; - } - *(char *) 0xbd000020 = string[count]; - for (loop = 0; loop < 2000; loop++) { - } - } -} Index: arch/mips/galileo-boards/ev96100/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/galileo-boards/ev96100/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/galileo-boards/ev96100/Makefile 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/galileo-boards/ev96100/Makefile 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 Index: arch/mips/galileo-boards/ev96100/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/galileo-boards/ev96100/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/galileo-boards/ev96100/init.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/galileo-boards/ev96100/init.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -39,7 +39,7 @@ #include #include -#include +#include /* Environment variable */ Index: arch/mips/galileo-boards/ev96100/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/galileo-boards/ev96100/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/galileo-boards/ev96100/irq.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/galileo-boards/ev96100/irq.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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); } Index: arch/mips/galileo-boards/ev96100/pci_fixups.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/galileo-boards/ev96100/pci_fixups.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/galileo-boards/ev96100/pci_fixups.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/galileo-boards/ev96100/pci_fixups.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 Index: arch/mips/galileo-boards/ev96100/pci_ops.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/galileo-boards/ev96100/pci_ops.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/galileo-boards/ev96100/pci_ops.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/galileo-boards/ev96100/pci_ops.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 */ Index: arch/mips/galileo-boards/ev96100/puts.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/galileo-boards/ev96100/puts.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/galileo-boards/ev96100/puts.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/galileo-boards/ev96100/puts.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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); } Index: arch/mips/galileo-boards/ev96100/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/galileo-boards/ev96100/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/galileo-boards/ev96100/setup.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/galileo-boards/ev96100/setup.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -1,5 +1,4 @@ /* - * * BRIEF MODULE DESCRIPTION * Galileo EV96100 setup. * @@ -47,16 +46,10 @@ #include #include #include -#include -#include +#include #include -#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE) -extern void console_setup(char *, int *); -char serial_console[20]; -#endif - extern char * __init prom_getcmdline(void); extern void mips_reboot_setup(void); @@ -65,17 +58,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 +156,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 +166,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 +176,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 +191,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; } Index: arch/mips/galileo-boards/ev96100/time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/galileo-boards/ev96100/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/galileo-boards/ev96100/time.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/galileo-boards/ev96100/time.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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; Index: arch/mips/galileo-boards/generic/Makefile =================================================================== RCS file: arch/mips/galileo-boards/generic/Makefile diff -N arch/mips/galileo-boards/generic/Makefile --- arch/mips/galileo-boards/generic/Makefile 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: arch/mips/galileo-boards/generic/reset.c =================================================================== RCS file: arch/mips/galileo-boards/generic/reset.c diff -N arch/mips/galileo-boards/generic/reset.c --- arch/mips/galileo-boards/generic/reset.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; -} Index: arch/mips/gt64120/common/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/gt64120/common/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/gt64120/common/Makefile 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/gt64120/common/Makefile 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 Index: arch/mips/gt64120/common/gt_irq.c =================================================================== RCS file: arch/mips/gt64120/common/gt_irq.c diff -N arch/mips/gt64120/common/gt_irq.c --- arch/mips/gt64120/common/gt_irq.c 22 Jul 2004 19:49:16 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 -} Index: arch/mips/gt64120/common/pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/gt64120/common/pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/gt64120/common/pci.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/gt64120/common/pci.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 */ Index: arch/mips/gt64120/momenco_ocelot/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/gt64120/momenco_ocelot/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/gt64120/momenco_ocelot/Makefile 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/gt64120/momenco_ocelot/Makefile 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 Index: arch/mips/gt64120/momenco_ocelot/dbg_io.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/gt64120/momenco_ocelot/dbg_io.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/gt64120/momenco_ocelot/dbg_io.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/gt64120/momenco_ocelot/dbg_io.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -1,6 +1,6 @@ #include -#if defined(CONFIG_REMOTE_DEBUG) +#if defined(CONFIG_KGDB) #include /* For the serial port location and base baud */ Index: arch/mips/gt64120/momenco_ocelot/int-handler.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/gt64120/momenco_ocelot/int-handler.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/gt64120/momenco_ocelot/int-handler.S 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/gt64120/momenco_ocelot/int-handler.S 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 Index: arch/mips/gt64120/momenco_ocelot/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/gt64120/momenco_ocelot/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/gt64120/momenco_ocelot/irq.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/gt64120/momenco_ocelot/irq.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 :-) */ Index: arch/mips/gt64120/momenco_ocelot/pci.c =================================================================== RCS file: arch/mips/gt64120/momenco_ocelot/pci.c diff -N arch/mips/gt64120/momenco_ocelot/pci.c --- arch/mips/gt64120/momenco_ocelot/pci.c 22 Jul 2004 19:49:16 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); - } -} Index: arch/mips/gt64120/momenco_ocelot/prom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/gt64120/momenco_ocelot/prom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/gt64120/momenco_ocelot/prom.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/gt64120/momenco_ocelot/prom.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 */ Index: arch/mips/gt64120/momenco_ocelot/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/gt64120/momenco_ocelot/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/gt64120/momenco_ocelot/setup.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/gt64120/momenco_ocelot/setup.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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__ ( Index: arch/mips/hp-lj/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/hp-lj/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/hp-lj/Makefile 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/hp-lj/Makefile 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 Index: arch/mips/hp-lj/asic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/hp-lj/asic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/hp-lj/asic.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/hp-lj/asic.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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()]; Index: arch/mips/hp-lj/gdb_hook.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/hp-lj/gdb_hook.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/hp-lj/gdb_hook.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/hp-lj/gdb_hook.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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) ; Index: arch/mips/hp-lj/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/hp-lj/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/hp-lj/init.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/hp-lj/init.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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()); Index: arch/mips/hp-lj/int-handler.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/hp-lj/int-handler.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/hp-lj/int-handler.S 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/hp-lj/int-handler.S 4 Aug 2004 01:25:50 -0000 1.2 @@ -64,7 +64,7 @@ la a1, ret_from_irq jr a1 -*/ +*/ 3: j spurious_interrupt END(hpIRQ) Index: arch/mips/hp-lj/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/hp-lj/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/hp-lj/irq.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/hp-lj/irq.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 - + } Index: arch/mips/hp-lj/pci-dma.c =================================================================== RCS file: arch/mips/hp-lj/pci-dma.c diff -N arch/mips/hp-lj/pci-dma.c --- arch/mips/hp-lj/pci-dma.c 22 Jul 2004 19:49:15 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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)); -} - Index: arch/mips/hp-lj/pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/hp-lj/pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/hp-lj/pci.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/hp-lj/pci.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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; Index: arch/mips/hp-lj/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/hp-lj/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/hp-lj/setup.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/hp-lj/setup.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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); Index: arch/mips/hp-lj/utils.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/hp-lj/utils.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/hp-lj/utils.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/hp-lj/utils.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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; } } Index: arch/mips/ite-boards/generic/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ite-boards/generic/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ite-boards/generic/Makefile 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ite-boards/generic/Makefile 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 Index: arch/mips/ite-boards/generic/dbg_io.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ite-boards/generic/dbg_io.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ite-boards/generic/dbg_io.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ite-boards/generic/dbg_io.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -1,7 +1,7 @@ #include -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB /* --- CONFIG --- */ Index: arch/mips/ite-boards/generic/int-handler.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ite-boards/generic/int-handler.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ite-boards/generic/int-handler.S 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ite-boards/generic/int-handler.S 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 Index: arch/mips/ite-boards/generic/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ite-boards/generic/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ite-boards/generic/irq.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ite-boards/generic/irq.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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); Index: arch/mips/ite-boards/generic/it8172_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ite-boards/generic/it8172_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ite-boards/generic/it8172_pci.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ite-boards/generic/it8172_pci.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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)) Index: arch/mips/ite-boards/generic/it8172_rtc.c =================================================================== RCS file: arch/mips/ite-boards/generic/it8172_rtc.c diff -N arch/mips/ite-boards/generic/it8172_rtc.c --- arch/mips/ite-boards/generic/it8172_rtc.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 -}; Index: arch/mips/ite-boards/generic/it8172_setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ite-boards/generic/it8172_setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ite-boards/generic/it8172_setup.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ite-boards/generic/it8172_setup.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -32,26 +32,22 @@ #include #include #include -#include #include #include #include #include +#include +#include #include #include +#include #include #include #ifdef CONFIG_PC_KEYB #include #endif -#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE) -extern void console_setup(char *, int *); -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 +67,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 +124,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 +163,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 +199,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 +224,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 +243,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 +265,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() Index: arch/mips/ite-boards/generic/lpc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ite-boards/generic/lpc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ite-boards/generic/lpc.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ite-boards/generic/lpc.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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)); Index: arch/mips/ite-boards/generic/pmon_prom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ite-boards/generic/pmon_prom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ite-boards/generic/pmon_prom.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ite-boards/generic/pmon_prom.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 { Index: arch/mips/ite-boards/generic/reset.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ite-boards/generic/reset.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ite-boards/generic/reset.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ite-boards/generic/reset.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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)); } Index: arch/mips/ite-boards/generic/time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ite-boards/generic/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ite-boards/generic/time.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/ite-boards/generic/time.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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); +extern unsigned int mips_hpt_frequency; -/* +/* * 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_hpt_frequency = read_c0_count(); /* restore interrupts */ - __restore_flags(flags); - - return (mips_counter_frequency / HZ); + local_irq_restore(flags); + + return (mips_hpt_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); } Index: arch/mips/ite-boards/ivr/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ite-boards/ivr/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ite-boards/ivr/Makefile 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ite-boards/ivr/Makefile 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 Index: arch/mips/ite-boards/ivr/README =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ite-boards/ivr/README,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ite-boards/ivr/README 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ite-boards/ivr/README 4 Aug 2004 01:25:50 -0000 1.2 @@ -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. Index: arch/mips/ite-boards/ivr/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ite-boards/ivr/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ite-boards/ivr/init.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ite-boards/ivr/init.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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); Index: arch/mips/ite-boards/ivr/pci_fixup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ite-boards/ivr/pci_fixup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ite-boards/ivr/pci_fixup.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ite-boards/ivr/pci_fixup.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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; } Index: arch/mips/ite-boards/qed-4n-s01b/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ite-boards/qed-4n-s01b/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ite-boards/qed-4n-s01b/Makefile 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/ite-boards/qed-4n-s01b/Makefile 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 Index: arch/mips/ite-boards/qed-4n-s01b/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ite-boards/qed-4n-s01b/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ite-boards/qed-4n-s01b/init.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/ite-boards/qed-4n-s01b/init.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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); Index: arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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; } Index: arch/mips/jazz/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jazz/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jazz/Makefile 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jazz/Makefile 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 Index: arch/mips/jazz/floppy-jazz.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jazz/floppy-jazz.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jazz/floppy-jazz.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jazz/floppy-jazz.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -1,5 +1,4 @@ -/* $Id: floppy-jazz.c,v 1.1 2004/07/22 19:49:14 joff 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) Index: arch/mips/jazz/int-handler.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jazz/int-handler.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jazz/int-handler.S 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jazz/int-handler.S 4 Aug 2004 01:25:50 -0000 1.2 @@ -1,5 +1,4 @@ -/* $Id: int-handler.S,v 1.1 2004/07/22 19:49:14 joff 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 /* Index: arch/mips/jazz/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jazz/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jazz/irq.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jazz/irq.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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) Index: arch/mips/jazz/jazzdma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jazz/jazzdma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jazz/jazzdma.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jazz/jazzdma.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,8 @@ */ #define CONF_DEBUG_VDMA 0 +static spinlock_t jazz_dma_lock = SPIN_LOCK_UNLOCKED; + static unsigned long vdma_pagetable_start; /* @@ -42,10 +45,9 @@ */ static inline void vdma_pgtbl_init(void) { - int i; + VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; unsigned long paddr = 0; - VDMA_PGTBL_ENTRY *pgtbl = - (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; + int i; for (i = 0; i < VDMA_PGTBL_ENTRIES; i++) { pgtbl[i].frame = paddr; @@ -88,15 +90,9 @@ */ unsigned long vdma_alloc(unsigned long paddr, unsigned long size) { - VDMA_PGTBL_ENTRY *entry = - (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; - int first; - int last; - int pages; - unsigned int frame; - unsigned long laddr; - int i; - unsigned long flags; + VDMA_PGTBL_ENTRY *entry = (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; + int first, last, pages, frame, i; + unsigned long laddr, flags; /* check arguments */ @@ -112,7 +108,8 @@ return VDMA_ERROR; /* invalid physical address */ } - save_and_cli(flags); + spin_lock_saveirq(&jazz_dma_lock, flags); + /* * Find free chunk */ @@ -121,8 +118,9 @@ while (1) { while (entry[first].owner != VDMA_PAGE_EMPTY && first < VDMA_PGTBL_ENTRIES) first++; - if (first + pages > VDMA_PGTBL_ENTRIES) { /* nothing free */ - restore_flags(flags); + if (first + pages > VDMA_PGTBL_ENTRIES) { + /* nothing free */ + spin_unlock_restoreirq(&jazz_dma_lock, flags); return VDMA_ERROR; } @@ -153,8 +151,7 @@ r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0); if (vdma_debug > 1) - printk - ("vdma_alloc: Allocated %d pages starting from %08lx\n", + printk("vdma_alloc: Allocated %d pages starting from %08lx\n", pages, laddr); if (vdma_debug > 2) { @@ -170,7 +167,8 @@ printk("\n"); } - restore_flags(flags); + spin_unlock_restoreirq(&jazz_dma_lock, flags); + return laddr; } @@ -181,8 +179,7 @@ */ int vdma_free(unsigned long laddr) { - VDMA_PGTBL_ENTRY *pgtbl = - (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; + VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; int i; i = laddr >> 12; @@ -213,27 +210,23 @@ int vdma_remap(unsigned long laddr, unsigned long paddr, unsigned long size) { - VDMA_PGTBL_ENTRY *pgtbl = - (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; + VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; int first, pages, npages; if (laddr > 0xffffff) { if (vdma_debug) - printk - ("vdma_map: Invalid logical address: %08lx\n", + printk("vdma_map: Invalid logical address: %08lx\n", laddr); return -EINVAL; /* invalid logical address */ } if (paddr > 0x1fffffff) { if (vdma_debug) - printk - ("vdma_map: Invalid physical address: %08lx\n", + printk("vdma_map: Invalid physical address: %08lx\n", paddr); return -EINVAL; /* invalid physical address */ } - npages = pages = - (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1; + npages = pages = (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1; first = laddr >> 12; if (vdma_debug) printk("vdma_remap: first=%x, pages=%x\n", first, pages); @@ -287,10 +280,8 @@ */ unsigned long vdma_phys2log(unsigned long paddr) { - int i; - int frame; - VDMA_PGTBL_ENTRY *pgtbl = - (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; + VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; + int frame, i; frame = paddr & ~(VDMA_PAGESIZE - 1); @@ -310,8 +301,7 @@ */ unsigned long vdma_log2phys(unsigned long laddr) { - VDMA_PGTBL_ENTRY *pgtbl = - (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; + VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; return pgtbl[laddr >> 12].frame + (laddr & (VDMA_PAGESIZE - 1)); } @@ -347,9 +337,8 @@ printk("\n"); printk("vdma_chnl_enables: "); for (i = 0; i < 8; i++) - printk("%04x ", - (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + - (i << 5))); + printk("%04x ", r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + + (i << 5))); printk("\n"); } @@ -399,8 +388,7 @@ void vdma_disable(int channel) { if (vdma_debug) { - int status = - r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + + int status = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5)); printk("vdma_disable: channel %d\n", channel); Index: arch/mips/jazz/kbd-jazz.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jazz/kbd-jazz.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jazz/kbd-jazz.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jazz/kbd-jazz.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -1,5 +1,4 @@ -/* $Id: kbd-jazz.c,v 1.1 2004/07/22 19:49:14 joff 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); Index: arch/mips/jazz/reset.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jazz/reset.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jazz/reset.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jazz/reset.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -1,11 +1,6 @@ /* - * linux/arch/mips/jazz/process.c - * - * Reset a Jazz machine. - * - * $Id: reset.c,v 1.1 2004/07/22 19:49:14 joff Exp $ + * 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); Index: arch/mips/jazz/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jazz/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jazz/setup.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jazz/setup.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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; Index: arch/mips/jmr3927/common/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jmr3927/common/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jmr3927/common/Makefile 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jmr3927/common/Makefile 4 Aug 2004 01:25:50 -0000 1.2 @@ -6,13 +6,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:= tx3927.o -obj-y += prom.o puts.o rtc_ds1742.o +obj-y += prom.o puts.o include $(TOPDIR)/Rules.make Index: arch/mips/jmr3927/common/prom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jmr3927/common/prom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jmr3927/common/prom.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jmr3927/common/prom.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 Index: arch/mips/jmr3927/common/puts.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jmr3927/common/puts.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jmr3927/common/puts.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jmr3927/common/puts.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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; Index: arch/mips/jmr3927/common/rtc_ds1742.c =================================================================== RCS file: arch/mips/jmr3927/common/rtc_ds1742.c diff -N arch/mips/jmr3927/common/rtc_ds1742.c --- arch/mips/jmr3927/common/rtc_ds1742.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,173 +0,0 @@ -/*********************************************************************** - * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * 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 - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU 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 exports a function, rtc_ds1386_init(), which expects an - * uncached base address as the argument. It will set the two function - * pointers expected by the MIPS generic timer code. - */ - -#include -#include -#include - -#include -#include - -#include -#include - -#define EPOCH 2000 - -#undef BCD_TO_BIN -#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10) - -#undef BIN_TO_BCD -#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10) - -static unsigned long rtc_base; - -static unsigned long -rtc_ds1742_get_time(void) -{ - unsigned int year, month, day, hour, minute, second; - unsigned int century; - - CMOS_WRITE(RTC_READ, RTC_CONTROL); - second = BCD_TO_BIN(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); - minute = BCD_TO_BIN(CMOS_READ(RTC_MINUTES)); - hour = BCD_TO_BIN(CMOS_READ(RTC_HOURS)); - day = BCD_TO_BIN(CMOS_READ(RTC_DATE)); - month = BCD_TO_BIN(CMOS_READ(RTC_MONTH)); - year = BCD_TO_BIN(CMOS_READ(RTC_YEAR)); - century = BCD_TO_BIN(CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK); - CMOS_WRITE(0, RTC_CONTROL); - - year += century * 100; - - return mktime(year, month, day, hour, minute, second); -} -extern void to_tm(unsigned long tim, struct rtc_time * tm); - -static int -rtc_ds1742_set_time(unsigned long t) -{ - struct rtc_time tm; - u8 year, month, day, hour, minute, second; - u8 cmos_year, cmos_month, cmos_day, cmos_hour, cmos_minute, cmos_second; - int cmos_century; - - CMOS_WRITE(RTC_READ, RTC_CONTROL); - cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); - cmos_minute = (u8)CMOS_READ(RTC_MINUTES); - cmos_hour = (u8)CMOS_READ(RTC_HOURS); - cmos_day = (u8)CMOS_READ(RTC_DATE); - cmos_month = (u8)CMOS_READ(RTC_MONTH); - cmos_year = (u8)CMOS_READ(RTC_YEAR); - cmos_century = CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK; - - CMOS_WRITE(RTC_WRITE, RTC_CONTROL); - - /* convert */ - to_tm(t, &tm); - - /* check each field one by one */ - year = BIN_TO_BCD(tm.tm_year - EPOCH); - if (year != cmos_year) { - CMOS_WRITE(year,RTC_YEAR); - } - - month = BIN_TO_BCD(tm.tm_mon); - if (month != (cmos_month & 0x1f)) { - CMOS_WRITE((month & 0x1f) | (cmos_month & ~0x1f),RTC_MONTH); - } - - day = BIN_TO_BCD(tm.tm_mday); - if (day != cmos_day) { - - CMOS_WRITE(day, RTC_DATE); - } - - if (cmos_hour & 0x40) { - /* 12 hour format */ - hour = 0x40; - if (tm.tm_hour > 12) { - hour |= 0x20 | (BIN_TO_BCD(hour-12) & 0x1f); - } else { - hour |= BIN_TO_BCD(tm.tm_hour); - } - } else { - /* 24 hour format */ - hour = BIN_TO_BCD(tm.tm_hour) & 0x3f; - } - if (hour != cmos_hour) CMOS_WRITE(hour, RTC_HOURS); - - minute = BIN_TO_BCD(tm.tm_min); - if (minute != cmos_minute) { - CMOS_WRITE(minute, RTC_MINUTES); - } - - second = BIN_TO_BCD(tm.tm_sec); - 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); - - return 0; -} - -void -rtc_ds1742_init(unsigned long base) -{ - u8 cmos_second; - - /* remember the base */ - rtc_base = base; - db_assert((rtc_base & 0xe0000000) == KSEG1); - - /* set the function pointers */ - rtc_get_time = rtc_ds1742_get_time; - rtc_set_time = rtc_ds1742_set_time; - - /* clear oscillator stop bit */ - CMOS_WRITE(RTC_READ, RTC_CONTROL); - cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); - CMOS_WRITE(RTC_WRITE, RTC_CONTROL); - CMOS_WRITE(cmos_second, RTC_SECONDS); /* clear msb */ - CMOS_WRITE(0, RTC_CONTROL); -} Index: arch/mips/jmr3927/rbhma3100/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jmr3927/rbhma3100/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jmr3927/rbhma3100/Makefile 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jmr3927/rbhma3100/Makefile 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 Index: arch/mips/jmr3927/rbhma3100/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jmr3927/rbhma3100/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jmr3927/rbhma3100/init.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jmr3927/rbhma3100/init.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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; Index: arch/mips/jmr3927/rbhma3100/int-handler.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jmr3927/rbhma3100/int-handler.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jmr3927/rbhma3100/int-handler.S 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jmr3927/rbhma3100/int-handler.S 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 * Index: arch/mips/jmr3927/rbhma3100/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jmr3927/rbhma3100/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jmr3927/rbhma3100/irq.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jmr3927/rbhma3100/irq.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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; } Index: arch/mips/jmr3927/rbhma3100/kgdb_io.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jmr3927/rbhma3100/kgdb_io.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jmr3927/rbhma3100/kgdb_io.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jmr3927/rbhma3100/kgdb_io.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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); Index: arch/mips/jmr3927/rbhma3100/pci_fixup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jmr3927/rbhma3100/pci_fixup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jmr3927/rbhma3100/pci_fixup.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jmr3927/rbhma3100/pci_fixup.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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) Index: arch/mips/jmr3927/rbhma3100/pci_ops.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jmr3927/rbhma3100/pci_ops.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jmr3927/rbhma3100/pci_ops.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jmr3927/rbhma3100/pci_ops.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 */ Index: arch/mips/jmr3927/rbhma3100/rtc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jmr3927/rbhma3100/rtc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jmr3927/rbhma3100/rtc.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jmr3927/rbhma3100/rtc.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -1,7 +1,7 @@ /* * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. - * ahennessy@mvista.com + * ahennessy@mvista.com * * RTC routines for Dallas chip. * @@ -31,17 +31,16 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include /* bad name... */ -#include +#include static unsigned char jmr3927_rtc_read_data(unsigned long addr) { - return jmr3927_nvram_in(addr); + return readb(addr); } static void jmr3927_rtc_write_data(unsigned char data, unsigned long addr) { - jmr3927_nvram_out(data, addr); + writeb(data, addr); } static int jmr3927_rtc_bcd_mode(void) Index: arch/mips/jmr3927/rbhma3100/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/jmr3927/rbhma3100/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/jmr3927/rbhma3100/setup.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/jmr3927/rbhma3100/setup.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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)) Index: arch/mips/kernel/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/Makefile 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/Makefile 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 semaphore.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 @@ -30,6 +30,7 @@ obj-$(CONFIG_CPU_R5000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R5432) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_RM7000) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_RM9000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_NEVADA) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R10000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_SB1) += r4k_fpu.o r4k_switch.o @@ -39,9 +40,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 +51,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 Index: arch/mips/kernel/branch.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/branch.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/branch.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/branch.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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; Index: arch/mips/kernel/cpu-probe.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/cpu-probe.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/cpu-probe.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/cpu-probe.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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) @@ -33,29 +34,41 @@ ".set\tmips0"); } +/* The Au1xxx wait is available only if we run CONFIG_PM and + * the timer setup found we had a 32KHz counter available. + * There are still problems with functions that may call au1k_wait + * directly, but that will be discovered pretty quickly. + */ +extern void (*au1k_wait_ptr)(void); void au1k_wait(void) { #ifdef CONFIG_PM /* 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; @@ -68,21 +81,31 @@ case CPU_R5000: case CPU_NEVADA: case CPU_RM7000: +/* case CPU_RM9000: */ case CPU_TX49XX: case CPU_4KC: case CPU_4KEC: case CPU_4KSC: case CPU_5KC: /* case CPU_20KC:*/ + case CPU_24K: + case CPU_25KF: cpu_wait = r4k_wait; printk(" available.\n"); break; +#ifdef CONFIG_PM case CPU_AU1000: case CPU_AU1100: case CPU_AU1500: - cpu_wait = au1k_wait; - printk(" available.\n"); + if (au1k_wait_ptr != NULL) { + cpu_wait = au1k_wait_ptr; + printk(" available.\n"); + } + else { + printk(" unavailable.\n"); + } break; +#endif default: printk(" unavailable.\n"); break; @@ -104,12 +127,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,367 +146,444 @@ { 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) + | MIPS_CPU_COUNTER) -__init void cpu_probe(void) +static inline void cpu_probe_legacy(struct cpuinfo_mips *c) { -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) - unsigned long config0 = read_32bit_cp0_register(CP0_CONFIG); - unsigned long config1; - - 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(); - if (config1 & (1 << 3)) - mips_cpu.options |= MIPS_CPU_WATCH; - if (config1 & (1 << 2)) - mips_cpu.options |= MIPS_CPU_MIPS16; - if (config1 & (1 << 1)) - mips_cpu.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 - } - mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT; - } + switch (c->processor_id & 0xff00) { + case PRID_IMP_R2000: + 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 ((c->processor_id & 0xff) == PRID_REV_R3000A) + if (cpu_has_confreg()) + c->cputype = CPU_R3081E; + else + c->cputype = CPU_R3000A; + else + 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 ((c->processor_id & 0xff) >= PRID_REV_R4400) + c->cputype = CPU_R4400SC; + else + 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 (c->processor_id & 0xf0) { +#ifndef CONFIG_VR4181 + case PRID_REV_VR4111: + c->cputype = CPU_VR4111; + break; +#else + case PRID_REV_VR4181: + c->cputype = CPU_VR4181; + break; #endif - mips_cpu.processor_id = read_32bit_cp0_register(CP0_PRID); - switch (mips_cpu.processor_id & 0xff0000) { - case PRID_COMP_LEGACY: - switch (mips_cpu.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; + case PRID_REV_VR4121: + c->cputype = CPU_VR4121; break; - case PRID_IMP_R3000: - if ((mips_cpu.processor_id & 0xff) == PRID_REV_R3000A) - if (cpu_has_confreg()) - mips_cpu.cputype = CPU_R3081E; - else - mips_cpu.cputype = CPU_R3000A; + case PRID_REV_VR4122: + if ((c->processor_id & 0xf) < 0x3) + c->cputype = CPU_VR4122; 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_VR4181A; break; - case PRID_IMP_R4000: - if ((mips_cpu.processor_id & 0xff) == PRID_REV_R4400) - mips_cpu.cputype = CPU_R4400SC; + case PRID_REV_VR4130: + if ((c->processor_id & 0xf) < 0x4) + c->cputype = CPU_VR4131; 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_VR4133; break; - case PRID_IMP_VR41XX: - switch (mips_cpu.processor_id & 0xf0) { -#ifndef CONFIG_VR4181 - case PRID_REV_VR4111: - mips_cpu.cputype = CPU_VR4111; - break; -#else - case PRID_REV_VR4181: - mips_cpu.cputype = CPU_VR4181; - break; -#endif - case PRID_REV_VR4121: - mips_cpu.cputype = CPU_VR4121; + default: + printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); + c->cputype = CPU_VR41XX; break; - case PRID_REV_VR4122: - if ((mips_cpu.processor_id & 0xf) < 0x3) - mips_cpu.cputype = CPU_VR4122; - else - mips_cpu.cputype = CPU_VR4181A; + } + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS; + c->tlbsize = 32; + break; + case PRID_IMP_R4300: + 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: + 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: + /* + * This processor doesn't have an MMU, so it's not + * "real easy" to run Linux on it. It is left purely + * for documentation. Commented out because it shares + * it's c0_prid id number with the TX3900. + */ + 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: + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB; + + if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) { + c->cputype = CPU_TX3927; + c->tlbsize = 64; + } else { + switch (c->processor_id & 0xff) { + case PRID_REV_TX3912: + c->cputype = CPU_TX3912; + c->tlbsize = 32; break; - case PRID_REV_VR4131: - mips_cpu.cputype = CPU_VR4131; - mips_cpu.icache.ways = 2; - mips_cpu.dcache.ways = 2; + case PRID_REV_TX3922: + c->cputype = CPU_TX3922; + c->tlbsize = 64; break; default: - printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); - mips_cpu.cputype = CPU_VR41XX; + c->cputype = CPU_UNKNOWN; break; } - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS; - mips_cpu.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; - 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; - break; - #if 0 - case PRID_IMP_R4650: - /* - * This processor doesn't have an MMU, so it's not - * "real easy" to run Linux on it. It is left purely - * 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; - break; - #endif - case PRID_IMP_TX39: - mips_cpu.isa_level = MIPS_CPU_ISA_I; - mips_cpu.options = MIPS_CPU_TLB; - - if ((mips_cpu.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; - } else { - switch (mips_cpu.processor_id & 0xff) { - case PRID_REV_TX3912: - mips_cpu.cputype = CPU_TX3912; - mips_cpu.tlbsize = 32; - break; - case PRID_REV_TX3922: - mips_cpu.cputype = CPU_TX3922; - mips_cpu.tlbsize = 64; - break; - default: - mips_cpu.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; - 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; - 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; - 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; - 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; - 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; - 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; - 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; - 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; - /* - * Undocumented RM7000: Bit 29 in the info register of - * the RM7000 v2.0 indicates if the TLB has 48 or 64 - * entries. - * - * 29 1 => 64 entry JTLB - * 0 => 48 entry JTLB - */ - mips_cpu.tlbsize = (get_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 */ - 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; - 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; - break; - default: - mips_cpu.cputype = CPU_UNKNOWN; - break; } break; -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) - case PRID_COMP_MIPS: - switch (mips_cpu.processor_id & 0xff00) { - case PRID_IMP_4KC: - mips_cpu.cputype = CPU_4KC; - mips_cpu.isa_level = MIPS_CPU_ISA_M32; - break; - case PRID_IMP_4KEC: - mips_cpu.cputype = CPU_4KEC; - mips_cpu.isa_level = MIPS_CPU_ISA_M32; + case PRID_IMP_R4700: + 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: + c->cputype = CPU_TX49XX; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_LLSC; + if (!(c->processor_id & 0x08)) + c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; + c->tlbsize = 48; + break; + case PRID_IMP_R5000: + 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: + 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: + 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: + 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: + 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: + 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: + 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 + * entries. + * + * 29 1 => 64 entry JTLB + * 0 => 48 entry JTLB + */ + c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; + break; + case PRID_IMP_RM9000: + c->cputype = CPU_RM9000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + /* + * Bit 29 in the info register of the RM9000 + * indicates if the TLB has 48 or 64 entries. + * + * 29 1 => 64 entry JTLB + * 0 => 48 entry JTLB + */ + c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; + break; + case PRID_IMP_R8000: + 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: + 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: + 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: + c->cputype = CPU_UNKNOWN; + break; + } +} + +static inline void decode_config1(struct cpuinfo_mips *c) +{ + unsigned long config0 = read_c0_config(); + unsigned long config1; + + if ((config0 & (1 << 31)) == 0) + return; /* actually wort a panic() */ + + /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */ + 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)) + c->options |= MIPS_CPU_WATCH; + if (config1 & (1 << 2)) + c->options |= MIPS_CPU_MIPS16; + if (config1 & (1 << 1)) + c->options |= MIPS_CPU_EJTAG; + if (config1 & 1) { + c->options |= MIPS_CPU_FPU; + c->options |= MIPS_CPU_32FPR; + } + c->scache.flags = MIPS_CACHE_NOT_PRESENT; + + c->tlbsize = ((config1 >> 25) & 0x3f) + 1; +} + +static inline void cpu_probe_mips(struct cpuinfo_mips *c) +{ + decode_config1(c); + switch (c->processor_id & 0xff00) { + case PRID_IMP_4KC: + c->cputype = CPU_4KC; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_4KEC: + c->cputype = CPU_4KEC; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_4KSC: + c->cputype = CPU_4KSC; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_5KC: + c->cputype = CPU_5KC; + c->isa_level = MIPS_CPU_ISA_M64; + break; + case PRID_IMP_20KC: + c->cputype = CPU_20KC; + c->isa_level = MIPS_CPU_ISA_M64; + break; + case PRID_IMP_24K: + c->cputype = CPU_24K; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_25KF: + c->cputype = CPU_25KF; + c->isa_level = MIPS_CPU_ISA_M64; + /* Probe for L2 cache */ + c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } +} + +static inline void cpu_probe_alchemy(struct cpuinfo_mips *c) +{ + decode_config1(c); + switch (c->processor_id & 0xff00) { + case PRID_IMP_AU1_REV1: + case PRID_IMP_AU1_REV2: + switch ((c->processor_id >> 24) & 0xff) { + case 0: + c->cputype = CPU_AU1000; break; - case PRID_IMP_4KSC: - mips_cpu.cputype = CPU_4KSC; - mips_cpu.isa_level = MIPS_CPU_ISA_M32; + case 1: + c->cputype = CPU_AU1500; break; - case PRID_IMP_5KC: - mips_cpu.cputype = CPU_5KC; - mips_cpu.isa_level = MIPS_CPU_ISA_M64; + case 2: + c->cputype = CPU_AU1100; break; - case PRID_IMP_20KC: - mips_cpu.cputype = CPU_20KC; - mips_cpu.isa_level = MIPS_CPU_ISA_M64; + case 3: + c->cputype = CPU_AU1550; break; default: - mips_cpu.cputype = CPU_UNKNOWN; + panic("Unknown Au Core!"); break; } + c->isa_level = MIPS_CPU_ISA_M32; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } +} + +static inline void cpu_probe_sibyte(struct cpuinfo_mips *c) +{ + decode_config1(c); + switch (c->processor_id & 0xff00) { + case PRID_IMP_SB1: + 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. */ + c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; +#endif + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } +} + +static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c) +{ + decode_config1(c); + 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; + } +} + +__init void cpu_probe(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + + c->processor_id = PRID_IMP_UNKNOWN; + c->fpu_id = FPIR_IMP_NONE; + c->cputype = CPU_UNKNOWN; + + c->processor_id = read_c0_prid(); + switch (c->processor_id & 0xff0000) { + + case PRID_COMP_LEGACY: + cpu_probe_legacy(c); + break; + case PRID_COMP_MIPS: + cpu_probe_mips(c); break; case PRID_COMP_ALCHEMY: - switch (mips_cpu.processor_id & 0xff00) { - case PRID_IMP_AU1_REV1: - case PRID_IMP_AU1_REV2: - switch ((mips_cpu.processor_id >> 24) & 0xff) { - case 0: - mips_cpu.cputype = CPU_AU1000; - break; - case 1: - mips_cpu.cputype = CPU_AU1500; - break; - case 2: - mips_cpu.cputype = CPU_AU1100; - break; - default: - panic("Unknown Au Core!"); - break; - } - mips_cpu.isa_level = MIPS_CPU_ISA_M32; - break; - default: - mips_cpu.cputype = CPU_UNKNOWN; - break; - } + cpu_probe_alchemy(c); break; -#endif /* CONFIG_CPU_MIPS32 */ case PRID_COMP_SIBYTE: - switch (mips_cpu.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; -#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS - /* FPU in pass1 is known to have issues. */ - mips_cpu.options |= MIPS_CPU_FPU; -#endif - break; - default: - mips_cpu.cputype = CPU_UNKNOWN; - break; - } + cpu_probe_sibyte(c); + break; + + case PRID_COMP_SANDCRAFT: + cpu_probe_sandcraft(c); 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); } Index: arch/mips/kernel/entry.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/entry.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/entry.S 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/entry.S 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 */ Index: arch/mips/kernel/gdb-low.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/gdb-low.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/gdb-low.S 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/gdb-low.S 4 Aug 2004 01:25:50 -0000 1.2 @@ -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) Index: arch/mips/kernel/gdb-stub.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/gdb-stub.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/gdb-stub.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/gdb-stub.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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" + "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" + "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) Index: arch/mips/kernel/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/head.S 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/head.S 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 */ @@ -150,14 +160,7 @@ .set noreorder /* - * Stack for kernel and init, current variable - */ - la $28, init_task_union - addiu t0, $28, KERNEL_STACK_SIZE-32 - subu sp, t0, 4*SZREG - - sw t0, kernelsp - /* The firmware/bootloader passes argc/argp/envp + * The firmware/bootloader passes argc/argp/envp * to us as arguments. But clear bss first because * the romvec and other important info is stored there * by prom_init(). @@ -170,6 +173,14 @@ bne t0, t1, 1b sw zero, (t0) + /* + * Stack for kernel and init, current variable + */ + la $28, init_task_union + addiu t0, $28, KERNEL_STACK_SIZE-32 + subu sp, t0, 4*SZREG + sw t0, kernelsp + jal init_arch nop END(kernel_entry) @@ -187,7 +198,7 @@ mtc0 zero, CP0_WIRED CLI mfc0 t0, CP0_STATUS - li t1, ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX) + li t1, ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_UX) and t0, t1 or t0, (ST0_CU0); jal start_secondary Index: arch/mips/kernel/i8259.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/i8259.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/i8259.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/i8259.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -15,6 +15,7 @@ #include #include +#include #include void enable_8259A_irq(unsigned int irq); Index: arch/mips/kernel/ioport.c =================================================================== RCS file: arch/mips/kernel/ioport.c diff -N arch/mips/kernel/ioport.c --- arch/mips/kernel/ioport.c 22 Jul 2004 19:49:16 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; -} Index: arch/mips/kernel/ipc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/ipc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/ipc.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/ipc.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -32,7 +32,11 @@ 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: { @@ -93,6 +97,6 @@ return sys_shmctl (first, second, (struct shmid_ds *) ptr); default: - return -EINVAL; + return -ENOSYS; } } Index: arch/mips/kernel/irixelf.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/irixelf.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/irixelf.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/irixelf.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 */ Index: arch/mips/kernel/irixinv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/irixinv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/irixinv.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/irixinv.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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); Index: arch/mips/kernel/irixsig.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/irixsig.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/irixsig.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/irixsig.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 */ @@ -675,49 +676,53 @@ continue; flag = 1; switch (p->state) { - case TASK_STOPPED: - if (!p->exit_code) - continue; - if (!(options & (W_TRAPPED|W_STOPPED)) && - !(p->ptrace & PT_PTRACED)) - continue; - if (ru != NULL) - getrusage(p, RUSAGE_BOTH, ru); - __put_user(SIGCHLD, &info->sig); - __put_user(0, &info->code); - __put_user(p->pid, &info->stuff.procinfo.pid); - __put_user((p->exit_code >> 8) & 0xff, - &info->stuff.procinfo.procdata.child.status); - __put_user(p->times.tms_utime, &info->stuff.procinfo.procdata.child.utime); - __put_user(p->times.tms_stime, &info->stuff.procinfo.procdata.child.stime); - p->exit_code = 0; - retval = 0; - goto end_waitsys; - case TASK_ZOMBIE: - current->times.tms_cutime += p->times.tms_utime + p->times.tms_cutime; - current->times.tms_cstime += p->times.tms_stime + p->times.tms_cstime; - if (ru != NULL) - getrusage(p, RUSAGE_BOTH, ru); - __put_user(SIGCHLD, &info->sig); - __put_user(1, &info->code); /* CLD_EXITED */ - __put_user(p->pid, &info->stuff.procinfo.pid); - __put_user((p->exit_code >> 8) & 0xff, - &info->stuff.procinfo.procdata.child.status); - __put_user(p->times.tms_utime, - &info->stuff.procinfo.procdata.child.utime); - __put_user(p->times.tms_stime, - &info->stuff.procinfo.procdata.child.stime); - retval = 0; - if (p->p_opptr != p->p_pptr) { - REMOVE_LINKS(p); - p->p_pptr = p->p_opptr; - SET_LINKS(p); - notify_parent(p, SIGCHLD); - } else - release_task(p); - goto end_waitsys; - default: + case TASK_STOPPED: + if (!p->exit_code) + continue; + if (!(options & (W_TRAPPED|W_STOPPED)) && + !(p->ptrace & PT_PTRACED)) continue; + read_unlock(&tasklist_lock); + if (ru != NULL) + getrusage(p, RUSAGE_BOTH, ru); + __put_user(SIGCHLD, &info->sig); + __put_user(0, &info->code); + __put_user(p->pid, &info->stuff.procinfo.pid); + __put_user((p->exit_code >> 8) & 0xff, + &info->stuff.procinfo.procdata.child.status); + __put_user(p->times.tms_utime, &info->stuff.procinfo.procdata.child.utime); + __put_user(p->times.tms_stime, &info->stuff.procinfo.procdata.child.stime); + p->exit_code = 0; + retval = 0; + goto end_waitsys; + case TASK_ZOMBIE: + current->times.tms_cutime += p->times.tms_utime + p->times.tms_cutime; + current->times.tms_cstime += p->times.tms_stime + p->times.tms_cstime; + read_unlock(&tasklist_lock); + if (ru != NULL) + getrusage(p, RUSAGE_BOTH, ru); + __put_user(SIGCHLD, &info->sig); + __put_user(1, &info->code); /* CLD_EXITED */ + __put_user(p->pid, &info->stuff.procinfo.pid); + __put_user((p->exit_code >> 8) & 0xff, + &info->stuff.procinfo.procdata.child.status); + __put_user(p->times.tms_utime, + &info->stuff.procinfo.procdata.child.utime); + __put_user(p->times.tms_stime, + &info->stuff.procinfo.procdata.child.stime); + retval = 0; + if (p->p_opptr != p->p_pptr) { + write_lock_irq(&tasklist_lock); + REMOVE_LINKS(p); + p->p_pptr = p->p_opptr; + SET_LINKS(p); + notify_parent(p, SIGCHLD); + write_unlock_irq(&tasklist_lock); + } else + release_task(p); + goto end_waitsys; + default: + continue; } } read_unlock(&tasklist_lock); Index: arch/mips/kernel/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/irq.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/irq.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -211,7 +211,7 @@ void __global_cli(void) { - unsigned int flags; + unsigned long flags; __save_flags(flags); if (flags & ST0_IE) { @@ -870,7 +870,7 @@ if (!shared) { desc->depth = 0; - desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING); + desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS); desc->handler->startup(irq); } spin_unlock_irqrestore(&desc->lock,flags); @@ -916,8 +916,8 @@ return -EFAULT; /* - * Parse the first 8 characters as a hex string, any non-hex char - * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. + * Parse the first HEX_DIGITS characters as a hex string, any non-hex + * char is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. */ value = 0; Index: arch/mips/kernel/irq_cpu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/irq_cpu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/irq_cpu.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/irq_cpu.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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); } Index: arch/mips/kernel/mips_ksyms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/mips_ksyms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/mips_ksyms.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/mips_ksyms.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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 @@ -64,7 +62,7 @@ EXPORT_SYMBOL_NOVERS(strstr); EXPORT_SYMBOL_NOVERS(strtok); -EXPORT_SYMBOL(_clear_page); +EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(kernel_thread); /* @@ -86,35 +84,11 @@ /* * Functions to control caches. */ -EXPORT_SYMBOL(_flush_page_to_ram); EXPORT_SYMBOL(_flush_cache_all); EXPORT_SYMBOL(invalid_pte_table); /* - * Semaphore stuff - */ -EXPORT_SYMBOL(__down); -EXPORT_SYMBOL(__down_interruptible); -EXPORT_SYMBOL(__down_trylock); -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 Index: arch/mips/kernel/old-irq.c =================================================================== RCS file: arch/mips/kernel/old-irq.c diff -N arch/mips/kernel/old-irq.c --- arch/mips/kernel/old-irq.c 22 Jul 2004 19:49:16 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); Index: arch/mips/kernel/old-time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/old-time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/old-time.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/old-time.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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; } Index: arch/mips/kernel/pci-dma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/pci-dma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/pci-dma.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/pci-dma.c 4 Aug 2004 01:25:50 -0000 1.2 @@ -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); Index: arch/mips/kernel/pci.c =================================================================== RCS file: arch/mips/kernel/pci.c diff -N arch/mips/kernel/pci.c --- arch/mips/kernel/pci.c 22 Jul 2004 19:49:16 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 */ -} Index: arch/mips/kernel/pci_auto.c =================================================================== RCS file: arch/mips/kernel/pci_auto.c diff -N arch/mips/kernel/pci_auto.c --- arch/mips/kernel/pci_auto.c 22 Jul 2004 19:49:16 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); -} Index: arch/mips/kernel/proc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/proc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/proc.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/proc.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -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", @@ -43,6 +39,7 @@ [CPU_R6000A] "R6000A", [CPU_R8000] "R8000", [CPU_R10000] "R10000", + [CPU_R12000] "R12000", [CPU_R4300] "R4300", [CPU_R4650] "R4650", [CPU_R4700] "R4700", @@ -51,6 +48,7 @@ [CPU_R4640] "R4640", [CPU_NEVADA] "Nevada", [CPU_RM7000] "RM7000", + [CPU_RM9000] "RM9000", [CPU_R5432] "R5432", [CPU_4KC] "MIPS 4Kc", [CPU_5KC] "MIPS 5Kc", @@ -66,21 +64,24 @@ [CPU_VR41XX] "NEC Vr41xx", [CPU_R5500] "R5500", [CPU_TX49XX] "TX49xx", - [CPU_TX39XX] "TX39xx", [CPU_20KC] "MIPS 20Kc", + [CPU_24K] "MIPS 24K", + [CPU_25KF] "MIPS 25Kf", [CPU_VR4111] "NEC VR4111", [CPU_VR4121] "NEC VR4121", [CPU_VR4122] "NEC VR4122", [CPU_VR4131] "NEC VR4131", + [CPU_VR4133] "NEC VR4133", [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 +98,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 +108,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 +141,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, }; Index: arch/mips/kernel/process.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/process.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/process.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/process.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -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; Index: arch/mips/kernel/ptrace.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/ptrace.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/ptrace.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/ptrace.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -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); Index: arch/mips/kernel/r2300_switch.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/r2300_switch.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/r2300_switch.S 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/r2300_switch.S 4 Aug 2004 01:25:51 -0000 1.2 @@ -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) Index: arch/mips/kernel/r4k_switch.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/r4k_switch.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/r4k_switch.S 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/r4k_switch.S 4 Aug 2004 01:25:51 -0000 1.2 @@ -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) Index: arch/mips/kernel/scall_o32.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/scall_o32.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/scall_o32.S 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/scall_o32.S 4 Aug 2004 01:25:51 -0000 1.2 @@ -18,7 +18,7 @@ #include /* Highest syscall used of any syscall flavour */ -#define MAX_SYSCALL_NO __NR_Linux + __NR_Linux_syscalls +#define MAX_SYSCALL_NO __NR_O32_Linux + __NR_O32_Linux_syscalls .align 5 NESTED(handle_sys, PT_SIZE, sp) @@ -309,7 +309,7 @@ LEAF(sys_syscall) lw 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 sll v0, a0, 2 Index: arch/mips/kernel/semaphore.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/semaphore.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/semaphore.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/semaphore.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -1,129 +1,272 @@ /* - * Generic semaphore code. Buyer beware. Do your own - * specific changes in + * Copyright (C) 1999, 2001, 02, 03 Ralf Baechle + * + * Heavily inspired by the Alpha implementation */ - +#include +#include +#include #include -#include + +#ifdef CONFIG_CPU_HAS_LLDSCD +/* + * On machines without lld/scd we need a spinlock to make the manipulation of + * sem->count and sem->waking atomic. Scalability isn't an issue because + * this lock is used on UP only so it's just an empty variable. + */ +spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED; + +EXPORT_SYMBOL(semaphore_lock); +#endif /* - * 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. + * 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() 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) +void __up_wakeup(struct semaphore *sem) { - wake_one_more(sem); wake_up(&sem->wait); } +EXPORT_SYMBOL(__up_wakeup); + +#ifdef CONFIG_CPU_HAS_LLSC + +static inline int waking_non_zero(struct semaphore *sem) +{ + int ret, tmp; + + __asm__ __volatile__( + "1: ll %1, %2 # waking_non_zero \n" + " blez %1, 2f \n" + " subu %0, %1, 1 \n" + " sc %0, %2 \n" + " beqz %0, 1b \n" + "2: \n" + : "=r" (ret), "=r" (tmp), "+m" (sem->waking) + : "0" (0)); + + return ret; +} + +#else /* !CONFIG_CPU_HAS_LLSC */ + +static inline int waking_non_zero(struct semaphore *sem) +{ + unsigned long flags; + int waking, ret = 0; + + spin_lock_irqsave(&semaphore_lock, flags); + waking = atomic_read(&sem->waking); + if (waking > 0) { + atomic_set(&sem->waking, waking - 1); + ret = 1; + } + spin_unlock_irqrestore(&semaphore_lock, flags); + + return ret; +} + +#endif /* !CONFIG_CPU_HAS_LLSC */ + /* - * Perform the "down" function. Return zero for semaphore acquired, - * return negative for signalled out of the function. + * 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). + * 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. * - * Either form may be used in conjunction with "up()". + * 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; \ +void __down_failed(struct semaphore * sem) +{ + struct task_struct *tsk = current; + wait_queue_t wait; + init_waitqueue_entry(&wait, tsk); + __set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue_exclusive(&sem->wait, &wait); -#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. \ - */ \ + /* + * 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; \ + if (waking_non_zero(sem)) + break; + schedule(); + __set_current_state(TASK_UNINTERRUPTIBLE); + } + __set_current_state(TASK_RUNNING); remove_wait_queue(&sem->wait, &wait); +} + +EXPORT_SYMBOL(__down_failed); + +#ifdef CONFIG_CPU_HAS_LLDSCD + +/* + * waking_non_zero_interruptible: + * 1 got the lock + * 0 go to sleep + * -EINTR interrupted + * + * We must undo the sem->count down_interruptible decrement + * simultaneously and atomically with the sem->waking adjustment, + * otherwise we can race with wake_one_more. + * + * This is accomplished by doing a 64-bit lld/scd on the 2 32-bit words. + * + * This is crazy. Normally it's strictly forbidden to use 64-bit operations + * in the 32-bit MIPS kernel. In this case it's however ok because if an + * interrupt has destroyed the upper half of registers sc will fail. + * Note also that this will not work for MIPS32 CPUs! + * + * Pseudocode: + * + * If(sem->waking > 0) { + * Decrement(sem->waking) + * Return(SUCCESS) + * } else If(signal_pending(tsk)) { + * Increment(sem->count) + * Return(-EINTR) + * } else { + * Return(SLEEP) + * } + */ -void __down(struct semaphore * sem) +static inline int +waking_non_zero_interruptible(struct semaphore *sem, struct task_struct *tsk) { - DOWN_VAR - DOWN_HEAD(TASK_UNINTERRUPTIBLE) - if (waking_non_zero(sem)) - break; - schedule(); - DOWN_TAIL(TASK_UNINTERRUPTIBLE) + long ret, tmp; + + __asm__ __volatile__( + " .set push # waking_non_zero_interruptible \n" + " .set mips3 \n" + " .set noat \n" + "0: lld %1, %2 \n" + " li %0, 0 \n" + " sll $1, %1, 0 \n" + " blez $1, 1f \n" + " daddiu %1, %1, -1 \n" + " li %0, 1 \n" + " b 2f \n" + "1: beqz %3, 2f \n" + " li %0, %4 \n" + " dli $1, 0x0000000100000000 \n" + " daddu %1, %1, $1 \n" + "2: scd %1, %2 \n" + " beqz %1, 0b \n" + " .set pop \n" + : "=&r" (ret), "=&r" (tmp), "=m" (*sem) + : "r" (signal_pending(tsk)), "i" (-EINTR)); + + return ret; } -int __down_interruptible(struct semaphore * sem) +#else /* !CONFIG_CPU_HAS_LLDSCD */ + +static inline int waking_non_zero_interruptible(struct semaphore *sem, + struct task_struct *tsk) { - int ret = 0; - DOWN_VAR - DOWN_HEAD(TASK_INTERRUPTIBLE) + int waking, pending, ret = 0; + unsigned long flags; - ret = waking_non_zero_interruptible(sem, tsk); - if (ret) - { - if (ret == 1) - /* ret != 0 only if we get interrupted -arca */ - ret = 0; - break; + pending = signal_pending(tsk); + + spin_lock_irqsave(&semaphore_lock, flags); + waking = atomic_read(&sem->waking); + if (waking > 0) { + atomic_set(&sem->waking, waking - 1); + ret = 1; + } else if (pending) { + atomic_set(&sem->count, atomic_read(&sem->count) + 1); + ret = -EINTR; } - schedule(); - DOWN_TAIL(TASK_INTERRUPTIBLE) + spin_unlock_irqrestore(&semaphore_lock, flags); + return ret; } -int __down_trylock(struct semaphore * sem) +#endif /* !CONFIG_CPU_HAS_LLDSCD */ + +int __down_failed_interruptible(struct semaphore * sem) { - return waking_non_zero_trylock(sem); + struct task_struct *tsk = current; + wait_queue_t wait; + int ret = 0; + + init_waitqueue_entry(&wait, tsk); + __set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue_exclusive(&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 (;;) { + ret = waking_non_zero_interruptible(sem, tsk); + if (ret) { + if (ret == 1) + /* ret != 0 only if we get interrupted -arca */ + ret = 0; + break; + } + schedule(); + __set_current_state(TASK_INTERRUPTIBLE); + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&sem->wait, &wait); + + return ret; } + +EXPORT_SYMBOL(__down_failed_interruptible); Index: arch/mips/kernel/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/setup.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/setup.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -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", - PHYSADDR(initrd_end), + "(0x%08lx > 0x%08lx)\ndisabling initrd\n", + (unsigned long) 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,268 @@ } } +#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 momenco_jaguar_atx_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_MOMENCO_JAGUAR_ATX + case MACH_GROUP_MOMENCO: + momenco_jaguar_atx_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 +#ifdef CONFIG_PMC_YOSEMITE + case MACH_GROUP_TITAN: + pmc_yosemite_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); Index: arch/mips/kernel/signal.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/signal.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/signal.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/signal.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -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); Index: arch/mips/kernel/smp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/smp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/smp.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/smp.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -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. */ @@ -54,39 +52,6 @@ int __cpu_logical_map[NR_CPUS]; cycles_t cacheflush_time; -/* These are defined by the board-specific code. */ - -/* - * Cause the function described by call_data to be executed on the passed - * cpu. When the function has finished, increment the finished field of - * call_data. - */ -void core_send_ipi(int cpu, unsigned int action); - -/* - * Clear all undefined state in the cpu, set up sp and gp to the passed - * values, and kick the cpu into smp_bootstrap(); - */ -void prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp); - -/* - * After we've done initial boot, this function is called to allow the - * board code to clean up state, if needed - */ -void prom_init_secondary(void); - -/* - * Do whatever setup needs to be done for SMP at the board level. Return - * the number of cpus in the system, including this one - */ -int prom_setup_smp(void); - -void prom_smp_finish(void); - -static void smp_tune_scheduling(void) -{ -} - void __init smp_callin(void) { #if 0 @@ -95,33 +60,6 @@ #endif } -#ifndef CONFIG_SGI_IP27 -/* - * Hook for doing final board-specific setup after the generic smp setup - * is done - */ -asmlinkage void start_secondary(void) -{ - unsigned int cpu = smp_processor_id(); - - prom_init_secondary(); - per_cpu_trap_init(); - - /* - * XXX parity protection should be folded in here when it's converted - * to an option instead of something based on .cputype - */ - pgd_current[cpu] = init_mm.pgd; - cpu_data[cpu].udelay_val = loops_per_jiffy; - prom_smp_finish(); - printk("Slave cpu booted successfully\n"); - CPUMASK_SETB(cpu_online_map, cpu); - atomic_inc(&cpus_booted); - while (!atomic_read(&smp_commenced)); - cpu_idle(); -} -#endif /* CONFIG_SGI_IP27 */ - void __init smp_commence(void) { wmb(); @@ -138,7 +76,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 +108,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 +124,7 @@ if (wait) while (atomic_read(&data.finished) != cpus) barrier(); - spin_unlock(&call_lock); + spin_unlock(&smp_call_lock); return 0; } @@ -224,7 +162,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 +220,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 +252,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 +276,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); } Index: arch/mips/kernel/syscall.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/syscall.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/syscall.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/syscall.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -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,86 @@ 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 an R4k-compatible timer of a known frequency. + */ +static void c0_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 use solely as a high precision timer. */ +static void c0_hpt_init(unsigned int count) +{ + write_c0_count(read_c0_count() - count); +} + +/* For use both as a high precision timer and an interrupt source. */ +static void c0_hpt_timer_init(unsigned int count) +{ + count = read_c0_count() - count; + expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy; + write_c0_count(expirelo - cycles_per_jiffy); + write_c0_compare(expirelo); + write_c0_count(count); +} + +int (*mips_timer_state)(void); +void (*mips_timer_ack)(void); +unsigned int (*mips_hpt_read)(void); +void (*mips_hpt_init)(unsigned int); /* @@ -65,22 +156,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 +180,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 +213,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 +283,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 +309,7 @@ return res; } -unsigned long calibrate_div64_gettimeoffset(void) +static unsigned long calibrate_div64_gettimeoffset(void) { u32 count; unsigned long res, tmp; @@ -239,54 +319,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" + "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) + : "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 +393,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 +406,20 @@ } /* - * 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; - - /* - * 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; + unsigned long j; + unsigned int count; - /* - * 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); + count = mips_hpt_read(); + mips_timer_ack(); - } + /* Update timerhi/timerlo for intra-jiffy calibration. */ + timerhi += count < timerlo; /* Wrap around */ + timerlo = count; /* * call the generic timer interrupt handling @@ -360,27 +431,59 @@ * 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; + * + * The first timer interrupt comes late as interrupts are + * enabled long after timers are initialized. Therefore the + * high precision timer is fast, leading to wrong gettimeoffset() + * calculations. We deal with it by setting it based on the + * number of its ticks between the second and the third interrupt. + * That is still somewhat imprecise, but it's a good estimate. + * --macro + */ + j = jiffies; + if (j < 4) { + static unsigned int prev_count; + static int hpt_initialized; + + switch (j) { + case 0: + timerhi = timerlo = 0; + mips_hpt_init(count); + break; + case 2: + prev_count = count; + break; + case 3: + if (!hpt_initialized) { + unsigned int c3 = 3 * (count - prev_count); + + timerhi = 0; + timerlo = c3; + mips_hpt_init(count - c3); + hpt_initialized = 1; + } + break; + default: + break; + } } #if !defined(CONFIG_SMP) @@ -391,7 +494,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 */ @@ -430,7 +533,9 @@ int cpu = smp_processor_id(); irq_enter(cpu, irq); - kstat.irqs[cpu][irq]++; + + if (cpu != 0) + kstat.irqs[cpu][irq]++; /* we keep interrupt disabled all the time */ local_timer_interrupt(irq, NULL, regs); @@ -446,7 +551,7 @@ * * 1) board_time_init() - * a) (optional) set up RTC routines, - * b) (optional) calibrate and set the mips_counter_frequency + * b) (optional) calibrate and set the mips_hpt_frequency * (only needed if you intended to use fixed_rate_gettimeoffset * or use cpu counter as timer interrupt source) * 2) setup xtime based on rtc_get_time(). @@ -458,74 +563,144 @@ * 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_hpt_frequency; static struct irqaction timer_irqaction = { - timer_interrupt, - SA_INTERRUPT, - 0, - "timer", - NULL, - NULL + .handler = timer_interrupt, + .flags = SA_INTERRUPT, + .name = "timer", }; +static unsigned int __init calibrate_hpt(void) +{ + u64 frequency; + u32 hpt_start, hpt_end, hpt_count, hz; + + const int loops = HZ / 10; + int log_2_loops = 0; + int i; + + /* + * We want to calibrate for 0.1s, but to avoid a 64-bit + * division we round the number of loops up to the nearest + * power of 2. + */ + while (loops > 1 << log_2_loops) + log_2_loops++; + i = 1 << log_2_loops; + + /* + * Wait for a rising edge of the timer interrupt. + */ + while (mips_timer_state()); + while (!mips_timer_state()); + + /* + * Now see how many high precision timer ticks happen + * during the calculated number of periods between timer + * interrupts. + */ + hpt_start = mips_hpt_read(); + do { + while (mips_timer_state()); + while (!mips_timer_state()); + } while (--i); + hpt_end = mips_hpt_read(); + + hpt_count = hpt_end - hpt_start; + hz = HZ; + frequency = (u64)hpt_count * (u64)hz; + + return frequency >> log_2_loops; +} + 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_hpt_frequency && !mips_timer_state) { + /* 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. Or we can get it. */ + if (!mips_hpt_read) { + /* No external high precision timer -- use R4k. */ + mips_hpt_read = c0_hpt_read; + + if (mips_timer_state) + mips_hpt_init = c0_hpt_init; + else { + /* No external timer interrupt -- use R4k. */ + mips_hpt_init = c0_hpt_timer_init; + mips_timer_ack = c0_timer_ack; + } + } + if (!mips_hpt_frequency) + mips_hpt_frequency = calibrate_hpt(); - /* caclulate cache parameters */ - if (mips_counter_frequency) { - u32 count; - - 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 = mips_counter_frequency / 100000; - sll32_usecs_per_cycle = 0xffffffff / sll32_usecs_per_cycle; - sll32_usecs_per_cycle *= 10; + do_gettimeoffset = fixed_rate_gettimeoffset; - /* - * 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); - } + /* Calculate cache parameters. */ + cycles_per_jiffy = (mips_hpt_frequency + HZ / 2) / HZ; + + /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */ + do_div64_32(sll32_usecs_per_cycle, + 1000000, mips_hpt_frequency / 2, + mips_hpt_frequency); + + /* Report the high precision timer rate for a reference. */ + printk("Using %u.%03u MHz high precision timer.\n", + ((mips_hpt_frequency + 500) / 1000) / 1000, + ((mips_hpt_frequency + 500) / 1000) % 1000); + } + + 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 +713,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 +736,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 +753,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); Index: arch/mips/kernel/traps.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/traps.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/traps.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/traps.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -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,9 @@ 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); +void (*board_nmi_handler_setup)(void); int kstack_depth_to_print = 24; @@ -81,107 +74,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 +212,7 @@ } } -void show_regs(struct pt_regs * regs) +void show_regs(struct pt_regs *regs) { /* * Saved main processor registers @@ -330,10 +222,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]); @@ -343,9 +235,10 @@ /* * Saved cp0 registers */ - printk("epc : %08lx %s\nStatus: %08lx\nCause : %08lx\n", - regs->cp0_epc, print_tainted(), regs->cp0_status, - regs->cp0_cause); + printk("epc : %08lx %s\n", regs->cp0_epc, print_tainted()); + printk("Status: %08lx\n", regs->cp0_status); + printk("Cause : %08lx\n", regs->cp0_cause); + printk("PrId : %08x\n", read_c0_prid()); } void show_registers(struct pt_regs *regs) @@ -433,7 +326,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 +357,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 +385,153 @@ 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; + + 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; - if (compute_return_epc(regs)) + /* + * 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; + } + + return -EFAULT; /* Strange things going on ... */ +} + +asmlinkage void do_ov(struct pt_regs *regs) +{ + siginfo_t info; info.si_code = FPE_INTOVF; info.si_signo = SIGFPE; @@ -541,41 +575,21 @@ /* 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; siginfo_t info; + die_if_kernel("Break instruction in kernel code", regs); + if (get_insn_opcode(regs, &opcode)) return; @@ -611,8 +625,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 +658,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 +749,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 +759,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 +776,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 +794,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 +811,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 +845,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 +863,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 +873,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 +885,39 @@ unsigned int cpu = smp_processor_id(); /* Some firmware leaves the BEV flag set, clear it. */ - clear_cp0_status(ST0_BEV); + clear_c0_status(ST0_CU3|ST0_CU2|ST0_CU1|ST0_BEV|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(cpu << 23); + write_c0_context(cpu << 23); + + atomic_inc(&init_mm.mm_count); + current->active_mm = &init_mm; + BUG_ON(current->mm); + 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 +929,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 +957,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 +975,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 +1002,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 +1012,12 @@ restore_fp_context = fpu_emulator_restore_context; } - if (mips_cpu.isa_level == MIPS_CPU_ISA_IV) - set_cp0_status(ST0_XX); + if (board_nmi_handler_setup) + board_nmi_handler_setup(); + + 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 */ Index: arch/mips/kernel/unaligned.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/kernel/unaligned.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/kernel/unaligned.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/kernel/unaligned.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -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 @@ -40,7 +40,7 @@ * Below a little program to play around with this feature. * * #include - * #include + * #include * * struct foo { * unsigned char bar[8]; @@ -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; } Index: arch/mips/kernel/vm86.c =================================================================== RCS file: arch/mips/kernel/vm86.c diff -N arch/mips/kernel/vm86.c --- arch/mips/kernel/vm86.c 22 Jul 2004 19:49:16 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; -} Index: arch/mips/lib/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/lib/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/lib/Makefile 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/lib/Makefile 4 Aug 2004 01:25:51 -0000 1.2 @@ -7,9 +7,11 @@ 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 + +export-objs := rtc-std.o rtc-no.o ifeq ($(CONFIG_CPU_R3000)$(CONFIG_CPU_TX39XX),y) obj-y += r3k_dump_tlb.o @@ -18,7 +20,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 Index: arch/mips/lib/dump_tlb.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/lib/dump_tlb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/lib/dump_tlb.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/lib/dump_tlb.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -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++; } } Index: arch/mips/lib/ide-no.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/lib/ide-no.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/lib/ide-no.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/lib/ide-no.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -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 }; Index: arch/mips/lib/ide-std.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/lib/ide-std.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/lib/ide-std.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/lib/ide-std.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -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 }; Index: arch/mips/lib/kbd-no.c =================================================================== RCS file: arch/mips/lib/kbd-no.c diff -N arch/mips/lib/kbd-no.c --- arch/mips/lib/kbd-no.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 -}; Index: arch/mips/lib/memcpy.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/lib/memcpy.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/lib/memcpy.S 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/lib/memcpy.S 4 Aug 2004 01:25:51 -0000 1.2 @@ -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 Index: arch/mips/lib/r3k_dump_tlb.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/lib/r3k_dump_tlb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/lib/r3k_dump_tlb.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/lib/r3k_dump_tlb.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -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 Index: arch/mips/lib/rtc-no.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/lib/rtc-no.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/lib/rtc-no.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/lib/rtc-no.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -9,6 +9,7 @@ * Copyright (C) 1998, 2001 by Ralf Baechle */ #include +#include #include static unsigned int shouldnt_happen(void) @@ -24,7 +25,9 @@ } 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 }; + +EXPORT_SYMBOL(rtc_ops); Index: arch/mips/lib/rtc-std.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/lib/rtc-std.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/lib/rtc-std.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/lib/rtc-std.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -7,6 +7,7 @@ * * Copyright (C) 1998, 2001 by Ralf Baechle */ +#include #include #include @@ -32,3 +33,5 @@ &std_rtc_write_data, &std_rtc_bcd_mode }; + +EXPORT_SYMBOL(rtc_ops); Index: arch/mips/math-emu/cp1emu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/math-emu/cp1emu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/math-emu/cp1emu.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/math-emu/cp1emu.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -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; Index: arch/mips/math-emu/dp_cmp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/math-emu/dp_cmp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/math-emu/dp_cmp.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/math-emu/dp_cmp.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -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; Index: arch/mips/math-emu/dp_fint.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/math-emu/dp_fint.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/math-emu/dp_fint.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/math-emu/dp_fint.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -33,6 +33,8 @@ CLEARCX; + xc = ( 0 ? xc : xc ); + if (x == 0) return ieee754dp_zero(0); if (x == 1 || x == -1) Index: arch/mips/math-emu/dp_flong.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/math-emu/dp_flong.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/math-emu/dp_flong.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/math-emu/dp_flong.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -33,6 +33,8 @@ CLEARCX; + xc = ( 0 ? xc : xc ); + if (x == 0) return ieee754dp_zero(0); if (x == 1 || x == -1) Index: arch/mips/math-emu/ieee754dp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/math-emu/ieee754dp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/math-emu/ieee754dp.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/math-emu/ieee754dp.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -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)) Index: arch/mips/math-emu/ieee754int.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/math-emu/ieee754int.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/math-emu/ieee754int.h 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/math-emu/ieee754int.h 4 Aug 2004 01:25:51 -0000 1.2 @@ -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) Index: arch/mips/math-emu/ieee754sp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/math-emu/ieee754sp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/math-emu/ieee754sp.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/math-emu/ieee754sp.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -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)) Index: arch/mips/math-emu/ieee754xcpt.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/math-emu/ieee754xcpt.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/math-emu/ieee754xcpt.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/math-emu/ieee754xcpt.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -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]); } Index: arch/mips/math-emu/kernel_linkage.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/math-emu/kernel_linkage.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/math-emu/kernel_linkage.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/math-emu/kernel_linkage.c 4 Aug 2004 01:25:51 -0000 1.2 @@ -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 Index: arch/mips/math-emu/sp_cmp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/math-emu/sp_cmp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/math-emu/sp_cmp.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/math-emu/sp_cmp.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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; Index: arch/mips/math-emu/sp_fint.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/math-emu/sp_fint.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/math-emu/sp_fint.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/math-emu/sp_fint.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -33,6 +33,8 @@ CLEARCX; + xc = ( 0 ? xc : xc ); + if (x == 0) return ieee754sp_zero(0); if (x == 1 || x == -1) Index: arch/mips/math-emu/sp_flong.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/math-emu/sp_flong.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/math-emu/sp_flong.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/math-emu/sp_flong.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -33,6 +33,8 @@ CLEARCX; + xc = ( 0 ? xc : xc ); + if (x == 0) return ieee754sp_zero(0); if (x == 1 || x == -1) Index: arch/mips/math-emu/sp_sqrt.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/math-emu/sp_sqrt.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/math-emu/sp_sqrt.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/math-emu/sp_sqrt.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -29,7 +29,6 @@ ieee754sp ieee754sp_sqrt(ieee754sp x) { - int sign = (int) 0x80000000; int ix, s, q, m, t, i; unsigned int r; COMPXSP; Index: arch/mips/math-emu/sp_sub.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/math-emu/sp_sub.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/math-emu/sp_sub.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/math-emu/sp_sub.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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) { Index: arch/mips/mips-boards/atlas/atlas_int.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mips-boards/atlas/atlas_int.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mips-boards/atlas/atlas_int.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/mips-boards/atlas/atlas_int.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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(); Index: arch/mips/mips-boards/atlas/atlas_setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mips-boards/atlas/atlas_setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mips-boards/atlas/atlas_setup.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/mips-boards/atlas/atlas_setup.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -29,16 +30,11 @@ #include #include #include -#include +#include #include #include -#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE) -extern void console_setup(char *, int *); -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 +50,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); @@ -79,18 +71,24 @@ #ifdef CONFIG_SERIAL_CONSOLE argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) { - int i = 0; + struct console_cmdline *c = &console_cmdline[0]; char *s = prom_getenv("modetty0"); - while(s[i] >= '0' && s[i] <= '9') + int i = 0; + static char options[8]; + while (s && s[i] >= '0' && s[i] <= '9') { + options[i] = s[i]; i++; - strcpy(serial_console, "ttyS0,"); - strncpy(serial_console + 6, s, i); - prom_printf("Config serial console: %s\n", serial_console); - console_setup(serial_console, NULL); + } + options[i] = 0; + strcpy(c->name, "ttyS"); + c->options = s ? options : NULL; + c->index = 0; + prom_printf("Serial console: %s%d %s\n", + c->name, c->index, options); } #endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) { int line; @@ -122,7 +120,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; Index: arch/mips/mips-boards/generic/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mips-boards/generic/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mips-boards/generic/Makefile 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/mips-boards/generic/Makefile 4 Aug 2004 01:25:52 -0000 1.2 @@ -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 Index: arch/mips/mips-boards/generic/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mips-boards/generic/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mips-boards/generic/init.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/mips-boards/generic/init.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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(); Index: arch/mips/mips-boards/generic/memory.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mips-boards/generic/memory.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mips-boards/generic/memory.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/mips-boards/generic/memory.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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; } Index: arch/mips/mips-boards/generic/pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mips-boards/generic/pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mips-boards/generic/pci.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/mips-boards/generic/pci.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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 */ Index: arch/mips/mips-boards/generic/printf.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mips-boards/generic/printf.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mips-boards/generic/printf.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/mips-boards/generic/printf.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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); } Index: arch/mips/mips-boards/generic/time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mips-boards/generic/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mips-boards/generic/time.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/mips-boards/generic/time.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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,27 +87,27 @@ */ 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_hpt_frequency = read_c0_count(); /* restore interrupts */ - __restore_flags(flags); + local_irq_restore(flags); - return (mips_counter_frequency / HZ); + return (mips_hpt_frequency / HZ); } unsigned long __init mips_rtc_get_time(void) @@ -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); } Index: arch/mips/mips-boards/malta/malta_int.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mips-boards/malta/malta_int.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mips-boards/malta/malta_int.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/mips-boards/malta/malta_int.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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,11 +158,11 @@ 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); - printk("GT_CPU_ERR_ADDR = %0x2%08x\n", datahi,data); + data = GT_READ(0x70); + datahi = GT_READ(0x78); + printk("GT_CPU_ERR_ADDR = %02x%08x\n", datahi, data); break; case MIPS_REVISION_CORID_BONITO64: case MIPS_REVISION_CORID_CORE_20K: @@ -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(); Index: arch/mips/mips-boards/malta/malta_setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mips-boards/malta/malta_setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mips-boards/malta/malta_setup.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/mips-boards/malta/malta_setup.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -45,16 +45,9 @@ #include #endif -#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE) -extern void console_setup(char *, int *); -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 +57,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 +75,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 +103,7 @@ } #endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) { int line; @@ -130,8 +116,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 +129,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; Index: arch/mips/mips-boards/sead/sead_int.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mips-boards/sead/sead_int.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mips-boards/sead/sead_int.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/mips-boards/sead/sead_int.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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; Index: arch/mips/mips-boards/sead/sead_setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mips-boards/sead/sead_setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mips-boards/sead/sead_setup.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/mips-boards/sead/sead_setup.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -31,11 +32,6 @@ #include #include -#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE) -extern void console_setup(char *, int *); -char serial_console[20]; -#endif - extern void mips_reboot_setup(void); extern void mips_time_init(void); extern void mips_timer_setup(struct irqaction *irq); @@ -45,10 +41,6 @@ return "MIPS SEAD"; } -void __init bus_error_init(void) -{ -} - void __init sead_setup(void) { char *argptr; @@ -58,21 +50,27 @@ #ifdef CONFIG_SERIAL_CONSOLE argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) { - int i = 0; + struct console_cmdline *c = &console_cmdline[0]; char *s = prom_getenv("modetty0"); - while(s[i] >= '0' && s[i] <= '9') + int i = 0; + static char options[8]; + while (s && s[i] >= '0' && s[i] <= '9') { + options[i] = s[i]; i++; - strcpy(serial_console, "ttyS0,"); - strncpy(serial_console + 6, s, i); - prom_printf("Config serial console: %s\n", serial_console); - console_setup(serial_console, NULL); + } + options[i] = 0; + strcpy(c->name, "ttyS"); + c->options = s ? options : NULL; + c->index = 0; + prom_printf("Serial console: %s%d %s\n", + c->name, c->index, options); } #endif 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; Index: arch/mips/mips-boards/sead/sead_time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mips-boards/sead/sead_time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mips-boards/sead/sead_time.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/mips-boards/sead/sead_time.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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); } Index: arch/mips/mm/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mm/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mm/Makefile 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/mm/Makefile 4 Aug 2004 01:25:52 -0000 1.2 @@ -10,28 +10,30 @@ 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_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_R3000) += pg-r4k.o c-r3k.o tlb-r3k.o tlbex-r3k.o +obj-$(CONFIG_CPU_TX39XX) += pg-r4k.o c-tx39.o tlb-r3k.o tlbex-r3k.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_RM9000) += 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_RM7000_CPU_SCACHE) += sc-rm7k.o +obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o +obj-$(CONFIG_SGI_IP22) += sc-ip22.o include $(TOPDIR)/Rules.make Index: arch/mips/mm/c-andes.c =================================================================== RCS file: arch/mips/mm/c-andes.c diff -N arch/mips/mm/c-andes.c --- arch/mips/mm/c-andes.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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(); -} Index: arch/mips/mm/c-mips32.c =================================================================== RCS file: arch/mips/mm/c-mips32.c diff -N arch/mips/mm/c-mips32.c --- arch/mips/mm/c-mips32.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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(); -} Index: arch/mips/mm/c-r3k.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mm/c-r3k.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mm/c-r3k.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/mm/c-r3k.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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 @@ -34,14 +35,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 +58,7 @@ size = 0; } - write_32bit_cp0_register(CP0_STATUS, flags); + write_c0_status(flags); return size * sizeof(*p); } @@ -69,24 +70,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 +98,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 +115,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 +157,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 +172,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 +214,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 +241,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 +259,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 +268,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 +291,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) @@ -319,10 +317,8 @@ void __init ld_mmu_r23000(void) { - unsigned long config; - - _clear_page = r3k_clear_page; - _copy_page = r3k_copy_page; + extern void build_clear_page(void); + extern void build_copy_page(void); r3k_probe_cache(); @@ -331,16 +327,19 @@ _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; + _flush_cache_sigtramp = r3k_flush_cache_sigtramp; + _flush_data_cache_page = r3k_flush_data_cache_page; + _dma_cache_wback_inv = r3k_dma_cache_wback_inv; - 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); + 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); + build_clear_page(); + build_copy_page(); } Index: arch/mips/mm/c-r4k.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mm/c-r4k.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mm/c-r4k.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/mm/c-r4k.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -3,44 +3,30 @@ * 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 - -#undef DEBUG_CACHE +static unsigned long icache_size, dcache_size, scache_size; /* * Dummy cache handling routines for machines without boardcaches @@ -48,884 +34,259 @@ 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 void (* r4k_blast_dcache_page)(unsigned long addr); -static inline void r4k_flush_cache_all_s16d16i16(void) +static inline void r4k_blast_dcache_page_dc32(unsigned long addr) { - blast_dcache16(); blast_icache16(); blast_scache16(); + R4600_HIT_CACHEOP_WAR_IMPL; + blast_dcache32_page(addr); } -static inline void r4k_flush_cache_all_s32d16i16(void) +static inline void r4k_blast_dcache_page_setup(void) { - blast_dcache16(); blast_icache16(); blast_scache32(); -} + unsigned long dc_lsize = current_cpu_data.dcache.linesz; -static inline void r4k_flush_cache_all_s64d16i16(void) -{ - blast_dcache16(); blast_icache16(); blast_scache64(); + if (dc_lsize == 16) + r4k_blast_dcache_page = blast_dcache16_page; + else if (dc_lsize == 32) + r4k_blast_dcache_page = r4k_blast_dcache_page_dc32; } -static inline void r4k_flush_cache_all_s128d16i16(void) -{ - blast_dcache16(); blast_icache16(); blast_scache128(); -} +static void (* r4k_blast_dcache_page_indexed)(unsigned long addr); -static inline void r4k_flush_cache_all_s32d32i32(void) +static void r4k_blast_dcache_page_indexed_setup(void) { - blast_dcache32(); blast_icache32(); blast_scache32(); -} + unsigned long 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) + r4k_blast_dcache_page_indexed = blast_dcache16_page_indexed; + else if (dc_lsize == 32) + r4k_blast_dcache_page_indexed = blast_dcache32_page_indexed; } -static inline void r4k_flush_cache_all_s128d32i32(void) -{ - blast_dcache32(); blast_icache32(); blast_scache128(); -} +static void (* r4k_blast_dcache)(void); -static inline void r4k_flush_cache_all_d16i16(void) +static inline void r4k_blast_dcache_setup(void) { - blast_dcache16(); blast_icache16(); -} + unsigned long dc_lsize = current_cpu_data.dcache.linesz; -static inline void r4k_flush_cache_all_d32i32(void) -{ - blast_dcache32(); blast_icache32(); + if (dc_lsize == 16) + r4k_blast_dcache = blast_dcache16; + else if (dc_lsize == 32) + r4k_blast_dcache = blast_dcache32; } -static void -r4k_flush_cache_range_s16d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - - 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_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; - } - } - } -} +/* 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 void -r4k_flush_cache_range_s32d16i16(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_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; - } - } - } + 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_s64d16i16(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; - - if (mm->context == 0) - return; + 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; - 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; - } - } - } + 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_s128d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - - if (mm->context == 0) - return; +static void (* r4k_blast_icache_page)(unsigned long 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_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 r4k_blast_icache_page_setup(void) { - struct vm_area_struct *vma; - - if (mm->context == 0) - return; + unsigned long ic_lsize = current_cpu_data.icache.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_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; - } - } - } + if (ic_lsize == 16) + r4k_blast_icache_page = blast_icache16_page; + else if (ic_lsize == 32) + r4k_blast_icache_page = blast_icache32_page; + else if (ic_lsize == 64) + r4k_blast_icache_page = blast_icache64_page; } -static void r4k_flush_cache_range_s64d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - - 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; - } - } - } -} +static void (* r4k_blast_icache_page_indexed)(unsigned long addr); -static void r4k_flush_cache_range_s128d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) +static inline void r4k_blast_icache_page_indexed_setup(void) { - struct vm_area_struct *vma; - - if (mm->context == 0) - return; + unsigned long ic_lsize = current_cpu_data.icache.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_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 (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - blast_dcache16(); blast_icache16(); - } + if (ic_lsize == 16) + r4k_blast_icache_page_indexed = blast_icache16_page_indexed; + else if (ic_lsize == 32 && TX49XX_ICACHE_INDEX_INV_WAR) + r4k_blast_icache_page_indexed = tx49_blast_icache32_page_indexed; + else if (ic_lsize == 32) + r4k_blast_icache_page_indexed = blast_icache32_page_indexed; + else if (ic_lsize == 64) + r4k_blast_icache_page_indexed = blast_icache64_page_indexed; } -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(); - } -} +static void (* r4k_blast_icache)(void); -/* - * 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) +static inline void r4k_blast_icache_setup(void) { - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s16d16i16(); - } -} + unsigned long ic_lsize = current_cpu_data.icache.linesz; -static void r4k_flush_cache_mm_s32d16i16(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s32d16i16(); - } + if (ic_lsize == 16) + r4k_blast_icache = blast_icache16; + else if (ic_lsize == 32 && TX49XX_ICACHE_INDEX_INV_WAR) + r4k_blast_icache = tx49_blast_icache32; + else if (ic_lsize == 32) + r4k_blast_icache = blast_icache32; + else if (ic_lsize == 64) + r4k_blast_icache = blast_icache64; } -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(); - } -} +static void (* r4k_blast_scache_page)(unsigned long addr); -static void r4k_flush_cache_mm_s128d16i16(struct mm_struct *mm) +static inline void r4k_blast_scache_page_setup(void) { - if (mm->context != 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 (mm->context != 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 (mm->context != 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 (mm->context != 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 (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_d16i16(); - } -} + unsigned long sc_lsize = current_cpu_data.scache.linesz; -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(); - } + if (sc_lsize == 16) + r4k_blast_scache_page = blast_scache16_page; + else if (sc_lsize == 32) + r4k_blast_scache_page = blast_scache32_page; + else if (sc_lsize == 64) + r4k_blast_scache_page = blast_scache64_page; + else if (sc_lsize == 128) + r4k_blast_scache_page = blast_scache128_page; } -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 (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_scache16_page_indexed(page); - } else - blast_scache16_page(page); -out: -} +static void (* r4k_blast_scache)(void); -static void r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma, - unsigned long page) +static inline void r4k_blast_scache_setup(void) { - 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; + unsigned long sc_lsize = current_cpu_data.scache.linesz; -#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_scache32_page_indexed(page); - } else - blast_scache32_page(page); -out: + if (sc_lsize == 16) + r4k_blast_scache = blast_scache16; + else if (sc_lsize == 32) + r4k_blast_scache = blast_scache32; + else if (sc_lsize == 64) + r4k_blast_scache = blast_scache64; + else if (sc_lsize == 128) + r4k_blast_scache = blast_scache128; } -static void r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma, - unsigned long page) +static void r4k_flush_cache_all(void) { - 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) + 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 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: -} - -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 (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_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); - - /* - * 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_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 (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: -} - -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 (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_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 (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 == 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); + + 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(); } -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 +296,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 +309,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 +318,218 @@ * 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); + ClearPageDcacheDirty(page); + + return; + } + + if (!cpu_has_ic_fills_f_dc) { + unsigned long addr = (unsigned long) page_address(page); + r4k_blast_dcache_page(addr); + ClearPageDcacheDirty(page); + } + + /* + * 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,354 +538,543 @@ */ 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; - /* Clear internal cache refill buffer */ - *(volatile unsigned int *)KSEG1; -#endif + c->options |= MIPS_CPU_CACHE_CDEX_P; + break; - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); + 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; -#ifdef R4600_V2_HIT_CACHEOP_WAR - __restore_flags(flags); -#endif -} + c->options |= MIPS_CPU_CACHE_CDEX_P; + 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_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; + + c->options |= MIPS_CPU_CACHE_CDEX_P; + 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 */ + + c->options |= MIPS_CPU_CACHE_CDEX_P; + 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; + + c->options |= MIPS_CPU_PREFETCH; + break; + + case CPU_VR4133: + write_c0_config(config & ~CONF_EB); + case CPU_VR4131: + /* Workaround for cache instruction bug of VR4131 */ + if (c->processor_id == 0x0c80U || c->processor_id == 0x0c81U || + c->processor_id == 0x0c82U) { + config &= ~0x00000030U; + config |= 0x00410000U; + write_c0_config(config); + } + 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; + + c->options |= MIPS_CPU_CACHE_CDEX_P; + 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 */ + + c->options |= MIPS_CPU_CACHE_CDEX_P; + break; + + case CPU_RM7000: + rm7k_erratum31(); + + case CPU_RM9000: + 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; + + c->options |= MIPS_CPU_CACHE_CDEX_P | MIPS_CPU_PREFETCH; + 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; + + if (config & 0x8) /* VI bit */ + c->icache.flags |= MIPS_CACHE_VTAG; + + /* + * 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; + c->options |= MIPS_CPU_PREFETCH; + 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; + + 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; -/* 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. + 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(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; - 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_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; - 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; - _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; -} + scache_size = addr; + c->scache.linesz = 16 << ((config & R4K_CONF_SB) >> 22); + c->scache.ways = 1; + c->dcache.waybit = 0; /* does not matter */ -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_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; + return 1; } 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); + if (sc_present) + c->options |= MIPS_CPU_CACHE_CDEX_S; + 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(); +#ifdef CONFIG_R5000_CPU_SCACHE + r5k_sc_init(); #endif - break; + return; + + case CPU_RM7000: + case CPU_RM9000: +#ifdef CONFIG_RM7000_CPU_SCACHE + rm7k_sc_init(); +#endif + return; + default: - setup_scache_funcs(); + sc_present = 0; } + if (!sc_present) + 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"); -void __init ld_mmu_r4xx0(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); + /* compute a couple of other cache variables */ + c->scache.waysize = scache_size / c->scache.ways; - change_cp0_config(CONF_CM_CMASK | CONF_CU, CONF_CM_DEFAULT); + c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways); - probe_icache(config); - probe_dcache(config); - setup_scache(config); + printk("Unified secondary cache %ldkB %s, linesize %d bytes.\n", + scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); - 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; - } + c->options |= MIPS_CPU_SUBSET_CACHES; +} - _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; +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 void build_clear_page(void); + extern void build_copy_page(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(); + + if (c->dcache.sets * c->dcache.ways > PAGE_SIZE) + c->dcache.flags |= MIPS_CACHE_ALIASES; + + r4k_blast_dcache_page_setup(); + r4k_blast_dcache_page_indexed_setup(); + r4k_blast_dcache_setup(); + r4k_blast_icache_page_setup(); + r4k_blast_icache_page_indexed_setup(); + r4k_blast_icache_setup(); + r4k_blast_scache_page_setup(); + r4k_blast_scache_setup(); + + /* + * 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(); + coherency_setup(); + + build_clear_page(); + build_copy_page(); } Index: arch/mips/mm/c-r5432.c =================================================================== RCS file: arch/mips/mm/c-r5432.c diff -N arch/mips/mm/c-r5432.c --- arch/mips/mm/c-r5432.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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(); -} Index: arch/mips/mm/c-rm7k.c =================================================================== RCS file: arch/mips/mm/c-rm7k.c diff -N arch/mips/mm/c-rm7k.c --- arch/mips/mm/c-rm7k.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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(); -} Index: arch/mips/mm/c-sb1.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mm/c-sb1.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mm/c-sb1.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/mm/c-sb1.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -1,7 +1,7 @@ /* * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) - * 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 @@ -25,37 +25,26 @@ #include #include +extern void sb1_dma_init(void); + /* 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; -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; - } -} +static unsigned int icache_range_cutoff; +static unsigned int dcache_range_cutoff; /* * The dcache is fully coherent to the system, with one @@ -70,59 +59,224 @@ * 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; + + addr &= PAGE_MASK; + 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 +293,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 +345,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) +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 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 +520,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 +529,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 +549,56 @@ */ void ld_mmu_sb1(void) { + extern char except_vec2_sb1; + extern char handle_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); + memcpy((void *)KSEG1ADDR(&handle_vec2_sb1), &handle_vec2_sb1, 0x80); + probe_cache_sizes(); - _clear_page = sb1_clear_page; - _copy_page = sb1_copy_page; +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS + sb1_dma_init(); +#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_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 */ - /* None of these are needed for the sb1 */ - _flush_cache_page = (void *) sb1_nop; + /* This implies an Icache flush too, so can't be nop'ed */ + _flush_cache_page = sb1_flush_cache_page; _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(); } Index: arch/mips/mm/c-tx39.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mm/c-tx39.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mm/c-tx39.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/mm/c-tx39.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -25,18 +25,21 @@ /* 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 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 +49,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 +60,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); +} - __save_and_cli(flags); - blast_dcache16_wayLSB(); +static inline void tx39_blast_icache_page_indexed(unsigned long addr) +{ + 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_page_indexed(addr); + write_c0_conf(config); + local_irq_restore(flags); +} + +static inline void tx39_blast_icache(void) +{ + 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(); + 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 +165,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 +187,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 +199,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 +208,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,77 +331,92 @@ { 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; } } void __init ld_mmu_tx39(void) { + extern void build_clear_page(void); + extern void build_copy_page(void); unsigned long config; - _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 +424,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 +441,50 @@ 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); + + build_clear_page(); + build_copy_page(); } Index: arch/mips/mm/c-tx49.c =================================================================== RCS file: arch/mips/mm/c-tx49.c diff -N arch/mips/mm/c-tx49.c --- arch/mips/mm/c-tx49.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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(); -} Index: arch/mips/mm/fault.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mm/fault.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mm/fault.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/mm/fault.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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; } } Index: arch/mips/mm/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mm/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mm/init.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/mm/init.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -43,15 +43,21 @@ 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) +void pgd_init(unsigned long page) { - /* This should flush more selectivly ... */ - __flush_cache_all(); + unsigned long *p = (unsigned long *) page; + int i; - return 0; + 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; + } } /* @@ -67,7 +73,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 +168,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 +197,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: */ @@ -250,7 +261,13 @@ zones_size[ZONE_DMA] = low; #endif #ifdef CONFIG_HIGHMEM - zones_size[ZONE_HIGHMEM] = high - low; + if (cpu_has_dc_aliases) { + printk(KERN_WARNING "This processor doesn't support highmem."); + if (high - low) + printk(" %dk highmem ignored", high - low); + printk("\n"); + } else + zones_size[ZONE_HIGHMEM] = high - low; #endif free_area_init(zones_size); @@ -360,7 +377,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) { Index: arch/mips/mm/ioremap.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mm/ioremap.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mm/ioremap.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/mm/ioremap.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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) Index: arch/mips/mm/loadmmu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mm/loadmmu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mm/loadmmu.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/mm/loadmmu.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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. */ @@ -18,22 +22,18 @@ #include #include -/* memory functions */ -void (*_clear_page)(void * page); -void (*_copy_page)(void * to, void * from); - /* Cache operations. */ void (*_flush_cache_all)(void); 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 +49,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) || defined(CONFIG_CPU_RM9000) 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 +82,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 +94,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 +104,11 @@ sb1_tlb_init(); break; #endif + + case CPU_R8000: + panic("R8000 is unsupported"); + break; + default: panic("Yeee, unsupported mmu/cache architecture."); } Index: arch/mips/mm/pg-andes.S =================================================================== RCS file: arch/mips/mm/pg-andes.S diff -N arch/mips/mm/pg-andes.S --- arch/mips/mm/pg-andes.S 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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) Index: arch/mips/mm/pg-mips32.c =================================================================== RCS file: arch/mips/mm/pg-mips32.c diff -N arch/mips/mm/pg-mips32.c --- arch/mips/mm/pg-mips32.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 - -/* page functions */ -void r3k_clear_page(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "addiu\t$1,%0,%2\n" - "1:\tsw\t$0,(%0)\n\t" - "sw\t$0,4(%0)\n\t" - "sw\t$0,8(%0)\n\t" - "sw\t$0,12(%0)\n\t" - "addiu\t%0,32\n\t" - "sw\t$0,-16(%0)\n\t" - "sw\t$0,-12(%0)\n\t" - "sw\t$0,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t$0,-4(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE) - : "memory"); -} - -void r3k_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" - "addiu\t$1,%0,%8\n" - "1:\tlw\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" - "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\tat\n\t" - ".set\treorder" - : "=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - : "0" (to), "1" (from), - "I" (PAGE_SIZE)); -} - -/* - * Initialize new page directory with pointers to invalid ptes - */ -void pgd_init(unsigned long page) -{ - unsigned long dummy1, dummy2; - - /* - * The plain and boring version for the R3000. No cache flushing - * stuff is implemented since the R3000 has physical caches. - */ - __asm__ __volatile__( - ".set\tnoreorder\n" - "1:\tsw\t%2, (%0)\n\t" - "sw\t%2, 4(%0)\n\t" - "sw\t%2, 8(%0)\n\t" - "sw\t%2, 12(%0)\n\t" - "sw\t%2, 16(%0)\n\t" - "sw\t%2, 20(%0)\n\t" - "sw\t%2, 24(%0)\n\t" - "sw\t%2, 28(%0)\n\t" - "subu\t%1, 1\n\t" - "bnez\t%1, 1b\n\t" - "addiu\t%0, 32\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2) - :"r" ((unsigned long) invalid_pte_table), "0" (page), - "1" (USER_PTRS_PER_PGD / 8)); -} Index: arch/mips/mm/pg-r4k.S =================================================================== RCS file: arch/mips/mm/pg-r4k.S diff -N arch/mips/mm/pg-r4k.S --- arch/mips/mm/pg-r4k.S 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,690 +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 -#include -#include -#include -#include - -#ifdef CONFIG_64BIT_PHYS_ADDR -#define PGD_SIZE 0x2000 -#else -#define PGD_SIZE 0x1000 -#endif - - .text - .set mips3 - .set noat - -/* - * 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. - */ - -LEAF(r4k_clear_page_d16) - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_D, (a0) - sd zero, (a0) - sd zero, 8(a0) - cache Create_Dirty_Excl_D, 16(a0) - sd zero, 16(a0) - sd zero, 24(a0) - addiu a0, 64 - cache Create_Dirty_Excl_D, -32(a0) - sd zero, -32(a0) - sd zero, -24(a0) - cache Create_Dirty_Excl_D, -16(a0) - sd zero, -16(a0) - sd zero, -8(a0) - bne AT, a0, 1b - jr ra - END(r4k_clear_page_d16) - -LEAF(r4k_clear_page_d32) - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_D, (a0) - sd zero, (a0) - sd zero, 8(a0) - sd zero, 16(a0) - sd zero, 24(a0) - addiu a0, 64 - cache Create_Dirty_Excl_D, -32(a0) - sd zero, -32(a0) - sd zero, -24(a0) - sd zero, -16(a0) - sd zero, -8(a0) - bne AT, a0, 1b - jr ra - END(r4k_clear_page_d32) - -/* - * 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 - */ - -LEAF(r4k_clear_page_r4600_v1) - addiu AT, a0, _PAGE_SIZE -1: nop - nop - nop - nop - cache Create_Dirty_Excl_D, (a0) - sd zero, (a0) - sd zero, 8(a0) - sd zero, 16(a0) - sd zero, 24(a0) - addiu a0, 64 - nop - nop - nop - cache Create_Dirty_Excl_D, -32(a0) - sd zero, -32(a0) - sd zero, -24(a0) - sd zero, -16(a0) - sd zero, -8(a0) - bne AT, a0, 1b - jr ra - END(r4k_clear_page_r4600_v1) - -LEAF(r4k_clear_page_r4600_v2) - mfc0 a1, CP0_STATUS - ori AT, a1, 1 - xori AT, 1 - mtc0 AT, CP0_STATUS - nop - nop - nop - - .set volatile - la AT, KSEG1 - lw zero, (AT) - .set novolatile - - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_D, (a0) - sd zero, (a0) - sd zero, 8(a0) - sd zero, 16(a0) - sd zero, 24(a0) - addiu a0, 64 - cache Create_Dirty_Excl_D, -32(a0) - sd zero, -32(a0) - sd zero, -24(a0) - sd zero, -16(a0) - sd zero, -8(a0) - bne AT, a0, 1b - - mfc0 AT, CP0_STATUS # __restore_flags - andi a1, 1 - ori AT, 1 - xori AT, 1 - or a1, AT - mtc0 a1, CP0_STATUS - nop - nop - nop - - jr ra - END(r4k_clear_page_r4600_v2) - -/* - * 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? - */ - -LEAF(r4k_clear_page_s16) - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_SD, (a0) - sd zero, (a0) - sd zero, 8(a0) - cache Create_Dirty_Excl_SD, 16(a0) - sd zero, 16(a0) - sd zero, 24(a0) - addiu a0, 64 - cache Create_Dirty_Excl_SD, -32(a0) - sd zero, -32(a0) - sd zero, -24(a0) - cache Create_Dirty_Excl_SD, -16(a0) - sd zero, -16(a0) - sd zero, -8(a0) - bne AT, a0, 1b - jr ra - END(r4k_clear_page_s16) - -LEAF(r4k_clear_page_s32) - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_SD, (a0) - sd zero, (a0) - sd zero, 8(a0) - sd zero, 16(a0) - sd zero, 24(a0) - addiu a0, 64 - cache Create_Dirty_Excl_SD, -32(a0) - sd zero, -32(a0) - sd zero, -24(a0) - sd zero, -16(a0) - sd zero, -8(a0) - bne AT, a0, 1b - jr ra - END(r4k_clear_page_s32) - -LEAF(r4k_clear_page_s64) - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_SD, (a0) - sd zero, (a0) - sd zero, 8(a0) - sd zero, 16(a0) - sd zero, 24(a0) - addiu a0, 64 - sd zero, -32(a0) - sd zero, -24(a0) - sd zero, -16(a0) - sd zero, -8(a0) - bne AT, a0, 1b - jr ra - END(r4k_clear_page_s64) - -LEAF(r4k_clear_page_s128) - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_SD, (a0) - sd zero, (a0) - sd zero, 8(a0) - sd zero, 16(a0) - sd zero, 24(a0) - sd zero, 32(a0) - sd zero, 40(a0) - sd zero, 48(a0) - sd zero, 56(a0) - addiu a0, 128 - sd zero, -64(a0) - sd zero, -56(a0) - sd zero, -48(a0) - sd zero, -40(a0) - sd zero, -32(a0) - sd zero, -24(a0) - sd zero, -16(a0) - sd zero, -8(a0) - bne AT, a0, 1b - jr ra - END(r4k_clear_page_s128) - -/* - * This is still inefficient. We only can do better if we know the - * virtual address where the copy will be accessed. - */ - -LEAF(r4k_copy_page_d16) - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_D, (a0) - lw a3, (a1) - lw a2, 4(a1) - lw v1, 8(a1) - lw v0, 12(a1) - sw a3, (a0) - sw a2, 4(a0) - sw v1, 8(a0) - sw v0, 12(a0) - cache Create_Dirty_Excl_D, 16(a0) - lw a3, 16(a1) - lw a2, 20(a1) - lw v1, 24(a1) - lw v0, 28(a1) - sw a3, 16(a0) - sw a2, 20(a0) - sw v1, 24(a0) - sw v0, 28(a0) - cache Create_Dirty_Excl_D, 32(a0) - addiu a0, 64 - addiu a1, 64 - lw a3, -32(a1) - lw a2, -28(a1) - lw v1, -24(a1) - lw v0, -20(a1) - sw a3, -32(a0) - sw a2, -28(a0) - sw v1, -24(a0) - sw v0, -20(a0) - cache Create_Dirty_Excl_D, -16(a0) - lw a3, -16(a1) - lw a2, -12(a1) - lw v1, -8(a1) - lw v0, -4(a1) - sw a3, -16(a0) - sw a2, -12(a0) - sw v1, -8(a0) - sw v0, -4(a0) - bne AT, a0, 1b - jr ra - END(r4k_copy_page_d16) - -LEAF(r4k_copy_page_d32) - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_D, (a0) - lw a3, (a1) - lw a2, 4(a1) - lw v1, 8(a1) - lw v0, 12(a1) - sw a3, (a0) - sw a2, 4(a0) - sw v1, 8(a0) - sw v0, 12(a0) - lw a3, 16(a1) - lw a2, 20(a1) - lw v1, 24(a1) - lw v0, 28(a1) - sw a3, 16(a0) - sw a2, 20(a0) - sw v1, 24(a0) - sw v0, 28(a0) - cache Create_Dirty_Excl_D, 32(a0) - addiu a0, 64 - addiu a1, 64 - lw a3, -32(a1) - lw a2, -28(a1) - lw v1, -24(a1) - lw v0, -20(a1) - sw a3, -32(a0) - sw a2, -28(a0) - sw v1, -24(a0) - sw v0, -20(a0) - lw a3, -16(a1) - lw a2, -12(a1) - lw v1, -8(a1) - lw v0, -4(a1) - sw a3, -16(a0) - sw a2, -12(a0) - sw v1, -8(a0) - sw v0, -4(a0) - bne AT, a0, 1b - jr ra - END(r4k_copy_page_d32) - -/* - * Again a special version for the R4600 V1.x - */ - -LEAF(r4k_copy_page_r4600_v1) - addiu AT, a0, _PAGE_SIZE -1: nop - nop - nop - nop - cache Create_Dirty_Excl_D, (a0) - lw a3, (a1) - lw a2, 4(a1) - lw v1, 8(a1) - lw v0, 12(a1) - sw a3, (a0) - sw a2, 4(a0) - sw v1, 8(a0) - sw v0, 12(a0) - lw a3, 16(a1) - lw a2, 20(a1) - lw v1, 24(a1) - lw v0, 28(a1) - sw a3, 16(a0) - sw a2, 20(a0) - sw v1, 24(a0) - sw v0, 28(a0) - nop - nop - nop - nop - cache Create_Dirty_Excl_D, 32(a0) - addiu a0, 64 - addiu a1, 64 - lw a3, -32(a1) - lw a2, -28(a1) - lw v1, -24(a1) - lw v0, -20(a1) - sw a3, -32(a0) - sw a2, -28(a0) - sw v1, -24(a0) - sw v0, -20(a0) - lw a3, -16(a1) - lw a2, -12(a1) - lw v1, -8(a1) - lw v0, -4(a1) - sw a3, -16(a0) - sw a2, -12(a0) - sw v1, -8(a0) - sw v0, -4(a0) - bne AT, a0, 1b - jr ra - END(r4k_copy_page_r4600_v1) - -LEAF(r4k_copy_page_r4600_v2) - mfc0 v1, CP0_STATUS - ori AT, v1, 1 - xori AT, 1 - - mtc0 AT, CP0_STATUS - nop - nop - nop - - addiu AT, a0, _PAGE_SIZE -1: nop - nop - nop - nop - cache Create_Dirty_Excl_D, (a0) - lw t1, (a1) - lw t0, 4(a1) - lw a3, 8(a1) - lw a2, 12(a1) - sw t1, (a0) - sw t0, 4(a0) - sw a3, 8(a0) - sw a2, 12(a0) - lw t1, 16(a1) - lw t0, 20(a1) - lw a3, 24(a1) - lw a2, 28(a1) - sw t1, 16(a0) - sw t0, 20(a0) - sw a3, 24(a0) - sw a2, 28(a0) - nop - nop - nop - nop - cache Create_Dirty_Excl_D, 32(a0) - addiu a0, 64 - addiu a1, 64 - lw t1, -32(a1) - lw t0, -28(a1) - lw a3, -24(a1) - lw a2, -20(a1) - sw t1, -32(a0) - sw t0, -28(a0) - sw a3, -24(a0) - sw a2, -20(a0) - lw t1, -16(a1) - lw t0, -12(a1) - lw a3, -8(a1) - lw a2, -4(a1) - sw t1, -16(a0) - sw t0, -12(a0) - sw a3, -8(a0) - sw a2, -4(a0) - bne AT, a0, 1b - - mfc0 AT, CP0_STATUS # __restore_flags - andi v1, 1 - ori AT, 1 - xori AT, 1 - or v1, AT - mtc0 v1, CP0_STATUS - nop - nop - nop - jr ra - END(r4k_copy_page_r4600_v2) - -/* - * These are for R4000SC / R4400MC - */ - -LEAF(r4k_copy_page_s16) - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_SD, (a0) - lw a3, (a1) - lw a2, 4(a1) - lw v1, 8(a1) - lw v0, 12(a1) - sw a3, (a0) - sw a2, 4(a0) - sw v1, 8(a0) - sw v0, 12(a0) - cache Create_Dirty_Excl_SD, 16(a0) - lw a3, 16(a1) - lw a2, 20(a1) - lw v1, 24(a1) - lw v0, 28(a1) - sw a3, 16(a0) - sw a2, 20(a0) - sw v1, 24(a0) - sw v0, 28(a0) - cache Create_Dirty_Excl_SD, 32(a0) - addiu a0, 64 - addiu a1, 64 - lw a3, -32(a1) - lw a2, -28(a1) - lw v1, -24(a1) - lw v0, -20(a1) - sw a3, -32(a0) - sw a2, -28(a0) - sw v1, -24(a0) - sw v0, -20(a0) - cache Create_Dirty_Excl_SD, -16(a0) - lw a3, -16(a1) - lw a2, -12(a1) - lw v1, -8(a1) - lw v0, -4(a1) - sw a3, -16(a0) - sw a2, -12(a0) - sw v1, -8(a0) - sw v0, -4(a0) - bne AT, a0, 1b - jr ra - END(r4k_copy_page_s16) - -LEAF(r4k_copy_page_s32) - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_SD, (a0) - lw a3, (a1) - lw a2, 4(a1) - lw v1, 8(a1) - lw v0, 12(a1) - sw a3, (a0) - sw a2, 4(a0) - sw v1, 8(a0) - sw v0, 12(a0) - lw a3, 16(a1) - lw a2, 20(a1) - lw v1, 24(a1) - lw v0, 28(a1) - sw a3, 16(a0) - sw a2, 20(a0) - sw v1, 24(a0) - sw v0, 28(a0) - cache Create_Dirty_Excl_SD, 32(a0) - addiu a0, 64 - addiu a1, 64 - lw a3, -32(a1) - lw a2, -28(a1) - lw v1, -24(a1) - lw v0, -20(a1) - sw a3, -32(a0) - sw a2, -28(a0) - sw v1, -24(a0) - sw v0, -20(a0) - lw a3, -16(a1) - lw a2, -12(a1) - lw v1, -8(a1) - lw v0, -4(a1) - sw a3, -16(a0) - sw a2, -12(a0) - sw v1, -8(a0) - sw v0, -4(a0) - bne AT, a0, 1b - jr ra - END(r4k_copy_page_s32) - -LEAF(r4k_copy_page_s64) - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_SD, (a0) - lw a3, (a1) - lw a2, 4(a1) - lw v1, 8(a1) - lw v0, 12(a1) - sw a3, (a0) - sw a2, 4(a0) - sw v1, 8(a0) - sw v0, 12(a0) - lw a3, 16(a1) - lw a2, 20(a1) - lw v1, 24(a1) - lw v0, 28(a1) - sw a3, 16(a0) - sw a2, 20(a0) - sw v1, 24(a0) - sw v0, 28(a0) - addiu a0, 64 - addiu a1, 64 - lw a3, -32(a1) - lw a2, -28(a1) - lw v1, -24(a1) - lw v0, -20(a1) - sw a3, -32(a0) - sw a2, -28(a0) - sw v1, -24(a0) - sw v0, -20(a0) - lw a3, -16(a1) - lw a2, -12(a1) - lw v1, -8(a1) - lw v0, -4(a1) - sw a3, -16(a0) - sw a2, -12(a0) - sw v1, -8(a0) - sw v0, -4(a0) - bne AT, a0, 1b - jr ra - END(r4k_copy_page_s64) - -LEAF(r4k_copy_page_s128) - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_SD, (a0) - lw a3, (a1) - lw a2, 4(a1) - lw v1, 8(a1) - lw v0, 12(a1) - sw a3, (a0) - sw a2, 4(a0) - sw v1, 8(a0) - sw v0, 12(a0) - lw a3, 16(a1) - lw a2, 20(a1) - lw v1, 24(a1) - lw v0, 28(a1) - sw a3, 16(a0) - sw a2, 20(a0) - sw v1, 24(a0) - sw v0, 28(a0) - lw a3, 32(a1) - lw a2, 36(a1) - lw v1, 40(a1) - lw v0, 44(a1) - sw a3, 32(a0) - sw a2, 36(a0) - sw v1, 40(a0) - sw v0, 44(a0) - lw a3, 48(a1) - lw a2, 52(a1) - lw v1, 56(a1) - lw v0, 60(a1) - sw a3, 48(a0) - sw a2, 52(a0) - sw v1, 56(a0) - sw v0, 60(a0) - addiu a0, 128 - addiu a1, 128 - lw a3, -64(a1) - lw a2, -60(a1) - lw v1, -56(a1) - lw v0, -52(a1) - sw a3, -64(a0) - sw a2, -60(a0) - sw v1, -56(a0) - sw v0, -52(a0) - lw a3, -48(a1) - lw a2, -44(a1) - lw v1, -40(a1) - lw v0, -36(a1) - sw a3, -48(a0) - sw a2, -44(a0) - sw v1, -40(a0) - sw v0, -36(a0) - lw a3, -32(a1) - lw a2, -28(a1) - lw v1, -24(a1) - lw v0, -20(a1) - sw a3, -32(a0) - sw a2, -28(a0) - sw v1, -24(a0) - sw v0, -20(a0) - lw a3, -16(a1) - lw a2, -12(a1) - lw v1, -8(a1) - lw v0, -4(a1) - sw a3, -16(a0) - sw a2, -12(a0) - sw v1, -8(a0) - sw v0, -4(a0) - bne AT, a0, 1b - jr ra - END(r4k_copy_page_s128) - -/* This one still needs to receive cache optimizations */ -LEAF(pgd_init) - addiu AT, a0, PGD_SIZE / 2 - la v0, invalid_pte_table -1: sw v0, (a0) - sw v0, 4(a0) - sw v0, 8(a0) - sw v0, 12(a0) - addiu a0, 32 - sw v0, -16(a0) - sw v0, -12(a0) - sw v0, -8(a0) - sw v0, -4(a0) - bne AT, a0, 1b - jr ra - END(pgd_init) Index: arch/mips/mm/pg-r5432.c =================================================================== RCS file: arch/mips/mm/pg-r5432.c diff -N arch/mips/mm/pg-r5432.c --- arch/mips/mm/pg-r5432.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,117 +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, 2000 Ralf Baechle (ralf@gnu.org) - */ -#include -#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; - } -} Index: arch/mips/mm/pg-rm7k.c =================================================================== RCS file: arch/mips/mm/pg-rm7k.c diff -N arch/mips/mm/pg-rm7k.c --- arch/mips/mm/pg-rm7k.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; - } -} Index: arch/mips/mm/pg-sb1.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mm/pg-sb1.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mm/pg-sb1.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/mm/pg-sb1.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -1,9 +1,11 @@ /* * 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. + * Copyright (C) 2002, 2003 Broadcom Corporation * - * 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 +22,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" @@ -31,16 +41,21 @@ #define SB1_PREF_STORE_STREAMED_HINT "5" #endif -/* These are the functions hooked by the memory management function pointers */ -void sb1_clear_page(void *page) +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS +static inline void clear_page_cpu(void *page) +#else +void clear_page(void *page) +#endif { - /* 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 +78,24 @@ " 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) +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS +static inline void copy_page_cpu(void *to, void *from) +#else +void copy_page(void *to, void *from) +#endif { - - /* 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 +142,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 clear_page(void *page) +{ + int cpu = smp_processor_id(); + + /* if the page is above Kseg0, use old way */ + if (KSEGX(page) != K0BASE) + return clear_page_cpu(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 copy_page(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 copy_page_cpu(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 /* CONFIG_SIBYTE_DMA_PAGEOPS */ Index: arch/mips/mm/r5k-sc.c =================================================================== RCS file: arch/mips/mm/r5k-sc.c diff -N arch/mips/mm/r5k-sc.c --- arch/mips/mm/r5k-sc.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; - } -} Index: arch/mips/mm/tlb-r3k.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mm/tlb-r3k.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mm/tlb-r3k.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/mm/tlb-r3k.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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); } } Index: arch/mips/mm/tlb-r4k.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mm/tlb-r4k.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mm/tlb-r4k.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/mm/tlb-r4k.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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,72 +109,102 @@ 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); } } +/* + * Remove one kernel space TLB entry. This entry is assumed to be marked + * global so we don't do the ASID thing. + */ +void local_flush_tlb_one(unsigned long page) +{ + unsigned long flags; + int oldpid, idx; + + page &= (PAGE_MASK << 1); + oldpid = read_c0_entryhi() & ASID_MASK; + + local_irq_save(flags); + write_c0_entryhi(page); + BARRIER; + tlb_probe(); + BARRIER; + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + if (idx >= 0) { + /* Make sure all entries differ. */ + write_c0_entryhi(KSEG0+idx*0x2000); + tlb_write_indexed(); + } + BARRIER; + write_c0_entryhi(oldpid); + local_irq_restore(flags); +} + /* 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. */ -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 +218,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 +255,9 @@ tlb_write_indexed(); } BARRIER; - set_entryhi(pid); + write_c0_entryhi(pid); BARRIER; - __restore_flags(flags); + local_irq_restore(flags); } #if 0 @@ -235,23 +270,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 +298,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 +338,58 @@ 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; + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int reg; - prid = read_32bit_cp0_register(CP0_PRID) & 0xff00; - if (prid == PRID_IMP_RM7000 || !(config & (1 << 31))) - /* - * Not a MIPS32 complianant CPU. Config 1 register not - * supported, we assume R4k style. Cpu probing already figured - * out the number of tlb entries. - */ + /* + * If this isn't a MIPS32 / MIPS64 compliant CPU. Config 1 register + * is not supported, we assume R4k style. Cpu probing already figured + * out the number of tlb entries. + */ + if ((c->processor_id & 0xff0000) == PRID_COMP_LEGACY) return; - config1 = read_mips32_cp0_config1(); + reg = read_c0_config1(); if (!((config >> 7) & 3)) - panic("No MMU present"); - else - mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1; + panic("No TLB present"); + + c->tlbsize = ((reg >> 25) & 0x3f) + 1; } 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 +399,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_DEFAULT_MASK); + 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); Index: arch/mips/mm/tlb-sb1.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mm/tlb-sb1.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mm/tlb-sb1.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/mm/tlb-sb1.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -1,7 +1,7 @@ /* * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) - * 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 @@ -18,11 +18,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include +#include #include #include #include -extern char except_vec0_r4000[]; +extern char except_vec0_sb1[]; + +#define UNIQUE_ENTRYHI(idx) (KSEG0 + ((idx) << (PAGE_SHIFT + 1))) /* Dump the current entry* and pagemask registers */ static inline void dump_cur_tlb_regs(void) @@ -47,13 +50,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 +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" - " 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,21 @@ 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); + + entry = read_c0_wired(); + while (entry < current_cpu_data.tlbsize) { + write_c0_entryhi(UNIQUE_ENTRYHI(entry)); + write_c0_index(entry); tlb_write_indexed(); + entry++; } - set_entryhi(old_ctx); - __restore_flags(flags); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); } @@ -117,7 +116,7 @@ * Use increments of the maximum page size (16MB), and check for duplicate * entries before doing a given write. Then, when we're safe from collisions * with the firmware, go back and give all the entries invalid addresses with - * the normal flush routine. + * the normal flush routine. Wired entries will be killed as well! */ void sb1_sanitize_tlb(void) { @@ -126,15 +125,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,103 +148,109 @@ 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(UNIQUE_ENTRYHI(idx)); + 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(UNIQUE_ENTRYHI(idx)); tlb_write_indexed(); finish: - set_entryhi(oldpid); + write_c0_entryhi(oldpid); } - __restore_flags(flags); + local_irq_restore(flags); } +/* + * Remove one kernel space TLB entry. This entry is assumed to be marked + * global so we don't do the ASID thing. + */ +void local_flush_tlb_one(unsigned long page) +{ + unsigned long flags; + int oldpid, idx; + + page &= (PAGE_MASK << 1); + oldpid = read_c0_entryhi() & ASID_MASK; + + local_irq_save(flags); + write_c0_entryhi(page); + tlb_probe(); + idx = read_c0_index(); + if (idx >= 0) { + /* Make sure all entries differ. */ + write_c0_entryhi(UNIQUE_ENTRYHI(idx)); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + tlb_write_indexed(); + } + + write_c0_entryhi(oldpid); + local_irq_restore(flags); +} /* All entries common to a mm share an asid. To effectively flush 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 +264,52 @@ 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); +} + +void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, + unsigned long entryhi, unsigned long pagemask) +{ + unsigned long flags; + unsigned long wired; + unsigned long old_pagemask; + unsigned long old_ctx; + + local_irq_save(flags); + old_ctx = read_c0_entryhi() & 0xff; + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); + write_c0_wired(wired + 1); + write_c0_index(wired); + + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); + tlb_write_indexed(); + + write_c0_entryhi(old_ctx); + write_c0_pagemask(old_pagemask); + + local_flush_tlb_all(); + local_irq_restore(flags); } /* @@ -297,10 +319,8 @@ */ void sb1_tlb_init(void) { - u32 config1; - - config1 = read_mips32_cp0_config1(); - mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1; + write_c0_pagemask(PM_DEFAULT_MASK); + write_c0_wired(0); /* * We don't know what state the firmware left the TLB's in, so this is @@ -309,6 +329,6 @@ */ sb1_sanitize_tlb(); - memcpy((void *)KSEG0, except_vec0_r4000, 0x80); + memcpy((void *)KSEG0, except_vec0_sb1, 0x80); flush_icache_range(KSEG0, KSEG0 + 0x80); } Index: arch/mips/mm/tlbex-r4k.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/mm/tlbex-r4k.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/mm/tlbex-r4k.S 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/mm/tlbex-r4k.S 4 Aug 2004 01:25:52 -0000 1.2 @@ -23,6 +23,7 @@ #include #include #include +#include #define TLB_OPTIMIZE /* If you are paranoid, disable this. */ @@ -31,31 +32,131 @@ #define PTE_S sd #define PTE_SRL dsrl #define P_MTC0 dmtc0 -#define PTE_SIZE 8 -#define PTEP_INDX_MSK 0xff0 -#define PTE_INDX_MSK 0xff8 -#define PTE_INDX_SHIFT 9 #else #define PTE_L lw #define PTE_S sw #define PTE_SRL srl #define P_MTC0 mtc0 -#define PTE_SIZE 4 -#define PTEP_INDX_MSK 0xff8 -#define PTE_INDX_MSK 0xffc -#define PTE_INDX_SHIFT 10 #endif +#define PTE_PAGE_SIZE (_PAGE_SIZE << _PTE_ORDER) +#define PTE_PAGE_SHIFT (_PAGE_SHIFT + _PTE_ORDER) +#define PTEP_INDX_MSK ((PTE_PAGE_SIZE - 1) & ~(_PTE_T_SIZE << 1 - 1)) +#define PTE_INDX_MSK ((PTE_PAGE_SIZE - 1) & ~(_PTE_T_SIZE - 1)) +#define PTE_INDX_SHIFT (PTE_PAGE_SHIFT - _PTE_T_LOG2) + +/* + * 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, _PGD_T_LOG2; \ + 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_T_SIZE; \ + xori ptr, ptr, _PTE_T_SIZE; \ + PTE_L tmp, _PTE_T_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 -#define GET_PTE_OFF(reg) -#elif CONFIG_CPU_VR41XX -#define GET_PTE_OFF(reg) srl reg, reg, 3 +/* + * Different for VR41xx because it supports 1k as smallest page size + */ +#ifdef CONFIG_CPU_VR41XX +#define BASE_VPN_SHIFT 6 #else -#define GET_PTE_OFF(reg) srl reg, reg, 1 +#define BASE_VPN_SHIFT 4 #endif +#if (BASE_VPN_SHIFT- PTE_T_LOG2-1) > 0 +#define GET_PTE_OFF(reg) srl reg, reg, BASE_VPN_SHIFT-_PTE_T_LOG2-1 +#else +#define GET_PTE_OFF(reg) +#endif + + /* * These handlers much be written in a relocatable manner * because based upon the cpu type an arbitrary one of the @@ -67,20 +168,10 @@ .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 - - sll k0, k0, 2 + sll k0, k0, _PGD_T_LOG2 addu k1, k1, k0 # add in pgd offset mfc0 k0, CP0_CONTEXT # get context reg lw k1, (k1) @@ -88,35 +179,35 @@ 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_L k1, _PTE_T_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 b 1f + rm9000_tlb_hazard tlbwr # write random tlb entry 1: nop + rm9000_tlb_hazard eret # return from trap END(except_vec0_r4000) /* 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) + sll k0, k0, _PGD_T_LOG2 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) - PTE_L k1, PTE_SIZE(k1) + PTE_L k1, _PTE_T_SIZE(k1) PTE_SRL k0, k0, 6 P_MTC0 k0, CP0_ENTRYLO0 PTE_SRL k1, k1, 6 @@ -144,17 +235,15 @@ mfc0 k0, CP0_BADVADDR # Get faulting address srl k0, k0, _PGDIR_SHIFT # get pgd only bits lw k1, pgd_current # get pgd pointer - sll k0, k0, 2 # log2(sizeof(pgd_t) + sll k0, k0, _PGD_T_LOG2 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 - PTE_L k1, PTE_SIZE(k1) # get odd pte + PTE_L k1, _PTE_T_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 @@ -166,13 +255,42 @@ 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, _PGD_T_LOG2 + 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_T_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) + sll k0, k0, _PGD_T_LOG2 addu k1, k1, k0 mfc0 k0, CP0_CONTEXT lw k1, (k1) @@ -182,7 +300,7 @@ and k0, k0, PTEP_INDX_MSK addu k1, k1, k0 PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) + PTE_L k1, _PTE_T_SIZE(k1) nop /* XXX */ tlbp PTE_SRL k0, k0, 6 @@ -201,10 +319,10 @@ /* 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) + sll k0, k0, _PGD_T_LOG2 addu k1, k1, k0 mfc0 k0, CP0_CONTEXT lw k1, (k1) @@ -214,7 +332,7 @@ and k0, k0, PTEP_INDX_MSK addu k1, k1, k0 PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) + PTE_L k1, _PTE_T_SIZE(k1) nop /* XXX */ tlbp PTE_SRL k0, k0, 6 @@ -233,10 +351,10 @@ /* 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) + sll k0, k0, _PGD_T_LOG2 addu k1, k1, k0 mfc0 k0, CP0_CONTEXT lw k1, (k1) @@ -246,7 +364,7 @@ and k0, k0, PTEP_INDX_MSK addu k1, k1, k0 PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) + PTE_L k1, _PTE_T_SIZE(k1) PTE_SRL k0, k0, 6 P_MTC0 zero, CP0_ENTRYLO0 P_MTC0 k0, CP0_ENTRYLO0 @@ -264,10 +382,10 @@ /* 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) + sll k0, k0, _PGD_T_LOG2 addu k1, k1, k0 mfc0 k0, CP0_CONTEXT lw k1, (k1) @@ -277,7 +395,7 @@ and k0, k0, PTEP_INDX_MSK addu k1, k1, k0 PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) + PTE_L k1, _PTE_T_SIZE(k1) nop /* XXX */ tlbp PTE_SRL k0, k0, 6 @@ -295,104 +413,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,8 +446,21 @@ .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 + .set mips3 /* Test present bit in entry. */ LOAD_PTE(k0, k1) R5K_HAZARD @@ -433,11 +468,13 @@ PTE_PRESENT(k0, k1, nopage_tlbl) PTE_MAKEVALID(k0, k1) PTE_RELOAD(k1, k0) + rm9000_tlb_hazard nop b 1f tlbwi 1: nop + rm9000_tlb_hazard .set mips3 eret .set mips0 @@ -459,11 +496,13 @@ PTE_WRITABLE(k0, k1, nopage_tlbs) PTE_MAKEWRITE(k0, k1) PTE_RELOAD(k1, k0) + rm9000_tlb_hazard nop b 1f tlbwi 1: nop + rm9000_tlb_hazard .set mips3 eret .set mips0 @@ -490,10 +529,12 @@ /* Now reload the entry into the tlb. */ PTE_RELOAD(k1, k0) + rm9000_tlb_hazard nop b 1f tlbwi 1: + rm9000_tlb_hazard nop .set mips3 eret @@ -503,4 +544,3 @@ nowrite_mod: DO_FAULT(1) END(handle_mod) - Index: arch/mips/mm/umap.c =================================================================== RCS file: arch/mips/mm/umap.c diff -N arch/mips/mm/umap.c --- arch/mips/mm/umap.c 22 Jul 2004 19:49:14 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; -} Index: arch/mips/momentum/ocelot_g/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/momentum/ocelot_g/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/momentum/ocelot_g/Makefile 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/momentum/ocelot_g/Makefile 4 Aug 2004 01:25:52 -0000 1.2 @@ -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 Index: arch/mips/momentum/ocelot_g/dbg_io.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/momentum/ocelot_g/dbg_io.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/momentum/ocelot_g/dbg_io.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/momentum/ocelot_g/dbg_io.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -1,6 +1,6 @@ #include -#if defined(CONFIG_REMOTE_DEBUG) +#if defined(CONFIG_KGDB) #include /* For the serial port location and base baud */ Index: arch/mips/momentum/ocelot_g/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/momentum/ocelot_g/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/momentum/ocelot_g/irq.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/momentum/ocelot_g/irq.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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 :-) */ Index: arch/mips/momentum/ocelot_g/ocelot_pld.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/momentum/ocelot_g/ocelot_pld.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/momentum/ocelot_g/ocelot_pld.h 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/momentum/ocelot_g/ocelot_pld.h 4 Aug 2004 01:25:52 -0000 1.2 @@ -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) Index: arch/mips/momentum/ocelot_g/pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/momentum/ocelot_g/pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/momentum/ocelot_g/pci.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/momentum/ocelot_g/pci.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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 */ Index: arch/mips/momentum/ocelot_g/prom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/momentum/ocelot_g/prom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/momentum/ocelot_g/prom.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/momentum/ocelot_g/prom.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -40,7 +40,7 @@ extern unsigned long gt64240_base; extern unsigned long bus_clock; -#ifdef CONFIG_GALILLEO_GT64240_ETH +#ifdef CONFIG_GALILEO_GT64240_ETH extern unsigned char prom_mac_addr_base[6]; #endif @@ -71,7 +71,7 @@ mips_machgroup = MACH_GROUP_MOMENCO; mips_machtype = MACH_MOMENCO_OCELOT_G; -#ifdef CONFIG_GALILLEO_GT64240_ETH +#ifdef CONFIG_GALILEO_GT64240_ETH /* get the base MAC address for on-board ethernet ports */ memcpy(prom_mac_addr_base, (void*)0xfc807cf2, 6); #endif Index: arch/mips/momentum/ocelot_g/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/momentum/ocelot_g/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/momentum/ocelot_g/setup.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/momentum/ocelot_g/setup.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -70,6 +70,10 @@ extern struct rtc_ops no_rtc_ops; +#ifdef CONFIG_GALILEO_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_GALILEO_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__ ( Index: arch/mips/philips/nino/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/philips/nino/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/philips/nino/Makefile 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/philips/nino/Makefile 4 Aug 2004 01:25:52 -0000 1.2 @@ -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 Index: arch/mips/philips/nino/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/philips/nino/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/philips/nino/irq.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/philips/nino/irq.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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); Index: arch/mips/philips/nino/power.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/philips/nino/power.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/philips/nino/power.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/philips/nino/power.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -19,7 +19,7 @@ outl(inl(TX3912_POWER_CTRL) | TX3912_POWER_CTRL_STOPCPU, TX3912_POWER_CTRL); - /* + /* * We wait until an interrupt happens... */ Index: arch/mips/philips/nino/prom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/philips/nino/prom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/philips/nino/prom.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/philips/nino/prom.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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 } Index: arch/mips/philips/nino/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/philips/nino/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/philips/nino/setup.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/philips/nino/setup.c 4 Aug 2004 01:25:52 -0000 1.2 @@ -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); Index: arch/mips/ramdisk/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/ramdisk/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/ramdisk/Makefile 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/ramdisk/Makefile 4 Aug 2004 01:25:53 -0000 1.2 @@ -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 - Index: arch/mips/sgi-ip22/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sgi-ip22/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sgi-ip22/Makefile 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sgi-ip22/Makefile 4 Aug 2004 01:25:53 -0000 1.2 @@ -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_BOARD_SCACHE) += ip22-sc.o -obj-$(CONFIG_IP22_EISA) += ip22-eisa.o +obj-$(CONFIG_EISA) += ip22-eisa.o + +export-objs := ip22-ksyms.o ip22-irq.o: ip22-irq.S Index: arch/mips/sgi-ip22/ip22-berr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sgi-ip22/ip22-berr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sgi-ip22/ip22-berr.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sgi-ip22/ip22-berr.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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; } Index: arch/mips/sgi-ip22/ip22-eisa.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sgi-ip22/ip22-eisa.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sgi-ip22/ip22-eisa.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sgi-ip22/ip22-eisa.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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). Index: arch/mips/sgi-ip22/ip22-gio.c =================================================================== RCS file: arch/mips/sgi-ip22/ip22-gio.c diff -N arch/mips/sgi-ip22/ip22-gio.c --- arch/mips/sgi-ip22/ip22-gio.c 22 Jul 2004 19:49:17 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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"); -} Index: arch/mips/sgi-ip22/ip22-hpc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sgi-ip22/ip22-hpc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sgi-ip22/ip22-hpc.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sgi-ip22/ip22-hpc.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -4,89 +4,53 @@ * 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 +#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; + /* ioremap can't fail */ + hpc3c0 = (struct hpc3_regs *) + ioremap(HPC3_CHIP0_BASE, sizeof(struct hpc3_regs)); + hpc3c1 = (struct hpc3_regs *) + ioremap(HPC3_CHIP1_BASE, sizeof(struct hpc3_regs)); + /* 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; } Index: arch/mips/sgi-ip22/ip22-int.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sgi-ip22/ip22-int.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sgi-ip22/ip22-int.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sgi-ip22/ip22-int.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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 */ + +#ifdef CONFIG_EISA + if (ip22_is_fullhouse()) /* Only Indigo-2 have EISA stuff */ ip22_eisa_init (); #endif } Index: arch/mips/sgi-ip22/ip22-mc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sgi-ip22/ip22-mc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sgi-ip22/ip22-mc.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sgi-ip22/ip22-mc.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -1,89 +1,116 @@ /* - * 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 +#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); + /* ioremap can't fail */ + sgimc = (struct sgimc_regs *) + ioremap(SGIMC_BASE, sizeof(struct sgimc_regs)); 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 +120,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 +161,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) {} Index: arch/mips/sgi-ip22/ip22-reset.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sgi-ip22/ip22-reset.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sgi-ip22/ip22-reset.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sgi-ip22/ip22-reset.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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); Index: arch/mips/sgi-ip22/ip22-rtc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sgi-ip22/ip22-rtc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sgi-ip22/ip22-rtc.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sgi-ip22/ip22-rtc.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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 }; Index: arch/mips/sgi-ip22/ip22-sc.c =================================================================== RCS file: arch/mips/sgi-ip22/ip22-sc.c diff -N arch/mips/sgi-ip22/ip22-sc.c --- arch/mips/sgi-ip22/ip22-sc.c 22 Jul 2004 19:49:17 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; - } -} Index: arch/mips/sgi-ip22/ip22-setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sgi-ip22/ip22-setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sgi-ip22/ip22-setup.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sgi-ip22/ip22-setup.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -22,39 +22,31 @@ #include #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 *); +#ifdef CONFIG_EISA +extern struct fd_ops std_fd_ops; #endif +extern struct rtc_ops ip22_rtc_ops; -extern void sgitime_init(void); - -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 +54,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 +70,61 @@ 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; + void __init ip22_setup(void) { - char *ctype; -#ifdef CONFIG_REMOTE_DEBUG + struct console_cmdline *c; + char *con; +#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,91 +138,95 @@ /* 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)); + /* Set EISA IO port base for Indigo2 */ + set_io_port_base(KSEG1ADDR(0x00080000)); + /* Nothing registered console before us, so simply use first entry */ + c = &console_cmdline[0]; /* ARCS console environment variable is set to "g?" for * graphics console, it is set to "d" for the first serial * line and "d2" for the second serial line. */ - ctype = ArcGetEnvironmentVariable("console"); - if (*ctype == 'd') { -#ifdef CONFIG_SERIAL_CONSOLE - 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 + con = ArcGetEnvironmentVariable("console"); + if (con && *con == 'd') { + static char options[8]; + char *baud = ArcGetEnvironmentVariable("dbaud"); + strcpy(c->name, "ttyS"); + c->index = *(con + 1) == '2' ? 1 : 0; + if (baud) { + strcpy(options, baud); + c->options = options; + } + } else if (!con || *con != 'g') { + /* Use ARC if we don't want serial ('d') or Newport ('g'). */ + prom_flags |= PROM_FLAG_USE_AS_CONSOLE; + strcpy(c->name, "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 - { - unsigned long *gfxinfo; - long (*__vec)(void) = (void *) *(long *)((PROMBLOCK)->pvector + 0x20); + if (con && *con == 'g'){ + ULONG *gfxinfo; + ULONG * (*__vec)(void) = (void *) (long) + *((_PULONG *)(long)((PROMBLOCK)->pvector + 0x20)); - gfxinfo = (unsigned long *)__vec(); + gfxinfo = __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; +/* + * Warning: this is broken, means it has to be known at kernel compile time + * if a floppy module might ever be loaded + */ +#if defined(CONFIG_EISA) && defined(CONFIG_BLK_DEV_FD) + fd_ops = &std_fd_ops; +#endif + rtc_ops = &ip22_rtc_ops; + kbd_ops = &ip22_kbd_ops; #ifdef CONFIG_PSMOUSE aux_device_present = 0xaa; #endif Index: arch/mips/sgi-ip22/ip22-system.c =================================================================== RCS file: arch/mips/sgi-ip22/ip22-system.c diff -N arch/mips/sgi-ip22/ip22-system.c --- arch/mips/sgi-ip22/ip22-system.c 22 Jul 2004 19:49:17 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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"); -} Index: arch/mips/sgi-ip22/ip22-time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sgi-ip22/ip22-time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sgi-ip22/ip22-time.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sgi-ip22/ip22-time.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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] & 0x3f; + 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(); + mips_hpt_frequency = r4k_tick * HZ; } /* 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; Index: arch/mips/sgi-ip27/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sgi-ip27/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sgi-ip27/Makefile 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sgi-ip27/Makefile 4 Aug 2004 01:25:53 -0000 1.2 @@ -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 Index: arch/mips/sgi-ip27/ip27-berr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sgi-ip27/ip27-berr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sgi-ip27/ip27-berr.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sgi-ip27/ip27-berr.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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); Index: arch/mips/sgi-ip27/ip27-console.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sgi-ip27/ip27-console.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sgi-ip27/ip27-console.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sgi-ip27/ip27-console.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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(); } Index: arch/mips/sgi-ip27/ip27-init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sgi-ip27/ip27-init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sgi-ip27/ip27-init.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sgi-ip27/ip27-init.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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) @@ -443,7 +466,6 @@ int num_cpus = 0; cpuid_t cpu, mycpuid = getcpuid(); cnodeid_t cnode; - extern void smp_bootstrap(void); sn_mp_setup(); /* Master has already done per_cpu_init() */ @@ -457,68 +479,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 +578,7 @@ init_new_context(current, &init_mm); current->processor = 0; init_idle(); - smp_tune_scheduling(); + /* smp_tune_scheduling(); XXX */ allowboot(); } Index: arch/mips/sgi-ip27/ip27-irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sgi-ip27/ip27-irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sgi-ip27/ip27-irq.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sgi-ip27/ip27-irq.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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); Index: arch/mips/sgi-ip27/ip27-nmi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sgi-ip27/ip27-nmi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sgi-ip27/ip27-nmi.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sgi-ip27/ip27-nmi.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -52,23 +52,77 @@ */ void -nmi_cpu_eframe_save(nasid_t nasid, - int slice) +nmi_cpu_eframe_save(nasid_t nasid, int slice) { - int i, numberof_nmi_cpu_regs; - machreg_t *prom_format; - - /* Get the total number of registers being saved by the prom */ - numberof_nmi_cpu_regs = sizeof(struct reg_struct) / sizeof(machreg_t); + struct reg_struct *nr; + int i; /* Get the pointer to the current cpu's register set. */ - prom_format = - (machreg_t *)(TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) + - slice * IP27_NMI_KREGS_CPU_SIZE); + nr = (struct reg_struct *) + (TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) + + slice * IP27_NMI_KREGS_CPU_SIZE); printk("NMI nasid %d: slice %d\n", nasid, slice); - for (i = 0; i < numberof_nmi_cpu_regs; i++) - printk("0x%lx ", prom_format[i]); + + /* + * Saved main processor registers + */ + for (i = 0; i < 32; ) { + if ((i % 4) == 0) + printk("$%2d :", i); + printk(" %016lx", nr->gpr[i]); + + i++; + if ((i % 4) == 0) + printk("\n"); + } + + printk("Hi : (value lost)\n"); + printk("Lo : (value lost)\n"); + + /* + * Saved cp0 registers + */ + printk("epc : %016lx %s\n", nr->epc, print_tainted()); + printk("Status: %08lx ", nr->sr); + + if (nr->sr & ST0_KX) + printk("KX "); + if (nr->sr & ST0_SX) + printk("SX "); + if (nr->sr & ST0_UX) + printk("UX "); + + switch (nr->sr & ST0_KSU) { + case KSU_USER: + printk("USER "); + break; + case KSU_SUPERVISOR: + printk("SUPERVISOR "); + break; + case KSU_KERNEL: + printk("KERNEL "); + break; + default: + printk("BAD_MODE "); + break; + } + + if (nr->sr & ST0_ERL) + printk("ERL "); + if (nr->sr & ST0_EXL) + printk("EXL "); + if (nr->sr & ST0_IE) + printk("IE "); + printk("\n"); + + printk("Cause : %08lx\n", nr->cause); + printk("PrId : %08x\n", read_c0_prid()); + printk("BadVA : %016lx\n", nr->badva); + printk("ErrEPC: %016lx\n", nr->error_epc); + printk("CErr : %016lx\n", nr->cache_err); + printk("NMI_SR: %016lx\n", nr->nmi_sr); + printk("\n\n"); } Index: arch/mips/sgi-ip27/ip27-pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sgi-ip27/ip27-pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sgi-ip27/ip27-pci.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sgi-ip27/ip27-pci.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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], Index: arch/mips/sgi-ip27/ip27-rtc.c =================================================================== RCS file: arch/mips/sgi-ip27/ip27-rtc.c diff -N arch/mips/sgi-ip27/ip27-rtc.c --- arch/mips/sgi-ip27/ip27-rtc.c 22 Jul 2004 19:49:17 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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--; -} Index: arch/mips/sgi-ip27/ip27-setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sgi-ip27/ip27-setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sgi-ip27/ip27-setup.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sgi-ip27/ip27-setup.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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; } Index: arch/mips/sgi-ip27/ip27-timer.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sgi-ip27/ip27-timer.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sgi-ip27/ip27-timer.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sgi-ip27/ip27-timer.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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) Index: arch/mips/sgi-ip32/Makefile =================================================================== RCS file: arch/mips/sgi-ip32/Makefile diff -N arch/mips/sgi-ip32/Makefile --- arch/mips/sgi-ip32/Makefile 22 Jul 2004 19:49:17 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: arch/mips/sgi-ip32/crime.c =================================================================== RCS file: arch/mips/sgi-ip32/crime.c diff -N arch/mips/sgi-ip32/crime.c --- arch/mips/sgi-ip32/crime.c 22 Jul 2004 19:49:17 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); -} Index: arch/mips/sgi-ip32/ip32-berr.c =================================================================== RCS file: arch/mips/sgi-ip32/ip32-berr.c diff -N arch/mips/sgi-ip32/ip32-berr.c --- arch/mips/sgi-ip32/ip32-berr.c 22 Jul 2004 19:49:17 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; -} Index: arch/mips/sgi-ip32/ip32-irq-glue.S =================================================================== RCS file: arch/mips/sgi-ip32/ip32-irq-glue.S diff -N arch/mips/sgi-ip32/ip32-irq-glue.S --- arch/mips/sgi-ip32/ip32-irq-glue.S 22 Jul 2004 19:49:17 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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) Index: arch/mips/sgi-ip32/ip32-irq.c =================================================================== RCS file: arch/mips/sgi-ip32/ip32-irq.c diff -N arch/mips/sgi-ip32/ip32-irq.c --- arch/mips/sgi-ip32/ip32-irq.c 22 Jul 2004 19:49:17 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); -} Index: arch/mips/sgi-ip32/ip32-pci.c =================================================================== RCS file: arch/mips/sgi-ip32/ip32-pci.c diff -N arch/mips/sgi-ip32/ip32-pci.c --- arch/mips/sgi-ip32/ip32-pci.c 22 Jul 2004 19:49:17 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; -} Index: arch/mips/sgi-ip32/ip32-reset.c =================================================================== RCS file: arch/mips/sgi-ip32/ip32-reset.c diff -N arch/mips/sgi-ip32/ip32-reset.c --- arch/mips/sgi-ip32/ip32-reset.c 22 Jul 2004 19:49:17 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; -} Index: arch/mips/sgi-ip32/ip32-rtc.c =================================================================== RCS file: arch/mips/sgi-ip32/ip32-rtc.c diff -N arch/mips/sgi-ip32/ip32-rtc.c --- arch/mips/sgi-ip32/ip32-rtc.c 22 Jul 2004 19:49:17 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 -}; Index: arch/mips/sgi-ip32/ip32-setup.c =================================================================== RCS file: arch/mips/sgi-ip32/ip32-setup.c diff -N arch/mips/sgi-ip32/ip32-setup.c --- arch/mips/sgi-ip32/ip32-setup.c 22 Jul 2004 19:49:17 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; -} Index: arch/mips/sgi-ip32/ip32-timer.c =================================================================== RCS file: arch/mips/sgi-ip32/ip32-timer.c diff -N arch/mips/sgi-ip32/ip32-timer.c --- arch/mips/sgi-ip32/ip32-timer.c 22 Jul 2004 19:49:17 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 (); -} Index: arch/mips/sibyte/cfe/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sibyte/cfe/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sibyte/cfe/Makefile 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/sibyte/cfe/Makefile 4 Aug 2004 01:25:53 -0000 1.2 @@ -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 Index: arch/mips/sibyte/cfe/cfe_api.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sibyte/cfe/cfe_api.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sibyte/cfe/cfe_api.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sibyte/cfe/cfe_api.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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 */ Index: arch/mips/sibyte/cfe/cfe_api.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sibyte/cfe/cfe_api.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sibyte/cfe/cfe_api.h 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sibyte/cfe/cfe_api.h 4 Aug 2004 01:25:53 -0000 1.2 @@ -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 */ Index: arch/mips/sibyte/cfe/cfe_error.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sibyte/cfe/cfe_error.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sibyte/cfe/cfe_error.h 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sibyte/cfe/cfe_error.h 4 Aug 2004 01:25:53 -0000 1.2 @@ -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 Index: arch/mips/sibyte/cfe/cfe_xiocb.h =================================================================== RCS file: arch/mips/sibyte/cfe/cfe_xiocb.h diff -N arch/mips/sibyte/cfe/cfe_xiocb.h --- arch/mips/sibyte/cfe/cfe_xiocb.h 22 Jul 2004 19:49:16 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; Index: arch/mips/sibyte/cfe/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sibyte/cfe/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sibyte/cfe/setup.c 22 Jul 2004 19:49:16 -0000 1.1 +++ arch/mips/sibyte/cfe/setup.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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,13 +23,11 @@ #include #include #include -#include #include #include #include -#include "cfe_xiocb.h" #include "cfe_api.h" #include "cfe_error.h" @@ -48,10 +46,6 @@ #endif #endif -#define SB1250_DUART_MINOR_BASE 192 /* XXXKW put this somewhere sane */ -#define SB1250_PROMICE_MINOR_BASE 191 /* XXXKW put this somewhere sane */ -kdev_t cfe_consdev; - #define SIBYTE_MAX_MEM_REGIONS 8 phys_t board_mem_region_addrs[SIBYTE_MAX_MEM_REGIONS]; phys_t board_mem_region_sizes[SIBYTE_MAX_MEM_REGIONS]; @@ -62,6 +56,8 @@ quite redundant. But not something to fix just now */ extern char arcs_cmdline[]; +int cfe_cons_handle; + #ifdef CONFIG_EMBEDDED_RAMDISK /* These are symbols defined by the ramdisk linker script */ extern unsigned char __rd_start; @@ -72,6 +68,10 @@ static int reboot_smp = 0; #endif +#ifdef CONFIG_KGDB +extern int kgdb_port; +#endif + static void cfe_linux_exit(void) { #ifdef CONFIG_SMP @@ -95,8 +95,8 @@ static __init void prom_meminit(void) { - u64 addr, size; /* regardless of 64BIT_PHYS_ADDR */ - long type; + u64 addr, size, type; /* regardless of 64BIT_PHYS_ADDR */ + int mem_flags = 0; unsigned int idx; int rd_flag; #ifdef CONFIG_BLK_DEV_INITRD @@ -114,8 +114,8 @@ } #endif - initrd_pstart = __pa(initrd_start); - initrd_pend = __pa(initrd_end); + initrd_pstart = CPHYSADDR(initrd_start); + initrd_pend = CPHYSADDR(initrd_end); if (initrd_start && ((initrd_pstart > MAX_RAM_SIZE) || (initrd_pend > MAX_RAM_SIZE))) { @@ -124,7 +124,7 @@ #endif /* INITRD */ - for (idx = 0; cfe_enummem(idx, &addr, &size, &type) != CFE_ERR_NOMORE; + for (idx = 0; cfe_enummem(idx, mem_flags, &addr, &size, &type) != CFE_ERR_NOMORE; idx++) { rd_flag = 0; if (type == CFE_MI_AVAILABLE) { @@ -189,6 +189,18 @@ #ifdef CONFIG_BLK_DEV_INITRD static int __init initrd_setup(char *str) { + char rdarg[64]; + int idx; + + /* Make a copy of the initrd argument so we can smash it up here */ + for (idx = 0; idx < sizeof(rdarg)-1; idx++) { + if (!str[idx] || (str[idx] == ' ')) break; + rdarg[idx] = str[idx]; + } + + rdarg[idx] = 0; + str = rdarg; + /* *Initrd location comes in the form "@" * 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; -} Index: arch/mips/sibyte/sb1250/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sibyte/sb1250/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sibyte/sb1250/Makefile 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sibyte/sb1250/Makefile 4 Aug 2004 01:25:53 -0000 1.2 @@ -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 Index: arch/mips/sibyte/sb1250/bcm1250_tbprof.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sibyte/sb1250/bcm1250_tbprof.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sibyte/sb1250/bcm1250_tbprof.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sibyte/sb1250/bcm1250_tbprof.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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; } Index: arch/mips/sibyte/sb1250/bcm1250_tbprof.h =================================================================== RCS file: arch/mips/sibyte/sb1250/bcm1250_tbprof.h diff -N arch/mips/sibyte/sb1250/bcm1250_tbprof.h --- arch/mips/sibyte/sb1250/bcm1250_tbprof.h 22 Jul 2004 19:49:17 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: arch/mips/sibyte/sb1250/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sibyte/sb1250/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sibyte/sb1250/irq.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sibyte/sb1250/irq.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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 */ Index: arch/mips/sibyte/sb1250/irq_handler.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sibyte/sb1250/irq_handler.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sibyte/sb1250/irq_handler.S 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sibyte/sb1250/irq_handler.S 4 Aug 2004 01:25:53 -0000 1.2 @@ -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 */ Index: arch/mips/sibyte/sb1250/lib_hssubr.S =================================================================== RCS file: arch/mips/sibyte/sb1250/lib_hssubr.S diff -N arch/mips/sibyte/sb1250/lib_hssubr.S --- arch/mips/sibyte/sb1250/lib_hssubr.S 22 Jul 2004 19:49:17 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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) Index: arch/mips/sibyte/sb1250/lib_hssubr.h =================================================================== RCS file: arch/mips/sibyte/sb1250/lib_hssubr.h diff -N arch/mips/sibyte/sb1250/lib_hssubr.h --- arch/mips/sibyte/sb1250/lib_hssubr.h 22 Jul 2004 19:49:17 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 */ Index: arch/mips/sibyte/sb1250/pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sibyte/sb1250/pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sibyte/sb1250/pci.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sibyte/sb1250/pci.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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. Index: arch/mips/sibyte/sb1250/prom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sibyte/sb1250/prom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sibyte/sb1250/prom.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sibyte/sb1250/prom.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -117,3 +117,7 @@ phys_t addr = pagenr << PAGE_SHIFT; return (addr < (CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024)); } + +void prom_putchar(char c) +{ +} Index: arch/mips/sibyte/sb1250/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sibyte/sb1250/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sibyte/sb1250/setup.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sibyte/sb1250/setup.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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); } } Index: arch/mips/sibyte/sb1250/smp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sibyte/sb1250/smp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sibyte/sb1250/smp.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sibyte/sb1250/smp.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -62,9 +62,6 @@ void sb1250_smp_finish(void) { - extern void sb1_sanitize_tlb(void); - - sb1_sanitize_tlb(); sb1250_time_init(); } @@ -91,8 +88,33 @@ } extern atomic_t cpus_booted; -extern int prom_setup_smp(void); -extern int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp); +extern atomic_t smp_commenced; + +/* + * Hook for doing final board-specific setup after the generic smp setup + * is done + */ +asmlinkage void start_secondary(void) +{ + unsigned int cpu = smp_processor_id(); + + cpu_probe(); + prom_init_secondary(); + per_cpu_trap_init(); + + /* + * XXX parity protection should be folded in here when it's converted + * to an option instead of something based on .cputype + */ + pgd_current[cpu] = init_mm.pgd; + cpu_data[cpu].udelay_val = loops_per_jiffy; + prom_smp_finish(); + printk("Slave cpu booted successfully\n"); + CPUMASK_SETB(cpu_online_map, cpu); + atomic_inc(&cpus_booted); + while (!atomic_read(&smp_commenced)); + cpu_idle(); +} void __init smp_boot_cpus(void) { @@ -108,6 +130,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 @@ -116,7 +141,6 @@ for (i = 1; i < smp_num_cpus; ) { struct task_struct *p; struct pt_regs regs; - int retval; printk("Starting CPU %d... ", i); /* Spawn a new process normally. Grab a pointer to @@ -128,9 +152,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); @@ -139,15 +160,13 @@ do { /* Iterate until we find a CPU that comes up */ cur_cpu++; - retval = prom_boot_secondary(cur_cpu, + prom_boot_secondary(cur_cpu, (unsigned long)p + KERNEL_STACK_SIZE - 32, (unsigned long)p); - } while (!retval && (cur_cpu < NR_CPUS)); - if (retval) { - i++; - } else { - panic("CPU discovery disaster"); - } + } while (cur_cpu < NR_CPUS); + __cpu_number_map[cur_cpu] = i; + __cpu_logical_map[i] = cur_cpu; + i++; } /* Wait for everyone to come up */ Index: arch/mips/sibyte/sb1250/time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sibyte/sb1250/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sibyte/sb1250/time.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sibyte/sb1250/time.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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,8 @@ 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]++; /* 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 +110,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); } /* Index: arch/mips/sibyte/swarm/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sibyte/swarm/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sibyte/swarm/Makefile 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sibyte/swarm/Makefile 4 Aug 2004 01:25:53 -0000 1.2 @@ -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 Index: arch/mips/sibyte/swarm/dbg_io.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sibyte/swarm/dbg_io.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sibyte/swarm/dbg_io.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sibyte/swarm/dbg_io.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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); Index: arch/mips/sibyte/swarm/rtc_xicor1241.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sibyte/swarm/rtc_xicor1241.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sibyte/swarm/rtc_xicor1241.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sibyte/swarm/rtc_xicor1241.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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); +} Index: arch/mips/sibyte/swarm/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sibyte/swarm/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sibyte/swarm/setup.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/sibyte/swarm/setup.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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 Index: arch/mips/sni/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sni/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sni/Makefile 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/sni/Makefile 4 Aug 2004 01:25:53 -0000 1.2 @@ -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 Index: arch/mips/sni/int-handler.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sni/int-handler.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sni/int-handler.S 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/sni/int-handler.S 4 Aug 2004 01:25:53 -0000 1.2 @@ -47,7 +47,7 @@ bnez t1, _hwint0 nop - j restore_all # spurious interrupt + j ret_from_irq # spurious interrupt nop ############################################################################## Index: arch/mips/sni/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sni/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sni/irq.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/sni/irq.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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); Index: arch/mips/sni/pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sni/pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sni/pci.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/sni/pci.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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 */ Index: arch/mips/sni/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/sni/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/sni/setup.c 22 Jul 2004 19:49:14 -0000 1.1 +++ arch/mips/sni/setup.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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; /* Index: arch/mips/tools/offset.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/tools/offset.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/tools/offset.c 22 Jul 2004 19:49:15 -0000 1.1 +++ arch/mips/tools/offset.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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 @@ -21,7 +22,7 @@ #define offset(string, ptr, member) \ __asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member))) #define constant(string, member) \ - __asm__("\n@@@" string "%x0" : : "i" (member)) + __asm__("\n@@@" string "%x0" : : "ri" (member)) #define size(string, size) \ __asm__("\n@@@" string "%0" : : "i" (sizeof(size))) #define linefeed text("") @@ -93,6 +94,12 @@ offset("#define TASK_PID ", struct task_struct, pid); size( "#define TASK_STRUCT_SIZE ", struct task_struct); linefeed; + + text("/* MIPS task_struct allocation info. */"); + constant("#define _THREAD_ORDER ", THREAD_ORDER); + constant("#define _THREAD_SIZE ", THREAD_SIZE); + constant("#define _THREAD_MASK ", THREAD_MASK); + linefeed; } void output_thread_defines(void) @@ -137,9 +144,29 @@ offset("#define MM_CONTEXT ", struct mm_struct, context); linefeed; constant("#define _PAGE_SIZE ", PAGE_SIZE); - constant("#define _PGD_ORDER ", PGD_ORDER); + constant("#define _PAGE_SHIFT ", PAGE_SHIFT); + linefeed; + constant("#define _PGD_T_SIZE ", sizeof(pgd_t)); + constant("#define _PMD_T_SIZE ", sizeof(pmd_t)); + constant("#define _PTE_T_SIZE ", sizeof(pte_t)); + linefeed; + constant("#define _PGD_T_LOG2 ", PGD_T_LOG2); + constant("#define _PMD_T_LOG2 ", PMD_T_LOG2); + constant("#define _PTE_T_LOG2 ", PTE_T_LOG2); + linefeed; + constant("#define _PMD_SHIFT ", PMD_SHIFT); constant("#define _PGDIR_SHIFT ", PGDIR_SHIFT); linefeed; + constant("#define _PGD_ORDER ", PGD_ORDER); +#ifdef PMD_ORDER + constant("#define _PMD_ORDER ", PMD_ORDER); +#endif + constant("#define _PTE_ORDER ", PTE_ORDER); + linefeed; + constant("#define _PTRS_PER_PGD ", PTRS_PER_PGD); + constant("#define _PTRS_PER_PMD ", PTRS_PER_PMD); + constant("#define _PTRS_PER_PTE ", PTRS_PER_PTE); + linefeed; } void output_sc_defines(void) @@ -151,12 +178,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) Index: arch/mips/vr4181/common/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr4181/common/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr4181/common/irq.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr4181/common/irq.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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(); Index: arch/mips/vr4181/common/serial.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr4181/common/serial.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr4181/common/serial.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr4181/common/serial.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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. Index: arch/mips/vr4181/common/time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr4181/common/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr4181/common/time.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr4181/common/time.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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 */ Index: arch/mips/vr4181/osprey/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr4181/osprey/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr4181/osprey/Makefile 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr4181/osprey/Makefile 4 Aug 2004 01:25:53 -0000 1.2 @@ -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 Index: arch/mips/vr4181/osprey/prom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr4181/osprey/prom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr4181/osprey/prom.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr4181/osprey/prom.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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. */ Index: arch/mips/vr4181/osprey/reset.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr4181/osprey/reset.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr4181/osprey/reset.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr4181/osprey/reset.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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)); } Index: arch/mips/vr4181/osprey/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr4181/osprey/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr4181/osprey/setup.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr4181/osprey/setup.c 4 Aug 2004 01:25:53 -0000 1.2 @@ -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; Index: arch/mips/vr41xx/common/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr41xx/common/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr41xx/common/Makefile 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr41xx/common/Makefile 4 Aug 2004 01:25:54 -0000 1.2 @@ -12,10 +12,14 @@ O_TARGET := vr41xx.o -obj-y := bcu.o cmu.o giu.o icu.o int-handler.o reset.o +obj-y := bcu.o cmu.o giu.o icu.o int-handler.o ksyms.o reset.o rtc.o + +export-objs := ksyms.o vrc4171.o vrc4173.o obj-$(CONFIG_PCI) += pciu.o obj-$(CONFIG_SERIAL) += serial.o -obj-$(CONFIG_VR41XX_TIME_C) += time.o +obj-$(CONFIG_VRC4171) += vrc4171.o +obj-$(CONFIG_VRC4173) += vrc4173.o +obj-$(subst m,y,$(CONFIG_IDE)) += ide.o include $(TOPDIR)/Rules.make Index: arch/mips/vr41xx/common/bcu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr41xx/common/bcu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr41xx/common/bcu.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr41xx/common/bcu.c 4 Aug 2004 01:25:54 -0000 1.2 @@ -33,27 +33,22 @@ /* * Changes: * MontaVista Software Inc. or + * - New creation, NEC VR4122 and VR4131 are supported. * - Added support for NEC VR4111 and VR4121. * - * Paul Mundt - * - Calculate mips_counter_frequency properly on VR4131. - * - * MontaVista Software Inc. or - * - New creation, NEC VR4122 and VR4131 are supported. + * Yoichi Yuasa + * - Added support for NEC VR4133. */ #include #include -#include #include #include -#include -#include -#define VR4111_CLKSPEEDREG KSEG1ADDR(0x0b000014) -#define VR4122_CLKSPEEDREG KSEG1ADDR(0x0f000014) -#define VR4131_CLKSPEEDREG VR4122_CLKSPEEDREG +#define CLKSPEEDREG_TYPE1 KSEG1ADDR(0x0b000014) +#define CLKSPEEDREG_TYPE2 KSEG1ADDR(0x0f000014) #define CLKSP(x) ((x) & 0x001f) + #define CLKSP_VR4133(x) ((x) & 0x0007) #define DIV2B 0x8000 #define DIV3B 0x4000 @@ -65,15 +60,27 @@ #define TDIVMODE(x) (2 << (((x) & 0x1000) >> 12)) #define VTDIVMODE(x) (((x) & 0x0700) >> 8) -unsigned long vr41xx_vtclock = 0; +static unsigned long vr41xx_vtclock; +static unsigned long vr41xx_tclock; -static inline u16 read_clkspeed(void) +unsigned long vr41xx_get_vtclock_frequency(void) { - switch (mips_cpu.cputype) { + return vr41xx_vtclock; +} + +unsigned long vr41xx_get_tclock_frequency(void) +{ + return vr41xx_tclock; +} + +static inline uint16_t read_clkspeed(void) +{ + switch (current_cpu_data.cputype) { case CPU_VR4111: - case CPU_VR4121: return readw(VR4111_CLKSPEEDREG); - case CPU_VR4122: return readw(VR4122_CLKSPEEDREG); - case CPU_VR4131: return readw(VR4131_CLKSPEEDREG); + case CPU_VR4121: return readw(CLKSPEEDREG_TYPE1); + case CPU_VR4122: + case CPU_VR4131: + case CPU_VR4133: return readw(CLKSPEEDREG_TYPE2); default: printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); break; @@ -82,76 +89,103 @@ return 0; } -static inline unsigned long calculate_pclock(u16 clkspeed) +static inline unsigned long calculate_pclock(uint16_t clkspeed) { unsigned long pclock = 0; - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: pclock = 18432000 * 64; + pclock /= CLKSP(clkspeed); break; case CPU_VR4122: pclock = 18432000 * 98; + pclock /= CLKSP(clkspeed); break; case CPU_VR4131: pclock = 18432000 * 108; + pclock /= CLKSP(clkspeed); + break; + case CPU_VR4133: + switch (CLKSP_VR4133(clkspeed)) { + case 0: + pclock = 133000000; + break; + case 1: + pclock = 149000000; + break; + case 2: + pclock = 165900000; + break; + case 3: + pclock = 199100000; + break; + case 4: + pclock = 265900000; + break; + default: + printk(KERN_INFO "Unknown PClock speed for NEC VR4133\n"); + break; + } break; default: printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); break; } - pclock /= CLKSP(clkspeed); printk(KERN_INFO "PClock: %ldHz\n", pclock); return pclock; } -static inline unsigned long calculate_vtclock(u16 clkspeed, unsigned long pclock) +static inline unsigned long calculate_vtclock(uint16_t clkspeed, unsigned long pclock) { - switch (mips_cpu.cputype) { + unsigned long vtclock = 0; + + switch (current_cpu_data.cputype) { case CPU_VR4111: /* The NEC VR4111 doesn't have the VTClock. */ break; case CPU_VR4121: - vr41xx_vtclock = pclock; + vtclock = pclock; /* DIVVT == 9 Divide by 1.5 . VTClock = (PClock * 6) / 9 */ if (DIVVT(clkspeed) == 9) - vr41xx_vtclock = pclock * 6; + vtclock = pclock * 6; /* DIVVT == 10 Divide by 2.5 . VTClock = (PClock * 4) / 10 */ else if (DIVVT(clkspeed) == 10) - vr41xx_vtclock = pclock * 4; - vr41xx_vtclock /= DIVVT(clkspeed); - printk(KERN_INFO "VTClock: %ldHz\n", vr41xx_vtclock); + vtclock = pclock * 4; + vtclock /= DIVVT(clkspeed); + printk(KERN_INFO "VTClock: %ldHz\n", vtclock); break; case CPU_VR4122: if(VTDIVMODE(clkspeed) == 7) - vr41xx_vtclock = pclock / 1; + vtclock = pclock / 1; else if(VTDIVMODE(clkspeed) == 1) - vr41xx_vtclock = pclock / 2; + vtclock = pclock / 2; else - vr41xx_vtclock = pclock / VTDIVMODE(clkspeed); - printk(KERN_INFO "VTClock: %ldHz\n", vr41xx_vtclock); + vtclock = pclock / VTDIVMODE(clkspeed); + printk(KERN_INFO "VTClock: %ldHz\n", vtclock); break; case CPU_VR4131: - vr41xx_vtclock = pclock / VTDIVMODE(clkspeed); - printk(KERN_INFO "VTClock: %ldHz\n", vr41xx_vtclock); + case CPU_VR4133: + vtclock = pclock / VTDIVMODE(clkspeed); + printk(KERN_INFO "VTClock: %ldHz\n", vtclock); break; default: printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); break; } - return vr41xx_vtclock; + return vtclock; } -static inline unsigned long calculate_tclock(u16 clkspeed, unsigned long pclock, +static inline unsigned long calculate_tclock(uint16_t clkspeed, unsigned long pclock, unsigned long vtclock) { unsigned long tclock = 0; - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: if (!(clkspeed & DIV2B)) tclock = pclock / 2; @@ -165,6 +199,7 @@ break; case CPU_VR4122: case CPU_VR4131: + case CPU_VR4133: tclock = vtclock / TDIVMODE(clkspeed); break; default: @@ -177,30 +212,14 @@ return tclock; } -static inline unsigned long calculate_mips_counter_frequency(unsigned long tclock) -{ - /* - * 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)) - tclock /= 2; - else - tclock /= 4; - - return tclock; -} - void __init vr41xx_bcu_init(void) { - unsigned long pclock, vtclock, tclock; - u16 clkspeed; + unsigned long pclock; + uint16_t clkspeed; clkspeed = read_clkspeed(); pclock = calculate_pclock(clkspeed); - vtclock = calculate_vtclock(clkspeed, pclock); - tclock = calculate_tclock(clkspeed, pclock, vtclock); - - mips_counter_frequency = calculate_mips_counter_frequency(tclock); + vr41xx_vtclock = calculate_vtclock(clkspeed, pclock); + vr41xx_tclock = calculate_tclock(clkspeed, pclock, vr41xx_vtclock); } Index: arch/mips/vr41xx/common/cmu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr41xx/common/cmu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr41xx/common/cmu.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr41xx/common/cmu.c 4 Aug 2004 01:25:54 -0000 1.2 @@ -33,52 +33,192 @@ /* * Changes: * MontaVista Software Inc. or + * - New creation, NEC VR4122 and VR4131 are supported. * - Added support for NEC VR4111 and VR4121. * - * MontaVista Software Inc. or - * - New creation, NEC VR4122 and VR4131 are supported. + * Yoichi Yuasa + * - Added support for NEC VR4133. */ #include #include #include #include +#include -#define VR4111_CMUCLKMSK KSEG1ADDR(0x0b000060) -#define VR4122_CMUCLKMSK KSEG1ADDR(0x0f000060) +#define CMUCLKMSK_TYPE1 KSEG1ADDR(0x0b000060) +#define CMUCLKMSK_TYPE2 KSEG1ADDR(0x0f000060) + #define MSKPIU 0x0001 + #define MSKSIU 0x0002 + #define MSKAIU 0x0004 + #define MSKKIU 0x0008 + #define MSKFIR 0x0010 + #define MSKDSIU 0x0820 + #define MSKCSI 0x0040 + #define MSKPCIU 0x0080 + #define MSKSSIU 0x0100 + #define MSKSHSP 0x0200 + #define MSKFFIR 0x0400 + #define MSKSCSI 0x1000 + #define MSKPPCIU 0x2000 +#define CMUCLKMSK2 KSEG1ADDR(0x0f000064) + #define MSKCEU 0x0001 + #define MSKMAC0 0x0002 + #define MSKMAC1 0x0004 static u32 vr41xx_cmu_base; -static u16 cmuclkmsk; +static u16 cmuclkmsk, cmuclkmsk2; -#define write_cmu(mask) writew((mask), vr41xx_cmu_base) +#define read_cmuclkmsk() readw(vr41xx_cmu_base) +#define read_cmuclkmsk2() readw(CMUCLKMSK2) +#define write_cmuclkmsk() writew(cmuclkmsk, vr41xx_cmu_base) +#define write_cmuclkmsk2() writew(cmuclkmsk2, CMUCLKMSK2) -void vr41xx_clock_supply(u16 mask) +void vr41xx_clock_supply(unsigned int clock) { - cmuclkmsk |= mask; - write_cmu(cmuclkmsk); + switch (clock) { + case PIU_CLOCK: + cmuclkmsk |= MSKPIU; + break; + case SIU_CLOCK: + cmuclkmsk |= MSKSIU | MSKSSIU; + break; + case AIU_CLOCK: + cmuclkmsk |= MSKAIU; + break; + case KIU_CLOCK: + cmuclkmsk |= MSKKIU; + break; + case FIR_CLOCK: + cmuclkmsk |= MSKFIR | MSKFFIR; + break; + case DSIU_CLOCK: + if (current_cpu_data.cputype == CPU_VR4111 || + current_cpu_data.cputype == CPU_VR4121) + cmuclkmsk |= MSKDSIU; + else + cmuclkmsk |= MSKSIU | MSKDSIU; + break; + case CSI_CLOCK: + cmuclkmsk |= MSKCSI | MSKSCSI; + break; + case PCIU_CLOCK: + cmuclkmsk |= MSKPCIU; + break; + case HSP_CLOCK: + cmuclkmsk |= MSKSHSP; + break; + case PCI_CLOCK: + cmuclkmsk |= MSKPPCIU; + break; + case CEU_CLOCK: + cmuclkmsk2 |= MSKCEU; + break; + case ETHER0_CLOCK: + cmuclkmsk2 |= MSKMAC0; + break; + case ETHER1_CLOCK: + cmuclkmsk2 |= MSKMAC1; + break; + default: + break; + } + + if (clock == CEU_CLOCK || clock == ETHER0_CLOCK || + clock == ETHER1_CLOCK) + write_cmuclkmsk2(); + else + write_cmuclkmsk(); } -void vr41xx_clock_mask(u16 mask) +void vr41xx_clock_mask(unsigned int clock) { - cmuclkmsk &= ~mask; - write_cmu(cmuclkmsk); + switch (clock) { + case PIU_CLOCK: + cmuclkmsk &= ~MSKPIU; + break; + case SIU_CLOCK: + if (current_cpu_data.cputype == CPU_VR4111 || + current_cpu_data.cputype == CPU_VR4121) { + cmuclkmsk &= ~(MSKSIU | MSKSSIU); + } else { + if (cmuclkmsk & MSKDSIU) + cmuclkmsk &= ~MSKSSIU; + else + cmuclkmsk &= ~(MSKSIU | MSKSSIU); + } + break; + case AIU_CLOCK: + cmuclkmsk &= ~MSKAIU; + break; + case KIU_CLOCK: + cmuclkmsk &= ~MSKKIU; + break; + case FIR_CLOCK: + cmuclkmsk &= ~(MSKFIR | MSKFFIR); + break; + case DSIU_CLOCK: + if (current_cpu_data.cputype == CPU_VR4111 || + current_cpu_data.cputype == CPU_VR4121) { + cmuclkmsk &= ~MSKDSIU; + } else { + if (cmuclkmsk & MSKSIU) + cmuclkmsk &= ~MSKDSIU; + else + cmuclkmsk &= ~(MSKSIU | MSKDSIU); + } + break; + case CSI_CLOCK: + cmuclkmsk &= ~(MSKCSI | MSKSCSI); + break; + case PCIU_CLOCK: + cmuclkmsk &= ~MSKPCIU; + break; + case HSP_CLOCK: + cmuclkmsk &= ~MSKSHSP; + break; + case PCI_CLOCK: + cmuclkmsk &= ~MSKPPCIU; + break; + case CEU_CLOCK: + cmuclkmsk2 &= ~MSKCEU; + break; + case ETHER0_CLOCK: + cmuclkmsk2 &= ~MSKMAC0; + break; + case ETHER1_CLOCK: + cmuclkmsk2 &= ~MSKMAC1; + break; + default: + break; + } + + if (clock == CEU_CLOCK || clock == ETHER0_CLOCK || + clock == ETHER1_CLOCK) + write_cmuclkmsk2(); + else + write_cmuclkmsk(); } -void __init vr41xx_cmu_init(u16 mask) +void __init vr41xx_cmu_init(void) { - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: - vr41xx_cmu_base = VR4111_CMUCLKMSK; + vr41xx_cmu_base = CMUCLKMSK_TYPE1; break; case CPU_VR4122: case CPU_VR4131: - vr41xx_cmu_base = VR4122_CMUCLKMSK; + vr41xx_cmu_base = CMUCLKMSK_TYPE2; + break; + case CPU_VR4133: + vr41xx_cmu_base = CMUCLKMSK_TYPE2; + cmuclkmsk2 = read_cmuclkmsk2(); break; default: panic("Unexpected CPU of NEC VR4100 series"); break; } - cmuclkmsk = mask; + cmuclkmsk = read_cmuclkmsk(); } Index: arch/mips/vr41xx/common/giu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr41xx/common/giu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr41xx/common/giu.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr41xx/common/giu.c 4 Aug 2004 01:25:54 -0000 1.2 @@ -34,6 +34,9 @@ * Changes: * MontaVista Software Inc. or * - New creation, NEC VR4111, VR4121, VR4122 and VR4131 are supported. + * + * Yoichi Yuasa + * - Added support for NEC VR4133. */ #include #include @@ -41,13 +44,12 @@ #include #include -#include #include #include #include -#define VR4111_GIUIOSELL KSEG1ADDR(0x0b000100) -#define VR4122_GIUIOSELL KSEG1ADDR(0x0f000140) +#define GIUIOSELL_TYPE1 KSEG1ADDR(0x0b000100) +#define GIUIOSELL_TYPE2 KSEG1ADDR(0x0f000140) #define GIUIOSELL 0x00 #define GIUIOSELH 0x02 @@ -61,15 +63,19 @@ #define GIUINTALSELH 0x16 #define GIUINTHTSELL 0x18 #define GIUINTHTSELH 0x1a +#define GIUFEDGEINHL 0x20 +#define GIUFEDGEINHH 0x22 +#define GIUREDGEINHL 0x24 +#define GIUREDGEINHH 0x26 -u32 vr41xx_giu_base = 0; +static uint32_t giu_base; -#define read_giuint(offset) readw(vr41xx_giu_base + (offset)) -#define write_giuint(val, offset) writew((val), vr41xx_giu_base + (offset)) +#define read_giuint(offset) readw(giu_base + (offset)) +#define write_giuint(val, offset) writew((val), giu_base + (offset)) -static inline u16 set_giuint(u16 offset, u16 set) +static inline uint16_t set_giuint(uint8_t offset, uint16_t set) { - u16 res; + uint16_t res; res = read_giuint(offset); res |= set; @@ -78,9 +84,9 @@ return res; } -static inline u16 clear_giuint(u16 offset, u16 clear) +static inline uint16_t clear_giuint(uint8_t offset, uint16_t clear) { - u16 res; + uint16_t res; res = read_giuint(offset); res &= ~clear; @@ -89,54 +95,86 @@ return res; } -void vr41xx_enable_giuint(u8 pin) +void vr41xx_enable_giuint(int pin) { if (pin < 16) - set_giuint(GIUINTENL, (u16)1 << pin); + set_giuint(GIUINTENL, (uint16_t)1 << pin); else - set_giuint(GIUINTENH, (u16)1 << (pin - 16)); + set_giuint(GIUINTENH, (uint16_t)1 << (pin - 16)); } -void vr41xx_disable_giuint(u8 pin) +void vr41xx_disable_giuint(int pin) { if (pin < 16) - clear_giuint(GIUINTENL, (u16)1 << pin); + clear_giuint(GIUINTENL, (uint16_t)1 << pin); else - clear_giuint(GIUINTENH, (u16)1 << (pin - 16)); + clear_giuint(GIUINTENH, (uint16_t)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((uint16_t)1 << pin, GIUINTSTATL); else - write_giuint(GIUINTSTATH, (u16)1 << (pin - 16)); + write_giuint((uint16_t)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; + uint16_t mask; if (pin < 16) { - mask = (u16)1 << pin; - if (trigger == TRIGGER_EDGE) { + mask = (uint16_t)1 << pin; + if (trigger != TRIGGER_LEVEL) { set_giuint(GIUINTTYPL, mask); if (hold == SIGNAL_HOLD) set_giuint(GIUINTHTSELL, mask); else clear_giuint(GIUINTHTSELL, mask); + if (current_cpu_data.cputype == CPU_VR4133) { + switch (trigger) { + case TRIGGER_EDGE_FALLING: + set_giuint(GIUFEDGEINHL, mask); + clear_giuint(GIUREDGEINHL, mask); + break; + case TRIGGER_EDGE_RISING: + clear_giuint(GIUFEDGEINHL, mask); + set_giuint(GIUREDGEINHL, mask); + break; + default: + set_giuint(GIUFEDGEINHL, mask); + set_giuint(GIUREDGEINHL, mask); + break; + } + } } else { clear_giuint(GIUINTTYPL, mask); clear_giuint(GIUINTHTSELL, mask); } } else { - mask = (u16)1 << (pin - 16); - if (trigger == TRIGGER_EDGE) { + mask = (uint16_t)1 << (pin - 16); + if (trigger != TRIGGER_LEVEL) { set_giuint(GIUINTTYPH, mask); if (hold == SIGNAL_HOLD) set_giuint(GIUINTHTSELH, mask); else clear_giuint(GIUINTHTSELH, mask); + if (current_cpu_data.cputype == CPU_VR4133) { + switch (trigger) { + case TRIGGER_EDGE_FALLING: + set_giuint(GIUFEDGEINHH, mask); + clear_giuint(GIUREDGEINHH, mask); + break; + case TRIGGER_EDGE_RISING: + clear_giuint(GIUFEDGEINHH, mask); + set_giuint(GIUREDGEINHH, mask); + break; + default: + set_giuint(GIUFEDGEINHH, mask); + set_giuint(GIUREDGEINHH, mask); + break; + } + } } else { clear_giuint(GIUINTTYPH, mask); clear_giuint(GIUINTHTSELH, mask); @@ -146,18 +184,18 @@ vr41xx_clear_giuint(pin); } -void vr41xx_set_irq_level(u8 pin, u8 level) +void vr41xx_set_irq_level(int pin, int level) { - u16 mask; + uint16_t mask; if (pin < 16) { - mask = (u16)1 << pin; + mask = (uint16_t)1 << pin; if (level == LEVEL_HIGH) set_giuint(GIUINTALSELL, mask); else clear_giuint(GIUINTALSELL, mask); } else { - mask = (u16)1 << (pin - 16); + mask = (uint16_t)1 << (pin - 16); if (level == LEVEL_HIGH) set_giuint(GIUINTALSELH, mask); else @@ -167,7 +205,6 @@ vr41xx_clear_giuint(pin); } -#define GIUINT_CASCADE_IRQ 16 #define GIUINT_NR_IRQS 32 enum { @@ -199,7 +236,7 @@ if(!get_irq_number) return -EINVAL; - pin = irq - GIU_IRQ(0); + pin = GIU_IRQ_TO_PIN(irq); giuint_cascade[pin].flag = GIUINT_CASCADE; giuint_cascade[pin].get_irq_number = get_irq_number; @@ -212,8 +249,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; @@ -222,7 +257,7 @@ disable_irq(GIUINT_CASCADE_IRQ); cascade = &giuint_cascade[pin]; - giuint_irq = pin + GIU_IRQ(0); + giuint_irq = GIU_IRQ(pin); if (cascade->flag == GIUINT_CASCADE) { cascade_irq = cascade->get_irq_number(giuint_irq); disable_irq(giuint_irq); @@ -242,14 +277,15 @@ { int i; - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: - vr41xx_giu_base = VR4111_GIUIOSELL; + giu_base = GIUIOSELL_TYPE1; break; case CPU_VR4122: case CPU_VR4131: - vr41xx_giu_base = VR4122_GIUIOSELL; + case CPU_VR4133: + giu_base = GIUIOSELL_TYPE2; break; default: panic("GIU: Unexpected CPU of NEC VR4100 series"); Index: arch/mips/vr41xx/common/icu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr41xx/common/icu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr41xx/common/icu.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr41xx/common/icu.c 4 Aug 2004 01:25:54 -0000 1.2 @@ -1,9 +1,9 @@ /* * FILE NAME - * arch/mips/vr41xx/vr4122/common/icu.c + * arch/mips/vr41xx/common/icu.c * * BRIEF MODULE DESCRIPTION - * Interrupt Control Unit routines for the NEC VR4122 and VR4131. + * Interrupt Control Unit routines for the NEC VR4100 series. * * Author: Yoichi Yuasa * yyuasa@mvista.com or source@mvista.com @@ -33,13 +33,11 @@ /* * Changes: * MontaVista Software Inc. or + * - New creation, NEC VR4122 and VR4131 are supported. * - Added support for NEC VR4111 and VR4121. * - * Paul Mundt - * - kgdb support. - * - * MontaVista Software Inc. or - * - New creation, NEC VR4122 and VR4131 are supported. + * Yoichi Yuasa + * - Coped with INTASSIGN of NEC VR4133. */ #include #include @@ -47,62 +45,65 @@ #include #include -#include #include -#include #include -#include +#include +#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 void vr41xx_enable_giuint(int pin); +extern void vr41xx_disable_giuint(int pin); +extern void vr41xx_clear_giuint(int pin); extern unsigned int giuint_do_IRQ(int pin, struct pt_regs *regs); -static u32 vr41xx_icu1_base = 0; -static u32 vr41xx_icu2_base = 0; +static uint32_t icu1_base; +static uint32_t icu2_base; -#define VR4111_SYSINT1REG KSEG1ADDR(0x0b000080) -#define VR4111_SYSINT2REG KSEG1ADDR(0x0b000200) +static unsigned char sysint1_assign[16] = { + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +static unsigned char sysint2_assign[16] = { + 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -#define VR4122_SYSINT1REG KSEG1ADDR(0x0f000080) -#define VR4122_SYSINT2REG KSEG1ADDR(0x0f0000a0) +#define SYSINT1REG_TYPE1 KSEG1ADDR(0x0b000080) +#define SYSINT2REG_TYPE1 KSEG1ADDR(0x0b000200) + +#define SYSINT1REG_TYPE2 KSEG1ADDR(0x0f000080) +#define SYSINT2REG_TYPE2 KSEG1ADDR(0x0f0000a0) #define SYSINT1REG 0x00 +#define INTASSIGN0 0x04 +#define INTASSIGN1 0x06 #define GIUINTLREG 0x08 #define MSYSINT1REG 0x0c #define MGIUINTLREG 0x14 #define NMIREG 0x18 #define SOFTREG 0x1a +#define INTASSIGN2 0x1c +#define INTASSIGN3 0x1e #define SYSINT2REG 0x00 #define GIUINTHREG 0x02 #define MSYSINT2REG 0x06 #define MGIUINTHREG 0x08 -#define read_icu1(offset) readw(vr41xx_icu1_base + (offset)) -#define write_icu1(val, offset) writew((val), vr41xx_icu1_base + (offset)) +#define SYSINT1_IRQ_TO_PIN(x) ((x) - SYSINT1_IRQ_BASE) /* Pin 0-15 */ +#define SYSINT2_IRQ_TO_PIN(x) ((x) - SYSINT2_IRQ_BASE) /* Pin 0-15 */ + +#define read_icu1(offset) readw(icu1_base + (offset)) +#define write_icu1(val, offset) writew((val), icu1_base + (offset)) -#define read_icu2(offset) readw(vr41xx_icu2_base + (offset)) -#define write_icu2(val, offset) writew((val), vr41xx_icu2_base + (offset)) +#define read_icu2(offset) readw(icu2_base + (offset)) +#define write_icu2(val, offset) writew((val), icu2_base + (offset)) -static inline u16 set_icu1(u16 offset, u16 set) +#define INTASSIGN_MAX 4 +#define INTASSIGN_MASK 0x0007 + +static inline uint16_t set_icu1(uint8_t offset, uint16_t set) { - u16 res; + uint16_t res; res = read_icu1(offset); res |= set; @@ -111,9 +112,9 @@ return res; } -static inline u16 clear_icu1(u16 offset, u16 clear) +static inline uint16_t clear_icu1(uint8_t offset, uint16_t clear) { - u16 res; + uint16_t res; res = read_icu1(offset); res &= ~clear; @@ -122,9 +123,9 @@ return res; } -static inline u16 set_icu2(u16 offset, u16 set) +static inline uint16_t set_icu2(uint8_t offset, uint16_t set) { - u16 res; + uint16_t res; res = read_icu2(offset); res |= set; @@ -133,9 +134,9 @@ return res; } -static inline u16 clear_icu2(u16 offset, u16 clear) +static inline uint16_t clear_icu2(uint8_t offset, uint16_t clear) { - u16 res; + uint16_t res; res = read_icu2(offset); res &= ~clear; @@ -148,17 +149,17 @@ static void enable_sysint1_irq(unsigned int irq) { - set_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE)); + set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); } static void disable_sysint1_irq(unsigned int irq) { - clear_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE)); + clear_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); } static unsigned int startup_sysint1_irq(unsigned int irq) { - set_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE)); + set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); return 0; /* never anything pending */ } @@ -169,35 +170,34 @@ static void end_sysint1_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - set_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE)); + set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); } static struct hw_interrupt_type sysint1_irq_type = { - "SYSINT1", - startup_sysint1_irq, - shutdown_sysint1_irq, - enable_sysint1_irq, - disable_sysint1_irq, - ack_sysint1_irq, - end_sysint1_irq, - NULL + .typename = "SYSINT1", + .startup = startup_sysint1_irq, + .shutdown = shutdown_sysint1_irq, + .enable = enable_sysint1_irq, + .disable = disable_sysint1_irq, + .ack = ack_sysint1_irq, + .end = end_sysint1_irq, }; /*=======================================================================*/ static void enable_sysint2_irq(unsigned int irq) { - set_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE)); + set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); } static void disable_sysint2_irq(unsigned int irq) { - clear_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE)); + clear_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); } static unsigned int startup_sysint2_irq(unsigned int irq) { - set_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE)); + set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); return 0; /* never anything pending */ } @@ -208,55 +208,48 @@ static void end_sysint2_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - set_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE)); + set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); } static struct hw_interrupt_type sysint2_irq_type = { - "SYSINT2", - startup_sysint2_irq, - shutdown_sysint2_irq, - enable_sysint2_irq, - disable_sysint2_irq, - ack_sysint2_irq, - end_sysint2_irq, - NULL + .typename = "SYSINT2", + .startup = startup_sysint2_irq, + .shutdown = shutdown_sysint2_irq, + .enable = enable_sysint2_irq, + .disable = disable_sysint2_irq, + .ack = ack_sysint2_irq, + .end = end_sysint2_irq, }; /*=======================================================================*/ -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 = GIU_IRQ_TO_PIN(irq); if (pin < 16) - set_icu1(MGIUINTLREG, (u16)1 << pin); + set_icu1(MGIUINTLREG, (uint16_t)1 << pin); else - set_icu2(MGIUINTHREG, (u16)1 << (pin - 16)); - + set_icu2(MGIUINTHREG, (uint16_t)1 << (pin - 16)); vr41xx_enable_giuint(pin); } static void disable_giuint_irq(unsigned int irq) { - u8 pin; + int pin; - pin = irq - GIUINT_IRQ_BASE; + pin = GIU_IRQ_TO_PIN(irq); vr41xx_disable_giuint(pin); - if (pin < 16) - clear_icu1(MGIUINTLREG, (u16)1 << pin); + clear_icu1(MGIUINTLREG, (uint16_t)1 << pin); else - clear_icu2(MGIUINTHREG, (u16)1 << (pin - 16)); + clear_icu2(MGIUINTHREG, (uint16_t)1 << (pin - 16)); } static unsigned int startup_giuint_irq(unsigned int irq) { - vr41xx_clear_giuint(irq - GIUINT_IRQ_BASE); + vr41xx_clear_giuint(GIU_IRQ_TO_PIN(irq)); enable_giuint_irq(irq); @@ -269,7 +262,7 @@ { disable_giuint_irq(irq); - vr41xx_clear_giuint(irq - GIUINT_IRQ_BASE); + vr41xx_clear_giuint(GIU_IRQ_TO_PIN(irq)); } static void end_giuint_irq(unsigned int irq) @@ -279,14 +272,13 @@ } static struct hw_interrupt_type giuint_irq_type = { - "GIUINT", - startup_giuint_irq, - shutdown_giuint_irq, - enable_giuint_irq, - disable_giuint_irq, - ack_giuint_irq, - end_giuint_irq, - NULL + .typename = "GIUINT", + .startup = startup_giuint_irq, + .shutdown = shutdown_giuint_irq, + .enable = enable_giuint_irq, + .disable = disable_giuint_irq, + .ack = ack_giuint_irq, + .end = end_giuint_irq, }; /*=======================================================================*/ @@ -297,16 +289,17 @@ { int i; - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: - vr41xx_icu1_base = VR4111_SYSINT1REG; - vr41xx_icu2_base = VR4111_SYSINT2REG; + icu1_base = SYSINT1REG_TYPE1; + icu2_base = SYSINT2REG_TYPE1; break; case CPU_VR4122: case CPU_VR4131: - vr41xx_icu1_base = VR4122_SYSINT1REG; - vr41xx_icu2_base = VR4122_SYSINT2REG; + case CPU_VR4133: + icu1_base = SYSINT1REG_TYPE2; + icu2_base = SYSINT2REG_TYPE2; break; default: panic("Unexpected CPU of NEC VR4100 series"); @@ -319,16 +312,20 @@ 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; } - setup_irq(ICU_CASCADE_IRQ, &icu_cascade); + setup_irq(INT0_CASCADE_IRQ, &icu_cascade); + setup_irq(INT1_CASCADE_IRQ, &icu_cascade); + setup_irq(INT2_CASCADE_IRQ, &icu_cascade); + setup_irq(INT3_CASCADE_IRQ, &icu_cascade); + setup_irq(INT4_CASCADE_IRQ, &icu_cascade); } void __init init_IRQ(void) @@ -342,31 +339,171 @@ vr41xx_giuint_init(); set_except_vector(0, vr41xx_handle_interrupt); +} + +/*=======================================================================*/ + +static inline int set_sysint1_assign(unsigned int irq, unsigned char assign) +{ + irq_desc_t *desc = irq_desc + irq; + uint16_t intassign0, intassign1; + unsigned int pin; + + pin = SYSINT1_IRQ_TO_PIN(irq); + + spin_lock_irq(&desc->lock); + + intassign0 = read_icu1(INTASSIGN0); + intassign1 = read_icu1(INTASSIGN1); + + switch (pin) { + case 0: + intassign0 &= ~INTASSIGN_MASK; + intassign0 |= (uint16_t)assign; + break; + case 1: + intassign0 &= ~(INTASSIGN_MASK << 3); + intassign0 |= (uint16_t)assign << 3; + break; + case 2: + intassign0 &= ~(INTASSIGN_MASK << 6); + intassign0 |= (uint16_t)assign << 6; + break; + case 3: + intassign0 &= ~(INTASSIGN_MASK << 9); + intassign0 |= (uint16_t)assign << 9; + break; + case 8: + intassign0 &= ~(INTASSIGN_MASK << 12); + intassign0 |= (uint16_t)assign << 12; + break; + case 9: + intassign1 &= ~INTASSIGN_MASK; + intassign1 |= (uint16_t)assign; + break; + case 11: + intassign1 &= ~(INTASSIGN_MASK << 6); + intassign1 |= (uint16_t)assign << 6; + break; + case 12: + intassign1 &= ~(INTASSIGN_MASK << 9); + intassign1 |= (uint16_t)assign << 9; + break; + default: + return -EINVAL; + } + + sysint1_assign[pin] = assign; + write_icu1(intassign0, INTASSIGN0); + write_icu1(intassign1, INTASSIGN1); + + spin_unlock_irq(&desc->lock); + + return 0; +} + +static inline int set_sysint2_assign(unsigned int irq, unsigned char assign) +{ + irq_desc_t *desc = irq_desc + irq; + uint16_t intassign2, intassign3; + unsigned int pin; + + pin = SYSINT2_IRQ_TO_PIN(irq); + + spin_lock_irq(&desc->lock); -#ifdef CONFIG_REMOTE_DEBUG - printk("Setting debug traps - please connect the remote debugger.\n"); - set_debug_traps(); - breakpoint(); -#endif + intassign2 = read_icu1(INTASSIGN2); + intassign3 = read_icu1(INTASSIGN3); + + switch (pin) { + case 0: + intassign2 &= ~INTASSIGN_MASK; + intassign2 |= (uint16_t)assign; + break; + case 1: + intassign2 &= ~(INTASSIGN_MASK << 3); + intassign2 |= (uint16_t)assign << 3; + break; + case 3: + intassign2 &= ~(INTASSIGN_MASK << 6); + intassign2 |= (uint16_t)assign << 6; + break; + case 4: + intassign2 &= ~(INTASSIGN_MASK << 9); + intassign2 |= (uint16_t)assign << 9; + break; + case 5: + intassign2 &= ~(INTASSIGN_MASK << 12); + intassign2 |= (uint16_t)assign << 12; + break; + case 6: + intassign3 &= ~INTASSIGN_MASK; + intassign3 |= (uint16_t)assign; + break; + case 7: + intassign3 &= ~(INTASSIGN_MASK << 3); + intassign3 |= (uint16_t)assign << 3; + break; + case 8: + intassign3 &= ~(INTASSIGN_MASK << 6); + intassign3 |= (uint16_t)assign << 6; + break; + case 9: + intassign3 &= ~(INTASSIGN_MASK << 9); + intassign3 |= (uint16_t)assign << 9; + break; + case 10: + intassign3 &= ~(INTASSIGN_MASK << 12); + intassign3 |= (uint16_t)assign << 12; + break; + default: + return -EINVAL; + } + + sysint2_assign[pin] = assign; + write_icu1(intassign2, INTASSIGN2); + write_icu1(intassign3, INTASSIGN3); + + spin_unlock_irq(&desc->lock); + + return 0; +} + +int vr41xx_set_intassign(unsigned int irq, unsigned char intassign) +{ + int retval = -EINVAL; + + if (current_cpu_data.cputype != CPU_VR4133) + return -EINVAL; + + if (intassign > INTASSIGN_MAX) + return -EINVAL; + + if (irq >= SYSINT1_IRQ_BASE && irq <= SYSINT1_IRQ_LAST) + retval = set_sysint1_assign(irq, intassign); + else if (irq >= SYSINT2_IRQ_BASE && irq <= SYSINT2_IRQ_LAST) + retval = set_sysint2_assign(irq, intassign); + + return retval; } /*=======================================================================*/ -static inline void giuint_irqdispatch(u16 pendl, u16 pendh, struct pt_regs *regs) +static inline void giuint_irq_dispatch(uint16_t pendl, uint16_t pendh, + struct pt_regs *regs) { int i; if (pendl) { for (i = 0; i < 16; i++) { - if (pendl & (0x0001 << i)) { + if (pendl & ((uint16_t)1 << i)) { giuint_do_IRQ(i, regs); return; } } - } - else if (pendh) { + } else { for (i = 0; i < 16; i++) { - if (pendh & (0x0001 << i)) { + if (pendh & ((uint16_t)1 << i)) { giuint_do_IRQ(i + 16, regs); return; } @@ -374,10 +511,10 @@ } } -asmlinkage void icu_irqdispatch(struct pt_regs *regs) +asmlinkage void irq_dispatch(unsigned char intnum, struct pt_regs *regs) { - u16 pend1, pend2, pendl, pendh; - u16 mask1, mask2, maskl, maskh; + uint16_t pend1, pend2, pendl, pendh; + uint16_t mask1, mask2, maskl, maskh; int i; pend1 = read_icu1(SYSINT1REG); @@ -392,31 +529,36 @@ pendh = read_icu2(GIUINTHREG); maskh = read_icu2(MGIUINTHREG); - pend1 &= mask1; - pend2 &= mask2; - pendl &= maskl; - pendh &= maskh; - - if (pend1) { - if ((pend1 & 0x01ff) == 0x0100) { - giuint_irqdispatch(pendl, pendh, regs); - } - else { - for (i = 0; i < 16; i++) { - if (pend1 & (0x0001 << i)) { - do_IRQ(SYSINT1_IRQ_BASE + i, regs); - break; + mask1 &= pend1; + mask2 &= pend2; + maskl &= pendl; + maskh &= pendh; + + if (mask1) { + for (i = 0; i < 16; i++) { + if (intnum == sysint1_assign[i] && + (mask1 & ((uint16_t)1 << i))) { + if (i == 8 && (maskl | maskh)) { + giuint_irq_dispatch(maskl, maskh, regs); + return; + } else { + do_IRQ(SYSINT1_IRQ(i), regs); + return; } } } - return; } - else if (pend2) { + + if (mask2) { for (i = 0; i < 16; i++) { - if (pend2 & (0x0001 << i)) { - do_IRQ(SYSINT2_IRQ_BASE + i, regs); - break; + if (intnum == sysint2_assign[i] && + (mask2 & ((uint16_t)1 << i))) { + do_IRQ(SYSINT2_IRQ(i), regs); + return; } } } + + printk(KERN_ERR "spurious interrupt: %04x,%04x,%04x,%04x\n", pend1, pend2, pendl, pendh); + atomic_inc(&irq_err_count); } Index: arch/mips/vr41xx/common/int-handler.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr41xx/common/int-handler.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr41xx/common/int-handler.S 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr41xx/common/int-handler.S 4 Aug 2004 01:25:54 -0000 1.2 @@ -34,6 +34,9 @@ * Changes: * MontaVista Software Inc. or * - New creation, NEC VR4100 series are supported. + * + * Yoichi Yuasa + * - Coped with INTASSIGN of NEC VR4133. */ #include #include @@ -59,55 +62,52 @@ andi t0, 0xff00 and t0, t0, t1 - andi t1, t0, CAUSEF_IP7 # timer interrupt - beqz t1, 1f + andi t1, t0, CAUSEF_IP7 # MIPS timer interrupt + bnez t1, handle_irq li a0, 7 - jal ll_timer_interrupt - move a1, sp - j ret_from_irq -1: - andi t1, t0, 0x7800 # check for IP3-6 - beqz t1, 2f + andi t1, t0, 0x7800 # check for Int1-4 + beqz t1, 1f - andi t1, t0, CAUSEF_IP3 # check for IP3 - bnez t1, handle_it + andi t1, t0, CAUSEF_IP3 # check for Int1 + bnez t1, handle_int + li a0, 1 + + andi t1, t0, CAUSEF_IP4 # check for Int2 + bnez t1, handle_int + li a0, 2 + + andi t1, t0, CAUSEF_IP5 # check for Int3 + bnez t1, handle_int li a0, 3 - andi t1, t0, CAUSEF_IP4 # check for IP4 - bnez t1, handle_it + andi t1, t0, CAUSEF_IP6 # check for Int4 + bnez t1, handle_int li a0, 4 - andi t1, t0, CAUSEF_IP5 # check for IP5 - bnez t1, handle_it - li a0, 5 - - andi t1, t0, CAUSEF_IP6 # check for IP6 - bnez t1, handle_it - li a0, 6 - -2: - andi t1, t0, CAUSEF_IP2 # check for IP2 - beqz t1, 3f - move a0, sp - jal icu_irqdispatch - nop - j ret_from_irq - nop +1: + andi t1, t0, CAUSEF_IP2 # check for Int0 + bnez t1, handle_int + li a0, 0 -3: andi t1, t0, CAUSEF_IP0 # check for IP0 - bnez t1, handle_it + bnez t1, handle_irq li a0, 0 andi t1, t0, CAUSEF_IP1 # check for IP1 - bnez t1, handle_it + bnez t1, handle_irq li a0, 1 j spurious_interrupt nop -handle_it: +handle_int: + jal irq_dispatch + move a1, sp + j ret_from_irq + nop + +handle_irq: jal do_IRQ move a1, sp j ret_from_irq Index: arch/mips/vr41xx/common/pciu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr41xx/common/pciu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr41xx/common/pciu.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr41xx/common/pciu.c 4 Aug 2004 01:25:54 -0000 1.2 @@ -51,8 +51,6 @@ #include "pciu.h" -extern unsigned long vr41xx_vtclock; - static inline int vr41xx_pci_config_access(struct pci_dev *dev, int where) { unsigned char bus = dev->bus->number; @@ -74,7 +72,7 @@ /* * Type 1 configuration */ - if (bus > 255 || PCI_SLOT(dev_fn) > 31 || where > 255) + if (PCI_SLOT(dev_fn) > 31 || where > 255) return -1; writel((bus << 16) | @@ -196,6 +194,7 @@ void __init vr41xx_pciu_init(struct vr41xx_pci_address_map *map) { struct vr41xx_pci_address_space *s; + unsigned long vtclock; u32 config; int n; @@ -215,11 +214,12 @@ udelay(1); /* Select PCI clock */ - if (vr41xx_vtclock < MAX_PCI_CLOCK) + vtclock = vr41xx_get_vtclock_frequency(); + if (vtclock < MAX_PCI_CLOCK) writel(EQUAL_VTCLOCK, PCICLKSELREG); - else if ((vr41xx_vtclock / 2) < MAX_PCI_CLOCK) + else if ((vtclock / 2) < MAX_PCI_CLOCK) writel(HALF_VTCLOCK, PCICLKSELREG); - else if ((vr41xx_vtclock / 4) < MAX_PCI_CLOCK) + else if ((vtclock / 4) < MAX_PCI_CLOCK) writel(QUARTER_VTCLOCK, PCICLKSELREG); else printk(KERN_INFO "Warning: PCI Clock is over 33MHz.\n"); @@ -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 { Index: arch/mips/vr41xx/common/pciu.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr41xx/common/pciu.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr41xx/common/pciu.h 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr41xx/common/pciu.h 4 Aug 2004 01:25:54 -0000 1.2 @@ -107,9 +107,6 @@ #define MAX_PCI_CLOCK 33333333 -#define PCIU_CLOCK 0x0080 -#define PCI_CLOCK 0x2000 - static inline int pciu_read_config_byte(int where, u8 *val) { u32 data; Index: arch/mips/vr41xx/common/reset.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr41xx/common/reset.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr41xx/common/reset.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr41xx/common/reset.c 4 Aug 2004 01:25:54 -0000 1.2 @@ -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)); } Index: arch/mips/vr41xx/common/serial.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr41xx/common/serial.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr41xx/common/serial.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr41xx/common/serial.c 4 Aug 2004 01:25:54 -0000 1.2 @@ -33,10 +33,11 @@ /* * Changes: * MontaVista Software Inc. or + * - New creation, NEC VR4122 and VR4131 are supported. * - Added support for NEC VR4111 and VR4121. * - * MontaVista Software Inc. or - * - New creation, NEC VR4122 and VR4131 are supported. + * Yoichi Yuasa + * - Added support for NEC VR4133. */ #include #include @@ -48,12 +49,12 @@ #include /* VR4111 and VR4121 SIU Registers */ -#define VR4111_SIURB KSEG1ADDR(0x0c000000) -#define VR4111_SIUIRSEL KSEG1ADDR(0x0c000008) +#define SIURB_TYPE1 KSEG1ADDR(0x0c000000) +#define SIUIRSEL_TYPE1 KSEG1ADDR(0x0c000008) -/* VR4122 and VR4131 SIU Registers */ -#define VR4122_SIURB KSEG1ADDR(0x0f000800) -#define VR4122_SIUIRSEL KSEG1ADDR(0x0f000808) +/* VR4122, VR4131 and VR4133 SIU Registers */ +#define SIURB_TYPE2 KSEG1ADDR(0x0f000800) +#define SIUIRSEL_TYPE2 KSEG1ADDR(0x0f000808) #define USE_RS232C 0x00 #define USE_IRDA 0x01 @@ -66,8 +67,6 @@ #define TMICMODE 0x20 #define SIU_BASE_BAUD 1152000 -#define SIU_CLOCK 0x0102 -#define SIU_IRQ 17 /* VR4122 and VR4131 DSIU Registers */ #define DSIURB KSEG1ADDR(0x0f000820) @@ -76,8 +75,6 @@ #define INTDSIU 0x0800 #define DSIU_BASE_BAUD 1152000 -#define DSIU_CLOCK 0x0802 -#define DSIU_IRQ 29 int vr41xx_serial_ports = 0; @@ -101,14 +98,15 @@ 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); + writew(val, SIUIRSEL_TYPE1); break; case CPU_VR4122: case CPU_VR4131: - writew(val, VR4122_SIUIRSEL); + case CPU_VR4133: + writew(val, SIUIRSEL_TYPE2); break; default: printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); @@ -128,14 +126,15 @@ 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; + s.iomem_base = (unsigned char *)SIURB_TYPE1; break; case CPU_VR4122: case CPU_VR4131: - s.iomem_base = (unsigned char *)VR4122_SIURB; + case CPU_VR4133: + s.iomem_base = (unsigned char *)SIURB_TYPE2; break; default: panic("Unexpected CPU of NEC VR4100 series"); @@ -155,7 +154,9 @@ { 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 && + current_cpu_data.cputype != CPU_VR4133) return; memset(&s, 0, sizeof(s)); Index: arch/mips/vr41xx/common/time.c =================================================================== RCS file: arch/mips/vr41xx/common/time.c diff -N arch/mips/vr41xx/common/time.c --- arch/mips/vr41xx/common/time.c 22 Jul 2004 19:49:17 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,94 +0,0 @@ -/* - * FILE NAME - * arch/mips/vr41xx/common/time.c - * - * BRIEF MODULE DESCRIPTION - * Timer routines for the NEC VR4100 series. - * - * 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. - */ -/* - * Changes: - * MontaVista Software Inc. or - * - Added support for NEC VR4100 series RTC Unit. - * - * MontaVista Software Inc. or - * - New creation, NEC VR4100 series are supported. - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define MIPS_COUNTER_TIMER_IRQ 7 - -#define VR4111_ETIMELREG KSEG1ADDR(0x0b0000c0) -#define VR4122_ETIMELREG KSEG1ADDR(0x0f000100) - -u32 vr41xx_rtc_base = 0; - -#ifdef CONFIG_VR41XX_RTC -extern unsigned long vr41xx_rtc_get_time(void); -extern int vr41xx_rtc_set_time(unsigned long sec); -#endif - -void vr41xx_time_init(void) -{ - switch (mips_cpu.cputype) { - case CPU_VR4111: - case CPU_VR4121: - vr41xx_rtc_base = VR4111_ETIMELREG; - break; - case CPU_VR4122: - case CPU_VR4131: - vr41xx_rtc_base = VR4122_ETIMELREG; - break; - default: - panic("Unexpected CPU of NEC VR4100 series"); - break; - } - -#ifdef CONFIG_VR41XX_RTC - rtc_get_time = vr41xx_rtc_get_time; - rtc_set_time = vr41xx_rtc_set_time; -#endif -} - -void vr41xx_timer_setup(struct irqaction *irq) -{ - u32 count; - - setup_irq(MIPS_COUNTER_TIMER_IRQ, irq); - - count = read_32bit_cp0_register(CP0_COUNT); - write_32bit_cp0_register (CP0_COMPARE, count + (mips_counter_frequency / HZ)); -} Index: arch/mips/vr41xx/nec-eagle/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr41xx/nec-eagle/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr41xx/nec-eagle/Makefile 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr41xx/nec-eagle/Makefile 4 Aug 2004 01:25:54 -0000 1.2 @@ -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 Index: arch/mips/vr41xx/nec-eagle/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr41xx/nec-eagle/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr41xx/nec-eagle/init.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr41xx/nec-eagle/init.c 4 Aug 2004 01:25:54 -0000 1.2 @@ -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; Index: arch/mips/vr41xx/nec-eagle/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr41xx/nec-eagle/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr41xx/nec-eagle/irq.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr41xx/nec-eagle/irq.c 4 Aug 2004 01:25:54 -0000 1.2 @@ -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); Index: arch/mips/vr41xx/nec-eagle/pci_fixup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr41xx/nec-eagle/pci_fixup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr41xx/nec-eagle/pci_fixup.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr41xx/nec-eagle/pci_fixup.c 4 Aug 2004 01:25:54 -0000 1.2 @@ -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); Index: arch/mips/vr41xx/nec-eagle/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr41xx/nec-eagle/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr41xx/nec-eagle/setup.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr41xx/nec-eagle/setup.c 4 Aug 2004 01:25:54 -0000 1.2 @@ -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); + vr41xx_cmu_init(); +#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 } Index: arch/mips/vr41xx/zao-capcella/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr41xx/zao-capcella/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr41xx/zao-capcella/Makefile 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr41xx/zao-capcella/Makefile 4 Aug 2004 01:25:54 -0000 1.2 @@ -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 Index: arch/mips/vr41xx/zao-capcella/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr41xx/zao-capcella/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr41xx/zao-capcella/init.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr41xx/zao-capcella/init.c 4 Aug 2004 01:25:54 -0000 1.2 @@ -30,13 +30,8 @@ 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; int i; /* @@ -50,17 +45,6 @@ mips_machgroup = MACH_GROUP_NEC_VR41XX; mips_machtype = MACH_ZAO_CAPCELLA; - - switch (mips_cpu.processor_id) { - case PRID_VR4131_REV1_2: - config = read_32bit_cp0_register(CP0_CONFIG); - config &= ~0x00000030UL; - config |= 0x00410000UL; - write_32bit_cp0_register(CP0_CONFIG, config); - break; - default: - break; - } } void __init prom_free_prom_memory (void) Index: arch/mips/vr41xx/zao-capcella/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips/vr41xx/zao-capcella/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips/vr41xx/zao-capcella/setup.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/mips/vr41xx/zao-capcella/setup.c 4 Aug 2004 01:25:54 -0000 1.2 @@ -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,15 +101,16 @@ 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(); - vr41xx_cmu_init(0x0102); + vr41xx_cmu_init(); vr41xx_siu_init(SIU_RS232C, 0); + vr41xx_dsiu_init(); #ifdef CONFIG_PCI vr41xx_pciu_init(&pci_address_map); Index: arch/mips64/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/Makefile 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/Makefile 4 Aug 2004 01:25:54 -0000 1.2 @@ -3,7 +3,7 @@ # License. See the file "COPYING" in the main directory of this archive # for more details. # -# Copyright (C) 2002 Maciej W. Rozycki +# Copyright (C) 2002, 2003 Maciej W. Rozycki # # 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 @@ -11,6 +11,8 @@ # this architecture # +comma := , + # # Select the object file format to substitute into the linker script. # @@ -36,40 +38,93 @@ # GCCFLAGS := -I $(TOPDIR)/include/asm/gcc GCCFLAGS += -mabi=64 -G 0 -mno-abicalls -fno-pic -Wa,--trap -pipe +GCCFLAGS += $(call check_gcc, -finline-limit=100000,) LINKFLAGS += -G 0 -static # -N MODFLAGS += -mlong-calls -ifdef CONFIG_REMOTE_DEBUG +ifdef CONFIG_DEBUG_INFO 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) +check_gas = $(shell if $(CC) $(1) -Wa,-Z -c -o /dev/null -xassembler /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) + +# +# Use: $(call set_gccflags,,,,) +# +# , -- preferred CPU and ISA designations (may require +# recent tools) +# , -- fallback CPU and ISA designations (have to work +# with up to the oldest supported tools) +# +set_gccflags = $(shell \ +while :; do \ + cpu=$(1); isa=-$(2); \ + for gcc_opt in -march= -mcpu=; do \ + $(CC) $$gcc_opt$$cpu $$isa -S -o /dev/null \ + -xc /dev/null > /dev/null 2>&1 && \ + break 2; \ + done; \ + cpu=$(3); isa=-$(4); \ + for gcc_opt in -march= -mcpu=; do \ + $(CC) $$gcc_opt$$cpu $$isa -S -o /dev/null \ + -xc /dev/null > /dev/null 2>&1 && \ + break 2; \ + done; \ + break; \ +done; \ +gcc_cpu=$$cpu; gcc_isa=$$isa; \ +gas_cpu=$$cpu; gas_isa=-Wa,$$isa; \ +while :; do \ + for gas_opt in -Wa,-march= -Wa,-mcpu=; do \ + $(CC) $$gas_opt$$cpu $$gas_isa -Wa,-Z -c -o /dev/null \ + -xassembler /dev/null > /dev/null 2>&1 && \ + break 2; \ + done; \ + gas_opt=; gas_cpu=; gas_isa=; \ + break; \ +done; \ +echo $$gcc_opt$$gcc_cpu $$gcc_isa $$gas_opt$$gas_cpu $$gas_isa) + # # CPU-dependent compiler/assembler options for optimization. # ifdef CONFIG_CPU_R4300 -GCCFLAGS += -mcpu=r4300 -mips3 +GCCFLAGS += $(call set_gccflags,r4300,mips3,r4300,mips3) endif ifdef CONFIG_CPU_R4X00 -GCCFLAGS += -mcpu=r4600 -mips3 +GCCFLAGS += $(call set_gccflags,r4600,mips3,r4600,mips3) endif ifdef CONFIG_CPU_R5000 -GCCFLAGS += -mcpu=r8000 -mips4 +GCCFLAGS += $(call set_gccflags,r5000,mips4,r8000,mips4) endif ifdef CONFIG_CPU_NEVADA -GCCFLAGS += -mcpu=r8000 -mips3 -mmad +GCCFLAGS += $(call set_gccflags,rm5200,mips4,r8000,mips4) +#GCCFLAGS += $(call check_gcc,-mmad,) +endif +ifdef CONFIG_CPU_RM7000 +GCCFLAGS += $(call set_gccflags,rm7000,mips4,r5000,mips4) +endif +ifdef CONFIG_CPU_RM9000 +GCCFLAGS += $(call set_gccflags,rm9000,mips4,r5000,mips4) endif ifdef CONFIG_CPU_R8000 -GCCFLAGS += -mcpu=r8000 -mips4 +GCCFLAGS += $(call set_gccflags,r8000,mips4,r8000,mips4) endif ifdef CONFIG_CPU_R10000 -GCCFLAGS += -mcpu=r8000 -mips4 +GCCFLAGS += $(call set_gccflags,r10000,mips4,r8000,mips4) endif ifdef CONFIG_CPU_SB1 -GCCFLAGS += -mcpu=r8000 -mips4 +GCCFLAGS += $(call set_gccflags,sb1,mips64,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 -CFLAGS += -mcpu=r8000 -mips4 +GCCFLAGS += $(call set_gccflags,mips64,mips64,r8000,mips4) endif # @@ -78,12 +133,51 @@ 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 # # +# Cobalt Server +# +ifdef CONFIG_MIPS_COBALT +SUBDIRS += arch/mips/cobalt +CORE_FILES += arch/mips/cobalt/cobalt.o +LOADADDR := 0x80080000 +endif + +# +# 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 +208,53 @@ 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 +CORE_FILES += arch/mips/momentum/ocelot_c/ocelot_c.o +SUBDIRS += arch/mips/momentum/ocelot_c +LOADADDR := 0x80100000 +endif + +ifdef CONFIG_MOMENCO_JAGUAR_ATX +LIBS += arch/mips/momentum/jaguar_atx/jaguar_atx.o +SUBDIRS += arch/mips/momentum/jaguar_atx +ifdef CONFIG_JAGUAR_DMALOW +LOADADDR := 0x88000000 +else +LOADADDR := 0x80100000 +endif +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 +290,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 +# Sibyte SB1250 SOC and Broadcom (SiByte) BCM112x SOCs # -# 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 -# -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: # -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 # @@ -192,21 +329,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 $(call check_gas,-Wa$(comma)-mgp64,) LINKFLAGS += -T arch/mips64/ld.script.elf32 endif # @@ -214,17 +342,27 @@ # ELF files from 32-bit files by conversion. # ifdef CONFIG_BOOT_ELF64 -GCCFLAGS += -Wa,-32 +GCCFLAGS += -Wa,-32 $(call check_gas,-Wa$(comma)-mgp64,) 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 +374,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=0xc000000080000000 $< $@ 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 +397,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 \ Index: arch/mips64/defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/defconfig 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/defconfig 4 Aug 2004 01:25:55 -0000 1.2 @@ -19,17 +19,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -52,20 +66,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 # @@ -86,7 +104,10 @@ # CONFIG_CPU_R8000 is not set CONFIG_CPU_R10000=y # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +CONFIG_SMP=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -99,12 +120,10 @@ # # 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 # 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 @@ -119,9 +138,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -148,6 +169,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set @@ -225,7 +247,6 @@ # 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 # @@ -261,12 +282,14 @@ # 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 # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -297,16 +320,16 @@ # 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 # -# I2O device support +# Fusion MPT 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_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set # # Network device support @@ -351,6 +374,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 @@ -397,6 +421,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -433,13 +458,23 @@ # 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 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 @@ -449,12 +484,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # 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 is not set # CONFIG_REISERFS_FS is not set @@ -464,11 +504,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 @@ -505,6 +546,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -513,6 +559,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 @@ -570,6 +617,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -578,13 +630,22 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set +CONFIG_NR_CPUS=64 +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips64/defconfig-atlas =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/defconfig-atlas,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/defconfig-atlas 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/defconfig-atlas 4 Aug 2004 01:25:55 -0000 1.2 @@ -19,17 +19,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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 +48,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,21 +60,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 # @@ -81,8 +101,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -95,11 +118,9 @@ # # 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 -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -114,9 +135,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -143,6 +166,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set @@ -187,6 +211,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -232,7 +262,6 @@ # 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 # @@ -269,12 +298,14 @@ # 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_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -305,17 +336,22 @@ # 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 +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) # -# 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_IEEE1394 is not set # # Network device support @@ -360,6 +396,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,6 +446,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -445,13 +483,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 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 @@ -461,12 +508,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # 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 is not set # CONFIG_REISERFS_FS is not set @@ -476,6 +528,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 @@ -517,6 +570,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -525,6 +583,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 @@ -567,6 +626,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -575,14 +639,22 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips64/defconfig-ip22 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/defconfig-ip22,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/defconfig-ip22 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/defconfig-ip22 4 Aug 2004 01:25:55 -0000 1.2 @@ -21,17 +21,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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 +50,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,28 +62,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 # @@ -90,8 +104,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -104,13 +121,11 @@ # # 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 +# CONFIG_EISA is not set # 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 @@ -125,9 +140,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -154,6 +171,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set @@ -198,6 +216,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -243,7 +267,6 @@ # 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 # @@ -282,12 +305,14 @@ # 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_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set @@ -310,9 +335,19 @@ # 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 # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# # Network device support # CONFIG_NETDEVICES=y @@ -354,6 +389,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 @@ -403,6 +439,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -411,7 +448,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 @@ -424,7 +484,11 @@ # Mice # # CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE 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 @@ -439,6 +503,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 +516,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,15 +527,21 @@ # 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=y +# CONFIG_INDYDOG is not set # CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200 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_DS1286=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -475,19 +551,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set -# CONFIG_DRM is not set # -# SGI Character devices +# Direct Rendering Manager (XFree86 DRI support) # -CONFIG_SGI_NEWPORT_CONSOLE=y -CONFIG_FONT_8x16=y -CONFIG_DUMMY_CONSOLE=y +# 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 @@ -497,11 +571,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 @@ -532,12 +607,17 @@ # 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 # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -546,6 +626,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 @@ -595,6 +676,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,20 +689,43 @@ # # Sound # -# CONFIG_SOUND 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 +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # -# SGI devices +# USB support # -CONFIG_SGI_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set -CONFIG_SGI_DS1286=y -# CONFIG_SGI_NEWPORT_GFX is not set +# CONFIG_USB is not set # -# USB support +# Support for USB gadgets # -# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set # # Bluetooth support @@ -629,12 +736,22 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips64/defconfig-ip27 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/defconfig-ip27,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/defconfig-ip27 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/defconfig-ip27 4 Aug 2004 01:25:55 -0000 1.2 @@ -19,17 +19,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -52,20 +66,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 # @@ -86,7 +104,10 @@ # CONFIG_CPU_R8000 is not set CONFIG_CPU_R10000=y # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +CONFIG_SMP=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -99,12 +120,10 @@ # # 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 # 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 @@ -119,9 +138,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -148,6 +169,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set @@ -225,7 +247,6 @@ # 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 # @@ -261,12 +282,14 @@ # 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 # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -297,16 +320,16 @@ # 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 # -# I2O device support +# Fusion MPT 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_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set # # Network device support @@ -351,6 +374,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 @@ -397,6 +421,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -433,13 +458,23 @@ # 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 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 @@ -449,12 +484,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # 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 is not set # CONFIG_REISERFS_FS is not set @@ -464,11 +504,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 @@ -505,6 +546,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -513,6 +559,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 @@ -570,6 +617,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -578,13 +630,22 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set +CONFIG_NR_CPUS=64 +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips64/defconfig-ip32 =================================================================== RCS file: arch/mips64/defconfig-ip32 diff -N arch/mips64/defconfig-ip32 --- arch/mips64/defconfig-ip32 22 Jul 2004 19:49:22 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: arch/mips64/defconfig-malta =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/defconfig-malta,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/defconfig-malta 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/defconfig-malta 4 Aug 2004 01:25:55 -0000 1.2 @@ -13,23 +13,36 @@ # # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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 +50,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,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 @@ -57,11 +76,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 @@ -84,7 +106,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -99,7 +125,6 @@ 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 @@ -114,9 +139,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -143,6 +170,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set @@ -176,8 +204,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 @@ -186,6 +214,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -231,7 +265,6 @@ # 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 # @@ -268,12 +301,14 @@ # 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_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -304,17 +339,22 @@ # 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 +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) # -# 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_IEEE1394 is not set # # Network device support @@ -359,6 +399,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 @@ -408,6 +449,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -444,13 +486,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 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 @@ -460,12 +511,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # 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 is not set # CONFIG_REISERFS_FS is not set @@ -475,6 +531,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 @@ -516,6 +573,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -523,13 +585,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 @@ -566,6 +630,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -574,14 +643,22 @@ # 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips64/defconfig-sb1250-swarm =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/defconfig-sb1250-swarm,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/defconfig-sb1250-swarm 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/defconfig-sb1250-swarm 4 Aug 2004 01:25:55 -0000 1.2 @@ -21,17 +21,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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 +50,9 @@ # 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,27 +62,45 @@ # 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_BW_TRACE 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 @@ -90,15 +122,15 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 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_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB 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,11 +144,9 @@ # # 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 -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -130,10 +160,12 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -160,6 +192,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set @@ -183,8 +216,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 @@ -199,6 +233,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -244,7 +284,6 @@ # 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 # @@ -253,6 +292,15 @@ # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# # Network device support # CONFIG_NETDEVICES=y @@ -294,6 +342,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 @@ -343,6 +392,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -370,12 +420,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 +453,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 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 @@ -419,12 +478,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # 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 @@ -434,6 +498,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 @@ -475,6 +540,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -483,6 +553,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 @@ -526,6 +597,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -534,11 +610,23 @@ # 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_DEBUG_INFO is not set +# CONFIG_SB1XXX_CORELIS is not set # CONFIG_MAGIC_SYSRQ is not set +CONFIG_NR_CPUS=64 +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips64/defconfig-sead =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/defconfig-sead,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/defconfig-sead 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/defconfig-sead 4 Aug 2004 01:25:55 -0000 1.2 @@ -19,17 +19,28 @@ # 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_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 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,9 @@ 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_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,16 +60,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 @@ -79,7 +96,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -94,7 +115,6 @@ # CONFIG_NET is not set # 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 @@ -109,9 +129,11 @@ # 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 +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -138,6 +160,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y @@ -175,7 +198,6 @@ # 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 # @@ -184,6 +206,15 @@ # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# # Amateur Radio support # # CONFIG_HAMRADIO is not set @@ -196,6 +227,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -231,13 +263,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 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 @@ -247,12 +288,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # 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 @@ -262,6 +308,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 @@ -303,6 +350,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # CONFIG_NCPFS_NLS is not set # CONFIG_SMB_FS is not set # CONFIG_ZISOFS_FS is not set @@ -345,17 +397,30 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET 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_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 Index: arch/mips64/ld.script.elf32.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/ld.script.elf32.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/ld.script.elf32.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/ld.script.elf32.S 4 Aug 2004 01:25:55 -0000 1.2 @@ -50,9 +50,6 @@ . = ALIGN(4096); /* Align double page for init_task_union */ __init_end = .; - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - . = ALIGN(32); .data.cacheline_aligned : { *(.data.cacheline_aligned) } @@ -77,6 +74,14 @@ { _fdata = . ; *(.data) + + /* Align the initial ramdisk image (INITRD) on page boundaries. */ + . = ALIGN(4096); + __rd_start = .; + *(.initrd) + . = ALIGN(4096); + __rd_end = .; + CONSTRUCTORS } .data1 : { *(.data1) } Index: arch/mips64/ld.script.elf64 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/ld.script.elf64,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/ld.script.elf64 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/ld.script.elf64 4 Aug 2004 01:25:55 -0000 1.2 @@ -59,9 +59,6 @@ . = ALIGN(4096); /* Align double page for init_task_union */ __init_end = .; - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - . = ALIGN(32); .data.cacheline_aligned : { *(.data.cacheline_aligned) } @@ -86,6 +83,14 @@ { _fdata = . ; *(.data) + + /* Align the initial ramdisk image (INITRD) on page boundaries. */ + . = ALIGN(4096); + __rd_start = .; + *(.initrd) + . = ALIGN(4096); + __rd_end = .; + CONSTRUCTORS } .data1 : { *(.data1) } Index: arch/mips64/boot/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/boot/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/boot/Makefile 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/boot/Makefile 4 Aug 2004 01:25:55 -0000 1.2 @@ -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: Index: arch/mips64/kernel/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/Makefile 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/Makefile 4 Aug 2004 01:25:55 -0000 1.2 @@ -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 semaphore.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 Index: arch/mips64/kernel/binfmt_elf32.c =================================================================== RCS file: arch/mips64/kernel/binfmt_elf32.c diff -N arch/mips64/kernel/binfmt_elf32.c --- arch/mips64/kernel/binfmt_elf32.c 22 Jul 2004 19:49:23 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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" Index: arch/mips64/kernel/branch.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/branch.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/branch.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/branch.c 4 Aug 2004 01:25:55 -0000 1.2 @@ -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; Index: arch/mips64/kernel/cpu-probe.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/cpu-probe.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/cpu-probe.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/cpu-probe.c 4 Aug 2004 01:25:55 -0000 1.2 @@ -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; @@ -74,6 +98,8 @@ case CPU_4KSC: case CPU_5KC: /* case CPU_20KC:*/ + case CPU_24K: + case CPU_25KF: cpu_wait = r4k_wait; printk(" available.\n"); break; @@ -89,9 +115,298 @@ } } +static inline void align_mod(const int align, const int mod) +{ + asm volatile( + ".set push\n\t" + ".set noreorder\n\t" + ".balign %0\n\t" + ".rept %1\n\t" + "nop\n\t" + ".endr\n\t" + ".set pop" + : + : "n" (align), "n" (mod)); +} + +static inline void mult_sh_align_mod(long *v1, long *v2, long *w, + const int align, const int mod) +{ + unsigned long flags; + int m1, m2; + long p, s, lv1, lv2, lw; + + /* + * 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 lv2 and p are + * used for. + */ + + local_irq_save(flags); + /* + * The following code leads to a wrong result of the first + * dsll32 when executed on R4000 rev. 2.2 or 3.0 (PRId + * 00000422 or 00000430, respectively). + * + * 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( + "" + : "=r" (m1), "=r" (m2), "=r" (s) + : "0" (5), "1" (8), "2" (5)); + align_mod(align, mod); + /* + * The trailing nop is needed to fullfill the two-instruction + * requirement between reading hi/lo and staring a mult/div. + * Leaving it out may cause gas insert a nop itself breaking + * the desired alignment of the next chunk. + */ + asm volatile( + ".set push\n\t" + ".set noat\n\t" + ".set noreorder\n\t" + ".set nomacro\n\t" + "mult %2, %3\n\t" + "dsll32 %0, %4, %5\n\t" + "mflo $0\n\t" + "dsll32 %1, %4, %5\n\t" + "nop\n\t" + ".set pop" + : "=&r" (lv1), "=r" (lw) + : "r" (m1), "r" (m2), "r" (s), "I" (0) + : "hi", "lo", "accum"); + /* 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 umulsi3 and mulsi3, but other + * multiplication variants lack the workaround. + */ + asm volatile( + "" + : "=r" (m1), "=r" (m2), "=r" (s) + : "0" (m1), "1" (m2), "2" (s)); + align_mod(align, mod); + p = m1 * m2; + lv2 = s << 32; + asm volatile( + "" + : "=r" (lv2) + : "0" (lv2), "r" (p)); + local_irq_restore(flags); + + *v1 = lv1; + *v2 = lv2; + *w = lw; +} + +static inline void check_mult_sh(void) +{ + long v1[8], v2[8], w[8]; + int bug, fix, i; + + printk("Checking for the multiply/shift bug... "); + + /* + * Testing discovered false negatives for certain code offsets + * into cache lines. Hence we test all possible offsets for + * the worst assumption of an R4000 I-cache line width of 32 + * bytes. + * + * We can't use a loop as alignment directives need to be + * immediates. + */ + mult_sh_align_mod(&v1[0], &v2[0], &w[0], 32, 0); + mult_sh_align_mod(&v1[1], &v2[1], &w[1], 32, 1); + mult_sh_align_mod(&v1[2], &v2[2], &w[2], 32, 2); + mult_sh_align_mod(&v1[3], &v2[3], &w[3], 32, 3); + mult_sh_align_mod(&v1[4], &v2[4], &w[4], 32, 4); + mult_sh_align_mod(&v1[5], &v2[5], &w[5], 32, 5); + mult_sh_align_mod(&v1[6], &v2[6], &w[6], 32, 6); + mult_sh_align_mod(&v1[7], &v2[7], &w[7], 32, 7); + + bug = 0; + for (i = 0; i < 8; i++) + if (v1[i] != w[i]) + bug = 1; + + if (bug == 0) { + printk("no.\n"); + return; + } + + printk("yes, workaround... "); + + fix = 1; + for (i = 0; i < 8; i++) + if (v2[i] != w[i]) + fix = 0; + + if (fix == 1) { + 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 (PRId 00000422 or + * 00000430, respectively). + * + * 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 (PRId 00000440). + * + * 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 (PRId 00000422 and + * 00000430, respectively), 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 +419,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,367 +438,437 @@ { 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) + | MIPS_CPU_COUNTER) -__init void cpu_probe(void) +static inline void cpu_probe_legacy(struct cpuinfo_mips *c) { -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) - unsigned long config0 = read_32bit_cp0_register(CP0_CONFIG); - unsigned long config1; - - 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(); - if (config1 & (1 << 3)) - mips_cpu.options |= MIPS_CPU_WATCH; - if (config1 & (1 << 2)) - mips_cpu.options |= MIPS_CPU_MIPS16; - if (config1 & (1 << 1)) - mips_cpu.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 - } - mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT; - } -#endif - mips_cpu.processor_id = read_32bit_cp0_register(CP0_PRID); - switch (mips_cpu.processor_id & 0xff0000) { - case PRID_COMP_LEGACY: - switch (mips_cpu.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; - break; - case PRID_IMP_R3000: - if ((mips_cpu.processor_id & 0xff) == PRID_REV_R3000A) - if (cpu_has_confreg()) - mips_cpu.cputype = CPU_R3081E; - else - mips_cpu.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; - break; - case PRID_IMP_R4000: - if ((mips_cpu.processor_id & 0xff) == PRID_REV_R4400) - mips_cpu.cputype = CPU_R4400SC; + switch (c->processor_id & 0xff00) { + case PRID_IMP_R2000: + 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 ((c->processor_id & 0xff) == PRID_REV_R3000A) + if (cpu_has_confreg()) + c->cputype = CPU_R3081E; 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; - break; - case PRID_IMP_VR41XX: - switch (mips_cpu.processor_id & 0xf0) { + c->cputype = CPU_R3000A; + else + 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 ((c->processor_id & 0xff) >= PRID_REV_R4400) + c->cputype = CPU_R4400SC; + else + 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 (c->processor_id & 0xf0) { #ifndef CONFIG_VR4181 - case PRID_REV_VR4111: - mips_cpu.cputype = CPU_VR4111; - break; -#else - case PRID_REV_VR4181: - mips_cpu.cputype = CPU_VR4181; - break; -#endif - case PRID_REV_VR4121: - mips_cpu.cputype = CPU_VR4121; - break; - case PRID_REV_VR4122: - if ((mips_cpu.processor_id & 0xf) < 0x3) - mips_cpu.cputype = CPU_VR4122; - else - mips_cpu.cputype = CPU_VR4181A; - break; - case PRID_REV_VR4131: - mips_cpu.cputype = CPU_VR4131; - mips_cpu.icache.ways = 2; - mips_cpu.dcache.ways = 2; - break; - default: - printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); - mips_cpu.cputype = CPU_VR41XX; - break; - } - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS; - mips_cpu.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; - 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; - break; - #if 0 - case PRID_IMP_R4650: - /* - * This processor doesn't have an MMU, so it's not - * "real easy" to run Linux on it. It is left purely - * 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; - break; - #endif - case PRID_IMP_TX39: - mips_cpu.isa_level = MIPS_CPU_ISA_I; - mips_cpu.options = MIPS_CPU_TLB; - - if ((mips_cpu.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; - } else { - switch (mips_cpu.processor_id & 0xff) { - case PRID_REV_TX3912: - mips_cpu.cputype = CPU_TX3912; - mips_cpu.tlbsize = 32; - break; - case PRID_REV_TX3922: - mips_cpu.cputype = CPU_TX3922; - mips_cpu.tlbsize = 64; - break; - default: - mips_cpu.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; - 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; - 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; - 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; - 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; - 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; + case PRID_REV_VR4111: + c->cputype = CPU_VR4111; 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; - 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; - 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; - /* - * Undocumented RM7000: Bit 29 in the info register of - * the RM7000 v2.0 indicates if the TLB has 48 or 64 - * entries. - * - * 29 1 => 64 entry JTLB - * 0 => 48 entry JTLB - */ - mips_cpu.tlbsize = (get_info() & (1 << 29)) ? 64 : 48; +#else + case PRID_REV_VR4181: + c->cputype = CPU_VR4181; 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 */ +#endif + case PRID_REV_VR4121: + c->cputype = CPU_VR4121; 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; + case PRID_REV_VR4122: + if ((c->processor_id & 0xf) < 0x3) + c->cputype = CPU_VR4122; + else + c->cputype = CPU_VR4181A; 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; + case PRID_REV_VR4130: + if ((c->processor_id & 0xf) < 0x4) + c->cputype = CPU_VR4131; + else + c->cputype = CPU_VR4133; break; default: - mips_cpu.cputype = CPU_UNKNOWN; + printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); + c->cputype = CPU_VR41XX; break; } + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS; + c->tlbsize = 32; break; -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) - case PRID_COMP_MIPS: - switch (mips_cpu.processor_id & 0xff00) { - case PRID_IMP_4KC: - mips_cpu.cputype = CPU_4KC; - mips_cpu.isa_level = MIPS_CPU_ISA_M32; - break; - case PRID_IMP_4KEC: - mips_cpu.cputype = CPU_4KEC; - mips_cpu.isa_level = MIPS_CPU_ISA_M32; - break; - case PRID_IMP_4KSC: - mips_cpu.cputype = CPU_4KSC; - mips_cpu.isa_level = MIPS_CPU_ISA_M32; - break; - case PRID_IMP_5KC: - mips_cpu.cputype = CPU_5KC; - mips_cpu.isa_level = MIPS_CPU_ISA_M64; - break; - case PRID_IMP_20KC: - mips_cpu.cputype = CPU_20KC; - mips_cpu.isa_level = MIPS_CPU_ISA_M64; - break; - default: - mips_cpu.cputype = CPU_UNKNOWN; - break; - } + case PRID_IMP_R4300: + 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_COMP_ALCHEMY: - switch (mips_cpu.processor_id & 0xff00) { - case PRID_IMP_AU1_REV1: - case PRID_IMP_AU1_REV2: - switch ((mips_cpu.processor_id >> 24) & 0xff) { - case 0: - mips_cpu.cputype = CPU_AU1000; - break; - case 1: - mips_cpu.cputype = CPU_AU1500; + case PRID_IMP_R4600: + 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: + /* + * This processor doesn't have an MMU, so it's not + * "real easy" to run Linux on it. It is left purely + * for documentation. Commented out because it shares + * it's c0_prid id number with the TX3900. + */ + 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: + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB; + + if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) { + c->cputype = CPU_TX3927; + c->tlbsize = 64; + } else { + switch (c->processor_id & 0xff) { + case PRID_REV_TX3912: + c->cputype = CPU_TX3912; + c->tlbsize = 32; break; - case 2: - mips_cpu.cputype = CPU_AU1100; + case PRID_REV_TX3922: + c->cputype = CPU_TX3922; + c->tlbsize = 64; break; default: - panic("Unknown Au Core!"); + c->cputype = CPU_UNKNOWN; break; } - mips_cpu.isa_level = MIPS_CPU_ISA_M32; - break; - default: - mips_cpu.cputype = CPU_UNKNOWN; - break; } break; -#endif /* CONFIG_CPU_MIPS32 */ - case PRID_COMP_SIBYTE: - switch (mips_cpu.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; -#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS - /* FPU in pass1 is known to have issues. */ - mips_cpu.options |= MIPS_CPU_FPU; -#endif + case PRID_IMP_R4700: + 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: + c->cputype = CPU_TX49XX; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_LLSC; + if (!(c->processor_id & 0x08)) + c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; + c->tlbsize = 48; + break; + case PRID_IMP_R5000: + 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: + 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: + 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: + 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: + 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: + 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: + 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 + * entries. + * + * 29 1 => 64 entry JTLB + * 0 => 48 entry JTLB + */ + c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; + break; + case PRID_IMP_RM9000: + c->cputype = CPU_RM9000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + /* + * Bit 29 in the info register of the RM9000 + * indicates if the TLB has 48 or 64 entries. + * + * 29 1 => 64 entry JTLB + * 0 => 48 entry JTLB + */ + c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; + break; + case PRID_IMP_R8000: + 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: + 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: + 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: + c->cputype = CPU_UNKNOWN; + break; + } +} + +static inline void decode_config1(struct cpuinfo_mips *c) +{ + unsigned long config0 = read_c0_config(); + unsigned long config1; + + if ((config0 & (1 << 31)) == 0) + return; /* actually wort a panic() */ + + /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */ + 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)) + c->options |= MIPS_CPU_WATCH; + if (config1 & (1 << 2)) + c->options |= MIPS_CPU_MIPS16; + if (config1 & (1 << 1)) + c->options |= MIPS_CPU_EJTAG; + if (config1 & 1) { + c->options |= MIPS_CPU_FPU; + c->options |= MIPS_CPU_32FPR; + } + c->scache.flags = MIPS_CACHE_NOT_PRESENT; + + c->tlbsize = ((config1 >> 25) & 0x3f) + 1; +} + +static inline void cpu_probe_mips(struct cpuinfo_mips *c) +{ + decode_config1(c); + switch (c->processor_id & 0xff00) { + case PRID_IMP_4KC: + c->cputype = CPU_4KC; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_4KEC: + c->cputype = CPU_4KEC; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_4KSC: + c->cputype = CPU_4KSC; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_5KC: + c->cputype = CPU_5KC; + c->isa_level = MIPS_CPU_ISA_M64; + break; + case PRID_IMP_20KC: + c->cputype = CPU_20KC; + c->isa_level = MIPS_CPU_ISA_M64; + break; + case PRID_IMP_24K: + c->cputype = CPU_24K; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_25KF: + c->cputype = CPU_25KF; + c->isa_level = MIPS_CPU_ISA_M64; + /* Probe for L2 cache */ + c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } +} + +static inline void cpu_probe_alchemy(struct cpuinfo_mips *c) +{ + decode_config1(c); + switch (c->processor_id & 0xff00) { + case PRID_IMP_AU1_REV1: + case PRID_IMP_AU1_REV2: + switch ((c->processor_id >> 24) & 0xff) { + case 0: + c->cputype = CPU_AU1000; + break; + case 1: + c->cputype = CPU_AU1500; + break; + case 2: + c->cputype = CPU_AU1100; break; default: - mips_cpu.cputype = CPU_UNKNOWN; + panic("Unknown Au Core!"); break; } + c->isa_level = MIPS_CPU_ISA_M32; + break; + } +} + +static inline void cpu_probe_sibyte(struct cpuinfo_mips *c) +{ + decode_config1(c); + switch (c->processor_id & 0xff00) { + case PRID_IMP_SB1: + 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. */ + c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; +#endif + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } +} + +static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c) +{ + decode_config1(c); + 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; + } +} + +__init void cpu_probe(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + + c->processor_id = PRID_IMP_UNKNOWN; + c->fpu_id = FPIR_IMP_NONE; + c->cputype = CPU_UNKNOWN; + + c->processor_id = read_c0_prid(); + switch (c->processor_id & 0xff0000) { + case PRID_COMP_LEGACY: + cpu_probe_legacy(c); + break; + case PRID_COMP_MIPS: + cpu_probe_mips(c); + break; + case PRID_COMP_ALCHEMY: + cpu_probe_alchemy(c); + break; + case PRID_COMP_SIBYTE: + cpu_probe_sibyte(c); + break; + + case PRID_COMP_SANDCRAFT: + cpu_probe_sandcraft(c); 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); } Index: arch/mips64/kernel/entry.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/entry.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/entry.S 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/entry.S 4 Aug 2004 01:25:55 -0000 1.2 @@ -18,7 +18,7 @@ #define KU_USER 0x10 .text - .align 4 + .align 5 FEXPORT(ret_from_fork) move a0, v0 # prev jal schedule_tail Index: arch/mips64/kernel/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/head.S 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/head.S 4 Aug 2004 01:25:55 -0000 1.2 @@ -105,11 +105,8 @@ CLI # disable interrupts - PTR_LA $28, init_task_union # init current pointer - daddiu sp, $28, KERNEL_STACK_SIZE-32 - set_saved_sp sp, t0 - - /* The firmware/bootloader passes argc/argp/envp + /* + * The firmware/bootloader passes argc/argp/envp * to us as arguments. But clear bss first because * the romvec and other important info is stored there * by prom_init(). @@ -122,6 +119,9 @@ sd zero, (t0) bne t0, t1, 1b + PTR_LA $28, init_task_union # init current pointer + daddiu sp, $28, KERNEL_STACK_SIZE-32 + set_saved_sp sp, t0, t1 dsubu sp, 4*SZREG # init stack pointer j init_arch @@ -135,7 +135,7 @@ NESTED(smp_bootstrap, 16, sp) #ifdef CONFIG_SGI_IP27 GET_NASID_ASM t1 - li t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \ + dli t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \ KLDIR_OFF_POINTER + K0BASE dsll t1, NASID_SHFT or t0, t0, t1 @@ -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,22 +166,19 @@ 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 .data .align 12 - page swapper_pg_dir, 1 - page invalid_pte_table, 0 - page invalid_pmd_table, 1 + page swapper_pg_dir, _PGD_ORDER + page invalid_pmd_table, _PMD_ORDER + page invalid_pte_table, _PTE_ORDER page kptbl, _PGD_ORDER .globl ekptbl page kpmdtbl, 0 Index: arch/mips64/kernel/i8259.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/i8259.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/i8259.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/i8259.c 4 Aug 2004 01:25:55 -0000 1.2 @@ -15,6 +15,7 @@ #include #include +#include #include void enable_8259A_irq(unsigned int irq); Index: arch/mips64/kernel/ioctl32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/ioctl32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/ioctl32.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/ioctl32.c 4 Aug 2004 01:25:55 -0000 1.2 @@ -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, 2003 Maciej W. Rozycki * * Mostly stolen from the sparc64 ioctl32 implementation. */ @@ -11,37 +12,60 @@ #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 +#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) +#include +#endif /* LVM */ #include #undef __KERNEL__ /* This file was born to be ugly ... */ #include #define __KERNEL__ +#include + #include #include +#include -#include +#include +#include + +#ifdef CONFIG_SIBYTE_TBPROF +#include +#endif long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); @@ -77,6 +101,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; @@ -177,7 +361,7 @@ struct ifreq32 *ifr32; struct ifreq *ifr; mm_segment_t old_fs; - int len; + unsigned int i, j; int err; if (copy_from_user(&ifc32, uifc32, sizeof(struct ifconf32))) @@ -196,16 +380,14 @@ } ifr = ifc.ifc_req; ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf); - len = ifc32.ifc_len / sizeof (struct ifreq32); - while (len--) { + for (i = 0; i < ifc32.ifc_len; i += sizeof (struct ifreq32)) { if (copy_from_user(ifr++, ifr32++, sizeof (struct ifreq32))) { - err = -EFAULT; - goto out; + kfree (ifc.ifc_buf); + return -EFAULT; } } - old_fs = get_fs(); - set_fs (KERNEL_DS); + old_fs = get_fs(); set_fs (KERNEL_DS); err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc); set_fs (old_fs); if (err) @@ -213,16 +395,26 @@ ifr = ifc.ifc_req; ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf); - len = ifc.ifc_len / sizeof (struct ifreq); - ifc32.ifc_len = len * sizeof (struct ifreq32); - - while (len--) { + for (i = 0, j = 0; i < ifc32.ifc_len && j < ifc.ifc_len; + i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) { if (copy_to_user(ifr32++, ifr++, sizeof (struct ifreq32))) { err = -EFAULT; goto out; } } - + if (ifc32.ifcbuf == 0) { + /* Translate from 64-bit structure multiple to + * a 32-bit one. + */ + i = ifc.ifc_len; + i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32)); + ifc32.ifc_len = i; + } else { + if (i <= ifc32.ifc_len) + ifc32.ifc_len = i; + else + ifc32.ifc_len = i - sizeof (struct ifreq32); + } if (copy_to_user(uifc32, &ifc32, sizeof(struct ifconf32))) { err = -EFAULT; goto out; @@ -355,6 +547,246 @@ return sys_ioctl(fd, cmd, arg); } +struct video_tuner32 { + s32 tuner; + u8 name[32]; + u32 rangelow, rangehigh; + u32 flags; + u16 mode, signal; +}; + +static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 *up) +{ + int i; + + if(get_user(kp->tuner, &up->tuner)) + return -EFAULT; + for(i = 0; i < 32; i++) + __get_user(kp->name[i], &up->name[i]); + __get_user(kp->rangelow, &up->rangelow); + __get_user(kp->rangehigh, &up->rangehigh); + __get_user(kp->flags, &up->flags); + __get_user(kp->mode, &up->mode); + __get_user(kp->signal, &up->signal); + return 0; +} + +static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 *up) +{ + int i; + + if(put_user(kp->tuner, &up->tuner)) + return -EFAULT; + for(i = 0; i < 32; i++) + __put_user(kp->name[i], &up->name[i]); + __put_user(kp->rangelow, &up->rangelow); + __put_user(kp->rangehigh, &up->rangehigh); + __put_user(kp->flags, &up->flags); + __put_user(kp->mode, &up->mode); + __put_user(kp->signal, &up->signal); + return 0; +} + +struct video_buffer32 { + /* void * */ u32 base; + s32 height, width, depth, bytesperline; +}; + +static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 *up) +{ + u32 tmp; + + if(get_user(tmp, &up->base)) + return -EFAULT; + kp->base = (void *) ((unsigned long)tmp); + __get_user(kp->height, &up->height); + __get_user(kp->width, &up->width); + __get_user(kp->depth, &up->depth); + __get_user(kp->bytesperline, &up->bytesperline); + return 0; +} + +static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 *up) +{ + u32 tmp = (u32)((unsigned long)kp->base); + + if(put_user(tmp, &up->base)) + return -EFAULT; + __put_user(kp->height, &up->height); + __put_user(kp->width, &up->width); + __put_user(kp->depth, &up->depth); + __put_user(kp->bytesperline, &up->bytesperline); + return 0; +} + +struct video_clip32 { + s32 x, y, width, height; + /* struct video_clip32 * */ u32 next; +}; + +struct video_window32 { + u32 x, y, width, height, chromakey, flags; + /* struct video_clip32 * */ u32 clips; + s32 clipcount; +}; + +static void free_kvideo_clips(struct video_window *kp) +{ + struct video_clip *cp; + + cp = kp->clips; + if(cp != NULL) + kfree(cp); +} + +static int get_video_window32(struct video_window *kp, struct video_window32 *up) +{ + struct video_clip32 *ucp; + struct video_clip *kcp; + int nclips, err, i; + u32 tmp; + + if(get_user(kp->x, &up->x)) + return -EFAULT; + __get_user(kp->y, &up->y); + __get_user(kp->width, &up->width); + __get_user(kp->height, &up->height); + __get_user(kp->chromakey, &up->chromakey); + __get_user(kp->flags, &up->flags); + __get_user(kp->clipcount, &up->clipcount); + __get_user(tmp, &up->clips); + ucp = (struct video_clip32 *)A(tmp); + kp->clips = NULL; + + nclips = kp->clipcount; + if(nclips == 0) + return 0; + + if(ucp == 0) + return -EINVAL; + + /* Peculiar interface... */ + if(nclips < 0) + nclips = VIDEO_CLIPMAP_SIZE; + + kcp = kmalloc(nclips * sizeof(struct video_clip), GFP_KERNEL); + err = -ENOMEM; + if(kcp == NULL) + goto cleanup_and_err; + + kp->clips = kcp; + for(i = 0; i < nclips; i++) { + __get_user(kcp[i].x, &ucp[i].x); + __get_user(kcp[i].y, &ucp[i].y); + __get_user(kcp[i].width, &ucp[i].width); + __get_user(kcp[i].height, &ucp[i].height); + kcp[nclips].next = NULL; + } + + return 0; + +cleanup_and_err: + free_kvideo_clips(kp); + return err; +} + +/* You get back everything except the clips... */ +static int put_video_window32(struct video_window *kp, struct video_window32 *up) +{ + if(put_user(kp->x, &up->x)) + return -EFAULT; + __put_user(kp->y, &up->y); + __put_user(kp->width, &up->width); + __put_user(kp->height, &up->height); + __put_user(kp->chromakey, &up->chromakey); + __put_user(kp->flags, &up->flags); + __put_user(kp->clipcount, &up->clipcount); + return 0; +} + +#define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32) +#define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32) +#define VIDIOCGWIN32 _IOR('v',9, struct video_window32) +#define VIDIOCSWIN32 _IOW('v',10, struct video_window32) +#define VIDIOCGFBUF32 _IOR('v',11, struct video_buffer32) +#define VIDIOCSFBUF32 _IOW('v',12, struct video_buffer32) +#define VIDIOCGFREQ32 _IOR('v',14, u32) +#define VIDIOCSFREQ32 _IOW('v',15, u32) + +static int do_video_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + union { + struct video_tuner vt; + struct video_buffer vb; + struct video_window vw; + unsigned long vx; + } karg; + mm_segment_t old_fs = get_fs(); + void *up = (void *)arg; + int err = 0; + + /* First, convert the command. */ + switch(cmd) { + case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break; + case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break; + case VIDIOCGWIN32: cmd = VIDIOCGWIN; break; + case VIDIOCSWIN32: cmd = VIDIOCSWIN; break; + case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break; + case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break; + case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break; + case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break; + }; + + switch(cmd) { + case VIDIOCSTUNER: + case VIDIOCGTUNER: + err = get_video_tuner32(&karg.vt, up); + break; + + case VIDIOCSWIN: + err = get_video_window32(&karg.vw, up); + break; + + case VIDIOCSFBUF: + err = get_video_buffer32(&karg.vb, up); + break; + + case VIDIOCSFREQ: + err = get_user(karg.vx, (u32 *)up); + break; + }; + if(err) + goto out; + + set_fs(KERNEL_DS); + err = sys_ioctl(fd, cmd, (unsigned long)&karg); + set_fs(old_fs); + + if(cmd == VIDIOCSWIN) + free_kvideo_clips(&karg.vw); + + if(err == 0) { + switch(cmd) { + case VIDIOCGTUNER: + err = put_video_tuner32(&karg.vt, up); + break; + + case VIDIOCGWIN: + err = put_video_window32(&karg.vw, up); + break; + + case VIDIOCGFBUF: + err = put_video_buffer32(&karg.vb, up); + break; + + case VIDIOCGFREQ: + err = put_user(((u32)karg.vx), (u32 *)up); + break; + }; + } +out: + return err; +} struct hd_geometry32 { unsigned char heads; unsigned char sectors; @@ -404,6 +836,12 @@ return -EINVAL; } +static int broken_blkgetsize(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + /* The mkswap binary hard codes it to Intel value :-((( */ + return w_long(fd, BLKGETSIZE, arg); +} + struct blkpg_ioctl_arg32 { int op; int flags; @@ -441,6 +879,39 @@ return err; } +/* Fix sizeof(sizeof()) breakage */ +#define BLKELVGET_32 _IOR(0x12,106,int) +#define BLKELVSET_32 _IOW(0x12,107,int) +#define BLKBSZGET_32 _IOR(0x12,112,int) +#define BLKBSZSET_32 _IOW(0x12,113,int) +#define BLKGETSIZE64_32 _IOR(0x12,114,int) + +static int do_blkelvget(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + return sys_ioctl(fd, BLKELVGET, arg); +} + +static int do_blkelvset(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + return sys_ioctl(fd, BLKELVSET, arg); +} + +static int do_blkbszget(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + return sys_ioctl(fd, BLKBSZGET, arg); +} + +static int do_blkbszset(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + return sys_ioctl(fd, BLKBSZSET, arg); +} + +static int do_blkgetsize64(unsigned int fd, unsigned int cmd, + unsigned long arg) +{ + return sys_ioctl(fd, BLKGETSIZE64, arg); +} + struct mtget32 { __u32 mt_type; __u32 mt_resid; @@ -571,6 +1042,679 @@ 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; +} + +#ifdef CONFIG_VT + +extern int tty_ioctl(struct inode * inode, struct file * file, + unsigned int cmd, unsigned long arg); + +static int vt_check(struct file *file) +{ + struct tty_struct *tty; + struct inode *inode = file->f_dentry->d_inode; + + if (file->f_op->ioctl != tty_ioctl) + return -EINVAL; + + tty = (struct tty_struct *)file->private_data; + if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl")) + return -EINVAL; + + if (tty->driver.ioctl != vt_ioctl) + return -EINVAL; + + /* + * To have permissions to do most of the vt ioctls, we either have + * to be the owner of the tty, or super-user. + */ + if (current->tty == tty || suser()) + return 1; + return 0; +} + +struct consolefontdesc32 { + unsigned short charcount; /* characters in font (256 or 512) */ + unsigned short charheight; /* scan lines per character (1-32) */ + u32 chardata; /* font data in expanded form */ +}; + +static int do_fontx_ioctl(unsigned int fd, int cmd, struct consolefontdesc32 *user_cfd, struct file *file) +{ + struct consolefontdesc cfdarg; + struct console_font_op op; + int i, perm; + + perm = vt_check(file); + if (perm < 0) return perm; + + if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc32))) + return -EFAULT; + + cfdarg.chardata = (unsigned char *)A(((struct consolefontdesc32 *)&cfdarg)->chardata); + + switch (cmd) { + case PIO_FONTX: + if (!perm) + return -EPERM; + op.op = KD_FONT_OP_SET; + op.flags = 0; + op.width = 8; + op.height = cfdarg.charheight; + op.charcount = cfdarg.charcount; + op.data = cfdarg.chardata; + return con_font_op(fg_console, &op); + case GIO_FONTX: + if (!cfdarg.chardata) + return 0; + op.op = KD_FONT_OP_GET; + op.flags = 0; + op.width = 8; + op.height = cfdarg.charheight; + op.charcount = cfdarg.charcount; + op.data = cfdarg.chardata; + i = con_font_op(fg_console, &op); + if (i) + return i; + cfdarg.charheight = op.height; + cfdarg.charcount = op.charcount; + ((struct consolefontdesc32 *)&cfdarg)->chardata = (unsigned long)cfdarg.chardata; + if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc32))) + return -EFAULT; + return 0; + } + return -EINVAL; +} + +struct console_font_op32 { + unsigned int op; /* operation code KD_FONT_OP_* */ + unsigned int flags; /* KD_FONT_FLAG_* */ + unsigned int width, height; /* font size */ + unsigned int charcount; + u32 data; /* font data with height fixed to 32 */ +}; + +static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, struct console_font_op32 *fontop, struct file *file) +{ + struct console_font_op op; + int perm = vt_check(file), i; + struct vt_struct *vt; + + if (perm < 0) return perm; + + if (copy_from_user(&op, (void *) fontop, sizeof(struct console_font_op32))) + return -EFAULT; + if (!perm && op.op != KD_FONT_OP_GET) + return -EPERM; + op.data = (unsigned char *)A(((struct console_font_op32 *)&op)->data); + op.flags |= KD_FONT_FLAG_OLD; + vt = (struct vt_struct *)((struct tty_struct *)file->private_data)->driver_data; + i = con_font_op(vt->vc_num, &op); + if (i) return i; + ((struct console_font_op32 *)&op)->data = (unsigned long)op.data; + if (copy_to_user((void *) fontop, &op, sizeof(struct console_font_op32))) + return -EFAULT; + return 0; +} + +#endif /* CONFIG_VT */ + +#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) +/* Ugh, LVM. Pitty it was not cleaned up before accepted :((. */ +typedef struct { + uint8_t vg_name[NAME_LEN]; + uint32_t vg_number; + uint32_t vg_access; + uint32_t vg_status; + uint32_t lv_max; + uint32_t lv_cur; + uint32_t lv_open; + uint32_t pv_max; + uint32_t pv_cur; + uint32_t pv_act; + uint32_t dummy; + uint32_t vgda; + uint32_t pe_size; + uint32_t pe_total; + uint32_t pe_allocated; + uint32_t pvg_total; + u32 proc; + u32 pv[ABS_MAX_PV + 1]; + u32 lv[ABS_MAX_LV + 1]; + uint8_t vg_uuid[UUID_LEN+1]; /* volume group UUID */ + uint8_t dummy1[200]; +} vg32_t; + +typedef struct { + uint8_t id[2]; + uint16_t version; + lvm_disk_data_t pv_on_disk; + lvm_disk_data_t vg_on_disk; + lvm_disk_data_t pv_namelist_on_disk; + lvm_disk_data_t lv_on_disk; + lvm_disk_data_t pe_on_disk; + uint8_t pv_name[NAME_LEN]; + uint8_t vg_name[NAME_LEN]; + uint8_t system_id[NAME_LEN]; + kdev_t pv_dev; + uint32_t pv_number; + uint32_t pv_status; + uint32_t pv_allocatable; + uint32_t pv_size; + uint32_t lv_cur; + uint32_t pe_size; + uint32_t pe_total; + uint32_t pe_allocated; + uint32_t pe_stale; + u32 pe; + u32 inode; + uint8_t pv_uuid[UUID_LEN+1]; +} pv32_t; + +typedef struct { + char lv_name[NAME_LEN]; + u32 lv; +} lv_req32_t; + +typedef struct { + u32 lv_index; + u32 lv; + /* Transfer size because user space and kernel space differ */ + uint16_t size; +} lv_status_byindex_req32_t; + +typedef struct { + __kernel_dev_t32 dev; + u32 lv; +} lv_status_bydev_req32_t; + +typedef struct { + uint8_t lv_name[NAME_LEN]; + kdev_t old_dev; + kdev_t new_dev; + u32 old_pe; + u32 new_pe; +} le_remap_req32_t; + +typedef struct { + char pv_name[NAME_LEN]; + u32 pv; +} pv_status_req32_t; + +typedef struct { + uint8_t lv_name[NAME_LEN]; + uint8_t vg_name[NAME_LEN]; + uint32_t lv_access; + uint32_t lv_status; + uint32_t lv_open; + kdev_t lv_dev; + uint32_t lv_number; + uint32_t lv_mirror_copies; + uint32_t lv_recovery; + uint32_t lv_schedule; + uint32_t lv_size; + u32 lv_current_pe; + uint32_t lv_current_le; + uint32_t lv_allocated_le; + uint32_t lv_stripes; + uint32_t lv_stripesize; + uint32_t lv_badblock; + uint32_t lv_allocation; + uint32_t lv_io_timeout; + uint32_t lv_read_ahead; + /* delta to version 1 starts here */ + u32 lv_snapshot_org; + u32 lv_snapshot_prev; + u32 lv_snapshot_next; + u32 lv_block_exception; + uint32_t lv_remap_ptr; + uint32_t lv_remap_end; + uint32_t lv_chunk_size; + uint32_t lv_snapshot_minor; + char dummy[200]; +} lv32_t; + +typedef struct { + u32 hash[2]; + u32 rsector_org; + kdev_t rdev_org; + u32 rsector_new; + kdev_t rdev_new; +} lv_block_exception32_t; + +static void put_lv_t(lv_t *l) +{ + if (l->lv_current_pe) vfree(l->lv_current_pe); + if (l->lv_block_exception) vfree(l->lv_block_exception); + kfree(l); +} + +static lv_t *get_lv_t(u32 p, int *errp) +{ + int err, i; + u32 ptr1, ptr2; + size_t size; + lv_block_exception32_t *lbe32; + lv_block_exception_t *lbe; + lv32_t *ul = (lv32_t *)A(p); + lv_t *l = (lv_t *) kmalloc(sizeof(lv_t), GFP_KERNEL); + + if (!l) { + *errp = -ENOMEM; + return NULL; + } + memset(l, 0, sizeof(lv_t)); + err = copy_from_user(l, ul, (long)&((lv32_t *)0)->lv_current_pe); + err |= __copy_from_user(&l->lv_current_le, &ul->lv_current_le, + ((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le)); + err |= __copy_from_user(&l->lv_remap_ptr, &ul->lv_remap_ptr, + ((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr)); + err |= __get_user(ptr1, &ul->lv_current_pe); + err |= __get_user(ptr2, &ul->lv_block_exception); + if (err) { + kfree(l); + *errp = -EFAULT; + return NULL; + } + if (ptr1) { + size = l->lv_allocated_le * sizeof(pe_t); + l->lv_current_pe = vmalloc(size); + if (l->lv_current_pe) + err = copy_from_user(l->lv_current_pe, (void *)A(ptr1), size); + } + if (!err && ptr2) { + size = l->lv_remap_end * sizeof(lv_block_exception_t); + l->lv_block_exception = lbe = vmalloc(size); + if (l->lv_block_exception) { + lbe32 = (lv_block_exception32_t *)A(ptr2); + memset(lbe, 0, size); + for (i = 0; i < l->lv_remap_end; i++, lbe++, lbe32++) { + err |= get_user(lbe->rsector_org, &lbe32->rsector_org); + err |= __get_user(lbe->rdev_org, &lbe32->rdev_org); + err |= __get_user(lbe->rsector_new, &lbe32->rsector_new); + err |= __get_user(lbe->rdev_new, &lbe32->rdev_new); + } + } + } + if (err || (ptr1 && !l->lv_current_pe) || (ptr2 && !l->lv_block_exception)) { + if (!err) + *errp = -ENOMEM; + else + *errp = -EFAULT; + put_lv_t(l); + return NULL; + } + return l; +} + +static int copy_lv_t(u32 ptr, lv_t *l) +{ + int err; + lv32_t *ul = (lv32_t *)A(ptr); + u32 ptr1; + size_t size; + + err = get_user(ptr1, &ul->lv_current_pe); + if (err) + return -EFAULT; + err = copy_to_user(ul, l, (long)&((lv32_t *)0)->lv_current_pe); + err |= __copy_to_user(&ul->lv_current_le, &l->lv_current_le, + ((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le)); + err |= __copy_to_user(&ul->lv_remap_ptr, &l->lv_remap_ptr, + ((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr)); + size = l->lv_allocated_le * sizeof(pe_t); + if (ptr1) + err |= __copy_to_user((void *)A(ptr1), l->lv_current_pe, size); + return err ? -EFAULT : 0; +} + +static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + vg_t *v = NULL; + union { + lv_req_t lv_req; + le_remap_req_t le_remap; + lv_status_byindex_req_t lv_byindex; + lv_status_bydev_req_t lv_bydev; + pv_status_req_t pv_status; + } u; + pv_t p; + int err; + u32 ptr = 0; + int i; + mm_segment_t old_fs; + void *karg = &u; + + switch (cmd) { + case VG_STATUS: + v = kmalloc(sizeof(vg_t), GFP_KERNEL); + if (!v) + return -ENOMEM; + karg = v; + break; + + case VG_CREATE_OLD: + case VG_CREATE: + v = kmalloc(sizeof(vg_t), GFP_KERNEL); + if (!v) + return -ENOMEM; + if (copy_from_user(v, (void *)arg, (long)&((vg32_t *)0)->proc)) { + kfree(v); + return -EFAULT; + } + /* 'proc' field is unused, just NULL it out. */ + v->proc = NULL; + if (copy_from_user(v->vg_uuid, ((vg32_t *)arg)->vg_uuid, UUID_LEN+1)) { + kfree(v); + return -EFAULT; + } + + karg = v; + memset(v->pv, 0, sizeof(v->pv) + sizeof(v->lv)); + if (v->pv_max > ABS_MAX_PV || v->lv_max > ABS_MAX_LV) + return -EPERM; + for (i = 0; i < v->pv_max; i++) { + err = __get_user(ptr, &((vg32_t *)arg)->pv[i]); + if (err) + break; + if (ptr) { + v->pv[i] = kmalloc(sizeof(pv_t), GFP_KERNEL); + if (!v->pv[i]) { + err = -ENOMEM; + break; + } + err = copy_from_user(v->pv[i], (void *)A(ptr), + sizeof(pv32_t) - 8 - UUID_LEN+1); + if (err) { + err = -EFAULT; + break; + } + err = copy_from_user(v->pv[i]->pv_uuid, + ((pv32_t *)A(ptr))->pv_uuid, + UUID_LEN+1); + if (err) { + err = -EFAULT; + break; + } + + v->pv[i]->pe = NULL; + v->pv[i]->bd = NULL; + } + } + if (!err) { + for (i = 0; i < v->lv_max; i++) { + err = __get_user(ptr, &((vg32_t *)arg)->lv[i]); + if (err) + break; + if (ptr) { + v->lv[i] = get_lv_t(ptr, &err); + if (err) + break; + } + } + } + break; + + case LV_CREATE: + case LV_EXTEND: + case LV_REDUCE: + case LV_REMOVE: + case LV_RENAME: + case LV_STATUS_BYNAME: + err = copy_from_user(&u.pv_status, arg, sizeof(u.pv_status.pv_name)); + if (err) + return -EFAULT; + if (cmd != LV_REMOVE) { + err = __get_user(ptr, &((lv_req32_t *)arg)->lv); + if (err) + return err; + u.lv_req.lv = get_lv_t(ptr, &err); + } else + u.lv_req.lv = NULL; + break; + + case LV_STATUS_BYINDEX: + err = get_user(u.lv_byindex.lv_index, + &((lv_status_byindex_req32_t *)arg)->lv_index); + err |= __get_user(ptr, &((lv_status_byindex_req32_t *)arg)->lv); + if (err) + return err; + u.lv_byindex.lv = get_lv_t(ptr, &err); + break; + + case LV_STATUS_BYDEV: + err = get_user(u.lv_bydev.dev, &((lv_status_bydev_req32_t *)arg)->dev); + err |= __get_user(ptr, &((lv_status_bydev_req32_t *)arg)->lv); + if (err) + return err; + u.lv_bydev.lv = get_lv_t(ptr, &err); + break; + + case VG_EXTEND: + err = copy_from_user(&p, (void *)arg, sizeof(pv32_t) - 8 - UUID_LEN+1); + if (err) + return -EFAULT; + err = copy_from_user(p.pv_uuid, ((pv32_t *)arg)->pv_uuid, UUID_LEN+1); + if (err) + return -EFAULT; + p.pe = NULL; + p.bd = NULL; + karg = &p; + break; + + case PV_CHANGE: + case PV_STATUS: + err = copy_from_user(&u.pv_status, arg, sizeof(u.lv_req.lv_name)); + if (err) + return -EFAULT; + err = __get_user(ptr, &((pv_status_req32_t *)arg)->pv); + if (err) + return err; + u.pv_status.pv = &p; + if (cmd == PV_CHANGE) { + err = copy_from_user(&p, (void *)A(ptr), + sizeof(pv32_t) - 8 - UUID_LEN+1); + if (err) + return -EFAULT; + p.pe = NULL; + p.bd = NULL; + } + break; + }; + + old_fs = get_fs(); set_fs (KERNEL_DS); + err = sys_ioctl (fd, cmd, (unsigned long)karg); + set_fs (old_fs); + + switch (cmd) { + case VG_STATUS: + if (!err) { + if (copy_to_user((void *)arg, v, (long)&((vg32_t *)0)->proc) || + clear_user(&((vg32_t *)arg)->proc, sizeof(vg32_t) - (long)&((vg32_t *)0)->proc)) + err = -EFAULT; + } + if (copy_to_user(((vg32_t *)arg)->vg_uuid, v->vg_uuid, UUID_LEN+1)) { + err = -EFAULT; + } + kfree(v); + break; + + case VG_CREATE_OLD: + case VG_CREATE: + for (i = 0; i < v->pv_max; i++) { + if (v->pv[i]) + kfree(v->pv[i]); + } + for (i = 0; i < v->lv_max; i++) { + if (v->lv[i]) + put_lv_t(v->lv[i]); + } + kfree(v); + break; + + case LV_STATUS_BYNAME: + if (!err && u.lv_req.lv) + err = copy_lv_t(ptr, u.lv_req.lv); + /* Fall through */ + + case LV_CREATE: + case LV_EXTEND: + case LV_REDUCE: + if (u.lv_req.lv) + put_lv_t(u.lv_req.lv); + break; + + case LV_STATUS_BYINDEX: + if (u.lv_byindex.lv) { + if (!err) + err = copy_lv_t(ptr, u.lv_byindex.lv); + put_lv_t(u.lv_byindex.lv); + } + break; + + case LV_STATUS_BYDEV: + if (u.lv_bydev.lv) { + if (!err) + err = copy_lv_t(ptr, u.lv_bydev.lv); + put_lv_t(u.lv_byindex.lv); + } + break; + + case PV_STATUS: + if (!err) { + err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8 - UUID_LEN+1); + if (err) + return -EFAULT; + err = copy_to_user(((pv_t *)A(ptr))->pv_uuid, p.pv_uuid, UUID_LEN + 1); + if (err) + return -EFAULT; + } + break; + }; + + return err; +} +#endif /* CONFIG_BLK_DEV_LVM */ + struct ioctl32_handler { unsigned int cmd; int (*function)(unsigned int, unsigned int, unsigned long); @@ -590,6 +1734,7 @@ IOCTL32_DEFAULT(TCSETAW), IOCTL32_DEFAULT(TCSETAF), IOCTL32_DEFAULT(TCSBRK), + IOCTL32_DEFAULT(TCSBRKP), IOCTL32_DEFAULT(TCXONC), IOCTL32_DEFAULT(TCFLSH), IOCTL32_DEFAULT(TCGETS), @@ -620,8 +1765,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,61 +1775,47 @@ IOCTL32_DEFAULT(FIONBIO), IOCTL32_DEFAULT(FIONREAD), - /* Big K */ - IOCTL32_DEFAULT(PIO_FONT), - IOCTL32_DEFAULT(GIO_FONT), - IOCTL32_DEFAULT(KDSIGACCEPT), - IOCTL32_DEFAULT(KDGETKEYCODE), - IOCTL32_DEFAULT(KDSETKEYCODE), - IOCTL32_DEFAULT(KIOCSOUND), - IOCTL32_DEFAULT(KDMKTONE), - IOCTL32_DEFAULT(KDGKBTYPE), - IOCTL32_DEFAULT(KDSETMODE), - IOCTL32_DEFAULT(KDGETMODE), - IOCTL32_DEFAULT(KDSKBMODE), - IOCTL32_DEFAULT(KDGKBMODE), - IOCTL32_DEFAULT(KDSKBMETA), - IOCTL32_DEFAULT(KDGKBMETA), - IOCTL32_DEFAULT(KDGKBENT), - IOCTL32_DEFAULT(KDSKBENT), - IOCTL32_DEFAULT(KDGKBSENT), - IOCTL32_DEFAULT(KDSKBSENT), - IOCTL32_DEFAULT(KDGKBDIACR), - IOCTL32_DEFAULT(KDSKBDIACR), - IOCTL32_DEFAULT(KDGKBLED), - IOCTL32_DEFAULT(KDSKBLED), - IOCTL32_DEFAULT(KDGETLED), - IOCTL32_DEFAULT(KDSETLED), - IOCTL32_DEFAULT(GIO_SCRNMAP), - IOCTL32_DEFAULT(PIO_SCRNMAP), - IOCTL32_DEFAULT(GIO_UNISCRNMAP), - IOCTL32_DEFAULT(PIO_UNISCRNMAP), - IOCTL32_DEFAULT(PIO_FONTRESET), - IOCTL32_DEFAULT(PIO_UNIMAPCLR), - - /* Big S */ - IOCTL32_DEFAULT(SCSI_IOCTL_GET_IDLUN), - IOCTL32_DEFAULT(SCSI_IOCTL_DOORLOCK), - IOCTL32_DEFAULT(SCSI_IOCTL_DOORUNLOCK), - IOCTL32_DEFAULT(SCSI_IOCTL_TEST_UNIT_READY), - IOCTL32_DEFAULT(SCSI_IOCTL_TAGGED_ENABLE), - IOCTL32_DEFAULT(SCSI_IOCTL_TAGGED_DISABLE), - IOCTL32_DEFAULT(SCSI_IOCTL_GET_BUS_NUMBER), - IOCTL32_DEFAULT(SCSI_IOCTL_SEND_COMMAND), - - /* Big V */ - IOCTL32_DEFAULT(VT_SETMODE), - IOCTL32_DEFAULT(VT_GETMODE), - IOCTL32_DEFAULT(VT_GETSTATE), - IOCTL32_DEFAULT(VT_OPENQRY), - IOCTL32_DEFAULT(VT_ACTIVATE), - IOCTL32_DEFAULT(VT_WAITACTIVE), - IOCTL32_DEFAULT(VT_RELDISP), - IOCTL32_DEFAULT(VT_DISALLOCATE), - IOCTL32_DEFAULT(VT_RESIZE), - IOCTL32_DEFAULT(VT_RESIZEX), - IOCTL32_DEFAULT(VT_LOCKSWITCH), - IOCTL32_DEFAULT(VT_UNLOCKSWITCH), +#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 */ + + /* Little v, the video4linux ioctls */ + IOCTL32_DEFAULT(VIDIOCGCAP), + IOCTL32_DEFAULT(VIDIOCGCHAN), + IOCTL32_DEFAULT(VIDIOCSCHAN), + IOCTL32_DEFAULT(VIDIOCGPICT), + IOCTL32_DEFAULT(VIDIOCSPICT), + IOCTL32_DEFAULT(VIDIOCCAPTURE), + + IOCTL32_DEFAULT(VIDIOCGWIN), + IOCTL32_DEFAULT(VIDIOCSWIN), + IOCTL32_DEFAULT(VIDIOCGFBUF), + IOCTL32_DEFAULT(VIDIOCSFBUF), + + IOCTL32_DEFAULT(VIDIOCKEY), + IOCTL32_DEFAULT(VIDIOCGAUDIO), + IOCTL32_DEFAULT(VIDIOCSAUDIO), + IOCTL32_DEFAULT(VIDIOCSYNC), + IOCTL32_DEFAULT(VIDIOCMCAPTURE), + IOCTL32_DEFAULT(VIDIOCGMBUF), + IOCTL32_DEFAULT(VIDIOCGUNIT), + IOCTL32_DEFAULT(VIDIOCGCAPTURE), + IOCTL32_DEFAULT(VIDIOCSCAPTURE), + /* BTTV specific... */ + IOCTL32_DEFAULT(_IOW('v', BASE_VIDIOCPRIVATE+0, char [256])), + IOCTL32_DEFAULT(_IOR('v', BASE_VIDIOCPRIVATE+1, char [256])), + IOCTL32_DEFAULT(_IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int)), + IOCTL32_DEFAULT(_IOW('v' , BASE_VIDIOCPRIVATE+3, char [16])), /* struct bttv_pll_info */ + IOCTL32_DEFAULT(_IOR('v' , BASE_VIDIOCPRIVATE+4, int)), + IOCTL32_DEFAULT(_IOR('v' , BASE_VIDIOCPRIVATE+5, int)), + IOCTL32_DEFAULT(_IOR('v' , BASE_VIDIOCPRIVATE+6, int)), + IOCTL32_DEFAULT(_IOR('v' , BASE_VIDIOCPRIVATE+7, int)), #ifdef CONFIG_NET /* Socket level stuff */ @@ -793,6 +1924,160 @@ /* 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), + /* Big Q for sound/OSS */ + IOCTL32_DEFAULT(SNDCTL_SEQ_RESET), + IOCTL32_DEFAULT(SNDCTL_SEQ_SYNC), + IOCTL32_DEFAULT(SNDCTL_SYNTH_INFO), + IOCTL32_DEFAULT(SNDCTL_SEQ_CTRLRATE), + IOCTL32_DEFAULT(SNDCTL_SEQ_GETOUTCOUNT), + IOCTL32_DEFAULT(SNDCTL_SEQ_GETINCOUNT), + IOCTL32_DEFAULT(SNDCTL_SEQ_PERCMODE), + IOCTL32_DEFAULT(SNDCTL_FM_LOAD_INSTR), + IOCTL32_DEFAULT(SNDCTL_SEQ_TESTMIDI), + IOCTL32_DEFAULT(SNDCTL_SEQ_RESETSAMPLES), + IOCTL32_DEFAULT(SNDCTL_SEQ_NRSYNTHS), + IOCTL32_DEFAULT(SNDCTL_SEQ_NRMIDIS), + IOCTL32_DEFAULT(SNDCTL_MIDI_INFO), + IOCTL32_DEFAULT(SNDCTL_SEQ_THRESHOLD), + IOCTL32_DEFAULT(SNDCTL_SYNTH_MEMAVL), + IOCTL32_DEFAULT(SNDCTL_FM_4OP_ENABLE), + IOCTL32_DEFAULT(SNDCTL_SEQ_PANIC), + IOCTL32_DEFAULT(SNDCTL_SEQ_OUTOFBAND), + IOCTL32_DEFAULT(SNDCTL_SEQ_GETTIME), + IOCTL32_DEFAULT(SNDCTL_SYNTH_ID), + IOCTL32_DEFAULT(SNDCTL_SYNTH_CONTROL), + IOCTL32_DEFAULT(SNDCTL_SYNTH_REMOVESAMPLE), + /* Big T for sound/OSS */ + IOCTL32_DEFAULT(SNDCTL_TMR_TIMEBASE), + IOCTL32_DEFAULT(SNDCTL_TMR_START), + IOCTL32_DEFAULT(SNDCTL_TMR_STOP), + IOCTL32_DEFAULT(SNDCTL_TMR_CONTINUE), + IOCTL32_DEFAULT(SNDCTL_TMR_TEMPO), + IOCTL32_DEFAULT(SNDCTL_TMR_SOURCE), + IOCTL32_DEFAULT(SNDCTL_TMR_METRONOME), + IOCTL32_DEFAULT(SNDCTL_TMR_SELECT), + /* Little m for sound/OSS */ + IOCTL32_DEFAULT(SNDCTL_MIDI_PRETIME), + IOCTL32_DEFAULT(SNDCTL_MIDI_MPUMODE), + IOCTL32_DEFAULT(SNDCTL_MIDI_MPUCMD), + /* Big P for sound/OSS */ + IOCTL32_DEFAULT(SNDCTL_DSP_RESET), + IOCTL32_DEFAULT(SNDCTL_DSP_SYNC), + IOCTL32_DEFAULT(SNDCTL_DSP_SPEED), + IOCTL32_DEFAULT(SNDCTL_DSP_STEREO), + IOCTL32_DEFAULT(SNDCTL_DSP_GETBLKSIZE), + IOCTL32_DEFAULT(SNDCTL_DSP_CHANNELS), + IOCTL32_DEFAULT(SOUND_PCM_WRITE_FILTER), + IOCTL32_DEFAULT(SNDCTL_DSP_POST), + IOCTL32_DEFAULT(SNDCTL_DSP_SUBDIVIDE), + IOCTL32_DEFAULT(SNDCTL_DSP_SETFRAGMENT), + IOCTL32_DEFAULT(SNDCTL_DSP_GETFMTS), + IOCTL32_DEFAULT(SNDCTL_DSP_SETFMT), + IOCTL32_DEFAULT(SNDCTL_DSP_GETOSPACE), + IOCTL32_DEFAULT(SNDCTL_DSP_GETISPACE), + IOCTL32_DEFAULT(SNDCTL_DSP_NONBLOCK), + IOCTL32_DEFAULT(SNDCTL_DSP_GETCAPS), + IOCTL32_DEFAULT(SNDCTL_DSP_GETTRIGGER), + IOCTL32_DEFAULT(SNDCTL_DSP_SETTRIGGER), + IOCTL32_DEFAULT(SNDCTL_DSP_GETIPTR), + IOCTL32_DEFAULT(SNDCTL_DSP_GETOPTR), + /* SNDCTL_DSP_MAPINBUF, XXX needs translation */ + /* SNDCTL_DSP_MAPOUTBUF, XXX needs translation */ + IOCTL32_DEFAULT(SNDCTL_DSP_SETSYNCRO), + IOCTL32_DEFAULT(SNDCTL_DSP_SETDUPLEX), + IOCTL32_DEFAULT(SNDCTL_DSP_GETODELAY), + IOCTL32_DEFAULT(SNDCTL_DSP_PROFILE), + IOCTL32_DEFAULT(SOUND_PCM_READ_RATE), + IOCTL32_DEFAULT(SOUND_PCM_READ_CHANNELS), + IOCTL32_DEFAULT(SOUND_PCM_READ_BITS), + IOCTL32_DEFAULT(SOUND_PCM_READ_FILTER), + /* Big C for sound/OSS */ + IOCTL32_DEFAULT(SNDCTL_COPR_RESET), + IOCTL32_DEFAULT(SNDCTL_COPR_LOAD), + IOCTL32_DEFAULT(SNDCTL_COPR_RDATA), + IOCTL32_DEFAULT(SNDCTL_COPR_RCODE), + IOCTL32_DEFAULT(SNDCTL_COPR_WDATA), + IOCTL32_DEFAULT(SNDCTL_COPR_WCODE), + IOCTL32_DEFAULT(SNDCTL_COPR_RUN), + IOCTL32_DEFAULT(SNDCTL_COPR_HALT), + IOCTL32_DEFAULT(SNDCTL_COPR_SENDMSG), + IOCTL32_DEFAULT(SNDCTL_COPR_RCVMSG), + /* Big M for sound/OSS */ + IOCTL32_DEFAULT(SOUND_MIXER_READ_VOLUME), + IOCTL32_DEFAULT(SOUND_MIXER_READ_BASS), + IOCTL32_DEFAULT(SOUND_MIXER_READ_TREBLE), + IOCTL32_DEFAULT(SOUND_MIXER_READ_SYNTH), + IOCTL32_DEFAULT(SOUND_MIXER_READ_PCM), + IOCTL32_DEFAULT(SOUND_MIXER_READ_SPEAKER), + IOCTL32_DEFAULT(SOUND_MIXER_READ_LINE), + IOCTL32_DEFAULT(SOUND_MIXER_READ_MIC), + IOCTL32_DEFAULT(SOUND_MIXER_READ_CD), + IOCTL32_DEFAULT(SOUND_MIXER_READ_IMIX), + IOCTL32_DEFAULT(SOUND_MIXER_READ_ALTPCM), + IOCTL32_DEFAULT(SOUND_MIXER_READ_RECLEV), + IOCTL32_DEFAULT(SOUND_MIXER_READ_IGAIN), + IOCTL32_DEFAULT(SOUND_MIXER_READ_OGAIN), + IOCTL32_DEFAULT(SOUND_MIXER_READ_LINE1), + IOCTL32_DEFAULT(SOUND_MIXER_READ_LINE2), + IOCTL32_DEFAULT(SOUND_MIXER_READ_LINE3), + IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_DIGITAL1)), + IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_DIGITAL2)), + IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_DIGITAL3)), + IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_PHONEIN)), + IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_PHONEOUT)), + IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_VIDEO)), + IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_RADIO)), + IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_MONITOR)), + IOCTL32_DEFAULT(SOUND_MIXER_READ_MUTE), + /* SOUND_MIXER_READ_ENHANCE, same value as READ_MUTE */ + /* SOUND_MIXER_READ_LOUD, same value as READ_MUTE */ + IOCTL32_DEFAULT(SOUND_MIXER_READ_RECSRC), + IOCTL32_DEFAULT(SOUND_MIXER_READ_DEVMASK), + IOCTL32_DEFAULT(SOUND_MIXER_READ_RECMASK), + IOCTL32_DEFAULT(SOUND_MIXER_READ_STEREODEVS), + IOCTL32_DEFAULT(SOUND_MIXER_READ_CAPS), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_VOLUME), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_BASS), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_TREBLE), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_SYNTH), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_PCM), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_SPEAKER), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_LINE), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_MIC), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_CD), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_IMIX), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_ALTPCM), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_RECLEV), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_IGAIN), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_OGAIN), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_LINE1), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_LINE2), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_LINE3), + IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_DIGITAL1)), + IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_DIGITAL2)), + IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_DIGITAL3)), + IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_PHONEIN)), + IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_PHONEOUT)), + IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_VIDEO)), + IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_RADIO)), + IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_MONITOR)), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_MUTE), + /* SOUND_MIXER_WRITE_ENHANCE, same value as WRITE_MUTE */ + /* SOUND_MIXER_WRITE_LOUD, same value as WRITE_MUTE */ + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_RECSRC), + IOCTL32_DEFAULT(SOUND_MIXER_INFO), + IOCTL32_DEFAULT(SOUND_OLD_MIXER_INFO), + IOCTL32_DEFAULT(SOUND_MIXER_ACCESS), + IOCTL32_DEFAULT(SOUND_MIXER_PRIVATE1), + IOCTL32_DEFAULT(SOUND_MIXER_PRIVATE2), + IOCTL32_DEFAULT(SOUND_MIXER_PRIVATE3), + IOCTL32_DEFAULT(SOUND_MIXER_PRIVATE4), + IOCTL32_DEFAULT(SOUND_MIXER_PRIVATE5), + IOCTL32_DEFAULT(SOUND_MIXER_GETLEVELS), + IOCTL32_DEFAULT(SOUND_MIXER_SETLEVELS), + IOCTL32_DEFAULT(OSS_GETVERSION), /* And these ioctls need translation */ IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32), @@ -838,11 +2123,53 @@ #endif /* CONFIG_NET */ + IOCTL32_HANDLER(BLKRAGET, w_long), + IOCTL32_HANDLER(BLKGETSIZE, w_long), + // IOCTL32_HANDLER(0x1260, broken_blkgetsize), + IOCTL32_HANDLER(BLKFRAGET, w_long), + IOCTL32_HANDLER(BLKSECTGET, w_long), + IOCTL32_HANDLER(BLKPG, blkpg_ioctl_trans), + IOCTL32_HANDLER(EXT2_IOC32_GETFLAGS, do_ext2_ioctl), IOCTL32_HANDLER(EXT2_IOC32_SETFLAGS, do_ext2_ioctl), IOCTL32_HANDLER(EXT2_IOC32_GETVERSION, do_ext2_ioctl), IOCTL32_HANDLER(EXT2_IOC32_SETVERSION, do_ext2_ioctl), + IOCTL32_HANDLER(VIDIOCGTUNER32, do_video_ioctl), + IOCTL32_HANDLER(VIDIOCSTUNER32, do_video_ioctl), + IOCTL32_HANDLER(VIDIOCGWIN32, do_video_ioctl), + IOCTL32_HANDLER(VIDIOCSWIN32, do_video_ioctl), + IOCTL32_HANDLER(VIDIOCGFBUF32, do_video_ioctl), + IOCTL32_HANDLER(VIDIOCSFBUF32, do_video_ioctl), + IOCTL32_HANDLER(VIDIOCGFREQ32, do_video_ioctl), + IOCTL32_HANDLER(VIDIOCSFREQ32, do_video_ioctl), + +#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) + IOCTL32_HANDLER(VG_STATUS, do_lvm_ioctl), + IOCTL32_HANDLER(VG_CREATE_OLD, do_lvm_ioctl), + IOCTL32_HANDLER(VG_CREATE, do_lvm_ioctl), + IOCTL32_HANDLER(VG_EXTEND, do_lvm_ioctl), + IOCTL32_HANDLER(LV_CREATE, do_lvm_ioctl), + IOCTL32_HANDLER(LV_REMOVE, do_lvm_ioctl), + IOCTL32_HANDLER(LV_EXTEND, do_lvm_ioctl), + IOCTL32_HANDLER(LV_REDUCE, do_lvm_ioctl), + IOCTL32_HANDLER(LV_RENAME, do_lvm_ioctl), + IOCTL32_HANDLER(LV_STATUS_BYNAME, do_lvm_ioctl), + IOCTL32_HANDLER(LV_STATUS_BYINDEX, do_lvm_ioctl), + IOCTL32_HANDLER(LV_STATUS_BYDEV, do_lvm_ioctl), + IOCTL32_HANDLER(PV_CHANGE, do_lvm_ioctl), + IOCTL32_HANDLER(PV_STATUS, do_lvm_ioctl), +#endif /* LVM */ + + /* take care of sizeof(sizeof()) breakage */ + /* elevator */ + IOCTL32_HANDLER(BLKELVGET_32, do_blkelvget), + IOCTL32_HANDLER(BLKELVSET_32, do_blkelvset), + /* block stuff */ + IOCTL32_HANDLER(BLKBSZGET_32, do_blkbszget), + IOCTL32_HANDLER(BLKBSZSET_32, do_blkbszset), + IOCTL32_HANDLER(BLKGETSIZE64_32, do_blkgetsize64), + IOCTL32_HANDLER(HDIO_GETGEO, hdio_getgeo), /* hdreg.h ioctls */ IOCTL32_HANDLER(HDIO_GET_UNMASKINTR, hdio_ioctl_trans), IOCTL32_HANDLER(HDIO_GET_MULTCOUNT, hdio_ioctl_trans), @@ -871,21 +2198,106 @@ IOCTL32_DEFAULT(BLKROSET), /* fs.h ioctls */ IOCTL32_DEFAULT(BLKROGET), IOCTL32_DEFAULT(BLKRRPART), - IOCTL32_HANDLER(BLKGETSIZE, w_long), - IOCTL32_DEFAULT(BLKFLSBUF), IOCTL32_DEFAULT(BLKRASET), - IOCTL32_HANDLER(BLKRAGET, w_long), IOCTL32_DEFAULT(BLKFRASET), - IOCTL32_HANDLER(BLKFRAGET, w_long), IOCTL32_DEFAULT(BLKSECTSET), - IOCTL32_HANDLER(BLKSECTGET, w_long), IOCTL32_DEFAULT(BLKSSZGET), - IOCTL32_HANDLER(BLKPG, blkpg_ioctl_trans), - IOCTL32_DEFAULT(BLKELVGET), - IOCTL32_DEFAULT(BLKELVSET), - IOCTL32_DEFAULT(BLKBSZGET), - IOCTL32_DEFAULT(BLKBSZSET), + + /* RAID */ + IOCTL32_DEFAULT(RAID_VERSION), + IOCTL32_DEFAULT(GET_ARRAY_INFO), + IOCTL32_DEFAULT(GET_DISK_INFO), + IOCTL32_DEFAULT(PRINT_RAID_DEBUG), + IOCTL32_DEFAULT(CLEAR_ARRAY), + IOCTL32_DEFAULT(ADD_NEW_DISK), + IOCTL32_DEFAULT(HOT_REMOVE_DISK), + IOCTL32_DEFAULT(SET_ARRAY_INFO), + IOCTL32_DEFAULT(SET_DISK_INFO), + IOCTL32_DEFAULT(WRITE_RAID_INFO), + IOCTL32_DEFAULT(UNPROTECT_ARRAY), + IOCTL32_DEFAULT(PROTECT_ARRAY), + IOCTL32_DEFAULT(HOT_ADD_DISK), + IOCTL32_DEFAULT(SET_DISK_FAULTY), + IOCTL32_DEFAULT(RUN_ARRAY), + IOCTL32_DEFAULT(START_ARRAY), + IOCTL32_DEFAULT(STOP_ARRAY), + IOCTL32_DEFAULT(STOP_ARRAY_RO), + IOCTL32_DEFAULT(RESTART_ARRAY_RW), + IOCTL32_DEFAULT(RAID_AUTORUN), + + /* Big K */ + IOCTL32_DEFAULT(PIO_FONT), + IOCTL32_DEFAULT(GIO_FONT), +#ifdef CONFIG_VT + IOCTL32_HANDLER(GIO_FONTX, do_fontx_ioctl), + IOCTL32_HANDLER(PIO_FONTX, do_fontx_ioctl), +#endif + IOCTL32_DEFAULT(KDSIGACCEPT), + IOCTL32_DEFAULT(KDGETKEYCODE), + IOCTL32_DEFAULT(KDSETKEYCODE), + IOCTL32_DEFAULT(KIOCSOUND), + IOCTL32_DEFAULT(KDMKTONE), + IOCTL32_DEFAULT(KDGKBTYPE), + IOCTL32_DEFAULT(KDSETMODE), + IOCTL32_DEFAULT(KDGETMODE), + IOCTL32_DEFAULT(KDSKBMODE), + IOCTL32_DEFAULT(KDGKBMODE), + IOCTL32_DEFAULT(KDSKBMETA), + IOCTL32_DEFAULT(KDGKBMETA), + IOCTL32_DEFAULT(KDGKBENT), + IOCTL32_DEFAULT(KDSKBENT), + IOCTL32_DEFAULT(KDGKBSENT), + IOCTL32_DEFAULT(KDSKBSENT), + IOCTL32_DEFAULT(KDGKBDIACR), + IOCTL32_DEFAULT(KDKBDREP), +#ifdef CONFIG_VT + IOCTL32_HANDLER(KDFONTOP, do_kdfontop_ioctl), +#endif + IOCTL32_DEFAULT(KDSKBDIACR), + IOCTL32_DEFAULT(KDGKBLED), + IOCTL32_DEFAULT(KDSKBLED), + IOCTL32_DEFAULT(KDGETLED), + IOCTL32_DEFAULT(KDSETLED), + IOCTL32_DEFAULT(GIO_SCRNMAP), + IOCTL32_DEFAULT(PIO_SCRNMAP), + IOCTL32_DEFAULT(GIO_UNISCRNMAP), + IOCTL32_DEFAULT(PIO_UNISCRNMAP), + IOCTL32_DEFAULT(PIO_FONTRESET), + IOCTL32_DEFAULT(PIO_UNIMAPCLR), + + /* Big S */ + IOCTL32_DEFAULT(SCSI_IOCTL_GET_IDLUN), + IOCTL32_DEFAULT(SCSI_IOCTL_PROBE_HOST), + IOCTL32_DEFAULT(SCSI_IOCTL_GET_PCI), + IOCTL32_DEFAULT(SCSI_IOCTL_DOORLOCK), + IOCTL32_DEFAULT(SCSI_IOCTL_DOORUNLOCK), + IOCTL32_DEFAULT(SCSI_IOCTL_TEST_UNIT_READY), + IOCTL32_DEFAULT(SCSI_IOCTL_TAGGED_ENABLE), + IOCTL32_DEFAULT(SCSI_IOCTL_TAGGED_DISABLE), + IOCTL32_DEFAULT(SCSI_IOCTL_GET_BUS_NUMBER), + IOCTL32_DEFAULT(SCSI_IOCTL_SEND_COMMAND), + + /* Big T */ + IOCTL32_DEFAULT(TUNSETNOCSUM), + IOCTL32_DEFAULT(TUNSETDEBUG), + IOCTL32_DEFAULT(TUNSETIFF), + IOCTL32_DEFAULT(TUNSETPERSIST), + IOCTL32_DEFAULT(TUNSETOWNER), + + /* Big V */ + IOCTL32_DEFAULT(VT_SETMODE), + IOCTL32_DEFAULT(VT_GETMODE), + IOCTL32_DEFAULT(VT_GETSTATE), + IOCTL32_DEFAULT(VT_OPENQRY), + IOCTL32_DEFAULT(VT_ACTIVATE), + IOCTL32_DEFAULT(VT_WAITACTIVE), + IOCTL32_DEFAULT(VT_RELDISP), + IOCTL32_DEFAULT(VT_DISALLOCATE), + IOCTL32_DEFAULT(VT_RESIZE), + IOCTL32_DEFAULT(VT_RESIZEX), + IOCTL32_DEFAULT(VT_LOCKSWITCH), + IOCTL32_DEFAULT(VT_UNLOCKSWITCH), #ifdef CONFIG_MD /* status */ @@ -915,6 +2327,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 +2351,40 @@ IOCTL32_DEFAULT(AUTOFS_IOC_PROTOVER), IOCTL32_HANDLER(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout), IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE), + IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE_MULTI), + + /* DEVFS */ + IOCTL32_DEFAULT(DEVFSDIOC_GET_PROTO_REV), + IOCTL32_DEFAULT(DEVFSDIOC_SET_EVENT_MASK), + IOCTL32_DEFAULT(DEVFSDIOC_RELEASE_EVENT_QUEUE), + IOCTL32_DEFAULT(DEVFSDIOC_SET_DEBUG_MASK), + + /* Raw devices */ + IOCTL32_DEFAULT(RAW_SETBIND), + IOCTL32_DEFAULT(RAW_GETBIND), + +#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) + /* 0xfe - lvm */ + IOCTL32_DEFAULT(VG_SET_EXTENDABLE), + IOCTL32_DEFAULT(VG_STATUS_GET_COUNT), + IOCTL32_DEFAULT(VG_STATUS_GET_NAMELIST), + IOCTL32_DEFAULT(VG_REMOVE), + IOCTL32_DEFAULT(VG_RENAME), + IOCTL32_DEFAULT(VG_REDUCE), + IOCTL32_DEFAULT(PE_LOCK_UNLOCK), + IOCTL32_DEFAULT(PV_FLUSH), + IOCTL32_DEFAULT(LVM_LOCK_LVM), + IOCTL32_DEFAULT(LVM_GET_IOP_VERSION), +#ifdef LVM_TOTAL_RESET + IOCTL32_DEFAULT(LVM_RESET), +#endif + IOCTL32_DEFAULT(LV_SET_ACCESS), + IOCTL32_DEFAULT(LV_SET_STATUS), + IOCTL32_DEFAULT(LV_SET_ALLOCATION), + IOCTL32_DEFAULT(LE_REMAP), + IOCTL32_DEFAULT(LV_BMAP), + IOCTL32_DEFAULT(LV_SNAPSHOT_USE_RATE), +#endif /* LVM */ /* Little p (/dev/rtc, /dev/envctrl, etc.) */ IOCTL32_DEFAULT(_IOR('p', 20, int[7])), /* RTCGET */ @@ -950,7 +2402,19 @@ 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) / \ Index: arch/mips64/kernel/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/irq.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/irq.c 4 Aug 2004 01:25:55 -0000 1.2 @@ -211,7 +211,7 @@ void __global_cli(void) { - unsigned int flags; + unsigned long flags; __save_flags(flags); if (flags & ST0_IE) { @@ -870,7 +870,7 @@ if (!shared) { desc->depth = 0; - desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING); + desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS); desc->handler->startup(irq); } spin_unlock_irqrestore(&desc->lock,flags); @@ -916,8 +916,8 @@ return -EFAULT; /* - * Parse the first 8 characters as a hex string, any non-hex char - * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. + * Parse the first HEX_DIGITS characters as a hex string, any non-hex + * char is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. */ value = 0; Index: arch/mips64/kernel/irq_cpu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/irq_cpu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/irq_cpu.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/irq_cpu.c 4 Aug 2004 01:25:55 -0000 1.2 @@ -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); } Index: arch/mips64/kernel/linux32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/linux32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/linux32.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/linux32.c 4 Aug 2004 01:25:55 -0000 1.2 @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -30,13 +29,46 @@ #include #include #include +#include #include #include +#include #include #include #include +extern asmlinkage long sys_socket(int family, int type, int protocol); +extern asmlinkage long sys_bind(int fd, struct sockaddr *umyaddr, int addrlen); +extern asmlinkage long sys_connect(int fd, struct sockaddr *uservaddr, + int addrlen); +extern asmlinkage long sys_listen(int fd, int backlog); +extern asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr, + int *upeer_addrlen); +extern asmlinkage long sys_getsockname(int fd, struct sockaddr *usockaddr, + int *usockaddr_len); +extern asmlinkage long sys_getpeername(int fd, struct sockaddr *usockaddr, + int *usockaddr_len); +extern asmlinkage long sys_socketpair(int family, int type, int protocol, + int *usockvec); +extern asmlinkage long sys_send(int fd, void * buff, size_t len, + unsigned flags); +extern asmlinkage long sys_sendto(int fd, void * buff, size_t len, + unsigned flags, struct sockaddr *addr, int addr_len); +extern asmlinkage long sys_recv(int fd, void * ubuf, size_t size, + unsigned flags); +extern asmlinkage long sys_recvfrom(int fd, void * ubuf, size_t size, + unsigned flags, struct sockaddr *addr, int *addr_len); +extern asmlinkage long sys_shutdown(int fd, int how); +extern asmlinkage long sys_setsockopt(int fd, int level, int optname, + char *optval, int optlen); +extern asmlinkage long sys_getsockopt(int fd, int level, int optname, + char *optval, int *optlen); +extern asmlinkage long sys_sendmsg(int fd, struct msghdr *msg, unsigned flags); +extern asmlinkage long sys_recvmsg(int fd, struct msghdr *msg, + unsigned int flags); + + /* Use this to get at 32-bit user passed pointers. */ /* A() macro should be used for places where you e.g. have some internal variable u32 and just want to get @@ -179,7 +211,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 +298,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 +366,6 @@ } err = copy_from_user(kaddr + offset, (char *)A(str), bytes_to_copy); - flush_page_to_ram(page); kunmap(page); if (err) @@ -416,26 +472,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 +503,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 +526,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 +543,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 +641,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 +662,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 +694,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 +830,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 +861,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 +985,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 @@ -1372,9 +1495,6 @@ return ret; } -extern asmlinkage int sys_setsockopt(int fd, int level, int optname, - char *optval, int optlen); - static int do_set_attach_filter(int fd, int level, int optname, char *optval, int optlen) { @@ -1572,6 +1692,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 +1746,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 +1771,6 @@ u32 pad; int err, err2; struct semid64_ds s; - struct semid_ds32 *usp; mm_segment_t old_fs; if (!uptr) @@ -1642,7 +1783,6 @@ else fourth.__pad = (void *)A(pad); switch (third & ~IPC_64) { - case IPC_INFO: case IPC_RMID: case IPC_SET: @@ -1659,34 +1799,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); + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = sys_semctl(first, second, third | IPC_64, fourth); + set_fs(old_fs); + + 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; @@ -1799,18 +1965,18 @@ } if (err) break; - old_fs = get_fs (); - set_fs (KERNEL_DS); - err = sys_msgctl (first, second, (struct msqid_ds *)&m); - set_fs (old_fs); + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = sys_msgctl(first, second | IPC_64, (struct msqid_ds *)&m); + set_fs(old_fs); break; case IPC_STAT: case MSG_STAT: - old_fs = get_fs (); - set_fs (KERNEL_DS); - err = sys_msgctl (first, second, (struct msqid_ds *)&m); - set_fs (old_fs); + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = sys_msgctl(first, second | IPC_64, (struct msqid_ds *)&m); + set_fs(old_fs); if (second & IPC_64) { if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) { err = -EFAULT; @@ -1871,8 +2037,6 @@ if (version == 1) return err; - if (version == 1) - return err; err = sys_shmat (first, uptr, second, &raddr); if (err) return err; @@ -1880,93 +2044,149 @@ return err; } +struct shm_info32 { + int used_ids; + u32 shm_tot, shm_rss, shm_swp; + u32 swap_attempts, swap_successes; +}; + static int do_sys32_shmctl (int first, int second, void *uptr) { + struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr; + struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr; + struct shm_info32 *uip = (struct shm_info32 *)uptr; int err = -EFAULT, err2; - struct shmid_ds s; struct shmid64_ds s64; - struct shmid_ds32 *up = (struct shmid_ds32 *)uptr; mm_segment_t old_fs; - struct shm_info32 { - int used_ids; - u32 shm_tot, shm_rss, shm_swp; - u32 swap_attempts, swap_successes; - } *uip = (struct shm_info32 *)uptr; struct shm_info si; + struct shmid_ds s; - 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); + 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 (); - set_fs (KERNEL_DS); - err = sys_shmctl (first, second, &s); - set_fs (old_fs); + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = sys_shmctl(first, second & ~IPC_64, &s); + set_fs(old_fs); break; case IPC_STAT: case SHM_STAT: - old_fs = get_fs (); - set_fs (KERNEL_DS); - err = sys_shmctl (first, second, (void *) &s64); - set_fs (old_fs); + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = sys_shmctl(first, second | IPC_64, (void *) &s64); + 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; case SHM_INFO: - old_fs = get_fs (); - set_fs (KERNEL_DS); - err = sys_shmctl (first, second, (void *)&si); - set_fs (old_fs); + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = sys_shmctl(first, second, (void *)&si); + set_fs(old_fs); if (err < 0) break; - err2 = put_user (si.used_ids, &uip->used_ids); - err2 |= __put_user (si.shm_tot, &uip->shm_tot); - err2 |= __put_user (si.shm_rss, &uip->shm_rss); - err2 |= __put_user (si.shm_swp, &uip->shm_swp); - err2 |= __put_user (si.swap_attempts, - &uip->swap_attempts); - err2 |= __put_user (si.swap_successes, - &uip->swap_successes); + err2 = put_user(si.used_ids, &uip->used_ids); + err2 |= __put_user(si.shm_tot, &uip->shm_tot); + err2 |= __put_user(si.shm_rss, &uip->shm_rss); + err2 |= __put_user(si.shm_swp, &uip->shm_swp); + err2 |= __put_user(si.swap_attempts, &uip->swap_attempts); + err2 |= __put_user (si.swap_successes, &uip->swap_successes); if (err2) err = -EFAULT; break; + default: + err = -EINVAL; + break; } + return err; } +static inline void *alloc_user_space(long len) +{ + unsigned long sp = (unsigned long) current + THREAD_SIZE - 32; + + return (void *) (sp - len); +} + +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 long sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) { @@ -1979,8 +2199,12 @@ 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); + break; + case SEMTIMEDOP: + err = sys32_semtimedop(first, (struct sembuf *)AA(ptr), second, + (const struct timespec32 *) AA(fifth)); break; case SEMGET: err = sys_semget (first, second, third); @@ -2037,83 +2261,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; @@ -2143,6 +2339,40 @@ return ret; } +/* ustat compatibility */ +struct ustat32 { + __kernel_daddr_t32 f_tfree; + __kernel_ino_t32 f_tinode; + char f_fname[6]; + char f_fpack[6]; +}; + +extern asmlinkage long sys_ustat(dev_t dev, struct ustat * ubuf); + +asmlinkage int sys32_ustat(dev_t dev, struct ustat32 * ubuf32) +{ + int err; + struct ustat tmp; + struct ustat32 tmp32; + mm_segment_t old_fs = get_fs(); + + set_fs(KERNEL_DS); + err = sys_ustat(dev, &tmp); + set_fs (old_fs); + + if (err) + goto out; + + memset(&tmp32,0,sizeof(struct ustat32)); + tmp32.f_tfree = tmp.f_tfree; + tmp32.f_tinode = tmp.f_tinode; + + err = copy_to_user(ubuf32,&tmp32,sizeof(struct ustat32)) ? -EFAULT : 0; + +out: + return err; +} + /* Handle adjtimex compatability. */ struct timex32 { @@ -2219,7 +2449,7 @@ /* * Declare the 32-bit version of the msghdr */ - + struct msghdr32 { unsigned int msg_name; /* Socket name */ int msg_namelen; /* Length of name */ @@ -2230,252 +2460,539 @@ 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; + + __ptr = (struct cmsghdr32 *)(((unsigned char *) __cmsg) + + CMSG32_ALIGN(__cmsg_len)); + if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size) + return NULL; - 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); + 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; } -extern __inline__ void +/* 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; +} + +static __inline__ void sockfd_put(struct socket *sock) { fput(sock->file); } /* 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; + +out_free_efault: + if(kcmsg_base != (struct cmsghdr *)stackbuf) + kfree(kcmsg_base); + return -EFAULT; +} - /* do not move before msg_sys is valid */ - err = -EINVAL; - if (msg_sys.msg_iovlen > UIO_MAXIOV) - 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); - /* 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; + 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); @@ -2486,6 +3003,98 @@ return sys_readahead(fd, merge_64(a2, a3), count); } +/* Argument list sizes for sys_socketcall */ +#define AL(x) ((x) * sizeof(unsigned int)) +static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), + AL(3),AL(3),AL(4),AL(4),AL(4),AL(6), + AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)}; +#undef AL + +/* + * System call vectors. + * + * Argument checking cleaned up. Saved 20% in size. + * This function doesn't need to set the kernel lock because + * it is set by the callees. + */ + +asmlinkage long sys32_socketcall(int call, unsigned int *args32) +{ + unsigned int a[6]; + unsigned int a0,a1; + int err; + + if(call<1||call>SYS_RECVMSG) + return -EINVAL; + + /* copy_from_user should be SMP safe. */ + if (copy_from_user(a, args32, socketcall_nargs[call])) + return -EFAULT; + + a0=a[0]; + a1=a[1]; + + switch (call) { + case SYS_SOCKET: + err = sys_socket(a0,a1,a[2]); + break; + case SYS_BIND: + err = sys_bind(a0,(struct sockaddr *)A(a1), a[2]); + break; + case SYS_CONNECT: + err = sys_connect(a0, (struct sockaddr *)A(a1), a[2]); + break; + case SYS_LISTEN: + err = sys_listen(a0,a1); + break; + case SYS_ACCEPT: + err = sys_accept(a0,(struct sockaddr *)A(a1), (int *)A(a[2])); + break; + case SYS_GETSOCKNAME: + err = sys_getsockname(a0,(struct sockaddr *)A(a1), (int *)A(a[2])); + break; + case SYS_GETPEERNAME: + err = sys_getpeername(a0, (struct sockaddr *)A(a1), (int *)A(a[2])); + break; + case SYS_SOCKETPAIR: + err = sys_socketpair(a0,a1, a[2], (int *)A(a[3])); + break; + case SYS_SEND: + err = sys_send(a0, (void *)A(a1), a[2], a[3]); + break; + case SYS_SENDTO: + err = sys_sendto(a0,(void *)A(a1), a[2], a[3], + (struct sockaddr *)A(a[4]), a[5]); + break; + case SYS_RECV: + err = sys_recv(a0, (void *)A(a1), a[2], a[3]); + break; + case SYS_RECVFROM: + err = sys_recvfrom(a0, (void *)A(a1), a[2], a[3], + (struct sockaddr *)A(a[4]), (int *)A(a[5])); + break; + case SYS_SHUTDOWN: + err = sys_shutdown(a0,a1); + break; + case SYS_SETSOCKOPT: + err = sys_setsockopt(a0, a1, a[2], (char *)A(a[3]), a[4]); + break; + case SYS_GETSOCKOPT: + err = sys_getsockopt(a0, a1, a[2], (char *)A(a[3]), (int *)A(a[4])); + break; + case SYS_SENDMSG: + err = sys_sendmsg(a0, (struct msghdr *) A(a1), a[2]); + break; + case SYS_RECVMSG: + err = sys_recvmsg(a0, (struct msghdr *) A(a1), a[2]); + break; + default: + err = -EINVAL; + break; + } + return err; +} + #ifdef CONFIG_MODULES /* From sparc64 */ @@ -2520,7 +3129,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 +3167,4 @@ return -ENOSYS; } -#endif +#endif /* CONFIG_MODULES */ Index: arch/mips64/kernel/mips64_ksyms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/mips64_ksyms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/mips64_ksyms.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/mips64_ksyms.c 4 Aug 2004 01:25:55 -0000 1.2 @@ -19,7 +19,9 @@ #include #include +#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE) #include +#endif #include #include #include @@ -60,7 +62,7 @@ EXPORT_SYMBOL_NOVERS(strtok); EXPORT_SYMBOL_NOVERS(strpbrk); -EXPORT_SYMBOL(_clear_page); +EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(kernel_thread); /* @@ -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); /* Index: arch/mips64/kernel/pci-dma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/pci-dma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/pci-dma.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/pci-dma.c 4 Aug 2004 01:25:55 -0000 1.2 @@ -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); Index: arch/mips64/kernel/proc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/proc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/proc.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/proc.c 4 Aug 2004 01:25:55 -0000 1.2 @@ -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", @@ -43,6 +39,7 @@ [CPU_R6000A] "R6000A", [CPU_R8000] "R8000", [CPU_R10000] "R10000", + [CPU_R12000] "R12000", [CPU_R4300] "R4300", [CPU_R4650] "R4650", [CPU_R4700] "R4700", @@ -51,6 +48,7 @@ [CPU_R4640] "R4640", [CPU_NEVADA] "Nevada", [CPU_RM7000] "RM7000", + [CPU_RM9000] "RM9000", [CPU_R5432] "R5432", [CPU_4KC] "MIPS 4Kc", [CPU_5KC] "MIPS 5Kc", @@ -66,21 +64,24 @@ [CPU_VR41XX] "NEC Vr41xx", [CPU_R5500] "R5500", [CPU_TX49XX] "TX49xx", - [CPU_TX39XX] "TX39xx", [CPU_20KC] "MIPS 20Kc", + [CPU_24K] "MIPS 24K", + [CPU_25KF] "MIPS 25Kf", [CPU_VR4111] "NEC VR4111", [CPU_VR4121] "NEC VR4121", [CPU_VR4122] "NEC VR4122", [CPU_VR4131] "NEC VR4131", + [CPU_VR4133] "NEC VR4133", [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 +98,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 +108,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 +141,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, }; Index: arch/mips64/kernel/process.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/process.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/process.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/process.c 4 Aug 2004 01:25:55 -0000 1.2 @@ -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; Index: arch/mips64/kernel/ptrace.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/ptrace.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/ptrace.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/ptrace.c 4 Aug 2004 01:25:55 -0000 1.2 @@ -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. */ Index: arch/mips64/kernel/r4k_fpu.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/r4k_fpu.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/r4k_fpu.S 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/r4k_fpu.S 4 Aug 2004 01:25:55 -0000 1.2 @@ -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 Index: arch/mips64/kernel/r4k_genex.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/r4k_genex.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/r4k_genex.S 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/r4k_genex.S 4 Aug 2004 01:25:55 -0000 1.2 @@ -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,8 @@ #include #include #include -#include +#include +#include BUILD_HANDLER adel ade ade silent /* #4 */ BUILD_HANDLER ades ade ade silent /* #5 */ @@ -27,29 +29,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 +71,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 Index: arch/mips64/kernel/r4k_switch.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/r4k_switch.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/r4k_switch.S 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/r4k_switch.S 4 Aug 2004 01:25:55 -0000 1.2 @@ -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) Index: arch/mips64/kernel/scall_64.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/scall_64.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/scall_64.S 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/scall_64.S 4 Aug 2004 01:25:55 -0000 1.2 @@ -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 @@ -32,14 +33,14 @@ #endif ld t1, PT_EPC(sp) # skip syscall on return - subu t0, v0, __NR_Linux # check syscall number - sltiu t0, t0, __NR_Linux_syscalls + 1 + subu t0, v0, __NR_64_Linux # check syscall number + sltiu t0, t0, __NR_64_Linux_syscalls + 1 daddiu t1, 4 # skip to next instruction beqz t0, illegal_syscall sd t1, PT_EPC(sp) dsll t0, v0, 3 # offset into table - ld t2, (sys_call_table - (__NR_Linux * 8))(t0) # syscall routine + ld t2, (sys_call_table - (__NR_64_Linux * 8))(t0) # syscall routine sd a3, PT_R26(sp) # save a3 for syscall restarting @@ -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,218 @@ .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_ni_syscall + 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 + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_semtimedop Index: arch/mips64/kernel/scall_o32.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/scall_o32.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/scall_o32.S 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/scall_o32.S 4 Aug 2004 01:25:55 -0000 1.2 @@ -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 @@ -374,7 +386,7 @@ sys sys_ni_syscall 0 /* was sys_olduname */ sys sys_umask 1 /* 4060 */ sys sys_chroot 1 - sys sys_ustat 2 + sys sys32_ustat 2 sys sys_dup2 2 sys sys_getppid 0 sys sys_getpgrp 0 /* 4065 */ @@ -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 @@ -414,7 +426,7 @@ sys sys32_statfs 2 sys sys32_fstatfs 2 /* 4100 */ sys sys_ni_syscall 0 /* sys_ioperm */ - sys sys_socketcall 2 + sys sys32_socketcall 2 sys sys_syslog 3 sys sys32_setitimer 3 sys sys32_getitimer 2 /* 4105 */ @@ -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 */ Index: arch/mips64/kernel/semaphore.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/semaphore.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/semaphore.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/semaphore.c 4 Aug 2004 01:25:56 -0000 1.2 @@ -1,129 +1,272 @@ /* - * Generic semaphore code. Buyer beware. Do your own - * specific changes in + * Copyright (C) 1999, 2001, 02, 03 Ralf Baechle + * + * Heavily inspired by the Alpha implementation */ - +#include +#include +#include #include -#include + +#ifdef CONFIG_CPU_HAS_LLDSCD +/* + * On machines without lld/scd we need a spinlock to make the manipulation of + * sem->count and sem->waking atomic. Scalability isn't an issue because + * this lock is used on UP only so it's just an empty variable. + */ +spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED; + +EXPORT_SYMBOL(semaphore_lock); +#endif /* - * 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. + * 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() 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) +void __up_wakeup(struct semaphore *sem) { - wake_one_more(sem); wake_up(&sem->wait); } +EXPORT_SYMBOL(__up_wakeup); + +#ifdef CONFIG_CPU_HAS_LLSC + +static inline int waking_non_zero(struct semaphore *sem) +{ + int ret, tmp; + + __asm__ __volatile__( + "1: ll %1, %2 # waking_non_zero \n" + " blez %1, 2f \n" + " subu %0, %1, 1 \n" + " sc %0, %2 \n" + " beqz %0, 1b \n" + "2: \n" + : "=r" (ret), "=r" (tmp), "+m" (sem->waking) + : "0" (0)); + + return ret; +} + +#else /* !CONFIG_CPU_HAS_LLSC */ + +static inline int waking_non_zero(struct semaphore *sem) +{ + unsigned long flags; + int waking, ret = 0; + + spin_lock_irqsave(&semaphore_lock, flags); + waking = atomic_read(&sem->waking); + if (waking > 0) { + atomic_set(&sem->waking, waking - 1); + ret = 1; + } + spin_unlock_irqrestore(&semaphore_lock, flags); + + return ret; +} + +#endif /* !CONFIG_CPU_HAS_LLSC */ + /* - * Perform the "down" function. Return zero for semaphore acquired, - * return negative for signalled out of the function. + * 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). + * 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. * - * Either form may be used in conjunction with "up()". + * 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; \ +void __down_failed(struct semaphore * sem) +{ + struct task_struct *tsk = current; + wait_queue_t wait; + init_waitqueue_entry(&wait, tsk); + __set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue_exclusive(&sem->wait, &wait); -#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. \ - */ \ + /* + * 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; \ + if (waking_non_zero(sem)) + break; + schedule(); + __set_current_state(TASK_UNINTERRUPTIBLE); + } + __set_current_state(TASK_RUNNING); remove_wait_queue(&sem->wait, &wait); +} + +EXPORT_SYMBOL(__down_failed); + +#ifdef CONFIG_CPU_HAS_LLDSCD + +/* + * waking_non_zero_interruptible: + * 1 got the lock + * 0 go to sleep + * -EINTR interrupted + * + * We must undo the sem->count down_interruptible decrement + * simultaneously and atomically with the sem->waking adjustment, + * otherwise we can race with wake_one_more. + * + * This is accomplished by doing a 64-bit lld/scd on the 2 32-bit words. + * + * This is crazy. Normally it's strictly forbidden to use 64-bit operations + * in the 32-bit MIPS kernel. In this case it's however ok because if an + * interrupt has destroyed the upper half of registers sc will fail. + * Note also that this will not work for MIPS32 CPUs! + * + * Pseudocode: + * + * If(sem->waking > 0) { + * Decrement(sem->waking) + * Return(SUCCESS) + * } else If(signal_pending(tsk)) { + * Increment(sem->count) + * Return(-EINTR) + * } else { + * Return(SLEEP) + * } + */ -void __down(struct semaphore * sem) +static inline int +waking_non_zero_interruptible(struct semaphore *sem, struct task_struct *tsk) { - DOWN_VAR - DOWN_HEAD(TASK_UNINTERRUPTIBLE) - if (waking_non_zero(sem)) - break; - schedule(); - DOWN_TAIL(TASK_UNINTERRUPTIBLE) + long ret, tmp; + + __asm__ __volatile__( + " .set push # waking_non_zero_interruptible \n" + " .set mips3 \n" + " .set noat \n" + "0: lld %1, %2 \n" + " li %0, 0 \n" + " sll $1, %1, 0 \n" + " blez $1, 1f \n" + " daddiu %1, %1, -1 \n" + " li %0, 1 \n" + " b 2f \n" + "1: beqz %3, 2f \n" + " li %0, %4 \n" + " dli $1, 0x0000000100000000 \n" + " daddu %1, %1, $1 \n" + "2: scd %1, %2 \n" + " beqz %1, 0b \n" + " .set pop \n" + : "=&r" (ret), "=&r" (tmp), "=m" (*sem) + : "r" (signal_pending(tsk)), "i" (-EINTR)); + + return ret; } -int __down_interruptible(struct semaphore * sem) +#else /* !CONFIG_CPU_HAS_LLDSCD */ + +static inline int waking_non_zero_interruptible(struct semaphore *sem, + struct task_struct *tsk) { - int ret = 0; - DOWN_VAR - DOWN_HEAD(TASK_INTERRUPTIBLE) + int waking, pending, ret = 0; + unsigned long flags; - ret = waking_non_zero_interruptible(sem, tsk); - if (ret) - { - if (ret == 1) - /* ret != 0 only if we get interrupted -arca */ - ret = 0; - break; + pending = signal_pending(tsk); + + spin_lock_irqsave(&semaphore_lock, flags); + waking = atomic_read(&sem->waking); + if (waking > 0) { + atomic_set(&sem->waking, waking - 1); + ret = 1; + } else if (pending) { + atomic_set(&sem->count, atomic_read(&sem->count) + 1); + ret = -EINTR; } - schedule(); - DOWN_TAIL(TASK_INTERRUPTIBLE) + spin_unlock_irqrestore(&semaphore_lock, flags); + return ret; } -int __down_trylock(struct semaphore * sem) +#endif /* !CONFIG_CPU_HAS_LLDSCD */ + +int __down_failed_interruptible(struct semaphore * sem) { - return waking_non_zero_trylock(sem); + struct task_struct *tsk = current; + wait_queue_t wait; + int ret = 0; + + init_waitqueue_entry(&wait, tsk); + __set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue_exclusive(&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 (;;) { + ret = waking_non_zero_interruptible(sem, tsk); + if (ret) { + if (ret == 1) + /* ret != 0 only if we get interrupted -arca */ + ret = 0; + break; + } + schedule(); + __set_current_state(TASK_INTERRUPTIBLE); + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&sem->wait, &wait); + + return ret; } + +EXPORT_SYMBOL(__down_failed_interruptible); Index: arch/mips64/kernel/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/setup.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/setup.c 4 Aug 2004 01:25:56 -0000 1.2 @@ -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,135 @@ /* 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 momenco_jaguar_atx_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_PMC_YOSEMITE + pmc_yosemite_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 +#ifdef CONFIG_MOMENCO_JAGUAR_ATX + momenco_jaguar_atx_setup(); +#endif strncpy(command_line, arcs_cmdline, CL_SIZE); memcpy(saved_command_line, command_line, CL_SIZE); @@ -385,11 +470,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); Index: arch/mips64/kernel/signal.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/signal.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/signal.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/signal.c 4 Aug 2004 01:25:56 -0000 1.2 @@ -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,41 +74,12 @@ /* * 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) +save_static_function(sys_rt_sigsuspend); +static_unused int _sys_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs) { sigset_t *unewset, saveset, newset; size_t sigsetsize; - save_static(®s); - /* XXX Don't preclude handling different sized sigset_t's. */ sigsetsize = regs.regs[5]; if (sigsetsize != sizeof(sigset_t)) @@ -136,47 +106,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 +115,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 +139,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 +160,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 +201,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 +227,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 +250,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 +271,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 +329,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 +339,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 +363,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 +392,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 Index: arch/mips64/kernel/signal32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/signal32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/signal32.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/signal32.c 4 Aug 2004 01:25:56 -0000 1.2 @@ -25,14 +25,20 @@ #include #include #include +#include + +/* + * Including would give use the 64-bit syscall numbers ... + */ +#define __NR_O32_sigreturn 4119 +#define __NR_O32_rt_sigreturn 4193 +#define __NR_O32_restart_syscall 4253 #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 +58,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 +67,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); @@ -114,12 +126,12 @@ /* * Atomically swap in the new signal mask, and wait for a signal. */ -asmlinkage inline int sys32_sigsuspend(abi64_no_regargs, struct pt_regs regs) +save_static_function(sys32_sigsuspend); +static_unused int _sys32_sigsuspend(abi64_no_regargs, struct pt_regs regs) { sigset32_t *uset; sigset_t newset, saveset; - save_static(®s); uset = (sigset32_t *) regs.regs[4]; if (get_sigset(&newset, uset)) return -EFAULT; @@ -141,13 +153,13 @@ } } -asmlinkage int sys32_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs) +save_static_function(sys32_rt_sigsuspend); +static_unused int _sys32_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs) { sigset32_t *uset; sigset_t newset, saveset; size_t sigsetsize; - save_static(®s); /* XXX Don't preclude handling different sized sigset_t's. */ sigsetsize = regs.regs[5]; if (sigsetsize != sizeof(sigset32_t)) @@ -190,8 +202,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 +220,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; } @@ -233,7 +241,7 @@ if (!access_ok(VERIFY_READ, uss, sizeof(*uss))) return -EFAULT; err |= __get_user(sp, &uss->ss_sp); - kss.ss_size = (long) sp; + kss.ss_sp = (void *) (long) sp; err |= __get_user(kss.ss_size, &uss->ss_size); err |= __get_user(kss.ss_flags, &uss->ss_flags); if (err) @@ -257,58 +265,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 +290,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 +315,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 +377,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 +401,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 +415,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 +445,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 +472,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 +526,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 +577,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 +585,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 +601,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 +817,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 +865,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 +881,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 +931,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; } Index: arch/mips64/kernel/smp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/smp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/smp.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/smp.c 4 Aug 2004 01:25:56 -0000 1.2 @@ -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. */ @@ -54,39 +52,6 @@ int __cpu_logical_map[NR_CPUS]; cycles_t cacheflush_time; -/* These are defined by the board-specific code. */ - -/* - * Cause the function described by call_data to be executed on the passed - * cpu. When the function has finished, increment the finished field of - * call_data. - */ -void core_send_ipi(int cpu, unsigned int action); - -/* - * Clear all undefined state in the cpu, set up sp and gp to the passed - * values, and kick the cpu into smp_bootstrap(); - */ -void prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp); - -/* - * After we've done initial boot, this function is called to allow the - * board code to clean up state, if needed - */ -void prom_init_secondary(void); - -/* - * Do whatever setup needs to be done for SMP at the board level. Return - * the number of cpus in the system, including this one - */ -int prom_setup_smp(void); - -void prom_smp_finish(void); - -static void smp_tune_scheduling(void) -{ -} - void __init smp_callin(void) { #if 0 @@ -95,33 +60,6 @@ #endif } -#ifndef CONFIG_SGI_IP27 -/* - * Hook for doing final board-specific setup after the generic smp setup - * is done - */ -asmlinkage void start_secondary(void) -{ - unsigned int cpu = smp_processor_id(); - - prom_init_secondary(); - per_cpu_trap_init(); - - /* - * XXX parity protection should be folded in here when it's converted - * to an option instead of something based on .cputype - */ - pgd_current[cpu] = init_mm.pgd; - cpu_data[cpu].udelay_val = loops_per_jiffy; - prom_smp_finish(); - printk("Slave cpu booted successfully\n"); - CPUMASK_SETB(cpu_online_map, cpu); - atomic_inc(&cpus_booted); - while (!atomic_read(&smp_commenced)); - cpu_idle(); -} -#endif /* CONFIG_SGI_IP27 */ - void __init smp_commence(void) { wmb(); @@ -138,7 +76,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 +108,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 +124,7 @@ if (wait) while (atomic_read(&data.finished) != cpus) barrier(); - spin_unlock(&call_lock); + spin_unlock(&smp_call_lock); return 0; } @@ -224,7 +162,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 +220,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 +252,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 +276,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); } Index: arch/mips64/kernel/syscall.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/syscall.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/syscall.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/syscall.c 4 Aug 2004 01:25:56 -0000 1.2 @@ -50,9 +50,11 @@ return res; } -#define COLOUR_ALIGN(addr,pgoff) \ - ((((addr)+SHMLBA-1)&~(SHMLBA-1)) + \ - (((pgoff)< TASK_SIZE - len) + return -ENOMEM; + if (addr & ~PAGE_MASK) + return -EINVAL; + if (flags & MAP_SHARED && pages_do_alias((pgoff << PAGE_SHIFT), addr)) + return -EINVAL; + + return addr; +} + asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, unsigned long prot, unsigned long flags, unsigned long fd, off_t offset) @@ -132,22 +147,22 @@ return error; } -asmlinkage int sys_fork(abi64_no_regargs, struct pt_regs regs) +save_static_function(sys_fork); +static_unused int _sys_fork(abi64_no_regargs, struct pt_regs regs) { int res; - save_static(®s); res = do_fork(SIGCHLD, regs.regs[29], ®s, 0); return res; } -asmlinkage int sys_clone(abi64_no_regargs, struct pt_regs regs) +save_static_function(sys_clone); +static_unused int _sys_clone(abi64_no_regargs, struct pt_regs regs) { unsigned long clone_flags; unsigned long newsp; int res; - save_static(®s); clone_flags = regs.regs[4]; newsp = regs.regs[5]; if (!newsp) @@ -186,12 +201,10 @@ return -ENOSYS; } -asmlinkage int -sys_sysmips(int cmd, long arg1, int arg2, int arg3) +asmlinkage int sys_sysmips(int cmd, long arg1, int arg2, int arg3) { - int *p; + int tmp, len; char *name; - int tmp, len, errno; switch(cmd) { case SETNAME: { @@ -207,7 +220,7 @@ return -EFAULT; down_write(&uts_sem); - strncpy(system_utsname.nodename, name, len); + strncpy(system_utsname.nodename, nodename, len); system_utsname.nodename[len] = '\0'; up_write(&uts_sem); return 0; @@ -223,7 +236,7 @@ return 0; case FLUSH_CACHE: - _flush_cache_l2(); + __flush_cache_all(); return 0; case MIPS_RDNVRAM: @@ -309,7 +322,7 @@ return sys_shmctl (first, second, (struct shmid_ds *) ptr); default: - return -EINVAL; + return -ENOSYS; } } Index: arch/mips64/kernel/time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/time.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/time.c 4 Aug 2004 01:25:56 -0000 1.2 @@ -1,9 +1,10 @@ /* * Copyright 2001 MontaVista Software Inc. * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * Copyright (c) 2003 Maciej W. Rozycki * * Common time service routines for MIPS machines. See - * Documents/MIPS/README.txt. + * Documentation/mips/time.README. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -17,10 +18,12 @@ #include #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,86 @@ 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 an R4k-compatible timer of a known frequency. + */ +static void c0_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 use solely as a high precision timer. */ +static void c0_hpt_init(unsigned int count) +{ + write_c0_count(read_c0_count() - count); +} + +/* For use both as a high precision timer and an interrupt source. */ +static void c0_hpt_timer_init(unsigned int count) +{ + count = read_c0_count() - count; + expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy; + write_c0_count(expirelo - cycles_per_jiffy); + write_c0_compare(expirelo); + write_c0_count(count); +} + +int (*mips_timer_state)(void); +void (*mips_timer_ack)(void); +unsigned int (*mips_hpt_read)(void); +void (*mips_hpt_init)(unsigned int); /* @@ -65,22 +156,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 +180,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 +213,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 +283,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 +309,7 @@ return res; } -unsigned long calibrate_div64_gettimeoffset(void) +static unsigned long calibrate_div64_gettimeoffset(void) { u32 count; unsigned long res, tmp; @@ -239,54 +319,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" + "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) + : "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 +381,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 +393,33 @@ * 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 long j; + 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; - - /* - * 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); + count = mips_hpt_read(); + mips_timer_ack(); - } + /* Update timerhi/timerlo for intra-jiffy calibration. */ + timerhi += count < timerlo; /* Wrap around */ + timerlo = count; /* * call the generic timer interrupt handling @@ -360,27 +431,59 @@ * 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; + * + * The first timer interrupt comes late as interrupts are + * enabled long after timers are initialized. Therefore the + * high precision timer is fast, leading to wrong gettimeoffset() + * calculations. We deal with it by setting it based on the + * number of its ticks between the second and the third interrupt. + * That is still somewhat imprecise, but it's a good estimate. + * --macro + */ + j = jiffies; + if (j < 4) { + static unsigned int prev_count; + static int hpt_initialized; + + switch (j) { + case 0: + timerhi = timerlo = 0; + mips_hpt_init(count); + break; + case 2: + prev_count = count; + break; + case 3: + if (!hpt_initialized) { + unsigned int c3 = 3 * (count - prev_count); + + timerhi = 0; + timerlo = c3; + mips_hpt_init(count - c3); + hpt_initialized = 1; + } + break; + default: + break; + } } #if !defined(CONFIG_SMP) @@ -391,7 +494,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 */ @@ -430,7 +533,9 @@ int cpu = smp_processor_id(); irq_enter(cpu, irq); - kstat.irqs[cpu][irq]++; + + if (cpu != 0) + kstat.irqs[cpu][irq]++; /* we keep interrupt disabled all the time */ local_timer_interrupt(irq, NULL, regs); @@ -446,7 +551,7 @@ * * 1) board_time_init() - * a) (optional) set up RTC routines, - * b) (optional) calibrate and set the mips_counter_frequency + * b) (optional) calibrate and set the mips_hpt_frequency * (only needed if you intended to use fixed_rate_gettimeoffset * or use cpu counter as timer interrupt source) * 2) setup xtime based on rtc_get_time(). @@ -458,73 +563,144 @@ * 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_hpt_frequency; static struct irqaction timer_irqaction = { - timer_interrupt, - SA_INTERRUPT, - 0, - "timer", - NULL, - NULL}; + .handler = timer_interrupt, + .flags = SA_INTERRUPT, + .name = "timer", +}; + +static unsigned int __init calibrate_hpt(void) +{ + u64 frequency; + u32 hpt_start, hpt_end, hpt_count, hz; + + const int loops = HZ / 10; + int log_2_loops = 0; + int i; + + /* + * We want to calibrate for 0.1s, but to avoid a 64-bit + * division we round the number of loops up to the nearest + * power of 2. + */ + while (loops > 1 << log_2_loops) + log_2_loops++; + i = 1 << log_2_loops; + + /* + * Wait for a rising edge of the timer interrupt. + */ + while (mips_timer_state()); + while (!mips_timer_state()); + + /* + * Now see how many high precision timer ticks happen + * during the calculated number of periods between timer + * interrupts. + */ + hpt_start = mips_hpt_read(); + do { + while (mips_timer_state()); + while (!mips_timer_state()); + } while (--i); + hpt_end = mips_hpt_read(); + + hpt_count = hpt_end - hpt_start; + hz = HZ; + frequency = (u64)hpt_count * (u64)hz; + + return frequency >> log_2_loops; +} 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_hpt_frequency && !mips_timer_state) { + /* 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. Or we can get it. */ + if (!mips_hpt_read) { + /* No external high precision timer -- use R4k. */ + mips_hpt_read = c0_hpt_read; + + if (mips_timer_state) + mips_hpt_init = c0_hpt_init; + else { + /* No external timer interrupt -- use R4k. */ + mips_hpt_init = c0_hpt_timer_init; + mips_timer_ack = c0_timer_ack; + } + } + if (!mips_hpt_frequency) + mips_hpt_frequency = calibrate_hpt(); - /* caclulate cache parameters */ - if (mips_counter_frequency) { - u32 count; - - 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 = mips_counter_frequency / 100000; - sll32_usecs_per_cycle = 0xffffffff / sll32_usecs_per_cycle; - sll32_usecs_per_cycle *= 10; + do_gettimeoffset = fixed_rate_gettimeoffset; - /* - * 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); - } + /* Calculate cache parameters. */ + cycles_per_jiffy = (mips_hpt_frequency + HZ / 2) / HZ; + + /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */ + do_div64_32(sll32_usecs_per_cycle, + 1000000, mips_hpt_frequency / 2, + mips_hpt_frequency); + + /* Report the high precision timer rate for a reference. */ + printk("Using %u.%03u MHz high precision timer.\n", + ((mips_hpt_frequency + 500) / 1000) / 1000, + ((mips_hpt_frequency + 500) / 1000) % 1000); + } + + 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 +713,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 +736,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 +753,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); Index: arch/mips64/kernel/traps.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/traps.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/traps.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/traps.c 4 Aug 2004 01:25:56 -0000 1.2 @@ -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", @@ -234,6 +232,7 @@ printk("epc : %016lx %s\nbadvaddr: %016lx\n", regs->cp0_epc, print_tainted(), regs->cp0_badvaddr); printk("Status : %08x [ ", (unsigned int) regs->cp0_status); + if (regs->cp0_status & ST0_KX) printk("KX "); if (regs->cp0_status & ST0_SX) printk("SX "); if (regs->cp0_status & ST0_UX) printk("UX "); @@ -249,6 +248,7 @@ printk("]\n"); printk("Cause : %08x\n", (unsigned int) regs->cp0_cause); + printk("PrId : %08x\n", read_c0_prid()); } void show_registers(struct pt_regs *regs) @@ -336,7 +336,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 +367,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 +395,153 @@ 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; + + regs->regs[(opcode & RT) >> 16] = value; + + compute_return_epc(regs); + return; - if (compute_return_epc(regs)) +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; + } + + return -EFAULT; /* Strange things going on ... */ +} + +asmlinkage void do_ov(struct pt_regs *regs) +{ + siginfo_t info; info.si_code = FPE_INTOVF; info.si_signo = SIGFPE; @@ -444,41 +585,21 @@ /* 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; siginfo_t info; + die_if_kernel("Break instruction in kernel code", regs); + if (get_insn_opcode(regs, &opcode)) return; @@ -520,7 +641,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 +672,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 +682,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 +758,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 +776,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 +786,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; Index: arch/mips64/kernel/unaligned.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/kernel/unaligned.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/kernel/unaligned.c 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/mips64/kernel/unaligned.c 4 Aug 2004 01:25:56 -0000 1.2 @@ -40,7 +40,7 @@ * Below a little program to play around with this feature. * * #include - * #include + * #include * * struct foo { * unsigned char bar[8]; @@ -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 + */ } Index: arch/mips64/lib/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/lib/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/lib/Makefile 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/lib/Makefile 4 Aug 2004 01:25:56 -0000 1.2 @@ -6,12 +6,15 @@ L_TARGET = lib.a -obj-y += csum_partial.o csum_partial_copy.o dump_tlb.o rtc-std.o \ - rtc-no.o memset.o memcpy.o strlen_user.o strncpy_user.o \ - strnlen_user.o watch.o +obj-y += csum_partial.o csum_partial_copy.o \ + promlib.o rtc-std.o rtc-no.o memcpy.o \ + memset.o watch.o strlen_user.o \ + strncpy_user.o dump_tlb.o strnlen_user.o + +export-objs := rtc-std.o rtc-no.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 Index: arch/mips64/lib/dump_tlb.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/lib/dump_tlb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/lib/dump_tlb.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/lib/dump_tlb.c 4 Aug 2004 01:25:56 -0000 1.2 @@ -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 "); Index: arch/mips64/lib/ide-no.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/lib/ide-no.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/lib/ide-no.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/lib/ide-no.c 4 Aug 2004 01:25:56 -0000 1.2 @@ -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 }; Index: arch/mips64/lib/ide-std.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/lib/ide-std.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/lib/ide-std.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/lib/ide-std.c 4 Aug 2004 01:25:56 -0000 1.2 @@ -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 }; Index: arch/mips64/lib/kbd-no.c =================================================================== RCS file: arch/mips64/lib/kbd-no.c diff -N arch/mips64/lib/kbd-no.c --- arch/mips64/lib/kbd-no.c 22 Jul 2004 19:49:22 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 -}; Index: arch/mips64/lib/memcpy.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/lib/memcpy.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/lib/memcpy.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/lib/memcpy.S 4 Aug 2004 01:25:56 -0000 1.2 @@ -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 Index: arch/mips64/lib/rtc-no.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/lib/rtc-no.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/lib/rtc-no.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/lib/rtc-no.c 4 Aug 2004 01:25:56 -0000 1.2 @@ -9,25 +9,25 @@ * Copyright (C) 1998, 2001 by Ralf Baechle */ #include +#include #include -static unsigned char no_rtc_read_data(unsigned long addr) +static unsigned int shouldnt_happen(void) { - panic("no_rtc_read_data called - shouldn't happen."); -} + static int called; -static void no_rtc_write_data(unsigned char data, unsigned long addr) -{ - panic("no_rtc_write_data called - shouldn't happen."); -} + if (!called) { + called = 1; + printk(KERN_DEBUG "RTC functions called - shouldn't happen\n"); + } -static int no_rtc_bcd_mode(void) -{ - panic("no_rtc_bcd_mode called - shouldn't happen."); + return 0; } struct rtc_ops no_rtc_ops = { - &no_rtc_read_data, - &no_rtc_write_data, - &no_rtc_bcd_mode + .rtc_read_data = (void *) &shouldnt_happen, + .rtc_write_data = (void *) &shouldnt_happen, + .rtc_bcd_mode = (void *) &shouldnt_happen }; + +EXPORT_SYMBOL(rtc_ops); Index: arch/mips64/lib/rtc-std.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/lib/rtc-std.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/lib/rtc-std.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/lib/rtc-std.c 4 Aug 2004 01:25:56 -0000 1.2 @@ -5,8 +5,9 @@ * * RTC routines for PC style attached Dallas chip. * - * Copyright (C) 1998 by Ralf Baechle + * Copyright (C) 1998, 2001 by Ralf Baechle */ +#include #include #include @@ -32,3 +33,5 @@ &std_rtc_write_data, &std_rtc_bcd_mode }; + +EXPORT_SYMBOL(rtc_ops); Index: arch/mips64/lib/strlen_user.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/lib/strlen_user.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/lib/strlen_user.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/lib/strlen_user.S 4 Aug 2004 01:25:56 -0000 1.2 @@ -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 Index: arch/mips64/lib/strncpy_user.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/lib/strncpy_user.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/lib/strncpy_user.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/lib/strncpy_user.S 4 Aug 2004 01:25:56 -0000 1.2 @@ -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 Index: arch/mips64/lib/strnlen_user.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/lib/strnlen_user.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/lib/strnlen_user.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/lib/strnlen_user.S 4 Aug 2004 01:25:56 -0000 1.2 @@ -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 Index: arch/mips64/mm/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/mm/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/mm/Makefile 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/mm/Makefile 4 Aug 2004 01:25:56 -0000 1.2 @@ -6,27 +6,30 @@ O_TARGET := mm.o -export-objs += umap.o -obj-y := extable.o init.o fault.o loadmmu.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) += 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 +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_RM9000) += 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_RM7000_CPU_SCACHE) += 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 Index: arch/mips64/mm/andes.c =================================================================== RCS file: arch/mips64/mm/andes.c diff -N arch/mips64/mm/andes.c --- arch/mips64/mm/andes.c 22 Jul 2004 19:49:22 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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? */ -} Index: arch/mips64/mm/c-mips64.c =================================================================== RCS file: arch/mips64/mm/c-mips64.c diff -N arch/mips64/mm/c-mips64.c --- arch/mips64/mm/c-mips64.c 22 Jul 2004 19:49:22 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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(); -} Index: arch/mips64/mm/c-sb1.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/mm/c-sb1.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/mm/c-sb1.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/mm/c-sb1.c 4 Aug 2004 01:25:56 -0000 1.2 @@ -1,7 +1,7 @@ /* * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) - * 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 @@ -25,6 +25,8 @@ #include #include +extern void sb1_dma_init(void); + /* These are probed at ld_mmu time */ static unsigned long icache_size; static unsigned long dcache_size; @@ -33,6 +35,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 +43,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 +59,224 @@ * 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); } -static inline void local_sb1___flush_icache_all(void) +#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; + + addr &= PAGE_MASK; + 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 +293,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 +345,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) -#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 @@ -364,64 +451,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 +520,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 +529,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 +549,55 @@ */ void ld_mmu_sb1(void) { + extern char except_vec2_sb1; + extern char handle_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); + memcpy((void *)KSEG1ADDR(&handle_vec2_sb1), &handle_vec2_sb1, 0x80); + probe_cache_sizes(); - _clear_page = sb1_clear_page; - _copy_page = sb1_copy_page; +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS + sb1_dma_init(); +#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_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_data_cache_page = (void *) sb1_nop; - /* None of these are needed for the sb1 */ - _flush_cache_page = (void *) sb1_nop; + /* This implies an Icache flush too, so can't be nop'ed */ + _flush_cache_page = sb1_flush_cache_page; - _flush_cache_sigtramp = sb1_flush_cache_sigtramp; - _flush_icache_all = sb1_flush_icache_all; + /* Full flushes */ + ___flush_cache_all = sb1___flush_cache_all; - change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); + 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(); } Index: arch/mips64/mm/fault.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/mm/fault.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/mm/fault.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/mm/fault.c 4 Aug 2004 01:25:56 -0000 1.2 @@ -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; @@ -267,5 +266,5 @@ return; vmalloc_fault: - panic("Pagefault for kernel virtual memory"); + die("Pagefault for kernel virtual memory", regs); } Index: arch/mips64/mm/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/mm/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/mm/init.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/mm/init.c 4 Aug 2004 01:25:59 -0000 1.2 @@ -63,7 +63,7 @@ { pgd_t *ret, *init; - ret = (pgd_t *) __get_free_pages(GFP_KERNEL, 1); + ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER); if (ret) { init = pgd_offset(&init_mm, 0); pgd_init((unsigned long)ret); @@ -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) Index: arch/mips64/mm/loadmmu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/mm/loadmmu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/mm/loadmmu.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/mm/loadmmu.c 4 Aug 2004 01:26:01 -0000 1.2 @@ -4,86 +4,102 @@ * 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); -void (*_copy_page)(void * to, void * from); /* Cache operations. */ void (*_flush_cache_all)(void); 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) || defined(CONFIG_CPU_RM9000) 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 +110,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."); } } Index: arch/mips64/mm/pg-mips64.c =================================================================== RCS file: arch/mips64/mm/pg-mips64.c diff -N arch/mips64/mm/pg-mips64.c --- arch/mips64/mm/pg-mips64.c 22 Jul 2004 19:49:22 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS #define SB1_PREF_LOAD_STREAMED_HINT "0" @@ -31,8 +41,11 @@ #define SB1_PREF_STORE_STREAMED_HINT "5" #endif -/* These are the functions hooked by the memory management function pointers */ -void sb1_clear_page(void *page) +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS +static inline void clear_page_cpu(void *page) +#else +void clear_page(void *page) +#endif { /* * JDCXXX - This should be bottlenecked by the write buffer, but these @@ -49,15 +62,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" @@ -67,7 +84,11 @@ } -void sb1_copy_page(void *to, void *from) +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS +static inline void copy_page_cpu(void *to, void *from) +#else +void copy_page(void *to, void *from) +#endif { /* * This should be optimized in assembly...can't use ld/sd, though, @@ -87,12 +108,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 +124,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 +146,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 clear_page(void *page) +{ + int cpu = smp_processor_id(); + + /* if the page is above Kseg0, use old way */ + if (KSEGX(page) != K0BASE) + return clear_page_cpu(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 copy_page(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 copy_page_cpu(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 /* CONFIG_SIBYTE_DMA_PAGEOPS */ Index: arch/mips64/mm/r4xx0.c =================================================================== RCS file: arch/mips64/mm/r4xx0.c diff -N arch/mips64/mm/r4xx0.c --- arch/mips64/mm/r4xx0.c 22 Jul 2004 19:49:22 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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(); -} Index: arch/mips64/mm/r5k-sc.c =================================================================== RCS file: arch/mips64/mm/r5k-sc.c diff -N arch/mips64/mm/r5k-sc.c --- arch/mips64/mm/r5k-sc.c 22 Jul 2004 19:49:22 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; - } -} Index: arch/mips64/mm/tlb-dbg-r4k.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/mm/tlb-dbg-r4k.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/mm/tlb-dbg-r4k.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/mm/tlb-dbg-r4k.c 4 Aug 2004 01:26:01 -0000 1.2 @@ -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(); Index: arch/mips64/mm/tlb-glue-r4k.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/mm/tlb-glue-r4k.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/mm/tlb-glue-r4k.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/mm/tlb-glue-r4k.S 4 Aug 2004 01:26:01 -0000 1.2 @@ -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 Index: arch/mips64/mm/tlb-r4k.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/mm/tlb-r4k.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/mm/tlb-r4k.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/mm/tlb-r4k.c 4 Aug 2004 01:26:01 -0000 1.2 @@ -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,99 @@ 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); } } /* + * Remove one kernel space TLB entry. This entry is assumed to be marked + * global so we don't do the ASID thing. + */ +void local_flush_tlb_one(unsigned long page) +{ + unsigned long flags; + int oldpid, idx; + + page &= (PAGE_MASK << 1); + oldpid = read_c0_entryhi() & ASID_MASK; + + local_irq_save(flags); + write_c0_entryhi(page); + BARRIER; + tlb_probe(); + BARRIER; + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + if (idx >= 0) { + /* Make sure all entries differ. */ + write_c0_entryhi(KSEG0+idx*0x2000); + tlb_write_indexed(); + } + BARRIER; + 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 +219,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 +251,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 +264,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 +304,64 @@ 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; + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int config1; - if (!(config & (1 << 31))) { - /* - * Not a MIPS64 complainant CPU. - * Config 1 register not supported, we assume R4k style. - */ - mips_cpu.tlbsize = 48; - } else { - config1 = read_mips32_cp0_config1(); - if (!((config >> 7) & 3)) - panic("No MMU present"); - else - mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1; - } + /* + * If this isn't a MIPS32 / MIPS64 compliant CPU. Config 1 register + * is not supported, we assume R4k style. Cpu probing already figured + * out the number of tlb entries. + */ + if ((c->processor_id & 0xff0000) == PRID_COMP_LEGACY) + return; - printk("Number of TLB entries %d.\n", mips_cpu.tlbsize); + config1 = read_c0_config1(); + if (!((config1 >> 7) & 3)) + panic("No MMU present"); + + c->tlbsize = ((config1 >> 25) & 0x3f) + 1; } 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_DEFAULT_MASK); + 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); } Index: arch/mips64/mm/tlb-sb1.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/mm/tlb-sb1.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/mm/tlb-sb1.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/mm/tlb-sb1.c 4 Aug 2004 01:26:02 -0000 1.2 @@ -1,7 +1,7 @@ /* * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) - * 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 @@ -18,10 +18,15 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include +#include #include #include #include +extern void except_vec1_sb1(void); + +#define UNIQUE_ENTRYHI(idx) (KSEG0 + ((idx) << (PAGE_SHIFT + 1))) + /* Dump the current entry* and pagemask registers */ static inline void dump_cur_tlb_regs(void) { @@ -31,8 +36,7 @@ __asm__ __volatile__ ( ".set push \n" ".set noreorder \n" - "#.set mips64 \n" - ".set mips4 \n" + ".set mips64 \n" ".set noat \n" " tlbr \n" " dmfc0 $1, $10 \n" @@ -46,13 +50,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, @@ -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,21 @@ 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); + + entry = read_c0_wired(); + while (entry < current_cpu_data.tlbsize) { + write_c0_entryhi(UNIQUE_ENTRYHI(entry)); + write_c0_index(entry); tlb_write_indexed(); + entry++; } - set_entryhi(old_ctx); - __restore_flags(flags); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); } @@ -117,7 +116,7 @@ * Use increments of the maximum page size (16MB), and check for duplicate * entries before doing a given write. Then, when we're safe from collisions * with the firmware, go back and give all the entries invalid addresses with - * the normal flush routine. + * the normal flush routine. Wired entries will be killed as well! */ void sb1_sanitize_tlb(void) { @@ -126,15 +125,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,103 +148,109 @@ 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(UNIQUE_ENTRYHI(idx)); + 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(UNIQUE_ENTRYHI(idx)); tlb_write_indexed(); finish: - set_entryhi(oldpid); + write_c0_entryhi(oldpid); } - __restore_flags(flags); + local_irq_restore(flags); } +/* + * Remove one kernel space TLB entry. This entry is assumed to be marked + * global so we don't do the ASID thing. + */ +void local_flush_tlb_one(unsigned long page) +{ + unsigned long flags; + int oldpid, idx; + + page &= (PAGE_MASK << 1); + oldpid = read_c0_entryhi() & ASID_MASK; + + local_irq_save(flags); + write_c0_entryhi(page); + tlb_probe(); + idx = read_c0_index(); + if (idx >= 0) { + /* Make sure all entries differ. */ + write_c0_entryhi(UNIQUE_ENTRYHI(idx)); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + tlb_write_indexed(); + } + + write_c0_entryhi(oldpid); + local_irq_restore(flags); +} /* All entries common to a mm share an asid. To effectively flush 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 +264,52 @@ 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); +} + +void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, + unsigned long entryhi, unsigned long pagemask) +{ + unsigned long flags; + unsigned long wired; + unsigned long old_pagemask; + unsigned long old_ctx; + + local_irq_save(flags); + old_ctx = read_c0_entryhi() & 0xff; + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); + write_c0_wired(wired + 1); + write_c0_index(wired); + + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); + tlb_write_indexed(); + + write_c0_entryhi(old_ctx); + write_c0_pagemask(old_pagemask); + + local_flush_tlb_all(); + local_irq_restore(flags); } /* @@ -297,10 +319,8 @@ */ void sb1_tlb_init(void) { - u32 config1; - - config1 = read_mips32_cp0_config1(); - mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1; + write_c0_pagemask(PM_DEFAULT_MASK); + write_c0_wired(0); /* * We don't know what state the firmware left the TLB's in, so this is @@ -308,5 +328,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); } Index: arch/mips64/mm/tlbex-r4k.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/mips64/mm/tlbex-r4k.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/mips64/mm/tlbex-r4k.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/mips64/mm/tlbex-r4k.S 4 Aug 2004 01:26:02 -0000 1.2 @@ -10,11 +10,19 @@ #include #include #include + #include +#include #include #include #include #include +#include + +#define PGD_INDX_MASK ((_PTRS_PER_PGD - 1) << _PGD_T_LOG2) +#define PMD_INDX_MASK ((_PTRS_PER_PMD - 1) << _PMD_T_LOG2) +#define PTE_INDX_MASK ((_PTRS_PER_PTE - 1) << _PTE_T_LOG2) +#define PTEP_INDX_MASK ((_PTRS_PER_PTE >> 1 - 1) << (_PTE_T_LOG2 + 1)) .data .comm pgd_current, NR_CPUS * 8, 8 @@ -34,17 +42,17 @@ #endif bltz \tmp, \kaddr ld \ptr, (\ptr) - dsrl \tmp, (PGDIR_SHIFT-3) # get pgd offset in bytes - andi \tmp, ((PTRS_PER_PGD - 1)<<3) + dsrl \tmp, PGDIR_SHIFT - 3 # get pgd offset in bytes + andi \tmp, PGD_INDX_MASK daddu \ptr, \tmp # add in pgd offset dmfc0 \tmp, CP0_BADVADDR ld \ptr, (\ptr) # get pmd pointer - dsrl \tmp, (PMD_SHIFT-3) # get pmd offset in bytes - andi \tmp, ((PTRS_PER_PMD - 1)<<3) + dsrl \tmp, PMD_SHIFT - 3 # get pmd offset in bytes + andi \tmp, PMD_INDX_MASK daddu \ptr, \tmp # add in pmd offset dmfc0 \tmp, CP0_XCONTEXT ld \ptr, (\ptr) # get pte pointer - andi \tmp, 0xff0 # get pte offset + andi \tmp, PTEP_INDX_MASK # get pte offset daddu \ptr, \tmp .endm @@ -64,7 +72,7 @@ */ dsubu \tmp, \tmp, \ptr dla \ptr, kptbl - dsrl \tmp, (PAGE_SHIFT+1) # get vpn2 + dsrl \tmp, _PAGE_SHIFT + 1 # get vpn2 dsll \tmp, 4 # byte offset of pte daddu \ptr, \ptr, \tmp @@ -72,8 +80,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 +105,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 +125,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 @@ -125,9 +151,11 @@ ld k0, 0(k1) # get even pte ld k1, 8(k1) # get odd pte PTE_RELOAD k0 k1 + rm9000_tlb_hazard b 1f tlbwr 1: nop + rm9000_tlb_hazard eret 9: # handle the vmalloc range @@ -135,12 +163,15 @@ ld k0, 0(k1) # get even pte ld k1, 8(k1) # get odd pte PTE_RELOAD k0 k1 + rm9000_tlb_hazard b 1f tlbwr 1: nop + rm9000_tlb_hazard eret END(handle_vec1_r4k) + __INIT /* @@ -164,8 +195,10 @@ ld k0, 0(k1) # get even pte ld k1, 8(k1) # get odd pte PTE_RELOAD k0 k1 + rm9000_tlb_hazard nop tlbwr + rm9000_tlb_hazard eret 9: # handle the vmalloc range @@ -173,8 +206,10 @@ ld k0, 0(k1) # get even pte ld k1, 8(k1) # get odd pte PTE_RELOAD k0 k1 + rm9000_tlb_hazard nop tlbwr + rm9000_tlb_hazard eret END(handle_vec1_r10k) Index: arch/mips64/mm/umap.c =================================================================== RCS file: arch/mips64/mm/umap.c diff -N arch/mips64/mm/umap.c --- arch/mips64/mm/umap.c 22 Jul 2004 19:49:22 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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; -} Index: arch/parisc/config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/config.in 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/parisc/config.in 4 Aug 2004 01:26:02 -0000 1.2 @@ -46,6 +46,10 @@ comment 'General options' bool 'Symmetric multi-processing support' CONFIG_SMP +if [ "$CONFIG_SMP" = "y" ]; then + int 'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32 +fi + bool 'Chassis LCD and LED support' CONFIG_CHASSIS_LCD_LED bool 'Kernel Debugger support' CONFIG_KWDB @@ -113,7 +117,6 @@ 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 @@ -137,7 +140,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 @@ -195,6 +198,10 @@ #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ + +int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 + endmenu +source crypto/Config.in source lib/Config.in Index: arch/parisc/defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/defconfig 22 Jul 2004 19:49:23 -0000 1.1 +++ arch/parisc/defconfig 4 Aug 2004 01:26:02 -0000 1.2 @@ -245,7 +245,6 @@ # CONFIG_IDEDMA_AUTO is not set # CONFIG_IDEDMA_IVB 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 Index: arch/parisc/kernel/cache.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/kernel/cache.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/kernel/cache.c 22 Jul 2004 19:49:25 -0000 1.1 +++ arch/parisc/kernel/cache.c 4 Aug 2004 01:26:02 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: cache.c,v 1.1 2004/07/22 19:49:25 joff Exp $ +/* $Id: cache.c,v 1.2 2004/08/04 01:26:02 joff 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 @@ -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) { + 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; + } - 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; + } } + Index: arch/parisc/kernel/ccio-dma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/kernel/ccio-dma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/kernel/ccio-dma.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/kernel/ccio-dma.c 4 Aug 2004 01:26:02 -0000 1.2 @@ -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++; Index: arch/parisc/kernel/ccio-rm-dma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/kernel/ccio-rm-dma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/kernel/ccio-rm-dma.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/kernel/ccio-rm-dma.c 4 Aug 2004 01:26:02 -0000 1.2 @@ -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++; Index: arch/parisc/kernel/drivers.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/kernel/drivers.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/kernel/drivers.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/kernel/drivers.c 4 Aug 2004 01:26:02 -0000 1.2 @@ -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); } Index: arch/parisc/kernel/entry.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/kernel/entry.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/kernel/entry.S 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/kernel/entry.S 4 Aug 2004 01:26:02 -0000 1.2 @@ -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 /* Index: arch/parisc/kernel/hardware.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/kernel/hardware.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/kernel/hardware.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/kernel/hardware.c 4 Aug 2004 01:26:02 -0000 1.2 @@ -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"}, Index: arch/parisc/kernel/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/kernel/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/kernel/head.S 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/kernel/head.S 4 Aug 2004 01:26:02 -0000 1.2 @@ -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) */ Index: arch/parisc/kernel/ioctl32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/kernel/ioctl32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/kernel/ioctl32.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/kernel/ioctl32.c 4 Aug 2004 01:26:02 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ioctl32.c,v 1.1 2004/07/22 19:49:24 joff Exp $ +/* $Id: ioctl32.c,v 1.2 2004/08/04 01:26:02 joff Exp $ * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) @@ -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) Index: arch/parisc/kernel/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/kernel/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/kernel/irq.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/kernel/irq.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -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 */ Index: arch/parisc/kernel/parisc_ksyms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/kernel/parisc_ksyms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/kernel/parisc_ksyms.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/kernel/parisc_ksyms.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -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); Index: arch/parisc/kernel/pci-dma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/kernel/pci-dma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/kernel/pci-dma.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/kernel/pci-dma.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -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 = { Index: arch/parisc/kernel/pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/kernel/pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/kernel/pci.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/kernel/pci.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: pci.c,v 1.1 2004/07/22 19:49:24 joff Exp $ +/* $Id: pci.c,v 1.2 2004/08/04 01:26:03 joff 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 Index: arch/parisc/kernel/perf.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/kernel/perf.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/kernel/perf.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/kernel/perf.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -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; Index: arch/parisc/kernel/processor.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/kernel/processor.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/kernel/processor.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/kernel/processor.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: processor.c,v 1.1 2004/07/22 19:49:24 joff Exp $ +/* $Id: processor.c,v 1.2 2004/08/04 01:26:03 joff Exp $ * * Initial setup-routines for HP 9000 based hardware. * @@ -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) { Index: arch/parisc/kernel/sba_iommu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/kernel/sba_iommu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/kernel/sba_iommu.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/kernel/sba_iommu.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -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", Index: arch/parisc/kernel/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/kernel/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/kernel/setup.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/kernel/setup.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.1 2004/07/22 19:49:24 joff Exp $ +/* $Id: setup.c,v 1.2 2004/08/04 01:26:03 joff Exp $ * * Initial setup-routines for HP 9000 based hardware. * Index: arch/parisc/kernel/smp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/kernel/smp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/kernel/smp.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/kernel/smp.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -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); Index: arch/parisc/kernel/traps.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/kernel/traps.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/kernel/traps.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/kernel/traps.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -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); } Index: arch/parisc/kernel/unaligned.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/kernel/unaligned.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/kernel/unaligned.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/kernel/unaligned.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -1,8 +1,9 @@ -/* $Id: unaligned.c,v 1.1 2004/07/22 19:49:24 joff Exp $ +/* $Id: unaligned.c,v 1.2 2004/08/04 01:26:03 joff Exp $ * * 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; } Index: arch/parisc/lib/checksum.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/lib/checksum.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/lib/checksum.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/lib/checksum.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -14,7 +14,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * $Id: checksum.c,v 1.1 2004/07/22 19:49:24 joff Exp $ + * $Id: checksum.c,v 1.2 2004/08/04 01:26:03 joff Exp $ */ #include #include Index: arch/parisc/math-emu/dfadd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/dfadd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/dfadd.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/dfadd.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/dfadd.c $Revision: 1.1 $ + * @(#) pa/spmath/dfadd.c $Revision: 1.2 $ * * Purpose: * Double_add: add two double precision values. Index: arch/parisc/math-emu/dfcmp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/dfcmp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/dfcmp.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/dfcmp.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/dfcmp.c $Revision: 1.1 $ + * @(#) pa/spmath/dfcmp.c $Revision: 1.2 $ * * Purpose: * dbl_cmp: compare two values Index: arch/parisc/math-emu/dfdiv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/dfdiv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/dfdiv.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/dfdiv.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/dfdiv.c $Revision: 1.1 $ + * @(#) pa/spmath/dfdiv.c $Revision: 1.2 $ * * Purpose: * Double Precision Floating-point Divide Index: arch/parisc/math-emu/dfmpy.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/dfmpy.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/dfmpy.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/dfmpy.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/dfmpy.c $Revision: 1.1 $ + * @(#) pa/spmath/dfmpy.c $Revision: 1.2 $ * * Purpose: * Double Precision Floating-point Multiply Index: arch/parisc/math-emu/dfrem.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/dfrem.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/dfrem.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/dfrem.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/dfrem.c $Revision: 1.1 $ + * @(#) pa/spmath/dfrem.c $Revision: 1.2 $ * * Purpose: * Double Precision Floating-point Remainder Index: arch/parisc/math-emu/dfsqrt.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/dfsqrt.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/dfsqrt.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/dfsqrt.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/dfsqrt.c $Revision: 1.1 $ + * @(#) pa/spmath/dfsqrt.c $Revision: 1.2 $ * * Purpose: * Double Floating-point Square Root Index: arch/parisc/math-emu/dfsub.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/dfsub.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/dfsub.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/dfsub.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/dfsub.c $Revision: 1.1 $ + * @(#) pa/spmath/dfsub.c $Revision: 1.2 $ * * Purpose: * Double_subtract: subtract two double precision values. Index: arch/parisc/math-emu/driver.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/driver.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/driver.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/driver.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -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); Index: arch/parisc/math-emu/fcnvff.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/fcnvff.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/fcnvff.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/fcnvff.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/fcnvff.c $Revision: 1.1 $ + * @(#) pa/spmath/fcnvff.c $Revision: 1.2 $ * * Purpose: * Single Floating-point to Double Floating-point Index: arch/parisc/math-emu/fcnvfu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/fcnvfu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/fcnvfu.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/fcnvfu.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/fcnvfu.c $Revision: 1.1 $ + * @(#) pa/spmath/fcnvfu.c $Revision: 1.2 $ * * Purpose: * Floating-point to Unsigned Fixed-point Converts Index: arch/parisc/math-emu/fcnvfut.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/fcnvfut.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/fcnvfut.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/fcnvfut.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/fcnvfut.c $Revision: 1.1 $ + * @(#) pa/spmath/fcnvfut.c $Revision: 1.2 $ * * Purpose: * Floating-point to Unsigned Fixed-point Converts with Truncation Index: arch/parisc/math-emu/fcnvfx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/fcnvfx.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/fcnvfx.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/fcnvfx.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/fcnvfx.c $Revision: 1.1 $ + * @(#) pa/spmath/fcnvfx.c $Revision: 1.2 $ * * Purpose: * Single Floating-point to Single Fixed-point Index: arch/parisc/math-emu/fcnvfxt.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/fcnvfxt.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/fcnvfxt.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/fcnvfxt.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/fcnvfxt.c $Revision: 1.1 $ + * @(#) pa/spmath/fcnvfxt.c $Revision: 1.2 $ * * Purpose: * Single Floating-point to Single Fixed-point /w truncated result Index: arch/parisc/math-emu/fcnvuf.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/fcnvuf.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/fcnvuf.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/fcnvuf.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/fcnvuf.c $Revision: 1.1 $ + * @(#) pa/spmath/fcnvuf.c $Revision: 1.2 $ * * Purpose: * Fixed point to Floating-point Converts Index: arch/parisc/math-emu/fcnvxf.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/fcnvxf.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/fcnvxf.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/fcnvxf.c 4 Aug 2004 01:26:03 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/fcnvxf.c $Revision: 1.1 $ + * @(#) pa/spmath/fcnvxf.c $Revision: 1.2 $ * * Purpose: * Single Fixed-point to Single Floating-point Index: arch/parisc/math-emu/float.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/float.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/float.h 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/float.h 4 Aug 2004 01:26:04 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/float.h $Revision: 1.1 $ + * @(#) pa/spmath/float.h $Revision: 1.2 $ * * Purpose: * <> Index: arch/parisc/math-emu/fmpyfadd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/fmpyfadd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/fmpyfadd.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/fmpyfadd.c 4 Aug 2004 01:26:05 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/fmpyfadd.c $Revision: 1.1 $ + * @(#) pa/spmath/fmpyfadd.c $Revision: 1.2 $ * * Purpose: * Double Floating-point Multiply Fused Add Index: arch/parisc/math-emu/fpu.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/fpu.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/fpu.h 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/fpu.h 4 Aug 2004 01:26:05 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/fp/fpu.h $Revision: 1.1 $ + * @(#) pa/fp/fpu.h $Revision: 1.2 $ * * Purpose: * <> Index: arch/parisc/math-emu/fpudispatch.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/fpudispatch.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/fpudispatch.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/fpudispatch.c 4 Aug 2004 01:26:05 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/fp/fpudispatch.c $Revision: 1.1 $ + * @(#) pa/fp/fpudispatch.c $Revision: 1.2 $ * * 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); Index: arch/parisc/math-emu/sfadd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/sfadd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/sfadd.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/sfadd.c 4 Aug 2004 01:26:05 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/sfadd.c $Revision: 1.1 $ + * @(#) pa/spmath/sfadd.c $Revision: 1.2 $ * * Purpose: * Single_add: add two single precision values. Index: arch/parisc/math-emu/sfcmp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/sfcmp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/sfcmp.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/sfcmp.c 4 Aug 2004 01:26:06 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/sfcmp.c $Revision: 1.1 $ + * @(#) pa/spmath/sfcmp.c $Revision: 1.2 $ * * Purpose: * sgl_cmp: compare two values Index: arch/parisc/math-emu/sfdiv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/sfdiv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/sfdiv.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/sfdiv.c 4 Aug 2004 01:26:06 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/sfdiv.c $Revision: 1.1 $ + * @(#) pa/spmath/sfdiv.c $Revision: 1.2 $ * * Purpose: * Single Precision Floating-point Divide Index: arch/parisc/math-emu/sfmpy.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/sfmpy.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/sfmpy.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/sfmpy.c 4 Aug 2004 01:26:06 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/sfmpy.c $Revision: 1.1 $ + * @(#) pa/spmath/sfmpy.c $Revision: 1.2 $ * * Purpose: * Single Precision Floating-point Multiply Index: arch/parisc/math-emu/sfrem.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/sfrem.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/sfrem.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/sfrem.c 4 Aug 2004 01:26:06 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/sfrem.c $Revision: 1.1 $ + * @(#) pa/spmath/sfrem.c $Revision: 1.2 $ * * Purpose: * Single Precision Floating-point Remainder Index: arch/parisc/math-emu/sfsqrt.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/sfsqrt.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/sfsqrt.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/sfsqrt.c 4 Aug 2004 01:26:06 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/sfsqrt.c $Revision: 1.1 $ + * @(#) pa/spmath/sfsqrt.c $Revision: 1.2 $ * * Purpose: * Single Floating-point Square Root Index: arch/parisc/math-emu/sfsub.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/math-emu/sfsub.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/math-emu/sfsub.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/math-emu/sfsub.c 4 Aug 2004 01:26:06 -0000 1.2 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/sfsub.c $Revision: 1.1 $ + * @(#) pa/spmath/sfsub.c $Revision: 1.2 $ * * Purpose: * Single_subtract: subtract two single precision values. Index: arch/parisc/mm/fault.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/mm/fault.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/mm/fault.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/mm/fault.c 4 Aug 2004 01:26:06 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.1 2004/07/22 19:49:24 joff Exp $ +/* $Id: fault.c,v 1.2 2004/08/04 01:26:06 joff 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 Index: arch/parisc/tools/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/tools/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/tools/Makefile 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/tools/Makefile 4 Aug 2004 01:26:06 -0000 1.2 @@ -3,7 +3,7 @@ # Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) # Copyright (C) 1997 Ralf Baechle (ralf@gnu.ai.mit.edu) # -# $Id: Makefile,v 1.1 2004/07/22 19:49:24 joff Exp $ +# $Id: Makefile,v 1.2 2004/08/04 01:26:06 joff Exp $ # TARGET := $(TOPDIR)/include/asm-$(ARCH)/offset.h Index: arch/parisc/tools/offset.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/parisc/tools/offset.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/parisc/tools/offset.c 22 Jul 2004 19:49:24 -0000 1.1 +++ arch/parisc/tools/offset.c 4 Aug 2004 01:26:06 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: offset.c,v 1.1 2004/07/22 19:49:24 joff Exp $ +/* $Id: offset.c,v 1.2 2004/08/04 01:26:06 joff Exp $ * * offset.c: Calculate pt_regs and task_struct offsets. * Index: arch/ppc/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/Makefile 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/Makefile 4 Aug 2004 01:26:06 -0000 1.2 @@ -14,11 +14,7 @@ # # Be sure to change PAGE_OFFSET in include/asm-ppc/page.h to match -KERNELLOAD =0xc0000000 - -ifeq ($(shell uname -m),ppc) -CHECKS = checks -endif +KERNELLOAD =$(CONFIG_KERNEL_START) LINKFLAGS = -T arch/ppc/vmlinux.lds -Ttext $(KERNELLOAD) -Bstatic CPPFLAGS := $(CPPFLAGS) -I$(TOPDIR)/arch/$(ARCH) @@ -46,18 +42,13 @@ CFLAGS += $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g') endif -ifdef CONFIG_4xx - HEAD := arch/ppc/kernel/head_4xx.o -else - ifdef CONFIG_8xx - HEAD := arch/ppc/kernel/head_8xx.o - else - HEAD := arch/ppc/kernel/head.o - ifdef CONFIG_6xx - HEAD += arch/ppc/kernel/idle_6xx.o - endif - endif -endif +HEAD-y := arch/ppc/kernel/head.o +HEAD-$(CONFIG_40x) := arch/ppc/kernel/head_4xx.o +HEAD-$(CONFIG_44x) := arch/ppc/kernel/head_44x.o +HEAD-$(CONFIG_8xx) := arch/ppc/kernel/head_8xx.o +HEAD-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o + +HEAD := $(HEAD-y) ARCH_SUBDIRS = arch/ppc/kernel arch/ppc/platforms arch/ppc/mm arch/ppc/lib SUBDIRS := $(SUBDIRS) $(ARCH_SUBDIRS) @@ -81,9 +72,9 @@ DRIVERS += arch/ppc/8xx_io/8xx_io.o endif -ifdef CONFIG_8260 -SUBDIRS += arch/ppc/8260_io -DRIVERS += arch/ppc/8260_io/8260_io.o +ifdef CONFIG_CPM2 +SUBDIRS += arch/ppc/cpm2_io +DRIVERS += arch/ppc/cpm2_io/cpm2_io.o endif ifdef CONFIG_APUS @@ -94,12 +85,12 @@ checks: @$(MAKE) -C arch/$(ARCH)/kernel checks -BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd +BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd uImage # All the instructions talk about "make bzImage". bzImage: zImage -$(BOOT_TARGETS): $(CHECKS) vmlinux +$(BOOT_TARGETS): vmlinux @$(MAKEBOOT) $@ %_config: arch/ppc/configs/%_defconfig Index: arch/ppc/config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/config.in 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/config.in 4 Aug 2004 01:26:06 -0000 1.2 @@ -13,6 +13,7 @@ mainmenu_option next_comment comment 'Code maturity level options' bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL +bool 'Prompt for advanced kernel configuration options' CONFIG_ADVANCED_OPTIONS endmenu mainmenu_option next_comment @@ -30,11 +31,16 @@ define_bool CONFIG_PPC32 y choice 'Processor Type' \ "6xx/7xx/74xx/8260 CONFIG_6xx \ - 4xx CONFIG_4xx \ - POWER3 CONFIG_POWER3 \ - POWER4 CONFIG_POWER4 \ + 40x CONFIG_40x \ + 44x CONFIG_44x \ + POWER3 CONFIG_POWER3 \ + POWER4 CONFIG_POWER4 \ 8xx CONFIG_8xx" 6xx +if [ "$CONFIG_40x" = "y" -o "$CONFIG_44x" = "y" ]; then + define_bool CONFIG_4xx y +fi + if [ "$CONFIG_6xx" = "y" ]; then bool 'MPC8260 CPM Support' CONFIG_8260 fi @@ -48,42 +54,62 @@ if [ "$CONFIG_6xx" = "y" -o "$CONFIG_POWER3" = "y" -o \ "$CONFIG_POWER4" = "y" ]; then define_bool CONFIG_PPC_STD_MMU y -else - define_bool CONFIG_PPC_STD_MMU n fi if [ "$CONFIG_8260" = "y" ]; then define_bool CONFIG_SERIAL_CONSOLE y - bool 'Support for EST8260' CONFIG_EST8260 -fi - -if [ "$CONFIG_4xx" = "y" ]; then - choice 'Machine Type' \ - "Oak CONFIG_OAK \ - Walnut CONFIG_WALNUT" Oak - if [ "$CONFIG_WALNUT" = "y" ]; then - define_bool CONFIG_IBM405_ERR77 y - fi + define_bool CONFIG_CPM2 y + bool ' MPC8272 Family Support' CONFIG_8272 + choice 'Machine Type' \ + "ADS8272 CONFIG_ADS8272 \ + EST8260 CONFIG_EST8260 \ + RPX8260 CONFIG_RPX6" RPX8260 +fi + +if [ "$CONFIG_ADS8272" = "y" ]; then + define_bool CONFIG_PQ2ADS y +fi + +if [ "$CONFIG_40x" = "y" ]; then + choice 'Machine Type' \ + "CPCI405 CONFIG_CPCI405 \ + EP405/EP405PC CONFIG_EP405 \ + Redwood-5 CONFIG_REDWOOD_5 \ + Redwood-6 CONFIG_REDWOOD_6 \ + Oak CONFIG_OAK \ + Walnut CONFIG_WALNUT" Walnut + + if [ "$CONFIG_EP405" = "y" ]; then + bool 'EP405PC Support' CONFIG_EP405PC + fi +fi + +if [ "$CONFIG_44x" = "y" ]; then + choice 'Machine Type' \ + "Ebony CONFIG_EBONY \ + Ocotea CONFIG_OCOTEA" Ebony fi if [ "$CONFIG_8xx" = "y" ]; then define_bool CONFIG_SERIAL_CONSOLE y + define_bool CONFIG_NOT_COHERENT_CACHE y choice 'Machine Type' \ "RPX-Lite CONFIG_RPXLITE \ RPX-Classic CONFIG_RPXCLASSIC \ BSE-IP CONFIG_BSEIP \ FADS CONFIG_FADS \ - TQM823L CONFIG_TQM823L \ - TQM850L CONFIG_TQM850L \ - TQM855L CONFIG_TQM855L \ - TQM860L CONFIG_TQM860L \ - FPS850L CONFIG_FPS850L \ - TQM860 CONFIG_TQM860 \ - SPD823TS CONFIG_SPD823TS \ - IVMS8 CONFIG_IVMS8 \ + D-Box2 CONFIG_DBOX2 \ + TQM823L CONFIG_TQM823L \ + TQM850L CONFIG_TQM850L \ + TQM855L CONFIG_TQM855L \ + TQM860L CONFIG_TQM860L \ + FPS850L CONFIG_FPS850L \ + TQM860 CONFIG_TQM860 \ + SPD823TS CONFIG_SPD823TS \ + IVMS8 CONFIG_IVMS8 \ IVML24 CONFIG_IVML24 \ - SM850 CONFIG_SM850 \ + SM850 CONFIG_SM850 \ MBX CONFIG_MBX \ WinCept CONFIG_WINCEPT" RPX-Lite @@ -93,22 +119,25 @@ "$CONFIG_TQM855L" = "y" -o \ "$CONFIG_TQM860L" = "y" -o \ "$CONFIG_SM850" = "y" ]; then - define_bool CONFIG_TQM8xxL y + define_bool CONFIG_TQM8xxL y fi fi if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "n" ]; then choice 'Machine Type' \ "CHRP/PowerMac/PReP CONFIG_ALL_PPC \ - Amiga-APUS CONFIG_APUS \ + Amiga-APUS CONFIG_APUS \ IBM-Spruce CONFIG_SPRUCE \ Motorola-LoPEC CONFIG_LOPEC \ + Motorola-Sandpoint CONFIG_SANDPOINT \ + Motorola-PowerPlus CONFIG_PPLUS \ + Motorola-PrPMC750 CONFIG_PRPMC750 \ SBS-Palomar4 CONFIG_PAL4 \ - Synergy-Gemini CONFIG_GEMINI" CHRP/PowerMac/PReP + Synergy-Gemini CONFIG_GEMINI" CHRP/PowerMac/PReP fi -if [ "$CONFIG_SPRUCE" = "y" ]; then - define_bool CONFIG_GEN550 y +if [ "$CONFIG_SANDPOINT" = "y" ]; then + bool 'Enable MPC10x store gathering' CONFIG_MPC10X_STORE_GATHERING fi if [ "$CONFIG_LOPEC" = "y" ]; then @@ -116,13 +145,27 @@ define_bool CONFIG_GEN550 y fi -if [ "$CONFIG_PPC_STD_MMU" != "y" ]; then - define_bool CONFIG_ALL_PPC n +if [ "$CONFIG_PPLUS" = "y" ]; then + define_bool CONFIG_GEN550 y +fi + +if [ "$CONFIG_PRPMC750" = "y" ]; then + define_bool CONFIG_GEN550 y +fi + +if [ "$CONFIG_SANDPOINT" = "y" ]; then + define_bool CONFIG_EPIC_SERIAL_MODE y + define_bool CONFIG_GEN550 y +fi + +if [ "$CONFIG_SPRUCE" = "y" ]; then + define_bool CONFIG_GEN550 y fi bool 'Symmetric multi-processing support' CONFIG_SMP if [ "$CONFIG_SMP" = "y" ]; then bool ' Distribute interrupts on all CPUs by default' CONFIG_IRQ_ALL_CPUS + int 'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32 fi if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "n" ];then @@ -134,11 +177,125 @@ fi define_bool CONFIG_PPC_ISATIMER y fi +if [ "$CONFIG_POWER4" = "y" ]; then + bool 'VMX (same as AltiVec) support' CONFIG_ALTIVEC +fi if [ "$CONFIG_4xx" = "y" -o "$CONFIG_8xx" = "y" ]; then bool 'Math emulation' CONFIG_MATH_EMULATION fi +if [ "$CONFIG_4xx" = "y" ]; then + +# +# Set generic PPC4xx options +# + define_bool CONFIG_NOT_COHERENT_CACHE y + + if [ "$CONFIG_40x" = "y" ]; then + choice 'TTYS0 device and default console' \ + "UART0 CONFIG_UART0_TTYS0 \ + UART1 CONFIG_UART0_TTYS1" UART0 + fi + +# +# Set processor implementation based on board +# + + if [ "$CONFIG_CPCI405" = "y" ]; then + define_bool CONFIG_405GP y + fi + + if [ "$CONFIG_EP405" = "y" ]; then + define_bool CONFIG_405GP y + fi + + if [ "$CONFIG_OAK" = "y" -o "$CONFIG_TIVO" = "y" ]; then + define_bool CONFIG_403GCX y + fi + + if [ "$CONFIG_REDWOOD_5" = "y" -o "$CONFIG_REDWOOD_6" = "y" ]; then + define_bool CONFIG_STB03xxx y + fi + + if [ "$CONFIG_WALNUT" = "y" ]; then + define_bool CONFIG_405GP y + fi + + if [ "$CONFIG_EBONY" = "y" ]; then + define_bool CONFIG_440GP y + fi + + if [ "$CONFIG_OCOTEA" = "y" ]; then + define_bool CONFIG_440GX y + fi + +# +# Set options based on processor implementation +# + if [ "$CONFIG_405GP" = "y" -o "$CONFIG_STB03xxx" = "y" ]; then + define_bool CONFIG_IBM_OCP y + define_bool CONFIG_PPC_OCP y + define_bool CONFIG_405 y + fi + + if [ "$CONFIG_440GP" = "y" ]; then + define_bool CONFIG_IBM_OCP y + define_bool CONFIG_PPC_OCP y + define_bool CONFIG_GEN550 y + define_bool CONFIG_440 y + fi + + if [ "$CONFIG_440GX" = "y" ]; then + define_bool CONFIG_IBM_OCP y + define_bool CONFIG_PPC_OCP y + define_bool CONFIG_GEN550 y + define_bool CONFIG_IBM_EMAC4 y + define_bool CONFIG_440A y + fi + +# +# Set options based on processor core +# + if [ "$CONFIG_40x" = "y" ]; then + define_bool CONFIG_IBM405_ERR51 y + fi + + if [ "$CONFIG_405" = "y" ]; then + define_bool CONFIG_IBM405_ERR77 y + fi + + if [ "$CONFIG_44x" = "y" ]; then + define_bool CONFIG_PTE_64BIT y + define_bool CONFIG_PIN_TLB y + define_bool CONFIG_BOOKE y + fi + + bool 'PPC4xx DMA controller support' CONFIG_PPC4xx_DMA + if [ "$CONFIG_PPC4xx_DMA" = "y" ]; then + if [ "$CONFIG_405GP" = "y" ]; then + define_bool CONFIG_PPC4xx_EDMA y + fi + if [ "$CONFIG_STB03xxx" = "y" ]; then + define_bool CONFIG_STBXXX_DMA y + fi + fi + +# +# Set other board specific options +# + if [ "$CONFIG_OAK" = "y" -o "$CONFIG_TIVO" = "y" -o \ + "$CONFIG_REDWOOD_5" = "y" -o "$CONFIG_REDWOOD_6" = "y" -o \ + "$CONFIG_WALNUT" = "y" ]; then + define_bool CONFIG_IBM_OPENBIOS y + fi + + if [ "$CONFIG_WALNUT" = "y" -o "$CONFIG_EP405" = "y" ]; then + define_bool CONFIG_BIOS_FIXUP y + fi + +fi + if [ "$CONFIG_8xx" = "y" -o "$CONFIG_8260" = "y" ]; then define_bool CONFIG_EMBEDDEDBOOT y fi @@ -148,8 +305,52 @@ comment 'General setup' bool 'High memory support (experimental)' CONFIG_HIGHMEM +if [ "$CONFIG_ADVANCED_OPTIONS" = "y" ]; then + if [ "$CONFIG_HIGHMEM" = "y" ]; then + bool " Set high memory pool address" CONFIG_HIGHMEM_START_BOOL + if [ "$CONFIG_HIGHMEM_START_BOOL" = "y" ]; then + hex " Virtual start address of high memory pool" CONFIG_HIGHMEM_START 0xfe000000 + fi + fi + bool " Set maximum low memory" CONFIG_LOWMEM_SIZE_BOOL + if [ "$CONFIG_LOWMEM_SIZE_BOOL" = "y" ]; then + hex " Maximum low memory size (in bytes)" CONFIG_LOWMEM_SIZE 0x20000000 + fi + + bool "Set custom kernel base address" CONFIG_KERNEL_START_BOOL + if [ "$CONFIG_KERNEL_START_BOOL" = "y" ]; then + hex " Virtual address of kernel base" CONFIG_KERNEL_START 0xc0000000 + fi + bool "Set custom user task size" CONFIG_TASK_SIZE_BOOL + if [ "$CONFIG_TASK_SIZE_BOOL" = "y" ]; then + hex " Size of user task space" CONFIG_TASK_SIZE 0x80000000 + fi + if [ "$CONFIG_8xx" = "y" ]; then + bool "Pinned Kernel TLBs (86x ONLY)" CONFIG_PIN_TLB + fi +fi + +if [ "$CONFIG_HIGHMEM_START_BOOL" != "y" ]; then + define_hex CONFIG_HIGHMEM_START 0xfe000000 +fi + +if [ "$CONFIG_LOWMEM_SIZE_BOOL" != "y" ]; then + define_hex CONFIG_LOWMEM_SIZE 0x30000000 +fi -define_bool CONFIG_ISA n +if [ "$CONFIG_KERNEL_START_BOOL" != "y" ]; then + define_hex CONFIG_KERNEL_START 0xc0000000 +fi + +if [ "$CONFIG_TASK_SIZE_BOOL" != "y" ]; then + define_hex CONFIG_TASK_SIZE 0x80000000 +fi + +if [ "$CONFIG_ALL_PPC" = "y" ]; then + bool 'Support for ISA-bus hardware' CONFIG_ISA +else + define_bool CONFIG_ISA n +fi define_bool CONFIG_EISA n define_bool CONFIG_SBUS n @@ -157,7 +358,8 @@ define_bool CONFIG_MCA n if [ "$CONFIG_4xx" = "y" -o "$CONFIG_8260" = "y" ]; then - define_bool CONFIG_PCI n + bool "Enable PCI" CONFIG_PCI + bool 'PC PS/2 style Keyboard' CONFIG_PC_KEYBOARD else if [ "$CONFIG_8xx" = "y" ]; then bool 'QSpan PCI' CONFIG_PCI_QSPAN @@ -184,6 +386,7 @@ define_bool CONFIG_BINFMT_ELF y define_bool CONFIG_KERNEL_ELF y tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC +bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER source drivers/pci/Config.in @@ -213,7 +416,7 @@ dep_bool ' Support for reading of PReP Residual Data in /proc' CONFIG_PROC_PREPRESIDUAL $CONFIG_PREP_RESIDUAL define_bool CONFIG_PPCBUG_NVRAM y fi -if [ "$CONFIG_LOPEC" = "y" ]; then +if [ "$CONFIG_PPLUS" = "y" -o "$CONFIG_LOPEC" = "y" ]; then bool 'Enable reading PPCBUG NVRAM during boot' CONFIG_PPCBUG_NVRAM fi @@ -276,7 +479,6 @@ 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 @@ -298,7 +500,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 @@ -329,7 +531,7 @@ mainmenu_option next_comment comment 'Console drivers' -if [ "$CONFIG_4xx" != "y" -a "$CONFIG_8xx" != "y" ]; then +if [ "$CONFIG_40x" != "y" -a "$CONFIG_8xx" != "y" ]; then bool 'Support for VGA Console' CONFIG_VGA_CONSOLE fi source drivers/video/Config.in @@ -404,14 +606,15 @@ source arch/ppc/8xx_io/Config.in fi -if [ "$CONFIG_8260" = "y" ]; then -source arch/ppc/8260_io/Config.in +if [ "$CONFIG_CPM2" = "y" ]; then +source arch/ppc/cpm2_io/Config.in fi source drivers/usb/Config.in source net/bluetooth/Config.in +source crypto/Config.in source lib/Config.in mainmenu_option next_comment @@ -461,4 +664,7 @@ if [ "$CONFIG_GEN550" = "y" ]; then bool 'Support for early boot texts over serial port' CONFIG_SERIAL_TEXT_DEBUG fi + +int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 + endmenu Index: arch/ppc/defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/defconfig 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/defconfig 4 Aug 2004 01:26:06 -0000 1.2 @@ -60,6 +60,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y CONFIG_BINFMT_MISC=m +# CONFIG_OOM_KILLER is not set CONFIG_PCI_NAMES=y CONFIG_HOTPLUG=y @@ -308,7 +309,6 @@ 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 Index: arch/ppc/vmlinux.lds =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/vmlinux.lds,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/vmlinux.lds 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/vmlinux.lds 4 Aug 2004 01:26:06 -0000 1.2 @@ -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 = .); } Index: arch/ppc/8260_io/Config.in =================================================================== RCS file: arch/ppc/8260_io/Config.in diff -N arch/ppc/8260_io/Config.in --- arch/ppc/8260_io/Config.in 22 Jul 2004 19:49:02 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,26 +0,0 @@ -# -# MPC8260 Communication options -# -mainmenu_option next_comment -comment 'MPC8260 CPM Options' -bool 'Enable SCC Console' CONFIG_SCC_CONSOLE -if [ "$CONFIG_NET_ETHERNET" = "y" ]; then - bool 'CPM SCC Ethernet' CONFIG_SCC_ENET - if [ "$CONFIG_SCC_ENET" = "y" ]; then - bool 'Ethernet on SCC1' CONFIG_SCC1_ENET - if [ "$CONFIG_SCC1_ENET" != "y" ]; then - bool 'Ethernet on SCC2' CONFIG_SCC2_ENET - fi - fi -# -# CONFIG_FEC_ENET is only used to get netdevices to call our init -# function. Any combination of FCC1,2,3 are supported. -# - bool 'FCC Ethernet' CONFIG_FEC_ENET - if [ "$CONFIG_FEC_ENET" = "y" ]; then - bool 'Ethernet on FCC1' CONFIG_FCC1_ENET - bool 'Ethernet on FCC2' CONFIG_FCC2_ENET - bool 'Ethernet on FCC3' CONFIG_FCC3_ENET - fi -fi -endmenu Index: arch/ppc/8260_io/Makefile =================================================================== RCS file: arch/ppc/8260_io/Makefile diff -N arch/ppc/8260_io/Makefile --- arch/ppc/8260_io/Makefile 22 Jul 2004 19:49:02 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,17 +0,0 @@ -# -# Makefile for the linux MPC8xx ppc-specific parts of comm processor -# -# 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 definition is now in the main makefile... - -O_TARGET := 8260_io.o - -obj-y := commproc.o uart.o - -obj-$(CONFIG_FEC_ENET) += fcc_enet.o -obj-$(CONFIG_SCC_ENET) += enet.o - -include $(TOPDIR)/Rules.make Index: arch/ppc/8260_io/commproc.c =================================================================== RCS file: arch/ppc/8260_io/commproc.c diff -N arch/ppc/8260_io/commproc.c --- arch/ppc/8260_io/commproc.c 22 Jul 2004 19:49:02 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,179 +0,0 @@ -/* - * General Purpose functions for the global management of the - * 8260 Communication Processor Module. - * Copyright (c) 1999 Dan Malek (dmalek@jlc.net) - * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com) - * 2.3.99 Updates - * - * In addition to the individual control of the communication - * channels, there are a few functions that globally affect the - * communication processor. - * - * Buffer descriptors must be allocated from the dual ported memory - * space. The allocator for that is here. When the communication - * process is reset, we reclaim the memory available. There is - * currently no deallocator for this memory. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static uint dp_alloc_base; /* Starting offset in DP ram */ -static uint dp_alloc_top; /* Max offset + 1 */ -static uint host_buffer; /* One page of host buffer */ -static uint host_end; /* end + 1 */ -cpm8260_t *cpmp; /* Pointer to comm processor space */ - -/* We allocate this here because it is used almost exclusively for - * the communication processor devices. - */ -immap_t *immr; - -void -m8260_cpm_reset(void) -{ - volatile immap_t *imp; - volatile cpm8260_t *commproc; - uint vpgaddr; - - immr = imp = (volatile immap_t *)IMAP_ADDR; - commproc = &imp->im_cpm; - - /* Reclaim the DP memory for our use. - */ - dp_alloc_base = CPM_DATAONLY_BASE; - dp_alloc_top = dp_alloc_base + CPM_DATAONLY_SIZE; - - /* Set the host page for allocation. - */ - host_buffer = - (uint) alloc_bootmem_pages(PAGE_SIZE * NUM_CPM_HOST_PAGES); - host_end = host_buffer + (PAGE_SIZE * NUM_CPM_HOST_PAGES); - - vpgaddr = host_buffer; - - /* Tell everyone where the comm processor resides. - */ - cpmp = (cpm8260_t *)commproc; -} - -/* Allocate some memory from the dual ported ram. - * To help protocols with object alignment restrictions, we do that - * if they ask. - */ -uint -m8260_cpm_dpalloc(uint size, uint align) -{ - uint retloc; - uint align_mask, off; - uint savebase; - - align_mask = align - 1; - savebase = dp_alloc_base; - - if ((off = (dp_alloc_base & align_mask)) != 0) - dp_alloc_base += (align - off); - - if ((dp_alloc_base + size) >= dp_alloc_top) { - dp_alloc_base = savebase; - return(CPM_DP_NOSPACE); - } - - retloc = dp_alloc_base; - dp_alloc_base += size; - - return(retloc); -} - -/* We also own one page of host buffer space for the allocation of - * UART "fifos" and the like. - */ -uint -m8260_cpm_hostalloc(uint size, uint align) -{ - uint retloc; - uint align_mask, off; - uint savebase; - - align_mask = align - 1; - savebase = host_buffer; - - if ((off = (host_buffer & align_mask)) != 0) - host_buffer += (align - off); - - if ((host_buffer + size) >= host_end) { - host_buffer = savebase; - return(0); - } - - retloc = host_buffer; - host_buffer += size; - - return(retloc); -} - -/* Set a baud rate generator. This needs lots of work. There are - * eight BRGs, which can be connected to the CPM channels or output - * as clocks. The BRGs are in two different block of internal - * memory mapped space. - * The baud rate clock is the system clock divided by something. - * It was set up long ago during the initial boot phase and is - * is given to us. - * Baud rate clocks are zero-based in the driver code (as that maps - * to port numbers). Documentation uses 1-based numbering. - */ -#define BRG_INT_CLK (((bd_t *)__res)->bi_brgfreq) -#define BRG_UART_CLK (BRG_INT_CLK/16) - -/* This function is used by UARTS, or anything else that uses a 16x - * oversampled clock. - */ -void -m8260_cpm_setbrg(uint brg, uint rate) -{ - volatile uint *bp; - - /* This is good enough to get SMCs running..... - */ - if (brg < 4) { - bp = (uint *)&immr->im_brgc1; - } - else { - bp = (uint *)&immr->im_brgc5; - brg -= 4; - } - bp += brg; - *bp = ((BRG_UART_CLK / rate) << 1) | CPM_BRG_EN; -} - -/* This function is used to set high speed synchronous baud rate - * clocks. - */ -void -m8260_cpm_fastbrg(uint brg, uint rate, int div16) -{ - volatile uint *bp; - - if (brg < 4) { - bp = (uint *)&immr->im_brgc1; - } - else { - bp = (uint *)&immr->im_brgc5; - brg -= 4; - } - bp += brg; - *bp = ((BRG_INT_CLK / rate) << 1) | CPM_BRG_EN; - if (div16) - *bp |= CPM_BRG_DIV16; -} Index: arch/ppc/8260_io/enet.c =================================================================== RCS file: arch/ppc/8260_io/enet.c diff -N arch/ppc/8260_io/enet.c --- arch/ppc/8260_io/enet.c 22 Jul 2004 19:49:02 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,862 +0,0 @@ -/* - * Ethernet driver for Motorola MPC8260. - * Copyright (c) 1999 Dan Malek (dmalek@jlc.net) - * Copyright (c) 2000 MontaVista Software Inc. (source@mvista.com) - * 2.3.99 Updates - * - * I copied this from the 8xx CPM Ethernet driver, so follow the - * credits back through that. - * - * This version of the driver is somewhat selectable for the different - * processor/board combinations. It works for the boards I know about - * now, and should be easily modified to include others. Some of the - * configuration information is contained in and the - * remainder is here. - * - * Buffer descriptors are kept in the CPM dual port RAM, and the frame - * buffers are in the host memory. - * - * Right now, I am very watseful with the buffers. I allocate memory - * pages and then divide them into 2K frame buffers. This way I know I - * have buffers large enough to hold one frame within one buffer descriptor. - * Once I get this working, I will use 64 or 128 byte CPM buffers, which - * will be much more memory efficient and will easily handle lots of - * small packets. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* - * Theory of Operation - * - * The MPC8260 CPM performs the Ethernet processing on an SCC. It can use - * an aribtrary number of buffers on byte boundaries, but must have at - * least two receive buffers to prevent constant overrun conditions. - * - * The buffer descriptors are allocated from the CPM dual port memory - * with the data buffers allocated from host memory, just like all other - * serial communication protocols. The host memory buffers are allocated - * from the free page pool, and then divided into smaller receive and - * transmit buffers. The size of the buffers should be a power of two, - * since that nicely divides the page. This creates a ring buffer - * structure similar to the LANCE and other controllers. - * - * Like the LANCE driver: - * The driver runs as two independent, single-threaded flows of control. One - * is the send-packet routine, which enforces single-threaded use by the - * cep->tx_busy flag. The other thread is the interrupt handler, which is - * single threaded by the hardware and other software. - */ - -/* The transmitter timeout - */ -#define TX_TIMEOUT (2*HZ) - -/* The number of Tx and Rx buffers. These are allocated from the page - * pool. The code may assume these are power of two, so it is best - * to keep them that size. - * We don't need to allocate pages for the transmitter. We just use - * the skbuffer directly. - */ -#define CPM_ENET_RX_PAGES 4 -#define CPM_ENET_RX_FRSIZE 2048 -#define CPM_ENET_RX_FRPPG (PAGE_SIZE / CPM_ENET_RX_FRSIZE) -#define RX_RING_SIZE (CPM_ENET_RX_FRPPG * CPM_ENET_RX_PAGES) -#define TX_RING_SIZE 8 /* Must be power of two */ -#define TX_RING_MOD_MASK 7 /* for this to work */ - -/* The CPM stores dest/src/type, data, and checksum for receive packets. - */ -#define PKT_MAXBUF_SIZE 1518 -#define PKT_MINBUF_SIZE 64 -#define PKT_MAXBLR_SIZE 1520 - -/* The CPM buffer descriptors track the ring buffers. The rx_bd_base and - * tx_bd_base always point to the base of the buffer descriptors. The - * cur_rx and cur_tx point to the currently available buffer. - * The dirty_tx tracks the current buffer that is being sent by the - * controller. The cur_tx and dirty_tx are equal under both completely - * empty and completely full conditions. The empty/ready indicator in - * the buffer descriptor determines the actual condition. - */ -struct scc_enet_private { - /* The saved address of a sent-in-place packet/buffer, for skfree(). */ - struct sk_buff* tx_skbuff[TX_RING_SIZE]; - ushort skb_cur; - ushort skb_dirty; - - /* CPM dual port RAM relative addresses. - */ - cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */ - cbd_t *tx_bd_base; - cbd_t *cur_rx, *cur_tx; /* The next free ring entry */ - cbd_t *dirty_tx; /* The ring entries to be free()ed. */ - scc_t *sccp; - struct net_device_stats stats; - uint tx_full; - spinlock_t lock; -}; - -static int scc_enet_open(struct net_device *dev); -static int scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev); -static int scc_enet_rx(struct net_device *dev); -static void scc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs); -static int scc_enet_close(struct net_device *dev); -static struct net_device_stats *scc_enet_get_stats(struct net_device *dev); -static void set_multicast_list(struct net_device *dev); - -/* These will be configurable for the SCC choice. -*/ -#define CPM_ENET_BLOCK CPM_CR_SCC1_SBLOCK -#define CPM_ENET_PAGE CPM_CR_SCC1_PAGE -#define PROFF_ENET PROFF_SCC1 -#define SCC_ENET 0 -#define SIU_INT_ENET SIU_INT_SCC1 - -/* These are both board and SCC dependent.... -*/ -#define PD_ENET_RXD ((uint)0x00000001) -#define PD_ENET_TXD ((uint)0x00000002) -#define PD_ENET_TENA ((uint)0x00000004) -#define PC_ENET_RENA ((uint)0x00020000) -#define PC_ENET_CLSN ((uint)0x00000004) -#define PC_ENET_TXCLK ((uint)0x00000800) -#define PC_ENET_RXCLK ((uint)0x00000400) -#define CMX_CLK_ROUTE ((uint)0x25000000) -#define CMX_CLK_MASK ((uint)0xff000000) - -/* Specific to a board. -*/ -#define PC_EST8260_ENET_LOOPBACK ((uint)0x80000000) -#define PC_EST8260_ENET_SQE ((uint)0x40000000) -#define PC_EST8260_ENET_NOTFD ((uint)0x20000000) - -static int -scc_enet_open(struct net_device *dev) -{ - - /* I should reset the ring buffers here, but I don't yet know - * a simple way to do that. - */ - netif_start_queue(dev); - return 0; /* Always succeed */ -} - -static int -scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct scc_enet_private *cep = (struct scc_enet_private *)dev->priv; - volatile cbd_t *bdp; - - - /* Fill in a Tx ring entry */ - bdp = cep->cur_tx; - -#ifndef final_version - if (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. - */ - printk("%s: tx queue full!.\n", dev->name); - return 1; - } -#endif - - /* Clear all of the status flags. - */ - bdp->cbd_sc &= ~BD_ENET_TX_STATS; - - /* If the frame is short, tell CPM to pad it. - */ - if (skb->len <= ETH_ZLEN) - bdp->cbd_sc |= BD_ENET_TX_PAD; - else - bdp->cbd_sc &= ~BD_ENET_TX_PAD; - - /* Set buffer length and buffer pointer. - */ - bdp->cbd_datlen = skb->len; - bdp->cbd_bufaddr = __pa(skb->data); - - /* Save skb pointer. - */ - cep->tx_skbuff[cep->skb_cur] = skb; - - 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, - * its the last BD of the frame, and to put the CRC on the end. - */ - bdp->cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | BD_ENET_TX_LAST | BD_ENET_TX_TC); - - dev->trans_start = jiffies; - - /* If this was the last BD in the ring, start at the beginning again. - */ - if (bdp->cbd_sc & BD_ENET_TX_WRAP) - bdp = cep->tx_bd_base; - else - bdp++; - - if (bdp->cbd_sc & BD_ENET_TX_READY) { - netif_stop_queue(dev); - cep->tx_full = 1; - } - - cep->cur_tx = (cbd_t *)bdp; - - spin_unlock_irq(&cep->lock); - - return 0; -} - -static void -scc_enet_timeout(struct net_device *dev) -{ - struct scc_enet_private *cep = (struct scc_enet_private *)dev->priv; - - printk("%s: transmit timed out.\n", dev->name); - cep->stats.tx_errors++; -#ifndef final_version - { - int i; - cbd_t *bdp; - printk(" Ring data dump: cur_tx %p%s cur_rx %p.\n", - cep->cur_tx, cep->tx_full ? " (full)" : "", - cep->cur_rx); - bdp = cep->tx_bd_base; - printk(" Tx @base %p :\n", bdp); - for (i = 0 ; i < TX_RING_SIZE; i++, bdp++) - printk("%04x %04x %08x\n", - bdp->cbd_sc, - bdp->cbd_datlen, - bdp->cbd_bufaddr); - bdp = cep->rx_bd_base; - printk(" Rx @base %p :\n", bdp); - for (i = 0 ; i < RX_RING_SIZE; i++, bdp++) - printk("%04x %04x %08x\n", - bdp->cbd_sc, - bdp->cbd_datlen, - bdp->cbd_bufaddr); - } -#endif - if (!cep->tx_full) - netif_wake_queue(dev); -} - -/* The interrupt handler. - * This is called from the CPM handler, not the MPC core interrupt. - */ -static void -scc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs) -{ - struct net_device *dev = dev_id; - volatile struct scc_enet_private *cep; - volatile cbd_t *bdp; - ushort int_events; - int must_restart; - - cep = (struct scc_enet_private *)dev->priv; - - /* Get the interrupt events that caused us to be here. - */ - int_events = cep->sccp->scc_scce; - cep->sccp->scc_scce = int_events; - must_restart = 0; - - /* Handle receive event in its own function. - */ - if (int_events & SCCE_ENET_RXF) - scc_enet_rx(dev_id); - - /* Check for a transmit error. The manual is a little unclear - * about this, so the debug code until I get it figured out. It - * appears that if TXE is set, then TXB is not set. However, - * if carrier sense is lost during frame transmission, the TXE - * bit is set, "and continues the buffer transmission normally." - * I don't know if "normally" implies TXB is set when the buffer - * descriptor is closed.....trial and error :-). - */ - - /* Transmit OK, or non-fatal error. Update the buffer descriptors. - */ - if (int_events & (SCCE_ENET_TXE | SCCE_ENET_TXB)) { - 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)) - break; - - if (bdp->cbd_sc & BD_ENET_TX_HB) /* No heartbeat */ - cep->stats.tx_heartbeat_errors++; - if (bdp->cbd_sc & BD_ENET_TX_LC) /* Late collision */ - cep->stats.tx_window_errors++; - if (bdp->cbd_sc & BD_ENET_TX_RL) /* Retrans limit */ - cep->stats.tx_aborted_errors++; - if (bdp->cbd_sc & BD_ENET_TX_UN) /* Underrun */ - cep->stats.tx_fifo_errors++; - if (bdp->cbd_sc & BD_ENET_TX_CSL) /* Carrier lost */ - cep->stats.tx_carrier_errors++; - - - /* No heartbeat or Lost carrier are not really bad errors. - * The others require a restart transmit command. - */ - if (bdp->cbd_sc & - (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) { - must_restart = 1; - cep->stats.tx_errors++; - } - - cep->stats.tx_packets++; - - /* Deferred means some collisions occurred during transmit, - * but we eventually sent the packet OK. - */ - if (bdp->cbd_sc & BD_ENET_TX_DEF) - cep->stats.collisions++; - - /* Free the sk buffer associated with this last transmit. - */ - dev_kfree_skb_irq(cep->tx_skbuff[cep->skb_dirty]); - cep->skb_dirty = (cep->skb_dirty + 1) & TX_RING_MOD_MASK; - - /* Update pointer to next buffer descriptor to be transmitted. - */ - if (bdp->cbd_sc & BD_ENET_TX_WRAP) - bdp = cep->tx_bd_base; - else - bdp++; - - /* I don't know if we can be held off from processing these - * interrupts for more than one frame time. I really hope - * not. In such a case, we would now want to check the - * currently available BD (cur_tx) and determine if any - * buffers between the dirty_tx and cur_tx have also been - * sent. We would want to process anything in between that - * does not have BD_ENET_TX_READY set. - */ - - /* Since we have freed up a buffer, the ring is no longer - * full. - */ - if (cep->tx_full) { - cep->tx_full = 0; - if (netif_queue_stopped(dev)) { - netif_wake_queue(dev); - } - } - - cep->dirty_tx = (cbd_t *)bdp; - } - - if (must_restart) { - volatile cpm8260_t *cp; - - /* Some transmit errors cause the transmitter to shut - * down. We now issue a restart transmit. Since the - * errors close the BD and update the pointers, the restart - * _should_ pick up without having to reset any of our - * pointers either. - */ - - cp = cpmp; - cp->cp_cpcr = - mk_cr_cmd(CPM_ENET_PAGE, CPM_ENET_BLOCK, 0, - CPM_CR_RESTART_TX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); - } - spin_unlock(&cep->lock); - } - - /* 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. - */ - if (int_events & SCCE_ENET_BSY) { - cep->stats.rx_dropped++; - printk("SCC ENET: BSY can't happen.\n"); - } - - return; -} - -/* During a receive, the cur_rx points to the current incoming buffer. - * When we update through the ring, if the next incoming buffer has - * not been given to the system, we just set the empty indicator, - * effectively tossing the packet. - */ -static int -scc_enet_rx(struct net_device *dev) -{ - struct scc_enet_private *cep; - volatile cbd_t *bdp; - struct sk_buff *skb; - ushort pkt_len; - - cep = (struct scc_enet_private *)dev->priv; - - /* First, grab all of the stats for the incoming packet. - * These get messed up if we get called due to a busy condition. - */ - bdp = cep->cur_rx; - -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. - */ - if ((bdp->cbd_sc & (BD_ENET_RX_FIRST | BD_ENET_RX_LAST)) != - (BD_ENET_RX_FIRST | BD_ENET_RX_LAST)) - printk("CPM ENET: rcv is not first+last\n"); -#endif - - /* Frame too long or too short. - */ - if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) - cep->stats.rx_length_errors++; - if (bdp->cbd_sc & BD_ENET_RX_NO) /* Frame alignment */ - cep->stats.rx_frame_errors++; - if (bdp->cbd_sc & BD_ENET_RX_CR) /* CRC Error */ - cep->stats.rx_crc_errors++; - if (bdp->cbd_sc & BD_ENET_RX_OV) /* FIFO overrun */ - cep->stats.rx_crc_errors++; - - /* Report late collisions as a frame error. - * On this error, the BD is closed, but we don't know what we - * have in the buffer. So, just drop this frame on the floor. - */ - if (bdp->cbd_sc & BD_ENET_RX_CL) { - cep->stats.rx_frame_errors++; - } - else { - - /* Process the incoming frame. - */ - cep->stats.rx_packets++; - pkt_len = bdp->cbd_datlen; - cep->stats.rx_bytes += pkt_len; - - /* This does 16 byte alignment, much more than we need. - * The packet length includes FCS, but we don't want to - * include that when passing upstream as it messes up - * bridging applications. - */ - skb = dev_alloc_skb(pkt_len-4); - - if (skb == NULL) { - printk("%s: Memory squeeze, dropping packet.\n", dev->name); - cep->stats.rx_dropped++; - } - else { - skb->dev = dev; - skb_put(skb,pkt_len-4); /* Make room */ - eth_copy_and_sum(skb, - (unsigned char *)__va(bdp->cbd_bufaddr), - pkt_len-4, 0); - skb->protocol=eth_type_trans(skb,dev); - netif_rx(skb); - } - } - - /* Clear the status flags for this buffer. - */ - bdp->cbd_sc &= ~BD_ENET_RX_STATS; - - /* Mark the buffer empty. - */ - bdp->cbd_sc |= BD_ENET_RX_EMPTY; - - /* Update BD pointer to next entry. - */ - if (bdp->cbd_sc & BD_ENET_RX_WRAP) - bdp = cep->rx_bd_base; - else - bdp++; - - } - cep->cur_rx = (cbd_t *)bdp; - - return 0; -} - -static int -scc_enet_close(struct net_device *dev) -{ - /* Don't know what to do yet. - */ - netif_stop_queue(dev); - - return 0; -} - -static struct net_device_stats *scc_enet_get_stats(struct net_device *dev) -{ - struct scc_enet_private *cep = (struct scc_enet_private *)dev->priv; - - return &cep->stats; -} - -/* Set or clear the multicast filter for this adaptor. - * Skeleton taken from sunlance driver. - * The CPM Ethernet implementation allows Multicast as well as individual - * MAC address filtering. Some of the drivers check to make sure it is - * a group multicast address, and discard those that are not. I guess I - * will do the same for now, but just remove the test if you want - * individual filtering as well (do the upper net layers want or support - * this kind of feature?). - */ - -static void set_multicast_list(struct net_device *dev) -{ - struct scc_enet_private *cep; - struct dev_mc_list *dmi; - u_char *mcptr, *tdptr; - volatile scc_enet_t *ep; - int i, j; - cep = (struct scc_enet_private *)dev->priv; - - /* Get pointer to SCC area in parameter RAM. - */ - 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; - } else { - - cep->sccp->scc_pmsr &= ~SCC_PSMR_PRO; - - if (dev->flags & IFF_ALLMULTI) { - /* Catch all multicast addresses, so set the - * filter to all 1's. - */ - ep->sen_gaddr1 = 0xffff; - ep->sen_gaddr2 = 0xffff; - ep->sen_gaddr3 = 0xffff; - ep->sen_gaddr4 = 0xffff; - } - else { - /* Clear filter and add the addresses in the list. - */ - ep->sen_gaddr1 = 0; - ep->sen_gaddr2 = 0; - ep->sen_gaddr3 = 0; - ep->sen_gaddr4 = 0; - - dmi = dev->mc_list; - - for (i=0; imc_count; i++) { - - /* Only support group multicast for now. - */ - if (!(dmi->dmi_addr[0] & 1)) - continue; - - /* The address in dmi_addr is LSB first, - * and taddr is MSB first. We have to - * copy bytes MSB first from dmi_addr. - */ - mcptr = (u_char *)dmi->dmi_addr + 5; - tdptr = (u_char *)&ep->sen_taddrh; - for (j=0; j<6; j++) - *tdptr++ = *mcptr--; - - /* Ask CPM to run CRC and set bit in - * filter mask. - */ - cpmp->cp_cpcr = mk_cr_cmd(CPM_ENET_PAGE, - CPM_ENET_BLOCK, 0, - CPM_CR_SET_GADDR) | CPM_CR_FLG; - /* this delay is necessary here -- Cort */ - udelay(10); - while (cpmp->cp_cpcr & CPM_CR_FLG); - } - } - } -} - -/* Initialize the CPM Ethernet on SCC. - */ -int __init scc_enet_init(void) -{ - struct net_device *dev; - struct scc_enet_private *cep; - int i, j; - unsigned char *eap; - unsigned long mem_addr; - bd_t *bd; - volatile cbd_t *bdp; - volatile cpm8260_t *cp; - volatile scc_t *sccp; - volatile scc_enet_t *ep; - volatile immap_t *immap; - volatile iop8260_t *io; - - cp = cpmp; /* Get pointer to Communication Processor */ - - immap = (immap_t *)IMAP_ADDR; /* and to internal registers */ - io = &immap->im_ioport; - - bd = (bd_t *)__res; - - /* Allocate some private information. - */ - cep = (struct scc_enet_private *)kmalloc(sizeof(*cep), GFP_KERNEL); - if (cep == NULL) - return -ENOMEM; - - __clear_user(cep,sizeof(*cep)); - spin_lock_init(&cep->lock); - - /* Create an Ethernet device instance. - */ - dev = init_etherdev(0, 0); - - /* Get pointer to SCC area in parameter RAM. - */ - ep = (scc_enet_t *)(&immap->im_dprambase[PROFF_ENET]); - - /* And another to the SCC register area. - */ - sccp = (volatile scc_t *)(&immap->im_scc[SCC_ENET]); - cep->sccp = (scc_t *)sccp; /* Keep the pointer handy */ - - /* Disable receive and transmit in case someone left it running. - */ - sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - - /* Configure port C and D pins for SCC Ethernet. This - * won't work for all SCC possibilities....it will be - * board/port specific. - */ - io->iop_pparc |= - (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 &= - ~(PC_ENET_RENA | PC_ENET_TXCLK | PC_ENET_RXCLK); - io->iop_psorc |= PC_ENET_CLSN; - - io->iop_ppard |= (PD_ENET_RXD | PD_ENET_TXD | PD_ENET_TENA); - io->iop_pdird |= (PD_ENET_TXD | PD_ENET_TENA); - io->iop_pdird &= ~PD_ENET_RXD; - io->iop_psord |= PD_ENET_TXD; - io->iop_psord &= ~(PD_ENET_RXD | PD_ENET_TENA); - - /* Configure Serial Interface clock routing. - * First, clear all SCC bits to zero, then set the ones we want. - */ - immap->im_cpmux.cmx_scr &= ~CMX_CLK_MASK; - immap->im_cpmux.cmx_scr |= CMX_CLK_ROUTE; - - /* Allocate space for the buffer descriptors in the DP ram. - * These are relative offsets in the DP ram address space. - * Initialize base addresses for the buffer descriptors. - */ - i = m8260_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE, 8); - ep->sen_genscc.scc_rbase = i; - cep->rx_bd_base = (cbd_t *)&immap->im_dprambase[i]; - - i = m8260_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE, 8); - ep->sen_genscc.scc_tbase = i; - cep->tx_bd_base = (cbd_t *)&immap->im_dprambase[i]; - - cep->dirty_tx = cep->cur_tx = cep->tx_bd_base; - cep->cur_rx = cep->rx_bd_base; - - ep->sen_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB; - ep->sen_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB; - - /* Set maximum bytes per receive buffer. - * This appears to be an Ethernet frame size, not the buffer - * fragment size. It must be a multiple of four. - */ - ep->sen_genscc.scc_mrblr = PKT_MAXBLR_SIZE; - - /* Set CRC preset and mask. - */ - ep->sen_cpres = 0xffffffff; - ep->sen_cmask = 0xdebb20e3; - - ep->sen_crcec = 0; /* CRC Error counter */ - ep->sen_alec = 0; /* alignment error counter */ - ep->sen_disfc = 0; /* discard frame counter */ - - ep->sen_pads = 0x8888; /* Tx short frame pad character */ - ep->sen_retlim = 15; /* Retry limit threshold */ - - ep->sen_maxflr = PKT_MAXBUF_SIZE; /* maximum frame length register */ - ep->sen_minflr = PKT_MINBUF_SIZE; /* minimum frame length register */ - - ep->sen_maxd1 = PKT_MAXBLR_SIZE; /* maximum DMA1 length */ - ep->sen_maxd2 = PKT_MAXBLR_SIZE; /* maximum DMA2 length */ - - /* Clear hash tables. - */ - ep->sen_gaddr1 = 0; - ep->sen_gaddr2 = 0; - ep->sen_gaddr3 = 0; - ep->sen_gaddr4 = 0; - ep->sen_iaddr1 = 0; - ep->sen_iaddr2 = 0; - ep->sen_iaddr3 = 0; - ep->sen_iaddr4 = 0; - - /* Set Ethernet station address. - * - * This is supplied in the board information structure, so we - * copy that into the controller. - */ - eap = (unsigned char *)&(ep->sen_paddrh); - for (i=5; i>=0; i--) - *eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i]; - - ep->sen_pper = 0; /* 'cause the book says so */ - ep->sen_taddrl = 0; /* temp address (LSB) */ - ep->sen_taddrm = 0; - ep->sen_taddrh = 0; /* temp address (MSB) */ - - /* Now allocate the host memory pages and initialize the - * buffer descriptors. - */ - bdp = cep->tx_bd_base; - for (i=0; icbd_sc = 0; - bdp->cbd_bufaddr = 0; - bdp++; - } - - /* Set the last buffer to wrap. - */ - bdp--; - bdp->cbd_sc |= BD_SC_WRAP; - - bdp = cep->rx_bd_base; - for (i=0; icbd_sc = BD_ENET_RX_EMPTY | BD_ENET_RX_INTR; - bdp->cbd_bufaddr = __pa(mem_addr); - mem_addr += CPM_ENET_RX_FRSIZE; - bdp++; - } - } - - /* Set the last buffer to wrap. - */ - bdp--; - bdp->cbd_sc |= BD_SC_WRAP; - - /* Let's re-initialize the channel now. We have to do it later - * than the manual describes because we have just now finished - * the BD initialization. - */ - cpmp->cp_cpcr = mk_cr_cmd(CPM_ENET_PAGE, CPM_ENET_BLOCK, 0, - CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); - - cep->skb_cur = cep->skb_dirty = 0; - - sccp->scc_scce = 0xffff; /* Clear any pending events */ - - /* Enable interrupts for transmit error, complete frame - * received, and any transmit buffer we have also set the - * interrupt flag. - */ - sccp->scc_sccm = (SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB); - - /* Install our interrupt handler. - */ - request_irq(SIU_INT_ENET, scc_enet_interrupt, 0, "enet", dev); - - /* Set GSMR_H to enable all normal operating modes. - * Set GSMR_L to enable Ethernet to MC68160. - */ - sccp->scc_gsmrh = 0; - sccp->scc_gsmrl = (SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 | SCC_GSMRL_TPP_10 | SCC_GSMRL_MODE_ENET); - - /* Set sync/delimiters. - */ - sccp->scc_dsr = 0xd555; - - /* Set processing mode. Use Ethernet CRC, catch broadcast, and - * start frame search 22 bit times after RENA. - */ - sccp->scc_pmsr = (SCC_PSMR_ENCRC | SCC_PSMR_NIB22); - - /* It is now OK to enable the Ethernet transmitter. - * Unfortunately, there are board implementation differences here. - */ - io->iop_pparc &= ~(PC_EST8260_ENET_LOOPBACK | - PC_EST8260_ENET_SQE | PC_EST8260_ENET_NOTFD); - io->iop_psorc &= ~(PC_EST8260_ENET_LOOPBACK | - PC_EST8260_ENET_SQE | PC_EST8260_ENET_NOTFD); - io->iop_pdirc |= (PC_EST8260_ENET_LOOPBACK | - PC_EST8260_ENET_SQE | PC_EST8260_ENET_NOTFD); - io->iop_pdatc &= ~(PC_EST8260_ENET_LOOPBACK | PC_EST8260_ENET_SQE); - io->iop_pdatc |= PC_EST8260_ENET_NOTFD; - - dev->base_addr = (unsigned long)ep; - dev->priv = cep; - - /* The CPM Ethernet specific entries in the device structure. */ - dev->open = scc_enet_open; - dev->hard_start_xmit = scc_enet_start_xmit; - dev->tx_timeout = scc_enet_timeout; - dev->watchdog_timeo = TX_TIMEOUT; - dev->stop = scc_enet_close; - dev->get_stats = scc_enet_get_stats; - dev->set_multicast_list = set_multicast_list; - - /* And last, enable the transmit and receive processing. - */ - sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); - - printk("%s: SCC ENET Version 0.1, ", dev->name); - for (i=0; i<5; i++) - printk("%02x:", dev->dev_addr[i]); - printk("%02x\n", dev->dev_addr[5]); - - return 0; -} - Index: arch/ppc/8260_io/fcc_enet.c =================================================================== RCS file: arch/ppc/8260_io/fcc_enet.c diff -N arch/ppc/8260_io/fcc_enet.c --- arch/ppc/8260_io/fcc_enet.c 22 Jul 2004 19:49:02 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1604 +0,0 @@ -/* - * Fast Ethernet Controller (FCC) driver for Motorola MPC8260. - * Copyright (c) 2000 MontaVista Software, Inc. Dan Malek (dmalek@jlc.net) - * - * This version of the driver is a combination of the 8xx fec and - * 8260 SCC Ethernet drivers. People seem to be choosing common I/O - * configurations, so this driver will work on the EST8260 boards and - * others yet to be announced. - * - * Right now, I am very watseful with the buffers. I allocate memory - * pages and then divide them into 2K frame buffers. This way I know I - * have buffers large enough to hold one frame within one buffer descriptor. - * Once I get this working, I will use 64 or 128 byte CPM buffers, which - * will be much more memory efficient and will easily handle lots of - * small packets. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* The transmitter timeout - */ -#define TX_TIMEOUT (2*HZ) - -/* The number of Tx and Rx buffers. These are allocated from the page - * pool. The code may assume these are power of two, so it is best - * to keep them that size. - * We don't need to allocate pages for the transmitter. We just use - * the skbuffer directly. - */ -#define FCC_ENET_RX_PAGES 16 -#define FCC_ENET_RX_FRSIZE 2048 -#define FCC_ENET_RX_FRPPG (PAGE_SIZE / FCC_ENET_RX_FRSIZE) -#define RX_RING_SIZE (FCC_ENET_RX_FRPPG * FCC_ENET_RX_PAGES) -#define TX_RING_SIZE 16 /* Must be power of two */ -#define TX_RING_MOD_MASK 15 /* for this to work */ - -/* The FCC stores dest/src/type, data, and checksum for receive packets. - */ -#define PKT_MAXBUF_SIZE 1518 -#define PKT_MINBUF_SIZE 64 - -/* Maximum input DMA size. Must be a should(?) be a multiple of 4. -*/ -#define PKT_MAXDMA_SIZE 1520 - -/* Maximum input buffer size. Must be a multiple of 32. -*/ -#define PKT_MAXBLR_SIZE 1536 - -static int fcc_enet_open(struct net_device *dev); -static int fcc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev); -static int fcc_enet_rx(struct net_device *dev); -static void fcc_enet_mii(struct net_device *dev); -static void fcc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs); -static int fcc_enet_close(struct net_device *dev); -static struct net_device_stats *fcc_enet_get_stats(struct net_device *dev); -static void set_multicast_list(struct net_device *dev); -static void restart_fcc(struct net_device *dev); - -/* These will be configurable for the FCC choice. - * Multiple ports can be configured. There is little choice among the - * I/O pins to the PHY, except the clocks. We will need some board - * dependent clock selection. - * Why in the hell did I put these inside #ifdef's? I dunno, maybe to - * help show what pins are used for each device. - */ - -/* I/O Pin assignment for FCC1. I don't yet know the best way to do this, - * but there is little variation among the choices. - */ -#define PA1_COL ((uint)0x00000001) -#define PA1_CRS ((uint)0x00000002) -#define PA1_TXER ((uint)0x00000004) -#define PA1_TXEN ((uint)0x00000008) -#define PA1_RXDV ((uint)0x00000010) -#define PA1_RXER ((uint)0x00000020) -#define PA1_TXDAT ((uint)0x00003c00) -#define PA1_RXDAT ((uint)0x0003c000) -#define PA1_PSORA0 (PA1_RXDAT | PA1_TXDAT) -#define PA1_PSORA1 (PA1_COL | PA1_CRS | PA1_TXER | PA1_TXEN | \ - PA1_RXDV | PA1_RXER) -#define PA1_DIRA0 (PA1_RXDAT | PA1_CRS | PA1_COL | PA1_RXER | PA1_RXDV) -#define PA1_DIRA1 (PA1_TXDAT | PA1_TXEN | PA1_TXER) - -/* CLK12 is receive, CLK11 is transmit. These are board specific. -*/ -#define PC_F1RXCLK ((uint)0x00000800) -#define PC_F1TXCLK ((uint)0x00000400) -#define CMX1_CLK_ROUTE ((uint)0x3e000000) -#define CMX1_CLK_MASK ((uint)0xff000000) - -/* I/O Pin assignment for FCC2. I don't yet know the best way to do this, - * but there is little variation among the choices. - */ -#define PB2_TXER ((uint)0x00000001) -#define PB2_RXDV ((uint)0x00000002) -#define PB2_TXEN ((uint)0x00000004) -#define PB2_RXER ((uint)0x00000008) -#define PB2_COL ((uint)0x00000010) -#define PB2_CRS ((uint)0x00000020) -#define PB2_TXDAT ((uint)0x000003c0) -#define PB2_RXDAT ((uint)0x00003c00) -#define PB2_PSORB0 (PB2_RXDAT | PB2_TXDAT | PB2_CRS | PB2_COL | \ - PB2_RXER | PB2_RXDV | PB2_TXER) -#define PB2_PSORB1 (PB2_TXEN) -#define PB2_DIRB0 (PB2_RXDAT | PB2_CRS | PB2_COL | PB2_RXER | PB2_RXDV) -#define PB2_DIRB1 (PB2_TXDAT | PB2_TXEN | PB2_TXER) - -/* CLK13 is receive, CLK14 is transmit. These are board dependent. -*/ -#define PC_F2RXCLK ((uint)0x00001000) -#define PC_F2TXCLK ((uint)0x00002000) -#define CMX2_CLK_ROUTE ((uint)0x00250000) -#define CMX2_CLK_MASK ((uint)0x00ff0000) - -/* I/O Pin assignment for FCC3. I don't yet know the best way to do this, - * but there is little variation among the choices. - */ -#define PB3_RXDV ((uint)0x00004000) -#define PB3_RXER ((uint)0x00008000) -#define PB3_TXER ((uint)0x00010000) -#define PB3_TXEN ((uint)0x00020000) -#define PB3_COL ((uint)0x00040000) -#define PB3_CRS ((uint)0x00080000) -#define PB3_TXDAT ((uint)0x0f000000) -#define PB3_RXDAT ((uint)0x00f00000) -#define PB3_PSORB0 (PB3_RXDAT | PB3_TXDAT | PB3_CRS | PB3_COL | \ - PB3_RXER | PB3_RXDV | PB3_TXER | PB3_TXEN) -#define PB3_PSORB1 (0) -#define PB3_DIRB0 (PB3_RXDAT | PB3_CRS | PB3_COL | PB3_RXER | PB3_RXDV) -#define PB3_DIRB1 (PB3_TXDAT | PB3_TXEN | PB3_TXER) - -/* CLK15 is receive, CLK16 is transmit. These are board dependent. -*/ -#define PC_F3RXCLK ((uint)0x00004000) -#define PC_F3TXCLK ((uint)0x00008000) -#define CMX3_CLK_ROUTE ((uint)0x00003700) -#define CMX3_CLK_MASK ((uint)0x0000ff00) - -/* MII status/control serial interface. -*/ -#define PC_MDIO ((uint)0x00400000) -#define PC_MDCK ((uint)0x00200000) - -/* A table of information for supporting FCCs. This does two things. - * First, we know how many FCCs we have and they are always externally - * numbered from zero. Second, it holds control register and I/O - * information that could be different among board designs. - */ -typedef struct fcc_info { - uint fc_fccnum; - uint fc_cpmblock; - uint fc_cpmpage; - uint fc_proff; - uint fc_interrupt; - uint fc_trxclocks; - uint fc_clockroute; - uint fc_clockmask; - uint fc_mdio; - uint fc_mdck; -} fcc_info_t; - -static fcc_info_t fcc_ports[] = { -#ifdef CONFIG_FCC1_ENET - { 0, CPM_CR_FCC1_SBLOCK, CPM_CR_FCC1_PAGE, PROFF_FCC1, SIU_INT_FCC1, - (PC_F1RXCLK | PC_F1TXCLK), CMX1_CLK_ROUTE, CMX1_CLK_MASK, - PC_MDIO, PC_MDCK }, -#endif -#ifdef CONFIG_FCC2_ENET - { 1, CPM_CR_FCC2_SBLOCK, CPM_CR_FCC2_PAGE, PROFF_FCC2, SIU_INT_FCC2, - (PC_F2RXCLK | PC_F2TXCLK), CMX2_CLK_ROUTE, CMX2_CLK_MASK, - PC_MDIO, PC_MDCK }, -#endif -#ifdef CONFIG_FCC3_ENET - { 2, CPM_CR_FCC3_SBLOCK, CPM_CR_FCC3_PAGE, PROFF_FCC3, SIU_INT_FCC3, - (PC_F3RXCLK | PC_F3TXCLK), CMX3_CLK_ROUTE, CMX3_CLK_MASK, - PC_MDIO, PC_MDCK }, -#endif -}; - -/* The FCC buffer descriptors track the ring buffers. The rx_bd_base and - * tx_bd_base always point to the base of the buffer descriptors. The - * cur_rx and cur_tx point to the currently available buffer. - * The dirty_tx tracks the current buffer that is being sent by the - * controller. The cur_tx and dirty_tx are equal under both completely - * empty and completely full conditions. The empty/ready indicator in - * the buffer descriptor determines the actual condition. - */ -struct fcc_enet_private { - /* The saved address of a sent-in-place packet/buffer, for skfree(). */ - struct sk_buff* tx_skbuff[TX_RING_SIZE]; - ushort skb_cur; - ushort skb_dirty; - - /* CPM dual port RAM relative addresses. - */ - cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */ - cbd_t *tx_bd_base; - cbd_t *cur_rx, *cur_tx; /* The next free ring entry */ - cbd_t *dirty_tx; /* The ring entries to be free()ed. */ - volatile fcc_t *fccp; - volatile fcc_enet_t *ep; - struct net_device_stats stats; - uint tx_full; - spinlock_t lock; - uint phy_address; - uint phy_type; - uint phy_duplex; - fcc_info_t *fip; -}; - -static void init_fcc_shutdown(fcc_info_t *fip, struct fcc_enet_private *cep, - volatile immap_t *immap); -static void init_fcc_startup(fcc_info_t *fip, struct net_device *dev); -static void init_fcc_ioports(fcc_info_t *fip, volatile iop8260_t *io, - volatile immap_t *immap); -static void init_fcc_param(fcc_info_t *fip, struct net_device *dev, - volatile immap_t *immap); - -/* MII processing. We keep this as simple as possible. Requests are - * placed on the list (if there is room). When the request is finished - * by the MII, an optional function may be called. - */ -typedef struct mii_list { - uint mii_regval; - void (*mii_func)(uint val, struct net_device *dev); - struct mii_list *mii_next; -} mii_list_t; - -#define NMII 20 -mii_list_t mii_cmds[NMII]; -mii_list_t *mii_free; -mii_list_t *mii_head; -mii_list_t *mii_tail; - -static int phyaddr; -static uint phytype; - -static int mii_queue(int request, void (*func)(uint, struct net_device *)); -static void mii_startup_cmds(void); -static uint mii_send_receive(fcc_info_t *fip, uint cmd); - -/* Make MII read/write commands for the FCC. -*/ - -#define mk_mii_phyaddr(ADDR) (0x60020000 | ((ADDR) << 23) | (2 << 18)) - -#define mk_mii_read(REG) (0x60020000 | ((phyaddr << 23) | \ - (REG & 0x1f) << 18)) - -#define mk_mii_write(REG, VAL) (0x50020000 | ((phyaddr << 23) | \ - (REG & 0x1f) << 18) | \ - (VAL & 0xffff)) - - -static int -fcc_enet_open(struct net_device *dev) -{ - netif_start_queue(dev); - return 0; /* Always succeed */ -} - -static int -fcc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct fcc_enet_private *cep = (struct fcc_enet_private *)dev->priv; - volatile cbd_t *bdp; - - - /* Fill in a Tx ring entry */ - bdp = cep->cur_tx; - -#ifndef final_version - if (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. - */ - printk("%s: tx queue full!.\n", dev->name); - return 1; - } -#endif - - /* Clear all of the status flags. - */ - bdp->cbd_sc &= ~BD_ENET_TX_STATS; - - /* If the frame is short, tell CPM to pad it. - */ - if (skb->len <= ETH_ZLEN) - bdp->cbd_sc |= BD_ENET_TX_PAD; - else - bdp->cbd_sc &= ~BD_ENET_TX_PAD; - - /* Set buffer length and buffer pointer. - */ - bdp->cbd_datlen = skb->len; - bdp->cbd_bufaddr = __pa(skb->data); - - /* Save skb pointer. - */ - cep->tx_skbuff[cep->skb_cur] = skb; - - 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, - * its the last BD of the frame, and to put the CRC on the end. - */ - bdp->cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | BD_ENET_TX_LAST | BD_ENET_TX_TC); - -#if 0 - /* Errata says don't do this. - */ - cep->fccp->fcc_ftodr = 0x8000; -#endif - dev->trans_start = jiffies; - - /* If this was the last BD in the ring, start at the beginning again. - */ - if (bdp->cbd_sc & BD_ENET_TX_WRAP) - bdp = cep->tx_bd_base; - else - bdp++; - - if (bdp->cbd_sc & BD_ENET_TX_READY) { - netif_stop_queue(dev); - cep->tx_full = 1; - } - - cep->cur_tx = (cbd_t *)bdp; - - spin_unlock_irq(&cep->lock); - - return 0; -} - - -static void -fcc_enet_timeout(struct net_device *dev) -{ - struct fcc_enet_private *cep = (struct fcc_enet_private *)dev->priv; - - printk("%s: transmit timed out.\n", dev->name); - cep->stats.tx_errors++; -#ifndef final_version - { - int i; - cbd_t *bdp; - printk(" Ring data dump: cur_tx %p%s cur_rx %p.\n", - cep->cur_tx, cep->tx_full ? " (full)" : "", - cep->cur_rx); - bdp = cep->tx_bd_base; - printk(" Tx @base %p :\n", bdp); - for (i = 0 ; i < TX_RING_SIZE; i++, bdp++) - printk("%04x %04x %08x\n", - bdp->cbd_sc, - bdp->cbd_datlen, - bdp->cbd_bufaddr); - bdp = cep->rx_bd_base; - printk(" Rx @base %p :\n", bdp); - for (i = 0 ; i < RX_RING_SIZE; i++, bdp++) - printk("%04x %04x %08x\n", - bdp->cbd_sc, - bdp->cbd_datlen, - bdp->cbd_bufaddr); - } -#endif - if (!cep->tx_full) - netif_wake_queue(dev); -} - -/* The interrupt handler. - */ -static void -fcc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs) -{ - struct net_device *dev = dev_id; - volatile struct fcc_enet_private *cep; - volatile cbd_t *bdp; - ushort int_events; - int must_restart; - - cep = (struct fcc_enet_private *)dev->priv; - - /* Get the interrupt events that caused us to be here. - */ - int_events = cep->fccp->fcc_fcce; - cep->fccp->fcc_fcce = int_events; - must_restart = 0; - - /* Handle receive event in its own function. - */ - if (int_events & FCC_ENET_RXF) - fcc_enet_rx(dev_id); - - /* Check for a transmit error. The manual is a little unclear - * about this, so the debug code until I get it figured out. It - * appears that if TXE is set, then TXB is not set. However, - * if carrier sense is lost during frame transmission, the TXE - * bit is set, "and continues the buffer transmission normally." - * I don't know if "normally" implies TXB is set when the buffer - * descriptor is closed.....trial and error :-). - */ - - /* Transmit OK, or non-fatal error. Update the buffer descriptors. - */ - if (int_events & (FCC_ENET_TXE | FCC_ENET_TXB)) { - 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)) - break; - - if (bdp->cbd_sc & BD_ENET_TX_HB) /* No heartbeat */ - cep->stats.tx_heartbeat_errors++; - if (bdp->cbd_sc & BD_ENET_TX_LC) /* Late collision */ - cep->stats.tx_window_errors++; - if (bdp->cbd_sc & BD_ENET_TX_RL) /* Retrans limit */ - cep->stats.tx_aborted_errors++; - if (bdp->cbd_sc & BD_ENET_TX_UN) /* Underrun */ - cep->stats.tx_fifo_errors++; - if (bdp->cbd_sc & BD_ENET_TX_CSL) /* Carrier lost */ - cep->stats.tx_carrier_errors++; - - - /* No heartbeat or Lost carrier are not really bad errors. - * The others require a restart transmit command. - */ - if (bdp->cbd_sc & - (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) { - must_restart = 1; - cep->stats.tx_errors++; - } - - cep->stats.tx_packets++; - - /* Deferred means some collisions occurred during transmit, - * but we eventually sent the packet OK. - */ - if (bdp->cbd_sc & BD_ENET_TX_DEF) - cep->stats.collisions++; - - /* Free the sk buffer associated with this last transmit. - */ - dev_kfree_skb_irq(cep->tx_skbuff[cep->skb_dirty]); - cep->skb_dirty = (cep->skb_dirty + 1) & TX_RING_MOD_MASK; - - /* Update pointer to next buffer descriptor to be transmitted. - */ - if (bdp->cbd_sc & BD_ENET_TX_WRAP) - bdp = cep->tx_bd_base; - else - bdp++; - - /* I don't know if we can be held off from processing these - * interrupts for more than one frame time. I really hope - * not. In such a case, we would now want to check the - * currently available BD (cur_tx) and determine if any - * buffers between the dirty_tx and cur_tx have also been - * sent. We would want to process anything in between that - * does not have BD_ENET_TX_READY set. - */ - - /* Since we have freed up a buffer, the ring is no longer - * full. - */ - if (cep->tx_full) { - cep->tx_full = 0; - if (netif_queue_stopped(dev)) { - netif_wake_queue(dev); - } - } - - cep->dirty_tx = (cbd_t *)bdp; - } - - if (must_restart) { - volatile cpm8260_t *cp; - - /* Some transmit errors cause the transmitter to shut - * down. We now issue a restart transmit. Since the - * errors close the BD and update the pointers, the restart - * _should_ pick up without having to reset any of our - * pointers either. - */ - - cp = cpmp; - cp->cp_cpcr = - mk_cr_cmd(cep->fip->fc_cpmpage, cep->fip->fc_cpmblock, - 0x0c, CPM_CR_RESTART_TX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); - } - spin_unlock(&cep->lock); - } - - /* Check for receive busy, i.e. packets coming but no place to - * put them. - */ - if (int_events & FCC_ENET_BSY) { - cep->stats.rx_dropped++; - } - return; -} - -/* During a receive, the cur_rx points to the current incoming buffer. - * When we update through the ring, if the next incoming buffer has - * not been given to the system, we just set the empty indicator, - * effectively tossing the packet. - */ -static int -fcc_enet_rx(struct net_device *dev) -{ - struct fcc_enet_private *cep; - volatile cbd_t *bdp; - struct sk_buff *skb; - ushort pkt_len; - - cep = (struct fcc_enet_private *)dev->priv; - - /* First, grab all of the stats for the incoming packet. - * These get messed up if we get called due to a busy condition. - */ - bdp = cep->cur_rx; - -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. - */ - if ((bdp->cbd_sc & (BD_ENET_RX_FIRST | BD_ENET_RX_LAST)) != - (BD_ENET_RX_FIRST | BD_ENET_RX_LAST)) - printk("CPM ENET: rcv is not first+last\n"); -#endif - - /* Frame too long or too short. - */ - if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) - cep->stats.rx_length_errors++; - if (bdp->cbd_sc & BD_ENET_RX_NO) /* Frame alignment */ - cep->stats.rx_frame_errors++; - if (bdp->cbd_sc & BD_ENET_RX_CR) /* CRC Error */ - cep->stats.rx_crc_errors++; - if (bdp->cbd_sc & BD_ENET_RX_OV) /* FIFO overrun */ - cep->stats.rx_crc_errors++; - - /* Report late collisions as a frame error. - * On this error, the BD is closed, but we don't know what we - * have in the buffer. So, just drop this frame on the floor. - */ - if (bdp->cbd_sc & BD_ENET_RX_CL) { - cep->stats.rx_frame_errors++; - } - else { - - /* Process the incoming frame. - */ - cep->stats.rx_packets++; - pkt_len = bdp->cbd_datlen; - cep->stats.rx_bytes += pkt_len; - - /* This does 16 byte alignment, much more than we need. - * The packet length includes FCS, but we don't want to - * include that when passing upstream as it messes up - * bridging applications. - */ - skb = dev_alloc_skb(pkt_len-4); - - if (skb == NULL) { - printk("%s: Memory squeeze, dropping packet.\n", dev->name); - cep->stats.rx_dropped++; - } - else { - skb->dev = dev; - skb_put(skb,pkt_len-4); /* Make room */ - eth_copy_and_sum(skb, - (unsigned char *)__va(bdp->cbd_bufaddr), - pkt_len-4, 0); - skb->protocol=eth_type_trans(skb,dev); - netif_rx(skb); - } - } - - /* Clear the status flags for this buffer. - */ - bdp->cbd_sc &= ~BD_ENET_RX_STATS; - - /* Mark the buffer empty. - */ - bdp->cbd_sc |= BD_ENET_RX_EMPTY; - - /* Update BD pointer to next entry. - */ - if (bdp->cbd_sc & BD_ENET_RX_WRAP) - bdp = cep->rx_bd_base; - else - bdp++; - - } - cep->cur_rx = (cbd_t *)bdp; - - return 0; -} - -static int -fcc_enet_close(struct net_device *dev) -{ - /* Don't know what to do yet. - */ - netif_stop_queue(dev); - - return 0; -} - -static struct net_device_stats *fcc_enet_get_stats(struct net_device *dev) -{ - struct fcc_enet_private *cep = (struct fcc_enet_private *)dev->priv; - - return &cep->stats; -} - -/* The MII is simulated from the 8xx FEC implementation. The FCC - * is not responsible for the MII control/status interface. - */ -static void -fcc_enet_mii(struct net_device *dev) -{ - struct fcc_enet_private *fep; - mii_list_t *mip; - uint mii_reg; - - fep = (struct fcc_enet_private *)dev->priv; -#if 0 - 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; - } - - if (mip->mii_func != NULL) - (*(mip->mii_func))(mii_reg, dev); - - mii_head = mip->mii_next; - mip->mii_next = mii_free; - mii_free = mip; - -#if 0 - if ((mip = mii_head) != NULL) - ep->fec_mii_data = mip->mii_regval; -#endif -} - -static int -mii_queue(int regval, void (*func)(uint, struct net_device *)) -{ - unsigned long flags; - mii_list_t *mip; - int retval; - - retval = 0; - - save_flags(flags); - cli(); - - if ((mip = mii_free) != NULL) { - mii_free = mip->mii_next; - mip->mii_regval = regval; - mip->mii_func = func; - mip->mii_next = NULL; - if (mii_head) { - mii_tail->mii_next = mip; - mii_tail = mip; - } - else { - mii_head = mii_tail = mip; -#if 0 - (&(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec))->fec_mii_data = regval; -#endif - } - } - else { - retval = 1; - } - - restore_flags(flags); - - return(retval); -} - -static volatile uint full_duplex; - -static void -mii_status(uint mii_reg, struct net_device *dev) -{ - volatile uint prev_duplex; - - if (((mii_reg >> 18) & 0x1f) == 1) { - /* status register. - */ - printk("fec: "); - if (mii_reg & 0x0004) - printk("link up"); - else - printk("link down"); - - if (mii_reg & 0x0010) - printk(",remote fault"); - if (mii_reg & 0x0020) - printk(",auto complete"); - printk("\n"); - } - if (((mii_reg >> 18) & 0x1f) == 0x14) { - /* Extended chip status register. - */ - prev_duplex = full_duplex; - printk("fec: "); - if (mii_reg & 0x0800) - printk("100 Mbps"); - else - printk("10 Mbps"); - - if (mii_reg & 0x1000) { - printk(", Full-Duplex\n"); - full_duplex = 1; - } - else { - printk(", Half-Duplex\n"); - full_duplex = 0; - } -#if 0 - if (prev_duplex != full_duplex) - restart_fec(dev); -#endif - } - if (((mii_reg >> 18) & 0x1f) == 31) { - /* QS6612 PHY Control/Status. - * OK, now we have it all, so figure out what is going on. - */ - prev_duplex = full_duplex; - printk("fec: "); - - mii_reg = (mii_reg >> 2) & 7; - - if (mii_reg & 1) - printk("10 Mbps"); - else - printk("100 Mbps"); - - if (mii_reg > 4) { - printk(", Full-Duplex\n"); - full_duplex = 1; - } - else { - printk(", Half-Duplex\n"); - full_duplex = 0; - } - -#if 0 - if (prev_duplex != full_duplex) - restart_fec(dev); -#endif - } -} - -static uint phyno; - -static void -mii_discover_phy3(uint mii_reg, struct net_device *dev) -{ - phytype <<= 16; - phytype |= (mii_reg & 0xffff); - printk("fec: Phy @ 0x%x, type 0x%08x\n", phyno, phytype); - mii_startup_cmds(); -} - -static void -mii_discover_phy(uint mii_reg, struct net_device *dev) -{ - if (phyno < 32) { - if ((phytype = (mii_reg & 0xffff)) != 0xffff) { - phyaddr = phyno; - mii_queue(mk_mii_read(3), mii_discover_phy3); - } - else { - phyno++; - mii_queue(mk_mii_phyaddr(phyno), mii_discover_phy); - } - } - else { - printk("FEC: No PHY device found.\n"); - } -} - -static void -mii_discover_phy_poll(fcc_info_t *fip) -{ - uint rv; - int i; - - for (i=0; i<32; i++) { - rv = mii_send_receive(fip, mk_mii_phyaddr(i)); - if ((phytype = (rv & 0xffff)) != 0xffff) { - phyaddr = i; - rv = mii_send_receive(fip, mk_mii_read(3)); - phytype <<= 16; - phytype |= (rv & 0xffff); - printk("fec: Phy @ 0x%x, type 0x%08x\n", phyaddr, phytype); - } - } -} - -static void -mii_startup_cmds(void) -{ - -#if 1 - /* Level One PHY. - */ - - /* Read status registers to clear any pending interrupt. - */ - mii_queue(mk_mii_read(1), mii_status); - mii_queue(mk_mii_read(18), mii_status); - - /* Read extended chip status register. - */ - mii_queue(mk_mii_read(0x14), mii_status); - - /* Set default operation of 100-TX....for some reason - * some of these bits are set on power up, which is wrong. - */ - mii_queue(mk_mii_write(0x13, 0), NULL); - - /* Enable Link status change interrupts. - */ - mii_queue(mk_mii_write(0x11, 0x0002), NULL); - - /* Don't advertize Full duplex. - mii_queue(mk_mii_write(0x04, 0x0021), NULL); - */ -#endif - -} - -/* This supports the mii_link interrupt below. - * We should get called three times. Once for register 1, once for - * register 18, and once for register 20. - */ -static uint mii_saved_reg1; - -static void -mii_relink(uint mii_reg, struct net_device *dev) -{ - volatile uint prev_duplex; - unsigned long flags; - - if (((mii_reg >> 18) & 0x1f) == 1) { - /* Just save the status register and get out. - */ - mii_saved_reg1 = mii_reg; - return; - } - if (((mii_reg >> 18) & 0x1f) == 18) { - /* Not much here, but has to be read to clear the - * interrupt condition. - */ - if ((mii_reg & 0x8000) == 0) - printk("fec: re-link and no IRQ?\n"); - if ((mii_reg & 0x4000) == 0) - printk("fec: no PHY power?\n"); - } - if (((mii_reg >> 18) & 0x1f) == 20) { - /* Extended chip status register. - * OK, now we have it all, so figure out what is going on. - */ - prev_duplex = full_duplex; - printk("fec: "); - if (mii_saved_reg1 & 0x0004) - printk("link up"); - else - printk("link down"); - - if (mii_saved_reg1 & 0x0010) - printk(", remote fault"); - if (mii_saved_reg1 & 0x0020) - printk(", auto complete"); - - if (mii_reg & 0x0800) - printk(", 100 Mbps"); - else - printk(", 10 Mbps"); - - if (mii_reg & 0x1000) { - printk(", Full-Duplex\n"); - full_duplex = 1; - } - else { - printk(", Half-Duplex\n"); - full_duplex = 0; - } - if (prev_duplex != full_duplex) { - save_flags(flags); - cli(); -#if 0 - restart_fec(dev); -#endif - restore_flags(flags); - } - } - if (((mii_reg >> 18) & 0x1f) == 31) { - /* QS6612 PHY Control/Status. - * OK, now we have it all, so figure out what is going on. - */ - prev_duplex = full_duplex; - printk("fec: "); - if (mii_saved_reg1 & 0x0004) - printk("link up"); - else - printk("link down"); - - if (mii_saved_reg1 & 0x0010) - printk(", remote fault"); - if (mii_saved_reg1 & 0x0020) - printk(", auto complete"); - - mii_reg = (mii_reg >> 2) & 7; - - if (mii_reg & 1) - printk(", 10 Mbps"); - else - printk(", 100 Mbps"); - - if (mii_reg > 4) { - printk(", Full-Duplex\n"); - full_duplex = 1; - } - else { - printk(", Half-Duplex\n"); - full_duplex = 0; - } - -#if 0 - if (prev_duplex != full_duplex) { - save_flags(flags); - cli(); - restart_fec(dev); - restore_flags(flags); - } -#endif - } -} - -/* Set or clear the multicast filter for this adaptor. - * Skeleton taken from sunlance driver. - * The CPM Ethernet implementation allows Multicast as well as individual - * MAC address filtering. Some of the drivers check to make sure it is - * a group multicast address, and discard those that are not. I guess I - * will do the same for now, but just remove the test if you want - * individual filtering as well (do the upper net layers want or support - * this kind of feature?). - */ -static void -set_multicast_list(struct net_device *dev) -{ - struct fcc_enet_private *cep; - struct dev_mc_list *dmi; - u_char *mcptr, *tdptr; - volatile fcc_enet_t *ep; - int i, j; - - cep = (struct fcc_enet_private *)dev->priv; - -return; - /* Get pointer to FCC area in parameter RAM. - */ - 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; - } else { - - cep->fccp->fcc_fpsmr &= ~FCC_PSMR_PRO; - - if (dev->flags & IFF_ALLMULTI) { - /* Catch all multicast addresses, so set the - * filter to all 1's. - */ - ep->fen_gaddrh = 0xffffffff; - ep->fen_gaddrl = 0xffffffff; - } - else { - /* Clear filter and add the addresses in the list. - */ - ep->fen_gaddrh = 0; - ep->fen_gaddrl = 0; - - dmi = dev->mc_list; - - for (i=0; imc_count; i++) { - - /* Only support group multicast for now. - */ - if (!(dmi->dmi_addr[0] & 1)) - continue; - - /* The address in dmi_addr is LSB first, - * and taddr is MSB first. We have to - * copy bytes MSB first from dmi_addr. - */ - mcptr = (u_char *)dmi->dmi_addr + 5; - tdptr = (u_char *)&ep->fen_taddrh; - for (j=0; j<6; j++) - *tdptr++ = *mcptr--; - - /* Ask CPM to run CRC and set bit in - * filter mask. - */ - cpmp->cp_cpcr = mk_cr_cmd(cep->fip->fc_cpmpage, - cep->fip->fc_cpmblock, 0x0c, - CPM_CR_SET_GADDR) | CPM_CR_FLG; - udelay(10); - while (cpmp->cp_cpcr & CPM_CR_FLG); - } - } - } -} - -/* Initialize the CPM Ethernet on FCC. - */ -int __init fec_enet_init(void) -{ - struct net_device *dev; - struct fcc_enet_private *cep; - fcc_info_t *fip; - int i, np; - volatile immap_t *immap; - volatile iop8260_t *io; - - immap = (immap_t *)IMAP_ADDR; /* and to internal registers */ - io = &immap->im_ioport; - - np = sizeof(fcc_ports) / sizeof(fcc_info_t); - fip = fcc_ports; - - while (np-- > 0) { - - /* Allocate some private information. - */ - cep = (struct fcc_enet_private *) - kmalloc(sizeof(*cep), GFP_KERNEL); - if (cep == NULL) - return -ENOMEM; - - __clear_user(cep,sizeof(*cep)); - spin_lock_init(&cep->lock); - cep->fip = fip; - - /* Create an Ethernet device instance. - */ - dev = init_etherdev(0, 0); - dev->priv = cep; - - init_fcc_shutdown(fip, cep, immap); - init_fcc_ioports(fip, io, immap); - init_fcc_param(fip, dev, immap); - - dev->base_addr = (unsigned long)(cep->ep); - - /* The CPM Ethernet specific entries in the device - * structure. - */ - dev->open = fcc_enet_open; - dev->hard_start_xmit = fcc_enet_start_xmit; - dev->tx_timeout = fcc_enet_timeout; - dev->watchdog_timeo = TX_TIMEOUT; - dev->stop = fcc_enet_close; - dev->get_stats = fcc_enet_get_stats; - dev->set_multicast_list = set_multicast_list; - - init_fcc_startup(fip, dev); - - printk("%s: FCC ENET Version 0.2, ", dev->name); - for (i=0; i<5; i++) - printk("%02x:", dev->dev_addr[i]); - printk("%02x\n", dev->dev_addr[5]); - - /* This is just a hack for now that works only on the EST - * board, or anything else that has MDIO/CK configured. - * It is mainly to test the MII software clocking. - */ - mii_discover_phy_poll(fip); - - fip++; - } - - return 0; -} - -/* Make sure the device is shut down during initialization. -*/ -static void __init -init_fcc_shutdown(fcc_info_t *fip, struct fcc_enet_private *cep, - volatile immap_t *immap) -{ - volatile fcc_enet_t *ep; - volatile fcc_t *fccp; - - /* Get pointer to FCC area in parameter RAM. - */ - ep = (fcc_enet_t *)(&immap->im_dprambase[fip->fc_proff]); - - /* And another to the FCC register area. - */ - fccp = (volatile fcc_t *)(&immap->im_fcc[fip->fc_fccnum]); - cep->fccp = fccp; /* Keep the pointers handy */ - cep->ep = ep; - - /* Disable receive and transmit in case someone left it running. - */ - fccp->fcc_gfmr &= ~(FCC_GFMR_ENR | FCC_GFMR_ENT); -} - -/* Initialize the I/O pins for the FCC Ethernet. -*/ -static void __init -init_fcc_ioports(fcc_info_t *fip, volatile iop8260_t *io, - volatile immap_t *immap) -{ - - /* FCC1 pins are on port A/C. FCC2/3 are port B/C. - */ - if (fip->fc_proff == PROFF_FCC1) { - /* Configure port A and C pins for FCC1 Ethernet. - */ - io->iop_pdira &= ~PA1_DIRA0; - io->iop_pdira |= PA1_DIRA1; - io->iop_psora &= ~PA1_PSORA0; - io->iop_psora |= PA1_PSORA1; - io->iop_ppara |= (PA1_DIRA0 | PA1_DIRA1); - } - if (fip->fc_proff == PROFF_FCC2) { - /* Configure port B and C pins for FCC Ethernet. - */ - io->iop_pdirb &= ~PB2_DIRB0; - io->iop_pdirb |= PB2_DIRB1; - io->iop_psorb &= ~PB2_PSORB0; - io->iop_psorb |= PB2_PSORB1; - io->iop_pparb |= (PB2_DIRB0 | PB2_DIRB1); - } - if (fip->fc_proff == PROFF_FCC3) { - /* Configure port B and C pins for FCC Ethernet. - */ - io->iop_pdirb &= ~PB3_DIRB0; - io->iop_pdirb |= PB3_DIRB1; - io->iop_psorb &= ~PB3_PSORB0; - io->iop_psorb |= PB3_PSORB1; - io->iop_pparb |= (PB3_DIRB0 | PB3_DIRB1); - } - - /* Port C has clocks...... - */ - io->iop_psorc &= ~(fip->fc_trxclocks); - io->iop_pdirc &= ~(fip->fc_trxclocks); - io->iop_pparc |= fip->fc_trxclocks; - - /* ....and the MII serial clock/data. - */ - io->iop_pdatc |= (fip->fc_mdio | fip->fc_mdck); - io->iop_podrc |= fip->fc_mdio; - io->iop_pdirc |= (fip->fc_mdio | fip->fc_mdck); - io->iop_pparc &= ~(fip->fc_mdio | fip->fc_mdck); - - /* Configure Serial Interface clock routing. - * First, clear all FCC bits to zero, - * then set the ones we want. - */ - immap->im_cpmux.cmx_fcr &= ~(fip->fc_clockmask); - immap->im_cpmux.cmx_fcr |= fip->fc_clockroute; -} - -static void __init -init_fcc_param(fcc_info_t *fip, struct net_device *dev, - volatile immap_t *immap) -{ - unsigned char *eap; - unsigned long mem_addr; - bd_t *bd; - int i, j; - struct fcc_enet_private *cep; - volatile fcc_enet_t *ep; - volatile cbd_t *bdp; - volatile cpm8260_t *cp; - - cep = (struct fcc_enet_private *)(dev->priv); - ep = cep->ep; - cp = cpmp; - - bd = (bd_t *)__res; - - /* Zero the whole thing.....I must have missed some individually. - * It works when I do this. - */ - memset((char *)ep, 0, sizeof(fcc_enet_t)); - - /* Allocate space for the buffer descriptors in the DP ram. - * These are relative offsets in the DP ram address space. - * Initialize base addresses for the buffer descriptors. - */ -#if 0 - /* I really want to do this, but for some reason it doesn't - * work with the data cache enabled, so I allocate from the - * main memory instead. - */ - i = m8260_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE, 8); - ep->fen_genfcc.fcc_rbase = (uint)&immap->im_dprambase[i]; - cep->rx_bd_base = (cbd_t *)&immap->im_dprambase[i]; - - i = m8260_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE, 8); - ep->fen_genfcc.fcc_tbase = (uint)&immap->im_dprambase[i]; - cep->tx_bd_base = (cbd_t *)&immap->im_dprambase[i]; -#else - cep->rx_bd_base = (cbd_t *)m8260_cpm_hostalloc(sizeof(cbd_t) * RX_RING_SIZE, 8); - ep->fen_genfcc.fcc_rbase = __pa(cep->rx_bd_base); - cep->tx_bd_base = (cbd_t *)m8260_cpm_hostalloc(sizeof(cbd_t) * TX_RING_SIZE, 8); - ep->fen_genfcc.fcc_tbase = __pa(cep->tx_bd_base); -#endif - - cep->dirty_tx = cep->cur_tx = cep->tx_bd_base; - cep->cur_rx = cep->rx_bd_base; - - ep->fen_genfcc.fcc_rstate = (CPMFCR_GBL | CPMFCR_EB) << 24; - ep->fen_genfcc.fcc_tstate = (CPMFCR_GBL | CPMFCR_EB) << 24; - - /* Set maximum bytes per receive buffer. - * It must be a multiple of 32. - */ - ep->fen_genfcc.fcc_mrblr = PKT_MAXBLR_SIZE; - - /* Allocate space in the reserved FCC area of DPRAM for the - * internal buffers. No one uses this space (yet), so we - * can do this. Later, we will add resource management for - * this area. - */ - mem_addr = CPM_FCC_SPECIAL_BASE + (fip->fc_fccnum * 128); - ep->fen_genfcc.fcc_riptr = mem_addr; - 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; - ep->fen_genfcc.fcc_tcrc = 0; - ep->fen_genfcc.fcc_res1 = 0; - ep->fen_genfcc.fcc_res2 = 0; - - ep->fen_camptr = 0; /* CAM isn't used in this driver */ - - /* Set CRC preset and mask. - */ - ep->fen_cmask = 0xdebb20e3; - ep->fen_cpres = 0xffffffff; - - ep->fen_crcec = 0; /* CRC Error counter */ - ep->fen_alec = 0; /* alignment error counter */ - ep->fen_disfc = 0; /* discard frame counter */ - ep->fen_retlim = 15; /* Retry limit threshold */ - ep->fen_pper = 0; /* Normal persistence */ - - /* Clear hash filter tables. - */ - ep->fen_gaddrh = 0; - ep->fen_gaddrl = 0; - ep->fen_iaddrh = 0; - ep->fen_iaddrl = 0; - - /* Clear the Out-of-sequence TxBD. - */ - ep->fen_tfcstat = 0; - ep->fen_tfclen = 0; - ep->fen_tfcptr = 0; - - ep->fen_mflr = PKT_MAXBUF_SIZE; /* maximum frame length register */ - ep->fen_minflr = PKT_MINBUF_SIZE; /* minimum frame length register */ - - /* Set Ethernet station address. - * - * This is supplied in the board information structure, so we - * copy that into the controller. - * So, far we have only been given one Ethernet address. We make - * it unique by setting a few bits in the upper byte of the - * non-static part of the address. - */ - eap = (unsigned char *)&(ep->fen_paddrh); - for (i=5; i>=0; i--) { - if (i == 3) { - dev->dev_addr[i] = bd->bi_enetaddr[i]; - dev->dev_addr[i] |= (1 << (7 - fip->fc_fccnum)); - *eap++ = dev->dev_addr[i]; - } - else { - *eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i]; - } - } - - ep->fen_taddrh = 0; - ep->fen_taddrm = 0; - ep->fen_taddrl = 0; - - ep->fen_maxd1 = PKT_MAXDMA_SIZE; /* maximum DMA1 length */ - ep->fen_maxd2 = PKT_MAXDMA_SIZE; /* maximum DMA2 length */ - - /* Clear stat counters, in case we ever enable RMON. - */ - ep->fen_octc = 0; - ep->fen_colc = 0; - ep->fen_broc = 0; - ep->fen_mulc = 0; - ep->fen_uspc = 0; - ep->fen_frgc = 0; - ep->fen_ospc = 0; - ep->fen_jbrc = 0; - ep->fen_p64c = 0; - ep->fen_p65c = 0; - ep->fen_p128c = 0; - ep->fen_p256c = 0; - ep->fen_p512c = 0; - ep->fen_p1024c = 0; - - ep->fen_rfthr = 0; /* Suggested by manual */ - ep->fen_rfcnt = 0; - ep->fen_cftype = 0; - - /* Now allocate the host memory pages and initialize the - * buffer descriptors. - */ - bdp = cep->tx_bd_base; - for (i=0; icbd_sc = 0; - bdp->cbd_datlen = 0; - bdp->cbd_bufaddr = 0; - bdp++; - } - - /* Set the last buffer to wrap. - */ - bdp--; - bdp->cbd_sc |= BD_SC_WRAP; - - bdp = cep->rx_bd_base; - for (i=0; icbd_sc = BD_ENET_RX_EMPTY | BD_ENET_RX_INTR; - bdp->cbd_datlen = 0; - bdp->cbd_bufaddr = __pa(mem_addr); - mem_addr += FCC_ENET_RX_FRSIZE; - bdp++; - } - } - - /* Set the last buffer to wrap. - */ - bdp--; - bdp->cbd_sc |= BD_SC_WRAP; - - /* Let's re-initialize the channel now. We have to do it later - * than the manual describes because we have just now finished - * the BD initialization. - */ - cp->cp_cpcr = mk_cr_cmd(fip->fc_cpmpage, fip->fc_cpmblock, 0x0c, - CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); - - cep->skb_cur = cep->skb_dirty = 0; -} - -/* Let 'er rip. -*/ -static void __init -init_fcc_startup(fcc_info_t *fip, struct net_device *dev) -{ - volatile fcc_t *fccp; - struct fcc_enet_private *cep; - - cep = (struct fcc_enet_private *)(dev->priv); - fccp = cep->fccp; - - fccp->fcc_fcce = 0xffff; /* Clear any pending events */ - - /* Enable interrupts for transmit error, complete frame - * received, and any transmit buffer we have also set the - * interrupt flag. - */ - fccp->fcc_fccm = (FCC_ENET_TXE | FCC_ENET_RXF | FCC_ENET_TXB); - - /* Install our interrupt handler. - */ - if (request_irq(fip->fc_interrupt, fcc_enet_interrupt, 0, "fenet", - dev) < 0) - printk("Can't get FCC IRQ %d\n", fip->fc_interrupt); - - /* Set GFMR to enable Ethernet operating mode. - */ - fccp->fcc_gfmr = (FCC_GFMR_TCI | FCC_GFMR_MODE_ENET); - - /* Set sync/delimiters. - */ - fccp->fcc_fdsr = 0xd555; - - /* Set protocol specific processing mode for Ethernet. - * This has to be adjusted for Full Duplex operation after we can - * determine how to detect that. - */ - fccp->fcc_fpsmr = FCC_PSMR_ENCRC; - - /* And last, enable the transmit and receive processing. - */ - fccp->fcc_gfmr |= (FCC_GFMR_ENR | FCC_GFMR_ENT); -} - -/* MII command/status interface. - * I'm not going to describe all of the details. You can find the - * protocol definition in many other places, including the data sheet - * of most PHY parts. - * I wonder what "they" were thinking (maybe weren't) when they leave - * the I2C in the CPM but I have to toggle these bits...... - */ -static uint -mii_send_receive(fcc_info_t *fip, uint cmd) -{ - unsigned long flags; - uint retval; - int read_op, i; - volatile immap_t *immap; - volatile iop8260_t *io; - - immap = (immap_t *)IMAP_ADDR; - io = &immap->im_ioport; - - /* When we get here, both clock and data are high, outputs. - * Output is open drain. - * Data transitions on high->low clock, is valid on low->high clock. - * Spec says edge transitions no closer than 160 nSec, minimum clock - * cycle 400 nSec. I could only manage about 500 nSec edges with - * an XOR loop, so I won't worry about delays yet. - * I disable interrupts during bit flipping to ensure atomic - * 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. - */ - save_flags(flags); - cli(); - for (i=0; i<64; i++) { - io->iop_pdatc ^= fip->fc_mdck; - udelay(0); - } - restore_flags(flags); - - read_op = ((cmd & 0xf0000000) == 0x60000000); - - /* We return the command word on a write op, or the command portion - * plus the new data on a read op. This is what the 8xx FEC does, - * and it allows the functions to simply look at the returned value - * and know the PHY/register as well. - */ - if (read_op) - retval = cmd; - else - retval = (cmd >> 16); - - /* Clock out the first 16 MS bits of the command. - */ - save_flags(flags); - cli(); - for (i=0; i<16; i++) { - io->iop_pdatc &= ~(fip->fc_mdck); - if (cmd & 0x80000000) - io->iop_pdatc |= fip->fc_mdio; - else - io->iop_pdatc &= ~(fip->fc_mdio); - cmd <<= 1; - io->iop_pdatc |= fip->fc_mdck; - udelay(0); - } - - /* Do the turn-around. If read op, we make the IO and input. - * If write op, do the 1/0 thing. - */ - io->iop_pdatc &= ~(fip->fc_mdck); - if (read_op) - io->iop_pdirc &= ~(fip->fc_mdio); - else - io->iop_pdatc |= fip->fc_mdio; - io->iop_pdatc |= fip->fc_mdck; - - /* I do this mainly to get just a little delay. - */ - restore_flags(flags); - save_flags(flags); - cli(); - io->iop_pdatc &= ~(fip->fc_mdck); - io->iop_pdirc &= ~(fip->fc_mdio); - io->iop_pdatc |= fip->fc_mdck; - - restore_flags(flags); - save_flags(flags); - cli(); - - /* For read, clock in 16 bits. For write, clock out - * rest of command. - */ - if (read_op) { - io->iop_pdatc &= ~(fip->fc_mdck); - udelay(0); - for (i=0; i<16; i++) { - io->iop_pdatc |= fip->fc_mdck; - udelay(0); - retval <<= 1; - if (io->iop_pdatc & fip->fc_mdio) - retval |= 1; - io->iop_pdatc &= ~(fip->fc_mdck); - udelay(0); - } - } - else { - for (i=0; i<16; i++) { - io->iop_pdatc &= ~(fip->fc_mdck); - if (cmd & 0x80000000) - io->iop_pdatc |= fip->fc_mdio; - else - io->iop_pdatc &= ~(fip->fc_mdio); - cmd <<= 1; - io->iop_pdatc |= fip->fc_mdck; - udelay(0); - } - io->iop_pdatc &= ~(fip->fc_mdck); - } - restore_flags(flags); - - /* Some diagrams show two 1 bits for "idle". I don't know if - * this is really necessary or if it was just to indicate nothing - * is going to happen for a while. - * Make the data pin an output, set the data high, and clock it. - */ - save_flags(flags); - cli(); - io->iop_pdatc |= fip->fc_mdio; - io->iop_pdirc |= fip->fc_mdio; - for (i=0; i<3; i++) - io->iop_pdatc ^= fip->fc_mdck; - restore_flags(flags); - - /* We exit with the same conditions as entry. - */ - return(retval); -} Index: arch/ppc/8260_io/uart.c =================================================================== RCS file: arch/ppc/8260_io/uart.c diff -N arch/ppc/8260_io/uart.c --- arch/ppc/8260_io/uart.c 22 Jul 2004 19:49:02 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,2725 +0,0 @@ -/* - * UART driver for MPC8260 CPM SCC or SMC - * Copyright (c) 1999 Dan Malek (dmalek@jlc.net) - * Copyright (c) 2000 MontaVista Software, Inc. (source@mvista.com) - * 2.3.99 updates - * - * I used the 8xx uart.c driver as the framework for this driver. - * The original code was written for the EST8260 board. I tried to make - * it generic, but there may be some assumptions in the structures that - * have to be fixed later. - * - * The 8xx and 8260 are similar, but not identical. Over time we - * could probably merge these two drivers. - * To save porting time, I did not bother to change any object names - * that are not accessed outside of this file. - * It still needs lots of work........When it was easy, I included code - * to support the SCCs. - * Only the SCCs support modem control, so that is not complete either. - * - * This module exports the following rs232 io functions: - * - * int rs_8xx_init(void); - */ - -#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_SERIAL_CONSOLE -#include - -/* this defines the index into rs_table for the port to use -*/ -#ifndef CONFIG_SERIAL_CONSOLE_PORT -#define CONFIG_SERIAL_CONSOLE_PORT 0 -#endif -#endif - -#define TX_WAKEUP ASYNC_SHARE_IRQ - -static char *serial_name = "CPM UART driver"; -static char *serial_version = "0.01"; - -static DECLARE_TASK_QUEUE(tq_serial); - -static struct tty_driver serial_driver, callout_driver; -static int serial_refcount; -static int serial_console_setup(struct console *co, char *options); - -/* - * Serial driver configuration section. Here are the various options: - */ -#define 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 - -#define _INLINE_ inline - -#define DBG_CNT(s) - -/* We overload some of the items in the data structure to meet our - * needs. For example, the port address is the CPM parameter ram - * offset for the SCC or SMC. The maximum number of ports is 4 SCCs and - * 2 SMCs. The "hub6" field is used to indicate the channel number, with - * 0 and 1 indicating the SMCs and 2, 3, 4, and 5 are the SCCs. - * Since these ports are so versatile, I don't yet have a strategy for - * their management. For example, SCC1 is used for Ethernet. Right - * now, just don't put them in the table. Of course, right now I just - * want the SMC to work as a uart :-).. - * The "type" field is currently set to 0, for PORT_UNKNOWN. It is - * not currently used. I should probably use it to indicate the port - * type of CMS or SCC. - * The SMCs do not support any modem control signals. - */ -#define smc_scc_num hub6 - -/* SMC2 is sometimes used for low performance TDM interfaces. Define - * this as 1 if you want SMC2 as a serial port UART managed by this driver. - * Define this as 0 if you wish to use SMC2 for something else. - */ -#define USE_SMC2 1 - -/* Define SCC to ttySx mapping. -*/ -#define SCC_NUM_BASE (USE_SMC2 + 1) /* SCC base tty "number" */ - -/* Define which SCC is the first one to use for a serial port. These - * are 0-based numbers, i.e. this assumes the first SCC (SCC1) is used - * for Ethernet, and the first available SCC for serial UART is SCC2. - * NOTE: IF YOU CHANGE THIS, you have to change the PROFF_xxx and - * interrupt vectors in the table below to match. - */ -#define SCC_IDX_BASE 1 /* table index */ - -static struct serial_state rs_table[] = { - /* UART CLK PORT IRQ FLAGS NUM */ - { 0, 0, PROFF_SMC1, SIU_INT_SMC1, 0, 0 }, /* SMC1 ttyS0 */ -#if USE_SMC2 - { 0, 0, PROFF_SMC2, SIU_INT_SMC2, 0, 1 }, /* SMC2 ttyS1 */ -#endif - { 0, 0, PROFF_SCC2, SIU_INT_SCC2, 0, SCC_NUM_BASE}, /* SCC2 ttyS2 */ - { 0, 0, PROFF_SCC3, SIU_INT_SCC3, 0, SCC_NUM_BASE + 1}, /* SCC3 ttyS3 */ -}; - -#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]; - -/* The number of buffer descriptors and their sizes. -*/ -#define RX_NUM_FIFO 4 -#define RX_BUF_SIZE 32 -#define TX_NUM_FIFO 4 -#define TX_BUF_SIZE 32 - -#ifndef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif - -/* The async_struct in serial.h does not really give us what we - * need, so define our own here. - */ -typedef struct serial_info { - int magic; - int flags; - struct serial_state *state; - struct tty_struct *tty; - int read_status_mask; - int ignore_status_mask; - int timeout; - int line; - 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 blocked_open; /* # of blocked opens */ - long session; /* Session of opening process */ - long pgrp; /* pgrp of opening process */ - struct tq_struct tqueue; - struct tq_struct tqueue_hangup; - wait_queue_head_t open_wait; - wait_queue_head_t close_wait; - - /* CPM Buffer Descriptor pointers. - */ - cbd_t *rx_bd_base; - cbd_t *rx_cur; - cbd_t *tx_bd_base; - cbd_t *tx_cur; -} ser_info_t; - -static void change_speed(ser_info_t *info); -static void rs_8xx_wait_until_sent(struct tty_struct *tty, int timeout); - -static inline int serial_paranoia_check(ser_info_t *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; -} - -/* - * This is used to figure out the divisor speeds and the timeouts, - * indexed by the termio value. The generic CPM functions are responsible - * for setting and assigning baud rate generators for us. - */ -static int baud_table[] = { - 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, - 9600, 19200, 38400, 57600, 115200, 230400, 460800, 0 }; - - -/* - * ------------------------------------------------------------ - * 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_8xx_stop(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - int idx; - unsigned long flags; - volatile scc_t *sccp; - volatile smc_t *smcp; - - 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]; - smcp->smc_smcm &= ~SMCM_TX; - } - else { - sccp = &immr->im_scc[idx - SCC_IDX_BASE]; - sccp->scc_sccm &= ~UART_SCCM_TX; - } - restore_flags(flags); -} - -static void rs_8xx_start(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - int idx; - unsigned long flags; - volatile scc_t *sccp; - volatile smc_t *smcp; - - 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]; - smcp->smc_smcm |= SMCM_TX; - } - else { - sccp = &immr->im_scc[idx - SCC_IDX_BASE]; - sccp->scc_sccm |= UART_SCCM_TX; - } - 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(ser_info_t *info, - int event) -{ - info->event |= 1 << event; - queue_task(&info->tqueue, &tq_serial); - mark_bh(SERIAL_BH); -} - -static _INLINE_ void receive_chars(ser_info_t *info) -{ - struct tty_struct *tty = info->tty; - unsigned char ch, *cp; - /*int ignored = 0;*/ - int i; - ushort status; - struct async_icount *icount; - volatile cbd_t *bdp; - - icount = &info->state->icount; - - /* Just loop through the closed BDs and copy the characters into - * the buffer. - */ - bdp = info->rx_cur; - for (;;) { - if (bdp->cbd_sc & BD_SC_EMPTY) /* If this one is empty */ - break; /* we are all done */ - - /* The read status mask tell us what we should do with - * incoming characters, especially if errors occur. - * One special case is the use of BD_SC_EMPTY. If - * this is not set, we are supposed to be ignoring - * inputs. In this case, just mark the buffer empty and - * continue. - if (!(info->read_status_mask & BD_SC_EMPTY)) { - bdp->cbd_sc |= BD_SC_EMPTY; - bdp->cbd_sc &= - ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV); - - if (bdp->cbd_sc & BD_SC_WRAP) - bdp = info->rx_bd_base; - else - bdp++; - continue; - } - */ - - /* Get the number of characters and the buffer pointer. - */ - i = bdp->cbd_datlen; - cp = (unsigned char *)__va(bdp->cbd_bufaddr); - status = bdp->cbd_sc; - - /* Check to see if there is room in the tty buffer for - * the characters in our BD buffer. If not, we exit - * now, leaving the BD with the characters. We'll pick - * them up again on the next receive interrupt (which could - * be a timeout). - */ - if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) - break; - - while (i-- > 0) { - ch = *cp++; - *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 & (BD_SC_BR | BD_SC_FR | - BD_SC_PR | BD_SC_OV)) { - /* - * For statistics only - */ - if (status & BD_SC_BR) - icount->brk++; - else if (status & BD_SC_PR) - icount->parity++; - else if (status & BD_SC_FR) - icount->frame++; - if (status & BD_SC_OV) - 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; - continue; - } - */ - status &= info->read_status_mask; - - if (status & (BD_SC_BR)) { -#ifdef SERIAL_DEBUG_INTR - printk("handling break...."); -#endif - *tty->flip.flag_buf_ptr = TTY_BREAK; - if (info->flags & ASYNC_SAK) - do_SAK(tty); - } else if (status & BD_SC_PR) - *tty->flip.flag_buf_ptr = TTY_PARITY; - else if (status & BD_SC_FR) - *tty->flip.flag_buf_ptr = TTY_FRAME; - if (status & BD_SC_OV) { - /* - * 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; - } - } - } - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - break; - - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - tty->flip.count++; - } - - /* This BD is ready to be used again. Clear status. - * Get next BD. - */ - bdp->cbd_sc |= BD_SC_EMPTY; - bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV); - - if (bdp->cbd_sc & BD_SC_WRAP) - bdp = info->rx_bd_base; - else - bdp++; - } - - info->rx_cur = (cbd_t *)bdp; - - queue_task(&tty->flip.tqueue, &tq_timer); -} - -static _INLINE_ void transmit_chars(ser_info_t *info) -{ - - if (info->flags & TX_WAKEUP) { - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); - } - -#ifdef SERIAL_DEBUG_INTR - printk("THRE..."); -#endif -} - -#ifdef notdef - /* I need to do this for the SCCs, so it is left as a reminder. - */ -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("scheduling hangup..."); -#endif - MOD_INC_USE_COUNT; - if (schedule_task(&info->tqueue_hangup) == 0) - MOD_DEC_USE_COUNT; - } - } - 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); - } - } - } -} -#endif - -/* - * This is the serial driver's interrupt routine for a single port - */ -static void rs_8xx_interrupt(int irq, void * dev_id, struct pt_regs * regs) -{ - u_char events; - int idx; - 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) { - smcp = &immr->im_smc[idx]; - events = smcp->smc_smce; - if (events & SMCM_RX) - receive_chars(info); - if (events & SMCM_TX) - transmit_chars(info); - smcp->smc_smce = events; - } - else { - sccp = &immr->im_scc[idx - SCC_IDX_BASE]; - events = sccp->scc_scce; - if (events & SCCM_RX) - receive_chars(info); - if (events & SCCM_TX) - transmit_chars(info); - sccp->scc_scce = events; - } - -#ifdef SERIAL_DEBUG_INTR - printk("rs_interrupt_single(%d, %x)...", - info->state->smc_scc_num, events); -#endif -#ifdef modem_control - check_modem_status(info); -#endif - 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_) -{ - ser_info_t *info = (ser_info_t *) 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 async_struct *info = (struct async_struct *) private_; - struct tty_struct *tty; - - tty = info->tty; - if (tty) - tty_hangup(tty); - MOD_DEC_USE_COUNT; -} - -/*static void rs_8xx_timer(void) -{ - printk("rs_8xx_timer\n"); -}*/ - - -static int startup(ser_info_t *info) -{ - unsigned long flags; - int retval=0; - int idx; - struct serial_state *state= info->state; - volatile smc_t *smcp; - volatile scc_t *sccp; - volatile smc_uart_t *up; - volatile scc_uart_t *scup; - - - save_flags(flags); cli(); - - if (info->flags & ASYNC_INITIALIZED) { - goto errout; - } - -#ifdef maybe - if (!state->port || !state->type) { - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - goto errout; - } -#endif - -#ifdef SERIAL_DEBUG_OPEN - printk("starting up ttys%d (irq %d)...", info->line, state->irq); -#endif - - -#ifdef modem_control - info->MCR = 0; - 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); - - /* - * 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]; - - /* Enable interrupts and I/O. - */ - smcp->smc_smcm |= (SMCM_RX | SMCM_TX); - smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN); - - /* We can tune the buffer length and idle characters - * to take advantage of the entire incoming buffer size. - * If mrblr is something other than 1, maxidl has to be - * non-zero or we never get an interrupt. The maxidl - * is the number of character times we wait after reception - * of the last character before we decide no more characters - * are coming. - */ - up = (smc_uart_t *)&immr->im_dprambase[state->port]; -#if 0 - up->smc_mrblr = 1; /* receive buffer length */ - up->smc_maxidl = 0; /* wait forever for next char */ -#else - up->smc_mrblr = RX_BUF_SIZE; - up->smc_maxidl = RX_BUF_SIZE; -#endif - up->smc_brkcr = 1; /* number of break chars */ - } - else { - sccp = &immr->im_scc[idx - SCC_IDX_BASE]; - scup = (scc_uart_t *)&immr->im_dprambase[state->port]; -#if 0 - scup->scc_genscc.scc_mrblr = 1; /* receive buffer length */ - scup->scc_maxidl = 0; /* wait forever for next char */ -#else - scup->scc_genscc.scc_mrblr = RX_BUF_SIZE; - scup->scc_maxidl = RX_BUF_SIZE; -#endif - - sccp->scc_sccm |= (UART_SCCM_TX | UART_SCCM_RX); - sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); - } - - 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(ser_info_t * info) -{ - unsigned long flags; - struct serial_state *state; - int idx; - volatile smc_t *smcp; - volatile scc_t *sccp; - - 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 */ - - if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { - smcp = &immr->im_smc[idx]; - - /* Disable interrupts and I/O. - */ - smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); -#ifdef CONFIG_SERIAL_CONSOLE - /* We can't disable the transmitter if this is the - * system console. - */ - if (idx != CONFIG_SERIAL_CONSOLE_PORT) -#endif - smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - } - else { - sccp = &immr->im_scc[idx - SCC_IDX_BASE]; - 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); - - info->flags &= ~ASYNC_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(ser_info_t *info) -{ - int baud_rate; - unsigned cflag, cval, scval, prev_mode; - int i, bits, sbits, idx; - unsigned long flags; - volatile smc_t *smcp; - volatile scc_t *sccp; - - if (!info->tty || !info->tty->termios) - return; - cflag = info->tty->termios->c_cflag; - - /* Character length programmed into the mode register is the - * sum of: 1 start bit, number of data bits, 0 or 1 parity bit, - * 1 or 2 stop bits, minus 1. - * The value 'bits' counts this for us. - */ - cval = 0; - scval = 0; - - /* byte size and parity */ - switch (cflag & CSIZE) { - case CS5: bits = 5; break; - case CS6: bits = 6; break; - case CS7: bits = 7; break; - case CS8: bits = 8; break; - /* Never happens, but GCC is too dumb to figure it out */ - default: bits = 8; break; - } - sbits = bits - 5; - - if (cflag & CSTOPB) { - cval |= SMCMR_SL; /* Two stops */ - scval |= SCU_PMSR_SL; - bits++; - } - if (cflag & PARENB) { - cval |= SMCMR_PEN; - scval |= SCU_PMSR_PEN; - bits++; - } - if (!(cflag & PARODD)) { - cval |= SMCMR_PM_EVEN; - scval |= (SCU_PMSR_REVP | SCU_PMSR_TEVP); - } - - /* Determine divisor based on baud rate */ - i = cflag & CBAUD; - if (i >= (sizeof(baud_table)/sizeof(int))) - baud_rate = 9600; - else - baud_rate = baud_table[i]; - - info->timeout = (TX_BUF_SIZE*HZ*bits); - info->timeout += HZ/50; /* Add .02 seconds of slop */ - -#ifdef modem_control - /* 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); -#endif - - /* - * Set up parity check flag - */ -#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) - - info->read_status_mask = (BD_SC_EMPTY | BD_SC_OV); - if (I_INPCK(info->tty)) - 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 - */ - info->ignore_status_mask = 0; - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= BD_SC_PR | BD_SC_FR; - if (I_IGNBRK(info->tty)) { - info->ignore_status_mask |= BD_SC_BR; - /* - * If we're ignore parity and break indicators, ignore - * overruns too. (For real raw support). - */ - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= BD_SC_OV; - } - /* - * !!! ignore all characters if CREAD is not set - */ - if ((cflag & CREAD) == 0) - info->read_status_mask &= ~BD_SC_EMPTY; - save_flags(flags); cli(); - - /* Start bit has not been added (so don't, because we would just - * subtract it later), and we need to add one for the number of - * stops bits (there is always at least one). - */ - bits++; - if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { - smcp = &immr->im_smc[idx]; - - /* Set the mode register. We want to keep a copy of the - * 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)); - } - else { - sccp = &immr->im_scc[idx - SCC_IDX_BASE]; - sccp->scc_pmsr = (sbits << 12) | scval; - } - - m8260_cpm_setbrg(info->state->smc_scc_num, baud_rate); - - restore_flags(flags); -} - -static void rs_8xx_put_char(struct tty_struct *tty, unsigned char ch) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - volatile cbd_t *bdp; - - if (serial_paranoia_check(info, tty->device, "rs_put_char")) - return; - - if (!tty) - return; - - bdp = info->tx_cur; - while (bdp->cbd_sc & BD_SC_READY); - - *((char *)__va(bdp->cbd_bufaddr)) = ch; - bdp->cbd_datlen = 1; - bdp->cbd_sc |= BD_SC_READY; - - /* Get next BD. - */ - if (bdp->cbd_sc & BD_SC_WRAP) - bdp = info->tx_bd_base; - else - bdp++; - - info->tx_cur = (cbd_t *)bdp; - -} - -static int rs_8xx_write(struct tty_struct * tty, int from_user, - const unsigned char *buf, int count) -{ - int c, ret = 0; - ser_info_t *info = (ser_info_t *)tty->driver_data; - volatile cbd_t *bdp; - - if (serial_paranoia_check(info, tty->device, "rs_write")) - return 0; - - if (!tty) - return 0; - - bdp = info->tx_cur; - - while (1) { - c = MIN(count, TX_BUF_SIZE); - - if (c <= 0) - break; - - if (bdp->cbd_sc & BD_SC_READY) { - info->flags |= TX_WAKEUP; - break; - } - - if (from_user) { - if (copy_from_user(__va(bdp->cbd_bufaddr), buf, c)) { - if (!ret) - ret = -EFAULT; - break; - } - } else { - memcpy(__va(bdp->cbd_bufaddr), buf, c); - } - - bdp->cbd_datlen = c; - bdp->cbd_sc |= BD_SC_READY; - - buf += c; - count -= c; - ret += c; - - /* Get next BD. - */ - if (bdp->cbd_sc & BD_SC_WRAP) - bdp = info->tx_bd_base; - else - bdp++; - info->tx_cur = (cbd_t *)bdp; - } - return ret; -} - -static int rs_8xx_write_room(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - int ret; - - if (serial_paranoia_check(info, tty->device, "rs_write_room")) - return 0; - - if ((info->tx_cur->cbd_sc & BD_SC_READY) == 0) { - info->flags &= ~TX_WAKEUP; - ret = TX_BUF_SIZE; - } - else { - info->flags |= TX_WAKEUP; - ret = 0; - } - return ret; -} - -/* I could track this with transmit counters....maybe later. -*/ -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; -} - -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; - - /* There is nothing to "flush", whatever we gave the CPM - * is on its way out. - */ - wake_up_interruptible(&tty->write_wait); - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); - info->flags &= ~TX_WAKEUP; -} - -/* - * This function is used to send a high-priority XON/XOFF character to - * the device - */ -static void rs_8xx_send_xchar(struct tty_struct *tty, char ch) -{ - volatile cbd_t *bdp; - - ser_info_t *info = (ser_info_t *)tty->driver_data; - - if (serial_paranoia_check(info, tty->device, "rs_send_char")) - return; - - bdp = info->tx_cur; - while (bdp->cbd_sc & BD_SC_READY); - - *((char *)__va(bdp->cbd_bufaddr)) = ch; - bdp->cbd_datlen = 1; - bdp->cbd_sc |= BD_SC_READY; - - /* Get next BD. - */ - if (bdp->cbd_sc & BD_SC_WRAP) - bdp = info->tx_bd_base; - else - bdp++; - - info->tx_cur = (cbd_t *)bdp; -} - -/* - * ------------------------------------------------------------ - * rs_throttle() - * - * This routine is called by the upper-layer tty layer to signal that - * incoming characters should be throttled. - * ------------------------------------------------------------ - */ -static void rs_8xx_throttle(struct tty_struct * tty) -{ - 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)); - -#ifdef modem_control - if (tty->termios->c_cflag & CRTSCTS) - info->MCR &= ~UART_MCR_RTS; - - cli(); - serial_out(info, UART_MCR, info->MCR); - sti(); -#endif -} - -static void rs_8xx_unthrottle(struct tty_struct * tty) -{ - 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; - else - rs_8xx_send_xchar(tty, START_CHAR(tty)); - } -#ifdef modem_control - if (tty->termios->c_cflag & CRTSCTS) - info->MCR |= UART_MCR_RTS; - cli(); - serial_out(info, UART_MCR, info->MCR); - sti(); -#endif -} - -/* - * ------------------------------------------------------------ - * rs_ioctl() and friends - * ------------------------------------------------------------ - */ - -#ifdef maybe -/* - * 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; - - cli(); - status = serial_in(info, UART_LSR); - sti(); - result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); - return put_user(result,value); -} -#endif - -static int get_modem_info(ser_info_t *info, unsigned int *value) -{ - unsigned int result = 0; -#ifdef modem_control - unsigned char control, status; - - control = info->MCR; - cli(); - status = serial_in(info, UART_MSR); - sti(); - 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); -#endif - return put_user(result,value); -} - -static int set_modem_info(ser_info_t *info, unsigned int cmd, - unsigned int *value) -{ - int error; - unsigned int arg; - - error = get_user(arg, value); - if (error) - return error; -#ifdef modem_control - 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 - 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 - break; - case TIOCMSET: - info->MCR = ((info->MCR & ~(UART_MCR_RTS | -#ifdef TIOCM_OUT1 - UART_MCR_OUT1 | - UART_MCR_OUT2 | -#endif - 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_DTR) ? UART_MCR_DTR : 0)); - break; - default: - return -EINVAL; - } - cli(); - serial_out(info, UART_MCR, info->MCR); - sti(); -#endif - return 0; -} - -/* Sending a break is a two step process on the SMC/SCC. It is accomplished - * by sending a STOP TRANSMIT command followed by a RESTART TRANSMIT - * command. We take advantage of the begin/end functions to make this - * happen. - */ -static void begin_break(ser_info_t *info) -{ - volatile cpm8260_t *cp; - uint page, sblock; - ushort num; - - cp = cpmp; - - if ((num = info->state->smc_scc_num) < SCC_NUM_BASE) { - if (num == 0) { - page = CPM_CR_SMC1_PAGE; - sblock = CPM_CR_SMC1_SBLOCK; - } - else { - page = CPM_CR_SMC2_PAGE; - sblock = CPM_CR_SMC2_SBLOCK; - } - } - else { - num -= SCC_NUM_BASE; - switch (num) { - case 0: - page = CPM_CR_SCC1_PAGE; - sblock = CPM_CR_SCC1_SBLOCK; - break; - case 1: - page = CPM_CR_SCC2_PAGE; - sblock = CPM_CR_SCC2_SBLOCK; - break; - case 2: - page = CPM_CR_SCC3_PAGE; - sblock = CPM_CR_SCC3_SBLOCK; - break; - case 3: - page = CPM_CR_SCC4_PAGE; - sblock = CPM_CR_SCC4_SBLOCK; - break; - default: return; - } - } - cp->cp_cpcr = mk_cr_cmd(page, sblock, 0, CPM_CR_STOP_TX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); -} - -static void end_break(ser_info_t *info) -{ - volatile cpm8260_t *cp; - uint page, sblock; - ushort num; - - cp = cpmp; - - if ((num = info->state->smc_scc_num) < SCC_NUM_BASE) { - if (num == 0) { - page = CPM_CR_SMC1_PAGE; - sblock = CPM_CR_SMC1_SBLOCK; - } - else { - page = CPM_CR_SMC2_PAGE; - sblock = CPM_CR_SMC2_SBLOCK; - } - } - else { - num -= SCC_NUM_BASE; - switch (num) { - case 0: - page = CPM_CR_SCC1_PAGE; - sblock = CPM_CR_SCC1_SBLOCK; - break; - case 1: - page = CPM_CR_SCC2_PAGE; - sblock = CPM_CR_SCC2_SBLOCK; - break; - case 2: - page = CPM_CR_SCC3_PAGE; - sblock = CPM_CR_SCC3_SBLOCK; - break; - case 3: - page = CPM_CR_SCC4_PAGE; - sblock = CPM_CR_SCC4_SBLOCK; - break; - default: return; - } - } - cp->cp_cpcr = mk_cr_cmd(page, sblock, 0, CPM_CR_RESTART_TX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); -} - -/* - * This routine sends a break character out the serial port. - */ -static void send_break(ser_info_t *info, int duration) -{ - current->state = TASK_INTERRUPTIBLE; -#ifdef SERIAL_DEBUG_SEND_BREAK - printk("rs_send_break(%d) jiff=%lu...", duration, jiffies); -#endif - begin_break(info); - schedule_timeout(duration); - end_break(info); -#ifdef SERIAL_DEBUG_SEND_BREAK - printk("done jiffies=%lu\n", jiffies); -#endif -} - - -static int rs_8xx_ioctl(struct tty_struct *tty, struct file * file, - unsigned int cmd, unsigned long arg) -{ - int error; - ser_info_t *info = (ser_info_t *)tty->driver_data; - int retval; - struct async_icount cnow; /* kernel counter temps */ - struct serial_icounter_struct *p_cuser; /* user space */ - - if (serial_paranoia_check(info, tty->device, "rs_ioctl")) - return -ENODEV; - - if ((cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { - 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 (signal_pending(current)) - return -EINTR; - if (!arg) { - send_break(info, HZ/4); /* 1/4 second */ - if (signal_pending(current)) - return -EINTR; - } - return 0; - case TCSBRKP: /* support for POSIX tcsendbreak() */ - retval = tty_check_change(tty); - if (retval) - return retval; - tty_wait_until_sent(tty, 0); - if (signal_pending(current)) - return -EINTR; - send_break(info, arg ? arg*(HZ/10) : HZ/4); - if (signal_pending(current)) - return -EINTR; - return 0; - case TIOCSBRK: - retval = tty_check_change(tty); - if (retval) - return retval; - tty_wait_until_sent(tty, 0); - begin_break(info); - return 0; - case TIOCCBRK: - retval = tty_check_change(tty); - if (retval) - return retval; - end_break(info); - return 0; - case TIOCGSOFTCAR: - return put_user(C_CLOCAL(tty) ? 1 : 0, (int *) arg); - case TIOCSSOFTCAR: - error = get_user(arg, (unsigned int *) arg); - if (error) - return error; - 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); -#ifdef maybe - case TIOCSERGETLSR: /* Get line status register */ - return get_lsr_info(info, (unsigned int *) arg); -#endif - /* - * 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: -#ifdef modem_control - cli(); - /* note the counters on entry */ - cprev = info->state->icount; - sti(); - while (1) { - interruptible_sleep_on(&info->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - cli(); - cnow = info->state->icount; /* atomic copy */ - sti(); - 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 */ -#else - 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 - * RI where only 0->1 is counted. - */ - case TIOCGICOUNT: - cli(); - cnow = info->state->icount; - sti(); - 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; - return 0; - - default: - return -ENOIOCTLCMD; - } - return 0; -} - -/* FIX UP modem control here someday...... -*/ -static void rs_8xx_set_termios(struct tty_struct *tty, struct termios *old_termios) -{ - 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(old_termios->c_iflag))) - return; - - change_speed(info); - -#ifdef modem_control - /* Handle transition to B0 status */ - if ((old_termios->c_cflag & CBAUD) && - !(tty->termios->c_cflag & CBAUD)) { - info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); - cli(); - 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)) { - info->MCR |= UART_MCR_DTR; - if (!tty->hw_stopped || - !(tty->termios->c_cflag & CRTSCTS)) { - info->MCR |= UART_MCR_RTS; - } - cli(); - serial_out(info, UART_MCR, info->MCR); - sti(); - } - - /* Handle turning off CRTSCTS */ - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - rs_8xx_start(tty); - } -#endif - -#if 0 - /* - * No need to wake up processes in open wait, since they - * sample the CLOCAL flag once, and don't recheck it. - * XXX It's not clear whether the current behavior is correct - * or not. Hence, this may change..... - */ - if (!(old_termios->c_cflag & CLOCAL) && - (tty->termios->c_cflag & CLOCAL)) - wake_up_interruptible(&info->open_wait); -#endif -} - -/* - * ------------------------------------------------------------ - * 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_8xx_close(struct tty_struct *tty, struct file * filp) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - struct serial_state *state; - unsigned long flags; - int idx; - volatile smc_t *smcp; - volatile scc_t *sccp; - - 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; - /* - * 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->read_status_mask &= ~BD_SC_EMPTY; - if (info->flags & ASYNC_INITIALIZED) { - if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { - smcp = &immr->im_smc[idx]; - smcp->smc_smcm &= ~SMCM_RX; - smcp->smc_smcmr &= ~SMCMR_REN; - } - else { - sccp = &immr->im_scc[idx - SCC_IDX_BASE]; - sccp->scc_sccm &= ~UART_SCCM_RX; - sccp->scc_gsmrl &= ~SCC_GSMRL_ENR; - } - /* - * Before we drop DTR, make sure the UART transmitter - * has completely drained; this is especially - * important if there is a transmit FIFO! - */ - rs_8xx_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_8xx_wait_until_sent(struct tty_struct *tty, int timeout) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - unsigned long orig_jiffies, char_time; - /*int lsr;*/ - volatile cbd_t *bdp; - - if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent")) - return; - -#ifdef maybe - if (info->state->type == PORT_UNKNOWN) - return; -#endif - - 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 = 1; - if (timeout) - char_time = MIN(char_time, 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 - - /* We go through the loop at least once because we can't tell - * exactly when the last character exits the shifter. There can - * be at least two characters waiting to be sent after the buffers - * are empty. - */ - do { -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("lsr = %d (jiff=%lu)...", lsr, jiffies); -#endif - current->state = TASK_INTERRUPTIBLE; -/* current->counter = 0; make us low-priority */ - schedule_timeout(char_time); - if (signal_pending(current)) - break; - if (timeout && time_after(jiffies, orig_jiffies + timeout)) - break; - bdp = info->tx_cur; - } while (bdp->cbd_sc & BD_SC_READY); - 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_8xx_hangup(struct tty_struct *tty) -{ - 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; - 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, - ser_info_t *info) -{ -#ifdef DO_THIS_LATER - DECLARE_WAITQUEUE(wait, current); -#endif - struct serial_state *state = info->state; - 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 (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); -#ifdef SERIAL_DO_RESTART - if (info->flags & ASYNC_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 & 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 this is an SMC port, we don't have modem control to wait - * for, so just get out here. - */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR)) || - (info->state->smc_scc_num < SCC_NUM_BASE)) { - 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; -#ifdef DO_THIS_LATER - 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 - cli(); - if (!tty_hung_up_p(filp)) - state->count--; - sti(); - info->blocked_open++; - while (1) { - 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)); - sti(); - 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(); - } - current->state = TASK_RUNNING; - remove_wait_queue(&info->open_wait, &wait); - if (!tty_hung_up_p(filp)) - 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 -#endif /* DO_THIS_LATER */ - if (retval) - return retval; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; -} - -static int get_async_struct(int line, ser_info_t **ret_info) -{ - struct serial_state *sstate; - - sstate = rs_table + line; - if (sstate->info) { - sstate->count++; - *ret_info = (ser_info_t *)sstate->info; - return 0; - } - else { - return -ENOMEM; - } -} - -/* - * 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_8xx_open(struct tty_struct *tty, struct file * filp) -{ - ser_info_t *info; - int retval, line; - - line = MINOR(tty->device) - tty->driver.minor_start; - if ((line < 0) || (line >= NR_PORTS)) - return -ENODEV; - retval = get_async_struct(line, &info); - if (retval) - return retval; - 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->state->count); -#endif - tty->driver_data = info; - info->tty = tty; - - /* - * Start up serial port - */ - retval = startup(info); - if (retval) - return retval; - - MOD_INC_USE_COUNT; - 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->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); - } - - 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 int inline line_info(char *buf, struct serial_state *state) -{ -#ifdef notdef - struct async_struct *info = state->info, scr_info; - char stat_buf[30], control, status; -#endif - int ret; - - ret = sprintf(buf, "%d: uart:%s port:%X irq:%d", - state->line, - (state->smc_scc_num < SCC_NUM_BASE) ? "SMC" : "SCC", - state->port, state->irq); - - if (!state->port || (state->type == PORT_UNKNOWN)) { - ret += sprintf(buf+ret, "\n"); - return ret; - } - -#ifdef notdef - /* - * 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; - } - cli(); - 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) - 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); -#endif - return ret; -} - -int rs_8xx_read_proc(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - int i, len = 0; - off_t begin = 0; - - len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version); - for (i = 0; i < NR_PORTS && len < 4000; i++) { - len += line_info(page + len, &rs_table[i]); - 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); -} - -/* - * --------------------------------------------------------------------- - * 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\n", serial_name, serial_version); -} - - -/* - * The serial console driver used during boot. Note that these names - * clash with those found in "serial.c", so we currently can't support - * the 16xxx uarts and these at the same time. I will fix this to become - * an indirect function call from tty_io.c (or something). - */ - -#ifdef CONFIG_SERIAL_CONSOLE - -/* - * 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 *c, const char *s, - unsigned count) -{ - struct serial_state *ser; - ser_info_t *info; - unsigned i; - volatile cbd_t *bdp, *bdbase; - volatile smc_uart_t *up; - volatile u_char *cp; - - ser = rs_table + c->index; - - /* If the port has been initialized for general use, we have - * to use the buffer descriptors allocated there. Otherwise, - * we simply use the single buffer allocated. - */ - if ((info = (ser_info_t *)ser->info) != NULL) { - bdp = info->tx_cur; - bdbase = info->tx_bd_base; - } - else { - /* Pointer to UART in parameter ram. - */ - up = (smc_uart_t *)&immr->im_dprambase[ser->port]; - - /* Get the address of the host memory buffer. - */ - bdp = bdbase = (cbd_t *)&immr->im_dprambase[up->smc_tbase]; - } - - /* - * We need to gracefully shut down the transmitter, disable - * interrupts, then send our bytes out. - */ - - /* - * Now, do each character. This is not as bad as it looks - * since this is a holding FIFO and not a transmitting FIFO. - * We could add the complexity of filling the entire transmit - * buffer, but we would just wait longer between accesses...... - */ - for (i = 0; i < count; i++, s++) { - /* Wait for transmitter fifo to empty. - * Ready indicates output is ready, and xmt is doing - * that, not that it is ready for us to send. - */ - while (bdp->cbd_sc & BD_SC_READY); - /* Send the character out. */ - cp = __va(bdp->cbd_bufaddr); - *cp = *s; - - bdp->cbd_datlen = 1; - bdp->cbd_sc |= BD_SC_READY; - - if (bdp->cbd_sc & BD_SC_WRAP) - bdp = bdbase; - else - bdp++; - - /* if a LF, also do CR... */ - if (*s == 10) { - while (bdp->cbd_sc & BD_SC_READY); - cp = __va(bdp->cbd_bufaddr); - *cp = 13; - bdp->cbd_datlen = 1; - bdp->cbd_sc |= BD_SC_READY; - - if (bdp->cbd_sc & BD_SC_WRAP) { - bdp = bdbase; - } - else { - bdp++; - } - } - } - - /* - * Finally, Wait for transmitter & holding register to empty - * and restore the IER - */ - while (bdp->cbd_sc & BD_SC_READY); - - if (info) - info->tx_cur = (cbd_t *)bdp; -} - -static kdev_t serial_console_device(struct console *c) -{ - return MKDEV(TTYAUX_MAJOR, 64 + c->index); -} - - -static struct console sercons = { - name: "ttyS", - write: serial_console_write, - device: serial_console_device, - setup: serial_console_setup, - flags: CON_PRINTBUFFER, - index: CONFIG_SERIAL_CONSOLE_PORT, -}; - -/* - * Register console. - */ -long __init console_8xx_init(long kmem_start, long kmem_end) -{ - register_console(&sercons); - return kmem_start; -} - -#endif - -/* Default console baud rate as determined by the board information - * structure. - */ -static int baud_idx; - -/* - * The serial driver boot-time initialization code! - */ -int __init rs_8xx_init(void) -{ - struct serial_state * state; - ser_info_t *info; - uint mem_addr, dp_addr; - int i, j, idx; - uint page, sblock; - volatile cbd_t *bdp; - volatile cpm8260_t *cp; - volatile smc_t *sp; - volatile smc_uart_t *up; - volatile scc_t *scp; - 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; - serial_driver.driver_name = "serial"; -#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 = 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 = - baud_idx | 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_8xx_open; - serial_driver.close = rs_8xx_close; - serial_driver.write = rs_8xx_write; - serial_driver.put_char = rs_8xx_put_char; - serial_driver.write_room = rs_8xx_write_room; - serial_driver.chars_in_buffer = rs_8xx_chars_in_buffer; - serial_driver.flush_buffer = rs_8xx_flush_buffer; - serial_driver.ioctl = rs_8xx_ioctl; - serial_driver.throttle = rs_8xx_throttle; - serial_driver.unthrottle = rs_8xx_unthrottle; - serial_driver.send_xchar = rs_8xx_send_xchar; - serial_driver.set_termios = rs_8xx_set_termios; - serial_driver.stop = rs_8xx_stop; - serial_driver.start = rs_8xx_start; - 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. - */ - 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; - callout_driver.read_proc = 0; - callout_driver.proc_entry = 0; - - if (tty_register_driver(&serial_driver)) - 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; - - /* This should have been done long ago by the early boot code, - * but do it again to make sure. - */ - *(ushort *)(&immap->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1; - *(ushort *)(&immap->im_dprambase[PROFF_SMC2_BASE]) = PROFF_SMC2; - - /* Geeze, here we go....Picking I/O port bits....Lots of - * choices. If you don't like mine, pick your own. - * Configure SMCs Tx/Rx. SMC1 is only on Port D, SMC2 is - * only on Port A. You either pick 'em, or not. - */ - io->iop_ppard |= 0x00c00000; - io->iop_pdird |= 0x00400000; - io->iop_pdird &= ~0x00800000; - io->iop_psord &= ~0x00c00000; -#if USE_SMC2 - io->iop_ppara |= 0x00c00000; - io->iop_pdira |= 0x00400000; - io->iop_pdira &= ~0x00800000; - io->iop_psora &= ~0x00c00000; -#endif - - /* Configure SCC2 and SCC3. Be careful about the fine print. - * Secondary options are only available when you take away - * the primary option. Unless the pins are used for something - * else, SCC2 and SCC3 are on Port B. - * Port B, 8 - SCC3 TxD - * Port B, 12 - SCC2 TxD - * Port B, 14 - SCC3 RxD - * Port B, 15 - SCC2 RxD - */ - io->iop_pparb |= 0x008b0000; - io->iop_pdirb |= 0x00880000; - io->iop_psorb |= 0x00880000; - io->iop_pdirb &= ~0x00030000; - io->iop_psorb &= ~0x00030000; - - /* Wire BRG1 to SMC1 and BRG2 to SMC2. - */ - immap->im_cpmux.cmx_smr = 0; - - /* Connect SCC2 and SCC3 to NMSI. Connect BRG3 to SCC2 and - * BRG4 to SCC3. - */ - immap->im_cpmux.cmx_scr &= ~0x00ffff00; - immap->im_cpmux.cmx_scr |= 0x00121b00; - - 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; - printk(KERN_INFO "ttyS%02d at 0x%04x is a %s\n", - i, state->port, - (state->smc_scc_num < SCC_NUM_BASE) ? "SMC" : "SCC"); -#ifdef CONFIG_SERIAL_CONSOLE - /* If we just printed the message on the console port, and - * we are about to initialize it for general use, we have - * to wait a couple of character times for the CR/NL to - * make it out of the transmit buffer. - */ - if (i == CONFIG_SERIAL_CONSOLE_PORT) - mdelay(2); -#endif - info = kmalloc(sizeof(ser_info_t), GFP_KERNEL); - if (info) { - /*memset(info, 0, sizeof(ser_info_t));*/ - __clear_user(info,sizeof(ser_info_t)); - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - info->magic = SERIAL_MAGIC; - info->flags = state->flags; - info->tqueue.routine = do_softint; - info->tqueue.data = info; - info->tqueue_hangup.routine = do_serial_hangup; - info->tqueue_hangup.data = info; - info->line = i; - info->state = state; - state->info = (struct async_struct *)info; - - /* We need to allocate a transmit and receive buffer - * descriptors from dual port ram, and a character - * buffer area from host mem. - */ - dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * RX_NUM_FIFO, 8); - - /* Allocate space for FIFOs in the host memory. - */ - mem_addr = m8260_cpm_hostalloc(RX_NUM_FIFO * RX_BUF_SIZE, 1); - - /* Set the physical address of the host memory - * buffers in the buffer descriptors, and the - * virtual address for us to work with. - */ - bdp = (cbd_t *)&immap->im_dprambase[dp_addr]; - info->rx_cur = info->rx_bd_base = (cbd_t *)bdp; - - for (j=0; j<(RX_NUM_FIFO-1); j++) { - bdp->cbd_bufaddr = __pa(mem_addr); - bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT; - mem_addr += RX_BUF_SIZE; - bdp++; - } - bdp->cbd_bufaddr = __pa(mem_addr); - bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT; - - if ((idx = state->smc_scc_num) < SCC_NUM_BASE) { - sp = &immap->im_smc[idx]; - up = (smc_uart_t *)&immap->im_dprambase[state->port]; - up->smc_rbase = dp_addr; - } - else { - scp = &immap->im_scc[idx - SCC_IDX_BASE]; - sup = (scc_uart_t *)&immap->im_dprambase[state->port]; - sup->scc_genscc.scc_rbase = dp_addr; - } - - dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * TX_NUM_FIFO, 8); - - /* Allocate space for FIFOs in the host memory. - */ - mem_addr = m8260_cpm_hostalloc(TX_NUM_FIFO * TX_BUF_SIZE, 1); - - /* Set the physical address of the host memory - * buffers in the buffer descriptors, and the - * virtual address for us to work with. - */ - bdp = (cbd_t *)&immap->im_dprambase[dp_addr]; - info->tx_cur = info->tx_bd_base = (cbd_t *)bdp; - - for (j=0; j<(TX_NUM_FIFO-1); j++) { - bdp->cbd_bufaddr = __pa(mem_addr); - bdp->cbd_sc = BD_SC_INTRPT; - mem_addr += TX_BUF_SIZE; - bdp++; - } - bdp->cbd_bufaddr = __pa(mem_addr); - bdp->cbd_sc = (BD_SC_WRAP | BD_SC_INTRPT); - - if (idx < SCC_NUM_BASE) { - up->smc_tbase = dp_addr; - - /* Set up the uart parameters in the - * parameter ram. - */ - up->smc_rfcr = CPMFCR_GBL | CPMFCR_EB; - up->smc_tfcr = CPMFCR_GBL | CPMFCR_EB; - - /* Set this to 1 for now, so we get single - * character interrupts. Using idle charater - * time requires some additional tuning. - */ - up->smc_mrblr = 1; - up->smc_maxidl = 0; - up->smc_brkcr = 1; - - /* Send the CPM an initialize command. - */ - if (state->smc_scc_num == 0) { - page = CPM_CR_SMC1_PAGE; - sblock = CPM_CR_SMC1_SBLOCK; - } - else { - page = CPM_CR_SMC2_PAGE; - sblock = CPM_CR_SMC2_SBLOCK; - } - - cp->cp_cpcr = mk_cr_cmd(page, sblock, 0, - CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; - - /* Disable all interrupts and clear all pending - * events. - */ - sp->smc_smcm = 0; - sp->smc_smce = 0xff; - } - else { - sup->scc_genscc.scc_tbase = dp_addr; - - /* Set up the uart parameters in the - * parameter ram. - */ - sup->scc_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB; - sup->scc_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB; - - /* Set this to 1 for now, so we get single - * character interrupts. Using idle charater - * time requires some additional tuning. - */ - sup->scc_genscc.scc_mrblr = 1; - sup->scc_maxidl = 0; - sup->scc_brkcr = 1; - sup->scc_parec = 0; - sup->scc_frmec = 0; - sup->scc_nosec = 0; - sup->scc_brkec = 0; - sup->scc_uaddr1 = 0; - sup->scc_uaddr2 = 0; - sup->scc_toseq = 0; - sup->scc_char1 = 0x8000; - sup->scc_char2 = 0x8000; - sup->scc_char3 = 0x8000; - sup->scc_char4 = 0x8000; - sup->scc_char5 = 0x8000; - sup->scc_char6 = 0x8000; - sup->scc_char7 = 0x8000; - sup->scc_char8 = 0x8000; - sup->scc_rccm = 0xc0ff; - - /* Send the CPM an initialize command. - */ - if (state->smc_scc_num == 2) { - page = CPM_CR_SCC2_PAGE; - sblock = CPM_CR_SCC2_SBLOCK; - } - else { - page = CPM_CR_SCC3_PAGE; - sblock = CPM_CR_SCC3_SBLOCK; - } - - cp->cp_cpcr = mk_cr_cmd(page, sblock, 0, - CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - scp->scc_gsmrh = 0; - scp->scc_gsmrl = - (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); - - /* Disable all interrupts and clear all pending - * events. - */ - scp->scc_sccm = 0; - scp->scc_scce = 0xffff; - scp->scc_dsr = 0x7e7e; - scp->scc_pmsr = 0x3000; - } - - /* Install interrupt handler. - */ - request_irq(state->irq, rs_8xx_interrupt, 0, "uart", - info); - - /* Set up the baud rate generator. - */ - m8260_cpm_setbrg(state->smc_scc_num, - baud_table[baud_idx]); - - /* If the port is the console, enable Rx and Tx. - */ -#ifdef CONFIG_SERIAL_CONSOLE - if (i == CONFIG_SERIAL_CONSOLE_PORT) - sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; -#endif - } - } - return 0; -} - -/* This must always be called before the rs_8xx_init() function, otherwise - * it blows away the port control information. -*/ -static int __init serial_console_setup(struct console *co, char *options) -{ - struct serial_state *ser; - uint mem_addr, dp_addr, bidx; - volatile cbd_t *bdp; - volatile cpm8260_t *cp; - volatile immap_t *immap; - volatile smc_t *sp; - volatile smc_uart_t *up; - volatile iop8260_t *io; - bd_t *bd; - - bd = (bd_t *)__res; - - for (bidx = 0; bidx < (sizeof(baud_table) / sizeof(int)); bidx++) - if (bd->bi_baudrate == baud_table[bidx]) - break; - - co->cflag = CREAD|CLOCAL|bidx|CS8; - baud_idx = bidx; - - ser = rs_table + co->index; - - - immap = immr; - cp = &immap->im_cpm; - io = &immap->im_ioport; - - /* This should have been done long ago by the early boot code, - * but do it again to make sure. - */ - *(ushort *)(&immap->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1; - *(ushort *)(&immap->im_dprambase[PROFF_SMC2_BASE]) = PROFF_SMC2; - - /* Right now, assume we are using SMCs. - */ - sp = &immap->im_smc[ser->smc_scc_num]; - - /* When we get here, the CPM has been reset, so we need - * to configure the port. - * We need to allocate a transmit and receive buffer descriptor - * from dual port ram, and a character buffer area from host mem. - */ - up = (smc_uart_t *)&immap->im_dprambase[ser->port]; - - /* Disable transmitter/receiver. - */ - sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - - /* Use Port D for SMC1 instead of other functions. - */ - io->iop_ppard |= 0x00c00000; - io->iop_pdird |= 0x00400000; - io->iop_pdird &= ~0x00800000; - io->iop_psord &= ~0x00c00000; - - /* Allocate space for two buffer descriptors in the DP ram. - */ - dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * 2, 8); - - /* Allocate space for two 2 byte FIFOs in the host memory. - */ - mem_addr = m8260_cpm_hostalloc(4, 1); - - /* Set the physical address of the host memory buffers in - * the buffer descriptors. - */ - bdp = (cbd_t *)&immap->im_dprambase[dp_addr]; - bdp->cbd_bufaddr = __pa(mem_addr); - (bdp+1)->cbd_bufaddr = __pa(mem_addr+2); - - /* For the receive, set empty and wrap. - * For transmit, set wrap. - */ - bdp->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP; - (bdp+1)->cbd_sc = BD_SC_WRAP; - - /* Set up the uart parameters in the parameter ram. - */ - up->smc_rbase = dp_addr; /* Base of receive buffer desc. */ - up->smc_tbase = dp_addr+sizeof(cbd_t); /* Base of xmt buffer desc. */ - up->smc_rfcr = CPMFCR_GBL | CPMFCR_EB; - up->smc_tfcr = CPMFCR_GBL | CPMFCR_EB; - - /* Set this to 1 for now, so we get single character interrupts. - */ - up->smc_mrblr = 1; /* receive buffer length */ - up->smc_maxidl = 0; /* wait forever for next char */ - - /* Send the CPM an initialize command. - */ - cp->cp_cpcr = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0, - CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; - - /* Set up the baud rate generator. - */ - m8260_cpm_setbrg(ser->smc_scc_num, bd->bi_baudrate); - - /* And finally, enable Rx and Tx. - */ - sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; - - return 0; -} Index: arch/ppc/8xx_io/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/8xx_io/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/8xx_io/Config.in 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/8xx_io/Config.in 4 Aug 2004 01:26:06 -0000 1.2 @@ -2,8 +2,14 @@ # MPC8xx Communication options # mainmenu_option next_comment -comment 'MPC8xx CPM Options' +comment 'MPC8xx Options' +comment 'Generic MPC8xx Options' +bool 'Copy-Back Data Cache (else Writethrough)' CONFIG_8xx_COPYBACK +bool 'CPU6 Silicon Errata (860 Pre Rev. C)' CONFIG_8xx_CPU6 +bool 'I2C/SPI Microcode Patch' CONFIG_UCODE_PATCH + +comment 'MPC8xx CPM Options' if [ "$CONFIG_NET_ETHERNET" = "y" ]; then bool 'CPM SCC Ethernet' CONFIG_SCC_ENET if [ "$CONFIG_SCC_ENET" = "y" ]; then @@ -12,25 +18,28 @@ SCC2 CONFIG_SCC2_ENET \ SCC3 CONFIG_SCC3_ENET" SCC1 fi - bool '860T FEC Ethernet' CONFIG_FEC_ENET + bool '8xxT FEC Ethernet' CONFIG_FEC_ENET if [ "$CONFIG_FEC_ENET" = "y" ]; then bool 'Use MDIO for PHY configuration' CONFIG_USE_MDIO fi bool 'Use Big CPM Ethernet Buffers' CONFIG_ENET_BIG_BUFFERS fi -bool 'Use SMC2 for UART' CONFIG_SMC2_UART -if [ "$CONFIG_SMC2_UART" = "y" ]; then +if [ "$CONFIG_SCC3_ENET" != "y" ]; then + bool 'Use SMC1 for UART' CONFIG_8xx_SMC1 +fi +bool 'Use SMC2 for UART' CONFIG_8xx_SMC2 +if [ "$CONFIG_8xx_SMC2" = "y" ]; then bool 'Use Alternate SMC2 I/O (823/850)' CONFIG_ALTSMC2 bool 'Use SMC2 for Console' CONFIG_CONS_SMC2 fi -bool 'Enable SCC2 and SCC3 for UART' CONFIG_USE_SCC_IO - -# This doesn't really belong here, but it is convenient to ask -# 8xx specific questions. - -comment 'Generic MPC8xx Options' -bool 'Copy-Back Data Cache (else Writethrough)' CONFIG_8xx_COPYBACK -bool 'CPU6 Silicon Errata (860 Pre Rev. C)' CONFIG_8xx_CPU6 -bool 'I2C/SPI Microcode Patch' CONFIG_UCODE_PATCH - +if [ "$CONFIG_SCC1_ENET" != "y" ]; then + bool 'Use SCC1 for UART' CONFIG_8xx_SCC1 +fi +if [ "$CONFIG_SCC2_ENET" != "y" ]; then + bool 'Use SCC2 for UART' CONFIG_8xx_SCC2 +fi +if [ "$CONFIG_SCC3_ENET" != "y" ]; then + bool 'Use SCC3 for UART' CONFIG_8xx_SCC3 +fi +bool 'Use SCC4 for UART' CONFIG_8xx_SCC4 endmenu Index: arch/ppc/8xx_io/commproc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/8xx_io/commproc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/8xx_io/commproc.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/8xx_io/commproc.c 4 Aug 2004 01:26:06 -0000 1.2 @@ -54,6 +54,7 @@ static struct cpm_action cpm_vecs[CPMVEC_NR]; static void cpm_interrupt(int irq, void * dev, struct pt_regs * regs); static void cpm_error_interrupt(int irq, void *, struct pt_regs * regs); +static void alloc_host_memory(void); /* Define a table of names to identify CPM interrupt handlers in * /proc/interrupts. @@ -104,7 +105,7 @@ }; void -m8xx_cpm_reset(uint host_page_addr) +m8xx_cpm_reset() { volatile immap_t *imp; volatile cpm8xx_t *commproc; @@ -130,7 +131,7 @@ * this is what we realy want for some applications, but the * manual recommends it. * Bit 25, FAM can also be set to use FEC aggressive mode (860T). - */ + */ imp->im_siu_conf.sc_sdcr = 1; /* Reclaim the DP memory for our use. @@ -138,25 +139,23 @@ dp_alloc_base = CPM_DATAONLY_BASE; dp_alloc_top = dp_alloc_base + CPM_DATAONLY_SIZE; - /* Set the host page for allocation. + /* Tell everyone where the comm processor resides. */ - host_buffer = host_page_addr; /* Host virtual page address */ - host_end = host_page_addr + PAGE_SIZE; + cpmp = (cpm8xx_t *)commproc; +} - /* We need to get this page early, so I have to do it the - * hard way. - */ - if (get_pteptr(&init_mm, host_page_addr, &pte)) { - pte_val(*pte) |= _PAGE_NO_CACHE; - flush_tlb_page(init_mm.mmap, host_buffer); - } - else { - panic("Huh? No CPM host page?"); - } +/* We used to do this earlier, but have to postpone as long as possible + * to ensure the kernel VM is now running. + */ +static void +alloc_host_memory() +{ + uint physaddr; - /* Tell everyone where the comm processor resides. + /* Set the host page for allocation. */ - cpmp = (cpm8xx_t *)commproc; + host_buffer = (uint)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &physaddr); + host_end = host_buffer + PAGE_SIZE; } /* This is called during init_IRQ. We used to do it above, but this @@ -321,6 +320,9 @@ { uint retloc; + if (host_buffer == 0) + alloc_host_memory(); + if ((host_buffer + size) >= host_end) return(0); Index: arch/ppc/8xx_io/enet.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/8xx_io/enet.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/8xx_io/enet.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/8xx_io/enet.c 4 Aug 2004 01:26:06 -0000 1.2 @@ -137,6 +137,11 @@ cbd_t *cur_rx, *cur_tx; /* The next free ring entry */ cbd_t *dirty_tx; /* The ring entries to be free()ed. */ scc_t *sccp; + + /* Virtual addresses for the receive buffers because we can't + * do a __va() on them anymore. + */ + unsigned char *rx_vaddr[RX_RING_SIZE]; struct net_device_stats stats; uint tx_free; spinlock_t lock; @@ -229,7 +234,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 +452,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. @@ -498,7 +503,7 @@ skb->dev = dev; skb_put(skb,pkt_len-4); /* Make room */ eth_copy_and_sum(skb, - (unsigned char *)__va(bdp->cbd_bufaddr), + cep->rx_vaddr[bdp - cep->rx_bd_base], pkt_len-4, 0); skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); @@ -567,7 +572,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 +599,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)) @@ -632,10 +637,9 @@ { struct net_device *dev; struct scc_enet_private *cep; - int i, j; - unsigned char *eap; - unsigned long mem_addr; - pte_t *pte; + int i, j, k; + unsigned char *eap, *ba; + dma_addr_t mem_addr; bd_t *bd; volatile cbd_t *bdp; volatile cpm8xx_t *cp; @@ -826,24 +830,21 @@ bdp->cbd_sc |= BD_SC_WRAP; bdp = cep->rx_bd_base; + k = 0; for (i=0; icbd_sc = BD_ENET_RX_EMPTY | BD_ENET_RX_INTR; - bdp->cbd_bufaddr = __pa(mem_addr); + bdp->cbd_bufaddr = mem_addr; + cep->rx_vaddr[k++] = ba; mem_addr += CPM_ENET_RX_FRSIZE; + ba += CPM_ENET_RX_FRSIZE; bdp++; } } Index: arch/ppc/8xx_io/fec.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/8xx_io/fec.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/8xx_io/fec.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/8xx_io/fec.c 4 Aug 2004 01:26:06 -0000 1.2 @@ -161,9 +161,14 @@ cbd_t *tx_bd_base; cbd_t *cur_rx, *cur_tx; /* The next free ring entry */ cbd_t *dirty_tx; /* The ring entries to be free()ed. */ - scc_t *sccp; + + /* Virtual addresses for the receive buffers because we can't + * do a __va() on them anymore. + */ + unsigned char *rx_vaddr[RX_RING_SIZE]; + struct net_device_stats stats; - uint tx_full; + uint tx_free; spinlock_t lock; #ifdef CONFIG_USE_MDIO @@ -229,6 +234,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 +301,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 +358,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 +380,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 +408,7 @@ } } #endif - if (!fep->tx_full) + if (fep->tx_free) netif_wake_queue(dev); } @@ -469,7 +468,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 +518,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); } @@ -594,7 +592,7 @@ fep->stats.rx_packets++; pkt_len = bdp->cbd_datlen; fep->stats.rx_bytes += pkt_len; - data = (__u8*)__va(bdp->cbd_bufaddr); + data = fep->rx_vaddr[bdp - fep->rx_bd_base]; /* This does 16 byte alignment, exactly what we need. * The packet length includes FCS, but we don't want to @@ -609,9 +607,7 @@ } else { skb->dev = dev; skb_put(skb,pkt_len-4); /* Make room */ - eth_copy_and_sum(skb, - (unsigned char *)__va(bdp->cbd_bufaddr), - pkt_len-4, 0); + eth_copy_and_sum(skb, data, pkt_len-4, 0); skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); } @@ -668,6 +664,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 +716,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 +728,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 +1022,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 +1087,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 +1159,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 +1394,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 +1438,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 +1508,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 +1556,7 @@ else { switch(cmd) - { + { case SIOCETHTOOL: return netdev_ethtool_ioctl(dev, (void*)rq->ifr_data); break; @@ -1571,7 +1587,7 @@ default: retval = -EOPNOTSUPP; break; - } + } } return retval; } @@ -1652,7 +1668,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. */ @@ -1687,10 +1703,9 @@ { struct net_device *dev; struct fec_enet_private *fep; - int i, j; - unsigned char *eap, *iap; - unsigned long mem_addr; - pte_t *pte; + int i, j, k; + unsigned char *eap, *iap, *ba; + dma_addr_t mem_addr; volatile cbd_t *bdp; cbd_t *cbd_base; volatile immap_t *immap; @@ -1761,14 +1776,7 @@ printk("FEC initialization failed.\n"); return 1; } - mem_addr = __get_free_page(GFP_KERNEL); - cbd_base = (cbd_t *)mem_addr; - - /* Make it uncached. - */ - pte = va_to_pte(mem_addr); - pte_val(*pte) |= _PAGE_NO_CACHE; - flush_tlb_page(init_mm.mmap, mem_addr); + cbd_base = (cbd_t *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr); /* Set receive and transmit descriptor base. */ @@ -1780,24 +1788,21 @@ /* Initialize the receive buffer descriptors. */ bdp = fep->rx_bd_base; + k = 0; for (i=0; icbd_sc = BD_ENET_RX_EMPTY; - bdp->cbd_bufaddr = __pa(mem_addr); + bdp->cbd_bufaddr = mem_addr; + fep->rx_vaddr[k++] = ba; mem_addr += FEC_ENET_RX_FRSIZE; + ba += FEC_ENET_RX_FRSIZE; bdp++; } } @@ -1927,6 +1932,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; @@ -1956,10 +1966,11 @@ /* Set receive and transmit descriptor base. */ - fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base)); - fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base)); + fecp->fec_r_des_start = iopa((uint)(fep->rx_bd_base)); + fecp->fec_x_des_start = iopa((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 +2054,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 +2089,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); } Index: arch/ppc/8xx_io/uart.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/8xx_io/uart.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/8xx_io/uart.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/8xx_io/uart.c 4 Aug 2004 01:26:06 -0000 1.2 @@ -81,7 +81,11 @@ #define TX_WAKEUP ASYNC_SHARE_IRQ static char *serial_name = "CPM UART driver"; -static char *serial_version = "0.03"; +static char *serial_version = "0.04"; + +/* TX buffer length used by my_console_write. + Assume minumun length until it gets set by this driver */ +static int console_tx_buf_len = 1; static DECLARE_TASK_QUEUE(tq_serial); @@ -112,7 +116,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 @@ -126,10 +130,27 @@ * type of SMC or SCC. * The SMCs do not support any modem control signals. */ -#define smc_scc_num hub6 -#define NUM_IS_SCC ((int)0x00010000) -#define PORT_NUM(P) ((P) & 0x0000ffff) -#define PORT_IS_SCC(P) ((P) & NUM_IS_SCC) +#define smc_scc_num hub6 +#define NUM_IS_SCC ((int)0x000100000) +#define NUM_BRG ((int)0x0000FF00) +#define NUM_BRG_SHIFT 8 +#define NUM ((int)0x000000FF) +#define NUM_SHIFT 0 +#define PORT_NUM(P) ((P) & NUM) +#define PORT_NUM_SET(N) (((N)-1) << NUM_SHIFT) +#define PORT_IS_SCC(P) ((P) & NUM_IS_SCC) +#define PORT_BRG(P) (((P) & NUM_BRG) >> NUM_BRG_SHIFT) +#define PORT_BRG_SET(P,B) (P) = (((P) & ~NUM_BRG) | ((B) << NUM_BRG_SHIFT)) + +/* Short names for the ports +*/ +#define QUICC_CPM_SMC1 (PORT_NUM_SET(1)) +#define QUICC_CPM_SMC2 (PORT_NUM_SET(2)) +#define QUICC_CPM_SCC1 (PORT_NUM_SET(1)|NUM_IS_SCC) +#define QUICC_CPM_SCC2 (PORT_NUM_SET(2)|NUM_IS_SCC) +#define QUICC_CPM_SCC3 (PORT_NUM_SET(3)|NUM_IS_SCC) +#define QUICC_CPM_SCC4 (PORT_NUM_SET(4)|NUM_IS_SCC) +#define QUICC_MAX_BRG 3 /* BRG1..BRG4 */ /* The serial port to use for KGDB. */ #ifdef CONFIG_KGDB_TTYS1 @@ -151,22 +172,24 @@ */ static struct serial_state rs_table[] = { /* UART CLK PORT IRQ FLAGS NUM */ -#ifndef CONFIG_SCC3_ENET /* SMC1 not usable with Ethernet on SCC3 */ - { 0, 0, PROFF_SMC1, CPMVEC_SMC1, 0, 0 }, /* SMC1 ttyS0 */ +#ifdef CONFIG_8xx_SMC1 + { 0, 0, PROFF_SMC1, CPMVEC_SMC1, 0, QUICC_CPM_SMC1 }, /* SMC1 ttySx */ +#endif +#ifdef CONFIG_8xx_SMC2 + { 0, 0, PROFF_SMC2, CPMVEC_SMC2, 0, QUICC_CPM_SMC2 }, /* SMC2 ttySx */ +#endif +#ifdef CONFIG_8xx_SCC1 + { 0, 0, PROFF_SCC1, CPMVEC_SCC1, 0, QUICC_CPM_SCC1 }, /* SCC1 ttySx */ +#endif +#ifdef CONFIG_8xx_SCC2 + { 0, 0, PROFF_SCC2, CPMVEC_SCC2, 0, QUICC_CPM_SCC2 }, /* SCC2 ttySx */ +#endif +#ifdef CONFIG_8xx_SCC3 + { 0, 0, PROFF_SCC3, CPMVEC_SCC3, 0, QUICC_CPM_SCC3 }, /* SCC3 ttySx */ +#endif +#ifdef CONFIG_8xx_SCC4 + { 0, 0, PROFF_SCC4, CPMVEC_SCC4, 0, QUICC_CPM_SCC4 }, /* SCC4 ttySx */ #endif -#if !defined(CONFIG_USB_MPC8xx) && !defined(CONFIG_USB_CLIENT_MPC8xx) -# ifdef CONFIG_SMC2_UART - { 0, 0, PROFF_SMC2, CPMVEC_SMC2, 0, 1 }, /* SMC2 ttyS1 */ -# endif -# ifdef CONFIG_USE_SCC_IO - { 0, 0, PROFF_SCC2, CPMVEC_SCC2, 0, (NUM_IS_SCC | 1) }, /* SCC2 ttyS2 */ - { 0, 0, PROFF_SCC3, CPMVEC_SCC3, 0, (NUM_IS_SCC | 2) }, /* SCC3 ttyS3 */ -# endif - #else /* CONFIG_USB_xxx */ -# ifdef CONFIG_USE_SCC_IO - { 0, 0, PROFF_SCC3, CPMVEC_SCC3, 0, (NUM_IS_SCC | 2) }, /* SCC3 ttyS3 */ -# endif -#endif /* CONFIG_USB_xxx */ }; #define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state)) @@ -177,6 +200,7 @@ /* The number of buffer descriptors and their sizes. */ +#define EARLY_BUF_SIZE 4 #define RX_NUM_FIFO 4 #define RX_BUF_SIZE 32 #define TX_NUM_FIFO 4 @@ -218,6 +242,12 @@ cbd_t *rx_cur; cbd_t *tx_bd_base; cbd_t *tx_cur; + + /* Virtual addresses for the FIFOs because we can't __va() a + * physical address anymore. + */ + unsigned char *rx_va_base; + unsigned char *tx_va_base; } ser_info_t; static struct console sercons = { @@ -281,7 +311,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 +335,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 +361,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. @@ -394,13 +424,13 @@ /* Get the number of characters and the buffer pointer. */ i = bdp->cbd_datlen; - cp = (unsigned char *)__va(bdp->cbd_bufaddr); + cp = info->rx_va_base + ((bdp - info->rx_bd_base) * RX_BUF_SIZE); status = bdp->cbd_sc; #ifdef CONFIG_KGDB - if (info->state->smc_scc_num == KGDB_SER_IDX) { - if (*cp == 0x03 || *cp == '$') - breakpoint(); + if (info->state->smc_scc_num == KGDB_SER_IDX && + (*cp == 0x03 || *cp == '$')) { + breakpoint(); return; } #endif @@ -420,7 +450,7 @@ icount->rx++; #ifdef SERIAL_DEBUG_INTR - printk("DR%02x:%02x...", ch, status); + printk("DR%02x:%02x...", ch, status); #endif *tty->flip.flag_buf_ptr = 0; if (status & (BD_SC_BR | BD_SC_FR | @@ -477,7 +507,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 +525,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 +573,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 +591,7 @@ { int status; struct async_icount *icount; - + status = serial_in(info, UART_MSR); if (status & UART_MSR_ANY_DELTA) { @@ -588,7 +618,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 +667,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 +693,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 +732,7 @@ { ser_info_t *info = (ser_info_t *) private_; struct tty_struct *tty; - + tty = info->tty; if (!tty) return; @@ -722,13 +752,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 +807,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 +815,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 +850,7 @@ info->flags |= ASYNC_INITIALIZED; restore_flags(flags); return 0; - + errout: restore_flags(flags); return retval; @@ -847,7 +877,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 +906,7 @@ #endif smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); } - + if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); @@ -977,7 +1007,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 +1017,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 +1040,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 +1053,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; @@ -1033,7 +1063,7 @@ smcp->smc_smcmr = new_mode; } - m8xx_cpm_setbrg((state - rs_table), baud_rate); + m8xx_cpm_setbrg(PORT_BRG(state->smc_scc_num), baud_rate); restore_flags(flags); } @@ -1042,6 +1072,8 @@ { ser_info_t *info = (ser_info_t *)tty->driver_data; volatile cbd_t *bdp; + unsigned char *cp; + unsigned long flags; if (serial_paranoia_check(info, tty->device, "rs_put_char")) return; @@ -1049,21 +1081,22 @@ if (!tty) return; + local_irq_save(flags); bdp = info->tx_cur; - while (bdp->cbd_sc & BD_SC_READY); - - *((char *)__va(bdp->cbd_bufaddr)) = ch; - bdp->cbd_datlen = 1; - bdp->cbd_sc |= BD_SC_READY; - /* Get next BD. */ if (bdp->cbd_sc & BD_SC_WRAP) - bdp = info->tx_bd_base; + info->tx_cur = info->tx_bd_base; else - bdp++; + info->tx_cur = (cbd_t *)bdp + 1; + local_irq_restore(flags); + + while (bdp->cbd_sc & BD_SC_READY); - info->tx_cur = (cbd_t *)bdp; + cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE); + *cp = ch; + bdp->cbd_datlen = 1; + bdp->cbd_sc |= BD_SC_READY; } @@ -1073,9 +1106,11 @@ int c, ret = 0; ser_info_t *info = (ser_info_t *)tty->driver_data; volatile cbd_t *bdp; + unsigned char *cp; + unsigned long flags; #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,46 +1118,53 @@ if (serial_paranoia_check(info, tty->device, "rs_write")) return 0; - if (!tty) + if (!tty) return 0; - bdp = info->tx_cur; - while (1) { c = MIN(count, TX_BUF_SIZE); if (c <= 0) break; + local_irq_save(flags); + bdp = info->tx_cur; if (bdp->cbd_sc & BD_SC_READY) { info->flags |= TX_WAKEUP; + local_irq_restore(flags); break; } + /* Get next BD. + */ + if (bdp->cbd_sc & BD_SC_WRAP) + info->tx_cur = info->tx_bd_base; + else + info->tx_cur = (cbd_t *)bdp + 1; + local_irq_restore(flags); - if (from_user) { - if (copy_from_user(__va(bdp->cbd_bufaddr), buf, c)) { - if (!ret) - ret = -EFAULT; - break; - } - } else { - memcpy(__va(bdp->cbd_bufaddr), buf, c); - } + cp = info->tx_va_base + ((bdp - info->tx_bd_base) * + TX_BUF_SIZE); + if (from_user) + c -= copy_from_user((void *)cp, buf, c); + else + memcpy((void *)cp, buf, c); - bdp->cbd_datlen = c; - bdp->cbd_sc |= BD_SC_READY; + if (c) { + bdp->cbd_datlen = c; + bdp->cbd_sc |= BD_SC_READY; + } else { + /* Need to TX at least 1 char to keep CPM sane */ + bdp->cbd_datlen = 1; + *cp = 0; + bdp->cbd_sc |= BD_SC_READY; + if (!ret) + ret = -EFAULT; + break; + } buf += c; count -= c; ret += c; - - /* Get next BD. - */ - if (bdp->cbd_sc & BD_SC_WRAP) - bdp = info->tx_bd_base; - else - bdp++; - info->tx_cur = (cbd_t *)bdp; } return ret; } @@ -1151,7 +1193,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 +1202,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; @@ -1181,33 +1223,35 @@ static void rs_8xx_send_xchar(struct tty_struct *tty, char ch) { volatile cbd_t *bdp; + unsigned char *cp; + unsigned long flags; ser_info_t *info = (ser_info_t *)tty->driver_data; if (serial_paranoia_check(info, tty->device, "rs_send_char")) return; + local_irq_save(flags); bdp = info->tx_cur; - while (bdp->cbd_sc & BD_SC_READY); - - *((char *)__va(bdp->cbd_bufaddr)) = ch; - bdp->cbd_datlen = 1; - bdp->cbd_sc |= BD_SC_READY; - /* Get next BD. */ if (bdp->cbd_sc & BD_SC_WRAP) - bdp = info->tx_bd_base; + info->tx_cur = info->tx_bd_base; else - bdp++; + info->tx_cur = (cbd_t *)bdp + 1; + local_irq_restore(flags); + while (bdp->cbd_sc & BD_SC_READY); - info->tx_cur = (cbd_t *)bdp; + cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE); + *cp = ch; + bdp->cbd_datlen = 1; + bdp->cbd_sc |= BD_SC_READY; } /* * ------------------------------------------------------------ * rs_throttle() - * + * * This routine is called by the upper-layer tty layer to signal that * incoming characters should be throttled. * ------------------------------------------------------------ @@ -1217,14 +1261,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 +1287,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 +1325,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 +1375,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 +1508,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 +1587,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 +1603,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 +1637,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 +1652,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 +1665,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 +1690,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 +1710,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 +1756,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; @@ -1772,10 +1816,10 @@ static void rs_8xx_wait_until_sent(struct tty_struct *tty, int timeout) { ser_info_t *info = (ser_info_t *)tty->driver_data; - unsigned long orig_jiffies, char_time; + unsigned long orig_jiffies, char_time, tst_res; /*int lsr;*/ volatile cbd_t *bdp; - + if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent")) return; @@ -1789,7 +1833,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. */ @@ -1807,6 +1851,7 @@ * are empty. */ do { + unsigned long flags; #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT printk("lsr = %d (jiff=%lu)...", lsr, jiffies); #endif @@ -1824,12 +1869,15 @@ * is the buffer is available. There are still characters * in the CPM FIFO. */ + local_irq_save(flags); bdp = info->tx_cur; if (bdp == info->tx_bd_base) bdp += (TX_NUM_FIFO-1); else bdp--; - } while (bdp->cbd_sc & BD_SC_READY); + tst_res = !!(bdp->cbd_sc & BD_SC_READY); + local_irq_restore(flags); + } while (tst_res); current->state = TASK_RUNNING; #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); @@ -1843,12 +1891,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 +1957,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 +1980,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 +1996,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 +2015,7 @@ if (info->flags & ASYNC_HUP_NOTIFY) retval = -EAGAIN; else - retval = -ERESTARTSYS; + retval = -ERESTARTSYS; #else retval = -EAGAIN; #endif @@ -2068,7 +2116,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 +2169,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 +2195,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); @@ -2217,6 +2265,11 @@ #ifdef CONFIG_SERIAL_CONSOLE +/* I need this just so I can store the virtual addresses and have + * common functions for the early console printing. + */ +static ser_info_t consinfo; + /* * Print a string to the serial port trying not to disturb any possible * real use of the port... @@ -2226,10 +2279,11 @@ { struct serial_state *ser; ser_info_t *info; - unsigned i; + unsigned i, c, cr_missing, max_tx_size; volatile cbd_t *bdp, *bdbase; volatile smc_uart_t *up; volatile u_char *cp; + unsigned long flags; ser = rs_table + idx; @@ -2238,87 +2292,77 @@ * we simply use the single buffer allocated. */ if ((info = (ser_info_t *)ser->info) != NULL) { - bdp = info->tx_cur; bdbase = info->tx_bd_base; - } - else { - /* Pointer to UART in parameter ram. - */ + } else { + /* Pointer to UART in parameter ram. */ up = (smc_uart_t *)&cpmp->cp_dparam[ser->port]; - /* Get the address of the host memory buffer. - */ - bdp = bdbase = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase]; - } + /* Get the address of the host memory buffer.*/ + info = &consinfo; + info->tx_bd_base = (cbd_t *)bdbase = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase]; + info->tx_cur = (cbd_t *)bdbase; + } + max_tx_size = console_tx_buf_len; + cr_missing = 0; + while (1){ + c = MIN(max_tx_size, count); + if (c <= 0) + break; - /* - * We need to gracefully shut down the transmitter, disable - * interrupts, then send our bytes out. - */ + local_irq_save(flags); + bdp = info->tx_cur; + bdbase = info->tx_bd_base; + if (bdp->cbd_sc & BD_SC_WRAP) + info->tx_cur = (cbd_t *)bdbase; + else + info->tx_cur = (cbd_t *)(bdp+1); + local_irq_restore(flags); - /* - * Now, do each character. This is not as bad as it looks - * since this is a holding FIFO and not a transmitting FIFO. - * We could add the complexity of filling the entire transmit - * buffer, but we would just wait longer between accesses...... - */ - for (i = 0; i < count; i++, s++) { /* Wait for transmitter fifo to empty. * Ready indicates output is ready, and xmt is doing * that, not that it is ready for us to send. */ while (bdp->cbd_sc & BD_SC_READY); - /* Send the character out. + /* Send the characters out. * If the buffer address is in the CPM DPRAM, don't * convert it. */ if ((uint)(bdp->cbd_bufaddr) > (uint)IMAP_ADDR) cp = (u_char *)(bdp->cbd_bufaddr); else - cp = __va(bdp->cbd_bufaddr); - *cp = *s; - - bdp->cbd_datlen = 1; - bdp->cbd_sc |= BD_SC_READY; + cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE); - if (bdp->cbd_sc & BD_SC_WRAP) - bdp = bdbase; - else - bdp++; - - /* if a LF, also do CR... */ - if (*s == 10) { - while (bdp->cbd_sc & BD_SC_READY); - cp = __va(bdp->cbd_bufaddr); - *cp = 13; - bdp->cbd_datlen = 1; - bdp->cbd_sc |= BD_SC_READY; - - if (bdp->cbd_sc & BD_SC_WRAP) { - bdp = bdbase; - } - else { - bdp++; - } + i=1; /* Keeps track of consumed TX buffer space */ + if (cr_missing) { + /* Previus loop didn't have room for the CR, insert it first in this */ + *cp++ = '\r'; + i++; + } + cr_missing = 0; + for (; i <= c; i++) { + if ((*cp++ = *s++) != '\n') + continue; /* Copy bytes until a NewLine is found */ + /* NewLine found, see if there is space in the TX buffer to add a CR */ + if (i < max_tx_size) { + *cp++ = '\r'; /* yes, there is space to add a CR */ + i++; + } else + cr_missing = 1; /* No space in the TX buffer, + rember it so it can be inserted in the next loop */ } - } - - /* - * Finally, Wait for transmitter & holding register to empty - * and restore the IER - */ - while (bdp->cbd_sc & BD_SC_READY); + count -= (c-cr_missing); + bdp->cbd_datlen = i-1; + bdp->cbd_sc |= BD_SC_READY; - if (info) - info->tx_cur = (cbd_t *)bdp; + } + /* while (bdp->cbd_sc & BD_SC_READY); is this really needed? */ } - static void serial_console_write(struct console *c, const char *s, 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 @@ -2358,10 +2402,13 @@ * If the port has been initialized for general use, we must * use information from the port structure. */ - if ((info = (ser_info_t *)ser->info)) + if ((info = (ser_info_t *)ser->info)) { bdp = info->rx_cur; - else + } + else { bdp = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; + info = &consinfo; + } /* * We need to gracefully shut down the receiver, disable @@ -2383,7 +2430,7 @@ if ((uint)(bdp->cbd_bufaddr) > (uint)IMAP_ADDR) cp = (u_char *)(bdp->cbd_bufaddr); else - cp = __va(bdp->cbd_bufaddr); + cp = info->rx_va_base + ((bdp - info->rx_bd_base) * RX_BUF_SIZE); if (obuf) { i = c = bdp->cbd_datlen; @@ -2522,6 +2569,43 @@ /* * The serial driver boot-time initialization code! */ + +int __init rs_8xx_alloc_brg(int port) +{ + static int brg = 0; + volatile cpm8xx_t *cp = cpmp; + int res = brg; + + /* "Wire" the BRG to the specified port + */ + switch (port) { + case QUICC_CPM_SMC1: + cp->cp_simode = (cp->cp_simode & ~(0x07<<12)) | (brg<<12); + break; + case QUICC_CPM_SMC2: + cp->cp_simode = (cp->cp_simode & ~(0x07<<28)) | (brg<<28); + break; + case QUICC_CPM_SCC1: + cp->cp_sicr = (cp->cp_sicr & ~(0xFF<<0)) | (((brg<<3)|(brg<<0))<<0); + break; + case QUICC_CPM_SCC2: + cp->cp_sicr = (cp->cp_sicr & ~(0xFF<<8)) | (((brg<<3)|(brg<<0))<<8); + break; + case QUICC_CPM_SCC3: + cp->cp_sicr = (cp->cp_sicr & ~(0xFF<<16)) | (((brg<<3)|(brg<<0))<<16); + break; + case QUICC_CPM_SCC4: + cp->cp_sicr = (cp->cp_sicr & ~(0xFF<<24)) | (((brg<<3)|(brg<<0))<<24); + break; + } + /* Consume this BRG - Note: the last BRG will be reused if this + */ + /* function is called too many times! + */ + if (brg < QUICC_MAX_BRG) brg++; + return res; +} + int __init rs_8xx_init(void) { struct serial_state * state; @@ -2536,13 +2620,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 +2666,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 +2686,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,14 +2747,17 @@ 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; state->icount.overrun = state->icount.brk = 0; - printk(KERN_INFO "ttyS%02d at 0x%04x is a %s\n", + PORT_BRG_SET(state->smc_scc_num, rs_8xx_alloc_brg(state->smc_scc_num)); + printk(KERN_INFO "ttyS%d at 0x%04x is on %s%d using BRG%d\n", i, (unsigned int)(state->port), - PORT_IS_SCC(state->smc_scc_num) ? "SCC" : "SMC"); + PORT_IS_SCC(state->smc_scc_num) ? "SCC" : "SMC", + PORT_NUM(state->smc_scc_num)+1, + PORT_BRG(state->smc_scc_num)+1); #ifdef CONFIG_SERIAL_CONSOLE /* If we just printed the message on the console port, and * we are about to initialize it for general use, we have @@ -2704,6 +2791,7 @@ /* Allocate space for FIFOs in the host memory. */ mem_addr = m8xx_cpm_hostalloc(RX_NUM_FIFO * RX_BUF_SIZE); + info->rx_va_base = (unsigned char *)mem_addr; /* Set the physical address of the host memory * buffers in the buffer descriptors, and the @@ -2713,12 +2801,12 @@ info->rx_cur = info->rx_bd_base = (cbd_t *)bdp; for (j=0; j<(RX_NUM_FIFO-1); j++) { - bdp->cbd_bufaddr = __pa(mem_addr); + bdp->cbd_bufaddr = iopa(mem_addr); bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT; mem_addr += RX_BUF_SIZE; bdp++; } - bdp->cbd_bufaddr = __pa(mem_addr); + bdp->cbd_bufaddr = iopa(mem_addr); bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT; idx = PORT_NUM(info->state->smc_scc_num); @@ -2738,6 +2826,7 @@ /* Allocate space for FIFOs in the host memory. */ mem_addr = m8xx_cpm_hostalloc(TX_NUM_FIFO * TX_BUF_SIZE); + info->tx_va_base = (unsigned char *)mem_addr; /* Set the physical address of the host memory * buffers in the buffer descriptors, and the @@ -2747,12 +2836,12 @@ info->tx_cur = info->tx_bd_base = (cbd_t *)bdp; for (j=0; j<(TX_NUM_FIFO-1); j++) { - bdp->cbd_bufaddr = __pa(mem_addr); + bdp->cbd_bufaddr = iopa(mem_addr); bdp->cbd_sc = BD_SC_INTRPT; mem_addr += TX_BUF_SIZE; bdp++; } - bdp->cbd_bufaddr = __pa(mem_addr); + bdp->cbd_bufaddr = iopa(mem_addr); bdp->cbd_sc = (BD_SC_WRAP | BD_SC_INTRPT); if (PORT_IS_SCC(info->state->smc_scc_num)) { @@ -2800,7 +2889,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 @@ -2846,12 +2935,14 @@ } #endif /* CONFIG_ALTSMC2 */ +#if 0 /* Connect the baud rate generator to the * SMC based upon index in rs_table. Also * make sure it is connected to NMSI. */ cp->cp_simode &= ~(0xffff << (idx * 16)); cp->cp_simode |= (i << ((idx * 16) + 12)); +#endif up->smc_tbase = dp_addr; @@ -2903,11 +2994,11 @@ /* Set up the baud rate generator. */ - m8xx_cpm_setbrg(i, baud_table[baud_idx]); + m8xx_cpm_setbrg(PORT_BRG(state->smc_scc_num), baud_table[baud_idx]); } } - + console_tx_buf_len = TX_BUF_SIZE; return 0; } @@ -2959,20 +3050,28 @@ * from dual port ram, and a character buffer area from host mem. */ + /* Allocate space for two FIFOs. We can't allocate from host + * memory yet because vm allocator isn't initialized + * during this early console init. + */ + dp_addr = m8xx_cpm_dpalloc(2*EARLY_BUF_SIZE); + mem_addr = (uint)(&cpmp->cp_dpmem[dp_addr]); + /* Allocate space for two buffer descriptors in the DP ram. */ dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * 2); - /* Allocate space for two 2 byte FIFOs in the host memory. - */ - mem_addr = m8xx_cpm_hostalloc(8); - /* Set the physical address of the host memory buffers in * the buffer descriptors. */ bdp = (cbd_t *)&cp->cp_dpmem[dp_addr]; - bdp->cbd_bufaddr = __pa(mem_addr); - (bdp+1)->cbd_bufaddr = __pa(mem_addr+4); + bdp->cbd_bufaddr = iopa(mem_addr); + (bdp+1)->cbd_bufaddr = iopa(mem_addr+4); + + consinfo.rx_va_base = (unsigned char *) mem_addr; + consinfo.rx_bd_base = (cbd_t *) bdp; + consinfo.tx_va_base = (unsigned char *) (mem_addr + EARLY_BUF_SIZE); + consinfo.tx_bd_base = (cbd_t *) (bdp+1); /* For the receive, set empty and wrap. * For transmit, set wrap. @@ -3028,7 +3127,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 @@ -3073,7 +3172,7 @@ /* Set up the baud rate generator. */ m8xx_cpm_setbrg((ser - rs_table), bd->bi_baudrate); - + console_tx_buf_len = EARLY_BUF_SIZE; return 0; } Index: arch/ppc/amiga/config.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/amiga/config.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/amiga/config.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/amiga/config.c 4 Aug 2004 01:26:06 -0000 1.2 @@ -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++) Index: arch/ppc/amiga/ints.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/amiga/ints.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/amiga/ints.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/amiga/ints.c 4 Aug 2004 01:26:06 -0000 1.2 @@ -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) { Index: arch/ppc/boot/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/Makefile 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/Makefile 4 Aug 2004 01:26:07 -0000 1.2 @@ -17,7 +17,7 @@ AFLAGS += -D__BOOTER__ OBJCOPY_ARGS = -O elf32-powerpc -MKIMAGE := ./utils/mkimage.wrapper +MKIMAGE := $(TOPDIR)/scripts/mkuboot.sh lib/zlib.a: lib/zlib.c $(MAKE) -C lib @@ -32,6 +32,8 @@ 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_PRPMC750) := mkbugboot mkprep tools-$(CONFIG_SPRUCE) := mktree # These are dirs we don't want to go into on BOOT_TARGETS. We have them for @@ -41,6 +43,9 @@ # These are the subdirs we want to use BOOTDIRS = $(filter-out $(NONBOOT), $(subdir-y)) +makeof1275: + $(MAKE) -C of1275 + # This will make the tools we need. We do it like this to ensure that we use # HOSTCC. -- Tom maketools: @@ -49,7 +54,7 @@ # The targets all boards support for boot images. BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd -$(BOOT_TARGETS): vmapus lib/zlib.a images/vmlinux.gz maketools +$(BOOT_TARGETS): vmapus lib/zlib.a images/vmlinux.gz makeof1275 maketools ifneq ($(BOOTDIRS),) for d in $(BOOTDIRS); do $(MAKE) -C $$d $@; done endif @@ -60,12 +65,14 @@ gzip $(GZIP_FLAGS) images/vmapus endif -# Make an image for PPCBoot -pImage: images/vmlinux.gz - $(MKIMAGE) -A ppc -O linux -T kernel -C gzip -a 00000000 -e 00000000 \ +# Make an image for PPCBoot / U-Boot. +uImage: $(MKIMAGE) images/vmlinux.gz + $(CONFIG_SHELL) $(MKIMAGE) -A ppc -O linux -T kernel \ + -C gzip -a 00000000 -e 00000000 \ -n 'Linux-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)' \ - -d $< images/vmlinux.PPCBoot - ln -sf vmlinux.PPCBoot images/pImage + -d images/vmlinux.gz images/vmlinux.UBoot + ln -sf vmlinux.UBoot images/uImage + rm -f ./mkuboot # These are subdirs with files not normally rm'ed. -- Tom clean: Index: arch/ppc/boot/chrp/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/chrp/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/chrp/Makefile 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/chrp/Makefile 4 Aug 2004 01:26:07 -0000 1.2 @@ -12,7 +12,7 @@ OBJS = ../common/crt0.o start.o main.o misc.o ../common/string.o image.o \ ../common/ofcommon.o -LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a +LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a ../of1275/of1275.a ADDNOTE = ../utils/addnote PIGGYBACK = ../utils/piggyback @@ -50,13 +50,13 @@ --set-section-flags=.sysmap=contents,alloc,load,readonly,data endif -zImage: $(OBJS) $(LIBS) $(ADDNOTE) +zImage: $(OBJS) $(LIBS) $(ADDNOTE) ../ld.script $(LD) $(LD_ARGS) -o ../images/$@.chrp $(OBJS) $(LIBS) $(OBJCOPY) ../images/$@.chrp ../images/$@.chrp -R .comment -R .ramdisk cp ../images/$@.chrp ../images/$@.chrp-rs6k $(ADDNOTE) ../images/$@.chrp-rs6k -zImage.initrd: $(OBJS) $(LIBS) $(ADDNOTE) ../images/ramdisk.image.gz +zImage.initrd: $(OBJS) $(LIBS) $(ADDNOTE) ../images/ramdisk.image.gz ../ld.script $(OBJCOPY) image.o image.o \ --add-section=.ramdisk=../images/ramdisk.image.gz \ --set-section-flags=.ramdisk=contents,alloc,load,readonly,data Index: arch/ppc/boot/chrp/main.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/chrp/main.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/chrp/main.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/chrp/main.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -7,6 +7,7 @@ * 2 of the License, or (at your option) any later version. */ #include "nonstdio.h" +#include "of1275.h" #include #include @@ -15,15 +16,11 @@ extern char __ramdisk_begin[], __ramdisk_end; extern char _start, _end; -extern int getprop(void *, const char *, void *, int); extern unsigned int heap_max; -extern void claim(unsigned int virt, unsigned int size, unsigned int align); -extern void *finddevice(const char *); extern void flush_cache(void *, unsigned long); extern void gunzip(void *, int, unsigned char *, int *); extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach, unsigned int progend); -extern void pause(void); char *avail_ram; char *begin_avail, *end_avail; @@ -43,6 +40,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 +49,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 +88,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"); Index: arch/ppc/boot/chrp/start.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/chrp/start.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/chrp/start.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/chrp/start.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -7,17 +7,13 @@ * 2 of the License, or (at your option) any later version. */ #include +#include "of1275.h" int (*prom)(void *args); -void *chosen_handle; -void *stdin; -void *stdout; -void *stderr; - -void exit(void); -void *finddevice(const char *name); -int getprop(void *phandle, const char *name, void *buf, int buflen); +phandle stdin; +phandle stdout; +phandle stderr; void printk(char *fmt, ...); @@ -27,163 +23,15 @@ void start(int a1, int a2, void *promptr) { - prom = promptr; - chosen_handle = finddevice("/chosen"); - if (chosen_handle == (void *) -1) + ofinit(promptr); + if (ofstdio(&stdin, &stdout, &stderr)) exit(); - if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) - exit(); - stderr = stdout; - if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) - exit(); - chrpboot(a1, a2, promptr); for (;;) exit(); } int -write(void *handle, void *ptr, int nb) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *ihandle; - void *addr; - int len; - int actual; - } args; - - args.service = "write"; - args.nargs = 3; - args.nret = 1; - args.ihandle = handle; - args.addr = ptr; - args.len = nb; - args.actual = -1; - prom(&args); - return args.actual; -} - -int -read(void *handle, void *ptr, int nb) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *ihandle; - void *addr; - int len; - int actual; - } args; - - args.service = "read"; - args.nargs = 3; - args.nret = 1; - args.ihandle = handle; - args.addr = ptr; - args.len = nb; - args.actual = -1; - (*prom)(&args); - return args.actual; -} - -void -exit(void) -{ - struct prom_args { - char *service; - } args; - - for (;;) { - args.service = "exit"; - (*prom)(&args); - } -} - -void -pause(void) -{ - struct prom_args { - char *service; - } args; - - args.service = "enter"; - (*prom)(&args); -} - -void * -finddevice(const char *name) -{ - struct prom_args { - char *service; - int nargs; - int nret; - const char *devspec; - void *phandle; - } args; - - args.service = "finddevice"; - args.nargs = 1; - args.nret = 1; - args.devspec = name; - args.phandle = (void *) -1; - (*prom)(&args); - return args.phandle; -} - -void * -claim(unsigned int virt, unsigned int size, unsigned int align) -{ - struct prom_args { - char *service; - int nargs; - int nret; - unsigned int virt; - unsigned int size; - unsigned int align; - void *ret; - } args; - - args.service = "claim"; - args.nargs = 3; - args.nret = 1; - args.virt = virt; - args.size = size; - args.align = align; - (*prom)(&args); - return args.ret; -} - -int -getprop(void *phandle, const char *name, void *buf, int buflen) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *phandle; - const char *name; - void *buf; - int buflen; - int size; - } args; - - args.service = "getprop"; - args.nargs = 4; - args.nret = 1; - args.phandle = phandle; - args.name = name; - args.buf = buf; - args.buflen = buflen; - args.size = -1; - (*prom)(&args); - return args.size; -} - -int putc(int c, void *f) { char ch = c; Index: arch/ppc/boot/common/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/common/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/common/Makefile 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/common/Makefile 4 Aug 2004 01:26:07 -0000 1.2 @@ -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 Index: arch/ppc/boot/common/crt0.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/common/crt0.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/common/crt0.S 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/boot/common/crt0.S 4 Aug 2004 01:26:07 -0000 1.2 @@ -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 @@ -70,7 +70,7 @@ ## Set up the stack lis r9,_start@h # r9 = &_start (text section entry) - addi r9,r9,_start@l + ori r9,r9,_start@l subi r1,r9,64 # Start the stack 64 bytes below _start clrrwi r1,r1,4 # Make sure it is aligned on 16 bytes. li r0,0 Index: arch/ppc/boot/common/misc-common.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/common/misc-common.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/common/misc-common.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/common/misc-common.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -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); Index: arch/ppc/boot/common/misc-simple.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/common/misc-simple.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/common/misc-simple.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/common/misc-simple.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -75,16 +75,9 @@ extern void gunzip(void *, int, unsigned char *, int *); extern void serial_fixups(void); -/* Allow decompress_kernel to be hooked into. This is the default. */ -void * __attribute__ ((weak)) -load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, - void *bp) -{ - return decompress_kernel(load_addr, num_words, cksum, bp); -} - struct bi_record * -decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum) +decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, + void *ignored) { #ifdef INTERACTIVE_CONSOLE int timer = 0; @@ -236,7 +229,7 @@ puts("\n"); } } - + rec->tag = BI_FIRST; rec->size = sizeof(struct bi_record); rec = (struct bi_record *)((unsigned long)rec + rec->size); @@ -271,3 +264,11 @@ return (struct bi_record *)rec_loc; } + +/* Allow decompress_kernel to be hooked into. This is the default. */ +void * __attribute__ ((weak)) +load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, + void *bp) +{ + return decompress_kernel(load_addr, num_words, cksum, bp); +} Index: arch/ppc/boot/common/mpc10x_memory.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/common/mpc10x_memory.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/common/mpc10x_memory.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/boot/common/mpc10x_memory.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -1,6 +1,6 @@ /* * arch/ppc/boot/common/mpc10x_common.c - * + * * A routine to find out how much memory the machine has. * * Based on: Index: arch/ppc/boot/common/ns16550.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/common/ns16550.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/common/ns16550.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/boot/common/ns16550.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -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 */ Index: arch/ppc/boot/common/ofcommon.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/common/ofcommon.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/common/ofcommon.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/common/ofcommon.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -8,6 +8,7 @@ */ #include "zlib.h" +#include "of1275.h" #include "nonstdio.h" #include #include @@ -18,8 +19,6 @@ extern int strcmp(const char *s1, const char *s2); extern char *avail_ram, *avail_high; extern char *end_avail; -extern void claim(unsigned int virt, unsigned int size, unsigned int align); -extern void pause(void); unsigned int heap_use, heap_max; Index: arch/ppc/boot/common/relocate.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/common/relocate.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/common/relocate.S 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/boot/common/relocate.S 4 Aug 2004 01:26:07 -0000 1.2 @@ -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 Index: arch/ppc/boot/common/util.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/common/util.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/common/util.S 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/boot/common/util.S 4 Aug 2004 01:26:07 -0000 1.2 @@ -160,9 +160,22 @@ blr +/* udelay (on non-601 processors) needs to know the period of the + * timebase in nanoseconds. This used to be hardcoded to be 60ns + * (period of 66MHz/4). Now a variable is used that is initialized to + * 60 for backward compatibility, but it can be overridden as necessary + * with code something like this: + * extern unsigned long timebase_period_ns; + * timebase_period_ns = 1000000000 / bd->bi_tbfreq; + */ + .data + .globl timebase_period_ns +timebase_period_ns: + .long 60 + + .text /* * Delay for a number of microseconds - * -- Use the BUS timer (assumes 66MHz) */ .globl udelay udelay: @@ -180,8 +193,13 @@ .udelay_not_601: mulli r4,r3,1000 /* nanoseconds */ - addi r4,r4,59 - li r5,60 + /* Change r4 to be the number of ticks using: + * (nanoseconds + (timebase_period_ns - 1 )) / timebase_period_ns + * timebase_period_ns defaults to 60 (16.6MHz) */ + lis r5,timebase_period_ns@ha + lwz r5,timebase_period_ns@l(r5) + add r4,r4,r5 + addi r4,r4,-1 divw r4,r4,r5 /* BUS ticks */ 1: mftbu r5 mftb r6 @@ -199,11 +217,6 @@ blt 2b 3: blr -.globl _put_MSR -_put_MSR: - mtmsr r3 - blr - .section ".relocate_code","xa" /* * Flush and enable instruction cache Index: arch/ppc/boot/images/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/images/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/images/Makefile 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/boot/images/Makefile 4 Aug 2004 01:26:07 -0000 1.2 @@ -9,4 +9,4 @@ gzip -vf9 vmlinux clean: - rm -f sImage vmapus vmlinux* miboot* zImage* zvmlinux* + rm -f sImage vmapus vmlinux* miboot* zImage* zvmlinux* uImage Index: arch/ppc/boot/include/mpc10x.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/include/mpc10x.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/include/mpc10x.h 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/boot/include/mpc10x.h 4 Aug 2004 01:26:07 -0000 1.2 @@ -58,7 +58,7 @@ #define MPC10X_MCTLR_EXT_MEM_START_2 0x8c /* Banks 4-7 */ #define MPC10X_MCTLR_MEM_END_1 0x90 /* Banks 0-3 */ -#define MPC10X_MCTLR_MEM_END_2i 0x94 /* Banks 4-7 */ +#define MPC10X_MCTLR_MEM_END_2 0x94 /* Banks 4-7 */ #define MPC10X_MCTLR_EXT_MEM_END_1 0x98 /* Banks 0-3 */ #define MPC10X_MCTLR_EXT_MEM_END_2 0x9c /* Banks 4-7 */ Index: arch/ppc/boot/include/rs6000.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/include/rs6000.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/include/rs6000.h 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/boot/include/rs6000.h 4 Aug 2004 01:26:07 -0000 1.2 @@ -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 */ Index: arch/ppc/boot/include/zlib.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/include/zlib.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/include/zlib.h 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/boot/include/zlib.h 4 Aug 2004 01:26:07 -0000 1.2 @@ -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. Index: arch/ppc/boot/lib/zlib.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/lib/zlib.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/lib/zlib.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/lib/zlib.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -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 */ Index: arch/ppc/boot/pmac/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/pmac/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/pmac/Makefile 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/pmac/Makefile 4 Aug 2004 01:26:07 -0000 1.2 @@ -14,7 +14,7 @@ COMMONOBJS = start.o misc.o ../common/string.o ../common/ofcommon.o COFFOBJS = ../common/coffcrt0.o $(COMMONOBJS) coffmain.o CHRPOBJS = ../common/crt0.o $(COMMONOBJS) chrpmain.o -LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a +LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a ../of1275/of1275.a MKNOTE := ../utils/mknote SIZE := ../utils/size @@ -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 @@ -86,7 +84,7 @@ rm -f coffboot.initrd ln -sf vmlinux.initrd.coff ../images/zImage.initrd.pmac -vmlinux.elf-pmac: $(CHRPOBJS) $(LIBS) $(MKNOTE) image.o +vmlinux.elf-pmac: $(CHRPOBJS) $(LIBS) $(MKNOTE) image.o ../ld.script $(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) $(LIBS) image.o $(MKNOTE) > note $(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note \ @@ -94,7 +92,7 @@ rm -f note vmlinux.initrd.elf-pmac: $(CHRPOBJS) $(LIBS) $(MKNOTE) image.o \ - ../images/ramdisk.image.gz + ../images/ramdisk.image.gz ../ld.script $(OBJCOPY) image.o image-elf.o \ --add-section=.ramdisk=../images/ramdisk.image.gz \ --set-section-flags=.ramdisk=contents,alloc,load,readonly,data Index: arch/ppc/boot/pmac/chrpmain.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/pmac/chrpmain.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/pmac/chrpmain.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/pmac/chrpmain.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -7,6 +7,7 @@ * 2 of the License, or (at your option) any later version. */ #include "nonstdio.h" +#include "of1275.h" #include #include @@ -15,16 +16,11 @@ extern char __ramdisk_begin[], __ramdisk_end; extern char _start, _end; -extern int getprop(void *, const char *, void *, int); extern unsigned int heap_max; -extern void *claim(unsigned int virt, unsigned int size, unsigned int align); -extern void *finddevice(const char *); extern void flush_cache(void *start, unsigned int len); extern void gunzip(void *, int, unsigned char *, int *); extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach, unsigned int progend); -extern void pause(void); -extern void release(void *ptr, unsigned int len); char *avail_ram; char *begin_avail, *end_avail; @@ -38,13 +34,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 +85,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"); Index: arch/ppc/boot/pmac/coffmain.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/pmac/coffmain.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/pmac/coffmain.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/pmac/coffmain.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -10,6 +10,7 @@ #include #include "nonstdio.h" +#include "of1275.h" #include "zlib.h" /* Passed from the linker */ @@ -17,17 +18,13 @@ extern char __ramdisk_begin[], __ramdisk_end; extern char _start, _end; -extern char *claim(unsigned, unsigned, unsigned); extern char image_data[], initrd_data[]; extern int initrd_len, image_len; -extern int getprop(void *, const char *, void *, int); extern unsigned int heap_max; -extern void *finddevice(const char *); extern void flush_cache(void *start, unsigned int len); extern void gunzip(void *, int, unsigned char *, int *); extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach, unsigned int progend); -extern void pause(void); extern void setup_bats(unsigned long start); char *avail_ram; @@ -44,13 +41,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 +91,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"); Index: arch/ppc/boot/pmac/start.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/pmac/start.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/pmac/start.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/pmac/start.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -7,33 +7,22 @@ * 2 of the License, or (at your option) any later version. */ #include +#include "of1275.h" extern int strlen(const char *s); extern void boot(int a1, int a2, void *prom); -int (*prom)(); +phandle stdin; +phandle stdout; +phandle stderr; -void *chosen_handle; -void *stdin; -void *stdout; -void *stderr; - -void exit(void); -void *finddevice(const char *name); -int getprop(void *phandle, const char *name, void *buf, int buflen); void printk(char *fmt, ...); void start(int a1, int a2, void *promptr) { - prom = (int (*)()) promptr; - chosen_handle = finddevice("/chosen"); - if (chosen_handle == (void *) -1) - exit(); - if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) - exit(); - stderr = stdout; - if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) + ofinit(promptr); + if (ofstdio(&stdin, &stdout, &stderr)) exit(); boot(a1, a2, promptr); @@ -41,30 +30,6 @@ exit(); } -int -write(void *handle, void *ptr, int nb) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *ihandle; - void *addr; - int len; - int actual; - } args; - - args.service = "write"; - args.nargs = 3; - args.nret = 1; - args.ihandle = handle; - args.addr = ptr; - args.len = nb; - args.actual = -1; - (*prom)(&args); - return args.actual; -} - int writestring(void *f, char *ptr, int nb) { int w = 0, i; @@ -85,142 +50,6 @@ } int -read(void *handle, void *ptr, int nb) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *ihandle; - void *addr; - int len; - int actual; - } args; - - args.service = "read"; - args.nargs = 3; - args.nret = 1; - args.ihandle = handle; - args.addr = ptr; - args.len = nb; - args.actual = -1; - (*prom)(&args); - return args.actual; -} - -void -exit(void) -{ - struct prom_args { - char *service; - } args; - - for (;;) { - args.service = "exit"; - (*prom)(&args); - } -} - -void -pause(void) -{ - struct prom_args { - char *service; - } args; - - args.service = "enter"; - (*prom)(&args); -} - -void * -finddevice(const char *name) -{ - struct prom_args { - char *service; - int nargs; - int nret; - const char *devspec; - void *phandle; - } args; - - args.service = "finddevice"; - args.nargs = 1; - args.nret = 1; - args.devspec = name; - args.phandle = (void *) -1; - (*prom)(&args); - return args.phandle; -} - -void * -claim(unsigned int virt, unsigned int size, unsigned int align) -{ - struct prom_args { - char *service; - int nargs; - int nret; - unsigned int virt; - unsigned int size; - unsigned int align; - void *ret; - } args; - - args.service = "claim"; - args.nargs = 3; - args.nret = 1; - args.virt = virt; - args.size = size; - args.align = align; - (*prom)(&args); - return args.ret; -} - -void -release(void *virt, unsigned int size) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *virt; - unsigned int size; - } args; - - args.service = "release"; - args.nargs = 2; - args.nret = 0; - args.virt = virt; - args.size = size; - (*prom)(&args); -} - -int -getprop(void *phandle, const char *name, void *buf, int buflen) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *phandle; - const char *name; - void *buf; - int buflen; - int size; - } args; - - args.service = "getprop"; - args.nargs = 4; - args.nret = 1; - args.phandle = phandle; - args.name = name; - args.buf = buf; - args.buflen = buflen; - args.size = -1; - (*prom)(&args); - return args.size; -} - -int putc(int c, void *f) { char ch = c; Index: arch/ppc/boot/prep/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/prep/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/prep/Makefile 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/prep/Makefile 4 Aug 2004 01:26:07 -0000 1.2 @@ -22,12 +22,12 @@ endif LD_ARGS = -T ../ld.script -Ttext 0x00800000 -Bstatic -obj-y := head.o ../simple/legacy.o misc.o of1275.o \ +obj-y := head.o ../simple/legacy.o misc.o \ ../common/util.o ../common/string.o \ ../common/misc-common.o \ ../common/serial_stub.o OBJCOPY_ARGS = -O elf32-powerpc -LIBS = ../lib/zlib.a +LIBS = ../lib/zlib.a ../of1275/of1275.a obj-$(CONFIG_SERIAL_CONSOLE) += ../common/ns16550.o obj-$(CONFIG_VGA_CONSOLE) += vreset.o kbd.o @@ -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 Index: arch/ppc/boot/prep/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/prep/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/prep/head.S 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/prep/head.S 4 Aug 2004 01:26:07 -0000 1.2 @@ -34,14 +34,29 @@ isync mr r11,r3 /* Save pointer to residual/board data */ - mr r25,r5 /* Save OFW pointer */ - /* Save the original MSR value */ - mfmsr r26 +/* + * Save the OF pointer to r25, but only if the entry point is in a sane + * location; if not we store 0. If there is no entry point, or it is + * invalid, we establish the default MSR value immediately. Otherwise, + * we defer doing that, to allow OF functions to be called, until we + * begin uncompressing the kernel. + */ + lis r3,0x0fff /* r3 = 0x0fffffff */ + ori r3,r3,0xffff - /* Establish default MSR value */ - li r3,MSR_IP|MSR_FP - mtmsr r3 + subc r3,r3,r5 /* r3 = (r5 <= r3) ? ~0 : 0 */ + subfe r3,r3,r3 + nand r3,r3,r3 + + and. r5,r5,r3 /* r5 will be cleared if (r5 > r3) */ + bne+ haveOF + + li r3,MSR_IP|MSR_FP /* Not OF: set MSR immediately */ + mtmsr r3 + isync +haveOF: + mr r25,r5 /* compute the size of the whole image in words. */ lis r4,start@h @@ -110,17 +125,12 @@ li r2,0x000F /* Mask pointer to 16-byte boundary */ andc r1,r1,r2 - /* Store the original MSR into 'orig_MSR' */ - lis r3,orig_MSR@h - ori r3,r3,orig_MSR@l - stw r26,0(r3) - /* Run loader */ mr r3,r8 /* Load point */ mr r4,r7 /* Program length */ mr r5,r6 /* Checksum */ mr r6,r11 /* Residual data */ - mr r7,r25 /* OFW interfaces */ + mr r7,r25 /* Validated OFW interface */ bl decompress_kernel /* Index: arch/ppc/boot/prep/misc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/prep/misc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/prep/misc.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/prep/misc.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -18,6 +18,7 @@ #include #include #include +#include "of1275.h" #include "nonstdio.h" #include "zlib.h" @@ -54,7 +55,6 @@ RESIDUAL hold_resid_buf; RESIDUAL *hold_residual = &hold_resid_buf; unsigned long initrd_size = 0; -unsigned long orig_MSR; char *zimage_start; int zimage_size; @@ -67,14 +67,9 @@ #endif /* CONFIG_VGA_CONSOLE */ extern int CRT_tstc(void); -extern void of_init(void *handler); -extern int of_finddevice(const char *device_specifier, int *phandle); -extern int of_getprop(int phandle, const char *name, void *buf, int buflen, - int *size); extern int vga_init(unsigned char *ISA_mem); extern void gunzip(void *, int, unsigned char *, int *); -extern void _put_MSR(unsigned int val); extern unsigned long serial_init(int chan, void *ignored); extern void serial_fixups(void); @@ -119,6 +114,27 @@ } #endif /* CONFIG_VGA_CONSOLE */ +static void +get_of_args(void) +{ + int size; + phandle chosen; + char buf[256]; + + /* Get bootargs property of /chosen node */ + if (!(chosen = finddevice("/chosen"))) + return; + + if (getprop(chosen, "bootargs", buf, sizeof(buf)) != 4) + return; + + if (size > sizeof(cmd_buf)) + size = sizeof(cmd_buf); + + if (size > 1) /* includes null-terminator */ + memcpy(cmd_buf, buf, size); +} + unsigned long decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, RESIDUAL *residual, void *OFW_interface) @@ -131,14 +147,13 @@ char *cp; /* Default to 32MiB memory. */ unsigned long TotalMemory = 0x02000000; - int dev_handle; - int mem_info[2]; - int res, size; - unsigned char board_type; - unsigned char base_mod; int start_multi = 0; unsigned int pci_viddid, pci_did, tulip_pci_base, tulip_base; + /* If we have Open Firmware, initialise it immediately */ + if (OFW_interface) + ofinit(OFW_interface); + serial_fixups(); com_port = serial_init(0, NULL); #if defined(CONFIG_VGA_CONSOLE) @@ -175,7 +190,8 @@ /* Is this Motorola PPCBug? */ if ((1 & residual->VitalProductData.FirmwareSupports) && (1 == residual->VitalProductData.FirmwareSupplier)) { - board_type = inb(0x800) & 0xF0; + unsigned char base_mod; + unsigned char board_type = inb(0x800) & 0xF0; /* * Reset the onboard 21x4x Ethernet @@ -231,35 +247,23 @@ * we don't try this on a PReP box without OF * -- Cort */ - while (OFW_interface && ((unsigned long)OFW_interface < 0x10000000) ) + while (OFW_interface) { - /* We need to restore the slightly inaccurate - * MSR so that OpenFirmware will behave. -- Tom - */ - _put_MSR(orig_MSR); - of_init(OFW_interface); + phandle dev_handle; + int mem_info[2]; /* get handle to memory description */ - res = of_finddevice("/memory@0", - &dev_handle); - if (res) + if (!(dev_handle = finddevice("/memory@0"))) break; /* get the info */ - res = of_getprop(dev_handle, - "reg", - mem_info, - sizeof(mem_info), - &size); - if (res) + if (getprop(dev_handle, "reg", mem_info, + sizeof(mem_info)) !=8) break; TotalMemory = mem_info[1]; break; } - - /* Enforce a sane MSR for booting. */ - _put_MSR(MSR_IP); } /* assume the chunk below 8M is free */ @@ -300,6 +304,10 @@ if (keyb_present) CRT_tstc(); /* Forces keyboard to be initialized */ + /* If we have OF then try to get args from there */ + if (OFW_interface) + get_of_args(); + puts("\nLinux/PPC load: "); cp = cmd_line; memcpy (cmd_line, cmd_preset, sizeof(cmd_preset)); @@ -338,6 +346,18 @@ *cp = 0; puts("\nUncompressing Linux..."); + /* + * If we have OF, then we have deferred setting the MSR. + * We must set it now because we are about to overwrite + * the exception table. The new MSR value will disable + * machine check exceptions and point the exception table + * to the ROM. + */ + if (OFW_interface) { + mtmsr(MSR_IP | MSR_FP); + asm volatile("isync"); + } + gunzip(0, 0x400000, zimage_start, &zimage_size); puts("done.\n"); @@ -353,7 +373,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 Index: arch/ppc/boot/prep/of1275.c =================================================================== RCS file: arch/ppc/boot/prep/of1275.c diff -N arch/ppc/boot/prep/of1275.c --- arch/ppc/boot/prep/of1275.c 22 Jul 2004 19:48:59 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,427 +0,0 @@ -/* Open Firmware Client Interface */ - - -#include "of1275.h" - - -static int (*of_server)(void *) = (int(*)(void*))-1; - -void -of_init(void *handler) -{ - of_server = (int(*)(void*))handler; -} - - -/* 6.3.2.1 Client interface */ - - -int -of_test(const char *name, int *missing) -{ - int result; - static of_test_service s; - s.service = "test"; - s.n_args = 1; - s.n_returns = 1; - s.name = name; - result = of_server(&s); - *missing = s.missing; - return result; -} - - -/* 6.3.2.2 Device tree */ - - -int -of_peer(int phandle, int *sibling_phandle) -{ - int result; - static of_peer_service s; - s.service = "peer"; - s.n_args = 1; - s.n_returns = 1; - s.phandle = phandle; - result = of_server(&s); - *sibling_phandle = s.sibling_phandle; - return result; -} - -int -of_child(int phandle, int *child_phandle) -{ - int result; - static of_child_service s; - s.service = "child"; - s.n_args = 1; - s.n_returns = 1; - s.phandle = phandle; - result = of_server(&s); - *child_phandle = s.child_phandle; - return result; -} - -int -of_parent(int phandle, int *parent_phandle) -{ - int result; - static of_parent_service s; - s.service = "parent"; - s.n_args = 1; - s.n_returns = 1; - s.phandle = phandle; - result = of_server(&s); - *parent_phandle = s.parent_phandle; - return result; -} - -int -of_instance_to_package(int ihandle, int *phandle) -{ - int result; - static of_instance_to_package_service s; - s.service = "instance-to-package"; - s.n_args = 1; - s.n_returns = 1; - s.ihandle = ihandle; - result = of_server(&s); - *phandle = s.phandle; - return result; -} - -int -of_getproplen(int phandle, const char *name, int *proplen) -{ - int result; - static of_getproplen_service s; - s.service = "getproplen"; - s.n_args = 2; - s.n_returns = 1; - s.phandle = phandle; - s.name = name; - result = of_server(&s); - *proplen = s.proplen; - return result; -} - -int -of_getprop(int phandle, const char *name, void *buf, int buflen, int *size) -{ - int result; - static of_getprop_service s; - s.service = "getprop"; - s.n_args = 4; - s.n_returns = 1; - s.phandle = phandle; - s.name = name; - s.buf = buf; - s.buflen = buflen; - result = of_server(&s); - *size = s.size; - return result; -} - -int -of_nextprop(int phandle, const char *previous, void *buf, int *flag) -{ - int result; - static of_nextprop_service s; - s.service = "nextprop"; - s.n_args = 3; - s.n_returns = 1; - s.phandle = phandle; - s.previous = previous; - s.buf = buf; - result = of_server(&s); - *flag = s.flag; - return result; -} - -int -of_setprop(int phandle, const char *name, void *buf, int len, int *size) -{ - int result; - static of_setprop_service s; - s.service = "setprop"; - s.n_args = 4; - s.n_returns = 1; - s.phandle = phandle; - s.name = name; - s.buf = buf; - s.len = len; - result = of_server(&s); - *size = s.size; - return result; -} - -int -of_canon(const char *device_specifier, void *buf, int buflen, int *length) -{ - int result; - static of_canon_service s; - s.service = "canon"; - s.n_args = 3; - s.n_returns = 1; - s.device_specifier = device_specifier; - s.buf = buf; - s.buflen = buflen; - result = of_server(&s); - *length = s.length; - return result; -} - -int -of_finddevice(const char *device_specifier, int *phandle) -{ - int result; - static of_finddevice_service s; - s.service = "finddevice"; - s.n_args = 1; - s.n_returns = 1; - s.device_specifier = device_specifier; - result = of_server(&s); - *phandle = s.phandle; - return result; -} - -int -of_instance_to_path(int ihandle, void *buf, int buflen, int *length) -{ - int result; - static of_instance_to_path_service s; - s.service = "instance-to-path"; - s.n_args = 3; - s.n_returns = 1; - s.ihandle = ihandle; - s.buf = buf; - s.buflen = buflen; - result = of_server(&s); - *length = s.length; - return result; -} - -int -of_package_to_path(int phandle, void *buf, int buflen, int *length) -{ - int result; - static of_package_to_path_service s; - s.service = "package-to-path"; - s.n_args = 3; - s.n_returns = 1; - s.phandle = phandle; - s.buf = buf; - s.buflen = buflen; - result = of_server(&s); - *length = s.length; - return result; -} - -/* int of_call_method(const char *method, int ihandle, ...); */ - - -/* 6.3.2.3 Device I/O */ - - -int -of_open(const char *device_specifier, int *ihandle) -{ - int result; - static of_open_service s; - s.service = "open"; - s.n_args = 1; - s.n_returns = 1; - s.device_specifier = device_specifier; - result = of_server(&s); - *ihandle = s.ihandle; - return result; -} - -int -of_close(int ihandle) -{ - int result; - static of_close_service s; - s.service = "close"; - s.n_args = 1; - s.n_returns = 0; - s.ihandle = ihandle; - result = of_server(&s); - return result; -} - -int -of_read(int ihandle, void *addr, int len, int *actual) -{ - int result; - static of_read_service s; - s.service = "read"; - s.n_args = 3; - s.n_returns = 1; - s.ihandle = ihandle; - s.addr = addr; - s.len = len; - result = of_server(&s); - *actual = s.actual; - return result; -} - -int -of_write(int ihandle, void *addr, int len, int *actual) -{ - int result; - static of_write_service s; - s.service = "write"; - s.n_args = 3; - s.n_returns = 1; - s.ihandle = ihandle; - s.addr = addr; - s.len = len; - result = of_server(&s); - *actual = s.actual; - return result; -} - -int -of_seek(int ihandle, int pos_hi, int pos_lo, int *status) -{ - int result; - static of_seek_service s; - s.service = "seek"; - s.n_args = 3; - s.n_returns = 1; - s.ihandle = ihandle; - s.pos_hi = pos_hi; - s.pos_lo = pos_lo; - result = of_server(&s); - *status = s.status; - return result; -} - - -/* 6.3.2.4 Memory */ - - -int -of_claim(void *virt, int size, int align, void **baseaddr) -{ - int result; - static of_claim_service s; - s.service = "claim"; - s.n_args = 3; - s.n_returns = 1; - s.virt = virt; - s.size = size; - s.align = align; - result = of_server(&s); - *baseaddr = s.baseaddr; - return result; -} - -int -of_release(void *virt, int size) -{ - int result; - static of_release_service s; - s.service = "release"; - s.n_args = 2; - s.n_returns = 0; - s.virt = virt; - s.size = size; - result = of_server(&s); - return result; -} - - -/* 6.3.2.5 Control transfer */ - - -int -of_boot(const char *bootspec) -{ - int result; - static of_boot_service s; - s.service = "boot"; - s.n_args = 1; - s.n_returns = 0; - s.bootspec = bootspec; - result = of_server(&s); - return result; -} - -int -of_enter(void) -{ - int result; - static of_enter_service s; - s.service = "enter"; - s.n_args = 0; - s.n_returns = 0; - result = of_server(&s); - return result; -} - -int -of_exit(void) -{ - int result; - static of_exit_service s; - s.service = "exit"; - s.n_args = 0; - s.n_returns = 0; - result = of_server(&s); - return result; -} - -/* int of_chain(void *virt, int size, void *entry, void *args, int len); */ - - -/* 6.3.2.6 User interface */ - - -/* int of_interpret(const char *arg, ...); */ - -int -of_set_callback(void *newfunc, void **oldfunc) -{ - int result; - static of_set_callback_service s; - s.service = "set-callback"; - s.n_args = 1; - s.n_returns = 1; - s.newfunc = newfunc; - result = of_server(&s); - *oldfunc = s.oldfunc; - return result; -} - -int -of_set_symbol_lookup(void *sym_to_value, void *value_to_sym) -{ - int result; - static of_set_symbol_lookup_service s; - s.service = "set-symbol-lookup"; - s.n_args = 2; - s.n_returns = 0; - s.sym_to_value = sym_to_value; - s.value_to_sym = s.value_to_sym; - result = of_server(&s); - return result; -} - - -/* 6.3.2.7 Time */ - - -int -of_milliseconds(int *ms) -{ - int result; - static of_milliseconds_service s; - s.service = "milliseconds"; - s.n_args = 0; - s.n_returns = 1; - result = of_server(&s); - *ms = s.ms; - return result; -} Index: arch/ppc/boot/prep/of1275.h =================================================================== RCS file: arch/ppc/boot/prep/of1275.h diff -N arch/ppc/boot/prep/of1275.h --- arch/ppc/boot/prep/of1275.h 22 Jul 2004 19:48:59 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,421 +0,0 @@ -/* 6.3.2.1 Client interface */ - - -typedef struct _of_test_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *name; - /*out*/ - int missing; -} of_test_service; - -int of_test(const char *name, int *missing); - - -/* 6.3.2.2 Device tree */ - - -typedef struct _of_peer_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - /*out*/ - int sibling_phandle; -} of_peer_service; - -int of_peer(int phandle, int *sibling_phandle); - - -typedef struct _of_child_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - /*out*/ - int child_phandle; -} of_child_service; - -int of_child(int phandle, int *child_phandle); - - -typedef struct _of_parent_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - /*out*/ - int parent_phandle; -} of_parent_service; - -int of_child(int phandle, int *parent_phandle); - - -typedef struct _of_instance_to_package_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int ihandle; - /*out*/ - int phandle; -} of_instance_to_package_service; - -int of_instance_to_package(int ihandle, int *phandle); - - -typedef struct _of_getproplen_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - const char *name; - /*out*/ - int proplen; -} of_getproplen_service; - -int of_getproplen(int phandle, const char *name, int *proplen); - - -typedef struct _of_getprop_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - const char *name; - void *buf; - int buflen; - /*out*/ - int size; -} of_getprop_service; - -int of_getprop(int phandle, const char *name, void *buf, int buflen, - int *size); - - -typedef struct _of_nextprop_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - const char *previous; - void *buf; - /*out*/ - int flag; -} of_nextprop_service; - -int of_nextprop(int phandle, const char *previous, void *buf, int *flag); - - -typedef struct _of_setprop_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - const char *name; - void *buf; - int len; - /*out*/ - int size; -} of_setprop_service; - -int of_setprop(int phandle, const char *name, void *buf, int len, int *size); - - -typedef struct _of_canon_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *device_specifier; - void *buf; - int buflen; - /*out*/ - int length; -} of_canon_service; - -int of_canon(const char *device_specifier, void *buf, int buflen, int *length); - - -typedef struct _of_finddevice_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *device_specifier; - /*out*/ - int phandle; -} of_finddevice_service; - -int of_finddevice(const char *device_specifier, int *phandle); - - -typedef struct _of_instance_to_path_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int ihandle; - void *buf; - int buflen; - /*out*/ - int length; -} of_instance_to_path_service; - -int of_instance_to_path(int ihandle, void *buf, int buflen, int *length); - - -typedef struct _of_package_to_path_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - void *buf; - int buflen; - /*out*/ - int length; -} of_package_to_path_service; - -int of_package_to_path(int phandle, void *buf, int buflen, int *length); - - -typedef struct _of_call_method_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *method; - int ihandle; - /*...*/ - int args[0]; -} of_call_method_service; - -int of_call_method(const char *method, int ihandle, ...); - - -/* 6.3.2.3 Device I/O */ - - -typedef struct _of_open_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *device_specifier; - /*out*/ - int ihandle; -} of_open_service; - -int of_open(const char *device_specifier, - int *ihandle); - - -typedef struct _of_close_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int ihandle; - /*out*/ -} of_close_service; - -int of_close(int ihandle); - - -typedef struct _of_read_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int ihandle; - void *addr; - int len; - /*out*/ - int actual; -} of_read_service; - -int of_read(int ihandle, void *addr, int len, int *actual); - - -typedef struct _of_write_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int ihandle; - void *addr; - int len; - /*out*/ - int actual; -} of_write_service; - -int of_write(int ihandle, void *addr, int len, int *actual); - - -typedef struct _of_seek_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int ihandle; - int pos_hi; - int pos_lo; - /*out*/ - int status; -} of_seek_service; - -int of_seek(int ihandle, int pos_hi, int pos_lo, int *status); - - -/* 6.3.2.4 Memory */ - - -typedef struct _of_claim_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - void *virt; - int size; - int align; - /*out*/ - void *baseaddr; -} of_claim_service; - -int of_claim(void *virt, int size, int align, void **baseaddr); - - -typedef struct _of_release_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - void *virt; - int size; - int align; - /*out*/ -} of_release_service; - -int of_release(void *virt, int size); - - -/* 6.3.2.5 Control transfer */ - - -typedef struct _of_boot_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *bootspec; - /*out*/ -} of_boot_service; - -int of_boot(const char *bootspec); - - -typedef struct _of_enter_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - /*out*/ -} of_enter_service; - -int of_enter(void); - - -typedef struct _of_exit_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - /*out*/ -} of_exit_service; - -int of_exit(void); - - -typedef struct _of_chain_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - void *virt; - int size; - void *entry; - void *args; - int len; - /*out*/ -} of_chain_service; - -int of_chain(void *virt, int size, void *entry, void *args, int len); - - -/* 6.3.2.6 User interface */ - - -typedef struct _of_interpret_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *cmd; - int args[0]; - /*...*/ - /*out*/ - /*...*/ -} of_interpret_service; - -int of_interpret(const char *arg, ...); - - -typedef struct _of_set_callback_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - void *newfunc; - /*out*/ - void *oldfunc; -} of_set_callback_service; - -int of_set_callback(void *newfunc, void **oldfunc); - - -typedef struct _of_set_symbol_lookup_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - void *sym_to_value; - void *value_to_sym; - /*out*/ -} of_set_symbol_lookup_service; - -int of_set_symbol_lookup(void *sym_to_value, void *value_to_sym); - - -/* 6.3.2.7 Time */ - - -typedef struct _of_milliseconds_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - /*out*/ - int ms; -} of_milliseconds_service; - -int of_milliseconds(int *ms); Index: arch/ppc/boot/prep/vreset.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/prep/vreset.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/prep/vreset.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/prep/vreset.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -389,7 +389,7 @@ extern void puts(const char *); static void unlockS3(void); -static void inline +static inline void outw(int port, unsigned short val) { outb(port, val >> 8); @@ -691,14 +691,14 @@ unsigned long regs[NPCIREGS]; } PCI_slots [NSLOTS] = { - { (unsigned long *)0x80808000, 0xDEADBEEF }, /* onboard */ - { (unsigned long *)0x80800800, 0xDEADBEEF }, /* onboard */ - { (unsigned long *)0x80801000, 0xDEADBEEF }, /* onboard */ - { (unsigned long *)0x80802000, 0xDEADBEEF }, /* onboard */ - { (unsigned long *)0x80804000, 0xDEADBEEF }, /* onboard */ - { (unsigned long *)0x80810000, 0xDEADBEEF }, /* slot A/1 */ - { (unsigned long *)0x80820000, 0xDEADBEEF }, /* slot B/2 */ - { (unsigned long *)0x80840000, 0xDEADBEEF } /* slot C/3 */ + { (unsigned long *)0x80808000, {0xDEADBEEF,} }, /* onboard */ + { (unsigned long *)0x80800800, {0xDEADBEEF,} }, /* onboard */ + { (unsigned long *)0x80801000, {0xDEADBEEF,} }, /* onboard */ + { (unsigned long *)0x80802000, {0xDEADBEEF,} }, /* onboard */ + { (unsigned long *)0x80804000, {0xDEADBEEF,} }, /* onboard */ + { (unsigned long *)0x80810000, {0xDEADBEEF,} }, /* slot A/1 */ + { (unsigned long *)0x80820000, {0xDEADBEEF,} }, /* slot B/2 */ + { (unsigned long *)0x80840000, {0xDEADBEEF,} } /* slot C/3 */ }; Index: arch/ppc/boot/simple/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/simple/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/simple/Makefile 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/boot/simple/Makefile 4 Aug 2004 01:26:07 -0000 1.2 @@ -9,12 +9,10 @@ # or implied. # # Notes: -# (1) For machine targets which produce more than one image, define -# ZNETBOOT and ZNETBOOTRD to the image which should be available for -# 'znetboot' and 'znetboot.initrd` -# (2) For machine targets which use the mktree program, define END to be -# the machine name you want in the image, and you can optionally set -# ENTRYPOINT which the image should be loaded at. The optimal setting +# (1) All machines must set the END variable to the suffix of the preferred +# final image (i.e. would be copied in 'make znetboot'. +# (2) For machine targets which use the mktree program you can optionally +# set ENTRYPOINT which the image should be loaded at. The optimal setting # for ENTRYPOINT is the link address. USE_STANDARD_AS_RULE := true @@ -25,27 +23,58 @@ ifeq ($(CONFIG_EMBEDDEDBOOT),y) ZIMAGE := zImage-EMBEDDED ZIMAGEINITRD := zImage.initrd-EMBEDDED +MISC := misc-embedded.o +END := embedded +endif +ifeq ($(CONFIG_IBM_OPENBIOS),y) +ZIMAGE := zImage-TREE +ZIMAGEINITRD := zImage.initrd-TREE +END := treeboot TFTPIMAGE := /tftpboot/zImage.embedded MISC := misc-embedded.o endif +ifeq ($(CONFIG_EBONY),y) +ZIMAGE := zImage-TREE +ZIMAGEINITRD := zImage.initrd-TREE +END := ebony +ENTRYPOINT := 0x00800000 +EXTRA := misc-44x.o +endif +ifeq ($(CONFIG_OCOTEA),y) +ZIMAGE := zImage-TREE +ZIMAGEINITRD := zImage.initrd-TREE +END := ocotea +ENTRYPOINT := 0x00800000 +EXTRA := misc-44x.o +endif ifeq ($(CONFIG_GEMINI),y) ZIMAGE := zImage-SMON ZIMAGEINITRD := zImage.initrd-SMON -TFTPIMAGE := /tftpboot/zImage.gemini +END := 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)$(CONFIG_PRPMC750),y) ZIMAGE := zImage-PPLUS ZIMAGEINITRD := zImage.initrd-PPLUS EXTRA := ../common/mpc10x_memory.o TFTPIMAGE := /tftpboot/zImage.pplus -ZNETBOOT := zImage.pplus -ZNETBOOTRD := zImage.initrd.pplus +END := pplus +endif +ifeq ($(CONFIG_PPLUS),y) +EXTRA := legacy.o endif - ifeq ($(CONFIG_PAL4),y) ZIMAGE := zImage-PAL4 ZIMAGEINITRD := zImage.initrd-PAL4 -TFTPIMAGE := /tftpboot/zImage.pal4 +END := pal4 +endif +ifeq ($(CONFIG_SANDPOINT),y) +ZIMAGE := zImage-SP +ZIMAGEINITRD := zImage.initrd-SP +CACHEFLAG := -include clear.S +TFTPIMAGE := /tftpboot/zImage.sandpoint +END := sandpoint endif ifeq ($(CONFIG_SPRUCE),y) ZIMAGE := zImage-TREE @@ -53,18 +82,20 @@ ENTRYPOINT := 0x00800000 MISC := misc-spruce.o END := spruce -TFTPIMAGE := /tftpboot/zImage.$(END) endif + +TFTPIMAGE ?= /tftpboot/zImage.$(END) ifeq ($(CONFIG_SMP),y) TFTPIMAGE += .smp endif + # Setup a default address to put ourselves, change it as needed. LD_ARGS = -T ../ld.script -Ttext 0x00800000 -Bstatic ifdef CONFIG_8xx LD_ARGS := -T ../ld.script -Ttext 0x00180000 -Bstatic endif -ifeq ($(CONFIG_8260)$(CONFIG_4xx),y) +ifeq ($(CONFIG_8260)$(CONFIG_40x),y) LD_ARGS := -T ../ld.script -Ttext 0x00400000 -Bstatic endif OBJCOPY_ARGS := -O elf32-powerpc @@ -74,7 +105,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 @@ -123,30 +154,22 @@ rm -f zvmlinux.initrd znetboot: zImage -ifneq ($(ZNETBOOT),) - cp ../images/$(ZNETBOOT) $(TFTPIMAGE) -else - cp ../images/zImage.* $(TFTPIMAGE) -endif + cp ../images/zImage.$(END) $(TFTPIMAGE) znetboot.initrd: zImage.initrd -ifneq ($(ZNETBOOTRD),) - cp ../images/$(ZNETBOOTRD) $(TFTPIMAGE) -else - cp ../images/zImage.* $(TFTPIMAGE) -endif + cp ../images/zImage.initrd.$(END) $(TFTPIMAGE) zImage-EMBEDDED: zvmlinux - mv zvmlinux ../images/zImage.embedded + mv zvmlinux ../images/zImage.$(END) zImage.initrd-EMBEDDED: zvmlinux.initrd - mv zvmlinux.initrd ../images/zImage.initrd.embedded + mv zvmlinux.initrd ../images/zImage.initrd.$(END) zImage-PAL4: zvmlinux - cp zvmlinux ../images/zImage.pal4 + mv zvmlinux ../images/zImage.$(END) zImage.initrd-PAL4: zvmlinux.initrd - cp zvmlinux.initrd ../images/zImage.initrd.pal4 + mv zvmlinux.initrd ../images/zImage.initrd.$(END) zImage-PPLUS: zvmlinux $(MKPREP) $(MKBUGBOOT) $(MKPREP) -pbp zvmlinux ../images/zImage.pplus @@ -156,11 +179,17 @@ $(MKPREP) -pbp zvmlinux.initrd ../images/zImage.initrd.pplus $(MKBUGBOOT) zvmlinux.initrd ../images/zImage.initrd.bugboot +zImage-SP: zvmlinux + mv zvmlinux ../images/zImage.sandpoint + +zImage.initrd-SP: zvmlinux.initrd + mv zvmlinux.initrd ../images/zImage.initrd.sandpoint + zImage-SMON: zvmlinux - dd if=zvmlinux of=../images/zImage.gemini skip=64 bs=1k + dd if=zvmlinux of=../images/zImage.$(END) skip=64 bs=1k zImage.initrd-SMON: zvmlinux.initrd - dd if=zvmlinux.initrd of=../images/zImage.initrd.gemini skip=64 bs=1k + dd if=zvmlinux.initrd of=../images/zImage.initrd.$(END) skip=64 bs=1k zImage-TREE: zvmlinux $(MKTREE) zvmlinux ../images/zImage.$(END) $(ENTRYPOINT) Index: arch/ppc/boot/simple/embed_config.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/simple/embed_config.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/simple/embed_config.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/boot/simple/embed_config.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -14,7 +14,7 @@ #endif #ifdef CONFIG_8260 #include -#include +#include #endif #ifdef CONFIG_4xx #include @@ -22,6 +22,7 @@ #if defined(CONFIG_405GP) || defined(CONFIG_NP405H) || defined(CONFIG_NP405L) #include #endif +extern unsigned long timebase_period_ns; /* For those boards that don't provide one. */ @@ -51,7 +52,7 @@ { u_char *mp; u_char eebuf[128]; - int i; + int i = 8; bd_t *bd; bd = *bdp; @@ -63,11 +64,21 @@ /* All we are looking for is the Ethernet MAC address. The * first 8 bytes are 'MOTOROLA', so check for part of that. + * Next, the VPD describes a MAC 'packet' as being of type 08 + * and size 06. So we look for that and the MAC must follow. + * If there are more than one, we still only care about the first. * If it's there, assume we have a valid MAC address. If not, * grab our default one. */ - if ((*(uint *)eebuf) == 0x4d4f544f) - mp = &eebuf[0x4c]; + if ((*(uint *)eebuf) == 0x4d4f544f) { + while (i < 127 && !(eebuf[i] == 0x08 && eebuf[i + 1] == 0x06)) + i += eebuf[i + 1] + 2; /* skip this packet */ + + if (i == 127) /* Couldn't find. */ + mp = (u_char *)def_enet_addr; + else + mp = &eebuf[i + 2]; + } else mp = (u_char *)def_enet_addr; @@ -369,8 +380,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 */ @@ -383,10 +394,10 @@ clk_8260(bd_t *bd) { uint scmr, vco_out, clkin; - uint plldf, pllmf, busdf, brgdf, cpmdf; - volatile immap_t *ip; + uint plldf, pllmf, busdf, cpmdf; + volatile cpm2_map_t *ip; - ip = (immap_t *)IMAP_ADDR; + ip = (cpm2_map_t *)CPM_MAP_ADDR; scmr = ip->im_clkrst.car_scmr; /* The clkin is always bus frequency. @@ -491,7 +502,6 @@ embed_config(bd_t **bdp) { u_char *cp, *keyvals; - int i; bd_t *bd; keyvals = (u_char *)*bdp; @@ -571,7 +581,7 @@ */ bd->bi_intfreq = 200000000; } -#endif /* RPX6 for testing */ +#endif /* RPX6 */ #ifdef CONFIG_ADS8260 void @@ -640,7 +650,7 @@ } #endif /* WILLOW */ -#ifdef CONFIG_TREEBOOT +#ifdef CONFIG_IBM_OPENBIOS /* This could possibly work for all treeboot roms. */ #define BOARD_INFO_VECTOR 0xFFFE0B50 @@ -654,15 +664,12 @@ bd_t *(*get_board_info)(void) = (bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR); #if !defined(CONFIG_STB03xxx) - volatile emac_t *emacp; - emacp = (emac_t *)EMAC0_BASE; /* assume 1st emac - armin */ - /* shut down the Ethernet controller that the boot rom * sometimes leaves running. */ - mtdcr(DCRN_MALCR, MALCR_MMSR); /* 1st reset MAL */ - while (mfdcr(DCRN_MALCR) & MALCR_MMSR) {}; /* wait for the reset */ - emacp->em0mr0 = 0x20000000; /* then reset EMAC */ + mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR); /* 1st reset MAL */ + while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; /* wait for the reset */ + out_be32((u32 *)EMAC0_BASE, 0x20000000); /* then reset EMAC */ eieio(); #endif @@ -752,6 +759,6 @@ bd->bi_busfreq = 100000000; bd->bi_pci_busfreq= 33000000 ; #endif + timebase_period_ns = 1000000000 / bd->bi_tbfreq; } #endif - Index: arch/ppc/boot/simple/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/simple/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/simple/head.S 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/boot/simple/head.S 4 Aug 2004 01:26:07 -0000 1.2 @@ -35,8 +35,8 @@ .globl start start: bl start_ -#ifdef CONFIG_TREEBOOT - /* The IBM "Tree" bootrom knows that the address of the bootrom +#ifdef CONFIG_IBM_OPENBIOS + /* The IBM OpenBIOS bootroms know that the address of the bootrom * read only structure is 4 bytes after _start. */ .long 0x62726f6d # structure ID - "brom" Index: arch/ppc/boot/simple/iic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/simple/iic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/simple/iic.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/boot/simple/iic.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -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; Index: arch/ppc/boot/simple/m8260_tty.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/simple/m8260_tty.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/simple/m8260_tty.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/boot/simple/m8260_tty.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -3,7 +3,8 @@ */ #include #include -#include +#include +#include uint no_print; extern char *params[]; @@ -29,12 +30,12 @@ volatile scc_uart_t *sup; #endif volatile cbd_t *tbdf, *rbdf; - volatile immap_t *ip; - volatile iop8260_t *io; - volatile cpm8260_t *cp; + volatile cpm2_map_t *ip; + volatile iop_cpm2_t *io; + volatile cpm_cpm2_t *cp; uint dpaddr, memaddr; - ip = (immap_t *)IMAP_ADDR; + ip = (cpm2_map_t *)CPM_MAP_ADDR; cp = &ip->im_cpm; io = &ip->im_ioport; @@ -223,10 +224,10 @@ volatile char *buf; volatile smc_uart_t *up; volatile scc_uart_t *sup; - volatile immap_t *ip; + volatile cpm2_map_t *ip; int i, nc; - ip = (immap_t *)IMAP_ADDR; + ip = (cpm2_map_t *)CPM_MAP_ADDR; #ifdef SCC_CONSOLE sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; @@ -255,10 +256,10 @@ volatile char *buf; volatile smc_uart_t *up; volatile scc_uart_t *sup; - volatile immap_t *ip; + volatile cpm2_map_t *ip; extern bd_t *board_info; - ip = (immap_t *)IMAP_ADDR; + ip = (cpm2_map_t *)CPM_MAP_ADDR; #ifdef SCC_CONSOLE sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; tbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_tbase]; @@ -298,9 +299,9 @@ volatile cbd_t *rbdf; volatile smc_uart_t *up; volatile scc_uart_t *sup; - volatile immap_t *ip; + volatile cpm2_map_t *ip; - ip = (immap_t *)IMAP_ADDR; + ip = (cpm2_map_t *)CPM_MAP_ADDR; #ifdef SCC_CONSOLE sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase]; Index: arch/ppc/boot/simple/misc-embedded.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/simple/misc-embedded.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/simple/misc-embedded.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/boot/simple/misc-embedded.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -78,6 +79,14 @@ extern void gunzip(void *, int, unsigned char *, int *); extern void embed_config(bd_t **bp); +/* Weak function for boards which don't need to build the + * board info struct because they are using PPCBoot/U-Boot. + */ +void __attribute__ ((weak)) +embed_config(bd_t **bdp) +{ +} + unsigned long load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, bd_t *bp) Index: arch/ppc/boot/simple/misc-spruce.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/simple/misc-spruce.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/simple/misc-spruce.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/boot/simple/misc-spruce.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -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 ) { Index: arch/ppc/boot/utils/mkbugboot.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/utils/mkbugboot.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/utils/mkbugboot.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/utils/mkbugboot.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -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 * @@ -51,29 +51,22 @@ /* size of read buffer */ #define SIZE 0x1000 -#ifndef __sun__ -/* typedef long int32_t; */ -typedef unsigned long uint32_t; -typedef unsigned short uint16_t; -typedef unsigned char uint8_t; -#endif - /* PPCBUG ROM boot header */ typedef struct bug_boot_header { - uint8_t magic_word[4]; /* "BOOT" */ - uint32_t entry_offset; /* Offset from top of header to code */ - uint32_t routine_length; /* Length of code */ - uint8_t routine_name[8]; /* Name of the boot code */ + unsigned char magic_word[4]; /* "BOOT" */ + unsigned long entry_offset; /* Offset from top of header to code */ + unsigned long routine_length; /* Length of code */ + unsigned char routine_name[8]; /* Name of the boot code */ } bug_boot_header_t; #define HEADER_SIZE sizeof(bug_boot_header_t) -uint32_t copy_image(int32_t in_fd, int32_t out_fd) +unsigned long copy_image(int32_t in_fd, int32_t out_fd) { - uint8_t buf[SIZE]; + unsigned char buf[SIZE]; int n; - uint32_t image_size = 0; - uint8_t zero = 0; + unsigned long image_size = 0; + unsigned char zero = 0; lseek(in_fd, ELF_HEADER_SIZE, SEEK_SET); @@ -95,11 +88,11 @@ return image_size; } -void write_bugboot_header(int32_t out_fd, uint32_t boot_size) +void write_bugboot_header(int32_t out_fd, unsigned long boot_size) { - uint8_t header_block[HEADER_SIZE]; + unsigned char 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 */ @@ -112,16 +105,16 @@ write(out_fd, header_block, HEADER_SIZE); } -uint16_t calc_checksum(int32_t bug_fd) +unsigned short calc_checksum(int32_t bug_fd) { - uint32_t checksum_var = 0; - uint8_t buf[2]; + unsigned long checksum_var = 0; + unsigned char buf[2]; int n; /* Checksum loop */ while ( (n = read(bug_fd, buf, 2) ) ) { - checksum_var = checksum_var + *(uint16_t *)buf; + checksum_var = checksum_var + *(unsigned short *)buf; /* If we carry out, mask it and add one to the checksum */ if (checksum_var >> 16) @@ -135,9 +128,9 @@ { int32_t image_fd, bugboot_fd; int argptr = 1; - uint32_t kernel_size = 0; - uint16_t checksum = 0; - uint8_t bugbootname[256]; + unsigned long kernel_size = 0; + unsigned short checksum = 0; + unsigned char bugbootname[256]; if ( (argc != 3) ) { @@ -146,7 +139,7 @@ } /* Get file args */ - + /* kernel image file */ if ((image_fd = open( argv[argptr] , 0)) < 0) exit(-1); @@ -182,7 +175,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); Index: arch/ppc/boot/utils/mkimage.wrapper =================================================================== RCS file: arch/ppc/boot/utils/mkimage.wrapper diff -N arch/ppc/boot/utils/mkimage.wrapper --- arch/ppc/boot/utils/mkimage.wrapper 22 Jul 2004 19:48:59 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,16 +0,0 @@ -#!/bin/bash - -# -# Build PPCBoot image when `mkimage' tool is available. -# - -MKIMAGE=$(type -path mkimage) - -if [ -z "${MKIMAGE}" ]; then - # Doesn't exist - echo '"mkimage" command not found - PPCBoot images will not be built' >&2 - exit 0; -fi - -# Call "mkimage" to create PPCBoot image -${MKIMAGE} "$@" Index: arch/ppc/boot/utils/mknote.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/utils/mknote.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/utils/mknote.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/utils/mknote.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -25,7 +25,7 @@ PL(0x1275); /* name */ printf("PowerPC"); printf("%c", 0); - + /* descriptor */ /* real-mode */ PL(0xffffffff); Index: arch/ppc/boot/utils/mkprep.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/utils/mkprep.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/utils/mkprep.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/utils/mkprep.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -12,12 +12,14 @@ * -- Cort * * Modified for x86 hosted builds by Matt Porter + * Modified for Sparc hosted builds by Peter Wahl */ #include #include #include #include +#include #include #include @@ -96,14 +98,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 +132,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,26 +142,26 @@ write_asm_data( in_fd, out_fd ); else copy_image(in_fd, out_fd); - + return 0; } void write_prep_partition(int in, int out) { unsigned char block[512]; - partition_entry_t *pe = (partition_entry_t *)&block[0x1BE]; + partition_entry_t pe; 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,13 +174,13 @@ /* 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 */ - pe->boot_indicator = BootActive; - pe->system_indicator = SystemPrep; + pe.boot_indicator = BootActive; + pe.system_indicator = SystemPrep; /* * The first block of the diskette is used by this "boot record" which * actually contains the partition table. (The first block of the @@ -186,12 +188,12 @@ * one partition on the diskette and it shall contain the rest of the * diskette. */ - pe->starting_head = 0; /* zero-based */ - pe->starting_sector = 2; /* one-based */ - pe->starting_cylinder = 0; /* zero-based */ - pe->ending_head = 1; /* assumes two heads */ - pe->ending_sector = 18; /* assumes 18 sectors/track */ - pe->ending_cylinder = 79; /* assumes 80 cylinders/diskette */ + pe.starting_head = 0; /* zero-based */ + pe.starting_sector = 2; /* one-based */ + pe.starting_cylinder = 0; /* zero-based */ + pe.ending_head = 1; /* assumes two heads */ + pe.ending_sector = 18; /* assumes 18 sectors/track */ + pe.ending_cylinder = 79; /* assumes 80 cylinders/diskette */ /* * The "PReP" software ignores the above fields and just looks at @@ -201,25 +203,27 @@ * - unlike the above sector numbers, the beginning sector is zero-based! */ #if 0 - pe->beginning_sector = cpu_to_le32(1); + 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; + pe.beginning_sector = 0; #else - pe->beginning_sector = cpu_to_le32(0); + pe.beginning_sector = cpu_to_le32(0); #endif /* __i386__ */ -#endif +#endif #ifdef __i386__ - pe->number_of_sectors = 2*18*80-1; + pe.number_of_sectors = 2*18*80-1; #else - pe->number_of_sectors = cpu_to_le32(2*18*80-1); + pe.number_of_sectors = cpu_to_le32(2*18*80-1); #endif /* __i386__ */ + memcpy(&block[0x1BE],&pe,sizeof(pe)); + 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 +249,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; Index: arch/ppc/boot/utils/mktree.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/boot/utils/mktree.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/boot/utils/mktree.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/boot/utils/mktree.c 4 Aug 2004 01:26:07 -0000 1.2 @@ -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" Index: arch/ppc/kernel/btext.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/btext.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/btext.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/btext.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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, }; Index: arch/ppc/kernel/checks.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/checks.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/checks.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/checks.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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" Index: arch/ppc/kernel/cpu_setup_6xx.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/cpu_setup_6xx.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/cpu_setup_6xx.S 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/cpu_setup_6xx.S 4 Aug 2004 01:26:08 -0000 1.2 @@ -104,8 +104,8 @@ /* 7400 <= rev 2.7 and 7410 rev = 1.0 suffer from some * erratas we work around here. - * Moto MPC710CE.pdf describes them, those are errata - * #3, #4 and #5 + * Moto MPC7410CE.pdf describes them, those are errata + * #3, #4 and #5 (7400 erratas #13, #14 and #15). * Note that we assume the firmware didn't choose to * apply other workarounds (there are other ones documented * in the .pdf). It appear that Apple firmware only works @@ -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) @@ -155,7 +155,20 @@ BEGIN_FTR_SECTION oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) - li r3,HID0_SPD + + /* 7400 Errata #7, don't enable SGE on < Rev 2.1 */ + mfpvr r10 + rlwinm r3,r10,16,16,31 + cmplwi r3,0x000c + bne 1f /* Not a 7400. */ + andi. r3,r10,0x0f0f + cmpwi 0,r3,0x0200 + bgt 1f /* Rev >= 2.1 */ + li r3,HID0_SGE /* 7400 rev < 2.1, clear SGE. */ + b 2f + +1: li r3,0 /* Don't clear SGE. */ +2: ori r3,r3,HID0_SPD andc r11,r11,r3 /* clear SPD: enable speculative */ li r3,0 mtspr ICTC,r3 /* Instruction Cache Throttling off */ @@ -213,7 +226,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..... @@ -223,9 +236,17 @@ oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) + /* We only want to disable BTIC on 7457's */ + mfpvr r3 + rlwinm r3,r3,16,16,31 + cmplwi r3,0x8002 + li r3,0 /* Assume we don't want to clear BTIC. */ + bne 2f /* Not a 7457. */ + li r3,HID0_BTIC /* 7457, clear BTIC. */ + /* All of the bits we have to clear.... */ - li r3,HID0_SPD | HID0_NOPDST | HID0_NOPTI +2: ori r3,r3,HID0_SPD | HID0_NOPDST | HID0_NOPTI andc r11,r11,r3 /* clear SPD: enable speculative */ li r3,0 @@ -248,20 +269,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 +333,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 +424,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 Index: arch/ppc/kernel/cputable.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/cputable.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/cputable.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/cputable.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -29,12 +29,12 @@ extern void __setup_cpu_745x(unsigned long offset, int cpu_nr, struct cpu_spec* spec); extern void __setup_cpu_power3(unsigned long offset, int cpu_nr, struct cpu_spec* spec); extern void __setup_cpu_power4(unsigned long offset, int cpu_nr, struct cpu_spec* spec); +extern void __setup_cpu_ppc970(unsigned long offset, int cpu_nr, struct cpu_spec* spec); extern void __setup_cpu_8xx(unsigned long offset, int cpu_nr, struct cpu_spec* spec); extern void __setup_cpu_generic(unsigned long offset, int cpu_nr, struct cpu_spec* spec); -#define CLASSIC_PPC (!defined(CONFIG_8xx) && \ - !defined(CONFIG_4xx) && !defined(CONFIG_POWER3) && \ - !defined(CONFIG_POWER4)) +#define CLASSIC_PPC (!defined(CONFIG_8xx) && !defined(CONFIG_4xx) && \ + !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4)) /* This table only contains "desktop" CPUs, it need to be filled with embedded * ones as well... @@ -140,20 +140,29 @@ 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_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_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 | - CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS, + CPU_FTR_750FX | CPU_FTR_HAS_HIGH_BATS, COMMON_PPC, 32, 32, __setup_cpu_750fx @@ -193,6 +202,15 @@ 32, 32, __setup_cpu_7410 }, + { /* 7450 1.x - no doze/nap */ + 0xffffff00, 0x80000100, "7450", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | + CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450, + COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC, + 32, 32, + __setup_cpu_745x + }, { /* 7450 2.0 - no doze/nap */ 0xffffffff, 0x80000200, "7450", CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | @@ -267,6 +285,14 @@ 32, 32, __setup_cpu_603 }, + { /* 8280 is a G2_LE (603e core, plus some) */ + 0x7fff0000, 0x00820000, "8280", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | + CPU_FTR_CAN_NAP | CPU_FTR_HAS_HIGH_BATS, + COMMON_PPC, + 32, 32, + __setup_cpu_603 + }, { /* default match, we assume split I/D cache & TB (non-601)... */ 0x00000000, 0x00000000, "(generic PPC)", CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, @@ -274,7 +300,7 @@ 32, 32, __setup_cpu_generic }, -#endif /* CLASSIC_PPC */ +#endif /* CLASSIC_PPC */ #ifdef CONFIG_PPC64BRIDGE { /* Power3 */ 0xffff0000, 0x00400000, "Power3 (630)", @@ -304,7 +330,7 @@ 128, 128, __setup_cpu_power3 }, -#endif /* CONFIG_PPC64BRIDGE */ +#endif /* CONFIG_PPC64BRIDGE */ #ifdef CONFIG_POWER4 { /* Power4 */ 0xffff0000, 0x00350000, "Power4", @@ -313,7 +339,15 @@ 128, 128, __setup_cpu_power4 }, -#endif /* CONFIG_POWER4 */ + { /* PPC970 */ + 0xffff0000, 0x00390000, "PPC970", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP, + COMMON_PPC | PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC, + 128, 128, + __setup_cpu_ppc970 + }, +#endif /* CONFIG_POWER4 */ #ifdef CONFIG_8xx { /* 8xx */ 0xffff0000, 0x00500000, "8xx", @@ -324,7 +358,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, @@ -361,6 +395,43 @@ 0, /*__setup_cpu_405 */ }, #endif /* CONFIG_4xx */ +#ifdef CONFIG_44x + { /* 440GP Rev. B */ + 0xf0000fff, 0x40000440, "440GP Rev. B", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, + PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, + 32, 32, + 0, /*__setup_cpu_440 */ + }, + { /* 440GP Rev. C */ + 0xf0000fff, 0x40000481, "440GP Rev. C", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, + PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, + 32, 32, + 0, /*__setup_cpu_440 */ + }, + { /* 440GX Rev. A */ + 0xf0000fff, 0x50000850, "440GX Rev. A", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, + PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, + 32, 32, + 0, /*__setup_cpu_440 */ + }, + { /* 440GX Rev. B */ + 0xf0000fff, 0x50000851, "440GX Rev. B", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, + PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, + 32, 32, + 0, /*__setup_cpu_440 */ + }, + { /* 440GX Rev. B1 (2.1) */ + 0xf0000fff, 0x50000852, "440GX Rev. B1 (2.1)", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, + PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, + 32, 32, + 0, /*__setup_cpu_440 */ + }, +#endif /* CONFIG_44x */ #if !CLASSIC_PPC { /* default match */ 0x00000000, 0x00000000, "(generic PPC)", Index: arch/ppc/kernel/entry.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/entry.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/entry.S 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/entry.S 4 Aug 2004 01:26:08 -0000 1.2 @@ -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 @@ -43,6 +43,10 @@ * Handle a system call. */ .text + .stabs "arch/ppc/kernel/",N_SO,0,0,0f + .stabs "entry.S",N_SO,0,0,0f +0: + _GLOBAL(DoSyscall) stw r0,THREAD+LAST_SYSCALL(r2) lwz r11,_CCR(r1) /* Clear SO bit in CR */ @@ -162,7 +166,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 +206,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) @@ -258,6 +262,15 @@ addi r1,r1,INT_FRAME_SIZE blr + .globl syscall_direct_return +syscall_direct_return: + addi r1,r3,-STACK_FRAME_OVERHEAD + lwz r10,TASK_PTRACE(r2) + andi. r10,r10,PT_TRACESYS + beq+ ret_from_except + bl syscall_trace + b ret_from_except + .globl ret_from_fork ret_from_fork: bl schedule_tail @@ -291,7 +304,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 +316,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 +339,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 +364,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 +403,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 */ Index: arch/ppc/kernel/find_name.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/find_name.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/find_name.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/find_name.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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; } Index: arch/ppc/kernel/gen550_dbg.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/gen550_dbg.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/gen550_dbg.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/gen550_dbg.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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); } Index: arch/ppc/kernel/gen550_kgdb.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/gen550_kgdb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/gen550_kgdb.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/gen550_kgdb.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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 * Index: arch/ppc/kernel/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/head.S 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/head.S 4 Aug 2004 01:26:08 -0000 1.2 @@ -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,9 +66,12 @@ mtspr DBAT##n##U,RA; \ mtspr DBAT##n##L,RB; \ 1: -#endif /* CONFIG_PPC64BRIDGE */ +#endif /* CONFIG_PPC64BRIDGE */ .text + .stabs "arch/ppc/kernel/",N_SO,0,0,0f + .stabs "head.S",N_SO,0,0,0f +0: .globl _stext _stext: @@ -79,7 +82,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. @@ -137,6 +140,18 @@ mr r28,r6 mr r27,r7 li r24,0 /* cpu # */ + +#ifdef CONFIG_POWER4 +/* + * On the PPC970, we have to turn off real-mode cache inhibit + * early, before we first turn the MMU off. + */ + mfspr r0,SPRN_PVR + srwi r0,r0,16 + cmpwi r0,0x39 + beql ppc970_setup_hid +#endif + /* * early_init() does the early machine identification and does * the necessary low-level setup and clears the BSS @@ -145,8 +160,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 @@ -157,11 +172,10 @@ */ bl mmu_off __after_mmu_off: - bl clear_bats - bl flush_tlbs #ifndef CONFIG_POWER4 - /* POWER4 doesn't have BATs */ + bl clear_bats + bl flush_tlbs bl initial_bats #if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) bl setup_disp_bat @@ -170,15 +184,23 @@ /* * Load up the SDR1 and segment register values now * since we don't have the BATs. + * Also make sure we are running in 32-bit mode. */ bl reloc_offset - addis r4,r3,_SDR1@ha /* get the value from _SDR1 */ - lwz r4,_SDR1@l(r4) /* assume hash table below 4GB */ - mtspr SDR1,r4 + addis r14,r3,_SDR1@ha /* get the value from _SDR1 */ + lwz r14,_SDR1@l(r14) /* assume hash table below 4GB */ + mtspr SDR1,r14 slbia - lis r5,0x2000 /* set pseudo-segment reg 12 */ - ori r5,r5,0x0ccc + lis r4,0x2000 /* set pseudo-segment reg 12 */ + ori r5,r4,0x0ccc mtsr 12,r5 + ori r4,r4,0x0888 /* set pseudo-segment reg 8 */ + mtsr 8,r4 /* (for access to serial port) */ + mfmsr r0 + clrldi r0,r0,1 + sync + mtmsr r0 + isync #endif /* CONFIG_POWER4 */ /* @@ -707,12 +729,22 @@ mtcrf 0x80,r3 rfi +#ifndef CONFIG_ALTIVEC +#define AltivecAssistException UnknownException +#endif + STD_EXCEPTION(0x1300, Trap_13, InstructionBreakpoint) STD_EXCEPTION(0x1400, SMI, SMIException) STD_EXCEPTION(0x1500, Trap_15, UnknownException) +#ifdef CONFIG_POWER4 STD_EXCEPTION(0x1600, Trap_16, UnknownException) + STD_EXCEPTION(0x1700, Trap_17, AltivecAssistException) + STD_EXCEPTION(0x1800, Trap_18, TAUException) +#else /* !CONFIG_POWER4 */ + STD_EXCEPTION(0x1600, Trap_16, AltivecAssistException) STD_EXCEPTION(0x1700, Trap_17, TAUException) STD_EXCEPTION(0x1800, Trap_18, UnknownException) +#endif STD_EXCEPTION(0x1900, Trap_19, UnknownException) STD_EXCEPTION(0x1a00, Trap_1a, UnknownException) STD_EXCEPTION(0x1b00, Trap_1b, UnknownException) @@ -828,6 +860,7 @@ bt- 9,power_save_6xx_restore /* Check NAP */ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) b transfer_to_handler_cont + #endif /* CONFIG_6xx */ /* @@ -983,7 +1016,9 @@ /* enable use of AltiVec after return */ oris r23,r23,MSR_VEC@h mfspr r5,SPRG3 /* current task's THREAD (phys) */ + li r4,1 li r20,THREAD_VSCR + stw r4,THREAD_USED_VR(r5) LVX(vr0,r20,r5) MTVSCR(vr0) REST_32VR(0,r20,r5) @@ -1181,7 +1216,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 @@ -1233,7 +1268,6 @@ andc r4,r4,r3 mtspr HID0,r4 sync - bl prom_init b __secondary_start #endif /* CONFIG_GEMINI */ .globl __secondary_start_psurge @@ -1277,7 +1311,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 @@ -1305,6 +1339,7 @@ /* enable MMU and jump to start_secondary */ li r4,MSR_KERNEL + FIX_SRR1(r4,r5) lis r3,start_secondary@h ori r3,r3,start_secondary@l mtspr SRR0,r3 @@ -1319,6 +1354,10 @@ */ _GLOBAL(__setup_cpu_power3) blr +_GLOBAL(__setup_cpu_power4) + blr +_GLOBAL(__setup_cpu_ppc970) + blr _GLOBAL(__setup_cpu_generic) blr @@ -1326,7 +1365,14 @@ _GLOBAL(__save_cpu_setup) blr _GLOBAL(__restore_cpu_setup) +#ifdef CONFIG_POWER4 + /* turn off real-mode cache inhibit on the PPC970 */ + mfspr r0,SPRN_PVR + srwi r0,r0,16 + cmpwi r0,0x39 + beq ppc970_setup_hid blr +#endif #endif /* CONFIG_6xx */ /* @@ -1334,6 +1380,11 @@ * IR=0 and DR=0. */ load_up_mmu: + sync /* Force all PTE updates to finish */ + isync + tlbia /* Clear all TLB entries */ + sync /* wait for tlbia/tlbie to finish */ + TLBSYNC /* ... on all CPUs */ /* Load the SDR1 register (hash table base & size) */ lis r6,_SDR1@ha tophys(r6,r6) @@ -1428,14 +1479,7 @@ SYNC RFI /* Load up the kernel context */ -2: - sync /* Force all PTE updates to finish */ - isync - tlbia /* Clear all TLB entries */ - sync /* wait for tlbia/tlbie to finish */ - TLBSYNC /* ... on all CPUs */ - - bl load_up_mmu +2: bl load_up_mmu #ifdef CONFIG_BDI_SWITCH /* Add helper information for the Abatron bdiGDB debugger. @@ -1498,13 +1542,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 +1619,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 @@ -1648,6 +1692,40 @@ blr #endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */ + +#else /* CONFIG_POWER4 */ +ppc970_setup_hid: + li r0,0 + sync + mtspr 0x3f4,r0 + isync + sync + mtspr 0x3f6,r0 + isync + mfspr r0,SPRN_HID0 + li r11,5 /* clear DOZE and SLEEP */ + rldimi r0,r11,52,8 /* and set NAP and DPM */ + mtspr SPRN_HID0,r0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + sync + isync + mfspr r0,SPRN_HID1 + li r11,0x1200 /* enable i-fetch cacheability */ + sldi r11,r11,44 /* and prefetch */ + or r0,r0,r11 + mtspr SPRN_HID1,r0 + mtspr SPRN_HID1,r0 + isync + li r0,0 + sync + mtspr 0x137,0 + isync + blr #endif /* CONFIG_POWER4 */ #ifdef CONFIG_8260 Index: arch/ppc/kernel/head_4xx.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/head_4xx.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/head_4xx.S 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/head_4xx.S 4 Aug 2004 01:26:08 -0000 1.2 @@ -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,192 @@ 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 */ + ori r21, r21, _PAGE_HWEXEC /* make it executable */ + + /* 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 +387,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 +460,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 */ + + /* 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 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 - STND_EXCEPTION(0x1100, DTLBMiss, PPC4xx_dtlb_miss) + /* 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 -### 0x1200 - Instruction TLB Miss Exception + ori r21, r21, _PAGE_ACCESSED + stw r21, 0(r22) - STND_EXCEPTION(0x1200, ITLBMiss, PPC4xx_itlb_miss) + /* 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 +679,215 @@ 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: + ori r21, r21, _PAGE_HWEXEC /* make it executable */ + 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 +897,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 Index: arch/ppc/kernel/head_8xx.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/head_8xx.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/head_8xx.S 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/head_8xx.S 4 Aug 2004 01:26:08 -0000 1.2 @@ -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 @@ -21,9 +21,9 @@ * */ +#include #include #include -#include #include #include #include @@ -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 */ @@ -327,7 +341,7 @@ beq 2f /* If zero, don't try to find a pte */ /* We have a pte table, so load the MI_TWC with the attributes - * for this page, which has only bit 31 set. + * for this "segment." */ tophys(r21,r21) ori r21,r21,1 /* Set valid bit */ @@ -336,7 +350,7 @@ stw r3, 12(r0) lwz r3, 12(r0) #endif - mtspr MI_TWC, r21 /* Set page attributes */ + mtspr MI_TWC, r21 /* Set segment attributes */ #ifdef CONFIG_8xx_CPU6 li r3, 0x3b80 stw r3, 12(r0) @@ -355,8 +369,6 @@ * set. All other Linux PTE bits control the behavior * of the MMU. */ - li r21, 0x0600 - andc r20, r20, r21 /* Clear 21, 22 */ li r21, 0x00f0 rlwimi r20, r21, 0, 24, 28 /* Set 24-27, clear 28 */ @@ -449,8 +461,6 @@ * set. All other Linux PTE bits control the behavior * of the MMU. */ - li r21, 0x0600 - andc r20, r20, r21 /* Clear 21, 22 */ li r21, 0x00f0 rlwimi r20, r21, 0, 24, 28 /* Set 24-27, clear 28 */ @@ -470,7 +480,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 +533,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 @@ -585,8 +604,6 @@ * set. All other Linux PTE bits control the behavior * of the MMU. */ - li r21, 0x0600 - andc r20, r20, r21 /* Clear 21, 22 */ li r21, 0x00f0 rlwimi r20, r21, 0, 24, 28 /* Set 24-27, clear 28 */ @@ -794,16 +811,31 @@ * kernel initialization. This maps the first 8 MBytes of memory 1:1 * virtual to physical. Also, set the cache mode since that is defined * by TLB entries and perform any additional mapping (like of the IMMR). + * If configured to pin some TLBs, we pin the first 8 Mbytes of kernel, + * 24 Mbytes of data, and the 8M IMMR space. Anything not covered by + * these mappings is mapped by page tables. */ initial_mmu: tlbia /* Invalidate all TLB entries */ +#ifdef CONFIG_PIN_TLB + lis r8, MI_RSV4I@h + ori r8, r8, 0x1c00 +#else li r8, 0 - mtspr MI_CTR, r8 /* Set instruction control to zero */ - lis r8, MD_RESETVAL@h +#endif + mtspr MI_CTR, r8 /* Set instruction MMU control */ + +#ifdef CONFIG_PIN_TLB + lis r10, (MD_RSV4I | MD_RESETVAL)@h + ori r10, r10, 0x1c00 + mr r8, r10 +#else + lis r10, MD_RESETVAL@h +#endif #ifndef CONFIG_8xx_COPYBACK - oris r8, r8, MD_WTDEF@h + oris r10, r10, MD_WTDEF@h #endif - mtspr MD_CTR, r8 /* Set data TLB control */ + mtspr MD_CTR, r10 /* Set data TLB control */ /* Now map the lower 8 Meg into the TLBs. For this quick hack, * we can load the instruction and data TLB registers with the @@ -827,6 +859,10 @@ /* Map another 8 MByte at the IMMR to get the processor * internal registers (among other things). */ +#ifdef CONFIG_PIN_TLB + addi r10, r10, 0x0100 + mtspr MD_CTR, r10 +#endif mfspr r9, 638 /* Get current IMMR */ andis. r9, r9, 0xff80 /* Get 8Mbyte boundary */ @@ -840,6 +876,30 @@ ori r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */ mtspr MD_RPN, r8 +#ifdef CONFIG_PIN_TLB + /* Map two more 8M kernel data pages. + */ + addi r10, r10, 0x0100 + mtspr MD_CTR, r10 + + lis r8, KERNELBASE@h /* Create vaddr for TLB */ + addis r8, r8, 0x0080 /* Add 8M */ + ori r8, r8, MI_EVALID /* Mark it valid */ + mtspr MD_EPN, r8 + li r9, MI_PS8MEG /* Set 8M byte page */ + ori r9, r9, MI_SVALID /* Make it valid */ + mtspr MD_TWC, r9 + li r11, MI_BOOTINIT /* Create RPN for address 0 */ + addis r11, r11, 0x0080 /* Add 8M */ + mtspr MD_RPN, r8 + + addis r8, r8, 0x0080 /* Add 8M */ + mtspr MD_EPN, r8 + mtspr MD_TWC, r9 + addis r11, r11, 0x0080 /* Add 8M */ + mtspr MD_RPN, r8 +#endif + /* Since the cache is enabled according to the information we * just loaded into the TLB, invalidate and enable the caches here. * We should probably check/set other modes....later. Index: arch/ppc/kernel/i8259.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/i8259.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/i8259.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/i8259.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -93,7 +93,7 @@ outb(cached_A1,0xA1); outb(cached_21,0x21); } - + static void i8259_mask_irq(unsigned int irq_nr) { unsigned long flags; Index: arch/ppc/kernel/idle.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/idle.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/idle.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/idle.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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; } Index: arch/ppc/kernel/idle_6xx.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/idle_6xx.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/idle_6xx.S 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/idle_6xx.S 4 Aug 2004 01:26:08 -0000 1.2 @@ -52,16 +52,16 @@ mfspr r4,SPRN_HID1 addis r6,r5,nap_save_hid1@ha stw r4,nap_save_hid1@l(r6) -END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX) +END_FTR_SECTION_IFSET(CPU_FTR_750FX) 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: -END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX) +1: +END_FTR_SECTION_IFSET(CPU_FTR_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 @@ -210,7 +210,7 @@ addis r22,r24,(nap_save_hid1-KERNELBASE)@ha lwz r22,nap_save_hid1@l(r22) mtspr SPRN_HID1, r22 -END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX) +END_FTR_SECTION_IFSET(CPU_FTR_750FX) b transfer_to_handler_cont .data Index: arch/ppc/kernel/indirect_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/indirect_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/indirect_pci.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/indirect_pci.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -24,15 +24,30 @@ #define cfg_read(val, addr, type, op) *val = op((type)(addr)) #define cfg_write(val, addr, type, op) op((type *)(addr), (val)) +#ifdef CONFIG_PPC_INDIRECT_PCI_BE +#define PCI_CFG_OUT out_be32 +#else +#define PCI_CFG_OUT out_le32 +#endif + #define INDIRECT_PCI_OP(rw, size, type, op, mask) \ static int \ 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); \ + PCI_CFG_OUT(hose->cfg_addr, \ + (0x80000000 | ((dev->bus->number - hose->bus_offset) << 16) \ + | (dev->devfn << 8) | ((offset & 0xfc) | cfg_type))); \ cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \ return PCIBIOS_SUCCESSFUL; \ } Index: arch/ppc/kernel/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/irq.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/irq.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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; } @@ -429,11 +429,11 @@ int status; struct irqaction *action; int cpu = smp_processor_id(); - irq_desc_t *desc = irq_desc + irq; + irq_desc_t *desc = &irq_desc[irq]; 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; @@ -501,12 +501,25 @@ * The ->end() handler has to deal with interrupts which got * disabled while the handler was running. */ - 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); - } + if (desc->handler) { + if (desc->handler->end) + desc->handler->end(irq); + else if (desc->handler->enable) + desc->handler->enable(irq); + } + +#ifdef CONFIG_DBOX2 + /* + * Interrupts marked as oneshot are level + * triggered. We disable them here for onboard + * hardware which can not be configured to + * generate edge triggered interrupts due to + * lack of documentation. + */ + if ((action) && (action->flags & SA_ONESHOT)) + disable_irq_nosync(irq); +#endif + spin_unlock(&desc->lock); } @@ -561,7 +574,7 @@ return; else once++; - + ppc_md.init_IRQ(); } @@ -700,11 +713,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 +742,7 @@ void __global_cli(void) { unsigned long flags; - + __save_flags(flags); if (flags & (1 << 15)) { int cpu = smp_processor_id(); Index: arch/ppc/kernel/l2cr.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/l2cr.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/l2cr.S 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/l2cr.S 4 Aug 2004 01:26:08 -0000 1.2 @@ -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 - + Index: arch/ppc/kernel/m8260_setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/m8260_setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/m8260_setup.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/m8260_setup.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -40,12 +40,12 @@ #include #include #include -#include +#include #include #include #include -#include "ppc8260_pic.h" +#include "cpm2_pic.h" static int m8260_set_rtc_time(unsigned long time); static unsigned long m8260_get_rtc_time(void); @@ -53,14 +53,14 @@ unsigned char __res[sizeof(bd_t)]; -extern void m8260_cpm_reset(void); +extern void cpm2_reset(void); static void __init m8260_setup_arch(void) { /* Reset the Communication Processor Module. */ - m8260_cpm_reset(); + cpm2_reset(); } static void @@ -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", @@ -172,18 +172,18 @@ void cpm_interrupt_init(void); #if 0 - ppc8260_pic.irq_offset = 0; + cpm2_pic.irq_offset = 0; #endif for ( i = 0 ; i < NR_SIU_INTS ; i++ ) - irq_desc[i].handler = &ppc8260_pic; - + irq_desc[i].handler = &cpm2_pic; + /* Initialize the default interrupt mapping priorities, * in case the boot rom changed something on us. */ - immr->im_intctl.ic_sicr = 0; - immr->im_intctl.ic_siprr = 0x05309770; - immr->im_intctl.ic_scprrh = 0x05309770; - immr->im_intctl.ic_scprrl = 0x05309770; + cpm2_immr->im_intctl.ic_sicr = 0; + cpm2_immr->im_intctl.ic_siprr = 0x05309770; + cpm2_immr->im_intctl.ic_scprrh = 0x05309770; + cpm2_immr->im_intctl.ic_scprrl = 0x05309770; } @@ -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)); } @@ -242,7 +242,7 @@ ppc_md.show_percpuinfo = m8260_show_percpuinfo; ppc_md.irq_cannonicalize = NULL; ppc_md.init_IRQ = m8260_init_IRQ; - ppc_md.get_irq = m8260_get_irq; + ppc_md.get_irq = cpm2_get_irq; ppc_md.init = NULL; ppc_md.restart = m8260_restart; Index: arch/ppc/kernel/m8xx_setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/m8xx_setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/m8xx_setup.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/m8xx_setup.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -58,6 +58,7 @@ extern unsigned long find_available_memory(void); extern void m8xx_cpm_reset(uint); +extern void m8xx_wdt_handler_install(bd_t *bp); void __init m8xx_setup_arch(void) @@ -184,6 +185,13 @@ if (request_irq(DEC_INTERRUPT, timebase_interrupt, 0, "tbint", NULL) != 0) panic("Could not allocate timer IRQ!"); + +#ifdef CONFIG_8xx_WDT + /* Install watchdog timer handler early because it might be + * already enabled by the bootloader + */ + m8xx_wdt_handler_install(binfo); +#endif } /* The RTC on the MPC8xx is an internal register. @@ -279,7 +287,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", Index: arch/ppc/kernel/misc.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/misc.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/misc.S 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/misc.S 4 Aug 2004 01:26:08 -0000 1.2 @@ -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,33 @@ * 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 +#elif defined(CONFIG_44x) + lis r3,0 + sync +1: + tlbwe r3,r3,PPC44x_TLB_PAGEID + addi r3,r3,1 + /* Load high watermark */ + lis r4,tlb_44x_hwater@h + ori r4,r4,tlb_44x_hwater@l + lwz r5,0(r4) + cmpw 0,r3,r5 + ble 1b + isync +#else /* !(CONFIG_40x || CONFIG_44x) */ #if defined(CONFIG_SMP) mfmsr r10 SYNC @@ -375,12 +402,48 @@ 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: +#elif defined(CONFIG_44x) + mfspr r4,SPRN_MMUCR /* Get MMUCR */ + lis r5,PPC44x_MMUCR_STS@h + ori r5,r5,PPC44x_MMUCR_TID@l /* Create mask */ + andc r4,r4,r5 /* Clear out TID/STS bits */ + mfspr r5,SPRN_PID /* Get PID */ + or r4,r4,r5 /* Set TID bits */ + mfmsr r6 /* Get MSR */ + andi. r6,r6,MSR_IS@l /* TS=1? */ + beq 11f /* If not, leave STS=0 */ + oris r4,r4,PPC44x_MMUCR_STS@h /* Set STS=1 */ +11: mtspr SPRN_MMUCR, r4 /* Put MMUCR */ + + tlbsx. r3, 0, r3 + bne 10f + sync + /* There are only 64 TLB entries, so r3 < 64, + * which means bit 22, is clear. Since 22 is + * the V bit in the TLB_PAGEID, loading this + * value will invalidate the TLB entry. + */ + tlbwe r3, r3, PPC44x_TLB_PAGEID + isync +10: +#else /* !(CONFIG_40x || CONFIG_44x) */ #if defined(CONFIG_SMP) mfmsr r10 SYNC @@ -394,6 +457,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 +471,7 @@ mtmsr r10 SYNC #endif +#endif /* CONFIG_40x */ blr /* @@ -418,9 +483,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 +504,7 @@ mfspr r3,HID0 ori r3,r3,HID0_ICFI mtspr HID0,r3 -#endif /* CONFIG_8xx */ +#endif /* CONFIG_8xx/4xx */ isync blr @@ -530,6 +604,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. + * 44x 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 +653,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 @@ -599,29 +694,36 @@ _GLOBAL(copy_page) addi r3,r3,-4 addi r4,r4,-4 + +#ifdef CONFIG_8xx + /* don't use prefetch on 8xx */ + li r0,4096/L1_CACHE_LINE_SIZE + mtctr r0 +1: COPY_16_BYTES + bdnz 1b + blr + +#else /* not 8xx, we can prefetch */ li r5,4 -#ifndef CONFIG_8xx -#if MAX_L1_COPY_PREFETCH > 1 - li r0,MAX_L1_COPY_PREFETCH +#if MAX_COPY_PREFETCH > 1 + li r0,MAX_COPY_PREFETCH li r11,4 mtctr r0 11: dcbt r11,r4 addi r11,r11,L1_CACHE_LINE_SIZE bdnz 11b -#else /* MAX_L1_COPY_PREFETCH == 1 */ +#else /* MAX_COPY_PREFETCH == 1 */ dcbt r5,r4 li r11,L1_CACHE_LINE_SIZE+4 -#endif /* MAX_L1_COPY_PREFETCH */ -#endif /* CONFIG_8xx */ - - li r0,4096/L1_CACHE_LINE_SIZE +#endif /* MAX_COPY_PREFETCH */ + li r0,4096/L1_CACHE_LINE_SIZE - MAX_COPY_PREFETCH + crclr 4*cr0+eq +2: mtctr r0 1: -#ifndef CONFIG_8xx dcbt r11,r4 dcbz r5,r3 -#endif COPY_16_BYTES #if L1_CACHE_LINE_SIZE >= 32 COPY_16_BYTES @@ -637,7 +739,12 @@ #endif #endif bdnz 1b - blr + beqlr + crnot 4*cr0+eq,4*cr0+eq + li r0,MAX_COPY_PREFETCH + li r11,4 + b 2b +#endif /* CONFIG_8xx */ /* * Atomic [test&set] exchange @@ -709,7 +816,7 @@ stb r5,0(r3) eieio bdnz 00b - blr + blr _GLOBAL(_insw) cmpwi 0,r5,0 @@ -729,9 +836,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 +860,7 @@ stwbrx r5,0,r3 eieio bdnz 00b - blr + blr _GLOBAL(ide_insw) _GLOBAL(_insw_ns) @@ -777,7 +884,7 @@ sth r5,0(r3) eieio bdnz 00b - blr + blr _GLOBAL(_insl_ns) cmpwi 0,r5,0 @@ -799,11 +906,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 +918,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 +936,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 +947,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 +966,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 +974,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 +1026,7 @@ /* * This routine is just here to keep GCC happy - sigh... - */ + */ _GLOBAL(__main) blr @@ -949,7 +1056,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 +1234,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 +1252,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 @@ -1185,6 +1292,24 @@ .long sys_ni_syscall /* reserved for sys_io_getevents */ .long sys_ni_syscall /* 230 reserved for sys_io_submit */ .long sys_ni_syscall /* reserved for sys_io_cancel */ + .long sys_ni_syscall /* reserved for sys_set_tid_address */ + .long sys_ni_syscall /* reserved for sys_fadvise64 */ + .long sys_ni_syscall /* reserved for sys_exit_group */ + .long sys_ni_syscall /* 235 reserved for sys_lookup_dcookie */ + .long sys_ni_syscall /* reserved for sys_epoll_create */ + .long sys_ni_syscall /* reserved for sys_epoll_ctl */ + .long sys_ni_syscall /* reserved for sys_epoll_wait */ + .long sys_ni_syscall /* reserved for sys_remap_file_pages */ + .long sys_ni_syscall /* 240 reserved for sys_timer_create */ + .long sys_ni_syscall /* reserved for sys_timer_settime */ + .long sys_ni_syscall /* reserved for sys_timer_gettime */ + .long sys_ni_syscall /* reserved for sys_timer_getoverrun */ + .long sys_ni_syscall /* reserved for sys_timer_delete */ + .long sys_ni_syscall /* 245 reserved for sys_clock_settime */ + .long sys_ni_syscall /* reserved for sys_clock_gettime */ + .long sys_ni_syscall /* reserved for sys_clock_getres */ + .long sys_ni_syscall /* reserved for sys_clock_nanosleep */ + .long sys_swapcontext .rept NR_syscalls-(.-sys_call_table)/4 .long sys_ni_syscall Index: arch/ppc/kernel/mk_defs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/mk_defs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/mk_defs.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/mk_defs.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -56,7 +56,11 @@ DEFINE(THREAD_VR0, offsetof(struct thread_struct, vr[0])); DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave)); DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr)); + DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr)); #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); Index: arch/ppc/kernel/mpc10x_common.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/mpc10x_common.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/mpc10x_common.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/mpc10x_common.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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); } Index: arch/ppc/kernel/open_pic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/open_pic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/open_pic.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/open_pic.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -69,7 +69,6 @@ * These functions are not used but the code is kept here * for completeness and future reference. */ -static void openpic_reset(void); #ifdef notused static void openpic_enable_8259_pass_through(void); static u_int openpic_get_priority(void); @@ -167,13 +166,21 @@ { u_int val; +#ifdef CONFIG_PPC_OPENPIC_BE + val = in_be32(addr); +#else val = in_le32(addr); +#endif return val; } static inline void openpic_write(volatile u_int *addr, u_int val) { +#ifdef CONFIG_PPC_OPENPIC_BE + out_be32(addr, val); +#else out_le32(addr, val); +#endif } static inline u_int openpic_readfield(volatile u_int *addr, u_int mask) @@ -212,7 +219,7 @@ u_int openpic_read_IPI(volatile u_int* addr) { u_int val = 0; -#ifdef CONFIG_POWER3 +#if defined(CONFIG_PPC_OPENPIC_BE) || defined(CONFIG_POWER3) val = in_be32(addr); #else val = in_le32(addr); @@ -540,7 +547,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 +564,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 +705,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 +719,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 +882,7 @@ { int i; unsigned long flags; - + spin_lock_irqsave(&openpic_setup_lock, flags); for (i=0; idma_mask != 0xffffffff) + if (hwdev == NULL || hwdev->dma_mask < 0xffffffff) gfp |= GFP_DMA; + +#ifdef CONFIG_NOT_COHERENT_CACHE + ret = consistent_alloc(gfp, size, dma_handle); +#else ret = (void *)__get_free_pages(gfp, get_order(size)); +#endif if (ret != NULL) { memset(ret, 0, size); +#ifndef CONFIG_NOT_COHERENT_CACHE *dma_handle = virt_to_bus(ret); +#endif } return ret; } @@ -34,5 +41,9 @@ void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) { +#ifdef CONFIG_NOT_COHERENT_CACHE + consistent_free(vaddr); +#else free_pages((unsigned long)vaddr, get_order(size)); +#endif } Index: arch/ppc/kernel/pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/pci.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/pci.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -67,7 +67,7 @@ { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources }, #ifdef CONFIG_ALL_PPC /* We should add per-machine fixup support in xxx_setup.c or xxx_pci.c */ - { PCI_FIXUP_FINAL, PCI_VENDOR_ID_TI, PCI_ANY_ID, pcibios_fixup_cardbus }, + { PCI_FIXUP_FINAL, PCI_VENDOR_ID_TI, PCI_ANY_ID, pcibios_fixup_cardbus }, #endif /* CONFIG_ALL_PPC */ { 0 } }; @@ -115,7 +115,7 @@ int reg; struct pci_controller* hose = dev->sysdata; 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; Index: arch/ppc/kernel/pci_auto.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/pci_auto.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/pci_auto.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/pci_auto.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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, Index: arch/ppc/kernel/ppc-stub.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/ppc-stub.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/ppc-stub.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/ppc-stub.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -135,7 +135,7 @@ /* typedef void (*trapfunc_t)(void); */ static void kgdb_fault_handler(struct pt_regs *regs); -static void handle_exception (struct pt_regs *regs); +static int handle_exception (struct pt_regs *regs); #if 0 /* Install an exception handler for kgdb */ @@ -387,14 +387,12 @@ int kgdb_bpt(struct pt_regs *regs) { - handle_exception(regs); - return 1; + return handle_exception(regs); } int kgdb_sstep(struct pt_regs *regs) { - handle_exception(regs); - return 1; + return handle_exception(regs); } void kgdb(struct pt_regs *regs) @@ -404,16 +402,14 @@ int kgdb_iabr_match(struct pt_regs *regs) { - printk("kgdb doesn't support iabr, what?!?\n"); - handle_exception(regs); - return 1; + printk(KERN_ERR "kgdb doesn't support iabr, what?!?\n"); + return handle_exception(regs); } int kgdb_dabr_match(struct pt_regs *regs) { - printk("kgdb doesn't support dabr, what?!?\n"); - handle_exception(regs); - return 1; + printk(KERN_ERR "kgdb doesn't support dabr, what?!?\n"); + return handle_exception(regs); } /* Convert the SPARC hardware trap type code to a unix signal number. */ @@ -459,7 +455,7 @@ /* * This function does all command processing for interfacing to gdb. */ -static void +static int handle_exception (struct pt_regs *regs) { int sigval; @@ -468,14 +464,19 @@ char *ptr; unsigned int msr; + /* We don't handle user-mode breakpoints. */ + if (user_mode(regs)) + return 0; + if (debugger_fault_handler) { debugger_fault_handler(regs); panic("kgdb longjump failed!\n"); } if (kgdb_active) { - printk("interrupt while in kgdb, returning\n"); - return; + printk(KERN_ERR "interrupt while in kgdb, returning\n"); + return 0; } + kgdb_active = 1; kgdb_started = 1; @@ -677,14 +678,14 @@ kgdb_interruptible(1); unlock_kernel(); kgdb_active = 0; - return; + return 1; case 's': kgdb_flush_cache_all(); regs->msr |= MSR_SE; unlock_kernel(); kgdb_active = 0; - return; + return 1; case 'r': /* Reset (if user process..exit ???)*/ panic("kgdb reset."); @@ -716,10 +717,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 +730,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'; Index: arch/ppc/kernel/ppc4xx_pic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/ppc4xx_pic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/ppc4xx_pic.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/ppc4xx_pic.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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 + } Index: arch/ppc/kernel/ppc8260_pic.c =================================================================== RCS file: arch/ppc/kernel/ppc8260_pic.c diff -N arch/ppc/kernel/ppc8260_pic.c --- arch/ppc/kernel/ppc8260_pic.c 22 Jul 2004 19:49:02 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,128 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "ppc8260_pic.h" - -/* The 8260 internal interrupt controller. It is usually - * the only interrupt controller. - * There are two 32-bit registers (high/low) for up to 64 - * possible interrupts. - * - * Now, the fun starts.....Interrupt Numbers DO NOT MAP - * in a simple arithmetic fashion to mask or pending registers. - * That is, interrupt 4 does not map to bit position 4. - * We create two tables, indexed by vector number, to indicate - * which register to use and which bit in the register to use. - */ -static u_char irq_to_siureg[] = { - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static u_char irq_to_siubit[] = { - 31, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, - 29, 30, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 31, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 15, 14, 13, 12, 11, 10, 9, 8, - 7, 6, 5, 4, 3, 2, 1, 0 -}; - -static void m8260_mask_irq(unsigned int irq_nr) -{ - int bit, word; - volatile uint *simr; - - bit = irq_to_siubit[irq_nr]; - word = irq_to_siureg[irq_nr]; - - simr = &(immr->im_intctl.ic_simrh); - ppc_cached_irq_mask[word] &= ~(1 << (31 - bit)); - simr[word] = ppc_cached_irq_mask[word]; -} - -static void m8260_unmask_irq(unsigned int irq_nr) -{ - int bit, word; - volatile uint *simr; - - bit = irq_to_siubit[irq_nr]; - word = irq_to_siureg[irq_nr]; - - simr = &(immr->im_intctl.ic_simrh); - ppc_cached_irq_mask[word] |= (1 << (31 - bit)); - simr[word] = ppc_cached_irq_mask[word]; -} - -static void m8260_mask_and_ack(unsigned int irq_nr) -{ - int bit, word; - volatile uint *simr, *sipnr; - - bit = irq_to_siubit[irq_nr]; - word = irq_to_siureg[irq_nr]; - - simr = &(immr->im_intctl.ic_simrh); - sipnr = &(immr->im_intctl.ic_sipnrh); - ppc_cached_irq_mask[word] &= ~(1 << (31 - bit)); - simr[word] = ppc_cached_irq_mask[word]; - sipnr[word] = 1 << (31 - bit); -} - -static void m8260_end_irq(unsigned int irq_nr) -{ - int bit, word; - volatile uint *simr; - - if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { - - bit = irq_to_siubit[irq_nr]; - word = irq_to_siureg[irq_nr]; - - simr = &(immr->im_intctl.ic_simrh); - ppc_cached_irq_mask[word] |= (1 << (31 - bit)); - simr[word] = ppc_cached_irq_mask[word]; - } -} - -struct hw_interrupt_type ppc8260_pic = { - " 8260 SIU ", - NULL, - NULL, - m8260_unmask_irq, - m8260_mask_irq, - m8260_mask_and_ack, - m8260_end_irq, - 0 -}; - -/* Return an interrupt vector or -1 if no interrupt is pending. */ -int -m8260_get_irq(struct pt_regs *regs) -{ - int irq; - unsigned long bits; - - /* For MPC8260, read the SIVEC register and shift the bits down - * to get the irq number. */ - bits = immr->im_intctl.ic_sivec; - irq = bits >> 26; - - if (irq == 0) /* 0 --> no irq is pending */ - irq = -1; - - return irq; -} - Index: arch/ppc/kernel/ppc8260_pic.h =================================================================== RCS file: arch/ppc/kernel/ppc8260_pic.h diff -N arch/ppc/kernel/ppc8260_pic.h --- arch/ppc/kernel/ppc8260_pic.h 22 Jul 2004 19:49:02 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,13 +0,0 @@ -#ifndef _PPC_KERNEL_PPC8260_H -#define _PPC_KERNEL_PPC8260_H - -#include - -extern struct hw_interrupt_type ppc8260_pic; - -void m8260_pic_init(void); -void m8260_do_IRQ(struct pt_regs *regs, - int cpu); -int m8260_get_irq(struct pt_regs *regs); - -#endif /* _PPC_KERNEL_PPC8260_H */ Index: arch/ppc/kernel/ppc8xx_pic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/ppc8xx_pic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/ppc8xx_pic.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/ppc8xx_pic.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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) Index: arch/ppc/kernel/ppc_htab.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/ppc_htab.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/ppc_htab.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/ppc_htab.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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 @@ -113,7 +113,7 @@ { unsigned long mmcr0 = 0, pmc1 = 0, pmc2 = 0; int n = 0; -#ifdef CONFIG_PPC_STD_MMU +#if defined(CONFIG_PPC_STD_MMU) && !defined(CONFIG_PPC64BRIDGE) int valid; unsigned int kptes = 0, uptes = 0, zombie_ptes = 0; PTE *ptr; @@ -150,6 +150,7 @@ goto return_string; } +#ifndef CONFIG_PPC64BRIDGE for ( ptr = Hash ; ptr < Hash_end ; ptr++) { unsigned int ctx, mctx, vsid; @@ -177,25 +178,30 @@ if (!valid) zombie_ptes++; } - +#endif + n += sprintf( buffer + n, "PTE Hash Table Information\n" "Size\t\t: %luKb\n" "Buckets\t\t: %lu\n" "Address\t\t: %08lx\n" "Entries\t\t: %lu\n" +#ifndef CONFIG_PPC64BRIDGE "User ptes\t: %u\n" "Kernel ptes\t: %u\n" "Zombies\t\t: %u\n" - "Percent full\t: %lu%%\n", - (unsigned long)(Hash_size>>10), + "Percent full\t: %lu%%\n" +#endif + , (unsigned long)(Hash_size>>10), (Hash_size/(sizeof(PTE)*8)), (unsigned long)Hash, - Hash_size/sizeof(PTE), - uptes, + Hash_size/sizeof(PTE) +#ifndef CONFIG_PPC64BRIDGE + , uptes, kptes, zombie_ptes, ((kptes+uptes)*100) / (Hash_size/sizeof(PTE)) +#endif ); n += sprintf( buffer + n, @@ -208,7 +214,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 +250,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 +301,7 @@ "i" (PMC1), "r" (0), "i"(PMC2) ); } } - + /* PMC1 values */ if ( !strncmp( buffer, "dtlb", 4) ) { @@ -310,7 +316,7 @@ :: "r" (tmp), "i" (MMCR0), "i" (MMCR0_PMC1_DTLB), "i" (PMC1), "r" (0) ); } - } + } if ( !strncmp( buffer, "ic miss", 7) ) { @@ -325,7 +331,7 @@ :: "r" (tmp), "i" (MMCR0), "i" (MMCR0_PMC1_ICACHEMISS), "i" (PMC1), "r" (0)); } - } + } /* PMC2 values */ if ( !strncmp( buffer, "load miss time", 14) ) @@ -343,7 +349,7 @@ "i" (PMC2), "r" (0) ); } } - + if ( !strncmp( buffer, "itlb", 4) ) { if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { @@ -374,21 +380,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 +402,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 +422,7 @@ flush_tlb_all(); reset_SDR1(); -#endif +#endif return count; #else /* CONFIG_PPC_STD_MMU */ return 0; @@ -441,18 +447,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 +470,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; @@ -503,29 +509,70 @@ left -= len; _set_L2CR(val); } else { + int is750fx = cur_cpu_spec[0]->cpu_features & CPU_FTR_750FX; p = buf; if (!first) *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" :""); - + if (!(val>>30&1)) + p += sprintf(p, "no "); + if (is750fx) + p += sprintf(p, "ECC checkstop"); + else + p += sprintf(p, "parity"); + + /* 75x & 74x0 have different L2CR than 745x */ + if (!(cur_cpu_spec[0]->cpu_features & + CPU_FTR_SPEC7450)) { + if (!is750fx) { + 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" : ""); + if (!is750fx) { + 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" : ""); + if (!is750fx) { + 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 { + if ((val>>11)&1) + p += sprintf(p, ", lock way 0"); + if ((val>>10)&1) + p += sprintf(p, ", lock way 1"); + if ((val>>9)&1) + p += sprintf(p, ", Snoop Hit in Locked Line Error Enabled"); + } + } 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 +606,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; +} Index: arch/ppc/kernel/ppc_ksyms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/ppc_ksyms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/ppc_ksyms.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/ppc_ksyms.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -159,11 +159,16 @@ EXPORT_SYMBOL(_outsw_ns); EXPORT_SYMBOL(_insl_ns); EXPORT_SYMBOL(_outsl_ns); +EXPORT_SYMBOL(iopa); +EXPORT_SYMBOL(mm_ptov); +EXPORT_SYMBOL(vmalloc_start); +EXPORT_SYMBOL(ioremap_bot); EXPORT_SYMBOL(ioremap); +#ifdef CONFIG_PTE_64BIT +EXPORT_SYMBOL(ioremap64); +#endif EXPORT_SYMBOL(__ioremap); EXPORT_SYMBOL(iounmap); -EXPORT_SYMBOL(iopa); -EXPORT_SYMBOL(mm_ptov); #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) \ || defined(CONFIG_USB_STORAGE) || defined(CONFIG_USB_STORAGE_MODULE) @@ -176,8 +181,23 @@ EXPORT_SYMBOL_NOVERS(pci_dram_offset); EXPORT_SYMBOL(pci_alloc_consistent); EXPORT_SYMBOL(pci_free_consistent); +EXPORT_SYMBOL(pci_bus_io_base); +EXPORT_SYMBOL(pci_bus_io_base_phys); +EXPORT_SYMBOL(pci_bus_mem_base_phys); +EXPORT_SYMBOL(pci_bus_to_hose); +EXPORT_SYMBOL(pci_resource_to_bus); +EXPORT_SYMBOL(pci_phys_to_bus); +EXPORT_SYMBOL(pci_bus_to_phys); #endif /* CONFIG_PCI */ +#ifdef CONFIG_NOT_COHERENT_CACHE +EXPORT_SYMBOL(consistent_alloc); +EXPORT_SYMBOL(consistent_free); +EXPORT_SYMBOL(consistent_sync); +EXPORT_SYMBOL(consistent_sync_page); +EXPORT_SYMBOL(flush_dcache_all); +#endif + EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(kernel_thread); @@ -253,15 +273,8 @@ EXPORT_SYMBOL(get_property); EXPORT_SYMBOL(request_OF_resource); EXPORT_SYMBOL(release_OF_resource); -EXPORT_SYMBOL(pci_bus_io_base); -EXPORT_SYMBOL(pci_bus_io_base_phys); -EXPORT_SYMBOL(pci_bus_mem_base_phys); EXPORT_SYMBOL(pci_device_to_OF_node); EXPORT_SYMBOL(pci_device_from_OF_node); -EXPORT_SYMBOL(pci_bus_to_hose); -EXPORT_SYMBOL(pci_resource_to_bus); -EXPORT_SYMBOL(pci_phys_to_bus); -EXPORT_SYMBOL(pci_bus_to_phys); EXPORT_SYMBOL(pmac_newworld); EXPORT_SYMBOL(nvram_read_byte); EXPORT_SYMBOL(nvram_write_byte); @@ -291,7 +304,7 @@ EXPORT_SYMBOL(abs); -#ifdef CONFIG_VGA_CONSOLE +#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_FB) EXPORT_SYMBOL(screen_info); #endif @@ -338,11 +351,20 @@ EXPORT_SYMBOL(debugger_fault_handler); #endif -#ifdef CONFIG_8xx +#if defined(CONFIG_8xx) || defined(CONFIG_4xx) EXPORT_SYMBOL(__res); +#endif +#ifdef CONFIG_8xx EXPORT_SYMBOL(cpm_install_handler); EXPORT_SYMBOL(cpm_free_handler); EXPORT_SYMBOL(m8xx_cpm_hostalloc); +EXPORT_SYMBOL(m8xx_cpm_dpalloc); +#ifdef CONFIG_8xx_WDT +extern int m8xx_wdt_get_timeout(void); +extern void m8xx_wdt_reset(void); +EXPORT_SYMBOL(m8xx_wdt_get_timeout); +EXPORT_SYMBOL(m8xx_wdt_reset); +#endif #endif /* CONFIG_8xx */ /* Those should really be inline */ @@ -353,6 +375,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 */ @@ -366,4 +392,3 @@ extern unsigned long agp_special_page; EXPORT_SYMBOL_NOVERS(agp_special_page); #endif /* defined(CONFIG_ALL_PPC) */ - Index: arch/ppc/kernel/prep_nvram.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/prep_nvram.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/prep_nvram.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/prep_nvram.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -25,7 +25,7 @@ outb(addr>>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 Index: arch/ppc/kernel/process.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/process.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/process.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/process.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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++) { @@ -404,6 +417,7 @@ memset(current->thread.vr, 0, sizeof(current->thread.vr)); memset(¤t->thread.vscr, 0, sizeof(current->thread.vscr)); current->thread.vrsave = 0; + current->thread.used_vr = 0; #endif /* CONFIG_ALTIVEC */ } @@ -475,7 +489,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 +587,7 @@ return; } -#if 0 +#if 0 if ( have_of ) { prom_print(s); @@ -600,7 +614,7 @@ y = 0; } } else { - vidmem [ ( x + cols * y ) * 2 ] = c; + vidmem [ ( x + cols * y ) * 2 ] = c; if ( ++x >= cols ) { x = 0; if ( ++y >= lines ) { Index: arch/ppc/kernel/prom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/prom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/prom.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/prom.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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; Index: arch/ppc/kernel/prom_init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/prom_init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/prom_init.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/prom_init.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -638,6 +638,72 @@ } } +#ifdef CONFIG_POWER4 +/* + * Set up a hash table with a set of entries in it to map the + * first 64MB of RAM. This is used on 64-bit machines since + * some of them don't have BATs. + * We assume the PTE will fit in the primary PTEG. + */ + +static inline void make_pte(unsigned long htab, unsigned int hsize, + unsigned int va, unsigned int pa, int mode) +{ + unsigned int *pteg; + unsigned int hash, i, vsid; + + vsid = ((va >> 28) * 0x111) << 12; + hash = ((va ^ vsid) >> 5) & 0x7fff80; + pteg = (unsigned int *)(htab + (hash & (hsize - 1))); + for (i = 0; i < 8; ++i, pteg += 4) { + if ((pteg[1] & 1) == 0) { + pteg[1] = vsid | ((va >> 16) & 0xf80) | 1; + pteg[3] = pa | mode; + break; + } + } +} + +extern unsigned long _SDR1; +extern PTE *Hash; +extern unsigned long Hash_size; + +static void __init +prom_alloc_htab(void) +{ + unsigned int hsize; + unsigned long htab; + unsigned int addr; + + /* + * Because of OF bugs we can't use the "claim" client + * interface to allocate memory for the hash table. + * This code is only used on 64-bit PPCs, and the only + * 64-bit PPCs at the moment are RS/6000s, and their + * OF is based at 0xc00000 (the 12M point), so we just + * arbitrarily use the 0x800000 - 0xc00000 region for the + * hash table. + * -- paulus. + */ + hsize = 4 << 20; /* POWER4 has no BATs */ + htab = (8 << 20); + call_prom("claim", 3, 1, htab, hsize, 0); + Hash = (void *)(htab + KERNELBASE); + Hash_size = hsize; + _SDR1 = htab + __ilog2(hsize) - 18; + + /* + * Put in PTEs for the first 64MB of RAM + */ + cacheable_memzero((void *)htab, hsize); + for (addr = 0; addr < 0x4000000; addr += 0x1000) + make_pte(htab, hsize, addr + KERNELBASE, addr, + _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX); + make_pte(htab, hsize, 0x80013000, 0x80013000, + _PAGE_ACCESSED | _PAGE_NO_CACHE | _PAGE_GUARDED | PP_RWXX); +} +#endif /* CONFIG_POWER4 */ + static void __init prom_instantiate_rtas(void) { @@ -705,8 +771,7 @@ /* First get a handle for the stdout device */ prom = pp; - prom_chosen = call_prom("finddevice", 1, 1, - "/chosen"); + prom_chosen = call_prom("finddevice", 1, 1, "/chosen"); if (prom_chosen == (void *)-1) prom_exit(); if ((int) call_prom("getprop", 4, 1, prom_chosen, @@ -739,6 +804,14 @@ prom_instantiate_rtas(); +#ifdef CONFIG_POWER4 + /* + * Find out how much memory we have and allocate a + * suitably-sized hash table. + */ + prom_alloc_htab(); +#endif + mem = check_display(mem); prom_print("copying OF device tree..."); Index: arch/ppc/kernel/ptrace.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/ptrace.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/ptrace.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/ptrace.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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: { Index: arch/ppc/kernel/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/setup.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/setup.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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(); @@ -152,12 +152,12 @@ return 0; pvr = cpu_data[i].pvr; lpj = cpu_data[i].loops_per_jiffy; - seq_printf(m, "processor\t: %lu\n", i); #else pvr = mfspr(PVR); lpj = loops_per_jiffy; #endif + seq_printf(m, "processor\t: %u\n", i); seq_printf(m, "cpu\t\t: "); if (cur_cpu_spec[i]->pvr_mask) @@ -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", @@ -258,7 +258,7 @@ unsigned long early_init(int r3, int r4, int r5) { - extern char __bss_start, _end; + extern char __bss_start[], _end[]; unsigned long phys; unsigned long offset = reloc_offset(); @@ -267,7 +267,7 @@ /* First zero the BSS -- use memset, some arches don't have * caches on yet */ - memset_io(PTRRELOC(&__bss_start), 0, &_end - &__bss_start); + memset_io(PTRRELOC(&__bss_start), 0, _end - __bss_start); /* * Identify the CPU type and fix up code sections @@ -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(); } @@ -566,12 +566,10 @@ #if defined(CONFIG_KGDB) kgdb_map_scc(); set_debug_traps(); - if (strstr(cmd_line, "nokgdb")) - printk("kgdb default breakpoint deactivated on command line\n"); - else { + if (strstr(cmd_line, "gdb")) { if (ppc_md.progress) ppc_md.progress("setup_arch: kgdb breakpoint", 0x4000); - printk("kgdb default breakpoint activated\n"); + printk("kgdb breakpoint activated\n"); breakpoint(); } #endif @@ -596,7 +594,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; @@ -605,6 +603,12 @@ do_init_bootmem(); if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); +#ifdef CONFIG_PPC_OCP + /* Initialize OCP device list */ + ocp_early_init(); + if ( ppc_md.progress ) ppc_md.progress("setup_arch: ocp_early_init", 0x3eab); +#endif + ppc_md.setup_arch(); if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); Index: arch/ppc/kernel/signal.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/signal.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/signal.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/signal.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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,17 +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, - * you should be able to step out of a signal handler to see what - * instruction executes next after the signal handler completes. - * Alternately, if you stepped into a signal handler, you should be - * able to continue 'til the next breakpoint from within the signal - * handler, even if the handler returns. - */ -#define MSR_USERCHANGE (MSR_FE0 | MSR_FE1) +extern void syscall_direct_return(struct pt_regs *regs); int do_signal(sigset_t *oldset, struct pt_regs *regs); @@ -117,7 +107,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]; @@ -157,13 +147,13 @@ int -sys_sigaltstack(const stack_t *uss, stack_t *uoss) +sys_sigaltstack(const stack_t *uss, stack_t *uoss, int r5, int r6, + int r7, int r8, struct pt_regs *regs) { - struct pt_regs *regs = (struct pt_regs *) &uss; return do_sigaltstack(uss, uoss, regs->gpr[1]); } -int +int sys_sigaction(int sig, const struct old_sigaction *act, struct old_sigaction *oact) { @@ -199,378 +189,403 @@ * When we have signals to deliver, we set up on the * user stack, going down from the original stack pointer: * a sigregs struct - * one or more sigcontext structs with + * a sigcontext struct * a gap of __SIGNAL_FRAMESIZE bytes * * Each of these things must be a multiple of 16 bytes in size. * */ struct sigregs { - elf_gregset_t gp_regs; - double fp_regs[ELF_NFPREG]; - unsigned long tramp[2]; + struct mcontext mctx; /* all the register values */ /* Programs using the rs6000/xcoff abi can save up to 19 gp regs and 18 fp regs below sp before decrementing it. */ int abigap[56]; }; -struct rt_sigframe -{ - unsigned long _unused[2]; - struct siginfo *pinfo; - void *puc; - struct siginfo info; - struct ucontext uc; -}; - +/* We use the mc_pad field for the signal return trampoline. */ +#define tramp mc_pad /* * When we have rt signals to deliver, we set up on the * user stack, going down from the original stack pointer: - * a sigregs struct - * one rt_sigframe struct (siginfo + ucontext) - * a gap of __SIGNAL_FRAMESIZE bytes + * one rt_sigframe struct (siginfo + ucontext + ABI gap) + * a gap of __SIGNAL_FRAMESIZE+16 bytes + * (the +16 is to get the siginfo and ucontext in the same + * positions as in older kernels). * * Each of these things must be a multiple of 16 bytes in size. * */ -int sys_rt_sigreturn(struct pt_regs *regs) +struct rt_sigframe { - struct rt_sigframe *rt_sf; - struct sigcontext_struct sigctx; - struct sigregs *sr; - int ret; - elf_gregset_t saved_regs; /* an array of ELF_NGREG unsigned longs */ - sigset_t set; - stack_t st; - unsigned long prevsp; + struct siginfo info; + struct ucontext uc; + /* Programs using the rs6000/xcoff abi can save up to 19 gp regs + and 18 fp regs below sp before decrementing it. */ + int abigap[56]; +}; - rt_sf = (struct rt_sigframe *)(regs->gpr[1] + __SIGNAL_FRAMESIZE); - if (copy_from_user(&sigctx, &rt_sf->uc.uc_mcontext, sizeof(sigctx)) - || copy_from_user(&set, &rt_sf->uc.uc_sigmask, sizeof(set)) - || copy_from_user(&st, &rt_sf->uc.uc_stack, sizeof(st))) - goto badframe; - sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); - current->blocked = set; - recalc_sigpending(current); - spin_unlock_irq(¤t->sigmask_lock); +/* + * Save the current user registers on the user stack. + * We only save the altivec registers if the process has used + * altivec instructions at some point. + */ +static int +save_user_regs(struct pt_regs *regs, struct mcontext *frame, int sigret) +{ + /* save general and floating-point registers */ if (regs->msr & MSR_FP) giveup_fpu(current); + if (__copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE) + || __copy_to_user(&frame->mc_fregs, current->thread.fpr, + ELF_NFPREG * sizeof(double))) + return 1; + + current->thread.fpscr = 0; /* turn off all fp exceptions */ - 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) - * see handle_signal() - */ - sr = (struct sigregs *) sigctx.regs; - if (copy_from_user(saved_regs, &sr->gp_regs, - sizeof(sr->gp_regs))) - goto badframe; - saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE) - | (saved_regs[PT_MSR] & MSR_USERCHANGE); - memcpy(regs, saved_regs, GP_REGS_SIZE); - if (copy_from_user(current->thread.fpr, &sr->fp_regs, - sizeof(sr->fp_regs))) - goto badframe; - /* This function sets back the stack flags into - the current task structure. */ - sys_sigaltstack(&st, NULL); - - ret = regs->result; - } else { - /* More signals to go */ - /* Set up registers for next signal handler */ - regs->gpr[1] = (unsigned long)rt_sf - __SIGNAL_FRAMESIZE; - if (copy_from_user(&sigctx, &rt_sf->uc.uc_mcontext, sizeof(sigctx))) - goto badframe; - sr = (struct sigregs *) sigctx.regs; - regs->gpr[3] = ret = sigctx.signal; - /* Get the siginfo */ - get_user(regs->gpr[4], (unsigned long *)&rt_sf->pinfo); - /* Get the ucontext */ - get_user(regs->gpr[5], (unsigned long *)&rt_sf->puc); - regs->gpr[6] = (unsigned long) rt_sf; - - regs->link = (unsigned long) &sr->tramp; - regs->nip = sigctx.handler; - if (get_user(prevsp, &sr->gp_regs[PT_R1]) - || put_user(prevsp, (unsigned long *) regs->gpr[1])) - goto badframe; - current->thread.fpscr = 0; +#ifdef CONFIG_ALTIVEC + /* save altivec registers */ + if (current->thread.used_vr) { + if (regs->msr & MSR_VEC) + giveup_altivec(current); + if (__copy_to_user(&frame->mc_vregs, current->thread.vr, + ELF_NVRREG * sizeof(vector128))) + return 1; + /* set MSR_VEC in the saved MSR value to indicate that + frame->mc_vregs contains valid data */ + if (__put_user(regs->msr | MSR_VEC, &frame->mc_gregs[PT_MSR])) + return 1; + } + /* else assert((regs->msr & MSR_VEC) == 0) */ + + /* We always copy to/from vrsave, it's 0 if we don't have or don't + * use altivec. Since VSCR only contains 32 bits saved in the least + * significant bits of a vector, we "cheat" and stuff VRSAVE in the + * most significant bits of that same vector. --BenH + */ + if (__put_user(current->thread.vrsave, (u32 *)&frame->mc_vregs[32])) + return 1; +#endif /* CONFIG_ALTIVEC */ + + if (sigret) { + /* Set up the sigreturn trampoline: li r0,sigret; sc */ + if (__put_user(0x38000000UL + sigret, &frame->tramp[0]) + || __put_user(0x44000002UL, &frame->tramp[1])) + return 1; + flush_icache_range((unsigned long) &frame->tramp[0], + (unsigned long) &frame->tramp[2]); } - return ret; -badframe: - do_exit(SIGSEGV); + return 0; } +/* + * Restore the current user register values from the user stack, + * (except for MSR). + */ +static int +restore_user_regs(struct pt_regs *regs, struct mcontext *sr) +{ +#ifdef CONFIG_ALTIVEC + unsigned long msr; +#endif + + /* copy up to but not including MSR */ + if (__copy_from_user(regs, &sr->mc_gregs, PT_MSR * sizeof(elf_greg_t))) + return 1; + /* copy from orig_r3 (the word after the MSR) up to the end */ + if (__copy_from_user(®s->orig_gpr3, &sr->mc_gregs[PT_ORIG_R3], + GP_REGS_SIZE - PT_ORIG_R3 * sizeof(elf_greg_t))) + return 1; + + /* force the process to reload the FP registers from + current->thread when it next does FP instructions */ + regs->msr &= ~MSR_FP; + if (__copy_from_user(current->thread.fpr, &sr->mc_fregs, + sizeof(sr->mc_fregs))) + return 1; + +#ifdef CONFIG_ALTIVEC + /* force the process to reload the altivec registers from + current->thread when it next does altivec instructions */ + regs->msr &= ~MSR_VEC; + if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_VEC) != 0) { + /* restore altivec registers from the stack */ + if (__copy_from_user(current->thread.vr, &sr->mc_vregs, + sizeof(sr->mc_vregs))) + return 1; + } else if (current->thread.used_vr) + memset(¤t->thread.vr, 0, ELF_NVRREG * sizeof(vector128)); + + /* Always get VRSAVE back */ + if (__get_user(current->thread.vrsave, (u32 *)&sr->mc_vregs[32])) + return 1; +#endif /* CONFIG_ALTIVEC */ + + return 0; +} + +/* + * Restore the user process's signal mask + */ +static void +restore_sigmask(sigset_t *set) +{ + sigdelsetmask(set, ~_BLOCKABLE); + spin_lock_irq(¤t->sigmask_lock); + current->blocked = *set; + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); +} + +/* + * Set up a signal frame for a "real-time" signal handler + * (one which gets siginfo). + */ static void -setup_rt_frame(struct pt_regs *regs, struct sigregs *frame, - signed long newsp) +handle_rt_signal(unsigned long sig, struct k_sigaction *ka, + siginfo_t *info, sigset_t *oldset, struct pt_regs * regs, + unsigned long newsp) { - struct rt_sigframe *rt_sf = (struct rt_sigframe *) newsp; + struct rt_sigframe *rt_sf; + struct mcontext *frame; + unsigned long origsp = newsp; + + /* Set up Signal Frame */ + /* Put a Real Time Context onto stack */ + newsp -= sizeof(*rt_sf); + rt_sf = (struct rt_sigframe *) newsp; + + /* create a stack frame for the caller of the handler */ + newsp -= __SIGNAL_FRAMESIZE + 16; - /* Set up preamble frame */ - if (verify_area(VERIFY_WRITE, frame, sizeof(*frame))) + if (verify_area(VERIFY_WRITE, (void *) newsp, origsp - newsp)) goto badframe; - if (regs->msr & MSR_FP) - giveup_fpu(current); - if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE) - || __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 - for sys_rt_sigreturn(). - */ - || __put_user(0x38006666UL, &frame->tramp[0]) /* li r0,0x6666 */ - || __put_user(0x44000002UL, &frame->tramp[1])) /* sc */ + + /* Put the siginfo & fill in most of the ucontext */ + if (__copy_to_user(&rt_sf->info, info, sizeof(*info)) + || __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]), + &rt_sf->uc.uc_stack.ss_flags) + || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size) + || __put_user(&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs) + || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset))) goto badframe; - flush_icache_range((unsigned long) &frame->tramp[0], - (unsigned long) &frame->tramp[2]); - current->thread.fpscr = 0; /* turn off all fp exceptions */ - /* Retrieve rt_sigframe from stack and - set up registers for signal handler - */ - newsp -= __SIGNAL_FRAMESIZE; - if (put_user(regs->gpr[1], (unsigned long *)newsp) - || get_user(regs->nip, &rt_sf->uc.uc_mcontext.handler) - || get_user(regs->gpr[3], &rt_sf->uc.uc_mcontext.signal) - || get_user(regs->gpr[4], (unsigned long *)&rt_sf->pinfo) - || get_user(regs->gpr[5], (unsigned long *)&rt_sf->puc)) + /* Save user registers on the stack */ + frame = &rt_sf->uc.uc_mcontext; + if (save_user_regs(regs, frame, 0x6666)) goto badframe; + if (put_user(regs->gpr[1], (unsigned long *)newsp)) + goto badframe; regs->gpr[1] = newsp; + regs->gpr[3] = sig; + regs->gpr[4] = (unsigned long) &rt_sf->info; + regs->gpr[5] = (unsigned long) &rt_sf->uc; regs->gpr[6] = (unsigned long) rt_sf; + regs->nip = (unsigned long) ka->sa.sa_handler; regs->link = (unsigned long) frame->tramp; return; badframe: #if DEBUG_SIG - printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n", + printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n", regs, frame, newsp); #endif - do_exit(SIGSEGV); + if (sig == SIGSEGV) + ka->sa.sa_handler = SIG_DFL; + force_sig(SIGSEGV, current); } -/* - * Do a signal return; undo the signal stack. - */ -int sys_sigreturn(struct pt_regs *regs) +static int do_setcontext(struct ucontext *ucp, struct pt_regs *regs) { - struct sigcontext_struct *sc, sigctx; - struct sigregs *sr; - int ret; - elf_gregset_t saved_regs; /* an array of ELF_NGREG unsigned longs */ sigset_t set; - unsigned long prevsp; + struct mcontext *mcp; - sc = (struct sigcontext_struct *)(regs->gpr[1] + __SIGNAL_FRAMESIZE); - if (copy_from_user(&sigctx, sc, sizeof(sigctx))) - goto badframe; + if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(set)) + || __get_user(mcp, &ucp->uc_regs)) + return -EFAULT; + restore_sigmask(&set); + if (restore_user_regs(regs, mcp)) + return -EFAULT; - set.sig[0] = sigctx.oldmask; -#if _NSIG_WORDS > 1 - set.sig[1] = sigctx._unused[3]; -#endif - sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); - current->blocked = set; - recalc_sigpending(current); - spin_unlock_irq(¤t->sigmask_lock); - if (regs->msr & MSR_FP ) - giveup_fpu(current); + return 0; +} - sc++; /* Look at next sigcontext */ - if (sc == (struct sigcontext_struct *)(sigctx.regs)) { - /* Last stacked signal - restore registers */ - sr = (struct sigregs *) sigctx.regs; - if (copy_from_user(saved_regs, &sr->gp_regs, - sizeof(sr->gp_regs))) - goto badframe; - saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE) - | (saved_regs[PT_MSR] & MSR_USERCHANGE); - memcpy(regs, saved_regs, GP_REGS_SIZE); - - if (copy_from_user(current->thread.fpr, &sr->fp_regs, - sizeof(sr->fp_regs))) - goto badframe; - - ret = regs->result; - - } else { - /* More signals to go */ - regs->gpr[1] = (unsigned long)sc - __SIGNAL_FRAMESIZE; - if (copy_from_user(&sigctx, sc, sizeof(sigctx))) - goto badframe; - sr = (struct sigregs *) sigctx.regs; - regs->gpr[3] = ret = sigctx.signal; - regs->gpr[4] = (unsigned long) sc; - regs->link = (unsigned long) &sr->tramp; - regs->nip = sigctx.handler; - - if (get_user(prevsp, &sr->gp_regs[PT_R1]) - || put_user(prevsp, (unsigned long *) regs->gpr[1])) - goto badframe; - current->thread.fpscr = 0; +int sys_swapcontext(struct ucontext *old_ctx, struct ucontext *new_ctx, + int r5, int r6, int r7, int r8, struct pt_regs *regs) +{ + unsigned char tmp; + + if (old_ctx != NULL) { + if (verify_area(VERIFY_WRITE, old_ctx, sizeof(*old_ctx)) + || save_user_regs(regs, &old_ctx->uc_mcontext, 0) + || __copy_to_user(&old_ctx->uc_sigmask, + ¤t->blocked, sizeof(sigset_t)) + || __put_user(&old_ctx->uc_mcontext, &old_ctx->uc_regs)) + return -EFAULT; } - return ret; + if (new_ctx == NULL) + return 0; + if (verify_area(VERIFY_READ, new_ctx, sizeof(*new_ctx)) + || __get_user(tmp, (u8 *) new_ctx) + || __get_user(tmp, (u8 *) (new_ctx + 1) - 1)) + return -EFAULT; -badframe: - do_exit(SIGSEGV); -} + /* + * If we get a fault copying the context into the kernel's + * image of the user's registers, we can't just return -EFAULT + * because the user's registers will be corrupted. For instance + * the NIP value may have been updated but not some of the + * other registers. Given that we have done the verify_area + * and successfully read the first and last bytes of the region + * above, this should only happen in an out-of-memory situation + * or if another thread unmaps the region containing the context. + * We kill the task with a SIGSEGV in this situation. + */ + if (do_setcontext(new_ctx, regs)) + do_exit(SIGSEGV); + syscall_direct_return(regs); + /* doesn't actually return back to here */ + return 0; +} + +int sys_rt_sigreturn(struct pt_regs *regs) +{ + struct rt_sigframe *rt_sf; + stack_t st; + + rt_sf = (struct rt_sigframe *)(regs->gpr[1] + __SIGNAL_FRAMESIZE + 16); + if (verify_area(VERIFY_READ, rt_sf, sizeof(struct rt_sigframe))) + goto bad; + if (do_setcontext(&rt_sf->uc, regs)) + goto bad; + + /* + * It's not clear whether or why it is desirable to save the + * sigaltstack setting on signal delivery and restore it on + * signal return. But other architectures do this and we have + * always done it up until now so it is probably better not to + * change it. -- paulus + */ + if (__copy_from_user(&st, &rt_sf->uc.uc_stack, sizeof(st))) + goto bad; + do_sigaltstack(&st, NULL, regs->gpr[1]); + + return regs->result; + + bad: + force_sig(SIGSEGV, current); + return 0; +} /* - * Set up a signal frame. + * OK, we're invoking a handler */ static void -setup_frame(struct pt_regs *regs, struct sigregs *frame, - unsigned long newsp) +handle_signal(unsigned long sig, struct k_sigaction *ka, + siginfo_t *info, sigset_t *oldset, struct pt_regs * regs, + unsigned long newsp) { - struct sigcontext_struct *sc = (struct sigcontext_struct *) newsp; + struct sigcontext *sc; + struct sigregs *frame; + unsigned long origsp = newsp; + + /* Set up Signal Frame */ + newsp -= sizeof(struct sigregs); + frame = (struct sigregs *) newsp; + + /* Put a sigcontext on the stack */ + newsp -= sizeof(*sc); + sc = (struct sigcontext *) newsp; - if (verify_area(VERIFY_WRITE, frame, sizeof(*frame))) + /* create a stack frame for the caller of the handler */ + newsp -= __SIGNAL_FRAMESIZE; + + if (verify_area(VERIFY_WRITE, (void *) newsp, origsp - newsp)) goto badframe; - if (regs->msr & MSR_FP) - giveup_fpu(current); - if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE) - || __copy_to_user(&frame->fp_regs, current->thread.fpr, - ELF_NFPREG * sizeof(double)) - || __put_user(0x38007777UL, &frame->tramp[0]) /* li r0,0x7777 */ - || __put_user(0x44000002UL, &frame->tramp[1])) /* sc */ + +#if _NSIG != 64 +#error "Please adjust handle_signal()" +#endif + if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler) + || __put_user(oldset->sig[0], &sc->oldmask) + || __put_user(oldset->sig[1], &sc->_unused[3]) + || __put_user((struct pt_regs *)frame, &sc->regs) + || __put_user(sig, &sc->signal)) goto badframe; - flush_icache_range((unsigned long) &frame->tramp[0], - (unsigned long) &frame->tramp[2]); - current->thread.fpscr = 0; /* turn off all fp exceptions */ - newsp -= __SIGNAL_FRAMESIZE; - if (put_user(regs->gpr[1], (unsigned long *)newsp) - || get_user(regs->nip, &sc->handler) - || get_user(regs->gpr[3], &sc->signal)) + if (save_user_regs(regs, &frame->mctx, 0x7777)) + goto badframe; + + if (put_user(regs->gpr[1], (unsigned long *)newsp)) goto badframe; regs->gpr[1] = newsp; + regs->gpr[3] = sig; regs->gpr[4] = (unsigned long) sc; - regs->link = (unsigned long) frame->tramp; + regs->nip = (unsigned long) ka->sa.sa_handler; + regs->link = (unsigned long) frame->mctx.tramp; return; badframe: #if DEBUG_SIG - printk("badframe in setup_frame, regs=%p frame=%p newsp=%lx\n", - regs, frame, newsp); + printk("badframe in handle_signal, regs=%p frame=%lx newsp=%lx\n", + regs, frame, *newspp); #endif - do_exit(SIGSEGV); + if (sig == SIGSEGV) + ka->sa.sa_handler = SIG_DFL; + force_sig(SIGSEGV, current); } /* - * OK, we're invoking a handler + * Do a signal return; undo the signal stack. */ -static void -handle_signal(unsigned long sig, struct k_sigaction *ka, - siginfo_t *info, sigset_t *oldset, struct pt_regs * regs, - unsigned long *newspp, unsigned long frame) +int sys_sigreturn(struct pt_regs *regs) { - struct sigcontext_struct *sc; - struct rt_sigframe *rt_sf; + struct sigcontext *sc, sigctx; + struct mcontext *sr; + int ret; + sigset_t set; + + sc = (struct sigcontext *)(regs->gpr[1] + __SIGNAL_FRAMESIZE); + if (copy_from_user(&sigctx, sc, sizeof(sigctx))) + goto badframe; - if (regs->trap == 0x0C00 /* System Call! */ - && ((int)regs->result == -ERESTARTNOHAND || - ((int)regs->result == -ERESTARTSYS && - !(ka->sa.sa_flags & SA_RESTART)))) - regs->result = -EINTR; + set.sig[0] = sigctx.oldmask; + set.sig[1] = sigctx._unused[3]; + restore_sigmask(&set); - /* Set up Signal Frame */ - if (ka->sa.sa_flags & SA_SIGINFO) { - /* Put a Real Time Context onto stack */ - *newspp -= sizeof(*rt_sf); - rt_sf = (struct rt_sigframe *) *newspp; - if (verify_area(VERIFY_WRITE, rt_sf, sizeof(*rt_sf))) - goto badframe; - - if (__put_user((unsigned long) ka->sa.sa_handler, &rt_sf->uc.uc_mcontext.handler) - || __put_user(&rt_sf->info, &rt_sf->pinfo) - || __put_user(&rt_sf->uc, &rt_sf->puc) - /* Put the siginfo */ - || __copy_to_user(&rt_sf->info, info, sizeof(*info)) - /* Create the ucontext */ - || __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]), - &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)) - /* mcontext.regs points to preamble register frame */ - || __put_user((struct pt_regs *)frame, &rt_sf->uc.uc_mcontext.regs) - || __put_user(sig, &rt_sf->uc.uc_mcontext.signal)) - goto badframe; - } else { - /* Put another sigcontext on the stack */ - *newspp -= sizeof(*sc); - 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 - || __put_user(oldset->sig[1], &sc->_unused[3]) -#endif - || __put_user((struct pt_regs *)frame, &sc->regs) - || __put_user(sig, &sc->signal)) - goto badframe; - } + sr = (struct mcontext *) sigctx.regs; + if (verify_area(VERIFY_READ, sr, sizeof(*sr)) + || restore_user_regs(regs, sr)) + goto badframe; - if (ka->sa.sa_flags & SA_ONESHOT) - ka->sa.sa_handler = SIG_DFL; + ret = regs->result; - 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); - } - return; + return ret; badframe: -#if DEBUG_SIG - printk("badframe in handle_signal, regs=%p frame=%lx newsp=%lx\n", - regs, frame, *newspp); - printk("sc=%p sig=%d ka=%p info=%p oldset=%p\n", sc, sig, ka, info, oldset); -#endif - do_exit(SIGSEGV); -} + force_sig(SIGSEGV, current); + return 0; +} -/* - * 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. - */ -int do_signal(sigset_t *oldset, struct pt_regs *regs) +static int get_signal_to_deliver(struct siginfo *infop, struct pt_regs *regs) { - siginfo_t info; struct k_sigaction *ka; - unsigned long frame, newsp; - - if (!oldset) - oldset = ¤t->blocked; - - newsp = frame = 0; + int signr; for (;;) { - unsigned long signr; - spin_lock_irq(¤t->sigmask_lock); - signr = dequeue_signal(¤t->blocked, &info); + signr = dequeue_signal(¤t->blocked, infop); spin_unlock_irq(¤t->sigmask_lock); if (!signr) - break; + return 0; if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) { /* Let the debugger run. */ @@ -589,17 +604,17 @@ 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 (signr != infop->si_signo) { + infop->si_signo = signr; + infop->si_errno = 0; + infop->si_code = SI_USER; + infop->si_pid = current->p_pptr->pid; + infop->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); + send_sig_info(signr, infop, current); continue; } } @@ -646,39 +661,85 @@ /* FALLTHRU */ default: - sig_exit(signr, exit_code, &info); + sig_exit(signr, exit_code, infop); /* NOTREACHED */ } } + return signr; + } +} - if ( (ka->sa.sa_flags & SA_ONSTACK) - && (! on_sig_stack(regs->gpr[1]))) - newsp = (current->sas_ss_sp + current->sas_ss_size); - else - newsp = regs->gpr[1]; - newsp = frame = newsp - sizeof(struct sigregs); - - /* Whee! Actually deliver the signal. */ - handle_signal(signr, ka, &info, oldset, regs, &newsp, frame); - break; - } - - if (regs->trap == 0x0C00 /* System Call! */ && - ((int)regs->result == -ERESTARTNOHAND || - (int)regs->result == -ERESTARTSYS || - (int)regs->result == -ERESTARTNOINTR)) { - regs->gpr[3] = regs->orig_gpr3; - regs->nip -= 4; /* Back up & retry system call */ - regs->result = 0; +/* + * 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. + */ +int do_signal(sigset_t *oldset, struct pt_regs *regs) +{ + siginfo_t info; + struct k_sigaction *ka; + unsigned long frame, newsp; + int signr; + + if (!oldset) + oldset = ¤t->blocked; + + newsp = frame = 0; + + signr = get_signal_to_deliver(&info, regs); + + ka = (signr == 0)? NULL: ¤t->sig->action[signr-1]; + + if (regs->trap == 0xc00) { /* system call */ + switch ((int) regs->result) { + case -ERESTARTSYS: + if (signr == 0 || (ka->sa.sa_flags & SA_RESTART)) + goto retry; + /* fall through */ + case -ERESTARTNOHAND: + if (signr > 0) { + /* make the system call return an EINTR */ + regs->result = -EINTR; + break; + } + /* fall through */ + case -ERESTARTNOINTR: + retry: + /* Back up & retry system call */ + regs->gpr[3] = regs->orig_gpr3; + regs->nip -= 4; + regs->result = 0; + break; + } } - if (newsp == frame) + if (signr == 0) return 0; /* no signals delivered */ + if ((ka->sa.sa_flags & SA_ONSTACK) && current->sas_ss_size + && !on_sig_stack(regs->gpr[1])) + newsp = current->sas_ss_sp + current->sas_ss_size; + else + newsp = regs->gpr[1]; + newsp &= ~0xfUL; + + /* Whee! Actually deliver the signal. */ if (ka->sa.sa_flags & SA_SIGINFO) - setup_rt_frame(regs, (struct sigregs *) frame, newsp); + handle_rt_signal(signr, ka, &info, oldset, regs, newsp); else - setup_frame(regs, (struct sigregs *) frame, newsp); + handle_signal(signr, ka, &info, oldset, regs, newsp); + + 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, signr); + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + } + return 1; } Index: arch/ppc/kernel/smp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/smp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/smp.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/smp.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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(); Index: arch/ppc/kernel/softemu8xx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/softemu8xx.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/softemu8xx.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/softemu8xx.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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) Index: arch/ppc/kernel/syscalls.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/syscalls.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/syscalls.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/syscalls.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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" @@ -57,7 +57,7 @@ * This is really horribly ugly. */ int -sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth) +sys_ipc(uint call, int first, int second, int third, void *ptr, long fifth) { int version, ret; @@ -67,24 +67,28 @@ ret = -EINVAL; switch (call) { case SEMOP: - ret = sys_semop (first, (struct sembuf *)ptr, second); + ret = sys_semtimedop(first, (struct sembuf *)ptr, second, NULL); + break; + case SEMTIMEDOP: + ret = sys_semtimedop(first, (struct sembuf *)ptr, second, + (const struct timespec *)fifth); break; case SEMGET: - ret = sys_semget (first, second, third); + ret = sys_semget(first, second, third); break; case SEMCTL: { union semun fourth; if (!ptr) break; - if ((ret = verify_area (VERIFY_READ, ptr, sizeof(long))) + if ((ret = verify_area(VERIFY_READ, ptr, sizeof(long))) || (ret = get_user(fourth.__pad, (void **)ptr))) break; - ret = sys_semctl (first, second, third, fourth); + ret = sys_semctl(first, second, third, fourth); break; } case MSGSND: - ret = sys_msgsnd (first, (struct msgbuf *) ptr, second, third); + ret = sys_msgsnd(first, (struct msgbuf *) ptr, second, third); break; case MSGRCV: switch (version) { @@ -93,26 +97,26 @@ if (!ptr) break; - if ((ret = verify_area (VERIFY_READ, ptr, sizeof(tmp))) + if ((ret = verify_area(VERIFY_READ, ptr, sizeof(tmp))) || (ret = copy_from_user(&tmp, (struct ipc_kludge *) ptr, sizeof (tmp)))) break; - ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, - third); + ret = sys_msgrcv(first, tmp.msgp, second, tmp.msgtyp, + third); break; } default: - ret = sys_msgrcv (first, (struct msgbuf *) ptr, - second, fifth, third); + ret = sys_msgrcv(first, (struct msgbuf *) ptr, + second, fifth, third); break; } break; case MSGGET: - ret = sys_msgget ((key_t) first, second); + ret = sys_msgget((key_t) first, second); break; case MSGCTL: - ret = sys_msgctl (first, second, (struct msqid_ds *) ptr); + ret = sys_msgctl(first, second, (struct msqid_ds *) ptr); break; case SHMAT: switch (version) { @@ -122,29 +126,31 @@ if ((ret = verify_area(VERIFY_WRITE, (ulong*) third, sizeof(ulong)))) break; - ret = sys_shmat (first, (char *) ptr, second, &raddr); + ret = sys_shmat(first, (char *) ptr, second, &raddr); if (ret) break; - ret = put_user (raddr, (ulong *) third); + ret = put_user(raddr, (ulong *) third); break; } case 1: /* iBCS2 emulator entry point */ if (!segment_eq(get_fs(), get_ds())) break; - ret = sys_shmat (first, (char *) ptr, second, - (ulong *) third); + ret = sys_shmat(first, (char *) ptr, second, + (ulong *) third); break; } break; - case SHMDT: - ret = sys_shmdt ((char *)ptr); + case SHMDT: + ret = sys_shmdt((char *)ptr); break; case SHMGET: - ret = sys_shmget (first, second, third); + ret = sys_shmget(first, second, third); break; case SHMCTL: - ret = sys_shmctl (first, second, (struct shmid_ds *) ptr); + ret = sys_shmctl(first, second, (struct shmid_ds *) ptr); break; + default: + ret = -ENOSYS; } return ret; @@ -167,6 +173,16 @@ return error; } +#ifndef CONFIG_40x +#define allow_mmap_address(addr) 1 +#else +/* Blech. On 40x allowing mmap() (MAP_FIXED) at the first few pages + * of (any process's) virtual memory is a security hole due to chip + * erratum #67 (and possibly also due to the (documented) bizarre + * prefetch behaviour around 'sc' see S3.8.2.1 of the user manual). */ +#define allow_mmap_address(addr) ((((addr) & PAGE_MASK) >= 0x2100) || suser()) +#endif + static inline unsigned long do_mmap2(unsigned long addr, size_t len, unsigned long prot, unsigned long flags, @@ -180,6 +196,10 @@ if (!(file = fget(fd))) goto out; } + + ret = -EINVAL; + if ((! allow_mmap_address(addr)) && (flags & MAP_FIXED)) + goto out; down_write(¤t->mm->mmap_sem); ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); @@ -263,7 +283,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); Index: arch/ppc/kernel/temp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/temp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/temp.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/temp.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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; Index: arch/ppc/kernel/time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/time.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/time.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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) Index: arch/ppc/kernel/todc_time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/todc_time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/todc_time.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/todc_time.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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(); /* Index: arch/ppc/kernel/traps.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/kernel/traps.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/kernel/traps.c 22 Jul 2004 19:49:02 -0000 1.1 +++ arch/ppc/kernel/traps.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -1,5 +1,5 @@ /* - * linux/arch/ppc/kernel/traps.c + * arch/ppc/kernel/traps.c * * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * @@ -167,12 +167,16 @@ #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 #define REASON_TRAP ESR_PTR +/* single-step stuff */ +#define single_stepping(regs) (current->thread.dbcr0 & DBCR0_IC) +#define clear_single_step(regs) (current->thread.dbcr0 &= ~DBCR0_IC) + #else /* On non-4xx, the reason for the machine check or program exception is in the MSR. */ @@ -181,6 +185,9 @@ #define REASON_ILLEGAL 0x80000 #define REASON_PRIVILEGED 0x40000 #define REASON_TRAP 0x20000 + +#define single_stepping(regs) ((regs)->msr & MSR_SE) +#define clear_single_step(regs) ((regs)->msr &= ~MSR_SE) #endif void @@ -205,15 +212,44 @@ if (check_io_access(regs)) return; -#ifdef CONFIG_4xx +#if defined(CONFIG_4xx) && !defined(CONFIG_440A) if (reason & ESR_IMCP) { printk("Instruction"); mtspr(SPRN_ESR, reason & ~ESR_IMCP); } else printk("Data"); printk(" machine check in kernel mode.\n"); - -#else /* CONFIG_4xx */ +#elif defined(CONFIG_440A) + printk("Machine check in kernel mode.\n"); + if (reason & ESR_IMCP){ + printk("Instruction Synchronous Machine Check exception\n"); + mtspr(SPRN_ESR, reason & ~ESR_IMCP); + } + else { + u32 mcsr = mfspr(SPRN_MCSR); + if (mcsr & MCSR_IB) + printk("Instruction Read PLB Error\n"); + if (mcsr & MCSR_DRB) + printk("Data Read PLB Error\n"); + if (mcsr & MCSR_DWB) + printk("Data Write PLB Error\n"); + if (mcsr & MCSR_TLBP) + printk("TLB Parity Error\n"); + if (mcsr & MCSR_ICP){ + flush_instruction_cache(); + printk("I-Cache Parity Error\n"); + } + if (mcsr & MCSR_DCSP) + printk("D-Cache Search Parity Error\n"); + if (mcsr & MCSR_DCFP) + printk("D-Cache Flush Parity Error\n"); + if (mcsr & MCSR_IMPE) + printk("Machine Check exception is imprecise\n"); + + /* Clear MCSR */ + mtspr(SPRN_MCSR, mcsr); + } +#else /* !CONFIG_4xx && !CONFIG_E500 */ printk("Machine check in kernel mode.\n"); printk("Caused by (from SRR1=%lx): ", reason); switch (reason & 0x601F0000) { @@ -320,6 +356,22 @@ return retval; } +/* + * After we have successfully emulated an instruction, we have to + * check if the instruction was being single-stepped, and if so, + * pretend we got a single-step exception. This was pointed out + * by Kumar Gala. -- paulus + */ +static void emulate_single_step(struct pt_regs *regs) +{ + if (single_stepping(regs)) { + clear_single_step(regs); + if (debugger_sstep(regs)) + return; + _exception(SIGTRAP, regs, TRAP_TRACE, 0); + } +} + void ProgramCheckException(struct pt_regs *regs) { @@ -327,8 +379,17 @@ 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) { + emulate_single_step(regs); return; + } #endif /* CONFIG_MATH_EMULATION */ if (reason & REASON_FP) { @@ -364,8 +425,10 @@ if (reason & REASON_PRIVILEGED) { /* Try to emulate it if we should. */ - if (emulate_instruction(regs) == 0) + if (emulate_instruction(regs) == 0) { + emulate_single_step(regs); return; + } _exception(SIGILL, regs, ILL_PRVOPC, regs->nip); return; } @@ -390,6 +453,7 @@ fixed = fix_alignment(regs); if (fixed == 1) { regs->nip += 4; /* skip over emulated instruction */ + emulate_single_step(regs); return; } if (fixed == -EFAULT) { @@ -446,19 +510,60 @@ _exception(SIGSEGV, regs, 0, 0); else _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); - } + } else + emulate_single_step(regs); } #endif /* CONFIG_8xx */ +#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) + +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 || CONFIG_BOOKE */ + #if !defined(CONFIG_TAU_INT) void TAUException(struct pt_regs *regs) { - printk("TAU trap at PC: %lx, SR: %lx, vector=%lx %s\n", + printk("Thermal trap at PC: %lx, SR: %lx, vector=%lx %s\n", regs->nip, regs->msr, regs->trap, print_tainted()); } #endif /* CONFIG_INT_TAU */ +#ifdef CONFIG_ALTIVEC +void +AltivecAssistException(struct pt_regs *regs) +{ + if (regs->msr & MSR_VEC) + giveup_altivec(current); + /* XXX quick hack for now: set the non-Java bit in the VSCR */ + current->thread.vscr.u[3] |= 0x10000; +} +#endif /* CONFIG_ALTIVEC */ + void __init trap_init(void) { } Index: arch/ppc/lib/checksum.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/lib/checksum.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/lib/checksum.S 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/lib/checksum.S 4 Aug 2004 01:26:08 -0000 1.2 @@ -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 */ Index: arch/ppc/lib/locks.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/lib/locks.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/lib/locks.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/lib/locks.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -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 */ Index: arch/ppc/lib/string.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/lib/string.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/lib/string.S 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/lib/string.S 4 Aug 2004 01:26:08 -0000 1.2 @@ -62,13 +62,14 @@ .text .text + .stabs "arch/ppc/lib/",N_SO,0,0,0f + .stabs "string.S",N_SO,0,0,0f CACHELINE_BYTES = L1_CACHE_LINE_SIZE LG_CACHELINE_BYTES = LG_L1_CACHE_LINE_SIZE CACHELINE_MASK = (L1_CACHE_LINE_SIZE-1) - .globl strcpy -strcpy: +_GLOBAL(strcpy) addi r5,r3,-1 addi r4,r4,-1 1: lbzu r0,1(r4) @@ -77,8 +78,9 @@ bne 1b blr - .globl strncpy -strncpy: +/* This clears out any unused part of the destination buffer, + just as the libc version does. -- paulus */ +_GLOBAL(strncpy) cmpwi 0,r5,0 beqlr mtctr r5 @@ -88,10 +90,15 @@ 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 -strcat: +_GLOBAL(strcat) addi r5,r3,-1 addi r4,r4,-1 1: lbzu r0,1(r5) @@ -104,8 +111,7 @@ bne 1b blr - .globl strcmp -strcmp: +_GLOBAL(strcmp) addi r5,r3,-1 addi r4,r4,-1 1: lbzu r3,1(r5) @@ -116,8 +122,7 @@ beq 1b blr - .globl strlen -strlen: +_GLOBAL(strlen) addi r4,r3,-1 1: lbzu r0,1(r4) cmpwi 0,r0,0 @@ -130,8 +135,7 @@ * to set them to zero. This requires that the destination * area is cacheable. -- paulus */ - .globl cacheable_memzero -cacheable_memzero: +_GLOBAL(cacheable_memzero) mr r5,r4 li r4,0 addi r6,r3,-4 @@ -181,8 +185,7 @@ bdnz 8b blr - .globl memset -memset: +_GLOBAL(memset) rlwimi r4,r4,8,16,23 rlwimi r4,r4,16,0,15 addi r6,r3,-4 @@ -207,8 +210,7 @@ bdnz 8b blr - .globl bcopy -bcopy: +_GLOBAL(bcopy) mr r6,r3 mr r3,r4 mr r4,r6 @@ -221,8 +223,7 @@ * We only use this version if the source and dest don't overlap. * -- paulus. */ - .global cacheable_memcpy -cacheable_memcpy: +_GLOBAL(cacheable_memcpy) add r7,r3,r5 /* test if the src & dst overlap */ add r8,r4,r5 cmplw 0,r4,r7 @@ -296,14 +297,12 @@ bdnz 40b 65: blr - .globl memmove -memmove: +_GLOBAL(memmove) cmplw 0,r3,r4 bgt backwards_memcpy /* fall through */ - .globl memcpy -memcpy: +_GLOBAL(memcpy) srwi. r7,r5,3 addi r6,r3,-4 addi r4,r4,-4 @@ -344,8 +343,7 @@ mtctr r7 b 1b - .globl backwards_memcpy -backwards_memcpy: +_GLOBAL(backwards_memcpy) rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ add r6,r3,r5 add r4,r4,r5 @@ -380,9 +378,8 @@ beq 2b mtctr r7 b 1b - - .globl memcmp -memcmp: + +_GLOBAL(memcmp) cmpwi 0,r5,0 ble- 2f mtctr r5 @@ -396,8 +393,7 @@ 2: li r3,0 blr - .global memchr -memchr: +_GLOBAL(memchr) cmpwi 0,r5,0 ble- 2f mtctr r5 @@ -409,8 +405,7 @@ 2: li r3,0 blr - .globl __copy_tofrom_user -__copy_tofrom_user: +_GLOBAL(__copy_tofrom_user) addi r4,r4,-4 addi r6,r3,-4 neg r0,r3 @@ -435,48 +430,57 @@ 73: stwu r9,4(r6) bdnz 72b + .section __ex_table,"a" + .align 2 + .long 70b,100f + .long 71b,101f + .long 72b,102f + .long 73b,103f + .text + 58: srwi. r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */ clrlwi r5,r5,32-LG_CACHELINE_BYTES li r11,4 beq 63f -#if !defined(CONFIG_8xx) +#ifdef CONFIG_8xx + /* Don't use prefetch on 8xx */ + mtctr r0 +53: COPY_16_BYTES_WITHEX(0) + bdnz 53b + +#else /* not CONFIG_8xx */ /* Here we decide how far ahead to prefetch the source */ + li r3,4 + cmpwi r0,1 + li r7,0 + ble 114f + li r7,1 #if MAX_COPY_PREFETCH > 1 /* Heuristically, for large transfers we prefetch MAX_COPY_PREFETCH cachelines ahead. For small transfers we prefetch 1 cacheline ahead. */ cmpwi r0,MAX_COPY_PREFETCH - li r7,1 - li r3,4 - ble 111f + ble 112f li r7,MAX_COPY_PREFETCH -111: mtctr r7 -112: dcbt r3,r4 +112: mtctr r7 +111: dcbt r3,r4 addi r3,r3,CACHELINE_BYTES - bdnz 112b -#else /* MAX_COPY_PREFETCH == 1 */ - li r3,CACHELINE_BYTES + 4 - dcbt r11,r4 -#endif /* MAX_COPY_PREFETCH */ -#endif /* CONFIG_8xx */ - - mtctr r0 -53: -#if !defined(CONFIG_8xx) + bdnz 111b +#else dcbt r3,r4 + addi r3,r3,CACHELINE_BYTES +#endif /* MAX_COPY_PREFETCH > 1 */ + +114: subf r8,r7,r0 + mr r0,r7 + mtctr r8 + +53: dcbt r3,r4 54: dcbz r11,r6 -#endif -/* had to move these to keep extable in order */ .section __ex_table,"a" .align 2 - .long 70b,100f - .long 71b,101f - .long 72b,102f - .long 73b,103f -#if !defined(CONFIG_8xx) .long 54b,105f -#endif .text /* the main body of the cacheline loop */ COPY_16_BYTES_WITHEX(0) @@ -494,6 +498,11 @@ #endif #endif bdnz 53b + cmpwi r0,0 + li r3,4 + li r7,0 + bne 114b +#endif /* CONFIG_8xx */ 63: srwi. r0,r5,2 mtctr r0 @@ -616,8 +625,7 @@ .long 114b,120b .text - .globl __clear_user -__clear_user: +_GLOBAL(__clear_user) addi r6,r3,-4 li r3,0 li r5,0 @@ -660,8 +668,7 @@ .long 8b,92b .text - .globl __strncpy_from_user -__strncpy_from_user: +_GLOBAL(__strncpy_from_user) addi r6,r3,-1 addi r4,r4,-1 cmpwi 0,r5,0 @@ -684,8 +691,7 @@ .text /* r3 = str, r4 = len (> 0), r5 = top (highest addr) */ - .globl __strnlen_user -__strnlen_user: +_GLOBAL(__strnlen_user) addi r7,r3,-1 subf r6,r7,r5 /* top+1 - str */ cmplw 0,r4,r6 Index: arch/ppc/math-emu/fcmpo.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/math-emu/fcmpo.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/math-emu/fcmpo.c 22 Jul 2004 19:49:01 -0000 1.1 +++ arch/ppc/math-emu/fcmpo.c 4 Aug 2004 01:26:08 -0000 1.2 @@ -37,7 +37,7 @@ *ccr &= ~(15 << ((7 - crfD) << 2)); *ccr |= (cmp << ((7 - crfD) << 2)); - + #ifdef DEBUG printk("CR: %08x\n", *ccr); #endif Index: arch/ppc/math-emu/op-1.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/math-emu/op-1.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/math-emu/op-1.h 22 Jul 2004 19:49:01 -0000 1.1 +++ arch/ppc/math-emu/op-1.h 4 Aug 2004 01:26:08 -0000 1.2 @@ -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. */ Index: arch/ppc/math-emu/op-2.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/math-emu/op-2.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/math-emu/op-2.h 22 Jul 2004 19:49:01 -0000 1.1 +++ arch/ppc/math-emu/op-2.h 4 Aug 2004 01:26:08 -0000 1.2 @@ -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. */ Index: arch/ppc/math-emu/op-4.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/math-emu/op-4.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/math-emu/op-4.h 22 Jul 2004 19:49:01 -0000 1.1 +++ arch/ppc/math-emu/op-4.h 4 Aug 2004 01:26:08 -0000 1.2 @@ -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. */ Index: arch/ppc/math-emu/op-common.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/math-emu/op-common.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/math-emu/op-common.h 22 Jul 2004 19:49:01 -0000 1.1 +++ arch/ppc/math-emu/op-common.h 4 Aug 2004 01:26:08 -0000 1.2 @@ -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 { \ Index: arch/ppc/math-emu/sfp-machine.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/math-emu/sfp-machine.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/math-emu/sfp-machine.h 22 Jul 2004 19:49:01 -0000 1.1 +++ arch/ppc/math-emu/sfp-machine.h 4 Aug 2004 01:26:08 -0000 1.2 @@ -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 Index: arch/ppc/math-emu/stfd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/math-emu/stfd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/math-emu/stfd.c 22 Jul 2004 19:49:01 -0000 1.1 +++ arch/ppc/math-emu/stfd.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -1,7 +1,7 @@ #include #include #include - + int stfd(void *frS, void *ea) { Index: arch/ppc/mm/4xx_mmu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/mm/4xx_mmu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/mm/4xx_mmu.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/mm/4xx_mmu.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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. */ } Index: arch/ppc/mm/4xx_tlb.c =================================================================== RCS file: arch/ppc/mm/4xx_tlb.c diff -N arch/ppc/mm/4xx_tlb.c --- arch/ppc/mm/4xx_tlb.c 22 Jul 2004 19:48:59 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); -} Index: arch/ppc/mm/4xx_tlb.h =================================================================== RCS file: arch/ppc/mm/4xx_tlb.h diff -N arch/ppc/mm/4xx_tlb.h --- arch/ppc/mm/4xx_tlb.h 22 Jul 2004 19:48:59 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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__ */ Index: arch/ppc/mm/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/mm/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/mm/Makefile 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/mm/Makefile 4 Aug 2004 01:26:09 -0000 1.2 @@ -18,7 +18,8 @@ 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_44x) += 44x_mmu.o +obj-$(CONFIG_NOT_COHERENT_CACHE) += cachemap.o include $(TOPDIR)/Rules.make Index: arch/ppc/mm/cachemap.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/mm/cachemap.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/mm/cachemap.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/mm/cachemap.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -11,6 +11,7 @@ * is the virtual address and 'dma_handle' is the physical address. * Mostly stolen from the ARM port, with some changes for PowerPC. * -- Dan + * Modified for 36-bit support. -Matt * * 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 @@ -48,14 +49,24 @@ #include #include -extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep); +#include "mmu_decl.h" +extern int map_page(unsigned long va, phys_addr_t pa, int flags); + +/* This function will allocate the requested contiguous pages and + * map them into the kernel's vmalloc() space. This is done so we + * get unique mapping for these pages, outside of the kernel's 1:1 + * virtual:physical mapping. This is necessary so we can cover large + * portions of the kernel with single large page TLB entries, and + * still get unique uncached pages for consistent DMA. + */ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) { - int order, rsize; - unsigned long page; - void *ret; - pte_t *pte; + int order, err, i; + unsigned long page, va, flags; + phys_addr_t pa; + struct vm_struct *area; + void *ret; if (in_interrupt()) BUG(); @@ -77,23 +88,41 @@ */ invalidate_dcache_range(page, page + size); - ret = (void *)page; - *dma_handle = virt_to_bus(ret); + /* Allocate some common virtual space to map the new pages. + */ + area = get_vm_area(size, VM_ALLOC); + if (area == 0) { + free_pages(page, order); + return NULL; + } + va = VMALLOC_VMADDR(area->addr); + ret = (void *)va; - /* Chase down all of the PTEs and mark them uncached. + /* This gives us the real physical address of the first page. */ - rsize = (int)size; - while (rsize > 0) { - if (get_pteptr(&init_mm, page, &pte)) { - pte_val(*pte) |= _PAGE_NO_CACHE | _PAGE_GUARDED; - flush_tlb_page(find_vma(&init_mm,page),page); - } - else { - BUG(); - return NULL; - } - page += PAGE_SIZE; - rsize -= PAGE_SIZE; + *dma_handle = pa = virt_to_bus((void *)page); + + flags = _PAGE_KERNEL | _PAGE_NO_CACHE; + + /* + * Set refcount=1 on all pages in an order>0 + * allocation so that vfree() will actually + * free all pages that were allocated. + */ + if (order > 0) + { + struct page *rpage = virt_to_page(page); + for (i = 1; i < (1 << order); i++) + set_page_count(rpage+i, 1); + } + + err = 0; + for (i = 0; i < size && err == 0; i += PAGE_SIZE) + err = map_page(va+i, pa+i, flags); + + if (err) { + vfree((void *)va); + return NULL; } return ret; @@ -101,42 +130,12 @@ /* * free page(s) as defined by the above mapping. - * The caller has to tell us the size so we can free the proper number - * of pages. We can't vmalloc() a new space for these pages and simply - * call vfree() like some other architectures because we could end up - * with aliased cache lines (or at least a cache line with the wrong - * attributes). This can happen when the PowerPC speculative loads - * across page boundaries. */ -void consistent_free(void *vaddr, size_t size) +void consistent_free(void *vaddr) { - int order, rsize; - unsigned long addr; - pte_t *pte; - if (in_interrupt()) BUG(); - - size = PAGE_ALIGN(size); - order = get_order(size); - - /* Chase down all of the PTEs and mark them cached again. - */ - addr = (unsigned long)vaddr; - rsize = (int)size; - while (rsize > 0) { - if (get_pteptr(&init_mm, addr, &pte)) { - pte_val(*pte) &= ~(_PAGE_NO_CACHE | _PAGE_GUARDED); - flush_tlb_page(find_vma(&init_mm,addr),addr); - } - else { - BUG(); - return; - } - addr += PAGE_SIZE; - rsize -= PAGE_SIZE; - } - free_pages((unsigned long)vaddr, order); + vfree(vaddr); } /* @@ -161,3 +160,17 @@ break; } } + +/* + * consistent_sync_page make a page are consistent. identical + * to consistent_sync, but takes a struct page instead of a virtual address + */ + +void consistent_sync_page(struct page *page, unsigned long offset, +size_t size, int direction) +{ + void *start; + + start = page_address(page) + offset; + consistent_sync(start, size, direction); +} Index: arch/ppc/mm/fault.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/mm/fault.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/mm/fault.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/mm/fault.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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" @@ -100,7 +100,7 @@ struct mm_struct *mm = current->mm; siginfo_t info; int code = SEGV_MAPERR; -#if defined(CONFIG_4xx) +#if defined(CONFIG_4xx) || defined (CONFIG_BOOKE) int is_write = error_code & ESR_DST; #else int is_write = 0; @@ -115,14 +115,14 @@ error_code &= 0x48200000; else is_write = error_code & 0x02000000; -#endif /* CONFIG_4xx */ +#endif /* CONFIG_4xx || CONFIG_BOOKE */ #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) if (debugger_fault_handler && regs->trap == 0x300) { debugger_fault_handler(regs); return; } -#if !defined(CONFIG_4xx) +#ifndef CONFIG_4xx if (error_code & 0x00400000) { /* DABR match */ if (debugger_dabr_match(regs)) @@ -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"); Index: arch/ppc/mm/hashtable.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/mm/hashtable.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/mm/hashtable.S 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/mm/hashtable.S 4 Aug 2004 01:26:09 -0000 1.2 @@ -1,9 +1,9 @@ /* * arch/ppc/kernel/hashtable.S * - * $Id: hashtable.S,v 1.1 2004/07/22 19:48:59 joff Exp $ + * $Id: hashtable.S,v 1.2 2004/08/04 01:26:09 joff 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 Index: arch/ppc/mm/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/mm/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/mm/init.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/mm/init.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -46,6 +46,31 @@ #include "mem_pieces.h" #include "mmu_decl.h" +/* + * Just any arbitrary offset to the start of the vmalloc VM area: the + * current 64MB value just means that there will be a 64MB "hole" after the + * physical memory until the kernel virtual memory starts. That means that + * any out-of-bounds memory accesses will hopefully be caught. + * The vmalloc() routines leaves a hole of 4kB between each vmalloced + * area for the same reason. ;) + * + * We no longer map larger than phys RAM with the BATs so we don't have + * to worry about the VMALLOC_OFFSET causing problems. We do have to worry + * about clashes between our early calls to ioremap() that start growing down + * from ioremap_base being run into the VM area allocations (growing upwards + * from VMALLOC_START). For this reason we have ioremap_bot to check when + * we actually run into our mappings setup in the early boot with the VM + * system. This really does become a problem for machines with good amounts + * of RAM. -- Cort + */ +#ifdef CONFIG_PIN_TLB +#define VMALLOC_OFFSET (0x2000000) /* 32M */ +#else +#define VMALLOC_OFFSET (0x1000000) /* 16M */ +#endif + +unsigned long vmalloc_start; + mmu_gather_t mmu_gathers[NR_CPUS]; unsigned long total_memory; @@ -313,6 +338,7 @@ total_lowmem = total_memory; adjust_total_lowmem(); set_phys_avail(total_lowmem); + vmalloc_start = KERNELBASE + total_lowmem; /* Initialize the MMU hardware */ if (ppc_md.progress) @@ -345,7 +371,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 @@ -459,6 +485,9 @@ totalram_pages += free_all_bootmem(); + /* adjust vmalloc_start */ + vmalloc_start = (vmalloc_start + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1); + #ifdef CONFIG_BLK_DEV_INITRD /* if we are booted from BootX with an initial ramdisk, make sure the ramdisk pages aren't reserved. */ @@ -573,14 +602,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 */ Index: arch/ppc/mm/mem_pieces.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/mm/mem_pieces.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/mm/mem_pieces.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/mm/mem_pieces.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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) { Index: arch/ppc/mm/mmu_context.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/mm/mmu_context.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/mm/mmu_context.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/mm/mmu_context.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -3,11 +3,8 @@ * PowerPC implementations where the MMU substantially follows the * architecture specification. This includes the 6xx, 7xx, 7xxx, * 8260, and POWER3 implementations but excludes the 8xx and 4xx. - * Although the iSeries hardware does comply with the architecture - * 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) * Index: arch/ppc/mm/mmu_decl.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/mm/mmu_decl.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/mm/mmu_decl.h 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/mm/mmu_decl.h 4 Aug 2004 01:26:09 -0000 1.2 @@ -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) * @@ -21,11 +21,12 @@ */ #include +#include extern void mapin_ram(void); extern void bat_mapin_ram(unsigned long bat2, unsigned long bat3); extern void adjust_total_lowmem(void); -extern int map_page(unsigned long va, unsigned long pa, int flags); +extern int map_page(unsigned long va, phys_addr_t pa, int flags); extern void setbat(int index, unsigned long virt, unsigned long phys, unsigned int size, int flags); extern void reserve_phys_mem(unsigned long start, unsigned long size); Index: arch/ppc/mm/pgtable.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/mm/pgtable.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/mm/pgtable.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/mm/pgtable.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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) * @@ -37,10 +37,11 @@ unsigned long ioremap_bot; int io_bat_index; -/* Maximum 768Mb of lowmem. On SMP, this value will be - * trimmed down to whatever can be covered by BATs though. +/* The maximum lowmem defaults to 768Mb, but this can be configured to + * another value. On SMP, this value will be trimmed down to whatever + * can be covered by BATs. */ -#define MAX_LOW_MEM 0x30000000 +#define MAX_LOW_MEM CONFIG_LOWMEM_SIZE #ifndef CONFIG_SMP struct pgtable_cache_struct quicklists; @@ -67,16 +68,35 @@ #define p_mapped_by_bats(x) (0UL) #endif /* HAVE_BATS */ +#ifdef CONFIG_PTE_64BIT void * -ioremap(unsigned long addr, unsigned long size) +ioremap(phys_addr_t addr, unsigned long size) +{ + phys_addr_t addr64 = fixup_bigphys_addr(addr, size);; + + return ioremap64(addr64, size); +} + +void * +ioremap64(unsigned long long addr, unsigned long size) { return __ioremap(addr, size, _PAGE_NO_CACHE); } +#else /* !CONFIG_PTE_64BIT */ + void * -__ioremap(unsigned long addr, unsigned long size, unsigned long flags) +ioremap(phys_addr_t addr, unsigned long size) { - unsigned long p, v, i; + return __ioremap(addr, size, _PAGE_NO_CACHE); +} +#endif /* CONFIG_PTE_64BIT */ + +void * +__ioremap(phys_addr_t addr, unsigned long size, unsigned long flags) +{ + unsigned long v, i; + phys_addr_t p; int err; /* @@ -101,7 +121,7 @@ */ if ( mem_init_done && (p < virt_to_phys(high_memory)) ) { - printk("__ioremap(): phys addr %0lx is RAM lr %p\n", p, + printk("__ioremap(): phys addr "PTE_FMT" is RAM lr %p\n", p, __builtin_return_address(0)); return NULL; } @@ -122,7 +142,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); @@ -152,7 +172,7 @@ } out: - return (void *) (v + (addr & ~PAGE_MASK)); + return (void *) (v + ((unsigned long)addr & ~PAGE_MASK)); } void iounmap(void *addr) @@ -168,7 +188,7 @@ } int -map_page(unsigned long va, unsigned long pa, int flags) +map_page(unsigned long va, phys_addr_t pa, int flags) { pmd_t *pd; pte_t *pg; @@ -193,13 +213,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 +244,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; @@ -238,7 +258,7 @@ printk(KERN_INFO "Memory BAT mapping: BAT2=%ldMb, BAT3=%ldMb," " residual: %ldMb\n", __bat2 >> 20, __bat3 >> 20, - (total_lowmem - (__bat2 - __bat3)) >> 20); + (total_lowmem - (__bat2 + __bat3)) >> 20); /* On SMP, we limit the lowmem to the area mapped with BATs. * We also assume nobody will do SMP with 601s @@ -278,11 +298,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 @@ -308,7 +328,7 @@ * virt, phys, size must all be page-aligned. * This should only be called before ioremap is called. */ -void __init io_block_mapping(unsigned long virt, unsigned long phys, +void __init io_block_mapping(unsigned long virt, phys_addr_t phys, unsigned int size, int flags) { int i; @@ -388,7 +408,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 +441,7 @@ goto exit; } } - + ret = (unsigned long) __va(paddr); } exit: Index: arch/ppc/mm/ppc_mmu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/mm/ppc_mmu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/mm/ppc_mmu.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/mm/ppc_mmu.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -3,11 +3,8 @@ * PowerPC implementations where the MMU substantially follows the * architecture specification. This includes the 6xx, 7xx, 7xxx, * 8260, and POWER3 implementations but excludes the 8xx and 4xx. - * Although the iSeries hardware does comply with the architecture - * 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 +83,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); } } @@ -181,6 +178,17 @@ #define MIN_N_HPTEG 1024 /* min 64kB hash table */ #endif +#ifdef CONFIG_POWER4 + /* The hash table has already been allocated and initialized + in prom.c */ + n_hpteg = Hash_size >> LG_HPTEG_SIZE; + lg_n_hpteg = __ilog2(n_hpteg); + + /* Remove the hash table from the available memory */ + if (Hash) + reserve_phys_mem(__pa(Hash), Hash_size); + +#else /* CONFIG_POWER4 */ /* * Allow 1 HPTE (1/8 HPTEG) for each page of memory. * This is less than the recommended amount, but then @@ -204,6 +212,7 @@ cacheable_memzero(Hash, Hash_size); _SDR1 = __pa(Hash) | SDR1_LOW_BITS; Hash_end = (PTE *) ((unsigned long)Hash + Hash_size); +#endif /* CONFIG_POWER4 */ printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n", total_memory >> 20, Hash_size >> 10, Hash); Index: arch/ppc/mm/tlb.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/mm/tlb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/mm/tlb.c 22 Jul 2004 19:48:59 -0000 1.1 +++ arch/ppc/mm/tlb.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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 } Index: arch/ppc/platforms/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/Makefile 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/Makefile 4 Aug 2004 01:26:09 -0000 1.2 @@ -26,8 +26,18 @@ O_TARGET := platform.o -export-objs := prep_setup.o +export-objs := prep_setup.o ibm440gp.o ibm440gx.o +obj-$(CONFIG_405GP) += ibm405gp.o +obj-$(CONFIG_440GP) += ibm440gp.o +obj-$(CONFIG_440GX) += ibm440gx.o + +obj-$(CONFIG_CPCI405) += cpci405.o +obj-$(CONFIG_EP405) += ep405.o +obj-$(CONFIG_REDWOOD_5) += redwood5.o ibmstb4.o +obj-$(CONFIG_REDWOOD_6) += redwood6.o ibmstbx25.o +obj-$(CONFIG_EBONY) += ebony.o +obj-$(CONFIG_OCOTEA) += ocotea.o obj-$(CONFIG_WALNUT) += walnut.o obj-$(CONFIG_APUS) += apus_setup.o @@ -46,6 +56,9 @@ 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_PRPMC750) += prpmc750.o +obj-$(CONFIG_SANDPOINT) += sandpoint.o obj-$(CONFIG_SPRUCE) += spruce_setup.o spruce_pci.o cpc700_pic.o ifeq ($(CONFIG_SMP),y) Index: arch/ppc/platforms/apus_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/apus_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/apus_pci.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/apus_pci.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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 */ Index: arch/ppc/platforms/chrp_setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/chrp_setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/chrp_setup.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/chrp_setup.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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); } Index: arch/ppc/platforms/chrp_smp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/chrp_smp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/chrp_smp.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/chrp_smp.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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. */ Index: arch/ppc/platforms/chrp_time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/chrp_time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/chrp_time.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/chrp_time.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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++) { Index: arch/ppc/platforms/cpc700.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/cpc700.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/cpc700.h 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/cpc700.h 4 Aug 2004 01:26:09 -0000 1.2 @@ -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 *); Index: arch/ppc/platforms/cpc700_pic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/cpc700_pic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/cpc700_pic.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/cpc700_pic.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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; Index: arch/ppc/platforms/error_log.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/error_log.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/error_log.c 22 Jul 2004 19:49:01 -0000 1.1 +++ arch/ppc/platforms/error_log.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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]; Index: arch/ppc/platforms/error_log.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/error_log.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/error_log.h 22 Jul 2004 19:49:01 -0000 1.1 +++ arch/ppc/platforms/error_log.h 4 Aug 2004 01:26:09 -0000 1.2 @@ -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 Index: arch/ppc/platforms/est8260.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/est8260.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/est8260.h 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/est8260.h 4 Aug 2004 01:26:09 -0000 1.2 @@ -4,7 +4,7 @@ * the configuration SCMR and the Power-On-Reset word. */ -#define IMAP_ADDR ((uint)0xf0000000) +#define CPM_MAP_ADDR ((uint)0xf0000000) /* A Board Information structure that is given to a program when Index: arch/ppc/platforms/gemini.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/gemini.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/gemini.h 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/gemini.h 4 Aug 2004 01:26:09 -0000 1.2 @@ -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. * */ Index: arch/ppc/platforms/gemini_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/gemini_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/gemini_pci.c 22 Jul 2004 19:49:01 -0000 1.1 +++ arch/ppc/platforms/gemini_pci.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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(); Index: arch/ppc/platforms/gemini_prom.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/gemini_prom.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/gemini_prom.S 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/gemini_prom.S 4 Aug 2004 01:26:09 -0000 1.2 @@ -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 Index: arch/ppc/platforms/gemini_serial.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/gemini_serial.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/gemini_serial.h 22 Jul 2004 19:49:01 -0000 1.1 +++ arch/ppc/platforms/gemini_serial.h 4 Aug 2004 01:26:09 -0000 1.2 @@ -15,11 +15,11 @@ #define BASE_BAUD (24576000 / 16) #ifdef CONFIG_SERIAL_DETECT_IRQ -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ) #define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ) #else -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) -#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF) +#define STD_COM_FLAGS ASYNC_BOOT_AUTOCONF +#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF #endif #define STD_SERIAL_PORT_DEFNS \ Index: arch/ppc/platforms/gemini_setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/gemini_setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/gemini_setup.c 22 Jul 2004 19:49:01 -0000 1.1 +++ arch/ppc/platforms/gemini_setup.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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; } Index: arch/ppc/platforms/lopec_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/lopec_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/lopec_pci.c 22 Jul 2004 19:49:01 -0000 1.1 +++ arch/ppc/platforms/lopec_pci.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -1,6 +1,6 @@ /* * arch/ppc/platforms/lopec_pci.c - * + * * PCI setup routines for the Motorola LoPEC. * * Author: Dan Cox Index: arch/ppc/platforms/lopec_serial.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/lopec_serial.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/lopec_serial.h 22 Jul 2004 19:49:01 -0000 1.1 +++ arch/ppc/platforms/lopec_serial.h 4 Aug 2004 01:26:09 -0000 1.2 @@ -33,7 +33,7 @@ #define STD_UART_OP(num) \ { 0, BASE_BAUD, UART##num##_PORT, UART##num##_INT, \ - (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST), \ + ASYNC_BOOT_AUTOCONF, \ iomem_base: UART##num##_IO_BASE, \ io_type: SERIAL_IO_MEM }, Index: arch/ppc/platforms/lopec_setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/lopec_setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/lopec_setup.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/lopec_setup.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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); @@ -299,7 +299,7 @@ serial_req.line = 0; serial_req.baud_base = BASE_BAUD; serial_req.irq = UART0_INT; - serial_req.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + serial_req.flags = ASYNC_BOOT_AUTOCONF; serial_req.io_type = SERIAL_IO_MEM; serial_req.iomem_base = ioremap(UART0_PORT, 8); @@ -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 */ Index: arch/ppc/platforms/pal4.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/pal4.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/pal4.h 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/pal4.h 4 Aug 2004 01:26:09 -0000 1.2 @@ -1,6 +1,6 @@ /* * arch/ppc/platforms/pal4.h - * + * * Definitions for SBS Palomar IV board * * Author: Dan Cox Index: arch/ppc/platforms/pal4_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/pal4_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/pal4_pci.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/pal4_pci.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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; Index: arch/ppc/platforms/pal4_serial.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/pal4_serial.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/pal4_serial.h 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/pal4_serial.h 4 Aug 2004 01:26:09 -0000 1.2 @@ -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 * @@ -20,19 +20,11 @@ #define RS_TABLE_SIZE 2 #define BASE_BAUD (33333333 / 4 / 16) -#ifdef CONFIG_SERIAL_DETECT_IRQ -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) -#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ) -#else -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) -#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF) -#endif - #define SERIAL_PORT_DFNS \ - {0, BASE_BAUD, CPC700_SERIAL_1, 3, STD_COM_FLAGS, \ + {0, BASE_BAUD, CPC700_SERIAL_1, 3, ASYNC_BOOT_AUTOCONF, \ iomem_base: (unsigned char *) CPC700_SERIAL_1, \ io_type: SERIAL_IO_MEM}, /* ttyS0 */ \ - {0, BASE_BAUD, CPC700_SERIAL_2, 4, STD_COM_FLAGS, \ + {0, BASE_BAUD, CPC700_SERIAL_2, 4, ASYNC_BOOT_AUTOCONF, \ iomem_base: (unsigned char *) CPC700_SERIAL_2, \ io_type: SERIAL_IO_MEM} Index: arch/ppc/platforms/pal4_setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/pal4_setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/pal4_setup.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/pal4_setup.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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; Index: arch/ppc/platforms/pmac_backlight.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/pmac_backlight.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/pmac_backlight.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/pmac_backlight.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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) Index: arch/ppc/platforms/pmac_feature.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/pmac_feature.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/pmac_feature.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/pmac_feature.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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); Index: arch/ppc/platforms/pmac_nvram.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/pmac_nvram.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/pmac_nvram.c 22 Jul 2004 19:49:01 -0000 1.1 +++ arch/ppc/platforms/pmac_nvram.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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) { Index: arch/ppc/platforms/pmac_pic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/pmac_pic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/pmac_pic.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/pmac_pic.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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", Index: arch/ppc/platforms/pmac_setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/pmac_setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/pmac_setup.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/pmac_setup.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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 Index: arch/ppc/platforms/pmac_sleep.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/pmac_sleep.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/pmac_sleep.S 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/pmac_sleep.S 4 Aug 2004 01:26:09 -0000 1.2 @@ -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) Index: arch/ppc/platforms/pmac_smp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/pmac_smp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/pmac_smp.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/pmac_smp.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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(); Index: arch/ppc/platforms/pmac_time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/pmac_time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/pmac_time.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/pmac_time.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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; } Index: arch/ppc/platforms/prep_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/prep_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/prep_pci.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/prep_pci.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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; @@ -1141,8 +1141,6 @@ prep_pcibios_fixup(void) { struct pci_dev *dev; - extern unsigned char *Motherboard_map; - extern unsigned char *Motherboard_routes; prep_route_pci_interrupts(); @@ -1183,7 +1181,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 +1189,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 +1211,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 +1261,7 @@ hose->ops = &prep_pci_ops; printk("PReP architecture\n"); -#ifdef CONFIG_PREP_RESIDUAL +#ifdef CONFIG_PREP_RESIDUAL { PPC_DEVICE *hostbridge; @@ -1277,7 +1275,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 Index: arch/ppc/platforms/prep_setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/prep_setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/prep_setup.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/prep_setup.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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; Index: arch/ppc/platforms/prep_time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/prep_time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/prep_time.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/prep_time.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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++) { Index: arch/ppc/platforms/proc_rtas.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/proc_rtas.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/proc_rtas.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/proc_rtas.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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; } Index: arch/ppc/platforms/residual.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/residual.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/residual.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/residual.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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; }; Index: arch/ppc/platforms/spd8xx.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/spd8xx.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/spd8xx.h 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/spd8xx.h 4 Aug 2004 01:26:09 -0000 1.2 @@ -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 */ Index: arch/ppc/platforms/spruce.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/spruce.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/spruce.h 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/spruce.h 4 Aug 2004 01:26:09 -0000 1.2 @@ -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) @@ -70,7 +70,7 @@ #define STD_UART_OP(num) \ { 0, BASE_BAUD, 0, UART##num##_INT, \ - (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ + ASYNC_BOOT_AUTOCONF, \ iomem_base: UART##num##_IO_BASE, \ io_type: SERIAL_IO_MEM}, Index: arch/ppc/platforms/spruce_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/spruce_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/spruce_pci.c 22 Jul 2004 19:49:01 -0000 1.1 +++ arch/ppc/platforms/spruce_pci.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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; Index: arch/ppc/platforms/spruce_setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/spruce_setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/spruce_setup.c 22 Jul 2004 19:49:01 -0000 1.1 +++ arch/ppc/platforms/spruce_setup.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -132,7 +132,7 @@ serial_req.line = 0; serial_req.port = 0; serial_req.irq = 3; - serial_req.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + serial_req.flags = ASYNC_BOOT_AUTOCONF; serial_req.io_type = SERIAL_IO_MEM; serial_req.iomem_base = (u_char *)UART0_IO_BASE; serial_req.iomem_reg_shift = 0; Index: arch/ppc/platforms/tqm8xx.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/tqm8xx.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/tqm8xx.h 22 Jul 2004 19:49:01 -0000 1.1 +++ arch/ppc/platforms/tqm8xx.h 4 Aug 2004 01:26:09 -0000 1.2 @@ -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 */ Index: arch/ppc/platforms/walnut.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/walnut.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/walnut.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/walnut.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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; } Index: arch/ppc/platforms/walnut.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/platforms/walnut.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/platforms/walnut.h 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/platforms/walnut.h 4 Aug 2004 01:26:09 -0000 1.2 @@ -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__ + +/* 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. + */ -#include -#include +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 -#ifdef __cplusplus -extern "C" { -#endif - -extern unsigned char __res[sizeof(bd_t)]; +/* Memory map for the IBM "Walnut" 405GP evaluation board. + * Generic 4xx plus RTC. + */ -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); +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 +#define WALNUT_PS2_BASE 0xF0100000 +#define WALNUT_FPGA_BASE 0xF0300000 -#ifdef __cplusplus -} -#endif -#endif /* __WALNUT_SETUP_H__ */ +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__ */ Index: arch/ppc/xmon/ppc-opc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/xmon/ppc-opc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/xmon/ppc-opc.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/xmon/ppc-opc.c 4 Aug 2004 01:26:09 -0000 1.2 @@ -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; Index: arch/ppc/xmon/start.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/xmon/start.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/xmon/start.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/xmon/start.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -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; Index: arch/ppc/xmon/start_8xx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/xmon/start_8xx.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/xmon/start_8xx.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/xmon/start_8xx.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -46,7 +46,7 @@ cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); use_screen = 0; - + prom_drawstring("xmon uses serial port\n"); } Index: arch/ppc/xmon/xmon.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc/xmon/xmon.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc/xmon/xmon.c 22 Jul 2004 19:49:00 -0000 1.1 +++ arch/ppc/xmon/xmon.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -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; -} +} Index: arch/ppc64/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/Makefile 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/Makefile 4 Aug 2004 01:26:10 -0000 1.2 @@ -19,6 +19,13 @@ CHECKS = checks endif +HAS_BIARCH := $(shell if $(CC) -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 := $(CC) -m64 +endif + LINKFLAGS = -T arch/ppc64/vmlinux.lds -Bstatic \ -e $(KERNELLOAD) -Ttext $(KERNELLOAD) CFLAGS := $(CFLAGS) -fsigned-char -msoft-float -pipe \ @@ -26,6 +33,11 @@ -mtraceback=full CPP = $(CC) -E $(CFLAGS) +HAVE_ZERO_BSS := $(shell if $(CC) -fno-zero-initialized-in-bss -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi) + +ifeq ($(HAVE_ZERO_BSS),y) +CFLAGS += -fno-zero-initialized-in-bss +endif HEAD := arch/ppc64/kernel/head.o @@ -38,10 +50,6 @@ SUBDIRS += arch/ppc64/xmon CORE_FILES += arch/ppc64/xmon/x.o endif -ifdef CONFIG_KDB -SUBDIRS += arch/ppc64/kdb -CORE_FILES += arch/ppc64/kdb/kdba.o -endif MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot Index: arch/ppc64/config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/config.in 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/config.in 4 Aug 2004 01:26:10 -0000 1.2 @@ -25,10 +25,11 @@ choice 'Machine Type' \ "pSeries CONFIG_PPC_PSERIES \ iSeries CONFIG_PPC_ISERIES" CONFIG_PPC_PSERIES - +bool 'VMX ( AltiVec ) Support' CONFIG_ALTIVEC bool 'Symmetric multi-processing support' CONFIG_SMP if [ "$CONFIG_SMP" = "y" ]; then bool ' Distribute interrupts on all CPUs by default' CONFIG_IRQ_ALL_CPUS + int 'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32 if [ "$CONFIG_PPC_PSERIES" = "y" ]; then bool ' Hardware multithreading' CONFIG_HMT fi @@ -39,8 +40,15 @@ 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 + +bool 'LPAR Configuration Data' CONFIG_LPARCFG endmenu @@ -114,7 +122,6 @@ 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 @@ -136,7 +143,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,20 +238,16 @@ source lib/Config.in +source crypto/Config.in + mainmenu_option next_comment comment 'Kernel hacking' bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ bool 'Include kgdb kernel debugger' CONFIG_KGDB bool 'Include xmon kernel debugger' CONFIG_XMON -bool 'Include kdb kernel debugger' CONFIG_KDB -if [ "$CONFIG_KDB" = "y" ]; then - bool ' KDB off by default' CONFIG_KDB_OFF - define_bool CONFIG_KALLSYMS y - define_bool CONFIG_XMON n -fi +bool 'Debug memory allocations' CONFIG_DEBUG_SLAB if [ "$CONFIG_XMON" = "y" ]; then - define_bool CONFIG_KDB n define_bool CONFIG_KALLSYMS n fi bool 'Include PPCDBG realtime debugging' CONFIG_PPCDBG @@ -254,4 +257,7 @@ dep_bool ' LKCD RLE compression' CONFIG_DUMP_COMPRESS_RLE $CONFIG_DUMP dep_bool ' LKCD GZIP compression' CONFIG_DUMP_COMPRESS_GZIP $CONFIG_DUMP fi + +int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 + endmenu Index: arch/ppc64/defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/defconfig 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/defconfig 4 Aug 2004 01:26:10 -0000 1.2 @@ -21,12 +21,18 @@ CONFIG_SERIAL_CONSOLE=y CONFIG_PPC_PSERIES=y # CONFIG_PPC_ISERIES is not set +CONFIG_ALTIVEC=y CONFIG_SMP=y CONFIG_IRQ_ALL_CPUS=y +CONFIG_NR_CPUS=32 # CONFIG_HMT is not set # 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 +CONFIG_LPARCFG=y # # Loadable module support @@ -73,6 +79,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y @@ -115,6 +122,12 @@ CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -190,7 +203,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 +217,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 @@ -224,7 +235,6 @@ # CONFIG_IDEDMA_AUTO is not set # 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 @@ -266,12 +276,14 @@ # 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_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -355,12 +367,14 @@ # 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=y # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -379,7 +393,6 @@ # 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 +405,7 @@ CONFIG_ACENIC_OMIT_TIGON_I=y # CONFIG_DL2K is not set CONFIG_E1000=y +CONFIG_E1000_NAPI=y # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set @@ -418,6 +432,10 @@ # CONFIG_IBMLS is not set # CONFIG_3C359 is not set # CONFIG_TMS380TR is not set +# CONFIG_TMSPCI is not set +# CONFIG_TMSISA is not set +# CONFIG_ABYSS is not set +# CONFIG_MADGEMC is not set # CONFIG_NET_FC is not set # CONFIG_RCPCI is not set # CONFIG_SHAPER is not set @@ -467,12 +485,15 @@ 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=y +CONFIG_FB_MATROX_G100=y +CONFIG_FB_MATROX_PROC=y # 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 @@ -500,6 +521,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set CONFIG_VIOPATH=y # @@ -553,6 +575,7 @@ # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200 is not set # CONFIG_SCx200_GPIO is not set # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set @@ -566,12 +589,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # 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 is not set CONFIG_REISERFS_FS=y @@ -581,6 +609,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 @@ -622,6 +651,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -630,6 +664,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=y CONFIG_NFSD_V3=y @@ -716,19 +751,29 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET 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 + +# # Kernel hacking # 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_DEBUG_SLAB is not set CONFIG_PPCDBG=y # CONFIG_DUMP is not set +CONFIG_LOG_BUF_SHIFT=0 Index: arch/ppc64/vmlinux.lds =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/vmlinux.lds,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/vmlinux.lds 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/vmlinux.lds 4 Aug 2004 01:26:10 -0000 1.2 @@ -73,6 +73,10 @@ __kallsyms : { *(__kallsyms) } __stop___kallsyms = .; + . = ALIGN(16); + __start___ftr_fixup = .; + __ftr_fixup : { *(__ftr_fixup) } + __stop___ftr_fixup = .; . = ALIGN(4096); .data.page_aligned : { *(.data.page_aligned) } Index: arch/ppc64/boot/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/boot/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/boot/Makefile 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/boot/Makefile 4 Aug 2004 01:26:10 -0000 1.2 @@ -31,6 +31,10 @@ OBJCOPYFLAGS = contents,alloc,load,readonly,data +LDVARS= \ + --defsym _vmlinux_memsize=0x`$(CROSS_COMPILE)nm -n $(TOPDIR)/vmlinux | sed '$$s/^........\([^ ]*\).*/\1/p;d'` \ + --defsym _vmlinux_filesize=0x`ls -l $(TOPDIR)/vmlinux | awk '{ printf "%x\n", $$5 }'` + .c.o: $(BOOTCC) $(BOOTCFLAGS) -c -o $*.o $< .S.o: @@ -39,7 +43,7 @@ CFLAGS = $(CPPFLAGS) -O -fno-builtin -DSTDC_HEADERS LD_ARGS = -Ttext 0x00400000 -e _start -OBJS = crt0.o string.o prom.o zImage.o zlib.o imagesize.o +OBJS = crt0.o string.o prom.o zImage.o zlib.o LIBS = ifeq ($(CONFIG_SMP),y) @@ -52,7 +56,7 @@ ifeq ($(CONFIG_PPC_ISERIES),y) all: vmlinux.sm else -all: $(TOPDIR)/zImage +all: zImage endif @@ -88,13 +92,14 @@ $(HOSTCC) $(HOSTCFLAGS) -o addnote addnote.c -imagesize.c: $(TOPDIR)/vmlinux - ls -l $(TOPDIR)/vmlinux | awk '{printf "/* generated -- do not edit! */\nunsigned long vmlinux_filesize = %d;\n", $$5}' > imagesize.c - $(CROSS_COMPILE)nm -n $(TOPDIR)/vmlinux | awk '{i=$$1}END{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr(i,8)}' >> imagesize.c - zImage.o: $(TOPDIR)/vmlinux -vmlinux .config System.map: % : $(TOPDIR)/% +uts_string: uts_string.txt + $(OBJCOPY) zImage.o \ + --add-section=.kernel:$@=$@.txt \ + --set-section-flags=.kernel:$@=$(OBJCOPYFLAGS) + +vmlinux .config System.map: % : $(TOPDIR)/% zImage.o gzip -cvf9 $(TOPDIR)/$@ > kernel-$@.gz $(OBJCOPY) zImage.o \ --add-section=.kernel:$@=kernel-$@.gz \ @@ -105,17 +110,23 @@ --add-section=.kernel:$@=ramdisk.image.gz \ --set-section-flags=.kernel:$@=$(OBJCOPYFLAGS) -zImage: $(OBJS) addnote vmlinux .config System.map - $(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) $(LIBS) +uts_string.txt: $(TOPDIR)/vmlinux + strings $(TOPDIR)/vmlinux | \ + grep -E 'Linux version .* .gcc version' > $@ + +zImage: $(OBJS) addnote uts_string vmlinux .config System.map + $(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) $(LIBS) \ + $(LDVARS) ./addnote $@ -zImage.initrd: $(OBJS) addnote vmlinux .config System.map initrd - $(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) $(LIBS) +zImage.initrd: $(OBJS) addnote uts_string vmlinux .config System.map initrd + $(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) $(LIBS) \ + $(LDVARS) ./addnote $@ clean: rm -f add{note,RamDisk,SystemMap} $(OBJS) initrd.o \ - vmlinux.{sm,initrd} zImage{,.initrd} imagesize.c \ + vmlinux.{sm,initrd} zImage{,.initrd} uts_string.txt \ kernel-{vmlinux,.config,System.map}.gz fastdep: Index: arch/ppc64/boot/addRamDisk.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/boot/addRamDisk.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/boot/addRamDisk.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/boot/addRamDisk.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -259,7 +259,7 @@ death("Could not read hvReleaseData\n", outputVmlinux, argv[4]); } /* Check hvReleaseData sanity */ - if (memcmp(inbuf, &eyeCatcher, 4) != 0) { + if (ntohl(*(u_int32_t *)inbuf) != eyeCatcher) { death("hvReleaseData is invalid\n", outputVmlinux, argv[4]); } /* Get the naca pointer */ Index: arch/ppc64/boot/addnote.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/boot/addnote.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/boot/addnote.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/boot/addnote.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -14,6 +14,7 @@ * Usage: addnote zImage */ #include +#include #include #include #include Index: arch/ppc64/boot/ppc32-types.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/boot/ppc32-types.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/boot/ppc32-types.h 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/boot/ppc32-types.h 4 Aug 2004 01:26:10 -0000 1.2 @@ -27,4 +27,10 @@ #define BITS_PER_LONG 32 +typedef struct { + __u32 u[4]; +} __attribute((aligned(16))) __vector128; + +typedef __vector128 vector128; + #endif /* _PPC64_TYPES_H */ Index: arch/ppc64/boot/zImage.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/boot/zImage.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/boot/zImage.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/boot/zImage.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -12,7 +12,6 @@ #include "ppc32-types.h" #include "zlib.h" #include -#include #include #include #include @@ -53,8 +52,9 @@ extern char _sysmap_end[]; extern char _initrd_start[]; extern char _initrd_end[]; -extern unsigned long vmlinux_filesize; -extern unsigned long vmlinux_memsize; + +extern void *_vmlinux_filesize; +extern void *_vmlinux_memsize; struct addr_range { unsigned long addr; @@ -69,8 +69,8 @@ static char scratch[128<<10]; /* 128kB of scratch space for gunzip */ typedef void (*kernel_entry_t)( unsigned long, - unsigned long, - void *, + unsigned long, + void *, struct bi_record *); @@ -86,13 +86,12 @@ start(unsigned long a1, unsigned long a2, void *promptr) { unsigned long i, claim_addr, claim_size; + unsigned long vmlinux_filesize; extern char _start; struct bi_record *bi_recs; kernel_entry_t kernel_entry; Elf64_Ehdr *elf64; Elf64_Phdr *elf64ph; - /* tell userland tools about uname -r */ - unsigned char this_uts[] = "Linux version " UTS_RELEASE; prom = (int (*)(void *)) promptr; chosen_handle = finddevice("/chosen"); @@ -104,20 +103,7 @@ if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) exit(); - printf("zImage starting: loaded at 0x%x\n\r", (unsigned)&_start); - printf("%s\n\r", this_uts); - -#if 0 - sysmap.size = (unsigned long)(_sysmap_end - _sysmap_start); - sysmap.memsize = sysmap.size; - if ( sysmap.size > 0 ) { - sysmap.addr = (RAM_END - sysmap.size) & ~0xFFF; - claim(sysmap.addr, RAM_END - sysmap.addr, 0); - printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r", - sysmap.addr, (unsigned long)_sysmap_start, sysmap.size); - memcpy((void *)sysmap.addr, (void *)_sysmap_start, sysmap.size); - } -#endif + printf("\n\rzImage starting: loaded at 0x%x\n\r", (unsigned)&_start); initrd.size = (unsigned long)(_initrd_end - _initrd_start); initrd.memsize = initrd.size; @@ -133,12 +119,13 @@ vmlinuz.addr = (unsigned long)_vmlinux_start; vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start); vmlinux.addr = (unsigned long)(void *)-1; + vmlinux_filesize = (unsigned long)&_vmlinux_filesize; vmlinux.size = PAGE_ALIGN(vmlinux_filesize); - vmlinux.memsize = vmlinux_memsize; + vmlinux.memsize = (unsigned long)&_vmlinux_memsize; claim_size = vmlinux.memsize /* PPPBBB: + fudge for bi_recs */; - for(claim_addr = PROG_START; - claim_addr <= PROG_START * 8; + for(claim_addr = PROG_START; + claim_addr <= PROG_START * 8; claim_addr += 0x100000) { printf(" trying: 0x%08lx\n\r", claim_addr); vmlinux.addr = (unsigned long)claim(claim_addr, claim_size, 0); Index: arch/ppc64/boot/zImage.lds =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/boot/zImage.lds,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/boot/zImage.lds 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/boot/zImage.lds 4 Aug 2004 01:26:10 -0000 1.2 @@ -58,6 +58,8 @@ CONSTRUCTORS } + .kernel:uts_string : { *(.kernel:uts_string) } + . = ALIGN(4096); _vmlinux_start = .; .kernel:vmlinux : { *(.kernel:vmlinux) } Index: arch/ppc64/boot/zlib.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/boot/zlib.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/boot/zlib.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/boot/zlib.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -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. Index: arch/ppc64/configs/iSeries_devfs_defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/configs/iSeries_devfs_defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/configs/iSeries_devfs_defconfig 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/configs/iSeries_devfs_defconfig 4 Aug 2004 01:26:10 -0000 1.2 @@ -21,9 +21,13 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_PPC_PSERIES is not set CONFIG_PPC_ISERIES=y +# CONFIG_ALTIVEC is not set CONFIG_SMP=y CONFIG_IRQ_ALL_CPUS=y +CONFIG_NR_CPUS=32 CONFIG_MSCHUNKS=y +# CONFIG_SHARED_MEMORY_ADDRESSING is not set +CONFIG_LPARCFG=y # # Loadable module support @@ -40,6 +44,7 @@ # CONFIG_MCA is not set # CONFIG_EISA is not set CONFIG_PCI=y +# CONFIG_PCMCIA is not set CONFIG_NET=y CONFIG_SYSCTL=y CONFIG_SYSVIPC=y @@ -50,7 +55,6 @@ CONFIG_BINFMT_MISC=y CONFIG_PCI_NAMES=y # CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set # # Parallel port support @@ -58,18 +62,6 @@ # 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 -# CONFIG_PNPBIOS is not set - -# # Block devices # # CONFIG_BLK_DEV_FD is not set @@ -77,12 +69,16 @@ # 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_CISS_MONITOR_THREAD 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 +# CONFIG_BLK_STATS is not set # # Multi-device support (RAID and LVM) @@ -101,8 +97,6 @@ # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -CONFIG_NETLINK=y -# CONFIG_RTNETLINK is not set # CONFIG_NETLINK_DEV is not set # CONFIG_NETFILTER is not set # CONFIG_FILTER is not set @@ -117,17 +111,30 @@ # 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=y # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP 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 @@ -143,7 +150,16 @@ # QoS and/or fair queueing # # CONFIG_NET_SCHED is not set -# CONFIG_BLK_DEV_IDE_MODES is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set # CONFIG_BLK_DEV_HD is not set # @@ -180,13 +196,16 @@ # 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_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -201,6 +220,7 @@ # 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 @@ -216,9 +236,8 @@ # 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 -# CONFIG_SCSI_MESH is not set -# CONFIG_SCSI_MAC53C94 is not set # # IEEE 1394 (FireWire) support (EXPERIMENTAL) @@ -247,12 +266,10 @@ # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set -# CONFIG_OAKNET is not set # CONFIG_SUNLANCE is not set # CONFIG_HAPPYMEAL is not set # CONFIG_SUNBMAC is not set # CONFIG_SUNQE is not set -# CONFIG_SUNLANCE is not set # CONFIG_SUNGEM is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -262,14 +279,18 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y CONFIG_PCNET32=m +# 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 @@ -281,11 +302,14 @@ # 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_NET_POCKET is not set @@ -295,11 +319,15 @@ CONFIG_ACENIC=m # CONFIG_ACENIC_OMIT_TIGON_I 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_VETH=y # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set @@ -317,7 +345,12 @@ CONFIG_TR=y CONFIG_IBMOL=m # CONFIG_IBMLS is not set +# CONFIG_3C359 is not set # CONFIG_TMS380TR is not set +# CONFIG_TMSPCI is not set +# CONFIG_TMSISA is not set +# CONFIG_ABYSS is not set +# CONFIG_MADGEMC is not set # CONFIG_NET_FC is not set # CONFIG_RCPCI is not set # CONFIG_SHAPER is not set @@ -333,11 +366,6 @@ # CONFIG_HAMRADIO is not set # -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# # ISDN subsystem # # CONFIG_ISDN is not set @@ -348,15 +376,6 @@ # CONFIG_CD_NO_IDESCSI is not set # -# Console drivers -# - -# -# Frame-buffer support -# -# CONFIG_FB is not set - -# # iSeries device drivers # CONFIG_VIOCONS=y @@ -386,6 +405,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 @@ -442,12 +462,19 @@ # 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_INTEL_RNG is not set +# CONFIG_SCx200 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 @@ -459,22 +486,33 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set -# CONFIG_MWAVE 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=y # CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_PROC_INFO=y # 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 @@ -484,11 +522,14 @@ # 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=y CONFIG_JOLIET=y -# CONFIG_MINIX_FS 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 @@ -507,16 +548,24 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG 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=m CONFIG_NFSD_V3=y +CONFIG_NFSD_TCP=y CONFIG_SUNRPC=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y @@ -530,6 +579,7 @@ # 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 @@ -564,6 +614,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=y # CONFIG_NLS_ISO8859_2 is not set @@ -581,114 +632,16 @@ # CONFIG_NLS_UTF8 is not set # -# Sound -# -# CONFIG_SOUND 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 - -# -# USB Device Class drivers -# -# 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 - -# -# USB Human Interface Devices (HID) -# -# CONFIG_USB_HID 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 - -# -# 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 -# -# 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 - -# -# 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 +# Library routines # -# 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_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_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_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set # -# USB Miscellaneous drivers +# Cryptographic options # -# CONFIG_USB_RIO500 is not set +# CONFIG_CRYPTO is not set # # Kernel hacking @@ -696,10 +649,7 @@ # CONFIG_MAGIC_SYSRQ is not set # CONFIG_KGDB is not set # CONFIG_XMON is not set -# CONFIG_KDB is not set -# CONFIG_KDB_OFF is not set -# CONFIG_KALLSYMS is not set +# CONFIG_DEBUG_SLAB 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_LOG_BUF_SHIFT=0 Index: arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig 4 Aug 2004 01:26:10 -0000 1.2 @@ -21,9 +21,13 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_PPC_PSERIES is not set CONFIG_PPC_ISERIES=y +# CONFIG_ALTIVEC is not set CONFIG_SMP=y CONFIG_IRQ_ALL_CPUS=y +CONFIG_NR_CPUS=32 CONFIG_MSCHUNKS=y +# CONFIG_SHARED_MEMORY_ADDRESSING is not set +CONFIG_LPARCFG=y # # Loadable module support @@ -40,6 +44,7 @@ # CONFIG_MCA is not set # CONFIG_EISA is not set CONFIG_PCI=y +# CONFIG_PCMCIA is not set CONFIG_NET=y CONFIG_SYSCTL=y CONFIG_SYSVIPC=y @@ -50,7 +55,6 @@ CONFIG_BINFMT_MISC=y CONFIG_PCI_NAMES=y # CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set # # Parallel port support @@ -58,17 +62,6 @@ # 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 @@ -77,12 +70,15 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD 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=64000 CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_STATS is not set # # Multi-device support (RAID and LVM) @@ -113,7 +109,6 @@ CONFIG_IP_ROUTE_MULTIPATH=y CONFIG_IP_ROUTE_TOS=y CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_ROUTE_LARGE_TABLES=y CONFIG_IP_PNP=y # CONFIG_IP_PNP_DHCP is not set # CONFIG_IP_PNP_BOOTP is not set @@ -129,6 +124,12 @@ CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -167,7 +168,6 @@ # 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 # @@ -206,12 +206,14 @@ # 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_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -242,6 +244,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 # @@ -284,15 +287,18 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y CONFIG_PCNET32=m +# 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 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 @@ -304,10 +310,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 @@ -320,12 +327,15 @@ CONFIG_ACENIC=m # CONFIG_ACENIC_OMIT_TIGON_I 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_VETH=y # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set @@ -345,6 +355,10 @@ # CONFIG_IBMLS is not set # CONFIG_3C359 is not set # CONFIG_TMS380TR is not set +# CONFIG_TMSPCI is not set +# CONFIG_TMSISA is not set +# CONFIG_ABYSS is not set +# CONFIG_MADGEMC is not set # CONFIG_NET_FC is not set # CONFIG_RCPCI is not set # CONFIG_SHAPER is not set @@ -360,11 +374,6 @@ # CONFIG_HAMRADIO is not set # -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# # ISDN subsystem # # CONFIG_ISDN is not set @@ -386,24 +395,6 @@ # CONFIG_CDU535 is not set # -# Console drivers -# - -# -# Frame-buffer support -# -# CONFIG_FB 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 - -# # iSeries device drivers # CONFIG_VIOCONS=y @@ -432,8 +423,8 @@ # CONFIG_MOXA_INTELLIO is not set # CONFIG_MOXA_SMARTIO is not set # CONFIG_ISI is not set -CONFIG_ICOM=m # 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 @@ -468,11 +459,19 @@ # 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 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 @@ -484,12 +483,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # # File systems # CONFIG_QUOTA=y +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y CONFIG_REISERFS_FS=y @@ -499,6 +503,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=y CONFIG_JBD=y @@ -516,9 +523,10 @@ CONFIG_ISO9660_FS=y CONFIG_JOLIET=y # CONFIG_ZISOFS is not set -# CONFIG_MINIX_FS 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 @@ -537,6 +545,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -545,9 +558,11 @@ # 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=y CONFIG_NFSD_V3=y +CONFIG_NFSD_TCP=y CONFIG_SUNRPC=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y @@ -563,7 +578,6 @@ CONFIG_NCPFS_NLS=y CONFIG_NCPFS_EXTRAS=y # CONFIG_ZISOFS_FS is not set -# CONFIG_ZLIB_FS_INFLATE is not set # # Partition Types @@ -616,14 +630,16 @@ CONFIG_NLS_UTF8=y # -# Sound +# Library routines # -# CONFIG_SOUND is not set +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set # -# USB support +# Cryptographic options # -# CONFIG_USB is not set +# CONFIG_CRYPTO is not set # # Kernel hacking @@ -631,10 +647,7 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_KGDB is not set # CONFIG_XMON is not set -# CONFIG_KDB is not set -# CONFIG_KDB_OFF is not set -# CONFIG_KALLSYMS is not set +# CONFIG_DEBUG_SLAB 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_LOG_BUF_SHIFT=0 Index: arch/ppc64/configs/pSeries_defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/configs/pSeries_defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/configs/pSeries_defconfig 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/configs/pSeries_defconfig 4 Aug 2004 01:26:10 -0000 1.2 @@ -21,12 +21,18 @@ CONFIG_SERIAL_CONSOLE=y CONFIG_PPC_PSERIES=y # CONFIG_PPC_ISERIES is not set +CONFIG_ALTIVEC=y CONFIG_SMP=y CONFIG_IRQ_ALL_CPUS=y +CONFIG_NR_CPUS=32 # CONFIG_HMT is not set # 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 +CONFIG_LPARCFG=y # # Loadable module support @@ -73,6 +79,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y @@ -115,6 +122,12 @@ CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -190,7 +203,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 +217,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 @@ -224,7 +235,6 @@ # CONFIG_IDEDMA_AUTO is not set # 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 @@ -266,12 +276,14 @@ # 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_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -355,12 +367,14 @@ # 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=y # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -379,7 +393,6 @@ # 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 +405,7 @@ CONFIG_ACENIC_OMIT_TIGON_I=y # CONFIG_DL2K is not set CONFIG_E1000=y +CONFIG_E1000_NAPI=y # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set @@ -418,6 +432,10 @@ # CONFIG_IBMLS is not set # CONFIG_3C359 is not set # CONFIG_TMS380TR is not set +# CONFIG_TMSPCI is not set +# CONFIG_TMSISA is not set +# CONFIG_ABYSS is not set +# CONFIG_MADGEMC is not set # CONFIG_NET_FC is not set # CONFIG_RCPCI is not set # CONFIG_SHAPER is not set @@ -467,12 +485,15 @@ 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=y +CONFIG_FB_MATROX_G100=y +CONFIG_FB_MATROX_PROC=y # 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 @@ -500,6 +521,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set CONFIG_VIOPATH=y # @@ -553,6 +575,7 @@ # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200 is not set # CONFIG_SCx200_GPIO is not set # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set @@ -566,12 +589,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # 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 is not set CONFIG_REISERFS_FS=y @@ -581,6 +609,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 @@ -622,6 +651,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -630,6 +664,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=y CONFIG_NFSD_V3=y @@ -716,19 +751,29 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET 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 + +# # Kernel hacking # 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_DEBUG_SLAB is not set CONFIG_PPCDBG=y # CONFIG_DUMP is not set +CONFIG_LOG_BUF_SHIFT=0 Index: arch/ppc64/kernel/HvCall.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/HvCall.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/HvCall.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/HvCall.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -1,7 +1,7 @@ /* * HvCall.c * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -60,7 +60,7 @@ curPtr = virt_to_absolute( (unsigned long) buffer ); for(i=0; i bytesLeft) { @@ -90,11 +90,11 @@ struct HvLpBufferList bufList; u64 bytesLeft = bufLen; u64 leftThisPage; - u64 curPtr = virt_to_absolute( (unsigned long) buffer ); + u64 curPtr = virt_to_absolute((unsigned long) buffer); while (bytesLeft) { bufList.addr = curPtr; - + leftThisPage = ((curPtr & PAGE_MASK) + PAGE_SIZE) - curPtr; if (leftThisPage > bytesLeft) { @@ -105,11 +105,11 @@ bytesLeft -= leftThisPage; } - curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE; - } - - HvCall2(HvCallBaseWriteLogBuffer, - virt_to_absolute((unsigned long)&bufList), bufLen); + HvCall2(HvCallBaseWriteLogBuffer, + virt_to_absolute((unsigned long) &bufList), + bufList.len); + curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE; + } } Index: arch/ppc64/kernel/LparData.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/LparData.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/LparData.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/LparData.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -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 }, Index: arch/ppc64/kernel/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/Makefile 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/Makefile 4 Aug 2004 01:26:10 -0000 1.2 @@ -17,7 +17,7 @@ O_TARGET := kernel.o -export-objs := ppc_ksyms.o setup.o +export-objs := ppc_ksyms.o setup.o vio.o viopath.o obj-y := ppc_ksyms.o setup.o entry.o traps.o irq.o idle.o \ time.o process.o signal.o syscalls.o misc.o ptrace.o \ @@ -27,23 +27,26 @@ 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 vio.o obj-$(CONFIG_PCI) += pci.o pci_dn.o pci_dma.o pSeries_lpar.o pSeries_hvCall.o ifeq ($(CONFIG_PPC_ISERIES),y) obj-$(CONFIG_PCI) += iSeries_pci.o iSeries_pci_reset.o iSeries_IoMmTable.o iSeries_irq.o iSeries_VpdInfo.o XmPciLpEvent.o +obj-$(CONFIG_VIOPATH) += viopath.o endif ifeq ($(CONFIG_PPC_PSERIES),y) obj-$(CONFIG_PCI) += pSeries_pci.o eeh.o -obj-y += rtasd.o nvram.o +obj-y += nvram.o rtasd.o endif obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o obj-$(CONFIG_SCANLOG) += scanlog.o +obj-$(CONFIG_LPARCFG) += lparcfg.o + obj-$(CONFIG_KGDB) += ppc-stub.o obj-$(CONFIG_SMP) += smp.o Index: arch/ppc64/kernel/XmPciLpEvent.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/XmPciLpEvent.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/XmPciLpEvent.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/XmPciLpEvent.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -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 { Index: arch/ppc64/kernel/align.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/align.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/align.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/align.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -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; Index: arch/ppc64/kernel/chrp_setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/chrp_setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/chrp_setup.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/chrp_setup.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -65,6 +65,7 @@ #include "open_pic.h" #include "xics.h" #include +#include extern volatile unsigned char *chrp_int_ack_special; @@ -81,18 +82,21 @@ extern void pckbd_init_hw(void); extern unsigned char pckbd_sysrq_xlate[128]; extern void openpic_init_IRQ(void); +extern void openpic_init_irq_desc(irq_desc_t *); extern void init_ras_IRQ(void); extern void find_and_init_phbs(void); extern void pSeries_pcibios_fixup(void); extern void iSeries_pcibios_fixup(void); +extern void pSeries_get_boot_time(struct rtc_time *rtc_time); extern void pSeries_get_rtc_time(struct rtc_time *rtc_time); extern int pSeries_set_rtc_time(struct rtc_time *rtc_time); void pSeries_calibrate_decr(void); -static void fwnmi_init(void); +static void machine_check_init(void); extern void SystemReset_FWNMI(void), MachineCheck_FWNMI(void); /* from head.S */ -int fwnmi_active; /* TRUE if an FWNMI handler is present */ +int fwnmi_active = 0; /* TRUE if an FWNMI handler is present */ +int check_exception_flag = 0; /* TRUE if a check-exception handler present */ kdev_t boot_dev; unsigned long virtPython0Facilities = 0; // python0 facility area (memory mapped io) (64-bit format) VIRTUAL address. @@ -136,7 +140,6 @@ void __init chrp_setup_arch(void) { - extern char cmd_line[]; struct device_node *root; unsigned int *opprop; @@ -155,11 +158,9 @@ ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); else #endif - ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */ + ROOT_DEV = to_kdev_t(0x0803); /* sda3 (sda1 is for the kernel or the bootloader) */ - printk("Boot arguments: %s\n", cmd_line); - - fwnmi_init(); + machine_check_init(); #ifndef CONFIG_PPC_ISERIES /* Find and initialize PCI host bridges */ @@ -201,20 +202,26 @@ } /* Initialize firmware assisted non-maskable interrupts if - * the firmware supports this feature. - * + * the firmware supports this feature. If it does not, + * look for the check-exception property. */ -static void __init fwnmi_init(void) +static void __init machine_check_init(void) { long ret; + int check_ex_token; int ibm_nmi_register = rtas_token("ibm,nmi-register"); - if (ibm_nmi_register == RTAS_UNKNOWN_SERVICE) - return; - ret = rtas_call(ibm_nmi_register, 2, 1, NULL, - __pa((unsigned long)SystemReset_FWNMI), - __pa((unsigned long)MachineCheck_FWNMI)); - if (ret == 0) - fwnmi_active = 1; + + if (ibm_nmi_register != RTAS_UNKNOWN_SERVICE) { + ret = rtas_call(ibm_nmi_register, 2, 1, NULL, + __pa((unsigned long)SystemReset_FWNMI), + __pa((unsigned long)MachineCheck_FWNMI)); + if (ret == 0) + fwnmi_active = 1; + } else { + check_ex_token = rtas_token("check-exception"); + if (check_ex_token != RTAS_UNKNOWN_SERVICE) + check_exception_flag = 1; + } } @@ -263,19 +270,23 @@ ppc_md.setup_residual = NULL; ppc_md.get_cpuinfo = chrp_get_cpuinfo; if(naca->interrupt_controller == IC_OPEN_PIC) { - ppc_md.init_IRQ = openpic_init_IRQ; + ppc_md.init_IRQ = openpic_init_IRQ; + ppc_md.init_irq_desc = openpic_init_irq_desc; ppc_md.get_irq = openpic_get_irq; } else { ppc_md.init_IRQ = xics_init_IRQ; + ppc_md.init_irq_desc = xics_init_irq_desc; ppc_md.get_irq = xics_get_irq; } ppc_md.init_ras_IRQ = init_ras_IRQ; #ifndef CONFIG_PPC_ISERIES ppc_md.pcibios_fixup = pSeries_pcibios_fixup; + ppc_md.log_error = pSeries_log_error; #else ppc_md.pcibios_fixup = NULL; // ppc_md.pcibios_fixup = iSeries_pcibios_fixup; + ppc_md.log_error = NULL; #endif @@ -286,7 +297,7 @@ ppc_md.halt = rtas_halt; ppc_md.time_init = NULL; - ppc_md.get_boot_time = pSeries_get_rtc_time; + ppc_md.get_boot_time = pSeries_get_boot_time; ppc_md.get_rtc_time = pSeries_get_rtc_time; ppc_md.set_rtc_time = pSeries_set_rtc_time; ppc_md.calibrate_decr = pSeries_calibrate_decr; @@ -305,6 +316,37 @@ 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, hypertas_len; + /* 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 |= + (firmware_features_table[i].val); + break; + } + } + hypertas_len = strlen(hypertas); + len -= hypertas_len +1; + hypertas+= hypertas_len +1; + } + } + + printk(KERN_INFO "firmware_features = 0x%lx\n", + cur_cpu_spec->firmware_features); } void __chrp @@ -315,6 +357,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 +374,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); Index: arch/ppc64/kernel/eeh.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/eeh.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/eeh.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/eeh.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -30,6 +30,7 @@ #include #include #include +#include #include "pci.h" #define BUID_HI(buid) ((buid) >> 32) @@ -114,6 +115,18 @@ ret = rtas_call(ibm_read_slot_reset_state, 3, 3, rets, dn->eeh_config_addr, BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid)); if (ret == 0 && rets[1] == 1 && rets[0] >= 2) { + unsigned char slot_err_buf[RTAS_ERROR_LOG_MAX]; + unsigned long slot_err_ret; + + memset(slot_err_buf, 0, RTAS_ERROR_LOG_MAX); + slot_err_ret = rtas_call(rtas_token("ibm,slot-error-detail"), + 8, 1, dn->eeh_config_addr, + BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid), + NULL, 0, __pa(slot_err_buf), RTAS_ERROR_LOG_MAX, + 2 /* Permanent Error */); + if (slot_err_ret == 0) + log_error(slot_err_buf, ERR_TYPE_RTAS_LOG, 1 /* Fatal */); + panic("EEH: MMIO failure (%ld) on device:\n %s %s\n", rets[0], dev->slot_name, dev->name); } @@ -129,17 +142,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 +173,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 +195,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 +213,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. Index: arch/ppc64/kernel/entry.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/entry.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/entry.S 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/entry.S 4 Aug 2004 01:26:10 -0000 1.2 @@ -27,6 +27,7 @@ #include #include #include +#include #ifdef CONFIG_PPC_ISERIES #define DO_SOFT_DISABLE @@ -46,16 +47,17 @@ */ .text _GLOBAL(DoSyscall) - std r0,THREAD+LAST_SYSCALL(r13) ld r11,_CCR(r1) /* Clear SO bit in CR */ lis r10,0x1000 andc r11,r11,r10 std r11,_CCR(r1) + ld r10,PACACURRENT(r13) + std r0,THREAD+LAST_SYSCALL(r10) #ifdef SHOW_SYSCALLS # ifdef SHOW_SYSCALLS_TASK LOADBASE(r31,show_syscalls_task) ld r31,show_syscalls_task@l(r31) - cmp 0,r13,r31 + cmp 0,r10,r31 bne 1f # endif /* SHOW_SYSCALLS_TASK */ LOADADDR(r3,7f) @@ -69,7 +71,7 @@ LOADADDR(r3,77f) ld r4,GPR8(r1) ld r5,GPR9(r1) - mr r6,r13 + ld r6, PACACURRENT(r13) bl .printk ld r0,GPR0(r1) ld r3,GPR3(r1) @@ -80,8 +82,8 @@ ld r8,GPR8(r1) 1: #endif /* SHOW_SYSCALLS */ - ld r10,TASK_PTRACE(r13) - andi. r10,r10,PT_TRACESYS + ld r11,TASK_PTRACE(r10) + andi. r11,r11,PT_TRACESYS bne- 50f cmpli 0,r0,NR_syscalls bge- 66f @@ -90,10 +92,10 @@ * */ #ifdef CONFIG_BINFMT_ELF32 - ld r10,THREAD+THREAD_FLAGS(r13) - andi. r10,r10,PPC_FLAG_32BIT + ld r11,THREAD+THREAD_FLAGS(r10) + andi. r11,r11,PPC_FLAG_32BIT beq- 15f - LOADADDR(r10,.sys_call_table32) + LOADADDR(r11,.sys_call_table32) /* Now mung the first 4 parameters into shape, by making certain that * the high bits (most significant 32 bits in 64 bit reg) are 0 * for the first 4 parameter regs(3-6). @@ -105,10 +107,10 @@ b 17f 15: #endif - LOADADDR(r10,.sys_call_table) + LOADADDR(r11,.sys_call_table) 17: slwi r0,r0,3 - ldx r10,r10,r0 /* Fetch system call handler [ptr] */ + ldx r10,r11,r0 /* Fetch system call handler [ptr] */ mtlr r10 addi r9,r1,STACK_FRAME_OVERHEAD blrl /* Call handler */ @@ -153,7 +155,8 @@ cmpli 0,r0,NR_syscalls bge- 66f #ifdef CONFIG_BINFMT_ELF32 - ld r10,THREAD+THREAD_FLAGS(r13) + ld r10,PACACURRENT(r13) + ld r10,THREAD+THREAD_FLAGS(r10) andi. r10,r10,PPC_FLAG_32BIT beq- 55f LOADADDR(r10,.sys_call_table32) @@ -214,7 +217,8 @@ _GLOBAL(ppc64_rt_sigreturn) bl .sys_rt_sigreturn -80: ld r10,TASK_PTRACE(r13) +80: ld r10,PACACURRENT(r13) + ld r10,TASK_PTRACE(r10) andi. r10,r10,PT_TRACESYS bne- 81f cmpi 0,r3,0 @@ -254,6 +258,11 @@ mflr r20 /* Return to switch caller */ mfmsr r22 li r6,MSR_FP /* Disable floating-point */ +#ifdef CONFIG_ALTIVEC +BEGIN_FTR_SECTION + oris r6,r6,MSR_VEC@h /* Disable altivec */ +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) +#endif /* CONFIG_ALTIVEC */ andc r22,r22,r6 mtmsrd r22 isync @@ -266,10 +275,9 @@ std r6,TRAP(r1) std r1,KSP(r3) /* Set old stack pointer */ - mfspr r5,SPRG3 /* Get Paca */ addi r3,r3,-THREAD /* old 'current' for return value */ - addi r13,r4,-THREAD /* Convert THREAD to 'current' */ - std r13,PACACURRENT(r5) /* Set new 'current' */ + addi r7,r4,-THREAD /* Convert THREAD to 'current' */ + std r7,PACACURRENT(r13) /* Set new 'current' */ #ifdef CONFIG_PPC_ISERIES ld r7,THREAD_FLAGS(r4) /* Get run light flag */ @@ -292,7 +300,8 @@ _GLOBAL(ret_from_fork) bl .schedule_tail - ld r0,TASK_PTRACE(r13) + ld r4,PACACURRENT(r13) + ld r0,TASK_PTRACE(r4) andi. r0,r0,PT_TRACESYS beq+ .ret_from_except bl .syscall_trace @@ -308,9 +317,8 @@ CHECKANYINT(r3,r4) beq+ 4f /* skip do_IRQ if no interrupts */ - mfspr r5,SPRG3 li r3,0 - stb r3,PACAPROCENABLED(r5) /* ensure we are disabled */ + stb r3,PACAPROCENABLED(r13) /* ensure we are disabled */ addi r3,r1,STACK_FRAME_OVERHEAD bl .do_IRQ b irq_recheck /* loop back and handle more */ @@ -322,14 +330,16 @@ beq+ restore /* if so, check need_resched and signals */ _GLOBAL(ret_to_user_hook) nop - /* NEED_RESCHED is a volatile long (64-bits) */ - ld r3,NEED_RESCHED(r13) + /* NEED_RESCHED is a volatile long (64-bits) */ + ld r3,PACACURRENT(r13) + ld r3,NEED_RESCHED(r3) cmpi 0,r3,0 /* check need_resched flag */ beq+ 7f bl .schedule /* SIGPENDING is an int (32-bits) */ -7: - lwz r5,SIGPENDING(r13) /* Check for pending unblocked signals */ +7: + ld r5,PACACURRENT(r13) + lwz r5,SIGPENDING(r5) /* Check for pending unblocked signals */ cmpwi 0,r5,0 beq+ restore li r3,0 @@ -372,26 +382,37 @@ #endif stdcx. r0,0,r1 /* to clear the reservation */ - mfspr r4,SPRG3 /* current task's PACA */ #ifdef DO_SOFT_DISABLE ld r0,SOFTE(r1) - stb r0,PACAPROCENABLED(r4) + stb r0,PACAPROCENABLED(r13) #endif /* if returning to user mode, save kernel SP */ ld r0,_MSR(r1) andi. r0,r0,MSR_PR beq+ 1f + ld r4,PACACURRENT(r13) +#ifdef CONFIG_ALTIVEC +BEGIN_FTR_SECTION + ld r0,THREAD+THREAD_VRSAVE(r4) + mtspr SPRN_VRSAVE,r0 /* if GPUL, restore VRSAVE reg */ +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) +#endif /* CONFIG_ALTIVEC */ addi r0,r1,INT_FRAME_SIZE /* size of frame */ - std r0,THREAD+KSP(r13) /* save kernel stack pointer */ - std r1,PACAKSAVE(r4) /* save exception stack pointer */ + std r0,THREAD+KSP(r4) /* save kernel stack pointer */ + std r1,PACAKSAVE(r13) /* save exception stack pointer */ + REST_GPR(13,r1) 1: + mfmsr r0 + li r2, MSR_RI + andc r0,r0,r2 + mtmsrd r0,1 + ld r0,_MSR(r1) mtspr SRR1,r0 ld r2,_CCR(r1) mtcrf 0xFF,r2 ld r2,_NIP(r1) mtspr SRR0,r2 - REST_GPR(13,r1) ld r0,GPR0(r1) ld r2,GPR2(r1) ld r3,GPR3(r1) @@ -437,14 +458,13 @@ 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. - */ - mfspr r4,SPRG3 /* Get PACA */ - std r1,PACAR1(r4) + */ + std r1,PACAR1(r13) mfmsr r6 - std r6,PACASAVEDMSR(r4) + std r6,PACASAVEDMSR(r13) /* Setup our real return addr */ SET_REG_TO_LABEL(r4,.rtas_return_loc) @@ -473,13 +493,19 @@ _STATIC(rtas_return_loc) /* relocation is off at this point */ - mfspr r4,SPRG3 /* Get PACA */ + mfspr r13,SPRG3 /* Get PACA */ SET_REG_TO_CONST(r5, KERNELBASE) - sub r4,r4,r5 /* RELOC the PACA base pointer */ - - ld r1,PACAR1(r4) /* Restore our SP */ + sub r13,r13,r5 /* RELOC the PACA base pointer */ + + mfmsr r6 /* Clear RI while SRR0/1 are live */ + li r0,MSR_RI + andc r6,r6,r0 + sync + mtmsrd r6 + + ld r1,PACAR1(r13) /* Restore our SP */ LOADADDR(r3,.rtas_restore_regs) - ld r4,PACASAVEDMSR(r4) /* Restore our MSR */ + ld r4,PACASAVEDMSR(r13) /* Restore our MSR */ mtspr SRR0,r3 mtspr SRR1,r4 @@ -492,9 +518,8 @@ REST_8GPRS(14, r1) /* Restore the non-volatiles */ REST_10GPRS(22, r1) /* ditto */ - /* put back current in r13 */ - mfspr r4,SPRG3 - ld r13,PACACURRENT(r4) + /* put back paca in r13 */ + mfspr r13,SPRG3 ld r4,_CCR(r1) mtcr r4 @@ -548,7 +573,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. */ Index: arch/ppc64/kernel/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/head.S 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/head.S 4 Aug 2004 01:26:10 -0000 1.2 @@ -14,6 +14,10 @@ * Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and * Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com * + * VMX/Altivec port from ppc32 (C) IBM 2003 + * Denis Joseph Barrow (dj@de.ibm.com,barrow_dj@yahoo.com) + * additional debugging & 2.4-2.5 VMX port + * Ben Herrenschmidt (benh@kernel.crashing.org) * This file contains the low-level support and setup for the * PowerPC-64 platform, including trap and interrupt dispatch. * @@ -32,11 +36,21 @@ #include #include #include +#include #ifdef CONFIG_PPC_ISERIES #define DO_SOFT_DISABLE #endif +/* copy saved SOFTE bit or EE bit from saved MSR depending + * if we are doing soft-disable or not + */ +#ifdef DO_SOFT_DISABLE +#define DO_COPY_EE() ld r20,SOFTE(r1) +#else +#define DO_COPY_EE() rldicl r20,r23,49,63 +#endif + /* * hcall interface to pSeries LPAR */ @@ -129,6 +143,10 @@ * All of it must fit below the first exception vector at 0x100. */ _GLOBAL(__secondary_hold) + mfmsr r24 + ori r24,r24,MSR_RI + mtmsrd r24 /* RI on */ + /* Grab our linux cpu number */ mr r24,r3 @@ -200,7 +218,7 @@ /* assumes *_common < 16b */ \ mfmsr r23; \ rotldi r23,r23,4; \ - ori r23,r23,0x30B; /* Set IR, DR, SF, ISF, HV */ \ + ori r23,r23,0x32B; /* Set IR, DR, RI, SF, ISF, HV*/ \ rotldi r23,r23,60; /* for generic handlers */ \ mtspr SRR0,r22; \ mtspr SRR1,r23; \ @@ -284,7 +302,7 @@ SAVE_8GPRS(2, r1); /* save r2 - r13 in stackframe */ \ SAVE_4GPRS(10, r1); \ ld r2,PACATOC(r20); \ - ld r13,PACACURRENT(r20) + mr r13,r20 /* * Note: code which follows this uses cr0.eq (set if from kernel), @@ -362,8 +380,17 @@ STD_EXCEPTION_PSERIES( 0xc00, SystemCall ) STD_EXCEPTION_PSERIES( 0xd00, SingleStep ) STD_EXCEPTION_PSERIES( 0xe00, Trap_0e ) - STD_EXCEPTION_PSERIES( 0xf00, PerformanceMonitor ) + . = 0xf00 + b PerformanceMonitor_Pseries + STD_EXCEPTION_PSERIES( 0xf20, AltiVecUnavailable ) + . = 0xf90 + .globl PerformanceMonitor_Pseries +PerformanceMonitor_Pseries: + EXCEPTION_PROLOG_PSERIES( 0xf00, PerformanceMonitor_common ) STD_EXCEPTION_PSERIES( 0x1300, InstructionBreakpoint ) + STD_EXCEPTION_PSERIES( 0x1700, AltiVecAssist ) + STD_EXCEPTION_PSERIES( 0x1800, ThermalInterrupt) + /* Space for the naca. Architected to be located at real address * 0x4000. Various tools rely on this location being fixed. @@ -435,8 +462,8 @@ .globl SystemReset_Iseries SystemReset_Iseries: - mfspr 25,SPRG3 /* Get paca address */ - lhz r24,PACAPACAINDEX(r25) /* Get processor # */ + mfspr 13,SPRG3 /* Get paca address */ + lhz r24,PACAPACAINDEX(r13) /* Get processor # */ cmpi 0,r24,0 /* Are we processor 0? */ beq .__start_initialization_iSeries /* Start up the first processor */ mfspr r4,CTRLF @@ -447,7 +474,7 @@ 1: HMT_LOW #ifdef CONFIG_SMP - lbz r23,PACAPROCSTART(r25) /* Test if this processor + lbz r23,PACAPROCSTART(r13) /* Test if this processor * should start */ sync LOADADDR(r3,current_set) @@ -477,7 +504,7 @@ #endif /* CONFIG_SMP */ li r0,-1 /* r0=-1 indicates a Hypervisor call */ sc /* Invoke the hypervisor via a system call */ - mfspr r25,SPRG3 /* Put r25 back ???? */ + mfspr r13,SPRG3 /* Put r13 back - why???? */ b 1b /* If SMP not configured, secondaries * loop forever */ @@ -550,6 +577,47 @@ STD_EXCEPTION_COMMON( 0xb00, Trap_0b, .UnknownException ) STD_EXCEPTION_COMMON( 0xd00, SingleStep, .SingleStepException ) STD_EXCEPTION_COMMON( 0xe00, Trap_0e, .UnknownException ) + + .globl AltiVecUnavailable_common +AltiVecUnavailable_common: + EXCEPTION_PROLOG_COMMON +#ifdef CONFIG_ALTIVEC + bne .load_up_altivec /* if from user, just load it up */ +#endif + addi r3,r1,STACK_FRAME_OVERHEAD + DO_COPY_EE() + li r6,0xf20 + bl .save_remaining_regs +#ifndef CONFIG_ALTIVEC + beq 1f + bl .IllegalAltiVecInstruction + b .ret_from_except +1: +#endif + bl .KernelAltiVecUnavailableException + BUG_OPCODE + + .global AltiVecAssist_common +AltiVecAssist_common: + EXCEPTION_PROLOG_COMMON + addi r3,r1,STACK_FRAME_OVERHEAD + DO_COPY_EE() + li r6,0x1700 + bl .save_remaining_regs + bl .AltiVecAssistException + b .ret_from_except + + .global ThermalInterrupt_common +ThermalInterrupt_common: + EXCEPTION_PROLOG_COMMON + addi r3,r1,STACK_FRAME_OVERHEAD + DO_COPY_EE() + li r6,0x1800 + bl .save_remaining_regs + bl .ThermalInterrupt + BUG_OPCODE + + STD_EXCEPTION_COMMON(0x1300, InstructionBreakpoint, .InstructionBreakpointException ) /* @@ -569,6 +637,12 @@ REST_GPR(0, r1) REST_8GPRS(2, r1) REST_4GPRS(10, r1) + + mfmsr r20 + li r21, MSR_RI + andc r20,r20,r21 + mtmsrd r20,1 + mtspr SRR1,r23 mtspr SRR0,r22 REST_4GPRS(20, r1) @@ -582,14 +656,17 @@ */ .globl DataAccess_common DataAccess_common: - mfspr r22,DAR - srdi r22,r22,60 - cmpi 0,r22,0xc + mfspr r22,DSISR + andis. r22,r22,0x0020 + beq 1f + mfspr r22,DAR /* if it's a segment table miss, */ + srdi r22,r22,60 /* check if it is in kernel region */ + cmpi 0,r22,0xc /* and call do_stab_bolted if so */ beq .do_stab_bolted cmpi 0,r22,0xb beq .do_stab_bolted -stab_bolted_user_return: +1: EXCEPTION_PROLOG_COMMON ld r3,_DSISR(r1) andis. r0,r3,0xa450 /* weird error? */ @@ -609,11 +686,7 @@ ld r4,_DAR(r1) ld r5,_DSISR(r1) addi r3,r1,STACK_FRAME_OVERHEAD -#ifdef DO_SOFT_DISABLE - ld r20,SOFTE(r1) /* Copy saved SOFTE bit */ -#else - rldicl r20,r23,49,63 /* copy EE bit from saved MSR */ -#endif + DO_COPY_EE() li r6,0x300 bl .save_remaining_regs bl .do_page_fault @@ -635,12 +708,9 @@ or. r3,r3,r3 /* Check return code */ beq fast_exception_return /* Return if we succeeded */ 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 + DO_COPY_EE() li r6,0x380 + li r5,0 bl .save_remaining_regs bl .do_page_fault b .ret_from_except @@ -662,13 +732,9 @@ bl .do_hash_page_ISI /* Try to handle as hpte fault */ 1: mr r4,r22 - mr r5,r23 + rlwinm r5,r23,0,4,4 /* We only care about PR in error_code */ 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 + DO_COPY_EE() li r6,0x400 bl .save_remaining_regs bl .do_page_fault @@ -684,12 +750,9 @@ beq fast_exception_return /* Return if we succeeded */ 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 + DO_COPY_EE() li r6,0x480 + li r5,0 bl .save_remaining_regs bl .do_page_fault b .ret_from_except @@ -746,6 +809,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 @@ -753,11 +823,7 @@ Alignment_common: EXCEPTION_PROLOG_COMMON 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 + DO_COPY_EE() li r6,0x600 bl .save_remaining_regs bl .AlignmentException @@ -767,11 +833,7 @@ ProgramCheck_common: EXCEPTION_PROLOG_COMMON 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 + DO_COPY_EE() li r6,0x700 bl .save_remaining_regs bl .ProgramCheckException @@ -781,11 +843,12 @@ 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 + DO_COPY_EE() 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: @@ -798,11 +861,7 @@ 1: #endif std r3,ORIG_GPR3(r1) -#ifdef DO_SOFT_DISABLE - ld r20,SOFTE(r1) -#else - rldicl r20,r23,49,63 /* copy EE bit from saved MSR */ -#endif + DO_COPY_EE() li r6,0xC00 bl .save_remaining_regs bl .DoSyscall @@ -1030,25 +1089,6 @@ _GLOBAL(do_stab_bolted) stw r23,EX_CCR(r21) /* save CR in exc. frame */ - mfspr r22,DSISR - andis. r22,r22,0x0020 - bne+ 2f - ld r22,8(r21) /* get SRR1 */ - andi. r22,r22,MSR_PR /* check if from user */ - bne+ stab_bolted_user_return /* from user, send the error on up */ - li r3,0 -#ifdef CONFIG_XMON - bl .xmon -#endif -#ifdef CONFIG_KDB - /* kdb(KDB_REASON_FAULT,regs->trap,regs); */ - li r3,1 /* reason_call, regs considered invalid*/ - li r4,0x200 /* trap */ - li r5,0 /* pointers to regs.*/ - bl .kdb -#endif -1: b 1b -2: /* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */ mfspr r21,DAR rldicl r20,r21,36,32 /* Permits a full 32b of ESID */ @@ -1144,6 +1184,12 @@ lwz r23,EX_CCR(r21) /* get saved CR */ /* note that this is almost identical to maskable_exception_exit */ mtcr r23 /* restore CR */ + + mfmsr r22 + li r23, MSR_RI + andc r22,r22,r23 + mtmsrd r22,1 + ld r22,EX_SRR0(r21) /* Get SRR0 from exc. frame */ ld r23,EX_SRR1(r21) /* Get SRR1 from exc. frame */ mtspr SRR0,r22 @@ -1185,7 +1231,7 @@ slbmfee r23,r22 rldicl r23,r23,37,63 cmpwi r23,0 - beq 3f /* Found an invalid entry */ + beq 4f /* Found an invalid entry */ addi r22,r22,1 cmpldi r22,64 @@ -1194,16 +1240,36 @@ /* No free entry - just take the next entry, round-robin */ /* XXX we should get the number of SLB entries from the naca */ SLB_NUM_ENTRIES = 64 - mfspr r21,SPRG3 +2: mfspr r21,SPRG3 ld r22,PACASTABRR(r21) addi r23,r22,1 cmpdi r23,SLB_NUM_ENTRIES - blt 2f + blt 3f li r23,1 -2: std r23,PACASTABRR(r21) +3: std r23,PACASTABRR(r21) /* r20 = vsid, r22 = entry */ -3: + + /* + * Never cast out the segment for our kernel stack. Since we + * dont invalidate the ERAT we could have a valid translation + * for the kernel stack during the first part of exception exit + * which gets invalidated due to a tlbie from another cpu at a + * non recoverable point (after setting srr0/1) - Anton + */ + slbmfee r23,r22 + srdi r23,r23,28 + /* + * This is incorrect (r1 is not the kernel stack) if we entered + * from userspace but there is no critical window from userspace + * so this should be OK. Also if we cast out the userspace stack + * segment while in userspace we will fault it straight back in. + */ + srdi r21,r1,28 + cmpd r21,r23 + beq- 2b + +4: /* Put together the vsid portion of the entry. */ li r21,0 rldimi r21,r20,12,0 @@ -1238,6 +1304,12 @@ lwz r23,EX_CCR(r21) /* get saved CR */ /* note that this is almost identical to maskable_exception_exit */ mtcr r23 /* restore CR */ + + mfmsr r22 + li r23, MSR_RI + andc r22,r22,r23 + mtmsrd r22,1 + ld r22,EX_SRR0(r21) /* Get SRR0 from exc. frame */ ld r23,EX_SRR1(r21) /* Get SRR1 from exc. frame */ mtspr SRR0,r22 @@ -1296,21 +1368,27 @@ * Indicate that r1 contains the kernel stack and * get the Kernel TOC and CURRENT pointers from the paca */ - mfspr r23,SPRG3 /* Get PACA */ - std r22,PACAKSAVE(r23) /* r1 is now kernel sp */ - ld r2,PACATOC(r23) /* Get Kernel TOC pointer */ + std r22,PACAKSAVE(r13) /* r1 is now kernel sp */ + ld r2,PACATOC(r13) /* Get Kernel TOC pointer */ /* * If from user state, update THREAD.regs */ beq 2f /* Modify THREAD.regs if from user */ addi r24,r1,STACK_FRAME_OVERHEAD - std r24,THREAD+PT_REGS(r13) + ld r22,PACACURRENT(r13) + std r24,THREAD+PT_REGS(r22) +#ifdef CONFIG_ALTIVEC +BEGIN_FTR_SECTION + mfspr r24,SPRN_VRSAVE /* if save vrsave register value */ + std r24,THREAD+THREAD_VRSAVE(r22) +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) +#endif /* CONFIG_ALTIVEC */ 2: SET_REG_TO_CONST(r22, MSR_KERNEL) #ifdef DO_SOFT_DISABLE - stb r20,PACAPROCENABLED(r23) /* possibly soft enable */ + stb r20,PACAPROCENABLED(r13) /* possibly soft enable */ ori r22,r22,MSR_EE /* always hard enable */ #else rldimi r22,r20,15,48 /* Insert desired EE value */ @@ -1357,20 +1435,20 @@ /* Set up a paca value for this processor. */ LOADADDR(r24, paca) /* Get base vaddr of Paca array */ - mulli r25,r3,PACA_SIZE /* Calculate vaddr of right Paca */ - add r25,r25,r24 /* for this processor. */ + mulli r13,r3,PACA_SIZE /* Calculate vaddr of right Paca */ + add r13,r13,r24 /* for this processor. */ - mtspr SPRG3,r25 /* Save vaddr of Paca in SPRG3 */ + mtspr SPRG3,r13 /* Save vaddr of Paca in SPRG3 */ mr r24,r3 /* __secondary_start needs cpu# */ 1: HMT_LOW - lbz r23,PACAPROCSTART(r25) /* Test if this processor should */ + lbz r23,PACAPROCSTART(r13) /* Test if this processor should */ /* start. */ sync /* Create a temp kernel stack for use before relocation is on. */ - mr r1,r25 + mr r1,r13 addi r1,r1,PACAGUARD addi r1,r1,0x1000 subi r1,r1,STACK_FRAME_OVERHEAD @@ -1390,6 +1468,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 @@ -1605,35 +1688,34 @@ 1: #endif /* CONFIG_SMP */ /* enable use of FP after return */ - addi r5,r13,THREAD - ld r4,THREAD_FPEXC_MODE(r5) + ld r4,PACACURRENT(r13) + addi r5,r4,THREAD /* Get THREAD */ + ld r20,THREAD_FPEXC_MODE(r5) ori r23,r23,MSR_FP - or r23,r23,r4 + or r23,r23,r20 lfd fr0,THREAD_FPSCR(r5) mtfsf 0xff,fr0 REST_32FPRS(0, r5) #ifndef CONFIG_SMP /* Update last_task_used_math to 'current' */ - std r13,last_task_used_math@l(r3) + std r4,last_task_used_math@l(r3) #endif /* CONFIG_SMP */ /* 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) @@ -1672,6 +1754,100 @@ #endif /* CONFIG_SMP */ blr +#ifdef CONFIG_ALTIVEC +/* + * load_up_altivec(unused, unused, tsk) + * Disable Altivec for the task which used altivec upreviously, + * and save its altivec registers in its thread_struct. + * Enables Altivec for use in the kernel on return. + * On SMP we know the fpu is free, since we give it up every + * switch (ie, no lazy save of the altivec registers). + * On entry: r13 == 'current' && last_task_used_altivec != 'current' + */ +_STATIC(load_up_altivec) +/* + * Disable AltiVec for the task which had AltiVec previously, + * and save its AltiVec registers in its thread_struct. + * Enables AltiVec for use in the kernel on return. + * On SMP we know the AltiVec units are free, since we give it up every + * switch. -- Kumar + */ + mfmsr r5 + oris r5,r5,MSR_VEC@h + mtmsrd r5 /* enable use of AltiVec now */ + isync +/* + * For SMP, we don't do lazy AltiVec switching because it just gets too + * horrendously complex, especially when a task switches from one CPU + * to another. Instead we call giveup_altivec in switch_to. + */ +#ifndef CONFIG_SMP + LOADBASE(r3,last_task_used_altivec) + ld r4,last_task_used_altivec@l(r3) + cmpi 0,r4,0 + beq 1f + addi r4,r4,THREAD /* want THREAD of last_task_used_altivec */ + SAVE_32VR(0,r20,r4) + MFVSCR(vr0) + li r20,THREAD_VSCR + STVX(vr0,r20,r4) + ld r5,PT_REGS(r4) + ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) + lis r20,MSR_VEC@h + andc r4,r4,r20 /* disable altivec for previous task */ + std r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#endif /* CONFIG_SMP */ + /* enable use of AltiVec after return */ + ld r4,PACACURRENT(r13) + addi r5,r4,THREAD + oris r23,r23,MSR_VEC@h + li r20,THREAD_VSCR + LVX(vr0,r20,r5) + MTVSCR(vr0) + REST_32VR(0,r20,r5) +#ifndef CONFIG_SMP + /* Update last_task_used_altivec to 'current' */ + std r4,last_task_used_altivec@l(r3) +#endif /* CONFIG_SMP */ + /* restore registers and return */ + b fast_exception_return +/* + * giveup_altivec(tsk) + * Disable AltiVec for the task given as the argument, + * and save the AltiVec registers in its thread_struct. + * Enables AltiVec for use in the kernel on return. + */ +_GLOBAL(giveup_altivec) + mfmsr r5 + oris r5,r5,MSR_VEC@h + mtmsrd r5 /* enable use of AltiVec now */ + isync + cmpi 0,r3,0 + beqlr- /* if no previous owner, done */ + addi r3,r3,THREAD /* want THREAD of task */ + ld r5,PT_REGS(r3) + cmpi 0,r5,0 + SAVE_32VR(0, r4, r3) + MFVSCR(vr0) + li r4,THREAD_VSCR + STVX(vr0, r4, r3) + beq 1f + ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) + lis r3,MSR_VEC@h + andc r4,r4,r3 /* disable AltiVec for previous task */ + std r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#ifndef CONFIG_SMP + li r5,0 + LOADBASE(r4,last_task_used_altivec) + std r5,last_task_used_altivec@l(r4) +#endif /* CONFIG_SMP */ + blr +#endif /* CONFIG_ALTIVEC */ + + + #ifdef CONFIG_SMP /* * This function is called after the master CPU has released the @@ -1683,7 +1859,7 @@ * On entry the following are set: * r1 = stack pointer. vaddr for iSeries, raddr (temp stack) for pSeries * r24 = cpu# (in Linux terms) - * r25 = paca virtual address + * r13 = paca virtual address * SPRG3 = paca virtual address */ _GLOBAL(__secondary_start) @@ -1695,10 +1871,10 @@ addi r2,r2,0x4000 addi r2,r2,0x4000 - std r2,PACATOC(r25) + std r2,PACATOC(r13) li r6,0 - std r6,PACAKSAVE(r25) - stb r6,PACAPROCENABLED(r25) + std r6,PACAKSAVE(r13) + stb r6,PACAPROCENABLED(r13) #ifndef CONFIG_PPC_ISERIES /* Initialize the page table pointer register. */ @@ -1707,18 +1883,18 @@ mtspr SDR1,r6 /* set the htab location */ #endif /* Initialize the first segment table (or SLB) entry */ - ld r3,PACASTABVIRT(r25) /* get addr of segment table */ + ld r3,PACASTABVIRT(r13) /* get addr of segment table */ bl .stab_initialize /* Initialize the kernel stack. Just a repeat for iSeries. */ LOADADDR(r3,current_set) sldi r28,r24,4 /* get current_set[cpu#] */ - ldx r13,r3,r28 - std r13,PACACURRENT(r25) - addi r1,r13,TASK_UNION_SIZE + ldx r28,r3,r28 + std r28,PACACURRENT(r13) + addi r1,r28,TASK_UNION_SIZE subi r1,r1,STACK_FRAME_OVERHEAD - ld r3,PACASTABREAL(r25) /* get raddr of segment table */ + ld r3,PACASTABREAL(r13) /* get raddr of segment table */ ori r4,r3,1 /* turn on valid bit */ #ifdef CONFIG_PPC_ISERIES @@ -1735,9 +1911,13 @@ bne 98f mfspr r3,PVR srwi r3,r3,16 - cmpwi r3,0x37 /* SStar */ + cmpwi r3,0x37 /* SStar */ + beq 97f + cmpwi r3,0x36 /* IStar */ + beq 97f + cmpwi r3,0x34 /* Pulsar */ bne 98f - li r3,H_SET_ASR /* hcall = H_SET_ASR */ +97: li r3,H_SET_ASR /* hcall = H_SET_ASR */ HSC /* Invoking hcall */ b 99f 98: /* !(rpa hypervisor) || !(sstar) */ @@ -1756,7 +1936,6 @@ mtspr SRR0,r3 mtspr SRR1,r4 rfid -#endif /* CONFIG_SMP */ /* * Running with relocation on at this point. All we want to do is @@ -1766,6 +1945,7 @@ li r3,0 std r3,0(r1) /* Zero the stack frame pointer */ bl .start_secondary +#endif /* CONFIG_SMP */ /* * This subroutine clobbers r11, r12 and the LR @@ -1805,6 +1985,10 @@ bl .reloc_offset mr r26,r3 + mfmsr r6 + ori r6,r6,MSR_RI + mtmsrd r6 /* RI on */ + /* setup the systemcfg pointer which is needed by *tab_initialize */ LOADADDR(r6,systemcfg) sub r6,r6,r26 /* addr of the variable systemcfg */ @@ -1861,6 +2045,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 @@ -1871,9 +2062,9 @@ /* stab_initialize */ li r27,0x4000 ld r6,PACA(r27) /* Get the base paca pointer */ - sub r6,r6,r26 /* convert to physical addr */ - mtspr SPRG3,r6 /* PPPBBB: Temp... -Peter */ - ld r3,PACASTABREAL(r6) + sub r13,r6,r26 /* convert to physical addr */ + mtspr SPRG3,r13 /* PPPBBB: Temp... -Peter */ + ld r3,PACASTABREAL(r13) ori r4,r3,1 /* turn on valid bit */ /* set the ASR */ @@ -1884,8 +2075,12 @@ mfspr r3,PVR srwi r3,r3,16 cmpwi r3,0x37 /* SStar */ + beq 97f + cmpwi r3,0x36 /* IStar */ + beq 97f + cmpwi r3,0x34 /* Pulsar */ bne 98f - li r3,H_SET_ASR /* hcall = H_SET_ASR */ +97: li r3,H_SET_ASR /* hcall = H_SET_ASR */ HSC /* Invoking hcall */ b 99f 98: /* This is not a hypervisor machine */ @@ -1949,6 +2144,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) @@ -1961,16 +2159,16 @@ LOADADDR(r4,naca) /* Get naca ptr address */ ld r4,0(r4) /* Get the location of the naca */ - ld r4,PACA(r4) /* Get the base paca pointer */ - mtspr SPRG3,r4 + ld r13,PACA(r4) /* Get the base paca pointer */ + mtspr SPRG3,r13 /* ptr to current */ - LOADADDR(r13,init_task_union) - std r13,PACACURRENT(r4) + LOADADDR(r4,init_task_union) + std r4,PACACURRENT(r13) - std r2,PACATOC(r4) + std r2,PACATOC(r13) li r5,0 - std r0,PACAKSAVE(r4) + std r0,PACAKSAVE(r13) /* ptr to hardware interrupt stack for processor 0 */ LOADADDR(r3, hardware_int_paca0) @@ -1979,10 +2177,10 @@ subi r5,r5,STACK_FRAME_OVERHEAD add r3,r3,r5 - std r3,PACAHRDWINTSTACK(r4) + std r3,PACAHRDWINTSTACK(r13) li r3,0 - stb r3,PACAHRDWINTCOUNT(r4) + stb r3,PACAHRDWINTCOUNT(r13) /* Restore the parms passed in from the bootloader. */ mr r3,r31 @@ -2006,6 +2204,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) Index: arch/ppc64/kernel/htab.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/htab.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/htab.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/htab.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -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: /* @@ -1151,7 +1179,7 @@ "mr 5, %3\n" "mr 6, %4\n" "mr 7, %5\n" - HSC + HVSC "mr %0, 3\n" "mr %1, 4\n" : "=r" (lpar_rc), "=r" (slot) @@ -1172,7 +1200,7 @@ "mr 5, %3\n" "mr 6, %4\n" "mr 7, %5\n" - HSC + HVSC "mr %0, 3\n" "mr %1, 4\n" : "=r" (lpar_rc), "=r" (slot) Index: arch/ppc64/kernel/i8259.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/i8259.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/i8259.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/i8259.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -123,7 +123,8 @@ static void i8259_end_irq(unsigned int irq) { - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + if (!(irqdesc(irq)->status & (IRQ_DISABLED|IRQ_INPROGRESS)) && + irqdesc(irq)->action) i8259_unmask_irq(irq); } @@ -146,7 +147,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 */ Index: arch/ppc64/kernel/iSeries_IoMmTable.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/iSeries_IoMmTable.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/iSeries_IoMmTable.h 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/iSeries_IoMmTable.h 4 Aug 2004 01:26:10 -0000 1.2 @@ -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. */ Index: arch/ppc64/kernel/iSeries_irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/iSeries_irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/iSeries_irq.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/iSeries_irq.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -70,15 +70,24 @@ void iSeries_init_irqMap(int irq); +void iSeries_init_irq_desc(irq_desc_t *desc) +{ + if (!desc->handler) + desc->handler = &iSeries_IRQ_handler; +} + /* This is called by init_IRQ. set in ppc_md.init_IRQ by iSeries_setup.c */ void __init iSeries_init_IRQ(void) { int i; + irq_desc_t *desc; + for (i = 0; i < NR_IRQS; i++) { - irq_desc[i].handler = &iSeries_IRQ_handler; - irq_desc[i].status = 0; - irq_desc[i].status |= IRQ_DISABLED; - irq_desc[i].depth = 1; + desc = real_irqdesc(i); + desc->handler = &iSeries_IRQ_handler; + desc->status = 0; + desc->status |= IRQ_DISABLED; + desc->depth = 1; iSeries_init_irqMap(i); } /* Register PCI event handler and open an event path */ @@ -117,6 +126,7 @@ u32 dsa = (busNumber << 16) | (subBusNumber << 8) | deviceId; struct iSeries_irqEntry* newEntry; unsigned long flags; + irq_desc_t *desc = irqdesc(irq); if (irq < 0 || irq >= NR_IRQS) { return -1; @@ -132,7 +142,7 @@ * done during buswalk, but it should not hurt anything except a * little performance to be smp safe. *******************************************************************/ - spin_lock_irqsave(&irq_desc[irq].lock, flags); + spin_lock_irqsave(&desc->lock, flags); if (iSeries_irqMap[irq].valid) { /* Push the new element onto the irq stack */ @@ -147,7 +157,7 @@ kfree(newEntry); rc = -1; } - spin_unlock_irqrestore(&irq_desc[irq].lock, flags); + spin_unlock_irqrestore(&desc->lock, flags); return rc; } @@ -179,10 +189,11 @@ int irq; unsigned long flags; for (irq=0; irq < NR_IRQS; irq++) { - spin_lock_irqsave(&irq_desc[irq].lock, flags); - irq_desc[irq].handler->startup(irq); - spin_unlock_irqrestore(&irq_desc[irq].lock, flags); - } + irq_desc_t *desc = irqdesc(irq); + spin_lock_irqsave(&desc->lock, flags); + desc->handler->startup(irq); + spin_unlock_irqrestore(&desc->lock, flags); + } } /* this is not called anywhere currently */ Index: arch/ppc64/kernel/iSeries_setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/iSeries_setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/iSeries_setup.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/iSeries_setup.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -49,6 +49,7 @@ #include #include #include +#include /* Function Prototypes */ @@ -62,6 +63,7 @@ extern void iSeries_pcibios_init(void); extern void iSeries_pcibios_fixup(void); extern void iSeries_pcibios_fixup_bus(int); +extern void iSeries_init_irq_desc(irq_desc_t *desc); /* Global Variables */ @@ -249,7 +251,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 ); @@ -305,6 +308,7 @@ ppc_md.get_cpuinfo = iSeries_get_cpuinfo; ppc_md.irq_cannonicalize = NULL; ppc_md.init_IRQ = iSeries_init_IRQ; + ppc_md.init_irq_desc = iSeries_init_irq_desc; ppc_md.init_ras_IRQ = NULL; ppc_md.get_irq = iSeries_get_irq; ppc_md.init = NULL; @@ -620,6 +624,8 @@ if (hpte.dw0.dw0.v) { /* HPTE exists, so just bolt it */ HvCallHpt_setSwBits(slot, 0x10, 0); + /* And make sure the pp bits are correct */ + HvCallHpt_setPp(slot, PP_RWXX); } else { /* No HPTE exists, so create a new bolted one */ make_pte(NULL, va, (unsigned long)__v2a(ea), @@ -698,6 +704,9 @@ systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR; printk("Processor version = %x\n", systemcfg->processor); +#if defined(CONFIG_IRQ_ALL_CPUS) + do_spread_lpevents(MAX_PACAS); +#endif } /* Index: arch/ppc64/kernel/idle.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/idle.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/idle.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/idle.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -2,7 +2,12 @@ * Idle daemon for PowerPC. Idle daemon will handle any action * that needs to be taken when the system becomes idle. * - * Written by Cort Dougan (cort@cs.nmt.edu) + * Originally Written by Cort Dougan (cort@cs.nmt.edu) + * + * iSeries supported added by Mike Corrigan + * + * Additional shared processor, SMT, and firmware support + * 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 @@ -10,6 +15,7 @@ * 2 of the License, or (at your option) any later version. */ #include +#include #include #include #include @@ -28,17 +34,19 @@ #include #include #include +#include #include #include #include #include +int (*idle_loop)(void); + #ifdef CONFIG_PPC_ISERIES static void yield_shared_processor(void) { struct paca_struct *lpaca = get_paca(); - unsigned long tb; HvCall_setEnabledInterrupts( HvCall_MaskIPI | HvCall_MaskLpEvent | @@ -46,68 +54,180 @@ HvCall_MaskTimeout ); if ( ! ItLpQueue_isLpIntPending( paca->lpQueuePtr ) ) { - tb = get_tb(); - /* Compute future tb value when yield should expire */ - HvCall_yieldProcessor( HvCall_YieldTimed, tb+tb_ticks_per_jiffy ); + /* + * Compute future tb value when yield should expire. + * We want to be woken up when the next decrementer is + * to fire. + */ - /* The decrementer stops during the yield. Force a fake decrementer - * here and let the timer_interrupt code sort out the actual time. + __cli(); + lpaca->yielded = 1; /* Indicate a prod is desired */ + lpaca->xLpPaca.xIdle = 1; /* Inform the HV we are idle */ + + HvCall_yieldProcessor(HvCall_YieldTimed, + lpaca->next_jiffy_update_tb); + + lpaca->yielded = 0; /* Back to IPI's */ + __sti(); + + /* + * The decrementer stops during the yield. Force a fake + * decrementer here and let the timer_interrupt code sort + * out the actual time. */ lpaca->xLpPaca.xIntDword.xFields.xDecrInt = 1; } process_iSeries_events(); } -#endif /* CONFIG_PPC_ISERIES */ -int idled(void) +int idle_iSeries(void) { struct paca_struct *lpaca; long oldval; -#ifdef CONFIG_PPC_ISERIES unsigned long CTRL; -#endif /* endless loop with no priority at all */ current->nice = 20; current->counter = -100; -#ifdef CONFIG_PPC_ISERIES + /* ensure iSeries run light will be out when idle */ current->thread.flags &= ~PPC_FLAG_RUN_LIGHT; CTRL = mfspr(CTRLF); CTRL &= ~RUNLATCH; mtspr(CTRLT, CTRL); -#endif init_idle(); lpaca = get_paca(); for (;;) { -#ifdef CONFIG_PPC_ISERIES if ( lpaca->xLpPaca.xSharedProc ) { if ( ItLpQueue_isLpIntPending( lpaca->lpQueuePtr ) ) process_iSeries_events(); if ( !current->need_resched ) yield_shared_processor(); - } - else -#endif - { + } else { /* Avoid an IPI by setting need_resched */ oldval = xchg(¤t->need_resched, -1); if (!oldval) { while(current->need_resched == -1) { -#ifdef CONFIG_PPC_ISERIES HMT_medium(); if ( ItLpQueue_isLpIntPending( lpaca->lpQueuePtr ) ) process_iSeries_events(); + HMT_low(); + } + } + } + HMT_medium(); + if (current->need_resched) { + lpaca->xLpPaca.xIdle = 0; + schedule(); + check_pgt_cache(); + } + } + return 0; +} #endif + +int idle_default(void) +{ + long oldval; + + current->nice = 20; + current->counter = -100; + init_idle(); + + for (;;) { + /* Avoid an IPI by setting need_resched */ + oldval = xchg(¤t->need_resched, -1); + if (!oldval) { + while(current->need_resched == -1) { HMT_low(); + } + } + HMT_medium(); + if (current->need_resched) { + schedule(); + check_pgt_cache(); + } + } + return 0; +} + +int idle_dedicated(void) +{ + long oldval; + struct paca_struct *lpaca = get_paca(), *ppaca;; + unsigned long start_snooze; + + ppaca = &paca[(lpaca->xPacaIndex) ^ 1]; + current->nice = 20; + current->counter = -100; + init_idle(); + + for (;;) { + /* Indicate to the HV that we are idle. Now would be + * a good time to find other work to dispatch. */ + lpaca->xLpPaca.xIdle = 1; + + /* Avoid an IPI by setting need_resched */ + oldval = xchg(¤t->need_resched, -1); + if (!oldval) { + start_snooze = __get_tb(); + while(current->need_resched == -1) { + if (__get_tb() < + (start_snooze + + naca->smt_snooze_delay*tb_ticks_per_usec)) { + HMT_low(); /* Low thread priority */ + continue; + } + + HMT_very_low(); /* Low power mode */ + + /* If the SMT mode is system controlled & the + * partner thread is doing work, switch into + * ST mode. + */ + if((naca->smt_state == SMT_DYNAMIC) && + (!(ppaca->xLpPaca.xIdle))) { + /* need_resched could be 1 or -1 at this + * point. If it is -1, set it to 0, so + * an IPI/Prod is sent. If it is 1, keep + * it that way & schedule work. + */ + oldval = xchg(¤t->need_resched, 0); + if(oldval == 1) { + current->need_resched = oldval; + break; + } + + /* DRENG: Go HMT_medium here ? */ + __cli(); + lpaca->yielded = 1; + + /* SMT dynamic mode. Cede will result + * in this thread going dormant, if the + * partner thread is still doing work. + * Thread wakes up if partner goes idle, + * an interrupt is presented, or a prod + * occurs. Returning from the cede + * enables external interrupts. + */ + cede_processor(); + + lpaca->yielded = 0; + } else { + /* Give the HV an opportunity at the + * processor, since we are not doing + * any work. + */ + poll_pending(); } } } HMT_medium(); if (current->need_resched) { + lpaca->xLpPaca.xIdle = 0; schedule(); check_pgt_cache(); } @@ -115,12 +235,78 @@ return 0; } +int idle_shared(void) +{ + struct paca_struct *lpaca = get_paca(); + + /* endless loop with no priority at all */ + current->nice = 20; + current->counter = -100; + + init_idle(); + + for (;;) { + /* Indicate to the HV that we are idle. Now would be + * a good time to find other work to dispatch. */ + lpaca->xLpPaca.xIdle = 1; + + if (!current->need_resched) { + __cli(); + lpaca->yielded = 1; + /* - * SMP entry into the idle task - calls the same thing as the - * non-smp versions. -- Cort + * Yield the processor to the hypervisor. We return if + * an external interrupt occurs (which are driven prior + * to returning here) or if a prod occurs from another + * processor. When returning here, external interrupts + * are enabled. */ + cede_processor(); + + lpaca->yielded = 0; + } + + HMT_medium(); + if (current->need_resched) { + lpaca->xLpPaca.xIdle = 0; + schedule(); + check_pgt_cache(); + } + } + + return 0; +} + int cpu_idle(void) { - idled(); + idle_loop(); return 0; } + +int idle_setup(void) +{ +#ifdef CONFIG_PPC_ISERIES + idle_loop = idle_iSeries; +#else + if (systemcfg->platform & PLATFORM_PSERIES) { + if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { + if(get_paca()->xLpPaca.xSharedProc) { + printk("idle = idle_shared\n"); + idle_loop = idle_shared; + } else { + printk("idle = idle_dedicated\n"); + idle_loop = idle_dedicated; + } + } else { + printk("idle = idle_default\n"); + idle_loop = idle_default; + } + } else { + printk("idle_setup: unknown platform, use idle_default\n"); + idle_loop = idle_default; + } +#endif + + return 1; +} + Index: arch/ppc64/kernel/ioctl32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/ioctl32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/ioctl32.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/ioctl32.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -566,11 +566,52 @@ goto out; } switch (ethcmd) { - case ETHTOOL_GDRVINFO: len = sizeof(struct ethtool_drvinfo); break; + case ETHTOOL_GSTRINGS: { + struct ethtool_gstrings *stringsaddr = (struct ethtool_gstrings *)A(data); + if (get_user(len, (u32 *)&stringsaddr->len)) { + err = -EFAULT; + goto out; + } + if (len > (PAGE_SIZE - sizeof(struct ethtool_gstrings))/ETH_GSTRING_LEN ) { + err = -EINVAL; + goto out; + } + len = (len*ETH_GSTRING_LEN) + sizeof(struct ethtool_gstrings); + break; + } + case ETHTOOL_GSTATS: { + struct ethtool_stats *statsaddr = (struct ethtool_stats *)A(data); + if (get_user(len, (u32 *)&statsaddr->n_stats)) { + err = -EFAULT; + goto out; + } + if (len > (PAGE_SIZE - sizeof(struct ethtool_stats))/sizeof(u64) ) { + err = -EINVAL; + goto out; + } + len = (len*sizeof(u64)) + sizeof(struct ethtool_stats); + break; + } + case ETHTOOL_SWOL: + case ETHTOOL_GWOL: + len = sizeof(struct ethtool_wolinfo); + break; + case ETHTOOL_GDRVINFO: + len = sizeof(struct ethtool_drvinfo); + break; case ETHTOOL_GMSGLVL: case ETHTOOL_SMSGLVL: case ETHTOOL_GLINK: - case ETHTOOL_NWAY_RST: len = sizeof(struct ethtool_value); break; + case ETHTOOL_NWAY_RST: + case ETHTOOL_SSG: + case ETHTOOL_GSG: + case ETHTOOL_GTXCSUM: + case ETHTOOL_STXCSUM: + case ETHTOOL_GRXCSUM: + case ETHTOOL_SRXCSUM: + case ETHTOOL_PHYS_ID: + len = sizeof(struct ethtool_value); + break; case ETHTOOL_GREGS: { struct ethtool_regs *regaddr = (struct ethtool_regs *)A(data); /* darned variable size arguments */ @@ -578,11 +619,44 @@ err = -EFAULT; goto out; } + if (len > PAGE_SIZE - sizeof(struct ethtool_regs)) { + err = -EINVAL; + goto out; + } 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; + } + if (len > PAGE_SIZE - sizeof(struct ethtool_eeprom)) { + err = -EINVAL; + goto out; + } + len += sizeof(struct ethtool_eeprom); + break; + } + case ETHTOOL_GRINGPARAM: + case ETHTOOL_SRINGPARAM: + len = sizeof(struct ethtool_ringparam); + break; + case ETHTOOL_GPAUSEPARAM: + case ETHTOOL_SPAUSEPARAM: + len = sizeof(struct ethtool_pauseparam); + break; + case ETHTOOL_GCOALESCE: + case ETHTOOL_SCOALESCE: + len = sizeof(struct ethtool_coalesce); + break; case ETHTOOL_GSET: - case ETHTOOL_SSET: len = sizeof(struct ethtool_cmd); break; + case ETHTOOL_SSET: + len = sizeof(struct ethtool_cmd); + break; default: err = -EOPNOTSUPP; goto out; @@ -1227,12 +1301,16 @@ u32 iov_len; } sg_iovec32_t; +#define EMU_SG_MAX 128 + static int alloc_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32) { sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32); sg_iovec_t *kiov; int i; + if (sgp->iovec_count > EMU_SG_MAX) + return -EINVAL; sgp->dxferp = kmalloc(sgp->iovec_count * sizeof(sg_iovec_t), GFP_KERNEL); if (!sgp->dxferp) @@ -1246,39 +1324,9 @@ if (__get_user(iov_base32, &uiov->iov_base) || __get_user(kiov->iov_len, &uiov->iov_len)) return -EFAULT; - - kiov->iov_base = kmalloc(kiov->iov_len, GFP_KERNEL); - if (!kiov->iov_base) - return -ENOMEM; - if (copy_from_user(kiov->iov_base, - (void *) A(iov_base32), - kiov->iov_len)) + if (verify_area(VERIFY_WRITE, (void *)A(iov_base32), kiov->iov_len)) return -EFAULT; - - uiov++; - kiov++; - } - - return 0; -} - -static int copy_back_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32) -{ - sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32); - sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp; - int i; - - for (i = 0; i < sgp->iovec_count; i++) { - u32 iov_base32; - - if (__get_user(iov_base32, &uiov->iov_base)) - return -EFAULT; - - if (copy_to_user((void *) A(iov_base32), - kiov->iov_base, - kiov->iov_len)) - return -EFAULT; - + kiov->iov_base = (void *)A(iov_base32); uiov++; kiov++; } @@ -1288,16 +1336,6 @@ static void free_sg_iovec(sg_io_hdr_t *sgp) { - sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp; - int i; - - for (i = 0; i < sgp->iovec_count; i++) { - if (kiov->iov_base) { - kfree(kiov->iov_base); - kiov->iov_base = NULL; - } - kiov++; - } kfree(sgp->dxferp); sgp->dxferp = NULL; } @@ -1326,6 +1364,10 @@ sg_io64.sbp = NULL; err |= __get_user(cmdp32, &sg_io32->cmdp); + if (sg_io64.cmd_len > 4*PAGE_SIZE || sg_io64.mx_sb_len > 4*PAGE_SIZE) { + err = -EINVAL; + goto out; + } sg_io64.cmdp = kmalloc(sg_io64.cmd_len, GFP_KERNEL); if (!sg_io64.cmdp) { err = -ENOMEM; @@ -1360,6 +1402,10 @@ goto out; } } else { + if (sg_io64.dxfer_len > 4*PAGE_SIZE) { + err = -EINVAL; + goto out; + } sg_io64.dxferp = kmalloc(sg_io64.dxfer_len, GFP_KERNEL); if (!sg_io64.dxferp) { err = -ENOMEM; @@ -1400,7 +1446,7 @@ err |= copy_to_user((void *)A(sbp32), sg_io64.sbp, sg_io64.mx_sb_len); if (sg_io64.dxferp) { if (sg_io64.iovec_count) - err |= copy_back_sg_iovec(&sg_io64, dxferp32); + ; else err |= copy_to_user((void *)A(dxferp32), sg_io64.dxferp, @@ -1456,6 +1502,8 @@ case PPPIOCSCOMPRESS32: if (copy_from_user(&data32, (struct ppp_option_data32 *)arg, sizeof(struct ppp_option_data32))) return -EFAULT; + if (data32.length > PAGE_SIZE) + return -EINVAL; data.ptr = kmalloc (data32.length, GFP_KERNEL); if (!data.ptr) return -ENOMEM; @@ -1658,10 +1706,9 @@ err |= __get_user(addr, &((struct cdrom_read_audio32 *)arg)->buf); if (err) return -EFAULT; - data = kmalloc(cdreadaudio.nframes * 2352, GFP_KERNEL); - if (!data) - return -ENOMEM; - cdreadaudio.buf = data; + if (verify_area(VERIFY_WRITE, (void *)A(addr), cdreadaudio.nframes*2352)) + return -EFAULT; + cdreadaudio.buf = (void *)A(addr); break; case CDROM_SEND_PACKET: karg = &cgc; @@ -1670,9 +1717,9 @@ err |= __get_user(cgc.buflen, &((struct cdrom_generic_command32 *)arg)->buflen); if (err) return -EFAULT; - if ((data = kmalloc(cgc.buflen, GFP_KERNEL)) == NULL) - return -ENOMEM; - cgc.buffer = data; + if (verify_area(VERIFY_WRITE, (void *)A(addr), cgc.buflen)) + return -EFAULT; + cgc.buffer = (void *)A(addr); break; default: do { @@ -1687,18 +1734,6 @@ set_fs (KERNEL_DS); err = sys_ioctl (fd, cmd, (unsigned long)karg); set_fs (old_fs); - if (err) - goto out; - switch (cmd) { - case CDROMREADAUDIO: - err = copy_to_user((char *)A(addr), data, cdreadaudio.nframes * 2352); - break; - case CDROM_SEND_PACKET: - err = copy_to_user((char *)A(addr), data, cgc.buflen); - break; - default: - break; - } out: if (data) kfree(data); return err ? -EFAULT : 0; @@ -2115,37 +2150,16 @@ if (iobuf32.buffer == (__kernel_caddr_t32) NULL || iobuf32.length == 0) { iobuf.buffer = (void*)(unsigned long)iobuf32.buffer; } else { - iobuf.buffer = kmalloc(iobuf.length, GFP_KERNEL); - if (iobuf.buffer == NULL) { - err = -ENOMEM; - goto out; - } - - err = copy_from_user(iobuf.buffer, (void *)A(iobuf32.buffer), iobuf.length); - if (err) { - err = -EFAULT; - goto out; - } + iobuf.buffer = A(iobuf32.buffer); + if (verify_area(VERIFY_WRITE, iobuf.buffer, iobuf.length)) + return -EINVAL; } old_fs = get_fs(); set_fs (KERNEL_DS); - err = sys_ioctl (fd, cmd, (unsigned long)&iobuf); + err = sys_ioctl (fd, cmd, (unsigned long)&iobuf); set_fs (old_fs); - if (err) - goto out; - - if (iobuf.buffer && iobuf.length > 0) { - err = copy_to_user((void *)A(iobuf32.buffer), iobuf.buffer, iobuf.length); - if (err) { - err = -EFAULT; - goto out; - } - } - err = __put_user(iobuf.length, &(((struct atm_iobuf32*)arg)->length)); - - out: - if (iobuf32.buffer && iobuf32.length > 0) - kfree(iobuf.buffer); + if (!err) + err = __put_user(iobuf.length, &(((struct atm_iobuf32*)arg)->length)); return err; } @@ -2168,40 +2182,19 @@ if (sioc32.arg == (__kernel_caddr_t32) NULL || sioc32.length == 0) { sioc.arg = (void*)(unsigned long)sioc32.arg; - } else { - sioc.arg = kmalloc(sioc.length, GFP_KERNEL); - if (sioc.arg == NULL) { - err = -ENOMEM; - goto out; - } - - err = copy_from_user(sioc.arg, (void *)A(sioc32.arg), sioc32.length); - if (err) { - err = -EFAULT; - goto out; - } - } - - old_fs = get_fs(); set_fs (KERNEL_DS); - err = sys_ioctl (fd, cmd, (unsigned long)&sioc); - set_fs (old_fs); - if (err) { - goto out; + } else { + sioc.arg = A(sioc32.arg); + if (verify_area(VERIFY_WRITE, sioc.arg, sioc32.length)) + return -EFAULT; } - - if (sioc.arg && sioc.length > 0) { - err = copy_to_user((void *)A(sioc32.arg), sioc.arg, sioc.length); - if (err) { - err = -EFAULT; - goto out; - } - } - err = __put_user(sioc.length, &(((struct atmif_sioc32*)arg)->length)); - - out: - if (sioc32.arg && sioc32.length > 0) - kfree(sioc.arg); - + + old_fs = get_fs(); set_fs (KERNEL_DS); + err = sys_ioctl (fd, cmd, (unsigned long)&sioc); + set_fs (old_fs); + + if (!err) + err = __put_user(sioc.length, &(((struct atmif_sioc32*)arg)->length)); + return err; } @@ -2417,12 +2410,24 @@ return NULL; } if (ptr1) { + if (l->lv_allocated_le > 2*PAGE_SIZE/sizeof(pe_t)) { + kfree(l); + *errp = -EINVAL; + return NULL; + } size = l->lv_allocated_le * sizeof(pe_t); l->lv_current_pe = vmalloc(size); if (l->lv_current_pe) err = copy_from_user(l->lv_current_pe, (void *)A(ptr1), size); } if (!err && ptr2) { + /* small limit */ + /* just verify area it? */ + if (l->lv_remap_end > 256*PAGE_SIZE/sizeof(lv_block_exception_t)) { + put_lv_t(l); + *errp = -EINVAL; + return NULL; + } size = l->lv_remap_end * sizeof(lv_block_exception_t); l->lv_block_exception = lbe = vmalloc(size); if (l->lv_block_exception) { @@ -3070,7 +3075,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) @@ -3586,17 +3591,11 @@ goto out; uptr = (void *) A(udata); - err = -ENOMEM; buflen = kurb->buffer_length; - kptr = kmalloc(buflen, GFP_KERNEL); - if (!kptr) - goto out; - - kurb->buffer = kptr; - err = -EFAULT; - if (copy_from_user(kptr, uptr, buflen)) - goto out_kptr; + err = verify_area(VERIFY_WRITE, uptr, buflen); + if (err) + goto out; old_fs = get_fs(); set_fs(KERNEL_DS); @@ -3607,15 +3606,9 @@ /* XXX Shit, this doesn't work for async URBs :-( XXX */ if (put_urb32(kurb, uurb)) { err = -EFAULT; - } else if ((kurb->endpoint & USB_DIR_IN) != 0) { - if (copy_to_user(uptr, kptr, buflen)) - err = -EFAULT; } } -out_kptr: - kfree(kptr); - out: kfree(kurb); return err; @@ -3687,14 +3680,13 @@ #define MEMWRITEOOB32 _IOWR('M',3,struct mtd_oob_buf32) #define MEMREADOOB32 _IOWR('M',4,struct mtd_oob_buf32) -static inline int +static inline int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg) { mm_segment_t old_fs = get_fs(); struct mtd_oob_buf32 *uarg = (struct mtd_oob_buf32 *)arg; struct mtd_oob_buf karg; u32 tmp; - char *ptr; int ret; if (get_user(karg.start, &uarg->start) || @@ -3702,21 +3694,12 @@ get_user(tmp, &uarg->ptr)) return -EFAULT; - ptr = (char *)A(tmp); - if (0 >= karg.length) - return -EINVAL; - - karg.ptr = kmalloc(karg.length, GFP_KERNEL); - if (NULL == karg.ptr) - return -ENOMEM; - - if (copy_from_user(karg.ptr, ptr, karg.length)) { - kfree(karg.ptr); + karg.ptr = A(tmp); + if (verify_area(VERIFY_WRITE, karg.ptr, karg.length)) return -EFAULT; - } set_fs(KERNEL_DS); - if (MEMREADOOB32 == cmd) + if (MEMREADOOB32 == cmd) ret = sys_ioctl(fd, MEMREADOOB, (unsigned long)&karg); else if (MEMWRITEOOB32 == cmd) ret = sys_ioctl(fd, MEMWRITEOOB, (unsigned long)&karg); @@ -3725,14 +3708,12 @@ set_fs(old_fs); if (0 == ret && cmd == MEMREADOOB32) { - ret = copy_to_user(ptr, karg.ptr, karg.length); - ret |= put_user(karg.start, &uarg->start); + ret = put_user(karg.start, &uarg->start); ret |= put_user(karg.length, &uarg->length); } - kfree(karg.ptr); - return ((0 == ret) ? 0 : -EFAULT); -} + return ret; +} /* Fix sizeof(sizeof()) breakage */ #define BLKELVGET_32 _IOR(0x12,106,int) @@ -3790,6 +3771,7 @@ COMPATIBLE_IOCTL(TCSETAW), COMPATIBLE_IOCTL(TCSETAF), COMPATIBLE_IOCTL(TCSBRK), +COMPATIBLE_IOCTL(TCSBRKP), COMPATIBLE_IOCTL(TCXONC), COMPATIBLE_IOCTL(TCFLSH), COMPATIBLE_IOCTL(TCGETS), @@ -3825,6 +3807,8 @@ COMPATIBLE_IOCTL(TIOCSSERIAL), COMPATIBLE_IOCTL(TIOCSERGETLSR), COMPATIBLE_IOCTL(TIOCSLTC), +COMPATIBLE_IOCTL(TIOCMIWAIT), +COMPATIBLE_IOCTL(TIOCGICOUNT), /* Big F */ COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO), COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO), @@ -3894,6 +3878,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), Index: arch/ppc64/kernel/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/irq.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/irq.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -56,8 +57,47 @@ #include #include -#include "local_irq.h" +/* + * Because the name space for interrupts is so large on ppc64 systems we + * avoid declaring a single array of "NR_IRQ" interrupts and instead build + * a three level tree leading to the irq_desc_t (similar to page tables). + * + * Currently we cover 24-bit irq values: + * 10-bits: the "base" dir (2-pages) + * 9-bits: the "middle" dir (1-page) + * 5-bits: the "bottom" page (1-page) holding 128byte irq_desc's. + * + * We pack a hw_irq_stat struct directly after the irq_desc in the otherwise + * wasted space of the cacheline. + * + * MAX_IRQS is the max this implementation will support. + * It is much larger than NR_IRQS which is bogus on this arch and often used + * to declare arrays. + * + * Note that all "undefined" mid table and bottom table pointers will point + * to dummy tables. Therefore, we don't need to check for NULL on spurious + * interrupts. + */ + +#define IRQ_BASE_INDEX_SIZE 10 +#define IRQ_MID_INDEX_SIZE 9 +#define IRQ_BOT_DESC_SIZE 5 + +#define IRQ_BASE_PTRS (1 << IRQ_BASE_INDEX_SIZE) +#define IRQ_MID_PTRS (1 << IRQ_MID_INDEX_SIZE) +#define IRQ_BOT_DESCS (1 << IRQ_BOT_DESC_SIZE) + +#define IRQ_BASE_IDX_SHIFT (IRQ_MID_INDEX_SIZE + IRQ_BOT_DESC_SIZE) +#define IRQ_MID_IDX_SHIFT (IRQ_BOT_DESC_SIZE) +#define IRQ_MID_IDX_MASK ((1 << IRQ_MID_INDEX_SIZE) - 1) +#define IRQ_BOT_IDX_MASK ((1 << IRQ_BOT_DESC_SIZE) - 1) + +irq_desc_t **irq_desc_base_dir[IRQ_BASE_PTRS] __page_aligned = {0}; +irq_desc_t **irq_desc_mid_null; +irq_desc_t *irq_desc_bot_null; + +unsigned int _next_irq(unsigned int irq); atomic_t ipi_recv; atomic_t ipi_sent; void enable_irq(unsigned int irq_nr); @@ -72,9 +112,10 @@ irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { [0 ... NR_IRQS-1] = { 0, NULL, NULL, 0, SPIN_LOCK_UNLOCKED}}; - + +static irq_desc_t *add_irq_desc(unsigned int irq); + int ppc_spurious_interrupts = 0; -struct irqaction *ppc_irq_action[NR_IRQS]; unsigned long lpEvent_count = 0; #ifdef CONFIG_XMON extern void xmon(struct pt_regs *regs); @@ -93,16 +134,200 @@ extern void (*debugger_fault_handler)(struct pt_regs *regs); #endif -/* nasty hack for shared irq's since we need to do kmalloc calls but - * can't very early in the boot when we need to do a request irq. - * this needs to be removed. - * -- Cort - */ #define IRQ_KMALLOC_ENTRIES 16 static int cache_bitmask = 0; static struct irqaction malloc_cache[IRQ_KMALLOC_ENTRIES]; extern int mem_init_done; +/* The hw_irq_stat struct is stored directly after the irq_desc_t + * in the same cacheline. We need to use care to make sure we don't + * overrun the size of the cacheline. + * + * Currently sizeof(irq_desc_t) is 40 bytes or less and this hw_irq_stat + * fills the rest of the cache line. + */ +struct hw_irq_stat { + unsigned long irqs; /* statistic per irq */ + unsigned long *per_cpu_stats; + struct proc_dir_entry *irq_dir, *smp_affinity; + unsigned long irq_affinity; /* ToDo: cpu bitmask */ +}; + +static inline struct hw_irq_stat *get_irq_stat(irq_desc_t *desc) +{ + /* WARNING: this assumes lock is the last field! */ + return (struct hw_irq_stat *)(&desc->lock+1); +} + +static inline unsigned long *get_irq_per_cpu(struct hw_irq_stat *hw) +{ + return hw->per_cpu_stats; +} + +static inline irq_desc_t **get_irq_mid_table(unsigned int irq) +{ + /* Assume irq < MAX_IRQS so we won't index off the end. */ + return irq_desc_base_dir[irq >> IRQ_BASE_IDX_SHIFT]; +} + +static inline irq_desc_t *get_irq_bot_table(unsigned int irq, + irq_desc_t **mid_ptr) +{ + return mid_ptr[(irq >> IRQ_MID_IDX_SHIFT) & IRQ_MID_IDX_MASK]; +} + +/* This should be inline. */ +void *_irqdesc(unsigned int irq) +{ + irq_desc_t **mid_table, *bot_table, *desc; + + mid_table = get_irq_mid_table(irq); + bot_table = get_irq_bot_table(irq, mid_table); + + desc = bot_table + (irq & IRQ_BOT_IDX_MASK); + return desc; +} + +/* + * This is used by the for_each_irq(i) macro to iterate quickly over + * all interrupts. It optimizes by skipping over ptrs to the null tables + * when possible, but it may produce false positives. + */ +unsigned int _next_irq(unsigned int irq) +{ + irq_desc_t **mid_table, *bot_table; + + irq++; + /* Easy case first...staying on the current bot_table. */ + if (irq & IRQ_BOT_IDX_MASK) + return irq; + + /* Now skip empty mid tables */ + while (irq < MAX_IRQS && + (mid_table = get_irq_mid_table(irq)) == irq_desc_mid_null) { + /* index to the next base index (i.e. the next mid table) */ + irq = (irq & ~(IRQ_BASE_IDX_SHIFT-1)) + IRQ_BASE_IDX_SHIFT; + } + /* And skip empty bot tables */ + while (irq < MAX_IRQS && + (bot_table = get_irq_bot_table(irq, mid_table)) == irq_desc_bot_null) { + /* index to the next mid index (i.e. the next bot table) */ + irq = (irq & ~(IRQ_MID_IDX_SHIFT-1)) + IRQ_MID_IDX_SHIFT; + } + return irq; +} + + +/* Same as irqdesc(irq) except it will "fault in" a real desc as needed + * rather than return the null entry. + * This is used by code that is actually defining the irq. + * + * NULL may be returned on memory allocation failure. In general, init code + * doesn't look for this, but setup_irq does. In this failure case the desc + * is left pointing at the null pages so callers of irqdesc() should + * always return something. + */ +void *_real_irqdesc(unsigned int irq) +{ + irq_desc_t *desc = irqdesc(irq); + if (((unsigned long)desc & PAGE_MASK) == + (unsigned long)irq_desc_bot_null) { + desc = add_irq_desc(irq); + } + return desc; +} + +/* Allocate an irq middle page and init entries to null page. */ +static irq_desc_t **alloc_irq_mid_page(void) +{ + irq_desc_t **m, **ent; + + if (mem_init_done) + m = (irq_desc_t **)__get_free_page(GFP_KERNEL); + else + m = (irq_desc_t **)alloc_bootmem_pages(PAGE_SIZE); + if (m) { + for (ent = m; ent < m + IRQ_MID_PTRS; ent++) { + *ent = irq_desc_bot_null; + } + } + return m; +} + +/* Allocate an irq bottom page and init the entries. */ +static irq_desc_t *alloc_irq_bot_page(void) +{ + irq_desc_t *b, *ent; + if (mem_init_done) + b = (irq_desc_t *)get_zeroed_page(GFP_KERNEL); + else + b = (irq_desc_t *)alloc_bootmem_pages(PAGE_SIZE); + if (b) { + for (ent = b; ent < b + IRQ_BOT_DESCS; ent++) { + ent->lock = SPIN_LOCK_UNLOCKED; + } + } + return b; +} + +/* + * The universe of interrupt numbers ranges from 0 to 2^24. + * Use a sparsely populated tree to map from the irq to the handler. + * Top level is 2 contiguous pages, covering the 10 most significant + * bits. Mid level is 1 page, covering 9 bits. Last page covering + * 5 bits is the irq_desc, each of which is 128B. + */ +static void irq_desc_init(void) { + irq_desc_t ***entry_p; + + /* + * Now initialize the tables to point though the NULL tables for + * the default case of no interrupt handler (spurious). + */ + irq_desc_bot_null = alloc_irq_bot_page(); + irq_desc_mid_null = alloc_irq_mid_page(); + if (!irq_desc_bot_null || !irq_desc_mid_null) + panic("irq_desc_init: could not allocate pages\n"); + for(entry_p = irq_desc_base_dir; + entry_p < irq_desc_base_dir + IRQ_BASE_PTRS; + entry_p++) { + *entry_p = irq_desc_mid_null; + } +} + +/* + * Add a new irq desc for the given irq if needed. + * This breaks any ptr to the "null" middle or "bottom" irq desc page. + * Note that we don't ever coalesce pages as the interrupts are released. + * This isn't worth the effort. We add the cpu stats info when the + * interrupt is actually requested. + * + * May return NULL if memory could not be allocated. + */ +static irq_desc_t *add_irq_desc(unsigned int irq) +{ + irq_desc_t **mid_table_p, *bot_table_p; + + mid_table_p = get_irq_mid_table(irq); + if(mid_table_p == irq_desc_mid_null) { + /* No mid table for this IRQ - create it */ + mid_table_p = alloc_irq_mid_page(); + if (!mid_table_p) return NULL; + irq_desc_base_dir[irq >> IRQ_BASE_IDX_SHIFT] = mid_table_p; + } + + bot_table_p = (irq_desc_t *)(*(mid_table_p + ((irq >> 5) & 0x1ff))); + + if(bot_table_p == irq_desc_bot_null) { + /* No bot table for this IRQ - create it */ + bot_table_p = alloc_irq_bot_page(); + if (!bot_table_p) return NULL; + mid_table_p[(irq >> IRQ_MID_IDX_SHIFT) & IRQ_MID_IDX_MASK] = bot_table_p; + } + + return bot_table_p + (irq & IRQ_BOT_IDX_MASK); +} + void *irq_kmalloc(size_t size, int pri) { unsigned int i; @@ -127,13 +352,44 @@ kfree(ptr); } +void allocate_per_cpu_stats(struct hw_irq_stat *hwstat) +{ + unsigned long *p; + + if (mem_init_done) { + p = (unsigned long *)kmalloc(sizeof(long)*NR_CPUS, GFP_KERNEL); + if (p) memset(p, 0, sizeof(long)*NR_CPUS); + } else + p = (unsigned long *)alloc_bootmem(sizeof(long)*NR_CPUS); + hwstat->per_cpu_stats = p; +} + 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; + irq_desc_t *desc = real_irqdesc(irq); + struct hw_irq_stat *hwstat; + + if (!desc) + return -ENOMEM; + + ppc_md.init_irq_desc(desc); + + hwstat = get_irq_stat(desc); + +#ifdef CONFIG_IRQ_ALL_CPUS + hwstat->irq_affinity = ~0; +#else + hwstat->irq_affinity = 0; +#endif + + /* Now is the time to add per-cpu kstat data to the desc + * since it appears we are actually going to use the irq. + */ + allocate_per_cpu_stats(hwstat); /* * Some drivers like serial.c use request_irq() heavily, @@ -189,11 +445,10 @@ static int do_free_irq(int irq, void* dev_id) { - irq_desc_t *desc; + irq_desc_t *desc = irqdesc(irq); struct irqaction **p; unsigned long flags; - desc = irq_desc + irq; spin_lock_irqsave(&desc->lock,flags); p = &desc->action; for (;;) { @@ -233,8 +488,9 @@ struct irqaction *action; int retval; - if (irq >= NR_IRQS) + if (irq >= MAX_IRQS) return -EINVAL; + if (!handler) /* We could implement really free_irq() instead of that... */ return do_free_irq(irq, dev_id); @@ -285,7 +541,7 @@ void disable_irq_nosync(unsigned int irq) { - irq_desc_t *desc = irq_desc + irq; + irq_desc_t *desc = irqdesc(irq); unsigned long flags; spin_lock_irqsave(&desc->lock, flags); @@ -317,7 +573,7 @@ if (!local_irq_count(smp_processor_id())) { do { barrier(); - } while (irq_desc[irq].status & IRQ_INPROGRESS); + } while (irqdesc(irq)->status & IRQ_INPROGRESS); } } @@ -333,7 +589,7 @@ void enable_irq(unsigned int irq) { - irq_desc_t *desc = irq_desc + irq; + irq_desc_t *desc = irqdesc(irq); unsigned long flags; spin_lock_irqsave(&desc->lock, flags); @@ -357,82 +613,57 @@ spin_unlock_irqrestore(&desc->lock, flags); } -/* one would think this function has one foot in the grave */ +/* This function as implemented was a potential source of data + * corruption. I pulled it for now, until it can be properly + * implemented. DRENG + */ int get_irq_list(char *buf) { - int i, len = 0, j; - struct irqaction * action; - - len += sprintf(buf+len, " "); - for (j=0; jhandler ) - continue; - 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 - len += sprintf(buf+len, "%10u ", kstat_irqs(i)); -#endif /* CONFIG_SMP */ -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", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge "); -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"); + return(0); } -#ifdef CONFIG_SMP -/* 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 -len += sprintf(buf+len, "BAD: %10u\n", ppc_spurious_interrupts); -return len; -} - - int show_interrupts(struct seq_file *p, void *v) { int i, j; struct irqaction * action; + irq_desc_t *desc; + struct hw_irq_stat *hwstat; + unsigned long *per_cpus; + unsigned long flags; seq_printf(p, " "); for (j=0; jlock, flags); + action = desc->action; + if (!action || !action->handler) - continue; - seq_printf(p, "%3d: ", i); -#ifdef CONFIG_SMP + goto skip; + seq_printf(p, "%3d: ", i); + hwstat = get_irq_stat(desc); + per_cpus = get_irq_per_cpu(hwstat); + if (per_cpus) { for (j = 0; j < smp_num_cpus; j++) - seq_printf(p, "%10u ", - kstat.irqs[cpu_logical_map(j)][i]); -#else - seq_printf(p, "%10u ", kstat_irqs(i)); -#endif /* CONFIG_SMP */ - if (irq_desc[i].handler) - seq_printf(p, " %s ", irq_desc[i].handler->typename ); + seq_printf(p, "%10lu ", per_cpus[j]); + } else { + seq_printf(p, "%10lu ", hwstat->irqs); + } + + if (irqdesc(i)->handler) + seq_printf(p, " %s ", irqdesc(i)->handler->typename ); else seq_printf(p, " None "); - seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge "); + seq_printf(p, "%s", (irqdesc(i)->status & IRQ_LEVEL) ? "Level " : "Edge "); seq_printf(p, " %s",action->name); for (action=action->next; action; action = action->next) seq_printf(p, ", %s", action->name); seq_putc(p, '\n'); +skip: + spin_unlock_irqrestore(&desc->lock, flags); } #ifdef CONFIG_SMP /* should this be per processor send/receive? */ @@ -470,9 +701,24 @@ int status; struct irqaction *action; int cpu = smp_processor_id(); - irq_desc_t *desc = irq_desc + irq; + irq_desc_t *desc = irqdesc(irq); + struct hw_irq_stat *hwstat; + unsigned long *per_cpus; + + /* Statistics. */ + hwstat = get_irq_stat(desc); /* same cache line as desc */ + hwstat->irqs++; + per_cpus = get_irq_per_cpu(hwstat); /* same cache line for < 8 cpus */ + if (per_cpus) + per_cpus[cpu]++; + if(irq < NR_IRQS) { kstat.irqs[cpu][irq]++; + } else { + kstat.irqs[cpu][NR_IRQS-1]++; + } + + spin_lock(&desc->lock); ack_irq(irq); /* @@ -544,11 +790,11 @@ * The ->end() handler has to deal with interrupts which got * disabled while the handler was running. */ - 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); + if (desc->handler) { + if (desc->handler->end) + desc->handler->end(irq); + else if (desc->handler->enable) + desc->handler->enable(irq); } spin_unlock(&desc->lock); } @@ -638,7 +884,10 @@ return; else once++; - + + /* Initialize the irq tree */ + irq_desc_init(); + ppc_md.init_IRQ(); if(ppc_md.init_ras_IRQ) ppc_md.init_ras_IRQ(); } @@ -794,6 +1043,7 @@ #endif /* CONFIG_SMP */ static struct proc_dir_entry * root_irq_dir; +#if 0 static struct proc_dir_entry * irq_dir [NR_IRQS]; static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; @@ -802,15 +1052,19 @@ #else /* CONFIG_IRQ_ALL_CPUS */ unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0x00000000}; #endif /* CONFIG_IRQ_ALL_CPUS */ +#endif #define HEX_DIGITS 8 static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { + irq_desc_t *desc = irqdesc((long)data); + struct hw_irq_stat *hwstat = get_irq_stat(desc); + if (count < HEX_DIGITS+1) return -EINVAL; - return sprintf (page, "%08x\n", irq_affinity[(int)(long)data]); + return sprintf(page, "%16lx\n", hwstat->irq_affinity); } static unsigned int parse_hex_value (const char *buffer, @@ -853,10 +1107,13 @@ static int irq_affinity_write_proc (struct file *file, const char *buffer, unsigned long count, void *data) { - int irq = (int)(long) data, full_count = count, err; + unsigned int irq = (long)data; + irq_desc_t *desc = irqdesc(irq); + struct hw_irq_stat *hwstat = get_irq_stat(desc); + int full_count = count, err; unsigned long new_value; - if (!irq_desc[irq].handler->set_affinity) + if (!desc->handler->set_affinity) return -EIO; err = parse_hex_value(buffer, count, &new_value); @@ -871,10 +1128,8 @@ if (!(new_value & cpu_online_map)) return -EINVAL; #endif - - irq_affinity[irq] = new_value; - irq_desc[irq].handler->set_affinity(irq, new_value); - + hwstat->irq_affinity = new_value; + desc->handler->set_affinity(irq, new_value); return full_count; } @@ -923,25 +1178,39 @@ { struct proc_dir_entry *entry; char name [MAX_NAMELEN]; + irq_desc_t *desc; + struct hw_irq_stat *hwstat; - if (!root_irq_dir || (irq_desc[irq].handler == NULL)) + desc = real_irqdesc(irq); + if (!root_irq_dir || !desc || !desc->handler) + return; + hwstat = get_irq_stat(desc); + if (hwstat->irq_dir) return; memset(name, 0, MAX_NAMELEN); sprintf(name, "%d", irq); /* create /proc/irq/1234 */ - irq_dir[irq] = proc_mkdir(name, root_irq_dir); + hwstat->irq_dir = proc_mkdir(name, root_irq_dir); + if(hwstat->irq_dir == NULL) { + printk(KERN_ERR "register_irq_proc: proc_mkdir failed.\n"); + return; + } /* create /proc/irq/1234/smp_affinity */ - entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]); + entry = create_proc_entry("smp_affinity", 0600, hwstat->irq_dir); - entry->nlink = 1; - entry->data = (void *)(long)irq; - entry->read_proc = irq_affinity_read_proc; - entry->write_proc = irq_affinity_write_proc; + if(entry) { + entry->nlink = 1; + entry->data = (void *)(long)irq; + entry->read_proc = irq_affinity_read_proc; + entry->write_proc = irq_affinity_write_proc; + } else { + printk(KERN_ERR "register_irq_proc: create_proc_entry failed.\n"); + } - smp_affinity_entry[irq] = entry; + hwstat->smp_affinity = entry; } unsigned long prof_cpu_mask = -1; @@ -953,20 +1222,27 @@ /* create /proc/irq */ root_irq_dir = proc_mkdir("irq", 0); + if(root_irq_dir == NULL) { + printk(KERN_ERR "init_irq_proc: proc_mkdir failed.\n"); + } /* create /proc/irq/prof_cpu_mask */ entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir); - entry->nlink = 1; - entry->data = (void *)&prof_cpu_mask; - entry->read_proc = prof_cpu_mask_read_proc; - entry->write_proc = prof_cpu_mask_write_proc; + if(entry) { + entry->nlink = 1; + entry->data = (void *)&prof_cpu_mask; + entry->read_proc = prof_cpu_mask_read_proc; + entry->write_proc = prof_cpu_mask_write_proc; + } else { + printk(KERN_ERR "init_irq_proc: create_proc_entry failed.\n"); + } /* * Create entries for all existing IRQs. */ - for (i = 0; i < NR_IRQS; i++) { - if (irq_desc[i].handler == NULL) + for_each_irq(i) { + if (irqdesc(i)->handler == NULL) continue; register_irq_proc(i); } Index: arch/ppc64/kernel/mf.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/mf.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/mf.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/mf.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -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 ) { Index: arch/ppc64/kernel/mf_proc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/mf_proc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/mf_proc.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/mf_proc.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -220,19 +220,22 @@ int proc_mf_change_side(struct file *file, const char *buffer, unsigned long count, void *data) { + char side; + if (!capable(CAP_SYS_ADMIN)) return -EACCES; + if (count == 0) + return 0; + if (get_user(side, buffer)) + return -EFAULT; - if ((*buffer != 'A') && - (*buffer != 'B') && - (*buffer != 'C') && - (*buffer != 'D')) + if ((side != 'A') && (side != 'B') && (side != 'C') && (side != 'D')) { printk(KERN_ERR "mf_proc.c: proc_mf_change_side: invalid side\n"); return -EINVAL; } - mf_setSide(*buffer); + mf_setSide(side); return count; } @@ -256,20 +259,24 @@ int proc_mf_change_src(struct file *file, const char *buffer, unsigned long count, void *data) { + char stkbuf[10]; if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if ((count < 4) && (count != 1)) - { + if ((count < 4) && (count != 1)) { printk(KERN_ERR "mf_proc: invalid src\n"); return -EINVAL; } - if ((count == 1) && ((*buffer) == '\0')) - { + if (count > 9) + count = 9; + if (copy_from_user (stkbuf, buffer, count)) + return -EFAULT; + + if ((count == 1) && ((*stkbuf) == '\0')) { mf_clearSrc(); } else { - mf_displaySrc(*(u32 *)buffer); + mf_displaySrc(*(u32 *)stkbuf); } return count; Index: arch/ppc64/kernel/misc.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/misc.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/misc.S 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/misc.S 4 Aug 2004 01:26:10 -0000 1.2 @@ -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 @@ -68,16 +69,14 @@ _GLOBAL(__no_use_save_flags) mfspr r4,SPRG3 lbz r3,PACAPROCENABLED(r4) + /* shift into position of MSR.EE */ + sldi r3,r3,15 blr -/* void __no_use_restore_flags(unsigned long flags) */ +/* void __no_use_restore_flags(unsigned long flags) */ _GLOBAL(__no_use_restore_flags) -/* - * Just set/clear the MSR_EE bit through restore/flags but do not - * change anything else. This is needed by the RT system and makes - * sense anyway. - * -- Cort - */ + /* shift from position of MSR.EE */ + srdi r3,r3,15 mfspr r6,SPRG3 lbz r5,PACAPROCENABLED(r6) /* Check if things are setup the way we want _already_. */ @@ -103,6 +102,8 @@ lbz r3,PACAPROCENABLED(r5) li r4,0 stb r4,PACAPROCENABLED(r5) + /* shift into position of MSR.EE */ + sldi r3,r3,15 blr /* Done */ _GLOBAL(__no_use_sti) @@ -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,96 @@ 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) +/* Dummy feature section to make sure section exists */ +BEGIN_FTR_SECTION +END_FTR_SECTION(0,0) + /* 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) */ @@ -492,9 +581,10 @@ bnelr /* return if parent */ li r0,0 /* clear out p->thread.regs */ - std r0,THREAD+PT_REGS(r13) /* since we don't have user ctx */ + ld r7,PACACURRENT(r13) + std r0,THREAD+PT_REGS(r7) /* since we don't have user ctx */ li r0,RUN_FLAG /* Run light on */ - std r0,THREAD+THREAD_FLAGS(r13) + std r0,THREAD+THREAD_FLAGS(r7) ld r2,8(r6) ld r6,0(r6) @@ -717,7 +807,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 +1038,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 Index: arch/ppc64/kernel/mk_defs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/mk_defs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/mk_defs.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/mk_defs.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -37,6 +37,7 @@ #include #include #include +#include #define DEFINE(sym, val) \ asm volatile("\n#define\t" #sym "\t%0" : : "i" (val)) @@ -132,6 +133,11 @@ DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0])); DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode)); DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr)); +#ifdef CONFIG_ALTIVEC + DEFINE(THREAD_VR0, offsetof(struct thread_struct, vr[0])); + DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave)); + DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr)); +#endif /* CONFIG_ALTIVEC */ DEFINE(THREAD_FLAGS, offsetof(struct thread_struct, flags)); DEFINE(PPC_FLAG_32BIT, PPC_FLAG_32BIT); /* @@ -188,5 +194,19 @@ 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)); + + /* 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; } Index: arch/ppc64/kernel/nvram.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/nvram.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/nvram.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/nvram.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -20,16 +20,44 @@ #include #include #include +#include +#include #include #include #include #include -static unsigned int rtas_nvram_size; +#include + +/*#define DEBUG_NVRAM*/ + +static int scan_nvram_partitions(void); +static int setup_nvram_partition(void); +static int create_os_nvram_partition(void); +static int remove_os_nvram_partition(void); +static unsigned char nvram_checksum(struct nvram_header *p); +static int write_nvram_header(struct nvram_partition * part); +static ssize_t __read_nvram(char *buf, size_t count, loff_t *index); +static ssize_t __write_nvram(char *buf, size_t count, loff_t *index); + +static unsigned int rtas_nvram_size = 0; static unsigned int nvram_fetch, nvram_store; -static char nvram_buf[4]; /* assume this is in the first 4GB */ +static char nvram_buf[NVRW_CNT]; /* assume this is in the first 4GB */ +static struct nvram_partition * nvram_part; +static long error_log_nvram_index = -1; +static long error_log_nvram_size = 0; +static spinlock_t nvram_lock = SPIN_LOCK_UNLOCKED; + +volatile int no_more_logging = 1; + +extern volatile int error_log_cnt; + +struct err_log_info { + int error_type; + unsigned int seq_num; +}; -static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) +static loff_t dev_ppc64_nvram_llseek(struct file *file, loff_t offset, int origin) { switch (origin) { case 1: @@ -46,53 +74,72 @@ } -static ssize_t read_nvram(struct file *file, char *buf, +static ssize_t dev_ppc64_read_nvram(struct file *file, char *buf, size_t count, loff_t *ppos) { - unsigned int i; unsigned long len; - char *p = buf; + char *tmp_buffer; if (verify_area(VERIFY_WRITE, buf, count)) return -EFAULT; if (*ppos >= rtas_nvram_size) return 0; - for (i = *ppos; count > 0 && i < rtas_nvram_size; ++i, ++p, --count) { - if ((rtas_call(nvram_fetch, 3, 2, &len, i, __pa(nvram_buf), 1) != 0) || - len != 1) - return -EIO; - if (__put_user(nvram_buf[0], p)) - return -EFAULT; + if (count > rtas_nvram_size) + count = rtas_nvram_size; + + tmp_buffer = kmalloc(count, GFP_KERNEL); + if (!tmp_buffer) { + printk(KERN_ERR "dev_ppc64_read_nvram: kmalloc failed\n"); + return 0; } - *ppos = i; - return p - buf; + + len = read_nvram(tmp_buffer, count, ppos); + if ((long)len <= 0) { + kfree(tmp_buffer); + return len; + } + + if (copy_to_user(buf, tmp_buffer, len)) { + kfree(tmp_buffer); + return -EFAULT; + } + + kfree(tmp_buffer); + return len; + } -static ssize_t write_nvram(struct file *file, const char *buf, +static ssize_t dev_ppc64_write_nvram(struct file *file, const char *buf, size_t count, loff_t *ppos) { - unsigned int i; unsigned long len; - const char *p = buf; - char c; + char * tmp_buffer; if (verify_area(VERIFY_READ, buf, count)) return -EFAULT; if (*ppos >= rtas_nvram_size) return 0; - for (i = *ppos; count > 0 && i < rtas_nvram_size; ++i, ++p, --count) { - if (__get_user(c, p)) - return -EFAULT; - nvram_buf[0] = c; - if ((rtas_call(nvram_store, 3, 2, &len, i, __pa(nvram_buf), 1) != 0) || - len != 1) - return -EIO; + if (count > rtas_nvram_size) + count = rtas_nvram_size; + + tmp_buffer = kmalloc(count, GFP_KERNEL); + if (!tmp_buffer) { + printk(KERN_ERR "dev_ppc64_write_nvram: kmalloc failed\n"); + return 0; } - *ppos = i; - return p - buf; + + if (copy_from_user(tmp_buffer, buf, count)) { + kfree(tmp_buffer); + return -EFAULT; + } + + len = write_nvram(tmp_buffer, count, ppos); + + kfree(tmp_buffer); + return len; } -static int nvram_ioctl(struct inode *inode, struct file *file, +static int dev_ppc64_nvram_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { return -EINVAL; @@ -100,10 +147,10 @@ struct file_operations nvram_fops = { .owner = THIS_MODULE, - .llseek = nvram_llseek, - .read = read_nvram, - .write = write_nvram, - .ioctl = nvram_ioctl, + .llseek = dev_ppc64_nvram_llseek, + .read = dev_ppc64_read_nvram, + .write = dev_ppc64_write_nvram, + .ioctl = dev_ppc64_nvram_ioctl }; static struct miscdevice nvram_dev = { @@ -112,26 +159,613 @@ &nvram_fops }; +ssize_t read_nvram(char *buf, size_t count, loff_t *index) +{ + unsigned long s; + ssize_t rc; + + spin_lock_irqsave(&nvram_lock, s); + rc = __read_nvram(buf, count, index); + spin_unlock_irqrestore(&nvram_lock, s); + + return rc; +} +static ssize_t __read_nvram(char *buf, size_t count, loff_t *index) +{ + unsigned int i; + unsigned long len; + unsigned long remainder; + char *p = buf; + + if (((*index + count) > rtas_nvram_size) || (count < 0)) + return 0; + + if (count <= NVRW_CNT) { + remainder = count; + } else { + remainder = count % NVRW_CNT; + } + + if (remainder) { + if((rtas_call(nvram_fetch, 3, 2, &len, *index, __pa(nvram_buf), + remainder) != 0) || len != remainder) { + return -EIO; + } + + count -= remainder; + memcpy(p, nvram_buf, remainder); + p += remainder; + } + + for (i = *index + remainder; count > 0 && i < rtas_nvram_size; + count -= NVRW_CNT) { + if ((rtas_call(nvram_fetch, 3, 2, &len, i, __pa(nvram_buf), + NVRW_CNT) != 0) || len != NVRW_CNT) { + return -EIO; + } + + memcpy(p, nvram_buf, NVRW_CNT); + + p += NVRW_CNT; + i += NVRW_CNT; + } + + *index = i; + return p - buf; +} + +ssize_t write_nvram(char *buf, size_t count, loff_t *index) +{ + unsigned long s; + ssize_t rc; + + spin_lock_irqsave(&nvram_lock, s); + rc = __write_nvram(buf, count, index); + spin_unlock_irqrestore(&nvram_lock, s); + + return rc; +} +static ssize_t __write_nvram(char *buf, size_t count, loff_t *index) +{ + unsigned int i; + unsigned long len; + const char *p = buf; + unsigned long remainder; + + if (((*index + count) > rtas_nvram_size) || (count < 0)) + return 0; + + if (count <= NVRW_CNT) { + remainder = count; + } else { + remainder = count % NVRW_CNT; + } + + if (remainder) { + memcpy(nvram_buf, p, remainder); + + if((rtas_call(nvram_store, 3, 2, &len, *index, __pa(nvram_buf), + remainder) != 0) || len != remainder) { + return -EIO; + } + + count -= remainder; + p += remainder; + } + + for (i = *index + remainder; count > 0 && i < rtas_nvram_size; + count -= NVRW_CNT) { + + memcpy(nvram_buf, p, NVRW_CNT); + + if ((rtas_call(nvram_store, 3, 2, &len, i, __pa(nvram_buf), + NVRW_CNT) != 0) || len != NVRW_CNT) { + return -EIO; + } + + p += NVRW_CNT; + i += NVRW_CNT; + } + + *index = i; + return p - buf; +} + int __init nvram_init(void) { struct device_node *nvram; unsigned int *nbytes_p, proplen; + int error; + int rc; + if ((nvram = find_type_devices("nvram")) != NULL) { nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen); if (nbytes_p && proplen == sizeof(unsigned int)) { rtas_nvram_size = *nbytes_p; + } else { + return -EIO; } + } else { + /* If we don't know how big NVRAM is then we shouldn't touch + the nvram partitions */ + return -EIO; } + nvram_fetch = rtas_token("nvram-fetch"); + if (nvram_fetch == RTAS_UNKNOWN_SERVICE) { + printk("nvram_init: Does not support nvram-fetch\n"); + return -EIO; + } + nvram_store = rtas_token("nvram-store"); + if (nvram_store == RTAS_UNKNOWN_SERVICE) { + printk("nvram_init: Does not support nvram-store\n"); + return -EIO; + } printk(KERN_INFO "PPC64 nvram contains %d bytes\n", rtas_nvram_size); - return misc_register(&nvram_dev); + rc = misc_register(&nvram_dev); + if (rc) { + printk(KERN_ERR "nvram_init: Failed misc_register (%d)\n", rc); + /* Going to continue to setup nvram for internal + * kernel services */ + } + + + /* initialize our anchor for the nvram partition list */ + nvram_part = kmalloc(sizeof(struct nvram_partition), GFP_KERNEL); + if (!nvram_part) { + printk(KERN_ERR "nvram_init: Failed kmalloc\n"); + return -ENOMEM; + } + INIT_LIST_HEAD(&nvram_part->partition); + + /* Get all the NVRAM partitions */ + error = scan_nvram_partitions(); + if (error) { + printk(KERN_ERR "nvram_init: Failed scan_nvram_partitions\n"); + return error; + } + + error = setup_nvram_partition(); + if (error) { + printk(KERN_WARNING "nvram_init: Could not find nvram partition" + " for nvram buffered error logging.\n"); + return error; + } + +#ifdef DEBUG_NVRAM + print_nvram_partitions("NVRAM Partitions"); +#endif + + return rc; } void __exit nvram_cleanup(void) { - misc_deregister( &nvram_dev ); + misc_deregister( &nvram_dev ); +} + +static int scan_nvram_partitions(void) +{ + loff_t cur_index = 0; + struct nvram_header phead; + struct nvram_partition * tmp_part; + unsigned char c_sum; + long size; + + while (cur_index < rtas_nvram_size) { + + size = read_nvram((char *)&phead, NVRAM_HEADER_LEN, &cur_index); + if (size != NVRAM_HEADER_LEN) { + printk(KERN_ERR "scan_nvram_partitions: Error parsing " + "nvram partitions\n"); + return size; + } + + cur_index -= NVRAM_HEADER_LEN; /* read_nvram will advance us */ + + c_sum = nvram_checksum(&phead); + if (c_sum != phead.checksum) + printk(KERN_WARNING "WARNING: nvram partition checksum " + "was %02x, should be %02x!\n", phead.checksum, c_sum); + + tmp_part = kmalloc(sizeof(struct nvram_partition), GFP_KERNEL); + if (!tmp_part) { + printk(KERN_ERR "scan_nvram_partitions: kmalloc failed\n"); + return -ENOMEM; + } + + memcpy(&tmp_part->header, &phead, NVRAM_HEADER_LEN); + tmp_part->index = cur_index; + list_add_tail(&tmp_part->partition, &nvram_part->partition); + + cur_index += phead.length * NVRAM_BLOCK_LEN; + } + + return 0; +} + +/* setup_nvram_partition + * + * This will setup the partition we need for buffering the + * error logs and cleanup partitions if needed. + * + * The general strategy is the following: + * 1.) If there is ppc64,linux partition large enough then use it. + * 2.) If there is not a ppc64,linux partition large enough, search + * for a free partition that is large enough. + * 3.) If there is not a free partition large enough remove + * _all_ OS partitions and consolidate the space. + * 4.) Will first try getting a chunk that will satisfy the maximum + * error log size (NVRAM_MAX_REQ). + * 5.) If the max chunk cannot be allocated then try finding a chunk + * that will satisfy the minum needed (NVRAM_MIN_REQ). + */ +static int setup_nvram_partition(void) +{ + struct list_head * p; + struct nvram_partition * part; + int rc; + + /* see if we have an OS partition that meets our needs. + will try getting the max we need. If not we'll delete + partitions and try again. */ + list_for_each(p, &nvram_part->partition) { + part = list_entry(p, struct nvram_partition, partition); + if (part->header.signature != NVRAM_SIG_OS) + continue; + + if (strcmp(part->header.name, "ppc64,linux")) + continue; + + if (part->header.length >= NVRAM_MIN_REQ) { + /* found our partition */ + error_log_nvram_index = part->index + NVRAM_HEADER_LEN; + error_log_nvram_size = (part->header.length * NVRAM_BLOCK_LEN) - + NVRAM_HEADER_LEN - sizeof(struct err_log_info); + return 0; + } + } + + /* try creating a partition with the free space we have */ + rc = create_os_nvram_partition(); + if (!rc) { + return 0; + } + + /* need to free up some space */ + rc = remove_os_nvram_partition(); + if (rc) { + return rc; + } + + /* create a partition in this new space */ + rc = create_os_nvram_partition(); + if (rc) { + printk(KERN_ERR "create_os_nvram_partition: Could not find a " + "NVRAM partition large enough (%d)\n", rc); + return rc; + } + + return 0; +} + +static int remove_os_nvram_partition(void) +{ + struct list_head *i; + struct list_head *j; + struct nvram_partition * part; + struct nvram_partition * cur_part; + int rc; + + list_for_each(i, &nvram_part->partition) { + part = list_entry(i, struct nvram_partition, partition); + if (part->header.signature != NVRAM_SIG_OS) + continue; + + /* Make os partition a free partition */ + part->header.signature = NVRAM_SIG_FREE; + sprintf(part->header.name, "wwwwwwwwwwww"); + part->header.checksum = nvram_checksum(&part->header); + + /* Merge contiguous free partitions backwards */ + list_for_each_prev(j, &part->partition) { + cur_part = list_entry(j, struct nvram_partition, partition); + if (cur_part == nvram_part || cur_part->header.signature != NVRAM_SIG_FREE) { + break; + } + + part->header.length += cur_part->header.length; + part->header.checksum = nvram_checksum(&part->header); + part->index = cur_part->index; + + list_del(&cur_part->partition); + kfree(cur_part); + j = &part->partition; /* fixup our loop */ + } + + /* Merge contiguous free partitions forwards */ + list_for_each(j, &part->partition) { + cur_part = list_entry(j, struct nvram_partition, partition); + if (cur_part == nvram_part || cur_part->header.signature != NVRAM_SIG_FREE) { + break; + } + + part->header.length += cur_part->header.length; + part->header.checksum = nvram_checksum(&part->header); + + list_del(&cur_part->partition); + kfree(cur_part); + j = &part->partition; /* fixup our loop */ + } + + rc = write_nvram_header(part); + if (rc <= 0) { + printk(KERN_ERR "remove_os_nvram_partition: write_nvram failed (%d)\n", rc); + return rc; + } + + } + + return 0; +} + +/* create_os_nvram_partition + * + * Create a OS linux partition to buffer error logs. + * Will create a partition starting at the first free + * space found if space has enough room. + */ +static int create_os_nvram_partition(void) +{ + struct list_head * p; + struct nvram_partition * part; + struct nvram_partition * new_part = NULL; + struct nvram_partition * free_part; + struct err_log_info seq_init = { 0, 0 }; + loff_t tmp_index; + long size = 0; + int rc; + + /* Find a free partition that will give us the maximum needed size + If can't find one that will give us the minimum size needed */ + list_for_each(p, &nvram_part->partition) { + part = list_entry(p, struct nvram_partition, partition); + if (part->header.signature != NVRAM_SIG_FREE) + continue; + + if (part->header.length >= NVRAM_MAX_REQ) { + size = NVRAM_MAX_REQ; + free_part = part; + break; + } + if (!size && part->header.length >= NVRAM_MIN_REQ) { + size = NVRAM_MIN_REQ; + free_part = part; + } + } + if (!size) { + return -ENOSPC; + } + + /* Create our OS partition */ + new_part = kmalloc(sizeof(struct nvram_partition), GFP_KERNEL); + if (!new_part) { + printk(KERN_ERR "create_os_nvram_partition: kmalloc failed\n"); + return -ENOMEM; + } + + new_part->index = free_part->index; + new_part->header.signature = NVRAM_SIG_OS; + new_part->header.length = size; + sprintf(new_part->header.name, "ppc64,linux"); + new_part->header.checksum = nvram_checksum(&new_part->header); + + rc = write_nvram_header(new_part); + if (rc <= 0) { + printk(KERN_ERR "create_os_nvram_partition: write_nvram_header \ + failed (%d)\n", rc); + kfree(new_part); + return rc; + } + + /* make sure and initialize to zero the sequence number and the error + type logged */ + tmp_index = new_part->index + NVRAM_HEADER_LEN; + rc = write_nvram((char *)&seq_init, sizeof(seq_init), &tmp_index); + if (rc <= 0) { + printk(KERN_ERR "create_os_nvram_partition: write_nvram failed (%d)\n", rc); + kfree(new_part); + return rc; + } + + error_log_nvram_index = new_part->index + NVRAM_HEADER_LEN; + error_log_nvram_size = (new_part->header.length * NVRAM_BLOCK_LEN) - + NVRAM_HEADER_LEN - sizeof(struct err_log_info); + + list_add_tail(&new_part->partition, &free_part->partition); + + if (free_part->header.length <= size) { + list_del(&free_part->partition); + kfree(free_part); + return 0; + } + + /* Adjust the partition we stole the space from */ + free_part->index += size * NVRAM_BLOCK_LEN; + free_part->header.length -= size; + free_part->header.checksum = nvram_checksum(&free_part->header); + + rc = write_nvram_header(free_part); + if (rc <= 0) { + printk(KERN_ERR "create_os_nvram_partition: write_nvram_header " + "failed (%d)\n", rc); + error_log_nvram_index = -1; + error_log_nvram_size = 0; + return rc; + } + + return 0; +} + + +void print_nvram_partitions(char * label) +{ + struct list_head * p; + struct nvram_partition * tmp_part; + + printk(KERN_WARNING "--------%s---------\n", label); + printk(KERN_WARNING "indx\t\tsig\tchks\tlen\tname\n"); + list_for_each(p, &nvram_part->partition) { + tmp_part = list_entry(p, struct nvram_partition, partition); + printk(KERN_WARNING "%d \t%02x\t%02x\t%d\t%s\n", + tmp_part->index, tmp_part->header.signature, + tmp_part->header.checksum, tmp_part->header.length, + tmp_part->header.name); + } +} + +/* write_error_log_nvram + * In NVRAM the partition containing the error log buffer will looks like: + * Header (in bytes): + * +-----------+----------+--------+------------+------------------+ + * | signature | checksum | length | name | data | + * |0 |1 |2 3|4 15|16 length-1| + * +-----------+----------+--------+------------+------------------+ + * NOTE: length is in NVRAM_BLOCK_LEN + * + * The 'data' section would look like (in bytes): + * +--------------+------------+-----------------------------------+ + * | event_logged | sequence # | error log | + * |0 3|4 7|8 error_log_nvram_size-1| + * +--------------+------------+-----------------------------------+ + * + * event_logged: 0 if event has not been logged to syslog, 1 if it has + * sequence #: The unique sequence # for each event. (until it wraps) + * error log: The error log from event_scan + */ +int write_error_log_nvram(char * buff, int num_bytes, unsigned int err_type) +{ + int rc; + loff_t tmp_index; + struct err_log_info info; + + if (no_more_logging) { + return -EPERM; + } + + if (error_log_nvram_index == -1) { + return -ESPIPE; + } + + if (num_bytes > error_log_nvram_size) { + num_bytes = error_log_nvram_size; + } + + info.error_type = err_type; + info.seq_num = error_log_cnt; + + tmp_index = error_log_nvram_index; + + rc = write_nvram((char *)&info, sizeof(struct err_log_info), &tmp_index); + if (rc <= 0) { + printk(KERN_ERR "write_error_log_nvram: Failed write_nvram (%d)\n", rc); + return rc; + } + + rc = write_nvram(buff, num_bytes, &tmp_index); + if (rc <= 0) { + printk(KERN_ERR "write_error_log_nvram: Failed write_nvram (%d)\n", rc); + return rc; + } + + return 0; +} + +/* read_error_log_nvram + * + * Reads nvram for error log for at most 'num_bytes' + */ +int read_error_log_nvram(char * buff, int num_bytes, unsigned int * err_type) +{ + int rc; + loff_t tmp_index; + struct err_log_info info; + + if (error_log_nvram_index == -1) + return -1; + + if (num_bytes > error_log_nvram_size) + num_bytes = error_log_nvram_size; + + tmp_index = error_log_nvram_index; + + rc = read_nvram((char *)&info, sizeof(struct err_log_info), &tmp_index); + if (rc <= 0) { + printk(KERN_ERR "read_error_log_nvram: Failed read_nvram (%d)\n", rc); + return rc; + } + + rc = read_nvram(buff, num_bytes, &tmp_index); + if (rc <= 0) { + printk(KERN_ERR "read_error_log_nvram: Failed read_nvram (%d)\n", rc); + return rc; + } + + error_log_cnt = info.seq_num; + *err_type = info.error_type; + + return 0; +} + +/* This doesn't actually zero anything, but it sets the event_logged + * word to tell that this event is safely in syslog. + */ +int clear_error_log_nvram() +{ + loff_t tmp_index; + int clear_word = ERR_FLAG_ALREADY_LOGGED; + int rc; + + if (error_log_nvram_index == -1) { + return -ESPIPE; + } + + tmp_index = error_log_nvram_index; + + rc = write_nvram((char *)&clear_word, sizeof(int), &tmp_index); + if (rc <= 0) { + printk(KERN_ERR "clear_error_log_nvram: Failed write_nvram (%d)\n", rc); + return rc; + } + + return 0; +} + +static int write_nvram_header(struct nvram_partition * part) +{ + loff_t tmp_index; + int rc; + + tmp_index = part->index; + rc = write_nvram((char *)&part->header, NVRAM_HEADER_LEN, &tmp_index); + + return rc; +} + +static unsigned char nvram_checksum(struct nvram_header *p) +{ + unsigned int c_sum, c_sum2; + unsigned short *sp = (unsigned short *)p->name; /* assume 6 shorts */ + c_sum = p->signature + p->length + sp[0] + sp[1] + sp[2] + sp[3] + sp[4] + sp[5]; + + /* The sum may have spilled into the 3rd byte. Fold it back. */ + c_sum = ((c_sum & 0xffff) + (c_sum >> 16)) & 0xffff; + /* The sum cannot exceed 2 bytes. Fold it into a checksum */ + c_sum2 = (c_sum >> 8) + (c_sum << 8); + c_sum = ((c_sum + c_sum2) >> 8) & 0xff; + return c_sum; } module_init(nvram_init); Index: arch/ppc64/kernel/open_pic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/open_pic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/open_pic.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/open_pic.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -20,7 +20,7 @@ #include #include #include - +#include #include #include "local_irq.h" @@ -131,13 +131,23 @@ #define GET_ISU(source) ISU[(source) >> 4][(source) & 0xf] +void +openpic_init_irq_desc(irq_desc_t *desc) +{ + /* Don't mess with the handler if already set. + * This leaves the setup of isa/ipi handlers undisturbed. + */ + if (!desc->handler) + desc->handler = &open_pic; +} + void __init openpic_init_IRQ(void) { struct device_node *np; int i; unsigned int *addrp; unsigned char* chrp_int_ack_special = 0; - unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS]; + unsigned char init_senses[NR_IRQS - NUM_ISA_INTERRUPTS]; int nmi_irq = -1; #if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON) struct device_node *kbd; @@ -152,13 +162,13 @@ __ioremap(addrp[prom_n_addr_cells(np)-1], 1, _PAGE_NO_CACHE); /* hydra still sets OpenPIC_InitSenses to a static set of values */ if (OpenPIC_InitSenses == NULL) { - prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS); - OpenPIC_InitSenses = init_senses; - OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS; - } - openpic_init(1, NUM_8259_INTERRUPTS, chrp_int_ack_special, nmi_irq); - for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ ) - irq_desc[i].handler = &i8259_pic; + prom_get_irq_senses(init_senses, NUM_ISA_INTERRUPTS, NR_IRQS); + OpenPIC_InitSenses = init_senses; + OpenPIC_NumInitSenses = NR_IRQS - NUM_ISA_INTERRUPTS; + } + openpic_init(1, NUM_ISA_INTERRUPTS, chrp_int_ack_special, nmi_irq); + for ( i = 0 ; i < NUM_ISA_INTERRUPTS ; i++ ) + real_irqdesc(i)->handler = &i8259_pic; i8259_init(); } @@ -343,8 +353,8 @@ /* Disabled, Priority 10..13 */ openpic_initipi(i, 10+i, openpic_vec_ipi+i); /* IPIs are per-CPU */ - irq_desc[openpic_vec_ipi+i].status |= IRQ_PER_CPU; - irq_desc[openpic_vec_ipi+i].handler = &open_pic_ipi; + real_irqdesc(openpic_vec_ipi+i)->status |= IRQ_PER_CPU; + real_irqdesc(openpic_vec_ipi+i)->handler = &open_pic_ipi; } #endif @@ -369,7 +379,7 @@ pri = (i == programmer_switch_irq)? 9: 8; sense = (i < OpenPIC_NumInitSenses)? OpenPIC_InitSenses[i]: 1; if (sense) - irq_desc[i+offset].status = IRQ_LEVEL; + real_irqdesc(i+offset)->status = IRQ_LEVEL; /* Enabled, Priority 8 or 9 */ openpic_initirq(i, pri, i+offset, !sense, sense); @@ -377,10 +387,6 @@ openpic_mapirq(i, 1<status & IRQ_LEVEL) != 0) openpic_eoi(); } Index: arch/ppc64/kernel/open_pic.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/open_pic.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/open_pic.h 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/open_pic.h 4 Aug 2004 01:26:10 -0000 1.2 @@ -37,9 +37,4 @@ extern void openpic_setup_ISU(int isu_num, unsigned long addr); extern void openpic_cause_IPI(u_int ipi, u_int cpumask); -extern inline int openpic_to_irq(int irq) -{ - return irq += NUM_8259_INTERRUPTS; -} -/*extern int open_pic_irq_offset;*/ #endif /* _PPC64_KERNEL_OPEN_PIC_H */ Index: arch/ppc64/kernel/pSeries_hvCall.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/pSeries_hvCall.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/pSeries_hvCall.S 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/pSeries_hvCall.S 4 Aug 2004 01:26:10 -0000 1.2 @@ -23,7 +23,7 @@ /* * hcall interface to pSeries LPAR */ -#define HSC .long 0x44000022 +#define HVSC .long 0x44000022 /* long plpar_hcall(unsigned long opcode, R3 unsigned long arg1, R4 @@ -45,7 +45,7 @@ std r9,-16(r1) std r10,-24(r1) - HSC /* invoke the hypervisor */ + HVSC /* invoke the hypervisor */ ld r10,-8(r1) /* Fetch r4-r7 ret args. */ std r4,0(r10) @@ -60,11 +60,85 @@ blr /* return r3 = status */ +/* long plpar_hcall_4out(unsigned long opcode, R3 + unsigned long arg1, R4 + unsigned long arg2, R5 + unsigned long arg3, R6 + unsigned long arg4, R7 + unsigned long *out1, (r4) R8 + unsigned long *out2, (r5) R9 + unsigned long *out3, (r6) R10 + unsigned long *out4); (r7) 112(R1). From Parameter save area. + */ +_GLOBAL(plpar_hcall_4out) + mfcr r0 + std r0,-8(r1) + ld r14,112(r1) + stdu r1,-48(r1) + + std r8,32(r1) /* Save out ptrs. */ + std r9,24(r1) + std r10,16(r1) + std r14,8(r1) + + HVSC /* invoke the hypervisor */ + + ld r14,32(r1) /* Fetch r4-r7 ret args. */ + std r4,0(r14) + ld r14,24(r1) + std r5,0(r14) + ld r14,16(r1) + std r6,0(r14) + ld r14,8(r1) + std r7,0(r14) + + ld r1,0(r1) + ld r0,-8(r1) + mtcrf 0xff,r0 + blr /* return r3 = status */ + + /* Simple interface with no output values (other than status) */ _GLOBAL(plpar_hcall_norets) mfcr r0 std r0,-8(r1) - HSC /* invoke the hypervisor */ + HVSC /* invoke the hypervisor */ + ld r0,-8(r1) + mtcrf 0xff,r0 + blr /* return r3 = status */ + + +/* long plpar_hcall_8arg_2ret(unsigned long opcode, R3 + unsigned long arg1, R4 + unsigned long arg2, R5 + unsigned long arg3, R6 + unsigned long arg4, R7 + unsigned long arg5, R8 + unsigned long arg6, R9 + unsigned long arg7, R10 + unsigned long arg8, 112(R1) + unsigned long *out1); 120(R1) + + */ + + .text +_GLOBAL(plpar_hcall_8arg_2ret) + mfcr r0 + + ld r11, 112(r1) /* put arg8 and out1 in R11 and R12 */ + ld r12, 120(r1) + + std r0,-8(r1) + stdu r1,-32(r1) + + std r12,-8(r1) /* Save out ptr */ + + HVSC /* invoke the hypervisor */ + + ld r10,-8(r1) /* Fetch r4 ret arg */ + std r4,0(r10) + + ld r1,0(r1) ld r0,-8(r1) mtcrf 0xff,r0 blr /* return r3 = status */ Index: arch/ppc64/kernel/pSeries_lpar.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/pSeries_lpar.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/pSeries_lpar.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/pSeries_lpar.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -35,6 +35,41 @@ #include #include #include +long poll_pending(void) +{ + unsigned long dummy; + return plpar_hcall(H_POLL_PENDING, 0, 0, 0, 0, + &dummy, &dummy, &dummy); +} + +long prod_processor(void) +{ + plpar_hcall_norets(H_PROD); + return(0); +} + +long cede_processor(void) +{ + plpar_hcall_norets(H_CEDE); + return(0); +} + +long register_vpa(unsigned long flags, unsigned long proc, unsigned long vpa) +{ + plpar_hcall_norets(H_REGISTER_VPA, flags, proc, vpa); + return(0); +} + +void vpa_init(int cpu) +{ + unsigned long flags; + + /* Register the Virtual Processor Area (VPA) */ + printk(KERN_INFO "register_vpa: cpu 0x%x\n", cpu); + flags = 1UL << (63 - 18); + paca[cpu].xLpPaca.xSLBCount = 64; /* SLB restore highwater mark */ + register_vpa(flags, cpu, __pa((unsigned long)&(paca[cpu].xLpPaca))); +} long plpar_tce_get(unsigned long liobn, unsigned long ioba, @@ -276,7 +311,6 @@ -/* Code for hvc_console. Should move it back eventually. */ int hvc_get_chars(int index, char *buf, int count) { @@ -319,24 +353,114 @@ return -1; } +/* return the number of client vterms present */ +/* XXX this requires an interface change to handle multiple discontiguous + * vterms */ int hvc_count(int *start_termno) { u32 *termno; - struct device_node *dn; + struct device_node *rtas; + struct device_node *vtys; - if ((dn = find_path_device("/rtas")) != NULL) { - if ((termno = (u32 *)get_property(dn, "ibm,termno", 0)) != NULL) { + /* consider only the first vty node. + * we should _always_ be able to find one. however, it may not be compatible + * with hvterm1, in which case hvc_console can't use it. */ + vtys = find_devices("vty"); + if (vtys && device_is_compatible(vtys, "hvterm1")) { + termno = (u32 *)get_property(vtys, "reg", 0); + if (start_termno && termno) + *start_termno = *termno; + return 1; /* we can't support >1 with this interface */ + } + + /* no vty nodes; use the /rtas/ibm,termno property */ + printk(KERN_ERR "%s: couldn't find a 'vty' node\n", __FUNCTION__); + if ((rtas = find_path_device("/rtas")) != NULL) { + if ((termno = (u32 *)get_property(rtas, "ibm,termno", 0)) != NULL) { if (start_termno) *start_termno = termno[0]; return termno[1]; } } + + /* couldn't find any vterms */ return 0; } #ifndef CONFIG_PPC_ISERIES void pSeries_lpar_mm_init(void); +/* returns 0 if couldn't find or use /chosen/stdout as console */ +static int find_udbg_vterm(void) +{ + struct device_node *stdout_node; + u32 *termno; + char *name; + int found = 0; + + /* find the boot console from /chosen/stdout */ + if (!of_stdout_device) { + printk(KERN_WARNING "couldn't get path from /chosen/stdout!\n"); + return found; + } + stdout_node = find_path_device(of_stdout_device); + if (!stdout_node) { + printk(KERN_WARNING "couldn't find node from /chosen/stdout\n"); + return found; + } + + /* now we have the stdout node; figure out what type of device it is. */ + name = (char *)get_property(stdout_node, "name", 0); + if (!name) { + printk(KERN_WARNING "stdout node missing 'name' property!\n"); + return found; + } + + if (strncmp(name, "vty", 3) == 0) { + char *compatible; + compatible = (char *)get_property(stdout_node, "compatible", 0); + if (compatible && (strncmp(compatible, "hvterm1", 7) == 0)) { + termno = (u32 *)get_property(stdout_node, "reg", 0); + if (termno) { + vtermno = termno[0]; + ppc_md.udbg_putc = udbg_putcLP; + ppc_md.udbg_getc = udbg_getcLP; + ppc_md.udbg_getc_poll = udbg_getc_pollLP; + found = 1; + } + } else { + /* XXX implement udbg_putcLP_vtty for hvterm-protocol1 case */ + printk(KERN_WARNING "%s doesn't speak hvterm1; " + "can't print udbg messages\n", of_stdout_device); + } + } else if (strncmp(name, "rtas", 4)) { + /* according to firmware, this should never happen. to be removed */ + printk(KERN_ERR "ATTENTION: /chosen/stdout should be /vdevice/vty@0!\n" + "Please report this to linuxppc64-dev@lists.linuxppc.org\n"); + + /* "ibm,termno" property is a pair of numbers. The first is the + * starting termno (the one we use) and the second is the number + * of terminals. */ + termno = (u32 *)get_property(stdout_node, "ibm,termno", 0); + if (termno) { + vtermno = termno[0]; + ppc_md.udbg_putc = udbg_putcLP; + ppc_md.udbg_getc = udbg_getcLP; + ppc_md.udbg_getc_poll = udbg_getc_pollLP; + found = 1; + } + } else if (strncmp(name, "serial", 6)) { + /* XXX fix ISA serial console */ + printk(KERN_WARNING "serial stdout on LPAR ('%s')! " + "can't print udbg messages\n", of_stdout_device); + } else { + printk(KERN_WARNING "don't know how to print to stdout '%s'\n", + of_stdout_device); + } + + return found; +} + /* This is called early in setup.c. * Use it to setup page table ppc_md stuff as well as udbg. */ @@ -353,23 +477,12 @@ pSeries_pcibios_init_early(); /* The keyboard is not useful in the LPAR environment. - * Leave all the interfaces NULL. + * Leave all ppc_md keyboard interfaces NULL. */ - /* lookup the first virtual terminal number in case we don't have a com port. - * Zero is probably correct in case someone calls udbg before the init. - * The property is a pair of numbers. The first is the starting termno (the - * one we use) and the second is the number of terminals. - */ - u32 *termno; - struct device_node *np = find_path_device("/rtas"); - if (np) { - termno = (u32 *)get_property(np, "ibm,termno", 0); - if (termno) - vtermno = termno[0]; + if (0 == find_udbg_vterm()) { + printk(KERN_WARNING + "can't use stdout; can't print early debug messages.\n"); } - ppc_md.udbg_putc = udbg_putcLP; - ppc_md.udbg_getc = udbg_getcLP; - ppc_md.udbg_getc_poll = udbg_getc_pollLP; } #endif Index: arch/ppc64/kernel/pSeries_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/pSeries_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/pSeries_pci.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/pSeries_pci.c 4 Aug 2004 01:26:10 -0000 1.2 @@ -208,6 +208,7 @@ PPCDBG(PPCDBG_BUSWALK,"\tDevice: %s No Interrupt used by device.\n",Pci_Dev->slot_name); return 0; } + Node = pci_device_to_OF_node(Pci_Dev); if ( Node == NULL) { PPCDBG(PPCDBG_BUSWALK,"\tDevice: %s Device Node not found.\n",Pci_Dev->slot_name); @@ -524,13 +525,22 @@ } phb->local_number = ((reg_struct.address >> 12) & 0xf) - 0x8; - /*************************************************************** - * Trying to build a known just gets the code in trouble. - ***************************************************************/ - } else { + } else { PPCDBG(PPCDBG_PHBINIT, "\tUnknown PHB Type!\n"); - printk("PCI: Unknown Phb Type!\n"); - return NULL; + + if (systemcfg->platform == PLATFORM_PSERIES_LPAR) { + + phb=pci_alloc_pci_controller("PHB UK",phb_type_unknown); + if (phb == NULL) return NULL; + + phb->cfg_addr = NULL; + phb->cfg_data = NULL; + phb->phb_regs = NULL; + phb->chip_regs = NULL; + } else { + printk("PCI: Unknown Phb Type!\n"); + return NULL; + } } /* Add a linux,phbnum property to the device tree so user code @@ -703,10 +713,6 @@ pci_read_irq_line(dev); PPCDBGCALL(PPCDBG_PHBINIT, dumpPci_Dev(dev) ); } - - if (naca->interrupt_controller == IC_PPC_XIC) { - xics_isa_init(); - } } /*********************************************************************** Index: arch/ppc64/kernel/pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/pci.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/pci.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -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); Index: arch/ppc64/kernel/pci.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/pci.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/pci.h 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/pci.h 4 Aug 2004 01:26:11 -0000 1.2 @@ -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); Index: arch/ppc64/kernel/pci_dma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/pci_dma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/pci_dma.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/pci_dma.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -97,11 +97,8 @@ unsigned order ); /* allocates a range of tces and sets them to the pages */ -static inline dma_addr_t get_tces( struct TceTable *, - unsigned order, - void *page, - unsigned numPages, - int direction ); +dma_addr_t get_tces(struct TceTable *, unsigned order, void *page, + unsigned numPages, int direction); static long test_tce_range( struct TceTable *, long tcenum, @@ -219,7 +216,7 @@ * Build a TceTable structure. This contains a multi-level bit map which * is used to manage allocation of the tce space. */ -static struct TceTable *build_tce_table( struct TceTable * tbl ) +struct TceTable *build_tce_table(struct TceTable * tbl) { unsigned long bits, bytes, totalBytes; unsigned long numBits[NUM_TCE_LEVELS], numBytes[NUM_TCE_LEVELS]; @@ -527,7 +524,8 @@ return retval; } -static inline dma_addr_t get_tces( struct TceTable *tbl, unsigned order, void *page, unsigned numPages, int direction ) +inline dma_addr_t get_tces(struct TceTable *tbl, unsigned order, + void *page, unsigned numPages, int direction) { long tcenum; unsigned long uaddr; @@ -537,8 +535,8 @@ uaddr = (unsigned long)page & PAGE_MASK; /* Allocate a range of tces */ - tcenum = alloc_tce_range( tbl, order ); - if ( tcenum != -1 ) { + tcenum = alloc_tce_range(tbl, order); + if (tcenum != -1) { /* We got the tces we wanted */ tcenum += tbl->startOffset; /* Offset into real TCE table */ retTce = tcenum << PAGE_SHIFT; /* Set the return dma address */ @@ -553,9 +551,9 @@ the TCE table with the MMIO that will send the bus address to the IOA */ __asm__ __volatile__ ("sync" : : : "memory"); - } - else { - panic("PCI_DMA: Tce Allocation failure in get_tces. 0x%p\n",tbl); + } else { + panic("get_tces: TCE allocation failed. 0x%p 0x%x\n", + tbl, order); } return retTce; @@ -586,8 +584,8 @@ } -static void tce_free(struct TceTable *tbl, dma_addr_t dma_addr, - unsigned order, unsigned num_pages) +void tce_free(struct TceTable *tbl, dma_addr_t dma_addr, + unsigned order, unsigned num_pages) { long tcenum, total_tces, free_tce; unsigned i; @@ -713,12 +711,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 +718,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); } } @@ -1014,34 +1007,34 @@ /* Client asked for way to much space. This is checked later anyway */ /* It is easier to debug here for the drivers than in the tce tables.*/ - if(order >= NUM_TCE_LEVELS) { - printk("PCI_DMA: pci_alloc_consistent size to large: 0x%lx \n",size); - return (void *)NO_TCE; + if (order >= NUM_TCE_LEVELS) { + printk("PCI_DMA: pci_alloc_consistent size too large: 0x%lx\n", + size); + return (void *)NULL; } tbl = get_tce_table(hwdev); - if ( tbl ) { + if (tbl) { /* Alloc enough pages (and possibly more) */ ret = (void *)__get_free_pages( GFP_ATOMIC, order ); - if ( ret ) { + if (ret) { /* Page allocation succeeded */ memset(ret, 0, nPages << PAGE_SHIFT); /* Set up tces to cover the allocated range */ tce = get_tces( tbl, order, ret, nPages, PCI_DMA_BIDIRECTIONAL ); - if ( tce == NO_TCE ) { - PPCDBG(PPCDBG_TCE, "pci_alloc_consistent: get_tces failed\n" ); + if (tce == NO_TCE) { free_pages( (unsigned long)ret, order ); ret = NULL; - } - else - { + } else { *dma_handle = tce; } + } else { + printk("pci_alloc_consistent: __get_free_pages failed for order = %d\n", order); } - else PPCDBG(PPCDBG_TCE, "pci_alloc_consistent: __get_free_pages failed for order = %d\n", order); + } else { + panic("pci_alloc_consistent: unable to find TCE table\n"); } - else PPCDBG(PPCDBG_TCE, "pci_alloc_consistent: get_tce_table failed for 0x%016lx\n", hwdev); PPCDBG(PPCDBG_TCE, "\tpci_alloc_consistent: dma_handle = 0x%16.16lx\n", *dma_handle); PPCDBG(PPCDBG_TCE, "\tpci_alloc_consistent: return = 0x%16.16lx\n", ret); @@ -1064,7 +1057,7 @@ /* Client asked for way to much space. This is checked later anyway */ /* It is easier to debug here for the drivers than in the tce tables.*/ if(order >= NUM_TCE_LEVELS) { - printk("PCI_DMA: pci_free_consistent size to large: 0x%lx \n",size); + printk("PCI_DMA: pci_free_consistent size too large: 0x%lx \n",size); return; } @@ -1092,7 +1085,7 @@ PPCDBG(PPCDBG_TCE, "pci_map_single:\n"); PPCDBG(PPCDBG_TCE, "\thwdev = 0x%16.16lx, size = 0x%16.16lx, direction = 0x%16.16lx, vaddr = 0x%16.16lx\n", hwdev, size, direction, vaddr); - if ( direction == PCI_DMA_NONE ) + if (direction == PCI_DMA_NONE) BUG(); uaddr = (unsigned long)vaddr; @@ -1103,15 +1096,18 @@ /* Client asked for way to much space. This is checked later anyway */ /* It is easier to debug here for the drivers than in the tce tables.*/ if(order >= NUM_TCE_LEVELS) { - printk("PCI_DMA: pci_map_single size to large: 0x%lx \n",size); - return NO_TCE; + panic("PCI_DMA: pci_map_single size too large: 0x%lx \n", size); + return dma_handle; } tbl = get_tce_table(hwdev); - if ( tbl ) { + if (tbl) { + /* get_tces panics if there are no entries available */ dma_handle = get_tces( tbl, order, vaddr, nPages, direction ); dma_handle |= ( uaddr & ~PAGE_MASK ); + } else { + panic("PCI_DMA: Unable to find TCE table.\n"); } return dma_handle; @@ -1134,7 +1130,7 @@ /* Client asked for way to much space. This is checked later anyway */ /* It is easier to debug here for the drivers than in the tce tables.*/ if(order >= NUM_TCE_LEVELS) { - printk("PCI_DMA: pci_unmap_single size to large: 0x%lx \n",size); + printk("PCI_DMA: pci_unmap_single size too large: 0x%lx \n",size); return; } @@ -1156,6 +1152,7 @@ { unsigned long nTces, numPages, startPage, endPage, prevEndPage; unsigned i; + void *address; prevEndPage = 0; nTces = 0; @@ -1164,8 +1161,10 @@ /* Compute the starting page number and * the ending page number for this entry */ - startPage = (unsigned long)sg->address >> PAGE_SHIFT; - endPage = ((unsigned long)sg->address + sg->length - 1) >> PAGE_SHIFT; + address = sg->address ? sg->address : + (page_address(sg->page) + sg->offset); + startPage = (unsigned long)address >> PAGE_SHIFT; + endPage = ((unsigned long)address + sg->length - 1) >> PAGE_SHIFT; numPages = endPage - startPage + 1; /* Simple optimization: if the previous entry ended * in the same page in which this entry starts @@ -1192,17 +1191,20 @@ u32 cur_start_dma; unsigned long cur_len_dma, cur_end_virt, uaddr; unsigned num_dma_ents; + void *address; dma_sg = sg; num_dma_ents = 1; /* Process the first sg entry */ - cur_start_dma = dma_addr + ((unsigned long)sg->address & (~PAGE_MASK)); + address = sg->address ? sg->address : + (page_address(sg->page) + sg->offset); + cur_start_dma = dma_addr + ((unsigned long)address & (~PAGE_MASK)); cur_len_dma = sg->length; /* cur_end_virt holds the address of the byte immediately after the * end of the current buffer. */ - cur_end_virt = (unsigned long)sg->address + cur_len_dma; + cur_end_virt = (unsigned long)address + cur_len_dma; /* Later code assumes that unused sg->dma_address and sg->dma_length * fields will be zero. Other archs seem to assume that the user * (device driver) guarantees that...I don't want to depend on that @@ -1227,7 +1229,9 @@ * or if the previous entry ends at a page boundary * and the current entry starts at a page boundary. */ - uaddr = (unsigned long)sg->address; + address = sg->address ? sg->address : + (page_address(sg->page) + sg->offset); + uaddr = (unsigned long)address; if ( ( uaddr != cur_end_virt ) && ( ( ( uaddr | cur_end_virt ) & (~PAGE_MASK) ) || ( ( uaddr & PAGE_MASK ) == ( ( cur_end_virt-1 ) & PAGE_MASK ) ) ) ) { @@ -1278,13 +1282,14 @@ /* Call the hypervisor to create the TCE entries. * return the number of TCEs created */ -static dma_addr_t create_tces_sg( struct TceTable *tbl, struct scatterlist *sg, - int nents, unsigned numTces, int direction ) +static dma_addr_t create_tces_sg(struct TceTable *tbl, struct scatterlist *sg, + int nents, unsigned numTces, int direction) { unsigned order, i, j; unsigned long startPage, endPage, prevEndPage, numPages, uaddr; long tcenum, starttcenum; dma_addr_t dmaAddr; + void *address; dmaAddr = NO_TCE; @@ -1292,23 +1297,26 @@ /* Client asked for way to much space. This is checked later anyway */ /* It is easier to debug here for the drivers than in the tce tables.*/ if(order >= NUM_TCE_LEVELS) { - printk("PCI_DMA: create_tces_sg size to large: 0x%x \n",(numTces << PAGE_SHIFT)); + printk("PCI_DMA: create_tces_sg size too large: 0x%llx \n",(numTces << PAGE_SHIFT)); + panic("numTces is off"); return NO_TCE; } /* allocate a block of tces */ - tcenum = alloc_tce_range( tbl, order ); - if ( tcenum != -1 ) { + tcenum = alloc_tce_range(tbl, order); + if (tcenum != -1) { tcenum += tbl->startOffset; starttcenum = tcenum; dmaAddr = tcenum << PAGE_SHIFT; prevEndPage = 0; for (j=0; jaddress >> PAGE_SHIFT; - endPage = ((unsigned long)sg->address + sg->length - 1) >> PAGE_SHIFT; + address = sg->address ? sg->address : + (page_address(sg->page) + sg->offset); + startPage = (unsigned long)address >> PAGE_SHIFT; + endPage = ((unsigned long)address + sg->length - 1) >> PAGE_SHIFT; numPages = endPage - startPage + 1; - uaddr = (unsigned long)sg->address; + uaddr = (unsigned long)address; /* If the previous entry ended in the same page that * the current page starts then they share that @@ -1340,6 +1348,9 @@ PPCDBG(PPCDBG_TCE, "create_tces_sg: numTces %d, tces used %d\n", numTces, (unsigned)(tcenum - starttcenum)); + } else { + panic("PCI_DMA: TCE allocation failure in create_tces_sg. 0x%p 0x%x\n", + tbl, order); } return dmaAddr; @@ -1349,32 +1360,37 @@ { struct TceTable * tbl; unsigned numTces; - int num_dma; + int num_dma = 0; dma_addr_t dma_handle; + void *address; - PPCDBG(PPCDBG_TCE, "pci_map_sg:\n"); - PPCDBG(PPCDBG_TCE, "\thwdev = 0x%16.16lx, sg = 0x%16.16lx, direction = 0x%16.16lx, nents = 0x%16.16lx\n", hwdev, sg, direction, nents); /* Fast path for a single entry scatterlist */ if ( nents == 1 ) { - sg->dma_address = pci_map_single( hwdev, sg->address, - sg->length, direction ); + address = sg->address ? sg->address : + (page_address(sg->page) + sg->offset); + sg->dma_address = pci_map_single( hwdev, address, + sg->length, direction ); sg->dma_length = sg->length; return 1; } - if ( direction == PCI_DMA_NONE ) + if (direction == PCI_DMA_NONE) BUG(); tbl = get_tce_table(hwdev); - if ( tbl ) { + if (tbl) { /* Compute the number of tces required */ - numTces = num_tces_sg( sg, nents ); + numTces = num_tces_sg(sg, nents); /* 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 ); + } else { + panic("pci_map_sg: unable to find TCE table\n"); } return num_dma; @@ -1410,7 +1426,7 @@ /* It is easier to debug here for the drivers than in the tce tables.*/ if(order >= NUM_TCE_LEVELS) { printk("PCI_DMA: dma_start_page:0x%lx dma_end_page:0x%lx\n",dma_start_page,dma_end_page); - printk("PCI_DMA: pci_unmap_sg size to large: 0x%x \n",(numTces << PAGE_SHIFT)); + printk("PCI_DMA: pci_unmap_sg size too large: 0x%x \n",(numTces << PAGE_SHIFT)); return; } Index: arch/ppc64/kernel/perfmon.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/perfmon.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/perfmon.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/perfmon.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -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}; @@ -419,6 +420,33 @@ return(0); } + +static long plpar_perfmon(int mode) +{ + return plpar_hcall_norets(H_PERFMON, mode, 0); +} + +static void pmc_configure_hardware() { + /* + * Debug bus enabled is required on GP for timeslice mode. + * Flood enabled is required on GP for PMC cycle profile mode + * iSeries SP sets this by default. pSeries requires the OS to enable. + */ + 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: + HvCall_setDebugBus(1); + break; + case PLATFORM_PSERIES_LPAR: + plpar_perfmon(1); + break; + case PLATFORM_PSERIES: + mtspr(HID0, mfspr(HID0) | 0x0000080000000000); + } + } +} + /* * pmc_profile * @@ -450,7 +478,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; @@ -782,29 +810,3 @@ } spin_unlock(&pmc_lock); } - -long plpar_perfmon(int mode) -{ - return plpar_hcall_norets(H_PERFMON, mode, 0); -} - -void pmc_configure_hardware() { - /* - * Debug bus enabled is required on GP for timeslice mode. - * 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)) { - /* Set up the debug bus to pmc mode - a feature of GP */ - switch(systemcfg->platform) { - case PLATFORM_ISERIES_LPAR: - HvCall_setDebugBus(1); - break; - case PLATFORM_PSERIES_LPAR: - plpar_perfmon(1); - break; - case PLATFORM_PSERIES: - mtspr(HID0, mfspr(HID0) | 0x0000080000000000); - } - } -} Index: arch/ppc64/kernel/pmc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/pmc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/pmc.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/pmc.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -74,7 +74,6 @@ page_table_lock : SPIN_LOCK_UNLOCKED}; extern spinlock_t hash_table_lock[]; -extern inline unsigned long get_lock_slot(unsigned long vpn); char * ppc64_pmc_stab(int file) @@ -206,7 +205,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; @@ -241,7 +240,7 @@ lock_slot = get_lock_slot(vpn); rpn = pa >> PAGE_SHIFT; - spin_lock(&hash_table_lock[lock_slot].lock); + spin_lock(&hash_table_lock[lock_slot]); /* Get a pointer to the linux page table entry for this page * allocating pmd or pte pages along the way as needed. Note * that the pmd & pte pages are not themselfs bolted. @@ -266,7 +265,7 @@ *ptep = pte; - spin_unlock(&hash_table_lock[lock_slot].lock); + spin_unlock(&hash_table_lock[lock_slot]); } spin_unlock(&btmalloc_mm.page_table_lock); Index: arch/ppc64/kernel/ppc_asm.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/ppc_asm.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/ppc_asm.h 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/ppc_asm.h 4 Aug 2004 01:26:11 -0000 1.2 @@ -44,6 +44,31 @@ #define REST_16FPRS(n, base) REST_8FPRS(n, base); REST_8FPRS(n+8, base) #define REST_32FPRS(n, base) REST_16FPRS(n, base); REST_16FPRS(n+16, base) +/* + * Once a version of gas that understands the AltiVec instructions + * is freely available, we can do this the normal way... - paulus + */ +#define LVX(r,a,b) .long (31<<26)+((r)<<21)+((a)<<16)+((b)<<11)+(103<<1) +#define STVX(r,a,b) .long (31<<26)+((r)<<21)+((a)<<16)+((b)<<11)+(231<<1) +#define MFVSCR(r) .long (4<<26)+((r)<<21)+(770<<1) +#define MTVSCR(r) .long (4<<26)+((r)<<11)+(802<<1) +#define DSSALL .long (0x1f<<26)+(0x10<<21)+(0x336<<1) + + +#define SAVE_VR(n,b,base) li b,THREAD_VR0+(16*(n)); STVX(n,b,base) +#define SAVE_2VR(n,b,base) SAVE_VR(n,b,base); SAVE_VR(n+1,b,base) +#define SAVE_4VR(n,b,base) SAVE_2VR(n,b,base); SAVE_2VR(n+2,b,base) +#define SAVE_8VR(n,b,base) SAVE_4VR(n,b,base); SAVE_4VR(n+4,b,base) +#define SAVE_16VR(n,b,base) SAVE_8VR(n,b,base); SAVE_8VR(n+8,b,base) +#define SAVE_32VR(n,b,base) SAVE_16VR(n,b,base); SAVE_16VR(n+16,b,base) +#define REST_VR(n,b,base) li b,THREAD_VR0+(16*(n)); LVX(n,b,base) +#define REST_2VR(n,b,base) REST_VR(n,b,base); REST_VR(n+1,b,base) +#define REST_4VR(n,b,base) REST_2VR(n,b,base); REST_2VR(n+2,b,base) +#define REST_8VR(n,b,base) REST_4VR(n,b,base); REST_4VR(n+4,b,base) +#define REST_16VR(n,b,base) REST_8VR(n,b,base); REST_8VR(n+8,b,base) +#define REST_32VR(n,b,base) REST_16VR(n,b,base); REST_16VR(n+16,b,base) + + #define CHECKANYINT(ra,rb) \ mfspr rb,SPRG3; /* Get Paca address */\ ld ra,PACALPPACA+LPPACAANYINT(rb); /* Get pending interrupt flags */\ Index: arch/ppc64/kernel/ppc_ksyms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/ppc_ksyms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/ppc_ksyms.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/ppc_ksyms.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -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(void); +extern int shared_task_unmark(void); +#endif + EXPORT_SYMBOL(do_signal); EXPORT_SYMBOL(syscall_trace); EXPORT_SYMBOL(do_IRQ); @@ -225,6 +232,12 @@ EXPORT_SYMBOL(flush_icache_user_range); EXPORT_SYMBOL(flush_icache_page); EXPORT_SYMBOL(flush_dcache_page); +#ifdef CONFIG_ALTIVEC +#ifndef CONFIG_SMP +EXPORT_SYMBOL(last_task_used_altivec); +#endif /* CONFIG_SMP */ +EXPORT_SYMBOL(giveup_altivec); +#endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_SMP EXPORT_SYMBOL(__global_cli); EXPORT_SYMBOL(__global_sti); @@ -256,6 +269,7 @@ EXPORT_SYMBOL(rtas_call); EXPORT_SYMBOL(rtas_data_buf); EXPORT_SYMBOL(rtas_data_buf_lock); +EXPORT_SYMBOL(rtas_extended_busy_delay_time); #endif #ifndef CONFIG_PPC_ISERIES @@ -309,3 +323,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 Index: arch/ppc64/kernel/proc_pcifr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/proc_pcifr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/proc_pcifr.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/proc_pcifr.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -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) */ } Index: arch/ppc64/kernel/proc_pmc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/proc_pmc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/proc_pmc.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/proc_pmc.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -49,15 +49,17 @@ 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); +void proc_ppc64_create_smt(void); + int proc_ppc64_pmc_find_file(void *data); int proc_ppc64_pmc_read(char *page, char **start, off_t off, int count, int *eof, char *buffer); @@ -145,8 +147,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 +180,11 @@ } /* 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); + } + + proc_ppc64_create_smt(); /* Create the /proc/ppc64/pcifr for the Pci Flight Recorder. */ proc_pciFr_init(proc_ppc64_root); @@ -195,7 +206,7 @@ ent->nlink = 1; ent->data = (void *)proc_ppc64_pmc_cpu_root[i]; ent->read_proc = (void *)proc_ppc64_pmc_stab_read; - ent->write_proc = (void *)proc_ppc64_pmc_stab_read; + ent->write_proc = NULL; } ent = create_proc_entry("htab", S_IRUGO | S_IWUSR, @@ -204,7 +215,7 @@ ent->nlink = 1; ent->data = (void *)proc_ppc64_pmc_cpu_root[i]; ent->read_proc = (void *)proc_ppc64_pmc_htab_read; - ent->write_proc = (void *)proc_ppc64_pmc_htab_read; + ent->write_proc = NULL; } } @@ -214,7 +225,7 @@ ent->nlink = 1; ent->data = (void *)proc_ppc64_pmc_system_root; ent->read_proc = (void *)proc_ppc64_pmc_stab_read; - ent->write_proc = (void *)proc_ppc64_pmc_stab_read; + ent->write_proc = NULL; } ent = create_proc_entry("htab", S_IRUGO | S_IWUSR, @@ -223,7 +234,7 @@ ent->nlink = 1; ent->data = (void *)proc_ppc64_pmc_system_root; ent->read_proc = (void *)proc_ppc64_pmc_htab_read; - ent->write_proc = (void *)proc_ppc64_pmc_htab_read; + ent->write_proc = NULL; } ent = create_proc_entry("profile", S_IWUSR | S_IRUGO, proc_ppc64_pmc_system_root); @@ -254,7 +265,7 @@ ent->nlink = 1; ent->data = (void *)proc_ppc64_pmc_cpu_root[i]; ent->read_proc = (void *)proc_ppc64_pmc_hw_read; - ent->write_proc = (void *)proc_ppc64_pmc_hw_read; + ent->write_proc = NULL; } } @@ -264,7 +275,7 @@ ent->nlink = 1; ent->data = (void *)proc_ppc64_pmc_system_root; ent->read_proc = (void *)proc_ppc64_pmc_hw_read; - ent->write_proc = (void *)proc_ppc64_pmc_hw_read; + ent->write_proc = NULL; } } @@ -442,6 +453,7 @@ static ssize_t write_profile(struct file * file, const char * buf, size_t count, loff_t *ppos) { + return(0); } static ssize_t read_trace(struct file *file, char *buf, @@ -466,6 +478,7 @@ static ssize_t write_trace(struct file * file, const char * buf, size_t count, loff_t *ppos) { + return(0); } static ssize_t read_timeslice(struct file *file, char *buf, @@ -474,7 +487,6 @@ unsigned long p = *ppos; ssize_t read; char * pnt; - unsigned int sample_step = 4; if (p >= (perfmon_base.timeslice_length)) return 0; if (count > (perfmon_base.timeslice_length) - p) @@ -491,6 +503,7 @@ static ssize_t write_timeslice(struct file * file, const char * buf, size_t count, loff_t *ppos) { + return(0); } int @@ -875,15 +888,24 @@ int proc_pmc_set_control( struct file *file, const char *buffer, unsigned long count, void *data ) { - if ( ! strncmp( buffer, "stop", 4 ) ) + char stkbuf[10]; + + if (count > 9) + count = 9; + if (copy_from_user (stkbuf, buffer, count)) + return -EFAULT; + + stkbuf[count] = 0; + + if ( ! strncmp( stkbuf, "stop", 4 ) ) proc_pmc_stop(); - else if ( ! strncmp( buffer, "start", 5 ) ) + else if ( ! strncmp( stkbuf, "start", 5 ) ) proc_pmc_start(); - else if ( ! strncmp( buffer, "reset", 5 ) ) + else if ( ! strncmp( stkbuf, "reset", 5 ) ) proc_pmc_reset(); - else if ( ! strncmp( buffer, "cpi", 3 ) ) + else if ( ! strncmp( stkbuf, "cpi", 3 ) ) proc_pmc_cpi(); - else if ( ! strncmp( buffer, "tlb", 3 ) ) + else if ( ! strncmp( stkbuf, "tlb", 3 ) ) proc_pmc_tlb(); /* IMPLEMENT ME */ @@ -1054,3 +1076,85 @@ remap_page_range( vma->vm_start, __pa(dp->data), dp->size, vma->vm_page_prot ); return 0; } + +static int proc_ppc64_smt_snooze_read(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + if (naca->smt_snooze_delay) + return sprintf(page, "%lu\n", naca->smt_snooze_delay); + else + return sprintf(page, "disabled\n"); +} + +static int proc_ppc64_smt_snooze_write(struct file* file, const char *buffer, + unsigned long count, void *data) +{ + unsigned long val; + char val_string[22]; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + if (count > sizeof(val_string) - 1) + return -EINVAL; + + if (copy_from_user(val_string, buffer, count)) + return -EFAULT; + + val_string[count] = '\0'; + + if (val_string[0] == '0' && (val_string[1] == '\n' || val_string[1] == '\0')) { + naca->smt_snooze_delay = 0; + return count; + } + + val = simple_strtoul(val_string, NULL, 10); + if (val != 0) + naca->smt_snooze_delay = val; + else + return -EINVAL; + + return count; +} + +static int proc_ppc64_smt_state_read(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + switch(naca->smt_state) { + case SMT_OFF: + return sprintf(page, "off\n"); + break; + case SMT_ON: + return sprintf(page, "on\n"); + break; + case SMT_DYNAMIC: + return sprintf(page, "dynamic\n"); + break; + default: + return sprintf(page, "unknown\n"); + break; + } +} + +void proc_ppc64_create_smt(void) +{ + struct proc_dir_entry *ent_snooze = + create_proc_entry("smt-snooze-delay", S_IRUGO | S_IWUSR, + proc_ppc64_root); + struct proc_dir_entry *ent_enabled = + create_proc_entry("smt-enabled", S_IRUGO | S_IWUSR, + proc_ppc64_root); + if (ent_snooze) { + ent_snooze->nlink = 1; + ent_snooze->data = NULL; + ent_snooze->read_proc = (void *)proc_ppc64_smt_snooze_read; + ent_snooze->write_proc = (void *)proc_ppc64_smt_snooze_write; + } + + if (ent_enabled) { + ent_enabled->nlink = 1; + ent_enabled->data = NULL; + ent_enabled->read_proc = (void *)proc_ppc64_smt_state_read; + ent_enabled->write_proc = NULL; + } +} Index: arch/ppc64/kernel/process.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/process.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/process.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/process.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -10,6 +10,9 @@ * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * + * VMX/Altivec port from ppc32 (c) IBM 2003 + * Denis Joseph Barrow (dj@de.ibm.com,barrow_dj@yahoo.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 @@ -42,10 +45,14 @@ #include #include #include +#include int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs); +#ifndef CONFIG_SMP struct task_struct *last_task_used_math = NULL; +struct task_struct *last_task_used_altivec = NULL; +#endif /* CONFIG_SMP */ static struct fs_struct init_fs = INIT_FS; static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS; @@ -92,6 +99,32 @@ return 1; } +#ifdef CONFIG_ALTIVEC +int +dump_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs) +{ + if (regs->msr & MSR_VEC) + giveup_altivec(current); + memcpy(vrregs, ¤t->thread.vr[0], sizeof(*vrregs)); + return 1; +} + + +void +enable_kernel_altivec(void) +{ +#ifdef CONFIG_SMP + if (current->thread.regs && (current->thread.regs->msr & MSR_VEC)) + giveup_altivec(current); + else + giveup_altivec(NULL); /* just enable AltiVec for kernel - force */ +#else + giveup_altivec(last_task_used_altivec); +#endif /* __SMP __ */ +} +#endif /* CONFIG_ALTIVEC */ + + void _switch_to(struct task_struct *prev, struct task_struct *new, struct task_struct **last) @@ -120,7 +153,21 @@ */ if ( prev->thread.regs && (prev->thread.regs->msr & MSR_FP) ) giveup_fpu(prev); - +#ifdef CONFIG_ALTIVEC + /* + * If the previous thread used altivec in the last quantum + * (thus changing altivec regs) then save them. + * We used to check the VRSAVE register but not all apps + * set it, so we don't rely on it now (and in fact we need + * to save & restore VSCR even if VRSAVE == 0). -- paulus + * + * On SMP we always save/restore altivec regs just to avoid the + * complexity of changing processors. + * -- Cort + */ + if ((prev->thread.regs && (prev->thread.regs->msr & MSR_VEC))) + giveup_altivec(prev); +#endif /* CONFIG_ALTIVEC */ /* prev->last_processor = prev->processor; */ current_set[smp_processor_id()].task = new; #endif /* CONFIG_SMP */ @@ -144,8 +191,11 @@ printk("TASK = %p[%d] '%s' ", current, current->pid, current->comm); printk("Last syscall: %ld ", current->thread.last_syscall); - printk("\nlast math %p ", last_task_used_math); - +#ifndef CONFIG_SMP + printk("\nlast math %p last altivec %p", last_task_used_math, + last_task_used_altivec); +#endif + #ifdef CONFIG_SMP /* printk(" CPU: %d last CPU: %d", current->processor,current->last_processor); */ #endif /* CONFIG_SMP */ @@ -172,14 +222,22 @@ void exit_thread(void) { +#ifndef CONFIG_SMP if (last_task_used_math == current) last_task_used_math = NULL; + if (last_task_used_altivec == current) + last_task_used_altivec = NULL; +#endif } void flush_thread(void) { +#ifndef CONFIG_SMP if (last_task_used_math == current) last_task_used_math = NULL; + if (last_task_used_altivec == current) + last_task_used_altivec = NULL; +#endif } void @@ -224,7 +282,6 @@ /* Stack is in kernel space - must adjust */ childregs->gpr[1] = (unsigned long)(childregs + 1); *((unsigned long *) childregs->gpr[1]) = 0; - childregs->gpr[13] = (unsigned long) p; } else { /* Provided stack is in user space */ childregs->gpr[1] = usp; @@ -243,6 +300,18 @@ p->thread.fpscr = current->thread.fpscr; p->thread.fpexc_mode = current->thread.fpexc_mode; +#ifdef CONFIG_ALTIVEC + /* + * copy altiVec info - assume lazy altiVec switch + * - kumar + */ + if (regs->msr & MSR_VEC) + giveup_altivec(current); + memcpy(&p->thread.vr, ¤t->thread.vr, sizeof(p->thread.vr)); + p->thread.vscr = current->thread.vscr; + childregs->msr &= ~MSR_VEC; +#endif /* CONFIG_ALTIVEC */ + return 0; } @@ -274,9 +343,19 @@ regs->gpr[1] = sp; regs->gpr[2] = toc; regs->msr = MSR_USER64; +#ifndef CONFIG_SMP if (last_task_used_math == current) last_task_used_math = 0; + if (last_task_used_altivec == current) + last_task_used_altivec = 0; +#endif /* CONFIG_SMP */ + memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); current->thread.fpscr = 0; +#ifdef CONFIG_ALTIVEC + memset(¤t->thread.vr[0], 0,offsetof(struct thread_struct,vrsave[2])- + offsetof(struct thread_struct,vr[0])); + current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */ +#endif /* CONFIG_ALTIVEC */ } # define PR_FP_EXC_DISABLED 0 /* FP exceptions disabled */ @@ -336,7 +415,10 @@ goto out; if (regs->msr & MSR_FP) giveup_fpu(current); - +#ifdef CONFIG_ALTIVEC + if (regs->msr & MSR_VEC) + giveup_altivec(current); +#endif /* CONFIG_ALTIVEC */ error = do_execve(filename, (char **) a1, (char **) a2, regs); if (error == 0) @@ -390,7 +472,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 +575,7 @@ * gets fixed. */ if (ip < first_sched || ip >= last_sched) - return (ip & 0xFFFFFFFF); + return (ip); } } while (count++ < 16); return 0; Index: arch/ppc64/kernel/prom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/prom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/prom.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/prom.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -168,7 +168,6 @@ extern struct rtas_t rtas; extern unsigned long klimit; -extern unsigned long embedded_sysmap_end; extern struct lmb lmb; #ifdef CONFIG_MSCHUNKS extern struct msChunks msChunks; @@ -180,12 +179,9 @@ char *bootpath = 0; char *bootdevice = 0; -struct device_node *allnodes = 0; +#define MAX_CPU_THREADS 2 -#define UNDEFINED_IRQ 0xffff -unsigned short real_irq_to_virt_map[NR_HW_IRQS]; -unsigned short virt_irq_to_real_map[NR_IRQS]; -int last_virt_irq = 2; /* index of last virt_irq. Skip through IPI */ +struct device_node *allnodes = 0; static unsigned long call_prom(const char *service, int nargs, int nret, ...); static void prom_exit(void); @@ -363,7 +359,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 +627,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; @@ -940,7 +937,7 @@ * By doing this, we avoid the pitfalls of trying to DMA to * MMIO space and the DMA alias hole. */ - minsize = 4UL << 20; + minsize = 8UL << 20; /* Align to the greater of the align or size */ align = (minalign < minsize) ? minsize : minalign; @@ -1053,12 +1050,16 @@ unsigned long offset = reloc_offset(); char type[64], *path; int cpuid = 0; + unsigned int interrupt_server[MAX_CPU_THREADS]; + unsigned int cpu_threads, hw_cpu_num; + int propsize; extern void __secondary_hold(void); extern unsigned long __secondary_hold_spinloop; extern unsigned long __secondary_hold_acknowledge; 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); @@ -1115,18 +1116,12 @@ call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"), ®, sizeof(reg)); - /* Only need to start secondary procs, not ourself. */ - if ( reg == _prom->cpu ) - continue; - path = (char *) mem; memset(path, 0, 256); if ((long) call_prom(RELOC("package-to-path"), 3, 1, node, path, 255) < 0) continue; - cpuid++; - #ifdef DEBUG_PROM prom_print_nl(); prom_print(RELOC("cpuid = 0x")); @@ -1138,56 +1133,80 @@ #endif _xPaca[cpuid].xHwProcNum = reg; - prom_print(RELOC("starting cpu ")); - prom_print(path); - /* Init the acknowledge var which will be reset by * the secondary cpu when it awakens from its OF * spinloop. */ *acknowledge = (unsigned long)-1; -#ifdef DEBUG_PROM - prom_print(RELOC(" 3) spinloop = 0x")); - prom_print_hex(spinloop); - prom_print_nl(); - prom_print(RELOC(" 3) *spinloop = 0x")); - prom_print_hex(*spinloop); - prom_print_nl(); - prom_print(RELOC(" 3) acknowledge = 0x")); - prom_print_hex(acknowledge); - prom_print_nl(); - prom_print(RELOC(" 3) *acknowledge = 0x")); - prom_print_hex(*acknowledge); - prom_print_nl(); - prom_print(RELOC(" 3) secondary_hold = 0x")); - prom_print_hex(secondary_hold); - prom_print_nl(); - prom_print(RELOC(" 3) cpuid = 0x")); - prom_print_hex(cpuid); - prom_print_nl(); -#endif - call_prom(RELOC("start-cpu"), 3, 0, node, secondary_hold, cpuid); - prom_print(RELOC("...")); - for ( i = 0 ; (i < 100000000) && - (*acknowledge == ((unsigned long)-1)); i++ ) ; -#ifdef DEBUG_PROM - { - unsigned long *p = 0x0; - prom_print(RELOC(" 4) 0x0 = 0x")); - prom_print_hex(*p); - prom_print_nl(); + propsize = call_prom(RELOC("getprop"), 4, 1, node, + RELOC("ibm,ppc-interrupt-server#s"), + &interrupt_server, + sizeof(interrupt_server)); + if (propsize < 0) { + /* no property. old hardware has no SMT */ + cpu_threads = 1; + interrupt_server[0] = reg; /* fake it with phys id */ + } else { + /* We have a threaded processor */ + cpu_threads = propsize / sizeof(u32); + if (cpu_threads > MAX_CPU_THREADS) { + prom_print(RELOC("SMT: too many threads!\nSMT: found ")); + prom_print_hex(cpu_threads); + prom_print(RELOC(", max is ")); + prom_print_hex(MAX_CPU_THREADS); + prom_print_nl(); + cpu_threads = 1; /* ToDo: panic? */ + } } -#endif - if (*acknowledge == cpuid) { - prom_print(RELOC("ok\n")); - /* Set the number of active processors. */ - _systemcfg->processorCount++; + + hw_cpu_num = interrupt_server[0]; + if (hw_cpu_num != _prom->cpu) { + /* Primary Thread of non-boot cpu */ + prom_print_hex(cpuid); + prom_print(RELOC(" : starting cpu ")); + prom_print(path); + prom_print(RELOC(" ... ")); + call_prom(RELOC("start-cpu"), 3, 0, node, + secondary_hold, cpuid); + + for(i = 0; (i < 100000000) && + (*acknowledge == ((unsigned long)-1)); i++ ); + + if (*acknowledge == cpuid) { + prom_print(RELOC("ok\n")); + /* Set the number of active processors. */ + _systemcfg->processorCount++; + _xPaca[cpuid].active = 1; + _xPaca[cpuid].available = 1; + } else { + prom_print(RELOC("failed: ")); + prom_print_hex(*acknowledge); + prom_print_nl(); + /* prom_panic(RELOC("cpu failed to start")); */ + } } else { - prom_print(RELOC("failed: ")); - prom_print_hex(*acknowledge); + prom_print_hex(cpuid); + prom_print(RELOC(" : booting cpu ")); + prom_print(path); + prom_print_nl(); + } + + /* Init paca for secondary threads. They start later. */ + for (i=1; i < cpu_threads; i++) { + cpuid++; + _xPaca[cpuid].xHwProcNum = interrupt_server[i]; + prom_print_hex(interrupt_server[i]); + prom_print(RELOC(" : preparing thread ... ")); + if (_naca->smt_state) { + _xPaca[cpuid].available = 1; + prom_print(RELOC("available")); + } else { + prom_print(RELOC("not available")); + } prom_print_nl(); } + cpuid++; } #ifdef CONFIG_HMT /* Only enable HMT on processors that provide support. */ @@ -1234,10 +1253,108 @@ #endif } +static void +smt_setup(void) +{ + char *p, *q; + char my_smt_enabled = SMT_DYNAMIC; + unsigned long my_smt_snooze_delay; + ihandle prom_options = NULL; + char option[9]; + unsigned long offset = reloc_offset(); + struct naca_struct *_naca = RELOC(naca); + char found = 0; + + if (strstr(RELOC(cmd_line), RELOC("smt-enabled="))) { + for (q = RELOC(cmd_line); (p = strstr(q, RELOC("smt-enabled="))) != 0; ) { + q = p + 12; + if (p > RELOC(cmd_line) && p[-1] != ' ') + continue; + found = 1; + if (q[0] == 'o' && q[1] == 'f' && + q[2] == 'f' && (q[3] == ' ' || q[3] == '\0')) { + my_smt_enabled = SMT_OFF; + } else if (q[0]=='o' && q[1] == 'n' && + (q[2] == ' ' || q[2] == '\0')) { + my_smt_enabled = SMT_ON; + } else { + my_smt_enabled = SMT_DYNAMIC; + } + } + } + if (!found) { + prom_options = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/options")); + if (prom_options != (ihandle) -1) { + call_prom(RELOC("getprop"), + 4, 1, prom_options, + RELOC("ibm,smt-enabled"), + option, sizeof(option)); + if (option[0] != 0) { + found = 1; + if (!strcmp(option, "off")) + my_smt_enabled = SMT_OFF; + else if (!strcmp(option, "on")) + my_smt_enabled = SMT_ON; + else + my_smt_enabled = SMT_DYNAMIC; + } + } + } + + if (!found ) + my_smt_enabled = SMT_DYNAMIC; /* default to on */ + + found = 0; + if (my_smt_enabled) { + if (strstr(RELOC(cmd_line), RELOC("smt-snooze-delay="))) { + for (q = RELOC(cmd_line); (p = strstr(q, RELOC("smt-snooze-delay="))) != 0; ) { + q = p + 17; + if (p > RELOC(cmd_line) && p[-1] != ' ') + continue; + found = 1; + /* Don't use simple_strtoul() because _ctype & others aren't RELOC'd */ + my_smt_snooze_delay = 0; + while (*q >= '0' && *q <= '9') { + my_smt_snooze_delay = my_smt_snooze_delay * 10 + *q - '0'; + q++; + } + } + } + + if (!found) { + prom_options = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/options")); + if (prom_options != (ihandle) -1) { + call_prom(RELOC("getprop"), + 4, 1, prom_options, + RELOC("ibm,smt-snooze-delay"), + option, sizeof(option)); + if (option[0] != 0) { + found = 1; + /* Don't use simple_strtoul() because _ctype & others aren't RELOC'd */ + my_smt_snooze_delay = 0; + q = option; + while (*q >= '0' && *q <= '9') { + my_smt_snooze_delay = my_smt_snooze_delay * 10 + *q - '0'; + q++; + } + } + } + } + + if (!found) { + my_smt_snooze_delay = 30000; /* default value */ + } + } else { + my_smt_snooze_delay = 0; /* default value */ + } + _naca->smt_snooze_delay = my_smt_snooze_delay; + _naca->smt_state = my_smt_enabled; +} + #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(); @@ -1357,7 +1474,6 @@ char *p, *d; unsigned long phys; u32 getprop_rval; - struct naca_struct *_naca = RELOC(naca); struct systemcfg *_systemcfg = RELOC(systemcfg); struct paca_struct *_xPaca = PTRRELOC(&paca[0]); struct prom_t *_prom = PTRRELOC(&prom); @@ -1365,9 +1481,6 @@ /* Default machine type. */ _systemcfg->platform = PLATFORM_PSERIES; - /* Reset klimit to take into account the embedded system map */ - if (RELOC(embedded_sysmap_end)) - RELOC(klimit) = __va(PAGE_ALIGN(RELOC(embedded_sysmap_end))); /* Get a handle to the prom entry point before anything else */ _prom->entry = pp; @@ -1530,12 +1643,13 @@ /* Initialize some system info into the Naca early... */ mem = prom_initialize_naca(mem); + smt_setup(); + /* If we are on an SMP machine, then we *MUST* do the * following, regardless of whether we have an SMP * kernel or not. */ - if (_systemcfg->processorCount > 1) - prom_hold_cpus(mem); + prom_hold_cpus(mem); #ifdef DEBUG_PROM prom_print(RELOC("copying OF device tree...\n")); @@ -1559,7 +1673,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"), @@ -1695,46 +1809,6 @@ return DOUBLEWORD_ALIGN(mem); } -void -virt_irq_init(void) -{ - int i; - for (i = 0; i < NR_IRQS; i++) - virt_irq_to_real_map[i] = UNDEFINED_IRQ; - for (i = 0; i < NR_HW_IRQS; i++) - real_irq_to_virt_map[i] = UNDEFINED_IRQ; -} - -/* Create a mapping for a real_irq if it doesn't already exist. - * Return the virtual irq as a convenience. - */ -unsigned long -virt_irq_create_mapping(unsigned long real_irq) -{ - unsigned long virq; - if (naca->interrupt_controller == IC_OPEN_PIC) - return real_irq; /* no mapping for openpic (for now) */ - virq = real_irq_to_virt(real_irq); - if (virq == UNDEFINED_IRQ) { - /* Assign a virtual IRQ number */ - if (real_irq < NR_IRQS && virt_irq_to_real(real_irq) == UNDEFINED_IRQ) { - /* A 1-1 mapping will work. */ - virq = real_irq; - } else { - while (last_virt_irq < NR_IRQS && - virt_irq_to_real(++last_virt_irq) != UNDEFINED_IRQ) - /* skip irq's in use */; - if (last_virt_irq >= NR_IRQS) - panic("Too many IRQs are required on this system. NR_IRQS=%d\n", NR_IRQS); - virq = last_virt_irq; - } - virt_irq_to_real_map[virq] = real_irq; - real_irq_to_virt_map[real_irq] = virq; - } - return virq; -} - - static int __init prom_next_node(phandle *nodep) { @@ -1831,6 +1905,23 @@ *prev_propp = PTRUNRELOC(pp); prev_propp = &pp->next; } + + /* Add a "linux_phandle" value */ + if (np->node != NULL) { + u32 ibm_phandle = 0; + int len; + + /* First see if "ibm,phandle" exists and use its value */ + len = (int) call_prom(RELOC("getprop"), 4, 1, node, + RELOC("ibm,phandle"), + &ibm_phandle, sizeof(ibm_phandle)); + if (len < 0) { + np->linux_phandle = np->node; + } else { + np->linux_phandle = ibm_phandle; + } + } + *prev_propp = 0; /* get the node's full name */ @@ -1864,8 +1955,6 @@ { unsigned long mem = klimit; - virt_irq_init(); - mem = finish_node(allnodes, mem, NULL, 0, 0); dev_tree_size = mem - (unsigned long) allnodes; @@ -1970,7 +2059,7 @@ np->n_intrs = ipsize / isize; mem_start += np->n_intrs * sizeof(struct interrupt_info); for (i = 0; i < np->n_intrs; ++i) { - np->intrs[i].line = openpic_to_irq(virt_irq_create_mapping(*interrupts++)); + np->intrs[i].line = irq_offset_up(*interrupts++); np->intrs[i].sense = 1; if (isize > 1) np->intrs[i].sense = *interrupts++; @@ -2332,7 +2421,7 @@ struct device_node *np; for (np = allnodes; np != 0; np = np->allnext) - if (np->node == ph) + if (np->linux_phandle == ph) return np; return NULL; } @@ -2423,7 +2512,7 @@ void __init -abort() +abort(void) { #ifdef CONFIG_XMON xmon(NULL); Index: arch/ppc64/kernel/ptrace.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/ptrace.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/ptrace.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/ptrace.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -67,6 +67,28 @@ return -EIO; } +#ifdef CONFIG_ALTIVEC +/* + * Get contents of AltiVec register state in task TASK + */ +static inline int get_vrregs(unsigned long data, struct task_struct *task) +{ + return (copy_to_user((void *)data,&task->thread.vr[0], + offsetof(struct thread_struct,vrsave[2])- + offsetof(struct thread_struct,vr[0])) ? -EFAULT : 0 ); +} + +/* + * Write contents of AltiVec register state into task TASK. + */ +static inline int set_vrregs(struct task_struct *task, unsigned long data) +{ + return (copy_from_user(&task->thread.vr[0],(void *)data, + offsetof(struct thread_struct,vrsave[2])- + offsetof(struct thread_struct,vr[0])) ? -EFAULT : 0 ); +} +#endif + static inline void set_single_step(struct task_struct *task) { @@ -316,6 +338,23 @@ } break; } +#ifdef CONFIG_ALTIVEC + case PTRACE_GETVRREGS: + /* Get the child altivec register state. */ + if (child->thread.regs->msr & MSR_VEC) + giveup_altivec(child); + ret = get_vrregs(data, child); + break; + + case PTRACE_SETVRREGS: + /* Set the child altivec register state. */ + /* this is to clear the MSR_VEC bit to force a reload + * of register state from memory */ + if (child->thread.regs->msr & MSR_VEC) + giveup_altivec(child); + ret = set_vrregs(child,data); + break; +#endif default: ret = -EIO; Index: arch/ppc64/kernel/ptrace32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/ptrace32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/ptrace32.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/ptrace32.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -31,6 +31,40 @@ #include #include +#ifdef CONFIG_ALTIVEC +/* + * Get contents of AltiVec register state in task TASK + */ +static inline int get_vrregs32(unsigned long data, struct task_struct *task) +{ + if(copy_to_user((void *)data,&task->thread.vr[0], + offsetof(struct thread_struct,vrsave)- + offsetof(struct thread_struct,vr[0]))) + return -EFAULT; + data+=offsetof(struct thread_struct,vrsave[1])- + offsetof(struct thread_struct,vr[0]); + if (put_user(task->thread.vrsave[1],((u32 *)data))) + return -EFAULT; + return 0; +} + +/* + * Write contents of AltiVec register state into task TASK. + */ +static inline int set_vrregs32(struct task_struct *task, unsigned long data) +{ + if(copy_from_user(&task->thread.vr[0],(void *)data, + offsetof(struct thread_struct,vrsave)- + offsetof(struct thread_struct,vr[0]))) + return -EFAULT; + data+=offsetof(struct thread_struct,vrsave[1])- + offsetof(struct thread_struct,vr[0]); + if (get_user(task->thread.vrsave[1],((u32 *)data))) + return -EFAULT; + return 0; +} +#endif + /* * Set of msr bits that gdb can change on behalf of a process. */ @@ -463,6 +497,23 @@ +#ifdef CONFIG_ALTIVEC + case PTRACE_GETVRREGS: + /* Get the child altivec register state. */ + if (child->thread.regs->msr & MSR_VEC) + giveup_altivec(child); + ret = get_vrregs32((unsigned long)data, child); + break; + + case PTRACE_SETVRREGS: + /* Set the child altivec register state. */ + /* this is to clear the MSR_VEC bit to force a reload + * of register state from memory */ + if (child->thread.regs->msr & MSR_VEC) + giveup_altivec(child); + ret = set_vrregs32(child,(unsigned long)data); + break; +#endif default: ret = -EIO; break; Index: arch/ppc64/kernel/ras.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/ras.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/ras.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/ras.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -73,7 +73,7 @@ (ireg = (unsigned int *)get_property(np, "open-pic-interrupt", &len))) { for(i=0; i<(len / sizeof(*ireg)); i++) { - request_irq(virt_irq_create_mapping(*(ireg)) + NUM_8259_INTERRUPTS, + request_irq(irq_offset_up(*(ireg)), &ras_error_interrupt, 0, "RAS_ERROR", NULL); ireg++; @@ -84,7 +84,7 @@ (ireg = (unsigned int *)get_property(np, "open-pic-interrupt", &len))) { for(i=0; i<(len / sizeof(*ireg)); i++) { - request_irq(virt_irq_create_mapping(*(ireg)) + NUM_8259_INTERRUPTS, + request_irq(irq_offset_up(*(ireg)), &ras_epow_interrupt, 0, "RAS_EPOW", NULL); ireg++; @@ -108,7 +108,7 @@ status = rtas_call(rtas_token("check-exception"), 6, 1, NULL, 0x500, irq, - EPOW_WARNING | POWERMGM_EVENTS, + RTAS_EPOW_WARNING | RTAS_POWERMGM_EVENTS, 1, /* Time Critical */ __pa(&log_entry), size); @@ -116,6 +116,9 @@ *((unsigned long *)&log_entry), status); printk(KERN_WARNING "EPOW <0x%lx 0x%lx>\n",*((unsigned long *)&log_entry), status); + + /* format and print the extended information */ + log_error((char *)&log_entry, ERR_TYPE_RTAS_LOG, 0); } /* @@ -132,15 +135,23 @@ struct rtas_error_log log_entry; unsigned int size = sizeof(log_entry); long status = 0xdeadbeef; + int fatal; status = rtas_call(rtas_token("check-exception"), 6, 1, NULL, 0x500, irq, - INTERNAL_ERROR, + RTAS_INTERNAL_ERROR, 1, /* Time Critical */ __pa(&log_entry), size); - if((status != 1) && - (log_entry.severity >= SEVERITY_ERROR_SYNC)) { + if ((status == 0) && (log_entry.severity >= SEVERITY_ERROR_SYNC)) + fatal = 1; + else + fatal = 0; + + /* format and print the extended information */ + log_error((char *)&log_entry, ERR_TYPE_RTAS_LOG, fatal); + + if (fatal) { udbg_printf("HW Error <0x%lx 0x%lx>\n", *((unsigned long *)&log_entry), status); printk(KERN_EMERG @@ -150,6 +161,7 @@ #ifndef DEBUG /* Don't actually power off when debugging so we can test * without actually failing while injecting errors. + * Error data will not be logged to syslog. */ ppc_md.power_off(); #endif Index: arch/ppc64/kernel/rtas-proc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/rtas-proc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/rtas-proc.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/rtas-proc.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -115,14 +115,23 @@ /* 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; + +static int set_time_for_power_on = RTAS_UNKNOWN_SERVICE; +static int set_time_of_day = RTAS_UNKNOWN_SERVICE; +static int get_sensor_state = RTAS_UNKNOWN_SERVICE; +static int set_indicator = RTAS_UNKNOWN_SERVICE; + +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 +169,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 +199,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); @@ -198,35 +220,80 @@ void proc_rtas_init(void) { struct proc_dir_entry *entry; + int display_character; + int errinjct_token; 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 */ + /* + * /proc/rtas entries + * only create entries if rtas token exists for desired function + */ - entry = create_proc_entry("progress", S_IRUGO|S_IWUSR, proc_rtas); - if (entry) entry->proc_fops = &ppc_rtas_progress_operations; + set_time_of_day = rtas_token("set-time-of-day"); + if (set_time_of_day != RTAS_UNKNOWN_SERVICE) { + 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("clock", S_IRUGO|S_IWUSR, proc_rtas); - if (entry) entry->proc_fops = &ppc_rtas_clock_operations; + set_time_for_power_on = rtas_token("set-time-for-power-on"); + if (set_time_for_power_on != RTAS_UNKNOWN_SERVICE) { + entry=create_proc_entry("poweron",S_IWUSR|S_IRUGO,rtas_proc_dir); + if (entry) entry->proc_fops = &ppc_rtas_poweron_operations; + } - entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, proc_rtas); - if (entry) entry->proc_fops = &ppc_rtas_poweron_operations; + get_sensor_state = rtas_token("get-sensor-state"); + if (get_sensor_state != RTAS_UNKNOWN_SERVICE) { + create_proc_read_entry("sensors", S_IRUGO, rtas_proc_dir, + ppc_rtas_sensor_read, NULL); + } - 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); - if (entry) entry->proc_fops = &ppc_rtas_tone_freq_operations; + set_indicator = rtas_token("set-indicator"); + if (set_indicator != RTAS_UNKNOWN_SERVICE) { + 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,rtas_proc_dir); + if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations; + } + + display_character = rtas_token("display-character"); + if ((display_character != RTAS_UNKNOWN_SERVICE) || + (set_indicator != RTAS_UNKNOWN_SERVICE)) { + entry=create_proc_entry("progress",S_IRUGO|S_IWUSR,rtas_proc_dir); + if (entry) entry->proc_fops = &ppc_rtas_progress_operations; + } + +#ifdef CONFIG_RTAS_ERRINJCT + errinjct_token = rtas_token("ibm,errinjct"); + if (errinjct_token != RTAS_UNKNOWN_SERVICE) { + entry=create_proc_entry("errinjct",S_IWUSR|S_IRUGO,rtas_proc_dir); + if (entry) entry->proc_fops = &ppc_rtas_errinjct_operations; + } +#endif - entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, proc_rtas); - if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations; } /* ****************************************************************** */ @@ -235,12 +302,19 @@ static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { + char stkbuf[40]; /* its small, its on stack */ struct rtc_time tm; unsigned long nowtime; char *dest; int error; - nowtime = simple_strtoul(buf, &dest, 10); + if (39 < count) + count = 39; + if (copy_from_user(stkbuf, buf, count)) + return -EFAULT; + + stkbuf[count] = 0; + nowtime = simple_strtoul(stkbuf, &dest, 10); if (*dest != '\0' && *dest != '\n') { printk("ppc_rtas_poweron_write: Invalid time\n"); return count; @@ -249,11 +323,11 @@ to_tm(nowtime, &tm); - error = rtas_call(rtas_token("set-time-for-power-on"), 7, 1, NULL, - tm.tm_year, tm.tm_mon, tm.tm_mday, + error = rtas_call(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; } @@ -261,18 +335,23 @@ static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf, size_t count, loff_t *ppos) { + char stkbuf[40]; /* its small, its on stack */ int n; + if (power_on_time == 0) - n = sprintf(buf, "Power on time not set\n"); + n = snprintf(stkbuf, 40, "Power on time not set\n"); else - n = sprintf(buf, "%lu\n", power_on_time); + n = snprintf(stkbuf, 40, "%lu\n", power_on_time); - if (*ppos >= strlen(buf)) + int sn = strlen(stkbuf) +1; + if (*ppos >= sn) return 0; - if (n > strlen(buf) - *ppos) - n = strlen(buf) - *ppos; + if (n > sn - *ppos) + n = sn - *ppos; if (n > count) n = count; + if (copy_to_user(buf, stkbuf + (*ppos), n)) + return -EFAULT; *ppos += n; return n; } @@ -285,11 +364,17 @@ { unsigned long hex; - strcpy(progress_led, buf); /* save the string */ + if (count >= MAX_LINELENGTH) + count = MAX_LINELENGTH -1; + if (copy_from_user(progress_led, buf, count)) + return -EFAULT; + + progress_led[count] = 0; + /* Lets see if the user passed hexdigits */ - hex = simple_strtoul(buf, NULL, 10); - - ppc_md.progress ((char *)buf, hex); + hex = simple_strtoul(progress_led, NULL, 10); + + ppc_md.progress((char *)progress_led, hex); return count; /* clear the line */ /* ppc_md.progress(" ", 0xffff);*/ @@ -298,15 +383,32 @@ static ssize_t ppc_rtas_progress_read(struct file * file, char * buf, size_t count, loff_t *ppos) { - int n = 0; - if (progress_led != NULL) - n = sprintf (buf, "%s\n", progress_led); - if (*ppos >= strlen(buf)) + int n = 0, sn; + + if (progress_led == NULL) return 0; - if (n > strlen(buf) - *ppos) - n = strlen(buf) - *ppos; + + char * tmpbuf = kmalloc(MAX_LINELENGTH, GFP_KERNEL); + if (!tmpbuf) { + printk(KERN_ERR "error: kmalloc failed\n"); + return -ENOMEM; + } + n = sprintf (tmpbuf, "%s\n", progress_led); + + sn = strlen (tmpbuf) +1; + if (*ppos >= sn) { + kfree(tmpbuf); + return 0; + } + if (n > sn - *ppos) + n = sn - *ppos; if (n > count) n = count; + if (copy_to_user(buf, tmpbuf + (*ppos), n)) { + kfree(tmpbuf); + return -EFAULT; + } + kfree(tmpbuf); *ppos += n; return n; } @@ -317,12 +419,19 @@ static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { + char stkbuf[40]; /* its small, its on stack */ struct rtc_time tm; unsigned long nowtime; char *dest; int error; - nowtime = simple_strtoul(buf, &dest, 10); + if (39 < count) + count = 39; + if (copy_from_user(stkbuf, buf, count)) + return -EFAULT; + + stkbuf[count] = 0; + nowtime = simple_strtoul(stkbuf, &dest, 10); if (*dest != '\0' && *dest != '\n') { printk("ppc_rtas_clock_write: Invalid time\n"); return count; @@ -350,21 +459,27 @@ year = ret[0]; mon = ret[1]; day = ret[2]; hour = ret[3]; min = ret[4]; sec = ret[5]; + char stkbuf[40]; /* its small, its on stack */ + if (error != 0){ printk(KERN_WARNING "error: reading the clock returned: %s\n", ppc_rtas_process_error(error)); - n = sprintf (buf, "0"); + n = snprintf(stkbuf, 40, "0"); } else { - n = sprintf (buf, "%lu\n", mktime(year, mon, day, hour, min, sec)); + n = snprintf(stkbuf, 40, "%lu\n", mktime(year, mon, day, hour, min, sec)); } kfree(ret); - if (*ppos >= strlen(buf)) + int sn = strlen(stkbuf) +1; + if (*ppos >= sn) return 0; - if (n > strlen(buf) - *ppos) - n = strlen(buf) - *ppos; + if (n > sn - *ppos) + n = sn - *ppos; if (n > count) n = count; + if (copy_to_user(buf, stkbuf + (*ppos), n)) + return -EFAULT; + *ppos += n; return n; } @@ -379,7 +494,6 @@ unsigned long ret; int state, error; char *buffer; - int get_sensor_state = rtas_token("get-sensor-state"); if (count < 0) return -EINVAL; @@ -393,8 +507,8 @@ memset(buffer, 0, MAX_LINELENGTH*MAX_SENSORS); n = sprintf ( buffer , "RTAS (RunTime Abstraction Services) Sensor Information\n"); - n += sprintf ( buffer+n, "Sensor\t\tValue\t\tCondition\tLocation\n"); - n += sprintf ( buffer+n, "********************************************************\n"); + n += sprintf ( buffer+n, "%-17s\t%-15s\t%-15s\tLocation\n", "Sensor", "Value", "Condition"); + n += sprintf ( buffer+n, "***************************************************************************\n"); if (ppc_rtas_find_all_sensors() != 0) { n += sprintf ( buffer+n, "\nNo sensors are available\n"); @@ -405,10 +519,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 +544,7 @@ n = count; else *eof = 1; + memcpy(buf, buffer + off, n); *start = buf; kfree(buffer); @@ -436,10 +555,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 +566,9 @@ sensors.quant = len / 8; /* int + int */ - for (i=0, j=0; j= 0 && state < value_arrsize) { + n += sprintf(buf+n, "%-15s\t", value_arr[state]); + } else { if (temperature) { - n += sprintf(buf+n, "%4d /%4d\t", state, cel_to_fahr(state)); + n += sprintf(buf+n, "%2d / %2d \t", state, cel_to_fahr(state)); } else - n += sprintf(buf+n, "%10d\t", state); + n += sprintf(buf+n, "%-10d\t", state); } if (unknown == 0) { - n += sprintf ( buf+n, "%s\t", ppc_rtas_process_error(error)); + n += sprintf ( buf+n, "%-15s\t", ppc_rtas_process_error(error)); n += get_location_code(s, buf+n); } return n; @@ -698,16 +825,16 @@ ret = (char *) get_property(rtas_node, rstr, &llen); n=0; - if (ret[0] == '\0') + if (ret == NULL || ret[0] == '\0') { n += sprintf ( buffer+n, "--- ");/* does not have a location */ - else { + } else { char t[50]; ret += pos; n += check_location_string(ret, buffer + n); n += sprintf ( buffer+n, " "); /* see how many characters we have printed */ - sprintf ( t, "%s ", ret); + snprintf( t, 50, "%s ", ret); pos += strlen(t); if (pos >= llen) pos=0; @@ -720,17 +847,25 @@ static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { + char stkbuf[40]; /* its small, its on stack */ unsigned long freq; char *dest; int error; - freq = simple_strtoul(buf, &dest, 10); + + if (39 < count) + count = 39; + if (copy_from_user(stkbuf, buf, count)) + return -EFAULT; + + stkbuf[count] = 0; + freq = simple_strtoul(stkbuf, &dest, 10); if (*dest != '\0' && *dest != '\n') { printk("ppc_rtas_tone_freq_write: Invalid tone freqency\n"); return count; } if (freq < 0) freq = 0; rtas_tone_frequency = freq; /* save it for later */ - error = rtas_call(rtas_token("set-indicator"), 3, 1, NULL, + error = rtas_call(set_indicator, 3, 1, NULL, TONE_FREQUENCY, 0, freq); if (error != 0) printk(KERN_WARNING "error: setting tone frequency returned: %s\n", @@ -741,15 +876,21 @@ static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf, size_t count, loff_t *ppos) { - int n; - n = sprintf(buf, "%lu\n", rtas_tone_frequency); + int n, sn; + char stkbuf[40]; /* its small, its on stack */ + + n = snprintf(stkbuf, 40, "%lu\n", rtas_tone_frequency); - if (*ppos >= strlen(buf)) + sn = strlen(stkbuf) +1; + if (*ppos >= sn) return 0; - if (n > strlen(buf) - *ppos) - n = strlen(buf) - *ppos; + if (n > sn - *ppos) + n = sn - *ppos; if (n > count) n = count; + if (copy_to_user(buf, stkbuf + (*ppos), n)) + return -EFAULT; + *ppos += n; return n; } @@ -759,10 +900,18 @@ static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { + char stkbuf[40]; /* its small, its on stack */ unsigned long volume; char *dest; int error; - volume = simple_strtoul(buf, &dest, 10); + + if (39 < count) + count = 39; + if (copy_from_user(stkbuf, buf, count)) + return -EFAULT; + + stkbuf[count] = 0; + volume = simple_strtoul(stkbuf, &dest, 10); if (*dest != '\0' && *dest != '\n') { printk("ppc_rtas_tone_volume_write: Invalid tone volume\n"); return count; @@ -771,7 +920,7 @@ if (volume > 100) volume = 100; rtas_tone_volume = volume; /* save it for later */ - error = rtas_call(rtas_token("set-indicator"), 3, 1, NULL, + error = rtas_call(set_indicator, 3, 1, NULL, TONE_VOLUME, 0, volume); if (error != 0) printk(KERN_WARNING "error: setting tone volume returned: %s\n", @@ -782,15 +931,170 @@ static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf, size_t count, loff_t *ppos) { - int n; - n = sprintf(buf, "%lu\n", rtas_tone_volume); + int n, sn; + char stkbuf[40]; /* its small, its on stack */ - if (*ppos >= strlen(buf)) + n = snprintf(stkbuf, 40, "%lu\n", rtas_tone_volume); + sn = strlen(stkbuf) +1; + if (*ppos >= sn) return 0; - if (n > strlen(buf) - *ppos) - n = strlen(buf) - *ppos; + if (n > sn - *ppos) + n = sn - *ppos; if (n > count) n = count; + if (copy_to_user(buf, stkbuf + (*ppos), n)) + return -EFAULT; + *ppos += n; return n; } + +/* ****************************************************************** */ +/* ERRINJCT */ +/* ****************************************************************** */ +static int ppc_rtas_errinjct_open(struct inode *inode, struct file *file) +{ + int rc; + + /* We will only allow one process to use error inject at a + time. Since errinjct is usually only used for testing, + this shouldn't be an issue */ + if (open_token) { + return -EAGAIN; + } + rc = rtas_errinjct_open(); + if (rc < 0) { + return -EIO; + } + open_token = rc; + + return 0; +} + +static ssize_t ppc_rtas_errinjct_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + char * tmpbuf; + char * ei_token; + char * workspace = NULL; + size_t max_len; + int token_len; + int rc; + + /* Verify the errinjct token length */ + if (count < ERRINJCT_TOKEN_LEN) { + max_len = count; + } else { + max_len = ERRINJCT_TOKEN_LEN; + } + + tmpbuf = (char *) kmalloc(max_len, GFP_KERNEL); + if (!tmpbuf) { + printk(KERN_WARNING "error: kmalloc failed\n"); + return -ENOMEM; + } + if (copy_from_user (tmpbuf, buf, max_len)) { + kfree(tmpbuf); + return -EFAULT; + } + token_len = strnlen(tmpbuf, max_len); + token_len++; /* Add one for the null termination */ + + ei_token = (char *)kmalloc(token_len, GFP_KERNEL); + if (!ei_token) { + printk(KERN_WARNING "error: kmalloc failed\n"); + kfree(tmpbuf); + return -ENOMEM; + } + + strncpy(ei_token, tmpbuf, token_len); + + if (count > 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(tmpbuf); + kfree(ei_token); + return -ENOMEM; + } + + memcpy(workspace, tmpbuf, max_len); + } + + rc = rtas_errinjct(open_token, ei_token, workspace); + + if (count > token_len) { + kfree(workspace); + } + kfree(ei_token); + kfree(tmpbuf); + + 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, sn; + int n = 0; + + int m = MAX_ERRINJCT_TOKENS * (ERRINJCT_TOKEN_LEN+1); + buffer = (char *)kmalloc(m, 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 += snprintf(buffer+n, m-n, ei_token_list[i].name); + n += snprintf(buffer+n, m-n, "\n"); + } + + sn = strlen(buffer) +1; + if (*ppos >= sn) { + kfree(buffer); + return 0; + } + if (n > sn - *ppos) + n = sn - *ppos; + + if (n > count) + n = count; + + if (copy_to_user(buf, buffer + *ppos, n)) { + kfree(buffer); + return -EFAULT; + } + + *ppos += n; + + kfree(buffer); + return n; +} Index: arch/ppc64/kernel/rtas.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/rtas.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/rtas.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/rtas.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -24,12 +25,15 @@ #include #include #include +#include #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 +63,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, ...) @@ -181,6 +185,26 @@ return (ulong)((nret > 0) ? rtas_args->rets[0] : 0); } +/* Given an RTAS status code of 990n compute the hinted delay of 10^n + * (last digit) milliseconds. For now we bound at n=3 (1 sec). + */ +unsigned int +rtas_extended_busy_delay_time(int status) +{ + int order = status - 9900; + unsigned int ms; + + if (order < 0) + order = 0; /* RTC depends on this for -2 clock busy */ + else if (order > 3) + order = 3; /* bound */ + + /* Use microseconds for reasonable accuracy */ + for (ms = 1000; order > 0; order--) + ms = ms * 10; + return ms / (1000000/HZ); /* round down is fine */ +} + #define FLASH_BLOCK_LIST_VERSION (1UL) static void rtas_flash_firmware(void) @@ -204,7 +228,8 @@ rtas_firmware_flash_list.num_blocks = 0; flist = (struct flash_block_list *)&rtas_firmware_flash_list; rtas_block_list = virt_to_absolute((unsigned long)flist); - if (rtas_block_list >= (4UL << 20)) { + + if (rtas_block_list >= 4UL*1024*1024*1024) { printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n"); return; } @@ -219,7 +244,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 +314,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 Index: arch/ppc64/kernel/rtas_flash.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/rtas_flash.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/rtas_flash.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/rtas_flash.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -25,6 +25,52 @@ #define MODULE_NAME "rtas_flash" #define FIRMWARE_FLASH_NAME "firmware_flash" +#define FIRMWARE_UPDATE_NAME "firmware_update" +#define MANAGE_FLASH_NAME "manage_flash" +#define VALIDATE_FLASH_NAME "validate_flash" + +/* General RTAS Status Codes */ +#define RTAS_RC_SUCCESS 0 +#define RTAS_RC_HW_ERR -1 +#define RTAS_RC_BUSY -2 + +/* Flash image status values */ +#define FLASH_AUTH -9002 /* RTAS Not Service Authority Partition */ +#define FLASH_NO_OP -1099 /* No operation initiated by user */ +#define FLASH_IMG_SHORT -1005 /* Flash image shorter than expected */ +#define FLASH_IMG_BAD_LEN -1004 /* Bad length value in flash list block */ +#define FLASH_IMG_NULL_DATA -1003 /* Bad data value in flash list block */ +#define FLASH_IMG_READY 0 /* Firmware img ready for flash on reboot */ + +/* Manage image status values */ +#define MANAGE_AUTH -9002 /* RTAS Not Service Authority Partition */ +#define MANAGE_ACTIVE_ERR -9001 /* RTAS Cannot Overwrite Active Img */ +#define MANAGE_NO_OP -1099 /* No operation initiated by user */ +#define MANAGE_PARAM_ERR -3 /* RTAS Parameter Error */ +#define MANAGE_HW_ERR -1 /* RTAS Hardware Error */ + +/* Validate image status values */ +#define VALIDATE_AUTH -9002 /* RTAS Not Service Authority Partition */ +#define VALIDATE_NO_OP -1099 /* No operation initiated by the user */ +#define VALIDATE_INCOMPLETE -1002 /* User copied < VALIDATE_BUF_SIZE */ +#define VALIDATE_READY -1001 /* Firmware image ready for validation */ +#define VALIDATE_PARAM_ERR -3 /* RTAS Parameter Error */ +#define VALIDATE_HW_ERR -1 /* RTAS Hardware Error */ +#define VALIDATE_TMP_UPDATE 0 /* Validate Return Status */ +#define VALIDATE_FLASH_AUTH 1 /* Validate Return Status */ +#define VALIDATE_INVALID_IMG 2 /* Validate Return Status */ +#define VALIDATE_CUR_UNKNOWN 3 /* Validate Return Status */ +#define VALIDATE_TMP_COMMIT_DL 4 /* Validate Return Status */ +#define VALIDATE_TMP_COMMIT 5 /* Validate Return Status */ +#define VALIDATE_TMP_UPDATE_DL 6 /* Validate Return Status */ + +/* ibm,manage-flash-image operation tokens */ +#define RTAS_REJECT_TMP_IMG 0 +#define RTAS_COMMIT_TMP_IMG 1 + +/* Array sizes */ +#define VALIDATE_BUF_SIZE 4096 +#define RTAS_MSG_MAXLEN 64 /* Local copy of the flash block list. * We only allow one open of the flash proc file and create this @@ -36,21 +82,35 @@ * is treated as the number of entries currently in the block * (i.e. not a byte count). This is all fixed on release. */ -static struct flash_block_list *flist; -static char *flash_msg; -static int flash_possible; - -static int rtas_flash_open(struct inode *inode, struct file *file) -{ - if ((file->f_mode & FMODE_WRITE) && flash_possible) { - if (flist) - return -EBUSY; - flist = (struct flash_block_list *)get_free_page(GFP_KERNEL); - if (!flist) - return -ENOMEM; - } - return 0; -} + +/* Status int must be first member of struct */ +struct rtas_update_flash_t +{ + int status; /* Flash update status */ + struct flash_block_list *flist; /* Local copy of flash block list */ +}; + +/* Status int must be first member of struct */ +struct rtas_manage_flash_t +{ + int status; /* Returned status */ + unsigned int op; /* Reject or commit image */ +}; + +/* Status int must be first member of struct */ +struct rtas_validate_flash_t +{ + int status; /* Returned status */ + char buf[VALIDATE_BUF_SIZE]; /* Candidate image buffer */ + unsigned int buf_size; /* Size of image buf */ + unsigned int update_results; /* Update results token */ +}; + +static spinlock_t flash_file_open_lock = SPIN_LOCK_UNLOCKED; +static struct proc_dir_entry *firmware_flash_pde = NULL; +static struct proc_dir_entry *firmware_update_pde = NULL; +static struct proc_dir_entry *validate_pde = NULL; +static struct proc_dir_entry *manage_pde = NULL; /* Do simple sanity checks on the flash image. */ static int flash_list_valid(struct flash_block_list *flist) @@ -59,32 +119,27 @@ int i; unsigned long block_size, image_size; - flash_msg = NULL; /* Paranoid self test here. We also collect the image size. */ image_size = 0; for (f = flist; f; f = f->next) { for (i = 0; i < f->num_blocks; i++) { if (f->blocks[i].data == NULL) { - flash_msg = "error: internal error null data\n"; - return 0; + return FLASH_IMG_NULL_DATA; } block_size = f->blocks[i].length; if (block_size <= 0 || block_size > PAGE_SIZE) { - flash_msg = "error: internal error bad length\n"; - return 0; + return FLASH_IMG_BAD_LEN; } image_size += block_size; } } - if (image_size < (256 << 10)) { - if (image_size < 2) - flash_msg = NULL; /* allow "clear" of image */ - else - flash_msg = "error: flash image short\n"; - return 0; - } + + if (image_size < 2) + return FLASH_NO_OP; + printk(KERN_INFO "FLASH: flash image with %ld bytes stored for hardware flash on reboot\n", image_size); - return 1; + + return FLASH_IMG_READY; } static void free_flash_list(struct flash_block_list *f) @@ -103,40 +158,80 @@ static int rtas_flash_release(struct inode *inode, struct file *file) { - if (flist) { - /* Always clear saved list on a new attempt. */ + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + struct rtas_update_flash_t *uf; + + uf = (struct rtas_update_flash_t *) dp->data; + if (uf->flist) { + /* File was opened in write mode for a new flash attempt */ + /* Clear saved list */ if (rtas_firmware_flash_list.next) { free_flash_list(rtas_firmware_flash_list.next); rtas_firmware_flash_list.next = NULL; } - if (flash_list_valid(flist)) - rtas_firmware_flash_list.next = flist; + if (uf->status != FLASH_AUTH) + uf->status = flash_list_valid(uf->flist); + + if (uf->status == FLASH_IMG_READY) + rtas_firmware_flash_list.next = uf->flist; else - free_flash_list(flist); - flist = NULL; + free_flash_list(uf->flist); + + uf->flist = NULL; } + + atomic_dec(&dp->count); return 0; } +static void get_flash_status_msg(int status, char *buf) +{ + char *msg; + + switch (status) { + case FLASH_AUTH: + msg = "error: this partition does not have service authority\n"; + break; + case FLASH_NO_OP: + msg = "info: no firmware image for flash\n"; + break; + case FLASH_IMG_SHORT: + msg = "error: flash image short\n"; + break; + case FLASH_IMG_BAD_LEN: + msg = "error: internal error bad length\n"; + break; + case FLASH_IMG_NULL_DATA: + msg = "error: internal error null data\n"; + break; + case FLASH_IMG_READY: + msg = "ready: firmware image ready for flash on reboot\n"; + break; + default: + sprintf(buf, "error: unexpected status value %d\n", status); + return; + } + + strcpy(buf, msg); +} + /* Reading the proc file will show status (not the firmware contents) */ static ssize_t rtas_flash_read(struct file *file, char *buf, size_t count, loff_t *ppos) { + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + struct rtas_update_flash_t *uf; + char msg[RTAS_MSG_MAXLEN]; int error; - char *msg; int msglen; - if (!flash_possible) { - msg = "error: this partition does not have service authority\n"; - } else if (flist) { - msg = "info: this file is busy for write by some process\n"; - } else if (flash_msg) { - msg = flash_msg; /* message from last flash attempt */ - } else if (rtas_firmware_flash_list.next) { - msg = "ready: firmware image ready for flash on reboot\n"; - } else { - msg = "info: no firmware image for flash\n"; + uf = (struct rtas_update_flash_t *) dp->data; + + if (!strcmp(dp->name, FIRMWARE_FLASH_NAME)) { + get_flash_status_msg(uf->status, msg); + } else { /* FIRMWARE_UPDATE_NAME */ + sprintf(msg, "%d\n", uf->status); } msglen = strlen(msg); if (msglen > count) @@ -149,7 +244,8 @@ if (error) return -EINVAL; - copy_to_user(buf, msg, msglen); + if (copy_to_user(buf, msg, msglen)) + return -EFAULT; if (ppos) *ppos = msglen; @@ -164,14 +260,28 @@ static ssize_t rtas_flash_write(struct file *file, const char *buffer, size_t count, loff_t *off) { - size_t len = count; + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + struct rtas_update_flash_t *uf; char *p; int next_free; - struct flash_block_list *fl = flist; + struct flash_block_list *fl; - if (!flash_possible || len == 0) - return len; /* discard data */ + uf = (struct rtas_update_flash_t *) dp->data; + if (uf->status == FLASH_AUTH || count == 0) + return count; /* discard data */ + + /* In the case that the image is not ready for flashing, the memory + * allocated for the block list will be freed upon the release of the + * proc file + */ + if (uf->flist == NULL) { + uf->flist = (struct flash_block_list *) get_free_page(GFP_KERNEL); + if (!uf->flist) + return -ENOMEM; + } + + fl = uf->flist; while (fl->next) fl = fl->next; /* seek to last block_list for append */ next_free = fl->num_blocks; @@ -184,47 +294,392 @@ next_free = 0; } - if (len > PAGE_SIZE) - len = PAGE_SIZE; + if (count > PAGE_SIZE) + count = PAGE_SIZE; p = (char *)get_free_page(GFP_KERNEL); if (!p) return -ENOMEM; - if(copy_from_user(p, buffer, len)) { + + if(copy_from_user(p, buffer, count)) { free_page((unsigned long)p); return -EFAULT; } fl->blocks[next_free].data = p; - fl->blocks[next_free].length = len; + fl->blocks[next_free].length = count; fl->num_blocks++; - return len; + return count; +} + +static int rtas_excl_open(struct inode *inode, struct file *file) +{ + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + + /* Enforce exclusive open with use count of PDE */ + spin_lock(&flash_file_open_lock); + if (atomic_read(&dp->count) > 1) { + spin_unlock(&flash_file_open_lock); + return -EBUSY; + } + + atomic_inc(&dp->count); + spin_unlock(&flash_file_open_lock); + + return 0; +} + +static int rtas_excl_release(struct inode *inode, struct file *file) +{ + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + + atomic_dec(&dp->count); + + return 0; +} + +static void manage_flash(struct rtas_manage_flash_t *args_buf) +{ + unsigned int wait_time; + s32 rc; + + while (1) { + rc = (s32) rtas_call(rtas_token("ibm,manage-flash-image"), 1, + 1, NULL, (long) args_buf->op); + if (rc == RTAS_RC_BUSY) + udelay(1); + else if (rtas_is_extended_busy(rc)) { + wait_time = rtas_extended_busy_delay_time(rc); + udelay(wait_time * 1000); + } else + break; + } + + args_buf->status = rc; +} + +static ssize_t manage_flash_read(struct file *file, char *buf, + size_t count, loff_t *ppos) +{ + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + struct rtas_manage_flash_t *args_buf; + char msg[RTAS_MSG_MAXLEN]; + int msglen; + int error; + + args_buf = (struct rtas_manage_flash_t *) dp->data; + if (args_buf == NULL) + return 0; + + msglen = sprintf(msg, "%d\n", args_buf->status); + if (msglen > count) + msglen = count; + + if (ppos && *ppos != 0) + return 0; /* be cheap */ + + error = verify_area(VERIFY_WRITE, buf, msglen); + if (error) + return -EINVAL; + + if (copy_to_user(buf, msg, msglen)) + return -EFAULT; + + if (ppos) + *ppos = msglen; + return msglen; +} + +static ssize_t manage_flash_write(struct file *file, const char *buf, + size_t count, loff_t *off) +{ + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + struct rtas_manage_flash_t *args_buf; + const char reject_str[] = "0"; + const char commit_str[] = "1"; + char stkbuf[10]; + int op; + + args_buf = (struct rtas_manage_flash_t *) dp->data; + if ((args_buf->status == MANAGE_AUTH) || (count == 0)) + return count; + + op = -1; + if (buf) { + if (count > 9) count = 9; + if (copy_from_user (stkbuf, buf, count)) { + return -EFAULT; + } + if (strncmp(stkbuf, reject_str, strlen(reject_str)) == 0) + op = RTAS_REJECT_TMP_IMG; + else if (strncmp(stkbuf, commit_str, strlen(commit_str)) == 0) + op = RTAS_COMMIT_TMP_IMG; + } + + if (op == -1) /* buf is empty, or contains invalid string */ + return -EINVAL; + + args_buf->op = op; + manage_flash(args_buf); + + return count; +} + +static void validate_flash(struct rtas_validate_flash_t *args_buf) +{ + int token = rtas_token("ibm,validate-flash-image"); + unsigned int wait_time; + long update_results; + s32 rc; + + rc = 0; + while(1) { + spin_lock(&rtas_data_buf_lock); + memcpy(rtas_data_buf, args_buf->buf, VALIDATE_BUF_SIZE); + rc = (s32) rtas_call(token, 2, 2, &update_results, + __pa(rtas_data_buf), args_buf->buf_size); + memcpy(args_buf->buf, rtas_data_buf, VALIDATE_BUF_SIZE); + spin_unlock(&rtas_data_buf_lock); + + if (rc == RTAS_RC_BUSY) + udelay(1); + else if (rtas_is_extended_busy(rc)) { + wait_time = rtas_extended_busy_delay_time(rc); + udelay(wait_time * 1000); + } else + break; + } + + args_buf->status = rc; + args_buf->update_results = (u32) update_results; +} + +static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf, + char *msg) +{ + int n; + + if (args_buf->status >= VALIDATE_TMP_UPDATE) { + n = sprintf(msg, "%d\n", args_buf->update_results); + if ((args_buf->update_results >= VALIDATE_CUR_UNKNOWN) || + (args_buf->update_results == VALIDATE_TMP_UPDATE)) + n += sprintf(msg + n, "%s\n", args_buf->buf); + } else { + n = sprintf(msg, "%d\n", args_buf->status); + } + return n; +} + +static ssize_t validate_flash_read(struct file *file, char *buf, + size_t count, loff_t *ppos) +{ + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + struct rtas_validate_flash_t *args_buf; + char msg[RTAS_MSG_MAXLEN]; + int msglen; + int error; + + args_buf = (struct rtas_validate_flash_t *) dp->data; + + if (ppos && *ppos != 0) + return 0; /* be cheap */ + + msglen = get_validate_flash_msg(args_buf, msg); + if (msglen > count) + msglen = count; + + error = verify_area(VERIFY_WRITE, buf, msglen); + if (error) + return -EINVAL; + + if (copy_to_user(buf, msg, msglen)) + return -EFAULT; + + if (ppos) + *ppos = msglen; + return msglen; +} + +static ssize_t validate_flash_write(struct file *file, const char *buf, + size_t count, loff_t *off) +{ + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + struct rtas_validate_flash_t *args_buf; + int rc; + + args_buf = (struct rtas_validate_flash_t *) dp->data; + + if (dp->data == NULL) { + dp->data = kmalloc(sizeof(struct rtas_validate_flash_t), + GFP_KERNEL); + if (dp->data == NULL) + return -ENOMEM; + } + + /* We are only interested in the first 4K of the + * candidate image */ + if ((*off >= VALIDATE_BUF_SIZE) || + (args_buf->status == VALIDATE_AUTH)) { + *off += count; + return count; + } + + if (*off + count >= VALIDATE_BUF_SIZE) { + count = VALIDATE_BUF_SIZE - *off; + args_buf->status = VALIDATE_READY; + } else { + args_buf->status = VALIDATE_INCOMPLETE; + } + + if (verify_area(VERIFY_READ, buf, count)) { + rc = -EFAULT; + goto done; + } + if (copy_from_user(args_buf->buf + *off, buf, count)) { + rc = -EFAULT; + goto done; + } + + *off += count; + rc = count; +done: + if (rc < 0) { + kfree(dp->data); + dp->data = NULL; + } + return rc; +} + +static int validate_flash_release(struct inode *inode, struct file *file) +{ + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + struct rtas_validate_flash_t *args_buf; + + args_buf = (struct rtas_validate_flash_t *) dp->data; + + if (args_buf->status == VALIDATE_READY) { + args_buf->buf_size = VALIDATE_BUF_SIZE; + validate_flash(args_buf); + } + + atomic_dec(&dp->count); + + return 0; +} + +static inline void remove_flash_pde(struct proc_dir_entry *dp) +{ + if (dp) { + if (dp->data != NULL) + kfree(dp->data); + remove_proc_entry(dp->name, rtas_proc_dir); + } +} + +static inline int initialize_flash_pde_data(const char *rtas_call_name, + size_t buf_size, + struct proc_dir_entry *dp) +{ + int *status; + int token; + + dp->data = kmalloc(buf_size, GFP_KERNEL); + if (dp->data == NULL) { + remove_flash_pde(dp); + return -ENOMEM; + } + + memset(dp->data, 0, buf_size); + + /* This code assumes that the status int is the first member of the + * struct + */ + status = (int *) dp->data; + token = rtas_token(rtas_call_name); + if (token == RTAS_UNKNOWN_SERVICE) + *status = FLASH_AUTH; + else + *status = FLASH_NO_OP; + + return 0; +} + +static inline struct proc_dir_entry * create_flash_pde(const char *filename, + struct file_operations *fops) +{ + struct proc_dir_entry *ent = NULL; + + ent = create_proc_entry(filename, S_IRUSR | S_IWUSR, rtas_proc_dir); + if (ent != NULL) { + ent->nlink = 1; + ent->proc_fops = fops; + ent->owner = THIS_MODULE; + } + + return ent; } static struct file_operations rtas_flash_operations = { read: rtas_flash_read, write: rtas_flash_write, - open: rtas_flash_open, + open: rtas_excl_open, release: rtas_flash_release, }; +static struct file_operations manage_flash_operations = { + read: manage_flash_read, + write: manage_flash_write, + open: rtas_excl_open, + release: rtas_excl_release, +}; + +static struct file_operations validate_flash_operations = { + read: validate_flash_read, + write: validate_flash_write, + open: rtas_excl_open, + release: validate_flash_release, +}; int __init rtas_flash_init(void) { - struct proc_dir_entry *ent = NULL; + int rc; if (!rtas_proc_dir) { printk(KERN_WARNING "rtas proc dir does not already exist"); return -ENOENT; } - if (rtas_token("ibm,update-flash-64-and-reboot") != RTAS_UNKNOWN_SERVICE) - flash_possible = 1; + firmware_flash_pde = create_flash_pde(FIRMWARE_FLASH_NAME, + &rtas_flash_operations); + rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot", + sizeof(struct rtas_update_flash_t), + firmware_flash_pde); + if (rc != 0) + return rc; + + firmware_update_pde = create_flash_pde(FIRMWARE_UPDATE_NAME, + &rtas_flash_operations); + rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot", + sizeof(struct rtas_update_flash_t), + firmware_update_pde); + if (rc != 0) + return rc; + + validate_pde = create_flash_pde(VALIDATE_FLASH_NAME, + &validate_flash_operations); + rc = initialize_flash_pde_data("ibm,validate-flash-image", + sizeof(struct rtas_validate_flash_t), + validate_pde); + if (rc != 0) + return rc; + + manage_pde = create_flash_pde(MANAGE_FLASH_NAME, + &manage_flash_operations); + rc = initialize_flash_pde_data("ibm,manage-flash-image", + sizeof(struct rtas_manage_flash_t), + manage_pde); + if (rc != 0) + return rc; - if ((ent = create_proc_entry(FIRMWARE_FLASH_NAME, S_IRUSR | S_IWUSR, rtas_proc_dir)) != NULL) { - ent->nlink = 1; - ent->proc_fops = &rtas_flash_operations; - ent->owner = THIS_MODULE; - } return 0; } @@ -232,7 +687,10 @@ { if (!rtas_proc_dir) return; - remove_proc_entry(FIRMWARE_FLASH_NAME, rtas_proc_dir); + remove_flash_pde(firmware_flash_pde); + remove_flash_pde(firmware_update_pde); + remove_flash_pde(validate_pde); + remove_flash_pde(manage_pde); } module_init(rtas_flash_init); Index: arch/ppc64/kernel/rtasd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/rtasd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/rtasd.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/rtasd.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -17,11 +17,14 @@ #include #include #include +#include #include #include #include #include +#include +#include #if 0 #define DEBUG(A...) printk(KERN_ERR A) @@ -29,34 +32,181 @@ #define DEBUG(A...) #endif -static spinlock_t rtas_log_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t log_lock = SPIN_LOCK_UNLOCKED; DECLARE_WAIT_QUEUE_HEAD(rtas_log_wait); -#define LOG_NUMBER 64 /* must be a power of two */ -#define LOG_NUMBER_MASK (LOG_NUMBER-1) - static char *rtas_log_buf; static unsigned long rtas_log_start; static unsigned long rtas_log_size; -static int surveillance_requested; +static int surveillance_timeout = -1; static unsigned int rtas_event_scan_rate; static unsigned int rtas_error_log_max; -#define EVENT_SCAN_ALL_EVENTS 0xf0000000 -#define SURVEILLANCE_TOKEN 9000 -#define SURVEILLANCE_TIMEOUT 1 -#define SURVEILLANCE_SCANRATE 1 +static unsigned int rtas_error_log_buffer_max; + +extern struct proc_dir_entry *proc_ppc64_root; +extern struct proc_dir_entry *rtas_proc_dir; +extern spinlock_t proc_ppc64_lock; +extern volatile int no_more_logging; + +volatile int error_log_cnt = 0; /* * 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 * make it big enough. */ -#define RTAS_ERROR_LOG_MAX 1024 static unsigned char logdata[RTAS_ERROR_LOG_MAX]; +/* To see this info, grep RTAS /var/log/messages and each entry + * will be collected together with obvious begin/end. + * There will be a unique identifier on the begin and end lines. + * This will persist across reboots. + * + * format of error logs returned from RTAS: + * bytes (size) : contents + * -------------------------------------------------------- + * 0-7 (8) : rtas_error_log + * 8-47 (40) : extended info + * 48-51 (4) : vendor id + * 52-1023 (vendor specific) : location code and debug data + */ +static void printk_log_rtas(char *buf, int len) +{ + + int i,j,n; + int perline = 16; + char buffer[64]; + char * str = "RTAS event"; + + printk(RTAS_ERR "%d -------- %s begin --------\n", error_log_cnt, str); + + /* + * Print perline bytes on each line, each line will start + * with RTAS and a changing number, so syslogd will + * print lines that are otherwise the same. Separate every + * 4 bytes with a space. + */ + for (i=0; i < len; i++) { + j = i % perline; + if (j == 0) { + memset(buffer, 0, sizeof(buffer)); + n = sprintf(buffer, "RTAS %d:", i/perline); + } + + if ((i % 4) == 0) + n += sprintf(buffer+n, " "); + + n += sprintf(buffer+n, "%02x", (unsigned char)buf[i]); + + if (j == (perline-1)) + printk(KERN_ERR "%s\n", buffer); + } + if ((i % perline) != 0) + printk(KERN_ERR "%s\n", buffer); + + printk(RTAS_ERR "%d -------- %s end ----------\n", error_log_cnt, str); +} + +static int log_rtas_len(char * buf) +{ + int len; + struct rtas_error_log *err; + + /* rtas fixed header */ + len = 8; + err = (struct rtas_error_log *)buf; + if (err->extended_log_length) { + + /* extended header */ + len += err->extended_log_length; + + if (len > RTAS_ERROR_LOG_MAX) + len = RTAS_ERROR_LOG_MAX; + } + return len; +} + +/* + * First write to nvram, if fatal error, that is the only + * place we log the info. The error will be picked up + * on the next reboot by rtasd. If not fatal, run the + * method for the type of error. Currently, only RTAS + * errors have methods implemented, but in the future + * there might be a need to store data in nvram before a + * call to panic(). +*/ +void pSeries_log_error(char *buf, unsigned int err_type, int fatal) +{ + unsigned long offset; + unsigned long s; + int len = 0; + + DEBUG("logging event\n"); + + if (buf == NULL) + return; + + spin_lock_irqsave(&log_lock, s); + + /* get length and increase count */ + switch (err_type & ERR_TYPE_MASK) { + case ERR_TYPE_RTAS_LOG: + len = log_rtas_len(buf); + if (!(err_type & ERR_FLAG_BOOT)) + error_log_cnt++; + break; + case ERR_TYPE_KERNEL_PANIC: + default: + spin_unlock_irqrestore(&log_lock, s); + return; + } + + /* Write error to NVRAM */ + if (!no_more_logging && !(err_type & ERR_FLAG_BOOT)) { + write_error_log_nvram(buf, len, err_type); + } + + /* Check to see if we need to or have stopped logging */ + if (fatal || no_more_logging) { + no_more_logging = 1; + spin_unlock_irqrestore(&log_lock, s); + return; + } + + /* call type specific method for error */ + switch (err_type & ERR_TYPE_MASK) { + case ERR_TYPE_RTAS_LOG: + /* put into syslog and error_log file */ + printk_log_rtas(buf, len); + + offset = rtas_error_log_buffer_max * + ((rtas_log_start+rtas_log_size) & LOG_NUMBER_MASK); + + /* First copy over sequence number */ + memcpy(&rtas_log_buf[offset], &error_log_cnt, sizeof(int)); + + /* Second copy over error log data */ + offset += sizeof(int); + memcpy(&rtas_log_buf[offset], buf, len); + + if (rtas_log_size < LOG_NUMBER) + rtas_log_size += 1; + else + rtas_log_start += 1; + + spin_unlock_irqrestore(&log_lock, s); + wake_up_interruptible(&rtas_log_wait); + break; + case ERR_TYPE_KERNEL_PANIC: + default: + spin_unlock_irqrestore(&log_lock, s); + return; + } + +} static int rtas_log_open(struct inode * inode, struct file * file) { return 0; @@ -67,36 +217,50 @@ return 0; } +/* This will check if all events are logged, if they are then, we + * know that we can safely clear the events in NVRAM. + * Next we'll sit and wait for something else to log. + */ static ssize_t rtas_log_read(struct file * file, char * buf, size_t count, loff_t *ppos) { int error; char *tmp; + unsigned long s; unsigned long offset; - if (!buf || count < rtas_error_log_max) + if (!buf || count < rtas_error_log_buffer_max) return -EINVAL; - count = rtas_error_log_max; + count = rtas_error_log_buffer_max; error = verify_area(VERIFY_WRITE, buf, count); if (error) - return -EINVAL; + return -EFAULT; - tmp = kmalloc(rtas_error_log_max, GFP_KERNEL); + tmp = kmalloc(count, GFP_KERNEL); if (!tmp) return -ENOMEM; + + spin_lock_irqsave(&log_lock, s); + /* if it's 0, then we know we got the last one (the one in NVRAM) */ + if (rtas_log_size == 0 && !no_more_logging) + clear_error_log_nvram(); + spin_unlock_irqrestore(&log_lock, s); + + error = wait_event_interruptible(rtas_log_wait, rtas_log_size); if (error) goto out; - spin_lock(&rtas_log_lock); - offset = rtas_error_log_max * (rtas_log_start & LOG_NUMBER_MASK); + spin_lock_irqsave(&log_lock, s); + offset = rtas_error_log_buffer_max * (rtas_log_start & LOG_NUMBER_MASK); memcpy(tmp, &rtas_log_buf[offset], count); + rtas_log_start += 1; rtas_log_size -= 1; - spin_unlock(&rtas_log_lock); + spin_unlock_irqrestore(&log_lock, s); error = copy_to_user(buf, tmp, count) ? -EFAULT : count; out: @@ -119,607 +283,18 @@ .release = rtas_log_release, }; - -#define RTAS_ERR KERN_ERR "RTAS: " - -/* Extended error log header (12 bytes) */ -struct exthdr { - unsigned int valid:1; - unsigned int unrecoverable:1; - unsigned int recoverable:1; - unsigned int unrecoverable_bypassed:1; /* i.e. degraded performance */ - unsigned int predictive:1; - unsigned int newlog:1; - unsigned int bigendian:1; /* always 1 */ - unsigned int /* reserved */:1; - - unsigned int platform_specific:1; /* only in version 3+ */ - unsigned int /* reserved */:3; - unsigned int platform_value:4; /* valid iff platform_specific */ - - unsigned int power_pc:1; /* always 1 */ - unsigned int /* reserved */:2; - unsigned int addr_invalid:1; /* failing_address is invalid */ - unsigned int format_type:4; -#define EXTLOG_FMT_CPU 1 -#define EXTLOG_FMT_MEMORY 2 -#define EXTLOG_FMT_IO 3 -#define EXTLOG_FMT_POST 4 -#define EXTLOG_FMT_ENV 5 -#define EXTLOG_FMT_POW 6 -#define EXTLOG_FMT_IBMDIAG 12 -#define EXTLOG_FMT_IBMSP 13 - - /* This group is in version 3+ only */ - unsigned int non_hardware:1; /* Firmware or software is suspect */ - unsigned int hot_plug:1; /* Failing component may be hot plugged */ - unsigned int group_failure:1; /* Group of components should be replaced */ - unsigned int /* reserved */:1; - - unsigned int residual:1; /* Residual error from previous boot (maybe a crash) */ - unsigned int boot:1; /* Error during boot */ - unsigned int config_change:1; /* Configuration changed since last boot */ - unsigned int post:1; /* Error during POST */ - - unsigned int bcdtime:32; /* Time of error in BCD HHMMSS00 */ - unsigned int bcddate:32; /* Time of error in BCD YYYYMMDD */ -}; - -struct cpuhdr { - unsigned int internal:1; - unsigned int intcache:1; - unsigned int extcache_parity:1; /* or multi-bit ECC */ - unsigned int extcache_ecc:1; - unsigned int sysbus_timeout:1; - unsigned int io_timeout:1; - unsigned int sysbus_parity:1; - unsigned int sysbus_protocol:1; - unsigned int cpuid:8; - unsigned int element:16; - unsigned int failing_address_hi:32; - unsigned int failing_address_lo:32; - - /* These are version 4+ */ - unsigned int try_reboot:1; /* 1 => fault may be fixed by reboot */ - unsigned int /* reserved */:7; - /* 15 bytes reserved here */ -}; - -struct memhdr { - unsigned int uncorrectable:1; - unsigned int ECC:1; - unsigned int threshold_exceeded:1; - unsigned int control_internal:1; - unsigned int bad_address:1; - unsigned int bad_data:1; - unsigned int bus:1; - unsigned int timeout:1; - unsigned int sysbus_parity:1; - unsigned int sysbus_timeout:1; - unsigned int sysbus_protocol:1; - unsigned int hostbridge_timeout:1; - unsigned int hostbridge_parity:1; - unsigned int reserved1:1; - unsigned int support:1; - unsigned int sysbus_internal:1; - unsigned int mem_controller_detected:8; /* who detected fault? */ - unsigned int mem_controller_faulted:8; /* who caused fault? */ - unsigned int failing_address_hi:32; - unsigned int failing_address_lo:32; - unsigned int ecc_syndrome:16; - unsigned int memory_card:8; - unsigned int reserved2:8; - unsigned int sub_elements:32; /* one bit per element */ - unsigned int element:16; -}; - -struct iohdr { - unsigned int bus_addr_parity:1; - unsigned int bus_data_parity:1; - unsigned int bus_timeout:1; - unsigned int bridge_internal:1; - unsigned int non_pci:1; /* i.e. secondary bus such as ISA */ - unsigned int mezzanine_addr_parity:1; - unsigned int mezzanine_data_parity:1; - unsigned int mezzanine_timeout:1; - - unsigned int bridge_via_sysbus:1; - unsigned int bridge_via_mezzanine:1; - unsigned int bridge_via_expbus:1; - unsigned int detected_by_expbus:1; - unsigned int expbus_data_parity:1; - unsigned int expbus_timeout:1; - unsigned int expbus_connection_failure:1; - unsigned int expbus_not_operating:1; - - /* IOA signalling the error */ - unsigned int pci_sig_busno:8; - unsigned int pci_sig_devfn:8; - unsigned int pci_sig_deviceid:16; - unsigned int pci_sig_vendorid:16; - unsigned int pci_sig_revisionid:8; - unsigned int pci_sig_slot:8; /* 00 => system board, ff => multiple */ - - /* IOA sending at time of error */ - unsigned int pci_send_busno:8; - unsigned int pci_send_devfn:8; - unsigned int pci_send_deviceid:16; - unsigned int pci_send_vendorid:16; - unsigned int pci_send_revisionid:8; - unsigned int pci_send_slot:8; /* 00 => system board, ff => multiple */ -}; - -struct posthdr { - unsigned int firmware:1; - unsigned int config:1; - unsigned int cpu:1; - unsigned int memory:1; - unsigned int io:1; - unsigned int keyboard:1; - unsigned int mouse:1; - unsigned int display:1; - - unsigned int ipl_floppy:1; - unsigned int ipl_controller:1; - unsigned int ipl_cdrom:1; - unsigned int ipl_disk:1; - unsigned int ipl_net:1; - unsigned int ipl_other:1; - unsigned int /* reserved */:1; - unsigned int firmware_selftest:1; - - char devname[12]; - unsigned int post_code:4; - unsigned int firmware_rev:2; - unsigned int loc_code:8; /* currently unused */ -}; - -struct epowhdr { - unsigned int epow_sensor_value:32; - unsigned int sensor:1; - unsigned int power_fault:1; - unsigned int fan:1; - unsigned int temp:1; - unsigned int redundancy:1; - unsigned int CUoD:1; - unsigned int /* reserved */:2; - - unsigned int general:1; - unsigned int power_loss:1; - unsigned int power_supply:1; - unsigned int power_switch:1; - unsigned int /* reserved */:4; - - unsigned int /* reserved */:16; - unsigned int sensor_token:32; - unsigned int sensor_index:32; - unsigned int sensor_value:32; - unsigned int sensor_status:32; -}; - -struct pm_eventhdr { - unsigned int event_id:32; -}; - -struct sphdr { - unsigned int ibm:32; /* "IBM\0" */ - - unsigned int timeout:1; - unsigned int i2c_bus:1; - unsigned int i2c_secondary_bus:1; - unsigned int sp_memory:1; - unsigned int sp_registers:1; - unsigned int sp_communication:1; - unsigned int sp_firmware:1; - unsigned int sp_hardware:1; - - unsigned int vpd_eeprom:1; - unsigned int op_panel:1; - unsigned int power_controller:1; - unsigned int fan_sensor:1; - unsigned int thermal_sensor:1; - unsigned int voltage_sensor:1; - unsigned int reserved1:2; - - unsigned int serial_port:1; - unsigned int nvram:1; - unsigned int rtc:1; - unsigned int jtag:1; - unsigned int tod_battery:1; - unsigned int reserved2:1; - unsigned int heartbeat:1; - unsigned int surveillance:1; - - unsigned int pcn_connection:1; /* power control network */ - unsigned int pcn_node:1; - unsigned int reserved3:2; - unsigned int pcn_access:1; - unsigned int reserved:3; - - unsigned int sensor_token:32; /* zero if undef */ - unsigned int sensor_index:32; /* zero if undef */ -}; - - -static char *severity_names[] = { - "NO ERROR", "EVENT", "WARNING", "ERROR_SYNC", "ERROR", "FATAL", "(6)", "(7)" -}; -static char *rtas_disposition_names[] = { - "FULLY RECOVERED", "LIMITED RECOVERY", "NOT RECOVERED", "(4)" -}; -static char *entity_names[] = { /* for initiator & targets */ - "UNKNOWN", "CPU", "PCI", "ISA", "MEMORY", "POWER MANAGEMENT", "HOT PLUG", "(7)", "(8)", - "(9)", "(10)", "(11)", "(12)", "(13)", "(14)", "(15)" -}; -static char *error_type[] = { /* Not all types covered here so need to bounds check */ - "UNKNOWN", "RETRY", "TCE_ERR", "INTERN_DEV_FAIL", - "TIMEOUT", "DATA_PARITY", "ADDR_PARITY", "CACHE_PARITY", - "ADDR_INVALID", "ECC_UNCORR", "ECC_CORR", -}; - -static char *rtas_error_type(int type) -{ - if (type < 11) - return error_type[type]; - if (type == 64) - return "SENSOR"; - if (type >=96 && type <= 159) - return "POWER"; - return error_type[0]; -} - -static void printk_cpu_failure(int version, struct exthdr *exthdr, char *data) -{ - struct cpuhdr cpuhdr; - - memcpy(&cpuhdr, data, sizeof(cpuhdr)); - - if (cpuhdr.internal) printk(RTAS_ERR "Internal error (not cache)\n"); - if (cpuhdr.intcache) printk(RTAS_ERR "Internal cache\n"); - if (cpuhdr.extcache_parity) printk(RTAS_ERR "External cache parity (or multi-bit)\n"); - if (cpuhdr.extcache_ecc) printk(RTAS_ERR "External cache ECC\n"); - if (cpuhdr.sysbus_timeout) printk(RTAS_ERR "System bus timeout\n"); - if (cpuhdr.io_timeout) printk(RTAS_ERR "I/O timeout\n"); - if (cpuhdr.sysbus_parity) printk(RTAS_ERR "System bus parity\n"); - if (cpuhdr.sysbus_protocol) printk(RTAS_ERR "System bus protocol/transfer\n"); - printk(RTAS_ERR "CPU id: %d\n", cpuhdr.cpuid); - printk(RTAS_ERR "Failing element: 0x%04x\n", cpuhdr.element); - if (!exthdr->addr_invalid) - printk(RTAS_ERR "Failing address: %08x%08x\n", cpuhdr.failing_address_hi, cpuhdr.failing_address_lo); - if (version >= 4 && cpuhdr.try_reboot) - printk(RTAS_ERR "A reboot of the system may correct the problem\n"); -} - -static void printk_mem_failure(int version, struct exthdr *exthdr, char *data) -{ - struct memhdr memhdr; - - memcpy(&memhdr, data, sizeof(memhdr)); - if (memhdr.uncorrectable) printk(RTAS_ERR "Uncorrectable Memory error\n"); - if (memhdr.ECC) printk(RTAS_ERR "ECC Correctable error\n"); - if (memhdr.threshold_exceeded) printk(RTAS_ERR "Correctable threshold exceeded\n"); - if (memhdr.control_internal) printk(RTAS_ERR "Memory Controller internal error\n"); - if (memhdr.bad_address) printk(RTAS_ERR "Memory Address error\n"); - if (memhdr.bad_data) printk(RTAS_ERR "Memory Data error\n"); - if (memhdr.bus) printk(RTAS_ERR "Memory bus/switch internal error\n"); - if (memhdr.timeout) printk(RTAS_ERR "Memory timeout\n"); - if (memhdr.sysbus_parity) printk(RTAS_ERR "System bus parity\n"); - if (memhdr.sysbus_timeout) printk(RTAS_ERR "System bus timeout\n"); - if (memhdr.sysbus_protocol) printk(RTAS_ERR "System bus protocol/transfer\n"); - if (memhdr.hostbridge_timeout) printk(RTAS_ERR "I/O Host Bridge timeout\n"); - if (memhdr.hostbridge_parity) printk(RTAS_ERR "I/O Host Bridge parity\n"); - if (memhdr.support) printk(RTAS_ERR "System support function error\n"); - if (memhdr.sysbus_internal) printk(RTAS_ERR "System bus internal hardware/switch error\n"); - printk(RTAS_ERR "Memory Controller that detected failure: %d\n", memhdr.mem_controller_detected); - printk(RTAS_ERR "Memory Controller that faulted: %d\n", memhdr.mem_controller_faulted); - if (!exthdr->addr_invalid) - printk(RTAS_ERR "Failing address: 0x%016x%016x\n", memhdr.failing_address_hi, memhdr.failing_address_lo); - printk(RTAS_ERR "ECC syndrome bits: 0x%04x\n", memhdr.ecc_syndrome); - printk(RTAS_ERR "Memory Card: %d\n", memhdr.memory_card); - printk(RTAS_ERR "Failing element: 0x%04x\n", memhdr.element); - printk(RTAS_ERR "Sub element bits: 0x%08x\n", memhdr.sub_elements); -} - -static void printk_io_failure(int version, struct exthdr *exthdr, char *data) -{ - struct iohdr iohdr; - - memcpy(&iohdr, data, sizeof(iohdr)); - if (iohdr.bus_addr_parity) printk(RTAS_ERR "I/O bus address parity\n"); - if (iohdr.bus_data_parity) printk(RTAS_ERR "I/O bus data parity\n"); - if (iohdr.bus_timeout) printk(RTAS_ERR "I/O bus timeout, access or other\n"); - if (iohdr.bridge_internal) printk(RTAS_ERR "I/O bus bridge/device internal\n"); - if (iohdr.non_pci) printk(RTAS_ERR "Signaling IOA is a PCI to non-PCI bridge (e.g. ISA)\n"); - if (iohdr.mezzanine_addr_parity) printk(RTAS_ERR "Mezzanine/System bus address parity\n"); - if (iohdr.mezzanine_data_parity) printk(RTAS_ERR "Mezzanine/System bus data parity\n"); - if (iohdr.mezzanine_timeout) printk(RTAS_ERR "Mezzanine/System bus timeout, transfer or protocol\n"); - if (iohdr.bridge_via_sysbus) printk(RTAS_ERR "Bridge is connected to system bus\n"); - if (iohdr.bridge_via_mezzanine) printk(RTAS_ERR "Bridge is connected to memory controller via mezzanine bus\n"); - if (iohdr.bridge_via_expbus) printk(RTAS_ERR "Bridge is connected to I/O expansion bus\n"); - if (iohdr.detected_by_expbus) printk(RTAS_ERR "Error on system bus detected by I/O expansion bus controller\n"); - if (iohdr.expbus_data_parity) printk(RTAS_ERR "I/O expansion bus data error\n"); - if (iohdr.expbus_timeout) printk(RTAS_ERR "I/O expansion bus timeout, access or other\n"); - if (iohdr.expbus_connection_failure) printk(RTAS_ERR "I/O expansion bus connection failure\n"); - if (iohdr.expbus_not_operating) printk(RTAS_ERR "I/O expansion unit not in an operating state (powered off, off-line)\n"); - - printk(RTAS_ERR "IOA Signaling the error: %d:%d.%d vendor:%04x device:%04x rev:%02x slot:%d\n", - iohdr.pci_sig_busno, iohdr.pci_sig_devfn >> 3, iohdr.pci_sig_devfn & 0x7, - iohdr.pci_sig_vendorid, iohdr.pci_sig_deviceid, iohdr.pci_sig_revisionid, iohdr.pci_sig_slot); - printk(RTAS_ERR "IOA Sending during the error: %d:%d.%d vendor:%04x device:%04x rev:%02x slot:%d\n", - iohdr.pci_send_busno, iohdr.pci_send_devfn >> 3, iohdr.pci_send_devfn & 0x7, - iohdr.pci_send_vendorid, iohdr.pci_send_deviceid, iohdr.pci_send_revisionid, iohdr.pci_send_slot); - -} - -static void printk_post_failure(int version, struct exthdr *exthdr, char *data) -{ - struct posthdr posthdr; - - memcpy(&posthdr, data, sizeof(posthdr)); - - if (posthdr.devname[0]) printk(RTAS_ERR "Failing Device: %s\n", posthdr.devname); - if (posthdr.firmware) printk(RTAS_ERR "Firmware Error\n"); - if (posthdr.config) printk(RTAS_ERR "Configuration Error\n"); - if (posthdr.cpu) printk(RTAS_ERR "CPU POST Error\n"); - if (posthdr.memory) printk(RTAS_ERR "Memory POST Error\n"); - if (posthdr.io) printk(RTAS_ERR "I/O Subsystem POST Error\n"); - if (posthdr.keyboard) printk(RTAS_ERR "Keyboard POST Error\n"); - if (posthdr.mouse) printk(RTAS_ERR "Mouse POST Error\n"); - if (posthdr.display) printk(RTAS_ERR "Display POST Error\n"); - - if (posthdr.ipl_floppy) printk(RTAS_ERR "Floppy IPL Error\n"); - if (posthdr.ipl_controller) printk(RTAS_ERR "Drive Controller Error during IPL\n"); - if (posthdr.ipl_cdrom) printk(RTAS_ERR "CDROM IPL Error\n"); - if (posthdr.ipl_disk) printk(RTAS_ERR "Disk IPL Error\n"); - if (posthdr.ipl_net) printk(RTAS_ERR "Network IPL Error\n"); - if (posthdr.ipl_other) printk(RTAS_ERR "Other (tape,flash) IPL Error\n"); - if (posthdr.firmware_selftest) printk(RTAS_ERR "Self-test error in firmware extended diagnostics\n"); - printk(RTAS_ERR "POST Code: %d\n", posthdr.post_code); - printk(RTAS_ERR "Firmware Revision Code: %d\n", posthdr.firmware_rev); -} - -static void printk_epow_warning(int version, struct exthdr *exthdr, char *data) -{ - struct epowhdr epowhdr; - - memcpy(&epowhdr, data, sizeof(epowhdr)); - printk(RTAS_ERR "EPOW Sensor Value: 0x%08x\n", epowhdr.epow_sensor_value); - if (epowhdr.sensor) { - printk(RTAS_ERR "EPOW detected by a sensor\n"); - printk(RTAS_ERR "Sensor Token: 0x%08x\n", epowhdr.sensor_token); - printk(RTAS_ERR "Sensor Index: 0x%08x\n", epowhdr.sensor_index); - printk(RTAS_ERR "Sensor Value: 0x%08x\n", epowhdr.sensor_value); - printk(RTAS_ERR "Sensor Status: 0x%08x\n", epowhdr.sensor_status); - } - if (epowhdr.power_fault) printk(RTAS_ERR "EPOW caused by a power fault\n"); - if (epowhdr.fan) printk(RTAS_ERR "EPOW caused by fan failure\n"); - if (epowhdr.temp) printk(RTAS_ERR "EPOW caused by over-temperature condition\n"); - if (epowhdr.redundancy) printk(RTAS_ERR "EPOW warning due to loss of redundancy\n"); - if (epowhdr.CUoD) printk(RTAS_ERR "EPOW warning due to CUoD Entitlement Exceeded\n"); - - if (epowhdr.general) printk(RTAS_ERR "EPOW general power fault\n"); - if (epowhdr.power_loss) printk(RTAS_ERR "EPOW power fault due to loss of power source\n"); - if (epowhdr.power_supply) printk(RTAS_ERR "EPOW power fault due to internal power supply failure\n"); - if (epowhdr.power_switch) printk(RTAS_ERR "EPOW power fault due to activation of power switch\n"); -} - -static void printk_pm_event(int version, struct exthdr *exthdr, char *data) -{ - struct pm_eventhdr pm_eventhdr; - - memcpy(&pm_eventhdr, data, sizeof(pm_eventhdr)); - printk(RTAS_ERR "Event id: 0x%08x\n", pm_eventhdr.event_id); -} - -static void printk_sp_log_msg(int version, struct exthdr *exthdr, char *data) -{ - struct sphdr sphdr; - u32 eyecatcher; - - memcpy(&sphdr, data, sizeof(sphdr)); - - eyecatcher = sphdr.ibm; - if (strcmp((char *)&eyecatcher, "IBM") != 0) - printk(RTAS_ERR "This log entry may be corrupt (IBM signature malformed)\n"); - if (sphdr.timeout) printk(RTAS_ERR "Timeout on communication response from service processor\n"); - if (sphdr.i2c_bus) printk(RTAS_ERR "I2C general bus error\n"); - if (sphdr.i2c_secondary_bus) printk(RTAS_ERR "I2C secondary bus error\n"); - if (sphdr.sp_memory) printk(RTAS_ERR "Internal service processor memory error\n"); - if (sphdr.sp_registers) printk(RTAS_ERR "Service processor error accessing special registers\n"); - if (sphdr.sp_communication) printk(RTAS_ERR "Service processor reports unknown communcation error\n"); - if (sphdr.sp_firmware) printk(RTAS_ERR "Internal service processor firmware error\n"); - if (sphdr.sp_hardware) printk(RTAS_ERR "Other internal service processor hardware error\n"); - if (sphdr.vpd_eeprom) printk(RTAS_ERR "Service processor error accessing VPD EEPROM\n"); - if (sphdr.op_panel) printk(RTAS_ERR "Service processor error accessing Operator Panel\n"); - if (sphdr.power_controller) printk(RTAS_ERR "Service processor error accessing Power Controller\n"); - if (sphdr.fan_sensor) printk(RTAS_ERR "Service processor error accessing Fan Sensor\n"); - if (sphdr.thermal_sensor) printk(RTAS_ERR "Service processor error accessing Thermal Sensor\n"); - if (sphdr.voltage_sensor) printk(RTAS_ERR "Service processor error accessing Voltage Sensor\n"); - if (sphdr.serial_port) printk(RTAS_ERR "Service processor error accessing serial port\n"); - if (sphdr.nvram) printk(RTAS_ERR "Service processor detected NVRAM error\n"); - if (sphdr.rtc) printk(RTAS_ERR "Service processor error accessing real time clock\n"); - if (sphdr.jtag) printk(RTAS_ERR "Service processor error accessing JTAG/COP\n"); - if (sphdr.tod_battery) printk(RTAS_ERR "Service processor or RTAS detects loss of voltage from TOD battery\n"); - if (sphdr.heartbeat) printk(RTAS_ERR "Loss of heartbeat from Service processor\n"); - if (sphdr.surveillance) printk(RTAS_ERR "Service processor detected a surveillance timeout\n"); - if (sphdr.pcn_connection) printk(RTAS_ERR "Power Control Network general connection failure\n"); - if (sphdr.pcn_node) printk(RTAS_ERR "Power Control Network node failure\n"); - if (sphdr.pcn_access) printk(RTAS_ERR "Service processor error accessing Power Control Network\n"); - - if (sphdr.sensor_token) printk(RTAS_ERR "Sensor Token 0x%08x (%d)\n", sphdr.sensor_token, sphdr.sensor_token); - if (sphdr.sensor_index) printk(RTAS_ERR "Sensor Index 0x%08x (%d)\n", sphdr.sensor_index, sphdr.sensor_index); -} - - -static void printk_ext_raw_data(char *data) -{ - int i; - printk(RTAS_ERR "raw ext data: "); - for (i = 0; i < 40; i++) { - printk("%02x", data[i]); - } - printk("\n"); -} - -static void printk_ext_log_data(int version, char *buf) -{ - char *data = buf+12; - struct exthdr exthdr; - memcpy(&exthdr, buf, sizeof(exthdr)); /* copy for alignment */ - if (!exthdr.valid) { - if (exthdr.bigendian && exthdr.power_pc) - printk(RTAS_ERR "extended log data is not valid\n"); - else - printk(RTAS_ERR "extended log data can not be decoded\n"); - return; - } - - /* Dump useful stuff in the exthdr */ - printk(RTAS_ERR "Status:%s%s%s%s%s\n", - exthdr.unrecoverable ? " unrecoverable" : "", - exthdr.recoverable ? " recoverable" : "", - exthdr.unrecoverable_bypassed ? " bypassed" : "", - exthdr.predictive ? " predictive" : "", - exthdr.newlog ? " new" : ""); - printk(RTAS_ERR "Date/Time: %08x %08x\n", exthdr.bcddate, exthdr.bcdtime); - switch (exthdr.format_type) { - case EXTLOG_FMT_CPU: - printk(RTAS_ERR "CPU Failure\n"); - printk_cpu_failure(version, &exthdr, data); - break; - case EXTLOG_FMT_MEMORY: - printk(RTAS_ERR "Memory Failure\n"); - printk_mem_failure(version, &exthdr, data); - break; - case EXTLOG_FMT_IO: - printk(RTAS_ERR "I/O Failure\n"); - printk_io_failure(version, &exthdr, data); - break; - case EXTLOG_FMT_POST: - printk(RTAS_ERR "POST Failure\n"); - printk_post_failure(version, &exthdr, data); - break; - case EXTLOG_FMT_ENV: - printk(RTAS_ERR "Environment and Power Warning\n"); - printk_epow_warning(version, &exthdr, data); - break; - case EXTLOG_FMT_POW: - printk(RTAS_ERR "Power Management Event\n"); - printk_pm_event(version, &exthdr, data); - break; - case EXTLOG_FMT_IBMDIAG: - printk(RTAS_ERR "IBM Diagnostic Log\n"); - printk_ext_raw_data(data); - break; - case EXTLOG_FMT_IBMSP: - printk(RTAS_ERR "IBM Service Processor Log\n"); - printk_sp_log_msg(version, &exthdr, data); - break; - default: - printk(RTAS_ERR "Unknown ext format type %d\n", exthdr.format_type); - printk_ext_raw_data(data); - break; - } -} - -#define MAX_LOG_DEBUG 10 -#define MAX_LOG_DEBUG_LEN 900 -/* Print log debug data. This appears after the location code. - * We limit the number of debug logs in case the data is somehow corrupt. - */ -static void printk_log_debug(char *buf) -{ - unsigned char *p = (unsigned char *)_ALIGN((unsigned long)buf, 4); - int len, n, logged; - - logged = 0; - while ((logged < MAX_LOG_DEBUG) && (len = ((p[0] << 8) | p[1])) >= 4) { - if (len > MAX_LOG_DEBUG_LEN) - len = MAX_LOG_DEBUG_LEN; /* bound it */ - printk("RTAS: Log Debug: %c%c ", p[2], p[3]); - for (n=4; n < len; n++) - printk("%02x", p[n]); - printk("\n"); - p = (unsigned char *)_ALIGN((unsigned long)p+len, 4); - logged++; - if (len == MAX_LOG_DEBUG_LEN) - return; /* no point continuing */ - } - if (logged == 0) - printk("RTAS: no log debug data present\n"); -} - - -/* Yeah, the output here is ugly, but we want a CE to be - * able to grep RTAS /var/log/messages and see all the info - * collected together with obvious begin/end. - */ -static void printk_log_rtas(char *buf) -{ - struct rtas_error_log *err = (struct rtas_error_log *)buf; - - printk(RTAS_ERR "-------- event-scan begin --------\n"); - if (strcmp(buf+8+40, "IBM") == 0) { - /* Location code follows */ - char *loc = buf+8+40+4; - int len = strlen(loc); - if (len < 64) { /* Sanity check */ - printk(RTAS_ERR "Location Code: %s\n", loc); - printk_log_debug(loc+len+1); - } - } - - printk(RTAS_ERR "%s: (%s) type: %s\n", - severity_names[err->severity], - rtas_disposition_names[err->disposition], - rtas_error_type(err->type)); - printk(RTAS_ERR "initiator: %s target: %s\n", - entity_names[err->initiator], entity_names[err->target]); - if (err->extended_log_length) - printk_ext_log_data(err->version, buf+8); - printk(RTAS_ERR "-------- event-scan end ----------\n"); -} - - -static void log_rtas(char *buf) -{ - unsigned long offset; - - DEBUG("logging rtas event\n"); - - /* Temporary -- perhaps we can do this when nobody has the log open? */ - printk_log_rtas(buf); - - spin_lock(&rtas_log_lock); - - offset = rtas_error_log_max * - ((rtas_log_start+rtas_log_size) & LOG_NUMBER_MASK); - - memcpy(&rtas_log_buf[offset], buf, rtas_error_log_max); - - if (rtas_log_size < LOG_NUMBER) - rtas_log_size += 1; - else - rtas_log_start += 1; - - spin_unlock(&rtas_log_lock); - wake_up_interruptible(&rtas_log_wait); -} - -static int enable_surveillance(void) +static int enable_surveillance(int timeout) { int error; error = rtas_call(rtas_token("set-indicator"), 3, 1, NULL, SURVEILLANCE_TOKEN, - 0, SURVEILLANCE_TIMEOUT); + 0, timeout); if (error) { printk(KERN_ERR "rtasd: could not enable surveillance\n"); return -1; } - rtas_event_scan_rate = SURVEILLANCE_SCANRATE; - return 0; } @@ -751,6 +326,9 @@ rtas_error_log_max = RTAS_ERROR_LOG_MAX; } + /* Make room for the sequence number */ + rtas_error_log_buffer_max = rtas_error_log_max + sizeof(int); + return 0; } @@ -758,20 +336,25 @@ static int rtasd(void *unused) { + unsigned int err_type; + unsigned long s; int cpu = 0; int error; int first_pass = 1; int event_scan = rtas_token("event-scan"); + int rc; if (event_scan == RTAS_UNKNOWN_SERVICE || get_eventscan_parms() == -1) goto error; - rtas_log_buf = vmalloc(rtas_error_log_max*LOG_NUMBER); + rtas_log_buf = vmalloc(rtas_error_log_buffer_max*LOG_NUMBER); if (!rtas_log_buf) { printk(KERN_ERR "rtasd: no memory\n"); goto error; } + no_more_logging = 0; + DEBUG("will sleep for %d jiffies\n", (HZ*60/rtas_event_scan_rate) / 2); daemonize(); @@ -786,11 +369,23 @@ current->cpus_allowed = 1UL << cpu_logical_map(cpu); schedule(); + /* See if we have any error stored in NVRAM */ + memset(logdata, 0, rtas_error_log_max); + + rc = read_error_log_nvram(logdata, rtas_error_log_max, &err_type); + if (!rc) { + if (err_type != ERR_FLAG_ALREADY_LOGGED) { + pSeries_log_error(logdata, err_type | ERR_FLAG_BOOT, 0); + } + } + while(1) { + + do { memset(logdata, 0, rtas_error_log_max); error = rtas_call(event_scan, 4, 1, NULL, - EVENT_SCAN_ALL_EVENTS, 0, + RTAS_EVENT_SCAN_ALL_EVENTS, 0, __pa(logdata), rtas_error_log_max); if (error == -1) { printk(KERN_ERR "event-scan failed\n"); @@ -798,7 +393,7 @@ } if (error == 0) - log_rtas(logdata); + pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, 0); } while(error == 0); @@ -807,9 +402,9 @@ cpu++; if (cpu >= smp_num_cpus) { - if (first_pass && surveillance_requested) { + if (first_pass && (surveillance_timeout != -1)) { DEBUG("enabling surveillance\n"); - if (enable_surveillance()) + if (enable_surveillance(surveillance_timeout)) goto error_vfree; DEBUG("surveillance enabled\n"); } @@ -821,12 +416,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 +427,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) @@ -862,8 +473,8 @@ int i; if (get_option(&str,&i)) { - if (i == 1) - surveillance_requested = 1; + if (i >= 0 && i <= 255) + surveillance_timeout = i; } return 1; Index: arch/ppc64/kernel/rtc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/rtc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/rtc.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/rtc.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -96,6 +97,7 @@ switch (cmd) { case RTC_RD_TIME: /* Read the time/date from RTC */ { + memset(&wtime, 0, sizeof(struct rtc_time)); ppc_md.get_rtc_time(&wtime); break; } @@ -272,20 +274,63 @@ } +#define MAX_RTC_WAIT 5000 /* 5 sec */ +#define RTAS_CLOCK_BUSY (-2) +void pSeries_get_boot_time(struct rtc_time *rtc_tm) +{ + unsigned long ret[8]; + int error, wait_time; + unsigned long max_wait_tb; + + max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; + do { + error = rtas_call(rtas_token("get-time-of-day"), 0, 8, (void *)&ret); + if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { + wait_time = rtas_extended_busy_delay_time(error); + /* This is boot time so we spin. */ + udelay(wait_time*1000); + error = RTAS_CLOCK_BUSY; + } + } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb)); + + if (error != 0) { + printk(KERN_WARNING "error: reading the clock failed (%d)\n", + error); + return; + } + + rtc_tm->tm_sec = ret[5]; + rtc_tm->tm_min = ret[4]; + rtc_tm->tm_hour = ret[3]; + rtc_tm->tm_mday = ret[2]; + rtc_tm->tm_mon = ret[1] - 1; + rtc_tm->tm_year = ret[0] - 1900; +} + +/* NOTE: get_rtc_time will get an error if executed in interrupt context + * and if a delay is needed to read the clock. In this case we just + * silently return without updating rtc_tm. + */ void pSeries_get_rtc_time(struct rtc_time *rtc_tm) { unsigned long ret[8]; - int error; - int count; + int error, wait_time; + unsigned long max_wait_tb; - /* - * error -2 is clock busy, we keep retrying a few times to see - * if it will come good -- paulus - */ - count = 0; + max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; do { error = rtas_call(rtas_token("get-time-of-day"), 0, 8, (void *)&ret); - } while (error == -2 && ++count < 1000); + if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { + if (in_interrupt()) { + printk(KERN_WARNING "error: reading clock would delay interrupt\n"); + return; /* delay not allowed */ + } + wait_time = rtas_extended_busy_delay_time(error); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(wait_time); + error = RTAS_CLOCK_BUSY; + } + } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb)); if (error != 0) { printk(KERN_WARNING "error: reading the clock failed (%d)\n", @@ -303,20 +348,24 @@ int pSeries_set_rtc_time(struct rtc_time *tm) { - int error; - int count; + int error, wait_time; + unsigned long max_wait_tb; - /* - * error -2 is clock busy, we keep retrying a few times to see - * if it will come good -- paulus - */ - count = 0; + max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; do { error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL, tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, 0); - } while (error == -2 && ++count < 1000); + if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { + if (in_interrupt()) + return 1; /* probably decrementer */ + wait_time = rtas_extended_busy_delay_time(error); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(wait_time); + error = RTAS_CLOCK_BUSY; + } + } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb)); if (error != 0) printk(KERN_WARNING "error: setting the clock failed (%d)\n", Index: arch/ppc64/kernel/scanlog.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/scanlog.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/scanlog.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/scanlog.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -129,17 +129,25 @@ static ssize_t scanlog_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { + char stkbuf[20]; unsigned long status; + if (count > 19) + count = 19; + if (copy_from_user (stkbuf, buf, count)) + return -EFAULT; + + stkbuf[count] = 0; + if (buf) { - if (strncmp(buf, "reset", 5) == 0) { + if (strncmp(stkbuf, "reset", 5) == 0) { DEBUG("reset scanlog\n"); status = rtas_call(ibm_scan_log_dump, 2, 1, NULL, NULL, 0); DEBUG("rtas returns %ld\n", status); - } else if (strncmp(buf, "debugon", 7) == 0) { + } else if (strncmp(stkbuf, "debugon", 7) == 0) { printk(KERN_ERR "scanlog: debug on\n"); scanlog_debug = 1; - } else if (strncmp(buf, "debugoff", 8) == 0) { + } else if (strncmp(stkbuf, "debugoff", 8) == 0) { printk(KERN_ERR "scanlog: debug off\n"); scanlog_debug = 0; } Index: arch/ppc64/kernel/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/setup.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/setup.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -37,9 +37,7 @@ #include #include #include -#ifdef CONFIG_KDB -#include -#endif +#include extern unsigned long klimit; /* extern void *stab; */ @@ -64,6 +62,7 @@ extern void pSeries_init_early( void ); extern void pSeriesLP_init_early(void); extern void mm_init_ppc64( void ); +extern void pseries_secondary_smp_init(unsigned long); unsigned long decr_overclock = 1; unsigned long decr_overclock_proc0 = 1; @@ -74,10 +73,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,12 +102,14 @@ }; /* - * 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, unsigned long r6, unsigned long r7) { + unsigned int ret, i; + /* This should be fixed properly in kernel/resource.c */ iomem_resource.end = MEM_SPACE_LIMIT; @@ -149,12 +146,27 @@ udbg_printf("---- start early boot console ----\n"); } - printk("Starting Linux PPC64 %s\n", UTS_RELEASE); + if (systemcfg->platform & PLATFORM_PSERIES) { + finish_device_tree(); + chrp_init(r3, r4, r5, r6, r7); + + /* Start secondary threads on SMT systems */ + for (i = 0; i < NR_CPUS; i++) { + if(cpu_available(i) && !cpu_possible(i)) { + printk("%16.16lx : starting thread\n", i); + rtas_call(rtas_token("start-cpu"), 3, 1, + (void *)&ret, + i, *((unsigned long *)pseries_secondary_smp_init), i); + paca[i].active = 1; + systemcfg->processorCount++; + } + } + } printk("-----------------------------------------------------\n"); printk("naca = 0x%p\n", naca); printk("naca->pftSize = 0x%lx\n", naca->pftSize); - printk("naca->paca = 0x%lx\n\n", naca->paca); + printk("naca->paca = 0x%p\n\n", naca->paca); printk("systemcfg = 0x%p\n", systemcfg); printk("systemcfg->platform = 0x%x\n", systemcfg->platform); printk("systemcfg->processor = 0x%x\n", systemcfg->processor); @@ -166,13 +178,16 @@ printk("htab_data.num_ptegs = 0x%lx\n", htab_data.htab_num_ptegs); printk("-----------------------------------------------------\n"); - if (systemcfg->platform & PLATFORM_PSERIES) { - finish_device_tree(); - chrp_init(r3, r4, r5, r6, r7); - } + printk("Starting Linux PPC64 %s\n", UTS_RELEASE); mm_init_ppc64(); + if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { + vpa_init(0); + } + + idle_setup(); + switch (systemcfg->platform) { case PLATFORM_ISERIES_LPAR: iSeries_init(); @@ -187,6 +202,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,35 +260,13 @@ pvr = paca[cpu_id].pvr; - switch (PVR_VER(pvr)) { - case PV_NORTHSTAR: - seq_printf(m, "RS64-II (northstar)\n"); - break; - case PV_PULSAR: - seq_printf(m, "RS64-III (pulsar)\n"); - break; - case PV_POWER4: - seq_printf(m, "POWER4 (gp)\n"); - break; - case PV_ICESTAR: - seq_printf(m, "RS64-III (icestar)\n"); - break; - case PV_SSTAR: - seq_printf(m, "RS64-IV (sstar)\n"); - break; - case PV_630: - seq_printf(m, "POWER3 (630)\n"); - break; - case PV_630p: - seq_printf(m, "POWER3 (630+)\n"); - break; - case PV_POWER4p: - seq_printf(m, "POWER4+ (gq)\n"); - break; - default: - seq_printf(m, "Unknown (%08x)\n", pvr); - break; - } + 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"); /* * Assume here that all clock rates are the same in a @@ -333,6 +327,7 @@ initrd_end = initrd_start + r4; ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); initrd_below_start_ok = 1; + lmb_reserve(__pa(initrd_start),r4); } #endif @@ -361,8 +356,11 @@ val = "hvc0"; } if (val) { - i = strlen(cmd_line); - sprintf(cmd_line + i, " AUTOCONSOLE console=%s", val); + char tmp_cmd_line[512]; + snprintf(tmp_cmd_line, 512, + "AUTOCONSOLE console=%s %s", + val, cmd_line); + memcpy(cmd_line, tmp_cmd_line, 512); printk("console= not found, add console=%s\ncmd_line is now %s\n", val, cmd_line); } @@ -393,7 +391,7 @@ } } - +#if 0 char *bi_tag2str(unsigned long tag) { switch (tag) { @@ -415,6 +413,7 @@ return "BI_UNKNOWN"; } } +#endif int parse_bootinfo(void) { @@ -495,12 +494,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 +553,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); } @@ -605,20 +598,35 @@ udbg_puts(" "); udbg_puthex(srr1); udbg_puts("\n"); } -int set_spread_lpevents( char * str ) +void do_spread_lpevents(unsigned long n) { - /* The parameter is the number of processors to share in processing lp events */ - unsigned long i; - unsigned long val = simple_strtoul( str, NULL, 0 ); - if ( ( val > 0 ) && ( val <= MAX_PACAS ) ) { - for ( i=1; i 0) && (val <= MAX_PACAS)) { + do_spread_lpevents(val); + } else printk("invalid spreaqd_lpevents %ld\n", val); + return 1; -} +} /* This should only be called on processor 0 during calibrate decr */ void setup_default_decr(void) Index: arch/ppc64/kernel/signal.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/signal.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/signal.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/signal.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -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); @@ -295,7 +296,9 @@ newsp = (current->sas_ss_sp + current->sas_ss_size); } - return (void *)((newsp - frame_size) & -8ul); + /* The ABI requires quadword alignment for the stack. */ + return (void *)((newsp - frame_size) & -16ul); + } static int Index: arch/ppc64/kernel/signal32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/signal32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/signal32.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/signal32.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -761,7 +761,7 @@ memset (d, 0, sizeof(siginfo_t32)); d->si_signo = s->si_signo; d->si_errno = s->si_errno; - d->si_code = s->si_code & 0xffff; + d->si_code = (short)s->si_code; if (s->si_signo >= SIGRTMIN) { d->si_pid = s->si_pid; d->si_uid = s->si_uid; @@ -1067,7 +1067,8 @@ if (ka->sa.sa_flags & SA_SIGINFO) { siginfo64to32(&siginfo32bit,info); - *newspp -= sizeof(*rt_stack_frame); + /* The ABI requires quadword alignment for the stack. */ + *newspp = (*newspp - sizeof(*rt_stack_frame)) & -16ul; rt_stack_frame = (struct rt_sigframe_32 *) (u64)(*newspp) ; if (verify_area(VERIFY_WRITE, rt_stack_frame, sizeof(*rt_stack_frame))) @@ -1095,7 +1096,7 @@ } } else { /* Put a sigcontext on the stack */ - *newspp -= sizeof(*sc); + *newspp = (*newspp - sizeof(*sc)) & -16ul; sc = (struct sigcontext32 *)(u64)*newspp; if (verify_area(VERIFY_WRITE, sc, sizeof(*sc))) goto badframe; @@ -1310,7 +1311,8 @@ newsp = (current->sas_ss_sp + current->sas_ss_size); else newsp = regs->gpr[1]; - newsp = frame = newsp - sizeof(struct sigregs32); + /* The ABI requires quadword alignment for the stack. */ + newsp = frame = (newsp - sizeof(struct sigregs32)) & -16ul; /* Whee! Actually deliver the signal. */ handle_signal32(signr, ka, &info, oldset, regs, &newsp, frame); Index: arch/ppc64/kernel/smp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/smp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/smp.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/kernel/smp.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -28,7 +28,7 @@ #define __KERNEL_SYSCALLS__ #include #include -/* #include */ +#include #include #include @@ -52,9 +52,10 @@ #include #include "open_pic.h" #include +#include #if defined(CONFIG_DUMP) || defined(CONFIG_DUMP_MODULE) int (*dump_ipi_function_ptr)(struct pt_regs *); -#include +#include #endif #ifdef CONFIG_KDB @@ -90,6 +91,9 @@ void xics_setup_cpu(void); void xics_cause_IPI(int cpu); +long h_register_vpa(unsigned long flags, unsigned long proc, + unsigned long vpa); + /* * XICS only has a single IPI, so encode the messages per CPU */ @@ -434,8 +438,17 @@ void smp_send_reschedule(int cpu) { + if ((systemcfg->platform & PLATFORM_LPAR) && + (paca[cpu].yielded == 1)) { +#ifdef CONFIG_PPC_ISERIES + HvCall_sendLpProd(cpu); +#else + prod_processor(cpu); +#endif + } else { smp_message_pass(cpu, PPC_MSG_RESCHEDULE, 0, 0); } +} #ifdef CONFIG_XMON void smp_send_xmon_break(int cpu) @@ -564,6 +577,7 @@ ret = 0; out: + call_data = NULL; HMT_medium(); spin_unlock_bh(&call_lock); return ret; @@ -571,9 +585,20 @@ void smp_call_function_interrupt(void) { - void (*func) (void *info) = call_data->func; - void *info = call_data->info; - int wait = call_data->wait; + void (*func) (void *info); + void *info; + int wait; + + + /* call_data will be NULL if the sender timed out while + * waiting on us to receive the call. + */ + if (!call_data) + return; + + func = call_data->func; + info = call_data->info; + wait = call_data->wait; /* * Notify initiating CPU that I've grabbed the data and am @@ -773,6 +798,12 @@ current->active_mm = &init_mm; smp_callin(); + get_paca()->yielded = 0; + + if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { + vpa_init(cpu); + } + /* Go into the idle loop. */ return cpu_idle(NULL); } Index: arch/ppc64/kernel/stab.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/stab.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/stab.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/stab.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -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" ); @@ -149,7 +159,6 @@ inline void make_slbe(unsigned long esid, unsigned long vsid, int large) { unsigned long entry, castout_entry; - slb_dword0 castout_esid_data; union { unsigned long word0; slb_dword0 data; @@ -158,6 +167,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 +189,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; @@ -198,29 +216,43 @@ PMC_SW_PROCESSOR(stab_capacity_castouts); + /* + * Never cast out the segment for our own stack. Since we + * dont invalidate the ERAT we could have a valid translation + * for our stack during the first part of exception exit + * which gets invalidated due to a tlbie from another cpu at a + * non recoverable point (after setting srr0/1) - Anton + */ + castout_entry = get_paca()->xStab_data.next_round_robin; - __asm__ __volatile__("slbmfee %0,%1" - : "=r" (castout_esid_data) - : "r" (castout_entry)); - - entry = castout_entry; - castout_entry++; - if(castout_entry >= naca->slb_size) { - castout_entry = 1; - } + do { + entry = castout_entry; + castout_entry++; + if (castout_entry >= naca->slb_size) + castout_entry = 1; + asm volatile("slbmfee %0,%1" : "=r" (esid_data) : "r" (entry)); + } while (esid_data.data.esid == GET_ESID((unsigned long)_get_SP())); + get_paca()->xStab_data.next_round_robin = castout_entry; - /* Invalidate the old entry. */ - castout_esid_data.v = 0; /* Set the class to 0 */ - /* slbie not needed as the previous mapping is still valid. */ - __asm__ __volatile__("slbie %0" : : "r" (castout_esid_data)); - + /* We're executing this code on the interrupt stack, so the + * above code might pick the kernel stack segment as the victim. + * + * Because of this, we need to invalidate the old entry. We need + * to do this since it'll otherwise be in the ERAT and might come + * back and haunt us if it get's thrown out of there at the wrong + * time (i.e. similar to throwing out our own stack above). + */ + + esid_data.data.v = 0; + __asm__ __volatile__("slbie %0" : : "r" (esid_data)); + /* * Write the new SLB entry. */ 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 +296,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 +346,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 +379,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 +397,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); } } Index: arch/ppc64/kernel/sys_ppc32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/sys_ppc32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/sys_ppc32.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/sys_ppc32.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -103,11 +104,37 @@ return ret; } +asmlinkage int sys32_ustat(__kernel_dev_t32 dev, struct ustat32 * ubuf) +{ + + struct super_block *s; + struct ustat32 tmp; + struct statfs sbuf; + int err = -EINVAL; + + s = get_super(to_kdev_t(dev)); + if (s == NULL) + goto out; + err = vfs_statfs(s, &sbuf); + drop_super(s); + if (err) + goto out; + + memset(&tmp,0,sizeof(struct ustat)); + tmp.f_tfree = sbuf.f_bfree; + tmp.f_tinode = sbuf.f_ffree; + + err = copy_to_user(ubuf, &tmp, sizeof(struct ustat32)) ? -EFAULT : 0; +out: + return err; + +} struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; }; typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *); +typedef __kernel_ssize_t32 ssize_t32; static long do_readv_writev32(int type, struct file *file, const struct iovec32 *vector, u32 count) @@ -148,6 +175,11 @@ ivp->iov_len = (__kernel_size_t) len; vector++; ivp++; + if ((len < 0) || (tot_len != (ssize_t32)tot_len)) { + if (iov != iovstack) + kfree(iov); + return -EINVAL; + } i--; } @@ -454,7 +486,7 @@ return err; } -struct dqblk32 { +struct user_dqblk32 { __u32 dqb_bhardlimit; __u32 dqb_bsoftlimit; __u32 dqb_curblocks; @@ -466,20 +498,20 @@ }; -extern asmlinkage long sys_quotactl(int cmd, const char *special, int id, caddr_t addr); +extern asmlinkage long sys_quotactl(unsigned int cmd, const char *special, qid_t id, caddr_t addr); /* Note: it is necessary to treat cmd and id as unsigned ints, * with the corresponding cast to a signed int to insure that the * 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 cmds = cmd >> SUBCMDSHIFT; + unsigned int cmd = cmd_parm; + qid_t id = (qid_t)id_parm; + unsigned int cmds = cmd >> SUBCMDSHIFT; int err; - struct dqblk d; + struct v1c_mem_dqblk d; mm_segment_t old_fs; char *spec; @@ -487,35 +519,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; } @@ -996,19 +1026,21 @@ static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf) { - int err; - - err = put_user (kbuf->f_type, &ubuf->f_type); - err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize); - err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks); - err |= __put_user (kbuf->f_bfree, &ubuf->f_bfree); - err |= __put_user (kbuf->f_bavail, &ubuf->f_bavail); - err |= __put_user (kbuf->f_files, &ubuf->f_files); - err |= __put_user (kbuf->f_ffree, &ubuf->f_ffree); - err |= __put_user (kbuf->f_namelen, &ubuf->f_namelen); - err |= __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]); - err |= __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]); - return err; + struct statfs32 tmp; + memset(&tmp, 0, sizeof(tmp)); + + tmp.f_type = kbuf->f_type; + tmp.f_bsize = kbuf->f_bsize; + tmp.f_blocks = kbuf->f_blocks; + tmp.f_bfree = kbuf->f_bfree; + tmp.f_bavail = kbuf->f_bavail; + tmp.f_files = kbuf->f_files; + tmp.f_ffree = kbuf->f_ffree; + tmp.f_namelen = kbuf->f_namelen; + tmp.f_fsid.val[0] = kbuf->f_fsid.val[0]; + tmp.f_fsid.val[1] = kbuf->f_fsid.val[1]; + + return copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0; } extern asmlinkage int sys_statfs(const char * path, struct statfs * buf); @@ -2311,7 +2343,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 +2356,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 +2364,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 +2393,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; @@ -2541,7 +2600,7 @@ err = -EFAULT; if (get_user(pad, (u32 *)uptr)) return err; - if (third == SETVAL) + if ((third & (~IPC_64)) == SETVAL) fourth.val = (int)pad; else fourth.__pad = (void *)A(pad); @@ -3029,7 +3088,7 @@ err = do_sys32_shmctl(first, second, (void *)AA(ptr)); break; default: - err = -EINVAL; + err = -ENOSYS; break; } @@ -3462,7 +3521,7 @@ if(msghdr_from_user32_to_kern(&kern_msg, user_msg)) return -EFAULT; if(kern_msg.msg_iovlen > UIO_MAXIOV) - return -EINVAL; + return -EMSGSIZE; err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ); if (err < 0) goto out; @@ -3700,7 +3759,7 @@ if(msghdr_from_user32_to_kern(&kern_msg, user_msg)) return -EFAULT; if(kern_msg.msg_iovlen > UIO_MAXIOV) - return -EINVAL; + return -EMSGSIZE; uaddr = kern_msg.msg_name; uaddr_len = &user_msg->msg_namelen; @@ -3961,8 +4020,10 @@ regs->nip = nip; regs->gpr[1] = sp; regs->msr = MSR_USER32; +#ifndef CONFIG_SMP if (last_task_used_math == current) last_task_used_math = 0; +#endif current->thread.fpscr = 0; } @@ -4581,8 +4642,6 @@ extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf, size_t count, loff_t pos); -typedef __kernel_ssize_t32 ssize_t32; - asmlinkage ssize_t32 sys32_pread(unsigned int fd, char *ubuf, __kernel_size_t32 count, u32 reg6, u32 poshi, u32 poslo) { Index: arch/ppc64/kernel/syscalls.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/syscalls.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/syscalls.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/syscalls.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -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); Index: arch/ppc64/kernel/time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/time.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/time.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -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; } Index: arch/ppc64/kernel/traps.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/traps.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/traps.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/traps.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -42,12 +42,15 @@ #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); /* This is true if we are using the firmware NMI handler (typically LPAR) */ extern int fwnmi_active; +/* This is true if we are using a check-exception based handler */ +extern int check_exception_flag; #ifdef CONFIG_XMON extern void xmon(struct pt_regs *regs); @@ -75,14 +78,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 */ @@ -90,6 +90,9 @@ void set_local_DABR(void *valp); +/* do not want to kmalloc or wait on lock during machine check */ +char mce_data_buf[RTAS_ERROR_LOG_MAX]__page_aligned; + /* * Trap & Exception support */ @@ -100,13 +103,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)) @@ -134,7 +133,9 @@ (errdata >= rtas.base && errdata < rtas.base + rtas.size - 16)) { savep = __va(errdata); regs->gpr[3] = savep[0]; /* restore original r3 */ - errhdr = (struct rtas_error_log *)(savep + 1); + memset(mce_data_buf, 0, RTAS_ERROR_LOG_MAX); + memcpy(mce_data_buf, (char *)(savep + 1), RTAS_ERROR_LOG_MAX); + errhdr = (struct rtas_error_log *)mce_data_buf; } else { printk("FWNMI: corrupt r3\n"); } @@ -164,95 +165,122 @@ } #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 } +/* + * See if we can recover from a machine check exception. + * This is only called on power4 (or above) and only via + * the Firmware Non-Maskable Interrupts (fwnmi) handler + * which provides the error analysis for us. + * + * Return 1 if corrected (or delivered a signal). + * Return 0 if there is nothing we can do. + */ +static int recover_mce(struct pt_regs *regs, struct rtas_error_log *errp) +{ + siginfo_t info; + int nonfatal = 0; + + + if (errp->disposition == DISP_FULLY_RECOVERED) { + /* Platform corrected itself */ + nonfatal = 1; + } else if ((regs->msr & MSR_RI) && + user_mode(regs) && + errp->severity == SEVERITY_ERROR_SYNC && + errp->disposition == DISP_NOT_RECOVERED && + errp->target == TARGET_MEMORY && + errp->type == TYPE_ECC_UNCORR && + !(current->pid == 0 || current->pid == 1)) { + /* Kill off a user process with an ECC error */ + printk(KERN_ERR "MCE: uncorrectable ecc error killed process %d (%s).\n", current->pid, current->comm); + + info.si_signo = SIGBUS; + info.si_errno = 0; + /* XXX better si_code for ECC error? */ + info.si_code = BUS_ADRERR; + info.si_addr = (void *)regs->nip; + _exception(SIGBUS, &info, regs); + nonfatal = 1; + } + + log_error((char *)errp, ERR_TYPE_RTAS_LOG, !nonfatal); + + return nonfatal; +} + +/* + * Handle a machine check. + * + * Note that on Power 4 and beyond Firmware Non-Maskable Interrupts (fwnmi) + * should be present. If so the handler which called us tells us if the + * error was recovered (never true if RI=0). + * + * On hardware prior to Power 4 these exceptions were asynchronous which + * means we can't tell exactly where it occurred and so we can't recover. + * + * Note that the debugger should test RI=0 and warn the user that system + * state has been corrupted. + */ void MachineCheckException(struct pt_regs *regs) { - siginfo_t info; + struct rtas_error_log *errp; if (fwnmi_active) { - struct rtas_error_log *errhdr = FWNMI_get_errinfo(regs); - if (errhdr) { - /* ToDo: attempt to recover from some errors here */ - } + errp = FWNMI_get_errinfo(regs); FWNMI_release_errinfo(); + if (errp && recover_mce(regs, errp)) + return; + } else if (check_exception_flag) { + int status; + unsigned long long srr1 = regs->msr; + + memset(mce_data_buf, 0, RTAS_ERROR_LOG_MAX); + /* XXX + * We only pass the low 32 bits of SRR1, this could + * be changed to 7 input params and the high 32 bits + * of SRR1 could be passed as the extended info argument. + */ + status = rtas_call(rtas_token("check-exception"), 6, 1, NULL, + 0x200, (uint)srr1, RTAS_INTERNAL_ERROR, 0, + __pa(mce_data_buf), RTAS_ERROR_LOG_MAX); + if (status == 0) + log_error((char *)mce_data_buf, ERR_TYPE_RTAS_LOG, 1); } - 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 +306,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; @@ -333,6 +356,19 @@ _exception(SIGFPE, info, regs); } +#ifndef CONFIG_ALTIVEC +void IllegalAltiVecInstruction(struct pt_regs *regs) +{ + siginfo_t info; + + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_code = ILL_ILLTRP; + info.si_addr = (void *)regs->nip; + _exception(SIGILL, &info, regs); +} +#endif + void ProgramCheckException(struct pt_regs *regs) { @@ -353,14 +389,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 +409,55 @@ } } + 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 +KernelAltiVecUnavailableException(struct pt_regs *regs) +{ + printk("Illegal Altivec used in kernel (task=0x%016lx, pc=0x%016lx, trap=0x%08x)\n", + (unsigned long)current, regs->nip, (unsigned int)regs->trap); + panic("Unrecoverable Altivec Unavailable Exception in Kernel"); +} + +void +AltiVecAssistException(struct pt_regs *regs) +{ +#ifdef CONFIG_ALTIVEC + printk("Altivec assist called by %s, switching java mode off\n", + current->comm); + /* We do this the "hard" way, but that's ok for now, maybe one + * day, we'll have a proper implementation... + */ + if (regs->msr & MSR_VEC) + giveup_altivec(current); + current->thread.vscr.u[3] |= 0x00010000; +#else + siginfo_t info; + + printk("Altivec assist called by %s;, no altivec support !\n", + current->comm); + + info.si_signo = SIGTRAP; + info.si_errno = 0; + info.si_code = 0; + info.si_addr = 0; + _exception(SIGTRAP, &info, regs); +#endif /* CONFIG_ALTIVEC */ +} + +void +ThermalInterrupt(struct pt_regs *regs) +{ + panic("Thermal interrupt exception not handled !"); +} + void SingleStepException(struct pt_regs *regs) { @@ -384,15 +465,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; Index: arch/ppc64/kernel/udbg.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/udbg.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/udbg.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/udbg.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -130,8 +130,10 @@ { int remain = n; char c; + if (!ppc_md.udbg_putc) - for (;;); /* stop here for cpuctl */ + return 0; + if ( s && *s != '\0' ) { while ( (( c = *s++ ) != '\0') && (remain-- > 0)) { ppc_md.udbg_putc(c); Index: arch/ppc64/kernel/xics.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/xics.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/xics.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/xics.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -51,7 +51,6 @@ }; #define XICS_IPI 2 -#define XICS_IRQ_OFFSET 0x10 #define XICS_IRQ_SPURIOUS 0 /* Want a priority other than 0. Various HW issues require this. */ @@ -136,25 +135,26 @@ void -xics_enable_irq( - u_int virq - ) +xics_enable_irq(u_int virq) { 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); + irq = irq_offset_down(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); @@ -171,18 +171,14 @@ } void -xics_disable_irq( - u_int virq - ) +xics_disable_irq(u_int virq) { u_int irq; unsigned long status; long call_status; - virq -= XICS_IRQ_OFFSET; - irq = virt_irq_to_real(virq); - call_status = rtas_call(ibm_int_off, 1, 1, (unsigned long*)&status, - irq); + irq = irq_offset_down(virq); + call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq); if( call_status != 0 ) { printk("xics_disable_irq: irq=%x: rtas_call failed, retn=%lx\n", irq, call_status); @@ -191,16 +187,12 @@ } void -xics_end_irq( - u_int irq - ) +xics_end_irq(u_int irq) { int cpu = smp_processor_id(); - ops->cppr_info(cpu, 0); /* actually the value overwritten by ack */ - iosync(); - ops->xirr_info_set(cpu, ((0xff<<24) | (virt_irq_to_real(irq-XICS_IRQ_OFFSET)))); iosync(); + ops->xirr_info_set(cpu, (0xff<<24) | irq_offset_down(irq)); } void @@ -208,7 +200,7 @@ { int cpu = smp_processor_id(); - if( irq < XICS_IRQ_OFFSET ) { + if (irq < irq_offset_value()) { i8259_pic.ack(irq); iosync(); ops->xirr_info_set(cpu, ((0xff<<24) | xics_irq_8259_cascade_real)); @@ -235,13 +227,13 @@ irq = i8259_irq(cpu); if(irq == -1) { /* Spurious cascaded interrupt. Still must ack xics */ - xics_end_irq(XICS_IRQ_OFFSET + xics_irq_8259_cascade); + xics_end_irq(irq_offset_up(xics_irq_8259_cascade)); irq = -1; } } else if( vec == XICS_IRQ_SPURIOUS ) { irq = -1; } else { - irq = real_irq_to_virt(vec) + XICS_IRQ_OFFSET; + irq = irq_offset_up(vec); } return irq; } @@ -286,6 +278,15 @@ } #endif /* CONFIG_SMP */ +void xics_init_irq_desc(irq_desc_t *desc) +{ + /* Don't mess with the handler if already set. + * This leaves the setup of isa handlers undisturbed. + */ + if (!desc->handler) + desc->handler = &xics_pic; +} + void xics_init_IRQ( void ) { @@ -369,7 +370,7 @@ while (1); } xics_irq_8259_cascade_real = *ireg; - xics_irq_8259_cascade = virt_irq_create_mapping(xics_irq_8259_cascade_real); + xics_irq_8259_cascade = xics_irq_8259_cascade_real; } if (systemcfg->platform == PLATFORM_PSERIES) { @@ -394,36 +395,24 @@ xics_8259_pic.enable = i8259_pic.enable; xics_8259_pic.disable = i8259_pic.disable; for (i = 0; i < 16; ++i) - irq_desc[i].handler = &xics_8259_pic; - for (; i < NR_IRQS; ++i) - irq_desc[i].handler = &xics_pic; + real_irqdesc(i)->handler = &xics_8259_pic; ops->cppr_info(0, 0xff); iosync(); if (xics_irq_8259_cascade != -1) { - if (request_irq(xics_irq_8259_cascade + XICS_IRQ_OFFSET, no_action, - 0, "8259 cascade", 0)) + if (request_irq(irq_offset_up(xics_irq_8259_cascade), + no_action, 0, "8259 cascade", 0)) printk(KERN_ERR "xics_init_IRQ: couldn't get 8259 cascade\n"); i8259_init(); } #ifdef CONFIG_SMP - real_irq_to_virt_map[XICS_IPI] = virt_irq_to_real_map[XICS_IPI] = XICS_IPI; - request_irq(XICS_IPI + XICS_IRQ_OFFSET, xics_ipi_action, 0, "IPI", 0); - irq_desc[XICS_IPI+XICS_IRQ_OFFSET].status |= IRQ_PER_CPU; + request_irq(irq_offset_up(XICS_IPI), xics_ipi_action, 0, "IPI", 0); + real_irqdesc(irq_offset_up(XICS_IPI))->status |= IRQ_PER_CPU; #endif ppc64_boot_msg(0x21, "XICS Done"); } -void xics_isa_init(void) -{ - return; - if (request_irq(xics_irq_8259_cascade + XICS_IRQ_OFFSET, no_action, - 0, "8259 cascade", 0)) - printk(KERN_ERR "xics_init_IRQ: couldn't get 8259 cascade\n"); - i8259_init(); -} - /* * Find first logical cpu and return its physical cpu number */ @@ -441,21 +430,19 @@ return default_distrib_server; } -void xics_set_affinity(unsigned int virq, unsigned long cpumask) +void xics_set_affinity(unsigned int irq, unsigned long cpumask) { - irq_desc_t *desc = irq_desc + virq; - unsigned int irq; + irq_desc_t *desc = irqdesc(irq); unsigned long flags; long status; unsigned long xics_status[2]; u32 newmask; - virq -= XICS_IRQ_OFFSET; - irq = virt_irq_to_real(virq); + irq = irq_offset_down(irq); if (irq == XICS_IPI) return; - spin_lock_irqsave(&desc->lock, flags); + spin_lock_irqsave(&desc->lock, flags); status = rtas_call(ibm_get_xive, 1, 3, (void *)&xics_status, irq); @@ -481,5 +468,5 @@ } out: - spin_unlock_irqrestore(&desc->lock, flags); + spin_unlock_irqrestore(&desc->lock, flags); } Index: arch/ppc64/kernel/xics.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/kernel/xics.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/kernel/xics.h 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/ppc64/kernel/xics.h 4 Aug 2004 01:26:11 -0000 1.2 @@ -18,7 +18,7 @@ extern struct hw_interrupt_type xics_8259_pic; void xics_init_IRQ(void); +void xics_init_irq_desc(irq_desc_t *); int xics_get_irq(struct pt_regs *); -void xics_isa_init(void); #endif /* _PPC_KERNEL_XICS_H */ Index: arch/ppc64/lib/copyuser.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/lib/copyuser.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/lib/copyuser.S 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/lib/copyuser.S 4 Aug 2004 01:26:11 -0000 1.2 @@ -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 Index: arch/ppc64/mm/fault.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/mm/fault.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/mm/fault.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/mm/fault.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -59,29 +59,59 @@ #endif /* - * For 600- and 800-family processors, the error_code parameter is DSISR - * for a data fault, SRR1 for an instruction fault. + * Check whether the instruction at regs->nip is a store using + * an update addressing form which will update r1. + */ +static int store_updates_sp(struct pt_regs *regs) +{ + unsigned int inst; + + if (get_user(inst, (unsigned int *)regs->nip)) + return 0; + /* check for 1 in the rA field */ + if (((inst >> 16) & 0x1f) != 1) + return 0; + /* check major opcode */ + switch (inst >> 26) { + case 37: /* stwu */ + case 39: /* stbu */ + case 45: /* sthu */ + case 53: /* stfsu */ + case 55: /* stfdu */ + return 1; + case 62: /* std or stdu */ + return (inst & 3) == 1; + case 31: + /* check minor opcode */ + switch ((inst >> 1) & 0x3ff) { + case 181: /* stdux */ + case 183: /* stwux */ + case 247: /* stbux */ + case 439: /* sthux */ + case 695: /* stfsux */ + case 759: /* stfdux */ + return 1; + } + } + return 0; +} + +/* + * The error_code parameter is + * - DSISR for a non-SLB data access fault, + * - SRR1 & 0x08000000 for a non-SLB instruction access fault + * - 0 any SLB fault. */ 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; unsigned long is_write = error_code & 0x02000000; unsigned long mm_fault_return; - PPCDBG(PPCDBG_MM, "Entering do_page_fault: addr = 0x%16.16lx, error_code = %lx\n\tregs_trap = %lx, srr0 = %lx, srr1 = %lx\n", address, error_code, regs->trap, get_srr0(), get_srr1()); - /* - * Fortunately the bit assignments in SRR1 for an instruction - * fault and DSISR for a data fault are mostly the same for the - * bits we are interested in. But there are some bits which - * indicate errors in DSISR but can validly be set in SRR1. - */ - if (regs->trap == 0x400) - error_code &= 0x48200000; - #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) if (debugger_fault_handler && (regs->trap == 0x300 || regs->trap == 0x380)) { @@ -90,8 +120,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 +129,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 +153,39 @@ PPCDBG(PPCDBG_MM, "\tdo_page_fault: vma->vm_flags = %lx, %lx\n", vma->vm_flags, VM_GROWSDOWN); goto bad_area; } + + /* + * N.B. The POWER/Open ABI allows programs to access up to + * 288 bytes below the stack pointer. + * The kernel signal delivery code writes up to about 1.5kB + * below the stack pointer (r1) before decrementing it. + * The exec code can write slightly over 640kB to the stack + * before setting the user r1. Thus we allow the stack to + * expand to 1MB without further checks. + */ + if (address + 0x100000 < vma->vm_end) { + /* get user regs even if this fault is in kernel mode */ + struct pt_regs *uregs = current->thread.regs; + if (uregs == NULL) + goto bad_area; + + /* + * A user-mode access to an address a long way below + * the stack pointer is only valid if the instruction + * is one which would update the stack pointer to the + * address accessed if the instruction completed, + * i.e. either stwu rs,n(r1) or stwux rs,r1,rb + * (or the byte, halfword, float or double forms). + * + * If we don't check this then any write to the area + * between the last mapped region and the stack will + * expand the stack rather than segfaulting. + */ + if (address + 2048 < uregs->gpr[1] + && (!user_mode(regs) || !store_updates_sp(regs))) + goto bad_area; + } + if (expand_stack(vma, address)) { PPCDBG(PPCDBG_MM, "\tdo_page_fault: expand_stack\n"); goto bad_area; @@ -243,13 +301,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); Index: arch/ppc64/mm/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/mm/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/mm/init.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/mm/init.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -279,7 +280,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 +297,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 +644,135 @@ 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; + + 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%p\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(void) +{ + 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 Index: arch/ppc64/xmon/xmon.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/ppc64/xmon/xmon.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/ppc64/xmon/xmon.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/ppc64/xmon/xmon.c 4 Aug 2004 01:26:11 -0000 1.2 @@ -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; } Index: arch/s390/config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390/config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390/config.in 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/s390/config.in 4 Aug 2004 01:26:12 -0000 1.2 @@ -32,6 +32,9 @@ comment 'Processor type and features' bool 'Symmetric multi-processing support' CONFIG_SMP bool 'IEEE FPU emulation' CONFIG_MATHEMU +if [ "$CONFIG_SMP" = "y" ]; then + int 'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32 +fi endmenu mainmenu_option next_comment @@ -39,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' \ @@ -73,6 +80,10 @@ # bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG #fi bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ + +int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 + endmenu +source crypto/Config.in source lib/Config.in Index: arch/s390/defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390/defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390/defconfig 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/s390/defconfig 4 Aug 2004 01:26:12 -0000 1.2 @@ -27,6 +27,7 @@ # CONFIG_SMP=y CONFIG_MATHEMU=y +CONFIG_NR_CPUS=32 # # General setup @@ -34,6 +35,8 @@ CONFIG_FAST_IRQ=y CONFIG_MACHCHK_WARNING=y CONFIG_CHSC=y +CONFIG_QDIO=m +# CONFIG_QDIO_PERF_STATS is not set CONFIG_IPL=y # CONFIG_IPL_TAPE is not set CONFIG_IPL_VM=y @@ -64,7 +67,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) @@ -105,8 +108,8 @@ # # S/390 tape hardware support # -CONFIG_S390_TAPE_3490=m -CONFIG_S390_TAPE_3480=m +CONFIG_S390_TAPE_3490=y +CONFIG_S390_TAPE_3480=y # # Network device drivers @@ -118,7 +121,8 @@ # CONFIG_TUN is not set CONFIG_NET_ETHERNET=y CONFIG_TR=y -# CONFIG_FDDI is not set +# CONFIG_C7000 is not set +CONFIG_FDDI=y # # S/390 network device drivers @@ -134,22 +138,112 @@ 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_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=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_ARP_MANGLE is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set CONFIG_IPV6=m -CONFIG_SHARED_IPV6_CARDS=y + +# +# 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_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=m +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set CONFIG_VLAN_8021Q=m @@ -158,6 +252,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 +265,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,9 +274,15 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN 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 @@ -187,33 +292,39 @@ # 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 +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 @@ -223,6 +334,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -230,12 +346,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 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 +366,88 @@ # 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 +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 +# CONFIG_FW_LOADER is not set Index: arch/s390/kernel/debug.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390/kernel/debug.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390/kernel/debug.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/s390/kernel/debug.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -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); Index: arch/s390/kernel/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390/kernel/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390/kernel/head.S 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/s390/kernel/head.S 4 Aug 2004 01:26:12 -0000 1.2 @@ -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 Index: arch/s390/kernel/process.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390/kernel/process.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390/kernel/process.c 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/s390/kernel/process.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -60,7 +60,9 @@ current->nice = 20; current->counter = -100; while (1) { + __cli(); if (current->need_resched) { + __sti(); schedule(); check_pgt_cache(); continue; Index: arch/s390/kernel/s390_ksyms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390/kernel/s390_ksyms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390/kernel/s390_ksyms.c 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/s390/kernel/s390_ksyms.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -23,6 +23,7 @@ EXPORT_SYMBOL_NOVERS(__copy_from_user_asm); EXPORT_SYMBOL_NOVERS(__copy_to_user_asm); EXPORT_SYMBOL_NOVERS(__clear_user_asm); +EXPORT_SYMBOL(diag10); /* * semaphore ops @@ -60,5 +61,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); Index: arch/s390/kernel/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390/kernel/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390/kernel/setup.c 22 Jul 2004 19:49:18 -0000 1.1 +++ arch/s390/kernel/setup.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -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; Index: arch/s390/mm/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390/mm/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390/mm/init.c 22 Jul 2004 19:49:17 -0000 1.1 +++ arch/s390/mm/init.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -67,6 +67,11 @@ return freed; } +void diag10(unsigned long addr) +{ + asm volatile ("diag %0,%0,0x10" : : "a" (addr)); +} + void show_mem(void) { int i, total = 0, reserved = 0; @@ -154,11 +159,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; } } Index: arch/s390x/config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390x/config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390x/config.in 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/s390x/config.in 4 Aug 2004 01:26:12 -0000 1.2 @@ -22,6 +22,9 @@ mainmenu_option next_comment comment 'Processor type and features' bool 'Symmetric multi-processing support' CONFIG_SMP +if [ "$CONFIG_SMP" = "y" ]; then + int 'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32 +fi bool 'Kernel support for 31 bit emulation' CONFIG_S390_SUPPORT if [ "$CONFIG_S390_SUPPORT" = "y" ]; then tristate 'Kernel support for 31 bit ELF binaries' CONFIG_BINFMT_ELF32 @@ -42,6 +45,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' \ @@ -77,6 +84,10 @@ # bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG #fi bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ + +int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 + endmenu +source crypto/Config.in source lib/Config.in Index: arch/s390x/defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390x/defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390x/defconfig 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/s390x/defconfig 4 Aug 2004 01:26:12 -0000 1.2 @@ -19,6 +19,7 @@ # Processor type and features # CONFIG_SMP=y +CONFIG_NR_CPUS=32 CONFIG_S390_SUPPORT=y CONFIG_BINFMT_ELF32=y @@ -35,6 +36,8 @@ CONFIG_FAST_IRQ=y CONFIG_MACHCHK_WARNING=y CONFIG_CHSC=y +CONFIG_QDIO=m +# CONFIG_QDIO_PERF_STATS is not set CONFIG_IPL=y # CONFIG_IPL_TAPE is not set CONFIG_IPL_VM=y @@ -105,8 +108,8 @@ # # S/390 tape hardware support # -CONFIG_S390_TAPE_3490=m -CONFIG_S390_TAPE_3480=m +CONFIG_S390_TAPE_3490=y +CONFIG_S390_TAPE_3480=y # # Network device drivers @@ -118,7 +121,8 @@ # CONFIG_TUN is not set CONFIG_NET_ETHERNET=y CONFIG_TR=y -# CONFIG_FDDI is not set +# CONFIG_C7000 is not set +CONFIG_FDDI=y # # S/390 network device drivers @@ -134,22 +138,52 @@ 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 + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set CONFIG_IPV6=m -CONFIG_SHARED_IPV6_CARDS=y + +# +# IPv6: Netfilter Configuration +# +# CONFIG_IP6_NF_QUEUE is not set +# CONFIG_IP6_NF_IPTABLES is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=m +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set CONFIG_VLAN_8021Q=m @@ -158,6 +192,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 +205,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,9 +214,15 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN 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 @@ -187,33 +232,39 @@ # 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 +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 @@ -223,6 +274,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -230,13 +286,18 @@ # 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 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 +308,88 @@ # 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 +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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 +# CONFIG_FW_LOADER is not set Index: arch/s390x/vmlinux-shared.lds =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390x/vmlinux-shared.lds,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390x/vmlinux-shared.lds 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/s390x/vmlinux-shared.lds 4 Aug 2004 01:26:12 -0000 1.2 @@ -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 { Index: arch/s390x/vmlinux.lds =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390x/vmlinux.lds,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390x/vmlinux.lds 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/s390x/vmlinux.lds 4 Aug 2004 01:26:12 -0000 1.2 @@ -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 { Index: arch/s390x/kernel/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390x/kernel/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390x/kernel/Makefile 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/s390x/kernel/Makefile 4 Aug 2004 01:26:12 -0000 1.2 @@ -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 Index: arch/s390x/kernel/binfmt_elf32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390x/kernel/binfmt_elf32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390x/kernel/binfmt_elf32.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/s390x/kernel/binfmt_elf32.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -35,7 +35,7 @@ /* For SVR4/S390 the function pointer to be registered with `atexit` is passed in R14. */ -#define ELF_PLAT_INIT(_r) \ +#define ELF_PLAT_INIT(_r, load_addr) \ do { \ _r->gprs[14] = 0; \ current->thread.flags |= S390_FLAG_31BIT; \ @@ -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" Index: arch/s390x/kernel/debug.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390x/kernel/debug.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390x/kernel/debug.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/s390x/kernel/debug.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -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); Index: arch/s390x/kernel/entry.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390x/kernel/entry.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390x/kernel/entry.S 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/s390x/kernel/entry.S 4 Aug 2004 01:26:12 -0000 1.2 @@ -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 */ Index: arch/s390x/kernel/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390x/kernel/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390x/kernel/head.S 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/s390x/kernel/head.S 4 Aug 2004 01:26:12 -0000 1.2 @@ -548,17 +548,6 @@ 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) @@ -601,7 +590,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 Index: arch/s390x/kernel/ioctl32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390x/kernel/ioctl32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390x/kernel/ioctl32.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/s390x/kernel/ioctl32.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -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; Index: arch/s390x/kernel/linux32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390x/kernel/linux32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390x/kernel/linux32.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/s390x/kernel/linux32.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +64,7 @@ #include #include +#include #include "linux32.h" @@ -384,18 +386,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 +506,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 +541,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 +558,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 +891,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 +936,7 @@ return sys32_fcntl(fd, cmd, arg); } -struct dqblk32 { +struct user_dqblk32 { __u32 dqb_bhardlimit; __u32 dqb_bsoftlimit; __u32 dqb_curblocks; @@ -925,46 +949,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; @@ -1851,7 +1874,11 @@ u32 totalswap; u32 freeswap; unsigned short procs; - char _f[22]; + unsigned short pad; + u32 totalhigh; + u32 freehigh; + unsigned int mem_unit; + char _f[8]; }; extern asmlinkage int sys_sysinfo(struct sysinfo *info); @@ -1876,6 +1903,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; @@ -2151,15 +2181,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 +2200,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 +2636,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 +2675,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 +2785,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 +2801,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 +3100,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 +3963,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 +4185,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 +4648,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); +} Index: arch/s390x/kernel/process.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390x/kernel/process.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390x/kernel/process.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/s390x/kernel/process.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -60,7 +60,9 @@ current->nice = 20; current->counter = -100; while (1) { + __cli(); if (current->need_resched) { + __sti(); schedule(); check_pgt_cache(); continue; Index: arch/s390x/kernel/s390_ksyms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390x/kernel/s390_ksyms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390x/kernel/s390_ksyms.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/s390x/kernel/s390_ksyms.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -13,6 +13,7 @@ #include #include #include +#include #if CONFIG_IP_MULTICAST #include #endif @@ -26,6 +27,7 @@ EXPORT_SYMBOL_NOVERS(__copy_from_user_asm); EXPORT_SYMBOL_NOVERS(__copy_to_user_asm); EXPORT_SYMBOL_NOVERS(__clear_user_asm); +EXPORT_SYMBOL(diag10); /* * semaphore ops @@ -62,6 +64,15 @@ EXPORT_SYMBOL(overflowuid); EXPORT_SYMBOL(overflowgid); +#ifdef CONFIG_S390_SUPPORT +/* + * Dynamically add/remove 31 bit ioctl conversion functions. + */ +EXPORT_SYMBOL(register_ioctl32_conversion); +EXPORT_SYMBOL(unregister_ioctl32_conversion); +EXPORT_SYMBOL(sys_ioctl); +#endif + /* * misc. */ @@ -70,5 +81,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); Index: arch/s390x/kernel/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390x/kernel/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390x/kernel/setup.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/s390x/kernel/setup.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -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*/ Index: arch/s390x/kernel/signal.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390x/kernel/signal.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390x/kernel/signal.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/s390x/kernel/signal.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -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 */ } } Index: arch/s390x/kernel/signal32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390x/kernel/signal32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390x/kernel/signal32.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/s390x/kernel/signal32.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -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: Index: arch/s390x/kernel/wrapper32.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390x/kernel/wrapper32.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390x/kernel/wrapper32.S 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/s390x/kernel/wrapper32.S 4 Aug 2004 01:26:12 -0000 1.2 @@ -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 Index: arch/s390x/mm/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/s390x/mm/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/s390x/mm/init.c 22 Jul 2004 19:49:19 -0000 1.1 +++ arch/s390x/mm/init.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -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. */ @@ -135,6 +170,15 @@ return freed; } +void diag10(unsigned long addr) +{ + if (addr >= 0x80000000) + return; + asm volatile ("sam31\n\t" + "diag %0,%0,0x10\n\t" + "sam64" : : "a" (addr) ); +} + void show_mem(void) { int i, total = 0,reserved = 0; @@ -234,11 +278,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; } } Index: arch/sh/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/Makefile 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/Makefile 4 Aug 2004 01:26:12 -0000 1.2 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.1 2004/07/22 19:48:57 joff Exp $ +# $Id: Makefile,v 1.2 2004/08/04 01:26:12 joff 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,18 @@ LDFLAGS := -EB endif +ifdef CONFIG_SH_DSP +AFLAGS += -Wa,-dsp +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 @@ -79,7 +91,7 @@ FORCE: ; zImage: vmlinux - @$(MAKEBOOT) zImage + @$(MAKEBOOT) $@ compressed: zImage Index: arch/sh/config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/config.in 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/config.in 4 Aug 2004 01:26:12 -0000 1.2 @@ -29,8 +29,10 @@ comment 'Processor type and features' choice 'SuperH system type' \ "Generic CONFIG_SH_GENERIC \ + SH4-202-MicroDev CONFIG_SH_SH4202_MICRODEV \ 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 \ @@ -43,11 +45,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 @@ -59,12 +65,20 @@ 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 \ + SH7751R CONFIG_CPU_SUBTYPE_SH7751R \ SH7751 CONFIG_CPU_SUBTYPE_SH7751 \ - ST40STB1 CONFIG_CPU_SUBTYPE_ST40STB1" SH7708 + SH4-202 CONFIG_CPU_SUBTYPE_SH4_202 \ + 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 @@ -85,9 +99,28 @@ define_bool CONFIG_CPU_SH3 n define_bool CONFIG_CPU_SH4 y fi +if [ "$CONFIG_CPU_SUBTYPE_SH7751R" = "y" ]; then + define_bool CONFIG_CPU_SH3 n + define_bool CONFIG_CPU_SH4 y + define_bool CONFIG_CPU_SUBTYPE_SH7751 y +fi +if [ "$CONFIG_CPU_SUBTYPE_SH4_202" = "y" ]; then + define_bool CONFIG_CPU_SH3 n + define_bool CONFIG_CPU_SH4 y +fi +if [ "$CONFIG_CPU_SUBTYPE_SH7751R" = "y" -o \ + "$CONFIG_CPU_SUBTYPE_SH4_202" = "y" ]; then + bool 'Use 2-way set associative caches' CONFIG_SH_CACHE_ASSOC +fi 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 @@ -101,13 +134,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 @@ -120,11 +159,33 @@ 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 + +hex 'Link address offset for booting' CONFIG_BOOT_LINK_OFFSET 00210000 + +dep_bool 'Enable OC RAM zone (experimental)' CONFIG_SCRATCH_SPACE $CONFIG_EXPERIMENTAL +bool 'DSP mode support' CONFIG_SH_DSP + +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 @@ -139,7 +200,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 @@ -148,7 +215,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 @@ -176,21 +243,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 @@ -214,6 +286,8 @@ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC +bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER + source drivers/parport/Config.in endmenu @@ -236,7 +310,6 @@ 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 @@ -260,7 +333,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 @@ -281,9 +354,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' @@ -310,6 +383,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 @@ -342,7 +416,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 @@ -386,6 +460,37 @@ 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 + +int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 + endmenu +source crypto/Config.in source lib/Config.in Index: arch/sh/defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/defconfig 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/defconfig 4 Aug 2004 01:26:12 -0000 1.2 @@ -121,7 +121,6 @@ # 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 # # SCSI support Index: arch/sh/vmlinux.lds.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/vmlinux.lds.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/vmlinux.lds.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/vmlinux.lds.S 4 Aug 2004 01:26:12 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: vmlinux.lds.S,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: vmlinux.lds.S,v 1.2 2004/08/04 01:26:12 joff Exp $ * ld script to make SuperH Linux kernel * Written by Niibe Yutaka */ Index: arch/sh/boot/compressed/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/boot/compressed/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/boot/compressed/Makefile 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/boot/compressed/Makefile 4 Aug 2004 01:26:12 -0000 1.2 @@ -18,9 +18,9 @@ # # ZIMAGE_OFFSET is the load offset of the compression loader # -ZIMAGE_OFFSET = $(shell printf "0x%8x" $$[0x80000000+0x$(CONFIG_MEMORY_START)+0x200000+0x10000]) +ZIMAGE_OFFSET = $(shell printf "0x%8x" $$[0x80000000+0x$(CONFIG_MEMORY_START)+0x$(CONFIG_BOOT_LINK_OFFSET)]) -ZLINKFLAGS = -Ttext $(ZIMAGE_OFFSET) $(ZLDFLAGS) +ZLINKFLAGS = -Ttext $(ZIMAGE_OFFSET) $(ZLDFLAGS) all: vmlinux Index: arch/sh/boot/compressed/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/boot/compressed/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/boot/compressed/head.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/boot/compressed/head.S 4 Aug 2004 01:26:12 -0000 1.2 @@ -2,6 +2,7 @@ * linux/arch/sh/boot/compressed/head.S * * Copyright (C) 1999 Stuart Menefy + * Copyright (C) 2003 SUGIOKA Toshinobu */ .text @@ -14,7 +15,54 @@ mov.l init_sr, r1 ldc r1, sr - /* First clear BSS */ + /* Move myself to proper location if necessary */ + mova 1f, r0 + mov.l 1f, r2 + cmp/eq r2, r0 + bt clear_bss + sub r0, r2 + mov.l bss_start_addr, r0 + mov #0xe0, r1 + and r1, r0 ! align cache line + mov.l text_start_addr, r3 + mov r0, r1 + sub r2, r1 +3: + mov.l @r1, r4 + mov.l @(4,r1), r5 + mov.l @(8,r1), r6 + mov.l @(12,r1), r7 + mov.l @(16,r1), r8 + mov.l @(20,r1), r9 + mov.l @(24,r1), r10 + mov.l @(28,r1), r11 + mov.l r4, @r0 + mov.l r5, @(4,r0) + mov.l r6, @(8,r0) + mov.l r7, @(12,r0) + mov.l r8, @(16,r0) + mov.l r9, @(20,r0) + mov.l r10, @(24,r0) + mov.l r11, @(28,r0) +#ifdef CONFIG_CPU_SH4 + ocbwb @r0 +#endif + cmp/hi r3, r0 + add #-32, r0 + bt/s 3b + add #-32, r1 + mov.l 2f, r0 + jmp @r0 + nop + + .align 2 +1: .long 1b +2: .long clear_bss +text_start_addr: + .long startup + + /* Clear BSS */ +clear_bss: mov.l end_addr, r1 mov.l bss_start_addr, r2 mov #0, r0 Index: arch/sh/kernel/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/Makefile 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/Makefile 4 Aug 2004 01:26:12 -0000 1.2 @@ -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,24 @@ 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 + +obj-$(CONFIG_SH_SH4202_MICRODEV)+= mach_microdev.o setup_microdev.o io_microdev.o irq_microdev.o +machine-specific-objs += mach_microdev.o setup_microdev.o io_microdev.o irq_microdev.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 Index: arch/sh/kernel/cf-enabler.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/cf-enabler.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/cf-enabler.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/cf-enabler.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: cf-enabler.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: cf-enabler.c,v 1.2 2004/08/04 01:26:12 joff 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(); } Index: arch/sh/kernel/dma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/dma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/dma.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/dma.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -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); -/**/ Index: arch/sh/kernel/entry.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/entry.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/entry.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/entry.S 4 Aug 2004 01:26:12 -0000 1.2 @@ -1,9 +1,11 @@ -/* $Id: entry.S,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: entry.S,v 1.2 2004/08/04 01:26:12 joff 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,60 @@ 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 + +#ifdef CONFIG_SH_DSP + mov.l @r15+, k0 ! DSP mode marker + mov.l 5f, k1 + cmp/eq k0, k1 ! Do we have a DSP stack frame? + bf skip_restore + + stc sr, k0 ! Enable CPU DSP mode + or k1, k0 ! (within kernel it may be disabled) + ldc k0, sr + mov r2, k0 ! Backup r2 + + ! Restore DSP registers from stack + mov r15, r2 + movs.l @r2+, a1 + movs.l @r2+, a0g + movs.l @r2+, a1g + movs.l @r2+, m0 + movs.l @r2+, m1 + mov r2, r15 + + lds.l @r15+, a0 + lds.l @r15+, x0 + lds.l @r15+, x1 + lds.l @r15+, y0 + lds.l @r15+, y1 + lds.l @r15+, dsr + ldc.l @r15+, rs + ldc.l @r15+, re + ldc.l @r15+, mod + + mov k0, r2 ! Restore r2 +skip_restore: +#endif + + ! ! ! 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,72 +614,30 @@ 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.l @r15+, k2 ! restore EXPEVT mov k4, r15 rte nop .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 +5: .long 0x00001000 ! DSP + ! Exception Vector Base ! @@ -717,6 +669,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 +700,56 @@ ! 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 + ! +#ifdef CONFIG_SH_DSP + mov.l r2, @-r15 ! Save r2, we need another reg + stc sr, k4 + mov.l 4f, r2 + tst r2, k4 ! Check if in DSP mode + mov.l @r15+, r2 ! Restore r2 now + bt/s skip_save + mov #0, k4 ! Set marker for no stack frame + + mov r2, k4 ! Backup r2 (in k4) for later + + ! Save DSP registers on stack + stc.l mod, @-r15 + stc.l re, @-r15 + stc.l rs, @-r15 + sts.l dsr, @-r15 + sts.l y1, @-r15 + sts.l y0, @-r15 + sts.l x1, @-r15 + sts.l x0, @-r15 + sts.l a0, @-r15 + mov r15, r2 + movs.l a1, @-r2 + movs.l a0g, @-r2 + movs.l a1g, @-r2 + movs.l m0, @-r2 + movs.l m1, @-r2 + mov r2, r15 + + mov k4, r2 ! Restore r2 + mov.l 4f, k4 ! Force DSP stack frame +skip_save: + mov.l k4, @-r15 ! Push DSP mode marker onto stack +#endif + + ! Save the user registers on the stack. + mov.l k2, @-r15 ! EXPEVT ! sts.l macl, @-r15 sts.l mach, @-r15 @@ -806,11 +769,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 +794,8 @@ 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 +4: .long 0x00001000 ! DSP bit set 5: .long 0xcfffffff ! RB=0, BL=0 6: .long 0x00080000 ! SZ=0, PR=1 @@ -862,7 +824,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 +866,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 +897,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 +992,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 +1024,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 +1055,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 +1088,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 +1268,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 +1282,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 +1339,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 +1382,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 Index: arch/sh/kernel/fpu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/fpu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/fpu.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/fpu.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: fpu.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: fpu.c,v 1.2 2004/08/04 01:26:12 joff Exp $ * * linux/arch/sh/kernel/fpu.c * @@ -18,6 +18,18 @@ #include #include +/* The PR (precision) bit in the FP Status Register must be clear when + * an frchg instruction is executed, otherwise the instruction is undefined. + * Executing frchg with PR set causes a trap on some SH4 implementations. + */ + +#define FPSCR_RCHG 0x00000000 + + +/* + * Save FPU registers onto task structure. + * Assume called with FPU enabled (SR.FD=0). + */ void save_fpu(struct task_struct *tsk) { @@ -57,9 +69,11 @@ "fmov.s fr3, @-%0\n\t" "fmov.s fr2, @-%0\n\t" "fmov.s fr1, @-%0\n\t" - "fmov.s fr0, @-%0" + "fmov.s fr0, @-%0\n\t" + "lds %2, fpscr\n\t" : /* no output */ : "r" ((char *)(&tsk->thread.fpu.hard.status)), + "r" (FPSCR_RCHG), "r" (FPSCR_INIT) : "memory"); @@ -108,7 +122,7 @@ "lds.l @%0+, fpscr\n\t" "lds.l @%0+, fpul\n\t" : /* no output */ - : "r" (&tsk->thread.fpu), "r" (FPSCR_INIT) + : "r" (&tsk->thread.fpu), "r" (FPSCR_RCHG) : "memory"); } @@ -118,7 +132,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" @@ -155,9 +170,119 @@ "fsts fpul, fr13\n\t" "fsts fpul, fr14\n\t" "fsts fpul, fr15\n\t" - "frchg" + "frchg\n\t" + "lds %2, fpscr\n\t" : /* no output */ - : "r" (0), "r" (FPSCR_INIT)); + : "r" (0), "r" (FPSCR_RCHG), "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 @@ -166,9 +291,10 @@ { 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 +307,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); Index: arch/sh/kernel/hd64465_gpio.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/hd64465_gpio.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/hd64465_gpio.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/hd64465_gpio.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: hd64465_gpio.c,v 1.1 2004/07/22 19:48:57 joff Exp $ + * $Id: hd64465_gpio.c,v 1.2 2004/08/04 01:26:12 joff Exp $ * by Greg Banks * (c) 2000 PocketPenguins Inc * Index: arch/sh/kernel/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/head.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/head.S 4 Aug 2004 01:26:12 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: head.S,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: head.S,v 1.2 2004/08/04 01:26:12 joff 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 Index: arch/sh/kernel/io_dc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/io_dc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/io_dc.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/io_dc.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: io_dc.c,v 1.1 2004/07/22 19:48:57 joff Exp $ + * $Id: io_dc.c,v 1.2 2004/08/04 01:26:12 joff Exp $ * I/O routines for SEGA Dreamcast */ Index: arch/sh/kernel/io_generic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/io_generic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/io_generic.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/io_generic.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: io_generic.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: io_generic.c,v 1.2 2004/08/04 01:26:12 joff Exp $ * * linux/arch/sh/kernel/io_generic.c * Index: arch/sh/kernel/io_hd64461.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/io_hd64461.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/io_hd64461.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/io_hd64461.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: io_hd64461.c,v 1.1 2004/07/22 19:48:57 joff Exp $ + * $Id: io_hd64461.c,v 1.2 2004/08/04 01:26:12 joff Exp $ * Copyright (C) 2000 YAEGASHI Takeshi * Typical I/O routines for HD64461 system. */ Index: arch/sh/kernel/io_hd64465.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/io_hd64465.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/io_hd64465.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/io_hd64465.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: io_hd64465.c,v 1.1 2004/07/22 19:48:57 joff Exp $ + * $Id: io_hd64465.c,v 1.2 2004/08/04 01:26:12 joff Exp $ * by Greg Banks * (c) 2000 PocketPenguins Inc * Index: arch/sh/kernel/io_se.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/io_se.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/io_se.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/io_se.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: io_se.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: io_se.c,v 1.2 2004/08/04 01:26:12 joff 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 Index: arch/sh/kernel/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/irq.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/irq.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: irq.c,v 1.2 2004/08/04 01:26:12 joff Exp $ * * linux/arch/sh/kernel/irq.c * @@ -246,7 +246,7 @@ 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 = desc->status & ~(IRQ_REPLAY | IRQ_WAITING | IRQ_INPROGRESS); status |= IRQ_PENDING; /* we _want_ to handle it */ /* Index: arch/sh/kernel/irq_imask.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/irq_imask.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/irq_imask.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/irq_imask.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: irq_imask.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: irq_imask.c,v 1.2 2004/08/04 01:26:12 joff Exp $ * * linux/arch/sh/kernel/irq_imask.c * Index: arch/sh/kernel/irq_intc2.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/irq_intc2.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/irq_intc2.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/irq_intc2.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -12,6 +12,8 @@ * Hitachi 7751 and the STM ST40 STB1. */ +#include +#include #include #include #include @@ -22,8 +24,11 @@ struct intc2_data { - unsigned int addr; /* Address of Interrupt Priority Register */ - int mask; /*Mask to apply */ + unsigned char msk_offset; + unsigned char msk_shift; +#ifdef CONFIG_CPU_SUBTYPE_ST40 + int (*clear_irq) (int); +#endif }; @@ -56,33 +61,34 @@ static void disable_intc2_irq(unsigned int irq) { - unsigned addr; - int offset=irq-INTC2_FIRST_IRQ; - unsigned val,flags; + int irq_offset = irq - INTC2_FIRST_IRQ; + int msk_shift, msk_offset; // Sanity check - if(offset<0 || offset>=NR_INTC2_IRQS) return; - - addr=intc2_data[offset].addr+INTC2_INTMSK_OFFSET; + if((irq_offset<0) || (irq_offset>=NR_INTC2_IRQS)) + return; - save_and_cli(flags); - val=ctrl_inl(addr); - val|=intc2_data[offset].mask; - ctrl_outl(val,addr); + msk_shift = intc2_data[irq_offset].msk_shift; + msk_offset = intc2_data[irq_offset].msk_offset; - restore_flags(flags); + ctrl_outl(1<=NR_INTC2_IRQS) return; + /* Sanity check */ + if((irq_offset<0) || (irq_offset>=NR_INTC2_IRQS)) + return; - ctrl_outl(intc2_data[offset].mask, - intc2_data[offset].addr+INTC2_INTMSKCLR_OFFSET); + msk_shift = intc2_data[irq_offset].msk_shift; + msk_offset = intc2_data[irq_offset].msk_offset; + ctrl_outl(1<=NR_INTC2_IRQS) { + if((irq_offset<0) || (irq_offset>=NR_INTC2_IRQS)) return; - } + disable_irq_nosync(irq); - /* Fill the data we need */ - intc2_data[offset].addr=addr; - intc2_data[offset].mask=1<irq, p->ipr_offset, p->ipr_shift, + p-> msk_offset, p->msk_shift, 13); + } +} + +/* Adds a termination callback to the interrupt */ +void intc2_add_clear_irq(int irq, int (*fn)(int)) +{ + if (irq < INTC2_FIRST_IRQ) + return; + intc2_data[irq - INTC2_FIRST_IRQ].clear_irq = fn; +} +#endif /* CONFIG_CPU_SUBTYPE_ST40 */ Index: arch/sh/kernel/irq_ipr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/irq_ipr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/irq_ipr.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/irq_ipr.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -1,15 +1,16 @@ -/* $Id: irq_ipr.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: irq_ipr.c,v 1.2 2004/08/04 01:26:12 joff 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,23 @@ 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 */ + +#ifdef CONFIG_CPU_SUBTYPE_ST40 + init_IRQ_intc2(); +#endif /* 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 +322,7 @@ if(d == 0) return irq; return PINT_IRQ_BASE + 8 + pint_map[d]; } +#endif return irq; } #endif Index: arch/sh/kernel/led_se.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/led_se.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/led_se.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/led_se.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -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) { Index: arch/sh/kernel/mach_7751se.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/mach_7751se.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/mach_7751se.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/mach_7751se.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -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, Index: arch/sh/kernel/mach_dc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/mach_dc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/mach_dc.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/mach_dc.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: mach_dc.c,v 1.1 2004/07/22 19:48:57 joff Exp $ + * $Id: mach_dc.c,v 1.2 2004/08/04 01:26:12 joff Exp $ * SEGA Dreamcast machine vector */ Index: arch/sh/kernel/pci-dc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/pci-dc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/pci-dc.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/pci-dc.c 4 Aug 2004 01:26:12 -0000 1.2 @@ -1,5 +1,5 @@ /* - $ $Id: pci-dc.c,v 1.1 2004/07/22 19:48:57 joff Exp $ + $ $Id: pci-dc.c,v 1.2 2004/08/04 01:26:12 joff Exp $ * Dreamcast PCI: Supports SEGA Broadband Adaptor only. */ Index: arch/sh/kernel/pci-sh7751.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/pci-sh7751.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/pci-sh7751.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/pci-sh7751.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -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)) { Index: arch/sh/kernel/pci_st40.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/pci_st40.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/pci_st40.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/pci_st40.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -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); } Index: arch/sh/kernel/pci_st40.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/pci_st40.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/pci_st40.h 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/pci_st40.h 4 Aug 2004 01:26:13 -0000 1.2 @@ -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__ */ Index: arch/sh/kernel/pcibios.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/pcibios.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/pcibios.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/pcibios.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: pcibios.c,v 1.1 2004/07/22 19:48:57 joff Exp $ + * $Id: pcibios.c,v 1.2 2004/08/04 01:26:13 joff Exp $ * * arch/sh/kernel/pcibios.c * Index: arch/sh/kernel/process.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/process.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/process.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/process.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: process.c,v 1.2 2004/08/04 01:26:13 joff 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); } Index: arch/sh/kernel/ptrace.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/ptrace.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/ptrace.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/ptrace.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ptrace.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: ptrace.c,v 1.2 2004/08/04 01:26:13 joff 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. */ @@ -365,6 +350,37 @@ break; } +#ifdef CONFIG_SH_DSP + case PTRACE_GETDSPREGS: { + unsigned long dp; + + ret = -EIO; + dp = ((unsigned long) child) + THREAD_SIZE - + sizeof(struct pt_dspregs); + if (*((int *) (dp - 4)) == SR_DSP) { + copy_to_user(addr, (void *) dp, + sizeof(struct pt_dspregs)); + ret = 0; + } + break; + } + + case PTRACE_SETDSPREGS: { + unsigned long dp; + int i; + + ret = -EIO; + dp = ((unsigned long) child) + THREAD_SIZE - + sizeof(struct pt_dspregs); + if (*((int *) (dp - 4)) == SR_DSP) { + copy_from_user((void *) dp, addr, + sizeof(struct pt_dspregs)); + ret = 0; + } + break; + } +#endif + default: ret = -EIO; break; Index: arch/sh/kernel/rtc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/rtc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/rtc.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/rtc.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -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 */ Index: arch/sh/kernel/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/setup.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/setup.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: setup.c,v 1.2 2004/08/04 01:26:13 joff 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 */ + Index: arch/sh/kernel/setup_cqreek.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/setup_cqreek.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/setup_cqreek.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/setup_cqreek.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: setup_cqreek.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: setup_cqreek.c,v 1.2 2004/08/04 01:26:13 joff Exp $ * * arch/sh/kernel/setup_cqreek.c * Index: arch/sh/kernel/setup_hd64461.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/setup_hd64461.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/setup_hd64461.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/setup_hd64461.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: setup_hd64461.c,v 1.1 2004/07/22 19:48:57 joff Exp $ + * $Id: setup_hd64461.c,v 1.2 2004/08/04 01:26:13 joff Exp $ * Copyright (C) 2000 YAEGASHI Takeshi * Hitachi HD64461 companion chip support */ Index: arch/sh/kernel/setup_hd64465.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/setup_hd64465.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/setup_hd64465.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/setup_hd64465.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: setup_hd64465.c,v 1.1 2004/07/22 19:48:57 joff Exp $ + * $Id: setup_hd64465.c,v 1.2 2004/08/04 01:26:13 joff Exp $ * * Setup and IRQ handling code for the HD64465 companion chip. * by Greg Banks Index: arch/sh/kernel/setup_se.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/setup_se.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/setup_se.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/setup_se.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: setup_se.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: setup_se.c,v 1.2 2004/08/04 01:26:13 joff 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 */ Index: arch/sh/kernel/sh_bios.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/sh_bios.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/sh_bios.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/sh_bios.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sh_bios.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: sh_bios.c,v 1.2 2004/08/04 01:26:13 joff Exp $ * * linux/arch/sh/kernel/sh_bios.c * C interface for trapping into the standard LinuxSH BIOS. Index: arch/sh/kernel/sh_ksyms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/sh_ksyms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/sh_ksyms.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/sh_ksyms.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -19,6 +19,7 @@ #include #include #include +#include #include extern void dump_thread(struct pt_regs *, struct user *); @@ -38,6 +39,7 @@ /* Networking helper routines. */ EXPORT_SYMBOL(csum_partial_copy); +EXPORT_SYMBOL(csum_partial_copy_generic); EXPORT_SYMBOL(strtok); EXPORT_SYMBOL(strpbrk); @@ -45,6 +47,7 @@ EXPORT_SYMBOL(strlen); EXPORT_SYMBOL(strnlen); EXPORT_SYMBOL(strchr); +EXPORT_SYMBOL(strrchr); EXPORT_SYMBOL(strcat); EXPORT_SYMBOL(strncat); @@ -56,6 +59,7 @@ #endif /* mem exports */ +EXPORT_SYMBOL(memscan); EXPORT_SYMBOL(memchr); EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memcpy_fromio); @@ -64,6 +68,7 @@ EXPORT_SYMBOL(memset_io); EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(memcmp); +EXPORT_SYMBOL(__copy_user); #ifdef CONFIG_VT EXPORT_SYMBOL(screen_info); @@ -77,7 +82,10 @@ EXPORT_SYMBOL(__up); EXPORT_SYMBOL(__down); EXPORT_SYMBOL(__down_interruptible); +EXPORT_SYMBOL(__down_trylock); +/* Delay loops */ +EXPORT_SYMBOL(__ndelay); EXPORT_SYMBOL(__udelay); EXPORT_SYMBOL(__const_udelay); @@ -102,3 +110,4 @@ EXPORT_SYMBOL(flush_dcache_page); #endif EXPORT_SYMBOL(flush_tlb_page); +EXPORT_SYMBOL(__xdiv64_32); Index: arch/sh/kernel/signal.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/signal.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/signal.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/signal.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: signal.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: signal.c,v 1.2 2004/08/04 01:26:13 joff 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,22 @@ * 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) */ +#define OR_R0_R0 0x200b /* or r0,r0 (insert to avoid hardware bug) */ + struct sigframe { struct sigcontext sc; unsigned long extramask[_NSIG_WORDS-1]; - char retcode[4]; + u16 retcode[8]; }; struct rt_sigframe { - struct siginfo *pinfo; - void *puc; struct siginfo info; struct ucontext uc; - char retcode[4]; + u16 retcode[8]; }; #if defined(__SH4__) @@ -196,39 +199,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 +250,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 +277,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 +293,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 +306,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 +314,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 +397,16 @@ 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(7), &frame->retcode[0]); + err |= __put_user(TRAP16, &frame->retcode[1]); + err |= __put_user(OR_R0_R0, &frame->retcode[2]); + err |= __put_user(OR_R0_R0, &frame->retcode[3]); + err |= __put_user(OR_R0_R0, &frame->retcode[4]); + err |= __put_user(OR_R0_R0, &frame->retcode[5]); + err |= __put_user(OR_R0_R0, &frame->retcode[6]); + err |= __put_user((__NR_sigreturn), &frame->retcode[7]); regs->pr = (unsigned long) frame->retcode; - err |= __put_user(code, (long *)(frame->retcode+0)); } if (err) @@ -423,6 +415,8 @@ /* Set up registers for signal handler */ regs->regs[15] = (unsigned long) frame; regs->regs[4] = signal; /* Arg for signal handler */ + regs->regs[5] = 0; + regs->regs[6] = (unsigned long) &frame->sc; regs->pc = (unsigned long) ka->sa.sa_handler; set_fs(USER_DS); @@ -433,6 +427,8 @@ #endif flush_cache_sigtramp(regs->pr); + if ((-regs->pr & (L1_CACHE_BYTES-1)) < sizeof(frame->retcode)) + flush_cache_sigtramp(regs->pr + L1_CACHE_BYTES); return; give_sigsegv: @@ -459,8 +455,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 +474,27 @@ 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(7), &frame->retcode[0]); + err |= __put_user(TRAP16, &frame->retcode[1]); + err |= __put_user(OR_R0_R0, &frame->retcode[2]); + err |= __put_user(OR_R0_R0, &frame->retcode[3]); + err |= __put_user(OR_R0_R0, &frame->retcode[4]); + err |= __put_user(OR_R0_R0, &frame->retcode[5]); + err |= __put_user(OR_R0_R0, &frame->retcode[6]); + err |= __put_user((__NR_rt_sigreturn), &frame->retcode[7]); 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); @@ -507,6 +504,8 @@ #endif flush_cache_sigtramp(regs->pr); + if ((-regs->pr & (L1_CACHE_BYTES-1)) < sizeof(frame->retcode)) + flush_cache_sigtramp(regs->pr + L1_CACHE_BYTES); return; give_sigsegv: @@ -521,10 +520,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 +538,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 +581,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 +689,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; } } Index: arch/sh/kernel/sys_sh.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/sys_sh.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/sys_sh.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/sys_sh.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -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); +} Index: arch/sh/kernel/time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/time.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/time.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,9 +1,10 @@ -/* $Id: time.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: time.c,v 1.2 2004/08/04 01:26:13 joff 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 + } Index: arch/sh/kernel/traps.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/kernel/traps.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/kernel/traps.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/kernel/traps.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,10 +1,11 @@ -/* $Id: traps.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: traps.c,v 1.2 2004/08/04 01:26:13 joff 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, \ @@ -38,10 +52,18 @@ { \ unsigned long error_code; \ \ + /* Check if it's a DSP instruction */ \ + if (is_dsp_inst(®s)) { \ + /* Enable DSP mode, and restart instruction. */ \ + regs.sr |= SR_DSP; \ + return; \ + } \ + \ asm volatile("stc r2_bank, %0": "=r" (error_code)); \ 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 +83,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 +323,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 +424,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 +452,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; } @@ -490,6 +534,28 @@ } } +#ifdef CONFIG_SH_DSP +/* + * SH-DSP support gerg@snapgear.com. + */ +int is_dsp_inst(struct pt_regs *regs) +{ + unsigned short inst; + + get_user(inst, ((unsigned short *) regs->pc)); + + inst &= 0xf000; + + /* Check for any type of DSP or support instruction */ + if ((inst == 0xf000) || (inst == 0x4000)) + return 1; + + return 0; +} +#else +#define is_dsp_inst(regs) (0) +#endif /* CONFIG_SH_DSP */ + DO_ERROR(12, SIGILL, "reserved instruction", reserved_inst, current) DO_ERROR(13, SIGILL, "illegal slot instruction", illegal_slot_inst, current) @@ -539,29 +605,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); } Index: arch/sh/lib/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/lib/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/lib/Makefile 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/lib/Makefile 4 Aug 2004 01:26:13 -0000 1.2 @@ -4,7 +4,7 @@ L_TARGET = lib.a obj-y = delay.o memcpy.o memset.o memmove.o memchr.o old-checksum.o \ - checksum.o strcasecmp.o strlen.o + checksum.o strcasecmp.o strlen.o udivdi3.o div64.o USE_STANDARD_AS_RULE := true Index: arch/sh/lib/checksum.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/lib/checksum.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/lib/checksum.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/lib/checksum.S 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: checksum.S,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: checksum.S,v 1.2 2004/08/04 01:26:13 joff Exp $ * * INET An implementation of the TCP/IP protocol suite for the LINUX * operating system. INET is implemented using the BSD Socket Index: arch/sh/lib/delay.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/lib/delay.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/lib/delay.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/lib/delay.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -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) */ +} Index: arch/sh/lib/memchr.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/lib/memchr.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/lib/memchr.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/lib/memchr.S 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: memchr.S,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: memchr.S,v 1.2 2004/08/04 01:26:13 joff Exp $ * * "memchr" implementation of SuperH * Index: arch/sh/lib/memcpy.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/lib/memcpy.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/lib/memcpy.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/lib/memcpy.S 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: memcpy.S,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: memcpy.S,v 1.2 2004/08/04 01:26:13 joff Exp $ * * "memcpy" implementation of SuperH * Index: arch/sh/lib/memmove.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/lib/memmove.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/lib/memmove.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/lib/memmove.S 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: memmove.S,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: memmove.S,v 1.2 2004/08/04 01:26:13 joff Exp $ * * "memmove" implementation of SuperH * Index: arch/sh/lib/memset.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/lib/memset.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/lib/memset.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/lib/memset.S 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: memset.S,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: memset.S,v 1.2 2004/08/04 01:26:13 joff Exp $ * * "memset" implementation of SuperH * Index: arch/sh/lib/strlen.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/lib/strlen.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/lib/strlen.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/lib/strlen.S 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: strlen.S,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: strlen.S,v 1.2 2004/08/04 01:26:13 joff Exp $ * * "strlen" implementation of SuperH * Index: arch/sh/mm/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/mm/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/mm/Makefile 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/mm/Makefile 4 Aug 2004 01:26:13 -0000 1.2 @@ -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 Index: arch/sh/mm/__clear_user_page-sh4.S =================================================================== RCS file: arch/sh/mm/__clear_user_page-sh4.S diff -N arch/sh/mm/__clear_user_page-sh4.S --- arch/sh/mm/__clear_user_page-sh4.S 22 Jul 2004 19:48:57 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,49 +0,0 @@ -/* $Id: __clear_user_page-sh4.S,v 1.1 2004/07/22 19:48:57 joff Exp $ - * - * __clear_user_page implementation of SuperH - * - * Copyright (C) 2001 Niibe Yutaka & Kaz Kojima - * - */ - -/* - * __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 - */ -#include -ENTRY(__clear_user_page) - mov r4,r6 - mov.w .L4096,r0 - 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 Index: arch/sh/mm/__copy_user_page-sh4.S =================================================================== RCS file: arch/sh/mm/__copy_user_page-sh4.S diff -N arch/sh/mm/__copy_user_page-sh4.S --- arch/sh/mm/__copy_user_page-sh4.S 22 Jul 2004 19:48:57 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,69 +0,0 @@ -/* $Id: __copy_user_page-sh4.S,v 1.1 2004/07/22 19:48:57 joff Exp $ - * - * __copy_user_page implementation of SuperH - * - * Copyright (C) 2001 Niibe Yutaka & Kaz Kojima - * - */ - -/* - * __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 - */ -#include -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 -.L4096: .word 4096 Index: arch/sh/mm/cache-sh3.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/mm/cache-sh3.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/mm/cache-sh3.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/mm/cache-sh3.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: cache-sh3.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: cache-sh3.c,v 1.2 2004/08/04 01:26:13 joff Exp $ * * linux/arch/sh/mm/cache-sh3.c * Index: arch/sh/mm/cache-sh4.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/mm/cache-sh4.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/mm/cache-sh4.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/mm/cache-sh4.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,9 +1,8 @@ -/* $Id: cache-sh4.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: cache-sh4.c,v 1.2 2004/08/04 01:26:13 joff 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 @@ -33,8 +32,17 @@ #define CCR_CACHE_ICI 0x0800 /* IC Invalidate */ #define CCR_CACHE_IIX 0x8000 /* IC Index Enable */ -/* Default CCR setup: 8k+16k-byte cache,P1-wb,enable */ -#define CCR_CACHE_VAL (CCR_CACHE_ICE|CCR_CACHE_CB|CCR_CACHE_OCE) + + +#if defined(CONFIG_SH_CACHE_ASSOC) +#define CCR_CACHE_EMODE 0x80000000 +/* CCR setup for associative mode: 16k+32k 2-way, P1 copy-back, enable */ +#define CCR_CACHE_VAL (CCR_CACHE_EMODE|CCR_CACHE_ENABLE|CCR_CACHE_CB) +#else +/* Default CCR setup: 8k+16k-byte cache, P1-copy-back, enable */ +#define CCR_CACHE_VAL (CCR_CACHE_ENABLE|CCR_CACHE_CB) +#endif + #define CCR_CACHE_INIT (CCR_CACHE_VAL|CCR_CACHE_OCI|CCR_CACHE_ICI) #define CCR_CACHE_ENABLE (CCR_CACHE_OCE|CCR_CACHE_ICE) @@ -42,8 +50,9 @@ #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_OC_WAY_SHIFT 14 #define CACHE_IC_WAY_SHIFT 13 #define CACHE_OC_ENTRY_SHIFT 5 #define CACHE_IC_ENTRY_SHIFT 5 @@ -53,13 +62,17 @@ #define CACHE_IC_NUM_ENTRIES 256 #define CACHE_OC_NUM_ENTRIES 512 +#define CACHE_NUM_WAYS 2 + 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; +#elif defined(CONFIG_CPU_SUBTYPE_SH4_202) + cpu_data->type = CPU_SH4202; #else #error Unknown SH4 CPU type #endif @@ -80,6 +93,26 @@ */ unsigned long addr, data; +#if defined(CONFIG_SH_CACHE_ASSOC) + unsigned long way; + + for (way = 0; way <= CACHE_NUM_WAYS; ++way) { + unsigned long waybit = way << CACHE_OC_WAY_SHIFT; + + for (addr = CACHE_OC_ADDRESS_ARRAY + waybit; + addr < (CACHE_OC_ADDRESS_ARRAY + waybit + + (CACHE_OC_NUM_ENTRIES << + CACHE_OC_ENTRY_SHIFT)); + addr += (1 << CACHE_OC_ENTRY_SHIFT)) { + + data = ctrl_inl(addr); + + if ((data & (CACHE_UPDATED|CACHE_VALID)) + == (CACHE_UPDATED|CACHE_VALID)) + ctrl_outl(data & ~CACHE_UPDATED, addr); + } + } +#else for (addr = CACHE_OC_ADDRESS_ARRAY; addr < (CACHE_OC_ADDRESS_ARRAY+ (CACHE_OC_NUM_ENTRIES << CACHE_OC_ENTRY_SHIFT)); @@ -89,6 +122,7 @@ == (CACHE_UPDATED|CACHE_VALID)) ctrl_outl(data & ~CACHE_UPDATED, addr); } +#endif } ctrl_outl(CCR_CACHE_INIT, CCR); @@ -109,7 +143,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 +211,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. * @@ -204,48 +249,36 @@ save_and_cli(flags); jump_to_P2(); ctrl_outl(0, index); /* Clear out Valid-bit */ + +#if defined(CONFIG_SH_CACHE_ASSOC) + /* Must invalidate both ways for associative cache */ + ctrl_outl(0, index | (1 << CACHE_IC_WAY_SHIFT)); +#endif + back_to_P1(); 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 +287,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 +370,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 +430,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 +438,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<>12]); } } + + +/****************************************************************************/ + +#if defined(CONFIG_SH_CACHE_ASSOC) +/* + * It is no possible to use the approach implement in clear_page.S when we + * are in 2-way set associative mode as it would only clear half the cache, in + * general. For the moment we simply implement it as a iteration through the + * cache flushing both ways, this in itself is not optimial as the delay latency + * for interupts is probably longer than necessary! + * + * benedict.gaster.superh.com + */ +void __flush_dcache_all(void) +{ + unsigned long flags; + unsigned long addr; + unsigned long way; + + save_and_cli(flags); +#if !defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH4_202) + jump_to_P2(); +#endif + /* Clear the U and V bits for each line and each way. On SH-4, this + * causes write-back if both U and V are set before the address write. + */ + for (way = 0; way <= 1; ++way) { + unsigned long waybit = way << CACHE_OC_WAY_SHIFT; + + /* Loop all the D-cache */ + for (addr = CACHE_OC_ADDRESS_ARRAY + waybit; + addr < (CACHE_OC_ADDRESS_ARRAY + waybit + + (CACHE_OC_NUM_ENTRIES << CACHE_OC_ENTRY_SHIFT)); + addr += (1 << CACHE_OC_ENTRY_SHIFT)) { + ctrl_outl(0, addr); + } + } + +#if !defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH4_202) + back_to_P1(); +#endif + restore_flags(flags); +} + +void flush_cache_4096_all(unsigned long start) +{ + unsigned long phys = PHYSADDR(start); + + /* Loop all the D-cache */ + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY, phys); +} +#endif + + + + + + +/****************************************************************************/ + +#if defined(CONFIG_SH_CACHE_ASSOC) +/* + * It is no possible to use the approach implement in clear_page.S when we + * are in 2-way set associative mode as it would only clear half the cache, in + * general. For the moment we simply implement it as a iteration through the + * cache flushing both ways, this in itself is not optimial as the delay latency + * for interupts is probably longer than necessary! + * + * benedict.gaster.superh.com + */ +void __flush_dcache_all(void) +{ + unsigned long flags; + unsigned long addr; + unsigned long way; + + save_and_cli(flags); +#if !defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH4_202) + jump_to_P2(); +#endif + /* Clear the U and V bits for each line and each way. On SH-4, this + * causes write-back if both U and V are set before the address write. + */ + for (way = 0; way <= 1; ++way) { + unsigned long waybit = way << CACHE_OC_WAY_SHIFT; + + /* Loop all the D-cache */ + for (addr = CACHE_OC_ADDRESS_ARRAY + waybit; + addr < (CACHE_OC_ADDRESS_ARRAY + waybit + + (CACHE_OC_NUM_ENTRIES << CACHE_OC_ENTRY_SHIFT)); + addr += (1 << CACHE_OC_ENTRY_SHIFT)) { + ctrl_outl(0, addr); + } + } + +#if !defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH4_202) + back_to_P1(); +#endif + restore_flags(flags); +} + +void flush_cache_4096_all(unsigned long start) +{ + unsigned long phys = PHYSADDR(start); + + /* Loop all the D-cache */ + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY, phys); +} +#endif + + + + + Index: arch/sh/mm/clear_page.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/mm/clear_page.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/mm/clear_page.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/mm/clear_page.S 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,10 +1,13 @@ -/* $Id: clear_page.S,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: clear_page.S,v 1.2 2004/08/04 01:26:13 joff Exp $ * - * clear_page implementation of SuperH + * __clear_user_page, __clear_user, clear_page implementation of SuperH * - * Copyright (C) 2001 Niibe Yutaka & Kaz Kojima + * Copyright (C) 2001 Kaz Kojima + * Copyright (C) 2001, 2002 Niibe Yutaka * */ +#include +#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,385 @@ 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 + +/* + * __flush_cache_4096 + * + * Flush the page at the specified physical address by writing to to + * the memory mapped address array. + * The offset into the memory mapped cache array selects the `color' of the + * virtual addresses which will be checked. + * Lower two bits of phys control the operation (invalidate/write-back). + * + * void __flush_cache_4096(unsigned long addr, unsigned long phys, + * unsigned long exec_offset); + * + * @addr: address of the memory mapped cache address array + * @phys: P1 address to be flushed + * @exec_offset: set to 0x20000000 if the flush needs to be executed from P2 + * (ie from uncached memory), otherwise 0. + */ + +/* + * Updated for the 2-way associative cache option on the SH-4-202 and SH7751R. + * + * The current implmentation simply adds an additional loop to flush the + * other way, but this could be improved by merging both loops to handle the + * flushing of boths ways with one iteration. + * + * benedict.gaster@superh.com + */ + +/* + * r4 --- addr + * r5 --- phys + * r6 --- exec_offset + */ + +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: +#if defined (CONFIG_SH_CACHE_ASSOC) + mov r5, r3 +#endif + .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 + +#if defined (CONFIG_SH_CACHE_ASSOC) + mov r4, r0 + mov #0x40, r1 ! set bit 14 in r0 to imply 2 way. + shll8 r1 + or r1, r0 + .rept 32 + mov.l r3,@r0 + mov.l r3,@(32,r0) + mov.l r3,@(r0,r6) + mov.l r3,@(r0,r7) + add r2,r3 + add r2,r0 + .endr +#endif + 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 + +! TODO : make this be dynamically selected based on CPU probing rather than assembled-in + +#if defined (CONFIG_SH_CACHE_ASSOC) + mov #0x40, r5 + shll8 r5 + add r4, r5 ! r5 = r4 + 16k +1: + ldc r2,sr ! set BL bit + movca.l r0,@r4 + movca.l r0,@r5 + ocbi @r4 + add #32,r4 + ocbi @r5 + add #32,r5 + movca.l r0,@r4 + movca.l r0,@r5 + ocbi @r4 + add #32,r4 + ocbi @r5 + add #32,r5 + movca.l r0,@r4 + movca.l r0,@r5 + ocbi @r4 + add #32,r4 + ocbi @r5 + add #32,r5 + movca.l r0,@r4 + movca.l r0,@r5 + ocbi @r4 + add #32, r4 + ocbi @r5 + ldc r1,sr ! restore SR + dt r3 + bf/s 1b + add #32,r5 + + rts + nop +#else +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 +#endif /* CONFIG_SH_CACHE_ASSOC */ + + .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 +! TODO : make this be dynamically selected based on CPU probing rather than assembled-in + +#if defined (CONFIG_SH_CACHE_ASSOC) + mov #0x40, r5 + shll8 r5 + add r4, r5 ! r5 = r4 + 16k +1: + ldc r2,sr ! set BL bit + movca.l r0,@r4 + movca.l r0,@r5 + ocbi @r4 + add #32,r4 + ocbi @r5 + add #32,r5 + movca.l r0,@r4 + movca.l r0,@r5 + ocbi @r4 + add #32,r4 + ocbi @r5 + add #32,r5 + movca.l r0,@r4 + movca.l r0,@r5 + ocbi @r4 + add #32,r4 + ocbi @r5 + add #32,r5 + movca.l r0,@r4 + movca.l r0,@r5 + ocbi @r4 + add #32,r4 + ocbi @r5 + + ldc r1,sr ! restore SR + dt r3 + bf/s 1b + add #32,r5 + + rts + nop +#else +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 +#endif + + .align 2 +2: .long 0xffffc000 +3: .long SYMBOL_NAME(empty_zero_page) +4: .long 0x10000000 ! BL bit + +#endif Index: arch/sh/mm/copy_page.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/mm/copy_page.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/mm/copy_page.S 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/mm/copy_page.S 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,10 +1,12 @@ -/* $Id: copy_page.S,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: copy_page.S,v 1.2 2004/08/04 01:26:13 joff 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 Index: arch/sh/mm/extable.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/mm/extable.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/mm/extable.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/mm/extable.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: extable.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: extable.c,v 1.2 2004/08/04 01:26:13 joff Exp $ * * linux/arch/sh/mm/extable.c * Taken from: Index: arch/sh/mm/fault.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/mm/fault.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/mm/fault.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/mm/fault.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: fault.c,v 1.2 2004/08/04 01:26:13 joff 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); Index: arch/sh/mm/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/mm/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/mm/init.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/mm/init.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: init.c,v 1.2 2004/08/04 01:26:13 joff 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(); } Index: arch/sh/mm/ioremap.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/mm/ioremap.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/mm/ioremap.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/mm/ioremap.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ioremap.c,v 1.1 2004/07/22 19:48:57 joff Exp $ +/* $Id: ioremap.c,v 1.2 2004/08/04 01:26:13 joff Exp $ * * arch/sh/mm/ioremap.c * Index: arch/sh/stboards/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sh/stboards/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sh/stboards/setup.c 22 Jul 2004 19:48:57 -0000 1.1 +++ arch/sh/stboards/setup.c 4 Aug 2004 01:26:13 -0000 1.2 @@ -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 Index: arch/sparc/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/Makefile 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/Makefile 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.1 2004/07/22 19:49:20 joff Exp $ +# $Id: Makefile,v 1.2 2004/08/04 01:26:14 joff Exp $ # sparc/Makefile # # Makefile for the architecture dependent flags and dependencies on the Index: arch/sparc/config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/config.in 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/config.in 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.1 2004/07/22 19:49:20 joff Exp $ +# $Id: config.in,v 1.2 2004/08/04 01:26:14 joff Exp $ # For a description of the syntax of this configuration file, # see Documentation/kbuild/config-language.txt. # @@ -30,6 +30,10 @@ bool 'Symmetric multi-processing support (does not work on sun4/sun4c)' CONFIG_SMP +if [ "$CONFIG_SMP" = "y" ]; then + int 'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32 +fi + # Identify this as a Sparc32 build define_bool CONFIG_SPARC32 y @@ -73,6 +77,7 @@ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC bool 'SunOS binary emulation' CONFIG_SUNOS_EMUL +bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER source drivers/parport/Config.in dep_tristate ' Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT endmenu @@ -123,14 +128,12 @@ 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 else define_bool CONFIG_IDE n - define_bool CONFIG_BLK_DEV_IDE_MODES n define_bool CONFIG_BLK_DEV_HD n fi @@ -210,8 +213,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 @@ -236,7 +239,7 @@ # if [ "$CONFIG_FDDI" = "y" ]; then # fi - if [ "$CONFIG_ATM" = "y" ]; then + if [ "$CONFIG_ATM" != "n" ]; then source drivers/atm/Config.in fi fi @@ -274,6 +277,9 @@ bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK fi +int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 + endmenu +source crypto/Config.in source lib/Config.in Index: arch/sparc/defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/defconfig 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/defconfig 4 Aug 2004 01:26:14 -0000 1.2 @@ -53,6 +53,7 @@ CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m CONFIG_SUNOS_EMUL=y +# CONFIG_OOM_KILLER is not set # # Parallel port support @@ -154,6 +155,17 @@ # CONFIG_SYN_COOKIES is not set CONFIG_IPV6=m # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=m +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +CONFIG_SCTP_HMAC_SHA1=y +# CONFIG_SCTP_HMAC_MD5 is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -191,7 +203,6 @@ # CONFIG_NET_PKTGEN=m # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -279,6 +290,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 @@ -288,6 +300,9 @@ # 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 is not set CONFIG_EXT3_FS=m CONFIG_JBD=m @@ -305,6 +320,9 @@ CONFIG_ISO9660_FS=m # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set CONFIG_MINIX_FS=m # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -324,6 +342,11 @@ # CONFIG_UDF_RW is not set CONFIG_UFS_FS=m # CONFIG_UFS_FS_WRITE is not set +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -332,13 +355,16 @@ CONFIG_INTERMEZZO_FS=m CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set # CONFIG_ROOT_NFS is not set CONFIG_NFSD=m # CONFIG_NFSD_V3 is not set +CONFIG_NFSD_TCP=y CONFIG_SUNRPC=y CONFIG_LOCKD=y CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_SMB_UNIX is not set # CONFIG_NCP_FS is not set # CONFIG_NCPFS_PACKET_SIGNING is not set # CONFIG_NCPFS_IOCTL_LOCKING is not set @@ -349,7 +375,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 @@ -415,4 +440,17 @@ # # Kernel hacking # -# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m Index: arch/sparc/boot/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/boot/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/boot/Makefile 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/boot/Makefile 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.1 2004/07/22 19:49:21 joff Exp $ +# $Id: Makefile,v 1.2 2004/08/04 01:26:14 joff Exp $ # Makefile for the Sparc boot stuff. # # Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/boot/btfixupprep.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/boot/btfixupprep.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/boot/btfixupprep.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/boot/btfixupprep.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: btfixupprep.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: btfixupprep.c,v 1.2 2004/08/04 01:26:14 joff Exp $ Simple utility to prepare vmlinux image for sparc. Resolves all BTFIXUP uses and settings and creates a special .s object to link to the image. @@ -167,6 +167,8 @@ } } else if (buffer[nbase+4] != '_') continue; + if (!strcmp (sect, ".text.exit")) + continue; if (strcmp (sect, ".text") && strcmp (sect, ".text.init") && strcmp (sect, ".fixup") && (strcmp (sect, "__ksymtab") || buffer[nbase+3] != 'f')) { if (buffer[nbase+3] == 'f') fprintf(stderr, "Wrong use of '%s' in '%s' section. It can be only used in .text, .text.init, .fixup and __ksymtab\n", buffer + shift, sect); Index: arch/sparc/boot/piggyback.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/boot/piggyback.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/boot/piggyback.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/boot/piggyback.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: piggyback.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: piggyback.c,v 1.2 2004/08/04 01:26:14 joff Exp $ Simple utility to make a single-image install kernel with initial ramdisk for Sparc tftpbooting without need to set up nfs. Index: arch/sparc/kernel/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/Makefile 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/Makefile 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.1 2004/07/22 19:49:21 joff Exp $ +# $Id: Makefile,v 1.2 2004/08/04 01:26:14 joff Exp $ # Makefile for the linux kernel. # # Note! Dependencies are done automagically by 'make dep', which also @@ -51,15 +51,11 @@ @echo "" >> asm_offsets.h @echo "#include " >> asm_offsets.h @echo "" >> asm_offsets.h - @echo "#ifndef CONFIG_SMP" >> asm_offsets.h - @echo "" >> asm_offsets.h @echo "#include " > tmp.c - @echo "#undef CONFIG_SMP" >> tmp.c @echo "#include " >> tmp.c $(CPP) $(CPPFLAGS) tmp.c -o tmp.i @echo "/* Automatically generated. Do not edit. */" > check_asm_data.c @echo "#include " >> check_asm_data.c - @echo "#undef CONFIG_SMP" >> check_asm_data.c @echo "#include " >> check_asm_data.c @echo "unsigned int check_asm_data[] = {" >> check_asm_data.c $(SH) ./check_asm.sh -data task tmp.i check_asm_data.c @@ -83,42 +79,6 @@ ./check_asm >> asm_offsets.h @rm -f check_asm check_asm.c @echo "" >> asm_offsets.h - @echo "#else /* CONFIG_SMP */" >> asm_offsets.h - @echo "" >> asm_offsets.h - @echo "#include " > tmp.c - @echo "#undef CONFIG_SMP" >> tmp.c - @echo "#define CONFIG_SMP 1" >> tmp.c - @echo "#include " >> tmp.c - $(CPP) $(CPPFLAGS) tmp.c -o tmp.i - @echo "/* Automatically generated. Do not edit. */" > check_asm_data.c - @echo "#include " >> check_asm_data.c - @echo "#undef CONFIG_SMP" >> check_asm_data.c - @echo "#define CONFIG_SMP 1" >> check_asm_data.c - @echo "#include " >> check_asm_data.c - @echo "unsigned int check_asm_data[] = {" >> check_asm_data.c - $(SH) ./check_asm.sh -data task tmp.i check_asm_data.c - $(SH) ./check_asm.sh -data mm tmp.i check_asm_data.c - $(SH) ./check_asm.sh -data thread tmp.i check_asm_data.c - @echo '};' >> check_asm_data.c - $(CC) $(CFLAGS) -S -o check_asm_data.s check_asm_data.c - @echo "/* Automatically generated. Do not edit. */" > check_asm.c - @echo 'extern int printf(const char *fmt, ...);' >>check_asm.c - @echo "unsigned int check_asm_data[] = {" >> check_asm.c - $(SH) ./check_asm.sh -ints check_asm_data.s check_asm.c - @echo "};" >> check_asm.c - @echo 'int main(void) {' >> check_asm.c - @echo 'int i = 0;' >> check_asm.c - $(SH) ./check_asm.sh -printf task tmp.i check_asm.c - $(SH) ./check_asm.sh -printf mm tmp.i check_asm.c - $(SH) ./check_asm.sh -printf thread tmp.i check_asm.c - @echo 'return 0; }' >> check_asm.c - @rm -f tmp.[ci] check_asm_data.[cs] - $(HOSTCC) -o check_asm check_asm.c - ./check_asm >> asm_offsets.h - @rm -f check_asm check_asm.c - @echo "" >> asm_offsets.h - @echo "#endif /* CONFIG_SMP */" >> asm_offsets.h - @echo "" >> asm_offsets.h @echo "#endif /* __ASM_OFFSETS_H__ */" >> asm_offsets.h @if test -r $(HPATH)/asm/asm_offsets.h; then \ if cmp -s asm_offsets.h $(HPATH)/asm/asm_offsets.h; then \ Index: arch/sparc/kernel/check_asm.sh =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/check_asm.sh,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/check_asm.sh 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/check_asm.sh 4 Aug 2004 01:26:14 -0000 1.2 @@ -11,7 +11,7 @@ echo " sizeof(struct $2_struct)," >> $4 ;; -ints) - sed -n -e '/check_asm_data:/,/\.size/p' <$2 | sed -e 's/check_asm_data://' -e 's/\.size.*//' -e 's/\.ident.*//' -e 's/\.global.*//' -e 's/\.long[ ]\([0-9]*\)/\1,/' >>$3 + sed -n -e '/check_asm_data:/,/\.size/p' <$2 | sed -e 's/check_asm_data://' -e 's/\.size.*//' -e 's/\.ident.*//' -e 's/\.global.*//' -e 's/\.section.*//' -e 's/\.long[ ]\([0-9]*\)/\1,/' >>$3 ;; *) exit 1 Index: arch/sparc/kernel/devices.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/devices.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/devices.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/devices.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -15,7 +15,7 @@ #include #include -struct prom_cpuinfo linux_cpus[32]; +struct prom_cpuinfo linux_cpus[NR_CPUS]; int linux_num_cpus = 0; extern void cpu_probe(void); @@ -72,7 +72,7 @@ if (linux_num_cpus == 0) { printk("No CPU nodes found, cannot continue.\n"); /* Probably a sun4e, Sun is trying to trick us ;-) */ - halt(); + prom_halt(); } printk("Found %d CPU prom device tree node(s).\n", linux_num_cpus); } Index: arch/sparc/kernel/ebus.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/ebus.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/ebus.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/ebus.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ebus.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: ebus.c,v 1.2 2004/08/04 01:26:14 joff Exp $ * ebus.c: PCI to EBus bridge device. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) Index: arch/sparc/kernel/entry.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/entry.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/entry.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/entry.S 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: entry.S,v 1.2 2004/08/04 01:26:14 joff Exp $ * arch/sparc/kernel/entry.S: Sparc trap low-level entry points. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/kernel/errtbls.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/errtbls.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/errtbls.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/errtbls.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: errtbls.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: errtbls.c,v 1.2 2004/08/04 01:26:14 joff Exp $ * errtbls.c: Error number conversion tables between various syscall * OS semantics. * Index: arch/sparc/kernel/etrap.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/etrap.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/etrap.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/etrap.S 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: etrap.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: etrap.S,v 1.2 2004/08/04 01:26:14 joff Exp $ * etrap.S: Sparc trap window preparation for entry into the * Linux kernel. * Index: arch/sparc/kernel/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/head.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/head.S 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: head.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: head.S,v 1.2 2004/08/04 01:26:14 joff Exp $ * head.S: The initial boot code for the Sparc port of Linux. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/kernel/idprom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/idprom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/idprom.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/idprom.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: idprom.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: idprom.c,v 1.2 2004/08/04 01:26:14 joff Exp $ * idprom.c: Routines to load the idprom into kernel addresses and * interpret the data contained within. * Index: arch/sparc/kernel/ioport.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/ioport.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/ioport.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/ioport.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ioport.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: ioport.c,v 1.2 2004/08/04 01:26:14 joff Exp $ * ioport.c: Simple io mapping allocator. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -760,7 +760,7 @@ default: printk("ioport_init: cpu type %d is unknown.\n", sparc_cpu_model); - halt(); + prom_halt(); }; } Index: arch/sparc/kernel/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/irq.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/irq.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: irq.c,v 1.2 2004/08/04 01:26:14 joff Exp $ * arch/sparc/kernel/irq.c: Interrupt request handling routines. On the * Sparc the IRQ's are basically 'cast in stone' * and you are supposed to probe the prom's device Index: arch/sparc/kernel/muldiv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/muldiv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/muldiv.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/muldiv.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: muldiv.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: muldiv.c,v 1.2 2004/08/04 01:26:14 joff Exp $ * muldiv.c: Hardware multiply/division illegal instruction trap * for sun4c/sun4 (which do not have those instructions) * Index: arch/sparc/kernel/pcic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/pcic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/pcic.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/pcic.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: pcic.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: pcic.c,v 1.2 2004/08/04 01:26:14 joff Exp $ * pcic.c: Sparc/PCI controller support * * Copyright (C) 1998 V. Roganov and G. Raiko Index: arch/sparc/kernel/process.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/process.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/process.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/process.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: process.c,v 1.2 2004/08/04 01:26:14 joff Exp $ * linux/arch/sparc/kernel/process.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/kernel/rtrap.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/rtrap.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/rtrap.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/rtrap.S 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: rtrap.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: rtrap.S,v 1.2 2004/08/04 01:26:14 joff Exp $ * rtrap.S: Return from Sparc trap low-level code. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/kernel/semaphore.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/semaphore.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/semaphore.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/semaphore.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: semaphore.c,v 1.1 2004/07/22 19:49:21 joff Exp $ */ +/* $Id: semaphore.c,v 1.2 2004/08/04 01:26:14 joff Exp $ */ /* sparc32 semaphore implementation, based on i386 version */ Index: arch/sparc/kernel/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/setup.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/setup.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: setup.c,v 1.2 2004/08/04 01:26:14 joff Exp $ * linux/arch/sparc/kernel/setup.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/kernel/signal.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/signal.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/signal.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/signal.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: signal.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: signal.c,v 1.2 2004/08/04 01:26:14 joff Exp $ * linux/arch/sparc/kernel/signal.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -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); Index: arch/sparc/kernel/sparc-stub.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/sparc-stub.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/sparc-stub.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/sparc-stub.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sparc-stub.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: sparc-stub.c,v 1.2 2004/08/04 01:26:14 joff Exp $ * sparc-stub.c: KGDB support for the Linux kernel. * * Modifications to run under Linux Index: arch/sparc/kernel/sparc_ksyms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/sparc_ksyms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/sparc_ksyms.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/sparc_ksyms.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sparc_ksyms.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: sparc_ksyms.c,v 1.2 2004/08/04 01:26:14 joff Exp $ * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/kernel/sun4d_irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/sun4d_irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/sun4d_irq.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/sun4d_irq.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sun4d_irq.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: sun4d_irq.c,v 1.2 2004/08/04 01:26:14 joff Exp $ * arch/sparc/kernel/sun4d_irq.c: * SS1000/SC2000 interrupt handling. * Index: arch/sparc/kernel/sun4d_smp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/sun4d_smp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/sun4d_smp.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/sun4d_smp.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -351,11 +351,11 @@ unsigned long a3 asm("i3") = arg3; unsigned long a4 asm("i4") = arg4; unsigned long a5 asm("i5") = arg5; - - __asm__ __volatile__(" - std %0, [%6] - std %2, [%6 + 8] - std %4, [%6 + 16]" : : + + __asm__ __volatile__( + "std %0, [%6]\n\t" + "std %2, [%6 + 8]\n\t" + "std %4, [%6 + 16]\n\t" : : "r"(f), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5), "r" (&ccall_info.func)); } Index: arch/sparc/kernel/sunos_asm.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/sunos_asm.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/sunos_asm.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/sunos_asm.S 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sunos_asm.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: sunos_asm.S,v 1.2 2004/08/04 01:26:14 joff Exp $ * sunos_asm.S: SunOS system calls which must have a low-level * entry point to operate correctly. * Index: arch/sparc/kernel/sunos_ioctl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/sunos_ioctl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/sunos_ioctl.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/sunos_ioctl.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sunos_ioctl.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: sunos_ioctl.c,v 1.2 2004/08/04 01:26:14 joff Exp $ * sunos_ioctl.c: The Linux Operating system: SunOS ioctl compatibility. * * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) Index: arch/sparc/kernel/sys_sparc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/sys_sparc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/sys_sparc.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/sys_sparc.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sys_sparc.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: sys_sparc.c,v 1.2 2004/08/04 01:26:14 joff Exp $ * linux/arch/sparc/kernel/sys_sparc.c * * This file contains various random system calls that @@ -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); Index: arch/sparc/kernel/sys_sunos.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/sys_sunos.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/sys_sunos.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/sys_sunos.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sys_sunos.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: sys_sunos.c,v 1.2 2004/08/04 01:26:14 joff Exp $ * sys_sunos.c: SunOS specific syscall compatibility support. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -193,7 +193,7 @@ * fool it, but this should catch most mistakes. */ freepages = atomic_read(&buffermem_pages) >> PAGE_SHIFT; - freepages += atomic_read(&page_cache_size); + freepages += page_cache_size; freepages >>= 1; freepages += nr_free_pages(); freepages += nr_swap_pages; @@ -688,8 +688,8 @@ static int sunos_nfs_mount(char *dir_name, int linux_flags, void *data) { - int server_fd; - char *the_name; + int server_fd, err; + char *the_name, *mount_page; struct nfs_mount_data linux_nfs_mount; struct sunos_nfs_mount_args sunos_mount; @@ -742,7 +742,16 @@ linux_nfs_mount.hostname [255] = 0; putname (the_name); - return do_mount ("", dir_name, "nfs", linux_flags, &linux_nfs_mount); + mount_page = (char *) get_zeroed_page(GFP_KERNEL); + if (!mount_page) + return -ENOMEM; + + memcpy(mount_page, &linux_nfs_mount, sizeof(linux_nfs_mount)); + + err = do_mount("", dir_name, "nfs", linux_flags, mount_page); + + free_page((unsigned long) mount_page); + return err; } asmlinkage int Index: arch/sparc/kernel/systbls.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/systbls.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/systbls.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/systbls.S 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: systbls.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: systbls.S,v 1.2 2004/08/04 01:26:14 joff Exp $ * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * Index: arch/sparc/kernel/time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/time.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/time.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: time.c,v 1.2 2004/08/04 01:26:14 joff Exp $ * linux/arch/sparc/kernel/time.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/kernel/trampoline.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/trampoline.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/trampoline.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/trampoline.S 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: trampoline.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: trampoline.S,v 1.2 2004/08/04 01:26:14 joff Exp $ * trampoline.S: SMP cpu boot-up trampoline code. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/kernel/traps.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/traps.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/traps.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/traps.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: traps.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: traps.c,v 1.2 2004/08/04 01:26:14 joff Exp $ * arch/sparc/kernel/traps.c * * Copyright 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/kernel/unaligned.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/unaligned.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/unaligned.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/unaligned.c 4 Aug 2004 01:26:14 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: unaligned.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: unaligned.c,v 1.2 2004/08/04 01:26:14 joff Exp $ * unaligned.c: Unaligned load/store trap handling with special * cases for the kernel to do them more quickly. * Index: arch/sparc/kernel/wof.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/wof.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/wof.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/wof.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: wof.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: wof.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * wof.S: Sparc window overflow handler. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/kernel/wuf.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/kernel/wuf.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/kernel/wuf.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/kernel/wuf.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: wuf.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: wuf.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * wuf.S: Window underflow trap handler for the Sparc. * * Copyright (C) 1995 David S. Miller Index: arch/sparc/lib/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/lib/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/lib/Makefile 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/lib/Makefile 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.1 2004/07/22 19:49:20 joff Exp $ +# $Id: Makefile,v 1.2 2004/08/04 01:26:15 joff Exp $ # Makefile for Sparc library files.. # Index: arch/sparc/lib/ashldi3.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/lib/ashldi3.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/lib/ashldi3.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/lib/ashldi3.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ashldi3.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: ashldi3.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * ashldi3.S: GCC emits these for certain drivers playing * with long longs. * Index: arch/sparc/lib/ashrdi3.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/lib/ashrdi3.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/lib/ashrdi3.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/lib/ashrdi3.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ashrdi3.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: ashrdi3.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * ashrdi3.S: The filesystem code creates all kinds of references to * this little routine on the sparc with gcc. * Index: arch/sparc/lib/blockops.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/lib/blockops.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/lib/blockops.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/lib/blockops.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: blockops.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: blockops.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * blockops.S: Common block zero optimized routines. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/lib/checksum.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/lib/checksum.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/lib/checksum.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/lib/checksum.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -145,36 +145,39 @@ .globl C_LABEL(__csum_partial_copy_start), C_LABEL(__csum_partial_copy_end) C_LABEL(__csum_partial_copy_start): -#define EX(x,y,a,b,z) \ +/* Work around cpp -rob */ +#define ALLOC #alloc +#define EXECINSTR #execinstr +#define EX(x,y,a,b) \ 98: x,y; \ - .section .fixup,z##alloc,z##execinstr; \ + .section .fixup,ALLOC,EXECINSTR; \ .align 4; \ 99: ba 30f; \ a, b, %o3; \ - .section __ex_table,z##alloc; \ + .section __ex_table,ALLOC; \ .align 4; \ .word 98b, 99b; \ .text; \ .align 4 -#define EX2(x,y,z) \ +#define EX2(x,y) \ 98: x,y; \ - .section __ex_table,z##alloc; \ + .section __ex_table,ALLOC; \ .align 4; \ .word 98b, 30f; \ .text; \ .align 4 -#define EX3(x,y,z) \ +#define EX3(x,y) \ 98: x,y; \ - .section __ex_table,z##alloc; \ + .section __ex_table,ALLOC; \ .align 4; \ .word 98b, 96f; \ .text; \ .align 4 -#define EXT(start,end,handler,z) \ - .section __ex_table,z##alloc; \ +#define EXT(start,end,handler) \ + .section __ex_table,ALLOC; \ .align 4; \ .word start, 0, end, handler; \ .text; \ @@ -247,21 +250,21 @@ cc_end_cruft: be 1f andcc %o3, 4, %g0 - EX(ldd [%o0 + 0x00], %g2, and %o3, 0xf,#) + EX(ldd [%o0 + 0x00], %g2, and %o3, 0xf) add %o1, 8, %o1 addcc %g2, %g7, %g7 add %o0, 8, %o0 addxcc %g3, %g7, %g7 - EX2(st %g2, [%o1 - 0x08],#) + EX2(st %g2, [%o1 - 0x08]) addx %g0, %g7, %g7 andcc %o3, 4, %g0 - EX2(st %g3, [%o1 - 0x04],#) + EX2(st %g3, [%o1 - 0x04]) 1: be 1f andcc %o3, 3, %o3 - EX(ld [%o0 + 0x00], %g2, add %o3, 4,#) + EX(ld [%o0 + 0x00], %g2, add %o3, 4) add %o1, 4, %o1 addcc %g2, %g7, %g7 - EX2(st %g2, [%o1 - 0x04],#) + EX2(st %g2, [%o1 - 0x04]) addx %g0, %g7, %g7 andcc %o3, 3, %g0 add %o0, 4, %o0 @@ -271,14 +274,14 @@ subcc %o3, 2, %o3 b 4f or %g0, %g0, %o4 -2: EX(lduh [%o0 + 0x00], %o4, add %o3, 2,#) +2: EX(lduh [%o0 + 0x00], %o4, add %o3, 2) add %o0, 2, %o0 - EX2(sth %o4, [%o1 + 0x00],#) + EX2(sth %o4, [%o1 + 0x00]) be 6f add %o1, 2, %o1 sll %o4, 16, %o4 -4: EX(ldub [%o0 + 0x00], %o5, add %g0, 1,#) - EX2(stb %o5, [%o1 + 0x00],#) +4: EX(ldub [%o0 + 0x00], %o5, add %g0, 1) + EX2(stb %o5, [%o1 + 0x00]) sll %o5, 8, %o5 or %o5, %o4, %o4 6: addcc %o4, %g7, %g7 @@ -295,9 +298,9 @@ andcc %o0, 0x2, %g0 be 1f andcc %o0, 0x4, %g0 - EX(lduh [%o0 + 0x00], %g4, add %g1, 0,#) + EX(lduh [%o0 + 0x00], %g4, add %g1, 0) sub %g1, 2, %g1 - EX2(sth %g4, [%o1 + 0x00],#) + EX2(sth %g4, [%o1 + 0x00]) add %o0, 2, %o0 sll %g4, 16, %g4 addcc %g4, %g7, %g7 @@ -311,9 +314,9 @@ or %g3, %g7, %g7 1: be 3f andcc %g1, 0xffffff80, %g0 - EX(ld [%o0 + 0x00], %g4, add %g1, 0,#) + EX(ld [%o0 + 0x00], %g4, add %g1, 0) sub %g1, 4, %g1 - EX2(st %g4, [%o1 + 0x00],#) + EX2(st %g4, [%o1 + 0x00]) add %o0, 4, %o0 addcc %g4, %g7, %g7 add %o1, 4, %o1 @@ -342,7 +345,7 @@ CSUMCOPY_BIGCHUNK(%o0,%o1,%g7,0x20,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3) CSUMCOPY_BIGCHUNK(%o0,%o1,%g7,0x40,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3) CSUMCOPY_BIGCHUNK(%o0,%o1,%g7,0x60,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3) -10: EXT(5b, 10b, 20f,#) ! note for exception handling +10: EXT(5b, 10b, 20f) ! note for exception handling sub %g1, 128, %g1 ! detract from length addx %g0, %g7, %g7 ! add in last carry bit andcc %g1, 0xffffff80, %g0 ! more to csum? @@ -367,7 +370,7 @@ CSUMCOPY_LASTCHUNK(%o0,%o1,%g7,0x28,%g2,%g3,%g4,%g5) CSUMCOPY_LASTCHUNK(%o0,%o1,%g7,0x18,%g2,%g3,%g4,%g5) CSUMCOPY_LASTCHUNK(%o0,%o1,%g7,0x08,%g2,%g3,%g4,%g5) -12: EXT(cctbl, 12b, 22f,#) ! note for exception table handling +12: EXT(cctbl, 12b, 22f) ! note for exception table handling addx %g0, %g7, %g7 andcc %o3, 0xf, %g0 ! check for low bits set ccte: bne cc_end_cruft ! something left, handle it out of band @@ -378,7 +381,7 @@ CSUMCOPY_BIGCHUNK_ALIGNED(%o0,%o1,%g7,0x20,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3) CSUMCOPY_BIGCHUNK_ALIGNED(%o0,%o1,%g7,0x40,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3) CSUMCOPY_BIGCHUNK_ALIGNED(%o0,%o1,%g7,0x60,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3) -11: EXT(ccdbl, 11b, 21f,#) ! note for exception table handling +11: EXT(ccdbl, 11b, 21f) ! note for exception table handling sub %g1, 128, %g1 ! detract from length addx %g0, %g7, %g7 ! add in last carry bit andcc %g1, 0xffffff80, %g0 ! more to csum? @@ -395,9 +398,9 @@ be,a 1f srl %g1, 1, %g4 sub %g1, 1, %g1 - EX(ldub [%o0], %g5, add %g1, 1,#) + EX(ldub [%o0], %g5, add %g1, 1) add %o0, 1, %o0 - EX2(stb %g5, [%o1],#) + EX2(stb %g5, [%o1]) srl %g1, 1, %g4 add %o1, 1, %o1 1: cmp %g4, 0 @@ -406,34 +409,34 @@ andcc %o0, 2, %g0 be,a 1f srl %g4, 1, %g4 - EX(lduh [%o0], %o4, add %g1, 0,#) + EX(lduh [%o0], %o4, add %g1, 0) sub %g1, 2, %g1 srl %o4, 8, %g2 sub %g4, 1, %g4 - EX2(stb %g2, [%o1],#) + EX2(stb %g2, [%o1]) add %o4, %g5, %g5 - EX2(stb %o4, [%o1 + 1],#) + EX2(stb %o4, [%o1 + 1]) add %o0, 2, %o0 srl %g4, 1, %g4 add %o1, 2, %o1 1: cmp %g4, 0 be,a 2f andcc %g1, 2, %g0 - EX3(ld [%o0], %o4,#) + EX3(ld [%o0], %o4) 5: srl %o4, 24, %g2 srl %o4, 16, %g3 - EX2(stb %g2, [%o1],#) + EX2(stb %g2, [%o1]) srl %o4, 8, %g2 - EX2(stb %g3, [%o1 + 1],#) + EX2(stb %g3, [%o1 + 1]) add %o0, 4, %o0 - EX2(stb %g2, [%o1 + 2],#) + EX2(stb %g2, [%o1 + 2]) addcc %o4, %g5, %g5 - EX2(stb %o4, [%o1 + 3],#) + EX2(stb %o4, [%o1 + 3]) addx %g5, %g0, %g5 ! I am now to lazy to optimize this (question it add %o1, 4, %o1 ! is worthy). Maybe some day - with the sll/srl subcc %g4, 1, %g4 ! tricks bne,a 5b - EX3(ld [%o0], %o4,#) + EX3(ld [%o0], %o4) sll %g5, 16, %g2 srl %g5, 16, %g5 srl %g2, 16, %g2 @@ -441,19 +444,19 @@ add %g2, %g5, %g5 2: be,a 3f andcc %g1, 1, %g0 - EX(lduh [%o0], %o4, and %g1, 3,#) + EX(lduh [%o0], %o4, and %g1, 3) andcc %g1, 1, %g0 srl %o4, 8, %g2 add %o0, 2, %o0 - EX2(stb %g2, [%o1],#) + EX2(stb %g2, [%o1]) add %g5, %o4, %g5 - EX2(stb %o4, [%o1 + 1],#) + EX2(stb %o4, [%o1 + 1]) add %o1, 2, %o1 3: be,a 1f sll %g5, 16, %o4 - EX(ldub [%o0], %g2, add %g0, 1,#) + EX(ldub [%o0], %g2, add %g0, 1) sll %g2, 8, %o4 - EX2(stb %g2, [%o1],#) + EX2(stb %g2, [%o1]) add %g5, %o4, %g5 sll %g5, 16, %o4 1: addcc %o4, %g5, %g5 Index: arch/sparc/lib/copy_user.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/lib/copy_user.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/lib/copy_user.S 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/lib/copy_user.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -16,41 +16,44 @@ #include #include -#define EX(x,y,a,b,z) \ +/* Work around cpp -rob */ +#define ALLOC #alloc +#define EXECINSTR #execinstr +#define EX(x,y,a,b) \ 98: x,y; \ - .section .fixup,z##alloc,z##execinstr; \ + .section .fixup,ALLOC,EXECINSTR; \ .align 4; \ 99: ba fixupretl; \ a, b, %g3; \ - .section __ex_table,z##alloc; \ + .section __ex_table,ALLOC; \ .align 4; \ .word 98b, 99b; \ .text; \ .align 4 -#define EX2(x,y,c,d,e,a,b,z) \ +#define EX2(x,y,c,d,e,a,b) \ 98: x,y; \ - .section .fixup,z##alloc,z##execinstr; \ + .section .fixup,ALLOC,EXECINSTR; \ .align 4; \ 99: c, d, e; \ ba fixupretl; \ a, b, %g3; \ - .section __ex_table,z##alloc; \ + .section __ex_table,ALLOC; \ .align 4; \ .word 98b, 99b; \ .text; \ .align 4 -#define EXO2(x,y,z) \ -98: x,##y; \ - .section __ex_table,z##alloc; \ +#define EXO2(x,y) \ +98: x, y; \ + .section __ex_table,ALLOC; \ .align 4; \ .word 98b, 97f; \ .text; \ .align 4 -#define EXT(start,end,handler,z) \ - .section __ex_table,z##alloc; \ +#define EXT(start,end,handler) \ + .section __ex_table,ALLOC; \ .align 4; \ .word start, 0, end, handler; \ .text; \ @@ -121,23 +124,23 @@ be 4f andcc %o1, 2, %g0 - EXO2(ldub [%o1], %g2,#) + EXO2(ldub [%o1], %g2) add %o1, 1, %o1 - EXO2(stb %g2, [%o0],#) + EXO2(stb %g2, [%o0]) sub %o2, 1, %o2 bne 3f add %o0, 1, %o0 - EXO2(lduh [%o1], %g2,#) + EXO2(lduh [%o1], %g2) add %o1, 2, %o1 - EXO2(sth %g2, [%o0],#) + EXO2(sth %g2, [%o0]) sub %o2, 2, %o2 b 3f add %o0, 2, %o0 4: - EXO2(lduh [%o1], %g2,#) + EXO2(lduh [%o1], %g2) add %o1, 2, %o1 - EXO2(sth %g2, [%o0],#) + EXO2(sth %g2, [%o0]) sub %o2, 2, %o2 b 3f add %o0, 2, %o0 @@ -160,9 +163,9 @@ be 2f mov %o2, %g1 - EXO2(ld [%o1], %o4,#) + EXO2(ld [%o1], %o4) sub %g1, 4, %g1 - EXO2(st %o4, [%o0],#) + EXO2(st %o4, [%o0]) add %o1, 4, %o1 add %o0, 4, %o0 2: @@ -177,7 +180,7 @@ MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5) MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5) 80: - EXT(5b, 80b, 50f,#) + EXT(5b, 80b, 50f) subcc %g7, 128, %g7 add %o1, 128, %o1 bne 5b @@ -204,37 +207,37 @@ MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5) MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5) copy_user_table_end: - EXT(copy_user_table, copy_user_table_end, 51f,#) + EXT(copy_user_table, copy_user_table_end, 51f) be copy_user_last7 andcc %g1, 4, %g0 - EX(ldd [%o1], %g2, and %g1, 0xf,#) + EX(ldd [%o1], %g2, and %g1, 0xf) add %o0, 8, %o0 add %o1, 8, %o1 - EX(st %g2, [%o0 - 0x08], and %g1, 0xf,#) - EX2(st %g3, [%o0 - 0x04], and %g1, 0xf, %g1, sub %g1, 4,#) + EX(st %g2, [%o0 - 0x08], and %g1, 0xf) + EX2(st %g3, [%o0 - 0x04], and %g1, 0xf, %g1, sub %g1, 4) copy_user_last7: be 1f andcc %g1, 2, %g0 - EX(ld [%o1], %g2, and %g1, 7,#) + EX(ld [%o1], %g2, and %g1, 7) add %o1, 4, %o1 - EX(st %g2, [%o0], and %g1, 7,#) + EX(st %g2, [%o0], and %g1, 7) add %o0, 4, %o0 1: be 1f andcc %g1, 1, %g0 - EX(lduh [%o1], %g2, and %g1, 3,#) + EX(lduh [%o1], %g2, and %g1, 3) add %o1, 2, %o1 - EX(sth %g2, [%o0], and %g1, 3,#) + EX(sth %g2, [%o0], and %g1, 3) add %o0, 2, %o0 1: be 1f nop - EX(ldub [%o1], %g2, add %g0, 1,#) - EX(stb %g2, [%o0], add %g0, 1,#) + EX(ldub [%o1], %g2, add %g0, 1) + EX(stb %g2, [%o0], add %g0, 1) 1: retl clr %o0 @@ -245,7 +248,7 @@ MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5) MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5) 81: - EXT(ldd_std, 81b, 52f,#) + EXT(ldd_std, 81b, 52f) subcc %g7, 128, %g7 add %o1, 128, %o1 bne ldd_std @@ -274,9 +277,9 @@ be 10f nop - EXO2(ldub [%o1], %g2,#) + EXO2(ldub [%o1], %g2) add %o1, 1, %o1 - EXO2(stb %g2, [%o0],#) + EXO2(stb %g2, [%o0]) sub %o2, 1, %o2 andcc %o2, 0xfffffff0, %o3 be short_end @@ -285,7 +288,7 @@ MOVE_HALFCHUNK(o1, o0, 0x00, g2, g3, g4, g5) MOVE_HALFCHUNK(o1, o0, 0x08, g2, g3, g4, g5) 82: - EXT(10b, 82b, 53f,#) + EXT(10b, 82b, 53f) subcc %o3, 0x10, %o3 add %o1, 0x10, %o1 bne 10b @@ -303,7 +306,7 @@ MOVE_SHORTCHUNK(o1, o0, -0x0e, g2, g3) MOVE_SHORTCHUNK(o1, o0, -0x10, g2, g3) 83: - EXT(byte_chunk, 83b, 54f,#) + EXT(byte_chunk, 83b, 54f) subcc %o3, 0x10, %o3 add %o1, 0x10, %o1 bne byte_chunk @@ -328,11 +331,11 @@ MOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3) MOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3) short_table_end: - EXT(84b, short_table_end, 55f,#) + EXT(84b, short_table_end, 55f) be 1f nop - EX(ldub [%o1], %g2, add %g0, 1,#) - EX(stb %g2, [%o0], add %g0, 1,#) + EX(ldub [%o1], %g2, add %g0, 1) + EX(stb %g2, [%o0], add %g0, 1) 1: retl clr %o0 @@ -344,11 +347,11 @@ be 1f andcc %o2, 4, %g0 - EXO2(ld [%o1 + 0x00], %g2,#) - EXO2(ld [%o1 + 0x04], %g3,#) + EXO2(ld [%o1 + 0x00], %g2) + EXO2(ld [%o1 + 0x04], %g3) add %o1, 8, %o1 - EXO2(st %g2, [%o0 + 0x00],#) - EX(st %g3, [%o0 + 0x04], sub %o2, 4,#) + EXO2(st %g2, [%o0 + 0x00]) + EX(st %g3, [%o0 + 0x04], sub %o2, 4) add %o0, 8, %o0 1: b copy_user_last7 Index: arch/sparc/lib/debuglocks.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/lib/debuglocks.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/lib/debuglocks.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/lib/debuglocks.c 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: debuglocks.c,v 1.1 2004/07/22 19:49:20 joff Exp $ +/* $Id: debuglocks.c,v 1.2 2004/08/04 01:26:15 joff Exp $ * debuglocks.c: Debugging versions of SMP locking primitives. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/lib/locks.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/lib/locks.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/lib/locks.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/lib/locks.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: locks.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: locks.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * locks.S: SMP low-level lock primitives on Sparc. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/lib/lshrdi3.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/lib/lshrdi3.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/lib/lshrdi3.S 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/lib/lshrdi3.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: lshrdi3.S,v 1.1 2004/07/22 19:49:20 joff Exp $ */ +/* $Id: lshrdi3.S,v 1.2 2004/08/04 01:26:15 joff Exp $ */ #include Index: arch/sparc/lib/memscan.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/lib/memscan.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/lib/memscan.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/lib/memscan.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: memscan.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: memscan.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * memscan.S: Optimized memscan for the Sparc. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/lib/memset.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/lib/memset.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/lib/memset.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/lib/memset.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -10,20 +10,23 @@ #include #include -#define EX(x,y,a,b,z) \ +/* Work around cpp -rob */ +#define ALLOC #alloc +#define EXECINSTR #execinstr +#define EX(x,y,a,b) \ 98: x,y; \ - .section .fixup,z##alloc,z##execinstr; \ + .section .fixup,ALLOC,EXECINSTR; \ .align 4; \ 99: ba 30f; \ a, b, %o0; \ - .section __ex_table,z##alloc; \ + .section __ex_table,ALLOC; \ .align 4; \ .word 98b, 99b; \ .text; \ .align 4 -#define EXT(start,end,handler,z) \ - .section __ex_table,z##alloc; \ +#define EXT(start,end,handler) \ + .section __ex_table,ALLOC; \ .align 4; \ .word start, 0, end, handler; \ .text; \ @@ -74,13 +77,13 @@ 3: cmp %o2, 3 be 2f - EX(stb %g3, [%o0], sub %o1, 0,#) + EX(stb %g3, [%o0], sub %o1, 0) cmp %o2, 2 be 2f - EX(stb %g3, [%o0 + 0x01], sub %o1, 1,#) + EX(stb %g3, [%o0 + 0x01], sub %o1, 1) - EX(stb %g3, [%o0 + 0x02], sub %o1, 2,#) + EX(stb %g3, [%o0 + 0x02], sub %o1, 2) 2: sub %o2, 4, %o2 add %o1, %o2, %o1 @@ -101,7 +104,7 @@ be 2f mov %g3, %g2 - EX(st %g3, [%o0], sub %o1, 0,#) + EX(st %g3, [%o0], sub %o1, 0) sub %o1, 4, %o1 add %o0, 4, %o0 2: @@ -113,7 +116,7 @@ subcc %o3, 128, %o3 ZERO_BIG_BLOCK(%o0, 0x40, %g2) 11: - EXT(10b, 11b, 20f,#) + EXT(10b, 11b, 20f) bne 10b add %o0, 128, %o0 @@ -138,17 +141,17 @@ be 1f andcc %o1, 2, %g0 - EX(st %g3, [%o0], and %o1, 7,#) + EX(st %g3, [%o0], and %o1, 7) add %o0, 4, %o0 1: be 1f andcc %o1, 1, %g0 - EX(sth %g3, [%o0], and %o1, 3,#) + EX(sth %g3, [%o0], and %o1, 3) add %o0, 2, %o0 1: bne,a 8f - EX(stb %g3, [%o0], and %o1, 1,#) + EX(stb %g3, [%o0], and %o1, 1) 8: retl clr %o0 @@ -161,7 +164,7 @@ add %o0, 1, %o0 subcc %o1, 1, %o1 bne,a 8b - EX(stb %g3, [%o0 - 1], add %o1, 1,#) + EX(stb %g3, [%o0 - 1], add %o1, 1) 0: retl clr %o0 Index: arch/sparc/lib/mul.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/lib/mul.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/lib/mul.S 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/lib/mul.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: mul.S,v 1.1 2004/07/22 19:49:20 joff Exp $ +/* $Id: mul.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * mul.S: This routine was taken from glibc-1.09 and is covered * by the GNU Library General Public License Version 2. */ Index: arch/sparc/lib/rem.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/lib/rem.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/lib/rem.S 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/lib/rem.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: rem.S,v 1.1 2004/07/22 19:49:20 joff Exp $ +/* $Id: rem.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * rem.S: This routine was taken from glibc-1.09 and is covered * by the GNU Library General Public License Version 2. */ Index: arch/sparc/lib/rwsem.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/lib/rwsem.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/lib/rwsem.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/lib/rwsem.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: rwsem.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: rwsem.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * Assembly part of rw semaphores. * * Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com) Index: arch/sparc/lib/sdiv.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/lib/sdiv.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/lib/sdiv.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/lib/sdiv.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sdiv.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: sdiv.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * sdiv.S: This routine was taken from glibc-1.09 and is covered * by the GNU Library General Public License Version 2. */ Index: arch/sparc/lib/strncmp.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/lib/strncmp.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/lib/strncmp.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/lib/strncmp.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: strncmp.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: strncmp.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * strncmp.S: Hand optimized Sparc assembly of GCC output from GNU libc * generic strncmp routine. */ Index: arch/sparc/lib/udiv.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/lib/udiv.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/lib/udiv.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/lib/udiv.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: udiv.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: udiv.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * udiv.S: This routine was taken from glibc-1.09 and is covered * by the GNU Library General Public License Version 2. */ Index: arch/sparc/lib/umul.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/lib/umul.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/lib/umul.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/lib/umul.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: umul.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: umul.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * umul.S: This routine was taken from glibc-1.09 and is covered * by the GNU Library General Public License Version 2. */ Index: arch/sparc/lib/urem.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/lib/urem.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/lib/urem.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/lib/urem.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: urem.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: urem.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * urem.S: This routine was taken from glibc-1.09 and is covered * by the GNU Library General Public License Version 2. */ Index: arch/sparc/math-emu/ashldi3.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/math-emu/ashldi3.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/math-emu/ashldi3.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/math-emu/ashldi3.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ashldi3.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: ashldi3.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * ashldi3.S: Math-emu code creates all kinds of references to * this little routine on the sparc with gcc. * Index: arch/sparc/math-emu/sfp-util.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/math-emu/sfp-util.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/math-emu/sfp-util.h 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/math-emu/sfp-util.h 4 Aug 2004 01:26:15 -0000 1.2 @@ -4,8 +4,8 @@ #include #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("addcc %r4,%5,%1 - addx %r2,%3,%0" \ + __asm__ ("addcc %r4,%5,%1\n\t" \ + "addx %r2,%3,%0\n" \ : "=r" ((USItype)(sh)), \ "=&r" ((USItype)(sl)) \ : "%rJ" ((USItype)(ah)), \ @@ -14,8 +14,8 @@ "rI" ((USItype)(bl)) \ : "cc") #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subcc %r4,%5,%1 - subx %r2,%3,%0" \ + __asm__ ("subcc %r4,%5,%1\n\t" \ + "subx %r2,%3,%0\n" \ : "=r" ((USItype)(sh)), \ "=&r" ((USItype)(sl)) \ : "rJ" ((USItype)(ah)), \ @@ -25,46 +25,46 @@ : "cc") #define umul_ppmm(w1, w0, u, v) \ - __asm__ ("! Inlined umul_ppmm - wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr - sra %3,31,%%g2 ! Don't move this insn - and %2,%%g2,%%g2 ! Don't move this insn - andcc %%g0,0,%%g1 ! Don't move this insn - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,%3,%%g1 - mulscc %%g1,0,%%g1 - add %%g1,%%g2,%0 - rd %%y,%1" \ + __asm__ ("! Inlined umul_ppmm\n\t" \ + "wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr\n\t" \ + "sra %3,31,%%g2 ! Don't move this insn\n\t" \ + "and %2,%%g2,%%g2 ! Don't move this insn\n\t" \ + "andcc %%g0,0,%%g1 ! Don't move this insn\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,%3,%%g1\n\t" \ + "mulscc %%g1,0,%%g1\n\t" \ + "add %%g1,%%g2,%0\n\t" \ + "rd %%y,%1\n" \ : "=r" ((USItype)(w1)), \ "=r" ((USItype)(w0)) \ : "%rI" ((USItype)(u)), \ @@ -74,30 +74,30 @@ /* It's quite necessary to add this much assembler for the sparc. The default udiv_qrnnd (in C) is more than 10 times slower! */ #define udiv_qrnnd(q, r, n1, n0, d) \ - __asm__ ("! Inlined udiv_qrnnd - mov 32,%%g1 - subcc %1,%2,%%g0 -1: bcs 5f - addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb - sub %1,%2,%1 ! this kills msb of n - addx %1,%1,%1 ! so this can't give carry - subcc %%g1,1,%%g1 -2: bne 1b - subcc %1,%2,%%g0 - bcs 3f - addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb - b 3f - sub %1,%2,%1 ! this kills msb of n -4: sub %1,%2,%1 -5: addxcc %1,%1,%1 - bcc 2b - subcc %%g1,1,%%g1 -! Got carry from n. Subtract next step to cancel this carry. - bne 4b - addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb - sub %1,%2,%1 -3: xnor %0,0,%0 - ! End of inline udiv_qrnnd" \ + __asm__ ("! Inlined udiv_qrnnd\n\t" \ + "mov 32,%%g1\n\t" \ + "subcc %1,%2,%%g0\n\t" \ + "1: bcs 5f\n\t" \ + "addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n\t" \ + "sub %1,%2,%1 ! this kills msb of n\n\t" \ + "addx %1,%1,%1 ! so this can't give carry\n\t" \ + "subcc %%g1,1,%%g1\n\t" \ + "2: bne 1b\n\t" \ + "subcc %1,%2,%%g0\n\t" \ + "bcs 3f\n\t" \ + "addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n\t" \ + "b 3f\n\t" \ + "sub %1,%2,%1 ! this kills msb of n\n\t" \ + "4: sub %1,%2,%1\n\t" \ + "5: addxcc %1,%1,%1\n\t" \ + "bcc 2b\n\t" \ + "subcc %%g1,1,%%g1\n\t" \ + "! Got carry from n. Subtract next step to cancel this carry.\n\t" \ + "bne 4b\n\t" \ + "addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb\n\t" \ + "sub %1,%2,%1\n\t" \ + "3: xnor %0,0,%0\n\t" \ + "! End of inline udiv_qrnnd\n" \ : "=&r" ((USItype)(q)), \ "=&r" ((USItype)(r)) \ : "r" ((USItype)(d)), \ Index: arch/sparc/mm/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/mm/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/mm/Makefile 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/mm/Makefile 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.1 2004/07/22 19:49:20 joff Exp $ +# $Id: Makefile,v 1.2 2004/08/04 01:26:15 joff Exp $ # Makefile for the linux Sparc-specific parts of the memory manager. # # Note! Dependencies are done automagically by 'make dep', which also Index: arch/sparc/mm/btfixup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/mm/btfixup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/mm/btfixup.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/mm/btfixup.c 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: btfixup.c,v 1.1 2004/07/22 19:49:20 joff Exp $ +/* $Id: btfixup.c,v 1.2 2004/08/04 01:26:15 joff Exp $ * btfixup.c: Boot time code fixup and relocator, so that * we can get rid of most indirect calls to achieve single * image sun4c and srmmu kernel. Index: arch/sparc/mm/fault.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/mm/fault.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/mm/fault.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/mm/fault.c 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.1 2004/07/22 19:49:20 joff Exp $ +/* $Id: fault.c,v 1.2 2004/08/04 01:26:15 joff Exp $ * fault.c: Page fault handlers for the Sparc. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/mm/generic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/mm/generic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/mm/generic.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/mm/generic.c 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: generic.c,v 1.1 2004/07/22 19:49:20 joff Exp $ +/* $Id: generic.c,v 1.2 2004/08/04 01:26:15 joff Exp $ * generic.c: Generic Sparc mm routines that are not dependent upon * MMU type but are Sparc specific. * Index: arch/sparc/mm/hypersparc.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/mm/hypersparc.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/mm/hypersparc.S 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/mm/hypersparc.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hypersparc.S,v 1.1 2004/07/22 19:49:20 joff Exp $ +/* $Id: hypersparc.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * hypersparc.S: High speed Hypersparc mmu/cache operations. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/mm/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/mm/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/mm/init.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/mm/init.c 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.1 2004/07/22 19:49:20 joff Exp $ +/* $Id: init.c,v 1.2 2004/08/04 01:26:15 joff Exp $ * linux/arch/sparc/mm/init.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/mm/io-unit.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/mm/io-unit.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/mm/io-unit.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/mm/io-unit.c 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: io-unit.c,v 1.1 2004/07/22 19:49:20 joff Exp $ +/* $Id: io-unit.c,v 1.2 2004/08/04 01:26:15 joff Exp $ * io-unit.c: IO-UNIT specific routines for memory management. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) Index: arch/sparc/mm/iommu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/mm/iommu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/mm/iommu.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/mm/iommu.c 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: iommu.c,v 1.1 2004/07/22 19:49:20 joff Exp $ +/* $Id: iommu.c,v 1.2 2004/08/04 01:26:15 joff Exp $ * iommu.c: IOMMU specific routines for memory management. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/mm/loadmmu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/mm/loadmmu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/mm/loadmmu.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/mm/loadmmu.c 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: loadmmu.c,v 1.1 2004/07/22 19:49:20 joff Exp $ +/* $Id: loadmmu.c,v 1.2 2004/08/04 01:26:15 joff Exp $ * loadmmu.c: This code loads up all the mm function pointers once the * machine type has been determined. It also sets the static * mmu values such as PAGE_NONE, etc. Index: arch/sparc/mm/nosrmmu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/mm/nosrmmu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/mm/nosrmmu.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/mm/nosrmmu.c 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: nosrmmu.c,v 1.1 2004/07/22 19:49:20 joff Exp $ +/* $Id: nosrmmu.c,v 1.2 2004/08/04 01:26:15 joff Exp $ * nosrmmu.c: This file is a bunch of dummies for sun4 compiles, * so that it does not need srmmu and avoid ifdefs. * Index: arch/sparc/mm/nosun4c.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/mm/nosun4c.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/mm/nosun4c.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/mm/nosun4c.c 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: nosun4c.c,v 1.1 2004/07/22 19:49:20 joff Exp $ +/* $Id: nosun4c.c,v 1.2 2004/08/04 01:26:15 joff Exp $ * nosun4c.c: This file is a bunch of dummies for SMP compiles, * so that it does not need sun4c and avoid ifdefs. * Index: arch/sparc/mm/srmmu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/mm/srmmu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/mm/srmmu.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/mm/srmmu.c 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: srmmu.c,v 1.1 2004/07/22 19:49:20 joff Exp $ +/* $Id: srmmu.c,v 1.2 2004/08/04 01:26:15 joff Exp $ * srmmu.c: SRMMU specific routines for memory management. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -126,6 +126,9 @@ #define SRMMU_NOCACHE_BITMAP_SHIFT (PAGE_SHIFT - 4) +/* The context table is a nocache user with the biggest alignment needs. */ +#define SRMMU_NOCACHE_ALIGN_MAX (sizeof(ctxd_t)*SRMMU_MAX_CONTEXTS) + void *srmmu_nocache_pool; void *srmmu_nocache_bitmap; int srmmu_nocache_low; @@ -260,6 +263,7 @@ /* we align on physical address */ if (align) { + BUG_ON(align > SRMMU_NOCACHE_ALIGN_MAX); va_tmp = (SRMMU_NOCACHE_VADDR + (offset << SRMMU_NOCACHE_BITMAP_SHIFT)); phys_tmp = (__nocache_pa(va_tmp) + align - 1) & ~(align - 1); va_tmp = (unsigned long)__nocache_va(phys_tmp); @@ -367,7 +371,8 @@ unsigned long paddr, vaddr; unsigned long pteval; - srmmu_nocache_pool = __alloc_bootmem(srmmu_nocache_size, PAGE_SIZE, 0UL); + srmmu_nocache_pool = __alloc_bootmem(srmmu_nocache_size, + SRMMU_NOCACHE_ALIGN_MAX, 0UL); memset(srmmu_nocache_pool, 0, srmmu_nocache_size); srmmu_nocache_bitmap = __alloc_bootmem(srmmu_nocache_bitmap_size, SMP_CACHE_BYTES, 0UL); Index: arch/sparc/mm/sun4c.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/mm/sun4c.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/mm/sun4c.c 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/mm/sun4c.c 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sun4c.c,v 1.1 2004/07/22 19:49:20 joff Exp $ +/* $Id: sun4c.c,v 1.2 2004/08/04 01:26:15 joff Exp $ * sun4c.c: Doing in software what should be done in hardware. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/mm/swift.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/mm/swift.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/mm/swift.S 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/mm/swift.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: swift.S,v 1.1 2004/07/22 19:49:20 joff Exp $ +/* $Id: swift.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * swift.S: MicroSparc-II mmu/cache operations. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) Index: arch/sparc/mm/tsunami.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/mm/tsunami.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/mm/tsunami.S 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/mm/tsunami.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: tsunami.S,v 1.1 2004/07/22 19:49:20 joff Exp $ +/* $Id: tsunami.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * tsunami.S: High speed MicroSparc-I mmu/cache operations. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/mm/viking.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/mm/viking.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/mm/viking.S 22 Jul 2004 19:49:20 -0000 1.1 +++ arch/sparc/mm/viking.S 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: viking.S,v 1.1 2004/07/22 19:49:20 joff Exp $ +/* $Id: viking.S,v 1.2 2004/08/04 01:26:15 joff Exp $ * viking.S: High speed Viking cache/mmu operations * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) Index: arch/sparc/prom/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/prom/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/prom/Makefile 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/prom/Makefile 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.1 2004/07/22 19:49:21 joff Exp $ +# $Id: Makefile,v 1.2 2004/08/04 01:26:15 joff Exp $ # Makefile for the Sun Boot PROM interface library under # Linux. # Index: arch/sparc/prom/bootstr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/prom/bootstr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/prom/bootstr.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/prom/bootstr.c 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: bootstr.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: bootstr.c,v 1.2 2004/08/04 01:26:15 joff Exp $ * bootstr.c: Boot string/argument acquisition from the PROM. * * Copyright(C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/prom/console.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/prom/console.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/prom/console.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/prom/console.c 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: console.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: console.c,v 1.2 2004/08/04 01:26:15 joff Exp $ * console.c: Routines that deal with sending and receiving IO * to/from the current console device using the PROM. * Index: arch/sparc/prom/devmap.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/prom/devmap.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/prom/devmap.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/prom/devmap.c 4 Aug 2004 01:26:15 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: devmap.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: devmap.c,v 1.2 2004/08/04 01:26:15 joff Exp $ * promdevmap.c: Map device/IO areas to virtual addresses. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/prom/devops.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/prom/devops.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/prom/devops.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/prom/devops.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: devops.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: devops.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * devops.c: Device operations using the PROM. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/prom/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/prom/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/prom/init.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/prom/init.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: init.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * init.c: Initialize internal variables used by the PROM * library functions. * Index: arch/sparc/prom/memory.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/prom/memory.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/prom/memory.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/prom/memory.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: memory.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: memory.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * memory.c: Prom routine for acquiring various bits of information * about RAM on the machine, both virtual and physical. * Index: arch/sparc/prom/misc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/prom/misc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/prom/misc.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/prom/misc.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: misc.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * misc.c: Miscellaneous prom functions that don't belong * anywhere else. * Index: arch/sparc/prom/mp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/prom/mp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/prom/mp.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/prom/mp.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: mp.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: mp.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * mp.c: OpenBoot Prom Multiprocessor support routines. Don't call * these on a UP or else you will halt and catch fire. ;) * Index: arch/sparc/prom/palloc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/prom/palloc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/prom/palloc.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/prom/palloc.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: palloc.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: palloc.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * palloc.c: Memory allocation from the Sun PROM. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/prom/ranges.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/prom/ranges.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/prom/ranges.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/prom/ranges.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ranges.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: ranges.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * ranges.c: Handle ranges in newer proms for obio/sbus. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc/prom/segment.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/prom/segment.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/prom/segment.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/prom/segment.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: segment.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: segment.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * segment.c: Prom routine to map segments in other contexts before * a standalone is completely mapped. This is for sun4 and * sun4c architectures only. Index: arch/sparc/prom/tree.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc/prom/tree.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc/prom/tree.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc/prom/tree.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: tree.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: tree.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * tree.c: Basic device tree traversal/scanning for the Linux * prom library. * Index: arch/sparc64/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/Makefile 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/Makefile 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.1 2004/07/22 19:49:21 joff Exp $ +# $Id: Makefile,v 1.2 2004/08/04 01:26:16 joff Exp $ # sparc64/Makefile # # Makefile for the architecture dependent flags and dependencies on the Index: arch/sparc64/config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/config.in 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/config.in 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.1 2004/07/22 19:49:21 joff Exp $ +# $Id: config.in,v 1.2 2004/08/04 01:26:16 joff Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # @@ -28,6 +28,10 @@ bool 'Symmetric multi-processing support' CONFIG_SMP +if [ "$CONFIG_SMP" = "y" ]; then + int 'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32 +fi + # Identify this as a Sparc64 build define_bool CONFIG_SPARC64 y @@ -79,6 +83,7 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate 'Solaris binary emulation (EXPERIMENTAL)' CONFIG_SOLARIS_EMUL fi +bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER source drivers/parport/Config.in dep_tristate ' Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT if [ "$CONFIG_PCI" = "y" ]; then @@ -128,7 +133,6 @@ 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 @@ -235,7 +239,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 @@ -302,12 +306,16 @@ bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK bool ' Verbose BUG() reporting (adds 70K)' CONFIG_DEBUG_BUGVERBOSE bool ' D-cache flush debugging' CONFIG_DEBUG_DCFLUSH + bool ' Debug BOOTMEM initialization' CONFIG_DEBUG_BOOTMEM fi bool 'Stack Overflow Detection Support' CONFIG_STACK_DEBUG if [ "$CONFIG_STACK_DEBUG" = "y" ] ; then define_bool CONFIG_MCOUNT y fi +int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 + endmenu +source crypto/Config.in source lib/Config.in Index: arch/sparc64/defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/defconfig 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/defconfig 4 Aug 2004 01:26:16 -0000 1.2 @@ -21,6 +21,7 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_SMP=y +CONFIG_NR_CPUS=32 CONFIG_SPARC64=y CONFIG_HOTPLUG=y CONFIG_HAVE_DEC_LOCK=y @@ -58,6 +59,7 @@ CONFIG_BINFMT_MISC=m # CONFIG_SUNOS_EMUL is not set CONFIG_SOLARIS_EMUL=m +# CONFIG_OOM_KILLER is not set # # Parallel port support @@ -68,11 +70,13 @@ # CONFIG_PARPORT_SERIAL is not set CONFIG_PARPORT_PC_FIFO=y # CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_PC_PCMCIA is not set # 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_IP22 is not set # CONFIG_PARPORT_OTHER is not set CONFIG_PARPORT_1284=y CONFIG_PRINTER=m @@ -104,6 +108,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 @@ -118,6 +123,7 @@ CONFIG_FB_PCI=y CONFIG_FB_ATY=y CONFIG_FB_ATY_CT=y +# CONFIG_FB_IT8181 is not set # CONFIG_FB_VIRTUAL is not set # CONFIG_FBCON_ADVANCED is not set CONFIG_FBCON_CFB8=y @@ -179,20 +185,141 @@ 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 + +# +# IP: Virtual Server Configuration +# +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m 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 + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +CONFIG_SCTP_HMAC_SHA1=y +# CONFIG_SCTP_HMAC_MD5 is not set # CONFIG_ATM is not set CONFIG_VLAN_8021Q=m @@ -227,13 +354,16 @@ CONFIG_NET_SCH_CBQ=m CONFIG_NET_SCH_HTB=m CONFIG_NET_SCH_CSZ=m +CONFIG_NET_SCH_HFSC=m CONFIG_NET_SCH_PRIO=m CONFIG_NET_SCH_RED=m CONFIG_NET_SCH_SFQ=m CONFIG_NET_SCH_TEQL=m CONFIG_NET_SCH_TBF=m CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DELAY=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 +422,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 @@ -325,10 +455,10 @@ # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set CONFIG_BLK_DEV_PDC202XX=y -CONFIG_BLK_DEV_IDE_MODES=y CONFIG_BLK_DEV_ATARAID=m CONFIG_BLK_DEV_ATARAID_PDC=m CONFIG_BLK_DEV_ATARAID_HPT=m +CONFIG_BLK_DEV_ATARAID_MEDLEY=m # CONFIG_BLK_DEV_ATARAID_SII is not set # @@ -365,6 +495,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 +563,7 @@ CONFIG_IEEE1394_CMP=m CONFIG_IEEE1394_AMDTP=m # CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_OUI_DB=y # # Network device support @@ -473,6 +608,7 @@ # CONFIG_AMD8111_ETH is not set CONFIG_ADAPTEC_STARFIRE=m # CONFIG_APRICOT is not set +CONFIG_B44=m # CONFIG_CS89x0 is not set CONFIG_TULIP=m # CONFIG_TULIP_MWI is not set @@ -487,6 +623,7 @@ CONFIG_FEALNX=m CONFIG_NATSEMI=m CONFIG_NE2K_PCI=m +CONFIG_FORCEDETH=m # CONFIG_NE3210 is not set # CONFIG_ES3210 is not set # CONFIG_8139CP is not set @@ -500,7 +637,6 @@ CONFIG_SUNDANCE=m CONFIG_SUNDANCE_MMIO=y # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set CONFIG_VIA_RHINE=m # CONFIG_VIA_RHINE_MMIO is not set CONFIG_WINBOND_840=m @@ -513,6 +649,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 @@ -588,11 +725,13 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_UINPUT=m # # 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,11 +741,12 @@ # 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 -CONFIG_EXT3_FS=m -CONFIG_JBD=m +CONFIG_EXT3_FS=y +CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FAT_FS=m CONFIG_MSDOS_FS=m @@ -616,7 +756,7 @@ # CONFIG_JFFS_FS is not set # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set +CONFIG_TMPFS=y CONFIG_RAMFS=y CONFIG_ISO9660_FS=m CONFIG_JOLIET=y @@ -630,8 +770,8 @@ # CONFIG_NTFS_RW is not set CONFIG_HPFS_FS=m 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 @@ -643,6 +783,11 @@ CONFIG_UDF_RW=y CONFIG_UFS_FS=m CONFIG_UFS_FS_WRITE=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -651,6 +796,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 @@ -748,6 +894,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +CONFIG_SOUND_AD1980=m +CONFIG_SOUND_WM97XX=m # # USB support @@ -821,6 +969,7 @@ CONFIG_USB_PWC=m CONFIG_USB_SE401=m CONFIG_USB_STV680=m +# CONFIG_USB_W9968CF is not set CONFIG_USB_VICAM=m CONFIG_USB_DSBR=m CONFIG_USB_DABUSB=m @@ -888,6 +1037,25 @@ CONFIG_USB_LCD=m # +# Support for USB gadgets +# +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_NET2280=y +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_CONTROLLER is not set +CONFIG_USB_NET2280=y +CONFIG_USB_GADGET_CONTROLLER=y +CONFIG_USB_GADGET_DUALSPEED=y + +# +# USB Gadget Drivers +# +# CONFIG_USB_ZERO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_FILE_STORAGE_TEST is not set + +# # Bluetooth support # CONFIG_BLUEZ=m @@ -903,11 +1071,12 @@ # Bluetooth device drivers # CONFIG_BLUEZ_HCIUSB=m -CONFIG_BLUEZ_USB_ZERO_PACKET=y +CONFIG_BLUEZ_HCIUSB_SCO=y CONFIG_BLUEZ_HCIUART=m CONFIG_BLUEZ_HCIUART_H4=y CONFIG_BLUEZ_HCIUART_BCSP=y CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y +CONFIG_BLUEZ_HCIBFUSB=m # CONFIG_BLUEZ_HCIDTL1 is not set # CONFIG_BLUEZ_HCIBT3C is not set # CONFIG_BLUEZ_HCIBLUECARD is not set @@ -928,10 +1097,36 @@ # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_DEBUG_DCFLUSH is not set +# CONFIG_DEBUG_BOOTMEM is not set # CONFIG_STACK_DEBUG is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# 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_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_TEST is not set # # Library routines # +CONFIG_CRC32=y CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y +CONFIG_FW_LOADER=m Index: arch/sparc64/boot/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/boot/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/boot/Makefile 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/boot/Makefile 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.1 2004/07/22 19:49:21 joff Exp $ +# $Id: Makefile,v 1.2 2004/08/04 01:26:16 joff Exp $ # Makefile for the Sparc64 boot stuff. # # Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -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: Index: arch/sparc64/boot/piggyback.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/boot/piggyback.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/boot/piggyback.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/boot/piggyback.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: piggyback.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: piggyback.c,v 1.2 2004/08/04 01:26:16 joff Exp $ Simple utility to make a single-image install kernel with initial ramdisk for Sparc64 tftpbooting without need to set up nfs. Index: arch/sparc64/kernel/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/Makefile 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/Makefile 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.1 2004/07/22 19:49:22 joff Exp $ +# $Id: Makefile,v 1.2 2004/08/04 01:26:16 joff Exp $ # Makefile for the linux kernel. # @@ -58,50 +58,11 @@ @echo >> asm_offsets.h @echo "#include " >> asm_offsets.h @echo >> asm_offsets.h - @echo "#ifndef CONFIG_SMP" >> asm_offsets.h - @echo >> asm_offsets.h - @echo "#include " > tmp.c - @echo "#undef CONFIG_SMP" >> tmp.c - @echo "#include " >> tmp.c - $(CPP) $(CPPFLAGS) -P tmp.c -o tmp.i - @echo "/* Automatically generated. Do not edit. */" > check_asm_data.c - @echo "#include " >> check_asm_data.c - @echo "#undef CONFIG_SMP" >> check_asm_data.c - @echo "#include " >> check_asm_data.c - @echo 'unsigned int check_asm_data[] = {' >> check_asm_data.c - $(SH) ./check_asm.sh -data task tmp.i check_asm_data.c - $(SH) ./check_asm.sh -data mm tmp.i check_asm_data.c - $(SH) ./check_asm.sh -data thread tmp.i check_asm_data.c - @echo '};' >> check_asm_data.c - $(CC) $(CPPFLAGS) $(CMODEL_CFLAG) -ffixed-g4 -S -o check_asm_data.s check_asm_data.c - @echo "/* Automatically generated. Do not edit. */" > check_asm.c - @echo 'extern int printf(const char *fmt, ...);' >>check_asm.c - @echo 'unsigned int check_asm_data[] = {' >> check_asm.c - $(SH) ./check_asm.sh -ints check_asm_data.s check_asm.c - @echo '};' >> check_asm.c - @echo 'int main(void) {' >> check_asm.c - @echo 'int i = 0;' >> check_asm.c - $(SH) ./check_asm.sh -printf task tmp.i check_asm.c - $(SH) ./check_asm.sh -printf mm tmp.i check_asm.c - $(SH) ./check_asm.sh -printf thread tmp.i check_asm.c - @echo 'return 0; }' >> check_asm.c - @rm -f tmp.[ci] check_asm_data.[cs] - $(HOSTCC) -o check_asm check_asm.c - ./check_asm >> asm_offsets.h - @rm -f check_asm check_asm.c - @echo >> asm_offsets.h - @echo "#else /* CONFIG_SMP */" >> asm_offsets.h - @echo "#ifndef CONFIG_DEBUG_SPINLOCK" >>asm_offsets.h - @echo >> asm_offsets.h @echo "#include " > tmp.c - @echo "#undef CONFIG_SMP" >> tmp.c - @echo "#define CONFIG_SMP 1" >> tmp.c @echo "#include " >> tmp.c $(CPP) $(CPPFLAGS) -P tmp.c -o tmp.i @echo "/* Automatically generated. Do not edit. */" > check_asm_data.c @echo "#include " >> check_asm_data.c - @echo "#undef CONFIG_SMP" >> check_asm_data.c - @echo "#define CONFIG_SMP 1" >> check_asm_data.c @echo "#include " >> check_asm_data.c @echo 'unsigned int check_asm_data[] = {' >> check_asm_data.c $(SH) ./check_asm.sh -data task tmp.i check_asm_data.c @@ -125,40 +86,6 @@ ./check_asm >> asm_offsets.h @rm -f check_asm check_asm.c @echo >> asm_offsets.h - @echo "#else /* CONFIG_DEBUG_SPINLOCK */" >> asm_offsets.h - @echo >> asm_offsets.h - @echo "#include " > tmp.c - $(CPP) $(CPPFLAGS) -P -DCONFIG_DEBUG_SPINLOCK tmp.c -o tmp.i - @echo "/* Automatically generated. Do not edit. */" > check_asm_data.c - @echo "#include " >> check_asm_data.c - @echo "#undef CONFIG_SMP" >> check_asm_data.c - @echo "#define CONFIG_SMP 1" >> check_asm_data.c - @echo "#include " >> check_asm_data.c - @echo 'unsigned int check_asm_data[] = {' >> check_asm_data.c - $(SH) ./check_asm.sh -data task tmp.i check_asm_data.c - $(SH) ./check_asm.sh -data mm tmp.i check_asm_data.c - $(SH) ./check_asm.sh -data thread tmp.i check_asm_data.c - @echo '};' >> check_asm_data.c - $(CC) $(CPPFLAGS) -DCONFIG_DEBUG_SPINLOCK $(CMODEL_CFLAG) -ffixed-g4 -S -o check_asm_data.s check_asm_data.c - @echo "/* Automatically generated. Do not edit. */" > check_asm.c - @echo 'extern int printf(const char *fmt, ...);' >>check_asm.c - @echo 'unsigned int check_asm_data[] = {' >> check_asm.c - $(SH) ./check_asm.sh -ints check_asm_data.s check_asm.c - @echo '};' >> check_asm.c - @echo 'int main(void) {' >> check_asm.c - @echo 'int i = 0;' >> check_asm.c - $(SH) ./check_asm.sh -printf task tmp.i check_asm.c - $(SH) ./check_asm.sh -printf mm tmp.i check_asm.c - $(SH) ./check_asm.sh -printf thread tmp.i check_asm.c - @echo 'return 0; }' >> check_asm.c - @rm -f tmp.[ci] check_asm_data.[cs] - $(HOSTCC) -o check_asm check_asm.c - ./check_asm >> asm_offsets.h - @rm -f check_asm check_asm.c - @echo "#endif /* CONFIG_DEBUG_SPINLOCK */" >> asm_offsets.h - @echo >> asm_offsets.h - @echo "#endif /* CONFIG_SMP */" >> asm_offsets.h - @echo >> asm_offsets.h @echo "#endif /* __ASM_OFFSETS_H__ */" >> asm_offsets.h @if test -r $(HPATH)/asm/asm_offsets.h; then \ if cmp -s asm_offsets.h $(HPATH)/asm/asm_offsets.h; then \ Index: arch/sparc64/kernel/central.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/central.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/central.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/central.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: central.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: central.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * central.c: Central FHC driver for Sunfire/Starfire/Wildfire. * * Copyright (C) 1997, 1999 David S. Miller (davem@redhat.com) Index: arch/sparc64/kernel/check_asm.sh =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/check_asm.sh,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/check_asm.sh 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/check_asm.sh 4 Aug 2004 01:26:16 -0000 1.2 @@ -11,7 +11,7 @@ echo " sizeof(struct $2_struct)," >> $4 ;; -ints) - sed -n -e '/check_asm_data:/,/\.size/p' <$2 | sed -e 's/check_asm_data://' -e 's/\.size.*//' -e 's/\.long[ ]\([0-9]*\)/\1,/' | grep -v '\.ident' >>$3 + sed -n -e '/check_asm_data:/,/\.size/p' <$2 | sed -e 's/check_asm_data://' -e 's/\.size.*//' -e 's/\.section.*//' -e 's/\.long[ ]\([0-9]*\)/\1,/' | grep -v '\.ident' >>$3 ;; *) exit 1 Index: arch/sparc64/kernel/chmc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/chmc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/chmc.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/chmc.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: chmc.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: chmc.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * memctrlr.c: Driver for UltraSPARC-III memory controller. * * Copyright (C) 2001 David S. Miller (davem@redhat.com) Index: arch/sparc64/kernel/cpu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/cpu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/cpu.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/cpu.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -37,6 +37,7 @@ { 0x17, 0x13, 0, "UltraSparc IIe integrated FPU"}, { 0x3e, 0x14, 0, "UltraSparc III integrated FPU"}, { 0x3e, 0x15, 0, "UltraSparc III+ integrated FPU"}, + { 0x3e, 0x16, 0, "UltraSparc IIIi integrated FPU"}, }; #define NSPARCFPU (sizeof(linux_sparc_fpu)/sizeof(struct cpu_fp_info)) @@ -45,31 +46,25 @@ { 0x17, 0x10, "TI UltraSparc I (SpitFire)"}, { 0x22, 0x10, "TI UltraSparc I (SpitFire)"}, { 0x17, 0x11, "TI UltraSparc II (BlackBird)"}, - { 0x17, 0x12, "TI UltraSparc IIi"}, - { 0x17, 0x13, "TI UltraSparc IIe"}, + { 0x17, 0x12, "TI UltraSparc IIi (Sabre)"}, + { 0x17, 0x13, "TI UltraSparc IIe (Hummingbird)"}, { 0x3e, 0x14, "TI UltraSparc III (Cheetah)"}, { 0x3e, 0x15, "TI UltraSparc III+ (Cheetah+)"}, + { 0x3e, 0x16, "TI UltraSparc IIIi (Jalapeno)"}, }; #define NSPARCCHIPS (sizeof(linux_sparc_chips)/sizeof(struct cpu_iu_info)) -#ifdef CONFIG_SMP -char *sparc_cpu_type[64] = { "cpu-oops", "cpu-oops1", "cpu-oops2", "cpu-oops3" }; -char *sparc_fpu_type[64] = { "fpu-oops", "fpu-oops1", "fpu-oops2", "fpu-oops3" }; -#else -char *sparc_cpu_type[64] = { "cpu-oops", }; -char *sparc_fpu_type[64] = { "fpu-oops", }; -#endif +char *sparc_cpu_type = "cpu-oops"; +char *sparc_fpu_type = "fpu-oops"; unsigned int fsr_storage; void __init cpu_probe(void) { unsigned long ver, fpu_vers, manuf, impl, fprs; - int i, cpuid; + int i; - cpuid = hard_smp_processor_id(); - fprs = fprs_read(); fprs_write(FPRS_FEF); __asm__ __volatile__ ("rdpr %%ver, %0; stx %%fsr, [%1]" @@ -86,7 +81,7 @@ for (i = 0; i < NSPARCCHIPS; i++) { if (linux_sparc_chips[i].manuf == manuf) { if (linux_sparc_chips[i].impl == impl) { - sparc_cpu_type[cpuid] + sparc_cpu_type = linux_sparc_chips[i].cpu_name; break; } @@ -105,14 +100,14 @@ printk("DEBUG: manuf[%lx] impl[%lx]\n", manuf, impl); } - sparc_cpu_type[cpuid] = "Unknown CPU"; + sparc_cpu_type = "Unknown CPU"; } for (i = 0; i < NSPARCFPU; i++) { if (linux_sparc_fpu[i].manuf == manuf && linux_sparc_fpu[i].impl == impl) { if (linux_sparc_fpu[i].fpu_vers == fpu_vers) { - sparc_fpu_type[cpuid] + sparc_fpu_type = linux_sparc_fpu[i].fp_name; break; } @@ -122,6 +117,6 @@ if (i == NSPARCFPU) { printk("DEBUG: manuf[%lx] impl[%lx] fsr.vers[%lx]\n", manuf, impl, fpu_vers); - sparc_fpu_type[cpuid] = "Unknown FPU"; + sparc_fpu_type = "Unknown FPU"; } } Index: arch/sparc64/kernel/dtlb_backend.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/dtlb_backend.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/dtlb_backend.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/dtlb_backend.S 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: dtlb_backend.S,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: dtlb_backend.S,v 1.2 2004/08/04 01:26:16 joff Exp $ * dtlb_backend.S: Back end to DTLB miss replacement strategy. * This is included directly into the trap table. * Index: arch/sparc64/kernel/dtlb_base.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/dtlb_base.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/dtlb_base.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/dtlb_base.S 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: dtlb_base.S,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: dtlb_base.S,v 1.2 2004/08/04 01:26:16 joff Exp $ * dtlb_base.S: Front end to DTLB miss replacement strategy. * This is included directly into the trap table. * Index: arch/sparc64/kernel/dtlb_prot.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/dtlb_prot.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/dtlb_prot.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/dtlb_prot.S 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: dtlb_prot.S,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: dtlb_prot.S,v 1.2 2004/08/04 01:26:16 joff Exp $ * dtlb_prot.S: DTLB protection trap strategy. * This is included directly into the trap table. * Index: arch/sparc64/kernel/ebus.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/ebus.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/ebus.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/ebus.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ebus.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: ebus.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * ebus.c: PCI to EBus bridge device. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -177,7 +177,8 @@ static int __init child_regs_nonstandard(struct linux_ebus_device *dev) { - if (!strcmp(dev->prom_name, "i2c")) + if (!strcmp(dev->prom_name, "i2c") || + !strcmp(dev->prom_name, "SUNW,lombus")) return 1; return 0; } Index: arch/sparc64/kernel/entry.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/entry.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/entry.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/entry.S 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: entry.S,v 1.2 2004/08/04 01:26:16 joff Exp $ * arch/sparc64/kernel/entry.S: Sparc64 trap low-level entry points. * * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu) @@ -911,10 +911,15 @@ sllx %g1, 63, %g2; \ or %g4, %g2, %g4; \ /* Get log entry pointer for this cpu at this trap level. */ \ + BRANCH_IF_JALAPENO(g2,g3,50f) \ ldxa [%g0] ASI_SAFARI_CONFIG, %g2; \ srlx %g2, 17, %g2; \ - and %g2, 0x3ff, %g2; \ - sllx %g2, 9, %g2; \ + ba,pt %xcc, 60f; \ + and %g2, 0x3ff, %g2; \ +50: ldxa [%g0] ASI_JBUS_CONFIG, %g2; \ + srlx %g2, 17, %g2; \ + and %g2, 0x1f, %g2; \ +60: sllx %g2, 9, %g2; \ sethi %hi(cheetah_error_log), %g3; \ ldx [%g3 + %lo(cheetah_error_log)], %g3; \ brz,pn %g3, 80f; \ @@ -1749,8 +1754,8 @@ cmp %o0, -ENOIOCTLCMD sllx %g2, 32, %g2 bgeu,pn %xcc, 1f - andcc %l0, 0x02, %l6 +80: andn %g3, %g2, %g3 /* System call success, clear Carry condition code. */ stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] bne,pn %icc, linux_syscall_trace2 @@ -1760,9 +1765,21 @@ stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] 1: + /* Really a failure? Check if force_successful_syscall_return() + * was invoked. + */ + ldx [%curptr + AOFF_task_thread + AOFF_thread_flags], %l0 + andcc %l0, SPARC_FLAG_SYS_SUCCESS, %g0 + be,pt %icc, 1f + andcc %l6, 0x02, %g0 + andn %l0, SPARC_FLAG_SYS_SUCCESS, %l0 + ba,pt %xcc, 80b + stx %l0, [%curptr + AOFF_task_thread + AOFF_thread_flags] + /* System call failure, set Carry condition code. * Also, get abs(errno) to return to the process. */ +1: sub %g0, %o0, %o0 or %g3, %g2, %g3 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] Index: arch/sparc64/kernel/etrap.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/etrap.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/etrap.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/etrap.S 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: etrap.S,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: etrap.S,v 1.2 2004/08/04 01:26:16 joff Exp $ * etrap.S: Preparing for entry into the kernel on Sparc V9. * * Copyright (C) 1996, 1997 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc64/kernel/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/head.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/head.S 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: head.S,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: head.S,v 1.2 2004/08/04 01:26:16 joff Exp $ * head.S: Initial boot code for the Sparc64 port of Linux. * * Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu) @@ -54,7 +54,15 @@ .ascii "HdrS" .word LINUX_VERSION_CODE - .half 0x0203 /* HdrS version */ + + /* History: + * + * 0x0300 : Supports being located at other than 0x4000 + * 0x0202 : Supports kernel params string + * 0x0201 : Supports reboot_command + */ + .half 0x0300 /* HdrS version */ + root_flags: .half 1 root_dev: @@ -66,7 +74,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 @@ -151,12 +159,31 @@ blu,pt %xcc, 1b add %l0, (1 << 3), %l0 + /* Search the small TLB. OBP never maps us like that but + * newer SILO can. + */ + clr %l0 + +1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1 + membar #Sync + andn %g1, %l2, %g1 + cmp %g1, %g2 + be,pn %xcc, cheetah_got_tlbentry + nop + cmp %l0, (15 << 3) + blu,pt %xcc, 1b + add %l0, (1 << 3), %l0 + + /* BUG() if we get here... */ + ta 0x5 + cheetah_got_tlbentry: ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g0 ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g1 membar #Sync and %g1, %g3, %g1 - sub %g1, %g2, %g1 + set 0x5fff, %l0 + andn %g1, %l0, %g1 or %g5, %g1, %g5 /* Clear out any KERNBASE area entries. */ @@ -333,13 +360,17 @@ blu,pt %xcc, 1b add %l0, (1 << 3), %l0 + /* BUG() if we get here... */ + ta 0x5 + spitfire_got_tlbentry: /* Nops here again, perhaps Cheetah/Blackbird are better behaved... */ nop nop nop and %g1, %g3, %g1 /* Mask to just get paddr bits. */ - sub %g1, %g2, %g1 /* Get rid of %pc offset to get base. */ + set 0x5fff, %l3 /* Mask offset to get phys base. */ + andn %g1, %l3, %g1 /* NOTE: We hold on to %g1 paddr base as we need it below to lock * NOTE: the PROM cif code into the TLB. @@ -647,11 +678,18 @@ nop not_starfire: + BRANCH_IF_JALAPENO(g1,g5,is_jalapeno) BRANCH_IF_ANY_CHEETAH(g1,g5,is_cheetah) ba,pt %xcc, not_cheetah nop +is_jalapeno: + ldxa [%g0] ASI_JBUS_CONFIG, %g1 + srlx %g1, 17, %g1 + ba,pt %xcc, set_worklist + and %g1, 0x1f, %g1 ! 5bit JBUS ID + is_cheetah: ldxa [%g0] ASI_SAFARI_CONFIG, %g1 srlx %g1, 17, %g1 @@ -742,8 +780,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: Index: arch/sparc64/kernel/idprom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/idprom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/idprom.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/idprom.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: idprom.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: idprom.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * idprom.c: Routines to load the idprom into kernel addresses and * interpret the data contained within. * Index: arch/sparc64/kernel/ioctl32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/ioctl32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/ioctl32.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/ioctl32.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ioctl32.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: ioctl32.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) @@ -1920,8 +1920,8 @@ __cgc_do_ptr((void **) &cgc->sense, &cgc32->sense)) return -EFAULT; - if (get_user(dir, &cgc->data_direction) || - put_user(dir, &cgc32->data_direction)) + if (get_user(dir, &cgc32->data_direction) || + put_user(dir, &cgc->data_direction)) return -EFAULT; if (copy_in_user(&cgc->quiet, &cgc32->quiet, @@ -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) @@ -4518,7 +4524,6 @@ /* Big T */ COMPATIBLE_IOCTL(TUNSETNOCSUM) COMPATIBLE_IOCTL(TUNSETDEBUG) -COMPATIBLE_IOCTL(TUNSETIFF) COMPATIBLE_IOCTL(TUNSETPERSIST) COMPATIBLE_IOCTL(TUNSETOWNER) /* Big V */ @@ -5036,6 +5041,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) @@ -5136,6 +5145,7 @@ HANDLE_IOCTL(SIOCGIFPFLAGS, dev_ifsioc) HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc) HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc) +HANDLE_IOCTL(TUNSETIFF, dev_ifsioc) HANDLE_IOCTL(SIOCETHTOOL, ethtool_ioctl) HANDLE_IOCTL(SIOCBONDENSLAVE, bond_ioctl) HANDLE_IOCTL(SIOCBONDRELEASE, bond_ioctl) Index: arch/sparc64/kernel/iommu_common.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/iommu_common.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/iommu_common.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/iommu_common.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: iommu_common.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: iommu_common.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * iommu_common.c: UltraSparc SBUS/PCI common iommu code. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) Index: arch/sparc64/kernel/iommu_common.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/iommu_common.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/iommu_common.h 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/iommu_common.h 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: iommu_common.h,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: iommu_common.h,v 1.2 2004/08/04 01:26:16 joff Exp $ * iommu_common.h: UltraSparc SBUS/PCI common iommu declarations. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) Index: arch/sparc64/kernel/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/irq.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/irq.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: irq.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * irq.c: UltraSparc IRQ handling/init/registry. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -148,12 +148,24 @@ return; if (tlb_type == cheetah || tlb_type == cheetah_plus) { - /* We set it to our Safari AID. */ - __asm__ __volatile__("ldxa [%%g0] %1, %0" - : "=r" (tid) - : "i" (ASI_SAFARI_CONFIG)); - tid = ((tid & (0x3ffUL<<17)) << 9); - tid &= IMAP_AID_SAFARI; + unsigned long ver; + + __asm__ ("rdpr %%ver, %0" : "=r" (ver)); + if ((ver >> 32) == 0x003e0016) { + /* We set it to our JBUS ID. */ + __asm__ __volatile__("ldxa [%%g0] %1, %0" + : "=r" (tid) + : "i" (ASI_JBUS_CONFIG)); + tid = ((tid & (0x1fUL<<17)) << 9); + tid &= IMAP_TID_JBUS; + } else { + /* We set it to our Safari AID. */ + __asm__ __volatile__("ldxa [%%g0] %1, %0" + : "=r" (tid) + : "i" (ASI_SAFARI_CONFIG)); + tid = ((tid & (0x3ffUL<<17)) << 9); + tid &= IMAP_AID_SAFARI; + } } else if (this_is_starfire == 0) { /* We set it to our UPA MID. */ __asm__ __volatile__("ldxa [%%g0] %1, %0" Index: arch/sparc64/kernel/isa.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/isa.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/isa.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/isa.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -20,22 +20,23 @@ printk(" [%s", isa_dev->prom_name); } -static void __init isa_dev_get_resource(struct isa_device *isa_dev) +static void __init isa_dev_get_resource(struct isa_device *isa_dev, + struct linux_prom_registers *pregs, + int pregs_size) { - struct linux_prom_registers regs[PROMREG_MAX]; unsigned long base, len; int prop_len; prop_len = prom_getproperty(isa_dev->prom_node, "reg", - (char *) regs, sizeof(regs)); + (char *) pregs, pregs_size); if (prop_len <= 0) return; /* Only the first one is interesting. */ - len = regs[0].reg_size; - base = (((unsigned long)regs[0].which_io << 32) | - (unsigned long)regs[0].phys_addr); + len = pregs[0].reg_size; + base = (((unsigned long)pregs[0].which_io << 32) | + (unsigned long)pregs[0].phys_addr); base += isa_dev->bus->parent->io_space.start; isa_dev->resource.start = base; @@ -53,6 +54,9 @@ * * The P1275 standard for ISA devices seems to also have been * totally ignored. + * + * On later systems, an interrupt-map and interrupt-map-mask scheme + * akin to EBUS is used. */ static struct { int obp_irq; @@ -67,33 +71,72 @@ { 0, 0x00 } /* end of table */ }; -static void __init isa_dev_get_irq(struct isa_device *isa_dev) +static int __init isa_dev_get_irq_using_imap(struct isa_device *isa_dev, + struct isa_bridge *isa_br, + int *interrupt, + struct linux_prom_registers *pregs) +{ + unsigned int hi, lo, irq; + int i; + + hi = pregs->which_io & isa_br->isa_intmask.phys_hi; + lo = pregs->phys_addr & isa_br->isa_intmask.phys_lo; + irq = *interrupt & isa_br->isa_intmask.interrupt; + for (i = 0; i < isa_br->num_isa_intmap; i++) { + if ((isa_br->isa_intmap[i].phys_hi == hi) && + (isa_br->isa_intmap[i].phys_lo == lo) && + (isa_br->isa_intmap[i].interrupt == irq)) { + *interrupt = isa_br->isa_intmap[i].cinterrupt; + return 0; + } + } + return -1; +} + +static void __init isa_dev_get_irq(struct isa_device *isa_dev, + struct linux_prom_registers *pregs) { int irq_prop; irq_prop = prom_getintdefault(isa_dev->prom_node, "interrupts", -1); if (irq_prop <= 0) { - isa_dev->irq = PCI_IRQ_NONE; + goto no_irq; } else { + struct pci_controller_info *pcic; + struct pci_pbm_info *pbm; int i; + if (isa_dev->bus->num_isa_intmap) { + if (!isa_dev_get_irq_using_imap(isa_dev, + isa_dev->bus, + &irq_prop, + pregs)) + goto route_irq; + } + for (i = 0; grover_irq_table[i].obp_irq != 0; i++) { if (grover_irq_table[i].obp_irq == irq_prop) { - struct pci_controller_info *pcic; - struct pci_pbm_info *pbm; int ino = grover_irq_table[i].pci_ino; - if (ino == 0) { - isa_dev->irq = PCI_IRQ_NONE; - } else { - pbm = isa_dev->bus->parent; - pcic = pbm->parent; - isa_dev->irq = pcic->irq_build(pbm, NULL, ino); - } + if (ino == 0) + goto no_irq; + + irq_prop = ino; + goto route_irq; } } + goto no_irq; + +route_irq: + pbm = isa_dev->bus->parent; + pcic = pbm->parent; + isa_dev->irq = pcic->irq_build(pbm, NULL, irq_prop); + return; } + +no_irq: + isa_dev->irq = PCI_IRQ_NONE; } static void __init isa_fill_children(struct isa_device *parent_isa_dev) @@ -105,6 +148,7 @@ printk(" ->"); while (node != 0) { + struct linux_prom_registers regs[PROMREG_MAX]; struct isa_device *isa_dev; int prop_len; @@ -138,8 +182,8 @@ if (prop_len <= 0) isa_dev->compatible[0] = '\0'; - isa_dev_get_resource(isa_dev); - isa_dev_get_irq(isa_dev); + isa_dev_get_resource(isa_dev, regs, sizeof(regs)); + isa_dev_get_irq(isa_dev, regs); report_dev(isa_dev, 1); @@ -152,6 +196,7 @@ int node = prom_getchild(isa_br->prom_node); while (node != 0) { + struct linux_prom_registers regs[PROMREG_MAX]; struct isa_device *isa_dev; int prop_len; @@ -194,8 +239,8 @@ if (prop_len <= 0) isa_dev->compatible[0] = '\0'; - isa_dev_get_resource(isa_dev); - isa_dev_get_irq(isa_dev); + isa_dev_get_resource(isa_dev, regs, sizeof(regs)); + isa_dev_get_irq(isa_dev, regs); report_dev(isa_dev, 0); @@ -260,6 +305,21 @@ isa_br->num_isa_ranges = (prop_len / sizeof(struct linux_prom_isa_ranges)); + prop_len = prom_getproperty(isa_br->prom_node, + "interrupt-map", + (char *) isa_br->isa_intmap, + sizeof(isa_br->isa_intmap)); + if (prop_len <= 0) + isa_br->num_isa_intmap = 0; + else + isa_br->num_isa_intmap = + (prop_len / sizeof(struct linux_prom_isa_intmap)); + + prop_len = prom_getproperty(isa_br->prom_node, + "interrupt-map-mask", + (char *) &(isa_br->isa_intmask), + sizeof(isa_br->isa_intmask)); + printk("isa%d:", isa_br->index); isa_fill_devices(isa_br); Index: arch/sparc64/kernel/itlb_base.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/itlb_base.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/itlb_base.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/itlb_base.S 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: itlb_base.S,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: itlb_base.S,v 1.2 2004/08/04 01:26:16 joff Exp $ * itlb_base.S: Front end to ITLB miss replacement strategy. * This is included directly into the trap table. * Index: arch/sparc64/kernel/pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/pci.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/pci.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: pci.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: pci.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * pci.c: UltraSparc PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) @@ -81,6 +81,8 @@ extern void sabre_init(int, char *); extern void psycho_init(int, char *); extern void schizo_init(int, char *); +extern void schizo_plus_init(int, char *); +extern void tomatillo_init(int, char *); static struct { char *model_name; @@ -92,12 +94,16 @@ { "SUNW,psycho", psycho_init }, { "pci108e,8000", psycho_init }, { "SUNW,schizo", schizo_init }, - { "pci108e,8001", schizo_init } + { "pci108e,8001", schizo_init }, + { "SUNW,schizo+", schizo_plus_init }, + { "pci108e,8002", schizo_plus_init }, + { "SUNW,tomatillo", tomatillo_init }, + { "pci108e,a801", tomatillo_init }, }; #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 +112,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) Index: arch/sparc64/kernel/pci_common.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/pci_common.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/pci_common.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/pci_common.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: pci_common.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: pci_common.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * pci_common.c: PCI controller common support. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) @@ -54,6 +54,7 @@ (pdev->vendor == PCI_VENDOR_ID_SUN) && (pdev->device == PCI_DEVICE_ID_SUN_PBM || pdev->device == PCI_DEVICE_ID_SUN_SCHIZO || + pdev->device == PCI_DEVICE_ID_SUN_TOMATILLO || pdev->device == PCI_DEVICE_ID_SUN_SABRE || pdev->device == PCI_DEVICE_ID_SUN_HUMMINGBIRD)) { *nregs = 0; @@ -316,14 +317,23 @@ { struct resource *res; int breg = (ap->phys_hi & 0xff); - int space = (ap->phys_hi >> 24) & 3; switch (breg) { case PCI_ROM_ADDRESS: + /* Unfortunately I have seen several cases where + * buggy FCODE uses a space value of '1' (I/O space) + * in the register property for the ROM address + * so disable this sanity check for now. + */ +#if 0 + { + int space = (ap->phys_hi >> 24) & 3; + /* It had better be MEM space. */ if (space != 2) bad_assignment(pdev, ap, NULL, 0); - + } +#endif res = &pdev->resource[PCI_ROM_RESOURCE]; break; @@ -699,7 +709,7 @@ struct pcidev_cookie *pcp = pdev->sysdata; struct pci_pbm_info *pbm = pcp->pbm; struct pci_controller_info *p = pbm->parent; - unsigned int portid = p->portid; + unsigned int portid = pbm->portid; unsigned int prom_irq; int prom_node = pcp->prom_node; int err; Index: arch/sparc64/kernel/pci_impl.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/pci_impl.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/pci_impl.h 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/pci_impl.h 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: pci_impl.h,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: pci_impl.h,v 1.2 2004/08/04 01:26:16 joff Exp $ * pci_impl.h: Helper definitions for PCI controller support. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) Index: arch/sparc64/kernel/pci_iommu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/pci_iommu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/pci_iommu.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/pci_iommu.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: pci_iommu.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: pci_iommu.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * pci_iommu.c: UltraSparc PCI controller IOM/STC support. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) @@ -829,5 +829,8 @@ } } + if (device_mask >= (1UL << 32UL)) + return 0; + return (device_mask & dma_addr_mask) == dma_addr_mask; } Index: arch/sparc64/kernel/pci_psycho.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/pci_psycho.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/pci_psycho.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/pci_psycho.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: pci_psycho.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: pci_psycho.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * pci_psycho.c: PSYCHO/U2P specific PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu) @@ -388,7 +388,6 @@ struct pci_dev *pdev, unsigned int ino) { - struct pci_controller_info *p = pbm->parent; struct ino_bucket *bucket; unsigned long imap, iclr; unsigned long imap_off, iclr_off; @@ -413,11 +412,11 @@ if (PIL_RESERVED(pil)) BUG(); - imap = p->controller_regs + imap_off; + imap = pbm->controller_regs + imap_off; imap += 4; iclr_off = psycho_iclr_offset(ino); - iclr = p->controller_regs + iclr_off; + iclr = pbm->controller_regs + iclr_off; iclr += 4; if ((ino & 0x20) == 0) @@ -484,7 +483,7 @@ int is_pbm_a) { struct pci_strbuf *strbuf = &pbm->stc; - unsigned long regbase = p->controller_regs; + unsigned long regbase = p->pbm_A.controller_regs; unsigned long err_base, tag_base, line_base; u64 control; int i; @@ -679,7 +678,7 @@ psycho_write(iommu->iommu_control, control | PSYCHO_IOMMU_CTRL_DENAB); for (i = 0; i < 16; i++) { - unsigned long base = p->controller_regs; + unsigned long base = p->pbm_A.controller_regs; iommu_tag[i] = psycho_read(base + PSYCHO_IOMMU_TAG + (i * 8UL)); @@ -756,8 +755,8 @@ static void psycho_ue_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_controller_info *p = dev_id; - unsigned long afsr_reg = p->controller_regs + PSYCHO_UE_AFSR; - unsigned long afar_reg = p->controller_regs + PSYCHO_UE_AFAR; + unsigned long afsr_reg = p->pbm_A.controller_regs + PSYCHO_UE_AFSR; + unsigned long afar_reg = p->pbm_A.controller_regs + PSYCHO_UE_AFAR; unsigned long afsr, afar, error_bits; int reported; @@ -831,8 +830,8 @@ static void psycho_ce_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_controller_info *p = dev_id; - unsigned long afsr_reg = p->controller_regs + PSYCHO_CE_AFSR; - unsigned long afar_reg = p->controller_regs + PSYCHO_CE_AFAR; + unsigned long afsr_reg = p->pbm_A.controller_regs + PSYCHO_CE_AFSR; + unsigned long afar_reg = p->pbm_A.controller_regs + PSYCHO_CE_AFAR; unsigned long afsr, afar, error_bits; int reported; @@ -911,6 +910,42 @@ #define PSYCHO_PCI_AFAR_A 0x2018UL #define PSYCHO_PCI_AFAR_B 0x4018UL +static void psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm_a) +{ + unsigned long csr_reg, csr, csr_error_bits; + u16 stat; + + if (is_pbm_a) { + csr_reg = pbm->controller_regs + PSYCHO_PCIA_CTRL; + } else { + csr_reg = pbm->controller_regs + PSYCHO_PCIB_CTRL; + } + csr = psycho_read(csr_reg); + csr_error_bits = + csr & (PSYCHO_PCICTRL_SBH_ERR | PSYCHO_PCICTRL_SERR); + if (csr_error_bits) { + /* Clear the errors. */ + psycho_write(csr_reg, csr); + + /* Log 'em. */ + if (csr_error_bits & PSYCHO_PCICTRL_SBH_ERR) + printk("%s: PCI streaming byte hole error asserted.\n", + pbm->name); + if (csr_error_bits & PSYCHO_PCICTRL_SERR) + printk("%s: PCI SERR signal asserted.\n", pbm->name); + } + pci_read_config_word(pbm->pci_bus->self, PCI_STATUS, &stat); + if (stat & (PCI_STATUS_PARITY | + PCI_STATUS_SIG_TARGET_ABORT | + PCI_STATUS_REC_TARGET_ABORT | + PCI_STATUS_REC_MASTER_ABORT | + PCI_STATUS_SIG_SYSTEM_ERROR)) { + printk("%s: PCI bus error, PCI_STATUS[%04x]\n", + pbm->name, stat); + pci_write_config_word(pbm->pci_bus->self, PCI_STATUS, 0xffff); + } +} + static void psycho_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_pbm_info *pbm = dev_id; @@ -921,11 +956,11 @@ is_pbm_a = (pbm == &pbm->parent->pbm_A); if (is_pbm_a) { - afsr_reg = p->controller_regs + PSYCHO_PCI_AFSR_A; - afar_reg = p->controller_regs + PSYCHO_PCI_AFAR_A; + afsr_reg = p->pbm_A.controller_regs + PSYCHO_PCI_AFSR_A; + afar_reg = p->pbm_A.controller_regs + PSYCHO_PCI_AFAR_A; } else { - afsr_reg = p->controller_regs + PSYCHO_PCI_AFSR_B; - afar_reg = p->controller_regs + PSYCHO_PCI_AFAR_B; + afsr_reg = p->pbm_A.controller_regs + PSYCHO_PCI_AFSR_B; + afar_reg = p->pbm_A.controller_regs + PSYCHO_PCI_AFAR_B; } /* Latch error status. */ @@ -939,7 +974,7 @@ PSYCHO_PCIAFSR_SMA | PSYCHO_PCIAFSR_STA | PSYCHO_PCIAFSR_SRTRY | PSYCHO_PCIAFSR_SPERR); if (!error_bits) - return; + return psycho_pcierr_intr_other(pbm, is_pbm_a); psycho_write(afsr_reg, error_bits); /* Log the error. */ @@ -1022,8 +1057,8 @@ static void __init psycho_register_error_handlers(struct pci_controller_info *p) { struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ - unsigned long base = p->controller_regs; - unsigned int irq, portid = p->portid; + unsigned long base = p->pbm_A.controller_regs; + unsigned int irq, portid = pbm->portid; u64 tmp; /* Build IRQs and register handlers. */ @@ -1043,6 +1078,7 @@ prom_halt(); } + pbm = &p->pbm_A; irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_PCIERR_A_INO); if (request_irq(irq, psycho_pcierr_intr, SA_SHIRQ, "PSYCHO PCIERR", &p->pbm_A) < 0) { @@ -1051,6 +1087,7 @@ prom_halt(); } + pbm = &p->pbm_B; irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_PCIERR_B_INO); if (request_irq(irq, psycho_pcierr_intr, SA_SHIRQ, "PSYCHO PCIERR", &p->pbm_B) < 0) { @@ -1310,26 +1347,26 @@ iommu->iommu_cur_ctx = 0; /* Register addresses. */ - iommu->iommu_control = p->controller_regs + PSYCHO_IOMMU_CONTROL; - iommu->iommu_tsbbase = p->controller_regs + PSYCHO_IOMMU_TSBBASE; - iommu->iommu_flush = p->controller_regs + PSYCHO_IOMMU_FLUSH; + iommu->iommu_control = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL; + iommu->iommu_tsbbase = p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE; + iommu->iommu_flush = p->pbm_A.controller_regs + PSYCHO_IOMMU_FLUSH; /* PSYCHO's IOMMU lacks ctx flushing. */ iommu->iommu_ctxflush = 0; /* We use the main control register of PSYCHO as the write * completion register. */ - iommu->write_complete_reg = p->controller_regs + PSYCHO_CONTROL; + iommu->write_complete_reg = p->pbm_A.controller_regs + PSYCHO_CONTROL; /* * Invalidate TLB Entries. */ - control = psycho_read(p->controller_regs + PSYCHO_IOMMU_CONTROL); + control = psycho_read(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL); control |= PSYCHO_IOMMU_CTRL_DENAB; - psycho_write(p->controller_regs + PSYCHO_IOMMU_CONTROL, control); + psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL, control); for(i = 0; i < 16; i++) { - psycho_write(p->controller_regs + PSYCHO_IOMMU_TAG + (i * 8UL), 0); - psycho_write(p->controller_regs + PSYCHO_IOMMU_DATA + (i * 8UL), 0); + psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_TAG + (i * 8UL), 0); + psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_DATA + (i * 8UL), 0); } /* Leave diag mode enabled for full-flushing done @@ -1360,16 +1397,16 @@ iommu->alloc_info[i].next = 0; } - psycho_write(p->controller_regs + PSYCHO_IOMMU_TSBBASE, __pa(tsbbase)); + psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE, __pa(tsbbase)); - control = psycho_read(p->controller_regs + PSYCHO_IOMMU_CONTROL); + control = psycho_read(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL); control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ); control |= (PSYCHO_IOMMU_TSBSZ_128K | PSYCHO_IOMMU_CTRL_ENAB); - psycho_write(p->controller_regs + PSYCHO_IOMMU_CONTROL, control); + psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL, control); /* If necessary, hook us up for starfire IRQ translations. */ if(this_is_starfire) - p->starfire_cookie = starfire_hookup(p->portid); + p->starfire_cookie = starfire_hookup(p->pbm_A.portid); else p->starfire_cookie = NULL; } @@ -1391,28 +1428,28 @@ u64 tmp; /* PROM sets the IRQ retry value too low, increase it. */ - psycho_write(p->controller_regs + PSYCHO_IRQ_RETRY, 0xff); + psycho_write(p->pbm_A.controller_regs + PSYCHO_IRQ_RETRY, 0xff); /* Enable arbiter for all PCI slots. */ - tmp = psycho_read(p->controller_regs + PSYCHO_PCIA_CTRL); + tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIA_CTRL); tmp |= PSYCHO_PCICTRL_AEN; - psycho_write(p->controller_regs + PSYCHO_PCIA_CTRL, tmp); + psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIA_CTRL, tmp); - tmp = psycho_read(p->controller_regs + PSYCHO_PCIB_CTRL); + tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIB_CTRL); tmp |= PSYCHO_PCICTRL_AEN; - psycho_write(p->controller_regs + PSYCHO_PCIB_CTRL, tmp); + psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_CTRL, tmp); /* Disable DMA write / PIO read synchronization on * both PCI bus segments. * [ U2P Erratum 1243770, STP2223BGA data sheet ] */ - tmp = psycho_read(p->controller_regs + PSYCHO_PCIA_DIAG); + tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIA_DIAG); tmp |= PSYCHO_PCIDIAG_DDWSYNC; - psycho_write(p->controller_regs + PSYCHO_PCIA_DIAG, tmp); + psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIA_DIAG, tmp); - tmp = psycho_read(p->controller_regs + PSYCHO_PCIB_DIAG); + tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG); tmp |= PSYCHO_PCIDIAG_DDWSYNC; - psycho_write(p->controller_regs + PSYCHO_PCIB_DIAG, tmp); + psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG, tmp); } static void __init pbm_register_toplevel_resources(struct pci_controller_info *p, @@ -1435,7 +1472,7 @@ struct pci_pbm_info *pbm, int is_pbm_a) { - unsigned long base = p->controller_regs; + unsigned long base = pbm->controller_regs; u64 control; if (is_pbm_a) { @@ -1500,14 +1537,21 @@ if (is_pbm_a) { pbm = &p->pbm_A; pbm->pci_first_slot = 1; - pbm->io_space.start = p->controller_regs + PSYCHO_IOSPACE_A; - pbm->mem_space.start = p->controller_regs + PSYCHO_MEMSPACE_A; + pbm->io_space.start = pbm->controller_regs + PSYCHO_IOSPACE_A; + pbm->mem_space.start = pbm->controller_regs + PSYCHO_MEMSPACE_A; } else { pbm = &p->pbm_B; pbm->pci_first_slot = 2; - pbm->io_space.start = p->controller_regs + PSYCHO_IOSPACE_B; - pbm->mem_space.start = p->controller_regs + PSYCHO_MEMSPACE_B; + pbm->io_space.start = pbm->controller_regs + PSYCHO_IOSPACE_B; + pbm->mem_space.start = pbm->controller_regs + PSYCHO_MEMSPACE_B; } + + pbm->chip_type = PBM_CHIP_TYPE_PSYCHO; + pbm->chip_version = + prom_getintdefault(prom_node, "version#", 0); + pbm->chip_revision = + prom_getintdefault(prom_node, "module-revision#", 0); + pbm->io_space.end = pbm->io_space.start + PSYCHO_IOSPACE_SIZE; pbm->io_space.flags = IORESOURCE_IO; pbm->mem_space.end = pbm->mem_space.start + PSYCHO_MEMSPACE_SIZE; @@ -1575,7 +1619,7 @@ spin_lock_irqsave(&pci_controller_lock, flags); for(p = pci_controller_root; p; p = p->next) { - if (p->portid == upa_portid) { + if (p->pbm_A.portid == upa_portid) { spin_unlock_irqrestore(&pci_controller_lock, flags); is_pbm_a = (p->pbm_A.prom_node == 0); psycho_pbm_init(p, node, is_pbm_a); @@ -1603,7 +1647,8 @@ pci_controller_root = p; spin_unlock_irqrestore(&pci_controller_lock, flags); - p->portid = upa_portid; + p->pbm_A.portid = upa_portid; + p->pbm_B.portid = upa_portid; p->index = pci_num_controllers++; p->pbms_same_domain = 0; p->scan_bus = psycho_scan_bus; @@ -1620,9 +1665,10 @@ prom_halt(); } - p->controller_regs = pr_regs[2].phys_addr; + p->pbm_A.controller_regs = pr_regs[2].phys_addr; + p->pbm_B.controller_regs = pr_regs[2].phys_addr; printk("PCI: Found PSYCHO, control regs at %016lx\n", - p->controller_regs); + p->pbm_A.controller_regs); p->pbm_A.config_space = p->pbm_B.config_space = (pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE); Index: arch/sparc64/kernel/pci_sabre.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/pci_sabre.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/pci_sabre.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/pci_sabre.c 4 Aug 2004 01:26:16 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: pci_sabre.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: pci_sabre.c,v 1.2 2004/08/04 01:26:16 joff Exp $ * pci_sabre.c: Sabre specific PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu) @@ -219,6 +219,7 @@ ((unsigned long)(REG))) static int hummingbird_p; +static struct pci_bus *sabre_root_bus; static void *sabre_pci_config_mkaddr(struct pci_pbm_info *pbm, unsigned char bus, @@ -324,16 +325,22 @@ return PCIBIOS_SUCCESSFUL; } +/* When accessing PCI config space of the PCI controller itself (bus + * 0, device slot 0, function 0) there are restrictions. Each + * register must be accessed as it's natural size. Thus, for example + * the Vendor ID must be accessed as a 16-bit quantity. + */ + static int sabre_read_byte(struct pci_dev *dev, int where, u8 *value) { - if (dev->bus->number) - return __sabre_read_byte(dev, where, value); - - if (sabre_out_of_range(dev->devfn)) { + if (!dev->bus->number && sabre_out_of_range(dev->devfn)) { *value = 0xff; return PCIBIOS_SUCCESSFUL; } + if (dev->bus->number || PCI_SLOT(dev->devfn)) + return __sabre_read_byte(dev, where, value); + if (where < 8) { u16 tmp; @@ -349,14 +356,14 @@ static int sabre_read_word(struct pci_dev *dev, int where, u16 *value) { - if (dev->bus->number) - return __sabre_read_word(dev, where, value); - - if (sabre_out_of_range(dev->devfn)) { + if (!dev->bus->number && sabre_out_of_range(dev->devfn)) { *value = 0xffff; return PCIBIOS_SUCCESSFUL; } + if (dev->bus->number || PCI_SLOT(dev->devfn)) + return __sabre_read_word(dev, where, value); + if (where < 8) return __sabre_read_word(dev, where, value); else { @@ -374,14 +381,14 @@ { u16 tmp; - if (dev->bus->number) - return __sabre_read_dword(dev, where, value); - - if (sabre_out_of_range(dev->devfn)) { + if (!dev->bus->number && sabre_out_of_range(dev->devfn)) { *value = 0xffffffff; return PCIBIOS_SUCCESSFUL; } + if (dev->bus->number || PCI_SLOT(dev->devfn)) + return __sabre_read_dword(dev, where, value); + sabre_read_word(dev, where, &tmp); *value = tmp; sabre_read_word(dev, where + 2, &tmp); @@ -630,7 +637,6 @@ struct pci_dev *pdev, unsigned int ino) { - struct pci_controller_info *p = pbm->parent; struct ino_bucket *bucket; unsigned long imap, iclr; unsigned long imap_off, iclr_off; @@ -655,11 +661,11 @@ if (PIL_RESERVED(pil)) BUG(); - imap = p->controller_regs + imap_off; + imap = pbm->controller_regs + imap_off; imap += 4; iclr_off = sabre_iclr_offset(ino); - iclr = p->controller_regs + iclr_off; + iclr = pbm->controller_regs + iclr_off; iclr += 4; if ((ino & 0x20) == 0) @@ -737,7 +743,7 @@ sabre_write(iommu->iommu_control, (control | SABRE_IOMMUCTRL_DENAB)); for (i = 0; i < 16; i++) { - unsigned long base = p->controller_regs; + unsigned long base = p->pbm_A.controller_regs; iommu_tag[i] = sabre_read(base + SABRE_IOMMU_TAG + (i * 8UL)); @@ -786,8 +792,8 @@ static void sabre_ue_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_controller_info *p = dev_id; - unsigned long afsr_reg = p->controller_regs + SABRE_UE_AFSR; - unsigned long afar_reg = p->controller_regs + SABRE_UECE_AFAR; + unsigned long afsr_reg = p->pbm_A.controller_regs + SABRE_UE_AFSR; + unsigned long afar_reg = p->pbm_A.controller_regs + SABRE_UECE_AFAR; unsigned long afsr, afar, error_bits; int reported; @@ -844,8 +850,8 @@ static void sabre_ce_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_controller_info *p = dev_id; - unsigned long afsr_reg = p->controller_regs + SABRE_CE_AFSR; - unsigned long afar_reg = p->controller_regs + SABRE_UECE_AFAR; + unsigned long afsr_reg = p->pbm_A.controller_regs + SABRE_CE_AFSR; + unsigned long afar_reg = p->pbm_A.controller_regs + SABRE_UECE_AFAR; unsigned long afsr, afar, error_bits; int reported; @@ -895,6 +901,38 @@ printk("]\n"); } +static void sabre_pcierr_intr_other(struct pci_controller_info *p) +{ + unsigned long csr_reg, csr, csr_error_bits; + u16 stat; + + csr_reg = p->pbm_A.controller_regs + SABRE_PCICTRL; + csr = sabre_read(csr_reg); + csr_error_bits = + csr & SABRE_PCICTRL_SERR; + if (csr_error_bits) { + /* Clear the errors. */ + sabre_write(csr_reg, csr); + + /* Log 'em. */ + if (csr_error_bits & SABRE_PCICTRL_SERR) + printk("SABRE%d: PCI SERR signal asserted.\n", + p->index); + } + pci_read_config_word(sabre_root_bus->self, + PCI_STATUS, &stat); + if (stat & (PCI_STATUS_PARITY | + PCI_STATUS_SIG_TARGET_ABORT | + PCI_STATUS_REC_TARGET_ABORT | + PCI_STATUS_REC_MASTER_ABORT | + PCI_STATUS_SIG_SYSTEM_ERROR)) { + printk("SABRE%d: PCI bus error, PCI_STATUS[%04x]\n", + p->index, stat); + pci_write_config_word(sabre_root_bus->self, + PCI_STATUS, 0xffff); + } +} + static void sabre_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_controller_info *p = dev_id; @@ -902,8 +940,8 @@ unsigned long afsr, afar, error_bits; int reported; - afsr_reg = p->controller_regs + SABRE_PIOAFSR; - afar_reg = p->controller_regs + SABRE_PIOAFAR; + afsr_reg = p->pbm_A.controller_regs + SABRE_PIOAFSR; + afar_reg = p->pbm_A.controller_regs + SABRE_PIOAFAR; /* Latch error status. */ afar = sabre_read(afar_reg); @@ -916,7 +954,7 @@ SABRE_PIOAFSR_SMA | SABRE_PIOAFSR_STA | SABRE_PIOAFSR_SRTRY | SABRE_PIOAFSR_SPERR); if (!error_bits) - return; + return sabre_pcierr_intr_other(p); sabre_write(afsr_reg, error_bits); /* Log the error. */ @@ -995,8 +1033,8 @@ static void __init sabre_register_error_handlers(struct pci_controller_info *p) { struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ - unsigned long base = p->controller_regs; - unsigned long irq, portid = p->portid; + unsigned long base = pbm->controller_regs; + unsigned long irq, portid = pbm->portid; u64 tmp; /* We clear the error bits in the appropriate AFSR before @@ -1044,13 +1082,12 @@ struct resource *root) { struct pci_pbm_info *pbm = pci_bus2pbm[pdev->bus->number]; - struct pci_controller_info *p = pbm->parent; unsigned long base; if (res->flags & IORESOURCE_IO) - base = p->controller_regs + SABRE_IOSPACE; + base = pbm->controller_regs + SABRE_IOSPACE; else - base = p->controller_regs + SABRE_MEMSPACE; + base = pbm->controller_regs + SABRE_MEMSPACE; res->start += base; res->end += base; @@ -1060,7 +1097,6 @@ { struct pcidev_cookie *pcp = pdev->sysdata; struct pci_pbm_info *pbm = pcp->pbm; - struct pci_controller_info *p = pbm->parent; struct resource *res; unsigned long base; u32 reg; @@ -1078,9 +1114,9 @@ is_64bit = 0; if (res->flags & IORESOURCE_IO) - base = p->controller_regs + SABRE_IOSPACE; + base = pbm->controller_regs + SABRE_IOSPACE; else { - base = p->controller_regs + SABRE_MEMSPACE; + base = pbm->controller_regs + SABRE_MEMSPACE; if ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) is_64bit = 1; @@ -1197,6 +1233,8 @@ pci_fixup_host_bridge_self(sabre_bus); sabre_bus->self->sysdata = cookie; + sabre_root_bus = sabre_bus; + apb_init(p, sabre_bus); sabres_scanned = 0; @@ -1256,21 +1294,21 @@ iommu->iommu_cur_ctx = 0; /* Register addresses. */ - iommu->iommu_control = p->controller_regs + SABRE_IOMMU_CONTROL; - iommu->iommu_tsbbase = p->controller_regs + SABRE_IOMMU_TSBBASE; - iommu->iommu_flush = p->controller_regs + SABRE_IOMMU_FLUSH; - iommu->write_complete_reg = p->controller_regs + SABRE_WRSYNC; + iommu->iommu_control = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL; + iommu->iommu_tsbbase = p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE; + iommu->iommu_flush = p->pbm_A.controller_regs + SABRE_IOMMU_FLUSH; + iommu->write_complete_reg = p->pbm_A.controller_regs + SABRE_WRSYNC; /* Sabre's IOMMU lacks ctx flushing. */ iommu->iommu_ctxflush = 0; /* Invalidate TLB Entries. */ - control = sabre_read(p->controller_regs + SABRE_IOMMU_CONTROL); + control = sabre_read(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL); control |= SABRE_IOMMUCTRL_DENAB; - sabre_write(p->controller_regs + SABRE_IOMMU_CONTROL, control); + sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control); for(i = 0; i < 16; i++) { - sabre_write(p->controller_regs + SABRE_IOMMU_TAG + (i * 8UL), 0); - sabre_write(p->controller_regs + SABRE_IOMMU_DATA + (i * 8UL), 0); + sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TAG + (i * 8UL), 0); + sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_DATA + (i * 8UL), 0); } /* Leave diag mode enabled for full-flushing done @@ -1287,9 +1325,9 @@ iommu->dma_addr_mask = dma_mask; memset((char *)tsbbase, 0, PAGE_SIZE << order); - sabre_write(p->controller_regs + SABRE_IOMMU_TSBBASE, __pa(tsbbase)); + sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE, __pa(tsbbase)); - control = sabre_read(p->controller_regs + SABRE_IOMMU_CONTROL); + control = sabre_read(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL); control &= ~(SABRE_IOMMUCTRL_TSBSZ | SABRE_IOMMUCTRL_TBWSZ); control |= SABRE_IOMMUCTRL_ENAB; switch(tsbsize) { @@ -1306,7 +1344,7 @@ prom_halt(); break; } - sabre_write(p->controller_regs + SABRE_IOMMU_CONTROL, control); + sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control); /* We start with no consistent mappings. */ iommu->lowest_consistent_map = @@ -1322,8 +1360,8 @@ struct pci_pbm_info *pbm) { char *name = pbm->name; - unsigned long ibase = p->controller_regs + SABRE_IOSPACE; - unsigned long mbase = p->controller_regs + SABRE_MEMSPACE; + unsigned long ibase = p->pbm_A.controller_regs + SABRE_IOSPACE; + unsigned long mbase = p->pbm_A.controller_regs + SABRE_MEMSPACE; unsigned int devfn; unsigned long first, last, i; u8 *addr, map; @@ -1416,6 +1454,7 @@ pbm = &p->pbm_B; else pbm = &p->pbm_A; + pbm->chip_type = PBM_CHIP_TYPE_SABRE; pbm->parent = p; pbm->prom_node = node; pbm->pci_first_slot = 1; @@ -1511,11 +1550,11 @@ pbm->io_space.name = pbm->mem_space.name = pbm->name; /* Hack up top-level resources. */ - pbm->io_space.start = p->controller_regs + SABRE_IOSPACE; + pbm->io_space.start = p->pbm_A.controller_regs + SABRE_IOSPACE; pbm->io_space.end = pbm->io_space.start + (1UL << 24) - 1UL; pbm->io_space.flags = IORESOURCE_IO; - pbm->mem_space.start = p->controller_regs + SABRE_MEMSPACE; + pbm->mem_space.start = p->pbm_A.controller_regs + SABRE_MEMSPACE; pbm->mem_space.end = pbm->mem_space.start + (unsigned long)dma_begin - 1UL; pbm->mem_space.flags = IORESOURCE_MEM; @@ -1543,6 +1582,7 @@ u32 busrange[2]; u32 vdma[2]; u32 upa_portid, dma_mask; + u64 clear_irq; int bus; hummingbird_p = 0; @@ -1590,7 +1630,8 @@ pci_controller_root = p; spin_unlock_irqrestore(&pci_controller_lock, flags); - p->portid = upa_portid; + p->pbm_A.portid = upa_portid; + p->pbm_B.portid = upa_portid; p->index = pci_num_controllers++; p->pbms_same_domain = 1; p->scan_bus = sabre_scan_bus; @@ -1613,20 +1654,31 @@ /* * First REG in property is base of entire SABRE register space. */ - p->controller_regs = pr_regs[0].phys_addr; - pci_dma_wsync = p->controller_regs + SABRE_WRSYNC; + p->pbm_A.controller_regs = pr_regs[0].phys_addr; + p->pbm_B.controller_regs = pr_regs[0].phys_addr; + pci_dma_wsync = p->pbm_A.controller_regs + SABRE_WRSYNC; printk("PCI: Found SABRE, main regs at %016lx, wsync at %016lx\n", - p->controller_regs, pci_dma_wsync); + p->pbm_A.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->pbm_A.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->pbm_A.controller_regs + clear_irq, 0x0UL); /* Error interrupts are enabled later after the bus scan. */ - sabre_write(p->controller_regs + SABRE_PCICTRL, + sabre_write(p->pbm_A.controller_regs + SABRE_PCICTRL, (SABRE_PCICTRL_MRLEN | SABRE_PCICTRL_SERR | SABRE_PCICTRL_ARBPARK | SABRE_PCICTRL_AEN)); /* Now map in PCI config space for entire SABRE. */ p->pbm_A.config_space = p->pbm_B.config_space = - (p->controller_regs + SABRE_CONFIGSPACE); + (p->pbm_A.controller_regs + SABRE_CONFIGSPACE); printk("SABRE: Shared PCI config space at %016lx\n", p->pbm_A.config_space); Index: arch/sparc64/kernel/pci_schizo.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/pci_schizo.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/pci_schizo.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/pci_schizo.c 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,7 +1,7 @@ -/* $Id: pci_schizo.c,v 1.1 2004/07/22 19:49:22 joff Exp $ - * pci_schizo.c: SCHIZO specific PCI controller support. +/* $Id: pci_schizo.c,v 1.2 2004/08/04 01:26:17 joff Exp $ + * pci_schizo.c: SCHIZO/TOMATILLO specific PCI controller support. * - * Copyright (C) 2001 David S. Miller (davem@redhat.com) + * Copyright (C) 2001, 2002, 2003 David S. Miller (davem@redhat.com) */ #include @@ -45,13 +45,7 @@ * block requires more space in Schizo's address space than * they predicted, thus requiring an address space reorg when * the newer Schizo is taped out. - * - * These offsets look weird because I keep in p->controller_regs - * the second PROM register property minus 0x10000 which is the - * base of the Safari and UPA64S registers of SCHIZO. */ -#define SCHIZO_PBM_A_REGS_OFF (0x600000UL - 0x400000UL) -#define SCHIZO_PBM_B_REGS_OFF (0x700000UL - 0x400000UL) /* Streaming buffer control register. */ #define SCHIZO_STRBUF_CTRL_LPTR 0x00000000000000f0UL /* LRU Lock Pointer */ @@ -101,25 +95,21 @@ { if (!pbm) return NULL; + bus -= pbm->pci_first_busno; return (void *) (SCHIZO_CONFIG_BASE(pbm) | SCHIZO_CONFIG_ENCODE(bus, devfn, where)); } -/* 4 slots on pbm A, and 6 slots on pbm B. In both cases - * slot 0 is the SCHIZO host bridge itself. - */ +/* Just make sure the bus number is in range. */ static int schizo_out_of_range(struct pci_pbm_info *pbm, unsigned char bus, unsigned char devfn) { - return ((pbm->parent == 0) || - ((pbm == &pbm->parent->pbm_B) && - (bus == pbm->pci_first_busno) && - PCI_SLOT(devfn) > 6) || - ((pbm == &pbm->parent->pbm_A) && - (bus == pbm->pci_first_busno) && - PCI_SLOT(devfn) > 4)); + if (bus < pbm->pci_first_busno || + bus > pbm->pci_last_busno) + return 1; + return 0; } /* SCHIZO PCI configuration space accessors. */ @@ -188,6 +178,15 @@ } pci_config_read32(addr, value); + if (where == PCI_PRIMARY_BUS && + dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && + *value != 0xffffffff) { + u8 *busp = ((u8 *) value) + 1; + int i; + + for (i = 0; i < 3; i++) + busp[i] += pbm->pci_first_busno; + } return PCIBIOS_SUCCESSFUL; } @@ -251,6 +250,20 @@ where); return PCIBIOS_SUCCESSFUL; } + + if (where == PCI_PRIMARY_BUS && + dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { + u8 *busp = ((u8 *) &value) + 1; + int i; + + for (i = 0; i < 3; i++) { + if (busp[i] >= pbm->pci_first_busno) + busp[i] += pbm->pci_first_busno; + else + busp[i] = 0; + } + } + pci_config_write32(addr, value); return PCIBIOS_SUCCESSFUL; } @@ -379,16 +392,10 @@ struct pci_dev *pdev, unsigned int ino) { - struct pci_controller_info *p = pbm->parent; struct ino_bucket *bucket; - unsigned long imap, iclr, pbm_off; + unsigned long imap, iclr; unsigned long imap_off, iclr_off; - int pil; - - if (pbm == &p->pbm_A) - pbm_off = SCHIZO_PBM_A_REGS_OFF; - else - pbm_off = SCHIZO_PBM_B_REGS_OFF; + int pil, ign_fixup; ino &= PCI_IRQ_INO; imap_off = schizo_imap_offset(ino); @@ -399,11 +406,11 @@ if (PIL_RESERVED(pil)) BUG(); - imap = p->controller_regs + pbm_off + imap_off; + imap = pbm->pbm_regs + imap_off; imap += 4; iclr_off = schizo_iclr_offset(ino); - iclr = p->controller_regs + pbm_off + iclr_off; + iclr = pbm->pbm_regs + iclr_off; iclr += 4; /* On Schizo, no inofixup occurs. This is because each @@ -411,8 +418,17 @@ * there is only one IMAP register for each PCI slot even * though four different INOs can be generated by each * PCI slot. + * + * But, for JBUS variants (essentially, Tomatillo), we have + * to fixup the lowest bit of the interrupt group number. */ - bucket = __bucket(build_irq(pil, 0, iclr, imap)); + ign_fixup = 0; + if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) { + if (pbm->portid & 1) + ign_fixup = (1 << 6); + } + + bucket = __bucket(build_irq(pil, ign_fixup, iclr, imap)); bucket->flags |= IBF_PCI; return __irq(bucket); @@ -428,6 +444,13 @@ static unsigned long stc_tag_buf[16]; static unsigned long stc_line_buf[16]; +/* These offsets look weird because I keep in pbm->controller_regs + * the second PROM register property minus 0x10000 which is the + * base of the Safari and UPA64S registers of SCHIZO. + */ +#define SCHIZO_PBM_A_REGS_OFF (0x600000UL - 0x400000UL) +#define SCHIZO_PBM_B_REGS_OFF (0x700000UL - 0x400000UL) + static void schizo_clear_other_err_intr(int irq) { struct ino_bucket *bucket = __bucket(irq); @@ -459,19 +482,12 @@ static void __schizo_check_stc_error_pbm(struct pci_pbm_info *pbm, enum schizo_error_type type) { - struct pci_controller_info *p = pbm->parent; struct pci_strbuf *strbuf = &pbm->stc; - unsigned long regbase = p->controller_regs; + unsigned long regbase = pbm->pbm_regs; unsigned long err_base, tag_base, line_base; u64 control; - char pbm_name = (pbm == &p->pbm_A ? 'A' : 'B'); int i; - if (pbm == &p->pbm_A) - regbase += SCHIZO_PBM_A_REGS_OFF; - else - regbase += SCHIZO_PBM_B_REGS_OFF; - err_base = regbase + SCHIZO_STC_ERR; tag_base = regbase + SCHIZO_STC_TAG; line_base = regbase + SCHIZO_STC_LINE; @@ -517,8 +533,8 @@ unsigned long errval = stc_error_buf[j]; if (errval != 0) { saw_error++; - printk("SCHIZO%d: PBM-%c STC_ERR(%d)[wr(%d)rd(%d)]\n", - p->index, pbm_name, + printk("%s: STC_ERR(%d)[wr(%d)rd(%d)]\n", + pbm->name, j, (errval & SCHIZO_STCERR_WRITE) ? 1 : 0, (errval & SCHIZO_STCERR_READ) ? 1 : 0); @@ -527,8 +543,8 @@ if (saw_error != 0) { unsigned long tagval = stc_tag_buf[i]; unsigned long lineval = stc_line_buf[i]; - printk("SCHIZO%d: PBM-%c STC_TAG(%d)[PA(%016lx)VA(%08lx)V(%d)R(%d)]\n", - p->index, pbm_name, + printk("%s: STC_TAG(%d)[PA(%016lx)VA(%08lx)V(%d)R(%d)]\n", + pbm->name, i, ((tagval & SCHIZO_STCTAG_PPN) >> 19UL), (tagval & SCHIZO_STCTAG_VPN), @@ -536,9 +552,9 @@ ((tagval & SCHIZO_STCTAG_READ) ? 1 : 0)); /* XXX Should spit out per-bank error information... -DaveM */ - printk("SCHIZO%d: PBM-%c STC_LINE(%d)[LIDX(%lx)SP(%lx)LADDR(%lx)EP(%lx)" + printk("%s: STC_LINE(%d)[LIDX(%lx)SP(%lx)LADDR(%lx)EP(%lx)" "V(%d)FOFN(%d)]\n", - p->index, pbm_name, + pbm->name, i, ((lineval & SCHIZO_STCLINE_LINDX) >> 23UL), ((lineval & SCHIZO_STCLINE_SPTR) >> 13UL), @@ -574,13 +590,11 @@ static void schizo_check_iommu_error_pbm(struct pci_pbm_info *pbm, enum schizo_error_type type) { - struct pci_controller_info *p = pbm->parent; struct pci_iommu *iommu = pbm->iommu; unsigned long iommu_tag[16]; unsigned long iommu_data[16]; unsigned long flags; u64 control; - char pbm_name = (pbm == &p->pbm_A ? 'A' : 'B'); int i; spin_lock_irqsave(&iommu->lock, flags); @@ -608,8 +622,8 @@ type_string = "ECC Error"; break; }; - printk("SCHIZO%d: PBM-%c IOMMU Error, type[%s]\n", - p->index, pbm_name, type_string); + printk("%s: IOMMU Error, type[%s]\n", + pbm->name, type_string); /* Put the IOMMU into diagnostic mode and probe * it's TLB for entries with error status. @@ -624,11 +638,7 @@ schizo_write(iommu->iommu_control, control | SCHIZO_IOMMU_CTRL_DENAB); - base = p->controller_regs; - if (pbm == &p->pbm_A) - base += SCHIZO_PBM_A_REGS_OFF; - else - base += SCHIZO_PBM_B_REGS_OFF; + base = pbm->pbm_regs; for (i = 0; i < 16; i++) { iommu_tag[i] = @@ -667,22 +677,23 @@ type_string = "ECC Error"; break; }; - printk("SCHIZO%d: PBM-%c IOMMU TAG(%d)[error(%s) ctx(%x) wr(%d) str(%d) " + printk("%s: IOMMU TAG(%d)[error(%s) ctx(%x) wr(%d) str(%d) " "sz(%dK) vpg(%08lx)]\n", - p->index, pbm_name, i, type_string, + pbm->name, i, type_string, (int)((tag & SCHIZO_IOMMU_TAG_CTXT) >> 25UL), ((tag & SCHIZO_IOMMU_TAG_WRITE) ? 1 : 0), ((tag & SCHIZO_IOMMU_TAG_STREAM) ? 1 : 0), ((tag & SCHIZO_IOMMU_TAG_SIZE) ? 64 : 8), (tag & SCHIZO_IOMMU_TAG_VPAGE) << IOMMU_PAGE_SHIFT); - printk("SCHIZO%d: PBM-%c IOMMU DATA(%d)[valid(%d) cache(%d) ppg(%016lx)]\n", - p->index, pbm_name, i, + printk("%s: IOMMU DATA(%d)[valid(%d) cache(%d) ppg(%016lx)]\n", + pbm->name, i, ((data & SCHIZO_IOMMU_DATA_VALID) ? 1 : 0), ((data & SCHIZO_IOMMU_DATA_CACHE) ? 1 : 0), (data & SCHIZO_IOMMU_DATA_PPAGE) << IOMMU_PAGE_SHIFT); } } - __schizo_check_stc_error_pbm(pbm, type); + if (pbm->stc.strbuf_enabled) + __schizo_check_stc_error_pbm(pbm, type); spin_unlock_irqrestore(&iommu->lock, flags); } @@ -697,26 +708,26 @@ #define SCHIZO_UE_AFSR 0x10030UL #define SCHIZO_UE_AFAR 0x10038UL -#define SCHIZO_UEAFSR_PPIO 0x8000000000000000UL -#define SCHIZO_UEAFSR_PDRD 0x4000000000000000UL -#define SCHIZO_UEAFSR_PDWR 0x2000000000000000UL -#define SCHIZO_UEAFSR_SPIO 0x1000000000000000UL -#define SCHIZO_UEAFSR_SDMA 0x0800000000000000UL -#define SCHIZO_UEAFSR_ERRPNDG 0x0300000000000000UL -#define SCHIZO_UEAFSR_BMSK 0x000003ff00000000UL -#define SCHIZO_UEAFSR_QOFF 0x00000000c0000000UL -#define SCHIZO_UEAFSR_AID 0x000000001f000000UL -#define SCHIZO_UEAFSR_PARTIAL 0x0000000000800000UL -#define SCHIZO_UEAFSR_OWNEDIN 0x0000000000400000UL -#define SCHIZO_UEAFSR_MTAGSYND 0x00000000000f0000UL -#define SCHIZO_UEAFSR_MTAG 0x000000000000e000UL -#define SCHIZO_UEAFSR_ECCSYND 0x00000000000001ffUL +#define SCHIZO_UEAFSR_PPIO 0x8000000000000000UL /* Safari */ +#define SCHIZO_UEAFSR_PDRD 0x4000000000000000UL /* Safari/Tomatillo */ +#define SCHIZO_UEAFSR_PDWR 0x2000000000000000UL /* Safari */ +#define SCHIZO_UEAFSR_SPIO 0x1000000000000000UL /* Safari */ +#define SCHIZO_UEAFSR_SDMA 0x0800000000000000UL /* Safari/Tomatillo */ +#define SCHIZO_UEAFSR_ERRPNDG 0x0300000000000000UL /* Safari */ +#define SCHIZO_UEAFSR_BMSK 0x000003ff00000000UL /* Safari */ +#define SCHIZO_UEAFSR_QOFF 0x00000000c0000000UL /* Safari/Tomatillo */ +#define SCHIZO_UEAFSR_AID 0x000000001f000000UL /* Safari/Tomatillo */ +#define SCHIZO_UEAFSR_PARTIAL 0x0000000000800000UL /* Safari */ +#define SCHIZO_UEAFSR_OWNEDIN 0x0000000000400000UL /* Safari */ +#define SCHIZO_UEAFSR_MTAGSYND 0x00000000000f0000UL /* Safari */ +#define SCHIZO_UEAFSR_MTAG 0x000000000000e000UL /* Safari */ +#define SCHIZO_UEAFSR_ECCSYND 0x00000000000001ffUL /* Safari */ static void schizo_ue_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_controller_info *p = dev_id; - unsigned long afsr_reg = p->controller_regs + SCHIZO_UE_AFSR; - unsigned long afar_reg = p->controller_regs + SCHIZO_UE_AFAR; + unsigned long afsr_reg = p->pbm_B.controller_regs + SCHIZO_UE_AFSR; + unsigned long afar_reg = p->pbm_B.controller_regs + SCHIZO_UE_AFAR; unsigned long afsr, afar, error_bits; int reported, limit; @@ -741,7 +752,7 @@ schizo_write(afsr_reg, error_bits); /* Log the error. */ - printk("SCHIZO%d: Uncorrectable Error, primary error type[%s]\n", + printk("PCI%d: Uncorrectable Error, primary error type[%s]\n", p->index, (((error_bits & SCHIZO_UEAFSR_PPIO) ? "PIO" : @@ -749,20 +760,20 @@ "DMA Read" : ((error_bits & SCHIZO_UEAFSR_PDWR) ? "DMA Write" : "???"))))); - printk("SCHIZO%d: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n", + printk("PCI%d: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n", p->index, (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL, (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL, (afsr & SCHIZO_UEAFSR_AID) >> 24UL); - printk("SCHIZO%d: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n", + printk("PCI%d: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n", p->index, (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0, (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0, (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL, (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL, (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL); - printk("SCHIZO%d: UE AFAR [%016lx]\n", p->index, afar); - printk("SCHIZO%d: UE Secondary errors [", p->index); + printk("PCI%d: UE AFAR [%016lx]\n", p->index, afar); + printk("PCI%d: UE Secondary errors [", p->index); reported = 0; if (afsr & SCHIZO_UEAFSR_SPIO) { reported++; @@ -803,8 +814,8 @@ static void schizo_ce_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_controller_info *p = dev_id; - unsigned long afsr_reg = p->controller_regs + SCHIZO_CE_AFSR; - unsigned long afar_reg = p->controller_regs + SCHIZO_CE_AFAR; + unsigned long afsr_reg = p->pbm_B.controller_regs + SCHIZO_CE_AFSR; + unsigned long afar_reg = p->pbm_B.controller_regs + SCHIZO_CE_AFAR; unsigned long afsr, afar, error_bits; int reported, limit; @@ -829,7 +840,7 @@ schizo_write(afsr_reg, error_bits); /* Log the error. */ - printk("SCHIZO%d: Correctable Error, primary error type[%s]\n", + printk("PCI%d: Correctable Error, primary error type[%s]\n", p->index, (((error_bits & SCHIZO_CEAFSR_PPIO) ? "PIO" : @@ -841,20 +852,20 @@ /* XXX Use syndrome and afar to print out module string just like * XXX UDB CE trap handler does... -DaveM */ - printk("SCHIZO%d: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n", + printk("PCI%d: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n", p->index, (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL, (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL, (afsr & SCHIZO_UEAFSR_AID) >> 24UL); - printk("SCHIZO%d: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n", + printk("PCI%d: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n", p->index, (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0, (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0, (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL, (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL, (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL); - printk("SCHIZO%d: CE AFAR [%016lx]\n", p->index, afar); - printk("SCHIZO%d: CE Secondary errors [", p->index); + printk("PCI%d: CE AFAR [%016lx]\n", p->index, afar); + printk("PCI%d: CE Secondary errors [", p->index); reported = 0; if (afsr & SCHIZO_CEAFSR_SPIO) { reported++; @@ -874,23 +885,101 @@ #define SCHIZO_PCI_AFSR 0x2010UL #define SCHIZO_PCI_AFAR 0x2018UL -#define SCHIZO_PCIAFSR_PMA 0x8000000000000000UL -#define SCHIZO_PCIAFSR_PTA 0x4000000000000000UL -#define SCHIZO_PCIAFSR_PRTRY 0x2000000000000000UL -#define SCHIZO_PCIAFSR_PPERR 0x1000000000000000UL -#define SCHIZO_PCIAFSR_PTTO 0x0800000000000000UL -#define SCHIZO_PCIAFSR_PUNUS 0x0400000000000000UL -#define SCHIZO_PCIAFSR_SMA 0x0200000000000000UL -#define SCHIZO_PCIAFSR_STA 0x0100000000000000UL -#define SCHIZO_PCIAFSR_SRTRY 0x0080000000000000UL -#define SCHIZO_PCIAFSR_SPERR 0x0040000000000000UL -#define SCHIZO_PCIAFSR_STTO 0x0020000000000000UL -#define SCHIZO_PCIAFSR_SUNUS 0x0010000000000000UL -#define SCHIZO_PCIAFSR_BMSK 0x000003ff00000000UL -#define SCHIZO_PCIAFSR_BLK 0x0000000080000000UL -#define SCHIZO_PCIAFSR_CFG 0x0000000040000000UL -#define SCHIZO_PCIAFSR_MEM 0x0000000020000000UL -#define SCHIZO_PCIAFSR_IO 0x0000000010000000UL +#define SCHIZO_PCIAFSR_PMA 0x8000000000000000UL /* Schizo/Tomatillo */ +#define SCHIZO_PCIAFSR_PTA 0x4000000000000000UL /* Schizo/Tomatillo */ +#define SCHIZO_PCIAFSR_PRTRY 0x2000000000000000UL /* Schizo/Tomatillo */ +#define SCHIZO_PCIAFSR_PPERR 0x1000000000000000UL /* Schizo/Tomatillo */ +#define SCHIZO_PCIAFSR_PTTO 0x0800000000000000UL /* Schizo/Tomatillo */ +#define SCHIZO_PCIAFSR_PUNUS 0x0400000000000000UL /* Schizo */ +#define SCHIZO_PCIAFSR_SMA 0x0200000000000000UL /* Schizo/Tomatillo */ +#define SCHIZO_PCIAFSR_STA 0x0100000000000000UL /* Schizo/Tomatillo */ +#define SCHIZO_PCIAFSR_SRTRY 0x0080000000000000UL /* Schizo/Tomatillo */ +#define SCHIZO_PCIAFSR_SPERR 0x0040000000000000UL /* Schizo/Tomatillo */ +#define SCHIZO_PCIAFSR_STTO 0x0020000000000000UL /* Schizo/Tomatillo */ +#define SCHIZO_PCIAFSR_SUNUS 0x0010000000000000UL /* Schizo */ +#define SCHIZO_PCIAFSR_BMSK 0x000003ff00000000UL /* Schizo/Tomatillo */ +#define SCHIZO_PCIAFSR_BLK 0x0000000080000000UL /* Schizo/Tomatillo */ +#define SCHIZO_PCIAFSR_CFG 0x0000000040000000UL /* Schizo/Tomatillo */ +#define SCHIZO_PCIAFSR_MEM 0x0000000020000000UL /* Schizo/Tomatillo */ +#define SCHIZO_PCIAFSR_IO 0x0000000010000000UL /* Schizo/Tomatillo */ + +#define SCHIZO_PCI_CTRL (0x2000UL) +#define SCHIZO_PCICTRL_BUS_UNUS (1UL << 63UL) /* Safari */ +#define SCHIZO_PCICTRL_ARB_PRIO (0x1ff << 52UL) /* Tomatillo */ +#define SCHIZO_PCICTRL_ESLCK (1UL << 51UL) /* Safari */ +#define SCHIZO_PCICTRL_ERRSLOT (7UL << 48UL) /* Safari */ +#define SCHIZO_PCICTRL_TTO_ERR (1UL << 38UL) /* Safari/Tomatillo */ +#define SCHIZO_PCICTRL_RTRY_ERR (1UL << 37UL) /* Safari/Tomatillo */ +#define SCHIZO_PCICTRL_DTO_ERR (1UL << 36UL) /* Safari/Tomatillo */ +#define SCHIZO_PCICTRL_SBH_ERR (1UL << 35UL) /* Safari */ +#define SCHIZO_PCICTRL_SERR (1UL << 34UL) /* Safari/Tomatillo */ +#define SCHIZO_PCICTRL_PCISPD (1UL << 33UL) /* Safari */ +#define SCHIZO_PCICTRL_MRM_PREF (1UL << 28UL) /* Tomatillo */ +#define SCHIZO_PCICTRL_RDO_PREF (1UL << 27UL) /* Tomatillo */ +#define SCHIZO_PCICTRL_RDL_PREF (1UL << 26UL) /* Tomatillo */ +#define SCHIZO_PCICTRL_PTO (3UL << 24UL) /* Safari/Tomatillo */ +#define SCHIZO_PCICTRL_PTO_SHIFT 24UL +#define SCHIZO_PCICTRL_TRWSW (7UL << 21UL) /* Tomatillo */ +#define SCHIZO_PCICTRL_F_TGT_A (1UL << 20UL) /* Tomatillo */ +#define SCHIZO_PCICTRL_S_DTO_INT (1UL << 19UL) /* Safari */ +#define SCHIZO_PCICTRL_F_TGT_RT (1UL << 19UL) /* Tomatillo */ +#define SCHIZO_PCICTRL_SBH_INT (1UL << 18UL) /* Safari */ +#define SCHIZO_PCICTRL_T_DTO_INT (1UL << 18UL) /* Tomatillo */ +#define SCHIZO_PCICTRL_EEN (1UL << 17UL) /* Safari/Tomatillo */ +#define SCHIZO_PCICTRL_PARK (1UL << 16UL) /* Safari/Tomatillo */ +#define SCHIZO_PCICTRL_PCIRST (1UL << 8UL) /* Safari */ +#define SCHIZO_PCICTRL_ARB_S (0x3fUL << 0UL) /* Safari */ +#define SCHIZO_PCICTRL_ARB_T (0xffUL << 0UL) /* Tomatillo */ + +static void schizo_pcierr_intr_other(struct pci_pbm_info *pbm) +{ + unsigned long csr_reg, csr, csr_error_bits; + u16 stat; + + csr_reg = pbm->pbm_regs + SCHIZO_PCI_CTRL; + csr = schizo_read(csr_reg); + csr_error_bits = + csr & (SCHIZO_PCICTRL_BUS_UNUS | + SCHIZO_PCICTRL_TTO_ERR | + SCHIZO_PCICTRL_RTRY_ERR | + SCHIZO_PCICTRL_DTO_ERR | + SCHIZO_PCICTRL_SBH_ERR | + SCHIZO_PCICTRL_SERR); + if (csr_error_bits) { + /* Clear the errors. */ + schizo_write(csr_reg, csr); + + /* Log 'em. */ + if (csr_error_bits & SCHIZO_PCICTRL_BUS_UNUS) + printk("%s: Bus unusable error asserted.\n", + pbm->name); + if (csr_error_bits & SCHIZO_PCICTRL_TTO_ERR) + printk("%s: PCI TRDY# timeout error asserted.\n", + pbm->name); + if (csr_error_bits & SCHIZO_PCICTRL_RTRY_ERR) + printk("%s: PCI excessive retry error asserted.\n", + pbm->name); + if (csr_error_bits & SCHIZO_PCICTRL_DTO_ERR) + printk("%s: PCI discard timeout error asserted.\n", + pbm->name); + if (csr_error_bits & SCHIZO_PCICTRL_SBH_ERR) + printk("%s: PCI streaming byte hole error asserted.\n", + pbm->name); + if (csr_error_bits & SCHIZO_PCICTRL_SERR) + printk("%s: PCI SERR signal asserted.\n", + pbm->name); + } + pci_read_config_word(pbm->pci_bus->self, PCI_STATUS, &stat); + if (stat & (PCI_STATUS_PARITY | + PCI_STATUS_SIG_TARGET_ABORT | + PCI_STATUS_REC_TARGET_ABORT | + PCI_STATUS_REC_MASTER_ABORT | + PCI_STATUS_SIG_SYSTEM_ERROR)) { + printk("%s: PCI bus error, PCI_STATUS[%04x]\n", + pbm->name, stat); + pci_write_config_word(pbm->pci_bus->self, PCI_STATUS, 0xffff); + } +} static void schizo_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs) { @@ -899,16 +988,8 @@ unsigned long afsr_reg, afar_reg, base; unsigned long afsr, afar, error_bits; int reported; - char pbm_name; - base = p->controller_regs; - if (pbm == &pbm->parent->pbm_A) { - base += SCHIZO_PBM_A_REGS_OFF; - pbm_name = 'A'; - } else { - base += SCHIZO_PBM_B_REGS_OFF; - pbm_name = 'B'; - } + base = pbm->pbm_regs; afsr_reg = base + SCHIZO_PCI_AFSR; afar_reg = base + SCHIZO_PCI_AFAR; @@ -926,12 +1007,12 @@ SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR | SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS); if (!error_bits) - return; + return schizo_pcierr_intr_other(pbm); schizo_write(afsr_reg, error_bits); /* Log the error. */ - printk("SCHIZO%d: PBM-%c PCI Error, primary error type[%s]\n", - p->index, pbm_name, + printk("%s: PCI Error, primary error type[%s]\n", + pbm->name, (((error_bits & SCHIZO_PCIAFSR_PMA) ? "Master Abort" : ((error_bits & SCHIZO_PCIAFSR_PTA) ? @@ -944,8 +1025,8 @@ "Timeout" : ((error_bits & SCHIZO_PCIAFSR_PUNUS) ? "Bus Unusable" : "???")))))))); - printk("SCHIZO%d: PBM-%c bytemask[%04lx] was_block(%d) space(%s)\n", - p->index, pbm_name, + printk("%s: bytemask[%04lx] was_block(%d) space(%s)\n", + pbm->name, (afsr & SCHIZO_PCIAFSR_BMSK) >> 32UL, (afsr & SCHIZO_PCIAFSR_BLK) ? 1 : 0, ((afsr & SCHIZO_PCIAFSR_CFG) ? @@ -954,10 +1035,10 @@ "Memory" : ((afsr & SCHIZO_PCIAFSR_IO) ? "I/O" : "???")))); - printk("SCHIZO%d: PBM-%c PCI AFAR [%016lx]\n", - p->index, pbm_name, afar); - printk("SCHIZO%d: PBM-%c PCI Secondary errors [", - p->index, pbm_name); + printk("%s: PCI AFAR [%016lx]\n", + pbm->name, afar); + printk("%s: PCI Secondary errors [", + pbm->name); reported = 0; if (afsr & SCHIZO_PCIAFSR_SMA) { reported++; @@ -1020,24 +1101,37 @@ #define SAFARI_ERRLOG_ERROUT 0x8000000000000000UL -#define SAFARI_ERROR_BADCMD 0x4000000000000000UL -#define SAFARI_ERROR_SSMDIS 0x2000000000000000UL -#define SAFARI_ERROR_BADMA 0x1000000000000000UL -#define SAFARI_ERROR_BADMB 0x0800000000000000UL -#define SAFARI_ERROR_BADMC 0x0400000000000000UL -#define SAFARI_ERROR_CPU1PS 0x0000000000002000UL -#define SAFARI_ERROR_CPU1PB 0x0000000000001000UL -#define SAFARI_ERROR_CPU0PS 0x0000000000000800UL -#define SAFARI_ERROR_CPU0PB 0x0000000000000400UL -#define SAFARI_ERROR_CIQTO 0x0000000000000200UL -#define SAFARI_ERROR_LPQTO 0x0000000000000100UL -#define SAFARI_ERROR_SFPQTO 0x0000000000000080UL -#define SAFARI_ERROR_UFPQTO 0x0000000000000040UL -#define SAFARI_ERROR_APERR 0x0000000000000020UL -#define SAFARI_ERROR_UNMAP 0x0000000000000010UL -#define SAFARI_ERROR_BUSERR 0x0000000000000004UL -#define SAFARI_ERROR_TIMEOUT 0x0000000000000002UL -#define SAFARI_ERROR_ILL 0x0000000000000001UL +#define BUS_ERROR_BADCMD 0x4000000000000000UL /* Schizo/Tomatillo */ +#define BUS_ERROR_SSMDIS 0x2000000000000000UL /* Safari */ +#define BUS_ERROR_BADMA 0x1000000000000000UL /* Safari */ +#define BUS_ERROR_BADMB 0x0800000000000000UL /* Safari */ +#define BUS_ERROR_BADMC 0x0400000000000000UL /* Safari */ +#define BUS_ERROR_SNOOP_GR 0x0000000000200000UL /* Tomatillo */ +#define BUS_ERROR_SNOOP_PCI 0x0000000000100000UL /* Tomatillo */ +#define BUS_ERROR_SNOOP_RD 0x0000000000080000UL /* Tomatillo */ +#define BUS_ERROR_SNOOP_RDS 0x0000000000020000UL /* Tomatillo */ +#define BUS_ERROR_SNOOP_RDSA 0x0000000000010000UL /* Tomatillo */ +#define BUS_ERROR_SNOOP_OWN 0x0000000000008000UL /* Tomatillo */ +#define BUS_ERROR_SNOOP_RDO 0x0000000000004000UL /* Tomatillo */ +#define BUS_ERROR_CPU1PS 0x0000000000002000UL /* Safari */ +#define BUS_ERROR_WDATA_PERR 0x0000000000002000UL /* Tomatillo */ +#define BUS_ERROR_CPU1PB 0x0000000000001000UL /* Safari */ +#define BUS_ERROR_CTRL_PERR 0x0000000000001000UL /* Tomatillo */ +#define BUS_ERROR_CPU0PS 0x0000000000000800UL /* Safari */ +#define BUS_ERROR_SNOOP_ERR 0x0000000000000800UL /* Tomatillo */ +#define BUS_ERROR_CPU0PB 0x0000000000000400UL /* Safari */ +#define BUS_ERROR_JBUS_ILL_B 0x0000000000000400UL /* Tomatillo */ +#define BUS_ERROR_CIQTO 0x0000000000000200UL /* Safari */ +#define BUS_ERROR_LPQTO 0x0000000000000100UL /* Safari */ +#define BUS_ERROR_JBUS_ILL_C 0x0000000000000100UL /* Tomatillo */ +#define BUS_ERROR_SFPQTO 0x0000000000000080UL /* Safari */ +#define BUS_ERROR_UFPQTO 0x0000000000000040UL /* Safari */ +#define BUS_ERROR_RD_PERR 0x0000000000000040UL /* Tomatillo */ +#define BUS_ERROR_APERR 0x0000000000000020UL /* Safari/Tomatillo */ +#define BUS_ERROR_UNMAP 0x0000000000000010UL /* Safari/Tomatillo */ +#define BUS_ERROR_BUSERR 0x0000000000000004UL /* Safari/Tomatillo */ +#define BUS_ERROR_TIMEOUT 0x0000000000000002UL /* Safari/Tomatillo */ +#define BUS_ERROR_ILL 0x0000000000000001UL /* Safari */ /* We only expect UNMAP errors here. The rest of the Safari errors * are marked fatal and thus cause a system reset. @@ -1047,19 +1141,19 @@ struct pci_controller_info *p = dev_id; u64 errlog; - errlog = schizo_read(p->controller_regs + SCHIZO_SAFARI_ERRLOG); - schizo_write(p->controller_regs + SCHIZO_SAFARI_ERRLOG, + errlog = schizo_read(p->pbm_B.controller_regs + SCHIZO_SAFARI_ERRLOG); + schizo_write(p->pbm_B.controller_regs + SCHIZO_SAFARI_ERRLOG, errlog & ~(SAFARI_ERRLOG_ERROUT)); - if (!(errlog & SAFARI_ERROR_UNMAP)) { - printk("SCHIZO%d: Unexpected Safari error interrupt, errlog[%016lx]\n", + if (!(errlog & BUS_ERROR_UNMAP)) { + printk("PCI%d: Unexpected Safari/JBUS error interrupt, errlog[%016lx]\n", p->index, errlog); schizo_clear_other_err_intr(irq); return; } - printk("SCHIZO%d: Safari interrupt, UNMAPPED error, interrogating IOMMUs.\n", + printk("PCI%d: Safari/JBUS interrupt, UNMAPPED error, interrogating IOMMUs.\n", p->index); schizo_check_iommu_error(p, SAFARI_ERR); @@ -1083,131 +1177,279 @@ #define SCHIZO_PCIERR_B_INO 0x33 /* PBM B PCI bus error */ #define SCHIZO_SERR_INO 0x34 /* Safari interface error */ -#define SCHIZO_PCIA_CTRL (SCHIZO_PBM_A_REGS_OFF + 0x2000UL) -#define SCHIZO_PCIB_CTRL (SCHIZO_PBM_B_REGS_OFF + 0x2000UL) -#define SCHIZO_PCICTRL_BUS_UNUS (1UL << 63UL) -#define SCHIZO_PCICTRL_ESLCK (1UL << 51UL) -#define SCHIZO_PCICTRL_ERRSLOT (7UL << 48UL) -#define SCHIZO_PCICTRL_TTO_ERR (1UL << 38UL) -#define SCHIZO_PCICTRL_RTRY_ERR (1UL << 37UL) -#define SCHIZO_PCICTRL_DTO_ERR (1UL << 36UL) -#define SCHIZO_PCICTRL_SBH_ERR (1UL << 35UL) -#define SCHIZO_PCICTRL_SERR (1UL << 34UL) -#define SCHIZO_PCICTRL_PCISPD (1UL << 33UL) -#define SCHIZO_PCICTRL_PTO (3UL << 24UL) -#define SCHIZO_PCICTRL_DTO_INT (1UL << 19UL) -#define SCHIZO_PCICTRL_SBH_INT (1UL << 18UL) -#define SCHIZO_PCICTRL_EEN (1UL << 17UL) -#define SCHIZO_PCICTRL_PARK (1UL << 16UL) -#define SCHIZO_PCICTRL_PCIRST (1UL << 8UL) -#define SCHIZO_PCICTRL_ARB (0x3fUL << 0UL) +struct pci_pbm_info *pbm_for_ino(struct pci_controller_info *p, u32 ino) +{ + ino &= IMAP_INO; + if (p->pbm_A.ino_bitmap & (1UL << ino)) + return &p->pbm_A; + if (p->pbm_B.ino_bitmap & (1UL << ino)) + return &p->pbm_B; + prom_printf("TOMATILLO%d: No entry in ino bitmap for %d\n", + p->index, ino); + prom_halt(); + /* NOTREACHED */ + return NULL; +} + +/* How the Tomatillo IRQs are routed around is pure guesswork here. + * + * All the Tomatillo devices I see in prtconf dumps seem to have only + * a single PCI bus unit attached to it. It would seem they are seperate + * devices because their PortID (ie. JBUS ID) values are all different + * and thus the registers are mapped to totally different locations. + * + * However, two Tomatillo's look "similar" in that the only difference + * in their PortID is the lowest bit. + * + * So if we were to ignore this lower bit, it certainly looks like two + * PCI bus units of the same Tomatillo. I still have not really + * figured this out... + */ +static void __init tomatillo_register_error_handlers(struct pci_controller_info *p) +{ + struct pci_pbm_info *pbm; + unsigned int irq; + struct ino_bucket *bucket; + u64 tmp, err_mask, err_no_mask; + + /* Build IRQs and register handlers. */ + pbm = pbm_for_ino(p, SCHIZO_UE_INO); + irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_UE_INO); + if (request_irq(irq, schizo_ue_intr, + SA_SHIRQ, "TOMATILLO UE", p) < 0) { + prom_printf("%s: Cannot register UE interrupt.\n", + pbm->name); + prom_halt(); + } + bucket = __bucket(irq); + tmp = readl(bucket->imap); + upa_writel(tmp, (pbm->pbm_regs + + schizo_imap_offset(SCHIZO_UE_INO) + 4)); + + pbm = pbm_for_ino(p, SCHIZO_CE_INO); + irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_CE_INO); + if (request_irq(irq, schizo_ce_intr, + SA_SHIRQ, "TOMATILLO CE", p) < 0) { + prom_printf("%s: Cannot register CE interrupt.\n", + pbm->name); + prom_halt(); + } + bucket = __bucket(irq); + tmp = upa_readl(bucket->imap); + upa_writel(tmp, (pbm->pbm_regs + + schizo_imap_offset(SCHIZO_CE_INO) + 4)); + + pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO); + irq = schizo_irq_build(pbm, NULL, ((pbm->portid << 6) | + SCHIZO_PCIERR_A_INO)); + if (request_irq(irq, schizo_pcierr_intr, + SA_SHIRQ, "TOMATILLO PCIERR", pbm) < 0) { + prom_printf("%s: Cannot register PBM A PciERR interrupt.\n", + pbm->name); + prom_halt(); + } + bucket = __bucket(irq); + tmp = upa_readl(bucket->imap); + upa_writel(tmp, (pbm->pbm_regs + + schizo_imap_offset(SCHIZO_PCIERR_A_INO) + 4)); + + pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO); + irq = schizo_irq_build(pbm, NULL, ((pbm->portid << 6) | + SCHIZO_PCIERR_B_INO)); + if (request_irq(irq, schizo_pcierr_intr, + SA_SHIRQ, "TOMATILLO PCIERR", pbm) < 0) { + prom_printf("%s: Cannot register PBM B PciERR interrupt.\n", + pbm->name); + prom_halt(); + } + bucket = __bucket(irq); + tmp = upa_readl(bucket->imap); + upa_writel(tmp, (pbm->pbm_regs + + schizo_imap_offset(SCHIZO_PCIERR_B_INO) + 4)); + + pbm = pbm_for_ino(p, SCHIZO_SERR_INO); + irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_SERR_INO); + if (request_irq(irq, schizo_safarierr_intr, + SA_SHIRQ, "TOMATILLO SERR", p) < 0) { + prom_printf("%s: Cannot register SafariERR interrupt.\n", + pbm->name); + prom_halt(); + } + bucket = __bucket(irq); + tmp = upa_readl(bucket->imap); + upa_writel(tmp, (pbm->pbm_regs + + schizo_imap_offset(SCHIZO_SERR_INO) + 4)); + + /* Enable UE and CE interrupts for controller. */ + schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL, + (SCHIZO_ECCCTRL_EE | + SCHIZO_ECCCTRL_UE | + SCHIZO_ECCCTRL_CE)); + + schizo_write(p->pbm_B.controller_regs + SCHIZO_ECC_CTRL, + (SCHIZO_ECCCTRL_EE | + SCHIZO_ECCCTRL_UE | + SCHIZO_ECCCTRL_CE)); + + /* Enable PCI Error interrupts and clear error + * bits. + */ + err_mask = (SCHIZO_PCICTRL_BUS_UNUS | + SCHIZO_PCICTRL_TTO_ERR | + SCHIZO_PCICTRL_RTRY_ERR | + SCHIZO_PCICTRL_SERR | + SCHIZO_PCICTRL_EEN); + + err_no_mask = SCHIZO_PCICTRL_DTO_ERR; + + tmp = schizo_read(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL); + tmp |= err_mask; + tmp &= ~err_no_mask; + schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL, tmp); + + tmp = schizo_read(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL); + tmp |= err_mask; + tmp &= ~err_no_mask; + schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL, tmp); + + err_mask = (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | + SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | + SCHIZO_PCIAFSR_PTTO | + SCHIZO_PCIAFSR_SMA | SCHIZO_PCIAFSR_STA | + SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR | + SCHIZO_PCIAFSR_STTO); + + schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_AFSR, err_mask); + schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_AFSR, err_mask); + + err_mask = (BUS_ERROR_BADCMD | BUS_ERROR_SNOOP_GR | + BUS_ERROR_SNOOP_PCI | BUS_ERROR_SNOOP_RD | + BUS_ERROR_SNOOP_RDS | BUS_ERROR_SNOOP_RDSA | + BUS_ERROR_SNOOP_OWN | BUS_ERROR_SNOOP_RDO | + BUS_ERROR_WDATA_PERR | BUS_ERROR_CTRL_PERR | + BUS_ERROR_SNOOP_ERR | BUS_ERROR_JBUS_ILL_B | + BUS_ERROR_JBUS_ILL_C | BUS_ERROR_RD_PERR | + BUS_ERROR_APERR | BUS_ERROR_UNMAP | + BUS_ERROR_BUSERR | BUS_ERROR_TIMEOUT); + + schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_ERRCTRL, + (SCHIZO_SAFERRCTRL_EN | err_mask)); + schizo_write(p->pbm_B.controller_regs + SCHIZO_SAFARI_ERRCTRL, + (SCHIZO_SAFERRCTRL_EN | err_mask)); + + schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_IRQCTRL, + (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); + schizo_write(p->pbm_B.controller_regs + SCHIZO_SAFARI_IRQCTRL, + (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); +} static void __init schizo_register_error_handlers(struct pci_controller_info *p) { - struct pci_pbm_info *pbm_a = &p->pbm_A; - struct pci_pbm_info *pbm_b = &p->pbm_B; - unsigned long base = p->controller_regs; - unsigned int irq, portid = p->portid; + struct pci_pbm_info *pbm; + unsigned int irq; struct ino_bucket *bucket; - u64 tmp; + u64 tmp, err_mask, err_no_mask; /* Build IRQs and register handlers. */ - irq = schizo_irq_build(pbm_b, NULL, (portid << 6) | SCHIZO_UE_INO); + pbm = pbm_for_ino(p, SCHIZO_UE_INO); + irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_UE_INO); if (request_irq(irq, schizo_ue_intr, SA_SHIRQ, "SCHIZO UE", p) < 0) { - prom_printf("SCHIZO%d: Cannot register UE interrupt.\n", - p->index); + prom_printf("%s: Cannot register UE interrupt.\n", + pbm->name); prom_halt(); } bucket = __bucket(irq); tmp = readl(bucket->imap); - upa_writel(tmp, (base + SCHIZO_PBM_B_REGS_OFF + schizo_imap_offset(SCHIZO_UE_INO) + 4)); + upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_UE_INO) + 4)); - irq = schizo_irq_build(pbm_b, NULL, (portid << 6) | SCHIZO_CE_INO); + pbm = pbm_for_ino(p, SCHIZO_CE_INO); + irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_CE_INO); if (request_irq(irq, schizo_ce_intr, SA_SHIRQ, "SCHIZO CE", p) < 0) { - prom_printf("SCHIZO%d: Cannot register CE interrupt.\n", - p->index); + prom_printf("%s: Cannot register CE interrupt.\n", + pbm->name); prom_halt(); } bucket = __bucket(irq); tmp = upa_readl(bucket->imap); - upa_writel(tmp, (base + SCHIZO_PBM_B_REGS_OFF + schizo_imap_offset(SCHIZO_CE_INO) + 4)); + upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_CE_INO) + 4)); - irq = schizo_irq_build(pbm_a, NULL, (portid << 6) | SCHIZO_PCIERR_A_INO); + pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO); + irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_PCIERR_A_INO); if (request_irq(irq, schizo_pcierr_intr, - SA_SHIRQ, "SCHIZO PCIERR", pbm_a) < 0) { - prom_printf("SCHIZO%d(PBMA): Cannot register PciERR interrupt.\n", - p->index); + SA_SHIRQ, "SCHIZO PCIERR", pbm) < 0) { + prom_printf("%s: Cannot register PBM A PciERR interrupt.\n", + pbm->name); prom_halt(); } bucket = __bucket(irq); tmp = upa_readl(bucket->imap); - upa_writel(tmp, (base + SCHIZO_PBM_A_REGS_OFF + schizo_imap_offset(SCHIZO_PCIERR_A_INO) + 4)); + upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_PCIERR_A_INO) + 4)); - irq = schizo_irq_build(pbm_b, NULL, (portid << 6) | SCHIZO_PCIERR_B_INO); + pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO); + irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_PCIERR_B_INO); if (request_irq(irq, schizo_pcierr_intr, - SA_SHIRQ, "SCHIZO PCIERR", pbm_b) < 0) { - prom_printf("SCHIZO%d(PBMB): Cannot register PciERR interrupt.\n", - p->index); + SA_SHIRQ, "SCHIZO PCIERR", &p->pbm_B) < 0) { + prom_printf("%s: Cannot register PBM B PciERR interrupt.\n", + pbm->name); prom_halt(); } bucket = __bucket(irq); tmp = upa_readl(bucket->imap); - upa_writel(tmp, (base + SCHIZO_PBM_B_REGS_OFF + schizo_imap_offset(SCHIZO_PCIERR_B_INO) + 4)); + upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_PCIERR_B_INO) + 4)); - irq = schizo_irq_build(pbm_b, NULL, (portid << 6) | SCHIZO_SERR_INO); + pbm = pbm_for_ino(p, SCHIZO_SERR_INO); + irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_SERR_INO); if (request_irq(irq, schizo_safarierr_intr, SA_SHIRQ, "SCHIZO SERR", p) < 0) { - prom_printf("SCHIZO%d(PBMB): Cannot register SafariERR interrupt.\n", - p->index); + prom_printf("%s: Cannot register SafariERR interrupt.\n", + pbm->name); prom_halt(); } bucket = __bucket(irq); tmp = upa_readl(bucket->imap); - upa_writel(tmp, (base + SCHIZO_PBM_B_REGS_OFF + schizo_imap_offset(SCHIZO_SERR_INO) + 4)); + upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_SERR_INO) + 4)); /* Enable UE and CE interrupts for controller. */ - schizo_write(base + SCHIZO_ECC_CTRL, + schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL, (SCHIZO_ECCCTRL_EE | SCHIZO_ECCCTRL_UE | SCHIZO_ECCCTRL_CE)); + err_mask = (SCHIZO_PCICTRL_BUS_UNUS | + SCHIZO_PCICTRL_ESLCK | + SCHIZO_PCICTRL_TTO_ERR | + SCHIZO_PCICTRL_RTRY_ERR | + SCHIZO_PCICTRL_SBH_ERR | + SCHIZO_PCICTRL_SERR | + SCHIZO_PCICTRL_SBH_INT | + SCHIZO_PCICTRL_EEN); + + err_no_mask = SCHIZO_PCICTRL_DTO_ERR; + /* Enable PCI Error interrupts and clear error * bits for each PBM. */ - tmp = schizo_read(base + SCHIZO_PCIA_CTRL); - tmp |= (SCHIZO_PCICTRL_BUS_UNUS | - SCHIZO_PCICTRL_ESLCK | - SCHIZO_PCICTRL_TTO_ERR | - SCHIZO_PCICTRL_RTRY_ERR | - SCHIZO_PCICTRL_DTO_ERR | - SCHIZO_PCICTRL_SBH_ERR | - SCHIZO_PCICTRL_SERR | - SCHIZO_PCICTRL_SBH_INT | - SCHIZO_PCICTRL_EEN); - schizo_write(base + SCHIZO_PCIA_CTRL, tmp); - - tmp = schizo_read(base + SCHIZO_PCIB_CTRL); - tmp |= (SCHIZO_PCICTRL_BUS_UNUS | - SCHIZO_PCICTRL_ESLCK | - SCHIZO_PCICTRL_TTO_ERR | - SCHIZO_PCICTRL_RTRY_ERR | - SCHIZO_PCICTRL_DTO_ERR | - SCHIZO_PCICTRL_SBH_ERR | - SCHIZO_PCICTRL_SERR | - SCHIZO_PCICTRL_SBH_INT | - SCHIZO_PCICTRL_EEN); - schizo_write(base + SCHIZO_PCIB_CTRL, tmp); + tmp = schizo_read(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL); + tmp |= err_mask; + tmp &= ~err_no_mask; + schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL, tmp); - schizo_write(base + SCHIZO_PBM_A_REGS_OFF + SCHIZO_PCI_AFSR, + schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_AFSR, (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS | SCHIZO_PCIAFSR_SMA | SCHIZO_PCIAFSR_STA | SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR | SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS)); - schizo_write(base + SCHIZO_PBM_B_REGS_OFF + SCHIZO_PCI_AFSR, + + tmp = schizo_read(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL); + tmp |= err_mask; + tmp &= ~err_no_mask; + schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL, tmp); + + schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_AFSR, (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS | @@ -1215,9 +1457,19 @@ SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR | SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS)); - /* Make all Safari error conditions fatal except unmapped errors - * which we make generate interrupts. + /* Make all Safari error conditions fatal except unmapped + * errors which we make generate interrupts. */ + err_mask = (BUS_ERROR_BADCMD | BUS_ERROR_SSMDIS | + BUS_ERROR_BADMA | BUS_ERROR_BADMB | + BUS_ERROR_BADMC | + BUS_ERROR_CPU1PS | BUS_ERROR_CPU1PB | + BUS_ERROR_CPU0PS | BUS_ERROR_CPU0PB | + BUS_ERROR_CIQTO | + BUS_ERROR_LPQTO | BUS_ERROR_SFPQTO | + BUS_ERROR_UFPQTO | BUS_ERROR_APERR | + BUS_ERROR_BUSERR | BUS_ERROR_TIMEOUT | + BUS_ERROR_ILL); #if 1 /* XXX Something wrong with some Excalibur systems * XXX Sun is shipping. The behavior on a 2-cpu @@ -1226,53 +1478,26 @@ * XXX their error status bits are cleared. Just * XXX ignore them for now. -DaveM */ - schizo_write(base + SCHIZO_SAFARI_ERRCTRL, - (SCHIZO_SAFERRCTRL_EN | - (SAFARI_ERROR_BADCMD | SAFARI_ERROR_SSMDIS | - SAFARI_ERROR_BADMA | SAFARI_ERROR_BADMB | - SAFARI_ERROR_BADMC | - SAFARI_ERROR_CIQTO | - SAFARI_ERROR_LPQTO | SAFARI_ERROR_SFPQTO | - SAFARI_ERROR_UFPQTO | SAFARI_ERROR_APERR | - SAFARI_ERROR_BUSERR | SAFARI_ERROR_TIMEOUT | - SAFARI_ERROR_ILL))); -#else - schizo_write(base + SCHIZO_SAFARI_ERRCTRL, - (SCHIZO_SAFERRCTRL_EN | - (SAFARI_ERROR_BADCMD | SAFARI_ERROR_SSMDIS | - SAFARI_ERROR_BADMA | SAFARI_ERROR_BADMB | - SAFARI_ERROR_BADMC | - SAFARI_ERROR_CPU1PS | SAFARI_ERROR_CPU1PB | - SAFARI_ERROR_CPU0PS | SAFARI_ERROR_CPU0PB | - SAFARI_ERROR_CIQTO | - SAFARI_ERROR_LPQTO | SAFARI_ERROR_SFPQTO | - SAFARI_ERROR_UFPQTO | SAFARI_ERROR_APERR | - SAFARI_ERROR_BUSERR | SAFARI_ERROR_TIMEOUT | - SAFARI_ERROR_ILL))); + err_mask &= ~(BUS_ERROR_CPU1PS | BUS_ERROR_CPU1PB | + BUS_ERROR_CPU0PS | BUS_ERROR_CPU0PB); #endif - schizo_write(base + SCHIZO_SAFARI_IRQCTRL, - (SCHIZO_SAFIRQCTRL_EN | (SAFARI_ERROR_UNMAP))); + schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_ERRCTRL, + (SCHIZO_SAFERRCTRL_EN | err_mask)); + + schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_IRQCTRL, + (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); } /* We have to do the config space accesses by hand, thus... */ -#define PBM_BRIDGE_BUS 0x40 -#define PBM_BRIDGE_SUBORDINATE 0x41 static void __init pbm_renumber(struct pci_pbm_info *pbm, u8 orig_busno) { - u8 *addr, busno; + u8 busno; int nbus; busno = pci_highest_busnum; nbus = pbm->pci_last_busno - pbm->pci_first_busno; - addr = schizo_pci_config_mkaddr(pbm, orig_busno, - 0, PBM_BRIDGE_BUS); - pci_config_write8(addr, busno); - addr = schizo_pci_config_mkaddr(pbm, busno, - 0, PBM_BRIDGE_SUBORDINATE); - pci_config_write8(addr, busno + nbus); - pbm->pci_first_busno = busno; pbm->pci_last_busno = busno + nbus; pci_highest_busnum = busno + nbus + 1; @@ -1282,75 +1507,8 @@ } while (nbus--); } -/* We have to do the config space accesses by hand here since - * the pci_bus2pbm array is not ready yet. - */ -static void __init pbm_pci_bridge_renumber(struct pci_pbm_info *pbm, - u8 busno) -{ - u32 devfn, l, class; - u8 hdr_type; - int is_multi = 0; - - for(devfn = 0; devfn < 0xff; ++devfn) { - u32 *dwaddr; - u8 *baddr; - - if (PCI_FUNC(devfn) != 0 && is_multi == 0) - continue; - - /* Anything there? */ - dwaddr = schizo_pci_config_mkaddr(pbm, busno, devfn, PCI_VENDOR_ID); - l = 0xffffffff; - pci_config_read32(dwaddr, &l); - if (l == 0xffffffff || l == 0x00000000 || - l == 0x0000ffff || l == 0xffff0000) { - is_multi = 0; - continue; - } - - baddr = schizo_pci_config_mkaddr(pbm, busno, devfn, PCI_HEADER_TYPE); - pci_config_read8(baddr, &hdr_type); - if (PCI_FUNC(devfn) == 0) - is_multi = hdr_type & 0x80; - - dwaddr = schizo_pci_config_mkaddr(pbm, busno, devfn, PCI_CLASS_REVISION); - class = 0xffffffff; - pci_config_read32(dwaddr, &class); - if ((class >> 16) == PCI_CLASS_BRIDGE_PCI) { - u32 buses = 0xffffffff; - - dwaddr = schizo_pci_config_mkaddr(pbm, busno, devfn, - PCI_PRIMARY_BUS); - pci_config_read32(dwaddr, &buses); - pbm_pci_bridge_renumber(pbm, (buses >> 8) & 0xff); - buses &= 0xff000000; - pci_config_write32(dwaddr, buses); - } - } -} - static void __init pbm_bridge_reconfigure(struct pci_controller_info *p) { - struct pci_pbm_info *pbm; - u8 *addr; - - /* Clear out primary/secondary/subordinate bus numbers on - * all PCI-to-PCI bridges under each PBM. The generic bus - * probing will fix them up. - */ - pbm_pci_bridge_renumber(&p->pbm_B, p->pbm_B.pci_first_busno); - pbm_pci_bridge_renumber(&p->pbm_A, p->pbm_A.pci_first_busno); - - /* Move PBM A out of the way. */ - pbm = &p->pbm_A; - addr = schizo_pci_config_mkaddr(pbm, pbm->pci_first_busno, - 0, PBM_BRIDGE_BUS); - pci_config_write8(addr, 0xff); - addr = schizo_pci_config_mkaddr(pbm, 0xff, - 0, PBM_BRIDGE_SUBORDINATE); - pci_config_write8(addr, 0xff); - /* Now we can safely renumber both PBMs. */ pbm_renumber(&p->pbm_B, p->pbm_B.pci_first_busno); pbm_renumber(&p->pbm_A, 0xff); @@ -1379,7 +1537,7 @@ struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL); if (!cookie) { - prom_printf("SCHIZO: Critical allocation failure.\n"); + prom_printf("%s: Critical allocation failure.\n", pbm->name); prom_halt(); } @@ -1401,20 +1559,42 @@ pci_setup_busmastering(pbm, pbm->pci_bus); } -static void __init schizo_scan_bus(struct pci_controller_info *p) +static void __init __schizo_scan_bus(struct pci_controller_info *p, + int chip_type) { + if (!p->pbm_B.prom_node || !p->pbm_A.prom_node) { + printk("PCI: Only one PCI bus module of controller found.\n"); + printk("PCI: Ignoring entire controller.\n"); + return; + } + pbm_bridge_reconfigure(p); pbm_config_busmastering(&p->pbm_B); - p->pbm_B.is_66mhz_capable = 0; + p->pbm_B.is_66mhz_capable = + prom_getbool(p->pbm_B.prom_node, "66mhz-capable"); pbm_config_busmastering(&p->pbm_A); - p->pbm_A.is_66mhz_capable = 1; + p->pbm_A.is_66mhz_capable = + prom_getbool(p->pbm_A.prom_node, "66mhz-capable"); pbm_scan_bus(p, &p->pbm_B); pbm_scan_bus(p, &p->pbm_A); /* After the PCI bus scan is complete, we can register * the error interrupt handlers. */ - schizo_register_error_handlers(p); + if (chip_type == PBM_CHIP_TYPE_TOMATILLO) + tomatillo_register_error_handlers(p); + else + schizo_register_error_handlers(p); +} + +static void __init schizo_scan_bus(struct pci_controller_info *p) +{ + __schizo_scan_bus(p, PBM_CHIP_TYPE_SCHIZO); +} + +static void __init tomatillo_scan_bus(struct pci_controller_info *p) +{ + __schizo_scan_bus(p, PBM_CHIP_TYPE_TOMATILLO); } static void __init schizo_base_address_update(struct pci_dev *pdev, int resource) @@ -1470,68 +1650,72 @@ res->end += root->start; } -/* Interrogate Safari match/mask registers to figure out where - * PCI MEM, I/O, and Config space are for this PCI bus module. +/* Use ranges property to determine where PCI MEM, I/O, and Config + * space are for this PCI bus module. */ +static void schizo_determine_mem_io_space(struct pci_pbm_info *pbm) +{ + int i, saw_cfg, saw_mem, saw_io; -#define SCHIZO_PCI_A_MEM_MATCH 0x00040UL -#define SCHIZO_PCI_A_MEM_MASK 0x00048UL -#define SCHIZO_PCI_A_IO_MATCH 0x00050UL -#define SCHIZO_PCI_A_IO_MASK 0x00058UL -#define SCHIZO_PCI_B_MEM_MATCH 0x00060UL -#define SCHIZO_PCI_B_MEM_MASK 0x00068UL -#define SCHIZO_PCI_B_IO_MATCH 0x00070UL -#define SCHIZO_PCI_B_IO_MASK 0x00078UL - -static void schizo_determine_mem_io_space(struct pci_pbm_info *pbm, - int is_pbm_a, unsigned long reg_base) -{ - u64 mem_match, mem_mask; - u64 io_match; - u64 a; - - if (is_pbm_a) { - mem_match = reg_base + SCHIZO_PCI_A_MEM_MATCH; - io_match = reg_base + SCHIZO_PCI_A_IO_MATCH; - } else { - mem_match = reg_base + SCHIZO_PCI_B_MEM_MATCH; - io_match = reg_base + SCHIZO_PCI_B_IO_MATCH; - } - mem_mask = mem_match + 0x8UL; + saw_cfg = saw_mem = saw_io = 0; + for (i = 0; i < pbm->num_pbm_ranges; i++) { + struct linux_prom_pci_ranges *pr = &pbm->pbm_ranges[i]; + unsigned long a; + int type; - a = schizo_read(mem_match) & ~0x8000000000000000UL; + type = (pr->child_phys_hi >> 24) & 0x3; + a = (((unsigned long)pr->parent_phys_hi << 32UL) | + ((unsigned long)pr->parent_phys_lo << 0UL)); - /* It should be 2GB in size but the decode is set for the full - * 4GB so we have to add the 2G by hand. - */ - pbm->mem_space.start = a; - pbm->mem_space.end = a + 0x80000000; - pbm->mem_space.flags = IORESOURCE_MEM; + switch (type) { + case 0: + /* PCI config space, 16MB */ + pbm->config_space = a; + saw_cfg = 1; + break; - /* This 32MB area is divided into two pieces. The first - * 16MB is Config space, the next 16MB is I/O space. - */ + case 1: + /* 16-bit IO space, 16MB */ + pbm->io_space.start = a; + pbm->io_space.end = a + ((16UL*1024UL*1024UL) - 1UL); + pbm->io_space.flags = IORESOURCE_IO; + saw_io = 1; + break; - a = schizo_read(io_match) & ~0x8000000000000000UL; - pbm->config_space = a; - printk("SCHIZO PBM%c: Local PCI config space at %016lx\n", - (is_pbm_a ? 'A' : 'B'), pbm->config_space); + case 2: + /* 32-bit MEM space, 2GB */ + pbm->mem_space.start = a; + pbm->mem_space.end = a + (0x80000000UL - 1UL); + pbm->mem_space.flags = IORESOURCE_MEM; + saw_mem = 1; + break; + + default: + break; + }; + } - a += (16UL * 1024UL * 1024UL); - pbm->io_space.start = a; - pbm->io_space.end = a + ((16UL * 1024UL * 1024UL) - 1UL); - pbm->io_space.flags = IORESOURCE_IO; + if (!saw_cfg || !saw_io || !saw_mem) { + prom_printf("%s: Fatal error, missing %s PBM range.\n", + pbm->name, + ((!saw_cfg ? + "CFG" : + (!saw_io ? + "IO" : "MEM")))); + prom_halt(); + } + + printk("%s: PCI CFG[%lx] IO[%lx] MEM[%lx]\n", + pbm->name, + pbm->config_space, + pbm->io_space.start, + pbm->mem_space.start); } static void __init pbm_register_toplevel_resources(struct pci_controller_info *p, struct pci_pbm_info *pbm) { - char *name = pbm->name; - - sprintf(name, "SCHIZO%d PBM%c", - p->index, - (pbm == &p->pbm_A ? 'A' : 'B')); - pbm->io_space.name = pbm->mem_space.name = name; + pbm->io_space.name = pbm->mem_space.name = pbm->name; request_resource(&ioport_resource, &pbm->io_space); request_resource(&iomem_resource, &pbm->mem_space); @@ -1539,40 +1723,29 @@ &pbm->mem_space); } -#define SCHIZO_STRBUF_CONTROL_A (SCHIZO_PBM_A_REGS_OFF + 0x02800UL) -#define SCHIZO_STRBUF_FLUSH_A (SCHIZO_PBM_A_REGS_OFF + 0x02808UL) -#define SCHIZO_STRBUF_FSYNC_A (SCHIZO_PBM_A_REGS_OFF + 0x02810UL) -#define SCHIZO_STRBUF_CTXFLUSH_A (SCHIZO_PBM_A_REGS_OFF + 0x02818UL) -#define SCHIZO_STRBUF_CTXMATCH_A (SCHIZO_PBM_A_REGS_OFF + 0x10000UL) - -#define SCHIZO_STRBUF_CONTROL_B (SCHIZO_PBM_B_REGS_OFF + 0x02800UL) -#define SCHIZO_STRBUF_FLUSH_B (SCHIZO_PBM_B_REGS_OFF + 0x02808UL) -#define SCHIZO_STRBUF_FSYNC_B (SCHIZO_PBM_B_REGS_OFF + 0x02810UL) -#define SCHIZO_STRBUF_CTXFLUSH_B (SCHIZO_PBM_B_REGS_OFF + 0x02818UL) -#define SCHIZO_STRBUF_CTXMATCH_B (SCHIZO_PBM_B_REGS_OFF + 0x10000UL) - -static void schizo_pbm_strbuf_init(struct pci_controller_info *p, - struct pci_pbm_info *pbm, - int is_pbm_a) +#define SCHIZO_STRBUF_CONTROL (0x02800UL) +#define SCHIZO_STRBUF_FLUSH (0x02808UL) +#define SCHIZO_STRBUF_FSYNC (0x02810UL) +#define SCHIZO_STRBUF_CTXFLUSH (0x02818UL) +#define SCHIZO_STRBUF_CTXMATCH (0x10000UL) + +static void schizo_pbm_strbuf_init(struct pci_pbm_info *pbm) { - unsigned long base = p->controller_regs; + unsigned long base = pbm->pbm_regs; u64 control; - /* SCHIZO has context flushing. */ - if (is_pbm_a) { - pbm->stc.strbuf_control = base + SCHIZO_STRBUF_CONTROL_A; - pbm->stc.strbuf_pflush = base + SCHIZO_STRBUF_FLUSH_A; - pbm->stc.strbuf_fsync = base + SCHIZO_STRBUF_FSYNC_A; - pbm->stc.strbuf_ctxflush = base + SCHIZO_STRBUF_CTXFLUSH_A; - pbm->stc.strbuf_ctxmatch_base = base + SCHIZO_STRBUF_CTXMATCH_A; - } else { - pbm->stc.strbuf_control = base + SCHIZO_STRBUF_CONTROL_B; - pbm->stc.strbuf_pflush = base + SCHIZO_STRBUF_FLUSH_B; - pbm->stc.strbuf_fsync = base + SCHIZO_STRBUF_FSYNC_B; - pbm->stc.strbuf_ctxflush = base + SCHIZO_STRBUF_CTXFLUSH_B; - pbm->stc.strbuf_ctxmatch_base = base + SCHIZO_STRBUF_CTXMATCH_B; + if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) { + /* TOMATILLO lacks streaming cache. */ + return; } + /* SCHIZO has context flushing. */ + pbm->stc.strbuf_control = base + SCHIZO_STRBUF_CONTROL; + pbm->stc.strbuf_pflush = base + SCHIZO_STRBUF_FLUSH; + pbm->stc.strbuf_fsync = base + SCHIZO_STRBUF_FSYNC; + pbm->stc.strbuf_ctxflush = base + SCHIZO_STRBUF_CTXFLUSH; + pbm->stc.strbuf_ctxmatch_base = base + SCHIZO_STRBUF_CTXMATCH; + pbm->stc.strbuf_flushflag = (volatile unsigned long *) ((((unsigned long)&pbm->stc.__flushflag_buf[0]) + 63UL) @@ -1594,48 +1767,63 @@ pbm->stc.strbuf_enabled = 1; } -#define SCHIZO_IOMMU_CONTROL_A (SCHIZO_PBM_A_REGS_OFF + 0x00200UL) -#define SCHIZO_IOMMU_TSBBASE_A (SCHIZO_PBM_A_REGS_OFF + 0x00208UL) -#define SCHIZO_IOMMU_FLUSH_A (SCHIZO_PBM_A_REGS_OFF + 0x00210UL) -#define SCHIZO_IOMMU_CTXFLUSH_A (SCHIZO_PBM_A_REGS_OFF + 0x00218UL) -#define SCHIZO_IOMMU_TAG_A (SCHIZO_PBM_A_REGS_OFF + 0x0a580UL) -#define SCHIZO_IOMMU_DATA_A (SCHIZO_PBM_A_REGS_OFF + 0x0a600UL) -#define SCHIZO_IOMMU_CONTROL_B (SCHIZO_PBM_B_REGS_OFF + 0x00200UL) -#define SCHIZO_IOMMU_TSBBASE_B (SCHIZO_PBM_B_REGS_OFF + 0x00208UL) -#define SCHIZO_IOMMU_FLUSH_B (SCHIZO_PBM_B_REGS_OFF + 0x00210UL) -#define SCHIZO_IOMMU_CTXFLUSH_B (SCHIZO_PBM_B_REGS_OFF + 0x00218UL) -#define SCHIZO_IOMMU_TAG_B (SCHIZO_PBM_B_REGS_OFF + 0x0a580UL) -#define SCHIZO_IOMMU_DATA_B (SCHIZO_PBM_B_REGS_OFF + 0x0a600UL) - -static void schizo_pbm_iommu_init(struct pci_controller_info *p, - struct pci_pbm_info *pbm, - int is_pbm_a) +#define SCHIZO_IOMMU_CONTROL (0x00200UL) +#define SCHIZO_IOMMU_TSBBASE (0x00208UL) +#define SCHIZO_IOMMU_FLUSH (0x00210UL) +#define SCHIZO_IOMMU_CTXFLUSH (0x00218UL) + +static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm) { struct pci_iommu *iommu = pbm->iommu; - unsigned long tsbbase, i, tagbase, database; + unsigned long tsbbase, i, tagbase, database, order; + u32 vdma[2], dma_mask; u64 control; + int err, tsbsize; + + err = prom_getproperty(pbm->prom_node, "virtual-dma", + (char *)&vdma[0], sizeof(vdma)); + if (err == 0 || err == -1) { + /* No property, use default values. */ + vdma[0] = 0xc0000000; + vdma[1] = 0x40000000; + } + + dma_mask = vdma[0]; + switch (vdma[1]) { + case 0x20000000: + dma_mask |= 0x1fffffff; + tsbsize = 64; + break; + + case 0x40000000: + dma_mask |= 0x3fffffff; + tsbsize = 128; + break; + + case 0x80000000: + dma_mask |= 0x7fffffff; + tsbsize = 128; + break; + + default: + prom_printf("SCHIZO: strange virtual-dma size.\n"); + prom_halt(); + }; /* Setup initial software IOMMU state. */ spin_lock_init(&iommu->lock); iommu->iommu_cur_ctx = 0; /* Register addresses, SCHIZO has iommu ctx flushing. */ - if (is_pbm_a) { - iommu->iommu_control = p->controller_regs + SCHIZO_IOMMU_CONTROL_A; - iommu->iommu_tsbbase = p->controller_regs + SCHIZO_IOMMU_TSBBASE_A; - iommu->iommu_flush = p->controller_regs + SCHIZO_IOMMU_FLUSH_A; - iommu->iommu_ctxflush = p->controller_regs + SCHIZO_IOMMU_CTXFLUSH_A; - } else { - iommu->iommu_control = p->controller_regs + SCHIZO_IOMMU_CONTROL_B; - iommu->iommu_tsbbase = p->controller_regs + SCHIZO_IOMMU_TSBBASE_B; - iommu->iommu_flush = p->controller_regs + SCHIZO_IOMMU_FLUSH_B; - iommu->iommu_ctxflush = p->controller_regs + SCHIZO_IOMMU_CTXFLUSH_B; - } + iommu->iommu_control = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL; + iommu->iommu_tsbbase = pbm->pbm_regs + SCHIZO_IOMMU_TSBBASE; + iommu->iommu_flush = pbm->pbm_regs + SCHIZO_IOMMU_FLUSH; + iommu->iommu_ctxflush = pbm->pbm_regs + SCHIZO_IOMMU_CTXFLUSH; /* We use the main control/status register of SCHIZO as the write * completion register. */ - iommu->write_complete_reg = p->controller_regs + 0x10000UL; + iommu->write_complete_reg = pbm->controller_regs + 0x10000UL; /* * Invalidate TLB Entries. @@ -1644,13 +1832,11 @@ control |= SCHIZO_IOMMU_CTRL_DENAB; schizo_write(iommu->iommu_control, control); - if (is_pbm_a) - tagbase = SCHIZO_IOMMU_TAG_A, database = SCHIZO_IOMMU_DATA_A; - else - tagbase = SCHIZO_IOMMU_TAG_B, database = SCHIZO_IOMMU_DATA_B; + tagbase = SCHIZO_IOMMU_TAG, database = SCHIZO_IOMMU_DATA; + for(i = 0; i < 16; i++) { - schizo_write(p->controller_regs + tagbase + (i * 8UL), 0); - schizo_write(p->controller_regs + database + (i * 8UL), 0); + schizo_write(pbm->pbm_regs + tagbase + (i * 8UL), 0); + schizo_write(pbm->pbm_regs + database + (i * 8UL), 0); } /* Leave diag mode enabled for full-flushing done @@ -1661,16 +1847,32 @@ * table (128K ioptes * 8 bytes per iopte). This is * page order 7 on UltraSparc. */ - tsbbase = __get_free_pages(GFP_KERNEL, get_order(IO_TSB_SIZE)); + order = get_order(tsbsize * 8 * 1024); + tsbbase = __get_free_pages(GFP_KERNEL, order); if (!tsbbase) { - prom_printf("SCHIZO_IOMMU: Error, gfp(tsb) failed.\n"); + prom_printf("%s: Error, gfp(tsb) failed.\n", pbm->name); prom_halt(); } + iommu->page_table = (iopte_t *)tsbbase; - iommu->page_table_sz_bits = 17; - iommu->page_table_map_base = 0xc0000000; - iommu->dma_addr_mask = 0xffffffff; - memset((char *)tsbbase, 0, IO_TSB_SIZE); + iommu->page_table_map_base = vdma[0]; + iommu->dma_addr_mask = dma_mask; + memset((char *)tsbbase, 0, PAGE_SIZE << order); + + switch (tsbsize) { + case 64: + iommu->page_table_sz_bits = 16; + break; + + case 128: + iommu->page_table_sz_bits = 17; + break; + + default: + prom_printf("iommu_init: Illegal TSB size %d\n", tsbsize); + prom_halt(); + break; + }; /* We start with no consistent mappings. */ iommu->lowest_consistent_map = @@ -1685,28 +1887,194 @@ control = schizo_read(iommu->iommu_control); control &= ~(SCHIZO_IOMMU_CTRL_TSBSZ | SCHIZO_IOMMU_CTRL_TBWSZ); - control |= (SCHIZO_IOMMU_TSBSZ_128K | SCHIZO_IOMMU_CTRL_ENAB); + switch (tsbsize) { + case 64: + control |= SCHIZO_IOMMU_TSBSZ_64K; + break; + case 128: + control |= SCHIZO_IOMMU_TSBSZ_128K; + break; + }; + + control |= SCHIZO_IOMMU_CTRL_ENAB; schizo_write(iommu->iommu_control, control); } -static void schizo_pbm_init(struct pci_controller_info *p, - int prom_node, int is_pbm_a) +#define SCHIZO_PCI_IRQ_RETRY (0x1a00UL) +#define SCHIZO_IRQ_RETRY_INF 0xffUL + +#define SCHIZO_PCI_DIAG (0x2020UL) +#define SCHIZO_PCIDIAG_D_BADECC (1UL << 10UL) /* Disable BAD ECC errors (Schizo) */ +#define SCHIZO_PCIDIAG_D_BYPASS (1UL << 9UL) /* Disable MMU bypass mode (Schizo/Tomatillo) */ +#define SCHIZO_PCIDIAG_D_TTO (1UL << 8UL) /* Disable TTO errors (Schizo/Tomatillo) */ +#define SCHIZO_PCIDIAG_D_RTRYARB (1UL << 7UL) /* Disable retry arbitration (Schizo) */ +#define SCHIZO_PCIDIAG_D_RETRY (1UL << 6UL) /* Disable retry limit (Schizo/Tomatillo) */ +#define SCHIZO_PCIDIAG_D_INTSYNC (1UL << 5UL) /* Disable interrupt/DMA synch (Schizo/Tomatillo) */ +#define SCHIZO_PCIDIAG_I_DMA_PARITY (1UL << 3UL) /* Invert DMA parity (Schizo/Tomatillo) */ +#define SCHIZO_PCIDIAG_I_PIOD_PARITY (1UL << 2UL) /* Invert PIO data parity (Schizo/Tomatillo) */ +#define SCHIZO_PCIDIAG_I_PIOA_PARITY (1UL << 1UL) /* Invert PIO address parity (Schizo/Tomatillo) */ + +#define TOMATILLO_PCI_IOC_CSR (0x2248UL) +#define TOMATILLO_IOC_PART_WPENAB 0x0000000000080000UL +#define TOMATILLO_IOC_RDMULT_PENAB 0x0000000000040000UL +#define TOMATILLO_IOC_RDONE_PENAB 0x0000000000020000UL +#define TOMATILLO_IOC_RDLINE_PENAB 0x0000000000010000UL +#define TOMATILLO_IOC_RDMULT_PLEN 0x000000000000c000UL +#define TOMATILLO_IOC_RDMULT_PLEN_SHIFT 14UL +#define TOMATILLO_IOC_RDONE_PLEN 0x0000000000003000UL +#define TOMATILLO_IOC_RDONE_PLEN_SHIFT 12UL +#define TOMATILLO_IOC_RDLINE_PLEN 0x0000000000000c00UL +#define TOMATILLO_IOC_RDLINE_PLEN_SHIFT 10UL +#define TOMATILLO_IOC_PREF_OFF 0x00000000000003f8UL +#define TOMATILLO_IOC_PREF_OFF_SHIFT 3UL +#define TOMATILLO_IOC_RDMULT_CPENAB 0x0000000000000004UL +#define TOMATILLO_IOC_RDONE_CPENAB 0x0000000000000002UL +#define TOMATILLO_IOC_RDLINE_CPENAB 0x0000000000000001UL + +#define TOMATILLO_PCI_IOC_TDIAG (0x2250UL) +#define TOMATILLO_PCI_IOC_DDIAG (0x2290UL) + +static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm) { + u64 tmp; + + /* Set IRQ retry to infinity. */ + schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, + SCHIZO_IRQ_RETRY_INF); + + /* Enable arbiter for all PCI slots. Also, disable PCI interval + * timer so that DTO (Discard TimeOuts) are not reported because + * some Schizo revisions report them erroneously. + */ + tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_CTRL); + if (pbm->chip_type == PBM_CHIP_TYPE_SCHIZO_PLUS && + pbm->chip_version == 0x5 && + pbm->chip_revision == 0x1) + tmp |= 0x0f; + else + tmp |= 0xff; + + tmp &= ~SCHIZO_PCICTRL_PTO; + if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO && + pbm->chip_version == 0x2) + tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT; + else + tmp |= 0x1UL << SCHIZO_PCICTRL_PTO_SHIFT; + + if (!prom_getbool(pbm->prom_node, "no-bus-parking")) + tmp |= SCHIZO_PCICTRL_PARK; + + if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) + tmp |= SCHIZO_PCICTRL_MRM_PREF; + + schizo_write(pbm->pbm_regs + SCHIZO_PCI_CTRL, tmp); + + tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_DIAG); + tmp &= ~(SCHIZO_PCIDIAG_D_RTRYARB | + SCHIZO_PCIDIAG_D_RETRY | + SCHIZO_PCIDIAG_D_INTSYNC); + schizo_write(pbm->pbm_regs + SCHIZO_PCI_DIAG, tmp); + + if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) { + /* Clear prefetch lengths to workaround a bug in + * Jalapeno... + */ + tmp = (TOMATILLO_IOC_PART_WPENAB | + (1 << TOMATILLO_IOC_PREF_OFF_SHIFT) | + TOMATILLO_IOC_RDMULT_CPENAB | + TOMATILLO_IOC_RDONE_CPENAB | + TOMATILLO_IOC_RDLINE_CPENAB); + + schizo_write(pbm->pbm_regs + TOMATILLO_PCI_IOC_CSR, + tmp); + } +} + +static void __init schizo_pbm_init(struct pci_controller_info *p, + int prom_node, u32 portid, + int chip_type) +{ + struct linux_prom64_registers pr_regs[4]; unsigned int busrange[2]; struct pci_pbm_info *pbm; + const char *chipset_name; + u32 ino_bitmap[2]; + int is_pbm_a; int err; + switch (chip_type) { + case PBM_CHIP_TYPE_TOMATILLO: + chipset_name = "TOMATILLO"; + break; + + case PBM_CHIP_TYPE_SCHIZO_PLUS: + chipset_name = "SCHIZO+"; + break; + + case PBM_CHIP_TYPE_SCHIZO: + default: + chipset_name = "SCHIZO"; + break; + }; + + /* For SCHIZO, three OBP regs: + * 1) PBM controller regs + * 2) Schizo front-end controller regs (same for both PBMs) + * 3) PBM PCI config space + * + * For TOMATILLO, four OBP regs: + * 1) PBM controller regs + * 2) Tomatillo front-end controller regs + * 3) PBM PCI config space + * 4) Ichip regs + */ + err = prom_getproperty(prom_node, "reg", + (char *)&pr_regs[0], + sizeof(pr_regs)); + if (err == 0 || err == -1) { + prom_printf("%s: Fatal error, no reg property.\n", + chipset_name); + prom_halt(); + } + + is_pbm_a = ((pr_regs[0].phys_addr & 0x00700000) == 0x00600000); + if (is_pbm_a) pbm = &p->pbm_A; else pbm = &p->pbm_B; - schizo_determine_mem_io_space(pbm, is_pbm_a, p->controller_regs); - pbm_register_toplevel_resources(p, pbm); - + pbm->portid = portid; pbm->parent = p; pbm->prom_node = prom_node; pbm->pci_first_slot = 1; + + pbm->chip_type = chip_type; + pbm->chip_version = + prom_getintdefault(prom_node, "version#", 0); + pbm->chip_revision = + prom_getintdefault(prom_node, "module-revision#", 0); + + pbm->pbm_regs = pr_regs[0].phys_addr; + pbm->controller_regs = pr_regs[1].phys_addr - 0x10000UL; + + sprintf(pbm->name, + (chip_type == PBM_CHIP_TYPE_TOMATILLO ? + "TOMATILLO%d PBM%c" : + "SCHIZO%d PBM%c"), + p->index, + (pbm == &p->pbm_A ? 'A' : 'B')); + + printk("%s: ver[%x:%x], portid %x, " + "cregs[%lx] pregs[%lx]\n", + pbm->name, + pbm->chip_version, pbm->chip_revision, + pbm->portid, + pbm->controller_regs, + pbm->pbm_regs); + + schizo_pbm_hw_init(pbm); + prom_getstring(prom_node, "name", pbm->prom_name, sizeof(pbm->prom_name)); @@ -1714,11 +2082,17 @@ err = prom_getproperty(prom_node, "ranges", (char *) pbm->pbm_ranges, sizeof(pbm->pbm_ranges)); - if (err != -1) - pbm->num_pbm_ranges = - (err / sizeof(struct linux_prom_pci_ranges)); - else - pbm->num_pbm_ranges = 0; + if (err == 0 || err == -1) { + prom_printf("%s: Fatal error, no ranges property.\n", + pbm->name); + prom_halt(); + } + + pbm->num_pbm_ranges = + (err / sizeof(struct linux_prom_pci_ranges)); + + schizo_determine_mem_io_space(pbm); + pbm_register_toplevel_resources(p, pbm); err = prom_getproperty(prom_node, "interrupt-map", (char *)pbm->pbm_intmap, @@ -1729,8 +2103,8 @@ (char *)&pbm->pbm_intmask, sizeof(pbm->pbm_intmask)); if (err == -1) { - prom_printf("SCHIZO-PBM: Fatal error, no " - "interrupt-map-mask.\n"); + prom_printf("%s: Fatal error, no " + "interrupt-map-mask.\n", pbm->name); prom_halt(); } } else { @@ -1738,95 +2112,65 @@ memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask)); } + err = prom_getproperty(prom_node, "ino-bitmap", + (char *) &ino_bitmap[0], + sizeof(ino_bitmap)); + if (err == 0 || err == -1) { + prom_printf("%s: Fatal error, no ino-bitmap.\n", pbm->name); + prom_halt(); + } + pbm->ino_bitmap = (((u64)ino_bitmap[1] << 32UL) | + ((u64)ino_bitmap[0] << 0UL)); + err = prom_getproperty(prom_node, "bus-range", (char *)&busrange[0], sizeof(busrange)); if (err == 0 || err == -1) { - prom_printf("SCHIZO-PBM: Fatal error, no bus-range.\n"); + prom_printf("%s: Fatal error, no bus-range.\n", pbm->name); prom_halt(); } pbm->pci_first_busno = busrange[0]; pbm->pci_last_busno = busrange[1]; - schizo_pbm_iommu_init(p, pbm, is_pbm_a); - schizo_pbm_strbuf_init(p, pbm, is_pbm_a); + schizo_pbm_iommu_init(pbm); + schizo_pbm_strbuf_init(pbm); } -#define SCHIZO_PCIA_IRQ_RETRY (SCHIZO_PBM_A_REGS_OFF + 0x1a00UL) -#define SCHIZO_PCIB_IRQ_RETRY (SCHIZO_PBM_B_REGS_OFF + 0x1a00UL) -#define SCHIZO_IRQ_RETRY_INF 0xffUL - -#define SCHIZO_PCIA_DIAG (SCHIZO_PBM_A_REGS_OFF + 0x2020UL) -#define SCHIZO_PCIB_DIAG (SCHIZO_PBM_B_REGS_OFF + 0x2020UL) -#define SCHIZO_PCIDIAG_D_BADECC (1UL << 10UL) /* Disable BAD ECC errors */ -#define SCHIZO_PCIDIAG_D_BYPASS (1UL << 9UL) /* Disable MMU bypass mode */ -#define SCHIZO_PCIDIAG_D_TTO (1UL << 8UL) /* Disable TTO errors */ -#define SCHIZO_PCIDIAG_D_RTRYARB (1UL << 7UL) /* Disable retry arbitration */ -#define SCHIZO_PCIDIAG_D_RETRY (1UL << 6UL) /* Disable retry limit */ -#define SCHIZO_PCIDIAG_D_INTSYNC (1UL << 5UL) /* Disable interrupt/DMA synch */ -#define SCHIZO_PCIDIAG_I_DMA_PARITY (1UL << 3UL) /* Invert DMA parity */ -#define SCHIZO_PCIDIAG_I_PIOD_PARITY (1UL << 2UL) /* Invert PIO data parity */ -#define SCHIZO_PCIDIAG_I_PIOA_PARITY (1UL << 1U)L /* Invert PIO address parity */ - -static void schizo_controller_hwinit(struct pci_controller_info *p) +static inline int portid_compare(u32 x, u32 y, int chip_type) { - unsigned long pbm_a_base, pbm_b_base; - u64 tmp; - - pbm_a_base = p->controller_regs + SCHIZO_PBM_A_REGS_OFF; - pbm_b_base = p->controller_regs + SCHIZO_PBM_B_REGS_OFF; - - /* Set IRQ retry to infinity. */ - schizo_write(p->controller_regs + SCHIZO_PCIA_IRQ_RETRY, - SCHIZO_IRQ_RETRY_INF); - schizo_write(p->controller_regs + SCHIZO_PCIB_IRQ_RETRY, - SCHIZO_IRQ_RETRY_INF); - - /* Enable arbiter for all PCI slots. Also, disable PCI interval - * timer so that DTO (Discard TimeOuts) are not reported because - * some Schizo revisions report them erroneously. - */ - - tmp = schizo_read(p->controller_regs + SCHIZO_PCIA_CTRL); - tmp |= SCHIZO_PCICTRL_ARB; - tmp &= ~SCHIZO_PCICTRL_PTO; - schizo_write(p->controller_regs + SCHIZO_PCIA_CTRL, tmp); - - tmp = schizo_read(p->controller_regs + SCHIZO_PCIB_CTRL); - tmp |= SCHIZO_PCICTRL_ARB; - tmp &= ~SCHIZO_PCICTRL_PTO; - schizo_write(p->controller_regs + SCHIZO_PCIB_CTRL, tmp); - - /* Disable TTO error reporting (won't happen anyway since we - * disabled the PCI interval timer above) and retry arbitration - * (can cause hangs in some Schizo revisions). - */ - tmp = schizo_read(p->controller_regs + SCHIZO_PCIA_DIAG); - tmp |= (SCHIZO_PCIDIAG_D_TTO | SCHIZO_PCIDIAG_D_RTRYARB); - schizo_write(p->controller_regs + SCHIZO_PCIA_DIAG, tmp); - - tmp = schizo_read(p->controller_regs + SCHIZO_PCIB_DIAG); - tmp |= (SCHIZO_PCIDIAG_D_TTO | SCHIZO_PCIDIAG_D_RTRYARB); - schizo_write(p->controller_regs + SCHIZO_PCIB_DIAG, tmp); + if (chip_type == PBM_CHIP_TYPE_TOMATILLO) { + if (x == (y ^ 1)) + return 1; + return 0; + } + return (x == y); } -void __init schizo_init(int node, char *model_name) +static void __init __schizo_init(int node, char *model_name, int chip_type) { - struct linux_prom64_registers pr_regs[3]; struct pci_controller_info *p; struct pci_iommu *iommu; unsigned long flags; + int is_pbm_a; u32 portid; - int is_pbm_a, err; portid = prom_getintdefault(node, "portid", 0xff); spin_lock_irqsave(&pci_controller_lock, flags); for(p = pci_controller_root; p; p = p->next) { - if (p->portid == portid) { + struct pci_pbm_info *pbm; + + if (p->pbm_A.prom_node && p->pbm_B.prom_node) + continue; + + pbm = (p->pbm_A.prom_node ? + &p->pbm_A : + &p->pbm_B); + + if (portid_compare(pbm->portid, portid, chip_type)) { spin_unlock_irqrestore(&pci_controller_lock, flags); is_pbm_a = (p->pbm_A.prom_node == 0); - schizo_pbm_init(p, node, is_pbm_a); + schizo_pbm_init(p, node, portid, chip_type); return; } } @@ -1860,38 +2204,33 @@ pci_controller_root = p; spin_unlock_irqrestore(&pci_controller_lock, flags); - p->portid = portid; p->index = pci_num_controllers++; p->pbms_same_domain = 0; - p->scan_bus = schizo_scan_bus; + p->scan_bus = (chip_type == PBM_CHIP_TYPE_TOMATILLO ? + tomatillo_scan_bus : + schizo_scan_bus); p->irq_build = schizo_irq_build; p->base_address_update = schizo_base_address_update; p->resource_adjust = schizo_resource_adjust; p->pci_ops = &schizo_ops; - /* Three OBP regs: - * 1) PBM controller regs - * 2) Schizo front-end controller regs (same for both PBMs) - * 3) PBM PCI config space - */ - err = prom_getproperty(node, "reg", - (char *)&pr_regs[0], - sizeof(pr_regs)); - if (err == 0 || err == -1) { - prom_printf("SCHIZO: Fatal error, no reg property.\n"); - prom_halt(); - } - - p->controller_regs = pr_regs[1].phys_addr - 0x10000UL; - printk("PCI: Found SCHIZO, control regs at %016lx\n", - p->controller_regs); - /* Like PSYCHO we have a 2GB aligned area for memory space. */ pci_memspace_mask = 0x7fffffffUL; - /* Init core controller. */ - schizo_controller_hwinit(p); + schizo_pbm_init(p, node, portid, chip_type); +} - is_pbm_a = ((pr_regs[0].phys_addr & 0x00700000) == 0x00600000); - schizo_pbm_init(p, node, is_pbm_a); +void __init schizo_init(int node, char *model_name) +{ + __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO); +} + +void __init schizo_plus_init(int node, char *model_name) +{ + __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS); +} + +void __init tomatillo_init(int node, char *model_name) +{ + __schizo_init(node, model_name, PBM_CHIP_TYPE_TOMATILLO); } Index: arch/sparc64/kernel/power.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/power.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/power.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/power.c 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: power.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: power.c,v 1.2 2004/08/04 01:26:17 joff Exp $ * power.c: Power management driver. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) Index: arch/sparc64/kernel/process.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/process.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/process.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/process.c 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: process.c,v 1.2 2004/08/04 01:26:17 joff Exp $ * arch/sparc64/kernel/process.c * * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc64/kernel/rtrap.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/rtrap.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/rtrap.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/rtrap.S 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: rtrap.S,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: rtrap.S,v 1.2 2004/08/04 01:26:17 joff Exp $ * rtrap.S: Preparing for return from trap on Sparc V9. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) Index: arch/sparc64/kernel/sbus.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/sbus.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/sbus.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/sbus.c 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sbus.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: sbus.c,v 1.2 2004/08/04 01:26:17 joff Exp $ * sbus.c: UltraSparc SBUS controller support. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) Index: arch/sparc64/kernel/semaphore.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/semaphore.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/semaphore.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/semaphore.c 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: semaphore.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: semaphore.c,v 1.2 2004/08/04 01:26:17 joff Exp $ * semaphore.c: Sparc64 semaphore implementation. * * This is basically the PPC semaphore scheme ported to use Index: arch/sparc64/kernel/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/setup.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/setup.c 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: setup.c,v 1.2 2004/08/04 01:26:17 joff Exp $ * linux/arch/sparc64/kernel/setup.c * * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu) @@ -40,6 +40,7 @@ #include #include #include +#include #ifdef CONFIG_IP_PNP #include @@ -456,7 +457,7 @@ char saved_command_line[256]; char reboot_command[256]; -extern unsigned long phys_base; +extern unsigned long phys_base, kern_base, kern_size; static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 }; @@ -527,6 +528,22 @@ highest_paddr = top; } + switch (tlb_type) { + default: + case spitfire: + kern_base = spitfire_get_itlb_data(sparc64_highest_locked_tlbent()); + kern_base &= _PAGE_PADDR_SF; + break; + + case cheetah: + case cheetah_plus: + kern_base = cheetah_get_litlb_data(sparc64_highest_locked_tlbent()); + kern_base &= _PAGE_PADDR; + break; + }; + + kern_size = (unsigned long)&_end - (unsigned long)KERNBASE; + if (!root_flags) root_mountflags &= ~MS_RDONLY; ROOT_DEV = to_kdev_t(root_dev); @@ -604,8 +621,8 @@ /* BUFFER is PAGE_SIZE bytes long. */ -extern char *sparc_cpu_type[]; -extern char *sparc_fpu_type[]; +extern char *sparc_cpu_type; +extern char *sparc_fpu_type; extern void smp_info(struct seq_file *); extern void smp_bogo(struct seq_file *); @@ -617,8 +634,6 @@ static int show_cpuinfo(struct seq_file *m, void *__unused) { - int cpuid = smp_processor_id(); - seq_printf(m, "cpu\t\t: %s\n" "fpu\t\t: %s\n" @@ -632,8 +647,8 @@ "Cpu0ClkTck\t: %016lx\n" #endif , - sparc_cpu_type[cpuid], - sparc_fpu_type[cpuid], + sparc_cpu_type, + sparc_fpu_type, prom_rev, prom_prev >> 16, (prom_prev >> 8) & 0xff, Index: arch/sparc64/kernel/signal.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/signal.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/signal.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/signal.c 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: signal.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: signal.c,v 1.2 2004/08/04 01:26:17 joff Exp $ * arch/sparc64/kernel/signal.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -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); Index: arch/sparc64/kernel/signal32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/signal32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/signal32.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/signal32.c 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: signal32.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: signal32.c,v 1.2 2004/08/04 01:26:17 joff Exp $ * arch/sparc64/kernel/signal32.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -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); Index: arch/sparc64/kernel/smp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/smp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/smp.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/smp.c 4 Aug 2004 01:26:17 -0000 1.2 @@ -133,7 +133,6 @@ static volatile unsigned long callin_flag = 0; extern void inherit_locked_prom_mappings(int save_p); -extern void cpu_probe(void); void __init smp_callin(void) { @@ -153,8 +152,6 @@ __flush_cache_all(); __flush_tlb_all(); - cpu_probe(); - smp_setup_percpu_timer(); __sti(); @@ -537,12 +534,19 @@ #endif static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, unsigned long mask) { - u64 pstate; - int nack_busy_id; + u64 pstate, ver; + int nack_busy_id, is_jalapeno; if (!mask) return; + /* Unfortunately, someone at Sun had the brilliant idea to make the + * busy/nack fields hard-coded by ITID number for this Ultra-III + * derivative processor. + */ + __asm__ ("rdpr %%ver, %0" : "=r" (ver)); + is_jalapeno = ((ver >> 32) == 0x003e0016); + __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); retry: @@ -567,11 +571,13 @@ if (mask & (1UL << i)) { u64 target = (i << 14) | 0x70; - target |= (nack_busy_id++ << 24); + if (!is_jalapeno) + target |= (nack_busy_id << 24); __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" "membar #Sync\n\t" : /* no outputs */ : "r" (target), "i" (ASI_INTR_W)); + nack_busy_id++; ncpus--; } } @@ -618,7 +624,14 @@ */ for (i = 0; i < NR_CPUS; i++) { if (mask & (1UL << i)) { - if ((dispatch_stat & (0x2 << this_busy_nack)) == 0) + u64 check_mask; + + if (is_jalapeno) + check_mask = (0x2UL << (2*i)); + else + check_mask = (0x2UL << + this_busy_nack); + if ((dispatch_stat & check_mask) == 0) mask &= ~(1UL << i); this_busy_nack += 2; } Index: arch/sparc64/kernel/sparc64_ksyms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/sparc64_ksyms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/sparc64_ksyms.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/sparc64_ksyms.c 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sparc64_ksyms.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: sparc64_ksyms.c,v 1.2 2004/08/04 01:26:17 joff Exp $ * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc64/kernel/starfire.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/starfire.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/starfire.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/starfire.c 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: starfire.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: starfire.c,v 1.2 2004/08/04 01:26:17 joff Exp $ * starfire.c: Starfire/E10000 support. * * Copyright (C) 1998 David S. Miller (davem@redhat.com) Index: arch/sparc64/kernel/sunos_ioctl32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/sunos_ioctl32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/sunos_ioctl32.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/sunos_ioctl32.c 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sunos_ioctl32.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: sunos_ioctl32.c,v 1.2 2004/08/04 01:26:17 joff Exp $ * sunos_ioctl32.c: SunOS ioctl compatability on sparc64. * * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) Index: arch/sparc64/kernel/sys32.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/sys32.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/sys32.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/sys32.S 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sys32.S,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: sys32.S,v 1.2 2004/08/04 01:26:17 joff Exp $ * sys32.S: I-cache tricks for 32-bit compatability layer simple * conversions. * Index: arch/sparc64/kernel/sys_sparc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/sys_sparc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/sys_sparc.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/sys_sparc.c 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sys_sparc.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: sys_sparc.c,v 1.2 2004/08/04 01:26:17 joff Exp $ * linux/arch/sparc64/kernel/sys_sparc.c * * This file contains various random system calls that @@ -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; Index: arch/sparc64/kernel/sys_sparc32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/sys_sparc32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/sys_sparc32.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/sys_sparc32.c 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sys_sparc32.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: sys_sparc32.c,v 1.2 2004/08/04 01:26:17 joff Exp $ * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -414,7 +415,7 @@ * * This is really horribly ugly. */ -#define IPCOP_MASK(__x) (1UL << (__x)) +#define IPCOP_MASK(__x) (1UL << ((__x)&~IPC_64)) static int do_sys32_semctl(int first, int second, int third, void *uptr) { union semun fourth; @@ -426,7 +427,7 @@ err = -EFAULT; if (get_user (pad, (u32 *)uptr)) goto out; - if(third == SETVAL) + if ((third & ~IPC_64) == SETVAL) fourth.val = (int)pad; else fourth.__pad = (void *)A(pad); @@ -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; @@ -1766,14 +1799,13 @@ if (err) goto out; - if (!type_page) { - err = -EINVAL; - goto out; + if (type_page) { + is_smb = !strcmp((char *)type_page, SMBFS_NAME); + is_ncp = !strcmp((char *)type_page, NCPFS_NAME); + } else { + is_smb = is_ncp = 0; } - is_smb = !strcmp((char *)type_page, SMBFS_NAME); - is_ncp = !strcmp((char *)type_page, NCPFS_NAME); - err = copy_mount_stuff_to_kernel((const void *)AA(data), &data_page); if (err) goto type_out; @@ -1891,7 +1923,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 +1936,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 +1971,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 +2155,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 +2163,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 +2970,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 +3001,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); } @@ -4424,6 +4453,9 @@ extern asmlinkage long sys32_sysctl(struct __sysctl_args32 *args) { +#ifndef CONFIG_SYSCTL + return -ENOSYS; +#else struct __sysctl_args32 tmp; int error; size_t oldlen, *oldlenp = NULL; @@ -4458,4 +4490,5 @@ copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); } return error; +#endif } Index: arch/sparc64/kernel/sys_sunos32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/sys_sunos32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/sys_sunos32.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/sys_sunos32.c 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sys_sunos32.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: sys_sunos32.c,v 1.2 2004/08/04 01:26:17 joff Exp $ * sys_sunos32.c: SunOS binary compatability layer on sparc64. * * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu) @@ -157,7 +157,7 @@ * fool it, but this should catch most mistakes. */ freepages = atomic_read(&buffermem_pages) >> PAGE_SHIFT; - freepages += atomic_read(&page_cache_size); + freepages += page_cache_size; freepages >>= 1; freepages += nr_free_pages(); freepages += nr_swap_pages; @@ -654,8 +654,8 @@ /* XXXXXXXXXXXXXXXXXXXX */ static int sunos_nfs_mount(char *dir_name, int linux_flags, void *data) { - int server_fd; - char *the_name; + int server_fd, err; + char *the_name, *mount_page; struct nfs_mount_data linux_nfs_mount; struct sunos_nfs_mount_args sunos_mount; @@ -708,7 +708,16 @@ linux_nfs_mount.hostname [255] = 0; putname (the_name); - return do_mount ("", dir_name, "nfs", linux_flags, &linux_nfs_mount); + mount_page = (char *) get_zeroed_page(GFP_KERNEL); + if (!mount_page) + return -ENOMEM; + + memcpy(mount_page, &linux_nfs_mount, sizeof(linux_nfs_mount)); + + err = do_mount("", dir_name, "nfs", linux_flags, mount_page); + + free_page((unsigned long) mount_page); + return err; } /* XXXXXXXXXXXXXXXXXXXX */ Index: arch/sparc64/kernel/systbls.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/systbls.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/systbls.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/systbls.S 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: systbls.S,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: systbls.S,v 1.2 2004/08/04 01:26:17 joff Exp $ * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * Index: arch/sparc64/kernel/time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/time.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/time.c 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: time.c,v 1.2 2004/08/04 01:26:17 joff Exp $ * time.c: UltraSparc timer and TOD clock support. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -775,6 +775,7 @@ strcmp(model, "mk48t08") && strcmp(model, "mk48t59") && strcmp(model, "m5819") && + strcmp(model, "m5819p") && strcmp(model, "ds1287")) { if (cbus != NULL) { prom_printf("clock_probe: Central bus lacks timer chip.\n"); @@ -833,7 +834,8 @@ } if (!strcmp(model, "ds1287") || - !strcmp(model, "m5819")) { + !strcmp(model, "m5819") || + !strcmp(model, "m5819p")) { ds1287_regs = edev->resource[0].start; } else { mstk48t59_regs = edev->resource[0].start; @@ -853,7 +855,8 @@ prom_halt(); } if (!strcmp(model, "ds1287") || - !strcmp(model, "m5819")) { + !strcmp(model, "m5819") || + !strcmp(model, "m5819p")) { ds1287_regs = isadev->resource.start; } else { mstk48t59_regs = isadev->resource.start; Index: arch/sparc64/kernel/trampoline.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/trampoline.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/trampoline.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/trampoline.S 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: trampoline.S,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: trampoline.S,v 1.2 2004/08/04 01:26:17 joff Exp $ * trampoline.S: Jump start slave processors on sparc64. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc64/kernel/traps.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/traps.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/traps.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/traps.c 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: traps.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: traps.c,v 1.2 2004/08/04 01:26:17 joff Exp $ * arch/sparc64/kernel/traps.c * * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu) @@ -401,6 +401,179 @@ }; #define CHAFSR_INVALID ((u64)-1L) +/* This table is ordered in priority of errors and matches the + * AFAR overwrite policy as well. + */ + +struct afsr_error_table { + unsigned long mask; + const char *name; +}; + +static const char CHAFSR_PERR_msg[] = + "System interface protocol error"; +static const char CHAFSR_IERR_msg[] = + "Internal processor error"; +static const char CHAFSR_ISAP_msg[] = + "System request parity error on incoming addresss"; +static const char CHAFSR_UCU_msg[] = + "Uncorrectable E-cache ECC error for ifetch/data"; +static const char CHAFSR_UCC_msg[] = + "SW Correctable E-cache ECC error for ifetch/data"; +static const char CHAFSR_UE_msg[] = + "Uncorrectable system bus data ECC error for read"; +static const char CHAFSR_EDU_msg[] = + "Uncorrectable E-cache ECC error for stmerge/blkld"; +static const char CHAFSR_EMU_msg[] = + "Uncorrectable system bus MTAG error"; +static const char CHAFSR_WDU_msg[] = + "Uncorrectable E-cache ECC error for writeback"; +static const char CHAFSR_CPU_msg[] = + "Uncorrectable ECC error for copyout"; +static const char CHAFSR_CE_msg[] = + "HW corrected system bus data ECC error for read"; +static const char CHAFSR_EDC_msg[] = + "HW corrected E-cache ECC error for stmerge/blkld"; +static const char CHAFSR_EMC_msg[] = + "HW corrected system bus MTAG ECC error"; +static const char CHAFSR_WDC_msg[] = + "HW corrected E-cache ECC error for writeback"; +static const char CHAFSR_CPC_msg[] = + "HW corrected ECC error for copyout"; +static const char CHAFSR_TO_msg[] = + "Unmapped error from system bus"; +static const char CHAFSR_BERR_msg[] = + "Bus error response from system bus"; +static const char CHAFSR_IVC_msg[] = + "HW corrected system bus data ECC error for ivec read"; +static const char CHAFSR_IVU_msg[] = + "Uncorrectable system bus data ECC error for ivec read"; +static struct afsr_error_table __cheetah_error_table[] = { + { CHAFSR_PERR, CHAFSR_PERR_msg }, + { CHAFSR_IERR, CHAFSR_IERR_msg }, + { CHAFSR_ISAP, CHAFSR_ISAP_msg }, + { CHAFSR_UCU, CHAFSR_UCU_msg }, + { CHAFSR_UCC, CHAFSR_UCC_msg }, + { CHAFSR_UE, CHAFSR_UE_msg }, + { CHAFSR_EDU, CHAFSR_EDU_msg }, + { CHAFSR_EMU, CHAFSR_EMU_msg }, + { CHAFSR_WDU, CHAFSR_WDU_msg }, + { CHAFSR_CPU, CHAFSR_CPU_msg }, + { CHAFSR_CE, CHAFSR_CE_msg }, + { CHAFSR_EDC, CHAFSR_EDC_msg }, + { CHAFSR_EMC, CHAFSR_EMC_msg }, + { CHAFSR_WDC, CHAFSR_WDC_msg }, + { CHAFSR_CPC, CHAFSR_CPC_msg }, + { CHAFSR_TO, CHAFSR_TO_msg }, + { CHAFSR_BERR, CHAFSR_BERR_msg }, + /* These two do not update the AFAR. */ + { CHAFSR_IVC, CHAFSR_IVC_msg }, + { CHAFSR_IVU, CHAFSR_IVU_msg }, + { 0, NULL }, +}; +static const char CHPAFSR_DTO_msg[] = + "System bus unmapped error for prefetch/storequeue-read"; +static const char CHPAFSR_DBERR_msg[] = + "System bus error for prefetch/storequeue-read"; +static const char CHPAFSR_THCE_msg[] = + "Hardware corrected E-cache Tag ECC error"; +static const char CHPAFSR_TSCE_msg[] = + "SW handled correctable E-cache Tag ECC error"; +static const char CHPAFSR_TUE_msg[] = + "Uncorrectable E-cache Tag ECC error"; +static const char CHPAFSR_DUE_msg[] = + "System bus uncorrectable data ECC error due to prefetch/store-fill"; +static struct afsr_error_table __cheetah_plus_error_table[] = { + { CHAFSR_PERR, CHAFSR_PERR_msg }, + { CHAFSR_IERR, CHAFSR_IERR_msg }, + { CHAFSR_ISAP, CHAFSR_ISAP_msg }, + { CHAFSR_UCU, CHAFSR_UCU_msg }, + { CHAFSR_UCC, CHAFSR_UCC_msg }, + { CHAFSR_UE, CHAFSR_UE_msg }, + { CHAFSR_EDU, CHAFSR_EDU_msg }, + { CHAFSR_EMU, CHAFSR_EMU_msg }, + { CHAFSR_WDU, CHAFSR_WDU_msg }, + { CHAFSR_CPU, CHAFSR_CPU_msg }, + { CHAFSR_CE, CHAFSR_CE_msg }, + { CHAFSR_EDC, CHAFSR_EDC_msg }, + { CHAFSR_EMC, CHAFSR_EMC_msg }, + { CHAFSR_WDC, CHAFSR_WDC_msg }, + { CHAFSR_CPC, CHAFSR_CPC_msg }, + { CHAFSR_TO, CHAFSR_TO_msg }, + { CHAFSR_BERR, CHAFSR_BERR_msg }, + { CHPAFSR_DTO, CHPAFSR_DTO_msg }, + { CHPAFSR_DBERR, CHPAFSR_DBERR_msg }, + { CHPAFSR_THCE, CHPAFSR_THCE_msg }, + { CHPAFSR_TSCE, CHPAFSR_TSCE_msg }, + { CHPAFSR_TUE, CHPAFSR_TUE_msg }, + { CHPAFSR_DUE, CHPAFSR_DUE_msg }, + /* These two do not update the AFAR. */ + { CHAFSR_IVC, CHAFSR_IVC_msg }, + { CHAFSR_IVU, CHAFSR_IVU_msg }, + { 0, NULL }, +}; +static const char JPAFSR_JETO_msg[] = + "System interface protocol error, hw timeout caused"; +static const char JPAFSR_SCE_msg[] = + "Parity error on system snoop results"; +static const char JPAFSR_JEIC_msg[] = + "System interface protocol error, illegal command detected"; +static const char JPAFSR_JEIT_msg[] = + "System interface protocol error, illegal ADTYPE detected"; +static const char JPAFSR_OM_msg[] = + "Out of range memory error has occurred"; +static const char JPAFSR_ETP_msg[] = + "Parity error on L2 cache tag SRAM"; +static const char JPAFSR_UMS_msg[] = + "Error due to unsupported store"; +static const char JPAFSR_RUE_msg[] = + "Uncorrectable ECC error from remote cache/memory"; +static const char JPAFSR_RCE_msg[] = + "Correctable ECC error from remote cache/memory"; +static const char JPAFSR_BP_msg[] = + "JBUS parity error on returned read data"; +static const char JPAFSR_WBP_msg[] = + "JBUS parity error on data for writeback or block store"; +static const char JPAFSR_FRC_msg[] = + "Foreign read to DRAM incurring correctable ECC error"; +static const char JPAFSR_FRU_msg[] = + "Foreign read to DRAM incurring uncorrectable ECC error"; +static struct afsr_error_table __jalapeno_error_table[] = { + { JPAFSR_JETO, JPAFSR_JETO_msg }, + { JPAFSR_SCE, JPAFSR_SCE_msg }, + { JPAFSR_JEIC, JPAFSR_JEIC_msg }, + { JPAFSR_JEIT, JPAFSR_JEIT_msg }, + { CHAFSR_PERR, CHAFSR_PERR_msg }, + { CHAFSR_IERR, CHAFSR_IERR_msg }, + { CHAFSR_ISAP, CHAFSR_ISAP_msg }, + { CHAFSR_UCU, CHAFSR_UCU_msg }, + { CHAFSR_UCC, CHAFSR_UCC_msg }, + { CHAFSR_UE, CHAFSR_UE_msg }, + { CHAFSR_EDU, CHAFSR_EDU_msg }, + { JPAFSR_OM, JPAFSR_OM_msg }, + { CHAFSR_WDU, CHAFSR_WDU_msg }, + { CHAFSR_CPU, CHAFSR_CPU_msg }, + { CHAFSR_CE, CHAFSR_CE_msg }, + { CHAFSR_EDC, CHAFSR_EDC_msg }, + { JPAFSR_ETP, JPAFSR_ETP_msg }, + { CHAFSR_WDC, CHAFSR_WDC_msg }, + { CHAFSR_CPC, CHAFSR_CPC_msg }, + { CHAFSR_TO, CHAFSR_TO_msg }, + { CHAFSR_BERR, CHAFSR_BERR_msg }, + { JPAFSR_UMS, JPAFSR_UMS_msg }, + { JPAFSR_RUE, JPAFSR_RUE_msg }, + { JPAFSR_RCE, JPAFSR_RCE_msg }, + { JPAFSR_BP, JPAFSR_BP_msg }, + { JPAFSR_WBP, JPAFSR_WBP_msg }, + { JPAFSR_FRC, JPAFSR_FRC_msg }, + { JPAFSR_FRU, JPAFSR_FRU_msg }, + /* These two do not update the AFAR. */ + { CHAFSR_IVU, CHAFSR_IVU_msg }, + { 0, NULL }, +}; +static struct afsr_error_table *cheetah_error_table; +static unsigned long cheetah_afsr_errors; + /* This is allocated at boot time based upon the largest hardware * cpu ID in the system. We allocate two entries per cpu, one for * TL==0 logging and one for TL >= 1 logging. @@ -436,7 +609,7 @@ void cheetah_ecache_flush_init(void) { - unsigned long largest_size, smallest_linesize, order; + unsigned long largest_size, smallest_linesize, order, ver; char type[16]; int node, highest_cpu, i; @@ -522,6 +695,18 @@ for (i = 0; i < 2 * highest_cpu; i++) cheetah_error_log[i].afsr = CHAFSR_INVALID; + __asm__ ("rdpr %%ver, %0" : "=r" (ver)); + if ((ver >> 32) == 0x003e0016) { + cheetah_error_table = &__jalapeno_error_table[0]; + cheetah_afsr_errors = JPAFSR_ERRORS; + } else if ((ver >> 32) == 0x003e0015) { + cheetah_error_table = &__cheetah_plus_error_table[0]; + cheetah_afsr_errors = CHPAFSR_ERRORS; + } else { + cheetah_error_table = &__cheetah_error_table[0]; + cheetah_afsr_errors = CHAFSR_ERRORS; + } + /* Now patch trap tables. */ memcpy(tl0_fecc, cheetah_fecc_trap_vector, (8 * 4)); memcpy(tl1_fecc, cheetah_fecc_trap_vector_tl1, (8 * 4)); @@ -720,36 +905,6 @@ NONE, NONE }; -/* This table is ordered in priority of errors and matches the - * AFAR overwrite policy as well. - */ -static struct { - unsigned long mask; - char *name; -} cheetah_error_table[] = { - { CHAFSR_PERR, "System interface protocol error" }, - { CHAFSR_IERR, "Internal processor error" }, - { CHAFSR_ISAP, "System request parity error on incoming addresss" }, - { CHAFSR_UCU, "Uncorrectable E-cache ECC error for ifetch/data" }, - { CHAFSR_UCC, "SW Correctable E-cache ECC error for ifetch/data" }, - { CHAFSR_UE, "Uncorrectable system bus data ECC error for read" }, - { CHAFSR_EDU, "Uncorrectable E-cache ECC error for stmerge/blkld" }, - { CHAFSR_EMU, "Uncorrectable system bus MTAG error" }, - { CHAFSR_WDU, "Uncorrectable E-cache ECC error for writeback" }, - { CHAFSR_CPU, "Uncorrectable ECC error for copyout" }, - { CHAFSR_CE, "HW corrected system bus data ECC error for read" }, - { CHAFSR_EDC, "HW corrected E-cache ECC error for stmerge/blkld" }, - { CHAFSR_EMC, "HW corrected system bus MTAG ECC error" }, - { CHAFSR_WDC, "HW corrected E-cache ECC error for writeback" }, - { CHAFSR_CPC, "HW corrected ECC error for copyout" }, - { CHAFSR_TO, "Unmapped error from system bus" }, - { CHAFSR_BERR, "Bus error response from system bus" }, - /* These two do not update the AFAR. */ - { CHAFSR_IVC, "HW corrected system bus data ECC error for ivec read" }, - { CHAFSR_IVU, "Uncorrectable system bus data ECC error for ivec read" }, - { 0, NULL } -}; - /* Return the highest priority error conditon mentioned. */ static __inline__ unsigned long cheetah_get_hipri(unsigned long afsr) { @@ -763,7 +918,7 @@ return tmp; } -static char *cheetah_get_string(unsigned long bit) +static const char *cheetah_get_string(unsigned long bit) { int i; @@ -876,7 +1031,7 @@ info->ecache_data[2], info->ecache_data[3]); - afsr = (afsr & ~hipri) & CHAFSR_ERRORS; + afsr = (afsr & ~hipri) & cheetah_afsr_errors; while (afsr != 0UL) { unsigned long bit = cheetah_get_hipri(afsr); @@ -899,7 +1054,7 @@ __asm__ __volatile__("ldxa [%%g0] %1, %0\n\t" : "=r" (afsr) : "i" (ASI_AFSR)); - if ((afsr & CHAFSR_ERRORS) != 0) { + if ((afsr & cheetah_afsr_errors) != 0) { if (logp != NULL) { __asm__ __volatile__("ldxa [%%g0] %1, %0\n\t" : "=r" (afar) @@ -1125,12 +1280,12 @@ flush_all = flush_line = 0; if ((afsr & CHAFSR_EDC) != 0UL) { - if ((afsr & CHAFSR_ERRORS) == CHAFSR_EDC) + if ((afsr & cheetah_afsr_errors) == CHAFSR_EDC) flush_line = 1; else flush_all = 1; } else if ((afsr & CHAFSR_CPC) != 0UL) { - if ((afsr & CHAFSR_ERRORS) == CHAFSR_CPC) + if ((afsr & cheetah_afsr_errors) == CHAFSR_CPC) flush_line = 1; else flush_all = 1; @@ -1253,12 +1408,12 @@ flush_all = flush_line = 0; if ((afsr & CHAFSR_EDU) != 0UL) { - if ((afsr & CHAFSR_ERRORS) == CHAFSR_EDU) + if ((afsr & cheetah_afsr_errors) == CHAFSR_EDU) flush_line = 1; else flush_all = 1; } else if ((afsr & CHAFSR_BERR) != 0UL) { - if ((afsr & CHAFSR_ERRORS) == CHAFSR_BERR) + if ((afsr & cheetah_afsr_errors) == CHAFSR_BERR) flush_line = 1; else flush_all = 1; Index: arch/sparc64/kernel/ttable.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/ttable.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/ttable.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/ttable.S 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ttable.S,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: ttable.S,v 1.2 2004/08/04 01:26:17 joff Exp $ * ttable.S: Sparc V9 Trap Table(s) with SpitFire/Cheetah extensions. * * Copyright (C) 1996, 2001 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc64/kernel/unaligned.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/unaligned.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/unaligned.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/unaligned.c 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: unaligned.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: unaligned.c,v 1.2 2004/08/04 01:26:17 joff Exp $ * unaligned.c: Unaligned load/store trap handling with special * cases for the kernel to do them more quickly. * @@ -479,7 +479,9 @@ extern void do_fpother(struct pt_regs *regs); extern void do_privact(struct pt_regs *regs); -extern void data_access_exception(struct pt_regs *regs); +extern void data_access_exception(struct pt_regs *regs, + unsigned long sfsr, + unsigned long sfar); int handle_ldf_stq(u32 insn, struct pt_regs *regs) { @@ -522,14 +524,14 @@ break; } default: - data_access_exception(regs); + data_access_exception(regs, 0, addr); return 1; } if (put_user (first >> 32, (u32 *)addr) || __put_user ((u32)first, (u32 *)(addr + 4)) || __put_user (second >> 32, (u32 *)(addr + 8)) || __put_user ((u32)second, (u32 *)(addr + 12))) { - data_access_exception(regs); + data_access_exception(regs, 0, addr); return 1; } } else { @@ -542,7 +544,7 @@ do_privact(regs); return 1; } else if (asi > ASI_SNFL) { - data_access_exception(regs); + data_access_exception(regs, 0, addr); return 1; } switch (insn & 0x180000) { @@ -559,7 +561,7 @@ err |= __get_user (data[i], (u32 *)(addr + 4*i)); } if (err && !(asi & 0x2 /* NF */)) { - data_access_exception(regs); + data_access_exception(regs, 0, addr); return 1; } if (asi & 0x8) /* Little */ { @@ -662,7 +664,7 @@ *(u64 *)(f->regs + freg) = value; current->thread.fpsaved[0] |= flag; } else { -daex: data_access_exception(regs); +daex: data_access_exception(regs, sfsr, sfar); return; } advance(regs); @@ -706,7 +708,7 @@ __put_user ((u32)value, (u32 *)(sfar + 4))) goto daex; } else { -daex: data_access_exception(regs); +daex: data_access_exception(regs, sfsr, sfar); return; } advance(regs); Index: arch/sparc64/kernel/winfixup.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/kernel/winfixup.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/kernel/winfixup.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/kernel/winfixup.S 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: winfixup.S,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: winfixup.S,v 1.2 2004/08/04 01:26:17 joff Exp $ * * winfixup.S: Handle cases where user stack pointer is found to be bogus. * Index: arch/sparc64/lib/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/Makefile 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/Makefile 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.1 2004/07/22 19:49:21 joff Exp $ +# $Id: Makefile,v 1.2 2004/08/04 01:26:17 joff Exp $ # Makefile for Sparc64 library files.. # Index: arch/sparc64/lib/PeeCeeI.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/PeeCeeI.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/PeeCeeI.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/PeeCeeI.c 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: PeeCeeI.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: PeeCeeI.c,v 1.2 2004/08/04 01:26:17 joff Exp $ * PeeCeeI.c: The emerging standard... * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc64/lib/U3copy_from_user.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/U3copy_from_user.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/U3copy_from_user.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/U3copy_from_user.S 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: U3copy_from_user.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: U3copy_from_user.S,v 1.2 2004/08/04 01:26:17 joff Exp $ * U3memcpy.S: UltraSparc-III optimized copy from userspace. * * Copyright (C) 1999, 2000 David S. Miller (davem@redhat.com) Index: arch/sparc64/lib/U3copy_in_user.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/U3copy_in_user.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/U3copy_in_user.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/U3copy_in_user.S 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: U3copy_in_user.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: U3copy_in_user.S,v 1.2 2004/08/04 01:26:17 joff Exp $ * U3memcpy.S: UltraSparc-III optimized copy within userspace. * * Copyright (C) 1999, 2000 David S. Miller (davem@redhat.com) Index: arch/sparc64/lib/U3copy_to_user.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/U3copy_to_user.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/U3copy_to_user.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/U3copy_to_user.S 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: U3copy_to_user.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: U3copy_to_user.S,v 1.2 2004/08/04 01:26:17 joff Exp $ * U3memcpy.S: UltraSparc-III optimized copy to userspace. * * Copyright (C) 1999, 2000 David S. Miller (davem@redhat.com) Index: arch/sparc64/lib/U3memcpy.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/U3memcpy.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/U3memcpy.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/U3memcpy.S 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: U3memcpy.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: U3memcpy.S,v 1.2 2004/08/04 01:26:17 joff Exp $ * U3memcpy.S: UltraSparc-III optimized memcpy. * * Copyright (C) 1999, 2000 David S. Miller (davem@redhat.com) Index: arch/sparc64/lib/VIS.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/VIS.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/VIS.h 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/VIS.h 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: VIS.h,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: VIS.h,v 1.2 2004/08/04 01:26:17 joff Exp $ * VIS.h: High speed copy/clear operations utilizing the UltraSparc * Visual Instruction Set. * Index: arch/sparc64/lib/VISbzero.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/VISbzero.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/VISbzero.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/VISbzero.S 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: VISbzero.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: VISbzero.S,v 1.2 2004/08/04 01:26:17 joff Exp $ * VISbzero.S: High speed clear operations utilizing the UltraSparc * Visual Instruction Set. * Index: arch/sparc64/lib/VIScopy.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/VIScopy.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/VIScopy.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/VIScopy.S 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: VIScopy.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: VIScopy.S,v 1.2 2004/08/04 01:26:17 joff Exp $ * VIScopy.S: High speed copy operations utilizing the UltraSparc * Visual Instruction Set. * @@ -120,7 +120,6 @@ #define EXVIS2(x,y) EXVISN(x,y,2) #define EXVIS3(x,y) EXVISN(x,y,3) #define EXVIS4(x,y) EXVISN(x,y,4) -#define EXVIS5(x,y) EXVISN(x,y,5) #define FREG_FROB(f1, f2, f3, f4, f5, f6, f7, f8, f9) \ faligndata %f1, %f2, %f48; \ @@ -135,7 +134,7 @@ #define MAIN_LOOP_CHUNK(src, dest, fdest, fsrc, len, jmptgt) \ EXVIS(LDBLK [%src] ASIBLK, %fdest); \ ASI_SETDST_BLK \ - EXVIS2(STBLK %fsrc, [%dest] ASIBLK); \ + EXVIS(STBLK %fsrc, [%dest] ASIBLK); \ add %src, 0x40, %src; \ subcc %len, 0x40, %len; \ be,pn %xcc, jmptgt; \ @@ -156,14 +155,14 @@ #ifdef __KERNEL__ #define STORE_JUMP(dest, fsrc, target) \ srl asi_dest, 3, %g5; \ - EXVIS3(STBLK %fsrc, [%dest] ASIBLK); \ + EXVIS2(STBLK %fsrc, [%dest] ASIBLK); \ xor asi_dest, ASI_BLK_XOR1, asi_dest;\ add %dest, 0x40, %dest; \ xor asi_dest, %g5, asi_dest; \ ba,pt %xcc, target; #else #define STORE_JUMP(dest, fsrc, target) \ - EXVIS3(STBLK %fsrc, [%dest] ASIBLK); \ + EXVIS2(STBLK %fsrc, [%dest] ASIBLK); \ add %dest, 0x40, %dest; \ ba,pt %xcc, target; #endif @@ -182,7 +181,7 @@ subcc %left, 8, %left; \ bl,pn %xcc, vis_out; \ faligndata %f0, %f1, %f48; \ - EXVIS4(STDF %f48, [%dest] ASINORMAL); \ + EXVIS3(STDF %f48, [%dest] ASINORMAL); \ add %dest, 8, %dest; #define UNEVEN_VISCHUNK_LAST(dest, f0, f1, left) \ @@ -675,21 +674,21 @@ xor asi_src, %g5, asi_src ! IEU0 Group #endif vis_slk:ASI_SETSRC_NOBLK ! LSU Group - EXVIS4(LDDF [%o1] ASINORMAL, %f2) ! Load Group + EXVIS3(LDDF [%o1] ASINORMAL, %f2) ! Load Group add %o1, 8, %o1 ! IEU0 subcc %g3, 8, %g3 ! IEU1 ASI_SETDST_NOBLK ! LSU Group faligndata %f0, %f2, %f8 ! GRU Group - EXVIS5(STDF %f8, [%o0] ASINORMAL) ! Store + EXVIS4(STDF %f8, [%o0] ASINORMAL) ! Store bl,pn %xcc, vis_out_slp ! CTI add %o0, 8, %o0 ! IEU0 Group ASI_SETSRC_NOBLK ! LSU Group - EXVIS4(LDDF [%o1] ASINORMAL, %f0) ! Load Group + EXVIS3(LDDF [%o1] ASINORMAL, %f0) ! Load Group add %o1, 8, %o1 ! IEU0 subcc %g3, 8, %g3 ! IEU1 ASI_SETDST_NOBLK ! LSU Group faligndata %f2, %f0, %f8 ! GRU Group - EXVIS5(STDF %f8, [%o0] ASINORMAL) ! Store + EXVIS4(STDF %f8, [%o0] ASINORMAL) ! Store bge,pt %xcc, vis_slk ! CTI add %o0, 8, %o0 ! IEU0 Group vis_out_slp: @@ -1138,20 +1137,18 @@ sub %g7, %g2, %g7 ba,pt %xcc, VIScopyfixup_ret add %g7, %o2, %o1 -VIScopyfixup_vis3: - sub %o2, 0x80, %o2 VIScopyfixup_vis2: - add %o2, 0x40, %o2 + sub %o2, 0x40, %o2 VIScopyfixup_vis0: add %o2, 0x80, %o2 VIScopyfixup_vis1: add %g7, %g3, %g7 ba,pt %xcc, VIScopyfixup_ret add %o2, %g7, %o1 -VIScopyfixup_vis5: - add %g3, 8, %g3 VIScopyfixup_vis4: add %g3, 8, %g3 +VIScopyfixup_vis3: + add %g3, 8, %g3 ba,pt %xcc, VIScopyfixup_ret add %o2, %g3, %o1 #endif Index: arch/sparc64/lib/VIScsum.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/VIScsum.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/VIScsum.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/VIScsum.S 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: VIScsum.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: VIScsum.S,v 1.2 2004/08/04 01:26:17 joff Exp $ * VIScsum.S: High bandwidth IP checksumming utilizing the UltraSparc * Visual Instruction Set. * Index: arch/sparc64/lib/VIScsumcopy.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/VIScsumcopy.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/VIScsumcopy.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/VIScsumcopy.S 4 Aug 2004 01:26:17 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: VIScsumcopy.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: VIScsumcopy.S,v 1.2 2004/08/04 01:26:17 joff Exp $ * VIScsumcopy.S: High bandwidth IP checksumming with simultaneous * copying utilizing the UltraSparc Visual Instruction Set. * Index: arch/sparc64/lib/VIScsumcopyusr.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/VIScsumcopyusr.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/VIScsumcopyusr.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/VIScsumcopyusr.S 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: VIScsumcopyusr.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: VIScsumcopyusr.S,v 1.2 2004/08/04 01:26:18 joff Exp $ * VIScsumcopyusr.S: High bandwidth IP checksumming with simultaneous * copying utilizing the UltraSparc Visual Instruction Set. * Index: arch/sparc64/lib/VISmemset.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/VISmemset.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/VISmemset.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/VISmemset.S 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: VISmemset.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: VISmemset.S,v 1.2 2004/08/04 01:26:18 joff Exp $ * VISmemset.S: High speed memset operations utilizing the UltraSparc * Visual Instruction Set. * Index: arch/sparc64/lib/VISsave.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/VISsave.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/VISsave.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/VISsave.S 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: VISsave.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: VISsave.S,v 1.2 2004/08/04 01:26:18 joff Exp $ * VISsave.S: Code for saving FPU register state for * VIS routines. One should not call this directly, * but use macros provided in . Index: arch/sparc64/lib/atomic.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/atomic.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/atomic.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/atomic.S 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: atomic.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: atomic.S,v 1.2 2004/08/04 01:26:18 joff Exp $ * atomic.S: These things are too big to do inline. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) Index: arch/sparc64/lib/bitops.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/bitops.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/bitops.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/bitops.S 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: bitops.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: bitops.S,v 1.2 2004/08/04 01:26:18 joff Exp $ * bitops.S: Sparc64 atomic bit operations. * * Copyright (C) 2000 David S. Miller (davem@redhat.com) Index: arch/sparc64/lib/blockops.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/blockops.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/blockops.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/blockops.S 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: blockops.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: blockops.S,v 1.2 2004/08/04 01:26:18 joff Exp $ * blockops.S: UltraSparc block zero optimized routines. * * Copyright (C) 1996, 1998, 1999, 2000 David S. Miller (davem@redhat.com) Index: arch/sparc64/lib/debuglocks.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/debuglocks.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/debuglocks.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/debuglocks.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: debuglocks.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: debuglocks.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * debuglocks.c: Debugging versions of SMP locking primitives. * * Copyright (C) 1998 David S. Miller (davem@redhat.com) Index: arch/sparc64/lib/dec_and_lock.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/dec_and_lock.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/dec_and_lock.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/dec_and_lock.S 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: dec_and_lock.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: dec_and_lock.S,v 1.2 2004/08/04 01:26:18 joff Exp $ * dec_and_lock.S: Sparc64 version of "atomic_dec_and_lock()" * using cas and ldstub instructions. * Index: arch/sparc64/lib/memcmp.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/memcmp.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/memcmp.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/memcmp.S 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: memcmp.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: memcmp.S,v 1.2 2004/08/04 01:26:18 joff Exp $ * Sparc64 optimized memcmp code. * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) Index: arch/sparc64/lib/memscan.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/memscan.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/memscan.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/memscan.S 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: memscan.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: memscan.S,v 1.2 2004/08/04 01:26:18 joff Exp $ * memscan.S: Optimized memscan for Sparc64. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@ultra.linux.cz) Index: arch/sparc64/lib/rwlock.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/rwlock.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/rwlock.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/rwlock.S 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: rwlock.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: rwlock.S,v 1.2 2004/08/04 01:26:18 joff Exp $ * rwlocks.S: These things are too big to do inline. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) Index: arch/sparc64/lib/strncmp.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/strncmp.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/strncmp.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/strncmp.S 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: strncmp.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: strncmp.S,v 1.2 2004/08/04 01:26:18 joff Exp $ * Sparc64 optimized strncmp code. * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) Index: arch/sparc64/lib/strncpy_from_user.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/lib/strncpy_from_user.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/lib/strncpy_from_user.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/lib/strncpy_from_user.S 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: strncpy_from_user.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: strncpy_from_user.S,v 1.2 2004/08/04 01:26:18 joff Exp $ * strncpy_from_user.S: Sparc64 strncpy from userspace. * * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz) Index: arch/sparc64/math-emu/math.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/math-emu/math.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/math-emu/math.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/math-emu/math.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: math.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: math.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * arch/sparc64/math-emu/math.c * * Copyright (C) 1997,1999 Jakub Jelinek (jj@ultra.linux.cz) Index: arch/sparc64/math-emu/sfp-util.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/math-emu/sfp-util.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/math-emu/sfp-util.h 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/math-emu/sfp-util.h 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sfp-util.h,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: sfp-util.h,v 1.2 2004/08/04 01:26:18 joff Exp $ * arch/sparc64/math-emu/sfp-util.h * * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz) Index: arch/sparc64/mm/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/mm/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/mm/Makefile 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/mm/Makefile 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.1 2004/07/22 19:49:21 joff Exp $ +# $Id: Makefile,v 1.2 2004/08/04 01:26:18 joff Exp $ # Makefile for the linux Sparc64-specific parts of the memory manager. # Index: arch/sparc64/mm/fault.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/mm/fault.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/mm/fault.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/mm/fault.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: fault.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc64/mm/generic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/mm/generic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/mm/generic.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/mm/generic.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: generic.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: generic.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * generic.c: Generic Sparc mm routines that are not dependent upon * MMU type but are Sparc specific. * Index: arch/sparc64/mm/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/mm/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/mm/init.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/mm/init.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: init.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * arch/sparc64/mm/init.c * * Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu) @@ -34,6 +34,7 @@ #include #include #include +#include mmu_gather_t mmu_gathers[NR_CPUS]; @@ -44,9 +45,16 @@ unsigned long *sparc64_valid_addr_bitmap; /* Ugly, but necessary... -DaveM */ -unsigned long phys_base; +unsigned long phys_base, kern_base, kern_size; -enum ultra_tlb_layout tlb_type = spitfire; +/* This is even uglier. We have a problem where the kernel may not be + * located at phys_base. However, initial __alloc_bootmem() calls need to + * be adjusted to be within the 4-8Megs that the kernel is mapped to, else + * those page mappings wont work. Things are ok after inherit_prom_mappings + * is called though. Dave says he'll clean this up some other time. + * -- BenC + */ +static unsigned long bootmap_base; /* get_new_mmu_context() uses "cache + 1". */ spinlock_t ctx_alloc_lock = SPIN_LOCK_UNLOCKED; @@ -54,9 +62,6 @@ #define CTX_BMAP_SLOTS (1UL << (CTX_VERSION_SHIFT - 6)) unsigned long mmu_context_bmap[CTX_BMAP_SLOTS]; -/* References to section boundaries */ -extern char __init_begin, __init_end, _start, _end, etext, edata; - /* Initial ramdisk setup */ extern unsigned int sparc_ramdisk_image; extern unsigned int sparc_ramdisk_size; @@ -346,7 +351,7 @@ n += 5 * sizeof(struct linux_prom_translation); for (tsz = 1; tsz < n; tsz <<= 1) /* empty */; - trans = __alloc_bootmem(tsz, SMP_CACHE_BYTES, 0UL); + trans = __alloc_bootmem(tsz, SMP_CACHE_BYTES, bootmap_base); if (trans == NULL) { prom_printf("inherit_prom_mappings: Cannot alloc translations.\n"); prom_halt(); @@ -366,7 +371,7 @@ * in inherit_locked_prom_mappings()). */ #define OBP_PMD_SIZE 2048 - prompmd = __alloc_bootmem(OBP_PMD_SIZE, OBP_PMD_SIZE, 0UL); + prompmd = __alloc_bootmem(OBP_PMD_SIZE, OBP_PMD_SIZE, bootmap_base); if (prompmd == NULL) early_pgtable_allocfail("pmd"); memset(prompmd, 0, OBP_PMD_SIZE); @@ -384,7 +389,7 @@ if (pmd_none(*pmdp)) { ptep = __alloc_bootmem(BASE_PAGE_SIZE, BASE_PAGE_SIZE, - 0UL); + bootmap_base); if (ptep == NULL) early_pgtable_allocfail("pte"); memset(ptep, 0, BASE_PAGE_SIZE); @@ -1204,6 +1209,10 @@ unsigned long bootmap_pfn, bytes_avail, size; int i; +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("bootmem_init: Scan sp_banks, "); +#endif + bytes_avail = 0UL; for (i = 0; sp_banks[i].num_bytes != 0; i++) { end_of_phys_memory = sp_banks[i].base_addr + @@ -1234,15 +1243,8 @@ * image. The kernel is hard mapped below PAGE_OFFSET in a * 4MB locked TLB translation. */ - start_pfn = PAGE_ALIGN((unsigned long) &_end) - - ((unsigned long) KERNBASE); + start_pfn = PAGE_ALIGN(kern_base + kern_size) >> PAGE_SHIFT; - /* Adjust up to the physical address where the kernel begins. */ - start_pfn += phys_base; - - /* Now shift down to get the real physical page frame number. */ - start_pfn >>= PAGE_SHIFT; - bootmap_pfn = start_pfn; end_pfn = end_of_phys_memory >> PAGE_SHIFT; @@ -1270,19 +1272,33 @@ /* Initialize the boot-time allocator. */ max_pfn = max_low_pfn = end_pfn; min_low_pfn = phys_base >> PAGE_SHIFT; - bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, phys_base>>PAGE_SHIFT, end_pfn); + +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("init_bootmem(min[%lx], bootmap[%lx], max[%lx])\n", + min_low_pfn, bootmap_pfn, max_low_pfn); +#endif + bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, min_low_pfn, end_pfn); + + bootmap_base = bootmap_pfn << PAGE_SHIFT; /* Now register the available physical memory with the * allocator. */ - for (i = 0; sp_banks[i].num_bytes != 0; i++) - free_bootmem(sp_banks[i].base_addr, - sp_banks[i].num_bytes); + for (i = 0; sp_banks[i].num_bytes != 0; i++) { +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("free_bootmem(sp_banks:%d): base[%lx] size[%lx]\n", + i, sp_banks[i].base_addr, sp_banks[i].num_bytes); +#endif + free_bootmem(sp_banks[i].base_addr, sp_banks[i].num_bytes); + } #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) { size = initrd_end - initrd_start; - +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("reserve_bootmem(initrd): base[%lx] size[%lx]\n", + initrd_start, size); +#endif /* Resert the initrd image area. */ reserve_bootmem(initrd_start, size); *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT; @@ -1292,15 +1308,21 @@ } #endif /* Reserve the kernel text/data/bss. */ - size = (start_pfn << PAGE_SHIFT) - phys_base; - reserve_bootmem(phys_base, size); - *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT; +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("reserve_bootmem(kernel): base[%lx] size[%lx]\n", kern_base, kern_size); +#endif + reserve_bootmem(kern_base, kern_size); + *pages_avail -= PAGE_ALIGN(kern_size) >> PAGE_SHIFT; /* Reserve the bootmem map. We do not account for it * in pages_avail because we will release that memory * in free_all_bootmem. */ size = bootmap_size; +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("reserve_bootmem(bootmap): base[%lx] size[%lx]\n", + (bootmap_pfn << PAGE_SHIFT), size); +#endif reserve_bootmem((bootmap_pfn << PAGE_SHIFT), size); *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT; @@ -1319,7 +1341,7 @@ extern pmd_t swapper_pmd_dir[1024]; extern unsigned int sparc64_vpte_patchme1[1]; extern unsigned int sparc64_vpte_patchme2[1]; - unsigned long alias_base = phys_base + PAGE_OFFSET; + unsigned long alias_base = kern_base + PAGE_OFFSET; unsigned long second_alias_page = 0; unsigned long pt, flags, end_pfn, pages_avail; unsigned long shift = alias_base - ((unsigned long)KERNBASE); @@ -1339,7 +1361,7 @@ * if this were not true we wouldn't boot up to this point * anyways. */ - pt = phys_base | _PAGE_VALID | _PAGE_SZ4MB; + pt = kern_base | _PAGE_VALID | _PAGE_SZ4MB; pt |= _PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W; __save_and_cli(flags); if (tlb_type == spitfire) { @@ -1419,14 +1441,6 @@ pages_avail = 0; last_valid_pfn = end_pfn = bootmem_init(&pages_avail); -#ifdef CONFIG_SUN_SERIAL - /* This does not logically belong here, but we need to - * call it at the moment we are able to use the bootmem - * allocator. - */ - sun_serial_setup(); -#endif - /* Inherit non-locked OBP mappings. */ inherit_prom_mappings(); @@ -1441,7 +1455,16 @@ } inherit_locked_prom_mappings(1); - + +#ifdef CONFIG_SUN_SERIAL + /* This does not logically belong here, but we need to call it at + * the moment we are able to use the bootmem allocator. This _has_ + * to be done after the prom_mappings above so since + * __alloc_bootmem() doesn't work correctly until then. + */ + sun_serial_setup(); +#endif + /* We only created DTLB mapping of this stuff. */ spitfire_flush_dtlb_nucleus_page(alias_base); if (second_alias_page) @@ -1611,17 +1634,15 @@ i = last_valid_pfn >> ((22 - PAGE_SHIFT) + 6); i += 1; sparc64_valid_addr_bitmap = (unsigned long *) - __alloc_bootmem(i << 3, SMP_CACHE_BYTES, 0UL); + __alloc_bootmem(i << 3, SMP_CACHE_BYTES, bootmap_base); if (sparc64_valid_addr_bitmap == NULL) { prom_printf("mem_init: Cannot alloc valid_addr_bitmap.\n"); prom_halt(); } memset(sparc64_valid_addr_bitmap, 0, i << 3); - addr = PAGE_OFFSET + phys_base; - last = PAGE_ALIGN((unsigned long)&_end) - - ((unsigned long) KERNBASE); - last += PAGE_OFFSET + phys_base; + addr = PAGE_OFFSET + kern_base; + last = PAGE_ALIGN(kern_size) + addr; while (addr < last) { set_bit(__pa(addr) >> 22, sparc64_valid_addr_bitmap); addr += PAGE_SIZE; @@ -1632,6 +1653,9 @@ max_mapnr = last_valid_pfn - (phys_base >> PAGE_SHIFT); high_memory = __va(last_valid_pfn << PAGE_SHIFT); +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("mem_init: Calling free_all_bootmem().\n"); +#endif num_physpages = free_all_bootmem() - 1; /* @@ -1658,7 +1682,7 @@ /* Put empty_pg_dir on pgd_quicklist */ extern pgd_t empty_pg_dir[1024]; unsigned long addr = (unsigned long)empty_pg_dir; - unsigned long alias_base = phys_base + PAGE_OFFSET - + unsigned long alias_base = kern_base + PAGE_OFFSET - (long)(KERNBASE); memset(empty_pg_dir, 0, sizeof(empty_pg_dir)); @@ -1693,7 +1717,7 @@ struct page *p; page = (addr + - ((unsigned long) __va(phys_base)) - + ((unsigned long) __va(kern_base)) - ((unsigned long) KERNBASE)); p = virt_to_page(page); Index: arch/sparc64/mm/modutil.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/mm/modutil.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/mm/modutil.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/mm/modutil.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: modutil.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: modutil.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * arch/sparc64/mm/modutil.c * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -11,9 +11,9 @@ #include #include -static struct vm_struct * modvmlist = NULL; +static struct vm_struct *modvmlist = NULL; -void module_unmap (void * addr) +void __module_unmap(void *addr, int free_area_pages) { struct vm_struct **p, *tmp; @@ -26,7 +26,9 @@ for (p = &modvmlist ; (tmp = *p) ; p = &tmp->next) { if (tmp->addr == addr) { *p = tmp->next; - vmfree_area_pages(VMALLOC_VMADDR(tmp->addr), tmp->size); + if (free_area_pages) + vmfree_area_pages(VMALLOC_VMADDR(tmp->addr), + tmp->size); kfree(tmp); return; } @@ -34,13 +36,19 @@ printk("Trying to unmap nonexistent module vm area (%p)\n", addr); } -void * module_map (unsigned long size) +void module_unmap(void *addr) +{ + __module_unmap(addr, 1); +} + +void *module_map (unsigned long size) { void * addr; struct vm_struct **p, *tmp, *area; size = PAGE_ALIGN(size); - if (!size || size > MODULES_LEN) return NULL; + if (!size || size > MODULES_LEN) + return NULL; addr = (void *) MODULES_VADDR; for (p = &modvmlist; (tmp = *p) ; p = &tmp->next) { @@ -48,17 +56,19 @@ break; addr = (void *) (tmp->size + (unsigned long) tmp->addr); } - if ((unsigned long) addr + size >= MODULES_END) return NULL; + if ((unsigned long) addr + size >= MODULES_END) + return NULL; area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL); - if (!area) return NULL; + if (!area) + return NULL; area->size = size + PAGE_SIZE; area->addr = addr; area->next = *p; *p = area; if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size, GFP_KERNEL, PAGE_KERNEL)) { - module_unmap(addr); + __module_unmap(addr, 0); return NULL; } return addr; Index: arch/sparc64/mm/ultra.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/mm/ultra.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/mm/ultra.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/mm/ultra.S 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ultra.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: ultra.S,v 1.2 2004/08/04 01:26:18 joff Exp $ * ultra.S: Don't expand these all over the place... * * Copyright (C) 1997, 2000 David S. Miller (davem@redhat.com) Index: arch/sparc64/prom/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/prom/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/prom/Makefile 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/prom/Makefile 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.1 2004/07/22 19:49:21 joff Exp $ +# $Id: Makefile,v 1.2 2004/08/04 01:26:18 joff Exp $ # Makefile for the Sun Boot PROM interface library under # Linux. # Index: arch/sparc64/prom/bootstr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/prom/bootstr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/prom/bootstr.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/prom/bootstr.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: bootstr.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: bootstr.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * bootstr.c: Boot string/argument acquisition from the PROM. * * Copyright(C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -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; } Index: arch/sparc64/prom/console.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/prom/console.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/prom/console.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/prom/console.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: console.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: console.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * console.c: Routines that deal with sending and receiving IO * to/from the current console device using the PROM. * Index: arch/sparc64/prom/devops.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/prom/devops.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/prom/devops.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/prom/devops.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: devops.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: devops.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * devops.c: Device operations using the PROM. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc64/prom/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/prom/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/prom/init.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/prom/init.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: init.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * init.c: Initialize internal variables used by the PROM * library functions. * @@ -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(); Index: arch/sparc64/prom/map.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/prom/map.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/prom/map.S 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/prom/map.S 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: map.S,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: map.S,v 1.2 2004/08/04 01:26:18 joff Exp $ * map.S: Tricky coding required to fixup the kernel OBP maps * properly. * Index: arch/sparc64/prom/memory.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/prom/memory.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/prom/memory.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/prom/memory.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: memory.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: memory.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * memory.c: Prom routine for acquiring various bits of information * about RAM on the machine, both virtual and physical. * Index: arch/sparc64/prom/misc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/prom/misc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/prom/misc.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/prom/misc.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: misc.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * misc.c: Miscellaneous prom functions that don't belong * anywhere else. * Index: arch/sparc64/prom/p1275.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/prom/p1275.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/prom/p1275.c 22 Jul 2004 19:49:21 -0000 1.1 +++ arch/sparc64/prom/p1275.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: p1275.c,v 1.1 2004/07/22 19:49:21 joff Exp $ +/* $Id: p1275.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * p1275.c: Sun IEEE 1275 PROM low level interface routines * * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) Index: arch/sparc64/prom/printf.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/prom/printf.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/prom/printf.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/prom/printf.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: printf.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: printf.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * printf.c: Internal prom library printf facility. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: arch/sparc64/prom/tree.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/prom/tree.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/prom/tree.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/prom/tree.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: tree.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: tree.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * tree.c: Basic device tree traversal/scanning for the Linux * prom library. * Index: arch/sparc64/solaris/conv.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/solaris/conv.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/solaris/conv.h 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/solaris/conv.h 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: conv.h,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: conv.h,v 1.2 2004/08/04 01:26:18 joff Exp $ * conv.h: Utility macros for Solaris emulation * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) Index: arch/sparc64/solaris/entry64.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/solaris/entry64.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/solaris/entry64.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/solaris/entry64.S 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: entry64.S,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: entry64.S,v 1.2 2004/08/04 01:26:18 joff Exp $ * entry64.S: Solaris syscall emulation entry point. * * Copyright (C) 1996,1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) Index: arch/sparc64/solaris/fs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/solaris/fs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/solaris/fs.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/solaris/fs.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: fs.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: fs.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * fs.c: fs related syscall emulation for Solaris * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) Index: arch/sparc64/solaris/ioctl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/solaris/ioctl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/solaris/ioctl.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/solaris/ioctl.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ioctl.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: ioctl.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * ioctl.c: Solaris ioctl emulation. * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) Index: arch/sparc64/solaris/ipc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/solaris/ipc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/solaris/ipc.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/solaris/ipc.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ipc.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: ipc.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * ipc.c: Solaris IPC emulation * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) Index: arch/sparc64/solaris/misc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/solaris/misc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/solaris/misc.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/solaris/misc.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: misc.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * misc.c: Miscelaneous syscall emulation for Solaris * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) Index: arch/sparc64/solaris/signal.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/solaris/signal.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/solaris/signal.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/solaris/signal.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: signal.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: signal.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * signal.c: Signal emulation for Solaris * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) Index: arch/sparc64/solaris/signal.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/solaris/signal.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/solaris/signal.h 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/solaris/signal.h 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: signal.h,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: signal.h,v 1.2 2004/08/04 01:26:18 joff Exp $ * signal.h: Signal emulation for Solaris * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) Index: arch/sparc64/solaris/socket.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/solaris/socket.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/solaris/socket.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/solaris/socket.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: socket.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: socket.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * socket.c: Socket syscall emulation for Solaris 2.6+ * * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) Index: arch/sparc64/solaris/socksys.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/solaris/socksys.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/solaris/socksys.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/solaris/socksys.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: socksys.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: socksys.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * socksys.c: /dev/inet/ stuff for Solaris emulation. * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) Index: arch/sparc64/solaris/socksys.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/solaris/socksys.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/solaris/socksys.h 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/solaris/socksys.h 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: socksys.h,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: socksys.h,v 1.2 2004/08/04 01:26:18 joff Exp $ * socksys.h: Definitions for STREAMS modules emulation code. * * Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz) Index: arch/sparc64/solaris/systbl.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/solaris/systbl.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/solaris/systbl.S 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/solaris/systbl.S 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: systbl.S,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: systbl.S,v 1.2 2004/08/04 01:26:18 joff Exp $ * systbl.S: System call entry point table for Solaris compatibility. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) Index: arch/sparc64/solaris/timod.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/sparc64/solaris/timod.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/sparc64/solaris/timod.c 22 Jul 2004 19:49:22 -0000 1.1 +++ arch/sparc64/solaris/timod.c 4 Aug 2004 01:26:18 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: timod.c,v 1.1 2004/07/22 19:49:22 joff Exp $ +/* $Id: timod.c,v 1.2 2004/08/04 01:26:18 joff Exp $ * timod.c: timod emulation. * * Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz) Index: arch/x86_64/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/Makefile 22 Jul 2004 19:49:25 -0000 1.1 +++ arch/x86_64/Makefile 4 Aug 2004 01:26:18 -0000 1.2 @@ -19,7 +19,7 @@ # 20010105 Andi Kleen, add IA32 compiler. # ....and later removed it again.... # -# $Id: Makefile,v 1.1 2004/07/22 19:49:25 joff Exp $ +# $Id: Makefile,v 1.2 2004/08/04 01:26:18 joff Exp $ # # early bootup linking needs 32bit. You can either use real 32bit tools @@ -38,6 +38,8 @@ LDFLAGS=-e stext LINKFLAGS =-T $(TOPDIR)/arch/x86_64/vmlinux.lds $(LDFLAGS) +check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1 ; then echo "$(1)"; else echo "$(2)"; fi) + CFLAGS += -mno-red-zone CFLAGS += -mcmodel=kernel CFLAGS += -pipe @@ -46,13 +48,20 @@ 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 endif +# this is needed right now for the 32bit ioctl code +CFLAGS += $(call check_gcc,-fno-unit-at-a-time,) -# prevent gcc from keeping the stack 16 byte aligned (FIXME) -#CFLAGS += -mpreferred-stack-boundary=2 +ifdef CONFIG_MK8 +CFLAGS += $(call check_gcc,-march=k8,) +endif +ifdef CONFIG_MPSC +CFLAGS += $(call check_gcc,-march=nocona,) +endif HEAD := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o Index: arch/x86_64/config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/config.in 22 Jul 2004 19:49:25 -0000 1.1 +++ arch/x86_64/config.in 4 Aug 2004 01:26:18 -0000 1.2 @@ -10,7 +10,7 @@ define_bool CONFIG_ISA n define_bool CONFIG_SBUS n -define_bool CONFIG_UID16 y +define_bool CONFIG_UID16 n define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n define_bool CONFIG_X86_CMPXCHG y @@ -34,13 +34,19 @@ comment 'Processor type and features' choice 'Processor family' \ "AMD-Hammer CONFIG_MK8 \ + Intel-x86-64 CONFIG_MPSC \ Generic-x86-64 CONFIG_GENERIC_CPU" AMD-Hammer # # Define implied options from the CPU selection here # +if [ "$CONFIG_GENERIC_CPU" = "y" -o "$CONFIG_MPSC" = "y" ]; then +define_int CONFIG_X86_L1_CACHE_BYTES 128 +define_int CONFIG_X86_L1_CACHE_SHIFT 7 +else define_int CONFIG_X86_L1_CACHE_BYTES 64 define_int CONFIG_X86_L1_CACHE_SHIFT 6 +fi define_bool CONFIG_X86_TSC y define_bool CONFIG_X86_GOOD_APIC y @@ -58,6 +64,9 @@ bool 'Symmetric multi-processing support' CONFIG_SMP bool 'HPET timers' CONFIG_HPET_TIMER bool 'IOMMU support' CONFIG_GART_IOMMU +if [ "$CONFIG_GART_IOMMU" = "y" ]; then + bool 'SWIOTLB support' CONFIG_SWIOTLB +fi if [ "$CONFIG_GART_IOMMU" != "y" ]; then define_bool CONFIG_DUMMY_IOMMU y @@ -66,13 +75,16 @@ define_bool CONFIG_X86_UP_IOAPIC y else define_bool CONFIG_HAVE_DEC_LOCK y + int 'Maximum number of CPUs (2-8)' CONFIG_NR_CPUS 4 fi bool 'Machine check support' CONFIG_MCE -bool 'K8 NUMA support' CONFIG_K8_NUMA -if [ "$CONFIG_K8_NUMA" = "y" ]; then +if [ "$CONFIG_SMP" = "y" ]; then + bool 'K8 NUMA support' CONFIG_K8_NUMA + if [ "$CONFIG_K8_NUMA" = "y" ]; then define_bool CONFIG_DISCONTIGMEM y define_bool CONFIG_NUMA y + fi fi endmenu @@ -112,12 +124,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 +180,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 +239,8 @@ source net/bluetooth/Config.in +source crypto/Config.in + mainmenu_option next_comment comment 'Kernel hacking' @@ -247,6 +256,9 @@ bool ' IOMMU leak tracing' CONFIG_IOMMU_LEAK bool ' Probalistic stack overflow check' CONFIG_DEBUG_STACKOVERFLOW fi + +int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 + endmenu source lib/Config.in Index: arch/x86_64/defconfig =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/defconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/defconfig 22 Jul 2004 19:49:25 -0000 1.1 +++ arch/x86_64/defconfig 4 Aug 2004 01:26:18 -0000 1.2 @@ -5,7 +5,7 @@ CONFIG_X86=y # CONFIG_ISA is not set # CONFIG_SBUS is not set -CONFIG_UID16=y +# CONFIG_UID16 is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_X86_CMPXCHG=y @@ -26,10 +26,11 @@ # # Processor type and features # -CONFIG_MK8=y +# CONFIG_MK8 is not set +CONFIG_MPSC=y # CONFIG_GENERIC_CPU is not set -CONFIG_X86_L1_CACHE_BYTES=64 -CONFIG_X86_L1_CACHE_SHIFT=6 +CONFIG_X86_L1_CACHE_BYTES=128 +CONFIG_X86_L1_CACHE_SHIFT=7 CONFIG_X86_TSC=y CONFIG_X86_GOOD_APIC=y CONFIG_X86_MSR=y @@ -40,12 +41,16 @@ CONFIG_X86_IO_APIC=y CONFIG_X86_LOCAL_APIC=y CONFIG_MTRR=y -# CONFIG_SMP is not set +CONFIG_SMP=y CONFIG_HPET_TIMER=y CONFIG_GART_IOMMU=y -CONFIG_X86_UP_IOAPIC=y +CONFIG_SWIOTLB=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_NR_CPUS=4 CONFIG_MCE=y -# CONFIG_K8_NUMA is not set +CONFIG_K8_NUMA=y +CONFIG_DISCONTIGMEM=y +CONFIG_NUMA=y # # General setup @@ -65,16 +70,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_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 +# CONFIG_ACPI_RELAXED_AML is not set # # Memory Technology Devices (MTD) @@ -95,6 +113,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y @@ -136,6 +155,15 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_SCTP_HMAC_NONE is not set +CONFIG_SCTP_HMAC_SHA1=y +# CONFIG_SCTP_HMAC_MD5 is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -218,7 +246,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 @@ -231,14 +259,12 @@ # 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_NFORCE is not set +CONFIG_BLK_DEV_PIIX=y # 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 @@ -251,10 +277,10 @@ 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_MEDLEY is not set # CONFIG_BLK_DEV_ATARAID_SII is not set # @@ -295,9 +321,15 @@ CONFIG_AIC7XXX_RESET_DELAY_MS=15000 # 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_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -324,18 +356,22 @@ # 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 # # Fusion MPT device support # -# CONFIG_FUSION is not set -# CONFIG_FUSION_BOOT is not set +CONFIG_FUSION=y +CONFIG_FUSION_BOOT=y +CONFIG_FUSION_MAX_SGE=40 # CONFIG_FUSION_ISENSE is not set # CONFIG_FUSION_CTL is not set # CONFIG_FUSION_LAN is not set @@ -391,7 +427,8 @@ # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set -# CONFIG_E1000 is not set +CONFIG_E1000=y +# CONFIG_E1000_NAPI is not set # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set @@ -446,6 +483,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -497,9 +535,11 @@ # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200 is not set # CONFIG_SCx200_GPIO is not set # CONFIG_AMD_RNG is not set # CONFIG_INTEL_RNG is not set +CONFIG_HW_RANDOM=y # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -512,7 +552,7 @@ # # CONFIG_FTAPE is not set CONFIG_AGP=y -CONFIG_AGP_AMD_8151=y +CONFIG_AGP_AMD_K8=y CONFIG_AGP_INTEL=y CONFIG_AGP_I810=y CONFIG_AGP_VIA=y @@ -520,8 +560,15 @@ CONFIG_AGP_SIS=y CONFIG_AGP_ALI=y CONFIG_AGP_SWORKS=y +CONFIG_AGP_NVIDIA=y +# CONFIG_AGP_ATI is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # CONFIG_MWAVE is not set +# CONFIG_OBMOUSE is not set # # Multimedia devices @@ -532,6 +579,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=y @@ -541,6 +589,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 @@ -569,9 +618,6 @@ # 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 @@ -582,7 +628,12 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set -CONFIG_SIMICSFS=y +# CONFIG_SIMICSFS is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -591,6 +642,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=y CONFIG_NFSD_V3=y @@ -683,25 +735,37 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Kernel hacking # CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_SLAB=y CONFIG_MAGIC_SYSRQ=y -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_CHECKING is not set +CONFIG_DEBUG_SPINLOCK=y +CONFIG_CHECKING=y # CONFIG_INIT_DEBUG is not set -# CONFIG_IOMMU_DEBUG is not set +CONFIG_IOMMU_DEBUG=y CONFIG_IOMMU_LEAK=y # CONFIG_DEBUG_STACKOVERFLOW is not set +CONFIG_LOG_BUF_SHIFT=17 # # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set Index: arch/x86_64/boot/setup.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/boot/setup.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/boot/setup.S 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/boot/setup.S 4 Aug 2004 01:26:19 -0000 1.2 @@ -289,8 +289,9 @@ /* minimum CPUID flags for x86-64 */ /* see http://www.x86-64.org/lists/discuss/msg02971.html */ #define SSE_MASK ((1<<25)|(1<<26)) -#define REQUIRED_MASK1 ((1<<0)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<8)|(1<<11)| \ - (1<<13)|(1<<15)|(1<<24)|(1<<29)) +#define REQUIRED_MASK1 ((1<<0)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<8)|\ + (1<<13)|(1<<15)|(1<<24)) +#define REQUIRED_MASK2 (1<<29) pushfl /* standard way to check for cpuid */ popl %eax @@ -302,10 +303,10 @@ popl %eax cmpl %eax,%ebx jz no_longmode /* cpu has no cpuid */ - movl $0x80000000,%eax + movl $0x0,%eax cpuid - cmpl $0x80000001,%eax - jb no_longmode /* no extended cpuid */ + cmpl $0x1,%eax + jb no_longmode /* no cpuid 1 */ xor %di,%di cmpl $0x68747541,%ebx /* AuthenticAMD */ jnz noamd @@ -315,11 +316,20 @@ jnz noamd mov $1,%di /* cpu is from AMD */ noamd: - movl $0x80000001,%eax + movl $0x1,%eax cpuid andl $REQUIRED_MASK1,%edx xorl $REQUIRED_MASK1,%edx jnz no_longmode + movl $0x80000000,%eax + cpuid + cmpl $0x80000001,%eax + jb no_longmode /* no extended cpuid */ + movl $0x80000001,%eax + cpuid + andl $REQUIRED_MASK2,%edx + xorl $REQUIRED_MASK2,%edx + jnz no_longmode sse_test: movl $1,%eax cpuid @@ -347,6 +357,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 @@ -519,7 +534,7 @@ cmpw $0, %cs:realmode_swtch jz rmodeswtch_normal - lcall %cs:realmode_swtch + lcall *%cs:realmode_swtch jmp rmodeswtch_end Index: arch/x86_64/boot/compressed/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/boot/compressed/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/boot/compressed/head.S 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/boot/compressed/head.S 4 Aug 2004 01:26:19 -0000 1.2 @@ -3,7 +3,7 @@ * * Copyright (C) 1991, 1992, 1993 Linus Torvalds * - * $Id: head.S,v 1.1 2004/07/22 19:49:26 joff Exp $ + * $Id: head.S,v 1.2 2004/08/04 01:26:19 joff Exp $ */ /* Index: arch/x86_64/boot/tools/build.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/boot/tools/build.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/boot/tools/build.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/boot/tools/build.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: build.c,v 1.1 2004/07/22 19:49:26 joff Exp $ + * $Id: build.c,v 1.2 2004/08/04 01:26:19 joff Exp $ * * Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 1997 Martin Mares Index: arch/x86_64/ia32/fpu32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/ia32/fpu32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/ia32/fpu32.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/ia32/fpu32.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -2,7 +2,7 @@ * Copyright 2002 Andi Kleen, SuSE Labs. * FXSAVE<->i387 conversion support. Based on code by Gareth Hughes. * This is used for ptrace, signals and coredumps in 32bit emulation. - * $Id: fpu32.c,v 1.1 2004/07/22 19:49:26 joff Exp $ + * $Id: fpu32.c,v 1.2 2004/08/04 01:26:19 joff Exp $ */ #include Index: arch/x86_64/ia32/ia32_binfmt.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/ia32/ia32_binfmt.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/ia32/ia32_binfmt.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/ia32/ia32_binfmt.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -27,7 +28,6 @@ #define ELF_NAME "elf/i386" -#define IA32_PAGE_OFFSET 0xFFFFe000 #define IA32_STACK_TOP IA32_PAGE_OFFSET #define ELF_ET_DYN_BASE (IA32_PAGE_OFFSET/3 + 0x1000000) @@ -162,7 +162,7 @@ # define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE #endif -#define ELF_PLAT_INIT(r) elf32_init(r) +#define ELF_PLAT_INIT(r, load_addr) elf32_init(r) #define setup_arg_pages(bprm) ia32_setup_arg_pages(bprm) extern void load_gs_index(unsigned); @@ -243,8 +243,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; Index: arch/x86_64/ia32/ia32_ioctl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/ia32/ia32_ioctl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/ia32/ia32_ioctl.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/ia32/ia32_ioctl.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ia32_ioctl.c,v 1.1 2004/07/22 19:49:26 joff Exp $ +/* $Id: ia32_ioctl.c,v 1.2 2004/08/04 01:26:19 joff Exp $ * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) @@ -112,10 +113,16 @@ #include - #define A(__x) ((void *)(unsigned long)(__x)) #define AA(__x) A(__x) +/* Allocate memory on the user stack */ +static __inline__ void *compat_alloc_user_space(long len) +{ + struct pt_regs *regs = (void *)current->thread.rsp0 - sizeof(struct pt_regs); + return (void *)regs->rsp - len; +} + /* Aiee. Someone does not find a difference between int and long */ #define EXT2_IOC32_GETFLAGS _IOR('f', 1, int) #define EXT2_IOC32_SETFLAGS _IOW('f', 2, int) @@ -1778,7 +1785,10 @@ unsigned int buflen; int stat; __kernel_caddr_t32 sense; - __kernel_caddr_t32 reserved[3]; + unsigned char data_direction; + int quiet; + int timeout; + __kernel_caddr_t32 reserved[1]; }; static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) @@ -1820,17 +1830,25 @@ return -EFAULT; cdreadaudio.buf = (void *)A(addr); break; - case CDROM_SEND_PACKET: + case CDROM_SEND_PACKET: { + __kernel_caddr_t32 sense; karg = &cgc; err = copy_from_user(cgc.cmd, &((struct cdrom_generic_command32 *)arg)->cmd, sizeof(cgc.cmd)); err |= __get_user(addr, &((struct cdrom_generic_command32 *)arg)->buffer); err |= __get_user(cgc.buflen, &((struct cdrom_generic_command32 *)arg)->buflen); + err |= __get_user(sense, &((struct cdrom_generic_command32 *)arg)->sense); + err |= __get_user(cgc.data_direction, &((struct cdrom_generic_command32 *)arg)->data_direction); + err |= __get_user(cgc.timeout, &((struct cdrom_generic_command32 *)arg)->timeout); if (err) return -EFAULT; if (verify_area(VERIFY_WRITE, (void *)A(addr), cgc.buflen)) return -EFAULT; + if (sense && verify_area(VERIFY_WRITE, (void *)A(sense), sizeof(struct request_sense))) + return -EFAULT; cgc.buffer = (void *)A(addr); + cgc.sense = (void *)A(sense); break; + } default: do { static int count; @@ -2472,6 +2490,9 @@ mm_segment_t old_fs; void *karg = &u; + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + switch (cmd) { case VG_STATUS: v = kmalloc(sizeof(vg_t), GFP_KERNEL); @@ -2744,7 +2765,7 @@ struct file *file = fget(fd); struct tty_struct *real_tty; - if (!fd) + if (!file) return -EBADF; if (file->f_op->ioctl != tty_ioctl) return -EINVAL; @@ -2914,7 +2935,7 @@ return ret; case RTC_IRQP_SET32: - cmd = RTC_EPOCH_SET; + cmd = RTC_IRQP_SET; break; case RTC_EPOCH_READ32: @@ -3481,6 +3502,77 @@ return err; } + +struct compat_iw_point { + __u32 pointer; + __u16 length; + __u16 flags; +}; + +static int do_wireless_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + struct iwreq *iwr, *iwr_u; + struct iw_point *iwp; + struct compat_iw_point *iwp_u; + __u32 pointer; + __u16 length, flags; + + iwr_u = (struct iwreq *) (u64)arg; + iwp_u = (struct compat_iw_point *) &iwr_u->u.data; + iwr = compat_alloc_user_space(sizeof(*iwr)); + if (iwr == NULL) + return -ENOMEM; + + iwp = &iwr->u.data; + + if (verify_area(VERIFY_WRITE, iwr, sizeof(*iwr))) + return -EFAULT; + + if (__copy_in_user(&iwr->ifr_ifrn.ifrn_name[0], + &iwr_u->ifr_ifrn.ifrn_name[0], + sizeof(iwr->ifr_ifrn.ifrn_name))) + return -EFAULT; + + if (__get_user(pointer, &iwp_u->pointer) || + __get_user(length, &iwp_u->length) || + __get_user(flags, &iwp_u->flags)) + return -EFAULT; + + if (__put_user((u64)pointer, &iwp->pointer) || + __put_user(length, &iwp->length) || + __put_user(flags, &iwp->flags)) + return -EFAULT; + + return sys_ioctl(fd, cmd, (unsigned long) iwr); +} + +struct compat_ctrlmsg_ioctl { + struct usb_ctrlrequest req; + u32 data; +}; + +struct ctrlmsg_ioctl { + struct usb_ctrlrequest req; + void *data; +}; + +#define SCANNER_IOCTL_CTRLMSG _IOWR('U', 0x22, struct usb_ctrlrequest) + +static int scanner_ioctl_ctrlmsg(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + struct ctrlmsg_ioctl *c64; + struct compat_ctrlmsg_ioctl *c32 = (void *)arg; + u32 ptr; + + c64 = compat_alloc_user_space(sizeof(struct ctrlmsg_ioctl)); + + if (copy_in_user(&c64->req, &c32->req, sizeof(struct usb_ctrlrequest)) || + get_user(ptr, &c32->data) || + put_user((void *)(unsigned long)ptr, &c64->data)) + return -EFAULT; + return sys_ioctl(fd,cmd, (unsigned long)c64); +} + struct ioctl_trans { unsigned long cmd; int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp); @@ -3488,7 +3580,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" ); @@ -3535,6 +3627,7 @@ COMPATIBLE_IOCTL(TIOCGPTN) COMPATIBLE_IOCTL(TIOCSPTLCK) COMPATIBLE_IOCTL(TIOCSERGETLSR) +COMPATIBLE_IOCTL(FIOQSIZE) /* Big F */ COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO) COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO) @@ -4353,6 +4446,32 @@ HANDLE_IOCTL(MTRRIOC32_DEL_PAGE_ENTRY, mtrr_ioctl32) HANDLE_IOCTL(MTRRIOC32_GET_PAGE_ENTRY, mtrr_ioctl32) HANDLE_IOCTL(MTRRIOC32_KILL_PAGE_ENTRY, mtrr_ioctl32) +/* wireless */ +HANDLE_IOCTL(SIOCGIWRANGE, do_wireless_ioctl) +HANDLE_IOCTL(SIOCSIWSPY, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWSPY, do_wireless_ioctl) +HANDLE_IOCTL(SIOCSIWTHRSPY, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWTHRSPY, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWAPLIST, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWSCAN, do_wireless_ioctl) +HANDLE_IOCTL(SIOCSIWESSID, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWESSID, do_wireless_ioctl) +HANDLE_IOCTL(SIOCSIWNICKN, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWNICKN, do_wireless_ioctl) +HANDLE_IOCTL(SIOCSIWENCODE, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWENCODE, do_wireless_ioctl) +COMPATIBLE_IOCTL(SIOCGIWNAME) + +COMPATIBLE_IOCTL(SIOCSIFNAME) +/* usb scanner */ +#define SCANNER_IOCTL_VENDOR _IOR('U', 0x20, int) +#define SCANNER_IOCTL_PRODUCT _IOR('U', 0x21, int) + +COMPATIBLE_IOCTL(SCANNER_IOCTL_VENDOR) +COMPATIBLE_IOCTL(SCANNER_IOCTL_PRODUCT) +/* USB scanner 'U' */ +HANDLE_IOCTL(SCANNER_IOCTL_CTRLMSG, scanner_ioctl_ctrlmsg) + IOCTL_TABLE_END #define IOCTL_HASHSIZE 256 @@ -4416,6 +4535,9 @@ struct ioctl_trans *t; unsigned long hash = ioctl32_hash(cmd); + if (handler == NULL) + handler = (void *)sys_ioctl; + lock_kernel(); for (t = (struct ioctl_trans *)ioctl32_hash_table[hash]; t; @@ -4529,7 +4651,9 @@ t = (struct ioctl_trans *)t->next; if (t) { handler = t->handler; + lock_kernel(); error = handler(fd, cmd, arg, filp); + unlock_kernel(); } else if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { error = siocdevprivate_ioctl(fd, cmd, arg); } else { Index: arch/x86_64/ia32/ia32_signal.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/ia32/ia32_signal.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/ia32/ia32_signal.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/ia32/ia32_signal.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -7,7 +7,7 @@ * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes * 2000-12-* x86-64 compatibility mode signal handling by Andi Kleen * - * $Id: ia32_signal.c,v 1.1 2004/07/22 19:49:26 joff Exp $ + * $Id: ia32_signal.c,v 1.2 2004/08/04 01:26:19 joff Exp $ */ #include @@ -78,6 +78,10 @@ default: err |= __put_user(from->si_uid, &to->si_uid); break; + case __SI_POLL >> 16: + err |= __put_user(from->si_band, &to->si_band); + err |= __put_user(from->si_fd, &to->si_fd); + break; /* case __SI_RT: This is not generated by the kernel as of now. */ } return err; Index: arch/x86_64/ia32/ia32entry.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/ia32/ia32entry.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/ia32/ia32entry.S 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/ia32/ia32entry.S 4 Aug 2004 01:26:19 -0000 1.2 @@ -3,7 +3,7 @@ * * Copyright 2000,2001 Andi Kleen, SuSE Labs. * - * $Id: ia32entry.S,v 1.1 2004/07/22 19:49:26 joff Exp $ + * $Id: ia32entry.S,v 1.2 2004/08/04 01:26:19 joff Exp $ */ #include @@ -256,10 +256,10 @@ .quad sys32_adjtimex .quad sys32_mprotect /* 125 */ .quad sys32_sigprocmask - .quad sys32_module_warning /* create_module */ - .quad sys32_module_warning /* init_module */ - .quad sys32_module_warning /* delete module */ - .quad sys32_module_warning /* 130 get_kernel_syms */ + .quad sys32_create_module + .quad sys32_init_module + .quad sys32_delete_module + .quad sys32_get_kernel_syms /* 130 */ .quad ni_syscall /* quotactl */ .quad sys_getpgid .quad sys_fchdir @@ -296,7 +296,7 @@ .quad sys_setresuid16 .quad sys_getresuid16 /* 165 */ .quad sys32_vm86_warning /* vm86 */ - .quad quiet_ni_syscall /* query_module */ + .quad sys32_query_module .quad sys_poll .quad sys32_nfsservctl .quad sys_setresgid16 /* 170 */ @@ -322,8 +322,8 @@ .quad stub32_vfork /* 190 */ .quad sys32_getrlimit .quad sys32_mmap2 - .quad sys_truncate - .quad sys_ftruncate + .quad sys32_truncate64 + .quad sys32_ftruncate64 .quad sys32_stat64 /* 195 */ .quad sys32_lstat64 .quad sys32_fstat64 Index: arch/x86_64/ia32/ipc32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/ia32/ipc32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/ia32/ipc32.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/ia32/ipc32.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -16,6 +16,8 @@ #include +extern int sem_ctls[]; + /* * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation.. * @@ -163,6 +165,7 @@ #define SEMOP 1 #define SEMGET 2 #define SEMCTL 3 +#define SEMTIMEDOP 4 #define MSGSND 11 #define MSGRCV 12 #define MSGGET 13 @@ -638,7 +641,27 @@ 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: { + int err; + mm_segment_t oldfs = get_fs(); + struct timespec32 *ts32 = (struct timespec32 *)AA(fifth); + struct timespec ts; + if ((unsigned)second > sem_ctls[2]) + return -EINVAL; + if (ts32) { + if (get_user(ts.tv_sec, &ts32->tv_sec) || + __get_user(ts.tv_nsec, &ts32->tv_nsec) || + verify_area(VERIFY_READ, (void *)AA(ptr), + second*sizeof(struct sembuf))) + return -EFAULT; + } + set_fs(KERNEL_DS); + err = sys_semtimedop(first, (struct sembuf *)AA(ptr), second, + ts32 ? &ts : NULL); + set_fs(oldfs); + return err; + } case SEMGET: return sys_semget(first, second, third); case SEMCTL: @@ -663,9 +686,7 @@ case SHMCTL: return shmctl32(first, second, (void *)AA(ptr)); - default: - return -EINVAL; } - return -EINVAL; + return -ENOSYS; } Index: arch/x86_64/ia32/ptrace32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/ia32/ptrace32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/ia32/ptrace32.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/ia32/ptrace32.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -8,7 +8,7 @@ * This allows to access 64bit processes too; but there is no way to see the extended * register contents. * - * $Id: ptrace32.c,v 1.1 2004/07/22 19:49:26 joff Exp $ + * $Id: ptrace32.c,v 1.2 2004/08/04 01:26:19 joff Exp $ */ #include @@ -25,6 +25,10 @@ #include #include +/* determines which flags the user has access to. */ +/* 1 = access 0 = no access */ +#define FLAG_MASK 0x44dd5UL + #define R32(l,q) \ case offsetof(struct user32, regs.l): stack[offsetof(struct pt_regs, q)/8] = val; break @@ -69,9 +73,12 @@ R32(eip, rip); R32(esp, rsp); - case offsetof(struct user32, regs.eflags): - stack[offsetof(struct pt_regs, eflags)/8] = val & 0x44dd5; + case offsetof(struct user32, regs.eflags): { + __u64 *flags = &stack[offsetof(struct pt_regs, eflags)/8]; + val &= FLAG_MASK; + *flags = val | (*flags & ~FLAG_MASK); break; + } case offsetof(struct user32, u_debugreg[4]): case offsetof(struct user32, u_debugreg[5]): Index: arch/x86_64/ia32/socket32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/ia32/socket32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/ia32/socket32.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/ia32/socket32.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -503,7 +503,6 @@ __u32 filter; } *fprog32 = (struct sock_fprog32 *)optval; struct sock_fprog kfprog; - unsigned int fsize; mm_segment_t old_fs; __u32 uptr; int ret; Index: arch/x86_64/ia32/sys_ia32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/ia32/sys_ia32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/ia32/sys_ia32.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/ia32/sys_ia32.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -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.1 2004/07/22 19:49:26 joff Exp $ + * $Id: sys_ia32.c,v 1.2 2004/08/04 01:26:19 joff Exp $ */ #include @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -84,17 +85,23 @@ #define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid) extern int overflowuid,overflowgid; +typedef u16 old_uid_t; +typedef u16 old_gid_t; + +#include "../../../kernel/uid16.c" static int putstat(struct stat32 *ubuf, struct stat *kbuf) { + if (kbuf->st_size > 0x7fffffff) + return -EOVERFLOW; if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct stat32)) || __put_user (kbuf->st_dev, &ubuf->st_dev) || __put_user (kbuf->st_ino, &ubuf->st_ino) || __put_user (kbuf->st_mode, &ubuf->st_mode) || __put_user (kbuf->st_nlink, &ubuf->st_nlink) || - __put_user (kbuf->st_uid, &ubuf->st_uid) || - __put_user (kbuf->st_gid, &ubuf->st_gid) || + __put_user (high2lowuid(kbuf->st_uid), &ubuf->st_uid) || + __put_user (high2lowgid(kbuf->st_gid), &ubuf->st_gid) || __put_user (kbuf->st_rdev, &ubuf->st_rdev) || __put_user (kbuf->st_size, &ubuf->st_size) || __put_user (kbuf->st_atime, &ubuf->st_atime) || @@ -111,16 +118,21 @@ asmlinkage long sys32_newstat(char * filename, struct stat32 *statbuf) { + char *name; int ret; struct stat s; mm_segment_t old_fs = get_fs(); + name = getname(filename); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs (KERNEL_DS); - ret = sys_newstat(filename, &s); + ret = sys_newstat(name, &s); set_fs (old_fs); - if (putstat (statbuf, &s)) - return -EFAULT; + putname(name); + if (ret) return ret; + return putstat(statbuf, &s); } extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf); @@ -128,16 +140,21 @@ asmlinkage long sys32_newlstat(char * filename, struct stat32 *statbuf) { + char *name; int ret; struct stat s; mm_segment_t old_fs = get_fs(); + name = getname(filename); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs (KERNEL_DS); - ret = sys_newlstat(filename, &s); + ret = sys_newlstat(name, &s); set_fs (old_fs); - if (putstat (statbuf, &s)) - return -EFAULT; + putname(name); + if (ret) return ret; + return putstat(statbuf, &s); } extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf); @@ -152,9 +169,25 @@ set_fs (KERNEL_DS); ret = sys_newfstat(fd, &s); set_fs (old_fs); - if (putstat (statbuf, &s)) - return -EFAULT; + if (ret) return ret; + return putstat(statbuf, &s); +} + +extern long sys_truncate(char *, loff_t); + +asmlinkage long +sys32_truncate64(char * filename, unsigned long offset_low, unsigned long offset_high) +{ + return sys_truncate(filename, ((loff_t) offset_high << 32) | offset_low); +} + +extern long sys_ftruncate(int, loff_t); + +asmlinkage long +sys32_ftruncate64(unsigned int fd, unsigned long offset_low, unsigned long offset_high) +{ + return sys_ftruncate(fd, ((loff_t) offset_high << 32) | offset_low); } /* Another set for IA32/LFS -- x86_64 struct stat is different due to @@ -185,31 +218,41 @@ asmlinkage long sys32_stat64(char * filename, struct stat64 *statbuf) { + char *name; int ret; struct stat s; mm_segment_t old_fs = get_fs(); + name = getname(filename); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs (KERNEL_DS); - ret = sys_newstat(filename, &s); + ret = sys_newstat(name, &s); set_fs (old_fs); - if (putstat64 (statbuf, &s)) - return -EFAULT; + putname(name); + if (ret) return ret; + return putstat64(statbuf, &s); } asmlinkage long sys32_lstat64(char * filename, struct stat64 *statbuf) { + char *name; int ret; struct stat s; mm_segment_t old_fs = get_fs(); + name = getname(filename); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs (KERNEL_DS); - ret = sys_newlstat(filename, &s); + ret = sys_newlstat(name, &s); set_fs (old_fs); - if (putstat64 (statbuf, &s)) - return -EFAULT; + putname(name); + if (ret) return ret; + return putstat64(statbuf, &s); } asmlinkage long @@ -222,9 +265,9 @@ set_fs (KERNEL_DS); ret = sys_newfstat(fd, &s); set_fs (old_fs); - if (putstat64 (statbuf, &s)) - return -EFAULT; + if (ret) return ret; + return putstat64(statbuf, &s); } /* Don't set O_LARGEFILE implicitely. */ @@ -475,7 +518,13 @@ __put_user (kbuf->f_ffree, &ubuf->f_ffree) || __put_user (kbuf->f_namelen, &ubuf->f_namelen) || __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) || - __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1])) + __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) || + __put_user (0, &ubuf->f_spare[0]) || + __put_user (0, &ubuf->f_spare[1]) || + __put_user (0, &ubuf->f_spare[2]) || + __put_user (0, &ubuf->f_spare[3]) || + __put_user (0, &ubuf->f_spare[4]) || + __put_user (0, &ubuf->f_spare[5])) return -EFAULT; return 0; } @@ -488,10 +537,15 @@ int ret; struct statfs s; mm_segment_t old_fs = get_fs(); + const char *name; + name = getname(path); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs (KERNEL_DS); - ret = sys_statfs((const char *)path, &s); + ret = sys_statfs(name, &s); set_fs (old_fs); + putname(name); if (put_statfs(buf, &s)) return -EFAULT; return ret; @@ -845,6 +899,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 +910,6 @@ * long-words. */ ret = -ENOMEM; - size = FDS_BYTES(n); bits = kmalloc(6 * size, GFP_KERNEL); if (!bits) goto out_nofds; @@ -925,11 +979,6 @@ (struct timeval32 *)A(a.tvp)); } -struct timespec32 { - int tv_sec; - int tv_nsec; -}; - extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp); asmlinkage long @@ -1062,8 +1111,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 +1129,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 +1152,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)) @@ -1229,7 +1286,6 @@ return sys32_wait4(pid, stat_addr, options, NULL); } - extern asmlinkage long sys_getrusage(int who, struct rusage *ru); @@ -1400,8 +1456,12 @@ asmlinkage long sys32_ni_syscall(int call) { + /* Disable for now because the emulation should be pretty complete + and we miss some syscalls from 2.6. */ +#if 0 printk(KERN_INFO "IA32 syscall %d from %s not implemented\n", call, current->comm); +#endif return -ENOSYS; } @@ -1494,7 +1554,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); @@ -1505,10 +1569,30 @@ struct sysinfo s; int ret; mm_segment_t old_fs = get_fs (); + int bitcount = 0; 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 (verify_area(VERIFY_WRITE, info, sizeof(struct sysinfo32)) || __put_user (s.uptime, &info->uptime) || __put_user (s.loads[0], &info->loads[0]) || @@ -1520,7 +1604,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; } @@ -1715,7 +1802,7 @@ return -EFAULT; } set_fs (KERNEL_DS); - ret = sys_rt_sigtimedwait(&s, &info, &t, sigsetsize); + ret = sys_rt_sigtimedwait(&s, &info, uts ? &t : NULL, sigsetsize); set_fs (old_fs); if (ret >= 0 && uinfo) { if (copy_to_user (uinfo, siginfo64to32(&info32, &info), @@ -2519,17 +2606,422 @@ } #endif -long sys32_module_warning(void) +#ifdef CONFIG_MODULES + +extern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size); + +asmlinkage unsigned long sys32_create_module(const char *name_user, __kernel_size_t32 size) { - static long warn_time = -(60*HZ); - if (time_before(warn_time + 60*HZ,jiffies) && strcmp(current->comm,"klogd")) { - printk(KERN_INFO "%s: 32bit modutils not supported on 64bit kernel\n", - current->comm); - warn_time = jiffies; + return sys_create_module(name_user, (size_t)size); +} + +extern asmlinkage int sys_init_module(const char *name_user, struct module *mod_user); + +/* Hey, when you're trying to init module, take time and prepare us a nice 64bit + * module structure, even if from 32bit modutils... Why to pollute kernel... :)) + */ +asmlinkage int sys32_init_module(const char *name_user, struct module *mod_user) +{ + return sys_init_module(name_user, mod_user); +} + +extern asmlinkage int sys_delete_module(const char *name_user); + +asmlinkage int sys32_delete_module(const char *name_user) +{ + return sys_delete_module(name_user); +} + +struct module_info32 { + u32 addr; + u32 size; + u32 flags; + s32 usecount; +}; + +/* Query various bits about modules. */ + +static inline long +get_mod_name(const char *user_name, char **buf) +{ + unsigned long page; + long retval; + + if ((unsigned long)user_name >= TASK_SIZE + && !segment_eq(get_fs (), KERNEL_DS)) + return -EFAULT; + + page = __get_free_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + + retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE); + if (retval > 0) { + if (retval < PAGE_SIZE) { + *buf = (char *)page; + return retval; } - return -ENOSYS ; + retval = -ENAMETOOLONG; + } else if (!retval) + retval = -EINVAL; + + free_page(page); + return retval; +} + +static inline void +put_mod_name(char *buf) +{ + free_page((unsigned long)buf); } +static __inline__ struct module *find_module(const char *name) +{ + struct module *mod; + + for (mod = module_list; mod ; mod = mod->next) { + if (mod->flags & MOD_DELETED) + continue; + if (!strcmp(mod->name, name)) + break; + } + + return mod; +} + +static int +qm_modules(char *buf, size_t bufsize, __kernel_size_t32 *ret) +{ + struct module *mod; + size_t nmod, space, len; + + nmod = space = 0; + + for (mod = module_list; mod->next != NULL; mod = mod->next, ++nmod) { + len = strlen(mod->name)+1; + if (len > bufsize) + goto calc_space_needed; + if (copy_to_user(buf, mod->name, len)) + return -EFAULT; + buf += len; + bufsize -= len; + space += len; + } + + if (put_user(nmod, ret)) + return -EFAULT; + else + return 0; + +calc_space_needed: + space += len; + while ((mod = mod->next)->next != NULL) + space += strlen(mod->name)+1; + + if (put_user(space, ret)) + return -EFAULT; + else + return -ENOSPC; +} + +static int +qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret) +{ + size_t i, space, len; + + if (mod->next == NULL) + return -EINVAL; + if (!MOD_CAN_QUERY(mod)) + return put_user(0, ret); + + space = 0; + for (i = 0; i < mod->ndeps; ++i) { + const char *dep_name = mod->deps[i].dep->name; + + len = strlen(dep_name)+1; + if (len > bufsize) + goto calc_space_needed; + if (copy_to_user(buf, dep_name, len)) + return -EFAULT; + buf += len; + bufsize -= len; + space += len; + } + + return put_user(i, ret); + +calc_space_needed: + space += len; + while (++i < mod->ndeps) + space += strlen(mod->deps[i].dep->name)+1; + + if (put_user(space, ret)) + return -EFAULT; + else + return -ENOSPC; +} + +static int +qm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret) +{ + size_t nrefs, space, len; + struct module_ref *ref; + + if (mod->next == NULL) + return -EINVAL; + if (!MOD_CAN_QUERY(mod)) + if (put_user(0, ret)) + return -EFAULT; + else + return 0; + + space = 0; + for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) { + const char *ref_name = ref->ref->name; + + len = strlen(ref_name)+1; + if (len > bufsize) + goto calc_space_needed; + if (copy_to_user(buf, ref_name, len)) + return -EFAULT; + buf += len; + bufsize -= len; + space += len; + } + + if (put_user(nrefs, ret)) + return -EFAULT; + else + return 0; + +calc_space_needed: + space += len; + while ((ref = ref->next_ref) != NULL) + space += strlen(ref->ref->name)+1; + + if (put_user(space, ret)) + return -EFAULT; + else + return -ENOSPC; +} + +static inline int +qm_symbols(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret) +{ + size_t i, space, len; + struct module_symbol *s; + char *strings; + unsigned *vals; + + if (!MOD_CAN_QUERY(mod)) + if (put_user(0, ret)) + return -EFAULT; + else + return 0; + + space = mod->nsyms * 2*sizeof(u32); + + i = len = 0; + s = mod->syms; + + if (space > bufsize) + goto calc_space_needed; + + if (!access_ok(VERIFY_WRITE, buf, space)) + return -EFAULT; + + bufsize -= space; + vals = (unsigned *)buf; + strings = buf+space; + + for (; i < mod->nsyms ; ++i, ++s, vals += 2) { + len = strlen(s->name)+1; + if (len > bufsize) + goto calc_space_needed; + + if (copy_to_user(strings, s->name, len) + || __put_user(s->value, vals+0) + || __put_user(space, vals+1)) + return -EFAULT; + + strings += len; + bufsize -= len; + space += len; + } + + if (put_user(i, ret)) + return -EFAULT; + else + return 0; + +calc_space_needed: + for (; i < mod->nsyms; ++i, ++s) + space += strlen(s->name)+1; + + if (put_user(space, ret)) + return -EFAULT; + else + return -ENOSPC; +} + +static inline int +qm_info(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret) +{ + int error = 0; + + if (mod->next == NULL) + return -EINVAL; + + if (sizeof(struct module_info32) <= bufsize) { + struct module_info32 info; + info.addr = (unsigned long)mod; + info.size = mod->size; + info.flags = mod->flags; + info.usecount = + ((mod_member_present(mod, can_unload) + && mod->can_unload) + ? -1 : atomic_read(&mod->uc.usecount)); + + if (copy_to_user(buf, &info, sizeof(struct module_info32))) + return -EFAULT; + } else + error = -ENOSPC; + + if (put_user(sizeof(struct module_info32), ret)) + return -EFAULT; + + return error; +} + +asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kernel_size_t32 bufsize, u32 ret) +{ + struct module *mod; + int err; + + lock_kernel(); + if (name_user == 0) { + /* This finds "kernel_module" which is not exported. */ + for(mod = module_list; mod->next != NULL; mod = mod->next) + ; + } else { + long namelen; + char *name; + + if ((namelen = get_mod_name(name_user, &name)) < 0) { + err = namelen; + goto out; + } + err = -ENOENT; + if (namelen == 0) { + /* This finds "kernel_module" which is not exported. */ + for(mod = module_list; mod->next != NULL; mod = mod->next) + ; + } else if ((mod = find_module(name)) == NULL) { + put_mod_name(name); + goto out; + } + put_mod_name(name); + } + + switch (which) + { + case 0: + err = 0; + break; + case QM_MODULES: + err = qm_modules(buf, bufsize, (__kernel_size_t32 *)AA(ret)); + break; + case QM_DEPS: + err = qm_deps(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret)); + break; + case QM_REFS: + err = qm_refs(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret)); + break; + case QM_SYMBOLS: + err = qm_symbols(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret)); + break; + case QM_INFO: + err = qm_info(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret)); + break; + default: + err = -EINVAL; + break; + } +out: + unlock_kernel(); + return err; +} + +struct kernel_sym32 { + u32 value; + char name[60]; +}; + +extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table); + +asmlinkage int sys32_get_kernel_syms(struct kernel_sym32 *table) +{ + int len, i; + struct kernel_sym *tbl; + mm_segment_t old_fs; + + len = sys_get_kernel_syms(NULL); + if (!table) return len; + tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL); + if (!tbl) return -ENOMEM; + old_fs = get_fs(); + set_fs (KERNEL_DS); + sys_get_kernel_syms(tbl); + set_fs (old_fs); + for (i = 0; i < len; i++, table++) { + if (put_user (tbl[i].value, &table->value) || + copy_to_user (table->name, tbl[i].name, 60)) + break; + } + kfree (tbl); + return i; +} + +#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 int +sys32_get_kernel_syms(struct kernel_sym *table) +{ + return -ENOSYS; +} + +#endif /* CONFIG_MODULES */ + long sys32_vm86_warning(void) { static long warn_time = -(60*HZ); @@ -2550,7 +3042,7 @@ static int __init ia32_init (void) { - printk("IA32 emulation $Id: sys_ia32.c,v 1.1 2004/07/22 19:49:26 joff Exp $\n"); + printk("IA32 emulation $Id: sys_ia32.c,v 1.2 2004/08/04 01:26:19 joff 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); Index: arch/x86_64/kernel/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/Makefile 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/Makefile 4 Aug 2004 01:26:19 -0000 1.2 @@ -14,13 +14,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 swiotlb.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 @@ -34,9 +33,13 @@ obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o +obj-$(CONFIG_SWIOTLB) += swiotlb.o obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o obj-$(CONFIG_MCE) += bluesmoke.o +obj-$(CONFIG_ACPI_BOOT) += acpi.o +obj-$(CONFIG_ACPI_SLEEP) += acpi_wakeup.o suspend.o + include $(TOPDIR)/Rules.make Index: arch/x86_64/kernel/acpitable.c =================================================================== RCS file: arch/x86_64/kernel/acpitable.c diff -N arch/x86_64/kernel/acpitable.c --- arch/x86_64/kernel/acpitable.c 22 Jul 2004 19:49:26 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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"); -} Index: arch/x86_64/kernel/aperture.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/aperture.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/aperture.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/aperture.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -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.1 2004/07/22 19:49:26 joff Exp $ + * $Id: aperture.c,v 1.2 2004/08/04 01:26:19 joff Exp $ */ #include #include @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include #include @@ -25,6 +27,8 @@ int fallback_aper_order __initdata = 1; /* 64MB */ int fallback_aper_force __initdata = 0; +int iommu_aperture; + extern int no_iommu, force_mmu; /* This code runs before the PCI subsystem is initialized, so just @@ -64,16 +68,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"); @@ -82,20 +200,20 @@ if (read_pci_config(0, num, 3, 0x00) != NB_ID_3) continue; + iommu_aperture = 1; + aper_order = (read_pci_config(0, num, 3, 0x90) >> 1) & 7; aper_size = (32 * 1024 * 1024) << aper_order; 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 +222,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 +263,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); } } Index: arch/x86_64/kernel/apic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/apic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/apic.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/apic.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -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); + Index: arch/x86_64/kernel/bluesmoke.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/bluesmoke.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/bluesmoke.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/bluesmoke.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -25,14 +25,6 @@ static int banks; static unsigned long ignored_banks, disabled_banks; -/* Machine Check on everything dubious. This is a good setting - for device driver testing. */ -#define K8_DRIVER_DEBUG ((1<<13)-1) -/* Report RAM errors and Hyper Transport Problems, but ignore Device - aborts and GART errors. */ -#define K8_NORMAL_OP 0xff -static u32 k8_nb_flags __initdata = K8_NORMAL_OP; - static void generic_machine_check(struct pt_regs * regs, long error_code) { int recover=1; @@ -125,7 +117,68 @@ return NULL; } -static void check_k8_nb(void) +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(int header) { struct pci_dev *nb; nb = find_k8_nb(); @@ -137,22 +190,52 @@ pci_read_config_dword(nb, 0x4c, &statushigh); if (!(statushigh & (1<<31))) return; - printk(KERN_ERR "Northbridge status %08x%08x\n", + if (header) + printk(KERN_ERR "CPU %d: Silent Northbridge MCE\n", smp_processor_id()); + + 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"); + + printk(KERN_ERR " Error %s\n", extendederr[(statuslow >> 16) & 0xf]); + + unsigned short errcode = statuslow & 0xffff; + switch ((statuslow >> 16) & 0xF) { + case 5: + printk(KERN_ERR " GART TLB error %s %s\n", + transaction[(errcode >> 2) & 3], + cachelevel[errcode & 3]); + break; + case 8: + printk(KERN_ERR " ECC error syndrome %x\n", + (((statuslow >> 24) & 0xff) << 8) | ((statushigh >> 15) & 0x7f)); + /*FALL THROUGH*/ + default: + printk(KERN_ERR " bus error %s, %s\n %s\n %s, %s\n", + partproc[(errcode >> 9) & 0x3], + timeout[(errcode >> 8) & 1], + memtrans[(errcode >> 4) & 0xf], + memoryio[(errcode >> 2) & 0x3], + cachelevel[(errcode & 0x3)]); + /* should only print when it was a HyperTransport related error. */ + printk(KERN_ERR " link number %x\n", (statushigh >> 4) & 3); + break; + } + + + int i; + for (i = 0; i < 32; i++) { + if (i == 26 || i == 28) + continue; + if (highbits[i] && (statushigh & (1<rip, regs->rsp); - others: generic_machine_check(regs, error_code); } @@ -245,7 +327,6 @@ { u64 cap; int i; - struct pci_dev *nb; if (!test_bit(X86_FEATURE_MCE, &c->x86_capability) || !test_bit(X86_FEATURE_MCA, &c->x86_capability)) @@ -260,17 +341,8 @@ wrmsrl(MSR_IA32_MC0_STATUS+4*i,0); } - nb = find_k8_nb(); - if (nb != NULL) { - u32 reg, reg2; - pci_read_config_dword(nb, 0x40, ®); - pci_write_config_dword(nb, 0x40, k8_nb_flags); - pci_read_config_dword(nb, 0x44, ®2); - pci_write_config_dword(nb, 0x44, reg2); - printk(KERN_INFO "Machine Check for K8 Northbridge %d enabled (%x,%x)\n", - nb->devfn, reg, reg2); - ignored_banks |= (1UL<<4); - } + if (cap & (1<<8)) + wrmsrl(MSR_IA32_MCG_CTL, 0xffffffffffffffffULL); set_in_cr4(X86_CR4_MCE); @@ -368,7 +440,6 @@ mce=nok8 disable k8 specific features mce=disable disable bank NUMBER mce=enable enable bank number - mce=device Enable device driver test reporting in NB mce=NUMBER mcheck timer interval number seconds. Can be also comma separated in a single mce= */ static int __init mcheck_enable(char *str) @@ -385,8 +456,6 @@ disabled_banks |= ~(1< #include #include #include +#include #include #include #include #include #include +#include +#include #include +#include +#include extern unsigned long table_start, table_end; extern char _end[]; +#ifdef CONFIG_ACPI_BOOT +extern acpi_interrupt_flags acpi_sci_flags; +#endif + extern struct resource code_resource, data_resource, vram_resource; /* Check for some hardcoded bad areas that early boot is not allowed to touch */ @@ -488,7 +497,6 @@ mem_size = ALT_MEM_K; who = "BIOS-e801"; } - e820.nr_map = 0; add_memory_region(0, LOWMEMSIZE(), E820_RAM); add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM); @@ -537,8 +545,56 @@ else if (!memcmp(from,"iommu=",6)) { iommu_setup(from+6); } - #endif +#ifdef CONFIG_SMP + /* + * If the BIOS enumerates physical processors before logical, + * maxcpus=N at enumeration-time can be used to disable HT. + */ + else if (!memcmp(from, "maxcpus=", 8)) { + extern unsigned int max_cpus; + + max_cpus = simple_strtoul(from + 8, NULL, 0); + } +#endif + +#ifdef CONFIG_ACPI_BOOT + else if (!memcmp(from, "acpi=off", 8)) + disable_acpi(); + + /* acpi=strict disables out-of-spec workarounds */ + else if (!memcmp(from, "acpi=strict", 11)) { + acpi_strict = 1; + } + + else if (!memcmp(from, "pci=noacpi", 10)) { + acpi_noirq_set(); + } + + else if (!memcmp(from, "acpi_sci=edge", 13)) + acpi_sci_flags.trigger = 1; + else if (!memcmp(from, "acpi_sci=level", 14)) + acpi_sci_flags.trigger = 3; + else if (!memcmp(from, "acpi_sci=high", 13)) + acpi_sci_flags.polarity = 1; + else if (!memcmp(from, "acpi_sci=low", 12)) + acpi_sci_flags.polarity = 3; +#endif + else if (!memcmp(from,"maxcpus=0",9)) { + disable_ioapic_setup(); + apic_disabled = 1; + } + + else if (!memcmp(from, "noapic", 6)) + disable_ioapic_setup(); + else if (!memcmp(from, "nolocalapic", 11) || !memcmp(from,"nolapic",7)) + apic_disabled = 1; + else if (!memcmp(from,"apic",4)) { + extern int ioapic_force; + ioapic_force = 1; + skip_ioapic_setup = 0; + } + next: c = *(from++); if (!c) Index: arch/x86_64/kernel/entry.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/entry.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/entry.S 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/entry.S 4 Aug 2004 01:26:19 -0000 1.2 @@ -5,7 +5,7 @@ * Copyright (C) 2000, 2001, 2002 Andi Kleen SuSE Labs * Copyright (C) 2000 Pavel Machek * - * $Id: entry.S,v 1.1 2004/07/22 19:49:26 joff Exp $ + * $Id: entry.S,v 1.2 2004/08/04 01:26:19 joff Exp $ */ /* @@ -351,6 +351,7 @@ .section .fixup,"ax" /* force a signal here? this matches i386 behaviour */ bad_iret: + /* runs with kernelgs again */ movq $-9999,%rdi /* better code? */ jmp do_exit .previous @@ -504,7 +505,12 @@ incl %r15d /* There are two places in the kernel that can potentially fault with usergs. Handle them here. */ - cmpq $iret_label,RIP(%rsp) + leaq iret_label(%rip),%rdx + cmpq %rdx,RIP(%rsp) + je 1f + /* check truncated address too. This works around a CPU issue */ + movl %edx,%edx /* zero extend */ + cmpq %rdx,RIP(%rsp) je 1f cmpq $gs_change,RIP(%rsp) jne error_action Index: arch/x86_64/kernel/head.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/head.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/head.S 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/head.S 4 Aug 2004 01:26:19 -0000 1.2 @@ -6,7 +6,7 @@ * Copyright (C) 2000 Karsten Keil * Copyright (C) 2001,2002 Andi Kleen * - * $Id: head.S,v 1.1 2004/07/22 19:49:26 joff Exp $ + * $Id: head.S,v 1.2 2004/08/04 01:26:19 joff Exp $ */ @@ -39,6 +39,9 @@ movl %ebx,%ebp /* Save trampoline flag */ + movl $__KERNEL_DS,%eax + movl %eax,%ds + /* First check if extended functions are implemented */ movl $0x80000000, %eax cpuid @@ -119,25 +122,11 @@ movl $0x100F00, %eax lgdt (%eax) +second: movl $0x100F10, %eax /* Finally jump in 64bit mode */ ljmp *(%eax) -second: - /* abuse syscall to get into 64bit mode. this way we don't need - a working low identity mapping just for the short 32bit roundtrip. - XXX kludge. this should not be needed. */ - movl $MSR_STAR,%ecx - xorl %eax,%eax - movl $(__USER32_CS<<16)|__KERNEL_CS,%edx - wrmsr - - movl $MSR_CSTAR,%ecx - movl $0xffffffff,%edx - movl $0x80100100,%eax # reach_long64 absolute - wrmsr - syscall - .code64 .org 0x100 reach_long64: @@ -198,6 +187,7 @@ 1: jmp 1b + .globl pGDT32 .org 0xf00 pGDT32: .word gdt32_end-gdt_table32 @@ -311,11 +301,22 @@ ENTRY(level3_physmem_pgt) .quad 0x0000000000105007 /* -> level2_kernel_pgt (so that __va works even before pagetable_init) */ -.org 0xb000 + .org 0xb000 +#ifdef CONFIG_ACPI_SLEEP +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 */ +#endif + .data .globl SYMBOL_NAME(gdt) + .globl pGDT64 .word 0 .align 16 .word 0 @@ -340,7 +341,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 0x008f9a000000ffff /* __KERNEL_COMPAT32_CS */ .quad 0x00af9a000000ffff /* __KERNEL_CS */ .quad 0x00cf92000000ffff /* __KERNEL_DS */ .quad 0x00cffe000000ffff /* __USER32_CS */ Index: arch/x86_64/kernel/head64.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/head64.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/head64.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/head64.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -3,7 +3,7 @@ * * Copyright (C) 2000 Andrea Arcangeli SuSE * - * $Id: head64.c,v 1.1 2004/07/22 19:49:26 joff Exp $ + * $Id: head64.c,v 1.2 2004/08/04 01:26:19 joff Exp $ */ #include Index: arch/x86_64/kernel/io_apic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/io_apic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/io_apic.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/io_apic.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -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 @@ -163,6 +165,14 @@ struct IO_APIC_route_entry entry; unsigned long flags; + /* Check delivery_mode to be sure we're not clearing an SMI pin */ + spin_lock_irqsave(&ioapic_lock, flags); + *(((int*)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin); + *(((int*)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin); + spin_unlock_irqrestore(&ioapic_lock, flags); + if (entry.delivery_mode == dest_SMI) + return; + /* * Disable it in the IO-APIC irq-routing table: */ @@ -192,9 +202,11 @@ int pirq_entries [MAX_PIRQS]; int pirqs_enabled; int skip_ioapic_setup; +int ioapic_force; static int __init noioapic_setup(char *str) { + ioapic_force = 1; skip_ioapic_setup = 1; return 1; } @@ -203,12 +215,66 @@ static int __init ioapic_setup(char *str) { + ioapic_force = 1; skip_ioapic_setup = 0; return 1; } __setup("apic", ioapic_setup); +#ifndef CONFIG_SMP +#include +#include +#include + +/* Temporary Hack. Nvidia and VIA boards currently only work with IO-APIC + off. Check for an Nvidia or VIA PCI bridge and turn it off. + Use pci direct infrastructure because this runs before the PCI subsystem. + + Can be overwritten with "apic" */ +void __init check_ioapic(void) +{ + int num,slot,func; + if (ioapic_force) + return; + + /* 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; + u32 vendor; + class = read_pci_config(num,slot,func, + PCI_CLASS_REVISION); + if (class == 0xffffffff) + break; + + if ((class >> 16) != PCI_CLASS_BRIDGE_PCI) + continue; + + vendor = read_pci_config(num, slot, func, + PCI_VENDOR_ID); + vendor &= 0xffff; + switch (vendor) { + case PCI_VENDOR_ID_NVIDIA: + case PCI_VENDOR_ID_VIA: + printk(KERN_INFO + "PCI bridge %02x:%02x from %x found. Setting \"noapic\". Overwrite with \"apic\"\n", + num,slot,vendor); + skip_ioapic_setup = 1; + return; + } + + /* No multi-function device? */ + u8 type = read_pci_config_byte(num,slot,func, + PCI_HEADER_TYPE); + if (!(type & 0x80)) + break; + } + } + } +} +#endif static int __init ioapic_pirq_setup(char *str) { @@ -710,7 +776,7 @@ entry.vector = vector; /* - * The timer IRQ doesnt have to know that behind the + * The timer IRQ doesn't have to know that behind the * scene we have a 8259A-master in AEOI mode ... */ irq_desc[0].handler = &ioapic_edge_irq_type; @@ -1582,7 +1648,7 @@ printk(" failed.\n"); if (nmi_watchdog) { - printk(KERN_WARNING "timer doesnt work through the IO-APIC - disabling NMI Watchdog!\n"); + printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n"); nmi_watchdog = 0; } @@ -1641,13 +1707,177 @@ 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(); + if (!acpi_ioapic) + setup_ioapic_ids_from_mpc(); sync_Arb_IDs(); setup_IO_APIC_irqs(); init_IO_APIC_traps(); check_timer(); - print_IO_APIC(); + if (!acpi_ioapic) + 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, 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; + + /* + * IRQs < 16 are already in the irq_2_pin[] map + */ + if (irq >= 16) + 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 entry.vector; +} + +#endif /*CONFIG_ACPI_BOOT*/ Index: arch/x86_64/kernel/ioport.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/ioport.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/ioport.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/ioport.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -19,35 +19,13 @@ /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value) { - unsigned long mask; - unsigned long *bitmap_base = bitmap + base / sizeof(long); - unsigned low_index = base & (BITS_PER_LONG - 1); - int length = low_index + extent; - - if (low_index != 0) { - mask = (~0UL << low_index); - if (length < 64) - mask &= ~(~0UL << length); + int i; if (new_value) - *bitmap_base++ |= mask; + for (i = base; i < base + extent; i++) + __set_bit(i, bitmap); else - *bitmap_base++ &= ~mask; - length -= 64; - } - - mask = (new_value ? ~0UL : 0UL); - while (length >= 64) { - *bitmap_base++ = mask; - length -= 64; - } - - if (length > 0) { - mask = ~(~0UL << length); - if (new_value) - *bitmap_base++ |= mask; - else - *bitmap_base++ &= ~mask; - } + for (i = base; i < base + extent; i++) + clear_bit(i, bitmap); } /* Index: arch/x86_64/kernel/irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/irq.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/irq.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -154,57 +155,56 @@ * Generic, controller-independent functions: */ -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { int i, j; struct irqaction * action; - char *p = buf; - p += sprintf(p, " "); + seq_printf(p, " "); for (j=0; jtypename); - p += sprintf(p, " %s", action->name); + seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) - p += sprintf(p, ", %s", action->name); - *p++ = '\n'; + seq_printf(p, ", %s", action->name); + seq_putc(p,'\n'); } - p += sprintf(p, "NMI: "); + seq_printf(p, "NMI: "); for (j = 0; j < smp_num_cpus; j++) - p += sprintf(p, "%10u ", + seq_printf(p, "%10u ", nmi_count(cpu_logical_map(j))); - p += sprintf(p, "\n"); + seq_printf(p, "\n"); #if CONFIG_X86_LOCAL_APIC - p += sprintf(p, "LOC: "); + seq_printf(p, "LOC: "); for (j = 0; j < smp_num_cpus; j++) - p += sprintf(p, "%10u ", + seq_printf(p, "%10u ", apic_timer_irqs[cpu_logical_map(j)]); - p += sprintf(p, "\n"); + seq_printf(p, "\n"); #endif - p += sprintf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); + seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); #ifdef CONFIG_X86_IO_APIC #ifdef APIC_MISMATCH_DEBUG - p += sprintf(p, "MIS: %10u\n", atomic_read(&irq_mis_count)); + seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count)); #endif #endif - return p - buf; -} + return 0; +} /* * Global interrupt locks for SMP. Allow interrupts to come in on any @@ -1051,7 +1051,7 @@ if (!shared) { desc->depth = 0; - desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING); + desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS); desc->handler->startup(irq); } spin_unlock_irqrestore(&desc->lock,flags); Index: arch/x86_64/kernel/mpparse.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/mpparse.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/mpparse.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/mpparse.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -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,14 +25,19 @@ #include #include +#include #include #include #include #include #include +#include /* Have we found an MP table */ int smp_found_config = 0; +#ifdef CONFIG_SMP +extern unsigned int max_cpus; +#endif /* * Various Linux-internal data structures created from the @@ -107,6 +114,20 @@ Dprintk(" Bootup CPU\n"); boot_cpu_id = m->mpc_apicid; } + +#ifdef CONFIG_SMP + if (num_processors >= NR_CPUS) { + printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached." + " Processor ignored.\n", NR_CPUS); + return; + } + if (num_processors >= max_cpus) { + printk(KERN_WARNING "WARNING: maxcpus limit of %i reached." + " Processor ignored.\n", max_cpus); + return; + } +#endif + num_processors++; if (m->mpc_apicid > MAX_APICS) { @@ -135,9 +156,12 @@ str[6] = 0; Dprintk("Bus #%d is %s\n", m->mpc_busid, str); - if (m->mpc_busid >= MAX_MP_BUSSES) { +#if MAX_MP_BUSSES < 256 + if ((long)m->mpc_busid >= MAX_MP_BUSSES) { printk(KERN_ERR "MAX_MP_BUSSES ERROR mpc_busid %d, max %d\n", m->mpc_busid, MAX_MP_BUSSES); - } else if (strncmp(str, "ISA", 3) == 0) { + } else +#endif + if (strncmp(str, "ISA", 3) == 0) { mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; } else if (strncmp(str, "EISA", 4) == 0) { mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA; @@ -249,7 +273,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 +289,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 +505,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 +657,344 @@ #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); +} + +#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%x, " + "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) && (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_srcbus == intsrc.mpc_srcbus) + && (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 = mp_INT; + 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 + +extern FADT_DESCRIPTOR acpi_fadt; + +#endif /*CONFIG_ACPI_HT_ONLY*/ + +int acpi_tolerant; + +#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; + int edge_level = 0; + int active_high_low = 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, &edge_level, &active_high_low); + if (!irq) + continue; + } else { + edge_level = 1; + active_high_low = 1; + irq = entry->link.index; + } + + irq = entry->link.index; + + /* Don't set up the ACPI SCI because it's already set up */ + if (acpi_fadt.sci_int == irq) { + entry->irq = irq; /*we still need to set entry's 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 -> 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); + } + + print_IO_APIC(); + + return; +} + +#endif /*CONFIG_ACPI_PCI*/ + +#endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/ + +#endif /*CONFIG_ACPI_BOOT*/ Index: arch/x86_64/kernel/msr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/msr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/msr.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/msr.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -1,4 +1,4 @@ -#ident "$Id: msr.c,v 1.1 2004/07/22 19:49:26 joff Exp $" +#ident "$Id: msr.c,v 1.2 2004/08/04 01:26:19 joff Exp $" /* ----------------------------------------------------------------------- * * * Copyright 2000 H. Peter Anvin - All Rights Reserved Index: arch/x86_64/kernel/mtrr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/mtrr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/mtrr.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/mtrr.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -70,6 +70,9 @@ #define MTRR_VERSION "2.02 (20020716)" +#define MTRR_BEG_BIT 12 +#define MTRR_END_BIT 7 + #undef Dprintk #define Dprintk(...) @@ -141,11 +144,14 @@ write_cr0(cr0); wbinvd(); - /* Disable MTRRs, and set the default type to uncached */ rdmsr(MSR_MTRRdefType, ctxt->deftype_lo, ctxt->deftype_hi); - wrmsr(MSR_MTRRdefType, ctxt->deftype_lo & 0xf300UL, ctxt->deftype_hi); } +static void set_mtrr_disable(struct set_mtrr_context *ctxt) +{ + /* Disable MTRRs, and set the default type to uncached */ + wrmsr(MSR_MTRRdefType, ctxt->deftype_lo & 0xf300UL, ctxt->deftype_hi); +} /* Restore the processor after a set_mtrr_prepare */ static void set_mtrr_done (struct set_mtrr_context *ctxt) @@ -192,8 +198,9 @@ static void get_mtrr (unsigned int reg, u64 *base, u32 *size, mtrr_type * type) { - u32 mask_lo, mask_hi, base_lo, base_hi; - u64 newsize; + u32 count, tmp, mask_lo, mask_hi; + int i; + u32 base_lo, base_hi; rdmsr (MSR_MTRRphysMask(reg), mask_lo, mask_hi); if ((mask_lo & 0x800) == 0) { @@ -206,10 +213,16 @@ rdmsr (MSR_MTRRphysBase(reg), base_lo, base_hi); - /* Work out the shifted address mask. */ - newsize = (u64) mask_hi << 32 | (mask_lo & ~0x800); - newsize = ~newsize+1; - *size = (u32) newsize >> PAGE_SHIFT; + count = 0; + tmp = mask_lo >> MTRR_BEG_BIT; + for (i = MTRR_BEG_BIT; i <= 31; i++, tmp = tmp >> 1) + count = (count << (~tmp & 1)) | (~tmp & 1); + + tmp = mask_hi; + for (i = 0; i <= MTRR_END_BIT; i++, tmp = tmp >> 1) + count = (count << (~tmp & 1)) | (~tmp & 1); + + *size = (count+1); *base = base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT; *type = base_lo & 0xff; } @@ -232,8 +245,10 @@ u64 base64; u64 size64; - if (do_safe) + if (do_safe) { set_mtrr_prepare (&ctxt); + set_mtrr_disable (&ctxt); + } if (size == 0) { /* The invalid bit is kept in the mask, so we simply clear the @@ -243,7 +258,7 @@ base64 = (base << PAGE_SHIFT) & size_and_mask; wrmsr (MSR_MTRRphysBase(reg), base64 | type, base64 >> 32); - size64 = ~((size << PAGE_SHIFT) - 1); + size64 = ~(((u64)size << PAGE_SHIFT) - 1); size64 = size64 & size_and_mask; wrmsr (MSR_MTRRphysMask(reg), (u32) (size64 | 0x800), (u32) (size64 >> 32)); } @@ -420,6 +435,7 @@ static atomic_t undone_count; +static volatile int wait_barrier_mtrr_disable = FALSE; static volatile int wait_barrier_execute = FALSE; static volatile int wait_barrier_cache_enable = FALSE; @@ -441,8 +457,18 @@ set_mtrr_prepare (&ctxt); /* Notify master that I've flushed and disabled my cache */ atomic_dec (&undone_count); - while (wait_barrier_execute) + + while (wait_barrier_mtrr_disable) { + rep_nop(); barrier (); + } + set_mtrr_disable (&ctxt); + /* wait again for disable confirmation*/ + atomic_dec (&undone_count); + while (wait_barrier_execute) { + rep_nop(); + barrier(); + } /* The master has cleared me to execute */ set_mtrr_up (data->smp_reg, data->smp_base, data->smp_size, @@ -452,8 +478,10 @@ atomic_dec (&undone_count); /* Wait for master to clear me to enable cache and return */ - while (wait_barrier_cache_enable) + while (wait_barrier_cache_enable) { + rep_nop(); barrier (); + } set_mtrr_done (&ctxt); } @@ -469,6 +497,7 @@ data.smp_type = type; wait_barrier_execute = TRUE; wait_barrier_cache_enable = TRUE; + wait_barrier_mtrr_disable = TRUE; atomic_set (&undone_count, smp_num_cpus - 1); /* Start the ball rolling on other CPUs */ @@ -477,10 +506,21 @@ /* Flush and disable the local CPU's cache */ set_mtrr_prepare (&ctxt); + while (atomic_read (&undone_count) > 0) { + rep_nop(); + barrier(); + } + + /* Set up for completion wait and then release other CPUs to change MTRRs*/ + atomic_set (&undone_count, smp_num_cpus - 1); + wait_barrier_mtrr_disable = FALSE; + set_mtrr_disable (&ctxt); /* Wait for all other CPUs to flush and disable their caches */ - while (atomic_read (&undone_count) > 0) + while (atomic_read (&undone_count) > 0) { + rep_nop (); barrier (); + } /* Set up for completion wait and then release other CPUs to change MTRRs */ atomic_set (&undone_count, smp_num_cpus - 1); @@ -488,8 +528,10 @@ set_mtrr_up (reg, base, size, type, FALSE); /* Now wait for other CPUs to complete the function */ - while (atomic_read (&undone_count) > 0) + while (atomic_read (&undone_count) > 0) { + rep_nop(); barrier (); + } /* Now all CPUs should have finished the function. Release the barrier to allow them to re-enable their caches and return from their interrupt, @@ -1272,6 +1314,7 @@ for this CPU while the MTRRs are changed, but changing this requires more invasive changes to the way the kernel boots */ set_mtrr_prepare (&ctxt); + set_mtrr_disable (&ctxt); mask = set_mtrr_state (&smp_mtrr_state, &ctxt); set_mtrr_done (&ctxt); Index: arch/x86_64/kernel/nmi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/nmi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/nmi.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/nmi.c 4 Aug 2004 01:26:19 -0000 1.2 @@ -30,9 +30,17 @@ unsigned int nmi_watchdog = NMI_LOCAL_APIC; static unsigned int nmi_hz = HZ; unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ +int panic_on_timeout; int nmi_watchdog_disabled; +/* Small problem with theaw events is that they stop ticking + when the CPU is idling. This means you get varying NMI watchdog + frequencies depending on the CPU load. + + I doubt it can be fixed because it's unlikely that the CPU does + performance counters while being in C* states. -AK */ + #define K7_EVNTSEL_ENABLE (1 << 22) #define K7_EVNTSEL_INT (1 << 20) #define K7_EVNTSEL_OS (1 << 17) @@ -121,6 +129,13 @@ { int nmi; + if (!strncmp(str,"panic",5)) { + panic_on_timeout = 1; + str = strchr(str, ','); + if (!str) + return 1; + ++str; + } get_option(&str, &nmi); if (nmi >= NMI_INVALID) @@ -207,6 +222,11 @@ { unsigned int evntsel; +#if 0 + /* No check, so can start with slow frequency */ + nmi_hz = 1; +#endif + nmi_perfctr_msr = MSR_K7_PERFCTR0; clear_msr_range(MSR_K7_EVNTSEL0, 4); @@ -380,6 +400,8 @@ bust_spinlocks(1); printk("NMI Watchdog detected LOCKUP on CPU%d, eip %16lx, registers:\n", cpu, regs->rip); show_registers(regs); + if (panic_on_timeout) + panic("NMI lockup"); printk("console shuts up ...\n"); console_silent(); spin_unlock(&nmi_print_lock); Index: arch/x86_64/kernel/pci-dma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/pci-dma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/pci-dma.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/pci-dma.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -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; } Index: arch/x86_64/kernel/pci-gart.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/pci-gart.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/pci-gart.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/pci-gart.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -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.1 2004/07/22 19:49:26 joff Exp $ + * $Id: pci-gart.c,v 1.2 2004/08/04 01:26:20 joff 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 @@ -57,6 +42,7 @@ #else int force_mmu = 0; #endif +int iommu_fullflush = 1; extern int fallback_aper_order; extern int fallback_aper_force; @@ -72,7 +58,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 +77,29 @@ 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; } + } + if (iommu_fullflush) + need_flush = 1; spin_unlock_irqrestore(&iommu_bitmap_lock, flags); return offset; } @@ -114,20 +109,42 @@ 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++) { + u32 w; + pci_write_config_dword(northbridges[i], 0x9c, + northbridge_flush_word[i] | 1); + do { + pci_read_config_dword(northbridges[i], 0x9c, &w); + } while (w & 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 +167,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 +217,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 +266,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 +301,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; @@ -296,6 +310,12 @@ BUG_ON(dir == PCI_DMA_NONE); +#ifdef CONFIG_SWIOTLB + if (swiotlb) + return swiotlb_map_single(dev,addr,size,dir); +#endif + + phys_mem = virt_to_phys(addr); if (!need_iommu(dev, phys_mem, size)) return phys_mem; @@ -318,18 +338,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 +357,22 @@ size_t size, int direction) { unsigned long iommu_page; - int i, npages; + int npages; + +#ifdef CONFIG_SWIOTLB + if (swiotlb) { + swiotlb_unmap_single(hwdev,dma_addr,size,direction); + return; + } +#endif + + if (dma_addr < iommu_bus_base + EMERGENCY_PAGES*PAGE_SIZE || - dma_addr > iommu_bus_base + iommu_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 +380,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 +467,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); @@ -462,6 +485,7 @@ nommu: /* XXX: reject 0xffffffff mask now in pci mapping functions */ + if (end_pfn >= 0xffffffff>>PAGE_SHIFT) printk(KERN_ERR "PCI-DMA: More than 4GB of RAM and no IOMMU\n" KERN_ERR "PCI-DMA: 32bit PCI IO may malfunction."); return -1; @@ -479,7 +503,14 @@ no_agp = no_agp || (agp_init() < 0) || (agp_copy_info(&info) < 0); #endif - if (no_iommu || (!force_mmu && end_pfn < 0xffffffff>>PAGE_SHIFT)) { + if (swiotlb) { + no_iommu = 1; + printk(KERN_INFO "PCI-DMA: Using SWIOTLB\n"); + return; + } + + + if (no_iommu || (!force_mmu && end_pfn < 0xffffffff>>PAGE_SHIFT) || !iommu_aperture) { printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n"); no_iommu = 1; return; @@ -534,7 +565,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 +598,10 @@ 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. + nofullflush use optimized IOMMU flushing (may break on some devices). + default off. */ __init int iommu_setup(char *opt) { @@ -560,12 +617,17 @@ force_mmu = 1; if (!memcmp(p,"noforce", 7)) force_mmu = 0; + if (!memcmp(p,"nofullflush", 11)) + iommu_fullflush = 0; if (!memcmp(p, "memaper", 7)) { fallback_aper_force = 1; p += 7; - if (*p == '=' && get_option(&p, &arg)) + if (*p == '=') { + ++p; + if (get_option(&p, &arg)) fallback_aper_order = arg; } + } #ifdef CONFIG_IOMMU_LEAK if (!memcmp(p,"leak", 4)) { leak_trace = 1; Index: arch/x86_64/kernel/pci-irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/pci-irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/pci-irq.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/pci-irq.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -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); Index: arch/x86_64/kernel/pci-pc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/pci-pc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/pci-pc.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/pci-pc.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -18,10 +18,12 @@ #include #include #include +#include #include #include #include +#include #include "pci-x86_64.h" @@ -31,6 +33,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 +53,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 +176,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 +384,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 +544,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 +588,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_disabled && !acpi_noirq && !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 @@ -454,6 +645,9 @@ } else if (!strncmp(str, "lastbus=", 8)) { pcibios_last_bus = simple_strtol(str+8, NULL, 0); return NULL; + } else if (!strncmp(str, "noacpi", 6)) { + acpi_noirq_set(); + return NULL; } return str; } @@ -469,6 +663,15 @@ if ((err = pcibios_enable_resources(dev, mask)) < 0) return err; + +#ifdef CONFIG_ACPI_PCI + if (!acpi_noirq && pci_using_acpi_prt) { + acpi_pci_irq_enable(dev); + return 0; + } +#endif + pcibios_enable_irq(dev); + return 0; } Index: arch/x86_64/kernel/pci-x86_64.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/pci-x86_64.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/pci-x86_64.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/pci-x86_64.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -294,6 +294,17 @@ } } +void __init pcibios_set_cacheline_size(void) +{ + struct cpuinfo_x86 *c = &boot_cpu_data; + + pci_cache_line_size = 32 >> 2; + if (c->x86 >= 6 && c->x86_vendor == X86_VENDOR_AMD) + pci_cache_line_size = 64 >> 2; /* K7 & K8 */ + else if (c->x86 > 6 && c->x86_vendor == X86_VENDOR_INTEL) + pci_cache_line_size = 128 >> 2; /* P4 */ +} + void __init pcibios_resource_survey(void) { DBG("PCI: Allocating resources\n"); Index: arch/x86_64/kernel/pci-x86_64.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/pci-x86_64.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/pci-x86_64.h 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/pci-x86_64.h 4 Aug 2004 01:26:20 -0000 1.2 @@ -27,8 +27,10 @@ /* pci-i386.c */ extern unsigned int pcibios_max_latency; +extern u8 pci_cache_line_size; void pcibios_resource_survey(void); +void pcibios_set_cacheline_size(void); int pcibios_enable_resources(struct pci_dev *, int mask); /* pci-pc.c */ Index: arch/x86_64/kernel/process.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/process.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/process.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/process.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -9,7 +9,7 @@ * X86-64 port * Andi Kleen. * - * $Id: process.c,v 1.1 2004/07/22 19:49:26 joff Exp $ + * $Id: process.c,v 1.2 2004/08/04 01:26:20 joff Exp $ */ /* @@ -54,6 +54,7 @@ #include #include #include +#include #include @@ -146,11 +147,57 @@ } } +/* + * This is a kind of hybrid between poll and halt idle routines. This uses new + * Monitor/Mwait instructions on P4 processors with PNI. We Monitor + * need_resched and go to optimized wait state through Mwait. + * Whenever someone changes need_resched, we would be woken up from Mwait + * (without an IPI). + */ +static void mwait_idle (void) +{ + int oldval; + + __sti(); + /* Setting need_resched to -1 skips sending IPI during idle resched */ + oldval = xchg(¤t->need_resched, -1); + if (!oldval) { + do { + __monitor((void *)¤t->need_resched, 0, 0); + if (current->need_resched != -1) + break; + __mwait(0, 0); + } while (current->need_resched == -1); + } +} + +int __init select_idle_routine(struct cpuinfo_x86 *c) +{ + if (cpu_has(c, X86_FEATURE_MWAIT)) { + printk("Monitor/Mwait feature present.\n"); + /* + * Take care of system with asymmetric CPUs. + * Use, mwait_idle only if all cpus support it. + * If not, we fallback to default_idle() + */ + if (!pm_idle) { + pm_idle = mwait_idle; + } + return 1; + } + pm_idle = default_idle; + return 1; +} + + static int __init idle_setup (char *str) { if (!strncmp(str, "poll", 4)) { printk("using polling idle threads.\n"); pm_idle = poll_idle; + } else if (!strncmp(str, "halt", 4)) { + printk("using halt in idle threads.\n"); + pm_idle = default_idle; } return 1; @@ -158,35 +205,38 @@ __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 struct { long x; } no_idt[3]; +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 reboot 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,10 +245,35 @@ } return 1; } - __setup("reboot=", reboot_setup); -static inline void kb_wait(void) +/* 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 void kb_wait(void) { int i; @@ -207,60 +282,77 @@ 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); } Index: arch/x86_64/kernel/setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/setup.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/setup.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -26,9 +26,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -46,6 +48,16 @@ #include #include +int acpi_disabled = 0; +#ifdef CONFIG_ACPI_BOOT +int acpi_noirq __initdata = 0; /* skip ACPI IRQ initialization */ +#endif + + +int swiotlb; + +extern int phys_proc_id[NR_CPUS]; + /* * Machine setup.. */ @@ -55,6 +67,7 @@ }; unsigned long mmu_cr4_features; +EXPORT_SYMBOL(mmu_cr4_features); /* For PCI or other memory-mapped resources */ unsigned long pci_mem_start = 0x10000000; @@ -219,6 +232,8 @@ e820_end_of_ram(); + check_efer(); + init_memory_mapping(); #ifdef CONFIG_BLK_DEV_INITRD @@ -271,6 +286,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 +305,17 @@ #endif paging_init(); +#if !defined(CONFIG_SMP) && defined(CONFIG_X86_IO_APIC) + extern void check_ioapic(void); + check_ioapic(); +#endif + +#ifdef CONFIG_ACPI_BOOT + /* + * Parse the ACPI tables for possible boot-time SMP configuration. + */ + acpi_boot_init(); +#endif #ifdef CONFIG_X86_LOCAL_APIC /* * get boot-time SMP configuration: @@ -314,6 +346,12 @@ #ifdef CONFIG_GART_IOMMU iommu_hole_init(); #endif +#ifdef CONFIG_SWIOTLB + if (!iommu_aperture && end_pfn >= 0xffffffff>>PAGE_SHIFT) { + swiotlb_init(); + swiotlb = 1; + } +#endif #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) @@ -359,7 +397,10 @@ c->x86_cache_size=(ecx>>24)+(edx>>24); if (n >= 0x80000006) { printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line/%d way)\n", - ecx_2>>16, ecx_2&0xFF, (ecx_2>>12)&0xf); + ecx_2>>16, ecx_2&0xFF, + /* use bits[15:13] as power of 2 for # of ways */ + 1 << ((ecx>>13) & 0x7) + /* Direct and Full associative L2 are very unlikely */); c->x86_cache_size = ecx_2 >> 16; c->x86_tlbsize = ((ebx>>16)&0xff) + ((ebx_2>>16)&0xfff) + (ebx&0xff) + ((ebx_2)&0xfff); @@ -374,6 +415,198 @@ } } +#define LVL_1_INST 1 +#define LVL_1_DATA 2 +#define LVL_2 3 +#define LVL_3 4 +#define LVL_TRACE 5 + +struct _cache_table +{ + unsigned char descriptor; + char cache_type; + short size; +}; + +/* all the cache descriptor types we care about (no TLB or trace cache entries) */ +static struct _cache_table cache_table[] __initdata = +{ + { 0x06, LVL_1_INST, 8 }, + { 0x08, LVL_1_INST, 16 }, + { 0x0A, LVL_1_DATA, 8 }, + { 0x0C, LVL_1_DATA, 16 }, + { 0x22, LVL_3, 512 }, + { 0x23, LVL_3, 1024 }, + { 0x25, LVL_3, 2048 }, + { 0x29, LVL_3, 4096 }, + { 0x39, LVL_2, 128 }, + { 0x3C, LVL_2, 256 }, + { 0x41, LVL_2, 128 }, + { 0x42, LVL_2, 256 }, + { 0x43, LVL_2, 512 }, + { 0x44, LVL_2, 1024 }, + { 0x45, LVL_2, 2048 }, + { 0x66, LVL_1_DATA, 8 }, + { 0x67, LVL_1_DATA, 16 }, + { 0x68, LVL_1_DATA, 32 }, + { 0x70, LVL_TRACE, 12 }, + { 0x71, LVL_TRACE, 16 }, + { 0x72, LVL_TRACE, 32 }, + { 0x79, LVL_2, 128 }, + { 0x7A, LVL_2, 256 }, + { 0x7B, LVL_2, 512 }, + { 0x7C, LVL_2, 1024 }, + { 0x82, LVL_2, 256 }, + { 0x83, LVL_2, 512 }, + { 0x84, LVL_2, 1024 }, + { 0x85, LVL_2, 2048 }, + { 0x00, 0, 0} +}; + +int select_idle_routine(struct cpuinfo_x86 *c); + +static void __init init_intel(struct cpuinfo_x86 *c) +{ + unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ + char *p = NULL; + u32 eax, dummy; + + unsigned int n; + + + select_idle_routine(c); + if (c->cpuid_level > 1) { + /* supports eax=2 call */ + int i, j, n; + int regs[4]; + unsigned char *dp = (unsigned char *)regs; + + /* Number of times to iterate */ + n = cpuid_eax(2) & 0xFF; + + for ( i = 0 ; i < n ; i++ ) { + cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]); + + /* If bit 31 is set, this is an unknown format */ + for ( j = 0 ; j < 3 ; j++ ) { + if ( regs[j] < 0 ) regs[j] = 0; + } + + /* Byte 0 is level count, not a descriptor */ + for ( j = 1 ; j < 16 ; j++ ) { + unsigned char des = dp[j]; + unsigned char k = 0; + + /* look up this descriptor in the table */ + while (cache_table[k].descriptor != 0) + { + if (cache_table[k].descriptor == des) { + switch (cache_table[k].cache_type) { + case LVL_1_INST: + l1i += cache_table[k].size; + break; + case LVL_1_DATA: + l1d += cache_table[k].size; + break; + case LVL_2: + l2 += cache_table[k].size; + break; + case LVL_3: + l3 += cache_table[k].size; + break; + case LVL_TRACE: + trace += cache_table[k].size; + break; + } + break; + } + + k++; + } + } + } + + if ( trace ) + printk (KERN_INFO "CPU: Trace cache: %dK uops", trace); + else if ( l1i ) + printk (KERN_INFO "CPU: L1 I cache: %dK", l1i); + if ( l1d ) + printk(", L1 D cache: %dK\n", l1d); + else + printk("\n"); + if ( l2 ) + printk(KERN_INFO "CPU: L2 cache: %dK\n", l2); + if ( l3 ) + printk(KERN_INFO "CPU: L3 cache: %dK\n", l3); + + /* + * This assumes the L3 cache is shared; it typically lives in + * the northbridge. The L1 caches are included by the L2 + * cache, and so should not be included for the purpose of + * SMP switching weights. + */ + c->x86_cache_size = l2 ? l2 : (l1i+l1d); + } + + if ( p ) + strcpy(c->x86_model_id, p); + +#ifdef CONFIG_SMP + if (test_bit(X86_FEATURE_HT, &c->x86_capability)) { + int index_lsb, index_msb, tmp; + int initial_apic_id; + int cpu = smp_processor_id(); + u32 ebx, ecx, edx; + + cpuid(1, &eax, &ebx, &ecx, &edx); + smp_num_siblings = (ebx & 0xff0000) >> 16; + + if (smp_num_siblings == 1) { + printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); + } else if (smp_num_siblings > 1 ) { + index_lsb = 0; + index_msb = 31; + /* + * At this point we only support two siblings per + * processor package. + */ +#define NR_SIBLINGS 2 + if (smp_num_siblings != NR_SIBLINGS) { + printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings); + smp_num_siblings = 1; + return; + } + tmp = smp_num_siblings; + while ((tmp & 1) == 0) { + tmp >>=1 ; + index_lsb++; + } + tmp = smp_num_siblings; + while ((tmp & 0x80000000 ) == 0) { + tmp <<=1 ; + index_msb--; + } + if (index_lsb != index_msb ) + index_msb++; + initial_apic_id = ebx >> 24 & 0xff; + phys_proc_id[cpu] = initial_apic_id >> index_msb; + + printk(KERN_INFO "CPU: Physical Processor ID: %d\n", + phys_proc_id[cpu]); + } + + } +#endif + + n = cpuid_eax(0x80000000); + if (n >= 0x80000008) { + cpuid(0x80000008, &eax, &dummy, &dummy, &dummy); + c->x86_virt_bits = (eax >> 8) & 0xff; + c->x86_phys_bits = eax & 0xff; + } + +} + static int __init init_amd(struct cpuinfo_x86 *c) { int r; @@ -403,6 +636,8 @@ if (!strcmp(v, "AuthenticAMD")) c->x86_vendor = X86_VENDOR_AMD; + else if (!strcmp(v, "GenuineIntel")) + c->x86_vendor = X86_VENDOR_INTEL; else c->x86_vendor = X86_VENDOR_UNKNOWN; } @@ -418,7 +653,7 @@ */ void __init identify_cpu(struct cpuinfo_x86 *c) { - int junk, i; + int i; u32 xlvl, tfms; c->loops_per_jiffy = loops_per_jiffy; @@ -442,7 +677,7 @@ /* Intel-defined flags: level 0x00000001 */ if ( c->cpuid_level >= 0x00000001 ) { __u32 misc; - cpuid(0x00000001, &tfms, &misc, &junk, + cpuid(0x00000001, &tfms, &misc, &c->x86_capability[4], &c->x86_capability[0]); c->x86 = (tfms >> 8) & 15; c->x86_model = (tfms >> 4) & 15; @@ -491,9 +726,12 @@ init_amd(c); break; + case X86_VENDOR_INTEL: + init_intel(c); + break; case X86_VENDOR_UNKNOWN: default: - /* Not much we can do here... */ + display_cacheinfo(c); break; } @@ -551,7 +789,7 @@ "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov", "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx", - "fxsr", "sse", "sse2", "ss", NULL, "tm", "ia64", NULL, + "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe", /* AMD-defined */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -570,6 +808,12 @@ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* Intel Defined (cpuid 1 and ecx) */ + "pni", NULL, NULL, "monitor", "ds-cpl", NULL, NULL, "est", + "tm2", NULL, "cid", NULL, NULL, "cmpxchg16b", NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; static char *x86_power_flags[] = { "ts", /* temperature sensor */ @@ -606,6 +850,11 @@ seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size); +#ifdef CONFIG_SMP + seq_printf(m, "physical id\t: %d\n",phys_proc_id[c - cpu_data]); + seq_printf(m, "siblings\t: %d\n",smp_num_siblings); +#endif + seq_printf(m, "fpu\t\t: yes\n" "fpu_exception\t: yes\n" @@ -630,6 +879,7 @@ seq_printf(m, "TLB size\t: %d 4K pages\n", c->x86_tlbsize); seq_printf(m, "clflush size\t: %d\n", c->x86_clflush_size); + if (c->x86_phys_bits > 0) seq_printf(m, "address sizes\t: %u bits physical, %u bits virtual\n", c->x86_phys_bits, c->x86_virt_bits); Index: arch/x86_64/kernel/setup64.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/setup64.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/setup64.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/setup64.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -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.1 2004/07/22 19:49:26 joff Exp $ + * $Id: setup64.c,v 1.2 2004/08/04 01:26:20 joff 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,9 +143,34 @@ wrmsrl(MSR_GS_BASE, cpu_pda + cpu); } -#define EXCEPTION_STK_ORDER 0 /* >= N_EXCEPTION_STACKS*EXCEPTION_STKSZ */ +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 +} + char boot_exception_stacks[N_EXCEPTION_STACKS*EXCEPTION_STKSZ]; +void check_efer(void) +{ + unsigned long efer; + rdmsrl(MSR_EFER, efer); + if (!(efer & EFER_NX) || do_not_nx) { + __supported_pte_mask &= ~_PAGE_NX; + } else { + __supported_pte_mask |= _PAGE_NX; + } +} + /* * cpu_init() initializes state that is per-CPU. Some data is already * initialized (naturally) in the bootstrap process, such as the GDT @@ -102,17 +186,12 @@ int nr = smp_processor_id(); #endif struct tss_struct * t = &init_tss[nr]; - unsigned long v, efer; - char *estacks; + unsigned long v; + unsigned long estack; /* CPU 0 is initialised in head64.c */ - if (nr != 0) { + if (nr != 0) pda_init(nr); - estacks = (char *)__get_free_pages(GFP_ATOMIC, EXCEPTION_STK_ORDER); - if (!estacks) - panic("Can't allocate exception stacks for CPU %d\n",nr); - } else - estacks = boot_exception_stacks; if (test_and_set_bit(nr, &cpu_initialized)) panic("CPU#%d already initialized!\n", nr); @@ -132,22 +211,9 @@ 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; - } + check_efer(); t->io_map_base = INVALID_IO_BITMAP_OFFSET; memset(t->io_bitmap, 0xff, sizeof(t->io_bitmap)); @@ -162,10 +228,17 @@ /* * set up and load the per-CPU TSS */ - estacks += EXCEPTION_STKSZ; + estack = (unsigned long)boot_exception_stacks + EXCEPTION_STKSZ; for (v = 0; v < N_EXCEPTION_STACKS; v++) { - t->ist[v] = (unsigned long)estacks; - estacks += EXCEPTION_STKSZ; + if (nr == 0) { + t->ist[v] = estack; + estack += EXCEPTION_STKSZ; + } else { + estack = __get_free_pages(GFP_ATOMIC, EXCEPTION_STK_ORDER); + if(!estack) + panic("Can't allocate exception stack %lu for CPU %d\n", v, nr); + t->ist[v] = estack + EXCEPTION_STKSZ; + } } atomic_inc(&init_mm.mm_count); Index: arch/x86_64/kernel/signal.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/signal.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/signal.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/signal.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -8,7 +8,7 @@ * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes * 2000-2001 x86-64 support by Andi Kleen * - * $Id: signal.c,v 1.1 2004/07/22 19:49:26 joff Exp $ + * $Id: signal.c,v 1.2 2004/08/04 01:26:20 joff Exp $ */ #include @@ -71,6 +71,10 @@ default: err |= __put_user(from->si_uid, &to->si_uid); break; + case __SI_POLL >> 16: + err |= __put_user(from->si_band, &to->si_band); + err |= __put_user(from->si_fd, &to->si_fd); + break; /* case __SI_RT: This is not generated by the kernel as of now. */ } return err; Index: arch/x86_64/kernel/smp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/smp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/smp.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/smp.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -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(); } /* @@ -546,26 +548,3 @@ atomic_inc(&call_data->finished); } } - -/* Slow. Should be only used for debugging. */ -int slow_smp_processor_id(void) -{ - int stack_location; - unsigned long sp = (unsigned long)&stack_location; - int offset = 0, cpu; - - for (offset = 0; (cpu_online_map >> offset); offset = cpu + 1) { - cpu = ffz(~(cpu_online_map >> offset)); - - if (sp >= (u64)cpu_pda[cpu].irqstackptr - IRQSTACKSIZE && - sp <= (u64)cpu_pda[cpu].irqstackptr) - return cpu; - - unsigned long estack = init_tss[cpu].ist[0] - EXCEPTION_STKSZ; - if (sp >= estack && sp <= estack+(1<<(PAGE_SHIFT+EXCEPTION_STK_ORDER))) - return cpu; - } - - return stack_smp_processor_id(); -} - Index: arch/x86_64/kernel/smpboot.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/smpboot.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/smpboot.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/smpboot.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -50,15 +50,21 @@ #include #include #include +#include /* Setup configured maximum number of CPUs to activate */ -static int max_cpus = -1; +unsigned int max_cpus = NR_CPUS; static int cpu_mask = -1; /* Total count of live CPUs */ int smp_num_cpus = 1; +/* Number of siblings per CPU package */ +int smp_num_siblings = 1; +int __initdata phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ +int cpu_sibling_map[NR_CPUS] __cacheline_aligned; + /* Bitmask of currently online CPUs */ unsigned long cpu_online_map; @@ -83,10 +89,6 @@ * * Command-line option of "nosmp" or "maxcpus=0" will disable SMP * activation entirely (the MPS table probe still happens, though). - * - * Command-line option of "maxcpus=", where is an integer - * greater than 0, limits the maximum number of CPUs activated in - * SMP mode to . */ static int __init nosmp(char *str) @@ -97,15 +99,6 @@ __setup("nosmp", nosmp); -static int __init maxcpus(char *str) -{ - get_option(&str, &max_cpus); - return 1; -} - -__setup("maxcpus=", maxcpus); - - static int __init cpumask(char *str) { get_option(&str, &cpu_mask); @@ -863,7 +856,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"); io_apic_irqs = 0; cpu_online_map = phys_cpu_present_map = 1; @@ -907,10 +900,8 @@ if (!max_cpus) { smp_found_config = 0; printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n"); - io_apic_irqs = 0; cpu_online_map = phys_cpu_present_map = 1; smp_num_cpus = 1; - apic_disabled = 1; goto smp_done; } @@ -937,8 +928,6 @@ continue; if (((1<= 0) && (max_cpus <= cpucount+1)) - continue; cpu = do_boot_cpu(apicid); @@ -993,6 +982,34 @@ Dprintk("Boot done.\n"); /* + * If Hyper-Threading is avaialble, construct cpu_sibling_map[], so + * that we can tell the sibling CPU efficiently. + */ + if (test_bit(X86_FEATURE_HT, boot_cpu_data.x86_capability) + && smp_num_siblings > 1) { + for (cpu = 0; cpu < NR_CPUS; cpu++) + cpu_sibling_map[cpu] = NO_PROC_ID; + + for (cpu = 0; cpu < smp_num_cpus; cpu++) { + int i; + + for (i = 0; i < smp_num_cpus; i++) { + if (i == cpu) + continue; + if (phys_proc_id[cpu] == phys_proc_id[i]) { + cpu_sibling_map[cpu] = i; + printk("cpu_sibling_map[%d] = %d\n", cpu, cpu_sibling_map[cpu]); + break; + } + } + if (cpu_sibling_map[cpu] == NO_PROC_ID) { + smp_num_siblings = 1; + printk(KERN_WARNING "WARNING: No sibling found for CPU %d.\n", cpu); + } + } + } + + /* * Here we can be sure that there is an IO-APIC in the system. Let's * go and set it up: */ @@ -1012,6 +1029,9 @@ if (cpu_has_tsc && cpucount) synchronize_tsc_bp(); + if (nmi_watchdog != 0) + check_nmi_watchdog(); + smp_done: zap_low_mappings(); time_init_smp(); Index: arch/x86_64/kernel/sys_x86_64.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/sys_x86_64.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/sys_x86_64.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/sys_x86_64.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -128,3 +128,17 @@ unsigned long raddr; return sys_shmat(shmid,shmaddr,shmflg,&raddr) ?: raddr; } + +asmlinkage long sys_time64(long * tloc) +{ + struct timeval now; + int i; + + do_gettimeofday(&now); + i = now.tv_sec; + if (tloc) { + if (put_user(i,tloc)) + i = -EFAULT; + } + return i; +} Index: arch/x86_64/kernel/time.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/time.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/time.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -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); } Index: arch/x86_64/kernel/traps.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/traps.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/traps.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/traps.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -7,7 +7,7 @@ * Pentium III FXSR, SSE support * Gareth Hughes , May 2000 * - * $Id: traps.c,v 1.1 2004/07/22 19:49:26 joff Exp $ + * $Id: traps.c,v 1.2 2004/08/04 01:26:20 joff Exp $ */ /* @@ -81,7 +81,7 @@ struct notifier_block *die_chain; -int kstack_depth_to_print = 40; +int kstack_depth_to_print = 12; #ifdef CONFIG_KALLSYMS #include @@ -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); @@ -342,16 +342,25 @@ spinlock_t die_lock = SPIN_LOCK_UNLOCKED; int die_owner = -1; -void die(const char * str, struct pt_regs * regs, long err) +void __die(const char * str, struct pt_regs * regs, long err) +{ + printk(KERN_EMERG "%s: %04lx\n", str, err & 0xffff); + notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); + show_registers(regs); + /* Execute summary in case the oops scrolled away */ + printk(KERN_EMERG "RIP "); + printk_address(regs->rip); + printk(" RSP <%016lx>\n", regs->rsp); +} + +void prepare_die(unsigned long *flags) { int cpu; console_verbose(); bust_spinlocks(1); - handle_BUG(regs); - printk(KERN_EMERG "%s: %04lx\n", str, err & 0xffff); - 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) @@ -360,9 +369,23 @@ spin_lock(&die_lock); } die_owner = cpu; - show_registers(regs); +} + +void exit_die(unsigned long flags) +{ + die_owner = -1; + spin_unlock_irqrestore(&die_lock, flags); + __sti(); /* back scroll should work */ bust_spinlocks(0); - spin_unlock_irq(&die_lock); +} + +void die(const char * str, struct pt_regs * regs, long err) +{ + unsigned long flags; + prepare_die(&flags); + handle_BUG(regs); + __die(str, regs, err); + exit_die(flags); do_exit(SIGSEGV); } @@ -402,8 +425,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 +444,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 +503,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 +624,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 +839,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 +867,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 /* Index: arch/x86_64/kernel/vsyscall.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/vsyscall.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/vsyscall.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/vsyscall.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -12,7 +12,7 @@ * vsyscalls. One vsyscall can reserve more than 1 slot to avoid * jumping out of line if necessary. * - * $Id: vsyscall.c,v 1.1 2004/07/22 19:49:26 joff Exp $ + * $Id: vsyscall.c,v 1.2 2004/08/04 01:26:20 joff Exp $ */ /* Index: arch/x86_64/kernel/x8664_ksyms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/kernel/x8664_ksyms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/kernel/x8664_ksyms.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/kernel/x8664_ksyms.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -13,7 +13,9 @@ #include #include #include +#include +#include #include #include #include @@ -52,6 +54,7 @@ EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(pm_idle); EXPORT_SYMBOL(pm_power_off); +EXPORT_SYMBOL(sys_ioctl); #ifdef CONFIG_IO_DEBUG EXPORT_SYMBOL(__io_virt_debug); @@ -94,6 +97,7 @@ EXPORT_SYMBOL(pci_map_sg); EXPORT_SYMBOL(pci_unmap_sg); +EXPORT_SYMBOL(bad_dma_address); #ifdef CONFIG_PCI EXPORT_SYMBOL(pcibios_penalize_isa_irq); @@ -222,4 +226,8 @@ #endif extern void int_ret_from_sys_call(void); -EXPORT_SYMBOL(int_ret_from_sys_call); +EXPORT_SYMBOL_NOVERS(int_ret_from_sys_call); + +EXPORT_SYMBOL(touch_nmi_watchdog); + +EXPORT_SYMBOL(do_fork); Index: arch/x86_64/lib/copy_page.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/lib/copy_page.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/lib/copy_page.S 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/lib/copy_page.S 4 Aug 2004 01:26:20 -0000 1.2 @@ -1,5 +1,7 @@ /* Written 2003 by Andi Kleen, based on a kernel by Evandro Menezes */ +#include + /* Don't use streaming store because it's better when the target ends up in cache. */ @@ -8,16 +10,13 @@ .globl copy_page .p2align 4 copy_page: - prefetch (%rsi) - prefetch 1*64(%rsi) - prefetch 2*64(%rsi) - prefetch 3*64(%rsi) - prefetch 4*64(%rsi) + + prefetcht0 (%rsi) + prefetcht0 1*64(%rsi) +#ifdef CONFIG_MK8 prefetchw (%rdi) prefetchw 1*64(%rdi) - prefetchw 2*64(%rdi) - prefetchw 3*64(%rdi) - prefetchw 4*64(%rdi) +#endif subq $3*8,%rsp movq %rbx,(%rsp) @@ -38,7 +37,7 @@ movq 48 (%rsi), %r11 movq 56 (%rsi), %r12 - prefetch 5*64(%rsi) + prefetcht0 5*64(%rsi) movq %rax, (%rdi) movq %rbx, 8 (%rdi) @@ -49,7 +48,9 @@ movq %r11, 48 (%rdi) movq %r12, 56 (%rdi) +#ifdef CONFIG_MK8 prefetchw 5*64(%rdi) +#endif leaq 64 (%rsi), %rsi leaq 64 (%rdi), %rdi Index: arch/x86_64/lib/copy_user.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/lib/copy_user.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/lib/copy_user.S 22 Jul 2004 19:49:25 -0000 1.1 +++ arch/x86_64/lib/copy_user.S 4 Aug 2004 01:26:20 -0000 1.2 @@ -4,7 +4,9 @@ * Functions to copy from and to user space. */ -#define FIX_ALIGNMENT 1 + #include + +/* #define FIX_ALIGNMENT 1 */ #include #include @@ -59,9 +61,10 @@ .globl copy_user_generic .p2align 4 copy_user_generic: - /* Put the first cacheline into cache. This should handle - the small movements in ioctls etc., but not penalize the bigger - filesystem data copies too much. */ + prefetcht0 (%rsi) +#ifdef CONFIG_MK8 + prefetchw (%rdi) +#endif pushq %rbx xorl %eax,%eax /*zero for the exception handler */ Index: arch/x86_64/lib/csum-copy.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/lib/csum-copy.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/lib/csum-copy.S 22 Jul 2004 19:49:25 -0000 1.1 +++ arch/x86_64/lib/csum-copy.S 4 Aug 2004 01:26:20 -0000 1.2 @@ -44,43 +44,9 @@ .previous .endm - .macro ignore L=.Lignore -30: - .section __ex_table,"a" - .align 8 - .quad 30b,\L - .previous - .endm - - .globl csum_partial_copy_generic .p2align 4 csum_partial_copy_generic: - cmpl $3*64,%edx - jle .Lignore - - ignore - prefetch (%rdi) - ignore - prefetch 1*64(%rdi) - ignore - prefetch 2*64(%rdi) - ignore - prefetch 3*64(%rdi) - ignore - prefetch 4*64(%rdi) - ignore - prefetchw (%rsi) - ignore - prefetchw 1*64(%rsi) - ignore - prefetchw 2*64(%rsi) - ignore - prefetchw 3*64(%rsi) - ignore - prefetchw 4*64(%rsi) - -.Lignore: subq $7*8,%rsp movq %rbx,2*8(%rsp) movq %r12,3*8(%rsp) @@ -126,9 +92,6 @@ source movq 56(%rdi),%r13 - ignore 2f - prefetch 5*64(%rdi) -2: adcq %rbx,%rax adcq %r8,%rax adcq %r11,%rax @@ -158,10 +121,6 @@ dest movq %r13,56(%rsi) - ignore 3f - prefetchw 5*64(%rsi) -3: - leaq 64(%rdi),%rdi leaq 64(%rsi),%rsi Index: arch/x86_64/lib/csum-partial.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/lib/csum-partial.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/lib/csum-partial.c 22 Jul 2004 19:49:25 -0000 1.1 +++ arch/x86_64/lib/csum-partial.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -136,11 +136,10 @@ } /* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c + * this routine is used for miscellaneous IP-like checksums. */ unsigned short ip_compute_csum(unsigned char * buff, int len) { - return ~csum_partial(buff,len,0); + return csum_fold(csum_partial(buff,len,0)); } Index: arch/x86_64/lib/thunk.S =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/lib/thunk.S,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/lib/thunk.S 22 Jul 2004 19:49:25 -0000 1.1 +++ arch/x86_64/lib/thunk.S 4 Aug 2004 01:26:20 -0000 1.2 @@ -3,7 +3,7 @@ * disturbance of register allocation in some inline assembly constructs. * Copyright 2001,2002 by Andi Kleen, SuSE Labs. * Subject to the GNU public license, v.2. No warranty of any kind. - * $Id: thunk.S,v 1.1 2004/07/22 19:49:25 joff Exp $ + * $Id: thunk.S,v 1.2 2004/08/04 01:26:20 joff Exp $ */ #include Index: arch/x86_64/lib/usercopy.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/lib/usercopy.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/lib/usercopy.c 22 Jul 2004 19:49:25 -0000 1.1 +++ arch/x86_64/lib/usercopy.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -68,7 +68,7 @@ asm volatile( " testq %[size8],%[size8]\n" " jz 4f\n" - "0: movnti %[zero],(%[dst])\n" + "0: movq %[zero],(%[dst])\n" " addq %[eight],%[dst]\n" " decl %%ecx ; jnz 0b\n" "4: movq %[size1],%%rcx\n" @@ -77,7 +77,7 @@ "1: movb %b[zero],(%[dst])\n" " incq %[dst]\n" " decl %%ecx ; jnz 1b\n" - "2: sfence\n" + "2:\n" ".section .fixup,\"ax\"\n" "3: lea 0(%[size1],%[size8],8),%[size8]\n" " jmp 2b\n" @@ -126,3 +126,11 @@ s++; } } + +unsigned long copy_in_user(void *to, const void *from, unsigned len) +{ + if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) { + return copy_user_generic(to, from, len); + } + return len; +} Index: arch/x86_64/mm/extable.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/mm/extable.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/mm/extable.c 22 Jul 2004 19:49:25 -0000 1.1 +++ arch/x86_64/mm/extable.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -1,10 +1,11 @@ /* - * linux/arch/i386/mm/extable.c + * linux/arch/x86_64/mm/extable.c */ #include #include #include +#include #include extern const struct exception_table_entry __start___ex_table[]; @@ -39,6 +40,10 @@ unsigned long ret = 0; unsigned long flags; + /* Workaround for an Opteron issue */ + if ((addr >> 32) == 0) + addr |= 0xffffffffUL << 32; + #ifndef CONFIG_MODULES /* There is only the kernel to search. */ ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr); Index: arch/x86_64/mm/fault.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/mm/fault.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/mm/fault.c 22 Jul 2004 19:49:25 -0000 1.1 +++ arch/x86_64/mm/fault.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -94,6 +94,85 @@ printk("BAD\n"); } +/* Sometimes the CPU reports invalid exceptions on prefetch. + Check that here and ignore. + Opcode checker based on code by Richard Brunner */ +static int is_prefetch(struct pt_regs *regs, unsigned long addr) +{ + unsigned char *instr = (unsigned char *)(regs->rip); + int scan_more = 1; + int prefetch = 0; + unsigned char *max_instr = instr + 15; + + /* Avoid recursive faults for this common case */ + if (regs->rip == addr) + return 0; + + if (regs->cs & (1<<2)) + return 0; + + while (scan_more && instr < max_instr) { + unsigned char opcode; + unsigned char instr_hi; + unsigned char instr_lo; + + if (__get_user(opcode, instr)) + break; + + instr_hi = opcode & 0xf0; + instr_lo = opcode & 0x0f; + instr++; + + switch (instr_hi) { + case 0x20: + case 0x30: + /* Values 0x26,0x2E,0x36,0x3E are valid x86 + prefixes. In long mode, the CPU will signal + invalid opcode if some of these prefixes are + present so we will never get here anyway */ + scan_more = ((instr_lo & 7) == 0x6); + break; + + case 0x40: + /* In AMD64 long mode, 0x40 to 0x4F are valid REX prefixes + Need to figure out under what instruction mode the + instruction was issued ... */ + /* Could check the LDT for lm, but for now it's good + enough to assume that long mode only uses well known + segments or kernel. */ + scan_more = ((regs->cs & 3) == 0) || (regs->cs == __USER_CS); + break; + + case 0x60: + /* 0x64 thru 0x67 are valid prefixes in all modes. */ + scan_more = (instr_lo & 0xC) == 0x4; + break; + case 0xF0: + /* 0xF0, 0xF2, and 0xF3 are valid prefixes in all modes. */ + scan_more = !instr_lo || (instr_lo>>1) == 1; + break; + case 0x00: + /* Prefetch instruction is 0x0F0D or 0x0F18 */ + scan_more = 0; + if (__get_user(opcode, instr)) + break; + prefetch = (instr_lo == 0xF) && + (opcode == 0x0D || opcode == 0x18); + break; + default: + scan_more = 0; + break; + } + } + +#if 0 + if (prefetch) + printk("%s: prefetch caused page fault at %lx/%lx\n", current->comm, + regs->rip, addr); +#endif + return prefetch; +} + int page_fault_trace; int exception_trace = 1; @@ -156,7 +235,15 @@ * context, we must not take the fault.. */ if (in_interrupt() || !mm) - goto no_context; + goto bad_area_nosemaphore; + + /* + * Work around K8 errata #100. See the K8 specification update for + * details. Any code segment in LDT is compatibility mode. + */ + if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) && + (address >> 32)) + return; again: down_read(&mm->mmap_sem); @@ -226,16 +313,22 @@ up_read(&mm->mmap_sem); bad_area_nosemaphore: - /* 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 (is_prefetch(regs, address)) + return; + + 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; - tsk->thread.error_code = error_code; + /* Kernel addresses are always protection faults */ + tsk->thread.error_code = error_code | (address >= TASK_SIZE); tsk->thread.trap_no = 14; info.si_signo = SIGSEGV; info.si_errno = 0; @@ -253,28 +346,31 @@ 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; } + if (is_prefetch(regs, address)) + return; + /* * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice. */ - console_verbose(); - bust_spinlocks(1); - + unsigned long flags; + prepare_die(&flags); 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 %016lx\n",address); - printk(" printing rip:\n"); - printk("%016lx\n", regs->rip); + printk(KERN_ALERT " at %016lx RIP: ", address); + printk_address(regs->rip); dump_pagetable(address); - die("Oops", regs, error_code); - bust_spinlocks(0); + __die("Oops", regs, error_code); + /* Executive summary in case the oops scrolled away */ + printk(KERN_EMERG "CR2: %016lx\n", address); + exit_die(flags); do_exit(SIGKILL); /* @@ -296,10 +392,13 @@ do_sigbus: up_read(&mm->mmap_sem); - /* - * Send a sigbus, regardless of whether we were in kernel - * or user mode. - */ + /* Kernel mode? Handle exceptions or die */ + if (!(error_code & 4)) + goto no_context; + + if (is_prefetch(regs, address)) + return; + tsk->thread.cr2 = address; tsk->thread.error_code = error_code; tsk->thread.trap_no = 14; @@ -308,10 +407,6 @@ info.si_code = BUS_ADRERR; info.si_addr = (void *)address; force_sig_info(SIGBUS, &info, tsk); - - /* Kernel mode? Handle exceptions or die */ - if (!(error_code & 4)) - goto no_context; return; Index: arch/x86_64/mm/init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/mm/init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/mm/init.c 22 Jul 2004 19:49:25 -0000 1.1 +++ arch/x86_64/mm/init.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -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(); } Index: arch/x86_64/mm/ioremap.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/mm/ioremap.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/mm/ioremap.c 22 Jul 2004 19:49:25 -0000 1.1 +++ arch/x86_64/mm/ioremap.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -125,12 +125,12 @@ */ if (phys_addr < virt_to_phys(high_memory)) { char *t_addr, *t_end; - struct page *page; t_addr = __va(phys_addr); t_end = t_addr + (size - 1); #ifndef CONFIG_DISCONTIGMEM + struct page *page; for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++) if(!PageReserved(page)) return NULL; Index: arch/x86_64/mm/k8topology.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/mm/k8topology.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/mm/k8topology.c 22 Jul 2004 19:49:25 -0000 1.1 +++ arch/x86_64/mm/k8topology.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -6,7 +6,7 @@ * Instead the northbridge registers are read directly. * * Copyright 2002 Andi Kleen, SuSE Labs. - * $Id: k8topology.c,v 1.1 2004/07/22 19:49:25 joff Exp $ + * $Id: k8topology.c,v 1.2 2004/08/04 01:26:20 joff Exp $ */ #include #include @@ -20,6 +20,8 @@ #include #include +#define Dprintk(x...) + int memnode_shift; u8 memnodemap[NODEMAPSIZE]; @@ -98,7 +100,7 @@ printk(KERN_INFO "Scanning NUMA topology in Northbridge %d\n", nb); - numnodes = (read_pci_config(0, nb, 0, 0x60 ) >> 4) & 3; + numnodes = (read_pci_config(0, nb, 0, 0x60 ) >> 4) & 7; memset(&nodes,0,sizeof(nodes)); prevbase = 0; @@ -109,7 +111,10 @@ base = read_pci_config(0, nb, 1, 0x40 + i*8); limit = read_pci_config(0, nb, 1, 0x44 + i*8); - nodeid = limit & 3; + nodeid = limit & 7; + if ((base & 3) == 0) { + continue; + } if (!limit) { printk(KERN_INFO "Skipping node entry %d (base %lx)\n", i, base); continue; @@ -145,7 +150,7 @@ if (limit == base) continue; if (limit < base) { - printk(KERN_INFO"Node %d bogus settings %lx-%lx. Ignored.\n", + Dprintk(KERN_INFO"Node %d bogus settings %lx-%lx. Ignored.\n", nodeid, base, limit); continue; } @@ -176,10 +181,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; } Index: arch/x86_64/mm/numa.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/mm/numa.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/mm/numa.c 22 Jul 2004 19:49:25 -0000 1.1 +++ arch/x86_64/mm/numa.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -1,7 +1,7 @@ /* * Generic VM initialization for x86-64 NUMA setups. * Copyright 2002 Andi Kleen, SuSE Labs. - * $Id: numa.c,v 1.1 2004/07/22 19:49:25 joff Exp $ + * $Id: numa.c,v 1.2 2004/08/04 01:26:20 joff Exp $ */ #include #include Index: arch/x86_64/mm/pageattr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/mm/pageattr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/mm/pageattr.c 22 Jul 2004 19:49:25 -0000 1.1 +++ arch/x86_64/mm/pageattr.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -52,7 +52,7 @@ /* is this worth it? */ int i; for (i = 0; i < PAGE_SIZE; i += cpu->x86_clflush_size) - asm volatile("clflush %0" :: "m" (address + i)); + asm volatile("clflush (%0)" :: "r" (address + i)); } else asm volatile("wbinvd":::"memory"); __flush_tlb_one(address); Index: arch/x86_64/tools/offset.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/arch/x86_64/tools/offset.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- arch/x86_64/tools/offset.c 22 Jul 2004 19:49:26 -0000 1.1 +++ arch/x86_64/tools/offset.c 4 Aug 2004 01:26:20 -0000 1.2 @@ -1,7 +1,7 @@ /* Written 2000 by Andi Kleen */ /* This program is never executed, just its assembly is examined for offsets (this trick is needed to get cross compiling right) */ -/* $Id: offset.c,v 1.1 2004/07/22 19:49:26 joff Exp $ */ +/* $Id: offset.c,v 1.2 2004/08/04 01:26:20 joff Exp $ */ #define ASM_OFFSET_H 1 #ifndef __KERNEL__ #define __KERNEL__ Index: Documentation/Changes =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/Changes,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/Changes 22 Jul 2004 19:50:27 -0000 1.1 +++ Documentation/Changes 4 Aug 2004 01:33:00 -0000 1.2 @@ -56,7 +56,9 @@ o e2fsprogs 1.25 # tune2fs o jfsutils 1.0.12 # fsck.jfs -V o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs +o xfsprogs 2.6.0 # xfs_db -V o pcmcia-cs 3.1.21 # cardmgr -V +o quota-tools 3.09 # quota -V o PPP 2.4.0 # pppd --version o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version @@ -190,6 +192,16 @@ versions of mkreiserfs, resize_reiserfs, debugreiserfs and reiserfsck. These utils work on both i386 and alpha platforms. +Xfsprogs +-------- + +The latest version of xfsprogs contains mkfs.xfs, xfs_db, and the +xfs_repair utilities, among others, for the XFS filesystem. It is +architecture independent and any version from 2.0.0 onward should +work correctly with this version of the XFS kernel code (2.6.0 or +later is recommended, due to some significant improvements). + + Pcmcia-cs --------- @@ -197,6 +209,14 @@ kernel source. Pay attention when you recompile your kernel ;-). Also, be sure to upgrade to the latest pcmcia-cs release. +Quota-tools +----------- + +Support for 32 bit uid's and gid's is required if you want to use +the newer version 2 quota format. Quota-tools version 3.07 and +newer has this support. Use the recommended version or newer +from the table above. + Intel IA32 microcode -------------------- @@ -327,6 +347,10 @@ ------------- o +Xfsprogs +-------- +o + LVM toolset ----------- o @@ -335,6 +359,10 @@ --------- o +Quota-tools +---------- +o + Jade ---- o Index: Documentation/Configure.help =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/Configure.help,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/Configure.help 22 Jul 2004 19:50:27 -0000 1.1 +++ Documentation/Configure.help 4 Aug 2004 01:33:00 -0000 1.2 @@ -2,8 +2,6 @@ # Eric S. Raymond # Steven Cole # -# Version 3.01: current with 2.4.19+ -# # Translations of this file available on the WWW: # # - Japanese, maintained by the JF Project , at @@ -12,20 +10,13 @@ # # - 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 # # -# To access a document on the WWW, you need to have a direct Internet -# connection and a browser program such as netscape or lynx. If you -# only have email access, you can still use FTP and WWW servers: send -# an email to with the text -# send usenet/news.answers/internet-services/access-via-email -# in the body of the message. -# # Information about what a kernel is, what it does, how to patch and # compile it and much more is contained in the Kernel-HOWTO, available # at . Before you start @@ -109,6 +100,15 @@ like MGA monitors that you are very unlikely to see on today's systems. +Prompt for advanced kernel configuration options +CONFIG_ADVANCED_OPTIONS + This option will enable prompting for a variety of advanced kernel + configuration options. These options can cause the kernel to not + work if they are set incorrectly, but can be used to optimize certain + aspects of kernel memory management. + + Unless you know what you are doing you *should not* enable this option. + Symmetric Multi-Processing support CONFIG_SMP This enables support for systems with more than one CPU. If you have @@ -137,6 +137,15 @@ If you don't know what to do here, say N. +Maximum number of CPUs +CONFIG_NR_CPUS + This allows you to specify the maximum number of CPUs which this + kernel will support. The maximum supported value is 32 and the + mimimum value which makes sense is 2. + + This is purely to save memory - each supported CPU adds + approximately eight kilobytes to the kernel image. + Intel or compatible 80x86 processor CONFIG_X86 This is Linux's home port. Linux was originally native to the Intel @@ -403,6 +412,20 @@ Otherwise low memory pages are used as bounce buffers causing a degrade in performance. +OOM killer support +CONFIG_OOM_KILLER + This option selects the kernel behaviour during total out of memory + condition. + + The default behaviour is to, as soon as no freeable memory and no swap + space are available, kill the task which tries to allocate memory. + The default behaviour is very reliable. + + If you select this option, as soon as no freeable memory is available, + the kernel will try to select the "best" task to be killed. + + If unsure, say N. + Normal floppy disk support CONFIG_BLK_DEV_FD If you want to use the floppy disk drive(s) of your PC under Linux, @@ -467,6 +490,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 @@ -1124,11 +1159,28 @@ This effect can be also invoked by calling "idex=ata66" If unsure, say N. +ATI IXP chipset IDE support +CONFIG_BLK_DEV_ATIIXP + This driver adds explicit support for ATI IXP chipset. + This allows the kernel to change PIO, DMA and UDMA speeds + and to configure the chip to optimum performance. + + Say Y here if you have an ATI IXP chipset IDE controller. + CMD64X/CMD680 chipset support CONFIG_BLK_DEV_CMD64X Say Y here if you have an IDE controller which uses any of these chipsets: CMD643, CMD646 and CMD648. +Compaq Triflex IDE support +CONFIG_BLK_DEV_TRIFLEX + Say Y here if you have a Compaq Triflex IDE controller, such + as those commonly found on Compaq Pentium-Pro systems + + If you want to compile it as a module, say M here and read + . The module will be called + triflex.o. + CY82C693 chipset support CONFIG_BLK_DEV_CY82C693 This driver adds detection and support for the CY82C693 chipset @@ -1198,11 +1250,26 @@ This is a driver for the OPTi 82C621 EIDE controller. Please read the comments at the top of . +National SCx200 chipset support +CONFIG_BLK_DEV_SC1200 + This driver adds support for the built in IDE on the National + SCx200 series of embedded x86 "Geode" systems + + If you want to compile it as a module, say M here and read + . The module will be called + sc1200.o. + ServerWorks OSB4/CSB5 chipset support CONFIG_BLK_DEV_SVWKS This driver adds PIO/(U)DMA support for the ServerWorks OSB4/CSB5 chipsets. +SGI IOC4 chipset support +CONFIG_BLK_DEV_SGIIOC4 + This driver adds PIO & MultiMode DMA-2 support for the SGI IOC4 + chipset. Please say Y here, if you have an Altix System from + Silicon Graphics Inc. + Intel PIIXn chipsets support CONFIG_BLK_DEV_PIIX This driver adds PIO mode setting and tuning for all PIIX IDE @@ -1252,6 +1319,29 @@ If unsure, say N. +PROMISE PDC202{68|69|70|71|75|76|77} support +CONFIG_BLK_DEV_PDC202XX_NEW + Promise Ultra 100 TX2 [PDC20268] + Promise Ultra 133 PTX2 [PDC20269] + Promise FastTrak LP/TX2/TX4 [PDC20270] + Promise FastTrak TX2000 [PDC20271] + Promise MB Ultra 133 [PDC20275] + Promise MB FastTrak 133 [PDC20276] + Promise FastTrak 133 [PDC20277] + + This driver adds up to 4 more EIDE devices sharing a single + interrupt. This device is a bootable PCI UDMA controller. Since + multiple cards can be installed and there are BIOS ROM problems that + happen if the BIOS revisions of all installed cards (max of five) do + not match, the driver attempts to do dynamic tuning of the chipset + at boot-time for max speed. Ultra33 BIOS 1.25 or newer is required + for more than one card. + + If you say Y here, you need to say Y to "Use DMA by default when + available" as well. + + If unsure, say N. + Special UDMA Feature CONFIG_PDC202XX_BURST This option causes the pdc202xx driver to enable UDMA modes on the @@ -1417,12 +1507,15 @@ Amiga Gayle IDE interface support CONFIG_BLK_DEV_GAYLE - This is the IDE driver for the builtin IDE interface on some Amiga - models. It supports both the `A1200 style' (used in A600 and A1200) - and `A4000 style' (used in A4000 and A4000T) of the Gayle IDE - interface. Say Y if you have such an Amiga model and want to use IDE - devices (hard disks, CD-ROM drives, etc.) that are connected to the - builtin IDE interface. + This is the IDE driver for the Amiga Gayle IDE interface. It supports + both the `A1200 style' and `A4000 style' of the Gayle IDE interface, + This includes builtin IDE interfaces on some Amiga models (A600, + A1200, A4000, and A4000T), and IDE interfaces on the Zorro expansion + bus (M-Tech E-Matrix 530 expansion card). + Say Y if you have an Amiga with a Gayle IDE interface and want to use + IDE devices (hard disks, CD-ROM drives, etc.) that are connected to it. + Note that you also have to enable Zorro bus support if you want to + use Gayle IDE interfaces on the Zorro expansion bus. Falcon IDE interface support CONFIG_BLK_DEV_FALCON_IDE @@ -1455,12 +1548,6 @@ Say Y if you have an IDE doubler. The driver is enabled at kernel runtime using the "ide=doubler" kernel boot parameter. -WarpEngine SCSI support -CONFIG_WARPENGINE_SCSI - Support for MacroSystem Development's WarpEngine Amiga SCSI-2 - controller. Info at - . - Builtin PowerMac IDE support CONFIG_BLK_DEV_IDE_PMAC This driver provides support for the built-in IDE controller on @@ -1474,6 +1561,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 @@ -2001,12 +2093,46 @@ If you choose to compile this as a module, the module will be called hptraid.o. +CMD/Silicon Image Medley Software RAID +CONFIG_BLK_DEV_ATARAID_MEDLEY + Say Y or M if you have a Silicon Image 3112 SATA RAID controller, + a CMD680 based controller, or another IDE RAID controller that uses + CMD's Medley software RAID, and want Linux to use the software RAID + feature of this card. This driver uses /dev/ataraid/dXpY (X and Y + numbers) as device names. + + This driver currently only supports RAID0 (striped) mode, so if you + are using RAID1 (mirroring) this will not work for you. In that + case, you may want to try the Silicon Image Medley Software RAID + driver (below). + + Support for mirroring is planned in the future. + + If you choose to compile this as a module, the module will be called + medley.o. + +Silicon Image Medley Software RAID (old driver) +CONFIG_BLK_DEV_ATARAID_SII + Say Y or M if you have a Silicon Image SATARaid controller + and want Linux to use the softwareraid feature of this card. + This driver uses /dev/ataraid/dXpY (X and Y numbers) as device + names. + + This driver does not reliably detect all Medley RAID sets, and could + be dangerous if you have a striped set with disks of different size. + + You should use the new Medley RAID driver (above), unless you use + RAID1 (mirroring), which the new driver does not yet support. + + If you choose to compile this as a module, the module will be called + silraid.o. + Support for Acer PICA 1 chipset CONFIG_ACER_PICA_61 This is a machine with a R4400 133/150 MHz CPU. To compile a Linux kernel that runs on these, say Y here. For details about Linux on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at - . + . Support for Algorithmics P4032 (EXPERIMENTAL) CONFIG_ALGOR_P4032 @@ -2014,11 +2140,22 @@ The board uses the R4300 and a R5230 CPUs. For more information about this board see . +SGI SN2 L1 serial port support +CONFIG_SGI_L1_SERIAL + If you have an SGI SN2 and you want to use the serial port connected + to the system controller (you want this!), say Y. Otherwise, say N. + +SGI SN2 L1 serial console support +CONFIG_SGI_L1_SERIAL_CONSOLE + If you have an SGI SN2 and you would like to use the system + controller serial port as your console (you want this!), say Y. + Otherwise, say N. + Support for BAGET MIPS series CONFIG_BAGET_MIPS This enables support for the Baget, a Russian embedded system. For more details about the Baget see the Linux/MIPS FAQ on - . + . Baget AMD LANCE support CONFIG_BAGETLANCE @@ -2029,7 +2166,7 @@ Support for DECstations CONFIG_DECSTATION This enables support for DEC's MIPS based workstations. For details - see the Linux/MIPS FAQ on and the + see the Linux/MIPS FAQ on and the DECstation porting pages on . If you have one of the following DECstation Models you definitely @@ -2095,6 +2232,85 @@ 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). + +Bus trace dump on bus error +CONFIG_SIBYTE_BW_TRACE + Run a continuous bus trace, dumping the raw data as soon as a ZBbus + error is detected. Cannot work if ZBbus profiling is turned on, and + also will interfere with JTAG-based trace buffer activity. Raw + buffer data is dumped to console, and must be processed off-line. + +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 @@ -2108,7 +2324,7 @@ This is a machine with a R4000 100 MHz CPU. To compile a Linux kernel that runs on these, say Y here. For details about Linux on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at - . + . Enable Qtronix 990P Keyboard Support CONFIG_QTRONIX_KEYBOARD @@ -2120,7 +2336,7 @@ This is a machine with a R4000 100 MHz CPU. To compile a Linux kernel that runs on these, say Y here. For details about Linux on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at - . + . Support for SNI RM200 PCI CONFIG_SNI_RM200_PCI @@ -2164,11 +2380,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 +2392,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 +2536,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 +2568,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 +2821,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 +3295,32 @@ If you want to compile it as a module, say M here and read . If unsure, say `N'. +ARP tables support +CONFIG_IP_NF_ARPTABLES + arptables is a general, extensible packet identification framework. + The ARP packet filtering and mangling (manipulation)subsystems + use this: say Y or M here if you want to use either of those. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + +ARP packet filtering +CONFIG_IP_NF_ARPFILTER + ARP packet filtering defines a table `filter', which has a series of + rules for simple ARP packet filtering at local input and + local output. See the man page for arptables(8). + + 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. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + TCP Explicit Congestion Notification support CONFIG_INET_ECN Explicit Congestion Notification (ECN) allows routers to notify @@ -3096,6 +3365,255 @@ If you want to compile it as a module, say M here and read . If unsure, say `N'. +IP: virtual server support +CONFIG_IP_VS + IP Virtual Server support will let you build a high-performance + virtual server based on cluster of two or more real servers. This + option must be enabled for at least one of the clustered computers + that will take care of intercepting incomming connections to a + single IP address and scheduling them to real servers. + + Three request dispatching techniques are implemented, they are + virtual server via NAT, virtual server via tunneling and virtual + server via direct routing. The several scheduling algorithms can + be used to choose which server the connection is directed to, + thus load balancing can be achieved among the servers. For more + information and its administration program, please visit the + following URL: + http://www.linuxvirtualserver.org/ + + If you want to compile it in kernel, say Y. If you want to compile + it as a module, say M here and read Documentation/modules.txt. If + unsure, say N. + +IP virtual server debugging +CONFIG_IP_VS_DEBUG + Say Y here if you want to get additional messages useful in + debugging the IP virtual server code. You can change the debug + level in /proc/sys/net/ipv4/vs/debug_level + +IPVS connection hash table size (the Nth power of 2) +CONFIG_IP_VS_TAB_BITS + The IPVS connection hash table uses the chaining scheme to handle + hash collisions. Using a big IPVS connection hash table will greatly + reduce conflicts when there are hundreds of thousands of connections + in the hash table. + + Note the table size must be power of 2. The table size will be the + value of 2 to the your input number power. The number to choose is + from 8 to 20, the default number is 12, which means the table size + is 4096. Don't input the number too small, otherwise you will lose + performance on it. You can adapt the table size yourself, according + to your virtual server application. It is good to set the table size + not far less than the number of connections per second multiplying + average lasting time of connection in the table. For example, your + virtual server gets 200 connections per second, the connection lasts + for 200 seconds in average in the connection table, the table size + should be not far less than 200x200, it is good to set the table + size 32768 (2**15). + + Another note that each connection occupies 128 bytes effectively and + each hash entry uses 8 bytes, so you can estimate how much memory is + needed for your box. + +IPVS: round-robin scheduling +CONFIG_IP_VS_RR + The robin-robin scheduling algorithm simply directs network + connections to different real servers in a round-robin manner. + + If you want to compile it in kernel, say Y. If you want to compile + it as a module, say M here and read Documentation/modules.txt. If + unsure, say N. + +IPVS: weighted round-robin scheduling +CONFIG_IP_VS_WRR + The weighted robin-robin scheduling algorithm directs network + connections to different real servers based on server weights + in a round-robin manner. Servers with higher weights receive + new connections first than those with less weights, and servers + with higher weights get more connections than those with less + weights and servers with equal weights get equal connections. + + If you want to compile it in kernel, say Y. If you want to compile + it as a module, say M here and read Documentation/modules.txt. If + unsure, say N. + +IPVS: least-connection scheduling +CONFIG_IP_VS_LC + The least-connection scheduling algorithm directs network + connections to the server with the least number of active + connections. + + If you want to compile it in kernel, say Y. If you want to compile + it as a module, say M here and read Documentation/modules.txt. If + unsure, say N. + +IPVS: weighted least-connection scheduling +CONFIG_IP_VS_WLC + The weighted least-connection scheduling algorithm directs network + connections to the server with the least active connections + normalized by the server weight. + + If you want to compile it in kernel, say Y. If you want to compile + it as a module, say M here and read Documentation/modules.txt. If + unsure, say N. + +IPVS: locality-based least-connection scheduling +CONFIG_IP_VS_LBLC + The locality-based least-connection scheduling algorithm is for + destination IP load balancing. It is usually used in cache cluster. + This algorithm usually directs packet destined for an IP address to + its server if the server is alive and under load. If the server is + overloaded (its active connection numbers is larger than its weight) + and there is a server in its half load, then allocate the weighted + least-connection server to this IP address. + + If you want to compile it in kernel, say Y. If you want to compile + it as a module, say M here and read Documentation/modules.txt. If + unsure, say N. + +IPVS: locality-based least-connection with replication scheduling +CONFIG_IP_VS_LBLCR + The locality-based least-connection with replication scheduling + algorithm is also for destination IP load balancing. It is + usually used in cache cluster. It differs from the LBLC scheduling + as follows: the load balancer maintains mappings from a target + to a set of server nodes that can serve the target. Requests for + a target are assigned to the least-connection node in the target's + server set. If all the node in the server set are over loaded, + it picks up a least-connection node in the cluster and adds it + in the sever set for the target. If the server set has not been + modified for the specified time, the most loaded node is removed + from the server set, in order to avoid high degree of replication. + + If you want to compile it in kernel, say Y. If you want to compile + it as a module, say M here and read Documentation/modules.txt. If + unsure, say N. + +IPVS: destination hashing scheduling +CONFIG_IP_VS_DH + The destination hashing scheduling algorithm assigns network + connections to the servers through looking up a statically assigned + hash table by their destination IP addresses. + + If you want to compile it in kernel, say Y. If you want to compile + it as a module, say M here and read Documentation/modules.txt. If + unsure, say N. + +IPVS: source hashing scheduling +CONFIG_IP_VS_SH + The source hashing scheduling algorithm assigns network + connections to the servers through looking up a statically assigned + hash table by their source IP addresses. + + If you want to compile it in kernel, say Y. If you want to compile + it as a module, say M here and read Documentation/modules.txt. If + unsure, say N. + +IPVS: shortest expected delay scheduling +CONFIG_IP_VS_SED + The shortest expected delay scheduling algorithm assigns network + connections to the server with the shortest expected delay. The + expected delay that the job will experience is (Ci + 1) / Ui if + sent to the ith server, in which Ci is the number of connections + on the the ith server and Ui is the fixed service rate (weight) + of the ith server. + + If you want to compile it in kernel, say Y. If you want to compile + it as a module, say M here and read Documentation/modules.txt. If + unsure, say N. + +IPVS: never queue scheduling +CONFIG_IP_VS_NQ + The never queue scheduling algorithm adopts a two-speed model. + When there is an idle server available, the job will be sent to + the idle server, instead of waiting for a fast one. When there + is no idle server available, the job will be sent to the server + that minimize its expected delay (The Shortest Expected Delay + scheduling algorithm). + + If you want to compile it in kernel, say Y. If you want to compile + it as a module, say M here and read Documentation/modules.txt. If + unsure, say N. + +IPVS: FTP protocol helper +CONFIG_IP_VS_FTP + FTP is a protocol that transfers IP address and/or port number in + the payload. In the virtual server via Network Address Translation, + the IP address and port number of real servers cannot be sent to + clients in ftp connections directly, so FTP protocol helper is + required for tracking the connection and mangling it back to that of + virtual service. + + If you want to compile it in kernel, say Y. If you want to compile + it as a module, say M here and read Documentation/modules.txt. If + unsure, say N. + +AH/ESP match support (EXPERIMENTAL) +CONFIG_IP6_NF_MATCH_AHESP + This module allows one to match AH and ESP packets. + + If you want to compile it as a module, say M here and read + . The modules will be called + ip6t_ah.o and ip6t_esp.o. + + If unsure, say 'N'. + +Routing header match support +CONFIG_IP6_NF_MATCH_RT + rt matching allows you to match packets based on the routing + header of the packet. + + If you want to compile it as a module, say M here and read + . The module will be called + ip6t_rt.o. + + If unsure, say 'N'. + +Hop-by-hop and Dst opts header match support +CONFIG_IP6_NF_MATCH_OPTS + This allows one to match packets based on the hop-by-hop + and destination options headers of a packet. + + If you want to compile it as a module, say M here and read + . The modules will be called + ip6t_hbh.o and ip6t_dst.o. + + If unsure, say 'N'. + +Fragmentation header match support +CONFIG_IP6_NF_MATCH_FRAG + frag matching allows you to match packets based on the fragmentation + header of the packet. + + If you want to compile it as a module, say M here and read + . The module will be called + ip6t_frag.o. + + If unsure, say 'N'. + +HL match support +CONFIG_IP6_NF_MATCH_HL + HL matching allows you to match packets based on the hop + limit of the packet. + + If you want to compile it as a module, say M here and read + . The module will be called + ip6t_hl.o. + + If unsure, say 'N'. + +IPv6 Extension Headers Match (EXPERIMENTAL) +CONFIG_IP6_NF_MATCH_IPV6HEADER + This module allows one to match packets based upon + the ipv6 extension headers. + + If you want to compile it as a module, say M here and read + . The module will be called + ip6t_ipv6header.o. + + If unsure, say 'N'. + SYN flood protection CONFIG_SYN_COOKIES Normal TCP/IP networking is open to an attack known as "SYN @@ -3341,7 +3859,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 +3950,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 @@ -3458,6 +3969,24 @@ via the file /proc/rtc and its behaviour is set by various ioctls on /dev/rtc. +Dallas DS1742 RTC Support +CONFIG_DS1742 + If you say Y here and create a character special file /dev/rtc with + major number 10 and minor number 135 using mknod ("man mknod"), you + will get access to the real time clock present on various Toshiba + MIPS-based boards. It reports status information via the file + /proc/driver/rtc and its behaviour is set by various ioctls on + /dev/rtc or /dev/misc/rtc if using devfs. + + For technical information and application notes, please see the + Dallas Semiconductor website: + . + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module is called ds1742.o. If you want to compile it as a module, + say M here and read . + Indy/I2 Hardware Watchdog CONFIG_INDYDOG Hardwaredriver for the Indy's/I2's watchdog. This is a @@ -3583,29 +4112,37 @@ 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. -CONFIG_AGP_AMD_8151 +CONFIG_AGP_AMD_K8 This option gives you AGP support for the GLX component of - XFree86 on AMD K8 with an AGP 8151 chipset. + XFree86 on an AMD Opteron/Athlon64 using the on-CPU GART. 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. Generic SiS support CONFIG_AGP_SIS - This option gives you AGP support for the GLX component of the "soon - to be released" XFree86 4.x on Silicon Integrated Systems [SiS] - chipsets. + This option gives you AGP support for the GLX component of + XFree86 4.x on Silicon Integrated Systems [SiS] chipsets. - Note that 5591/5592 AGP chipsets are NOT supported. + Note that 5591/5592 AGP chipsets are NOT specifically supported; + However, the driver works well on these, too. 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. Serverworks LE/HE support CONFIG_AGP_SWORKS - Say Y here to support the Serverworks AGP card. See + 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 @@ -3626,6 +4163,13 @@ This option gives you AGP GART support for the HP ZX1 chipset for IA64 processors. +CONFIG_AGP_ATI + This option gives you AGP support for the GLX component of + XFree86 4.x on the ATI RadeonIGP family of 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. + Support for ISA-bus hardware CONFIG_ISA Find out whether you have ISA slots on your motherboard. ISA is the @@ -3977,6 +4521,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 @@ -4504,21 +5053,25 @@ 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-AA TURBOchannel framebuffer support +CONFIG_FB_PMAG_AA + Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1) + used mainly in the MIPS-based DECstation series. 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 @@ -4799,27 +5352,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. + + 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. - If you need support for G450 or G550 secondary head, say Y to - "Matrox G450/G550 second head support" below. +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 @@ -4862,32 +5434,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 @@ -4987,21 +5541,23 @@ This is the frame buffer device driver for the Hitachi HD64461 LCD frame buffer card. -SIS acceleration +SIS display support CONFIG_FB_SIS - This is the frame buffer device driver for the SiS 630 and 640 Super - Socket 7 UMA cards. Specs available at . + This is the frame buffer device driver for the SiS 300, 315 and 330 + series chipsets. Documentation available at the maintainer's site + at . -SIS 630/540/730 support +SIS 300 series support CONFIG_FB_SIS_300 - This is the frame buffer device driver for the SiS 630 and related - Super Socket 7 UMA cards. Specs available at - . + This enables support for SiS 300 series chipsets (300/305, 540, 630, + 730). Documentation available at the maintainer's website at + . -SIS 315H/315 support +SIS 315/330 series support CONFIG_FB_SIS_315 - This is the frame buffer device driver for the SiS 315 graphics - card. Specs available at . + This enables support for SiS 315/330 series chipsets (315, 550, 650, + M650, 651, 661FX, M661FX, 740, 741, 330). Documentation available at + the maintainer's site . IMS Twin Turbo display support CONFIG_FB_IMSTT @@ -5057,6 +5613,17 @@ is at . +Mach64 Generic LCD support +CONFIG_FB_ATY_GENERIC_LCD + Enabling this option enables the Atyfb driver to drive LCD panels. It + will autodetect the resulution and format of your display and emulate + other resolutions using the hardware stretcher on the chip. + Say Y here if you have computer with a Rage LT Pro, Rage Mobility M1, + Rage XC or Rage XL chip and a laptop LCD display or any other LCD display + that needs to be digitally driven. It is not necessary to enable this + option if you are using an LCD display with a normal VGA connector, + but it won't hurt if you do. + ATI Radeon display support CONFIG_FB_RADEON Choose this option if you want to use an ATI Radeon graphics card as @@ -5483,11 +6050,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 @@ -5666,6 +6228,73 @@ It is safe to say N here for now. +The SCTP Protocol (EXPERIMENTAL) +CONFIG_IP_SCTP + Stream Control Transmission Protocol + + From RFC 2960 (http://www.ietf.org/rfc/rfc2960.txt) + + "SCTP is a reliable transport protocol operating on top of a + connectionless packet network such as IP. It offers the following + services to its users: + + -- acknowledged error-free non-duplicated transfer of user data, + -- data fragmentation to conform to discovered path MTU size, + -- sequenced delivery of user messages within multiple streams, + with an option for order-of-arrival delivery of individual user + messages, + -- optional bundling of multiple user messages into a single SCTP + packet, and + -- network-level fault tolerance through supporting of multi- + homing at either or both ends of an association." + + This protocol support 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 sctp. If you want to compile it + as a module, say M here and read . + + If in doubt, say N. + +SCTP: Debug messages +CONFIG_SCTP_DBG_MSG + If you say Y, this will enable verbose debugging messages. + + If unsure, say N. However, if you are running into problems, use + this option to gather detailed trace information + +SCTP: Debug object counts +CONFIG_SCTP_DBG_OBJCNT + If you say Y, this will enable debugging support for counting the + type of objects that are currently allocated. This is useful for + identifying memory leaks. If the /proc filesystem is enabled this + debug information can be viewed by + 'cat /proc/net/sctp/sctp_dbg_objcnt' + + If unsure, say N + +#choice +SCTP: HMAC algorithm +CONFIG_SCTP_HMAC_NONE + Choose an HMAC algorithm to be used during association establishment. + It can be one of SHA1, MD5 or NONE. It is advised to use either HMAC-MD5 + or HMAC-SHA1. + See configuration for Cryptographic API and enable these algorithms + to make usable by SCTP. + +SCTP: SHA1 HMAC algorithm +CONFIG_SCTP_HMAC_SHA1 + Enable the use of HMAC-SHA1 during association establishment. It + is advised to use either HMAC-MD5 or HMAC-SHA1. + See configuration for Cryptographic API and enable these algorithms + to make usable by SCTP. + +SCTP: MD5 HMAC algorithm +config SCTP_HMAC_MD5 + Enable the use of HMAC-MD5 during association establishment. It is + advised to use either HMAC-MD5 or HMAC-SHA1. + See configuration for Cryptographic API and enable these algorithms + to make usable by SCTP. + Kernel httpd acceleration CONFIG_KHTTPD The kernel httpd acceleration daemon (kHTTPd) is a (limited) web @@ -6433,8 +7062,11 @@ Packet socket: mmapped IO CONFIG_PACKET_MMAP - If you say Y here, the Packet protocol driver will use an IO - mechanism that results in faster communication. + If you say Y here, the Packet protocol driver can use a faster and + more efficient capture method. This feature also allows bigger + receive buffers. To take advantage of this method who have to use + a libpcap library that supports it. For more info see + . If unsure, say N. @@ -6800,7 +7432,7 @@ CONFIG_CISS_SCSI_TAPE When enabled (Y), this option allows SCSI tape drives and SCSI medium changers (tape robots) to be accessed via a Compaq 5xxx array - controller. (See Documentation/cciss.txt for more details.) + controller. (See for more details.) "SCSI support" and "SCSI tape support" must also be enabled for this option to work. @@ -6808,6 +7440,15 @@ When this option is disabled (N), the SCSI portion of the driver is not compiled. +Enable monitor thread +CONFIG_CISS_MONITOR_THREAD + Intended for use with multipath configurations (see the md driver). + This option allows a per-adapter monitoring thread to periodically + poll the adapter to detect failure modes in which the processor + is unable to receive interrupts from the adapter, thus enabling + fail-over to an alternate adapter in such situations. See + for more details. + QuickNet Internet LineJack/PhoneJack support CONFIG_PHONE_IXJ Say M if you have a telephony card manufactured by Quicknet @@ -6911,6 +7552,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. @@ -6963,6 +7613,16 @@ architecture is based on LSI Logic's Message Passing Interface (MPI) specification. +Maximum number of scatter gather entries +CONFIG_FUSION_MAX_SGE + This option allows you to specify the maximum number of scatter- + gather entries per I/O. The driver defaults to 40, a reasonable number + for most systems. However, the user may increase this up to 128. + Increasing this parameter will require significantly more memory + on a per controller instance. Increasing the parameter is not + necessary (or recommended) unless the user will be running + large I/O's via the raw interface. + Fusion MPT enhanced SCSI error reporting [optional] module CONFIG_FUSION_ISENSE The isense module (roughly stands for Interpret SENSE data) is @@ -7230,6 +7890,27 @@ there should be no noticeable performance impact as long as you have logging turned off. +QDIO base support for IBM S/390 and zSeries +CONFIG_QDIO + This driver provides the Queued Direct I/O base support for the + IBM S/390 (G5 and G6) and eServer zSeries (z800 and z900). + + For details please refer to the documentation provided by IBM at + + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called qdio.o. If you want to compile it as a + module, say M here and read . + + If unsure, say Y. + +Performance statistics for QDIO base support +CONFIG_QDIO_PERF_STATS + Say Y here to get performance statistics in /proc/qdio_perf + + If unsure, say N. + SGI WD93C93 SCSI Driver CONFIG_SCSI_SGIWD93 Say Y here to support the on-board WD93C93 SCSI controller found (a) @@ -7297,47 +7978,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 @@ -7345,16 +8019,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 @@ -7463,6 +8164,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. @@ -7743,7 +8521,7 @@ 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 sym53c8xx.o. + will be called sym53c8xx_2.o. PCI DMA addressing mode CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE @@ -8406,16 +9184,31 @@ say M here and read . The module will be called AM53C974.o. -AMI MegaRAID support +AMI MegaRAID support (old driver) CONFIG_SCSI_MEGARAID - This driver supports the AMI MegaRAID 418, 428, 438, 466, 762, 490 - and 467 SCSI host adapters. + This driver supports the AMI MegaRAID 418, 428, 438, 466, 762, 490, + 467, 471 and 493 SCSI host adapters. + + This is the old and very heavily tested driver but lacks features + like clustering. 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 megaraid.o. +AMI MegaRAID support (new driver) +CONFIG_SCSI_MEGARAID2 + This driver supports the AMI MegaRAID 418, 428, 438, 466, 762, 490, + 467, 471, 493 and new Ultra320(518, 520, 531, 532) SCSI host adapters. + + This is the newer less tested but more featureful driver. + + 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 megaraid2.o. + Intel/ICP (former GDT SCSI Disk Array) RAID Controller support CONFIG_SCSI_GDTH Formerly called GDT SCSI Disk Array Controller Support. @@ -8758,6 +9551,17 @@ Say Y if you really want or need the debugging output, everyone else says N. +CONFIG_IEEE1394_OUI_DB + If you say Y here, then an OUI list (vendor unique ID's) will be + compiled into the ieee1394 module. This doesn't really do much + except being able to display the vendor of a hardware node. The + downside is that it adds about 300k to the size of the module, + or kernel (depending on whether you compile ieee1394 as a + module, or static in the kernel). + + This option is not needed for userspace programs like gscanbus + to show this information. + Network device support CONFIG_NETDEVICES You can say N here if you don't intend to connect your Linux box to @@ -9416,6 +10220,17 @@ Support for these adaptors is so far still incomplete and buggy. You have been warned. +Hermes 802.11b in TMD7160/NCP130 based PCI adaptor support +CONFIG_TMD_HERMES + Enable support for PCMCIA cards supported by the "Hermes" (aka + orinoco) driver when used in TMD7160 based PCI adaptors. These + adaptors are not a full PCMCIA controller but act as a more limited + PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that + 802.11b PCMCIA cards can be used in desktop machines. + + Support for these adaptors is so far still incomplete and buggy. + You have been warned. + Prism 2.5 PCI 802.11b adaptor support CONFIG_PCI_HERMES Enable support for PCI and mini-PCI 802.11b wireless NICs based on @@ -9486,6 +10301,19 @@ say M here and read . The module will be called airo_cs.o. +Atmel at76c502/at76c504 PCMCIA cards +CONFIG_PCMCIA_ATMEL + A driver for PCMCIA 802.11 wireless cards based on the + Atmel fast-vnet chips. This driver supports standard + Linux wireless extensions. + + Many cards based on this chipset do not have flash memory + and need their firmware loaded at start-up. If yours is + one of these, you will need to provide a firmware image + to be loaded into the card by the driver. The Atmel + firmware package can be downloaded from + http://www.thekelleys.org.uk/atmel/atmel_firmware.tar.gz + Aviator/Raytheon 2.4MHz wireless support CONFIG_PCMCIA_RAYCS Say Y here if you intend to attach an Aviator/Raytheon PCMCIA @@ -9681,36 +10509,17 @@ This driver supports the FarSync T-Series X.21 (and V.35/V.24) cards from FarSite Communications Ltd. Synchronous communication is supported on all ports at speeds up to - 8Mb/s (128K on V.24) using synchronous PPP or Cisco HDLC. + 8Mb/s (128K on V.24) using synchronous PPP, Cisco HDLC, raw HDLC, + Frame Relay or X.25/LAPB. 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 farsync.o and if you want the module to be automatically loaded when the interface is referenced then you - should add "alias syncX farsync" to /etc/modules.conf for each + should add "alias hdlcX farsync" to /etc/modules.conf for each interface, where X is 0, 1, 2, ... -CONFIG_HDLC_DEBUG_PKT - This option is for developers only - do NOT use on production - systems. - -CONFIG_HDLC_DEBUG_HARD_HEADER - This option is for developers only - do NOT use on production - systems. - -CONFIG_HDLC_DEBUG_ECN - This option is for developers only - do NOT use on production - systems. - -CONFIG_HDLC_DEBUG_RINGS - If you answer Y here you will be able to get a diagnostic dump of - port's TX and RX packet rings, using "sethdlc hdlcX private" - command. It does not affect normal operations. - - If unsure, say Y here. - - Frame Relay (DLCI) support CONFIG_DLCI This is support for the frame relay protocol; frame relay is a fast @@ -9915,7 +10724,16 @@ whenever you want). If you want to compile it as a module, say M here and read . -CSZ packet scheduler (experimental) +CONFIG_NET_SCH_HFSC + Say Y here if you want to use the Hierarchical Fair Service Curve + (HFSC) packet scheduling algorithm for some of your network devices. + + This code is also available as a module called sch_hfsc.o ( = 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 . + +CSZ packet scheduler CONFIG_NET_SCH_CSZ Say Y here if you want to use the Clark-Shenker-Zhang (CSZ) packet scheduling algorithm for some of your network devices. At the @@ -10029,6 +10847,14 @@ whenever you want). If you want to compile it as a module, say M here and read . +Network delay simualtor +CONFIG_NET_SCH_DELAY + Say Y if you want to delay packets by a fixed amount of + time. This is often useful to simulate network delay when + testing applications or protocols. + + This code is also available as a module called sch_delay.o + Ingress Qdisc CONFIG_NET_SCH_INGRESS If you say Y here, you will be able to police incoming bandwidth @@ -10235,6 +11061,26 @@ The module will be called dscc4.o. For general information about modules read . +PCISYNC feature +CONFIG_DSCC4_PCISYNC + Due to Etinc's design choice for its PCISYNC cards, some operations + are only allowed on specific ports of the DSCC4. This option is the + only way for the driver to know that it shouldn't return a success + code for these operations. + + Please say Y if your card is an Etinc's PCISYNC. + +Hard reset support +CONFIG_DSCC4_PCI_RST + Various DSCC4 bug forbid any reliable software reset of the asic. + As a replacement, some vendors provide a way to assert the PCI #RST + pin of DSCC4 through the GPIO port of the card. If you choose Y, the + driver will make use of this feature before module removal (i.e. rmmod). + This feature is known to exist on Commtech's cards. + Contact your manufacturer for details. + + Say Y if yout card supports this feature. + LanMedia Corp. serial boards (SSI/V.35, T1/E1, HSSI, T3) CONFIG_LANMEDIA This is a driver for the following Lan Media family of serial @@ -10424,9 +11270,6 @@ You must say Y to "/proc file system support" (CONFIG_PROC_FS) to use this driver. - If you want to compile this as a module, say M and read - . The module will be called comx.o. - Support for COMX/CMX/HiCOMX boards CONFIG_COMX_HW_COMX Hardware driver for the 'CMX', 'COMX' and 'HiCOMX' boards from the @@ -10583,6 +11426,15 @@ If unsure, say N here. +Raw HDLC Ethernet device support +CONFIG_HDLC_RAW_ETH + Say Y to this option if you want generic HDLC driver to support + raw HDLC Ethernet device emulation over WAN (Wide Area Network) + connections. + You will need it for Ethernet over HDLC bridges. + + If unsure, say N here. + Cisco HDLC support CONFIG_HDLC_CISCO Say Y to this option if you want generic HDLC driver to support @@ -10597,13 +11449,6 @@ If unsure, say N here. -Frame-Relay bridging support -CONFIG_HDLC_FR_BRIDGE - Say Y to this option if you want generic HDLC driver to support - bridging LAN frames over Frame-Relay links. - - If unsure, say N here. - Synchronous Point-to-Point Protocol (PPP) support CONFIG_HDLC_PPP Say Y to this option if you want generic HDLC driver to support @@ -10618,6 +11463,39 @@ If unsure, say N here. +Cyclades-PC300 support +CONFIG_PC300 + This is a driver for the Cyclades-PC300 synchronous communication + boards. These boards provide synchronous serial interfaces to your + Linux box (interfaces currently available are RS-232/V.35, X.21 and + T1/E1). If you wish to support Multilink PPP, please select the + option below this one and read the file README.mlppp provided by PC300 + package. + + 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 Documentation/modules.txt. The module will be + called pc300.o. + + If you haven't heard about it, it's safe to say N. + +Cyclades-PC300 Sync TTY (to MLPPP) support +CONFIG_PC300_MLPPP + Say 'Y' to this option if you are planning to use Multilink PPP over the + PC300 synchronous communication boards. + +CONFIG_PCI200SYN + This driver is for PCI200SYN cards made by Goramo sp. j. + If you have such a card, say Y or M here and see + + + 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 pci200syn.o. + + If unsure, say N here. + SDL RISCom/N2 support CONFIG_N2 This driver is for RISCom/N2 single or dual channel ISA cards @@ -10974,33 +11852,71 @@ The safe and default value for this is N. -SysKonnect SK-98xx and SK-95xx Gigabit Ethernet Adapter family support +Marvell Yukon / SysKonnect SK-98xx and SK-95xx Gigabit Ethernet Adapter family support CONFIG_SK98LIN - Say Y here if you have a SysKonnect SK-98xx or SK-95xx Gigabit - Ethernet Server Adapter. The following adapters are supported by - this driver: - - SK-9521 10/100/1000Base-T Adapter - - SK-9821 Gigabit Ethernet 1000Base-T Server Adapter - - SK-9822 Gigabit Ethernet 1000Base-T Dual Port Server Adapter - - SK-9841 Gigabit Ethernet 1000Base-LX Server Adapter - - SK-9842 Gigabit Ethernet 1000Base-LX Dual Port Server Adapter - - SK-9843 Gigabit Ethernet 1000Base-SX Server Adapter - - SK-9844 Gigabit Ethernet 1000Base-SX Dual Port Server Adapter - - SK-9861 Gigabit Ethernet 1000Base-SX Server Adapter - - SK-9862 Gigabit Ethernet 1000Base-SX Dual Port Server Adapter - - SK-9871 Gigabit Ethernet 1000Base-ZX Server Adapter - - SK-9872 Gigabit Ethernet 1000Base-ZX Dual Port Server Adapter - - SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter - - SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter - - SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter - - SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter - - SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter - - SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter + Say Y here if you have a Marvell Yukon or SysKonnect SK-98xx/SK-95xx + compliant Gigabit Ethernet Adapter. The following adapters are supported + by this driver: + - 3Com 3C940 Gigabit LOM Ethernet Adapter + - 3Com 3C941 Gigabit LOM Ethernet Adapter + - Allied Telesyn AT-2970LX Gigabit Ethernet Adapter + - Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter + - Allied Telesyn AT-2970SX Gigabit Ethernet Adapter + - Allied Telesyn AT-2970SX/2SC Gigabit Ethernet Adapter + - Allied Telesyn AT-2970TX Gigabit Ethernet Adapter + - Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter + - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter + - Allied Telesyn AT-2971T Gigabit Ethernet Adapter + - DGE-530T Gigabit Ethernet Adapter + - EG1032 v2 Instant Gigabit Network Adapter + - EG1064 v2 Instant Gigabit Network Adapter + - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit) + - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron) + - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus) + - Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS) + - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox) + - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn) + - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte) + - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill) + - Marvell RDK-8001 Adapter + - Marvell RDK-8002 Adapter + - Marvell RDK-8003 Adapter + - Marvell RDK-8004 Adapter + - Marvell RDK-8006 Adapter + - Marvell RDK-8007 Adapter + - Marvell RDK-8008 Adapter + - Marvell RDK-8009 Adapter + - Marvell RDK-8010 Adapter + - Marvell RDK-8011 Adapter + - Marvell RDK-8012 Adapter + - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit) + - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit) + - N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L) + - SK-9521 10/100/1000Base-T Adapter + - SK-9521 V2.0 10/100/1000Base-T Adapter + - SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T) + - SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter + - SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link) + - SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX) + - SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter + - SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link) + - SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX) + - SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter + - SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link) + - SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter + - SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition) + - SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter + - SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link) + - SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX) + - SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter + - SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) + - SMC EZ Card 1000 (SMC9452TXV.2) The adapters support Jumbo Frames. The dual link adapters support link-failover and dual port features. - The V2.0 adapters support the scatter-gather functionality with - sendfile(). Read Documentation/networking/sk98lin.txt for information about + Both Marvell Yukon and SysKonnect SK-98xx/SK-95xx adapters support + the scatter-gather functionality with sendfile(). Please refer to + Documentation/networking/sk98lin.txt for more information about optional driver parameters. Questions concerning this driver may be addressed to: linux@syskonnect.de @@ -11010,6 +11926,7 @@ say M here and read Documentation/modules.txt. This is recommended. The module will be called sk98lin.o. + Sun GEM support CONFIG_SUNGEM Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0. See also @@ -11034,6 +11951,24 @@ say M here and read . This is recommended. The module will be called tg3.o. +MV-64340 Ethernet support +CONFIG_MV64340_ETH + This driver supports the Marvell Discovery II MV64340 device + as an Ethernet controller. Say Y here and select Port 0,1,2 + as needed. Otherwise, say N. + +MV-64340 Port 0 +CONFIG_MV64340_ETH_0 + Enable port 0 on the MV64340 Ethernet controller. + +MV-64340 Port 1 +CONFIG_MV64340_ETH_1 + Enable port 1 on the MV64340 Ethernet controller. + +MV-64340 Port 2 +CONFIG_MV64340_ETH_2 + Enable port 2 on the MV64340 Ethernet controller. + MyriCOM Gigabit Ethernet support CONFIG_MYRI_SBUS This driver supports MyriCOM Sbus gigabit Ethernet cards. @@ -11496,6 +12431,28 @@ 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. + +nForce Ethernet support (EXPERIMENTAL) +CONFIG_FORCEDETH + If you have a network (Ethernet) controller of this type, say Y and + read the Ethernet-HOWTO, available from + . + + To compile this driver as a module, choose M here and read + . The module will be + called forcedeth.o. + CS89x0 support (Daynaport CS and LC cards) CONFIG_CS89x0 Support for CS89x0 chipset based Ethernet cards. If you have a @@ -11868,15 +12825,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 @@ -12315,7 +13263,6 @@ The module will be called madgemc.o. If you want to compile it as a module, say M here and read . - SMC ISA/MCA Token Ring adapter support CONFIG_SMCTR This is support for the ISA and MCA SMC Token Ring cards, @@ -12808,10 +13755,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 @@ -12872,22 +13827,49 @@ . 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'. + +MTD concatenating support +CONFIG_MTD_CONCAT + Support for concatenating several MTD devices into a single + (virtual) one. This allows you to have -for example- a JFFS(2) + file system spanning multiple physical flash chips. If unsure, + say 'Y'. + + If compiled as a module, it will be called mtdconcat.o. + ARM Firmware Suite flash layout / partition parsing CONFIG_MTD_AFS_PARTS The ARM Firmware Suite allows the user to divide flash devices into @@ -13055,6 +14037,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 @@ -13070,6 +14056,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 @@ -13134,6 +14124,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 @@ -13281,6 +14276,14 @@ D-Box 2 board. If you have one of these boards and would like to use the flash chips on it, say 'Y'. +CFI Flash devices mapped on IBM Redwood +CONFIG_MTD_REDWOOD + This enables access routines for the flash chips on the IBM + Redwood 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 redwood.o. + CFI Flash device mapped on the XScale IQ80310 board CONFIG_MTD_IQ80310 This enables access routines for the flash chips on the Intel XScale @@ -13413,6 +14416,20 @@ CONFIG_MTD_NAND_SPIA If you had to ask, you don't have one. Say 'N'. +SmartMediaCard on autronix autcpu12 board +CONFIG_MTD_NAND_AUTCPU12 + This enables the driver for the autronix autcpu12 board to + access the SmartMediaCard. + + If compiled as a module, it will be called autcpu12.o. + +Support for Cirrus Logic EBD7312 evaluation board +CONFIG_MTD_NAND_EDB7312 + This enables the driver for the Cirrus Logic EBD7312 evaluation + board to access the onboard NAND Flash. + + If compiled as a module, it will be called edb7312.o. + M-Systems Disk-On-Chip 1000 support CONFIG_MTD_DOC1000 This provides an MTD device driver for the M-Systems DiskOnChip @@ -13554,6 +14571,18 @@ . The module will be called slram.o +DEC MS02-NV NVRAM module support +CONFIG_MTD_MS02NV + This is an 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 @@ -13842,6 +14871,25 @@ The module will be called usb-ohci.o. If you want to compile it as a module, say M here and read . +SL811HS (x86, StrongARM) support +CONFIG_USB_SL811HS + Embedded Open Host Controller SL811HS from CYPRESS SEMICONDUCTOR INC. + + + Board USB1104 in i386 architecture with PC/104-bus. + + + + StrongARM is currently not testet and not for PC/104-bus! + StrongARM need a special hardware with Chip Select directly from CPU. + See also SL811HS_ALT. + +SL811HS_ALT (x86, StrongARM) support +CONFIG_USB_SL811HS_ALT + Embedded Open Host Controller SL811HS from CYPRESS SEMICONDUCTOR INC. + Alternate with isochornous mode and better interrupt handling. + See also SL811HS. + USB Human Interface Device (full HID) support CONFIG_USB_HID Say Y here if you want full HID support to connect keyboards, @@ -13899,8 +14947,8 @@ USB HIDBP Mouse (basic) support CONFIG_USB_MOUSE Say Y here only if you are absolutely sure that you don't want - to use the generic HID driver for your USB keyboard and prefer - to use the keyboard in its limited Boot Protocol mode instead. + to use the generic HID driver for your USB mouse and prefer + to use the mouse in its limited Boot Protocol mode instead. This is almost certainly not what you want. @@ -13938,11 +14986,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). @@ -13963,6 +15012,16 @@ If unsure, say Y. +HP OB600 C/CT Pop-Up Mouse +CONFIG_OBMOUSE + Only add this driver if you have an Omnibook 600C or 600CT laptop. + This driver has no probe routine and must assume ports 0x238-23b + belong to the Pop-Up mouse. Depends on CONFIG_INPUT_MOUSEDEV. + + Best is to use a module and load the obmouse driver at runtime. + Say M here and read . + + Input core support CONFIG_INPUT Say Y here if you want to enable any of the following options for @@ -14029,6 +15088,15 @@ accessible under char device 13:64+ - /dev/input/eventX in a generic way. This is the future ... +CONFIG_INPUT_UINPUT + Say Y here if you want to support user level drivers for input + subsystem accessible under char device 10:223 - /dev/input/uinput. + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called uinput.o. If you want to compile it as a + module, say M here and read . + USB Scanner support CONFIG_USB_SCANNER Say Y here if you want to connect a USB scanner to your computer's @@ -14269,6 +15337,9 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49W Say Y here to include firmware for the USA-49W converter. +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC + Say Y here to include firmware for the USA-49WLC converter. + USB ZyXEL omni.net LCD Plus Driver CONFIG_USB_SERIAL_OMNINET Say Y here if you want to use a ZyXEL omni.net LCD ISDN TA. @@ -14461,6 +15532,31 @@ The module will be called ov511.o. If you want to compile it as a module, say M here and read . +USB W996[87]CF Camera support +CONFIG_USB_W9968CF + Say Y here if you want support for cameras based on + Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips. + + This driver has an optional plugin, which is distributed as a + separate module only (released under GPL). It contains code that + allows you to use higher resolutions and framerates, and cannot + be included in the official Linux kernel for performance purposes. + At the moment the driver needs a third-party module for the CMOS + sensors, which is available on internet: it is recommended to read + for more informations and for + a list of supported cameras. + + This driver uses the Video For Linux and the I2C APIs. + You must say Y or M to both "Video For Linux" and "I2C Support" + to use this driver. Information on this API and pointers to "v4l" + programs may be found on the WWW at + . + + 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 w9968cf.o. If you want to compile it as a + module, say M here and read . + USB Communication Class Ethernet device support CONFIG_USB_CDCETHER This driver supports devices conforming to the Communication Device @@ -14932,6 +16028,99 @@ 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 . + +CONFIG_USB_GADGET + USB is a master/slave protocol, organized with one master + host (such as a PC) controlling up to 127 peripheral devices. + The USB hardware is asymmetric, which makes it easier to set up: + you can't connect two "to-the-host" connectors to each other. + + Linux can run in the host, or in the peripheral. In both cases + you need a low level bus controller driver, and some software + talking to it. Peripheral controllers are often discrete silicon, + or are integrated with the CPU in a microcontroller. The more + familiar host side controllers have names like like "EHCI", "OHCI", + or "UHCI", and are usually integrated into southbridges on PC + motherboards. + + Enable this configuration option if you want to run Linux inside + a USB peripheral device. Configure one hardware driver for your + peripheral/device side bus controller, and a "gadget driver" for + your peripheral protocol. (If you use modular gadget drivers, + you may configure more than one.) + + If in doubt, say "N" and don't enable these drivers; most people + don't have this kind of hardware (except maybe inside Linux PDAs). + +CONFIG_USB_NET2280 + NetChip 2280 is a PCI based USB peripheral controller which + supports both full and high speed USB 2.0 data transfers. + + It has six configurable endpoints, as well as endpoint zero + (for control transfers) and several endpoints with dedicated + functions. + + Say "y" to link the driver statically, or "m" to build a + dynamically linked module called "net2280" and force all + gadget drivers to also be dynamically linked. + +CONFIG_USB_ZERO + Gadget Zero is a two-configuration device. It either sinks and + sources bulk data; or it loops back a configurable number of + transfers. It also implements control requests, for "chapter 9" + conformance. The driver needs only two bulk-capable endpoints, so + it can work on top of most device-side usb controllers. It's + useful for testing, and is also a working example showing how + USB "gadget drivers" can be written. + + Make this be the first driver you try using on top of any new + USB peripheral controller driver. Then you can use host-side + test software, like the "usbtest" driver, to put your hardware + and its driver through a basic set of functional tests. + + Gadget Zero also works with the host-side "usb-skeleton" driver, + and with many kinds of host-side test software. You may need + to tweak product and vendor IDs before host software knows about + this device, and arrange to select an appropriate configuration. + + Say "y" to link the driver statically, or "m" to build a + dynamically linked module called "g_zero". + +CONFIG_USB_ETH + This driver implements Ethernet style communication, in either + of two ways: + + - The "Communication Device Class" (CDC) Ethernet Control Model. + That protocol is often avoided with pure Ethernet adapters, in + favor of simpler vendor-specific hardware, but is widely + supported by firmware for smart network devices. + + - On hardware can't implement that protocol, a simpler approach + is used, placing fewer demands on USB. + + Within the USB device, this gadget driver exposes a network device + "usbX", where X depends on what other networking devices you have. + Treat it like a two-node Ethernet link: host, and gadget. + + The Linux-USB host-side "usbnet" driver interoperates with this + driver, so that deep I/O queues can be supported. On 2.4 kernels, + use "CDCEther" instead, if you're using the CDC option. That CDC + mode should also interoperate with standard CDC Ethernet class + drivers on other host operating systems. + + Say "y" to link the driver statically, or "m" to build a + dynamically linked module called "g_ether". + 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 @@ -15246,21 +16435,15 @@ architectural foundations. In general, ReiserFS is as fast as ext2, but is very efficient with - large directories and small files. Additional patches are needed - for NFS and quotas, please see for links. - - It is more easily extended to have features currently found in - database and keyword search systems than block allocation based file - systems are. The next version will be so extended, and will support - plugins consistent with our motto ``It takes more than a license to - make source code open.'' - - Read to learn more about reiserfs. + large directories and small files. It is much faster for writes, + and slightly slower for reads than ext2. It is much faster than + ext3. It will be obsoleted by Reiser4 in not too long, so keep + an eye on our website for when Reiser4 ships. - Sponsored by Threshold Networks, Emusic.com, and Bigstorage.com. + Mount with the notail option if performance matters more to you than + saving space (the design flaw underlying this is fixed in reiser4). - If you like it, you can pay us to add new features to it that you - need, buy a support contract, or pay us to port it to another OS. + Read to learn more about reiserfs. Enable extra Reiserfs consistency checks CONFIG_REISERFS_CHECK @@ -15832,6 +17015,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 @@ -15988,7 +17195,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. @@ -16001,6 +17208,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 @@ -16179,6 +17401,80 @@ Say Y here if you want to try writing to UFS partitions. This is experimental, so you should back up your UFS partitions beforehand. +XFS filesystem support +CONFIG_XFS_FS + XFS is a high performance journaling filesystem which originated + on the SGI IRIX platform. It is completely multi-threaded, can + support large files and large filesystems, extended attributes, + variable block sizes, is extent based, and makes extensive use of + Btrees (directories, extents, free space) to aid both performance + and scalability. + + Refer to the documentation at + for complete details. This implementation is on-disk compatible + with the IRIX version of XFS. + + If you want to compile this file system 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 xfs.o. Be aware, however, that if the file + system of your root partition is compiled as a module, you'll need + to use an initial ramdisk (initrd) to boot. + +Quota support +CONFIG_XFS_QUOTA + If you say Y here, you will be able to set limits for disk usage on + a per user and/or per group basis under XFS. XFS considers quota + information as filesystem metadata and uses journaling to provide a + higher level guarantee of consistency. The on-disk data format for + quota is also compatible with the IRIX version of XFS, allowing a + filesystem to be migrated between Linux and IRIX without any need + for conversion. + + If unsure, say N. More comprehensive documentation can be found in + README.quota in the xfsprogs package. XFS quota can be used either + with or without the generic quota support enabled (CONFIG_QUOTA) - + they are completely independent subsystems. + +Realtime support (EXPERIMENTAL) +CONFIG_XFS_RT + If you say Y here you will be able to mount and use XFS filesystems + which contain a realtime subvolume. The realtime subvolume is a + separate area of disk space where only file data is stored. The + realtime subvolume is designed to provide very deterministic + data rates suitable for media streaming applications. + + See the xfs man page in section 5 for a bit more information. + + This feature is unsupported at this time, is not yet fully + functional, and may cause serious problems. + + If unsure, say N. + +Tracing support (EXPERIMENTAL) +CONFIG_XFS_TRACE + Say Y here to get an XFS build with activity tracing enabled. + Enabling this option will attach historical information to XFS + inodes, pagebufs, certain locks, the log, the IO path, and a + few other key areas within XFS. These traces can be examined + using a kernel debugger. + + Note that for the pagebuf traces, you will also have to enable + the sysctl in /proc/sys/vm/pagebuf/debug for this to work. + + Say N unless you are an XFS developer. + +Debugging support (EXPERIMENTAL) +CONFIG_XFS_DEBUG + Say Y here to get an XFS build with many debugging features, + including ASSERT checks, function wrappers around macros, + and extra sanity-checking functions in various code paths. + + Note that the resulting code will be HUGE and SLOW, and probably + not useful unless you are debugging a particular problem. + + Say N unless you are an XFS developer, or play one on TV. + Advanced partition selection CONFIG_PARTITION_ADVANCED Say Y here if you would like to use hard disks under Linux which @@ -16485,6 +17781,17 @@ smbmount from samba 2.2.0 or later supports this. +Enable Unix Extensions +CONFIG_SMB_UNIX + Enabling this will make smbfs use the CIFS Unix Extensions if + supported by the server. These extensions allows use of unix user + ids, permissions, file modes, symlinks, etc that normally do not + work on smbfs. + + Samba 3.0 servers supports these extensions. + + If you don't know what all this is about, it is safe to say Y. + Coda file system support (advanced network fs) CONFIG_CODA_FS Coda is an advanced network file system, similar to NFS in that it @@ -17172,6 +18479,24 @@ Enable this option if you intend to use a HIL keyboard. +HP System Device Controller support +CONFIG_HP_SDC + This option enables supports for the the "System Device Controller", + an i8042 carrying microcode to manage a few miscellanous devices + on some Hewlett Packard systems. The SDC itself contains a 10ms + resolution timer/clock capable of delivering interrupts on periodic + and one-shot basis. The SDC may also be connected to a battery-backed + real-time clock, a basic audio waveform generator, and an HP-HIL + Master Link Controller serving up to seven input devices. + + By itself this option is rather useless, but enabling it will + enable selection of drivers for the abovementioned devices. + It is, however, incompatible with the old, reliable HIL keyboard + driver, and the new HIL driver is experimental, so if you plan to + use a HIL keyboard as your primary keyboard, you may wish to + keep using that driver until the new HIL drivers have had more + testing. + Include IOP (IIfx/Quadra 9x0) ADB driver CONFIG_ADB_IOP The I/O Processor (IOP) is an Apple custom IC designed to provide @@ -17316,6 +18641,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 @@ -17480,6 +18812,19 @@ read . The module will be called istallion.o. +PDC software console support +CONFIG_PDC_CONSOLE + Saying Y here will enable the software based PDC console to be + used as the system console. This is useful for machines in + which the hardware based console has not been written yet. The + following steps must be competed to use the PDC console: + + 1. create the device entry (mknod /dev/ttyB0 c 60 0) + 2. Edit the /etc/inittab to start a getty listening on /dev/ttyB0 + 3. Add device ttyB0 to /etc/securetty (if you want to log on as + root on this console.) + 4. Change the kernel command console parameter to: console=ttyB0 + Microgate SyncLink adapter support CONFIG_SYNCLINK Provides support for the SyncLink ISA and PCI multiprotocol serial @@ -17777,7 +19122,7 @@ Say Y here to support the on-board sound generator on the Integrated Technology Express, Inc. ITE8172 SBC. Vendor page at ; picture of the - board at . + board at . I2C support CONFIG_I2C @@ -17846,9 +19191,9 @@ . The module will be called i2c-elv.o. -Velleman K9000 adapter +Velleman K8000 adapter CONFIG_I2C_VELLEMAN - This supports the Velleman K9000 parallel-port I2C adapter. Say Y + This supports the Velleman K8000 parallel-port I2C adapter. Say Y if you own such an adapter. This driver is also available as a module. If you want to compile @@ -17913,6 +19258,21 @@ . 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. + +SGI I2C Algorithm +CONFIG_I2C_ALGO_SGI + Supports the SGI interfaces like the ones found on SGI Indy VINO + or SGI O2 MACE. + I2C device interface CONFIG_I2C_CHARDEV Say Y here to use i2c-* device files, usually found in the /dev @@ -17934,6 +19294,15 @@ it as a module, say M here and read . The module will be called i2c-proc.o. +Powermac Keywest I2C interface +CONFIG_I2C_KEYWEST + This supports the use of the I2C interface in the combo-I/O + chip on recent Apple machines. Say Y if you have such a machine. + + This driver is also available as a module. If you want to compile + it as a module, say M here and read Documentation/modules.txt. + The module will be called i2c-keywest.o. + Bus Mouse Support CONFIG_BUSMOUSE Say Y here if your machine has a bus mouse as opposed to a serial @@ -18443,6 +19812,13 @@ selected, the module will be called i810.o. AGP support is required for this driver to work. +Intel 830M, 845G, 852GM, 855GM, 865G +CONFIG_DRM_I830 + Choose this option if you have a system that has Intel 830M, 845G, + 852GM, 855GM or 865G integrated graphics. If M is selected, the + module will be called i830.o. AGP support is required for this driver + to work. + Matrox G200/G400/G450 CONFIG_DRM_MGA Choose this option if you have a Matrox G200, G400 or G450 graphics @@ -18596,6 +19972,21 @@ If unsure, say N. +Intel/AMD/VIA HW Random Number Generator support +CONFIG_HW_RANDOM + This driver provides kernel-side support for the + Random Number Generator hardware found on Intel i8xx-based motherboards, + AMD 76x-based motherboards, and Via Nehemiah CPUs. + + Provides a character driver, used to read() entropy data. + + To compile this driver as a module ( = 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 + hw_random. + + If unsure, say N. + Power Management support CONFIG_PM "Power Management" means that parts of your computer are shut @@ -18645,10 +20036,7 @@ The ACPI Sourceforge project may also be of interest: -Enable ACPI 2.0 with errata 1.3 -CONFIG_ACPI20 - Enable support for the 2.0 version of the ACPI interpreter. See the - help for ACPI for caveats and discussion. + Note that "acpi=off" can be used to disable all ACPI code in the kernel. ACPI kernel configuration manager CONFIG_ACPI_KERNEL_CONFIG @@ -18661,23 +20049,6 @@ of verbosity. Saying Y enables these statements. This will increase your kernel size by around 50K. -ACPI Bus Manager -CONFIG_ACPI_BUSMGR - The ACPI Bus Manager enumerates devices in the ACPI namespace, and - handles PnP messages. All ACPI devices use its services, so using - them requires saying Y here. - -ACPI System Driver -CONFIG_ACPI_SYS - This driver will enable your system to shut down using ACPI, and - dump your ACPI DSDT table using /proc/acpi/dsdt. - -ACPI Processor Driver -CONFIG_ACPI_CPU - 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 Button CONFIG_ACPI_BUTTON This driver registers for events based on buttons, such as the @@ -18686,6 +20057,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 @@ -18698,16 +20083,61 @@ the battery and thermal drivers. If you are compiling for a laptop, say Y. -ACPI Control Method Battery -CONFIG_ACPI_CMBATT - This driver adds support for battery information through - /proc/acpi/battery. If you have a laptop with a battery, say Y. - ACPI Thermal CONFIG_ACPI_THERMAL 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. + + Note: the display switching code is currently considered EXPERIMENTAL, + toying with these values may even lock your machine. + + 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 @@ -19159,6 +20589,15 @@ . The module will be called cpuid.o +x86 BIOS Enhanced Disk Drive support +CONFIG_EDD + Say Y or M here if you want to enable BIOS Enhanced Disk Drive + Services real mode BIOS calls to determine which disk + BIOS tries boot from. This information is then exported via /proc. + + This option is experimental, but believed to be safe, + and most disk controller BIOS vendors do not yet implement this feature. + SBC-60XX Watchdog Timer CONFIG_60XX_WDT This driver can be used with the watchdog timer found on some @@ -19225,6 +20664,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 @@ -19975,6 +21425,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 @@ -20258,10 +21716,10 @@ DSP 16 card. Enter: 0 for Sony, 1 for Panasonic, 2 for IDE, 4 for no CD-ROM present. -C-Media PCI (CMI8338/8378) +C-Media PCI (CMI8338/8738) CONFIG_SOUND_CMPCI Say Y or M if you have a PCI sound card using the CMI8338 - or the CMI8378 chipset. Data on these chips are available at + or the CMI8738 chipset. Data on these chips are available at . A userspace utility to control some internal registers of these @@ -20601,6 +22059,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 @@ -20612,14 +22087,14 @@ This is an evaluation board based on the Galileo GT-64120 single-chip system controller that contains a MIPS R5000 compatible core running at 75/100MHz. Their website is located at - . Say Y here if you wish to build a + . Say Y here if you wish to build a kernel for this platform. Galileo EV96100 Evaluation board CONFIG_MIPS_EV96100 This is an evaluation board based on the Galielo GT-96100 LAN/WAN communications controllers containing a MIPS R5000 compatible core - running at 83MHz. Their website is . Say Y + running at 83MHz. Their website is . Say Y here if you wish to build a kernel for this platform. Support for ITE 8172G board @@ -20635,8 +22110,8 @@ This is an evaluation board built by Globespan to showcase their iVR (Internet Video Recorder) design. It utilizes a QED RM5231 R5000 MIPS core. More information can be found out their website - located at P. Say Y - here if you wish to build a kernel for this platform. + located at . Say Y here if you wish to + build a kernel for this platform. Support for Alchemy Semi PB1000 board CONFIG_MIPS_PB1000 @@ -20669,19 +22144,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 @@ -20751,6 +22219,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 @@ -21122,6 +22601,11 @@ This enables HiSax support for the HFC-S+, HFC-SP and HFC-PCMCIA cards. This code is not finished yet. +Formula-n enter:now PCI card (EXPERIMENTAL) +CONFIG_HISAX_ENTERNOW_PCI + This enables HiSax support for the Formula-n enter:now PCI + ISDN card. + Am7930 CONFIG_HISAX_AMD7930 This enables HiSax support for the AMD7930 chips on some SPARCs. @@ -21599,6 +23083,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. @@ -21653,6 +23138,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. @@ -21705,7 +23199,7 @@ kernel or say M to compile it as module (hci_usb.o). HCI USB SCO (voice) support -CONFIG_BLUEZ_USB_SCO +CONFIG_BLUEZ_HCIUSB_SCO This option enables the SCO support in the HCI USB driver. You need this to transmit voice data with your Bluetooth USB device. And your device must also support sending SCO data over the HCI layer, because some of @@ -21713,14 +23207,6 @@ Say Y here to compile support for HCI SCO data. -HCI USB zero packet support -CONFIG_BLUEZ_USB_ZERO_PACKET - This option is provided only as a work around for buggy Bluetooth USB - devices. Do NOT enable it unless you know for sure that your device - requires zero packets. - - Most people should say N here. - HCI VHCI Virtual HCI device driver CONFIG_BLUEZ_HCIVHCI Bluetooth Virtual HCI device driver. @@ -21729,6 +23215,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. @@ -21789,6 +23285,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 @@ -21837,15 +23351,22 @@ "ser_a2232.o". If you want to do this, answer M here and read "". -A4000T SCSI support -CONFIG_A4000T_SCSI - Support for the NCR53C710 SCSI controller on the Amiga 4000T. - -A4091 SCSI support -CONFIG_A4091_SCSI - Support for the NCR53C710 chip on the Amiga 4091 Z3 SCSI2 controller - (1993). Very obscure -- the 4091 was part of an Amiga 4000 upgrade - plan at the time the Amiga business was sold to DKB. +Amiga NCR53c710 SCSI support +CONFIG_SCSI_AMIGA7XX + Support for various NCR53c710-based SCSI controllers on the Amiga. + This includes: + - the builtin SCSI controller on the Amiga 4000T, + - the Amiga 4091 Zorro III SCSI-2 controller, + - the MacroSystem Development's WarpEngine Amiga SCSI-2 controller + (info at + ), + - the SCSI controller on the Phase5 Blizzard PowerUP 603e+ + accelerator card for the Amiga 1200, + - the SCSI controller on the GVP Turbo 040/060 accelerator. + Note that all of the above SCSI controllers, except for the builtin + SCSI controller on the Amiga 4000T, reside on the Zorro expansion + bus, so you also have to enable Zorro bus support if you want to use + them. Atari support CONFIG_ATARI @@ -22167,11 +23688,6 @@ 1260 accelerator, and the optional SCSI module, say Y. Otherwise, say N. -Blizzard PowerUP 603e+ SCSI support -CONFIG_BLZ603EPLUS_SCSI - If you have an Amiga 1200 with a Phase5 Blizzard PowerUP 603e+ - accelerator, say Y. Otherwise, say N. - Fastlane SCSI support CONFIG_FASTLANE_SCSI If you have the Phase5 Fastlane Z3 SCSI controller, or plan to use @@ -22182,7 +23698,7 @@ If you have the BSC Oktagon SCSI disk controller for the Amiga, say Y to this question. If you're in doubt about whether you have one, see the picture at - . + . Atari native SCSI support CONFIG_ATARI_SCSI @@ -22231,15 +23747,16 @@ want). The module is called ariadne.o. If you want to compile it as a module, say M here and read . -Ariadne II and X-Surf support -CONFIG_ARIADNE2 - This driver is for the Village Tronic Ariadne II and the Individual +Zorro NS8390-based Ethernet support +CONFIG_ZORRO8390 + This driver is for Zorro Ethernet cards using an NS8390-compatible + chipset, like the Village Tronic Ariadne II and the Individual Computers X-Surf Ethernet cards. If you have such a card, say Y. Otherwise, say N. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called ariadne2.o. If you want to compile it as + The module is called zorro8390.o. If you want to compile it as a module, say M here and read . A2065 support @@ -22570,7 +24087,7 @@ PCMCIA interface (example: IDIF860 systems) Use SMC2 for UART -CONFIG_SMC2_UART +CONFIG_8xx_SMC2 If you would like to use SMC2 as a serial port, say Y here. If in doubt, say Y here. @@ -23012,6 +24529,38 @@ /proc/sys/dev/mac_hid/mouse_button2_keycode /proc/sys/dev/mac_hid/mouse_button3_keycode +Set high memory pool address +CONFIG_HIGHMEM_START_BOOL + Unless you know what you are doing you *should not* set this option. + + It can be used to override the default PKMAP_BASE address which + is the location of the high memory pool. This can be useful in + optimizing virtual memory usage in a system. + +Set maximum low memory +CONFIG_LOWMEM_SIZE_BOOL + Unless you know what you are doing you *should not* set this option. + + It can be used to override the standard calculated value of + MAX_LOW_MEM. This can be useful in optimizing virtual memory usage + in a system. + +Set custom kernel base address +CONFIG_KERNEL_START_BOOL + Unless you know what you are doing you *should not* set this option. + + It can be used to override the standard PAGE_OFFSET/KERNELBASE + value used by the kernel. This can be useful in controlling + amount of virtual address space available to the kernel. + +Set custom user task size +CONFIG_TASK_SIZE_BOOL + Unless you know what you are doing you *should not* set this option. + + It can be used to override the standard TASK_SIZE value used + by the kernel. This can be useful in controlling amount of + virtual address space available to user tasks. + Enhanced Real Time Clock Support (/dev/rtc) CONFIG_PPC_RTC If you say Y here and create a character special file /dev/rtc with @@ -23058,6 +24607,11 @@ If unsure, say Y. +Support for Lpar Configuration data in /proc +CONFIG_LPARCFG + This option adds lparcfg entry as /proc/ppc64/lparcfg which returns + system configuration info in = pairs. + MESH (Power Mac internal SCSI) support CONFIG_SCSI_MESH Many Power Macintoshes and clones have a MESH (Macintosh Enhanced @@ -23532,8 +25086,8 @@ SGI Vino Video For Linux CONFIG_VIDEO_VINO - Say Y here to build in support for the Vino video input system found - on SGI Indy machines. + Say Y here to include support for SGI VINO (Video In No Out) system + found on SGI Indy workstations. Stradis 4:2:2 MPEG-2 video driver CONFIG_VIDEO_STRADIS @@ -23616,6 +25170,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 @@ -23889,6 +25449,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 @@ -24282,35 +25856,73 @@ Say Y if you want support for the ARM922T processor. Otherwise, say N. -Support low power wait for interrupt -CONFIG_CPU_ARM922_CPU_IDLE - Saying Y here will allow the processor to enter a low power - mode whilst waiting for an interrupt in idle. If you're unsure - say Y. +Disable instruction cache +CONFIG_CPU_ICACHE_DISABLE + Say Y here to disable the processor instruction cache. Unless + you have a reason to do this, say N. -Enable ARM922T instruction cache -CONFIG_CPU_ARM922_I_CACHE_ON - Say Y here to enable the processor instruction cache. Unless - you have a reason not to, say Y. - -Enable ARM922T data cache -CONFIG_CPU_ARM922_D_CACHE_ON - Say Y here to enable the processor data cache. Unless - you have a reason not to, say Y. +Disable data cache +CONFIG_CPU_DCACHE_DISABLE + Say Y here to disable the processor data cache. Unless + you have a reason to do this, say N. Use data cache in writethrough mode -CONFIG_CPU_ARM922_WRITETHROUGH +CONFIG_CPU_DCACHE_WRITETHROUGH Say Y here to use the data cache in writethough mode. Unless you specifically require this, say N. Support ARM1020 processor CONFIG_CPU_ARM1020 - The ARM1020 is the cached version of the ARM10 processor, + The ARM1020 is the 32K cached version of the ARM10 processor, with an addition of a floating-point unit. Say Y if you want support for the ARM1020 processor. Otherwise, say N. +Support ARM1022 processor +CONFIG_CPU_ARM1022 + The ARM1022E is the 16K cached version of the ARM10 processor, + with an addition of a floating-point unit. + + Say Y if you want support for the ARM1022 processor. + Otherwise, say N. + +Force round-robin cache line replacement +CONFIG_CPU_CACHE_ROUND_ROBIN + Say Y here to force the caches to use a round-robin + algorithm when picking a cache line to evict. Unless you + specifically require this, say N. + +Disable the write buffer +CONFIG_CPU_WB_DISABLE + Say Y here to turn off the write buffer (if possible) + Unless you specifically require this, say N. Note that + not all ARM processors allow the write buffer to be + disabled. + +Disable branch prediction +CONFIG_CPU_BPREDICT_DISABLE + The ARM10 family of processors support branch prediction, + which can significantly speed up execution of loops. + Say Y here to disable branch prediction. Unless you + specifically require this, say N. + +Compressed boot loader in ROM/flash +CONFIG_ZBOOT_ROM + Say Y here if you intend to execute your compressed kernel image (zImage) + directly from ROM or flash. If unsure, say N. + +Compressed ROM boot loader base address +CONFIG_ZBOOT_ROM_TEXT + The base address for zImage. Unless you have special requirements, you + should not change this value. + +Compressed ROM boot loader BSS address +CONFIG_ZBOOT_ROM_BSS + The base address of 64KiB of read/write memory, which must be available + while the decompressor is running. Unless you have special requirements, + you should not change this value. + Support StrongARM SA-110 processor CONFIG_CPU_SA110 The Intel StrongARM(R) SA-110 is a 32-bit microprocessor and @@ -24492,6 +26104,19 @@ output to the second serial port on these devices. Saying N will cause the debug messages to appear on the first serial port. +Kernel log buffer length shift +CONFIG_LOG_BUF_SHIFT + The kernel log buffer has a fixed size of : + 64 kB (2^16) on MULTIQUAD and IA64, + 128 kB (2^17) on S390 + 32 kB (2^15) on SMP systems + 16 kB (2^14) on UP systems + + You have the ability to change this size with this paramter which + fixes the bit shift of to get the buffer length (which must be a + power of 2). Eg: a value of 16 sets the buffer to 64 kB (2^16). + The default value of 0 uses standard values above. + Disable pgtable cache CONFIG_NO_PGT_CACHE Normally the kernel maintains a `quicklist' of preallocated @@ -24848,6 +26473,44 @@ brave people. System crashes and other bad things are likely to occur if you use this driver. If in doubt, select N. +Tieman Voyager USB Braille display support (EXPERIMENTAL) +CONFIG_USB_BRLVGER + Say Y here if you want to use the Voyager USB Braille display from + Tieman. See for more + information. + + 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 brlvger.o. If you want to compile it as + a module, say M here and read . + +KB Gear JamStudio tablet support +CONFIG_USB_KBTAB + Say Y here if you want to use the USB version of the KB Gear + JamStudio tablet. 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). + The module will be called kbtab.o. If you want to compile it as a + module, say M here and read . + +USB Inside Out Edgeport Serial Driver (TI devices) +CONFIG_USB_SERIAL_EDGEPORT_TI + Say Y here if you want to use any of the devices from Inside Out + Networks (Digi) that are not supported by the io_edgeport driver. + This includes the Edgeport/1 device. + + 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 io_ti.o. If you want to compile it + as a module, say M here and read . + +USB Keyspan MPR Firmware +CONFIG_USB_SERIAL_KEYSPAN_MPR + Say Y here to include firmware for the Keyspan MPR converter. + Winbond W83977AF IrDA Device Driver CONFIG_WINBOND_FIR Say Y here if you want to build IrDA support for the Winbond @@ -24914,6 +26577,14 @@ here and read . The module will be called smc-ircc.o. +VIA IrCC +CONFIG_VIA_IRCC_FIR + Say Y here if you want to build support for the VIA Fast Infrared + Communications Controller. It is used in all sorts of VIA686a- and + VT1211-based notebooks. If you want to compile it as a module, say M + here and read . The module will be + called via-ircc.o. + ALi M5123 FIR controller driver CONFIG_ALI_FIR Say Y here if you want to build support for the ALi M5123 FIR @@ -25892,11 +27563,13 @@ # Choice: ia64type Itanium CONFIG_ITANIUM - Select your IA64 processor type. The default is Intel Itanium. + Select your IA-64 processor type. The default is Intel Itanium. + This choice is safe for all IA-64 systems, but may not perform + optimally on systems with, say, Itanium 2 or newer processors. -McKinley +Itanium 2 CONFIG_MCKINLEY - Select this to configure for a McKinley processor. + Select this to configure for an Itanium 2 (McKinley) processor. # Choice: ia64system IA-64 system type @@ -25905,16 +27578,11 @@ will run on any supported IA-64 system. However, if you configure a kernel for your specific system, it will be faster and smaller. - To find out what type of IA-64 system you have, you may want to - check the IA-64 Linux web site at . - As of the time of this writing, most hardware is DIG compliant, - so the "DIG-compliant" option is usually the right choice. - - HP-simulator For the HP simulator (). - HP-zx1 For HP zx1 Platforms. - SN1 For SGI SN1 Platforms. - SN2 For SGI SN2 Platforms. - DIG-compliant For DIG ("Developer's Interface Guide") compliant systems. + generic For any supported IA-64 system + DIG-compliant For DIG ("Developer's Interface Guide") compliant systems + HP For HP systems + SGI-SN2 For SGI SN2 systems + Ski-simulator For the HP simulator () If you don't know what to do, choose "generic". @@ -25953,6 +27621,14 @@ Say Y here to enable machine check support for IA-64. If you're unsure, answer Y. +Use PAL_HALT_LIGHT in idle loop +CONFIG_IA64_PAL_IDLE + Say Y here to enable use of PAL_HALT_LIGHT in the cpu_idle loop. + This allows the CPU to enter a low power state when idle. You + can enable CONFIG_IA64_PALINFO and check /proc/pal/cpu0/power_info + to see the power consumption and latency for this state. If you're + unsure your firmware supports it, answer N. + Disable IA-64 Virtual Hash Page Table CONFIG_DISABLE_VHPT The Virtual Hash Page Table (VHPT) enhances virtual address @@ -25973,12 +27649,31 @@ and restore instructions. It's useful for tracking down spinlock problems, but slow! If you're unsure, select N. -Early printk support (requires VGA!) +Early printk support CONFIG_IA64_EARLY_PRINTK - Selecting this option uses the VGA screen for printk() output before - the consoles are initialised. It is useful for debugging problems - early in the boot process, but only if you have a VGA screen - attached. If you're unsure, select N. + Selecting this option uses a UART or VGA screen (or both) for + printk() output before the consoles are initialised. It is useful + for debugging problems early in the boot process, but only if you + have a serial terminal or a VGA screen attached. If you're unsure, + select N. + +Early printk on serial port +CONFIG_IA64_EARLY_PRINTK_UART + Select this option to use a serial port for early printk() output. + You must also select either CONFIG_IA64_EARLY_PRINTK_UART_BASE or + CONFIG_SERIAL_HCDP. If you select CONFIG_SERIAL_HCDP, early + printk() output will appear on the first console device described by + the HCDP. If you set CONFIG_IA64_EARLY_PRINTK_UART_BASE, the HCDP + will be ignored. + +UART base address +CONFIG_IA64_EARLY_PRINTK_UART_BASE + The physical MMIO address of the UART to use for early printk(). + This overrides any UART located using the EFI HCDP table. + +Early printk on VGA +CONFIG_IA64_EARLY_PRINTK_VGA + Select this option to use VGA for early printk() output. Print possible IA64 hazards to console CONFIG_IA64_PRINT_HAZARDS @@ -26003,6 +27698,58 @@ To use this option, you have to check that the "/proc file system support" (CONFIG_PROC_FS) is enabled, too. +PPC4xx DMA controller support +CONFIG_PPC4xx_DMA + Select this to enable support for the PPC4xx general purpose DMA + controller. + +ttyS0 device +CONFIG_UART0_TTYS0 + This option reverses the mapping between the hardware UART and software + device. Selecting UART0 gives the normal mapping of UART0=ttyS0 and + UART1=ttyS1. Selecting UART1 gives the reverse mapping of UART0=ttyS1 + and UART1=ttyS0. Most people will use UART0. + +PowerPC 405 on-chip ethernet +CONFIG_IBM_OCP_ENET + If you want to use the 405 built-in ethernet select this. + +CONFIG_IBM_OCP_ENET_ERROR_MSG + Enable this option to print verbose debug messages for troubleshooting. + +PowerPC 405 on-chip ethernet -- Number of receive buffers +CONFIG_IBM_OCP_ENET_RX_BUFF + Number of ethernet receive (read) buffers. Unless you know what you + are doing the default should be fine. + +PowerPC 405 on-chip ethernet -- Number of transmit buffers +CONFIG_IBM_OCP_ENET_TX_BUFF + Number of ethernet transmit (write) buffers. Unless you know what + you are doing the default should be fine. + +PowerPC 405 on-chip ethernet -- Amount of bytes to Reserve on a skb +CONFIG_IBM_OCP_ENET_SKB_RES + Many standard ethernet drivers need to reserve 2 bytes of data + on the skb before giving the data ptr to the hardware. This is + so the IP data will be 16-byte aligned when it goes up the stack. + This is a requirement for some processors and it can cause major + slow downs on others. The 405GP dose not have problems with the + misaligned data so the default is 0. If you need to route the + incoming ethernet packets to another device that has alignment + requirements this can help remove a data copy. A value of 2 can + help at getting 16-byte aligned IP data for another device. A + larger value can be used when routing to a IP tunnel device. + Make sure XXX_DESC_SIZE - XXX_SKB_RES >= 1514, or larger if VLANS + are used. + +PPC 405 I2C Algorithm +CONFIG_PPC405_I2C_ALGO + Enable this option to use the built-in I2C on your 405. + +PPC 405 I2C Adapter +CONFIG_PPC405_I2C_ADAP + Enable this option to use the built-in I2C on your 405. + /proc/efi/vars support CONFIG_EFI_VARS If you say Y here, you are able to get EFI (Extensible Firmware @@ -26095,6 +27842,11 @@ best used in conjunction with the NMI watchdog so that spinlock deadlocks are also debuggable. +Additional run-time checks +CONFIG_CHECKING + Enables some internal consistency checks for kernel debugging. + You should normally say N. + Read-write spinlock debugging CONFIG_DEBUG_RWLOCK If you say Y here then read-write lock processing will count how many @@ -26117,7 +27869,7 @@ Include kgdb kernel debugger CONFIG_KGDB Include in-kernel hooks for kgdb, the Linux kernel source level - debugger. This project has a web page at + debugger. For i386 architecture there is project page at . Include xmon kernel debugger @@ -26230,6 +27982,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 . @@ -26283,6 +28038,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. @@ -26330,6 +28090,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 @@ -26359,6 +28127,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 @@ -26373,6 +28147,35 @@ CONFIG_CPU_SUBTYPE_SH7750 Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU. +SH7751 +CONFIG_CPU_SUBTYPE_SH7751 + Select SH7751 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 @@ -26513,7 +28316,7 @@ Say Y here to support the on-board IDE controller on the Integrated Technology Express, Inc. ITE8172 SBC. Vendor page at ; picture of the - board at . + board at . Support ARM926T processor CONFIG_CPU_ARM926T @@ -26681,21 +28484,21 @@ Say Y here to support the older, Revision C version of the Integrated Technology Express, Inc. ITE8172 SBC. Vendor page at ; picture of the - board at . + board at . Enable Smart Card Reader 0 Support CONFIG_IT8172_SCR0 Say Y here to support smart-card reader 0 (SCR0) on the Integrated Technology Express, Inc. ITE8172 SBC. Vendor page at ; picture of the - board at . + board at . Enable Smart Card Reader 1 Support CONFIG_IT8172_SCR1 Say Y here to support smart-card reader 1 (SCR1) on the Integrated Technology Express, Inc. ITE8172 SBC. Vendor page at ; picture of the - board at . + board at . IT8172 IDE Tuning support CONFIG_IT8172_TUNING @@ -26717,6 +28520,12 @@ If unsure, say N. +Hotplug firmware loading support (EXPERIMENTAL) +CONFIG_FW_LOADER + This option is provided for the case where no in-kernel-tree modules require + hotplug firmware loading support, but a module built outside the kernel tree + does. + NatSemi SCx200 support CONFIG_SCx200 This provides basic support for the National Semiconductor SCx200 @@ -26727,6 +28536,14 @@ This support is also available as a module. If compiled as a module, it will be called scx200.o. +NatSemi SCx200 GPIO support +CONFIG_SCx200_GPIO + Give userspace access to the GPIO pins on the National + Semiconductor SCx200 processors. + + This support is also available as a module. If compiled as a + module, it will be called scx200_gpio.o. + NatSemi SCx200 Watchdog CONFIG_SCx200_WDT Enable the built-in watchdog timer support on the National @@ -26743,8 +28560,142 @@ 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 +CONFIG_SCx200_I2C Enable the use of two GPIO pins of a SCx200 processor as an I2C bus. If you don't know what to do here, say N. @@ -26801,6 +28752,222 @@ 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. + +Chassis LCD and LED support +CONFIG_CHASSIS_LCD_LED + Say Y here if you want to enable support for the Heartbeat, + Disk/Network activities LEDs on some PA-RISC machines, + or support for the LCD that can be found on recent material. + + This has nothing to do with LED State support for A, J and E class. + + If unsure, say Y. + +VSC/GSC/HSC bus support +CONFIG_GSC + The VSC, GSC and HSC busses were used from the earliest 700-series + workstations up to and including the C360/J2240 workstations. They + were also used in servers from the E-class to the K-class. They + are not found in B1000, C3000, J5000, A500, L1000, N4000 and upwards. + If in doubt, say "Y". + +Wax I/O support +CONFIG_GSC_WAX + Say Y here to support the Wax multifunction chip found in some + older systems, including B/C/D/R class and 715/64, 715/80 and + 715/100. Wax includes an EISA adapter, a serial port (not always + used), a HIL interface chip and is also known to be used as the + GSC bridge for an X.25 GSC card. + +GSCtoPCI/Dino PCI support +CONFIG_GSC_DINO + Say Y here to support the Dino & Cujo GSC to PCI bridges found in + machines from the B132 to the C360, the J2240 and the A180. Some + GSC/HSC cards (eg gigabit & dual 100 Mbit Ethernet) have a Dino on + the card, and you also need to say Y here if you have such a card. + Note that Dino also supplies one of the serial ports on certain + machines. If in doubt, say Y. + +HPET timers +CONFIG_HPET_TIMER + Use the IA-PC HPET (High Precision Event Timer) to manage + time in preference to the PIT and RTC, if a HPET is + present. The HPET provides a stable time base on SMP + systems, unlike the RTC, but it is more expensive to access, + as it is off-chip. You can find the HPET spec at + . + + If unsure, say Y. + +IOMMU support +CONFIG_GART_IOMMU + Support the K8 IOMMU. Needed to run systems with more than 4GB of memory + properly with 32-bit PCI devices that do not support DAC (Double Address + Cycle). The IOMMU can be turned off at runtime with the iommu=off parameter. + Normally the kernel will take the right choice by itself. + If unsure say Y + +Debug __init statements +CONFIG_INIT_DEBUG + Fill __init and __initdata at the end of boot. This helps debugging + invalid uses of __init and __initdata after initialization. + +Force IOMMU to on +CONFIG_IOMMU_DEBUG + Force the IOMMU to on even when you have less than 4GB of memory and add + debugging code. + Can be disabled at boot time with iommu=noforce. + +IOMMU leak tracing +CONFIG_IOMMU_LEAK + Add a simple leak tracer to the IOMMU code. This is useful when you + are debugging a buggy device driver that leaks IOMMU mappings. + +pSeries Hypervisor Virtual Console support +CONFIG_HVC_CONSOLE + pSeries machines when partitioned support a hypervisor virtual + console. This driver allows each pSeries partition to have a console + which is accessed via the HMC. + +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_CAST5 + CAST5 (CAST-128) cipher algorithm. + + The CAST5 encryption algorithm (synonymous with CAST-128) is + described in RFC2144. + +CONFIG_CRYPTO_CAST6 + CAST6 (CAST-256) cipher algorithm. + + The CAST6 encryption algorithm (synonymous with CAST-256) is + described in RFC2612. + +CONFIG_CRYPTO_ARC4 + ARC4 cipher algorithm. + + This is a stream cipher using keys ranging from 8 bits to 2048 + bits in length. ARC4 is commonly used in protocols such as WEP + and SSL. + +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. + +CONFIG_SOUND_WM97XX + Say Y here to support the Wolfson WM9705 and WM9712 touchscreen + controllers. These controllers are mainly found in PDA's + i.e. Dell Axim and Toshiba e740 + + This is experimental code. + Please see Documentation/wolfson-touchscreen.txt for + a complete list of parameters. + + In order to use this driver, a char device called wm97xx with a major + number of 10 and minor number 16 will have to be created under + /dev/touchscreen. + + e.g. + mknod /dev/touchscreen/wm97xx c 10 16 + + 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. The module will be called ac97_plugin_wm97xx.o. + + If unsure, say N. + # # A couple of things I keep forgetting: # capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet, Index: Documentation/README.nsp_cs.eng =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/README.nsp_cs.eng,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/README.nsp_cs.eng 22 Jul 2004 19:50:27 -0000 1.1 +++ Documentation/README.nsp_cs.eng 4 Aug 2004 01:33:01 -0000 1.2 @@ -8,8 +8,8 @@ for Linux. 2. My Linux environment -Linux kernel: 2.4.7 / 2.2.19 -pcmcia-cs: 3.1.27 +Linux kernel: 2.4.20 / 2.5.63 +pcmcia-cs: 3.1.33 gcc: gcc-2.95.4 PC card: I-O data PCSC-F (NinjaSCSI-3) I-O data CBSC-II in 16 bit mode (NinjaSCSI-32Bi) @@ -46,22 +46,16 @@ $ make config ... -[3] If you use this driver with Kernel 2.2, Unpack pcmcia-cs in some directory - and make & install. This driver requies pcmcia-cs header file. -$ cd /usr/src -$ tar zxvf cs-pcmcia-cs-3.x.x.tar.gz -... - -[4] Extract this driver's archive somewhere, and edit Makefile, then do make. +[3] Extract this driver's archive somewhere, and edit Makefile, then do make. $ tar -zxvf nsp_cs-x.x.tar.gz $ cd nsp_cs-x.x $ emacs Makefile ... $ make -[5] Copy nsp_cs.o to suitable plase, like /lib/modules//pcmcia/ . +[4] Copy nsp_cs.o to suitable plase, like /lib/modules//pcmcia/ . -[6] Add these lines to /etc/pcmcia/config . +[5] Add these lines to /etc/pcmcia/config . If you yse pcmcia-cs-3.1.8 or later, we can use "nsp_cs.conf" file. So, you don't need to edit file. Just copy to /etc/pcmcia/ . @@ -97,7 +91,7 @@ bind "nsp_cs" ------------------------------------- -[7] Start (or restart) pcmcia-cs. +[6] Start (or restart) pcmcia-cs. # /etc/rc.d/rc.pcmcia start (BSD style) or # /etc/init.d/pcmcia start (SYSV style) @@ -113,8 +107,7 @@ your data. Please backup your data when you use this driver. 6. Known Bugs - In 2.4 kernel, you can't use 640MB Optical disk. This error comes from -high level SCSI driver. + Many bugs in this driver. Be careful! 7. Testing Please send me some reports(bug reports etc..) of this software. @@ -127,4 +120,4 @@ See GPL. -2001/08/08 yokota@netlab.is.tsukuba.ac.jp +2002/01/17 yokota@netlab.is.tsukuba.ac.jp Index: Documentation/SubmittingDrivers =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/SubmittingDrivers,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/SubmittingDrivers 22 Jul 2004 19:50:28 -0000 1.1 +++ Documentation/SubmittingDrivers 4 Aug 2004 01:33:01 -0000 1.2 @@ -35,12 +35,12 @@ Linux 2.4: The same rules apply as 2.2. The final contact point for Linux 2.4 - submissions is Marcelo Tosatti . + submissions is Marcelo Tosatti . Linux 2.5: The same rules apply as 2.4 except that you should follow linux-kernel to track changes in API's. The final contact point for Linux 2.5 - submissions is Linus Torvalds . + submissions is Linus Torvalds . What Criteria Determine Acceptance ---------------------------------- Index: Documentation/cciss.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/cciss.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/cciss.txt 22 Jul 2004 19:50:27 -0000 1.1 +++ Documentation/cciss.txt 4 Aug 2004 01:33:01 -0000 1.2 @@ -12,6 +12,8 @@ * SA 641 * SA 642 * SA 6400 + * SA 6400 U320 Expansion Module + * SA 6i If nodes are not already created in the /dev/cciss directory @@ -52,6 +54,56 @@ /dev/cciss/c1d1p2 Controller 1, disk 1, partition 2 /dev/cciss/c1d1p3 Controller 1, disk 1, partition 3 +Support for more than 8 controllers +----------------------------------- +Originally the driver only supports 8 controllers in the system, +and this is due to the major numbers assigned to the driver +(104 thru 111). + +The driver can now support up to 32 controllers in the system. + +For the ninth controller and beyond, the major numbers will be +assigned dynamically by the kernel when it is discovered, +and there is no guarantee what the major number you will get, +but most likely it will start from 254 and goes down from there. + +You can check the assigned major numbers by typing + cat /proc/devices +And look for cciss controllers + +Once you have this, you need to create device nodes in +/dev/cciss directory. The nodes for the first 8 controllers +should already be created by mkdev.cciss script or +/etc/makedev.d/cciss script. You can add the major number(s) +in those scripts, or create the nodes manually by using +the mknod command. + +You can also use mknod_dyn.cciss and rmnod_dyn.cciss scripts +to create or remove nodes easily. These scripts can be found +in the Documentation directory. + +Then you can mount the devices and create partitions +(You also need to make nodes for these partitions). + +As for the minor number, the disk device will have a minor +number divisible by 16 (e.g: 0, 16, 32 etc), and the +partitions on those disk devices will have the minor number +of the disk device plus the partition number (1-15). +For example, disk d2 will have minor number 32, and its +partitions 1 and 2 will have minor numbers 33 and 34. + +Look at the mkdev.cciss script for example. + +Note: + In 2.4 kernel, partition names are hard coded in + /usr/src/linux/fs/partitions/check.c + and only for the first 8 cciss controllers. The rest + will be reported as ccissXX. This should not affect + I/O operation or performance. Please apply the + cciss_2.4_partition_name.patch to address this. This + will not be an issue under 2.5 kernel, since partition + names will be handled by the driver. + SCSI tape drive and medium changer support ------------------------------------------ @@ -126,3 +178,55 @@ access these devices too, as if the array controller were merely a SCSI controller in the same way that we are allowing it to access SCSI tape drives. +Monitor Threads +--------------- + +For multipath configurations (acheived via a higher level driver, such +as the "md" driver) it is important that failure of a controller is detected. +Ordinarily, the driver is entirely interrupt driven. If a failure occurs +in such a way that the processor cannot receive interrupts from an adapter, +the driver will wait forever for i/o's to complete. In a multipath +configuration this is undesirable, as the md driver relies on i/o's being +reported as failed by the low level driver to trigger failing over to an +alternate controller. The monitor threads allow the driver to detect such +situations and report outstanding i/o's as having failed so that recovery +actions such switching to an alternate controller can occur. The monitor +threads periodically sends a trivial "no-operation" command down to +the controllers and expect them to complete within a a reasonable (short) +time period. The firmware on the adapter is designed such that no matter +how busy the adapter is serving i/o, it can respond quickly to a +"no-operation" command. In the event that a deadline elapses before a no +operation command completes, all outstanding commands on that controller +are reported back to the upper layers as having failed, and any new commands +sent to the controller are immediately reported back as failed. + +To enable the monitor threads, the compile time option must be enabled +(via the usual linux kernel configuration) and the monitor thread must +be enabled at runtime as well. A system may have many adapters, but +perhaps only a single pair operating in a multipath configuration. +In this way, it is possible to run monitoring threads only for those +adapters which require it. + +To start a monitoring thread on the first cciss adapter, "cciss0" with +a polling interval of 30 seconds, execute the following command: + + echo "monitor 30" > /proc/driver/cciss/cciss0 + +To change the polling interval, to say, 60 seconds: + + echo "monitor 60" > /proc/driver/cciss/cciss0 + +(Note, the change will not take effect until the previous polling +interval elapses.) + +To disable the monitoring thread, set the polling interval to 0 seconds: + + echo "monitor 0" > /proc/driver/cciss/cciss0 + +(Again, the monitoring thread will not exit until the previous polling +interval elapses.) + +The minimum monitoring period is 10 seconds, and the maximum monitoring +period is 3600 seconds (1 hour). The no-operation command must complete +with 5 seconds of submission in all cases or the controller will be presumed +failed. Index: Documentation/devices.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/devices.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/devices.txt 22 Jul 2004 19:50:27 -0000 1.1 +++ Documentation/devices.txt 4 Aug 2004 01:33:01 -0000 1.2 @@ -419,6 +419,7 @@ 220 = /dev/mptctl Message passing technology (MPT) control 221 = /dev/mvista/hssdsi Montavista PICMG hot swap system driver 222 = /dev/mvista/hasi Montavista PICMG high availability + 223 = /dev/input/uinput User level driver support for input 240-255 Reserved for local use 11 char Raw keyboard device @@ -2531,17 +2532,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 Index: Documentation/ioctl-number.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/ioctl-number.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/ioctl-number.txt 22 Jul 2004 19:50:27 -0000 1.1 +++ Documentation/ioctl-number.txt 4 Aug 2004 01:33:01 -0000 1.2 @@ -171,10 +171,6 @@ 0xA0 all linux/sdp/sdp.h Industrial Device Project -0xA2 00-0F DVD decoder driver in development: - -0xA3 00-1F Philips SAA7146 dirver in development: - 0xA3 80-8F Port ACL in development: 0xA3 90-9F linux/dtlk.h Index: Documentation/kernel-parameters.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/kernel-parameters.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/kernel-parameters.txt 22 Jul 2004 19:50:27 -0000 1.1 +++ Documentation/kernel-parameters.txt 4 Aug 2004 01:33:01 -0000 1.2 @@ -69,9 +69,25 @@ 53c7xx= [HW,SCSI] Amiga SCSI controllers. acpi= [HW,ACPI] Advanced Configuration and Power Interface + 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. + strict Be less tolerant of platforms that are not + strictly ACPI specification compliant. + + acpi_sci= [HW,ACPI] ACPI System Control Interrupt trigger mode + Format: { level | edge | high | low } + + acpi_irq_balance ACPI will balance active IRQs + acpi_irq_nobalance ACPI will not move active IRQs + acpi_irq_pci= If irq_balance, Clear listed IRQs for use by PCI + acpi_irq_isa= If irq_balance, Mark listed IRQs used by ISA + + acpi_osi= [HW,ACPI] empty param disables _OSI + + acpi_serialize [HW,ACPI] force serialization of AML methods - acpismp=force [IA-32] Early setup parse and use ACPI SMP table. - ad1816= [HW,SOUND] ad1848= [HW,SOUND] @@ -276,6 +292,8 @@ keepinitrd [HW, ARM] + lapic [IA-32,APIC] Enable the local APIC even if BIOS disabled it. + load_ramdisk= [RAM] List of ramdisks to load from floppy. lockd.udpport= [NFS] @@ -341,6 +359,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 +423,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 @@ -402,6 +430,8 @@ nointroute [IA-64] + nolapic [IA-32,APIC] Do not enable or use the local APIC. + no-scroll [VGA] nosmp [SMP] Tells an SMP kernel to act as a UP kernel. @@ -491,7 +521,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. Index: Documentation/nmi_watchdog.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/nmi_watchdog.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/nmi_watchdog.txt 22 Jul 2004 19:50:27 -0000 1.1 +++ Documentation/nmi_watchdog.txt 4 Aug 2004 01:33:01 -0000 1.2 @@ -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" Index: Documentation/pci.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/pci.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/pci.txt 22 Jul 2004 19:50:27 -0000 1.1 +++ Documentation/pci.txt 4 Aug 2004 01:33:01 -0000 1.2 @@ -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). Index: Documentation/sonypi.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/sonypi.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/sonypi.txt 22 Jul 2004 19:50:27 -0000 1.1 +++ Documentation/sonypi.txt 4 Aug 2004 01:33:01 -0000 1.2 @@ -8,7 +8,9 @@ Copyright (C) 2000 Andrew Tridgell This driver enables access to the Sony Programmable I/O Control Device which -can be found in many (all ?) Sony Vaio laptops. +can be found in many Sony Vaio laptops. Some newer Sony laptops (seems to be +limited to new FX series laptops, at least the FX501 and the FX702) lack a +sonypi device and are not supported at all by this driver. It will give access (through a user space utility) to some events those laptops generate, like: @@ -96,6 +98,7 @@ SONYPI_THUMBPHRASE_MASK 0x0200 SONYPI_MEYE_MASK 0x0400 SONYPI_MEMORYSTICK_MASK 0x0800 + SONYPI_BATTERY_MASK 0x1000 useinput: if set (which is the default) jogdial events are forwarded to the input subsystem as mouse wheel @@ -130,7 +133,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. Index: Documentation/sysrq.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/sysrq.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/sysrq.txt 22 Jul 2004 19:50:27 -0000 1.1 +++ Documentation/sysrq.txt 4 Aug 2004 01:33:01 -0000 1.2 @@ -1,6 +1,6 @@ Linux Magic System Request Key Hacks Documentation for sysrq.c version 1.15 -Last update: $Date: 2004/07/22 19:50:27 $ +Last update: $Date: 2004/08/04 01:33:01 $ * What is the magic SysRq key? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Index: Documentation/zorro.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/zorro.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/zorro.txt 22 Jul 2004 19:50:27 -0000 1.1 +++ Documentation/zorro.txt 4 Aug 2004 01:33:02 -0000 1.2 @@ -2,7 +2,7 @@ ---------------------------------------- Written by Geert Uytterhoeven -Last revised: February 27, 2000 +Last revised: September 5, 2003 1. Introduction @@ -77,7 +77,7 @@ The treatment of these regions depends on the type of Zorro space: - Zorro II address space is always mapped and does not have to be mapped - explicitly using ioremap(). + explicitly using z_ioremap(). Conversion from bus/physical Zorro II addresses to kernel virtual addresses and vice versa is done using: @@ -85,22 +85,20 @@ virt_addr = ZTWO_VADDR(bus_addr); bus_addr = ZTWO_PADDR(virt_addr); - - Zorro III address space must be mapped explicitly using ioremap() first + - Zorro III address space must be mapped explicitly using z_ioremap() first before it can be accessed: - virt_addr = ioremap(bus_addr, size); + virt_addr = z_ioremap(bus_addr, size); ... - iounmap(virt_addr); + z_iounmap(virt_addr); 5. References ------------- linux/include/linux/zorro.h -linux/include/linux/ioport.h -linux/include/asm-m68k/io.h -linux/include/asm-m68k/amigahw.h -linux/include/asm-ppc/io.h +linux/include/asm-{m68k,ppc}/zorro.h +linux/include/linux/zorro_ids.h linux/drivers/zorro /proc/bus/zorro Index: Documentation/arm/SA1100/CERF =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/arm/SA1100/CERF,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/arm/SA1100/CERF 22 Jul 2004 19:50:28 -0000 1.1 +++ Documentation/arm/SA1100/CERF 4 Aug 2004 01:33:02 -0000 1.2 @@ -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 - Index: Documentation/cdrom/aztcd =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/cdrom/aztcd,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/cdrom/aztcd 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/cdrom/aztcd 4 Aug 2004 01:33:02 -0000 1.2 @@ -1,4 +1,4 @@ -$Id: aztcd,v 1.1 2004/07/22 19:50:29 joff Exp $ +$Id: aztcd,v 1.2 2004/08/04 01:33:02 joff Exp $ Readme-File /usr/src/Documentation/cdrom/aztcd for AZTECH CD-ROM CDA268-01A, ORCHID CD-3110, Index: Documentation/cdrom/cdrom-standard.tex =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/cdrom/cdrom-standard.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/cdrom/cdrom-standard.tex 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/cdrom/cdrom-standard.tex 4 Aug 2004 01:33:02 -0000 1.2 @@ -1,5 +1,5 @@ \documentclass{article} -\def\version{$Id: cdrom-standard.tex,v 1.1 2004/07/22 19:50:29 joff Exp $} +\def\version{$Id: cdrom-standard.tex,v 1.2 2004/08/04 01:33:02 joff Exp $} \newcommand{\newsection}[1]{\newpage\section{#1}} \evensidemargin=0pt Index: Documentation/cris/README =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/cris/README,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/cris/README 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/cris/README 4 Aug 2004 01:33:02 -0000 1.2 @@ -1,6 +1,6 @@ Linux 2.4 on the CRIS architecture ================================== -$Id: README,v 1.1 2004/07/22 19:50:29 joff Exp $ +$Id: README,v 1.2 2004/08/04 01:33:02 joff Exp $ This is a port of Linux 2.4 to Axis Communications ETRAX 100LX embedded network CPU. For more information about CRIS and ETRAX please see further @@ -103,7 +103,7 @@ ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000 Axis Communications AB eth0 initialized eth0: changed MAC to 00:40:8C:CD:00:00 -ETRAX 100LX serial-driver $Revision: 1.1 $, (c) 2000 Axis Communications AB +ETRAX 100LX serial-driver $Revision: 1.2 $, (c) 2000 Axis Communications AB ttyS0 at 0xb0000060 is a builtin UART with DMA ttyS1 at 0xb0000068 is a builtin UART with DMA ttyS2 at 0xb0000070 is a builtin UART with DMA @@ -133,7 +133,7 @@ Hostname is bbox1 Telnetd starting, using port 23. using /bin/sash as shell. -sftpd[15]: sftpd $Revision: 1.1 $ starting up +sftpd[15]: sftpd $Revision: 1.2 $ starting up Index: Documentation/fb/README-sstfb.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/fb/README-sstfb.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/fb/README-sstfb.txt 22 Jul 2004 19:50:28 -0000 1.1 +++ Documentation/fb/README-sstfb.txt 4 Aug 2004 01:33:02 -0000 1.2 @@ -170,5 +170,5 @@ Ghozlane Toumi -$Date: 2004/07/22 19:50:28 $ +$Date: 2004/08/04 01:33:02 $ http://sstfb.sourceforge.net/README Index: Documentation/fb/pvr2fb.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/fb/pvr2fb.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/fb/pvr2fb.txt 22 Jul 2004 19:50:28 -0000 1.1 +++ Documentation/fb/pvr2fb.txt 4 Aug 2004 01:33:02 -0000 1.2 @@ -1,4 +1,4 @@ -$Id: pvr2fb.txt,v 1.1 2004/07/22 19:50:28 joff Exp $ +$Id: pvr2fb.txt,v 1.2 2004/08/04 01:33:02 joff Exp $ What is pvr2fb? =============== Index: Documentation/fb/tgafb.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/fb/tgafb.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/fb/tgafb.txt 22 Jul 2004 19:50:28 -0000 1.1 +++ Documentation/fb/tgafb.txt 4 Aug 2004 01:33:02 -0000 1.2 @@ -1,4 +1,4 @@ -$Id: tgafb.txt,v 1.1 2004/07/22 19:50:28 joff Exp $ +$Id: tgafb.txt,v 1.2 2004/08/04 01:33:02 joff Exp $ What is tgafb? =============== Index: Documentation/fb/vesafb.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/fb/vesafb.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/fb/vesafb.txt 22 Jul 2004 19:50:28 -0000 1.1 +++ Documentation/fb/vesafb.txt 4 Aug 2004 01:33:02 -0000 1.2 @@ -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! Index: Documentation/filesystems/00-INDEX =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/filesystems/00-INDEX,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/filesystems/00-INDEX 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/filesystems/00-INDEX 4 Aug 2004 01:33:02 -0000 1.2 @@ -48,3 +48,5 @@ - info on using the VFAT filesystem used in Windows NT and Windows 95 vfs.txt - Overview of the Virtual File System +xfs.txt + - info and mount options for the XFS filesystem. Index: Documentation/filesystems/befs.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/filesystems/befs.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/filesystems/befs.txt 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/filesystems/befs.txt 4 Aug 2004 01:33:02 -0000 1.2 @@ -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. Index: Documentation/filesystems/jfs.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/filesystems/jfs.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/filesystems/jfs.txt 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/filesystems/jfs.txt 4 Aug 2004 01:33:02 -0000 1.2 @@ -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: @@ -23,6 +23,19 @@ read-write. The resize keyword with no value will grow the volume to the full size of the partition. +nointegrity Do not write to the journal. The primary use of this option + is to allow for higher performance when restoring a volume + from backup media. The integrity of the volume is not + guaranteed if the system abnormally abends. + +integrity Default. Commit metadata changes to the journal. Use this + option to remount a volume where the nointegrity option was + previously specified in order to restore normal behavior. + +errors=continue Keep going on a filesystem error. +errors=remount-ro Default. Remount the filesystem read-only on an error. +errors=panic Panic and halt the machine if an error occurs. + JFS TODO list: Plans for our near term development items Index: Documentation/filesystems/sysv-fs.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/filesystems/sysv-fs.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/filesystems/sysv-fs.txt 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/filesystems/sysv-fs.txt 4 Aug 2004 01:33:02 -0000 1.2 @@ -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 Index: Documentation/filesystems/tmpfs.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/filesystems/tmpfs.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/filesystems/tmpfs.txt 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/filesystems/tmpfs.txt 4 Aug 2004 01:33:02 -0000 1.2 @@ -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 Index: Documentation/i2c/dev-interface =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/i2c/dev-interface,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/i2c/dev-interface 22 Jul 2004 19:50:28 -0000 1.1 +++ Documentation/i2c/dev-interface 4 Aug 2004 01:33:03 -0000 1.2 @@ -87,7 +87,7 @@ ioctl(file,I2C_TENBIT,long select) Selects ten bit addresses if select not equals 0, selects normal 7 bit - addresses if select equals 0. + addresses if select equals 0. Default 0. ioctl(file,I2C_FUNCS,unsigned long *funcs) Gets the adapter functionality and puts it in *funcs. Index: Documentation/i2c/i2c-protocol =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/i2c/i2c-protocol,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/i2c/i2c-protocol 22 Jul 2004 19:50:28 -0000 1.1 +++ Documentation/i2c/i2c-protocol 4 Aug 2004 01:33:03 -0000 1.2 @@ -52,10 +52,10 @@ We have found some I2C devices that needs the following modifications: Flag I2C_M_NOSTART: - In a combined transaction, no 'S Addr' is generated at some point. - For example, setting I2C_M_NOSTART on the second partial message + In a combined transaction, no 'S Addr Wr/Rd [A]' is generated at some + point. For example, setting I2C_M_NOSTART on the second partial message generates something like: - S Addr Rd [A] [Data] NA Wr [A] Data [A] P + S Addr Rd [A] [Data] NA Data [A] P If you set the I2C_M_NOSTART variable for the first partial message, we do not generate Addr, but we do generate the startbit S. This will probably confuse all other clients on your bus, so don't try this. @@ -65,4 +65,3 @@ need to emit an Rd instead of a Wr, or vice versa, you set this flag. For example: S Addr Rd [A] Data [A] Data [A] ... [A] Data [A] P - Index: Documentation/i2c/smbus-protocol =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/i2c/smbus-protocol,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/i2c/smbus-protocol 22 Jul 2004 19:50:28 -0000 1.1 +++ Documentation/i2c/smbus-protocol 4 Aug 2004 01:33:03 -0000 1.2 @@ -1,3 +1,10 @@ +SMBus Protocol Summary +====================== +The following is a summary of the SMBus protocol. It applies to +all revisions of the protocol (1.0, 1.1, and 2.0). +Certain protocol features which are not supported by +this package are briefly described at the end of this document. + Some adapters understand only the SMBus (System Management Bus) protocol, which is a subset from the I2C protocol. Fortunately, many devices use only the same subset, which makes it possible to put them on an SMBus. @@ -6,7 +13,7 @@ I2C protocol). This makes it possible to use the device driver on both SMBus adapters and I2C adapters (the SMBus command set is automatically translated to I2C on I2C adapters, but plain I2C commands can not be -handled at all on a pure SMBus adapter). +handled at all on most pure SMBus adapters). Below is a list of SMBus commands. @@ -54,7 +61,7 @@ This is the reverse of Read Byte: it sends a single byte to a device. See Read Byte for more information. -S Addr Wr [A] Data NA P +S Addr Wr [A] Data [A] P SMBus Read Byte Data @@ -109,7 +116,7 @@ SMBus Block Read ================ -This command reads a block of upto 32 bytes from a device, from a +This command reads a block of up to 32 bytes from a device, from a designated register that is specified through the Comm byte. The amount of data is specified by the device in the Count byte. @@ -120,8 +127,90 @@ SMBus Block Write ================= -The opposite of the Block Read command, this writes upto 32 bytes to +The opposite of the Block Read command, this writes up to 32 bytes to a device, to a designated register that is specified through the Comm byte. The amount of data is specified in the Count byte. S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P + + +SMBus Block Process Call +======================== + +SMBus Block Process Call was introduced in Revision 2.0 of the specification. + +This command selects a device register (through the Comm byte), sends +1 to 31 bytes of data to it, and reads 1 to 31 bytes of data in return. + +S Addr Wr [A] Comm [A] Count [A] Data [A] ... + S Addr Rd [A] [Count] A [Data] ... NA P + + +SMBus Host Notify +================= + +This command is sent from a SMBus device acting as a master to the +SMBus host acting as a slave. +It is the same form as Write Word, with the command code replaced by the +alerting device's address. + +[S] [HostAddr] [Wr] A [DevAddr] A [DataLow] A [DataHigh] A [P] + + +Packet Error Checking (PEC) +=========================== +Packet Error Checking was introduced in Revision 1.1 of the specification. + +PEC adds a CRC-8 error-checking byte to all transfers. + + +Address Resolution Protocol (ARP) +================================= +The Address Resolution Protocol was introduced in Revision 2.0 of +the specification. It is a higher-layer protocol which uses the +messages above. + +ARP adds device enumeration and dynamic address assignment to +the protocol. All ARP communications use slave address 0x61 and +require PEC checksums. + + +I2C Block Transactions +====================== +The following I2C block transactions are supported by the +SMBus layer and are described here for completeness. +I2C block transactions do not limit the number of bytes transferred +but the SMBus layer places a limit of 32 bytes. + + +I2C Block Read +============== + +This command reads a block of bytes from a device, from a +designated register that is specified through the Comm byte. + +S Addr Wr [A] Comm [A] + S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P + + +I2C Block Read (2 Comm bytes) +============================= + +This command reads a block of bytes from a device, from a +designated register that is specified through the two Comm bytes. + +S Addr Wr [A] Comm1 [A] Comm2 [A] + S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P + + +I2C Block Write +=============== + +The opposite of the Block Read command, this writes bytes to +a device, to a designated register that is specified through the +Comm byte. Note that command lengths of 0, 2, or more bytes are +supported as they are indistinguishable from data. + +S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P + + Index: Documentation/i2c/summary =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/i2c/summary,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/i2c/summary 22 Jul 2004 19:50:28 -0000 1.1 +++ Documentation/i2c/summary 4 Aug 2004 01:33:03 -0000 1.2 @@ -4,7 +4,7 @@ ============= I2C (pronounce: I squared C) is a protocol developed by Philips. It is a -slow two-wire protocol (10-100 kHz), but it suffices for many types of +slow two-wire protocol (10-400 kHz), but it suffices for many types of devices. SMBus (System Management Bus) is a subset of the I2C protocol. Many @@ -43,15 +43,15 @@ Included Bus Drivers ==================== -Note that not only stable drivers are patched into the kernel by 'mkpatch'. +Note that only stable drivers are patched into the kernel by 'mkpatch'. Base modules ------------ -i2c-core: The basic I2C code, including the /proc interface -i2c-dev: The /dev interface -i2c-proc: The /proc interface for device (client) drivers +i2c-core: The basic I2C code, including the /proc/bus/i2c* interface +i2c-dev: The /dev/i2c-* interface +i2c-proc: The /proc/sys/dev/sensors interface for device (client) drivers Algorithm drivers ----------------- @@ -71,5 +71,5 @@ i2c-ppc405: IBM 405xx processor I2C device (uses i2c-algo-ppc405) (NOT BUILT BY DEFAULT) i2c-pport: Primitive parallel port adapter (uses i2c-algo-bit) i2c-rpx: RPX board Motorola 8xx I2C device (uses i2c-algo-8xx) (NOT BUILT BY DEFAULT) -i2c-velleman: Velleman K9000 parallel port adapter (uses i2c-algo-bit) +i2c-velleman: Velleman K8000 parallel port adapter (uses i2c-algo-bit) Index: Documentation/i2c/writing-clients =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/i2c/writing-clients,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/i2c/writing-clients 22 Jul 2004 19:50:28 -0000 1.1 +++ Documentation/i2c/writing-clients 4 Aug 2004 01:33:03 -0000 1.2 @@ -365,7 +365,7 @@ The detect client function is called by i2c_probe or i2c_detect. The `kind' parameter contains 0 if this call is due to a `force' -parameter, and 0 otherwise (for i2c_detect, it contains 0 if +parameter, and -1 otherwise (for i2c_detect, it contains 0 if this call is due to the generic `force' parameter, and the chip type number if it is due to a specific `force' parameter). @@ -448,9 +448,9 @@ /* Note that we reserve some space for foo_data too. If you don't need it, remove it. We do it here to help to lessen memory fragmentation. */ - if (! (new_client = kmalloc(sizeof(struct i2c_client)) + + if (! (new_client = kmalloc(sizeof(struct i2c_client) + sizeof(struct foo_data), - GFP_KERNEL)) { + GFP_KERNEL))) { err = -ENOMEM; goto ERROR0; } Index: Documentation/i386/zero-page.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/i386/zero-page.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/i386/zero-page.txt 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/i386/zero-page.txt 4 Aug 2004 01:33:03 -0000 1.2 @@ -31,6 +31,7 @@ 0x1e0 unsigned long ALT_MEM_K, alternative mem check, in Kb 0x1e8 char number of entries in E820MAP (below) +0x1e9 unsigned char number of entries in EDDBUF (below) 0x1f1 char size of setup.S, number of sectors 0x1f2 unsigned short MOUNT_ROOT_RDONLY (if !=0) 0x1f4 unsigned short size of compressed kernel-part in the @@ -65,7 +66,12 @@ 0x21c unsigned long INITRD_SIZE, size in bytes of ramdisk image 0x220 4 bytes (setup.S) 0x224 unsigned short setup.S heap end pointer +0x228 4 bytes unknown, but writing this in setup.S makes + kernel fail to decompress on some systems +0x2cc 4 bytes DISK80_SIG_BUFFER (setup.S) 0x2d0 - 0x600 E820MAP +0x600 - 0x7ff EDDBUF (setup.S) for disk signature read sector +0x600 - 0x7de EDDBUF (setup.S) 0x800 string, 2K max COMMAND_LINE, the kernel commandline as copied using CL_OFFSET. Index: Documentation/ia64/efirtc.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/ia64/efirtc.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/ia64/efirtc.txt 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/ia64/efirtc.txt 4 Aug 2004 01:33:03 -0000 1.2 @@ -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. Index: Documentation/input/gameport-programming.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/input/gameport-programming.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/input/gameport-programming.txt 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/input/gameport-programming.txt 4 Aug 2004 01:33:03 -0000 1.2 @@ -1,4 +1,4 @@ -$Id: gameport-programming.txt,v 1.1 2004/07/22 19:50:29 joff Exp $ +$Id: gameport-programming.txt,v 1.2 2004/08/04 01:33:03 joff Exp $ Programming gameport drivers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Index: Documentation/input/input-programming.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/input/input-programming.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/input/input-programming.txt 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/input/input-programming.txt 4 Aug 2004 01:33:03 -0000 1.2 @@ -1,4 +1,4 @@ -$Id: input-programming.txt,v 1.1 2004/07/22 19:50:29 joff Exp $ +$Id: input-programming.txt,v 1.2 2004/08/04 01:33:03 joff Exp $ Programming input drivers ~~~~~~~~~~~~~~~~~~~~~~~~~ Index: Documentation/input/input.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/input/input.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/input/input.txt 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/input/input.txt 4 Aug 2004 01:33:03 -0000 1.2 @@ -1,7 +1,7 @@ Linux Input drivers v1.0 (c) 1999-2001 Vojtech Pavlik Sponsored by SuSE - $Id: input.txt,v 1.1 2004/07/22 19:50:29 joff Exp $ + $Id: input.txt,v 1.2 2004/08/04 01:33:03 joff Exp $ ---------------------------------------------------------------------------- 0. Disclaimer Index: Documentation/input/joystick-api.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/input/joystick-api.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/input/joystick-api.txt 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/input/joystick-api.txt 4 Aug 2004 01:33:03 -0000 1.2 @@ -5,7 +5,7 @@ 7 Aug 1998 - $Id: joystick-api.txt,v 1.1 2004/07/22 19:50:29 joff Exp $ + $Id: joystick-api.txt,v 1.2 2004/08/04 01:33:03 joff Exp $ 1. Initialization ~~~~~~~~~~~~~~~~~ Index: Documentation/input/joystick-parport.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/input/joystick-parport.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/input/joystick-parport.txt 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/input/joystick-parport.txt 4 Aug 2004 01:33:03 -0000 1.2 @@ -2,7 +2,7 @@ (c) 1998-2000 Vojtech Pavlik (c) 1998 Andree Borrmann Sponsored by SuSE - $Id: joystick-parport.txt,v 1.1 2004/07/22 19:50:29 joff Exp $ + $Id: joystick-parport.txt,v 1.2 2004/08/04 01:33:03 joff Exp $ ---------------------------------------------------------------------------- 0. Disclaimer Index: Documentation/input/joystick.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/input/joystick.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/input/joystick.txt 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/input/joystick.txt 4 Aug 2004 01:33:03 -0000 1.2 @@ -1,7 +1,7 @@ Linux Joystick driver v2.0.0 (c) 1996-2000 Vojtech Pavlik Sponsored by SuSE - $Id: joystick.txt,v 1.1 2004/07/22 19:50:29 joff Exp $ + $Id: joystick.txt,v 1.2 2004/08/04 01:33:03 joff Exp $ ---------------------------------------------------------------------------- 0. Disclaimer Index: Documentation/isdn/INTERFACE =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/isdn/INTERFACE,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/isdn/INTERFACE 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/isdn/INTERFACE 4 Aug 2004 01:33:03 -0000 1.2 @@ -1,4 +1,4 @@ -$Id: INTERFACE,v 1.1 2004/07/22 19:50:29 joff Exp $ +$Id: INTERFACE,v 1.2 2004/08/04 01:33:03 joff Exp $ Description of the Interface between Linklevel and Hardwarelevel of isdn4linux: Index: Documentation/isdn/INTERFACE.fax =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/isdn/INTERFACE.fax,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/isdn/INTERFACE.fax 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/isdn/INTERFACE.fax 4 Aug 2004 01:33:03 -0000 1.2 @@ -1,4 +1,4 @@ -$Id: INTERFACE.fax,v 1.1 2004/07/22 19:50:29 joff Exp $ +$Id: INTERFACE.fax,v 1.2 2004/08/04 01:33:03 joff Exp $ Description of the fax-subinterface between linklevel and hardwarelevel of Index: Documentation/isdn/README.act2000 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/isdn/README.act2000,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/isdn/README.act2000 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/isdn/README.act2000 4 Aug 2004 01:33:03 -0000 1.2 @@ -1,4 +1,4 @@ -$Id: README.act2000,v 1.1 2004/07/22 19:50:29 joff Exp $ +$Id: README.act2000,v 1.2 2004/08/04 01:33:03 joff Exp $ This document describes the ACT2000 driver for the IBM Active 2000 ISDN card. Index: Documentation/isdn/README.audio =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/isdn/README.audio,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/isdn/README.audio 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/isdn/README.audio 4 Aug 2004 01:33:03 -0000 1.2 @@ -1,4 +1,4 @@ -$Id: README.audio,v 1.1 2004/07/22 19:50:29 joff Exp $ +$Id: README.audio,v 1.2 2004/08/04 01:33:03 joff Exp $ ISDN subsystem for Linux. Description of audio mode. Index: Documentation/isdn/README.eicon =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/isdn/README.eicon,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/isdn/README.eicon 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/isdn/README.eicon 4 Aug 2004 01:33:03 -0000 1.2 @@ -1,4 +1,4 @@ -$Id: README.eicon,v 1.1 2004/07/22 19:50:29 joff Exp $ +$Id: README.eicon,v 1.2 2004/08/04 01:33:03 joff Exp $ (c) 1999,2000 Armin Schindler (mac@melware.de) (c) 1999,2000 Cytronics & Melware (info@melware.de) Index: Documentation/isdn/README.hysdn =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/isdn/README.hysdn,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/isdn/README.hysdn 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/isdn/README.hysdn 4 Aug 2004 01:33:03 -0000 1.2 @@ -1,4 +1,4 @@ -$Id: README.hysdn,v 1.1 2004/07/22 19:50:29 joff Exp $ +$Id: README.hysdn,v 1.2 2004/08/04 01:33:03 joff Exp $ The hysdn driver has been written by by Werner Cornelius (werner@isdn4linux.de or werner@titro.de) for Hypercope GmbH Aachen Germany. Hypercope agreed to publish this driver Index: Documentation/isdn/README.icn =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/isdn/README.icn,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/isdn/README.icn 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/isdn/README.icn 4 Aug 2004 01:33:03 -0000 1.2 @@ -1,4 +1,4 @@ -$Id: README.icn,v 1.1 2004/07/22 19:50:29 joff Exp $ +$Id: README.icn,v 1.2 2004/08/04 01:33:03 joff Exp $ You can get the ICN-ISDN-card from: Index: Documentation/m68k/00-INDEX =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/m68k/00-INDEX,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/m68k/00-INDEX 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/m68k/00-INDEX 4 Aug 2004 01:33:03 -0000 1.2 @@ -1,7 +1,5 @@ 00-INDEX - this file -framebuffer.txt - - info about the Linux/m68k frame buffer device kernel-options.txt - command line options for Linux/m68k Index: Documentation/mips/time.README =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/mips/time.README,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/mips/time.README 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/mips/time.README 4 Aug 2004 01:33:03 -0000 1.2 @@ -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. Index: Documentation/networking/00-INDEX =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/networking/00-INDEX,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/networking/00-INDEX 22 Jul 2004 19:50:30 -0000 1.1 +++ Documentation/networking/00-INDEX 4 Aug 2004 01:33:03 -0000 1.2 @@ -97,8 +97,8 @@ sis900.txt - SiS 900/7016 Fast Ethernet device driver info. sk98lin.txt - - SysKonnect SK-98xx and SK-98xx Gigabit Ethernet Adapter family - driver info. + - Marvell Yukon Chipset / SysKonnect SK-98xx compliant Gigabit + Ethernet Adapter family driver info skfp.txt - SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info. smc9.txt Index: Documentation/networking/atm.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/networking/atm.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/networking/atm.txt 22 Jul 2004 19:50:30 -0000 1.1 +++ Documentation/networking/atm.txt 4 Aug 2004 01:33:03 -0000 1.2 @@ -1,8 +1,8 @@ In order to use anything but the most primitive functions of ATM, several user-mode programs are required to assist the kernel. These programs and related material can be found via the ATM on Linux Web -page at http://icawww1.epfl.ch/linux-atm/ +page at http://linux-atm.sourceforge.net/ If you encounter problems with ATM, please report them on the ATM on Linux mailing list. Subscription information, archives, etc., -can be found on http://icawww1.epfl.ch/linux-atm/ +can be found on http://linux-atm.sourceforge.net/ Index: Documentation/networking/bonding.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/networking/bonding.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/networking/bonding.txt 22 Jul 2004 19:50:30 -0000 1.1 +++ Documentation/networking/bonding.txt 4 Aug 2004 01:33:03 -0000 1.2 @@ -21,7 +21,7 @@ Table of Contents ================= - + Installation Bond Configuration Module Parameters @@ -31,6 +31,7 @@ Frequently Asked Questions High Availability Promiscuous Sniffing notes +8021q VLAN support Limitations Resources and Links @@ -43,10 +44,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. @@ -66,7 +67,7 @@ /usr/include/linux. To install ifenslave.c, do: - # gcc -Wall -Wstrict-prototypes -O -I/usr/src/linux/include ifenslave.c -o ifenslave + # gcc -Wall -Wstrict-prototypes -O -I/usr/src/linux/include ifenslave.c -o ifenslave # cp ifenslave /sbin/ifenslave @@ -74,10 +75,10 @@ ================== You will need to add at least the following line to /etc/modules.conf -so the bonding driver will automatically load when the bond0 interface is -configured. Refer to the modules.conf manual page for specific modules.conf -syntax details. The Module Parameters section of this document describes each -bonding driver parameter. +so the bonding driver will automatically load when the bond0 interface is +configured. Refer to the modules.conf manual page for specific modules.conf +syntax details. The Module Parameters section of this document describes each +bonding driver parameter. alias bond0 bonding @@ -108,17 +109,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 +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 @@ -128,30 +129,26 @@ (use appropriate values for your network above) -You can then create a script containing these commands and place it in the +You can then create a script containing these commands and place it in the appropriate rc directory. If you specifically need all network drivers loaded before the bonding driver, -adding the following line to modules.conf will cause the network driver for +adding the following line to modules.conf will cause the network driver for eth0 and eth1 to be loaded before the bonding driver. probeall bond0 eth0 eth1 bonding -Be careful not to reference bond0 itself at the end of the line, or modprobe +Be careful not to reference bond0 itself at the end of the line, or modprobe will die in an endless recursive loop. -To have device characteristics (such as MTU size) propagate to slave devices, -set the bond characteristics before enslaving the device. The characteristics -are propagated during the enslave process. - -If running SNMP agents, the bonding driver should be loaded before any network -drivers participating in a bond. This requirement is due to the the interface -index (ipAdEntIfIndex) being associated to the first interface found with a -given IP address. That is, there is only one ipAdEntIfIndex for each IP -address. For example, if eth0 and eth1 are slaves of bond0 and the driver for -eth0 is loaded before the bonding driver, the interface for the IP address -will be associated with the eth0 interface. This configuration is shown below, -the IP address 192.168.1.1 has an interface index of 2 which indexes to eth0 +If running SNMP agents, the bonding driver should be loaded before any network +drivers participating in a bond. This requirement is due to the the interface +index (ipAdEntIfIndex) being associated to the first interface found with a +given IP address. That is, there is only one ipAdEntIfIndex for each IP +address. For example, if eth0 and eth1 are slaves of bond0 and the driver for +eth0 is loaded before the bonding driver, the interface for the IP address +will be associated with the eth0 interface. This configuration is shown below, +the IP address 192.168.1.1 has an interface index of 2 which indexes to eth0 in the ifDescr table (ifDescr.2). interfaces.ifTable.ifEntry.ifDescr.1 = lo @@ -166,8 +163,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 @@ -188,10 +186,10 @@ Module Parameters ================= -Optional parameters for the bonding driver can be supplied as command line -arguments to the insmod command. Typically, these parameters are specified in -the file /etc/modules.conf (see the manual page for modules.conf). The -available bonding driver parameters are listed below. If a parameter is not +Optional parameters for the bonding driver can be supplied as command line +arguments to the insmod command. Typically, these parameters are specified in +the file /etc/modules.conf (see the manual page for modules.conf). The +available bonding driver parameters are listed below. If a parameter is not specified the default value is used. When initially configuring a bond, it is recommended "tail -f /var/log/messages" be run in a separate window to watch for bonding driver error messages. @@ -200,6 +198,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,26 +243,36 @@ 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 externally visible on only one port (network adapter) 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,15 +280,110 @@ 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 curr_active_slave) while having a unique hw + address for each slave in the bond. If the curr_active_slave + fails it's hw address is swapped with the new curr_active_slave + that was chosen. + +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 @@ -265,89 +406,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 +499,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,22 +510,22 @@ 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/bonding directory. -Sample contents of /proc/net/bond0/info after the driver is loaded with +Sample contents of /proc/net/bonding/bond0 after the driver is loaded with parameters of mode=0 and miimon=1000 is shown below. - + Bonding Mode: load balancing (round-robin) Currently Active Slave: eth0 MII Status: up MII Polling Interval (ms): 1000 Up Delay (ms): 0 Down Delay (ms): 0 - + Slave Interface: eth1 MII Status: up Link Failure Count: 1 - + Slave Interface: eth0 MII Status: up Link Failure Count: 1 @@ -443,33 +533,34 @@ 2) Network verification ----------------------- 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. +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 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 +bond0 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4 inet addr:XXX.XXX.XXX.YYY Bcast:XXX.XXX.XXX.255 Mask:255.255.252.0 UP BROADCAST RUNNING MASTER MULTICAST MTU:1500 Metric:1 RX packets:7224794 errors:0 dropped:0 overruns:0 frame:0 TX packets:3286647 errors:1 dropped:0 overruns:1 carrier:0 - collisions:0 txqueuelen:0 + collisions:0 txqueuelen:0 -eth0 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4 +eth0 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4 inet addr:XXX.XXX.XXX.YYY Bcast:XXX.XXX.XXX.255 Mask:255.255.252.0 UP BROADCAST RUNNING SLAVE MULTICAST MTU:1500 Metric:1 RX packets:3573025 errors:0 dropped:0 overruns:0 frame:0 TX packets:1643167 errors:1 dropped:0 overruns:1 carrier:0 - collisions:0 txqueuelen:100 - Interrupt:10 Base address:0x1080 + collisions:0 txqueuelen:100 + Interrupt:10 Base address:0x1080 -eth1 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4 +eth1 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4 inet addr:XXX.XXX.XXX.YYY Bcast:XXX.XXX.XXX.255 Mask:255.255.252.0 UP BROADCAST RUNNING SLAVE MULTICAST MTU:1500 Metric:1 RX packets:3651769 errors:0 dropped:0 overruns:0 frame:0 TX packets:1643480 errors:0 dropped:0 overruns:0 carrier:0 - collisions:0 txqueuelen:100 - Interrupt:9 Base address:0x1400 + collisions:0 txqueuelen:100 + Interrupt:9 Base address:0x1400 Frequently Asked Questions @@ -488,8 +579,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? @@ -498,9 +588,9 @@ 5. What happens when a slave link dies? - If your ethernet cards support MII or ETHTOOL link status monitoring - and the MII monitoring has been enabled in the driver (see description - of module parameters), there will be no adverse consequences. This + If your ethernet cards support MII or ETHTOOL link status monitoring + and the MII monitoring has been enabled in the driver (see description + of module parameters), there will be no adverse consequences. This release of the bonding driver knows how to get the MII information and enables or disables its slaves according to their link status. See section on High Availability for additional information. @@ -508,37 +598,49 @@ 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 duration, 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 - continue to send packets but some packets will be lost. Retransmits + driver will not handle this situation very well. The driver will + continue to send packets but some packets will be lost. Retransmits will cause serious degradation of performance (in the case when one of two slave links fails, 50% packets will be lost, which is a serious problem for both TCP and UDP). 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 + 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 models (450) can define trunks between ports on different physical 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? @@ -548,32 +650,24 @@ is then passed to all following slaves and remains persistent (even if the the first slave is removed) until the bonding device is brought down or reconfigured. - + If you wish to change the MAC address, you can set it with ifconfig: # ifconfig bond0 hw ether 00:11:22:33:44:55 The MAC address can be also changed by bringing down/up the device and then changing its slaves (or their order): - + # ifconfig bond0 down ; modprobe -r bonding # ifconfig bond0 .... up # ifenslave bond0 eth... This method will automatically take the address from the next slave that will be added. - - To restore your slaves' MAC addresses, you need to detach them - from the bond (`ifenslave -d bond0 eth0'), set them down - (`ifconfig eth0 down'), unload the drivers (`rmmod 3c59x', for - example) and reload them to get the MAC addresses from their - eeproms. If the driver is shared by several devices, you need - to turn them all down. Another solution is to look for the MAC - address at boot time (dmesg or tail /var/log/messages) and to - reset it by hand with ifconfig : - # ifconfig eth0 down - # ifconfig eth0 hw ether 00:20:40:60:80:A0 + To restore your slaves' MAC addresses, you need to detach them + from the bond (`ifenslave -d bond0 eth0'). The bonding driver will then + restore the MAC addresses that the slaves had before they were enslaved. 9. Which transmit polices can be used? @@ -591,32 +685,46 @@ 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 ================= To implement high availability using the bonding driver, the driver needs to be -compiled as a module, because currently it is the only way to pass parameters +compiled as a module, because currently it is the only way to pass parameters to the driver. This may change in the future. -High availability is achieved by using MII or ETHTOOL status reporting. You -need to verify that all your interfaces support MII or ETHTOOL link status -reporting. On Linux kernel 2.2.17, all the 100 Mbps capable drivers and -yellowfin gigabit driver support MII. To determine if ETHTOOL link reporting -is available for interface eth0, type "ethtool eth0" and the "Link detected:" -line should contain the correct link status. If your system has an interface -that does not support MII or ETHTOOL status reporting, a failure of its link -will not be detected! A message indicating MII and ETHTOOL is not supported by -a network driver is logged when the bonding driver is loaded with a non-zero +High availability is achieved by using MII or ETHTOOL status reporting. You +need to verify that all your interfaces support MII or ETHTOOL link status +reporting. On Linux kernel 2.2.17, all the 100 Mbps capable drivers and +yellowfin gigabit driver support MII. To determine if ETHTOOL link reporting +is available for interface eth0, type "ethtool eth0" and the "Link detected:" +line should contain the correct link status. If your system has an interface +that does not support MII or ETHTOOL status reporting, a failure of its link +will not be detected! A message indicating MII and ETHTOOL is not supported by +a network driver is logged when the bonding driver is loaded with a non-zero miimon value. The bonding driver can regularly check all its slaves links using the ETHTOOL -IOCTL (ETHTOOL_GLINK command) or by checking the MII status registers. The -check interval is specified by the module argument "miimon" (MII monitoring). -It takes an integer that represents the checking time in milliseconds. It -should not come to close to (1000/HZ) (10 milli-seconds on i386) because it -may then reduce the system interactivity. A value of 100 seems to be a good -starting point. It means that a dead link will be detected at most 100 +IOCTL (ETHTOOL_GLINK command) or by checking the MII status registers. The +check interval is specified by the module argument "miimon" (MII monitoring). +It takes an integer that represents the checking time in milliseconds. It +should not come to close to (1000/HZ) (10 milli-seconds on i386) because it +may then reduce the system interactivity. A value of 100 seems to be a good +starting point. It means that a dead link will be detected at most 100 milli-seconds after it goes down. Example: @@ -628,7 +736,7 @@ alias bond0 bonding options bond0 miimon=100 -There are currently two policies for high availability. They are dependent on +There are currently two policies for high availability. They are dependent on whether: a) hosts are connected to a single host or switch that support trunking @@ -678,7 +786,7 @@ # ifenslave bond0 eth0 eth1 -2) High Availability on two or more switches (or a single switch without +2) High Availability on two or more switches (or a single switch without trunking support) --------------------------------------------------------------------------- This mode is more problematic because it relies on the fact that there @@ -724,7 +832,7 @@ In this configuration, there is an ISL - Inter Switch Link (could be a trunk), several servers (host1, host2 ...) attached to both switches each, and one or -more ports to the outside world (port3...). One an only one slave on each host +more ports to the outside world (port3...). One and only one slave on each host is active at a time, while all links are still monitored (the system can detect a failure of active and backup links). @@ -737,10 +845,10 @@ connected to one switch and host2's to the other. Such system will survive a failure of a single host, cable, or switch. The worst thing that may happen in the case of a switch failure is that half of the hosts will be temporarily -unreachable until the other switch expires its tables. +unreachable until the other switch expires its tables. Example 2: Using multiple ethernet cards connected to a switch to configure - NIC failover (switch is not required to support trunking). + NIC failover (switch is not required to support trunking). +----------+ +----------+ @@ -814,6 +922,41 @@ just ignore all the warnings it emits. +8021q VLAN support +================== + +It is possible to configure VLAN devices over a bond interface using the 8021q +driver. However, only packets coming from the 8021q driver and passing through +bonding will be tagged by default. Self generated packets, like bonding's +learning packets or ARP packets generated by either ALB mode or the ARP +monitor mechanism, are tagged internally by bonding itself. As a result, +bonding has to "learn" what VLAN IDs are configured on top of it, and it uses +those IDs to tag self generated packets. + +For simplicity reasons, and to support the use of adapters that can do VLAN +hardware acceleration offloding, the bonding interface declares itself as +fully hardware offloaing capable, it gets the add_vid/kill_vid notifications +to gather the necessary information, and it propagates those actions to the +slaves. +In case of mixed adapter types, hardware accelerated tagged packets that should +go through an adapter that is not offloading capable are "un-accelerated" by the +bonding driver so the VLAN tag sits in the regular location. + +VLAN interfaces *must* be added on top of a bonding interface only after +enslaving at least one slave. This is because until the first slave is added the +bonding interface has a HW address of 00:00:00:00:00:00, which will be copied by +the VLAN interface when it is created. + +Notice that a problem would occur if all slaves are released from a bond that +still has VLAN interfaces on top of it. When later coming to add new slaves, the +bonding interface would get a HW address from the first slave, which might not +match that of the VLAN interfaces. It is recommended that either all VLANs are +removed and then re-added, or to manually set the bonding interface's HW +address so it matches the VLAN's. (Note: changing a VLAN interface's HW address +would set the underlying device -- i.e. the bonding interface -- to promiscouos +mode, which might not be what you want). + + Limitations =========== The main limitations are : @@ -824,12 +967,8 @@ servers, but may be useful when the front switches send multicast information on their links (e.g. VRRP), or even health-check the servers. Use the arp_interval/arp_ip_target parameters to count incoming/outgoing - frames. + 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 @@ -844,13 +983,12 @@ You will also find a lot of information regarding Ethernet, NWay, MII, etc. at www.scyld.com. -For new versions of the driver, patches for older kernels and the updated -userspace tools, take a look at Willy Tarreau's site : +Patches for 2.2 kernels are at Willy Tarreau's site : - http://wtarreau.free.fr/pub/bonding/ - - http://www-miaif.lip6.fr/willy/pub/bonding/ + - http://www-miaif.lip6.fr/~tarreau/pub/bonding/ To get latest informations about Linux Kernel development, please consult the Linux Kernel Mailing List Archives at : - http://boudicca.tux.org/hypermail/linux-kernel/latest/ + http://www.ussg.iu.edu/hypermail/linux/kernel/ -- END -- Index: Documentation/networking/generic-hdlc.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/networking/generic-hdlc.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/networking/generic-hdlc.txt 22 Jul 2004 19:50:30 -0000 1.1 +++ Documentation/networking/generic-hdlc.txt 4 Aug 2004 01:33:03 -0000 1.2 @@ -1,11 +1,13 @@ -Generic HDLC layer for Linux kernel 2.4/2.5 +Generic HDLC layer Krzysztof Halasa -May, 2001 +January, 2003 Generic HDLC layer currently supports: -- Frame Relay (ANSI, CCITT and no LMI), with ARP support (no InARP), -- raw HDLC (IPv4 only), +- Frame Relay (ANSI, CCITT and no LMI), with ARP support (no InARP). + Normal (routed) and Ethernet-bridged (Ethernet device emulation) + interfaces can share a single PVC. +- raw HDLC - either IP (IPv4) interface or Ethernet device emulation. - Cisco HDLC, - PPP (uses syncppp.c), - X.25 (uses X.25 routines). @@ -15,6 +17,10 @@ - RISCom/N2 by SDL Communications Inc. - and others, some not in the official kernel. +Ethernet device emulation (using HDLC or Frame-Relay PVC) is compatible +with IEEE 802.1Q (VLANs) and 802.1D (Ethernet bridging). + + Make sure the hdlc.o and the hardware driver are loaded. It should create a number of "hdlc" (hdlc0 etc) network devices, one for each WAN port. You'll need the "sethdlc" utility, get it from: @@ -32,8 +38,10 @@ sethdlc hdlc0 cisco interval 10 timeout 25 or sethdlc hdlc0 rs232 clock ext - sethdlc fr lmi ansi - sethdlc create 99 + sethdlc hdlc0 fr lmi ansi + sethdlc hdlc0 create 99 + ifconfig hdlc0 up + ifconfig pvc0 localIP pointopoint remoteIP In Frame Relay mode, ifconfig master hdlc device up (without assigning any IP address to it) before using pvc devices. @@ -58,6 +66,9 @@ no-parity / crc16 / crc16-pr0 (CRC16 with preset zeros) / crc32-itu crc16-itu (CRC16 with ITU-T polynomial) / crc16-itu-pr0 - sets parity +* hdlc-eth - Ethernet device emulation using HDLC. Parity and encoding + as above. + * cisco - sets Cisco HDLC mode (IP, IPv6 and IPX supported) interval - time in seconds between keepalive packets timeout - time in seconds after last received keepalive packet before @@ -77,7 +88,12 @@ n392 - error threshold - both user and network n393 - monitored events count - both user and network -* create | delete n - FR only - adds / deletes PVC interface with DLCI #n. +Frame-Relay only: +* create n | delete n - adds / deletes PVC interface with DLCI #n. + Newly created interface will be named pvc0, pvc1 etc. + +* create ether n | delete ether n - adds a device for Ethernet-bridged + frames. The device will be named pvceth0, pvceth1 etc. @@ -104,11 +120,11 @@ If you have a problem with N2 or C101 card, you can issue the "private" -command to see port's packet descriptor rings: +command to see port's packet descriptor rings (in kernel logs): sethdlc hdlc0 private -The hardware driver have to be build with CONFIG_HDLC_DEBUG_RINGS. +The hardware driver has to be build with CONFIG_HDLC_DEBUG_RINGS. Attaching this info to bug reports would be helpful. Anyway, let me know if you have problems using this. Index: Documentation/networking/ifenslave.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/networking/ifenslave.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/networking/ifenslave.c 22 Jul 2004 19:50:30 -0000 1.1 +++ Documentation/networking/ifenslave.c 4 Aug 2004 01:33:03 -0000 1.2 @@ -4,8 +4,6 @@ * This program controls the Linux implementation of running multiple * network interfaces in parallel. * - * Usage: ifenslave [-v] master-interface < slave-interface [metric ] > ... - * * Author: Donald Becker * Copyright 1994-1996 Donald Becker * @@ -27,7 +25,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,27 +42,76 @@ * * - 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. + * + * - 2003/12/01 - Shmulik Hen + * - Code cleanup and style changes + * set version to 1.1.0 */ +#define APP_VERSION "1.1.0" +#define APP_RELDATE "December 1, 2003" +#define APP_NAME "ifenslave" + static char *version = -"ifenslave.c:v0.07 9/9/97 Donald 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"; +APP_NAME ".c:v" APP_VERSION " (" APP_RELDATE ")\n" +"o Donald Becker (becker@cesdis.gsfc.nasa.gov).\n" +"o Detach support added on 2000/10/02 by Willy Tarreau (willy at meta-x.org).\n" +"o 2.4 kernel support added on 2001/02/16 by Chad N. Tindel\n" +" (ctindel at ieee dot org).\n"; static const char *usage_msg = -"Usage: ifenslave [-adfrvVh] < [metric ] > ...\n" -" ifenslave -c master-interface slave-if\n"; +"Usage: ifenslave [-f] [...]\n" +" ifenslave -d [...]\n" +" ifenslave -c \n" +" ifenslave --help\n"; -static const char *howto_msg = -"Usage: ifenslave [-adfrvVh] < [metric ] > ...\n" -" ifenslave -c master-interface slave-if\n" +static const char *help_msg = "\n" " To create a bond device, simply follow these three steps :\n" " - ensure that the required drivers are properly loaded :\n" @@ -72,18 +119,32 @@ " - assign an IP address to the bond device :\n" " # ifconfig bond0 netmask broadcast \n" " - attach all the interfaces you need to the bond device :\n" -" # ifenslave bond0 eth0 eth1 eth2\n" +" # ifenslave [{-f|--force}] bond0 eth0 [eth1 [eth2]...]\n" " If bond0 didn't have a MAC address, it will take eth0's. Then, all\n" " interfaces attached AFTER this assignment will get the same MAC addr.\n" -"\n" -" To detach a dead interface without setting the bond device down :\n" -" # ifenslave -d bond0 eth1\n" +" (except for ALB/TLB modes)\n" "\n" " To set the bond device down and automatically release all the slaves :\n" " # ifconfig bond0 down\n" "\n" +" To detach a dead interface without setting the bond device down :\n" +" # ifenslave {-d|--detach} bond0 eth0 [eth1 [eth2]...]\n" +"\n" " To change active slave :\n" -" # ifenslave -c bond0 eth0\n" +" # ifenslave {-c|--change-active} bond0 eth0\n" +"\n" +" To show master interface info\n" +" # ifenslave bond0\n" +"\n" +" To show all interfaces info\n" +" # ifenslave {-a|--all-interfaces}\n" +"\n" +" To be more verbose\n" +" # ifenslave {-v|--verbose} ...\n" +"\n" +" # ifenslave {-u|--usage} Show usage\n" +" # ifenslave {-V|--version} Show version\n" +" # ifenslave {-h|--help} This message\n" "\n"; #include @@ -98,444 +159,344 @@ #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. */ - {"force", 0, 0, 'f'}, /* Force the operation. */ - {"help", 0, 0, '?'}, /* Give help */ - {"howto", 0, 0, 'h'}, /* Give some more help */ - {"receive-slave", 0, 0, 'r'}, /* Make a receive-only slave. */ - {"verbose", 0, 0, 'v'}, /* Report each action taken. */ - {"version", 0, 0, 'V'}, /* Emit version information. */ - {"detach", 0, 0, 'd'}, /* Detach a slave interface. */ - {"change-active", 0, 0, 'c'}, /* Change the active slave. */ - { 0, 0, 0, 0 } + /* { name has_arg *flag val } */ + {"all-interfaces", 0, 0, 'a'}, /* Show all interfaces. */ + {"change-active", 0, 0, 'c'}, /* Change the active slave. */ + {"detach", 0, 0, 'd'}, /* Detach a slave interface. */ + {"force", 0, 0, 'f'}, /* Force the operation. */ + {"help", 0, 0, 'h'}, /* Give help */ + {"usage", 0, 0, 'u'}, /* Give usage */ + {"verbose", 0, 0, 'v'}, /* Report each action taken. */ + {"version", 0, 0, 'V'}, /* Emit version information. */ + { 0, 0, 0, 0} }; /* Command-line flags. */ unsigned int -opt_a = 0, /* Show-all-interfaces flag. */ -opt_f = 0, /* Force the operation. */ -opt_r = 0, /* Set up a Rx-only slave. */ -opt_d = 0, /* detach a slave interface. */ -opt_c = 0, /* change-active-slave flag. */ -verbose = 0, /* Verbose flag. */ -opt_version = 0, -opt_howto = 0; -int skfd = -1; /* AF_INET socket for ioctl() calls. */ +opt_a = 0, /* Show-all-interfaces flag. */ +opt_c = 0, /* Change-active-slave flag. */ +opt_d = 0, /* Detach a slave interface. */ +opt_f = 0, /* Force the operation. */ +opt_h = 0, /* Help */ +opt_u = 0, /* Usage */ +opt_v = 0, /* Verbose flag. */ +opt_V = 0; /* Version */ + +int skfd = -1; /* AF_INET socket for ioctl() calls.*/ +int abi_ver = 0; /* userland - kernel ABI version */ +int hwaddr_set = 0; /* Master's hwaddr is set */ +int saved_errno; + +struct ifreq master_mtu, master_flags, master_hwaddr; +struct ifreq slave_mtu, slave_flags, slave_hwaddr; + +struct dev_ifr { + struct ifreq *req_ifr; + char *req_name; + int req_type; +}; + +struct dev_ifr master_ifra[] = { + {&master_mtu, "SIOCGIFMTU", SIOCGIFMTU}, + {&master_flags, "SIOCGIFFLAGS", SIOCGIFFLAGS}, + {&master_hwaddr, "SIOCGIFHWADDR", SIOCGIFHWADDR}, + {NULL, "", 0} +}; + +struct dev_ifr slave_ifra[] = { + {&slave_mtu, "SIOCGIFMTU", SIOCGIFMTU}, + {&slave_flags, "SIOCGIFFLAGS", SIOCGIFFLAGS}, + {&slave_hwaddr, "SIOCGIFHWADDR", SIOCGIFHWADDR}, + {NULL, "", 0} +}; static void if_print(char *ifname); +static int get_drv_info(char *master_ifname); +static int get_if_settings(char *ifname, struct dev_ifr ifra[]); +static int get_slave_flags(char *slave_ifname); +static int set_master_hwaddr(char *master_ifname, struct sockaddr *hwaddr); +static int set_slave_hwaddr(char *slave_ifname, struct sockaddr *hwaddr); +static int set_slave_mtu(char *slave_ifname, int mtu); +static int set_if_flags(char *ifname, short flags); +static int set_if_up(char *ifname, short flags); +static int set_if_down(char *ifname, short flags); +static int clear_if_addr(char *ifname); +static int set_if_addr(char *master_ifname, char *slave_ifname); +static int change_active(char *master_ifname, char *slave_ifname); +static int enslave(char *master_ifname, char *slave_ifname); +static int release(char *master_ifname, char *slave_ifname); +#define v_print(fmt, args...) \ + if (opt_v) \ + fprintf(stderr, fmt, ## args ) -int -main(int argc, char **argv) +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 c, errflag = 0; - sa_family_t master_family; char **spp, *master_ifname, *slave_ifname; - int hwaddr_notset; - int master_up; + int c, i, rv; + int res = 0; + int exclusive = 0; - while ((c = getopt_long(argc, argv, "acdfrvV?h", longopts, 0)) != EOF) + while ((c = getopt_long(argc, argv, "acdfhuvV", longopts, 0)) != EOF) { switch (c) { - case 'a': opt_a++; break; - case 'f': opt_f++; break; - case 'r': opt_r++; break; - case 'd': opt_d++; break; - case 'c': opt_c++; break; - case 'v': verbose++; break; - case 'V': opt_version++; break; - case 'h': opt_howto++; break; - case '?': errflag++; - } + case 'a': opt_a++; exclusive++; break; + case 'c': opt_c++; exclusive++; break; + case 'd': opt_d++; exclusive++; break; + case 'f': opt_f++; exclusive++; break; + case 'h': opt_h++; exclusive++; break; + case 'u': opt_u++; exclusive++; break; + case 'v': opt_v++; break; + case 'V': opt_V++; exclusive++; break; - /* option check */ - if (opt_c) - if(opt_a || opt_f || opt_r || opt_d || verbose || opt_version || - opt_howto || errflag ) { + case '?': fprintf(stderr, usage_msg); - return 2; + res = 2; + goto out; } + } - if (errflag) { + /* options check */ + if (exclusive > 1) { fprintf(stderr, usage_msg); - return 2; + res = 2; + goto out; + } + + if (opt_v || opt_V) { + printf(version); + if (opt_V) { + res = 0; + goto out; + } } - if (opt_howto) { - fprintf(stderr, howto_msg); - return 0; + if (opt_u) { + printf(usage_msg); + res = 0; + goto out; } - if (verbose || opt_version) { - printf(version); - if (opt_version) - exit(0); + if (opt_h) { + printf(usage_msg); + printf(help_msg); + res = 0; + goto out; } - /* Open a basic socket. */ - if ((skfd = socket(AF_INET, SOCK_DGRAM,0)) < 0) { + /* Open a basic socket */ + if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); - exit(-1); + res = 1; + goto out; } - if (verbose) - fprintf(stderr, "DEBUG: argc=%d, optind=%d and argv[optind] is %s.\n", - argc, optind, argv[optind]); - - /* No remaining args means show all interfaces. */ - if (optind == argc) { - if_print((char *)NULL); - (void) close(skfd); - exit(0); + if (opt_a) { + if (optind == argc) { + /* No remaining args */ + /* show all interfaces */ + if_print((char *)NULL); + goto out; + } else { + /* Just show usage */ + fprintf(stderr, usage_msg); + res = 2; + goto out; + } } - /* Copy the interface name. */ + /* Copy the interface name */ spp = argv + optind; master_ifname = *spp++; - slave_ifname = *spp++; - /* Check command line. */ - if (opt_c) { - char **tempp = spp; - if ((master_ifname == NULL)||(slave_ifname == NULL)||(*tempp++ != NULL)) { - fprintf(stderr, usage_msg); - return 2; - } + if (master_ifname == NULL) { + fprintf(stderr, usage_msg); + res = 2; + goto out; } - /* A single args means show the configuration for this interface. */ - if (slave_ifname == NULL) { - if_print(master_ifname); - (void) close(skfd); - exit(0); + /* exchange abi version with bonding module */ + res = get_drv_info(master_ifname); + if (res) { + fprintf(stderr, + "Master '%s': Error: handshake with driver failed. " + "Aborting\n", + master_ifname); + goto out; } - /* Get the vitals from the master interface. */ - { - struct ifreq *ifra[7] = { &if_ipaddr, &if_mtu, &if_dstaddr, - &if_brdaddr, &if_netmask, &if_flags, - &if_hwaddr }; - const char *req_name[7] = { - "IP address", "MTU", "destination address", - "broadcast address", "netmask", "status flags", - "hardware address" }; - const int ioctl_req_type[7] = { - SIOCGIFADDR, SIOCGIFMTU, SIOCGIFDSTADDR, - SIOCGIFBRDADDR, SIOCGIFNETMASK, SIOCGIFFLAGS, - SIOCGIFHWADDR }; - int i; - - for (i = 0; i < 7; i++) { - strncpy(ifra[i]->ifr_name, master_ifname, IFNAMSIZ); - if (ioctl(skfd, ioctl_req_type[i], ifra[i]) < 0) { - fprintf(stderr, - "Something broke getting the master's %s: %s.\n", - req_name[i], strerror(errno)); - } - } + slave_ifname = *spp++; - 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; + if (slave_ifname == NULL) { + if (opt_d || opt_c) { + fprintf(stderr, usage_msg); + res = 2; + goto out; } - /* The family '1' is ARPHRD_ETHER for ethernet. */ - if (if_hwaddr.ifr_hwaddr.sa_family != 1 && !opt_f) { - fprintf(stderr, "The specified master interface '%s' is not" - " ethernet-like.\n This program is designed to work" - " with ethernet-like network interfaces.\n" - " Use the '-f' option to force the operation.\n", - master_ifname); + /* A single arg means show the + * configuration for this interface + */ + if_print(master_ifname); + goto out; + } - exit (1); - } - master_family = if_hwaddr.ifr_hwaddr.sa_family; - if (verbose) { - unsigned char *hwaddr = (unsigned char *)if_hwaddr.ifr_hwaddr.sa_data; - printf("The current hardware address (SIOCGIFHWADDR) of %s is type %d " - "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n", master_ifname, - if_hwaddr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1], - hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]); - } + res = get_if_settings(master_ifname, master_ifra); + if (res) { + /* Probably a good reason not to go on */ + fprintf(stderr, + "Master '%s': Error: get settings failed: %s. " + "Aborting\n", + master_ifname, strerror(res)); + goto out; } + /* check if master is indeed a master; + * if not then fail any operation + */ + if (!(master_flags.ifr_flags & IFF_MASTER)) { + fprintf(stderr, + "Illegal operation; the specified interface '%s' " + "is not a master. Aborting\n", + master_ifname); + res = 1; + goto out; + } - /* do this when enslaving interfaces */ - do { - if (opt_d) { /* detach a slave interface from the master */ - strncpy(if_flags.ifr_name, master_ifname, IFNAMSIZ); - strncpy(if_flags.ifr_slave, slave_ifname, IFNAMSIZ); - if ((ioctl(skfd, SIOCBONDRELEASE, &if_flags) < 0) && - (ioctl(skfd, BOND_RELEASE_OLD, &if_flags) < 0)) { - 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 */ - 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)); - } - 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)); - } - } - } - } - 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 - */ - - 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)); - return 1; - } + /* check if master is up; if not then fail any operation */ + if (!(master_flags.ifr_flags & IFF_UP)) { + fprintf(stderr, + "Illegal operation; the specified master interface " + "'%s' is not up.\n", + master_ifname); + res = 1; + goto out; + } - if (hwaddr_notset) { - /* 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 - * 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; - } - } + /* Only for enslaving */ + if (!opt_c && !opt_d) { + sa_family_t master_family = master_hwaddr.ifr_hwaddr.sa_family; + unsigned char *hwaddr = + (unsigned char *)master_hwaddr.ifr_hwaddr.sa_data; - 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; - } - } + /* The family '1' is ARPHRD_ETHER for ethernet. */ + if (master_family != 1 && !opt_f) { + fprintf(stderr, + "Illegal operation: The specified master " + "interface '%s' is not ethernet-like.\n " + "This program is designed to work with " + "ethernet-like network interfaces.\n " + "Use the '-f' option to force the " + "operation.\n", + master_ifname); + res = 1; + goto out; + } - if (!goterr) { - strncpy(if_hwaddr.ifr_name, - master_ifname, IFNAMSIZ); - if (ioctl(skfd, SIOCSIFHWADDR, - &if_hwaddr) < 0) { - fprintf(stderr, - "Could not set MAC " - "address of %s: %s\n", - master_ifname, - strerror(errno)); - goterr=1; - } else { - hwaddr_notset = 0; - } - } + /* Check master's hw addr */ + for (i = 0; i < 6; i++) { + if (hwaddr[i] != 0) { + hwaddr_set = 1; + break; + } + } - 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 (hwaddr_set) { + v_print("current hardware address of master '%s' " + "is %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, " + "type %d\n", + master_ifname, + hwaddr[0], hwaddr[1], + hwaddr[2], hwaddr[3], + hwaddr[4], hwaddr[5], + master_family); + } + } - } else { - /* we'll assign master's hwaddr to this slave */ - 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)); - } - } - - 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)); - if (saved_errno == EBUSY) - fprintf(stderr, " The slave device %s is busy: it must be" - " 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"); - else if (saved_errno == EINVAL) - fprintf(stderr, " The slave device's address type does not match" - " the master's address type.\n"); - } else { - if (verbose) { - unsigned char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data; - printf("Slave's (%s) hardware address set to " - "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n", slave_ifname, - hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]); - } - } - } - - if (*spp && !strcmp(*spp, "metric")) { - if (*++spp == NULL) { - fprintf(stderr, usage_msg); - exit(2); - } - if_metric.ifr_metric = atoi(*spp); - strncpy(if_metric.ifr_name, slave_ifname, IFNAMSIZ); - if (ioctl(skfd, SIOCSIFMETRIC, &if_metric) < 0) { - fprintf(stderr, "SIOCSIFMETRIC on %s: %s\n", slave_ifname, - strerror(errno)); - goterr = 1; - } - spp++; - } - - if (strncpy(if_ipaddr.ifr_name, slave_ifname, IFNAMSIZ) <= 0 - || ioctl(skfd, SIOCSIFADDR, &if_ipaddr) < 0) { - fprintf(stderr, - "Something broke setting the slave's address: %s.\n", - strerror(errno)); - } else { - if (verbose) { - unsigned char *ipaddr = if_ipaddr.ifr_addr.sa_data; - printf("Set the slave's (%s) IP address to %d.%d.%d.%d.\n", - 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) { - 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", - slave_ifname, strerror(errno)); - } else { - if (verbose) { - unsigned char *ipaddr = if_dstaddr.ifr_dstaddr.sa_data; - printf("Set the slave's (%s) destination address to %d.%d.%d.%d.\n", - 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, - "Something broke setting the slave (%s) broadcast address: %s.\n", - slave_ifname, strerror(errno)); - } else { - if (verbose) { - unsigned char *ipaddr = if_brdaddr.ifr_broadaddr.sa_data; - printf("Set the slave's (%s) broadcast address to %d.%d.%d.%d.\n", - slave_ifname, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]); + /* Accepts only one slave */ + if (opt_c) { + /* change active slave */ + res = get_slave_flags(slave_ifname); + if (res) { + fprintf(stderr, + "Slave '%s': Error: get flags failed. " + "Aborting\n", + slave_ifname); + goto out; + } + res = change_active(master_ifname, slave_ifname); + if (res) { + fprintf(stderr, + "Master '%s', Slave '%s': Error: " + "Change active failed\n", + master_ifname, slave_ifname); + } + } else { + /* Accept multiple slaves */ + do { + if (opt_d) { + /* detach a slave interface from the master */ + rv = get_slave_flags(slave_ifname); + if (rv) { + /* Can't work with this slave. */ + /* remember the error and skip it*/ + fprintf(stderr, + "Slave '%s': Error: get flags " + "failed. Skipping\n", + slave_ifname); + res = rv; + continue; } - } - - if (strncpy(if_netmask.ifr_name, slave_ifname, IFNAMSIZ) <= 0 - || ioctl(skfd, SIOCSIFNETMASK, &if_netmask) < 0) { - fprintf(stderr, - "Something broke setting the slave (%s) netmask: %s.\n", - slave_ifname, strerror(errno)); - } else { - if (verbose) { - unsigned char *ipaddr = if_netmask.ifr_netmask.sa_data; - printf("Set the slave's (%s) netmask to %d.%d.%d.%d.\n", - slave_ifname, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]); + rv = release(master_ifname, slave_ifname); + if (rv) { + fprintf(stderr, + "Master '%s', Slave '%s': Error: " + "Release failed\n", + master_ifname, slave_ifname); + res = rv; } - } - - 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)); } else { - if (verbose) - printf("Set the slave's (%s) flags %4.4x.\n", slave_ifname, if_flags.ifr_flags); - } - - /* Do the real thing */ - 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)); - } + /* attach a slave interface to the master */ + rv = get_if_settings(slave_ifname, slave_ifra); + if (rv) { + /* Can't work with this slave. */ + /* remember the error and skip it*/ + fprintf(stderr, + "Slave '%s': Error: get " + "settings failed: %s. " + "Skipping\n", + slave_ifname, strerror(rv)); + res = rv; + continue; } - else { - if ((ioctl(skfd, SIOCBONDCHANGEACTIVE, &if_flags) < 0) && - (ioctl(skfd, BOND_CHANGE_ACTIVE_OLD, &if_flags) < 0)) { - fprintf(stderr, "SIOCBONDCHANGEACTIVE: %s.\n", strerror(errno)); - } + rv = enslave(master_ifname, slave_ifname); + if (rv) { + fprintf(stderr, + "Master '%s', Slave '%s': Error: " + "Enslave failed\n", + master_ifname, slave_ifname); + res = rv; } } - } - } while ( (slave_ifname = *spp++) != NULL); + } while ((slave_ifname = *spp++) != NULL); + } - /* Close the socket. */ - (void) close(skfd); +out: + if (skfd >= 0) { + close(skfd); + } - return(goterr); + return res; } static short mif_flags; @@ -544,35 +505,34 @@ static int if_getconfig(char *ifname) { struct ifreq ifr; - int metric, mtu; /* Parameters of the master interface. */ + int metric, mtu; /* Parameters of the master interface. */ struct sockaddr dstaddr, broadaddr, netmask; + unsigned char *hwaddr; strcpy(ifr.ifr_name, ifname); if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) return -1; mif_flags = ifr.ifr_flags; printf("The result of SIOCGIFFLAGS on %s is %x.\n", - ifname, ifr.ifr_flags); + ifname, ifr.ifr_flags); strcpy(ifr.ifr_name, ifname); if (ioctl(skfd, SIOCGIFADDR, &ifr) < 0) return -1; printf("The result of SIOCGIFADDR is %2.2x.%2.2x.%2.2x.%2.2x.\n", - ifr.ifr_addr.sa_data[0], ifr.ifr_addr.sa_data[1], - ifr.ifr_addr.sa_data[2], ifr.ifr_addr.sa_data[3]); + ifr.ifr_addr.sa_data[0], ifr.ifr_addr.sa_data[1], + ifr.ifr_addr.sa_data[2], ifr.ifr_addr.sa_data[3]); strcpy(ifr.ifr_name, ifname); if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) return -1; - { - /* Gotta convert from 'char' to unsigned for printf(). */ - unsigned char *hwaddr = (unsigned char *)ifr.ifr_hwaddr.sa_data; - printf("The result of SIOCGIFHWADDR is type %d " - "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n", - ifr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1], - hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]); - } + /* Gotta convert from 'char' to unsigned for printf(). */ + hwaddr = (unsigned char *)ifr.ifr_hwaddr.sa_data; + printf("The result of SIOCGIFHWADDR is type %d " + "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n", + ifr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1], + hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]); strcpy(ifr.ifr_name, ifname); if (ioctl(skfd, SIOCGIFMETRIC, &ifr) < 0) { @@ -604,7 +564,7 @@ } else netmask = ifr.ifr_netmask; - return(0); + return 0; } static void if_print(char *ifname) @@ -618,15 +578,16 @@ ifc.ifc_len = sizeof(buff); ifc.ifc_buf = buff; if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) { - fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno)); + perror("SIOCGIFCONF failed"); return; } ifr = ifc.ifc_req; for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) { if (if_getconfig(ifr->ifr_name) < 0) { - fprintf(stderr, "%s: unknown interface.\n", - ifr->ifr_name); + fprintf(stderr, + "%s: unknown interface.\n", + ifr->ifr_name); continue; } @@ -634,12 +595,508 @@ /*ife_print(&ife);*/ } } else { - if (if_getconfig(ifname) < 0) - fprintf(stderr, "%s: unknown interface.\n", ifname); + if (if_getconfig(ifname) < 0) { + fprintf(stderr, + "%s: unknown interface.\n", ifname); + } + } +} + +static int get_drv_info(char *master_ifname) +{ + struct ifreq ifr; + struct ethtool_drvinfo info; + char *endptr; + + 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) { + if (errno == EOPNOTSUPP) { + goto out; + } + + saved_errno = errno; + v_print("Master '%s': Error: get bonding info failed %s\n", + master_ifname, strerror(saved_errno)); + return 1; + } + + abi_ver = strtoul(info.fw_version, &endptr, 0); + if (*endptr) { + v_print("Master '%s': Error: got invalid string as an ABI " + "version from the bonding module\n", + master_ifname); + return 1; + } + +out: + v_print("ABI ver is %d\n", abi_ver); + + return 0; +} + +static int change_active(char *master_ifname, char *slave_ifname) +{ + struct ifreq ifr; + int res = 0; + + if (!(slave_flags.ifr_flags & IFF_SLAVE)) { + fprintf(stderr, + "Illegal operation: The specified slave interface " + "'%s' is not a slave\n", + slave_ifname); + return 1; + } + + strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ); + strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ); + if ((ioctl(skfd, SIOCBONDCHANGEACTIVE, &ifr) < 0) && + (ioctl(skfd, BOND_CHANGE_ACTIVE_OLD, &ifr) < 0)) { + saved_errno = errno; + v_print("Master '%s': Error: SIOCBONDCHANGEACTIVE failed: " + "%s\n", + master_ifname, strerror(saved_errno)); + res = 1; + } + + return res; +} + +static int enslave(char *master_ifname, char *slave_ifname) +{ + struct ifreq ifr; + int res = 0; + + if (slave_flags.ifr_flags & IFF_SLAVE) { + fprintf(stderr, + "Illegal operation: The specified slave interface " + "'%s' is already a slave\n", + slave_ifname); + return 1; + } + + res = set_if_down(slave_ifname, slave_flags.ifr_flags); + if (res) { + fprintf(stderr, + "Slave '%s': Error: bring interface down failed\n", + slave_ifname); + return res; + } + + if (abi_ver < 2) { + /* Older bonding versions would panic if the slave has no IP + * address, so get the IP setting from the master. + */ + res = set_if_addr(master_ifname, slave_ifname); + if (res) { + fprintf(stderr, + "Slave '%s': Error: set address failed\n", + slave_ifname); + return res; + } + } else { + res = clear_if_addr(slave_ifname); + if (res) { + fprintf(stderr, + "Slave '%s': Error: clear address failed\n", + slave_ifname); + return res; + } + } + + if (master_mtu.ifr_mtu != slave_mtu.ifr_mtu) { + res = set_slave_mtu(slave_ifname, master_mtu.ifr_mtu); + if (res) { + fprintf(stderr, + "Slave '%s': Error: set MTU failed\n", + slave_ifname); + return res; + } + } + + if (hwaddr_set) { + /* Master already has an hwaddr + * so set it's hwaddr to the slave + */ + if (abi_ver < 1) { + /* The driver is using an old ABI, so + * the application sets the slave's + * hwaddr + */ + res = set_slave_hwaddr(slave_ifname, + &(master_hwaddr.ifr_hwaddr)); + if (res) { + fprintf(stderr, + "Slave '%s': Error: set hw address " + "failed\n", + slave_ifname); + goto undo_mtu; + } + + /* For old ABI the application needs to bring the + * slave back up + */ + res = set_if_up(slave_ifname, slave_flags.ifr_flags); + if (res) { + fprintf(stderr, + "Slave '%s': Error: bring interface " + "down failed\n", + slave_ifname); + goto undo_slave_mac; + } + } + /* The driver is using a new ABI, + * so the driver takes care of setting + * the slave's hwaddr and bringing + * it up again + */ + } else { + /* No hwaddr for master yet, so + * set the slave's hwaddr to it + */ + if (abi_ver < 1) { + /* For old ABI, the master needs to be + * down before setting it's hwaddr + */ + res = set_if_down(master_ifname, master_flags.ifr_flags); + if (res) { + fprintf(stderr, + "Master '%s': Error: bring interface " + "down failed\n", + master_ifname); + goto undo_mtu; + } + } + + res = set_master_hwaddr(master_ifname, + &(slave_hwaddr.ifr_hwaddr)); + if (res) { + fprintf(stderr, + "Master '%s': Error: set hw address " + "failed\n", + master_ifname); + goto undo_mtu; + } + + if (abi_ver < 1) { + /* For old ABI, bring the master + * back up + */ + res = set_if_up(master_ifname, master_flags.ifr_flags); + if (res) { + fprintf(stderr, + "Master '%s': Error: bring interface " + "up failed\n", + master_ifname); + goto undo_master_mac; + } + } + + hwaddr_set = 1; } + + /* Do the real thing */ + strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ); + strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ); + if ((ioctl(skfd, SIOCBONDENSLAVE, &ifr) < 0) && + (ioctl(skfd, BOND_ENSLAVE_OLD, &ifr) < 0)) { + saved_errno = errno; + v_print("Master '%s': Error: SIOCBONDENSLAVE failed: %s\n", + master_ifname, strerror(saved_errno)); + res = 1; + } + + if (res) { + goto undo_master_mac; + } + + return 0; + +/* rollback (best effort) */ +undo_master_mac: + set_master_hwaddr(master_ifname, &(master_hwaddr.ifr_hwaddr)); + hwaddr_set = 0; + goto undo_mtu; +undo_slave_mac: + set_slave_hwaddr(slave_ifname, &(slave_hwaddr.ifr_hwaddr)); +undo_mtu: + set_slave_mtu(slave_ifname, slave_mtu.ifr_mtu); + return res; +} + +static int release(char *master_ifname, char *slave_ifname) +{ + struct ifreq ifr; + int res = 0; + + if (!(slave_flags.ifr_flags & IFF_SLAVE)) { + fprintf(stderr, + "Illegal operation: The specified slave interface " + "'%s' is not a slave\n", + slave_ifname); + return 1; + } + + strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ); + strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ); + if ((ioctl(skfd, SIOCBONDRELEASE, &ifr) < 0) && + (ioctl(skfd, BOND_RELEASE_OLD, &ifr) < 0)) { + saved_errno = errno; + v_print("Master '%s': Error: SIOCBONDRELEASE failed: %s\n", + master_ifname, strerror(saved_errno)); + return 1; + } 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 MAC/IP + */ + res = set_if_down(slave_ifname, slave_flags.ifr_flags); + if (res) { + fprintf(stderr, + "Slave '%s': Error: bring interface " + "down failed\n", + slave_ifname); + } + } + + /* set to default mtu */ + set_slave_mtu(slave_ifname, 1500); + + return res; +} + +static int get_if_settings(char *ifname, struct dev_ifr ifra[]) +{ + int i; + int res = 0; + + for (i = 0; ifra[i].req_ifr; i++) { + strncpy(ifra[i].req_ifr->ifr_name, ifname, IFNAMSIZ); + res = ioctl(skfd, ifra[i].req_type, ifra[i].req_ifr); + if (res < 0) { + saved_errno = errno; + v_print("Interface '%s': Error: %s failed: %s\n", + ifname, ifra[i].req_name, + strerror(saved_errno)); + + return saved_errno; + } + } + + return 0; +} + +static int get_slave_flags(char *slave_ifname) +{ + int res = 0; + + strncpy(slave_flags.ifr_name, slave_ifname, IFNAMSIZ); + res = ioctl(skfd, SIOCGIFFLAGS, &slave_flags); + if (res < 0) { + saved_errno = errno; + v_print("Slave '%s': Error: SIOCGIFFLAGS failed: %s\n", + slave_ifname, strerror(saved_errno)); + } else { + v_print("Slave %s: flags %04X.\n", + slave_ifname, slave_flags.ifr_flags); + } + + return res; +} + +static int set_master_hwaddr(char *master_ifname, struct sockaddr *hwaddr) +{ + unsigned char *addr = (unsigned char *)hwaddr->sa_data; + struct ifreq ifr; + int res = 0; + + strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ); + memcpy(&(ifr.ifr_hwaddr), hwaddr, sizeof(struct sockaddr)); + res = ioctl(skfd, SIOCSIFHWADDR, &ifr); + if (res < 0) { + saved_errno = errno; + v_print("Master '%s': Error: SIOCSIFHWADDR failed: %s\n", + master_ifname, strerror(saved_errno)); + return res; + } else { + v_print("Master '%s': hardware address set to " + "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n", + master_ifname, addr[0], addr[1], addr[2], + addr[3], addr[4], addr[5]); + } + + return res; +} + +static int set_slave_hwaddr(char *slave_ifname, struct sockaddr *hwaddr) +{ + unsigned char *addr = (unsigned char *)hwaddr->sa_data; + struct ifreq ifr; + int res = 0; + + strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ); + memcpy(&(ifr.ifr_hwaddr), hwaddr, sizeof(struct sockaddr)); + res = ioctl(skfd, SIOCSIFHWADDR, &ifr); + if (res < 0) { + saved_errno = errno; + + v_print("Slave '%s': Error: SIOCSIFHWADDR failed: %s\n", + slave_ifname, strerror(saved_errno)); + + if (saved_errno == EBUSY) { + v_print(" The device is busy: it must be idle " + "before running this command.\n"); + } else if (saved_errno == EOPNOTSUPP) { + v_print(" The device does not support setting " + "the MAC address.\n" + " Your kernel likely does not support slave " + "devices.\n"); + } else if (saved_errno == EINVAL) { + v_print(" The device's address type does not match " + "the master's address type.\n"); + } + return res; + } else { + v_print("Slave '%s': hardware address set to " + "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n", + slave_ifname, addr[0], addr[1], addr[2], + addr[3], addr[4], addr[5]); + } + + return res; +} + +static int set_slave_mtu(char *slave_ifname, int mtu) +{ + struct ifreq ifr; + int res = 0; + + ifr.ifr_mtu = mtu; + strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ); + + res = ioctl(skfd, SIOCSIFMTU, &ifr); + if (res < 0) { + saved_errno = errno; + v_print("Slave '%s': Error: SIOCSIFMTU failed: %s\n", + slave_ifname, strerror(saved_errno)); + } else { + v_print("Slave '%s': MTU set to %d.\n", slave_ifname, mtu); + } + + return res; +} + +static int set_if_flags(char *ifname, short flags) +{ + struct ifreq ifr; + int res = 0; + + ifr.ifr_flags = flags; + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + + res = ioctl(skfd, SIOCSIFFLAGS, &ifr); + if (res < 0) { + saved_errno = errno; + v_print("Interface '%s': Error: SIOCSIFFLAGS failed: %s\n", + ifname, strerror(saved_errno)); + } else { + v_print("Interface '%s': flags set to %04X.\n", ifname, flags); + } + + return res; +} + +static int set_if_up(char *ifname, short flags) +{ + return set_if_flags(ifname, flags | IFF_UP); +} + +static int set_if_down(char *ifname, short flags) +{ + return set_if_flags(ifname, flags & ~IFF_UP); +} + +static int clear_if_addr(char *ifname) +{ + struct ifreq ifr; + int res = 0; + + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + ifr.ifr_addr.sa_family = AF_INET; + memset(ifr.ifr_addr.sa_data, 0, sizeof(ifr.ifr_addr.sa_data)); + + res = ioctl(skfd, SIOCSIFADDR, &ifr); + if (res < 0) { + saved_errno = errno; + v_print("Interface '%s': Error: SIOCSIFADDR failed: %s\n", + ifname, strerror(saved_errno)); + } else { + v_print("Interface '%s': address cleared\n", ifname); + } + + return res; +} + +static int set_if_addr(char *master_ifname, char *slave_ifname) +{ + struct ifreq ifr; + int res; + unsigned char *ipaddr; + int i; + struct { + char *req_name; + char *desc; + int g_ioctl; + int s_ioctl; + } ifra[] = { + {"IFADDR", "addr", SIOCGIFADDR, SIOCSIFADDR}, + {"DSTADDR", "destination addr", SIOCGIFDSTADDR, SIOCSIFDSTADDR}, + {"BRDADDR", "broadcast addr", SIOCGIFBRDADDR, SIOCSIFBRDADDR}, + {"NETMASK", "netmask", SIOCGIFNETMASK, SIOCSIFNETMASK}, + {NULL, NULL, 0, 0}, + }; + + for (i = 0; ifra[i].req_name; i++) { + strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ); + res = ioctl(skfd, ifra[i].g_ioctl, &ifr); + if (res < 0) { + int saved_errno = errno; + + v_print("Interface '%s': Error: SIOCG%s failed: %s\n", + master_ifname, ifra[i].req_name, + strerror(saved_errno)); + + ifr.ifr_addr.sa_family = AF_INET; + memset(ifr.ifr_addr.sa_data, 0, + sizeof(ifr.ifr_addr.sa_data)); + } + + strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ); + res = ioctl(skfd, ifra[i].s_ioctl, &ifr); + if (res < 0) { + int saved_errno = errno; + + v_print("Interface '%s': Error: SIOCS%s failed: %s\n", + slave_ifname, ifra[i].req_name, + strerror(saved_errno)); + + return res; + } + + ipaddr = ifr.ifr_addr.sa_data; + v_print("Interface '%s': set IP %s to %d.%d.%d.%d\n", + slave_ifname, ifra[i].desc, + ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]); + } + + return 0; } - /* * Local variables: * version-control: t @@ -650,3 +1107,4 @@ * compile-command: "gcc -Wall -Wstrict-prototypes -O -I/usr/src/linux/include ifenslave.c -o ifenslave" * End: */ + Index: Documentation/networking/ip-sysctl.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/networking/ip-sysctl.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/networking/ip-sysctl.txt 22 Jul 2004 19:50:30 -0000 1.1 +++ Documentation/networking/ip-sysctl.txt 4 Aug 2004 01:33:03 -0000 1.2 @@ -481,6 +481,55 @@ conf/{all,interface}/arp_filter is set to TRUE, it will be disabled otherwise +arp_announce - INTEGER + Define different restriction levels for announcing the local + source IP address from IP packets in ARP requests sent on + interface: + 0 - (default) Use any local address, configured on any interface + 1 - Try to avoid local addresses that are not in the target's + subnet for this interface. This mode is useful when target + hosts reachable via this interface require the source IP + address in ARP requests to be part of their logical network + configured on the receiving interface. When we generate the + request we will check all our subnets that include the + target IP and will preserve the source address if it is from + such subnet. If there is no such subnet we select source + address according to the rules for level 2. + 2 - Always use the best local address for this target. + In this mode we ignore the source address in the IP packet + and try to select local address that we prefer for talks with + the target host. Such local address is selected by looking + for primary IP addresses on all our subnets on the outgoing + interface that include the target IP address. If no suitable + local address is found we select the first local address + we have on the outgoing interface or on all other interfaces, + with the hope we will receive reply for our request and + even sometimes no matter the source IP address we announce. + + The max value from conf/{all,interface}/arp_announce is used. + + Increasing the restriction level gives more chance for + receiving answer from the resolved target while decreasing + the level announces more valid sender's information. + +arp_ignore - INTEGER + Define different modes for sending replies in response to + received ARP requests that resolve local target IP addresses: + 0 - (default): reply for any local target IP address, configured + on any interface + 1 - reply only if the target IP address is local address + configured on the incoming interface + 2 - reply only if the target IP address is local address + configured on the incoming interface and both with the + sender's IP address are part from same subnet on this interface + 3 - do not reply for local addresses configured with scope host, + only resolutions for global and link addresses are replied + 4-7 - reserved + 8 - do not reply for all local addresses + + The max value from conf/{all,interface}/arp_ignore is used + when ARP request is received on the {interface} + tag - INTEGER Allows you to write a number, which can be used as required. Default value is 0. @@ -623,4 +672,4 @@ Pekka Savola YOSHIFUJI Hideaki / USAGI Project -$Id: ip-sysctl.txt,v 1.1 2004/07/22 19:50:30 joff Exp $ +$Id: ip-sysctl.txt,v 1.2 2004/08/04 01:33:03 joff Exp $ Index: Documentation/networking/sk98lin.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/networking/sk98lin.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/networking/sk98lin.txt 22 Jul 2004 19:50:30 -0000 1.1 +++ Documentation/networking/sk98lin.txt 4 Aug 2004 01:33:03 -0000 1.2 @@ -1,11 +1,11 @@ -(C)Copyright 1999-2002 SysKonnect GmbH. +(C)Copyright 1999-2003 Marvell(R). All rights reserved =========================================================================== -sk98lin.txt created 19-Dec-2002 +sk98lin.txt created 15-Dec-2003 -Readme File for sk98lin v6.02 -SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX +Readme File for sk98lin v6.21 +Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX This file contains 1 Overview @@ -19,7 +19,6 @@ 5 Large Frame Support 6 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad) 7 Troubleshooting - 8 History =========================================================================== @@ -27,8 +26,9 @@ 1 Overview =========== -The sk98lin driver supports the SysKonnect SK-98xx and SK-95xx family -on Linux. It has been tested with Linux on Intel/x86 machines. +The sk98lin driver supports the Marvell Yukon and SysKonnect +SK-98xx/SK-95xx compliant Gigabit Ethernet Adapter on Linux. It has +been tested with Linux on Intel/x86 machines. *** @@ -75,8 +75,8 @@ To integrate the driver permanently into the kernel, proceed as follows: 1. Select the menu "Network device support" and then "Ethernet(1000Mbit)" -2. Mark "SysKonnect SK-98xx and SK-95xx Gigabit Ethernet Adapter - family support" with (*) +2. Mark "Marvell Yukon Chipset / SysKonnect SK-98xx family support" + with (*) 3. Build a new kernel when the configuration of the above options is finished. 4. Install the new kernel. @@ -87,8 +87,8 @@ 1. Enable 'loadable module support' in the kernel. 2. For automatic driver start, enable the 'Kernel module loader'. 3. Select the menu "Network device support" and then "Ethernet(1000Mbit)" -4. Mark "SysKonnect SK-98xx and SK-95xx Gigabit Ethernet Adapter - family support" with (M) +4. Mark "Marvell Yukon Chipset / SysKonnect SK-98xx family support" + with (M) 5. Execute the command "make modules". 6. Execute the command "make modules_install". The appropiate modules will be installed. @@ -100,21 +100,23 @@ To load the module manually, proceed as follows: 1. Enter "modprobe sk98lin". -2. If the SysKonnect SK-98xx adapter is installed in your computer and you - have a /proc file system, execute the command: +2. If a Marvell Yukon or SysKonnect SK-98xx adapter is installed in + your computer and you have a /proc file system, execute the command: "ls /proc/net/sk98lin/" This should produce an output containing a line with the following format: eth0 eth1 ... which indicates that your adapter has been found and initialized. - NOTE 1: If you have more than one SysKonnect SK-98xx adapter installed, - the adapters will be listed as 'eth0', 'eth1', 'eth2', etc. - For each adapter, repeat steps 3 and 4 below. - - NOTE 2: If you have other Ethernet adapters installed, your SysKonnect - SK-98xx adapter will be mapped to the next available number, - e.g. 'eth1'. The mapping is executed automatically. + NOTE 1: If you have more than one Marvell Yukon or SysKonnect SK-98xx + adapter installed, the adapters will be listed as 'eth0', + 'eth1', 'eth2', etc. + For each adapter, repeat steps 3 and 4 below. + + NOTE 2: If you have other Ethernet adapters installed, your Marvell + Yukon or SysKonnect SK-98xx adapter will be mapped to the + next available number, e.g. 'eth1'. The mapping is executed + automatically. The module installation message (displayed either in a system log file or on the console) prints a line for each adapter found containing the corresponding 'ethX'. @@ -141,7 +143,7 @@ Use 'ping ' to verify the connection to other computers on your network. 5. To check the adapter configuration view /proc/net/sk98lin/[devicename]. - For example by executing: + For example by executing: "cat /proc/net/sk98lin/eth0" Unload the module @@ -184,7 +186,7 @@ unload and reload the driver. The syntax of the driver parameters is: - modprobe sk98lin parameter=value1[,value2[,value3...]] + modprobe sk98lin parameter=value1[,value2[,value3...]] where value1 refers to the first adapter, value2 to the second etc. @@ -198,7 +200,7 @@ to FULL, and on the second adapter to HALF. Then, you must enter: - modprobe sk98lin AutoNeg=On,Off DupCap=Full,Half + modprobe sk98lin AutoNeg_A=On,Off DupCap_A=Full,Half NOTE: The number of adapters that can be configured this way is limited in the driver (file skge.c, constant SK_MAX_CARD_PARAM). @@ -256,9 +258,9 @@ port reports during auto-negotiation. It can be set for each port individually. Possible modes: - -- Sym = Symetric: both link partners are allowed to send + -- Sym = Symmetric: both link partners are allowed to send PAUSE frames - -- SymOrRem = SymetricOrRemote: both or only remote partner + -- SymOrRem = SymmetricOrRemote: both or only remote partner are allowed to send PAUSE frames -- LocSend = LocalSend: only local link partner is allowed to send PAUSE frames @@ -283,6 +285,101 @@ 4.2 Adapter Parameters ----------------------- +Connection Type (SK-98xx V2.0 copper adapters only) +--------------- +Parameter: ConType +Values: Auto, 100FD, 100HD, 10FD, 10HD +Default: Auto + +The parameter 'ConType' is a combination of all five per-port parameters +within one single parameter. This simplifies the configuration of both ports +of an adapter card! The different values of this variable reflect the most +meaningful combinations of port parameters. + +The following table shows the values of 'ConType' and the corresponding +combinations of the per-port parameters: + + ConType | DupCap AutoNeg FlowCtrl Role Speed + ----------+------------------------------------------------------ + Auto | Both On SymOrRem Auto Auto + 100FD | Full Off None Auto (ignored) 100 + 100HD | Half Off None Auto (ignored) 100 + 10FD | Full Off None Auto (ignored) 10 + 10HD | Half Off None Auto (ignored) 10 + +Stating any other port parameter together with this 'ConType' variable +will result in a merged configuration of those settings. This due to +the fact, that the per-port parameters (e.g. Speed_? ) have a higher +priority than the combined variable 'ConType'. + +NOTE: This parameter is always used on both ports of the adapter card. + +Interrupt Moderation +-------------------- +Parameter: Moderation +Values: None, Static, Dynamic +Default: None + +Interrupt moderation is employed to limit the maxmimum number of interrupts +the driver has to serve. That is, one or more interrupts (which indicate any +transmit or receive packet to be processed) are queued until the driver +processes them. When queued interrupts are to be served, is determined by the +'IntsPerSec' parameter, which is explained later below. + +Possible modes: + + -- None - No interrupt moderation is applied on the adapter card. + Therefore, each transmit or receive interrupt is served immediately + as soon as it appears on the interrupt line of the adapter card. + + -- Static - Interrupt moderation is applied on the adapter card. + All transmit and receive interrupts are queued until a complete + moderation interval ends. If such a moderation interval ends, all + queued interrupts are processed in one big bunch without any delay. + The term 'static' reflects the fact, that interrupt moderation is + always enabled, regardless how much network load is currently + passing via a particular interface. In addition, the duration of + the moderation interval has a fixed length that never changes while + the driver is operational. + + -- Dynamic - Interrupt moderation might be applied on the adapter card, + depending on the load of the system. If the driver detects that the + system load is too high, the driver tries to shield the system against + too much network load by enabling interrupt moderation. If - at a later + time - the CPU utilizaton decreases again (or if the network load is + negligible) the interrupt moderation will automatically be disabled. + +Interrupt moderation should be used when the driver has to handle one or more +interfaces with a high network load, which - as a consequence - leads also to a +high CPU utilization. When moderation is applied in such high network load +situations, CPU load might be reduced by 20-30%. + +NOTE: The drawback of using interrupt moderation is an increase of the round- +trip-time (RTT), due to the queueing and serving of interrupts at dedicated +moderation times. + +Interrupts per second +--------------------- +Parameter: IntsPerSec +Values: 30...40000 (interrupts per second) +Default: 2000 + +This parameter is only used, if either static or dynamic interrupt moderation +is used on a network adapter card. Using this paramter if no moderation is +applied, will lead to no action performed. + +This parameter determines the length of any interrupt moderation interval. +Assuming that static interrupt moderation is to be used, an 'IntsPerSec' +parameter value of 2000 will lead to an interrupt moderation interval of +500 microseconds. + +NOTE: The duration of the moderation interval is to be chosen with care. +At first glance, selecting a very long duration (e.g. only 100 interrupts per +second) seems to be meaningful, but the increase of packet-processing delay +is tremendous. On the other hand, selecting a very short moderation time might +compensate the use of any moderation being applied. + + Preferred Port -------------- Parameter: PrefPort @@ -365,11 +462,11 @@ 6 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad) ================================================================== -The SysKonnect Linux drivers are able to support VLAN and Link Aggregation -according to IEEE standards 802.1, 802.1q, and 802.3ad. These features are -only available after installation of open source modules available on the -Internet: -For VLAN go to: http://scry.wanfear.com/~greear/vlan.html +The Marvell Yukon/SysKonnect Linux drivers are able to support VLAN and +Link Aggregation according to IEEE standards 802.1, 802.1q, and 802.3ad. +These features are only available after installation of open source +modules available on the Internet: +For VLAN go to: http://www.candelatech.com/~greear/vlan.html For Link Aggregation go to: http://www.st.rim.or.jp/~yumo NOTE: SysKonnect GmbH does not offer any support for these open source @@ -448,7 +545,7 @@ Nr: 0xcc Msg: SkGeInitPort() cannot init running ports" Reason: You are using a driver compiled for single processor machines - on a multiprocessor machine with SMP (Symetric MultiProcessor) + on a multiprocessor machine with SMP (Symmetric MultiProcessor) kernel. Solution: Configure your kernel appropriately and recompile the kernel or the modules. @@ -459,208 +556,13 @@ support for help (linux@syskonnect.de). When contacting our technical support, please ensure that the following information is available: -- System Manufacturer and Model -- Boards in your system +- System Manufacturer and HW Informations (CPU, Memory... ) +- PCI-Boards in your system - Distribution - Kernel version - Driver version *** -8 History -========== -VERSION 6.00 (In-Kernel version) -New Features: -- Support for SK-98xx V2.0 adapters -- Support for gmac -- Support for kernel 2.4.x and kernel 2.2.x -- Zerocopy support for kernel 2.4.x with sendfile() -- Support for scatter-gather functionality with sendfile() -- Speed support for SK-98xx V2.0 adapters -- New ProcFs entries -- New module parameters -Problems fixed: -- ProcFS initialization -- csum packet error -- Ierror/crc counter error (#10767) -- rx_too_long counter error (#10751) -Known limitations: -- None - -VERSION 4.11 -New Features: -- none -Problems fixed: -- Error statistic counter fix (#10620) -- RLMT-Fixes (#10659, #10639, #10650) -- LM80 sensor initialization fix (#10623) -- SK-CSUM memory fixes (#10610). -Known limitations: -- None - -VERSION 4.10 -New Features: -- New ProcFs entries -Problems fixed: -- Corrected some printk's -Known limitations: -- None - -VERSION 4.09 -New Features: -- IFF_RUNNING support (link status) -- New ProcFs entries -Problems fixed: -- too long counters -- too short counters -- Kernel error compilation -Known limitations: -- None - -VERSION 4.06 (In-Kernel version) -Problems fixed: -- MTU init problems - -VERSION 4.04 -Problems fixed: -- removed VLAN error messages - -VERSION 4.02 (In-Kernel version) -New Features: -- Add Kernel 2.4 changes -Known limitations: -- None - -VERSION 4.01 (In-Kernel version) -Problems fixed: -- Full statistics support for DualNet mode -Known limitations: -- None - -VERSION 4.00 (In-Kernel version) -Problems fixed: -- Memory leak found -New Features: -- Proc filesystem integration -- DualNet functionality integrated -- Rlmt networks added -Known limitations: -- statistics partially incorrect in DualNet mode - -VERSION 3.04 (In-Kernel version) -Problems fixed: -- Driver start failed on UltraSPARC -- Rx checksum calculation for big endian machines did not work -- Jumbo frames were counted as input-errors in netstat - -VERSION 3.03 (Standalone version) -Problems fixed: -- Compilation did not find script "printver.sh" if "." not in PATH -Known limitations: -- None - -VERSION 3.02 (In-Kernel version) -Problems fixed: -- None -New Features: -- Integration in Linux kernel source (2.2.14 and 2.3.29) -Known limitations: -- None - -VERSION 3.01 -Problems fixed: -- None -New Features: -- Full source release -Known limitations: -- None - -VERSION 3.00 -Problems fixed: -- None -New Features: -- Support for 1000Base-T adapters (SK-9821 and SK-9822) -Known limitations: -- None - -VERSION 1.07 -Problems fixed: -- RlmtMode parameter value strings were wrong (#10437) -- Driver sent too many RLMT frames (#10439) -- Driver did not recognize network segmentation (#10440) -- RLMT switched too often on segmented network (#10441) -Known limitations: -- None - -VERSION 1.06 -Problems fixed: -- System panic'ed after some time when running with - RlmtMode=CheckOtherLink or RlmtMode=CheckSeg (#10421) - Panic message: "Kernel panic: skput: over ... dev: eth0" -- Driver did not switch back to default port when connected - back-to-back (#10422). -Changes: -- RlmtMode parameter names have changed -New features: -- There is now a version for ALPHA processors -Known limitations: -- None - -VERSION 1.05 -Problems fixed: -- Driver failed to load on kernels with version information - for module symbols enabled -Known limitations: -- None - -VERSION 1.04 -Problems fixed: -- Large frame support does work now (no autonegotiation - support for large frames, just manually selectable) -New Features: -- Receive checksumming in hardware -- Performance optimizations - Some numbers (on two PII-400 machines, back-to-back): - netpipe: 300 MBit/sec, with large frames: 470 MBit/sec - ttcp: 38 MByte/sec, with large frames: 60 MByte/sec - ttcp (UDP send): 66 MByte/sec, with large frames: 106 MByte/sec -Known limitations: -- None - -VERSION 1.03 -Problems fixed: -- Unloading with "rmmod" caused segmentation fault (#10415) -- The link LED flickered from time to time, if no link was - established (#10402) -- Installation problems with RedHat 6.0 (#10409) -New Features: -- Connection state ouput at "network connection up" -Known limitations: -- None - -VERSION 1.02 -Problems fixed: -- Failed with multiple adapters -- Failed with Single Port adapters -- Startup string was only displayed if adapter found -- No link could be established on certain switches when the switches were - rebooted. (#10377) -Known limitations: -- Segmentation fault at "rmmod" with kernel 2.2.3 on some machines - -VERSION 1.01 -Problems fixed: -- Sensor status was not set back to 'ok' after 'warning/error'. (#10386) -Changes: -- improved parallelism in driver - -VERSION 1.00 -Known limitations: -- not tested with all kernel versions (I don't have that much time :-) -- only x86 version available (if you need others, ask for it) -- source code not completely available ***End of Readme File*** - - - Index: Documentation/power/pci.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/power/pci.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/power/pci.txt 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/power/pci.txt 4 Aug 2004 01:33:04 -0000 1.2 @@ -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 Index: Documentation/s390/CommonIO =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/s390/CommonIO,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/s390/CommonIO 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/s390/CommonIO 4 Aug 2004 01:33:04 -0000 1.2 @@ -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. Index: Documentation/s390/Debugging390.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/s390/Debugging390.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/s390/Debugging390.txt 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/s390/Debugging390.txt 4 Aug 2004 01:33:04 -0000 1.2 @@ -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 Index: Documentation/s390/cds.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/s390/cds.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/s390/cds.txt 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/s390/cds.txt 4 Aug 2004 01:33:04 -0000 1.2 @@ -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 @@ -864,23 +1122,6 @@ not operational -EBUSY - the console device is already defined -reset_cons_dev - Reset Console Device - -This routine allows for resetting the console device specification. See -set_cons_dev() for details. - -int reset_cons_dev( int irq); - -irq : subchannel identifying the system console device - -The reset_cons_dev() function returns - - 0 - successful completion --EIO - an unhandled interrupt condition is pending for the - specified subchannel (irq) - status pending --ENODEV - irq doesn't specify a valid subchannel or the devive is - not operational - wait_cons_dev - Synchronously Wait for Console Processing The wait_cons_dev() routine is used by the console device driver when its Index: Documentation/serial/driver =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/serial/driver,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/serial/driver 22 Jul 2004 19:50:30 -0000 1.1 +++ Documentation/serial/driver 4 Aug 2004 01:33:04 -0000 1.2 @@ -3,7 +3,7 @@ -------------------- - $Id: driver,v 1.1 2004/07/22 19:50:30 joff Exp $ + $Id: driver,v 1.2 2004/08/04 01:33:04 joff Exp $ This document is meant as a brief overview of some aspects of the new serial Index: Documentation/sound/Introduction =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/sound/Introduction,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/sound/Introduction 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/sound/Introduction 4 Aug 2004 01:33:04 -0000 1.2 @@ -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. Index: Documentation/sound/OPL3-SA =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/sound/OPL3-SA,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/sound/OPL3-SA 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/sound/OPL3-SA 4 Aug 2004 01:33:04 -0000 1.2 @@ -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. Index: Documentation/sound/VIBRA16 =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/sound/VIBRA16,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/sound/VIBRA16 22 Jul 2004 19:50:29 -0000 1.1 +++ Documentation/sound/VIBRA16 4 Aug 2004 01:33:04 -0000 1.2 @@ -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 Index: Documentation/usb/uhci.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/usb/uhci.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/usb/uhci.txt 22 Jul 2004 19:50:28 -0000 1.1 +++ Documentation/usb/uhci.txt 4 Aug 2004 01:33:05 -0000 1.2 @@ -6,7 +6,7 @@ Deti Fliegl, deti@fliegl.de (executive slave) (lead voice) Thomas Sailer, sailer@ife.ee.ethz.ch (chief consultant) (cheer leader) - $Id: uhci.txt,v 1.1 2004/07/22 19:50:28 joff Exp $ + $Id: uhci.txt,v 1.2 2004/08/04 01:33:05 joff Exp $ This document and the new uhci sources can be found on http://hotswap.in.tum.de/usb Index: Documentation/usb/usb-serial.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/usb/usb-serial.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/usb/usb-serial.txt 22 Jul 2004 19:50:28 -0000 1.1 +++ Documentation/usb/usb-serial.txt 4 Aug 2004 01:33:05 -0000 1.2 @@ -88,6 +88,9 @@ necessary. Some devices need this before they can talk to the USB port properly. + Devices that are not compiled into the kernel can be specified with module + parameters. e.g. modprobe visor vendor=0x54c product=0x66 + There is a webpage and mailing lists for this portion of the driver at: http://usbvisor.sourceforge.net/ Index: Documentation/video4linux/meye.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/video4linux/meye.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/video4linux/meye.txt 22 Jul 2004 19:50:30 -0000 1.1 +++ Documentation/video4linux/meye.txt 4 Aug 2004 01:33:05 -0000 1.2 @@ -16,6 +16,28 @@ MJPEG hardware grabbing is supported via a private API (see below). +Hardware supported: +------------------- + +This driver supports the 'second' version of the MotionEye camera :) + +The first version was connected directly on the video bus of the Neomagic +video card and is unsupported. + +The second one, made by Kawasaki Steel is fully supported by this +driver (PCI vendor/device is 0x136b/0xff01) + +The third one, present in recent (more or less last year) Picturebooks +(C1M* models), is not supported. The manufacturer has given the specs +to the developers under a NDA (which allows the develoment of a GPL +driver however), but things are not moving very fast (see +http://r-engine.sourceforge.net/) (PCI vendor/device is 0x10cf/0x2011). + +There is a forth model connected on the USB bus in TR1* Vaio laptops. +This camera is not supported at all by the current driver, in fact +little information if any is available for this camera +(USB vendor/device is 0x054c/0x0107). + Driver options: --------------- Index: Documentation/video4linux/bttv/CARDLIST =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/video4linux/bttv/CARDLIST,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/video4linux/bttv/CARDLIST 22 Jul 2004 19:50:30 -0000 1.1 +++ Documentation/video4linux/bttv/CARDLIST 4 Aug 2004 01:33:05 -0000 1.2 @@ -7,7 +7,7 @@ card=5 - Diamond DTV2000 card=6 - AVerMedia TVPhone card=7 - MATRIX-Vision MV-Delta - card=8 - Lifeview FlyVideo II (Bt848) LR26 + card=8 - Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26 card=9 - IMS/IXmicro TurboTV card=10 - Hauppauge (bt878) card=11 - MIRO PCTV pro @@ -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,21 @@ 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 + card=105 - ProVideo PV143 + card=106 - PHYTEC VD-009-X1 MiniDIN (bt878) + card=107 - PHYTEC VD-009-X1 Combi (bt878) + card=108 - PHYTEC VD-009 MiniDIN (bt878) + card=109 - PHYTEC VD-009 Combi (bt878) tuner.o type=0 - Temic PAL (4002 FH5) @@ -139,3 +151,5 @@ 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 + type=41 - Philips PAL_MK (FI1216 MK) Index: Documentation/video4linux/bttv/Sound-FAQ =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/video4linux/bttv/Sound-FAQ,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/video4linux/bttv/Sound-FAQ 22 Jul 2004 19:50:30 -0000 1.1 +++ Documentation/video4linux/bttv/Sound-FAQ 4 Aug 2004 01:33:05 -0000 1.2 @@ -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 Index: Documentation/x86_64/mm.txt =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/Documentation/x86_64/mm.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Documentation/x86_64/mm.txt 22 Jul 2004 19:50:30 -0000 1.1 +++ Documentation/x86_64/mm.txt 4 Aug 2004 01:33:05 -0000 1.2 @@ -191,4 +191,4 @@ Andrea SuSE Andi Kleen SuSE -$Id: mm.txt,v 1.1 2004/07/22 19:50:30 joff Exp $ +$Id: mm.txt,v 1.2 2004/08/04 01:33:05 joff Exp $ Index: drivers/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/Makefile,v retrieving revision 1.1 retrieving revision 1.4 diff -u -r1.1 -r1.4 --- drivers/Makefile 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/Makefile 14 Feb 2006 18:16:57 -0000 1.4 @@ -6,9 +6,9 @@ # -mod-subdirs := dio hil mtd sbus video macintosh usb input telephony sgi ide \ +mod-subdirs := dio hil mtd mtd2k sbus video macintosh usb input telephony ide \ message/i2o message/fusion scsi md ieee1394 pnp isdn atm \ - fc4 net/hamradio i2c l3 acpi bluetooth serial + fc4 net/hamradio i2c l3 acpi bluetooth serial usb/gadget subdir-y := parport serial char block net sound misc media cdrom hotplug pld subdir-m := $(subdir-y) @@ -20,6 +20,7 @@ subdir-$(CONFIG_HIL) += hil subdir-$(CONFIG_PCMCIA) += pcmcia subdir-$(CONFIG_MTD) += mtd +subdir-$(CONFIG_MTD2K) += mtd2k subdir-$(CONFIG_SBUS) += sbus subdir-$(CONFIG_ZORRO) += zorro subdir-$(CONFIG_NUBUS) += nubus @@ -28,9 +29,9 @@ subdir-$(CONFIG_MAC) += macintosh subdir-$(CONFIG_PPC32) += macintosh subdir-$(CONFIG_USB) += usb +subdir-$(CONFIG_USB_GADGET) += usb/gadget 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 @@ -46,7 +47,7 @@ subdir-$(CONFIG_HAMRADIO) += net/hamradio subdir-$(CONFIG_I2C) += i2c subdir-$(CONFIG_L3) += l3 -subdir-$(CONFIG_ACPI) += acpi +subdir-$(CONFIG_ACPI_BOOT) += acpi subdir-$(CONFIG_BLUEZ) += bluetooth subdir-$(CONFIG_SSI) += ssi Index: drivers/acorn/char/i2c.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acorn/char/i2c.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acorn/char/i2c.c 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/acorn/char/i2c.c 4 Aug 2004 01:28:32 -0000 1.2 @@ -33,9 +33,13 @@ 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) + +/* + * Acorn machines store the year in the static RAM at + * location 128. + */ #define CMOS_YEAR (64 + 128) static inline int rtc_command(int cmd, void *data) @@ -49,51 +53,91 @@ } /* + * Update the century + year bytes in the CMOS RAM, ensuring + * that the check byte is correctly adjusted for the change. + */ +static int rtc_update_year(unsigned int new_year) +{ + unsigned char yr[2], chk; + struct mem cmos_year = { CMOS_YEAR, sizeof(yr), yr }; + struct mem cmos_check = { CMOS_CHECKSUM, 1, &chk }; + int ret; + + ret = rtc_command(MEM_READ, &cmos_check); + if (ret) + goto out; + ret = rtc_command(MEM_READ, &cmos_year); + if (ret) + goto out; + + chk -= yr[1] + yr[0]; + + yr[1] = new_year / 100; + yr[0] = new_year % 100; + + chk += yr[1] + yr[0]; + + ret = rtc_command(MEM_WRITE, &cmos_year); + if (ret == 0) + ret = rtc_command(MEM_WRITE, &cmos_check); + out: + return ret; +} + + +/* * Read the current RTC time and date, and update xtime. */ static void get_rtc_time(struct rtc_tm *rtctm, unsigned int *year) { unsigned char ctrl, yr[2]; struct mem rtcmem = { CMOS_YEAR, sizeof(yr), yr }; + int real_year, year_offset; /* * Ensure that the RTC is running. */ rtc_command(RTC_GETCTRL, &ctrl); if (ctrl & 0xc0) { - unsigned char new_ctrl; - - new_ctrl = ctrl & ~0xc0; + unsigned char new_ctrl = ctrl & ~0xc0; - printk("RTC: resetting control %02X -> %02X\n", - ctrl, new_ctrl); + printk(KERN_WARNING "RTC: resetting control %02x -> %02x\n", + ctrl, new_ctrl); rtc_command(RTC_SETCTRL, &new_ctrl); } + if (rtc_command(RTC_GETDATETIME, rtctm) || + rtc_command(MEM_READ, &rtcmem)) + return; + + real_year = yr[0]; + /* - * Acorn machines store the year in - * the static RAM at location 192. + * The RTC year holds the LSB two bits of the current + * year, which should reflect the LSB two bits of the + * CMOS copy of the year. Any difference indicates + * that we have to correct the CMOS version. */ - if (rtc_command(MEM_READ, &rtcmem)) - return; + year_offset = rtctm->year_off - (real_year & 3); + if (year_offset < 0) + /* + * RTC year wrapped. Adjust it appropriately. + */ + year_offset += 4; - if (rtc_command(RTC_GETDATETIME, rtctm)) - return; + *year = real_year + year_offset + yr[1] * 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 }; + unsigned char leap; int ret; leap = (!(year % 4) && (year % 100)) || !(year % 400); - if (rtctm->mon > 12 || rtctm->mday == 0) + if (rtctm->mon > 12 || rtctm->mon == 0 || rtctm->mday == 0) return -EINVAL; if (rtctm->mday > (days_in_mon[rtctm->mon] + (rtctm->mon == 2 && leap))) @@ -102,21 +146,16 @@ if (rtctm->hours >= 24 || rtctm->mins >= 60 || rtctm->secs >= 60) return -EINVAL; - 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; + /* + * The RTC's own 2-bit year must reflect the least + * significant two bits of the CMOS year. + */ + rtctm->year_off = (year % 100) & 3; - chk += yr[1] + yr[0]; + ret = rtc_command(RTC_SETDATETIME, rtctm); + if (ret == 0) + ret = rtc_update_year(year); - rtc_command(MEM_WRITE, &cmos_year); - rtc_command(MEM_WRITE, &cmos_check); - } return ret; } @@ -187,13 +226,12 @@ 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 put_user(1900, (unsigned long *)arg); } return -EINVAL; Index: drivers/acorn/net/ether1.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acorn/net/ether1.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acorn/net/ether1.c 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/acorn/net/ether1.c 4 Aug 2004 01:28:32 -0000 1.2 @@ -153,35 +153,35 @@ length -= thislen; __asm__ __volatile__( - "subs %3, %3, #2 - bmi 2f -1: ldr %0, [%1], #2 - mov %0, %0, lsl #16 - orr %0, %0, %0, lsr #16 - str %0, [%2], #4 - subs %3, %3, #2 - bmi 2f - ldr %0, [%1], #2 - mov %0, %0, lsl #16 - orr %0, %0, %0, lsr #16 - str %0, [%2], #4 - subs %3, %3, #2 - bmi 2f - ldr %0, [%1], #2 - mov %0, %0, lsl #16 - orr %0, %0, %0, lsr #16 - str %0, [%2], #4 - subs %3, %3, #2 - bmi 2f - ldr %0, [%1], #2 - mov %0, %0, lsl #16 - orr %0, %0, %0, lsr #16 - str %0, [%2], #4 - subs %3, %3, #2 - bpl 1b -2: adds %3, %3, #1 - ldreqb %0, [%1] - streqb %0, [%2]" +" subs %3, %3, #2 \n" +" bmi 2f \n" +"1: ldr %0, [%1], #2 \n" +" mov %0, %0, lsl #16 \n" +" orr %0, %0, %0, lsr #16 \n" +" str %0, [%2], #4 \n" +" subs %3, %3, #2 \n" +" bmi 2f \n" +" ldr %0, [%1], #2 \n" +" mov %0, %0, lsl #16 \n" +" orr %0, %0, %0, lsr #16 \n" +" str %0, [%2], #4 \n" +" subs %3, %3, #2 \n" +" bmi 2f \n" +" ldr %0, [%1], #2 \n" +" mov %0, %0, lsl #16 \n" +" orr %0, %0, %0, lsr #16 \n" +" str %0, [%2], #4 \n" +" subs %3, %3, #2 \n" +" bmi 2f \n" +" ldr %0, [%1], #2 \n" +" mov %0, %0, lsl #16 \n" +" orr %0, %0, %0, lsr #16 \n" +" str %0, [%2], #4 \n" +" subs %3, %3, #2 \n" +" bpl 1b \n" +"2: adds %3, %3, #1 \n" +" ldreqb %0, [%1] \n" +" streqb %0, [%2] \n" : "=&r" (used), "=&r" (data) : "r" (addr), "r" (thislen), "1" (data)); @@ -215,35 +215,35 @@ length -= thislen; __asm__ __volatile__( - "subs %3, %3, #2 - bmi 2f -1: ldr %0, [%2], #4 - strb %0, [%1], #1 - mov %0, %0, lsr #8 - strb %0, [%1], #1 - subs %3, %3, #2 - bmi 2f - ldr %0, [%2], #4 - strb %0, [%1], #1 - mov %0, %0, lsr #8 - strb %0, [%1], #1 - subs %3, %3, #2 - bmi 2f - ldr %0, [%2], #4 - strb %0, [%1], #1 - mov %0, %0, lsr #8 - strb %0, [%1], #1 - subs %3, %3, #2 - bmi 2f - ldr %0, [%2], #4 - strb %0, [%1], #1 - mov %0, %0, lsr #8 - strb %0, [%1], #1 - subs %3, %3, #2 - bpl 1b -2: adds %3, %3, #1 - ldreqb %0, [%2] - streqb %0, [%1]" +" subs %3, %3, #2 \n" +" bmi 2f \n" +"1: ldr %0, [%2], #4 \n" +" strb %0, [%1], #1 \n" +" mov %0, %0, lsr #8 \n" +" strb %0, [%1], #1 \n" +" subs %3, %3, #2 \n" +" bmi 2f \n" +" ldr %0, [%2], #4 \n" +" strb %0, [%1], #1 \n" +" mov %0, %0, lsr #8 \n" +" strb %0, [%1], #1 \n" +" subs %3, %3, #2 \n" +" bmi 2f \n" +" ldr %0, [%2], #4 \n" +" strb %0, [%1], #1 \n" +" mov %0, %0, lsr #8 \n" +" strb %0, [%1], #1 \n" +" subs %3, %3, #2 \n" +" bmi 2f \n" +" ldr %0, [%2], #4 \n" +" strb %0, [%1], #1 \n" +" mov %0, %0, lsr #8 \n" +" strb %0, [%1], #1 \n" +" subs %3, %3, #2 \n" +" bpl 1b \n" +"2: adds %3, %3, #1 \n" +" ldreqb %0, [%2] \n" +" streqb %0, [%1] \n" : "=&r" (used), "=&r" (data) : "r" (addr), "r" (thislen), "1" (data)); Index: drivers/acorn/scsi/cumana_1.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acorn/scsi/cumana_1.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acorn/scsi/cumana_1.c 22 Jul 2004 19:50:11 -0000 1.1 +++ drivers/acorn/scsi/cumana_1.c 4 Aug 2004 01:28:32 -0000 1.2 @@ -34,8 +34,8 @@ /* * $Log: cumana_1.c,v $ - * Revision 1.1 2004/07/22 19:50:11 joff - * Initial revision + * Revision 1.2 2004/08/04 01:28:32 joff + * merging 2.4.26-vrs1 * * Revision 1.3 1998/05/03 20:45:32 alan * ARM SCSI update. This adds the eesox driver and massively updates the @@ -156,20 +156,20 @@ ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0; outb(0x00, instance->io_port - 577); - if (instance->irq != IRQ_NONE) + if (instance->irq != SCSI_IRQ_NONE) if (request_irq(instance->irq, do_cumanascsi_intr, SA_INTERRUPT, "CumanaSCSI-1", NULL)) { printk("scsi%d: IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); - instance->irq = IRQ_NONE; + instance->irq = SCSI_IRQ_NONE; } - if (instance->irq == IRQ_NONE) { + if (instance->irq == SCSI_IRQ_NONE) { printk("scsi%d: interrupts not enabled. for better interactive performance,\n", instance->host_no); printk("scsi%d: please jumper the board for a free IRQ.\n", instance->host_no); } printk("scsi%d: at port %lX irq", instance->host_no, instance->io_port); - if (instance->irq == IRQ_NONE) + if (instance->irq == SCSI_IRQ_NONE) printk ("s disabled"); else printk (" %d", instance->irq); @@ -188,7 +188,7 @@ { int i; - if (shpnt->irq != IRQ_NONE) + if (shpnt->irq != SCSI_IRQ_NONE) free_irq (shpnt->irq, NULL); if (shpnt->io_port) release_region (shpnt->io_port, shpnt->n_io_port); Index: drivers/acorn/scsi/ecoscsi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acorn/scsi/ecoscsi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acorn/scsi/ecoscsi.c 22 Jul 2004 19:50:11 -0000 1.1 +++ drivers/acorn/scsi/ecoscsi.c 4 Aug 2004 01:28:32 -0000 1.2 @@ -33,8 +33,8 @@ /* * $Log: ecoscsi.c,v $ - * Revision 1.1 2004/07/22 19:50:11 joff - * Initial revision + * Revision 1.2 2004/08/04 01:28:32 joff + * merging 2.4.26-vrs1 * * Revision 1.2 1998/03/08 05:49:47 davem * Merge to 2.1.89 @@ -109,7 +109,7 @@ instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); instance->io_port = 0x80ce8000; instance->n_io_port = 144; - instance->irq = IRQ_NONE; + instance->irq = SCSI_IRQ_NONE; if (check_region (instance->io_port, instance->n_io_port)) { scsi_unregister (instance); @@ -133,20 +133,20 @@ return 0; } - if (instance->irq != IRQ_NONE) + if (instance->irq != SCSI_IRQ_NONE) if (request_irq(instance->irq, do_ecoscsi_intr, SA_INTERRUPT, "ecoscsi", NULL)) { printk("scsi%d: IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); - instance->irq = IRQ_NONE; + instance->irq = SCSI_IRQ_NONE; } - if (instance->irq != IRQ_NONE) { + if (instance->irq != SCSI_IRQ_NONE) { printk("scsi%d: eek! Interrupts enabled, but I don't think\n", instance->host_no); printk("scsi%d: that the board had an interrupt!\n", instance->host_no); } printk("scsi%d: at port %X irq", instance->host_no, instance->io_port); - if (instance->irq == IRQ_NONE) + if (instance->irq == SCSI_IRQ_NONE) printk ("s disabled"); else printk (" %d", instance->irq); @@ -160,7 +160,7 @@ int ecoscsi_release (struct Scsi_Host *shpnt) { - if (shpnt->irq != IRQ_NONE) + if (shpnt->irq != SCSI_IRQ_NONE) free_irq (shpnt->irq, NULL); if (shpnt->io_port) release_region (shpnt->io_port, shpnt->n_io_port); Index: drivers/acorn/scsi/oak.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acorn/scsi/oak.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acorn/scsi/oak.c 22 Jul 2004 19:50:11 -0000 1.1 +++ drivers/acorn/scsi/oak.c 4 Aug 2004 01:28:32 -0000 1.2 @@ -33,8 +33,8 @@ /* * $Log: oak.c,v $ - * Revision 1.1 2004/07/22 19:50:11 joff - * Initial revision + * Revision 1.2 2004/08/04 01:28:32 joff + * merging 2.4.26-vrs1 * * Revision 1.3 1998/05/03 20:45:37 alan * ARM SCSI update. This adds the eesox driver and massively updates the @@ -100,7 +100,7 @@ }; #define OAK_ADDRESS(card) (ecard_address((card), ECARD_MEMC, 0)) -#define OAK_IRQ(card) (IRQ_NONE) +#define OAK_IRQ(card) (SCSI_IRQ_NONE) /* * Function : int oakscsi_detect(Scsi_Host_Template * tpnt) * @@ -139,20 +139,20 @@ instance->n_io_port = 255; request_region (instance->io_port, instance->n_io_port, "Oak SCSI"); - if (instance->irq != IRQ_NONE) + if (instance->irq != SCSI_IRQ_NONE) if (request_irq(instance->irq, do_oakscsi_intr, SA_INTERRUPT, "Oak SCSI", NULL)) { printk("scsi%d: IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); - instance->irq = IRQ_NONE; + instance->irq = SCSI_IRQ_NONE; } - if (instance->irq != IRQ_NONE) { + if (instance->irq != SCSI_IRQ_NONE) { printk("scsi%d: eek! Interrupts enabled, but I don't think\n", instance->host_no); printk("scsi%d: that the board had an interrupt!\n", instance->host_no); } printk("scsi%d: at port %lX irq", instance->host_no, instance->io_port); - if (instance->irq == IRQ_NONE) + if (instance->irq == SCSI_IRQ_NONE) printk ("s disabled"); else printk (" %d", instance->irq); @@ -175,7 +175,7 @@ { int i; - if (shpnt->irq != IRQ_NONE) + if (shpnt->irq != SCSI_IRQ_NONE) free_irq (shpnt->irq, NULL); if (shpnt->io_port) release_region (shpnt->io_port, shpnt->n_io_port); Index: drivers/acpi/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/Config.in 22 Jul 2004 19:49:48 -0000 1.1 +++ drivers/acpi/Config.in 4 Aug 2004 01:28:33 -0000 1.2 @@ -1,17 +1,88 @@ # -# 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 + + 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 + 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 + else + if [ "$CONFIG_SMP" = "y" ]; then + define_bool CONFIG_ACPI_BOOT y + 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 Index: drivers/acpi/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/Makefile 22 Jul 2004 19:49:48 -0000 1.1 +++ drivers/acpi/Makefile 4 Aug 2004 01:28:33 -0000 1.2 @@ -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 Index: drivers/acpi/acpi_ksyms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/acpi_ksyms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/acpi_ksyms.c 22 Jul 2004 19:49:48 -0000 1.1 +++ drivers/acpi/acpi_ksyms.c 4 Aug 2004 01:28:33 -0000 1.2 @@ -1,64 +1,56 @@ /* - * ksyms.c - ACPI exported symbols + * acpi_ksyms.c - ACPI Kernel Symbols ($Revision: 1.2 $) * - * 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); Index: drivers/acpi/driver.c =================================================================== RCS file: drivers/acpi/driver.c diff -N drivers/acpi/driver.c --- drivers/acpi/driver.c 22 Jul 2004 19:49:48 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: drivers/acpi/os.c =================================================================== RCS file: drivers/acpi/os.c diff -N drivers/acpi/os.c --- drivers/acpi/os.c 22 Jul 2004 19:49:48 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,920 +0,0 @@ -/****************************************************************************** - * - * Module Name: os.c - Linux OSL functions - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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; -} - Index: drivers/acpi/debugger/Makefile =================================================================== RCS file: drivers/acpi/debugger/Makefile diff -N drivers/acpi/debugger/Makefile --- drivers/acpi/debugger/Makefile 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: drivers/acpi/debugger/dbcmds.c =================================================================== RCS file: drivers/acpi/debugger/dbcmds.c diff -N drivers/acpi/debugger/dbcmds.c --- drivers/acpi/debugger/dbcmds.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,996 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbcmds - debug commands and output routines - * $Revision: 1.1 $ - * - ******************************************************************************/ - -/* - * 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 */ Index: drivers/acpi/debugger/dbdisasm.c =================================================================== RCS file: drivers/acpi/debugger/dbdisasm.c diff -N drivers/acpi/debugger/dbdisasm.c --- drivers/acpi/debugger/dbdisasm.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,715 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbdisasm - parser op tree display routines - * $Revision: 1.1 $ - * - ******************************************************************************/ - -/* - * 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 */ - Index: drivers/acpi/debugger/dbdisply.c =================================================================== RCS file: drivers/acpi/debugger/dbdisply.c diff -N drivers/acpi/debugger/dbdisply.c --- drivers/acpi/debugger/dbdisply.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,794 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbdisply - debug display commands - * $Revision: 1.1 $ - * - ******************************************************************************/ - -/* - * 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 */ - Index: drivers/acpi/debugger/dbexec.c =================================================================== RCS file: drivers/acpi/debugger/dbexec.c diff -N drivers/acpi/debugger/dbexec.c --- drivers/acpi/debugger/dbexec.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,404 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbexec - debugger control method execution - * $Revision: 1.1 $ - * - ******************************************************************************/ - -/* - * 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 */ - - Index: drivers/acpi/debugger/dbfileio.c =================================================================== RCS file: drivers/acpi/debugger/dbfileio.c diff -N drivers/acpi/debugger/dbfileio.c --- drivers/acpi/debugger/dbfileio.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: 1.1 $ - * - ******************************************************************************/ - -/* - * 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 */ - Index: drivers/acpi/debugger/dbhistry.c =================================================================== RCS file: drivers/acpi/debugger/dbhistry.c diff -N drivers/acpi/debugger/dbhistry.c --- drivers/acpi/debugger/dbhistry.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,201 +0,0 @@ -/****************************************************************************** - * - * Module Name: dbhistry - debugger HISTORY command - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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 */ - Index: drivers/acpi/debugger/dbinput.c =================================================================== RCS file: drivers/acpi/debugger/dbinput.c diff -N drivers/acpi/debugger/dbinput.c --- drivers/acpi/debugger/dbinput.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,924 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbinput - user front-end to the AML debugger - * $Revision: 1.1 $ - * - ******************************************************************************/ - -/* - * 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 */ - Index: drivers/acpi/debugger/dbstats.c =================================================================== RCS file: drivers/acpi/debugger/dbstats.c diff -N drivers/acpi/debugger/dbstats.c --- drivers/acpi/debugger/dbstats.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,456 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbstats - Generation and display of ACPI table statistics - * $Revision: 1.1 $ - * - ******************************************************************************/ - -/* - * 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 */ Index: drivers/acpi/debugger/dbutils.c =================================================================== RCS file: drivers/acpi/debugger/dbutils.c diff -N drivers/acpi/debugger/dbutils.c --- drivers/acpi/debugger/dbutils.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,384 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbutils - AML debugger utilities - * $Revision: 1.1 $ - * - ******************************************************************************/ - -/* - * 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 */ - - Index: drivers/acpi/debugger/dbxface.c =================================================================== RCS file: drivers/acpi/debugger/dbxface.c diff -N drivers/acpi/debugger/dbxface.c --- drivers/acpi/debugger/dbxface.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,321 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbxface - AML Debugger external interfaces - * $Revision: 1.1 $ - * - ******************************************************************************/ - -/* - * 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 */ Index: drivers/acpi/dispatcher/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/dispatcher/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/dispatcher/Makefile 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/dispatcher/Makefile 4 Aug 2004 01:28:33 -0000 1.2 @@ -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) Index: drivers/acpi/dispatcher/dsfield.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/dispatcher/dsfield.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/dispatcher/dsfield.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/dispatcher/dsfield.c 4 Aug 2004 01:28:33 -0000 1.2 @@ -1,78 +1,98 @@ /****************************************************************************** * * Module Name: dsfield - Dispatcher field routines - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 { @@ -85,29 +105,48 @@ return_ACPI_STATUS (AE_AML_NO_OPERAND); } - /* - * Enter the Name_string into the namespace - */ - 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 (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + if (walk_state->deferred_node) { + node = walk_state->deferred_node; + status = AE_OK; + } + else { + /* + * 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 + */ + 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); + } } /* 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 = 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 +164,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 +192,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 +207,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 +228,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 +307,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 +320,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 +334,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 +378,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 +476,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 +535,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 +549,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); } Index: drivers/acpi/dispatcher/dsmethod.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/dispatcher/dsmethod.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/dispatcher/dsmethod.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/dispatcher/dsmethod.c 4 Aug 2004 01:28:33 -0000 1.2 @@ -1,51 +1,67 @@ /****************************************************************************** * * Module Name: dsmethod - Parser/Interpreter interface - control method parsing - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,21 +93,20 @@ 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", + acpi_ut_get_node_name (obj_handle), 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); } /* Create a mutex for the method if there is a concurrency limit */ - if ((obj_desc->method.concurrency != INFINITE_CONCURRENCY) && + if ((obj_desc->method.concurrency != ACPI_INFINITE_CONCURRENCY) && (!obj_desc->method.semaphore)) { status = acpi_os_create_semaphore (obj_desc->method.concurrency, obj_desc->method.concurrency, @@ -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", + acpi_ut_get_node_name (obj_handle), 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,47 +300,46 @@ return_ACPI_STATUS (status); } + if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) { + /* 1) Parse: Create a new walk state for the preempting walk */ - /* 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; - } + 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); + } - /* Create and init a Root Node */ - op = acpi_ps_alloc_op (AML_SCOPE_OP); - if (!op) { - status = AE_NO_MEMORY; - goto cleanup; - } + /* Create and init a Root Node */ - status = acpi_ds_init_aml_walk (next_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 */ - goto cleanup; - } + op = acpi_ps_create_scope_op (); + if (!op) { + status = AE_NO_MEMORY; + goto cleanup; + } - /* Begin AML parse */ + status = acpi_ds_init_aml_walk (next_walk_state, op, method_node, + obj_desc->method.aml_start, obj_desc->method.aml_length, + NULL, NULL, 1); + if (ACPI_FAILURE (status)) { + acpi_ds_delete_walk_state (next_walk_state); + goto cleanup; + } - status = acpi_ps_parse_aml (next_walk_state); - acpi_ps_delete_parse_tree (op); + /* Begin AML parse */ + 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; } - /* * The resolved arguments were put on the previous walk state's operand * stack. Operands on the previous walk state stack always @@ -353,8 +368,13 @@ 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)); + + if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { + status = obj_desc->method.implementation (next_walk_state); + return_ACPI_STATUS (status); + } return_ACPI_STATUS (AE_OK); @@ -362,18 +382,22 @@ /* On error, we must delete the new walk state */ cleanup: - acpi_ds_terminate_control_method (next_walk_state); + if (next_walk_state->method_desc) { + /* Decrement the thread count on the method parse tree */ + + next_walk_state->method_desc->method.thread_count--; + } + (void) acpi_ds_terminate_control_method (next_walk_state); acpi_ds_delete_walk_state (next_walk_state); return_ACPI_STATUS (status); - } /******************************************************************************* * - * 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 +408,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 +429,6 @@ return_ACPI_STATUS (status); } } - else { /* * Delete the return value if it will not be used by the @@ -413,24 +436,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 +463,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,21 +493,49 @@ * 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 */ + if (walk_state->method_desc->method.thread_count) { + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, + "*** Not deleting method namespace, there are still %d threads\n", + walk_state->method_desc->method.thread_count)); + } - walk_state->method_desc->method.thread_count--; if (!walk_state->method_desc->method.thread_count) { /* + * Support to dynamically change a method from not_serialized to + * Serialized if it appears that the method is written foolishly and + * does not support multiple thread execution. The best example of this + * is if such a method creates namespace objects and blocks. A second + * thread will fail with an AE_ALREADY_EXISTS exception + * + * This code is here because we must wait until the last thread exits + * before creating the synchronization semaphore. + */ + if ((walk_state->method_desc->method.concurrency == 1) && + (!walk_state->method_desc->method.semaphore)) { + status = acpi_os_create_semaphore (1, + 1, + &walk_state->method_desc->method.semaphore); + } + + /* * There are no more threads executing this method. Perform * additional cleanup. * @@ -493,7 +547,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 +561,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); } Index: drivers/acpi/dispatcher/dsmthdat.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/dispatcher/dsmthdat.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/dispatcher/dsmthdat.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/dispatcher/dsmthdat.c 4 Aug 2004 01:28:33 -0000 1.2 @@ -1,193 +1,196 @@ /******************************************************************************* * * Module Name: dsmthdat - control method arguments and local variables - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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. + * Do not copy the arg in order to implement call by reference + */ + status = acpi_ds_method_data_set_value (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; - FUNCTION_TRACE ("Ds_method_data_set_entry"); + ACPI_FUNCTION_TRACE ("ds_method_data_set_value"); - /* Get a pointer to the stack entry to set */ + 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))); - status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry); + /* Get the namespace node for the arg/local */ + + 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 */ + /* Install the object */ - *entry = 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); -} - + /* Uninitialized local/arg, return TYPE_ANY */ -/******************************************************************************* - * - * 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. - * - ******************************************************************************/ - -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,26 @@ 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: + ACPI_REPORT_ERROR (("Not Arg/Local opcode: %X\n", opcode)); + 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,117 +482,133 @@ /******************************************************************************* * - * 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; + union acpi_operand_object *new_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 the reference count on the object is more than one, we must + * take a copy of the object before we store. A reference count + * of exactly 1 means that the object was just created during the + * evaluation of an expression, and we can safely use it since it + * is not used anywhere else. + */ + new_obj_desc = obj_desc; + if (obj_desc->common.reference_count > 1) { + status = acpi_ut_copy_iobject_to_iobject (obj_desc, &new_obj_desc, walk_state); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } /* * If there is an object already in this slot, we either @@ -667,7 +616,7 @@ * 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 +624,52 @@ * 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: [%s]\n", + acpi_ut_get_descriptor_name (current_obj_desc))); + 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", + new_obj_desc, current_obj_desc)); + + /* + * Store this object to the Node + * (perform the indirect store) + */ + status = acpi_ex_store_object_to_node (new_obj_desc, + current_obj_desc->reference.object, walk_state); + + /* Remove local reference if we copied the object above */ + + if (new_obj_desc != obj_desc) { + acpi_ut_remove_reference (new_obj_desc); + } + return_ACPI_STATUS (status); + } } -#endif /* * Delete the existing object @@ -722,27 +678,20 @@ acpi_ds_method_data_delete_value (opcode, index, walk_state); } - /* - * Install the Obj_stack descriptor (*Src_desc) into + * Install the Obj descriptor (*new_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); - + status = acpi_ds_method_data_set_value (opcode, index, new_obj_desc, walk_state); - /* Error exit */ + /* Remove local reference if we copied the object above */ -cleanup: + if (new_obj_desc != obj_desc) { + acpi_ut_remove_reference (new_obj_desc); + } return_ACPI_STATUS (status); } + Index: drivers/acpi/dispatcher/dsobject.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/dispatcher/dsobject.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/dispatcher/dsobject.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/dispatcher/dsobject.c 4 Aug 2004 01:28:33 -0000 1.2 @@ -1,692 +1,617 @@ /****************************************************************************** * * Module Name: dsobject - Dispatcher object management routines - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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"); + ACPI_FUNCTION_TRACE_PTR ("ds_create_node", op); - 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)); - - 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: -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; + 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; + + + 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: + + obj_desc->string.pointer = op->common.value.string; + obj_desc->string.length = (u32) ACPI_STRLEN (op->common.value.string); - status = acpi_ds_build_internal_simple_obj (walk_state, op, obj_desc_ptr); + /* + * 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; - /* Re-type the object according to it's argument */ +#ifndef ACPI_NO_METHOD_EXECUTION + status = acpi_ds_method_data_get_node (AML_ARG_OP, obj_desc->reference.offset, + walk_state, (struct acpi_namespace_node **) &obj_desc->reference.object); +#endif + break; - node->type = obj_desc->common.type; + default: /* Other literals, etc.. */ - /* Init obj */ + if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) { + /* Node was saved in Op */ - status = acpi_ns_attach_object (node, obj_desc, (u8) node->type); + obj_desc->reference.node = op->common.node; + } - /* Remove local reference to the object */ + obj_desc->reference.opcode = opcode; + break; + } + break; + + + default: + + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unimplemented data type: %X\n", + ACPI_GET_OBJECT_TYPE (obj_desc))); + + status = AE_AML_OPERAND_TYPE; + break; + } - acpi_ut_remove_reference (obj_desc); return_ACPI_STATUS (status); } Index: drivers/acpi/dispatcher/dsopcode.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/dispatcher/dsopcode.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/dispatcher/dsopcode.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/dispatcher/dsopcode.c 4 Aug 2004 01:28:33 -0000 1.2 @@ -2,126 +2,121 @@ * * Module Name: dsopcode - Dispatcher Op Region support and handling of * "control" opcodes - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 (deferred) 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?? */ + /* Mark this parse as a deferred opcode */ - walk_state->parse_flags = 0; + walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP; + walk_state->deferred_node = node; - /* 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 +124,256 @@ 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 deferred arguments */ - 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); + /* Execute the opcode and arguments */ + + 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); } + /* Mark this execution as a deferred opcode */ + + walk_state->deferred_node = node; 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 Arg Init\n", + acpi_ut_get_node_name (node))); - 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 Buffer object + * + * 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_REPORT_ERROR (( + "No pointer back to NS node in buffer obj %p\n", obj_desc)); + return_ACPI_STATUS (AE_AML_INTERNAL); } - /* TBD: No Walk flags?? */ + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg 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 Package object + * + * 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_REPORT_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 Arg 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 Arg Init at AML %p\n", + acpi_ut_get_node_name (node), extra_desc->extra.aml_start)); + + /* Execute the argument AML */ + + 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 +381,278 @@ /* 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 not a NS Node [%s]\n", + acpi_ps_get_opcode_name (aml_opcode), acpi_ut_get_descriptor_name (result_desc))); 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 [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n", + acpi_ut_get_node_name (result_desc), + bit_offset + bit_count, + acpi_ut_get_node_name (buffer_desc->buffer.node), + 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 +661,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 +710,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 +739,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_FORMAT_UINT64 (obj_desc->region.address), obj_desc->region.length)); /* Now the address and length are valid for this opregion */ @@ -731,11 +755,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 +866,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 +893,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 +918,10 @@ break; - case AML_RETURN_OP: break; - default: break; } @@ -815,9 +932,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 +942,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 +1006,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 +1033,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 +1049,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 +1074,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 +1093,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 +1101,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); } Index: drivers/acpi/dispatcher/dsutils.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/dispatcher/dsutils.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/dispatcher/dsutils.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/dispatcher/dsutils.c 4 Aug 2004 01:28:33 -0000 1.2 @@ -1,48 +1,68 @@ /******************************************************************************* * * Module Name: dsutils - Dispatcher utilities - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 +72,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 +88,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 +114,99 @@ * 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) { @@ -212,10 +239,9 @@ return_VOID; } - 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 +255,90 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_create_operand + * FUNCTION: acpi_ds_resolve_operands + * + * PARAMETERS: walk_state - Current walk state with operands on stack + * + * RETURN: Status * - * PARAMETERS: Walk_state + * 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 reference, not by value. This means + * that the actual objects are passed, not copies of the objects. + */ + 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 * 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,72 +386,86 @@ /* * All prefixes have been handled, and the name is - * in Name_string + * in name_string */ + /* - * Differentiate between a namespace "create" operation - * versus a "lookup" operation (IMODE_LOAD_PASS2 vs. - * IMODE_EXECUTE) in order to support the creation of - * namespace objects during the execution of control methods. + * Special handling for buffer_field declarations. This is a deferred + * opcode that unfortunately defines the field name as the last + * parameter instead of the first. We get here when we are performing + * the deferred execution, so the actual name of the field is already + * in the namespace. We don't want to attempt to look it up again + * because we may be executing in a different scope than where the + * actual opcode exists. */ - parent_op = arg->parent; - op_info = acpi_ps_get_opcode_info (parent_op->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)) { - /* Enter name into namespace if not found */ - - interpreter_mode = IMODE_LOAD_PASS2; + if ((walk_state->deferred_node) && + (walk_state->deferred_node->type == ACPI_TYPE_BUFFER_FIELD) && + (arg_index != 0)) { + obj_desc = ACPI_CAST_PTR (union acpi_operand_object, walk_state->deferred_node); + status = AE_OK; } + else /* All other opcodes */ { + /* + * Differentiate between a namespace "create" operation + * versus a "lookup" operation (IMODE_LOAD_PASS2 vs. + * IMODE_EXECUTE) in order to support the creation of + * namespace objects during the execution of control methods. + */ + 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->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 */ - else { - /* Return a failure if name not found */ - - interpreter_mode = IMODE_EXECUTE; - } - - status = acpi_ns_lookup (walk_state->scope_info, name_string, - ACPI_TYPE_ANY, interpreter_mode, - NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE, - walk_state, - (acpi_namespace_node **) &obj_desc); - - /* Free the namestring created above */ - - ACPI_MEM_FREE (name_string); - - /* - * The only case where we pass through (ignore) a NOT_FOUND - * error is for the Cond_ref_of opcode. - */ - if (status == AE_NOT_FOUND) { - if (parent_op->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; - status = AE_OK; + interpreter_mode = ACPI_IMODE_LOAD_PASS2; } - else { - /* - * We just plain didn't find it -- which is a - * very serious error at this point - */ - status = AE_AML_NAME_NOT_FOUND; + /* Return a failure if name not found */ - /* TBD: Externalize Name_string and print */ + interpreter_mode = ACPI_IMODE_EXECUTE; + } - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Object name was not found in namespace\n")); + status = acpi_ns_lookup (walk_state->scope_info, name_string, + ACPI_TYPE_ANY, interpreter_mode, + ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, + walk_state, + 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. + */ + if (status == AE_NOT_FOUND) { + 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_CAST_PTR (union acpi_operand_object, acpi_gbl_root_node); + status = AE_OK; + } + else { + /* + * We just plain didn't find it -- which is a + * very serious error at this point + */ + status = AE_AML_NAME_NOT_FOUND; + } + } + + 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 +478,39 @@ 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 +526,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 +543,7 @@ acpi_ut_delete_object_desc (obj_desc); return_ACPI_STATUS (status); } - } + } /* Put the operand object on the object stack */ @@ -443,7 +552,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 +561,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 +575,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 +600,7 @@ /* Move on to next argument, if any */ - arg = arg->next; + arg = arg->common.next; arg_count++; } @@ -504,7 +613,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 +621,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); -} - - Index: drivers/acpi/dispatcher/dswexec.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/dispatcher/dswexec.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/dispatcher/dswexec.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/dispatcher/dswexec.c 4 Aug 2004 01:28:33 -0000 1.2 @@ -2,45 +2,64 @@ * * Module Name: dswexec - Dispatcher method execution callbacks; * dispatch to interpreter. - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,42 @@ 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++) { + else { /* - * Remove a reference to all operands, including both - * "Arguments" and "Targets". + * Treat constructs of the form "Store(local_x,local_x)" as noops when the + * Local is uninitialized. */ - acpi_ut_remove_reference (walk_state->operands[i]); - walk_state->operands[i] = NULL; + if ((status == AE_AML_UNINITIALIZED_LOCAL) && + (walk_state->opcode == AML_STORE_OP) && + (walk_state->operands[0]->common.type == ACPI_TYPE_LOCAL_REFERENCE) && + (walk_state->operands[1]->common.type == ACPI_TYPE_LOCAL_REFERENCE) && + (walk_state->operands[0]->reference.opcode == + walk_state->operands[1]->reference.opcode)) { + status = AE_OK; + } + 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 +457,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 +476,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 +493,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 +516,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 +532,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 +602,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 +629,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 +641,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 +652,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 +662,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); } Index: drivers/acpi/dispatcher/dswload.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/dispatcher/dswload.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/dispatcher/dswload.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/dispatcher/dswload.c 4 Aug 2004 01:28:33 -0000 1.2 @@ -1,48 +1,66 @@ /****************************************************************************** * * Module Name: dswload - Dispatcher namespace load callbacks - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,127 @@ /* 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]\n", 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. + */ + if (walk_state->deferred_node) { + /* This name is already in the namespace, get the node */ + + node = walk_state->deferred_node; + status = AE_OK; + break; + } + + 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 ((ACPI_DB_DISPATCH, "[%s] Cannot already exist\n", + acpi_ut_get_type_name (object_type))); + } + else { + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Both Find or Create allowed\n", + acpi_ut_get_type_name (object_type))); + } + + /* + * 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 +296,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 +317,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 +332,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 */ + + object_type = walk_state->op_info->object_type; + +#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->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 - data_type = acpi_ds_map_named_opcode_to_data_type (op->opcode); + 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 (op->opcode == AML_NAME_OP) { - /* For Name opcode, check the argument */ + 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 (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 (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 +444,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; + + ACPI_FUNCTION_TRACE ("ds_load2_begin_op"); - PROC_NAME ("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,112 +474,186 @@ 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); } /* * 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. + * + * Note: Name may already exist if we are executing a deferred opcode. */ - status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, data_type, - IMODE_EXECUTE, NS_NO_UPSEARCH, walk_state, &(node)); + if (walk_state->deferred_node) { + /* This name is already in the namespace, get the node */ + + node = walk_state->deferred_node; + status = AE_OK; + break; + } + + 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; + /* Initialize the new op */ - if (original) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "old %p new %p\n", original, node)); - - 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 +666,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 +714,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 +753,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 +775,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 +806,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 +842,6 @@ status = AE_OK; goto cleanup; - break; } /* Delete operands */ @@ -608,40 +852,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 +885,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 +905,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 +940,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); } Index: drivers/acpi/dispatcher/dswscope.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/dispatcher/dswscope.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/dispatcher/dswscope.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/dispatcher/dswscope.c 4 Aug 2004 01:28:33 -0000 1.2 @@ -1,36 +1,53 @@ /****************************************************************************** * * Module Name: dswscope - Scope stack manipulation - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,30 +100,30 @@ 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: Invalid object type: 0x%X\n", type)); } - /* Allocate a new scope object */ scope_info = acpi_ut_create_generic_state (); @@ -120,17 +137,38 @@ 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] (%s)", + acpi_ut_get_node_name (old_scope_info->scope.node), + acpi_ut_get_type_name (old_scope_info->common.value))); + } + else { + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, + "[\\___] (%s)", "ROOT")); + } + + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, + ", New scope -> [%4.4s] (%s)\n", + acpi_ut_get_node_name (scope_info->scope.node), + 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); - return_ACPI_STATUS (AE_OK); } /**************************************************************************** * - * FUNCTION: Acpi_ds_scope_stack_pop + * FUNCTION: acpi_ds_scope_stack_pop * * PARAMETERS: Type - The type of frame to be found * @@ -147,12 +185,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,11 +202,27 @@ 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] (%s), New scope -> ", + (u32) walk_state->scope_depth, + acpi_ut_get_node_name (scope_info->scope.node), + 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", + acpi_ut_get_node_name (new_scope_info->scope.node), + 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); - return_ACPI_STATUS (AE_OK); } Index: drivers/acpi/dispatcher/dswstate.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/dispatcher/dswstate.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/dispatcher/dswstate.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/dispatcher/dswstate.c 4 Aug 2004 01:28:33 -0000 1.2 @@ -1,63 +1,80 @@ /****************************************************************************** * * Module Name: dswstate - Dispatcher parse tree walk management routines - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 + * Index - Where to insert the object + * walk_state - Current Walk state * * RETURN: Status * - * DESCRIPTION: Push an object onto this walk's result stack + * DESCRIPTION: Insert an object onto this walk's result stack * ******************************************************************************/ 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 +84,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 +103,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 +112,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_result_remove + * FUNCTION: acpi_ds_result_remove * * PARAMETERS: Object - Where to return the popped object - * Walk_state - Current Walk state + * Index - Where to extract the object + * walk_state - Current Walk state * * RETURN: Status * @@ -109,14 +127,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 +144,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 +168,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 +177,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 +191,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 +216,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 +224,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); } @@ -218,12 +235,13 @@ return (AE_AML_NO_RETURN_VALUE); } + /******************************************************************************* * - * 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 +252,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 +269,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,25 +290,24 @@ 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)); - return (AE_OK); } /******************************************************************************* * - * 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,22 +317,22 @@ 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; if (!state) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result stack frame\n")); + ACPI_REPORT_ERROR (("No result stack frame during push\n")); 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 +345,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 +358,23 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_result_stack_push + * FUNCTION: acpi_ds_result_stack_push * - * PARAMETERS: Object - Object to push - * Walk_state - Current Walk state + * PARAMETERS: 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 +394,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 */ @@ -407,11 +421,10 @@ return (AE_AML_NO_OPERAND); } - 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,19 +565,20 @@ 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); } #endif + /******************************************************************************* * - * 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 +589,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 +622,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 +636,14 @@ 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 +675,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 +690,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 +709,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 +776,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 +788,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 +818,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 +853,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,22 +872,28 @@ /* 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 + * Op - Current parse op + * method_node - Control method NS node, if any + * aml_start - Start of AML + * aml_length - Length of AML + * Params - Method args, if any + * return_obj_desc - Where to store a return object, if any + * pass_number - 1, 2, or 3 * - * RETURN: None + * RETURN: Status * * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk * @@ -879,20 +901,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 +923,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,10 +936,9 @@ if (method_node) { walk_state->parser_state.start_node = method_node; - walk_state->walk_type = WALK_METHOD; - walk_state->method_node = method_node; - walk_state->method_desc = acpi_ns_get_attached_object (method_node); - + 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 */ @@ -928,13 +949,30 @@ /* 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 +984,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 +1003,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,12 +1020,11 @@ return; } - if (walk_state->parser_state.scope) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p walk still has a scope list\n", walk_state)); } - /* Always must free any linked control states */ + /* Always must free any linked control states */ while (walk_state->control_state) { state = walk_state->control_state; @@ -1023,7 +1058,7 @@ /****************************************************************************** * - * FUNCTION: Acpi_ds_delete_walk_state_cache + * FUNCTION: acpi_ds_delete_walk_state_cache * * PARAMETERS: None * @@ -1038,7 +1073,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); Index: drivers/acpi/events/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/events/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/events/Makefile 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/events/Makefile 4 Aug 2004 01:28:33 -0000 1.2 @@ -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) Index: drivers/acpi/events/evevent.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/events/evevent.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/events/evevent.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/events/evevent.c 4 Aug 2004 01:28:33 -0000 1.2 @@ -1,49 +1,62 @@ /****************************************************************************** * - * Module Name: evevent - Fixed and General Purpose Acpi_event - * handling and dispatch - * $Revision: 1.1 $ + * Module Name: evevent - Fixed Event handling and dispatch * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); -} Index: drivers/acpi/events/evmisc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/events/evmisc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/events/evmisc.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/events/evmisc.c 4 Aug 2004 01:28:33 -0000 1.2 @@ -1,42 +1,92 @@ /****************************************************************************** * - * Module Name: evmisc - ACPI device notification handler dispatch - * and ACPI Global Lock support - * $Revision: 1.1 $ + * Module Name: evmisc - Miscellaneous event manager support functions * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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: * @@ -47,22 +97,36 @@ * ******************************************************************************/ +#ifdef ACPI_DEBUG_OUTPUT +static const char *acpi_notify_value_names[] = +{ + "Bus Check", + "Device Check", + "Device Wake", + "Eject request", + "Device Check Light", + "Frequency Mismatch", + "Bus Mode Mismatch", + "Power Fault" +}; +#endif + 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"); /* - * For value 1 (Ejection Request), some device method may need to be run. + * For value 3 (Ejection Request), some device method may need to be run. * For value 2 (Device Wake) if _PRW exists, the _PS0 method may need to be run. * For value 0x80 (Status Change) on the power button or sleep button, * initiate soft-off or sleep operation? @@ -70,65 +134,47 @@ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Dispatching Notify(%X) on node %p\n", notify_value, node)); - switch (notify_value) { - case 0: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Notify value: Re-enumerate Devices\n")); - break; - - case 1: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Notify value: Ejection Request\n")); - break; - - case 2: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Notify value: Device Wake\n")); - break; - - case 0x80: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Notify value: Status Change\n")); - break; - - default: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Unknown Notify Value: %X \n", notify_value)); - break; + if (notify_value <= 7) { + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Notify value: %s\n", + acpi_notify_value_names[notify_value])); + } + else { + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "notify value: 0x2.2_x **Device Specific**\n", + notify_value)); } - /* - * 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 +195,9 @@ 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", + acpi_ut_get_node_name (node), node)); } return (status); @@ -158,7 +206,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ev_notify_dispatch + * FUNCTION: acpi_ev_notify_dispatch * * PARAMETERS: * @@ -169,42 +217,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 +261,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 +273,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ev_global_lock_thread + * FUNCTION: acpi_ev_global_lock_thread * * RETURN: None * @@ -237,25 +283,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 +318,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 +329,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 +337,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 +364,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 +376,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 +392,7 @@ /****************************************************************************** * - * FUNCTION: Acpi_ev_acquire_global_lock + * FUNCTION: acpi_ev_acquire_global_lock * * RETURN: Status * @@ -345,116 +401,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; + + ACPI_FUNCTION_TRACE ("ev_acquire_global_lock"); - 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; } + Index: drivers/acpi/events/evregion.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/events/evregion.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/events/evregion.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/events/evregion.c 4 Aug 2004 01:28:33 -0000 1.2 @@ -1,66 +1,93 @@ /****************************************************************************** * - * Module Name: evregion - ACPI Address_space (Op_region) handler dispatch - * $Revision: 1.1 $ + * Module Name: evregion - ACPI address_space (op_region) handler dispatch * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 + +static 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 @@ -115,27 +136,33 @@ * ******************************************************************************/ -static acpi_status +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; - FUNCTION_TRACE ("Ev_execute_reg_method"); + ACPI_FUNCTION_TRACE ("ev_execute_reg_method"); - if (region_obj->region.extra->extra.method_REG == NULL) { + region_obj2 = acpi_ns_get_secondary_object (region_obj); + if (!region_obj2) { + return_ACPI_STATUS (AE_NOT_EXIST); + } + + 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,132 +218,156 @@ 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.handler; if (!handler_desc) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "no handler for region(%p) [%s]\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "No handler for Region [%4.4s] (%p) [%s]\n", + acpi_ut_get_node_name (region_obj->region.node), 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.handler->address_space, handler, + ACPI_FORMAT_UINT64 (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); } + /******************************************************************************* * - * 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 +377,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; - FUNCTION_TRACE ("Ev_disassociate_region_from_handler"); + ACPI_FUNCTION_TRACE ("ev_detach_region"); - region_context = region_obj->region.extra->extra.region_context; + region_obj2 = acpi_ns_get_secondary_object (region_obj); + if (!region_obj2) { + return_VOID; + } + region_context = ®ion_obj2->extra.region_context; - /* - * Get the address handler from the region object - */ - handler_obj = region_obj->region.addr_handler; + /* Get the address handler from the region object */ + + handler_obj = region_obj->region.handler; 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, region_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.handler = 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 +499,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,60 +513,47 @@ ******************************************************************************/ 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; - - FUNCTION_TRACE ("Ev_associate_region_and_handler"); + ACPI_FUNCTION_TRACE ("ev_attach_region"); ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, - "Adding Region %p to address handler %p [%s]\n", - region_obj, handler_obj, acpi_ut_get_region_name (region_obj->region.space_id))); + "Adding Region [%4.4s] %p to address handler %p [%s]\n", + acpi_ut_get_node_name (region_obj->region.node), + 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 */ - /* - * 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; + region_obj->region.next = handler_obj->address_space.region_list; + handler_obj->address_space.region_list = region_obj; - /* - * set the region's handler - */ - region_obj->region.addr_handler = handler_obj; + /* Install the region's handler */ - /* - * Last thing, tell all users that this region is usable - */ - if (acpi_ns_is_locked) { - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + if (region_obj->region.handler) { + return_ACPI_STATUS (AE_ALREADY_EXISTS); } - status = acpi_ev_execute_reg_method (region_obj, 1); + region_obj->region.handler = handler_obj; + acpi_ut_add_reference (handler_obj); - if (acpi_ns_is_locked) { - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); - } - - return_ACPI_STATUS (status); + return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * 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 + * PARAMETERS: walk_namespace callback * - * 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 +564,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 +596,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,82 +609,141 @@ 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.handler; + 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); + + /* Connect the region to the new handler */ + + status = acpi_ev_attach_region (handler_obj, obj_desc, FALSE); + return (status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ev_reg_run + * + * PARAMETERS: walk_namespace callback + * + * DESCRIPTION: Run _REg method for region objects of the requested space_iD + * + ******************************************************************************/ + +acpi_status +acpi_ev_reg_run ( + acpi_handle obj_handle, + u32 level, + void *context, + void **return_value) +{ + union acpi_operand_object *handler_obj; + union acpi_operand_object *obj_desc; + struct acpi_namespace_node *node; + acpi_status status; + + + handler_obj = (union acpi_operand_object *) context; + + /* Parameter validation */ + + if (!handler_obj) { + return (AE_OK); + } + + /* Convert and validate the device handle */ + + node = acpi_ns_map_handle_to_node (obj_handle); + if (!node) { + return (AE_BAD_PARAMETER); + } /* - * Then connect the region to the new handler + * We only care about regions.and objects + * that are allowed to have address space handlers */ - status = acpi_ev_associate_region_and_handler (handler_obj, obj_desc, FALSE); + if ((node->type != ACPI_TYPE_REGION) && + (node != acpi_gbl_root_node)) { + return (AE_OK); + } + + /* Check for an existing internal object */ + + obj_desc = acpi_ns_get_attached_object (node); + if (!obj_desc) { + /* No object, just exit */ + + return (AE_OK); + } + + + /* Object is a Region */ + + if (obj_desc->region.space_id != handler_obj->address_space.space_id) { + /* + * This region is for a different address space + * -- just ignore it + */ + return (AE_OK); + } + status = acpi_ev_execute_reg_method (obj_desc, 1); return (status); } - Index: drivers/acpi/events/evrgnini.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/events/evrgnini.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/events/evrgnini.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/events/evrgnini.c 4 Aug 2004 01:28:33 -0000 1.2 @@ -1,47 +1,63 @@ /****************************************************************************** * - * Module Name: evrgnini- ACPI Address_space (Op_region) init - * $Revision: 1.1 $ + * Module Name: evrgnini- ACPI address_space (op_region) init * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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.handler; 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. - */ - - /* - * 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); + parent_node = acpi_ns_get_parent_node (region_obj->region.node); /* - * 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", + acpi_ut_get_node_name (pci_root_node), 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,144 @@ 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.handler = 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.handler; break; case ACPI_TYPE_PROCESSOR: - handler_obj = obj_desc->processor.addr_handler; + handler_obj = obj_desc->processor.handler; break; case ACPI_TYPE_THERMAL: - handler_obj = obj_desc->thermal_zone.addr_handler; + handler_obj = obj_desc->thermal_zone.handler; + 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)); + status = acpi_ev_attach_region (handler_obj, region_obj, + acpi_ns_locked); + /* - * Found it! Now update the region and the handler + * Tell all users that this region is usable by running the _REG + * method */ - acpi_ev_associate_region_and_handler (handler_obj, region_obj, - acpi_ns_locked); + if (acpi_ns_locked) { + status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } + + status = acpi_ev_execute_reg_method (region_obj, 1); + + if (acpi_ns_locked) { + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } + 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); Index: drivers/acpi/events/evsci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/events/evsci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/events/evsci.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/events/evsci.c 4 Aug 2004 01:28:33 -0000 1.2 @@ -2,281 +2,198 @@ * * Module Name: evsci - System Control Interrupt configuration and * legacy to ACPI mode state transition functions - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); } Index: drivers/acpi/events/evxface.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/events/evxface.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/events/evxface.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/events/evxface.c 4 Aug 2004 01:28:33 -0000 1.2 @@ -1,43 +1,59 @@ /****************************************************************************** * * Module Name: evxface - External interfaces for ACPI events - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); } Index: drivers/acpi/events/evxfevnt.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/events/evxfevnt.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/events/evxfevnt.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/events/evxfevnt.c 4 Aug 2004 01:28:33 -0000 1.2 @@ -1,43 +1,58 @@ /****************************************************************************** * * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,401 +145,605 @@ /******************************************************************************* * - * 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) { - - case ACPI_EVENT_FIXED: + if (event > ACPI_EVENT_MAX) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } - /* Decode the Fixed Acpi_event */ + /* + * 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); + } - switch (event) { - case ACPI_EVENT_PMTIMER: - register_id = TMR_EN; - break; + /* Make sure that the hardware responded */ - case ACPI_EVENT_GLOBAL: - register_id = GBL_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_POWER_BUTTON: - register_id = PWRBTN_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_SLEEP_BUTTON: - register_id = SLPBTN_EN; - break; + return_ACPI_STATUS (status); +} - case ACPI_EVENT_RTC: - register_id = RTC_EN; - break; - default: - return_ACPI_STATUS (AE_BAD_PARAMETER); - 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) + * + ******************************************************************************/ - /* - * 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_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; - break; + ACPI_FUNCTION_TRACE ("acpi_enable_gpe"); - 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 */ - /* Enable the requested 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; + } - if (flags & ACPI_EVENT_ENABLE) { - acpi_hw_enable_gpe (event); - } - if (flags & ACPI_EVENT_WAKE_ENABLE) { - acpi_hw_enable_gpe_for_wakeup (event); - } + /* Check for Wake vs Runtime GPE */ - break; + if (flags & ACPI_EVENT_WAKE_ENABLE) { + /* Ensure the requested wake GPE is disabled */ + status = acpi_hw_disable_gpe (gpe_event_info); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } - default: + /* Defer Enable of Wake GPE until sleep time */ - status = AE_BAD_PARAMETER; + acpi_hw_enable_gpe_for_wakeup (gpe_event_info); + } + else { + /* Enable the requested runtime GPE */ + + status = acpi_hw_enable_gpe (gpe_event_info); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } } +unlock_and_exit: + if (flags & ACPI_NOT_ISR) { + (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); + } return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_disable_event + * FUNCTION: acpi_disable_event * - * 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: Event - The fixed eventto be enabled + * Flags - Reserved * * RETURN: Status * - * DESCRIPTION: Disable an ACPI event (fixed and general purpose) + * DESCRIPTION: Disable an ACPI event (fixed) * ******************************************************************************/ acpi_status acpi_disable_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_disable_event"); + ACPI_FUNCTION_TRACE ("acpi_disable_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: + /* + * 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); + } - /* Decode the Fixed Acpi_event */ + 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); + } - switch (event) { - case ACPI_EVENT_PMTIMER: - register_id = TMR_EN; - break; + 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); + } - case ACPI_EVENT_GLOBAL: - register_id = GBL_EN; - break; + return_ACPI_STATUS (status); +} - case ACPI_EVENT_POWER_BUTTON: - register_id = PWRBTN_EN; - break; - case ACPI_EVENT_SLEEP_BUTTON: - register_id = SLPBTN_EN; - break; +/******************************************************************************* + * + * FUNCTION: acpi_disable_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: Disable an ACPI event (general purpose) + * + ******************************************************************************/ + +acpi_status +acpi_disable_gpe ( + acpi_handle gpe_device, + u32 gpe_number, + u32 flags) +{ + acpi_status status = AE_OK; + struct acpi_gpe_event_info *gpe_event_info; - case ACPI_EVENT_RTC: - register_id = RTC_EN; - break; - default: - return_ACPI_STATUS (AE_BAD_PARAMETER); - break; - } + ACPI_FUNCTION_TRACE ("acpi_disable_gpe"); + - /* - * 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); + /* 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: + /* + * 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); + } - /* Ensure that we have a valid GPE number */ +unlock_and_exit: + if (flags & ACPI_NOT_ISR) { + (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); + } + return_ACPI_STATUS (status); +} - if ((event > ACPI_GPE_MAX) || - (acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - /* Disable the requested GPE number */ +/******************************************************************************* + * + * FUNCTION: acpi_clear_event + * + * PARAMETERS: Event - The fixed event to be cleared + * + * RETURN: Status + * + * DESCRIPTION: Clear an ACPI event (fixed) + * + ******************************************************************************/ - if (flags & ACPI_EVENT_DISABLE) { - acpi_hw_disable_gpe (event); - } - if (flags & ACPI_EVENT_WAKE_DISABLE) { - acpi_hw_disable_gpe_for_wakeup (event); - } +acpi_status +acpi_clear_event ( + u32 event) +{ + acpi_status status = AE_OK; - break; + ACPI_FUNCTION_TRACE ("acpi_clear_event"); - default: - status = AE_BAD_PARAMETER; + + /* Decode the Fixed Event */ + + if (event > ACPI_EVENT_MAX) { + return_ACPI_STATUS (AE_BAD_PARAMETER); } + /* + * 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); + return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_clear_event + * FUNCTION: acpi_clear_gpe * - * PARAMETERS: Event - The fixed event or GPE to be cleared - * Type - The type of event + * 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 (fixed and general purpose) + * DESCRIPTION: Clear an ACPI event (general purpose) * ******************************************************************************/ acpi_status -acpi_clear_event ( - u32 event, - u32 type) +acpi_clear_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; - FUNCTION_TRACE ("Acpi_clear_event"); + ACPI_FUNCTION_TRACE ("acpi_clear_gpe"); - /* The Type must be either Fixed Acpi_event or GPE */ + /* Use semaphore lock if not executing at interrupt level */ - switch (type) { + if (flags & ACPI_NOT_ISR) { + status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } - case ACPI_EVENT_FIXED: + /* Ensure that we have a valid GPE number */ - /* Decode the Fixed Acpi_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; + } - switch (event) { - case ACPI_EVENT_PMTIMER: - register_id = TMR_STS; - break; + status = acpi_hw_clear_gpe (gpe_event_info); - case ACPI_EVENT_GLOBAL: - register_id = GBL_STS; - break; +unlock_and_exit: + if (flags & ACPI_NOT_ISR) { + (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); + } + return_ACPI_STATUS (status); +} - case ACPI_EVENT_POWER_BUTTON: - register_id = PWRBTN_STS; - break; - case ACPI_EVENT_SLEEP_BUTTON: - register_id = SLPBTN_STS; - break; +/******************************************************************************* + * + * FUNCTION: acpi_get_event_status + * + * PARAMETERS: Event - The fixed event + * Event Status - Where the current status of the event will + * be returned + * + * RETURN: Status + * + * DESCRIPTION: Obtains and returns the current status of the event + * + ******************************************************************************/ - case ACPI_EVENT_RTC: - register_id = RTC_STS; - break; +acpi_status +acpi_get_event_status ( + u32 event, + acpi_event_status *event_status) +{ + acpi_status status = AE_OK; - default: - return_ACPI_STATUS (AE_BAD_PARAMETER); - break; - } - /* - * 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_event_status"); - case ACPI_EVENT_GPE: + if (!event_status) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } - /* Ensure that we have a valid GPE number */ + /* Decode the Fixed Event */ - if ((event > ACPI_GPE_MAX) || - (acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } + if (event > ACPI_EVENT_MAX) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + /* Get the status of the requested fixed event */ + + status = acpi_get_register (acpi_gbl_fixed_event_info[event].status_register_id, + event_status, ACPI_MTX_LOCK); + + return_ACPI_STATUS (status); +} - acpi_hw_clear_gpe (event); - 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) + * + ******************************************************************************/ + +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; - default: + ACPI_FUNCTION_TRACE ("acpi_get_gpe_status"); + + /* 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 */ + + 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 */ + + status = acpi_hw_get_gpe_status (gpe_event_info, event_status); + +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); } Index: drivers/acpi/events/evxfregn.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/events/evxfregn.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/events/evxfregn.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/events/evxfregn.c 4 Aug 2004 01:28:33 -0000 1.2 @@ -2,84 +2,101 @@ * * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and * Address Spaces. - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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.handler; - /* 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,129 @@ /* 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, + acpi_ut_get_node_name (node), 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.handler; + + /* + * The Device object is the first reference on the handler_obj. + * Each region that uses the handler adds a reference. + */ + obj_desc->device.handler = 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); + status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, ACPI_UINT32_MAX, + ACPI_NS_WALK_UNLOCK, acpi_ev_install_handler, + handler_obj, NULL); /* - * Place this handler 1st on the list + * Now we can run the _REG methods for all Regions for this + * space ID. This is a separate walk in order to handle any + * interdependencies between regions and _REG methods. (i.e. handlers + * must be installed for all regions of this Space ID before we + * can run any _REG methods. */ - 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_reg_run, + 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 +359,6 @@ goto unlock_and_exit; } - /* Make sure the internal object exists */ obj_desc = acpi_ns_get_attached_object (node); @@ -322,25 +367,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.handler; + last_obj_ptr = &obj_desc->device.handler; 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 +394,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); } Index: drivers/acpi/executer/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/Makefile 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/Makefile 4 Aug 2004 01:28:34 -0000 1.2 @@ -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) Index: drivers/acpi/executer/exconfig.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exconfig.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exconfig.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exconfig.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -1,242 +1,464 @@ /****************************************************************************** * * Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes) - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 */ + + ACPI_MEMSET (&table_info, 0, sizeof (struct acpi_table_desc)); + + table_info.type = 5; + 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"); + + +#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 + + /* Find the ACPI table */ + + 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); + } + + /* Table 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; - FUNCTION_TRACE ("Ex_load_op"); + return_ACPI_STATUS (AE_OK); + } - /* TBD: [Unhandled] Object can be either a field or an opregion */ + /* Default nodes */ + start_node = walk_state->scope_info->scope.node; + parent_node = acpi_gbl_root_node; - /* Get the table header */ + /* root_path (optional parameter) */ - 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)); + 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); } } + *return_desc = 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_OK; + 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); } Index: drivers/acpi/executer/exconvrt.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exconvrt.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exconvrt.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exconvrt.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -1,49 +1,64 @@ /****************************************************************************** * * Module Name: exconvrt - Object conversion routines - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 + * result_desc - Where the new Integer object is returned + * walk_state - Current method state * * RETURN: Status * @@ -53,61 +68,41 @@ 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); + return_ACPI_STATUS (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); - } - - - /* * 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 * strings. @@ -120,23 +115,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 +150,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,166 +182,181 @@ } *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 + * result_desc - Where the new buffer object is returned + * 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; - - - FUNCTION_ENTRY (); - + u32 i; + u32 j; + u32 k = 0; + char hex_digit; + acpi_integer digit; + u32 remainder; + u32 length; + u8 leading_zero; + + + 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) { case 10: remainder = 0; - for (i = ACPI_MAX_DECIMAL_DIGITS; i > 0 ; i--) { + for (i = ACPI_MAX_DECIMAL_DIGITS; i > 0; i--) { /* Divide by nth factor of 10 */ digit = integer; - for (j = 1; j < i; j++) { - acpi_ut_short_divide (&digit, 10, &digit, &remainder); + for (j = 0; j < i; j++) { + (void) acpi_ut_short_divide (&digit, 10, &digit, &remainder); } /* Create the decimal digit */ - if (digit != 0) { + if (remainder != 0) { leading_zero = FALSE; } if (!leading_zero) { - string[k] = (u8) (ASCII_ZERO + remainder); + string[k] = (u8) (ACPI_ASCII_ZERO + remainder); k++; } } break; + case 16: /* Copy the integer to the buffer */ @@ -336,44 +364,48 @@ 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++; } } break; + default: break; } /* * Since leading zeros are supressed, we must check for the case where - * the integer equals 0. + * the integer equals 0 * * 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 - * Integer, Buffer, or String - * Walk_state - Current method state + * PARAMETERS: obj_desc - Object to be converted. Must be an + * Integer, Buffer, or String + * result_desc - Where the string object is returned + * Base - 10 or 16 + * max_length - Max length of the returned string + * walk_state - Current method state * * RETURN: Status * @@ -383,39 +415,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; + u8 *new_buf; + u8 *pointer; + u32 string_length; + u32 i; - 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 +457,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 +486,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 +513,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,93 +522,78 @@ 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; - } - - else { - /* Must copy the string first and then truncate it */ + default: + return_ACPI_STATUS (AE_TYPE); + } - 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. + * result_desc - Where the converted object is returned + * 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; - FUNCTION_TRACE ("Ex_convert_to_target_type"); + ACPI_FUNCTION_TRACE ("ex_convert_to_target_type"); + /* Default behavior */ + + *result_desc = source_desc; + /* * If required by the target, * perform implicit conversion on the source before we store it. @@ -592,7 +604,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 +613,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 +629,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 +645,24 @@ * 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: + ACPI_REPORT_ERROR (("Bad destination type during conversion: %X\n", + destination_type)); + status = AE_AML_INTERNAL; break; } break; @@ -651,21 +670,22 @@ 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))); + ACPI_REPORT_ERROR (("Bad Target Type (ARGI): %X\n", + GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args))) status = AE_AML_INTERNAL; } - /* * Source-to-Target conversion semantics: * Index: drivers/acpi/executer/excreate.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/excreate.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/excreate.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/excreate.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -1,48 +1,65 @@ /****************************************************************************** * * Module Name: excreate - Named object creation - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,81 @@ 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) || + (target_node->type == ACPI_TYPE_LOCAL_METHOD_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 = ACPI_CAST_PTR (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; + + case ACPI_TYPE_METHOD: + + /* + * 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_METHOD_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 +153,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 +165,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 +180,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 +192,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 +207,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 +238,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 +251,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 +269,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 +284,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 */ + /* Get the Namespace Node */ - 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,16 +314,15 @@ * 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); } ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Region Type - %s (%X)\n", acpi_ut_get_region_name (region_space), region_space)); - /* Create the region descriptor */ obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_REGION); @@ -261,21 +331,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 +348,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 */ + + 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: -*/ +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,14 +492,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 +509,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,9 +547,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 +556,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 +574,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 */ @@ -506,34 +599,39 @@ obj_desc->method.aml_start = aml_start; obj_desc->method.aml_length = aml_length; - /* disassemble the method flags */ - + /* + * Disassemble the method flags. Split off the Arg Count + * for efficiency + */ method_flags = (u8) operand[1]->integer.value; - obj_desc->method.method_flags = method_flags; - obj_desc->method.param_count = (u8) (method_flags & METHOD_FLAGS_ARG_COUNT); + obj_desc->method.method_flags = (u8) (method_flags & ~AML_METHOD_ARG_COUNT); + obj_desc->method.param_count = (u8) (method_flags & AML_METHOD_ARG_COUNT); /* * Get the concurrency count. If required, a semaphore will be * created for this method when it is parsed. */ - if (method_flags & METHOD_FLAGS_SERIALIZED) { + if (acpi_gbl_all_methods_serialized) { + obj_desc->method.concurrency = 1; + obj_desc->method.method_flags |= AML_METHOD_SERIALIZED; + } + else if (method_flags & AML_METHOD_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); + (((method_flags & AML_METHOD_SYNCH_LEVEL) >> 4) + 1); } - else { - obj_desc->method.concurrency = INFINITE_CONCURRENCY; + obj_desc->method.concurrency = ACPI_INFINITE_CONCURRENCY; } /* 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 */ Index: drivers/acpi/executer/exdump.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exdump.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exdump.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exdump.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -1,271 +1,196 @@ /****************************************************************************** * * Module Name: exdump - Interpreter debug output routines - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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! + * This usually indicates that something serious is wrong */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Null stack entry ptr\n")); - return (AE_OK); + acpi_os_printf ("Null Object Descriptor\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 is a 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 node or operand object: [%s]\n", + obj_desc, acpi_ut_get_descriptor_name (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) { - /* Value is a Number */ + if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { + /* Value is an Integer */ - 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_FORMAT_UINT64 (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 */ + /* Value is an Integer */ - 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_FORMAT_UINT64 (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 */ + /* 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 +200,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 +212,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 +226,102 @@ 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_FORMAT_UINT64 (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_FORMAT_UINT64 (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 +329,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 +398,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 +445,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_FORMAT_UINT64 (value)); +#endif +} + + +/***************************************************************************** + * + * FUNCTION: acpi_ex_dump_node * * PARAMETERS: *Node - Descriptor to dump * Flags - Force display @@ -587,37 +508,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", acpi_ut_get_node_name (node)); + 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 +546,241 @@ 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 an ACPI operand object: [%s]\n", + obj_desc, acpi_ut_get_descriptor_name (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_FORMAT_UINT64 (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 ("Handler", obj_desc->device.handler); + 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 ("Handler", obj_desc->region.handler); + 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 ("Handler", obj_desc->processor.handler); 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 ("Handler", obj_desc->thermal_zone.handler); 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_METHOD_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; } Index: drivers/acpi/executer/exfield.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exfield.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exfield.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exfield.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -1,69 +1,85 @@ /****************************************************************************** * * Module Name: exfield - ACPI AML (p-code) execution - field manipulation - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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, + "field_read [TO]: Obj %p, Type %X, Buf %p, byte_len %X\n", + obj_desc, ACPI_GET_OBJECT_TYPE (obj_desc), buffer, (u32) length)); + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "field_read [FROM]: bit_len %X, bit_off %X, byte_off %X\n", + obj_desc->common_field.bit_length, + obj_desc->common_field.start_field_bit_offset, + obj_desc->common_field.base_byte_offset)); - /* 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,61 @@ 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, + "field_write [FROM]: Obj %p (%s:%X), Buf %p, byte_len %X\n", + source_desc, acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (source_desc)), + ACPI_GET_OBJECT_TYPE (source_desc), buffer, length)); + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "field_write [TO]: Obj %p (%s:%X), bit_len %X, bit_off %X, byte_off %X\n", + obj_desc, acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (obj_desc)), + ACPI_GET_OBJECT_TYPE (obj_desc), + 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); } + Index: drivers/acpi/executer/exfldio.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exfldio.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exfldio.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exfldio.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -1,73 +1,95 @@ /****************************************************************************** * * Module Name: exfldio - Aml Field I/O - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 Region if necessary and + * validate the request. * ******************************************************************************/ 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); } @@ -75,31 +97,50 @@ * If the Region Address and Length have not been previously evaluated, * evaluate them now and save the results. */ - if (!(rgn_desc->region.flags & AOPOBJ_DATA_VALID)) { - + if (!(rgn_desc->common.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); + } + +#ifdef ACPI_UNDER_DEVELOPMENT + /* + * If the Field access is any_acc, we can now compute the optimal + * access (because we know know the length of the parent region) + */ + if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) { + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } +#endif + /* * 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", + acpi_ut_get_node_name (obj_desc->common_field.node), + obj_desc->common_field.access_byte_width, + acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length)); } /* @@ -107,12 +148,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", + acpi_ut_get_node_name (obj_desc->common_field.node), + obj_desc->common_field.base_byte_offset, + field_datum_byte_offset, obj_desc->common_field.access_byte_width, + acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length)); - return_ACPI_STATUS (AE_AML_REGION_LIMIT); + if (!acpi_strict) { + /* + * 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); + + 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); + } } return_ACPI_STATUS (AE_OK); @@ -121,593 +196,753 @@ /******************************************************************************* * - * 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; - FUNCTION_TRACE_U32 ("Ex_read_field_datum", field_datum_byte_offset); + ACPI_FUNCTION_TRACE ("ex_access_region"); - if (!value) { - local_value = 0; - value = &local_value; /* support reads without saving value */ + /* + * 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); } - /* Clear the entire return buffer first, [Very Important!] */ - - *value = 0; - /* - * Buffer_fields - Read from a Buffer - * Other Fields - Read from a Operation Region. + * 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 */ - switch (obj_desc->common.type) { - case ACPI_TYPE_BUFFER_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; - /* - * For Buffer_fields, we only need to copy the data from the - * source buffer. Length is the field width in bytes. - */ - 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); - status = AE_OK; - break; + 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], Width %X, byte_base %X, Offset %X at %8.8X%8.8X\n", + acpi_ut_get_region_name (rgn_desc->region.space_id), + rgn_desc->region.space_id, + obj_desc->common_field.access_byte_width, + obj_desc->common_field.base_byte_offset, + field_datum_byte_offset, + ACPI_FORMAT_UINT64 (address))); - case INTERNAL_TYPE_REGION_FIELD: - case INTERNAL_TYPE_BANK_FIELD: + /* Invoke the appropriate address_space/op_region handler */ - /* - * 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, "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))); - - /* 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); - status = acpi_ev_address_space_dispatch (rgn_desc, ACPI_READ_ADR_SPACE, - address, obj_desc->common_field.access_bit_width, value); + if (ACPI_FAILURE (status)) { if (status == AE_NOT_IMPLEMENTED) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region %s(%X) not implemented\n", + 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_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)); } - 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, "Returned value=%08X \n", *value)); - return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ex_get_buffer_datum + * FUNCTION: acpi_ex_register_overflow * - * PARAMETERS: Merged_datum - Value to store - * Buffer - Receiving buffer - * Byte_granularity - 1/2/4 Granularity of the field - * (aka Datum Size) - * Offset - Datum offset into the buffer + * PARAMETERS: *obj_desc - Register(Field) to be written + * Value - Value to be stored * - * RETURN: none + * RETURN: TRUE if value overflows the field, FALSE otherwise * - * DESCRIPTION: Store the merged datum to the buffer according to the - * byte granularity + * 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. * ******************************************************************************/ -static void -acpi_ex_get_buffer_datum( - u32 *datum, - void *buffer, - u32 byte_granularity, - u32 offset) +u8 +acpi_ex_register_overflow ( + union acpi_operand_object *obj_desc, + acpi_integer value) { - FUNCTION_ENTRY (); - + 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); + } - switch (byte_granularity) { - case ACPI_FIELD_BYTE_GRANULARITY: - *datum = ((u8 *) buffer) [offset]; - break; + 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); + } - case ACPI_FIELD_WORD_GRANULARITY: - MOVE_UNALIGNED16_TO_32 (datum, &(((u16 *) buffer) [offset])); - break; + /* The Value will fit into the field with no truncation */ - case ACPI_FIELD_DWORD_GRANULARITY: - MOVE_UNALIGNED32_TO_32 (datum, &(((u32 *) buffer) [offset])); - break; - } + return (FALSE); } /******************************************************************************* * - * FUNCTION: Acpi_ex_set_buffer_datum + * FUNCTION: acpi_ex_field_datum_io * - * PARAMETERS: Merged_datum - Value to store - * Buffer - Receiving buffer - * Byte_granularity - 1/2/4 Granularity of the field - * (aka Datum Size) - * Offset - Datum offset into the buffer + * 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: none + * RETURN: Status * - * DESCRIPTION: Store the merged datum to the buffer according to the - * byte granularity + * 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) * ******************************************************************************/ -static void -acpi_ex_set_buffer_datum ( - u32 merged_datum, - void *buffer, - u32 byte_granularity, - u32 offset) +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; - FUNCTION_ENTRY (); + ACPI_FUNCTION_TRACE_U32 ("ex_field_datum_io", field_datum_byte_offset); - switch (byte_granularity) { - case ACPI_FIELD_BYTE_GRANULARITY: - ((u8 *) buffer) [offset] = (u8) merged_datum; + + 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; + } + + /* + * The four types of fields are: + * + * buffer_field - Read/write from/to a Buffer + * region_field - Read/write from/to a Operation Region. + * bank_field - Write to a Bank Register, then read/write from/to an op_region + * index_field - Write to an Index Register, then read/write from/to a Data Register + */ + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { + case 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); + } + } + + 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 ACPI_FIELD_WORD_GRANULARITY: - MOVE_UNALIGNED16_TO_16 (&(((u16 *) buffer)[offset]), &merged_datum); + + 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 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_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); + } + + /* + * Now that the Bank has been selected, fall through to the + * region_field case and write the datum to the Operation Region + */ + + /*lint -fallthrough */ + + + 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_FIELD_DWORD_GRANULARITY: - MOVE_UNALIGNED32_TO_32 (&(((u32 *) buffer)[offset]), &merged_datum); + + 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); + } + + /* Write the index value to the index_register (itself a region_field) */ + + field_datum_byte_offset += obj_desc->index_field.value; + + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Write to Index Register: Value %8.8X\n", + field_datum_byte_offset)); + + status = acpi_ex_insert_into_field (obj_desc->index_field.index_obj, + &field_datum_byte_offset, + sizeof (field_datum_byte_offset)); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "I/O to Data Register: value_ptr %p\n", + value)); + + 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, sizeof (acpi_integer)); + } + else { + /* Write the datum to the data_register */ + + status = acpi_ex_insert_into_field (obj_desc->index_field.data_obj, + value, sizeof (acpi_integer)); + } + break; + + + default: + + ACPI_REPORT_ERROR (("Wrong object type in field I/O %X\n", + ACPI_GET_OBJECT_TYPE (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, Width %d\n", + ACPI_FORMAT_UINT64 (*value), + obj_desc->common_field.access_byte_width)); + } + else { + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Written %8.8X%8.8X, Width %d\n", + ACPI_FORMAT_UINT64 (*value), + obj_desc->common_field.access_byte_width)); + } + } + + return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ex_extract_from_field + * FUNCTION: acpi_ex_write_with_update_rule * - * PARAMETERS: *Obj_desc - Field to be read - * *Value - Where to store value + * PARAMETERS: *obj_desc - Field to be set + * Value - Value to store * * RETURN: Status * - * DESCRIPTION: Retrieve the value of the given field + * DESCRIPTION: Apply the field update rule to a field write * ******************************************************************************/ acpi_status -acpi_ex_extract_from_field ( - acpi_operand_object *obj_desc, - void *buffer, - u32 buffer_length) +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; - 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 = AE_OK; + acpi_integer merged_value; + acpi_integer current_value; - FUNCTION_TRACE ("Ex_extract_from_field"); + ACPI_FUNCTION_TRACE_U32 ("ex_write_with_update_rule", mask); - /* - * The field must fit within the caller's buffer - */ - byte_field_length = 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", - byte_field_length, buffer_length)); + /* Start with the new bits */ - return_ACPI_STATUS (AE_BUFFER_OVERFLOW); - } + merged_value = field_value; - /* Convert field byte count to datum count, round up if necessary */ + /* 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); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - datum_count = ROUND_UP_TO (byte_field_length, obj_desc->common_field.access_byte_width); + merged_value |= (current_value & ~mask); + } + break; - 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)); + case AML_FIELD_UPDATE_WRITE_AS_ONES: - /* - * 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); + /* Set positions outside the field to all ones */ - /* Read the first raw datum to prime the loop */ + merged_value |= ~mask; + break; - field_datum_byte_offset = 0; - datum_offset= 0; + case AML_FIELD_UPDATE_WRITE_AS_ZEROS: - status = acpi_ex_read_field_datum (obj_desc, field_datum_byte_offset, &previous_raw_datum); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + /* 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); + } } + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Mask %8.8X%8.8X, datum_offset %X, Width %X, Value %8.8X%8.8X, merged_value %8.8X%8.8X\n", + ACPI_FORMAT_UINT64 (mask), + field_datum_byte_offset, + obj_desc->common_field.access_byte_width, + ACPI_FORMAT_UINT64 (field_value), + ACPI_FORMAT_UINT64 (merged_value))); - /* We might actually be done if the request fits in one datum */ + /* Write the merged value */ - if ((datum_count == 1) && - (obj_desc->common_field.access_flags & AFIELD_SINGLE_DATUM)) { - /* 1) Shift the valid data bits down to start at bit 0 */ + status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset, + &merged_value, ACPI_WRITE); - merged_datum = (previous_raw_datum >> obj_desc->common_field.start_field_bit_offset); + return_ACPI_STATUS (status); +} - /* 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); - } +/******************************************************************************* + * + * FUNCTION: acpi_ex_get_buffer_datum + * + * 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) + * buffer_offset - Datum offset into the buffer + * + * RETURN: none + * + * DESCRIPTION: Get a datum from the buffer according to the buffer field + * byte granularity + * + ******************************************************************************/ - /* Store the datum to the caller buffer */ +void +acpi_ex_get_buffer_datum ( + acpi_integer *datum, + void *buffer, + u32 buffer_length, + u32 byte_granularity, + u32 buffer_offset) +{ + u32 index; - acpi_ex_set_buffer_datum (merged_datum, buffer, obj_desc->common_field.access_byte_width, - datum_offset); - return_ACPI_STATUS (AE_OK); - } + ACPI_FUNCTION_TRACE_U32 ("ex_get_buffer_datum", byte_granularity); - /* We need to get more raw data to complete one or more field data */ + /* Get proper index into buffer (handles big/little endian) */ - while (datum_offset < datum_count) { - field_datum_byte_offset += obj_desc->common_field.access_byte_width; + index = ACPI_BUFFER_INDEX (buffer_length, buffer_offset, byte_granularity); - /* - * If the field is aligned on a byte boundary, we don't want - * 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, - */ - 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); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - } + /* Move the requested number of bytes */ - /* - * Create the (possibly) merged datum to be stored to the caller buffer - */ - if (obj_desc->common_field.start_field_bit_offset == 0) { - /* Field is not skewed and we can just copy the datum */ + switch (byte_granularity) { + case ACPI_FIELD_BYTE_GRANULARITY: - merged_datum = previous_raw_datum; - } + *datum = ((u8 *) buffer) [index]; + break; - else { - /* - * Put together the appropriate bits of the two raw data to make a - * single complete field datum - * - * 1) Normalize the first datum down to bit 0 - */ - merged_datum = (previous_raw_datum >> obj_desc->common_field.start_field_bit_offset); + case ACPI_FIELD_WORD_GRANULARITY: - /* 2) Insert the second datum "above" the first datum */ + ACPI_MOVE_16_TO_64 (datum, &(((u16 *) buffer) [index])); + break; - merged_datum |= (this_raw_datum << obj_desc->common_field.datum_valid_bits); + case ACPI_FIELD_DWORD_GRANULARITY: - if ((datum_offset >= (datum_count -1))) { - /* - * This is the last iteration of the loop. We need to clear - * any unused bits (bits that are not part of this field) that - * came from the last raw datum before we store the final - * merged datum into the caller buffer. - */ - if (obj_desc->common_field.end_buffer_valid_bits) { - merged_datum &= - MASK_BITS_ABOVE (obj_desc->common_field.end_buffer_valid_bits); - } - } - } + ACPI_MOVE_32_TO_64 (datum, &(((u32 *) buffer) [index])); + break; - /* - * 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); + case ACPI_FIELD_QWORD_GRANULARITY: - /* - * Save the raw datum that was just acquired since it may contain bits - * of the *next* field datum. Update offsets - */ - previous_raw_datum = this_raw_datum; - datum_offset++; + ACPI_MOVE_64_TO_64 (datum, &(((u64 *) buffer) [index])); + break; + + default: + /* Should not get here */ + break; } - return_ACPI_STATUS (AE_OK); + return_VOID; } /******************************************************************************* * - * FUNCTION: Acpi_ex_write_field_datum + * FUNCTION: acpi_ex_set_buffer_datum * - * PARAMETERS: *Obj_desc - Field to be set - * Value - Value to store + * PARAMETERS: merged_datum - Value to store + * Buffer - Receiving buffer + * buffer_length - Entire length (used for big-endian only) + * byte_granularity - 1/2/4/8 Granularity of the field + * (aka Datum Size) + * buffer_offset - Datum offset into the buffer * - * RETURN: Status + * RETURN: none * - * DESCRIPTION: Store the value into the given field + * DESCRIPTION: Store the merged datum to the buffer according to the + * byte granularity * ******************************************************************************/ -static acpi_status -acpi_ex_write_field_datum ( - acpi_operand_object *obj_desc, - u32 field_datum_byte_offset, - u32 value) +void +acpi_ex_set_buffer_datum ( + acpi_integer merged_datum, + void *buffer, + u32 buffer_length, + u32 byte_granularity, + u32 buffer_offset) { - acpi_status status = AE_OK; - acpi_operand_object *rgn_desc = NULL; - ACPI_PHYSICAL_ADDRESS address; + u32 index; - FUNCTION_TRACE_U32 ("Ex_write_field_datum", field_datum_byte_offset); + ACPI_FUNCTION_TRACE_U32 ("ex_set_buffer_datum", byte_granularity); - /* - * 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; + /* Get proper index into buffer (handles big/little endian) */ + index = ACPI_BUFFER_INDEX (buffer_length, buffer_offset, byte_granularity); - case INTERNAL_TYPE_REGION_FIELD: - case INTERNAL_TYPE_BANK_FIELD: + /* Move the requested number of bytes */ - /* - * 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); - } + switch (byte_granularity) { + case ACPI_FIELD_BYTE_GRANULARITY: - /* - * 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; + ((u8 *) buffer) [index] = (u8) merged_datum; + break; - 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)); + case ACPI_FIELD_WORD_GRANULARITY: - /* Invoke the appropriate Address_space/Op_region handler */ + ACPI_MOVE_64_TO_16 (&(((u16 *) buffer)[index]), &merged_datum); + break; - status = acpi_ev_address_space_dispatch (rgn_desc, ACPI_WRITE_ADR_SPACE, - address, obj_desc->common_field.access_bit_width, &value); + case ACPI_FIELD_DWORD_GRANULARITY: - 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)); - } + ACPI_MOVE_64_TO_32 (&(((u32 *) buffer)[index]), &merged_datum); + break; - 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)); - } + case ACPI_FIELD_QWORD_GRANULARITY: + ACPI_MOVE_64_TO_64 (&(((u64 *) buffer)[index]), &merged_datum); 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; + /* Should not get here */ break; } - - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value written=%08X \n", value)); - return_ACPI_STATUS (status); + return_VOID; } /******************************************************************************* * - * FUNCTION: Acpi_ex_write_field_datum_with_update_rule + * FUNCTION: acpi_ex_extract_from_field * - * PARAMETERS: *Obj_desc - Field to be set - * Value - Value to store + * PARAMETERS: *obj_desc - Field to be read + * *Value - Where to store value * * RETURN: Status * - * DESCRIPTION: Apply the field update rule to a field write + * DESCRIPTION: Retrieve the value of the given field * ******************************************************************************/ -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 +acpi_ex_extract_from_field ( + union acpi_operand_object *obj_desc, + void *buffer, + u32 buffer_length) { - acpi_status status = AE_OK; - u32 merged_value; - u32 current_value; + acpi_status status; + u32 field_datum_byte_offset; + u32 buffer_datum_offset; + acpi_integer previous_raw_datum = 0; + acpi_integer this_raw_datum = 0; + acpi_integer merged_datum = 0; + u32 byte_field_length; + u32 datum_count; + u32 i; - FUNCTION_TRACE ("Ex_write_field_datum_with_update_rule"); + ACPI_FUNCTION_TRACE ("ex_extract_from_field"); - /* Start with the new bits */ + /* + * The field must fit within the caller's buffer + */ + 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_BFIELD, + "Field size %X (bytes) too large for buffer (%X)\n", + byte_field_length, buffer_length)); - merged_value = field_value; + return_ACPI_STATUS (AE_BUFFER_OVERFLOW); + } - /* If the mask is all ones, we don't need to worry about the update rule */ + /* Convert field byte count to datum count, round up if necessary */ - if (mask != ACPI_UINT32_MAX) { - /* Decode the update rule */ + datum_count = ACPI_ROUND_UP_TO (byte_field_length, + obj_desc->common_field.access_byte_width); - 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); + /* + * If the field is not aligned on a datum boundary and does not + * fit within a single datum, we must read an extra datum. + * + * 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.end_field_valid_bits != 0) && + (!(obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM))) { + datum_count++; + } + + 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 the buffer + * is longer than the size of the field. + */ + ACPI_MEMSET (buffer, 0, buffer_length); + + field_datum_byte_offset = 0; + buffer_datum_offset= 0; + + /* Read the entire field */ + + for (i = 0; i < datum_count; i++) { + 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); + } + + /* We might actually be done if the request fits in one datum */ + + if ((datum_count == 1) && + (obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM)) { + /* 1) Shift the valid data bits down to start at bit 0 */ + + merged_datum = (this_raw_datum >> obj_desc->common_field.start_field_bit_offset); + + /* 2) Mask off any upper unused bits (bits not part of the field) */ + + if (obj_desc->common_field.end_buffer_valid_bits) { + merged_datum &= ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_buffer_valid_bits); } - break; + /* Store the datum to the caller buffer */ - case UPDATE_WRITE_AS_ONES: + acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length, + obj_desc->common_field.access_byte_width, buffer_datum_offset); - /* Set positions outside the field to all ones */ + return_ACPI_STATUS (AE_OK); + } - merged_value |= ~mask; - break; + /* Special handling for the last datum to ignore extra bits */ + if ((i >= (datum_count -1)) && + (obj_desc->common_field.end_field_valid_bits)) { + /* + * This is the last iteration of the loop. We need to clear + * any unused bits (bits that are not part of this field) before + * we store the final merged datum into the caller buffer. + */ + this_raw_datum &= + ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits); + } - case UPDATE_WRITE_AS_ZEROS: + /* + * Create the (possibly) merged datum to be stored to the caller buffer + */ + if (obj_desc->common_field.start_field_bit_offset == 0) { + /* Field is not skewed and we can just copy the datum */ - /* Set positions outside the field to all zeros */ + acpi_ex_set_buffer_datum (this_raw_datum, buffer, buffer_length, + obj_desc->common_field.access_byte_width, buffer_datum_offset); + buffer_datum_offset++; + } + else { + /* Not aligned -- on the first iteration, just save the datum */ - merged_value &= mask; - break; + if (i != 0) { + /* + * Put together the appropriate bits of the two raw data to make a + * single complete field datum + * + * 1) Normalize the first datum down to bit 0 + */ + merged_datum = (previous_raw_datum >> obj_desc->common_field.start_field_bit_offset); + /* 2) Insert the second datum "above" the first datum */ - 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; + merged_datum |= (this_raw_datum << obj_desc->common_field.datum_valid_bits); + + acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length, + obj_desc->common_field.access_byte_width, buffer_datum_offset); + buffer_datum_offset++; + } + + /* + * Save the raw datum that was just acquired since it may contain bits + * of the *next* field datum + */ + previous_raw_datum = this_raw_datum; } - } + field_datum_byte_offset += obj_desc->common_field.access_byte_width; + } - /* Write the merged value */ + /* For non-aligned case, there is one last datum to insert */ - status = acpi_ex_write_field_datum (obj_desc, field_datum_byte_offset, - merged_value); + if (obj_desc->common_field.start_field_bit_offset != 0) { + merged_datum = (this_raw_datum >> obj_desc->common_field.start_field_bit_offset); - 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)); + acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length, + obj_desc->common_field.access_byte_width, buffer_datum_offset); + } - return_ACPI_STATUS (status); + return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ex_insert_into_field + * 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 +953,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 +977,28 @@ * 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); } + byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES ( + obj_desc->common_field.start_field_bit_offset + + obj_desc->common_field.bit_length); + /* 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, + "Bytes %X, Datums %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 +1011,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 +1020,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,16 +1042,20 @@ /* 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); } + /* We just wrote the first datum */ + + datum_offset++; + /* 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); } @@ -828,14 +1071,13 @@ * applied in Part3 below. */ while (datum_offset < datum_count) { - datum_offset++; field_datum_byte_offset += obj_desc->common_field.access_byte_width; /* * 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 +1091,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 */ @@ -861,37 +1102,37 @@ * a datum boundary. Update Rule must be applied to the bits outside * the field. */ - if (datum_offset == datum_count) { + datum_offset++; + if ((datum_offset == datum_count) && + (obj_desc->common_field.end_field_valid_bits)) { /* * If there are dangling non-aligned bits, perform one more merged write * Else - field is aligned at the end, no need for any more writes */ - if (obj_desc->common_field.end_field_valid_bits) { - /* - * Part3: - * This is the last datum and the field does not end on a datum boundary. - * Build the partial datum and write with the update rule. - * - * Mask off the unused bits above (after) the end-of-field - */ - mask = MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits); - merged_datum &= mask; - /* Write the last datum with the update rule */ + /* + * Part3: + * This is the last datum and the field does not end on a datum boundary. + * Build the partial datum and write with the update rule. + * + * Mask off the unused bits above (after) the end-of-field + */ + mask = ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits); + merged_datum &= mask; - status = acpi_ex_write_field_datum_with_update_rule (obj_desc, mask, - merged_datum, field_datum_byte_offset); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + /* Write the last datum with the update rule */ + + 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 */ + /* Normal (aligned) 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); } Index: drivers/acpi/executer/exmisc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exmisc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exmisc.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exmisc.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -2,122 +2,229 @@ /****************************************************************************** * * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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_REPORT_ERROR (("Unknown Reference subtype in get ref %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_REPORT_ERROR (("Invalid descriptor type in get ref: %X\n", + ACPI_GET_DESCRIPTOR_TYPE (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,62 @@ /* 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 */ + + ACPI_REPORT_ERROR (("Concat - invalid obj type: %X\n", + ACPI_GET_OBJECT_TYPE (obj_desc1))); status = AE_AML_INTERNAL; return_desc = NULL; } - *actual_return_desc = return_desc; return (AE_OK); @@ -284,11 +368,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 +384,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 +426,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 +449,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 +470,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 +516,9 @@ return (TRUE); } break; + + default: + break; } return (FALSE); Index: drivers/acpi/executer/exmutex.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exmutex.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exmutex.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exmutex.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -2,107 +2,136 @@ /****************************************************************************** * * Module Name: exmutex - ASL Mutex Acquire/Release functions - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,55 +141,74 @@ 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", + acpi_ut_get_node_name (obj_desc->mutex.node))); + 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", + acpi_ut_get_node_name (obj_desc->mutex.node))); 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) { - obj_desc->mutex.acquisition_depth++; - return_ACPI_STATUS (AE_OK); + if (obj_desc->mutex.owner_thread) { + /* Special case for Global Lock, allow all threads */ + + if ((obj_desc->mutex.owner_thread->thread_id == walk_state->thread->thread_id) || + (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore)) { + /* + * The mutex is already owned by this thread, + * just increment the acquisition depth + */ + obj_desc->mutex.acquisition_depth++; + return_ACPI_STATUS (AE_OK); + } } /* Acquire the mutex, wait if necessary */ 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; + + /* Link the mutex to the current thread for force-unlock at method exit */ - acpi_ex_link_mutex (obj_desc, (acpi_operand_object *) - &(walk_state->walk_list->acquired_mutex_list)); + acpi_ex_link_mutex (obj_desc, walk_state->thread); return_ACPI_STATUS (AE_OK); } @@ -168,9 +216,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 +228,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 +243,31 @@ /* 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", + acpi_ut_get_node_name (obj_desc->mutex.node))); return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED); } - /* The Mutex is owned, but this thread must be the owner */ + /* 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", + acpi_ut_get_node_name (obj_desc->mutex.node))); + return_ACPI_STATUS (AE_AML_INTERNAL); + } - if (obj_desc->mutex.owner != walk_state) { + /* + * The Mutex is owned, but this thread must be the owner. + * Special case for Global Lock, any thread can release + */ + if ((obj_desc->mutex.owner_thread->thread_id != walk_state->thread->thread_id) && + (obj_desc->mutex.semaphore != acpi_gbl_global_lock_semaphore)) { + ACPI_REPORT_ERROR (( + "Thread %X cannot release Mutex [%4.4s] acquired by thread %X\n", + walk_state->thread->thread_id, + acpi_ut_get_node_name (obj_desc->mutex.node), + obj_desc->mutex.owner_thread->thread_id)); return_ACPI_STATUS (AE_AML_NOT_OWNER); } @@ -209,7 +275,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", + acpi_ut_get_node_name (obj_desc->mutex.node))); return_ACPI_STATUS (AE_AML_MUTEX_ORDER); } @@ -223,6 +291,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 +301,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 +310,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 +320,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 +339,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; + } } Index: drivers/acpi/executer/exnames.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exnames.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exnames.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exnames.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -2,36 +2,53 @@ /****************************************************************************** * * Module Name: exnames - interpreter/scanner name load/execute - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); Index: drivers/acpi/executer/exoparg1.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exoparg1.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exoparg1.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exoparg1.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -2,39 +2,57 @@ /****************************************************************************** * * Module Name: exoparg1 - AML execution - opcodes with 1 argument - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,161 @@ 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_FORMAT_UINT64 (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 +409,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 +429,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 +485,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 +501,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 +513,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_1R", 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 +546,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 +568,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 +584,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 +605,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 +653,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 +662,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 +780,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 +803,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 +810,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 +827,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; Index: drivers/acpi/executer/exoparg2.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exoparg2.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exoparg2.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exoparg2.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -1,40 +1,56 @@ /****************************************************************************** * * Module Name: exoparg2 - AML execution - opcodes with 2 arguments - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,20 +315,22 @@ * 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: + ACPI_REPORT_ERROR (("Concat - invalid obj type: %X\n", + ACPI_GET_OBJECT_TYPE (operand[0]))); status = AE_AML_INTERNAL; } @@ -331,20 +343,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 +413,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 +424,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]; 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 +480,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 +488,9 @@ goto cleanup; } - walk_state->result_obj = return_desc; + if (!walk_state->result_obj) { + walk_state->result_obj = return_desc; + } } @@ -466,9 +508,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 +520,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 +542,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 +551,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 +561,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 +573,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) { Index: drivers/acpi/executer/exoparg3.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exoparg3.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exoparg3.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exoparg3.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -2,37 +2,55 @@ /****************************************************************************** * * Module Name: exoparg3 - AML execution - opcodes with 3 arguments - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,26 @@ 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", - (u32) operand[0]->integer.value, (u32) operand[1]->integer.value, + "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 +119,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 +129,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 +144,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 +156,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 +176,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 +184,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 +197,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 +243,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); } Index: drivers/acpi/executer/exoparg6.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exoparg6.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exoparg6.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exoparg6.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -2,37 +2,55 @@ /****************************************************************************** * * Module Name: exoparg6 - AML execution - opcodes with 6 arguments - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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; } Index: drivers/acpi/executer/exprep.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exprep.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exprep.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exprep.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -2,292 +2,448 @@ /****************************************************************************** * * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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") +#ifdef ACPI_UNDER_DEVELOPMENT /******************************************************************************* * - * FUNCTION: Acpi_ex_decode_field_access_type + * FUNCTION: acpi_ex_generate_access + * + * PARAMETERS: field_bit_offset - Start of field within parent region/buffer + * field_bit_length - Length of field in bits + * region_length - Length of parent in bytes + * + * RETURN: Field granularity (8, 16, 32 or 64) and + * byte_alignment (1, 2, 3, or 4) + * + * DESCRIPTION: Generate an optimal access width for fields defined with the + * any_acc keyword. + * + * NOTE: Need to have the region_length in order to check for boundary + * conditions (end-of-region). However, the region_length is a deferred + * operation. Therefore, to complete this implementation, the generation + * of this access width must be deferred until the region length has + * been evaluated. + * + ******************************************************************************/ + +static u32 +acpi_ex_generate_access ( + u32 field_bit_offset, + u32 field_bit_length, + u32 region_length) +{ + u32 field_byte_length; + u32 field_byte_offset; + u32 field_byte_end_offset; + u32 access_byte_width; + u32 field_start_offset; + u32 field_end_offset; + u32 minimum_access_width = 0xFFFFFFFF; + u32 minimum_accesses = 0xFFFFFFFF; + u32 accesses; + + + ACPI_FUNCTION_TRACE ("ex_generate_access"); + + + /* Round Field start offset and length to "minimal" byte boundaries */ + + field_byte_offset = ACPI_DIV_8 (ACPI_ROUND_DOWN (field_bit_offset, 8)); + field_byte_end_offset = ACPI_DIV_8 (ACPI_ROUND_UP (field_bit_length + field_bit_offset, 8)); + field_byte_length = field_byte_end_offset - field_byte_offset; + + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Bit length %d, Bit offset %d\n", + field_bit_length, field_bit_offset)); + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Byte Length %d, Byte Offset %d, End Offset %d\n", + field_byte_length, field_byte_offset, field_byte_end_offset)); + + /* + * Iterative search for the maximum access width that is both aligned + * and does not go beyond the end of the region + * + * Start at byte_acc and work upwards to qword_acc max. (1,2,4,8 bytes) + */ + for (access_byte_width = 1; access_byte_width <= 8; access_byte_width <<= 1) { + /* + * 1) Round end offset up to next access boundary and make sure that this + * does not go beyond the end of the parent region. + * 2) When the Access width is greater than the field_byte_length, we are done. + * (This does not optimize for the perfectly aligned case yet). + */ + if (ACPI_ROUND_UP (field_byte_end_offset, access_byte_width) <= region_length) { + field_start_offset = ACPI_ROUND_DOWN (field_byte_offset, access_byte_width) / + access_byte_width; + field_end_offset = ACPI_ROUND_UP ((field_byte_length + field_byte_offset), + access_byte_width) / access_byte_width; + accesses = field_end_offset - field_start_offset; + + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "access_width %d end is within region\n", access_byte_width)); + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Field Start %d, Field End %d -- requires %d accesses\n", + field_start_offset, field_end_offset, accesses)); + + /* Single access is optimal */ + + if (accesses <= 1) { + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Entire field can be accessed with one operation of size %d\n", + access_byte_width)); + return_VALUE (access_byte_width); + } + + /* + * Fits in the region, but requires more than one read/write. + * try the next wider access on next iteration + */ + if (accesses < minimum_accesses) { + minimum_accesses = accesses; + minimum_access_width = access_byte_width; + } + } + else { + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "access_width %d end is NOT within region\n", access_byte_width)); + if (access_byte_width == 1) { + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Field goes beyond end-of-region!\n")); + return_VALUE (0); /* Field does not fit in the region at all */ + } + + /* This width goes beyond the end-of-region, back off to previous access */ + + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Backing off to previous optimal access width of %d\n", + minimum_access_width)); + return_VALUE (minimum_access_width); + } + } + + /* Could not read/write field with one operation, just use max access width */ + + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Cannot access field in one operation, using width 8\n")); + return_VALUE (8); +} +#endif /* ACPI_UNDER_DEVELOPMENT */ + + +/******************************************************************************* + * + * 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; + u32 byte_alignment; + u32 bit_length; - switch (access) { - case ACCESS_ANY_ACC: + ACPI_FUNCTION_TRACE ("ex_decode_field_access"); - *alignment = 8; - /* Use the length to set the access type */ + access = (field_flags & AML_FIELD_ACCESS_TYPE_MASK); - if (length <= 8) { - return (8); - } - else if (length <= 16) { - return (16); - } - else if (length <= 32) { - return (32); - } - else if (length <= 64) { - return (64); - } + switch (access) { + case AML_FIELD_ACCESS_ANY: - /* Default is 8 (byte) */ +#ifdef ACPI_UNDER_DEVELOPMENT + byte_alignment = acpi_ex_generate_access (obj_desc->common_field.start_field_bit_offset, + obj_desc->common_field.bit_length, + 0xFFFFFFFF /* Temp until we pass region_length as param */); + bit_length = byte_alignment * 8; +#endif - return (8); + byte_alignment = 1; + bit_length = 8; 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); + return_VALUE (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_VALUE (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 = (u32) + 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 +452,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,47 +463,51 @@ /* 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: bit_off %X, Off %X, Gran %X, Region %p\n", obj_desc->field.start_field_bit_offset, obj_desc->field.base_byte_offset, - obj_desc->field.access_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")); + ACPI_REPORT_ERROR (("Null Index Object during field prep\n")); return_ACPI_STATUS (AE_AML_INTERNAL); } @@ -355,22 +516,30 @@ 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: bit_off %X, Off %X, Value %X, Gran %X, Index %p, Data %p\n", + obj_desc->index_field.start_field_bit_offset, + obj_desc->index_field.base_byte_offset, + obj_desc->index_field.value, + 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], obj_desc %p\n", + info->field_node, acpi_ut_get_node_name (info->field_node), obj_desc)); /* Remove local reference to the object */ Index: drivers/acpi/executer/exregion.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exregion.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exregion.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exregion.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -1,52 +1,66 @@ /****************************************************************************** * - * Module Name: exregion - ACPI default Op_region (address space) handlers - * $Revision: 1.1 $ + * Module Name: exregion - ACPI default op_region (address space) handlers * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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_FORMAT_UINT64 (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_FORMAT_UINT64 (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_FORMAT_UINT64 (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); +} + + Index: drivers/acpi/executer/exresnte.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exresnte.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exresnte.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exresnte.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -2,51 +2,67 @@ /****************************************************************************** * * Module Name: exresnte - AML Interpreter object resolution - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 +#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 +83,40 @@ 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) || + (entry_type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) { + /* There is always exactly one level of indirection */ + + node = ACPI_CAST_PTR (struct acpi_namespace_node, node->object); + 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 +139,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 +192,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 +206,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 +234,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,62 +242,28 @@ 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: + case ACPI_TYPE_LOCAL_REFERENCE: switch (source_desc->reference.opcode) { + case AML_LOAD_OP: - case AML_ZERO_OP: - - temp_val = 0; - break; - - case AML_ONE_OP: - - temp_val = 1; - break; - - case AML_ONES_OP: - - temp_val = ACPI_INTEGER_MAX; - break; - - case AML_REVISION_OP: + /* This is a ddb_handle */ + /* Return an additional reference to the object */ - temp_val = ACPI_CA_SUPPORT_LEVEL; + obj_desc = source_desc; + acpi_ut_add_reference (obj_desc); break; default: + /* No named references are allowed here */ - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported reference opcode %X\n", - source_desc->reference.opcode)); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported Reference opcode %X (%s)\n", + source_desc->reference.opcode, + acpi_ps_get_opcode_name (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); + return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } break; @@ -283,7 +277,7 @@ return_ACPI_STATUS (AE_AML_OPERAND_TYPE); - } /* switch (Entry_type) */ + } /* switch (entry_type) */ /* Put the object descriptor on the stack */ Index: drivers/acpi/executer/exresolv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exresolv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exresolv.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exresolv.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -2,156 +2,67 @@ /****************************************************************************** * * Module Name: exresolv - AML Interpreter object resolution - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 +#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 +72,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 +86,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 +99,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 +133,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 +194,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 +209,7 @@ case ACPI_TYPE_PACKAGE: + obj_desc = *stack_desc->reference.where; if (obj_desc) { /* @@ -359,7 +221,6 @@ acpi_ut_add_reference (obj_desc); *stack_ptr = obj_desc; } - else { /* * A NULL object descriptor means an unitialized element of @@ -372,83 +233,248 @@ } break; + default: + /* Invalid reference object */ - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Unknown Target_type %X in Index/Reference obj %p\n", + ACPI_REPORT_ERROR (( + "During resolve, 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: + case AML_LOAD_OP: /* Just leave the object as-is */ + break; default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Reference object subtype %02X in %p\n", - opcode, stack_desc)); + ACPI_REPORT_ERROR (("During resolve, Unknown Reference opcode %X (%s) in %p\n", + opcode, acpi_ps_get_opcode_name (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) { + ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n", + node, acpi_ut_get_descriptor_name (node))); + return_ACPI_STATUS (AE_AML_INTERNAL); + } + + /* Get the attached object */ + + obj_desc = acpi_ns_get_attached_object (node); + if (!obj_desc) { + /* No object, use the NS node type */ + + type = acpi_ns_get_type (node); + goto exit; + } + + /* Check for circular references */ + + if (obj_desc == operand) { + return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE); + } + break; + + + case AML_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) { + ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n", + node, acpi_ut_get_descriptor_name (node))); + return_ACPI_STATUS (AE_AML_INTERNAL); + } + + /* Get the attached object */ + + obj_desc = acpi_ns_get_attached_object (node); + if (!obj_desc) { + /* No object, use the NS node type */ + + type = acpi_ns_get_type (node); + goto exit; + } + + /* Check for circular references */ + + if (obj_desc == operand) { + return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE); + } + break; + + + case AML_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); } Index: drivers/acpi/executer/exresop.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exresop.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exresop.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exresop.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -2,49 +2,63 @@ /****************************************************************************** * * Module Name: exresop - AML Interpreter operand/object resolution - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,21 +152,19 @@ 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", + ACPI_REPORT_ERROR (("resolve_operands: %X is not a valid AML opcode\n", opcode)); 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 @@ -146,7 +172,7 @@ */ while (GET_CURRENT_ARG_TYPE (arg_types)) { if (!stack_ptr || !*stack_ptr) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null stack entry at %p\n", + ACPI_REPORT_ERROR (("resolve_operands: Null stack entry at %p\n", stack_ptr)); return_ACPI_STATUS (AE_AML_INTERNAL); @@ -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,38 @@ 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: + case AML_LOAD_OP: /* ddb_handle from LOAD_OP or LOAD_TABLE_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", - obj_desc->reference.opcode)); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Unknown Reference Opcode %X [%s]\n", + obj_desc->reference.opcode, + (acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name)); 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)); + "Invalid descriptor %p [%s]\n", + obj_desc, acpi_ut_get_descriptor_name (obj_desc))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } @@ -231,34 +260,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 */ + + 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_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 +308,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 +340,9 @@ return_ACPI_STATUS (status); } + /* Get the resolved object */ + + obj_desc = *stack_ptr; /* * Check the resulting object (value) type @@ -321,20 +366,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 */ @@ -349,6 +380,13 @@ type_needed = ACPI_TYPE_ANY; break; + case ARGI_DDBHANDLE: + + /* Need an operand of type ACPI_TYPE_DDB_HANDLE */ + + type_needed = ACPI_TYPE_LOCAL_REFERENCE; + break; + /* * The more complex cases allow multiple resolved object types @@ -358,22 +396,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 +418,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 +440,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 */ - /* Need a buffer, string, package or Node reference */ + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { + case ACPI_TYPE_STRING: + case ACPI_TYPE_BUFFER: - 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)); + /* Valid operand */ + break; + + 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 +587,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 +614,6 @@ } /* while (*Types) */ - return_ACPI_STATUS (status); } Index: drivers/acpi/executer/exstore.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exstore.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exstore.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exstore.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -2,113 +2,142 @@ /****************************************************************************** * * Module Name: exstore - AML Interpreter object store support - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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: - /* Destination object must be an object of type Reference */ + /* Allow stores to Constants -- a Noop as per ACPI spec */ - if (dest_desc->common.type != INTERNAL_TYPE_REFERENCE) { - /* Destination is not an Reference */ + if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) { + return_ACPI_STATUS (AE_OK); + } + + /*lint -fallthrough */ + + default: + + /* Destination is not a Reference object */ 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,75 +181,62 @@ * 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, "0x%8.8X%8.8X\n", + ACPI_FORMAT_UINT64 (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 0x%.2X", + (u32) source_desc->buffer.length)); + ACPI_DUMP_BUFFER (source_desc->buffer.pointer, + (source_desc->buffer.length < 32) ? source_desc->buffer.length : 32); break; case ACPI_TYPE_STRING: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s\n", source_desc->string.pointer)); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Length 0x%.2X, \"%s\"\n", + source_desc->string.length, source_desc->string.pointer)); break; 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, "Size 0x%.2X Elements Ptr - %p\n", + source_desc->package.count, 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, "%p\n", + 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_REPORT_ERROR (("ex_store: 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 +244,39 @@ /******************************************************************************* * - * 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; + u32 i; - 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 +284,41 @@ * 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. + * The parent package object is at index_desc->Reference.Object + */ + obj_desc = *(index_desc->reference.where); - 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); - } - } + /* Do the conversion/store */ - /* Install the new descriptor into the package */ + 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); + } + + /* + * 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 (new_desc == source_desc) { + acpi_ut_add_reference (new_desc); } - 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); - } + /* Increment reference count by the ref count of the parent package -1 */ + + for (i = 1; i < ((union acpi_operand_object *) index_desc->reference.object)->common.reference_count; i++) { + acpi_ut_add_reference (new_desc); } } break; @@ -343,21 +326,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 +347,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 +413,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 +451,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 +477,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); -} - Index: drivers/acpi/executer/exstoren.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exstoren.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exstoren.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exstoren.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -3,130 +3,147 @@ * * Module Name: exstoren - AML Interpreter object store support, * Store to Node (namespace object) - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 #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 */ + + status = acpi_ex_resolve_to_value (source_desc_ptr, walk_state); + if (ACPI_FAILURE (status)) { + break; + } + } + + /* For copy_object, no further validation necessary */ - /* TBD: FIX - check for source==REF, resolve, then check type */ + if (walk_state->opcode == AML_COPY_OP) { + 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) && + !((ACPI_GET_OBJECT_TYPE (source_desc) == ACPI_TYPE_LOCAL_REFERENCE) && (source_desc->reference.opcode == AML_LOAD_OP))) { /* - * 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: + case ACPI_TYPE_LOCAL_METHOD_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")); + ACPI_REPORT_ERROR (("Store into Alias - should never happen\n")); status = AE_AML_INTERNAL; break; @@ -147,12 +164,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 +178,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); } Index: drivers/acpi/executer/exstorob.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exstorob.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exstorob.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exstorob.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -2,48 +2,61 @@ /****************************************************************************** * * Module Name: exstorob - AML Interpreter object store support, store to object - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); } Index: drivers/acpi/executer/exsystem.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exsystem.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exsystem.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exsystem.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -2,42 +2,58 @@ /****************************************************************************** * * Module Name: exsystem - Interface to OS services - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,46 +109,55 @@ /******************************************************************************* * - * 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, + * in microseconds * - * RETURN: None + * RETURN: Status * * DESCRIPTION: Suspend running thread for specified amount of time. + * Note: ACPI specification requires that Stall() does not + * relinquish the processor, and delays longer than 100 usec + * should use Sleep() instead. We allow stalls up to 255 usec + * for compatibility with other interpreters and existing BIOSs. * ******************************************************************************/ -void +acpi_status acpi_ex_system_do_stall ( - u32 how_long) + u32 how_long) { - FUNCTION_ENTRY (); - + acpi_status status = AE_OK; - if (how_long > 1000) /* 1 millisecond */ { - /* Since this thread will sleep, we must release the interpreter */ - acpi_ex_exit_interpreter (); - - acpi_os_stall (how_long); + ACPI_FUNCTION_ENTRY (); - /* And now we must get the interpreter again */ - acpi_ex_enter_interpreter (); + if (how_long > 255) /* 255 microseconds */ { + /* + * Longer than 255 usec, this is an error + * + * (ACPI specifies 100 usec as max, but this gives some slack in + * order to support existing BIOSs) + */ + ACPI_REPORT_ERROR (("Stall: Time parameter is too large (%d)\n", how_long)); + status = AE_AML_OPERAND_VALUE; } - 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, + * in milliseconds * * RETURN: None * @@ -139,12 +165,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 +184,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 +223,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 +250,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 +266,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 +277,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 +290,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 +308,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 +323,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 +355,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 +370,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; } Index: drivers/acpi/executer/exutils.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/executer/exutils.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/executer/exutils.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/executer/exutils.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -2,26 +2,44 @@ /****************************************************************************** * * Module Name: exutils - interpreter/scanner utilities - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 Index: drivers/acpi/hardware/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/hardware/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/hardware/Makefile 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/hardware/Makefile 4 Aug 2004 01:28:34 -0000 1.2 @@ -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) Index: drivers/acpi/hardware/hwacpi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/hardware/hwacpi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/hardware/hwacpi.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/hardware/hwacpi.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -2,40 +2,57 @@ /****************************************************************************** * * Module Name: hwacpi - ACPI Hardware Initialization/Mode Interface - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,191 +66,128 @@ 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; - FUNCTION_TRACE ("Hw_set_mode"); + ACPI_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_REPORT_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_REPORT_ERROR (("No ACPI mode transition supported in this system (enable/disable both zero)\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; - /* Give the platform some time to react */ + default: + return_ACPI_STATUS (AE_BAD_PARAMETER); + } - acpi_os_stall (20000); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("Could not write mode change, %s\n", acpi_format_exception (status))); + return_ACPI_STATUS (status); + } - if (acpi_hw_get_mode () == mode) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Mode %X successfully enabled\n", mode)); - status = AE_OK; + /* + * 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) { + if (acpi_hw_get_mode() == mode) { + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Mode %X successfully enabled\n", mode)); + return_ACPI_STATUS (AE_OK); + } + acpi_os_stall(1000); + retry--; } - return_ACPI_STATUS (status); + ACPI_REPORT_ERROR (("Hardware never changed modes\n")); + return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); } /****************************************************************************** * - * FUNCTION: Acpi_hw_get_mode + * FUNCTION: acpi_hw_get_mode * * PARAMETERS: none * @@ -247,74 +201,34 @@ u32 acpi_hw_get_mode (void) { + acpi_status status; + u32 value; - 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); - } -} - - -/****************************************************************************** - * - * 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"); + ACPI_FUNCTION_TRACE ("hw_get_mode"); - 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); - } + /* 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); - 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 2.0 clarified that if SMI_CMD in FADT is zero, + * system does not support mode transition. + */ + if (!acpi_gbl_FADT->smi_cmd) { + return_VALUE (ACPI_SYS_MODE_ACPI); + } - 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); + } } - - Index: drivers/acpi/hardware/hwgpe.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/hardware/hwgpe.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/hardware/hwgpe.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/hardware/hwgpe.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -2,86 +2,100 @@ /****************************************************************************** * * Module Name: hwgpe - Low level GPE enable/disable/clear functions - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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_event_info - Info block for the GPE to be enabled * - * RETURN: None + * RETURN: Status * * DESCRIPTION: Enable a single GPE. * ******************************************************************************/ -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; - + u32 in_byte; + 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)]; /* * 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_event_info - Info block for the GPE to be enabled * * RETURN: None * @@ -92,82 +106,91 @@ 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 + * Set the bit so we will not enable this GPE when sleeping (and disable + * it upon wake) */ - acpi_gbl_gpe_registers[register_index].wake_enable |= bit_mask; + gpe_register_info->wake_enable |= gpe_event_info->bit_mask; + gpe_event_info->flags |= (ACPI_GPE_TYPE_WAKE | ACPI_GPE_ENABLED); } + /****************************************************************************** * - * FUNCTION: Acpi_hw_disable_gpe + * FUNCTION: acpi_hw_disable_gpe * - * PARAMETERS: Gpe_number - The GPE + * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled * - * RETURN: None + * RETURN: Status * * DESCRIPTION: Disable a single GPE. * ******************************************************************************/ -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); + } - acpi_hw_disable_gpe_for_wakeup(gpe_number); + /* 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); + } + + /* Make sure this GPE is disabled for wake, also */ + + 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_event_info - Info block for the GPE to be disabled * * RETURN: None * @@ -178,205 +201,398 @@ 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; + /* Clear the bit so we will disable this when sleeping */ + + 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_event_info - Info block for the GPE to be cleared * - * RETURN: None + * RETURN: status_status * - * DESCRIPTION: Clear a single GPE. + * DESCRIPTION: Clear the status bit for a single GPE. * ******************************************************************************/ -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_event_info - Info block for the GPE to queried + * event_status - Where the GPE status is returned * - * RETURN: None + * RETURN: Status * * DESCRIPTION: Return the status of a single GPE. * ******************************************************************************/ -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; + acpi_status status; + + + /* Examine each GPE Register within the block */ - FUNCTION_ENTRY (); + for (i = 0; i < gpe_block->register_count; i++) { + /* Disable all GPEs in this register */ + + status = acpi_hw_low_level_write (8, 0x00, + &gpe_block->register_info[i].enable_address); + if (ACPI_FAILURE (status)) { + return (status); + } + } - for (i = 0; i < acpi_gbl_gpe_register_count; i++) { + 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 status bits for 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; + acpi_status status; + + + /* Examine each GPE Register within the block */ + + for (i = 0; i < gpe_block->register_count; i++) { + /* Clear status on all GPEs in this register */ + + status = acpi_hw_low_level_write (8, 0xFF, + &gpe_block->register_info[i].status_address); + if (ACPI_FAILURE (status)) { + return (status); + } + } + + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: acpi_hw_prepare_gpe_block_for_sleep + * + * PARAMETERS: gpe_xrupt_info - GPE Interrupt info + * gpe_block - Gpe Block info + * + * RETURN: Status + * + * DESCRIPTION: Disable all runtime GPEs and enable all wakeup GPEs -- within + * a single GPE block + * + ******************************************************************************/ + +static acpi_status +acpi_hw_prepare_gpe_block_for_sleep ( + 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 + * Read the enabled/disabled status of all GPEs. We * will be using it to restore all the GPEs later. + * + * NOTE: Wake GPEs are are ALL disabled at this time, so when we wake + * and restore this register, they will be automatically disabled. */ - 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. + * 1) Disable all runtime GPEs + * 2) Enable all 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); + } + + /* Point to next GPE register */ + + gpe_register_info++; } + + return (AE_OK); } + /****************************************************************************** * - * FUNCTION: Acpi_hw_enable_non_wakeup_gpes + * FUNCTION: acpi_hw_prepare_gpes_for_sleep * * PARAMETERS: None * - * RETURN: None + * RETURN: Status * - * DESCRIPTION: Enable all non-wakeup GPEs we previously enabled. + * DESCRIPTION: Disable all runtime GPEs, enable all wake 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 the runtime GPEs are + * re-enabled. * ******************************************************************************/ -void -acpi_hw_enable_non_wakeup_gpes ( +acpi_status +acpi_hw_prepare_gpes_for_sleep ( void) { - u32 i; + acpi_status status; - FUNCTION_ENTRY (); - for (i = 0; i < acpi_gbl_gpe_register_count; i++) { + ACPI_FUNCTION_ENTRY (); + + + status = acpi_ev_walk_gpe_list (acpi_hw_prepare_gpe_block_for_sleep); + return (status); +} + + +/****************************************************************************** + * + * FUNCTION: acpi_hw_restore_gpe_block_on_wake + * + * PARAMETERS: gpe_xrupt_info - GPE Interrupt info + * gpe_block - Gpe Block info + * + * RETURN: Status + * + * DESCRIPTION: Enable all runtime GPEs and disable all wake GPEs -- in one + * GPE block + * + ******************************************************************************/ + +static acpi_status +acpi_hw_restore_gpe_block_on_wake ( + 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 */ + + /* 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++) { + /* Clear the entire status register */ + + status = acpi_hw_low_level_write (8, 0xFF, + &gpe_block->register_info[i].status_address); + if (ACPI_FAILURE (status)) { + return (status); + } + /* - * We previously stored the enabled status of all GPEs. - * Blast them back in. + * Restore the GPE Enable register, which will do the following: + * + * 1) Disable all wakeup GPEs + * 2) Enable all runtime GPEs + * + * (On sleep, we saved the enabled status of all GPEs) */ - 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); + } + + /* Point to next GPE register */ + + gpe_register_info++; } + + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: acpi_hw_restore_gpes_on_wake + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Enable all runtime GPEs and disable all wake GPEs -- in all + * GPE blocks + * + ******************************************************************************/ + +acpi_status +acpi_hw_restore_gpes_on_wake ( + void) +{ + acpi_status status; + + + ACPI_FUNCTION_ENTRY (); + + + status = acpi_ev_walk_gpe_list (acpi_hw_restore_gpe_block_on_wake); + return (status); } Index: drivers/acpi/hardware/hwregs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/hardware/hwregs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/hardware/hwregs.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/hardware/hwregs.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -3,71 +3,60 @@ * * Module Name: hwregs - Read/write access functions for the various ACPI * control and status registers. - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,401 @@ * ******************************************************************************/ -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_sleep_state_names[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_sleep_state_names[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_sleep_state_names[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_FORMAT_UINT64 (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_FORMAT_UINT64 (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 +467,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 +578,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 +744,85 @@ 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_FORMAT_UINT64 (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 +830,25 @@ 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_FORMAT_UINT64 (reg->address), + acpi_ut_get_region_name (reg->address_space_id))); + + return (status); } Index: drivers/acpi/hardware/hwsleep.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/hardware/hwsleep.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/hardware/hwsleep.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/hardware/hwsleep.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -2,70 +2,95 @@ /****************************************************************************** * * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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") + + +#define METHOD_NAME__BFS "\\_BFS" +#define METHOD_NAME__GTS "\\_GTS" +#define METHOD_NAME__PTS "\\_PTS" +#define METHOD_NAME__SST "\\_SI._SST" +#define METHOD_NAME__WAK "\\_WAK" + +#define ACPI_SST_INDICATOR_OFF 0 +#define ACPI_SST_WORKING 1 +#define ACPI_SST_WAKING 2 +#define ACPI_SST_SLEEPING 3 +#define ACPI_SST_SLEEP_CONTEXT 4 /****************************************************************************** * - * 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"); - + ACPI_FUNCTION_TRACE ("acpi_set_firmware_waking_vector"); - /* Make sure that we have an FACS */ - - 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 +99,356 @@ /****************************************************************************** * - * 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, METHOD_NAME__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, METHOD_NAME__GTS, &arg_list, NULL); + if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { + return_ACPI_STATUS (status); + } - disable (); + /* Setup the argument to _SST */ - acpi_hw_disable_non_wakeup_gpes(); + switch (sleep_state) { + case ACPI_STATE_S0: + arg.integer.value = ACPI_SST_WORKING; + break; + + case ACPI_STATE_S1: + case ACPI_STATE_S2: + case ACPI_STATE_S3: + arg.integer.value = ACPI_SST_SLEEPING; + break; + + case ACPI_STATE_S4: + arg.integer.value = ACPI_SST_SLEEP_CONTEXT; + break; + + default: + arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is indicator off */ + break; + } - PM1Acontrol = (u16) acpi_hw_register_read (ACPI_MTX_LOCK, PM1_CONTROL); + /* Set the system indicators to show the desired sleep state. */ - ACPI_DEBUG_PRINT ((ACPI_DB_OK, "Entering S%d\n", sleep_state)); + status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL); + if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { + ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status))); + } - /* mask off SLP_EN and SLP_TYP fields */ + return_ACPI_STATUS (AE_OK); +} - PM1Acontrol &= ~(SLP_TYPE_X_MASK | SLP_EN_MASK); - PM1Bcontrol = PM1Acontrol; - /* mask in SLP_TYP */ +/****************************************************************************** + * + * 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_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); - PM1Acontrol |= (type_a << acpi_hw_get_bit_shift (SLP_TYPE_X_MASK)); - PM1Bcontrol |= (type_b << acpi_hw_get_bit_shift (SLP_TYPE_X_MASK)); + if (sleep_state != ACPI_STATE_S5) { + /* Clear wake status */ - /* write #1: fill in SLP_TYP data */ + 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); + } + } - acpi_hw_register_write (ACPI_MTX_LOCK, PM1A_CONTROL, PM1Acontrol); - acpi_hw_register_write (ACPI_MTX_LOCK, PM1B_CONTROL, PM1Bcontrol); + /* + * 1) Disable all runtime GPEs + * 2) Enable all wakeup GPEs + */ + status = acpi_hw_prepare_gpes_for_sleep (); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - /* mask in SLP_EN */ + /* Get current value of PM1A control */ - PM1Acontrol |= (1 << acpi_hw_get_bit_shift (SLP_EN_MASK)); - PM1Bcontrol |= (1 << acpi_hw_get_bit_shift (SLP_EN_MASK)); + 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)); - /* flush caches */ + /* Clear SLP_EN and SLP_TYP fields */ - wbinvd(); + PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | sleep_enable_reg_info->access_bit_mask); + PM1Bcontrol = PM1Acontrol; - /* write #2: SLP_TYP + SLP_EN */ + /* Insert SLP_TYP bits */ - acpi_hw_register_write (ACPI_MTX_LOCK, PM1A_CONTROL, PM1Acontrol); - acpi_hw_register_write (ACPI_MTX_LOCK, PM1B_CONTROL, PM1Bcontrol); + PM1Acontrol |= (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position); + PM1Bcontrol |= (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position); /* - * Wait a second, then try again. This is to get S4/5 to work on all machines. + * We split the writes of SLP_TYP and SLP_EN to workaround + * poorly implemented hardware. */ - 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))); + /* Write #1: fill in SLP_TYP data */ + + 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); + } + + /* Insert SLP_ENABLE bit */ + + PM1Acontrol |= sleep_enable_reg_info->access_bit_mask; + PM1Bcontrol |= sleep_enable_reg_info->access_bit_mask; + + /* Write #2: SLP_TYP + SLP_EN */ + + ACPI_FLUSH_CPU_CACHE (); + + 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); + } + + if (sleep_state > ACPI_STATE_S3) { + /* + * We wanted to sleep > S3, but it didn't happen (by virtue of the fact that + * we are still executing!) + * + * Wait ten seconds, then try again. This is to get S4/S5 to work on all machines. + * + * We wait so long to allow chipsets that poll this reg very slowly to + * still read the right value. Ideally, this 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); + status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_DO_NOT_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Spin until we wake */ + + } while (!in_value); + + return_ACPI_STATUS (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: acpi_enter_sleep_state_s4bios + * + * 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"); + + + 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); + } + + /* + * 1) Disable all runtime GPEs + * 2) Enable all wakeup GPEs + */ + status = acpi_hw_prepare_gpes_for_sleep (); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } - while (!acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_LOCK, WAK_STS)); - acpi_hw_enable_non_wakeup_gpes(); + ACPI_FLUSH_CPU_CACHE (); - enable (); + 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 + * FUNCTION: acpi_leave_sleep_state * - * PARAMETERS: Sleep_state - Which sleep state we just exited + * PARAMETERS: sleep_state - Which sleep state we just exited * * RETURN: Status * @@ -244,29 +458,115 @@ 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; + struct acpi_bit_register_info *sleep_type_reg_info; + struct acpi_bit_register_info *sleep_enable_reg_info; + u32 PM1Acontrol; + u32 PM1Bcontrol; + + + ACPI_FUNCTION_TRACE ("acpi_leave_sleep_state"); - FUNCTION_TRACE ("Acpi_leave_sleep_state"); + /* + * Set SLP_TYPE and SLP_EN to state S0. + * This is unclear from the ACPI Spec, but it is required + * by some machines. + */ + status = acpi_get_sleep_type_data (ACPI_STATE_S0, + &acpi_gbl_sleep_type_a, &acpi_gbl_sleep_type_b); + if (ACPI_SUCCESS (status)) { + 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); + + /* Get current value of PM1A control */ + + status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); + if (ACPI_SUCCESS (status)) { + /* Clear SLP_EN and SLP_TYP fields */ + + PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | + sleep_enable_reg_info->access_bit_mask); + PM1Bcontrol = PM1Acontrol; + + /* Insert SLP_TYP bits */ + + PM1Acontrol |= (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position); + PM1Bcontrol |= (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position); + + /* Just ignore any errors */ + + (void) acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol); + (void) acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol); + } + } + + /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ + acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; + + /* 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; + + /* Ignore any errors from these methods */ + + arg.integer.value = ACPI_SST_WAKING; + status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL); + if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { + ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status))); + } + arg.integer.value = sleep_state; + status = acpi_evaluate_object (NULL, METHOD_NAME__BFS, &arg_list, NULL); + if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { + ACPI_REPORT_ERROR (("Method _BFS failed, %s\n", acpi_format_exception (status))); + } - acpi_evaluate_object (NULL, "\\_BFS", &arg_list, NULL); - acpi_evaluate_object (NULL, "\\_WAK", &arg_list, NULL); + status = acpi_evaluate_object (NULL, METHOD_NAME__WAK, &arg_list, NULL); + if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { + ACPI_REPORT_ERROR (("Method _WAK failed, %s\n", acpi_format_exception (status))); + } + /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */ - /* _WAK returns stuff - do we want to look at it? */ + /* + * Restore the GPEs: + * 1) Disable all wakeup GPEs + * 2) Enable all runtime GPEs + */ + status = acpi_hw_restore_gpes_on_wake (); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - acpi_hw_enable_non_wakeup_gpes(); + /* Enable power button */ - return_ACPI_STATUS (AE_OK); + acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].enable_register_id, + 1, ACPI_MTX_DO_NOT_LOCK); + acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].status_register_id, + 1, ACPI_MTX_DO_NOT_LOCK); + + /* Enable BM arbitration */ + + status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + arg.integer.value = ACPI_SST_WORKING; + status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL); + if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { + ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status))); + } + + return_ACPI_STATUS (status); } Index: drivers/acpi/hardware/hwtimer.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/hardware/hwtimer.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/hardware/hwtimer.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/hardware/hwtimer.c 4 Aug 2004 01:28:34 -0000 1.2 @@ -2,38 +2,55 @@ /****************************************************************************** * * Name: hwtimer.c - ACPI Power Management Timer Interface - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); } Index: drivers/acpi/include/acconfig.h =================================================================== RCS file: drivers/acpi/include/acconfig.h diff -N drivers/acpi/include/acconfig.h --- drivers/acpi/include/acconfig.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,162 +0,0 @@ -/****************************************************************************** - * - * Name: acconfig.h - Global configuration constants - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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 */ - Index: drivers/acpi/include/acdebug.h =================================================================== RCS file: drivers/acpi/include/acdebug.h diff -N drivers/acpi/include/acdebug.h --- drivers/acpi/include/acdebug.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,410 +0,0 @@ -/****************************************************************************** - * - * Name: acdebug.h - ACPI/AML debugger - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/include/acdispat.h =================================================================== RCS file: drivers/acpi/include/acdispat.h diff -N drivers/acpi/include/acdispat.h --- drivers/acpi/include/acdispat.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,453 +0,0 @@ -/****************************************************************************** - * - * Name: acdispat.h - dispatcher (parser to interpreter interface) - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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_ */ Index: drivers/acpi/include/acevents.h =================================================================== RCS file: drivers/acpi/include/acevents.h diff -N drivers/acpi/include/acevents.h --- drivers/acpi/include/acevents.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,217 +0,0 @@ -/****************************************************************************** - * - * Name: acevents.h - Event subcomponent prototypes and defines - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/include/acexcep.h =================================================================== RCS file: drivers/acpi/include/acexcep.h diff -N drivers/acpi/include/acexcep.h --- drivers/acpi/include/acexcep.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,248 +0,0 @@ -/****************************************************************************** - * - * Name: acexcep.h - Exception codes returned by the ACPI subsystem - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/include/acglobal.h =================================================================== RCS file: drivers/acpi/include/acglobal.h diff -N drivers/acpi/include/acglobal.h --- drivers/acpi/include/acglobal.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,232 +0,0 @@ -/****************************************************************************** - * - * Name: acglobal.h - Declarations for global variables - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/include/achware.h =================================================================== RCS file: drivers/acpi/include/achware.h diff -N drivers/acpi/include/achware.h --- drivers/acpi/include/achware.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,166 +0,0 @@ -/****************************************************************************** - * - * Name: achware.h -- hardware specific interfaces - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/include/acinterp.h =================================================================== RCS file: drivers/acpi/include/acinterp.h diff -N drivers/acpi/include/acinterp.h --- drivers/acpi/include/acinterp.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,704 +0,0 @@ -/****************************************************************************** - * - * Name: acinterp.h - Interpreter subcomponent prototypes and defines - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/include/aclocal.h =================================================================== RCS file: drivers/acpi/include/aclocal.h diff -N drivers/acpi/include/aclocal.h --- drivers/acpi/include/aclocal.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,973 +0,0 @@ -/****************************************************************************** - * - * Name: aclocal.h - Internal data types used across the ACPI subsystem - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/include/acmacros.h =================================================================== RCS file: drivers/acpi/include/acmacros.h diff -N drivers/acpi/include/acmacros.h --- drivers/acpi/include/acmacros.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,584 +0,0 @@ -/****************************************************************************** - * - * Name: acmacros.h - C macros for the entire subsystem. - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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 */ Index: drivers/acpi/include/acnamesp.h =================================================================== RCS file: drivers/acpi/include/acnamesp.h diff -N drivers/acpi/include/acnamesp.h --- drivers/acpi/include/acnamesp.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,423 +0,0 @@ -/****************************************************************************** - * - * Name: acnamesp.h - Namespace subcomponent prototypes and defines - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/include/acobject.h =================================================================== RCS file: drivers/acpi/include/acobject.h diff -N drivers/acpi/include/acobject.h --- drivers/acpi/include/acobject.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,451 +0,0 @@ - -/****************************************************************************** - * - * Name: acobject.h - Definition of acpi_operand_object (Internal object only) - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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 */ Index: drivers/acpi/include/acoutput.h =================================================================== RCS file: drivers/acpi/include/acoutput.h diff -N drivers/acpi/include/acoutput.h --- drivers/acpi/include/acoutput.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,182 +0,0 @@ -/****************************************************************************** - * - * Name: acoutput.h -- debug output - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/include/acparser.h =================================================================== RCS file: drivers/acpi/include/acparser.h diff -N drivers/acpi/include/acparser.h --- drivers/acpi/include/acparser.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,293 +0,0 @@ -/****************************************************************************** - * - * Module Name: acparser.h - AML Parser subcomponent prototypes and defines - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/include/acpi.h =================================================================== RCS file: drivers/acpi/include/acpi.h diff -N drivers/acpi/include/acpi.h --- drivers/acpi/include/acpi.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,51 +0,0 @@ -/****************************************************************************** - * - * Name: acpi.h - Master include file, Publics and external data. - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/include/acpiosxf.h =================================================================== RCS file: drivers/acpi/include/acpiosxf.h diff -N drivers/acpi/include/acpiosxf.h --- drivers/acpi/include/acpiosxf.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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__ */ Index: drivers/acpi/include/acpixf.h =================================================================== RCS file: drivers/acpi/include/acpixf.h diff -N drivers/acpi/include/acpixf.h --- drivers/acpi/include/acpixf.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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__ */ Index: drivers/acpi/include/acresrc.h =================================================================== RCS file: drivers/acpi/include/acresrc.h diff -N drivers/acpi/include/acresrc.h --- drivers/acpi/include/acresrc.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,320 +0,0 @@ -/****************************************************************************** - * - * Name: acresrc.h - Resource Manager function prototypes - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/include/acstruct.h =================================================================== RCS file: drivers/acpi/include/acstruct.h diff -N drivers/acpi/include/acstruct.h --- drivers/acpi/include/acstruct.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,199 +0,0 @@ -/****************************************************************************** - * - * Name: acstruct.h - Internal structs - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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 Index: drivers/acpi/include/actables.h =================================================================== RCS file: drivers/acpi/include/actables.h diff -N drivers/acpi/include/actables.h --- drivers/acpi/include/actables.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,200 +0,0 @@ -/****************************************************************************** - * - * Name: actables.h - ACPI table management - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/include/actbl.h =================================================================== RCS file: drivers/acpi/include/actbl.h diff -N drivers/acpi/include/actbl.h --- drivers/acpi/include/actbl.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,217 +0,0 @@ -/****************************************************************************** - * - * Name: actbl.h - Table data structures defined in ACPI specification - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/include/actbl1.h =================================================================== RCS file: drivers/acpi/include/actbl1.h diff -N drivers/acpi/include/actbl1.h --- drivers/acpi/include/actbl1.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,123 +0,0 @@ -/****************************************************************************** - * - * Name: actbl1.h - ACPI 1.0 tables - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ - - Index: drivers/acpi/include/actbl2.h =================================================================== RCS file: drivers/acpi/include/actbl2.h diff -N drivers/acpi/include/actbl2.h --- drivers/acpi/include/actbl2.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,186 +0,0 @@ -/****************************************************************************** - * - * Name: actbl2.h - ACPI Specification Revision 2.0 Tables - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ - Index: drivers/acpi/include/actbl71.h =================================================================== RCS file: drivers/acpi/include/actbl71.h diff -N drivers/acpi/include/actbl71.h --- drivers/acpi/include/actbl71.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ - Index: drivers/acpi/include/actypes.h =================================================================== RCS file: drivers/acpi/include/actypes.h diff -N drivers/acpi/include/actypes.h --- drivers/acpi/include/actypes.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1118 +0,0 @@ -/****************************************************************************** - * - * Name: actypes.h - Common data types for the entire ACPI subsystem - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/include/acutils.h =================================================================== RCS file: drivers/acpi/include/acutils.h diff -N drivers/acpi/include/acutils.h --- drivers/acpi/include/acutils.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,662 +0,0 @@ -/****************************************************************************** - * - * Name: acutils.h -- prototypes for the common (subsystem-wide) procedures - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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 */ Index: drivers/acpi/include/amlcode.h =================================================================== RCS file: drivers/acpi/include/amlcode.h diff -N drivers/acpi/include/amlcode.h --- drivers/acpi/include/amlcode.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/include/platform/acenv.h =================================================================== RCS file: drivers/acpi/include/platform/acenv.h diff -N drivers/acpi/include/platform/acenv.h --- drivers/acpi/include/platform/acenv.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,294 +0,0 @@ -/****************************************************************************** - * - * Name: acenv.h - Generation environment specific items - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/include/platform/acgcc.h =================================================================== RCS file: drivers/acpi/include/platform/acgcc.h diff -N drivers/acpi/include/platform/acgcc.h --- drivers/acpi/include/platform/acgcc.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,196 +0,0 @@ -/****************************************************************************** - * - * Name: acgcc.h - GCC specific defines, etc. - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/include/platform/aclinux.h =================================================================== RCS file: drivers/acpi/include/platform/aclinux.h diff -N drivers/acpi/include/platform/aclinux.h --- drivers/acpi/include/platform/aclinux.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,71 +0,0 @@ -/****************************************************************************** - * - * Name: aclinux.h - OS specific defines, etc. - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/kdb/README.txt =================================================================== RCS file: drivers/acpi/kdb/README.txt diff -N drivers/acpi/kdb/README.txt --- drivers/acpi/kdb/README.txt 22 Jul 2004 19:49:48 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: drivers/acpi/kdb/kdbm_acpi.c =================================================================== RCS file: drivers/acpi/kdb/kdbm_acpi.c diff -N drivers/acpi/kdb/kdbm_acpi.c --- drivers/acpi/kdb/kdbm_acpi.c 22 Jul 2004 19:49:48 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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"); -} Index: drivers/acpi/namespace/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/namespace/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/namespace/Makefile 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/namespace/Makefile 4 Aug 2004 01:28:35 -0000 1.2 @@ -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) Index: drivers/acpi/namespace/nsaccess.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/namespace/nsaccess.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/namespace/nsaccess.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/namespace/nsaccess.c 4 Aug 2004 01:28:35 -0000 1.2 @@ -1,43 +1,60 @@ /******************************************************************************* * * Module Name: nsaccess - Top-level functions for accessing ACPI namespace - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,51 @@ 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++) { + /* _OSI is optional for now, will be permanent later */ + + if (!ACPI_STRCMP (init_val->name, "_OSI") && !acpi_gbl_create_osi_method) { + continue; + } + 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 +123,21 @@ /* * 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 +153,29 @@ * 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_ASL_COMPILER) || defined (_ACPI_DUMP_App) + + /* i_aSL Compiler cheats by putting parameter count in the owner_iD */ + + new_node->owner_id = obj_desc->method.param_count; +#else + /* Mark this as a very SPECIAL method */ + + obj_desc->method.method_flags = AML_METHOD_INTERNAL_ONLY; + obj_desc->method.implementation = acpi_ut_osi_implementation; +#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 +184,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.sync_level = - (u16) STRTOUL (init_val->val, NULL, 10); + obj_desc->mutex.node = new_node; + obj_desc->mutex.sync_level = (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 +213,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 +226,8 @@ 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 +236,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 +246,31 @@ unlock_and_exit: - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + + /* Save a handle to "_GPE", it is always present */ + + if (ACPI_SUCCESS (status)) { + status = acpi_ns_get_node_by_path ("\\_GPE", NULL, ACPI_NS_NO_UPSEARCH, + &acpi_gbl_fadt_gpe_device); + } + 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 +284,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; + 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); - DEBUG_EXEC (u32 i;) - - 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 +327,274 @@ */ 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_REPORT_ERROR (("ns_lookup: %p is not a namespace node [%s]\n", + prefix_node, acpi_ut_get_descriptor_name (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; - - /* point to segment part */ + if (*path == (u8) AML_ROOT_PREFIX) { + /* Pathname is fully qualified, start from the root */ - pathname++; + this_node = acpi_gbl_root_node; + search_parent_flag = ACPI_NS_NO_UPSEARCH; - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching from root [%p]\n", - current_node)); + /* Point to name segment part */ - /* Direct reference to root, "\" */ + path++; - 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", + acpi_ut_get_node_name (prefix_node), 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", + acpi_ut_get_node_name (this_node), 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; - /* point to first segment */ + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, + "Prefix-only Pathname (Zero name segments), Flags=%X\n", flags)); + break; - pathname++; + case AML_DUAL_NAME_PREFIX: + + /* More than one name_seg, search rules do not apply */ + + search_parent_flag = ACPI_NS_NO_UPSEARCH; + + /* 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; + } - MOVE_UNALIGNED32_TO_32 (&simple_name, pathname); + /* Set error flag according to caller */ - /* Try to find the ACPI name */ + if (flags & ACPI_NS_ERROR_IF_FOUND) { + local_flags |= ACPI_NS_ERROR_IF_FOUND; + } + } - status = acpi_ns_search_and_enter (simple_name, walk_state, - current_node, interpreter_mode, - this_search_type, local_flags, - &this_node); + /* Extract one ACPI name from the front of the pathname */ + 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_METHOD_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 +602,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)); } } Index: drivers/acpi/namespace/nsalloc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/namespace/nsalloc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/namespace/nsalloc.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/namespace/nsalloc.c 4 Aug 2004 01:28:35 -0000 1.2 @@ -1,43 +1,60 @@ /******************************************************************************* * * Module Name: nsalloc - Namespace allocation and deletion utilities - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 (acpi_ut_get_node_name (child_node), acpi_ut_get_node_name (node)) < 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,27 @@ /* 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) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n", + acpi_ut_get_node_name (node), acpi_ut_get_type_name (node->type), node, owner_id, + acpi_ut_get_node_name (parent_node), acpi_ut_get_type_name (parent_node->type), + parent_node)); /* * Increment the reference count(s) of all parents up to * the root! */ - while ((node = acpi_ns_get_parent_object (node)) != NULL) { + while ((node = acpi_ns_get_parent_node (node)) != NULL) { node->reference_count++; } @@ -251,27 +354,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 +409,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 +454,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 +506,6 @@ child_node = 0; } } - else { /* * No more children of this parent node. @@ -403,17 +525,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 +548,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 +601,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 +675,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; } Index: drivers/acpi/namespace/nsdump.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/namespace/nsdump.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/namespace/nsdump.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/namespace/nsdump.c 4 Aug 2004 01:28:35 -0000 1.2 @@ -1,45 +1,102 @@ /****************************************************************************** * * Module Name: nsdump - table dumping routines for debug - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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) || defined(ENABLE_DEBUGGER) +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_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--) { + acpi_os_printf ("%2d%*s", (u32) level - 1, (int) level * 2, " "); - /* Print appropriate characters to form tree structure */ + /* Check the node type and name */ - 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, "-")); - } - } + if (type > ACPI_TYPE_LOCAL_MAX) { + ACPI_REPORT_WARNING (("Invalid ACPI Type %08X\n", type)); } - - /* Check the integrity of our data */ - - if (type > INTERNAL_TYPE_MAX) { - type = INTERNAL_TYPE_DEF_ANY; /* prints as *ERROR* */ - } - - 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 ", + acpi_ut_get_node_name (this_node), 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,147 @@ 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\n", 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_FORMAT_UINT64 (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_FORMAT_UINT64 (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]", + acpi_ut_get_node_name (obj_desc->buffer_field.buffer_obj->buffer.node)); + } 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]", + acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node)); 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]", + acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node), + acpi_ut_get_node_name (obj_desc->bank_field.bank_obj->common_field.node)); + break; + + + case ACPI_TYPE_LOCAL_INDEX_FIELD: + + acpi_os_printf ("Idx [%4.4s] Dat [%4.4s]", + acpi_ut_get_node_name (obj_desc->index_field.index_obj->common_field.node), + acpi_ut_get_node_name (obj_desc->index_field.data_obj->common_field.node)); 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_ALIAS: + case ACPI_TYPE_LOCAL_METHOD_ALIAS: + + acpi_os_printf ("Target %4.4s (%p)\n", acpi_ut_get_node_name (obj_desc), 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 +366,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 %.3X 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 (" I:%8.8X8.8%X\n", + ACPI_FORMAT_UINT64 (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 +445,56 @@ /* 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: + + acpi_os_printf ("(Ptr to Node)\n"); + bytes_to_dump = sizeof (struct acpi_namespace_node); + break; - 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); - } + case ACPI_DESC_TYPE_OPERAND: - else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) { - obj_type = obj_desc->common.type; + obj_type = ACPI_GET_OBJECT_TYPE (obj_desc); - if (obj_type > INTERNAL_TYPE_MAX) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to ACPI Object type %X [UNKNOWN])\n", obj_type)); + 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; - else { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(String or Buffer - not descriptor)\n")); + + default: + + acpi_os_printf ("(String or Buffer ptr - not an object descriptor) [%s]\n", + acpi_ut_get_descriptor_name (obj_desc)); 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,176 +503,97 @@ */ 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; info.owner_id = owner_id; 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); + (void) acpi_ns_walk_namespace (type, start_handle, max_depth, + ACPI_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. + * FUNCTION: acpi_ns_dump_tables * - ******************************************************************************/ - -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); -} - -#endif - -/******************************************************************************* - * - * 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 +602,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,18 +616,17 @@ * 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; ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "\\\n")); } - acpi_ns_dump_objects (ACPI_TYPE_ANY, ACPI_DISPLAY_OBJECTS, max_depth, ACPI_UINT32_MAX, search_handle); return_VOID; @@ -671,10 +635,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 +646,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 Index: drivers/acpi/namespace/nseval.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/namespace/nseval.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/namespace/nseval.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/namespace/nseval.c 4 Aug 2004 01:28:35 -0000 1.2 @@ -2,51 +2,68 @@ * * Module Name: nseval - Object evaluation interfaces -- includes control * method lookup and execution. - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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; + acpi_status status; + struct acpi_namespace_node *prefix_node; + struct acpi_namespace_node *node = NULL; + union acpi_generic_state *scope_info; + char *internal_path = NULL; - FUNCTION_TRACE ("Ns_evaluate_relative"); + ACPI_FUNCTION_TRACE ("ns_evaluate_relative"); /* @@ -89,28 +106,36 @@ return_ACPI_STATUS (status); } + scope_info = acpi_ut_create_generic_state (); + if (!scope_info) { + goto cleanup1; + } + /* 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)) { + goto cleanup; + } 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; } /* Lookup the name in the namespace */ - scope_info.scope.node = prefix_node; - status = acpi_ns_lookup (&scope_info, internal_path, ACPI_TYPE_ANY, - IMODE_EXECUTE, NS_NO_UPSEARCH, NULL, + scope_info->scope.node = prefix_node; + status = acpi_ns_lookup (scope_info, internal_path, ACPI_TYPE_ANY, + 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,16 +144,18 @@ * 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: + acpi_ut_delete_generic_state (scope_info); +cleanup1: ACPI_MEM_FREE (internal_path); return_ACPI_STATUS (status); } @@ -136,12 +163,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 +183,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 +202,21 @@ return_ACPI_STATUS (status); } - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + goto cleanup; + } /* Lookup the name in the namespace */ status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY, - 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 +225,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 +248,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 +267,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,14 +299,25 @@ /* 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); } + /* + * For a method alias, we must grab the actual method node + * so that proper scoping context will be established + * before execution. + */ + if (acpi_ns_get_type (node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) { + node = ACPI_CAST_PTR (struct acpi_namespace_node, node->object); + } /* * Two major cases here: @@ -285,7 +326,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 +335,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 +343,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 +362,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 +377,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 +396,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 +413,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 +430,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 +453,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); } + Index: drivers/acpi/namespace/nsinit.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/namespace/nsinit.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/namespace/nsinit.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/namespace/nsinit.c 4 Aug 2004 01:28:35 -0000 1.2 @@ -1,41 +1,59 @@ /****************************************************************************** * * Module Name: nsinit - namespace initialization - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,40 @@ 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:")); + + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "Executing device _INI methods:")); + /* Walk namespace for all objects of type Device or Processor */ - status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, FALSE, acpi_ns_init_one_device, &info, NULL); + status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, TRUE, acpi_ns_init_one_device, &info, NULL); + + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); 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 +171,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 +191,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 +256,60 @@ 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", + acpi_ut_get_node_name (node), 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 +318,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_init_one_device + * FUNCTION: acpi_ns_init_one_device * * PARAMETERS: acpi_walk_callback * @@ -280,85 +332,99 @@ 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, ".")); + node = acpi_ns_map_handle_to_node (obj_handle); + if (!node) { + return_ACPI_STATUS (AE_BAD_PARAMETER); } - info->device_count++; - - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + /* + * We will run _STA/_INI on Devices and Processors only + */ + if ((node->type != ACPI_TYPE_DEVICE) && + (node->type != ACPI_TYPE_PROCESSOR)) { + return_ACPI_STATUS (AE_OK); + } - node = acpi_ns_map_handle_to_node (obj_handle); - if (!node) { - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - return (AE_BAD_PARAMETER); + if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && (!(acpi_dbg_level & ACPI_LV_INFO))) { + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, ".")); } - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + info->device_count++; /* * 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 */ + if (node->type == ACPI_TYPE_DEVICE) { + /* Ignore error and move on to next device */ - return_ACPI_STATUS (AE_OK); - } + return_ACPI_STATUS (AE_OK); + } - info->num_STA++; + /* _STA is not required for Processor objects */ + } + else { + info->num_STA++; - if (!(flags & 0x01)) { - /* don't look at children of a not present device */ + if (!(flags & 0x01)) { + /* Don't look at children of a not present device */ - return_ACPI_STATUS(AE_CTRL_DEPTH); + 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); } Index: drivers/acpi/namespace/nsload.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/namespace/nsload.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/namespace/nsload.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/namespace/nsload.c 4 Aug 2004 01:28:35 -0000 1.2 @@ -1,239 +1,91 @@ /****************************************************************************** * * Module Name: nsload - namespace loading/expanding/contracting procedures - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 Index: drivers/acpi/namespace/nsnames.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/namespace/nsnames.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/namespace/nsnames.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/namespace/nsnames.c 4 Aug 2004 01:28:35 -0000 1.2 @@ -1,126 +1,175 @@ /******************************************************************************* * * Module Name: nsnames - Name manipulation and search - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); } Index: drivers/acpi/namespace/nsobject.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/namespace/nsobject.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/namespace/nsobject.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/namespace/nsobject.c 4 Aug 2004 01:28:35 -0000 1.2 @@ -2,43 +2,58 @@ * * Module Name: nsobject - Utilities for objects attached to namespace * table entries - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,170 @@ 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 %p [%s]\n", + node, acpi_ut_get_descriptor_name (node))); 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, acpi_ut_get_node_name (node))); + /* 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, acpi_ut_get_node_name (node), obj_desc)); /* Remove one reference on the object (and all subobjects) */ @@ -265,30 +246,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); +} + + Index: drivers/acpi/namespace/nssearch.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/namespace/nssearch.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/namespace/nssearch.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/namespace/nssearch.c 4 Aug 2004 01:28:35 -0000 1.2 @@ -1,52 +1,69 @@ /******************************************************************************* * * Module Name: nssearch - Namespace search - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,58 @@ 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) { + /* Resolve a control method alias if any */ + + if (acpi_ns_get_type (next_node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) { + next_node = ACPI_CAST_PTR (struct acpi_namespace_node, next_node->object); } /* - * 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] (%s) %p found in scope [%4.4s] %p\n", + (char *) &target_name, acpi_ut_get_type_name (next_node->type), + next_node, acpi_ut_get_node_name (node), 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 +146,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] (%s) not found in search in scope [%4.4s] %p first child %p\n", + (char *) &target_name, acpi_ut_get_type_name (type), + acpi_ut_get_node_name (node), node, node->child)); return_ACPI_STATUS (AE_NOT_FOUND); } @@ -158,18 +159,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 +184,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 +239,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 +250,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 +318,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 +329,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 +338,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 +351,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); Index: drivers/acpi/namespace/nsutils.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/namespace/nsutils.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/namespace/nsutils.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/namespace/nsutils.c 4 Aug 2004 01:28:35 -0000 1.2 @@ -2,42 +2,203 @@ * * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing * parents and siblings and Scope manipulation - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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; + + + if (!node) { + acpi_os_printf ("[NULL NAME]"); + return; + } + + /* 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 +210,7 @@ u8 acpi_ns_valid_root_prefix ( - NATIVE_CHAR prefix) + char prefix) { return ((u8) (prefix == '\\')); @@ -58,7 +219,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_valid_path_separator + * FUNCTION: acpi_ns_valid_path_separator * * PARAMETERS: Sep - Character to be checked * @@ -70,7 +231,7 @@ u8 acpi_ns_valid_path_separator ( - NATIVE_CHAR sep) + char sep) { return ((u8) (sep == '.')); @@ -79,7 +240,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_get_type + * FUNCTION: acpi_ns_get_type * * PARAMETERS: Handle - Parent Node to be examined * @@ -87,25 +248,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 input pointer\n")); 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 +277,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 +307,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 +325,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 +365,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 +383,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 +413,6 @@ result = &internal_name[3]; } } - else { /* * Not fully qualified. @@ -268,23 +425,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 +449,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 +470,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])); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n", + internal_name, internal_name)); } else { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "returning [%p] (rel) \"%s\"\n", - internal_name, &internal_name[2])); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n", + internal_name, internal_name)); } return_ACPI_STATUS (AE_OK); @@ -337,9 +489,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 +504,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 +521,6 @@ return_ACPI_STATUS (AE_BAD_PARAMETER); } - /* Get the length of the new internal name */ info.external_name = external_name; @@ -398,10 +549,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 +564,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 +596,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 +609,9 @@ } break; + + default: + break; } /* @@ -464,62 +620,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 +685,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 +698,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 +716,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 +740,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 +764,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 +781,7 @@ return (NULL); } - if (Node == Acpi_gbl_Root_node) + if (Node == acpi_gbl_root_node) { return (ACPI_ROOT_OBJECT); } @@ -637,7 +794,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_terminate + * FUNCTION: acpi_ns_terminate * * PARAMETERS: none * @@ -650,39 +807,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 +841,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_opens_scope + * FUNCTION: acpi_ns_opens_scope * * PARAMETERS: Type - A valid namespace type * @@ -702,34 +852,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 +891,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 (pathname) { + /* Convert path to internal representation */ - if (!acpi_gbl_root_node) { - return_ACPI_STATUS (AE_NO_NAMESPACE); - } - - 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); + goto cleanup; } - - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); - /* Setup lookup scope (search starting point) */ scope_info.scope.node = start_node; @@ -780,30 +928,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))); } + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - +cleanup: /* Cleanup */ - - ACPI_MEM_FREE (internal_path); + 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 +963,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, acpi_ut_get_node_name (child_node), + parent_node, acpi_ut_get_node_name (parent_node))); - 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, acpi_ut_get_node_name (child_node))); } 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 +1006,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 +1035,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_get_next_valid_node + * FUNCTION: acpi_ns_get_next_valid_node * * PARAMETERS: Node - Current table entry * @@ -938,9 +1048,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 */ Index: drivers/acpi/namespace/nswalk.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/namespace/nswalk.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/namespace/nswalk.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/namespace/nswalk.c 4 Aug 2004 01:28:35 -0000 1.2 @@ -1,49 +1,66 @@ /****************************************************************************** * * Module Name: nswalk - Functions for walking the ACPI namespace - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); } } Index: drivers/acpi/namespace/nsxfname.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/namespace/nsxfname.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/namespace/nsxfname.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/namespace/nsxfname.c 4 Aug 2004 01:28:35 -0000 1.2 @@ -2,50 +2,63 @@ * * Module Name: nsxfname - Public interfaces to the ACPI subsystem * ACPI Namespace oriented interfaces - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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, acpi_ut_get_node_name (node), 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,134 @@ 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 */ + + 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; + } - /* Execute the _UID method and save the result */ + /* Execute the Device._STA method */ - status = acpi_ut_execute_UID (node, &uid); - if (ACPI_SUCCESS (status)) { - STRCPY (info->unique_id, uid.buffer); + 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; + } + + /* Execute the Device._sx_d methods */ + + status = acpi_ut_execute_sxds (node, info.highest_dstates); + if (ACPI_SUCCESS (status)) { + info.valid |= ACPI_VALID_STA; + } - info->valid |= ACPI_VALID_UID; + 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); } Index: drivers/acpi/namespace/nsxfobj.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/namespace/nsxfobj.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/namespace/nsxfobj.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/namespace/nsxfobj.c 4 Aug 2004 01:28:35 -0000 1.2 @@ -2,345 +2,60 @@ * * Module Name: nsxfobj - Public interfaces to the ACPI subsystem * ACPI Object oriented interfaces - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); -} - - -/******************************************************************************* - * - * 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); -} - + ACPI_MODULE_NAME ("nsxfobj") /******************************************************************************* * - * 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 status; - acpi_namespace_node *node; - u32 flags; - acpi_device_id device_id; - acpi_get_devices_info *info; +acpi_status +acpi_get_next_object ( + acpi_object_type type, + acpi_handle parent, + acpi_handle child, + acpi_handle *ret_handle) +{ + 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); } + + Index: drivers/acpi/ospm/Makefile =================================================================== RCS file: drivers/acpi/ospm/Makefile diff -N drivers/acpi/ospm/Makefile --- drivers/acpi/ospm/Makefile 22 Jul 2004 19:49:48 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: drivers/acpi/ospm/ac_adapter/Makefile =================================================================== RCS file: drivers/acpi/ospm/ac_adapter/Makefile diff -N drivers/acpi/ospm/ac_adapter/Makefile --- drivers/acpi/ospm/ac_adapter/Makefile 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: drivers/acpi/ospm/ac_adapter/ac.c =================================================================== RCS file: drivers/acpi/ospm/ac_adapter/ac.c diff -N drivers/acpi/ospm/ac_adapter/ac.c --- drivers/acpi/ospm/ac_adapter/ac.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,398 +0,0 @@ -/***************************************************************************** - * - * Module Name: ac.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); -} Index: drivers/acpi/ospm/ac_adapter/ac_osl.c =================================================================== RCS file: drivers/acpi/ospm/ac_adapter/ac_osl.c diff -N drivers/acpi/ospm/ac_adapter/ac_osl.c --- drivers/acpi/ospm/ac_adapter/ac_osl.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,257 +0,0 @@ -/***************************************************************************** - * - * Module Name: ac_osl.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); Index: drivers/acpi/ospm/battery/Makefile =================================================================== RCS file: drivers/acpi/ospm/battery/Makefile diff -N drivers/acpi/ospm/battery/Makefile --- drivers/acpi/ospm/battery/Makefile 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: drivers/acpi/ospm/battery/bt.c =================================================================== RCS file: drivers/acpi/ospm/battery/bt.c diff -N drivers/acpi/ospm/battery/bt.c --- drivers/acpi/ospm/battery/bt.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,654 +0,0 @@ -/***************************************************************************** - * - * Module Name: bt.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); -} Index: drivers/acpi/ospm/battery/bt_osl.c =================================================================== RCS file: drivers/acpi/ospm/battery/bt_osl.c diff -N drivers/acpi/ospm/battery/bt_osl.c --- drivers/acpi/ospm/battery/bt_osl.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,443 +0,0 @@ -/****************************************************************************** - * - * Module Name: bt_osl.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); Index: drivers/acpi/ospm/busmgr/Makefile =================================================================== RCS file: drivers/acpi/ospm/busmgr/Makefile diff -N drivers/acpi/ospm/busmgr/Makefile --- drivers/acpi/ospm/busmgr/Makefile 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: drivers/acpi/ospm/busmgr/bm.c =================================================================== RCS file: drivers/acpi/ospm/busmgr/bm.c diff -N drivers/acpi/ospm/busmgr/bm.c --- drivers/acpi/ospm/busmgr/bm.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1146 +0,0 @@ -/****************************************************************************** - * - * Module Name: bm.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); -} Index: drivers/acpi/ospm/busmgr/bm_osl.c =================================================================== RCS file: drivers/acpi/ospm/busmgr/bm_osl.c diff -N drivers/acpi/ospm/busmgr/bm_osl.c --- drivers/acpi/ospm/busmgr/bm_osl.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,390 +0,0 @@ -/***************************************************************************** - * - * Module Name: bm_osl.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); Index: drivers/acpi/ospm/busmgr/bmdriver.c =================================================================== RCS file: drivers/acpi/ospm/busmgr/bmdriver.c diff -N drivers/acpi/ospm/busmgr/bmdriver.c --- drivers/acpi/ospm/busmgr/bmdriver.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,469 +0,0 @@ -/***************************************************************************** - * - * Module Name: bmdriver.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); -} Index: drivers/acpi/ospm/busmgr/bmnotify.c =================================================================== RCS file: drivers/acpi/ospm/busmgr/bmnotify.c diff -N drivers/acpi/ospm/busmgr/bmnotify.c --- drivers/acpi/ospm/busmgr/bmnotify.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,312 +0,0 @@ -/***************************************************************************** - * - * Module Name: bmnotify.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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; -} - - Index: drivers/acpi/ospm/busmgr/bmpm.c =================================================================== RCS file: drivers/acpi/ospm/busmgr/bmpm.c diff -N drivers/acpi/ospm/busmgr/bmpm.c --- drivers/acpi/ospm/busmgr/bmpm.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,442 +0,0 @@ -/***************************************************************************** - * - * Module Name: bmpm.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); -} Index: drivers/acpi/ospm/busmgr/bmpower.c =================================================================== RCS file: drivers/acpi/ospm/busmgr/bmpower.c diff -N drivers/acpi/ospm/busmgr/bmpower.c --- drivers/acpi/ospm/busmgr/bmpower.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,664 +0,0 @@ -/**************************************************************************** - * - * Module Name: bmpower.c - Driver for ACPI Power Resource 'devices' - * $Revision: 1.1 $ - * - ****************************************************************************/ - -/* - * 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); -} - - Index: drivers/acpi/ospm/busmgr/bmrequest.c =================================================================== RCS file: drivers/acpi/ospm/busmgr/bmrequest.c diff -N drivers/acpi/ospm/busmgr/bmrequest.c --- drivers/acpi/ospm/busmgr/bmrequest.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,164 +0,0 @@ -/****************************************************************************** - * - * Module Name: bmrequest.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); -} Index: drivers/acpi/ospm/busmgr/bmsearch.c =================================================================== RCS file: drivers/acpi/ospm/busmgr/bmsearch.c diff -N drivers/acpi/ospm/busmgr/bmsearch.c --- drivers/acpi/ospm/busmgr/bmsearch.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,192 +0,0 @@ -/****************************************************************************** - * - * Module Name: bmsearch.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); - } -} - Index: drivers/acpi/ospm/busmgr/bmutils.c =================================================================== RCS file: drivers/acpi/ospm/busmgr/bmutils.c diff -N drivers/acpi/ospm/busmgr/bmutils.c --- drivers/acpi/ospm/busmgr/bmutils.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,611 +0,0 @@ -/***************************************************************************** - * - * Module Name: bmutils.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); -} - - Index: drivers/acpi/ospm/button/Makefile =================================================================== RCS file: drivers/acpi/ospm/button/Makefile diff -N drivers/acpi/ospm/button/Makefile --- drivers/acpi/ospm/button/Makefile 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: drivers/acpi/ospm/button/bn.c =================================================================== RCS file: drivers/acpi/ospm/button/bn.c diff -N drivers/acpi/ospm/button/bn.c --- drivers/acpi/ospm/button/bn.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,507 +0,0 @@ -/***************************************************************************** - * - * Module Name: bn.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); -} Index: drivers/acpi/ospm/button/bn_osl.c =================================================================== RCS file: drivers/acpi/ospm/button/bn_osl.c diff -N drivers/acpi/ospm/button/bn_osl.c --- drivers/acpi/ospm/button/bn_osl.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,311 +0,0 @@ -/****************************************************************************** - * - * Module Name: bn_osl.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); Index: drivers/acpi/ospm/ec/Makefile =================================================================== RCS file: drivers/acpi/ospm/ec/Makefile diff -N drivers/acpi/ospm/ec/Makefile --- drivers/acpi/ospm/ec/Makefile 22 Jul 2004 19:49:48 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: drivers/acpi/ospm/ec/ec_osl.c =================================================================== RCS file: drivers/acpi/ospm/ec/ec_osl.c diff -N drivers/acpi/ospm/ec/ec_osl.c --- drivers/acpi/ospm/ec/ec_osl.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,91 +0,0 @@ -/***************************************************************************** - * - * Module Name: ec_osl.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); Index: drivers/acpi/ospm/ec/ecgpe.c =================================================================== RCS file: drivers/acpi/ospm/ec/ecgpe.c diff -N drivers/acpi/ospm/ec/ecgpe.c --- drivers/acpi/ospm/ec/ecgpe.c 22 Jul 2004 19:49:48 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,249 +0,0 @@ -/***************************************************************************** - * - * Module Name: ecgpe.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); -} Index: drivers/acpi/ospm/ec/ecmain.c =================================================================== RCS file: drivers/acpi/ospm/ec/ecmain.c diff -N drivers/acpi/ospm/ec/ecmain.c --- drivers/acpi/ospm/ec/ecmain.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,498 +0,0 @@ -/***************************************************************************** - * - * Module Name: ecmain.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); -} Index: drivers/acpi/ospm/ec/ecspace.c =================================================================== RCS file: drivers/acpi/ospm/ec/ecspace.c diff -N drivers/acpi/ospm/ec/ecspace.c --- drivers/acpi/ospm/ec/ecspace.c 22 Jul 2004 19:49:48 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,192 +0,0 @@ -/***************************************************************************** - * - * Module Name: ecspace.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); -} Index: drivers/acpi/ospm/ec/ectransx.c =================================================================== RCS file: drivers/acpi/ospm/ec/ectransx.c diff -N drivers/acpi/ospm/ec/ectransx.c --- drivers/acpi/ospm/ec/ectransx.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,343 +0,0 @@ -/***************************************************************************** - * - * Module Name: ectransx.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); -} Index: drivers/acpi/ospm/include/ac.h =================================================================== RCS file: drivers/acpi/ospm/include/ac.h diff -N drivers/acpi/ospm/include/ac.h --- drivers/acpi/ospm/include/ac.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,102 +0,0 @@ -/***************************************************************************** - * - * Module Name: ac.h - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/ospm/include/bm.h =================================================================== RCS file: drivers/acpi/ospm/include/bm.h diff -N drivers/acpi/ospm/include/bm.h --- drivers/acpi/ospm/include/bm.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,583 +0,0 @@ -/***************************************************************************** - * - * Module name: bm.h - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/ospm/include/bmpower.h =================================================================== RCS file: drivers/acpi/ospm/include/bmpower.h diff -N drivers/acpi/ospm/include/bmpower.h --- drivers/acpi/ospm/include/bmpower.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,75 +0,0 @@ -/***************************************************************************** - * - * Module name: bmpower.h - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/ospm/include/bn.h =================================================================== RCS file: drivers/acpi/ospm/include/bn.h diff -N drivers/acpi/ospm/include/bn.h --- drivers/acpi/ospm/include/bn.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,122 +0,0 @@ -/****************************************************************************** - * - * Module Name: bn.h - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/ospm/include/bt.h =================================================================== RCS file: drivers/acpi/ospm/include/bt.h diff -N drivers/acpi/ospm/include/bt.h --- drivers/acpi/ospm/include/bt.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,164 +0,0 @@ -/****************************************************************************** - * - * Module Name: bt.h - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/ospm/include/ec.h =================================================================== RCS file: drivers/acpi/ospm/include/ec.h diff -N drivers/acpi/ospm/include/ec.h --- drivers/acpi/ospm/include/ec.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,202 +0,0 @@ -/***************************************************************************** - * - * Module Name: ec.h - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/ospm/include/pr.h =================================================================== RCS file: drivers/acpi/ospm/include/pr.h diff -N drivers/acpi/ospm/include/pr.h --- drivers/acpi/ospm/include/pr.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,265 +0,0 @@ -/****************************************************************************** - * - * Module Name: processor.h - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/ospm/include/sm.h =================================================================== RCS file: drivers/acpi/ospm/include/sm.h diff -N drivers/acpi/ospm/include/sm.h --- drivers/acpi/ospm/include/sm.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,91 +0,0 @@ -/***************************************************************************** - * - * Module Name: sm.h - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/ospm/include/tz.h =================================================================== RCS file: drivers/acpi/ospm/include/tz.h diff -N drivers/acpi/ospm/include/tz.h --- drivers/acpi/ospm/include/tz.h 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,252 +0,0 @@ -/***************************************************************************** - * - * Module Name: tz.h - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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__ */ Index: drivers/acpi/ospm/processor/Makefile =================================================================== RCS file: drivers/acpi/ospm/processor/Makefile diff -N drivers/acpi/ospm/processor/Makefile --- drivers/acpi/ospm/processor/Makefile 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: drivers/acpi/ospm/processor/pr.c =================================================================== RCS file: drivers/acpi/ospm/processor/pr.c diff -N drivers/acpi/ospm/processor/pr.c --- drivers/acpi/ospm/processor/pr.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,497 +0,0 @@ -/***************************************************************************** - * - * Module Name: pr.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); -} Index: drivers/acpi/ospm/processor/pr_osl.c =================================================================== RCS file: drivers/acpi/ospm/processor/pr_osl.c diff -N drivers/acpi/ospm/processor/pr_osl.c --- drivers/acpi/ospm/processor/pr_osl.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,344 +0,0 @@ -/****************************************************************************** - * - * Module Name: pr_osl.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); Index: drivers/acpi/ospm/processor/prperf.c =================================================================== RCS file: drivers/acpi/ospm/processor/prperf.c diff -N drivers/acpi/ospm/processor/prperf.c --- drivers/acpi/ospm/processor/prperf.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,456 +0,0 @@ -/***************************************************************************** - * - * Module Name: prperf.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); -} - Index: drivers/acpi/ospm/processor/prpower.c =================================================================== RCS file: drivers/acpi/ospm/processor/prpower.c diff -N drivers/acpi/ospm/processor/prpower.c --- drivers/acpi/ospm/processor/prpower.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,665 +0,0 @@ -/***************************************************************************** - * - * Module Name: prpower.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); -} Index: drivers/acpi/ospm/system/Makefile =================================================================== RCS file: drivers/acpi/ospm/system/Makefile diff -N drivers/acpi/ospm/system/Makefile --- drivers/acpi/ospm/system/Makefile 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: drivers/acpi/ospm/system/sm.c =================================================================== RCS file: drivers/acpi/ospm/system/sm.c diff -N drivers/acpi/ospm/system/sm.c --- drivers/acpi/ospm/system/sm.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,373 +0,0 @@ -/***************************************************************************** - * - * Module Name: sm.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); -} Index: drivers/acpi/ospm/system/sm_osl.c =================================================================== RCS file: drivers/acpi/ospm/system/sm_osl.c diff -N drivers/acpi/ospm/system/sm_osl.c --- drivers/acpi/ospm/system/sm_osl.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,922 +0,0 @@ -/****************************************************************************** - * - * Module Name: sm_osl.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); Index: drivers/acpi/ospm/thermal/Makefile =================================================================== RCS file: drivers/acpi/ospm/thermal/Makefile diff -N drivers/acpi/ospm/thermal/Makefile --- drivers/acpi/ospm/thermal/Makefile 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: drivers/acpi/ospm/thermal/tz.c =================================================================== RCS file: drivers/acpi/ospm/thermal/tz.c diff -N drivers/acpi/ospm/thermal/tz.c --- drivers/acpi/ospm/thermal/tz.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,642 +0,0 @@ -/***************************************************************************** - * - * Module Name: tz.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); -} Index: drivers/acpi/ospm/thermal/tz_osl.c =================================================================== RCS file: drivers/acpi/ospm/thermal/tz_osl.c diff -N drivers/acpi/ospm/thermal/tz_osl.c --- drivers/acpi/ospm/thermal/tz_osl.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,398 +0,0 @@ -/****************************************************************************** - * - * Module Name: tz_osl.c - * $Revision: 1.1 $ - * - *****************************************************************************/ - -/* - * 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); Index: drivers/acpi/ospm/thermal/tzpolicy.c =================================================================== RCS file: drivers/acpi/ospm/thermal/tzpolicy.c diff -N drivers/acpi/ospm/thermal/tzpolicy.c --- drivers/acpi/ospm/thermal/tzpolicy.c 22 Jul 2004 19:49:49 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,578 +0,0 @@ -/**************************************************************************** - * - * Module Name: tzpolicy.c - - * $Revision: 1.1 $ - * - ****************************************************************************/ - -/* - * 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); -} Index: drivers/acpi/parser/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/parser/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/parser/Makefile 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/parser/Makefile 4 Aug 2004 01:28:36 -0000 1.2 @@ -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) Index: drivers/acpi/parser/psargs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/parser/psargs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/parser/psargs.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/parser/psargs.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,43 +1,61 @@ /****************************************************************************** * * Module Name: psargs - Parse AML opcode arguments - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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_REPORT_ERROR (( + "ps_get_next_namepath: 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 = (u32) 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 = (u32) 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); } Index: drivers/acpi/parser/psopcode.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/parser/psopcode.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/parser/psopcode.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/parser/psopcode.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,36 +1,54 @@ /****************************************************************************** * * Module Name: psopcode - Parser/Interpreter opcode information table - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 } - Index: drivers/acpi/parser/psparse.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/parser/psparse.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/parser/psparse.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/parser/psparse.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,26 +1,44 @@ /****************************************************************************** * * Module Name: psparse - Parser top level AML parse routines - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 + */ + 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->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)) { + 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: - /* - * 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. - */ + parser_state->aml = walk_state->aml_last_while; + walk_state->control_state->common.value = FALSE; + status = AE_CTRL_BREAK; + break; + + case AE_CTRL_CONTINUE: + + + parser_state->aml = walk_state->aml_last_while; + status = AE_CTRL_CONTINUE; + break; - /* TBD: How to handle a break within a while. */ - /* This code attempts it */ + 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,27 @@ 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 = NULL; + struct acpi_parse_state *parser_state; + u8 *aml_op_start = NULL; - FUNCTION_TRACE_PTR ("Ps_parse_loop", walk_state); + ACPI_FUNCTION_TRACE_PTR ("ps_parse_loop", walk_state); + if (walk_state->descending_callback == NULL) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } 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 +450,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 +469,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 +477,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 +494,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 = (u32) 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 +525,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 +542,85 @@ 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; + /* Allocate a new pre_op if necessary */ + + if (!pre_op) { + pre_op = acpi_ps_alloc_op (walk_state->opcode); + if (!pre_op) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + } + + 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); + 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 +628,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 +641,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 +657,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,244 +672,318 @@ } } - 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; - default: - /* Op is not a constant or string, append each argument */ + /* Op is not a constant or string, append each argument to the Op */ + + while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) && + !walk_state->arg_count) { + walk_state->aml_offset = (u32) 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; + } - 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); 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); } + /* Special processing for certain opcodes */ - /* For a method, save the length and address of the body */ + switch (op->common.aml_opcode) { + case AML_METHOD_OP: - if (op->opcode == AML_METHOD_OP) { /* - * Skip parsing of control method or opregion body, + * Skip parsing of control method * because we don't have enough info in the first pass - * to parse them correctly. + * to parse it correctly. + * + * Save the length and address of the body */ - ((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 */ - /* - * 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 Buffers and Packages + * 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; + if (pre_op) { + acpi_ps_free_op (pre_op); + pre_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); - default: /* All other non-AE_OK status */ + acpi_ps_complete_this_op (walk_state, op); + op = NULL; - if (op == NULL) { - acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count); + status = AE_OK; + break; + + + 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 +997,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 +1016,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 +1033,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 +1044,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 +1060,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 +1101,62 @@ 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); + + /* Check for possible multi-thread reentrancy problem */ + + if ((status == AE_ALREADY_EXISTS) && + (!walk_state->method_desc->method.semaphore)) { + /* + * This method is marked not_serialized, but it tried to create a named + * object, causing the second thread entrance to fail. We will workaround + * this by marking the method permanently as Serialized. + */ + walk_state->method_desc->method.method_flags |= AML_METHOD_SERIALIZED; + walk_state->method_desc->method.concurrency = 1; + } + } + + if (walk_state->method_desc) { + /* Decrement the thread count on the method parse tree */ + + if (walk_state->method_desc->method.thread_count) { + walk_state->method_desc->method.thread_count--; + } + } /* 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 +1167,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 +1182,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 +1215,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 +1224,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); } Index: drivers/acpi/parser/psscope.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/parser/psscope.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/parser/psscope.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/parser/psscope.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,41 +1,59 @@ /****************************************************************************** * * Module Name: psscope - Parser scope stack management routines - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,23 +151,22 @@ 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); } - scope->common.data_type = ACPI_DESC_TYPE_STATE_PSCOPE; scope->parse_scope.op = op; scope->parse_scope.arg_list = remaining_args; @@ -160,17 +177,15 @@ acpi_ut_push_generic_state (&parser_state->scope, scope); - if (arg_count == ACPI_VAR_ARGS) { /* multiple arguments */ scope->parse_scope.arg_end = parser_state->pkg_end; } - 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 +194,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 +210,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"); /* @@ -223,7 +238,6 @@ acpi_ut_delete_generic_state (scope); } - else { /* empty parse stack, prepare to fetch next opcode */ @@ -232,7 +246,6 @@ *arg_count = 0; } - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped Op %p Args %X\n", *op, *arg_count)); return_VOID; } @@ -240,9 +253,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,18 +266,18 @@ 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) { - return; + return_VOID; } - /* Delete anything on the scope stack */ while (parser_state->scope) { Index: drivers/acpi/parser/pstree.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/parser/pstree.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/parser/pstree.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/parser/pstree.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,40 +1,58 @@ /****************************************************************************** * * Module Name: pstree - Parser op tree manipulation/traversal/search - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); Index: drivers/acpi/parser/psutils.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/parser/psutils.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/parser/psutils.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/parser/psutils.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,47 +1,89 @@ /****************************************************************************** * * Module Name: psutils - Parser miscellaneous utilities (Parser only) - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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; } Index: drivers/acpi/parser/pswalk.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/parser/pswalk.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/parser/pswalk.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/parser/pswalk.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,47 +1,62 @@ /****************************************************************************** * * Module Name: pswalk - Parser routines to walk parsed op tree(s) - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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; Index: drivers/acpi/parser/psxface.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/parser/psxface.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/parser/psxface.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/parser/psxface.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,51 +1,68 @@ /****************************************************************************** * * Module Name: psxface - Parser external interfaces - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,106 +119,123 @@ * 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); + status = AE_NO_MEMORY; + goto cleanup1; } + /* + * 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); + status = AE_NO_MEMORY; + goto cleanup2; } 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 */ - return_ACPI_STATUS (status); + goto cleanup3; } /* Parse the AML */ status = acpi_ps_parse_aml (walk_state); acpi_ps_delete_parse_tree (op); + if (ACPI_FAILURE (status)) { + goto cleanup1; /* Walk state is already deleted */ + } /* * 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); + status = AE_NO_MEMORY; + goto cleanup1; } /* 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); + status = AE_NO_MEMORY; + goto cleanup2; } 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 */ - return_ACPI_STATUS (status); + goto cleanup3; } /* * The walk of the parse tree is where we actually execute the method */ status = acpi_ps_parse_aml (walk_state); + goto cleanup2; /* Walk state already deleted */ + + +cleanup3: + acpi_ds_delete_walk_state (walk_state); + +cleanup2: acpi_ps_delete_parse_tree (op); +cleanup1: if (params) { /* 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 */ + + (void) acpi_ut_update_object_reference (params[i], REF_DECREMENT); } } - if (ACPI_FAILURE (status)) { - DUMP_PATHNAME (method_node, "Ps_execute: method failed -", - ACPI_LV_ERROR, _COMPONENT); + return_ACPI_STATUS (status); } - /* * 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); } Index: drivers/acpi/resources/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/resources/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/resources/Makefile 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/resources/Makefile 4 Aug 2004 01:28:36 -0000 1.2 @@ -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) Index: drivers/acpi/resources/rsaddr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/resources/rsaddr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/resources/rsaddr.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/resources/rsaddr.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,81 +1,105 @@ /******************************************************************************* * * Module Name: rsaddr - Address resource descriptors (16/32/64) - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); + + /* Validate minimum descriptor length */ + + if (temp16 < 13) { + return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); + } *bytes_consumed = temp16 + 3; output_struct->id = ACPI_RSTYPE_ADDRESS16; @@ -87,6 +111,7 @@ temp8 = *buffer; /* Values 0-2 are valid */ + if (temp8 > 2) { return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); } @@ -99,24 +124,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 +146,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); + (u16) ((temp8 >> 1) & 0x03); } - 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 +169,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) @@ -190,8 +206,11 @@ * pointer to where the null terminated string goes: * Each Interrupt takes 32-bits + the 5 bytes of the * stream that are default. + * + * Note: Some resource descriptors will have an additional null, so + * we add 1 to the length. */ - if (*bytes_consumed > 16) { + if (*bytes_consumed > (16 + 1)) { /* Dereference the Index */ temp8 = *buffer; @@ -204,9 +223,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 +247,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 +263,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 +275,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 +291,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 +318,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,20 +341,22 @@ */ 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); temp8 |= (linked_list->data.address16.attribute.memory.cache_attribute & - 0x0F) << 1; + 0x03) << 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 +365,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 +401,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 + * 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,65 +427,67 @@ * 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; + /* Validate minimum descriptor length */ + + if (temp16 < 23) { + return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); + } + *bytes_consumed = temp16 + 3; output_struct->id = ACPI_RSTYPE_ADDRESS32; /* @@ -520,22 +535,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); + (u16) ((temp8 >> 1) & 0x03); } - 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 +559,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) @@ -584,8 +594,11 @@ * This will leave us pointing to the Resource Source Index * If it is present, then save it off and calculate the * pointer to where the null terminated string goes: + * + * Note: Some resource descriptors will have an additional null, so + * we add 1 to the length. */ - if (*bytes_consumed > 26) { + if (*bytes_consumed > (26 + 1)) { /* Dereference the Index */ temp8 = *buffer; @@ -599,14 +612,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 +634,13 @@ output_struct->data.address32.resource_source.string_length = index + 1; /* - * 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. + * 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. */ 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 +650,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 +662,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 +678,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 +702,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,20 +729,22 @@ */ 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); temp8 |= (linked_list->data.address32.attribute.memory.cache_attribute & - 0x0F) << 1; + 0x03) << 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 +753,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 +789,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 +820,58 @@ /******************************************************************************* * - * 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); + + /* Validate minimum descriptor length */ + + if (temp16 < 43) { + return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); + } *bytes_consumed = temp16 + 3; output_struct->id = ACPI_RSTYPE_ADDRESS64; @@ -874,6 +883,7 @@ temp8 = *buffer; /* Values 0-2 are valid */ + if(temp8 > 2) { return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); } @@ -912,22 +922,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); + (u16) ((temp8 >> 1) & 0x03); } - 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 +946,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) @@ -978,8 +983,11 @@ * pointer to where the null terminated string goes: * Each Interrupt takes 32-bits + the 5 bytes of the * stream that are default. + * + * Note: Some resource descriptors will have an additional null, so + * we add 1 to the length. */ - if (*bytes_consumed > 46) { + if (*bytes_consumed > (46 + 1)) { /* Dereference the Index */ temp8 = *buffer; @@ -993,14 +1001,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; @@ -1013,18 +1020,16 @@ * Add the terminating null */ *temp_ptr = 0x00; - 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 +1039,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 +1051,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 +1067,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; @@ -1087,12 +1091,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,20 +1118,22 @@ */ 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); temp8 |= (linked_list->data.address64.attribute.memory.cache_attribute & - 0x0F) << 1; + 0x03) << 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 +1142,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 +1178,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 + * 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 Index: drivers/acpi/resources/rscalc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/resources/rscalc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/resources/rscalc.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/resources/rscalc.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,44 +1,62 @@ /******************************************************************************* * * Module Name: rscalc - Calculate stream and list lengths - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 */ @@ -681,17 +696,15 @@ default: /* * If we get here, everything is out of sync, - * so exit with an error + * 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 += (u32) 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); } Index: drivers/acpi/resources/rscreate.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/resources/rscreate.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/resources/rscreate.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/resources/rscreate.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,50 +1,67 @@ /******************************************************************************* * * Module Name: rscreate - Create resource lists/tables - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 = (u32) 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); } Index: drivers/acpi/resources/rsdump.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/resources/rsdump.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/resources/rsdump.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/resources/rsdump.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,41 +1,59 @@ /******************************************************************************* * * Module Name: rsdump - Functions to display the resource structures. - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,35 @@ } 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 (" Granularity: %8.8X%8.8X\n", + ACPI_FORMAT_UINT64 (address64_data->granularity)); - acpi_os_printf (" Address range min: %16X\n", - address64_data->min_address_range); + acpi_os_printf (" Address range min: %8.8X%8.8X\n", + ACPI_FORMAT_UINT64 (address64_data->min_address_range)); - acpi_os_printf (" Address range max: %16X\n", - address64_data->max_address_range); + acpi_os_printf (" Address range max: %8.8X%8.8X\n", + ACPI_FORMAT_UINT64 (address64_data->max_address_range)); - acpi_os_printf (" Address translation offset: %16X\n", - address64_data->address_translation_offset); + acpi_os_printf (" Address translation offset: %8.8X%8.8X\n", + ACPI_FORMAT_UINT64 (address64_data->address_translation_offset)); - acpi_os_printf (" Address Length: %16X\n", - address64_data->address_length); + acpi_os_printf (" Address Length: %8.8X%8.8X\n", + ACPI_FORMAT_UINT64 (address64_data->address_length)); if(0xFF != address64_data->resource_source.index) { acpi_os_printf (" Resource Source Index: %X\n", @@ -893,7 +926,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_dump_extended_irq + * FUNCTION: acpi_rs_dump_extended_irq * * PARAMETERS: Data - pointer to the resource structure to dump. * @@ -905,31 +938,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 +987,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_dump_resource_list + * FUNCTION: acpi_rs_dump_resource_list * * PARAMETERS: Data - pointer to the resource structure to dump. * @@ -966,18 +999,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 +1022,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 +1043,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 +1082,7 @@ } - resource = POINTER_ADD (acpi_resource, resource, resource->length); + resource = ACPI_PTR_ADD (struct acpi_resource, resource, resource->length); } } @@ -1058,7 +1091,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_dump_irq_list + * FUNCTION: acpi_rs_dump_irq_list * * PARAMETERS: Data - pointer to the routing table to dump. * @@ -1070,36 +1103,36 @@ 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_FORMAT_UINT64 (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; Index: drivers/acpi/resources/rsio.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/resources/rsio.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/resources/rsio.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/resources/rsio.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,73 +1,90 @@ /******************************************************************************* * * Module Name: rsio - IO and DMA resource descriptors - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); } Index: drivers/acpi/resources/rsirq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/resources/rsirq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/resources/rsirq.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/resources/rsirq.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,75 +1,92 @@ /******************************************************************************* * * Module Name: rsirq - IRQ resource descriptors - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 @@ -111,27 +132,28 @@ temp8 = *buffer; /* - * Check for HE, LL or HL + * Check for HE, LL interrupts */ - if (temp8 & 0x01) { - output_struct->data.irq.edge_level = EDGE_SENSITIVE; - output_struct->data.irq.active_high_low = ACTIVE_HIGH; - } + switch (temp8 & 0x09) { + case 0x01: /* HE */ + output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE; + output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH; + break; + + case 0x08: /* LL */ + output_struct->data.irq.edge_level = ACPI_LEVEL_SENSITIVE; + output_struct->data.irq.active_high_low = ACPI_ACTIVE_LOW; + break; - else { - if (temp8 & 0x8) { - output_struct->data.irq.edge_level = LEVEL_SENSITIVE; - output_struct->data.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); - } + default: + /* + * Only _LL and _HE polarity/trigger interrupts + * are allowed (ACPI spec, section "IRQ Format") + * so 0x00 and 0x09 are illegal. + */ + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Invalid interrupt polarity/trigger in resource list, %X\n", temp8)); + return_ACPI_STATUS (AE_BAD_DATA); } /* @@ -139,21 +161,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 +186,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 +202,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 +244,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 +270,62 @@ /* * 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); + + /* Validate minimum descriptor length */ + + if (temp16 < 6) { + return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); + } *bytes_consumed = temp16 + 3; output_struct->id = ACPI_RSTYPE_EXT_IRQ; @@ -316,28 +339,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 @@ -350,6 +365,12 @@ buffer += 1; temp8 = *buffer; + /* Must have at least one IRQ */ + + if (temp8 < 1) { + return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); + } + output_struct->data.extended_irq.number_of_interrupts = temp8; /* @@ -367,8 +388,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 */ @@ -381,9 +402,12 @@ * pointer to where the null terminated string goes: * Each Interrupt takes 32-bits + the 5 bytes of the * stream that are default. + * + * Note: Some resource descriptors will have an additional null, so + * we add 1 to the length. */ 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 + 1)) { /* Dereference the Index */ temp8 = *buffer; @@ -397,14 +421,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 *)((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 +443,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 +459,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 +471,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 +487,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 +510,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 +519,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 +550,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 +562,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 Index: drivers/acpi/resources/rslist.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/resources/rslist.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/resources/rslist.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/resources/rslist.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,41 +1,59 @@ /******************************************************************************* * * Module Name: rslist - Linked list utilities - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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 = (u32) 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); } Index: drivers/acpi/resources/rsmemory.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/resources/rsmemory.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/resources/rsmemory.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/resources/rsmemory.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,73 +1,90 @@ /******************************************************************************* * * Module Name: rsmem24 - Memory resource descriptors - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); } Index: drivers/acpi/resources/rsmisc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/resources/rsmisc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/resources/rsmisc.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/resources/rsmisc.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,70 +1,87 @@ /******************************************************************************* * * Module Name: rsmisc - Miscellaneous resource descriptors - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); } Index: drivers/acpi/resources/rsutils.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/resources/rsutils.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/resources/rsutils.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/resources/rsutils.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,44 +1,62 @@ /******************************************************************************* * * Module Name: rsutils - Utilities for the resource manager - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); } Index: drivers/acpi/resources/rsxface.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/resources/rsxface.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/resources/rsxface.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/resources/rsxface.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,44 +1,60 @@ /******************************************************************************* * * Module Name: rsxface - Public interfaces to the resource manager - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,112 @@ /******************************************************************************* * - * 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. + * + ******************************************************************************/ + +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; + struct acpi_resource *buffer_end; + + + 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); + } + + /* Setup pointers */ + + resource = (struct acpi_resource *) buffer.pointer; + buffer_end = (struct acpi_resource *) ((u8 *) buffer.pointer + buffer.length); + + /* Walk the resource list */ + + 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; + } + + /* Get the next resource descriptor */ + + resource = ACPI_NEXT_RESOURCE (resource); + + /* Check for end-of-buffer */ + + if (resource >= buffer_end) { + goto cleanup; + } + } + +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 + * 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 +325,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 +353,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); +} Index: drivers/acpi/tables/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/tables/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/tables/Makefile 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/tables/Makefile 4 Aug 2004 01:28:36 -0000 1.2 @@ -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) Index: drivers/acpi/tables/tbconvrt.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/tables/tbconvrt.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/tables/tbconvrt.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/tables/tbconvrt.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,71 +1,84 @@ /****************************************************************************** * * Module Name: tbconvrt - ACPI Table conversion utilities - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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->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 + (ACPI_CAST_PTR (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]; + (ACPI_CAST_PTR (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 = ACPI_CAST_PTR (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*/ - - FADT2->header = FADT71->header; + ACPI_STORE_ADDRESS (new_gas_struct->address, address); - /* 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->length < sizeof (struct fadt_descriptor_rev1)) { + ACPI_REPORT_ERROR (("Invalid FADT table length: 0x%X\n", acpi_gbl_FADT->length)); + return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH); + } - FADT2->iapc_boot_arch = BAF_LEGACY_DEVICES; + if (acpi_gbl_FADT->revision >= FADT2_REVISION_ID) { + if (acpi_gbl_FADT->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->length, acpi_gbl_FADT->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->header.length = sizeof (FADT_DESCRIPTOR); - + acpi_gbl_FADT = local_fadt; + acpi_gbl_FADT->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 = ACPI_CAST_PTR (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_gbl_FADT->length, acpi_gbl_FADT->length)); + ACPI_DUMP_BUFFER ((u8 *) (acpi_gbl_FADT), acpi_gbl_FADT->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); } Index: drivers/acpi/tables/tbget.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/tables/tbget.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/tables/tbget.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/tables/tbget.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,754 +1,490 @@ /****************************************************************************** * * Module Name: tbget - ACPI Table get* routines - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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_FORMAT_UINT64 (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; + acpi_status status; - FUNCTION_TRACE ("Tb_get_all_tables"); + ACPI_FUNCTION_TRACE ("tb_get_table_body"); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Number of tables: %d\n", number_of_tables)); - - /* - * 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_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); - } + ACPI_REPORT_INFO (("Table [%4.4s] replaced by host OS\n", + table_info->pointer->signature)); - 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: + /* Pointer matches processor mode, copy the table to a new buffer */ -/******************************************************************************* - * - * 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) - * - ******************************************************************************/ - -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_FORMAT_UINT64 (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); - /* Convert and/or copy to an XSDT structure */ +#if (!ACPI_CHECKSUM_ABORT) + if (ACPI_FAILURE (status)) { + /* Ignore the error if configuration says so */ - 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_FORMAT_UINT64 (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); + *table_ptr_loc = NULL; + if (acpi_gbl_table_lists[table_type].next) { + *table_ptr_loc = acpi_gbl_table_lists[table_type].next->pointer; } + return_ACPI_STATUS (AE_OK); + } - /* 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); } Index: drivers/acpi/tables/tbinstal.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/tables/tbinstal.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/tables/tbinstal.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/tables/tbinstal.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,44 +1,118 @@ /****************************************************************************** * * Module Name: tbinstal - ACPI table installation and removal - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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; - FUNCTION_TRACE_U32 ("Tb_init_table_descriptor", table_type); + ACPI_FUNCTION_TRACE_U32 ("tb_init_table_descriptor", table_type); + + + /* Allocate a descriptor for this table */ + + table_desc = ACPI_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++; - - /* Update the original previous */ + list_head->count++; - 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,59 +425,31 @@ 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); - - - /* Get the head of the list */ - - table_desc = list_head; - count = list_head->count; + /* + * Free the table + * 1) Get the head of the list + */ + table_desc = acpi_gbl_table_lists[type].next; + count = acpi_gbl_table_lists[type].count; /* - * Walk the entire list, deleting both the allocated tables - * and the table descriptors + * 2) Walk the entire list, deleting both the allocated tables + * and the table descriptors */ for (i = 0; i < count; i++) { 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 +460,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 +506,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); } Index: drivers/acpi/tables/tbutils.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/tables/tbutils.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/tables/tbutils.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/tables/tbutils.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,162 +1,102 @@ /****************************************************************************** * * Module Name: tbutils - Table manipulation utilities - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); } Index: drivers/acpi/tables/tbxface.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/tables/tbxface.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/tables/tbxface.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/tables/tbxface.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -2,42 +2,59 @@ * * Module Name: tbxface - Public interfaces to the ACPI subsystem * ACPI table oriented interfaces - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); } Index: drivers/acpi/tables/tbxfroot.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/tables/tbxfroot.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/tables/tbxfroot.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/tables/tbxfroot.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,46 +1,301 @@ /****************************************************************************** * * Module Name: tbxfroot - Find the root ACPI table (RSDT) - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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_FORMAT_UINT64 (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 = (ACPI_CAST_PTR (RSDT_DESCRIPTOR, rsdt_info.pointer))->table_offset_entry[i]; + } + else { + address.pointer.value = + (ACPI_CAST_PTR (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 +305,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 +345,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 +377,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 +402,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 +421,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 +474,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 Index: drivers/acpi/utilities/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/utilities/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/utilities/Makefile 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/utilities/Makefile 4 Aug 2004 01:28:36 -0000 1.2 @@ -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) Index: drivers/acpi/utilities/utalloc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/utilities/utalloc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/utilities/utalloc.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/acpi/utilities/utalloc.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,44 +1,58 @@ /****************************************************************************** * * Module Name: utalloc - local cache and memory allocation routines - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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: Address - Address of allocated memory + * 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: 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 0%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,83 @@ void acpi_ut_dump_allocations ( - u32 component, - NATIVE_CHAR *module) + u32 component, + char *module) { - acpi_debug_mem_block *element; - u32 i; - - - FUNCTION_TRACE ("Ut_dump_allocations"); + struct acpi_debug_mem_block *element; + union acpi_descriptor *descriptor; + u32 num_outstanding = 0; - 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)); - - /* 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)); + ((module == NULL) || (0 == ACPI_STRCMP (module, element->module)))) { + /* Ignore allocated objects that are in a cache */ + + descriptor = ACPI_CAST_PTR (union acpi_descriptor, &element->user_space); + if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) { + acpi_os_printf ("%p Len %04X %9.9s-%d [%s] ", + descriptor, element->size, element->module, + element->line, acpi_ut_get_descriptor_name (descriptor)); + + /* Most of the elements will be Operand objects. */ + + switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) { + case ACPI_DESC_TYPE_OPERAND: + acpi_os_printf ("%12.12s R%hd", + acpi_ut_get_type_name (descriptor->object.common.type), + descriptor->object.common.reference_count); break; case ACPI_DESC_TYPE_PARSER: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " Parse_obj Opcode %04X", - ((acpi_parse_object *)(&element->user_space))->opcode)); + acpi_os_printf ("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)); - break; - - case ACPI_DESC_TYPE_STATE: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " Untyped State_obj")); + acpi_os_printf ("%4.4s", + acpi_ut_get_node_name (&descriptor->node)); break; - case ACPI_DESC_TYPE_STATE_UPDATE: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " UPDATE State_obj")); - break; - - case ACPI_DESC_TYPE_STATE_PACKAGE: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " PACKAGE State_obj")); - break; - - case ACPI_DESC_TYPE_STATE_CONTROL: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " CONTROL State_obj")); - break; - - case ACPI_DESC_TYPE_STATE_RPSCOPE: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " ROOT-PARSE-SCOPE State_obj")); - break; - - case ACPI_DESC_TYPE_STATE_PSCOPE: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " PARSE-SCOPE State_obj")); - break; - - case ACPI_DESC_TYPE_STATE_WSCOPE: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " WALK-SCOPE State_obj")); - break; - - case ACPI_DESC_TYPE_STATE_RESULT: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " RESULT State_obj")); - break; - - case ACPI_DESC_TYPE_STATE_NOTIFY: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " NOTIFY State_obj")); + default: 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; - -} - + (void) acpi_ut_release_mutex (ACPI_MTX_MEMORY); -/******************************************************************************* - * - * 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. - * - ******************************************************************************/ + /* Print summary */ -void * -acpi_ut_allocate ( - u32 size, - u32 component, - NATIVE_CHAR *module, - u32 line) -{ - acpi_debug_mem_block *address; - acpi_status status; - - - 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; + if (!num_outstanding) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "No outstanding allocations.\n")); } - - 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); - } - - 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 */ Index: drivers/acpi/utilities/utcopy.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/utilities/utcopy.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/utilities/utcopy.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/acpi/utilities/utcopy.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,46 +1,62 @@ /****************************************************************************** * * Module Name: utcopy - Internal to external object translation utilities - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); } + Index: drivers/acpi/utilities/utdebug.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/utilities/utdebug.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/utilities/utdebug.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/acpi/utilities/utdebug.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,46 +1,63 @@ /****************************************************************************** * * Module Name: utdebug - Debug print routines - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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_FORMAT_UINT64 (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"); Index: drivers/acpi/utilities/utdelete.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/utilities/utdelete.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/utilities/utdelete.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/acpi/utilities/utdelete.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,42 +1,59 @@ /******************************************************************************* * * Module Name: utdelete - object deletion and reference count utilities - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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.handler; + 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.handler; + 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))); - } + /* Now the object can be safely deleted */ - 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))); - - 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; + union acpi_operand_object *tmp; - 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,19 @@ * 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 */ + tmp = object->device.system_notify; + if (tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT) + object->device.system_notify = NULL; + acpi_ut_update_ref_count (tmp, action); + + tmp = object->device.device_notify; + if (tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT) + object->device.device_notify = NULL; + acpi_ut_update_ref_count (tmp, action); - next = object->addr_handler.next; - while (next) { - new = next->addr_handler.next; - acpi_ut_update_ref_count (next, action); - - next = new; - } break; @@ -460,8 +476,12 @@ 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; } + + tmp = object->package.elements[i]; + if (tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT) + object->package.elements[i] = NULL; } break; @@ -470,63 +490,86 @@ 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; } + + tmp = object->buffer_field.buffer_obj; + if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT) + object->buffer_field.buffer_obj = NULL; 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; } + + tmp = object->field.region_obj; + if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT) + object->field.region_obj = NULL; 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; } + tmp = object->bank_field.bank_obj; + if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT) + object->bank_field.bank_obj = NULL; + 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; } + + tmp = object->bank_field.region_obj; + if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT) + object->bank_field.region_obj = NULL; 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; } + tmp = object->index_field.index_obj; + if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT) + object->index_field.index_obj = NULL; + 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; } + + tmp = object->index_field.data_obj; + if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT) + object->index_field.data_obj = NULL; 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 +577,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 +609,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 +642,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 +654,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 +672,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; } Index: drivers/acpi/utilities/uteval.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/utilities/uteval.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/utilities/uteval.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/acpi/utilities/uteval.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,123 +1,314 @@ /****************************************************************************** * * Module Name: uteval - Object evaluation - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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_osi_implementation * - * PARAMETERS: *Object_name - Object name to be evaluated - * Device_node - Node for the device - * *Address - Where the value is returned + * PARAMETERS: walk_state - Current walk state + * + * RETURN: Status + * + * DESCRIPTION: Implementation of _OSI predefined control method + * Supported = _OSI (String) + * + ******************************************************************************/ + +acpi_status +acpi_ut_osi_implementation ( + struct acpi_walk_state *walk_state) +{ + union acpi_operand_object *string_desc; + union acpi_operand_object *return_desc; + acpi_native_uint i; + + + ACPI_FUNCTION_TRACE ("ut_osi_implementation"); + + + /* Validate the string input argument */ + + string_desc = walk_state->arguments[0].object; + if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) { + return_ACPI_STATUS (AE_TYPE); + } + + /* Create a return object (Default value = 0) */ + + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); + if (!return_desc) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + /* Compare input string to table of supported strings */ + + for (i = 0; i < ACPI_NUM_OSI_STRINGS; i++) { + if (!ACPI_STRCMP (string_desc->string.pointer, + (char *) acpi_gbl_valid_osi_strings[i])) { + /* This string is supported */ + + return_desc->integer.value = 0xFFFFFFFF; + break; + } + } + + walk_state->return_desc = return_desc; + return_ACPI_STATUS (AE_CTRL_TERMINATE); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_evaluate_object + * + * 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", + acpi_ut_get_node_name (prefix_node), 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: 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 + * PARAMETERS: device_node - Node for the device * *Hid - Where the HID is returned * * RETURN: Status @@ -131,170 +322,255 @@ 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)); + + /* The _CID object can be either a single CID or a package (list) of CIDs */ + + if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) { + /* Translate each package element */ + + for (i = 0; i < count; i++) { + 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); } + /* Cleanup on error */ + + if (ACPI_FAILURE (status)) { + ACPI_MEM_FREE (cid_list); + } else { - if (obj_desc->common.type == ACPI_TYPE_INTEGER) { - /* Convert the Numeric UID to string */ + *return_cid_list = cid_list; + } - acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->buffer); - } + /* On exit, we must delete the _CID return object */ - else { - /* Copy the String UID from the returned object */ + acpi_ut_remove_reference (obj_desc); + return_ACPI_STATUS (status); +} - STRNCPY(uid->buffer, obj_desc->string.pointer, sizeof(uid->buffer)); - } + +/******************************************************************************* + * + * FUNCTION: acpi_ut_execute_UID + * + * PARAMETERS: device_node - Node for the device + * *Uid - Where the UID is returned + * + * RETURN: Status + * + * 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_UID ( + struct acpi_namespace_node *device_node, + struct acpi_device_id *uid) +{ + union acpi_operand_object *obj_desc; + acpi_status status; + + + ACPI_FUNCTION_TRACE ("ut_execute_UID"); + + + 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); } + if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { + /* Convert the Numeric UID to string */ + + acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->value); + } + else { + /* Copy the String UID from the returned object */ + + acpi_ut_copy_id_string (uid->value, obj_desc->string.pointer, + sizeof (uid->value)); + } /* On exit, we must delete the return object */ acpi_ut_remove_reference (obj_desc); - - return (status); + return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ut_execute_STA + * FUNCTION: acpi_ut_execute_STA * - * PARAMETERS: Device_node - Node for the device + * PARAMETERS: device_node - Node for the device * *Flags - Where the status flags are returned * * RETURN: Status @@ -308,62 +584,97 @@ acpi_status acpi_ut_execute_STA ( - acpi_namespace_node *device_node, - u32 *flags) + struct acpi_namespace_node *device_node, + u32 *flags) { - 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_STA"); - /* Execute the method */ + 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", + acpi_ut_get_node_name (device_node))); - 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)); + *flags = 0x0F; + status = AE_OK; + } - *flags = 0x0F; - status = AE_OK; + return_ACPI_STATUS (status); } - 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))); - } + /* Extract the status flags */ - else /* success */ { - /* Did we get a return object? */ + *flags = (u32) obj_desc->integer.value; - if (!obj_desc) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _STA\n")); - return_ACPI_STATUS (AE_TYPE); - } + /* On exit, we must delete the return object */ - /* Is the return object of the correct type? */ + acpi_ut_remove_reference (obj_desc); + return_ACPI_STATUS (status); +} - 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)); - } - else { - /* Extract the status flags */ +/******************************************************************************* + * + * FUNCTION: acpi_ut_execute_Sxds + * + * 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 + * + ******************************************************************************/ + +acpi_status +acpi_ut_execute_sxds ( + struct acpi_namespace_node *device_node, + u8 *highest) +{ + union acpi_operand_object *obj_desc; + acpi_status status; + u32 i; + + + ACPI_FUNCTION_TRACE ("ut_execute_Sxds"); + + + for (i = 0; i < 4; i++) { + highest[i] = 0xFF; + status = acpi_ut_evaluate_object (device_node, + (char *) acpi_gbl_highest_dstate_names[i], + ACPI_BTYPE_INTEGER, &obj_desc); + if (ACPI_FAILURE (status)) { + if (status != AE_NOT_FOUND) { + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, + "%s on Device %4.4s, %s\n", + (char *) acpi_gbl_highest_dstate_names[i], + acpi_ut_get_node_name (device_node), + acpi_format_exception (status))); - *flags = (u32) obj_desc->integer.value; + return_ACPI_STATUS (status); + } } + else { + /* Extract the Dstate value */ - /* On exit, we must delete the return object */ + highest[i] = (u8) obj_desc->integer.value; - acpi_ut_remove_reference (obj_desc); + /* Delete the return object */ + + acpi_ut_remove_reference (obj_desc); + } } - return_ACPI_STATUS (status); + return_ACPI_STATUS (AE_OK); } Index: drivers/acpi/utilities/utglobal.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/utilities/utglobal.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/utilities/utglobal.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/acpi/utilities/utglobal.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,44 +1,58 @@ /****************************************************************************** * * Module Name: utglobal - Global variables for the ACPI subsystem - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,55 @@ /* 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_sleep_state_names[ACPI_S_STATE_COUNT] = { + "\\_S0_", + "\\_S1_", + "\\_S2_", + "\\_S3_", + "\\_S4_", + "\\_S5_"}; + +const char *acpi_gbl_highest_dstate_names[4] = { + "_S1D", + "_S2D", + "_S3D", + "_S4D"}; + +/* Strings supported by the _OSI predefined (internal) method */ + +const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] = { + "Linux", + "Windows 2000", + "Windows 2001", + "Windows 2001.1"}; /****************************************************************************** @@ -158,86 +202,78 @@ /* - * 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. + * Predefined ACPI Names (Built-in to the Interpreter) * * NOTES: - * 1) _SB_ is defined to be a device to allow _SB_/_INI to be run + * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run * during the initialization sequence. */ +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"}, -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 */ +#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 method_alias */ + ACPI_NS_NORMAL, /* 23 Notify */ + ACPI_NS_NORMAL, /* 24 Address Handler */ + ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 25 Resource Desc */ + ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 26 Resource Field */ + ACPI_NS_NEWSCOPE, /* 27 Scope */ + ACPI_NS_NORMAL, /* 28 Extra */ + ACPI_NS_NORMAL, /* 29 Data */ + ACPI_NS_NORMAL /* 30 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 +285,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,86 +297,195 @@ /****************************************************************************** * - * 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. + * ******************************************************************************/ +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}, +}; -acpi_table_desc acpi_gbl_acpi_tables[NUM_ACPI_TABLES]; +/****************************************************************************** + * + * 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, ACPI_BITMASK_RT_CLOCK_STATUS, ACPI_BITMASK_RT_CLOCK_ENABLE}, +}; -/* - * 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 * stored in a table it really means that we have thus far seen no evidence to - * indicatewhat type is actually going to be stored for this entry. + * indicate what 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 +494,188 @@ /* 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" + /* 22 */ "method_alias", + /* 23 */ "Notify", + /* 24 */ "addr_handler", + /* 25 */ "resource_desc", + /* 26 */ "resource_fld", + /* 27 */ "Scope", + /* 28 */ "Extra", + /* 29 */ "Data", + /* 30 */ "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))); +} /***************************************************************************** * - * FUNCTION: Acpi_ut_get_region_name + * FUNCTION: acpi_ut_get_node_name * - * PARAMETERS: None. + * PARAMETERS: Object - A namespace node * - * RETURN: Status + * RETURN: Pointer to a string * - * DESCRIPTION: Translate a Space ID into a name string (Debug only) + * DESCRIPTION: Validate the node and return the node's ACPI name. * ****************************************************************************/ -NATIVE_CHAR * -acpi_ut_get_region_name ( - u8 space_id) +char * +acpi_ut_get_node_name ( + void *object) { + struct acpi_namespace_node *node = (struct acpi_namespace_node *) object; + + + if (!object) + { + return ("NULL NODE"); + } + + if (object == ACPI_ROOT_OBJECT) + { + node = acpi_gbl_root_node; + } - if (space_id >= USER_REGION_BEGIN) + if (node->descriptor != ACPI_DESC_TYPE_NAMED) { - return ("User_defined_region"); + return ("****"); } - else if (space_id >= NUM_REGION_TYPES) + if (!acpi_ut_valid_acpi_name (* (u32 *) node->name.ascii)) { - return ("Invalid_space_iD"); + return ("----"); } - return ((NATIVE_CHAR *) acpi_gbl_region_types[space_id]); + return (node->name.ascii); } -/* Data used in keeping track of fields */ +/***************************************************************************** + * + * FUNCTION: acpi_ut_get_descriptor_name + * + * PARAMETERS: Object - An ACPI object + * + * RETURN: Pointer to a string + * + * DESCRIPTION: Validate object and return the descriptor type + * + ****************************************************************************/ -const NATIVE_CHAR *acpi_gbl_FEnames[NUM_FIELD_NAMES] = +static const char *acpi_gbl_desc_type_names[] = /* printable names of descriptor types */ { - "skip", - "?access?" -}; /* FE = Field Element */ + /* 00 */ "Invalid", + /* 01 */ "Cached", + /* 02 */ "State-Generic", + /* 03 */ "State-Update", + /* 04 */ "State-Package", + /* 05 */ "State-Control", + /* 06 */ "State-root_parse_scope", + /* 07 */ "State-parse_scope", + /* 08 */ "State-walk_scope", + /* 09 */ "State-Result", + /* 10 */ "State-Notify", + /* 11 */ "State-Thread", + /* 12 */ "Walk", + /* 13 */ "Parser", + /* 14 */ "Operand", + /* 15 */ "Node" +}; -const NATIVE_CHAR *acpi_gbl_match_ops[NUM_MATCH_OPS] = +char * +acpi_ut_get_descriptor_name ( + void *object) { - "Error", - "MTR", - "MEQ", - "MLE", - "MLT", - "MGE", - "MGT" -}; + if (!object) + { + return ("NULL OBJECT"); + } -/* Access type decoding */ + if (ACPI_GET_DESCRIPTOR_TYPE (object) > ACPI_DESC_TYPE_MAX) + { + return ((char *) acpi_gbl_bad_type); + } -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" -}; + return ((char *) acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE (object)]); +} -/* Update rule decoding */ -const NATIVE_CHAR *acpi_gbl_update_rules[NUM_UPDATE_RULES] = +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) +/* + * Strings and procedures used for debug only + */ + +/***************************************************************************** + * + * FUNCTION: acpi_ut_get_mutex_name + * + * PARAMETERS: None. + * + * RETURN: Status + * + * DESCRIPTION: Translate a mutex ID into a name string (Debug only) + * + ****************************************************************************/ + +char * +acpi_ut_get_mutex_name ( + u32 mutex_id) { - "Preserve", - "Write_as_ones", - "Write_as_zeros" -}; + + if (mutex_id > MAX_MUTEX) + { + return ("Invalid Mutex ID"); + } + + return (acpi_gbl_mutex_names[mutex_id]); +} #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 +685,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 +701,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 +711,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; - } - - acpi_ut_release_mutex (ACPI_MTX_CACHES); + default: + break; + } + (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 +778,39 @@ acpi_ut_init_globals ( void) { - u32 i; + u32 i; + + + ACPI_FUNCTION_TRACE ("ut_init_globals"); + /* Runtime configuration */ - FUNCTION_TRACE ("Ut_init_globals"); + acpi_gbl_create_osi_method = TRUE; + acpi_gbl_all_methods_serialized = FALSE; + acpi_gbl_leave_wake_gpes_disabled = TRUE; /* 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 +822,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 +861,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 +873,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; Index: drivers/acpi/utilities/utinit.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/utilities/utinit.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/utilities/utinit.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/utilities/utinit.c 4 Aug 2004 01:28:36 -0000 1.2 @@ -1,52 +1,63 @@ /****************************************************************************** * * Module Name: utinit - Common ACPI subsystem initialization - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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; } Index: drivers/acpi/utilities/utmath.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/utilities/utmath.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/utilities/utmath.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/utilities/utmath.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -1,34 +1,52 @@ /******************************************************************************* * * Module Name: utmath - Integer math support routines - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); } Index: drivers/acpi/utilities/utmisc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/utilities/utmisc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/utilities/utmisc.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/utilities/utmisc.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -1,45 +1,292 @@ /******************************************************************************* * * Module Name: utmisc - common utility procedures - * $Revision: 1.1 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,19 +301,23 @@ u8 acpi_ut_valid_acpi_name ( - u32 name) + u32 name) { - NATIVE_CHAR *name_ptr = (NATIVE_CHAR *) &name; - u32 i; + char *name_ptr = (char *) &name; + char character; + acpi_native_uint i; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); for (i = 0; i < ACPI_NAME_SIZE; i++) { - if (!((name_ptr[i] == '_') || - (name_ptr[i] >= 'A' && name_ptr[i] <= 'Z') || - (name_ptr[i] >= '0' && name_ptr[i] <= '9'))) { + character = *name_ptr; + name_ptr++; + + if (!((character == '_') || + (character >= 'A' && character <= 'Z') || + (character >= '0' && character <= '9'))) { return (FALSE); } } @@ -77,7 +328,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_valid_acpi_character + * FUNCTION: acpi_ut_valid_acpi_character * * PARAMETERS: Character - The character to be examined * @@ -89,10 +340,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 +353,186 @@ /******************************************************************************* * - * 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 * - * PARAMETERS: Src_string - The source string to convert to + * RETURN: Converted value * - * RETURN: Src_string + * 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 + * + * 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 +546,31 @@ 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); } } - return_ACPI_STATUS (AE_OK); + status = acpi_os_create_lock (&acpi_gbl_gpe_lock); + return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ut_mutex_terminate + * FUNCTION: acpi_ut_mutex_terminate * * PARAMETERS: None. * @@ -186,28 +584,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 +616,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 +641,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 +653,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 +676,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 +688,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 +710,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 +729,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 +754,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 +766,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 +781,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 +796,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 +816,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 +838,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 +852,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 +873,6 @@ return (AE_NO_MEMORY); } - acpi_ut_push_generic_state (state_list, state); return (AE_OK); } @@ -491,11 +880,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 +894,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 +910,6 @@ return (AE_NO_MEMORY); } - acpi_ut_push_generic_state (state_list, state); return (AE_OK); } @@ -529,9 +917,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 +930,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 +947,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 +957,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 +982,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_create_generic_state + * FUNCTION: acpi_ut_create_generic_state * * PARAMETERS: None * @@ -605,13 +993,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 +1016,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 +1069,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 +1099,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 +1111,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 +1144,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_create_control_state + * FUNCTION: acpi_ut_create_control_state * * PARAMETERS: None * @@ -728,28 +1155,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 +1183,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_delete_generic_state + * FUNCTION: acpi_ut_delete_generic_state * * PARAMETERS: State - The state object to be deleted * @@ -770,9 +1196,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 +1208,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_delete_generic_state_cache + * FUNCTION: acpi_ut_delete_generic_state_cache * * PARAMETERS: None * @@ -797,7 +1223,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 +1233,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 +1245,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 +1266,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 +1301,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 +1319,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 +1343,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 +1447,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 +1459,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 +1474,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 +1485,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 +1500,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); Index: drivers/acpi/utilities/utobject.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/utilities/utobject.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/utilities/utobject.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/acpi/utilities/utobject.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -1,48 +1,63 @@ /****************************************************************************** * * Module Name: utobject - ACPI object create/delete/size/cache routines - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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,113 @@ /******************************************************************************* * - * 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)); - } - - else { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "**** Obj %p is of unknown type\n", object)); - } + return (TRUE); - return (FALSE); + default: + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + "%p is not not an ACPI operand obj [%s]\n", + object, acpi_ut_get_descriptor_name (object))); + break; } - - /* The object appears to be a valid acpi_operand_object */ - - return (TRUE); + 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 +251,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 +282,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,16 +294,17 @@ 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)); + "%p is not an ACPI Operand object [%s]\n", object, + acpi_ut_get_descriptor_name (object))); return_VOID; } @@ -232,11 +316,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 +331,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 +341,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 +358,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 +375,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 +415,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 +446,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 +476,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 +502,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 +541,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 +557,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 +578,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 +592,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); } Index: drivers/acpi/utilities/utxface.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/acpi/utilities/utxface.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/acpi/utilities/utxface.c 22 Jul 2004 19:49:49 -0000 1.1 +++ drivers/acpi/utilities/utxface.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -1,46 +1,61 @@ /****************************************************************************** * * Module Name: utxface - External interfaces for "global" ACPI functions - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2004, 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); +} Index: drivers/at91/i2c/at91_i2c.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/at91/i2c/at91_i2c.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/at91/i2c/at91_i2c.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/at91/i2c/at91_i2c.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -46,70 +46,16 @@ static struct at91_i2c_local *at91_i2c_device; /* - * SMBUS-type transfer entrypoint + * Poll the i2c status register until the specified bit is set. + * Returns 0 if timed out (100 msec) */ -static s32 at91_smbus_xfer(struct i2c_adapter *adap, - u16 addr, - unsigned short flags, - char read_write, - u8 command, int size, union i2c_smbus_data *data) -{ -#if 0 - struct at91_i2c_local *device = (struct at91_i2c_local *) adap->data; - int len; - u8 *buffer; - u16 cur_word; - int rc = 0; - - /* Prepare datas & select mode */ - switch (size) { - case I2C_SMBUS_QUICK: - len = 0; - buffer = NULL; - break; - case I2C_SMBUS_BYTE: - len = 1; - buffer = &data->byte; - break; - case I2C_SMBUS_BYTE_DATA: - len = 1; - buffer = &data->byte; - break; - case I2C_SMBUS_WORD_DATA: - len = 2; - cur_word = cpu_to_le16(data->word); - buffer = (u8 *) & cur_word; - break; - case I2C_SMBUS_BLOCK_DATA: - len = data->block[0]; - buffer = &data->block[1]; - break; - default: - return -1; - } - - /* Original driver had this limitation */ - if (len > 32) - len = 32; - - DBG("chan: %d, addr: 0x%x, transfer len: %d, read: %d\n", - device->chan_no, addr, len, read_write == I2C_SMBUS_READ); - - /* Set up address and r/w bit */ - write_reg(reg_addr, (addr << 1) | ((read_write == I2C_SMBUS_READ) ? 0x01 : 0x00)); - - /* Set up the sub address */ +static short at91_poll_status(AT91PS_TWI twi, unsigned long bit) { + int loop_cntr = 10000; + do { + udelay(10); + } while (!(twi->TWI_SR & bit) && (--loop_cntr > 0)); - /* Start sending address & enable interrupt */ - write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_XADDR); - write_reg(reg_ier, KW_I2C_IRQ_MASK); - - DBG("transfer done\n"); - - if (size == I2C_SMBUS_WORD_DATA && read_write == I2C_SMBUS_READ) - data->word = le16_to_cpu(cur_word); -#endif - return 0; + return (loop_cntr > 0); } /* @@ -121,11 +67,17 @@ AT91PS_TWI twi = (AT91PS_TWI) device->base_addr; struct i2c_msg *pmsg; - int completed = 0, length; + int length; unsigned char *buf; + /* + * i2c_smbus_xfer_emulated() in drivers/i2c/i2c-core.c states: + * "... In the case of writing, we need to use only one message; + * when reading, we need two..." + */ + pmsg = msgs; /* look at 1st message, it contains the address/command */ - if (num == 2 && pmsg->len >= 1 && pmsg->len <= 3) { + if (num >= 1 && num <= 2) { DBG("xfer: doing %s %d bytes to 0x%02x - %d messages\n", pmsg->flags & I2C_M_RD ? "read" : "write", pmsg->len, pmsg->buf[0], num); @@ -142,7 +94,10 @@ else /* must be 3 */ twi->TWI_IADR = pmsg->buf[0] << 16 | pmsg->buf[1] << 8 | pmsg->buf[2]; - pmsg++; /* go to real message */ + /* 1st message contains the address/command */ + if (num > 1) + pmsg++; /* go to real message */ + length = pmsg->len; buf = pmsg->buf; if (length && buf) { /* sanity check */ @@ -152,33 +107,41 @@ if (!length) twi->TWI_CR = AT91C_TWI_STOP; /* Wait until transfer is finished */ - do - udelay(10); - while (!(twi->TWI_SR & AT91C_TWI_RXRDY)); + if (!at91_poll_status(twi, AT91C_TWI_RXRDY)) { + printk(KERN_ERR "at91_i2c: timeout 1\n"); + return 0; + } *buf++ = twi->TWI_RHR; } - do { - udelay(10); - } while (!(twi->TWI_SR & AT91C_TWI_TXCOMP)); + if (!at91_poll_status(twi, AT91C_TWI_TXCOMP)) { + printk(KERN_ERR "at91_i2c: timeout 2\n"); + return 0; + } } else { twi->TWI_CR = AT91C_TWI_START; while (length--) { twi->TWI_THR = *buf++; if (!length) twi->TWI_CR = AT91C_TWI_STOP; - do { - udelay(10); - } while (!(twi->TWI_SR & AT91C_TWI_TXRDY)); + if (!at91_poll_status(twi, AT91C_TWI_TXRDY)) { + printk(KERN_ERR "at91_i2c: timeout 3\n"); + return 0; + } } /* Wait until transfer is finished */ - do { - udelay(10); - } while (!(twi->TWI_SR & AT91C_TWI_TXCOMP)); + if (!at91_poll_status(twi, AT91C_TWI_TXCOMP)) { + printk(KERN_ERR "at91_i2c: timeout 4\n"); + return 0; + } } } + DBG("transfer complete\n"); + return num; + } + else { + printk(KERN_ERR "at91_i2c: unexpected number of messages: %d\n", num); + return 0; } - DBG("transfer done\n"); - return completed++; } /* @@ -197,7 +160,6 @@ static void at91_inc(struct i2c_adapter *adapter) { MOD_INC_USE_COUNT; - AT91_SYS->PMC_PCER = 1 << AT91C_ID_TWI; /* enable peripheral clock */ } /* @@ -205,7 +167,6 @@ */ static void at91_dec(struct i2c_adapter *adapter) { - AT91_SYS->PMC_PCDR = 1 << AT91C_ID_TWI; /* disable peripheral clock */ MOD_DEC_USE_COUNT; } @@ -213,7 +174,6 @@ static struct i2c_algorithm at91_algorithm = { name:"at91 i2c", id:I2C_ALGO_SMBUS, - smbus_xfer:at91_smbus_xfer, master_xfer:at91_xfer, functionality:at91_func, }; @@ -228,6 +188,7 @@ int rc; AT91_CfgPIO_TWI(); + AT91_SYS->PMC_PCER = 1 << AT91C_ID_TWI; /* enable peripheral clock */ twi->TWI_IDR = 0x3ff; /* Disable all interrupts */ twi->TWI_CR = AT91C_TWI_SWRST; /* Reset peripheral */ @@ -277,6 +238,8 @@ rc = i2c_del_adapter(&device->adapter); device->adapter.data = NULL; kfree(device); + + AT91_SYS->PMC_PCDR = 1 << AT91C_ID_TWI; /* disable peripheral clock */ /* We aren't that prepared to deal with this... */ if (rc) Index: drivers/at91/i2c/at91_i2c.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/at91/i2c/at91_i2c.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/at91/i2c/at91_i2c.h 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/at91/i2c/at91_i2c.h 4 Aug 2004 01:28:37 -0000 1.2 @@ -23,7 +23,7 @@ #define AT91C_TWI_CLOCK 100000 #define AT91C_TWI_SCLOCK (10 * AT91C_MASTER_CLOCK / AT91C_TWI_CLOCK) -#define AT91C_TWI_CKDIV1 (1 << 16) /* TWI clock divider */ +#define AT91C_TWI_CKDIV1 (2 << 16) /* TWI clock divider. NOTE: see Errata #22 */ #if (AT91C_TWI_SCLOCK % 10) >= 5 #define AT91C_TWI_CLDIV2 ((AT91C_TWI_SCLOCK / 10) - 5) Index: drivers/at91/mtd/at91_dataflash.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/at91/mtd/at91_dataflash.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/at91/mtd/at91_dataflash.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/at91/mtd/at91_dataflash.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -135,7 +135,7 @@ /* ......................................................................... */ /* - * Erase a block of flash. + * Erase blocks of flash. */ int at91_dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) { @@ -150,7 +150,7 @@ /* Sanity checks */ if (instr->addr + instr->len > mtd->size) return -EINVAL; - if ((instr->len != mtd->erasesize) || (instr->len != priv->page_size)) + if ((instr->len % mtd->erasesize != 0) || (instr->len % priv->page_size != 0)) return -EINVAL; if ((instr->addr % priv->page_size) != 0) return -EINVAL; @@ -159,23 +159,28 @@ if (!command) return -ENOMEM; - /* Calculate flash page address */ - pageaddr = (instr->addr / priv->page_size) << priv->page_offset; - - command[0] = OP_ERASE_PAGE; - command[1] = (pageaddr & 0x00FF0000) >> 16; - command[2] = (pageaddr & 0x0000FF00) >> 8; - command[3] = 0; + while (instr->len > 0) { + /* Calculate flash page address */ + pageaddr = (instr->addr / priv->page_size) << priv->page_offset; + + command[0] = OP_ERASE_PAGE; + command[1] = (pageaddr & 0x00FF0000) >> 16; + command[2] = (pageaddr & 0x0000FF00) >> 8; + command[3] = 0; #ifdef DEBUG_DATAFLASH - printk("ERASE: (%x) %x %x %x [%i]\n", command[0], command[1], command[2], command[3], pageaddr); + printk("ERASE: (%x) %x %x %x [%i]\n", command[0], command[1], command[2], command[3], pageaddr); #endif - /* Send command to SPI device */ - spi_access_bus(priv->spi); - do_spi_transfer(1, command, 4, command, 4, NULL, 0, NULL, 0); + /* Send command to SPI device */ + spi_access_bus(priv->spi); + do_spi_transfer(1, command, 4, command, 4, NULL, 0, NULL, 0); - at91_dataflash_waitready(); /* poll status until ready */ - spi_release_bus(priv->spi); + at91_dataflash_waitready(); /* poll status until ready */ + spi_release_bus(priv->spi); + + instr->addr += priv->page_size; /* next page */ + instr->len -= priv->page_size; + } kfree(command); @@ -249,10 +254,11 @@ struct dataflash_local *priv = (struct dataflash_local *) mtd->priv; unsigned int pageaddr, addr, offset, writelen; size_t remaining; - char *writebuf; + u_char *writebuf; unsigned short status; int res = 0; char* command; + char* tmpbuf = NULL; #ifdef DEBUG_DATAFLASH printk("dataflash_write: %lli .. %lli\n", to, to+len); @@ -279,6 +285,13 @@ writebuf = buf; remaining = len; + /* Allocate temporary buffer */ + tmpbuf = kmalloc(priv->page_size, GFP_KERNEL); + if (!tmpbuf) { + kfree(command); + return -ENOMEM; + } + /* Gain access to the SPI bus */ spi_access_bus(priv->spi); @@ -310,7 +323,7 @@ #ifdef DEBUG_DATAFLASH printk("PROGRAM: (%x) %x %x %x\n", command[0], command[1], command[2], command[3]); #endif - do_spi_transfer(2, command, 4, command, 4, writebuf, writelen, writebuf, writelen); + do_spi_transfer(2, command, 4, command, 4, writebuf, writelen, tmpbuf, writelen); at91_dataflash_waitready(); /* (3) Compare to Buffer1 */ @@ -348,6 +361,7 @@ /* Release SPI bus */ spi_release_bus(priv->spi); + kfree(tmpbuf); kfree(command); return res; } Index: drivers/at91/mtd/at91_nand.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/at91/mtd/at91_nand.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/at91/mtd/at91_nand.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/at91/mtd/at91_nand.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -31,7 +31,7 @@ * MTD structure for AT91 board */ static struct mtd_info *at91_mtd = NULL; -static struct nand_chip *my_nand_chip; +static struct nand_chip *my_nand_chip = NULL; static int at91_fio_base; @@ -79,7 +79,7 @@ /* * Hardware specific access to control-lines */ -void at91_hwcontrol(int cmd) +static void at91_hwcontrol(int cmd) { struct nand_chip *my_nand = my_nand_chip; switch(cmd) @@ -168,14 +168,14 @@ /* * Read the Device Ready pin. */ -int at91_device_ready(void) +static int at91_device_ready(void) { return AT91_PIO_SmartMedia_RDY(); } /* * Main initialization routine */ -int __init at91_init (void) +static int __init at91_init (void) { struct nand_chip *my_nand; int err = 0; @@ -211,7 +211,8 @@ my_nand->IO_ADDR_W = at91_fio_base; my_nand->hwcontrol = at91_hwcontrol; my_nand->dev_ready = at91_device_ready; - my_nand->cmdfunc = at91_nand_command; /* we need our own */ + my_nand->cmdfunc = at91_nand_command; /* we need our own */ + my_nand->eccmode = NAND_ECC_SOFT; /* enable ECC */ /* 20 us command delay time */ my_nand->chip_delay = 20; @@ -222,11 +223,11 @@ tDH Data Hold Time 20 - ns tALS ALE Set up Time 20 - ns 16ns at 60 MHz ~= 3 */ -#define AT91C_SM_ID_RWH (5 << 28) /* debug only orig = 5 */ +#define AT91C_SM_ID_RWH (5 << 28) /* orig = 5 */ #define AT91C_SM_RWH (1 << 28) /* orig = 1 */ #define AT91C_SM_RWS (0 << 24) /* orig = 0 */ #define AT91C_SM_TDF (1 << 8) /* orig = 1 */ -#define AT91C_SM_NWS (3) /* orig = 3 */ +#define AT91C_SM_NWS (5) /* orig = 3 */ AT91_SYS->EBI_SMC2_CSR[3] = ( AT91C_SM_RWH | AT91C_SM_RWS | AT91C_SMC2_ACSS_STANDARD | AT91C_SMC2_DBW_8 | AT91C_SM_TDF | Index: drivers/at91/net/at91_ether.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/at91/net/at91_ether.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/at91/net/at91_ether.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/at91/net/at91_ether.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -6,6 +6,9 @@ * Based on an earlier Atmel EMAC macrocell driver by Atmel and Lineo Inc. * Initial version by Rick Bronson 01/11/2003 * + * Intel LXT971A PHY support by Christopher Bahns & David Knickerbocker + * (Polaroid 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 @@ -55,10 +58,10 @@ * Write value to the a PHY register * Note: MDI interface is assumed to already have been enabled. */ -static void write_phy(AT91PS_EMAC regs, unsigned char address, unsigned int value) +static void write_phy(AT91PS_EMAC regs, unsigned char phy_addr, unsigned char address, unsigned int value) { regs->EMAC_MAN = (AT91C_EMAC_HIGH | AT91C_EMAC_CODE_802_3 | AT91C_EMAC_RW_W - | (address << 18)) + (value & 0xffff); + | ((phy_addr & 0x1f) << 23) | (address << 18)) + (value & 0xffff); /* Wait until IDLE bit in Network Status register is cleared */ // TODO: Enforce some maximum loop-count? @@ -69,10 +72,10 @@ * Read value stored in a PHY register. * Note: MDI interface is assumed to already have been enabled. */ -static void read_phy(AT91PS_EMAC regs, unsigned char address, unsigned int *value) +static void read_phy(AT91PS_EMAC regs, unsigned char phy_addr, unsigned char address, unsigned int *value) { regs->EMAC_MAN = AT91C_EMAC_HIGH | AT91C_EMAC_CODE_802_3 | AT91C_EMAC_RW_R - | (address << 18); + | ((phy_addr & 0x1f) << 23) | (address << 18); /* Wait until IDLE bit in Network Status register is cleared */ // TODO: Enforce some maximum loop-count? @@ -96,15 +99,15 @@ unsigned int speed, duplex; /* Link status is latched, so read twice to get current value */ - read_phy(regs, MII_BMSR, &bmsr); - read_phy(regs, MII_BMSR, &bmsr); + read_phy(regs, 0, MII_BMSR, &bmsr); + read_phy(regs, 0, MII_BMSR, &bmsr); if (!(bmsr & BMSR_LSTATUS)) return -1; /* no link */ - read_phy(regs, MII_BMCR, &bmcr); + read_phy(regs, 0, MII_BMCR, &bmcr); if (bmcr & BMCR_ANENABLE) { /* AutoNegotiation is enabled */ if (!(bmsr & BMSR_ANEGCOMPLETE)) return -2; /* auto-negotitation in progress */ - read_phy(regs, MII_LPA, &lpa); + read_phy(regs, 0, MII_LPA, &lpa); if ((lpa & LPA_100FULL) || (lpa & LPA_100HALF)) speed = SPEED_100; else speed = SPEED_10; if ((lpa & LPA_100FULL) || (lpa & LPA_10FULL)) duplex = DUPLEX_FULL; @@ -135,16 +138,20 @@ /* * Handle interrupts from the PHY */ -void at91ether_phy_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static void at91ether_phy_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; + struct at91_private *lp = (struct at91_private *) dev->priv; AT91PS_EMAC emac = (AT91PS_EMAC) dev->base_addr; int status; unsigned int phy; enable_mdi(emac); - - read_phy(emac, MII_DSINTR_REG, &phy); /* acknowledge interrupt in PHY */ + if (lp->phy_type == MII_DM9161_ID) + read_phy(emac, 0, MII_DSINTR_REG, &phy); /* ack interrupt in Davicom PHY */ + else if (lp->phy_type == MII_LXT971A_ID) + read_phy(emac, 0, MII_ISINTS_REG, &phy); /* ack interrupt in Intel PHY */ + status = AT91_SYS->PIOC_ISR; /* acknowledge interrupt in PIO */ status = update_linkspeed(dev, emac); @@ -162,61 +169,103 @@ /* * Initialize and enable the PHY interrupt when link-state changes */ -void enable_phyirq(struct net_device *dev, AT91PS_EMAC regs) +static void enable_phyirq(struct net_device *dev, AT91PS_EMAC regs) { struct at91_private *lp = (struct at91_private *) dev->priv; unsigned int dsintr, status; - static int first_init = 0; - - if (first_init == 0) { - // TODO: Check error code. Really need a generic PIO (interrupt) - // layer since we're really only interested in the PC4 line. - (void) request_irq(4, at91ether_phy_interrupt, 0, dev->name, dev); - - AT91_SYS->PIOC_ODR = AT91C_PIO_PC4; /* Configure as input */ - - first_init = 1; - } - else { - status = AT91_SYS->PIOC_ISR; /* clear any pending PIO interrupts */ - AT91_SYS->PIOC_IER = AT91C_PIO_PC4; /* Enable interrupt */ + // TODO: Check error code. Really need a generic PIO (interrupt) + // layer since we're really only interested in the PC4 (DK) or PC2 (CSB337) line. + (void) request_irq(AT91C_ID_PIOC, at91ether_phy_interrupt, 0, dev->name, dev); + + status = AT91_SYS->PIOC_ISR; /* clear any pending PIO interrupts */ +#ifdef CONFIG_MACH_CSB337 + AT91_SYS->PIOC_IER = AT91C_PIO_PC2; /* Enable interrupt */ +#else + AT91_SYS->PIOC_IER = AT91C_PIO_PC4; /* Enable interrupt */ +#endif - spin_lock_irq(&lp->lock); - enable_mdi(regs); - read_phy(regs, MII_DSINTR_REG, &dsintr); + spin_lock_irq(&lp->lock); + enable_mdi(regs); + + if (lp->phy_type == MII_DM9161_ID) { /* for Davicom PHY */ + read_phy(regs, 0, MII_DSINTR_REG, &dsintr); dsintr = dsintr & ~0xf00; /* clear bits 8..11 */ - write_phy(regs, MII_DSINTR_REG, dsintr); - disable_mdi(regs); - spin_unlock_irq(&lp->lock); + write_phy(regs, 0, MII_DSINTR_REG, dsintr); + } + else if (lp->phy_type == MII_LXT971A_ID) { /* for Intel PHY */ + read_phy(regs, 0, MII_ISINTE_REG, &dsintr); + dsintr = dsintr | 0xf2; /* set bits 1, 4..7 */ + write_phy(regs, 0, MII_ISINTE_REG, dsintr); } + + disable_mdi(regs); + spin_unlock_irq(&lp->lock); } /* * Disable the PHY interrupt */ -void disable_phyirq(struct net_device *dev, AT91PS_EMAC regs) +static void disable_phyirq(struct net_device *dev, AT91PS_EMAC regs) { struct at91_private *lp = (struct at91_private *) dev->priv; unsigned int dsintr; spin_lock_irq(&lp->lock); enable_mdi(regs); - read_phy(regs, MII_DSINTR_REG, &dsintr); - dsintr = dsintr | 0xf00; /* set bits 8..11 */ - write_phy(regs, MII_DSINTR_REG, dsintr); + + if (lp->phy_type == MII_DM9161_ID) { /* for Davicom PHY */ + read_phy(regs, 0, MII_DSINTR_REG, &dsintr); + dsintr = dsintr | 0xf00; /* set bits 8..11 */ + write_phy(regs, 0, MII_DSINTR_REG, dsintr); + } + else if (lp->phy_type == MII_LXT971A_ID) { /* for Intel PHY */ + read_phy(regs, 0, MII_ISINTE_REG, &dsintr); + dsintr = dsintr & ~0xf2; /* clear bits 1, 4..7 */ + write_phy(regs, 0, MII_ISINTE_REG, dsintr); + } + disable_mdi(regs); spin_unlock_irq(&lp->lock); +#ifdef CONFIG_MACH_CSB337 + AT91_SYS->PIOC_IDR = AT91C_PIO_PC2; /* Disable interrupt */ +#else AT91_SYS->PIOC_IDR = AT91C_PIO_PC4; /* Disable interrupt */ +#endif + free_irq(AT91C_ID_PIOC, dev); /* Free interrupt handler */ } +/* + * Perform a software reset of the PHY. + */ +static void reset_phy(struct net_device *dev, AT91PS_EMAC regs) +{ + struct at91_private *lp = (struct at91_private *) dev->priv; + unsigned int bmcr; + + spin_lock_irq(&lp->lock); + enable_mdi(regs); + + /* Perform PHY reset */ + write_phy(regs, 0, MII_BMCR, BMCR_RESET); + + /* Wait until PHY reset is complete */ + do { + read_phy(regs, 0, MII_BMCR, &bmcr); + } while (!(bmcr && BMCR_RESET)); + + disable_mdi(regs); + spin_unlock_irq(&lp->lock); +} + + /* ......................... ADDRESS MANAGEMENT ........................ */ /* * Set the ethernet MAC address in dev->dev_addr */ -void get_mac_address(struct net_device *dev) { +static void get_mac_address(struct net_device *dev) { AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr; char addr[6]; unsigned int hi, lo; @@ -342,7 +391,7 @@ AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr; unsigned int value; - read_phy(regs, location, &value); + read_phy(regs, phy_id, location, &value); return value; } @@ -350,7 +399,7 @@ { AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr; - write_phy(regs, location, value); + write_phy(regs, phy_id, location, value); } /* @@ -373,6 +422,10 @@ case ETHTOOL_GSET: { struct ethtool_cmd ecmd = { ETHTOOL_GSET }; res = mii_ethtool_gset(&lp->mii, &ecmd); + if (lp->phy_media == PORT_FIBRE) { /* override media type since mii.c doesn't know */ + ecmd.supported = SUPPORTED_FIBRE; + ecmd.port = PORT_FIBRE; + } if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) res = -EFAULT; break; @@ -464,7 +517,7 @@ return -EADDRNOTAVAIL; AT91_SYS->PMC_PCER = 1 << AT91C_ID_EMAC; /* Re-enable Peripheral clock */ - regs->EMAC_CTL |= AT91C_EMAC_CSR; /* Clear internal statistics */ + regs->EMAC_CTL |= AT91C_EMAC_CSR; /* Clear internal statistics */ /* Enable PHY interrupt */ enable_phyirq(dev, regs); @@ -659,11 +712,12 @@ /* * Initialize the ethernet interface */ -static int at91ether_setup(struct net_device *dev) +static int at91ether_setup(struct net_device *dev, unsigned long phy_type) { struct at91_private *lp; AT91PS_EMAC regs; static int already_initialized = 0; + unsigned int val; if (already_initialized) return 0; @@ -715,16 +769,30 @@ regs->EMAC_CTL = 0; #ifdef CONFIG_AT91_ETHER_RMII - regs->EMAC_CFG = AT91C_EMAC_RMII; + regs->EMAC_CFG = AT91C_EMAC_BIG | AT91C_EMAC_RMII; #else - regs->EMAC_CFG = 0; + regs->EMAC_CFG = AT91C_EMAC_BIG; #endif + if (phy_type == MII_LXT971A_ID) + regs->EMAC_CFG |= AT91C_EMAC_CLK_HCLK_64; /* MDIO clock = system clock/64 */ + + if (phy_type == MII_DM9161_ID) { + spin_lock_irq(&lp->lock); + enable_mdi(regs); + + read_phy(regs, 0, MII_DSCR_REG, &val); + if ((val & (1 << 10)) == 0) /* DSCR bit 10 is 0 -- fiber mode */ + lp->phy_media = PORT_FIBRE; + + disable_mdi(regs); + spin_unlock_irq(&lp->lock); + } lp->mii.dev = dev; /* Support for ethtool */ lp->mii.mdio_read = mdio_read; lp->mii.mdio_write = mdio_write; - - enable_phyirq(dev, regs); + + lp->phy_type = phy_type; /* Type of PHY connected */ /* Determine current link speed */ spin_lock_irq(&lp->lock); @@ -740,6 +808,10 @@ regs->EMAC_CFG & AT91C_EMAC_FD ? "FullDuplex" : "HalfDuplex", dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + if (phy_type == MII_DM9161_ID) + printk(KERN_INFO "%s: Davicom 9196 PHY %s\n", dev->name, (lp->phy_media == PORT_FIBRE) ? "(Fiber)" : "(Copper)"); + else if (phy_type == MII_LXT971A_ID) + printk(KERN_INFO "%s: Intel LXT971A PHY\n", dev->name); already_initialized = 1; return 0; @@ -748,7 +820,7 @@ /* * Detect MAC and PHY and perform initialization */ -int at91ether_probe(struct net_device *dev) +static int at91ether_probe(struct net_device *dev) { AT91PS_EMAC regs = (AT91PS_EMAC) AT91C_VA_BASE_EMAC; unsigned int phyid1, phyid2; @@ -761,17 +833,22 @@ AT91_CfgPIO_EMAC_MII(); #endif + AT91_CfgPIO_EMAC_PHY(); /* Configure PHY interrupt */ AT91_SYS->PMC_PCER = 1 << AT91C_ID_EMAC; /* Enable Peripheral clock */ /* Read the PHY ID registers */ enable_mdi(regs); - read_phy(regs, MII_PHYSID1, &phyid1); - read_phy(regs, MII_PHYSID2, &phyid2); + read_phy(regs, 0, MII_PHYSID1, &phyid1); + read_phy(regs, 0, MII_PHYSID2, &phyid2); disable_mdi(regs); /* Davicom 9161: PHY_ID1 = 0x181 PHY_ID2 = B881 */ if (((phyid1 << 16) | (phyid2 & 0xfff0)) == MII_DM9161_ID) { - detected = at91ether_setup(dev); + detected = at91ether_setup(dev, MII_DM9161_ID); + } + /* Intel LXT971A: PHY_ID1 = 0x13 PHY_ID2 = 78E0 */ + else if (((phyid1 << 16) | (phyid2 & 0xfff0)) == MII_LXT971A_ID) { + detected = at91ether_setup(dev, MII_LXT971A_ID); } AT91_SYS->PMC_PCDR = 1 << AT91C_ID_EMAC; /* Disable Peripheral clock */ Index: drivers/at91/net/at91_ether.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/at91/net/at91_ether.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/at91/net/at91_ether.h 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/at91/net/at91_ether.h 4 Aug 2004 01:28:37 -0000 1.2 @@ -22,9 +22,17 @@ #define MII_DM9161_ID 0x0181b880 /* Davicom specific registers */ +#define MII_DSCR_REG 16 #define MII_DSCSR_REG 17 #define MII_DSINTR_REG 21 +/* Intel LXT971A PHY */ +#define MII_LXT971A_ID 0x001378E0 + +/* Intel specific registers */ +#define MII_ISINTE_REG 18 +#define MII_ISINTS_REG 19 + /* ........................................................................ */ #define MAX_RBUFF_SZ 0x600 /* 1518 rounded up */ @@ -55,7 +63,9 @@ struct mii_if_info mii; /* ethtool support */ /* PHY */ + unsigned long phy_type; /* type of PHY (PHY_ID) */ spinlock_t lock; /* lock for MDI interface */ + short phy_media; /* media interface type */ /* Transmit */ struct sk_buff *skb; /* holds skb until xmit interrupt completes */ Index: drivers/at91/rtc/at91_rtc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/at91/rtc/at91_rtc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/at91/rtc/at91_rtc.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/at91/rtc/at91_rtc.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -94,7 +94,7 @@ | BIN2BCD(tval->tm_min) << 8 | BIN2BCD(tval->tm_hour) << 16; - AT91_SYS->RTC_CALR = BIN2BCD(tval->tm_year / 100) /* century */ + AT91_SYS->RTC_CALR = BIN2BCD((tval->tm_year + 1900) / 100) /* century */ | BIN2BCD(tval->tm_year % 100) << 8 /* year */ | BIN2BCD(tval->tm_mon + 1) << 16 /* tm_mon starts at zero */ | BIN2BCD(tval->tm_wday + 1) << 21 /* day of the week [0-6], Sunday=0 */ @@ -180,7 +180,7 @@ return (rtc_irq_data) ? 0 : POLLIN | POLLRDNORM; } -ssize_t at91_rtc_read(struct file * file, char *buf, size_t count, loff_t * ppos) +static ssize_t at91_rtc_read(struct file * file, char *buf, size_t count, loff_t * ppos) { DECLARE_WAITQUEUE(wait, current); unsigned long data; @@ -222,7 +222,6 @@ out: set_current_state(TASK_RUNNING); remove_wait_queue(&at91_rtc_wait, &wait); - remove_wait_queue(&at91_rtc_update, &wait); return retval; } @@ -262,6 +261,7 @@ rtc_irq_data = 0; break; case RTC_ALM_READ: /* read alarm */ + memset(&tm, 0, sizeof(struct rtc_time)); at91_rtc_decodetime(&(AT91_SYS->RTC_TIMALR), &(AT91_SYS->RTC_CALALR), &tm); tm.tm_yday = compute_yday(tm.tm_year, tm.tm_mon, tm.tm_mday); tm.tm_year = at91_alarm_year - 1900; @@ -290,6 +290,7 @@ } break; case RTC_RD_TIME: /* read time */ + memset(&tm, 0, sizeof(struct rtc_time)); at91_rtc_decodetime(&(AT91_SYS->RTC_TIMR), &(AT91_SYS->RTC_CALR), &tm); tm.tm_yday = compute_yday(tm.tm_year, tm.tm_mon, tm.tm_mday); tm.tm_year = tm.tm_year - 1900; Index: drivers/at91/serial/at91_serial.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/at91/serial/at91_serial.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/at91/serial/at91_serial.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/at91/serial/at91_serial.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -34,23 +34,9 @@ #include #include +#include #include -/* - * This is a temporary structure for registering these - * functions; it is intended to be discarded after boot. - */ -struct uart_port; -struct uart_info; -struct at91_port_fns { - void (*set_mctrl)(struct uart_port *, u_int); - u_int (*get_mctrl)(struct uart_port *); - void (*enable_ms)(struct uart_port *); - void (*pm)(struct uart_port *, u_int, u_int); - int (*set_wake)(struct uart_port *, u_int); - int (*open)(struct uart_port *, struct uart_info *); - void (*close)(struct uart_port *, struct uart_info *); -}; #if defined(CONFIG_SERIAL_AT91_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) #define SUPPORT_SYSRQ @@ -76,14 +62,26 @@ #define UART_PUT_CHAR(port,v) ((AT91PS_USART)(port)->membase)->US_THR = v #define UART_GET_BRGR(port) ((AT91PS_USART)(port)->membase)->US_BRGR #define UART_PUT_BRGR(port,v) ((AT91PS_USART)(port)->membase)->US_BRGR = v +#define UART_PUT_RTOR(port,v) ((AT91PS_USART)(port)->membase)->US_RTOR = v // #define UART_GET_CR(port) ((AT91PS_USART)(port)->membase)->US_CR // is write-only + /* PDC registers */ +#define UART_PUT_PTCR(port,v) ((AT91PS_USART)(port)->membase)->US_PTCR = v +#define UART_PUT_RPR(port,v) ((AT91PS_USART)(port)->membase)->US_RPR = v +#define UART_PUT_RCR(port,v) ((AT91PS_USART)(port)->membase)->US_RCR = v +#define UART_GET_RCR(port) ((AT91PS_USART)(port)->membase)->US_RCR +#define UART_PUT_RNPR(port,v) ((AT91PS_USART)(port)->membase)->US_RNPR = v +#define UART_PUT_RNCR(port,v) ((AT91PS_USART)(port)->membase)->US_RNCR = v + static struct tty_driver normal, callout; static struct tty_struct *at91_table[AT91C_NR_UART]; static struct termios *at91_termios[AT91C_NR_UART], *at91_termios_locked[AT91C_NR_UART]; -static int (*at91_open)(struct uart_port *, struct uart_info *); -static void (*at91_close)(struct uart_port *, struct uart_info *); + +const int at91_serialmap[AT91C_NR_UART] = AT91C_UART_MAP; + +static int (*at91_open)(struct uart_port *); +static void (*at91_close)(struct uart_port *); #ifdef SUPPORT_SYSRQ static struct console at91_console; @@ -149,16 +147,14 @@ /* * Start transmitting. */ -static void at91_start_tx(struct uart_port *port, u_int nonempty, u_int from_tty) +static void at91_start_tx(struct uart_port *port, u_int from_tty) { - if (nonempty) { - unsigned long flags; + unsigned long flags; - local_irq_save(flags); - port->read_status_mask |= AT91C_US_TXRDY; - UART_PUT_IER(port, AT91C_US_TXRDY); - local_irq_restore(flags); - } + local_irq_save(flags); + port->read_status_mask |= AT91C_US_TXRDY; + UART_PUT_IER(port, AT91C_US_TXRDY); + local_irq_restore(flags); } /* @@ -191,10 +187,10 @@ /* * Characters received (called from interrupt handler) */ -static void at91_rx_chars(struct uart_info *info, struct pt_regs *regs) +static void at91_rx_chars(struct uart_port *port, struct pt_regs *regs) { + struct uart_info *info = port->info; struct tty_struct *tty = info->tty; - struct uart_port *port = info->port; unsigned int status, ch, flg, ignored = 0; status = UART_GET_CSR(port); @@ -214,7 +210,7 @@ if (status & (AT91C_US_PARE | AT91C_US_FRAME | AT91C_US_OVRE)) goto handle_error; - if (uart_handle_sysrq_char(info, ch, regs)) + if (uart_handle_sysrq_char(port, ch, regs)) goto ignore_char; error_return: @@ -266,7 +262,7 @@ flg = TTY_OVERRUN; } #ifdef SUPPORT_SYSRQ - info->sysrq = 0; + port->sysrq = 0; #endif goto error_return; } @@ -274,9 +270,9 @@ /* * Transmit characters (called from interrupt handler) */ -static void at91_tx_chars(struct uart_info *info) +static void at91_tx_chars(struct uart_port *port) { - struct uart_port *port = info->port; + struct circ_buf *xmit = &port->info->xmit; if (port->x_char) { UART_PUT_CHAR(port, port->x_char); @@ -284,26 +280,24 @@ port->x_char = 0; return; } - if (info->xmit.head == info->xmit.tail - || info->tty->stopped - || info->tty->hw_stopped) { - at91_stop_tx(info->port, 0); + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { + at91_stop_tx(port, 0); return; } while (UART_GET_CSR(port) & AT91C_US_TXRDY) { - UART_PUT_CHAR(port, info->xmit.buf[info->xmit.tail]); - info->xmit.tail = (info->xmit.tail + 1) & (UART_XMIT_SIZE - 1); + UART_PUT_CHAR(port, xmit->buf[xmit->tail]); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; - if (info->xmit.head == info->xmit.tail) + if (uart_circ_empty(xmit)) break; } - if (CIRC_CNT(info->xmit.head, info->xmit.tail, UART_XMIT_SIZE) < WAKEUP_CHARS) - uart_event(info, EVT_WRITE_WAKEUP); + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(port); - if (info->xmit.head == info->xmit.tail) - at91_stop_tx(info->port, 0); + if (uart_circ_empty(xmit)) + at91_stop_tx(port, 0); } /* @@ -311,8 +305,7 @@ */ static void at91_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct uart_info *info = dev_id; - struct uart_port *port = info->port; + struct uart_port *port = dev_id; unsigned int status, pending, pass_counter = 0; status = UART_GET_CSR(port); @@ -320,15 +313,15 @@ if (pending) { do { if (pending & AT91C_US_RXRDY) - at91_rx_chars(info, regs); + at91_rx_chars(port, regs); /* Clear the relevent break bits */ if (pending & AT91C_US_RXBRK) { UART_PUT_CR(port, AT91C_US_RSTSTA); port->icount.brk++; #ifdef SUPPORT_SYSRQ - if (port->line == at91_console.index && !info->sysrq) { - info->sysrq = jiffies + HZ*5; + if (port->line == at91_console.index && !port->sysrq) { + port->sysrq = jiffies + HZ*5; } #endif } @@ -338,17 +331,17 @@ if (pending & AT91C_US_DSRIC) port->icount.dsr++; if (pending & AT91C_US_DCDIC) { port->icount.dcd++; - uart_handle_dcd_change(info, status & AT91C_US_DCD); + uart_handle_dcd_change(port, status & AT91C_US_DCD); } if (pending & AT91C_US_CTSIC) { port->icount.cts++; - uart_handle_cts_change(info, status & AT91C_US_CTS); + uart_handle_cts_change(port, status & AT91C_US_CTS); } if (pending & (AT91C_US_RIIC | AT91C_US_DSRIC | AT91C_US_DCDIC | AT91C_US_CTSIC)) - wake_up_interruptible(&info->delta_msr_wait); + wake_up_interruptible(&port->info->delta_msr_wait); if (pending & AT91C_US_TXRDY) - at91_tx_chars(info); + at91_tx_chars(port); if (pass_counter++ > AT91_ISR_PASS_LIMIT) break; @@ -361,14 +354,14 @@ /* * Perform initialization and enable port for reception */ -static int at91_startup(struct uart_port *port, struct uart_info *info) +static int at91_startup(struct uart_port *port) { int retval; /* * Allocate the IRQ */ - retval = request_irq(port->irq, at91_interrupt, SA_SHIRQ, "at91_serial", info); + retval = request_irq(port->irq, at91_interrupt, SA_SHIRQ, "at91_serial", port); if (retval) { printk("at91_serial: at91_startup - Can't get irq\n"); return retval; @@ -378,9 +371,9 @@ * control line interrupts) */ if (at91_open) { - retval = at91_open(port, info); + retval = at91_open(port); if (retval) { - free_irq(port->irq, info); + free_irq(port->irq, port); return retval; } } @@ -403,19 +396,19 @@ /* * Disable the port */ -static void at91_shutdown(struct uart_port *port, struct uart_info *info) +static void at91_shutdown(struct uart_port *port) { /* * Free the interrupt */ - free_irq(port->irq, info); + free_irq(port->irq, port); /* * If there is a specific "close" function (to unregister * control line interrupts) */ if (at91_close) - at91_close(port, info); + at91_close(port); /* * Disable all interrupts, port and break condition. @@ -428,6 +421,8 @@ AT91_SYS->PMC_PCDR = 1 << port->irq; } +static struct uart_ops at91_pops; /* forward declaration */ + /* * Change the port parameters */ @@ -461,7 +456,13 @@ /* parity */ if (cflag & PARENB) { - if (cflag & PARODD) + if (cflag & CMSPAR) { /* Mark or Space parity */ + if (cflag & PARODD) + mode |= AT91C_US_PAR_MARK; + else + mode |= AT91C_US_PAR_SPACE; + } + else if (cflag & PARODD) mode |= AT91C_US_PAR_ODD; else mode |= AT91C_US_PAR_EVEN; @@ -512,6 +513,10 @@ /* restore interrupts */ UART_PUT_IER(port, imr); + + /* CTS flow-control and modem-status interrupts */ + if (UART_ENABLE_MS(port, cflag)) + at91_pops.enable_ms(port); } /* @@ -597,7 +602,26 @@ static struct uart_port at91_ports[AT91C_NR_UART]; -void __init at91_register_uart_fns(struct at91_port_fns *fns) +void __init at91_init_ports(void) +{ + static int first = 1; + int i; + + if (!first) + return; + first = 0; + + for (i = 0; i < AT91C_NR_UART; i++) { + at91_ports[i].iotype = SERIAL_IO_MEM; + at91_ports[i].flags = ASYNC_BOOT_AUTOCONF; + at91_ports[i].uartclk = AT91C_MASTER_CLOCK; + at91_ports[i].ops = &at91_pops; + at91_ports[i].fifosize = 1; + at91_ports[i].line = i; + } +} + +void __init at91_register_uart_fns(struct at91rm9200_port_fns *fns) { if (fns->enable_ms) at91_pops.enable_ms = fns->enable_ms; @@ -621,12 +645,6 @@ return; } - at91_ports[idx].iotype = SERIAL_IO_MEM; - at91_ports[idx].flags = ASYNC_BOOT_AUTOCONF; - at91_ports[idx].uartclk = AT91C_MASTER_CLOCK; - at91_ports[idx].ops = &at91_pops; - at91_ports[idx].fifosize = 0; - switch (port) { case 0: at91_ports[idx].membase = (void *) AT91C_VA_BASE_US0; @@ -665,10 +683,6 @@ #ifdef CONFIG_SERIAL_AT91_CONSOLE -#ifndef CONFIG_AT91_DEFAULT_BAUDRATE -#define CONFIG_AT91_DEFAULT_BAUDRATE 115200 -#endif - /* * Interrupts are disabled on entering */ @@ -720,9 +734,11 @@ */ static void __init at91_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits) { - unsigned int cr, mr, quot; + unsigned int mr, quot; // TODO: CR is a write-only register +// unsigned int cr; +// // cr = UART_GET_CR(port) & (AT91C_US_RXEN | AT91C_US_TXEN); // if (cr == (AT91C_US_RXEN | AT91C_US_TXEN)) { // /* ok, the port was enabled */ @@ -749,7 +765,7 @@ static int __init at91_console_setup(struct console *co, char *options) { struct uart_port *port; - int baud = CONFIG_AT91_DEFAULT_BAUDRATE; + int baud = AT91C_CONSOLE_DEFAULT_BAUDRATE; int bits = 8; int parity = 'n'; int flow = 'n'; @@ -785,6 +801,7 @@ void __init at91_console_init(void) { + at91_init_ports(); register_console(&at91_console); } @@ -810,17 +827,36 @@ termios_locked: at91_termios_locked, minor: MINOR_START, nr: AT91C_NR_UART, - port: at91_ports, cons: AT91_CONSOLE_DEVICE, }; static int __init at91_serial_init(void) { - return uart_register_driver(&at91_reg); + int ret, i; + + at91_init_ports(); + + ret = uart_register_driver(&at91_reg); + if (ret) + return ret; + + for (i = 0; i < AT91C_NR_UART; i++) { + if (at91_serialmap[i] >= 0) + uart_add_one_port(&at91_reg, &at91_ports[i]); + } + + return 0; } static void __exit at91_serial_exit(void) { + int i; + + for (i = 0; i < AT91C_NR_UART; i++) { + if (at91_serialmap[i] >= 0) + uart_remove_one_port(&at91_reg, &at91_ports[i]); + } + uart_unregister_driver(&at91_reg); } Index: drivers/at91/spi/at91_spi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/at91/spi/at91_spi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/at91/spi/at91_spi.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/at91/spi/at91_spi.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -30,7 +30,7 @@ DECLARE_COMPLETION(transfer_complete); /* SPI controller device */ -AT91PS_SPI controller = (AT91PS_SPI) AT91C_VA_BASE_SPI; +static AT91PS_SPI controller = (AT91PS_SPI) AT91C_VA_BASE_SPI; /* ......................................................................... */ @@ -171,7 +171,7 @@ /* * Handle interrupts from the SPI controller. */ -void spi_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static void spi_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned int status; struct spi_local *device = (struct spi_local *) &spi_dev[current_device]; Index: drivers/at91/spi/at91_spidev.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/at91/spi/at91_spidev.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/at91/spi/at91_spidev.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/at91/spi/at91_spidev.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -112,7 +112,7 @@ return res; } -int spidev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static int spidev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int spi_device = MINOR(inode->i_rdev); @@ -131,7 +131,7 @@ /* * Open the SPI device */ -int spidev_open(struct inode *inode, struct file *file) +static int spidev_open(struct inode *inode, struct file *file) { unsigned int spi_device = MINOR(inode->i_rdev); @@ -205,7 +205,7 @@ /* * Remove the SPI /dev interface driver */ -static void at91_spidev_exit(void) +static void __exit at91_spidev_exit(void) { #ifdef CONFIG_DEVFS_FS devfs_unregister(devfs_handle); Index: drivers/at91/usb/at91_usb-ohci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/at91/usb/at91_usb-ohci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/at91/usb/at91_usb-ohci.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/at91/usb/at91_usb-ohci.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -46,6 +46,10 @@ return -EIO; } + /* Enable PLLB */ + AT91_SYS->CKGR_PLLBR = AT91_PLLB_INIT; + while ((AT91_SYS->PMC_SR & 4) == 0); + /* Now, enable the USB clock */ AT91_SYS->PMC_SCER = AT91C_PMC_UHP; /* enable system clock */ AT91_SYS->PMC_PCER = 1 << AT91C_ID_UHP; /* enable peripheral clock */ Index: drivers/at91/watchdog/at91_wdt.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/at91/watchdog/at91_wdt.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/at91/watchdog/at91_wdt.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/at91/watchdog/at91_wdt.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -27,7 +27,7 @@ /* * Disable the watchdog. */ -void at91_wdt_stop(void) +static void at91_wdt_stop(void) { AT91_SYS->ST_WDMR = AT91C_ST_EXTEN; } @@ -35,7 +35,7 @@ /* * Enable and reset the watchdog. */ -void at91_wdt_start(void) +static void at91_wdt_start(void) { AT91_SYS->ST_WDMR = AT91C_ST_EXTEN | AT91C_ST_RSTEN | (((65536 * at91wdt_time) >> 8) & AT91C_ST_WDV); AT91_SYS->ST_CR = AT91C_ST_WDRST; Index: drivers/atm/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/atm/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/atm/Config.in 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/atm/Config.in 4 Aug 2004 01:28:37 -0000 1.2 @@ -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 Index: drivers/atm/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/atm/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/atm/Makefile 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/atm/Makefile 4 Aug 2004 01:28:37 -0000 1.2 @@ -52,10 +52,12 @@ CONFIG_ATM_FORE200E_SBA_FW := sba200e_ecd.bin2 endif endif - obj-$(CONFIG_ATM_FORE200E) += fore_200e.o -EXTRA_CFLAGS=-g +obj-$(CONFIG_ATM_HE) += he.o +ifeq ($(CONFIG_ATM_HE_USE_SUNI),y) + obj-$(CONFIG_ATM_HE) += suni.o +endif list-multi := fore_200e.o fore_200e-objs := fore200e.o $(FORE200E_FW_OBJS) Index: drivers/atm/ambassador.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/atm/ambassador.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/atm/ambassador.c 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/atm/ambassador.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -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) Index: drivers/atm/atmdev_init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/atm/atmdev_init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/atm/atmdev_init.c 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/atm/atmdev_init.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -10,9 +10,6 @@ #ifdef CONFIG_ATM_ZATM extern int zatm_detect(void); #endif -#ifdef CONFIG_ATM_NICSTAR -extern int nicstar_detect(void); -#endif #ifdef CONFIG_ATM_AMBASSADOR extern int amb_detect(void); #endif @@ -41,9 +38,6 @@ #ifdef CONFIG_ATM_ZATM devs += zatm_detect(); #endif -#ifdef CONFIG_ATM_NICSTAR - devs += nicstar_detect(); -#endif #ifdef CONFIG_ATM_AMBASSADOR devs += amb_detect(); #endif Index: drivers/atm/atmtcp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/atm/atmtcp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/atm/atmtcp.c 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/atm/atmtcp.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -155,6 +155,7 @@ { struct atm_cirange ci; struct atm_vcc *vcc; + struct sock *s; if (cmd != ATM_SETCIRANGE) return -ENOIOCTLCMD; if (copy_from_user(&ci,(void *) arg,sizeof(ci))) return -EFAULT; @@ -162,9 +163,18 @@ 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; - for (vcc = dev->vccs; vcc; vcc = vcc->next) + read_lock(&vcc_sklist_lock); + for (s = vcc_sklist; s; s = s->next) { + vcc = s->protinfo.af_atm; + if (vcc->dev != dev) + continue; if ((vcc->vpi >> ci.vpi_bits) || - (vcc->vci >> ci.vci_bits)) return -EBUSY; + (vcc->vci >> ci.vci_bits)) { + read_unlock(&vcc_sklist_lock); + return -EBUSY; + } + } + read_unlock(&vcc_sklist_lock); dev->ci_range = ci; return 0; } @@ -229,6 +239,7 @@ { struct atm_dev *atmtcp_dev; struct atmtcp_dev_data *dev_data; + struct sock *s; struct atm_vcc *walk; atmtcp_dev = (struct atm_dev *) vcc->dev_data; @@ -239,8 +250,14 @@ kfree(dev_data); shutdown_atm_dev(atmtcp_dev); vcc->dev_data = NULL; - for (walk = atmtcp_dev->vccs; walk; walk = walk->next) + read_lock(&vcc_sklist_lock); + for (s = vcc_sklist; s; s = s->next) { + walk = s->protinfo.af_atm; + if (walk->dev != atmtcp_dev) + continue; wake_up(&walk->sleep); + } + read_unlock(&vcc_sklist_lock); } @@ -248,7 +265,8 @@ { struct atm_dev *dev; struct atmtcp_hdr *hdr; - struct atm_vcc *out_vcc; + struct sock *s; + struct atm_vcc *out_vcc = NULL; struct sk_buff *new_skb; int result = 0; @@ -260,11 +278,17 @@ (struct atmtcp_control *) skb->data); goto done; } - for (out_vcc = dev->vccs; out_vcc; out_vcc = out_vcc->next) + read_lock(&vcc_sklist_lock); + for (s = vcc_sklist; s; s = s->next) { + out_vcc = s->protinfo.af_atm; + if (out_vcc->dev != dev) + continue; if (out_vcc->vpi == ntohs(hdr->vpi) && out_vcc->vci == ntohs(hdr->vci) && out_vcc->qos.rxtp.traffic_class != ATM_NONE) break; + } + read_unlock(&vcc_sklist_lock); if (!out_vcc) { atomic_inc(&vcc->stats->tx_err); goto done; @@ -293,13 +317,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 +333,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 +375,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_put(dev); + return -EMEDIUMTYPE; + } if (PRIV(dev)->vcc) return -EBUSY; } else { @@ -368,7 +390,8 @@ if (error) return error; } PRIV(dev)->vcc = vcc; - bind_vcc(vcc,&atmtcp_control_dev); + vcc->dev = &atmtcp_control_dev; + vcc_insert_socket(vcc->sk); set_bit(ATM_VF_META,&vcc->flags); set_bit(ATM_VF_READY,&vcc->flags); vcc->dev_data = dev; @@ -389,14 +412,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_put(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_put(dev); shutdown_atm_dev(dev); return 0; } Index: drivers/atm/eni.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/atm/eni.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/atm/eni.c 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/atm/eni.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -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) { + struct sock *s; struct atm_vcc *walk; + read_lock(&vcc_sklist_lock); if (*vpi == ATM_VPI_ANY) *vpi = 0; if (*vci == ATM_VCI_ANY) { for (*vci = ATM_NOT_RSV_VCI; *vci < NR_VCI; (*vci)++) { @@ -1891,28 +1898,47 @@ ENI_DEV(vcc->dev)->rx_map[*vci]) continue; if (vcc->qos.txtp.traffic_class != ATM_NONE) { - for (walk = vcc->dev->vccs; walk; - walk = walk->next) + for (s = vcc_sklist; s; s = s->next) { + walk = s->protinfo.af_atm; + if (walk->dev != vcc->dev) + continue; if (test_bit(ATM_VF_ADDR,&walk->flags) && walk->vci == *vci && walk->qos.txtp.traffic_class != ATM_NONE) break; - if (walk) continue; + } + if (s) continue; } break; } + read_unlock(&vcc_sklist_lock); return *vci == NR_VCI ? -EADDRINUSE : 0; } - if (*vci == ATM_VCI_UNSPEC) return 0; + if (*vci == ATM_VCI_UNSPEC) { + read_unlock(&vcc_sklist_lock); + return 0; + } if (vcc->qos.rxtp.traffic_class != ATM_NONE && - ENI_DEV(vcc->dev)->rx_map[*vci]) + ENI_DEV(vcc->dev)->rx_map[*vci]) { + read_unlock(&vcc_sklist_lock); return -EADDRINUSE; - if (vcc->qos.txtp.traffic_class == ATM_NONE) return 0; - for (walk = vcc->dev->vccs; walk; walk = walk->next) + } + if (vcc->qos.txtp.traffic_class == ATM_NONE) { + read_unlock(&vcc_sklist_lock); + return 0; + } + for (s = vcc_sklist; s; s = s->next) { + walk = s->protinfo.af_atm; + if (walk->dev != vcc->dev) + continue; 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) { + read_unlock(&vcc_sklist_lock); return -EADDRINUSE; + } + } + read_unlock(&vcc_sklist_lock); return 0; } @@ -2120,6 +2146,7 @@ static int eni_proc_read(struct atm_dev *dev,loff_t *pos,char *page) { + struct sock *s; static const char *signal[] = { "LOST","unknown","okay" }; struct eni_dev *eni_dev = ENI_DEV(dev); struct atm_vcc *vcc; @@ -2192,10 +2219,15 @@ return sprintf(page,"%10sbacklog %u packets\n","", skb_queue_len(&tx->backlog)); } - for (vcc = dev->vccs; vcc; vcc = vcc->next) { - struct eni_vcc *eni_vcc = ENI_VCC(vcc); + read_lock(&vcc_sklist_lock); + for (s = vcc_sklist; s; s = s->next) { + struct eni_vcc *eni_vcc; int length; + vcc = s->protinfo.af_atm; + if (vcc->dev != dev) + continue; + eni_vcc = ENI_VCC(vcc); if (--left) continue; length = sprintf(page,"vcc %4d: ",vcc->vci); if (eni_vcc->rx) { @@ -2210,8 +2242,10 @@ length += sprintf(page+length,"tx[%d], txing %d bytes", eni_vcc->tx->index,eni_vcc->txing); page[length] = '\n'; + read_unlock(&vcc_sklist_lock); return length+1; } + read_unlock(&vcc_sklist_lock); for (i = 0; i < eni_dev->free_len; i++) { struct eni_free *fe = eni_dev->free_list+i; unsigned long offset; Index: drivers/atm/fore200e.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/atm/fore200e.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/atm/fore200e.c 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/atm/fore200e.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -1,5 +1,5 @@ /* - $Id: fore200e.c,v 1.1 2004/07/22 19:49:28 joff Exp $ + $Id: fore200e.c,v 1.2 2004/08/04 01:28:37 joff Exp $ A FORE Systems 200E-series driver for ATM on Linux. Christophe Lizzi (lizzi@cnam.fr), October 1999-March 2000. @@ -1077,15 +1077,22 @@ static struct atm_vcc* fore200e_find_vcc(struct fore200e* fore200e, struct rpd* rpd) { + struct sock *s; struct atm_vcc* vcc; - for (vcc = fore200e->atm_dev->vccs; vcc; vcc = vcc->next) { - - if (vcc->vpi == rpd->atm_header.vpi && vcc->vci == rpd->atm_header.vci) - break; + read_lock(&vcc_sklist_lock); + for(s = vcc_sklist; s; s = s->next) { + vcc = s->protinfo.af_atm; + if (vcc->dev != fore200e->atm_dev) + continue; + if (vcc->vpi == rpd->atm_header.vpi && vcc->vci == rpd->atm_header.vci) { + read_unlock(&vcc_sklist_lock); + return vcc; + } } - - return vcc; + read_unlock(&vcc_sklist_lock); + + return NULL; } @@ -1355,15 +1362,22 @@ fore200e_walk_vccs(struct atm_vcc *vcc, short *vpi, int *vci) { struct atm_vcc* walk; + struct sock *s; /* find a free VPI */ + + read_lock(&vcc_sklist_lock); + if (*vpi == ATM_VPI_ANY) { - for (*vpi = 0, walk = vcc->dev->vccs; walk; walk = walk->next) { + for (*vpi = 0, s = vcc_sklist; s; s = s->next) { + walk = s->protinfo.af_atm; + if (walk->dev != vcc->dev) + continue; if ((walk->vci == *vci) && (walk->vpi == *vpi)) { (*vpi)++; - walk = vcc->dev->vccs; + s = vcc_sklist; } } } @@ -1371,15 +1385,20 @@ /* find a free VCI */ if (*vci == ATM_VCI_ANY) { - for (*vci = ATM_NOT_RSV_VCI, walk = vcc->dev->vccs; walk; walk = walk->next) { + for (*vci = ATM_NOT_RSV_VCI, s = vcc_sklist; s; s = s->next) { + walk = s->protinfo.af_atm; + if (walk->dev != vcc->dev) + continue; if ((walk->vpi = *vpi) && (walk->vci == *vci)) { *vci = walk->vci + 1; - walk = vcc->dev->vccs; + s = vcc_sklist; } } } + read_unlock(&vcc_sklist_lock); + return 0; } @@ -2640,6 +2659,7 @@ static int fore200e_proc_read(struct atm_dev *dev,loff_t* pos,char* page) { + struct sock *s; struct fore200e* fore200e = FORE200E_DEV(dev); int len, left = *pos; @@ -2886,7 +2906,12 @@ len = sprintf(page,"\n" " VCCs:\n address\tVPI.VCI:AAL\t(min/max tx PDU size) (min/max rx PDU size)\n"); - for (vcc = fore200e->atm_dev->vccs; vcc; vcc = vcc->next) { + read_lock(&vcc_sklist_lock); + for (s = vcc_sklist; s; s = s->next) { + vcc = s->protinfo.af_atm; + + if (vcc->dev != fore200e->atm_dev) + continue; fore200e_vcc = FORE200E_VCC(vcc); @@ -2900,6 +2925,7 @@ fore200e_vcc->rx_max_pdu ); } + read_unlock(&vcc_sklist_lock); return len; } Index: drivers/atm/fore200e.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/atm/fore200e.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/atm/fore200e.h 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/atm/fore200e.h 4 Aug 2004 01:28:37 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: fore200e.h,v 1.1 2004/07/22 19:49:28 joff Exp $ */ +/* $Id: fore200e.h,v 1.2 2004/08/04 01:28:37 joff Exp $ */ #ifndef _FORE200E_H #define _FORE200E_H Index: drivers/atm/fore200e_mkfirm.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/atm/fore200e_mkfirm.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/atm/fore200e_mkfirm.c 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/atm/fore200e_mkfirm.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -1,5 +1,5 @@ /* - $Id: fore200e_mkfirm.c,v 1.1 2004/07/22 19:49:28 joff Exp $ + $Id: fore200e_mkfirm.c,v 1.2 2004/08/04 01:28:37 joff Exp $ mkfirm.c: generates a C readable file from a binary firmware image Index: drivers/atm/horizon.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/atm/horizon.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/atm/horizon.c 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/atm/horizon.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -359,8 +359,8 @@ static unsigned short debug = 0; static unsigned short vpi_bits = 0; -static unsigned short max_tx_size = 9000; -static unsigned short max_rx_size = 9000; +static int max_tx_size = 9000; +static int max_rx_size = 9000; static unsigned char pci_lat = 0; /********** access functions **********/ @@ -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; @@ -2916,11 +2919,11 @@ PRINTK (KERN_ERR, "vpi_bits has been limited to %hu", vpi_bits = HRZ_MAX_VPI); - if (max_tx_size > TX_AAL5_LIMIT) + if (max_tx_size < 0 || max_tx_size > TX_AAL5_LIMIT) PRINTK (KERN_NOTICE, "max_tx_size has been limited to %hu", max_tx_size = TX_AAL5_LIMIT); - if (max_rx_size > RX_AAL5_LIMIT) + if (max_rx_size < 0 || max_rx_size > RX_AAL5_LIMIT) PRINTK (KERN_NOTICE, "max_rx_size has been limited to %hu", max_rx_size = RX_AAL5_LIMIT); @@ -2935,8 +2938,8 @@ MODULE_LICENSE("GPL"); MODULE_PARM(debug, "h"); MODULE_PARM(vpi_bits, "h"); -MODULE_PARM(max_tx_size, "h"); -MODULE_PARM(max_rx_size, "h"); +MODULE_PARM(max_tx_size, "i"); +MODULE_PARM(max_rx_size, "i"); MODULE_PARM(pci_lat, "b"); MODULE_PARM_DESC(debug, "debug bitmap, see .h file"); MODULE_PARM_DESC(vpi_bits, "number of bits (0..4) to allocate to VPIs"); Index: drivers/atm/idt77252.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/atm/idt77252.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/atm/idt77252.c 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/atm/idt77252.c 4 Aug 2004 01:28:37 -0000 1.2 @@ -1,8 +1,8 @@ /******************************************************************* - * ident "$Id: idt77252.c,v 1.1 2004/07/22 19:49:28 joff Exp $" + * ident "$Id: idt77252.c,v 1.2 2004/08/04 01:28:37 joff Exp $" * * $Author: joff $ - * $Date: 2004/07/22 19:49:28 $ + * $Date: 2004/08/04 01:28:37 $ * * Copyright (c) 2000 ATecoM GmbH * @@ -30,7 +30,7 @@ * *******************************************************************/ static char const rcsid[] = -"$Id: idt77252.c,v 1.1 2004/07/22 19:49:28 joff Exp $"; +"$Id: idt77252.c,v 1.2 2004/08/04 01:28:37 joff Exp $"; #include @@ -665,8 +665,8 @@ skb_queue_head_init(&scq->transmit); skb_queue_head_init(&scq->pending); - TXPRINTK("idt77252: SCQ: base 0x%p, next 0x%p, last 0x%p, paddr %08x\n", - scq->base, scq->next, scq->last, scq->paddr); + TXPRINTK("idt77252: SCQ: base 0x%p, next 0x%p, last 0x%p, paddr %08llx\n", + scq->base, scq->next, scq->last, (unsigned long long)scq->paddr); return scq; } @@ -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,34 +2404,43 @@ static int idt77252_find_vcc(struct atm_vcc *vcc, short *vpi, int *vci) { + struct sock *s; struct atm_vcc *walk; + read_lock(&vcc_sklist_lock); if (*vpi == ATM_VPI_ANY) { *vpi = 0; - walk = vcc->dev->vccs; - while (walk) { + s = vcc_sklist; + while (s) { + walk = s->protinfo.af_atm; + if (walk->dev != vcc->dev) + continue; if ((walk->vci == *vci) && (walk->vpi == *vpi)) { (*vpi)++; - walk = vcc->dev->vccs; + s = vcc_sklist; continue; } - walk = walk->next; + s = s->next; } } if (*vci == ATM_VCI_ANY) { *vci = ATM_NOT_RSV_VCI; - walk = vcc->dev->vccs; - while (walk) { + s = vcc_sklist; + while (s) { + walk = s->protinfo.af_atm; + if (walk->dev != vcc->dev) + continue; if ((walk->vci == *vci) && (walk->vpi == *vpi)) { (*vci)++; - walk = vcc->dev->vccs; + s = vcc_sklist; continue; } - walk = walk->next; + s = s->next; } } + read_unlock(&vcc_sklist_lock); return 0; } Index: drivers/atm/idt77252.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/atm/idt77252.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/atm/idt77252.h 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/atm/idt77252.h 4 Aug 2004 01:28:37 -0000 1.2 @@ -1,8 +1,8 @@ /******************************************************************* - * ident "$Id: idt77252.h,v 1.1 2004/07/22 19:49:29 joff Exp $" + * ident "$Id: idt77252.h,v 1.2 2004/08/04 01:28:37 joff Exp $" * * $Author: joff $ - * $Date: 2004/07/22 19:49:29 $ + * $Date: 2004/08/04 01:28:37 $ * * Copyright (c) 2000 ATecoM GmbH * Index: drivers/atm/iphase.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/atm/iphase.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/atm/iphase.c 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/atm/iphase.c 4 Aug 2004 01:28:38 -0000 1.2 @@ -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 Index: drivers/atm/lanai.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/atm/lanai.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/atm/lanai.c 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/atm/lanai.c 4 Aug 2004 01:28:38 -0000 1.2 @@ -2842,7 +2842,6 @@ phy_get: NULL, feedback: NULL, change_qos: lanai_change_qos, - free_rx_skb: NULL, proc_read: lanai_proc_read }; Index: drivers/atm/nicstar.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/atm/nicstar.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/atm/nicstar.c 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/atm/nicstar.c 4 Aug 2004 01:28:38 -0000 1.2 @@ -112,9 +112,6 @@ /* Macros *********************************************************************/ -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -#define MIN(a,b) ((a) < (b) ? (a) : (b)) - #define CMD_BUSY(card) (readl((card)->membase + STAT) & NS_STAT_CMDBZ) #define NS_DELAY mdelay(1) @@ -214,8 +211,8 @@ static u32 ns_read_sram(ns_dev *card, u32 sram_address); static void ns_write_sram(ns_dev *card, u32 sram_address, u32 *value, int count); -static int __init ns_init_card(int i, struct pci_dev *pcidev); -static void __init ns_init_card_error(ns_dev *card, int error); +static int __devinit ns_init_card(int i, struct pci_dev *pcidev); +static void __devinit ns_init_card_error(ns_dev *card, int error); static scq_info *get_scq(int size, u32 scd); static void free_scq(scq_info *scq, struct atm_vcc *vcc); static void push_rxbufs(ns_dev *card, u32 type, u32 handle1, u32 addr1, @@ -276,198 +273,152 @@ /* Functions*******************************************************************/ -#ifdef MODULE - -int __init init_module(void) +static int __devinit nicstar_init_one(struct pci_dev *pcidev, + const struct pci_device_id *ent) { - int i; - unsigned error = 0; /* Initialized to remove compile warning */ - struct pci_dev *pcidev; - - XPRINTK("nicstar: init_module() called.\n"); - if(!pci_present()) - { - printk("nicstar: no PCI subsystem found.\n"); - return -EIO; - } + static int index = -1; + unsigned int error; - for(i = 0; i < NS_MAX_CARDS; i++) - cards[i] = NULL; + index++; + cards[index] = NULL; - pcidev = NULL; - for(i = 0; i < NS_MAX_CARDS; i++) - { - if ((pcidev = pci_find_device(PCI_VENDOR_ID_IDT, - PCI_DEVICE_ID_IDT_IDT77201, - pcidev)) == NULL) - break; - - error = ns_init_card(i, pcidev); - if (error) - cards[i--] = NULL; /* Try to find another card but don't increment index */ - } - - if (i == 0) - { - if (!error) - { - printk("nicstar: no cards found.\n"); - return -ENXIO; - } - else - return -EIO; + error = ns_init_card(index, pcidev); + if (error) { + cards[index--] = NULL; /* don't increment index */ + goto err_out; } - TXPRINTK("nicstar: TX debug enabled.\n"); - RXPRINTK("nicstar: RX debug enabled.\n"); - PRINTK("nicstar: General debug enabled.\n"); -#ifdef PHY_LOOPBACK - printk("nicstar: using PHY loopback.\n"); -#endif /* PHY_LOOPBACK */ - XPRINTK("nicstar: init_module() returned.\n"); - init_timer(&ns_timer); - ns_timer.expires = jiffies + NS_POLL_PERIOD; - ns_timer.data = 0UL; - ns_timer.function = ns_poll; - add_timer(&ns_timer); return 0; +err_out: + return -ENODEV; } -void cleanup_module(void) +static void __devexit nicstar_remove_one(struct pci_dev *pcidev) { int i, j; - unsigned short pci_command; - ns_dev *card; + ns_dev *card = pci_get_drvdata(pcidev); struct sk_buff *hb; struct sk_buff *iovb; struct sk_buff *lb; struct sk_buff *sb; - XPRINTK("nicstar: cleanup_module() called.\n"); - - if (MOD_IN_USE) - printk("nicstar: module in use, remove delayed.\n"); + i = card->index; - del_timer(&ns_timer); - - for (i = 0; i < NS_MAX_CARDS; i++) - { - if (cards[i] == NULL) - continue; - - card = cards[i]; + if (cards[i] == NULL) + return; - if (card->atmdev->phy && card->atmdev->phy->stop) - card->atmdev->phy->stop(card->atmdev); + if (card->atmdev->phy && card->atmdev->phy->stop) + card->atmdev->phy->stop(card->atmdev); - /* Stop everything */ - writel(0x00000000, card->membase + CFG); + /* Stop everything */ + writel(0x00000000, card->membase + CFG); - /* De-register device */ - atm_dev_deregister(card->atmdev); + /* De-register device */ + atm_dev_deregister(card->atmdev); - /* Disable memory mapping and busmastering */ - if (pci_read_config_word(card->pcidev, PCI_COMMAND, &pci_command) != 0) - { - printk("nicstar%d: can't read PCI_COMMAND.\n", i); - } - pci_command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); - if (pci_write_config_word(card->pcidev, PCI_COMMAND, pci_command) != 0) - { - printk("nicstar%d: can't write PCI_COMMAND.\n", i); - } - - /* Free up resources */ - j = 0; - PRINTK("nicstar%d: freeing %d huge buffers.\n", i, card->hbpool.count); - while ((hb = skb_dequeue(&card->hbpool.queue)) != NULL) - { - dev_kfree_skb_any(hb); - j++; - } - PRINTK("nicstar%d: %d huge buffers freed.\n", i, j); - j = 0; - PRINTK("nicstar%d: freeing %d iovec buffers.\n", i, card->iovpool.count); - while ((iovb = skb_dequeue(&card->iovpool.queue)) != NULL) - { - dev_kfree_skb_any(iovb); - j++; - } - PRINTK("nicstar%d: %d iovec buffers freed.\n", i, j); - while ((lb = skb_dequeue(&card->lbpool.queue)) != NULL) - dev_kfree_skb_any(lb); - while ((sb = skb_dequeue(&card->sbpool.queue)) != NULL) - dev_kfree_skb_any(sb); - free_scq(card->scq0, NULL); - for (j = 0; j < NS_FRSCD_NUM; j++) - { - if (card->scd2vc[j] != NULL) - free_scq(card->scd2vc[j]->scq, card->scd2vc[j]->tx_vcc); - } - kfree(card->rsq.org); - kfree(card->tsq.org); - free_irq(card->pcidev->irq, card); - iounmap((void *) card->membase); - kfree(card); - + /* Disable PCI device */ + pci_disable_device(pcidev); + + /* Free up resources */ + j = 0; + PRINTK("nicstar%d: freeing %d huge buffers.\n", i, card->hbpool.count); + while ((hb = skb_dequeue(&card->hbpool.queue)) != NULL) + { + dev_kfree_skb_any(hb); + j++; } - XPRINTK("nicstar: cleanup_module() returned.\n"); + PRINTK("nicstar%d: %d huge buffers freed.\n", i, j); + j = 0; + PRINTK("nicstar%d: freeing %d iovec buffers.\n", i, card->iovpool.count); + while ((iovb = skb_dequeue(&card->iovpool.queue)) != NULL) + { + dev_kfree_skb_any(iovb); + j++; + } + PRINTK("nicstar%d: %d iovec buffers freed.\n", i, j); + while ((lb = skb_dequeue(&card->lbpool.queue)) != NULL) + dev_kfree_skb_any(lb); + while ((sb = skb_dequeue(&card->sbpool.queue)) != NULL) + dev_kfree_skb_any(sb); + free_scq(card->scq0, NULL); + for (j = 0; j < NS_FRSCD_NUM; j++) + { + if (card->scd2vc[j] != NULL) + free_scq(card->scd2vc[j]->scq, card->scd2vc[j]->tx_vcc); + } + kfree(card->rsq.org); + kfree(card->tsq.org); + free_irq(card->pcidev->irq, card); + iounmap((void *) card->membase); + kfree(card); } -#else -int __init nicstar_detect(void) +static struct pci_device_id nicstar_pci_tbl[] __devinitdata = { - int i; - unsigned error = 0; /* Initialized to remove compile warning */ - struct pci_dev *pcidev; + {PCI_VENDOR_ID_IDT, PCI_DEVICE_ID_IDT_IDT77201, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0,} /* terminate list */ +}; +MODULE_DEVICE_TABLE(pci, nicstar_pci_tbl); - if(!pci_present()) - { - printk("nicstar: no PCI subsystem found.\n"); - return -EIO; - } - for(i = 0; i < NS_MAX_CARDS; i++) - cards[i] = NULL; - pcidev = NULL; - for(i = 0; i < NS_MAX_CARDS; i++) - { - if ((pcidev = pci_find_device(PCI_VENDOR_ID_IDT, - PCI_DEVICE_ID_IDT_IDT77201, - pcidev)) == NULL) - break; +static struct pci_driver nicstar_driver = { + .name = "nicstar", + .id_table = nicstar_pci_tbl, + .probe = nicstar_init_one, + .remove = __devexit_p(nicstar_remove_one), +}; - error = ns_init_card(i, pcidev); - if (error) - cards[i--] = NULL; /* Try to find another card but don't increment index */ - } - if (i == 0 && error) - return -EIO; +static int __init nicstar_init(void) +{ + unsigned error = 0; /* Initialized to remove compile warning */ + + XPRINTK("nicstar: nicstar_init() called.\n"); + + error = pci_module_init(&nicstar_driver); + TXPRINTK("nicstar: TX debug enabled.\n"); RXPRINTK("nicstar: RX debug enabled.\n"); PRINTK("nicstar: General debug enabled.\n"); #ifdef PHY_LOOPBACK printk("nicstar: using PHY loopback.\n"); #endif /* PHY_LOOPBACK */ - XPRINTK("nicstar: init_module() returned.\n"); + XPRINTK("nicstar: nicstar_init() returned.\n"); - init_timer(&ns_timer); - ns_timer.expires = jiffies + NS_POLL_PERIOD; - ns_timer.data = 0UL; - ns_timer.function = ns_poll; - add_timer(&ns_timer); - return i; + if (!error) { + init_timer(&ns_timer); + ns_timer.expires = jiffies + NS_POLL_PERIOD; + ns_timer.data = 0UL; + ns_timer.function = ns_poll; + add_timer(&ns_timer); + } + + return error; } -#endif /* MODULE */ + +static void __exit nicstar_cleanup(void) +{ + XPRINTK("nicstar: nicstar_cleanup() called.\n"); + + if (MOD_IN_USE) + printk("nicstar: module in use, remove delayed.\n"); + + del_timer(&ns_timer); + + pci_unregister_driver(&nicstar_driver); + + XPRINTK("nicstar: nicstar_cleanup() returned.\n"); +} + static u32 ns_read_sram(ns_dev *card, u32 sram_address) @@ -509,11 +460,10 @@ } -static int __init ns_init_card(int i, struct pci_dev *pcidev) +static int __devinit ns_init_card(int i, struct pci_dev *pcidev) { int j; struct ns_dev *card = NULL; - unsigned short pci_command; unsigned char pci_latency; unsigned error; u32 data; @@ -542,6 +492,8 @@ spin_lock_init(&card->int_lock); spin_lock_init(&card->res_lock); + pci_set_drvdata(pcidev, card); + card->index = i; card->atmdev = NULL; card->pcidev = pcidev; @@ -556,21 +508,7 @@ } PRINTK("nicstar%d: membase at 0x%x.\n", i, card->membase); - if (pci_read_config_word(pcidev, PCI_COMMAND, &pci_command) != 0) - { - printk("nicstar%d: can't read PCI_COMMAND.\n", i); - error = 4; - ns_init_card_error(card, error); - return error; - } - pci_command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); - if (pci_write_config_word(pcidev, PCI_COMMAND, pci_command) != 0) - { - printk("nicstar%d: can't write PCI_COMMAND.\n", i); - error = 5; - ns_init_card_error(card, error); - return error; - } + pci_set_master(pcidev); if (pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency) != 0) { @@ -941,9 +879,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], @@ -991,7 +934,7 @@ -static void __init ns_init_card_error(ns_dev *card, int error) +static void __devinit ns_init_card_error(ns_dev *card, int error) { if (error >= 17) { @@ -1040,6 +983,7 @@ } if (error >= 3) { + pci_disable_device(card->pcidev); kfree(card); } } @@ -1659,9 +1603,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 +1803,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 +2228,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 +2265,7 @@ return; } } - else /* ATM_SKB(iovb)->iovcnt >= 2 */ + else /* NS_SKB(iovb)->iovcnt >= 2 */ { if (skb->list != &card->lbpool.queue) { @@ -2330,7 +2274,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 +2298,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 +2306,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 +2328,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 +2405,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 +2443,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,10 +2466,10 @@ 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); + tocopy = min_t(int, remaining, iov->iov_len); memcpy(hb->tail, lb->data, tocopy); skb_put(hb, tocopy); iov++; @@ -3143,3 +3087,8 @@ spin_unlock_irqrestore(&card->res_lock, flags); return (unsigned char) data; } + + + +module_init(nicstar_init); +module_exit(nicstar_cleanup); Index: drivers/atm/nicstar.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/atm/nicstar.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/atm/nicstar.h 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/atm/nicstar.h 4 Aug 2004 01:28:38 -0000 1.2 @@ -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 */ Index: drivers/atm/nicstarmac.copyright =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/atm/nicstarmac.copyright,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/atm/nicstarmac.copyright 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/atm/nicstarmac.copyright 4 Aug 2004 01:28:38 -0000 1.2 @@ -13,7 +13,7 @@ * * Modified to work with the IDT7721 nicstar -- AAL5 (tested) only. * - * R. D. Rechenmacher , Aug. 6, 1997 $Revision: 1.1 $ $Date: 2004/07/22 19:49:28 $ + * R. D. Rechenmacher , Aug. 6, 1997 $Revision: 1.2 $ $Date: 2004/08/04 01:28:38 $ * * Linux driver for the IDT77201 NICStAR PCI ATM controller. * PHY component is expected to be 155 Mbps S/UNI-Lite or IDT 77155; Index: drivers/atm/zatm.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/atm/zatm.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/atm/zatm.c 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/atm/zatm.c 4 Aug 2004 01:28:38 -0000 1.2 @@ -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; Index: drivers/block/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/block/Config.in,v retrieving revision 1.1 retrieving revision 1.4 diff -u -r1.1 -r1.4 --- drivers/block/Config.in 22 Jul 2004 19:50:12 -0000 1.1 +++ drivers/block/Config.in 16 Jan 2009 20:34:27 -0000 1.4 @@ -4,6 +4,9 @@ mainmenu_option next_comment comment 'Block devices' +tristate 'SD card support' CONFIG_BLK_DEV_TS_SD +dep_mbool 'Prosoft 8000 SD card support' CONFIG_PROSOFT_SD $CONFIG_BLK_DEV_TS_SD + tristate 'Normal floppy disk support' CONFIG_BLK_DEV_FD if [ "$CONFIG_AMIGA" = "y" ]; then tristate 'Amiga floppy support' CONFIG_AMIGA_FLOPPY @@ -36,6 +39,7 @@ dep_tristate 'Compaq SMART2 support' CONFIG_BLK_CPQ_DA $CONFIG_PCI dep_tristate 'Compaq Smart Array 5xxx support' CONFIG_BLK_CPQ_CISS_DA $CONFIG_PCI dep_mbool ' SCSI tape drive support for Smart Array 5xxx' CONFIG_CISS_SCSI_TAPE $CONFIG_BLK_CPQ_CISS_DA $CONFIG_SCSI +dep_mbool ' Enable monitor thread' CONFIG_CISS_MONITOR_THREAD $CONFIG_BLK_CPQ_CISS_DA dep_tristate 'Mylex DAC960/DAC1100 PCI RAID Controller support' CONFIG_BLK_DEV_DAC960 $CONFIG_PCI dep_tristate 'Micro Memory MM5415 Battery Backed RAM support (EXPERIMENTAL)' CONFIG_BLK_DEV_UMEM $CONFIG_PCI $CONFIG_EXPERIMENTAL Index: drivers/block/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/block/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/block/Makefile 22 Jul 2004 19:50:11 -0000 1.1 +++ drivers/block/Makefile 3 Feb 2006 20:35:49 -0000 1.2 @@ -10,7 +10,7 @@ O_TARGET := block.o -export-objs := ll_rw_blk.o blkpg.o loop.o DAC960.o genhd.o acsi.o +export-objs := ll_rw_blk.o blkpg.o loop.o DAC960.o genhd.o acsi.o obj-y := ll_rw_blk.o blkpg.o genhd.o elevator.o @@ -31,9 +31,15 @@ obj-$(CONFIG_BLK_DEV_DAC960) += DAC960.o obj-$(CONFIG_BLK_DEV_UMEM) += umem.o obj-$(CONFIG_BLK_DEV_NBD) += nbd.o +obj-$(CONFIG_BLK_DEV_TS_SD) += ts_sd.o +obj-$(CONFIG_BLK_DEV_TS_SD) += sdcard.o +#sd.o subdir-$(CONFIG_PARIDE) += paride +#sd.o: ts_sd.o block.o +# $(LD) -r -o $@ sdcard.o ts_sd.o + ifeq ($(CONFIG_ARCH_ACORN),y) mod-subdirs += ../acorn/block subdir-y += ../acorn/block Index: drivers/block/cciss.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/block/cciss.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/block/cciss.c 22 Jul 2004 19:50:12 -0000 1.1 +++ drivers/block/cciss.c 4 Aug 2004 01:28:38 -0000 1.2 @@ -38,19 +38,20 @@ #include #include #include +#include #include #include #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.50)" +#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,4,50) /* 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_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"); +MODULE_AUTHOR("Hewlett-Packard Company"); +MODULE_DESCRIPTION("Driver for HP SA5xxx SA6xxx Controllers version 2.4.50"); +MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400 6i"); MODULE_LICENSE("GPL"); #include "cciss_cmd.h" @@ -73,6 +74,10 @@ 0x0E11, 0x409B, 0, 0, 0}, { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, 0x0E11, 0x409C, 0, 0, 0}, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, + 0x0E11, 0x409D, 0, 0, 0}, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, + 0x0E11, 0x4091, 0, 0, 0}, {0,} }; MODULE_DEVICE_TABLE(pci, cciss_pci_device_id); @@ -91,22 +96,43 @@ { 0x409A0E11, "Smart Array 641", &SA5_access}, { 0x409B0E11, "Smart Array 642", &SA5_access}, { 0x409C0E11, "Smart Array 6400", &SA5_access}, + { 0x409D0E11, "Smart Array 6400 EM", &SA5_access}, + { 0x40910E11, "Smart Array 6i", &SA5_access}, }; /* 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 #define READ_AHEAD 128 #define NR_CMDS 128 /* #commands that can be outstanding */ -#define MAX_CTLR 8 +#define MAX_CTLR 32 -#define CCISS_DMA_MASK 0xFFFFFFFF /* 32 bit DMA */ +/* No sense in giving up our preallocated major numbers */ +#if MAX_CTLR < 8 +#error"cciss.c: MAX_CTLR must be 8 or greater" +#endif -static ctlr_info_t *hba[MAX_CTLR]; +/* Originally cciss driver only supports 8 major number */ +#define MAX_CTLR_ORIG COMPAQ_CISS_MAJOR7 - COMPAQ_CISS_MAJOR + 1 + +#define CCISS_DMA_MASK 0xFFFFFFFFFFFFFFFF /* 64 bit DMA */ +#ifdef CONFIG_CISS_MONITOR_THREAD +static int cciss_monitor(void *ctlr); +static int start_monitor_thread(ctlr_info_t *h, unsigned char *cmd, + unsigned long count, int (*cciss_monitor)(void *), int *rc); +static u32 heartbeat_timer = 0; +#else +#define cciss_monitor(x) +#define kill_monitor_thead(x) +#endif + +static ctlr_info_t *hba[MAX_CTLR]; +static int map_major_to_ctlr[MAX_BLKDEV] = {0}; /* gets ctlr num from maj num */ static struct proc_dir_entry *proc_cciss; static void do_cciss_request(request_queue_t *q); @@ -184,7 +210,11 @@ "Current # commands on controller: %d\n" "Max Q depth since init: %d\n" "Max # commands on controller since init: %d\n" - "Max SG entries since init: %d\n\n", + "Max SG entries since init: %d\n" + MONITOR_PERIOD_PATTERN + MONITOR_DEADLINE_PATTERN + MONITOR_STATUS_PATTERN + "\n", h->devname, h->product_name, (unsigned long)h->board_id, @@ -192,7 +222,10 @@ (unsigned int)h->intr, h->num_luns, h->Qdepth, h->commands_outstanding, - h->maxQsinceinit, h->max_outstanding, h->maxSG); + h->maxQsinceinit, h->max_outstanding, h->maxSG, + MONITOR_PERIOD_VALUE(h), + MONITOR_DEADLINE_VALUE(h), + CTLR_STATUS(h)); pos += size; len += size; cciss_proc_tape_report(ctlr, buffer, &pos, &len); @@ -227,10 +260,8 @@ { unsigned char cmd[80]; int len; -#ifdef CONFIG_CISS_SCSI_TAPE ctlr_info_t *h = (ctlr_info_t *) data; int rc; -#endif if (count > sizeof(cmd)-1) return -EINVAL; @@ -240,6 +271,7 @@ len = strlen(cmd); if (cmd[len-1] == '\n') cmd[--len] = '\0'; + # ifdef CONFIG_CISS_SCSI_TAPE if (strcmp("engage scsi", cmd)==0) { rc = cciss_engage_scsi(h->ctlr); @@ -250,6 +282,10 @@ /* might be nice to have "disengage" too, but it's not safely possible. (only 1 module use count, lock issues.) */ # endif + + if (START_MONITOR_THREAD(h, cmd, count, cciss_monitor, &rc) == 0) + return rc; + return -EINVAL; } @@ -396,14 +432,14 @@ */ static int cciss_open(struct inode *inode, struct file *filep) { - int ctlr = MAJOR(inode->i_rdev) - MAJOR_NR; + int ctlr = map_major_to_ctlr[MAJOR(inode->i_rdev)]; int dsk = MINOR(inode->i_rdev) >> NWD_SHIFT; #ifdef CCISS_DEBUG printk(KERN_DEBUG "cciss_open %x (%x:%x)\n", inode->i_rdev, ctlr, dsk); #endif /* CCISS_DEBUG */ - if (ctlr > MAX_CTLR || hba[ctlr] == NULL) + if (ctlr > MAX_CTLR || hba[ctlr] == NULL || !CTLR_IS_ALIVE(hba[ctlr])) return -ENXIO; /* * Root is allowed to open raw volume zero even if its not configured @@ -437,7 +473,7 @@ */ static int cciss_release(struct inode *inode, struct file *filep) { - int ctlr = MAJOR(inode->i_rdev) - MAJOR_NR; + int ctlr = map_major_to_ctlr[MAJOR(inode->i_rdev)]; int dsk = MINOR(inode->i_rdev) >> NWD_SHIFT; #ifdef CCISS_DEBUG @@ -457,7 +493,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg) { - int ctlr = MAJOR(inode->i_rdev) - MAJOR_NR; + int ctlr = map_major_to_ctlr[MAJOR(inode->i_rdev)]; int dsk = MINOR(inode->i_rdev) >> NWD_SHIFT; #ifdef CCISS_DEBUG @@ -472,12 +508,8 @@ driver_geo.heads = hba[ctlr]->drv[dsk].heads; driver_geo.sectors = hba[ctlr]->drv[dsk].sectors; driver_geo.cylinders = hba[ctlr]->drv[dsk].cylinders; - } else { - driver_geo.heads = 0xff; - driver_geo.sectors = 0x3f; - driver_geo.cylinders = - hba[ctlr]->drv[dsk].nr_blocks / (0xff*0x3f); - } + } else + return -ENXIO; driver_geo.start= hba[ctlr]->hd[MINOR(inode->i_rdev)].start_sect; if (copy_to_user((void *) arg, &driver_geo, @@ -492,12 +524,8 @@ driver_geo.heads = hba[ctlr]->drv[dsk].heads; driver_geo.sectors = hba[ctlr]->drv[dsk].sectors; driver_geo.cylinders = hba[ctlr]->drv[dsk].cylinders; - } else { - driver_geo.heads = 0xff; - driver_geo.sectors = 0x3f; - driver_geo.cylinders = - hba[ctlr]->drv[dsk].nr_blocks / (0xff*0x3f); - } + } else + return -ENXIO; driver_geo.start= hba[ctlr]->hd[MINOR(inode->i_rdev)].start_sect; if (copy_to_user((void *) arg, &driver_geo, @@ -578,7 +606,7 @@ &(c->cfgtable->HostWrite.CoalIntCount)); writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL); - for(i=0;ivaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) break; @@ -586,8 +614,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 +658,7 @@ writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL); - for(i=0;ivaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) break; @@ -635,8 +666,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; } @@ -997,7 +1031,7 @@ int i; target = MINOR(dev) >> NWD_SHIFT; - ctlr = MAJOR(dev) - MAJOR_NR; + ctlr = map_major_to_ctlr[MAJOR(dev)]; gdev = &(hba[ctlr]->gendisk); spin_lock_irqsave(&io_request_lock, flags); @@ -1016,12 +1050,12 @@ for(i=max_p-1; i>=0; i--) { int minor = start+i; - invalidate_device(MKDEV(MAJOR_NR + ctlr, minor), 1); + invalidate_device(MKDEV(hba[ctlr]->major, minor), 1); gdev->part[minor].start_sect = 0; gdev->part[minor].nr_sects = 0; /* reset the blocksize so we can read the partition table */ - blksize_size[MAJOR_NR+ctlr][minor] = 1024; + blksize_size[hba[ctlr]->major][minor] = 1024; } /* setup partitions per disk */ grok_partitions(gdev, target, MAX_PART, @@ -1062,7 +1096,7 @@ for (i=max_p-1; i>=0; i--) { int minor = start+i; /* printk("invalidating( %d %d)\n", ctlr, minor); */ - invalidate_device(MKDEV(MAJOR_NR+ctlr, minor), 1); + invalidate_device(MKDEV(hba[ctlr]->major, minor), 1); /* so open will now fail */ h->sizes[minor] = 0; /* so it will no longer appear in /proc/partitions */ @@ -1097,7 +1131,8 @@ size_t size, unsigned int use_unit_num, unsigned int log_unit, - __u8 page_code ) + __u8 page_code, + __u8 cmdtype) { ctlr_info_t *h = hba[ctlr]; CommandList_struct *c; @@ -1121,6 +1156,9 @@ } c->Header.Tag.lower = c->busaddr; /* tag is phys addr of cmd */ /* Fill in Request block */ + c->Request.CDB[0] = cmd; + c->Request.Type.Type = cmdtype; + if (cmdtype == TYPE_CMD) { switch (cmd) { case CISS_INQUIRY: /* If the logical unit number is 0 then, this is going @@ -1140,11 +1178,9 @@ c->Request.CDB[2] = page_code; } c->Request.CDBLen = 6; - c->Request.Type.Type = TYPE_CMD; c->Request.Type.Attribute = ATTR_SIMPLE; c->Request.Type.Direction = XFER_READ; /* Read */ c->Request.Timeout = 0; /* Don't time out */ - c->Request.CDB[0] = CISS_INQUIRY; c->Request.CDB[4] = size & 0xFF; break; case CISS_REPORT_LOG: @@ -1153,11 +1189,9 @@ So we have nothing to write. */ c->Request.CDBLen = 12; - c->Request.Type.Type = TYPE_CMD; c->Request.Type.Attribute = ATTR_SIMPLE; c->Request.Type.Direction = XFER_READ; /* Read */ c->Request.Timeout = 0; /* Don't time out */ - c->Request.CDB[0] = CISS_REPORT_LOG; c->Request.CDB[6] = (size >> 24) & 0xFF; /* MSB */ c->Request.CDB[7] = (size >> 16) & 0xFF; c->Request.CDB[8] = (size >> 8) & 0xFF; @@ -1168,18 +1202,38 @@ hba[ctlr]->drv[log_unit].LunID; c->Header.LUN.LogDev.Mode = 1; c->Request.CDBLen = 10; - c->Request.Type.Type = TYPE_CMD; /* It is a command. */ c->Request.Type.Attribute = ATTR_SIMPLE; c->Request.Type.Direction = XFER_READ; /* Read */ c->Request.Timeout = 0; /* Don't time out */ - c->Request.CDB[0] = CCISS_READ_CAPACITY; break; default: printk(KERN_WARNING "cciss: Unknown Command 0x%x sent attempted\n", cmd); cmd_free(h, c, 1); return IO_ERROR; - }; + } + } else if (cmdtype == TYPE_MSG) { + switch (cmd) { + case 3: /* No-Op message */ + c->Request.CDBLen = 1; + c->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Type.Direction = XFER_WRITE; + c->Request.Timeout = 0; + c->Request.CDB[0] = cmd; + break; + default: + printk(KERN_WARNING + "cciss%d: unknown message type %d\n", + ctlr, cmd); + cmd_free(h, c, 1); + return IO_ERROR; + } + } else { + printk(KERN_WARNING + "cciss%d: unknown command type %d\n", ctlr, cmdtype); + cmd_free(h, c, 1); + return IO_ERROR; + } /* Fill in the scatter gather information */ if (size > 0) { @@ -1342,18 +1396,10 @@ } return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff, - sizeof(ReportLunData_struct), 0, 0, 0 ); + sizeof(ReportLunData_struct), 0, 0, 0, TYPE_CMD); 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" @@ -1449,7 +1495,7 @@ memset(size_buff, 0, sizeof(ReadCapdata_struct)); return_code = sendcmd_withirq(CCISS_READ_CAPACITY, ctlr, size_buff, sizeof(ReadCapdata_struct), 1, - logvol, 0 ); + logvol, 0, TYPE_CMD); if (return_code == IO_OK) { total_size = (0xff & (unsigned int) size_buff->total_size[0]) << 24; @@ -1480,7 +1526,7 @@ /* Execute the command to read the disk geometry */ memset(inq_buff, 0, sizeof(InquiryData_struct)); return_code = sendcmd_withirq(CISS_INQUIRY, ctlr, inq_buff, - sizeof(InquiryData_struct), 1, logvol ,0xC1 ); + sizeof(InquiryData_struct), 1, logvol ,0xC1, TYPE_CMD); if (return_code == IO_OK) { if (inq_buff->data_byte[8] == 0xFF) { printk(KERN_WARNING @@ -1538,12 +1584,12 @@ for(i=max_p-1; i>=0; i--) { int minor = start+i; - invalidate_device(MKDEV(MAJOR_NR + ctlr, minor), 1); + invalidate_device(MKDEV(hba[ctlr]->major, minor), 1); gdev->part[minor].start_sect = 0; gdev->part[minor].nr_sects = 0; /* reset the blocksize so we can read the partition table */ - blksize_size[MAJOR_NR+ctlr][minor] = block_size; + blksize_size[hba[ctlr]->major][minor] = block_size; hba[ctlr]->hardsizes[minor] = block_size; } @@ -1588,7 +1634,8 @@ } memset(size_buff, 0, sizeof(ReadCapdata_struct)); return_code = sendcmd_withirq(CCISS_READ_CAPACITY, ctlr, size_buff, - sizeof( ReadCapdata_struct), 1, logvol, 0 ); + sizeof( ReadCapdata_struct), 1, logvol, 0, + TYPE_CMD); if (return_code == IO_OK) { total_size = (0xff & (unsigned int)(size_buff->total_size[0])) << 24; @@ -1617,7 +1664,7 @@ /* Execute the command to read the disk geometry */ memset(inq_buff, 0, sizeof(InquiryData_struct)); return_code = sendcmd_withirq(CISS_INQUIRY, ctlr, inq_buff, - sizeof(InquiryData_struct), 1, logvol ,0xC1 ); + sizeof(InquiryData_struct), 1, logvol ,0xC1, TYPE_CMD); if (return_code == IO_OK) { if (inq_buff->data_byte[8] == 0xFF) { printk(KERN_WARNING "cciss: reading geometry failed, " @@ -1656,12 +1703,12 @@ for (i=max_p-1; i>=0; i--) { int minor = start+i; - invalidate_device(MKDEV(MAJOR_NR + ctlr, minor), 1); + invalidate_device(MKDEV(hba[ctlr]->major, minor), 1); gdev->part[minor].start_sect = 0; gdev->part[minor].nr_sects = 0; /* reset the blocksize so we can read the partition table */ - blksize_size[MAJOR_NR+ctlr][minor] = 1024; + blksize_size[hba[ctlr]->major][minor] = block_size; hba[ctlr]->hardsizes[minor] = block_size; } @@ -2225,7 +2272,7 @@ if (creq->nr_segments > MAXSGENTRIES) BUG(); - if (h->ctlr != MAJOR(creq->rq_dev)-MAJOR_NR ) { + if( h->ctlr != map_major_to_ctlr[MAJOR(creq->rq_dev)] ) { printk(KERN_WARNING "doreq cmd for %d, %x at %p\n", h->ctlr, creq->rq_dev, creq); blkdev_dequeue_request(creq); @@ -2234,6 +2281,15 @@ goto startio; } + /* make sure controller is alive. */ + if (!CTLR_IS_ALIVE(h)) { + printk(KERN_WARNING "cciss%d: I/O quit ", h->ctlr); + blkdev_dequeue_request(creq); + complete_buffers(creq->bh, 0); + end_that_request_last(creq); + return; + } + if (( c = cmd_alloc(h, 1)) == NULL) goto startio; @@ -2339,7 +2395,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; /* @@ -2383,7 +2439,7 @@ /* * See if we can queue up some more IO */ - do_cciss_request(BLK_DEFAULT_QUEUE(MAJOR_NR + h->ctlr)); + do_cciss_request(BLK_DEFAULT_QUEUE(h->major)); spin_unlock_irqrestore(&io_request_lock, flags); } /* @@ -2435,25 +2491,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, ready = 0; + __u32 board_id, scratchpad; + __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 +2552,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 +2584,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,30 +2596,50 @@ * 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 */ c->vaddr = remap_pci_mem(c->paddr, 200); + /* Wait for the board to become ready. (PCI hotplug needs this.) + * We poll for up to 120 secs, once per 100ms. */ + for (i=0; i < 1200; i++) { + scratchpad = readl(c->vaddr + SA5_SCRATCHPAD_OFFSET); + if (scratchpad == 0xffff0000) { + ready = 1; + break; + } + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ / 10); /* wait 100ms */ + } + if (!ready) { + printk(KERN_WARNING "cciss: Board not ready. Timed out.\n"); + return -1; + } /* 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(c); + return -1; + } cfg_offset = readl(c->vaddr + SA5_CTMEM_OFFSET); #ifdef CCISS_DEBUG printk("cfg offset = %x\n", cfg_offset); #endif /* CCISS_DEBUG */ c->cfgtable = (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; @@ -2574,6 +2667,17 @@ printk("Does not appear to be a valid CISS config table\n"); return -1; } + +#ifdef CONFIG_X86 +{ + /* Need to enable prefetch in the SCSI core for 6400 in x86 */ + __u32 prefetch; + prefetch = readl(&(c->cfgtable->SCSI_Prefetch)); + prefetch |= 0x100; + writel(prefetch, &(c->cfgtable->SCSI_Prefetch)); +} +#endif + #ifdef CCISS_DEBUG printk("Trying to put board into Simple mode\n"); #endif /* CCISS_DEBUG */ @@ -2583,11 +2687,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 +2771,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"); @@ -2795,8 +2902,10 @@ return i; } } - printk(KERN_WARNING "cciss: This driver supports a maximum" - " of 8 controllers.\n"); + printk(KERN_WARNING + "cciss: This driver supports a maximum of %d controllers.\n" + "You can change this value in cciss.c and recompile.\n", + MAX_CTLR); return -1; } @@ -2805,7 +2914,174 @@ kfree(hba[i]); hba[i]=NULL; } +#ifdef CONFIG_CISS_MONITOR_THREAD +static void fail_all_cmds(unsigned long ctlr) +{ + /* If we get here, the board is apparently dead. */ + ctlr_info_t *h = hba[ctlr]; + CommandList_struct *c; + unsigned long flags; + + printk(KERN_WARNING "cciss%d: controller not responding.\n", h->ctlr); + h->alive = 0; /* the controller apparently died... */ + + spin_lock_irqsave(&io_request_lock, flags); + + pci_disable_device(h->pdev); /* Make sure it is really dead. */ + + /* move everything off the request queue onto the completed queue */ + while( (c = h->reqQ) != NULL ) { + removeQ(&(h->reqQ), c); + h->Qdepth--; + addQ (&(h->cmpQ), c); + } + + /* Now, fail everything on the completed queue with a HW error */ + while( (c = h->cmpQ) != NULL ) { + removeQ(&h->cmpQ, c); + c->err_info->CommandStatus = CMD_HARDWARE_ERR; + if (c->cmd_type == CMD_RWREQ) { + complete_command(h, c, 0); + } else if (c->cmd_type == CMD_IOCTL_PEND) + complete(c->waiting); +# ifdef CONFIG_CISS_SCSI_TAPE + else if (c->cmd_type == CMD_SCSI) + complete_scsi_command(c, 0, 0); +# endif + } + spin_unlock_irqrestore(&io_request_lock, flags); + return; +} +static int cciss_monitor(void *ctlr) +{ + /* If the board fails, we ought to detect that. So we periodically + send down a No-Op message and expect it to complete quickly. If it + doesn't, then we assume the board is dead, and fail all commands. + This is useful mostly in a multipath configuration, so that failover + will happen. */ + + int rc; + ctlr_info_t *h = (ctlr_info_t *) ctlr; + unsigned long flags; + u32 current_timer; + daemonize(); + exit_files(current); + reparent_to_init(); + + printk("cciss%d: Monitor thread starting.\n", h->ctlr); + + /* only listen to signals if the HA was loaded as a module. */ +#define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM)) + siginitsetinv(¤t->blocked, SHUTDOWN_SIGS); + sprintf(current->comm, "ccissmon%d", h->ctlr); + h->monitor_thread = current; + + init_timer(&h->watchdog); + h->watchdog.function = fail_all_cmds; + h->watchdog.data = (unsigned long) h->ctlr; + while (1) { + /* check heartbeat timer */ + current_timer = readl(&h->cfgtable->HeartBeat); + current_timer &= 0x0fffffff; + if (heartbeat_timer == current_timer) { + fail_all_cmds(h->ctlr); + break; + } + else + heartbeat_timer = current_timer; + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(h->monitor_period * HZ); + h->watchdog.expires = jiffies + HZ * h->monitor_deadline; + add_timer(&h->watchdog); + /* send down a trivial command (no op message) to ctlr */ + rc = sendcmd_withirq(3, h->ctlr, NULL, 0, 0, 0, 0, TYPE_MSG); + del_timer(&h->watchdog); + if (!CTLR_IS_ALIVE(h)) + break; + if (signal_pending(current)) { + printk(KERN_WARNING "%s received signal.\n", + current->comm); + break; + } + if (h->monitor_period == 0) /* zero period means exit thread */ + break; + } + printk(KERN_INFO "%s exiting.\n", current->comm); + spin_lock_irqsave(&io_request_lock, flags); + h->monitor_started = 0; + h->monitor_thread = NULL; + spin_unlock_irqrestore(&io_request_lock, flags); + return 0; +} +static int start_monitor_thread(ctlr_info_t *h, unsigned char *cmd, + unsigned long count, int (*cciss_monitor)(void *), int *rc) +{ + unsigned long flags; + unsigned int new_period, old_period, new_deadline, old_deadline; + + if (strncmp("monitor", cmd, 7) == 0) { + new_period = simple_strtol(cmd + 8, NULL, 10); + spin_lock_irqsave(&io_request_lock, flags); + new_deadline = h->monitor_deadline; + spin_unlock_irqrestore(&io_request_lock, flags); + } else if (strncmp("deadline", cmd, 8) == 0) { + new_deadline = simple_strtol(cmd + 9, NULL, 10); + spin_lock_irqsave(&io_request_lock, flags); + new_period = h->monitor_period; + spin_unlock_irqrestore(&io_request_lock, flags); + } else + return -1; + if (new_period != 0 && new_period < CCISS_MIN_PERIOD) + new_period = CCISS_MIN_PERIOD; + if (new_period > CCISS_MAX_PERIOD) + new_period = CCISS_MAX_PERIOD; + if (new_deadline >= new_period) { + new_deadline = new_period - 5; + printk(KERN_INFO "setting deadline to %d\n", new_deadline); + } + spin_lock_irqsave(&io_request_lock, flags); + if (h->monitor_started != 0) { + old_period = h->monitor_period; + old_deadline = h->monitor_deadline; + h->monitor_period = new_period; + h->monitor_deadline = new_deadline; + spin_unlock_irqrestore(&io_request_lock, flags); + if (new_period == 0) { + printk(KERN_INFO "cciss%d: stopping monitor thread\n", + h->ctlr); + *rc = count; + return 0; + } + if (new_period != old_period) + printk(KERN_INFO "cciss%d: adjusting monitor thread " + "period from %d to %d seconds\n", + h->ctlr, old_period, new_period); + if (new_deadline != old_deadline) + printk(KERN_INFO "cciss%d: adjusting monitor thread " + "deadline from %d to %d seconds\n", + h->ctlr, old_deadline, new_deadline); + *rc = count; + return 0; + } + h->monitor_started = 1; + h->monitor_period = new_period; + h->monitor_deadline = new_deadline; + spin_unlock_irqrestore(&io_request_lock, flags); + kernel_thread(cciss_monitor, h, 0); + *rc = count; + return 0; +} + +static void kill_monitor_thread(ctlr_info_t *h) +{ + if (h->monitor_thread) + send_sig(SIGKILL, h->monitor_thread, 1); +} +#else +#define kill_monitor_thread(h) +#endif /* * This is it. Find all the controllers and register them. I really hate * stealing all these major device numbers. @@ -2817,6 +3093,7 @@ request_queue_t *q; int i; int j; + int rc; printk(KERN_DEBUG "cciss: Device 0x%x has been found at" " bus %d dev %d func %d\n", @@ -2832,26 +3109,33 @@ } sprintf(hba[i]->devname, "cciss%d", i); hba[i]->ctlr = i; + + /* register with the major number, or get a dynamic major number */ + /* by passing 0 as argument */ + + if (i < MAX_CTLR_ORIG) + hba[i]->major = MAJOR_NR + i; + hba[i]->pdev = pdev; + ASSERT_CTLR_ALIVE(hba[i]); - /* 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)) { + rc = (register_blkdev(hba[i]->major, hba[i]->devname, &cciss_fops)); + if (rc < 0) { printk(KERN_ERR "cciss: Unable to get major number " - "%d for %s\n", MAJOR_NR+i, hba[i]->devname); + "%d for %s\n", hba[i]->major, hba[i]->devname); release_io_mem(hba[i]); free_hba(i); return -1; + } else { + if (i < MAX_CTLR_ORIG) { + hba[i]->major = MAJOR_NR + i; + map_major_to_ctlr[MAJOR_NR + i] = i; + } else { + hba[i]->major = rc; + map_major_to_ctlr[rc] = i; + } } + /* make sure the board interrupts are off */ hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF); if (request_irq(hba[i]->intr, do_cciss_intr, @@ -2860,7 +3144,8 @@ printk(KERN_ERR "cciss: Unable to get irq %d for %s\n", hba[i]->intr, hba[i]->devname); - unregister_blkdev( MAJOR_NR+i, hba[i]->devname); + unregister_blkdev( hba[i]->major, hba[i]->devname); + map_major_to_ctlr[hba[i]->major] = 0; release_io_mem(hba[i]); free_hba(i); return -1; @@ -2889,7 +3174,8 @@ hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle); free_irq(hba[i]->intr, hba[i]); - unregister_blkdev(MAJOR_NR+i, hba[i]->devname); + unregister_blkdev(hba[i]->major, hba[i]->devname); + map_major_to_ctlr[hba[i]->major] = 0; release_io_mem(hba[i]); free_hba(i); printk( KERN_ERR "cciss: out of memory"); @@ -2916,16 +3202,16 @@ cciss_procinit(i); - q = BLK_DEFAULT_QUEUE(MAJOR_NR + i); + q = BLK_DEFAULT_QUEUE(hba[i]->major); q->queuedata = hba[i]; blk_init_queue(q, do_cciss_request); blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); blk_queue_headactive(q, 0); /* fill in the other Kernel structs */ - blksize_size[MAJOR_NR+i] = hba[i]->blocksizes; - hardsect_size[MAJOR_NR+i] = hba[i]->hardsizes; - read_ahead[MAJOR_NR+i] = READ_AHEAD; + blksize_size[hba[i]->major] = hba[i]->blocksizes; + hardsect_size[hba[i]->major] = hba[i]->hardsizes; + read_ahead[hba[i]->major] = READ_AHEAD; /* Set the pointers to queue functions */ q->back_merge_fn = cpq_back_merge_fn; @@ -2934,7 +3220,7 @@ /* Fill in the gendisk data */ - hba[i]->gendisk.major = MAJOR_NR + i; + hba[i]->gendisk.major = hba[i]->major; hba[i]->gendisk.major_name = "cciss"; hba[i]->gendisk.minor_shift = NWD_SHIFT; hba[i]->gendisk.max_p = MAX_PART; @@ -2949,7 +3235,7 @@ cciss_geninit(i); for(j=0; jgendisk), - MKDEV(MAJOR_NR+i, j <<4), + MKDEV(hba[i]->major, j <<4), MAX_PART, &cciss_fops, hba[i]->drv[j].nr_blocks); @@ -2976,20 +3262,24 @@ "already be removed \n"); return; } - /* Turn board interrupts off and send the flush cache command */ - /* sendcmd will turn off interrupt, and send the flush... - * To write all data in the battery backed cache to disks */ + kill_monitor_thread(hba[i]); + /* no sense in trying to flush a dead board's cache. */ + if (CTLR_IS_ALIVE(hba[i])) { + /* Turn board interrupts off and flush the cache */ + /* write all data in the battery backed cache to disks */ memset(flush_buf, 0, 4); - return_code = sendcmd(CCISS_CACHE_FLUSH, i, flush_buf, 4,0,0,0, NULL); - if (return_code != IO_OK) { + return_code = sendcmd(CCISS_CACHE_FLUSH, i, flush_buf, + 4, 0, 0, 0, NULL); + if (return_code != IO_OK) printk(KERN_WARNING - "Error Flushing cache on controller %d\n", i); + "cciss%d: Error flushing cache\n", i); } free_irq(hba[i]->intr, hba[i]); pci_set_drvdata(pdev, NULL); iounmap((void*)hba[i]->vaddr); cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ - unregister_blkdev(MAJOR_NR+i, hba[i]->devname); + unregister_blkdev(hba[i]->major, hba[i]->devname); + map_major_to_ctlr[hba[i]->major] = 0; remove_proc_entry(hba[i]->devname, proc_cciss); @@ -3021,12 +3311,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) Index: drivers/block/cciss.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/block/cciss.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/block/cciss.h 22 Jul 2004 19:50:12 -0000 1.1 +++ drivers/block/cciss.h 4 Aug 2004 01:28:38 -0000 1.2 @@ -40,18 +40,19 @@ struct ctlr_info { int ctlr; + int major; char devname[8]; char *product_name; 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 */ @@ -91,6 +92,40 @@ #ifdef CONFIG_CISS_SCSI_TAPE void *scsi_ctlr; /* ptr to structure containing scsi related stuff */ #endif +#ifdef CONFIG_CISS_MONITOR_THREAD + struct timer_list watchdog; + struct task_struct *monitor_thread; + unsigned int monitor_period; + unsigned int monitor_deadline; + unsigned char alive; + unsigned char monitor_started; +#define CCISS_MIN_PERIOD 10 +#define CCISS_MAX_PERIOD 3600 +#define CTLR_IS_ALIVE(h) (h->alive) +#define ASSERT_CTLR_ALIVE(h) { h->alive = 1; \ + h->monitor_period = 0; \ + h->monitor_started = 0; } +#define MONITOR_STATUS_PATTERN "Status: %s\n" +#define CTLR_STATUS(h) CTLR_IS_ALIVE(h) ? "operational" : "failed" +#define MONITOR_PERIOD_PATTERN "Monitor thread period: %d\n" +#define MONITOR_PERIOD_VALUE(h) (h->monitor_period) +#define MONITOR_DEADLINE_PATTERN "Monitor thread deadline: %d\n" +#define MONITOR_DEADLINE_VALUE(h) (h->monitor_deadline) +#define START_MONITOR_THREAD(h, cmd, count, cciss_monitor, rc) \ + start_monitor_thread(h, cmd, count, cciss_monitor, rc) +#else + +#define MONITOR_PERIOD_PATTERN "%s" +#define MONITOR_PERIOD_VALUE(h) "" +#define MONITOR_DEADLINE_PATTERN "%s" +#define MONITOR_DEADLINE_VALUE(h) "" +#define MONITOR_STATUS_PATTERN "%s\n" +#define CTLR_STATUS(h) "" +#define CTLR_IS_ALIVE(h) (1) +#define ASSERT_CTLR_ALIVE(h) +#define START_MONITOR_THREAD(a,b,c,d,rc) (*rc == 0) + +#endif }; /* Defining the diffent access_menthods */ @@ -102,6 +137,7 @@ #define SA5_REPLY_INTR_MASK_OFFSET 0x34 #define SA5_REPLY_PORT_OFFSET 0x44 #define SA5_INTR_STATUS 0x30 +#define SA5_SCRATCHPAD_OFFSET 0xB0 #define SA5_CTCFG_OFFSET 0xB4 #define SA5_CTMEM_OFFSET 0xB8 @@ -139,9 +175,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 +193,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); } Index: drivers/block/cciss_cmd.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/block/cciss_cmd.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/block/cciss_cmd.h 22 Jul 2004 19:50:11 -0000 1.1 +++ drivers/block/cciss_cmd.h 4 Aug 2004 01:28:38 -0000 1.2 @@ -266,6 +266,7 @@ DWORD Reserved; BYTE ServerName[16]; DWORD HeartBeat; + DWORD SCSI_Prefetch; } CfgTable_struct; #pragma pack() #endif /* CCISS_CMD_H */ Index: drivers/block/cciss_scsi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/block/cciss_scsi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/block/cciss_scsi.c 22 Jul 2004 19:50:12 -0000 1.1 +++ drivers/block/cciss_scsi.c 4 Aug 2004 01:28:39 -0000 1.2 @@ -71,16 +71,7 @@ #endif #endif -static struct cciss_scsi_hba_t ccissscsi[MAX_CTLR] = { - { name: "cciss0", ndevices: 0 }, - { name: "cciss1", ndevices: 0 }, - { name: "cciss2", ndevices: 0 }, - { name: "cciss3", ndevices: 0 }, - { name: "cciss4", ndevices: 0 }, - { name: "cciss5", ndevices: 0 }, - { name: "cciss6", ndevices: 0 }, - { name: "cciss7", ndevices: 0 }, -}; +static struct cciss_scsi_hba_t ccissscsi[MAX_CTLR]; /* We need one Scsi_Host_Template *per controller* instead of the usual one Scsi_Host_Template per controller *type*. This @@ -92,11 +83,7 @@ (that's called from cciss.c:cciss_init_one()) */ static -Scsi_Host_Template driver_template[MAX_CTLR] = -{ - CCISS_SCSI, CCISS_SCSI, CCISS_SCSI, CCISS_SCSI, - CCISS_SCSI, CCISS_SCSI, CCISS_SCSI, CCISS_SCSI, -}; +Scsi_Host_Template driver_template[MAX_CTLR]; #pragma pack(1) struct cciss_scsi_cmd_stack_elem_t { @@ -602,6 +589,8 @@ for(i=0; iLUN[i][3] & 0xC0) continue; memset(inq_buff, 0, sizeof(InquiryData_struct)); memcpy(scsi3addr, ld_buff->LUN[i], 8); /* ugly... */ return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff, @@ -803,13 +792,7 @@ sh->this_id = SELF_SCSI_ID; - /* This is a bit kludgey, using the adapter name to figure out */ - /* which scsi host template we've got, won't scale beyond 9 ctlrs. */ - i = tpnt->name[5] - '0'; - -# if MAX_CTLR > 9 -# error "cciss_scsi.c: MAX_CTLR > 9, code maintenance needed." -# endif + i = simple_strtol((char *)&tpnt->name[5], NULL, 10); if (i<0 || i>=MAX_CTLR || hba[i] == NULL) { /* we didn't find ourself... we shouldn't get here. */ @@ -1167,6 +1150,7 @@ int devtype; /* for each physical lun, do an inquiry */ + if (ld_buff->LUN[i][3] & 0xC0) continue; memset(inq_buff, 0, sizeof(InquiryData_struct)); memcpy(&scsi3addr[0], &ld_buff->LUN[i][0], 8); @@ -1182,6 +1166,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; @@ -1522,9 +1512,10 @@ unsigned long flags; CPQ_TAPE_LOCK(ctlr, flags); - driver_template[ctlr].name = ccissscsi[ctlr].name; - driver_template[ctlr].proc_name = ccissscsi[ctlr].name; - driver_template[ctlr].module = THIS_MODULE;; + + sprintf( ccissscsi[ctlr].name, "cciss%d", ctlr ); + + init_driver_template(ctlr); /* Since this is really a block driver, the SCSI core may not be initialized yet, in which case, calling scsi_register_module Index: drivers/block/cciss_scsi.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/block/cciss_scsi.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/block/cciss_scsi.h 22 Jul 2004 19:50:12 -0000 1.1 +++ drivers/block/cciss_scsi.h 4 Aug 2004 01:28:39 -0000 1.2 @@ -89,7 +89,7 @@ }; struct cciss_scsi_hba_t { - char *name; + char name[32]; int ndevices; #define CCISS_MAX_SCSI_DEVS_PER_HBA 16 struct cciss_scsi_dev_t dev[CCISS_MAX_SCSI_DEVS_PER_HBA]; Index: drivers/block/cpqarray.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/block/cpqarray.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/block/cpqarray.c 22 Jul 2004 19:50:11 -0000 1.1 +++ drivers/block/cpqarray.c 4 Aug 2004 01:28:39 -0000 1.2 @@ -41,13 +41,13 @@ #define SMART2_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) -#define DRIVER_NAME "Compaq SMART2 Driver (v 2.4.25)" -#define DRIVER_VERSION SMART2_DRIVER_VERSION(2,4,25) +#define DRIVER_NAME "Compaq SMART2 Driver (v 2.4.28)" +#define DRIVER_VERSION SMART2_DRIVER_VERSION(2,4,28) /* Embedded module documentation macros - see modules.h */ /* Original author Chris Frantz - Compaq Computer Corporation */ MODULE_AUTHOR("Compaq Computer Corporation"); -MODULE_DESCRIPTION("Driver for Compaq Smart2 Array Controllers version 2.4.25"); +MODULE_DESCRIPTION("Driver for Compaq Smart2 Array Controllers version 2.4.28"); MODULE_LICENSE("GPL"); #define MAJOR_NR COMPAQ_SMART2_MAJOR @@ -180,6 +180,7 @@ static int deregister_disk(int ctlr, int logvol); static int register_new_disk(int cltr,int logvol); +static int cpqarray_register_ctlr(int ctlr, int type); #ifdef CONFIG_PROC_FS static void ida_procinit(int i); @@ -470,10 +471,111 @@ return 1; } +static int cpqarray_register_ctlr(int ctlr, int type) +{ + request_queue_t *q; + int j; + + /* + * register block devices + * Find disks and fill in structs + * Get an interrupt, set the Q depth and get into /proc + */ + + /* If this successful it should insure that we are the only */ + /* instance of the driver for this card */ + if (register_blkdev(MAJOR_NR+ctlr, hba[ctlr]->devname, &ida_fops)) { + printk(KERN_ERR "cpqarray: Unable to get major number %d\n", MAJOR_NR+ctlr); + goto err_out; + } + + hba[ctlr]->access.set_intr_mask(hba[ctlr], 0); + if (request_irq(hba[ctlr]->intr, do_ida_intr, + SA_INTERRUPT|SA_SHIRQ|SA_SAMPLE_RANDOM, + hba[ctlr]->devname, hba[ctlr])) { + printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n", + hba[ctlr]->intr, hba[ctlr]->devname); + unregister_blkdev(MAJOR_NR+ctlr, hba[ctlr]->devname); + goto err_out; + } + hba[ctlr]->cmd_pool = (cmdlist_t *)pci_alloc_consistent( + hba[ctlr]->pci_dev, NR_CMDS * sizeof(cmdlist_t), + &(hba[ctlr]->cmd_pool_dhandle)); + hba[ctlr]->cmd_pool_bits = (__u32*)kmalloc( + ((NR_CMDS+31)/32)*sizeof(__u32), GFP_KERNEL); + + if (hba[ctlr]->cmd_pool_bits == NULL || hba[ctlr]->cmd_pool == NULL) { + if (hba[ctlr]->cmd_pool_bits) + kfree(hba[ctlr]->cmd_pool_bits); + if (hba[ctlr]->cmd_pool) + pci_free_consistent(hba[ctlr]->pci_dev, + NR_CMDS * sizeof(cmdlist_t), + hba[ctlr]->cmd_pool, + hba[ctlr]->cmd_pool_dhandle); + + free_irq(hba[ctlr]->intr, hba[ctlr]); + unregister_blkdev(MAJOR_NR+ctlr, hba[ctlr]->devname); + printk( KERN_ERR "cpqarray: out of memory"); + goto err_out; + } + memset(hba[ctlr]->cmd_pool, 0, NR_CMDS * sizeof(cmdlist_t)); + memset(hba[ctlr]->cmd_pool_bits, 0, ((NR_CMDS+31)/32)*sizeof(__u32)); + printk(KERN_INFO "cpqarray: Finding drives on %s", hba[ctlr]->devname); + getgeometry(ctlr); + start_fwbk(ctlr); + + hba[ctlr]->access.set_intr_mask(hba[ctlr], FIFO_NOT_EMPTY); + + ida_procinit(ctlr); + + q = BLK_DEFAULT_QUEUE(MAJOR_NR + ctlr); + q->queuedata = hba[ctlr]; + blk_init_queue(q, do_ida_request); + if (type) + blk_queue_bounce_limit(q, hba[ctlr]->pci_dev->dma_mask); + blk_queue_headactive(q, 0); + blksize_size[MAJOR_NR+ctlr] = hba[ctlr]->blocksizes; + hardsect_size[MAJOR_NR+ctlr] = hba[ctlr]->hardsizes; + read_ahead[MAJOR_NR+ctlr] = READ_AHEAD; + + q->back_merge_fn = cpq_back_merge_fn; + q->front_merge_fn = cpq_front_merge_fn; + q->merge_requests_fn = cpq_merge_requests_fn; + + hba[ctlr]->gendisk.major = MAJOR_NR + ctlr; + hba[ctlr]->gendisk.major_name = "ida"; + hba[ctlr]->gendisk.minor_shift = NWD_SHIFT; + hba[ctlr]->gendisk.max_p = IDA_MAX_PART; + hba[ctlr]->gendisk.part = hba[ctlr]->hd; + hba[ctlr]->gendisk.sizes = hba[ctlr]->sizes; + hba[ctlr]->gendisk.nr_real = hba[ctlr]->highest_lun+1; + hba[ctlr]->gendisk.fops = &ida_fops; + + /* Get on the disk list */ + add_gendisk(&(hba[ctlr]->gendisk)); + + init_timer(&hba[ctlr]->timer); + hba[ctlr]->timer.expires = jiffies + IDA_TIMER; + hba[ctlr]->timer.data = (unsigned long)hba[ctlr]; + hba[ctlr]->timer.function = ida_timer; + add_timer(&hba[ctlr]->timer); + + ida_geninit(ctlr); + for(j=0; jgendisk), MKDEV(MAJOR_NR+ctlr,j<<4), + IDA_MAX_PART, &ida_fops, hba[ctlr]->drv[j].nr_blks); + return(ctlr); + +err_out: + release_io_mem(hba[ctlr]); + free_hba(ctlr); + return (-1); +} + + static int __init cpqarray_init_one( struct pci_dev *pdev, const struct pci_device_id *ent) { - request_queue_t *q; int i,j; @@ -500,102 +602,7 @@ return (-1); } - /* - * register block devices - * Find disks and fill in structs - * Get an interrupt, set the Q depth and get into /proc - */ - - /* If this successful it should insure that we are the only */ - /* instance of the driver */ - if (register_blkdev(MAJOR_NR+i, hba[i]->devname, &ida_fops)) { - printk(KERN_ERR "cpqarray: Unable to get major number %d for ida\n", - MAJOR_NR+i); - release_io_mem(hba[i]); - free_hba(i); - return (-1); - } - - - hba[i]->access.set_intr_mask(hba[i], 0); - if (request_irq(hba[i]->intr, do_ida_intr, - SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, - hba[i]->devname, hba[i])) { - - printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n", - hba[i]->intr, hba[i]->devname); - unregister_blkdev(MAJOR_NR+i, hba[i]->devname); - release_io_mem(hba[i]); - free_hba(i); - return (-1); - } - hba[i]->cmd_pool = (cmdlist_t *)pci_alloc_consistent( - hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t), - &(hba[i]->cmd_pool_dhandle)); - hba[i]->cmd_pool_bits = (__u32*)kmalloc( - ((NR_CMDS+31)/32)*sizeof(__u32), GFP_KERNEL); - - if(hba[i]->cmd_pool_bits == NULL || hba[i]->cmd_pool == NULL) { - if(hba[i]->cmd_pool_bits) - kfree(hba[i]->cmd_pool_bits); - if(hba[i]->cmd_pool) - pci_free_consistent(hba[i]->pci_dev, - NR_CMDS * sizeof(cmdlist_t), - hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); - free_irq(hba[i]->intr, hba[i]); - unregister_blkdev(MAJOR_NR+i, hba[i]->devname); - printk( KERN_ERR "cpqarray: out of memory"); - release_io_mem(hba[i]); - free_hba(i); - return (-1); - } - memset(hba[i]->cmd_pool, 0, NR_CMDS * sizeof(cmdlist_t)); - memset(hba[i]->cmd_pool_bits, 0, ((NR_CMDS+31)/32)*sizeof(__u32)); - printk(KERN_INFO "cpqarray: Finding drives on %s", hba[i]->devname); - getgeometry(i); - start_fwbk(i); - - hba[i]->access.set_intr_mask(hba[i], FIFO_NOT_EMPTY); - - ida_procinit(i); - - q = BLK_DEFAULT_QUEUE(MAJOR_NR + i); - q->queuedata = hba[i]; - blk_init_queue(q, do_ida_request); - blk_queue_bounce_limit(q, hba[i]->pci_dev->dma_mask); - blk_queue_headactive(q, 0); - blksize_size[MAJOR_NR+i] = hba[i]->blocksizes; - hardsect_size[MAJOR_NR+i] = hba[i]->hardsizes; - read_ahead[MAJOR_NR+i] = READ_AHEAD; - - q->back_merge_fn = cpq_back_merge_fn; - q->front_merge_fn = cpq_front_merge_fn; - q->merge_requests_fn = cpq_merge_requests_fn; - - hba[i]->gendisk.major = MAJOR_NR + i; - hba[i]->gendisk.major_name = "ida"; - hba[i]->gendisk.minor_shift = NWD_SHIFT; - hba[i]->gendisk.max_p = IDA_MAX_PART; - hba[i]->gendisk.part = hba[i]->hd; - hba[i]->gendisk.sizes = hba[i]->sizes; - hba[i]->gendisk.nr_real = hba[i]->highest_lun+1; - hba[i]->gendisk.fops = &ida_fops; - - /* Get on the disk list */ - add_gendisk(&(hba[i]->gendisk)); - - init_timer(&hba[i]->timer); - hba[i]->timer.expires = jiffies + IDA_TIMER; - hba[i]->timer.data = (unsigned long)hba[i]; - hba[i]->timer.function = ida_timer; - add_timer(&hba[i]->timer); - - ida_geninit(i); - for(j=0; jgendisk), MKDEV(MAJOR_NR+i,j<<4), - IDA_MAX_PART, &ida_fops, hba[i]->drv[j].nr_blks); - - return(i); + return (cpqarray_register_ctlr(i, 1)); } static struct pci_driver cpqarray_pci_driver = { name: "cpqarray", @@ -616,7 +623,7 @@ /* detect controllers */ printk(DRIVER_NAME "\n"); - pci_register_driver(&cpqarray_pci_driver); + pci_module_init(&cpqarray_pci_driver); cpqarray_eisa_detect(); for(i=0; i< MAX_CTLR; i++) { @@ -868,6 +875,11 @@ num_ctlr++; i++; + + if (cpqarray_register_ctlr(ctlr, 0) == -1) + printk(KERN_WARNING + "cpqarray%d: Can't register EISA controller\n", + ctlr); } return num_ctlr; @@ -1377,6 +1389,7 @@ case BLKFLSBUF: case BLKBSZSET: case BLKBSZGET: + case BLKSSZGET: case BLKROSET: case BLKROGET: case BLKRASET: Index: drivers/block/floppy.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/block/floppy.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/block/floppy.c 22 Jul 2004 19:50:12 -0000 1.1 +++ drivers/block/floppy.c 4 Aug 2004 01:28:39 -0000 1.2 @@ -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(); Index: drivers/block/genhd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/block/genhd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/block/genhd.c 22 Jul 2004 19:50:12 -0000 1.1 +++ drivers/block/genhd.c 4 Aug 2004 01:28:39 -0000 1.2 @@ -201,7 +201,7 @@ disk_round_stats(hd); seq_printf(s, "%4d %4d %10d %s " - "%d %d %d %d %d %d %d %d %d %d %d\n", + "%u %u %u %u %u %u %u %u %d %u %u\n", gp->major, n, gp->sizes[n], disk_name(gp, n, buf), hd->rd_ios, hd->rd_merges, Index: drivers/block/ll_rw_blk.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/block/ll_rw_blk.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/block/ll_rw_blk.c 22 Jul 2004 19:50:11 -0000 1.1 +++ drivers/block/ll_rw_blk.c 4 Aug 2004 01:28:39 -0000 1.2 @@ -134,6 +134,10 @@ unsigned long blk_max_low_pfn, blk_max_pfn; int blk_nohighio = 0; +int block_dump = 0; + +static struct timer_list writeback_timer; + static inline int get_max_sectors(kdev_t dev) { if (!max_sectors[MAJOR(dev)]) @@ -189,11 +193,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)); } @@ -228,6 +233,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 @@ -402,7 +425,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, @@ -412,21 +435,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; } @@ -435,23 +471,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); } @@ -504,6 +545,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 @@ -524,12 +567,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; @@ -540,29 +600,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: * @@ -574,28 +624,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) @@ -603,21 +648,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]; @@ -831,7 +892,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; @@ -841,9 +901,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); + } } } @@ -875,6 +955,15 @@ return; q->elevator.elevator_merge_req_fn(req, next); + + /* At this point we have either done a back merge + * or front merge. We need the smaller start_time of + * the merged requests to be the current request + * for accounting purposes. + */ + if (time_after(req->start_time, next->start_time)) + req->start_time = next->start_time; + req->bhtail->b_reqnext = next->bh; req->bhtail = next->bhtail; req->nr_sectors = req->hard_nr_sectors += next->hard_nr_sectors; @@ -914,16 +1003,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) { @@ -961,7 +1052,6 @@ */ max_sectors = get_max_sectors(bh->b_rdev); -again: req = NULL; head = &q->queue_head; /* @@ -970,7 +1060,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; @@ -989,6 +1081,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); @@ -1011,6 +1104,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); @@ -1043,7 +1137,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; } @@ -1055,6 +1149,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; } } @@ -1077,10 +1174,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: @@ -1209,8 +1311,18 @@ 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); + + if (block_dump) + printk(KERN_DEBUG "%s: %s block %lu/%u on %s\n", current->comm, rw == WRITE ? "WRITE" : "READ", bh->b_rsector, count, kdevname(bh->b_rdev)); + + put_bh(bh); switch (rw) { case WRITE: kstat.pgpgout += count; @@ -1287,9 +1399,7 @@ for (i = 0; i < nr; i++) { struct buffer_head *bh = bhs[i]; - /* Only one thread can actually submit the I/O. */ - if (test_and_set_bit(BH_Lock, &bh->b_state)) - continue; + lock_buffer(bh); /* We have the buffer lock */ atomic_inc(&bh->b_count); @@ -1330,6 +1440,11 @@ extern int stram_device_init (void); #endif +static void blk_writeback_timer(unsigned long data) +{ + wakeup_bdflush(); + wakeup_kupdate(); +} /** * end_that_request_first - end I/O on one buffer. @@ -1363,6 +1478,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); @@ -1385,10 +1501,18 @@ return 0; } +extern int laptop_mode; + void end_that_request_last(struct request *req) { struct completion *waiting = req->waiting; + /* + * schedule the writeout of pending dirty data when the disk is idle + */ + if (laptop_mode && req->cmd == READ) + mod_timer(&writeback_timer, jiffies + 5 * HZ); + req_finished_io(req); blkdev_release_request(req); if (waiting) @@ -1416,6 +1540,9 @@ blk_max_low_pfn = max_low_pfn - 1; blk_max_pfn = max_pfn - 1; + init_timer(&writeback_timer); + writeback_timer.function = blk_writeback_timer; + #ifdef CONFIG_AMIGA_Z2RAM z2_init(); #endif @@ -1524,6 +1651,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); Index: drivers/block/loop.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/block/loop.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/block/loop.c 22 Jul 2004 19:50:12 -0000 1.1 +++ drivers/block/loop.c 4 Aug 2004 01:28:39 -0000 1.2 @@ -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: Index: drivers/block/nbd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/block/nbd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/block/nbd.c 22 Jul 2004 19:50:11 -0000 1.1 +++ drivers/block/nbd.c 4 Aug 2004 01:28:39 -0000 1.2 @@ -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 Index: drivers/block/sdcard.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/block/sdcard.c,v retrieving revision 1.1 retrieving revision 1.4 diff -u -r1.1 -r1.4 --- drivers/block/sdcard.c 22 Aug 2006 16:08:59 -0000 1.1 +++ drivers/block/sdcard.c 16 Jan 2009 20:34:27 -0000 1.4 @@ -1,264 +1,654 @@ -#include -#include -#include -#include /* printk() */ -#include /* kmalloc() */ -#include /* everything... */ -#include /* error codes */ -#include /* size_t */ -#include /* O_ACCMODE */ -#include /* HDIO_GETGEO */ -#include /* cli(), *_flags */ -#include -#include -#include -#include -#include - -#define MAJOR_NR sdcard_major /* force definitions on in blk.h */ -int sdcard_major; /* must be declared before including blk.h */ - -#include -#include /* blk_ioctl() */ -#include - -extern void __udelay(unsigned int); -#define udelay(x) __udelay((x)) -#include "sd.c" - -MODULE_AUTHOR("Technologic Systems"); -MODULE_LICENSE("Proprietary"); -MODULE_PARM(io, "l"); -MODULE_PARM(name, "s"); - -static unsigned char *name = "sdcard0"; -static unsigned int io = 0x13000000; -static int sdcard_size; -static int sdcard_sizes[16]; -static struct hd_struct sdcard_partitions[16]; -static devfs_handle_t devfs_handle; -static struct gendisk sdcard_gendisk; -static unsigned char *start; - -/* Forwards */ -static int sdcard_revalidate(kdev_t i_rdev); -static struct block_device_operations sdcard_bdops; - - -static int sdcard_open(struct inode *inode, struct file *filp) -{ - MOD_INC_USE_COUNT; - return 0; -} - - -static int sdcard_release(struct inode *inode, struct file *filp) -{ - MOD_DEC_USE_COUNT; - return 0; -} - - -static int sdcard_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - int err; - struct hd_geometry geo; - - switch (cmd) { - case HDIO_GETGEO: - /* - * get geometry: we have to fake one... trim the size to a - * multiple of 512 (256k): tell we have 32 sectors, 16 heads, - * whatever cylinders. - */ - - // TODO: This should match what the SD cards look like in a - // USB adapter dongle. -- JO - - err = !access_ok(VERIFY_WRITE, arg, sizeof(geo)); - if (err) - return -EFAULT; - - geo.cylinders = sdcard_size / (16 * 32); - geo.heads = 16; - geo.sectors = 32; - geo.start = 0; - - if (copy_to_user((void *) arg, &geo, sizeof(geo))) - return -EFAULT; - - return 0; - - default: - /* - * For ioctls we don't understand, let the block layer handle them. - */ - - return blk_ioctl(inode->i_rdev, cmd, arg); - } - - return -ENOTTY; -} - - -static int sdcard_check_change(kdev_t i_rdev) -{ - if (sdping()) { - sdinit(start); - return 1; - } else return 0; -} - - -static struct block_device_operations sdcard_bdops = { - open: sdcard_open, - release: sdcard_release, - ioctl: sdcard_ioctl, - revalidate: sdcard_revalidate, - check_media_change: sdcard_check_change, -}; - - -static int sdcard_revalidate(kdev_t i_rdev) -{ - - /* first clear old partition information */ - memset(sdcard_gendisk.sizes + 1, 0, 15 * sizeof(int)); - memset(sdcard_gendisk.part + 1, 0, 15 * sizeof(struct hd_struct)); - - sdcard_size = sdcard_gendisk.part[0].nr_sects = sdsize(); - - /* then fill new info */ - register_disk(&sdcard_gendisk, i_rdev, 16, &sdcard_bdops, sdcard_size); - - return 0; -} - - -static int sdcard_make_request(request_queue_t * q, int rw, - struct buffer_head *bh) -{ - unsigned int ret = 0; - bh->b_rsector += sdcard_partitions[MINOR(bh->b_rdev)].start_sect; - - switch (rw) { - case READ: - ret = sdread(bh->b_rsector, bh->b_data, bh->b_size / 512); - if (ret) { - sdinit(start); - ret = sdread(bh->b_rsector, bh->b_data, bh->b_size / 512); - } - printk(KERN_INFO "r%db\n", bh->b_size); - bh->b_end_io(bh, !ret); - break; - case WRITE: - refile_buffer(bh); - ret = sdwrite(bh->b_rsector, bh->b_data, bh->b_size / 512); - if (ret && !sdwprot()) { - sdinit(start); - ret = sdwrite(bh->b_rsector, bh->b_data, bh->b_size / 512); - } - printk(KERN_INFO "w%db\n", bh->b_size); - if (ret == 0) mark_buffer_uptodate(bh, 1); - bh->b_end_io(bh, !ret); - break; - default: - bh->b_end_io(bh, 0); - break; - } - return 0; -} - - -static int sdcard_init(void) -{ - int model = inw(TS7XXX_MODEL) & 0x7; - int pldrev = inw(TS7XXX_PLDREV) & 0x7; - int opts = inw(0x02400000 + TS7XXX_IO16_BASE) & 0x7; - unsigned int scratchreg0 = inl(SYSCON_SCRREG0); - - start = (unsigned char *) __ioremap(io, 4, 0); - - printk("%s: Technologic Systems SD card controller, address 0x%x\n", - name, io); - - /* - if (!((model == TS7260 && pldrev >= 5 && (opts & 0x4)) || model == TS7300)) { - printk("%s: no SD card option present on this board\n", name); - return 1; - } - */ - - sdcard_size = 0; - if (scratchreg0) { - sdcard_size = sdfastinit(start, scratchreg0); - outl(0, SYSCON_SCRREG0); - } - if (sdcard_size == 0) sdcard_size = sdinit(start); - - if (sdcard_size == 0) { - printk("%s: no card found\n", name); - return 1; - } else { - printk("%s: card size %d sectors\n", name, sdcard_size); - } - - sdcard_major = register_blkdev(0, name, &sdcard_bdops); - devfs_handle = devfs_mk_dir(NULL, name, NULL); - - memset(sdcard_sizes, 0, 16 * sizeof(int)); - sdcard_sizes[0] = sdcard_size; - - memset(sdcard_partitions, 0, 16 * sizeof(struct hd_struct)); - sdcard_partitions[0].nr_sects = sdcard_size; - - sdcard_gendisk.minor_shift = 4; - sdcard_gendisk.max_p = 16; - sdcard_gendisk.fops = &sdcard_bdops; - sdcard_gendisk.major = sdcard_major; - sdcard_gendisk.major_name = name; - sdcard_gendisk.part = sdcard_partitions; - sdcard_gendisk.nr_real = 1; - sdcard_gendisk.sizes = sdcard_sizes; - - add_gendisk(&sdcard_gendisk); - - blk_size[sdcard_major] = sdcard_sizes; - hardsect_size[sdcard_major] = NULL; - blksize_size[sdcard_major] = NULL; - read_ahead[sdcard_major] = 0; - - blk_queue_make_request(BLK_DEFAULT_QUEUE(sdcard_major), - sdcard_make_request); - register_disk(&sdcard_gendisk, MKDEV(sdcard_major, 0), 16, - &sdcard_bdops, sdcard_size); - - EXPORT_NO_SYMBOLS; - - return 0; -} - - -static void sdcard_cleanup(void) -{ - unregister_blkdev(sdcard_major, name); - devfs_unregister(devfs_handle); - - blk_size[sdcard_major] = NULL; - - del_gendisk(&sdcard_gendisk); - __iounmap((unsigned char *) io); -} - - -int init_module(void) -{ - return sdcard_init(); -} - - -void cleanup_module(void) -{ - return sdcard_cleanup(); -} +#include +#include +#include +#include /* printk() */ +#include /* kmalloc() */ +#include /* everything... */ +#include /* error codes */ +#include /* size_t */ +#include /* O_ACCMODE */ +#include /* HDIO_GETGEO */ +#include /* cli(), *_flags */ +#include +#include +#include +#include +#include +#include +#include + +#define MAJOR_NR sdcard_major /* force definitions on in blk.h */ +int sdcard_major; /* must be declared before including blk.h */ + +#include +#include /* blk_ioctl() */ +#include + +#include + +extern void __udelay(unsigned int); +#define udelay(x) __udelay((x)) + + + +#ifdef CONFIG_PROSOFT_SD +#include "tssdcore2.c" +#define TS7XXX_SDCARD1 0x600FF000 +#else +#include "sdcore.c" +#define TS7XXX_SDCARD1 (TS7XXX_IO8_BASE_PHYS|SDCARD1_OFFSET) +#define SDCARD1_OFFSET 0x03000000 +#endif + +#define SD_DEFNAME "sdcard0" +#define SD_DEFIOSIZE 4 +#define SD_NUMDEV 1 +#define SD_SHIFT 4 //max 16 partitions +#define SD_NUMPART 1 << 4 +#define SD_RAHEAD 0 +#define SD_BLKSIZE 1024 +#define SD_HARDSECT 512 + +#define DMA_ENABLE 1 +#define DMA_CHANNEL 10 +#define DMA_BUFSIZE 1024 +#define DMA_M2M_0_SIZE 0x40 +#define DMA_M2M_1_SIZE 0x40 + +static unsigned char *name = SD_DEFNAME; +static unsigned int io = TS7XXX_SDCARD1; +static int rahead = SD_RAHEAD; +static int hardsect = SD_HARDSECT; +static int dmaenable = 0; +static int dmach = 1; +static int sd_blocksizes[1 << SD_SHIFT]; + +MODULE_AUTHOR("Technologic Systems"); +MODULE_LICENSE("Proprietary"); +MODULE_PARM(io, "l"); +MODULE_PARM(name, "s"); +MODULE_PARM(rahead, "i"); +MODULE_PARM(dmach, "l"); +MODULE_PARM(dmaenable, "l"); + +struct sdcarddev { + + struct sdcore sc_sdcore; + + int sdcard_size; + int sdcard_sizes[SD_NUMPART]; + int sdcard_hardsect_sizes[SD_NUMPART]; + struct hd_struct sdcard_partitions[SD_NUMPART]; + struct gendisk sdcard_gendisk; + devfs_handle_t devfs_handle; + + struct timer_list timer; + spinlock_t lock; + + int irq; + unsigned long dmaregs; + int dmach; + + int busy, thread, parksect; +}; + +static struct sdcarddev *sc; +static struct block_device_operations sdcard_bdops; + +DECLARE_WAIT_QUEUE_HEAD (qthr); +DECLARE_WAIT_QUEUE_HEAD (qdma); + + +#define DMA_DECLBASE(x) unsigned int dmaregs = (x); +#define DMA_WRITE(x, y) *(volatile uint32_t *)(dmaregs + M2M_OFFSET_ ## x) = (y) +#define DMA_READ(x) *(volatile uint32_t *)(dmaregs + M2M_OFFSET_ ## x) + + +static void int_handler(int irq, void *dev_id, struct pt_regs * regs) +{ + struct sdcarddev *scarg = (struct sdcarddev *)dev_id; + DMA_DECLBASE(scarg->dmaregs); + + DMA_WRITE(INTERRUPT, 0x0); + wake_up_interruptible(&qdma); + + return; +} + +pte_t * vmalloc_to_pte(void * vmalloc_addr) +{ + unsigned long addr = (unsigned long) vmalloc_addr; + volatile int *v = *(int *)vmalloc_addr; + pmd_t *pmd; + pte_t *pte = NULL; + pgd_t *pgd; + + pgd = pgd_offset_k(addr); + if (!pgd_none(*pgd)) { + pmd = pmd_offset(pgd, addr); + if (!pmd_none(*pmd)) { + pte = pte_offset(pmd, addr); + } + } + return pte; +} + + +static int sdcard_dmastream(void *os_arg, unsigned char *dat, unsigned int buflen) +{ + struct sdcarddev *scarg = (struct sdcarddev *)os_arg; + int i; + unsigned int s; + DMA_DECLBASE(scarg->dmaregs); + static unsigned char dummymem[8]; + static unsigned long dummymem_paddr = 0; + static unsigned char bufmem[520]; + + //udelay(2000); + //udelay(10000); + + // s = inl(SMCBCR1); + //outl(0x8602, SMCBCR1); + DMA_WRITE(CONTROL, 0x11085000); + DMA_WRITE(SAR_BASE0, io|SDDAT ); + + if (dat) { + // pte_t *pte = vmalloc_to_pte(bufmem); + //unsigned long paddr = pte_pfn(*pte) << PAGE_SHIFT; + /* paddr += (unsigned long)bufmem & 0xfff; + */ + + // DMA_WRITE(DAR_BASE0, virt_to_bus(dat)); + /* + printk("dat:%x, paddr:%x, *pte:%x, pte:%x\n", dat, paddr, *pte, pte); + printk("virt_to_bus:%x\n", virt_to_bus(dat)); + */ + //printk("%x=>%x\n", dat, virt_to_bus(dat)); + //paddr = virt_to_bus(dat); + DMA_WRITE(DAR_BASE0, virt_to_bus(dat)); + } + else { + /* + struct page *pg = vmalloc_to_page(dummymem); + unsigned long pfn = page_to_pfn(pg); + unsigned int node = PFN_TO_NID(pfn); + struct pglist_data *nd = NODE_DATA(node); + unsigned long paddr = nd->node_start_paddr; + unsigned long off = pg - NODE_MEM_MAP(node); + paddr += (off << PAGE_SHIFT) + ((unsigned long)dummymem & 0xfff); + */ + if (dummymem_paddr == 0) { + pte_t *pte = vmalloc_to_pte(dummymem); + dummymem_paddr = pte_pfn(*pte) << PAGE_SHIFT; + dummymem_paddr += (unsigned long)dummymem & 0xfff; + } + + DMA_WRITE(DAR_BASE0, dummymem_paddr); + } + + DMA_WRITE(BCR0, buflen); + +// if (buflen > 8) { +// DMA_WRITE(CONTROL, 0x1108500c); +// interruptible_sleep_on(&qdma); +// if (signal_pending (current)) +// return 1; +// } else { + DMA_WRITE(CONTROL, 0x11085008); + while (!(DMA_READ(STATUS) & 0x40)); + DMA_WRITE(INTERRUPT, 0x0); +// } + // outl(s, SMCBCR1); + /* printk("--\n"); + for (i = 0; i < (buflen / 16); i++) { + int j; + for (j = 0; j < 16; j++) { + printk("%02x ", bufmem[(i * 16) + j]); + } + printk("\n"); + } + */ + + return 0; +} + + +static int sdcard_dmaprep(void *os_arg, unsigned char *buf, unsigned int buflen) +{ + invalidate_dcache_range(buf, buf + buflen); + return 0; +} + + +static void sdcard_delay(void *arg, unsigned int us) +{ + udelay(us); +} + + +static int sdcard_open(struct inode *inode, struct file *filp) +{ + MOD_INC_USE_COUNT; + return 0; +} + + +static int sdcard_release(struct inode *inode, struct file *filp) +{ + MOD_DEC_USE_COUNT; + return 0; +} + + +static int sdcard_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) +{ + int err; + struct hd_geometry geo; + + switch (cmd) { + case HDIO_GETGEO: + /* + * get geometry: we have to fake one... trim the size to a + * multiple of 512 (256k): tell we have 32 sectors, 16 heads, + * whatever cylinders. + */ + + // TODO: This should match what the SD cards look like in a + // USB adapter dongle. -- JO + + err = !access_ok(VERIFY_WRITE, arg, sizeof(geo)); + if (err) + return -EFAULT; + + geo.cylinders = sc->sdcard_size / (16 * 32); + geo.heads = 16; + geo.sectors = 32; + geo.start = 0; + + if (copy_to_user((void *) arg, &geo, sizeof(geo))) + return -EFAULT; + + return 0; + + default: + /* + * For ioctls we don't understand, let the block layer handle them. + */ + return blk_ioctl(inode->i_rdev, cmd, arg); + } + + return -ENOTTY; +} + + +static int sdcard_check_change(kdev_t i_rdev) +{ + return 0; +} + + + +static int sdcard_revalidate(kdev_t i_rdev) +{ + /* first clear old partition information */ + memset(sc->sdcard_gendisk.sizes+1, 0, (sc->sdcard_gendisk.max_p-1)*sizeof(int)); + memset(sc->sdcard_gendisk.part+1, 0, (sc->sdcard_gendisk.max_p-1)*sizeof(struct hd_struct)); + + sc->sdcard_size = sc->sdcard_gendisk.part[0].nr_sects = sdreset(&sc->sc_sdcore); + + /* then fill new info */ + register_disk(&sc->sdcard_gendisk, i_rdev, (sc->sdcard_gendisk.max_p), &sdcard_bdops, sc->sdcard_size); + + return 0; +} + + +static int sdcard_make_request(request_queue_t * q, int rw, struct buffer_head *bh) +{ + unsigned int ret = 0, sect; + static int busy = 0; + + if (busy++ != 0) panic("recursive make_request!\n"); + + sect = bh->b_rsector + sc->sdcard_partitions[MINOR(bh->b_rdev)].start_sect; + del_timer(&sc->timer); + + switch (rw) { + case READ: + case READA: + ret = sdread(&sc->sc_sdcore, sect, bh->b_data, bh->b_size / hardsect); + if (ret) { + sdreset(&sc->sc_sdcore); + ret = sdread(&sc->sc_sdcore, sect, bh->b_data, bh->b_size / hardsect); + } + //printk(KERN_INFO "r %db %x %x\n", bh->b_size, sc->sdcard_partitions[MINOR(bh->b_rdev)].start_sect, bh->b_rsector); + bh->b_end_io(bh, !ret); + sc->parksect = sect + (bh->b_size / hardsect) - 1; + break; + + case WRITE: + //refile_buffer(bh); + ret = sdwrite(&sc->sc_sdcore, sect, bh->b_data, bh->b_size / hardsect); + if (ret && !sc->sc_sdcore.sd_wprot) { + sdreset(&sc->sc_sdcore); + ret = sdwrite(&sc->sc_sdcore, sect, bh->b_data, bh->b_size / hardsect); + } + //printk(KERN_INFO "w %db %x %x\n", bh->b_size, sc->sdcard_partitions[MINOR(bh->b_rdev)].start_sect, bh->b_rsector); + if (ret == 0) mark_buffer_uptodate(bh, 1); + sc->timer.expires = jiffies + (HZ / 2); + add_timer(&sc->timer); + bh->b_end_io(bh, !ret); + break; + + default: + bh->b_end_io(bh, 0); + break; + } + busy--; + return 0; +} + + +static int sdcard_transfer(const struct request *req) +{ + unsigned int ret = 0; + int size; + u8 *ptr; + + del_timer(&sc->timer); + ptr = sc->sdcard_partitions[MINOR(req->rq_dev)].start_sect + req->sector; + size = req->current_nr_sectors * hardsect; + + switch(req->cmd) { + case READ: + ret = sdread(&sc->sc_sdcore, ptr, req->buffer, req->current_nr_sectors); + if (ret) { + sdreset(&sc->sc_sdcore); + ret = sdread(&sc->sc_sdcore, ptr, req->buffer, req->current_nr_sectors); + } + //printk(KERN_INFO "r%db,%x,%d\n", size, ptr, req->current_nr_sectors); + sc->parksect = ptr + req->current_nr_sectors - 1; + return !ret; + case WRITE: + //sc->sc_sdcore.sd_erasehint = req->current_nr_sectors; + ret = sdwrite(&sc->sc_sdcore, ptr, req->buffer, req->current_nr_sectors); + if (ret && !sc->sc_sdcore.sd_wprot) { + sdreset(&sc->sc_sdcore); + // sc->sc_sdcore.sd_erasehint = req->current_nr_sectors; + ret = sdwrite(&sc->sc_sdcore, ptr, req->buffer, req->current_nr_sectors); + } + //printk(KERN_INFO "w%db,%x,%d\n", size, ptr, req->current_nr_sectors); + sc->timer.expires = jiffies + HZ; + add_timer(&sc->timer); + return !ret; + default: + return 0; + } +} + +static void sdcard_processrequest(request_queue_t *q) { + struct request *req; + int status; + + spin_lock_irq (&io_request_lock); + + while(! list_empty(&q->queue_head)) { + + req = blkdev_entry_next_request(&q->queue_head); + blkdev_dequeue_request(req); + spin_unlock_irq (&io_request_lock); + + //printk(KERN_INFO "request thread %p: cmd %i sec %li (nr. %li)\n", req, req->cmd, req->sector, req->current_nr_sectors); + + spin_lock(&sc->lock); + do { + status = sdcard_transfer(req); + } while (end_that_request_first(req, status, name)); + spin_unlock(&sc->lock); + + spin_lock_irq (&io_request_lock); + end_that_request_last(req); + } + + spin_unlock_irq (&io_request_lock); +} + +static int sdcard_thread(void *data) +{ + daemonize(); + exit_files(current); + reparent_to_init(); + sprintf(current->comm, name); + + sc->busy = 0; + sc->thread = 1; + + for (;;) { + interruptible_sleep_on(&qthr); + if (signal_pending (current)) + return 0; + + sdcard_processrequest(&blk_dev[sdcard_major].request_queue); + + spin_lock(&sc->lock); + sc->busy = 0; + spin_unlock(&sc->lock); + } + + return 0; +} + + +static void sdcard_request(request_queue_t *q) +{ + if (sc->busy) + return; + + spin_lock(&sc->lock); + sc->busy = 1; + spin_unlock(&sc->lock); + + if (!sc->thread) { + sdcard_processrequest(q); + + spin_lock(&sc->lock); + sc->busy = 0; + spin_unlock(&sc->lock); + } + + else { + wake_up_interruptible(&qthr); + } + +} + +static struct block_device_operations sdcard_bdops = { + open: sdcard_open, + release: sdcard_release, + ioctl: sdcard_ioctl, + revalidate: sdcard_revalidate, + check_media_change: sdcard_check_change, +}; + +static void sdcommit(unsigned long *ptr) { + char buf[512]; + + sdread(&sc->sc_sdcore, sc->parksect, buf, 1); +} + +static int shutdownhook(struct notifier_block *NotifierBlock, + unsigned long Event, + void *Buffer) +{ + del_timer(&sc->timer); + if (!(Event == SYS_RESTART || Event == SYS_HALT || Event == SYS_POWER_OFF)) + return NOTIFY_DONE; + sdcommit(NULL); + return NOTIFY_OK; +} + +static struct notifier_block shutdownhook_notifier = { shutdownhook, NULL, 0 }; + +static int sdcard_init(void) +{ + unsigned int scratchreg0, i; + + /* + int model = inw(TS7XXX_MODEL) & 0x7; + int pldrev = inw(TS7XXX_PLDREV) & 0x7; + int opts = inw(0x02400000 + TS7XXX_IO16_BASE) & 0x7; + if (!((model == TS7260 && pldrev >= 5 && (opts & 0x4)) || model == TS7300)) { + printk("%s: no SD card option present on this board\n", name); + return 1; + } + */ + + printk("%s: Technologic Systems SD card controller, address 0x%x\n", name, io); + + sc = kmalloc(sizeof(struct sdcarddev), GFP_KERNEL); + memset(sc, 0, sizeof(struct sdcarddev)); + + + spin_lock_init(&sc->lock); + //kernel_thread(sdcard_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); + //kernel_thread(sdcard_thread, NULL, 0); + + + /*** DMA INIT ***/ + sc->irq = IRQ_DMAM2M1; + sc->dmach = DMA_CHANNEL; + + if (dmach) + sc->dmaregs = (unsigned long) __ioremap(DMA_M2M_1_BASE, DMA_M2M_1_SIZE, 0); + else + sc->dmaregs = (unsigned long) __ioremap(DMA_M2M_0_BASE, DMA_M2M_0_SIZE, 0); + + if (dmaenable) { + // request_irq(sc->irq, int_handler, SA_SHIRQ, name, sc); + sc->sc_sdcore.os_dmastream = sdcard_dmastream; + sc->sc_sdcore.os_dmaprep = sdcard_dmaprep; + + // Enable M2M DMA channel 1 power + outl(0xaa, SYSCON_SWLOCK); + if (dmach) + outl(inl(SYSCON_PWRCNT)|SYSCON_PWRCNT_DMA_M2MCH1, SYSCON_PWRCNT); + else + outl(inl(SYSCON_PWRCNT)|SYSCON_PWRCNT_DMA_M2MCH0, SYSCON_PWRCNT); + + // Enable M2M DMA channel 1 DRQ pins + outl(0xaa, SYSCON_SWLOCK); + if (dmach) + outl(inl(SYSCON_DEVCFG)|SYSCON_DEVCFG_D1onG, SYSCON_DEVCFG); + else + outl(inl(SYSCON_DEVCFG)|SYSCON_DEVCFG_D0onG, SYSCON_DEVCFG); + + // Speed up bus timing -- potentially breaks ISA bus cycles! ///? + //outl(0x8601, SMCBCR1); + + } + else { + sc->sc_sdcore.os_dmastream = NULL; + sc->sc_sdcore.os_dmaprep = NULL; + } + + sc->busy = 0; + sc->thread = 0; + sc->sc_sdcore.os_arg = sc; + sc->sc_sdcore.os_delay = sdcard_delay; + sc->sc_sdcore.sd_writeparking = 1; + + //sc->sc_sdcore.sd_regstart = (unsigned long) IO_ADDRESS(TS7XXX_IO8_BASE|SDCARD1_OFFSET); + sc->sc_sdcore.sd_regstart = (unsigned long) __ioremap(io, SD_DEFIOSIZE, 0); + + scratchreg0 = inl(SYSCON_SCRREG0); + if (scratchreg0) { + sc->sc_sdcore.sdboot_token = scratchreg0; + outl(0, SYSCON_SCRREG0); + } + + sc->sdcard_size = sdreset(&sc->sc_sdcore); + if (sc->sdcard_size == 0) { + printk("%s: no card found\n", name); + kfree(sc); + return 1; + } else { + printk("%s: card size %d sectors\n", name, sc->sdcard_size); + } + + init_timer(&sc->timer); + sc->timer.function = sdcommit; + sc->parksect = 0; + register_reboot_notifier(&shutdownhook_notifier); + + sdcard_major = register_blkdev(0, name, &sdcard_bdops); + sc->devfs_handle = devfs_mk_dir(NULL, name, NULL); + + sc->sdcard_gendisk.minor_shift = SD_SHIFT; + sc->sdcard_gendisk.max_p = SD_NUMPART; + sc->sdcard_gendisk.fops = &sdcard_bdops; + sc->sdcard_gendisk.major = sdcard_major; + sc->sdcard_gendisk.major_name = name; + sc->sdcard_gendisk.nr_real = SD_NUMDEV; + + for(i = 0; i < SD_NUMPART; i++) + sc->sdcard_hardsect_sizes[i] = 512; // sc->sc_sdcore.sd_blocksize; + memset(sc->sdcard_sizes, 0, sc->sdcard_gendisk.max_p*sizeof(int) ); + memset(sc->sdcard_partitions, 0, sc->sdcard_gendisk.max_p*sizeof(struct hd_struct) ); + sc->sdcard_sizes[0] = sc->sdcard_partitions[0].nr_sects = sc->sdcard_size; + sc->sdcard_gendisk.sizes = sc->sdcard_sizes; + sc->sdcard_gendisk.part = sc->sdcard_partitions; + + add_gendisk(&sc->sdcard_gendisk); + + blk_size[sdcard_major] = sc->sdcard_sizes; + hardsect_size[sdcard_major] = sc->sdcard_hardsect_sizes; + + for(i=0;i<(1 << SD_SHIFT);i++) + sd_blocksizes[i] = SD_BLKSIZE; + + blksize_size[sdcard_major] = sd_blocksizes; + read_ahead[sdcard_major] = rahead; + + blk_queue_make_request(BLK_DEFAULT_QUEUE(sdcard_major), sdcard_make_request); +// blk_init_queue(BLK_DEFAULT_QUEUE(sdcard_major), sdcard_request); + + register_disk(&sc->sdcard_gendisk, MKDEV(sdcard_major, 0), sc->sdcard_gendisk.max_p, &sdcard_bdops, sc->sdcard_size); + + EXPORT_NO_SYMBOLS; + + return 0; +} + + +static void sdcard_cleanup(void) +{ + fsync_dev(MKDEV(sdcard_major, 0)); + devfs_register_partitions(&sc->sdcard_gendisk, 0, 1); //unregister + unregister_blkdev(sdcard_major, name); + + del_gendisk(&sc->sdcard_gendisk); + blk_size[sdcard_major] = NULL; + + free_irq(sc->irq, name); + __iounmap((unsigned long *) sc->sc_sdcore.sd_regstart); + __iounmap((unsigned long *) sc->dmaregs); + __iounmap((unsigned char *) io); + + devfs_unregister(sc->devfs_handle); + + kfree(sc); +} + + +int init_module(void) +{ + return sdcard_init(); +} + + +void cleanup_module(void) +{ + return sdcard_cleanup(); +} + + Index: drivers/block/swim3.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/block/swim3.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/block/swim3.c 22 Jul 2004 19:50:11 -0000 1.1 +++ drivers/block/swim3.c 4 Aug 2004 01:28:39 -0000 1.2 @@ -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; Index: drivers/block/ts_sd.c =================================================================== RCS file: drivers/block/ts_sd.c diff -N drivers/block/ts_sd.c --- drivers/block/ts_sd.c 3 Feb 2006 20:36:40 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,606 +0,0 @@ -#include -#include -#include -#include /* printk() */ -#include /* kmalloc() */ -#include /* everything... */ -#include /* error codes */ -#include /* size_t */ -#include /* O_ACCMODE */ -#include /* HDIO_GETGEO */ -#include /* cli(), *_flags */ - -#include "sdcard.h" - -#define MAJOR_NR ts_sd_major /* force definitions on in blk.h */ -int ts_sd_major; /* must be declared before including blk.h */ - -#include "ts_sd.h" /* local definitions */ -#include -#include /* blk_ioctl() */ - -/* - * Non-prefixed symbols are static. They are meant to be assigned at - * load time. Prefixed symbols are not static, so they can be used in - * debugging. They are hidden anyways by register_symtab() unless - * TS_SD_DEBUG is defined. - */ - -#define TS_SD_SIZE 244 - -MODULE_AUTHOR("Someone"); -MODULE_LICENSE("GPL"); - -int ts_sd_devs, ts_sd_rahead, ts_sd_size; -int ts_sd_blksize, ts_sd_irq; - -/* The following items are obtained through kmalloc() in ts_sd_init() */ - -ts_sd_Dev *ts_sd_devices = NULL; -int *ts_sd_sizes = NULL; - -/* Forwards */ -int ts_sd_revalidate(kdev_t i_rdev); -struct block_device_operations ts_sd_bdops; - -/* - * Time for our genhd structure. - */ -struct gendisk ts_sd_gendisk = { - major: 0, /* Major number assigned later */ - major_name: "ts_sd", /* Name of the major device */ - minor_shift: TS_SD_SHIFT, /* Shift to get device number */ - max_p: 1 << TS_SD_SHIFT, /* Number of partitions */ - fops: &ts_sd_bdops, /* Block dev operations */ -/* everything else is dynamic */ -}; - -struct hd_struct *ts_sd_partitions = NULL; - -/* - * Open and close - */ - -int ts_sd_open (struct inode *inode, struct file *filp) -{ - - printk("ts_sd_open()\n"); - - ts_sd_Dev *dev; /* device information */ - int num = DEVICE_NR(inode->i_rdev); - - if (num >= ts_sd_devs) - return -ENODEV; - - dev = ts_sd_devices + num; - - spin_lock(&dev->lock); - - - - if (!dev->data) { - // dev->data = (void *)IO_ADDRESS(TS7XXX_IO8_BASE + 0x3000000); - /* - printk("vmalloc %d\n",ts_sd_blksize*ts_sd_size); - dev->data = vmalloc(ts_sd_blksize*ts_sd_size); - */ - } - /* - if (!dev->data) - { - printk("Error accessing SD card...\n"); - spin_unlock(&dev->lock); - return -ENOMEM; - } - */ - dev->usage++; - MOD_INC_USE_COUNT; - spin_unlock(&dev->lock); - - return 0; /* success */ -} - - - -int ts_sd_release (struct inode *inode, struct file *filp) -{ - printk("ts_sd_release()\n"); - - ts_sd_Dev *dev = ts_sd_devices + DEVICE_NR(inode->i_rdev); - - spin_lock(&dev->lock); - dev->usage--; - - if (!dev->usage) { - - /* but flush it right now */ - fsync_dev(inode->i_rdev); - invalidate_buffers(inode->i_rdev); - } - - MOD_DEC_USE_COUNT; - spin_unlock(&dev->lock); - - return 0; -} - - -/* - * The ioctl() implementation - */ - -int ts_sd_ioctl (struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - int err, size; - struct hd_geometry geo; - -printk("ts_sd_ioctl()\n"); - - switch(cmd) { - - case BLKGETSIZE: - -printk("BLKGETSIZE, arg = 0x%lx\n", arg); - /* Return the device size, expressed in sectors */ - err = ! access_ok (VERIFY_WRITE, arg, sizeof(long)); - if (err) - return -EFAULT; - - size = ts_sd_gendisk.part[MINOR(inode->i_rdev)].nr_sects; - - if (copy_to_user((long *) arg, &size, sizeof (long))) - return -EFAULT; - return 0; - - case BLKFLSBUF: /* flush */ - -printk("BLKLSBUF, arg = 0x%lx\n", arg); - if (! capable(CAP_SYS_RAWIO)) - return -EACCES; /* only root */ - - fsync_dev(inode->i_rdev); - invalidate_buffers(inode->i_rdev); - - return 0; - - case BLKRAGET: /* return the readahead value */ - -printk("BLKRAGET, arg = 0x%lx\n", arg); - err = ! access_ok(VERIFY_WRITE, arg, sizeof(long)); - - if (err) - return -EFAULT; - - put_user(read_ahead[MAJOR(inode->i_rdev)],(long *) arg); - - return 0; - - case BLKRASET: /* set the readahead value */ - -printk("BLKRASET, arg = 0x%lx\n", arg); - - if (!capable(CAP_SYS_RAWIO)) - return -EACCES; - - if (arg > 0xff) - return -EINVAL; /* limit it */ - - read_ahead[MAJOR(inode->i_rdev)] = arg; - - return 0; - - case BLKRRPART: /* re-read partition table */ - -printk("BLKRRPART, arg = 0x%lx\n", arg); - - return ts_sd_revalidate(inode->i_rdev); - - case HDIO_GETGEO: - -printk("HDIO_GETGEO, arg = 0x%lx\n", arg); - - /* - * get geometry: we have to fake one... trim the size to a - * multiple of 64 (32k): tell we have 16 sectors, 4 heads, - * whatever cylinders. Tell also that data starts at sector. 4. - */ - - err = ! access_ok(VERIFY_WRITE, arg, sizeof(geo)); - if (err) - return -EFAULT; - -size = ts_sd_size * ts_sd_blksize / TS_SD_HARDSECT; -geo.cylinders = (size & ~0x3f) >> 6; -geo.heads = 4; -geo.sectors = 16; -geo.start = 0; - - if (copy_to_user((void *) arg, &geo, sizeof(geo))) - return -EFAULT; - - return 0; - - default: - /* - * For ioctls we don't understand, let the block layer handle them. - */ - - return blk_ioctl(inode->i_rdev, cmd, arg); - } - - return -ENOTTY; /* unknown command */ -} - -/* - * Support for removable devices - */ - -int ts_sd_check_change(kdev_t i_rdev) -{ - int minor = DEVICE_NR(i_rdev); - -printk("ts_sd_check_change()\n"); - -// ts_sd_Dev *dev = ts_sd_devices + minor; - - if (minor >= ts_sd_devs) /* paranoid */ - return 0; - -PDEBUG("check_change for dev %i\n",minor); - -//EWD: how do we check if the device is still present? - - return 0; /* still valid */ - -} - - -/* - * The file operations - */ - -struct block_device_operations ts_sd_bdops = { - open: ts_sd_open, - release: ts_sd_release, - ioctl: ts_sd_ioctl, - revalidate: ts_sd_revalidate, - check_media_change: ts_sd_check_change, -}; - - -/* - * Note no locks taken out here. In a worst case scenario, we could drop - * a chunk of system memory. But that should never happen, since validation - * happens at open or mount time, when locks are held. - */ -int ts_sd_revalidate(kdev_t i_rdev) -{ - /* first partition, # of partitions */ - // int part1 = (DEVICE_NR(i_rdev) << TS_SD_SHIFT) + 1; - // int npart = (1 << TS_SD_SHIFT) -1; - -printk("ts_sd_revalidate()\n"); - - /* first clear old partition information */ -// memset(ts_sd_gendisk.sizes+part1, 0, npart*sizeof(int)); -// memset(ts_sd_gendisk.part +part1, 0, npart*sizeof(struct hd_struct)); - - ts_sd_gendisk.part[DEVICE_NR(i_rdev) << TS_SD_SHIFT].nr_sects = - ts_sd_size << 1; - - /* then fill new info */ - printk(KERN_INFO "ts_sd partition check: (%d) ", DEVICE_NR(i_rdev)); - register_disk(&ts_sd_gendisk, i_rdev, TS_SD_MAXNRDEV, &ts_sd_bdops, - ts_sd_size << 1); - - return 0; -} - -/* - * Block-driver specific functions - */ - -/* - * Find the device for this request. - */ -/* -static ts_sd_Dev *ts_sd_locate_device(const struct request *req) -{ - int devno; - -printk("ts_sd_locate_device()\n"); - - ts_sd_Dev *device; - - // Check if the minor number is in range - devno = DEVICE_NR(req->rq_dev); - - if (devno >= ts_sd_devs) - { - static int count = 0; - - if (count++ < 5) // print the message at most five times - printk(KERN_WARNING - "ts_sd: request for unknown device\n"); - return NULL; - } - - device = ts_sd_devices + devno; - - return device; -} -*/ - -int ts_sd_make_request(request_queue_t *q, int rw, struct buffer_head *bh) { - ts_sd_Dev *device; - u8 *ptr; - static int i=0; - - device = ts_sd_devices + MINOR(bh->b_rdev); - // device->data points to the buffer we use as ram disk - ptr = device->data + (8192 + bh->b_rsector) * TS_SD_HARDSECT; - - if (ptr + bh->b_size > device->data + ts_sd_blksize*ts_sd_size) { - static int count = 0; - if (count++ < 4) { - printk(KERN_WARNING "ts_sd: request past end of partition\n"); - bh->b_end_io(bh,0); - return 0; - } - } - - switch(rw) { // Do the transfer - case READ: - case READA: // Readahead - // next version will take a sector address -// printk("%d:open read @%p to %p for %p\n",i++,(int)ptr,bh->b_data,bh->b_size); - if (1 || i < 10 || i == 22) { - sd_readblks((int)ptr,bh->b_data,bh->b_size); - } - printk("close read\n"); - bh->b_end_io(bh, 1); - printk("end read\n"); - break; - case WRITE: - refile_buffer(bh); - sd_writeblks((int)ptr,bh->b_data,bh->b_size); - mark_buffer_uptodate(bh, 1); - bh->b_end_io(bh, 1); - break; - default: // can't happen - bh->b_end_io(bh, 0); - break; - } - return 0; -} - -void getSDSize(int *blksize,int *blocks) { - unsigned char csd[18]; - unsigned char *start; - int csize, csize_mult, read_bl_len; - - start = (void *)IO_ADDRESS(TS7XXX_IO8_BASE + 0x3000000); - init_sd(start, csd); - - csize = ((csd[7] & 0x03) << 10) | ((csd[8] << 2) | - ((csd[9] & 0xc0) >> 6)); - csize_mult = ((csd[10] & 0x03) << 1) | ((csd[11] & 0x80) >> 7); - read_bl_len = (csd[6] & 0x0F); - - *blksize = 1 << read_bl_len; - - *blocks = (csize + 1) * (1 << (csize_mult + 2)); - printk("SD card: %d blocks of %d bytes each\n",*blocks,*blksize); -} - -/* - * Finally, the module stuff - */ - -int ts_sd_init(void) -{ - int result, i; -printk("ts_sd_init\n"); - getSDSize(&ts_sd_blksize,&ts_sd_size); - - ts_sd_major = TS_SD_MAJOR; - ts_sd_devs = TS_SD_DEVS; - ts_sd_rahead = TS_SD_RAHEAD; - - result = register_blkdev(ts_sd_major, "ts_sd", &ts_sd_bdops); - - if (result < 0) { - printk(KERN_WARNING "ts_sd: can't get major %d\n",ts_sd_major); - return result; - } - - if (ts_sd_major == 0) { - ts_sd_major = result; // dynamic - } - - ts_sd_gendisk.major = ts_sd_major; /* was unknown at load time */ - ts_sd_devices = kmalloc(ts_sd_devs * sizeof (ts_sd_Dev), GFP_KERNEL); - - if (!ts_sd_devices) { - goto fail_malloc; - } - memset(ts_sd_devices, 0, ts_sd_devs * sizeof (ts_sd_Dev)); - - for (i=0; i < ts_sd_devs; i++) { - ts_sd_devices[i].size = ts_sd_size; - spin_lock_init(&ts_sd_devices[i].lock); - } - - /* - * Assign the other needed values: request, rahead, size, blksize, - * hardsect. All the minor devices feature the same value. - * Note that `ts_sd' defines all of them to allow testing non-default - * values. A real device could well avoid setting values in global - * arrays if it uses the default values. - */ - - read_ahead[ts_sd_major] = ts_sd_rahead; - result = -ENOMEM; // for the possible errors - - ts_sd_sizes = kmalloc((ts_sd_devs << TS_SD_SHIFT) * sizeof(int),GFP_KERNEL); - - if (!ts_sd_sizes) { - goto fail_malloc; - } - - // Start with zero-sized partitions, and correctly sized units - memset(ts_sd_sizes, 0, (ts_sd_devs << TS_SD_SHIFT) * sizeof(int)); - - for (i=0; i< ts_sd_devs; i++) { - ts_sd_sizes[i<ts_sd: init complete, %d devs, size %d blks %d\n", - ts_sd_devs, ts_sd_size, ts_sd_blksize); - - return 0; /* succeed */ - - fail_malloc: - printk("ts_sd fatal: unable to allocate memory!\n"); - - read_ahead[ts_sd_major] = 0; - if (ts_sd_sizes) { - kfree(ts_sd_sizes); - } - if (ts_sd_partitions) { - kfree(ts_sd_partitions); - } - blk_size[ts_sd_major] = NULL; - - if (ts_sd_devices) { - kfree(ts_sd_devices); - ts_sd_devices = NULL; - } - unregister_blkdev(ts_sd_major, "ts_sd"); - - return result; -} - -void ts_sd_cleanup(void) -{ - int i; - struct gendisk **gdp; -printk("ts_sd_cleanup\n"); - /* - * Before anything else, get rid of the timer functions. Set the "usage" - * flag on each device as well, under lock, so that if the timer fires up - * just before we delete it, it will either complete or abort. Otherwise - * we have nasty race conditions to worry about. - */ - for (i = 0; i < ts_sd_devs; i++) { - ts_sd_Dev *dev = ts_sd_devices + i; - spin_lock(&dev->lock); - dev->usage++; - spin_unlock(&dev->lock); - } -printk("ts_sd_cleanup1\n"); - - /* flush it all and reset all the data structures */ - for (i=0; isizes as well */ - blk_size[ts_sd_major] = NULL; - } -printk("ts_sd_cleanup2c\n"); - if (ts_sd_gendisk.part) { - kfree(ts_sd_gendisk.part); - } -printk("ts_sd_cleanup2d\n"); - if (blksize_size[ts_sd_major]) { - kfree(blksize_size[ts_sd_major]); - blksize_size[ts_sd_major] = NULL; - } -printk("ts_sd_cleanup3\n"); - - /* - * Get our gendisk structure off the list. - */ - for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next)) { - if (*gdp == &ts_sd_gendisk) { - *gdp = (*gdp)->next; - break; - } - } -printk("ts_sd_cleanup4\n"); - /* finally, the usual cleanup */ - for (i=0; i < ts_sd_devs; i++) { - // Free the ramdisk memory - if (ts_sd_devices[i].data) { - vfree(ts_sd_devices[i].data); - } - kfree(ts_sd_devices); - } -printk("ts_sd_cleanup5\n"); - -} - -int init_module(void) { - return ts_sd_init(); -} - -void cleanup_module(void) { - return ts_sd_cleanup(); -} - Index: drivers/block/ts_sd.h =================================================================== RCS file: drivers/block/ts_sd.h diff -N drivers/block/ts_sd.h --- drivers/block/ts_sd.h 3 Feb 2006 20:36:40 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,57 +0,0 @@ -#include -#include -#include -#include -#include - -#define TS_SD_DEBUG - -/* - * Macros to help debugging - */ - -#undef PDEBUG /* undef it, just in case */ -#ifdef TS_SD_DEBUG -# ifdef __KERNEL__ - /* This one if debugging is on, and kernel space */ -# define PDEBUG(fmt, args...) printk( KERN_DEBUG "ts_sd: " fmt, ## args) -# else - /* This one for user space */ -# define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args) -# endif -#else -# define PDEBUG(fmt, args...) /* not debugging: nothing */ -#endif - -#undef PDEBUGG -#define PDEBUGG(fmt, args...) /* nothing: it's a placeholder */ - - -#define TS_SD_MAJOR 0 /* dynamic major by default */ -#define TS_SD_DEVS 1 /* two disks */ -#define TS_SD_RAHEAD 1 /* two sectors */ -//#define TS_SD_BLKSIZE 512 -#define TS_SD_HARDSECT 512 /* 512-byte hardware sectors */ - -#define TS_SD_SHIFT 4 /* max 16 partitions */ -#define TS_SD_MAXNRDEV 4 /* max 4 device units */ -#define DEVICE_NR(device) (MINOR(device)>>TS_SD_SHIFT) -#define DEVICE_NAME "pd" /* name for messaging */ -#define DEVICE_INTR ts_sd_intrptr /* pointer to the bottom half */ -#define DEVICE_NO_RANDOM /* no entropy to contribute */ -#define DEVICE_REQUEST ts_sd_request -#define DEVICE_OFF(d) /* do-nothing */ - -/* - * The ts_sd device is removable: if it is left closed for more than - * half a minute, it is removed. Thus use a usage count and a - * kernel timer - */ - -typedef struct ts_sd_Dev { - int size; - int usage; - struct timer_list timer; - spinlock_t lock; - u8 *data; -} ts_sd_Dev; Index: drivers/block/umem.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/block/umem.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/block/umem.c 22 Jul 2004 19:50:12 -0000 1.1 +++ drivers/block/umem.c 4 Aug 2004 01:28:39 -0000 1.2 @@ -1307,7 +1307,7 @@ release_mem_region(card->mem_base, card->mem_len); failed_req_mem: #endif - iounmap((void *) card->csr_base); + iounmap((void *) card->csr_remap); failed_remap_csr: release_mem_region(card->csr_base, card->csr_len); failed_req_csr: Index: drivers/block/paride/bpck6.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/block/paride/bpck6.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/block/paride/bpck6.c 22 Jul 2004 19:50:12 -0000 1.1 +++ drivers/block/paride/bpck6.c 4 Aug 2004 01:28:39 -0000 1.2 @@ -194,11 +194,11 @@ if(out) { ppc6_close(PPCSTRUCT(pi)); - return(1); if(verbose) { printk(KERN_DEBUG "leaving probe\n"); } + return(1); } else { Index: drivers/bluetooth/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/bluetooth/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/bluetooth/Config.in 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/bluetooth/Config.in 4 Aug 2004 01:28:39 -0000 1.2 @@ -7,8 +7,7 @@ dep_tristate 'HCI USB driver' CONFIG_BLUEZ_HCIUSB $CONFIG_BLUEZ $CONFIG_USB if [ "$CONFIG_BLUEZ_HCIUSB" != "n" ]; then - bool ' SCO (voice) support' CONFIG_BLUEZ_USB_SCO - bool ' USB zero packet support' CONFIG_BLUEZ_USB_ZERO_PACKET + bool ' SCO (voice) support' CONFIG_BLUEZ_HCIUSB_SCO fi dep_tristate 'HCI UART driver' CONFIG_BLUEZ_HCIUART $CONFIG_BLUEZ @@ -18,6 +17,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 Index: drivers/bluetooth/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/bluetooth/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/bluetooth/Makefile 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/bluetooth/Makefile 4 Aug 2004 01:28:39 -0000 1.2 @@ -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 Index: drivers/bluetooth/hci_bcsp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/bluetooth/hci_bcsp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/bluetooth/hci_bcsp.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/bluetooth/hci_bcsp.c 4 Aug 2004 01:28:39 -0000 1.2 @@ -25,7 +25,7 @@ */ /* - * $Id: hci_bcsp.c,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: hci_bcsp.c,v 1.2 2004/08/04 01:28:39 joff Exp $ */ #define VERSION "0.1" Index: drivers/bluetooth/hci_bcsp.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/bluetooth/hci_bcsp.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/bluetooth/hci_bcsp.h 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/bluetooth/hci_bcsp.h 4 Aug 2004 01:28:39 -0000 1.2 @@ -25,7 +25,7 @@ */ /* - * $Id: hci_bcsp.h,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: hci_bcsp.h,v 1.2 2004/08/04 01:28:39 joff Exp $ */ #ifndef __HCI_BCSP_H__ Index: drivers/bluetooth/hci_h4.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/bluetooth/hci_h4.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/bluetooth/hci_h4.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/bluetooth/hci_h4.c 4 Aug 2004 01:28:39 -0000 1.2 @@ -25,7 +25,7 @@ /* * BlueZ HCI UART(H4) protocol. * - * $Id: hci_h4.c,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: hci_h4.c,v 1.2 2004/08/04 01:28:39 joff Exp $ */ #define VERSION "1.2" Index: drivers/bluetooth/hci_h4.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/bluetooth/hci_h4.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/bluetooth/hci_h4.h 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/bluetooth/hci_h4.h 4 Aug 2004 01:28:39 -0000 1.2 @@ -23,7 +23,7 @@ */ /* - * $Id: hci_h4.h,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: hci_h4.h,v 1.2 2004/08/04 01:28:39 joff Exp $ */ #ifdef __KERNEL__ Index: drivers/bluetooth/hci_ldisc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/bluetooth/hci_ldisc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/bluetooth/hci_ldisc.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/bluetooth/hci_ldisc.c 4 Aug 2004 01:28:39 -0000 1.2 @@ -25,7 +25,7 @@ /* * BlueZ HCI UART driver. * - * $Id: hci_ldisc.c,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: hci_ldisc.c,v 1.2 2004/08/04 01:28:39 joff Exp $ */ #define VERSION "2.1" Index: drivers/bluetooth/hci_uart.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/bluetooth/hci_uart.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/bluetooth/hci_uart.h 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/bluetooth/hci_uart.h 4 Aug 2004 01:28:39 -0000 1.2 @@ -23,7 +23,7 @@ */ /* - * $Id: hci_uart.h,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: hci_uart.h,v 1.2 2004/08/04 01:28:39 joff Exp $ */ #ifndef N_HCI Index: drivers/bluetooth/hci_usb.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/bluetooth/hci_usb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/bluetooth/hci_usb.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/bluetooth/hci_usb.c 4 Aug 2004 01:28:39 -0000 1.2 @@ -28,9 +28,9 @@ * Copyright (c) 2000 Greg Kroah-Hartman * Copyright (c) 2000 Mark Douglas Corner * - * $Id: hci_usb.c,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: hci_usb.c,v 1.2 2004/08/04 01:28:39 joff Exp $ */ -#define VERSION "2.4" +#define VERSION "2.5" #include #include @@ -62,7 +62,7 @@ #define BT_DMP( A... ) #endif -#ifndef CONFIG_BLUEZ_USB_ZERO_PACKET +#ifndef CONFIG_BLUEZ_HCIUSB_ZERO_PACKET #undef USB_ZERO_PACKET #define USB_ZERO_PACKET 0 #endif @@ -73,9 +73,15 @@ /* Generic Bluetooth USB device */ { USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) }, + /* AVM BlueFRITZ! USB v2.0 */ + { USB_DEVICE(0x057c, 0x3800) }, + /* Ericsson with non-standard id */ { USB_DEVICE(0x0bdb, 0x1002) }, + /* ALPS Module with non-standard id */ + { USB_DEVICE(0x044e, 0x3002) }, + /* Bluetooth Ultraport Module from IBM */ { USB_DEVICE(0x04bf, 0x030a) }, @@ -84,9 +90,15 @@ MODULE_DEVICE_TABLE (usb, bluetooth_ids); -static struct usb_device_id ignore_ids[] = { +static struct usb_device_id blacklist_ids[] = { /* Broadcom BCM2033 without firmware */ - { USB_DEVICE(0x0a5c, 0x2033) }, + { USB_DEVICE(0x0a5c, 0x2033), driver_info: HCI_IGNORE }, + + /* Broadcom BCM2035 */ + { USB_DEVICE(0x0a5c, 0x200a), driver_info: HCI_RESET }, + + /* Digianswer device */ + { USB_DEVICE(0x08fd, 0x0001), driver_info: HCI_DIGIANSWER }, { } /* Terminating entry */ }; @@ -133,6 +145,7 @@ return _urb_dequeue(__completed_q(husb, type)); } +#ifdef CONFIG_BLUEZ_HCIUSB_SCO static void __fill_isoc_desc(struct urb *urb, int len, int mtu) { int offset = 0, i; @@ -152,6 +165,7 @@ } urb->number_of_packets = i; } +#endif static int hci_usb_intr_rx_submit(struct hci_usb *husb) { @@ -229,7 +243,7 @@ return err; } -#ifdef CONFIG_BLUEZ_USB_SCO +#ifdef CONFIG_BLUEZ_HCIUSB_SCO static int hci_usb_isoc_rx_submit(struct hci_usb *husb) { struct _urb *_urb; @@ -300,8 +314,10 @@ for (i = 0; i < HCI_MAX_BULK_RX; i++) hci_usb_bulk_rx_submit(husb); -#ifdef CONFIG_BLUEZ_USB_SCO - hci_usb_isoc_rx_submit(husb); +#ifdef CONFIG_BLUEZ_HCIUSB_SCO + if (husb->isoc_iface) + for (i = 0; i < HCI_MAX_ISOC_RX; i++) + hci_usb_isoc_rx_submit(husb); #endif } else { clear_bit(HCI_RUNNING, &hdev->flags); @@ -426,7 +442,7 @@ } else dr = (void *) _urb->urb.setup_packet; - dr->bRequestType = HCI_CTRL_REQ; + dr->bRequestType = husb->ctrl_req; dr->bRequest = 0; dr->wIndex = 0; dr->wValue = 0; @@ -467,7 +483,7 @@ return __tx_submit(husb, _urb); } -#ifdef CONFIG_BLUEZ_USB_SCO +#ifdef CONFIG_BLUEZ_HCIUSB_SCO static inline int hci_usb_send_isoc(struct hci_usb *husb, struct sk_buff *skb) { struct _urb *_urb = __get_completed(husb, skb->pkt_type); @@ -518,10 +534,10 @@ skb_queue_head(q, skb); } -#ifdef CONFIG_BLUEZ_USB_SCO +#ifdef CONFIG_BLUEZ_HCIUSB_SCO /* Process SCO queue */ q = __transmit_q(husb, HCI_SCODATA_PKT); - if (!atomic_read(__pending_tx(husb, HCI_SCODATA_PKT)) && + if (atomic_read(__pending_tx(husb, HCI_SCODATA_PKT)) < HCI_MAX_ISOC_TX && (skb = skb_dequeue(q))) { if (hci_usb_send_isoc(husb, skb) < 0) skb_queue_head(q, skb); @@ -577,7 +593,7 @@ hdev->stat.acl_tx++; break; -#ifdef CONFIG_BLUEZ_USB_SCO +#ifdef CONFIG_BLUEZ_HCIUSB_SCO case HCI_SCODATA_PKT: hdev->stat.sco_tx++; break; @@ -627,7 +643,7 @@ } else return -EILSEQ; break; -#ifdef CONFIG_BLUEZ_USB_SCO +#ifdef CONFIG_BLUEZ_HCIUSB_SCO case HCI_SCODATA_PKT: if (count >= HCI_SCO_HDR_SIZE) { hci_sco_hdr *h = data; @@ -638,7 +654,7 @@ #endif } BT_DBG("new packet len %d", len); - + skb = bluez_skb_alloc(len, GFP_ATOMIC); if (!skb) { BT_ERR("%s no memory for the packet", husb->hdev.name); @@ -692,7 +708,7 @@ goto resubmit; if (_urb->type == HCI_SCODATA_PKT) { -#ifdef CONFIG_BLUEZ_USB_SCO +#ifdef CONFIG_BLUEZ_HCIUSB_SCO int i; for (i=0; i < urb->number_of_packets; i++) { BT_DBG("desc %d status %d offset %d len %d", i, @@ -786,8 +802,14 @@ iface = &udev->actconfig->interface[0]; - /* Check our black list */ - if (usb_match_id(udev, iface, ignore_ids)) + if (!id->driver_info) { + const struct usb_device_id *match; + match = usb_match_id(udev, iface, blacklist_ids); + if (match) + id = match; + } + + if (id->driver_info & HCI_IGNORE) return NULL; /* Check number of endpoints */ @@ -827,9 +849,9 @@ bulk_out_ep[i] = ep; break; -#ifdef CONFIG_BLUEZ_USB_SCO +#ifdef CONFIG_BLUEZ_HCIUSB_SCO case USB_ENDPOINT_XFER_ISOC: - if (ep->wMaxPacketSize < size) + if (ep->wMaxPacketSize < size || a > 2) break; size = ep->wMaxPacketSize; @@ -853,7 +875,7 @@ goto done; } -#ifdef CONFIG_BLUEZ_USB_SCO +#ifdef CONFIG_BLUEZ_HCIUSB_SCO if (!isoc_in_ep[1] || !isoc_out_ep[1]) { BT_DBG("Isoc endpoints not found"); isoc_iface = NULL; @@ -872,7 +894,12 @@ husb->bulk_in_ep = bulk_in_ep[0]; husb->intr_in_ep = intr_in_ep[0]; -#ifdef CONFIG_BLUEZ_USB_SCO + if (id->driver_info & HCI_DIGIANSWER) + husb->ctrl_req = HCI_DIGI_REQ; + else + husb->ctrl_req = HCI_CTRL_REQ; + +#ifdef CONFIG_BLUEZ_HCIUSB_SCO if (isoc_iface) { BT_DBG("isoc ifnum %d alts %d", isoc_ifnum, isoc_alts); if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) { @@ -906,6 +933,9 @@ hdev->send = hci_usb_send_frame; hdev->destruct = hci_usb_destruct; + if (id->driver_info & HCI_RESET) + set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks); + if (hci_register_dev(hdev) < 0) { BT_ERR("Can't register HCI device"); goto probe_error; @@ -968,6 +998,6 @@ module_init(hci_usb_init); module_exit(hci_usb_cleanup); -MODULE_AUTHOR("Maxim Krasnyansky "); +MODULE_AUTHOR("Maxim Krasnyansky , Marcel Holtmann "); MODULE_DESCRIPTION("BlueZ HCI USB driver ver " VERSION); MODULE_LICENSE("GPL"); Index: drivers/bluetooth/hci_usb.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/bluetooth/hci_usb.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/bluetooth/hci_usb.h 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/bluetooth/hci_usb.h 4 Aug 2004 01:28:39 -0000 1.2 @@ -24,7 +24,7 @@ */ /* - * $Id: hci_usb.h,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: hci_usb.h,v 1.2 2004/08/04 01:28:39 joff Exp $ */ #ifdef __KERNEL__ @@ -35,12 +35,20 @@ #define HCI_DEV_PROTOCOL 0x01 /* Bluetooth programming protocol */ #define HCI_CTRL_REQ 0x20 +#define HCI_DIGI_REQ 0x40 + +#define HCI_IGNORE 0x01 +#define HCI_RESET 0x02 +#define HCI_DIGIANSWER 0x04 #define HCI_MAX_IFACE_NUM 3 #define HCI_MAX_BULK_TX 4 #define HCI_MAX_BULK_RX 1 +#define HCI_MAX_ISOC_RX 2 +#define HCI_MAX_ISOC_TX 2 + #define HCI_MAX_ISOC_FRAMES 10 struct _urb_queue { @@ -119,6 +127,8 @@ struct usb_endpoint_descriptor *isoc_out_ep; struct usb_endpoint_descriptor *isoc_in_ep; + __u8 ctrl_req; + struct sk_buff_head transmit_q[4]; struct sk_buff *reassembly[4]; // Reassembly buffers Index: drivers/bluetooth/hci_vhci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/bluetooth/hci_vhci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/bluetooth/hci_vhci.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/bluetooth/hci_vhci.c 4 Aug 2004 01:28:39 -0000 1.2 @@ -25,7 +25,7 @@ /* * BlueZ HCI virtual device driver. * - * $Id: hci_vhci.c,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: hci_vhci.c,v 1.2 2004/08/04 01:28:39 joff Exp $ */ #define VERSION "1.1" Index: drivers/bluetooth/hci_vhci.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/bluetooth/hci_vhci.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/bluetooth/hci_vhci.h 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/bluetooth/hci_vhci.h 4 Aug 2004 01:28:39 -0000 1.2 @@ -23,7 +23,7 @@ */ /* - * $Id: hci_vhci.h,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: hci_vhci.h,v 1.2 2004/08/04 01:28:39 joff Exp $ */ #ifndef __HCI_VHCI_H Index: drivers/cdrom/aztcd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/cdrom/aztcd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/cdrom/aztcd.c 22 Jul 2004 19:50:13 -0000 1.1 +++ drivers/cdrom/aztcd.c 4 Aug 2004 01:28:39 -0000 1.2 @@ -1,6 +1,6 @@ #define AZT_VERSION "2.60" -/* $Id: aztcd.c,v 1.1 2004/07/22 19:50:13 joff Exp $ +/* $Id: aztcd.c,v 1.2 2004/08/04 01:28:39 joff Exp $ linux/drivers/block/aztcd.c - Aztech CD268 CDROM driver Copyright (C) 1994-98 Werner Zimmermann(Werner.Zimmermann@fht-esslingen.de) Index: drivers/cdrom/aztcd.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/cdrom/aztcd.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/cdrom/aztcd.h 22 Jul 2004 19:50:13 -0000 1.1 +++ drivers/cdrom/aztcd.h 4 Aug 2004 01:28:40 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: aztcd.h,v 1.1 2004/07/22 19:50:13 joff Exp $ +/* $Id: aztcd.h,v 1.2 2004/08/04 01:28:40 joff Exp $ * * Definitions for a AztechCD268 CD-ROM interface * Copyright (C) 1994-98 Werner Zimmermann Index: drivers/cdrom/cdrom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/cdrom/cdrom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/cdrom/cdrom.c 22 Jul 2004 19:50:13 -0000 1.1 +++ drivers/cdrom/cdrom.c 4 Aug 2004 01:28:40 -0000 1.2 @@ -1882,20 +1882,26 @@ if (cgc->buflen < 0 || cgc->buflen >= 131072) return -EINVAL; - if ((ubuf = cgc->buffer)) { + usense = cgc->sense; + cgc->sense = &sense; + if (usense && !access_ok(VERIFY_WRITE, usense, sizeof(*usense))) { + return -EFAULT; + } + + ubuf = cgc->buffer; + if (cgc->data_direction == CGC_DATA_READ || + cgc->data_direction == CGC_DATA_WRITE) { cgc->buffer = kmalloc(cgc->buflen, GFP_KERNEL); if (cgc->buffer == NULL) return -ENOMEM; } - usense = cgc->sense; - cgc->sense = &sense; - if (usense && !access_ok(VERIFY_WRITE, usense, sizeof(*usense))) - return -EFAULT; if (cgc->data_direction == CGC_DATA_READ) { - if (!access_ok(VERIFY_READ, ubuf, cgc->buflen)) + if (!access_ok(VERIFY_READ, ubuf, cgc->buflen)) { + kfree(cgc->buffer); return -EFAULT; + } } else if (cgc->data_direction == CGC_DATA_WRITE) { if (copy_from_user(cgc->buffer, ubuf, cgc->buflen)) { kfree(cgc->buffer); @@ -1907,7 +1913,10 @@ __copy_to_user(usense, cgc->sense, sizeof(*usense)); if (!ret && cgc->data_direction == CGC_DATA_READ) __copy_to_user(ubuf, cgc->buffer, cgc->buflen); - kfree(cgc->buffer); + if (cgc->data_direction == CGC_DATA_READ || + cgc->data_direction == CGC_DATA_WRITE) { + kfree(cgc->buffer); + } return ret; } Index: drivers/cdrom/cm206.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/cdrom/cm206.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/cdrom/cm206.c 22 Jul 2004 19:50:13 -0000 1.1 +++ drivers/cdrom/cm206.c 4 Aug 2004 01:28:40 -0000 1.2 @@ -1,6 +1,6 @@ /* cm206.c. A linux-driver for the cm206 cdrom player with cm260 adapter card. Copyright (c) 1995--1997 David A. van Leeuwen. - $Id: cm206.c,v 1.1 2004/07/22 19:50:13 joff Exp $ + $Id: cm206.c,v 1.2 2004/08/04 01:28:40 joff Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -176,7 +176,7 @@ * - Philips/LMS cm260 product specification * * David van Leeuwen, david@tm.tno.nl. */ -#define REVISION "$Revision: 1.1 $" +#define REVISION "$Revision: 1.2 $" #include Index: drivers/cdrom/mcdx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/cdrom/mcdx.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/cdrom/mcdx.c 22 Jul 2004 19:50:12 -0000 1.1 +++ drivers/cdrom/mcdx.c 4 Aug 2004 01:28:40 -0000 1.2 @@ -53,7 +53,7 @@ #if RCS static const char *mcdx_c_version - = "$Id: mcdx.c,v 1.1 2004/07/22 19:50:12 joff Exp $"; + = "$Id: mcdx.c,v 1.2 2004/08/04 01:28:40 joff Exp $"; #endif #include @@ -1254,7 +1254,7 @@ xwarn("Version 2.14(hs) \n"); #endif - xwarn("$Id: mcdx.c,v 1.1 2004/07/22 19:50:12 joff Exp $\n"); + xwarn("$Id: mcdx.c,v 1.2 2004/08/04 01:28:40 joff Exp $\n"); /* zero the pointer array */ for (drive = 0; drive < MCDX_NDRIVES; drive++) Index: drivers/cdrom/optcd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/cdrom/optcd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/cdrom/optcd.c 22 Jul 2004 19:50:13 -0000 1.1 +++ drivers/cdrom/optcd.c 4 Aug 2004 01:28:40 -0000 1.2 @@ -1,5 +1,5 @@ /* linux/drivers/cdrom/optcd.c - Optics Storage 8000 AT CDROM driver - $Id: optcd.c,v 1.1 2004/07/22 19:50:13 joff Exp $ + $Id: optcd.c,v 1.2 2004/08/04 01:28:40 joff Exp $ Copyright (C) 1995 Leo Spiekman (spiekman@dutette.et.tudelft.nl) Index: drivers/cdrom/optcd.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/cdrom/optcd.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/cdrom/optcd.h 22 Jul 2004 19:50:13 -0000 1.1 +++ drivers/cdrom/optcd.h 4 Aug 2004 01:28:40 -0000 1.2 @@ -1,5 +1,5 @@ /* linux/include/linux/optcd.h - Optics Storage 8000 AT CDROM driver - $Id: optcd.h,v 1.1 2004/07/22 19:50:13 joff Exp $ + $Id: optcd.h,v 1.2 2004/08/04 01:28:40 joff Exp $ Copyright (C) 1995 Leo Spiekman (spiekman@dutette.et.tudelft.nl) Index: drivers/char/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/Config.in,v retrieving revision 1.1 retrieving revision 1.7 diff -u -r1.1 -r1.7 --- drivers/char/Config.in 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/Config.in 16 Jan 2009 19:55:40 -0000 1.7 @@ -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 fi if [ "$CONFIG_ARCH_EP9301" = "y" -o \ @@ -30,6 +30,9 @@ "SPI-PS2 CONFIG_EP93XX_KBD_SPI \ USB CONFIG_EP93XX_KBD_USB" USB fi + bool ' Support for JNS200 3rd serial UART' CONFIG_JNS200_SERIAL + tristate ' 9-bit serial port support' CONFIG_SERIAL9BIT + tristate ' TS-7KV serial port support' CONFIG_TS7KVSERIAL fi if [ "$CONFIG_ARCH_ACORN" = "y" ]; then dep_tristate ' Atomwide serial port support' CONFIG_ATOMWIDE_SERIAL $CONFIG_SERIAL @@ -92,35 +95,55 @@ fi fi if [ "$CONFIG_MIPS" = "y" ]; then - bool ' TX3912/PR31700 serial port support' CONFIG_SERIAL_TX3912 - dep_bool ' Console on TX3912/PR31700 serial port' CONFIG_SERIAL_TX3912_CONSOLE $CONFIG_SERIAL_TX3912 - bool ' Enable Au1000 UART Support' CONFIG_AU1000_UART - if [ "$CONFIG_AU1000_UART" = "y" ]; then - bool ' Enable Au1000 serial console' CONFIG_AU1000_SERIAL_CONSOLE - fi - bool 'TXx927 SIO support' CONFIG_TXX927_SERIAL - if [ "$CONFIG_TXX927_SERIAL" = "y" ]; then - bool 'TXx927 SIO Console support' CONFIG_TXX927_SERIAL_CONSOLE - fi - if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then - bool ' Support for sb1250 onchip DUART' CONFIG_SIBYTE_SB1250_DUART - if [ "$CONFIG_SIBYTE_SB1250_DUART" = "y" ]; then - bool ' Console on SB1250 DUART' CONFIG_SIBYTE_SB1250_DUART_CONSOLE - if [ "$CONFIG_SIBYTE_SB1250_DUART_CONSOLE" = "y" ]; then - define_bool CONFIG_SERIAL_CONSOLE y - fi - int ' Output buffers size (in bytes)' CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE 1024 - bool ' Leave port 1 alone (for kgdb or audio)' CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1 - fi - fi + bool ' TX3912/PR31700 serial port support' CONFIG_SERIAL_TX3912 + dep_bool ' Console on TX3912/PR31700 serial port' CONFIG_SERIAL_TX3912_CONSOLE $CONFIG_SERIAL_TX3912 + bool ' TMPTX39XX/49XX serial port support' CONFIG_SERIAL_TXX9 + dep_bool ' Console on TMPTX39XX/49XX serial port' CONFIG_SERIAL_TXX9_CONSOLE $CONFIG_SERIAL_TXX9 + if [ "$CONFIG_SOC_AU1X00" = "y" ]; then + bool ' Enable Au1x00 UART Support' CONFIG_AU1X00_UART + if [ "$CONFIG_AU1X00_UART" = "y" ]; then + bool ' Enable Au1x00 serial console' CONFIG_AU1X00_SERIAL_CONSOLE + fi + dep_tristate ' Au1x00 USB TTY Device support' CONFIG_AU1X00_USB_TTY $CONFIG_SOC_AU1X00 + if [ "$CONFIG_AU1000_USB_TTY" != "y" ]; then + dep_tristate ' Au1x00 USB Raw Device support' CONFIG_AU1X00_USB_RAW $CONFIG_SOC_AU1X00 + fi + if [ "$CONFIG_AU1X00_USB_TTY" != "n" -o \ + "$CONFIG_AU1X00_USB_RAW" != "n" ]; then + define_bool CONFIG_AU1X00_USB_DEVICE y + fi + fi + bool ' TXx927 SIO support' CONFIG_TXX927_SERIAL + if [ "$CONFIG_TXX927_SERIAL" = "y" ]; then + bool ' TXx927 SIO Console support' CONFIG_TXX927_SERIAL_CONSOLE + fi + if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then + bool ' Support for BCM1xxx onchip DUART' CONFIG_SIBYTE_SB1250_DUART + if [ "$CONFIG_SIBYTE_SB1250_DUART" = "y" ]; then + bool ' Console on BCM1xxx DUART' CONFIG_SIBYTE_SB1250_DUART_CONSOLE + if [ "$CONFIG_SIBYTE_SB1250_DUART_CONSOLE" = "y" ]; then + define_bool CONFIG_SERIAL_CONSOLE y + fi + fi + fi fi - if [ "$CONFIG_MIPS" = "y" ]; then - bool ' TMPTX3912/PR31700 serial port support' CONFIG_SERIAL_TX3912 - dep_bool ' Console on TMPTX3912/PR31700 serial port' CONFIG_SERIAL_TX3912_CONSOLE $CONFIG_SERIAL_TX3912 - bool ' Enable Au1000 UART Support' CONFIG_AU1000_UART - if [ "$CONFIG_AU1000_UART" = "y" ]; then - bool ' Enable Au1000 serial console' CONFIG_AU1000_SERIAL_CONSOLE - fi + if [ "$CONFIG_DECSTATION" = "y" ]; then + bool ' DECstation serial support' CONFIG_SERIAL_DEC + dep_bool ' Support for console on a DECstation serial port' CONFIG_SERIAL_DEC_CONSOLE $CONFIG_SERIAL_DEC + dep_bool ' DZ11 serial support' CONFIG_DZ $CONFIG_SERIAL_DEC $CONFIG_MIPS32 + dep_bool ' Z85C30 serial support' CONFIG_ZS $CONFIG_SERIAL_DEC $CONFIG_TC + fi + if [ "$CONFIG_SGI_IP22" = "y" ]; then + bool ' SGI Zilog85C30 serial support' CONFIG_IP22_SERIAL + fi + if [ "$CONFIG_IA64" = "y" ]; then + bool ' SGI SN2 l1 serial port support' CONFIG_SGI_L1_SERIAL + if [ "$CONFIG_SGI_L1_SERIAL" = "y" ]; then + bool ' SGI SN2 l1 Console support' CONFIG_SGI_L1_SERIAL_CONSOLE + fi + if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ]; then + bool ' SGI SN2 IOC4 serial port support' CONFIG_SGI_IOC4_SERIAL + fi fi if [ "$CONFIG_PARISC" = "y" ]; then bool ' PDC software console support' CONFIG_PDC_CONSOLE @@ -143,6 +166,9 @@ fi bool 'Enable Smart Card Reader 0 Support ' CONFIG_IT8172_SCR0 fi +if [ "$CONFIG_CPU_VR41XX" = "y" ]; then + bool 'NEC VR4100 series Keyboard Interface Unit Support ' CONFIG_VR41XX_KIU +fi if [ "$CONFIG_ARCH_AT91RM9200" = "y" ]; then tristate 'AT91RM9200 SPI device interface' CONFIG_AT91_SPIDEV fi @@ -166,9 +192,12 @@ dep_tristate 'Texas Instruments parallel link cable support' CONFIG_TIPAR $CONFIG_PARPORT fi -if [ "$CONFIG_PPC64" ] ; then +if [ "$CONFIG_PPC64" = "y" ] ; 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 @@ -188,6 +217,9 @@ if [ "$CONFIG_ADB" = "y" -a "$CONFIG_ADB_KEYBOARD" = "y" ]; then dep_tristate ' Apple Desktop Bus mouse support (old driver)' CONFIG_ADBMOUSE $CONFIG_BUSMOUSE fi +# if [ "$CONFIG_DECSTATION" = "y" ]; then +# dep_bool ' MAXINE Access.Bus mouse (VSXXX-BB/GB) support' CONFIG_DTOP_MOUSE $CONFIG_ACCESSBUS +# fi fi tristate 'Mouse Support (not serial and bus mice)' CONFIG_MOUSE @@ -225,7 +257,7 @@ mainmenu_option next_comment comment 'Watchdog Cards' -bool 'Watchdog Timer Support' CONFIG_WATCHDOG +bool 'Watchdog Timer Support' CONFIG_WATCHDOG if [ "$CONFIG_WATCHDOG" != "n" ]; then bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT tristate ' Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT @@ -238,15 +270,13 @@ dep_tristate ' DC21285 watchdog' CONFIG_21285_WATCHDOG $CONFIG_FOOTBRIDGE dep_tristate ' NetWinder WB83C977 watchdog' CONFIG_977_WATCHDOG $CONFIG_ARCH_NETWINDER dep_tristate ' SA1100 watchdog' CONFIG_SA1100_WATCHDOG $CONFIG_ARCH_SA1100 + dep_tristate ' EPXA watchdog' CONFIG_EPXA_WATCHDOG $CONFIG_ARCH_CAMELOT dep_tristate ' Omaha watchdog' CONFIG_OMAHA_WATCHDOG $CONFIG_ARCH_OMAHA dep_tristate ' AT91RM9200 watchdog' CONFIG_AT91_WATCHDOG $CONFIG_ARCH_AT91RM9200 fi tristate ' Eurotech CPU-1220/1410 Watchdog Timer' CONFIG_EUROTECH_WDT tristate ' IB700 SBC Watchdog Timer' CONFIG_IB700_WDT tristate ' ICP ELectronics Wafer 5823 Watchdog' CONFIG_WAFER_WDT - if [ "$CONFIG_SGI_IP22" = "y" ]; then - dep_tristate ' Indy/I2 Hardware Watchdog' CONFIG_INDYDOG $CONFIG_SGI_IP22 - fi tristate ' Intel i810 TCO timer / Watchdog' CONFIG_I810_TCO tristate ' Mixcom Watchdog' CONFIG_MIXCOMWD tristate ' SBC-60XX Watchdog Timer' CONFIG_60XX_WDT @@ -263,7 +293,13 @@ fi fi tristate ' ZF MachZ Watchdog' CONFIG_MACHZ_WDT + if [ "$CONFIG_SGI_IP22" = "y" ]; then + dep_tristate ' Indy/I2 Hardware Watchdog' CONFIG_INDYDOG $CONFIG_SGI_IP22 + fi dep_tristate ' AMD 766/768 TCO Timer/Watchdog' CONFIG_AMD7XX_TCO $CONFIG_EXPERIMENTAL + if [ "$CONFIG_8xx" = "y" ]; then + tristate ' MPC8xx Watchdog Timer' CONFIG_8xx_WDT + fi fi endmenu @@ -275,7 +311,12 @@ fi tristate 'NetWinder flash support' CONFIG_NWFLASH fi -dep_tristate 'NatSemi SCx200 GPIO Support' CONFIG_SCx200_GPIO $CONFIG_SCx200 +tristate 'NatSemi SCx200 Support' CONFIG_SCx200 +dep_tristate ' NatSemi SCx200 GPIO Support' CONFIG_SCx200_GPIO $CONFIG_SCx200 + +if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ] ; then + bool 'SGI SN2 fetchop support' CONFIG_FETCHOP +fi if [ "$CONFIG_X86" = "y" -o "$CONFIG_X86_64" = "y" ]; then dep_tristate 'AMD 768/8111 Random Number Generator support' CONFIG_AMD_RNG $CONFIG_PCI @@ -283,15 +324,35 @@ if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" ]; then dep_tristate 'Intel i8x0 Random Number Generator support' CONFIG_INTEL_RNG $CONFIG_PCI fi +if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" -o \ + "$CONFIG_X86_64" = "y" ]; then + dep_tristate 'Intel/AMD/VIA HW Random Number Generator support' CONFIG_HW_RANDOM $CONFIG_PCI +fi dep_tristate 'AMD 76x native power management (Experimental)' CONFIG_AMD_PM768 $CONFIG_PCI tristate '/dev/nvram support' CONFIG_NVRAM tristate 'Enhanced Real Time Clock Support' CONFIG_RTC +if [ "$CONFIG_ARCH_EP9301" = "y" ]; then + bool 'TS-5620 Real Time Clock board' CONFIG_TS_RTC + bool 'Prosoft 8000 Real Time Clock board' CONFIG_PROSOFT_RTC +fi if [ "$CONFIG_IA64" = "y" ]; then bool 'EFI Real Time Clock Services' CONFIG_EFI_RTC fi if [ "$CONFIG_OBSOLETE" = "y" -a "$CONFIG_ALPHA_BOOK1" = "y" ]; then bool 'Tadpole ANA H8 Support (OBSOLETE)' CONFIG_H8 fi +if [ "$CONFIG_MIPS" = "y" -a "$CONFIG_NEW_TIME_C" = "y" ]; then + tristate 'Generic MIPS RTC Support' CONFIG_MIPS_RTC +fi +if [ "$CONFIG_SGI_IP22" = "y" ]; then + bool 'SGI DS1286 RTC support' CONFIG_SGI_DS1286 +fi +if [ "$CONFIG_SGI_IP27" = "y" ]; then + bool 'SGI M48T35 RTC support' CONFIG_SGI_IP27_RTC +fi +if [ "$CONFIG_TOSHIBA_RBTX4927" = "y" -o "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then + tristate 'Dallas DS1742 RTC support' CONFIG_DS1742 +fi if [ "$CONFIG_ARCH_SA1100" = "y" ]; then tristate 'SA1100 Real Time Clock' CONFIG_SA1100_RTC fi @@ -315,13 +376,14 @@ if [ "$CONFIG_FTAPE" != "n" ]; then source drivers/char/ftape/Config.in fi + endmenu if [ "$CONFIG_GART_IOMMU" = "y" ]; then - bool '/dev/agpgart (AGP Support)' CONFIG_AGP - define_bool CONFIG_AGP_AMD_8151 y + bool '/dev/agpgart (AGP Support)' CONFIG_AGP + define_bool CONFIG_AGP_AMD_K8 y else - tristate '/dev/agpgart (AGP Support)' CONFIG_AGP + tristate '/dev/agpgart (AGP Support)' CONFIG_AGP fi if [ "$CONFIG_AGP" != "n" ]; then bool ' Intel 440LX/BX/GX and I815/I820/I830M/I830MP/I840/I845/I850/I860 support' CONFIG_AGP_INTEL @@ -329,16 +391,23 @@ bool ' VIA chipset support' CONFIG_AGP_VIA bool ' AMD Irongate, 761, and 762 support' CONFIG_AGP_AMD if [ "$CONFIG_GART_IOMMU" != "y" ]; then - bool ' AMD 8151 support' CONFIG_AGP_AMD_8151 + bool ' AMD Opteron/Athlon64 on-CPU GART support' CONFIG_AGP_AMD_K8 fi 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 ' Intel 460GX support' CONFIG_AGP_I460 bool ' HP ZX1 AGP support' CONFIG_AGP_HP_ZX1 fi + bool ' ATI IGP chipset support' CONFIG_AGP_ATI fi +mainmenu_option next_comment +comment 'Direct Rendering Manager (XFree86 DRI support)' bool 'Direct Rendering Manager (XFree86 DRI support)' CONFIG_DRM if [ "$CONFIG_DRM" = "y" ]; then bool ' Build drivers for old (XFree 4.0) DRM' CONFIG_DRM_OLD @@ -351,13 +420,14 @@ source drivers/char/drm/Config.in fi fi +endmenu if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then source drivers/char/pcmcia/Config.in fi -if [ "$CONFIG_MIPS_AU1000" = "y" ]; then - tristate ' Alchemy Au1000 GPIO device support' CONFIG_AU1000_GPIO - tristate ' Au1000/ADS7846 touchscreen support' CONFIG_TS_AU1000_ADS7846 +if [ "$CONFIG_SOC_AU1X00" = "y" ]; then + tristate ' Alchemy Au1x00 GPIO device support' CONFIG_AU1X00_GPIO + tristate ' Au1000/ADS7846 touchscreen support' CONFIG_TS_AU1X00_ADS7846 fi if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then tristate ' ITE GPIO' CONFIG_ITE_GPIO @@ -365,6 +435,7 @@ if [ "$CONFIG_X86" = "y" ]; then tristate 'ACP Modem (Mwave) support' CONFIG_MWAVE + dep_tristate 'HP OB600 C/CT Pop-up mouse support' CONFIG_OBMOUSE $CONFIG_INPUT_MOUSEDEV fi endmenu Index: drivers/char/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/Makefile,v retrieving revision 1.1 retrieving revision 1.7 diff -u -r1.1 -r1.7 --- drivers/char/Makefile 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/Makefile 20 Oct 2005 21:21:55 -0000 1.7 @@ -24,11 +24,12 @@ export-objs := busmouse.o console.o keyboard.o sysrq.o \ misc.o pty.o random.o selection.o serial.o \ sonypi.o tty_io.o tty_ioctl.o generic_serial.o \ - au1000_gpio.o hp_psaux.o nvram.o scx200.o + au1000_gpio.o vac-serial.o hp_psaux.o nvram.o \ + scx200.o fetchop.o mod-subdirs := joystick ftape drm drm-4.0 pcmcia -list-multi := +list-multi := KEYMAP =defkeymap.o KEYBD =pc_keyb.o @@ -46,6 +47,10 @@ ifneq ($(CONFIG_PC_KEYB),y) KEYBD = endif + ifeq ($(CONFIG_VR41XX_KIU),y) + KEYMAP = + KEYBD = vr41xx_keyb.o + endif endif ifeq ($(ARCH),s390x) @@ -168,12 +173,11 @@ ifeq ($(CONFIG_DECSTATION),y) KEYMAP = KEYBD = - SERIAL = decserial.o endif ifeq ($(CONFIG_BAGET_MIPS),y) KEYBD = - SERIAL = + SERIAL = vac-serial.o endif ifeq ($(CONFIG_NINO),y) @@ -196,7 +200,8 @@ obj-$(CONFIG_VT) += vt.o vc_screen.o consolemap.o consolemap_deftbl.o $(CONSOLE) selection.o obj-$(CONFIG_SERIAL) += $(SERIAL) obj-$(CONFIG_SERIAL_HCDP) += hcdp_serial.o -obj-$(CONFIG_TS_AU1000_ADS7846) += au1000_ts.o +obj-$(CONFIG_TS_AU1X00_ADS7846) += au1000_ts.o +obj-$(CONFIG_SERIAL_DEC) += decserial.o obj-$(CONFIG_TOUCHSCREEN_ANAKIN) += anakin_ts.o ifndef CONFIG_SUN_KEYBOARD @@ -205,6 +210,8 @@ obj-$(CONFIG_PCI) += keyboard.o $(KEYMAP) endif +obj-$(CONFIG_SERIAL9BIT) += serial9bit.o +obj-$(CONFIG_TS7KVSERIAL) += ts7kvserial.o obj-$(CONFIG_HIL) += hp_keyb.o obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o @@ -237,6 +244,10 @@ obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o obj-$(CONFIG_SERIAL_TX3912) += generic_serial.o serial_tx3912.o obj-$(CONFIG_TXX927_SERIAL) += serial_txx927.o +obj-$(CONFIG_SERIAL_TXX9) += generic_serial.o serial_txx9.o +obj-$(CONFIG_IP22_SERIAL) += sgiserial.o +obj-$(CONFIG_AU1X00_UART) += au1x00-serial.o +obj-$(CONFIG_SGI_L1_SERIAL) += sn_serial.o subdir-$(CONFIG_RIO) += rio subdir-$(CONFIG_INPUT) += joystick @@ -245,11 +256,13 @@ obj-$(CONFIG_LOGIBUSMOUSE) += logibusmouse.o obj-$(CONFIG_PRINTER) += lp.o obj-$(CONFIG_TIPAR) += tipar.o +obj-$(CONFIG_OBMOUSE) += obmouse.o ifeq ($(CONFIG_INPUT),y) obj-y += joystick/js.o endif +obj-$(CONFIG_FETCHOP) += fetchop.o obj-$(CONFIG_BUSMOUSE) += busmouse.o obj-$(CONFIG_DTLK) += dtlk.o obj-$(CONFIG_R3964) += n_r3964.o @@ -265,6 +278,9 @@ obj-$(CONFIG_RTC) += rtc.o obj-$(CONFIG_GEN_RTC) += genrtc.o obj-$(CONFIG_EFI_RTC) += efirtc.o +obj-$(CONFIG_SGI_DS1286) += ds1286.o +obj-$(CONFIG_MIPS_RTC) += mips_rtc.o +obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o obj-$(CONFIG_SA1100_RTC) += sa1100-rtc.o obj-$(CONFIG_OMAHA_RTC) += omaha-rtc.o ifeq ($(CONFIG_PPC),) @@ -273,12 +289,17 @@ obj-$(CONFIG_TOSHIBA) += toshiba.o obj-$(CONFIG_I8K) += i8k.o obj-$(CONFIG_DS1620) += ds1620.o +obj-$(CONFIG_DS1742) += ds1742.o obj-$(CONFIG_INTEL_RNG) += i810_rng.o obj-$(CONFIG_AMD_RNG) += amd768_rng.o +obj-$(CONFIG_HW_RANDOM) += hw_random.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 +obj-$(CONFIG_AU1X00_GPIO) += au1000_gpio.o +obj-$(CONFIG_AU1X00_USB_TTY) += au1000_usbtty.o +obj-$(CONFIG_AU1X00_USB_RAW) += au1000_usbraw.o obj-$(CONFIG_COBALT_LCD) += lcd.o obj-$(CONFIG_QIC02_TAPE) += tpqic02.o @@ -298,7 +319,8 @@ obj-$(CONFIG_DZ) += dz.o obj-$(CONFIG_NWBUTTON) += nwbutton.o obj-$(CONFIG_NWFLASH) += nwflash.o -obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o scx200.o +obj-$(CONFIG_SCx200) += scx200.o +obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o obj-$(CONFIG_SA1100_CONSUS) += consusbutton.o # Only one watchdog can succeed. We probe the hardware watchdog @@ -329,9 +351,12 @@ obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o +obj-$(CONFIG_EPXA_WATCHDOG) += epxa_wdt.o obj-$(CONFIG_OMAHA_WATCHDOG) += omaha_wdt.o obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o obj-$(CONFIG_AMD7XX_TCO) += amd7xx_tco.o +obj-$(CONFIG_INDYDOG) += indydog.o +obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o # I2C char devices obj-$(CONFIG_I2C_DS1307) += ds1307.o Index: drivers/char/alim7101_wdt.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/alim7101_wdt.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/alim7101_wdt.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/alim7101_wdt.c 4 Aug 2004 01:28:40 -0000 1.2 @@ -209,7 +209,7 @@ static int fop_close(struct inode * inode, struct file * file) { - if(wdt_expect_close) + if ((wdt_expect_close) || (! nowayout)) wdt_turnoff(); else { printk(OUR_NAME ": device file closed unexpectedly. Will not stop the WDT!\n"); Index: drivers/char/amd76x_pm.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/amd76x_pm.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/amd76x_pm.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/amd76x_pm.c 4 Aug 2004 01:28:40 -0000 1.2 @@ -78,6 +78,7 @@ #include #include #include +#include #include "amd76x_pm.h" @@ -473,7 +474,7 @@ } #endif - +#ifdef AMD76X_POS /* * Activate sleep state via its ACPI register (PM1_CNT). */ @@ -488,8 +489,6 @@ outw(regshort, amd76x_pm_cfg.slp_reg); } - -#ifdef AMD76X_POS /* * Wrapper function to activate POS sleep state. */ @@ -576,16 +575,18 @@ int found; /* Find northbridge */ - found = pci_module_init(&amd_nb_driver); - if (found < 0) { + found = pci_register_driver(&amd_nb_driver); + if (found <= 0) { printk(KERN_ERR "amd76x_pm: Could not find northbridge\n"); + pci_unregister_driver(&amd_nb_driver); return 1; } /* Find southbridge */ - found = pci_module_init(&amd_sb_driver); - if (found < 0) { + found = pci_register_driver(&amd_sb_driver); + if (found <= 0) { printk(KERN_ERR "amd76x_pm: Could not find southbridge\n"); + pci_unregister_driver(&amd_sb_driver); pci_unregister_driver(&amd_nb_driver); return 1; } @@ -619,6 +620,8 @@ #ifndef AMD76X_NTH if (!amd76x_pm_cfg.curr_idle) { printk(KERN_ERR "amd76x_pm: Idle function not changed\n"); + pci_unregister_driver(&amd_nb_driver); + pci_unregister_driver(&amd_sb_driver); return 1; } Index: drivers/char/amd7xx_tco.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/amd7xx_tco.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/amd7xx_tco.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/amd7xx_tco.c 4 Aug 2004 01:28:40 -0000 1.2 @@ -1,6 +1,6 @@ /* * AMD 766/768 TCO Timer Driver - * (c) Copyright 2002 Zwane Mwaikambo + * (c) Copyright 2002 Zwane Mwaikambo * All Rights Reserved. * * Parts from; @@ -34,35 +34,48 @@ #include #include -#define AMDTCO_MODULE_VER "build 20020601" +#define AMDTCO_MODULE_VER "build 20021116" #define AMDTCO_MODULE_NAME "amd7xx_tco" #define PFX AMDTCO_MODULE_NAME ": " -#define MAX_TIMEOUT 38 /* max of 38 seconds */ +#define MAX_TIMEOUT 38 /* max of 38 seconds, although the system will only + * reset itself after the second timeout */ /* pmbase registers */ -#define GLOBAL_SMI_REG 0x2a -#define TCO_EN (1 << 1) /* bit 1 in global SMI register */ #define TCO_RELOAD_REG 0x40 /* bits 0-5 are current count, 6-7 are reserved */ #define TCO_INITVAL_REG 0x41 /* bits 0-5 are value to load, 6-7 are reserved */ #define TCO_TIMEOUT_MASK 0x3f +#define TCO_STATUS1_REG 0x44 #define TCO_STATUS2_REG 0x46 #define NDTO_STS2 (1 << 1) /* we're interested in the second timeout */ #define BOOT_STS (1 << 2) /* will be set if NDTO_STS2 was set before reboot */ #define TCO_CTRL1_REG 0x48 #define TCO_HALT (1 << 11) +#define NO_REBOOT (1 << 10) /* in DevB:3x48 */ -static char banner[] __initdata = KERN_INFO PFX AMDTCO_MODULE_VER; +static char banner[] __initdata = KERN_INFO PFX AMDTCO_MODULE_VER "\n"; static int timeout = 38; static u32 pmbase; /* PMxx I/O base */ static struct pci_dev *dev; static struct semaphore open_sem; -spinlock_t amdtco_lock; /* only for device access */ +static spinlock_t amdtco_lock; /* only for device access */ static int expect_close = 0; MODULE_PARM(timeout, "i"); MODULE_PARM_DESC(timeout, "range is 0-38 seconds, default is 38"); +static inline u8 seconds_to_ticks(int seconds) +{ + /* the internal timer is stored as ticks which decrement + * every 0.6 seconds */ + return (seconds * 10) / 6; +} + +static inline int ticks_to_seconds(u8 ticks) +{ + return (ticks * 6) / 10; +} + static inline int amdtco_status(void) { u16 reg; @@ -81,28 +94,19 @@ static inline void amdtco_ping(void) { - u8 reg; - - spin_lock(&amdtco_lock); - reg = inb(pmbase+TCO_RELOAD_REG); - outb(1 | reg, pmbase+TCO_RELOAD_REG); - spin_unlock(&amdtco_lock); + outb(1, pmbase+TCO_RELOAD_REG); } static inline int amdtco_gettimeout(void) { - return inb(TCO_RELOAD_REG) & TCO_TIMEOUT_MASK; + u8 reg = inb(pmbase+TCO_RELOAD_REG) & TCO_TIMEOUT_MASK; + return ticks_to_seconds(reg); } static inline void amdtco_settimeout(unsigned int timeout) { - u8 reg; - - spin_lock(&amdtco_lock); - reg = inb(pmbase+TCO_INITVAL_REG); - reg |= timeout & TCO_TIMEOUT_MASK; + u8 reg = seconds_to_ticks(timeout) & TCO_TIMEOUT_MASK; outb(reg, pmbase+TCO_INITVAL_REG); - spin_unlock(&amdtco_lock); } static inline void amdtco_global_enable(void) @@ -110,9 +114,12 @@ u16 reg; spin_lock(&amdtco_lock); - reg = inw(pmbase+GLOBAL_SMI_REG); - reg |= TCO_EN; - outw(reg, pmbase+GLOBAL_SMI_REG); + + /* clear NO_REBOOT on DevB:3x48 p97 */ + pci_read_config_word(dev, 0x48, ®); + reg &= ~NO_REBOOT; + pci_write_config_word(dev, 0x48, reg); + spin_unlock(&amdtco_lock); } @@ -150,10 +157,12 @@ if (timeout > MAX_TIMEOUT) timeout = MAX_TIMEOUT; + amdtco_disable(); amdtco_settimeout(timeout); amdtco_global_enable(); + amdtco_enable(); amdtco_ping(); - printk(KERN_INFO PFX "Watchdog enabled, timeout = %d/%d seconds", + printk(KERN_INFO PFX "Watchdog enabled, timeout = %ds of %ds\n", amdtco_gettimeout(), timeout); return 0; @@ -202,7 +211,7 @@ case WDIOC_GETTIMEOUT: return put_user(amdtco_gettimeout(), (int *)arg); - + case WDIOC_SETOPTIONS: if (copy_from_user(&tmp, (int *)arg, sizeof tmp)) return -EFAULT; @@ -225,7 +234,7 @@ printk(KERN_INFO PFX "Watchdog disabled\n"); } else { amdtco_ping(); - printk(KERN_CRIT PFX "Unexpected close!, timeout in %d seconds)\n", timeout); + printk(KERN_CRIT PFX "Unexpected close!, timeout in %d seconds\n", timeout); } up(&open_sem); @@ -253,10 +262,9 @@ } #endif amdtco_ping(); - return len; } - return 0; + return len; } @@ -291,7 +299,6 @@ }; static struct pci_device_id amdtco_pci_tbl[] __initdata = { - /* AMD 766 PCI_IDs here */ { 0x1022, 0x7443, PCI_ANY_ID, PCI_ANY_ID, }, { 0, } }; @@ -361,6 +368,9 @@ if (ints[0] > 0) timeout = ints[1]; + if (!timeout || timeout > 38) + timeout = MAX_TIMEOUT; + return 1; } @@ -370,7 +380,7 @@ module_init(amdtco_init); module_exit(amdtco_exit); -MODULE_AUTHOR("Zwane Mwaikambo "); +MODULE_AUTHOR("Zwane Mwaikambo "); MODULE_DESCRIPTION("AMD 766/768 TCO Timer Driver"); MODULE_LICENSE("GPL"); EXPORT_NO_SYMBOLS; Index: drivers/char/applicom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/applicom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/applicom.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/applicom.c 4 Aug 2004 01:28:40 -0000 1.2 @@ -1,7 +1,7 @@ /* Derived from Applicom driver ac.c for SCO Unix */ /* Ported by David Woodhouse, Axiom (Cambridge) Ltd. */ /* dwmw2@redhat.com 30/8/98 */ -/* $Id: applicom.c,v 1.1 2004/07/22 19:49:51 joff Exp $ */ +/* $Id: applicom.c,v 1.2 2004/08/04 01:28:40 joff Exp $ */ /* This module is for Linux 2.1 and 2.2 series kernels. */ /*****************************************************************************/ /* J PAGET 18/02/94 passage V2.4.2 ioctl avec code 2 reset to les interrupt */ @@ -203,7 +203,7 @@ void *RamIO; int boardno; - printk(KERN_INFO "Applicom driver: $Id: applicom.c,v 1.1 2004/07/22 19:49:51 joff Exp $\n"); + printk(KERN_INFO "Applicom driver: $Id: applicom.c,v 1.2 2004/08/04 01:28:40 joff Exp $\n"); /* No mem and irq given - check for a PCI card */ @@ -786,7 +786,7 @@ writeb(1, apbs[IndexCard].RamIO + RAM_IT_FROM_PC); break; case 6: - printk(KERN_INFO "APPLICOM driver release .... V2.8.0 ($Revision: 1.1 $)\n"); + printk(KERN_INFO "APPLICOM driver release .... V2.8.0 ($Revision: 1.2 $)\n"); printk(KERN_INFO "Number of installed boards . %d\n", (int) numboards); printk(KERN_INFO "Segment of board ........... %X\n", (int) mem); printk(KERN_INFO "Interrupt IRQ number ....... %d\n", (int) irq); Index: drivers/char/applicom.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/applicom.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/applicom.h 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/applicom.h 4 Aug 2004 01:28:40 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: applicom.h,v 1.1 2004/07/22 19:49:51 joff Exp $ */ +/* $Id: applicom.h,v 1.2 2004/08/04 01:28:40 joff Exp $ */ #ifndef __LINUX_APPLICOM_H__ Index: drivers/char/au1000_gpio.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/au1000_gpio.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/au1000_gpio.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/au1000_gpio.c 4 Aug 2004 01:28:40 -0000 1.2 @@ -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 Index: drivers/char/au1000_ts.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/au1000_ts.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/au1000_ts.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/au1000_ts.c 4 Aug 2004 01:28:40 -0000 1.2 @@ -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); Index: drivers/char/console.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/console.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/console.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/console.c 4 Aug 2004 01:28:40 -0000 1.2 @@ -118,6 +118,8 @@ const struct consw *conswitchp; +static void __console_callback(void); + /* A bitmap for codes <32. A bit of 1 indicates that the code * corresponding to that bit number invokes some special action * (such as cursor movement) and should not be displayed as a @@ -248,9 +250,16 @@ schedule_console_callback(); } +extern int machine_paniced; + void schedule_console_callback(void) { - schedule_task(&console_callback_tq); + /* Don't care about locking after panic - but I want to switch the console + NOW */ + if (machine_paniced) + __console_callback(); + else + schedule_task(&console_callback_tq); } static void scrup(int currcons, unsigned int t, unsigned int b, int nr) @@ -2126,10 +2135,15 @@ * with other console code and prevention of re-entrancy is * ensured with console_sem. */ -static void console_callback(void *ignored) +static void console_callback(void *unused) { acquire_console_sem(); + __console_callback(); + release_console_sem(); +} +static void __console_callback(void) +{ if (want_console >= 0) { if (want_console != fg_console && vc_cons_allocated(want_console)) { hide_cursor(fg_console); @@ -2151,8 +2165,6 @@ sw->con_scrolldelta(vc_cons[currcons].d, scrollback_delta); scrollback_delta = 0; } - - release_console_sem(); } void set_console(int nr) @@ -2852,6 +2864,12 @@ timer_do_blank_screen(0, 1); } +void disable_console_blank(void) +{ + del_timer_sync(&console_timer); + blankinterval = 0; +} + void poke_blanked_console(void) { del_timer(&console_timer); Index: drivers/char/cyclades.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/cyclades.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/cyclades.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/cyclades.c 4 Aug 2004 01:28:40 -0000 1.2 @@ -2,7 +2,7 @@ #define Z_WAKE #undef Z_EXT_CHARS_IN_BUFFER static char rcsid[] = -"$Revision: 1.1 $$Date: 2004/07/22 19:49:51 $"; +"$Revision: 1.2 $$Date: 2004/08/04 01:28:40 $"; /* * linux/drivers/char/cyclades.c @@ -25,8 +25,8 @@ * This version supports shared IRQ's (only for PCI boards). * * $Log: cyclades.c,v $ - * Revision 1.1 2004/07/22 19:49:51 joff - * Initial revision + * Revision 1.2 2004/08/04 01:28:40 joff + * merging 2.4.26-vrs1 * * Revision 2.3.2.8 2000/07/06 18:14:16 ivan * Fixed the PCI detection function to work properly on Alpha systems. Index: drivers/char/decserial.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/decserial.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/decserial.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/decserial.c 4 Aug 2004 01:28:41 -0000 1.2 @@ -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) Index: drivers/char/ds1307.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ds1307.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ds1307.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/ds1307.h 4 Aug 2004 01:28:41 -0000 1.2 @@ -11,7 +11,7 @@ #ifndef DS1307_H #define DS1307_H -#if defined(CONFIG_PXA_EMERSON_SBC) || defined(CONFIG_PXA_CERF_BOARD) +#if defined(CONFIG_PXA_EMERSON_SBC) || defined(CONFIG_PXA_CERF_BOARD) || defined(CONFIG_MACH_CSB337) #define DS1307_I2C_SLAVE_ADDR 0x68 #else #define DS1307_I2C_SLAVE_ADDR 0xffff Index: drivers/char/dummy_keyb.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/dummy_keyb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/dummy_keyb.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/dummy_keyb.c 4 Aug 2004 01:28:41 -0000 1.2 @@ -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) { Index: drivers/char/dz.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/dz.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/dz.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/dz.c 4 Aug 2004 01:28:41 -0000 1.2 @@ -21,7 +21,7 @@ * [07-SEP-99] Bugfixes */ -#define DEBUG_DZ 1 +#undef DEBUG_DZ #include #include @@ -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 @@ -256,13 +254,19 @@ if (tmp & DZ_PERR) { *tty->flip.flag_buf_ptr = TTY_PARITY; +#ifdef DEBUG_DZ debug_console("PERR\n", 5); +#endif } else if (tmp & DZ_FERR) { *tty->flip.flag_buf_ptr = TTY_FRAME; +#ifdef DEBUG_DZ debug_console("FERR\n", 5); +#endif } if (tmp & DZ_OERR) { +#ifdef DEBUG_DZ debug_console("OERR\n", 5); +#endif if (tty->flip.count < TTY_FLIPBUF_SIZE) { tty->flip.count++; tty->flip.flag_buf_ptr++; @@ -862,7 +866,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; @@ -1301,7 +1305,7 @@ int __init dz_init(void) { - int i, tmp; + int i; long flags; struct dz_serial *info; @@ -1404,7 +1408,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 +1417,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(); + while (dz_in(info, DZ_CSR) & DZ_CLR); + iob(); /* enable scanning */ dz_out(info, DZ_CSR, DZ_MSE); @@ -1428,13 +1432,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 +1580,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 +1593,6 @@ register_console(&dz_sercons); } -#endif /* CONFIG_SERIAL_CONSOLE */ +#endif /* CONFIG_SERIAL_DEC_CONSOLE */ MODULE_LICENSE("GPL"); Index: drivers/char/efirtc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/efirtc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/efirtc.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/efirtc.c 4 Aug 2004 01:28:41 -0000 1.2 @@ -118,6 +118,7 @@ static void convert_from_efi_time(efi_time_t *eft, struct rtc_time *wtime) { + memset(wtime, 0, sizeof(struct rtc_time)); wtime->tm_sec = eft->second; wtime->tm_min = eft->minute; wtime->tm_hour = eft->hour; Index: drivers/char/genrtc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/genrtc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/genrtc.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/genrtc.c 4 Aug 2004 01:28:41 -0000 1.2 @@ -378,69 +378,13 @@ return 0; } -static int gen_rtc_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data); - - -/* - * The various file operations we support. - */ - -static struct file_operations gen_rtc_fops = { - .owner = THIS_MODULE, -#ifdef CONFIG_GEN_RTC_X - .read = gen_rtc_read, - .poll = gen_rtc_poll, -#endif - .ioctl = gen_rtc_ioctl, - .open = gen_rtc_open, - .release = gen_rtc_release, -}; - -static struct miscdevice rtc_gen_dev = -{ - .minor = RTC_MINOR, - .name = "rtc", - .fops = &gen_rtc_fops, -}; - -static int __init rtc_generic_init(void) -{ - int retval; - - printk(KERN_INFO "Generic RTC Driver v%s\n", RTC_VERSION); - - retval = misc_register(&rtc_gen_dev); - if(retval < 0) - return retval; #ifdef CONFIG_PROC_FS - if((create_proc_read_entry ("driver/rtc", 0, 0, gen_rtc_read_proc, NULL)) == NULL){ - misc_deregister(&rtc_gen_dev); - return -ENOMEM; - } -#endif - - return 0; -} - -static void __exit rtc_generic_exit(void) -{ - remove_proc_entry ("driver/rtc", NULL); - misc_deregister(&rtc_gen_dev); -} - -module_init(rtc_generic_init); -module_exit(rtc_generic_exit); -EXPORT_NO_SYMBOLS; - /* * Info exported via "/proc/rtc". */ -#ifdef CONFIG_PROC_FS - static int gen_rtc_proc_output(char *buf) { char *p; @@ -528,6 +472,59 @@ #endif /* CONFIG_PROC_FS */ +/* + * The various file operations we support. + */ + +static struct file_operations gen_rtc_fops = { + .owner = THIS_MODULE, +#ifdef CONFIG_GEN_RTC_X + .read = gen_rtc_read, + .poll = gen_rtc_poll, +#endif + .ioctl = gen_rtc_ioctl, + .open = gen_rtc_open, + .release = gen_rtc_release, +}; + +static struct miscdevice rtc_gen_dev = +{ + .minor = RTC_MINOR, + .name = "rtc", + .fops = &gen_rtc_fops, +}; + +static int __init rtc_generic_init(void) +{ + int retval; + + printk(KERN_INFO "Generic RTC Driver v%s\n", RTC_VERSION); + + retval = misc_register(&rtc_gen_dev); + if(retval < 0) + return retval; + +#ifdef CONFIG_PROC_FS + if((create_proc_read_entry ("driver/rtc", 0, 0, gen_rtc_read_proc, NULL)) == NULL){ + misc_deregister(&rtc_gen_dev); + return -ENOMEM; + } +#endif + + return 0; +} + +static void __exit rtc_generic_exit(void) +{ + remove_proc_entry ("driver/rtc", NULL); + misc_deregister(&rtc_gen_dev); +} + + +module_init(rtc_generic_init); +module_exit(rtc_generic_exit); +EXPORT_NO_SYMBOLS; + MODULE_AUTHOR("Richard Zidlicky"); MODULE_LICENSE("GPL"); Index: drivers/char/hcdp_serial.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/hcdp_serial.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/hcdp_serial.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/hcdp_serial.c 4 Aug 2004 01:28:41 -0000 1.2 @@ -219,3 +219,41 @@ printk("Leaving setup_serial_hcdp()\n"); #endif } + +#ifdef CONFIG_IA64_EARLY_PRINTK_UART +unsigned long hcdp_early_uart(void) +{ + efi_system_table_t *systab; + efi_config_table_t *config_tables; + hcdp_t *hcdp = 0; + hcdp_dev_t *dev; + int i; + + systab = (efi_system_table_t *) ia64_boot_param->efi_systab; + if (!systab) + return 0; + systab = __va(systab); + + config_tables = (efi_config_table_t *) systab->tables; + if (!config_tables) + return 0; + config_tables = __va(config_tables); + + for (i = 0; i < systab->nr_tables; i++) { + if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) { + hcdp = (hcdp_t *) config_tables[i].table; + break; + } + } + if (!hcdp) + return 0; + hcdp = __va(hcdp); + + for (i = 0, dev = hcdp->hcdp_dev; i < hcdp->num_entries; i++, dev++) { + if (dev->type == HCDP_DEV_CONSOLE) + return (u64) dev->base_addr.addrhi << 32 + | dev->base_addr.addrlo; + } + return 0; +} +#endif Index: drivers/char/hp600_keyb.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/hp600_keyb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/hp600_keyb.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/hp600_keyb.c 4 Aug 2004 01:28:41 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: hp600_keyb.c,v 1.1 2004/07/22 19:49:51 joff Exp $ + * $Id: hp600_keyb.c,v 1.2 2004/08/04 01:28:41 joff Exp $ * Copyright (C) 2000 YAEGASHI Takeshi * HP600 keyboard scan routine and translation table * Copyright (C) 2000 Niibe Yutaka Index: drivers/char/hvc_console.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/hvc_console.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/hvc_console.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/hvc_console.c 4 Aug 2004 01:28:41 -0000 1.2 @@ -252,7 +252,11 @@ hvc_driver.magic = TTY_DRIVER_MAGIC; hvc_driver.driver_name = "hvc"; +#ifdef CONFIG_DEVFS_FS hvc_driver.name = "hvc/%d"; +#else + hvc_driver.name = "hvc"; +#endif hvc_driver.major = HVC_MAJOR; hvc_driver.minor_start = HVC_MINOR; hvc_driver.num = hvc_count(&hvc_offset); Index: drivers/char/i810-tco.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/i810-tco.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/i810-tco.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/i810-tco.c 4 Aug 2004 01:28:41 -0000 1.2 @@ -25,7 +25,8 @@ * 82801AA & 82801AB chip : document number 290655-003, 290677-004, * 82801BA & 82801BAM chip : document number 290687-002, 298242-005, * 82801CA & 82801CAM chip : document number 290716-001, 290718-001, - * 82801DB & 82801E chip : document number 290744-001, 273599-001 + * 82801DB & 82801E chip : document number 290744-001, 273599-001, + * 82801EB & 82801ER chip : document number 252516-001 * * 20000710 Nils Faerber * Initial Version 0.01 @@ -42,9 +43,11 @@ * clean up ioctls (WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS and * WDIOC_SETOPTIONS), made i810tco_getdevice __init, * removed boot_status, removed tco_timer_read, - * added support for 82801DB and 82801E chipset, general cleanup. + * added support for 82801DB and 82801E chipset, + * added support for 82801EB and 8280ER chipset, + * general cleanup. */ - + #include #include #include @@ -167,7 +170,7 @@ * Reload (trigger) the timer. Lock is needed so we dont reload it during * a reprogramming event */ - + static void tco_timer_reload (void) { spin_lock(&tco_lock); @@ -310,6 +313,7 @@ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, PCI_ANY_ID, PCI_ANY_ID, }, { 0, }, }; MODULE_DEVICE_TABLE (pci, i810tco_pci_tbl); Index: drivers/char/i810-tco.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/i810-tco.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/i810-tco.h 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/i810-tco.h 4 Aug 2004 01:28:41 -0000 1.2 @@ -1,5 +1,5 @@ /* - * i810-tco 0.05: TCO timer driver for i8xx chipsets + * i810-tco: TCO timer driver for i8xx chipsets * * (c) Copyright 2000 kernel concepts , All Rights Reserved. * http://www.kernelconcepts.de @@ -8,7 +8,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. - * + * * Neither kernel concepts nor Nils Faerber admit liability nor provide * warranty for any of this software. This material is provided * "AS-IS" and at no charge. Index: drivers/char/indydog.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/indydog.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/indydog.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/indydog.c 4 Aug 2004 01:28:41 -0000 1.2 @@ -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; Index: drivers/char/ip2main.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ip2main.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ip2main.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/ip2main.c 4 Aug 2004 01:28:41 -0000 1.2 @@ -988,7 +988,7 @@ static void __init ip2_init_board( int boardnum ) { - int i,rc; + int i; int nports = 0, nboxes = 0; i2ChanStrPtr pCh; i2eBordStrPtr pB = i2BoardPtrTable[boardnum]; Index: drivers/char/ite_gpio.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ite_gpio.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ite_gpio.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/ite_gpio.c 4 Aug 2004 01:28:41 -0000 1.2 @@ -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 Index: drivers/char/keyboard.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/keyboard.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/keyboard.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/keyboard.c 4 Aug 2004 01:28:42 -0000 1.2 @@ -14,7 +14,7 @@ * `Sticky' modifier keys, 951006. * * 11-11-96: SAK should now work in the raw mode (Martin Mares) - * + * * Modified to provide 'generic' keyboard support by Hamish Macdonald * Merge with the m68k keyboard driver and split-off of the PC low-level * parts by Geert Uytterhoeven, May 1997 @@ -95,9 +95,9 @@ static unsigned long key_down[256/BITS_PER_LONG]; static int dead_key_next; -/* +/* * In order to retrieve the shift_state (for the mouse server), either - * the variable must be global, or a new procedure must be created to + * the variable must be global, or a new procedure must be created to * return the value. I chose the former way. */ int shift_state; @@ -222,6 +222,7 @@ unsigned char keycode; char up_flag = down ? 0 : 0200; char raw_mode; + char have_keycode; pm_access(pm_kbd); @@ -239,16 +240,30 @@ tty = NULL; } kbd = kbd_table + fg_console; - if ((raw_mode = (kbd->kbdmode == VC_RAW))) { + /* + * Convert scancode to keycode + */ + raw_mode = (kbd->kbdmode == VC_RAW); + have_keycode = kbd_translate(scancode, &keycode, raw_mode); + if (raw_mode) { /* * The following is a workaround for hardware - * which sometimes send the key release event twice + * which sometimes send the key release event twice */ unsigned char next_scancode = scancode|up_flag; - if (up_flag && next_scancode==prev_scancode) { + if (have_keycode && up_flag && next_scancode==prev_scancode) { /* unexpected 2nd release event */ } else { - prev_scancode=next_scancode; + /* + * Only save previous scancode if it was a key-up + * and had a single-byte scancode. + */ + if (!have_keycode) + prev_scancode = 1; + else if (!up_flag || prev_scancode == 1) + prev_scancode = 0; + else + prev_scancode = next_scancode; put_queue(next_scancode); } /* we do not return yet, because we want to maintain @@ -256,10 +271,7 @@ values when finishing RAW mode or when changing VT's */ } - /* - * Convert scancode to keycode - */ - if (!kbd_translate(scancode, &keycode, raw_mode)) + if (!have_keycode) goto out; /* @@ -416,21 +428,6 @@ shift_state = 0; } -#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) { @@ -438,7 +435,6 @@ con_schedule_flip(tty); } } -#endif static void puts_queue(char *cp) { @@ -537,7 +533,7 @@ static void decr_console(void) { int i; - + for (i = fg_console-1; i != fg_console; i--) { if (i == -1) i = MAX_NR_CONSOLES-1; @@ -1062,7 +1058,7 @@ kbd0.slockstate = 0; kbd0.modeflags = KBD_DEFMODE; kbd0.kbdmode = VC_XLATE; - + for (i = 0 ; i < MAX_NR_CONSOLES ; i++) kbd_table[i] = kbd0; Index: drivers/char/lcd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/lcd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/lcd.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/lcd.c 4 Aug 2004 01:28:42 -0000 1.2 @@ -14,6 +14,7 @@ #define RTC_IO_EXTENT 0x10 /*Only really two ports, but... */ +#include #include #include #include Index: drivers/char/lcd.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/lcd.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/lcd.h 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/lcd.h 4 Aug 2004 01:28:42 -0000 1.2 @@ -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))) Index: drivers/char/mem.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/mem.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/mem.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/mem.c 4 Aug 2004 01:28:42 -0000 1.2 @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -500,16 +501,23 @@ */ static loff_t memory_lseek(struct file * file, loff_t offset, int orig) { + loff_t ret; + switch (orig) { case 0: file->f_pos = offset; - return file->f_pos; + ret = file->f_pos; + force_successful_syscall_return(); + break; case 1: file->f_pos += offset; - return file->f_pos; + ret = file->f_pos; + force_successful_syscall_return(); + break; default: - return -EINVAL; + ret = -EINVAL; } + return ret; } static int open_port(struct inode * inode, struct file * filp) Index: drivers/char/misc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/misc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/misc.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/misc.c 4 Aug 2004 01:28:44 -0000 1.2 @@ -66,10 +66,6 @@ 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); @@ -267,15 +263,6 @@ #ifdef CONFIG_PMAC_PBOOK pmu_device_init(); #endif -#ifdef CONFIG_SGI_NEWPORT_GFX - gfx_register (); -#endif -#ifdef CONFIG_SGI_IP22 - streamable_init (); -#endif -#ifdef CONFIG_SGI_NEWPORT_GFX - gfx_register (); -#endif #ifdef CONFIG_TOSHIBA tosh_init(); #endif Index: drivers/char/n_hdlc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/n_hdlc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/n_hdlc.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/n_hdlc.c 4 Aug 2004 01:28:44 -0000 1.2 @@ -9,7 +9,7 @@ * Al Longyear , Paul Mackerras * * Original release 01/11/99 - * $Id: n_hdlc.c,v 1.1 2004/07/22 19:49:51 joff Exp $ + * $Id: n_hdlc.c,v 1.2 2004/08/04 01:28:44 joff Exp $ * * This code is released under the GNU General Public License (GPL) * @@ -78,7 +78,7 @@ */ #define HDLC_MAGIC 0x239e -#define HDLC_VERSION "$Revision: 1.1 $" +#define HDLC_VERSION "$Revision: 1.2 $" #include #include @@ -172,9 +172,9 @@ /* * HDLC buffer list manipulation functions */ -void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list); -void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf); -N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list); +static void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list); +static void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf); +static N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list); /* Local functions */ @@ -183,13 +183,16 @@ MODULE_PARM(debuglevel, "i"); MODULE_PARM(maxframe, "i"); +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif /* debug level can be set by insmod for debugging purposes */ #define DEBUG_LEVEL_INFO 1 -int debuglevel=0; +static int debuglevel=0; /* max frame size for memory allocations */ -ssize_t maxframe=4096; +static ssize_t maxframe=4096; /* TTY callbacks */ @@ -265,7 +268,8 @@ } else break; } - + if (n_hdlc->tbuf) + kfree(n_hdlc->tbuf); kfree(n_hdlc); } /* end of n_hdlc_release() */ @@ -905,7 +909,7 @@ * Arguments: list pointer to buffer list * Return Value: None */ -void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list) +static void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list) { memset(list,0,sizeof(N_HDLC_BUF_LIST)); spin_lock_init(&list->spinlock); @@ -922,7 +926,7 @@ * * Return Value: None */ -void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf) +static void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf) { unsigned long flags; spin_lock_irqsave(&list->spinlock,flags); @@ -952,7 +956,7 @@ * * pointer to HDLC buffer if available, otherwise NULL */ -N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list) +static N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list) { unsigned long flags; N_HDLC_BUF *buf; @@ -1025,5 +1029,4 @@ module_init(n_hdlc_init); module_exit(n_hdlc_exit); -MODULE_LICENSE("GPL"); EXPORT_NO_SYMBOLS; Index: drivers/char/n_r3964.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/n_r3964.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/n_r3964.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/n_r3964.c 4 Aug 2004 01:28:44 -0000 1.2 @@ -13,8 +13,8 @@ * L. Haag * * $Log: n_r3964.c,v $ - * Revision 1.1 2004/07/22 19:49:51 joff - * Initial revision + * Revision 1.2 2004/08/04 01:28:44 joff + * merging 2.4.26-vrs1 * * Revision 1.8 2000/03/23 14:14:54 dwmw2 * Fix race in sleeping in r3964_read() @@ -220,7 +220,7 @@ { int status; - printk ("r3964: Philips r3964 Driver $Revision: 1.1 $\n"); + printk ("r3964: Philips r3964 Driver $Revision: 1.2 $\n"); /* * Register the tty line discipline Index: drivers/char/n_tty.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/n_tty.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/char/n_tty.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/n_tty.c 7 Mar 2008 19:32:51 -0000 1.3 @@ -962,7 +962,7 @@ ssize_t retval = 0; ssize_t size; long timeout; - unsigned long flags; + unsigned long flags,flags2; do_it_again: @@ -1021,6 +1021,7 @@ } add_wait_queue(&tty->read_wait, &wait); + save_flags_cli(flags2); set_bit(TTY_DONT_FLIP, &tty->flags); while (nr) { /* First test for status change. */ @@ -1061,7 +1062,9 @@ break; } clear_bit(TTY_DONT_FLIP, &tty->flags); + restore_flags(flags2); timeout = schedule_timeout(timeout); + save_flags_cli(flags2); set_bit(TTY_DONT_FLIP, &tty->flags); continue; } @@ -1128,6 +1131,7 @@ timeout = time; } clear_bit(TTY_DONT_FLIP, &tty->flags); + restore_flags(flags2); up(&tty->atomic_read); remove_wait_queue(&tty->read_wait, &wait); @@ -1238,7 +1242,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; } Index: drivers/char/pcwd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/pcwd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/pcwd.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/pcwd.c 4 Aug 2004 01:28:44 -0000 1.2 @@ -933,8 +933,7 @@ release_region (pcwd_info.io_addr, pcwd_info.card_info->io_size); - if (pcwd_info.flags & PCWD_PCI_REG) - pci_unregister_driver (&pcwd_driver); + pci_unregister_driver (&pcwd_driver); return; } Index: drivers/char/q40_keyb.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/q40_keyb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/q40_keyb.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/q40_keyb.c 4 Aug 2004 01:28:44 -0000 1.2 @@ -400,7 +400,7 @@ #define KBD_NO_DATA (-1) /* No data */ #define KBD_BAD_DATA (-2) /* Parity or other error */ -static int __init kbd_read_input(void) +static int __init q40kbd_read_input(void) { int retval = KBD_NO_DATA; unsigned char status; @@ -421,7 +421,7 @@ int maxread = 100; /* Random number */ do { - if (kbd_read_input() == KBD_NO_DATA) + if (q40kbd_read_input() == KBD_NO_DATA) break; } while (--maxread); } Index: drivers/char/qtronixmap.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/qtronixmap.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/qtronixmap.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/qtronixmap.c 4 Aug 2004 01:28:44 -0000 1.2 @@ -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; Index: drivers/char/random.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/random.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/random.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/random.c 4 Aug 2004 01:28:44 -0000 1.2 @@ -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 @@ -713,7 +715,9 @@ static struct timer_rand_state keyboard_timer_state; static struct timer_rand_state mouse_timer_state; static struct timer_rand_state extract_timer_state; +#ifndef CONFIG_ARCH_S390 static struct timer_rand_state *irq_timer_state[NR_IRQS]; +#endif static struct timer_rand_state *blkdev_timer_state[MAX_BLKDEV]; /* @@ -789,6 +793,7 @@ batch_entropy_store(num, time, entropy); } +#ifndef CONFIG_ARCH_S390 void add_keyboard_randomness(unsigned char scancode) { static unsigned char last_scancode; @@ -811,6 +816,7 @@ add_timer_randomness(irq_timer_state[irq], 0x100+irq); } +#endif void add_blkdev_randomness(int major) { @@ -1443,8 +1449,10 @@ #ifdef CONFIG_SYSCTL sysctl_init_random(random_state); #endif +#ifndef CONFIG_ARCH_S390 for (i = 0; i < NR_IRQS; i++) irq_timer_state[i] = NULL; +#endif for (i = 0; i < MAX_BLKDEV; i++) blkdev_timer_state[i] = NULL; memset(&keyboard_timer_state, 0, sizeof(struct timer_rand_state)); @@ -1453,6 +1461,7 @@ extract_timer_state.dont_count_entropy = 1; } +#ifndef CONFIG_ARCH_S390 void rand_initialize_irq(int irq) { struct timer_rand_state *state; @@ -1470,6 +1479,7 @@ irq_timer_state[irq] = state; } } +#endif void rand_initialize_blkdev(int major, int mode) { @@ -2069,7 +2079,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 +2089,7 @@ mb(); ip_cnt++; } - spin_unlock(&ip_lock); + spin_unlock_bh(&ip_lock); return keyptr; } @@ -2302,9 +2312,11 @@ +#ifndef CONFIG_ARCH_S390 EXPORT_SYMBOL(add_keyboard_randomness); EXPORT_SYMBOL(add_mouse_randomness); EXPORT_SYMBOL(add_interrupt_randomness); +#endif EXPORT_SYMBOL(add_blkdev_randomness); EXPORT_SYMBOL(batch_entropy_store); EXPORT_SYMBOL(generate_random_uuid); Index: drivers/char/rocket.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/rocket.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/rocket.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/rocket.c 4 Aug 2004 01:28:44 -0000 1.2 @@ -1944,6 +1944,10 @@ str = "8J"; max_num_aiops = 1; break; + case PCI_DEVICE_ID_RP4J: + str = "4J"; + max_num_aiops = 1; + break; case PCI_DEVICE_ID_RP16INTF: str = "16"; max_num_aiops = 2; @@ -2006,6 +2010,10 @@ PCI_DEVICE_ID_RP8J, i, &bus, &device_fn)) if (register_PCI(count+boards_found, bus, device_fn)) count++; + if (!pcibios_find_device(PCI_VENDOR_ID_RP, + PCI_DEVICE_ID_RP4J, i, &bus, &device_fn)) + if (register_PCI(count+boards_found, bus, device_fn)) + count++; if(!pcibios_find_device(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP8OCTA, i, &bus, &device_fn)) if(register_PCI(count+boards_found, bus, device_fn)) @@ -2031,6 +2039,10 @@ if(register_PCI(count+boards_found, bus, device_fn)) count++; if(!pcibios_find_device(PCI_VENDOR_ID_RP, + PCI_DEVICE_ID_RP4J, i, &bus, &device_fn)) + if(register_PCI(count+boards_found, bus, device_fn)) + count++; + if(!pcibios_find_device(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RPP4, i, &bus, &device_fn)) if(register_PCI(count+boards_found, bus, device_fn)) count++; Index: drivers/char/rocket_int.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/rocket_int.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/rocket_int.h 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/rocket_int.h 4 Aug 2004 01:28:44 -0000 1.2 @@ -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. - * */ /* @@ -1199,6 +1200,9 @@ #ifndef PCI_DEVICE_ID_RP8J #define PCI_DEVICE_ID_RP8J 0x0006 #endif +#ifndef PCI_DEVICE_ID_RP4J +#define PCI_DEVICE_ID_RP4J 0x0007 +#endif #ifndef PCI_DEVICE_ID_RPP4 #define PCI_DEVICE_ID_RPP4 0x000A #endif Index: drivers/char/rtc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/rtc.c,v retrieving revision 1.1 retrieving revision 1.9 diff -u -r1.1 -r1.9 --- drivers/char/rtc.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/rtc.c 16 Jan 2009 19:55:40 -0000 1.9 @@ -35,17 +35,16 @@ * 1.09a Pete Zaitcev: Sun SPARC * 1.09b Jeff Garzik: Modularize, init cleanup * 1.09c Jeff Garzik: SMP cleanup - * 1.10 Paul Barton-Davis: add support for async I/O + * 1.10 Paul Barton-Davis: add support for async I/O * 1.10a Andrea Arcangeli: Alpha updates * 1.10b Andrew Morton: SMP lock fix * 1.10c Cesar Barros: SMP locking fixes and cleanup * 1.10d Paul Gortmaker: delete paranoia check in rtc_exit * 1.10e Maciej W. Rozycki: Handle DECstation's year weirdness. + * 1.10f Maciej W. Rozycki: Handle memory-mapped chips properly. */ -#define RTC_VERSION "1.10e" - -#define RTC_IO_EXTENT 0x10 /* Only really two ports, but... */ +#define RTC_VERSION "1.10f" /* * Note that *all* calls to CMOS_READ and CMOS_WRITE are done with @@ -68,6 +67,7 @@ #include #include #include +#include #include #include @@ -80,11 +80,269 @@ #include #endif + + static unsigned long rtc_port; static int rtc_irq = PCI_IRQ_NONE; #endif +#if RTC_IRQ static int rtc_has_irq = 1; +#endif + +int cmos_method_old = 1, cmos_method_boc = 0; + +#define TS_MODEL_REG 0x2000000 +#define TS_MODEL_7400 4 + +//Prosoft RTC support +volatile static unsigned char *ts7350_rtc = NULL; +volatile static unsigned short *ts7350_pc104 = NULL; + +#define TS7350_RTC_BASE 0x600ff000 +#define TS7350_RTC_SIZE 0x00001000 +#define TS7350_RTC_INDEX 0x00000870 //0x600ff870 +#define TS7350_RTC_DATA 0x00000871 //0x600ff871 +#define TS7350_PC104_BASE 0x600ff000 +#define TS7350_PC104_SIZE 0x00000100 +#define TS7350_PC104_A_LOW 0x0000004c //0x600ff098 +#define TS7350_PC104_A_UPPER 0x0000004d //0x600ff09a +#define TS7350_PC104_B_LOW 0x0000004e //0x600ff09c +#define TS7350_PC104_B_UPPER 0x0000004f //0x600ff09e +#define TS7350_PC104_ISACONF 0x0000006a //0x600ff0d4 + +#define RESTORE_PC104 config_pc104(1) +#define SETUP_PC104 config_pc104(0) + +static inline void config_pc104(int restore) +{ + static unsigned short a_lower, a_upper, b_lower, b_upper, isaconf; + + if (restore) { + + //save PC/104 status regs + ts7350_pc104[TS7350_PC104_A_LOW] = a_lower; + ts7350_pc104[TS7350_PC104_A_UPPER] = a_upper; + ts7350_pc104[TS7350_PC104_B_LOW] = b_lower; + ts7350_pc104[TS7350_PC104_B_UPPER] = b_upper; + ts7350_pc104[TS7350_PC104_B_UPPER] = isaconf; + + } else { + + if (!ts7350_rtc) + ts7350_rtc = (unsigned char *) + __ioremap(TS7350_RTC_BASE, TS7350_RTC_SIZE, 0); + + if (!ts7350_pc104) + ts7350_pc104 = (unsigned short *) + __ioremap(TS7350_PC104_BASE, TS7350_PC104_SIZE, 0); + + //save PC/104 status regs + a_lower = ts7350_pc104[TS7350_PC104_A_LOW]; + a_upper = ts7350_pc104[TS7350_PC104_A_UPPER]; + b_lower = ts7350_pc104[TS7350_PC104_B_LOW]; + b_upper = ts7350_pc104[TS7350_PC104_B_UPPER]; + isaconf = ts7350_pc104[TS7350_PC104_ISACONF]; + + //configure PC/104 connector for PC/104 bus + //we need to do this to talk to the RTC + ts7350_pc104[TS7350_PC104_A_LOW] = 0x5555; + ts7350_pc104[TS7350_PC104_A_UPPER] = 0x5555; + ts7350_pc104[TS7350_PC104_B_LOW] = 0x5555; + ts7350_pc104[TS7350_PC104_B_UPPER] = 0x5555; + + //setup PC/104 setup time and hold time + ts7350_pc104[TS7350_PC104_ISACONF] = 0x1ef; + + //ensure RTC battery is enabled + ts7350_rtc[TS7350_RTC_INDEX] = 0xa; + ts7350_rtc[TS7350_RTC_DATA] = 0x20; + } +} + +static unsigned char ts7350_rtc_readbyte(unsigned long addr) +{ + unsigned char value; + + SETUP_PC104; + ts7350_rtc[TS7350_RTC_INDEX] = addr; + value = ts7350_rtc[TS7350_RTC_DATA]; + RESTORE_PC104; + + return value; +} + +static void ts7350_rtc_writebyte(unsigned char value, unsigned long addr) +{ + SETUP_PC104; + ts7350_rtc[TS7350_RTC_INDEX] = addr; + ts7350_rtc[TS7350_RTC_DATA] = value; + RESTORE_PC104; +} + +static inline int get_ts_model(void) { + return (inw(TS7XXX_IO16_BASE + TS_MODEL_REG)) & 7; +} + +static inline unsigned char CMOSREAD_OLD(int addr) { + return CMOS_READ(addr); +} + +static inline unsigned char CMOSWRITE_OLD(unsigned char byte,int addr) { + return CMOS_WRITE(byte,addr); +} + +#undef CMOS_READ +#undef CMOS_WRITE + + + +static inline unsigned char CMOSREAD_BOC(int addr) { + outb_p((addr), BOC_RTCIDX); + return inb_p(BOC_RTCDATA); +} + +static inline unsigned char CMOSWRITE_BOC(unsigned char val,int addr) { + outb_p((addr), BOC_RTCIDX); + outb_p((val), BOC_RTCDATA); +} + + +void setRTCdata(unsigned char ch) { + volatile unsigned char *dr = (void *)IO_ADDRESS(0x80840000); + volatile unsigned char *ddr = (void *)IO_ADDRESS(0x80840010); + + *ddr = 0xFF; + *dr = ch; + //printk("DR wrote %02X, read %02X (DDR=%02X)\n",ch,*dr,*ddr); +} + +unsigned char getRTCdata(void) { + volatile unsigned char *dr = (void *)IO_ADDRESS(0x80840000); + volatile unsigned char *ddr = (void *)IO_ADDRESS(0x80840010); + + *ddr = 0x00; + return *dr; +} + +void setRTC_RD(int en) { + volatile unsigned char *dr = (void *)IO_ADDRESS(0x80840040); + volatile unsigned char *ddr = (void *)IO_ADDRESS(0x80840044); + + *ddr = *ddr | 8; + *dr = !en ? (*dr | 8) : (*dr & 0xF7); +} + +void setRTC_CS(int en) { + volatile unsigned char *dr = (void *)IO_ADDRESS(0x80840040); + volatile unsigned char *ddr = (void *)IO_ADDRESS(0x80840044); + + *ddr = *ddr | 32; + *dr = !en ? (*dr | 32) : (*dr & 0xDF); +} + +void setRTC_ALE(int en) { + volatile unsigned char *dr = (void *)IO_ADDRESS(0x80840040); + volatile unsigned char *ddr = (void *)IO_ADDRESS(0x80840044); + + *ddr = *ddr | 16; + *dr = en ? (*dr | 16) : (*dr & 0xEF); +} + +void setRTC_WR(int en) { + volatile unsigned char *dr = (void *)IO_ADDRESS(0x80840030); + volatile unsigned char *ddr = (void *)IO_ADDRESS(0x80840034); + + *ddr = *ddr | 8; + *dr = !en ? (*dr | 8) : (*dr & 0xF7); +} + +static inline unsigned char CMOSREAD_NEW(int addr) { + unsigned char ch; + + setRTC_RD(0); + udelay(1); + setRTC_WR(0); + udelay(1); + setRTC_ALE(0); + udelay(1); + setRTC_CS(1); + udelay(1); + setRTCdata(addr); + udelay(1); + setRTC_ALE(1); + udelay(1); + setRTC_ALE(0); + udelay(1); + getRTCdata(); // turn bus around + udelay(1); + setRTC_RD(1); + udelay(1); + ch = getRTCdata(); + udelay(1); + setRTC_RD(0); + udelay(1); + setRTC_CS(0); + //printk("CMOS_READ @%X -> %X\n",addr,ch); + return ch; +} + +static inline unsigned char CMOSWRITE_NEW(unsigned char ch,int addr) { + //printk("CMOS_WRITE @%X <- %X\n",addr,ch); + setRTC_RD(0); + udelay(1); + setRTC_WR(0); + udelay(1); + setRTC_ALE(0); + udelay(1); + setRTC_CS(1); + udelay(1); + setRTC_ALE(1); + udelay(1); + setRTCdata(addr); + udelay(1); + setRTC_ALE(0); + udelay(1); + setRTC_WR(1); + udelay(1); + setRTCdata(ch); + udelay(1); + setRTC_WR(0); + udelay(1); + setRTC_CS(0); + return ch; +} + +static inline unsigned char CMOS_READ(int addr) { +#ifndef CONFIG_PROSOFT_RTC + return (cmos_method_boc) ? CMOSREAD_BOC(addr) : + (cmos_method_old) ? CMOSREAD_OLD(addr) : CMOSREAD_NEW(addr); +#else +return ts7350_rtc_readbyte((unsigned long) addr); +#endif +} + +static inline unsigned char CMOS_WRITE(unsigned char byte,int addr) { +#ifndef CONFIG_PROSOFT_RTC + return (cmos_method_boc) ? CMOSWRITE_BOC(byte,addr) : + (cmos_method_old) ? CMOSWRITE_OLD(byte,addr):CMOSWRITE_NEW(byte,addr); +#else + ts7350_rtc_writebyte(byte, (unsigned long) addr); +#endif +} + +void CMOS_INIT(void) { +#ifndef CONFIG_PROSOFT_RTC + + volatile unsigned *dr = (void *)IO_ADDRESS(0x809300C0); + + *dr = 0xAA; + dr = (void *)IO_ADDRESS(0x80930080); + *dr = 0x08140d00; +#endif + + CMOS_WRITE(0x20,0xa); +} /* * We sponge a minor off of the misc major. No need slurping @@ -97,7 +355,9 @@ static DECLARE_WAIT_QUEUE_HEAD(rtc_wait); +#if RTC_IRQ static struct timer_list rtc_irq_timer; +#endif static ssize_t rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos); @@ -238,14 +498,22 @@ if (rtc_has_irq == 0) return -EIO; - if (count < sizeof(unsigned long)) + /* + * Historically this function used to assume that sizeof(unsigned long) + * is the same in userspace and kernelspace. This lead to problems + * for configurations with multiple ABIs such a the MIPS o32 and 64 + * ABIs supported on the same kernel. So now we support read of both + * 4 and 8 bytes and assume that's the sizeof(unsigned long) in the + * userspace ABI. + */ + if (count != sizeof(unsigned int) && count != sizeof(unsigned long)) return -EINVAL; add_wait_queue(&rtc_wait, &wait); - - current->state = TASK_INTERRUPTIBLE; do { + __set_current_state(TASK_INTERRUPTIBLE); + /* First make it right. Then make it fast. Putting this whole * block within the parentheses of a while would be too * confusing. And no, xchg() is not the answer. */ @@ -268,9 +536,12 @@ schedule(); } while (1); - retval = put_user(data, (unsigned long *)buf); + if (count == sizeof(unsigned int)) + retval = put_user(data, (unsigned int *)buf); + else + retval = put_user(data, (unsigned long *)buf); if (!retval) - retval = sizeof(unsigned long); + retval = count; out: current->state = TASK_RUNNING; remove_wait_queue(&rtc_wait, &wait); @@ -362,7 +633,7 @@ * means "don't care" or "match all". Only the tm_hour, * tm_min, and tm_sec values are filled in. */ - + memset(&wtime, 0, sizeof(struct rtc_time)); get_rtc_alm_time(&wtime); break; } @@ -406,6 +677,7 @@ } case RTC_RD_TIME: /* Read the time/date from RTC */ { + memset(&wtime, 0, sizeof(struct rtc_time)); get_rtc_time(&wtime); break; } @@ -706,6 +978,14 @@ struct isa_device *isa_dev; #endif #endif +#ifndef __sparc__ + void *r; +#endif + + if (get_ts_model() == 4) { + printk("Using DIO to access RTC\n"); + cmos_method_old = 0; + } #ifdef __sparc__ for_each_ebus(ebus) { @@ -752,18 +1032,56 @@ } no_irq: #else - if (!request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc")) + +#ifdef CONFIG_TS_RTC { - printk(KERN_ERR "rtc: I/O port %d is not free.\n", RTC_PORT (0)); + unsigned char i; + + CMOS_INIT(); + CMOS_WRITE(0xaa, 0x7f); + i = CMOS_READ(0x7f) ^ 0xaa; + CMOS_WRITE(0x55, 0x7e); + i |= CMOS_READ(0x7e) ^ 0x55; + if (i != 0) { + if (cmos_method_old) { + cmos_method_boc = 1; + CMOS_INIT(); // try the above again with BOC access method + CMOS_WRITE(0xaa, 0x7f); + i = CMOS_READ(0x7f) ^ 0xaa; + CMOS_WRITE(0x55, 0x7e); + i |= CMOS_READ(0x7e) ^ 0x55; + } + if (i != 0) { + cmos_method_boc = 0; + printk("rtc: no TS-5620 RTC detected.\n"); + return -EIO; + } + } + while((CMOS_READ(0xa) & 0x80) != 0); + // BCD mode, 24 hr mode + CMOS_WRITE(0x2, 0xb); + + } +#endif + + if (RTC_IOMAPPED) + r = request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc"); + else + r = request_mem_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc"); + if (!r) { + printk(KERN_ERR "rtc: I/O resource %lx is not free.\n", + (long)(RTC_PORT(0))); return -EIO; } #if RTC_IRQ - if(request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "rtc", NULL)) - { + if(request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "rtc", NULL)) { /* Yeah right, seeing as irq 8 doesn't even hit the bus. */ printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ); - release_region(RTC_PORT(0), RTC_IO_EXTENT); + if (RTC_IOMAPPED) + release_region(RTC_PORT(0), RTC_IO_EXTENT); + else + release_mem_region(RTC_PORT(0), RTC_IO_EXTENT); return -EIO; } #endif @@ -847,7 +1165,10 @@ if (rtc_has_irq) free_irq (rtc_irq, &rtc_port); #else - release_region (RTC_PORT (0), RTC_IO_EXTENT); + if (RTC_IOMAPPED) + release_region(RTC_PORT(0), RTC_IO_EXTENT); + else + release_mem_region(RTC_PORT(0), RTC_IO_EXTENT); #if RTC_IRQ if (rtc_has_irq) free_irq (RTC_IRQ, NULL); Index: drivers/char/sb1250_duart.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/sb1250_duart.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/sb1250_duart.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/sb1250_duart.c 4 Aug 2004 01:28:45 -0000 1.2 @@ -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) { + 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,87 @@ 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); + WRITE_SERCSR(M_DUART_RX_EN|M_DUART_TX_EN, + port->cmd, 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 +930,4 @@ register_console(&sb1250_ser_cons); } -#endif /* CONFIG_SERIAL_CONSOLE */ +#endif /* CONFIG_SIBYTE_SB1250_DUART_CONSOLE */ Index: drivers/char/sbc60xxwdt.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/sbc60xxwdt.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/sbc60xxwdt.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/sbc60xxwdt.c 4 Aug 2004 01:28:45 -0000 1.2 @@ -335,7 +335,7 @@ release_region(WDT_START,1); err_out_region1: release_region(WDT_STOP,1); -err_out: +/* err_out: */ return rc; } Index: drivers/char/scan_keyb.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/scan_keyb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/scan_keyb.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/scan_keyb.c 4 Aug 2004 01:28:45 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: scan_keyb.c,v 1.1 2004/07/22 19:49:50 joff Exp $ + * $Id: scan_keyb.c,v 1.2 2004/08/04 01:28:45 joff Exp $ * Copyright (C) 2000 YAEGASHI Takeshi * Generic scan keyboard driver */ Index: drivers/char/scan_keyb.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/scan_keyb.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/scan_keyb.h 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/scan_keyb.h 4 Aug 2004 01:28:45 -0000 1.2 @@ -1,7 +1,7 @@ #ifndef __DRIVER_CHAR_SCAN_KEYB_H #define __DRIVER_CHAR_SCAN_KEYB_H /* - * $Id: scan_keyb.h,v 1.1 2004/07/22 19:49:50 joff Exp $ + * $Id: scan_keyb.h,v 1.2 2004/08/04 01:28:45 joff Exp $ * Copyright (C) 2000 YAEGASHI Takeshi * Generic scan keyboard driver */ Index: drivers/char/ser_a2232.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ser_a2232.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ser_a2232.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/ser_a2232.c 4 Aug 2004 01:28:45 -0000 1.2 @@ -1,6 +1,6 @@ /* drivers/char/ser_a2232.c */ -/* $Id: ser_a2232.c,v 1.1 2004/07/22 19:49:52 joff Exp $ */ +/* $Id: ser_a2232.c,v 1.2 2004/08/04 01:28:45 joff Exp $ */ /* Linux serial driver for the Amiga A2232 board */ @@ -776,7 +776,7 @@ volatile u_char *to; volatile struct a2232memory *mem; -#ifdef __SMP__ +#ifdef CONFIG_SMP return -ENODEV; /* This driver is not SMP aware. Is there an SMP ZorroII-bus-machine? */ #endif Index: drivers/char/ser_a2232.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ser_a2232.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ser_a2232.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/ser_a2232.h 4 Aug 2004 01:28:45 -0000 1.2 @@ -1,6 +1,6 @@ /* drivers/char/ser_a2232.h */ -/* $Id: ser_a2232.h,v 1.1 2004/07/22 19:49:52 joff Exp $ */ +/* $Id: ser_a2232.h,v 1.2 2004/08/04 01:28:45 joff Exp $ */ /* Linux serial driver for the Amiga A2232 board */ Index: drivers/char/ser_a2232fw.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ser_a2232fw.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ser_a2232fw.h 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/ser_a2232fw.h 4 Aug 2004 01:28:45 -0000 1.2 @@ -1,6 +1,6 @@ /* drivers/char/ser_a2232fw.h */ -/* $Id: ser_a2232fw.h,v 1.1 2004/07/22 19:49:50 joff Exp $ */ +/* $Id: ser_a2232fw.h,v 1.2 2004/08/04 01:28:45 joff Exp $ */ /* * Copyright (c) 1995 Jukka Marin . Index: drivers/char/serial.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/serial.c,v retrieving revision 1.1 retrieving revision 1.7 diff -u -r1.1 -r1.7 --- drivers/char/serial.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/serial.c 20 Oct 2005 21:21:55 -0000 1.7 @@ -222,6 +222,7 @@ #ifdef CONFIG_MAGIC_SYSRQ #include #endif +#include /* * All of the compatibilty code so we can compile serial.c against @@ -421,6 +422,15 @@ outb(info->hub6 - 1 + offset, info->port); return inb(info->port+1); #endif + case SERIAL_IO_TS7KV: + { + int swin = inb(info->port + 0x1e); + int ret; + outb(0x0, info->port + 0x1e); + ret = inb(info->port + offset); + outb(swin, info->port + 0x1e); + return ret; + } case SERIAL_IO_MEM: return readb((unsigned long) info->iomem_base + (offset<iomem_reg_shift)); @@ -439,6 +449,14 @@ outb(value, info->port+1); break; #endif + case SERIAL_IO_TS7KV: + { + int swin = inb(info->port + 0x1e); + outb(0x0, info->port + 0x1e); + outb(value, info->port + offset); + outb(swin, info->port + 0x1e); + break; + } case SERIAL_IO_MEM: writeb(value, (unsigned long) info->iomem_base + (offset<iomem_reg_shift)); @@ -914,10 +932,15 @@ if (status & UART_LSR_DR) receive_chars(info, &status, regs); check_modem_status(info); +#ifdef CONFIG_MELAN if ((status & UART_LSR_THRE) || /* For buggy ELAN processors */ ((iir & UART_IIR_ID) == UART_IIR_THRI)) transmit_chars(info, 0); +#else + if (status & UART_LSR_THRE) + transmit_chars(info, 0); +#endif if (pass_counter++ > RS_ISR_PASS_LIMIT) { #if SERIAL_DEBUG_INTR printk("rs_single loop break.\n"); @@ -2696,6 +2719,24 @@ /* "setserial -W" is called in Debian boot */ printk ("TIOCSER?WILD ioctl obsolete, ignored.\n"); return 0; + case TIOC_SBCC485: + if (info->io_type != SERIAL_IO_TS7KV) + return -EINVAL; + + serial_out(info, 0x8, serial_in(info, 0x8) & ~0x1); + return 0; + + case TIOC_SBCS485: + if (info->io_type != SERIAL_IO_TS7KV) + return -EINVAL; + + if (arg & AUTO485FD) + serial_out(info, 0x8, 0x3); + + if (arg & AUTO485HD) + serial_out(info, 0x8, 0x1); + + return 0; default: return -ENOIOCTLCMD; @@ -3741,7 +3782,14 @@ /* Check for Startech UART's */ serial_outp(info, UART_LCR, UART_LCR_DLAB); if (serial_in(info, UART_EFR) == 0) { + serial_outp(info, UART_EFR, 0xA8); + if (serial_in(info, UART_EFR) == 0) { + /* We are a NS16552D/Motorola + * 8xxx DUART, stop. */ + goto out; + } state->type = PORT_16650; + serial_outp(info, UART_EFR, 0); } else { serial_outp(info, UART_LCR, 0xBF); if (serial_in(info, UART_EFR) == 0) @@ -3790,6 +3838,7 @@ } } #endif +out: serial_outp(info, UART_LCR, save_lcr); if (state->type == PORT_16450) { scratch = serial_in(info, UART_SCR); @@ -4353,9 +4402,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 +4499,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 }, @@ -4920,11 +4971,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, }, Index: drivers/char/serial167.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/serial167.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/serial167.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/serial167.c 4 Aug 2004 01:28:45 -0000 1.2 @@ -9,7 +9,7 @@ * ============================================================== * * static char rcsid[] = - * "$Revision: 1.1 $$Date: 2004/07/22 19:49:52 $"; + * "$Revision: 1.2 $$Date: 2004/08/04 01:28:45 $"; * * linux/kernel/cyclades.c * @@ -28,8 +28,8 @@ * int cy_open(struct tty_struct *tty, struct file *filp); * * $Log: serial167.c,v $ - * Revision 1.1 2004/07/22 19:49:52 joff - * Initial revision + * Revision 1.2 2004/08/04 01:28:45 joff + * merging 2.4.26-vrs1 * * Revision 1.36.1.4 1995/03/29 06:14:14 bentson * disambiguate between Cyclom-16Y and Cyclom-32Ye; Index: drivers/char/serial9bit.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/serial9bit.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/char/serial9bit.c 12 Oct 2005 17:31:21 -0000 1.1 +++ drivers/char/serial9bit.c 1 Nov 2005 01:55:43 -0000 1.3 @@ -1,5 +1,5 @@ /* - * 9-bit serial port driver for Oxford 16550 UARTs. + * 9-bit serial port driver for Oxford 16550 UARTs. */ #include @@ -11,51 +11,498 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include #include #include +#include +#include -static int serial9bit_users; -static int serial9bit_base; +MODULE_AUTHOR("Ronald Gomes"); +MODULE_DESCRIPTION("9-bit serial driver for TS-SER1 PC104 board from Technologic Systems"); +MODULE_LICENSE("GPL"); + +char *name="serial9bit"; +int io=-1; +int irq=-1; + +MODULE_PARM(name, "1s"); +MODULE_PARM_DESC(name,"Name of the 9-bit serial /dev entry."); +MODULE_PARM(io, "1i"); +MODULE_PARM_DESC(io,"IO address for 9-bit serial board"); +MODULE_PARM(irq, "1i"); +MODULE_PARM_DESC(irq,"IRQ line for 9-bit serial board"); + + +#define TSISA_BASE_IO 0x01E00000 + +#define TSSER1_BASE_IO 0x02E8 +#define TSSER2_BASE_IO 0x03E8 +#define TSSER3_BASE_IO 0x03EA +#define TSSER_SIZE_IO 0x8 + +static int users; + +typedef struct serial9bit_dev { + char *name; + int io; + int irq; + unsigned long base_addr; + int bakACR; +} serial9bit_dev; + +static struct serial9bit_dev *dev; + +DECLARE_WAIT_QUEUE_HEAD (rqueue); +DECLARE_WAIT_QUEUE_HEAD (wqueue); + +#ifdef DECLARE_MUTEX +static DECLARE_MUTEX(sem); +#else +static struct semaphore sem = MUTEX; +#endif + +/* + * OX16C950 REGISTER DEFINES + */ + +//Standard 550 Compatible Registers +#define THR_OFFSET 0x00 +#define RHR_OFFSET 0x00 +#define IER_OFFSET 0x01 +#define FCR_OFFSET 0x02 +#define ISR_OFFSET 0x02 +#define LCR_OFFSET 0x03 +#define MCR_OFFSET 0x04 +#define LSR_OFFSET 0x05 +#define MSR_OFFSET 0x06 +#define SPR_OFFSET 0x07 +#define DLL_OFFSET 0x00 +#define DLM_OFFSET 0x01 + +//650 Compatible Registers +#define EFR_OFFSET 0x02 +#define XON1_OFFSET 0x04 +#define XON2_OFFSET 0x05 +#define XOFF1_OFFSET 0x06 +#define XOFF2_OFFSET 0x07 + +//950 Specific Registers +#define ASR_OFFSET 0x01 +#define RFL_OFFSET 0x03 +#define TFL_OFFSET 0x04 +#define ICR_OFFSET 0x05 + +//Indexed Control Register Set +#define ACR_INDEX 0x00 +#define CPR_INDEX 0x01 +#define TCR_INDEX 0x02 +#define CKS_INDEX 0x03 +#define TTL_INDEX 0x04 +#define RTL_INDEX 0x05 +#define FCL_INDEX 0x06 +#define FCH_INDEX 0x07 +#define ID1_INDEX 0x08 +#define ID2_INDEX 0x09 +#define ID3_INDEX 0x0A +#define REV_INDEX 0x0B +#define CSR_INDEX 0x0C +#define NMR_INDEX 0x0D +#define MDM_INDEX 0x0E +#define RFC_INDEX 0x0F +#define GDS_INDEX 0x10 +#define DMS_INDEX 0x11 +#define PIDX_INDEX 0x12 +#define CKA_INDEX 0x13 + +//Misc - Bits +#define RECEIVE_FIFO 0x00 +#define TRANSMIT_FIFO 0x01 +#define LCR_DL_ACCESS_KEY 0x80 +#define LCR_650_ACCESS_KEY 0xBF +#define ACR_ICR_READ_EN 0x40 +#define FCR_FIFO_EN 0x01 +#define EFR_ENHANCED_MODE_EN 0x10 +#define NMR_9BIT_MODE_EN 0x01 +#define NMR_9BIT_INTERRUPT_EN 0x02 +#define ACR_950_READ_EN 0x40 +#define LSR_DATA_AVAILABLE 0x01 +#define LSR_FIFO_EMPTY 0x20 + +//LSR error handler +#define LSR_OVERRUN_ERROR 0x02 +#define LSR_PARITY_ERROR 0x04 +#define LSR_FRAMING_ERROR 0x08 +#define LSR_BREAK 0x10 +#define LSR_DATA_ERROR 0x80 +#define LSR_ERROR_MASK (LSR_FRAMING_ERROR | LSR_BREAK | LSR_DATA_ERROR) + +//Baud Rate Divisor +#define DIVISOR_BAUD_110 0x0300 +#define DIVISOR_BAUD_300 0x0180 +#define DIVISOR_BAUD_600 0x00C0 +#define DIVISOR_BAUD_1200 0x0060 +#define DIVISOR_BAUD_2400 0x0030 +#define DIVISOR_BAUD_4800 0x0018 +#define DIVISOR_BAUD_9600 0x000C +#define DIVISOR_BAUD_19200 0x0006 +#define DIVISOR_BAUD_28800 0x0004 +#define DIVISOR_BAUD_38400 0x0003 +#define DIVISOR_BAUD_57600 0x0002 +#define DIVISOR_BAUD_115200 0x0001 + +//Interrupts +#define IER_RX_INTERRUPT_EN 0x01 +#define IER_TX_INTERRUPT_EN 0x02 +#define IER_LSTAT_INTERRUPT_EN 0x04 +#define IER_MSTAT_INTERRUPT_EN 0x08 +#define IER_CHR_INTERRUPT_EN 0x20 +#define IER_RTS_INTERRUPT_EN 0x40 +#define IER_CTS_INTERRUPT_EN 0x80 + +//Type match +#define FALSE 0 +#define TRUE 1 + +//Functions declarations +unsigned char readReg(serial9bit_dev *dev, unsigned char offset); +void writeReg(serial9bit_dev *dev, unsigned char offset, unsigned char value); +unsigned short readDivisor(serial9bit_dev *dev); +void writeDivisor(serial9bit_dev *dev, unsigned short divisor); +unsigned char read650(serial9bit_dev *dev, unsigned char offset); +void write650(serial9bit_dev *dev, unsigned char offset, unsigned char value); +unsigned char readASR(serial9bit_dev *dev); +void writeASRBit(serial9bit_dev *dev, unsigned char bit, unsigned char value); +unsigned char readICR(serial9bit_dev *dev, unsigned char index); +void writeICR(serial9bit_dev *dev, unsigned char index, unsigned char value); +unsigned char readFIFOLevel(serial9bit_dev *dev, unsigned char fifo); +void lockAdditionalStatus(serial9bit_dev *dev); +void unlockAdditionalStatus(serial9bit_dev *dev); + + +/* + * Implementation section of basic functions + */ + +//read-write basic routines for registers +unsigned char readReg(serial9bit_dev *dev, unsigned char offset) +{ + return inb(dev->base_addr + offset); +} + +void writeReg(serial9bit_dev *dev, unsigned char offset, unsigned char value) +{ + outb(value, dev->base_addr + offset); +} + +//divisor latch word registers +unsigned short readDivisor(serial9bit_dev *dev) +{ + unsigned short dlldlm; + unsigned char oldLCR; + oldLCR = readReg(dev, LCR_OFFSET); + writeReg(dev, LCR_OFFSET, oldLCR|LCR_DL_ACCESS_KEY); + dlldlm = (readReg(dev, DLM_OFFSET)<<8); + dlldlm += readReg(dev, DLL_OFFSET); + writeReg(dev, LCR_OFFSET, oldLCR); + return dlldlm; +} + +void writeDivisor(serial9bit_dev *dev, unsigned short divisor) +{ + unsigned char oldLCR; + oldLCR = readReg(dev, LCR_OFFSET); + writeReg(dev, LCR_OFFSET, oldLCR|LCR_DL_ACCESS_KEY); + writeReg(dev, DLL_OFFSET, divisor&0x00FF ); + writeReg(dev, DLM_OFFSET, (divisor&0xFF00)>>8 ); + writeReg(dev, LCR_OFFSET, oldLCR); +} + +//650 compatible registers. +unsigned char read650(serial9bit_dev *dev, unsigned char offset) +{ + unsigned char result, oldLCR; + oldLCR = readReg(dev, LCR_OFFSET); + writeReg(dev, LCR_OFFSET, LCR_650_ACCESS_KEY); + result = readReg(dev, offset); + writeReg(dev, LCR_OFFSET, oldLCR); + return result; +} + +void write650(serial9bit_dev *dev, unsigned char offset, unsigned char value) +{ + unsigned char oldLCR; + oldLCR = readReg(dev, LCR_OFFSET); + writeReg(dev, LCR_OFFSET, LCR_650_ACCESS_KEY); + writeReg(dev, offset, value); + writeReg(dev, LCR_OFFSET, oldLCR); +} + +//950 compatible registers. +unsigned char readASR(serial9bit_dev *dev) +{ + unsigned char retVal; + unlockAdditionalStatus(dev); + retVal = readReg(dev, ASR_OFFSET); + lockAdditionalStatus(dev); + return retVal; +} + +void writeASRBit(serial9bit_dev *dev, unsigned char bit, unsigned char value) +{ + unsigned char currentASR; + if( bit!=0 && bit!=1 ) + return + unlockAdditionalStatus(dev); + currentASR = readReg(dev, ASR_OFFSET); + if(value) + currentASR |= (1 << bit); + else + currentASR &= ~(1 << bit); + writeReg(dev, ASR_OFFSET, currentASR); + lockAdditionalStatus(dev); +} + +//Reading FIFO Levels +unsigned char readFIFOLevel(serial9bit_dev *dev, unsigned char fifo) +{ + unsigned char level1, offset; + if (fifo == RECEIVE_FIFO) offset = RFL_OFFSET; + else offset = TFL_OFFSET; + unlockAdditionalStatus(dev); + level1 = readReg(dev, offset); + lockAdditionalStatus(dev); + return level1; +} + +//950 compatible registers. +void lockAdditionalStatus(serial9bit_dev *dev) +{ + dev->bakACR &= ~ACR_950_READ_EN; + writeICR(dev, ACR_INDEX, dev->bakACR); +} + +void unlockAdditionalStatus(serial9bit_dev *dev) +{ + dev->bakACR |= ACR_950_READ_EN; + writeICR(dev, ACR_INDEX, dev->bakACR); +} + +unsigned char readICR(serial9bit_dev *dev, unsigned char index) +{ + unsigned char retVal; + writeICR(dev, ACR_INDEX, (unsigned char)(dev->bakACR|ACR_ICR_READ_EN)); + writeReg(dev, SPR_OFFSET, index); + retVal = readReg(dev, ICR_OFFSET); + writeICR(dev, ACR_INDEX, (unsigned char)(dev->bakACR&~ACR_ICR_READ_EN)); + return retVal; +} + +void writeICR(serial9bit_dev *dev, unsigned char index, unsigned char value) +{ + writeReg(dev, SPR_OFFSET, index); + writeReg(dev, ICR_OFFSET, value); + if (index==ACR_INDEX) + dev->bakACR = value; +} + +//Device Detection +unsigned char detectOX16C95x(serial9bit_dev *dev) +{ + unsigned char id1, id2, id3, rev; + id1 = readICR(dev, ID1_INDEX); + id2 = readICR(dev, ID2_INDEX); + id3 = readICR(dev, ID3_INDEX); + rev = readICR(dev, REV_INDEX); + return ((id1==0x16)&&(id2==0xC9)&&((id3&0xF0)==0x50)); +} + +//Enable 9-bit mode +void set9BitModeEnable(serial9bit_dev *dev, unsigned char state, unsigned char bit9int) +{ + unsigned char nmr = readICR(dev, NMR_INDEX); + if(state) + if(bit9int) nmr |= (NMR_9BIT_MODE_EN + NMR_9BIT_INTERRUPT_EN); + else nmr &=~(NMR_9BIT_INTERRUPT_EN); + else + nmr &= ~ NMR_9BIT_MODE_EN; + writeICR(dev, NMR_INDEX, nmr); +} + +//Send 9-bit +void send9BitData(serial9bit_dev *dev, unsigned short data) +{ + writeReg(dev, SPR_OFFSET, (data & 0x0100)>>8); + writeReg(dev, THR_OFFSET, data & 0x00FF); +} + +//Receive 9-bit +unsigned short receive9BitData(serial9bit_dev *dev) +{ + unsigned char lsr = readReg(dev, LSR_OFFSET); + unsigned short data = readReg(dev, RHR_OFFSET); + if(lsr & LSR_PARITY_ERROR) data |= 0x0100; + return data; +} + + +/* + * Implementation Section of linux device driver basic API functions + */ static int serial9bit_open(struct inode *inode, struct file *file) { - if(test_and_set_bit(1,&serial9bit_users)) - return -EBUSY; + //if(test_and_set_bit(1,&serial9bit_users)) + // return -EBUSY; MOD_INC_USE_COUNT; return 0; } static int serial9bit_release(struct inode *inode, struct file *file) { - serial9bit_users = 0; + //serial9bit_users = 0; MOD_DEC_USE_COUNT; return 0; } -static ssize_t serial9bit_write(struct file *file, const char *data, size_t len, loff_t *ppos) +static ssize_t serial9bit_write(struct file *filp, char *buf, size_t len, loff_t *offp) { - printk(KERN_INFO "Serial 9-bit driver write\n"); - /* Can't seek (pwrite) on this device */ - if (ppos != &file->f_pos) + int retval = len; + unsigned short *kbuf, *ptr; + + if (offp != &filp->f_pos) return -ESPIPE; - - /* Can't write odd number of bytes. (16-bit data expected) */ - if (len & 0x1) + + if (len&0x1) return -EINVAL; - return 0; + if (down_interruptible(&sem)) + return -ERESTARTSYS; + + while ( (readReg(dev, LSR_OFFSET)&LSR_FIFO_EMPTY)==0 ) + { + if (filp->f_flags & O_NONBLOCK) + return -EAGAIN; + up (&sem); + interruptible_sleep_on(&wqueue); + if (signal_pending (current)) + return -ERESTARTSYS; + if (down_interruptible(&sem)) + return -ERESTARTSYS; + } + + kbuf=(unsigned short *)kmalloc(len, GFP_KERNEL); + if (!kbuf) { + retval = -ENOMEM; + goto err; + } + if (copy_from_user(kbuf, buf, len)) { + retval = -EFAULT; + goto err; + } + ptr=kbuf; + + while (len) { + if (readFIFOLevel(dev, TRANSMIT_FIFO) == 128) + break; + send9BitData(dev, *(ptr++)); + len-=2; + } + + kfree(kbuf); + up (&sem); + + return retval-len; + + err: + kfree(kbuf); + up (&sem); + return retval; } -static ssize_t serial9bit_read(struct file *filp, char * buf, size_t size, loff_t *offp) + +static ssize_t serial9bit_read(struct file *filp, char *buf, size_t len, loff_t *offp) { - printk(KERN_INFO "Serial 9-bit driver read\n"); - /* Can't read odd number of bytes. (16-bit data) */ - if (size & 0x1) + int retval=len, i=0; + unsigned short *kbuf, *ptr; + unsigned short lsr; + + if (len&0x1) return -EINVAL; - return 0; + if (down_interruptible(&sem)) + return -ERESTARTSYS; + + while ( (readReg(dev, LSR_OFFSET)&LSR_DATA_AVAILABLE)==0 ) + { + writeReg(dev, IER_OFFSET, IER_RX_INTERRUPT_EN|IER_TX_INTERRUPT_EN); + up (&sem); + if (filp->f_flags & O_NONBLOCK) + return -EAGAIN; + interruptible_sleep_on(&rqueue); + if (signal_pending (current)) + return -ERESTARTSYS; + if (down_interruptible(&sem)) + return -ERESTARTSYS; + } + + kbuf=(unsigned short *)kmalloc(len, GFP_KERNEL); + if (!kbuf) { + retval = -ENOMEM; + goto err; + } + ptr=kbuf; + + while (len) + { + lsr = readReg(dev, LSR_OFFSET); + + if (i==10) break; + if ( (lsr&LSR_DATA_AVAILABLE)==0 ) { + udelay(10); + i++; + continue; + } + i=0; + + if ( (lsr&LSR_ERROR_MASK) ) + break; + + *(ptr++) = receive9BitData(dev); + len-=2; + } + + if ( (retval > 0) && copy_to_user(buf, kbuf, retval-len)) { + retval = -EFAULT; + goto err; + } + + kfree(kbuf); + up (&sem); + + if ( (lsr&LSR_ERROR_MASK) ) { + printk(KERN_ERR "serial9bit: Read interrupted due "); + if (lsr&LSR_FRAMING_ERROR) + printk("framing "); + if (lsr&LSR_BREAK) + printk("break "); + if (lsr&LSR_DATA_ERROR) + printk("data "); + printk("error\n"); + } + + return retval-len; + + err: + kfree(kbuf); + up (&sem); + return retval; } @@ -68,17 +515,33 @@ } } +static void int_handler(int irq, void *dev_id, struct pt_regs * regs) +{ + int isr = readReg(dev, ISR_OFFSET); + printk("serial9bit: interrupt handler 0x%x\n", isr); + + if (isr&0x4) { + writeReg(dev, IER_OFFSET, IER_TX_INTERRUPT_EN); + wake_up_interruptible(&rqueue); + } + + if (isr&0x2) + wake_up_interruptible(&rqueue); + + return; +} + static struct file_operations serial9bit_fops= { owner: THIS_MODULE, write: serial9bit_write, - read: serial9bit_read, + read: serial9bit_read, ioctl: serial9bit_ioctl, - open: serial9bit_open, - release: serial9bit_release, + open: serial9bit_open, + release: serial9bit_release, }; -static struct miscdevice serial9bit_miscdev= +struct miscdevice serial9bit_miscdev= { MISC_DYNAMIC_MINOR, "serial9bit", @@ -87,13 +550,77 @@ static int __init serial9bit_init(void) { - int ret; - printk(KERN_INFO "Serial 9-bit driver init\n"); + int ret=0; + printk(KERN_INFO "serial9bit: Serial 9-bit driver init\n"); + + //IO module parameter check + if (io==-1 || irq==-1) { + printk(KERN_INFO "serial9bit: You must provide the IO address and IRQ line\n"); + return -ENODEV; + } + + dev = kmalloc(sizeof(serial9bit_dev), GFP_KERNEL); + if (!dev) { + printk(KERN_INFO "serial9bit: Error on memory allocation\n"); + return -ENOMEM; + } + memset(dev, 0, sizeof(serial9bit_dev)); + + //Mapping IO base address + dev->name = name; + dev->io = io; + dev->irq = irq; + dev->base_addr = (unsigned long)TS7XXX_IOMEM + io; + + if (check_mem_region(dev->base_addr, TSSER_SIZE_IO)) { + printk(KERN_INFO "serial9bit: Requested memory already in use\n"); + kfree(dev); + return -ENOMEM; + } + request_mem_region(dev->base_addr, TSSER_SIZE_IO, dev->name); - ret = misc_register(&serial9bit_miscdev); + //Chip detection + { + //950 Mode selection + write650(dev, EFR_OFFSET, EFR_ENHANCED_MODE_EN); + writeReg(dev, FCR_OFFSET, FCR_FIFO_EN); + //9-bit chip detection test + if (!detectOX16C95x(dev)) { + printk(KERN_INFO "serial9bit: 9-bit chip NOT detected\n"); + release_mem_region(dev->base_addr, TSSER_SIZE_IO); + kfree(dev); + return -ENODEV; + } + } - if (ret) + //Configuration for 9-Bit Mode + { + writeDivisor(dev, DIVISOR_BAUD_9600); + writeReg(dev, MCR_OFFSET, readReg(dev, MCR_OFFSET)&~0x10); + writeReg(dev, IER_OFFSET, IER_RX_INTERRUPT_EN|IER_TX_INTERRUPT_EN); + set9BitModeEnable(dev, TRUE, TRUE); + } + + //Registering IRQ + if ((ret = request_irq(dev->irq, int_handler, SA_SHIRQ, dev->name, dev)) > 0) { + printk(KERN_INFO "serial9bit: Error on irq %i request\n", dev->irq); + release_mem_region(dev->base_addr, TSSER_SIZE_IO); + kfree(dev); return ret; + } + + //Registering the device + devfs + serial9bit_miscdev.name = name; + if ((ret = misc_register(&serial9bit_miscdev)) > 0) { + printk(KERN_INFO "serial9bit: Error on device registration\n"); + free_irq(dev->irq, dev->name); + release_mem_region(dev->base_addr, TSSER_SIZE_IO); + kfree(dev); + return ret; + } + + printk(KERN_INFO "serial9bit: Driver loaded with I/O address 0x%lx and IRQ %i\n", + dev->base_addr, dev->irq); return 0; } @@ -101,6 +628,10 @@ static void __exit serial9bit_exit(void) { misc_deregister(&serial9bit_miscdev); + free_irq(dev->irq, dev->name); + release_mem_region(dev->base_addr, TSSER_SIZE_IO); + kfree(dev); + printk(KERN_INFO "serial9bit: Driver unloaded\n"); } module_init(serial9bit_init); Index: drivers/char/serial_tx3912.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/serial_tx3912.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/serial_tx3912.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/serial_tx3912.c 4 Aug 2004 01:28:45 -0000 1.2 @@ -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) { Index: drivers/char/sh-sci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/sh-sci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/sh-sci.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/sh-sci.c 4 Aug 2004 01:28:45 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sh-sci.c,v 1.1 2004/07/22 19:49:50 joff Exp $ +/* $Id: sh-sci.c,v 1.2 2004/08/04 01:28:45 joff Exp $ * * linux/drivers/char/sh-sci.c * @@ -6,6 +6,8 @@ * Copyright (C) 1999, 2000 Niibe Yutaka * Copyright (C) 2000 Sugioka Toshinobu * Modified to support multiple serial ports. Stuart Menefy (May 2000). + * Modified to support SecureEdge. David McCullough (2002) + * Modified to support SH7300 SCIF. Takashi Kusuda (Jun 2003). * * TTY code is based on sx.c (Specialix SX driver) by: * @@ -32,7 +34,7 @@ #include #include #include -#ifdef CONFIG_SERIAL_CONSOLE +#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_SH_KGDB_CONSOLE) #include #endif @@ -50,17 +52,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 +138,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 +180,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 +192,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,16 +230,147 @@ 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 +597,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); @@ -389,6 +605,11 @@ port->init_pins(port, cflag); sci_out(port, SCSCR, SCSCR_INIT(port)); + + if (cflag & CLOCAL) + port->gs.flags &= ~ASYNC_CHECK_CD; + else + port->gs.flags |= ASYNC_CHECK_CD; } static int sci_set_real_termios(void *ptr) @@ -401,22 +622,6 @@ sci_enable_rx_interrupts(port); } - /* Tell line discipline whether we will do input cooking */ - if (I_OTHER(port->gs.tty)) - clear_bit(TTY_HW_COOK_IN, &port->gs.tty->flags); - else - set_bit(TTY_HW_COOK_IN, &port->gs.tty->flags); - -/* Tell line discipline whether we will do output cooking. - * If OPOST is set and no other output flags are set then we can do output - * processing. Even if only *one* other flag in the O_OTHER group is set - * we do cooking in software. - */ - if (O_OPOST(port->gs.tty) && !O_OTHER(port->gs.tty)) - set_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags); - else - clear_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags); - return 0; } @@ -437,8 +642,8 @@ static void sci_transmit_chars(struct sci_port *port) { - int count, i; - int txroom; + unsigned int count, i; + unsigned int txroom; unsigned long flags; unsigned short status; unsigned short ctrl; @@ -461,14 +666,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,9 +720,13 @@ 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; + int count; struct tty_struct *tty; int copied=0; unsigned short status; @@ -523,55 +736,108 @@ return; 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; } - /* Don't copy more bytes than there is room for in the buffer */ - if (tty->flip.count + count > TTY_FLIPBUF_SIZE) - count = TTY_FLIPBUF_SIZE - tty->flip.count; + /* we must clear RDF or we get stuck in the interrupt for ever */ + sci_in(port, SCxSR); /* dummy read */ + sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); - /* 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; if (port->type == PORT_SCI) { - tty->flip.char_buf_ptr[0] = sci_in(port, SCxRDR); - tty->flip.flag_buf_ptr[0] = TTY_NORMAL; + if (tty->flip.count < TTY_FLIPBUF_SIZE) { + *tty->flip.char_buf_ptr++ = sci_in(port, SCxRDR); + *tty->flip.flag_buf_ptr++ = TTY_NORMAL; + tty->flip.count++; + port->icount.rx++; + copied++; + count--; + } } else { - for (i=0; iflip.char_buf_ptr[i] = sci_in(port, SCxRDR); + while (count > 0 && tty->flip.count < TTY_FLIPBUF_SIZE){ + 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--; + continue; + } + /* Nonzero => end-of-break */ + dprintk("scif: debounce<%02x>\n", c); + port->break_flag = 0; + if (STEPFN(c)) { + count--; + 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--; + continue; + } else if (c != 0) { + break_pressed = 0; + } + } +#endif /* CONFIG_SERIAL_CONSOLE && CONFIG_MAGIC_SYSRQ */ + + /* Store data and status */ + *tty->flip.char_buf_ptr++ = c; + if (status&SCxSR_FER(port)) { - tty->flip.flag_buf_ptr[i] = TTY_FRAME; + *tty->flip.flag_buf_ptr++ = TTY_FRAME; dprintk("sci: frame error\n"); } else if (status&SCxSR_PER(port)) { - tty->flip.flag_buf_ptr[i] = TTY_PARITY; + *tty->flip.flag_buf_ptr++ = TTY_PARITY; dprintk("sci: parity error\n"); } else { - tty->flip.flag_buf_ptr[i] = TTY_NORMAL; + *tty->flip.flag_buf_ptr++ = TTY_NORMAL; } + tty->flip.count++; + port->icount.rx++; + copied++; + count--; } } - sci_in(port, SCxSR); /* dummy read */ - sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); - - /* Update the kernel buffer end */ - tty->flip.count += count; - tty->flip.char_buf_ptr += count; - tty->flip.flag_buf_ptr += count; - - copied += count; - port->icount.rx += count; + /* drop any remaining chars, we are full */ + if (count > 0) { + /* force an overrun error on last received char */ + tty->flip.flag_buf_ptr[TTY_FLIPBUF_SIZE - 1] = TTY_OVERRUN; + while (count-- > 0) + (void) sci_in(port, SCxRDR); + } } 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 +890,33 @@ 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"); } +#if defined(CONFIG_CPU_SH3) || defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) + break_continue: +#endif -#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_ST40STB1) +#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined (CONFIG_CPU_SUBTYPE_SH7751) || 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 +942,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 +989,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_; @@ -779,6 +1087,15 @@ static int sci_get_CD(void * ptr) { /* If you have signal for CD (Carrier Detect), please change here. */ + +#if defined(CONFIG_SH_SECUREEDGE5410) + struct sci_port *port = ptr; + + if (port == &sci_ports[0] || port == &sci_ports[1]) + if ((sci_getsignals(port) & TIOCM_CAR) == 0) + return 0; +#endif + return 1; } @@ -811,7 +1128,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 +1137,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 +1152,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 +1197,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 +1221,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 +1317,7 @@ * was throttled */ port->gs.flags &= ~SCI_RX_THROTTLE; + sci_enable_rx_interrupts(port); return; } @@ -1110,14 +1453,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 +1481,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 = @@ -1147,6 +1511,18 @@ (port->type == PORT_SCI) ? "SCI" : "SCIF"); } +#if defined(CONFIG_SH_SECUREEDGE5410) + init_timer(&sci_timer_struct); + sci_timer_struct.function = sci_timer; + sci_timer_struct.data = 0; + sci_timer_struct.expires = jiffies + HZ/25; + add_timer(&sci_timer_struct); + + j = SECUREEDGE_READ_IOPORT(); + sci_dcdstatus[0] = !(j & 0x10); + sci_dcdstatus[1] = !(j & 0x1); +#endif + sci_init_drivers(); #ifdef CONFIG_SH_STANDARD_BIOS @@ -1163,6 +1539,9 @@ void cleanup_module(void) { +#if defined(CONFIG_SH_SECUREEDGE5410) + del_timer(&sci_timer_struct); +#endif tty_unregister_driver(&sci_driver); tty_unregister_driver(&sci_callout_driver); } @@ -1202,6 +1581,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; @@ -1227,6 +1612,9 @@ case 115200: cflag |= B115200; break; + case 230400: + cflag |= B230400; + break; case 9600: default: cflag |= B9600; @@ -1251,11 +1639,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 +1686,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 */ Index: drivers/char/sh-sci.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/sh-sci.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/sh-sci.h 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/sh-sci.h 4 Aug 2004 01:28:45 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sh-sci.h,v 1.1 2004/07/22 19:49:50 joff Exp $ +/* $Id: sh-sci.h,v 1.2 2004/08/04 01:28:45 joff 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,16 @@ 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_SH4_202) +# define SCI_NPORTS 1 +# define SCI_INIT { \ + { {}, PORT_SCIF, 0xFFE80000, SH4_SCIF_IRQS, sci_init_pins_scif } \ +} +# define SCSPTR2 0xFFE80020 /* 16 bit SCIF */ +# 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_ST40) # define SCI_NPORTS 2 # define SCI_INIT { \ { {}, PORT_SCIF, 0xffe00000, STB1_SCIF1_IRQS, sci_init_pins_scif }, \ @@ -70,6 +92,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 +148,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 +173,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 +210,7 @@ /* SCFCR */ #define SCFCR_RFRST 0x0002 #define SCFCR_TFRST 0x0004 +#define SCFCR_TCRST 0x4000 #define SCFCR_MCE 0x0008 #define SCI_MAJOR 204 @@ -161,29 +219,6 @@ /* Generic serial flags */ #define SCI_RX_THROTTLE 0x0000001 -/* generic serial tty */ -#define O_OTHER(tty) \ - ((O_OLCUC(tty)) ||\ - (O_ONLCR(tty)) ||\ - (O_OCRNL(tty)) ||\ - (O_ONOCR(tty)) ||\ - (O_ONLRET(tty)) ||\ - (O_OFILL(tty)) ||\ - (O_OFDEL(tty)) ||\ - (O_NLDLY(tty)) ||\ - (O_CRDLY(tty)) ||\ - (O_TABDLY(tty)) ||\ - (O_BSDLY(tty)) ||\ - (O_VTDLY(tty)) ||\ - (O_FFDLY(tty))) - -#define I_OTHER(tty) \ - ((I_INLCR(tty)) ||\ - (I_IGNCR(tty)) ||\ - (I_ICRNL(tty)) ||\ - (I_IUCLC(tty)) ||\ - (L_ISIG(tty))) - #define SCI_MAGIC 0xbabeface /* @@ -202,6 +237,7 @@ struct async_icount icount; struct tq_struct tqueue; unsigned long event; + int break_flag; }; #define SCI_IN(size, offset) \ @@ -248,11 +284,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 +302,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 +324,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 +338,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) { @@ -294,7 +356,7 @@ return ctrl_inb(SCPDR)&0x04 ? 1 : 0; /* IRDA */ return 1; } -#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) +#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH4_202) static inline int sci_rxd_in(struct sci_port *port) { #ifndef SCIF_ONLY @@ -307,7 +369,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 +378,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 +420,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) @@ -360,4 +432,5 @@ #define BPS_38400 SCBRR_VALUE(38400) #define BPS_57600 SCBRR_VALUE(57600) #define BPS_115200 SCBRR_VALUE(115200) +#define BPS_230400 SCBRR_VALUE(230400) Index: drivers/char/shwdt.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/shwdt.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/shwdt.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/shwdt.c 4 Aug 2004 01:28:45 -0000 1.2 @@ -3,7 +3,7 @@ * * Watchdog driver for integrated watchdog in the SuperH processors. * - * Copyright (C) 2001, 2002 Paul Mundt + * Copyright (C) 2001, 2002, 2003, 2004 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 @@ -12,6 +12,7 @@ * * 14-Dec-2001 Matt Domsch * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT + * * 19-Apr-2002 Rob Radez * Added expect close support, made emulated timeout runtime changeable * general cleanups, add some ioctls @@ -31,8 +32,10 @@ #include #if defined(CONFIG_CPU_SH5) - #define WTCNT CPRC_BASE + 0x10 - #define WTCSR CPRC_BASE + 0x18 + extern unsigned long cprc_base; + + #define WTCNT (cprc_base+0x10) + #define WTCSR (cprc_base+0x18) #elif defined(CONFIG_CPU_SH4) #define WTCNT 0xffc00008 #define WTCSR 0xffc0000c @@ -82,22 +85,43 @@ #define WTCSR_CKS_4096 0x07 /* - * Default clock division ratio is 5.25 msecs. Overload this at module load - * time. Any value not in the msec range will default to a timeout of one - * jiffy, which exceeds the usec overflow periods. + * Default clock division ratio is 5.25 msecs. For an additional table of + * values, consult the asm-sh/watchdog.h. Overload this at module load + * time. + * + * In order for this to work reliably we need to have HZ set to 1000 or + * something quite higher than 100 (or we need a proper high-res timer + * implementation that will deal with this properly), otherwise the 10ms + * resolution of a jiffy is enough to trigger the overflow. For things like + * the SH-4 and SH-5, this isn't necessarily that big of a problem, though + * for the SH-2 and SH-3, this isn't recommended unless the WDT is absolutely + * necssary. + * + * As a result of this timing problem, the only modes that are particularly + * feasible are the 4096 and the 2048 divisors, which yeild 5.25 and 2.62ms + * overflow periods respectively. + * + * Also, since we can't really expect userspace to be responsive enough + * before the overflow happens, we maintain two seperate timers .. One in + * the kernel for clearing out WOVF every 2ms or so (again, this depends on + * HZ == 1000), and another for monitoring userspace writes to the WDT device. + * + * As such, we currently use a configurable heartbeat interval which defaults + * to 30s. In this case, the userspace daemon is only responsible for periodic + * writes to the device before the next heartbeat is scheduled. If the daemon + * misses its deadline, the kernel timer will allow the WDT to overflow. */ static int clock_division_ratio = WTCSR_CKS_4096; -#define msecs_to_jiffies(msecs) (jiffies + ((HZ * msecs + 999) / 1000)) +#define msecs_to_jiffies(msecs) (jiffies + (HZ * msecs + 9999) / 10000) #define next_ping_period(cks) msecs_to_jiffies(cks - 4) -static unsigned long sh_is_open; +static unsigned long shwdt_is_open; static struct watchdog_info sh_wdt_info; static char shwdt_expect_close; - static struct timer_list timer; static unsigned long next_heartbeat; -static int sh_heartbeat = 30; +static int heartbeat = 30; #ifdef CONFIG_WATCHDOG_NOWAYOUT static int nowayout = 1; @@ -119,6 +143,22 @@ } /** + * sh_wdt_read_csr - Read from Control/Status Register + * + * Reads back the WTCSR value. + */ +static inline __u8 sh_wdt_read_csr(void) +{ + /* + * XXX: This is pretty straightforward on SH-3 and up, though on + * anything lower we have seperate locations for reading and + * writing the CSR value. We just keep this around for general + * completeness. + */ + return ctrl_inb(WTCSR); +} + +/** * sh_wdt_write_csr - Write to Control/Status Register * * @val: Value to write @@ -138,13 +178,29 @@ */ static void sh_wdt_start(void) { - timer.expires = next_ping_period(clock_division_ratio); - next_heartbeat = jiffies + (sh_heartbeat * HZ); - add_timer(&timer); + __u8 csr; + + mod_timer(&timer, next_ping_period(clock_division_ratio)); + next_heartbeat = jiffies + (heartbeat * HZ); + + csr = sh_wdt_read_csr(); + csr |= WTCSR_WT | clock_division_ratio; + sh_wdt_write_csr(csr); - sh_wdt_write_csr(WTCSR_WT | WTCSR_CKS_4096); sh_wdt_write_cnt(0); - sh_wdt_write_csr((ctrl_inb(WTCSR) | WTCSR_TME)); + + /* + * These processors have a bit of an inconsistent initialization + * process.. starting with SH-3, RSTS was moved to WTCSR, and the + * RSTCSR register was removed. + * + * On the SH-2 these semantics are even odder, as we have to deal + * with RSTCSR outright. See the 2.6 code for this. + */ + csr = sh_wdt_read_csr(); + csr |= WTCSR_TME; + csr &= ~WTCSR_RSTS; + sh_wdt_write_csr(csr); } /** @@ -154,9 +210,13 @@ */ static void sh_wdt_stop(void) { + __u8 csr; + del_timer(&timer); - sh_wdt_write_csr((ctrl_inb(WTCSR) & ~WTCSR_TME)); + csr = sh_wdt_read_csr(); + csr &= ~WTCSR_TME; + sh_wdt_write_csr(csr); } /** @@ -169,11 +229,15 @@ static void sh_wdt_ping(unsigned long data) { if (time_before(jiffies, next_heartbeat)) { - sh_wdt_write_csr((ctrl_inb(WTCSR) & ~WTCSR_IOVF)); + __u8 csr; + + csr = sh_wdt_read_csr(); + csr &= ~WTCSR_IOVF; + sh_wdt_write_csr(csr); + sh_wdt_write_cnt(0); - timer.expires = next_ping_period(clock_division_ratio); - add_timer(&timer); + mod_timer(&timer, next_ping_period(clock_division_ratio)); } } @@ -187,7 +251,7 @@ */ static int sh_wdt_open(struct inode *inode, struct file *file) { - if (test_and_set_bit(0, &sh_is_open)) + if (test_and_set_bit(0, &shwdt_is_open)) return -EBUSY; sh_wdt_start(); @@ -209,9 +273,10 @@ sh_wdt_stop(); } else { printk(KERN_CRIT "shwdt: Unexpected close, not stopping watchdog!\n"); - next_heartbeat = jiffies + (sh_heartbeat * HZ); + next_heartbeat = jiffies + (heartbeat * HZ); } - clear_bit(0, &sh_is_open); + + clear_bit(0, &shwdt_is_open); shwdt_expect_close = 0; return 0; @@ -246,7 +311,7 @@ if (c == 'V') shwdt_expect_close = 42; } - next_heartbeat = jiffies + (sh_heartbeat * HZ); + next_heartbeat = jiffies + (heartbeat * HZ); } return count; @@ -275,13 +340,13 @@ sizeof(sh_wdt_info))) { return -EFAULT; } - + break; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, (int *)arg); case WDIOC_KEEPALIVE: - next_heartbeat = jiffies + (sh_heartbeat * HZ); + next_heartbeat = jiffies + (heartbeat * HZ); break; case WDIOC_SETTIMEOUT: @@ -289,11 +354,11 @@ return -EFAULT; if (new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ return -EINVAL; - sh_heartbeat = new_timeout; - next_heartbeat = jiffies + (sh_heartbeat * HZ); + heartbeat = new_timeout; + next_heartbeat = jiffies + (heartbeat * HZ); /* Fall */ case WDIOC_GETTIMEOUT: - return put_user(sh_heartbeat, (int *)arg); + return put_user(heartbeat, (int *)arg); case WDIOC_SETOPTIONS: { int options, retval = -EINVAL; @@ -310,7 +375,7 @@ sh_wdt_start(); retval = 0; } - + return retval; } default: Index: drivers/char/softdog.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/softdog.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/softdog.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/softdog.c 4 Aug 2004 01:28:45 -0000 1.2 @@ -124,7 +124,7 @@ * Shut off the timer. * Lock it in if it's a module and we set nowayout */ - if (expect_close) { + if (expect_close || nowayout == 0) { del_timer(&watchdog_ticktock); } else { printk(KERN_CRIT "SOFTDOG: WDT device closed unexpectedly. WDT will not stop!\n"); Index: drivers/char/sonypi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/sonypi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/sonypi.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/sonypi.c 4 Aug 2004 01:28:45 -0000 1.2 @@ -120,16 +120,16 @@ 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; } /* Initializes the device - this comes from the AML code in the ACPI bios */ -static void __devinit sonypi_type1_srs(void) { +static void sonypi_type1_srs(void) { u32 v; pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v); @@ -151,12 +151,12 @@ pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v); } -static void __devinit sonypi_type2_srs(void) { - if (ec_write(SONYPI_SHIB, (sonypi_device.ioport1 & 0xFF00) >> 8)) +static void sonypi_type2_srs(void) { + 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,28 +293,22 @@ /* 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; } /* Interrupt handler: some event is available */ -void sonypi_irq(int irq, void *dev_id, struct pt_regs *regs) { +static irqreturn_t sonypi_irq(int irq, void *dev_id, struct pt_regs *regs) { u8 v1, v2, event = 0; int i, j; 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); + v2 = inb_p(sonypi_device.ioport1 + sonypi_device.evtype_offset); for (i = 0; sonypi_eventtypes[i].model; i++) { if (sonypi_device.model != sonypi_eventtypes[i].model) @@ -334,10 +328,17 @@ if (verbose) printk(KERN_WARNING "sonypi: unknown event port1=0x%02x,port2=0x%02x\n",v1,v2); - return; + /* We need to return IRQ_HANDLED here because there *are* + * events belonging to the sonypi device we don't know about, + * but we still don't want those to pollute the logs... */ + return IRQ_HANDLED; 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,8 +352,9 @@ (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); + return IRQ_HANDLED; } /* External camera command (exported to the motion eye v4l driver) */ @@ -507,7 +509,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 +521,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 +557,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 +613,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 @@ -671,11 +669,13 @@ if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) { ioport_list = sonypi_type2_ioport_list; sonypi_device.region_size = SONYPI_TYPE2_REGION_SIZE; + sonypi_device.evtype_offset = SONYPI_TYPE2_EVTYPE_OFFSET; irq_list = sonypi_type2_irq_list; } else { ioport_list = sonypi_type1_ioport_list; sonypi_device.region_size = SONYPI_TYPE1_REGION_SIZE; + sonypi_device.evtype_offset = SONYPI_TYPE1_EVTYPE_OFFSET; irq_list = sonypi_type1_irq_list; } @@ -696,36 +696,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 +756,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 +773,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 +797,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 +810,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); Index: drivers/char/sonypi.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/sonypi.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/sonypi.h 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/sonypi.h 4 Aug 2004 01:28:45 -0000 1.2 @@ -37,7 +37,7 @@ #ifdef __KERNEL__ #define SONYPI_DRIVER_MAJORVERSION 1 -#define SONYPI_DRIVER_MINORVERSION 18 +#define SONYPI_DRIVER_MINORVERSION 22 #define SONYPI_DEVICE_MODEL_TYPE1 1 #define SONYPI_DEVICE_MODEL_TYPE2 2 @@ -56,12 +56,14 @@ #define SONYPI_BASE 0x50 #define SONYPI_G10A (SONYPI_BASE+0x14) #define SONYPI_TYPE1_REGION_SIZE 0x08 +#define SONYPI_TYPE1_EVTYPE_OFFSET 0x04 /* type2 series specifics */ #define SONYPI_SIRQ 0x9b #define SONYPI_SLOB 0x9c #define SONYPI_SHIB 0x9d #define SONYPI_TYPE2_REGION_SIZE 0x20 +#define SONYPI_TYPE2_EVTYPE_OFFSET 0x12 /* battery / brightness addresses */ #define SONYPI_BAT_FLAGS 0x81 @@ -167,6 +169,7 @@ #define SONYPI_THUMBPHRASE_MASK 0x00000200 #define SONYPI_MEYE_MASK 0x00000400 #define SONYPI_MEMORYSTICK_MASK 0x00000800 +#define SONYPI_BATTERY_MASK 0x00001000 struct sonypi_event { u8 data; @@ -236,6 +239,7 @@ { 0x01, SONYPI_EVENT_PKEY_P1 }, { 0x02, SONYPI_EVENT_PKEY_P2 }, { 0x04, SONYPI_EVENT_PKEY_P3 }, + { 0x5c, SONYPI_EVENT_PKEY_P1 }, { 0, 0 } }; @@ -293,6 +297,13 @@ { 0, 0 } }; +/* The set of possible battery events */ +static struct sonypi_event sonypi_batteryev[] = { + { 0x20, SONYPI_EVENT_BATTERY_INSERT }, + { 0x30, SONYPI_EVENT_BATTERY_REMOVE }, + { 0, 0 } +}; + struct sonypi_eventtypes { int model; u8 data; @@ -307,19 +318,23 @@ { SONYPI_DEVICE_MODEL_TYPE1, 0x20, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, { SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_BLUETOOTH_MASK, sonypi_blueev }, { SONYPI_DEVICE_MODEL_TYPE1, 0x40, SONYPI_PKEY_MASK, sonypi_pkeyev }, + { SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, + { SONYPI_DEVICE_MODEL_TYPE1, 0x40, SONYPI_BATTERY_MASK, sonypi_batteryev }, { SONYPI_DEVICE_MODEL_TYPE2, 0, 0xffffffff, sonypi_releaseev }, { SONYPI_DEVICE_MODEL_TYPE2, 0x38, SONYPI_LID_MASK, sonypi_lidev }, - { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_JOGGER_MASK, sonypi_joggerev }, - { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_CAPTURE_MASK, sonypi_captureev }, - { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, - { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_BLUETOOTH_MASK, sonypi_blueev }, + { SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_JOGGER_MASK, sonypi_joggerev }, + { SONYPI_DEVICE_MODEL_TYPE2, 0x61, SONYPI_CAPTURE_MASK, sonypi_captureev }, + { SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, + { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_BLUETOOTH_MASK, sonypi_blueev }, { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev }, - { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_BACK_MASK, sonypi_backev }, + { SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_BACK_MASK, sonypi_backev }, { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_HELP_MASK, sonypi_helpev }, - { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_ZOOM_MASK, sonypi_zoomev }, - { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev }, - { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, + { SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_ZOOM_MASK, sonypi_zoomev }, + { SONYPI_DEVICE_MODEL_TYPE2, 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev }, + { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, + { SONYPI_DEVICE_MODEL_TYPE2, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev }, + { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev }, { 0, 0, 0, 0 } }; @@ -335,6 +350,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" @@ -345,13 +369,14 @@ u16 ioport1; u16 ioport2; u16 region_size; + u16 evtype_offset; int camera_power; int bluetooth_power; struct semaphore lock; 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 @@ -371,16 +396,18 @@ } #ifdef CONFIG_ACPI -#include -#if (ACPI_CA_VERSION > 0x20021121) -#define USE_ACPI -#endif +#define SONYPI_ACPI_ACTIVE (!acpi_disabled) +#else +#define SONYPI_ACPI_ACTIVE 0 #endif /* CONFIG_ACPI */ -#ifndef USE_ACPI extern int verbose; -static inline int ec_write(u8 addr, u8 value) { +static inline int sonypi_ec_write(u8 addr, u8 value) { +#ifdef CONFIG_ACPI_EC + if (SONYPI_ACPI_ACTIVE) + 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 +418,11 @@ return 0; } -static inline int ec_read(u8 addr, u8 *value) { +static inline int sonypi_ec_read(u8 addr, u8 *value) { +#ifdef CONFIG_ACPI_EC + if (SONYPI_ACPI_ACTIVE) + 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 +431,6 @@ *value = inb_p(SONYPI_DATA_IOPORT); return 0; } -#endif /* ! USE_ACPI */ #endif /* __KERNEL__ */ Index: drivers/char/sx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/sx.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/sx.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/sx.c 4 Aug 2004 01:28:45 -0000 1.2 @@ -33,8 +33,8 @@ * * Revision history: * $Log: sx.c,v $ - * Revision 1.1 2004/07/22 19:49:50 joff - * Initial revision + * Revision 1.2 2004/08/04 01:28:45 joff + * merging 2.4.26-vrs1 * * Revision 1.33 2000/03/09 10:00:00 pvdl,wolff * - Fixed module and port counting @@ -203,8 +203,8 @@ * */ -#define RCS_ID "$Id: sx.c,v 1.1 2004/07/22 19:49:50 joff Exp $" -#define RCS_REV "$Revision: 1.1 $" +#define RCS_ID "$Id: sx.c,v 1.2 2004/08/04 01:28:45 joff Exp $" +#define RCS_REV "$Revision: 1.2 $" #include Index: drivers/char/synclink.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/synclink.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/synclink.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/synclink.c 4 Aug 2004 01:28:45 -0000 1.2 @@ -1,7 +1,7 @@ /* * linux/drivers/char/synclink.c * - * $Id: synclink.c,v 1.1 2004/07/22 19:49:52 joff Exp $ + * $Id: synclink.c,v 1.2 2004/08/04 01:28:45 joff Exp $ * * Device driver for Microgate SyncLink ISA and PCI * high speed multiprotocol serial adapters. @@ -198,6 +198,7 @@ int flags; int count; /* count of opens */ int line; + int hw_version; unsigned short close_delay; unsigned short closing_wait; /* time to wait before closing */ @@ -270,6 +271,7 @@ int rx_enabled; int rx_overflow; + int rx_rcc_underrun; int tx_enabled; int tx_active; @@ -922,7 +924,7 @@ MODULE_PARM(txholdbufs,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i"); static char *driver_name = "SyncLink serial driver"; -static char *driver_version = "$Revision: 1.1 $"; +static char *driver_version = "$Revision: 1.2 $"; static int __init synclink_init_one (struct pci_dev *dev, const struct pci_device_id *ent); @@ -930,11 +932,14 @@ static struct pci_device_id synclink_pci_tbl[] __devinitdata = { { PCI_VENDOR_ID_MICROGATE, PCI_DEVICE_ID_MICROGATE_USC, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_MICROGATE, 0x0210, PCI_ANY_ID, PCI_ANY_ID, }, { 0, }, /* terminate list */ }; MODULE_DEVICE_TABLE(pci, synclink_pci_tbl); +#ifdef MODULE_LICENSE MODULE_LICENSE("GPL"); +#endif static struct pci_driver synclink_pci_driver = { name: "synclink", @@ -999,6 +1004,9 @@ printk(badmagic, kdevname(device), routine); return 1; } +#else + if (!info) + return 1; #endif return 0; } @@ -1140,8 +1148,16 @@ if ( debug_level >= DEBUG_LEVEL_BH ) printk( "%s(%d):mgsl_bh_receive(%s)\n", __FILE__,__LINE__,info->device_name); - - while( (get_rx_frame)(info) ); + do + { + if (info->rx_rcc_underrun) { + unsigned long flags; + spin_lock_irqsave(&info->irq_spinlock,flags); + usc_start_receiver(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + return; + } + } while(get_rx_frame(info)); } void mgsl_bh_transmit(struct mgsl_struct *info) @@ -1583,6 +1599,21 @@ if ( debug_level >= DEBUG_LEVEL_ISR ) printk("%s(%d):mgsl_isr_misc status=%04X\n", __FILE__,__LINE__,status); + + if ((status & MISCSTATUS_RCC_UNDERRUN) && + (info->params.mode == MGSL_MODE_HDLC)) { + + /* turn off receiver and rx DMA */ + usc_EnableReceiver(info,DISABLE_UNCONDITIONAL); + usc_DmaCmd(info, DmaCmd_ResetRxChannel); + usc_UnlatchRxstatusBits(info, RXSTATUS_ALL); + usc_ClearIrqPendingBits(info, RECEIVE_DATA + RECEIVE_STATUS); + usc_DisableInterrupts(info, RECEIVE_DATA + RECEIVE_STATUS); + + /* schedule BH handler to restart receiver */ + info->pending_bh |= BH_RECEIVE; + info->rx_rcc_underrun = 1; + } usc_ClearIrqPendingBits( info, MISC ); usc_UnlatchMiscstatusBits( info, status ); @@ -3251,14 +3282,17 @@ { struct mgsl_struct * info = (struct mgsl_struct *)tty->driver_data; - if (!info || mgsl_paranoia_check(info, tty->device, "mgsl_close")) + if (mgsl_paranoia_check(info, tty->device, "mgsl_close")) return; if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):mgsl_close(%s) entry, count=%d\n", __FILE__,__LINE__, info->device_name, info->count); - if (!info->count || tty_hung_up_p(filp)) + if (!info->count) + return; + + if (tty_hung_up_p(filp)) goto cleanup; if ((tty->count == 1) && (info->count != 1)) { @@ -3393,7 +3427,7 @@ schedule_timeout(char_time); if (signal_pending(current)) break; - if (timeout && ((orig_jiffies + timeout) < jiffies)) + if (timeout && time_after(jiffies, orig_jiffies + timeout)) break; } } else { @@ -3403,7 +3437,7 @@ schedule_timeout(char_time); if (signal_pending(current)) break; - if (timeout && ((orig_jiffies + timeout) < jiffies)) + if (timeout && time_after(jiffies, orig_jiffies + timeout)) break; } } @@ -3612,16 +3646,11 @@ info = mgsl_device_list; while(info && info->line != line) info = info->next_device; - if ( !info ){ - printk("%s(%d):Can't find specified device on open (line=%d)\n", - __FILE__,__LINE__,line); + if (mgsl_paranoia_check(info, tty->device, "mgsl_open")) return -ENODEV; - } tty->driver_data = info; info->tty = tty; - if (mgsl_paranoia_check(info, tty->device, "mgsl_open")) - return -ENODEV; if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):mgsl_open(%s), old ref count = %d\n", @@ -3695,6 +3724,8 @@ cleanup: if (retval) { + if (tty->count == 1) + info->tty = 0; /* tty layer will release tty struct */ if(MOD_IN_USE) MOD_DEC_USE_COUNT; if(info->count) @@ -3760,7 +3791,7 @@ if (info->icount.rxover) ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover); if (info->icount.rxcrc) - ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxcrc); + ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc); } else { ret += sprintf(buf+ret, " ASYNC tx:%d rx:%d", info->icount.tx, info->icount.rx); @@ -4291,9 +4322,7 @@ info->get_tx_holding_index=0; /* restart transmit timer */ - del_timer(&info->tx_timer); - info->tx_timer.expires = jiffies + jiffies_from_ms(5000); - add_timer(&info->tx_timer); + mod_timer(&info->tx_timer, jiffies + jiffies_from_ms(5000)); ret = 1; } @@ -4511,12 +4540,12 @@ info->max_frame_size = 65535; if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { - printk( "SyncLink device %s added:PCI bus IO=%04X IRQ=%d Mem=%08X LCR=%08X MaxFrameSize=%u\n", - info->device_name, info->io_base, info->irq_level, + printk( "SyncLink PCI v%d %s: IO=%04X IRQ=%d Mem=%08X,%08X MaxFrameSize=%u\n", + info->hw_version + 1, info->device_name, info->io_base, info->irq_level, info->phys_memory_base, info->phys_lcr_base, info->max_frame_size ); } else { - printk( "SyncLink device %s added:ISA bus IO=%04X IRQ=%d DMA=%d MaxFrameSize=%u\n", + printk( "SyncLink ISA %s: IO=%04X IRQ=%d DMA=%d MaxFrameSize=%u\n", info->device_name, info->io_base, info->irq_level, info->dma_level, info->max_frame_size ); } @@ -5367,7 +5396,11 @@ usc_EnableMasterIrqBit( info ); usc_ClearIrqPendingBits( info, RECEIVE_STATUS + RECEIVE_DATA + - TRANSMIT_STATUS + TRANSMIT_DATA ); + TRANSMIT_STATUS + TRANSMIT_DATA + MISC); + + /* arm RCC underflow interrupt */ + usc_OutReg(info, SICR, (u16)(usc_InReg(info,SICR) | BIT3)); + usc_EnableInterrupts(info, MISC); info->mbre_bit = 0; outw( 0, info->io_base ); /* clear Master Bus Enable (DCAR) */ @@ -5375,10 +5408,11 @@ info->mbre_bit = BIT8; outw( BIT8, info->io_base ); /* set Master Bus Enable (DCAR) */ - /* Enable DMAEN (Port 7, Bit 14) */ - /* This connects the DMA request signal to the ISA bus */ - /* on the ISA adapter. This has no effect for the PCI adapter */ - usc_OutReg( info, PCR, (u16)((usc_InReg(info, PCR) | BIT15) & ~BIT14) ); + if (info->bus_type == MGSL_BUS_TYPE_ISA) { + /* Enable DMAEN (Port 7, Bit 14) */ + /* This connects the DMA request signal to the ISA bus */ + usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT15) & ~BIT14)); + } /* DMA Control Register (DCR) * @@ -5804,6 +5838,7 @@ info->rx_enabled = 0; info->rx_overflow = 0; + info->rx_rcc_underrun = 0; } /* end of stop_receiver() */ @@ -6355,10 +6390,11 @@ usc_EnableMasterIrqBit( info ); - /* Enable INTEN (Port 6, Bit12) */ - /* This connects the IRQ request signal to the ISA bus */ - /* on the ISA adapter. This has no effect for the PCI adapter */ - usc_OutReg( info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) & ~BIT12) ); + if (info->bus_type == MGSL_BUS_TYPE_ISA) { + /* Enable INTEN (Port 6, Bit12) */ + /* This connects the IRQ request signal to the ISA bus */ + usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) & ~BIT12)); + } } /* end of usc_set_async_mode() */ @@ -6449,10 +6485,11 @@ usc_loopback_frame( info ); usc_set_sdlc_mode( info ); - /* Enable INTEN (Port 6, Bit12) */ - /* This connects the IRQ request signal to the ISA bus */ - /* on the ISA adapter. This has no effect for the PCI adapter */ - usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) & ~BIT12)); + if (info->bus_type == MGSL_BUS_TYPE_ISA) { + /* Enable INTEN (Port 6, Bit12) */ + /* This connects the IRQ request signal to the ISA bus */ + usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) & ~BIT12)); + } usc_enable_aux_clock(info, info->params.clock_speed); @@ -7496,7 +7533,7 @@ EndTime = jiffies + jiffies_from_ms(100); for(;;) { - if ( jiffies > EndTime ) { + if (time_after(jiffies, EndTime)) { rc = FALSE; break; } @@ -7552,7 +7589,7 @@ EndTime = jiffies + jiffies_from_ms(100); for(;;) { - if ( jiffies > EndTime ) { + if (time_after(jiffies, EndTime)) { rc = FALSE; break; } @@ -7600,7 +7637,7 @@ spin_unlock_irqrestore(&info->irq_spinlock,flags); while ( !(status & (BIT6+BIT5+BIT4+BIT2+BIT1)) ) { - if ( jiffies > EndTime ) { + if (time_after(jiffies, EndTime)) { rc = FALSE; break; } @@ -7627,8 +7664,7 @@ /* Wait for 16C32 to write receive status to buffer entry. */ status=info->rx_buffer_list[0].status; while ( status == 0 ) { - if ( jiffies > EndTime ) { - printk(KERN_ERR"mark 4\n"); + if (time_after(jiffies, EndTime)) { rc = FALSE; break; } @@ -8202,17 +8238,20 @@ info->bus_type = MGSL_BUS_TYPE_PCI; info->io_addr_size = 8; info->irq_flags = SA_SHIRQ; - - /* Store the PCI9050 misc control register value because a flaw - * in the PCI9050 prevents LCR registers from being read if - * BIOS assigns an LCR base address with bit 7 set. - * - * Only the misc control register is accessed for which only - * write access is needed, so set an initial value and change - * bits to the device instance data as we write the value - * to the actual misc control register. - */ - info->misc_ctrl_value = 0x087e4546; + + if (dev->device == 0x0210) { + /* Version 1 PCI9030 based universal PCI adapter */ + info->misc_ctrl_value = 0x007c4080; + info->hw_version = 1; + } else { + /* Version 0 PCI9050 based 5V PCI adapter + * A PCI9050 bug prevents reading LCR registers if + * LCR base address bit 7 is set. Maintain shadow + * value so we can write to LCR misc control reg. + */ + info->misc_ctrl_value = 0x087e4546; + info->hw_version = 0; + } mgsl_add_device(info); Index: drivers/char/synclinkmp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/synclinkmp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/synclinkmp.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/synclinkmp.c 4 Aug 2004 01:28:46 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: synclinkmp.c,v 1.1 2004/07/22 19:49:50 joff Exp $ + * $Id: synclinkmp.c,v 1.2 2004/08/04 01:28:46 joff Exp $ * * Device driver for Microgate SyncLink Multiport * high speed multiprotocol serial adapter. @@ -504,7 +504,7 @@ MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_DEVICES) "i"); static char *driver_name = "SyncLink MultiPort driver"; -static char *driver_version = "$Revision: 1.1 $"; +static char *driver_version = "$Revision: 1.2 $"; static int __devinit synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent); static void __devexit synclinkmp_remove_one(struct pci_dev *dev); @@ -515,6 +515,10 @@ }; MODULE_DEVICE_TABLE(pci, synclinkmp_pci_tbl); +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif + static struct pci_driver synclinkmp_pci_driver = { name: "synclinkmp", id_table: synclinkmp_pci_tbl, @@ -724,6 +728,9 @@ printk(badmagic, kdevname(device), routine); return 1; } +#else + if (!info) + return 1; #endif return 0; } @@ -748,12 +755,8 @@ info = synclinkmp_device_list; while(info && info->line != line) info = info->next_device; - if ( !info ){ - printk("%s(%d):%s Can't find specified device on open (line=%d)\n", - __FILE__,__LINE__,info->device_name,line); + if (sanity_check(info, tty->device, "open")) return -ENODEV; - } - if ( info->init_error ) { printk("%s(%d):%s device is not allocated, init error=%d\n", __FILE__,__LINE__,info->device_name,info->init_error); @@ -762,8 +765,6 @@ tty->driver_data = info; info->tty = tty; - if (sanity_check(info, tty->device, "open")) - return -ENODEV; if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):%s open(), old ref count = %d\n", @@ -825,6 +826,8 @@ cleanup: if (retval) { + if (tty->count == 1) + info->tty = 0; /* tty layer will release tty struct */ if(MOD_IN_USE) MOD_DEC_USE_COUNT; if(info->count) @@ -841,14 +844,17 @@ { SLMP_INFO * info = (SLMP_INFO *)tty->driver_data; - if (!info || sanity_check(info, tty->device, "close")) + if (sanity_check(info, tty->device, "close")) return; if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):%s close() entry, count=%d\n", __FILE__,__LINE__, info->device_name, info->count); - if (!info->count || tty_hung_up_p(filp)) + if (!info->count) + return; + + if (tty_hung_up_p(filp)) goto cleanup; if ((tty->count == 1) && (info->count != 1)) { @@ -1203,7 +1209,7 @@ schedule_timeout(char_time); if (signal_pending(current)) break; - if (timeout && ((orig_jiffies + timeout) < jiffies)) + if (timeout && time_after(jiffies, orig_jiffies + timeout)) break; } } else { @@ -1214,7 +1220,7 @@ schedule_timeout(char_time); if (signal_pending(current)) break; - if (timeout && ((orig_jiffies + timeout) < jiffies)) + if (timeout && time_after(jiffies, orig_jiffies + timeout)) break; } } Index: drivers/char/sysrq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/sysrq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/sysrq.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/sysrq.c 4 Aug 2004 01:28:46 -0000 1.2 @@ -1,6 +1,6 @@ /* -*- linux-c -*- * - * $Id: sysrq.c,v 1.1 2004/07/22 19:49:51 joff Exp $ + * $Id: sysrq.c,v 1.2 2004/08/04 01:28:46 joff Exp $ * * Linux Magic System Request Key Hacks * @@ -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; Index: drivers/char/tipar.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/tipar.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/tipar.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/tipar.c 4 Aug 2004 01:28:46 -0000 1.2 @@ -71,9 +71,11 @@ #define DRIVER_DESC "Device driver for TI/PC parallel link cables" #define DRIVER_LICENSE "GPL" -#define VERSION(ver,rel,seq) (((ver)<<16) | ((rel)<<8) | (seq)) -#if LINUX_VERSION_CODE < VERSION(2,5,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) # define minor(x) MINOR(x) +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) # define need_resched() (current->need_resched) #endif Index: drivers/char/tpqic02.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/tpqic02.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/tpqic02.c 22 Jul 2004 19:49:50 -0000 1.1 +++ drivers/char/tpqic02.c 4 Aug 2004 01:28:46 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: tpqic02.c,v 1.1 2004/07/22 19:49:50 joff Exp $ +/* $Id: tpqic02.c,v 1.2 2004/08/04 01:28:46 joff Exp $ * * Driver for tape drive support for Linux-i386 * @@ -137,8 +137,8 @@ static volatile struct tpstatus tperror; /* last drive status */ -static char rcs_revision[] = "$Revision: 1.1 $"; -static char rcs_date[] = "$Date: 2004/07/22 19:49:50 $"; +static char rcs_revision[] = "$Revision: 1.2 $"; +static char rcs_date[] = "$Date: 2004/08/04 01:28:46 $"; /* Flag bits for status and outstanding requests. * (Could all be put in one bit-field-struct.) Index: drivers/char/tty_io.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/tty_io.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/tty_io.c 22 Jul 2004 19:49:51 -0000 1.1 +++ drivers/char/tty_io.c 4 Aug 2004 01:28:46 -0000 1.2 @@ -19,7 +19,7 @@ * Also restructured routines so that there is more of a separation * between the high-level tty routines (tty_io.c and tty_ioctl.c) and * the low-level tty routines (serial.c, pty.c, console.c). This - * makes for cleaner and more compact code. -TYT, 9/17/92 + * makes for cleaner and more compact code. -TYT, 9/17/92 * * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines * which can be dynamically activated and de-activated by the line @@ -41,7 +41,7 @@ * * New TIOCLINUX variants added. * -- mj@k332.feld.cvut.cz, 19-Nov-95 - * + * * Restrict vt switching via ioctl() * -- grif@cs.ucr.edu, 5-Dec-95 * @@ -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); @@ -152,12 +153,18 @@ extern void tub3270_init(void); extern void uart_console_init(void); extern void sgi_serial_console_init(void); +extern void sn_sal_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); extern void rs285_console_init(void); +extern int hvc_console_init(void); #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -194,7 +201,7 @@ else sprintf(buf, name, idx + tty->driver.name_base); - + return buf; } @@ -232,7 +239,7 @@ #ifdef CHECK_TTY_COUNT struct list_head *p; int count = 0; - + file_list_lock(); for(p = tty->tty_files.next; p != &tty->tty_files; p = p->next) { if(list_entry(p, struct file, f_list)->private_data == tty) @@ -248,7 +255,7 @@ "!= #fd's(%d) in %s\n", kdevname(tty->device), tty->count, count, routine); return count; - } + } #endif return 0; } @@ -257,14 +264,14 @@ { if (disc < N_TTY || disc >= NR_LDISCS) return -EINVAL; - + if (new_ldisc) { ldiscs[disc] = *new_ldisc; ldiscs[disc].flags |= LDISC_FLAG_DEFINED; ldiscs[disc].num = disc; } else memset(&ldiscs[disc], 0, sizeof(struct tty_ldisc)); - + return 0; } @@ -294,7 +301,7 @@ o_ldisc = tty->ldisc; tty_wait_until_sent(tty, 0); - + /* Shutdown the current discipline. */ if (tty->ldisc.close) (tty->ldisc.close)(tty); @@ -332,7 +339,7 @@ { int major, minor; struct tty_driver *p; - + minor = MINOR(device); major = MAJOR(device); @@ -449,9 +456,7 @@ redirect = NULL; } spin_unlock(&redirect_lock); - if (f) - fput(f); - + check_tty_count(tty, "do_tty_hangup"); file_list_lock(); for (l = tty->tty_files.next; l != &tty->tty_files; l = l->next) { @@ -468,7 +473,7 @@ filp->f_op = &hung_up_tty_fops; } file_list_unlock(); - + /* FIXME! What are the locking issues here? This may me overdoing things.. */ { unsigned long flags; @@ -505,7 +510,7 @@ "error %d\n", -i); } } - + read_lock(&tasklist_lock); for_each_task(p) { if ((tty->session > 0) && (p->session == tty->session) && @@ -537,13 +542,15 @@ } else if (tty->driver.hangup) (tty->driver.hangup)(tty); unlock_kernel(); + if (f) + fput(f); } void tty_hangup(struct tty_struct * tty) { #ifdef TTY_DEBUG_HANGUP char buf[64]; - + printk(KERN_DEBUG "%s hangup...\n", tty_name(tty, buf)); #endif schedule_task(&tty->tq_hangup); @@ -643,7 +650,7 @@ wake_up_interruptible(&tty->write_wait); } -static ssize_t tty_read(struct file * file, char * buf, size_t count, +static ssize_t tty_read(struct file * file, char * buf, size_t count, loff_t *ppos) { int i; @@ -700,7 +707,7 @@ size_t count) { ssize_t ret = 0, written = 0; - + if (file->f_flags & O_NONBLOCK) { if (down_trylock(&tty->atomic_write)) return -EAGAIN; @@ -828,7 +835,7 @@ struct tty_struct *tty, *o_tty; struct termios *tp, **tp_loc, *o_tp, **o_tp_loc; struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; - struct tty_driver *driver; + struct tty_driver *driver; int retval=0; int idx; @@ -838,7 +845,7 @@ idx = MINOR(device) - driver->minor_start; - /* + /* * Check whether we need to acquire the tty semaphore to avoid * race conditions. For now, play it safe. */ @@ -852,7 +859,7 @@ * First time open is complex, especially for PTY devices. * This code guarantees that either everything succeeds and the * TTY is ready for operation, or else the table slots are vacated - * and the allocated memory released. (Except that the termios + * and the allocated memory released. (Except that the termios * and locked termios may be retained.) */ @@ -931,13 +938,13 @@ o_tty->link = tty; } - /* + /* * All structures have been allocated, so now we install them. - * Failures after this point use release_mem to clean up, so + * Failures after this point use release_mem to clean up, so * there's no need to null out the local pointers. */ driver->table[idx] = tty; - + if (!*tp_loc) *tp_loc = tp; if (!*ltp_loc) @@ -947,7 +954,7 @@ (*driver->refcount)++; tty->count++; - /* + /* * Structures all installed ... call the ldisc open routines. * If we fail here just call release_mem to clean up. No need * to decrement the use counts, as release_mem doesn't care. @@ -981,7 +988,7 @@ if (driver->type == TTY_DRIVER_TYPE_PTY && driver->subtype == PTY_TYPE_MASTER) { /* - * special case for PTY masters: only one open permitted, + * special case for PTY masters: only one open permitted, * and the slave side open count is incremented as well. */ if (tty->count) { @@ -995,7 +1002,7 @@ success: *ret_tty = tty; - + /* All paths come through here to release the semaphore */ end_init: up_tty_sem(idx); @@ -1043,7 +1050,7 @@ } o_tty->magic = 0; (*o_tty->driver.refcount)--; - list_del(&o_tty->tty_files); + list_del_init(&o_tty->tty_files); free_tty_struct(o_tty); } @@ -1055,7 +1062,7 @@ } tty->magic = 0; (*tty->driver.refcount)--; - list_del(&tty->tty_files); + list_del_init(&tty->tty_files); free_tty_struct(tty); } @@ -1073,7 +1080,7 @@ int pty_master, tty_closing, o_tty_closing, do_sleep; int idx; char buf[64]; - + tty = (struct tty_struct *)filp->private_data; if (tty_paranoia_check(tty, filp->f_dentry->d_inode->i_rdev, "release_dev")) return; @@ -1131,7 +1138,7 @@ idx, kdevname(tty->device)); return; } - if (o_tty->termios_locked != + if (o_tty->termios_locked != tty->driver.other->termios_locked[idx]) { printk(KERN_DEBUG "release_dev: other->termios_locked[" "%d] not o_termios_locked for (%s)\n", @@ -1197,11 +1204,11 @@ printk(KERN_WARNING "release_dev: %s: read/write wait queue " "active!\n", tty_name(tty, buf)); schedule(); - } + } /* - * The closing flags are now consistent with the open counts on - * both sides, and we've completed the last operation that could + * The closing flags are now consistent with the open counts on + * both sides, and we've completed the last operation that could * block, so it's safe to proceed with closing. */ if (pty_master) { @@ -1259,7 +1266,7 @@ /* check whether both sides are closing ... */ if (!tty_closing || (o_tty && !o_tty_closing)) return; - + #ifdef TTY_DEBUG_HANGUP printk(KERN_DEBUG "freeing tty structure..."); #endif @@ -1277,14 +1284,14 @@ (o_tty->ldisc.close)(o_tty); o_tty->ldisc = ldiscs[N_TTY]; } - + /* - * Make sure that the tty's task queue isn't activated. + * Make sure that the tty's task queue isn't activated. */ run_task_queue(&tq_timer); flush_scheduled_tasks(); - /* + /* * The release_mem function takes care of the details of clearing * the slots and preserving the termios structure. */ @@ -1475,7 +1482,7 @@ tty = (struct tty_struct *)filp->private_data; if (tty_paranoia_check(tty, filp->f_dentry->d_inode->i_rdev, "tty_fasync")) return 0; - + retval = fasync_helper(fd, filp, on, &tty->fasync); if (retval <= 0) return retval; @@ -1690,7 +1697,7 @@ static int tty_generic_brk(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { - if (cmd == TCSBRK && arg) + if (cmd == TCSBRK && arg) { /* tcdrain case */ int retval = tty_check_change(tty); @@ -1711,7 +1718,7 @@ { struct tty_struct *tty, *real_tty; int retval; - + tty = (struct tty_struct *)file->private_data; if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl")) return -EINVAL; @@ -1731,7 +1738,7 @@ if (tty->driver.ioctl) return tty->driver.ioctl(tty, file, cmd, arg); return -EINVAL; - + /* These two ioctl's always return success; even if */ /* the driver doesn't support them. */ case TCSBRK: @@ -1754,7 +1761,7 @@ case TIOCSBRK: case TIOCCBRK: case TCSBRK: - case TCSBRKP: + case TCSBRKP: retval = tty_check_change(tty); if (retval) return retval; @@ -1817,7 +1824,7 @@ case TIOCSBRK: /* Turn break on, unconditionally */ tty->driver.break_ctl(tty, -1); return 0; - + case TIOCCBRK: /* Turn break off, unconditionally */ tty->driver.break_ctl(tty, 0); return 0; @@ -1830,7 +1837,7 @@ if (!arg) return send_break(tty, HZ/4); return 0; - case TCSBRKP: /* support for POSIX tcsendbreak() */ + case TCSBRKP: /* support for POSIX tcsendbreak() */ return send_break(tty, arg ? arg*(HZ/10) : HZ/4); } if (tty->driver.ioctl) { @@ -1852,7 +1859,7 @@ * prevent trojan horses by killing all processes associated with this * tty when the user hits the "Secure Attention Key". Required for * super-paranoid applications --- see the Orange Book for more details. - * + * * This code could be nicer; ideally it should send a HUP, wait a few * seconds, then send a INT, and then a KILL signal. But you then * have to coordinate with the init process, since all processes associated @@ -1876,7 +1883,7 @@ int session; int i; struct file *filp; - + if (!tty) return; session = tty->session; @@ -1961,7 +1968,7 @@ count = tty->flip.count; tty->flip.count = 0; restore_flags(flags); - + tty->ldisc.receive_buf(tty, cp, fp, count); } @@ -1993,7 +2000,7 @@ i = cflag & CBAUD; if (i & CBAUDEX) { i &= ~CBAUDEX; - if (i < 1 || i+15 >= n_baud_table) + if (i < 1 || i+15 >= n_baud_table) tty->termios->c_cflag &= ~CBAUDEX; else i += 15; @@ -2006,7 +2013,7 @@ } return(tty->alt_speed); } - + return baud_table[i]; } @@ -2072,7 +2079,7 @@ mode |= S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; break; } - if ( (minor < driver->minor_start) || + if ( (minor < driver->minor_start) || (minor >= driver->minor_start + driver->num) ) { printk(KERN_ERR "Attempt to register invalid minor number " "with devfs (%d:%d).\n", (int)driver->major,(int)minor); @@ -2125,12 +2132,12 @@ if (!driver->put_char) driver->put_char = tty_default_put_char; - + driver->prev = 0; driver->next = tty_drivers; if (tty_drivers) tty_drivers->prev = driver; tty_drivers = driver; - + if ( !(driver->flags & TTY_DRIVER_NO_DEVFS) ) { for(i = 0; i < driver->num; i++) tty_register_devfs(driver, 0, driver->minor_start + i); @@ -2149,7 +2156,7 @@ int i, found = 0; struct termios *tp; const char *othername = NULL; - + if (*driver->refcount) return -EBUSY; @@ -2159,7 +2166,7 @@ else if (p->major == driver->major) othername = p->name; } - + if (!found) return -ENOENT; @@ -2174,7 +2181,7 @@ driver->prev->next = driver->next; else tty_drivers = driver->next; - + if (driver->next) driver->next->prev = driver->prev; @@ -2214,7 +2221,7 @@ (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY); /* - * Set up the standard termios. Individual tty drivers may + * Set up the standard termios. Individual tty drivers may * deviate from this; this is used as a template. */ memset(&tty_std_termios, 0, sizeof(struct termios)); @@ -2226,20 +2233,23 @@ ECHOCTL | ECHOKE | IEXTEN; /* - * set up the console device so that later boot sequences can + * set up the console device so that later boot sequences can * inform about problems etc.. */ #ifdef CONFIG_EARLY_PRINTK - disable_early_printk(); + disable_early_printk(); +#endif +#ifdef CONFIG_HVC_CONSOLE + hvc_console_init(); #endif #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)) +#if (defined(CONFIG_8xx) || defined(CONFIG_CPM2)) console_8xx_init(); #elif defined(CONFIG_MAC_SERIAL) && defined(CONFIG_SERIAL) if (_machine == _MACH_Pmac) @@ -2253,9 +2263,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 +2273,9 @@ sci_console_init(); #endif #endif +#ifdef CONFIG_SERIAL_DEC_CONSOLE + dec_serial_console_init(); +#endif #ifdef CONFIG_TN3270_CONSOLE tub3270_con_init(); #endif @@ -2290,9 +2300,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 #ifdef CONFIG_SERIAL_21285_CONSOLE rs285_console_init(); #endif @@ -2328,7 +2344,7 @@ dev_tty_driver.num = 1; dev_tty_driver.type = TTY_DRIVER_TYPE_SYSTEM; dev_tty_driver.subtype = SYSTEM_TYPE_TTY; - + if (tty_register_driver(&dev_tty_driver)) panic("Couldn't register /dev/tty driver\n"); @@ -2344,7 +2360,7 @@ panic("Couldn't register /dev/console driver\n"); /* console calls tty_register_driver() before kmalloc() works. - * Thus, we can't devfs_register() then. Do so now, instead. + * Thus, we can't devfs_register() then. Do so now, instead. */ #ifdef CONFIG_VT con_init_devfs(); @@ -2362,7 +2378,7 @@ if (tty_register_driver(&dev_ptmx_driver)) panic("Couldn't register /dev/ptmx driver\n"); #endif - + #ifdef CONFIG_VT dev_console_driver = dev_tty_driver; dev_console_driver.driver_name = "/dev/vc/0"; @@ -2377,6 +2393,12 @@ kbd_init(); #endif +#ifdef CONFIG_SGI_L1_SERIAL_CONSOLE + if (ia64_platform_is("sn2")) { + sn_sal_serial_console_init(); + return; /* only one console right now for SN2 */ + } +#endif #ifdef CONFIG_ESPSERIAL /* init ESP before rs, so rs doesn't see the port */ espserial_init(); #endif @@ -2410,16 +2432,16 @@ #ifdef CONFIG_SPECIALIX specialix_init(); #endif -#if (defined(CONFIG_8xx) || defined(CONFIG_8260)) +#if (defined(CONFIG_8xx) || defined(CONFIG_CPM2)) rs_8xx_init(); #endif /* CONFIG_8xx */ pty_init(); #ifdef CONFIG_MOXA_SMARTIO mxser_init(); -#endif +#endif #ifdef CONFIG_MOXA_INTELLIO moxa_init(); -#endif +#endif #ifdef CONFIG_VT vcs_init(); #endif Index: drivers/char/wdt977.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/wdt977.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/wdt977.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/wdt977.c 4 Aug 2004 01:28:46 -0000 1.2 @@ -27,6 +27,7 @@ #include #include #include +#include #define WATCHDOG_MINOR 130 Index: drivers/char/wdt_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/wdt_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/wdt_pci.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/wdt_pci.c 4 Aug 2004 01:28:46 -0000 1.2 @@ -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 Index: drivers/char/agp/agp.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/agp/agp.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/agp/agp.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/agp/agp.h 4 Aug 2004 01:28:46 -0000 1.2 @@ -166,9 +166,18 @@ #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 +#ifndef PCI_DEVICE_ID_VIA_8380_0 +#define PCI_DEVICE_ID_VIA_8380_0 0x0204 +#endif +#ifndef PCI_DEVICE_ID_VIA_8385_0 +#define PCI_DEVICE_ID_VIA_8385_0 0x3188 +#endif #ifndef PCI_DEVICE_ID_INTEL_810_0 #define PCI_DEVICE_ID_INTEL_810_0 0x7120 #endif @@ -184,6 +193,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 @@ -202,6 +229,12 @@ #ifndef PCI_DEVICE_ID_INTEL_860_0 #define PCI_DEVICE_ID_INTEL_860_0 0x2531 #endif +#ifndef PCI_DEVICE_ID_INTEL_7205_0 +#define PCI_DEVICE_ID_INTEL_7205_0 0x255d +#endif +#ifndef PCI_DEVICE_ID_INTEL_7505_0 +#define PCI_DEVICE_ID_INTEL_7505_0 0x2550 +#endif #ifndef PCI_DEVICE_ID_INTEL_810_DC100_0 #define PCI_DEVICE_ID_INTEL_810_DC100_0 0x7122 #endif @@ -229,6 +262,9 @@ #ifndef PCI_DEVICE_ID_INTEL_82443GX_1 #define PCI_DEVICE_ID_INTEL_82443GX_1 0x71a1 #endif +#ifndef PCI_DEVICE_ID_INTEL_460GX +#define PCI_DEVICE_ID_INTEL_460GX 0x84ea +#endif #ifndef PCI_DEVICE_ID_AMD_IRONGATE_0 #define PCI_DEVICE_ID_AMD_IRONGATE_0 0x7006 #endif @@ -271,6 +307,33 @@ #ifndef PCI_DEVICE_ID_AL_M1671_0 #define PCI_DEVICE_ID_AL_M1671_0 0x1671 #endif +#ifndef PCI_VENDOR_ID_ATI +#define PCI_VENDOR_ID_ATI 0x1002 +#endif +#ifndef PCI_DEVICE_ID_ATI_RS100 +#define PCI_DEVICE_ID_ATI_RS100 0xcab0 +#endif +#ifndef PCI_DEVICE_ID_ATI_RS200 +#define PCI_DEVICE_ID_ATI_RS200 0xcab2 +#endif +#ifndef PCI_DEVICE_ID_ATI_RS250 +#define PCI_DEVICE_ID_ATI_RS250 0xcab3 +#endif +#ifndef PCI_DEVICE_ID_ATI_RS200_B +#define PCI_DEVICE_ID_ATI_RS200_B 0xcbb3 +#endif +#ifndef PCI_DEVICE_ID_ATI_RS300_100 +#define PCI_DEVICE_ID_ATI_RS300_100 0x5830 +#endif +#ifndef PCI_DEVICE_ID_ATI_RS300_133 +#define PCI_DEVICE_ID_ATI_RS300_133 0x5831 +#endif +#ifndef PCI_DEVICE_ID_ATI_RS300_166 +#define PCI_DEVICE_ID_ATI_RS300_166 0x5832 +#endif +#ifndef PCI_DEVICE_ID_ATI_RS300_200 +#define PCI_DEVICE_ID_ATI_RS300_200 0x5833 +#endif /* intel register */ #define INTEL_APBASE 0x10 @@ -280,6 +343,36 @@ #define INTEL_NBXCFG 0x50 #define INTEL_ERRSTS 0x91 +/* Intel 460GX Registers */ +#define INTEL_I460_APBASE 0x10 +#define INTEL_I460_BAPBASE 0x98 +#define INTEL_I460_GXBCTL 0xa0 +#define INTEL_I460_AGPSIZ 0xa2 +#define INTEL_I460_ATTBASE 0xfe200000 +#define INTEL_I460_GATT_VALID (1UL << 24) +#define INTEL_I460_GATT_COHERENT (1UL << 25) +/* 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 @@ -323,6 +416,10 @@ #define INTEL_I860_MCHCFG 0x50 #define INTEL_I860_ERRSTS 0xc8 +/* intel i7505 registers */ +#define INTEL_I7505_MCHCFG 0x50 +#define INTEL_I7505_ERRSTS 0x42 + /* intel i810 registers */ #define I810_GMADDR 0x10 #define I810_MMADDR 0x14 @@ -412,13 +509,48 @@ #define SVWRKS_POSTFLUSH 0x14 #define SVWRKS_DIRFLUSH 0x0c -/* HP ZX1 SBA registers */ -#define HP_ZX1_CTRL 0x200 +/* 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 + +/* NVIDIA x86-64 registers */ +#define NVIDIA_X86_64_0_APBASE 0x10 +#define NVIDIA_X86_64_1_APBASE1 0x50 +#define NVIDIA_X86_64_1_APLIMIT1 0x54 +#define NVIDIA_X86_64_1_APSIZE 0xa8 +#define NVIDIA_X86_64_1_APBASE2 0xd8 +#define NVIDIA_X86_64_1_APLIMIT2 0xdc + +/* HP ZX1 IOC registers */ #define HP_ZX1_IBASE 0x300 #define HP_ZX1_IMASK 0x308 #define HP_ZX1_PCOM 0x310 #define HP_ZX1_TCNFG 0x318 #define HP_ZX1_PDIR_BASE 0x320 -#define HP_ZX1_CACHE_FLUSH 0x428 + +/* HP ZX1 LBA registers */ +#define HP_ZX1_AGP_STATUS 0x64 +#define HP_ZX1_AGP_COMMAND 0x68 + +/* ATI register */ +#define ATI_APBASE 0x10 +#define ATI_GART_MMBASE_ADDR 0x14 +#define ATI_RS100_APSIZE 0xac +#define ATI_RS300_APSIZE 0xf8 +#define ATI_RS100_IG_AGPMODE 0xb0 +#define ATI_RS300_IG_AGPMODE 0xfc + +#define ATI_GART_FEATURE_ID 0x00 +#define ATI_GART_BASE 0x04 +#define ATI_GART_CACHE_SZBASE 0x08 +#define ATI_GART_CACHE_CNTRL 0x0c +#define ATI_GART_CACHE_ENTRY_CNTRL 0x10 #endif /* _AGP_BACKEND_PRIV_H */ Index: drivers/char/agp/agpgart_be.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/agp/agpgart_be.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/agp/agpgart_be.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/agp/agpgart_be.c 4 Aug 2004 01:28:46 -0000 1.2 @@ -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_X86 +#include +#endif #include #include "agp.h" @@ -60,6 +69,7 @@ EXPORT_SYMBOL(agp_backend_release); static void flush_cache(void); +static int agp_init_one(struct pci_dev *dev); static struct agp_bridge_data agp_bridge; static int agp_try_unsupported __initdata = 0; @@ -577,7 +587,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 +1232,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; @@ -1381,51 +1428,101 @@ #endif /* CONFIG_AGP_I810 */ - #ifdef CONFIG_AGP_INTEL +#ifdef CONFIG_AGP_I460 -#endif /* CONFIG_AGP_I810 */ +/* BIOS configures the chipset so that one of two apbase registers are used */ +static u8 intel_i460_dynamic_apbase = 0x10; -#ifdef CONFIG_AGP_INTEL +/* 460 supports multiple GART page sizes, so GART pageshift is dynamic */ +static u8 intel_i460_pageshift = 12; +static u32 intel_i460_pagesize; -static int intel_fetch_size(void) -{ - int i; - u16 temp; - aper_size_info_16 *values; +/* Keep track of which is larger, chipset or kernel page size. */ +static u32 intel_i460_cpk = 1; - pci_read_config_word(agp_bridge.dev, INTEL_APSIZE, &temp); - values = A_SIZE_16(agp_bridge.aperture_sizes); +/* Structure for tracking partial use of 4MB GART pages */ +static u32 **i460_pg_detail = NULL; +static u32 *i460_pg_count = NULL; - for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { - if (temp == 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; - } - } +#define I460_CPAGES_PER_KPAGE (PAGE_SIZE >> intel_i460_pageshift) +#define I460_KPAGES_PER_CPAGE ((1 << intel_i460_pageshift) >> PAGE_SHIFT) - return 0; +#define I460_SRAM_IO_DISABLE (1 << 4) +#define I460_BAPBASE_ENABLE (1 << 3) +#define I460_AGPSIZ_MASK 0x7 +#define I460_4M_PS (1 << 1) + +#define log2(x) ffz(~(x)) + +static gatt_mask intel_i460_masks[] = +{ + { INTEL_I460_GATT_VALID | INTEL_I460_GATT_COHERENT, 0 } +}; + +static unsigned long intel_i460_mask_memory(unsigned long addr, int type) +{ + /* Make sure the returned address is a valid GATT entry */ + return (agp_bridge.masks[0].mask | (((addr & + ~((1 << intel_i460_pageshift) - 1)) & 0xffffff000) >> 12)); } +static unsigned long intel_i460_unmask_memory(unsigned long addr) +{ + /* Turn a GATT entry into a physical address */ + return ((addr & 0xffffff) << 12); +} -static int intel_8xx_fetch_size(void) +static int intel_i460_fetch_size(void) { int i; u8 temp; aper_size_info_8 *values; - pci_read_config_byte(agp_bridge.dev, INTEL_APSIZE, &temp); + /* Determine the GART page size */ + pci_read_config_byte(agp_bridge.dev, INTEL_I460_GXBCTL, &temp); + intel_i460_pageshift = (temp & I460_4M_PS) ? 22 : 12; + intel_i460_pagesize = 1UL << intel_i460_pageshift; - /* Intel 815 chipsets have a _weird_ APSIZE register with only - * one non-reserved bit, so mask the others out ... */ - if (agp_bridge.type == INTEL_I815) - temp &= (1 << 3); - values = A_SIZE_8(agp_bridge.aperture_sizes); + pci_read_config_byte(agp_bridge.dev, INTEL_I460_AGPSIZ, &temp); + + /* Exit now if the IO drivers for the GART SRAMS are turned off */ + if (temp & I460_SRAM_IO_DISABLE) { + printk(KERN_WARNING PFX "GART SRAMS disabled on 460GX chipset\n"); + printk(KERN_WARNING PFX "AGPGART operation not possible\n"); + return 0; + } + + /* Make sure we don't try to create an 2 ^ 23 entry GATT */ + if ((intel_i460_pageshift == 0) && ((temp & I460_AGPSIZ_MASK) == 4)) { + printk(KERN_WARNING PFX "We can't have a 32GB aperture with 4KB" + " GART pages\n"); + return 0; + } + + /* Determine the proper APBASE register */ + if (temp & I460_BAPBASE_ENABLE) + intel_i460_dynamic_apbase = INTEL_I460_BAPBASE; + else + intel_i460_dynamic_apbase = INTEL_I460_APBASE; + for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { - if (temp == values[i].size_value) { + + /* + * Dynamically calculate the proper num_entries and page_order + * values for the define aperture sizes. Take care not to + * shift off the end of values[i].size. + */ + values[i].num_entries = (values[i].size << 8) >> + (intel_i460_pageshift - 12); + values[i].page_order = log2((sizeof(u32)*values[i].num_entries) + >> PAGE_SHIFT); + } + + for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { + /* Neglect control bits when matching up size_value */ + if ((temp & I460_AGPSIZ_MASK) == values[i].size_value) { agp_bridge.previous_size = agp_bridge.current_size = (void *) (values + i); agp_bridge.aperture_size_idx = i; @@ -1436,370 +1533,947 @@ return 0; } -static void intel_tlbflush(agp_memory * mem) -{ - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2200); - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280); -} - - -static void intel_8xx_tlbflush(agp_memory * mem) +/* There isn't anything to do here since 460 has no GART TLB. */ +static void intel_i460_tlb_flush(agp_memory * mem) { - u32 temp; - pci_read_config_dword(agp_bridge.dev, INTEL_AGPCTRL, &temp); - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, temp & ~(1 << 7)); - pci_read_config_dword(agp_bridge.dev, INTEL_AGPCTRL, &temp); - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, temp | (1 << 7)); + return; } - -static void intel_cleanup(void) +/* + * This utility function is needed to prevent corruption of the control bits + * which are stored along with the aperture size in 460's AGPSIZ register + */ +static void intel_i460_write_agpsiz(u8 size_value) { - u16 temp; - aper_size_info_16 *previous_size; + u8 temp; - previous_size = A_SIZE_16(agp_bridge.previous_size); - pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp); - pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp & ~(1 << 9)); - pci_write_config_word(agp_bridge.dev, INTEL_APSIZE, - previous_size->size_value); + pci_read_config_byte(agp_bridge.dev, INTEL_I460_AGPSIZ, &temp); + pci_write_config_byte(agp_bridge.dev, INTEL_I460_AGPSIZ, + ((temp & ~I460_AGPSIZ_MASK) | size_value)); } - -static void intel_8xx_cleanup(void) +static void intel_i460_cleanup(void) { - u16 temp; aper_size_info_8 *previous_size; previous_size = A_SIZE_8(agp_bridge.previous_size); - pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp); - pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp & ~(1 << 9)); - pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, - previous_size->size_value); + intel_i460_write_agpsiz(previous_size->size_value); + + if (intel_i460_cpk == 0) { + vfree(i460_pg_detail); + vfree(i460_pg_count); + } } -static int intel_configure(void) +/* Control bits for Out-Of-GART coherency and Burst Write Combining */ +#define I460_GXBCTL_OOG (1UL << 0) +#define I460_GXBCTL_BWC (1UL << 2) + +static int intel_i460_configure(void) { - u32 temp; - u16 temp2; - aper_size_info_16 *current_size; + union { + u32 small[2]; + u64 large; + } temp; + u8 scratch; + int i; - current_size = A_SIZE_16(agp_bridge.current_size); + aper_size_info_8 *current_size; - /* aperture size */ - pci_write_config_word(agp_bridge.dev, INTEL_APSIZE, - current_size->size_value); + temp.large = 0; - /* address to map to */ - pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + current_size = A_SIZE_8(agp_bridge.current_size); + intel_i460_write_agpsiz(current_size->size_value); - /* attbase - aperture base */ - pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, - agp_bridge.gatt_bus_addr); + /* + * Do the necessary rigmarole to read all eight bytes of APBASE. + * This has to be done since the AGP aperture can be above 4GB on + * 460 based systems. + */ + pci_read_config_dword(agp_bridge.dev, intel_i460_dynamic_apbase, + &(temp.small[0])); + pci_read_config_dword(agp_bridge.dev, intel_i460_dynamic_apbase + 4, + &(temp.small[1])); + + /* Clear BAR control bits */ + agp_bridge.gart_bus_addr = temp.large & ~((1UL << 3) - 1); + + pci_read_config_byte(agp_bridge.dev, INTEL_I460_GXBCTL, &scratch); + pci_write_config_byte(agp_bridge.dev, INTEL_I460_GXBCTL, + (scratch & 0x02) | I460_GXBCTL_OOG | I460_GXBCTL_BWC); + + /* + * Initialize partial allocation trackers if a GART page is bigger than + * a kernel page. + */ + if (I460_CPAGES_PER_KPAGE >= 1) { + intel_i460_cpk = 1; + } else { + intel_i460_cpk = 0; - /* agpctrl */ - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280); + i460_pg_detail = (void *) vmalloc(sizeof(*i460_pg_detail) * + current_size->num_entries); + i460_pg_count = (void *) vmalloc(sizeof(*i460_pg_count) * + current_size->num_entries); + + for (i = 0; i < current_size->num_entries; i++) { + i460_pg_count[i] = 0; + i460_pg_detail[i] = NULL; + } + } - /* paccfg/nbxcfg */ - pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp2); - pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, - (temp2 & ~(1 << 10)) | (1 << 9)); - /* clear any possible error conditions */ - pci_write_config_byte(agp_bridge.dev, INTEL_ERRSTS + 1, 7); return 0; } -static int intel_815_configure(void) -{ - u32 temp, addr; - u8 temp2; - aper_size_info_8 *current_size; +static int intel_i460_create_gatt_table(void) { - current_size = A_SIZE_8(agp_bridge.current_size); + char *table; + int i; + int page_order; + int num_entries; + void *temp; + unsigned int read_back; - /* aperture size */ - pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, - current_size->size_value); + /* + * Load up the fixed address of the GART SRAMS which hold our + * GATT table. + */ + table = (char *) __va(INTEL_I460_ATTBASE); - /* address to map to */ - pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + temp = agp_bridge.current_size; + page_order = A_SIZE_8(temp)->page_order; + num_entries = A_SIZE_8(temp)->num_entries; - /* attbase - aperture base */ - /* the Intel 815 chipset spec. says that bits 29-31 in the - * ATTBASE register are reserved -> try not to write them */ - if (agp_bridge.gatt_bus_addr & INTEL_815_ATTBASE_MASK) - panic("gatt bus addr too high"); - pci_read_config_dword(agp_bridge.dev, INTEL_ATTBASE, &addr); - addr &= INTEL_815_ATTBASE_MASK; - addr |= agp_bridge.gatt_bus_addr; - pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, addr); + agp_bridge.gatt_table_real = (u32 *) table; + agp_bridge.gatt_table = ioremap_nocache(virt_to_phys(table), + (PAGE_SIZE * (1 << page_order))); + agp_bridge.gatt_bus_addr = virt_to_phys(agp_bridge.gatt_table_real); - /* agpctrl */ - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + for (i = 0; i < num_entries; i++) { + agp_bridge.gatt_table[i] = 0; + } + + /* + * The 460 spec says we have to read the last location written to + * make sure that all writes have taken effect + */ + read_back = agp_bridge.gatt_table[i - 1]; - /* apcont */ - pci_read_config_byte(agp_bridge.dev, INTEL_815_APCONT, &temp2); - pci_write_config_byte(agp_bridge.dev, INTEL_815_APCONT, - temp2 | (1 << 1)); - /* clear any possible error conditions */ - /* Oddness : this chipset seems to have no ERRSTS register ! */ return 0; } -static void intel_820_tlbflush(agp_memory * mem) +static int intel_i460_free_gatt_table(void) { - return; -} + int num_entries; + int i; + void *temp; + unsigned int read_back; -static void intel_820_cleanup(void) -{ - u8 temp; - aper_size_info_8 *previous_size; + temp = agp_bridge.current_size; - previous_size = A_SIZE_8(agp_bridge.previous_size); - pci_read_config_byte(agp_bridge.dev, INTEL_I820_RDCR, &temp); - pci_write_config_byte(agp_bridge.dev, INTEL_I820_RDCR, - temp & ~(1 << 1)); - pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, - previous_size->size_value); + num_entries = A_SIZE_8(temp)->num_entries; + + for (i = 0; i < num_entries; i++) { + agp_bridge.gatt_table[i] = 0; + } + + /* + * The 460 spec says we have to read the last location written to + * make sure that all writes have taken effect + */ + read_back = agp_bridge.gatt_table[i - 1]; + + iounmap(agp_bridge.gatt_table); + + return 0; } +/* These functions are called when PAGE_SIZE exceeds the GART page size */ -static int intel_820_configure(void) +static int intel_i460_insert_memory_cpk(agp_memory * mem, + off_t pg_start, int type) { - u32 temp; - u8 temp2; - aper_size_info_8 *current_size; + int i, j, k, num_entries; + void *temp; + unsigned long paddr; + unsigned int read_back; - current_size = A_SIZE_8(agp_bridge.current_size); + /* + * The rest of the kernel will compute page offsets in terms of + * PAGE_SIZE. + */ + pg_start = I460_CPAGES_PER_KPAGE * pg_start; - /* aperture size */ - pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, - current_size->size_value); + temp = agp_bridge.current_size; + num_entries = A_SIZE_8(temp)->num_entries; - /* address to map to */ - pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + if ((pg_start + I460_CPAGES_PER_KPAGE * mem->page_count) > num_entries) { + printk(KERN_WARNING PFX "Looks like we're out of AGP memory\n"); + return -EINVAL; + } - /* attbase - aperture base */ - pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, - agp_bridge.gatt_bus_addr); + j = pg_start; + while (j < (pg_start + I460_CPAGES_PER_KPAGE * mem->page_count)) { + if (!PGE_EMPTY(agp_bridge.gatt_table[j])) { + return -EBUSY; + } + j++; + } - /* agpctrl */ - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + for (i = 0, j = pg_start; i < mem->page_count; i++) { + + paddr = mem->memory[i]; + + for (k = 0; k < I460_CPAGES_PER_KPAGE; k++, j++, paddr += intel_i460_pagesize) + agp_bridge.gatt_table[j] = (unsigned int) + agp_bridge.mask_memory(paddr, mem->type); + } + + /* + * The 460 spec says we have to read the last location written to + * make sure that all writes have taken effect + */ + read_back = agp_bridge.gatt_table[j - 1]; - /* global enable aperture access */ - /* This flag is not accessed through MCHCFG register as in */ - /* i850 chipset. */ - pci_read_config_byte(agp_bridge.dev, INTEL_I820_RDCR, &temp2); - pci_write_config_byte(agp_bridge.dev, INTEL_I820_RDCR, - temp2 | (1 << 1)); - /* clear any possible AGP-related error conditions */ - pci_write_config_word(agp_bridge.dev, INTEL_I820_ERRSTS, 0x001c); return 0; } -static int intel_830mp_configure(void) +static int intel_i460_remove_memory_cpk(agp_memory * mem, off_t pg_start, + int type) { - u32 temp; - u16 temp2; - aper_size_info_8 *current_size; - - current_size = A_SIZE_8(agp_bridge.current_size); - - /* aperture size */ - pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, - current_size->size_value); + int i; + unsigned int read_back; - /* address to map to */ - pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + pg_start = I460_CPAGES_PER_KPAGE * pg_start; - /* attbase - aperture base */ - pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, - agp_bridge.gatt_bus_addr); + for (i = pg_start; i < (pg_start + I460_CPAGES_PER_KPAGE * + mem->page_count); i++) + agp_bridge.gatt_table[i] = 0; - /* agpctrl */ - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + /* + * The 460 spec says we have to read the last location written to + * make sure that all writes have taken effect + */ + read_back = agp_bridge.gatt_table[i - 1]; - /* gmch */ - pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp2); - pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, - temp2 | (1 << 9)); - /* clear any possible AGP-related error conditions */ - pci_write_config_word(agp_bridge.dev, INTEL_I830_ERRSTS, 0x1c); - return 0; + return 0; } - +/* + * These functions are called when the GART page size exceeds PAGE_SIZE. + * + * This situation is interesting since AGP memory allocations that are + * smaller than a single GART page are possible. The structures i460_pg_count + * and i460_pg_detail track partial allocation of the large GART pages to + * work around this issue. + * + * i460_pg_count[pg_num] tracks the number of kernel pages in use within + * GART page pg_num. i460_pg_detail[pg_num] is an array containing a + * psuedo-GART entry for each of the aforementioned kernel pages. The whole + * of i460_pg_detail is equivalent to a giant GATT with page size equal to + * that of the kernel. + */ -static int intel_840_configure(void) +static void *intel_i460_alloc_large_page(int pg_num) { - u32 temp; - u16 temp2; - aper_size_info_8 *current_size; + int i; + void *bp, *bp_end; + struct page *page; - current_size = A_SIZE_8(agp_bridge.current_size); + i460_pg_detail[pg_num] = (void *) vmalloc(sizeof(u32) * + I460_KPAGES_PER_CPAGE); + if (i460_pg_detail[pg_num] == NULL) { + printk(KERN_WARNING PFX "Out of memory, we're in trouble...\n"); + return NULL; + } - /* aperture size */ - pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, - current_size->size_value); + for (i = 0; i < I460_KPAGES_PER_CPAGE; i++) + i460_pg_detail[pg_num][i] = 0; - /* address to map to */ - pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + bp = (void *) __get_free_pages(GFP_KERNEL, + intel_i460_pageshift - PAGE_SHIFT); + if (bp == NULL) { + printk(KERN_WARNING PFX "Couldn't alloc 4M GART page...\n"); + return NULL; + } - /* attbase - aperture base */ - pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, - agp_bridge.gatt_bus_addr); + bp_end = bp + ((PAGE_SIZE * + (1 << (intel_i460_pageshift - PAGE_SHIFT))) - 1); - /* agpctrl */ - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + for (page = virt_to_page(bp); page <= virt_to_page(bp_end); page++) { + atomic_inc(&page->count); + set_bit(PG_locked, &page->flags); + atomic_inc(&agp_bridge.current_memory_agp); + } - /* mcgcfg */ - pci_read_config_word(agp_bridge.dev, INTEL_I840_MCHCFG, &temp2); - pci_write_config_word(agp_bridge.dev, INTEL_I840_MCHCFG, - temp2 | (1 << 9)); - /* clear any possible error conditions */ - pci_write_config_word(agp_bridge.dev, INTEL_I840_ERRSTS, 0xc000); - return 0; + return bp; } -static int intel_845_configure(void) +static void intel_i460_free_large_page(int pg_num, unsigned long addr) { - u32 temp; - u8 temp2; - aper_size_info_8 *current_size; + struct page *page; + void *bp, *bp_end; - current_size = A_SIZE_8(agp_bridge.current_size); + bp = (void *) __va(addr); + bp_end = bp + (PAGE_SIZE * + (1 << (intel_i460_pageshift - PAGE_SHIFT))); - /* aperture size */ - pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, - current_size->size_value); + vfree(i460_pg_detail[pg_num]); + i460_pg_detail[pg_num] = NULL; - /* address to map to */ - pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + for (page = virt_to_page(bp); page < virt_to_page(bp_end); page++) { + put_page(page); + UnlockPage(page); + atomic_dec(&agp_bridge.current_memory_agp); + } - /* attbase - aperture base */ - pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, - agp_bridge.gatt_bus_addr); + free_pages((unsigned long) bp, intel_i460_pageshift - PAGE_SHIFT); +} + +static int intel_i460_insert_memory_kpc(agp_memory * mem, + off_t pg_start, int type) +{ + int i, pg, start_pg, end_pg, start_offset, end_offset, idx; + int num_entries; + void *temp; + unsigned int read_back; + unsigned long paddr; - /* agpctrl */ - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + temp = agp_bridge.current_size; + num_entries = A_SIZE_8(temp)->num_entries; - /* agpm */ - pci_read_config_byte(agp_bridge.dev, INTEL_I845_AGPM, &temp2); - pci_write_config_byte(agp_bridge.dev, INTEL_I845_AGPM, - temp2 | (1 << 1)); - /* clear any possible error conditions */ - pci_write_config_word(agp_bridge.dev, INTEL_I845_ERRSTS, 0x001c); + /* Figure out what pg_start means in terms of our large GART pages */ + start_pg = pg_start / I460_KPAGES_PER_CPAGE; + start_offset = pg_start % I460_KPAGES_PER_CPAGE; + end_pg = (pg_start + mem->page_count - 1) / + I460_KPAGES_PER_CPAGE; + end_offset = (pg_start + mem->page_count - 1) % + I460_KPAGES_PER_CPAGE; + + if (end_pg > num_entries) { + printk(KERN_WARNING PFX "Looks like we're out of AGP memory\n"); + return -EINVAL; + } + + /* Check if the requested region of the aperture is free */ + for (pg = start_pg; pg <= end_pg; pg++) { + /* Allocate new GART pages if necessary */ + if (i460_pg_detail[pg] == NULL) { + temp = intel_i460_alloc_large_page(pg); + if (temp == NULL) + return -ENOMEM; + agp_bridge.gatt_table[pg] = agp_bridge.mask_memory( + (unsigned long) temp, 0); + read_back = agp_bridge.gatt_table[pg]; + } + + for (idx = ((pg == start_pg) ? start_offset : 0); + idx < ((pg == end_pg) ? (end_offset + 1) + : I460_KPAGES_PER_CPAGE); + idx++) { + if(i460_pg_detail[pg][idx] != 0) + return -EBUSY; + } + } + + for (pg = start_pg, i = 0; pg <= end_pg; pg++) { + paddr = intel_i460_unmask_memory(agp_bridge.gatt_table[pg]); + for (idx = ((pg == start_pg) ? start_offset : 0); + idx < ((pg == end_pg) ? (end_offset + 1) + : I460_KPAGES_PER_CPAGE); + idx++, i++) { + mem->memory[i] = paddr + (idx * PAGE_SIZE); + i460_pg_detail[pg][idx] = + agp_bridge.mask_memory(mem->memory[i], mem->type); + + i460_pg_count[pg]++; + } + } + + return 0; +} + +static int intel_i460_remove_memory_kpc(agp_memory * mem, + off_t pg_start, int type) +{ + int i, pg, start_pg, end_pg, start_offset, end_offset, idx; + int num_entries; + void *temp; + unsigned int read_back; + unsigned long paddr; + + temp = agp_bridge.current_size; + num_entries = A_SIZE_8(temp)->num_entries; + + /* Figure out what pg_start means in terms of our large GART pages */ + start_pg = pg_start / I460_KPAGES_PER_CPAGE; + start_offset = pg_start % I460_KPAGES_PER_CPAGE; + end_pg = (pg_start + mem->page_count - 1) / + I460_KPAGES_PER_CPAGE; + end_offset = (pg_start + mem->page_count - 1) % + I460_KPAGES_PER_CPAGE; + + for (i = 0, pg = start_pg; pg <= end_pg; pg++) { + for (idx = ((pg == start_pg) ? start_offset : 0); + idx < ((pg == end_pg) ? (end_offset + 1) + : I460_KPAGES_PER_CPAGE); + idx++, i++) { + mem->memory[i] = 0; + i460_pg_detail[pg][idx] = 0; + i460_pg_count[pg]--; + } + + /* Free GART pages if they are unused */ + if (i460_pg_count[pg] == 0) { + paddr = intel_i460_unmask_memory(agp_bridge.gatt_table[pg]); + agp_bridge.gatt_table[pg] = agp_bridge.scratch_page; + read_back = agp_bridge.gatt_table[pg]; + + intel_i460_free_large_page(pg, paddr); + } + } + return 0; } -static void intel_845_resume(void) +/* Dummy routines to call the approriate {cpk,kpc} function */ + +static int intel_i460_insert_memory(agp_memory * mem, + off_t pg_start, int type) { - intel_845_configure(); + if (intel_i460_cpk) + return intel_i460_insert_memory_cpk(mem, pg_start, type); + else + return intel_i460_insert_memory_kpc(mem, pg_start, type); } +static int intel_i460_remove_memory(agp_memory * mem, + off_t pg_start, int type) +{ + if (intel_i460_cpk) + return intel_i460_remove_memory_cpk(mem, pg_start, type); + else + return intel_i460_remove_memory_kpc(mem, pg_start, type); +} -static int intel_850_configure(void) +/* + * If the kernel page size is smaller that the chipset page size, we don't + * want to allocate memory until we know where it is to be bound in the + * aperture (a multi-kernel-page alloc might fit inside of an already + * allocated GART page). Consequently, don't allocate or free anything + * if i460_cpk (meaning chipset pages per kernel page) isn't set. + * + * Let's just hope nobody counts on the allocated AGP memory being there + * before bind time (I don't think current drivers do)... + */ +static unsigned long intel_i460_alloc_page(void) { - u32 temp; - u16 temp2; - aper_size_info_8 *current_size; + if (intel_i460_cpk) + return agp_generic_alloc_page(); - current_size = A_SIZE_8(agp_bridge.current_size); + /* Returning NULL would cause problems */ + return ((unsigned long) ~0UL); +} - /* aperture size */ - pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, - current_size->size_value); +static void intel_i460_destroy_page(unsigned long page) +{ + if (intel_i460_cpk) + agp_generic_destroy_page(page); +} - /* address to map to */ - pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); +static aper_size_info_8 intel_i460_sizes[3] = +{ + /* + * The 32GB aperture is only available with a 4M GART page size. + * Due to the dynamic GART page size, we can't figure out page_order + * or num_entries until runtime. + */ + {32768, 0, 0, 4}, + {1024, 0, 0, 2}, + {256, 0, 0, 1} +}; - /* attbase - aperture base */ - pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, - agp_bridge.gatt_bus_addr); +static int __init intel_i460_setup(struct pci_dev *pdev) +{ + agp_bridge.masks = intel_i460_masks; + agp_bridge.aperture_sizes = (void *) intel_i460_sizes; + agp_bridge.size_type = U8_APER_SIZE; + agp_bridge.num_aperture_sizes = 3; + agp_bridge.dev_private_data = NULL; + agp_bridge.needs_scratch_page = FALSE; + agp_bridge.configure = intel_i460_configure; + agp_bridge.fetch_size = intel_i460_fetch_size; + agp_bridge.cleanup = intel_i460_cleanup; + agp_bridge.tlb_flush = intel_i460_tlb_flush; + agp_bridge.mask_memory = intel_i460_mask_memory; + agp_bridge.agp_enable = agp_generic_agp_enable; + agp_bridge.cache_flush = global_cache_flush; + agp_bridge.create_gatt_table = intel_i460_create_gatt_table; + agp_bridge.free_gatt_table = intel_i460_free_gatt_table; + agp_bridge.insert_memory = intel_i460_insert_memory; + agp_bridge.remove_memory = intel_i460_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 = intel_i460_alloc_page; + agp_bridge.agp_destroy_page = intel_i460_destroy_page; + agp_bridge.suspend = agp_generic_suspend; + agp_bridge.resume = agp_generic_resume; + agp_bridge.cant_use_aperture = 1; - /* agpctrl */ - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + return 0; - /* mcgcfg */ - pci_read_config_word(agp_bridge.dev, INTEL_I850_MCHCFG, &temp2); - pci_write_config_word(agp_bridge.dev, INTEL_I850_MCHCFG, - temp2 | (1 << 9)); - /* clear any possible AGP-related error conditions */ - pci_write_config_word(agp_bridge.dev, INTEL_I850_ERRSTS, 0x001c); - return 0; + (void) pdev; /* unused */ } -static int intel_860_configure(void) -{ - u32 temp; - u16 temp2; - aper_size_info_8 *current_size; - - current_size = A_SIZE_8(agp_bridge.current_size); +#endif /* CONFIG_AGP_I460 */ - /* aperture size */ - pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, - current_size->size_value); +#ifdef CONFIG_AGP_INTEL - /* address to map to */ - pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); +static int intel_fetch_size(void) +{ + int i; + u16 temp; + aper_size_info_16 *values; - /* attbase - aperture base */ - pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, - agp_bridge.gatt_bus_addr); + pci_read_config_word(agp_bridge.dev, INTEL_APSIZE, &temp); + values = A_SIZE_16(agp_bridge.aperture_sizes); - /* agpctrl */ - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { + if (temp == 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; + } + } - /* mcgcfg */ - pci_read_config_word(agp_bridge.dev, INTEL_I860_MCHCFG, &temp2); - pci_write_config_word(agp_bridge.dev, INTEL_I860_MCHCFG, - temp2 | (1 << 9)); - /* clear any possible AGP-related error conditions */ - pci_write_config_word(agp_bridge.dev, INTEL_I860_ERRSTS, 0xf700); return 0; } -static unsigned long intel_mask_memory(unsigned long addr, int type) +static int intel_8xx_fetch_size(void) { - /* Memory type is ignored */ + int i; + u8 temp; + aper_size_info_8 *values; - return addr | agp_bridge.masks[0].mask; + pci_read_config_byte(agp_bridge.dev, INTEL_APSIZE, &temp); + + /* Intel 815 chipsets have a _weird_ APSIZE register with only + * one non-reserved bit, so mask the others out ... */ + if (agp_bridge.type == INTEL_I815) + temp &= (1 << 3); + + values = A_SIZE_8(agp_bridge.aperture_sizes); + + for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { + if (temp == 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; } -static void intel_resume(void) +static void intel_tlbflush(agp_memory * mem) { - intel_configure(); + pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2200); + pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280); } -/* Setup function */ -static gatt_mask intel_generic_masks[] = -{ - {0x00000017, 0} -}; -static aper_size_info_8 intel_815_sizes[2] = +static void intel_8xx_tlbflush(agp_memory * mem) { - {64, 16384, 4, 0}, - {32, 8192, 3, 8}, -}; + u32 temp; + pci_read_config_dword(agp_bridge.dev, INTEL_AGPCTRL, &temp); + pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, temp & ~(1 << 7)); + pci_read_config_dword(agp_bridge.dev, INTEL_AGPCTRL, &temp); + pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, temp | (1 << 7)); +} -static aper_size_info_8 intel_8xx_sizes[7] = + +static void intel_cleanup(void) { - {256, 65536, 6, 0}, - {128, 32768, 5, 32}, - {64, 16384, 4, 48}, + u16 temp; + aper_size_info_16 *previous_size; + + previous_size = A_SIZE_16(agp_bridge.previous_size); + pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp); + pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp & ~(1 << 9)); + pci_write_config_word(agp_bridge.dev, INTEL_APSIZE, + previous_size->size_value); +} + + +static void intel_8xx_cleanup(void) +{ + u16 temp; + aper_size_info_8 *previous_size; + + previous_size = A_SIZE_8(agp_bridge.previous_size); + pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp); + pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp & ~(1 << 9)); + pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, + previous_size->size_value); +} + + +static int intel_configure(void) +{ + u32 temp; + u16 temp2; + aper_size_info_16 *current_size; + + current_size = A_SIZE_16(agp_bridge.current_size); + + /* aperture size */ + pci_write_config_word(agp_bridge.dev, INTEL_APSIZE, + current_size->size_value); + + /* address to map to */ + pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); + agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + + /* attbase - aperture base */ + pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, + agp_bridge.gatt_bus_addr); + + /* agpctrl */ + pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280); + + /* paccfg/nbxcfg */ + pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp2); + pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, + (temp2 & ~(1 << 10)) | (1 << 9)); + /* clear any possible error conditions */ + pci_write_config_byte(agp_bridge.dev, INTEL_ERRSTS + 1, 7); + return 0; +} + +static int intel_815_configure(void) +{ + u32 temp, addr; + u8 temp2; + aper_size_info_8 *current_size; + + current_size = A_SIZE_8(agp_bridge.current_size); + + /* aperture size */ + pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, + current_size->size_value); + + /* address to map to */ + pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); + agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + + /* attbase - aperture base */ + /* the Intel 815 chipset spec. says that bits 29-31 in the + * ATTBASE register are reserved -> try not to write them */ + if (agp_bridge.gatt_bus_addr & INTEL_815_ATTBASE_MASK) + panic("gatt bus addr too high"); + pci_read_config_dword(agp_bridge.dev, INTEL_ATTBASE, &addr); + addr &= INTEL_815_ATTBASE_MASK; + addr |= agp_bridge.gatt_bus_addr; + pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, addr); + + /* agpctrl */ + pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + + /* apcont */ + pci_read_config_byte(agp_bridge.dev, INTEL_815_APCONT, &temp2); + pci_write_config_byte(agp_bridge.dev, INTEL_815_APCONT, + temp2 | (1 << 1)); + /* clear any possible error conditions */ + /* Oddness : this chipset seems to have no ERRSTS register ! */ + return 0; +} + +static void intel_820_tlbflush(agp_memory * mem) +{ + return; +} + +static void intel_820_cleanup(void) +{ + u8 temp; + aper_size_info_8 *previous_size; + + previous_size = A_SIZE_8(agp_bridge.previous_size); + pci_read_config_byte(agp_bridge.dev, INTEL_I820_RDCR, &temp); + pci_write_config_byte(agp_bridge.dev, INTEL_I820_RDCR, + temp & ~(1 << 1)); + pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, + previous_size->size_value); +} + + +static int intel_820_configure(void) +{ + u32 temp; + u8 temp2; + aper_size_info_8 *current_size; + + current_size = A_SIZE_8(agp_bridge.current_size); + + /* aperture size */ + pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, + current_size->size_value); + + /* address to map to */ + pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); + agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + + /* attbase - aperture base */ + pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, + agp_bridge.gatt_bus_addr); + + /* agpctrl */ + pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + + /* global enable aperture access */ + /* This flag is not accessed through MCHCFG register as in */ + /* i850 chipset. */ + pci_read_config_byte(agp_bridge.dev, INTEL_I820_RDCR, &temp2); + pci_write_config_byte(agp_bridge.dev, INTEL_I820_RDCR, + temp2 | (1 << 1)); + /* clear any possible AGP-related error conditions */ + pci_write_config_word(agp_bridge.dev, INTEL_I820_ERRSTS, 0x001c); + return 0; +} + +static int intel_830mp_configure(void) +{ + u32 temp; + u16 temp2; + aper_size_info_8 *current_size; + + current_size = A_SIZE_8(agp_bridge.current_size); + + /* aperture size */ + pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, + current_size->size_value); + + /* address to map to */ + pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); + agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + + /* attbase - aperture base */ + pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, + agp_bridge.gatt_bus_addr); + + /* agpctrl */ + pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + + /* gmch */ + pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp2); + pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, + temp2 | (1 << 9)); + /* clear any possible AGP-related error conditions */ + pci_write_config_word(agp_bridge.dev, INTEL_I830_ERRSTS, 0x1c); + return 0; +} + + + +static int intel_840_configure(void) +{ + u32 temp; + u16 temp2; + aper_size_info_8 *current_size; + + current_size = A_SIZE_8(agp_bridge.current_size); + + /* aperture size */ + pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, + current_size->size_value); + + /* address to map to */ + pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); + agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + + /* attbase - aperture base */ + pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, + agp_bridge.gatt_bus_addr); + + /* agpctrl */ + pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + + /* mcgcfg */ + pci_read_config_word(agp_bridge.dev, INTEL_I840_MCHCFG, &temp2); + pci_write_config_word(agp_bridge.dev, INTEL_I840_MCHCFG, + temp2 | (1 << 9)); + /* clear any possible error conditions */ + pci_write_config_word(agp_bridge.dev, INTEL_I840_ERRSTS, 0xc000); + return 0; +} + +static int intel_845_configure(void) +{ + u32 temp; + u8 temp2; + aper_size_info_8 *current_size; + + current_size = A_SIZE_8(agp_bridge.current_size); + + /* aperture size */ + pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, + current_size->size_value); + + /* address to map to */ + pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); + agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + + /* attbase - aperture base */ + pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, + agp_bridge.gatt_bus_addr); + + /* agpctrl */ + pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + + /* agpm */ + pci_read_config_byte(agp_bridge.dev, INTEL_I845_AGPM, &temp2); + pci_write_config_byte(agp_bridge.dev, INTEL_I845_AGPM, + temp2 | (1 << 1)); + /* clear any possible error conditions */ + pci_write_config_word(agp_bridge.dev, INTEL_I845_ERRSTS, 0x001c); + return 0; +} + +static void intel_845_resume(void) +{ + intel_845_configure(); +} + + +static int intel_850_configure(void) +{ + u32 temp; + u16 temp2; + aper_size_info_8 *current_size; + + current_size = A_SIZE_8(agp_bridge.current_size); + + /* aperture size */ + pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, + current_size->size_value); + + /* address to map to */ + pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); + agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + + /* attbase - aperture base */ + pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, + agp_bridge.gatt_bus_addr); + + /* agpctrl */ + pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + + /* mcgcfg */ + pci_read_config_word(agp_bridge.dev, INTEL_I850_MCHCFG, &temp2); + pci_write_config_word(agp_bridge.dev, INTEL_I850_MCHCFG, + temp2 | (1 << 9)); + /* clear any possible AGP-related error conditions */ + pci_write_config_word(agp_bridge.dev, INTEL_I850_ERRSTS, 0x001c); + return 0; +} + +static int intel_860_configure(void) +{ + u32 temp; + u16 temp2; + aper_size_info_8 *current_size; + + current_size = A_SIZE_8(agp_bridge.current_size); + + /* aperture size */ + pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, + current_size->size_value); + + /* address to map to */ + pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); + agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + + /* attbase - aperture base */ + pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, + agp_bridge.gatt_bus_addr); + + /* agpctrl */ + pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + + /* mcgcfg */ + pci_read_config_word(agp_bridge.dev, INTEL_I860_MCHCFG, &temp2); + pci_write_config_word(agp_bridge.dev, INTEL_I860_MCHCFG, + temp2 | (1 << 9)); + /* clear any possible AGP-related error conditions */ + pci_write_config_word(agp_bridge.dev, INTEL_I860_ERRSTS, 0xf700); + return 0; +} + + +static int intel_7505_configure(void) +{ + u32 temp; + u16 temp2; + aper_size_info_8 *current_size; + + current_size = A_SIZE_8(agp_bridge.current_size); + + /* aperture size */ + pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, + current_size->size_value); + + /* address to map to */ + pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); + agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + + /* attbase - aperture base */ + pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, + agp_bridge.gatt_bus_addr); + + /* agpctrl */ + pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + + /* mcgcfg */ + pci_read_config_word(agp_bridge.dev, INTEL_I7505_MCHCFG, &temp2); + pci_write_config_word(agp_bridge.dev, INTEL_I7505_MCHCFG, + temp2 | (1 << 9)); + return 0; +} + + +static unsigned long intel_mask_memory(unsigned long addr, int type) +{ + /* Memory type is ignored */ + + return addr | agp_bridge.masks[0].mask; +} + +static void intel_resume(void) +{ + intel_configure(); +} + +/* Setup function */ +static gatt_mask intel_generic_masks[] = +{ + {0x00000017, 0} +}; + +static aper_size_info_8 intel_815_sizes[2] = +{ + {64, 16384, 4, 0}, + {32, 8192, 3, 8}, +}; + +static aper_size_info_8 intel_8xx_sizes[7] = +{ + {256, 65536, 6, 0}, + {128, 32768, 5, 32}, + {64, 16384, 4, 48}, {32, 8192, 3, 56}, {16, 4096, 2, 60}, {8, 2048, 1, 62}, @@ -2080,6 +2754,38 @@ (void) pdev; /* unused */ } +static int __init intel_7505_setup (struct pci_dev *pdev) +{ + agp_bridge.masks = intel_generic_masks; + agp_bridge.aperture_sizes = (void *) intel_8xx_sizes; + agp_bridge.size_type = U8_APER_SIZE; + agp_bridge.num_aperture_sizes = 7; + agp_bridge.dev_private_data = NULL; + agp_bridge.needs_scratch_page = FALSE; + agp_bridge.configure = intel_7505_configure; + agp_bridge.fetch_size = intel_8xx_fetch_size; + agp_bridge.cleanup = intel_8xx_cleanup; + agp_bridge.tlb_flush = intel_8xx_tlbflush; + agp_bridge.mask_memory = intel_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 = agp_generic_insert_memory; + agp_bridge.remove_memory = agp_generic_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; + + (void) pdev; /* unused */ +} + #endif /* CONFIG_AGP_INTEL */ #ifdef CONFIG_AGP_VIA @@ -2450,8 +3156,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 +3183,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); @@ -2698,38 +3404,11 @@ #endif /* CONFIG_AGP_AMD */ -#ifdef CONFIG_AGP_AMD_8151 +#ifdef CONFIG_AGP_AMD_K8 /* Begin AMD-8151 support */ -static u_int64_t pci_read64 (struct pci_dev *dev, int reg) -{ - union { - u64 full; - struct { - u32 high; - u32 low; - } split; - } tmp; - pci_read_config_dword(dev, reg, &tmp.split.high); - pci_read_config_dword(dev, reg+4, &tmp.split.low); - return tmp.full; -} - -static void pci_write64 (struct pci_dev *dev, int reg, u64 value) -{ - union { - u64 full; - struct { - u32 high; - u32 low; - } split; - } tmp; - tmp.full = value; - pci_write_config_dword(dev, reg, tmp.split.high); - pci_write_config_dword(dev, reg+4, tmp.split.low); -} - +/* This is misnamed. It is really a generic AMD K8 Northbridge AMD driver. */ static int x86_64_insert_memory(agp_memory * mem, off_t pg_start, int type) { @@ -2737,7 +3416,6 @@ void *temp; long tmp; u32 pte; - u64 addr; temp = agp_bridge.current_size; @@ -2767,9 +3445,8 @@ } for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { - addr = agp_bridge.mask_memory(mem->memory[i], mem->type); + tmp = agp_bridge.mask_memory(mem->memory[i], mem->type); - tmp = addr; BUG_ON(tmp & 0xffffff0000000ffc); pte = (tmp & 0x000000ff00000000) >> 28; pte |=(tmp & 0x00000000fffff000); @@ -2901,72 +3578,23 @@ {512, 131072, 7, 0x00000600 }, /* 1 1 0 0 0 0 */ {256, 65536, 6, 0x00000700 }, /* 1 1 1 0 0 0 */ {128, 32768, 5, 0x00000720 }, /* 1 1 1 1 0 0 */ - {64, 16384, 4, 0x00000730 }, /* 1 1 1 1 1 0 */ - {32, 8192, 3, 0x00000738 } /* 1 1 1 1 1 1 */ -}; - -static int amd_8151_configure(void) -{ - struct pci_dev *dev, *hammer=NULL; - int current_size; - int tmp, tmp2, i; - u64 aperbar; - unsigned long gatt_bus = virt_to_phys(agp_bridge.gatt_table_real); - - /* Configure AGP regs in each x86-64 host bridge. */ - pci_for_each_dev(dev) { - if (dev->bus->number==0 && - PCI_FUNC(dev->devfn)==3 && - PCI_SLOT(dev->devfn)>=24 && PCI_SLOT(dev->devfn)<=31) { - agp_bridge.gart_bus_addr = amd_x86_64_configure(dev,gatt_bus); - hammer = dev; - - /* - * TODO: Cache pci_dev's of x86-64's in private struct to save us - * having to scan the pci list each time. - */ - } - } - - if (hammer == NULL) { - return -ENODEV; - } - - /* Shadow x86-64 registers into 8151 registers. */ - - dev = agp_bridge.dev; - if (!dev) - return -ENODEV; - - current_size = amd_x86_64_fetch_size(); + {64, 16384, 4, 0x00000730 }, /* 1 1 1 1 1 0 */ + {32, 8192, 3, 0x00000738 } /* 1 1 1 1 1 1 */ +}; - pci_read_config_dword(dev, AMD_8151_APERTURESIZE, &tmp); - tmp &= ~(0xfff); +static int amd_8151_configure(void) +{ + struct pci_dev *dev; + unsigned long gatt_bus = virt_to_phys(agp_bridge.gatt_table_real); - /* translate x86-64 size bits to 8151 size bits*/ - for (i=0 ; i<7; i++) { - if (amd_8151_sizes[i].size == current_size) - tmp |= (amd_8151_sizes[i].size_value) << 3; + /* Configure AGP regs in each x86-64 host bridge. */ + pci_for_each_dev(dev) { + if (dev->bus->number==0 && + PCI_FUNC(dev->devfn)==3 && + PCI_SLOT(dev->devfn)>=24 && PCI_SLOT(dev->devfn)<=31) { + agp_bridge.gart_bus_addr = amd_x86_64_configure(dev,gatt_bus); + } } - pci_write_config_dword(dev, AMD_8151_APERTURESIZE, tmp); - - pci_read_config_dword (hammer, AMD_X86_64_GARTAPERTUREBASE, &tmp); - aperbar = pci_read64 (dev, AMD_8151_VMAPERTURE); - aperbar |= (tmp & 0x7fff) <<25; - aperbar &= 0x000000ffffffffff; - aperbar |= 1<<2; /* This address is a 64bit ptr FIXME: Make conditional in 32bit mode */ - pci_write64 (dev, AMD_8151_VMAPERTURE, aperbar); - - pci_read_config_dword(dev, AMD_8151_AGP_CTL , &tmp); - tmp &= ~(AMD_8151_GTLBEN | AMD_8151_APEREN); - - pci_read_config_dword(hammer, AMD_X86_64_GARTAPERTURECTL, &tmp2); - if (tmp2 & AMD_X86_64_GARTEN) - tmp |= AMD_8151_APEREN; - // FIXME: bit 7 of AMD_8151_AGP_CTL (GTLBEN) must be copied if set. - // But where is it set ? - pci_write_config_dword(dev, AMD_8151_AGP_CTL, tmp); - return 0; } @@ -2985,15 +3613,6 @@ tmp &= ~(AMD_X86_64_GARTEN); pci_write_config_dword (dev, AMD_X86_64_GARTAPERTURECTL, tmp); } - - /* Now shadow the disable in the 8151 */ - if (dev->vendor == PCI_VENDOR_ID_AMD && - dev->device == PCI_DEVICE_ID_AMD_8151_0) { - - pci_read_config_dword (dev, AMD_8151_AGP_CTL, &tmp); - tmp &= ~(AMD_8151_APEREN); - pci_write_config_dword (dev, AMD_8151_AGP_CTL, tmp); - } } } @@ -3007,7 +3626,7 @@ static gatt_mask amd_8151_masks[] = { - {0x00000001, 0} + {0, 0} }; @@ -3042,7 +3661,7 @@ printk (KERN_INFO "AGP: Found AGPv3 capable device at %d:%d:%d\n", device->bus->number, PCI_FUNC(device->devfn), PCI_SLOT(device->devfn)); } else { - printk (KERN_INFO "AGP: Meh. version %x AGP device found.\n", scratch); + printk (KERN_INFO "AGP: Version %x AGP device found.\n", scratch); } } } @@ -3161,7 +3780,163 @@ (void) pdev; /* unused */ } -#endif /* CONFIG_AGP_AMD_8151 */ +/* NVIDIA x86-64 chipset support */ + + +static struct _nvidia_x86_64_private { + struct pci_dev *dev_1; +} nvidia_x86_64_private; + + +static aper_size_info_32 nvidia_x86_64_sizes[5] = +{ + {512, 131072, 7, 0x00000000 }, + {256, 65536, 6, 0x00000008 }, + {128, 32768, 5, 0x0000000C }, + {64, 16384, 4, 0x0000000E }, + {32, 8192, 3, 0x0000000F } +}; + + +static int nvidia_x86_64_configure(void) +{ + struct pci_dev *dev, *hammer=NULL; + int i, current_size; + u32 tmp, apbase, apbar, aplimit; + unsigned long gatt_bus = virt_to_phys(agp_bridge.gatt_table_real); + + if (!agp_bridge.dev) + return -ENODEV; + + /* configure AGP regs in each x86-64 host bridge */ + pci_for_each_dev(dev) { + if (dev->bus->number==0 && + PCI_FUNC(dev->devfn)==3 && + PCI_SLOT(dev->devfn)>=24 && PCI_SLOT(dev->devfn)<=31) { + agp_bridge.gart_bus_addr = amd_x86_64_configure(dev,gatt_bus); + hammer = dev; + } + } + if (hammer == NULL) + return -ENODEV; + + /* translate x86-64 aperture size to NVIDIA aperture size */ + current_size = amd_x86_64_fetch_size(); + for (i = 0 ; i < agp_bridge.num_aperture_sizes; i++) { + if (nvidia_x86_64_sizes[i].size == current_size) + break; + } + /* if x86-64 size does not match any NVIDIA size, exit here */ + if (i == agp_bridge.num_aperture_sizes) + return -ENODEV; + pci_read_config_dword(nvidia_x86_64_private.dev_1, NVIDIA_X86_64_1_APSIZE, &tmp); + tmp &= ~(0xf); + tmp |= nvidia_x86_64_sizes[i].size_value; + pci_write_config_dword(nvidia_x86_64_private.dev_1, NVIDIA_X86_64_1_APSIZE, tmp); + + /* shadow x86-64 registers into NVIDIA registers */ + pci_read_config_dword (hammer, AMD_X86_64_GARTAPERTUREBASE, &apbase); + /* if x86-64 aperture base is beyond 4G, exit here */ + if ( (apbase & 0x7fff) >> (32 - 25) ) + return -ENODEV; + apbase = (apbase & 0x7fff) << 25; + + pci_read_config_dword(agp_bridge.dev, NVIDIA_X86_64_0_APBASE, &apbar); + apbar &= ~PCI_BASE_ADDRESS_MEM_MASK; + apbar |= apbase; + pci_write_config_dword(agp_bridge.dev, NVIDIA_X86_64_0_APBASE, apbar); + + /* Shadow into secondary device looks dubious, but we keep it for now. + If these two could be dropped then the NForce3 code path could + be just folded into the generic functions above. */ + + aplimit = apbase + (current_size * 1024 * 1024) - 1; + pci_write_config_dword(nvidia_x86_64_private.dev_1, NVIDIA_X86_64_1_APBASE1, apbase); + pci_write_config_dword(nvidia_x86_64_private.dev_1, NVIDIA_X86_64_1_APLIMIT1, aplimit); + pci_write_config_dword(nvidia_x86_64_private.dev_1, NVIDIA_X86_64_1_APBASE2, apbase); + pci_write_config_dword(nvidia_x86_64_private.dev_1, NVIDIA_X86_64_1_APLIMIT2, aplimit); + + /* Original driver updated the IORR here, but AMD documentation + explicitely discourages this for something already covered by the GART. */ + + return 0; +} + + +static void nvidia_x86_64_cleanup(void) +{ + struct pci_dev *dev; + u32 tmp; + + pci_for_each_dev(dev) { + /* disable gart translation */ + if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 && + (PCI_SLOT(dev->devfn) >=24) && (PCI_SLOT(dev->devfn) <=31)) { + + pci_read_config_dword (dev, AMD_X86_64_GARTAPERTURECTL, &tmp); + tmp &= ~(AMD_X86_64_GARTEN); + pci_write_config_dword (dev, AMD_X86_64_GARTAPERTURECTL, tmp); + } + } +} + + +static unsigned long nvidia_x86_64_mask_memory(unsigned long addr, int type) +{ + return addr | agp_bridge.masks[0].mask; +} + + +static gatt_mask nvidia_x86_64_masks[] = +{ + {0x00000001, 0} +}; + + +static int __init nvidia_x86_64_setup (struct pci_dev *pdev) +{ + nvidia_x86_64_private.dev_1 = + pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(11, 0)); + + if (nvidia_x86_64_private.dev_1 == NULL) { + printk(KERN_INFO PFX "agpgart: Detected an NVIDIA " + "nForce3 chipset, but could not find " + "the secondary device.\n"); + agp_bridge.type = NOT_SUPPORTED; + return -ENODEV; + } + + agp_bridge.masks = nvidia_x86_64_masks; + agp_bridge.aperture_sizes = (void *) nvidia_x86_64_sizes; + agp_bridge.size_type = U32_APER_SIZE; + agp_bridge.num_aperture_sizes = 5; + agp_bridge.dev_private_data = NULL; + agp_bridge.needs_scratch_page = FALSE; + agp_bridge.configure = nvidia_x86_64_configure; + agp_bridge.fetch_size = amd_x86_64_fetch_size; + agp_bridge.cleanup = nvidia_x86_64_cleanup; + agp_bridge.tlb_flush = amd_x86_64_tlbflush; + agp_bridge.mask_memory = nvidia_x86_64_mask_memory; + agp_bridge.agp_enable = agp_x86_64_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 = x86_64_insert_memory; + agp_bridge.remove_memory = agp_generic_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; + + (void) pdev; /* unused */ +} + +#endif /* CONFIG_AGP_AMD_K8 */ #ifdef CONFIG_AGP_ALI @@ -3559,8 +4334,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 +4363,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,12 +4778,340 @@ #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 err; + int i, 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); + err = nvidia_init_iorr(apbase, current_size->size * 1024 * 1024); + if (err) + return err; + + /* 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 #define log2(x) ffz(~(x)) #endif +#define HP_ZX1_IOC_OFFSET 0x1000 /* ACPI reports SBA, we want IOC */ + #define HP_ZX1_IOVA_BASE GB(1UL) #define HP_ZX1_IOVA_SIZE GB(1UL) #define HP_ZX1_GART_SIZE (HP_ZX1_IOVA_SIZE / 2) @@ -4018,19 +5121,16 @@ #define HP_ZX1_IOVA_TO_PDIR(va) ((va - hp_private.iova_base) >> \ hp_private.io_tlb_shift) +static int hp_zx1_gart_found; + static aper_size_info_fixed hp_zx1_sizes[] = { {0, 0, 0}, /* filled in by hp_zx1_fetch_size() */ }; -static gatt_mask hp_zx1_masks[] = -{ - {HP_ZX1_PDIR_VALID_BIT, 0} -}; - static struct _hp_private { - struct pci_dev *ioc; - volatile u8 *registers; + volatile u8 *ioc_regs; + volatile u8 *lba_regs; u64 *io_pdir; // PDIR for entire IOVA u64 *gatt; // PDIR just for GART (subset of above) u64 gatt_entries; @@ -4057,7 +5157,7 @@ * - IOVA space is 1Gb in size * - first 512Mb is IOMMU, second 512Mb is GART */ - hp->io_tlb_ps = INREG64(hp->registers, HP_ZX1_TCNFG); + hp->io_tlb_ps = INREG64(hp->ioc_regs, HP_ZX1_TCNFG); switch (hp->io_tlb_ps) { case 0: hp->io_tlb_shift = 12; break; case 1: hp->io_tlb_shift = 13; break; @@ -4073,297 +5173,752 @@ hp->io_page_size = 1 << hp->io_tlb_shift; hp->io_pages_per_kpage = PAGE_SIZE / hp->io_page_size; - hp->iova_base = INREG64(hp->registers, HP_ZX1_IBASE) & ~0x1; - hp->gart_base = hp->iova_base + HP_ZX1_IOVA_SIZE - HP_ZX1_GART_SIZE; + hp->iova_base = INREG64(hp->ioc_regs, HP_ZX1_IBASE) & ~0x1; + hp->gart_base = hp->iova_base + HP_ZX1_IOVA_SIZE - HP_ZX1_GART_SIZE; + + hp->gart_size = HP_ZX1_GART_SIZE; + hp->gatt_entries = hp->gart_size / hp->io_page_size; + + hp->io_pdir = phys_to_virt(INREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE)); + hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)]; + + if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) { + hp->gatt = 0; + hp->gatt_entries = 0; + printk(KERN_ERR PFX "No reserved IO PDIR entry found; " + "GART disabled\n"); + return -ENODEV; + } + + return 0; +} + +static int __init hp_zx1_ioc_owner(void) +{ + struct _hp_private *hp = &hp_private; + + printk(KERN_INFO PFX "HP ZX1 IOC: IOPDIR dedicated to GART\n"); + + /* + * Select an IOV page size no larger than system page size. + */ + if (PAGE_SIZE >= KB(64)) { + hp->io_tlb_shift = 16; + hp->io_tlb_ps = 3; + } else if (PAGE_SIZE >= KB(16)) { + hp->io_tlb_shift = 14; + hp->io_tlb_ps = 2; + } else if (PAGE_SIZE >= KB(8)) { + hp->io_tlb_shift = 13; + hp->io_tlb_ps = 1; + } else { + hp->io_tlb_shift = 12; + hp->io_tlb_ps = 0; + } + hp->io_page_size = 1 << hp->io_tlb_shift; + hp->io_pages_per_kpage = PAGE_SIZE / hp->io_page_size; + + hp->iova_base = HP_ZX1_IOVA_BASE; + hp->gart_size = HP_ZX1_GART_SIZE; + hp->gart_base = hp->iova_base + HP_ZX1_IOVA_SIZE - hp->gart_size; + + hp->gatt_entries = hp->gart_size / hp->io_page_size; + hp->io_pdir_size = (HP_ZX1_IOVA_SIZE / hp->io_page_size) * sizeof(u64); + + return 0; +} + +static int __init hp_zx1_ioc_init(u64 ioc_hpa, u64 lba_hpa) +{ + struct _hp_private *hp = &hp_private; + + hp->ioc_regs = ioremap(ioc_hpa, 1024); + hp->lba_regs = ioremap(lba_hpa, 256); + + /* + * If the IOTLB is currently disabled, we can take it over. + * Otherwise, we have to share with sba_iommu. + */ + hp->io_pdir_owner = (INREG64(hp->ioc_regs, HP_ZX1_IBASE) & 0x1) == 0; + + if (hp->io_pdir_owner) + return hp_zx1_ioc_owner(); + + return hp_zx1_ioc_shared(); +} + +static int hp_zx1_fetch_size(void) +{ + int size; + + size = hp_private.gart_size / MB(1); + hp_zx1_sizes[0].size = size; + agp_bridge.current_size = (void *) &hp_zx1_sizes[0]; + return size; +} + +static int hp_zx1_configure(void) +{ + struct _hp_private *hp = &hp_private; + + agp_bridge.gart_bus_addr = hp->gart_base; + agp_bridge.mode = INREG32(hp->lba_regs, HP_ZX1_AGP_STATUS); + + if (hp->io_pdir_owner) { + OUTREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE, + virt_to_phys(hp->io_pdir)); + OUTREG64(hp->ioc_regs, HP_ZX1_TCNFG, hp->io_tlb_ps); + OUTREG64(hp->ioc_regs, HP_ZX1_IMASK, ~(HP_ZX1_IOVA_SIZE - 1)); + OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, hp->iova_base | 0x1); + OUTREG64(hp->ioc_regs, HP_ZX1_PCOM, + hp->iova_base | log2(HP_ZX1_IOVA_SIZE)); + INREG64(hp->ioc_regs, HP_ZX1_PCOM); + } + + return 0; +} + +static void hp_zx1_cleanup(void) +{ + struct _hp_private *hp = &hp_private; + + if (hp->io_pdir_owner) + OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, 0); + iounmap((void *) hp->ioc_regs); + iounmap((void *) hp->lba_regs); +} + +static void hp_zx1_tlbflush(agp_memory * mem) +{ + struct _hp_private *hp = &hp_private; + + OUTREG64(hp->ioc_regs, HP_ZX1_PCOM, + hp->gart_base | log2(hp->gart_size)); + INREG64(hp->ioc_regs, HP_ZX1_PCOM); +} + +static int hp_zx1_create_gatt_table(void) +{ + struct _hp_private *hp = &hp_private; + int i; + + if (hp->io_pdir_owner) { + hp->io_pdir = (u64 *) __get_free_pages(GFP_KERNEL, + get_order(hp->io_pdir_size)); + if (!hp->io_pdir) { + printk(KERN_ERR PFX "Couldn't allocate contiguous " + "memory for I/O PDIR\n"); + hp->gatt = 0; + hp->gatt_entries = 0; + return -ENOMEM; + } + memset(hp->io_pdir, 0, hp->io_pdir_size); + + hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)]; + } + + for (i = 0; i < hp->gatt_entries; i++) { + hp->gatt[i] = (unsigned long) agp_bridge.scratch_page; + } + + return 0; +} + +static int hp_zx1_free_gatt_table(void) +{ + struct _hp_private *hp = &hp_private; + + if (hp->io_pdir_owner) + free_pages((unsigned long) hp->io_pdir, + get_order(hp->io_pdir_size)); + else + hp->gatt[0] = HP_ZX1_SBA_IOMMU_COOKIE; + return 0; +} + +static int hp_zx1_insert_memory(agp_memory * mem, off_t pg_start, int type) +{ + struct _hp_private *hp = &hp_private; + int i, k; + off_t j, io_pg_start; + int io_pg_count; + + if (type != 0 || mem->type != 0) { + return -EINVAL; + } + + io_pg_start = hp->io_pages_per_kpage * pg_start; + io_pg_count = hp->io_pages_per_kpage * mem->page_count; + if ((io_pg_start + io_pg_count) > hp->gatt_entries) { + return -EINVAL; + } + + j = io_pg_start; + while (j < (io_pg_start + io_pg_count)) { + if (hp->gatt[j]) { + return -EBUSY; + } + j++; + } + + for (i = 0, j = io_pg_start; i < mem->page_count; i++) { + unsigned long paddr; + + paddr = mem->memory[i]; + for (k = 0; + k < hp->io_pages_per_kpage; + k++, j++, paddr += hp->io_page_size) { + hp->gatt[j] = agp_bridge.mask_memory(paddr, type); + } + } + + agp_bridge.tlb_flush(mem); + return 0; +} + +static int hp_zx1_remove_memory(agp_memory * mem, off_t pg_start, int type) +{ + struct _hp_private *hp = &hp_private; + int i, io_pg_start, io_pg_count; + + if (type != 0 || mem->type != 0) { + return -EINVAL; + } + + io_pg_start = hp->io_pages_per_kpage * pg_start; + io_pg_count = hp->io_pages_per_kpage * mem->page_count; + for (i = io_pg_start; i < io_pg_count + io_pg_start; i++) { + hp->gatt[i] = agp_bridge.scratch_page; + } + + agp_bridge.tlb_flush(mem); + return 0; +} + +static unsigned long hp_zx1_mask_memory(unsigned long addr, int type) +{ + return HP_ZX1_PDIR_VALID_BIT | addr; +} + +static void hp_zx1_agp_enable(u32 mode) +{ + struct _hp_private *hp = &hp_private; + u32 command; + + command = INREG32(hp->lba_regs, HP_ZX1_AGP_STATUS); + + command = agp_collect_device_status(mode, command); + command |= 0x00000100; + + OUTREG32(hp->lba_regs, HP_ZX1_AGP_COMMAND, command); + + agp_device_command(command, 0); +} + +static int __init hp_zx1_setup(u64 ioc_hpa, u64 lba_hpa) +{ + agp_bridge.dev_private_data = NULL; + agp_bridge.size_type = FIXED_APER_SIZE; + agp_bridge.needs_scratch_page = FALSE; + agp_bridge.configure = hp_zx1_configure; + agp_bridge.fetch_size = hp_zx1_fetch_size; + agp_bridge.cleanup = hp_zx1_cleanup; + agp_bridge.tlb_flush = hp_zx1_tlbflush; + agp_bridge.mask_memory = hp_zx1_mask_memory; + agp_bridge.agp_enable = hp_zx1_agp_enable; + agp_bridge.cache_flush = global_cache_flush; + agp_bridge.create_gatt_table = hp_zx1_create_gatt_table; + agp_bridge.free_gatt_table = hp_zx1_free_gatt_table; + agp_bridge.insert_memory = hp_zx1_insert_memory; + agp_bridge.remove_memory = hp_zx1_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.cant_use_aperture = 1; + agp_bridge.type = HP_ZX1; + + fake_bridge_dev.vendor = PCI_VENDOR_ID_HP; + fake_bridge_dev.device = PCI_DEVICE_ID_HP_PCIX_LBA; + + return hp_zx1_ioc_init(ioc_hpa, lba_hpa); +} + +static acpi_status __init hp_zx1_gart_probe(acpi_handle obj, u32 depth, void *context, void **ret) +{ + acpi_handle handle, parent; + acpi_status status; + struct acpi_buffer buffer; + struct acpi_device_info *info; + u64 lba_hpa, sba_hpa, length; + int match; + + status = acpi_hp_csr_space(obj, &lba_hpa, &length); + if (ACPI_FAILURE(status)) + return AE_OK; + + /* Look for an enclosing IOC scope and find its CSR space */ + handle = obj; + do { + buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; + status = acpi_get_object_info(handle, &buffer); + if (ACPI_SUCCESS(status)) { + /* TBD check _CID also */ + info = buffer.pointer; + info->hardware_id.value[sizeof(info->hardware_id)-1] = '\0'; + match = (strcmp(info->hardware_id.value, "HWP0001") == 0); + ACPI_MEM_FREE(info); + if (match) { + status = acpi_hp_csr_space(handle, &sba_hpa, &length); + if (ACPI_SUCCESS(status)) + break; + else { + printk(KERN_ERR PFX "Detected HP ZX1 " + "AGP LBA but no IOC.\n"); + return AE_OK; + } + } + } + + status = acpi_get_parent(handle, &parent); + handle = parent; + } while (ACPI_SUCCESS(status)); + + if (hp_zx1_setup(sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa)) + return AE_OK; + + printk(KERN_INFO PFX "Detected HP ZX1 %s AGP chipset (ioc=%lx, lba=%lx)\n", + (char *) context, sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa); + + hp_zx1_gart_found = 1; + return AE_CTRL_TERMINATE; +} + +static int __init +hp_zx1_gart_init(void) +{ + acpi_get_devices("HWP0003", hp_zx1_gart_probe, "HWP0003", NULL); + if (hp_zx1_gart_found) + return 0; + + acpi_get_devices("HWP0007", hp_zx1_gart_probe, "HWP0007", NULL); + if (hp_zx1_gart_found) + return 0; - hp->gart_size = HP_ZX1_GART_SIZE; - hp->gatt_entries = hp->gart_size / hp->io_page_size; + return -ENODEV; +} - hp->io_pdir = phys_to_virt(INREG64(hp->registers, HP_ZX1_PDIR_BASE)); - hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)]; +#endif /* CONFIG_AGP_HP_ZX1 */ - if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) { - hp->gatt = 0; - hp->gatt_entries = 0; - printk(KERN_ERR PFX "No reserved IO PDIR entry found; " - "GART disabled\n"); - return -ENODEV; - } +#ifdef CONFIG_AGP_ATI +static aper_size_info_lvl2 ati_generic_sizes[7] = +{ + {2048, 524288, 0x0000000c}, + {1024, 262144, 0x0000000a}, + {512, 131072, 0x00000008}, + {256, 65536, 0x00000006}, + {128, 32768, 0x00000004}, + {64, 16384, 0x00000002}, + {32, 8192, 0x00000000} +}; - return 0; -} +static gatt_mask ati_generic_masks[] = +{ + {0x00000001, 0} +}; + +typedef struct _ati_page_map { + unsigned long *real; + unsigned long *remapped; +} ati_page_map; -static int __init hp_zx1_ioc_owner(u8 ioc_rev) +static struct _ati_generic_private { + volatile u8 *registers; + ati_page_map **gatt_pages; + int num_tables; +} ati_generic_private; + +static int ati_create_page_map(ati_page_map *page_map) { - struct _hp_private *hp = &hp_private; + int i, err = 0; - printk(KERN_INFO PFX "HP ZX1 IOC: IOPDIR dedicated to GART\n"); + page_map->real = (unsigned long *) __get_free_page(GFP_KERNEL); + if (page_map->real == NULL) + return -ENOMEM; + SetPageReserved(virt_to_page(page_map->real)); /* - * Select an IOV page size no larger than system page size. + * fredi - WARNING: added looking at the changes during + * 2.4.20. I dont know if it's needed though. */ - if (PAGE_SIZE >= KB(64)) { - hp->io_tlb_shift = 16; - hp->io_tlb_ps = 3; - } else if (PAGE_SIZE >= KB(16)) { - hp->io_tlb_shift = 14; - hp->io_tlb_ps = 2; - } else if (PAGE_SIZE >= KB(8)) { - hp->io_tlb_shift = 13; - hp->io_tlb_ps = 1; - } else { - hp->io_tlb_shift = 12; - hp->io_tlb_ps = 0; +#ifdef CONFIG_X86 + err = change_page_attr(virt_to_page(page_map->real), 1, PAGE_KERNEL_NOCACHE); +#endif + CACHE_FLUSH(); + page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), + PAGE_SIZE); + if (page_map->remapped == NULL || err) { + ClearPageReserved(virt_to_page(page_map->real)); + free_page((unsigned long) page_map->real); + page_map->real = NULL; + return -ENOMEM; } - hp->io_page_size = 1 << hp->io_tlb_shift; - hp->io_pages_per_kpage = PAGE_SIZE / hp->io_page_size; - - hp->iova_base = HP_ZX1_IOVA_BASE; - hp->gart_size = HP_ZX1_GART_SIZE; - hp->gart_base = hp->iova_base + HP_ZX1_IOVA_SIZE - hp->gart_size; + CACHE_FLUSH(); - hp->gatt_entries = hp->gart_size / hp->io_page_size; - hp->io_pdir_size = (HP_ZX1_IOVA_SIZE / hp->io_page_size) * sizeof(u64); + for(i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) + page_map->remapped[i] = agp_bridge.scratch_page; return 0; } -static int __init hp_zx1_ioc_init(void) +static void ati_free_page_map(ati_page_map *page_map) +{ + /* + * fredi - WARNING: added looking at the changes during + * 2.4.20. I dont know if it's needed though. + */ +#ifdef CONFIG_X86 + change_page_attr(virt_to_page(page_map->real), 1, PAGE_KERNEL); +#endif + iounmap(page_map->remapped); + ClearPageReserved(virt_to_page(page_map->real)); + free_page((unsigned long) page_map->real); +} + +static void ati_free_gatt_pages(void) { - struct _hp_private *hp = &hp_private; - struct pci_dev *ioc; int i; - u8 ioc_rev; + ati_page_map **tables; + ati_page_map *entry; - ioc = pci_find_device(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_ZX1_IOC, NULL); - if (!ioc) { - printk(KERN_ERR PFX "Detected HP ZX1 AGP bridge but no IOC\n"); - return -ENODEV; + tables = ati_generic_private.gatt_pages; + for(i = 0; i < ati_generic_private.num_tables; i++) { + entry = tables[i]; + if (entry != NULL) { + if (entry->real != NULL) + ati_free_page_map(entry); + kfree(entry); + } } - hp->ioc = ioc; + kfree(tables); +} + +static int ati_create_gatt_pages(int nr_tables) +{ + ati_page_map **tables; + ati_page_map *entry; + int retval = 0; + int i; - pci_read_config_byte(ioc, PCI_REVISION_ID, &ioc_rev); + tables = kmalloc((nr_tables + 1) * sizeof(ati_page_map *), + GFP_KERNEL); + if (tables == NULL) + return -ENOMEM; - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - if (pci_resource_flags(ioc, i) == IORESOURCE_MEM) { - hp->registers = (u8 *) ioremap(pci_resource_start(ioc, - i), - pci_resource_len(ioc, i)); + memset(tables, 0, sizeof(ati_page_map *) * (nr_tables + 1)); + for (i = 0; i < nr_tables; i++) { + entry = kmalloc(sizeof(ati_page_map), GFP_KERNEL); + if (entry == NULL) { + retval = -ENOMEM; break; } + memset(entry, 0, sizeof(ati_page_map)); + tables[i] = entry; + retval = ati_create_page_map(entry); + if (retval != 0) break; } - if (!hp->registers) { - printk(KERN_ERR PFX "Detected HP ZX1 AGP bridge but no CSRs\n"); + ati_generic_private.num_tables = nr_tables; + ati_generic_private.gatt_pages = tables; - return -ENODEV; - } + if (retval != 0) ati_free_gatt_pages(); - /* - * If the IOTLB is currently disabled, we can take it over. - * Otherwise, we have to share with sba_iommu. - */ - hp->io_pdir_owner = (INREG64(hp->registers, HP_ZX1_IBASE) & 0x1) == 0; + return retval; +} - if (hp->io_pdir_owner) - return hp_zx1_ioc_owner(ioc_rev); +/* + *Since we don't need contigious memory we just try + * to get the gatt table once + */ - return hp_zx1_ioc_shared(); -} +#define GET_PAGE_DIR_OFF(addr) (addr >> 22) +#define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \ + GET_PAGE_DIR_OFF(agp_bridge.gart_bus_addr)) +#define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12) +#undef GET_GATT +#define GET_GATT(addr) (ati_generic_private.gatt_pages[\ + GET_PAGE_DIR_IDX(addr)]->remapped) -static int hp_zx1_fetch_size(void) +static int ati_insert_memory(agp_memory * mem, + off_t pg_start, int type) { - int size; + int i, j, num_entries; + unsigned long *cur_gatt; + unsigned long addr; - size = hp_private.gart_size / MB(1); - hp_zx1_sizes[0].size = size; - agp_bridge.current_size = (void *) &hp_zx1_sizes[0]; - return size; -} + num_entries = A_SIZE_LVL2(agp_bridge.current_size)->num_entries; -static int hp_zx1_configure(void) -{ - struct _hp_private *hp = &hp_private; + if (type != 0 || mem->type != 0) + return -EINVAL; - agp_bridge.gart_bus_addr = hp->gart_base; - agp_bridge.capndx = pci_find_capability(agp_bridge.dev, PCI_CAP_ID_AGP); - pci_read_config_dword(agp_bridge.dev, - agp_bridge.capndx + PCI_AGP_STATUS, &agp_bridge.mode); + if ((pg_start + mem->page_count) > num_entries) + return -EINVAL; - if (hp->io_pdir_owner) { - OUTREG64(hp->registers, HP_ZX1_PDIR_BASE, - virt_to_phys(hp->io_pdir)); - OUTREG64(hp->registers, HP_ZX1_TCNFG, hp->io_tlb_ps); - OUTREG64(hp->registers, HP_ZX1_IMASK, ~(HP_ZX1_IOVA_SIZE - 1)); - OUTREG64(hp->registers, HP_ZX1_IBASE, hp->iova_base | 0x1); - OUTREG64(hp->registers, HP_ZX1_PCOM, - hp->iova_base | log2(HP_ZX1_IOVA_SIZE)); - INREG64(hp->registers, HP_ZX1_PCOM); + j = pg_start; + while (j < (pg_start + mem->page_count)) { + addr = (j * PAGE_SIZE) + agp_bridge.gart_bus_addr; + cur_gatt = GET_GATT(addr); + if (!PGE_EMPTY(cur_gatt[GET_GATT_OFF(addr)])) + return -EBUSY; + j++; } + if (mem->is_flushed == FALSE) { + CACHE_FLUSH(); + mem->is_flushed = TRUE; + } + + for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { + addr = (j * PAGE_SIZE) + agp_bridge.gart_bus_addr; + cur_gatt = GET_GATT(addr); + cur_gatt[GET_GATT_OFF(addr)] = + agp_bridge.mask_memory(mem->memory[i], mem->type); + } + agp_bridge.tlb_flush(mem); return 0; } -static void hp_zx1_cleanup(void) +static int ati_remove_memory(agp_memory * mem, off_t pg_start, + int type) { - struct _hp_private *hp = &hp_private; - - if (hp->io_pdir_owner) - OUTREG64(hp->registers, HP_ZX1_IBASE, 0); - iounmap((void *) hp->registers); -} + int i; + unsigned long *cur_gatt; + unsigned long addr; -static void hp_zx1_tlbflush(agp_memory * mem) -{ - struct _hp_private *hp = &hp_private; + if (type != 0 || mem->type != 0) { + return -EINVAL; + } + for (i = pg_start; i < (mem->page_count + pg_start); i++) { + addr = (i * PAGE_SIZE) + agp_bridge.gart_bus_addr; + cur_gatt = GET_GATT(addr); + cur_gatt[GET_GATT_OFF(addr)] = + (unsigned long) agp_bridge.scratch_page; + } - OUTREG64(hp->registers, HP_ZX1_PCOM, - hp->gart_base | log2(hp->gart_size)); - INREG64(hp->registers, HP_ZX1_PCOM); + agp_bridge.tlb_flush(mem); + return 0; } -static int hp_zx1_create_gatt_table(void) +static int ati_create_gatt_table(void) { - struct _hp_private *hp = &hp_private; + aper_size_info_lvl2 *value; + ati_page_map page_dir; + unsigned long addr; + int retval; + u32 temp; int i; + aper_size_info_lvl2 *current_size; - if (hp->io_pdir_owner) { - hp->io_pdir = (u64 *) __get_free_pages(GFP_KERNEL, - get_order(hp->io_pdir_size)); - if (!hp->io_pdir) { - printk(KERN_ERR PFX "Couldn't allocate contiguous " - "memory for I/O PDIR\n"); - hp->gatt = 0; - hp->gatt_entries = 0; - return -ENOMEM; - } - memset(hp->io_pdir, 0, hp->io_pdir_size); - - hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)]; - } + value = A_SIZE_LVL2(agp_bridge.current_size); + retval = ati_create_page_map(&page_dir); + if (retval != 0) + return retval; - for (i = 0; i < hp->gatt_entries; i++) { - hp->gatt[i] = (unsigned long) agp_bridge.scratch_page; + retval = ati_create_gatt_pages(value->num_entries / 1024); + if (retval != 0) { + ati_free_page_map(&page_dir); + return retval; } - return 0; -} - -static int hp_zx1_free_gatt_table(void) -{ - struct _hp_private *hp = &hp_private; - - if (hp->io_pdir_owner) - free_pages((unsigned long) hp->io_pdir, - get_order(hp->io_pdir_size)); - else - hp->gatt[0] = HP_ZX1_SBA_IOMMU_COOKIE; - return 0; -} + 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); -static int hp_zx1_insert_memory(agp_memory * mem, off_t pg_start, int type) -{ - struct _hp_private *hp = &hp_private; - int i, k; - off_t j, io_pg_start; - int io_pg_count; + /* Write out the size register */ + current_size = A_SIZE_LVL2(agp_bridge.current_size); - if (type != 0 || mem->type != 0) { - return -EINVAL; + if ((agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS100) || + (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200) || + (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200_B) || + (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS250)) { + pci_read_config_dword(agp_bridge.dev, ATI_RS100_APSIZE, &temp); + temp = (((temp & ~(0x0000000e)) | current_size->size_value) + | 0x00000001); + pci_write_config_dword(agp_bridge.dev, ATI_RS100_APSIZE, temp); + pci_read_config_dword(agp_bridge.dev, ATI_RS100_APSIZE, &temp); + } else { + pci_read_config_dword(agp_bridge.dev, ATI_RS300_APSIZE, &temp); + temp = (((temp & ~(0x0000000e)) | current_size->size_value) + | 0x00000001); + pci_write_config_dword(agp_bridge.dev, ATI_RS300_APSIZE, temp); + pci_read_config_dword(agp_bridge.dev, ATI_RS300_APSIZE, &temp); } - io_pg_start = hp->io_pages_per_kpage * pg_start; - io_pg_count = hp->io_pages_per_kpage * mem->page_count; - if ((io_pg_start + io_pg_count) > hp->gatt_entries) { - return -EINVAL; + /* + * Get the address for the gart region. + * This is a bus address even on the alpha, b/c its + * used to program the agp master not the cpu + */ + pci_read_config_dword(agp_bridge.dev, ATI_APBASE, &temp); + addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + agp_bridge.gart_bus_addr = addr; + + /* Calculate the agp offset */ + for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { + page_dir.remapped[GET_PAGE_DIR_OFF(addr)] = + virt_to_bus(ati_generic_private.gatt_pages[i]->real); + page_dir.remapped[GET_PAGE_DIR_OFF(addr)] |= 0x00000001; } - j = io_pg_start; - while (j < (io_pg_start + io_pg_count)) { - if (hp->gatt[j]) { - return -EBUSY; - } - j++; - } + return 0; +} - if (mem->is_flushed == FALSE) { - CACHE_FLUSH(); - mem->is_flushed = TRUE; +static int ati_free_gatt_table(void) +{ + ati_page_map page_dir; + + page_dir.real = (unsigned long *)agp_bridge.gatt_table_real; + page_dir.remapped = (unsigned long *)agp_bridge.gatt_table; + + ati_free_gatt_pages(); + ati_free_page_map(&page_dir); + return 0; +} + +static int ati_fetch_size(void) +{ + int i; + u32 temp; + aper_size_info_lvl2 *values; + + if ((agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS100) || + (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200) || + (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200_B) || + (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS250)) { + pci_read_config_dword(agp_bridge.dev, ATI_RS100_APSIZE, &temp); + } else { + pci_read_config_dword(agp_bridge.dev, ATI_RS300_APSIZE, &temp); } - for (i = 0, j = io_pg_start; i < mem->page_count; i++) { - unsigned long paddr; + temp = (temp & 0x0000000e); + values = A_SIZE_LVL2(agp_bridge.aperture_sizes); + for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { + if (temp == values[i].size_value) { + agp_bridge.previous_size = + agp_bridge.current_size = (void *) (values + i); - paddr = mem->memory[i]; - for (k = 0; - k < hp->io_pages_per_kpage; - k++, j++, paddr += hp->io_page_size) { - hp->gatt[j] = agp_bridge.mask_memory(paddr, type); + agp_bridge.aperture_size_idx = i; + return values[i].size; } } - agp_bridge.tlb_flush(mem); return 0; } -static int hp_zx1_remove_memory(agp_memory * mem, off_t pg_start, int type) +static int ati_configure(void) { - struct _hp_private *hp = &hp_private; - int i, io_pg_start, io_pg_count; + u32 temp; - if (type != 0 || mem->type != 0) { - return -EINVAL; + /* Get the memory mapped registers */ + pci_read_config_dword(agp_bridge.dev, ATI_GART_MMBASE_ADDR, &temp); + temp = (temp & 0xfffff000); + ati_generic_private.registers = (volatile u8 *) ioremap(temp, 4096); + + if ((agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS100) || + (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200) || + (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200_B) || + (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS250)) { + pci_write_config_dword(agp_bridge.dev, ATI_RS100_IG_AGPMODE, 0x20000); + } else { + pci_write_config_dword(agp_bridge.dev, ATI_RS300_IG_AGPMODE, 0x20000); } - io_pg_start = hp->io_pages_per_kpage * pg_start; - io_pg_count = hp->io_pages_per_kpage * mem->page_count; - for (i = io_pg_start; i < io_pg_count + io_pg_start; i++) { - hp->gatt[i] = agp_bridge.scratch_page; - } + /* address to map too */ + /* + pci_read_config_dword(agp_bridge.dev, ATI_APBASE, &temp); + agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + printk(KERN_INFO "IGP320 gart_bus_addr: %x\n", agp_bridge.gart_bus_addr); + */ + OUTREG32(ati_generic_private.registers, ATI_GART_FEATURE_ID, 0x60000); + + /* SIGNALED_SYSTEM_ERROR @ NB_STATUS */ + pci_read_config_dword(agp_bridge.dev, 4, &temp); + pci_write_config_dword(agp_bridge.dev, 4, temp | (1<<14)); - agp_bridge.tlb_flush(mem); + /* Write out the address of the gatt table */ + OUTREG32(ati_generic_private.registers, ATI_GART_BASE, + agp_bridge.gatt_bus_addr); + + /* Flush the tlb */ + OUTREG32(ati_generic_private.registers, ATI_GART_CACHE_CNTRL, 1); return 0; } -static unsigned long hp_zx1_mask_memory(unsigned long addr, int type) +static void ati_cleanup(void) { - return HP_ZX1_PDIR_VALID_BIT | addr; + aper_size_info_lvl2 *previous_size; + u32 temp; + + previous_size = A_SIZE_LVL2(agp_bridge.previous_size); + + /* Write back the previous size and disable gart translation */ + if ((agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS100) || + (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200) || + (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200_B) || + (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS250)) { + pci_read_config_dword(agp_bridge.dev, ATI_RS100_APSIZE, &temp); + temp = ((temp & ~(0x0000000f)) | previous_size->size_value); + pci_write_config_dword(agp_bridge.dev, ATI_RS100_APSIZE, temp); + } else { + pci_read_config_dword(agp_bridge.dev, ATI_RS300_APSIZE, &temp); + temp = ((temp & ~(0x0000000f)) | previous_size->size_value); + pci_write_config_dword(agp_bridge.dev, ATI_RS300_APSIZE, temp); + } + iounmap((void *) ati_generic_private.registers); } -static unsigned long hp_zx1_unmask_memory(unsigned long addr) +static void ati_tlbflush(agp_memory * mem) { - return addr & ~(HP_ZX1_PDIR_VALID_BIT); + OUTREG32(ati_generic_private.registers, ATI_GART_CACHE_CNTRL, 1); } -static int __init hp_zx1_setup (struct pci_dev *pdev) +static unsigned long ati_mask_memory(unsigned long addr, int type) { - agp_bridge.masks = hp_zx1_masks; - agp_bridge.dev_private_data = NULL; - agp_bridge.size_type = FIXED_APER_SIZE; + /* Memory type is ignored */ + return addr | agp_bridge.masks[0].mask; +} + +static int __init ati_generic_setup (struct pci_dev *pdev) +{ + agp_bridge.masks = ati_generic_masks; + agp_bridge.aperture_sizes = (void *) ati_generic_sizes; + agp_bridge.size_type = LVL2_APER_SIZE; + agp_bridge.num_aperture_sizes = 7; + agp_bridge.dev_private_data = (void *) &ati_generic_private; agp_bridge.needs_scratch_page = FALSE; - agp_bridge.configure = hp_zx1_configure; - agp_bridge.fetch_size = hp_zx1_fetch_size; - agp_bridge.cleanup = hp_zx1_cleanup; - agp_bridge.tlb_flush = hp_zx1_tlbflush; - agp_bridge.mask_memory = hp_zx1_mask_memory; - agp_bridge.unmask_memory = hp_zx1_unmask_memory; + agp_bridge.configure = ati_configure; + agp_bridge.fetch_size = ati_fetch_size; + agp_bridge.cleanup = ati_cleanup; + agp_bridge.tlb_flush = ati_tlbflush; + agp_bridge.mask_memory = ati_mask_memory; agp_bridge.agp_enable = agp_generic_agp_enable; agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = hp_zx1_create_gatt_table; - agp_bridge.free_gatt_table = hp_zx1_free_gatt_table; - agp_bridge.insert_memory = hp_zx1_insert_memory; - agp_bridge.remove_memory = hp_zx1_remove_memory; + agp_bridge.create_gatt_table = ati_create_gatt_table; + agp_bridge.free_gatt_table = ati_free_gatt_table; + agp_bridge.insert_memory = ati_insert_memory; + agp_bridge.remove_memory = ati_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.cant_use_aperture = 1; + agp_bridge.suspend = agp_generic_suspend; + agp_bridge.resume = agp_generic_resume; + agp_bridge.cant_use_aperture = 0; - return hp_zx1_ioc_init(); + return 0; (void) pdev; /* unused */ } - -#endif /* CONFIG_AGP_HP_ZX1 */ +#endif /* CONFIG_AGP_ATI */ /* per-chipset initialization data. * note -- all chipsets for a single vendor MUST be grouped together @@ -4459,6 +6014,20 @@ "AMD", "761", amd_irongate_setup }, +#endif +#ifdef CONFIG_AGP_AMD_K8 + { PCI_DEVICE_ID_AMD_8151_0, + PCI_VENDOR_ID_AMD, + AMD_8151, + "AMD", + "On-CPU GART", + amd_8151_setup }, + + /* Note: when adding more PCI-IDs for 8151 compatible bridges + add them to the end of their vendor lists, not here. + This list has to be ordered by vendor. */ +#endif /* CONFIG_AGP_AMD */ +#ifdef CONFIG_AGP_AMD { 0, PCI_VENDOR_ID_AMD, AMD_GENERIC, @@ -4467,15 +6036,6 @@ amd_irongate_setup }, #endif /* CONFIG_AGP_AMD */ -#ifdef CONFIG_AGP_AMD_8151 - { PCI_DEVICE_ID_AMD_8151_0, - PCI_VENDOR_ID_AMD, - AMD_8151, - "AMD", - "8151", - amd_8151_setup }, -#endif /* CONFIG_AGP_AMD */ - #ifdef CONFIG_AGP_INTEL { PCI_DEVICE_ID_INTEL_82443LX_0, PCI_VENDOR_ID_INTEL, @@ -4516,15 +6076,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, @@ -4549,6 +6132,18 @@ "Intel", "i860", intel_860_setup }, + { PCI_DEVICE_ID_INTEL_7205_0, + PCI_VENDOR_ID_INTEL, + INTEL_I7205, + "Intel", + "i7205", + intel_7505_setup }, + { PCI_DEVICE_ID_INTEL_7505_0, + PCI_VENDOR_ID_INTEL, + INTEL_I7505, + "Intel", + "i7505", + intel_7505_setup }, { 0, PCI_VENDOR_ID_INTEL, INTEL_GENERIC, @@ -4558,6 +6153,15 @@ #endif /* CONFIG_AGP_INTEL */ +#ifdef CONFIG_AGP_I460 + { PCI_DEVICE_ID_INTEL_460GX, + PCI_VENDOR_ID_INTEL, + INTEL_460GX, + "Intel", + "460GX", + intel_i460_setup }, +#endif + #ifdef CONFIG_AGP_SIS { PCI_DEVICE_ID_SI_740, PCI_VENDOR_ID_SI, @@ -4565,6 +6169,12 @@ "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, @@ -4583,6 +6193,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 +6211,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, @@ -4631,6 +6253,16 @@ "SiS", "550", sis_generic_setup }, +#endif +#ifdef CONFIG_AGP_AMD_K8 + { PCI_DEVICE_ID_SI_755, + PCI_VENDOR_ID_SI, + AMD_8151, + "AMD", + "On-CPU GART", + amd_8151_setup }, +#endif +#ifdef CONFIG_AGP_SIS { 0, PCI_VENDOR_ID_SI, SIS_GENERIC, @@ -4658,6 +6290,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,18 +6320,54 @@ "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_CLE266, PCI_VENDOR_ID_VIA, - VIA_APOLLO_P4X400, + VIA_CLE266, "Via", - "Apollo P4X400", + "CLE266", via_generic_setup }, + { PCI_DEVICE_ID_VIA_P4M266, + PCI_VENDOR_ID_VIA, + VIA_APOLLO_P4M266, + "Via", + "Apollo P4M266", + via_generic_setup }, +#endif +#ifdef CONFIG_AGP_AMD_K8 + { PCI_DEVICE_ID_VIA_8380_0, + PCI_VENDOR_ID_VIA, + AMD_8151, + "AMD", + "On-CPU GART", + amd_8151_setup }, + + /* VIA K8T800 */ + { PCI_DEVICE_ID_VIA_8385_0, + PCI_VENDOR_ID_VIA, + AMD_8151, + "AMD", + "On-CPU GART", + amd_8151_setup }, +#endif +#ifdef CONFIG_AGP_VIA { 0, PCI_VENDOR_ID_VIA, VIA_GENERIC, @@ -4702,14 +6376,93 @@ via_generic_setup }, #endif /* CONFIG_AGP_VIA */ -#ifdef CONFIG_AGP_HP_ZX1 - { PCI_DEVICE_ID_HP_ZX1_LBA, - PCI_VENDOR_ID_HP, - HP_ZX1, - "HP", - "ZX1", - hp_zx1_setup }, +#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 }, +#endif +#ifdef CONFIG_AGP_AMD_K8 + { PCI_DEVICE_ID_NVIDIA_NFORCE3, + PCI_VENDOR_ID_NVIDIA, + NVIDIA_NFORCE3, + "NVIDIA", + "nForce3/K8 On-CPU GART", + nvidia_x86_64_setup }, + { PCI_DEVICE_ID_NVIDIA_NFORCE3S, + PCI_VENDOR_ID_NVIDIA, + NVIDIA_NFORCE3, + "NVIDIA", + "nForce3S/K8 On-CPU GART", + nvidia_x86_64_setup }, #endif +#ifdef CONFIG_AGP_NVIDIA + { 0, + PCI_VENDOR_ID_NVIDIA, + NVIDIA_GENERIC, + "NVIDIA", + "Generic", + nvidia_generic_setup }, +#endif /* CONFIG_AGP_NVIDIA */ + +#ifdef CONFIG_AGP_ATI + { PCI_DEVICE_ID_ATI_RS100, + PCI_VENDOR_ID_ATI, + ATI_RS100, + "ATI", + "IGP320/M", + ati_generic_setup }, + { PCI_DEVICE_ID_ATI_RS200, + PCI_VENDOR_ID_ATI, + ATI_RS200, + "ATI", + "IGP330/340/345/350/M", + ati_generic_setup }, + { PCI_DEVICE_ID_ATI_RS200_B, + PCI_VENDOR_ID_ATI, + ATI_RS200, + "ATI", + "IGP330/340/345/350/M", + ati_generic_setup }, + { PCI_DEVICE_ID_ATI_RS250, + PCI_VENDOR_ID_ATI, + ATI_RS250, + "ATI", + "IGP7000/M", + ati_generic_setup }, + { PCI_DEVICE_ID_ATI_RS300_100, + PCI_VENDOR_ID_ATI, + ATI_RS300_100, + "ATI", + "IGP9100/M", + ati_generic_setup }, + { PCI_DEVICE_ID_ATI_RS300_133, + PCI_VENDOR_ID_ATI, + ATI_RS300_133, + "ATI", + "IGP9100/M", + ati_generic_setup }, + { PCI_DEVICE_ID_ATI_RS300_166, + PCI_VENDOR_ID_ATI, + ATI_RS300_166, + "ATI", + "IGP9100/M", + ati_generic_setup }, + { PCI_DEVICE_ID_ATI_RS300_200, + PCI_VENDOR_ID_ATI, + ATI_RS300_200, + "ATI", + "IGP9100/M", + ati_generic_setup }, +#endif /* CONFIG_AGP_ATI */ { 0, }, /* dummy final entry, always present */ }; @@ -4784,7 +6537,11 @@ } printk(KERN_ERR PFX "Unsupported %s chipset (device id: %04x)," +#ifdef MODULE " you might want to try agp_try_unsupported=1.\n", +#else + " you might want to boot with agp=try_unsupported\n", +#endif agp_bridge_info[i].vendor_name, pdev->device); return -ENODEV; } @@ -4795,13 +6552,52 @@ static int __init agp_find_supported_device(void) { struct pci_dev *dev = NULL; - u8 cap_ptr = 0x00; + int ret = -ENODEV; - if ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) == NULL) - return -ENODEV; +#ifdef CONFIG_AGP_HP_ZX1 + if (hp_zx1_gart_init() == 0) + return 0; +#endif + + while ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8, dev)) != NULL) { + ret = agp_init_one(dev); + if (ret != -ENODEV) + break; + } + return ret; +} + +static int __init agp_init_one(struct pci_dev *dev) +{ + u8 cap_ptr = 0x00; agp_bridge.dev = dev; +#ifdef CONFIG_AGP_AMD_K8 + /* If there is any K8 northbridge in the system always use the K8 driver */ + if (agp_try_unsupported + && pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, NULL) + && !pci_find_device(PCI_VENDOR_ID_NVIDIA, + PCI_DEVICE_ID_NVIDIA_NFORCE3, + NULL)) { + + /* find capndx */ + cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP); + if (cap_ptr == 0x00) + return -ENODEV; + agp_bridge.capndx = cap_ptr; + + /* Fill in the mode register */ + pci_read_config_dword(agp_bridge.dev, + agp_bridge.capndx + 4, + &agp_bridge.mode); + + printk(KERN_INFO PFX "Detected GART in AMD K8 Northbridge\n"); + agp_bridge.type = AMD_8151; + return amd_8151_setup(dev); + } +#endif + /* Need to test for I810 here */ #ifdef CONFIG_AGP_I810 if (dev->vendor == PCI_VENDOR_ID_INTEL) { @@ -4888,10 +6684,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 +6713,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; } @@ -4958,23 +6866,6 @@ #endif /* CONFIG_AGP_SWORKS */ -#ifdef CONFIG_AGP_HP_ZX1 - if (dev->vendor == PCI_VENDOR_ID_HP) { - do { - /* ZX1 LBAs can be either PCI or AGP bridges */ - if (pci_find_capability(dev, PCI_CAP_ID_AGP)) { - printk(KERN_INFO PFX "Detected HP ZX1 AGP " - "chipset at %s\n", dev->slot_name); - agp_bridge.type = HP_ZX1; - agp_bridge.dev = dev; - return hp_zx1_setup(dev); - } - dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8, dev); - } while (dev); - return -ENODEV; - } -#endif /* CONFIG_AGP_HP_ZX1 */ - /* find capndx */ cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP); if (cap_ptr == 0x00) @@ -5012,7 +6903,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) && @@ -5160,10 +7055,26 @@ &agp_copy_info }; +static int __initdata agp_off = 0; +int __init agp_setup(char *s) +{ + if (!strcmp(s,"off")) + agp_off = 1; + if (!strcmp(s,"try_unsupported")) + agp_try_unsupported = 1; + return 0; +} +__setup("agp=", agp_setup); + int __init agp_init(void) { int ret_val; + if (agp_off) { + printk("AGP disabled\n"); + return -1; + } + printk(KERN_INFO "Linux agpgart interface v%d.%d (c) Jeff Hartmann\n", AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR); Index: drivers/char/agp/agpgart_fe.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/agp/agpgart_fe.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/agp/agpgart_fe.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/agp/agpgart_fe.c 4 Aug 2004 01:28:46 -0000 1.2 @@ -301,7 +301,7 @@ agp_memory *memory; memory = agp_allocate_memory(pg_count, type); - printk(KERN_DEBUG "memory : %p\n", memory); +// printk(KERN_DEBUG "memory : %p\n", memory); if (memory == NULL) { return NULL; } Index: drivers/char/drm/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/Config.in 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/Config.in 4 Aug 2004 01:28:46 -0000 1.2 @@ -6,11 +6,15 @@ # tristate ' 3dfx Banshee/Voodoo3+' CONFIG_DRM_TDFX -#tristate ' 3dlabs GMX 2000' CONFIG_DRM_GAMMA +tristate ' 3dlabs GMX 2000' CONFIG_DRM_GAMMA tristate ' ATI Rage 128' CONFIG_DRM_R128 -dep_tristate ' ATI Radeon' CONFIG_DRM_RADEON $CONFIG_AGP +tristate ' ATI Radeon' CONFIG_DRM_RADEON dep_tristate ' Intel I810' CONFIG_DRM_I810 $CONFIG_AGP dep_mbool ' Enabled XFree 4.1 ioctl interface by default' CONFIG_DRM_I810_XFREE_41 $CONFIG_DRM_I810 dep_tristate ' Intel 830M' CONFIG_DRM_I830 $CONFIG_AGP dep_tristate ' Matrox g200/g400' CONFIG_DRM_MGA $CONFIG_AGP dep_tristate ' SiS' CONFIG_DRM_SIS $CONFIG_AGP +# +# Not ready yet. XFree DRI folks have to fix this up. +# dep_tristate ' S3 Savage' CONFIG_DRM_SAVAGE $CONFIG_AGP +# dep_tristate ' VIA CLE266' CONFIG_DRM_VIA $CONFIG_AGP Index: drivers/char/drm/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/Makefile 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/Makefile 4 Aug 2004 01:28:46 -0000 1.2 @@ -3,18 +3,20 @@ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. O_TARGET := drm.o -list-multi := gamma.o tdfx.o r128.o mga.o i810.o i830.o radeon.o ffb.o sis.o +list-multi := gamma.o tdfx.o r128.o mga.o i810.o i830.o radeon.o ffb.o sis.o savage.o gamma-objs := gamma_drv.o gamma_dma.o tdfx-objs := tdfx_drv.o r128-objs := r128_drv.o r128_cce.o r128_state.o mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o i810-objs := i810_drv.o i810_dma.o -i830-objs := i830_drv.o i830_dma.o - -radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o +i830-objs := i830_drv.o i830_dma.o i830_irq.o +savage-objs := savage_dma.o savage_drv.o savage_state.o +radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o ffb-objs := ffb_drv.o ffb_context.o sis-objs := sis_drv.o sis_ds.o sis_mm.o +via-objs := via_drv.o via_ds.o via_map.o via_mm.o + obj-$(CONFIG_DRM_GAMMA) += gamma.o obj-$(CONFIG_DRM_TDFX) += tdfx.o @@ -25,6 +27,8 @@ obj-$(CONFIG_DRM_I830) += i830.o obj-$(CONFIG_DRM_FFB) += ffb.o obj-$(CONFIG_DRM_SIS) += sis.o +obj-$(CONFIG_DRM_SAVAGE) += savage.o +obj-$(CONFIG_DRM_VIA) += via.o include $(TOPDIR)/Rules.make @@ -54,3 +58,9 @@ sis.o: $(sis-objs) $(lib) $(LD) -r -o $@ $(sis-objs) $(lib) + +savage.o: $(savage-objs) $(lib) + $(LD) -r -o $@ $(savage-objs) $(lib) + +via.o: $(via-objs) $(lib) + $(LD) -r -o $@ $(via-objs) $(lib) Index: drivers/char/drm/drm.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/drm.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/drm.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/drm.h 4 Aug 2004 01:28:46 -0000 1.2 @@ -38,10 +38,27 @@ #if defined(__linux__) #include #include /* For _IO* macros */ -#define DRM_IOCTL_NR(n) _IOC_NR(n) -#elif defined(__FreeBSD__) +#define DRM_IOCTL_NR(n) _IOC_NR(n) +#define DRM_IOC_VOID _IOC_NONE +#define DRM_IOC_READ _IOC_READ +#define DRM_IOC_WRITE _IOC_WRITE +#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE +#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) +#elif defined(__FreeBSD__) || defined(__NetBSD__) +#if defined(__FreeBSD__) && defined(XFree86Server) +/* Prevent name collision when including sys/ioccom.h */ +#undef ioctl #include -#define DRM_IOCTL_NR(n) ((n) & 0xff) +#define ioctl(a,b,c) xf86ioctl(a,b,c) +#else +#include +#endif /* __FreeBSD__ && xf86ioctl */ +#define DRM_IOCTL_NR(n) ((n) & 0xff) +#define DRM_IOC_VOID IOC_VOID +#define DRM_IOC_READ IOC_OUT +#define DRM_IOC_WRITE IOC_IN +#define DRM_IOC_READWRITE IOC_INOUT +#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) #endif #define XFREE86_VERSION(major,minor,patch,snap) \ @@ -84,6 +101,10 @@ /* Warning: If you change this structure, make sure you change * XF86DRIClipRectRec in the server as well */ +/* KW: Actually it's illegal to change either for + * backwards-compatibility reasons. + */ + typedef struct drm_clip_rect { unsigned short x1; unsigned short y1; @@ -106,6 +127,8 @@ #include "radeon_drm.h" #include "sis_drm.h" #include "i830_drm.h" +#include "savage_drm.h" +#include "via_drm.h" typedef struct drm_version { int version_major; /* Major version */ @@ -332,6 +355,32 @@ int funcnum; } drm_irq_busid_t; +typedef enum { + _DRM_VBLANK_ABSOLUTE = 0x0, /* Wait for specific vblank sequence number */ + _DRM_VBLANK_RELATIVE = 0x1, /* Wait for given number of vblanks */ + _DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */ +} drm_vblank_seq_type_t; + +#define _DRM_VBLANK_FLAGS_MASK _DRM_VBLANK_SIGNAL + +struct drm_wait_vblank_request { + drm_vblank_seq_type_t type; + unsigned int sequence; + unsigned long signal; +}; + +struct drm_wait_vblank_reply { + drm_vblank_seq_type_t type; + unsigned int sequence; + long tval_sec; + long tval_usec; +}; + +typedef union drm_wait_vblank { + struct drm_wait_vblank_request request; + struct drm_wait_vblank_reply reply; +} drm_wait_vblank_t; + typedef struct drm_agp_mode { unsigned long mode; } drm_agp_mode_t; @@ -371,10 +420,9 @@ #define DRM_IOCTL_BASE 'd' #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) -#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size) -#define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size) -#define DRM_IOWR(nr,size) _IOWR(DRM_IOCTL_BASE,nr,size) - +#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) +#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type) +#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type) #define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t) #define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t) @@ -427,86 +475,10 @@ #define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t) #define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t) -/* MGA specific ioctls */ -#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) -#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x41, drm_lock_t) -#define DRM_IOCTL_MGA_RESET DRM_IO( 0x42) -#define DRM_IOCTL_MGA_SWAP DRM_IO( 0x43) -#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x44, drm_mga_clear_t) -#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x45, drm_mga_vertex_t) -#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t) -#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x47, drm_mga_iload_t) -#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x48, drm_mga_blit_t) - -/* i810 specific ioctls */ -#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t) -#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t) -#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t) -#define DRM_IOCTL_I810_FLUSH DRM_IO( 0x43) -#define DRM_IOCTL_I810_GETAGE DRM_IO( 0x44) -#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t) -#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46) -#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t) -#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48) -#define DRM_IOCTL_I810_OV0INFO DRM_IOR( 0x49, drm_i810_overlay_t) -#define DRM_IOCTL_I810_FSTATUS DRM_IO ( 0x4a) -#define DRM_IOCTL_I810_OV0FLIP DRM_IO ( 0x4b) -#define DRM_IOCTL_I810_MC DRM_IOW( 0x4c, drm_i810_mc_t) -#define DRM_IOCTL_I810_RSTATUS DRM_IO ( 0x4d ) - - -/* Rage 128 specific ioctls */ -#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t) -#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41) -#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t) -#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43) -#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44) -#define DRM_IOCTL_R128_RESET DRM_IO( 0x46) -#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47) -#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t) -#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t) -#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t) -#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t) -#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t) -#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t) -#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t) -#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t) - -/* Radeon specific ioctls */ -#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t) -#define DRM_IOCTL_RADEON_CP_START DRM_IO( 0x41) -#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( 0x42, drm_radeon_cp_stop_t) -#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43) -#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44) -#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45) -#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t) -#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47) -#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t) -#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t) -#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t) -#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t) -#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t) -#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t) - -/* SiS specific ioctls */ -#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t) -#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t) -#define SIS_IOCTL_AGP_INIT DRM_IOWR(0x53, drm_sis_agp_t) -#define SIS_IOCTL_AGP_ALLOC DRM_IOWR(0x54, drm_sis_mem_t) -#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t) -#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t) -#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49) -#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50) - -/* I830 specific ioctls */ -#define DRM_IOCTL_I830_INIT DRM_IOW( 0x40, drm_i830_init_t) -#define DRM_IOCTL_I830_VERTEX DRM_IOW( 0x41, drm_i830_vertex_t) -#define DRM_IOCTL_I830_CLEAR DRM_IOW( 0x42, drm_i830_clear_t) -#define DRM_IOCTL_I830_FLUSH DRM_IO ( 0x43) -#define DRM_IOCTL_I830_GETAGE DRM_IO ( 0x44) -#define DRM_IOCTL_I830_GETBUF DRM_IOWR(0x45, drm_i830_dma_t) -#define DRM_IOCTL_I830_SWAP DRM_IO ( 0x46) -#define DRM_IOCTL_I830_COPY DRM_IOW( 0x47, drm_i830_copy_t) -#define DRM_IOCTL_I830_DOCOPY DRM_IO ( 0x48) +#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, drm_wait_vblank_t) + +/* Device specfic ioctls should only be in their respective headers + * The device specific ioctl range is 0x40 to 0x79. */ +#define DRM_COMMAND_BASE 0x40 #endif Index: drivers/char/drm/drmP.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/drmP.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/drmP.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/drmP.h 4 Aug 2004 01:28:47 -0000 1.2 @@ -53,6 +53,7 @@ #include #include /* For (un)lock_kernel */ #include +#include #if defined(__alpha__) || defined(__powerpc__) #include /* For pte_wrprotect */ #endif @@ -71,10 +72,7 @@ #include #include "drm.h" -/* page_to_bus for earlier kernels, not optimal in all cases */ -#ifndef page_to_bus -#define page_to_bus(page) ((unsigned int)(virt_to_bus(page_address(page)))) -#endif +#include "drm_os_linux.h" /* DRM template customization defaults */ @@ -209,6 +207,7 @@ (unsigned long)(n),sizeof(*(ptr)))) #endif /* i386 & alpha */ #endif +#define __REALLY_HAVE_SG (__HAVE_SG) /* Begin the DRM... */ @@ -251,41 +250,58 @@ #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) -#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT) + /* Backward compatibility section */ +#ifndef minor +#define minor(x) MINOR((x)) +#endif -/* Macros to make printk easier */ +#ifndef MODULE_LICENSE +#define MODULE_LICENSE(x) +#endif -#if ( __GNUC__ > 2 ) -#define DRM_ERROR(fmt, arg...) \ - printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* " fmt , __FUNCTION__, ##arg) -#define DRM_MEM_ERROR(area, fmt, arg...) \ - printk(KERN_ERR "[" DRM_NAME ":%s:%s] *ERROR* " fmt , __FUNCTION__, \ - DRM(mem_stats)[area].name , ##arg) -#define DRM_INFO(fmt, arg...) printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg) +#ifndef pte_offset_map +#define pte_offset_map pte_offset +#define pte_unmap(pte) +#endif -#if DRM_DEBUG_CODE -#define DRM_DEBUG(fmt, arg...) \ - do { \ - if ( DRM(flags) & DRM_FLAG_DEBUG ) \ - printk(KERN_DEBUG \ - "[" DRM_NAME ":%s] " fmt , \ - __FUNCTION__, \ - ##arg); \ - } while (0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) +static inline struct page * vmalloc_to_page(void * vmalloc_addr) +{ + unsigned long addr = (unsigned long) vmalloc_addr; + struct page *page = NULL; + pgd_t *pgd = pgd_offset_k(addr); + pmd_t *pmd; + pte_t *ptep, pte; + + if (!pgd_none(*pgd)) { + pmd = pmd_offset(pgd, addr); + if (!pmd_none(*pmd)) { + ptep = pte_offset_map(pmd, addr); + pte = *ptep; + if (pte_present(pte)) + page = pte_page(pte); + pte_unmap(ptep); + } + } + return page; +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#define DRM_RPR_ARG(vma) #else -#define DRM_DEBUG(fmt, arg...) do { } while (0) +#define DRM_RPR_ARG(vma) vma, #endif -#else /* Gcc 2.x */ -/* Work around a C preprocessor bug */ +#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT) /* Macros to make printk easier */ #define DRM_ERROR(fmt, arg...) \ - printk(KERN_ERR "[" DRM_NAME ":" __FUNCTION__ "] *ERROR* " fmt , ##arg) + printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* " fmt , __FUNCTION__ , ##arg) #define DRM_MEM_ERROR(area, fmt, arg...) \ - printk(KERN_ERR "[" DRM_NAME ":" __FUNCTION__ ":%s] *ERROR* " fmt , \ + printk(KERN_ERR "[" DRM_NAME ":%s:%s] *ERROR* " fmt , __FUNCTION__, \ DRM(mem_stats)[area].name , ##arg) #define DRM_INFO(fmt, arg...) printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg) @@ -294,16 +310,13 @@ do { \ if ( DRM(flags) & DRM_FLAG_DEBUG ) \ printk(KERN_DEBUG \ - "[" DRM_NAME ":" __FUNCTION__ "] " fmt , \ - ##arg); \ + "[" DRM_NAME ":%s] " fmt , \ + __FUNCTION__ , ##arg); \ } while (0) #else #define DRM_DEBUG(fmt, arg...) do { } while (0) #endif -#endif /* Gcc 2.x */ - - #define DRM_PROC_LIMIT (PAGE_SIZE-80) #define DRM_PROC_PRINT(fmt, arg...) \ @@ -315,13 +328,16 @@ if (len > DRM_PROC_LIMIT) { ret; *eof = 1; return len - offset; } /* Mapping helper macros */ -#define DRM_IOREMAP(map) \ - (map)->handle = DRM(ioremap)( (map)->offset, (map)->size ) +#define DRM_IOREMAP(map, dev) \ + (map)->handle = DRM(ioremap)((map)->offset, (map)->size, (dev) ) + +#define DRM_IOREMAP_NOCACHE(map, dev) \ + (map)->handle = DRM(ioremap_nocache)((map)->offset, (map)->size, (dev) ) -#define DRM_IOREMAPFREE(map) \ +#define DRM_IOREMAPFREE(map, dev) \ do { \ if ( (map)->handle && (map)->size ) \ - DRM(ioremapfree)( (map)->handle, (map)->size ); \ + DRM(ioremapfree)( (map)->handle, (map)->size, (dev) ); \ } while (0) #define DRM_FIND_MAP(_map, _o) \ @@ -599,6 +615,17 @@ drm_map_t *map; } drm_map_list_t; +#if __HAVE_VBL_IRQ + +typedef struct drm_vbl_sig { + struct list_head head; + unsigned int sequence; + struct siginfo info; + struct task_struct *task; +} drm_vbl_sig_t; + +#endif + typedef struct drm_device { const char *name; /* Simple driver name */ char *unique; /* Unique identifier: e.g., busid */ @@ -658,6 +685,13 @@ int last_context; /* Last current context */ unsigned long last_switch; /* jiffies at last context switch */ struct tq_struct tq; +#if __HAVE_VBL_IRQ + wait_queue_head_t vbl_queue; + atomic_t vbl_received; + spinlock_t vbl_lock; + drm_vbl_sig_t vbl_sigs; + unsigned int vbl_pending; +#endif cycles_t ctx_start; cycles_t lck_start; #if __HAVE_DMA_HISTOGRAM @@ -725,16 +759,16 @@ /* Mapping support (drm_vm.h) */ extern struct page *DRM(vm_nopage)(struct vm_area_struct *vma, unsigned long address, - int unused); + int write_access); extern struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma, unsigned long address, - int unused); + int write_access); extern struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma, unsigned long address, - int unused); + int write_access); extern struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma, unsigned long address, - int unused); + int write_access); extern void DRM(vm_open)(struct vm_area_struct *vma); extern void DRM(vm_close)(struct vm_area_struct *vma); extern void DRM(vm_shm_close)(struct vm_area_struct *vma); @@ -755,8 +789,9 @@ extern unsigned long DRM(alloc_pages)(int order, int area); extern void DRM(free_pages)(unsigned long address, int order, int area); -extern void *DRM(ioremap)(unsigned long offset, unsigned long size); -extern void DRM(ioremapfree)(void *pt, unsigned long size); +extern void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev); +extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev); +extern void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev); #if __REALLY_HAVE_AGP extern agp_memory *DRM(alloc_agp)(int pages, u32 type); @@ -885,6 +920,15 @@ extern int DRM(irq_uninstall)( drm_device_t *dev ); extern void DRM(dma_service)( int irq, void *device, struct pt_regs *regs ); +extern void DRM(driver_irq_preinstall)( drm_device_t *dev ); +extern void DRM(driver_irq_postinstall)( drm_device_t *dev ); +extern void DRM(driver_irq_uninstall)( drm_device_t *dev ); +#if __HAVE_VBL_IRQ +extern int DRM(wait_vblank)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int DRM(vblank_wait)(drm_device_t *dev, unsigned int *vbl_seq); +extern void DRM(vbl_send_signals)( drm_device_t *dev ); +#endif #if __HAVE_DMA_IRQ_BH extern void DRM(dma_immediate_bh)( void *dev ); #endif Index: drivers/char/drm/drm_agpsupport.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/drm_agpsupport.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/drm_agpsupport.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/drm_agpsupport.h 4 Aug 2004 01:28:47 -0000 1.2 @@ -73,9 +73,14 @@ drm_device_t *dev = priv->dev; int retcode; - if (!dev->agp || dev->agp->acquired || !drm_agp->acquire) + if (!dev->agp) + return -ENODEV; + if (dev->agp->acquired) + return -EBUSY; + if(!drm_agp->acquire) return -EINVAL; - if ((retcode = drm_agp->acquire())) return retcode; + if ((retcode = drm_agp->acquire())) + return retcode; dev->agp->acquired = 1; return 0; } @@ -259,67 +264,13 @@ return NULL; } head->memory = NULL; - switch (head->agp_info.chipset) { - case INTEL_GENERIC: head->chipset = "Intel"; break; - case INTEL_LX: head->chipset = "Intel 440LX"; break; - case INTEL_BX: head->chipset = "Intel 440BX"; break; - case INTEL_GX: head->chipset = "Intel 440GX"; break; - case INTEL_I810: head->chipset = "Intel i810"; break; - case INTEL_I815: head->chipset = "Intel i815"; break; - case INTEL_I820: head->chipset = "Intel i820"; break; - case INTEL_I840: head->chipset = "Intel i840"; break; - case INTEL_I845: head->chipset = "Intel i845"; break; - case INTEL_I850: head->chipset = "Intel i850"; break; - - case VIA_GENERIC: head->chipset = "VIA"; break; - case VIA_VP3: head->chipset = "VIA VP3"; break; - case VIA_MVP3: head->chipset = "VIA MVP3"; break; - case VIA_MVP4: head->chipset = "VIA MVP4"; break; - case VIA_APOLLO_KX133: head->chipset = "VIA Apollo KX133"; - break; - case VIA_APOLLO_KT133: head->chipset = "VIA Apollo KT133"; - break; - case VIA_APOLLO_KT400: head->chipset = "VIA Apollo KT400"; - break; - case VIA_APOLLO_PRO: head->chipset = "VIA Apollo Pro"; - break; - case VIA_APOLLO_P4X400: head->chipset = "VIA Apollo P4X400"; - break; - - case SIS_GENERIC: head->chipset = "SiS"; break; - case AMD_GENERIC: head->chipset = "AMD"; break; - case AMD_IRONGATE: head->chipset = "AMD Irongate"; break; - case AMD_8151: head->chipset = "AMD 8151"; break; - case ALI_GENERIC: head->chipset = "ALi"; break; - case ALI_M1541: head->chipset = "ALi M1541"; break; - - case ALI_M1621: head->chipset = "ALi M1621"; break; - case ALI_M1631: head->chipset = "ALi M1631"; break; - case ALI_M1632: head->chipset = "ALi M1632"; break; - case ALI_M1641: head->chipset = "ALi M1641"; break; - case ALI_M1644: head->chipset = "ALi M1644"; break; - case ALI_M1647: head->chipset = "ALi M1647"; break; - case ALI_M1651: head->chipset = "ALi M1651"; break; - - case SVWRKS_HE: head->chipset = "Serverworks HE"; - break; - case SVWRKS_LE: head->chipset = "Serverworks LE"; - break; - case SVWRKS_GENERIC: head->chipset = "Serverworks Generic"; - break; - - case HP_ZX1: head->chipset = "HP ZX1"; break; - - default: head->chipset = "Unknown"; break; - } head->cant_use_aperture = head->agp_info.cant_use_aperture; head->page_mask = head->agp_info.page_mask; - DRM_INFO("AGP %d.%d on %s @ 0x%08lx %ZuMB\n", + DRM_INFO("AGP %d.%d Aperture @ 0x%08lx %ZuMB\n", head->agp_info.version.major, head->agp_info.version.minor, - head->chipset, head->agp_info.aper_base, head->agp_info.aper_size); } Index: drivers/char/drm/drm_bufs.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/drm_bufs.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/drm_bufs.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/drm_bufs.h 4 Aug 2004 01:28:47 -0000 1.2 @@ -123,7 +123,7 @@ MTRR_TYPE_WRCOMB, 1 ); } #endif - map->handle = DRM(ioremap)( map->offset, map->size ); + map->handle = DRM(ioremap)( map->offset, map->size, dev ); break; case _DRM_SHM: @@ -136,6 +136,7 @@ } map->offset = (unsigned long)map->handle; if ( map->flags & _DRM_CONTAINS_LOCK ) { + dev->sigdata.lock = dev->lock.hw_lock = map->handle; /* Pointer to lock */ } break; @@ -244,7 +245,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - DRM(ioremapfree)(map->handle, map->size); + DRM(ioremapfree)(map->handle, map->size, dev); break; case _DRM_SHM: vfree(map->handle); Index: drivers/char/drm/drm_context.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/drm_context.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/drm_context.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/drm_context.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -554,7 +554,7 @@ /* Allocate a new queue */ down(&dev->struct_sem); - queue = gamma_alloc(sizeof(*queue), DRM_MEM_QUEUES); + queue = DRM(alloc)(sizeof(*queue), DRM_MEM_QUEUES); memset(queue, 0, sizeof(*queue)); atomic_set(&queue->use_count, 1); Index: drivers/char/drm/drm_dma.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/drm_dma.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/drm_dma.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/drm_dma.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -30,7 +30,7 @@ */ #include "drmP.h" - +#include "drm_os_linux.h" #include /* For task queue support */ #ifndef __HAVE_DMA_WAITQUEUE @@ -537,8 +537,18 @@ dev->tq.data = dev; #endif +#if __HAVE_VBL_IRQ + init_waitqueue_head(&dev->vbl_queue); + + spin_lock_init( &dev->vbl_lock ); + + INIT_LIST_HEAD( &dev->vbl_sigs.head ); + + dev->vbl_pending = 0; +#endif + /* Before installing handler */ - DRIVER_PREINSTALL(); + DRM(driver_irq_preinstall)(dev); /* Install handler */ ret = request_irq( dev->irq, DRM(dma_service), @@ -551,7 +561,7 @@ } /* After installing handler */ - DRIVER_POSTINSTALL(); + DRM(driver_irq_postinstall)(dev); return 0; } @@ -570,7 +580,7 @@ DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); - DRIVER_UNINSTALL(); + DRM(driver_irq_uninstall)( dev ); free_irq( irq, dev ); @@ -597,6 +607,142 @@ } } +#if __HAVE_VBL_IRQ + +int DRM(wait_vblank)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_wait_vblank_t vblwait; + struct timeval now; + int ret = 0; + unsigned int flags; + + if (!dev->irq) + return -EINVAL; + + DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data, + sizeof(vblwait) ); + + switch ( vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK ) { + case _DRM_VBLANK_RELATIVE: + vblwait.request.sequence += atomic_read( &dev->vbl_received ); + vblwait.request.type &= ~_DRM_VBLANK_RELATIVE; + case _DRM_VBLANK_ABSOLUTE: + break; + default: + return -EINVAL; + } + + flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK; + + if ( flags & _DRM_VBLANK_SIGNAL ) { + unsigned long irqflags; + drm_vbl_sig_t *vbl_sig; + + vblwait.reply.sequence = atomic_read( &dev->vbl_received ); + + spin_lock_irqsave( &dev->vbl_lock, irqflags ); + + /* Check if this task has already scheduled the same signal + * for the same vblank sequence number; nothing to be done in + * that case + */ + list_for_each( ( (struct list_head *) vbl_sig ), &dev->vbl_sigs.head ) { + if (vbl_sig->sequence == vblwait.request.sequence + && vbl_sig->info.si_signo == vblwait.request.signal + && vbl_sig->task == current) + { + spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); + goto done; + } + } + + if ( dev->vbl_pending >= 100 ) { + spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); + return -EBUSY; + } + + dev->vbl_pending++; + + spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); + + if ( !( vbl_sig = kmalloc(sizeof(drm_vbl_sig_t), GFP_KERNEL) ) ) + return -ENOMEM; + + + memset( (void *)vbl_sig, 0, sizeof(*vbl_sig) ); + + vbl_sig->sequence = vblwait.request.sequence; + vbl_sig->info.si_signo = vblwait.request.signal; + vbl_sig->task = current; + + spin_lock_irqsave( &dev->vbl_lock, irqflags ); + + list_add_tail( (struct list_head *) vbl_sig, &dev->vbl_sigs.head ); + + spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); + } else { + ret = DRM(vblank_wait)( dev, &vblwait.request.sequence ); + + do_gettimeofday( &now ); + vblwait.reply.tval_sec = now.tv_sec; + vblwait.reply.tval_usec = now.tv_usec; + } + +done: + DRM_COPY_TO_USER_IOCTL( (drm_wait_vblank_t *)data, vblwait, + sizeof(vblwait) ); + + return ret; +} + +void DRM(vbl_send_signals)( drm_device_t *dev ) +{ + struct list_head *tmp; + drm_vbl_sig_t *vbl_sig; + unsigned int vbl_seq = atomic_read( &dev->vbl_received ); + unsigned long flags; + + spin_lock_irqsave( &dev->vbl_lock, flags ); + + list_for_each_safe( ( (struct list_head *) vbl_sig ), tmp, &dev->vbl_sigs.head ) { + if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) { + vbl_sig->info.si_code = vbl_seq; + send_sig_info( vbl_sig->info.si_signo, &vbl_sig->info, vbl_sig->task ); + + list_del( (struct list_head *) vbl_sig ); + + + kfree( vbl_sig ); + dev->vbl_pending--; + } + } + + spin_unlock_irqrestore( &dev->vbl_lock, flags ); +} + +#endif /* __HAVE_VBL_IRQ */ + +#else + +int DRM(control)( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_control_t ctl; + + if ( copy_from_user( &ctl, (drm_control_t *)arg, sizeof(ctl) ) ) + return -EFAULT; + + switch ( ctl.func ) { + case DRM_INST_HANDLER: + case DRM_UNINST_HANDLER: + return 0; + default: + return -EINVAL; + } +} + #endif /* __HAVE_DMA_IRQ */ #endif /* __HAVE_DMA */ Index: drivers/char/drm/drm_drv.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/drm_drv.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/drm_drv.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/drm_drv.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -115,18 +115,34 @@ #ifndef DRIVER_FOPS #define DRIVER_FOPS \ static struct file_operations DRM(fops) = { \ - owner: THIS_MODULE, \ - open: DRM(open), \ - flush: DRM(flush), \ - release: DRM(release), \ - ioctl: DRM(ioctl), \ - mmap: DRM(mmap), \ - read: DRM(read), \ - fasync: DRM(fasync), \ - poll: DRM(poll), \ + .owner = THIS_MODULE, \ + .open = DRM(open), \ + .flush = DRM(flush), \ + .release = DRM(release), \ + .ioctl = DRM(ioctl), \ + .mmap = DRM(mmap), \ + .read = DRM(read), \ + .fasync = DRM(fasync), \ + .poll = DRM(poll), \ } #endif +#ifndef MODULE +/* DRM(options) is called by the kernel to parse command-line options + * passed via the boot-loader (e.g., LILO). It calls the insmod option + * routine, drm_parse_drm. + */ +/* Use an additional macro to avoid preprocessor troubles */ +#define DRM_OPTIONS_FUNC DRM(options) +static int __init DRM(options)( char *str ) +{ + DRM(parse_options)( str ); + return 1; +} + +__setup( DRIVER_NAME "=", DRM_OPTIONS_FUNC ); +#undef DRM_OPTIONS_FUNC +#endif /* * The default number of instances (minor numbers) to initialize. @@ -187,10 +203,8 @@ /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */ -#if __HAVE_DMA_IRQ [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { DRM(control), 1, 1 }, #endif -#endif #if __REALLY_HAVE_AGP [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { DRM(agp_acquire), 1, 1 }, @@ -208,6 +222,10 @@ [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { DRM(sg_free), 1, 1 }, #endif +#if __HAVE_VBL_IRQ + [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = { DRM(wait_vblank), 0, 0 }, +#endif + DRIVER_IOCTLS }; @@ -292,7 +310,7 @@ dev->map_count = 0; dev->vmalist = NULL; - dev->lock.hw_lock = NULL; + dev->sigdata.lock = dev->lock.hw_lock = NULL; init_waitqueue_head( &dev->lock.lock_queue ); dev->queue_count = 0; dev->queue_reserved = 0; @@ -425,7 +443,7 @@ DRM_DEBUG( "mtrr_del=%d\n", retcode ); } #endif - DRM(ioremapfree)( map->handle, map->size ); + DRM(ioremapfree)( map->handle, map->size, dev ); break; case _DRM_SHM: vfree(map->handle); @@ -477,7 +495,7 @@ DRM(dma_takedown)( dev ); #endif if ( dev->lock.hw_lock ) { - dev->lock.hw_lock = NULL; /* SHM removed */ + dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */ dev->lock.pid = 0; wake_up_interruptible( &dev->lock.lock_queue ); } @@ -705,7 +723,7 @@ int i; for (i = 0; i < DRM(numdevs); i++) { - if (MINOR(inode->i_rdev) == DRM(minor)[i]) { + if (minor(inode->i_rdev) == DRM(minor)[i]) { dev = &(DRM(device)[i]); break; } @@ -747,8 +765,8 @@ * Begin inline drm_release */ - DRM_DEBUG( "pid = %d, device = 0x%x, open_count = %d\n", - current->pid, dev->device, dev->open_count ); + DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n", + current->pid, (long)dev->device, dev->open_count ); if ( dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && @@ -873,8 +891,9 @@ atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] ); ++priv->ioctl_count; - DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%x, auth=%d\n", - current->pid, cmd, nr, dev->device, priv->authenticated ); + DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", + current->pid, cmd, nr, (long)dev->device, + priv->authenticated ); if ( nr >= DRIVER_IOCTL_COUNT ) { retcode = -EINVAL; @@ -1027,6 +1046,25 @@ atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] ); +#if __HAVE_KERNEL_CTX_SWITCH + /* We no longer really hold it, but if we are the next + * agent to request it then we should just be able to + * take it immediately and not eat the ioctl. + */ + dev->lock.pid = 0; + { + __volatile__ unsigned int *plock = &dev->lock.hw_lock->lock; + unsigned int old, new, prev, ctx; + + ctx = lock.context; + do { + old = *plock; + new = ctx; + prev = cmpxchg(plock, old, new); + } while (prev != old); + } + wake_up_interruptible(&dev->lock.lock_queue); +#else DRM(lock_transfer)( dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT ); #if __HAVE_DMA_SCHEDULE @@ -1041,6 +1079,7 @@ DRM_ERROR( "\n" ); } } +#endif /* !__HAVE_KERNEL_CTX_SWITCH */ unblock_all_signals(); return 0; Index: drivers/char/drm/drm_fops.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/drm_fops.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/drm_fops.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/drm_fops.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -37,7 +37,7 @@ int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev) { - kdev_t minor = MINOR(inode->i_rdev); + int minor = minor(inode->i_rdev); drm_file_t *priv; if (filp->f_flags & O_EXCL) return -EBUSY; /* No exclusive opens */ @@ -94,25 +94,8 @@ drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n", - current->pid, dev->device, dev->open_count); - if ( dev->lock.hw_lock && - _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && - dev->lock.pid == current->pid ) { - DRM_DEBUG( "Process %d closed fd, freeing lock for context %d\n", - current->pid, - _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) ); -#if __HAVE_RELEASE - DRIVER_RELEASE(); -#endif - DRM(lock_free)( dev, &dev->lock.hw_lock->lock, - _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) ); - - /* FIXME: may require heavy-handed reset of - hardware at this point, possibly - processed via a callback to the X - server. */ - } + DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", + current->pid, (long)dev->device, dev->open_count); return 0; } @@ -122,7 +105,7 @@ drm_device_t *dev = priv->dev; int retcode; - DRM_DEBUG("fd = %d, device = 0x%x\n", fd, dev->device); + DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)dev->device); retcode = fasync_helper(fd, filp, on, &dev->buf_async); if (retcode < 0) return retcode; return 0; Index: drivers/char/drm/drm_ioctl.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/drm_ioctl.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/drm_ioctl.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/drm_ioctl.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -111,7 +111,7 @@ do { struct pci_dev *pci_dev; - int b, d, f; + int domain, b, d, f; char *p; for(p = dev->unique; p && *p && *p != ':'; p++); @@ -123,6 +123,27 @@ f = (int)simple_strtoul(p+1, &p, 10); if (*p) break; + domain = b >> 8; + b &= 0xff; + +#ifdef __alpha__ + /* + * Find the hose the device is on (the domain number is the + * hose index) and offset the bus by the root bus of that + * hose. + */ + for(pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,NULL); + pci_dev; + pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,pci_dev)) { + struct pci_controller *hose = pci_dev->sysdata; + + if (hose->index == domain) { + b += hose->bus->number; + break; + } + } +#endif + pci_dev = pci_find_slot(b, PCI_DEVFN(d,f)); if (pci_dev) { dev->pdev = pci_dev; Index: drivers/char/drm/drm_lock.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/drm_lock.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/drm_lock.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/drm_lock.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -236,7 +236,7 @@ /* Allow signal delivery if lock isn't held */ - if (!_DRM_LOCK_IS_HELD(s->lock->lock) + if (!s->lock || !_DRM_LOCK_IS_HELD(s->lock->lock) || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) return 1; /* Otherwise, set flag to force call to Index: drivers/char/drm/drm_memory.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/drm_memory.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/drm_memory.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/drm_memory.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -290,7 +290,7 @@ } } -void *DRM(ioremap)(unsigned long offset, unsigned long size) +void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev) { void *pt; @@ -313,7 +313,30 @@ return pt; } -void DRM(ioremapfree)(void *pt, unsigned long size) +void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev) +{ + void *pt; + + if (!size) { + DRM_MEM_ERROR(DRM_MEM_MAPPINGS, + "Mapping 0 bytes at 0x%08lx\n", offset); + return NULL; + } + + if (!(pt = ioremap_nocache(offset, size))) { + spin_lock(&DRM(mem_lock)); + ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; + spin_unlock(&DRM(mem_lock)); + return NULL; + } + spin_lock(&DRM(mem_lock)); + ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; + DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size; + spin_unlock(&DRM(mem_lock)); + return pt; +} + +void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev) { int alloc_count; int free_count; Index: drivers/char/drm/drm_proc.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/drm_proc.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/drm_proc.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/drm_proc.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -147,10 +147,10 @@ *eof = 0; if (dev->unique) { - DRM_PROC_PRINT("%s 0x%x %s\n", - dev->name, dev->device, dev->unique); + DRM_PROC_PRINT("%s 0x%lx %s\n", + dev->name, (long)dev->device, dev->unique); } else { - DRM_PROC_PRINT("%s 0x%x\n", dev->name, dev->device); + DRM_PROC_PRINT("%s 0x%lx\n", dev->name, (long)dev->device); } if (len > request + offset) return request; Index: drivers/char/drm/drm_stub.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/drm_stub.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/drm_stub.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/drm_stub.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -48,7 +48,7 @@ static int DRM(stub_open)(struct inode *inode, struct file *filp) { - int minor = MINOR(inode->i_rdev); + int minor = minor(inode->i_rdev); int err = -ENODEV; struct file_operations *old_fops; @@ -65,8 +65,8 @@ } static struct file_operations DRM(stub_fops) = { - owner: THIS_MODULE, - open: DRM(stub_open) + .owner = THIS_MODULE, + .open = DRM(stub_open) }; static int DRM(stub_getminor)(const char *name, struct file_operations *fops, Index: drivers/char/drm/drm_vm.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/drm_vm.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/drm_vm.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/drm_vm.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -57,7 +57,7 @@ struct page *DRM(vm_nopage)(struct vm_area_struct *vma, unsigned long address, - int unused) + int write_access) { #if __REALLY_HAVE_AGP drm_file_t *priv = vma->vm_file->private_data; @@ -70,7 +70,7 @@ * Find the right map */ - if(!dev->agp->cant_use_aperture) goto vm_nopage_error; + if(!dev->agp || !dev->agp->cant_use_aperture) goto vm_nopage_error; list_for_each(list, &dev->maplist->head) { r_list = (drm_map_list_t *)list; @@ -141,9 +141,7 @@ return NOPAGE_OOM; get_page(page); -#if 0 /* XXX page_to_bus is not a portable interface available on all platforms. */ - DRM_DEBUG("0x%08lx => 0x%08llx\n", address, (u64)page_to_bus(page)); -#endif + DRM_DEBUG("shm_nopage 0x%lx\n", address); return page; } @@ -208,7 +206,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - DRM(ioremapfree)(map->handle, map->size); + DRM(ioremapfree)(map->handle, map->size, dev); break; case _DRM_SHM: vfree(map->handle); @@ -245,10 +243,7 @@ get_page(page); -#if 0 /* XXX page_to_bus is not a portable interface available on all platforms. */ - DRM_DEBUG("0x%08lx (page %lu) => 0x%08llx\n", address, page_nr, - (u64)page_to_bus(page)); -#endif + DRM_DEBUG("dma_nopage 0x%lx (page %lu)\n", address, page_nr); return page; } @@ -449,12 +444,12 @@ } offset = DRIVER_GET_REG_OFS(); #ifdef __sparc__ - if (io_remap_page_range(vma->vm_start, + if (io_remap_page_range(DRM_RPR_ARG(vma) vma->vm_start, VM_OFFSET(vma) + offset, vma->vm_end - vma->vm_start, vma->vm_page_prot, 0)) #else - if (remap_page_range(vma->vm_start, + if (remap_page_range(DRM_RPR_ARG(vma) vma->vm_start, VM_OFFSET(vma) + offset, vma->vm_end - vma->vm_start, vma->vm_page_prot)) Index: drivers/char/drm/ffb_context.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/ffb_context.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/ffb_context.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/ffb_context.c 4 Aug 2004 01:28:48 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ffb_context.c,v 1.1 2004/07/22 19:49:52 joff Exp $ +/* $Id: ffb_context.c,v 1.2 2004/08/04 01:28:48 joff Exp $ * ffb_context.c: Creator/Creator3D DRI/DRM context switching. * * Copyright (C) 2000 David S. Miller (davem@redhat.com) Index: drivers/char/drm/ffb_drv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/ffb_drv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/ffb_drv.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/ffb_drv.c 4 Aug 2004 01:28:48 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ffb_drv.c,v 1.1 2004/07/22 19:49:52 joff Exp $ +/* $Id: ffb_drv.c,v 1.2 2004/08/04 01:28:48 joff Exp $ * ffb_drv.c: Creator/Creator3D direct rendering driver. * * Copyright (C) 2000 David S. Miller (davem@redhat.com) @@ -372,25 +372,6 @@ return ret; } -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init ffb_options(char *str) -{ - DRM(parse_options)(str); - return 1; -} - -__setup(DRIVER_NAME "=", ffb_options); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" Index: drivers/char/drm/ffb_drv.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/ffb_drv.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/ffb_drv.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/ffb_drv.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ffb_drv.h,v 1.1 2004/07/22 19:49:52 joff Exp $ +/* $Id: ffb_drv.h,v 1.2 2004/08/04 01:28:48 joff Exp $ * ffb_drv.h: Creator/Creator3D direct rendering driver. * * Copyright (C) 2000 David S. Miller (davem@redhat.com) Index: drivers/char/drm/gamma.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/gamma.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/gamma.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/gamma.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -38,9 +38,36 @@ */ #define __HAVE_MTRR 1 +#define DRIVER_AUTHOR "VA Linux Systems Inc." + +#define DRIVER_NAME "gamma" +#define DRIVER_DESC "3DLabs gamma" +#define DRIVER_DATE "20010624" + +#define DRIVER_MAJOR 2 +#define DRIVER_MINOR 0 +#define DRIVER_PATCHLEVEL 0 + +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { gamma_dma, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_GAMMA_INIT)] = { gamma_dma_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_GAMMA_COPY)] = { gamma_dma_copy, 1, 1 } + +#define IOCTL_TABLE_NAME DRM(ioctls) +#define IOCTL_FUNC_NAME DRM(ioctl) + +#define __HAVE_COUNTERS 5 +#define __HAVE_COUNTER6 _DRM_STAT_IRQ +#define __HAVE_COUNTER7 _DRM_STAT_DMA +#define __HAVE_COUNTER8 _DRM_STAT_PRIMARY +#define __HAVE_COUNTER9 _DRM_STAT_SPECIAL +#define __HAVE_COUNTER10 _DRM_STAT_MISSED + /* DMA customization: */ #define __HAVE_DMA 1 +#define __HAVE_AGP 1 +#define __MUST_HAVE_AGP 0 #define __HAVE_OLD_DMA 1 #define __HAVE_PCI_DMA 1 @@ -61,33 +88,61 @@ #define __HAVE_DMA_QUIESCENT 1 #define DRIVER_DMA_QUIESCENT() do { \ /* FIXME ! */ \ - gamma_dma_quiescent_dual(dev); \ + gamma_dma_quiescent_single(dev); \ return 0; \ } while (0) #define __HAVE_DMA_IRQ 1 #define __HAVE_DMA_IRQ_BH 1 + +#if 1 #define DRIVER_PREINSTALL() do { \ drm_gamma_private_t *dev_priv = \ (drm_gamma_private_t *)dev->dev_private;\ - GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000000 ); \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2) cpu_relax(); \ + GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000004 ); \ GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); \ } while (0) - #define DRIVER_POSTINSTALL() do { \ drm_gamma_private_t *dev_priv = \ (drm_gamma_private_t *)dev->dev_private;\ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2) cpu_relax(); \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3) cpu_relax(); \ GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 ); \ GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 ); \ GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 ); \ } while (0) +#else +#define DRIVER_POSTINSTALL() do { \ + drm_gamma_private_t *dev_priv = \ + (drm_gamma_private_t *)dev->dev_private;\ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2) cpu_relax(); \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2) cpu_relax(); \ + GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002000 ); \ + GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000004 ); \ +} while (0) + +#define DRIVER_PREINSTALL() do { \ + drm_gamma_private_t *dev_priv = \ + (drm_gamma_private_t *)dev->dev_private;\ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2) cpu_relax(); \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2) cpu_relax(); \ + GAMMA_WRITE( GAMMA_GCOMMANDMODE, GAMMA_QUEUED_DMA_MODE );\ + GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 );\ +} while (0) +#endif #define DRIVER_UNINSTALL() do { \ drm_gamma_private_t *dev_priv = \ (drm_gamma_private_t *)dev->dev_private;\ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2) cpu_relax(); \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3) cpu_relax(); \ GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 ); \ GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 ); \ GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 ); \ } while (0) +#define DRIVER_AGP_BUFFERS_MAP( dev ) \ + ((drm_gamma_private_t *)((dev)->dev_private))->buffers + #endif /* __GAMMA_H__ */ Index: drivers/char/drm/gamma_dma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/gamma_dma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/gamma_dma.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/gamma_dma.c 4 Aug 2004 01:28:48 -0000 1.2 @@ -31,33 +31,32 @@ #include "gamma.h" #include "drmP.h" +#include "drm.h" +#include "gamma_drm.h" #include "gamma_drv.h" #include /* For task queue support */ #include - static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address, unsigned long length) { drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; - - GAMMA_WRITE(GAMMA_DMAADDRESS, virt_to_phys((void *)address)); - while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4) - ; + (drm_gamma_private_t *)dev->dev_private; + mb(); + while ( GAMMA_READ(GAMMA_INFIFOSPACE) < 2) cpu_relax(); + GAMMA_WRITE(GAMMA_DMAADDRESS, address); + while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4) cpu_relax(); GAMMA_WRITE(GAMMA_DMACOUNT, length / 4); } void gamma_dma_quiescent_single(drm_device_t *dev) { drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; + (drm_gamma_private_t *)dev->dev_private; + while (GAMMA_READ(GAMMA_DMACOUNT)) cpu_relax(); - while (GAMMA_READ(GAMMA_DMACOUNT)) - ; - while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) - ; + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 2) cpu_relax(); GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10); GAMMA_WRITE(GAMMA_SYNC, 0); @@ -71,56 +70,50 @@ void gamma_dma_quiescent_dual(drm_device_t *dev) { drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; + (drm_gamma_private_t *)dev->dev_private; + while (GAMMA_READ(GAMMA_DMACOUNT)) cpu_relax(); - while (GAMMA_READ(GAMMA_DMACOUNT)) - ; - while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) - ; + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) cpu_relax(); GAMMA_WRITE(GAMMA_BROADCASTMASK, 3); - GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10); GAMMA_WRITE(GAMMA_SYNC, 0); - /* Read from first MX */ + /* Read from first MX */ do { - while (!GAMMA_READ(GAMMA_OUTFIFOWORDS)) - ; + while (!GAMMA_READ(GAMMA_OUTFIFOWORDS)) cpu_relax(); } while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG); - /* Read from second MX */ + /* Read from second MX */ do { - while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000)) - ; + while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000)) cpu_relax(); } while (GAMMA_READ(GAMMA_OUTPUTFIFO + 0x10000) != GAMMA_SYNC_TAG); } void gamma_dma_ready(drm_device_t *dev) { drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; - - while (GAMMA_READ(GAMMA_DMACOUNT)) - ; + (drm_gamma_private_t *)dev->dev_private; + while (GAMMA_READ(GAMMA_DMACOUNT)) cpu_relax(); } static inline int gamma_dma_is_ready(drm_device_t *dev) { drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; - - return !GAMMA_READ(GAMMA_DMACOUNT); + (drm_gamma_private_t *)dev->dev_private; + return(!GAMMA_READ(GAMMA_DMACOUNT)); } void gamma_dma_service(int irq, void *device, struct pt_regs *regs) { - drm_device_t *dev = (drm_device_t *)device; - drm_device_dma_t *dma = dev->dma; + drm_device_t *dev = (drm_device_t *)device; + drm_device_dma_t *dma = dev->dma; drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; + (drm_gamma_private_t *)dev->dev_private; atomic_inc(&dev->counts[6]); /* _DRM_STAT_IRQ */ + + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) cpu_relax(); GAMMA_WRITE(GAMMA_GDELAYTIMER, 0xc350/2); /* 0x05S */ GAMMA_WRITE(GAMMA_GCOMMANDINTFLAGS, 8); GAMMA_WRITE(GAMMA_GINTFLAGS, 0x2001); @@ -164,7 +157,9 @@ } buf = dma->next_buffer; - address = (unsigned long)buf->address; + /* WE NOW ARE ON LOGICAL PAGES!! - using page table setup in dma_init */ + /* So we pass the buffer index value into the physical page offset */ + address = buf->idx << 12; length = buf->used; DRM_DEBUG("context %d, buffer %d (%ld bytes)\n", @@ -231,6 +226,9 @@ buf->time_dispatched = get_cycles(); #endif + /* WE NOW ARE ON LOGICAL PAGES!!! - overriding address */ + address = buf->idx << 12; + gamma_dma_dispatch(dev, address, length); gamma_free_buffer(dev, dma->this_buffer); dma->this_buffer = buf; @@ -523,11 +521,11 @@ } } if (retcode) { - DRM_ERROR("ctx%d w%d p%d c%d i%d l%d %d/%d\n", + DRM_ERROR("ctx%d w%d p%d c%ld i%d l%d %d/%d\n", d->context, last_buf->waiting, last_buf->pending, - DRM_WAITCOUNT(dev, d->context), + (long)DRM_WAITCOUNT(dev, d->context), last_buf->idx, last_buf->list, last_buf->pid, @@ -581,3 +579,267 @@ return retcode; } + +/* ============================================================= + * DMA initialization, cleanup + */ + +static int gamma_do_init_dma( drm_device_t *dev, drm_gamma_init_t *init ) +{ + drm_gamma_private_t *dev_priv; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + int i; + struct list_head *list; + unsigned long *pgt; + + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + dev_priv = DRM(alloc)( sizeof(drm_gamma_private_t), + DRM_MEM_DRIVER ); + if ( !dev_priv ) + return -ENOMEM; + + dev->dev_private = (void *)dev_priv; + + memset( dev_priv, 0, sizeof(drm_gamma_private_t) ); + + list_for_each(list, &dev->maplist->head) { + #warning list_entry() is needed here + drm_map_list_t *r_list = (drm_map_list_t *)list; + if( r_list->map && + r_list->map->type == _DRM_SHM && + r_list->map->flags & _DRM_CONTAINS_LOCK ) { + dev_priv->sarea = r_list->map; + break; + } + } + + DRM_FIND_MAP( dev_priv->mmio0, init->mmio0 ); + DRM_FIND_MAP( dev_priv->mmio1, init->mmio1 ); + DRM_FIND_MAP( dev_priv->mmio2, init->mmio2 ); + DRM_FIND_MAP( dev_priv->mmio3, init->mmio3 ); + + dev_priv->sarea_priv = (drm_gamma_sarea_t *) + ((u8 *)dev_priv->sarea->handle + + init->sarea_priv_offset); + + if (init->pcimode) { + buf = dma->buflist[GLINT_DRI_BUF_COUNT]; + pgt = buf->address; + + for (i = 0; i < GLINT_DRI_BUF_COUNT; i++) { + buf = dma->buflist[i]; + *pgt = virt_to_phys((void*)buf->address) | 0x07; + pgt++; + } + + buf = dma->buflist[GLINT_DRI_BUF_COUNT]; + } else { + DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); + + DRM_IOREMAP( dev_priv->buffers, dev ); + + buf = dma->buflist[GLINT_DRI_BUF_COUNT]; + pgt = buf->address; + + for (i = 0; i < GLINT_DRI_BUF_COUNT; i++) { + buf = dma->buflist[i]; + *pgt = (unsigned long)buf->address + 0x07; + pgt++; + } + + buf = dma->buflist[GLINT_DRI_BUF_COUNT]; + + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 1) cpu_relax(); + GAMMA_WRITE( GAMMA_GDMACONTROL, 0xe) ; + } + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 2); cpu_relax(); + GAMMA_WRITE( GAMMA_PAGETABLEADDR, virt_to_phys((void*)buf->address) ); + GAMMA_WRITE( GAMMA_PAGETABLELENGTH, 2 ); + + return 0; +} + +int gamma_do_cleanup_dma( drm_device_t *dev ) +{ + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + if ( dev->dev_private ) { + drm_gamma_private_t *dev_priv = dev->dev_private; + + DRM_IOREMAPFREE( dev_priv->buffers, dev ); + + DRM(free)( dev->dev_private, sizeof(drm_gamma_private_t), + DRM_MEM_DRIVER ); + dev->dev_private = NULL; + } + + return 0; +} + +int gamma_dma_init( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_gamma_init_t init; + + if ( copy_from_user( &init, (drm_gamma_init_t *)arg, sizeof(init) ) ) + return -EFAULT; + + switch ( init.func ) { + case GAMMA_INIT_DMA: + return gamma_do_init_dma( dev, &init ); + case GAMMA_CLEANUP_DMA: + return gamma_do_cleanup_dma( dev ); + } + + return -EINVAL; +} + +static int gamma_do_copy_dma( drm_device_t *dev, drm_gamma_copy_t *copy ) +{ + drm_device_dma_t *dma = dev->dma; + unsigned int *screenbuf; + + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + /* We've DRM_RESTRICTED this DMA buffer */ + + screenbuf = dma->buflist[ GLINT_DRI_BUF_COUNT + 1 ]->address; + +#if 0 + *buffer++ = 0x180; /* Tag (FilterMode) */ + *buffer++ = 0x200; /* Allow FBColor through */ + *buffer++ = 0x53B; /* Tag */ + *buffer++ = copy->Pitch; + *buffer++ = 0x53A; /* Tag */ + *buffer++ = copy->SrcAddress; + *buffer++ = 0x539; /* Tag */ + *buffer++ = copy->WidthHeight; /* Initiates transfer */ + *buffer++ = 0x53C; /* Tag - DMAOutputAddress */ + *buffer++ = virt_to_phys((void*)screenbuf); + *buffer++ = 0x53D; /* Tag - DMAOutputCount */ + *buffer++ = copy->Count; /* Reads HostOutFifo BLOCKS until ..*/ + + /* Data now sitting in dma->buflist[ GLINT_DRI_BUF_COUNT + 1 ] */ + /* Now put it back to the screen */ + + *buffer++ = 0x180; /* Tag (FilterMode) */ + *buffer++ = 0x400; /* Allow Sync through */ + *buffer++ = 0x538; /* Tag - DMARectangleReadTarget */ + *buffer++ = 0x155; /* FBSourceData | count */ + *buffer++ = 0x537; /* Tag */ + *buffer++ = copy->Pitch; + *buffer++ = 0x536; /* Tag */ + *buffer++ = copy->DstAddress; + *buffer++ = 0x535; /* Tag */ + *buffer++ = copy->WidthHeight; /* Initiates transfer */ + *buffer++ = 0x530; /* Tag - DMAAddr */ + *buffer++ = virt_to_phys((void*)screenbuf); + *buffer++ = 0x531; + *buffer++ = copy->Count; /* initiates DMA transfer of color data */ +#endif + + /* need to dispatch it now */ + + return 0; +} + +int gamma_dma_copy( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_gamma_copy_t copy; + + if ( copy_from_user( ©, (drm_gamma_copy_t *)arg, sizeof(copy) ) ) + return -EFAULT; + + return gamma_do_copy_dma( dev, © ); +} + +/* ============================================================= + * Per Context SAREA Support + */ + +int gamma_getsareactx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_priv_map_t request; + drm_map_t *map; + + if (copy_from_user(&request, + (drm_ctx_priv_map_t *)arg, + sizeof(request))) + return -EFAULT; + + down(&dev->struct_sem); + if ((int)request.ctx_id >= dev->max_context) { + up(&dev->struct_sem); + return -EINVAL; + } + + map = dev->context_sareas[request.ctx_id]; + up(&dev->struct_sem); + + request.handle = map->handle; + if (copy_to_user((drm_ctx_priv_map_t *)arg, &request, sizeof(request))) + return -EFAULT; + return 0; +} + +int gamma_setsareactx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_priv_map_t request; + drm_map_t *map = NULL; + drm_map_list_t *r_list; + struct list_head *list; + + if (copy_from_user(&request, + (drm_ctx_priv_map_t *)arg, + sizeof(request))) + return -EFAULT; + + down(&dev->struct_sem); + r_list = NULL; + list_for_each(list, &dev->maplist->head) { + r_list = (drm_map_list_t *)list; + if(r_list->map && + r_list->map->handle == request.handle) break; + } + if (list == &(dev->maplist->head)) { + up(&dev->struct_sem); + return -EINVAL; + } + map = r_list->map; + up(&dev->struct_sem); + + if (!map) return -EINVAL; + + down(&dev->struct_sem); + if ((int)request.ctx_id >= dev->max_context) { + up(&dev->struct_sem); + return -EINVAL; + } + dev->context_sareas[request.ctx_id] = map; + up(&dev->struct_sem); + return 0; +} + +/* drm_dma.h hooks +*/ +void DRM(driver_irq_preinstall)( drm_device_t *dev ) { +} + +void DRM(driver_irq_postinstall)( drm_device_t *dev ) { +} + +void DRM(driver_irq_uninstall)( drm_device_t *dev ) { +} Index: drivers/char/drm/gamma_drv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/gamma_drv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/gamma_drv.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/gamma_drv.c 4 Aug 2004 01:28:48 -0000 1.2 @@ -32,57 +32,18 @@ #include #include "gamma.h" #include "drmP.h" +#include "drm.h" +#include "gamma_drm.h" #include "gamma_drv.h" -#define DRIVER_AUTHOR "VA Linux Systems Inc." - -#define DRIVER_NAME "gamma" -#define DRIVER_DESC "3DLabs gamma" -#define DRIVER_DATE "20010216" - -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 0 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { gamma_dma, 1, 0 } - - -#define __HAVE_COUNTERS 5 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_DMA -#define __HAVE_COUNTER8 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER9 _DRM_STAT_SPECIAL -#define __HAVE_COUNTER10 _DRM_STAT_MISSED - - #include "drm_auth.h" +#include "drm_agpsupport.h" #include "drm_bufs.h" #include "drm_context.h" #include "drm_dma.h" #include "drm_drawable.h" #include "drm_drv.h" -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init gamma_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", gamma_options ); -#endif - - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" Index: drivers/char/drm/gamma_drv.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/gamma_drv.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/gamma_drv.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/gamma_drv.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -32,8 +32,9 @@ #ifndef _GAMMA_DRV_H_ #define _GAMMA_DRV_H_ - typedef struct drm_gamma_private { + drm_gamma_sarea_t *sarea_priv; + drm_map_t *sarea; drm_map_t *buffers; drm_map_t *mmio0; drm_map_t *mmio1; @@ -51,6 +52,11 @@ } \ } while (0) + /* gamma_dma.c */ +extern int gamma_dma_init( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int gamma_dma_copy( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); extern void gamma_dma_ready(drm_device_t *dev); extern void gamma_dma_quiescent_single(drm_device_t *dev); @@ -63,6 +69,7 @@ extern int gamma_find_devices(void); extern int gamma_found(void); +#define GLINT_DRI_BUF_COUNT 256 #define GAMMA_OFF(reg) \ ((reg < 0x1000) \ @@ -78,7 +85,6 @@ ((reg < 0x10000) ? dev_priv->mmio1->handle : \ ((reg < 0x11000) ? dev_priv->mmio2->handle : \ dev_priv->mmio3->handle)))) - #define GAMMA_ADDR(reg) (GAMMA_BASE(reg) + GAMMA_OFF(reg)) #define GAMMA_DEREF(reg) *(__volatile__ int *)GAMMA_ADDR(reg) #define GAMMA_READ(reg) GAMMA_DEREF(reg) @@ -91,9 +97,11 @@ #define GAMMA_FILTERMODE 0x8c00 #define GAMMA_GCOMMANDINTFLAGS 0x0c50 #define GAMMA_GCOMMANDMODE 0x0c40 +#define GAMMA_QUEUED_DMA_MODE 1<<1 #define GAMMA_GCOMMANDSTATUS 0x0c60 #define GAMMA_GDELAYTIMER 0x0c38 #define GAMMA_GDMACONTROL 0x0060 +#define GAMMA_USE_AGP 1<<1 #define GAMMA_GINTENABLE 0x0808 #define GAMMA_GINTFLAGS 0x0810 #define GAMMA_INFIFOSPACE 0x0018 @@ -101,5 +109,12 @@ #define GAMMA_OUTPUTFIFO 0x2000 #define GAMMA_SYNC 0x8c40 #define GAMMA_SYNC_TAG 0x0188 +#define GAMMA_PAGETABLEADDR 0x0C00 +#define GAMMA_PAGETABLELENGTH 0x0C08 + +#define GAMMA_PASSTHROUGH 0x1FE +#define GAMMA_DMAADDRTAG 0x530 +#define GAMMA_DMACOUNTTAG 0x531 +#define GAMMA_COMMANDINTTAG 0x532 #endif Index: drivers/char/drm/i810.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/i810.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/i810.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/i810.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -41,6 +41,47 @@ #define __HAVE_MTRR 1 #define __HAVE_CTX_BITMAP 1 +#define DRIVER_AUTHOR "VA Linux Systems Inc." + +#define DRIVER_NAME "i810" +#define DRIVER_DESC "Intel i810" +#define DRIVER_DATE "20020211" + +/* Interface history + * + * 1.1 - XFree86 4.1 + * 1.2 - XvMC interfaces + * - XFree86 4.2 + * 1.2.1 - Disable copying code (leave stub ioctls for backwards compatibility) + * - Remove requirement for interrupt (leave stubs again) + */ +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 2 +#define DRIVER_PATCHLEVEL 1 + +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)] = { i810_dma_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_CLEAR)] = { i810_clear_bufs, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)] = { i810_flush_ioctl, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_GETAGE)] = { i810_getage, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)] = { i810_swap_bufs, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)] = { i810_copybuf, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_OV0INFO)] = { i810_ov0_info, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_FSTATUS)] = { i810_fstatus, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_OV0FLIP)] = { i810_ov0_flip, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_MC)] = { i810_dma_mc, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_RSTATUS)] = { i810_rstatus, 1, 0 } + + +#define __HAVE_COUNTERS 4 +#define __HAVE_COUNTER6 _DRM_STAT_IRQ +#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY +#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY +#define __HAVE_COUNTER9 _DRM_STAT_DMA + /* Driver customization: */ #define __HAVE_RELEASE 1 @@ -60,50 +101,10 @@ i810_dma_quiescent( dev ); \ } while (0) -#define __HAVE_DMA_IRQ 1 -#define __HAVE_DMA_IRQ_BH 1 -#define __HAVE_SHARED_IRQ 1 -#define DRIVER_PREINSTALL() do { \ - drm_i810_private_t *dev_priv = \ - (drm_i810_private_t *)dev->dev_private; \ - u16 tmp; \ - tmp = I810_READ16( I810REG_HWSTAM ); \ - tmp = tmp & 0x6000; \ - I810_WRITE16( I810REG_HWSTAM, tmp ); \ - \ - tmp = I810_READ16( I810REG_INT_MASK_R ); \ - tmp = tmp & 0x6000; /* Unmask interrupts */ \ - I810_WRITE16( I810REG_INT_MASK_R, tmp ); \ - tmp = I810_READ16( I810REG_INT_ENABLE_R ); \ - tmp = tmp & 0x6000; /* Disable all interrupts */ \ - I810_WRITE16( I810REG_INT_ENABLE_R, tmp ); \ -} while (0) - -#define DRIVER_POSTINSTALL() do { \ - drm_i810_private_t *dev_priv = \ - (drm_i810_private_t *)dev->dev_private; \ - u16 tmp; \ - tmp = I810_READ16( I810REG_INT_ENABLE_R ); \ - tmp = tmp & 0x6000; \ - tmp = tmp | 0x0003; /* Enable bp & user interrupts */ \ - I810_WRITE16( I810REG_INT_ENABLE_R, tmp ); \ -} while (0) - -#define DRIVER_UNINSTALL() do { \ - drm_i810_private_t *dev_priv = \ - (drm_i810_private_t *)dev->dev_private; \ - u16 tmp; \ - if ( dev_priv ) { \ - tmp = I810_READ16( I810REG_INT_IDENTITY_R ); \ - tmp = tmp & ~(0x6000); /* Clear all interrupts */ \ - if ( tmp != 0 ) \ - I810_WRITE16( I810REG_INT_IDENTITY_R, tmp ); \ - \ - tmp = I810_READ16( I810REG_INT_ENABLE_R ); \ - tmp = tmp & 0x6000; /* Disable all interrupts */ \ - I810_WRITE16( I810REG_INT_ENABLE_R, tmp ); \ - } \ -} while (0) +/* Don't need an irq any more. The template code will make sure that + * a noop stub is generated for compatibility. + */ +#define __HAVE_DMA_IRQ 0 /* Buffer customization: */ Index: drivers/char/drm/i810_dma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/i810_dma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/i810_dma.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/i810_dma.c 4 Aug 2004 01:28:48 -0000 1.2 @@ -26,21 +26,20 @@ * * Authors: Rickard E. (Rik) Faith * Jeff Hartmann - * Keith Whitwell + * Keith Whitwell * */ #include #include "i810.h" #include "drmP.h" +#include "drm.h" +#include "i810_drm.h" #include "i810_drv.h" #include /* For task queue support */ -#include +#include -/* in case we don't have a 2.3.99-pre6 kernel or later: */ -#ifndef VM_DONTCOPY -#define VM_DONTCOPY 0 -#endif +#define DO_MUNMAP(m, a, l) do_munmap(m, a, l) #define I810_BUF_FREE 2 #define I810_BUF_CLIENT 1 @@ -51,29 +50,27 @@ #define RING_LOCALS unsigned int outring, ringmask; volatile char *virt; -#define BEGIN_LP_RING(n) do { \ - if (I810_VERBOSE) \ - DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \ - n, __FUNCTION__); \ - if (dev_priv->ring.space < n*4) \ - i810_wait_ring(dev, n*4); \ - dev_priv->ring.space -= n*4; \ - outring = dev_priv->ring.tail; \ - ringmask = dev_priv->ring.tail_mask; \ - virt = dev_priv->ring.virtual_start; \ +#define BEGIN_LP_RING(n) do { \ + if (0) DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \ + if (dev_priv->ring.space < n*4) \ + i810_wait_ring(dev, n*4); \ + dev_priv->ring.space -= n*4; \ + outring = dev_priv->ring.tail; \ + ringmask = dev_priv->ring.tail_mask; \ + virt = dev_priv->ring.virtual_start; \ } while (0) -#define ADVANCE_LP_RING() do { \ - if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \ - dev_priv->ring.tail = outring; \ - I810_WRITE(LP_RING + RING_TAIL, outring); \ +#define ADVANCE_LP_RING() do { \ + if (0) DRM_DEBUG("ADVANCE_LP_RING\n"); \ + dev_priv->ring.tail = outring; \ + I810_WRITE(LP_RING + RING_TAIL, outring); \ } while(0) -#define OUT_RING(n) do { \ - if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ - *(volatile unsigned int *)(virt + outring) = n; \ - outring += 4; \ - outring &= ringmask; \ +#define OUT_RING(n) do { \ + if (0) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ + *(volatile unsigned int *)(virt + outring) = n; \ + outring += 4; \ + outring &= ringmask; \ } while (0) static inline void i810_print_status_page(drm_device_t *dev) @@ -135,14 +132,14 @@ } static struct file_operations i810_buffer_fops = { - open: DRM(open), - flush: DRM(flush), - release: DRM(release), - ioctl: DRM(ioctl), - mmap: i810_mmap_buffers, - read: DRM(read), - fasync: DRM(fasync), - poll: DRM(poll), + .open = DRM(open), + .flush = DRM(flush), + .release = DRM(release), + .ioctl = DRM(ioctl), + .mmap = i810_mmap_buffers, + .read = DRM(read), + .fasync = DRM(fasync), + .poll = DRM(poll), }; int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) @@ -165,7 +162,7 @@ buf_priv->currently_mapped = I810_BUF_MAPPED; unlock_kernel(); - if (remap_page_range(vma->vm_start, + if (remap_page_range(DRM_RPR_ARG(vma) vma->vm_start, VM_OFFSET(vma), vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; @@ -183,28 +180,31 @@ if(buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL; - if(VM_DONTCOPY != 0) { - down_write( ¤t->mm->mmap_sem ); - old_fops = filp->f_op; - filp->f_op = &i810_buffer_fops; - dev_priv->mmap_buffer = buf; - buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, - PROT_READ|PROT_WRITE, - MAP_SHARED, - buf->bus_address); - dev_priv->mmap_buffer = NULL; - filp->f_op = old_fops; - if ((unsigned long)buf_priv->virtual > -1024UL) { - /* Real error */ - DRM_DEBUG("mmap error\n"); - retcode = (signed int)buf_priv->virtual; - buf_priv->virtual = 0; - } - up_write( ¤t->mm->mmap_sem ); - } else { - buf_priv->virtual = buf_priv->kernel_virtual; - buf_priv->currently_mapped = I810_BUF_MAPPED; + + + + down_write( ¤t->mm->mmap_sem ); + + old_fops = filp->f_op; + filp->f_op = &i810_buffer_fops; + dev_priv->mmap_buffer = buf; + buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, + PROT_READ|PROT_WRITE, + MAP_SHARED, + buf->bus_address); + dev_priv->mmap_buffer = NULL; + filp->f_op = old_fops; + if ((unsigned long)buf_priv->virtual > -1024UL) { + /* Real error */ + DRM_DEBUG("mmap error\n"); + retcode = (signed int)buf_priv->virtual; + buf_priv->virtual = 0; } + + + + up_write( ¤t->mm->mmap_sem ); + return retcode; } @@ -213,15 +213,21 @@ drm_i810_buf_priv_t *buf_priv = buf->dev_private; int retcode = 0; - if(VM_DONTCOPY != 0) { - if(buf_priv->currently_mapped != I810_BUF_MAPPED) - return -EINVAL; - down_write( ¤t->mm->mmap_sem ); - retcode = do_munmap(current->mm, - (unsigned long)buf_priv->virtual, - (size_t) buf->total); - up_write( ¤t->mm->mmap_sem ); - } + if(buf_priv->currently_mapped != I810_BUF_MAPPED) + return -EINVAL; + + + + down_write( ¤t->mm->mmap_sem ); + + retcode = DO_MUNMAP(current->mm, + (unsigned long)buf_priv->virtual, + (size_t) buf->total); + + + + up_write( ¤t->mm->mmap_sem ); + buf_priv->currently_mapped = I810_BUF_UNMAPPED; buf_priv->virtual = 0; @@ -270,11 +276,12 @@ if(dev_priv->ring.virtual_start) { DRM(ioremapfree)((void *) dev_priv->ring.virtual_start, - dev_priv->ring.Size); + dev_priv->ring.Size, dev); } if(dev_priv->hw_status_page != 0UL) { - pci_free_consistent(dev->pdev, PAGE_SIZE, (void *)dev_priv->hw_status_page, - dev_priv->dma_status_page); + pci_free_consistent(dev->pdev, PAGE_SIZE, + (void *)dev_priv->hw_status_page, + dev_priv->dma_status_page); /* Need to rewrite hardware status page */ I810_WRITE(0x02080, 0x1ffff000); } @@ -285,7 +292,7 @@ for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total); + DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total, dev); } } return 0; @@ -301,8 +308,6 @@ end = jiffies + (HZ*3); while (ring->space < n) { - int i; - ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; ring->space = ring->head - (ring->tail+8); if (ring->space < 0) ring->space += ring->Size; @@ -311,13 +316,12 @@ end = jiffies + (HZ*3); iters++; - if((signed)(end - jiffies) <= 0) { + if(time_before(end, jiffies)) { DRM_ERROR("space: %d wanted %d\n", ring->space, n); DRM_ERROR("lockup\n"); goto out_wait_ring; } - - for (i = 0 ; i < 2000 ; i++) ; + udelay(1); } out_wait_ring: @@ -358,7 +362,7 @@ *buf_priv->in_use = I810_BUF_FREE; buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address, - buf->total); + buf->total, dev); } return 0; } @@ -405,16 +409,13 @@ ((u8 *)dev_priv->sarea_map->handle + init->sarea_priv_offset); - atomic_set(&dev_priv->flush_done, 0); - init_waitqueue_head(&dev_priv->flush_queue); - dev_priv->ring.Start = init->ring_start; dev_priv->ring.End = init->ring_end; dev_priv->ring.Size = init->ring_size; dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base + init->ring_start, - init->ring_size); + init->ring_size, dev); if (dev_priv->ring.virtual_start == NULL) { dev->dev_private = (void *) dev_priv; @@ -440,8 +441,9 @@ dev_priv->zi1 = init->depth_offset | init->pitch_bits; /* Program Hardware Status Page */ - dev_priv->hw_status_page = (unsigned long)pci_alloc_consistent(dev->pdev, PAGE_SIZE, - &dev_priv->dma_status_page); + dev_priv->hw_status_page = + (unsigned long) pci_alloc_consistent(dev->pdev, PAGE_SIZE, + &dev_priv->dma_status_page); if(dev_priv->hw_status_page == 0UL) { dev->dev_private = (void *)dev_priv; i810_dma_cleanup(dev); @@ -451,7 +453,7 @@ memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE); DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page); - I810_WRITE(0x02080, dev_priv->dma_status_page); + I810_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); /* Now we need to init our freelist */ @@ -532,16 +534,12 @@ /* Most efficient way to verify state for the i810 is as it is * emitted. Non-conformant state is silently dropped. - * - * Use 'volatile' & local var tmp to force the emitted values to be - * identical to the verified ones. */ static void i810EmitContextVerified( drm_device_t *dev, - volatile unsigned int *code ) + unsigned int *code ) { drm_i810_private_t *dev_priv = dev->dev_private; int i, j = 0; - unsigned int tmp; RING_LOCALS; BEGIN_LP_RING( I810_CTX_SETUP_SIZE ); @@ -553,14 +551,13 @@ OUT_RING( code[I810_CTXREG_ST1] ); for ( i = 4 ; i < I810_CTX_SETUP_SIZE ; i++ ) { - tmp = code[i]; - - if ((tmp & (7<<29)) == (3<<29) && - (tmp & (0x1f<<24)) < (0x1d<<24)) + if ((code[i] & (7<<29)) == (3<<29) && + (code[i] & (0x1f<<24)) < (0x1d<<24)) { - OUT_RING( tmp ); + OUT_RING( code[i] ); j++; } + else printk("constext state dropped!!!\n"); } if (j & 1) @@ -574,7 +571,6 @@ { drm_i810_private_t *dev_priv = dev->dev_private; int i, j = 0; - unsigned int tmp; RING_LOCALS; BEGIN_LP_RING( I810_TEX_SETUP_SIZE ); @@ -585,14 +581,14 @@ OUT_RING( code[I810_TEXREG_MI3] ); for ( i = 4 ; i < I810_TEX_SETUP_SIZE ; i++ ) { - tmp = code[i]; - if ((tmp & (7<<29)) == (3<<29) && - (tmp & (0x1f<<24)) < (0x1d<<24)) + if ((code[i] & (7<<29)) == (3<<29) && + (code[i] & (0x1f<<24)) < (0x1d<<24)) { - OUT_RING( tmp ); + OUT_RING( code[i] ); j++; } + else printk("texture state dropped!!!\n"); } if (j & 1) @@ -617,9 +613,9 @@ if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) { OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING( tmp ); - } else - DRM_DEBUG("bad di1 %x (allow %x or %x)\n", - tmp, dev_priv->front_di1, dev_priv->back_di1); + } + else + printk("buffer state dropped\n"); /* invarient: */ @@ -704,7 +700,6 @@ continue; if ( flags & I810_FRONT ) { - DRM_DEBUG("clear front\n"); BEGIN_LP_RING( 6 ); OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); @@ -717,7 +712,6 @@ } if ( flags & I810_BACK ) { - DRM_DEBUG("clear back\n"); BEGIN_LP_RING( 6 ); OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); @@ -730,7 +724,6 @@ } if ( flags & I810_DEPTH ) { - DRM_DEBUG("clear depth\n"); BEGIN_LP_RING( 6 ); OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); @@ -756,8 +749,6 @@ int i; RING_LOCALS; - DRM_DEBUG("swapbuffers\n"); - i810_kernel_lost_context(dev); if (nbox > I810_NR_SAREA_CLIPRECTS) @@ -776,10 +767,6 @@ pbox->y2 > dev_priv->h) continue; - DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n", - pbox[i].x1, pbox[i].y1, - pbox[i].x2, pbox[i].y2); - BEGIN_LP_RING( 6 ); OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 ); OUT_RING( pitch | (0xCC << 16)); @@ -804,7 +791,7 @@ int nbox = sarea_priv->nbox; unsigned long address = (unsigned long)buf->bus_address; unsigned long start = address - dev->agp->base; - int i = 0, u; + int i = 0; RING_LOCALS; i810_kernel_lost_context(dev); @@ -812,33 +799,16 @@ if (nbox > I810_NR_SAREA_CLIPRECTS) nbox = I810_NR_SAREA_CLIPRECTS; - if (discard) { - u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, - I810_BUF_HARDWARE); - if(u != I810_BUF_CLIENT) { - DRM_DEBUG("xxxx 2\n"); - } - } - if (used > 4*1024) used = 0; if (sarea_priv->dirty) i810EmitState( dev ); - DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", - address, used, nbox); - - dev_priv->counter++; - DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter); - DRM_DEBUG( "i810_dma_dispatch\n"); - DRM_DEBUG( "start : %lx\n", start); - DRM_DEBUG( "used : %d\n", used); - DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4); - if (buf_priv->currently_mapped == I810_BUF_MAPPED) { - *(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE | - sarea_priv->vertex_prim | + unsigned int prim = (sarea_priv->vertex_prim & PR_MASK); + + *(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE | prim | ((used/4)-2)); if (used & 4) { @@ -871,154 +841,62 @@ } while (++i < nbox); } - BEGIN_LP_RING(10); - OUT_RING( CMD_STORE_DWORD_IDX ); - OUT_RING( 20 ); - OUT_RING( dev_priv->counter ); - OUT_RING( 0 ); - if (discard) { + dev_priv->counter++; + + (void) cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, + I810_BUF_HARDWARE); + + BEGIN_LP_RING(8); + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( 20 ); + OUT_RING( dev_priv->counter ); OUT_RING( CMD_STORE_DWORD_IDX ); OUT_RING( buf_priv->my_use_idx ); OUT_RING( I810_BUF_FREE ); + OUT_RING( CMD_REPORT_HEAD ); OUT_RING( 0 ); + ADVANCE_LP_RING(); } - - OUT_RING( CMD_REPORT_HEAD ); - OUT_RING( 0 ); - ADVANCE_LP_RING(); -} - - -/* Interrupts are only for flushing */ -void i810_dma_service(int irq, void *device, struct pt_regs *regs) -{ - drm_device_t *dev = (drm_device_t *)device; - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - u16 temp; - - atomic_inc(&dev->counts[_DRM_STAT_IRQ]); - temp = I810_READ16(I810REG_INT_IDENTITY_R); - temp = temp & ~(0x6000); - if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R, - temp); /* Clear all interrupts */ - else - return; - - queue_task(&dev->tq, &tq_immediate); - mark_bh(IMMEDIATE_BH); } -void i810_dma_immediate_bh(void *device) -{ - drm_device_t *dev = (drm_device_t *) device; - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - - atomic_set(&dev_priv->flush_done, 1); - wake_up_interruptible(&dev_priv->flush_queue); -} - -static inline void i810_dma_emit_flush(drm_device_t *dev) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - i810_kernel_lost_context(dev); - - BEGIN_LP_RING(2); - OUT_RING( CMD_REPORT_HEAD ); - OUT_RING( GFX_OP_USER_INTERRUPT ); - ADVANCE_LP_RING(); - -/* i810_wait_ring( dev, dev_priv->ring.Size - 8 ); */ -/* atomic_set(&dev_priv->flush_done, 1); */ -/* wake_up_interruptible(&dev_priv->flush_queue); */ -} - -static inline void i810_dma_quiescent_emit(drm_device_t *dev) +void i810_dma_quiescent(drm_device_t *dev) { drm_i810_private_t *dev_priv = dev->dev_private; RING_LOCALS; +/* printk("%s\n", __FUNCTION__); */ + i810_kernel_lost_context(dev); BEGIN_LP_RING(4); OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); OUT_RING( CMD_REPORT_HEAD ); OUT_RING( 0 ); - OUT_RING( GFX_OP_USER_INTERRUPT ); + OUT_RING( 0 ); ADVANCE_LP_RING(); -/* i810_wait_ring( dev, dev_priv->ring.Size - 8 ); */ -/* atomic_set(&dev_priv->flush_done, 1); */ -/* wake_up_interruptible(&dev_priv->flush_queue); */ -} - -void i810_dma_quiescent(drm_device_t *dev) -{ - DECLARE_WAITQUEUE(entry, current); - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - unsigned long end; - - if(dev_priv == NULL) { - return; - } - atomic_set(&dev_priv->flush_done, 0); - add_wait_queue(&dev_priv->flush_queue, &entry); - end = jiffies + (HZ*3); - - for (;;) { - current->state = TASK_INTERRUPTIBLE; - i810_dma_quiescent_emit(dev); - if (atomic_read(&dev_priv->flush_done) == 1) break; - if((signed)(end - jiffies) <= 0) { - DRM_ERROR("lockup\n"); - break; - } - schedule_timeout(HZ*3); - if (signal_pending(current)) { - break; - } - } - - current->state = TASK_RUNNING; - remove_wait_queue(&dev_priv->flush_queue, &entry); - - return; + i810_wait_ring( dev, dev_priv->ring.Size - 8 ); } static int i810_flush_queue(drm_device_t *dev) { - DECLARE_WAITQUEUE(entry, current); - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + drm_i810_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; - unsigned long end; int i, ret = 0; + RING_LOCALS; + +/* printk("%s\n", __FUNCTION__); */ - if(dev_priv == NULL) { - return 0; - } - atomic_set(&dev_priv->flush_done, 0); - add_wait_queue(&dev_priv->flush_queue, &entry); - end = jiffies + (HZ*3); - for (;;) { - current->state = TASK_INTERRUPTIBLE; - i810_dma_emit_flush(dev); - if (atomic_read(&dev_priv->flush_done) == 1) break; - if((signed)(end - jiffies) <= 0) { - DRM_ERROR("lockup\n"); - break; - } - schedule_timeout(HZ*3); - if (signal_pending(current)) { - ret = -EINTR; /* Can't restart */ - break; - } - } + i810_kernel_lost_context(dev); - current->state = TASK_RUNNING; - remove_wait_queue(&dev_priv->flush_queue, &entry); + BEGIN_LP_RING(2); + OUT_RING( CMD_REPORT_HEAD ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + i810_wait_ring( dev, dev_priv->ring.Size - 8 ); for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; @@ -1030,7 +908,7 @@ if (used == I810_BUF_HARDWARE) DRM_DEBUG("reclaimed from HARDWARE\n"); if (used == I810_BUF_CLIENT) - DRM_DEBUG("still on client HARDWARE\n"); + DRM_DEBUG("still on client\n"); } return ret; @@ -1070,7 +948,6 @@ drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - DRM_DEBUG("i810_flush_ioctl\n"); if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("i810_flush_ioctl called without lock held\n"); return -EINVAL; @@ -1101,9 +978,6 @@ return -EINVAL; } - DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n", - vertex.idx, vertex.used, vertex.discard); - if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL; i810_dma_dispatch_vertex( dev, @@ -1152,8 +1026,6 @@ drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - DRM_DEBUG("i810_swap_bufs\n"); - if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("i810_swap_buf called without lock held\n"); return -EINVAL; @@ -1189,7 +1061,6 @@ drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) dev_priv->sarea_priv; - DRM_DEBUG("getbuf\n"); if (copy_from_user(&d, (drm_i810_dma_t *)arg, sizeof(d))) return -EFAULT; @@ -1202,9 +1073,6 @@ retcode = i810_dma_get_buffer(dev, &d, filp); - DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n", - current->pid, retcode, d.granted); - if (copy_to_user((drm_dma_t *)arg, &d, sizeof(d))) return -EFAULT; sarea_priv->last_dispatch = (int) hw_status[5]; @@ -1212,47 +1080,19 @@ return retcode; } -int i810_copybuf(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) +int i810_copybuf(struct inode *inode, + struct file *filp, + unsigned int cmd, + unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_i810_copy_t d; - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - u32 *hw_status = (u32 *)dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; - drm_buf_t *buf; - drm_i810_buf_priv_t *buf_priv; - drm_device_dma_t *dma = dev->dma; - - if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("i810_dma called without lock held\n"); - return -EINVAL; - } - - if (copy_from_user(&d, (drm_i810_copy_t *)arg, sizeof(d))) - return -EFAULT; - - if(d.idx < 0 || d.idx > dma->buf_count) return -EINVAL; - buf = dma->buflist[ d.idx ]; - buf_priv = buf->dev_private; - if (buf_priv->currently_mapped != I810_BUF_MAPPED) return -EPERM; - - if(d.used < 0 || d.used > buf->total) return -EINVAL; - - if (copy_from_user(buf_priv->virtual, d.address, d.used)) - return -EFAULT; - - sarea_priv->last_dispatch = (int) hw_status[5]; - + /* Never copy - 2.4.x doesn't need it */ return 0; } int i810_docopy(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { - if(VM_DONTCOPY == 0) return 1; + /* Never copy - 2.4.x doesn't need it */ return 0; } @@ -1371,7 +1211,8 @@ data.offset = dev_priv->overlay_offset; data.physical = dev_priv->overlay_physical; - copy_to_user((drm_i810_overlay_t *)arg,&data,sizeof(data)); + if (copy_to_user((drm_i810_overlay_t *)arg,&data,sizeof(data))) + return -EFAULT; return 0; } Index: drivers/char/drm/i810_drm.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/i810_drm.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/i810_drm.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/i810_drm.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -88,6 +88,8 @@ #define I810_TEXREG_MCS 7 /* GFX_OP_MAP_COORD_SETS ??? */ #define I810_TEX_SETUP_SIZE 8 +/* Flags for clear ioctl + */ #define I810_FRONT 0x1 #define I810_BACK 0x2 #define I810_DEPTH 0x4 @@ -166,14 +168,34 @@ } drm_i810_sarea_t; +/* WARNING: If you change any of these defines, make sure to wear a bullet + * proof vest since these are part of the stable kernel<->userspace ABI + */ + +/* i810 specific ioctls + * The device specific ioctl range is 0x40 to 0x79. + */ +#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t) +#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t) +#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t) +#define DRM_IOCTL_I810_FLUSH DRM_IO( 0x43) +#define DRM_IOCTL_I810_GETAGE DRM_IO( 0x44) +#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t) +#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46) +#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t) +#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48) +#define DRM_IOCTL_I810_OV0INFO DRM_IOR( 0x49, drm_i810_overlay_t) +#define DRM_IOCTL_I810_FSTATUS DRM_IO ( 0x4a) +#define DRM_IOCTL_I810_OV0FLIP DRM_IO ( 0x4b) +#define DRM_IOCTL_I810_MC DRM_IOW( 0x4c, drm_i810_mc_t) +#define DRM_IOCTL_I810_RSTATUS DRM_IO ( 0x4d ) + typedef struct _drm_i810_clear { int clear_color; int clear_depth; int flags; } drm_i810_clear_t; - - /* These may be placeholders if we have more cliprects than * I810_NR_SAREA_CLIPRECTS. In that case, the client sets discard to * false, indicating that the buffer will be dispatched again with a @@ -191,6 +213,17 @@ void *address; /* Address to copy from */ } drm_i810_copy_t; +#define PR_TRIANGLES (0x0<<18) +#define PR_TRISTRIP_0 (0x1<<18) +#define PR_TRISTRIP_1 (0x2<<18) +#define PR_TRIFAN (0x3<<18) +#define PR_POLYGON (0x4<<18) +#define PR_LINES (0x5<<18) +#define PR_LINESTRIP (0x6<<18) +#define PR_RECTS (0x7<<18) +#define PR_MASK (0x7<<18) + + typedef struct drm_i810_dma { void *virtual; int request_idx; Index: drivers/char/drm/i810_drv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/i810_drv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/i810_drv.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/i810_drv.c 4 Aug 2004 01:28:48 -0000 1.2 @@ -33,42 +33,10 @@ #include #include "i810.h" #include "drmP.h" +#include "drm.h" +#include "i810_drm.h" #include "i810_drv.h" -#define DRIVER_AUTHOR "VA Linux Systems Inc." - -#define DRIVER_NAME "i810" -#define DRIVER_DESC "Intel i810" -#define DRIVER_DATE "20010920" - -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 0 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)] = { i810_dma_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_CLEAR)] = { i810_clear_bufs, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)] = { i810_flush_ioctl, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_GETAGE)] = { i810_getage, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)] = { i810_swap_bufs, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)] = { i810_copybuf, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_OV0INFO)] = { i810_ov0_info, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_FSTATUS)] = { i810_fstatus, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_OV0FLIP)] = { i810_ov0_flip, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_MC)] = { i810_dma_mc, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_RSTATUS)] = { i810_rstatus, 1, 0 } - - -#define __HAVE_COUNTERS 4 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY -#define __HAVE_COUNTER9 _DRM_STAT_DMA - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -77,25 +45,6 @@ #include "drm_drawable.h" #include "drm_drv.h" -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init i810_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", i810_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" Index: drivers/char/drm/i810_drv.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/i810_drv.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/i810_drv.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/i810_drv.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -63,10 +63,9 @@ unsigned long hw_status_page; unsigned long counter; - dma_addr_t dma_status_page; - atomic_t flush_done; - wait_queue_head_t flush_queue; /* Processes waiting until flush */ + dma_addr_t dma_status_page; + drm_buf_t *mmap_buffer; @@ -78,6 +77,7 @@ int overlay_physical; int w, h; int pitch; + } drm_i810_private_t; /* i810_dma.c */ @@ -92,8 +92,13 @@ extern int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma); + +/* Obsolete: + */ extern int i810_copybuf(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +/* Obsolete: + */ extern int i810_docopy(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); @@ -111,9 +116,6 @@ extern void i810_dma_quiescent(drm_device_t *dev); -#define I810_VERBOSE 0 - - int i810_dma_vertex(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); @@ -196,6 +198,7 @@ #define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23)) #define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23)) +#define CMD_OP_FRONTBUFFER_INFO ((0x0<<29)|(0x14<<23)) #define BR00_BITBLT_CLIENT 0x40000000 #define BR00_OP_COLOR_BLT 0x10000000 Index: drivers/char/drm/i830.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/i830.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/i830.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/i830.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -41,6 +41,48 @@ #define __HAVE_MTRR 1 #define __HAVE_CTX_BITMAP 1 +#define DRIVER_AUTHOR "VA Linux Systems Inc." + +#define DRIVER_NAME "i830" +#define DRIVER_DESC "Intel 830M" +#define DRIVER_DATE "20021108" + +/* Interface history: + * + * 1.1: Original. + * 1.2: ? + * 1.3: New irq emit/wait ioctls. + * New pageflip ioctl. + * New getparam ioctl. + * State for texunits 3&4 in sarea. + * New (alternative) layout for texture state. + */ +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 3 +#define DRIVER_PATCHLEVEL 2 + +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_INIT)] = { i830_dma_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_VERTEX)] = { i830_dma_vertex, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_CLEAR)] = { i830_clear_bufs, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_FLUSH)] = { i830_flush_ioctl, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_GETAGE)] = { i830_getage, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_GETBUF)] = { i830_getbuf, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_SWAP)] = { i830_swap_bufs, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_COPY)] = { i830_copybuf, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_DOCOPY)] = { i830_docopy, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_FLIP)] = { i830_flip_bufs, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_IRQ_EMIT)] = { i830_irq_emit, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_IRQ_WAIT)] = { i830_irq_wait, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_GETPARAM)] = { i830_getparam, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_SETPARAM)] = { i830_setparam, 1, 0 } + +#define __HAVE_COUNTERS 4 +#define __HAVE_COUNTER6 _DRM_STAT_IRQ +#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY +#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY +#define __HAVE_COUNTER9 _DRM_STAT_DMA + /* Driver customization: */ #define __HAVE_RELEASE 1 @@ -60,51 +102,50 @@ i830_dma_quiescent( dev ); \ } while (0) + +/* Driver will work either way: IRQ's save cpu time when waiting for + * the card, but are subject to subtle interactions between bios, + * hardware and the driver. + */ +#define USE_IRQS 0 + + +#if USE_IRQS #define __HAVE_DMA_IRQ 1 -#define __HAVE_DMA_IRQ_BH 1 -#define __HAVE_SHARED_IRQ 1 -#define DRIVER_PREINSTALL() do { \ - drm_i830_private_t *dev_priv = \ - (drm_i830_private_t *)dev->dev_private; \ - u16 tmp; \ - tmp = I830_READ16( I830REG_HWSTAM ); \ - tmp = tmp & 0x6000; \ - I830_WRITE16( I830REG_HWSTAM, tmp ); \ - \ - tmp = I830_READ16( I830REG_INT_MASK_R ); \ - tmp = tmp & 0x6000; /* Unmask interrupts */ \ - I830_WRITE16( I830REG_INT_MASK_R, tmp ); \ - tmp = I830_READ16( I830REG_INT_ENABLE_R ); \ - tmp = tmp & 0x6000; /* Disable all interrupts */ \ - I830_WRITE16( I830REG_INT_ENABLE_R, tmp ); \ -} while (0) +#define __HAVE_SHARED_IRQ 1 -#define DRIVER_POSTINSTALL() do { \ - drm_i830_private_t *dev_priv = \ +#define DRIVER_PREINSTALL() do { \ + drm_i830_private_t *dev_priv = \ (drm_i830_private_t *)dev->dev_private; \ - u16 tmp; \ - tmp = I830_READ16( I830REG_INT_ENABLE_R ); \ - tmp = tmp & 0x6000; \ - tmp = tmp | 0x0003; /* Enable bp & user interrupts */ \ - I830_WRITE16( I830REG_INT_ENABLE_R, tmp ); \ + \ + I830_WRITE16( I830REG_HWSTAM, 0xffff ); \ + I830_WRITE16( I830REG_INT_MASK_R, 0x0 ); \ + I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 ); \ } while (0) -#define DRIVER_UNINSTALL() do { \ - drm_i830_private_t *dev_priv = \ - (drm_i830_private_t *)dev->dev_private; \ - u16 tmp; \ - if ( dev_priv ) { \ - tmp = I830_READ16( I830REG_INT_IDENTITY_R ); \ - tmp = tmp & ~(0x6000); /* Clear all interrupts */ \ - if ( tmp != 0 ) \ - I830_WRITE16( I830REG_INT_IDENTITY_R, tmp ); \ - \ - tmp = I830_READ16( I830REG_INT_ENABLE_R ); \ - tmp = tmp & 0x6000; /* Disable all interrupts */ \ - I830_WRITE16( I830REG_INT_ENABLE_R, tmp ); \ - } \ + +#define DRIVER_POSTINSTALL() do { \ + drm_i830_private_t *dev_priv = \ + (drm_i830_private_t *)dev->dev_private; \ + I830_WRITE16( I830REG_INT_ENABLE_R, 0x2 ); \ + atomic_set(&dev_priv->irq_received, 0); \ + atomic_set(&dev_priv->irq_emitted, 0); \ + init_waitqueue_head(&dev_priv->irq_queue); \ } while (0) + +/* This gets called too late to be useful: dev_priv has already been + * freed. + */ +#define DRIVER_UNINSTALL() do { \ +} while (0) + +#else +#define __HAVE_DMA_IRQ 0 +#endif + + + /* Buffer customization: */ Index: drivers/char/drm/i830_dma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/i830_dma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/i830_dma.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/i830_dma.c 4 Aug 2004 01:28:48 -0000 1.2 @@ -26,20 +26,22 @@ * * Authors: Rickard E. (Rik) Faith * Jeff Hartmann - * Keith Whitwell - * Abraham vd Merwe + * Keith Whitwell + * Abraham vd Merwe * */ + #include "i830.h" #include "drmP.h" +#include "drm.h" +#include "i830_drm.h" #include "i830_drv.h" #include /* For task queue support */ +#include /* For FASTCALL on unlock_page() */ #include -/* in case we don't have a 2.3.99-pre6 kernel or later: */ -#ifndef VM_DONTCOPY -#define VM_DONTCOPY 0 -#endif + +#define DO_MUNMAP(m, a, l) do_munmap(m, a, l) #define I830_BUF_FREE 2 #define I830_BUF_CLIENT 1 @@ -48,54 +50,24 @@ #define I830_BUF_UNMAPPED 0 #define I830_BUF_MAPPED 1 -#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt; -#define DO_IDLE_WORKAROUND() \ -do { \ - int _head; \ - int _tail; \ - do { \ - _head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; \ - _tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR; \ - udelay(1); \ - } while(_head != _tail); \ -} while(0) - -#define I830_SYNC_WORKAROUND 0 - -#define BEGIN_LP_RING(n) do { \ - if (I830_VERBOSE) \ - DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \ - n, __FUNCTION__); \ - if (I830_SYNC_WORKAROUND) \ - DO_IDLE_WORKAROUND(); \ - if (dev_priv->ring.space < n*4) \ - i830_wait_ring(dev, n*4); \ - dev_priv->ring.space -= n*4; \ - outring = dev_priv->ring.tail; \ - ringmask = dev_priv->ring.tail_mask; \ - virt = dev_priv->ring.virtual_start; \ -} while (0) - -#define ADVANCE_LP_RING() do { \ - if (I830_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \ - dev_priv->ring.tail = outring; \ - I830_WRITE(LP_RING + RING_TAIL, outring); \ -} while(0) - -#define OUT_RING(n) do { \ - if (I830_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ - *(volatile unsigned int *)(virt + outring) = n; \ - outring += 4; \ - outring &= ringmask; \ -} while (0); + + + + + + + + + + static inline void i830_print_status_page(drm_device_t *dev) { drm_device_dma_t *dma = dev->dma; drm_i830_private_t *dev_priv = dev->dev_private; - u8 *temp = dev_priv->hw_status_page; + u32 *temp = (u32 *)dev_priv->hw_status_page; int i; DRM_DEBUG( "hw_status: Interrupt Status : %x\n", temp[0]); @@ -149,14 +121,14 @@ } static struct file_operations i830_buffer_fops = { - open: DRM(open), - flush: DRM(flush), - release: DRM(release), - ioctl: DRM(ioctl), - mmap: i830_mmap_buffers, - read: DRM(read), - fasync: DRM(fasync), - poll: DRM(poll), + .open = DRM(open), + .flush = DRM(flush), + .release = DRM(release), + .ioctl = DRM(ioctl), + .mmap = i830_mmap_buffers, + .read = DRM(read), + .fasync = DRM(fasync), + .poll = DRM(poll), }; int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) @@ -179,7 +151,7 @@ buf_priv->currently_mapped = I830_BUF_MAPPED; unlock_kernel(); - if (remap_page_range(vma->vm_start, + if (remap_page_range(DRM_RPR_ARG(vma) vma->vm_start, VM_OFFSET(vma), vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; @@ -197,28 +169,24 @@ if(buf_priv->currently_mapped == I830_BUF_MAPPED) return -EINVAL; - if(VM_DONTCOPY != 0) { - down_write( ¤t->mm->mmap_sem ); - old_fops = filp->f_op; - filp->f_op = &i830_buffer_fops; - dev_priv->mmap_buffer = buf; - buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, - PROT_READ|PROT_WRITE, - MAP_SHARED, - buf->bus_address); - dev_priv->mmap_buffer = NULL; - filp->f_op = old_fops; - if ((unsigned long)buf_priv->virtual > -1024UL) { - /* Real error */ - DRM_DEBUG("mmap error\n"); - retcode = (signed int)buf_priv->virtual; - buf_priv->virtual = 0; - } - up_write( ¤t->mm->mmap_sem ); - } else { - buf_priv->virtual = buf_priv->kernel_virtual; - buf_priv->currently_mapped = I830_BUF_MAPPED; + down_write( ¤t->mm->mmap_sem ); + old_fops = filp->f_op; + filp->f_op = &i830_buffer_fops; + dev_priv->mmap_buffer = buf; + buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, + PROT_READ|PROT_WRITE, + MAP_SHARED, + buf->bus_address); + dev_priv->mmap_buffer = NULL; + filp->f_op = old_fops; + if ((unsigned long)buf_priv->virtual > -1024UL) { + /* Real error */ + DRM_ERROR("mmap error\n"); + retcode = (signed int)buf_priv->virtual; + buf_priv->virtual = 0; } + up_write( ¤t->mm->mmap_sem ); + return retcode; } @@ -227,15 +195,15 @@ drm_i830_buf_priv_t *buf_priv = buf->dev_private; int retcode = 0; - if(VM_DONTCOPY != 0) { - if(buf_priv->currently_mapped != I830_BUF_MAPPED) - return -EINVAL; - down_write( ¤t->mm->mmap_sem ); - retcode = do_munmap(current->mm, - (unsigned long)buf_priv->virtual, - (size_t) buf->total); - up_write( ¤t->mm->mmap_sem ); - } + if(buf_priv->currently_mapped != I830_BUF_MAPPED) + return -EINVAL; + + down_write(¤t->mm->mmap_sem); + retcode = DO_MUNMAP(current->mm, + (unsigned long)buf_priv->virtual, + (size_t) buf->total); + up_write(¤t->mm->mmap_sem); + buf_priv->currently_mapped = I830_BUF_UNMAPPED; buf_priv->virtual = 0; @@ -260,7 +228,7 @@ retcode = i830_map_buffer(buf, filp); if(retcode) { i830_freelist_put(dev, buf); - DRM_DEBUG("mapbuf failed, retcode %d\n", retcode); + DRM_ERROR("mapbuf failed, retcode %d\n", retcode); return retcode; } buf->pid = priv->pid; @@ -284,14 +252,24 @@ if(dev_priv->ring.virtual_start) { DRM(ioremapfree)((void *) dev_priv->ring.virtual_start, - dev_priv->ring.Size); + dev_priv->ring.Size, dev); } - if(dev_priv->hw_status_page != NULL) { - pci_free_consistent(dev->pdev, PAGE_SIZE, - dev_priv->hw_status_page, dev_priv->dma_status_page); + if(dev_priv->hw_status_page != 0UL) { + pci_free_consistent(dev->pdev, PAGE_SIZE, + (void *)dev_priv->hw_status_page, + dev_priv->dma_status_page); /* Need to rewrite hardware status page */ I830_WRITE(0x02080, 0x1ffff000); } + + /* Disable interrupts here because after dev_private + * is freed, it's too late. + */ + if (dev->irq) { + I830_WRITE16( I830REG_INT_MASK_R, 0xffff ); + I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 ); + } + DRM(free)(dev->dev_private, sizeof(drm_i830_private_t), DRM_MEM_DRIVER); dev->dev_private = NULL; @@ -299,13 +277,13 @@ for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; drm_i830_buf_priv_t *buf_priv = buf->dev_private; - DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total); + DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total, dev); } } return 0; } -static int i830_wait_ring(drm_device_t *dev, int n) +int i830_wait_ring(drm_device_t *dev, int n, const char *caller) { drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_ring_buffer_t *ring = &(dev_priv->ring); @@ -314,7 +292,7 @@ unsigned int last_head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; end = jiffies + (HZ*3); - while (ring->space < n) { + while (ring->space < n) { ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; ring->space = ring->head - (ring->tail+8); if (ring->space < 0) ring->space += ring->Size; @@ -325,13 +303,13 @@ } iters++; - if(time_before(end,jiffies)) { + if(time_before(end, jiffies)) { DRM_ERROR("space: %d wanted %d\n", ring->space, n); DRM_ERROR("lockup\n"); goto out_wait_ring; } - - udelay(1); + udelay(1); + dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT; } out_wait_ring: @@ -344,9 +322,12 @@ drm_i830_ring_buffer_t *ring = &(dev_priv->ring); ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - ring->tail = I830_READ(LP_RING + RING_TAIL); + ring->tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR; ring->space = ring->head - (ring->tail+8); if (ring->space < 0) ring->space += ring->Size; + + if (ring->head == ring->tail) + dev_priv->sarea_priv->perf_boxes |= I830_BOX_RING_EMPTY; } static int i830_freelist_init(drm_device_t *dev, drm_i830_private_t *dev_priv) @@ -372,7 +353,7 @@ *buf_priv->in_use = I830_BUF_FREE; buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address, - buf->total); + buf->total, dev); } return 0; } @@ -420,16 +401,13 @@ ((u8 *)dev_priv->sarea_map->handle + init->sarea_priv_offset); - atomic_set(&dev_priv->flush_done, 0); - init_waitqueue_head(&dev_priv->flush_queue); - dev_priv->ring.Start = init->ring_start; dev_priv->ring.End = init->ring_end; dev_priv->ring.Size = init->ring_size; dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base + init->ring_start, - init->ring_size); + init->ring_size, dev); if (dev_priv->ring.virtual_start == NULL) { dev->dev_private = (void *) dev_priv; @@ -446,11 +424,17 @@ dev_priv->pitch = init->pitch; dev_priv->back_offset = init->back_offset; dev_priv->depth_offset = init->depth_offset; + dev_priv->front_offset = init->front_offset; dev_priv->front_di1 = init->front_offset | init->pitch_bits; dev_priv->back_di1 = init->back_offset | init->pitch_bits; dev_priv->zi1 = init->depth_offset | init->pitch_bits; + DRM_DEBUG("front_di1 %x\n", dev_priv->front_di1); + DRM_DEBUG("back_offset %x\n", dev_priv->back_offset); + DRM_DEBUG("back_di1 %x\n", dev_priv->back_di1); + DRM_DEBUG("pitch_bits %x\n", init->pitch_bits); + dev_priv->cpp = init->cpp; /* We are using seperate values as placeholders for mechanisms for * private backbuffer/depthbuffer usage. @@ -458,20 +442,23 @@ dev_priv->back_pitch = init->back_pitch; dev_priv->depth_pitch = init->depth_pitch; + dev_priv->do_boxes = 0; + dev_priv->use_mi_batchbuffer_start = 0; /* Program Hardware Status Page */ - dev_priv->hw_status_page = pci_alloc_consistent(dev->pdev, PAGE_SIZE, + dev_priv->hw_status_page = + (unsigned long) pci_alloc_consistent(dev->pdev, PAGE_SIZE, &dev_priv->dma_status_page); - if(dev_priv->hw_status_page == NULL) { + if(dev_priv->hw_status_page == 0UL) { dev->dev_private = (void *)dev_priv; i830_dma_cleanup(dev); DRM_ERROR("Can not allocate hardware status page\n"); return -ENOMEM; } - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); + memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE); + DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page); - I830_WRITE(0x02080, dev_priv->dma_status_page); + I830_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); /* Now we need to init our freelist */ @@ -517,83 +504,107 @@ return retcode; } +#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define ST1_ENABLE (1<<16) +#define ST1_MASK (0xffff) + /* Most efficient way to verify state for the i830 is as it is * emitted. Non-conformant state is silently dropped. - * - * Use 'volatile' & local var tmp to force the emitted values to be - * identical to the verified ones. */ -static void i830EmitContextVerified( drm_device_t *dev, - volatile unsigned int *code ) +static void i830EmitContextVerified( drm_device_t *dev, + unsigned int *code ) { drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; RING_LOCALS; - BEGIN_LP_RING( I830_CTX_SETUP_SIZE ); - for ( i = 0 ; i < I830_CTX_SETUP_SIZE ; i++ ) { + BEGIN_LP_RING( I830_CTX_SETUP_SIZE + 4 ); + + for ( i = 0 ; i < I830_CTXREG_BLENDCOLR0 ; i++ ) { tmp = code[i]; + if ((tmp & (7<<29)) == CMD_3D && + (tmp & (0x1f<<24)) < (0x1d<<24)) { + OUT_RING( tmp ); + j++; + } else { + DRM_ERROR("Skipping %d\n", i); + } + } -#if 0 - if ((tmp & (7<<29)) == (3<<29) && + OUT_RING( STATE3D_CONST_BLEND_COLOR_CMD ); + OUT_RING( code[I830_CTXREG_BLENDCOLR] ); + j += 2; + + for ( i = I830_CTXREG_VF ; i < I830_CTXREG_MCSB0 ; i++ ) { + tmp = code[i]; + if ((tmp & (7<<29)) == CMD_3D && (tmp & (0x1f<<24)) < (0x1d<<24)) { OUT_RING( tmp ); j++; } else { - printk("Skipping %d\n", i); + DRM_ERROR("Skipping %d\n", i); } -#else - OUT_RING( tmp ); - j++; -#endif } + OUT_RING( STATE3D_MAP_COORD_SETBIND_CMD ); + OUT_RING( code[I830_CTXREG_MCSB1] ); + j += 2; + if (j & 1) OUT_RING( 0 ); ADVANCE_LP_RING(); } -static void i830EmitTexVerified( drm_device_t *dev, - volatile unsigned int *code ) +static void i830EmitTexVerified( drm_device_t *dev, unsigned int *code ) { drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; RING_LOCALS; - BEGIN_LP_RING( I830_TEX_SETUP_SIZE ); - - OUT_RING( GFX_OP_MAP_INFO ); - OUT_RING( code[I830_TEXREG_MI1] ); - OUT_RING( code[I830_TEXREG_MI2] ); - OUT_RING( code[I830_TEXREG_MI3] ); - OUT_RING( code[I830_TEXREG_MI4] ); - OUT_RING( code[I830_TEXREG_MI5] ); - - for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) { - tmp = code[i]; - OUT_RING( tmp ); - j++; - } + if (code[I830_TEXREG_MI0] == GFX_OP_MAP_INFO || + (code[I830_TEXREG_MI0] & ~(0xf*LOAD_TEXTURE_MAP0)) == + (STATE3D_LOAD_STATE_IMMEDIATE_2|4)) { + + BEGIN_LP_RING( I830_TEX_SETUP_SIZE ); + + OUT_RING( code[I830_TEXREG_MI0] ); /* TM0LI */ + OUT_RING( code[I830_TEXREG_MI1] ); /* TM0S0 */ + OUT_RING( code[I830_TEXREG_MI2] ); /* TM0S1 */ + OUT_RING( code[I830_TEXREG_MI3] ); /* TM0S2 */ + OUT_RING( code[I830_TEXREG_MI4] ); /* TM0S3 */ + OUT_RING( code[I830_TEXREG_MI5] ); /* TM0S4 */ + + for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) { + tmp = code[i]; + OUT_RING( tmp ); + j++; + } - if (j & 1) - OUT_RING( 0 ); + if (j & 1) + OUT_RING( 0 ); - ADVANCE_LP_RING(); + ADVANCE_LP_RING(); + } + else + printk("rejected packet %x\n", code[0]); } static void i830EmitTexBlendVerified( drm_device_t *dev, - volatile unsigned int *code, - volatile unsigned int num) + unsigned int *code, + unsigned int num) { drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; RING_LOCALS; - BEGIN_LP_RING( num ); + if (!num) + return; + + BEGIN_LP_RING( num + 1 ); for ( i = 0 ; i < num ; i++ ) { tmp = code[i]; @@ -616,6 +627,8 @@ int i; RING_LOCALS; + return; /* Is this right ? -- Arjan */ + BEGIN_LP_RING( 258 ); if(is_shared == 1) { @@ -629,44 +642,43 @@ OUT_RING(palette[i]); } OUT_RING(0); + /* KW: WHERE IS THE ADVANCE_LP_RING? This is effectively a noop! + */ } /* Need to do some additional checking when setting the dest buffer. */ static void i830EmitDestVerified( drm_device_t *dev, - volatile unsigned int *code ) + unsigned int *code ) { drm_i830_private_t *dev_priv = dev->dev_private; unsigned int tmp; RING_LOCALS; - BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 6 ); + BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 10 ); + tmp = code[I830_DESTREG_CBUFADDR]; - if (tmp == dev_priv->front_di1) { - /* Don't use fence when front buffer rendering */ - OUT_RING( CMD_OP_DESTBUFFER_INFO ); - OUT_RING( BUF_3D_ID_COLOR_BACK | - BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) ); - OUT_RING( tmp ); + if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) { + if (((int)outring) & 8) { + OUT_RING(0); + OUT_RING(0); + } OUT_RING( CMD_OP_DESTBUFFER_INFO ); - OUT_RING( BUF_3D_ID_DEPTH | - BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp)); - OUT_RING( dev_priv->zi1 ); - } else if(tmp == dev_priv->back_di1) { - OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING( BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) | BUF_3D_USE_FENCE); OUT_RING( tmp ); + OUT_RING( 0 ); OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING( BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE | BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp)); OUT_RING( dev_priv->zi1 ); + OUT_RING( 0 ); } else { - DRM_DEBUG("bad di1 %x (allow %x or %x)\n", + DRM_ERROR("bad di1 %x (allow %x or %x)\n", tmp, dev_priv->front_di1, dev_priv->back_di1); } @@ -688,25 +700,39 @@ if((tmp & ~0x3) == GFX_OP_SCISSOR_ENABLE) { OUT_RING( tmp ); } else { - DRM_DEBUG("bad scissor enable\n"); + DRM_ERROR("bad scissor enable\n"); OUT_RING( 0 ); } - OUT_RING( code[I830_DESTREG_SENABLE] ); - OUT_RING( GFX_OP_SCISSOR_RECT ); OUT_RING( code[I830_DESTREG_SR1] ); OUT_RING( code[I830_DESTREG_SR2] ); + OUT_RING( 0 ); ADVANCE_LP_RING(); } +static void i830EmitStippleVerified( drm_device_t *dev, + unsigned int *code ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + BEGIN_LP_RING( 2 ); + OUT_RING( GFX_OP_STIPPLE ); + OUT_RING( code[1] ); + ADVANCE_LP_RING(); +} + + static void i830EmitState( drm_device_t *dev ) { drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; + DRM_DEBUG("%s %x\n", __FUNCTION__, dirty); + if (dirty & I830_UPLOAD_BUFFERS) { i830EmitDestVerified( dev, sarea_priv->BufferState ); sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS; @@ -740,17 +766,154 @@ } if (dirty & I830_UPLOAD_TEX_PALETTE_SHARED) { - i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 1); + i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 1); + } else { + if (dirty & I830_UPLOAD_TEX_PALETTE_N(0)) { + i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 0); + sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(0); + } + if (dirty & I830_UPLOAD_TEX_PALETTE_N(1)) { + i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0); + sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1); + } + + /* 1.3: + */ +#if 0 + if (dirty & I830_UPLOAD_TEX_PALETTE_N(2)) { + i830EmitTexPalette(dev, sarea_priv->Palette2[0], 0, 0); + sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2); + } + if (dirty & I830_UPLOAD_TEX_PALETTE_N(3)) { + i830EmitTexPalette(dev, sarea_priv->Palette2[1], 1, 0); + sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2); + } +#endif + } + + /* 1.3: + */ + if (dirty & I830_UPLOAD_STIPPLE) { + i830EmitStippleVerified( dev, + sarea_priv->StippleState); + sarea_priv->dirty &= ~I830_UPLOAD_STIPPLE; + } + + if (dirty & I830_UPLOAD_TEX2) { + i830EmitTexVerified( dev, sarea_priv->TexState2 ); + sarea_priv->dirty &= ~I830_UPLOAD_TEX2; + } + + if (dirty & I830_UPLOAD_TEX3) { + i830EmitTexVerified( dev, sarea_priv->TexState3 ); + sarea_priv->dirty &= ~I830_UPLOAD_TEX3; + } + + + if (dirty & I830_UPLOAD_TEXBLEND2) { + i830EmitTexBlendVerified( + dev, + sarea_priv->TexBlendState2, + sarea_priv->TexBlendStateWordsUsed2); + + sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND2; + } + + if (dirty & I830_UPLOAD_TEXBLEND3) { + i830EmitTexBlendVerified( + dev, + sarea_priv->TexBlendState3, + sarea_priv->TexBlendStateWordsUsed3); + sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND3; + } +} + +/* ================================================================ + * Performance monitoring functions + */ + +static void i830_fill_box( drm_device_t *dev, + int x, int y, int w, int h, + int r, int g, int b ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + u32 color; + unsigned int BR13, CMD; + RING_LOCALS; + + BR13 = (0xF0 << 16) | (dev_priv->pitch * dev_priv->cpp) | (1<<24); + CMD = XY_COLOR_BLT_CMD; + x += dev_priv->sarea_priv->boxes[0].x1; + y += dev_priv->sarea_priv->boxes[0].y1; + + if (dev_priv->cpp == 4) { + BR13 |= (1<<25); + CMD |= (XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB); + color = (((0xff) << 24) | (r << 16) | (g << 8) | b); } else { - if (dirty & I830_UPLOAD_TEX_PALETTE_N(0)) { - i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 0); - sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(0); - } - if (dirty & I830_UPLOAD_TEX_PALETTE_N(1)) { - i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0); - sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1); - } + color = (((r & 0xf8) << 8) | + ((g & 0xfc) << 3) | + ((b & 0xf8) >> 3)); + } + + BEGIN_LP_RING( 6 ); + OUT_RING( CMD ); + OUT_RING( BR13 ); + OUT_RING( (y << 16) | x ); + OUT_RING( ((y+h) << 16) | (x+w) ); + + if ( dev_priv->current_page == 1 ) { + OUT_RING( dev_priv->front_offset ); + } else { + OUT_RING( dev_priv->back_offset ); + } + + OUT_RING( color ); + ADVANCE_LP_RING(); +} + +static void i830_cp_performance_boxes( drm_device_t *dev ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + + /* Purple box for page flipping + */ + if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_FLIP ) + i830_fill_box( dev, 4, 4, 8, 8, 255, 0, 255 ); + + /* Red box if we have to wait for idle at any point + */ + if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_WAIT ) + i830_fill_box( dev, 16, 4, 8, 8, 255, 0, 0 ); + + /* Blue box: lost context? + */ + if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_LOST_CONTEXT ) + i830_fill_box( dev, 28, 4, 8, 8, 0, 0, 255 ); + + /* Yellow box for texture swaps + */ + if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_TEXTURE_LOAD ) + i830_fill_box( dev, 40, 4, 8, 8, 255, 255, 0 ); + + /* Green box if hardware never idles (as far as we can tell) + */ + if ( !(dev_priv->sarea_priv->perf_boxes & I830_BOX_RING_EMPTY) ) + i830_fill_box( dev, 64, 4, 8, 8, 0, 255, 0 ); + + + /* Draw bars indicating number of buffers allocated + * (not a great measure, easily confused) + */ + if (dev_priv->dma_used) { + int bar = dev_priv->dma_used / 10240; + if (bar > 100) bar = 100; + if (bar < 1) bar = 1; + i830_fill_box( dev, 4, 16, bar, 4, 196, 128, 128 ); + dev_priv->dma_used = 0; } + + dev_priv->sarea_priv->perf_boxes = 0; } static void i830_dma_dispatch_clear( drm_device_t *dev, int flags, @@ -768,6 +931,15 @@ unsigned int BR13, CMD, D_CMD; RING_LOCALS; + + if ( dev_priv->current_page == 1 ) { + unsigned int tmp = flags; + + flags &= ~(I830_FRONT | I830_BACK); + if ( tmp & I830_FRONT ) flags |= I830_BACK; + if ( tmp & I830_BACK ) flags |= I830_FRONT; + } + i830_kernel_lost_context(dev); switch(cpp) { @@ -808,7 +980,7 @@ OUT_RING( BR13 ); OUT_RING( (pbox->y1 << 16) | pbox->x1 ); OUT_RING( (pbox->y2 << 16) | pbox->x2 ); - OUT_RING( 0 ); + OUT_RING( dev_priv->front_offset ); OUT_RING( clear_color ); ADVANCE_LP_RING(); } @@ -847,13 +1019,17 @@ drm_clip_rect_t *pbox = sarea_priv->boxes; int pitch = dev_priv->pitch; int cpp = dev_priv->cpp; - int ofs = dev_priv->back_offset; int i; unsigned int CMD, BR13; RING_LOCALS; DRM_DEBUG("swapbuffers\n"); + i830_kernel_lost_context(dev); + + if (dev_priv->do_boxes) + i830_cp_performance_boxes( dev ); + switch(cpp) { case 2: BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24); @@ -870,7 +1046,6 @@ break; } - i830_kernel_lost_context(dev); if (nbox > I830_NR_SAREA_CLIPRECTS) nbox = I830_NR_SAREA_CLIPRECTS; @@ -890,23 +1065,72 @@ BEGIN_LP_RING( 8 ); OUT_RING( CMD ); OUT_RING( BR13 ); + OUT_RING( (pbox->y1 << 16) | pbox->x1 ); + OUT_RING( (pbox->y2 << 16) | pbox->x2 ); - OUT_RING( (pbox->y1 << 16) | - pbox->x1 ); - OUT_RING( (pbox->y2 << 16) | - pbox->x2 ); - - OUT_RING( 0 /* front ofs always zero */ ); - OUT_RING( (pbox->y1 << 16) | - pbox->x1 ); + if (dev_priv->current_page == 0) + OUT_RING( dev_priv->front_offset ); + else + OUT_RING( dev_priv->back_offset ); + OUT_RING( (pbox->y1 << 16) | pbox->x1 ); OUT_RING( BR13 & 0xffff ); - OUT_RING( ofs ); + + if (dev_priv->current_page == 0) + OUT_RING( dev_priv->back_offset ); + else + OUT_RING( dev_priv->front_offset ); ADVANCE_LP_RING(); } } +static void i830_dma_dispatch_flip( drm_device_t *dev ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n", + __FUNCTION__, + dev_priv->current_page, + dev_priv->sarea_priv->pf_current_page); + + i830_kernel_lost_context(dev); + + if (dev_priv->do_boxes) { + dev_priv->sarea_priv->perf_boxes |= I830_BOX_FLIP; + i830_cp_performance_boxes( dev ); + } + + + BEGIN_LP_RING( 2 ); + OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + + BEGIN_LP_RING( 6 ); + OUT_RING( CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP ); + OUT_RING( 0 ); + if ( dev_priv->current_page == 0 ) { + OUT_RING( dev_priv->back_offset ); + dev_priv->current_page = 1; + } else { + OUT_RING( dev_priv->front_offset ); + dev_priv->current_page = 0; + } + OUT_RING(0); + ADVANCE_LP_RING(); + + + BEGIN_LP_RING( 2 ); + OUT_RING( MI_WAIT_FOR_EVENT | + MI_WAIT_FOR_PLANE_A_FLIP ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + + + dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; +} static void i830_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf, @@ -936,7 +1160,7 @@ } } - if (used > 4*1024) + if (used > 4*1023) used = 0; if (sarea_priv->dirty) @@ -953,12 +1177,19 @@ DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4); if (buf_priv->currently_mapped == I830_BUF_MAPPED) { - *(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE | - sarea_priv->vertex_prim | - ((used/4)-2)); + u32 *vp = buf_priv->virtual; + + vp[0] = (GFX_OP_PRIMITIVE | + sarea_priv->vertex_prim | + ((used/4)-2)); + + if (dev_priv->use_mi_batchbuffer_start) { + vp[used/4] = MI_BATCH_BUFFER_END; + used += 4; + } if (used & 4) { - *(u32 *)((u32)buf_priv->virtual + used) = 0; + vp[used/4] = 0; used += 4; } @@ -978,80 +1209,45 @@ ADVANCE_LP_RING(); } - BEGIN_LP_RING(4); + if (dev_priv->use_mi_batchbuffer_start) { + BEGIN_LP_RING(2); + OUT_RING( MI_BATCH_BUFFER_START | (2<<6) ); + OUT_RING( start | MI_BATCH_NON_SECURE ); + ADVANCE_LP_RING(); + } + else { + BEGIN_LP_RING(4); + OUT_RING( MI_BATCH_BUFFER ); + OUT_RING( start | MI_BATCH_NON_SECURE ); + OUT_RING( start + used - 4 ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + } - OUT_RING( MI_BATCH_BUFFER ); - OUT_RING( start | MI_BATCH_NON_SECURE ); - OUT_RING( start + used - 4 ); - OUT_RING( 0 ); - ADVANCE_LP_RING(); - } while (++i < nbox); } - BEGIN_LP_RING(10); - OUT_RING( CMD_STORE_DWORD_IDX ); - OUT_RING( 20 ); - OUT_RING( dev_priv->counter ); - OUT_RING( 0 ); - if (discard) { + dev_priv->counter++; + + (void) cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, + I830_BUF_HARDWARE); + + BEGIN_LP_RING(8); + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( 20 ); + OUT_RING( dev_priv->counter ); OUT_RING( CMD_STORE_DWORD_IDX ); OUT_RING( buf_priv->my_use_idx ); OUT_RING( I830_BUF_FREE ); + OUT_RING( CMD_REPORT_HEAD ); OUT_RING( 0 ); + ADVANCE_LP_RING(); } - - OUT_RING( CMD_REPORT_HEAD ); - OUT_RING( 0 ); - ADVANCE_LP_RING(); -} - -/* Interrupts are only for flushing */ -void i830_dma_service(int irq, void *device, struct pt_regs *regs) -{ - drm_device_t *dev = (drm_device_t *)device; - drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; - u16 temp; - - temp = I830_READ16(I830REG_INT_IDENTITY_R); - temp = temp & ~(0x6000); - if(temp != 0) I830_WRITE16(I830REG_INT_IDENTITY_R, - temp); /* Clear all interrupts */ - else - return; - - queue_task(&dev->tq, &tq_immediate); - mark_bh(IMMEDIATE_BH); -} - -void DRM(dma_immediate_bh)(void *device) -{ - drm_device_t *dev = (drm_device_t *) device; - drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; - - atomic_set(&dev_priv->flush_done, 1); - wake_up_interruptible(&dev_priv->flush_queue); } -static inline void i830_dma_emit_flush(drm_device_t *dev) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - - i830_kernel_lost_context(dev); - BEGIN_LP_RING(2); - OUT_RING( CMD_REPORT_HEAD ); - OUT_RING( GFX_OP_USER_INTERRUPT ); - ADVANCE_LP_RING(); - - i830_wait_ring( dev, dev_priv->ring.Size - 8 ); - atomic_set(&dev_priv->flush_done, 1); - wake_up_interruptible(&dev_priv->flush_queue); -} - -static inline void i830_dma_quiescent_emit(drm_device_t *dev) +void i830_dma_quiescent(drm_device_t *dev) { drm_i830_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -1062,79 +1258,27 @@ OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); OUT_RING( CMD_REPORT_HEAD ); OUT_RING( 0 ); - OUT_RING( GFX_OP_USER_INTERRUPT ); + OUT_RING( 0 ); ADVANCE_LP_RING(); - i830_wait_ring( dev, dev_priv->ring.Size - 8 ); - atomic_set(&dev_priv->flush_done, 1); - wake_up_interruptible(&dev_priv->flush_queue); -} - -void i830_dma_quiescent(drm_device_t *dev) -{ - DECLARE_WAITQUEUE(entry, current); - drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; - unsigned long end; - - if(dev_priv == NULL) { - return; - } - atomic_set(&dev_priv->flush_done, 0); - add_wait_queue(&dev_priv->flush_queue, &entry); - end = jiffies + (HZ*3); - - for (;;) { - current->state = TASK_INTERRUPTIBLE; - i830_dma_quiescent_emit(dev); - if (atomic_read(&dev_priv->flush_done) == 1) break; - if(time_before(end, jiffies)) { - DRM_ERROR("lockup\n"); - break; - } - schedule_timeout(HZ*3); - if (signal_pending(current)) { - break; - } - } - - current->state = TASK_RUNNING; - remove_wait_queue(&dev_priv->flush_queue, &entry); - - return; + i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ ); } static int i830_flush_queue(drm_device_t *dev) { - DECLARE_WAITQUEUE(entry, current); - drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; + drm_i830_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; - unsigned long end; - int i, ret = 0; + int i, ret = 0; + RING_LOCALS; + + i830_kernel_lost_context(dev); - if(dev_priv == NULL) { - return 0; - } - atomic_set(&dev_priv->flush_done, 0); - add_wait_queue(&dev_priv->flush_queue, &entry); - end = jiffies + (HZ*3); - for (;;) { - current->state = TASK_INTERRUPTIBLE; - i830_dma_emit_flush(dev); - if (atomic_read(&dev_priv->flush_done) == 1) break; - if(time_before(end, jiffies)) { - DRM_ERROR("lockup\n"); - break; - } - schedule_timeout(HZ*3); - if (signal_pending(current)) { - ret = -EINTR; /* Can't restart */ - break; - } - } - - current->state = TASK_RUNNING; - remove_wait_queue(&dev_priv->flush_queue, &entry); + BEGIN_LP_RING(2); + OUT_RING( CMD_REPORT_HEAD ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ ); for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; @@ -1146,7 +1290,7 @@ if (used == I830_BUF_HARDWARE) DRM_DEBUG("reclaimed from HARDWARE\n"); if (used == I830_BUF_CLIENT) - DRM_DEBUG("still on client HARDWARE\n"); + DRM_DEBUG("still on client\n"); } return ret; @@ -1185,8 +1329,7 @@ { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - - DRM_DEBUG("i830_flush_ioctl\n"); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("i830_flush_ioctl called without lock held\n"); return -EINVAL; @@ -1275,6 +1418,53 @@ return 0; } + + +/* Not sure why this isn't set all the time: + */ +static void i830_do_init_pageflip( drm_device_t *dev ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + + DRM_DEBUG("%s\n", __FUNCTION__); + dev_priv->page_flipping = 1; + dev_priv->current_page = 0; + dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; +} + +int i830_do_cleanup_pageflip( drm_device_t *dev ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + + DRM_DEBUG("%s\n", __FUNCTION__); + if (dev_priv->current_page != 0) + i830_dma_dispatch_flip( dev ); + + dev_priv->page_flipping = 0; + return 0; +} + +int i830_flip_bufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_private_t *dev_priv = dev->dev_private; + + DRM_DEBUG("%s\n", __FUNCTION__); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i830_flip_buf called without lock held\n"); + return -EINVAL; + } + + if (!dev_priv->page_flipping) + i830_do_init_pageflip( dev ); + + i830_dma_dispatch_flip( dev ); + return 0; +} + int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -1324,46 +1514,80 @@ return retcode; } -int i830_copybuf(struct inode *inode, struct file *filp, unsigned int cmd, +int i830_copybuf(struct inode *inode, + struct file *filp, + unsigned int cmd, + unsigned long arg) +{ + /* Never copy - 2.4.x doesn't need it */ + return 0; +} + +int i830_docopy(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { + return 0; +} + + + +int i830_getparam( struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg ) +{ drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - drm_i830_copy_t d; - drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; - u32 *hw_status = (u32 *)dev_priv->hw_status_page; - drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) - dev_priv->sarea_priv; - drm_buf_t *buf; - drm_i830_buf_priv_t *buf_priv; - drm_device_dma_t *dma = dev->dma; + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_getparam_t param; + int value; - if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("i830_dma called without lock held\n"); + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); return -EINVAL; } - - if (copy_from_user(&d, (drm_i830_copy_t *)arg, sizeof(d))) - return -EFAULT; - - if(d.idx < 0 || d.idx > dma->buf_count) return -EINVAL; - buf = dma->buflist[ d.idx ]; - buf_priv = buf->dev_private; - if (buf_priv->currently_mapped != I830_BUF_MAPPED) return -EPERM; - - if(d.used < 0 || d.used > buf->total) return -EINVAL; - if (copy_from_user(buf_priv->virtual, d.address, d.used)) + if (copy_from_user(¶m, (drm_i830_getparam_t *)arg, sizeof(param) )) return -EFAULT; - sarea_priv->last_dispatch = (int) hw_status[5]; + switch( param.param ) { + case I830_PARAM_IRQ_ACTIVE: + value = dev->irq ? 1 : 0; + break; + default: + return -EINVAL; + } + if ( copy_to_user( param.value, &value, sizeof(int) ) ) { + DRM_ERROR( "copy_to_user\n" ); + return -EFAULT; + } + return 0; } -int i830_docopy(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) + +int i830_setparam( struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg ) { - if(VM_DONTCOPY == 0) return 1; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_setparam_t param; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + if (copy_from_user(¶m, (drm_i830_setparam_t *)arg, sizeof(param) )) + return -EFAULT; + + switch( param.param ) { + case I830_SETPARAM_USE_MI_BATCHBUFFER_START: + dev_priv->use_mi_batchbuffer_start = param.value; + break; + default: + return -EINVAL; + } + return 0; } Index: drivers/char/drm/i830_drm.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/i830_drm.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/i830_drm.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/i830_drm.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -3,6 +3,9 @@ /* WARNING: These defines must be the same as what the Xserver uses. * if you change them, you must change the defines in the Xserver. + * + * KW: Actually, you can't ever change them because doing so would + * break backwards compatibility. */ #ifndef _I830_DEFINES_ @@ -18,14 +21,12 @@ #define I830_NR_TEX_REGIONS 64 #define I830_LOG_MIN_TEX_REGION_SIZE 16 -/* if defining I830_ENABLE_4_TEXTURES, do it in i830_3d_reg.h, too */ -#if !defined(I830_ENABLE_4_TEXTURES) +/* KW: These aren't correct but someone set them to two and then + * released the module. Now we can't change them as doing so would + * break backwards compatibility. + */ #define I830_TEXTURE_COUNT 2 -#define I830_TEXBLEND_COUNT 2 /* always same as TEXTURE_COUNT? */ -#else /* defined(I830_ENABLE_4_TEXTURES) */ -#define I830_TEXTURE_COUNT 4 -#define I830_TEXBLEND_COUNT 4 /* always same as TEXTURE_COUNT? */ -#endif /* I830_ENABLE_4_TEXTURES */ +#define I830_TEXBLEND_COUNT I830_TEXTURE_COUNT #define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */ @@ -57,6 +58,7 @@ #define I830_UPLOAD_TEXBLEND_MASK 0xf00000 #define I830_UPLOAD_TEX_PALETTE_N(n) (0x1000000 << (n)) #define I830_UPLOAD_TEX_PALETTE_SHARED 0x4000000 +#define I830_UPLOAD_STIPPLE 0x8000000 /* Indices into buf.Setup where various bits of state are mirrored per * context and per buffer. These can be fired at the card as a unit, @@ -73,7 +75,6 @@ */ #define I830_DESTREG_CBUFADDR 0 -/* Invarient */ #define I830_DESTREG_DBUFADDR 1 #define I830_DESTREG_DV0 2 #define I830_DESTREG_DV1 3 @@ -109,6 +110,13 @@ #define I830_CTXREG_MCSB1 16 #define I830_CTX_SETUP_SIZE 17 +/* 1.3: Stipple state + */ +#define I830_STPREG_ST0 0 +#define I830_STPREG_ST1 1 +#define I830_STP_SETUP_SIZE 2 + + /* Texture state (per tex unit) */ @@ -124,6 +132,18 @@ #define I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS */ #define I830_TEX_SETUP_SIZE 10 +#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */ +#define I830_TEXREG_TM0S0 1 +#define I830_TEXREG_TM0S1 2 +#define I830_TEXREG_TM0S2 3 +#define I830_TEXREG_TM0S3 4 +#define I830_TEXREG_TM0S4 5 +#define I830_TEXREG_NOP0 6 /* noop */ +#define I830_TEXREG_NOP1 7 /* noop */ +#define I830_TEXREG_NOP2 8 /* noop */ +#define __I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS -- shared */ +#define __I830_TEX_SETUP_SIZE 10 + #define I830_FRONT 0x1 #define I830_BACK 0x2 #define I830_DEPTH 0x4 @@ -199,8 +219,53 @@ int ctxOwner; /* last context to upload state */ int vertex_prim; + + int pf_enabled; /* is pageflipping allowed? */ + int pf_active; + int pf_current_page; /* which buffer is being displayed? */ + + int perf_boxes; /* performance boxes to be displayed */ + + /* Here's the state for texunits 2,3: + */ + unsigned int TexState2[I830_TEX_SETUP_SIZE]; + unsigned int TexBlendState2[I830_TEXBLEND_SIZE]; + unsigned int TexBlendStateWordsUsed2; + + unsigned int TexState3[I830_TEX_SETUP_SIZE]; + unsigned int TexBlendState3[I830_TEXBLEND_SIZE]; + unsigned int TexBlendStateWordsUsed3; + + unsigned int StippleState[I830_STP_SETUP_SIZE]; } drm_i830_sarea_t; +/* Flags for perf_boxes + */ +#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ +#define I830_BOX_FLIP 0x2 /* populated by kernel */ +#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ +#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ +#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ + + +/* I830 specific ioctls + * The device specific ioctl range is 0x40 to 0x79. + */ +#define DRM_IOCTL_I830_INIT DRM_IOW( 0x40, drm_i830_init_t) +#define DRM_IOCTL_I830_VERTEX DRM_IOW( 0x41, drm_i830_vertex_t) +#define DRM_IOCTL_I830_CLEAR DRM_IOW( 0x42, drm_i830_clear_t) +#define DRM_IOCTL_I830_FLUSH DRM_IO ( 0x43) +#define DRM_IOCTL_I830_GETAGE DRM_IO ( 0x44) +#define DRM_IOCTL_I830_GETBUF DRM_IOWR(0x45, drm_i830_dma_t) +#define DRM_IOCTL_I830_SWAP DRM_IO ( 0x46) +#define DRM_IOCTL_I830_COPY DRM_IOW( 0x47, drm_i830_copy_t) +#define DRM_IOCTL_I830_DOCOPY DRM_IO ( 0x48) +#define DRM_IOCTL_I830_FLIP DRM_IO ( 0x49) +#define DRM_IOCTL_I830_IRQ_EMIT DRM_IOWR(0x4a, drm_i830_irq_emit_t) +#define DRM_IOCTL_I830_IRQ_WAIT DRM_IOW( 0x4b, drm_i830_irq_wait_t) +#define DRM_IOCTL_I830_GETPARAM DRM_IOWR(0x4c, drm_i830_getparam_t) +#define DRM_IOCTL_I830_SETPARAM DRM_IOWR(0x4d, drm_i830_setparam_t) + typedef struct _drm_i830_clear { int clear_color; int clear_depth; @@ -235,4 +300,36 @@ int granted; } drm_i830_dma_t; + +/* 1.3: Userspace can request & wait on irq's: + */ +typedef struct drm_i830_irq_emit { + int *irq_seq; +} drm_i830_irq_emit_t; + +typedef struct drm_i830_irq_wait { + int irq_seq; +} drm_i830_irq_wait_t; + + +/* 1.3: New ioctl to query kernel params: + */ +#define I830_PARAM_IRQ_ACTIVE 1 + +typedef struct drm_i830_getparam { + int param; + int *value; +} drm_i830_getparam_t; + + +/* 1.3: New ioctl to set kernel params: + */ +#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 + +typedef struct drm_i830_setparam { + int param; + int value; +} drm_i830_setparam_t; + + #endif /* _I830_DRM_H_ */ Index: drivers/char/drm/i830_drv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/i830_drv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/i830_drv.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/i830_drv.c 4 Aug 2004 01:28:48 -0000 1.2 @@ -29,41 +29,16 @@ * Jeff Hartmann * Gareth Hughes * Abraham vd Merwe + * Keith Whitwell */ #include #include "i830.h" #include "drmP.h" +#include "drm.h" +#include "i830_drm.h" #include "i830_drv.h" -#define DRIVER_AUTHOR "VA Linux Systems Inc." - -#define DRIVER_NAME "i830" -#define DRIVER_DESC "Intel 830M" -#define DRIVER_DATE "20011004" - -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 0 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_INIT)] = { i830_dma_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_VERTEX)] = { i830_dma_vertex, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_CLEAR)] = { i830_clear_bufs, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_FLUSH)] = { i830_flush_ioctl, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_GETAGE)] = { i830_getage, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_GETBUF)] = { i830_getbuf, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_SWAP)] = { i830_swap_bufs, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_COPY)] = { i830_copybuf, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_DOCOPY)] = { i830_docopy, 1, 0 }, - -#define __HAVE_COUNTERS 4 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY -#define __HAVE_COUNTER9 _DRM_STAT_DMA - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -72,25 +47,6 @@ #include "drm_drawable.h" #include "drm_drv.h" -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init i830_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", i830_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" Index: drivers/char/drm/i830_drv.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/i830_drv.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/i830_drv.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/i830_drv.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -61,24 +61,36 @@ drm_i830_sarea_t *sarea_priv; drm_i830_ring_buffer_t ring; - u8 *hw_status_page; + unsigned long hw_status_page; unsigned long counter; - - dma_addr_t dma_status_page; - atomic_t flush_done; - wait_queue_head_t flush_queue; /* Processes waiting until flush */ + dma_addr_t dma_status_page; + drm_buf_t *mmap_buffer; u32 front_di1, back_di1, zi1; int back_offset; int depth_offset; + int front_offset; int w, h; int pitch; int back_pitch; int depth_pitch; unsigned int cpp; + + int do_boxes; + int dma_used; + + int current_page; + int page_flipping; + + wait_queue_head_t irq_queue; + atomic_t irq_received; + atomic_t irq_emitted; + + int use_mi_batchbuffer_start; + } drm_i830_private_t; /* i830_dma.c */ @@ -109,24 +121,81 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -#define I830_VERBOSE 0 +extern int i830_flip_bufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + +extern int i830_getparam( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + +extern int i830_setparam( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + +/* i830_irq.c */ +extern int i830_irq_emit( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int i830_irq_wait( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int i830_wait_irq(drm_device_t *dev, int irq_nr); +extern int i830_emit_irq(drm_device_t *dev); + #define I830_BASE(reg) ((unsigned long) \ dev_priv->mmio_map->handle) #define I830_ADDR(reg) (I830_BASE(reg) + reg) -#define I830_DEREF(reg) *(__volatile__ int *)I830_ADDR(reg) -#define I830_READ(reg) I830_DEREF(reg) -#define I830_WRITE(reg,val) do { I830_DEREF(reg) = val; } while (0) +#define I830_DEREF(reg) *(__volatile__ unsigned int *)I830_ADDR(reg) +#define I830_READ(reg) readl((volatile u32 *)I830_ADDR(reg)) +#define I830_WRITE(reg,val) writel(val, (volatile u32 *)I830_ADDR(reg)) #define I830_DEREF16(reg) *(__volatile__ u16 *)I830_ADDR(reg) #define I830_READ16(reg) I830_DEREF16(reg) #define I830_WRITE16(reg,val) do { I830_DEREF16(reg) = val; } while (0) + + +#define I830_VERBOSE 0 + +#define RING_LOCALS unsigned int outring, ringmask, outcount; \ + volatile char *virt; + +#define BEGIN_LP_RING(n) do { \ + if (I830_VERBOSE) \ + printk("BEGIN_LP_RING(%d) in %s\n", \ + n, __FUNCTION__); \ + if (dev_priv->ring.space < n*4) \ + i830_wait_ring(dev, n*4, __FUNCTION__); \ + outcount = 0; \ + outring = dev_priv->ring.tail; \ + ringmask = dev_priv->ring.tail_mask; \ + virt = dev_priv->ring.virtual_start; \ +} while (0) + + +#define OUT_RING(n) do { \ + if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \ + *(volatile unsigned int *)(virt + outring) = n; \ + outcount++; \ + outring += 4; \ + outring &= ringmask; \ +} while (0) + +#define ADVANCE_LP_RING() do { \ + if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring); \ + dev_priv->ring.tail = outring; \ + dev_priv->ring.space -= outcount * 4; \ + I830_WRITE(LP_RING + RING_TAIL, outring); \ +} while(0) + +extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller); + + #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) #define CMD_REPORT_HEAD (7<<23) #define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) #define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) +#define STATE3D_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16)) +#define LOAD_TEXTURE_MAP0 (1<<11) + #define INST_PARSER_CLIENT 0x00000000 #define INST_OP_FLUSH 0x02000000 #define INST_FLUSH_MAP_CACHE 0x00000001 @@ -142,18 +211,21 @@ #define I830REG_INT_MASK_R 0x020a8 #define I830REG_INT_ENABLE_R 0x020a0 +#define I830_IRQ_RESERVED ((1<<13)|(3<<2)) + + #define LP_RING 0x2030 #define HP_RING 0x2040 #define RING_TAIL 0x00 -#define TAIL_ADDR 0x000FFFF8 +#define TAIL_ADDR 0x001FFFF8 #define RING_HEAD 0x04 #define HEAD_WRAP_COUNT 0xFFE00000 #define HEAD_WRAP_ONE 0x00200000 #define HEAD_ADDR 0x001FFFFC #define RING_START 0x08 -#define START_ADDR 0x00FFFFF8 +#define START_ADDR 0x0xFFFFF000 #define RING_LEN 0x0C -#define RING_NR_PAGES 0x000FF000 +#define RING_NR_PAGES 0x001FF000 #define RING_REPORT_MASK 0x00000006 #define RING_REPORT_64K 0x00000002 #define RING_REPORT_128K 0x00000004 @@ -184,6 +256,12 @@ #define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) +#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2) +#define ASYNC_FLIP (1<<22) + +#define CMD_3D (0x3<<29) +#define STATE3D_CONST_BLEND_COLOR_CMD (CMD_3D|(0x1d<<24)|(0x88<<16)) +#define STATE3D_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16)) #define BR00_BITBLT_CLIENT 0x40000000 #define BR00_OP_COLOR_BLT 0x10000000 @@ -208,8 +286,15 @@ #define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) #define MI_BATCH_BUFFER ((0x30<<23)|1) +#define MI_BATCH_BUFFER_START (0x31<<23) +#define MI_BATCH_BUFFER_END (0xA<<23) #define MI_BATCH_NON_SECURE (1) +#define MI_WAIT_FOR_EVENT ((0x3<<23)) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) +#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1) + +#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23)) #endif Index: drivers/char/drm/mga.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/mga.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/mga.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/mga.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -41,6 +41,33 @@ #define __HAVE_MTRR 1 #define __HAVE_CTX_BITMAP 1 +#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." + +#define DRIVER_NAME "mga" +#define DRIVER_DESC "Matrox G200/G400" +#define DRIVER_DATE "20010321" + +#define DRIVER_MAJOR 3 +#define DRIVER_MINOR 0 +#define DRIVER_PATCHLEVEL 2 + +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_dma_flush, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)] = { mga_dma_reset, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_dma_swap, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_dma_clear, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_dma_iload, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)] = { mga_dma_blit, 1, 0 }, + +#define __HAVE_COUNTERS 3 +#define __HAVE_COUNTER6 _DRM_STAT_IRQ +#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY +#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY + /* Driver customization: */ #define DRIVER_PRETAKEDOWN() do { \ Index: drivers/char/drm/mga_dma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/mga_dma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/mga_dma.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/mga_dma.c 4 Aug 2004 01:28:48 -0000 1.2 @@ -35,10 +35,11 @@ #include "mga.h" #include "drmP.h" +#include "drm.h" +#include "mga_drm.h" #include "mga_drv.h" - -#include /* For task queue support */ -#include +#include +#include "drm_os_linux.h" #define MGA_DEFAULT_USEC_TIMEOUT 10000 #define MGA_FREELIST_DEBUG 0 @@ -52,7 +53,7 @@ { u32 status = 0; int i; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK; @@ -74,7 +75,7 @@ { u32 status = 0; int i; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { status = MGA_READ( MGA_STATUS ) & MGA_DMA_IDLE_MASK; @@ -93,7 +94,7 @@ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_primary_buffer_t *primary = &dev_priv->prim; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); /* The primary DMA stream should look like new right about now. */ @@ -114,7 +115,7 @@ int mga_do_engine_reset( drm_mga_private_t *dev_priv ) { - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); /* Okay, so we've completely screwed up and locked the engine. * How about we clean up after ourselves? @@ -160,8 +161,8 @@ u32 head, tail; u32 status = 0; int i; - DMA_LOCALS; - DRM_DEBUG( "%s:\n", __FUNCTION__ ); + DMA_LOCALS; + DRM_DEBUG( "\n" ); /* We need to wait so that we can do an safe flush */ for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { @@ -207,7 +208,7 @@ mga_flush_write_combine(); MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER ); - DRM_DEBUG( "%s: done.\n", __FUNCTION__ ); + DRM_DEBUG( "done.\n" ); } void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv ) @@ -215,7 +216,7 @@ drm_mga_primary_buffer_t *primary = &dev_priv->prim; u32 head, tail; DMA_LOCALS; - DRM_DEBUG( "%s:\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); BEGIN_DMA_WRAP(); @@ -250,7 +251,7 @@ MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER ); set_bit( 0, &primary->wrapped ); - DRM_DEBUG( "%s: done.\n", __FUNCTION__ ); + DRM_DEBUG( "done.\n" ); } void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv ) @@ -258,7 +259,7 @@ drm_mga_primary_buffer_t *primary = &dev_priv->prim; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; u32 head = dev_priv->primary->offset; - DRM_DEBUG( "%s:\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); sarea_priv->last_wrap++; DRM_DEBUG( " wrap = %d\n", sarea_priv->last_wrap ); @@ -267,7 +268,7 @@ MGA_WRITE( MGA_PRIMADDRESS, head | MGA_DMA_GENERAL ); clear_bit( 0, &primary->wrapped ); - DRM_DEBUG( "%s: done.\n", __FUNCTION__ ); + DRM_DEBUG( "done.\n" ); } @@ -307,8 +308,7 @@ drm_mga_buf_priv_t *buf_priv; drm_mga_freelist_t *entry; int i; - DRM_DEBUG( "%s: count=%d\n", - __FUNCTION__, dma->buf_count ); + DRM_DEBUG( "count=%d\n", dma->buf_count ); dev_priv->head = DRM(alloc)( sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER ); @@ -354,7 +354,7 @@ drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_freelist_t *entry; drm_mga_freelist_t *next; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); entry = dev_priv->head; while ( entry ) { @@ -392,7 +392,7 @@ drm_mga_freelist_t *prev; drm_mga_freelist_t *tail = dev_priv->tail; u32 head, wrap; - DRM_DEBUG( "%s:\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); head = MGA_READ( MGA_PRIMADDRESS ); wrap = dev_priv->sarea_priv->last_wrap; @@ -424,8 +424,7 @@ drm_mga_buf_priv_t *buf_priv = buf->dev_private; drm_mga_freelist_t *head, *entry, *prev; - DRM_DEBUG( "%s: age=0x%06lx wrap=%d\n", - __FUNCTION__, + DRM_DEBUG( "age=0x%06lx wrap=%d\n", buf_priv->list_entry->age.head - dev_priv->primary->offset, buf_priv->list_entry->age.wrap ); @@ -458,9 +457,8 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) { drm_mga_private_t *dev_priv; - struct list_head *list; int ret; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); dev_priv = DRM(alloc)( sizeof(drm_mga_private_t), DRM_MEM_DRIVER ); if ( !dev_priv ) @@ -494,15 +492,8 @@ dev_priv->texture_offset = init->texture_offset[0]; dev_priv->texture_size = init->texture_size[0]; - list_for_each( list, &dev->maplist->head ) { - drm_map_list_t *entry = (drm_map_list_t *)list; - if ( entry->map && - entry->map->type == _DRM_SHM && - (entry->map->flags & _DRM_CONTAINS_LOCK) ) { - dev_priv->sarea = entry->map; - break; - } - } + DRM_GETSAREA(); + if(!dev_priv->sarea) { DRM_ERROR( "failed to find sarea!\n" ); /* Assign dev_private so we can do cleanup. */ @@ -565,9 +556,9 @@ (drm_mga_sarea_t *)((u8 *)dev_priv->sarea->handle + init->sarea_priv_offset); - DRM_IOREMAP( dev_priv->warp ); - DRM_IOREMAP( dev_priv->primary ); - DRM_IOREMAP( dev_priv->buffers ); + DRM_IOREMAP( dev_priv->warp, dev ); + DRM_IOREMAP( dev_priv->primary, dev ); + DRM_IOREMAP( dev_priv->buffers, dev ); if(!dev_priv->warp->handle || !dev_priv->primary->handle || @@ -626,8 +617,6 @@ dev_priv->prim.high_mark = 256 * DMA_BLOCK_SIZE; - spin_lock_init( &dev_priv->prim.list_lock ); - dev_priv->prim.status[0] = dev_priv->primary->offset; dev_priv->prim.status[1] = 0; @@ -650,14 +639,14 @@ int mga_do_cleanup_dma( drm_device_t *dev ) { - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); if ( dev->dev_private ) { drm_mga_private_t *dev_priv = dev->dev_private; - DRM_IOREMAPFREE( dev_priv->warp ); - DRM_IOREMAPFREE( dev_priv->primary ); - DRM_IOREMAPFREE( dev_priv->buffers ); + DRM_IOREMAPFREE( dev_priv->warp, dev ); + DRM_IOREMAPFREE( dev_priv->primary, dev ); + DRM_IOREMAPFREE( dev_priv->buffers, dev ); if ( dev_priv->head != NULL ) { mga_freelist_cleanup( dev ); @@ -725,7 +714,7 @@ #if MGA_DMA_DEBUG int ret = mga_do_wait_for_idle( dev_priv ); if ( ret < 0 ) - DRM_INFO( __FUNCTION__": -EBUSY\n" ); + DRM_INFO( "%s: -EBUSY\n", __FUNCTION__ ); return ret; #else return mga_do_wait_for_idle( dev_priv ); Index: drivers/char/drm/mga_drm.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/mga_drm.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/mga_drm.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/mga_drm.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -225,6 +225,20 @@ /* WARNING: If you change any of these defines, make sure to change the * defines in the Xserver file (xf86drmMga.h) */ + +/* MGA specific ioctls + * The device specific ioctl range is 0x40 to 0x79. + */ +#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) +#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x41, drm_lock_t) +#define DRM_IOCTL_MGA_RESET DRM_IO( 0x42) +#define DRM_IOCTL_MGA_SWAP DRM_IO( 0x43) +#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x44, drm_mga_clear_t) +#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x45, drm_mga_vertex_t) +#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t) +#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x47, drm_mga_iload_t) +#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x48, drm_mga_blit_t) + typedef struct _drm_mga_warp_index { int installed; unsigned long phys_addr; Index: drivers/char/drm/mga_drv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/mga_drv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/mga_drv.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/mga_drv.c 4 Aug 2004 01:28:48 -0000 1.2 @@ -32,37 +32,9 @@ #include #include "mga.h" #include "drmP.h" +#include "drm.h" +#include "mga_drm.h" #include "mga_drv.h" - -#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." - -#define DRIVER_NAME "mga" -#define DRIVER_DESC "Matrox G200/G400" -#define DRIVER_DATE "20010321" - -#define DRIVER_MAJOR 3 -#define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 2 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_dma_flush, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)] = { mga_dma_reset, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_dma_swap, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_dma_clear, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_dma_iload, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)] = { mga_dma_blit, 1, 0 }, - - -#define __HAVE_COUNTERS 3 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -70,27 +42,6 @@ #include "drm_dma.h" #include "drm_drawable.h" #include "drm_drv.h" - -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init mga_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", mga_options ); -#endif - - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" Index: drivers/char/drm/mga_drv.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/mga_drv.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/mga_drv.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/mga_drv.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -46,8 +46,6 @@ u32 last_wrap; u32 high_mark; - - spinlock_t list_lock; } drm_mga_primary_buffer_t; typedef struct drm_mga_freelist { @@ -257,7 +255,7 @@ #define BEGIN_DMA_WRAP() \ do { \ if ( MGA_VERBOSE ) { \ - DRM_INFO( "BEGIN_DMA() in %s\n", __FUNCTION__ ); \ + DRM_INFO( "BEGIN_DMA() in %s\n", __FUNCTION__ ); \ DRM_INFO( " space=0x%x\n", dev_priv->prim.space ); \ } \ prim = dev_priv->prim.start; \ @@ -276,7 +274,7 @@ #define FLUSH_DMA() \ do { \ if ( 0 ) { \ - DRM_INFO( "%s:\n" , __FUNCTION__); \ + DRM_INFO( "%s:\n", __FUNCTION__ ); \ DRM_INFO( " tail=0x%06x head=0x%06lx\n", \ dev_priv->prim.tail, \ MGA_READ( MGA_PRIMADDRESS ) - \ Index: drivers/char/drm/mga_state.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/mga_state.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/mga_state.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/mga_state.c 4 Aug 2004 01:28:48 -0000 1.2 @@ -34,8 +34,9 @@ #include "mga.h" #include "drmP.h" -#include "mga_drv.h" #include "drm.h" +#include "mga_drm.h" +#include "mga_drv.h" /* ================================================================ @@ -512,7 +513,7 @@ int nbox = sarea_priv->nbox; int i; DMA_LOCALS; - DRM_DEBUG("%s:\n" , __FUNCTION__); + DRM_DEBUG( "\n" ); BEGIN_DMA( 1 ); @@ -606,7 +607,7 @@ int nbox = sarea_priv->nbox; int i; DMA_LOCALS; - DRM_DEBUG( "%s:\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); sarea_priv->last_frame.head = dev_priv->prim.tail; sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap; @@ -760,8 +761,7 @@ u32 srcorg = buf->bus_address | MGA_SRCACC_AGP | MGA_SRCMAP_SYSMEM; u32 y2; DMA_LOCALS; - DRM_DEBUG( "%s: buf=%d used=%d\n", - __FUNCTION__, buf->idx, buf->used ); + DRM_DEBUG( "buf=%d used=%d\n", buf->idx, buf->used ); y2 = length / 64; @@ -815,7 +815,7 @@ int nbox = sarea_priv->nbox; u32 scandir = 0, i; DMA_LOCALS; - DRM_DEBUG( "%s:\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); BEGIN_DMA( 4 + nbox ); Index: drivers/char/drm/mga_warp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/mga_warp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/mga_warp.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/mga_warp.c 4 Aug 2004 01:28:48 -0000 1.2 @@ -27,8 +27,11 @@ * Gareth Hughes */ + #include "mga.h" #include "drmP.h" +#include "drm.h" +#include "mga_drm.h" #include "mga_drv.h" #include "mga_ucode.h" Index: drivers/char/drm/r128.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/r128.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/r128.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/r128.h 4 Aug 2004 01:28:48 -0000 1.2 @@ -43,6 +43,35 @@ #define __HAVE_SG 1 #define __HAVE_PCI_DMA 1 +#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." + +#define DRIVER_NAME "r128" +#define DRIVER_DESC "ATI Rage 128" +#define DRIVER_DATE "20010917" + +#define DRIVER_MAJOR 2 +#define DRIVER_MINOR 2 +#define DRIVER_PATCHLEVEL 0 + + +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { r128_cce_buffers, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)] = { r128_fullscreen, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 }, + /* Driver customization: */ #define DRIVER_PRERELEASE() do { \ Index: drivers/char/drm/r128_cce.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/r128_cce.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/r128_cce.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/r128_cce.c 4 Aug 2004 01:28:48 -0000 1.2 @@ -30,14 +30,14 @@ #include "r128.h" #include "drmP.h" +#include "drm.h" +#include "r128_drm.h" #include "r128_drv.h" - -#include /* For task queue support */ -#include +#include "drm_os_linux.h" +#include #define R128_FIFO_DEBUG 0 - /* CCE microcode (from ATI) */ static u32 r128_cce_microcode[] = { 0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0, @@ -83,6 +83,7 @@ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +int r128_do_wait_for_idle( drm_r128_private_t *dev_priv ); int R128_READ_PLL(drm_device_t *dev, int addr) { @@ -131,7 +132,7 @@ } #if R128_FIFO_DEBUG - DRM_ERROR( "%s failed!\n", __FUNCTION__ ); + DRM_ERROR( "failed!\n" ); #endif return -EBUSY; } @@ -147,7 +148,7 @@ } #if R128_FIFO_DEBUG - DRM_ERROR( "%s failed!\n", __FUNCTION__ ); + DRM_ERROR( "failed!\n" ); #endif return -EBUSY; } @@ -157,7 +158,7 @@ int i, ret; ret = r128_do_wait_for_fifo( dev_priv, 64 ); - if ( ret < 0 ) return ret; + if ( ret ) return ret; for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { if ( !(R128_READ( R128_GUI_STAT ) & R128_GUI_ACTIVE) ) { @@ -168,7 +169,7 @@ } #if R128_FIFO_DEBUG - DRM_ERROR( "%s failed!\n", __FUNCTION__ ); + DRM_ERROR( "failed!\n" ); #endif return -EBUSY; } @@ -183,7 +184,7 @@ { int i; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); r128_do_wait_for_idle( dev_priv ); @@ -319,7 +320,7 @@ u32 ring_start; u32 tmp; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); /* The manual (p. 2) says this address is in "VM space". This * means it's an offset from the start of AGP space. @@ -351,8 +352,8 @@ R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, entry->busaddr[page_ofs]); - DRM_DEBUG( "ring rptr: offset=0x%08llx handle=0x%08lx\n", - (u64)entry->busaddr[page_ofs], + DRM_DEBUG( "ring rptr: offset=0x%08x handle=0x%08lx\n", + entry->busaddr[page_ofs], entry->handle + tmp_ofs ); } @@ -374,9 +375,8 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) { drm_r128_private_t *dev_priv; - struct list_head *list; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); dev_priv = DRM(alloc)( sizeof(drm_r128_private_t), DRM_MEM_DRIVER ); if ( dev_priv == NULL ) @@ -481,15 +481,8 @@ dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) | (dev_priv->span_offset >> 5)); - list_for_each(list, &dev->maplist->head) { - drm_map_list_t *r_list = (drm_map_list_t *)list; - if( r_list->map && - r_list->map->type == _DRM_SHM && - r_list->map->flags & _DRM_CONTAINS_LOCK ) { - dev_priv->sarea = r_list->map; - break; - } - } + DRM_GETSAREA(); + if(!dev_priv->sarea) { DRM_ERROR("could not find sarea!\n"); dev->dev_private = (void *)dev_priv; @@ -549,9 +542,9 @@ init->sarea_priv_offset); if ( !dev_priv->is_pci ) { - DRM_IOREMAP( dev_priv->cce_ring ); - DRM_IOREMAP( dev_priv->ring_rptr ); - DRM_IOREMAP( dev_priv->buffers ); + DRM_IOREMAP( dev_priv->cce_ring, dev ); + DRM_IOREMAP( dev_priv->ring_rptr, dev ); + DRM_IOREMAP( dev_priv->buffers, dev ); if(!dev_priv->cce_ring->handle || !dev_priv->ring_rptr->handle || !dev_priv->buffers->handle) { @@ -622,16 +615,20 @@ if ( dev->dev_private ) { drm_r128_private_t *dev_priv = dev->dev_private; +#if __REALLY_HAVE_SG if ( !dev_priv->is_pci ) { - DRM_IOREMAPFREE( dev_priv->cce_ring ); - DRM_IOREMAPFREE( dev_priv->ring_rptr ); - DRM_IOREMAPFREE( dev_priv->buffers ); +#endif + DRM_IOREMAPFREE( dev_priv->cce_ring, dev ); + DRM_IOREMAPFREE( dev_priv->ring_rptr, dev ); + DRM_IOREMAPFREE( dev_priv->buffers, dev ); +#if __REALLY_HAVE_SG } else { if (!DRM(ati_pcigart_cleanup)( dev, dev_priv->phys_pci_gart, dev_priv->bus_pci_gart )) DRM_ERROR( "failed to cleanup PCI GART!\n" ); } +#endif DRM(free)( dev->dev_private, sizeof(drm_r128_private_t), DRM_MEM_DRIVER ); @@ -713,7 +710,7 @@ */ if ( stop.idle ) { ret = r128_do_cce_idle( dev_priv ); - if ( ret < 0 ) return ret; + if ( ret ) return ret; } /* Finally, we can turn off the CCE. If the engine isn't idle, @@ -790,7 +787,7 @@ static int r128_do_init_pageflip( drm_device_t *dev ) { drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); dev_priv->crtc_offset = R128_READ( R128_CRTC_OFFSET ); dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL ); @@ -808,7 +805,7 @@ int r128_do_cleanup_pageflip( drm_device_t *dev ) { drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); R128_WRITE( R128_CRTC_OFFSET, dev_priv->crtc_offset ); R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl ); Index: drivers/char/drm/r128_drm.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/r128_drm.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/r128_drm.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/r128_drm.h 4 Aug 2004 01:28:49 -0000 1.2 @@ -170,6 +170,27 @@ /* WARNING: If you change any of these defines, make sure to change the * defines in the Xserver file (xf86drmR128.h) */ + +/* Rage 128 specific ioctls + * The device specific ioctl range is 0x40 to 0x79. + */ +#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t) +#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41) +#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t) +#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43) +#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44) +#define DRM_IOCTL_R128_RESET DRM_IO( 0x46) +#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47) +#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t) +#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t) +#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t) +#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t) +#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t) +#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t) +#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t) +#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t) +#define DRM_IOCTL_R128_CLEAR2 DRM_IOW( 0x51, drm_r128_clear2_t) + typedef struct drm_r128_init { enum { R128_INIT_CCE = 0x01, Index: drivers/char/drm/r128_drv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/r128_drv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/r128_drv.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/r128_drv.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -32,48 +32,11 @@ #include #include "r128.h" #include "drmP.h" +#include "drm.h" +#include "r128_drm.h" #include "r128_drv.h" #include "ati_pcigart.h" -#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." - -#define DRIVER_NAME "r128" -#define DRIVER_DESC "ATI Rage 128" -#define DRIVER_DATE "20010917" - -#define DRIVER_MAJOR 2 -#define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 0 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { r128_cce_buffers, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)] = { r128_fullscreen, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 }, - - -#if 0 -/* GH: Count data sent to card via ring or vertex/indirect buffers. - */ -#define __HAVE_COUNTERS 3 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY -#endif - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -81,26 +44,6 @@ #include "drm_dma.h" #include "drm_drawable.h" #include "drm_drv.h" - -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init r128_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", r128_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" Index: drivers/char/drm/r128_drv.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/r128_drv.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/r128_drv.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/r128_drv.h 4 Aug 2004 01:28:49 -0000 1.2 @@ -33,9 +33,10 @@ #ifndef __R128_DRV_H__ #define __R128_DRV_H__ +#include -#define GET_RING_HEAD( ring ) le32_to_cpu( *(ring)->head ) -#define SET_RING_HEAD( ring, val ) *(ring)->head = cpu_to_le32( val ) +#define GET_RING_HEAD(ring) readl( (volatile u32 *) (ring)->head ) +#define SET_RING_HEAD(ring,val) writel( (val), (volatile u32 *) (ring)->head ) typedef struct drm_r128_freelist { unsigned int age; @@ -384,44 +385,11 @@ #define R128_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) #define R128_ADDR(reg) (R128_BASE( reg ) + reg) -#define R128_DEREF(reg) *(volatile u32 *)R128_ADDR( reg ) -#ifdef __alpha__ -#define R128_READ(reg) (_R128_READ((u32 *)R128_ADDR(reg))) -static inline u32 _R128_READ(u32 *addr) -{ - mb(); - return *(volatile u32 *)addr; -} -#define R128_WRITE(reg,val) \ -do { \ - wmb(); \ - R128_DEREF(reg) = val; \ -} while (0) -#else -#define R128_READ(reg) le32_to_cpu( R128_DEREF( reg ) ) -#define R128_WRITE(reg,val) \ -do { \ - R128_DEREF( reg ) = cpu_to_le32( val ); \ -} while (0) -#endif +#define R128_READ(reg) readl( (volatile u32 *) R128_ADDR(reg) ) +#define R128_WRITE(reg,val) writel( (val) , (volatile u32 *) R128_ADDR(reg)) -#define R128_DEREF8(reg) *(volatile u8 *)R128_ADDR( reg ) -#ifdef __alpha__ -#define R128_READ8(reg) _R128_READ8((u8 *)R128_ADDR(reg)) -static inline u8 _R128_READ8(u8 *addr) -{ - mb(); - return *(volatile u8 *)addr; -} -#define R128_WRITE8(reg,val) \ -do { \ - wmb(); \ - R128_DEREF8(reg) = val; \ -} while (0) -#else -#define R128_READ8(reg) R128_DEREF8( reg ) -#define R128_WRITE8(reg,val) do { R128_DEREF8( reg ) = val; } while (0) -#endif +#define R128_READ8(reg) readb( (volatile u8 *) R128_ADDR(reg) ) +#define R128_WRITE8(reg,val) writeb( (val), (volatile u8 *) R128_ADDR(reg) ) #define R128_WRITE_PLL(addr,val) \ do { \ @@ -470,6 +438,7 @@ return -EBUSY; \ } \ __ring_space_done: ; \ + break; \ } while (0) #define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ @@ -493,7 +462,11 @@ * Ring control */ +#if defined(__powerpc__) +#define r128_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring ) +#else #define r128_flush_write_combine() mb() +#endif #define R128_VERBOSE 0 Index: drivers/char/drm/r128_state.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/r128_state.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/r128_state.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/r128_state.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -23,15 +23,27 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * RED HAT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * THIS SOFTWARE IS NOT INTENDED FOR USE IN SAFETY CRITICAL SYSTEMS + * * Authors: * Gareth Hughes + * + * Memory allocation size checks added 14/01/2003, Alan Cox */ #include "r128.h" #include "drmP.h" -#include "r128_drv.h" #include "drm.h" -#include +#include "r128_drm.h" +#include "r128_drv.h" /* ================================================================ @@ -528,7 +540,7 @@ { drm_r128_private_t *dev_priv = dev->dev_private; RING_LOCALS; - DRM_DEBUG( "%s: page=%d\n", __FUNCTION__, dev_priv->current_page ); + DRM_DEBUG( "page=%d\n", dev_priv->current_page ); #if R128_PERFORMANCE_BOXES /* Do some trivial performance monitoring... @@ -577,8 +589,7 @@ int prim = buf_priv->prim; int i = 0; RING_LOCALS; - DRM_DEBUG( "%s: buf=%d nbox=%d\n", - __FUNCTION__, buf->idx, sarea_priv->nbox ); + DRM_DEBUG( "buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox ); if ( 0 ) r128_print_dirty( "dispatch_vertex", sarea_priv->dirty ); @@ -789,7 +800,7 @@ u32 *data; int dword_shift, dwords; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); /* The compiler won't optimize away a division by a variable, * even if the only legal values are powers of two. Thus, we'll @@ -902,6 +913,9 @@ DRM_DEBUG( "%s\n", __FUNCTION__ ); count = depth->n; + + if( count > 4096 || count <= 0) + return -EMSGSIZE; if ( copy_from_user( &x, depth->x, sizeof(x) ) ) { return -EFAULT; } @@ -995,6 +1009,9 @@ DRM_DEBUG( "%s\n", __FUNCTION__ ); count = depth->n; + + if( count > 4096 || count <= 0) + return -EMSGSIZE; x = kmalloc( count * sizeof(*x), GFP_KERNEL ); if ( x == NULL ) { @@ -1110,6 +1127,9 @@ DRM_DEBUG( "%s\n", __FUNCTION__ ); count = depth->n; + + if ( count > 4096 || count <= 0) + return -EMSGSIZE; if ( copy_from_user( &x, depth->x, sizeof(x) ) ) { return -EFAULT; } @@ -1152,6 +1172,9 @@ DRM_DEBUG( "%s\n", __FUNCTION__ ); count = depth->n; + if ( count > 4096 || count <= 0) + return -EMSGSIZE; + if ( count > dev_priv->depth_pitch ) { count = dev_priv->depth_pitch; } Index: drivers/char/drm/radeon.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/radeon.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/radeon.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/radeon.h 4 Aug 2004 01:28:49 -0000 1.2 @@ -44,7 +44,78 @@ #define __HAVE_SG 1 #define __HAVE_PCI_DMA 1 -/* Driver customization: +#define DRIVER_AUTHOR "Gareth Hughes, Keith Whitwell, others." + +#define DRIVER_NAME "radeon" +#define DRIVER_DESC "ATI Radeon" +#define DRIVER_DATE "20020828" + +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 7 +#define DRIVER_PATCHLEVEL 0 + +/* Interface history: + * + * 1.1 - ?? + * 1.2 - Add vertex2 ioctl (keith) + * - Add stencil capability to clear ioctl (gareth, keith) + * - Increase MAX_TEXTURE_LEVELS (brian) + * 1.3 - Add cmdbuf ioctl (keith) + * - Add support for new radeon packets (keith) + * - Add getparam ioctl (keith) + * - Add flip-buffers ioctl, deprecate fullscreen foo (keith). + * 1.4 - Add scratch registers to get_param ioctl. + * 1.5 - Add r200 packets to cmdbuf ioctl + * - Add r200 function to init ioctl + * - Add 'scalar2' instruction to cmdbuf + * 1.6 - Add static agp memory manager + * Add irq handler (won't be turned on unless X server knows to) + * Add irq ioctls and irq_active getparam. + * Add wait command for cmdbuf ioctl + * Add agp offset query for getparam + * 1.7 - Add support for cube map registers: R200_PP_CUBIC_FACES_[0..5] + * and R200_PP_CUBIC_OFFSET_F1_[0..5]. + * Added packets R200_EMIT_PP_CUBIC_FACES_[0..5] and + * R200_EMIT_PP_CUBIC_OFFSETS_[0..5]. (brian) + */ +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_INIT)] = { radeon_cp_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)] = { radeon_cp_start, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)] = { radeon_cp_stop, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)] = { radeon_cp_reset, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)] = { radeon_engine_reset, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_TEXTURE)] = { radeon_cp_texture, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX2)] = { radeon_cp_vertex2, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FLIP)] = { radeon_cp_flip, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_ALLOC)] = { radeon_mem_alloc, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FREE)] = { radeon_mem_free, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INIT_HEAP)] = { radeon_mem_init_heap, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_EMIT)] = { radeon_irq_emit, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_WAIT)] = { radeon_irq_wait, 1, 0 }, + + +#define USE_IRQS 1 +#if USE_IRQS +#define __HAVE_DMA_IRQ 1 +#define __HAVE_VBL_IRQ 1 +#define __HAVE_SHARED_IRQ 1 + +/* When a client dies: + * - Check for and clean up flipped page state + * - Free any alloced agp memory. + * + * DRM infrastructure takes care of reclaiming dma buffers. */ #define DRIVER_PRERELEASE() do { \ if ( dev->dev_private ) { \ @@ -52,31 +123,36 @@ if ( dev_priv->page_flipping ) { \ radeon_do_cleanup_pageflip( dev ); \ } \ + radeon_mem_release( dev_priv->agp_heap ); \ } \ } while (0) +/* On unloading the module: + * - Free memory heap structure + * - Remove mappings made at startup and free dev_private. + */ #define DRIVER_PRETAKEDOWN() do { \ - if ( dev->dev_private ) radeon_do_cleanup_cp( dev ); \ + if ( dev->dev_private ) { \ + drm_radeon_private_t *dev_priv = dev->dev_private; \ + radeon_mem_takedown( &(dev_priv->agp_heap) ); \ + radeon_do_cleanup_cp( dev ); \ + } \ } while (0) +#else +#define __HAVE_DMA_IRQ 0 +#endif + /* DMA customization: */ #define __HAVE_DMA 1 -#if 0 -/* GH: Remove this for now... */ -#define __HAVE_DMA_QUIESCENT 1 -#define DRIVER_DMA_QUIESCENT() do { \ - drm_radeon_private_t *dev_priv = dev->dev_private; \ - return radeon_do_cp_idle( dev_priv ); \ -} while (0) -#endif /* Buffer customization: */ #define DRIVER_BUF_PRIV_T drm_radeon_buf_priv_t -#define DRIVER_AGP_BUFFERS_MAP( dev ) \ +#define DRIVER_AGP_BUFFERS_MAP( dev ) \ ((drm_radeon_private_t *)((dev)->dev_private))->buffers #endif Index: drivers/char/drm/radeon_cp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/radeon_cp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/radeon_cp.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/radeon_cp.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -30,21 +30,278 @@ #include "radeon.h" #include "drmP.h" +#include "drm.h" +#include "radeon_drm.h" #include "radeon_drv.h" +#include "drm_os_linux.h" #include /* For task queue support */ #include - #define RADEON_FIFO_DEBUG 0 -#if defined(__alpha__) -# define PCIGART_ENABLED -#else -# undef PCIGART_ENABLED -#endif /* CP microcode (from ATI) */ +static u32 R200_cp_microcode[][2] = { + { 0x21007000, 0000000000 }, + { 0x20007000, 0000000000 }, + { 0x000000ab, 0x00000004 }, + { 0x000000af, 0x00000004 }, + { 0x66544a49, 0000000000 }, + { 0x49494174, 0000000000 }, + { 0x54517d83, 0000000000 }, + { 0x498d8b64, 0000000000 }, + { 0x49494949, 0000000000 }, + { 0x49da493c, 0000000000 }, + { 0x49989898, 0000000000 }, + { 0xd34949d5, 0000000000 }, + { 0x9dc90e11, 0000000000 }, + { 0xce9b9b9b, 0000000000 }, + { 0x000f0000, 0x00000016 }, + { 0x352e232c, 0000000000 }, + { 0x00000013, 0x00000004 }, + { 0x000f0000, 0x00000016 }, + { 0x352e272c, 0000000000 }, + { 0x000f0001, 0x00000016 }, + { 0x3239362f, 0000000000 }, + { 0x000077ef, 0x00000002 }, + { 0x00061000, 0x00000002 }, + { 0x00000020, 0x0000001a }, + { 0x00004000, 0x0000001e }, + { 0x00061000, 0x00000002 }, + { 0x00000020, 0x0000001a }, + { 0x00004000, 0x0000001e }, + { 0x00061000, 0x00000002 }, + { 0x00000020, 0x0000001a }, + { 0x00004000, 0x0000001e }, + { 0x00000016, 0x00000004 }, + { 0x0003802a, 0x00000002 }, + { 0x040067e0, 0x00000002 }, + { 0x00000016, 0x00000004 }, + { 0x000077e0, 0x00000002 }, + { 0x00065000, 0x00000002 }, + { 0x000037e1, 0x00000002 }, + { 0x040067e1, 0x00000006 }, + { 0x000077e0, 0x00000002 }, + { 0x000077e1, 0x00000002 }, + { 0x000077e1, 0x00000006 }, + { 0xffffffff, 0000000000 }, + { 0x10000000, 0000000000 }, + { 0x0003802a, 0x00000002 }, + { 0x040067e0, 0x00000006 }, + { 0x00007675, 0x00000002 }, + { 0x00007676, 0x00000002 }, + { 0x00007677, 0x00000002 }, + { 0x00007678, 0x00000006 }, + { 0x0003802b, 0x00000002 }, + { 0x04002676, 0x00000002 }, + { 0x00007677, 0x00000002 }, + { 0x00007678, 0x00000006 }, + { 0x0000002e, 0x00000018 }, + { 0x0000002e, 0x00000018 }, + { 0000000000, 0x00000006 }, + { 0x0000002f, 0x00000018 }, + { 0x0000002f, 0x00000018 }, + { 0000000000, 0x00000006 }, + { 0x01605000, 0x00000002 }, + { 0x00065000, 0x00000002 }, + { 0x00098000, 0x00000002 }, + { 0x00061000, 0x00000002 }, + { 0x64c0603d, 0x00000004 }, + { 0x00080000, 0x00000016 }, + { 0000000000, 0000000000 }, + { 0x0400251d, 0x00000002 }, + { 0x00007580, 0x00000002 }, + { 0x00067581, 0x00000002 }, + { 0x04002580, 0x00000002 }, + { 0x00067581, 0x00000002 }, + { 0x00000046, 0x00000004 }, + { 0x00005000, 0000000000 }, + { 0x00061000, 0x00000002 }, + { 0x0000750e, 0x00000002 }, + { 0x00019000, 0x00000002 }, + { 0x00011055, 0x00000014 }, + { 0x00000055, 0x00000012 }, + { 0x0400250f, 0x00000002 }, + { 0x0000504a, 0x00000004 }, + { 0x00007565, 0x00000002 }, + { 0x00007566, 0x00000002 }, + { 0x00000051, 0x00000004 }, + { 0x01e655b4, 0x00000002 }, + { 0x4401b0dc, 0x00000002 }, + { 0x01c110dc, 0x00000002 }, + { 0x2666705d, 0x00000018 }, + { 0x040c2565, 0x00000002 }, + { 0x0000005d, 0x00000018 }, + { 0x04002564, 0x00000002 }, + { 0x00007566, 0x00000002 }, + { 0x00000054, 0x00000004 }, + { 0x00401060, 0x00000008 }, + { 0x00101000, 0x00000002 }, + { 0x000d80ff, 0x00000002 }, + { 0x00800063, 0x00000008 }, + { 0x000f9000, 0x00000002 }, + { 0x000e00ff, 0x00000002 }, + { 0000000000, 0x00000006 }, + { 0x00000080, 0x00000018 }, + { 0x00000054, 0x00000004 }, + { 0x00007576, 0x00000002 }, + { 0x00065000, 0x00000002 }, + { 0x00009000, 0x00000002 }, + { 0x00041000, 0x00000002 }, + { 0x0c00350e, 0x00000002 }, + { 0x00049000, 0x00000002 }, + { 0x00051000, 0x00000002 }, + { 0x01e785f8, 0x00000002 }, + { 0x00200000, 0x00000002 }, + { 0x00600073, 0x0000000c }, + { 0x00007563, 0x00000002 }, + { 0x006075f0, 0x00000021 }, + { 0x20007068, 0x00000004 }, + { 0x00005068, 0x00000004 }, + { 0x00007576, 0x00000002 }, + { 0x00007577, 0x00000002 }, + { 0x0000750e, 0x00000002 }, + { 0x0000750f, 0x00000002 }, + { 0x00a05000, 0x00000002 }, + { 0x00600076, 0x0000000c }, + { 0x006075f0, 0x00000021 }, + { 0x000075f8, 0x00000002 }, + { 0x00000076, 0x00000004 }, + { 0x000a750e, 0x00000002 }, + { 0x0020750f, 0x00000002 }, + { 0x00600079, 0x00000004 }, + { 0x00007570, 0x00000002 }, + { 0x00007571, 0x00000002 }, + { 0x00007572, 0x00000006 }, + { 0x00005000, 0x00000002 }, + { 0x00a05000, 0x00000002 }, + { 0x00007568, 0x00000002 }, + { 0x00061000, 0x00000002 }, + { 0x00000084, 0x0000000c }, + { 0x00058000, 0x00000002 }, + { 0x0c607562, 0x00000002 }, + { 0x00000086, 0x00000004 }, + { 0x00600085, 0x00000004 }, + { 0x400070dd, 0000000000 }, + { 0x000380dd, 0x00000002 }, + { 0x00000093, 0x0000001c }, + { 0x00065095, 0x00000018 }, + { 0x040025bb, 0x00000002 }, + { 0x00061096, 0x00000018 }, + { 0x040075bc, 0000000000 }, + { 0x000075bb, 0x00000002 }, + { 0x000075bc, 0000000000 }, + { 0x00090000, 0x00000006 }, + { 0x00090000, 0x00000002 }, + { 0x000d8002, 0x00000006 }, + { 0x00005000, 0x00000002 }, + { 0x00007821, 0x00000002 }, + { 0x00007800, 0000000000 }, + { 0x00007821, 0x00000002 }, + { 0x00007800, 0000000000 }, + { 0x01665000, 0x00000002 }, + { 0x000a0000, 0x00000002 }, + { 0x000671cc, 0x00000002 }, + { 0x0286f1cd, 0x00000002 }, + { 0x000000a3, 0x00000010 }, + { 0x21007000, 0000000000 }, + { 0x000000aa, 0x0000001c }, + { 0x00065000, 0x00000002 }, + { 0x000a0000, 0x00000002 }, + { 0x00061000, 0x00000002 }, + { 0x000b0000, 0x00000002 }, + { 0x38067000, 0x00000002 }, + { 0x000a00a6, 0x00000004 }, + { 0x20007000, 0000000000 }, + { 0x01200000, 0x00000002 }, + { 0x20077000, 0x00000002 }, + { 0x01200000, 0x00000002 }, + { 0x20007000, 0000000000 }, + { 0x00061000, 0x00000002 }, + { 0x0120751b, 0x00000002 }, + { 0x8040750a, 0x00000002 }, + { 0x8040750b, 0x00000002 }, + { 0x00110000, 0x00000002 }, + { 0x000380dd, 0x00000002 }, + { 0x000000bd, 0x0000001c }, + { 0x00061096, 0x00000018 }, + { 0x844075bd, 0x00000002 }, + { 0x00061095, 0x00000018 }, + { 0x840075bb, 0x00000002 }, + { 0x00061096, 0x00000018 }, + { 0x844075bc, 0x00000002 }, + { 0x000000c0, 0x00000004 }, + { 0x804075bd, 0x00000002 }, + { 0x800075bb, 0x00000002 }, + { 0x804075bc, 0x00000002 }, + { 0x00108000, 0x00000002 }, + { 0x01400000, 0x00000002 }, + { 0x006000c4, 0x0000000c }, + { 0x20c07000, 0x00000020 }, + { 0x000000c6, 0x00000012 }, + { 0x00800000, 0x00000006 }, + { 0x0080751d, 0x00000006 }, + { 0x000025bb, 0x00000002 }, + { 0x000040c0, 0x00000004 }, + { 0x0000775c, 0x00000002 }, + { 0x00a05000, 0x00000002 }, + { 0x00661000, 0x00000002 }, + { 0x0460275d, 0x00000020 }, + { 0x00004000, 0000000000 }, + { 0x00007999, 0x00000002 }, + { 0x00a05000, 0x00000002 }, + { 0x00661000, 0x00000002 }, + { 0x0460299b, 0x00000020 }, + { 0x00004000, 0000000000 }, + { 0x01e00830, 0x00000002 }, + { 0x21007000, 0000000000 }, + { 0x00005000, 0x00000002 }, + { 0x00038042, 0x00000002 }, + { 0x040025e0, 0x00000002 }, + { 0x000075e1, 0000000000 }, + { 0x00000001, 0000000000 }, + { 0x000380d9, 0x00000002 }, + { 0x04007394, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, +}; + + static u32 radeon_cp_microcode[][2] = { { 0x21007000, 0000000000 }, { 0x20007000, 0000000000 }, @@ -346,6 +603,8 @@ u32 tmp; int i; + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; + tmp = RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT ); tmp |= RADEON_RB2D_DC_FLUSH_ALL; RADEON_WRITE( RADEON_RB2D_DSTCACHE_CTLSTAT, tmp ); @@ -370,6 +629,8 @@ { int i; + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { int slots = ( RADEON_READ( RADEON_RBBM_STATUS ) & RADEON_RBBM_FIFOCNT_MASK ); @@ -388,8 +649,10 @@ { int i, ret; + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; + ret = radeon_do_wait_for_fifo( dev_priv, 64 ); - if ( ret < 0 ) return ret; + if ( ret ) return ret; for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { if ( !(RADEON_READ( RADEON_RBBM_STATUS ) @@ -416,16 +679,31 @@ static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv ) { int i; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); radeon_do_wait_for_idle( dev_priv ); RADEON_WRITE( RADEON_CP_ME_RAM_ADDR, 0 ); - for ( i = 0 ; i < 256 ; i++ ) { - RADEON_WRITE( RADEON_CP_ME_RAM_DATAH, - radeon_cp_microcode[i][1] ); - RADEON_WRITE( RADEON_CP_ME_RAM_DATAL, - radeon_cp_microcode[i][0] ); + + if (dev_priv->is_r200) + { + DRM_INFO("Loading R200 Microcode\n"); + for ( i = 0 ; i < 256 ; i++ ) + { + RADEON_WRITE( RADEON_CP_ME_RAM_DATAH, + R200_cp_microcode[i][1] ); + RADEON_WRITE( RADEON_CP_ME_RAM_DATAL, + R200_cp_microcode[i][0] ); + } + } + else + { + for ( i = 0 ; i < 256 ; i++ ) { + RADEON_WRITE( RADEON_CP_ME_RAM_DATAH, + radeon_cp_microcode[i][1] ); + RADEON_WRITE( RADEON_CP_ME_RAM_DATAL, + radeon_cp_microcode[i][0] ); + } } } @@ -435,7 +713,7 @@ */ static void radeon_do_cp_flush( drm_radeon_private_t *dev_priv ) { - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); #if 0 u32 tmp; @@ -449,7 +727,7 @@ int radeon_do_cp_idle( drm_radeon_private_t *dev_priv ) { RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); BEGIN_RING( 6 ); @@ -458,6 +736,7 @@ RADEON_WAIT_UNTIL_IDLE(); ADVANCE_RING(); + COMMIT_RING(); return radeon_do_wait_for_idle( dev_priv ); } @@ -467,7 +746,7 @@ static void radeon_do_cp_start( drm_radeon_private_t *dev_priv ) { RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); radeon_do_wait_for_idle( dev_priv ); @@ -482,6 +761,7 @@ RADEON_WAIT_UNTIL_IDLE(); ADVANCE_RING(); + COMMIT_RING(); } /* Reset the Command Processor. This will not flush any pending @@ -491,7 +771,7 @@ static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv ) { u32 cur_read_ptr; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); @@ -505,7 +785,7 @@ */ static void radeon_do_cp_stop( drm_radeon_private_t *dev_priv ) { - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); RADEON_WRITE( RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS ); @@ -518,7 +798,7 @@ { drm_radeon_private_t *dev_priv = dev->dev_private; u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); radeon_do_pixcache_flush( dev_priv ); @@ -603,6 +883,7 @@ /* Set the write pointer delay */ RADEON_WRITE( RADEON_CP_RB_WPTR_DELAY, 0 ); + RADEON_READ( RADEON_CP_RB_WPTR_DELAY ); /* read back to propagate */ /* Initialize the ring buffer's read and write pointers */ cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); @@ -622,13 +903,63 @@ RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]); - DRM_DEBUG( "ring rptr: offset=0x%08llx handle=0x%08lx\n", - (u64)entry->busaddr[page_ofs], + DRM_DEBUG( "ring rptr: offset=0x%08x handle=0x%08lx\n", + entry->busaddr[page_ofs], entry->handle + tmp_ofs ); } + /* Initialize the scratch register pointer. This will cause + * the scratch register values to be written out to memory + * whenever they are updated. + * + * We simply put this behind the ring read pointer, this works + * with PCI GART as well as (whatever kind of) AGP GART + */ + RADEON_WRITE( RADEON_SCRATCH_ADDR, RADEON_READ( RADEON_CP_RB_RPTR_ADDR ) + + RADEON_SCRATCH_REG_OFFSET ); + + dev_priv->scratch = ((__volatile__ u32 *) + dev_priv->ring.head + + (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); + + RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 ); + + /* Writeback doesn't seem to work everywhere, test it first */ + writel(0, &dev_priv->scratch[1]); + RADEON_WRITE( RADEON_SCRATCH_REG1, 0xdeadbeef ); + + for ( tmp = 0 ; tmp < dev_priv->usec_timeout ; tmp++ ) { + if ( readl( &dev_priv->scratch[1] ) == 0xdeadbeef ) + break; + udelay(1); + } + + if ( tmp < dev_priv->usec_timeout ) { + dev_priv->writeback_works = 1; + DRM_DEBUG( "writeback test succeeded, tmp=%d\n", tmp ); + } else { + dev_priv->writeback_works = 0; + DRM_DEBUG( "writeback test failed\n" ); + } + + dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; + RADEON_WRITE( RADEON_LAST_FRAME_REG, + dev_priv->sarea_priv->last_frame ); + + dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0; + RADEON_WRITE( RADEON_LAST_DISPATCH_REG, + dev_priv->sarea_priv->last_dispatch ); + + dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0; + RADEON_WRITE( RADEON_LAST_CLEAR_REG, + dev_priv->sarea_priv->last_clear ); + /* Set ring buffer size */ +#ifdef __BIG_ENDIAN + RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT ); +#else RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw ); +#endif radeon_do_wait_for_idle( dev_priv ); @@ -647,9 +978,8 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) { drm_radeon_private_t *dev_priv; - struct list_head *list; u32 tmp; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER ); if ( dev_priv == NULL ) @@ -659,17 +989,6 @@ dev_priv->is_pci = init->is_pci; -#if !defined(PCIGART_ENABLED) - /* PCI support is not 100% working, so we disable it here. - */ - if ( dev_priv->is_pci ) { - DRM_ERROR( "PCI GART not yet supported for Radeon!\n" ); - dev->dev_private = (void *)dev_priv; - radeon_do_cleanup_cp(dev); - return -EINVAL; - } -#endif - if ( dev_priv->is_pci && !dev->sg ) { DRM_ERROR( "PCI GART memory not allocated!\n" ); dev->dev_private = (void *)dev_priv; @@ -686,12 +1005,10 @@ return -EINVAL; } + dev_priv->is_r200 = (init->func == RADEON_INIT_R200_CP); + dev_priv->do_boxes = 0; dev_priv->cp_mode = init->cp_mode; - /* Simple idle check. - */ - atomic_set( &dev_priv->idle_count, 0 ); - /* We don't support anything other than bus-mastering ring mode, * but the ring can be in either AGP or PCI space for the ring * read pointer. @@ -743,17 +1060,17 @@ * and screwing with the clear operation. */ dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | - RADEON_Z_ENABLE | (dev_priv->color_fmt << 10) | - RADEON_ZBLOCK16); + (1<<15)); - dev_priv->depth_clear.rb3d_zstencilcntl = (dev_priv->depth_fmt | - RADEON_Z_TEST_ALWAYS | - RADEON_STENCIL_TEST_ALWAYS | - RADEON_STENCIL_S_FAIL_KEEP | - RADEON_STENCIL_ZPASS_KEEP | - RADEON_STENCIL_ZFAIL_KEEP | - RADEON_Z_WRITE_ENABLE); + dev_priv->depth_clear.rb3d_zstencilcntl = + (dev_priv->depth_fmt | + RADEON_Z_TEST_ALWAYS | + RADEON_STENCIL_TEST_ALWAYS | + RADEON_STENCIL_S_FAIL_REPLACE | + RADEON_STENCIL_ZPASS_REPLACE | + RADEON_STENCIL_ZFAIL_REPLACE | + RADEON_Z_WRITE_ENABLE); dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW | RADEON_BFACE_SOLID | @@ -767,15 +1084,8 @@ RADEON_ROUND_MODE_TRUNC | RADEON_ROUND_PREC_8TH_PIX); - list_for_each(list, &dev->maplist->head) { - drm_map_list_t *r_list = (drm_map_list_t *)list; - if( r_list->map && - r_list->map->type == _DRM_SHM && - r_list->map->flags & _DRM_CONTAINS_LOCK ) { - dev_priv->sarea = r_list->map; - break; - } - } + DRM_GETSAREA(); + if(!dev_priv->sarea) { DRM_ERROR("could not find sarea!\n"); dev->dev_private = (void *)dev_priv; @@ -835,9 +1145,9 @@ init->sarea_priv_offset); if ( !dev_priv->is_pci ) { - DRM_IOREMAP( dev_priv->cp_ring ); - DRM_IOREMAP( dev_priv->ring_rptr ); - DRM_IOREMAP( dev_priv->buffers ); + DRM_IOREMAP( dev_priv->cp_ring, dev ); + DRM_IOREMAP( dev_priv->ring_rptr, dev ); + DRM_IOREMAP( dev_priv->buffers, dev ); if(!dev_priv->cp_ring->handle || !dev_priv->ring_rptr->handle || !dev_priv->buffers->handle) { @@ -896,34 +1206,7 @@ dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; -#if 0 - /* Initialize the scratch register pointer. This will cause - * the scratch register values to be written out to memory - * whenever they are updated. - * FIXME: This doesn't quite work yet, so we're disabling it - * for the release. - */ - RADEON_WRITE( RADEON_SCRATCH_ADDR, (dev_priv->ring_rptr->offset + - RADEON_SCRATCH_REG_OFFSET) ); - RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 ); -#endif - - dev_priv->scratch = ((__volatile__ u32 *) - dev_priv->ring_rptr->handle + - (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); - - dev_priv->sarea_priv->last_frame = 0; - RADEON_WRITE( RADEON_LAST_FRAME_REG, - dev_priv->sarea_priv->last_frame ); - - dev_priv->sarea_priv->last_dispatch = 0; - RADEON_WRITE( RADEON_LAST_DISPATCH_REG, - dev_priv->sarea_priv->last_dispatch ); - - dev_priv->sarea_priv->last_clear = 0; - RADEON_WRITE( RADEON_LAST_CLEAR_REG, - dev_priv->sarea_priv->last_clear ); - +#if __REALLY_HAVE_SG if ( dev_priv->is_pci ) { if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart, &dev_priv->bus_pci_gart)) { @@ -953,19 +1236,20 @@ RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */ RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */ } else { +#endif /* __REALLY_HAVE_SG */ /* Turn off PCI GART */ tmp = RADEON_READ( RADEON_AIC_CNTL ) & ~RADEON_PCIGART_TRANSLATE_EN; RADEON_WRITE( RADEON_AIC_CNTL, tmp ); +#if __REALLY_HAVE_SG } +#endif /* __REALLY_HAVE_SG */ radeon_cp_load_microcode( dev_priv ); radeon_cp_init_ring_buffer( dev, dev_priv ); -#if ROTATE_BUFS dev_priv->last_buf = 0; -#endif dev->dev_private = (void *)dev_priv; @@ -976,20 +1260,22 @@ int radeon_do_cleanup_cp( drm_device_t *dev ) { - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); if ( dev->dev_private ) { drm_radeon_private_t *dev_priv = dev->dev_private; if ( !dev_priv->is_pci ) { - DRM_IOREMAPFREE( dev_priv->cp_ring ); - DRM_IOREMAPFREE( dev_priv->ring_rptr ); - DRM_IOREMAPFREE( dev_priv->buffers ); + DRM_IOREMAPFREE( dev_priv->cp_ring, dev ); + DRM_IOREMAPFREE( dev_priv->ring_rptr, dev ); + DRM_IOREMAPFREE( dev_priv->buffers, dev ); } else { +#if __REALLY_HAVE_SG if (!DRM(ati_pcigart_cleanup)( dev, dev_priv->phys_pci_gart, dev_priv->bus_pci_gart )) DRM_ERROR( "failed to cleanup PCI GART!\n" ); +#endif /* __REALLY_HAVE_SG */ } DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t), @@ -1012,6 +1298,7 @@ switch ( init.func ) { case RADEON_INIT_CP: + case RADEON_INIT_R200_CP: return radeon_do_init_cp( dev, &init ); case RADEON_CLEANUP_CP: return radeon_do_cleanup_cp( dev ); @@ -1075,7 +1362,7 @@ */ if ( stop.idle ) { ret = radeon_do_cp_idle( dev_priv ); - if ( ret < 0 ) return ret; + if ( ret ) return ret; } /* Finally, we can turn off the CP. If the engine isn't idle, @@ -1145,117 +1432,74 @@ * Fullscreen mode */ -static int radeon_do_init_pageflip( drm_device_t *dev ) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "%s\n", __FUNCTION__ ); - - dev_priv->crtc_offset = RADEON_READ( RADEON_CRTC_OFFSET ); - dev_priv->crtc_offset_cntl = RADEON_READ( RADEON_CRTC_OFFSET_CNTL ); - - RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->front_offset ); - RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL, - dev_priv->crtc_offset_cntl | - RADEON_CRTC_OFFSET_FLIP_CNTL ); - - dev_priv->page_flipping = 1; - dev_priv->current_page = 0; - - return 0; -} - -int radeon_do_cleanup_pageflip( drm_device_t *dev ) +/* KW: Deprecated to say the least: + */ +int radeon_fullscreen(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data) { - drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "%s\n", __FUNCTION__ ); - - RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->crtc_offset ); - RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl ); - - dev_priv->page_flipping = 0; - dev_priv->current_page = 0; - return 0; } -int radeon_fullscreen( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_radeon_fullscreen_t fs; - - LOCK_TEST_WITH_RETURN( dev ); - - if ( copy_from_user( &fs, (drm_radeon_fullscreen_t *)arg, - sizeof(fs) ) ) - return -EFAULT; - - switch ( fs.func ) { - case RADEON_INIT_FULLSCREEN: - return radeon_do_init_pageflip( dev ); - case RADEON_CLEANUP_FULLSCREEN: - return radeon_do_cleanup_pageflip( dev ); - } - - return -EINVAL; -} - /* ================================================================ * Freelist management */ -#define RADEON_BUFFER_USED 0xffffffff -#define RADEON_BUFFER_FREE 0 -#if 0 -static int radeon_freelist_init( drm_device_t *dev ) +/* Original comment: FIXME: ROTATE_BUFS is a hack to cycle through + * bufs until freelist code is used. Note this hides a problem with + * the scratch register * (used to keep track of last buffer + * completed) being written to before * the last buffer has actually + * completed rendering. + * + * KW: It's also a good way to find free buffers quickly. + * + * KW: Ideally this loop wouldn't exist, and freelist_get wouldn't + * sleep. However, bugs in older versions of radeon_accel.c mean that + * we essentially have to do this, else old clients will break. + * + * However, it does leave open a potential deadlock where all the + * buffers are held by other clients, which can't release them because + * they can't get the lock. + */ + +drm_buf_t *radeon_freelist_get( drm_device_t *dev ) { drm_device_dma_t *dma = dev->dma; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_buf_t *buf; drm_radeon_buf_priv_t *buf_priv; - drm_radeon_freelist_t *entry; - int i; - - dev_priv->head = DRM(alloc)( sizeof(drm_radeon_freelist_t), - DRM_MEM_DRIVER ); - if ( dev_priv->head == NULL ) - return -ENOMEM; - - memset( dev_priv->head, 0, sizeof(drm_radeon_freelist_t) ); - dev_priv->head->age = RADEON_BUFFER_USED; + drm_buf_t *buf; + int i, t; + int start; - for ( i = 0 ; i < dma->buf_count ; i++ ) { - buf = dma->buflist[i]; - buf_priv = buf->dev_private; + if ( ++dev_priv->last_buf >= dma->buf_count ) + dev_priv->last_buf = 0; - entry = DRM(alloc)( sizeof(drm_radeon_freelist_t), - DRM_MEM_DRIVER ); - if ( !entry ) return -ENOMEM; - - entry->age = RADEON_BUFFER_FREE; - entry->buf = buf; - entry->prev = dev_priv->head; - entry->next = dev_priv->head->next; - if ( !entry->next ) - dev_priv->tail = entry; - - buf_priv->discard = 0; - buf_priv->dispatched = 0; - buf_priv->list_entry = entry; + start = dev_priv->last_buf; - dev_priv->head->next = entry; + for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) { + u32 done_age = GET_SCRATCH( 1 ); + DRM_DEBUG("done_age = %d\n",done_age); + for ( i = start ; i < dma->buf_count ; i++ ) { + buf = dma->buflist[i]; + buf_priv = buf->dev_private; + if ( buf->pid == 0 || (buf->pending && + buf_priv->age <= done_age) ) { + dev_priv->stats.requested_bufs++; + buf->pending = 0; + return buf; + } + start = 0; + } - if ( dev_priv->head->next ) - dev_priv->head->next->prev = entry; + if (t) { + udelay(1); + dev_priv->stats.freelist_loops++; + } } - return 0; - + DRM_DEBUG( "returning NULL!\n" ); + return NULL; } -#endif - +#if 0 drm_buf_t *radeon_freelist_get( drm_device_t *dev ) { drm_device_dma_t *dma = dev->dma; @@ -1263,76 +1507,40 @@ drm_radeon_buf_priv_t *buf_priv; drm_buf_t *buf; int i, t; -#if ROTATE_BUFS int start; -#endif - - /* FIXME: Optimize -- use freelist code */ + u32 done_age = readl(&dev_priv->scratch[1]); - for ( i = 0 ; i < dma->buf_count ; i++ ) { - buf = dma->buflist[i]; - buf_priv = buf->dev_private; - if ( buf->pid == 0 ) { - DRM_DEBUG( " ret buf=%d last=%d pid=0\n", - buf->idx, dev_priv->last_buf ); - return buf; - } - DRM_DEBUG( " skipping buf=%d pid=%d\n", - buf->idx, buf->pid ); - } - -#if ROTATE_BUFS if ( ++dev_priv->last_buf >= dma->buf_count ) dev_priv->last_buf = 0; + start = dev_priv->last_buf; -#endif - for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) { -#if 0 - /* FIXME: Disable this for now */ - u32 done_age = dev_priv->scratch[RADEON_LAST_DISPATCH]; -#else - u32 done_age = RADEON_READ( RADEON_LAST_DISPATCH_REG ); -#endif -#if ROTATE_BUFS + dev_priv->stats.freelist_loops++; + + for ( t = 0 ; t < 2 ; t++ ) { for ( i = start ; i < dma->buf_count ; i++ ) { -#else - for ( i = 0 ; i < dma->buf_count ; i++ ) { -#endif buf = dma->buflist[i]; buf_priv = buf->dev_private; - if ( buf->pending && buf_priv->age <= done_age ) { - /* The buffer has been processed, so it - * can now be used. - */ + if ( buf->pid == 0 || (buf->pending && + buf_priv->age <= done_age) ) { + dev_priv->stats.requested_bufs++; buf->pending = 0; - DRM_DEBUG( " ret buf=%d last=%d age=%d done=%d\n", buf->idx, dev_priv->last_buf, buf_priv->age, done_age ); return buf; } - DRM_DEBUG( " skipping buf=%d age=%d done=%d\n", - buf->idx, buf_priv->age, - done_age ); -#if ROTATE_BUFS - start = 0; -#endif } - udelay( 1 ); + start = 0; } - DRM_ERROR( "returning NULL!\n" ); return NULL; } +#endif void radeon_freelist_reset( drm_device_t *dev ) { drm_device_dma_t *dma = dev->dma; -#if ROTATE_BUFS drm_radeon_private_t *dev_priv = dev->dev_private; -#endif int i; -#if ROTATE_BUFS dev_priv->last_buf = 0; -#endif for ( i = 0 ; i < dma->buf_count ; i++ ) { drm_buf_t *buf = dma->buflist[i]; drm_radeon_buf_priv_t *buf_priv = buf->dev_private; @@ -1349,11 +1557,23 @@ { drm_radeon_ring_buffer_t *ring = &dev_priv->ring; int i; + u32 last_head = GET_RING_HEAD(ring); for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - radeon_update_ring_snapshot( ring ); + u32 head = GET_RING_HEAD(ring); + + ring->space = (head - ring->tail) * sizeof(u32); + if ( ring->space <= 0 ) + ring->space += ring->size; if ( ring->space > n ) return 0; + + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; + + if (head != last_head) + i = 0; + last_head = head; + udelay( 1 ); } Index: drivers/char/drm/radeon_drm.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/radeon_drm.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/radeon_drm.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/radeon_drm.h 4 Aug 2004 01:28:49 -0000 1.2 @@ -2,6 +2,7 @@ * * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Fremont, California. + * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -26,6 +27,7 @@ * Authors: * Kevin E. Martin * Gareth Hughes + * Keith Whitwell */ #ifndef __RADEON_DRM_H__ @@ -37,7 +39,8 @@ #ifndef __RADEON_SAREA_DEFINES__ #define __RADEON_SAREA_DEFINES__ -/* What needs to be changed for the current vertex buffer? +/* Old style state flags, required for sarea interface (1.1 and 1.2 + * clears) and 1.2 drm_vertex2 ioctl. */ #define RADEON_UPLOAD_CONTEXT 0x00000001 #define RADEON_UPLOAD_VERTFMT 0x00000002 @@ -56,11 +59,136 @@ #define RADEON_UPLOAD_TEX2IMAGES 0x00004000 #define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */ #define RADEON_REQUIRE_QUIESCENCE 0x00010000 -#define RADEON_UPLOAD_ALL 0x0001ffff +#define RADEON_UPLOAD_ZBIAS 0x00020000 /* version 1.2 and newer */ +#define RADEON_UPLOAD_ALL 0x003effff +#define RADEON_UPLOAD_CONTEXT_ALL 0x003e01ff + + +/* New style per-packet identifiers for use in cmd_buffer ioctl with + * the RADEON_EMIT_PACKET command. Comments relate new packets to old + * state bits and the packet size: + */ +#define RADEON_EMIT_PP_MISC 0 /* context/7 */ +#define RADEON_EMIT_PP_CNTL 1 /* context/3 */ +#define RADEON_EMIT_RB3D_COLORPITCH 2 /* context/1 */ +#define RADEON_EMIT_RE_LINE_PATTERN 3 /* line/2 */ +#define RADEON_EMIT_SE_LINE_WIDTH 4 /* line/1 */ +#define RADEON_EMIT_PP_LUM_MATRIX 5 /* bumpmap/1 */ +#define RADEON_EMIT_PP_ROT_MATRIX_0 6 /* bumpmap/2 */ +#define RADEON_EMIT_RB3D_STENCILREFMASK 7 /* masks/3 */ +#define RADEON_EMIT_SE_VPORT_XSCALE 8 /* viewport/6 */ +#define RADEON_EMIT_SE_CNTL 9 /* setup/2 */ +#define RADEON_EMIT_SE_CNTL_STATUS 10 /* setup/1 */ +#define RADEON_EMIT_RE_MISC 11 /* misc/1 */ +#define RADEON_EMIT_PP_TXFILTER_0 12 /* tex0/6 */ +#define RADEON_EMIT_PP_BORDER_COLOR_0 13 /* tex0/1 */ +#define RADEON_EMIT_PP_TXFILTER_1 14 /* tex1/6 */ +#define RADEON_EMIT_PP_BORDER_COLOR_1 15 /* tex1/1 */ +#define RADEON_EMIT_PP_TXFILTER_2 16 /* tex2/6 */ +#define RADEON_EMIT_PP_BORDER_COLOR_2 17 /* tex2/1 */ +#define RADEON_EMIT_SE_ZBIAS_FACTOR 18 /* zbias/2 */ +#define RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT 19 /* tcl/11 */ +#define RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED 20 /* material/17 */ +#define R200_EMIT_PP_TXCBLEND_0 21 /* tex0/4 */ +#define R200_EMIT_PP_TXCBLEND_1 22 /* tex1/4 */ +#define R200_EMIT_PP_TXCBLEND_2 23 /* tex2/4 */ +#define R200_EMIT_PP_TXCBLEND_3 24 /* tex3/4 */ +#define R200_EMIT_PP_TXCBLEND_4 25 /* tex4/4 */ +#define R200_EMIT_PP_TXCBLEND_5 26 /* tex5/4 */ +#define R200_EMIT_PP_TXCBLEND_6 27 /* /4 */ +#define R200_EMIT_PP_TXCBLEND_7 28 /* /4 */ +#define R200_EMIT_TCL_LIGHT_MODEL_CTL_0 29 /* tcl/7 */ +#define R200_EMIT_TFACTOR_0 30 /* tf/7 */ +#define R200_EMIT_VTX_FMT_0 31 /* vtx/5 */ +#define R200_EMIT_VAP_CTL 32 /* vap/1 */ +#define R200_EMIT_MATRIX_SELECT_0 33 /* msl/5 */ +#define R200_EMIT_TEX_PROC_CTL_2 34 /* tcg/5 */ +#define R200_EMIT_TCL_UCP_VERT_BLEND_CTL 35 /* tcl/1 */ +#define R200_EMIT_PP_TXFILTER_0 36 /* tex0/6 */ +#define R200_EMIT_PP_TXFILTER_1 37 /* tex1/6 */ +#define R200_EMIT_PP_TXFILTER_2 38 /* tex2/6 */ +#define R200_EMIT_PP_TXFILTER_3 39 /* tex3/6 */ +#define R200_EMIT_PP_TXFILTER_4 40 /* tex4/6 */ +#define R200_EMIT_PP_TXFILTER_5 41 /* tex5/6 */ +#define R200_EMIT_PP_TXOFFSET_0 42 /* tex0/1 */ +#define R200_EMIT_PP_TXOFFSET_1 43 /* tex1/1 */ +#define R200_EMIT_PP_TXOFFSET_2 44 /* tex2/1 */ +#define R200_EMIT_PP_TXOFFSET_3 45 /* tex3/1 */ +#define R200_EMIT_PP_TXOFFSET_4 46 /* tex4/1 */ +#define R200_EMIT_PP_TXOFFSET_5 47 /* tex5/1 */ +#define R200_EMIT_VTE_CNTL 48 /* vte/1 */ +#define R200_EMIT_OUTPUT_VTX_COMP_SEL 49 /* vtx/1 */ +#define R200_EMIT_PP_TAM_DEBUG3 50 /* tam/1 */ +#define R200_EMIT_PP_CNTL_X 51 /* cst/1 */ +#define R200_EMIT_RB3D_DEPTHXY_OFFSET 52 /* cst/1 */ +#define R200_EMIT_RE_AUX_SCISSOR_CNTL 53 /* cst/1 */ +#define R200_EMIT_RE_SCISSOR_TL_0 54 /* cst/2 */ +#define R200_EMIT_RE_SCISSOR_TL_1 55 /* cst/2 */ +#define R200_EMIT_RE_SCISSOR_TL_2 56 /* cst/2 */ +#define R200_EMIT_SE_VAP_CNTL_STATUS 57 /* cst/1 */ +#define R200_EMIT_SE_VTX_STATE_CNTL 58 /* cst/1 */ +#define R200_EMIT_RE_POINTSIZE 59 /* cst/1 */ +#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0 60 /* cst/4 */ +#define R200_EMIT_PP_CUBIC_FACES_0 61 +#define R200_EMIT_PP_CUBIC_OFFSETS_0 62 +#define R200_EMIT_PP_CUBIC_FACES_1 63 +#define R200_EMIT_PP_CUBIC_OFFSETS_1 64 +#define R200_EMIT_PP_CUBIC_FACES_2 65 +#define R200_EMIT_PP_CUBIC_OFFSETS_2 66 +#define R200_EMIT_PP_CUBIC_FACES_3 67 +#define R200_EMIT_PP_CUBIC_OFFSETS_3 68 +#define R200_EMIT_PP_CUBIC_FACES_4 69 +#define R200_EMIT_PP_CUBIC_OFFSETS_4 70 +#define R200_EMIT_PP_CUBIC_FACES_5 71 +#define R200_EMIT_PP_CUBIC_OFFSETS_5 72 +#define RADEON_MAX_STATE_PACKETS 73 + + +/* Commands understood by cmd_buffer ioctl. More can be added but + * obviously these can't be removed or changed: + */ +#define RADEON_CMD_PACKET 1 /* emit one of the register packets above */ +#define RADEON_CMD_SCALARS 2 /* emit scalar data */ +#define RADEON_CMD_VECTORS 3 /* emit vector data */ +#define RADEON_CMD_DMA_DISCARD 4 /* discard current dma buf */ +#define RADEON_CMD_PACKET3 5 /* emit hw packet */ +#define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */ +#define RADEON_CMD_SCALARS2 7 /* r200 stopgap */ +#define RADEON_CMD_WAIT 8 /* emit hw wait commands -- note: + * doesn't make the cpu wait, just + * the graphics hardware */ + + +typedef union { + int i; + struct { + unsigned char cmd_type, pad0, pad1, pad2; + } header; + struct { + unsigned char cmd_type, packet_id, pad0, pad1; + } packet; + struct { + unsigned char cmd_type, offset, stride, count; + } scalars; + struct { + unsigned char cmd_type, offset, stride, count; + } vectors; + struct { + unsigned char cmd_type, buf_idx, pad0, pad1; + } dma; + struct { + unsigned char cmd_type, flags, pad0, pad1; + } wait; +} drm_radeon_cmd_header_t; + +#define RADEON_WAIT_2D 0x1 +#define RADEON_WAIT_3D 0x2 + #define RADEON_FRONT 0x1 #define RADEON_BACK 0x2 #define RADEON_DEPTH 0x4 +#define RADEON_STENCIL 0x8 /* Primitive types */ @@ -78,12 +206,9 @@ /* Byte offsets for indirect buffer data */ #define RADEON_INDEX_PRIM_OFFSET 20 -#define RADEON_HOSTDATA_BLIT_OFFSET 32 #define RADEON_SCRATCH_REG_OFFSET 32 -/* Keep these small for testing - */ #define RADEON_NR_SAREA_CLIPRECTS 12 /* There are 2 heaps (local/AGP). Each region within a heap is a @@ -95,7 +220,7 @@ #define RADEON_NR_TEX_REGIONS 64 #define RADEON_LOG_TEX_GRANULARITY 16 -#define RADEON_MAX_TEXTURE_LEVELS 11 +#define RADEON_MAX_TEXTURE_LEVELS 12 #define RADEON_MAX_TEXTURE_UNITS 3 #endif /* __RADEON_SAREA_DEFINES__ */ @@ -155,28 +280,18 @@ /* Setup state */ unsigned int se_cntl_status; /* 0x2140 */ -#ifdef TCL_ENABLE - /* TCL state */ - radeon_color_regs_t se_tcl_material_emmissive; /* 0x2210 */ - radeon_color_regs_t se_tcl_material_ambient; - radeon_color_regs_t se_tcl_material_diffuse; - radeon_color_regs_t se_tcl_material_specular; - unsigned int se_tcl_shininess; - unsigned int se_tcl_output_vtx_fmt; - unsigned int se_tcl_output_vtx_sel; - unsigned int se_tcl_matrix_select_0; - unsigned int se_tcl_matrix_select_1; - unsigned int se_tcl_ucp_vert_blend_ctl; - unsigned int se_tcl_texture_proc_ctl; - unsigned int se_tcl_light_model_ctl; - unsigned int se_tcl_per_light_ctl[4]; -#endif - /* Misc state */ unsigned int re_top_left; /* 0x26c0 */ unsigned int re_misc; } drm_radeon_context_regs_t; +typedef struct { + /* Zbias state */ + unsigned int se_zbias_factor; /* 0x1dac */ + unsigned int se_zbias_constant; +} drm_radeon_context2_regs_t; + + /* Setup registers for each texture unit */ typedef struct { @@ -186,24 +301,37 @@ unsigned int pp_txcblend; unsigned int pp_txablend; unsigned int pp_tfactor; - unsigned int pp_border_color; - -#ifdef CUBIC_ENABLE - unsigned int pp_cubic_faces; - unsigned int pp_cubic_offset[5]; -#endif } drm_radeon_texture_regs_t; typedef struct { + unsigned int start; + unsigned int finish; + unsigned int prim:8; + unsigned int stateidx:8; + unsigned int numverts:16; /* overloaded as offset/64 for elt prims */ + unsigned int vc_format; /* vertex format */ +} drm_radeon_prim_t; + + +typedef struct { + drm_radeon_context_regs_t context; + drm_radeon_texture_regs_t tex[RADEON_MAX_TEXTURE_UNITS]; + drm_radeon_context2_regs_t context2; + unsigned int dirty; +} drm_radeon_state_t; + + +typedef struct { unsigned char next, prev; unsigned char in_use; int age; } drm_radeon_tex_region_t; typedef struct { - /* The channel for communication of state information to the kernel - * on firing a vertex buffer. + /* The channel for communication of state information to the + * kernel on firing a vertex buffer with either of the + * obsoleted vertex/index ioctls. */ drm_radeon_context_regs_t context_state; drm_radeon_texture_regs_t tex_state[RADEON_MAX_TEXTURE_UNITS]; @@ -225,16 +353,50 @@ drm_radeon_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1]; int tex_age[RADEON_NR_TEX_HEAPS]; int ctx_owner; + int pfState; /* number of 3d windows (0,1,2ormore) */ + int pfCurrentPage; /* which buffer is being displayed? */ + int crtc2_base; /* CRTC2 frame offset */ } drm_radeon_sarea_t; /* WARNING: If you change any of these defines, make sure to change the * defines in the Xserver file (xf86drmRadeon.h) + * + * KW: actually it's illegal to change any of this (backwards compatibility). */ + +/* Radeon specific ioctls + * The device specific ioctl range is 0x40 to 0x79. + */ +#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t) +#define DRM_IOCTL_RADEON_CP_START DRM_IO( 0x41) +#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( 0x42, drm_radeon_cp_stop_t) +#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43) +#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44) +#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45) +#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t) +#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47) +#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t) +#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t) +#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t) +#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t) +#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t) +#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t) +#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( 0x4f, drm_radeon_vertex2_t) +#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( 0x50, drm_radeon_cmd_buffer_t) +#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(0x51, drm_radeon_getparam_t) +#define DRM_IOCTL_RADEON_FLIP DRM_IO( 0x52) +#define DRM_IOCTL_RADEON_ALLOC DRM_IOWR( 0x53, drm_radeon_mem_alloc_t) +#define DRM_IOCTL_RADEON_FREE DRM_IOW( 0x54, drm_radeon_mem_free_t) +#define DRM_IOCTL_RADEON_INIT_HEAP DRM_IOW( 0x55, drm_radeon_mem_init_heap_t) +#define DRM_IOCTL_RADEON_IRQ_EMIT DRM_IOWR( 0x56, drm_radeon_irq_emit_t) +#define DRM_IOCTL_RADEON_IRQ_WAIT DRM_IOW( 0x57, drm_radeon_irq_wait_t) + typedef struct drm_radeon_init { enum { RADEON_INIT_CP = 0x01, - RADEON_CLEANUP_CP = 0x02 + RADEON_CLEANUP_CP = 0x02, + RADEON_INIT_R200_CP = 0x03, } func; unsigned long sarea_priv_offset; int is_pci; @@ -285,7 +447,7 @@ unsigned int clear_color; unsigned int clear_depth; unsigned int color_mask; - unsigned int depth_mask; + unsigned int depth_mask; /* misnamed field: should be stencil */ drm_radeon_clear_rect_t *depth_boxes; } drm_radeon_clear_t; @@ -304,6 +466,36 @@ int discard; /* Client finished with buffer? */ } drm_radeon_indices_t; +/* v1.2 - obsoletes drm_radeon_vertex and drm_radeon_indices + * - allows multiple primitives and state changes in a single ioctl + * - supports driver change to emit native primitives + */ +typedef struct drm_radeon_vertex2 { + int idx; /* Index of vertex buffer */ + int discard; /* Client finished with buffer? */ + int nr_states; + drm_radeon_state_t *state; + int nr_prims; + drm_radeon_prim_t *prim; +} drm_radeon_vertex2_t; + +/* v1.3 - obsoletes drm_radeon_vertex2 + * - allows arbitarily large cliprect list + * - allows updating of tcl packet, vector and scalar state + * - allows memory-efficient description of state updates + * - allows state to be emitted without a primitive + * (for clears, ctx switches) + * - allows more than one dma buffer to be referenced per ioctl + * - supports tcl driver + * - may be extended in future versions with new cmd types, packets + */ +typedef struct drm_radeon_cmd_buffer { + int bufsz; + char *buf; + int nbox; + drm_clip_rect_t *boxes; +} drm_radeon_cmd_buffer_t; + typedef struct drm_radeon_tex_image { unsigned int x, y; /* Blit coordinates */ unsigned int width, height; @@ -330,4 +522,55 @@ int discard; } drm_radeon_indirect_t; + +/* 1.3: An ioctl to get parameters that aren't available to the 3d + * client any other way. + */ +#define RADEON_PARAM_AGP_BUFFER_OFFSET 1 /* card offset of 1st agp buffer */ +#define RADEON_PARAM_LAST_FRAME 2 +#define RADEON_PARAM_LAST_DISPATCH 3 +#define RADEON_PARAM_LAST_CLEAR 4 +#define RADEON_PARAM_IRQ_NR 5 +#define RADEON_PARAM_AGP_BASE 6 /* card offset of agp base */ + +typedef struct drm_radeon_getparam { + int param; + int *value; +} drm_radeon_getparam_t; + +/* 1.6: Set up a memory manager for regions of shared memory: + */ +#define RADEON_MEM_REGION_AGP 1 +#define RADEON_MEM_REGION_FB 2 + +typedef struct drm_radeon_mem_alloc { + int region; + int alignment; + int size; + int *region_offset; /* offset from start of fb or agp */ +} drm_radeon_mem_alloc_t; + +typedef struct drm_radeon_mem_free { + int region; + int region_offset; +} drm_radeon_mem_free_t; + +typedef struct drm_radeon_mem_init_heap { + int region; + int size; + int start; +} drm_radeon_mem_init_heap_t; + + +/* 1.6: Userspace can request & wait on irq's: + */ +typedef struct drm_radeon_irq_emit { + int *irq_seq; +} drm_radeon_irq_emit_t; + +typedef struct drm_radeon_irq_wait { + int irq_seq; +} drm_radeon_irq_wait_t; + + #endif Index: drivers/char/drm/radeon_drv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/radeon_drv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/radeon_drv.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/radeon_drv.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -30,47 +30,11 @@ #include #include "radeon.h" #include "drmP.h" +#include "drm.h" +#include "radeon_drm.h" #include "radeon_drv.h" #include "ati_pcigart.h" -#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." - -#define DRIVER_NAME "radeon" -#define DRIVER_DESC "ATI Radeon" -#define DRIVER_DATE "20010405" - -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 1 -#define DRIVER_PATCHLEVEL 1 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_INIT)] = { radeon_cp_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)] = { radeon_cp_start, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)] = { radeon_cp_stop, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)] = { radeon_cp_reset, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)] = { radeon_engine_reset, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_TEXTURE)] = { radeon_cp_texture, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 }, - - -#if 0 -/* GH: Count data sent to card via ring or vertex/indirect buffers. - */ -#define __HAVE_COUNTERS 3 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY -#endif - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -78,26 +42,6 @@ #include "drm_dma.h" #include "drm_drawable.h" #include "drm_drv.h" - -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init radeon_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", radeon_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" Index: drivers/char/drm/radeon_drv.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/radeon_drv.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/radeon_drv.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/radeon_drv.h 4 Aug 2004 01:28:49 -0000 1.2 @@ -31,6 +31,9 @@ #ifndef __RADEON_DRV_H__ #define __RADEON_DRV_H__ +#define GET_RING_HEAD(ring) readl( (volatile u32 *) (ring)->head ) +#define SET_RING_HEAD(ring,val) writel( (val), (volatile u32 *) (ring)->head ) + typedef struct drm_radeon_freelist { unsigned int age; drm_buf_t *buf; @@ -58,6 +61,15 @@ u32 se_cntl; } drm_radeon_depth_clear_t; + +struct mem_block { + struct mem_block *next; + struct mem_block *prev; + int start; + int size; + int pid; /* 0: free, -1: heap, other: real pids */ +}; + typedef struct drm_radeon_private { drm_radeon_ring_buffer_t ring; drm_radeon_sarea_t *sarea_priv; @@ -71,27 +83,32 @@ drm_radeon_freelist_t *head; drm_radeon_freelist_t *tail; -/* FIXME: ROTATE_BUFS is a hask to cycle through bufs until freelist - code is used. Note this hides a problem with the scratch register - (used to keep track of last buffer completed) being written to before - the last buffer has actually completed rendering. */ -#define ROTATE_BUFS 1 -#if ROTATE_BUFS int last_buf; -#endif volatile u32 *scratch; + int writeback_works; int usec_timeout; + + int is_r200; + int is_pci; unsigned long phys_pci_gart; dma_addr_t bus_pci_gart; - atomic_t idle_count; + struct { + u32 boxes; + int freelist_timeouts; + int freelist_loops; + int requested_bufs; + int last_frame_reads; + int last_clear_reads; + int clears; + int texture_uploads; + } stats; + int do_boxes; int page_flipping; int current_page; - u32 crtc_offset; - u32 crtc_offset_cntl; u32 color_fmt; unsigned int front_offset; @@ -116,14 +133,18 @@ drm_map_t *ring_rptr; drm_map_t *buffers; drm_map_t *agp_textures; + + struct mem_block *agp_heap; + struct mem_block *fb_heap; + + /* SW interrupt */ + wait_queue_head_t swi_queue; + atomic_t swi_emitted; + } drm_radeon_private_t; typedef struct drm_radeon_buf_priv { u32 age; - int prim; - int discard; - int dispatched; - drm_radeon_freelist_t *list_entry; } drm_radeon_buf_priv_t; /* radeon_cp.c */ @@ -149,14 +170,6 @@ extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ); -static inline void -radeon_update_ring_snapshot( drm_radeon_ring_buffer_t *ring ) -{ - ring->space = (*(volatile int *)ring->head - ring->tail) * sizeof(u32); - if ( ring->space <= 0 ) - ring->space += ring->size; -} - extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv ); extern int radeon_do_cleanup_cp( drm_device_t *dev ); extern int radeon_do_cleanup_pageflip( drm_device_t *dev ); @@ -176,6 +189,34 @@ unsigned int cmd, unsigned long arg ); extern int radeon_cp_indirect( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); +extern int radeon_cp_vertex2(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg ); +extern int radeon_cp_cmdbuf(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg ); +extern int radeon_cp_getparam(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg ); +extern int radeon_cp_flip(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg ); + +extern int radeon_mem_alloc(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg ); +extern int radeon_mem_free(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg ); +extern int radeon_mem_init_heap(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg ); +extern void radeon_mem_takedown( struct mem_block **heap ); +extern void radeon_mem_release( struct mem_block *heap ); + + /* radeon_irq.c */ +extern int radeon_irq_emit(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg ); +extern int radeon_irq_wait(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg ); + +extern int radeon_emit_and_wait_irq(drm_device_t *dev); +extern int radeon_wait_irq(drm_device_t *dev, int swi_nr); +extern int radeon_emit_irq(drm_device_t *dev); + + +/* Flags for stats.boxes + */ +#define RADEON_BOX_DMA_IDLE 0x1 +#define RADEON_BOX_RING_FULL 0x2 +#define RADEON_BOX_FLIP 0x4 +#define RADEON_BOX_WAIT_IDLE 0x8 +#define RADEON_BOX_TEXTURE_LOAD 0x10 + /* Register definitions, register access macros and drmAddMap constants @@ -202,10 +243,10 @@ #define RADEON_CRTC_OFFSET_CNTL 0x0228 # define RADEON_CRTC_TILE_EN (1 << 15) # define RADEON_CRTC_OFFSET_FLIP_CNTL (1 << 16) +#define RADEON_CRTC2_OFFSET 0x0324 +#define RADEON_CRTC2_OFFSET_CNTL 0x0328 #define RADEON_RB3D_COLORPITCH 0x1c48 -#define RADEON_RB3D_DEPTHCLEARVALUE 0x1c30 -#define RADEON_RB3D_DEPTHXY_OFFSET 0x1c60 #define RADEON_DP_GUI_MASTER_CNTL 0x146c # define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) @@ -240,6 +281,24 @@ #define RADEON_SCRATCH_UMSK 0x0770 #define RADEON_SCRATCH_ADDR 0x0774 +#define GET_SCRATCH( x ) (dev_priv->writeback_works \ + ? readl( &dev_priv->scratch[(x)] ) \ + : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) ) + + +#define RADEON_GEN_INT_CNTL 0x0040 +# define RADEON_CRTC_VBLANK_MASK (1 << 0) +# define RADEON_GUI_IDLE_INT_ENABLE (1 << 19) +# define RADEON_SW_INT_ENABLE (1 << 25) + +#define RADEON_GEN_INT_STATUS 0x0044 +# define RADEON_CRTC_VBLANK_STAT (1 << 0) +# define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) +# define RADEON_GUI_IDLE_INT_TEST_ACK (1 << 19) +# define RADEON_SW_INT_TEST (1 << 25) +# define RADEON_SW_INT_TEST_ACK (1 << 25) +# define RADEON_SW_INT_FIRE (1 << 26) + #define RADEON_HOST_PATH_CNTL 0x0130 # define RADEON_HDP_SOFT_RESET (1 << 26) # define RADEON_HDP_WC_TIMEOUT_MASK (7 << 28) @@ -253,6 +312,12 @@ # define RADEON_ISYNC_WAIT_IDLEGUI (1 << 4) # define RADEON_ISYNC_CPSCRATCH_IDLEGUI (1 << 5) +#define RADEON_RBBM_GUICNTL 0x172c +# define RADEON_HOST_DATA_SWAP_NONE (0 << 0) +# define RADEON_HOST_DATA_SWAP_16BIT (1 << 0) +# define RADEON_HOST_DATA_SWAP_32BIT (2 << 0) +# define RADEON_HOST_DATA_SWAP_HDW (3 << 0) + #define RADEON_MC_AGP_LOCATION 0x014c #define RADEON_MC_FB_LOCATION 0x0148 #define RADEON_MCLK_CNTL 0x0012 @@ -290,10 +355,8 @@ # define RADEON_ROP_ENABLE (1 << 6) # define RADEON_STENCIL_ENABLE (1 << 7) # define RADEON_Z_ENABLE (1 << 8) -# define RADEON_DEPTH_XZ_OFFEST_ENABLE (1 << 9) -# define RADEON_ZBLOCK8 (0 << 15) -# define RADEON_ZBLOCK16 (1 << 15) #define RADEON_RB3D_DEPTHOFFSET 0x1c24 +#define RADEON_RB3D_DEPTHPITCH 0x1c28 #define RADEON_RB3D_PLANEMASK 0x1d84 #define RADEON_RB3D_STENCILREFMASK 0x1d7c #define RADEON_RB3D_ZCACHE_MODE 0x3250 @@ -306,9 +369,9 @@ # define RADEON_Z_TEST_MASK (7 << 4) # define RADEON_Z_TEST_ALWAYS (7 << 4) # define RADEON_STENCIL_TEST_ALWAYS (7 << 12) -# define RADEON_STENCIL_S_FAIL_KEEP (0 << 16) -# define RADEON_STENCIL_ZPASS_KEEP (0 << 20) -# define RADEON_STENCIL_ZFAIL_KEEP (0 << 20) +# define RADEON_STENCIL_S_FAIL_REPLACE (2 << 16) +# define RADEON_STENCIL_ZPASS_REPLACE (2 << 20) +# define RADEON_STENCIL_ZFAIL_REPLACE (2 << 24) # define RADEON_Z_WRITE_ENABLE (1 << 30) #define RADEON_RBBM_SOFT_RESET 0x00f0 # define RADEON_SOFT_RESET_CP (1 << 0) @@ -357,6 +420,16 @@ #define RADEON_SE_CNTL_STATUS 0x2140 #define RADEON_SE_LINE_WIDTH 0x1db8 #define RADEON_SE_VPORT_XSCALE 0x1d98 +#define RADEON_SE_ZBIAS_FACTOR 0x1db0 +#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED 0x2210 +#define RADEON_SE_TCL_OUTPUT_VTX_FMT 0x2254 +#define RADEON_SE_TCL_VECTOR_INDX_REG 0x2200 +# define RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT 16 +# define RADEON_VEC_INDX_DWORD_COUNT_SHIFT 28 +#define RADEON_SE_TCL_VECTOR_DATA_REG 0x2204 +#define RADEON_SE_TCL_SCALAR_INDX_REG 0x2208 +# define RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT 16 +#define RADEON_SE_TCL_SCALAR_DATA_REG 0x220C #define RADEON_SURFACE_ACCESS_FLAGS 0x0bf8 #define RADEON_SURFACE_ACCESS_CLR 0x0bfc #define RADEON_SURFACE_CNTL 0x0b00 @@ -421,6 +494,7 @@ #define RADEON_CP_RB_BASE 0x0700 #define RADEON_CP_RB_CNTL 0x0704 +# define RADEON_BUF_SWAP_32BIT (2 << 16) #define RADEON_CP_RB_RPTR_ADDR 0x070c #define RADEON_CP_RB_RPTR 0x0710 #define RADEON_CP_RB_WPTR 0x0714 @@ -457,11 +531,14 @@ #define RADEON_CP_PACKET3 0xC0000000 # define RADEON_3D_RNDR_GEN_INDX_PRIM 0x00002300 # define RADEON_WAIT_FOR_IDLE 0x00002600 +# define RADEON_3D_DRAW_VBUF 0x00002800 # define RADEON_3D_DRAW_IMMD 0x00002900 -# define RADEON_3D_CLEAR_ZMASK 0x00003200 +# define RADEON_3D_DRAW_INDX 0x00002A00 +# define RADEON_3D_LOAD_VBPNTR 0x00002F00 # define RADEON_CNTL_HOSTDATA_BLT 0x00009400 # define RADEON_CNTL_PAINT_MULTI 0x00009A00 # define RADEON_CNTL_BITBLT_MULTI 0x00009B00 +# define RADEON_CNTL_SET_SCISSORS 0xC0001E00 #define RADEON_CP_PACKET_MASK 0xC0000000 #define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 @@ -470,6 +547,7 @@ #define RADEON_CP_PACKET1_REG1_MASK 0x003ff800 #define RADEON_VTX_Z_PRESENT (1 << 31) +#define RADEON_VTX_PKCOLOR_PRESENT (1 << 3) #define RADEON_PRIM_TYPE_NONE (0 << 0) #define RADEON_PRIM_TYPE_POINT (1 << 0) @@ -482,6 +560,7 @@ #define RADEON_PRIM_TYPE_RECT_LIST (8 << 0) #define RADEON_PRIM_TYPE_3VRT_POINT_LIST (9 << 0) #define RADEON_PRIM_TYPE_3VRT_LINE_LIST (10 << 0) +#define RADEON_PRIM_TYPE_MASK 0xf #define RADEON_PRIM_WALK_IND (1 << 4) #define RADEON_PRIM_WALK_LIST (2 << 4) #define RADEON_PRIM_WALK_RING (3 << 4) @@ -508,6 +587,105 @@ #define RADEON_TXFORMAT_ARGB4444 5 #define RADEON_TXFORMAT_ARGB8888 6 #define RADEON_TXFORMAT_RGBA8888 7 +#define RADEON_TXFORMAT_VYUY422 10 +#define RADEON_TXFORMAT_YVYU422 11 +#define RADEON_TXFORMAT_DXT1 12 +#define RADEON_TXFORMAT_DXT23 14 +#define RADEON_TXFORMAT_DXT45 15 + +#define R200_PP_TXCBLEND_0 0x2f00 +#define R200_PP_TXCBLEND_1 0x2f10 +#define R200_PP_TXCBLEND_2 0x2f20 +#define R200_PP_TXCBLEND_3 0x2f30 +#define R200_PP_TXCBLEND_4 0x2f40 +#define R200_PP_TXCBLEND_5 0x2f50 +#define R200_PP_TXCBLEND_6 0x2f60 +#define R200_PP_TXCBLEND_7 0x2f70 +#define R200_SE_TCL_LIGHT_MODEL_CTL_0 0x2268 +#define R200_PP_TFACTOR_0 0x2ee0 +#define R200_SE_VTX_FMT_0 0x2088 +#define R200_SE_VAP_CNTL 0x2080 +#define R200_SE_TCL_MATRIX_SEL_0 0x2230 +#define R200_SE_TCL_TEX_PROC_CTL_2 0x22a8 +#define R200_SE_TCL_UCP_VERT_BLEND_CTL 0x22c0 +#define R200_PP_TXFILTER_5 0x2ca0 +#define R200_PP_TXFILTER_4 0x2c80 +#define R200_PP_TXFILTER_3 0x2c60 +#define R200_PP_TXFILTER_2 0x2c40 +#define R200_PP_TXFILTER_1 0x2c20 +#define R200_PP_TXFILTER_0 0x2c00 +#define R200_PP_TXOFFSET_5 0x2d78 +#define R200_PP_TXOFFSET_4 0x2d60 +#define R200_PP_TXOFFSET_3 0x2d48 +#define R200_PP_TXOFFSET_2 0x2d30 +#define R200_PP_TXOFFSET_1 0x2d18 +#define R200_PP_TXOFFSET_0 0x2d00 + +#define R200_PP_CUBIC_FACES_0 0x2c18 +#define R200_PP_CUBIC_FACES_1 0x2c38 +#define R200_PP_CUBIC_FACES_2 0x2c58 +#define R200_PP_CUBIC_FACES_3 0x2c78 +#define R200_PP_CUBIC_FACES_4 0x2c98 +#define R200_PP_CUBIC_FACES_5 0x2cb8 +#define R200_PP_CUBIC_OFFSET_F1_0 0x2d04 +#define R200_PP_CUBIC_OFFSET_F2_0 0x2d08 +#define R200_PP_CUBIC_OFFSET_F3_0 0x2d0c +#define R200_PP_CUBIC_OFFSET_F4_0 0x2d10 +#define R200_PP_CUBIC_OFFSET_F5_0 0x2d14 +#define R200_PP_CUBIC_OFFSET_F1_1 0x2d1c +#define R200_PP_CUBIC_OFFSET_F2_1 0x2d20 +#define R200_PP_CUBIC_OFFSET_F3_1 0x2d24 +#define R200_PP_CUBIC_OFFSET_F4_1 0x2d28 +#define R200_PP_CUBIC_OFFSET_F5_1 0x2d2c +#define R200_PP_CUBIC_OFFSET_F1_2 0x2d34 +#define R200_PP_CUBIC_OFFSET_F2_2 0x2d38 +#define R200_PP_CUBIC_OFFSET_F3_2 0x2d3c +#define R200_PP_CUBIC_OFFSET_F4_2 0x2d40 +#define R200_PP_CUBIC_OFFSET_F5_2 0x2d44 +#define R200_PP_CUBIC_OFFSET_F1_3 0x2d4c +#define R200_PP_CUBIC_OFFSET_F2_3 0x2d50 +#define R200_PP_CUBIC_OFFSET_F3_3 0x2d54 +#define R200_PP_CUBIC_OFFSET_F4_3 0x2d58 +#define R200_PP_CUBIC_OFFSET_F5_3 0x2d5c +#define R200_PP_CUBIC_OFFSET_F1_4 0x2d64 +#define R200_PP_CUBIC_OFFSET_F2_4 0x2d68 +#define R200_PP_CUBIC_OFFSET_F3_4 0x2d6c +#define R200_PP_CUBIC_OFFSET_F4_4 0x2d70 +#define R200_PP_CUBIC_OFFSET_F5_4 0x2d74 +#define R200_PP_CUBIC_OFFSET_F1_5 0x2d7c +#define R200_PP_CUBIC_OFFSET_F2_5 0x2d80 +#define R200_PP_CUBIC_OFFSET_F3_5 0x2d84 +#define R200_PP_CUBIC_OFFSET_F4_5 0x2d88 +#define R200_PP_CUBIC_OFFSET_F5_5 0x2d8c + +#define R200_RE_AUX_SCISSOR_CNTL 0x26f0 +#define R200_SE_VTE_CNTL 0x20b0 +#define R200_SE_TCL_OUTPUT_VTX_COMP_SEL 0x2250 +#define R200_PP_TAM_DEBUG3 0x2d9c +#define R200_PP_CNTL_X 0x2cc4 +#define R200_SE_VAP_CNTL_STATUS 0x2140 +#define R200_RE_SCISSOR_TL_0 0x1cd8 +#define R200_RE_SCISSOR_TL_1 0x1ce0 +#define R200_RE_SCISSOR_TL_2 0x1ce8 +#define R200_RB3D_DEPTHXY_OFFSET 0x1d60 +#define R200_RE_AUX_SCISSOR_CNTL 0x26f0 +#define R200_SE_VTX_STATE_CNTL 0x2180 +#define R200_RE_POINTSIZE 0x2648 +#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0 0x2254 + + +#define SE_VAP_CNTL__TCL_ENA_MASK 0x00000001 +#define SE_VAP_CNTL__FORCE_W_TO_ONE_MASK 0x00010000 +#define SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT 0x00000012 +#define SE_VTE_CNTL__VTX_XY_FMT_MASK 0x00000100 +#define SE_VTE_CNTL__VTX_Z_FMT_MASK 0x00000200 +#define SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK 0x00000001 +#define SE_VTX_FMT_0__VTX_W0_PRESENT_MASK 0x00000002 +#define SE_VTX_FMT_0__VTX_COLOR_0_FMT__SHIFT 0x0000000b +#define R200_3D_DRAW_IMMD_2 0xC0003500 +#define R200_SE_VTX_FMT_1 0x208c +#define R200_RE_CNTL 0x1c50 + /* Constants */ #define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ @@ -515,6 +693,7 @@ #define RADEON_LAST_FRAME_REG RADEON_SCRATCH_REG0 #define RADEON_LAST_DISPATCH_REG RADEON_SCRATCH_REG1 #define RADEON_LAST_CLEAR_REG RADEON_SCRATCH_REG2 +#define RADEON_LAST_SWI_REG RADEON_SCRATCH_REG3 #define RADEON_LAST_DISPATCH 1 #define RADEON_MAX_VB_AGE 0x7fffffff @@ -526,41 +705,11 @@ #define RADEON_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) #define RADEON_ADDR(reg) (RADEON_BASE( reg ) + reg) -#define RADEON_DEREF(reg) *(volatile u32 *)RADEON_ADDR( reg ) -#ifdef __alpha__ -#define RADEON_READ(reg) (_RADEON_READ((u32 *)RADEON_ADDR( reg ))) -static inline u32 _RADEON_READ(u32 *addr) -{ - mb(); - return *(volatile u32 *)addr; -} -#define RADEON_WRITE(reg,val) \ -do { \ - wmb(); \ - RADEON_DEREF(reg) = val; \ -} while (0) -#else -#define RADEON_READ(reg) RADEON_DEREF( reg ) -#define RADEON_WRITE(reg, val) do { RADEON_DEREF( reg ) = val; } while (0) -#endif - -#define RADEON_DEREF8(reg) *(volatile u8 *)RADEON_ADDR( reg ) -#ifdef __alpha__ -#define RADEON_READ8(reg) _RADEON_READ8((u8 *)RADEON_ADDR( reg )) -static inline u8 _RADEON_READ8(u8 *addr) -{ - mb(); - return *(volatile u8 *)addr; -} -#define RADEON_WRITE8(reg,val) \ -do { \ - wmb(); \ - RADEON_DEREF8( reg ) = val; \ -} while (0) -#else -#define RADEON_READ8(reg) RADEON_DEREF8( reg ) -#define RADEON_WRITE8(reg, val) do { RADEON_DEREF8( reg ) = val; } while (0) -#endif +#define RADEON_READ(reg) readl( (volatile u32 *) RADEON_ADDR(reg) ) +#define RADEON_WRITE(reg,val) writel( (val), (volatile u32 *) RADEON_ADDR(reg)) + +#define RADEON_READ8(reg) readb( (volatile u8 *) RADEON_ADDR(reg) ) +#define RADEON_WRITE8(reg,val) writeb( (val), (volatile u8 *) RADEON_ADDR(reg)) #define RADEON_WRITE_PLL( addr, val ) \ do { \ @@ -647,20 +796,16 @@ } \ } while (0) + +/* Perfbox functionality only. + */ #define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ do { \ - drm_radeon_ring_buffer_t *ring = &dev_priv->ring; int i; \ - if ( ring->space < ring->high_mark ) { \ - for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { \ - radeon_update_ring_snapshot( ring ); \ - if ( ring->space >= ring->high_mark ) \ - goto __ring_space_done; \ - udelay( 1 ); \ - } \ - DRM_ERROR( "ring space check failed!\n" ); \ - return -EBUSY; \ + if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE)) { \ + u32 head = GET_RING_HEAD(&dev_priv->ring); \ + if (head == dev_priv->ring.tail) \ + dev_priv->stats.boxes |= RADEON_BOX_DMA_IDLE; \ } \ - __ring_space_done: ; \ } while (0) #define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ @@ -668,7 +813,7 @@ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; \ if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \ int __ret = radeon_do_cp_idle( dev_priv ); \ - if ( __ret < 0 ) return __ret; \ + if ( __ret ) return __ret; \ sarea_priv->last_dispatch = 0; \ radeon_freelist_reset( dev ); \ } \ @@ -694,12 +839,9 @@ * Ring control */ -#define radeon_flush_write_combine() mb() - - #define RADEON_VERBOSE 0 -#define RING_LOCALS int write; unsigned int mask; volatile u32 *ring; +#define RING_LOCALS int write, _nr; unsigned int mask; u32 *ring; #define BEGIN_RING( n ) do { \ if ( RADEON_VERBOSE ) { \ @@ -707,9 +849,10 @@ n, __FUNCTION__ ); \ } \ if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ + COMMIT_RING(); \ radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \ } \ - dev_priv->ring.space -= (n) * sizeof(u32); \ + _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \ ring = dev_priv->ring.start; \ write = dev_priv->ring.tail; \ mask = dev_priv->ring.tail_mask; \ @@ -720,9 +863,22 @@ DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \ write, dev_priv->ring.tail ); \ } \ - radeon_flush_write_combine(); \ - dev_priv->ring.tail = write; \ - RADEON_WRITE( RADEON_CP_RB_WPTR, write ); \ + if (((dev_priv->ring.tail + _nr) & mask) != write) { \ + DRM_ERROR( \ + "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \ + ((dev_priv->ring.tail + _nr) & mask), \ + write, __LINE__); \ + } else \ + dev_priv->ring.tail = write; \ +} while (0) + +#define COMMIT_RING() do { \ + /* Flush writes to ring */ \ + rmb(); \ + GET_RING_HEAD( &dev_priv->ring ); \ + RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \ + /* read from PCI bus to ensure correct posting */ \ + RADEON_READ( RADEON_CP_RB_RPTR ); \ } while (0) #define OUT_RING( x ) do { \ @@ -734,6 +890,33 @@ write &= mask; \ } while (0) -#define RADEON_PERFORMANCE_BOXES 0 +#define OUT_RING_REG( reg, val ) do { \ + OUT_RING( CP_PACKET0( reg, 0 ) ); \ + OUT_RING( val ); \ +} while (0) + + +#define OUT_RING_USER_TABLE( tab, sz ) do { \ + int _size = (sz); \ + int *_tab = (tab); \ + \ + if (write + _size > mask) { \ + int i = (mask+1) - write; \ + if (__copy_from_user( (int *)(ring+write), \ + _tab, i*4 )) \ + return -EFAULT; \ + write = 0; \ + _size -= i; \ + _tab += i; \ + } \ + \ + if (_size && __copy_from_user( (int *)(ring+write), \ + _tab, _size*4 )) \ + return -EFAULT; \ + \ + write += _size; \ + write &= mask; \ +} while (0) + #endif /* __RADEON_DRV_H__ */ Index: drivers/char/drm/radeon_state.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/radeon_state.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/radeon_state.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/radeon_state.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -29,10 +29,11 @@ #include "radeon.h" #include "drmP.h" -#include "radeon_drv.h" #include "drm.h" -#include - +#include "drm_sarea.h" +#include "radeon_drm.h" +#include "radeon_drv.h" +#include "drm_os_linux.h" /* ================================================================ * CP hardware state programming functions @@ -47,360 +48,254 @@ box->x1, box->y1, box->x2, box->y2 ); BEGIN_RING( 4 ); - OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT, 0 ) ); OUT_RING( (box->y1 << 16) | box->x1 ); - OUT_RING( CP_PACKET0( RADEON_RE_WIDTH_HEIGHT, 0 ) ); OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_context( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 14 ); - - OUT_RING( CP_PACKET0( RADEON_PP_MISC, 6 ) ); - OUT_RING( ctx->pp_misc ); - OUT_RING( ctx->pp_fog_color ); - OUT_RING( ctx->re_solid_color ); - OUT_RING( ctx->rb3d_blendcntl ); - OUT_RING( ctx->rb3d_depthoffset ); - OUT_RING( ctx->rb3d_depthpitch ); - OUT_RING( ctx->rb3d_zstencilcntl ); - - OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 2 ) ); - OUT_RING( ctx->pp_cntl ); - OUT_RING( ctx->rb3d_cntl ); - OUT_RING( ctx->rb3d_coloroffset ); - - OUT_RING( CP_PACKET0( RADEON_RB3D_COLORPITCH, 0 ) ); - OUT_RING( ctx->rb3d_colorpitch ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_vertfmt( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 2 ); - - OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT, 0 ) ); - OUT_RING( ctx->se_coord_fmt ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_line( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 5 ); - - OUT_RING( CP_PACKET0( RADEON_RE_LINE_PATTERN, 1 ) ); - OUT_RING( ctx->re_line_pattern ); - OUT_RING( ctx->re_line_state ); - - OUT_RING( CP_PACKET0( RADEON_SE_LINE_WIDTH, 0 ) ); - OUT_RING( ctx->se_line_width ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_bumpmap( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 5 ); - - OUT_RING( CP_PACKET0( RADEON_PP_LUM_MATRIX, 0 ) ); - OUT_RING( ctx->pp_lum_matrix ); - - OUT_RING( CP_PACKET0( RADEON_PP_ROT_MATRIX_0, 1 ) ); - OUT_RING( ctx->pp_rot_matrix_0 ); - OUT_RING( ctx->pp_rot_matrix_1 ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_masks( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 4 ); - - OUT_RING( CP_PACKET0( RADEON_RB3D_STENCILREFMASK, 2 ) ); - OUT_RING( ctx->rb3d_stencilrefmask ); - OUT_RING( ctx->rb3d_ropcntl ); - OUT_RING( ctx->rb3d_planemask ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_viewport( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 7 ); - - OUT_RING( CP_PACKET0( RADEON_SE_VPORT_XSCALE, 5 ) ); - OUT_RING( ctx->se_vport_xscale ); - OUT_RING( ctx->se_vport_xoffset ); - OUT_RING( ctx->se_vport_yscale ); - OUT_RING( ctx->se_vport_yoffset ); - OUT_RING( ctx->se_vport_zscale ); - OUT_RING( ctx->se_vport_zoffset ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_setup( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 4 ); - - OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) ); - OUT_RING( ctx->se_cntl ); - OUT_RING( CP_PACKET0( RADEON_SE_CNTL_STATUS, 0 ) ); - OUT_RING( ctx->se_cntl_status ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_tcl( drm_radeon_private_t *dev_priv ) -{ -#ifdef TCL_ENABLE - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 29 ); - - OUT_RING( CP_PACKET0( RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 27 ) ); - OUT_RING( ctx->se_tcl_material_emmissive.red ); - OUT_RING( ctx->se_tcl_material_emmissive.green ); - OUT_RING( ctx->se_tcl_material_emmissive.blue ); - OUT_RING( ctx->se_tcl_material_emmissive.alpha ); - OUT_RING( ctx->se_tcl_material_ambient.red ); - OUT_RING( ctx->se_tcl_material_ambient.green ); - OUT_RING( ctx->se_tcl_material_ambient.blue ); - OUT_RING( ctx->se_tcl_material_ambient.alpha ); - OUT_RING( ctx->se_tcl_material_diffuse.red ); - OUT_RING( ctx->se_tcl_material_diffuse.green ); - OUT_RING( ctx->se_tcl_material_diffuse.blue ); - OUT_RING( ctx->se_tcl_material_diffuse.alpha ); - OUT_RING( ctx->se_tcl_material_specular.red ); - OUT_RING( ctx->se_tcl_material_specular.green ); - OUT_RING( ctx->se_tcl_material_specular.blue ); - OUT_RING( ctx->se_tcl_material_specular.alpha ); - OUT_RING( ctx->se_tcl_shininess ); - OUT_RING( ctx->se_tcl_output_vtx_fmt ); - OUT_RING( ctx->se_tcl_output_vtx_sel ); - OUT_RING( ctx->se_tcl_matrix_select_0 ); - OUT_RING( ctx->se_tcl_matrix_select_1 ); - OUT_RING( ctx->se_tcl_ucp_vert_blend_ctl ); - OUT_RING( ctx->se_tcl_texture_proc_ctl ); - OUT_RING( ctx->se_tcl_light_model_ctl ); - for ( i = 0 ; i < 4 ; i++ ) { - OUT_RING( ctx->se_tcl_per_light_ctl[i] ); - } - ADVANCE_RING(); -#else - DRM_ERROR( "TCL not enabled!\n" ); -#endif } -static inline void radeon_emit_misc( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 2 ); - - OUT_RING( CP_PACKET0( RADEON_RE_MISC, 0 ) ); - OUT_RING( ctx->re_misc ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_tex0( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[0]; - RING_LOCALS; - DRM_DEBUG( " %s: offset=0x%x\n", __FUNCTION__, tex->pp_txoffset ); - - BEGIN_RING( 9 ); - - OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_0, 5 ) ); - OUT_RING( tex->pp_txfilter ); - OUT_RING( tex->pp_txformat ); - OUT_RING( tex->pp_txoffset ); - OUT_RING( tex->pp_txcblend ); - OUT_RING( tex->pp_txablend ); - OUT_RING( tex->pp_tfactor ); - - OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_0, 0 ) ); - OUT_RING( tex->pp_border_color ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_tex1( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[1]; - RING_LOCALS; - DRM_DEBUG( " %s: offset=0x%x\n", __FUNCTION__, tex->pp_txoffset ); - - BEGIN_RING( 9 ); - - OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_1, 5 ) ); - OUT_RING( tex->pp_txfilter ); - OUT_RING( tex->pp_txformat ); - OUT_RING( tex->pp_txoffset ); - OUT_RING( tex->pp_txcblend ); - OUT_RING( tex->pp_txablend ); - OUT_RING( tex->pp_tfactor ); - - OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_1, 0 ) ); - OUT_RING( tex->pp_border_color ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_tex2( drm_radeon_private_t *dev_priv ) +/* Emit 1.1 state + */ +static void radeon_emit_state( drm_radeon_private_t *dev_priv, + drm_radeon_context_regs_t *ctx, + drm_radeon_texture_regs_t *tex, + unsigned int dirty ) { - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[2]; RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); - - BEGIN_RING( 9 ); - - OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_2, 5 ) ); - OUT_RING( tex->pp_txfilter ); - OUT_RING( tex->pp_txformat ); - OUT_RING( tex->pp_txoffset ); - OUT_RING( tex->pp_txcblend ); - OUT_RING( tex->pp_txablend ); - OUT_RING( tex->pp_tfactor ); - - OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_2, 0 ) ); - OUT_RING( tex->pp_border_color ); - - ADVANCE_RING(); -} - -static inline void radeon_emit_state( drm_radeon_private_t *dev_priv ) -{ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int dirty = sarea_priv->dirty; - - DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty ); + DRM_DEBUG( "dirty=0x%08x\n", dirty ); if ( dirty & RADEON_UPLOAD_CONTEXT ) { - radeon_emit_context( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_CONTEXT; + BEGIN_RING( 14 ); + OUT_RING( CP_PACKET0( RADEON_PP_MISC, 6 ) ); + OUT_RING( ctx->pp_misc ); + OUT_RING( ctx->pp_fog_color ); + OUT_RING( ctx->re_solid_color ); + OUT_RING( ctx->rb3d_blendcntl ); + OUT_RING( ctx->rb3d_depthoffset ); + OUT_RING( ctx->rb3d_depthpitch ); + OUT_RING( ctx->rb3d_zstencilcntl ); + OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 2 ) ); + OUT_RING( ctx->pp_cntl ); + OUT_RING( ctx->rb3d_cntl ); + OUT_RING( ctx->rb3d_coloroffset ); + OUT_RING( CP_PACKET0( RADEON_RB3D_COLORPITCH, 0 ) ); + OUT_RING( ctx->rb3d_colorpitch ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_VERTFMT ) { - radeon_emit_vertfmt( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_VERTFMT; + BEGIN_RING( 2 ); + OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT, 0 ) ); + OUT_RING( ctx->se_coord_fmt ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_LINE ) { - radeon_emit_line( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_LINE; + BEGIN_RING( 5 ); + OUT_RING( CP_PACKET0( RADEON_RE_LINE_PATTERN, 1 ) ); + OUT_RING( ctx->re_line_pattern ); + OUT_RING( ctx->re_line_state ); + OUT_RING( CP_PACKET0( RADEON_SE_LINE_WIDTH, 0 ) ); + OUT_RING( ctx->se_line_width ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_BUMPMAP ) { - radeon_emit_bumpmap( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_BUMPMAP; + BEGIN_RING( 5 ); + OUT_RING( CP_PACKET0( RADEON_PP_LUM_MATRIX, 0 ) ); + OUT_RING( ctx->pp_lum_matrix ); + OUT_RING( CP_PACKET0( RADEON_PP_ROT_MATRIX_0, 1 ) ); + OUT_RING( ctx->pp_rot_matrix_0 ); + OUT_RING( ctx->pp_rot_matrix_1 ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_MASKS ) { - radeon_emit_masks( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_MASKS; + BEGIN_RING( 4 ); + OUT_RING( CP_PACKET0( RADEON_RB3D_STENCILREFMASK, 2 ) ); + OUT_RING( ctx->rb3d_stencilrefmask ); + OUT_RING( ctx->rb3d_ropcntl ); + OUT_RING( ctx->rb3d_planemask ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_VIEWPORT ) { - radeon_emit_viewport( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_VIEWPORT; + BEGIN_RING( 7 ); + OUT_RING( CP_PACKET0( RADEON_SE_VPORT_XSCALE, 5 ) ); + OUT_RING( ctx->se_vport_xscale ); + OUT_RING( ctx->se_vport_xoffset ); + OUT_RING( ctx->se_vport_yscale ); + OUT_RING( ctx->se_vport_yoffset ); + OUT_RING( ctx->se_vport_zscale ); + OUT_RING( ctx->se_vport_zoffset ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_SETUP ) { - radeon_emit_setup( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_SETUP; - } - - if ( dirty & RADEON_UPLOAD_TCL ) { -#ifdef TCL_ENABLE - radeon_emit_tcl( dev_priv ); -#endif - sarea_priv->dirty &= ~RADEON_UPLOAD_TCL; + BEGIN_RING( 4 ); + OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) ); + OUT_RING( ctx->se_cntl ); + OUT_RING( CP_PACKET0( RADEON_SE_CNTL_STATUS, 0 ) ); + OUT_RING( ctx->se_cntl_status ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_MISC ) { - radeon_emit_misc( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_MISC; + BEGIN_RING( 2 ); + OUT_RING( CP_PACKET0( RADEON_RE_MISC, 0 ) ); + OUT_RING( ctx->re_misc ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_TEX0 ) { - radeon_emit_tex0( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_TEX0; + BEGIN_RING( 9 ); + OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_0, 5 ) ); + OUT_RING( tex[0].pp_txfilter ); + OUT_RING( tex[0].pp_txformat ); + OUT_RING( tex[0].pp_txoffset ); + OUT_RING( tex[0].pp_txcblend ); + OUT_RING( tex[0].pp_txablend ); + OUT_RING( tex[0].pp_tfactor ); + OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_0, 0 ) ); + OUT_RING( tex[0].pp_border_color ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_TEX1 ) { - radeon_emit_tex1( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_TEX1; + BEGIN_RING( 9 ); + OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_1, 5 ) ); + OUT_RING( tex[1].pp_txfilter ); + OUT_RING( tex[1].pp_txformat ); + OUT_RING( tex[1].pp_txoffset ); + OUT_RING( tex[1].pp_txcblend ); + OUT_RING( tex[1].pp_txablend ); + OUT_RING( tex[1].pp_tfactor ); + OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_1, 0 ) ); + OUT_RING( tex[1].pp_border_color ); + ADVANCE_RING(); } if ( dirty & RADEON_UPLOAD_TEX2 ) { -#if 0 - radeon_emit_tex2( dev_priv ); -#endif - sarea_priv->dirty &= ~RADEON_UPLOAD_TEX2; + BEGIN_RING( 9 ); + OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_2, 5 ) ); + OUT_RING( tex[2].pp_txfilter ); + OUT_RING( tex[2].pp_txformat ); + OUT_RING( tex[2].pp_txoffset ); + OUT_RING( tex[2].pp_txcblend ); + OUT_RING( tex[2].pp_txablend ); + OUT_RING( tex[2].pp_tfactor ); + OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_2, 0 ) ); + OUT_RING( tex[2].pp_border_color ); + ADVANCE_RING(); } +} - sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | - RADEON_UPLOAD_TEX1IMAGES | - RADEON_UPLOAD_TEX2IMAGES | - RADEON_REQUIRE_QUIESCENCE); +/* Emit 1.2 state + */ +static void radeon_emit_state2( drm_radeon_private_t *dev_priv, + drm_radeon_state_t *state ) +{ + RING_LOCALS; + + if (state->dirty & RADEON_UPLOAD_ZBIAS) { + BEGIN_RING( 3 ); + OUT_RING( CP_PACKET0( RADEON_SE_ZBIAS_FACTOR, 1 ) ); + OUT_RING( state->context2.se_zbias_factor ); + OUT_RING( state->context2.se_zbias_constant ); + ADVANCE_RING(); + } + + radeon_emit_state( dev_priv, &state->context, + state->tex, state->dirty ); } +/* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in + * 1.3 cmdbuffers allow all previous state to be updated as well as + * the tcl scalar and vector areas. + */ +static struct { + int start; + int len; + const char *name; +} packet[RADEON_MAX_STATE_PACKETS] = { + { RADEON_PP_MISC,7,"RADEON_PP_MISC" }, + { RADEON_PP_CNTL,3,"RADEON_PP_CNTL" }, + { RADEON_RB3D_COLORPITCH,1,"RADEON_RB3D_COLORPITCH" }, + { RADEON_RE_LINE_PATTERN,2,"RADEON_RE_LINE_PATTERN" }, + { RADEON_SE_LINE_WIDTH,1,"RADEON_SE_LINE_WIDTH" }, + { RADEON_PP_LUM_MATRIX,1,"RADEON_PP_LUM_MATRIX" }, + { RADEON_PP_ROT_MATRIX_0,2,"RADEON_PP_ROT_MATRIX_0" }, + { RADEON_RB3D_STENCILREFMASK,3,"RADEON_RB3D_STENCILREFMASK" }, + { RADEON_SE_VPORT_XSCALE,6,"RADEON_SE_VPORT_XSCALE" }, + { RADEON_SE_CNTL,2,"RADEON_SE_CNTL" }, + { RADEON_SE_CNTL_STATUS,1,"RADEON_SE_CNTL_STATUS" }, + { RADEON_RE_MISC,1,"RADEON_RE_MISC" }, + { RADEON_PP_TXFILTER_0,6,"RADEON_PP_TXFILTER_0" }, + { RADEON_PP_BORDER_COLOR_0,1,"RADEON_PP_BORDER_COLOR_0" }, + { RADEON_PP_TXFILTER_1,6,"RADEON_PP_TXFILTER_1" }, + { RADEON_PP_BORDER_COLOR_1,1,"RADEON_PP_BORDER_COLOR_1" }, + { RADEON_PP_TXFILTER_2,6,"RADEON_PP_TXFILTER_2" }, + { RADEON_PP_BORDER_COLOR_2,1,"RADEON_PP_BORDER_COLOR_2" }, + { RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" }, + { RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" }, + { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" }, + { R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0" }, + { R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1" }, + { R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2" }, + { R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3" }, + { R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4" }, + { R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5" }, + { R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6" }, + { R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7" }, + { R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0" }, + { R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0" }, + { R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0" }, + { R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL" }, + { R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0" }, + { R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2" }, + { R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL" }, + { R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0" }, + { R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1" }, + { R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2" }, + { R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3" }, + { R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4" }, + { R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5" }, + { R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0" }, + { R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1" }, + { R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2" }, + { R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3" }, + { R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4" }, + { R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5" }, + { R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL" }, + { R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL" }, + { R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3" }, + { R200_PP_CNTL_X, 1, "R200_PP_CNTL_X" }, + { R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET" }, + { R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL" }, + { R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0" }, + { R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1" }, + { R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2" }, + { R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS" }, + { R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL" }, + { R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE" }, + { R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0" }, + { R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0" }, /* 61 */ + { R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0" }, /* 62 */ + { R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1" }, + { R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1" }, + { R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2" }, + { R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2" }, + { R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3" }, + { R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3" }, + { R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4" }, + { R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4" }, + { R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5" }, + { R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5" }, +}; + + -#if RADEON_PERFORMANCE_BOXES /* ================================================================ * Performance monitoring functions */ @@ -409,10 +304,12 @@ int x, int y, int w, int h, int r, int g, int b ) { - u32 pitch, offset; u32 color; RING_LOCALS; + x += dev_priv->sarea_priv->boxes[0].x1; + y += dev_priv->sarea_priv->boxes[0].y1; + switch ( dev_priv->color_fmt ) { case RADEON_COLOR_FORMAT_RGB565: color = (((r & 0xf8) << 8) | @@ -425,8 +322,11 @@ break; } - offset = dev_priv->back_offset; - pitch = dev_priv->back_pitch >> 3; + BEGIN_RING( 4 ); + RADEON_WAIT_UNTIL_3D_IDLE(); + OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) ); + OUT_RING( 0xffffffff ); + ADVANCE_RING(); BEGIN_RING( 6 ); @@ -438,7 +338,12 @@ RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS ); - OUT_RING( (pitch << 22) | (offset >> 5) ); + if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { + OUT_RING( dev_priv->front_pitch_offset ); + } else { + OUT_RING( dev_priv->back_pitch_offset ); + } + OUT_RING( color ); OUT_RING( (x << 16) | y ); @@ -449,53 +354,77 @@ static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv ) { - if ( atomic_read( &dev_priv->idle_count ) == 0 ) { - radeon_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 ); - } else { - atomic_set( &dev_priv->idle_count, 0 ); + /* Collapse various things into a wait flag -- trying to + * guess if userspase slept -- better just to have them tell us. + */ + if (dev_priv->stats.last_frame_reads > 1 || + dev_priv->stats.last_clear_reads > dev_priv->stats.clears) { + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; } -} -#endif + if (dev_priv->stats.freelist_loops) { + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; + } + + /* Purple box for page flipping + */ + if ( dev_priv->stats.boxes & RADEON_BOX_FLIP ) + radeon_clear_box( dev_priv, 4, 4, 8, 8, 255, 0, 255 ); + /* Red box if we have to wait for idle at any point + */ + if ( dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE ) + radeon_clear_box( dev_priv, 16, 4, 8, 8, 255, 0, 0 ); + /* Blue box: lost context? + */ + + /* Yellow box for texture swaps + */ + if ( dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD ) + radeon_clear_box( dev_priv, 40, 4, 8, 8, 255, 255, 0 ); + + /* Green box if hardware never idles (as far as we can tell) + */ + if ( !(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE) ) + radeon_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 ); + + + /* Draw bars indicating number of buffers allocated + * (not a great measure, easily confused) + */ + if (dev_priv->stats.requested_bufs) { + if (dev_priv->stats.requested_bufs > 100) + dev_priv->stats.requested_bufs = 100; + + radeon_clear_box( dev_priv, 4, 16, + dev_priv->stats.requested_bufs, 4, + 196, 128, 128 ); + } + + memset( &dev_priv->stats, 0, sizeof(dev_priv->stats) ); + +} /* ================================================================ * CP command dispatch functions */ -static void radeon_print_dirty( const char *msg, unsigned int flags ) -{ - DRM_DEBUG( "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", - msg, - flags, - (flags & RADEON_UPLOAD_CONTEXT) ? "context, " : "", - (flags & RADEON_UPLOAD_VERTFMT) ? "vertfmt, " : "", - (flags & RADEON_UPLOAD_LINE) ? "line, " : "", - (flags & RADEON_UPLOAD_BUMPMAP) ? "bumpmap, " : "", - (flags & RADEON_UPLOAD_MASKS) ? "masks, " : "", - (flags & RADEON_UPLOAD_VIEWPORT) ? "viewport, " : "", - (flags & RADEON_UPLOAD_SETUP) ? "setup, " : "", - (flags & RADEON_UPLOAD_TCL) ? "tcl, " : "", - (flags & RADEON_UPLOAD_MISC) ? "misc, " : "", - (flags & RADEON_UPLOAD_TEX0) ? "tex0, " : "", - (flags & RADEON_UPLOAD_TEX1) ? "tex1, " : "", - (flags & RADEON_UPLOAD_TEX2) ? "tex2, " : "", - (flags & RADEON_UPLOAD_CLIPRECTS) ? "cliprects, " : "", - (flags & RADEON_REQUIRE_QUIESCENCE) ? "quiescence, " : "" ); -} - static void radeon_cp_dispatch_clear( drm_device_t *dev, drm_radeon_clear_t *clear, drm_radeon_clear_rect_t *depth_boxes ) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear; int nbox = sarea_priv->nbox; drm_clip_rect_t *pbox = sarea_priv->boxes; unsigned int flags = clear->flags; + u32 rb3d_cntl = 0, rb3d_stencilrefmask= 0; int i; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "flags = 0x%x\n", flags ); + + dev_priv->stats.clears++; if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { unsigned int tmp = flags; @@ -505,127 +434,277 @@ if ( tmp & RADEON_BACK ) flags |= RADEON_FRONT; } - for ( i = 0 ; i < nbox ; i++ ) { - int x = pbox[i].x1; - int y = pbox[i].y1; - int w = pbox[i].x2 - x; - int h = pbox[i].y2 - y; + if ( flags & (RADEON_FRONT | RADEON_BACK) ) { - DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n", - x, y, w, h, flags ); + BEGIN_RING( 4 ); - if ( flags & (RADEON_FRONT | RADEON_BACK) ) { - BEGIN_RING( 4 ); + /* Ensure the 3D stream is idle before doing a + * 2D fill to clear the front or back buffer. + */ + RADEON_WAIT_UNTIL_3D_IDLE(); + + OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) ); + OUT_RING( clear->color_mask ); - /* Ensure the 3D stream is idle before doing a - * 2D fill to clear the front or back buffer. - */ - RADEON_WAIT_UNTIL_3D_IDLE(); + ADVANCE_RING(); - OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) ); - OUT_RING( clear->color_mask ); + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->ctx_owner = 0; - ADVANCE_RING(); + for ( i = 0 ; i < nbox ; i++ ) { + int x = pbox[i].x1; + int y = pbox[i].y1; + int w = pbox[i].x2 - x; + int h = pbox[i].y2 - y; + + DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n", + x, y, w, h, flags ); + + if ( flags & RADEON_FRONT ) { + BEGIN_RING( 6 ); + + OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_SOLID_COLOR | + (dev_priv->color_fmt << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_P | + RADEON_GMC_CLR_CMP_CNTL_DIS ); + + OUT_RING( dev_priv->front_pitch_offset ); + OUT_RING( clear->clear_color ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (w << 16) | h ); + + ADVANCE_RING(); + } + + if ( flags & RADEON_BACK ) { + BEGIN_RING( 6 ); + + OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_SOLID_COLOR | + (dev_priv->color_fmt << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_P | + RADEON_GMC_CLR_CMP_CNTL_DIS ); + + OUT_RING( dev_priv->back_pitch_offset ); + OUT_RING( clear->clear_color ); - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT | - RADEON_UPLOAD_MASKS); + OUT_RING( (x << 16) | y ); + OUT_RING( (w << 16) | h ); + + ADVANCE_RING(); + } } + } - if ( flags & RADEON_FRONT ) { - BEGIN_RING( 6 ); + /* We have to clear the depth and/or stencil buffers by + * rendering a quad into just those buffers. Thus, we have to + * make sure the 3D engine is configured correctly. + */ + if ( dev_priv->is_r200 && + (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) { - OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_SOLID_COLOR | - (dev_priv->color_fmt << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_P | - RADEON_GMC_CLR_CMP_CNTL_DIS ); + int tempPP_CNTL; + int tempRE_CNTL; + int tempRB3D_CNTL; + int tempRB3D_ZSTENCILCNTL; + int tempRB3D_STENCILREFMASK; + int tempRB3D_PLANEMASK; + int tempSE_CNTL; + int tempSE_VTE_CNTL; + int tempSE_VTX_FMT_0; + int tempSE_VTX_FMT_1; + int tempSE_VAP_CNTL; + int tempRE_AUX_SCISSOR_CNTL; - OUT_RING( dev_priv->front_pitch_offset ); - OUT_RING( clear->clear_color ); + tempPP_CNTL = 0; + tempRE_CNTL = 0; - OUT_RING( (x << 16) | y ); - OUT_RING( (w << 16) | h ); + tempRB3D_CNTL = depth_clear->rb3d_cntl; + tempRB3D_CNTL &= ~(1<<15); /* unset radeon magic flag */ - ADVANCE_RING(); + tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl; + tempRB3D_STENCILREFMASK = 0x0; + + tempSE_CNTL = depth_clear->se_cntl; + + + + /* Disable TCL */ + + tempSE_VAP_CNTL = (/* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK | */ + (0x9 << SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT)); + + tempRB3D_PLANEMASK = 0x0; + + tempRE_AUX_SCISSOR_CNTL = 0x0; + + tempSE_VTE_CNTL = + SE_VTE_CNTL__VTX_XY_FMT_MASK | + SE_VTE_CNTL__VTX_Z_FMT_MASK; + + /* Vertex format (X, Y, Z, W)*/ + tempSE_VTX_FMT_0 = + SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK | + SE_VTX_FMT_0__VTX_W0_PRESENT_MASK; + tempSE_VTX_FMT_1 = 0x0; + + + /* + * Depth buffer specific enables + */ + if (flags & RADEON_DEPTH) { + /* Enable depth buffer */ + tempRB3D_CNTL |= RADEON_Z_ENABLE; + } else { + /* Disable depth buffer */ + tempRB3D_CNTL &= ~RADEON_Z_ENABLE; } - if ( flags & RADEON_BACK ) { - BEGIN_RING( 6 ); + /* + * Stencil buffer specific enables + */ + if ( flags & RADEON_STENCIL ) { + tempRB3D_CNTL |= RADEON_STENCIL_ENABLE; + tempRB3D_STENCILREFMASK = clear->depth_mask; + } else { + tempRB3D_CNTL &= ~RADEON_STENCIL_ENABLE; + tempRB3D_STENCILREFMASK = 0x00000000; + } - OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_SOLID_COLOR | - (dev_priv->color_fmt << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_P | - RADEON_GMC_CLR_CMP_CNTL_DIS ); + BEGIN_RING( 26 ); + RADEON_WAIT_UNTIL_2D_IDLE(); - OUT_RING( dev_priv->back_pitch_offset ); - OUT_RING( clear->clear_color ); + OUT_RING_REG( RADEON_PP_CNTL, tempPP_CNTL ); + OUT_RING_REG( R200_RE_CNTL, tempRE_CNTL ); + OUT_RING_REG( RADEON_RB3D_CNTL, tempRB3D_CNTL ); + OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL, + tempRB3D_ZSTENCILCNTL ); + OUT_RING_REG( RADEON_RB3D_STENCILREFMASK, + tempRB3D_STENCILREFMASK ); + OUT_RING_REG( RADEON_RB3D_PLANEMASK, tempRB3D_PLANEMASK ); + OUT_RING_REG( RADEON_SE_CNTL, tempSE_CNTL ); + OUT_RING_REG( R200_SE_VTE_CNTL, tempSE_VTE_CNTL ); + OUT_RING_REG( R200_SE_VTX_FMT_0, tempSE_VTX_FMT_0 ); + OUT_RING_REG( R200_SE_VTX_FMT_1, tempSE_VTX_FMT_1 ); + OUT_RING_REG( R200_SE_VAP_CNTL, tempSE_VAP_CNTL ); + OUT_RING_REG( R200_RE_AUX_SCISSOR_CNTL, + tempRE_AUX_SCISSOR_CNTL ); + ADVANCE_RING(); - OUT_RING( (x << 16) | y ); - OUT_RING( (w << 16) | h ); + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->ctx_owner = 0; - ADVANCE_RING(); + for ( i = 0 ; i < nbox ; i++ ) { + + /* Funny that this should be required -- + * sets top-left? + */ + radeon_emit_clip_rect( dev_priv, + &sarea_priv->boxes[i] ); + BEGIN_RING( 14 ); + OUT_RING( CP_PACKET3( R200_3D_DRAW_IMMD_2, 12 ) ); + OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST | + RADEON_PRIM_WALK_RING | + (3 << RADEON_NUM_VERTICES_SHIFT)) ); + OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); + OUT_RING( depth_boxes[i].ui[CLEAR_Y1] ); + OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); + OUT_RING( 0x3f800000 ); + OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); + OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); + OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); + OUT_RING( 0x3f800000 ); + OUT_RING( depth_boxes[i].ui[CLEAR_X2] ); + OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); + OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); + OUT_RING( 0x3f800000 ); + ADVANCE_RING(); } + } + else if ( (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) { + + rb3d_cntl = depth_clear->rb3d_cntl; if ( flags & RADEON_DEPTH ) { - drm_radeon_depth_clear_t *depth_clear = - &dev_priv->depth_clear; + rb3d_cntl |= RADEON_Z_ENABLE; + } else { + rb3d_cntl &= ~RADEON_Z_ENABLE; + } - if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { - radeon_emit_state( dev_priv ); - } + if ( flags & RADEON_STENCIL ) { + rb3d_cntl |= RADEON_STENCIL_ENABLE; + rb3d_stencilrefmask = clear->depth_mask; /* misnamed field */ + } else { + rb3d_cntl &= ~RADEON_STENCIL_ENABLE; + rb3d_stencilrefmask = 0x00000000; + } - /* FIXME: Render a rectangle to clear the depth - * buffer. So much for those "fast Z clears"... - */ - BEGIN_RING( 23 ); + BEGIN_RING( 13 ); + RADEON_WAIT_UNTIL_2D_IDLE(); + + OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 1 ) ); + OUT_RING( 0x00000000 ); + OUT_RING( rb3d_cntl ); + + OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL, + depth_clear->rb3d_zstencilcntl ); + OUT_RING_REG( RADEON_RB3D_STENCILREFMASK, + rb3d_stencilrefmask ); + OUT_RING_REG( RADEON_RB3D_PLANEMASK, + 0x00000000 ); + OUT_RING_REG( RADEON_SE_CNTL, + depth_clear->se_cntl ); + ADVANCE_RING(); + + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->ctx_owner = 0; - RADEON_WAIT_UNTIL_2D_IDLE(); + for ( i = 0 ; i < nbox ; i++ ) { + + /* Funny that this should be required -- + * sets top-left? + */ + radeon_emit_clip_rect( dev_priv, + &sarea_priv->boxes[i] ); - OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 1 ) ); - OUT_RING( 0x00000000 ); - OUT_RING( depth_clear->rb3d_cntl ); - OUT_RING( CP_PACKET0( RADEON_RB3D_ZSTENCILCNTL, 0 ) ); - OUT_RING( depth_clear->rb3d_zstencilcntl ); - OUT_RING( CP_PACKET0( RADEON_RB3D_PLANEMASK, 0 ) ); - OUT_RING( 0x00000000 ); - OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) ); - OUT_RING( depth_clear->se_cntl ); + BEGIN_RING( 15 ); - OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 10 ) ); - OUT_RING( RADEON_VTX_Z_PRESENT ); + OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 13 ) ); + OUT_RING( RADEON_VTX_Z_PRESENT | + RADEON_VTX_PKCOLOR_PRESENT); OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST | RADEON_PRIM_WALK_RING | RADEON_MAOS_ENABLE | RADEON_VTX_FMT_RADEON_MODE | (3 << RADEON_NUM_VERTICES_SHIFT)) ); + OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); OUT_RING( depth_boxes[i].ui[CLEAR_Y1] ); OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); + OUT_RING( 0x0 ); OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); + OUT_RING( 0x0 ); OUT_RING( depth_boxes[i].ui[CLEAR_X2] ); OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); + OUT_RING( 0x0 ); ADVANCE_RING(); - - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT | - RADEON_UPLOAD_SETUP | - RADEON_UPLOAD_MASKS); } } @@ -651,13 +730,13 @@ drm_clip_rect_t *pbox = sarea_priv->boxes; int i; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); -#if RADEON_PERFORMANCE_BOXES /* Do some trivial performance monitoring... */ - radeon_cp_performance_boxes( dev_priv ); -#endif + if (dev_priv->do_boxes) + radeon_cp_performance_boxes( dev_priv ); + /* Wait for the 3D stream to idle before dispatching the bitblt. * This will prevent data corruption between the two streams. @@ -689,9 +768,17 @@ RADEON_DP_SRC_SOURCE_MEMORY | RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS ); - - OUT_RING( dev_priv->back_pitch_offset ); - OUT_RING( dev_priv->front_pitch_offset ); + + /* Make this work even if front & back are flipped: + */ + if (dev_priv->current_page == 0) { + OUT_RING( dev_priv->back_pitch_offset ); + OUT_RING( dev_priv->front_pitch_offset ); + } + else { + OUT_RING( dev_priv->front_pitch_offset ); + OUT_RING( dev_priv->back_pitch_offset ); + } OUT_RING( (x << 16) | y ); OUT_RING( (x << 16) | y ); @@ -717,29 +804,33 @@ static void radeon_cp_dispatch_flip( drm_device_t *dev ) { drm_radeon_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - DRM_DEBUG( "%s: page=%d\n", __FUNCTION__, dev_priv->current_page ); + drm_sarea_t *sarea = (drm_sarea_t *)dev_priv->sarea->handle; + int offset = (dev_priv->current_page == 1) + ? dev_priv->front_offset : dev_priv->back_offset; + RING_LOCALS; + DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n", + __FUNCTION__, + dev_priv->current_page, + dev_priv->sarea_priv->pfCurrentPage); -#if RADEON_PERFORMANCE_BOXES /* Do some trivial performance monitoring... */ - radeon_cp_performance_boxes( dev_priv ); -#endif + if (dev_priv->do_boxes) { + dev_priv->stats.boxes |= RADEON_BOX_FLIP; + radeon_cp_performance_boxes( dev_priv ); + } + /* Update the frame offsets for both CRTCs + */ BEGIN_RING( 6 ); RADEON_WAIT_UNTIL_3D_IDLE(); - RADEON_WAIT_UNTIL_PAGE_FLIPPED(); - - OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET, 0 ) ); - - if ( dev_priv->current_page == 0 ) { - OUT_RING( dev_priv->back_offset ); - dev_priv->current_page = 1; - } else { - OUT_RING( dev_priv->front_offset ); - dev_priv->current_page = 0; - } + OUT_RING_REG( RADEON_CRTC_OFFSET, ( ( sarea->frame.y * dev_priv->front_pitch + + sarea->frame.x + * ( dev_priv->color_fmt - 2 ) ) & ~7 ) + + offset ); + OUT_RING_REG( RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base + + offset ); ADVANCE_RING(); @@ -748,6 +839,8 @@ * performing the swapbuffer ioctl. */ dev_priv->sarea_priv->last_frame++; + dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page = + 1 - dev_priv->current_page; BEGIN_RING( 2 ); @@ -756,82 +849,118 @@ ADVANCE_RING(); } +static int bad_prim_vertex_nr( int primitive, int nr ) +{ + switch (primitive & RADEON_PRIM_TYPE_MASK) { + case RADEON_PRIM_TYPE_NONE: + case RADEON_PRIM_TYPE_POINT: + return nr < 1; + case RADEON_PRIM_TYPE_LINE: + return (nr & 1) || nr == 0; + case RADEON_PRIM_TYPE_LINE_STRIP: + return nr < 2; + case RADEON_PRIM_TYPE_TRI_LIST: + case RADEON_PRIM_TYPE_3VRT_POINT_LIST: + case RADEON_PRIM_TYPE_3VRT_LINE_LIST: + case RADEON_PRIM_TYPE_RECT_LIST: + return nr % 3 || nr == 0; + case RADEON_PRIM_TYPE_TRI_FAN: + case RADEON_PRIM_TYPE_TRI_STRIP: + return nr < 3; + default: + return 1; + } +} + + + +typedef struct { + unsigned int start; + unsigned int finish; + unsigned int prim; + unsigned int numverts; + unsigned int offset; + unsigned int vc_format; +} drm_radeon_tcl_prim_t; + static void radeon_cp_dispatch_vertex( drm_device_t *dev, - drm_buf_t *buf ) + drm_buf_t *buf, + drm_radeon_tcl_prim_t *prim, + drm_clip_rect_t *boxes, + int nbox ) + { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_buf_priv_t *buf_priv = buf->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - int format = sarea_priv->vc_format; - int offset = dev_priv->agp_buffers_offset + buf->offset; - int size = buf->used; - int prim = buf_priv->prim; + drm_clip_rect_t box; + int offset = dev_priv->agp_buffers_offset + buf->offset + prim->start; + int numverts = (int)prim->numverts; int i = 0; RING_LOCALS; - DRM_DEBUG( "%s: nbox=%d\n", __FUNCTION__, sarea_priv->nbox ); - if ( 0 ) - radeon_print_dirty( "dispatch_vertex", sarea_priv->dirty ); + DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d %d verts\n", + prim->prim, + prim->vc_format, + prim->start, + prim->finish, + prim->numverts); + + if (bad_prim_vertex_nr( prim->prim, prim->numverts )) { + DRM_ERROR( "bad prim %x numverts %d\n", + prim->prim, prim->numverts ); + return; + } + + do { + /* Emit the next cliprect */ + if ( i < nbox ) { + if (__copy_from_user( &box, &boxes[i], sizeof(box) )) + return; - if ( buf->used ) { - buf_priv->dispatched = 1; - - if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { - radeon_emit_state( dev_priv ); + radeon_emit_clip_rect( dev_priv, &box ); } - do { - /* Emit the next set of up to three cliprects */ - if ( i < sarea_priv->nbox ) { - radeon_emit_clip_rect( dev_priv, - &sarea_priv->boxes[i] ); - } + /* Emit the vertex buffer rendering commands */ + BEGIN_RING( 5 ); - /* Emit the vertex buffer rendering commands */ - BEGIN_RING( 5 ); + OUT_RING( CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, 3 ) ); + OUT_RING( offset ); + OUT_RING( numverts ); + OUT_RING( prim->vc_format ); + OUT_RING( prim->prim | RADEON_PRIM_WALK_LIST | + RADEON_COLOR_ORDER_RGBA | + RADEON_VTX_FMT_RADEON_MODE | + (numverts << RADEON_NUM_VERTICES_SHIFT) ); - OUT_RING( CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, 3 ) ); - OUT_RING( offset ); - OUT_RING( size ); - OUT_RING( format ); - OUT_RING( prim | RADEON_PRIM_WALK_LIST | - RADEON_COLOR_ORDER_RGBA | - RADEON_VTX_FMT_RADEON_MODE | - (size << RADEON_NUM_VERTICES_SHIFT) ); + ADVANCE_RING(); - ADVANCE_RING(); + i++; + } while ( i < nbox ); +} - i++; - } while ( i < sarea_priv->nbox ); - } - if ( buf_priv->discard ) { - buf_priv->age = dev_priv->sarea_priv->last_dispatch; - /* Emit the vertex buffer age */ - BEGIN_RING( 2 ); - RADEON_DISPATCH_AGE( buf_priv->age ); - ADVANCE_RING(); +static void radeon_cp_discard_buffer( drm_device_t *dev, drm_buf_t *buf ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_buf_priv_t *buf_priv = buf->dev_private; + RING_LOCALS; - buf->pending = 1; - buf->used = 0; - /* FIXME: Check dispatched field */ - buf_priv->dispatched = 0; - } + buf_priv->age = ++dev_priv->sarea_priv->last_dispatch; - dev_priv->sarea_priv->last_dispatch++; + /* Emit the vertex buffer age */ + BEGIN_RING( 2 ); + RADEON_DISPATCH_AGE( buf_priv->age ); + ADVANCE_RING(); - sarea_priv->dirty &= ~RADEON_UPLOAD_CLIPRECTS; - sarea_priv->nbox = 0; + buf->pending = 1; + buf->used = 0; } - static void radeon_cp_dispatch_indirect( drm_device_t *dev, drm_buf_t *buf, int start, int end ) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_buf_priv_t *buf_priv = buf->dev_private; RING_LOCALS; DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n", buf->idx, start, end ); @@ -852,8 +981,6 @@ data[dwords++] = RADEON_CP_PACKET2; } - buf_priv->dispatched = 1; - /* Fire off the indirect buffer */ BEGIN_RING( 3 ); @@ -863,100 +990,75 @@ ADVANCE_RING(); } - - if ( buf_priv->discard ) { - buf_priv->age = dev_priv->sarea_priv->last_dispatch; - - /* Emit the indirect buffer age */ - BEGIN_RING( 2 ); - RADEON_DISPATCH_AGE( buf_priv->age ); - ADVANCE_RING(); - - buf->pending = 1; - buf->used = 0; - /* FIXME: Check dispatched field */ - buf_priv->dispatched = 0; - } - - dev_priv->sarea_priv->last_dispatch++; } + static void radeon_cp_dispatch_indices( drm_device_t *dev, - drm_buf_t *buf, - int start, int end, - int count ) + drm_buf_t *elt_buf, + drm_radeon_tcl_prim_t *prim, + drm_clip_rect_t *boxes, + int nbox ) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_buf_priv_t *buf_priv = buf->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - int format = sarea_priv->vc_format; - int offset = dev_priv->agp_buffers_offset; - int prim = buf_priv->prim; + drm_clip_rect_t box; + int offset = dev_priv->agp_buffers_offset + prim->offset; u32 *data; int dwords; int i = 0; - RING_LOCALS; - DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count ); - - if ( 0 ) - radeon_print_dirty( "dispatch_indices", sarea_priv->dirty ); - - if ( start != end ) { - buf_priv->dispatched = 1; - - if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { - radeon_emit_state( dev_priv ); - } - - dwords = (end - start + 3) / sizeof(u32); - - data = (u32 *)((char *)dev_priv->buffers->handle - + buf->offset + start); + int start = prim->start + RADEON_INDEX_PRIM_OFFSET; + int count = (prim->finish - start) / sizeof(u16); - data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 ); - - data[1] = offset; - data[2] = RADEON_MAX_VB_VERTS; - data[3] = format; - data[4] = (prim | RADEON_PRIM_WALK_IND | - RADEON_COLOR_ORDER_RGBA | - RADEON_VTX_FMT_RADEON_MODE | - (count << RADEON_NUM_VERTICES_SHIFT) ); - - if ( count & 0x1 ) { - data[dwords-1] &= 0x0000ffff; - } - - do { - /* Emit the next set of up to three cliprects */ - if ( i < sarea_priv->nbox ) { - radeon_emit_clip_rect( dev_priv, - &sarea_priv->boxes[i] ); - } - - radeon_cp_dispatch_indirect( dev, buf, start, end ); - - i++; - } while ( i < sarea_priv->nbox ); + DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n", + prim->prim, + prim->vc_format, + prim->start, + prim->finish, + prim->offset, + prim->numverts); + + if (bad_prim_vertex_nr( prim->prim, count )) { + DRM_ERROR( "bad prim %x count %d\n", + prim->prim, count ); + return; } - if ( buf_priv->discard ) { - buf_priv->age = dev_priv->sarea_priv->last_dispatch; - /* Emit the vertex buffer age */ - BEGIN_RING( 2 ); - RADEON_DISPATCH_AGE( buf_priv->age ); - ADVANCE_RING(); + if ( start >= prim->finish || + (prim->start & 0x7) ) { + DRM_ERROR( "buffer prim %d\n", prim->prim ); + return; + } + + dwords = (prim->finish - prim->start + 3) / sizeof(u32); + + data = (u32 *)((char *)dev_priv->buffers->handle + + elt_buf->offset + prim->start); + + data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 ); + data[1] = offset; + data[2] = prim->numverts; + data[3] = prim->vc_format; + data[4] = (prim->prim | + RADEON_PRIM_WALK_IND | + RADEON_COLOR_ORDER_RGBA | + RADEON_VTX_FMT_RADEON_MODE | + (count << RADEON_NUM_VERTICES_SHIFT) ); + + do { + if ( i < nbox ) { + if (__copy_from_user( &box, &boxes[i], sizeof(box) )) + return; + + radeon_emit_clip_rect( dev_priv, &box ); + } - buf->pending = 1; - /* FIXME: Check dispatched field */ - buf_priv->dispatched = 0; - } + radeon_cp_dispatch_indirect( dev, elt_buf, + prim->start, + prim->finish ); - dev_priv->sarea_priv->last_dispatch++; + i++; + } while ( i < nbox ); - sarea_priv->dirty &= ~RADEON_UPLOAD_CLIPRECTS; - sarea_priv->nbox = 0; } #define RADEON_MAX_TEXTURE_SIZE (RADEON_BUFFER_SIZE - 8 * sizeof(u32)) @@ -967,25 +1069,35 @@ { drm_radeon_private_t *dev_priv = dev->dev_private; drm_buf_t *buf; - drm_radeon_buf_priv_t *buf_priv; u32 format; u32 *buffer; - u8 *data; + const u8 *data; int size, dwords, tex_width, blit_width; - u32 y, height; - int ret = 0, i; + u32 height; + int i; RING_LOCALS; - /* FIXME: Be smarter about this... + dev_priv->stats.boxes |= RADEON_BOX_TEXTURE_LOAD; + + /* Flush the pixel cache. This ensures no pixel data gets mixed + * up with the texture data from the host data blit, otherwise + * part of the texture image may be corrupted. */ - buf = radeon_freelist_get( dev ); - if ( !buf ) return -EAGAIN; + BEGIN_RING( 4 ); + RADEON_FLUSH_CACHE(); + RADEON_WAIT_UNTIL_IDLE(); + ADVANCE_RING(); - DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n", - tex->offset >> 10, tex->pitch, tex->format, - image->x, image->y, image->width, image->height ); +#ifdef __BIG_ENDIAN + /* The Mesa texture functions provide the data in little endian as the + * chip wants it, but we need to compensate for the fact that the CP + * ring gets byte-swapped + */ + BEGIN_RING( 2 ); + OUT_RING_REG( RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT ); + ADVANCE_RING(); +#endif - buf_priv = buf->dev_private; /* The compiler won't optimize away a division by a variable, * even if the only legal values are powers of two. Thus, we'll @@ -1002,6 +1114,8 @@ case RADEON_TXFORMAT_ARGB1555: case RADEON_TXFORMAT_RGB565: case RADEON_TXFORMAT_ARGB4444: + case RADEON_TXFORMAT_VYUY422: + case RADEON_TXFORMAT_YVYU422: format = RADEON_COLOR_FORMAT_RGB565; tex_width = tex->width * 2; blit_width = image->width * 2; @@ -1017,56 +1131,46 @@ return -EINVAL; } - DRM_DEBUG( " tex=%dx%d blit=%d\n", - tex_width, tex->height, blit_width ); - - /* Flush the pixel cache. This ensures no pixel data gets mixed - * up with the texture data from the host data blit, otherwise - * part of the texture image may be corrupted. - */ - BEGIN_RING( 4 ); - - RADEON_FLUSH_CACHE(); - RADEON_WAIT_UNTIL_IDLE(); + DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width ); - ADVANCE_RING(); + do { + DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n", + tex->offset >> 10, tex->pitch, tex->format, + image->x, image->y, image->width, image->height ); - /* Make a copy of the parameters in case we have to update them - * for a multi-pass texture blit. + /* Make a copy of some parameters in case we have to + * update them for a multi-pass texture blit. */ - y = image->y; height = image->height; - data = (u8 *)image->data; + data = (const u8 *)image->data; size = height * blit_width; if ( size > RADEON_MAX_TEXTURE_SIZE ) { - /* Texture image is too large, do a multipass upload */ - ret = -EAGAIN; - - /* Adjust the blit size to fit the indirect buffer */ height = RADEON_MAX_TEXTURE_SIZE / blit_width; size = height * blit_width; - - /* Update the input parameters for next time */ - image->y += height; - image->height -= height; - image->data = (char *)image->data + size; - - if ( copy_to_user( tex->image, image, sizeof(*image) ) ) { - DRM_ERROR( "EFAULT on tex->image\n" ); - return -EFAULT; - } } else if ( size < 4 && size > 0 ) { size = 4; + } else if ( size == 0 ) { + return 0; + } + + buf = radeon_freelist_get( dev ); + if ( 0 && !buf ) { + radeon_do_cp_idle( dev_priv ); + buf = radeon_freelist_get( dev ); + } + if ( !buf ) { + DRM_DEBUG("radeon_cp_dispatch_texture: EAGAIN\n"); + copy_to_user( tex->image, image, sizeof(*image) ); + return -EAGAIN; } - dwords = size / 4; /* Dispatch the indirect buffer. */ - buffer = (u32 *)((char *)dev_priv->buffers->handle + buf->offset); - + buffer = (u32*)((char*)dev_priv->buffers->handle + buf->offset); + dwords = size / 4; buffer[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 ); buffer[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL | RADEON_GMC_BRUSH_NONE | @@ -1080,7 +1184,7 @@ buffer[2] = (tex->pitch << 22) | (tex->offset >> 10); buffer[3] = 0xffffffff; buffer[4] = 0xffffffff; - buffer[5] = (y << 16) | image->x; + buffer[5] = (image->y << 16) | image->x; buffer[6] = (height << 16) | image->width; buffer[7] = dwords; @@ -1112,30 +1216,34 @@ buf->pid = current->pid; buf->used = (dwords + 8) * sizeof(u32); - buf_priv->discard = 1; radeon_cp_dispatch_indirect( dev, buf, 0, buf->used ); + radeon_cp_discard_buffer( dev, buf ); + + /* Update the input parameters for next time */ + image->y += height; + image->height -= height; + (const u8 *)image->data += size; + } while (image->height > 0); /* Flush the pixel cache after the blit completes. This ensures * the texture data is written out to memory before rendering * continues. */ BEGIN_RING( 4 ); - RADEON_FLUSH_CACHE(); RADEON_WAIT_UNTIL_2D_IDLE(); - ADVANCE_RING(); - - return ret; + return 0; } + static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple ) { drm_radeon_private_t *dev_priv = dev->dev_private; int i; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); BEGIN_RING( 35 ); @@ -1158,31 +1266,95 @@ int radeon_cp_clear( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_clear_t clear; + drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; + DRM_DEBUG( "\n" ); + + LOCK_TEST_WITH_RETURN( dev ); + + if ( copy_from_user( &clear, (drm_radeon_clear_t *)arg, + sizeof(clear) ) ) + return -EFAULT; + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + + if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS ) + sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; + + if ( copy_from_user( &depth_boxes, clear.depth_boxes, + sarea_priv->nbox * sizeof(depth_boxes[0]) ) ) + return -EFAULT; + + radeon_cp_dispatch_clear( dev, &clear, depth_boxes ); + + COMMIT_RING(); + return 0; +} + + +/* Not sure why this isn't set all the time: + */ +static int radeon_do_init_pageflip( drm_device_t *dev ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + DRM_DEBUG( "\n" ); + + BEGIN_RING( 6 ); + RADEON_WAIT_UNTIL_3D_IDLE(); + OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET_CNTL, 0 ) ); + OUT_RING( RADEON_READ( RADEON_CRTC_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL ); + OUT_RING( CP_PACKET0( RADEON_CRTC2_OFFSET_CNTL, 0 ) ); + OUT_RING( RADEON_READ( RADEON_CRTC2_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL ); + ADVANCE_RING(); + + dev_priv->page_flipping = 1; + dev_priv->current_page = 0; + dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page; + + return 0; +} + +/* Called whenever a client dies, from DRM(release). + * NOTE: Lock isn't necessarily held when this is called! + */ +int radeon_do_cleanup_pageflip( drm_device_t *dev ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "\n" ); + + if (dev_priv->current_page != 0) + radeon_cp_dispatch_flip( dev ); + + dev_priv->page_flipping = 0; + return 0; +} + +/* Swapping and flipping are different operations, need different ioctls. + * They can & should be intermixed to support multiple 3d windows. + */ +int radeon_cp_flip(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_clear_t clear; - drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &clear, (drm_radeon_clear_t *)arg, - sizeof(clear) ) ) - return -EFAULT; - RING_SPACE_TEST_WITH_RETURN( dev_priv ); - if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS ) - sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; - - if ( copy_from_user( &depth_boxes, clear.depth_boxes, - sarea_priv->nbox * sizeof(depth_boxes[0]) ) ) - return -EFAULT; - - radeon_cp_dispatch_clear( dev, &clear, depth_boxes ); + if (!dev_priv->page_flipping) + radeon_do_init_pageflip( dev ); + + radeon_cp_dispatch_flip( dev ); + COMMIT_RING(); return 0; } @@ -1193,7 +1365,7 @@ drm_device_t *dev = priv->dev; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); @@ -1202,14 +1374,10 @@ if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; - if ( !dev_priv->page_flipping ) { - radeon_cp_dispatch_swap( dev ); - dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT | - RADEON_UPLOAD_MASKS); - } else { - radeon_cp_dispatch_flip( dev ); - } + radeon_cp_dispatch_swap( dev ); + dev_priv->sarea_priv->ctx_owner = 0; + COMMIT_RING(); return 0; } @@ -1219,10 +1387,11 @@ drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; - drm_radeon_buf_priv_t *buf_priv; drm_radeon_vertex_t vertex; + drm_radeon_tcl_prim_t prim; LOCK_TEST_WITH_RETURN( dev ); @@ -1235,8 +1404,8 @@ sizeof(vertex) ) ) return -EFAULT; - DRM_DEBUG( "%s: pid=%d index=%d count=%d discard=%d\n", - __FUNCTION__, current->pid, + DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n", + current->pid, vertex.idx, vertex.count, vertex.discard ); if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) { @@ -1254,7 +1423,6 @@ VB_AGE_TEST_WITH_RETURN( dev_priv ); buf = dma->buflist[vertex.idx]; - buf_priv = buf->dev_private; if ( buf->pid != current->pid ) { DRM_ERROR( "process %d using buffer owned by %d\n", @@ -1266,12 +1434,39 @@ return -EINVAL; } - buf->used = vertex.count; - buf_priv->prim = vertex.prim; - buf_priv->discard = vertex.discard; + /* Build up a prim_t record: + */ + if (vertex.count) { + buf->used = vertex.count; /* not used? */ + + if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { + radeon_emit_state( dev_priv, + &sarea_priv->context_state, + sarea_priv->tex_state, + sarea_priv->dirty ); + + sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | + RADEON_UPLOAD_TEX1IMAGES | + RADEON_UPLOAD_TEX2IMAGES | + RADEON_REQUIRE_QUIESCENCE); + } + + prim.start = 0; + prim.finish = vertex.count; /* unused */ + prim.prim = vertex.prim; + prim.numverts = vertex.count; + prim.vc_format = dev_priv->sarea_priv->vc_format; + + radeon_cp_dispatch_vertex( dev, buf, &prim, + dev_priv->sarea_priv->boxes, + dev_priv->sarea_priv->nbox ); + } - radeon_cp_dispatch_vertex( dev, buf ); + if (vertex.discard) { + radeon_cp_discard_buffer( dev, buf ); + } + COMMIT_RING(); return 0; } @@ -1281,10 +1476,11 @@ drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; - drm_radeon_buf_priv_t *buf_priv; drm_radeon_indices_t elts; + drm_radeon_tcl_prim_t prim; int count; LOCK_TEST_WITH_RETURN( dev ); @@ -1317,7 +1513,6 @@ VB_AGE_TEST_WITH_RETURN( dev_priv ); buf = dma->buflist[elts.idx]; - buf_priv = buf->dev_private; if ( buf->pid != current->pid ) { DRM_ERROR( "process %d using buffer owned by %d\n", @@ -1342,11 +1537,37 @@ } buf->used = elts.end; - buf_priv->prim = elts.prim; - buf_priv->discard = elts.discard; - radeon_cp_dispatch_indices( dev, buf, elts.start, elts.end, count ); + if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { + radeon_emit_state( dev_priv, + &sarea_priv->context_state, + sarea_priv->tex_state, + sarea_priv->dirty ); + + sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | + RADEON_UPLOAD_TEX1IMAGES | + RADEON_UPLOAD_TEX2IMAGES | + RADEON_REQUIRE_QUIESCENCE); + } + + + /* Build up a prim_t record: + */ + prim.start = elts.start; + prim.finish = elts.end; + prim.prim = elts.prim; + prim.offset = 0; /* offset from start of dma buffers */ + prim.numverts = RADEON_MAX_VB_VERTS; /* duh */ + prim.vc_format = dev_priv->sarea_priv->vc_format; + + radeon_cp_dispatch_indices( dev, buf, &prim, + dev_priv->sarea_priv->boxes, + dev_priv->sarea_priv->nbox ); + if (elts.discard) { + radeon_cp_discard_buffer( dev, buf ); + } + COMMIT_RING(); return 0; } @@ -1358,6 +1579,7 @@ drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_texture_t tex; drm_radeon_tex_image_t image; + int ret; LOCK_TEST_WITH_RETURN( dev ); @@ -1377,7 +1599,10 @@ RING_SPACE_TEST_WITH_RETURN( dev_priv ); VB_AGE_TEST_WITH_RETURN( dev_priv ); - return radeon_cp_dispatch_texture( dev, &tex, &image ); + ret = radeon_cp_dispatch_texture( dev, &tex, &image ); + + COMMIT_RING(); + return ret; } int radeon_cp_stipple( struct inode *inode, struct file *filp, @@ -1402,6 +1627,7 @@ radeon_cp_dispatch_stipple( dev, mask ); + COMMIT_RING(); return 0; } @@ -1413,7 +1639,6 @@ drm_radeon_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; - drm_radeon_buf_priv_t *buf_priv; drm_radeon_indirect_t indirect; RING_LOCALS; @@ -1439,7 +1664,6 @@ } buf = dma->buflist[indirect.idx]; - buf_priv = buf->dev_private; if ( buf->pid != current->pid ) { DRM_ERROR( "process %d using buffer owned by %d\n", @@ -1461,7 +1685,6 @@ VB_AGE_TEST_WITH_RETURN( dev_priv ); buf->used = indirect.end; - buf_priv->discard = indirect.discard; /* Wait for the 3D stream to idle before the indirect buffer * containing 2D acceleration commands is processed. @@ -1477,6 +1700,526 @@ * privileged clients. */ radeon_cp_dispatch_indirect( dev, buf, indirect.start, indirect.end ); + if (indirect.discard) { + radeon_cp_discard_buffer( dev, buf ); + } + + + COMMIT_RING(); + return 0; +} + +int radeon_cp_vertex2(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_radeon_vertex2_t vertex; + int i; + unsigned char laststate; + + LOCK_TEST_WITH_RETURN( dev ); + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex2_t *)data, + sizeof(vertex) ); + + DRM_DEBUG( "pid=%d index=%d discard=%d\n", + current->pid, + vertex.idx, vertex.discard ); + + if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) { + DRM_ERROR( "buffer index %d (of %d max)\n", + vertex.idx, dma->buf_count - 1 ); + return -EINVAL; + } + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); + + buf = dma->buflist[vertex.idx]; + + if ( buf->pid != current->pid ) { + DRM_ERROR( "process %d using buffer owned by %d\n", + current->pid, buf->pid ); + return -EINVAL; + } + + if ( buf->pending ) { + DRM_ERROR( "sending pending buffer %d\n", vertex.idx ); + return -EINVAL; + } + + if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) + return -EINVAL; + + for (laststate = 0xff, i = 0 ; i < vertex.nr_prims ; i++) { + drm_radeon_prim_t prim; + drm_radeon_tcl_prim_t tclprim; + + if ( copy_from_user( &prim, &vertex.prim[i], sizeof(prim) ) ) + return -EFAULT; + + if ( prim.stateidx != laststate ) { + drm_radeon_state_t state; + + if ( copy_from_user( &state, + &vertex.state[prim.stateidx], + sizeof(state) ) ) + return -EFAULT; + + radeon_emit_state2( dev_priv, &state ); + + laststate = prim.stateidx; + } + + tclprim.start = prim.start; + tclprim.finish = prim.finish; + tclprim.prim = prim.prim; + tclprim.vc_format = prim.vc_format; + + if ( prim.prim & RADEON_PRIM_WALK_IND ) { + tclprim.offset = prim.numverts * 64; + tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */ + + radeon_cp_dispatch_indices( dev, buf, &tclprim, + sarea_priv->boxes, + sarea_priv->nbox); + } else { + tclprim.numverts = prim.numverts; + tclprim.offset = 0; /* not used */ + + radeon_cp_dispatch_vertex( dev, buf, &tclprim, + sarea_priv->boxes, + sarea_priv->nbox); + } + + if (sarea_priv->nbox == 1) + sarea_priv->nbox = 0; + } + + if ( vertex.discard ) { + radeon_cp_discard_buffer( dev, buf ); + } + + COMMIT_RING(); + return 0; +} + + +static int radeon_emit_packets( + drm_radeon_private_t *dev_priv, + drm_radeon_cmd_header_t header, + drm_radeon_cmd_buffer_t *cmdbuf ) +{ + int id = (int)header.packet.packet_id; + int sz, reg; + int *data = (int *)cmdbuf->buf; + RING_LOCALS; + + if (id >= RADEON_MAX_STATE_PACKETS) + return -EINVAL; + + sz = packet[id].len; + reg = packet[id].start; + + if (sz * sizeof(int) > cmdbuf->bufsz) + return -EINVAL; + + BEGIN_RING(sz+1); + OUT_RING( CP_PACKET0( reg, (sz-1) ) ); + OUT_RING_USER_TABLE( data, sz ); + ADVANCE_RING(); + + cmdbuf->buf += sz * sizeof(int); + cmdbuf->bufsz -= sz * sizeof(int); + return 0; +} + +static __inline__ int radeon_emit_scalars( + drm_radeon_private_t *dev_priv, + drm_radeon_cmd_header_t header, + drm_radeon_cmd_buffer_t *cmdbuf ) +{ + int sz = header.scalars.count; + int *data = (int *)cmdbuf->buf; + int start = header.scalars.offset; + int stride = header.scalars.stride; + RING_LOCALS; + + BEGIN_RING( 3+sz ); + OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) ); + OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); + OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) ); + OUT_RING_USER_TABLE( data, sz ); + ADVANCE_RING(); + cmdbuf->buf += sz * sizeof(int); + cmdbuf->bufsz -= sz * sizeof(int); + return 0; +} + +/* God this is ugly + */ +static __inline__ int radeon_emit_scalars2( + drm_radeon_private_t *dev_priv, + drm_radeon_cmd_header_t header, + drm_radeon_cmd_buffer_t *cmdbuf ) +{ + int sz = header.scalars.count; + int *data = (int *)cmdbuf->buf; + int start = ((unsigned int)header.scalars.offset) + 0x100; + int stride = header.scalars.stride; + RING_LOCALS; + + BEGIN_RING( 3+sz ); + OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) ); + OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); + OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) ); + OUT_RING_USER_TABLE( data, sz ); + ADVANCE_RING(); + cmdbuf->buf += sz * sizeof(int); + cmdbuf->bufsz -= sz * sizeof(int); + return 0; +} + +static __inline__ int radeon_emit_vectors( + drm_radeon_private_t *dev_priv, + drm_radeon_cmd_header_t header, + drm_radeon_cmd_buffer_t *cmdbuf ) +{ + int sz = header.vectors.count; + int *data = (int *)cmdbuf->buf; + int start = header.vectors.offset; + int stride = header.vectors.stride; + RING_LOCALS; + + BEGIN_RING( 3+sz ); + OUT_RING( CP_PACKET0( RADEON_SE_TCL_VECTOR_INDX_REG, 0 ) ); + OUT_RING( start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); + OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_VECTOR_DATA_REG, (sz-1) ) ); + OUT_RING_USER_TABLE( data, sz ); + ADVANCE_RING(); + + cmdbuf->buf += sz * sizeof(int); + cmdbuf->bufsz -= sz * sizeof(int); + return 0; +} + + +static int radeon_emit_packet3( drm_device_t *dev, + drm_radeon_cmd_buffer_t *cmdbuf ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + int cmdsz, tmp; + int *cmd = (int *)cmdbuf->buf; + RING_LOCALS; + + DRM_DEBUG("\n"); + + if (__get_user( tmp, &cmd[0])) + return -EFAULT; + + cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16); + + if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 || + cmdsz * 4 > cmdbuf->bufsz) + return -EINVAL; + + BEGIN_RING( cmdsz ); + OUT_RING_USER_TABLE( cmd, cmdsz ); + ADVANCE_RING(); + + cmdbuf->buf += cmdsz * 4; + cmdbuf->bufsz -= cmdsz * 4; + return 0; +} + + +static int radeon_emit_packet3_cliprect( drm_device_t *dev, + drm_radeon_cmd_buffer_t *cmdbuf, + int orig_nbox ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_clip_rect_t box; + int cmdsz, tmp; + int *cmd = (int *)cmdbuf->buf; + drm_clip_rect_t *boxes = cmdbuf->boxes; + int i = 0; + RING_LOCALS; + + DRM_DEBUG("\n"); + + if (__get_user( tmp, &cmd[0])) + return -EFAULT; + + cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16); + + if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 || + cmdsz * 4 > cmdbuf->bufsz) + return -EINVAL; + + if (!orig_nbox) + goto out; + + do { + if ( i < cmdbuf->nbox ) { + if (__copy_from_user( &box, &boxes[i], sizeof(box) )) + return -EFAULT; + /* FIXME The second and subsequent times round + * this loop, send a WAIT_UNTIL_3D_IDLE before + * calling emit_clip_rect(). This fixes a + * lockup on fast machines when sending + * several cliprects with a cmdbuf, as when + * waving a 2D window over a 3D + * window. Something in the commands from user + * space seems to hang the card when they're + * sent several times in a row. That would be + * the correct place to fix it but this works + * around it until I can figure that out - Tim + * Smith */ + if ( i ) { + BEGIN_RING( 2 ); + RADEON_WAIT_UNTIL_3D_IDLE(); + ADVANCE_RING(); + } + radeon_emit_clip_rect( dev_priv, &box ); + } + + BEGIN_RING( cmdsz ); + OUT_RING_USER_TABLE( cmd, cmdsz ); + ADVANCE_RING(); + + } while ( ++i < cmdbuf->nbox ); + if (cmdbuf->nbox == 1) + cmdbuf->nbox = 0; + + out: + cmdbuf->buf += cmdsz * 4; + cmdbuf->bufsz -= cmdsz * 4; + return 0; +} + + +static int radeon_emit_wait( drm_device_t *dev, int flags ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + DRM_DEBUG("%s: %x\n", __FUNCTION__, flags); + switch (flags) { + case RADEON_WAIT_2D: + BEGIN_RING( 2 ); + RADEON_WAIT_UNTIL_2D_IDLE(); + ADVANCE_RING(); + break; + case RADEON_WAIT_3D: + BEGIN_RING( 2 ); + RADEON_WAIT_UNTIL_3D_IDLE(); + ADVANCE_RING(); + break; + case RADEON_WAIT_2D|RADEON_WAIT_3D: + BEGIN_RING( 2 ); + RADEON_WAIT_UNTIL_IDLE(); + ADVANCE_RING(); + break; + default: + return -EINVAL; + } + + return 0; +} + +int radeon_cp_cmdbuf(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf = 0; + int idx; + drm_radeon_cmd_buffer_t cmdbuf; + drm_radeon_cmd_header_t header; + int orig_nbox; + + LOCK_TEST_WITH_RETURN( dev ); + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + DRM_COPY_FROM_USER_IOCTL( cmdbuf, (drm_radeon_cmd_buffer_t *)data, + sizeof(cmdbuf) ); + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); + + + if (verify_area( VERIFY_READ, cmdbuf.buf, cmdbuf.bufsz )) + return -EFAULT; + + if (cmdbuf.nbox && + verify_area( VERIFY_READ, cmdbuf.boxes, + cmdbuf.nbox * sizeof(drm_clip_rect_t))) + return -EFAULT; + + orig_nbox = cmdbuf.nbox; + + while ( cmdbuf.bufsz >= sizeof(header) ) { + + if (__get_user( header.i, (int *)cmdbuf.buf )) { + DRM_ERROR("__get_user %p\n", cmdbuf.buf); + return -EFAULT; + } + + cmdbuf.buf += sizeof(header); + cmdbuf.bufsz -= sizeof(header); + + switch (header.header.cmd_type) { + case RADEON_CMD_PACKET: + DRM_DEBUG("RADEON_CMD_PACKET\n"); + if (radeon_emit_packets( dev_priv, header, &cmdbuf )) { + DRM_ERROR("radeon_emit_packets failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_SCALARS: + DRM_DEBUG("RADEON_CMD_SCALARS\n"); + if (radeon_emit_scalars( dev_priv, header, &cmdbuf )) { + DRM_ERROR("radeon_emit_scalars failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_VECTORS: + DRM_DEBUG("RADEON_CMD_VECTORS\n"); + if (radeon_emit_vectors( dev_priv, header, &cmdbuf )) { + DRM_ERROR("radeon_emit_vectors failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_DMA_DISCARD: + DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n"); + idx = header.dma.buf_idx; + if ( idx < 0 || idx >= dma->buf_count ) { + DRM_ERROR( "buffer index %d (of %d max)\n", + idx, dma->buf_count - 1 ); + return -EINVAL; + } + + buf = dma->buflist[idx]; + if ( buf->pid != current->pid || buf->pending ) { + DRM_ERROR( "bad buffer\n" ); + return -EINVAL; + } + + radeon_cp_discard_buffer( dev, buf ); + break; + + case RADEON_CMD_PACKET3: + DRM_DEBUG("RADEON_CMD_PACKET3\n"); + if (radeon_emit_packet3( dev, &cmdbuf )) { + DRM_ERROR("radeon_emit_packet3 failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_PACKET3_CLIP: + DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n"); + if (radeon_emit_packet3_cliprect( dev, &cmdbuf, orig_nbox )) { + DRM_ERROR("radeon_emit_packet3_clip failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_SCALARS2: + DRM_DEBUG("RADEON_CMD_SCALARS2\n"); + if (radeon_emit_scalars2( dev_priv, header, &cmdbuf )) { + DRM_ERROR("radeon_emit_scalars2 failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_WAIT: + DRM_DEBUG("RADEON_CMD_WAIT\n"); + if (radeon_emit_wait( dev, header.wait.flags )) { + DRM_ERROR("radeon_emit_wait failed\n"); + return -EINVAL; + } + break; + default: + DRM_ERROR("bad cmd_type %d at %p\n", + header.header.cmd_type, + cmdbuf.buf - sizeof(header)); + return -EINVAL; + } + } + + + DRM_DEBUG("DONE\n"); + COMMIT_RING(); + return 0; +} + + + +int radeon_cp_getparam(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_getparam_t param; + int value; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + DRM_COPY_FROM_USER_IOCTL( param, (drm_radeon_getparam_t *)data, + sizeof(param) ); + + DRM_DEBUG( "pid=%d\n", current->pid ); + + switch( param.param ) { + case RADEON_PARAM_AGP_BUFFER_OFFSET: + value = dev_priv->agp_buffers_offset; + break; + case RADEON_PARAM_LAST_FRAME: + dev_priv->stats.last_frame_reads++; + value = GET_SCRATCH( 0 ); + break; + case RADEON_PARAM_LAST_DISPATCH: + value = GET_SCRATCH( 1 ); + break; + case RADEON_PARAM_LAST_CLEAR: + dev_priv->stats.last_clear_reads++; + value = GET_SCRATCH( 2 ); + break; + case RADEON_PARAM_IRQ_NR: + value = dev->irq; + break; + case RADEON_PARAM_AGP_BASE: + value = dev_priv->agp_vm_start; + break; + default: + return -EINVAL; + } + + if ( copy_to_user( param.value, &value, sizeof(int) ) ) { + DRM_ERROR( "copy_to_user\n" ); + return -EFAULT; + } + return 0; } Index: drivers/char/drm/sis.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/sis.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/sis.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/sis.h 4 Aug 2004 01:28:49 -0000 1.2 @@ -24,7 +24,7 @@ * DEALINGS IN THE SOFTWARE. * */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis.h,v 1.1 2001/05/19 18:29:22 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis.h,v 1.2 2001/12/19 21:25:59 dawes Exp $ */ #ifndef __SIS_H__ #define __SIS_H__ @@ -42,6 +42,31 @@ #define __HAVE_MTRR 1 #define __HAVE_CTX_BITMAP 1 +#define DRIVER_AUTHOR "SIS" +#define DRIVER_NAME "sis" +#define DRIVER_DESC "SIS 300/630/540" +#define DRIVER_DATE "20010503" +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 0 +#define DRIVER_PATCHLEVEL 0 + +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(SIS_IOCTL_FB_ALLOC)] = { sis_fb_alloc, 1, 0 }, \ + [DRM_IOCTL_NR(SIS_IOCTL_FB_FREE)] = { sis_fb_free, 1, 0 }, \ + /* AGP Memory Management */ \ + [DRM_IOCTL_NR(SIS_IOCTL_AGP_INIT)] = { sisp_agp_init, 1, 0 }, \ + [DRM_IOCTL_NR(SIS_IOCTL_AGP_ALLOC)] = { sisp_agp_alloc, 1, 0 }, \ + [DRM_IOCTL_NR(SIS_IOCTL_AGP_FREE)] = { sisp_agp_free, 1, 0 } +#if 0 /* these don't appear to be defined */ + /* SIS Stereo */ + [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { sis_control, 1, 1 }, + [DRM_IOCTL_NR(SIS_IOCTL_FLIP)] = { sis_flip, 1, 1 }, + [DRM_IOCTL_NR(SIS_IOCTL_FLIP_INIT)] = { sis_flip_init, 1, 1 }, + [DRM_IOCTL_NR(SIS_IOCTL_FLIP_FINAL)] = { sis_flip_final, 1, 1 } +#endif + +#define __HAVE_COUNTERS 5 + /* Buffer customization: */ #define DRIVER_AGP_BUFFERS_MAP( dev ) \ Index: drivers/char/drm/sis_drm.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/sis_drm.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/sis_drm.h 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/sis_drm.h 4 Aug 2004 01:28:49 -0000 1.2 @@ -2,6 +2,16 @@ #ifndef _sis_drm_public_h_ #define _sis_drm_public_h_ +/* SiS specific ioctls */ +#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t) +#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t) +#define SIS_IOCTL_AGP_INIT DRM_IOWR(0x53, drm_sis_agp_t) +#define SIS_IOCTL_AGP_ALLOC DRM_IOWR(0x54, drm_sis_mem_t) +#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t) +#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t) +#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49) +#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50) + typedef struct { int context; unsigned int offset; Index: drivers/char/drm/sis_drv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/sis_drv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/sis_drv.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/sis_drv.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -31,31 +31,6 @@ #include "sis_drm.h" #include "sis_drv.h" -#define DRIVER_AUTHOR "SIS" -#define DRIVER_NAME "sis" -#define DRIVER_DESC "SIS 300/630/540" -#define DRIVER_DATE "20010503" -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 0 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(SIS_IOCTL_FB_ALLOC)] = { sis_fb_alloc, 1, 0 }, \ - [DRM_IOCTL_NR(SIS_IOCTL_FB_FREE)] = { sis_fb_free, 1, 0 }, \ - /* AGP Memory Management */ \ - [DRM_IOCTL_NR(SIS_IOCTL_AGP_INIT)] = { sisp_agp_init, 1, 0 }, \ - [DRM_IOCTL_NR(SIS_IOCTL_AGP_ALLOC)] = { sisp_agp_alloc, 1, 0 }, \ - [DRM_IOCTL_NR(SIS_IOCTL_AGP_FREE)] = { sisp_agp_free, 1, 0 } -#if 0 /* these don't appear to be defined */ - /* SIS Stereo */ - [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { sis_control, 1, 1 }, - [DRM_IOCTL_NR(SIS_IOCTL_FLIP)] = { sis_flip, 1, 1 }, - [DRM_IOCTL_NR(SIS_IOCTL_FLIP_INIT)] = { sis_flip_init, 1, 1 }, - [DRM_IOCTL_NR(SIS_IOCTL_FLIP_FINAL)] = { sis_flip_final, 1, 1 } -#endif - -#define __HAVE_COUNTERS 5 - #include "drm_auth.h" #include "drm_agpsupport.h" #include "drm_bufs.h" Index: drivers/char/drm/sis_ds.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/sis_ds.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/sis_ds.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/sis_ds.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -49,16 +49,19 @@ set_t *set; set = (set_t *)MALLOC(sizeof(set_t)); - if (set) { + if(set) + { for(i = 0; i < SET_SIZE; i++){ set->list[i].free_next = i+1; set->list[i].alloc_next = -1; - } + } + set->list[SET_SIZE-1].free_next = -1; set->free = 0; set->alloc = -1; set->trace = -1; } + return set; } Index: drivers/char/drm/tdfx_drv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm/tdfx_drv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm/tdfx_drv.c 22 Jul 2004 19:49:52 -0000 1.1 +++ drivers/char/drm/tdfx_drv.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -82,25 +82,6 @@ #include "drm_drawable.h" #include "drm_drv.h" -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init tdfx_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", tdfx_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" Index: drivers/char/drm-4.0/agpsupport.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm-4.0/agpsupport.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm-4.0/agpsupport.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/drm-4.0/agpsupport.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -264,6 +264,7 @@ #if LINUX_VERSION_CODE >= 0x020400 case INTEL_I840: head->chipset = "Intel i840"; break; #endif + case INTEL_460GX: head->chipset = "Intel 460GX"; break; case VIA_GENERIC: head->chipset = "VIA"; break; case VIA_VP3: head->chipset = "VIA VP3"; break; @@ -275,9 +276,12 @@ break; case VIA_APOLLO_KT133: head->chipset = "VIA Apollo KT133"; break; + case VIA_APOLLO_KM266: head->chipset = "VIA Apollo KM266 / KL266"; + break; 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"; @@ -297,6 +301,7 @@ break; case SVWRKS_HE: head->chipset = "Serverworks HE"; break; case SVWRKS_LE: head->chipset = "Serverworks LE"; break; + case HP_ZX1: head->chipset = "HP ZX1"; break; default: head->chipset = "Unknown"; break; } Index: drivers/char/drm-4.0/bufs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm-4.0/bufs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm-4.0/bufs.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/drm-4.0/bufs.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -87,7 +87,7 @@ MTRR_TYPE_WRCOMB, 1); } #endif - map->handle = drm_ioremap(map->offset, map->size); + map->handle = drm_ioremap(map->offset, map->size, dev); break; Index: drivers/char/drm-4.0/drmP.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm-4.0/drmP.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm-4.0/drmP.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/drm-4.0/drmP.h 4 Aug 2004 01:28:49 -0000 1.2 @@ -679,8 +679,8 @@ extern unsigned long drm_alloc_pages(int order, int area); extern void drm_free_pages(unsigned long address, int order, int area); -extern void *drm_ioremap(unsigned long offset, unsigned long size); -extern void drm_ioremapfree(void *pt, unsigned long size); +extern void *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev); +extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev); #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) extern agp_memory *drm_alloc_agp(int pages, u32 type); Index: drivers/char/drm-4.0/ffb_context.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm-4.0/ffb_context.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm-4.0/ffb_context.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/drm-4.0/ffb_context.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ffb_context.c,v 1.1 2004/07/22 19:49:54 joff Exp $ +/* $Id: ffb_context.c,v 1.2 2004/08/04 01:28:49 joff Exp $ * ffb_context.c: Creator/Creator3D DRI/DRM context switching. * * Copyright (C) 2000 David S. Miller (davem@redhat.com) Index: drivers/char/drm-4.0/ffb_drv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm-4.0/ffb_drv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm-4.0/ffb_drv.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/drm-4.0/ffb_drv.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ffb_drv.c,v 1.1 2004/07/22 19:49:54 joff Exp $ +/* $Id: ffb_drv.c,v 1.2 2004/08/04 01:28:49 joff Exp $ * ffb_drv.c: Creator/Creator3D direct rendering driver. * * Copyright (C) 2000 David S. Miller (davem@redhat.com) @@ -158,7 +158,7 @@ switch (map->type) { case _DRM_REGISTERS: case _DRM_FRAME_BUFFER: - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: Index: drivers/char/drm-4.0/ffb_drv.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm-4.0/ffb_drv.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm-4.0/ffb_drv.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/drm-4.0/ffb_drv.h 4 Aug 2004 01:28:49 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ffb_drv.h,v 1.1 2004/07/22 19:49:54 joff Exp $ +/* $Id: ffb_drv.h,v 1.2 2004/08/04 01:28:49 joff Exp $ * ffb_drv.h: Creator/Creator3D direct rendering driver. * * Copyright (C) 2000 David S. Miller (davem@redhat.com) Index: drivers/char/drm-4.0/gamma_drv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm-4.0/gamma_drv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm-4.0/gamma_drv.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/drm-4.0/gamma_drv.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -258,7 +258,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: drm_free_pages((unsigned long)map->handle, Index: drivers/char/drm-4.0/i810_dma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm-4.0/i810_dma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm-4.0/i810_dma.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/drm-4.0/i810_dma.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -305,7 +305,7 @@ if(dev_priv->ring.virtual_start) { drm_ioremapfree((void *) dev_priv->ring.virtual_start, - dev_priv->ring.Size); + dev_priv->ring.Size, dev); } if(dev_priv->hw_status_page != 0UL) { i810_free_page(dev, dev_priv->hw_status_page); @@ -319,7 +319,7 @@ for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - drm_ioremapfree(buf_priv->kernel_virtual, buf->total); + drm_ioremapfree(buf_priv->kernel_virtual, buf->total, dev); } } return 0; @@ -393,7 +393,7 @@ *buf_priv->in_use = I810_BUF_FREE; buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, - buf->total); + buf->total, dev); } return 0; } @@ -430,7 +430,7 @@ dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + init->ring_start, - init->ring_size); + init->ring_size, dev); dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; Index: drivers/char/drm-4.0/i810_drv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm-4.0/i810_drv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm-4.0/i810_drv.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/drm-4.0/i810_drv.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -286,7 +286,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: drm_free_pages((unsigned long)map->handle, Index: drivers/char/drm-4.0/memory.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm-4.0/memory.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm-4.0/memory.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/drm-4.0/memory.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -296,7 +296,7 @@ } } -void *drm_ioremap(unsigned long offset, unsigned long size) +void *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev) { void *pt; @@ -319,7 +319,7 @@ return pt; } -void drm_ioremapfree(void *pt, unsigned long size) +void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev) { int alloc_count; int free_count; Index: drivers/char/drm-4.0/mga_dma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm-4.0/mga_dma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm-4.0/mga_dma.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/drm-4.0/mga_dma.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -308,7 +308,7 @@ temp = ((temp + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; dev_priv->ioremap = drm_ioremap(dev->agp->base + offset, - temp); + temp, dev); if(dev_priv->ioremap == NULL) { DRM_ERROR("Ioremap failed\n"); return -ENOMEM; @@ -635,7 +635,7 @@ dev_priv->primary_size + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE; - drm_ioremapfree((void *) dev_priv->ioremap, temp); + drm_ioremapfree((void *) dev_priv->ioremap, temp, dev); } if(dev_priv->status_page != NULL) { iounmap(dev_priv->status_page); Index: drivers/char/drm-4.0/mga_drv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm-4.0/mga_drv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm-4.0/mga_drv.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/drm-4.0/mga_drv.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -286,7 +286,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: drm_free_pages((unsigned long)map->handle, Index: drivers/char/drm-4.0/r128_cce.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm-4.0/r128_cce.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm-4.0/r128_cce.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/drm-4.0/r128_cce.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -86,12 +86,12 @@ }; -#define DO_REMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size) +#define DO_REMAP(_m, _d) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size, (_d)) -#define DO_REMAPFREE(_m) \ +#define DO_REMAPFREE(_m, _d) \ do { \ if ((_m)->handle && (_m)->size) \ - drm_ioremapfree((_m)->handle, (_m)->size); \ + drm_ioremapfree((_m)->handle, (_m)->size, (_d)); \ } while (0) #define DO_FIND_MAP(_m, _o) \ @@ -481,12 +481,12 @@ (drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle + init->sarea_priv_offset); - DO_REMAP( dev_priv->cce_ring ); - DO_REMAP( dev_priv->ring_rptr ); - DO_REMAP( dev_priv->buffers ); + DO_REMAP( dev_priv->cce_ring, dev ); + DO_REMAP( dev_priv->ring_rptr, dev ); + DO_REMAP( dev_priv->buffers, dev ); #if 0 if ( !dev_priv->is_pci ) { - DO_REMAP( dev_priv->agp_textures ); + DO_REMAP( dev_priv->agp_textures, dev ); } #endif @@ -521,12 +521,12 @@ if ( dev->dev_private ) { drm_r128_private_t *dev_priv = dev->dev_private; - DO_REMAPFREE( dev_priv->cce_ring ); - DO_REMAPFREE( dev_priv->ring_rptr ); - DO_REMAPFREE( dev_priv->buffers ); + DO_REMAPFREE( dev_priv->cce_ring, dev ); + DO_REMAPFREE( dev_priv->ring_rptr, dev ); + DO_REMAPFREE( dev_priv->buffers, dev ); #if 0 if ( !dev_priv->is_pci ) { - DO_REMAPFREE( dev_priv->agp_textures ); + DO_REMAPFREE( dev_priv->agp_textures, dev ); } #endif Index: drivers/char/drm-4.0/r128_drv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm-4.0/r128_drv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm-4.0/r128_drv.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/drm-4.0/r128_drv.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -296,7 +296,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: drm_free_pages((unsigned long)map->handle, Index: drivers/char/drm-4.0/r128_state.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm-4.0/r128_state.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm-4.0/r128_state.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/drm-4.0/r128_state.c 4 Aug 2004 01:28:49 -0000 1.2 @@ -938,6 +938,9 @@ } count = depth->n; + + if (count > 4096 || count <= 0) + return -EMSGSIZE; if ( copy_from_user( &x, depth->x, sizeof(x) ) ) { return -EFAULT; } @@ -1048,6 +1051,9 @@ count = depth->n; + if (count > 4096 || count <= 0) + return -EMSGSIZE; + x = kmalloc( count * sizeof(*x), 0 ); if ( x == NULL ) { return -ENOMEM; @@ -1178,6 +1184,10 @@ } count = depth->n; + + if (count > 4096 || count <= 0) + return -EMSGSIZE; + if ( copy_from_user( &x, depth->x, sizeof(x) ) ) { return -EFAULT; } @@ -1235,6 +1245,8 @@ } count = depth->n; + if (count > 4096 || count <= 0) + return -EMSGSIZE; if ( count > dev_priv->depth_pitch ) { count = dev_priv->depth_pitch; } Index: drivers/char/drm-4.0/radeon_cp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm-4.0/radeon_cp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm-4.0/radeon_cp.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/drm-4.0/radeon_cp.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -300,12 +300,12 @@ }; -#define DO_IOREMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size) +#define DO_IOREMAP(_m, _d) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size, (_d)) -#define DO_IOREMAPFREE(_m) \ +#define DO_IOREMAPFREE(_m, _d) \ do { \ if ((_m)->handle && (_m)->size) \ - drm_ioremapfree((_m)->handle, (_m)->size); \ + drm_ioremapfree((_m)->handle, (_m)->size, (_d));\ } while (0) #define DO_FIND_MAP(_m, _o) \ @@ -757,12 +757,12 @@ (drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle + init->sarea_priv_offset); - DO_IOREMAP( dev_priv->cp_ring ); - DO_IOREMAP( dev_priv->ring_rptr ); - DO_IOREMAP( dev_priv->buffers ); + DO_IOREMAP( dev_priv->cp_ring, dev ); + DO_IOREMAP( dev_priv->ring_rptr, dev ); + DO_IOREMAP( dev_priv->buffers, dev ); #if 0 if ( !dev_priv->is_pci ) { - DO_IOREMAP( dev_priv->agp_textures ); + DO_IOREMAP( dev_priv->agp_textures, dev ); } #endif @@ -828,12 +828,12 @@ if ( dev->dev_private ) { drm_radeon_private_t *dev_priv = dev->dev_private; - DO_IOREMAPFREE( dev_priv->cp_ring ); - DO_IOREMAPFREE( dev_priv->ring_rptr ); - DO_IOREMAPFREE( dev_priv->buffers ); + DO_IOREMAPFREE( dev_priv->cp_ring, dev ); + DO_IOREMAPFREE( dev_priv->ring_rptr, dev ); + DO_IOREMAPFREE( dev_priv->buffers, dev ); #if 0 if ( !dev_priv->is_pci ) { - DO_IOREMAPFREE( dev_priv->agp_textures ); + DO_IOREMAPFREE( dev_priv->agp_textures, dev ); } #endif Index: drivers/char/drm-4.0/radeon_drv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm-4.0/radeon_drv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm-4.0/radeon_drv.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/drm-4.0/radeon_drv.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -294,7 +294,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: drm_free_pages((unsigned long)map->handle, Index: drivers/char/drm-4.0/tdfx_drv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/drm-4.0/tdfx_drv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/drm-4.0/tdfx_drv.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/drm-4.0/tdfx_drv.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -264,7 +264,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: drm_free_pages((unsigned long)map->handle, Index: drivers/char/ftape/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/Makefile 22 Jul 2004 19:49:53 -0000 1.1 +++ drivers/char/ftape/Makefile 4 Aug 2004 01:28:50 -0000 1.2 @@ -16,8 +16,8 @@ # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. # # $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/Makefile,v $ -# $Revision: 1.1 $ -# $Date: 2004/07/22 19:49:53 $ +# $Revision: 1.2 $ +# $Date: 2004/08/04 01:28:50 $ # # Makefile for the QIC-40/80/3010/3020 floppy-tape driver for # Linux. Index: drivers/char/ftape/compressor/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/compressor/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/compressor/Makefile 22 Jul 2004 19:49:53 -0000 1.1 +++ drivers/char/ftape/compressor/Makefile 4 Aug 2004 01:28:50 -0000 1.2 @@ -16,8 +16,8 @@ # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. # # $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/compressor/Makefile,v $ -# $Revision: 1.1 $ -# $Date: 2004/07/22 19:49:53 $ +# $Revision: 1.2 $ +# $Date: 2004/08/04 01:28:50 $ # # Makefile for the optional compressor for th zftape VFS # interface to the QIC-40/80/3010/3020 floppy-tape driver for Index: drivers/char/ftape/compressor/lzrw3.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/compressor/lzrw3.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/compressor/lzrw3.c 22 Jul 2004 19:49:53 -0000 1.1 +++ drivers/char/ftape/compressor/lzrw3.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -1,7 +1,7 @@ /* * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/compressor/lzrw3.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:53 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * Implementation of Ross Williams lzrw3 algorithm. Adaption for zftape. * Index: drivers/char/ftape/compressor/lzrw3.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/compressor/lzrw3.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/compressor/lzrw3.h 22 Jul 2004 19:49:53 -0000 1.1 +++ drivers/char/ftape/compressor/lzrw3.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -2,8 +2,8 @@ #define _LZRW3_H /* * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/compressor/lzrw3.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:53 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * include files for lzrw3. Only slighty modified from the original * version. Assembles the three include files compress.h, port.h and Index: drivers/char/ftape/compressor/zftape-compress.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/compressor/zftape-compress.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/compressor/zftape-compress.c 22 Jul 2004 19:49:53 -0000 1.1 +++ drivers/char/ftape/compressor/zftape-compress.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -28,8 +28,8 @@ */ char zftc_src[] ="$Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/compressor/zftape-compress.c,v $"; - char zftc_rev[] = "$Revision: 1.1 $"; - char zftc_dat[] = "$Date: 2004/07/22 19:49:53 $"; + char zftc_rev[] = "$Revision: 1.2 $"; + char zftc_dat[] = "$Date: 2004/08/04 01:28:50 $"; #include #include Index: drivers/char/ftape/compressor/zftape-compress.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/compressor/zftape-compress.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/compressor/zftape-compress.h 22 Jul 2004 19:49:53 -0000 1.1 +++ drivers/char/ftape/compressor/zftape-compress.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -20,8 +20,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/compressor/zftape-compress.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:53 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains macros and definitions for zftape's * builtin compression code. Index: drivers/char/ftape/lowlevel/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/Makefile 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/Makefile 4 Aug 2004 01:28:50 -0000 1.2 @@ -16,8 +16,8 @@ # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. # # $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/Makefile,v $ -# $Revision: 1.1 $ -# $Date: 2004/07/22 19:49:54 $ +# $Revision: 1.2 $ +# $Date: 2004/08/04 01:28:50 $ # # Makefile for the lowlevel part QIC-40/80/3010/3020 floppy-tape # driver for Linux. Index: drivers/char/ftape/lowlevel/fc-10.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/fc-10.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/fc-10.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/fc-10.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -44,8 +44,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/fc-10.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains code for the CMS FC-10/FC-20 card. */ Index: drivers/char/ftape/lowlevel/fc-10.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/fc-10.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/fc-10.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/fc-10.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -20,8 +20,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/fc-10.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains definitions for the FC-10 code * of the QIC-40/80 floppy-tape driver for Linux. Index: drivers/char/ftape/lowlevel/fdc-io.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/fdc-io.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/fdc-io.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/fdc-io.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -18,8 +18,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/fdc-io.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the low-level floppy disk interface code * for the QIC-40/80/3010/3020 floppy-tape driver "ftape" for Index: drivers/char/ftape/lowlevel/fdc-io.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/fdc-io.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/fdc-io.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/fdc-io.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -21,8 +21,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/fdc-io.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the declarations for the low level * functions that communicate with the floppy disk controller, Index: drivers/char/ftape/lowlevel/fdc-isr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/fdc-isr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/fdc-isr.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/fdc-isr.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -18,8 +18,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/fdc-isr.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the interrupt service routine and * associated code for the QIC-40/80/3010/3020 floppy-tape driver Index: drivers/char/ftape/lowlevel/fdc-isr.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/fdc-isr.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/fdc-isr.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/fdc-isr.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -21,8 +21,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/fdc-isr.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file declares the global variables necessary to * synchronize the interrupt service routine (isr) with the Index: drivers/char/ftape/lowlevel/ftape-bsm.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-bsm.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-bsm.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-bsm.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -18,8 +18,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-bsm.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the bad-sector map handling code for * the QIC-117 floppy tape driver for Linux. Index: drivers/char/ftape/lowlevel/ftape-bsm.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-bsm.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-bsm.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-bsm.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -21,8 +21,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-bsm.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains definitions for the bad sector map handling * routines for the QIC-117 floppy-tape driver for Linux. Index: drivers/char/ftape/lowlevel/ftape-buffer.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-buffer.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-buffer.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-buffer.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -17,8 +17,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-buffer.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the allocator/dealloctor for ftape's dynamic dma * buffer. Index: drivers/char/ftape/lowlevel/ftape-buffer.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-buffer.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-buffer.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-buffer.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -20,8 +20,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-buffer.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the allocator/dealloctor for ftape's dynamic dma * buffer. Index: drivers/char/ftape/lowlevel/ftape-calibr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-calibr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-calibr.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-calibr.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -17,8 +17,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-calibr.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * GP calibration routine for processor speed dependent * functions. Index: drivers/char/ftape/lowlevel/ftape-calibr.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-calibr.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-calibr.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-calibr.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -20,8 +20,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-calibr.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains a gp calibration routine for * hardware dependent timeout functions. Index: drivers/char/ftape/lowlevel/ftape-ctl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-ctl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-ctl.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-ctl.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -18,8 +18,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-ctl.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the non-read/write ftape functions for the * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux. Index: drivers/char/ftape/lowlevel/ftape-ctl.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-ctl.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-ctl.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-ctl.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -21,8 +21,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-ctl.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the non-standard IOCTL related definitions * for the QIC-40/80/3010/3020 floppy-tape driver "ftape" for Index: drivers/char/ftape/lowlevel/ftape-ecc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-ecc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-ecc.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-ecc.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -23,8 +23,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-ecc.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the Reed-Solomon error correction code * for the QIC-40/80 floppy-tape driver for Linux. Index: drivers/char/ftape/lowlevel/ftape-ecc.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-ecc.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-ecc.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-ecc.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -24,8 +24,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-ecc.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the definitions for the * Reed-Solomon error correction code Index: drivers/char/ftape/lowlevel/ftape-format.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-format.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-format.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-format.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -17,8 +17,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-format.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the code to support formatting of floppy * tape cartridges with the QIC-40/80/3010/3020 floppy-tape Index: drivers/char/ftape/lowlevel/ftape-format.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-format.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-format.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-format.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -20,8 +20,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-format.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the low level definitions for the * formatting support for the QIC-40/80/3010/3020 floppy-tape Index: drivers/char/ftape/lowlevel/ftape-init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-init.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-init.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -57,8 +57,8 @@ /* Global vars. */ char ft_src[] __initdata = "$Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-init.c,v $"; -char ft_rev[] __initdata = "$Revision: 1.1 $"; -char ft_dat[] __initdata = "$Date: 2004/07/22 19:49:54 $"; +char ft_rev[] __initdata = "$Revision: 1.2 $"; +char ft_dat[] __initdata = "$Date: 2004/08/04 01:28:50 $"; /* Called by modules package when installing the driver Index: drivers/char/ftape/lowlevel/ftape-init.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-init.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-init.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-init.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -21,8 +21,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-init.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the definitions for the interface to * the Linux kernel for floppy tape driver ftape. Index: drivers/char/ftape/lowlevel/ftape-io.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-io.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-io.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-io.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -19,8 +19,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-io.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the general control functions for the * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux. Index: drivers/char/ftape/lowlevel/ftape-io.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-io.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-io.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-io.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -21,8 +21,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-io.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains definitions for the glue part of the * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux. Index: drivers/char/ftape/lowlevel/ftape-proc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-proc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-proc.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-proc.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -17,8 +17,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-proc.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the procfs interface for the * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux. Index: drivers/char/ftape/lowlevel/ftape-proc.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-proc.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-proc.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-proc.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -20,8 +20,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-proc.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains definitions for the procfs interface of the * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux. Index: drivers/char/ftape/lowlevel/ftape-read.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-read.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-read.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-read.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -18,8 +18,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-read.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the reading code * for the QIC-117 floppy-tape driver for Linux. Index: drivers/char/ftape/lowlevel/ftape-read.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-read.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-read.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-read.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -21,8 +21,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-read.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the definitions for the read functions * for the QIC-117 floppy-tape driver for Linux. Index: drivers/char/ftape/lowlevel/ftape-rw.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-rw.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-rw.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-rw.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -18,8 +18,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-rw.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains some common code for the segment read and * segment write routines for the QIC-117 floppy-tape driver for Index: drivers/char/ftape/lowlevel/ftape-rw.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-rw.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-rw.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-rw.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -21,8 +21,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-rw.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the definitions for the read and write * functions for the QIC-117 floppy-tape driver for Linux. Index: drivers/char/ftape/lowlevel/ftape-setup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-setup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-setup.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-setup.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -17,8 +17,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-setup.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the code for processing the kernel command * line options for the QIC-40/80/3010/3020 floppy-tape driver Index: drivers/char/ftape/lowlevel/ftape-tracing.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-tracing.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-tracing.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-tracing.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -18,8 +18,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-tracing.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the reading code * for the QIC-117 floppy-tape driver for Linux. Index: drivers/char/ftape/lowlevel/ftape-tracing.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-tracing.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-tracing.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-tracing.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -21,8 +21,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-tracing.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains definitions that eases the debugging of the * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux. Index: drivers/char/ftape/lowlevel/ftape-write.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-write.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-write.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-write.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -18,8 +18,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-write.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the writing code * for the QIC-117 floppy-tape driver for Linux. Index: drivers/char/ftape/lowlevel/ftape-write.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-write.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape-write.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape-write.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -23,8 +23,8 @@ $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape-write.h,v $ $Author: joff $ * - $Revision: 1.1 $ - $Date: 2004/07/22 19:49:54 $ + $Revision: 1.2 $ + $Date: 2004/08/04 01:28:50 $ $State: Exp $ * * This file contains the definitions for the write functions Index: drivers/char/ftape/lowlevel/ftape_syms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape_syms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape_syms.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape_syms.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -17,8 +17,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape_syms.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the symbols that the ftape low level * part of the QIC-40/80/3010/3020 floppy-tape driver "ftape" Index: drivers/char/ftape/lowlevel/ftape_syms.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape_syms.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/lowlevel/ftape_syms.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/lowlevel/ftape_syms.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -20,8 +20,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/lowlevel/ftape_syms.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the definitions needed to export symbols * from the QIC-40/80/3010/3020 floppy-tape driver "ftape" for Index: drivers/char/ftape/zftape/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/zftape/Makefile 22 Jul 2004 19:49:53 -0000 1.1 +++ drivers/char/ftape/zftape/Makefile 4 Aug 2004 01:28:50 -0000 1.2 @@ -16,8 +16,8 @@ # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. # # $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/Makefile,v $ -# $Revision: 1.1 $ -# $Date: 2004/07/22 19:49:53 $ +# $Revision: 1.2 $ +# $Date: 2004/08/04 01:28:50 $ # # Makefile for the QIC-40/80/3010/3020 zftape interface VFS to # ftape Index: drivers/char/ftape/zftape/zftape-buffers.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-buffers.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/zftape/zftape-buffers.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/zftape/zftape-buffers.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -17,8 +17,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-buffers.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the dynamic buffer allocation routines * of zftape Index: drivers/char/ftape/zftape/zftape-buffers.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-buffers.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/zftape/zftape-buffers.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/zftape/zftape-buffers.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -20,8 +20,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-buffers.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * memory allocation routines. * Index: drivers/char/ftape/zftape/zftape-ctl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-ctl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/zftape/zftape-ctl.c 22 Jul 2004 19:49:53 -0000 1.1 +++ drivers/char/ftape/zftape/zftape-ctl.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -17,8 +17,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-ctl.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:53 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the non-read/write zftape functions * for the QIC-40/80/3010/3020 floppy-tape driver for Linux. Index: drivers/char/ftape/zftape/zftape-ctl.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-ctl.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/zftape/zftape-ctl.h 22 Jul 2004 19:49:53 -0000 1.1 +++ drivers/char/ftape/zftape/zftape-ctl.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -20,8 +20,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-ctl.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:53 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the non-standard IOCTL related definitions * for the QIC-40/80 floppy-tape driver for Linux. Index: drivers/char/ftape/zftape/zftape-eof.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-eof.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/zftape/zftape-eof.c 22 Jul 2004 19:49:53 -0000 1.1 +++ drivers/char/ftape/zftape/zftape-eof.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -22,8 +22,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-eof.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:53 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the eof mark handling code * for the QIC-40/80 floppy-tape driver for Linux. Index: drivers/char/ftape/zftape/zftape-eof.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-eof.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/zftape/zftape-eof.h 22 Jul 2004 19:49:53 -0000 1.1 +++ drivers/char/ftape/zftape/zftape-eof.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -21,8 +21,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-eof.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:53 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * Definitions and declarations for the end of file markers * for the QIC-40/80 floppy-tape driver for Linux. Index: drivers/char/ftape/zftape/zftape-init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/zftape/zftape-init.c 22 Jul 2004 19:49:53 -0000 1.1 +++ drivers/char/ftape/zftape/zftape-init.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -49,8 +49,8 @@ #include "../zftape/zftape_syms.h" char zft_src[] __initdata = "$Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-init.c,v $"; -char zft_rev[] __initdata = "$Revision: 1.1 $"; -char zft_dat[] __initdata = "$Date: 2004/07/22 19:49:53 $"; +char zft_rev[] __initdata = "$Revision: 1.2 $"; +char zft_dat[] __initdata = "$Date: 2004/08/04 01:28:50 $"; MODULE_AUTHOR("(c) 1996, 1997 Claus-Justus Heine " "(claus@momo.math.rwth-aachen.de)"); Index: drivers/char/ftape/zftape/zftape-init.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-init.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/zftape/zftape-init.h 22 Jul 2004 19:49:53 -0000 1.1 +++ drivers/char/ftape/zftape/zftape-init.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -20,8 +20,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-init.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:53 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains definitions and macro for the vfs * interface defined by zftape Index: drivers/char/ftape/zftape/zftape-read.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-read.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/zftape/zftape-read.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/zftape/zftape-read.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -17,8 +17,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-read.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the high level reading code * for the QIC-117 floppy-tape driver for Linux. Index: drivers/char/ftape/zftape/zftape-read.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-read.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/zftape/zftape-read.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/zftape/zftape-read.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -20,8 +20,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-read.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the definitions for the read functions * for the zftape driver for Linux. Index: drivers/char/ftape/zftape/zftape-rw.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-rw.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/zftape/zftape-rw.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/zftape/zftape-rw.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -17,8 +17,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-rw.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains some common code for the r/w code for * zftape. Index: drivers/char/ftape/zftape/zftape-rw.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-rw.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/zftape/zftape-rw.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/zftape/zftape-rw.h 4 Aug 2004 01:28:50 -0000 1.2 @@ -20,8 +20,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-rw.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file contains the definitions for the read and write * functions for the QIC-117 floppy-tape driver for Linux. Index: drivers/char/ftape/zftape/zftape-vtbl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-vtbl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/zftape/zftape-vtbl.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/zftape/zftape-vtbl.c 4 Aug 2004 01:28:50 -0000 1.2 @@ -18,8 +18,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-vtbl.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:50 $ * * This file defines a volume table as defined in various QIC * standards. Index: drivers/char/ftape/zftape/zftape-vtbl.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-vtbl.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/zftape/zftape-vtbl.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/zftape/zftape-vtbl.h 4 Aug 2004 01:28:51 -0000 1.2 @@ -21,8 +21,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-vtbl.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:51 $ * * This file defines a volume table as defined in the QIC-80 * development standards. Index: drivers/char/ftape/zftape/zftape-write.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-write.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/zftape/zftape-write.c 22 Jul 2004 19:49:53 -0000 1.1 +++ drivers/char/ftape/zftape/zftape-write.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -17,8 +17,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-write.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:53 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:51 $ * * This file contains the writing code * for the QIC-117 floppy-tape driver for Linux. Index: drivers/char/ftape/zftape/zftape-write.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-write.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/zftape/zftape-write.h 22 Jul 2004 19:49:53 -0000 1.1 +++ drivers/char/ftape/zftape/zftape-write.h 4 Aug 2004 01:28:51 -0000 1.2 @@ -20,8 +20,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape-write.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:53 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:51 $ * * This file contains the definitions for the write functions * for the zftape driver for Linux. Index: drivers/char/ftape/zftape/zftape_syms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape_syms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/zftape/zftape_syms.c 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/zftape/zftape_syms.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -17,8 +17,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape_syms.c,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:51 $ * * This file contains the symbols that the zftape frontend to * the ftape floppy tape driver exports Index: drivers/char/ftape/zftape/zftape_syms.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape_syms.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ftape/zftape/zftape_syms.h 22 Jul 2004 19:49:54 -0000 1.1 +++ drivers/char/ftape/zftape/zftape_syms.h 4 Aug 2004 01:28:51 -0000 1.2 @@ -20,8 +20,8 @@ * * $Source: /cvsroot/ts-7200/dist/linux24/drivers/char/ftape/zftape/zftape_syms.h,v $ - * $Revision: 1.1 $ - * $Date: 2004/07/22 19:49:54 $ + * $Revision: 1.2 $ + * $Date: 2004/08/04 01:28:51 $ * * This file contains the definitions needed for the symbols * ftape exports Index: drivers/char/ipmi/ipmi_kcs_intf.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/ipmi/ipmi_kcs_intf.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/ipmi/ipmi_kcs_intf.c 22 Jul 2004 19:49:53 -0000 1.1 +++ drivers/char/ipmi/ipmi_kcs_intf.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -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, Index: drivers/char/joystick/a3d.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/a3d.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/a3d.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/a3d.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: a3d.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: a3d.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1998-2001 Vojtech Pavlik * Index: drivers/char/joystick/adi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/adi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/adi.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/adi.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: adi.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: adi.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1998-2000 Vojtech Pavlik * Index: drivers/char/joystick/amijoy.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/amijoy.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/amijoy.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/amijoy.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: amijoy.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: amijoy.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1998-2000 Vojtech Pavlik * Index: drivers/char/joystick/analog.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/analog.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/analog.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/analog.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: analog.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: analog.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1996-2000 Vojtech Pavlik * Index: drivers/char/joystick/cobra.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/cobra.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/cobra.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/cobra.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: cobra.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: cobra.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1999-2000 Vojtech Pavlik * Index: drivers/char/joystick/db9.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/db9.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/db9.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/db9.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: db9.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: db9.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1999 Vojtech Pavlik * Index: drivers/char/joystick/emu10k1-gp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/emu10k1-gp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/emu10k1-gp.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/emu10k1-gp.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: emu10k1-gp.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: emu10k1-gp.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 2001 Vojtech Pavlik * Index: drivers/char/joystick/gamecon.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/gamecon.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/gamecon.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/gamecon.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: gamecon.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: gamecon.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1999-2001 Vojtech Pavlik * Index: drivers/char/joystick/gameport.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/gameport.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/gameport.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/gameport.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: gameport.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: gameport.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1999-2000 Vojtech Pavlik * Index: drivers/char/joystick/gf2k.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/gf2k.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/gf2k.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/gf2k.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: gf2k.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: gf2k.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1998-2000 Vojtech Pavlik * Index: drivers/char/joystick/grip.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/grip.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/grip.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/grip.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: grip.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: grip.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1998-2000 Vojtech Pavlik * Index: drivers/char/joystick/iforce.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/iforce.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/iforce.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/iforce.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: iforce.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: iforce.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 2000-2001 Vojtech Pavlik * Copyright (c) 2001 Johann Deneux Index: drivers/char/joystick/interact.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/interact.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/interact.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/interact.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: interact.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: interact.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 2000 Vojtech Pavlik * Index: drivers/char/joystick/lightning.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/lightning.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/lightning.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/lightning.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: lightning.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: lightning.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1998-2001 Vojtech Pavlik * Index: drivers/char/joystick/magellan.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/magellan.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/magellan.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/magellan.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: magellan.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: magellan.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1999-2000 Vojtech Pavlik * Index: drivers/char/joystick/ns558.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/ns558.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/ns558.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/ns558.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: ns558.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: ns558.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1999-2001 Vojtech Pavlik * Copyright (c) 1999 Brian Gerst Index: drivers/char/joystick/pcigame.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/pcigame.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/pcigame.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/pcigame.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: pcigame.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: pcigame.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 2000-2001 Vojtech Pavlik * Index: drivers/char/joystick/serio.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/serio.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/serio.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/serio.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: serio.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: serio.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1999-2000 Vojtech Pavlik * Index: drivers/char/joystick/serport.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/serport.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/serport.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/serport.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: serport.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: serport.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1999-2001 Vojtech Pavlik * Index: drivers/char/joystick/sidewinder.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/sidewinder.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/sidewinder.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/sidewinder.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: sidewinder.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: sidewinder.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1998-2001 Vojtech Pavlik * Index: drivers/char/joystick/spaceball.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/spaceball.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/spaceball.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/spaceball.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: spaceball.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: spaceball.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1999-2000 Vojtech Pavlik * Index: drivers/char/joystick/spaceorb.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/spaceorb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/spaceorb.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/spaceorb.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: spaceorb.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: spaceorb.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1999-2000 Vojtech Pavlik * Index: drivers/char/joystick/stinger.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/stinger.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/stinger.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/stinger.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: stinger.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: stinger.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 2000-2001 Vojtech Pavlik * Copyright (c) 2000 Mark Fletcher Index: drivers/char/joystick/tmdc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/tmdc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/tmdc.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/tmdc.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: tmdc.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: tmdc.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1998-2000 Vojtech Pavlik * Index: drivers/char/joystick/turbografx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/turbografx.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/turbografx.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/turbografx.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: turbografx.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: turbografx.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1998-2000 Vojtech Pavlik * Index: drivers/char/joystick/warrior.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/joystick/warrior.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/joystick/warrior.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/joystick/warrior.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: warrior.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: warrior.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Copyright (c) 1999-2000 Vojtech Pavlik * Index: drivers/char/pcmcia/serial_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/pcmcia/serial_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/pcmcia/serial_cs.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/pcmcia/serial_cs.c 20 Oct 2004 22:34:38 -0000 1.2 @@ -337,7 +337,7 @@ link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = (try == 0) ? - 16 : cf->io.flags & CISTPL_IO_LINES_MASK; + 10 : cf->io.flags & CISTPL_IO_LINES_MASK; i = CardServices(RequestIO, link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } Index: drivers/char/pcmcia/synclink_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/pcmcia/synclink_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/pcmcia/synclink_cs.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/char/pcmcia/synclink_cs.c 4 Aug 2004 01:28:51 -0000 1.2 @@ -1,7 +1,7 @@ /* * linux/drivers/char/synclink_cs.c * - * $Id: synclink_cs.c,v 1.1 2004/07/22 19:49:55 joff Exp $ + * $Id: synclink_cs.c,v 1.2 2004/08/04 01:28:51 joff Exp $ * * Device driver for Microgate SyncLink PC Card * multiprotocol serial adapter. @@ -483,6 +483,7 @@ static int debug_level = 0; static int maxframe[MAX_DEVICE_COUNT] = {0,}; +static int dosyncppp[MAX_DEVICE_COUNT] = {1,1,1,1}; /* The old way: bit map of interrupts to choose from */ /* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */ @@ -499,9 +500,14 @@ MODULE_PARM(cuamajor,"i"); MODULE_PARM(debug_level,"i"); MODULE_PARM(maxframe,"1-" __MODULE_STRING(MAX_DEVICE_COUNT) "i"); +MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_DEVICE_COUNT) "i"); + +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif static char *driver_name = "SyncLink PC Card driver"; -static char *driver_version = "$Revision: 1.1 $"; +static char *driver_version = "$Revision: 1.2 $"; static struct tty_driver serial_driver, callout_driver; static int serial_refcount; @@ -871,6 +877,9 @@ printk(badmagic, kdevname(device), routine); return 1; } +#else + if (!info) + return 1; #endif return 0; } @@ -2616,14 +2625,17 @@ { MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data; - if (!info || mgslpc_paranoia_check(info, tty->device, "mgslpc_close")) + if (mgslpc_paranoia_check(info, tty->device, "mgslpc_close")) return; if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):mgslpc_close(%s) entry, count=%d\n", __FILE__,__LINE__, info->device_name, info->count); - if (!info->count || tty_hung_up_p(filp)) + if (!info->count) + return; + + if (tty_hung_up_p(filp)) goto cleanup; if ((tty->count == 1) && (info->count != 1)) { @@ -2747,7 +2759,7 @@ schedule_timeout(char_time); if (signal_pending(current)) break; - if (timeout && ((orig_jiffies + timeout) < jiffies)) + if (timeout && time_after(jiffies, orig_jiffies + timeout)) break; } } else { @@ -2757,7 +2769,7 @@ schedule_timeout(char_time); if (signal_pending(current)) break; - if (timeout && ((orig_jiffies + timeout) < jiffies)) + if (timeout && time_after(jiffies, orig_jiffies + timeout)) break; } } @@ -2937,16 +2949,11 @@ info = mgslpc_device_list; while(info && info->line != line) info = info->next_device; - if ( !info ){ - printk("%s(%d):Can't find specified device on open (line=%d)\n", - __FILE__,__LINE__,line); + if (mgslpc_paranoia_check(info, tty->device, "mgslpc_open")) return -ENODEV; - } tty->driver_data = info; info->tty = tty; - if (mgslpc_paranoia_check(info, tty->device, "mgslpc_open")) - return -ENODEV; if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):mgslpc_open(%s), old ref count = %d\n", @@ -3008,6 +3015,8 @@ cleanup: if (retval) { + if (tty->count == 1) + info->tty = 0; /* tty layer will release tty struct */ if(MOD_IN_USE) MOD_DEC_USE_COUNT; if(info->count) @@ -3181,8 +3190,7 @@ if (info->line < MAX_DEVICE_COUNT) { if (maxframe[info->line]) info->max_frame_size = maxframe[info->line]; -// info->dosyncppp = dosyncppp[info->line]; - info->dosyncppp = 1; + info->dosyncppp = dosyncppp[info->line]; } mgslpc_device_count++; Index: drivers/char/rio/rio_linux.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/char/rio/rio_linux.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/char/rio/rio_linux.c 22 Jul 2004 19:49:53 -0000 1.1 +++ drivers/char/rio/rio_linux.c 4 Aug 2004 01:28:52 -0000 1.2 @@ -27,8 +27,8 @@ * * Revision history: * $Log: rio_linux.c,v $ - * Revision 1.1 2004/07/22 19:49:53 joff - * Initial revision + * Revision 1.2 2004/08/04 01:28:52 joff + * merging 2.4.26-vrs1 * * Revision 1.1 1999/07/11 10:13:54 wolff * Initial revision @@ -36,8 +36,8 @@ * */ -#define RCS_ID "$Id: rio_linux.c,v 1.1 2004/07/22 19:49:53 joff Exp $" -#define RCS_REV "$Revision: 1.1 $" +#define RCS_ID "$Id: rio_linux.c,v 1.2 2004/08/04 01:28:52 joff Exp $" +#define RCS_REV "$Revision: 1.2 $" #include Index: drivers/cpufreq/userspace.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/cpufreq/userspace.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/cpufreq/userspace.c 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/cpufreq/userspace.c 4 Aug 2004 01:28:52 -0000 1.2 @@ -4,7 +4,7 @@ * Copyright (C) 2001 Russell King * (C) 2002 - 2003 Dominik Brodowski * - * $Id: userspace.c,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: userspace.c,v 1.2 2004/08/04 01:28:52 joff 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 Index: drivers/gsc/dino.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/gsc/dino.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/gsc/dino.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/gsc/dino.c 4 Aug 2004 01:28:52 -0000 1.2 @@ -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 Index: drivers/hil/hp_sdc_rtc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hil/hp_sdc_rtc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hil/hp_sdc_rtc.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/hil/hp_sdc_rtc.c 4 Aug 2004 01:28:52 -0000 1.2 @@ -561,6 +561,7 @@ } case RTC_ALM_READ: /* Read the present alarm time */ { + memset(&ttime, 0, sizeof(struct timeval)); if (hp_sdc_rtc_read_mt(&ttime)) return -EFAULT; break; } @@ -609,6 +610,7 @@ } case RTC_RD_TIME: /* Read the time/date from RTC */ { + memset(&wtime, 0, sizeof(struct rtc_time)); if (hp_sdc_rtc_read_bbrtc(&wtime)) return -EFAULT; break; } Index: drivers/hotplug/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/Config.in 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/Config.in 4 Aug 2004 01:28:52 -0000 1.2 @@ -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" = "y" ]; then + dep_tristate ' ACPI PCI Hotplug driver' CONFIG_HOTPLUG_PCI_ACPI $CONFIG_HOTPLUG_PCI +fi endmenu Index: drivers/hotplug/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/Makefile 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/Makefile 4 Aug 2004 01:28:52 -0000 1.2 @@ -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 \ Index: drivers/hotplug/acpiphp.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/acpiphp.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/acpiphp.h 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/acpiphp.h 4 Aug 2004 01:28:52 -0000 1.2 @@ -1,12 +1,12 @@ /* * ACPI PCI Hot Plug Controller Driver * - * Copyright (c) 1995,2001 Compaq Computer Corporation - * 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) 1995,2001 Compaq Computer Corporation + * 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,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 */ Index: drivers/hotplug/acpiphp_core.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/acpiphp_core.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/acpiphp_core.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/acpiphp_core.c 4 Aug 2004 01:28:52 -0000 1.2 @@ -1,12 +1,12 @@ /* * ACPI PCI Hot Plug Controller Driver * - * Copyright (c) 1995,2001 Compaq Computer Corporation - * 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) 1995,2001 Compaq Computer Corporation + * 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,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); } /** Index: drivers/hotplug/acpiphp_glue.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/acpiphp_glue.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/acpiphp_glue.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/acpiphp_glue.c 4 Aug 2004 01:28:52 -0000 1.2 @@ -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 Hiroshi Aono (h-aono@ap.jp.nec.com) - * Copyright (c) 2002 NEC Corporation + * 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,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 Index: drivers/hotplug/acpiphp_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/acpiphp_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/acpiphp_pci.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/acpiphp_pci.c 4 Aug 2004 01:28:52 -0000 1.2 @@ -1,12 +1,12 @@ /* * ACPI PCI HotPlug PCI configuration space management * - * 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 Hiroshi Aono (h-aono@ap.jp.nec.com) - * Copyright (c) 2002 NEC Corporation + * 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-kochi@bq.jp.nec.com) + * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.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 * */ Index: drivers/hotplug/acpiphp_res.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/acpiphp_res.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/acpiphp_res.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/acpiphp_res.c 4 Aug 2004 01:28:52 -0000 1.2 @@ -1,12 +1,12 @@ /* * ACPI PCI HotPlug Utility functions * - * Copyright (c) 1995,2001 Compaq Computer Corporation - * 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) 1995,2001 Compaq Computer Corporation + * 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-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 , * */ Index: drivers/hotplug/cpqphp.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/cpqphp.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/cpqphp.h 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/cpqphp.h 4 Aug 2004 01:28:52 -0000 1.2 @@ -1,9 +1,9 @@ /* * Compaq Hot Plug Controller Driver * - * Copyright (c) 1995,2001 Compaq Computer Corporation - * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2001 IBM + * Copyright (C) 1995,2001 Compaq Computer Corporation + * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001 IBM * * All rights reserved. * @@ -747,7 +747,7 @@ return 1; hp_slot = slot->device - ctrl->slot_device_offset; - dbg(__FUNCTION__": slot->device = %d, ctrl->slot_device_offset = %d \n", slot->device, ctrl->slot_device_offset); + dbg("%s: slot->device = %d, ctrl->slot_device_offset = %d \n", __FUNCTION__, slot->device, ctrl->slot_device_offset); status = (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot)); @@ -785,7 +785,7 @@ DECLARE_WAITQUEUE(wait, current); int retval = 0; - dbg(__FUNCTION__" - start\n"); + dbg("%s - start\n", __FUNCTION__); add_wait_queue(&ctrl->queue, &wait); set_current_state(TASK_INTERRUPTIBLE); /* Sleep for up to 1 second to wait for the LED to change. */ @@ -795,7 +795,7 @@ if (signal_pending(current)) retval = -EINTR; - dbg(__FUNCTION__" - end\n"); + dbg("%s - end\n", __FUNCTION__); return retval; } Index: drivers/hotplug/cpqphp_core.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/cpqphp_core.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/cpqphp_core.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/cpqphp_core.c 4 Aug 2004 01:28:52 -0000 1.2 @@ -1,9 +1,9 @@ /* * Compaq Hot Plug Controller Driver * - * Copyright (c) 1995,2001 Compaq Computer Corporation - * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2001 IBM Corp. + * Copyright (C) 1995,2001 Compaq Computer Corporation + * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001 IBM Corp. * * All rights reserved. * @@ -320,7 +320,7 @@ void *slot_entry= NULL; int result; - dbg(__FUNCTION__"\n"); + dbg("%s\n", __FUNCTION__); tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR); @@ -482,7 +482,7 @@ u8 tbus, tdevice, tslot, bridgeSlot; - dbg(__FUNCTION__" %p, %d, %d, %p\n", ops, bus_num, dev_num, slot); + dbg("%s %p, %d, %d, %p\n", __FUNCTION__, ops, bus_num, dev_num, slot); bridgeSlot = 0xFF; @@ -598,7 +598,7 @@ if (slot == NULL) return -ENODEV; - dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); ctrl = slot->ctrl; if (ctrl == NULL) @@ -633,7 +633,7 @@ if (slot == NULL) return -ENODEV; - dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); ctrl = slot->ctrl; if (ctrl == NULL) @@ -673,7 +673,7 @@ if (slot == NULL) return -ENODEV; - dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); ctrl = slot->ctrl; if (ctrl == NULL) @@ -701,7 +701,7 @@ struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); struct controller *ctrl; - dbg(__FUNCTION__"\n"); + dbg("%s\n", __FUNCTION__); if (slot == NULL) return -ENODEV; @@ -722,7 +722,7 @@ if (slot == NULL) return -ENODEV; - dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); ctrl = slot->ctrl; if (ctrl == NULL) @@ -740,7 +740,7 @@ if (slot == NULL) return -ENODEV; - dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); ctrl = slot->ctrl; if (ctrl == NULL) @@ -758,7 +758,7 @@ if (slot == NULL) return -ENODEV; - dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); ctrl = slot->ctrl; if (ctrl == NULL) @@ -777,7 +777,7 @@ if (slot == NULL) return -ENODEV; - dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); ctrl = slot->ctrl; if (ctrl == NULL) @@ -865,7 +865,7 @@ // TODO: This code can be made to support non-Compaq or Intel subsystem IDs rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid); if (rc) { - err(__FUNCTION__" : pci_read_config_word failed\n"); + err("%s : pci_read_config_word failed\n", __FUNCTION__); return rc; } dbg("Subsystem Vendor ID: %x\n", subsystem_vid); @@ -876,14 +876,14 @@ ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL); if (!ctrl) { - err(__FUNCTION__" : out of memory\n"); + err("%s : out of memory\n", __FUNCTION__); return -ENOMEM; } memset(ctrl, 0, sizeof(struct controller)); rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid); if (rc) { - err(__FUNCTION__" : pci_read_config_word failed\n"); + err("%s : pci_read_config_word failed\n", __FUNCTION__); goto err_free_ctrl; } @@ -1139,7 +1139,7 @@ // Store PCI Config Space for all devices on this bus rc = cpqhp_save_config(ctrl, ctrl->bus, readb(ctrl->hpc_reg + SLOT_MASK)); if (rc) { - err(__FUNCTION__": unable to save PCI configuration data, error %d\n", rc); + err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc); goto err_iounmap; } @@ -1169,7 +1169,7 @@ rc = ctrl_slot_setup(ctrl, smbios_start, smbios_table); if (rc) { err(msg_initialization_err, 6); - err(__FUNCTION__": unable to save PCI configuration data, error %d\n", rc); + err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc); goto err_iounmap; } Index: drivers/hotplug/cpqphp_ctrl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/cpqphp_ctrl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/cpqphp_ctrl.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/cpqphp_ctrl.c 4 Aug 2004 01:28:52 -0000 1.2 @@ -1,9 +1,9 @@ /* * Compaq Hot Plug Controller Driver * - * Copyright (c) 1995,2001 Compaq Computer Corporation - * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2001 IBM Corp. + * Copyright (C) 1995,2001 Compaq Computer Corporation + * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001 IBM Corp. * * All rights reserved. * @@ -771,13 +771,13 @@ return(NULL); for (node = *head; node; node = node->next) { - dbg(__FUNCTION__": req_size =%x node=%p, base=%x, length=%x\n", - size, node, node->base, node->length); + dbg("%s: req_size =%x node=%p, base=%x, length=%x\n", + __FUNCTION__, size, node, node->base, node->length); if (node->length < size) continue; if (node->base & (size - 1)) { - dbg(__FUNCTION__": not aligned\n"); + dbg("%s: not aligned\n", __FUNCTION__); // this one isn't base aligned properly // so we'll make a new entry and split it up temp_dword = (node->base | (size-1)) + 1; @@ -803,7 +803,7 @@ // Don't need to check if too small since we already did if (node->length > size) { - dbg(__FUNCTION__": too big\n"); + dbg("%s: too big\n", __FUNCTION__); // this one is longer than we need // so we'll make a new entry and split it up split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); @@ -820,7 +820,7 @@ node->next = split_node; } // End of too big on top end - dbg(__FUNCTION__": got one!!!\n"); + dbg("%s: got one!!!\n", __FUNCTION__); // If we got here, then it is the right size // Now take it out of the list if (*head == node) { @@ -855,7 +855,7 @@ struct pci_resource *node2; int out_of_order = 1; - dbg(__FUNCTION__": head = %p, *head = %p\n", head, *head); + dbg("%s: head = %p, *head = %p\n",__FUNCTION__, head, *head); if (!(*head)) return(1); @@ -942,7 +942,7 @@ // Read to clear posted writes misc = readw(ctrl->hpc_reg + MISC); - dbg (__FUNCTION__" - waking up\n"); + dbg ("%s - waking up\n", __FUNCTION__); wake_up_interruptible(&ctrl->queue); } @@ -1394,8 +1394,8 @@ struct resource_lists res_lists; hp_slot = func->device - ctrl->slot_device_offset; - dbg(__FUNCTION__": func->device, slot_offset, hp_slot = %d, %d ,%d\n", - func->device, ctrl->slot_device_offset, hp_slot); + dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n", + __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot); // Wait for exclusive access to hardware down(&ctrl->crit_sect); @@ -1444,55 +1444,55 @@ // turn on board and blink green LED // Wait for exclusive access to hardware - dbg(__FUNCTION__": before down\n"); + dbg("%s: before down\n", __FUNCTION__); down(&ctrl->crit_sect); - dbg(__FUNCTION__": after down\n"); + dbg("%s: after down\n", __FUNCTION__); - dbg(__FUNCTION__": before slot_enable\n"); + dbg("%s: before slot_enable\n", __FUNCTION__); slot_enable (ctrl, hp_slot); - dbg(__FUNCTION__": before green_LED_blink\n"); + dbg("%s: before green_LED_blink\n", __FUNCTION__); green_LED_blink (ctrl, hp_slot); - dbg(__FUNCTION__": before amber_LED_blink\n"); + dbg("%s: before amber_LED_blink\n", __FUNCTION__); amber_LED_off (ctrl, hp_slot); - dbg(__FUNCTION__": before set_SOGO\n"); + dbg("%s: before set_SOGO\n", __FUNCTION__); set_SOGO(ctrl); // Wait for SOBS to be unset - dbg(__FUNCTION__": before wait_for_ctrl_irq\n"); + dbg("%s: before wait_for_ctrl_irq\n", __FUNCTION__); wait_for_ctrl_irq (ctrl); - dbg(__FUNCTION__": after wait_for_ctrl_irq\n"); + dbg("%s: after wait_for_ctrl_irq\n", __FUNCTION__); // Done with exclusive hardware access - dbg(__FUNCTION__": before up\n"); + dbg("%s: before up\n", __FUNCTION__); up(&ctrl->crit_sect); - dbg(__FUNCTION__": after up\n"); + dbg("%s: after up\n", __FUNCTION__); // Wait for ~1 second because of hot plug spec - dbg(__FUNCTION__": before long_delay\n"); + dbg("%s: before long_delay\n", __FUNCTION__); long_delay(1*HZ); - dbg(__FUNCTION__": after long_delay\n"); + dbg("%s: after long_delay\n", __FUNCTION__); - dbg(__FUNCTION__": func status = %x\n", func->status); + dbg("%s: func status = %x\n", __FUNCTION__, func->status); // Check for a power fault if (func->status == 0xFF) { // power fault occurred, but it was benign temp_register = 0xFFFFFFFF; - dbg(__FUNCTION__": temp register set to %x by power fault\n", temp_register); + dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register); rc = POWER_FAILURE; func->status = 0; } else { // Get vendor/device ID u32 rc = pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_VENDOR_ID, &temp_register); - dbg(__FUNCTION__": pci_read_config_dword returns %d\n", rc); - dbg(__FUNCTION__": temp_register is %x\n", temp_register); + dbg("%s: pci_read_config_dword returns %d\n", __FUNCTION__, rc); + dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register); if (rc != 0) { // Something's wrong here temp_register = 0xFFFFFFFF; - dbg(__FUNCTION__": temp register set to %x by error\n", temp_register); + dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register); } // Preset return code. It will be changed later if things go okay. rc = NO_ADAPTER_PRESENT; @@ -1508,7 +1508,7 @@ rc = configure_new_device(ctrl, func, 0, &res_lists); - dbg(__FUNCTION__": back from configure_new_device\n"); + dbg("%s: back from configure_new_device\n", __FUNCTION__); ctrl->io_head = res_lists.io_head; ctrl->mem_head = res_lists.mem_head; ctrl->p_mem_head = res_lists.p_mem_head; @@ -1545,7 +1545,7 @@ func->is_a_board = 0x01; //next, we will instantiate the linux pci_dev structures (with appropriate driver notification, if already present) - dbg(__FUNCTION__": configure linux pci_dev structure\n"); + dbg("%s: configure linux pci_dev structure\n", __FUNCTION__); index = 0; do { new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++); @@ -1612,7 +1612,7 @@ device = func->device; hp_slot = func->device - ctrl->slot_device_offset; - dbg("In "__FUNCTION__", hp_slot = %d\n", hp_slot); + dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); // When we get here, it is safe to change base Address Registers. // We will attempt to save the base Address Register Lengths @@ -1942,7 +1942,7 @@ func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0); dbg("In power_down_board, func = %p, ctrl = %p\n", func, ctrl); if (!func) { - dbg("Error! func NULL in "__FUNCTION__"\n"); + dbg("Error! func NULL in %s\n", __FUNCTION__); return ; } @@ -1966,7 +1966,7 @@ func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0); dbg("In add_board, func = %p, ctrl = %p\n", func, ctrl); if (!func) { - dbg("Error! func NULL in "__FUNCTION__"\n"); + dbg("Error! func NULL in %s\n", __FUNCTION__); return ; } @@ -2081,7 +2081,7 @@ } if (rc) { - dbg(__FUNCTION__": rc = %d\n", rc); + dbg("%s: rc = %d\n", __FUNCTION__, rc); } if (p_slot) @@ -2347,11 +2347,11 @@ new_slot = func; - dbg(__FUNCTION__"\n"); + dbg("%s\n", __FUNCTION__); // Check for Multi-function device rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, 0x0E, &temp_byte); if (rc) { - dbg(__FUNCTION__": rc = %d\n", rc); + dbg("%s: rc = %d\n", __FUNCTION__, rc); return rc; } Index: drivers/hotplug/cpqphp_nvram.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/cpqphp_nvram.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/cpqphp_nvram.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/cpqphp_nvram.c 4 Aug 2004 01:28:52 -0000 1.2 @@ -1,9 +1,9 @@ /* * Compaq Hot Plug Controller Driver * - * Copyright (c) 1995,2001 Compaq Computer Corporation - * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2001 IBM Corp. + * Copyright (C) 1995,2001 Compaq Computer Corporation + * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001 IBM Corp. * * All rights reserved. * @@ -160,7 +160,7 @@ (temp6 == 'Q')) { result = 1; } - dbg (__FUNCTION__" - returned %d\n", result); + dbg ("%s - returned %d\n",__FUNCTION__, result); return result; } Index: drivers/hotplug/cpqphp_nvram.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/cpqphp_nvram.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/cpqphp_nvram.h 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/cpqphp_nvram.h 4 Aug 2004 01:28:52 -0000 1.2 @@ -1,8 +1,8 @@ /* * Compaq Hot Plug Controller Driver * - * Copyright (c) 1995,2001 Compaq Computer Corporation - * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 1995,2001 Compaq Computer Corporation + * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) * * All rights reserved. * Index: drivers/hotplug/cpqphp_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/cpqphp_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/cpqphp_pci.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/cpqphp_pci.c 4 Aug 2004 01:28:52 -0000 1.2 @@ -1,9 +1,9 @@ /* * Compaq Hot Plug Controller Driver * - * Copyright (c) 1995,2001 Compaq Computer Corporation - * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2001 IBM Corp. + * Copyright (C) 1995,2001 Compaq Computer Corporation + * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001 IBM Corp. * * All rights reserved. * @@ -139,7 +139,7 @@ //We did not even find a hotplug rep of the function, create it //This code might be taken out if we can guarantee the creation of functions //in parallel (hotplug and Linux at the same time). - dbg("@@@@@@@@@@@ cpqhp_slot_create in "__FUNCTION__"\n"); + dbg("@@@@@@@@@@@ cpqhp_slot_create in %s\n", __FUNCTION__); temp_func = cpqhp_slot_create(bus->number); if (temp_func == NULL) return -ENOMEM; @@ -306,7 +306,7 @@ memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped)); memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped)); - dbg(__FUNCTION__": bus/dev/func = %x/%x/%x\n",func->bus, func->device, func->function); + dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus, func->device, func->function); for (j=0; j<8 ; j++) { struct pci_dev* temp = pci_find_slot(func->bus, (func->device << 3) | j); @@ -354,10 +354,10 @@ fakedev.devfn = dev_num << 3; fakedev.bus = &fakebus; fakebus.number = bus_num; - dbg(__FUNCTION__": dev %d, bus %d, pin %d, num %d\n", - dev_num, bus_num, int_pin, irq_num); + dbg("%s: dev %d, bus %d, pin %d, num %d\n", + __FUNCTION__, dev_num, bus_num, int_pin, irq_num); rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num); - dbg(__FUNCTION__":rc %d\n", rc); + dbg("%s:rc %d\n", __FUNCTION__, rc); if (!rc) return !rc; @@ -1585,7 +1585,7 @@ int rc = 0; struct pci_resource *node; struct pci_resource *t_node; - dbg(__FUNCTION__"\n"); + dbg("%s\n", __FUNCTION__); if (!func) return(1); Index: drivers/hotplug/cpqphp_proc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/cpqphp_proc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/cpqphp_proc.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/cpqphp_proc.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -1,9 +1,9 @@ /* * Compaq Hot Plug Controller Driver * - * Copyright (c) 1995,2001 Compaq Computer Corporation - * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2001 IBM Corp. + * Copyright (C) 1995,2001 Compaq Computer Corporation + * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001 IBM Corp. * * All rights reserved. * Index: drivers/hotplug/ibmphp.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/ibmphp.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/ibmphp.h 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/ibmphp.h 4 Aug 2004 01:28:53 -0000 1.2 @@ -6,8 +6,8 @@ * * Written By: Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation * - * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2001,2002 IBM Corp. + * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001,2002 IBM Corp. * * All rights reserved. * Index: drivers/hotplug/ibmphp_core.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/ibmphp_core.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/ibmphp_core.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/ibmphp_core.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -3,8 +3,8 @@ * * Written By: Chuck Cole, Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation * - * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2001,2002 IBM Corp. + * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001,2002 IBM Corp. * * All rights reserved. * Index: drivers/hotplug/ibmphp_ebda.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/ibmphp_ebda.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/ibmphp_ebda.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/ibmphp_ebda.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -3,8 +3,8 @@ * * Written By: Tong Yu, IBM Corporation * - * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2001,2002 IBM Corp. + * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001,2002 IBM Corp. * * All rights reserved. * @@ -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; Index: drivers/hotplug/ibmphp_hpc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/ibmphp_hpc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/ibmphp_hpc.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/ibmphp_hpc.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -3,7 +3,7 @@ * * Written By: Jyoti Shah, IBM Corporation * - * Copyright (c) 2001-2002 IBM Corp. + * Copyright (C) 2001-2002 IBM Corp. * * All rights reserved. * Index: drivers/hotplug/ibmphp_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/ibmphp_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/ibmphp_pci.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/ibmphp_pci.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -3,8 +3,8 @@ * * Written By: Irene Zubarev, IBM Corporation * - * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2001,2002 IBM Corp. + * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001,2002 IBM Corp. * * All rights reserved. * Index: drivers/hotplug/ibmphp_res.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/ibmphp_res.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/ibmphp_res.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/ibmphp_res.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -3,8 +3,8 @@ * * Written By: Irene Zubarev, IBM Corporation * - * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2001,2002 IBM Corp. + * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001,2002 IBM Corp. * * All rights reserved. * Index: drivers/hotplug/pci_hotplug.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/pci_hotplug.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/pci_hotplug.h 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/pci_hotplug.h 4 Aug 2004 01:28:53 -0000 1.2 @@ -1,9 +1,9 @@ /* * PCI HotPlug Core Functions * - * Copyright (c) 1995,2001 Compaq Computer Corporation - * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2001 IBM Corp. + * Copyright (C) 1995,2001 Compaq Computer Corporation + * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001 IBM Corp. * * All rights reserved. * Index: drivers/hotplug/pci_hotplug_core.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/pci_hotplug_core.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/pci_hotplug_core.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/pci_hotplug_core.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -1,8 +1,8 @@ /* * PCI HotPlug Controller Core * - * Copyright (c) 2001-2002 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2001-2002 IBM Corp. + * Copyright (C) 2001-2002 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001-2002 IBM Corp. * * All rights reserved. * @@ -49,7 +49,7 @@ #define MY_NAME THIS_MODULE->name #endif -#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: "__FUNCTION__": " fmt , MY_NAME , ## arg); } while (0) +#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __FUNCTION__ , ## arg); } while (0) #define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg) #define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg) #define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg) Index: drivers/hotplug/pci_hotplug_util.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/hotplug/pci_hotplug_util.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/hotplug/pci_hotplug_util.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/hotplug/pci_hotplug_util.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -1,9 +1,9 @@ /* * PCI HotPlug Utility functions * - * Copyright (c) 1995,2001 Compaq Computer Corporation - * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2001 IBM Corp. + * Copyright (C) 1995,2001 Compaq Computer Corporation + * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001 IBM Corp. * * All rights reserved. * @@ -41,7 +41,7 @@ #define MY_NAME THIS_MODULE->name #endif -#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: "__FUNCTION__": " fmt , MY_NAME , ## arg); } while (0) +#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __FUNCTION__ , ## arg); } while (0) #define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg) #define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg) #define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg) Index: drivers/i2c/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/i2c/Config.in,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/i2c/Config.in 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/i2c/Config.in 21 Feb 2007 00:01:10 -0000 1.3 @@ -7,18 +7,18 @@ tristate 'I2C support' CONFIG_I2C if [ "$CONFIG_I2C" != "n" ]; then - dep_tristate 'I2C bit-banging interfaces' CONFIG_I2C_ALGOBIT $CONFIG_I2C if [ "$CONFIG_I2C_ALGOBIT" != "n" ]; then dep_tristate ' Philips style parallel port adapter' CONFIG_I2C_PHILIPSPAR $CONFIG_I2C_ALGOBIT $CONFIG_PARPORT dep_tristate ' ELV adapter' CONFIG_I2C_ELV $CONFIG_I2C_ALGOBIT - dep_tristate ' Velleman K9000 adapter' CONFIG_I2C_VELLEMAN $CONFIG_I2C_ALGOBIT - dep_tristate ' NatSemi SCx200 I2C using GPIO pins' CONFIG_SCx200_I2C $CONFIG_SCx200 $CONFIG_I2C_ALGOBIT + dep_tristate ' Velleman K8000 adapter' CONFIG_I2C_VELLEMAN $CONFIG_I2C_ALGOBIT + dep_tristate ' EP93xx I2C using GPIO pins' CONFIG_EP93XX_I2C $CONFIG_I2C_ALGOBIT + dep_tristate ' NatSemi SCx200 I2C using GPIO pins' CONFIG_SCx200_I2C $CONFIG_SCx200_GPIO $CONFIG_I2C_ALGOBIT if [ "$CONFIG_SCx200_I2C" != "n" ]; then int ' GPIO pin used for SCL' CONFIG_SCx200_I2C_SCL 12 int ' GPIO pin used for SDA' CONFIG_SCx200_I2C_SDA 13 fi - dep_tristate ' NatSemi SCx200 ACCESS.bus' CONFIG_SCx200_ACB $CONFIG_I2C + dep_tristate ' Guide GPIO adapter' CONFIG_I2C_GUIDE $CONFIG_I2C_ALGOBIT if [ "$CONFIG_ARCH_OMAHA" = "y" ]; then dep_tristate ' Omaha I2C interface' CONFIG_I2C_OMAHA $CONFIG_I2C @@ -29,6 +29,8 @@ fi fi + dep_tristate 'NatSemi SCx200 ACCESS.bus' CONFIG_SCx200_ACB $CONFIG_I2C + dep_tristate 'I2C PCF 8584 interfaces' CONFIG_I2C_ALGOPCF $CONFIG_I2C if [ "$CONFIG_I2C_ALGOPCF" != "n" ]; then dep_tristate ' Elektor ISA card' CONFIG_I2C_ELEKTOR $CONFIG_I2C_ALGOPCF @@ -43,7 +45,7 @@ if [ "$CONFIG_8xx" = "y" ]; then dep_tristate 'MPC8xx CPM I2C interface' CONFIG_I2C_ALGO8XX $CONFIG_I2C if [ "$CONFIG_RPXLITE" = "y" -o "$CONFIG_RPXCLASSIC" = "y" ]; then - dep_tristate ' Embedded Planet RPX Lite/Classic suppoort' CONFIG_I2C_RPXLITE $CONFIG_I2C_ALGO8XX + dep_tristate ' Embedded Planet RPX Lite/Classic support' CONFIG_I2C_RPXLITE $CONFIG_I2C_ALGO8XX fi fi if [ "$CONFIG_405" = "y" ]; then @@ -61,11 +63,19 @@ dep_tristate 'Atmel AT91RM9200 I2C Two-Wire interface (TWI)' CONFIG_I2C_AT91 $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 + + if [ "$CONFIG_SGI_IP22" = "y" ]; then + dep_tristate 'I2C SGI interfaces' CONFIG_I2C_ALGO_SGI $CONFIG_I2C + fi + # This is needed for automatic patch generation: sensors code starts here # This is needed for automatic patch generation: sensors code ends here dep_tristate 'I2C device interface' CONFIG_I2C_CHARDEV $CONFIG_I2C - dep_tristate 'I2C /proc interface (required for hardware sensors)' CONFIG_I2C_PROC $CONFIG_I2C - + dep_tristate 'I2C /proc interface (required for hardware sensors)' CONFIG_I2C_PROC $CONFIG_I2C $CONFIG_SYSCTL fi endmenu Index: drivers/i2c/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/i2c/Makefile,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/i2c/Makefile 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/i2c/Makefile 21 Feb 2007 00:01:10 -0000 1.3 @@ -5,7 +5,8 @@ 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-algo-sibyte.o i2c-algo-sgi.o \ + i2c-proc.o i2c-ep93xx.o # Init order: core, chardev, bit adapters, pcf adapters @@ -20,6 +21,7 @@ obj-$(CONFIG_I2C_GUIDE) += i2c-guide.o obj-$(CONFIG_I2C_FRODO) += i2c-frodo.o obj-$(CONFIG_I2C_OMAHA) += i2c-omaha.o +obj-$(CONFIG_EP93XX_I2C) += i2c-ep93xx.o # PCF adapters obj-$(CONFIG_I2C_ALGOPCF) += i2c-algo-pcf.o @@ -30,10 +32,11 @@ 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 +obj-$(CONFIG_I2C_ALGO_SGI) += i2c-algo-sgi.o # This is needed for automatic patch generation: sensors code starts here # This is needed for automatic patch generation: sensors code ends here include $(TOPDIR)/Rules.make - Index: drivers/i2c/i2c-adap-ite.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/i2c/i2c-adap-ite.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/i2c/i2c-adap-ite.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/i2c/i2c-adap-ite.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -61,11 +60,7 @@ static int i2c_debug=0; static struct iic_ite gpi; -#if (LINUX_VERSION_CODE < 0x020301) -static struct wait_queue *iic_wait = NULL; -#else static wait_queue_head_t iic_wait; -#endif static int iic_pending; /* ----- global defines ----------------------------------------------- */ @@ -271,9 +266,6 @@ piic->iic_own = own; iic_ite_data.data = (void *)piic; -#if (LINUX_VERSION_CODE >= 0x020301) - init_waitqueue_head(&iic_wait); -#endif if (iic_hw_resrc_init() == 0) { if (i2c_iic_add_bus(&iic_ite_ops) < 0) return -ENODEV; Index: drivers/i2c/i2c-algo-bit.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/i2c/i2c-algo-bit.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/i2c/i2c-algo-bit.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/i2c/i2c-algo-bit.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -21,13 +21,12 @@ /* With some changes from Kyösti Mälkki and even Frodo Looijaard */ -/* $Id: i2c-algo-bit.c,v 1.1 2004/07/22 19:49:29 joff Exp $ */ +/* $Id: i2c-algo-bit.c,v 1.2 2004/08/04 01:28:53 joff Exp $ */ #include #include #include #include -#include #include #include #include @@ -123,7 +122,7 @@ if (current->need_resched) schedule(); } - DEBSTAT(printk("needed %ld jiffies\n", jiffies-start)); + DEBSTAT(printk(KERN_DEBUG "needed %ld jiffies\n", jiffies-start)); #ifdef SLO_IO SLO_IO #endif @@ -186,12 +185,12 @@ struct i2c_algo_bit_data *adap = i2c_adap->algo_data; /* assert: scl is low */ - DEB2(printk(" i2c_outb:%2.2X\n",c&0xff)); + DEB2(printk(KERN_DEBUG " i2c_outb:%2.2X\n",c&0xff)); for ( i=7 ; i>=0 ; i-- ) { sb = c & ( 1 << i ); setsda(adap,sb); udelay(adap->udelay); - DEBPROTO(printk("%d",sb!=0)); + DEBPROTO(printk(KERN_DEBUG "%d",sb!=0)); if (sclhi(adap)<0) { /* timed out */ sdahi(adap); /* we don't want to block the net */ return -ETIMEDOUT; @@ -208,10 +207,10 @@ }; /* read ack: SDA should be pulled down by slave */ ack=getsda(adap); /* ack: sda is pulled low ->success. */ - DEB2(printk(" i2c_outb: getsda() = 0x%2.2x\n", ~ack )); + DEB2(printk(KERN_DEBUG " i2c_outb: getsda() = 0x%2.2x\n", ~ack )); - DEBPROTO( printk("[%2.2x]",c&0xff) ); - DEBPROTO(if (0==ack){ printk(" A ");} else printk(" NA ") ); + DEBPROTO( printk(KERN_DEBUG "[%2.2x]",c&0xff) ); + DEBPROTO(if (0==ack){ printk(KERN_DEBUG " A ");} else printk(KERN_DEBUG " NA ") ); scllo(adap); return 0==ack; /* return 1 if device acked */ /* assert: scl is low (sda undef) */ @@ -227,7 +226,7 @@ struct i2c_algo_bit_data *adap = i2c_adap->algo_data; /* assert: scl is low */ - DEB2(printk("i2c_inb.\n")); + DEB2(printk(KERN_DEBUG "i2c_inb.\n")); sdahi(adap); for (i=0;i<8;i++) { @@ -240,7 +239,7 @@ scllo(adap); } /* assert: scl is low */ - DEBPROTO(printk(" %2.2x", indata & 0xff)); + DEBPROTO(printk(KERN_DEBUG " 0x%02x", indata & 0xff)); return (int) (indata & 0xff); } @@ -348,7 +347,7 @@ i2c_start(adap); udelay(adap->udelay); } - DEB2(if (i) printk("i2c-algo-bit.o: needed %d retries for %d\n", + DEB2(if (i) printk(KERN_DEBUG "i2c-algo-bit.o: needed %d retries for %d\n", i,addr)); return ret; } @@ -363,7 +362,7 @@ while (count > 0) { c = *temp; - DEB2(printk("i2c-algo-bit.o: %s i2c_write: writing %2.2X\n", + DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: %s sendbytes: writing %2.2X\n", i2c_adap->name, c&0xff)); retval = i2c_outb(i2c_adap,c); if (retval>0) { @@ -371,7 +370,7 @@ temp++; wrcount++; } else { /* arbitration or no acknowledge */ - printk("i2c-algo-bit.o: %s i2c_write: error - bailout.\n", + printk(KERN_ERR "i2c-algo-bit.o: %s sendbytes: error - bailout.\n", i2c_adap->name); i2c_stop(adap); return (retval<0)? retval : -EFAULT; @@ -399,7 +398,7 @@ *temp = inval; rdcount++; } else { /* read timed out */ - printk("i2c-algo-bit.o: i2c_read: i2c_inb timed out.\n"); + printk(KERN_ERR "i2c-algo-bit.o: readbytes: i2c_inb timed out.\n"); break; } @@ -412,7 +411,7 @@ } if (sclhi(adap)<0) { /* timeout */ sdahi(adap); - printk("i2c-algo-bit.o: i2c_read: Timeout at ack\n"); + printk(KERN_ERR "i2c-algo-bit.o: readbytes: Timeout at ack\n"); return -ETIMEDOUT; }; scllo(adap); @@ -442,18 +441,18 @@ if ( (flags & I2C_M_TEN) ) { /* a ten bit address */ addr = 0xf0 | (( msg->addr >> 7) & 0x03); - DEB2(printk("addr0: %d\n",addr)); + DEB2(printk(KERN_DEBUG "addr0: %d\n",addr)); /* try extended address code...*/ ret = try_address(i2c_adap, addr, retries); if (ret!=1) { - printk("died at extended address code.\n"); + printk(KERN_ERR "died at extended address code.\n"); return -EREMOTEIO; } /* the remaining 8 bit address */ ret = i2c_outb(i2c_adap,msg->addr & 0x7f); if (ret != 1) { /* the chip did not ack / xmission error occurred */ - printk("died at 2nd address code.\n"); + printk(KERN_ERR "died at 2nd address code.\n"); return -EREMOTEIO; } if ( flags & I2C_M_RD ) { @@ -462,7 +461,7 @@ addr |= 0x01; ret = try_address(i2c_adap, addr, retries); if (ret!=1) { - printk("died at extended address code.\n"); + printk(KERN_ERR "died at extended address code.\n"); return -EREMOTEIO; } } @@ -497,22 +496,22 @@ } ret = bit_doAddress(i2c_adap,pmsg,i2c_adap->retries); if (ret != 0) { - DEB2(printk("i2c-algo-bit.o: NAK from device adr %#2x msg #%d\n" - ,msgs[i].addr,i)); + DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: NAK from device addr %2.2x msg #%d\n", + msgs[i].addr,i)); return (ret<0) ? ret : -EREMOTEIO; } } if (pmsg->flags & I2C_M_RD ) { /* read bytes into buffer*/ ret = readbytes(i2c_adap,pmsg->buf,pmsg->len); - DEB2(printk("i2c-algo-bit.o: read %d bytes.\n",ret)); + DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: read %d bytes.\n",ret)); if (ret < pmsg->len ) { return (ret<0)? ret : -EREMOTEIO; } } else { /* write bytes from buffer */ ret = sendbytes(i2c_adap,pmsg->buf,pmsg->len); - DEB2(printk("i2c-algo-bit.o: wrote %d bytes.\n",ret)); + DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: wrote %d bytes.\n",ret)); if (ret < pmsg->len ) { return (ret<0) ? ret : -EREMOTEIO; } @@ -562,7 +561,7 @@ return -ENODEV; } - DEB2(printk("i2c-algo-bit.o: hw routines for %s registered.\n", + DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: hw routines for %s registered.\n", adap->name)); /* register new adapter to i2c module... */ Index: drivers/i2c/i2c-algo-ite.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/i2c/i2c-algo-ite.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/i2c/i2c-algo-ite.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/i2c/i2c-algo-ite.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include Index: drivers/i2c/i2c-algo-pcf.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/i2c/i2c-algo-pcf.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/i2c/i2c-algo-pcf.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/i2c/i2c-algo-pcf.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -99,7 +98,7 @@ } #endif if (timeout <= 0) { - printk("Timeout waiting for Bus Busy\n"); + printk(KERN_ERR "Timeout waiting for Bus Busy\n"); } return (timeout<=0); @@ -144,7 +143,7 @@ { unsigned char temp; - DEB3(printk("i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1))); + DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1))); /* S1=0x80: S0 selected, serial interface off */ set_pcf(adap, 1, I2C_PCF_PIN); @@ -152,7 +151,7 @@ PCF8584 does that when ESO is zero */ /* PCF also resets PIN bit */ if ((temp = get_pcf(adap, 1)) != (0)) { - DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp)); + DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp)); return -ENXIO; /* definetly not PCF8584 */ } @@ -160,7 +159,7 @@ i2c_outb(adap, get_own(adap)); /* check it's realy writen */ if ((temp = i2c_inb(adap)) != get_own(adap)) { - DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp)); + DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp)); return -ENXIO; } @@ -168,7 +167,7 @@ set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1); /* check to see S2 now selected */ if ((temp = get_pcf(adap, 1)) != I2C_PCF_ES1) { - DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp)); + DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp)); return -ENXIO; } @@ -176,7 +175,7 @@ i2c_outb(adap, get_clock(adap)); /* check it's realy writen, the only 5 lowest bits does matter */ if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) { - DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp)); + DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp)); return -ENXIO; } @@ -185,11 +184,11 @@ /* check to see PCF is realy idled and we can access status register */ if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) { - DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp)); + DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp)); return -ENXIO; } - printk("i2c-algo-pcf.o: deteted and initialized PCF8584.\n"); + printk(KERN_DEBUG "i2c-algo-pcf.o: deteted and initialized PCF8584.\n"); return 0; } @@ -215,7 +214,7 @@ i2c_stop(adap); udelay(adap->udelay); } - DEB2(if (i) printk("i2c-algo-pcf.o: needed %d retries for %d\n",i, + DEB2(if (i) printk(KERN_DEBUG "i2c-algo-pcf.o: needed %d retries for %d\n",i, addr)); return ret; } @@ -228,20 +227,20 @@ int wrcount, status, timeout; for (wrcount=0; wrcountname, buf[wrcount]&0xff)); i2c_outb(adap, buf[wrcount]); timeout = wait_for_pin(adap, &status); if (timeout) { i2c_stop(adap); - printk("i2c-algo-pcf.o: %s i2c_write: " + printk(KERN_ERR "i2c-algo-pcf.o: %s i2c_write: " "error - timeout.\n", i2c_adap->name); return -EREMOTEIO; /* got a better one ?? */ } #ifndef STUB_I2C if (status & I2C_PCF_LRB) { i2c_stop(adap); - printk("i2c-algo-pcf.o: %s i2c_write: " + printk(KERN_ERR "i2c-algo-pcf.o: %s i2c_write: " "error - no ack.\n", i2c_adap->name); return -EREMOTEIO; /* got a better one ?? */ } @@ -269,14 +268,14 @@ if (wait_for_pin(adap, &status)) { i2c_stop(adap); - printk("i2c-algo-pcf.o: pcf_readbytes timed out.\n"); + printk(KERN_ERR "i2c-algo-pcf.o: pcf_readbytes timed out.\n"); return (-1); } #ifndef STUB_I2C if ((status & I2C_PCF_LRB) && (i != count)) { i2c_stop(adap); - printk("i2c-algo-pcf.o: i2c_read: i2c_inb, No ack.\n"); + printk(KERN_ERR "i2c-algo-pcf.o: i2c_read: i2c_inb, No ack.\n"); return (-1); } #endif @@ -312,18 +311,18 @@ if ( (flags & I2C_M_TEN) ) { /* a ten bit address */ addr = 0xf0 | (( msg->addr >> 7) & 0x03); - DEB2(printk("addr0: %d\n",addr)); + DEB2(printk(KERN_DEBUG "addr0: %d\n",addr)); /* try extended address code...*/ ret = try_address(adap, addr, retries); if (ret!=1) { - printk("died at extended address code.\n"); + printk(KERN_ERR "died at extended address code.\n"); return -EREMOTEIO; } /* the remaining 8 bit address */ i2c_outb(adap,msg->addr & 0x7f); /* Status check comes here */ if (ret != 1) { - printk("died at 2nd address code.\n"); + printk(KERN_ERR "died at 2nd address code.\n"); return -EREMOTEIO; } if ( flags & I2C_M_RD ) { @@ -332,7 +331,7 @@ addr |= 0x01; ret = try_address(adap, addr, retries); if (ret!=1) { - printk("died at extended address code.\n"); + printk(KERN_ERR "died at extended address code.\n"); return -EREMOTEIO; } } @@ -360,7 +359,7 @@ /* Check for bus busy */ timeout = wait_for_bb(adap); if (timeout) { - DEB2(printk("i2c-algo-pcf.o: " + DEB2(printk(KERN_ERR "i2c-algo-pcf.o: " "Timeout waiting for BB in pcf_xfer\n");) return -EIO; } @@ -368,7 +367,7 @@ for (i = 0;ret >= 0 && i < num; i++) { pmsg = &msgs[i]; - DEB2(printk("i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n", + DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n", pmsg->flags & I2C_M_RD ? "read" : "write", pmsg->len, pmsg->addr, i + 1, num);) @@ -383,7 +382,7 @@ timeout = wait_for_pin(adap, &status); if (timeout) { i2c_stop(adap); - DEB2(printk("i2c-algo-pcf.o: Timeout waiting " + DEB2(printk(KERN_ERR "i2c-algo-pcf.o: Timeout waiting " "for PIN(1) in pcf_xfer\n");) return (-EREMOTEIO); } @@ -392,12 +391,12 @@ /* Check LRB (last rcvd bit - slave ack) */ if (status & I2C_PCF_LRB) { i2c_stop(adap); - DEB2(printk("i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");) + DEB2(printk(KERN_ERR "i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");) return (-EREMOTEIO); } #endif - DEB3(printk("i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n", + DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n", i, msgs[i].addr, msgs[i].flags, msgs[i].len);) /* Read */ @@ -407,20 +406,20 @@ (i + 1 == num)); if (ret != pmsg->len) { - DEB2(printk("i2c-algo-pcf.o: fail: " + DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: " "only read %d bytes.\n",ret)); } else { - DEB2(printk("i2c-algo-pcf.o: read %d bytes.\n",ret)); + DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: read %d bytes.\n",ret)); } } else { /* Write */ ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len, (i + 1 == num)); if (ret != pmsg->len) { - DEB2(printk("i2c-algo-pcf.o: fail: " + DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: " "only wrote %d bytes.\n",ret)); } else { - DEB2(printk("i2c-algo-pcf.o: wrote %d bytes.\n",ret)); + DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: wrote %d bytes.\n",ret)); } } } @@ -461,7 +460,7 @@ int i, status; struct i2c_algo_pcf_data *pcf_adap = adap->algo_data; - DEB2(printk("i2c-algo-pcf.o: hw routines for %s registered.\n", + DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: hw routines for %s registered.\n", adap->name)); /* register new adapter to i2c module... */ Index: drivers/i2c/i2c-core.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/i2c/i2c-core.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/i2c/i2c-core.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/i2c/i2c-core.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -20,7 +20,7 @@ /* With some changes from Kyösti Mälkki . All SMBus-related things are written by Frodo Looijaard */ -/* $Id: i2c-core.c,v 1.1 2004/07/22 19:49:29 joff Exp $ */ +/* $Id: i2c-core.c,v 1.2 2004/08/04 01:28:53 joff Exp $ */ #include #include @@ -33,20 +33,15 @@ /* ----- compatibility stuff ----------------------------------------------- */ -#include #include -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1) -#define init_MUTEX(s) do { *(s) = MUTEX; } while(0) -#endif - #include /* ----- global defines ---------------------------------------------------- */ /* exclusive access to the bus */ #define I2C_LOCK(adap) down(&adap->lock) -#define I2C_UNLOCK(adap) up(&adap->lock) +#define I2C_UNLOCK(adap) up(&adap->lock) #define ADAP_LOCK() down(&adap_lock) #define ADAP_UNLOCK() up(&adap_lock) @@ -84,27 +79,17 @@ static int i2cproc_init(void); static void i2cproc_cleanup(void); -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,27)) -static void monitor_bus_i2c(struct inode *inode, int fill); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */ - -static ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count, +static ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count, loff_t *ppos); static int read_bus_i2c(char *buf, char **start, off_t offset, int len, int *eof , void *private); -/* To implement the dynamic /proc/bus/i2c-? files, we need our own +/* To implement the dynamic /proc/bus/i2c-? files, we need our own implementation of the read hook */ static struct file_operations i2cproc_operations = { read: i2cproc_bus_read, }; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48)) -static struct inode_operations i2cproc_inode_operations = { - &i2cproc_operations -}; -#endif - static int i2cproc_initialized = 0; #else /* undef CONFIG_PROC_FS */ @@ -116,8 +101,8 @@ /* --------------------------------------------------- - * registering functions - * --------------------------------------------------- + * registering functions + * --------------------------------------------------- */ /* ----- @@ -134,7 +119,7 @@ if (NULL == adapters[i]) break; if (I2C_ADAP_MAX == i) { - printk(KERN_WARNING + printk(KERN_WARNING " i2c-core.o: register_adapter(%s) - enlarge I2C_ADAP_MAX.\n", adap->name); res = -ENOMEM; @@ -144,7 +129,7 @@ adapters[i] = adap; adap_count++; ADAP_UNLOCK(); - + /* init data types */ init_MUTEX(&adap->lock); @@ -164,34 +149,26 @@ goto ERROR1; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,48)) proc_entry->proc_fops = &i2cproc_operations; -#else - proc_entry->ops = &i2cproc_inode_operations; -#endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27)) proc_entry->owner = THIS_MODULE; -#else - proc_entry->fill_inode = &monitor_bus_i2c; -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */ adap->inode = proc_entry->low_ino; } #endif /* def CONFIG_PROC_FS */ /* inform drivers of new adapters */ - DRV_LOCK(); + DRV_LOCK(); for (j=0;jflags&(I2C_DF_NOTIFY|I2C_DF_DUMMY))) /* We ignore the return code; if it fails, too bad */ drivers[j]->attach_adapter(adap); DRV_UNLOCK(); - - DEB(printk("i2c-core.o: adapter %s registered as adapter %d.\n", + + DEB(printk(KERN_DEBUG "i2c-core.o: adapter %s registered as adapter %d.\n", adap->name,i)); - return 0; + return 0; ERROR1: @@ -214,7 +191,7 @@ if (adap == adapters[i]) break; if (I2C_ADAP_MAX == i) { - printk( "i2c-core.o: unregister_adapter adap [%s] not found.\n", + printk(KERN_WARNING "i2c-core.o: unregister_adapter adap [%s] not found.\n", adap->name); res = -ENODEV; goto ERROR0; @@ -226,13 +203,13 @@ * this or hell will break loose... */ DRV_LOCK(); - for (j = 0; j < I2C_DRIVER_MAX; j++) + for (j = 0; j < I2C_DRIVER_MAX; j++) if (drivers[j] && (drivers[j]->flags & I2C_DF_DUMMY)) if ((res = drivers[j]->attach_adapter(adap))) { - printk("i2c-core.o: can't detach adapter %s " + printk(KERN_WARNING "i2c-core.o: can't detach adapter %s " "while detaching driver %s: driver not " "detached!",adap->name,drivers[j]->name); - goto ERROR1; + goto ERROR1; } DRV_UNLOCK(); @@ -247,7 +224,7 @@ * must be deleted, as this would cause invalid states. */ if ((res=client->driver->detach_client(client))) { - printk("i2c-core.o: adapter %s not " + printk(KERN_ERR "i2c-core.o: adapter %s not " "unregistered, because client at " "address %02x can't be detached. ", adap->name, client->addr); @@ -264,9 +241,9 @@ adapters[i] = NULL; adap_count--; - - ADAP_UNLOCK(); - DEB(printk("i2c-core.o: adapter unregistered: %s\n",adap->name)); + + ADAP_UNLOCK(); + DEB(printk(KERN_DEBUG "i2c-core.o: adapter unregistered: %s\n",adap->name)); return 0; ERROR0: @@ -292,7 +269,7 @@ if (NULL == drivers[i]) break; if (I2C_DRIVER_MAX == i) { - printk(KERN_WARNING + printk(KERN_WARNING " i2c-core.o: register_driver(%s) " "- enlarge I2C_DRIVER_MAX.\n", driver->name); @@ -302,11 +279,11 @@ drivers[i] = driver; driver_count++; - + DRV_UNLOCK(); /* driver was successfully added */ - - DEB(printk("i2c-core.o: driver %s registered.\n",driver->name)); - + + DEB(printk(KERN_DEBUG "i2c-core.o: driver %s registered.\n",driver->name)); + ADAP_LOCK(); /* now look for instances of driver on our adapters @@ -337,11 +314,11 @@ return -ENODEV; } /* Have a look at each adapter, if clients of this driver are still - * attached. If so, detach them to be able to kill the driver + * attached. If so, detach them to be able to kill the driver * afterwards. */ - DEB2(printk("i2c-core.o: unregister_driver - looking for clients.\n")); - /* removing clients does not depend on the notify flag, else + DEB2(printk(KERN_DEBUG "i2c-core.o: unregister_driver - looking for clients.\n")); + /* removing clients does not depend on the notify flag, else * invalid operation might (will!) result, when using stale client * pointers. */ @@ -350,16 +327,16 @@ struct i2c_adapter *adap = adapters[k]; if (adap == NULL) /* skip empty entries. */ continue; - DEB2(printk("i2c-core.o: examining adapter %s:\n", + DEB2(printk(KERN_DEBUG "i2c-core.o: examining adapter %s:\n", adap->name)); if (driver->flags & I2C_DF_DUMMY) { /* DUMMY drivers do not register their clients, so we have to * use a trick here: we call driver->attach_adapter to * *detach* it! Of course, each dummy driver should know about - * this or hell will break loose... + * this or hell will break loose... */ if ((res = driver->attach_adapter(adap))) { - printk("i2c-core.o: while unregistering " + printk(KERN_WARNING "i2c-core.o: while unregistering " "dummy driver %s, adapter %s could " "not be detached properly; driver " "not unloaded!",driver->name, @@ -368,17 +345,17 @@ return res; } } else { - for (j=0;jclients[j]; - if (client != NULL && + if (client != NULL && client->driver == driver) { - DEB2(printk("i2c-core.o: " + DEB2(printk(KERN_DEBUG "i2c-core.o: " "detaching client %s:\n", client->name)); if ((res = driver-> detach_client(client))) { - printk("i2c-core.o: while " + printk(KERN_ERR "i2c-core.o: while " "unregistering driver " "`%s', the client at " "address %02x of " @@ -399,15 +376,15 @@ drivers[i] = NULL; driver_count--; DRV_UNLOCK(); - - DEB(printk("i2c-core.o: driver unregistered: %s\n",driver->name)); + + DEB(printk(KERN_DEBUG "i2c-core.o: driver unregistered: %s\n",driver->name)); return 0; } int i2c_check_addr (struct i2c_adapter *adapter, int addr) { int i; - for (i = 0; i < I2C_CLIENT_MAX ; i++) + for (i = 0; i < I2C_CLIENT_MAX ; i++) if (adapter->clients[i] && (adapter->clients[i]->addr == addr)) return -EBUSY; return 0; @@ -425,7 +402,7 @@ if (NULL == adapter->clients[i]) break; if (I2C_CLIENT_MAX == i) { - printk(KERN_WARNING + printk(KERN_WARNING " i2c-core.o: attach_client(%s) - enlarge I2C_CLIENT_MAX.\n", client->name); return -ENOMEM; @@ -433,18 +410,18 @@ adapter->clients[i] = client; adapter->client_count++; - - if (adapter->client_register) - if (adapter->client_register(client)) - printk("i2c-core.o: warning: client_register seems " + + if (adapter->client_register) + if (adapter->client_register(client)) + printk(KERN_DEBUG "i2c-core.o: warning: client_register seems " "to have failed for client %02x at adapter %s\n", client->addr,adapter->name); - DEB(printk("i2c-core.o: client [%s] registered to adapter [%s](pos. %d).\n", + DEB(printk(KERN_DEBUG "i2c-core.o: client [%s] registered to adapter [%s](pos. %d).\n", client->name, adapter->name,i)); if(client->flags & I2C_CLIENT_ALLOW_USE) client->usage_count = 0; - + return 0; } @@ -463,14 +440,14 @@ client->name); return -ENODEV; } - - if( (client->flags & I2C_CLIENT_ALLOW_USE) && + + if( (client->flags & I2C_CLIENT_ALLOW_USE) && (client->usage_count>0)) return -EBUSY; - - if (adapter->client_unregister != NULL) + + if (adapter->client_unregister != NULL) if ((res = adapter->client_unregister(client))) { - printk("i2c-core.o: client_unregister [%s] failed, " + printk(KERN_ERR "i2c-core.o: client_unregister [%s] failed, " "client not detached",client->name); return res; } @@ -478,7 +455,7 @@ adapter->clients[i] = NULL; adapter->client_count--; - DEB(printk("i2c-core.o: client [%s] unregistered.\n",client->name)); + DEB(printk(KERN_DEBUG "i2c-core.o: client [%s] unregistered.\n",client->name)); return 0; } @@ -494,7 +471,7 @@ void i2c_dec_use_client(struct i2c_client *client) { - + if (client->driver->dec_use != NULL) client->driver->dec_use(client); @@ -502,65 +479,65 @@ client->adapter->dec_use(client->adapter); } -struct i2c_client *i2c_get_client(int driver_id, int adapter_id, +struct i2c_client *i2c_get_client(int driver_id, int adapter_id, struct i2c_client *prev) { int i,j; - + /* Will iterate through the list of clients in each adapter of adapters-list - in search for a client that matches the search criteria. driver_id or - adapter_id are ignored if set to 0. If both are ignored this returns + in search for a client that matches the search criteria. driver_id or + adapter_id are ignored if set to 0. If both are ignored this returns first client found. */ - - i = j = 0; - - /* set starting point */ + + i = j = 0; + + /* set starting point */ if(prev) { if(!(prev->adapter)) return (struct i2c_client *) -EINVAL; - + for(j=0; j < I2C_ADAP_MAX; j++) if(prev->adapter == adapters[j]) break; - + /* invalid starting point? */ if (I2C_ADAP_MAX == j) { printk(KERN_WARNING " i2c-core.o: get_client adapter for client:[%s] not found\n", prev->name); return (struct i2c_client *) -ENODEV; - } - + } + for(i=0; i < I2C_CLIENT_MAX; i++) if(prev == adapters[j]->clients[i]) break; - + /* invalid starting point? */ if (I2C_CLIENT_MAX == i) { printk(KERN_WARNING " i2c-core.o: get_client client:[%s] not found\n", prev->name); return (struct i2c_client *) -ENODEV; - } - + } + i++; /* start from one after prev */ } - + for(; j < I2C_ADAP_MAX; j++) { if(!adapters[j]) continue; - + if(adapter_id && (adapters[j]->id != adapter_id)) continue; - + for(; i < I2C_CLIENT_MAX; i++) { if(!adapters[j]->clients[i]) continue; - + if(driver_id && (adapters[j]->clients[i]->driver->id != driver_id)) continue; - if(adapters[j]->clients[i]->flags & I2C_CLIENT_ALLOW_USE) + if(adapters[j]->clients[i]->flags & I2C_CLIENT_ALLOW_USE) return adapters[j]->clients[i]; } i = 0; @@ -572,12 +549,12 @@ int i2c_use_client(struct i2c_client *client) { if(client->flags & I2C_CLIENT_ALLOW_USE) { - if (client->flags & I2C_CLIENT_ALLOW_MULTIPLE_USE) + if (client->flags & I2C_CLIENT_ALLOW_MULTIPLE_USE) client->usage_count++; else { - if(client->usage_count > 0) + if(client->usage_count > 0) return -EBUSY; - else + else client->usage_count++; } } @@ -598,9 +575,9 @@ return -EPERM; } } - + i2c_dec_use_client(client); - + return 0; } @@ -611,20 +588,8 @@ #ifdef CONFIG_PROC_FS -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,27)) -/* Monitor access to /proc/bus/i2c*; make unloading i2c-proc impossible - if some process still uses it or some file in it */ -void monitor_bus_i2c(struct inode *inode, int fill) -{ - if (fill) - MOD_INC_USE_COUNT; - else - MOD_DEC_USE_COUNT; -} -#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,37)) */ - /* This function generates the output for /proc/bus/i2c */ -int read_bus_i2c(char *buf, char **start, off_t offset, int len, int *eof, +int read_bus_i2c(char *buf, char **start, off_t offset, int len, int *eof, void *private) { int i; @@ -650,7 +615,7 @@ } /* This function generates the output for /proc/bus/i2c-? */ -ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count, +ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count, loff_t *ppos) { struct inode * inode = file->f_dentry->d_inode; @@ -661,7 +626,7 @@ int order[I2C_CLIENT_MAX]; if (count > 4000) - return -EINVAL; + return -EINVAL; len_total = file->f_pos + count; /* Too bad if this gets longer (unlikely) */ if (len_total > 4000) @@ -676,12 +641,12 @@ sorted by address */ order_nr=0; for (j = 0; j < I2C_CLIENT_MAX; j++) { - if ((client = adapters[i]->clients[j]) && + if ((client = adapters[i]->clients[j]) && (client->driver->id != I2C_DRIVERID_I2CDEV)) { - for(k = order_nr; - (k > 0) && + for(k = order_nr; + (k > 0) && adapters[i]->clients[order[k-1]]-> - addr > client->addr; + addr > client->addr; k--) order[k] = order[k-1]; order[k] = j; @@ -700,7 +665,7 @@ len = len - file->f_pos; if (len > count) len = count; - if (len < 0) + if (len < 0) len = 0; if (copy_to_user (buf,kbuf+file->f_pos, len)) { kfree(kbuf); @@ -724,19 +689,15 @@ printk("i2c-core.o: /proc/bus/ does not exist"); i2cproc_cleanup(); return -ENOENT; - } + } proc_bus_i2c = create_proc_entry("i2c",0,proc_bus); if (!proc_bus_i2c) { - printk("i2c-core.o: Could not create /proc/bus/i2c"); + printk(KERN_ERR "i2c-core.o: Could not create /proc/bus/i2c"); i2cproc_cleanup(); return -ENOENT; } proc_bus_i2c->read_proc = &read_bus_i2c; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27)) proc_bus_i2c->owner = THIS_MODULE; -#else - proc_bus_i2c->fill_inode = &monitor_bus_i2c; -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27)) */ i2cproc_initialized += 2; return 0; } @@ -763,7 +724,7 @@ int ret; if (adap->algo->master_xfer) { - DEB2(printk("i2c-core.o: master_xfer: %s with %d msgs.\n", + DEB2(printk(KERN_DEBUG "i2c-core.o: master_xfer: %s with %d msgs.\n", adap->name,num)); I2C_LOCK(adap); @@ -772,7 +733,7 @@ return ret; } else { - printk("i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n", + printk(KERN_ERR "i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n", adap->id); return -ENOSYS; } @@ -789,10 +750,10 @@ msg.flags = client->flags & I2C_M_TEN; msg.len = count; (const char *)msg.buf = buf; - - DEB2(printk("i2c-core.o: master_send: writing %d bytes on %s.\n", + + DEB2(printk(KERN_DEBUG "i2c-core.o: master_send: writing %d bytes on %s.\n", count,client->adapter->name)); - + I2C_LOCK(adap); ret = adap->algo->master_xfer(adap,&msg,1); I2C_UNLOCK(adap); @@ -802,7 +763,7 @@ */ return (ret == 1 )? count : ret; } else { - printk("i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n", + printk(KERN_ERR "i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n", client->adapter->id); return -ENOSYS; } @@ -820,22 +781,22 @@ msg.len = count; msg.buf = buf; - DEB2(printk("i2c-core.o: master_recv: reading %d bytes on %s.\n", + DEB2(printk(KERN_DEBUG "i2c-core.o: master_recv: reading %d bytes on %s.\n", count,client->adapter->name)); - + I2C_LOCK(adap); ret = adap->algo->master_xfer(adap,&msg,1); I2C_UNLOCK(adap); - - DEB2(printk("i2c-core.o: master_recv: return:%d (count:%d, addr:0x%02x)\n", + + DEB2(printk(KERN_DEBUG "i2c-core.o: master_recv: return:%d (count:%d, addr:0x%02x)\n", ret, count, client->addr)); - + /* if everything went ok (i.e. 1 msg transmitted), return #bytes * transmitted, else error code. */ return (ret == 1 )? count : ret; } else { - printk("i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n", + printk(KERN_ERR "i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n", client->adapter->id); return -ENOSYS; } @@ -848,7 +809,7 @@ int ret = 0; struct i2c_adapter *adap = client->adapter; - DEB2(printk("i2c-core.o: i2c ioctl, cmd: 0x%x, arg: %#lx\n", cmd, arg)); + DEB2(printk(KERN_DEBUG "i2c-core.o: i2c ioctl, cmd: 0x%x, arg: %#lx\n", cmd, arg)); switch ( cmd ) { case I2C_RETRIES: adap->retries = arg; @@ -890,17 +851,17 @@ found = 0; for (i = 0; !found && (address_data->force[i] != I2C_CLIENT_END); i += 3) { - if (((adap_id == address_data->force[i]) || + if (((adap_id == address_data->force[i]) || (address_data->force[i] == ANY_I2C_BUS)) && (addr == address_data->force[i+1])) { - DEB2(printk("i2c-core.o: found force parameter for adapter %d, addr %04x\n", + DEB2(printk(KERN_DEBUG "i2c-core.o: found force parameter for adapter %d, addr %04x\n", adap_id,addr)); if ((err = found_proc(adapter,addr,0,0))) return err; found = 1; } } - if (found) + if (found) continue; /* If this address is in one of the ignores, we can forget about @@ -908,10 +869,10 @@ for (i = 0; !found && (address_data->ignore[i] != I2C_CLIENT_END); i += 2) { - if (((adap_id == address_data->ignore[i]) || + if (((adap_id == address_data->ignore[i]) || ((address_data->ignore[i] == ANY_I2C_BUS))) && (addr == address_data->ignore[i+1])) { - DEB2(printk("i2c-core.o: found ignore parameter for adapter %d, " + DEB2(printk(KERN_DEBUG "i2c-core.o: found ignore parameter for adapter %d, " "addr %04x\n", adap_id ,addr)); found = 1; } @@ -923,22 +884,22 @@ ((address_data->ignore_range[i]==ANY_I2C_BUS))) && (addr >= address_data->ignore_range[i+1]) && (addr <= address_data->ignore_range[i+2])) { - DEB2(printk("i2c-core.o: found ignore_range parameter for adapter %d, " + DEB2(printk(KERN_DEBUG "i2c-core.o: found ignore_range parameter for adapter %d, " "addr %04x\n", adap_id,addr)); found = 1; } } - if (found) + if (found) continue; - /* Now, we will do a detection, but only if it is in the normal or - probe entries */ + /* Now, we will do a detection, but only if it is in the normal or + probe entries */ for (i = 0; !found && (address_data->normal_i2c[i] != I2C_CLIENT_END); i += 1) { if (addr == address_data->normal_i2c[i]) { found = 1; - DEB2(printk("i2c-core.o: found normal i2c entry for adapter %d, " + DEB2(printk(KERN_DEBUG "i2c-core.o: found normal i2c entry for adapter %d, " "addr %02x", adap_id,addr)); } } @@ -949,7 +910,7 @@ if ((addr >= address_data->normal_i2c_range[i]) && (addr <= address_data->normal_i2c_range[i+1])) { found = 1; - DEB2(printk("i2c-core.o: found normal i2c_range entry for adapter %d, " + DEB2(printk(KERN_DEBUG "i2c-core.o: found normal i2c_range entry for adapter %d, " "addr %04x\n", adap_id,addr)); } } @@ -961,7 +922,7 @@ ((address_data->probe[i] == ANY_I2C_BUS))) && (addr == address_data->probe[i+1])) { found = 1; - DEB2(printk("i2c-core.o: found probe parameter for adapter %d, " + DEB2(printk(KERN_DEBUG "i2c-core.o: found probe parameter for adapter %d, " "addr %04x\n", adap_id,addr)); } } @@ -973,11 +934,11 @@ (addr >= address_data->probe_range[i+1]) && (addr <= address_data->probe_range[i+2])) { found = 1; - DEB2(printk("i2c-core.o: found probe_range parameter for adapter %d, " + DEB2(printk(KERN_DEBUG "i2c-core.o: found probe_range parameter for adapter %d, " "addr %04x\n", adap_id,addr)); } } - if (!found) + if (!found) continue; /* OK, so we really should examine this address. First check @@ -1100,8 +1061,8 @@ { union i2c_smbus_data data; int i; - if (length > 32) - length = 32; + if (length > I2C_SMBUS_BLOCK_MAX) + length = I2C_SMBUS_BLOCK_MAX; for (i = 1; i <= length; i++) data.block[i] = values[i-1]; data.block[0] = length; @@ -1115,8 +1076,8 @@ { union i2c_smbus_data data; int i; - if (length > 32) - length = 32; + if (length > I2C_SMBUS_I2C_BLOCK_MAX) + length = I2C_SMBUS_I2C_BLOCK_MAX; for (i = 1; i <= length; i++) data.block[i] = values[i-1]; data.block[0] = length; @@ -1125,11 +1086,11 @@ I2C_SMBUS_I2C_BLOCK_DATA,&data); } -/* Simulate a SMBus command using the i2c protocol +/* Simulate a SMBus command using the i2c protocol No checking of parameters is done! */ -static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, +static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, unsigned short flags, - char read_write, u8 command, int size, + char read_write, u8 command, int size, union i2c_smbus_data * data) { /* So we need to generate a series of msgs. In the case of writing, we @@ -1139,7 +1100,7 @@ unsigned char msgbuf0[34]; unsigned char msgbuf1[34]; int num = read_write == I2C_SMBUS_READ?2:1; - struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 }, + struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 }, { addr, flags | I2C_M_RD, 0, msgbuf1 } }; int i; @@ -1185,15 +1146,15 @@ break; case I2C_SMBUS_BLOCK_DATA: if (read_write == I2C_SMBUS_READ) { - printk("i2c-core.o: Block read not supported under " - "I2C emulation!\n"); - return -1; + printk(KERN_ERR "i2c-core.o: Block read not supported " + "under I2C emulation!\n"); + return -1; } else { msg[0].len = data->block[0] + 2; - if (msg[0].len > 34) { - printk("i2c-core.o: smbus_access called with " + if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) { + printk(KERN_ERR "i2c-core.o: smbus_access called with " "invalid block write size (%d)\n", - msg[0].len); + data->block[0]); return -1; } for (i = 1; i <= msg[0].len; i++) @@ -1201,7 +1162,7 @@ } break; default: - printk("i2c-core.o: smbus_access called with invalid size (%d)\n", + printk(KERN_ERR "i2c-core.o: smbus_access called with invalid size (%d)\n", size); return -1; } @@ -1217,7 +1178,7 @@ case I2C_SMBUS_BYTE_DATA: data->byte = msgbuf1[0]; break; - case I2C_SMBUS_WORD_DATA: + case I2C_SMBUS_WORD_DATA: case I2C_SMBUS_PROC_CALL: data->word = msgbuf1[0] | (msgbuf1[1] << 8); break; @@ -1227,7 +1188,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags, - char read_write, u8 command, int size, + char read_write, u8 command, int size, union i2c_smbus_data * data) { s32 res; @@ -1245,7 +1206,7 @@ /* You should always define `functionality'; the 'else' is just for - backward compatibility. */ + backward compatibility. */ u32 i2c_get_functionality (struct i2c_adapter *adap) { if (adap->algo->functionality) @@ -1263,7 +1224,7 @@ static int __init i2c_init(void) { - printk(KERN_DEBUG "i2c-core.o: i2c core module\n"); + printk(KERN_INFO "i2c-core.o: i2c core module version %s (%s)\n", I2C_VERSION, I2C_DATE); memset(adapters,0,sizeof(adapters)); memset(drivers,0,sizeof(drivers)); adap_count=0; @@ -1271,9 +1232,9 @@ init_MUTEX(&adap_lock); init_MUTEX(&driver_lock); - + i2cproc_init(); - + return 0; } @@ -1315,9 +1276,10 @@ MODULE_AUTHOR("Simon G. Vogl "); MODULE_DESCRIPTION("I2C-Bus main module"); +MODULE_LICENSE("GPL"); + MODULE_PARM(i2c_debug, "i"); MODULE_PARM_DESC(i2c_debug,"debug level"); -MODULE_LICENSE("GPL"); module_init(i2c_init); module_exit(i2cproc_cleanup); Index: drivers/i2c/i2c-dev.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/i2c/i2c-dev.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/i2c/i2c-dev.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/i2c/i2c-dev.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -1,5 +1,5 @@ /* - i2c-dev.c - i2c-bus driver, char device interface + i2c-dev.c - i2c-bus driver, char device interface Copyright (C) 1995-97 Simon G. Vogl Copyright (C) 1998-99 Frodo Looijaard @@ -25,20 +25,17 @@ /* The I2C_RDWR ioctl code is written by Kolja Waschk */ -/* The devfs code is contributed by Philipp Matthias Hahn +/* The devfs code is contributed by Philipp Matthias Hahn */ -/* $Id: i2c-dev.c,v 1.1 2004/07/22 19:49:29 joff Exp $ */ +/* $Id: i2c-dev.c,v 1.2 2004/08/04 01:28:53 joff Exp $ */ #include #include #include #include #include -#include -#if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) #include -#endif /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */ #ifdef CONFIG_DEVFS_FS #include #endif @@ -55,15 +52,12 @@ /* struct file_operations changed too often in the 2.1 series for nice code */ -#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9) -static loff_t i2cdev_lseek (struct file *file, loff_t offset, int origin); -#endif -static ssize_t i2cdev_read (struct file *file, char *buf, size_t count, +static ssize_t i2cdev_read (struct file *file, char *buf, size_t count, loff_t *offset); -static ssize_t i2cdev_write (struct file *file, const char *buf, size_t count, +static ssize_t i2cdev_write (struct file *file, const char *buf, size_t count, loff_t *offset); -static int i2cdev_ioctl (struct inode *inode, struct file *file, +static int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); static int i2cdev_open (struct inode *inode, struct file *file); @@ -78,14 +72,8 @@ static void i2cdev_cleanup(void); static struct file_operations i2cdev_fops = { -#if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) owner: THIS_MODULE, -#endif /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */ -#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9) - llseek: i2cdev_lseek, -#else llseek: no_llseek, -#endif read: i2cdev_read, write: i2cdev_write, ioctl: i2cdev_ioctl, @@ -123,20 +111,6 @@ static int i2cdev_initialized; -#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9) -/* Note that the lseek function is called llseek in 2.1 kernels. But things - are complicated enough as is. */ -loff_t i2cdev_lseek (struct file *file, loff_t offset, int origin) -{ -#ifdef DEBUG - struct inode *inode = file->f_dentry->d_inode; - printk("i2c-dev.o: i2c-%d lseek to %ld bytes relative to %d.\n", - MINOR(inode->i_rdev),(long) offset,origin); -#endif /* DEBUG */ - return -ESPIPE; -} -#endif - static ssize_t i2cdev_read (struct file *file, char *buf, size_t count, loff_t *offset) { @@ -149,16 +123,16 @@ struct i2c_client *client = (struct i2c_client *)file->private_data; - if(count > 8192) + if (count > 8192) count = 8192; - + /* copy user space data to kernel space. */ tmp = kmalloc(count,GFP_KERNEL); if (tmp==NULL) return -ENOMEM; #ifdef DEBUG - printk("i2c-dev.o: i2c-%d reading %d bytes.\n",MINOR(inode->i_rdev), + printk(KERN_DEBUG "i2c-dev.o: i2c-%d reading %d bytes.\n",MINOR(inode->i_rdev), count); #endif @@ -180,9 +154,9 @@ struct inode *inode = file->f_dentry->d_inode; #endif /* DEBUG */ - if(count > 8192) + if (count > 8192) count = 8192; - + /* copy user space data to kernel space. */ tmp = kmalloc(count,GFP_KERNEL); if (tmp==NULL) @@ -193,7 +167,7 @@ } #ifdef DEBUG - printk("i2c-dev.o: i2c-%d writing %d bytes.\n",MINOR(inode->i_rdev), + printk(KERN_DEBUG "i2c-dev.o: i2c-%d writing %d bytes.\n",MINOR(inode->i_rdev), count); #endif ret = i2c_master_send(client,tmp,count); @@ -201,7 +175,7 @@ return ret; } -int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd, +int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct i2c_client *client = (struct i2c_client *)file->private_data; @@ -209,18 +183,19 @@ 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; #ifdef DEBUG - printk("i2c-dev.o: i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n", + printk(KERN_DEBUG "i2c-dev.o: i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n", MINOR(inode->i_rdev),cmd, arg); #endif /* DEBUG */ switch ( cmd ) { case I2C_SLAVE: case I2C_SLAVE_FORCE: - if ((arg > 0x3ff) || + if ((arg > 0x3ff) || (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f)) return -EINVAL; if ((cmd == I2C_SLAVE) && i2c_check_addr(client->adapter,arg)) @@ -238,9 +213,9 @@ return (copy_to_user((unsigned long *)arg,&funcs, sizeof(unsigned long)))?-EFAULT:0; - case I2C_RDWR: - if (copy_from_user(&rdwr_arg, - (struct i2c_rdwr_ioctl_data *)arg, + case I2C_RDWR: + if (copy_from_user(&rdwr_arg, + (struct i2c_rdwr_ioctl_data *)arg, sizeof(rdwr_arg))) return -EFAULT; @@ -248,28 +223,35 @@ * be sent at once */ if (rdwr_arg.nmsgs > 42) return -EINVAL; - + rdwr_pa = (struct i2c_msg *) - kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg), + kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg), GFP_KERNEL); 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) { @@ -277,10 +259,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; } } @@ -288,21 +271,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)) { @@ -311,6 +293,7 @@ } kfree(rdwr_pa[i].buf); } + kfree(data_ptrs); kfree(rdwr_pa); return res; @@ -319,25 +302,25 @@ (struct i2c_smbus_ioctl_data *) arg, sizeof(struct i2c_smbus_ioctl_data))) return -EFAULT; - if ((data_arg.size != I2C_SMBUS_BYTE) && + if ((data_arg.size != I2C_SMBUS_BYTE) && (data_arg.size != I2C_SMBUS_QUICK) && - (data_arg.size != I2C_SMBUS_BYTE_DATA) && + (data_arg.size != I2C_SMBUS_BYTE_DATA) && (data_arg.size != I2C_SMBUS_WORD_DATA) && (data_arg.size != I2C_SMBUS_PROC_CALL) && (data_arg.size != I2C_SMBUS_BLOCK_DATA) && (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA)) { #ifdef DEBUG - printk("i2c-dev.o: size out of range (%x) in ioctl I2C_SMBUS.\n", + printk(KERN_DEBUG "i2c-dev.o: size out of range (%x) in ioctl I2C_SMBUS.\n", data_arg.size); #endif return -EINVAL; } - /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1, + /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1, so the check is valid if size==I2C_SMBUS_QUICK too. */ - if ((data_arg.read_write != I2C_SMBUS_READ) && + if ((data_arg.read_write != I2C_SMBUS_READ) && (data_arg.read_write != I2C_SMBUS_WRITE)) { #ifdef DEBUG - printk("i2c-dev.o: read_write out of range (%x) in ioctl I2C_SMBUS.\n", + printk(KERN_DEBUG "i2c-dev.o: read_write out of range (%x) in ioctl I2C_SMBUS.\n", data_arg.read_write); #endif return -EINVAL; @@ -346,7 +329,7 @@ /* Note that command values are always valid! */ if ((data_arg.size == I2C_SMBUS_QUICK) || - ((data_arg.size == I2C_SMBUS_BYTE) && + ((data_arg.size == I2C_SMBUS_BYTE) && (data_arg.read_write == I2C_SMBUS_WRITE))) /* These are special: we do not use data */ return i2c_smbus_xfer(client->adapter, client->addr, @@ -357,7 +340,7 @@ if (data_arg.data == NULL) { #ifdef DEBUG - printk("i2c-dev.o: data is NULL pointer in ioctl I2C_SMBUS.\n"); + printk(KERN_DEBUG "i2c-dev.o: data is NULL pointer in ioctl I2C_SMBUS.\n"); #endif return -EINVAL; } @@ -365,13 +348,13 @@ if ((data_arg.size == I2C_SMBUS_BYTE_DATA) || (data_arg.size == I2C_SMBUS_BYTE)) datasize = sizeof(data_arg.data->byte); - else if ((data_arg.size == I2C_SMBUS_WORD_DATA) || + else if ((data_arg.size == I2C_SMBUS_WORD_DATA) || (data_arg.size == I2C_SMBUS_PROC_CALL)) datasize = sizeof(data_arg.data->word); else /* size == I2C_SMBUS_BLOCK_DATA */ datasize = sizeof(data_arg.data->block); - if ((data_arg.size == I2C_SMBUS_PROC_CALL) || + if ((data_arg.size == I2C_SMBUS_PROC_CALL) || (data_arg.read_write == I2C_SMBUS_WRITE)) { if (copy_from_user(&temp, data_arg.data, datasize)) return -EFAULT; @@ -379,7 +362,7 @@ res = i2c_smbus_xfer(client->adapter,client->addr,client->flags, data_arg.read_write, data_arg.command,data_arg.size,&temp); - if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) || + if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) || (data_arg.read_write == I2C_SMBUS_READ))) { if (copy_to_user(data_arg.data, &temp, datasize)) return -EFAULT; @@ -399,7 +382,7 @@ if ((minor >= I2CDEV_ADAPS_MAX) || ! (i2cdev_adaps[minor])) { #ifdef DEBUG - printk("i2c-dev.o: Trying to open unattached adapter i2c-%d\n", + printk(KERN_DEBUG "i2c-dev.o: Trying to open unattached adapter i2c-%d\n", minor); #endif return -ENODEV; @@ -415,12 +398,9 @@ if (i2cdev_adaps[minor]->inc_use) i2cdev_adaps[minor]->inc_use(i2cdev_adaps[minor]); -#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0) - MOD_INC_USE_COUNT; -#endif /* LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0) */ #ifdef DEBUG - printk("i2c-dev.o: opened i2c-%d\n",minor); + printk(KERN_DEBUG "i2c-dev.o: opened i2c-%d\n",minor); #endif return 0; } @@ -431,18 +411,12 @@ kfree(file->private_data); file->private_data=NULL; #ifdef DEBUG - printk("i2c-dev.o: Closed: i2c-%d\n", minor); + printk(KERN_DEBUG "i2c-dev.o: Closed: i2c-%d\n", minor); #endif -#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0) - MOD_DEC_USE_COUNT; -#else /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */ lock_kernel(); -#endif /* LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0) */ if (i2cdev_adaps[minor]->dec_use) i2cdev_adaps[minor]->dec_use(i2cdev_adaps[minor]); -#if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) unlock_kernel(); -#endif /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */ return 0; } @@ -452,11 +426,11 @@ char name[8]; if ((i = i2c_adapter_id(adap)) < 0) { - printk("i2c-dev.o: Unknown adapter ?!?\n"); + printk(KERN_DEBUG "i2c-dev.o: Unknown adapter ?!?\n"); return -ENODEV; } if (i >= I2CDEV_ADAPS_MAX) { - printk("i2c-dev.o: Adapter number too large?!? (%d)\n",i); + printk(KERN_DEBUG "i2c-dev.o: Adapter number too large?!? (%d)\n",i); return -ENODEV; } @@ -469,7 +443,7 @@ S_IFCHR | S_IRUSR | S_IWUSR, &i2cdev_fops, NULL); #endif - printk("i2c-dev.o: Registered '%s' as minor %d\n",adap->name,i); + printk(KERN_DEBUG "i2c-dev.o: Registered '%s' as minor %d\n",adap->name,i); } else { /* This is actually a detach_adapter call! */ #ifdef CONFIG_DEVFS_FS @@ -477,7 +451,7 @@ #endif i2cdev_adaps[i] = NULL; #ifdef DEBUG - printk("i2c-dev.o: Adapter unregistered: %s\n",adap->name); + printk(KERN_DEBUG "i2c-dev.o: Adapter unregistered: %s\n",adap->name); #endif } @@ -499,7 +473,7 @@ { int res; - printk(KERN_DEBUG "i2c-dev.o: i2c /dev entries driver module\n"); + printk(KERN_INFO "i2c-dev.o: i2c /dev entries driver module version %s (%s)\n", I2C_VERSION, I2C_DATE); i2cdev_initialized = 0; #ifdef CONFIG_DEVFS_FS @@ -507,7 +481,7 @@ #else if (register_chrdev(I2C_MAJOR,"i2c",&i2cdev_fops)) { #endif - printk("i2c-dev.o: unable to get major %d for i2c bus\n", + printk(KERN_ERR "i2c-dev.o: unable to get major %d for i2c bus\n", I2C_MAJOR); return -EIO; } @@ -517,7 +491,7 @@ i2cdev_initialized ++; if ((res = i2c_add_driver(&i2cdev_driver))) { - printk("i2c-dev.o: Driver registration failed, module not inserted.\n"); + printk(KERN_ERR "i2c-dev.o: Driver registration failed, module not inserted.\n"); i2cdev_cleanup(); return res; } @@ -561,4 +535,3 @@ module_init(i2c_dev_init); module_exit(i2cdev_cleanup); - Index: drivers/i2c/i2c-elektor.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/i2c/i2c-elektor.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/i2c/i2c-elektor.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/i2c/i2c-elektor.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -55,11 +54,7 @@ in some functions, called from the algo-pcf module. Sometimes it's need to be rewriten - but for now just remove this for simpler reading */ -#if (LINUX_VERSION_CODE < 0x020301) -static struct wait_queue *pcf_wait = NULL; -#else static wait_queue_head_t pcf_wait; -#endif static int pcf_pending; /* ----- global defines ----------------------------------------------- */ @@ -78,7 +73,7 @@ val |= I2C_PCF_ENI; } - DEB3(printk("i2c-elektor.o: Write 0x%X 0x%02X\n", address, val & 255)); + DEB3(printk(KERN_DEBUG "i2c-elektor.o: Write 0x%X 0x%02X\n", address, val & 255)); switch (mmapped) { case 0: /* regular I/O */ @@ -99,7 +94,7 @@ int address = ctl ? (base + 1) : base; int val = mmapped ? readb(address) : inb(address); - DEB3(printk("i2c-elektor.o: Read 0x%X 0x%02X\n", address, val)); + DEB3(printk(KERN_DEBUG "i2c-elektor.o: Read 0x%X 0x%02X\n", address, val)); return (val); } @@ -142,7 +137,9 @@ { if (!mmapped) { if (check_region(base, 2) < 0 ) { - printk("i2c-elektor.o: requested I/O region (0x%X:2) is in use.\n", base); + printk(KERN_ERR + "i2c-elektor.o: requested I/O region (0x%X:2) " + "is in use.\n", base); return -ENODEV; } else { request_region(base, 2, "i2c (isa bus adapter)"); @@ -150,7 +147,7 @@ } if (irq > 0) { if (request_irq(irq, pcf_isa_handler, 0, "PCF8584", 0) < 0) { - printk("i2c-elektor.o: Request irq%d failed\n", irq); + printk(KERN_ERR "i2c-elektor.o: Request irq%d failed\n", irq); irq = 0; } else enable_irq(irq); @@ -234,7 +231,7 @@ /* yeap, we've found cypress, let's check config */ if (!pci_read_config_byte(cy693_dev, 0x47, &config)) { - DEB3(printk("i2c-elektor.o: found cy82c693, config register 0x47 = 0x%02x.\n", config)); + DEB3(printk(KERN_DEBUG "i2c-elektor.o: found cy82c693, config register 0x47 = 0x%02x.\n", config)); /* UP2000 board has this register set to 0xe1, but the most significant bit as seems can be @@ -256,7 +253,7 @@ 8.25 MHz (PCI/4) clock (this can be read from cypress) */ clock = I2C_PCF_CLK | I2C_PCF_TRNS90; - printk("i2c-elektor.o: found API UP2000 like board, will probe PCF8584 later.\n"); + printk(KERN_INFO "i2c-elektor.o: found API UP2000 like board, will probe PCF8584 later.\n"); } } } @@ -265,19 +262,17 @@ /* sanity checks for mmapped I/O */ if (mmapped && base < 0xc8000) { - printk("i2c-elektor.o: incorrect base address (0x%0X) specified for mmapped I/O.\n", base); + printk(KERN_ERR "i2c-elektor.o: incorrect base address (0x%0X) specified for mmapped I/O.\n", base); return -ENODEV; } - printk("i2c-elektor.o: i2c pcf8584-isa adapter module\n"); + printk(KERN_INFO "i2c-elektor.o: i2c pcf8584-isa adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE); if (base == 0) { base = DEFAULT_BASE; } -#if (LINUX_VERSION_CODE >= 0x020301) init_waitqueue_head(&pcf_wait); -#endif if (pcf_isa_init() == 0) { if (i2c_pcf_add_bus(&pcf_isa_ops) < 0) return -ENODEV; @@ -285,7 +280,7 @@ return -ENODEV; } - printk("i2c-elektor.o: found device at %#x.\n", base); + printk(KERN_DEBUG "i2c-elektor.o: found device at %#x.\n", base); return 0; } Index: drivers/i2c/i2c-elv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/i2c/i2c-elv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/i2c/i2c-elv.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/i2c/i2c-elv.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -21,13 +21,12 @@ /* With some changes from Kyösti Mälkki and even Frodo Looijaard */ -/* $Id: i2c-elv.c,v 1.1 2004/07/22 19:49:29 joff Exp $ */ +/* $Id: i2c-elv.c,v 1.2 2004/08/04 01:28:53 joff Exp $ */ #include #include #include #include -#include #include #include @@ -76,7 +75,7 @@ PortData |=2; } outb(PortData, DATA); -} +} static int bit_elv_getscl(void *data) { @@ -91,18 +90,18 @@ static int bit_elv_init(void) { if (check_region(base,(base == 0x3bc)? 3 : 8) < 0 ) { - return -ENODEV; + return -ENODEV; } else { /* test for ELV adap. */ if (inb(base+1) & 0x80) { /* BUSY should be high */ - DEBINIT(printk("i2c-elv.o: Busy was low.\n")); + DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Busy was low.\n")); return -ENODEV; } else { outb(0x0c,base+2); /* SLCT auf low */ udelay(400); if ( !(inb(base+1) && 0x10) ) { outb(0x04,base+2); - DEBINIT(printk("i2c-elv.o: Select was high.\n")); + DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Select was high.\n")); return -ENODEV; } } @@ -161,12 +160,12 @@ bit_elv_inc_use, bit_elv_dec_use, bit_elv_reg, - bit_elv_unreg, + bit_elv_unreg, }; static int __init i2c_bitelv_init(void) { - printk("i2c-elv.o: i2c ELV parallel port adapter module\n"); + printk(KERN_INFO "i2c-elv.o: i2c ELV parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE); if (base==0) { /* probe some values */ base=DEFAULT_BASE; @@ -186,7 +185,7 @@ return -ENODEV; } } - printk("i2c-elv.o: found device at %#x.\n",base); + printk(KERN_DEBUG "i2c-elv.o: found device at %#x.\n",base); return 0; } @@ -203,7 +202,6 @@ MODULE_DESCRIPTION("I2C-Bus adapter routines for ELV parallel port adapter"); MODULE_LICENSE("GPL"); - MODULE_PARM(base, "i"); module_init(i2c_bitelv_init); Index: drivers/i2c/i2c-keywest.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/i2c/i2c-keywest.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/i2c/i2c-keywest.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/i2c/i2c-keywest.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -45,7 +45,6 @@ #include #include -#include #include #include #include Index: drivers/i2c/i2c-pcf8584.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/i2c/i2c-pcf8584.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/i2c/i2c-pcf8584.h 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/i2c/i2c-pcf8584.h 4 Aug 2004 01:28:53 -0000 1.2 @@ -21,7 +21,7 @@ /* With some changes from Frodo Looijaard */ -/* $Id: i2c-pcf8584.h,v 1.1 2004/07/22 19:49:29 joff Exp $ */ +/* $Id: i2c-pcf8584.h,v 1.2 2004/08/04 01:28:53 joff Exp $ */ #ifndef I2C_PCF8584_H #define I2C_PCF8584_H 1 Index: drivers/i2c/i2c-philips-par.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/i2c/i2c-philips-par.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/i2c/i2c-philips-par.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/i2c/i2c-philips-par.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -16,12 +16,12 @@ You 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 */ -/* $Id: i2c-philips-par.c,v 1.1 2004/07/22 19:49:29 joff Exp $ */ +/* $Id: i2c-philips-par.c,v 1.2 2004/08/04 01:28:53 joff Exp $ */ #include #include @@ -72,7 +72,7 @@ static void bit_lp_setscl(void *data, int state) { - /*be cautious about state of the control register - + /*be cautious about state of the control register - touch only the one bit needed*/ if (state) { parport_write_control((struct parport *) data, @@ -126,7 +126,7 @@ static int bit_lp_getsda2(void *data) { - return (parport_read_status((struct parport *) data) & + return (parport_read_status((struct parport *) data) & PARPORT_STATUS_BUSY) ? 0 : 1; } @@ -154,7 +154,7 @@ * Encapsulate the above functions in the correct operations structure. * This is only done when more than one hardware adapter is supported. */ - + static struct i2c_algo_bit_data bit_lp_data = { NULL, bit_lp_setsda, @@ -162,7 +162,7 @@ bit_lp_getsda, bit_lp_getscl, 80, 80, 100, /* waits, timeout */ -}; +}; static struct i2c_algo_bit_data bit_lp_data2 = { NULL, @@ -171,7 +171,7 @@ bit_lp_getsda2, NULL, 80, 80, 100, /* waits, timeout */ -}; +}; static struct i2c_adapter bit_lp_ops = { "Philips Parallel port adapter", @@ -190,18 +190,18 @@ struct i2c_par *adapter = kmalloc(sizeof(struct i2c_par), GFP_KERNEL); if (!adapter) { - printk("i2c-philips-par: Unable to malloc.\n"); + printk(KERN_ERR "i2c-philips-par: Unable to malloc.\n"); return; } - printk("i2c-philips-par.o: attaching to %s\n", port->name); + printk(KERN_DEBUG "i2c-philips-par.o: attaching to %s\n", port->name); adapter->pdev = parport_register_device(port, "i2c-philips-par", - NULL, NULL, NULL, + NULL, NULL, NULL, PARPORT_FLAG_EXCL, NULL); if (!adapter->pdev) { - printk("i2c-philips-par: Unable to register with parport.\n"); + printk(KERN_ERR "i2c-philips-par: Unable to register with parport.\n"); return; } @@ -212,13 +212,13 @@ /* reset hardware to sane state */ parport_claim_or_block(adapter->pdev); - bit_lp_setsda(port, 1); - bit_lp_setscl(port, 1); + adapter->bit_lp_data.setsda(port, 1); + adapter->bit_lp_data.setscl(port, 1); parport_release(adapter->pdev); if (i2c_bit_add_bus(&adapter->adapter) < 0) { - printk("i2c-philips-par: Unable to register with I2C.\n"); + printk(KERN_ERR "i2c-philips-par: Unable to register with I2C.\n"); parport_unregister_device(adapter->pdev); kfree(adapter); return; /* No good */ @@ -250,41 +250,25 @@ } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,4) static struct parport_driver i2c_driver = { "i2c-philips-par", i2c_parport_attach, i2c_parport_detach, NULL }; -#endif static int __init i2c_bitlp_init(void) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,4) - struct parport *port; -#endif - printk("i2c-philips-par.o: i2c Philips parallel port adapter module\n"); + printk(KERN_INFO "i2c-philips-par.o: i2c Philips parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,4) parport_register_driver(&i2c_driver); -#else - for (port = parport_enumerate(); port; port=port->next) - i2c_parport_attach(port); -#endif - + return 0; } static void __exit i2c_bitlp_exit(void) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,4) parport_unregister_driver(&i2c_driver); -#else - struct parport *port; - for (port = parport_enumerate(); port; port=port->next) - i2c_parport_detach(port); -#endif } EXPORT_NO_SYMBOLS; Index: drivers/i2c/i2c-proc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/i2c/i2c-proc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/i2c/i2c-proc.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/i2c/i2c-proc.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -23,7 +23,6 @@ This driver puts entries in /proc/sys/dev/sensors for each I2C device */ -#include #include #include #include @@ -38,10 +37,6 @@ #include -/* FIXME need i2c versioning */ -#define LM_DATE "20010825" -#define LM_VERSION "2.6.1" - #ifndef THIS_MODULE #define THIS_MODULE NULL #endif @@ -67,10 +62,6 @@ static struct i2c_client *i2c_clients[SENSORS_ENTRY_MAX]; static unsigned short i2c_inodes[SENSORS_ENTRY_MAX]; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1) -static void i2c_fill_inode(struct inode *inode, int fill); -static void i2c_dir_fill_inode(struct inode *inode, int fill); -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1) */ static ctl_table sysctl_table[] = { {CTL_DEV, "dev", NULL, 0, 0555}, @@ -200,12 +191,7 @@ #endif /* DEBUG */ i2c_inodes[id - 256] = new_header->ctl_table->child->child->de->low_ino; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27)) new_header->ctl_table->child->child->de->owner = controlling_mod; -#else - new_header->ctl_table->child->child->de->fill_inode = - &i2c_dir_fill_inode; -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27)) */ return id; } @@ -684,7 +670,7 @@ && (addr == this_force->force[j + 1])) { #ifdef DEBUG printk - ("i2c-proc.o: found force parameter for adapter %d, addr %04x\n", + (KERN_DEBUG "i2c-proc.o: found force parameter for adapter %d, addr %04x\n", adapter_id, addr); #endif if ( @@ -714,7 +700,7 @@ && (addr == address_data->ignore[i + 1])) { #ifdef DEBUG printk - ("i2c-proc.o: found ignore parameter for adapter %d, " + (KERN_DEBUG "i2c-proc.o: found ignore parameter for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; @@ -734,7 +720,7 @@ && (addr <= address_data->ignore_range[i + 2])) { #ifdef DEBUG printk - ("i2c-proc.o: found ignore_range parameter for adapter %d, " + (KERN_DEBUG "i2c-proc.o: found ignore_range parameter for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; @@ -753,7 +739,7 @@ if (addr == address_data->normal_isa[i]) { #ifdef DEBUG printk - ("i2c-proc.o: found normal isa entry for adapter %d, " + (KERN_DEBUG "i2c-proc.o: found normal isa entry for adapter %d, " "addr %04x\n", adapter_id, addr); #endif @@ -775,7 +761,7 @@ 0)) { #ifdef DEBUG printk - ("i2c-proc.o: found normal isa_range entry for adapter %d, " + (KERN_DEBUG "i2c-proc.o: found normal isa_range entry for adapter %d, " "addr %04x", adapter_id, addr); #endif found = 1; @@ -789,7 +775,7 @@ found = 1; #ifdef DEBUG printk - ("i2c-proc.o: found normal i2c entry for adapter %d, " + (KERN_DEBUG "i2c-proc.o: found normal i2c entry for adapter %d, " "addr %02x", adapter_id, addr); #endif } @@ -805,7 +791,7 @@ { #ifdef DEBUG printk - ("i2c-proc.o: found normal i2c_range entry for adapter %d, " + (KERN_DEBUG "i2c-proc.o: found normal i2c_range entry for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; @@ -822,7 +808,7 @@ && (addr == address_data->probe[i + 1])) { #ifdef DEBUG printk - ("i2c-proc.o: found probe parameter for adapter %d, " + (KERN_DEBUG "i2c-proc.o: found probe parameter for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; @@ -841,7 +827,7 @@ found = 1; #ifdef DEBUG printk - ("i2c-proc.o: found probe_range parameter for adapter %d, " + (KERN_DEBUG "i2c-proc.o: found probe_range parameter for adapter %d, " "addr %04x\n", adapter_id, addr); #endif } @@ -862,17 +848,12 @@ int __init sensors_init(void) { - printk("i2c-proc.o version %s (%s)\n", LM_VERSION, LM_DATE); + printk(KERN_INFO "i2c-proc.o version %s (%s)\n", I2C_VERSION, I2C_DATE); i2c_initialized = 0; if (! (i2c_proc_header = register_sysctl_table(i2c_proc, 0))) return -ENOMEM; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1)) i2c_proc_header->ctl_table->child->de->owner = THIS_MODULE; -#else - i2c_proc_header->ctl_table->child->de->fill_inode = - &i2c_fill_inode; -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1)) */ i2c_initialized++; return 0; } Index: drivers/i2c/i2c-velleman.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/i2c/i2c-velleman.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/i2c/i2c-velleman.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/i2c/i2c-velleman.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -1,5 +1,5 @@ /* ------------------------------------------------------------------------- */ -/* i2c-velleman.c i2c-hw access for Velleman K9000 adapters */ +/* i2c-velleman.c i2c-hw access for Velleman K8000 adapters */ /* ------------------------------------------------------------------------- */ /* Copyright (C) 1995-96, 2000 Simon G. Vogl @@ -18,7 +18,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ------------------------------------------------------------------------- */ -/* $Id: i2c-velleman.c,v 1.1 2004/07/22 19:49:29 joff Exp $ */ +/* $Id: i2c-velleman.c,v 1.2 2004/08/04 01:28:53 joff Exp $ */ #include #include @@ -65,7 +65,7 @@ } else { outb(inb(CTRL) | I2C_SCL, CTRL); } - + } static void bit_velle_setsda(void *data, int state) @@ -75,8 +75,8 @@ } else { outb(inb(CTRL) | I2C_SDA, CTRL); } - -} + +} static int bit_velle_getscl(void *data) { @@ -95,7 +95,7 @@ base)); return -ENODEV; } else { - request_region(base, (base == 0x3bc)? 3 : 8, + request_region(base, (base == 0x3bc)? 3 : 8, "i2c (Vellemann adapter)"); bit_velle_setsda((void*)base,1); bit_velle_setscl((void*)base,1); @@ -104,7 +104,7 @@ } static void __exit bit_velle_exit(void) -{ +{ release_region( base , (base == 0x3bc)? 3 : 8 ); } @@ -156,7 +156,7 @@ static int __init i2c_bitvelle_init(void) { - printk("i2c-velleman.o: i2c Velleman K8000 adapter module\n"); + printk(KERN_INFO "i2c-velleman.o: i2c Velleman K8000 adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE); if (base==0) { /* probe some values */ base=DEFAULT_BASE; @@ -176,7 +176,7 @@ return -ENODEV; } } - printk("i2c-velleman.o: found device at %#x.\n",base); + printk(KERN_DEBUG "i2c-velleman.o: found device at %#x.\n",base); return 0; } Index: drivers/ide/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/Config.in 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/ide/Config.in 4 Aug 2004 01:28:53 -0000 1.2 @@ -31,86 +31,90 @@ dep_bool ' CMD640 enhanced support' CONFIG_BLK_DEV_CMD640_ENHANCED $CONFIG_BLK_DEV_CMD640 dep_bool ' ISA-PNP EIDE support' CONFIG_BLK_DEV_ISAPNP $CONFIG_ISAPNP if [ "$CONFIG_PCI" = "y" ]; then - bool ' PCI IDE chipset support' CONFIG_BLK_DEV_IDEPCI - if [ "$CONFIG_BLK_DEV_IDEPCI" = "y" ]; then - dep_bool ' Generic PCI IDE Chipset Support' CONFIG_BLK_DEV_GENERIC $CONFIG_BLK_DEV_IDEPCI - bool ' Sharing PCI IDE interrupts support' CONFIG_IDEPCI_SHARE_IRQ - bool ' Generic PCI bus-master DMA support' CONFIG_BLK_DEV_IDEDMA_PCI - bool ' Boot off-board chipsets first support' CONFIG_BLK_DEV_OFFBOARD - dep_bool ' Force enable legacy 2.0.X HOSTS to use DMA' CONFIG_BLK_DEV_IDEDMA_FORCED $CONFIG_BLK_DEV_IDEDMA_PCI - dep_bool ' Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO $CONFIG_BLK_DEV_IDEDMA_PCI + bool ' PCI IDE chipset support' CONFIG_BLK_DEV_IDEPCI + if [ "$CONFIG_BLK_DEV_IDEPCI" = "y" ]; then + dep_bool ' Generic PCI IDE Chipset Support' CONFIG_BLK_DEV_GENERIC $CONFIG_BLK_DEV_IDEPCI + bool ' Sharing PCI IDE interrupts support' CONFIG_IDEPCI_SHARE_IRQ + bool ' Generic PCI bus-master DMA support' CONFIG_BLK_DEV_IDEDMA_PCI + bool ' Boot off-board chipsets first support' CONFIG_BLK_DEV_OFFBOARD + dep_bool ' Force enable legacy 2.0.X HOSTS to use DMA' CONFIG_BLK_DEV_IDEDMA_FORCED $CONFIG_BLK_DEV_IDEDMA_PCI + dep_bool ' Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' Enable DMA only for disks ' CONFIG_IDEDMA_ONLYDISK $CONFIG_IDEDMA_PCI_AUTO - define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PCI - dep_bool ' ATA Work(s) In Progress (EXPERIMENTAL)' CONFIG_IDEDMA_PCI_WIP $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL -# dep_bool ' Good-Bad DMA Model-Firmware (WIP)' CONFIG_IDEDMA_NEW_DRIVE_LISTINGS $CONFIG_IDEDMA_PCI_WIP + define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PCI + dep_bool ' ATA Work(s) In Progress (EXPERIMENTAL)' CONFIG_IDEDMA_PCI_WIP $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL +# dep_bool ' Good-Bad DMA Model-Firmware (WIP)' CONFIG_IDEDMA_NEW_DRIVE_LISTINGS $CONFIG_IDEDMA_PCI_WIP dep_tristate ' Pacific Digital ADMA-100 basic support' CONFIG_BLK_DEV_ADMA100 $CONFIG_BLK_DEV_IDEDMA_PCI - 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_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 - dep_tristate ' CY82C693 chipset support' CONFIG_BLK_DEV_CY82C693 $CONFIG_BLK_DEV_IDEDMA_PCI - dep_tristate ' Cyrix CS5530 MediaGX chipset support' CONFIG_BLK_DEV_CS5530 $CONFIG_BLK_DEV_IDEDMA_PCI - dep_tristate ' HPT34X chipset support' CONFIG_BLK_DEV_HPT34X $CONFIG_BLK_DEV_IDEDMA_PCI - dep_mbool ' HPT34X AUTODMA support (WIP)' CONFIG_HPT34X_AUTODMA $CONFIG_BLK_DEV_HPT34X $CONFIG_IDEDMA_PCI_WIP - dep_tristate ' HPT36X/37X chipset support' CONFIG_BLK_DEV_HPT366 $CONFIG_BLK_DEV_IDEDMA_PCI - dep_tristate ' Intel PIIXn chipsets support' CONFIG_BLK_DEV_PIIX $CONFIG_BLK_DEV_IDEDMA_PCI - if [ "$CONFIG_MIPS_ITE8172" = "y" -o "$CONFIG_MIPS_IVR" = "y" ]; then - dep_mbool ' IT8172 IDE support' CONFIG_BLK_DEV_IT8172 $CONFIG_BLK_DEV_IDEDMA_PCI - fi - 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_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 - fi - dep_tristate ' RZ1000 chipset bugfix/support' CONFIG_BLK_DEV_RZ1000 $CONFIG_X86 - dep_tristate ' SCx200 chipset support' CONFIG_BLK_DEV_SC1200 $CONFIG_BLK_DEV_IDEDMA_PCI - dep_tristate ' ServerWorks OSB4/CSB5/CSB6 chipsets support' CONFIG_BLK_DEV_SVWKS $CONFIG_BLK_DEV_IDEDMA_PCI - dep_tristate ' Silicon Image chipset support' CONFIG_BLK_DEV_SIIMAGE $CONFIG_BLK_DEV_IDEDMA_PCI - dep_tristate ' SiS5513 chipset support' CONFIG_BLK_DEV_SIS5513 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86 - dep_tristate ' SLC90E66 chipset support' CONFIG_BLK_DEV_SLC90E66 $CONFIG_BLK_DEV_IDEDMA_PCI - dep_tristate ' Tekram TRM290 chipset support' CONFIG_BLK_DEV_TRM290 $CONFIG_BLK_DEV_IDEDMA_PCI - dep_tristate ' VIA82CXXX chipset support' CONFIG_BLK_DEV_VIA82CXXX $CONFIG_BLK_DEV_IDEDMA_PCI - if [ "$CONFIG_PPC" = "y" -o "$CONFIG_ARM" = "y" ]; then - dep_tristate ' Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105 $CONFIG_BLK_DEV_IDEPCI - fi + 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 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 ' ATI IXP chipset IDE support' CONFIG_BLK_DEV_ATIIXP $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86 + 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 + dep_tristate ' CY82C693 chipset support' CONFIG_BLK_DEV_CY82C693 $CONFIG_BLK_DEV_IDEDMA_PCI + dep_tristate ' Cyrix CS5530 MediaGX chipset support' CONFIG_BLK_DEV_CS5530 $CONFIG_BLK_DEV_IDEDMA_PCI + dep_tristate ' HPT34X chipset support' CONFIG_BLK_DEV_HPT34X $CONFIG_BLK_DEV_IDEDMA_PCI + dep_mbool ' HPT34X AUTODMA support (WIP)' CONFIG_HPT34X_AUTODMA $CONFIG_BLK_DEV_HPT34X $CONFIG_IDEDMA_PCI_WIP + dep_tristate ' HPT36X/37X chipset support' CONFIG_BLK_DEV_HPT366 $CONFIG_BLK_DEV_IDEDMA_PCI + dep_tristate ' Intel PIIXn chipsets support' CONFIG_BLK_DEV_PIIX $CONFIG_BLK_DEV_IDEDMA_PCI + if [ "$CONFIG_MIPS_ITE8172" = "y" -o "$CONFIG_MIPS_IVR" = "y" ]; then + dep_mbool ' IT8172 IDE support' CONFIG_BLK_DEV_IT8172 $CONFIG_BLK_DEV_IDEDMA_PCI + fi + 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_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 + fi + dep_tristate ' RZ1000 chipset bugfix/support' CONFIG_BLK_DEV_RZ1000 $CONFIG_X86 + dep_tristate ' SCx200 chipset support' CONFIG_BLK_DEV_SC1200 $CONFIG_BLK_DEV_IDEDMA_PCI + dep_tristate ' ServerWorks OSB4/CSB5/CSB6 chipsets support' CONFIG_BLK_DEV_SVWKS $CONFIG_BLK_DEV_IDEDMA_PCI + if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ] ; then + dep_tristate ' SGI IOC4 chipset support' CONFIG_BLK_DEV_SGIIOC4 $CONFIG_BLK_DEV_IDEDMA_PCI + fi + dep_tristate ' Silicon Image chipset support' CONFIG_BLK_DEV_SIIMAGE $CONFIG_BLK_DEV_IDEDMA_PCI + dep_tristate ' SiS5513 chipset support' CONFIG_BLK_DEV_SIS5513 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86 + dep_tristate ' SLC90E66 chipset support' CONFIG_BLK_DEV_SLC90E66 $CONFIG_BLK_DEV_IDEDMA_PCI + dep_tristate ' Tekram TRM290 chipset support' CONFIG_BLK_DEV_TRM290 $CONFIG_BLK_DEV_IDEDMA_PCI + dep_tristate ' VIA82CXXX chipset support' CONFIG_BLK_DEV_VIA82CXXX $CONFIG_BLK_DEV_IDEDMA_PCI + if [ "$CONFIG_PPC" = "y" -o "$CONFIG_ARM" = "y" ]; then + dep_tristate ' Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105 $CONFIG_BLK_DEV_IDEPCI + fi fi fi if [ "$CONFIG_ALL_PPC" = "y" ]; then - bool ' Builtin PowerMac IDE support' CONFIG_BLK_DEV_IDE_PMAC - dep_bool ' Probe internal Kauai ATA/100 first' CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST $CONFIG_BLK_DEV_IDE_PMAC - dep_bool ' PowerMac IDE DMA support' CONFIG_BLK_DEV_IDEDMA_PMAC $CONFIG_BLK_DEV_IDE_PMAC - dep_bool ' Use DMA by default' CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO $CONFIG_BLK_DEV_IDEDMA_PMAC - if [ "$CONFIG_BLK_DEV_IDE_PMAC" = "y" ]; then - define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PMAC - fi - if [ "$CONFIG_BLK_DEV_IDEDMA_PMAC" = "y" ]; then - define_bool CONFIG_BLK_DEV_IDEPCI $CONFIG_BLK_DEV_IDEDMA_PMAC - fi + bool ' Builtin PowerMac IDE support' CONFIG_BLK_DEV_IDE_PMAC + dep_bool ' Probe internal Kauai ATA/100 first' CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST $CONFIG_BLK_DEV_IDE_PMAC + dep_bool ' PowerMac IDE DMA support' CONFIG_BLK_DEV_IDEDMA_PMAC $CONFIG_BLK_DEV_IDE_PMAC + dep_bool ' Use DMA by default' CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO $CONFIG_BLK_DEV_IDEDMA_PMAC + if [ "$CONFIG_BLK_DEV_IDE_PMAC" = "y" ]; then + define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PMAC + fi + if [ "$CONFIG_BLK_DEV_IDEDMA_PMAC" = "y" ]; then + define_bool CONFIG_BLK_DEV_IDEPCI $CONFIG_BLK_DEV_IDEDMA_PMAC + fi fi - if [ "$CONFIG_SIBYTE_SWARM" = "y" ]; then - bool ' Broadcom SiByte onboard IDE support' CONFIG_BLK_DEV_IDE_SIBYTE + 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 - dep_bool ' ICS IDE interface support' CONFIG_BLK_DEV_IDE_ICSIDE $CONFIG_ARCH_ACORN - dep_bool ' ICS DMA support' CONFIG_BLK_DEV_IDEDMA_ICS $CONFIG_BLK_DEV_IDE_ICSIDE - dep_bool ' Use ICS DMA by default' CONFIG_IDEDMA_ICS_AUTO $CONFIG_BLK_DEV_IDEDMA_ICS - define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_ICS - dep_bool ' RapIDE interface support' CONFIG_BLK_DEV_IDE_RAPIDE $CONFIG_ARCH_ACORN + dep_bool ' ICS IDE interface support' CONFIG_BLK_DEV_IDE_ICSIDE $CONFIG_ARCH_ACORN + dep_bool ' ICS DMA support' CONFIG_BLK_DEV_IDEDMA_ICS $CONFIG_BLK_DEV_IDE_ICSIDE + dep_bool ' Use ICS DMA by default' CONFIG_IDEDMA_ICS_AUTO $CONFIG_BLK_DEV_IDEDMA_ICS + define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_ICS + dep_bool ' RapIDE interface support' CONFIG_BLK_DEV_IDE_RAPIDE $CONFIG_ARCH_ACORN fi if [ "$CONFIG_ARCH_RISCSTATION" = "y" ]; then dep_bool ' RiscStation IDE' CONFIG_BLK_DEV_IDE_RISCSTATION $CONFIG_ARCH_RISCSTATION fi - if [ "$CONFIG_ARCH_EP9312" = "y" -o \ - "$CONFIG_ARCH_EP9315" = "y" ]; then - bool ' EP93xx IDE Support' CONFIG_BLK_DEV_EP93XX + if [ "CONFIG_ARCH_EP312" = "y" -o \ + "$CONFIG_ARCH_EP9315" = "y" ]; then + bool ' EP93xx IDE Support' CONFIG_BLK_DEV_EP93XX else - define_bool CONFIG_BLK_DEV_EP93XX n + define_bool CONFIG_BLK_DEV_EP93XX n fi if [ "$CONFIG_ARCH_EP9301" = "y" ]; then bool ' TS-7XXX Compact Flash IDE Support' CONFIG_BLK_DEV_TSCF @@ -124,43 +128,46 @@ define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_EP93XX fi if [ "$CONFIG_AMIGA" = "y" ]; then - dep_bool ' Amiga Gayle IDE interface support' CONFIG_BLK_DEV_GAYLE $CONFIG_AMIGA - dep_mbool ' Amiga IDE Doubler support (EXPERIMENTAL)' CONFIG_BLK_DEV_IDEDOUBLER $CONFIG_BLK_DEV_GAYLE $CONFIG_EXPERIMENTAL + dep_bool ' Amiga Gayle IDE interface support' CONFIG_BLK_DEV_GAYLE $CONFIG_AMIGA + dep_mbool ' Amiga IDE Doubler support (EXPERIMENTAL)' CONFIG_BLK_DEV_IDEDOUBLER $CONFIG_BLK_DEV_GAYLE $CONFIG_EXPERIMENTAL fi if [ "$CONFIG_ZORRO" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then - dep_mbool ' Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)' CONFIG_BLK_DEV_BUDDHA $CONFIG_ZORRO $CONFIG_EXPERIMENTAL + dep_mbool ' Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)' CONFIG_BLK_DEV_BUDDHA $CONFIG_ZORRO $CONFIG_EXPERIMENTAL fi if [ "$CONFIG_ATARI" = "y" ]; then - dep_bool ' Falcon IDE interface support' CONFIG_BLK_DEV_FALCON_IDE $CONFIG_ATARI + dep_bool ' Falcon IDE interface support' CONFIG_BLK_DEV_FALCON_IDE $CONFIG_ATARI + fi + if [ "$CONFIG_CPCI405" = "y" ]; then + dep_bool ' CPCI-405 IDE interface support' CONFIG_BLK_DEV_CPCI405_IDE $CONFIG_CPCI405 fi if [ "$CONFIG_MAC" = "y" ]; then - dep_bool ' Macintosh Quadra/Powerbook IDE interface support' CONFIG_BLK_DEV_MAC_IDE $CONFIG_MAC + dep_bool ' Macintosh Quadra/Powerbook IDE interface support' CONFIG_BLK_DEV_MAC_IDE $CONFIG_MAC fi if [ "$CONFIG_Q40" = "y" ]; then - dep_bool ' Q40/Q60 IDE interface support' CONFIG_BLK_DEV_Q40IDE $CONFIG_Q40 + dep_bool ' Q40/Q60 IDE interface support' CONFIG_BLK_DEV_Q40IDE $CONFIG_Q40 fi if [ "$CONFIG_8xx" = "y" ]; then dep_bool ' MPC8xx IDE support' CONFIG_BLK_DEV_MPC8xx_IDE $CONFIG_8xx fi if [ "$CONFIG_BLK_DEV_MPC8xx_IDE" = "y" ]; then - choice 'Type of MPC8xx IDE interface' \ - "8xx_PCCARD CONFIG_IDE_8xx_PCCARD \ - 8xx_DIRECT CONFIG_IDE_8xx_DIRECT \ - EXT_DIRECT CONFIG_IDE_EXT_DIRECT" 8xx_PCCARD + choice 'Type of MPC8xx IDE interface' \ + "8xx_PCCARD CONFIG_IDE_8xx_PCCARD \ + 8xx_DIRECT CONFIG_IDE_8xx_DIRECT \ + EXT_DIRECT CONFIG_IDE_EXT_DIRECT" 8xx_PCCARD fi # no isa -> no vlb dep_bool ' Other IDE chipset support' CONFIG_IDE_CHIPSETS $CONFIG_ISA if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then - comment 'Note: most of these also require special kernel boot parameters' - bool ' Generic 4 drives/port support' CONFIG_BLK_DEV_4DRIVES - dep_tristate ' ALI M14xx support' CONFIG_BLK_DEV_ALI14XX $CONFIG_BLK_DEV_IDE - dep_tristate ' DTC-2278 support' CONFIG_BLK_DEV_DTC2278 $CONFIG_BLK_DEV_IDE - dep_tristate ' Holtek HT6560B support' CONFIG_BLK_DEV_HT6560B $CONFIG_BLK_DEV_IDE - dep_tristate ' PROMISE DC4030 support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC4030 $CONFIG_BLK_DEV_IDEDISK $CONFIG_EXPERIMENTAL - dep_tristate ' QDI QD65xx support' CONFIG_BLK_DEV_QD65XX $CONFIG_BLK_DEV_IDE - dep_tristate ' UMC-8672 support' CONFIG_BLK_DEV_UMC8672 $CONFIG_BLK_DEV_IDE + comment 'Note: most of these also require special kernel boot parameters' + bool ' Generic 4 drives/port support' CONFIG_BLK_DEV_4DRIVES + dep_tristate ' ALI M14xx support' CONFIG_BLK_DEV_ALI14XX $CONFIG_BLK_DEV_IDE + dep_tristate ' DTC-2278 support' CONFIG_BLK_DEV_DTC2278 $CONFIG_BLK_DEV_IDE + dep_tristate ' Holtek HT6560B support' CONFIG_BLK_DEV_HT6560B $CONFIG_BLK_DEV_IDE + dep_tristate ' PROMISE DC4030 support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC4030 $CONFIG_BLK_DEV_IDEDISK $CONFIG_EXPERIMENTAL + dep_tristate ' QDI QD65xx support' CONFIG_BLK_DEV_QD65XX $CONFIG_BLK_DEV_IDE + dep_tristate ' UMC-8672 support' CONFIG_BLK_DEV_UMC8672 $CONFIG_BLK_DEV_IDE fi fi else @@ -201,44 +208,10 @@ ## dep_mbool CONFIG_BLK_DEV_NTF_DISK $CONFIG_BLK_DEV_IDEDISK ##fi -if [ "$CONFIG_BLK_DEV_4DRIVES" = "y" -o \ - "$CONFIG_BLK_DEV_ALI14XX" != "n" -o \ - "$CONFIG_BLK_DEV_DTC2278" != "n" -o \ - "$CONFIG_BLK_DEV_HT6560B" != "n" -o \ - "$CONFIG_BLK_DEV_PDC4030" != "n" -o \ - "$CONFIG_BLK_DEV_QD65XX" != "n" -o \ - "$CONFIG_BLK_DEV_UMC8672" != "n" -o \ - "$CONFIG_BLK_DEV_AEC62XX" = "y" -o \ - "$CONFIG_BLK_DEV_ALI15X3" = "y" -o \ - "$CONFIG_BLK_DEV_AMD74XX" = "y" -o \ - "$CONFIG_BLK_DEV_CMD640" = "y" -o \ - "$CONFIG_BLK_DEV_CMD64X" = "y" -o \ - "$CONFIG_BLK_DEV_CS5530" = "y" -o \ - "$CONFIG_BLK_DEV_CY82C693" = "y" -o \ - "$CONFIG_BLK_DEV_HPT34X" = "y" -o \ - "$CONFIG_BLK_DEV_HPT366" = "y" -o \ - "$CONFIG_BLK_DEV_IDE_PMAC" = "y" -o \ - "$CONFIG_BLK_DEV_IT8172" = "y" -o \ - "$CONFIG_BLK_DEV_MPC8xx_IDE" = "y" -o \ - "$CONFIG_BLK_DEV_NFORCE" = "y" -o \ - "$CONFIG_BLK_DEV_OPTI621" = "y" -o \ - "$CONFIG_BLK_DEV_SVWKS" = "y" -o \ - "$CONFIG_BLK_DEV_PDC202XX" = "y" -o \ - "$CONFIG_BLK_DEV_PIIX" = "y" -o \ - "$CONFIG_BLK_DEV_SVWKS" = "y" -o \ - "$CONFIG_BLK_DEV_SIIMAGE" = "y" -o \ - "$CONFIG_BLK_DEV_SIS5513" = "y" -o \ - "$CONFIG_BLK_DEV_SL82C105" = "y" -o \ - "$CONFIG_BLK_DEV_SLC90E66" = "y" -o \ - "$CONFIG_BLK_DEV_VIA82CXXX" = "y" ]; then - define_bool CONFIG_BLK_DEV_IDE_MODES y -else - define_bool CONFIG_BLK_DEV_IDE_MODES n -fi - dep_tristate 'Support for IDE Raid controllers (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL dep_tristate ' Support Promise software RAID (Fasttrak(tm)) (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID_PDC $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID dep_tristate ' Highpoint 370 software RAID (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID_HPT $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID +dep_tristate ' CMD/Silicon Image Medley Software RAID (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID_MEDLEY $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID dep_tristate ' Silicon Image Medley software RAID (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID_SII $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID endmenu Index: drivers/ide/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/Makefile 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/ide/Makefile 4 Aug 2004 01:28:53 -0000 1.2 @@ -8,9 +8,8 @@ # 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 +export-objs := ide-iops.o ide-taskfile.o ide-proc.o ide.o ide-probe.o ide-probe-mini.o ide-dma.o ide-lib.o setup-pci.o ide-io.o ide-disk.o all-subdirs := arm legacy pci ppc raid mod-subdirs := arm legacy pci ppc raid @@ -29,24 +28,28 @@ # 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-probe.o ide-geometry.o +ide-detect-objs := ide-probe-mini.o +ifeq ($(CONFIG_PROC_FS),y) +ide-core-objs += ide-proc.o +endif 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 ifeq ($(CONFIG_BLK_DEV_IDE),y) obj-y += legacy/idedriver-legacy.o @@ -54,14 +57,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) + Index: drivers/ide/ide-cd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/ide-cd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/ide-cd.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/ide/ide-cd.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -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) @@ -2226,7 +2231,7 @@ minor = (drive->select.b.unit) << PARTN_BITS; dev = MKDEV(HWIF(drive)->major, minor); stat = cdrom_get_last_written(dev, &toc->capacity); - if (stat) + if (stat || !toc->capacity) stat = cdrom_read_capacity(drive, &toc->capacity, sense); if (stat) toc->capacity = 0x1fffff; @@ -3257,7 +3262,7 @@ } if (ide_register_subdriver(drive, &ide_cdrom_driver, IDE_SUBDRIVER_VERSION)) { - printk("%s: Failed to register the driver with " + printk("ide-cd: %s: Failed to register the driver with " "ide.c\n", drive->name); kfree(info); continue; Index: drivers/ide/ide-default.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/ide-default.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/ide-default.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/ide/ide-default.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -40,6 +40,21 @@ { } +static int idedefault_open(struct inode *inode, struct file *filp, ide_drive_t *drive) +{ + MOD_INC_USE_COUNT; + if(filp->f_flags & O_NDELAY) + return 0; + MOD_DEC_USE_COUNT; + drive->usage--; + return -ENXIO; +} + +static void idedefault_release(struct inode *inode, struct file *filp, ide_drive_t *drive) +{ + MOD_DEC_USE_COUNT; +} + int idedefault_init (void); int idedefault_attach(ide_drive_t *drive); @@ -56,6 +71,8 @@ supports_dsc_overlap: 0, init: idedefault_init, attach: idedefault_attach, + open: idedefault_open, + release: idedefault_release }; static ide_module_t idedefault_module = { @@ -85,13 +102,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"); Index: drivers/ide/ide-disk.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/ide-disk.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/ide-disk.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/ide/ide-disk.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -1196,7 +1196,7 @@ drive->bios_cyl = drive->cyl; drive->capacity48 = capacity_2; drive->capacity = (unsigned long) capacity_2; - return; + goto check_capacity48; /* Determine capacity, and use LBA if the drive properly supports it */ } else if ((id->capability & 2) && lba_capacity_is_ok(id)) { capacity = id->lba_capacity; @@ -1228,6 +1228,15 @@ drive->sect = 63; drive->cyl = (unsigned long)(drive->capacity48) / (drive->head * drive->sect); } + +check_capacity48: + /* Limit disk size to 137GB if LBA48 addressing is not supported */ + if (drive->addressing == 0 && drive->capacity48 > (1ULL)<<28) { + printk("%s: cannot use LBA48 - capacity reset " + "from %llu to %llu\n", + drive->name, drive->capacity48, (1ULL)<<28); + drive->capacity48 = (1ULL)<<28; + } } static unsigned long idedisk_capacity (ide_drive_t *drive) Index: drivers/ide/ide-dma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/ide-dma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/ide-dma.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/ide/ide-dma.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -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 */ } /** Index: drivers/ide/ide-floppy.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/ide-floppy.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/ide-floppy.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/ide/ide-floppy.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -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 Index: drivers/ide/ide-geometry.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/ide-geometry.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/ide-geometry.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/ide/ide-geometry.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -83,7 +83,6 @@ } -extern ide_drive_t * get_info_ptr(kdev_t); extern unsigned long current_capacity (ide_drive_t *); /* @@ -156,7 +155,7 @@ int transl = 1; /* try translation */ int ret = 0; - drive = get_info_ptr(i_rdev); + drive = ide_info_ptr(i_rdev, 0); if (!drive) return 0; Index: drivers/ide/ide-io.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/ide-io.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/ide-io.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/ide/ide-io.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -56,38 +56,6 @@ #include "ide_modes.h" -#if (DISK_RECOVERY_TIME > 0) - -Error So the User Has To Fix the Compilation And Stop Hacking Port 0x43 -Does anyone ever use this anyway ?? - -/* - * For really screwy hardware (hey, at least it *can* be used with Linux) - * we can enforce a minimum delay time between successive operations. - */ -static unsigned long read_timer (ide_hwif_t *hwif) -{ - unsigned long t, flags; - int i; - - /* FIXME this is completely unsafe! */ - local_irq_save(flags); - t = jiffies * 11932; - outb_p(0, 0x43); - i = inb_p(0x40); - i |= inb_p(0x40) << 8; - local_irq_restore(flags); - return (t - i); -} -#endif /* DISK_RECOVERY_TIME */ - -static inline void set_recovery_timer (ide_hwif_t *hwif) -{ -#if (DISK_RECOVERY_TIME > 0) - hwif->last_time = read_timer(hwif); -#endif /* DISK_RECOVERY_TIME */ -} - /* * ide_end_request - complete an IDE I/O * @drive: IDE device for the I/O @@ -237,6 +205,7 @@ * by read a sector's worth of data from the drive. Of course, * this may not help if the drive is *waiting* for data from *us*. */ + void try_to_flush_leftover_data (ide_drive_t *drive) { int i = (drive->mult_count ? drive->mult_count : 1) * SECTOR_WORDS; @@ -573,9 +542,9 @@ EXPORT_SYMBOL(execute_drive_cmd); /** - * start_request - start of I/O and command issuing for IDE + * ide_start_request - start of I/O and command issuing for IDE * - * start_request() initiates handling of a new I/O request. It + * ide_start_request() initiates handling of a new I/O request. It * accepts commands and I/O (read/write) requests. It also does * the final remapping for weird stuff like EZDrive. Once * device mapper can work sector level the EZDrive stuff can go away @@ -583,7 +552,7 @@ * FIXME: this function needs a rename */ -ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) +static ide_startstop_t ide_start_request (ide_drive_t *drive, struct request *rq) { ide_startstop_t startstop; unsigned long block, blockend; @@ -591,12 +560,12 @@ ide_hwif_t *hwif = HWIF(drive); #ifdef DEBUG - printk("%s: start_request: current=0x%08lx\n", + printk("%s: ide_start_request: current=0x%08lx\n", hwif->name, (unsigned long) rq); #endif /* bail early if we've exceeded max_failures */ - if (drive->max_failures && (drive->failures > drive->max_failures)) { + if (!drive->present || (drive->max_failures && (drive->failures > drive->max_failures))) { goto kill_rq; } @@ -636,10 +605,6 @@ if (block == 0 && drive->remap_0_to_1 == 1) block = 1; /* redirect MBR access to EZ-Drive partn table */ -#if (DISK_RECOVERY_TIME > 0) - while ((read_timer() - hwif->last_time) < DISK_RECOVERY_TIME); -#endif - SELECT_DRIVE(drive); if (ide_wait_stat(&startstop, drive, drive->ready_stat, BUSY_STAT|DRQ_STAT, WAIT_READY)) { printk(KERN_ERR "%s: drive not ready for command\n", drive->name); @@ -663,16 +628,6 @@ return ide_stopped; } -EXPORT_SYMBOL(start_request); - -int restart_request (ide_drive_t *drive, struct request *rq) -{ - (void) start_request(drive, rq); - return 0; -} - -EXPORT_SYMBOL(restart_request); - /** * ide_stall_queue - pause an IDE device * @drive: drive to stall @@ -865,7 +820,7 @@ spin_unlock(&io_request_lock); local_irq_enable(); /* allow other IRQs while we start this request */ - startstop = start_request(drive, rq); + startstop = ide_start_request(drive, rq); spin_lock_irq(&io_request_lock); if (hwif->irq != masked_irq) enable_irq(hwif->irq); @@ -896,15 +851,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 +872,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 +904,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 +928,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 +957,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 +993,14 @@ 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; } @@ -1227,7 +1190,6 @@ * same irq as is currently being serviced here, and Linux * won't allow another of the same (on any CPU) until we return. */ - set_recovery_timer(HWIF(drive)); drive->service_time = jiffies - drive->service_start; if (startstop == ide_stopped) { if (hwgroup->handler == NULL) { /* paranoia */ @@ -1247,7 +1209,7 @@ * get_info_ptr() returns the (ide_drive_t *) for a given device number. * It returns NULL if the given device number does not match any present drives. */ -ide_drive_t *get_info_ptr (kdev_t i_rdev) +ide_drive_t *ide_info_ptr (kdev_t i_rdev, int force) { int major = MAJOR(i_rdev); unsigned int h; @@ -1258,7 +1220,7 @@ unsigned unit = DEVICE_NR(i_rdev); if (unit < MAX_DRIVES) { ide_drive_t *drive = &hwif->drives[unit]; - if (drive->present) + if (drive->present || force) return drive; } break; @@ -1267,7 +1229,7 @@ return NULL; } -EXPORT_SYMBOL(get_info_ptr); +EXPORT_SYMBOL(ide_info_ptr); /** * ide_init_drive_cmd - initialize a drive command request Index: drivers/ide/ide-iops.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/ide-iops.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/ide-iops.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/ide/ide-iops.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -666,6 +666,15 @@ timeout += jiffies; while ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) { if (time_after(jiffies, timeout)) { + /* + * One last read after the timeout in case + * heavy interrupt load made us not make any + * progress during the timeout.. + */ + stat = hwif->INB(IDE_STATUS_REG); + if (!(stat & BUSY_STAT)) + break; + local_irq_restore(flags); *startstop = DRIVER(drive)->error(drive, "status timeout", stat); return 1; @@ -741,6 +750,10 @@ int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) { + /* SATA has no cable restrictions */ + if (HWIF(drive)->sata) + return 0; + if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) && (args->tfRegister[IDE_SECTOR_OFFSET] > XFER_UDMA_2) && (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) { Index: drivers/ide/ide-pnp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/ide-pnp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/ide-pnp.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/ide/ide-pnp.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -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"); Index: drivers/ide/ide-probe.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/ide-probe.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/ide-probe.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/ide/ide-probe.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -102,7 +102,8 @@ if (id->config == 0x848a) return 1; /* CompactFlash */ if (!strncmp(id->model, "KODAK ATA_FLASH", 15) /* Kodak */ || !strncmp(id->model, "Hitachi CV", 10) /* Hitachi */ - || !strncmp(id->model, "SunDisk SDCFB", 13) /* SunDisk */ + || !strncmp(id->model, "SunDisk SDCFB", 13) /* old SanDisk */ + || !strncmp(id->model, "SanDisk SDCFB", 13) /* SanDisk */ || !strncmp(id->model, "HAGIWARA HPC", 12) /* Hagiwara */ || !strncmp(id->model, "LEXAR ATA_FLASH", 15) /* Lexar */ || !strncmp(id->model, "ATA_FLASH", 9)) /* Simple Tech */ @@ -553,7 +554,7 @@ } /** - * probe_for_drives - upper level drive probe + * ide_probe_for_drives - upper level drive probe * @drive: drive to probe for * * probe_for_drive() tests for existence of a given drive using do_probe() @@ -564,7 +565,7 @@ * still be 0) */ -static inline u8 probe_for_drive (ide_drive_t *drive) +u8 ide_probe_for_drive (ide_drive_t *drive) { /* * In order to keep things simple we have an id @@ -687,9 +688,6 @@ //EXPORT_SYMBOL(hwif_register); -/* Enable code below on all archs later, for now, I want it on PPC - */ -#ifdef CONFIG_PPC /* * This function waits for the hwif to report a non-busy status * see comments in probe_hwif() @@ -716,7 +714,7 @@ return ((stat & BUSY_STAT) == 0) ? 0 : -EBUSY; } -static int wait_hwif_ready(ide_hwif_t *hwif) +int ide_wait_hwif_ready(ide_hwif_t *hwif) { int rc; @@ -751,7 +749,67 @@ return rc; } -#endif /* CONFIG_PPC */ + +void ide_probe_reset(ide_hwif_t *hwif) +{ + if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) { + unsigned long timeout = jiffies + WAIT_WORSTCASE; + u8 stat; + + printk(KERN_WARNING "%s: reset\n", hwif->name); + hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]); + udelay(10); + hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); + do { + ide_delay_50ms(); + stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]); + } while ((stat & BUSY_STAT) && time_after(timeout, jiffies)); + } +} + +void ide_tune_drives(ide_hwif_t *hwif) +{ + int unit; + + for (unit = 0; unit < MAX_DRIVES; ++unit) { + ide_drive_t *drive = &hwif->drives[unit]; + int enable_dma = 1; + + if (drive->present) { + if (hwif->tuneproc != NULL && + drive->autotune == IDE_TUNE_AUTO) + /* auto-tune PIO mode */ + hwif->tuneproc(drive, 255); + +#ifdef CONFIG_IDEDMA_ONLYDISK + if (drive->media != ide_disk) + enable_dma = 0; +#endif + /* + * MAJOR HACK BARF :-/ + * + * FIXME: chipsets own this cruft! + */ + /* + * Move here to prevent module loading clashing. + */ + // drive->autodma = hwif->autodma; + if ((hwif->ide_dma_check) && + ((drive->autotune == IDE_TUNE_DEFAULT) || + (drive->autotune == IDE_TUNE_AUTO))) { + /* + * Force DMAing for the beginning of the check. + * Some chipsets appear to do interesting + * things, if not checked and cleared. + * PARANOIA!!! + */ + hwif->ide_dma_off_quietly(drive); + if (enable_dma) + hwif->ide_dma_check(drive); + } + } + } +} /* * This routine only knows how to look for drive units 0 and 1 @@ -822,7 +880,7 @@ * * BenH. */ - if (wait_hwif_ready(hwif)) + if (ide_wait_hwif_ready(hwif)) printk(KERN_WARNING "%s: Wait for ready failed before probe !\n", hwif->name); #endif /* CONFIG_PPC */ @@ -834,7 +892,7 @@ ide_drive_t *drive = &hwif->drives[unit]; drive->dn = ((hwif->channel ? 2 : 0) + unit); hwif->drives[unit].dn = ((hwif->channel ? 2 : 0) + unit); - (void) probe_for_drive(drive); + (void) ide_probe_for_drive(drive); if (drive->present && !hwif->present) { hwif->present = 1; if (hwif->chipset != ide_4drives || @@ -844,20 +902,8 @@ } } } - if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) { - unsigned long timeout = jiffies + WAIT_WORSTCASE; - u8 stat; - - printk(KERN_WARNING "%s: reset\n", hwif->name); - hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]); - udelay(10); - hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); - do { - ide_delay_50ms(); - stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]); - } while ((stat & BUSY_STAT) && time_after(timeout, jiffies)); - - } + + ide_probe_reset(hwif); local_irq_restore(flags); /* * Use cached IRQ number. It might be (and is...) changed by probe @@ -865,45 +911,9 @@ */ if (irqd) enable_irq(irqd); + + ide_tune_drives(hwif); - for (unit = 0; unit < MAX_DRIVES; ++unit) { - ide_drive_t *drive = &hwif->drives[unit]; - int enable_dma = 1; - - if (drive->present) { - if (hwif->tuneproc != NULL && - drive->autotune == IDE_TUNE_AUTO) - /* auto-tune PIO mode */ - hwif->tuneproc(drive, 255); - -#ifdef CONFIG_IDEDMA_ONLYDISK - if (drive->media != ide_disk) - enable_dma = 0; -#endif - /* - * MAJOR HACK BARF :-/ - * - * FIXME: chipsets own this cruft! - */ - /* - * Move here to prevent module loading clashing. - */ - // drive->autodma = hwif->autodma; - if ((hwif->ide_dma_check) && - ((drive->autotune == IDE_TUNE_DEFAULT) || - (drive->autotune == IDE_TUNE_AUTO))) { - /* - * Force DMAing for the beginning of the check. - * Some chipsets appear to do interesting - * things, if not checked and cleared. - * PARANOIA!!! - */ - hwif->ide_dma_off_quietly(drive); - if (enable_dma) - hwif->ide_dma_check(drive); - } - } - } } EXPORT_SYMBOL(probe_hwif); @@ -971,6 +981,7 @@ q->queuedata = HWGROUP(drive); blk_init_queue(q, do_ide_request); + blk_queue_throttle_sectors(q, 1); } #undef __IRQ_HELL_SPIN @@ -1334,13 +1345,6 @@ EXPORT_SYMBOL(export_ide_init_queue); -u8 export_probe_for_drive (ide_drive_t *drive) -{ - return probe_for_drive(drive); -} - -EXPORT_SYMBOL(export_probe_for_drive); - #ifndef HWIF_PROBE_CLASSIC_METHOD int probe_hwif_init (ide_hwif_t *hwif) { @@ -1413,22 +1417,30 @@ #ifdef MODULE extern int (*ide_xlate_1024_hook)(kdev_t, int, int, const char *); -int init_module (void) +static int ideprobe_done = 0; + +int ideprobe_init_module (void) { unsigned int index; + + if (ideprobe_done) + return -EBUSY; for (index = 0; index < MAX_HWIFS; ++index) ide_unregister(index); ideprobe_init(); create_proc_ide_interfaces(); ide_xlate_1024_hook = ide_xlate_1024; + ideprobe_done++; return 0; } -void cleanup_module (void) +void ideprobe_cleanup_module (void) { ide_probe = NULL; ide_xlate_1024_hook = 0; } +EXPORT_SYMBOL(ideprobe_init_module); +EXPORT_SYMBOL(ideprobe_cleanup_module); MODULE_LICENSE("GPL"); #endif /* MODULE */ Index: drivers/ide/ide-proc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/ide-proc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/ide-proc.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/ide/ide-proc.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -795,7 +795,6 @@ for (d = 0; d < MAX_DRIVES; d++) { ide_drive_t *drive = &hwif->drives[d]; - ide_driver_t *driver = drive->driver; if (!drive->present) continue; @@ -803,13 +802,8 @@ continue; drive->proc = proc_mkdir(drive->name, parent); - if (drive->proc) { + if (drive->proc) ide_add_proc_entries(drive->proc, generic_drive_entries, drive); - if (driver) { - ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive); - ide_add_proc_entries(drive->proc, driver->proc, drive); - } - } sprintf(name,"ide%d/%s", (drive->name[2]-'a')/2, drive->name); ent = proc_symlink(drive->name, proc_ide_root, name); if (!ent) return; @@ -818,35 +812,6 @@ EXPORT_SYMBOL(create_proc_ide_drives); -void recreate_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive) -{ - struct proc_dir_entry *ent; - struct proc_dir_entry *parent = hwif->proc; - char name[64]; -// ide_driver_t *driver = drive->driver; - - if (drive->present && !drive->proc) { - drive->proc = proc_mkdir(drive->name, parent); - if (drive->proc) - ide_add_proc_entries(drive->proc, generic_drive_entries, drive); - -/* - * assume that we have these already, however, should test FIXME! - * if (driver) { - * ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive); - * ide_add_proc_entries(drive->proc, driver->proc, drive); - * } - * - */ - sprintf(name,"ide%d/%s", (drive->name[2]-'a')/2, drive->name); - ent = proc_symlink(drive->name, proc_ide_root, name); - if (!ent) - return; - } -} - -EXPORT_SYMBOL(recreate_proc_ide_device); - void destroy_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive) { ide_driver_t *driver = drive->driver; @@ -983,16 +948,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); Index: drivers/ide/ide-tape.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/ide-tape.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/ide-tape.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/ide/ide-tape.c 4 Aug 2004 01:28:53 -0000 1.2 @@ -1,9 +1,9 @@ /* - * linux/drivers/ide/ide-tape.c Version 1.17b Dec, 2002 + * linux/drivers/ide/ide-tape.c Version 1.17c Sep, 2003 * * Copyright (C) 1995 - 1999 Gadi Oxman * - * $Header: /cvsroot/ts-7200/dist/linux24/drivers/ide/ide-tape.c,v 1.1 2004/07/22 19:49:29 joff Exp $ + * $Header: /cvsroot/ts-7200/dist/linux24/drivers/ide/ide-tape.c,v 1.2 2004/08/04 01:28:53 joff Exp $ * * This driver was constructed as a student project in the software laboratory * of the faculty of electrical engineering in the Technion - Israel's @@ -313,6 +313,9 @@ * Cosmetic fixes to miscellaneous debugging output messages. * Set the minimum /proc/ide/hd?/settings values for "pipeline", * "pipeline_min", and "pipeline_max" to 1. + * Ver 1.17c Sep 2003 Stuart Hayes + * Initialized "feature" in idetape_issue_packet_command + * (this was causing lockups on certain systems) * * Here are some words from the first releases of hd.c, which are quoted * in ide.c and apply here as well: @@ -422,7 +425,7 @@ * sharing a (fast) ATA-2 disk with any (slow) new ATAPI device. */ -#define IDETAPE_VERSION "1.17b-ac1" +#define IDETAPE_VERSION "1.17c" #include #include @@ -2367,6 +2370,8 @@ atapi_feature_t feature; atapi_bcount_t bcount; + feature.all = 0; + #if IDETAPE_DEBUG_BUGS if (tape->pc->c[0] == IDETAPE_REQUEST_SENSE_CMD && pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) { Index: drivers/ide/ide-timing.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/ide-timing.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/ide-timing.h 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/ide/ide-timing.h 4 Aug 2004 01:28:54 -0000 1.2 @@ -2,7 +2,7 @@ #define _IDE_TIMING_H /* - * $Id: ide-timing.h,v 1.1 2004/07/22 19:49:29 joff Exp $ + * $Id: ide-timing.h,v 1.2 2004/08/04 01:28:54 joff Exp $ * * Copyright (c) 1999-2001 Vojtech Pavlik */ Index: drivers/ide/ide.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/ide.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/ide.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/ide/ide.c 4 Aug 2004 01:28:54 -0000 1.2 @@ -239,6 +239,7 @@ hwif->ultra_mask = 0x80; /* disable all ultra */ hwif->mwdma_mask = 0x80; /* disable all mwdma */ hwif->swdma_mask = 0x80; /* disable all swdma */ + hwif->sata = 0; /* assume PATA */ default_hwif_iops(hwif); default_hwif_transport(hwif); @@ -472,7 +473,7 @@ unsigned int p, major, minor; unsigned long flags; - if ((drive = get_info_ptr(i_rdev)) == NULL) + if ((drive = ide_info_ptr(i_rdev, 0)) == NULL) return -ENODEV; major = MAJOR(i_rdev); minor = drive->select.b.unit << PARTN_BITS; @@ -561,30 +562,48 @@ static int ide_open (struct inode * inode, struct file * filp) { ide_drive_t *drive; + int force = 1/*FIXME 0*/; + + if(capable(CAP_SYS_ADMIN) && (filp->f_flags & O_NDELAY)) + force = 1; - if ((drive = get_info_ptr(inode->i_rdev)) == NULL) + if ((drive = ide_info_ptr(inode->i_rdev, force)) == NULL) return -ENXIO; - if (drive->driver == &idedefault_driver) - ide_driver_module(1); - if (drive->driver == &idedefault_driver) { - if (drive->media == ide_disk) - (void) request_module("ide-disk"); - if (drive->scsi) - (void) request_module("ide-scsi"); - if (drive->media == ide_cdrom) - (void) request_module("ide-cd"); - if (drive->media == ide_tape) - (void) request_module("ide-tape"); - if (drive->media == ide_floppy) - (void) request_module("ide-floppy"); + + /* + * If the device is present make sure that we attach any + * needed driver + */ + + if (drive->present) + { + if (drive->driver == &idedefault_driver) + ide_driver_module(1); + if (drive->driver == &idedefault_driver) { + if (drive->media == ide_disk) + (void) request_module("ide-disk"); + if (drive->scsi) + (void) request_module("ide-scsi"); + if (drive->media == ide_cdrom) + (void) request_module("ide-cd"); + if (drive->media == ide_tape) + (void) request_module("ide-tape"); + if (drive->media == ide_floppy) + (void) request_module("ide-floppy"); + } + + /* The locking here isnt enough, but this is hard to fix + in the 2.4 cases */ + while (drive->busy) + sleep_on(&drive->wqueue); } - /* The locking here isnt enough, but this is hard to fix - in the 2.4 cases */ - while (drive->busy) - sleep_on(&drive->wqueue); + /* + * Now do the actual open + */ + drive->usage++; - if (!drive->dead) + if (!drive->dead || force) return DRIVER(drive)->open(inode, filp, drive); printk(KERN_WARNING "%s: driver not present\n", drive->name); drive->usage--; @@ -599,7 +618,7 @@ { ide_drive_t *drive; - if ((drive = get_info_ptr(inode->i_rdev)) != NULL) { + if ((drive = ide_info_ptr(inode->i_rdev, 1)) != NULL) { drive->usage--; DRIVER(drive)->release(inode, file, drive); } @@ -650,6 +669,179 @@ extern void init_hwif_data(unsigned int index); +/** + * ide_prepare_tristate - prepare interface for warm unplug + * @drive: drive on this hwif we are using + * + * Prepares a drive for shutdown after a bus tristate. The + * drives must be quiescent and the only user the calling ioctl + */ + +static int ide_prepare_tristate(ide_drive_t *our_drive) +{ + ide_drive_t *drive; + int unit; + unsigned long flags; + int minor; + int p; + int i; + ide_hwif_t *hwif = HWIF(our_drive); + + if(our_drive->busy) + printk("HUH? We are busy.\n"); + + if (!hwif->present) + BUG(); + spin_lock_irqsave(&io_request_lock, flags); + + /* Abort if anything is busy */ + for (unit = 0; unit < MAX_DRIVES; ++unit) { + drive = &hwif->drives[unit]; + if (!drive->present) + continue; + if (drive == our_drive && drive->usage != 1) + goto abort; + if (drive != our_drive && drive->usage) + goto abort; + if (drive->busy) + goto abort; + } + /* Commit to shutdown sequence */ + for (unit = 0; unit < MAX_DRIVES; ++unit) { + drive = &hwif->drives[unit]; + if (!drive->present) + continue; + if (drive != our_drive && DRIVER(drive)->shutdown(drive)) + goto abort; + } + /* We hold the lock here.. which is important as we need to play + with usage counts beyond the scenes */ + + our_drive->usage--; + i = DRIVER(our_drive)->shutdown(our_drive); + if(i) + goto abort_fix; + /* Drive shutdown sequence done */ + /* Prevent new opens ?? */ + spin_unlock_irqrestore(&io_request_lock, flags); + /* + * Flush kernel side caches, and dump the /proc files + */ + spin_unlock_irqrestore(&io_request_lock, flags); + for (unit = 0; unit < MAX_DRIVES; ++unit) { + drive = &hwif->drives[unit]; + if (!drive->present) + continue; + DRIVER(drive)->cleanup(drive); + minor = drive->select.b.unit << PARTN_BITS; + for (p = 0; p < (1<part[p].nr_sects > 0) { + kdev_t devp = MKDEV(hwif->major, minor+p); + invalidate_device(devp, 0); + } + } +#ifdef CONFIG_PROC_FS + destroy_proc_ide_drives(hwif); +#endif + } + spin_lock_irqsave(&io_request_lock, flags); + our_drive->usage++; + for (i = 0; i < MAX_DRIVES; ++i) { + drive = &hwif->drives[i]; + if (drive->de) { + devfs_unregister(drive->de); + drive->de = NULL; + } + if (!drive->present) + continue; + if (drive->id != NULL) { + kfree(drive->id); + drive->id = NULL; + } + drive->present = 0; + /* Safe to clear now */ + drive->dead = 0; + } + spin_unlock_irqrestore(&io_request_lock, flags); + return 0; + +abort_fix: + our_drive->usage++; +abort: + spin_unlock_irqrestore(&io_request_lock, flags); + return -EBUSY; +} + + +/** + * ide_resume_hwif - return a hwif to active mode + * @hwif: interface to resume + * + * Restore a dead interface from tristate back to normality. At this + * point the hardware driver busproc has reconnected the bus, but + * nothing else has happened + */ + +static int ide_resume_hwif(ide_drive_t *our_drive) +{ + ide_hwif_t *hwif = HWIF(our_drive); + int err = ide_wait_hwif_ready(hwif); + int irqd; + int present = 0; + int unit; + + if(err) + { + printk(KERN_ERR "%s: drives not ready.\n", our_drive->name); + return err; + } + + /* The drives are now taking commands */ + + irqd = hwif->irq; + if(irqd) + disable_irq(irqd); + + /* Identify and probe the drives */ + + for (unit = 0; unit < MAX_DRIVES; ++unit) { + ide_drive_t *drive = &hwif->drives[unit]; + drive->dn = ((hwif->channel ? 2 : 0) + unit); + drive->usage = 0; + drive->busy = 0; + hwif->drives[unit].dn = ((hwif->channel ? 2 : 0) + unit); + (void) ide_probe_for_drive(drive); + if (drive->present) + present = 1; + } + ide_probe_reset(hwif); + if(irqd) + enable_irq(irqd); + + if(present) + printk(KERN_INFO "ide: drives found on hot-added interface.\n"); + + /* + * Set up the drive modes (Even if we didnt swap drives + * we may have lost settings when we disconnected the bus) + */ + + ide_tune_drives(hwif); + if(present) + hwif->present = 1; + + /* + * Reattach the devices to drivers + */ + for (unit = 0; unit < MAX_DRIVES; ++unit) { + ide_drive_t *drive = &hwif->drives[unit]; + if(drive->present && !drive->dead) + ide_attach_drive(drive); + } + our_drive->usage++; + return 0; +} + int ide_unregister (unsigned int index) { struct gendisk *gd; @@ -812,6 +1004,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; @@ -1428,6 +1621,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. @@ -1545,11 +1740,22 @@ struct request rq; kdev_t dev; ide_settings_t *setting; - + int force = 0; + if (!inode || !(dev = inode->i_rdev)) return -EINVAL; + + switch(cmd) + { + case HDIO_GET_BUSSTATE: + case HDIO_SET_BUSSTATE: + case HDIO_SCAN_HWIF: + case HDIO_UNREGISTER_HWIF: + force = 1; + } + major = MAJOR(dev); minor = MINOR(dev); - if ((drive = get_info_ptr(inode->i_rdev)) == NULL) + if ((drive = ide_info_ptr(inode->i_rdev, force)) == NULL) return -ENODEV; down(&ide_setting_sem); @@ -1748,11 +1954,42 @@ return 0; case HDIO_SET_BUSSTATE: + { + ide_hwif_t *hwif = HWIF(drive); + if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if (HWIF(drive)->busproc) +#ifdef OLD_STUFF + if (hwif->busproc) return HWIF(drive)->busproc(drive, (int)arg); return -EOPNOTSUPP; +#else + if(hwif->bus_state == arg) + return 0; + + if(hwif->bus_state == BUSSTATE_ON) + { + /* "drive" may vanish beyond here */ + if((err = ide_prepare_tristate(drive)) != 0) + return err; + hwif->bus_state = arg; + } + if (hwif->busproc) + { + err = hwif->busproc(drive, (int)arg); + if(err) + return err; + } + if(arg != BUSSTATE_OFF) + { + err = ide_resume_hwif(drive); + hwif->bus_state = arg; + if(err) + return err; + } + return 0; +#endif + } default: return DRIVER(drive)->ioctl(drive, inode, file, cmd, arg); @@ -1764,7 +2001,7 @@ { ide_drive_t *drive; - if ((drive = get_info_ptr(i_rdev)) == NULL) + if ((drive = ide_info_ptr(i_rdev, 0)) == NULL) return -ENODEV; return DRIVER(drive)->media_change(drive); } @@ -2124,8 +2361,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 */ @@ -2224,6 +2461,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) @@ -2234,25 +2509,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); @@ -2301,6 +2568,12 @@ macide_init(); } #endif /* CONFIG_BLK_DEV_MAC_IDE */ +#ifdef CONFIG_BLK_DEV_CPCI405_IDE + { + extern void cpci405ide_init(void); + cpci405ide_init(); + } +#endif /* CONFIG_BLK_DEV_CPCI405_IDE */ #ifdef CONFIG_BLK_DEV_Q40IDE { extern void q40ide_init(void); @@ -2313,12 +2586,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) @@ -2375,6 +2642,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 (); @@ -2605,8 +2876,10 @@ drive->revalidate = 1; drive->suspend_reset = 0; #ifdef CONFIG_PROC_FS - ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive); - ide_add_proc_entries(drive->proc, driver->proc, drive); + if (drive->driver != &idedefault_driver) { + ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive); + ide_add_proc_entries(drive->proc, driver->proc, drive); + } #endif return 0; } @@ -2624,9 +2897,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); Index: drivers/ide/setup-pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/setup-pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/setup-pci.c 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/ide/setup-pci.c 4 Aug 2004 01:28:54 -0000 1.2 @@ -137,7 +137,7 @@ "native PCI mode\n", name); return -EOPNOTSUPP; } - printk("%s: placing both ports into native PCI mode\n", name); + printk(KERN_INFO "%s: placing both ports into native PCI mode\n", name); (void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5); if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) || (progif & 5) != 5) { @@ -172,7 +172,7 @@ * is already in DMA mode we check and enforce IDE simplex rules. */ -static unsigned long __init ide_get_or_set_dma_base (ide_hwif_t *hwif) +static unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif) { unsigned long dma_base = 0; struct pci_dev *dev = hwif->pci_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) ? Index: drivers/ide/legacy/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/legacy/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/legacy/Makefile 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/legacy/Makefile 4 Aug 2004 01:28:54 -0000 1.2 @@ -17,8 +17,11 @@ obj-$(CONFIG_BLK_DEV_MAC_IDE) += macide.o obj-$(CONFIG_BLK_DEV_Q40IDE) += q40ide.o +obj-$(CONFIG_BLK_DEV_IDE_SIBYTE) += sibyte.o + obj-$(CONFIG_BLK_DEV_IDECS) += ide-cs.o + # Last of all obj-$(CONFIG_BLK_DEV_HD) += hd.o Index: drivers/ide/legacy/buddha.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/legacy/buddha.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/legacy/buddha.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/legacy/buddha.c 4 Aug 2004 01:28:54 -0000 1.2 @@ -146,6 +146,7 @@ void __init buddha_init(void) { hw_regs_t hw; + ide_hwif_t *hwif; int i, index; struct zorro_dev *z = NULL; @@ -212,8 +213,9 @@ IRQ_AMIGA_PORTS); } - index = ide_register_hw(&hw, NULL); + index = ide_register_hw(&hw, &hwif); if (index != -1) { + hwif->mmio = 2; printk("ide%d: ", index); switch(type) { case BOARD_BUDDHA: Index: drivers/ide/legacy/gayle.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/legacy/gayle.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/legacy/gayle.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/legacy/gayle.c 4 Aug 2004 01:28:54 -0000 1.2 @@ -29,7 +29,7 @@ */ #define GAYLE_BASE_4000 0xdd2020 /* A4000/A4000T */ -#define GAYLE_BASE_1200 0xda0000 /* A1200/A600 */ +#define GAYLE_BASE_1200 0xda0000 /* A1200/A600 and E-Matrix 530 */ /* * Offsets from one of the above bases @@ -118,9 +118,17 @@ if (!MACH_IS_AMIGA) return; - if (!(a4000 = AMIGAHW_PRESENT(A4000_IDE)) && !AMIGAHW_PRESENT(A1200_IDE)) - return; + if ((a4000 = AMIGAHW_PRESENT(A4000_IDE)) || AMIGAHW_PRESENT(A1200_IDE)) + goto found; + +#ifdef CONFIG_ZORRO + if (zorro_find_device(ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530_SCSI_IDE, + NULL)) + goto found; +#endif + return; +found: for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) { ide_ioreg_t base, ctrlport, irqport; ide_ack_intr_t *ack_intr; @@ -174,16 +182,5 @@ } } else release_mem_region(res_start, res_n); - -#if 1 /* TESTING */ - if (i == 1) { - volatile u_short *addr = (u_short *)base; - u_short data; - printk("+++ Probing for IDE doubler... "); - *addr = 0xffff; - data = *addr; - printk("probe returned 0x%02x (PLEASE REPORT THIS!!)\n", data); - } -#endif /* TESTING */ } } Index: drivers/ide/legacy/pdc4030.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/legacy/pdc4030.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/legacy/pdc4030.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/legacy/pdc4030.c 4 Aug 2004 01:28:54 -0000 1.2 @@ -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 Index: drivers/ide/pci/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/pci/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/pci/Makefile 22 Jul 2004 19:49:29 -0000 1.1 +++ drivers/ide/pci/Makefile 4 Aug 2004 01:28:54 -0000 1.2 @@ -8,6 +8,7 @@ obj-$(CONFIG_BLK_DEV_AEC62XX) += aec62xx.o obj-$(CONFIG_BLK_DEV_ALI15X3) += alim15x3.o obj-$(CONFIG_BLK_DEV_AMD74XX) += amd74xx.o +obj-$(CONFIG_BLK_DEV_ATIIXP) += atiixp.o obj-$(CONFIG_BLK_DEV_CMD640) += cmd640.o obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o @@ -24,6 +25,7 @@ obj-$(CONFIG_BLK_DEV_RZ1000) += rz1000.o obj-$(CONFIG_BLK_DEV_SVWKS) += serverworks.o obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o +obj-$(CONFIG_BLK_DEV_SGIIOC4) += sgiioc4.o obj-$(CONFIG_BLK_DEV_SIIMAGE) += siimage.o obj-$(CONFIG_BLK_DEV_SIS5513) += sis5513.o obj-$(CONFIG_BLK_DEV_SL82C105) += sl82c105.o Index: drivers/ide/pci/alim15x3.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/pci/alim15x3.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/pci/alim15x3.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/pci/alim15x3.c 4 Aug 2004 01:28:54 -0000 1.2 @@ -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); } Index: drivers/ide/pci/amd74xx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/pci/amd74xx.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/pci/amd74xx.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/pci/amd74xx.c 4 Aug 2004 01:28:54 -0000 1.2 @@ -1,7 +1,7 @@ /* - * Version 2.10 + * Version 2.13 * - * AMD 755/756/766/8111 and nVidia nForce IDE driver for Linux. + * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s IDE driver for Linux. * * Copyright (c) 2000-2002 Vojtech Pavlik * @@ -40,9 +40,11 @@ #define AMD_UDMA_33 0x01 #define AMD_UDMA_66 0x02 #define AMD_UDMA_100 0x03 +#define AMD_UDMA_133 0x04 #define AMD_CHECK_SWDMA 0x08 #define AMD_BAD_SWDMA 0x10 #define AMD_BAD_FIFO 0x20 +#define AMD_CHECK_SERENADE 0x40 /* * AMD SouthBridge chips. @@ -50,29 +52,32 @@ static struct amd_ide_chip { unsigned short id; - unsigned char rev; unsigned long base; unsigned char flags; } amd_ide_chips[] = { - { PCI_DEVICE_ID_AMD_COBRA_7401, 0x00, 0x40, AMD_UDMA_33 | AMD_BAD_SWDMA }, /* AMD-755 Cobra */ - { PCI_DEVICE_ID_AMD_VIPER_7409, 0x00, 0x40, AMD_UDMA_66 | AMD_CHECK_SWDMA }, /* AMD-756 Viper */ - { PCI_DEVICE_ID_AMD_VIPER_7411, 0x00, 0x40, AMD_UDMA_100 | AMD_BAD_FIFO }, /* AMD-766 Viper */ - { PCI_DEVICE_ID_AMD_OPUS_7441, 0x00, 0x40, AMD_UDMA_100 }, /* AMD-768 Opus */ - { PCI_DEVICE_ID_AMD_8111_IDE, 0x00, 0x40, AMD_UDMA_100 }, /* AMD-8111 */ - { PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, 0x00, 0x50, AMD_UDMA_100 }, /* nVidia nForce */ - { PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, 0x00, 0x50, AMD_UDMA_100 }, /* nVidia nForce */ - + { PCI_DEVICE_ID_AMD_COBRA_7401, 0x40, AMD_UDMA_33 | AMD_BAD_SWDMA }, + { PCI_DEVICE_ID_AMD_VIPER_7409, 0x40, AMD_UDMA_66 | AMD_CHECK_SWDMA }, + { PCI_DEVICE_ID_AMD_VIPER_7411, 0x40, AMD_UDMA_100 | AMD_BAD_FIFO }, + { PCI_DEVICE_ID_AMD_OPUS_7441, 0x40, AMD_UDMA_100 }, + { PCI_DEVICE_ID_AMD_8111_IDE, 0x40, AMD_UDMA_133 | AMD_CHECK_SERENADE }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, 0x50, AMD_UDMA_100 }, + { PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, 0x50, AMD_UDMA_133 }, + { PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE, 0x50, AMD_UDMA_133 }, + { PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA, 0x50, AMD_UDMA_133 }, + { PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE, 0x50, AMD_UDMA_133 }, + { PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE, 0x50, AMD_UDMA_133 }, + { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, 0x50, AMD_UDMA_133 }, + { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, 0x50, AMD_UDMA_133 }, { 0 } }; static struct amd_ide_chip *amd_config; -static unsigned char amd_enabled; +static ide_pci_device_t *amd_chipset; static unsigned int amd_80w; static unsigned int amd_clock; -static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3 }; -static unsigned char amd_udma2cyc[] = { 4, 6, 8, 10, 3, 2, 1, 1 }; -static char *amd_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100" }; +static char *amd_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" }; +static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 7 }; /* * AMD /proc entry. @@ -83,6 +88,7 @@ #include #include +static unsigned char amd_udma2cyc[] = { 4, 6, 8, 10, 3, 2, 1, 15 }; static unsigned long amd_base; static struct pci_dev *bmide_dev; extern int (*amd74xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */ @@ -104,7 +110,7 @@ amd_print("----------AMD BusMastering IDE Configuration----------------"); - amd_print("Driver Version: 2.10"); + amd_print("Driver Version: 2.13"); amd_print("South Bridge: %s", bmide_dev->name); pci_read_config_byte(dev, PCI_REVISION_ID, &t); @@ -155,6 +161,12 @@ continue; } + if (den[i] && uen[i] && udma[i] == 15) { + speed[i] = amd_clock * 4; + cycle[i] = 500000 / amd_clock; + continue; + } + speed[i] = 4 * amd_clock / ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2); cycle[i] = 1000000 * ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2) / amd_clock / 2; } @@ -200,6 +212,7 @@ case AMD_UDMA_33: t = timing->udma ? (0xc0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; case AMD_UDMA_66: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 2, 10)]) : 0x03; break; case AMD_UDMA_100: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 10)]) : 0x03; break; + case AMD_UDMA_133: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 15)]) : 0x03; break; default: return; } @@ -234,6 +247,7 @@ } if (speed == XFER_UDMA_5 && amd_clock <= 33333) t.udma = 1; + if (speed == XFER_UDMA_6 && amd_clock <= 33333) t.udma = 15; amd_set_speed(HWIF(drive)->pci_dev, drive->dn, &t); @@ -251,9 +265,6 @@ static void amd74xx_tune_drive(ide_drive_t *drive, u8 pio) { - if (!((amd_enabled >> HWIF(drive)->channel) & 1)) - return; - if (pio == 255) { amd_set_drive(drive, ide_find_best_mode(drive, XFER_PIO | XFER_EPIO)); return; @@ -276,7 +287,8 @@ XFER_PIO | XFER_EPIO | XFER_MWDMA | XFER_UDMA | ((amd_config->flags & AMD_BAD_SWDMA) ? 0 : XFER_SWDMA) | (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_66 ? XFER_UDMA_66 : 0) | - (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0)); + (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0) | + (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_133 ? XFER_UDMA_133 : 0)); amd_set_drive(drive, speed); @@ -312,13 +324,15 @@ switch (amd_config->flags & AMD_UDMA) { + case AMD_UDMA_133: case AMD_UDMA_100: pci_read_config_byte(dev, AMD_CABLE_DETECT, &t); pci_read_config_dword(dev, AMD_UDMA_TIMING, &u); amd_80w = ((t & 0x3) ? 1 : 0) | ((t & 0xc) ? 2 : 0); for (i = 24; i >= 0; i -= 8) if (((u >> i) & 4) && !(amd_80w & (1 << (1 - (i >> 4))))) { - printk(KERN_WARNING "AMD_IDE: Bios didn't set cable bits corectly. Enabling workaround.\n"); + printk(KERN_WARNING "%s: BIOS didn't set cable bits correctly. Enabling workaround.\n", + amd_chipset->name); amd_80w |= (1 << (1 - (i >> 4))); } break; @@ -331,9 +345,6 @@ break; } - pci_read_config_dword(dev, AMD_IDE_ENABLE, &u); - amd_enabled = ((u & 1) ? 2 : 0) | ((u & 2) ? 1 : 0); - /* * Take care of prefetch & postwrite. */ @@ -343,6 +354,15 @@ (amd_config->flags & AMD_BAD_FIFO) ? (t & 0x0f) : (t | 0xf0)); /* + * Take care of incorrectly wired Serenade mainboards. + */ + + if ((amd_config->flags & AMD_CHECK_SERENADE) && + dev->subsystem_vendor == PCI_VENDOR_ID_AMD && + dev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE) + amd_config->flags = AMD_UDMA_100; + +/* * Determine the system bus clock. */ @@ -355,8 +375,10 @@ } if (amd_clock < 20000 || amd_clock > 50000) { - printk(KERN_WARNING "AMD_IDE: User given PCI clock speed impossible (%d), using 33 MHz instead.\n", amd_clock); - printk(KERN_WARNING "AMD_IDE: Use ide0=ata66 if you want to assume 80-wire cable\n"); + printk(KERN_WARNING "%s: User given PCI clock speed impossible (%d), using 33 MHz instead.\n", + amd_chipset->name, amd_clock); + printk(KERN_WARNING "%s: Use ide0=ata66 if you want to assume 80-wire cable\n", + amd_chipset->name); amd_clock = 33333; } @@ -365,8 +387,8 @@ */ pci_read_config_byte(dev, PCI_REVISION_ID, &t); - printk(KERN_INFO "AMD_IDE: %s (rev %02x) %s controller on pci%s\n", - dev->name, t, amd_dma[amd_config->flags & AMD_UDMA], dev->slot_name); + printk(KERN_INFO "%s: %s (rev %02x) %s controller\n", + amd_chipset->name, pci_name(dev), t, amd_dma[amd_config->flags & AMD_UDMA]); /* * Register /proc/ide/amd74xx entry @@ -381,13 +403,7 @@ } #endif /* DISPLAY_AMD_TIMINGS && CONFIG_PROC_FS */ - - return 0; -} - -static unsigned int __init ata66_amd74xx(ide_hwif_t *hwif) -{ - return ((amd_enabled & amd_80w) >> hwif->channel) & 1; + return dev->irq; } static void __init init_hwif_amd74xx(ide_hwif_t *hwif) @@ -414,8 +430,8 @@ hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; - if (!(hwif->udma_four)) - hwif->udma_four = ((amd_enabled & amd_80w) >> hwif->channel) & 1; + if (!hwif->udma_four) + hwif->udma_four = (amd_80w >> hwif->channel) & 1; hwif->ide_dma_check = &amd74xx_ide_dma_check; if (!noautodma) hwif->autodma = 1; @@ -423,37 +439,31 @@ hwif->drives[1].autodma = hwif->autodma; } -/* - * We allow the BM-DMA driver only work on enabled interfaces. - */ - -static void __init init_dma_amd74xx(ide_hwif_t *hwif, unsigned long dmabase) -{ - if ((amd_enabled >> hwif->channel) & 1) - ide_setup_dma(hwif, dmabase, 8); -} - -extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *); - static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = amd74xx_chipsets + id->driver_data; + amd_chipset = amd74xx_chipsets + id->driver_data; amd_config = amd_ide_chips + id->driver_data; - if (dev->device != d->device) BUG(); + if (dev->device != amd_chipset->device) BUG(); if (dev->device != amd_config->id) BUG(); - ide_setup_pci_device(dev, d); + ide_setup_pci_device(dev, amd_chipset); MOD_INC_USE_COUNT; return 0; } static struct pci_device_id amd74xx_pci_tbl[] __devinitdata = { - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7401, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7411, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7441, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6}, + { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7401, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, + { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7411, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, + { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7441, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, + { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 }, { 0, }, }; Index: drivers/ide/pci/amd74xx.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/pci/amd74xx.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/pci/amd74xx.h 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/pci/amd74xx.h 4 Aug 2004 01:28:54 -0000 1.2 @@ -27,7 +27,6 @@ static unsigned int init_chipset_amd74xx(struct pci_dev *, const char *); static void init_hwif_amd74xx(ide_hwif_t *); -static void init_dma_amd74xx(ide_hwif_t *, unsigned long); static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { { /* 0 */ @@ -35,9 +34,7 @@ .device = PCI_DEVICE_ID_AMD_COBRA_7401, .name = "AMD7401", .init_chipset = init_chipset_amd74xx, - .init_iops = NULL, .init_hwif = init_hwif_amd74xx, - .init_dma = init_dma_amd74xx, .channels = 2, .autodma = AUTODMA, .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, @@ -48,9 +45,7 @@ .device = PCI_DEVICE_ID_AMD_VIPER_7409, .name = "AMD7409", .init_chipset = init_chipset_amd74xx, - .init_iops = NULL, .init_hwif = init_hwif_amd74xx, - .init_dma = init_dma_amd74xx, .channels = 2, .autodma = AUTODMA, .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, @@ -61,9 +56,7 @@ .device = PCI_DEVICE_ID_AMD_VIPER_7411, .name = "AMD7411", .init_chipset = init_chipset_amd74xx, - .init_iops = NULL, .init_hwif = init_hwif_amd74xx, - .init_dma = init_dma_amd74xx, .channels = 2, .autodma = AUTODMA, .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, @@ -74,9 +67,7 @@ .device = PCI_DEVICE_ID_AMD_OPUS_7441, .name = "AMD7441", .init_chipset = init_chipset_amd74xx, - .init_iops = NULL, .init_hwif = init_hwif_amd74xx, - .init_dma = init_dma_amd74xx, .channels = 2, .autodma = AUTODMA, .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, @@ -87,9 +78,7 @@ .device = PCI_DEVICE_ID_AMD_8111_IDE, .name = "AMD8111", .init_chipset = init_chipset_amd74xx, - .init_iops = NULL, .init_hwif = init_hwif_amd74xx, - .init_dma = init_dma_amd74xx, .autodma = AUTODMA, .channels = 2, .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, @@ -101,9 +90,7 @@ .device = PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, .name = "NFORCE", .init_chipset = init_chipset_amd74xx, - .init_iops = NULL, .init_hwif = init_hwif_amd74xx, - .init_dma = init_dma_amd74xx, .channels = 2, .autodma = AUTODMA, .enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, @@ -115,15 +102,79 @@ .device = PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, .name = "NFORCE2", .init_chipset = init_chipset_amd74xx, - .init_iops = NULL, .init_hwif = init_hwif_amd74xx, - .init_dma = init_dma_amd74xx, .channels = 2, .autodma = AUTODMA, .enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, .bootable = ON_BOARD, .extra = 0, }, + { /* 7 */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE, + .name = "NFORCE2S", + .init_chipset = init_chipset_amd74xx, + .init_hwif = init_hwif_amd74xx, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, + .bootable = ON_BOARD, + }, + { /* 8 */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA, + .name = "NFORCE2S-SATA", + .init_chipset = init_chipset_amd74xx, + .init_hwif = init_hwif_amd74xx, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, + .bootable = ON_BOARD, + }, + { /* 9 */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE, + .name = "NFORCE3", + .init_chipset = init_chipset_amd74xx, + .init_hwif = init_hwif_amd74xx, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, + .bootable = ON_BOARD, + }, + { /* 10 */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE, + .name = "NFORCE3S", + .init_chipset = init_chipset_amd74xx, + .init_hwif = init_hwif_amd74xx, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, + .bootable = ON_BOARD, + }, + { /* 11 */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, + .name = "NFORCE3S-SATA", + .init_chipset = init_chipset_amd74xx, + .init_hwif = init_hwif_amd74xx, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, + .bootable = ON_BOARD, + }, + { /* 12 */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, + .name = "NFORCE3S-SATA2", + .init_chipset = init_chipset_amd74xx, + .init_hwif = init_hwif_amd74xx, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, + .bootable = ON_BOARD, + }, { .vendor = 0, .device = 0, Index: drivers/ide/pci/cmd640.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/pci/cmd640.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/pci/cmd640.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/pci/cmd640.c 4 Aug 2004 01:28:54 -0000 1.2 @@ -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"); Index: drivers/ide/pci/generic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/pci/generic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/pci/generic.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/pci/generic.c 4 Aug 2004 01:28:54 -0000 1.2 @@ -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, }, }; Index: drivers/ide/pci/generic.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/pci/generic.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/pci/generic.h 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/pci/generic.h 4 Aug 2004 01:28:54 -0000 1.2 @@ -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, @@ -135,6 +148,7 @@ } }; +#if 0 static ide_pci_device_t unknown_chipset[] __devinitdata = { { /* 0 */ .vendor = 0, @@ -157,5 +171,6 @@ } }; +#endif #endif /* IDE_GENERIC_H */ Index: drivers/ide/pci/hpt366.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/pci/hpt366.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/pci/hpt366.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/pci/hpt366.c 4 Aug 2004 01:28:54 -0000 1.2 @@ -1,7 +1,7 @@ /* * linux/drivers/ide/pci/hpt366.c Version 0.36 April 25, 2003 * - * Copyright (C) 1999-2002 Andre Hedrick + * Copyright (C) 1999-2003 Andre Hedrick * Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2003 Red Hat Inc * @@ -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); } @@ -665,6 +668,31 @@ return __ide_dma_lostirq(drive); } +/* returns 1 if DMA IRQ issued, 0 otherwise */ +static int hpt374_ide_dma_test_irq(ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + u16 bfifo = 0; + u8 reginfo = hwif->channel ? 0x56 : 0x52; + u8 dma_stat; + + pci_read_config_word(hwif->pci_dev, reginfo, &bfifo); + if (bfifo & 0x1FF) { +// printk("%s: %d bytes in FIFO\n", drive->name, bfifo); + return 0; + } + + dma_stat = hwif->INB(hwif->dma_status); + /* return 1 if INTR asserted */ + if ((dma_stat & 4) == 4) + return 1; + + if (!drive->waiting_for_dma) + printk(KERN_WARNING "%s: (%s) called while not waiting\n", + drive->name, __FUNCTION__); + return 0; +} + static int hpt374_ide_dma_end (ide_drive_t *drive) { struct pci_dev *dev = HWIF(drive)->pci_dev; @@ -919,6 +947,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 +987,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 +1002,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 +1026,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 +1056,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); @@ -1237,11 +1270,13 @@ hwif->udma_four = ((ata66 & regmask) ? 0 : 1); hwif->ide_dma_check = &hpt366_config_drive_xfer_rate; - if (hpt_minimum_revision(dev,8)) + if (hpt_minimum_revision(dev,8)) { + hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq; hwif->ide_dma_end = &hpt374_ide_dma_end; - else if (hpt_minimum_revision(dev,5)) + } else if (hpt_minimum_revision(dev,5)) { + hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq; hwif->ide_dma_end = &hpt374_ide_dma_end; - else if (hpt_minimum_revision(dev,3)) { + } else if (hpt_minimum_revision(dev,3)) { hwif->ide_dma_begin = &hpt370_ide_dma_begin; hwif->ide_dma_end = &hpt370_ide_dma_end; hwif->ide_dma_timeout = &hpt370_ide_dma_timeout; @@ -1334,7 +1369,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 +1384,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: Index: drivers/ide/pci/pdc202xx_new.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/pci/pdc202xx_new.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/pci/pdc202xx_new.h 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/pci/pdc202xx_new.h 4 Aug 2004 01:28:54 -0000 1.2 @@ -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, Index: drivers/ide/pci/pdc202xx_old.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/pci/pdc202xx_old.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/pci/pdc202xx_old.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/pci/pdc202xx_old.c 4 Aug 2004 01:28:55 -0000 1.2 @@ -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; } @@ -749,9 +697,6 @@ hwif->tuneproc = &config_chipset_for_pio; hwif->quirkproc = &pdc202xx_quirkproc; - if (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20265) - hwif->addressing = (hwif->channel) ? 0 : 1; - if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) { hwif->busproc = &pdc202xx_tristate; hwif->resetproc = &pdc202xx_reset; @@ -859,18 +804,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 +817,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); } Index: drivers/ide/pci/piix.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/pci/piix.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/pci/piix.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/pci/piix.c 4 Aug 2004 01:28:55 -0000 1.2 @@ -153,6 +153,8 @@ case PCI_DEVICE_ID_INTEL_82801DB_11: case PCI_DEVICE_ID_INTEL_82801EB_11: case PCI_DEVICE_ID_INTEL_82801E_11: + case PCI_DEVICE_ID_INTEL_ESB_2: + case PCI_DEVICE_ID_INTEL_ICH6_2: p += sprintf(p, "PIIX4 Ultra 100 "); break; case PCI_DEVICE_ID_INTEL_82372FB_1: @@ -290,6 +292,8 @@ case PCI_DEVICE_ID_INTEL_82801DB_10: case PCI_DEVICE_ID_INTEL_82801DB_11: case PCI_DEVICE_ID_INTEL_82801EB_11: + case PCI_DEVICE_ID_INTEL_ESB_2: + case PCI_DEVICE_ID_INTEL_ICH6_2: mode = 3; break; /* UDMA 66 capable */ @@ -599,6 +603,65 @@ } /** + * ich3_busproc - bus isolation ioctl + * @drive: drive to isolate/restore + * @state: bus state to set + * + * Used by the ICH3 to handle bus isolation. We have to do + * a little bit of fixing to keep the hardware happy. + */ + +static int ich3_busproc (ide_drive_t * drive, int state) +{ + ide_hwif_t *hwif = HWIF(drive); + u32 sig_mode; + int shift; + int bits; + + if(hwif->channel == 0) + shift = 17; + else + shift = 19; + + switch (state) { + case BUSSTATE_ON: + bits = 0x00; + hwif->drives[0].failures = 0; + hwif->drives[1].failures = 0; + break; + case BUSSTATE_OFF: + bits = 0x01; + break; + case BUSSTATE_TRISTATE: + bits = 0x10; + break; + default: + return -EINVAL; + } + + if(bits) + { + int port = hwif->channel == 0 ? 0x40 : 0x42; + u16 reg; + hwif->drives[0].failures = hwif->drives[0].max_failures + 1; + hwif->drives[1].failures = hwif->drives[1].max_failures + 1; + /* Turn off IORDY checking to avoid hangs */ + pci_read_config_word(hwif->pci_dev, port, ®); + reg&=~(1<<5)|(1<<1); + pci_write_config_word(hwif->pci_dev, port, reg); + } + /* Todo: Check locking */ + pci_read_config_dword(hwif->pci_dev, 0x54, &sig_mode); + sig_mode&=~(3<pci_dev, 0x54, sig_mode); + + hwif->bus_state = state; + return 0; +} + + +/** * init_chipset_piix - set up the PIIX chipset * @dev: PCI device to set up * @name: Name of the device @@ -621,6 +684,8 @@ case PCI_DEVICE_ID_INTEL_82801DB_11: case PCI_DEVICE_ID_INTEL_82801EB_11: case PCI_DEVICE_ID_INTEL_82801E_11: + case PCI_DEVICE_ID_INTEL_ESB_2: + case PCI_DEVICE_ID_INTEL_ICH6_2: { unsigned int extra = 0; pci_read_config_dword(dev, 0x54, &extra); @@ -693,6 +758,10 @@ case PCI_DEVICE_ID_INTEL_82801AB_1: hwif->ultra_mask = 0x07; break; + case PCI_DEVICE_ID_INTEL_82801CA_10: + case PCI_DEVICE_ID_INTEL_82801CA_11: + hwif->busproc = ich3_busproc; + /* fall through */ default: pci_read_config_byte(hwif->pci_dev, 0x54, ®54h); pci_read_config_byte(hwif->pci_dev, 0x55, ®55h); @@ -812,6 +881,8 @@ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_11, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_10,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18}, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19}, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20}, { 0, }, }; Index: drivers/ide/pci/piix.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/pci/piix.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/pci/piix.h 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/pci/piix.h 4 Aug 2004 01:28:55 -0000 1.2 @@ -305,6 +305,34 @@ .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, .bootable = ON_BOARD, .extra = 0, + },{ /* 19 */ + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_ESB_2, + .name = "ICH5", + .init_setup = init_setup_piix, + .init_chipset = init_chipset_piix, + .init_iops = NULL, + .init_hwif = init_hwif_piix, + .init_dma = init_dma_piix, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, + .bootable = ON_BOARD, + .extra = 0, + },{ /* 20 */ + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_ICH6_2, + .name = "ICH6", + .init_setup = init_setup_piix, + .init_chipset = init_chipset_piix, + .init_iops = NULL, + .init_hwif = init_hwif_piix, + .init_dma = init_dma_piix, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, + .bootable = ON_BOARD, + .extra = 0, },{ .vendor = 0, .device = 0, Index: drivers/ide/pci/serverworks.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/pci/serverworks.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/pci/serverworks.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/pci/serverworks.c 4 Aug 2004 01:28:55 -0000 1.2 @@ -273,7 +273,7 @@ ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - u8 speed = ide_rate_filter(svwks_ratemask(drive), xferspeed); + u8 speed; u8 pio = ide_get_best_pio_mode(drive, 255, 5, NULL); u8 unit = (drive->select.b.unit & 0x01); u8 csb5 = svwks_csb_check(dev); @@ -281,6 +281,11 @@ u8 dma_timing = 0, pio_timing = 0; u16 csb5_pio = 0; + if (xferspeed == 255) /* PIO auto-tuning */ + speed = XFER_PIO_0 + pio; + else + speed = ide_rate_filter(svwks_ratemask(drive), xferspeed); + /* If we are about to put a disk into UDMA mode we screwed up. Our code assumes we never _ever_ do this on an OSB4 */ Index: drivers/ide/pci/siimage.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/pci/siimage.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/pci/siimage.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/pci/siimage.c 4 Aug 2004 01:28:55 -0000 1.2 @@ -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,103 @@ 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(); + return 0; +} + +/** + * 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 +148,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 +196,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 +259,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 +355,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 +374,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 +435,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 +473,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 +530,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 +559,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 +571,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 +613,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 +622,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 +639,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 +666,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 +704,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 +723,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 +765,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 +789,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 +813,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 +854,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 +927,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 +1062,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,8 +1113,11 @@ 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; + hwif->sata = 1; + } if (!hwif->dma_base) { hwif->drives[0].autotune = 1; @@ -846,7 +1129,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 +1143,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 +1171,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 +1193,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, }, }; Index: drivers/ide/pci/siimage.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/pci/siimage.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/pci/siimage.h 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/pci/siimage.h 4 Aug 2004 01:28:55 -0000 1.2 @@ -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, Index: drivers/ide/pci/sis5513.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/pci/sis5513.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/pci/sis5513.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/pci/sis5513.c 4 Aug 2004 01:28:55 -0000 1.2 @@ -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 */ - Index: drivers/ide/pci/via82cxxx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/pci/via82cxxx.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/pci/via82cxxx.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/pci/via82cxxx.c 4 Aug 2004 01:28:55 -0000 1.2 @@ -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 */ Index: drivers/ide/ppc/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/ppc/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/ppc/Makefile 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/ppc/Makefile 4 Aug 2004 01:28:55 -0000 1.2 @@ -4,6 +4,7 @@ obj-y := obj-m := +obj-$(CONFIG_BLK_DEV_CPCI405_IDE) += cpci405ide.o obj-$(CONFIG_BLK_DEV_MPC8xx_IDE) += mpc8xx.o obj-$(CONFIG_BLK_DEV_IDE_PMAC) += pmac.o obj-$(CONFIG_BLK_DEV_IDE_SWARM) += swarm.o Index: drivers/ide/raid/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/raid/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/raid/Makefile 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/raid/Makefile 4 Aug 2004 01:28:55 -0000 1.2 @@ -12,6 +12,7 @@ obj-$(CONFIG_BLK_DEV_ATARAID) += ataraid.o obj-$(CONFIG_BLK_DEV_ATARAID_PDC) += pdcraid.o obj-$(CONFIG_BLK_DEV_ATARAID_HPT) += hptraid.o +obj-$(CONFIG_BLK_DEV_ATARAID_MEDLEY) += medley.o obj-$(CONFIG_BLK_DEV_ATARAID_SII) += silraid.o EXTRA_CFLAGS := -I../ Index: drivers/ide/raid/hptraid.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/raid/hptraid.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/raid/hptraid.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/raid/hptraid.c 4 Aug 2004 01:28:55 -0000 1.2 @@ -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 __initdata 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) { @@ -441,7 +584,7 @@ ide_drive_t *ideinfo; dev = MKDEV(major,minor); - ideinfo = get_info_ptr (dev); + ideinfo = ide_info_ptr (dev, 0); if (ideinfo==NULL) return 0; @@ -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;isect==0) return 0; - lba = (ideinfo->capacity / (ideinfo->head*ideinfo->sect)); - lba = lba * (ideinfo->head*ideinfo->sect); - lba = lba - ideinfo->sect; + if (ideinfo->head!=255) { + lba = (ideinfo->capacity / (ideinfo->head*ideinfo->sect)); + lba = lba * (ideinfo->head*ideinfo->sect); + lba = lba - ideinfo->sect; } + else { + lba = ideinfo->capacity - ideinfo->sect; + } return lba; } Index: drivers/ide/raid/silraid.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ide/raid/silraid.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ide/raid/silraid.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/ide/raid/silraid.c 4 Aug 2004 01:28:55 -0000 1.2 @@ -253,7 +253,7 @@ ide_drive_t *ideinfo; dev = MKDEV(major,minor); - ideinfo = get_info_ptr (dev); + ideinfo = ide_info_ptr (dev, 0); if (ideinfo==NULL) return 0; Index: drivers/ieee1394/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/Config.in 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/Config.in 4 Aug 2004 01:28:55 -0000 1.2 @@ -40,6 +40,7 @@ fi bool 'Excessive debugging output' CONFIG_IEEE1394_VERBOSEDEBUG + bool "OUI Database built-in" CONFIG_IEEE1394_OUI_DB fi endmenu fi Index: drivers/ieee1394/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/Makefile 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/Makefile 4 Aug 2004 01:28:55 -0000 1.2 @@ -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 > $@ Index: drivers/ieee1394/amdtp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/amdtp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/amdtp.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/amdtp.c 4 Aug 2004 01:28:55 -0000 1.2 @@ -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; Index: drivers/ieee1394/cmp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/cmp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/cmp.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/cmp.c 4 Aug 2004 01:28:55 -0000 1.2 @@ -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; @@ -158,7 +158,7 @@ } static int pcr_read(struct hpsb_host *host, int nodeid, quadlet_t *buf, - u64 addr, unsigned int length, u16 flags) + u64 addr, size_t length, u16 flags) { int csraddr = addr - CSR_REGISTER_BASE; int plug; Index: drivers/ieee1394/csr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/csr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/csr.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/csr.c 4 Aug 2004 01:28:55 -0000 1.2 @@ -19,6 +19,8 @@ #include #include /* needed for MODULE_PARM */ +#include +#include #include "ieee1394_types.h" #include "hosts.h" @@ -87,6 +89,37 @@ 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++; + + HPSB_VERBOSE("CSR: setting expire to %lu, HZ=%d", csr->expire, HZ); +} + static void add_host(struct hpsb_host *host) { @@ -98,6 +131,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; @@ -156,7 +190,7 @@ /* Read topology / speed maps and configuration ROM */ static int read_maps(struct hpsb_host *host, int nodeid, quadlet_t *buffer, - u64 addr, unsigned int length, u16 fl) + u64 addr, size_t length, u16 fl) { unsigned long flags; int csraddr = addr - CSR_REGISTER_BASE; @@ -166,6 +200,7 @@ if (csraddr < CSR_TOPOLOGY_MAP) { if (csraddr + length > CSR_CONFIG_ROM + host->csr.rom_size) { + spin_unlock_irqrestore(&host->csr.lock, flags); return RCODE_ADDRESS_ERROR; } src = ((char *)host->csr.rom) + csraddr - CSR_CONFIG_ROM; @@ -185,7 +220,7 @@ #define out if (--length == 0) break static int read_regs(struct hpsb_host *host, int nodeid, quadlet_t *buf, - u64 addr, unsigned int length, u16 flags) + u64 addr, size_t length, u16 flags) { int csraddr = addr - CSR_REGISTER_BASE; int oldcycle; @@ -299,7 +334,7 @@ } static int write_regs(struct hpsb_host *host, int nodeid, int destid, - quadlet_t *data, u64 addr, unsigned int length, u16 flags) + quadlet_t *data, u64 addr, size_t length, u16 flags) { int csraddr = addr - CSR_REGISTER_BASE; @@ -334,10 +369,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 +445,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 +591,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 */ } @@ -623,7 +660,7 @@ } static int write_fcp(struct hpsb_host *host, int nodeid, int dest, - quadlet_t *data, u64 addr, unsigned int length, u16 flags) + quadlet_t *data, u64 addr, size_t length, u16 flags) { int csraddr = addr - CSR_REGISTER_BASE; Index: drivers/ieee1394/csr.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/csr.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/csr.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/csr.h 4 Aug 2004 01:28:55 -0000 1.2 @@ -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; Index: drivers/ieee1394/dma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/dma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/dma.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/dma.c 4 Aug 2004 01:28:55 -0000 1.2 @@ -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; } @@ -85,8 +86,8 @@ memset(dma->kvirt, 0, n_pages * PAGE_SIZE); /* allocate scatter/gather list */ - dma->sglist = kmalloc(dma->n_pages * sizeof(struct scatterlist), GFP_KERNEL); - if(!dma->sglist) { + dma->sglist = vmalloc(dma->n_pages * sizeof(struct scatterlist)); + 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) { - kfree(dma->sglist); + if (dma->sglist) { + vfree(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; Index: drivers/ieee1394/dma.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/dma.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/dma.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/dma.h 4 Aug 2004 01:28:55 -0000 1.2 @@ -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; } Index: drivers/ieee1394/dv1394-private.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/dv1394-private.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/dv1394-private.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/dv1394-private.h 4 Aug 2004 01:28:55 -0000 1.2 @@ -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 */ Index: drivers/ieee1394/dv1394.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/dv1394.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/dv1394.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/dv1394.c 4 Aug 2004 01:28:55 -0000 1.2 @@ -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"); Index: drivers/ieee1394/dv1394.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/dv1394.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/dv1394.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/dv1394.h 4 Aug 2004 01:28:55 -0000 1.2 @@ -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(); } } Index: drivers/ieee1394/eth1394.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/eth1394.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/eth1394.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/eth1394.c 4 Aug 2004 01:28:55 -0000 1.2 @@ -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: 1043 $ 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, 4096, 4096 +}; + 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; - /* Set the spinlock before grabbing IRQ! */ - priv->lock = SPIN_LOCK_UNLOCKED; + /* 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); + + 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); + + 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); - skb_reserve(skb, (dev->hard_header_len + 15) & ~15); + 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, size_t 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,326 @@ 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; +} - memcpy (skb_put (skb, len), buf, len); +/****************************************** + * 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); - /* 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); + struct arphdr *arp = (struct arphdr *)skb->data; + unsigned char *arp_ptr = (unsigned char *)(arp + 1); + struct eth1394_arp *arp1394 = (struct eth1394_arp *)skb->data; - 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; - } + /* 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); - netif_stop_queue(dev); - if (netif_rx (skb) == NET_RX_DROP) { - priv->stats.rx_errors++; - priv->stats.rx_dropped++; - goto bad_proto; - } + return; +} + +/* 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)) { + 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; + + return 0; +} -/* This function is our scheduled write */ -static void hpsb_write_sched (void *__ptask) +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)) { + free_hpsb_packet(packet); + return -1; } + ptask->packet = packet; + hpsb_set_packet_complete_task(ptask->packet, ether1394_complete_cb, + ptask); + + if (!hpsb_send_packet(packet)) { + ether1394_free_packet(packet); + return -1; + } + + return 0; +} + +/* 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 +1465,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: 1043 $"); + /* 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 +1626,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, Index: drivers/ieee1394/eth1394.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/eth1394.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/eth1394.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/eth1394.h 4 Aug 2004 01:28:55 -0000 1.2 @@ -24,35 +24,48 @@ #ifndef __ETH1394_H #define __ETH1394_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 +#include "ieee1394.h" + +/* Register for incoming packets. This is 4096 bytes, which supports up to + * S3200 (per Table 16-3 of IEEE 1394b-2002). */ +#define ETHER1394_REGION_ADDR_LEN 4096 #define ETHER1394_REGION_ADDR 0xfffff0200000ULL #define ETHER1394_REGION_ADDR_END (ETHER1394_REGION_ADDR + ETHER1394_REGION_ADDR_LEN) /* 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 */ Index: drivers/ieee1394/highlevel.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/highlevel.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/highlevel.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/highlevel.c 4 Aug 2004 01:28:55 -0000 1.2 @@ -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; @@ -413,7 +436,7 @@ } void highlevel_iso_receive(struct hpsb_host *host, void *data, - unsigned int length) + size_t length) { struct list_head *entry; struct hpsb_highlevel *hl; @@ -433,7 +456,7 @@ } void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction, - void *data, unsigned int length) + void *data, size_t length) { struct list_head *entry; struct hpsb_highlevel *hl; Index: drivers/ieee1394/highlevel.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/highlevel.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/highlevel.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/highlevel.h 4 Aug 2004 01:28:55 -0000 1.2 @@ -45,14 +45,14 @@ * packet header (first quadlet, CRCs are missing). You may get called * for channel/host combinations you did not request. */ void (*iso_receive) (struct hpsb_host *host, int channel, - quadlet_t *data, unsigned int length); + quadlet_t *data, size_t length); /* A write request was received on either the FCP_COMMAND (direction = * 0) or the FCP_RESPONSE (direction = 1) register. The cts arg * contains the cts field (first byte of data). */ void (*fcp_request) (struct hpsb_host *host, int nodeid, int direction, - int cts, u8 *data, unsigned int length); + int cts, u8 *data, size_t length); struct list_head hl_list; @@ -78,9 +78,9 @@ will send the response itself */ int (*read) (struct hpsb_host *host, int nodeid, quadlet_t *buffer, - u64 addr, unsigned int length, u16 flags); + u64 addr, size_t length, u16 flags); int (*write) (struct hpsb_host *host, int nodeid, int destid, - quadlet_t *data, u64 addr, unsigned int length, u16 flags); + quadlet_t *data, u64 addr, size_t length, u16 flags); /* Lock transactions: write results of ext_tcode operation into * *store. */ @@ -116,9 +116,9 @@ u64 addr, octlet_t data, octlet_t arg, int ext_tcode, u16 flags); void highlevel_iso_receive(struct hpsb_host *host, void *data, - unsigned int length); + size_t length); void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction, - void *data, unsigned int length); + void *data, size_t length); /* @@ -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 */ Index: drivers/ieee1394/hosts.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/hosts.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/hosts.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/hosts.c 4 Aug 2004 01:28:55 -0000 1.2 @@ -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); Index: drivers/ieee1394/hosts.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/hosts.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/hosts.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/hosts.h 4 Aug 2004 01:28:55 -0000 1.2 @@ -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 { Index: drivers/ieee1394/ieee1394-ioctl.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/ieee1394-ioctl.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/ieee1394-ioctl.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/ieee1394-ioctl.h 4 Aug 2004 01:28:55 -0000 1.2 @@ -60,9 +60,13 @@ _IOWR('#', 0x14, struct video1394_mmap) #define VIDEO1394_IOC_UNTALK_CHANNEL \ _IOW ('#', 0x15, int) +/* + * This one is broken: it really wanted + * "sizeof (struct video1394_wait) + sizeof (struct video1394_queue_variable)" + * but got just a "size_t" + */ #define VIDEO1394_IOC_TALK_QUEUE_BUFFER \ - _IOW ('#', 0x16, sizeof (struct video1394_wait) + \ - sizeof (struct video1394_queue_variable)) + _IOW ('#', 0x16, size_t) #define VIDEO1394_IOC_TALK_WAIT_BUFFER \ _IOW ('#', 0x17, struct video1394_wait) #define VIDEO1394_IOC_LISTEN_POLL_BUFFER \ @@ -100,6 +104,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 */ Index: drivers/ieee1394/ieee1394.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/ieee1394.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/ieee1394.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/ieee1394.h 4 Aug 2004 01:28:55 -0000 1.2 @@ -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 Index: drivers/ieee1394/ieee1394_core.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/ieee1394_core.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/ieee1394_core.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/ieee1394_core.c 4 Aug 2004 01:28:55 -0000 1.2 @@ -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,28 +58,33 @@ /* 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 }; +#ifdef CONFIG_IEEE1394_VERBOSEDEBUG static void dump_packet(const char *text, quadlet_t *data, int size) { - int i; + int i; - size /= 4; - size = (size > 4 ? 4 : size); + size /= 4; + size = (size > 4 ? 4 : size); - printk(KERN_DEBUG "ieee1394: %s", text); - for (i = 0; i < size; i++) { - printk(" %8.8x", data[i]); - } - printk("\n"); + printk(KERN_DEBUG "ieee1394: %s", text); + for (i = 0; i < size; i++) + printk(" %08x", data[i]); + printk("\n"); } +#else +#define dump_packet(x,y,z) +#endif 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; } @@ -276,8 +280,8 @@ static void build_speed_map(struct hpsb_host *host, int nodecount) { - char speedcap[nodecount]; - char cldcnt[nodecount]; + u8 speedcap[nodecount]; + u8 cldcnt[nodecount]; u8 *map = host->speed_map; struct selfid *sid; struct ext_selfid *esid; @@ -285,7 +289,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; } } @@ -328,7 +332,7 @@ for (i = 1; i < nodecount; i++) { for (j = cldcnt[i], n = i - 1; j > 0; j--) { cldcnt[i] += cldcnt[n]; - speedcap[n] = MIN(speedcap[n], speedcap[i]); + speedcap[n] = min(speedcap[n], speedcap[i]); n -= cldcnt[n] + 1; } } @@ -337,11 +341,11 @@ for (i = n - cldcnt[n]; i <= n; i++) { for (j = 0; j < (n - cldcnt[n]); j++) { map[j*64 + i] = map[i*64 + j] = - MIN(map[i*64 + j], speedcap[n]); + min(map[i*64 + j], speedcap[n]); } for (j = n + 1; j < nodecount; j++) { map[j*64 + i] = map[i*64 + j] = - MIN(map[i*64 + j], speedcap[n]); + min(map[i*64 + j], speedcap[n]); } } } @@ -351,9 +355,7 @@ void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid) { if (host->in_bus_reset) { -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - HPSB_INFO("Including SelfID 0x%x", sid); -#endif + HPSB_VERBOSE("Including SelfID 0x%x", sid); host->topology_map[host->selfid_count++] = sid; } else { HPSB_NOTICE("Spurious SelfID packet (0x%08x) received from bus %d", @@ -380,15 +382,16 @@ } 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); } -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - HPSB_INFO("selfid_complete called with successful SelfID stage " - "... irm_id: 0x%X node_id: 0x%X",host->irm_id,host->node_id); -#endif + HPSB_VERBOSE("selfid_complete called with successful SelfID stage " + "... irm_id: 0x%X node_id: 0x%X",host->irm_id,host->node_id); + /* irm_id is kept up to date by check_selfids() */ if (host->irm_id == host->node_id) { host->is_irm = 1; @@ -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; @@ -547,10 +549,9 @@ } } -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG dump_packet("send packet local:", packet->header, packet->header_size); -#endif + hpsb_packet_sent(host, packet, packet->expect_response?ACK_PENDING:ACK_COMPLETE); hpsb_packet_received(host, data, size, 0); @@ -565,7 +566,6 @@ + NODEID_TO_NODE(packet->node_id)]; } -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG switch (packet->speed_code) { case 2: dump_packet("send packet 400:", packet->header, @@ -579,7 +579,6 @@ dump_packet("send packet 100:", packet->header, packet->header_size); } -#endif return host->driver->transmit_packet(host, packet); } @@ -614,7 +613,7 @@ } if (lh == &host->pending_packets) { - HPSB_DEBUG("unsolicited response packet received - np"); + HPSB_DEBUG("unsolicited response packet received - no tlabel match"); dump_packet("contents:", data, 16); spin_unlock_irqrestore(&host->pending_pkt_lock, flags); return; @@ -638,7 +637,7 @@ if (!tcode_match || (packet->tlabel != tlabel) || (packet->node_id != (data[1] >> 16))) { - HPSB_INFO("unsolicited response packet received"); + HPSB_INFO("unsolicited response packet received - tcode mismatch"); dump_packet("contents:", data, 16); spin_unlock_irqrestore(&host->pending_pkt_lock, flags); @@ -820,6 +819,8 @@ if (rcode >= 0) { fill_async_readblock_resp(packet, rcode, length); send_packet_nocare(packet); + } else { + free_hpsb_packet(packet); } break; @@ -893,9 +894,7 @@ return; } -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG dump_packet("received packet:", data, size); -#endif tcode = (data[0] >> 4) & 0xf; @@ -936,7 +935,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 +945,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 +955,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 +979,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 +1023,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 +1047,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 +1089,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 +1133,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 +1146,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 +1158,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 +1171,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 +1202,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 +1252,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); @@ -1278,6 +1273,7 @@ EXPORT_SYMBOL(hpsb_free_tlabel); EXPORT_SYMBOL(hpsb_make_readpacket); EXPORT_SYMBOL(hpsb_make_writepacket); +EXPORT_SYMBOL(hpsb_make_streampacket); EXPORT_SYMBOL(hpsb_make_lockpacket); EXPORT_SYMBOL(hpsb_make_lock64packet); EXPORT_SYMBOL(hpsb_make_phypacket); @@ -1297,6 +1293,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 +1351,4 @@ EXPORT_SYMBOL(hpsb_iso_packet_sent); EXPORT_SYMBOL(hpsb_iso_packet_received); EXPORT_SYMBOL(hpsb_iso_wake); +EXPORT_SYMBOL(hpsb_iso_recv_flush); Index: drivers/ieee1394/ieee1394_core.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/ieee1394_core.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/ieee1394_core.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/ieee1394_core.h 4 Aug 2004 01:28:55 -0000 1.2 @@ -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); Index: drivers/ieee1394/ieee1394_hotplug.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/ieee1394_hotplug.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/ieee1394_hotplug.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/ieee1394_hotplug.h 4 Aug 2004 01:28:55 -0000 1.2 @@ -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 */ Index: drivers/ieee1394/ieee1394_transactions.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/ieee1394_transactions.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/ieee1394_transactions.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/ieee1394_transactions.c 4 Aug 2004 01:28:55 -0000 1.2 @@ -95,14 +95,14 @@ 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, int channel, int tag, int sync) { packet->header[0] = (length << 16) | (tag << 14) | (channel << 8) - | (TCODE_STREAM_DATA << 4) | sync; + | (TCODE_STREAM_DATA << 4) | sync; packet->header_size = 4; packet->data_size = length; @@ -113,40 +113,40 @@ /** * hpsb_get_tlabel - allocate a transaction label * @packet: the packet who's tlabel/tpool we set - * @wait: whether to sleep if no tlabel is available * - * Every asynchronous transaction on the 1394 bus needs a transaction label to - * match the response to the request. This label has to be different from any - * other transaction label in an outstanding request to the same node to make - * matching possible without ambiguity. + * Every asynchronous transaction on the 1394 bus needs a transaction + * label to match the response to the request. This label has to be + * different from any other transaction label in an outstanding request to + * the same node to make matching possible without ambiguity. * - * There are 64 different tlabels, so an allocated tlabel has to be freed with - * hpsb_free_tlabel() after the transaction is complete (unless it's reused again for - * the same target node). - * - * @wait cannot be set if in_interrupt() + * There are 64 different tlabels, so an allocated tlabel has to be freed + * with hpsb_free_tlabel() after the transaction is complete (unless it's + * reused again for the same target node). * * Return value: Zero on success, otherwise non-zero. A non-zero return - * generally means there are no available tlabels. + * generally means there are no available tlabels. If this is called out + * of interrupt or atomic context, then it will sleep until can return a + * tlabel. */ -int hpsb_get_tlabel(struct hpsb_packet *packet, int wait) +int hpsb_get_tlabel(struct hpsb_packet *packet) { unsigned long flags; struct hpsb_tlabel_pool *tp; tp = &packet->host->tpool[packet->node_id & NODE_MASK]; - if (wait) { - BUG_ON(in_interrupt()); - down(&tp->count); - } else { + if (in_interrupt()) { if (down_trylock(&tp->count)) return 1; + } else { + down(&tp->count); } 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)); @@ -268,7 +268,7 @@ packet->host = host; packet->node_id = node; - if (hpsb_get_tlabel(packet, in_interrupt() ? 0 : 1)) { + if (hpsb_get_tlabel(packet)) { free_hpsb_packet(packet); return NULL; } @@ -299,7 +299,7 @@ packet->host = host; packet->node_id = node; - if (hpsb_get_tlabel(packet, in_interrupt() ? 0 : 1)) { + if (hpsb_get_tlabel(packet)) { free_hpsb_packet(packet); return NULL; } @@ -315,6 +315,35 @@ return packet; } +struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer, int length, + int channel, int tag, int sync) +{ + struct hpsb_packet *packet; + + if (length == 0) + return NULL; + + packet = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0)); + if (!packet) + return NULL; + + if (length % 4) { /* zero padding bytes */ + packet->data[length >> 2] = 0; + } + packet->host = host; + + if (hpsb_get_tlabel(packet)) { + free_hpsb_packet(packet); + return NULL; + } + + fill_async_stream_packet(packet, length, channel, tag, sync); + if (buffer) + memcpy(packet->data, buffer, length); + + return packet; +} + struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node, u64 addr, int extcode, quadlet_t *data, quadlet_t arg) @@ -327,7 +356,7 @@ p->host = host; p->node_id = node; - if (hpsb_get_tlabel(p, in_interrupt() ? 0 : 1)) { + if (hpsb_get_tlabel(p)) { free_hpsb_packet(p); return NULL; } @@ -364,7 +393,7 @@ p->host = host; p->node_id = node; - if (hpsb_get_tlabel(p, in_interrupt() ? 0 : 1)) { + if (hpsb_get_tlabel(p)) { free_hpsb_packet(p); return NULL; } @@ -573,44 +602,23 @@ 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; u8 specifier_id_lo = specifier_id & 0xff; -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - HPSB_DEBUG("Send GASP: channel = %d, length = %d", channel, length); -#endif + HPSB_VERBOSE("Send GASP: channel = %d, length = %Zd", channel, length); length += 8; - - packet = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0)); + + packet = hpsb_make_streampacket(host, NULL, length, channel, 3, 0); if (!packet) return -ENOMEM; - if (length % 4) { - packet->data[length / 4] = 0; - } - - packet->host = host; - fill_async_stream_packet(packet, length, channel, 3, 0); - packet->data[0] = cpu_to_be32((host->node_id << 16) | specifier_id_hi); packet->data[1] = cpu_to_be32((specifier_id_lo << 24) | (version & 0x00ffffff)); - 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 + memcpy(&(packet->data[2]), buffer, length - 8); packet->generation = generation; Index: drivers/ieee1394/ieee1394_transactions.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/ieee1394_transactions.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/ieee1394_transactions.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/ieee1394_transactions.h 4 Aug 2004 01:28:56 -0000 1.2 @@ -7,7 +7,7 @@ /* * Get and free transaction labels. */ -int hpsb_get_tlabel(struct hpsb_packet *packet, int wait); +int hpsb_get_tlabel(struct hpsb_packet *packet); void hpsb_free_tlabel(struct hpsb_packet *packet); struct hpsb_packet *hpsb_make_readpacket(struct hpsb_host *host, nodeid_t node, @@ -25,6 +25,8 @@ int tag, int sync); struct hpsb_packet *hpsb_make_writepacket (struct hpsb_host *host, nodeid_t node, u64 addr, quadlet_t *buffer, size_t length); +struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer, + int length, int channel, int tag, int sync); /* * hpsb_packet_success - Make sense of the ack and reply codes and Index: drivers/ieee1394/ieee1394_types.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/ieee1394_types.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/ieee1394_types.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/ieee1394_types.h 4 Aug 2004 01:28:56 -0000 1.2 @@ -7,16 +7,18 @@ #include #include #include +#include #include #include -#ifndef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif - -#ifndef MAX -#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#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 @@ -36,7 +38,7 @@ (_tp)->next = 0; \ (_tp)->allocations = 0; \ sema_init(&(_tp)->count, 63); \ -} while(0) +} while (0) typedef u32 quadlet_t; @@ -57,8 +59,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) @@ -68,6 +71,12 @@ #define HPSB_WARN(fmt, args...) HPSB_PRINT(KERN_WARNING, fmt , ## args) #define HPSB_ERR(fmt, args...) HPSB_PRINT(KERN_ERR, fmt , ## args) +#ifdef CONFIG_IEEE1394_VERBOSEDEBUG +#define HPSB_VERBOSE(fmt, args...) HPSB_PRINT(KERN_DEBUG, fmt , ## args) +#else +#define HPSB_VERBOSE(fmt, args...) +#endif + #define HPSB_PANIC(fmt, args...) panic("ieee1394: " fmt "\n" , ## args) #define HPSB_TRACE() HPSB_PRINT(KERN_INFO, "TRACE - %s, %s(), line %d", __FILE__, __FUNCTION__, __LINE__) Index: drivers/ieee1394/iso.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/iso.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/iso.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/iso.c 4 Aug 2004 01:28:56 -0000 1.2 @@ -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); } Index: drivers/ieee1394/iso.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/iso.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/iso.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/iso.h 4 Aug 2004 01:28:56 -0000 1.2 @@ -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); Index: drivers/ieee1394/nodemgr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/nodemgr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/nodemgr.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/nodemgr.c 4 Aug 2004 01:28:56 -0000 1.2 @@ -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; @@ -772,9 +785,8 @@ envp[i++] = 0; /* NOTE: user mode daemons can call the agents too */ -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - HPSB_DEBUG("NodeMgr: %s %s %016Lx", argv[0], verb, (long long unsigned)ud->ne->guid); -#endif + HPSB_VERBOSE("NodeMgr: %s %s %016Lx", argv[0], verb, (long long unsigned)ud->ne->guid); + value = call_usermodehelper(argv[0], argv, envp); kfree(buf); kfree(envp); @@ -787,9 +799,7 @@ static inline void nodemgr_call_policy(char *verb, struct unit_directory *ud) { -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - HPSB_DEBUG("NodeMgr: nodemgr_call_policy(): hotplug not enabled"); -#endif + HPSB_VERBOSE("NodeMgr: nodemgr_call_policy(): hotplug not enabled"); return; } @@ -979,14 +989,12 @@ ne->busopt.generation = (busoptions >> 4) & 0xf; ne->busopt.lnkspd = busoptions & 0x7; -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - HPSB_DEBUG("NodeMgr: raw=0x%08x irmc=%d cmc=%d isc=%d bmc=%d pmc=%d " - "cyc_clk_acc=%d max_rec=%d gen=%d lspd=%d", - busoptions, ne->busopt.irmc, ne->busopt.cmc, - ne->busopt.isc, ne->busopt.bmc, ne->busopt.pmc, - ne->busopt.cyc_clk_acc, ne->busopt.max_rec, - ne->busopt.generation, ne->busopt.lnkspd); -#endif + HPSB_VERBOSE("NodeMgr: raw=0x%08x irmc=%d cmc=%d isc=%d bmc=%d pmc=%d " + "cyc_clk_acc=%d max_rec=%d gen=%d lspd=%d", + busoptions, ne->busopt.irmc, ne->busopt.cmc, + ne->busopt.isc, ne->busopt.bmc, ne->busopt.pmc, + ne->busopt.cyc_clk_acc, ne->busopt.max_rec, + ne->busopt.generation, ne->busopt.lnkspd); /* * When the config rom changes we disconnect all drivers and @@ -1014,17 +1022,17 @@ 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; } + ne->generation = generation; + if (ne->busopt.generation != ((busoptions >> 4) & 0xf)) nodemgr_process_config_rom (ne, busoptions); - /* Since that's done, we can declare this record current */ - ne->generation = generation; - list_for_each (lh, &ne->unit_directories) { ud = list_entry (lh, struct unit_directory, node_list); if (ud->driver && ud->driver->update != NULL) @@ -1044,10 +1052,9 @@ * work though, and we are forced to doing quadlet sized * reads. */ -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - HPSB_INFO("Initiating ConfigROM request for node " NODE_BUS_FMT, - NODE_BUS_ARGS(nodeid)); -#endif + HPSB_VERBOSE("Initiating ConfigROM request for node " NODE_BUS_FMT, + NODE_BUS_ARGS(host, nodeid)); + /* * Must retry a few times if config rom read returns zero (how long?). Will * not normally occur, but we should do the right thing. For example, with @@ -1059,7 +1066,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 +1083,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 +1099,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 +1109,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 +1145,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 +1236,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,14 +1303,17 @@ * 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)) + if (schedule_timeout(HZ/16)) { + up(&nodemgr_serialize); goto caught_signal; + } /* Now get the generation in which the node ID's we collect * are valid. During the bus scan we will use this generation @@ -1317,7 +1325,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++)) { @@ -1335,9 +1343,7 @@ } caught_signal: -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - HPSB_DEBUG ("NodeMgr: Exiting thread"); -#endif + HPSB_VERBOSE("NodeMgr: Exiting thread"); complete_and_exit(&hi->exited, 0); } @@ -1452,9 +1458,7 @@ struct host_info *hi = hpsb_get_hostinfo(&nodemgr_highlevel, host); if (hi != NULL) { -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - HPSB_DEBUG ("NodeMgr: Processing host reset for %s", host->driver->name); -#endif + HPSB_VERBOSE("NodeMgr: Processing host reset for %s", hi->daemon_name); up(&hi->reset_sem); } else HPSB_ERR ("NodeMgr: could not process reset of unused host"); Index: drivers/ieee1394/nodemgr.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/nodemgr.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/nodemgr.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/nodemgr.h 4 Aug 2004 01:28:56 -0000 1.2 @@ -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); Index: drivers/ieee1394/ohci1394.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/ohci1394.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/ohci1394.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/ohci1394.c 4 Aug 2004 01:28:56 -0000 1.2 @@ -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: 1045 $ 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,10 +1461,10 @@ 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; + cmd->control |= cpu_to_le32(DMA_CTL_WAIT); /* match sync field */ contextMatch |= (sync&0xf)<<8; @@ -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,51 +1666,47 @@ 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 */ - u16 xferstatus = im->status >> 16; + u16 xferstatus = le32_to_cpu(im->status) >> 16; /* rescount is the number of bytes *remaining to be written* in the block */ - u16 rescount = im->status & 0xFFFF; + u16 rescount = le32_to_cpu(im->status) & 0xFFFF; 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); } } Index: drivers/ieee1394/pcilynx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/pcilynx.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/pcilynx.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/pcilynx.c 4 Aug 2004 01:28:56 -0000 1.2 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -1004,7 +1005,7 @@ DECLARE_WAITQUEUE(wait, current); count &= ~3; - count = MIN(count, 53196); + count = min(count, 53196); retval = count; if (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS)) @@ -1015,14 +1016,14 @@ reg_write(md->lynx, LBUS_ADDR, md->type | offset); pcl = edit_pcl(md->lynx, md->lynx->dmem_pcl, &pcltmp); - pcl->buffer[0].control = PCL_CMD_LBUS_TO_PCI | MIN(count, 4092); + pcl->buffer[0].control = PCL_CMD_LBUS_TO_PCI | min(count, 4092); pcl->buffer[0].pointer = physbuf; count -= 4092; i = 0; while (count > 0) { i++; - pcl->buffer[i].control = MIN(count, 4092); + pcl->buffer[i].control = min(count, 4092); pcl->buffer[i].pointer = physbuf + i * 4092; count -= 4092; } @@ -1126,7 +1127,7 @@ retval = copy_to_user(buffer, md->lynx->mem_dma_buffer, count); up(&md->lynx->mem_dma_mutex); - if (retval < 0) return retval; + if (retval) return -EFAULT; *offset += count; return count; } @@ -1147,14 +1148,17 @@ /* FIXME: dereferencing pointers to PCI mem doesn't work everywhere */ switch (md->type) { case aux: - copy_from_user(md->lynx->aux_port+(*offset), buffer, count); + if (copy_from_user(md->lynx->aux_port+(*offset), buffer, count)) + return -EFAULT; break; case ram: - copy_from_user(md->lynx->local_ram+(*offset), buffer, count); + if (copy_from_user(md->lynx->local_ram+(*offset), buffer, count)) + return -EFAULT; break; case rom: /* the ROM may be writeable */ - copy_from_user(md->lynx->local_rom+(*offset), buffer, count); + if (copy_from_user(md->lynx->local_rom+(*offset), buffer, count)) + return -EFAULT; break; } @@ -1459,6 +1463,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 +1518,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 +1618,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 @@ -1789,9 +1808,8 @@ i2c_adapter.algo_data = &i2c_adapter_data; i2c_adapter_data.data = lynx; -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - PRINT(KERN_DEBUG, lynx->id,"original eeprom control: %d",reg_read(lynx,SERIAL_EEPROM_CONTROL)); -#endif + PRINTD(KERN_DEBUG, lynx->id,"original eeprom control: %d", + reg_read(lynx, SERIAL_EEPROM_CONTROL)); /* reset hardware to sane state */ lynx->i2c_driven_state = 0x00000070; @@ -1834,17 +1852,16 @@ if (i2c_transfer(&i2c_adapter, msg, 2) < 0) { PRINT(KERN_ERR, lynx->id, "unable to read bus info block from i2c"); } else { -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG int i; -#endif - PRINT(KERN_INFO, lynx->id, "got bus info block from serial eeprom"); - /* FIXME: probably we shoud rewrite the max_rec, max_ROM(1394a), generation(1394a) and link_spd(1394a) field - and recalculate the CRC */ -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - for (i=0; i < 5 ; i++) - PRINT(KERN_DEBUG, lynx->id, "Businfo block quadlet %i: %08x",i, be32_to_cpu(lynx->config_rom[i])); -#endif + PRINT(KERN_INFO, lynx->id, "got bus info block from serial eeprom"); + /* FIXME: probably we shoud rewrite the max_rec, max_ROM(1394a), + * generation(1394a) and link_spd(1394a) field and recalculate + * the CRC */ + + for (i = 0; i < 5 ; i++) + PRINTD(KERN_DEBUG, lynx->id, "Businfo block quadlet %i: %08x", + i, be32_to_cpu(lynx->config_rom[i])); /* info_length, crc_length and 1394 magic number to check, if it is really a bus info block */ if (((be32_to_cpu(lynx->config_rom[0]) & 0xffff0000) == 0x04040000) && Index: drivers/ieee1394/raw1394.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/raw1394.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/raw1394.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/raw1394.c 4 Aug 2004 01:28:56 -0000 1.2 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -44,11 +45,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" @@ -84,9 +85,9 @@ static struct hpsb_highlevel raw1394_highlevel; static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer, - u64 addr, unsigned int length, u16 flags); + u64 addr, size_t length, u16 flags); static int arm_write (struct hpsb_host *host, int nodeid, int destid, - quadlet_t *data, u64 addr, unsigned int length, u16 flags); + quadlet_t *data, u64 addr, size_t length, u16 flags); static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store, u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode, u16 flags); static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store, @@ -181,6 +182,7 @@ if ((req->req.type == RAW1394_REQ_ASYNC_READ) || (req->req.type == RAW1394_REQ_ASYNC_WRITE) || + (req->req.type == RAW1394_REQ_ASYNC_STREAM) || (req->req.type == RAW1394_REQ_LOCK) || (req->req.type == RAW1394_REQ_LOCK64)) hpsb_free_tlabel(packet); @@ -294,7 +296,7 @@ } static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data, - unsigned int length) + size_t length) { unsigned long flags; struct list_head *lh; @@ -346,7 +348,7 @@ req->req.generation = get_hpsb_generation(host); req->req.misc = 0; req->req.recvb = ptr2int(fi->iso_buffer); - req->req.length = MIN(length, fi->iso_buffer_length); + req->req.length = min(length, fi->iso_buffer_length); list_add_tail(&req->list, &reqs); } @@ -363,7 +365,7 @@ } static void fcp_request(struct hpsb_host *host, int nodeid, int direction, - int cts, u8 *data, unsigned int length) + int cts, u8 *data, size_t length) { unsigned long flags; struct list_head *lh; @@ -539,9 +541,9 @@ if (khl != NULL) { req->req.error = RAW1394_ERROR_NONE; - req->req.length = MIN(req->req.length, - sizeof(struct raw1394_khost_list) - * req->req.misc); + req->req.length = min(req->req.length, + (u32)(sizeof(struct raw1394_khost_list) + * req->req.misc)); req->free_data = 1; } else { return -ENOMEM; @@ -602,7 +604,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; @@ -690,6 +692,21 @@ req->req.length = 0; break; + case RAW1394_REQ_ASYNC_STREAM: + DBGMSG("stream_request called"); + + packet = hpsb_make_streampacket(fi->host, NULL, req->req.length, node & 0x3f/*channel*/, + (req->req.misc >> 16) & 0x3, req->req.misc & 0xf); + if (!packet) + return -ENOMEM; + + if (copy_from_user(packet->data, int2ptr(req->req.sendb), + req->req.length)) + req->req.error = RAW1394_ERROR_MEMFAULT; + + req->req.length = 0; + break; + case RAW1394_REQ_LOCK: DBGMSG("lock_request called"); if ((req->req.misc == EXTCODE_FETCH_ADD) @@ -879,7 +896,7 @@ } static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer, - u64 addr, unsigned int length, u16 flags) + u64 addr, size_t length, u16 flags) { struct pending_request *req; struct list_head *lh; @@ -893,7 +910,7 @@ struct arm_request_response *arm_req_resp = NULL; DBGMSG("arm_read called by node: %X" - "addr: %4.4x %8.8x length: %u", nodeid, + "addr: %4.4x %8.8x length: %Zu", nodeid, (u16) ((addr >>32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF), length); spin_lock(&host_info_lock); @@ -1015,7 +1032,7 @@ } static int arm_write (struct hpsb_host *host, int nodeid, int destid, - quadlet_t *data, u64 addr, unsigned int length, u16 flags) + quadlet_t *data, u64 addr, size_t length, u16 flags) { struct pending_request *req; struct list_head *lh; @@ -1029,7 +1046,7 @@ struct arm_request_response *arm_req_resp = NULL; DBGMSG("arm_write called by node: %X" - "addr: %4.4x %8.8x length: %u", nodeid, + "addr: %4.4x %8.8x length: %Zu", nodeid, (u16) ((addr >>32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF), length); spin_lock(&host_info_lock); @@ -1567,8 +1584,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) & ~(0xFFFFFFFFFFFFULL)) != 0) || + (((req->req.address + req->req.length) & ~(0xFFFFFFFFFFFFULL)) != 0)) { req->req.length = 0; return (-EINVAL); } @@ -1579,7 +1596,7 @@ return (-ENOMEM); } /* allocation of addr_space_buffer */ - addr->addr_space_buffer = (u8 *)kmalloc(req->req.length,SLAB_KERNEL); + addr->addr_space_buffer = (u8 *)vmalloc(req->req.length); if (!(addr->addr_space_buffer)) { kfree(addr); req->req.length = 0; @@ -1593,7 +1610,7 @@ /* init: user -> kernel */ if (copy_from_user(addr->addr_space_buffer,int2ptr(req->req.sendb), req->req.length)) { - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); return (-EFAULT); } @@ -1634,7 +1651,7 @@ } if (same_host) { /* addressrange occupied by same host */ - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); spin_unlock_irqrestore(&host_info_lock, flags); return (-EALREADY); @@ -1669,7 +1686,7 @@ int2ptr(&addr->start),sizeof(u64))) { printk(KERN_ERR "raw1394: arm_register failed " " address-range-entry is invalid -> EFAULT !!!\n"); - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); spin_unlock_irqrestore(&host_info_lock, flags); return (-EFAULT); @@ -1687,7 +1704,7 @@ list_add_tail(&addr->addr_list, &fi->addr_list); } else { DBGMSG("arm_register failed errno: %d \n",retval); - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); spin_unlock_irqrestore(&host_info_lock, flags); return (-EALREADY); @@ -1761,7 +1778,7 @@ if (another_host) { DBGMSG("delete entry from list -> success"); list_del(&addr->addr_list); - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); free_pending_request(req); /* immediate success or fail */ spin_unlock_irqrestore(&host_info_lock, flags); @@ -1776,7 +1793,7 @@ DBGMSG("delete entry from list -> success"); list_del(&addr->addr_list); spin_unlock_irqrestore(&host_info_lock, flags); - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); free_pending_request(req); /* immediate success or fail */ return sizeof(struct raw1394_request); @@ -2009,7 +2026,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 +2042,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 +2072,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 +2097,10 @@ { struct raw1394_iso_status stat; - if(copy_from_user(&stat, uaddr, sizeof(stat))) + if (!fi->host) + return -EINVAL; + + if (copy_from_user(&stat, uaddr, sizeof(stat))) return -EFAULT; fi->iso_handle = hpsb_iso_xmit_init(fi->host, @@ -2090,13 +2110,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 +2129,10 @@ { struct raw1394_iso_status stat; - if(copy_from_user(&stat, uaddr, sizeof(stat))) + if (!fi->host) + return -EINVAL; + + if (copy_from_user(&stat, uaddr, sizeof(stat))) return -EFAULT; fi->iso_handle = hpsb_iso_recv_init(fi->host, @@ -2118,13 +2141,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 +2158,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 +2174,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 +2204,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 +2234,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 +2246,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 +2273,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 +2287,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 +2297,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 +2312,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 +2400,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++) { @@ -2433,7 +2458,7 @@ } DBGMSG("raw1394_release: delete addr_entry from list"); list_del(&addr->addr_list); - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); } /* while */ spin_unlock_irq(&host_info_lock); Index: drivers/ieee1394/raw1394.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/raw1394.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/raw1394.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/raw1394.h 4 Aug 2004 01:28:56 -0000 1.2 @@ -19,6 +19,7 @@ #define RAW1394_REQ_LOCK64 103 #define RAW1394_REQ_ISO_SEND 104 #define RAW1394_REQ_ASYNC_SEND 105 +#define RAW1394_REQ_ASYNC_STREAM 106 #define RAW1394_REQ_ISO_LISTEN 200 #define RAW1394_REQ_FCP_LISTEN 201 Index: drivers/ieee1394/sbp2.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/sbp2.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/sbp2.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/sbp2.c 4 Aug 2004 01:28:56 -0000 1.2 @@ -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: 1074 $ 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, }; @@ -643,7 +389,7 @@ sbp2util_allocate_write_packet(struct sbp2scsi_host_info *hi, struct node_entry *ne, u64 addr, size_t data_size, - quadlet_t *data) + quadlet_t *data, int complete) { struct hpsb_packet *packet; @@ -653,8 +399,9 @@ if (!packet) return NULL; - hpsb_set_packet_complete_task(packet, (void (*)(void*))sbp2_free_packet, - packet); + if (complete) + hpsb_set_packet_complete_task(packet, + (void (*)(void*))sbp2_free_packet, packet); hpsb_node_fill_packet(ne, packet); @@ -815,22 +562,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 +586,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 +620,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 +628,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 +639,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 +759,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 +770,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 +792,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 +935,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 +945,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++) { @@ -1192,6 +974,15 @@ return -EBUSY; } + /* Schedule a timeout here. The reason is that we may be so close + * to a bus reset, that the device is not available for logins. + * This can happen when the bus reset is caused by the host + * connected to the sbp2 device being removed. That host would + * have a certain amount of time to relogin before the sbp2 device + * allows someone else to login instead. One second makes sense. */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ); + /* * Login to the sbp-2 device */ @@ -1216,6 +1007,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 +1083,8 @@ SBP2_DEBUG("SBP-2 device removed, SCSI ID = %d", scsi_id->id); + list_del(&scsi_id->list); + kfree(scsi_id); } @@ -1295,7 +1094,7 @@ * physical dma in hardware). Mostly just here for debugging... */ static int sbp2_handle_physdma_write(struct hpsb_host *host, int nodeid, int destid, quadlet_t *data, - u64 addr, unsigned int length, u16 flags) + u64 addr, size_t length, u16 flags) { /* @@ -1311,7 +1110,7 @@ * physical dma in hardware). Mostly just here for debugging... */ static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_t *data, - u64 addr, unsigned int length, u16 flags) + u64 addr, size_t length, u16 flags) { /* @@ -1362,6 +1161,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 +1180,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 +1275,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 +1317,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 +1429,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 +1555,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 +1606,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 +1617,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 +1649,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 +1660,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 +1744,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); @@ -1922,7 +1773,7 @@ packet = sbp2util_allocate_write_packet(hi, scsi_id->ne, scsi_id->sbp2_command_block_agent_addr + SBP2_AGENT_RESET_OFFSET, - 4, &data); + 4, &data, wait ? 0 : 1); if (!packet) { SBP2_ERR("sbp2util_allocate_write_packet failed"); @@ -1938,6 +1789,7 @@ if (wait) { down(&packet->state_change); down(&packet->state_change); + sbp2_free_packet(packet); } /* @@ -2232,7 +2084,7 @@ packet = sbp2util_allocate_write_packet(hi, scsi_id->ne, scsi_id->sbp2_command_block_agent_addr + - SBP2_ORB_POINTER_OFFSET, 8, NULL); + SBP2_ORB_POINTER_OFFSET, 8, NULL, 1); if (!packet) { SBP2_ERR("sbp2util_allocate_write_packet failed"); @@ -2282,7 +2134,7 @@ packet = sbp2util_allocate_write_packet(hi, scsi_id->ne, scsi_id->sbp2_command_block_agent_addr + - SBP2_DOORBELL_OFFSET, 4, &data); + SBP2_DOORBELL_OFFSET, 4, &data, 1); if (!packet) { SBP2_ERR("sbp2util_allocate_write_packet failed"); @@ -2586,7 +2438,7 @@ * This function deals with status writes from the SBP-2 device */ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid, - quadlet_t *data, u64 addr, unsigned int length, u16 fl) + quadlet_t *data, u64 addr, size_t length, u16 fl) { struct sbp2scsi_host_info *hi = NULL; struct scsi_id_instance_data *scsi_id = NULL; @@ -3053,28 +2905,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 +2933,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 +2968,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 +3000,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)"); Index: drivers/ieee1394/sbp2.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/sbp2.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/sbp2.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/sbp2.h 4 Aug 2004 01:28:56 -0000 1.2 @@ -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,21 +469,22 @@ /* * 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 static int sbp2_handle_physdma_write(struct hpsb_host *host, int nodeid, int destid, quadlet_t *data, - u64 addr, unsigned int length, u16 flags); + u64 addr, size_t length, u16 flags); static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_t *data, - u64 addr, unsigned int length, u16 flags); + u64 addr, size_t length, u16 flags); #endif /* @@ -486,7 +495,7 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id); static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id); static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid, - quadlet_t *data, u64 addr, unsigned int length, u16 flags); + quadlet_t *data, u64 addr, size_t length, u16 flags); static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait); static int sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id, struct sbp2_command_info *command, @@ -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); Index: drivers/ieee1394/video1394.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/ieee1394/video1394.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/ieee1394/video1394.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/ieee1394/video1394.c 4 Aug 2004 01:28:56 -0000 1.2 @@ -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" @@ -216,6 +216,7 @@ d->frame_size = buf_size; d->buf_size = PAGE_ALIGN(buf_size); d->last_buffer = -1; + INIT_LIST_HEAD(&d->link); init_waitqueue_head(&d->waitq); /* Init the regions for easy cleanup */ @@ -594,7 +595,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 +714,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 +811,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 +825,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 +861,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 +925,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 +954,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 +996,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 +1008,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 +1022,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 +1046,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 +1101,10 @@ reg_write(ohci, d->ctrlSet, 0x1000); } } + + if (qv.packet_sizes) + kfree(qv.packet_sizes); + return 0; } @@ -1095,7 +1114,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 +1131,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, Index: drivers/input/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/input/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/input/Config.in 22 Jul 2004 19:50:13 -0000 1.1 +++ drivers/input/Config.in 4 Aug 2004 01:28:56 -0000 1.2 @@ -14,6 +14,7 @@ fi dep_tristate ' Joystick support' CONFIG_INPUT_JOYDEV $CONFIG_INPUT dep_tristate ' Event interface support' CONFIG_INPUT_EVDEV $CONFIG_INPUT +dep_tristate ' User level driver support' CONFIG_INPUT_UINPUT $CONFIG_INPUT dep_tristate ' MX1 touchscreen support' CONFIG_INPUT_MX1TS $CONFIG_INPUT_MOUSEDEV $CONFIG_ARCH_MX1ADS endmenu Index: drivers/input/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/input/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/input/Makefile 22 Jul 2004 19:50:13 -0000 1.1 +++ drivers/input/Makefile 4 Aug 2004 01:28:56 -0000 1.2 @@ -25,6 +25,7 @@ obj-$(CONFIG_INPUT_JOYDEV) += joydev.o obj-$(CONFIG_INPUT_EVDEV) += evdev.o obj-$(CONFIG_INPUT_MX1TS) += mx1ts.o +obj-$(CONFIG_INPUT_UINPUT) += uinput.o # The global Rules.make. Index: drivers/input/evdev.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/input/evdev.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/input/evdev.c 22 Jul 2004 19:50:13 -0000 1.1 +++ drivers/input/evdev.c 4 Aug 2004 01:28:56 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: evdev.c,v 1.1 2004/07/22 19:50:13 joff Exp $ + * $Id: evdev.c,v 1.2 2004/08/04 01:28:56 joff Exp $ * * Copyright (c) 1999-2001 Vojtech Pavlik * Index: drivers/input/input.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/input/input.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/input/input.c 22 Jul 2004 19:50:13 -0000 1.1 +++ drivers/input/input.c 4 Aug 2004 01:28:56 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: input.c,v 1.1 2004/07/22 19:50:13 joff Exp $ + * $Id: input.c,v 1.2 2004/08/04 01:28:56 joff Exp $ * * Copyright (c) 1999-2001 Vojtech Pavlik * @@ -422,7 +422,7 @@ static int __init input_init(void) { if (devfs_register_chrdev(INPUT_MAJOR, "input", &input_fops)) { - printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR); + printk(KERN_ERR "input: unable to register char major %d\n", INPUT_MAJOR); return -EBUSY; } input_devfs_handle = devfs_mk_dir(NULL, "input", NULL); Index: drivers/input/joydev.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/input/joydev.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/input/joydev.c 22 Jul 2004 19:50:13 -0000 1.1 +++ drivers/input/joydev.c 4 Aug 2004 01:28:56 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: joydev.c,v 1.1 2004/07/22 19:50:13 joff Exp $ + * $Id: joydev.c,v 1.2 2004/08/04 01:28:56 joff Exp $ * * Copyright (c) 1999-2000 Vojtech Pavlik * Copyright (c) 1999 Colin Van Dyke Index: drivers/input/keybdev.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/input/keybdev.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/input/keybdev.c 22 Jul 2004 19:50:13 -0000 1.1 +++ drivers/input/keybdev.c 4 Aug 2004 01:28:56 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: keybdev.c,v 1.1 2004/07/22 19:50:13 joff Exp $ + * $Id: keybdev.c,v 1.2 2004/08/04 01:28:56 joff Exp $ * * Copyright (c) 1999-2000 Vojtech Pavlik * @@ -154,16 +154,18 @@ static struct input_handler keybdev_handler; +static unsigned int ledstate = 0xff; + void keybdev_ledfunc(unsigned int led) { struct input_handle *handle; - for (handle = keybdev_handler.handle; handle; handle = handle->hnext) { + ledstate = led; + for (handle = keybdev_handler.handle; handle; handle = handle->hnext) { input_event(handle->dev, EV_LED, LED_SCROLLL, !!(led & 0x01)); input_event(handle->dev, EV_LED, LED_NUML, !!(led & 0x02)); input_event(handle->dev, EV_LED, LED_CAPSL, !!(led & 0x04)); - } } @@ -172,7 +174,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); } @@ -201,7 +204,12 @@ input_open_device(handle); // printk(KERN_INFO "keybdev.c: Adding keyboard: input%d\n", dev->number); - kbd_refresh_leds(); + + if (ledstate != 0xff) { + input_event(dev, EV_LED, LED_SCROLLL, !!(ledstate & 0x01)); + input_event(dev, EV_LED, LED_NUML, !!(ledstate & 0x02)); + input_event(dev, EV_LED, LED_CAPSL, !!(ledstate & 0x04)); + } return handle; } Index: drivers/input/mousedev.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/input/mousedev.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/input/mousedev.c 22 Jul 2004 19:50:13 -0000 1.1 +++ drivers/input/mousedev.c 4 Aug 2004 01:28:56 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: mousedev.c,v 1.1 2004/07/22 19:50:13 joff Exp $ + * $Id: mousedev.c,v 1.2 2004/08/04 01:28:56 joff Exp $ * * Copyright (c) 1999-2000 Vojtech Pavlik * Index: drivers/isdn/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/Config.in 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/Config.in 4 Aug 2004 01:28:56 -0000 1.2 @@ -8,6 +8,7 @@ if [ "$CONFIG_INET" != "n" ]; then bool ' Support synchronous PPP' CONFIG_ISDN_PPP if [ "$CONFIG_ISDN_PPP" != "n" ]; then + dep_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 Index: drivers/isdn/isdn_audio.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdn_audio.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdn_audio.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/isdn_audio.c 4 Aug 2004 01:28:56 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_audio.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: isdn_audio.c,v 1.2 2004/08/04 01:28:56 joff Exp $ * * Linux ISDN subsystem, audio conversion and compression (linklevel). * @@ -15,7 +15,7 @@ #include "isdn_audio.h" #include "isdn_common.h" -char *isdn_audio_revision = "$Revision: 1.1 $"; +char *isdn_audio_revision = "$Revision: 1.2 $"; /* * Misc. lookup-tables. Index: drivers/isdn/isdn_audio.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdn_audio.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdn_audio.h 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/isdn_audio.h 4 Aug 2004 01:28:56 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_audio.h,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: isdn_audio.h,v 1.2 2004/08/04 01:28:56 joff Exp $ * * Linux ISDN subsystem, audio conversion and compression (linklevel). * Index: drivers/isdn/isdn_common.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdn_common.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdn_common.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/isdn_common.c 4 Aug 2004 01:28:56 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_common.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: isdn_common.c,v 1.2 2004/08/04 01:28:56 joff Exp $ * * Linux ISDN subsystem, common used functions (linklevel). * @@ -44,7 +44,7 @@ isdn_dev *dev; -static char *isdn_revision = "$Revision: 1.1 $"; +static char *isdn_revision = "$Revision: 1.2 $"; extern char *isdn_net_revision; extern char *isdn_tty_revision; Index: drivers/isdn/isdn_common.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdn_common.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdn_common.h 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/isdn_common.h 4 Aug 2004 01:28:56 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_common.h,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: isdn_common.h,v 1.2 2004/08/04 01:28:56 joff Exp $ * * header for Linux ISDN subsystem * common used functions and debugging-switches (linklevel). Index: drivers/isdn/isdn_concap.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdn_concap.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdn_concap.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/isdn_concap.c 4 Aug 2004 01:28:56 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_concap.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: isdn_concap.c,v 1.2 2004/08/04 01:28:56 joff Exp $ * * Linux ISDN subsystem, protocol encapsulation * Index: drivers/isdn/isdn_concap.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdn_concap.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdn_concap.h 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/isdn_concap.h 4 Aug 2004 01:28:56 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_concap.h,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: isdn_concap.h,v 1.2 2004/08/04 01:28:56 joff Exp $ * * Linux ISDN subsystem, protocol encapsulation * Index: drivers/isdn/isdn_net.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdn_net.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdn_net.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/isdn_net.c 4 Aug 2004 01:28:56 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_net.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: isdn_net.c,v 1.2 2004/08/04 01:28:56 joff Exp $ * * Linux ISDN subsystem, network interfaces and related functions (linklevel). * @@ -183,7 +183,7 @@ static void isdn_net_ciscohdlck_connected(isdn_net_local *lp); static void isdn_net_ciscohdlck_disconnected(isdn_net_local *lp); -char *isdn_net_revision = "$Revision: 1.1 $"; +char *isdn_net_revision = "$Revision: 1.2 $"; /* * Code for raw-networking over ISDN @@ -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 Index: drivers/isdn/isdn_net.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdn_net.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdn_net.h 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/isdn_net.h 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_net.h,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: isdn_net.h,v 1.2 2004/08/04 01:28:57 joff Exp $ * * header for Linux ISDN subsystem, network related functions (linklevel). * Index: drivers/isdn/isdn_ppp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdn_ppp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdn_ppp.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/isdn_ppp.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_ppp.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: isdn_ppp.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Linux ISDN subsystem, functions for synchronous PPP (linklevel). * @@ -13,6 +13,9 @@ #include #include #include +#ifdef CONFIG_IPPP_FILTER +#include +#endif #include "isdn_common.h" #include "isdn_ppp.h" @@ -69,7 +72,7 @@ static int isdn_ppp_bundle(struct ippp_struct *, int unit); #endif /* CONFIG_ISDN_MPP */ -char *isdn_ppp_revision = "$Revision: 1.1 $"; +char *isdn_ppp_revision = "$Revision: 1.2 $"; static struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS]; @@ -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]; Index: drivers/isdn/isdn_ppp.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdn_ppp.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdn_ppp.h 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/isdn_ppp.h 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_ppp.h,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: isdn_ppp.h,v 1.2 2004/08/04 01:28:57 joff Exp $ * * header for Linux ISDN subsystem, functions for synchronous PPP (linklevel). * @@ -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); Index: drivers/isdn/isdn_tty.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdn_tty.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdn_tty.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/isdn_tty.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_tty.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: isdn_tty.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Linux ISDN subsystem, tty functions and AT-command emulator (linklevel). * @@ -53,7 +53,7 @@ static int si2bit[8] = {4, 1, 4, 4, 4, 4, 4, 4}; -char *isdn_tty_revision = "$Revision: 1.1 $"; +char *isdn_tty_revision = "$Revision: 1.2 $"; /* isdn_tty_try_read() is called from within isdn_tty_rcv_skb() Index: drivers/isdn/isdn_tty.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdn_tty.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdn_tty.h 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/isdn_tty.h 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_tty.h,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: isdn_tty.h,v 1.2 2004/08/04 01:28:57 joff Exp $ * * header for Linux ISDN subsystem, tty related functions (linklevel). * Index: drivers/isdn/isdn_ttyfax.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdn_ttyfax.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdn_ttyfax.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/isdn_ttyfax.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_ttyfax.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: isdn_ttyfax.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Linux ISDN subsystem, tty_fax AT-command emulator (linklevel). * @@ -20,7 +20,7 @@ #include "isdn_ttyfax.h" -static char *isdn_tty_fax_revision = "$Revision: 1.1 $"; +static char *isdn_tty_fax_revision = "$Revision: 1.2 $"; #define PARSE_ERROR1 { isdn_tty_fax_modem_result(1, info); return 1; } Index: drivers/isdn/isdn_ttyfax.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdn_ttyfax.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdn_ttyfax.h 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/isdn_ttyfax.h 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_ttyfax.h,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: isdn_ttyfax.h,v 1.2 2004/08/04 01:28:57 joff Exp $ * * header for Linux ISDN subsystem, tty_fax related functions (linklevel). * Index: drivers/isdn/isdn_v110.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdn_v110.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdn_v110.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/isdn_v110.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_v110.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: isdn_v110.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Linux ISDN subsystem, V.110 related functions (linklevel). * @@ -19,7 +19,7 @@ #undef ISDN_V110_DEBUG -char *isdn_v110_revision = "$Revision: 1.1 $"; +char *isdn_v110_revision = "$Revision: 1.2 $"; #define V110_38400 255 #define V110_19200 15 Index: drivers/isdn/isdn_v110.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdn_v110.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdn_v110.h 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/isdn_v110.h 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_v110.h,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: isdn_v110.h,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Linux ISDN subsystem, V.110 related functions (linklevel). * Index: drivers/isdn/isdn_x25iface.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdn_x25iface.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdn_x25iface.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/isdn_x25iface.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_x25iface.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: isdn_x25iface.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Linux ISDN subsystem, X.25 related functions * Index: drivers/isdn/isdn_x25iface.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdn_x25iface.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdn_x25iface.h 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/isdn_x25iface.h 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_x25iface.h,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: isdn_x25iface.h,v 1.2 2004/08/04 01:28:57 joff Exp $ * * header for Linux ISDN subsystem, x.25 related functions * Index: drivers/isdn/act2000/act2000.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/act2000/act2000.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/act2000/act2000.h 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/isdn/act2000/act2000.h 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: act2000.h,v 1.1 2004/07/22 19:49:58 joff Exp $ +/* $Id: act2000.h,v 1.2 2004/08/04 01:28:57 joff Exp $ * * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000. * Index: drivers/isdn/act2000/act2000_isa.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/act2000/act2000_isa.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/act2000/act2000_isa.c 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/isdn/act2000/act2000_isa.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: act2000_isa.c,v 1.1 2004/07/22 19:49:58 joff Exp $ +/* $Id: act2000_isa.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000 (ISA-Version). * Index: drivers/isdn/act2000/act2000_isa.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/act2000/act2000_isa.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/act2000/act2000_isa.h 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/isdn/act2000/act2000_isa.h 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: act2000_isa.h,v 1.1 2004/07/22 19:49:58 joff Exp $ +/* $Id: act2000_isa.h,v 1.2 2004/08/04 01:28:57 joff Exp $ * * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000 (ISA-Version). * Index: drivers/isdn/act2000/capi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/act2000/capi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/act2000/capi.c 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/isdn/act2000/capi.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: capi.c,v 1.1 2004/07/22 19:49:58 joff Exp $ +/* $Id: capi.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000. * CAPI encoder/decoder Index: drivers/isdn/act2000/capi.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/act2000/capi.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/act2000/capi.h 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/isdn/act2000/capi.h 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: capi.h,v 1.1 2004/07/22 19:49:58 joff Exp $ +/* $Id: capi.h,v 1.2 2004/08/04 01:28:57 joff Exp $ * * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000. * Index: drivers/isdn/act2000/module.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/act2000/module.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/act2000/module.c 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/isdn/act2000/module.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: module.c,v 1.1 2004/07/22 19:49:58 joff Exp $ +/* $Id: module.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000. * Index: drivers/isdn/avmb1/avm_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/avm_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/avm_cs.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/avmb1/avm_cs.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: avm_cs.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: avm_cs.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * A PCMCIA client driver for AVM B1/M1/M2 * Index: drivers/isdn/avmb1/avmcard.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/avmcard.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/avmcard.h 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/avmb1/avmcard.h 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: avmcard.h,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: avmcard.h,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Copyright 1999 by Carsten Paeth * Index: drivers/isdn/avmb1/b1.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/b1.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/b1.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/avmb1/b1.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: b1.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: b1.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Common module for AVM B1 cards. * @@ -27,7 +27,7 @@ #include "capicmd.h" #include "capiutil.h" -static char *revision = "$Revision: 1.1 $"; +static char *revision = "$Revision: 1.2 $"; /* ------------------------------------------------------------- */ Index: drivers/isdn/avmb1/b1dma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/b1dma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/b1dma.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/avmb1/b1dma.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: b1dma.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: b1dma.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Common module for AVM B1 cards that support dma with AMCC * @@ -28,7 +28,7 @@ #include "capicmd.h" #include "capiutil.h" -static char *revision = "$Revision: 1.1 $"; +static char *revision = "$Revision: 1.2 $"; /* ------------------------------------------------------------- */ Index: drivers/isdn/avmb1/b1isa.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/b1isa.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/b1isa.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/avmb1/b1isa.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: b1isa.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: b1isa.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Module for AVM B1 ISA-card. * @@ -24,7 +24,7 @@ #include "capilli.h" #include "avmcard.h" -static char *revision = "$Revision: 1.1 $"; +static char *revision = "$Revision: 1.2 $"; /* ------------------------------------------------------------- */ Index: drivers/isdn/avmb1/b1pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/b1pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/b1pci.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/avmb1/b1pci.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: b1pci.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: b1pci.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Module for AVM B1 PCI-card. * @@ -26,7 +26,7 @@ #include "capilli.h" #include "avmcard.h" -static char *revision = "$Revision: 1.1 $"; +static char *revision = "$Revision: 1.2 $"; /* ------------------------------------------------------------- */ Index: drivers/isdn/avmb1/b1pcmcia.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/b1pcmcia.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/b1pcmcia.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/avmb1/b1pcmcia.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: b1pcmcia.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: b1pcmcia.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Module for AVM B1/M1/M2 PCMCIA-card. * @@ -25,7 +25,7 @@ #include "capilli.h" #include "avmcard.h" -static char *revision = "$Revision: 1.1 $"; +static char *revision = "$Revision: 1.2 $"; /* ------------------------------------------------------------- */ Index: drivers/isdn/avmb1/c4.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/c4.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/c4.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/avmb1/c4.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: c4.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: c4.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Module for AVM C4 & C2 card. * @@ -29,7 +29,7 @@ #include "capilli.h" #include "avmcard.h" -static char *revision = "$Revision: 1.1 $"; +static char *revision = "$Revision: 1.2 $"; #undef CONFIG_C4_DEBUG #undef CONFIG_C4_POLLDEBUG Index: drivers/isdn/avmb1/capi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/capi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/capi.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/avmb1/capi.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: capi.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: capi.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * CAPI 2.0 Interface for Linux * @@ -45,7 +45,7 @@ #include "capifs.h" #endif -static char *revision = "$Revision: 1.1 $"; +static char *revision = "$Revision: 1.2 $"; MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface"); MODULE_AUTHOR("Carsten Paeth"); Index: drivers/isdn/avmb1/capicmd.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/capicmd.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/capicmd.h 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/avmb1/capicmd.h 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: capicmd.h,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: capicmd.h,v 1.2 2004/08/04 01:28:57 joff Exp $ * * CAPI 2.0 Interface for Linux * Index: drivers/isdn/avmb1/capidev.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/capidev.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/capidev.h 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/avmb1/capidev.h 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: capidev.h,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: capidev.h,v 1.2 2004/08/04 01:28:57 joff Exp $ * * CAPI 2.0 Interface for Linux * Index: drivers/isdn/avmb1/capidrv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/capidrv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/capidrv.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/avmb1/capidrv.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: capidrv.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: capidrv.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * ISDN4Linux Driver, using capi20 interface (kernelcapi) * @@ -35,7 +35,7 @@ #include "capicmd.h" #include "capidrv.h" -static char *revision = "$Revision: 1.1 $"; +static char *revision = "$Revision: 1.2 $"; static int debugmode = 0; MODULE_DESCRIPTION("CAPI4Linux: Interface to ISDN4Linux"); @@ -523,13 +523,25 @@ static void send_message(capidrv_contr * card, _cmsg * cmsg) { - struct sk_buff *skb; - size_t len; + struct sk_buff *skb; + size_t len; + u16 err; + capi_cmsg2message(cmsg, cmsg->buf); len = CAPIMSG_LEN(cmsg->buf); skb = alloc_skb(len, GFP_ATOMIC); + if(!skb) { + printk(KERN_ERR "no skb len(%d) memory\n", len); + return; + } memcpy(skb_put(skb, len), cmsg->buf, len); - (*capifuncs->capi_put_message) (global.appid, skb); + err = (*capifuncs->capi_put_message) (global.appid, skb); + if (err) { + printk(KERN_WARNING "%s: capi_put_message error: %04x\n", + __FUNCTION__, err); + kfree_skb(skb); + return; + } global.nsentctlpkt++; } @@ -2188,10 +2200,10 @@ free_ncci(card, card->bchans[card->nbchan-1].nccip); if (card->bchans[card->nbchan-1].plcip) free_plci(card, card->bchans[card->nbchan-1].plcip); - if (card->plci_list) - printk(KERN_ERR "capidrv: bug in free_plci()\n"); card->nbchan--; } + if (card->plci_list) + printk(KERN_ERR "capidrv: bug in free_plci()\n"); kfree(card->bchans); card->bchans = 0; Index: drivers/isdn/avmb1/capidrv.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/capidrv.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/capidrv.h 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/avmb1/capidrv.h 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: capidrv.h,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: capidrv.h,v 1.2 2004/08/04 01:28:57 joff Exp $ * * ISDN4Linux Driver, using capi20 interface (kernelcapi) * Index: drivers/isdn/avmb1/capifs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/capifs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/capifs.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/avmb1/capifs.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: capifs.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: capifs.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Copyright 2000 by Carsten Paeth * @@ -32,7 +32,7 @@ MODULE_AUTHOR("Carsten Paeth"); MODULE_LICENSE("GPL"); -static char *revision = "$Revision: 1.1 $"; +static char *revision = "$Revision: 1.2 $"; struct capifs_ncci { struct inode *inode; Index: drivers/isdn/avmb1/capifs.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/capifs.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/capifs.h 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/avmb1/capifs.h 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: capifs.h,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: capifs.h,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Copyright 2000 by Carsten Paeth * Index: drivers/isdn/avmb1/capilli.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/capilli.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/capilli.h 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/avmb1/capilli.h 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: capilli.h,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: capilli.h,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Kernel CAPI 2.0 Driver Interface for Linux * Index: drivers/isdn/avmb1/capiutil.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/capiutil.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/capiutil.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/avmb1/capiutil.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: capiutil.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: capiutil.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * CAPI 2.0 convert capi message to capi message struct * Index: drivers/isdn/avmb1/capiutil.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/capiutil.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/capiutil.h 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/avmb1/capiutil.h 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: capiutil.h,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: capiutil.h,v 1.2 2004/08/04 01:28:57 joff Exp $ * * CAPI 2.0 defines & types * Index: drivers/isdn/avmb1/kcapi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/kcapi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/kcapi.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/avmb1/kcapi.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: kcapi.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: kcapi.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Kernel CAPI 2.0 Module * @@ -33,7 +33,7 @@ #include #endif -static char *revision = "$Revision: 1.1 $"; +static char *revision = "$Revision: 1.2 $"; /* ------------------------------------------------------------- */ @@ -546,7 +546,13 @@ static void notify_up(__u32 contr) { struct capi_interface_user *p; + __u16 appl; + for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { + if (!VALID_APPLID(appl)) continue; + if (APPL(appl)->releasing) continue; + CARD(contr)->driver->register_appl(CARD(contr), appl, &APPL(appl)->rparam); + } printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr); spin_lock(&capi_users_lock); for (p = capi_users; p; p = p->next) { @@ -714,12 +720,16 @@ nextpp = &(*pp)->next; } } - APPL(appl)->releasing--; - if (APPL(appl)->releasing <= 0) { - APPL(appl)->signal = 0; - APPL_MARK_FREE(appl); - printk(KERN_INFO "kcapi: appl %d down\n", appl); - } + if (APPL(appl)->releasing) { /* only release if the application was marked for release */ + printk(KERN_DEBUG "kcapi: appl %d releasing(%d)\n", appl, APPL(appl)->releasing); + APPL(appl)->releasing--; + if (APPL(appl)->releasing <= 0) { + APPL(appl)->signal = 0; + APPL_MARK_FREE(appl); + printk(KERN_INFO "kcapi: appl %d down\n", appl); + } + } else + printk(KERN_WARNING "kcapi: appl %d card%d released without request\n", appl, card->cnr); } /* * ncci management @@ -872,16 +882,7 @@ static void controllercb_ready(struct capi_ctr * card) { - __u16 appl; - card->cardstate = CARD_RUNNING; - - for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { - if (!VALID_APPLID(appl)) continue; - if (APPL(appl)->releasing) continue; - card->driver->register_appl(card, appl, &APPL(appl)->rparam); - } - printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n", CARDNR(card), card->name); Index: drivers/isdn/avmb1/t1isa.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/t1isa.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/t1isa.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/avmb1/t1isa.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: t1isa.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: t1isa.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Module for AVM T1 HEMA-card. * @@ -25,7 +25,7 @@ #include "capilli.h" #include "avmcard.h" -static char *revision = "$Revision: 1.1 $"; +static char *revision = "$Revision: 1.2 $"; /* ------------------------------------------------------------- */ Index: drivers/isdn/avmb1/t1pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/avmb1/t1pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/avmb1/t1pci.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/avmb1/t1pci.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: t1pci.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: t1pci.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Module for AVM T1 PCI-card. * @@ -26,7 +26,7 @@ #include "capilli.h" #include "avmcard.h" -static char *revision = "$Revision: 1.1 $"; +static char *revision = "$Revision: 1.2 $"; #undef CONFIG_T1PCI_DEBUG #undef CONFIG_T1PCI_POLLDEBUG Index: drivers/isdn/divert/divert_procfs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/divert/divert_procfs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/divert/divert_procfs.c 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/isdn/divert/divert_procfs.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: divert_procfs.c,v 1.1 2004/07/22 19:49:58 joff Exp $ +/* $Id: divert_procfs.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Filesystem handling for the diversion supplementary services. * Index: drivers/isdn/divert/isdn_divert.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/divert/isdn_divert.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/divert/isdn_divert.c 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/isdn/divert/isdn_divert.c 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_divert.c,v 1.1 2004/07/22 19:49:58 joff Exp $ +/* $Id: isdn_divert.c,v 1.2 2004/08/04 01:28:57 joff Exp $ * * DSS1 main diversion supplementary handling for i4l. * Index: drivers/isdn/divert/isdn_divert.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/divert/isdn_divert.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/divert/isdn_divert.h 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/isdn/divert/isdn_divert.h 4 Aug 2004 01:28:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdn_divert.h,v 1.1 2004/07/22 19:49:58 joff Exp $ +/* $Id: isdn_divert.h,v 1.2 2004/08/04 01:28:57 joff Exp $ * * Header for the diversion supplementary ioctl interface. * Index: drivers/isdn/eicon/eicon.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/eicon/eicon.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/eicon/eicon.h 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/eicon/eicon.h 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: eicon.h,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: eicon.h,v 1.2 2004/08/04 01:28:58 joff Exp $ * * ISDN low-level module for Eicon active ISDN-Cards. * Index: drivers/isdn/eicon/eicon_dsp.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/eicon/eicon_dsp.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/eicon/eicon_dsp.h 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/eicon/eicon_dsp.h 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: eicon_dsp.h,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: eicon_dsp.h,v 1.2 2004/08/04 01:28:58 joff Exp $ * * ISDN lowlevel-module for Eicon active cards. * DSP definitions Index: drivers/isdn/eicon/eicon_idi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/eicon/eicon_idi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/eicon/eicon_idi.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/eicon/eicon_idi.c 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: eicon_idi.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: eicon_idi.c,v 1.2 2004/08/04 01:28:58 joff Exp $ * * ISDN lowlevel-module for Eicon active cards. * IDI interface @@ -25,7 +25,7 @@ #undef EICON_FULL_SERVICE_OKTETT -char *eicon_idi_revision = "$Revision: 1.1 $"; +char *eicon_idi_revision = "$Revision: 1.2 $"; eicon_manifbuf *manbuf; Index: drivers/isdn/eicon/eicon_idi.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/eicon/eicon_idi.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/eicon/eicon_idi.h 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/eicon/eicon_idi.h 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: eicon_idi.h,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: eicon_idi.h,v 1.2 2004/08/04 01:28:58 joff Exp $ * * ISDN lowlevel-module for the Eicon active cards. * IDI-Interface Index: drivers/isdn/eicon/eicon_io.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/eicon/eicon_io.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/eicon/eicon_io.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/eicon/eicon_io.c 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: eicon_io.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: eicon_io.c,v 1.2 2004/08/04 01:28:58 joff Exp $ * * ISDN low-level module for Eicon active ISDN-Cards. * Code for communicating with hardware. Index: drivers/isdn/eicon/eicon_isa.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/eicon/eicon_isa.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/eicon/eicon_isa.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/eicon/eicon_isa.c 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: eicon_isa.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: eicon_isa.c,v 1.2 2004/08/04 01:28:58 joff Exp $ * * ISDN low-level module for Eicon active ISDN-Cards. * Hardware-specific code for old ISA cards. @@ -20,7 +20,7 @@ #define release_shmem release_region #define request_shmem request_region -char *eicon_isa_revision = "$Revision: 1.1 $"; +char *eicon_isa_revision = "$Revision: 1.2 $"; #undef EICON_MCA_DEBUG Index: drivers/isdn/eicon/eicon_isa.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/eicon/eicon_isa.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/eicon/eicon_isa.h 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/eicon/eicon_isa.h 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: eicon_isa.h,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: eicon_isa.h,v 1.2 2004/08/04 01:28:58 joff Exp $ * * ISDN low-level module for Eicon active ISDN-Cards. * Index: drivers/isdn/eicon/eicon_mod.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/eicon/eicon_mod.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/eicon/eicon_mod.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/eicon/eicon_mod.c 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: eicon_mod.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: eicon_mod.c,v 1.2 2004/08/04 01:28:58 joff Exp $ * * ISDN lowlevel-module for Eicon active cards. * @@ -44,7 +44,7 @@ static eicon_card *cards = (eicon_card *) NULL; /* glob. var , contains start of card-list */ -static char *eicon_revision = "$Revision: 1.1 $"; +static char *eicon_revision = "$Revision: 1.2 $"; extern char *eicon_pci_revision; extern char *eicon_isa_revision; Index: drivers/isdn/eicon/eicon_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/eicon/eicon_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/eicon/eicon_pci.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/eicon/eicon_pci.c 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: eicon_pci.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: eicon_pci.c,v 1.2 2004/08/04 01:28:58 joff Exp $ * * ISDN low-level module for Eicon active ISDN-Cards. * Hardware-specific code for PCI cards. @@ -24,7 +24,7 @@ #include "adapter.h" #include "uxio.h" -char *eicon_pci_revision = "$Revision: 1.1 $"; +char *eicon_pci_revision = "$Revision: 1.2 $"; #if CONFIG_PCI /* intire stuff is only for PCI */ #ifdef CONFIG_ISDN_DRV_EICON_PCI Index: drivers/isdn/eicon/eicon_pci.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/eicon/eicon_pci.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/eicon/eicon_pci.h 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/eicon/eicon_pci.h 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: eicon_pci.h,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: eicon_pci.h,v 1.2 2004/08/04 01:28:58 joff Exp $ * * ISDN low-level module for Eicon active ISDN-Cards (PCI part). * Index: drivers/isdn/hisax/amd7930_fn.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/amd7930_fn.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/amd7930_fn.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/amd7930_fn.c 4 Aug 2004 01:28:58 -0000 1.2 @@ -61,6 +61,40 @@ #include #include +static WORD initAMD[] __devinitdata = { + 0x0100, + + 0x00A5, 3, 0x01, 0x40, 0x58, // LPR, LMR1, LMR2 + 0x0086, 1, 0x0B, // DMR1 (D-Buffer TH-Interrupts on) + 0x0087, 1, 0xFF, // DMR2 + 0x0092, 1, 0x03, // EFCR (extended mode d-channel-fifo on) + 0x0090, 4, 0xFE, 0xFF, 0x02, 0x0F, // FRAR4, SRAR4, DMR3, DMR4 (address recognition ) + 0x0084, 2, 0x80, 0x00, // DRLR + 0x00C0, 1, 0x47, // PPCR1 + 0x00C8, 1, 0x01, // PPCR2 + + 0x0102, + 0x0107, + 0x01A1, 1, + 0x0121, 1, + 0x0189, 2, + + 0x0045, 4, 0x61, 0x72, 0x00, 0x00, // MCR1, MCR2, MCR3, MCR4 + 0x0063, 2, 0x08, 0x08, // GX + 0x0064, 2, 0x08, 0x08, // GR + 0x0065, 2, 0x99, 0x00, // GER + 0x0066, 2, 0x7C, 0x8B, // STG + 0x0067, 2, 0x00, 0x00, // FTGR1, FTGR2 + 0x0068, 2, 0x20, 0x20, // ATGR1, ATGR2 + 0x0069, 1, 0x4F, // MMR1 + 0x006A, 1, 0x00, // MMR2 + 0x006C, 1, 0x40, // MMR3 + 0x0021, 1, 0x02, // INIT + 0x00A3, 1, 0x40, // LMR1 + + 0xFFFF}; + + static void Amd7930_new_ph(struct IsdnCardState *cs); Index: drivers/isdn/hisax/amd7930_fn.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/amd7930_fn.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/amd7930_fn.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/amd7930_fn.h 4 Aug 2004 01:28:58 -0000 1.2 @@ -32,38 +32,5 @@ #define DBUSY_TIMER_VALUE 80 -static WORD initAMD[] = { - 0x0100, - - 0x00A5, 3, 0x01, 0x40, 0x58, // LPR, LMR1, LMR2 - 0x0086, 1, 0x0B, // DMR1 (D-Buffer TH-Interrupts on) - 0x0087, 1, 0xFF, // DMR2 - 0x0092, 1, 0x03, // EFCR (extended mode d-channel-fifo on) - 0x0090, 4, 0xFE, 0xFF, 0x02, 0x0F, // FRAR4, SRAR4, DMR3, DMR4 (address recognition ) - 0x0084, 2, 0x80, 0x00, // DRLR - 0x00C0, 1, 0x47, // PPCR1 - 0x00C8, 1, 0x01, // PPCR2 - - 0x0102, - 0x0107, - 0x01A1, 1, - 0x0121, 1, - 0x0189, 2, - - 0x0045, 4, 0x61, 0x72, 0x00, 0x00, // MCR1, MCR2, MCR3, MCR4 - 0x0063, 2, 0x08, 0x08, // GX - 0x0064, 2, 0x08, 0x08, // GR - 0x0065, 2, 0x99, 0x00, // GER - 0x0066, 2, 0x7C, 0x8B, // STG - 0x0067, 2, 0x00, 0x00, // FTGR1, FTGR2 - 0x0068, 2, 0x20, 0x20, // ATGR1, ATGR2 - 0x0069, 1, 0x4F, // MMR1 - 0x006A, 1, 0x00, // MMR2 - 0x006C, 1, 0x40, // MMR3 - 0x0021, 1, 0x02, // INIT - 0x00A3, 1, 0x40, // LMR1 - - 0xFFFF}; - extern void Amd7930_interrupt(struct IsdnCardState *cs, unsigned char irflags); extern void Amd7930_init(struct IsdnCardState *cs); Index: drivers/isdn/hisax/arcofi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/arcofi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/arcofi.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/arcofi.c 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: arcofi.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: arcofi.c,v 1.2 2004/08/04 01:28:58 joff Exp $ * * Ansteuerung ARCOFI 2165 * Index: drivers/isdn/hisax/arcofi.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/arcofi.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/arcofi.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/arcofi.h 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: arcofi.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: arcofi.h,v 1.2 2004/08/04 01:28:58 joff Exp $ * * Ansteuerung ARCOFI 2165 * Index: drivers/isdn/hisax/asuscom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/asuscom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/asuscom.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/asuscom.c 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: asuscom.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: asuscom.c,v 1.2 2004/08/04 01:28:58 joff Exp $ * * low level stuff for ASUSCOM NETWORK INC. ISDNLink cards * @@ -23,7 +23,7 @@ extern const char *CardType[]; -const char *Asuscom_revision = "$Revision: 1.1 $"; +const char *Asuscom_revision = "$Revision: 1.2 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) Index: drivers/isdn/hisax/avm_a1.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/avm_a1.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/avm_a1.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/avm_a1.c 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: avm_a1.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: avm_a1.c,v 1.2 2004/08/04 01:28:58 joff Exp $ * * low level stuff for AVM A1 (Fritz) isdn cards * @@ -18,7 +18,7 @@ #include "isdnl1.h" extern const char *CardType[]; -static const char *avm_revision = "$Revision: 1.1 $"; +static const char *avm_revision = "$Revision: 1.2 $"; #define AVM_A1_STAT_ISAC 0x01 #define AVM_A1_STAT_HSCX 0x02 Index: drivers/isdn/hisax/avm_a1p.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/avm_a1p.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/avm_a1p.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/hisax/avm_a1p.c 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: avm_a1p.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: avm_a1p.c,v 1.2 2004/08/04 01:28:58 joff Exp $ * * low level stuff for the following AVM cards: * A1 PCMCIA @@ -57,7 +57,7 @@ #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) -static const char *avm_revision = "$Revision: 1.1 $"; +static const char *avm_revision = "$Revision: 1.2 $"; static inline u_char ReadISAC(struct IsdnCardState *cs, u_char offset) Index: drivers/isdn/hisax/avm_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/avm_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/avm_pci.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/hisax/avm_pci.c 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: avm_pci.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: avm_pci.c,v 1.2 2004/08/04 01:28:58 joff Exp $ * * low level stuff for AVM Fritz!PCI and ISA PnP isdn cards * @@ -23,7 +23,7 @@ #include extern const char *CardType[]; -static const char *avm_pci_rev = "$Revision: 1.1 $"; +static const char *avm_pci_rev = "$Revision: 1.2 $"; #define AVM_FRITZ_PCI 1 #define AVM_FRITZ_PNP 2 Index: drivers/isdn/hisax/avma1_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/avma1_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/avma1_cs.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/avma1_cs.c 4 Aug 2004 01:28:58 -0000 1.2 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include Index: drivers/isdn/hisax/bkm_a4t.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/bkm_a4t.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/bkm_a4t.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/hisax/bkm_a4t.c 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: bkm_a4t.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: bkm_a4t.c,v 1.2 2004/08/04 01:28:58 joff Exp $ * * low level stuff for T-Berkom A4T * @@ -24,7 +24,7 @@ extern const char *CardType[]; -const char *bkm_a4t_revision = "$Revision: 1.1 $"; +const char *bkm_a4t_revision = "$Revision: 1.2 $"; static inline u_char Index: drivers/isdn/hisax/bkm_a8.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/bkm_a8.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/bkm_a8.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/bkm_a8.c 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: bkm_a8.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: bkm_a8.c,v 1.2 2004/08/04 01:28:58 joff Exp $ * * low level stuff for Scitel Quadro (4*S0, passive) * @@ -28,7 +28,7 @@ extern const char *CardType[]; -const char sct_quadro_revision[] = "$Revision: 1.1 $"; +const char sct_quadro_revision[] = "$Revision: 1.2 $"; static const char *sct_quadro_subtypes[] = { Index: drivers/isdn/hisax/bkm_ax.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/bkm_ax.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/bkm_ax.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/bkm_ax.h 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: bkm_ax.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: bkm_ax.h,v 1.2 2004/08/04 01:28:58 joff Exp $ * * low level decls for T-Berkom cards A4T and Scitel Quadro (4*S0, passive) * Index: drivers/isdn/hisax/callc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/callc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/callc.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/callc.c 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: callc.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: callc.c,v 1.2 2004/08/04 01:28:58 joff Exp $ * * Author Karsten Keil * Copyright by Karsten Keil @@ -26,7 +26,7 @@ #define MOD_USE_COUNT ( GET_USE_COUNT (&__this_module)) #endif /* MODULE */ -const char *lli_revision = "$Revision: 1.1 $"; +const char *lli_revision = "$Revision: 1.2 $"; extern struct IsdnCard cards[]; extern int nrcards; Index: drivers/isdn/hisax/cert.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/cert.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/cert.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/cert.c 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: cert.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: cert.c,v 1.2 2004/08/04 01:28:58 joff Exp $ * * Author Karsten Keil * Copyright by Karsten Keil Index: drivers/isdn/hisax/config.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/config.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/config.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/config.c 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: config.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: config.c,v 1.2 2004/08/04 01:28:58 joff Exp $ * * Author Karsten Keil * Copyright by Karsten Keil @@ -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; Index: drivers/isdn/hisax/diva.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/diva.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/diva.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/diva.c 4 Aug 2004 01:28:58 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: diva.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: diva.c,v 1.2 2004/08/04 01:28:58 joff Exp $ * * low level stuff for Eicon.Diehl Diva Family ISDN cards * @@ -29,7 +29,7 @@ extern const char *CardType[]; -const char *Diva_revision = "$Revision: 1.1 $"; +const char *Diva_revision = "$Revision: 1.2 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) Index: drivers/isdn/hisax/elsa.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/elsa.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/elsa.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/elsa.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: elsa.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: elsa.c,v 1.2 2004/08/04 01:28:59 joff Exp $ * * low level stuff for Elsa isdn cards * @@ -34,7 +34,7 @@ extern const char *CardType[]; -const char *Elsa_revision = "$Revision: 1.1 $"; +const char *Elsa_revision = "$Revision: 1.2 $"; const char *Elsa_Types[] = {"None", "PC", "PCC-8", "PCC-16", "PCF", "PCF-Pro", "PCMCIA", "QS 1000", "QS 3000", "Microlink PCI", "QS 3000 PCI", Index: drivers/isdn/hisax/elsa_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/elsa_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/elsa_cs.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/hisax/elsa_cs.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -72,7 +72,7 @@ MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); static char *version = -"elsa_cs.c $Revision: 1.1 $ $Date: 2004/07/22 19:49:56 $ (K.Lichtenwalder)"; +"elsa_cs.c $Revision: 1.2 $ $Date: 2004/08/04 01:28:59 $ (K.Lichtenwalder)"; #else #define DEBUG(n, args...) #endif Index: drivers/isdn/hisax/elsa_ser.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/elsa_ser.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/elsa_ser.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/elsa_ser.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: elsa_ser.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: elsa_ser.c,v 1.2 2004/08/04 01:28:59 joff Exp $ * * stuff for the serial modem on ELSA cards * Index: drivers/isdn/hisax/enternow_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/enternow_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/enternow_pci.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/hisax/enternow_pci.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -75,7 +75,7 @@ -const char *enternow_pci_rev = "$Revision: 1.1 $"; +const char *enternow_pci_rev = "$Revision: 1.2 $"; /* *************************** I/O-Interface functions ************************************* */ Index: drivers/isdn/hisax/fsm.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/fsm.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/fsm.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/hisax/fsm.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: fsm.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: fsm.c,v 1.2 2004/08/04 01:28:59 joff Exp $ * * Finite state machine * Index: drivers/isdn/hisax/fsm.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/fsm.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/fsm.h 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/hisax/fsm.h 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: fsm.h,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: fsm.h,v 1.2 2004/08/04 01:28:59 joff Exp $ * * Finite state machine * Index: drivers/isdn/hisax/gazel.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/gazel.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/gazel.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/gazel.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: gazel.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: gazel.c,v 1.2 2004/08/04 01:28:59 joff Exp $ * * low level stuff for Gazel isdn cards * @@ -22,7 +22,7 @@ #include extern const char *CardType[]; -const char *gazel_revision = "$Revision: 1.1 $"; +const char *gazel_revision = "$Revision: 1.2 $"; #define R647 1 #define R685 2 Index: drivers/isdn/hisax/hfc_2bds0.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/hfc_2bds0.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/hfc_2bds0.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/hfc_2bds0.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hfc_2bds0.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: hfc_2bds0.c,v 1.2 2004/08/04 01:28:59 joff Exp $ * * specific routines for CCD's HFC 2BDS0 * Index: drivers/isdn/hisax/hfc_2bds0.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/hfc_2bds0.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/hfc_2bds0.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/hfc_2bds0.h 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hfc_2bds0.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: hfc_2bds0.h,v 1.2 2004/08/04 01:28:59 joff Exp $ * * specific defines for CCD's HFC 2BDS0 * Index: drivers/isdn/hisax/hfc_2bs0.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/hfc_2bs0.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/hfc_2bs0.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/hfc_2bs0.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hfc_2bs0.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: hfc_2bs0.c,v 1.2 2004/08/04 01:28:59 joff Exp $ * * specific routines for CCD's HFC 2BS0 * Index: drivers/isdn/hisax/hfc_2bs0.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/hfc_2bs0.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/hfc_2bs0.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/hfc_2bs0.h 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hfc_2bs0.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: hfc_2bs0.h,v 1.2 2004/08/04 01:28:59 joff Exp $ * * specific defines for CCD's HFC 2BS0 * Index: drivers/isdn/hisax/hfc_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/hfc_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/hfc_pci.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/hisax/hfc_pci.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hfc_pci.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: hfc_pci.c,v 1.2 2004/08/04 01:28:59 joff Exp $ * * low level driver for CCD´s hfc-pci based cards * @@ -26,7 +26,7 @@ extern const char *CardType[]; -static const char *hfcpci_revision = "$Revision: 1.1 $"; +static const char *hfcpci_revision = "$Revision: 1.2 $"; /* table entry in the PCI devices list */ typedef struct { Index: drivers/isdn/hisax/hfc_pci.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/hfc_pci.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/hfc_pci.h 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/hisax/hfc_pci.h 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hfc_pci.h,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: hfc_pci.h,v 1.2 2004/08/04 01:28:59 joff Exp $ * * specific defines for CCD's HFC 2BDS0 PCI chips * Index: drivers/isdn/hisax/hfc_sx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/hfc_sx.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/hfc_sx.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/hisax/hfc_sx.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hfc_sx.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: hfc_sx.c,v 1.2 2004/08/04 01:28:59 joff Exp $ * * level driver for CCD´s hfc-s+/sp based cards * @@ -21,7 +21,7 @@ extern const char *CardType[]; -static const char *hfcsx_revision = "$Revision: 1.1 $"; +static const char *hfcsx_revision = "$Revision: 1.2 $"; /***************************************/ /* IRQ-table for CCDs demo board */ Index: drivers/isdn/hisax/hfc_sx.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/hfc_sx.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/hfc_sx.h 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/hisax/hfc_sx.h 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hfc_sx.h,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: hfc_sx.h,v 1.2 2004/08/04 01:28:59 joff Exp $ * * specific defines for CCD's HFC 2BDS0 S+,SP chips * Index: drivers/isdn/hisax/hfcscard.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/hfcscard.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/hfcscard.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/hfcscard.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hfcscard.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: hfcscard.c,v 1.2 2004/08/04 01:28:59 joff Exp $ * * low level stuff for hfcs based cards (Teles3c, ACER P10) * @@ -19,7 +19,7 @@ extern const char *CardType[]; -static const char *hfcs_revision = "$Revision: 1.1 $"; +static const char *hfcs_revision = "$Revision: 1.2 $"; static void hfcs_interrupt(int intno, void *dev_id, struct pt_regs *regs) Index: drivers/isdn/hisax/hisax.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/hisax.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/hisax.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/hisax.h 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hisax.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: hisax.h,v 1.2 2004/08/04 01:28:59 joff Exp $ * * Basic declarations, defines and prototypes * Index: drivers/isdn/hisax/hisax_fcpcipnp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/hisax_fcpcipnp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/hisax_fcpcipnp.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/hisax_fcpcipnp.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -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) Index: drivers/isdn/hisax/hscx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/hscx.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/hscx.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/hscx.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hscx.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: hscx.c,v 1.2 2004/08/04 01:28:59 joff Exp $ * * HSCX specific routines * Index: drivers/isdn/hisax/hscx.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/hscx.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/hscx.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/hscx.h 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hscx.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: hscx.h,v 1.2 2004/08/04 01:28:59 joff Exp $ * * HSCX specific defines * Index: drivers/isdn/hisax/hscx_irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/hscx_irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/hscx_irq.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/hscx_irq.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hscx_irq.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: hscx_irq.c,v 1.2 2004/08/04 01:28:59 joff Exp $ * * low level b-channel stuff for Siemens HSCX * Index: drivers/isdn/hisax/icc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/icc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/icc.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/hisax/icc.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: icc.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: icc.c,v 1.2 2004/08/04 01:28:59 joff Exp $ * * ICC specific routines * Index: drivers/isdn/hisax/icc.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/icc.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/icc.h 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/hisax/icc.h 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: icc.h,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: icc.h,v 1.2 2004/08/04 01:28:59 joff Exp $ * * ICC specific routines * Index: drivers/isdn/hisax/ipac.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/ipac.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/ipac.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/ipac.h 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ipac.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: ipac.h,v 1.2 2004/08/04 01:28:59 joff Exp $ * * IPAC specific defines * Index: drivers/isdn/hisax/isac.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/isac.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/isac.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/isac.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isac.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: isac.c,v 1.2 2004/08/04 01:28:59 joff Exp $ * * ISAC specific routines * Index: drivers/isdn/hisax/isac.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/isac.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/isac.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/isac.h 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isac.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: isac.h,v 1.2 2004/08/04 01:28:59 joff Exp $ * * ISAC specific defines * Index: drivers/isdn/hisax/isar.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/isar.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/isar.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/isar.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isar.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: isar.c,v 1.2 2004/08/04 01:28:59 joff Exp $ * * isar.c ISAR (Siemens PSB 7110) specific routines * Index: drivers/isdn/hisax/isar.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/isar.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/isar.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/isar.h 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isar.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: isar.h,v 1.2 2004/08/04 01:28:59 joff Exp $ * * ISAR (Siemens PSB 7110) specific defines * Index: drivers/isdn/hisax/isdnl1.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/isdnl1.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/isdnl1.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/isdnl1.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdnl1.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: isdnl1.c,v 1.2 2004/08/04 01:28:59 joff Exp $ * * common low level stuff for Siemens Chipsetbased isdn cards * @@ -18,7 +18,7 @@ * */ -const char *l1_revision = "$Revision: 1.1 $"; +const char *l1_revision = "$Revision: 1.2 $"; #define __NO_VERSION__ #include Index: drivers/isdn/hisax/isdnl1.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/isdnl1.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/isdnl1.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/isdnl1.h 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdnl1.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: isdnl1.h,v 1.2 2004/08/04 01:28:59 joff Exp $ * * Layer 1 defines * Index: drivers/isdn/hisax/isdnl2.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/isdnl2.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/isdnl2.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/isdnl2.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdnl2.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: isdnl2.c,v 1.2 2004/08/04 01:28:59 joff Exp $ * * Author Karsten Keil * based on the teles driver from Jan den Ouden @@ -20,7 +20,7 @@ #include "hisax.h" #include "isdnl2.h" -const char *l2_revision = "$Revision: 1.1 $"; +const char *l2_revision = "$Revision: 1.2 $"; static void l2m_debug(struct FsmInst *fi, char *fmt, ...); Index: drivers/isdn/hisax/isdnl2.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/isdnl2.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/isdnl2.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/isdnl2.h 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdnl2.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: isdnl2.h,v 1.2 2004/08/04 01:28:59 joff Exp $ * * Layer 2 defines * Index: drivers/isdn/hisax/isdnl3.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/isdnl3.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/isdnl3.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/isdnl3.c 4 Aug 2004 01:28:59 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdnl3.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: isdnl3.c,v 1.2 2004/08/04 01:28:59 joff Exp $ * * Author Karsten Keil * based on the teles driver from Jan den Ouden @@ -21,7 +21,7 @@ #include "isdnl3.h" #include -const char *l3_revision = "$Revision: 1.1 $"; +const char *l3_revision = "$Revision: 1.2 $"; static struct Fsm l3fsm; Index: drivers/isdn/hisax/isdnl3.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/isdnl3.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/isdnl3.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/isdnl3.h 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdnl3.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: isdnl3.h,v 1.2 2004/08/04 01:29:00 joff Exp $ * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. Index: drivers/isdn/hisax/isurf.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/isurf.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/isurf.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/isurf.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isurf.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: isurf.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * low level stuff for Siemens I-Surf/I-Talk cards * @@ -20,7 +20,7 @@ extern const char *CardType[]; -static const char *ISurf_revision = "$Revision: 1.1 $"; +static const char *ISurf_revision = "$Revision: 1.2 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -235,8 +235,18 @@ pd->prepare(pd); pd->deactivate(pd); pd->activate(pd); + /* The ISA-PnP logic apparently + * expects upper limit address to be + * set. Since the isa-pnp module + * doesn't do this, so we have to make + * up for it. + */ + isapnp_cfg_begin(pd->bus->number, pd->devfn); + isapnp_write_word(ISAPNP_CFG_MEM+3, + pd->resource[8].end >> 8); + isapnp_cfg_end(); cs->hw.isurf.reset = pd->resource[0].start; - cs->hw.isurf.phymem = pd->resource[1].start; + cs->hw.isurf.phymem = pd->resource[8].start; cs->irq = pd->irq_resource[0].start; if (!cs->irq || !cs->hw.isurf.reset || !cs->hw.isurf.phymem) { printk(KERN_ERR "ISurfPnP:some resources are missing %d/%x/%lx\n", Index: drivers/isdn/hisax/ix1_micro.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/ix1_micro.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/ix1_micro.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/ix1_micro.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ix1_micro.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: ix1_micro.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * low level stuff for ITK ix1-micro Rev.2 isdn cards * derived from the original file teles3.c from Karsten Keil @@ -26,7 +26,7 @@ #include "isdnl1.h" extern const char *CardType[]; -const char *ix1_revision = "$Revision: 1.1 $"; +const char *ix1_revision = "$Revision: 1.2 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) Index: drivers/isdn/hisax/jade.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/jade.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/jade.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/jade.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: jade.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: jade.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * JADE stuff (derived from original hscx.c) * Index: drivers/isdn/hisax/jade.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/jade.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/jade.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/jade.h 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: jade.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: jade.h,v 1.2 2004/08/04 01:29:00 joff Exp $ * * JADE specific defines * Index: drivers/isdn/hisax/jade_irq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/jade_irq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/jade_irq.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/jade_irq.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: jade_irq.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: jade_irq.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * Low level JADE IRQ stuff (derived from original hscx_irq.c) * Index: drivers/isdn/hisax/l3_1tr6.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/l3_1tr6.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/l3_1tr6.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/l3_1tr6.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: l3_1tr6.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: l3_1tr6.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * German 1TR6 D-channel protocol * @@ -20,7 +20,7 @@ #include extern char *HiSax_getrev(const char *revision); -const char *l3_1tr6_revision = "$Revision: 1.1 $"; +const char *l3_1tr6_revision = "$Revision: 1.2 $"; #define MsgHead(ptr, cref, mty, dis) \ *ptr++ = dis; \ Index: drivers/isdn/hisax/l3_1tr6.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/l3_1tr6.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/l3_1tr6.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/l3_1tr6.h 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: l3_1tr6.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: l3_1tr6.h,v 1.2 2004/08/04 01:29:00 joff Exp $ * * German 1TR6 D-channel protocol defines * Index: drivers/isdn/hisax/l3dss1.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/l3dss1.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/l3dss1.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/l3dss1.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: l3dss1.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: l3dss1.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * EURO/DSS1 D-channel protocol * @@ -27,7 +27,7 @@ #include extern char *HiSax_getrev(const char *revision); -const char *dss1_revision = "$Revision: 1.1 $"; +const char *dss1_revision = "$Revision: 1.2 $"; #define EXT_BEARER_CAPS 1 Index: drivers/isdn/hisax/l3dss1.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/l3dss1.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/l3dss1.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/l3dss1.h 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: l3dss1.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: l3dss1.h,v 1.2 2004/08/04 01:29:00 joff Exp $ * * DSS1 (Euro) D-channel protocol defines * Index: drivers/isdn/hisax/l3ni1.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/l3ni1.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/l3ni1.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/l3ni1.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: l3ni1.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: l3ni1.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * NI1 D-channel protocol * @@ -25,7 +25,7 @@ #include extern char *HiSax_getrev(const char *revision); -const char *ni1_revision = "$Revision: 1.1 $"; +const char *ni1_revision = "$Revision: 1.2 $"; #define EXT_BEARER_CAPS 1 Index: drivers/isdn/hisax/l3ni1.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/l3ni1.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/l3ni1.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/l3ni1.h 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: l3ni1.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: l3ni1.h,v 1.2 2004/08/04 01:29:00 joff Exp $ * * NI1 D-channel protocol * Index: drivers/isdn/hisax/lmgr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/lmgr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/lmgr.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/lmgr.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: lmgr.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: lmgr.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * Layermanagement module * Index: drivers/isdn/hisax/mic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/mic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/mic.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/hisax/mic.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: mic.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: mic.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * low level stuff for mic cards * @@ -19,7 +19,7 @@ extern const char *CardType[]; -const char *mic_revision = "$Revision: 1.1 $"; +const char *mic_revision = "$Revision: 1.2 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) Index: drivers/isdn/hisax/netjet.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/netjet.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/netjet.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/netjet.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: netjet.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: netjet.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * low level stuff for Traverse Technologie NETJet ISDN cards * @@ -26,7 +26,7 @@ #include #include "netjet.h" -const char *NETjet_revision = "$Revision: 1.1 $"; +const char *NETjet_revision = "$Revision: 1.2 $"; /* Interface functions */ Index: drivers/isdn/hisax/netjet.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/netjet.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/netjet.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/netjet.h 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: netjet.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: netjet.h,v 1.2 2004/08/04 01:29:00 joff Exp $ * * NETjet common header file * Index: drivers/isdn/hisax/niccy.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/niccy.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/niccy.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/niccy.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: niccy.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: niccy.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * low level stuff for Dr. Neuhaus NICCY PnP and NICCY PCI and * compatible (SAGEM cybermodem) @@ -25,7 +25,7 @@ #include extern const char *CardType[]; -const char *niccy_revision = "$Revision: 1.1 $"; +const char *niccy_revision = "$Revision: 1.2 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) Index: drivers/isdn/hisax/nj_s.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/nj_s.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/nj_s.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/nj_s.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: nj_s.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: nj_s.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. @@ -16,7 +16,7 @@ #include #include "netjet.h" -const char *NETjet_S_revision = "$Revision: 1.1 $"; +const char *NETjet_S_revision = "$Revision: 1.2 $"; static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off) { Index: drivers/isdn/hisax/nj_u.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/nj_u.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/nj_u.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/nj_u.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: nj_u.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: nj_u.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. @@ -16,7 +16,7 @@ #include #include "netjet.h" -const char *NETjet_U_revision = "$Revision: 1.1 $"; +const char *NETjet_U_revision = "$Revision: 1.2 $"; static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off) { Index: drivers/isdn/hisax/q931.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/q931.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/q931.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/q931.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: q931.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: q931.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * code to decode ITU Q.931 call control messages * Index: drivers/isdn/hisax/s0box.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/s0box.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/s0box.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/s0box.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: s0box.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: s0box.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * low level stuff for Creatix S0BOX * @@ -18,7 +18,7 @@ #include "isdnl1.h" extern const char *CardType[]; -const char *s0box_revision = "$Revision: 1.1 $"; +const char *s0box_revision = "$Revision: 1.2 $"; static inline void writereg(unsigned int padr, signed int addr, u_char off, u_char val) { Index: drivers/isdn/hisax/saphir.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/saphir.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/saphir.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/hisax/saphir.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: saphir.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: saphir.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * low level stuff for HST Saphir 1 * @@ -20,7 +20,7 @@ #include "isdnl1.h" extern const char *CardType[]; -static char *saphir_rev = "$Revision: 1.1 $"; +static char *saphir_rev = "$Revision: 1.2 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) Index: drivers/isdn/hisax/sedlbauer.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/sedlbauer.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/sedlbauer.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/sedlbauer.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sedlbauer.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: sedlbauer.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * low level stuff for Sedlbauer cards * includes support for the Sedlbauer speed star (speed star II), @@ -52,7 +52,7 @@ extern const char *CardType[]; -const char *Sedlbauer_revision = "$Revision: 1.1 $"; +const char *Sedlbauer_revision = "$Revision: 1.2 $"; const char *Sedlbauer_Types[] = {"None", "speed card/win", "speed star", "speed fax+", Index: drivers/isdn/hisax/sportster.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/sportster.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/sportster.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/sportster.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sportster.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: sportster.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * low level stuff for USR Sportster internal TA * @@ -20,7 +20,7 @@ #include "isdnl1.h" extern const char *CardType[]; -const char *sportster_revision = "$Revision: 1.1 $"; +const char *sportster_revision = "$Revision: 1.2 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) Index: drivers/isdn/hisax/st5481_d.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/st5481_d.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/st5481_d.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/hisax/st5481_d.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -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}, }; Index: drivers/isdn/hisax/tei.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/tei.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/tei.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/hisax/tei.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: tei.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: tei.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * Author Karsten Keil * based on the teles driver from Jan den Ouden @@ -21,7 +21,7 @@ #include #include -const char *tei_revision = "$Revision: 1.1 $"; +const char *tei_revision = "$Revision: 1.2 $"; #define ID_REQUEST 1 #define ID_ASSIGNED 2 Index: drivers/isdn/hisax/teleint.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/teleint.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/teleint.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/teleint.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: teleint.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: teleint.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * low level stuff for TeleInt isdn cards * @@ -19,7 +19,7 @@ extern const char *CardType[]; -const char *TeleInt_revision = "$Revision: 1.1 $"; +const char *TeleInt_revision = "$Revision: 1.2 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) Index: drivers/isdn/hisax/teles0.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/teles0.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/teles0.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/teles0.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: teles0.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: teles0.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * low level stuff for Teles Memory IO isdn cards * @@ -24,7 +24,7 @@ extern const char *CardType[]; -const char *teles0_revision = "$Revision: 1.1 $"; +const char *teles0_revision = "$Revision: 1.2 $"; #define TELES_IOMEM_SIZE 0x400 #define byteout(addr,val) outb(val,addr) Index: drivers/isdn/hisax/teles3.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/teles3.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/teles3.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/teles3.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: teles3.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: teles3.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * low level stuff for Teles 16.3 & PNP isdn cards * @@ -22,7 +22,7 @@ #include "isdnl1.h" extern const char *CardType[]; -const char *teles3_revision = "$Revision: 1.1 $"; +const char *teles3_revision = "$Revision: 1.2 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) Index: drivers/isdn/hisax/telespci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/telespci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/telespci.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hisax/telespci.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: telespci.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: telespci.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * low level stuff for Teles PCI isdn cards * @@ -22,7 +22,7 @@ #include extern const char *CardType[]; -const char *telespci_revision = "$Revision: 1.1 $"; +const char *telespci_revision = "$Revision: 1.2 $"; #define ZORAN_PO_RQ_PEN 0x02000000 #define ZORAN_PO_WR 0x00800000 Index: drivers/isdn/hisax/w6692.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/w6692.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/w6692.c 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/hisax/w6692.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: w6692.c,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: w6692.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * Winbond W6692 specific routines * @@ -42,7 +42,7 @@ extern const char *CardType[]; -const char *w6692_revision = "$Revision: 1.1 $"; +const char *w6692_revision = "$Revision: 1.2 $"; #define DBUSY_TIMER_VALUE 80 Index: drivers/isdn/hisax/w6692.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hisax/w6692.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hisax/w6692.h 22 Jul 2004 19:49:56 -0000 1.1 +++ drivers/isdn/hisax/w6692.h 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: w6692.h,v 1.1 2004/07/22 19:49:56 joff Exp $ +/* $Id: w6692.h,v 1.2 2004/08/04 01:29:00 joff Exp $ * * Winbond W6692 specific defines * Index: drivers/isdn/hysdn/boardergo.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hysdn/boardergo.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hysdn/boardergo.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hysdn/boardergo.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: boardergo.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: boardergo.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * Linux driver for HYSDN cards, specific routines for ergo type boards. * Index: drivers/isdn/hysdn/boardergo.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hysdn/boardergo.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hysdn/boardergo.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hysdn/boardergo.h 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: boardergo.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: boardergo.h,v 1.2 2004/08/04 01:29:00 joff Exp $ * * Linux driver for HYSDN cards, definitions for ergo type boards (buffers..). * Index: drivers/isdn/hysdn/hycapi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hysdn/hycapi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hysdn/hycapi.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hysdn/hycapi.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hycapi.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: hycapi.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * Linux driver for HYSDN cards, CAPI2.0-Interface. * @@ -29,7 +29,7 @@ #include "hysdn_defs.h" #include -static char hycapi_revision[]="$Revision: 1.1 $"; +static char hycapi_revision[]="$Revision: 1.2 $"; unsigned int hycapi_enable = 0xffffffff; MODULE_PARM(hycapi_enable, "i"); Index: drivers/isdn/hysdn/hysdn_boot.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hysdn/hysdn_boot.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hysdn/hysdn_boot.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hysdn/hysdn_boot.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hysdn_boot.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: hysdn_boot.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * Linux driver for HYSDN cards * specific routines for booting and pof handling Index: drivers/isdn/hysdn/hysdn_defs.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hysdn/hysdn_defs.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hysdn/hysdn_defs.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hysdn/hysdn_defs.h 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hysdn_defs.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: hysdn_defs.h,v 1.2 2004/08/04 01:29:00 joff Exp $ * * Linux driver for HYSDN cards * global definitions and exported vars and functions. Index: drivers/isdn/hysdn/hysdn_init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hysdn/hysdn_init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hysdn/hysdn_init.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hysdn/hysdn_init.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hysdn_init.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: hysdn_init.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * Linux driver for HYSDN cards, init functions. * @@ -33,7 +33,7 @@ MODULE_AUTHOR("Werner Cornelius"); MODULE_LICENSE("GPL"); -static char *hysdn_init_revision = "$Revision: 1.1 $"; +static char *hysdn_init_revision = "$Revision: 1.2 $"; int cardmax; /* number of found cards */ hysdn_card *card_root = NULL; /* pointer to first card */ Index: drivers/isdn/hysdn/hysdn_net.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hysdn/hysdn_net.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hysdn/hysdn_net.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hysdn/hysdn_net.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hysdn_net.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: hysdn_net.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * Linux driver for HYSDN cards, net (ethernet type) handling routines. * @@ -29,7 +29,7 @@ MODULE_PARM(hynet_enable, "i"); /* store the actual version for log reporting */ -char *hysdn_net_revision = "$Revision: 1.1 $"; +char *hysdn_net_revision = "$Revision: 1.2 $"; #define MAX_SKB_BUFFERS 20 /* number of buffers for keeping TX-data */ Index: drivers/isdn/hysdn/hysdn_pof.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hysdn/hysdn_pof.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hysdn/hysdn_pof.h 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hysdn/hysdn_pof.h 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hysdn_pof.h,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: hysdn_pof.h,v 1.2 2004/08/04 01:29:00 joff Exp $ * * Linux driver for HYSDN cards, definitions used for handling pof-files. * Index: drivers/isdn/hysdn/hysdn_procconf.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hysdn/hysdn_procconf.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hysdn/hysdn_procconf.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hysdn/hysdn_procconf.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hysdn_procconf.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: hysdn_procconf.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * Linux driver for HYSDN cards, /proc/net filesystem dir and conf functions. * @@ -21,7 +21,7 @@ #include "hysdn_defs.h" -static char *hysdn_procconf_revision = "$Revision: 1.1 $"; +static char *hysdn_procconf_revision = "$Revision: 1.2 $"; #define INFO_OUT_LEN 80 /* length of info line including lf */ Index: drivers/isdn/hysdn/hysdn_proclog.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hysdn/hysdn_proclog.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hysdn/hysdn_proclog.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hysdn/hysdn_proclog.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hysdn_proclog.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: hysdn_proclog.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * Linux driver for HYSDN cards, /proc/net filesystem log functions. * Index: drivers/isdn/hysdn/hysdn_sched.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/hysdn/hysdn_sched.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/hysdn/hysdn_sched.c 22 Jul 2004 19:49:57 -0000 1.1 +++ drivers/isdn/hysdn/hysdn_sched.c 4 Aug 2004 01:29:00 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: hysdn_sched.c,v 1.1 2004/07/22 19:49:57 joff Exp $ +/* $Id: hysdn_sched.c,v 1.2 2004/08/04 01:29:00 joff Exp $ * * Linux driver for HYSDN cards * scheduler routines for handling exchange card <-> pc. Index: drivers/isdn/icn/icn.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/icn/icn.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/icn/icn.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/icn/icn.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: icn.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: icn.c,v 1.2 2004/08/04 01:29:01 joff Exp $ * * ISDN low-level module for the ICN active ISDN-Card. * @@ -41,7 +41,7 @@ #undef MAP_DEBUG static char -*revision = "$Revision: 1.1 $"; +*revision = "$Revision: 1.2 $"; static int icn_addcard(int, char *, char *); Index: drivers/isdn/icn/icn.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/icn/icn.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/icn/icn.h 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/icn/icn.h 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: icn.h,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: icn.h,v 1.2 2004/08/04 01:29:01 joff Exp $ * * ISDN lowlevel-module for the ICN active ISDN-Card. * Index: drivers/isdn/isdnloop/isdnloop.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdnloop/isdnloop.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdnloop/isdnloop.c 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/isdn/isdnloop/isdnloop.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdnloop.c,v 1.1 2004/07/22 19:49:58 joff Exp $ +/* $Id: isdnloop.c,v 1.2 2004/08/04 01:29:01 joff Exp $ * * ISDN low-level module implementing a dummy loop driver. * @@ -14,7 +14,7 @@ #include #include "isdnloop.h" -static char *revision = "$Revision: 1.1 $"; +static char *revision = "$Revision: 1.2 $"; static char *isdnloop_id; MODULE_DESCRIPTION("ISDN4Linux: Pseudo Driver that simulates an ISDN card"); Index: drivers/isdn/isdnloop/isdnloop.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/isdnloop/isdnloop.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/isdnloop/isdnloop.h 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/isdn/isdnloop/isdnloop.h 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: isdnloop.h,v 1.1 2004/07/22 19:49:58 joff Exp $ +/* $Id: isdnloop.h,v 1.2 2004/08/04 01:29:01 joff Exp $ * * Loopback lowlevel module for testing of linklevel. * Index: drivers/isdn/sc/card.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/sc/card.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/sc/card.h 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/sc/card.h 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: card.h,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: card.h,v 1.2 2004/08/04 01:29:01 joff Exp $ * * Driver parameters for SpellCaster ISA ISDN adapters * Index: drivers/isdn/sc/command.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/sc/command.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/sc/command.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/sc/command.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: command.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: command.c,v 1.2 2004/08/04 01:29:01 joff Exp $ * * Copyright (C) 1996 SpellCaster Telecommunications Inc. * Index: drivers/isdn/sc/debug.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/sc/debug.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/sc/debug.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/sc/debug.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: debug.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: debug.c,v 1.2 2004/08/04 01:29:01 joff Exp $ * * Copyright (C) 1996 SpellCaster Telecommunications Inc. * Index: drivers/isdn/sc/debug.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/sc/debug.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/sc/debug.h 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/sc/debug.h 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: debug.h,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: debug.h,v 1.2 2004/08/04 01:29:01 joff Exp $ * * Copyright (C) 1996 SpellCaster Telecommunications Inc. * Index: drivers/isdn/sc/event.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/sc/event.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/sc/event.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/sc/event.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: event.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: event.c,v 1.2 2004/08/04 01:29:01 joff Exp $ * * Copyright (C) 1996 SpellCaster Telecommunications Inc. * Index: drivers/isdn/sc/interrupt.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/sc/interrupt.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/sc/interrupt.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/sc/interrupt.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: interrupt.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: interrupt.c,v 1.2 2004/08/04 01:29:01 joff Exp $ * * Copyright (C) 1996 SpellCaster Telecommunications Inc. * Index: drivers/isdn/sc/message.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/sc/message.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/sc/message.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/sc/message.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: message.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: message.c,v 1.2 2004/08/04 01:29:01 joff Exp $ * * functions for sending and receiving control messages * Index: drivers/isdn/sc/message.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/sc/message.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/sc/message.h 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/sc/message.h 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: message.h,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: message.h,v 1.2 2004/08/04 01:29:01 joff Exp $ * * Copyright (C) 1996 SpellCaster Telecommunications Inc. * Index: drivers/isdn/sc/packet.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/sc/packet.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/sc/packet.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/sc/packet.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: packet.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: packet.c,v 1.2 2004/08/04 01:29:01 joff Exp $ * * Copyright (C) 1996 SpellCaster Telecommunications Inc. * Index: drivers/isdn/sc/shmem.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/sc/shmem.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/sc/shmem.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/sc/shmem.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: shmem.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: shmem.c,v 1.2 2004/08/04 01:29:01 joff Exp $ * * Copyright (C) 1996 SpellCaster Telecommunications Inc. * Index: drivers/isdn/sc/timer.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/sc/timer.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/sc/timer.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/sc/timer.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: timer.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: timer.c,v 1.2 2004/08/04 01:29:01 joff Exp $ * * Copyright (C) 1996 SpellCaster Telecommunications Inc. * Index: drivers/isdn/tpam/tpam.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/tpam/tpam.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/tpam/tpam.h 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/tpam/tpam.h 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: tpam.h,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: tpam.h,v 1.2 2004/08/04 01:29:01 joff Exp $ * * Turbo PAM ISDN driver for Linux. (Kernel Driver) * Index: drivers/isdn/tpam/tpam_commands.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/tpam/tpam_commands.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/tpam/tpam_commands.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/tpam/tpam_commands.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: tpam_commands.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: tpam_commands.c,v 1.2 2004/08/04 01:29:01 joff Exp $ * * Turbo PAM ISDN driver for Linux. (Kernel Driver - ISDN commands) * Index: drivers/isdn/tpam/tpam_crcpc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/tpam/tpam_crcpc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/tpam/tpam_crcpc.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/tpam/tpam_crcpc.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: tpam_crcpc.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: tpam_crcpc.c,v 1.2 2004/08/04 01:29:01 joff Exp $ * * Turbo PAM ISDN driver for Linux. (Kernel Driver - CRC encoding) * Index: drivers/isdn/tpam/tpam_hdlc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/tpam/tpam_hdlc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/tpam/tpam_hdlc.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/tpam/tpam_hdlc.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: tpam_hdlc.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: tpam_hdlc.c,v 1.2 2004/08/04 01:29:01 joff Exp $ * * Turbo PAM ISDN driver for Linux. (Kernel Driver - HDLC encoding) * Index: drivers/isdn/tpam/tpam_main.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/tpam/tpam_main.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/tpam/tpam_main.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/tpam/tpam_main.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: tpam_main.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: tpam_main.c,v 1.2 2004/08/04 01:29:01 joff Exp $ * * Turbo PAM ISDN driver for Linux. (Kernel Driver - main routines) * Index: drivers/isdn/tpam/tpam_memory.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/tpam/tpam_memory.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/tpam/tpam_memory.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/tpam/tpam_memory.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: tpam_memory.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: tpam_memory.c,v 1.2 2004/08/04 01:29:01 joff Exp $ * * Turbo PAM ISDN driver for Linux. (Kernel Driver - Board Memory Access) * Index: drivers/isdn/tpam/tpam_nco.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/tpam/tpam_nco.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/tpam/tpam_nco.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/tpam/tpam_nco.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: tpam_nco.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: tpam_nco.c,v 1.2 2004/08/04 01:29:01 joff Exp $ * * Turbo PAM ISDN driver for Linux. * (Kernel Driver - Low Level NCO Manipulation) Index: drivers/isdn/tpam/tpam_queues.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/isdn/tpam/tpam_queues.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/isdn/tpam/tpam_queues.c 22 Jul 2004 19:49:55 -0000 1.1 +++ drivers/isdn/tpam/tpam_queues.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: tpam_queues.c,v 1.1 2004/07/22 19:49:55 joff Exp $ +/* $Id: tpam_queues.c,v 1.2 2004/08/04 01:29:01 joff Exp $ * * Turbo PAM ISDN driver for Linux. (Kernel Driver) * @@ -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"); Index: drivers/macintosh/adb-iop.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/macintosh/adb-iop.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/macintosh/adb-iop.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/macintosh/adb-iop.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -106,6 +106,9 @@ struct adb_iopmsg *amsg = (struct adb_iopmsg *) msg->message; struct adb_request *req; uint flags; +#ifdef DEBUG_ADB_IOP + int i; +#endif save_flags(flags); cli(); @@ -113,12 +116,10 @@ req = current_req; #ifdef DEBUG_ADB_IOP - printk("adb_iop_listen: rcvd packet, %d bytes: %02X %02X", + printk("adb_iop_listen %p: rcvd packet, %d bytes: %02X %02X", req, (uint) amsg->count + 2, (uint) amsg->flags, (uint) amsg->cmd); - i = 0; - while (i < amsg->count) { - printk(" %02X", (uint) amsg->data[i++]); - } + for (i = 0; i < amsg->count; i++) + printk(" %02X", (uint) amsg->data[i]); printk("\n"); #endif @@ -136,7 +137,7 @@ adb_iop_end_req(req, idle); } } else { - /* TODO: is it possible for more tha one chunk of data */ + /* TODO: is it possible for more than one chunk of data */ /* to arrive before the timeout? If so we need to */ /* use reply_ptr here like the other drivers do. */ if ((adb_iop_state == awaiting_reply) && @@ -165,6 +166,9 @@ unsigned long flags; struct adb_request *req; struct adb_iopmsg amsg; +#ifdef DEBUG_ADB_IOP + int i; +#endif /* get the packet to send */ req = current_req; @@ -174,7 +178,7 @@ cli(); #ifdef DEBUG_ADB_IOP - printk("adb_iop_start: sending packet, %d bytes:", req->nbytes); + printk("adb_iop_start %p: sending packet, %d bytes:", req, req->nbytes); for (i = 0 ; i < req->nbytes ; i++) printk(" %02X", (uint) req->data[i]); printk("\n"); @@ -271,13 +275,17 @@ int adb_iop_reset_bus(void) { - struct adb_request req; + struct adb_request req = { + .reply_expected = 0, + .nbytes = 2, + .data = { ADB_PACKET, 0 }, + }; - req.reply_expected = 0; - req.nbytes = 2; - req.data[0] = ADB_PACKET; - req.data[1] = 0; /* RESET */ adb_iop_write(&req); - while (!req.complete) adb_iop_poll(); + while (!req.complete) { + adb_iop_poll(); + schedule(); + } + return 0; } Index: drivers/macintosh/adb.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/macintosh/adb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/macintosh/adb.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/macintosh/adb.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -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); Index: drivers/macintosh/adbhid.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/macintosh/adbhid.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/macintosh/adbhid.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/macintosh/adbhid.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -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); Index: drivers/macintosh/apm_emu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/macintosh/apm_emu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/macintosh/apm_emu.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/macintosh/apm_emu.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -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); Index: drivers/macintosh/macio-adb.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/macintosh/macio-adb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/macintosh/macio-adb.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/macintosh/macio-adb.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -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); } Index: drivers/macintosh/macserial.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/macintosh/macserial.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/macintosh/macserial.c 22 Jul 2004 19:50:27 -0000 1.1 +++ drivers/macintosh/macserial.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -8,7 +8,7 @@ * * Receive DMA code by Takashi Oe . * - * $Id: macserial.c,v 1.1 2004/07/22 19:50:27 joff Exp $ + * $Id: macserial.c,v 1.2 2004/08/04 01:29:01 joff Exp $ */ #include Index: drivers/macintosh/mediabay.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/macintosh/mediabay.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/macintosh/mediabay.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/macintosh/mediabay.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -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"); } } Index: drivers/macintosh/rtc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/macintosh/rtc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/macintosh/rtc.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/macintosh/rtc.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -64,6 +64,7 @@ case RTC_RD_TIME: if (ppc_md.get_rtc_time) { + memset(&rtc_tm, 0, sizeof(struct rtc_time)); get_rtc_time(&rtc_tm); if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time))) Index: drivers/macintosh/via-cuda.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/macintosh/via-cuda.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/macintosh/via-cuda.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/macintosh/via-cuda.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -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); } Index: drivers/macintosh/via-macii.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/macintosh/via-macii.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/macintosh/via-macii.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/macintosh/via-macii.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -21,13 +21,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include static volatile unsigned char *via; Index: drivers/macintosh/via-pmu.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/macintosh/via-pmu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/macintosh/via-pmu.c 22 Jul 2004 19:50:27 -0000 1.1 +++ drivers/macintosh/via-pmu.c 4 Aug 2004 01:29:01 -0000 1.2 @@ -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); Index: drivers/md/lvm-fs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/md/lvm-fs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/md/lvm-fs.c 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/md/lvm-fs.c 4 Aug 2004 01:29:02 -0000 1.2 @@ -59,9 +59,9 @@ static int _proc_read_global(char *page, char **start, off_t off, int count, int *eof, void *data); -static int _vg_info(vg_t *vg_ptr, char *buf); -static int _lv_info(vg_t *vg_ptr, lv_t *lv_ptr, char *buf); -static int _pv_info(pv_t *pv_ptr, char *buf); +static int _vg_info(vg_t * vg_ptr, char *buf); +static int _lv_info(vg_t * vg_ptr, lv_t * lv_ptr, char *buf); +static int _pv_info(pv_t * pv_ptr, char *buf); static void _show_uuid(const char *src, char *b, char *e); @@ -78,65 +78,72 @@ /* inline functions */ /* public interface */ -void __init lvm_init_fs() { +void __init lvm_init_fs() +{ struct proc_dir_entry *pde; /* User-space has already registered this */ #if 0 - lvm_devfs_handle = devfs_register( - 0 , "lvm", 0, LVM_CHAR_MAJOR, 0, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, - &lvm_chr_fops, NULL); + lvm_devfs_handle = devfs_register(0, "lvm", 0, LVM_CHAR_MAJOR, 0, + S_IFCHR | S_IRUSR | S_IWUSR | + S_IRGRP, &lvm_chr_fops, NULL); #endif lvm_proc_dir = create_proc_entry(LVM_DIR, S_IFDIR, &proc_root); if (lvm_proc_dir) { - lvm_proc_vg_subdir = create_proc_entry(LVM_VG_SUBDIR, S_IFDIR, - lvm_proc_dir); + lvm_proc_vg_subdir = + create_proc_entry(LVM_VG_SUBDIR, S_IFDIR, + lvm_proc_dir); pde = create_proc_entry(LVM_GLOBAL, S_IFREG, lvm_proc_dir); - if ( pde != NULL) pde->read_proc = _proc_read_global; + if (pde != NULL) + pde->read_proc = _proc_read_global; } } -void lvm_fin_fs() { +void lvm_fin_fs() +{ #if 0 - devfs_unregister (lvm_devfs_handle); + devfs_unregister(lvm_devfs_handle); #endif remove_proc_entry(LVM_GLOBAL, lvm_proc_dir); remove_proc_entry(LVM_VG_SUBDIR, lvm_proc_dir); remove_proc_entry(LVM_DIR, &proc_root); } -void lvm_fs_create_vg(vg_t *vg_ptr) { +void lvm_fs_create_vg(vg_t * vg_ptr) +{ struct proc_dir_entry *pde; if (!vg_ptr) return; vg_devfs_handle[vg_ptr->vg_number] = - devfs_mk_dir(0, vg_ptr->vg_name, NULL); + devfs_mk_dir(0, vg_ptr->vg_name, NULL); - ch_devfs_handle[vg_ptr->vg_number] = devfs_register( - vg_devfs_handle[vg_ptr->vg_number] , "group", - DEVFS_FL_DEFAULT, LVM_CHAR_MAJOR, vg_ptr->vg_number, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, - &lvm_chr_fops, NULL); + ch_devfs_handle[vg_ptr->vg_number] = + devfs_register(vg_devfs_handle[vg_ptr->vg_number], "group", + DEVFS_FL_DEFAULT, LVM_CHAR_MAJOR, + vg_ptr->vg_number, + S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, + &lvm_chr_fops, NULL); vg_ptr->vg_dir_pde = create_proc_entry(vg_ptr->vg_name, S_IFDIR, lvm_proc_vg_subdir); - if((pde = create_proc_entry("group", S_IFREG, vg_ptr->vg_dir_pde))) { + if ((pde = + create_proc_entry("group", S_IFREG, vg_ptr->vg_dir_pde))) { pde->read_proc = _proc_read_vg; pde->data = vg_ptr; } vg_ptr->lv_subdir_pde = - create_proc_entry(LVM_LV_SUBDIR, S_IFDIR, vg_ptr->vg_dir_pde); + create_proc_entry(LVM_LV_SUBDIR, S_IFDIR, vg_ptr->vg_dir_pde); vg_ptr->pv_subdir_pde = - create_proc_entry(LVM_PV_SUBDIR, S_IFDIR, vg_ptr->vg_dir_pde); + create_proc_entry(LVM_PV_SUBDIR, S_IFDIR, vg_ptr->vg_dir_pde); } -void lvm_fs_remove_vg(vg_t *vg_ptr) { +void lvm_fs_remove_vg(vg_t * vg_ptr) +{ int i; if (!vg_ptr) @@ -146,18 +153,20 @@ ch_devfs_handle[vg_ptr->vg_number] = NULL; /* remove lv's */ - for(i = 0; i < vg_ptr->lv_max; i++) - if(vg_ptr->lv[i]) lvm_fs_remove_lv(vg_ptr, vg_ptr->lv[i]); + for (i = 0; i < vg_ptr->lv_max; i++) + if (vg_ptr->lv[i]) + lvm_fs_remove_lv(vg_ptr, vg_ptr->lv[i]); /* must not remove directory before leaf nodes */ devfs_unregister(vg_devfs_handle[vg_ptr->vg_number]); vg_devfs_handle[vg_ptr->vg_number] = NULL; /* remove pv's */ - for(i = 0; i < vg_ptr->pv_max; i++) - if(vg_ptr->pv[i]) lvm_fs_remove_pv(vg_ptr, vg_ptr->pv[i]); + for (i = 0; i < vg_ptr->pv_max; i++) + if (vg_ptr->pv[i]) + lvm_fs_remove_pv(vg_ptr, vg_ptr->pv[i]); - if(vg_ptr->vg_dir_pde) { + if (vg_ptr->vg_dir_pde) { remove_proc_entry(LVM_LV_SUBDIR, vg_ptr->vg_dir_pde); vg_ptr->lv_subdir_pde = NULL; @@ -172,13 +181,15 @@ } -static inline const char *_basename(const char *str) { +static inline const char *_basename(const char *str) +{ const char *name = strrchr(str, '/'); name = name ? name + 1 : str; return name; } -devfs_handle_t lvm_fs_create_lv(vg_t *vg_ptr, lv_t *lv) { +devfs_handle_t lvm_fs_create_lv(vg_t * vg_ptr, lv_t * lv) +{ struct proc_dir_entry *pde; const char *name; @@ -187,21 +198,24 @@ name = _basename(lv->lv_name); - lv_devfs_handle[MINOR(lv->lv_dev)] = devfs_register( - vg_devfs_handle[vg_ptr->vg_number], name, - DEVFS_FL_DEFAULT, LVM_BLK_MAJOR, MINOR(lv->lv_dev), - S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP, - &lvm_blk_dops, NULL); - - if(vg_ptr->lv_subdir_pde && - (pde = create_proc_entry(name, S_IFREG, vg_ptr->lv_subdir_pde))) { + lv_devfs_handle[MINOR(lv->lv_dev)] = + devfs_register(vg_devfs_handle[vg_ptr->vg_number], name, + DEVFS_FL_DEFAULT, LVM_BLK_MAJOR, + MINOR(lv->lv_dev), + S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP, + &lvm_blk_dops, NULL); + + if (vg_ptr->lv_subdir_pde && + (pde = + create_proc_entry(name, S_IFREG, vg_ptr->lv_subdir_pde))) { pde->read_proc = _proc_read_lv; pde->data = lv; } return lv_devfs_handle[MINOR(lv->lv_dev)]; } -void lvm_fs_remove_lv(vg_t *vg_ptr, lv_t *lv) { +void lvm_fs_remove_lv(vg_t * vg_ptr, lv_t * lv) +{ if (!vg_ptr || !lv) return; @@ -209,51 +223,55 @@ devfs_unregister(lv_devfs_handle[MINOR(lv->lv_dev)]); lv_devfs_handle[MINOR(lv->lv_dev)] = NULL; - if(vg_ptr->lv_subdir_pde) { + if (vg_ptr->lv_subdir_pde) { const char *name = _basename(lv->lv_name); remove_proc_entry(name, vg_ptr->lv_subdir_pde); } } -static inline void _make_pv_name(const char *src, char *b, char *e) { +static inline void _make_pv_name(const char *src, char *b, char *e) +{ int offset = strlen(LVM_DIR_PREFIX); - if(strncmp(src, LVM_DIR_PREFIX, offset)) + if (strncmp(src, LVM_DIR_PREFIX, offset)) offset = 0; e--; src += offset; - while(*src && (b != e)) { + while (*src && (b != e)) { *b++ = (*src == '/') ? '_' : *src; src++; } *b = '\0'; } -void lvm_fs_create_pv(vg_t *vg_ptr, pv_t *pv) { +void lvm_fs_create_pv(vg_t * vg_ptr, pv_t * pv) +{ struct proc_dir_entry *pde; char name[NAME_LEN]; if (!vg_ptr || !pv) return; - if(!vg_ptr->pv_subdir_pde) + if (!vg_ptr->pv_subdir_pde) return; _make_pv_name(pv->pv_name, name, name + sizeof(name)); - if((pde = create_proc_entry(name, S_IFREG, vg_ptr->pv_subdir_pde))) { + if ((pde = + create_proc_entry(name, S_IFREG, vg_ptr->pv_subdir_pde))) { pde->read_proc = _proc_read_pv; pde->data = pv; } } -void lvm_fs_remove_pv(vg_t *vg_ptr, pv_t *pv) { +void lvm_fs_remove_pv(vg_t * vg_ptr, pv_t * pv) +{ char name[NAME_LEN]; if (!vg_ptr || !pv) return; - if(!vg_ptr->pv_subdir_pde) + if (!vg_ptr->pv_subdir_pde) return; _make_pv_name(pv->pv_name, name, name + sizeof(name)); @@ -262,7 +280,8 @@ static int _proc_read_vg(char *page, char **start, off_t off, - int count, int *eof, void *data) { + int count, int *eof, void *data) +{ int sz = 0; vg_t *vg_ptr = data; char uuid[NAME_LEN]; @@ -279,9 +298,11 @@ sz += sprintf(page + sz, "PV max: %u\n", vg_ptr->pv_max); sz += sprintf(page + sz, "PV current: %u\n", vg_ptr->pv_cur); sz += sprintf(page + sz, "PV active: %u\n", vg_ptr->pv_act); - sz += sprintf(page + sz, "PE size: %u\n", vg_ptr->pe_size / 2); + sz += + sprintf(page + sz, "PE size: %u\n", vg_ptr->pe_size / 2); sz += sprintf(page + sz, "PE total: %u\n", vg_ptr->pe_total); - sz += sprintf(page + sz, "PE allocated: %u\n", vg_ptr->pe_allocated); + sz += + sprintf(page + sz, "PE allocated: %u\n", vg_ptr->pe_allocated); _show_uuid(vg_ptr->vg_uuid, uuid, uuid + sizeof(uuid)); sz += sprintf(page + sz, "uuid: %s\n", uuid); @@ -290,7 +311,8 @@ } static int _proc_read_lv(char *page, char **start, off_t off, - int count, int *eof, void *data) { + int count, int *eof, void *data) +{ int sz = 0; lv_t *lv = data; @@ -301,7 +323,7 @@ sz += sprintf(page + sz, "number: %u\n", lv->lv_number); sz += sprintf(page + sz, "open: %u\n", lv->lv_open); sz += sprintf(page + sz, "allocation: %u\n", lv->lv_allocation); - if(lv->lv_stripes > 1) { + if (lv->lv_stripes > 1) { sz += sprintf(page + sz, "stripes: %u\n", lv->lv_stripes); sz += sprintf(page + sz, "stripesize: %u\n", @@ -314,7 +336,8 @@ } static int _proc_read_pv(char *page, char **start, off_t off, - int count, int *eof, void *data) { + int count, int *eof, void *data) +{ int sz = 0; pv_t *pv = data; char uuid[NAME_LEN]; @@ -329,7 +352,7 @@ sz += sprintf(page + sz, "PE total: %u\n", pv->pe_total); sz += sprintf(page + sz, "PE allocated: %u\n", pv->pe_allocated); sz += sprintf(page + sz, "device: %02u:%02u\n", - MAJOR(pv->pv_dev), MINOR(pv->pv_dev)); + MAJOR(pv->pv_dev), MINOR(pv->pv_dev)); _show_uuid(pv->pv_uuid, uuid, uuid + sizeof(uuid)); sz += sprintf(page + sz, "uuid: %s\n", uuid); @@ -337,13 +360,15 @@ return sz; } -static int _proc_read_global(char *page, char **start, off_t pos, int count, - int *eof, void *data) { +static int _proc_read_global(char *page, char **start, off_t pos, + int count, int *eof, void *data) +{ #define LVM_PROC_BUF ( i == 0 ? dummy_buf : &buf[sz]) - int c, i, l, p, v, vg_counter, pv_counter, lv_counter, lv_open_counter, - lv_open_total, pe_t_bytes, hash_table_bytes, lv_block_exception_t_bytes, seconds; + int c, i, l, p, v, vg_counter, pv_counter, lv_counter, + lv_open_counter, lv_open_total, pe_t_bytes, hash_table_bytes, + lv_block_exception_t_bytes, seconds; static off_t sz; off_t sz_last; static char *buf = NULL; @@ -359,12 +384,12 @@ lvm_name, pos, count); #endif - if(pos != 0 && buf != NULL) + if (pos != 0 && buf != NULL) goto out; - sz_last = vg_counter = pv_counter = lv_counter = lv_open_counter = \ - lv_open_total = pe_t_bytes = hash_table_bytes = \ - lv_block_exception_t_bytes = 0; + sz_last = vg_counter = pv_counter = lv_counter = lv_open_counter = + lv_open_total = pe_t_bytes = hash_table_bytes = + lv_block_exception_t_bytes = 0; /* get some statistics */ for (v = 0; v < ABS_MAX_VG; v++) { @@ -374,14 +399,26 @@ lv_counter += vg_ptr->lv_cur; if (vg_ptr->lv_cur > 0) { for (l = 0; l < vg[v]->lv_max; l++) { - if ((lv_ptr = vg_ptr->lv[l]) != NULL) { - pe_t_bytes += lv_ptr->lv_allocated_le; - hash_table_bytes += lv_ptr->lv_snapshot_hash_table_size; - if (lv_ptr->lv_block_exception != NULL) - lv_block_exception_t_bytes += lv_ptr->lv_remap_end; + if ((lv_ptr = + vg_ptr->lv[l]) != NULL) { + pe_t_bytes += + lv_ptr-> + lv_allocated_le; + hash_table_bytes += + lv_ptr-> + lv_snapshot_hash_table_size; + if (lv_ptr-> + lv_block_exception != + NULL) + lv_block_exception_t_bytes + += + lv_ptr-> + lv_remap_end; if (lv_ptr->lv_open > 0) { lv_open_counter++; - lv_open_total += lv_ptr->lv_open; + lv_open_total += + lv_ptr-> + lv_open; } } } @@ -403,8 +440,7 @@ 2nd to fill the malloced buffer */ for (i = 0; i < 2; i++) { sz = 0; - sz += sprintf(LVM_PROC_BUF, - "LVM " + sz += sprintf(LVM_PROC_BUF, "LVM " #ifdef MODULE "module" #else @@ -422,8 +458,7 @@ lv_open_counter == 1 ? "" : "s"); if (lv_open_total > 0) sz += sprintf(LVM_PROC_BUF, - " %d times)\n", - lv_open_total); + " %d times)\n", lv_open_total); else sz += sprintf(LVM_PROC_BUF, ")"); sz += sprintf(LVM_PROC_BUF, @@ -431,7 +466,8 @@ vg_counter * sizeof(vg_t) + pv_counter * sizeof(pv_t) + lv_counter * sizeof(lv_t) + - pe_t_bytes + hash_table_bytes + lv_block_exception_t_bytes + sz_last, + pe_t_bytes + hash_table_bytes + + lv_block_exception_t_bytes + sz_last, lvm_iop_version); seconds = CURRENT_TIME - loadtime; @@ -445,46 +481,70 @@ } sz += sprintf(LVM_PROC_BUF, "%d:%02d:%02d active\n", (seconds % 86400) / 3600, - (seconds % 3600) / 60, - seconds % 60); + (seconds % 3600) / 60, seconds % 60); if (vg_counter > 0) { for (v = 0; v < ABS_MAX_VG; v++) { /* volume group */ if ((vg_ptr = vg[v]) != NULL) { - sz += _vg_info(vg_ptr, LVM_PROC_BUF); + sz += + _vg_info(vg_ptr, LVM_PROC_BUF); /* physical volumes */ sz += sprintf(LVM_PROC_BUF, "\n PV%s ", - vg_ptr->pv_cur == 1 ? ": " : "s:"); + vg_ptr->pv_cur == + 1 ? ": " : "s:"); c = 0; - for (p = 0; p < vg_ptr->pv_max; p++) { - if ((pv_ptr = vg_ptr->pv[p]) != NULL) { - sz += _pv_info(pv_ptr, LVM_PROC_BUF); + for (p = 0; p < vg_ptr->pv_max; + p++) { + if ((pv_ptr = + vg_ptr->pv[p]) != + NULL) { + sz += + _pv_info + (pv_ptr, + LVM_PROC_BUF); c++; - if (c < vg_ptr->pv_cur) - sz += sprintf(LVM_PROC_BUF, - "\n "); + if (c < + vg_ptr->pv_cur) + sz += + sprintf + (LVM_PROC_BUF, + "\n "); } } /* logical volumes */ sz += sprintf(LVM_PROC_BUF, "\n LV%s ", - vg_ptr->lv_cur == 1 ? ": " : "s:"); + vg_ptr->lv_cur == + 1 ? ": " : "s:"); c = 0; - for (l = 0; l < vg_ptr->lv_max; l++) { - if ((lv_ptr = vg_ptr->lv[l]) != NULL) { - sz += _lv_info(vg_ptr, lv_ptr, LVM_PROC_BUF); + for (l = 0; l < vg_ptr->lv_max; + l++) { + if ((lv_ptr = + vg_ptr->lv[l]) != + NULL) { + sz += + _lv_info + (vg_ptr, + lv_ptr, + LVM_PROC_BUF); c++; - if (c < vg_ptr->lv_cur) - sz += sprintf(LVM_PROC_BUF, - "\n "); + if (c < + vg_ptr->lv_cur) + sz += + sprintf + (LVM_PROC_BUF, + "\n "); } } - if (vg_ptr->lv_cur == 0) sz += sprintf(LVM_PROC_BUF, "none"); + if (vg_ptr->lv_cur == 0) + sz += + sprintf(LVM_PROC_BUF, + "none"); sz += sprintf(LVM_PROC_BUF, "\n"); } } @@ -495,14 +555,15 @@ unlock_kernel(); if (buf == NULL) { sz = 0; - return sprintf(page, "%s - vmalloc error at line %d\n", + return sprintf(page, + "%s - vmalloc error at line %d\n", lvm_name, __LINE__); } } sz_last = sz; } - out: + out: if (pos > sz - 1) { lock_kernel(); vfree(buf); @@ -522,11 +583,13 @@ /* * provide VG info for proc filesystem use (global) */ -static int _vg_info(vg_t *vg_ptr, char *buf) { +static int _vg_info(vg_t * vg_ptr, char *buf) +{ int sz = 0; char inactive_flag = ' '; - if (!(vg_ptr->vg_status & VG_ACTIVE)) inactive_flag = 'I'; + if (!(vg_ptr->vg_status & VG_ACTIVE)) + inactive_flag = 'I'; sz = sprintf(buf, "\nVG: %c%s [%d PV, %d LV/%d open] " " PE Size: %d KB\n" @@ -537,13 +600,13 @@ vg_ptr->pv_cur, vg_ptr->lv_cur, vg_ptr->lv_open, - vg_ptr->pe_size >> 1, + vg_ptr->pe_size >> 1, vg_ptr->pe_size * vg_ptr->pe_total >> 1, vg_ptr->pe_total, vg_ptr->pe_allocated * vg_ptr->pe_size >> 1, - vg_ptr->pe_allocated, + vg_ptr->pe_allocated, (vg_ptr->pe_total - vg_ptr->pe_allocated) * - vg_ptr->pe_size >> 1, + vg_ptr->pe_size >> 1, vg_ptr->pe_total - vg_ptr->pe_allocated); return sz; } @@ -552,10 +615,11 @@ /* * provide LV info for proc filesystem use (global) */ -static int _lv_info(vg_t *vg_ptr, lv_t *lv_ptr, char *buf) { +static int _lv_info(vg_t * vg_ptr, lv_t * lv_ptr, char *buf) +{ int sz = 0; char inactive_flag = 'A', allocation_flag = ' ', - stripes_flag = ' ', rw_flag = ' ', *basename; + stripes_flag = ' ', rw_flag = ' ', *basename; if (!(lv_ptr->lv_status & LV_ACTIVE)) inactive_flag = 'I'; @@ -568,35 +632,33 @@ stripes_flag = 'L'; if (lv_ptr->lv_stripes > 1) stripes_flag = 'S'; - sz += sprintf(buf+sz, + sz += sprintf(buf + sz, "[%c%c%c%c", inactive_flag, - rw_flag, - allocation_flag, - stripes_flag); + rw_flag, allocation_flag, stripes_flag); if (lv_ptr->lv_stripes > 1) - sz += sprintf(buf+sz, "%-2d", - lv_ptr->lv_stripes); + sz += sprintf(buf + sz, "%-2d", lv_ptr->lv_stripes); else - sz += sprintf(buf+sz, " "); + sz += sprintf(buf + sz, " "); /* FIXME: use _basename */ basename = strrchr(lv_ptr->lv_name, '/'); - if ( basename == 0) basename = lv_ptr->lv_name; - else basename++; - sz += sprintf(buf+sz, "] %-25s", basename); + if (basename == 0) + basename = lv_ptr->lv_name; + else + basename++; + sz += sprintf(buf + sz, "] %-25s", basename); if (strlen(basename) > 25) - sz += sprintf(buf+sz, + sz += sprintf(buf + sz, "\n "); - sz += sprintf(buf+sz, "%9d /%-6d ", + sz += sprintf(buf + sz, "%9d /%-6d ", lv_ptr->lv_size >> 1, lv_ptr->lv_size / vg_ptr->pe_size); if (lv_ptr->lv_open == 0) - sz += sprintf(buf+sz, "close"); + sz += sprintf(buf + sz, "close"); else - sz += sprintf(buf+sz, "%dx open", - lv_ptr->lv_open); + sz += sprintf(buf + sz, "%dx open", lv_ptr->lv_open); return sz; } @@ -605,7 +667,8 @@ /* * provide PV info for proc filesystem use (global) */ -static int _pv_info(pv_t *pv, char *buf) { +static int _pv_info(pv_t * pv, char *buf) +{ int sz = 0; char inactive_flag = 'A', allocation_flag = ' '; char *pv_name = NULL; @@ -615,9 +678,11 @@ allocation_flag = 'A'; if (!(pv->pv_allocatable & PV_ALLOCATABLE)) allocation_flag = 'N'; - pv_name = strchr(pv->pv_name+1,'/'); - if ( pv_name == 0) pv_name = pv->pv_name; - else pv_name++; + pv_name = strchr(pv->pv_name + 1, '/'); + if (pv_name == 0) + pv_name = pv->pv_name; + else + pv_name++; sz = sprintf(buf, "[%c%c] %-21s %8d /%-6d " "%8d /%-6d %8d /%-6d", @@ -629,17 +694,17 @@ pv->pe_allocated * pv->pe_size >> 1, pv->pe_allocated, (pv->pe_total - pv->pe_allocated) * - pv->pe_size >> 1, - pv->pe_total - pv->pe_allocated); + pv->pe_size >> 1, pv->pe_total - pv->pe_allocated); return sz; } -static void _show_uuid(const char *src, char *b, char *e) { +static void _show_uuid(const char *src, char *b, char *e) +{ int i; e--; - for(i = 0; *src && (b != e); i++) { - if(i && !(i & 0x3)) + for (i = 0; *src && (b != e); i++) { + if (i && !(i & 0x3)) *b++ = '-'; *b++ = *src++; } Index: drivers/md/lvm-internal.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/md/lvm-internal.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/md/lvm-internal.h 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/md/lvm-internal.h 4 Aug 2004 01:29:02 -0000 1.2 @@ -50,7 +50,7 @@ extern struct file_operations lvm_chr_fops; #ifndef uchar -typedef unsigned char uchar; +typedef unsigned char uchar; #endif extern struct block_device_operations lvm_blk_dops; @@ -89,24 +89,24 @@ int lvm_get_blksize(kdev_t); int lvm_snapshot_alloc(lv_t *); int lvm_snapshot_fill_COW_page(vg_t *, lv_t *); -int lvm_snapshot_COW(kdev_t, ulong, ulong, ulong, vg_t *vg, lv_t *); +int lvm_snapshot_COW(kdev_t, ulong, ulong, ulong, vg_t * vg, lv_t *); int lvm_snapshot_remap_block(kdev_t *, ulong *, ulong, lv_t *); void lvm_snapshot_release(lv_t *); int lvm_write_COW_table_block(vg_t *, lv_t *); void lvm_hash_link(lv_block_exception_t *, kdev_t, ulong, lv_t *); int lvm_snapshot_alloc_hash_table(lv_t *); -void lvm_drop_snapshot(vg_t *vg, lv_t *, const char *); +void lvm_drop_snapshot(vg_t * vg, lv_t *, const char *); /* lvm_fs.c */ void lvm_init_fs(void); void lvm_fin_fs(void); -void lvm_fs_create_vg(vg_t *vg_ptr); -void lvm_fs_remove_vg(vg_t *vg_ptr); -devfs_handle_t lvm_fs_create_lv(vg_t *vg_ptr, lv_t *lv); -void lvm_fs_remove_lv(vg_t *vg_ptr, lv_t *lv); -void lvm_fs_create_pv(vg_t *vg_ptr, pv_t *pv); -void lvm_fs_remove_pv(vg_t *vg_ptr, pv_t *pv); +void lvm_fs_create_vg(vg_t * vg_ptr); +void lvm_fs_remove_vg(vg_t * vg_ptr); +devfs_handle_t lvm_fs_create_lv(vg_t * vg_ptr, lv_t * lv); +void lvm_fs_remove_lv(vg_t * vg_ptr, lv_t * lv); +void lvm_fs_create_pv(vg_t * vg_ptr, pv_t * pv); +void lvm_fs_remove_pv(vg_t * vg_ptr, pv_t * pv); #endif Index: drivers/md/lvm-snap.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/md/lvm-snap.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/md/lvm-snap.c 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/md/lvm-snap.c 4 Aug 2004 01:29:02 -0000 1.2 @@ -42,6 +42,9 @@ * 15/10/2001 - fix snapshot alignment problem [CM] * - fix snapshot full oops (always check lv_block_exception) [CM] * 26/06/2002 - support for new list_move macro [patch@luckynet.dynu.com] + * 26/07/2002 - removed conditional list_move macro because we will + * discontinue LVM1 before 2.6 anyway + * 27/08/2003 - fixed unsafe list handling in lvm_find_exception_table() [HM] * */ @@ -57,7 +60,8 @@ #include "lvm-internal.h" -static char *lvm_snap_version __attribute__ ((unused)) = "LVM "LVM_RELEASE_NAME" snapshot code ("LVM_RELEASE_DATE")\n"; +static char *lvm_snap_version __attribute__ ((unused)) = + "LVM " LVM_RELEASE_NAME " snapshot code (" LVM_RELEASE_DATE ")\n"; extern const char *const lvm_name; @@ -65,19 +69,20 @@ void lvm_snapshot_release(lv_t *); -static int _write_COW_table_block(vg_t *vg, lv_t *lv, int idx, +static int _write_COW_table_block(vg_t * vg, lv_t * lv, int idx, const char **reason); -static void _disable_snapshot(vg_t *vg, lv_t *lv); +static void _disable_snapshot(vg_t * vg, lv_t * lv); static inline int __brw_kiovec(int rw, int nr, struct kiobuf *iovec[], kdev_t dev, unsigned long b[], int size, - lv_t *lv) { + lv_t * lv) +{ return brw_kiovec(rw, nr, iovec, dev, b, size); } -static int _pv_get_number(vg_t * vg, kdev_t rdev, uint *pvn) +static int _pv_get_number(vg_t * vg, kdev_t rdev, uint * pvn) { uint p; for (p = 0; p < vg->pv_max; p++) { @@ -104,34 +109,33 @@ #define hashfn(dev,block,mask,chunk_size) \ ((HASHDEV(dev)^((block)/(chunk_size))) & (mask)) -static inline lv_block_exception_t * -lvm_find_exception_table(kdev_t org_dev, unsigned long org_start, lv_t * lv) +static inline lv_block_exception_t *lvm_find_exception_table(kdev_t + org_dev, + unsigned long + org_start, + lv_t * lv) { - struct list_head * hash_table = lv->lv_snapshot_hash_table, * next; + struct list_head *hash_table = lv->lv_snapshot_hash_table, *next, *n; unsigned long mask = lv->lv_snapshot_hash_mask; int chunk_size = lv->lv_chunk_size; - lv_block_exception_t * ret; + lv_block_exception_t *ret; int i = 0; - hash_table = &hash_table[hashfn(org_dev, org_start, mask, chunk_size)]; + hash_table = + &hash_table[hashfn(org_dev, org_start, mask, chunk_size)]; ret = NULL; - for (next = hash_table->next; next != hash_table; next = next->next) - { - lv_block_exception_t * exception; + + for (next = hash_table->next, n = next->next; next != hash_table; + next = n, n = next->next) { + lv_block_exception_t *exception; exception = list_entry(next, lv_block_exception_t, hash); if (exception->rsector_org == org_start && - exception->rdev_org == org_dev) - { - if (i) - { + exception->rdev_org == org_dev) { + if (i) { /* fun, isn't it? :) */ -#ifdef list_move - list_move(next, hash_table); -#else list_del(next); list_add(next, hash_table); -#endif } ret = exception; break; @@ -145,13 +149,14 @@ kdev_t org_dev, unsigned long org_start, lv_t * lv) { - struct list_head * hash_table = lv->lv_snapshot_hash_table; + struct list_head *hash_table = lv->lv_snapshot_hash_table; unsigned long mask = lv->lv_snapshot_hash_mask; int chunk_size = lv->lv_chunk_size; if (!hash_table) BUG(); - hash_table = &hash_table[hashfn(org_dev, org_start, mask, chunk_size)]; + hash_table = + &hash_table[hashfn(org_dev, org_start, mask, chunk_size)]; list_add(&exception->hash, hash_table); } @@ -163,26 +168,25 @@ * * We need to be holding at least a read lock on lv->lv_lock. */ -int lvm_snapshot_remap_block(kdev_t * org_dev, unsigned long * org_sector, +int lvm_snapshot_remap_block(kdev_t * org_dev, unsigned long *org_sector, unsigned long pe_start, lv_t * lv) { int ret; unsigned long pe_off, pe_adjustment, __org_start; kdev_t __org_dev; int chunk_size = lv->lv_chunk_size; - lv_block_exception_t * exception; + lv_block_exception_t *exception; if (!lv->lv_block_exception) return -1; pe_off = pe_start % chunk_size; - pe_adjustment = (*org_sector-pe_off) % chunk_size; + pe_adjustment = (*org_sector - pe_off) % chunk_size; __org_start = *org_sector - pe_adjustment; __org_dev = *org_dev; ret = 0; exception = lvm_find_exception_table(__org_dev, __org_start, lv); - if (exception) - { + if (exception) { *org_dev = exception->rdev_new; *org_sector = exception->rsector_new + pe_adjustment; ret = 1; @@ -190,7 +194,7 @@ return ret; } -void lvm_drop_snapshot(vg_t *vg, lv_t *lv_snap, const char *reason) +void lvm_drop_snapshot(vg_t * vg, lv_t * lv_snap, const char *reason) { kdev_t last_dev; int i; @@ -203,7 +207,7 @@ _disable_snapshot(vg, lv_snap); for (i = last_dev = 0; i < lv_snap->lv_remap_ptr; i++) { - if ( lv_snap->lv_block_exception[i].rdev_new != last_dev) { + if (lv_snap->lv_block_exception[i].rdev_new != last_dev) { last_dev = lv_snap->lv_block_exception[i].rdev_new; invalidate_buffers(last_dev); } @@ -214,14 +218,14 @@ printk(KERN_INFO "%s -- giving up to snapshot %s on %s: %s\n", - lvm_name, lv_snap->lv_snapshot_org->lv_name, lv_snap->lv_name, - reason); + lvm_name, lv_snap->lv_snapshot_org->lv_name, + lv_snap->lv_name, reason); } static inline int lvm_snapshot_prepare_blocks(unsigned long *blocks, - unsigned long start, - int nr_sectors, - int blocksize) + unsigned long start, + int nr_sectors, + int blocksize) { int i, sectors_per_block, nr_blocks; @@ -244,8 +248,7 @@ int correct_size = BLOCK_SIZE, i, major; major = MAJOR(dev); - if (blksize_size[major]) - { + if (blksize_size[major]) { i = blksize_size[major][MINOR(dev)]; if (i) correct_size = i; @@ -254,10 +257,10 @@ } #ifdef DEBUG_SNAPSHOT -static inline void invalidate_snap_cache(unsigned long start, unsigned long nr, - kdev_t dev) +static inline void invalidate_snap_cache(unsigned long start, + unsigned long nr, kdev_t dev) { - struct buffer_head * bh; + struct buffer_head *bh; int sectors_per_block, i, blksize, minor; minor = MINOR(dev); @@ -266,8 +269,7 @@ nr /= sectors_per_block; start /= sectors_per_block; - for (i = 0; i < nr; i++) - { + for (i = 0; i < nr; i++) { bh = get_hash_table(dev, start++, blksize); if (bh) bforget(bh); @@ -280,40 +282,44 @@ { int id = 0, is = lv_snap->lv_remap_ptr; ulong blksize_snap; - lv_COW_table_disk_t * lv_COW_table = (lv_COW_table_disk_t *) - page_address(lv_snap->lv_COW_table_iobuf->maplist[0]); + lv_COW_table_disk_t *lv_COW_table = (lv_COW_table_disk_t *) + page_address(lv_snap->lv_COW_table_iobuf->maplist[0]); if (is == 0) return 0; is--; blksize_snap = - lvm_get_blksize(lv_snap->lv_block_exception[is].rdev_new); + lvm_get_blksize(lv_snap->lv_block_exception[is].rdev_new); is -= is % (blksize_snap / sizeof(lv_COW_table_disk_t)); memset(lv_COW_table, 0, blksize_snap); - for ( ; is < lv_snap->lv_remap_ptr; is++, id++) { + for (; is < lv_snap->lv_remap_ptr; is++, id++) { /* store new COW_table entry */ - lv_block_exception_t *be = lv_snap->lv_block_exception + is; + lv_block_exception_t *be = + lv_snap->lv_block_exception + is; uint pvn; if (_pv_get_number(vg, be->rdev_org, &pvn)) goto bad; lv_COW_table[id].pv_org_number = cpu_to_le64(pvn); - lv_COW_table[id].pv_org_rsector = cpu_to_le64(be->rsector_org); + lv_COW_table[id].pv_org_rsector = + cpu_to_le64(be->rsector_org); if (_pv_get_number(vg, be->rdev_new, &pvn)) goto bad; lv_COW_table[id].pv_snap_number = cpu_to_le64(pvn); - lv_COW_table[id].pv_snap_rsector = cpu_to_le64(be->rsector_new); + lv_COW_table[id].pv_snap_rsector = + cpu_to_le64(be->rsector_new); } return 0; - bad: - printk(KERN_ERR "%s -- lvm_snapshot_fill_COW_page failed", lvm_name); + bad: + printk(KERN_ERR "%s -- lvm_snapshot_fill_COW_page failed", + lvm_name); return -1; } @@ -323,12 +329,12 @@ * * We need to hold a write lock on lv_snap->lv_lock. */ -int lvm_write_COW_table_block(vg_t * vg, lv_t *lv_snap) +int lvm_write_COW_table_block(vg_t * vg, lv_t * lv_snap) { int r; const char *err; - if((r = _write_COW_table_block(vg, lv_snap, - lv_snap->lv_remap_ptr - 1, &err))) + if ((r = _write_COW_table_block(vg, lv_snap, + lv_snap->lv_remap_ptr - 1, &err))) lvm_drop_snapshot(vg, lv_snap, err); return r; } @@ -349,13 +355,15 @@ unsigned long org_phys_sector, unsigned long org_pe_start, unsigned long org_virt_sector, - vg_t *vg, lv_t* lv_snap) + vg_t * vg, lv_t * lv_snap) { - const char * reason; - unsigned long org_start, snap_start, snap_phys_dev, virt_start, pe_off; + const char *reason; + unsigned long org_start, snap_start, snap_phys_dev, virt_start, + pe_off; unsigned long phys_start; - int idx = lv_snap->lv_remap_ptr, chunk_size = lv_snap->lv_chunk_size; - struct kiobuf * iobuf = lv_snap->lv_iobuf; + int idx = lv_snap->lv_remap_ptr, chunk_size = + lv_snap->lv_chunk_size; + struct kiobuf *iobuf = lv_snap->lv_iobuf; unsigned long *blocks = iobuf->blocks; int blksize_snap, blksize_org, min_blksize, max_blksize; int max_sectors, nr_sectors; @@ -366,7 +374,8 @@ /* calculate physical boundaries of source chunk */ pe_off = org_pe_start % chunk_size; - org_start = org_phys_sector - ((org_phys_sector-pe_off) % chunk_size); + org_start = + org_phys_sector - ((org_phys_sector - pe_off) % chunk_size); virt_start = org_virt_sector - (org_phys_sector - org_start); /* calculate physical boundaries of destination chunk */ @@ -381,25 +390,22 @@ lvm_name, kdevname(org_phys_dev), org_phys_sector, org_start, kdevname(snap_phys_dev), snap_start, - chunk_size, - org_pe_start, pe_off, - org_virt_sector); + chunk_size, org_pe_start, pe_off, org_virt_sector); #endif blksize_org = lvm_sectsize(org_phys_dev); blksize_snap = lvm_sectsize(snap_phys_dev); max_blksize = max(blksize_org, blksize_snap); min_blksize = min(blksize_org, blksize_snap); - max_sectors = KIO_MAX_SECTORS * (min_blksize>>9); + max_sectors = KIO_MAX_SECTORS * (min_blksize >> 9); - if (chunk_size % (max_blksize>>9)) + if (chunk_size % (max_blksize >> 9)) goto fail_blksize; /* Don't change org_start, we need it to fill in the exception table */ phys_start = org_start; - while (chunk_size) - { + while (chunk_size) { nr_sectors = min(chunk_size, max_sectors); chunk_size -= nr_sectors; @@ -410,7 +416,8 @@ goto fail_prepare; if (__brw_kiovec(READ, 1, &iobuf, org_phys_dev, blocks, - blksize_org, lv_snap) != (nr_sectors<<9)) + blksize_org, + lv_snap) != (nr_sectors << 9)) goto fail_raw_read; if (!lvm_snapshot_prepare_blocks(blocks, snap_start, @@ -418,7 +425,8 @@ goto fail_prepare; if (__brw_kiovec(WRITE, 1, &iobuf, snap_phys_dev, blocks, - blksize_snap, lv_snap) != (nr_sectors<<9)) + blksize_snap, + lv_snap) != (nr_sectors << 9)) goto fail_raw_write; phys_start += nr_sectors; @@ -440,53 +448,55 @@ org_phys_dev, org_start, lv_snap); lv_snap->lv_remap_ptr = idx + 1; if (lv_snap->lv_snapshot_use_rate > 0) { - if (lv_snap->lv_remap_ptr * 100 / lv_snap->lv_remap_end >= lv_snap->lv_snapshot_use_rate) + if (lv_snap->lv_remap_ptr * 100 / lv_snap->lv_remap_end >= + lv_snap->lv_snapshot_use_rate) wake_up_interruptible(&lv_snap->lv_snapshot_wait); } return 0; /* slow path */ -out: + out: lvm_drop_snapshot(vg, lv_snap, reason); return 1; -fail_out_of_space: + fail_out_of_space: reason = "out of space"; goto out; -fail_raw_read: + fail_raw_read: reason = "read error"; goto out; -fail_raw_write: + fail_raw_write: reason = "write error"; goto out; -fail_blksize: + fail_blksize: reason = "blocksize error"; goto out; -fail_prepare: + fail_prepare: reason = "couldn't prepare kiovec blocks " - "(start probably isn't block aligned)"; + "(start probably isn't block aligned)"; goto out; } -int lvm_snapshot_alloc_iobuf_pages(struct kiobuf * iobuf, int sectors) +int lvm_snapshot_alloc_iobuf_pages(struct kiobuf *iobuf, int sectors) { int bytes, nr_pages, err, i; bytes = sectors * SECTOR_SIZE; nr_pages = (bytes + ~PAGE_MASK) >> PAGE_SHIFT; err = expand_kiobuf(iobuf, nr_pages); - if (err) goto out; + if (err) + goto out; err = -ENOMEM; iobuf->locked = 1; iobuf->nr_pages = 0; - for (i = 0; i < nr_pages; i++) - { - struct page * page; + for (i = 0; i < nr_pages; i++) { + struct page *page; page = alloc_page(GFP_KERNEL); - if (!page) goto out; + if (!page) + goto out; iobuf->maplist[i] = page; LockPage(page); @@ -496,7 +506,7 @@ err = 0; -out: + out: return err; } @@ -516,13 +526,13 @@ { int err; unsigned long buckets, max_buckets, size; - struct list_head * hash; + struct list_head *hash; buckets = lv->lv_remap_end; max_buckets = calc_max_buckets(); buckets = min(buckets, max_buckets); - while (buckets & (buckets-1)) - buckets &= (buckets-1); + while (buckets & (buckets - 1)) + buckets &= (buckets - 1); size = buckets * sizeof(struct list_head); @@ -534,47 +544,51 @@ goto out; lv->lv_snapshot_hash_table_size = size; - lv->lv_snapshot_hash_mask = buckets-1; + lv->lv_snapshot_hash_mask = buckets - 1; while (buckets--) - INIT_LIST_HEAD(hash+buckets); + INIT_LIST_HEAD(hash + buckets); err = 0; -out: + out: return err; } int lvm_snapshot_alloc(lv_t * lv_snap) { - int ret, max_sectors; + int ret; /* allocate kiovec to do chunk io */ ret = alloc_kiovec(1, &lv_snap->lv_iobuf); - if (ret) goto out; - - max_sectors = KIO_MAX_SECTORS << (PAGE_SHIFT-9); + if (ret) + goto out; - ret = lvm_snapshot_alloc_iobuf_pages(lv_snap->lv_iobuf, max_sectors); - if (ret) goto out_free_kiovec; + ret = lvm_snapshot_alloc_iobuf_pages(lv_snap->lv_iobuf, + KIO_MAX_SECTORS); + if (ret) + goto out_free_kiovec; /* allocate kiovec to do exception table io */ ret = alloc_kiovec(1, &lv_snap->lv_COW_table_iobuf); - if (ret) goto out_free_kiovec; + if (ret) + goto out_free_kiovec; ret = lvm_snapshot_alloc_iobuf_pages(lv_snap->lv_COW_table_iobuf, - PAGE_SIZE/SECTOR_SIZE); - if (ret) goto out_free_both_kiovecs; + PAGE_SIZE / SECTOR_SIZE); + if (ret) + goto out_free_both_kiovecs; ret = lvm_snapshot_alloc_hash_table(lv_snap); - if (ret) goto out_free_both_kiovecs; + if (ret) + goto out_free_both_kiovecs; -out: + out: return ret; -out_free_both_kiovecs: + out_free_both_kiovecs: unmap_kiobuf(lv_snap->lv_COW_table_iobuf); free_kiovec(1, &lv_snap->lv_COW_table_iobuf); lv_snap->lv_COW_table_iobuf = NULL; -out_free_kiovec: + out_free_kiovec: unmap_kiobuf(lv_snap->lv_iobuf); free_kiovec(1, &lv_snap->lv_iobuf); lv_snap->lv_iobuf = NULL; @@ -585,27 +599,23 @@ void lvm_snapshot_release(lv_t * lv) { - if (lv->lv_block_exception) - { + if (lv->lv_block_exception) { vfree(lv->lv_block_exception); lv->lv_block_exception = NULL; } - if (lv->lv_snapshot_hash_table) - { + if (lv->lv_snapshot_hash_table) { vfree(lv->lv_snapshot_hash_table); lv->lv_snapshot_hash_table = NULL; lv->lv_snapshot_hash_table_size = 0; } - if (lv->lv_iobuf) - { - kiobuf_wait_for_io(lv->lv_iobuf); + if (lv->lv_iobuf) { + kiobuf_wait_for_io(lv->lv_iobuf); unmap_kiobuf(lv->lv_iobuf); free_kiovec(1, &lv->lv_iobuf); lv->lv_iobuf = NULL; } - if (lv->lv_COW_table_iobuf) - { - kiobuf_wait_for_io(lv->lv_COW_table_iobuf); + if (lv->lv_COW_table_iobuf) { + kiobuf_wait_for_io(lv->lv_COW_table_iobuf); unmap_kiobuf(lv->lv_COW_table_iobuf); free_kiovec(1, &lv->lv_COW_table_iobuf); lv->lv_COW_table_iobuf = NULL; @@ -613,55 +623,67 @@ } -static int _write_COW_table_block(vg_t *vg, lv_t *lv_snap, - int idx, const char **reason) { +static int _write_COW_table_block(vg_t * vg, lv_t * lv_snap, + int idx, const char **reason) +{ int blksize_snap; int end_of_table; int idx_COW_table; uint pvn; ulong snap_pe_start, COW_table_sector_offset, - COW_entries_per_pe, COW_chunks_per_pe, COW_entries_per_block; + COW_entries_per_pe, COW_chunks_per_pe, COW_entries_per_block; ulong blocks[1]; kdev_t snap_phys_dev; lv_block_exception_t *be; struct kiobuf *COW_table_iobuf = lv_snap->lv_COW_table_iobuf; - lv_COW_table_disk_t * lv_COW_table = - ( lv_COW_table_disk_t *) page_address(lv_snap->lv_COW_table_iobuf->maplist[0]); + lv_COW_table_disk_t *lv_COW_table = + (lv_COW_table_disk_t *) page_address(lv_snap-> + lv_COW_table_iobuf-> + maplist[0]); COW_chunks_per_pe = LVM_GET_COW_TABLE_CHUNKS_PER_PE(vg, lv_snap); COW_entries_per_pe = LVM_GET_COW_TABLE_ENTRIES_PER_PE(vg, lv_snap); /* get physical addresse of destination chunk */ snap_phys_dev = lv_snap->lv_block_exception[idx].rdev_new; - snap_pe_start = lv_snap->lv_block_exception[idx - (idx % COW_entries_per_pe)].rsector_new - lv_snap->lv_chunk_size; + snap_pe_start = + lv_snap->lv_block_exception[idx - + (idx % + COW_entries_per_pe)].rsector_new - + lv_snap->lv_chunk_size; blksize_snap = lvm_sectsize(snap_phys_dev); - COW_entries_per_block = blksize_snap / sizeof(lv_COW_table_disk_t); - idx_COW_table = idx % COW_entries_per_pe % COW_entries_per_block; + COW_entries_per_block = blksize_snap / sizeof(lv_COW_table_disk_t); + idx_COW_table = idx % COW_entries_per_pe % COW_entries_per_block; - if ( idx_COW_table == 0) memset(lv_COW_table, 0, blksize_snap); + if (idx_COW_table == 0) + memset(lv_COW_table, 0, blksize_snap); /* sector offset into the on disk COW table */ - COW_table_sector_offset = (idx % COW_entries_per_pe) / (SECTOR_SIZE / sizeof(lv_COW_table_disk_t)); - - /* COW table block to write next */ - blocks[0] = (snap_pe_start + COW_table_sector_offset) >> (blksize_snap >> 10); + COW_table_sector_offset = + (idx % COW_entries_per_pe) / (SECTOR_SIZE / + sizeof(lv_COW_table_disk_t)); + + /* COW table block to write next */ + blocks[0] = + (snap_pe_start + + COW_table_sector_offset) >> (blksize_snap >> 10); /* store new COW_table entry */ be = lv_snap->lv_block_exception + idx; - if(_pv_get_number(vg, be->rdev_org, &pvn)) + if (_pv_get_number(vg, be->rdev_org, &pvn)) goto fail_pv_get_number; lv_COW_table[idx_COW_table].pv_org_number = cpu_to_le64(pvn); lv_COW_table[idx_COW_table].pv_org_rsector = - cpu_to_le64(be->rsector_org); - if(_pv_get_number(vg, snap_phys_dev, &pvn)) + cpu_to_le64(be->rsector_org); + if (_pv_get_number(vg, snap_phys_dev, &pvn)) goto fail_pv_get_number; lv_COW_table[idx_COW_table].pv_snap_number = cpu_to_le64(pvn); lv_COW_table[idx_COW_table].pv_snap_rsector = - cpu_to_le64(be->rsector_new); + cpu_to_le64(be->rsector_new); COW_table_iobuf->length = blksize_snap; /* COW_table_iobuf->nr_pages = 1; */ @@ -672,36 +694,42 @@ /* initialization of next COW exception table block with zeroes */ end_of_table = idx % COW_entries_per_pe == COW_entries_per_pe - 1; - if (idx_COW_table % COW_entries_per_block == COW_entries_per_block - 1 || end_of_table) - { + if (idx_COW_table % COW_entries_per_block == + COW_entries_per_block - 1 || end_of_table) { /* don't go beyond the end */ - if (idx + 1 >= lv_snap->lv_remap_end) goto out; + if (idx + 1 >= lv_snap->lv_remap_end) + goto out; memset(lv_COW_table, 0, blksize_snap); - if (end_of_table) - { + if (end_of_table) { idx++; - snap_phys_dev = lv_snap->lv_block_exception[idx].rdev_new; - snap_pe_start = lv_snap->lv_block_exception[idx - (idx % COW_entries_per_pe)].rsector_new - lv_snap->lv_chunk_size; + snap_phys_dev = + lv_snap->lv_block_exception[idx].rdev_new; + snap_pe_start = + lv_snap->lv_block_exception[idx - + (idx % + COW_entries_per_pe)]. + rsector_new - lv_snap->lv_chunk_size; blksize_snap = lvm_sectsize(snap_phys_dev); blocks[0] = snap_pe_start >> (blksize_snap >> 10); - } else blocks[0]++; + } else + blocks[0]++; if (__brw_kiovec(WRITE, 1, &COW_table_iobuf, snap_phys_dev, - blocks, blksize_snap, lv_snap) != - blksize_snap) + blocks, blksize_snap, lv_snap) != + blksize_snap) goto fail_raw_write; } -out: + out: return 0; -fail_raw_write: + fail_raw_write: *reason = "write error"; return 1; -fail_pv_get_number: + fail_pv_get_number: *reason = "_pv_get_number failed"; return 1; } @@ -717,10 +745,12 @@ * to activate the snapshot and prevent this from happening. */ -static void _disable_snapshot(vg_t *vg, lv_t *lv) { +static void _disable_snapshot(vg_t * vg, lv_t * lv) +{ const char *err; - lv->lv_block_exception[0].rsector_org = LVM_SNAPSHOT_DROPPED_SECTOR; - if(_write_COW_table_block(vg, lv, 0, &err) < 0) { + lv->lv_block_exception[0].rsector_org = + LVM_SNAPSHOT_DROPPED_SECTOR; + if (_write_COW_table_block(vg, lv, 0, &err) < 0) { printk(KERN_ERR "%s -- couldn't disable snapshot: %s\n", lvm_name, err); } Index: drivers/md/lvm.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/md/lvm.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/md/lvm.c 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/md/lvm.c 4 Aug 2004 01:29:02 -0000 1.2 @@ -8,7 +8,8 @@ * January-March,May,July,September,October 1999 * January,February,July,September-November 2000 * January-May,June,October 2001 - * May-July 2002 + * May-August 2002 + * February 2003 * * * LVM driver is free software; you can redistribute it and/or modify @@ -220,6 +221,12 @@ * - support HDIO_GETGEO_BIG ioctl * 05/07/2002 - fixed OBO error on vg array access [benh@kernel.crashing.org] * 22/07/2002 - streamlined blk_ioctl() call + * 14/08/2002 - stored fs handle in lvm_do_lv_rename + * [kaoru@bsd.tnes.nec.co.jp] + * 06/02/2003 - fix persistent snapshot extend/reduce bug in + * lvm_do_lv_extend_reduce() [dalestephenson@mac.com] + * 04/03/2003 - snapshot extend/reduce memory leak + * - VG PE counter wrong [dalestephenson@mac.com] * */ @@ -283,13 +290,14 @@ /* * External function prototypes */ -static int lvm_make_request_fn(request_queue_t*, int, struct buffer_head*); +static int lvm_make_request_fn(request_queue_t *, int, + struct buffer_head *); static int lvm_blk_ioctl(struct inode *, struct file *, uint, ulong); static int lvm_blk_open(struct inode *, struct file *); static int lvm_blk_close(struct inode *, struct file *); -static int lvm_get_snapshot_use_rate(lv_t *lv_ptr, void *arg); +static int lvm_get_snapshot_use_rate(lv_t * lv_ptr, void *arg); static int lvm_user_bmap(struct inode *, struct lv_bmap *); static int lvm_chr_open(struct inode *, struct file *); @@ -319,13 +327,13 @@ static int lvm_do_lv_extend_reduce(int, char *, lv_t *); static int lvm_do_lv_remove(int, char *, int); static int lvm_do_lv_rename(vg_t *, lv_req_t *, lv_t *); -static int lvm_do_lv_status_byname(vg_t *r, void *); +static int lvm_do_lv_status_byname(vg_t * r, void *); static int lvm_do_lv_status_byindex(vg_t *, void *); static int lvm_do_lv_status_bydev(vg_t *, void *); -static int lvm_do_pe_lock_unlock(vg_t *r, void *); +static int lvm_do_pe_lock_unlock(vg_t * r, void *); -static int lvm_do_pv_change(vg_t*, void*); +static int lvm_do_pv_change(vg_t *, void *); static int lvm_do_pv_status(vg_t *, void *); static int lvm_do_pv_flush(void *); @@ -335,15 +343,15 @@ static int lvm_do_vg_rename(vg_t *, void *); static int lvm_do_vg_remove(int); static void lvm_geninit(struct gendisk *); -static void __update_hardsectsize(lv_t *lv); +static void __update_hardsectsize(lv_t * lv); static void _queue_io(struct buffer_head *bh, int rw); static struct buffer_head *_dequeue_io(void); static void _flush_io(struct buffer_head *bh); -static int _open_pv(pv_t *pv); -static void _close_pv(pv_t *pv); +static int _open_pv(pv_t * pv); +static void _close_pv(pv_t * pv); static unsigned long _sectors_to_k(unsigned long sect); @@ -354,7 +362,8 @@ /* variables */ -char *lvm_version = "LVM version "LVM_RELEASE_NAME"("LVM_RELEASE_DATE")"; +char *lvm_version = + "LVM version " LVM_RELEASE_NAME "(" LVM_RELEASE_DATE ")"; ushort lvm_iop_version = LVM_DRIVER_IOP_VERSION; int loadtime = 0; const char *const lvm_name = LVM_NAME; @@ -397,19 +406,18 @@ struct file_operations lvm_chr_fops = { - owner: THIS_MODULE, - open: lvm_chr_open, - release: lvm_chr_close, - ioctl: lvm_chr_ioctl, + owner:THIS_MODULE, + open:lvm_chr_open, + release:lvm_chr_close, + ioctl:lvm_chr_ioctl, }; /* block device operations structure needed for 2.3.38? and above */ -struct block_device_operations lvm_blk_dops = -{ - owner: THIS_MODULE, - open: lvm_blk_open, - release: lvm_blk_close, - ioctl: lvm_blk_ioctl, +struct block_device_operations lvm_blk_dops = { + .owner = THIS_MODULE, + .open = lvm_blk_open, + .release = lvm_blk_close, + .ioctl = lvm_blk_ioctl, }; @@ -419,15 +427,14 @@ static int lvm_hardsectsizes[MAX_LV]; static int lvm_size[MAX_LV]; -static struct gendisk lvm_gendisk = -{ - major: MAJOR_NR, - major_name: LVM_NAME, - minor_shift: 0, - max_p: 1, - part: lvm_hd_struct, - sizes: lvm_size, - nr_real: MAX_LV, +static struct gendisk lvm_gendisk = { + .major = MAJOR_NR, + .major_name = LVM_NAME, + .minor_shift = 0, + .max_p = 1, + .part = lvm_hd_struct, + .sizes = lvm_size, + .nr_real = MAX_LV, }; @@ -464,7 +471,8 @@ lvm_hd_name_ptr = lvm_hd_name; #endif - blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), lvm_make_request_fn); + blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), + lvm_make_request_fn); /* initialise the pe lock */ @@ -482,7 +490,7 @@ #endif return 0; -} /* lvm_init() */ +} /* lvm_init() */ /* * cleanup... @@ -515,11 +523,12 @@ lvm_fin_fs(); #ifdef MODULE - printk(KERN_INFO "%s -- Module successfully deactivated\n", lvm_name); + printk(KERN_INFO "%s -- Module successfully deactivated\n", + lvm_name); #endif return; -} /* lvm_cleanup() */ +} /* lvm_cleanup() */ /* * support function to initialize lvm variables @@ -549,7 +558,7 @@ } return; -} /* lvm_init_vars() */ +} /* lvm_init_vars() */ /******************************************************************** @@ -572,13 +581,15 @@ minor, VG_CHR(minor), MODE_TO_STR(file->f_mode), lock); /* super user validation */ - if (!capable(CAP_SYS_ADMIN)) return -EACCES; + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; /* Group special file open */ - if (VG_CHR(minor) > MAX_VG) return -ENXIO; + if (VG_CHR(minor) > MAX_VG) + return -ENXIO; spin_lock(&lvm_lock); - if(lock == current->pid) + if (lock == current->pid) _lock_open_count++; spin_unlock(&lvm_lock); @@ -587,7 +598,7 @@ MOD_INC_USE_COUNT; return 0; -} /* lvm_chr_open() */ +} /* lvm_chr_open() */ /* @@ -604,16 +615,19 @@ uint extendable, l, v; void *arg = (void *) a; lv_t lv; - vg_t* vg_ptr = vg[VG_CHR(minor)]; + vg_t *vg_ptr = vg[VG_CHR(minor)]; /* otherwise cc will complain about unused variables */ (void) lvm_lock; - P_IOCTL("chr MINOR: %d command: 0x%X arg: %p VG#: %d mode: %s%s\n", - minor, command, arg, VG_CHR(minor), MODE_TO_STR(file->f_mode)); + P_IOCTL + ("chr MINOR: %d command: 0x%X arg: %p VG#: %d mode: %s%s\n", + minor, command, arg, VG_CHR(minor), + MODE_TO_STR(file->f_mode)); #ifdef LVM_TOTAL_RESET - if (lvm_reset_spindown > 0) return -EACCES; + if (lvm_reset_spindown > 0) + return -EACCES; #endif /* Main command switch */ @@ -625,7 +639,8 @@ case LVM_GET_IOP_VERSION: /* check lvm version to ensure driver/tools+lib interoperability */ - if (copy_to_user(arg, &lvm_iop_version, sizeof(ushort)) != 0) + if (copy_to_user(arg, &lvm_iop_version, sizeof(ushort)) != + 0) return -EFAULT; return 0; @@ -634,7 +649,8 @@ /* lock reset function */ lvm_reset_spindown = 1; for (v = 0; v < ABS_MAX_VG; v++) { - if (vg[v] != NULL) lvm_do_vg_remove(v); + if (vg[v] != NULL) + lvm_do_vg_remove(v); } #ifdef MODULE @@ -642,28 +658,28 @@ MOD_INC_USE_COUNT; while (GET_USE_COUNT(&__this_module) > 1) MOD_DEC_USE_COUNT; -#endif /* MODULE */ +#endif /* MODULE */ lock = 0; /* release lock */ wake_up_interruptible(&lvm_wait); return 0; -#endif /* LVM_TOTAL_RESET */ +#endif /* LVM_TOTAL_RESET */ case LE_REMAP: /* remap a logical extent (after moving the physical extent) */ - return lvm_do_le_remap(vg_ptr,arg); + return lvm_do_le_remap(vg_ptr, arg); case PE_LOCK_UNLOCK: /* lock/unlock i/o to a physical extent to move it to another physical volume (move's done in user space's pvmove) */ - return lvm_do_pe_lock_unlock(vg_ptr,arg); + return lvm_do_pe_lock_unlock(vg_ptr, arg); case VG_CREATE_OLD: /* create a VGDA */ return lvm_do_vg_create(arg, minor); case VG_CREATE: - /* create a VGDA, assume VG number is filled in */ + /* create a VGDA, assume VG number is filled in */ return lvm_do_vg_create(arg, -1); case VG_EXTEND: @@ -685,8 +701,10 @@ case VG_SET_EXTENDABLE: /* set/clear extendability flag of volume group */ - if (vg_ptr == NULL) return -ENXIO; - if (copy_from_user(&extendable, arg, sizeof(extendable)) != 0) + if (vg_ptr == NULL) + return -ENXIO; + if (copy_from_user(&extendable, arg, sizeof(extendable)) != + 0) return -EFAULT; if (extendable == VG_EXTENDABLE || @@ -695,13 +713,15 @@ vg_ptr->vg_status |= VG_EXTENDABLE; else vg_ptr->vg_status &= ~VG_EXTENDABLE; - } else return -EINVAL; + } else + return -EINVAL; return 0; case VG_STATUS: /* get volume group data (only the vg_t struct) */ - if (vg_ptr == NULL) return -ENXIO; + if (vg_ptr == NULL) + return -ENXIO; if (copy_to_user(arg, vg_ptr, sizeof(vg_t)) != 0) return -EFAULT; return 0; @@ -734,21 +754,26 @@ case LV_REMOVE: case LV_RENAME: /* create, extend, reduce, remove or rename a logical volume */ - if (vg_ptr == NULL) return -ENXIO; + if (vg_ptr == NULL) + return -ENXIO; if (copy_from_user(&lv_req, arg, sizeof(lv_req)) != 0) return -EFAULT; if (command != LV_REMOVE) { - if (copy_from_user(&lv, lv_req.lv, sizeof(lv_t)) != 0) + if (copy_from_user(&lv, lv_req.lv, sizeof(lv_t)) != + 0) return -EFAULT; } switch (command) { case LV_CREATE: - return lvm_do_lv_create(minor, lv_req.lv_name, &lv); + return lvm_do_lv_create(minor, lv_req.lv_name, + &lv); case LV_EXTEND: case LV_REDUCE: - return lvm_do_lv_extend_reduce(minor, lv_req.lv_name, &lv); + return lvm_do_lv_extend_reduce(minor, + lv_req.lv_name, + &lv); case LV_REMOVE: return lvm_do_lv_remove(minor, lv_req.lv_name, -1); @@ -776,12 +801,12 @@ case PV_CHANGE: /* change a physical volume */ - return lvm_do_pv_change(vg_ptr,arg); + return lvm_do_pv_change(vg_ptr, arg); case PV_STATUS: /* get physical volume data (pv_t structure only) */ - return lvm_do_pv_status(vg_ptr,arg); + return lvm_do_pv_status(vg_ptr, arg); case PV_FLUSH: @@ -797,7 +822,7 @@ } return 0; -} /* lvm_chr_ioctl */ +} /* lvm_chr_ioctl */ /* @@ -815,12 +840,14 @@ } #endif - if (lvm_chr_open_count > 0) lvm_chr_open_count--; + if (lvm_chr_open_count > 0) + lvm_chr_open_count--; spin_lock(&lvm_lock); - if(lock == current->pid) { - if(!_lock_open_count) { - P_DEV("chr_close: unlocking LVM for pid %d\n", lock); + if (lock == current->pid) { + if (!_lock_open_count) { + P_DEV("chr_close: unlocking LVM for pid %d\n", + lock); lock = 0; wake_up_interruptible(&lvm_wait); } else @@ -831,7 +858,7 @@ MOD_DEC_USE_COUNT; return 0; -} /* lvm_chr_close() */ +} /* lvm_chr_close() */ @@ -851,7 +878,8 @@ vg_t *vg_ptr = vg[VG_BLK(minor)]; P_DEV("blk_open MINOR: %d VG#: %d LV#: %d mode: %s%s\n", - minor, VG_BLK(minor), LV_BLK(minor), MODE_TO_STR(file->f_mode)); + minor, VG_BLK(minor), LV_BLK(minor), + MODE_TO_STR(file->f_mode)); #ifdef LVM_TOTAL_RESET if (lvm_reset_spindown > 0) @@ -861,26 +889,27 @@ if (vg_ptr != NULL && (vg_ptr->vg_status & VG_ACTIVE) && (lv_ptr = vg_ptr->lv[LV_BLK(minor)]) != NULL && - LV_BLK(minor) >= 0 && - LV_BLK(minor) < vg_ptr->lv_max) { + LV_BLK(minor) >= 0 && LV_BLK(minor) < vg_ptr->lv_max) { /* Check parallel LV spindown (LV remove) */ - if (lv_ptr->lv_status & LV_SPINDOWN) return -EPERM; + if (lv_ptr->lv_status & LV_SPINDOWN) + return -EPERM; /* Check inactive LV and open for read/write */ /* We need to be able to "read" an inactive LV to re-activate it again */ if ((file->f_mode & FMODE_WRITE) && (!(lv_ptr->lv_status & LV_ACTIVE))) - return -EPERM; + return -EPERM; if (!(lv_ptr->lv_access & LV_WRITE) && (file->f_mode & FMODE_WRITE)) return -EACCES; - /* be sure to increment VG counter */ - if (lv_ptr->lv_open == 0) vg_ptr->lv_open++; + /* be sure to increment VG counter */ + if (lv_ptr->lv_open == 0) + vg_ptr->lv_open++; lv_ptr->lv_open++; MOD_INC_USE_COUNT; @@ -890,10 +919,10 @@ return 0; } return -ENXIO; -} /* lvm_blk_open() */ +} /* lvm_blk_open() */ /* Deliver "hard disk geometry" */ -static int _hdio_getgeo(ulong a, lv_t *lv_ptr, int what) +static int _hdio_getgeo(ulong a, lv_t * lv_ptr, int what) { int ret = 0; uchar heads = 128; @@ -901,34 +930,34 @@ ulong start = 0; uint cylinders; - while ( heads * sectors > lv_ptr->lv_size) { + while (heads * sectors > lv_ptr->lv_size) { heads >>= 1; sectors >>= 1; } cylinders = lv_ptr->lv_size / heads / sectors; switch (what) { - case 0: + case 0: { struct hd_geometry *hd = (struct hd_geometry *) a; if (put_user(heads, &hd->heads) || - put_user(sectors, &hd->sectors) || - put_user((ushort) cylinders, &hd->cylinders) || + put_user(sectors, &hd->sectors) || + put_user((ushort) cylinders, &hd->cylinders) || put_user(start, &hd->start)) return -EFAULT; break; } #ifdef HDIO_GETGEO_BIG - case 1: + case 1: { struct hd_big_geometry *hd = - (struct hd_big_geometry *) a; + (struct hd_big_geometry *) a; if (put_user(heads, &hd->heads) || - put_user(sectors, &hd->sectors) || - put_user(cylinders, &hd->cylinders) || + put_user(sectors, &hd->sectors) || + put_user(cylinders, &hd->cylinders) || put_user(start, &hd->start)) return -EFAULT; break; @@ -960,91 +989,92 @@ LV_BLK(minor), MODE_TO_STR(file->f_mode)); switch (cmd) { - case BLKRASET: - /* set read ahead for block device */ - ret = blk_ioctl(dev, cmd, a); - if (ret) - return ret; - lv_ptr->lv_read_ahead = (long) a; - LVM_CORRECT_READ_AHEAD(lv_ptr->lv_read_ahead); - break; - - case HDIO_GETGEO: + case BLKRASET: + /* set read ahead for block device */ + ret = blk_ioctl(dev, cmd, a); + if (ret) + return ret; + lv_ptr->lv_read_ahead = (long) a; + LVM_CORRECT_READ_AHEAD(lv_ptr->lv_read_ahead); + break; + + case HDIO_GETGEO: #ifdef HDIO_GETGEO_BIG - case HDIO_GETGEO_BIG: + case HDIO_GETGEO_BIG: #endif - /* get disk geometry */ - P_IOCTL("%s -- lvm_blk_ioctl -- HDIO_GETGEO\n", - lvm_name); - if (!a) - return -EINVAL; - - switch (cmd) { - case HDIO_GETGEO: - return _hdio_getgeo(a, lv_ptr, 0); + /* get disk geometry */ + P_IOCTL("%s -- lvm_blk_ioctl -- HDIO_GETGEO\n", lvm_name); + if (!a) + return -EINVAL; + + switch (cmd) { + case HDIO_GETGEO: + return _hdio_getgeo(a, lv_ptr, 0); #ifdef HDIO_GETGEO_BIG - case HDIO_GETGEO_BIG: - return _hdio_getgeo(a, lv_ptr, 1); + case HDIO_GETGEO_BIG: + return _hdio_getgeo(a, lv_ptr, 1); #endif - } - - case LV_BMAP: - /* turn logical block into (dev_t, block). non privileged. */ - /* don't bmap a snapshot, since the mapping can change */ - if (lv_ptr->lv_access & LV_SNAPSHOT) - return -EPERM; - - return lvm_user_bmap(inode, (struct lv_bmap *) arg); - - case LV_SET_ACCESS: - /* set access flags of a logical volume */ - if (!capable(CAP_SYS_ADMIN)) return -EACCES; - - down_write(&lv_ptr->lv_lock); - lv_ptr->lv_access = (ulong) arg; - up_write(&lv_ptr->lv_lock); - - if ( lv_ptr->lv_access & LV_WRITE) - set_device_ro(lv_ptr->lv_dev, 0); - else - set_device_ro(lv_ptr->lv_dev, 1); - break; - - - case LV_SET_ALLOCATION: - /* set allocation flags of a logical volume */ - if (!capable(CAP_SYS_ADMIN)) return -EACCES; - down_write(&lv_ptr->lv_lock); - lv_ptr->lv_allocation = (ulong) arg; - up_write(&lv_ptr->lv_lock); - break; - - case LV_SET_STATUS: - /* set status flags of a logical volume */ - if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if (!((ulong) arg & LV_ACTIVE) && lv_ptr->lv_open > 1) - return -EPERM; - down_write(&lv_ptr->lv_lock); - lv_ptr->lv_status = (ulong) arg; - up_write(&lv_ptr->lv_lock); - break; - - case LV_SNAPSHOT_USE_RATE: - return lvm_get_snapshot_use_rate(lv_ptr, arg); - - default: - /* Handle rest here */ - ret = blk_ioctl(dev, cmd, a); - if (ret) - printk(KERN_WARNING - "%s -- lvm_blk_ioctl: unknown " - "cmd 0x%x\n", - lvm_name, cmd); - return ret; + } + + case LV_BMAP: + /* turn logical block into (dev_t, block). non privileged. */ + /* don't bmap a snapshot, since the mapping can change */ + if (lv_ptr->lv_access & LV_SNAPSHOT) + return -EPERM; + + return lvm_user_bmap(inode, (struct lv_bmap *) arg); + + case LV_SET_ACCESS: + /* set access flags of a logical volume */ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + down_write(&lv_ptr->lv_lock); + lv_ptr->lv_access = (ulong) arg; + up_write(&lv_ptr->lv_lock); + + if (lv_ptr->lv_access & LV_WRITE) + set_device_ro(lv_ptr->lv_dev, 0); + else + set_device_ro(lv_ptr->lv_dev, 1); + break; + + + case LV_SET_ALLOCATION: + /* set allocation flags of a logical volume */ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + down_write(&lv_ptr->lv_lock); + lv_ptr->lv_allocation = (ulong) arg; + up_write(&lv_ptr->lv_lock); + break; + + case LV_SET_STATUS: + /* set status flags of a logical volume */ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + if (!((ulong) arg & LV_ACTIVE) && lv_ptr->lv_open > 1) + return -EPERM; + down_write(&lv_ptr->lv_lock); + lv_ptr->lv_status = (ulong) arg; + up_write(&lv_ptr->lv_lock); + break; + + case LV_SNAPSHOT_USE_RATE: + return lvm_get_snapshot_use_rate(lv_ptr, arg); + + default: + /* Handle rest here */ + ret = blk_ioctl(dev, cmd, a); + if (ret) + printk(KERN_WARNING + "%s -- lvm_blk_ioctl: unknown " + "cmd 0x%x\n", lvm_name, cmd); + return ret; } return 0; -} /* lvm_blk_ioctl() */ +} /* lvm_blk_ioctl() */ /* @@ -1059,15 +1089,16 @@ P_DEV("blk_close MINOR: %d VG#: %d LV#: %d\n", minor, VG_BLK(minor), LV_BLK(minor)); - if (lv_ptr->lv_open == 1) vg_ptr->lv_open--; + if (lv_ptr->lv_open == 1) + vg_ptr->lv_open--; lv_ptr->lv_open--; MOD_DEC_USE_COUNT; return 0; -} /* lvm_blk_close() */ +} /* lvm_blk_close() */ -static int lvm_get_snapshot_use_rate(lv_t *lv, void *arg) +static int lvm_get_snapshot_use_rate(lv_t * lv, void *arg) { lv_snapshot_use_rate_req_t lv_rate_req; @@ -1122,20 +1153,20 @@ if (get_user(block, &user_result->lv_block)) return -EFAULT; - memset(&bh,0,sizeof bh); + memset(&bh, 0, sizeof bh); bh.b_blocknr = block; bh.b_dev = bh.b_rdev = inode->i_rdev; bh.b_size = lvm_get_blksize(bh.b_dev); bh.b_rsector = block * (bh.b_size >> 9); bh.b_end_io = NULL; - if ((err = lvm_map(&bh, READ)) < 0) { + if ((err = lvm_map(&bh, READ)) < 0) { printk("lvm map failed: %d\n", err); return -EINVAL; } return put_user(kdev_t_to_nr(bh.b_rdev), &user_result->lv_dev) || - put_user(bh.b_rsector/(bh.b_size>>9), &user_result->lv_block) ? - -EFAULT : 0; + put_user(bh.b_rsector / (bh.b_size >> 9), + &user_result->lv_block) ? -EFAULT : 0; } @@ -1144,7 +1175,8 @@ * (see init_module/lvm_init) */ static void __remap_snapshot(kdev_t rdev, ulong rsector, - ulong pe_start, lv_t *lv, vg_t *vg) { + ulong pe_start, lv_t * lv, vg_t * vg) +{ /* copy a chunk from the origin to a snapshot device */ down_write(&lv->lv_lock); @@ -1159,7 +1191,8 @@ } static inline void _remap_snapshot(kdev_t rdev, ulong rsector, - ulong pe_start, lv_t *lv, vg_t *vg) { + ulong pe_start, lv_t * lv, vg_t * vg) +{ int r; /* check to see if this chunk is already in the snapshot */ @@ -1176,7 +1209,8 @@ /* * extents destined for a pe that is on the move should be deferred */ -static inline int _should_defer(kdev_t pv, ulong sector, uint32_t pe_size) { +static inline int _should_defer(kdev_t pv, ulong sector, uint32_t pe_size) +{ return ((pe_lock_req.lock == LOCK_PE) && (pv == pe_lock_req.data.pv_dev) && (sector >= pe_lock_req.data.pv_offset) && @@ -1223,34 +1257,32 @@ goto bad; } - if ((rw == WRITE || rw == WRITEA) && - !(lv->lv_access & LV_WRITE)) { + if ((rw == WRITE || rw == WRITEA) && !(lv->lv_access & LV_WRITE)) { printk(KERN_CRIT "%s - lvm_map: ll_rw_blk write for readonly LV %s\n", lvm_name, lv->lv_name); goto bad; } - P_MAP("%s - lvm_map minor: %d *rdev: %s *rsector: %lu size:%lu\n", - lvm_name, minor, - kdevname(bh->b_rdev), - rsector_org, size); + P_MAP + ("%s - lvm_map minor: %d *rdev: %s *rsector: %lu size:%lu\n", + lvm_name, minor, kdevname(bh->b_rdev), rsector_org, size); if (rsector_org + size > lv->lv_size) { printk(KERN_ALERT "%s - lvm_map access beyond end of device; *rsector: " - "%lu or size: %lu wrong for minor: %2d\n", - lvm_name, rsector_org, size, minor); + "%lu or size: %lu wrong for minor: %2d\n", + lvm_name, rsector_org, size, minor); goto bad; } - if (lv->lv_stripes < 2) { /* linear mapping */ + if (lv->lv_stripes < 2) { /* linear mapping */ /* get the index */ index = rsector_org / vg_this->pe_size; pe_start = lv->lv_current_pe[index].pe; rsector_map = lv->lv_current_pe[index].pe + - (rsector_org % vg_this->pe_size); + (rsector_org % vg_this->pe_size); rdev_map = lv->lv_current_pe[index].dev; P_MAP("lv_current_pe[%ld].pe: %d rdev: %s rsector:%ld\n", @@ -1263,22 +1295,23 @@ stripe_length = vg_this->pe_size * lv->lv_stripes; stripe_index = (rsector_org % stripe_length) / - lv->lv_stripesize; + lv->lv_stripesize; index = rsector_org / stripe_length + - (stripe_index % lv->lv_stripes) * - (lv->lv_allocated_le / lv->lv_stripes); + (stripe_index % lv->lv_stripes) * + (lv->lv_allocated_le / lv->lv_stripes); pe_start = lv->lv_current_pe[index].pe; rsector_map = lv->lv_current_pe[index].pe + - (rsector_org % stripe_length) - - (stripe_index % lv->lv_stripes) * lv->lv_stripesize - - stripe_index / lv->lv_stripes * - (lv->lv_stripes - 1) * lv->lv_stripesize; + (rsector_org % stripe_length) - + (stripe_index % lv->lv_stripes) * lv->lv_stripesize - + stripe_index / lv->lv_stripes * + (lv->lv_stripes - 1) * lv->lv_stripesize; rdev_map = lv->lv_current_pe[index].dev; P_MAP("lv_current_pe[%ld].pe: %d rdev: %s rsector:%ld\n" "stripe_length: %ld stripe_index: %ld\n", - index, lv->lv_current_pe[index].pe, kdevname(rdev_map), - rsector_map, stripe_length, stripe_index); + index, lv->lv_current_pe[index].pe, + kdevname(rdev_map), rsector_map, stripe_length, + stripe_index); } /* @@ -1287,8 +1320,8 @@ * we need to queue this request, because this is in the fast path. */ if (rw == WRITE || rw == WRITEA) { - if(_defer_extent(bh, rw, rdev_map, - rsector_map, vg_this->pe_size)) { + if (_defer_extent(bh, rw, rdev_map, + rsector_map, vg_this->pe_size)) { up_read(&lv->lv_lock); return 0; @@ -1299,15 +1332,15 @@ lv->lv_current_pe[index].reads++; /* statistic */ /* snapshot volume exception handling on physical device address base */ - if (!(lv->lv_access & (LV_SNAPSHOT|LV_SNAPSHOT_ORG))) + if (!(lv->lv_access & (LV_SNAPSHOT | LV_SNAPSHOT_ORG))) goto out; - if (lv->lv_access & LV_SNAPSHOT) { /* remap snapshot */ + if (lv->lv_access & LV_SNAPSHOT) { /* remap snapshot */ if (lvm_snapshot_remap_block(&rdev_map, &rsector_map, pe_start, lv) < 0) goto bad; - } else if (rw == WRITE || rw == WRITEA) { /* snapshot origin */ + } else if (rw == WRITE || rw == WRITEA) { /* snapshot origin */ lv_t *snap; /* start with first snapshot and loop through all of @@ -1321,22 +1354,22 @@ /* Serializes the COW with the accesses to the snapshot device */ _remap_snapshot(rdev_map, rsector_map, - pe_start, snap, vg_this); + pe_start, snap, vg_this); } } - out: + out: bh->b_rdev = rdev_map; bh->b_rsector = rsector_map; up_read(&lv->lv_lock); return 1; - bad: + bad: if (bh->b_end_io) - buffer_IO_error(bh); + buffer_IO_error(bh); up_read(&lv->lv_lock); return -1; -} /* lvm_map() */ +} /* lvm_map() */ /* @@ -1368,9 +1401,8 @@ /* * make request function */ -static int lvm_make_request_fn(request_queue_t *q, - int rw, - struct buffer_head *bh) +static int lvm_make_request_fn(request_queue_t * q, + int rw, struct buffer_head *bh) { return (lvm_map(bh, rw) <= 0) ? 0 : 1; } @@ -1386,7 +1418,7 @@ */ static int lvm_do_lock_lvm(void) { -lock_try_again: + lock_try_again: spin_lock(&lvm_lock); if (lock != 0 && lock != current->pid) { P_DEV("lvm_do_lock_lvm: locked by pid %d ...\n", lock); @@ -1404,19 +1436,20 @@ P_DEV("lvm_do_lock_lvm: locking LVM for pid %d\n", lock); spin_unlock(&lvm_lock); return 0; -} /* lvm_do_lock_lvm */ +} /* lvm_do_lock_lvm */ /* * character device support function lock/unlock physical extend */ -static int lvm_do_pe_lock_unlock(vg_t *vg_ptr, void *arg) +static int lvm_do_pe_lock_unlock(vg_t * vg_ptr, void *arg) { pe_lock_req_t new_lock; struct buffer_head *bh; uint p; - if (vg_ptr == NULL) return -ENXIO; + if (vg_ptr == NULL) + return -ENXIO; if (copy_from_user(&new_lock, arg, sizeof(new_lock)) != 0) return -EFAULT; @@ -1427,7 +1460,8 @@ new_lock.data.pv_dev == vg_ptr->pv[p]->pv_dev) break; } - if (p == vg_ptr->pv_max) return -ENXIO; + if (p == vg_ptr->pv_max) + return -ENXIO; /* * this sync releaves memory pressure to lessen the @@ -1478,12 +1512,13 @@ /* * character device support function logical extend remap */ -static int lvm_do_le_remap(vg_t *vg_ptr, void *arg) +static int lvm_do_le_remap(vg_t * vg_ptr, void *arg) { uint l, le; lv_t *lv_ptr; - if (vg_ptr == NULL) return -ENXIO; + if (vg_ptr == NULL) + return -ENXIO; if (copy_from_user(&le_remap_req, arg, sizeof(le_remap_req_t)) != 0) return -EFAULT; @@ -1515,7 +1550,7 @@ } } return -ENXIO; -} /* lvm_do_le_remap() */ +} /* lvm_do_le_remap() */ /* @@ -1529,7 +1564,7 @@ vg_t *vg_ptr; lv_t **snap_lv_ptr; - if ((vg_ptr = kmalloc(sizeof(vg_t),GFP_KERNEL)) == NULL) { + if ((vg_ptr = kmalloc(sizeof(vg_t), GFP_KERNEL)) == NULL) { printk(KERN_CRIT "%s -- VG_CREATE: kmalloc error VG at line %d\n", lvm_name, __LINE__); @@ -1537,8 +1572,9 @@ } /* get the volume group structure */ if (copy_from_user(vg_ptr, arg, sizeof(vg_t)) != 0) { - P_IOCTL("lvm_do_vg_create ERROR: copy VG ptr %p (%d bytes)\n", - arg, sizeof(vg_t)); + P_IOCTL + ("lvm_do_vg_create ERROR: copy VG ptr %p (%d bytes)\n", + arg, sizeof(vg_t)); kfree(vg_ptr); return -EFAULT; } @@ -1548,8 +1584,10 @@ minor = vg_ptr->vg_number; /* check limits */ - if (minor >= ABS_MAX_VG) + if (minor >= ABS_MAX_VG) { + kfree(vg_ptr); return -EFAULT; + } /* Validate it */ if (vg[VG_CHR(minor)] != NULL) { @@ -1572,7 +1610,7 @@ if (vg_ptr->lv_max > ABS_MAX_LV) { printk(KERN_WARNING - "%s -- Can't activate VG: ABS_MAX_LV too small for %u\n", + "%s -- Can't activate VG: ABS_MAX_LV too small for %u\n", lvm_name, vg_ptr->lv_max); kfree(vg_ptr); return -EPERM; @@ -1590,7 +1628,7 @@ /* user space address */ if ((pvp = vg_ptr->pv[p]) != NULL) { ret = lvm_do_pv_create(pvp, vg_ptr, p); - if ( ret != 0) { + if (ret != 0) { lvm_do_vg_remove(minor); return ret; } @@ -1598,7 +1636,7 @@ } size = vg_ptr->lv_max * sizeof(lv_t *); - if ((snap_lv_ptr = vmalloc ( size)) == NULL) { + if ((snap_lv_ptr = vmalloc(size)) == NULL) { printk(KERN_CRIT "%s -- VG_CREATE: vmalloc error snapshot LVs at line %d\n", lvm_name, __LINE__); @@ -1614,12 +1652,12 @@ /* user space address */ if ((lvp = vg_ptr->lv[l]) != NULL) { if (copy_from_user(&lv, lvp, sizeof(lv_t)) != 0) { - P_IOCTL("ERROR: copying LV ptr %p (%d bytes)\n", - lvp, sizeof(lv_t)); - lvm_do_vg_remove(minor); - return -EFAULT; + P_IOCTL + ("ERROR: copying LV ptr %p (%d bytes)\n", + lvp, sizeof(lv_t)); + goto copy_fault; } - if ( lv.lv_access & LV_SNAPSHOT) { + if (lv.lv_access & LV_SNAPSHOT) { snap_lv_ptr[ls] = lvp; vg_ptr->lv[l] = NULL; ls++; @@ -1628,8 +1666,7 @@ vg_ptr->lv[l] = NULL; /* only create original logical volumes for now */ if (lvm_do_lv_create(minor, lv.lv_name, &lv) != 0) { - lvm_do_vg_remove(minor); - return -EFAULT; + goto copy_fault; } } } @@ -1639,12 +1676,10 @@ for (l = 0; l < ls; l++) { lv_t *lvp = snap_lv_ptr[l]; if (copy_from_user(&lv, lvp, sizeof(lv_t)) != 0) { - lvm_do_vg_remove(minor); - return -EFAULT; + goto copy_fault; } if (lvm_do_lv_create(minor, lv.lv_name, &lv) != 0) { - lvm_do_vg_remove(minor); - return -EFAULT; + goto copy_fault; } } @@ -1659,24 +1694,30 @@ vg_ptr->vg_status |= VG_ACTIVE; return 0; -} /* lvm_do_vg_create() */ +copy_fault: + lvm_do_vg_remove(minor); + vfree(snap_lv_ptr); + return -EFAULT; +} /* lvm_do_vg_create() */ /* * character device support function VGDA extend */ -static int lvm_do_vg_extend(vg_t *vg_ptr, void *arg) +static int lvm_do_vg_extend(vg_t * vg_ptr, void *arg) { int ret = 0; uint p; pv_t *pv_ptr; - if (vg_ptr == NULL) return -ENXIO; + if (vg_ptr == NULL) + return -ENXIO; if (vg_ptr->pv_cur < vg_ptr->pv_max) { for (p = 0; p < vg_ptr->pv_max; p++) { - if ( ( pv_ptr = vg_ptr->pv[p]) == NULL) { + if ((pv_ptr = vg_ptr->pv[p]) == NULL) { ret = lvm_do_pv_create(arg, vg_ptr, p); - if ( ret != 0) return ret; + if (ret != 0) + return ret; pv_ptr = vg_ptr->pv[p]; vg_ptr->pe_total += pv_ptr->pe_total; return 0; @@ -1684,26 +1725,28 @@ } } return -EPERM; -} /* lvm_do_vg_extend() */ +} /* lvm_do_vg_extend() */ /* * character device support function VGDA reduce */ -static int lvm_do_vg_reduce(vg_t *vg_ptr, void *arg) { +static int lvm_do_vg_reduce(vg_t * vg_ptr, void *arg) +{ uint p; pv_t *pv_ptr; - if (vg_ptr == NULL) return -ENXIO; + if (vg_ptr == NULL) + return -ENXIO; if (copy_from_user(pv_name, arg, sizeof(pv_name)) != 0) return -EFAULT; for (p = 0; p < vg_ptr->pv_max; p++) { pv_ptr = vg_ptr->pv[p]; if (pv_ptr != NULL && - strcmp(pv_ptr->pv_name, - pv_name) == 0) { - if (pv_ptr->lv_cur > 0) return -EPERM; + strcmp(pv_ptr->pv_name, pv_name) == 0) { + if (pv_ptr->lv_cur > 0) + return -EPERM; lvm_do_pv_remove(vg_ptr, p); /* Make PV pointer array contiguous */ for (; p < vg_ptr->pv_max - 1; p++) @@ -1713,55 +1756,56 @@ } } return -ENXIO; -} /* lvm_do_vg_reduce */ +} /* lvm_do_vg_reduce */ /* * character device support function VG rename */ -static int lvm_do_vg_rename(vg_t *vg_ptr, void *arg) +static int lvm_do_vg_rename(vg_t * vg_ptr, void *arg) { int l = 0, p = 0, len = 0; - char vg_name[NAME_LEN] = { 0,}; - char lv_name[NAME_LEN] = { 0,}; + char vg_name[NAME_LEN] = { 0, }; + char lv_name[NAME_LEN] = { 0, }; char *ptr = NULL; lv_t *lv_ptr = NULL; pv_t *pv_ptr = NULL; /* If the VG doesn't exist in the kernel then just exit */ - if (!vg_ptr) return 0; + if (!vg_ptr) + return 0; if (copy_from_user(vg_name, arg, sizeof(vg_name)) != 0) return -EFAULT; lvm_fs_remove_vg(vg_ptr); - strncpy ( vg_ptr->vg_name, vg_name, sizeof ( vg_name)-1); - for ( l = 0; l < vg_ptr->lv_max; l++) - { - if ((lv_ptr = vg_ptr->lv[l]) == NULL) continue; - memset (lv_ptr->vg_name, 0, sizeof (*vg_name)); - strncpy(lv_ptr->vg_name, vg_name, sizeof ( vg_name)); + strncpy(vg_ptr->vg_name, vg_name, sizeof(vg_name) - 1); + for (l = 0; l < vg_ptr->lv_max; l++) { + if ((lv_ptr = vg_ptr->lv[l]) == NULL) + continue; + memset(lv_ptr->vg_name, 0, sizeof(*vg_name)); + strncpy(lv_ptr->vg_name, vg_name, sizeof(vg_name)); ptr = strrchr(lv_ptr->lv_name, '/'); ptr = ptr ? ptr + 1 : lv_ptr->lv_name; - strncpy(lv_name, ptr, sizeof ( lv_name)); + strncpy(lv_name, ptr, sizeof(lv_name)); len = sizeof(LVM_DIR_PREFIX); strcpy(lv_ptr->lv_name, LVM_DIR_PREFIX); strncat(lv_ptr->lv_name, vg_name, NAME_LEN - len); - strcat (lv_ptr->lv_name, "/"); + strcat(lv_ptr->lv_name, "/"); len += strlen(vg_name) + 1; strncat(lv_ptr->lv_name, lv_name, NAME_LEN - len); } - for ( p = 0; p < vg_ptr->pv_max; p++) - { - if ( (pv_ptr = vg_ptr->pv[p]) == NULL) continue; + for (p = 0; p < vg_ptr->pv_max; p++) { + if ((pv_ptr = vg_ptr->pv[p]) == NULL) + continue; strncpy(pv_ptr->vg_name, vg_name, NAME_LEN); } lvm_fs_create_vg(vg_ptr); /* Need to add PV entries */ - for ( p = 0; p < vg_ptr->pv_act; p++) { + for (p = 0; p < vg_ptr->pv_act; p++) { pv_t *pv_ptr = vg_ptr->pv[p]; if (pv_ptr) @@ -1769,18 +1813,18 @@ } /* Need to add LV entries */ - for ( l = 0; l < vg_ptr->lv_max; l++) { + for (l = 0; l < vg_ptr->lv_max; l++) { lv_t *lv_ptr = vg_ptr->lv[l]; if (!lv_ptr) continue; lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].de = - lvm_fs_create_lv(vg_ptr, lv_ptr); + lvm_fs_create_lv(vg_ptr, lv_ptr); } return 0; -} /* lvm_do_vg_rename */ +} /* lvm_do_vg_rename */ /* @@ -1792,7 +1836,8 @@ vg_t *vg_ptr = vg[VG_CHR(minor)]; pv_t *pv_ptr; - if (vg_ptr == NULL) return -ENXIO; + if (vg_ptr == NULL) + return -ENXIO; #ifdef LVM_TOTAL_RESET if (vg_ptr->lv_open > 0 && lvm_reset_spindown == 0) @@ -1843,20 +1888,21 @@ MOD_DEC_USE_COUNT; return 0; -} /* lvm_do_vg_remove() */ +} /* lvm_do_vg_remove() */ /* * character device support function physical volume create */ -static int lvm_do_pv_create(pv_t *pvp, vg_t *vg_ptr, ulong p) { +static int lvm_do_pv_create(pv_t * pvp, vg_t * vg_ptr, ulong p) +{ pv_t *pv; int err; if (!vg_ptr) return -ENXIO; - pv = kmalloc(sizeof(pv_t),GFP_KERNEL); + pv = kmalloc(sizeof(pv_t), GFP_KERNEL); if (pv == NULL) { printk(KERN_CRIT "%s -- PV_CREATE: kmalloc error PV at line %d\n", @@ -1867,8 +1913,9 @@ memset(pv, 0, sizeof(*pv)); if (copy_from_user(pv, pvp, sizeof(pv_t)) != 0) { - P_IOCTL("lvm_do_pv_create ERROR: copy PV ptr %p (%d bytes)\n", - pvp, sizeof(pv_t)); + P_IOCTL + ("lvm_do_pv_create ERROR: copy PV ptr %p (%d bytes)\n", + pvp, sizeof(pv_t)); kfree(pv); return -EFAULT; } @@ -1889,13 +1936,14 @@ vg_ptr->pv[p] = pv; return 0; -} /* lvm_do_pv_create() */ +} /* lvm_do_pv_create() */ /* * character device support function physical volume remove */ -static int lvm_do_pv_remove(vg_t *vg_ptr, ulong p) { +static int lvm_do_pv_remove(vg_t * vg_ptr, ulong p) +{ pv_t *pv = vg_ptr->pv[p]; lvm_fs_remove_pv(vg_ptr, pv); @@ -1913,7 +1961,7 @@ } -static void __update_hardsectsize(lv_t *lv) +static void __update_hardsectsize(lv_t * lv) { int max_hardsectsize = 0, hardsectsize = 0; int p; @@ -1925,9 +1973,10 @@ if (max_hardsectsize == 0) max_hardsectsize = hardsectsize; else if (hardsectsize != max_hardsectsize) { - P_DEV("%s PV[%d] (%s) sector size %d, not %d\n", - lv->lv_name, p, kdevname(pv->pv_dev), - hardsectsize, max_hardsectsize); + P_DEV + ("%s PV[%d] (%s) sector size %d, not %d\n", + lv->lv_name, p, kdevname(pv->pv_dev), + hardsectsize, max_hardsectsize); break; } } @@ -1937,12 +1986,14 @@ if (hardsectsize != max_hardsectsize) { int le; for (le = 0; le < lv->lv_allocated_le; le++) { - hardsectsize = lvm_sectsize(lv->lv_current_pe[le].dev); + hardsectsize = + lvm_sectsize(lv->lv_current_pe[le].dev); if (hardsectsize > max_hardsectsize) { - P_DEV("%s LE[%d] (%s) blocksize %d not %d\n", - lv->lv_name, le, - kdevname(lv->lv_current_pe[le].dev), - hardsectsize, max_hardsectsize); + P_DEV + ("%s LE[%d] (%s) blocksize %d not %d\n", + lv->lv_name, le, + kdevname(lv->lv_current_pe[le].dev), + hardsectsize, max_hardsectsize); max_hardsectsize = hardsectsize; } } @@ -1952,7 +2003,9 @@ (lv->lv_status & LV_ACTIVE)) { int e; for (e = 0; e < lv->lv_remap_end; e++) { - hardsectsize = lvm_sectsize(lv->lv_block_exception[e].rdev_new); + hardsectsize = + lvm_sectsize(lv->lv_block_exception[e]. + rdev_new); if (hardsectsize > max_hardsectsize) max_hardsectsize = hardsectsize; } @@ -1969,7 +2022,7 @@ /* * character device support function logical volume create */ -static int lvm_do_lv_create(int minor, char *lv_name, lv_t *lv) +static int lvm_do_lv_create(int minor, char *lv_name, lv_t * lv) { int e, ret, l, le, l_new, p, size, activate = 1; ulong lv_status_save; @@ -1997,14 +2050,18 @@ else { for (l = 0; l < vg_ptr->lv_max; l++) { if (vg_ptr->lv[l] == NULL) - if (l_new == -1) l_new = l; + if (l_new == -1) + l_new = l; } } - if (l_new == -1) return -EPERM; - else l = l_new; + if (l_new == -1) + return -EPERM; + else + l = l_new; - if ((lv_ptr = kmalloc(sizeof(lv_t),GFP_KERNEL)) == NULL) {; - printk(KERN_CRIT "%s -- LV_CREATE: kmalloc error LV at line %d\n", + if ((lv_ptr = kmalloc(sizeof(lv_t), GFP_KERNEL)) == NULL) {; + printk(KERN_CRIT + "%s -- LV_CREATE: kmalloc error LV at line %d\n", lvm_name, __LINE__); return -ENOMEM; } @@ -2036,8 +2093,7 @@ if ((lv_ptr->lv_current_pe = vmalloc(size)) == NULL) { printk(KERN_CRIT "%s -- LV_CREATE: vmalloc error LV_CURRENT_PE of %d Byte " - "at line %d\n", - lvm_name, size, __LINE__); + "at line %d\n", lvm_name, size, __LINE__); P_KFREE("%s -- kfree %d\n", lvm_name, __LINE__); kfree(lv_ptr); vg_ptr->lv[l] = NULL; @@ -2066,7 +2122,9 @@ lv_ptr->lv_snapshot_org = vg_ptr->lv[LV_BLK(lv_ptr->lv_snapshot_minor)]; if (lv_ptr->lv_snapshot_org != NULL) { - size = lv_ptr->lv_remap_end * sizeof(lv_block_exception_t); + size = + lv_ptr->lv_remap_end * + sizeof(lv_block_exception_t); if (!size) { printk(KERN_WARNING @@ -2076,29 +2134,32 @@ return -EINVAL; } - if ((lv_ptr->lv_block_exception = vmalloc(size)) == NULL) { + if ((lv_ptr->lv_block_exception = + vmalloc(size)) == NULL) { printk(KERN_CRIT "%s -- lvm_do_lv_create: vmalloc error LV_BLOCK_EXCEPTION " "of %d byte at line %d\n", lvm_name, size, __LINE__); - P_KFREE("%s -- kfree %d\n", lvm_name, - __LINE__); + P_KFREE("%s -- kfree %d\n", + lvm_name, __LINE__); kfree(lv_ptr); vg_ptr->lv[l] = NULL; return -ENOMEM; } - if (copy_from_user(lv_ptr->lv_block_exception, lvbe, size)) { + if (copy_from_user + (lv_ptr->lv_block_exception, lvbe, + size)) { vfree(lv_ptr->lv_block_exception); kfree(lv_ptr); vg_ptr->lv[l] = NULL; return -EFAULT; } - if(lv_ptr->lv_block_exception[0].rsector_org == - LVM_SNAPSHOT_DROPPED_SECTOR) - { + if (lv_ptr->lv_block_exception[0]. + rsector_org == + LVM_SNAPSHOT_DROPPED_SECTOR) { printk(KERN_WARNING - "%s -- lvm_do_lv_create: snapshot has been dropped and will not be activated\n", + "%s -- lvm_do_lv_create: snapshot has been dropped and will not be activated\n", lvm_name); activate = 0; } @@ -2112,36 +2173,54 @@ which can be the original logical volume */ lv_ptr = vg_ptr->lv[l]; /* now lv_ptr points to our new last snapshot logical volume */ - lv_ptr->lv_current_pe = lv_ptr->lv_snapshot_org->lv_current_pe; - lv_ptr->lv_allocated_snapshot_le = lv_ptr->lv_allocated_le; - lv_ptr->lv_allocated_le = lv_ptr->lv_snapshot_org->lv_allocated_le; - lv_ptr->lv_current_le = lv_ptr->lv_snapshot_org->lv_current_le; - lv_ptr->lv_size = lv_ptr->lv_snapshot_org->lv_size; - lv_ptr->lv_stripes = lv_ptr->lv_snapshot_org->lv_stripes; - lv_ptr->lv_stripesize = lv_ptr->lv_snapshot_org->lv_stripesize; + lv_ptr->lv_current_pe = + lv_ptr->lv_snapshot_org->lv_current_pe; + lv_ptr->lv_allocated_snapshot_le = + lv_ptr->lv_allocated_le; + lv_ptr->lv_allocated_le = + lv_ptr->lv_snapshot_org-> + lv_allocated_le; + lv_ptr->lv_current_le = + lv_ptr->lv_snapshot_org->lv_current_le; + lv_ptr->lv_size = + lv_ptr->lv_snapshot_org->lv_size; + lv_ptr->lv_stripes = + lv_ptr->lv_snapshot_org->lv_stripes; + lv_ptr->lv_stripesize = + lv_ptr->lv_snapshot_org->lv_stripesize; /* Update the VG PE(s) used by snapshot reserve space. */ - vg_ptr->pe_allocated += lv_ptr->lv_allocated_snapshot_le; + vg_ptr->pe_allocated += + lv_ptr->lv_allocated_snapshot_le; - if ((ret = lvm_snapshot_alloc(lv_ptr)) != 0) - { + if ((ret = + lvm_snapshot_alloc(lv_ptr)) != 0) { vfree(lv_ptr->lv_block_exception); kfree(lv_ptr); vg_ptr->lv[l] = NULL; return ret; } - for ( e = 0; e < lv_ptr->lv_remap_ptr; e++) - lvm_hash_link (lv_ptr->lv_block_exception + e, - lv_ptr->lv_block_exception[e].rdev_org, - lv_ptr->lv_block_exception[e].rsector_org, lv_ptr); + for (e = 0; e < lv_ptr->lv_remap_ptr; e++) + lvm_hash_link(lv_ptr-> + lv_block_exception + + e, + lv_ptr-> + lv_block_exception + [e].rdev_org, + lv_ptr-> + lv_block_exception + [e].rsector_org, + lv_ptr); /* need to fill the COW exception table data into the page for disk i/o */ - if(lvm_snapshot_fill_COW_page(vg_ptr, lv_ptr)) { + if (lvm_snapshot_fill_COW_page + (vg_ptr, lv_ptr)) { kfree(lv_ptr); vg_ptr->lv[l] = NULL; return -EINVAL; } - init_waitqueue_head(&lv_ptr->lv_snapshot_wait); + init_waitqueue_head(&lv_ptr-> + lv_snapshot_wait); } else { kfree(lv_ptr); vg_ptr->lv[l] = NULL; @@ -2152,7 +2231,7 @@ vg_ptr->lv[l] = NULL; return -EINVAL; } - } /* if ( vg[VG_CHR(minor)]->lv[l]->lv_access & LV_SNAPSHOT) */ + } /* if ( vg[VG_CHR(minor)]->lv[l]->lv_access & LV_SNAPSHOT) */ lv_ptr = vg_ptr->lv[l]; lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].start_sect = 0; @@ -2180,23 +2259,24 @@ down_write(&org->lv_lock); org->lv_access |= LV_SNAPSHOT_ORG; - lv_ptr->lv_access &= ~LV_SNAPSHOT_ORG; /* this can only hide an userspace bug */ + lv_ptr->lv_access &= ~LV_SNAPSHOT_ORG; /* this can only hide an userspace bug */ /* Link in the list of snapshot volumes */ - for (last = org; last->lv_snapshot_next; last = last->lv_snapshot_next); + for (last = org; last->lv_snapshot_next; + last = last->lv_snapshot_next); lv_ptr->lv_snapshot_prev = last; last->lv_snapshot_next = lv_ptr; up_write(&org->lv_lock); } /* activate the logical volume */ - if(activate) + if (activate) lv_ptr->lv_status |= LV_ACTIVE; else lv_ptr->lv_status &= ~LV_ACTIVE; - if ( lv_ptr->lv_access & LV_WRITE) + if (lv_ptr->lv_access & LV_WRITE) set_device_ro(lv_ptr->lv_dev, 0); else set_device_ro(lv_ptr->lv_dev, 1); @@ -2210,7 +2290,7 @@ lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].de = lvm_fs_create_lv(vg_ptr, lv_ptr); return 0; -} /* lvm_do_lv_create() */ +} /* lvm_do_lv_create() */ /* @@ -2233,7 +2313,8 @@ } } } - if (l == vg_ptr->lv_max) return -ENXIO; + if (l == vg_ptr->lv_max) + return -ENXIO; lv_ptr = vg_ptr->lv[l]; #ifdef LVM_TOTAL_RESET @@ -2253,14 +2334,15 @@ if (lv_ptr->lv_access & LV_SNAPSHOT) { /* - * Atomically make the snapshot invisible + * Atomically make the the snapshot invisible * to the original lv before playing with it. */ - lv_t * org = lv_ptr->lv_snapshot_org; + lv_t *org = lv_ptr->lv_snapshot_org; down_write(&org->lv_lock); /* remove this snapshot logical volume from the chain */ - lv_ptr->lv_snapshot_prev->lv_snapshot_next = lv_ptr->lv_snapshot_next; + lv_ptr->lv_snapshot_prev->lv_snapshot_next = + lv_ptr->lv_snapshot_next; if (lv_ptr->lv_snapshot_next != NULL) { lv_ptr->lv_snapshot_next->lv_snapshot_prev = lv_ptr->lv_snapshot_prev; @@ -2299,7 +2381,7 @@ vg_lv_map[MINOR(lv_ptr->lv_dev)].lv_number = -1; /* correct the PE count in PVs if this is not a snapshot - logical volume */ + logical volume */ if (!(lv_ptr->lv_access & LV_SNAPSHOT)) { /* only if this is no snapshot logical volume because we share the lv_current_pe[] structs with the @@ -2320,13 +2402,15 @@ vg_ptr->lv[l] = NULL; vg_ptr->lv_cur--; return 0; -} /* lvm_do_lv_remove() */ +} /* lvm_do_lv_remove() */ /* * logical volume extend / reduce */ -static int __extend_reduce_snapshot(vg_t *vg_ptr, lv_t *old_lv, lv_t *new_lv) { +static int __extend_reduce_snapshot(vg_t * vg_ptr, lv_t * old_lv, + lv_t * new_lv) +{ ulong size; lv_block_exception_t *lvbe; @@ -2357,7 +2441,8 @@ return 0; } -static int __extend_reduce(vg_t *vg_ptr, lv_t *old_lv, lv_t *new_lv) { +static int __extend_reduce(vg_t * vg_ptr, lv_t * old_lv, lv_t * new_lv) +{ ulong size, l, p, end; pe_t *pe; @@ -2373,7 +2458,7 @@ /* get the PE structures from user space */ if (copy_from_user(pe, new_lv->lv_current_pe, size)) { - if(old_lv->lv_access & LV_SNAPSHOT) + if (old_lv->lv_access & LV_SNAPSHOT) vfree(new_lv->lv_snapshot_hash_table); vfree(pe); return -EFAULT; @@ -2398,7 +2483,7 @@ vg_ptr->pe_allocated++; for (p = 0; p < vg_ptr->pv_cur; p++) { if (vg_ptr->pv[p]->pv_dev == - new_lv->lv_current_pe[l].dev) { + new_lv->lv_current_pe[l].dev) { vg_ptr->pv[p]->pe_allocated++; break; } @@ -2410,25 +2495,30 @@ end = min(old_lv->lv_current_le, new_lv->lv_current_le); for (l = 0; l < end; l++) { new_lv->lv_current_pe[l].reads += - old_lv->lv_current_pe[l].reads; + old_lv->lv_current_pe[l].reads; new_lv->lv_current_pe[l].writes += - old_lv->lv_current_pe[l].writes; + old_lv->lv_current_pe[l].writes; } } else { /* striped logical volume */ - uint i, j, source, dest, end, old_stripe_size, new_stripe_size; + uint i, j, source, dest, end, old_stripe_size, + new_stripe_size; - old_stripe_size = old_lv->lv_allocated_le / old_lv->lv_stripes; - new_stripe_size = new_lv->lv_allocated_le / new_lv->lv_stripes; + old_stripe_size = + old_lv->lv_allocated_le / old_lv->lv_stripes; + new_stripe_size = + new_lv->lv_allocated_le / new_lv->lv_stripes; end = min(old_stripe_size, new_stripe_size); for (i = source = dest = 0; i < new_lv->lv_stripes; i++) { for (j = 0; j < end; j++) { new_lv->lv_current_pe[dest + j].reads += - old_lv->lv_current_pe[source + j].reads; + old_lv->lv_current_pe[source + + j].reads; new_lv->lv_current_pe[dest + j].writes += - old_lv->lv_current_pe[source + j].writes; + old_lv->lv_current_pe[source + + j].writes; } source += old_stripe_size; dest += new_stripe_size; @@ -2438,7 +2528,7 @@ return 0; } -static int lvm_do_lv_extend_reduce(int minor, char *lv_name, lv_t *new_lv) +static int lvm_do_lv_extend_reduce(int minor, char *lv_name, lv_t * new_lv) { int r; ulong l, e, size; @@ -2453,7 +2543,8 @@ return -EINVAL; for (l = 0; l < vg_ptr->lv_max; l++) - if (vg_ptr->lv[l] && !strcmp(vg_ptr->lv[l]->lv_name, lv_name)) + if (vg_ptr->lv[l] + && !strcmp(vg_ptr->lv[l]->lv_name, lv_name)) break; if (l == vg_ptr->lv_max) @@ -2464,43 +2555,49 @@ if (old_lv->lv_access & LV_SNAPSHOT) { /* only perform this operation on active snapshots */ if (old_lv->lv_status & LV_ACTIVE) - r = __extend_reduce_snapshot(vg_ptr, old_lv, new_lv); + r = __extend_reduce_snapshot(vg_ptr, old_lv, + new_lv); else r = -EPERM; } else r = __extend_reduce(vg_ptr, old_lv, new_lv); - if(r) + if (r) return r; - /* copy relevent fields */ + /* copy relevant fields */ down_write(&old_lv->lv_lock); - if(new_lv->lv_access & LV_SNAPSHOT) { + if (new_lv->lv_access & LV_SNAPSHOT) { size = (new_lv->lv_remap_end > old_lv->lv_remap_end) ? - old_lv->lv_remap_ptr : new_lv->lv_remap_end; + old_lv->lv_remap_ptr : new_lv->lv_remap_end; size *= sizeof(lv_block_exception_t); memcpy(new_lv->lv_block_exception, old_lv->lv_block_exception, size); + vfree(old_lv->lv_block_exception); + vfree(old_lv->lv_snapshot_hash_table); old_lv->lv_remap_end = new_lv->lv_remap_end; old_lv->lv_block_exception = new_lv->lv_block_exception; old_lv->lv_snapshot_hash_table = - new_lv->lv_snapshot_hash_table; + new_lv->lv_snapshot_hash_table; old_lv->lv_snapshot_hash_table_size = - new_lv->lv_snapshot_hash_table_size; + new_lv->lv_snapshot_hash_table_size; old_lv->lv_snapshot_hash_mask = - new_lv->lv_snapshot_hash_mask; + new_lv->lv_snapshot_hash_mask; - for (e = 0; e < new_lv->lv_remap_ptr; e++) + for (e = 0; e < old_lv->lv_remap_ptr; e++) lvm_hash_link(new_lv->lv_block_exception + e, - new_lv->lv_block_exception[e].rdev_org, - new_lv->lv_block_exception[e].rsector_org, - new_lv); - + new_lv->lv_block_exception[e]. + rdev_org, + new_lv->lv_block_exception[e]. + rsector_org, new_lv); + + vg_ptr->pe_allocated -= old_lv->lv_allocated_snapshot_le; + vg_ptr->pe_allocated += new_lv->lv_allocated_le; + old_lv->lv_allocated_snapshot_le = new_lv->lv_allocated_le; } else { - vfree(old_lv->lv_current_pe); vfree(old_lv->lv_snapshot_hash_table); @@ -2509,24 +2606,26 @@ old_lv->lv_current_le = new_lv->lv_current_le; old_lv->lv_current_pe = new_lv->lv_current_pe; lvm_gendisk.part[MINOR(old_lv->lv_dev)].nr_sects = - old_lv->lv_size; + old_lv->lv_size; lvm_size[MINOR(old_lv->lv_dev)] = old_lv->lv_size >> 1; if (old_lv->lv_access & LV_SNAPSHOT_ORG) { lv_t *snap; - for(snap = old_lv->lv_snapshot_next; snap; - snap = snap->lv_snapshot_next) { + for (snap = old_lv->lv_snapshot_next; snap; + snap = snap->lv_snapshot_next) { down_write(&snap->lv_lock); - snap->lv_current_pe = old_lv->lv_current_pe; + snap->lv_current_pe = + old_lv->lv_current_pe; snap->lv_allocated_le = - old_lv->lv_allocated_le; - snap->lv_current_le = old_lv->lv_current_le; + old_lv->lv_allocated_le; + snap->lv_current_le = + old_lv->lv_current_le; snap->lv_size = old_lv->lv_size; - lvm_gendisk.part[MINOR(snap->lv_dev)].nr_sects - = old_lv->lv_size; + lvm_gendisk.part[MINOR(snap->lv_dev)]. + nr_sects = old_lv->lv_size; lvm_size[MINOR(snap->lv_dev)] = - old_lv->lv_size >> 1; + old_lv->lv_size >> 1; __update_hardsectsize(snap); up_write(&snap->lv_lock); } @@ -2537,13 +2636,13 @@ up_write(&old_lv->lv_lock); return 0; -} /* lvm_do_lv_extend_reduce() */ +} /* lvm_do_lv_extend_reduce() */ /* * character device support function logical volume status by name */ -static int lvm_do_lv_status_byname(vg_t *vg_ptr, void *arg) +static int lvm_do_lv_status_byname(vg_t * vg_ptr, void *arg) { uint l; lv_status_byname_req_t lv_status_byname_req; @@ -2551,137 +2650,166 @@ void *saved_ptr2; lv_t *lv_ptr; - if (vg_ptr == NULL) return -ENXIO; + if (vg_ptr == NULL) + return -ENXIO; if (copy_from_user(&lv_status_byname_req, arg, sizeof(lv_status_byname_req_t)) != 0) return -EFAULT; - if (lv_status_byname_req.lv == NULL) return -EINVAL; + if (lv_status_byname_req.lv == NULL) + return -EINVAL; for (l = 0; l < vg_ptr->lv_max; l++) { if ((lv_ptr = vg_ptr->lv[l]) != NULL && strcmp(lv_ptr->lv_name, lv_status_byname_req.lv_name) == 0) { - /* Save usermode pointers */ - if (copy_from_user(&saved_ptr1, &lv_status_byname_req.lv->lv_current_pe, sizeof(void*)) != 0) + /* Save usermode pointers */ + if (copy_from_user + (&saved_ptr1, + &lv_status_byname_req.lv->lv_current_pe, + sizeof(void *)) != 0) + return -EFAULT; + if (copy_from_user + (&saved_ptr2, + &lv_status_byname_req.lv->lv_block_exception, + sizeof(void *)) != 0) return -EFAULT; - if (copy_from_user(&saved_ptr2, &lv_status_byname_req.lv->lv_block_exception, sizeof(void*)) != 0) - return -EFAULT; - if (copy_to_user(lv_status_byname_req.lv, - lv_ptr, - sizeof(lv_t)) != 0) + if (copy_to_user(lv_status_byname_req.lv, + lv_ptr, sizeof(lv_t)) != 0) return -EFAULT; if (saved_ptr1 != NULL) { if (copy_to_user(saved_ptr1, lv_ptr->lv_current_pe, lv_ptr->lv_allocated_le * - sizeof(pe_t)) != 0) + sizeof(pe_t)) != 0) return -EFAULT; } /* Restore usermode pointers */ - if (copy_to_user(&lv_status_byname_req.lv->lv_current_pe, &saved_ptr1, sizeof(void*)) != 0) - return -EFAULT; + if (copy_to_user + (&lv_status_byname_req.lv->lv_current_pe, + &saved_ptr1, sizeof(void *)) != 0) + return -EFAULT; return 0; } } return -ENXIO; -} /* lvm_do_lv_status_byname() */ +} /* lvm_do_lv_status_byname() */ /* * character device support function logical volume status by index */ -static int lvm_do_lv_status_byindex(vg_t *vg_ptr,void *arg) +static int lvm_do_lv_status_byindex(vg_t * vg_ptr, void *arg) { lv_status_byindex_req_t lv_status_byindex_req; void *saved_ptr1; void *saved_ptr2; lv_t *lv_ptr; - if (vg_ptr == NULL) return -ENXIO; + if (vg_ptr == NULL) + return -ENXIO; if (copy_from_user(&lv_status_byindex_req, arg, sizeof(lv_status_byindex_req)) != 0) return -EFAULT; if (lv_status_byindex_req.lv == NULL) return -EINVAL; - if ( ( lv_ptr = vg_ptr->lv[lv_status_byindex_req.lv_index]) == NULL) + if ((lv_ptr = vg_ptr->lv[lv_status_byindex_req.lv_index]) == NULL) return -ENXIO; /* Save usermode pointers */ - if (copy_from_user(&saved_ptr1, &lv_status_byindex_req.lv->lv_current_pe, sizeof(void*)) != 0) - return -EFAULT; - if (copy_from_user(&saved_ptr2, &lv_status_byindex_req.lv->lv_block_exception, sizeof(void*)) != 0) - return -EFAULT; + if (copy_from_user + (&saved_ptr1, &lv_status_byindex_req.lv->lv_current_pe, + sizeof(void *)) != 0) + return -EFAULT; + if (copy_from_user + (&saved_ptr2, &lv_status_byindex_req.lv->lv_block_exception, + sizeof(void *)) != 0) + return -EFAULT; - if (copy_to_user(lv_status_byindex_req.lv, lv_ptr, sizeof(lv_t)) != 0) + if (copy_to_user(lv_status_byindex_req.lv, lv_ptr, sizeof(lv_t)) != + 0) return -EFAULT; if (saved_ptr1 != NULL) { if (copy_to_user(saved_ptr1, lv_ptr->lv_current_pe, lv_ptr->lv_allocated_le * - sizeof(pe_t)) != 0) + sizeof(pe_t)) != 0) return -EFAULT; } /* Restore usermode pointers */ - if (copy_to_user(&lv_status_byindex_req.lv->lv_current_pe, &saved_ptr1, sizeof(void *)) != 0) - return -EFAULT; + if (copy_to_user + (&lv_status_byindex_req.lv->lv_current_pe, &saved_ptr1, + sizeof(void *)) != 0) + return -EFAULT; return 0; -} /* lvm_do_lv_status_byindex() */ +} /* lvm_do_lv_status_byindex() */ /* * character device support function logical volume status by device number */ -static int lvm_do_lv_status_bydev(vg_t * vg_ptr, void * arg) { +static int lvm_do_lv_status_bydev(vg_t * vg_ptr, void *arg) +{ int l; lv_status_bydev_req_t lv_status_bydev_req; void *saved_ptr1; void *saved_ptr2; lv_t *lv_ptr; - if (vg_ptr == NULL) return -ENXIO; + if (vg_ptr == NULL) + return -ENXIO; if (copy_from_user(&lv_status_bydev_req, arg, sizeof(lv_status_bydev_req)) != 0) return -EFAULT; - for ( l = 0; l < vg_ptr->lv_max; l++) { - if ( vg_ptr->lv[l] == NULL) continue; - if ( vg_ptr->lv[l]->lv_dev == lv_status_bydev_req.dev) break; + for (l = 0; l < vg_ptr->lv_max; l++) { + if (vg_ptr->lv[l] == NULL) + continue; + if (vg_ptr->lv[l]->lv_dev == lv_status_bydev_req.dev) + break; } - if ( l == vg_ptr->lv_max) return -ENXIO; + if (l == vg_ptr->lv_max) + return -ENXIO; lv_ptr = vg_ptr->lv[l]; /* Save usermode pointers */ - if (copy_from_user(&saved_ptr1, &lv_status_bydev_req.lv->lv_current_pe, sizeof(void*)) != 0) - return -EFAULT; - if (copy_from_user(&saved_ptr2, &lv_status_bydev_req.lv->lv_block_exception, sizeof(void*)) != 0) - return -EFAULT; + if (copy_from_user + (&saved_ptr1, &lv_status_bydev_req.lv->lv_current_pe, + sizeof(void *)) != 0) + return -EFAULT; + if (copy_from_user + (&saved_ptr2, &lv_status_bydev_req.lv->lv_block_exception, + sizeof(void *)) != 0) + return -EFAULT; - if (copy_to_user(lv_status_bydev_req.lv, lv_ptr, sizeof(lv_t)) != 0) + if (copy_to_user(lv_status_bydev_req.lv, lv_ptr, sizeof(lv_t)) != + 0) return -EFAULT; if (saved_ptr1 != NULL) { if (copy_to_user(saved_ptr1, lv_ptr->lv_current_pe, lv_ptr->lv_allocated_le * - sizeof(pe_t)) != 0) + sizeof(pe_t)) != 0) return -EFAULT; } /* Restore usermode pointers */ - if (copy_to_user(&lv_status_bydev_req.lv->lv_current_pe, &saved_ptr1, sizeof(void *)) != 0) - return -EFAULT; + if (copy_to_user + (&lv_status_bydev_req.lv->lv_current_pe, &saved_ptr1, + sizeof(void *)) != 0) + return -EFAULT; return 0; -} /* lvm_do_lv_status_bydev() */ +} /* lvm_do_lv_status_bydev() */ /* * character device support function rename a logical volume */ -static int lvm_do_lv_rename(vg_t *vg_ptr, lv_req_t *lv_req, lv_t *lv) +static int lvm_do_lv_rename(vg_t * vg_ptr, lv_req_t * lv_req, lv_t * lv) { int l = 0; int ret = 0; @@ -2690,33 +2818,36 @@ if (!vg_ptr) return -ENXIO; - for (l = 0; l < vg_ptr->lv_max; l++) - { - if ( (lv_ptr = vg_ptr->lv[l]) == NULL) continue; - if (lv_ptr->lv_dev == lv->lv_dev) - { + for (l = 0; l < vg_ptr->lv_max; l++) { + if ((lv_ptr = vg_ptr->lv[l]) == NULL) + continue; + if (lv_ptr->lv_dev == lv->lv_dev) { lvm_fs_remove_lv(vg_ptr, lv_ptr); - strncpy(lv_ptr->lv_name, lv_req->lv_name, NAME_LEN); - lvm_fs_create_lv(vg_ptr, lv_ptr); + strncpy(lv_ptr->lv_name, lv_req->lv_name, + NAME_LEN); + lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].de = + lvm_fs_create_lv(vg_ptr, lv_ptr); break; } } - if (l == vg_ptr->lv_max) ret = -ENODEV; + if (l == vg_ptr->lv_max) + ret = -ENODEV; return ret; -} /* lvm_do_lv_rename */ +} /* lvm_do_lv_rename */ /* * character device support function physical volume change */ -static int lvm_do_pv_change(vg_t *vg_ptr, void *arg) +static int lvm_do_pv_change(vg_t * vg_ptr, void *arg) { uint p; pv_t *pv_ptr; struct block_device *bd; - if (vg_ptr == NULL) return -ENXIO; + if (vg_ptr == NULL) + return -ENXIO; if (copy_from_user(&pv_change_req, arg, sizeof(pv_change_req)) != 0) return -EFAULT; @@ -2724,8 +2855,7 @@ for (p = 0; p < vg_ptr->pv_max; p++) { pv_ptr = vg_ptr->pv[p]; if (pv_ptr != NULL && - strcmp(pv_ptr->pv_name, - pv_change_req.pv_name) == 0) { + strcmp(pv_ptr->pv_name, pv_change_req.pv_name) == 0) { bd = pv_ptr->bd; if (copy_from_user(pv_ptr, @@ -2741,17 +2871,18 @@ } } return -ENXIO; -} /* lvm_do_pv_change() */ +} /* lvm_do_pv_change() */ /* * character device support function get physical volume status */ -static int lvm_do_pv_status(vg_t *vg_ptr, void *arg) +static int lvm_do_pv_status(vg_t * vg_ptr, void *arg) { uint p; pv_t *pv_ptr; - if (vg_ptr == NULL) return -ENXIO; + if (vg_ptr == NULL) + return -ENXIO; if (copy_from_user(&pv_status_req, arg, sizeof(pv_status_req)) != 0) return -EFAULT; @@ -2759,17 +2890,15 @@ for (p = 0; p < vg_ptr->pv_max; p++) { pv_ptr = vg_ptr->pv[p]; if (pv_ptr != NULL && - strcmp(pv_ptr->pv_name, - pv_status_req.pv_name) == 0) { + strcmp(pv_ptr->pv_name, pv_status_req.pv_name) == 0) { if (copy_to_user(pv_status_req.pv, - pv_ptr, - sizeof(pv_t)) != 0) + pv_ptr, sizeof(pv_t)) != 0) return -EFAULT; return 0; } } return -ENXIO; -} /* lvm_do_pv_status() */ +} /* lvm_do_pv_status() */ /* @@ -2811,13 +2940,15 @@ hardsect_size[MAJOR_NR] = lvm_hardsectsizes; return; -} /* lvm_gen_init() */ +} /* lvm_gen_init() */ /* Must have down_write(_pe_lock) when we enqueue buffers */ -static void _queue_io(struct buffer_head *bh, int rw) { - if (bh->b_reqnext) BUG(); +static void _queue_io(struct buffer_head *bh, int rw) +{ + if (bh->b_reqnext) + BUG(); bh->b_reqnext = _pe_requests; _pe_requests = bh; } @@ -2855,14 +2986,15 @@ /* * we must open the pv's before we use them */ -static int _open_pv(pv_t *pv) { +static int _open_pv(pv_t * pv) +{ int err; struct block_device *bd; if (!(bd = bdget(kdev_t_to_nr(pv->pv_dev)))) return -ENOMEM; - err = blkdev_get(bd, FMODE_READ|FMODE_WRITE, 0, BDEV_FILE); + err = blkdev_get(bd, FMODE_READ | FMODE_WRITE, 0, BDEV_FILE); if (err) return err; @@ -2870,7 +3002,8 @@ return 0; } -static void _close_pv(pv_t *pv) { +static void _close_pv(pv_t * pv) +{ if (pv) { struct block_device *bdev = pv->bd; pv->bd = NULL; @@ -2882,7 +3015,7 @@ static unsigned long _sectors_to_k(unsigned long sect) { - if(SECTOR_SIZE > 1024) { + if (SECTOR_SIZE > 1024) { return sect * (SECTOR_SIZE / 1024); } Index: drivers/md/md.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/md/md.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/md/md.c 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/md/md.c 4 Aug 2004 01:29:02 -0000 1.2 @@ -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) Index: drivers/md/raid1.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/md/raid1.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/md/raid1.c 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/md/raid1.c 4 Aug 2004 01:29:02 -0000 1.2 @@ -487,6 +487,12 @@ goto rb_out; +#if defined(CONFIG_ALPHA) && ((__GNUC__ < 3) || \ + ((__GNUC__ == 3) && (__GNUC_MINOR__ < 3))) + /* Work around a compiler bug in older gcc */ + new_disk = *(volatile int *)&new_disk; +#endif + /* make sure that disk is operational */ while( !conf->mirrors[new_disk].operational) { if (new_disk <= 0) new_disk = conf->raid_disks; @@ -544,6 +550,11 @@ /* Find the disk which is closest */ +#if defined(CONFIG_ALPHA) && ((__GNUC__ < 3) || \ + ((__GNUC__ == 3) && (__GNUC_MINOR__ < 3))) + /* Work around a compiler bug in older gcc */ + disk = *(volatile int *)&disk; +#endif do { if (disk <= 0) disk = conf->raid_disks; @@ -1436,7 +1447,7 @@ block_nr = sector_nr; bsize = 512; while (!(block_nr & 1) && bsize < PAGE_SIZE - && (block_nr+2)*(bsize>>9) < (mddev->sb->size *2)) { + && (block_nr+2)*(bsize>>9) <= (mddev->sb->size *2)) { block_nr >>= 1; bsize <<= 1; } Index: drivers/md/raid5.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/md/raid5.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/md/raid5.c 22 Jul 2004 19:49:28 -0000 1.1 +++ drivers/md/raid5.c 4 Aug 2004 01:29:02 -0000 1.2 @@ -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); Index: drivers/media/radio/radio-gemtek-pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/radio/radio-gemtek-pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/radio/radio-gemtek-pci.c 22 Jul 2004 19:50:13 -0000 1.1 +++ drivers/media/radio/radio-gemtek-pci.c 4 Aug 2004 01:29:02 -0000 1.2 @@ -86,7 +86,7 @@ u8 mute; }; -static const char rcsid[] = "$Id: radio-gemtek-pci.c,v 1.1 2004/07/22 19:50:13 joff Exp $"; +static const char rcsid[] = "$Id: radio-gemtek-pci.c,v 1.2 2004/08/04 01:29:02 joff Exp $"; static int nr_radio = -1; Index: drivers/media/video/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/Config.in 22 Jul 2004 19:50:19 -0000 1.1 +++ drivers/media/video/Config.in 4 Aug 2004 01:29:02 -0000 1.2 @@ -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" -a "$CONFIG_I2C" != "n" ]; then + dep_tristate ' SGI VINO (EXPERIMENTAL)' CONFIG_VIDEO_VINO $CONFIG_VIDEO_DEV $CONFIG_I2C_ALGO_SGI fi dep_tristate ' Stradis 4:2:2 MPEG-2 video driver (EXPERIMENTAL)' CONFIG_VIDEO_STRADIS $CONFIG_VIDEO_DEV $CONFIG_PCI fi @@ -46,7 +49,7 @@ dep_tristate ' Miro DC10(+) support' CONFIG_VIDEO_ZORAN_DC10 $CONFIG_VIDEO_ZORAN $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C dep_tristate ' Linux Media Labs LML33 support' CONFIG_VIDEO_ZORAN_LML33 $CONFIG_VIDEO_ZORAN $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C dep_tristate ' Zoran ZR36120/36125 Video For Linux' CONFIG_VIDEO_ZR36120 $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then +if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_HIGHMEM64G" != "y" ]; then dep_tristate ' Sony Vaio Picturebook Motion Eye Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_MEYE $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_SONYPI fi # unfortunately, this depends on having CONFIG_FB_CYBER2000 Index: drivers/media/video/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/Makefile 22 Jul 2004 19:50:18 -0000 1.1 +++ drivers/media/video/Makefile 4 Aug 2004 01:29:02 -0000 1.2 @@ -16,7 +16,7 @@ obj-n := obj- := -SUB_DIRS := +SUB_DIRS := MOD_SUB_DIRS := $(SUB_DIRS) ALL_SUB_DIRS := $(SUB_DIRS) @@ -38,26 +38,26 @@ tda7432.o tda9875.o tda9887.o tuner.o obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o -obj-$(CONFIG_VIDEO_ZR36120) += zoran.o +obj-$(CONFIG_VIDEO_ZR36120) += zoran.o i2c-old.o obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o i2c-old.o -obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o i2c-old.o +obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o obj-$(CONFIG_VIDEO_W9966) += w9966.o obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o i2c-old.o obj-$(CONFIG_VIDEO_ZORAN_BUZ) += saa7111.o saa7185.o obj-$(CONFIG_VIDEO_ZORAN_DC10) += saa7110.o adv7175.o -obj-$(CONFIG_VIDEO_ZORAN_LML33) += bt819.o bt856.o obj-$(CONFIG_VIDEO_CYBERPRO) += cyberpro.o i2c-old.o saa7111.o obj-$(CONFIG_VIDEO_LML33) += bt856.o bt819.o obj-$(CONFIG_VIDEO_PMS) += pms.o obj-$(CONFIG_VIDEO_PLANB) += planb.o -obj-$(CONFIG_VIDEO_VINO) += vino.o -obj-$(CONFIG_VIDEO_STRADIS) += stradis.o +obj-$(CONFIG_VIDEO_VINO) += saa7191.o indycam.o vino.o +obj-$(CONFIG_VIDEO_STRADIS) += stradis.o i2c-old.o obj-$(CONFIG_VIDEO_CPIA) += cpia.o 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. @@ -81,8 +81,8 @@ fastdep: -zoran.o: zr36120.o zr36120_i2c.o zr36120_mem.o - $(LD) $(LD_RFLAG) -r -o $@ zr36120.o zr36120_i2c.o zr36120_mem.o +zoran.o: $(zoran-objs) + $(LD) $(LD_RFLAG) -r -o $@ $(zoran-objs) bttv.o: $(bttv-objs) $(LD) $(LD_RFLAG) -r -o $@ $(bttv-objs) Index: drivers/media/video/audiochip.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/audiochip.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/audiochip.h 22 Jul 2004 19:50:19 -0000 1.1 +++ drivers/media/video/audiochip.h 4 Aug 2004 01:29:02 -0000 1.2 @@ -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 */ Index: drivers/media/video/bttv-cards.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/bttv-cards.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/bttv-cards.c 22 Jul 2004 19:50:18 -0000 1.1 +++ drivers/media/video/bttv-cards.c 4 Aug 2004 01:29:02 -0000 1.2 @@ -21,22 +21,23 @@ You 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 +#ifdef CONFIG_FW_LOADER +# include +#endif #include #include "bttvp.h" -#include "tuner.h" #include "bt832.h" /* fwd decl */ @@ -61,6 +62,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); @@ -77,6 +79,7 @@ static unsigned int card[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET}; static unsigned int pll[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET}; static unsigned int tuner[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET}; +static unsigned int svhs[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET}; #ifdef MODULE static unsigned int autoload = 1; #else @@ -153,13 +156,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 +173,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 +203,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 +240,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 +348,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 +655,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 +763,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 +947,7 @@ /* ---- card 0x34 ---------------------------------- */ /* David Härdeman */ .name = "Pinnacle PCTV Studio Pro", - .video_inputs = 3, + .video_inputs = 4, .audio_inputs = 1, .tuner = 0, .svhs = 3, @@ -1190,7 +1216,7 @@ .tuner_type = -1, .pll = PLL_28, .muxsel = { 2 }, - gpiomask: 0 + .gpiomask = 0 },{ /* Tomasz Pyra */ .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)", @@ -1277,7 +1303,7 @@ },{ .name = "Powercolor MTV878/ MTV878R/ MTV878F", .video_inputs = 3, - audio_inputs: 2, + .audio_inputs = 2, .tuner = 0, .svhs = 2, .gpiomask = 0x1C800F, // Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset @@ -1317,7 +1343,7 @@ },{ .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF", .video_inputs = 4, - audio_inputs: 3, + .audio_inputs = 3, .tuner = 0, .svhs = 2, .gpiomask = 7, @@ -1367,18 +1393,19 @@ .gpiomask = 7, .audiomux = {7}, },{ - .name = "GV-BCTV5/PCI", + .name = "IODATA GV-BCTV5/PCI", .video_inputs = 3, .audio_inputs = 1, .tuner = 0, .svhs = 2, - .gpiomask = 0x010f00, + .gpiomask = 0x0f0f80, .muxsel = {2, 3, 1, 0}, - .audiomux = {0x10000, 0, 0x10000, 0, 0, 0}, + .audiomux = {0x030000, 0x010000, 0x030000, 0, 0x020000, 0}, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC_M, .audio_hook = gvbctv3pci_audio, + .has_radio = 1, },{ .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */ .video_inputs = 4, /* id-inputs-clock */ @@ -1548,11 +1575,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 +1600,8 @@ not soldered here, though unknown wiring. Card lacks: external audio in, pci subsystem id. */ - },{ + /* ---- card 0x60 ---------------------------------- */ .name = "MachTV", .video_inputs = 3, @@ -1621,17 +1650,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 +1841,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"); } @@ -1679,12 +1859,8 @@ btv->type=card[btv->nr]; /* print which card config we are using */ - sprintf(btv->video_dev.name,"BT%d%s(%.23s)", - btv->id, - (btv->id==848 && btv->revision==0x12) ? "A" : "", - bttv_tvcards[btv->type].name); printk(KERN_INFO "bttv%d: using: %s [card=%d,%s]\n",btv->nr, - btv->video_dev.name,btv->type, + bttv_tvcards[btv->type].name, btv->type, card[btv->nr] < bttv_num_tvcards ? "insmod option" : "autodetected"); @@ -2095,6 +2271,9 @@ &btv->pinnacle_id); if (btv->tuner_type != UNSET) bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type); + btv->svhs = bttv_tvcards[btv->type].svhs; + if (svhs[btv->nr] != UNSET) + btv->svhs = svhs[btv->nr]; if (bttv_tvcards[btv->type].has_radio) btv->has_radio=1; @@ -2241,7 +2420,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 +2472,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 +2516,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 +2533,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 +2547,27 @@ 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; + int rc; + + rc = request_firmware(&fw_entry, "hcwamc.rbf", pci_name(btv->dev)); + if (rc != 0) { + printk(KERN_WARNING "bttv%d: no altera firmware [via hotplug]\n", + btv->nr); + return rc; + } + rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size); + printk(KERN_INFO "bttv%d: altera firmware upload %s\n", + btv->nr, (rc < 0) ? "failed" : "ok"); + release_firmware(fw_entry); + return rc; +} +#endif /* ----------------------------------------------------------------------- */ /* some osprey specific stuff */ @@ -2495,12 +2700,12 @@ static void __devinit avermedia_eeprom(struct bttv *btv) { - int tuner_make,tuner_tv_fm,tuner_format,tuner=0,remote; + int tuner_make,tuner_tv_fm,tuner_format,tuner=0; - tuner_make = (eeprom_data[0x41] & 0x7); - tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3; - tuner_format = (eeprom_data[0x42] & 0xf0) >> 4; - remote = (eeprom_data[0x42] & 0x01); + tuner_make = (eeprom_data[0x41] & 0x7); + tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3; + tuner_format = (eeprom_data[0x42] & 0xf0) >> 4; + btv->has_remote = (eeprom_data[0x42] & 0x01); if (tuner_make == 0 || tuner_make == 2) if(tuner_format <=9) @@ -2517,8 +2722,8 @@ } else printk("Unknown type"); printk(" radio:%s remote control:%s\n", - tuner_tv_fm?"yes":"no", - remote?"yes":"no"); + tuner_tv_fm ? "yes" : "no", + btv->has_remote ? "yes" : "no"); } /* used on Voodoo TV/FM (Voodoo 200), S0 wired to 0x10000 */ @@ -2613,7 +2818,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 +2838,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 +2850,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 +2969,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 +3423,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 */ @@ -3216,9 +3471,11 @@ latency = 0x0A; #endif +#if 0 /* print which chipset we have */ while ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8,dev))) - printk(KERN_INFO "bttv: Host bridge is %s\n",dev->name); + printk(KERN_INFO "bttv: Host bridge is %s\n",pci_name(dev)); +#endif /* print warnings about any quirks found */ if (triton1) Index: drivers/media/video/bttv-driver.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/bttv-driver.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/bttv-driver.c 22 Jul 2004 19:50:19 -0000 1.1 +++ drivers/media/video/bttv-driver.c 4 Aug 2004 01:29:02 -0000 1.2 @@ -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; @@ -400,13 +400,10 @@ #endif input %= bttv_tvcards[btv->type].video_inputs; - if (input==bttv_tvcards[btv->type].svhs) - { + if (input == btv->svhs) { btor(BT848_CONTROL_COMP, BT848_E_CONTROL); btor(BT848_CONTROL_COMP, BT848_O_CONTROL); - } - else - { + } else { btand(~BT848_CONTROL_COMP, BT848_E_CONTROL); btand(~BT848_CONTROL_COMP, BT848_O_CONTROL); } @@ -609,7 +606,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 +731,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 +773,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 +1052,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); @@ -1667,7 +1665,7 @@ v.type=VIDEO_TYPE_TV; v.tuners=1; } - else if (channel==bttv_tvcards[btv->type].svhs) + else if (channel == btv->svhs) strcpy(v.name,"S-Video"); else if (bttv_tvcards[btv->type].muxsel[v.channel] < 0) strcpy(v.name,"Digital Video"); @@ -1756,6 +1754,7 @@ case VIDIOCSPICT: { struct video_picture p; + if (copy_from_user(&p, arg,sizeof(p))) return -EFAULT; if (p.palette > PALETTEFMT_MAX) @@ -2198,7 +2197,7 @@ static struct video_device bttv_template= { .owner = THIS_MODULE, - .name = "UNSET", + .name = "bttv video", .type = VID_TYPE_TUNER|VID_TYPE_CAPTURE|VID_TYPE_OVERLAY|VID_TYPE_TELETEXT, .hardware = VID_HARDWARE_BT848, .open = bttv_open, @@ -2367,7 +2366,6 @@ static int radio_open(struct video_device *dev, int flags) { struct bttv *btv = (struct bttv *)(dev-1); - unsigned long v; down(&btv->lock); if (btv->user) @@ -2375,8 +2373,6 @@ btv->user++; btv->radio = 1; - v = 400*16; - bttv_call_i2c_clients(btv,VIDIOCSFREQ,&v); bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type); bt848_muxsel(btv,0); up(&btv->lock); @@ -2737,10 +2733,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 +2816,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)) @@ -3150,7 +3147,7 @@ return result; } -static struct pci_device_id bttv_pci_tbl[] __devinitdata = { +static struct pci_device_id bttv_pci_tbl[] = { {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849, @@ -3173,6 +3170,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 +3187,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) Index: drivers/media/video/bttv-if.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/bttv-if.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/bttv-if.c 22 Jul 2004 19:50:19 -0000 1.1 +++ drivers/media/video/bttv-if.c 4 Aug 2004 01:29:02 -0000 1.2 @@ -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; @@ -194,6 +190,7 @@ return state; } +#ifndef I2C_PEC static void bttv_inc_use(struct i2c_adapter *adap) { MOD_INC_USE_COUNT; @@ -203,10 +200,11 @@ { MOD_DEC_USE_COUNT; } +#endif 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 +214,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) @@ -252,16 +243,23 @@ }; static struct i2c_adapter bttv_i2c_adap_template = { +#ifdef I2C_PEC + .owner = THIS_MODULE, +#else .inc_use = bttv_inc_use, .dec_use = bttv_dec_use, - .name = "bt848", +#endif +#ifdef I2C_ADAP_CLASS_TV_ANALOG + .class = I2C_ADAP_CLASS_TV_ANALOG, +#endif + 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 +333,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; Index: drivers/media/video/bttv.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/bttv.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/bttv.h 22 Jul 2004 19:50:18 -0000 1.1 +++ drivers/media/video/bttv.h 4 Aug 2004 01:29:02 -0000 1.2 @@ -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); Index: drivers/media/video/bttvp.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/bttvp.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/bttvp.h 22 Jul 2004 19:50:19 -0000 1.1 +++ drivers/media/video/bttvp.h 4 Aug 2004 01:29:02 -0000 1.2 @@ -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,108) #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]; @@ -129,6 +131,7 @@ unsigned int tuner_type; unsigned int pinnacle_id; unsigned int channel; + unsigned int svhs; unsigned int nr; unsigned short id; @@ -148,6 +151,7 @@ int audio_chip; /* set to one of the chips supported by bttv.c */ int radio; int has_radio; + int has_remote; /* miro/pinnacle + Aimslab VHX philips matchbox (tea5757 radio tuner) support */ Index: drivers/media/video/cpia.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/cpia.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/cpia.c 22 Jul 2004 19:50:18 -0000 1.1 +++ drivers/media/video/cpia.c 4 Aug 2004 01:29:03 -0000 1.2 @@ -1683,13 +1683,9 @@ * values. - rich@annexia.org */ if (cam->params.exposure.redComp < 220 || - cam->params.exposure.redComp > 255 || cam->params.exposure.green1Comp < 214 || - cam->params.exposure.green1Comp > 255 || cam->params.exposure.green2Comp < 214 || - cam->params.exposure.green2Comp > 255 || - cam->params.exposure.blueComp < 230 || - cam->params.exposure.blueComp > 255) + cam->params.exposure.blueComp < 230) { printk (KERN_WARNING "*_comp parameters have gone AWOL (%d/%d/%d/%d) - reseting them\n", cam->params.exposure.redComp, Index: drivers/media/video/cpia.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/cpia.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/cpia.h 22 Jul 2004 19:50:18 -0000 1.1 +++ drivers/media/video/cpia.h 4 Aug 2004 01:29:03 -0000 1.2 @@ -393,12 +393,14 @@ /* ErrorCode */ #define ERROR_FLICKER_BELOW_MIN_EXP 0x01 /*flicker exposure got below minimum exposure */ -#define ALOG(lineno,fmt,args...) printk(fmt,lineno,##args) -#define LOG(fmt,args...) ALOG((__LINE__),KERN_INFO __FILE__":"__FUNCTION__"(%d):"fmt,##args) +#define ALOG(function,lineno,fmt,args...) printk(fmt, function, lineno, ##args) +#define LOG(fmt,args...) ALOG((__FUNCTION__), (__LINE__), \ + KERN_INFO __FILE__":%s(%d):"fmt, ##args) #ifdef _CPIA_DEBUG_ -#define ADBG(lineno,fmt,args...) printk(fmt, jiffies, lineno, ##args) -#define DBG(fmt,args...) ADBG((__LINE__),KERN_DEBUG __FILE__"(%ld):"__FUNCTION__"(%d):"fmt,##args) +#define ADBG(function,lineno,fmt,args...) printk(fmt, jiffies, function, lineno, ##args) +#define DBG(fmt,args...) ADBG((__FUNCTION__), (__LINE__), \ + KERN_DEBUG __FILE__"(%ld):%s(%d):"fmt, ##args) #else #define DBG(fmn,args...) do {} while(0) #endif Index: drivers/media/video/cpia_pp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/cpia_pp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/cpia_pp.c 22 Jul 2004 19:50:18 -0000 1.1 +++ drivers/media/video/cpia_pp.c 4 Aug 2004 01:29:03 -0000 1.2 @@ -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) { Index: drivers/media/video/i2c-old.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/i2c-old.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/i2c-old.c 22 Jul 2004 19:50:19 -0000 1.1 +++ drivers/media/video/i2c-old.c 4 Aug 2004 01:29:03 -0000 1.2 @@ -45,17 +45,11 @@ { printk(KERN_INFO "i2c: initialized%s\n", scan ? " (i2c bus scan enabled)" : ""); - /* anything to do here ? */ -#if defined(CONFIG_VIDEO_BUZ) || defined(CONFIG_VIDEO_CYBERPRO) + +#if defined(CONFIG_VIDEO_CYBERPRO) saa7111_init(); #endif -#ifdef CONFIG_VIDEO_BUZ - saa7185_init(); -#endif -#ifdef CONFIG_VIDEO_LML33 - bt819_init(); - bt856_init(); -#endif + return 0; } @@ -67,10 +61,10 @@ int i,j,ack=1; unsigned char addr; LOCK_FLAGS; - + /* probe for device */ LOCK_I2C_BUS(bus); - for (addr = driver->addr_l; addr <= driver->addr_h; addr += 2) + for (addr = driver->addr_l; addr <= driver->addr_h; addr += 2) { i2c_start(bus); ack = i2c_sendbyte(bus,addr,0); @@ -102,8 +96,8 @@ device->addr = addr; /* Attach */ - - if (driver->attach(device)!=0) + + if (driver->attach(device)!=0) { kfree(device); return; @@ -129,7 +123,7 @@ for (i = 0; i < I2C_DEVICE_MAX; i++) if (device == device->driver->devices[i]) break; - if (I2C_DEVICE_MAX == i) + if (I2C_DEVICE_MAX == i) { printk(KERN_WARNING "i2c: detach_device #1: device not found: %s\n", device->name); @@ -141,7 +135,7 @@ for (i = 0; i < I2C_DEVICE_MAX; i++) if (device == device->bus->devices[i]) break; - if (I2C_DEVICE_MAX == i) + if (I2C_DEVICE_MAX == i) { printk(KERN_WARNING "i2c: detach_device #2: device not found: %s\n", device->name); @@ -173,19 +167,19 @@ busses[i] = bus; bus_count++; REGPRINT(printk("i2c: bus registered: %s\n",bus->name)); - + MOD_INC_USE_COUNT; - if (scan) + if (scan) { /* scan whole i2c bus */ LOCK_I2C_BUS(bus); - for (i = 0; i < 256; i+=2) + for (i = 0; i < 256; i+=2) { i2c_start(bus); ack = i2c_sendbyte(bus,i,0); i2c_stop(bus); - if (!ack) + if (!ack) { printk(KERN_INFO "i2c: scanning bus %s: found device at addr=0x%02x\n", bus->name,i); @@ -213,20 +207,20 @@ for (i = 0; i < I2C_BUS_MAX; i++) if (bus == busses[i]) break; - if (I2C_BUS_MAX == i) + if (I2C_BUS_MAX == i) { printk(KERN_WARNING "i2c: unregister_bus #1: bus not found: %s\n", bus->name); return -ENODEV; } - + MOD_DEC_USE_COUNT; - + busses[i] = NULL; bus_count--; REGPRINT(printk("i2c: bus unregistered: %s\n",bus->name)); - return 0; + return 0; } /* ----------------------------------------------------------------------- */ @@ -246,9 +240,9 @@ drivers[i] = driver; driver_count++; - + MOD_INC_USE_COUNT; - + REGPRINT(printk("i2c: driver registered: %s\n",driver->name)); /* Probe available busses */ @@ -271,7 +265,7 @@ for (i = 0; i < I2C_DRIVER_MAX; i++) if (driver == drivers[i]) break; - if (I2C_DRIVER_MAX == i) + if (I2C_DRIVER_MAX == i) { printk(KERN_WARNING "i2c: unregister_driver: driver not found: %s\n", driver->name); @@ -279,7 +273,7 @@ } MOD_DEC_USE_COUNT; - + drivers[i] = NULL; driver_count--; REGPRINT(printk("i2c: driver unregistered: %s\n",driver->name)); @@ -343,7 +337,7 @@ int i2c_ack(struct i2c_bus *bus) { int ack; - + I2C_SET(bus,0,1); I2C_SET(bus,1,1); ack = I2C_GET(bus); @@ -354,7 +348,7 @@ int i2c_sendbyte(struct i2c_bus *bus,unsigned char data,int wait_for_ack) { int i, ack; - + I2C_SET(bus,0,0); for (i=7; i>=0; i--) (data&(1<=0; i--) + for (i=7; i>=0; i--) { I2C_SET(bus,1,1); if (I2C_GET(bus)) @@ -388,7 +382,7 @@ int i2c_read(struct i2c_bus *bus, unsigned char addr) { int ret; - + if (bus->i2c_read) return bus->i2c_read(bus, addr); Index: drivers/media/video/id.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/id.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/id.h 22 Jul 2004 19:50:18 -0000 1.1 +++ drivers/media/video/id.h 4 Aug 2004 01:29:03 -0000 1.2 @@ -27,6 +27,9 @@ #ifndef I2C_DRIVERID_TDA9874 # define I2C_DRIVERID_TDA9874 I2C_DRIVERID_EXP0+7 #endif +#ifndef I2C_DRIVERID_SAA6752HS +# define I2C_DRIVERID_SAA6752HS I2C_DRIVERID_EXP0+8 +#endif /* algorithms */ #ifndef I2C_ALGO_SAA7134 Index: drivers/media/video/meye.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/meye.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/meye.c 22 Jul 2004 19:50:19 -0000 1.1 +++ drivers/media/video/meye.c 4 Aug 2004 01:29:03 -0000 1.2 @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -139,7 +138,7 @@ memset(mem, 0, size); /* Clear the ram out, no junk to the user */ adr = (unsigned long)mem; while (size > 0) { - mem_map_reserve(vmalloc_to_page((void *)adr)); + SetPageReserved(vmalloc_to_page((void *)adr)); adr += PAGE_SIZE; size -= PAGE_SIZE; } @@ -153,7 +152,7 @@ if (mem) { adr = (unsigned long) mem; while ((long) size > 0) { - mem_map_unreserve(vmalloc_to_page((void *)adr)); + ClearPageReserved(vmalloc_to_page((void *)adr)); adr += PAGE_SIZE; size -= PAGE_SIZE; } @@ -161,35 +160,78 @@ } } -/* return a page table pointing to N pages of locked memory */ +/****************************************************************************/ +/* 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 + * + * NOTE: The meye device expects dma_addr_t size to be 32 bits + * (the toc must be exactly 1024 entries each of them being 4 bytes + * in size, the whole result being 4096 bytes). We're using here + * dma_addr_t for correctness but the compilation of this driver is + * disabled for HIGHMEM64G=y, where sizeof(dma_addr_t) != 4 + */ static int ptable_alloc(void) { - u32 *pt; + dma_addr_t *pt; int i; 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); - if (!meye.mchip_ptable[MCHIP_NB_PAGES]) { + meye.mchip_ptable_toc = dma_alloc_coherent(meye.mchip_dev, + PAGE_SIZE, + &meye.mchip_dmahandle, + GFP_KERNEL); + if (!meye.mchip_ptable_toc) { meye.mchip_dmahandle = 0; return -1; } - pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES]; + pt = meye.mchip_ptable_toc; 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]; + pt = meye.mchip_ptable_toc; 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++; } + dma_free_coherent(meye.mchip_dev, + PAGE_SIZE, + meye.mchip_ptable_toc, + meye.mchip_dmahandle); + meye.mchip_ptable_toc = 0; meye.mchip_dmahandle = 0; return -1; } @@ -199,25 +241,26 @@ } static void ptable_free(void) { - u32 *pt; + dma_addr_t *pt; int i; - pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES]; + pt = meye.mchip_ptable_toc; 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); + if (meye.mchip_ptable_toc) + dma_free_coherent(meye.mchip_dev, + PAGE_SIZE, + meye.mchip_ptable_toc, + meye.mchip_dmahandle); memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable)); + meye.mchip_ptable_toc = 0; meye.mchip_dmahandle = 0; } @@ -614,25 +657,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"); } /****************************************************************************/ @@ -833,7 +876,7 @@ /* Interrupt handling */ /****************************************************************************/ -static void meye_irq(int irq, void *dev_id, struct pt_regs *regs) { +static irqreturn_t meye_irq(int irq, void *dev_id, struct pt_regs *regs) { u32 v; int reqnr; v = mchip_read(MCHIP_MM_INTA); @@ -841,7 +884,7 @@ while (1) { v = mchip_get_frame(); if (!(v & MCHIP_MM_FIR_RDY)) - return; + return IRQ_NONE; switch (meye.mchip_mode) { case MCHIP_HIC_MODE_CONT_OUT: @@ -874,11 +917,12 @@ default: /* do not free frame, since it can be a snap */ - return; + return IRQ_NONE; } /* switch */ mchip_free_frame(); } + return IRQ_HANDLED; } /****************************************************************************/ @@ -918,7 +962,7 @@ case VIDIOCGCAP: { struct video_capability *b = arg; - strcpy(b->name,meye.video_dev.name); + strcpy(b->name,meye.video_dev->name); b->type = VID_TYPE_CAPTURE; b->channels = 1; b->audios = 0; @@ -1223,6 +1267,8 @@ .type = VID_TYPE_CAPTURE, .hardware = VID_HARDWARE_MEYE, .fops = &meye_fops, + .release = video_device_release, + .minor = -1, }; #ifdef CONFIG_PM @@ -1273,10 +1319,16 @@ goto out1; } - sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 1); - meye.mchip_dev = pcidev; - memcpy(&meye.video_dev, &meye_template, sizeof(meye_template)); + meye.video_dev = video_device_alloc(); + if (!meye.video_dev) { + printk(KERN_ERR "meye: video_device_alloc() failed!\n"); + ret = -EBUSY; + goto out1; + } + memcpy(meye.video_dev, &meye_template, sizeof(meye_template)); + + sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 1); if ((ret = pci_enable_device(meye.mchip_dev))) { printk(KERN_ERR "meye: pci_enable_device failed\n"); @@ -1333,7 +1385,7 @@ wait_ms(1); mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK); - if (video_register_device(&meye.video_dev, VFL_TYPE_GRABBER, video_nr) < 0) { + if (video_register_device(meye.video_dev, VFL_TYPE_GRABBER, video_nr) < 0) { printk(KERN_ERR "meye: video_register_device failed\n"); ret = -EIO; @@ -1381,6 +1433,9 @@ out3: pci_disable_device(meye.mchip_dev); out2: + video_device_release(meye.video_dev); + meye.video_dev = NULL; + sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 0); out1: return ret; @@ -1388,10 +1443,12 @@ static void __devexit meye_remove(struct pci_dev *pcidev) { - video_unregister_device(&meye.video_dev); + video_unregister_device(meye.video_dev); mchip_hic_stop(); + mchip_dma_free(); + /* disable interrupts */ mchip_set(MCHIP_MM_INTA, 0x0); @@ -1404,8 +1461,6 @@ pci_disable_device(meye.mchip_dev); - mchip_dma_free(); - if (meye.grab_fbuffer) rvfree(meye.grab_fbuffer, gbuffers*gbufsize); @@ -1414,7 +1469,7 @@ printk(KERN_INFO "meye: removed\n"); } -static struct pci_device_id meye_pci_tbl[] __devinitdata = { +static struct pci_device_id meye_pci_tbl[] = { { PCI_VENDOR_ID_KAWASAKI, PCI_DEVICE_ID_MCHIP_KL5A72002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { } @@ -1474,8 +1529,6 @@ MODULE_DESCRIPTION("video4linux driver for the MotionEye camera"); MODULE_LICENSE("GPL"); -EXPORT_NO_SYMBOLS; - MODULE_PARM(gbuffers,"i"); MODULE_PARM_DESC(gbuffers,"number of capture buffers, default is 2 (32 max)"); MODULE_PARM(gbufsize,"i"); Index: drivers/media/video/meye.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/meye.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/meye.h 22 Jul 2004 19:50:19 -0000 1.1 +++ drivers/media/video/meye.h 4 Aug 2004 01:29:03 -0000 1.2 @@ -31,13 +31,11 @@ #define _MEYE_PRIV_H_ #define MEYE_DRIVER_MAJORVERSION 1 -#define MEYE_DRIVER_MINORVERSION 6 +#define MEYE_DRIVER_MINORVERSION 9 #include #include #include -#include -#include /****************************************************************************/ /* Motion JPEG chip registers */ @@ -300,7 +298,8 @@ u8 mchip_fnum; /* current mchip frame number */ unsigned char *mchip_mmregs; /* mchip: memory mapped registers */ - u8 *mchip_ptable[MCHIP_NB_PAGES+1];/* mchip: ptable + ptable toc */ + u8 *mchip_ptable[MCHIP_NB_PAGES];/* mchip: ptable */ + dma_addr_t *mchip_ptable_toc; /* mchip: ptable toc */ dma_addr_t mchip_dmahandle; /* mchip: dma handle to ptable toc */ unsigned char *grab_fbuffer; /* capture framebuffer */ @@ -312,7 +311,7 @@ struct meye_queue grabq; /* queue for buffers to be grabbed */ - struct video_device video_dev; /* video device parameters */ + struct video_device *video_dev; /* video device parameters */ struct video_picture picture; /* video picture parameters */ struct meye_params params; /* additional parameters */ #ifdef CONFIG_PM Index: drivers/media/video/msp3400.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/msp3400.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/msp3400.c 22 Jul 2004 19:50:19 -0000 1.1 +++ drivers/media/video/msp3400.c 4 Aug 2004 01:29:03 -0000 1.2 @@ -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 */ @@ -1414,14 +1405,19 @@ static int msp_probe(struct i2c_adapter *adap) { +#ifdef I2C_ADAP_CLASS_TV_ANALOG + if (adap->class & I2C_ADAP_CLASS_TV_ANALOG) + return i2c_probe(adap, &addr_data, msp_attach); +#else if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) return i2c_probe(adap, &addr_data, msp_attach); +#endif return 0; } 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 +1429,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 +1501,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 +1533,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 +1555,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 +1568,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; } Index: drivers/media/video/planb.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/planb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/planb.c 22 Jul 2004 19:50:19 -0000 1.1 +++ drivers/media/video/planb.c 4 Aug 2004 01:29:03 -0000 1.2 @@ -28,7 +28,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: planb.c,v 1.1 2004/07/22 19:50:19 joff Exp $ */ +/* $Id: planb.c,v 1.2 2004/08/04 01:29:03 joff Exp $ */ #include #include Index: drivers/media/video/planb.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/planb.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/planb.h 22 Jul 2004 19:50:19 -0000 1.1 +++ drivers/media/video/planb.h 4 Aug 2004 01:29:03 -0000 1.2 @@ -28,7 +28,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: planb.h,v 1.1 2004/07/22 19:50:19 joff Exp $ */ +/* $Id: planb.h,v 1.2 2004/08/04 01:29:03 joff Exp $ */ #ifndef _PLANB_H_ #define _PLANB_H_ Index: drivers/media/video/saa5249.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/saa5249.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/saa5249.c 22 Jul 2004 19:50:18 -0000 1.1 +++ drivers/media/video/saa5249.c 4 Aug 2004 01:29:03 -0000 1.2 @@ -12,7 +12,7 @@ * * Copyright (c) 1998 Richard Guenther * - * $Id: saa5249.c,v 1.1 2004/07/22 19:50:18 joff Exp $ + * $Id: saa5249.c,v 1.2 2004/08/04 01:29:03 joff Exp $ * * Derived From * Index: drivers/media/video/saa7110.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/saa7110.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/saa7110.c 22 Jul 2004 19:50:18 -0000 1.1 +++ drivers/media/video/saa7110.c 4 Aug 2004 01:29:03 -0000 1.2 @@ -392,7 +392,7 @@ break; default: - DEBUG(printk(KERN_INFO "unknown saa7110_command??(%d)\n",cmd)); + DEBUG(printk(KERN_INFO "unknown saa7110_command?(%d)\n",cmd)); return -EINVAL; } return 0; @@ -404,7 +404,7 @@ { "saa7110", /* name */ - I2C_DRIVERID_VIDEODECODER, /* in i2c.h */ + I2C_DRIVERID_VIDEODECODER, /* in i2c-old.h */ I2C_SAA7110, I2C_SAA7110+1, /* Addr range */ saa7110_attach, Index: drivers/media/video/saa7146.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/saa7146.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/saa7146.h 22 Jul 2004 19:50:18 -0000 1.1 +++ drivers/media/video/saa7146.h 4 Aug 2004 01:29:03 -0000 1.2 @@ -25,7 +25,7 @@ #include #include -#include +#include #include #ifndef O_NONCAP Index: drivers/media/video/saa7196.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/saa7196.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/saa7196.h 22 Jul 2004 19:50:18 -0000 1.1 +++ drivers/media/video/saa7196.h 4 Aug 2004 01:29:03 -0000 1.2 @@ -13,7 +13,7 @@ The default values used for PlanB are my mistakes. */ -/* $Id: saa7196.h,v 1.1 2004/07/22 19:50:18 joff Exp $ */ +/* $Id: saa7196.h,v 1.2 2004/08/04 01:29:03 joff Exp $ */ #ifndef _SAA7196_H_ #define _SAA7196_H_ Index: drivers/media/video/tda7432.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/tda7432.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/tda7432.c 22 Jul 2004 19:50:19 -0000 1.1 +++ drivers/media/video/tda7432.c 4 Aug 2004 01:29:03 -0000 1.2 @@ -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); @@ -341,14 +341,19 @@ static int tda7432_probe(struct i2c_adapter *adap) { +#ifdef I2C_ADAP_CLASS_TV_ANALOG + if (adap->class & I2C_ADAP_CLASS_TV_ANALOG) + return i2c_probe(adap, &addr_data, tda7432_attach); +#else if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) return i2c_probe(adap, &addr_data, tda7432_attach); +#endif return 0; } 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 +366,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 +530,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) Index: drivers/media/video/tda9875.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/tda9875.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/tda9875.c 22 Jul 2004 19:50:19 -0000 1.1 +++ drivers/media/video/tda9875.c 4 Aug 2004 01:29:03 -0000 1.2 @@ -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); @@ -274,14 +275,19 @@ static int tda9875_probe(struct i2c_adapter *adap) { +#ifdef I2C_ADAP_CLASS_TV_ANALOG + if (adap->class & I2C_ADAP_CLASS_TV_ANALOG) + return i2c_probe(adap, &addr_data, tda9875_attach); +#else if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) return i2c_probe(adap, &addr_data, tda9875_attach); +#endif return 0; } 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 +300,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 +322,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 +340,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 +401,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) Index: drivers/media/video/tda9887.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/tda9887.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/tda9887.c 22 Jul 2004 19:50:19 -0000 1.1 +++ drivers/media/video/tda9887.c 4 Aug 2004 01:29:03 -0000 1.2 @@ -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,24 @@ static int tda9887_probe(struct i2c_adapter *adap) { - int rc; - +#ifdef I2C_ADAP_CLASS_TV_ANALOG + if (adap->class & I2C_ADAP_CLASS_TV_ANALOG) + return i2c_probe(adap, &addr_data, tda9887_attach); +#else 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; +#endif + 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 +397,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 +452,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) Index: drivers/media/video/tuner.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/tuner.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/tuner.c 22 Jul 2004 19:50:19 -0000 1.1 +++ drivers/media/video/tuner.c 4 Aug 2004 01:29:03 -0000 1.2 @@ -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,31 @@ 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; + +#ifdef I2C_ADAP_CLASS_TV_ANALOG + if (adap->class & I2C_ADAP_CLASS_TV_ANALOG) + return i2c_probe(adap, &addr_data, tuner_attach); +#else 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; +#endif + 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 +877,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,12 +893,15 @@ 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; case AUDC_SET_RADIO: - t->radio = 1; + if (!t->radio) { + set_tv_freq(client,400 * 16); + t->radio = 1; + } break; case AUDC_CONFIG_PINNACLE: switch (*iarg) { @@ -970,9 +980,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) Index: drivers/media/video/tuner.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/tuner.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/tuner.h 22 Jul 2004 19:50:19 -0000 1.1 +++ drivers/media/video/tuner.h 4 Aug 2004 01:29:03 -0000 1.2 @@ -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 */ Index: drivers/media/video/tvaudio.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/tvaudio.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/tvaudio.c 22 Jul 2004 19:50:18 -0000 1.1 +++ drivers/media/video/tvaudio.c 4 Aug 2004 01:29:03 -0000 1.2 @@ -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); } @@ -1410,19 +1507,23 @@ static int chip_probe(struct i2c_adapter *adap) { +#ifdef I2C_ADAP_CLASS_TV_ANALOG + if (adap->class & I2C_ADAP_CLASS_TV_ANALOG) + return i2c_probe(adap, &addr_data, chip_attach); +#else 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; } +#endif + 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 +1549,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 +1580,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 +1603,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 +1659,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) Index: drivers/media/video/tvaudio.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/tvaudio.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/tvaudio.h 22 Jul 2004 19:50:18 -0000 1.1 +++ drivers/media/video/tvaudio.h 4 Aug 2004 01:29:03 -0000 1.2 @@ -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 */ Index: drivers/media/video/tvmixer.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/tvmixer.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/tvmixer.c 22 Jul 2004 19:50:18 -0000 1.1 +++ drivers/media/video/tvmixer.c 4 Aug 2004 01:29:03 -0000 1.2 @@ -10,21 +10,19 @@ #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 iminor(inode) minor(inode->i_rdev) #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 +86,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 +95,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 +134,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; @@ -178,7 +176,7 @@ static int tvmixer_open(struct inode *inode, struct file *file) { - int i, minor = minor(inode->i_rdev); + int i, minor = iminor(inode); struct TVMIXER *mix = NULL; struct i2c_client *client = NULL; @@ -195,8 +193,10 @@ /* lock bttv in memory while the mixer is in use */ file->private_data = mix; +#ifndef I2C_PEC if (client->adapter->inc_use) client->adapter->inc_use(client->adapter); +#endif return 0; } @@ -210,15 +210,25 @@ return -ENODEV; } +#ifndef I2C_PEC if (client->adapter->dec_use) client->adapter->dec_use(client->adapter); +#endif return 0; } static struct i2c_driver driver = { +#ifdef I2C_PEC + .owner = THIS_MODULE, +#endif .name = "tv card mixer driver", .id = I2C_DRIVERID_TVMIXER, +#ifdef I2C_DF_DUMMY .flags = I2C_DF_DUMMY, +#else + .flags = I2C_DF_NOTIFY, + .detach_adapter = tvmixer_adapters, +#endif .attach_adapter = tvmixer_adapters, .detach_client = tvmixer_clients, }; @@ -237,8 +247,6 @@ { int i; - if (debug) - printk("tvmixer: adapter %s\n",adap->name); for (i=0; iclients[i]) continue; @@ -252,6 +260,10 @@ struct video_audio va; int i,minor; +#ifdef I2C_ADAP_CLASS_TV_ANALOG + if (!(client->adapter->class & I2C_ADAP_CLASS_TV_ANALOG)) + return -1; +#else /* TV card ??? */ switch (client->adapter->id) { case I2C_ALGO_BIT | I2C_HW_B_BT848: @@ -260,12 +272,9 @@ 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); +#endif /* unregister ?? */ for (i = 0; i < DEV_MAX; i++) { @@ -274,7 +283,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 +299,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 +343,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)); } } } Index: drivers/media/video/videodev.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/videodev.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/videodev.c 22 Jul 2004 19:50:19 -0000 1.1 +++ drivers/media/video/videodev.c 4 Aug 2004 01:29:03 -0000 1.2 @@ -62,6 +62,20 @@ #endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */ +struct video_device *video_device_alloc(void) +{ + struct video_device *vfd; + vfd = kmalloc(sizeof(*vfd),GFP_KERNEL); + if (NULL == vfd) + return NULL; + memset(vfd,0,sizeof(*vfd)); + return vfd; +} + +void video_device_release(struct video_device *vfd) +{ + kfree(vfd); +} /* * Read will do some smarts later on. Buffer pin etc. @@ -611,6 +625,8 @@ #endif devfs_unregister (vfd->devfs_handle); + if (vfd->release) + vfd->release(vfd); video_device[vfd->minor]=NULL; MOD_DEC_USE_COUNT; up(&videodev_lock); @@ -661,6 +677,8 @@ module_init(videodev_init) module_exit(videodev_exit) +EXPORT_SYMBOL(video_device_alloc); +EXPORT_SYMBOL(video_device_release); EXPORT_SYMBOL(video_register_device); EXPORT_SYMBOL(video_unregister_device); EXPORT_SYMBOL(video_devdata); Index: drivers/media/video/vino.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/vino.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/vino.c 22 Jul 2004 19:50:19 -0000 1.1 +++ drivers/media/video/vino.c 4 Aug 2004 01:29:03 -0000 1.2 @@ -1,257 +1,1196 @@ /* - * (incomplete) Driver for the Vino Video input system found in SGI Indys. + * Driver for the VINO (Video In No Out) system found in SGI Indys. + * + * This file is subject to the terms and conditions of the GNU General Public + * License version 2 as published by the Free Software Foundation. * - * Copyright (C) 1999 Ulf Carlsson (ulfc@bun.falkenberg.se) - * - * This isn't complete yet, please don't expect any video until I've written - * some more code. + * Copyright (C) 2003 Ladislav Michl */ #include +#include #include #include -#include #include +#include +#include +#include +#include +#include #include - -#include -#include +#include +#include +#include + +#include +#include +#include +#include +#include #include "vino.h" +/* debugging? */ +#if 1 +#define DEBUG(x...) printk(x); +#else +#define DEBUG(x...) +#endif + +/* VINO video size */ +#define VINO_PAL_WIDTH 768 +#define VINO_PAL_HEIGHT 576 +#define VINO_NTSC_WIDTH 646 +#define VINO_NTSC_HEIGHT 486 + +/* set this to some sensible values. note: VINO_MIN_WIDTH has to be 8*x */ +#define VINO_MIN_WIDTH 32 +#define VINO_MIN_HEIGHT 32 + +/* channel selection */ +#define VINO_INPUT_COMP 0 +#define VINO_INPUT_SVIDEO 1 +#define VINO_INPUT_CAMERA 2 +#define VINO_INPUT_CHANNELS 3 + +#define PAGE_RATIO (PAGE_SIZE / VINO_PAGE_SIZE) + +/* VINO ASIC registers */ +struct sgi_vino *vino; + +static const char *vinostr = "VINO IndyCam/TV"; +static int threshold_a = 512; +static int threshold_b = 512; + struct vino_device { struct video_device vdev; +#define VINO_CHAN_A 1 +#define VINO_CHAN_B 2 + int chan; + int alpha; + /* clipping... */ + unsigned int left, right, top, bottom; + /* decimation used */ + unsigned int decimation; + /* palette used, picture hue, etc */ + struct video_picture picture; + /* VINO_INPUT_COMP, VINO_INPUT_SVIDEO or VINO_INPUT_CAMERA */ + unsigned int input; + /* bytes per line */ + unsigned int line_size; + /* descriptor table (virtual addresses) */ + unsigned long *desc; + /* # of allocated pages */ + int page_count; + /* descriptor table (dma addresses) */ + struct { + dma_addr_t *cpu; + dma_addr_t dma; + } dma_desc; + /* add some more space to let VINO trigger End Of Field interrupt + * before reaching end of buffer */ +#define VINO_FBUFSIZE (VINO_PAL_WIDTH * VINO_PAL_HEIGHT * 4 + 2 * PAGE_SIZE) + unsigned int frame_size; +#define VINO_BUF_UNUSED 0 +#define VINO_BUF_GRABBING 1 +#define VINO_BUF_DONE 2 + int buffer_state; + + wait_queue_head_t dma_wait; + spinlock_t state_lock; + struct semaphore sem; - unsigned long chan; -#define VINO_CHAN_A 0 -#define VINO_CHAN_B 1 + /* Make sure we only have one user at the time */ + int users; +}; - unsigned long flags; -#define VINO_DMA_ACTIVE (1<<0) +struct vino_client { + struct i2c_client *driver; + int owner; }; -/* We can actually receive TV and IndyCam input at the same time. Believe it or - * not.. - */ -static struct vino_device vino[2]; +struct vino_video { + struct vino_device chA; + struct vino_device chB; + + struct vino_client decoder; + struct vino_client camera; + spinlock_t vino_lock; + spinlock_t input_lock; + + /* Loaded into VINO descriptors to clear End Of Descriptors table + * interupt condition */ + unsigned long dummy_desc; + struct { + dma_addr_t *cpu; + dma_addr_t dma; + } dummy_dma; +}; + +static struct vino_video *Vino; + +/* --- */ + +unsigned i2c_vino_getctrl(void *data) +{ + return vino->i2c_control; +} + +void i2c_vino_setctrl(void *data, unsigned val) +{ + vino->i2c_control = val; +} + +unsigned i2c_vino_rdata(void *data) +{ + return vino->i2c_data; +} + +void i2c_vino_wdata(void *data, unsigned val) +{ + vino->i2c_data = val; +} + +static struct i2c_algo_sgi_data i2c_sgi_vino_data = +{ + .getctrl = &i2c_vino_getctrl, + .setctrl = &i2c_vino_setctrl, + .rdata = &i2c_vino_rdata, + .wdata = &i2c_vino_wdata, + .xfer_timeout = 200, + .ack_timeout = 1000, +}; -/* Those registers have to be accessed by either *one* 64 bit write or *one* 64 - * bit read. We need some asm to fix this. We can't use mips3 as standard - * because we just save 32 bits at context switch. +/* + * There are two possible clients on VINO I2C bus, so we limit usage only + * to them. */ +static int i2c_vino_client_reg(struct i2c_client *client) +{ + int res = 0; + + spin_lock(&Vino->input_lock); + switch (client->driver->id) { + case I2C_DRIVERID_SAA7191: + if (Vino->decoder.driver) + res = -EBUSY; + else + Vino->decoder.driver = client; + break; + case I2C_DRIVERID_INDYCAM: + if (Vino->camera.driver) + res = -EBUSY; + else + Vino->camera.driver = client; + break; + default: + res = -ENODEV; + } + spin_unlock(&Vino->input_lock); + + return res; +} -static __inline__ unsigned long long vino_reg_read(unsigned long addr) +static int i2c_vino_client_unreg(struct i2c_client *client) { - unsigned long long ret __attribute__ ((aligned (64))); - unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE); - unsigned long flags; - - save_and_cli(flags); - __asm__ __volatile__( - ".set\tmips3\n\t" - ".set\tnoat\n\t" - "ld\t$1,(%0)\n\t" - "sd\t$1,(%1)\n\t" - ".set\tat\n\t" - ".set\tmips0" - : - :"r" (virt_addr), "r" (&ret)); - restore_flags(flags); + int res = 0; + + spin_lock(&Vino->input_lock); + if (client == Vino->decoder.driver) { + if (Vino->decoder.owner) + res = -EBUSY; + else + Vino->decoder.driver = NULL; + } else if (client == Vino->camera.driver) { + if (Vino->camera.owner) + res = -EBUSY; + else + Vino->camera.driver = NULL; + } + spin_unlock(&Vino->input_lock); - return ret; + return res; +} + +static struct i2c_adapter vino_i2c_adapter = +{ + .name = "VINO I2C bus", + .id = I2C_HW_SGI_VINO, + .algo_data = &i2c_sgi_vino_data, + .client_register = &i2c_vino_client_reg, + .client_unregister = &i2c_vino_client_unreg, +}; + +static int vino_i2c_add_bus(void) +{ + return i2c_sgi_add_bus(&vino_i2c_adapter); +} + +static int vino_i2c_del_bus(void) +{ + return i2c_sgi_del_bus(&vino_i2c_adapter); +} + +static int i2c_camera_command(unsigned int cmd, void *arg) +{ + return Vino->camera.driver->driver->command(Vino->camera.driver, + cmd, arg); } -static __inline__ void vino_reg_write(unsigned long long value, - unsigned long addr) +static int i2c_decoder_command(unsigned int cmd, void *arg) { - unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE); - unsigned long flags; + return Vino->decoder.driver->driver->command(Vino->decoder.driver, + cmd, arg); +} + +/* --- */ - /* we might lose the upper parts of the registers which are not saved - * if there comes an interrupt in our way, play safe */ +static int bytes_per_pixel(struct vino_device *v) +{ + switch (v->picture.palette) { + case VIDEO_PALETTE_GREY: + return 1; + case VIDEO_PALETTE_YUV422: + return 2; + default: /* VIDEO_PALETTE_RGB32 */ + return 4; + } +} - save_and_cli(flags); - __asm__ __volatile__( - ".set\tmips3\n\t" - ".set\tnoat\n\t" - "ld\t$1,(%0)\n\t" - "sd\t$1,(%1)\n\t" - ".set\tat\n\t" - ".set\tmips0" - : - :"r" (&value), "r" (virt_addr)); - restore_flags(flags); -} - -static __inline__ void vino_reg_and(unsigned long long value, - unsigned long addr) -{ - unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE); - unsigned long tmp, flags; - - __save_and_cli(flags); - __asm__ __volatile__( - ".set\tmips3\t\t\t# vino_reg_and\n\t" - ".set\tnoat\n\t" - "ld\t$1, (%1)\n\t" - "ld\t%0, (%2)\n\t" - "and\t$1, $1, %0\n\t" - "sd\t$1, (%1)\n\t" - ".set\tat\n\t" - ".set\tmips0" - : "=&r" (tmp) - : "r" (virt_addr), "r" (&value)); - __restore_flags(flags); -} - -static __inline__ void vino_reg_or(unsigned long long value, - unsigned long addr) -{ - unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE); - unsigned long tmp, flags; - - save_and_cli(flags); - __asm__ __volatile__( - ".set\tmips3\n\t" - ".set\tnoat\n\t" - "ld\t$1, (%1)\n\t" - "ld\t%0, (%2)\n\t" - "or\t$1, $1, %0\n\t" - "sd\t$1, (%1)\n\t" - ".set\tat\n\t" - ".set\tmips0" - : "=&r" (tmp) - : "r" (virt_addr), "r" (&value)); - restore_flags(flags); +static int get_capture_norm(struct vino_device *v) +{ + if (v->input == VINO_INPUT_CAMERA) + return VIDEO_MODE_NTSC; + else { + /* TODO */ + return VIDEO_MODE_NTSC; + } } -static int vino_dma_setup(void) +/* + * Set clipping. Try new values to fit, if they don't return -EINVAL + */ +static int set_clipping(struct vino_device *v, int x, int y, int w, int h, + int d) { + int maxwidth, maxheight, lsize; + + if (d < 1) + d = 1; + if (d > 8) + d = 8; + if (w / d < VINO_MIN_WIDTH || h / d < VINO_MIN_HEIGHT) + return -EINVAL; + if (get_capture_norm(v) == VIDEO_MODE_NTSC) { + maxwidth = VINO_NTSC_WIDTH; + maxheight = VINO_NTSC_HEIGHT; + } else { + maxwidth = VINO_PAL_WIDTH; + maxheight = VINO_PAL_HEIGHT; + } + if (x < 0) + x = 0; + if (y < 0) + y = 0; + y &= ~1; /* odd/even fields */ + if (x + w > maxwidth) { + w = maxwidth - x; + if (w / d < VINO_MIN_WIDTH) + x = maxwidth - VINO_MIN_WIDTH * d; + } + if (y + h > maxheight) { + h = maxheight - y; + if (h / d < VINO_MIN_HEIGHT) + y = maxheight - VINO_MIN_HEIGHT * d; + } + /* line size must be multiple of 8 bytes */ + lsize = (bytes_per_pixel(v) * w / d) & ~7; + w = lsize * d / bytes_per_pixel(v); + v->left = x; + v->top = y; + v->right = x + w; + v->bottom = y + h; + v->decimation = d; + v->line_size = lsize; + DEBUG("VINO: clipping %d, %d, %d, %d / %d - %d\n", v->left, v->top, + v->right, v->bottom, v->decimation, v->line_size); return 0; } -static void vino_dma_stop(void) +static int set_scaling(struct vino_device *v, int w, int h) { + int maxwidth, maxheight, lsize, d; + + if (w < VINO_MIN_WIDTH || h < VINO_MIN_HEIGHT) + return -EINVAL; + if (get_capture_norm(v) == VIDEO_MODE_NTSC) { + maxwidth = VINO_NTSC_WIDTH; + maxheight = VINO_NTSC_HEIGHT; + } else { + maxwidth = VINO_PAL_WIDTH; + maxheight = VINO_PAL_HEIGHT; + } + if (w > maxwidth) + w = maxwidth; + if (h > maxheight) + h = maxheight; + d = max(maxwidth / w, maxheight / h); + if (d > 8) + d = 8; + /* line size must be multiple of 8 bytes */ + lsize = (bytes_per_pixel(v) * w) & ~7; + w = lsize * d / bytes_per_pixel(v); + h *= d; + if (v->left + w > maxwidth) + v->left = maxwidth - w; + if (v->top + h > maxheight) + v->top = (maxheight - h) & ~1; /* odd/even fields */ + /* FIXME: -1 bug... Verify clipping with video signal generator */ + v->right = v->left + w; + v->bottom = v->top + h; + v->decimation = d; + v->line_size = lsize; + DEBUG("VINO: scaling %d, %d, %d, %d / %d - %d\n", v->left, v->top, + v->right, v->bottom, v->decimation, v->line_size); + return 0; } -static int vino_init(void) +/* + * Prepare vino for DMA transfer... (execute only with vino_lock locked) + */ +static int dma_setup(struct vino_device *v) { - unsigned long ret; - unsigned short rev, id; - unsigned long long foo; - unsigned long *bar; - - bar = (unsigned long *) &foo; - - ret = vino_reg_read(VINO_REVID); - - rev = (ret & VINO_REVID_REV_MASK); - id = (ret & VINO_REVID_ID_MASK) >> 4; - - printk("Vino: ID:%02hx Rev:%02hx\n", id, rev); - - foo = vino_reg_read(VINO_A_DESC_DATA0); - printk("0x%lx", bar[0]); - printk("%lx ", bar[1]); - foo = vino_reg_read(VINO_A_DESC_DATA1); - printk("0x%lx", bar[0]); - printk("%lx ", bar[1]); - foo = vino_reg_read(VINO_A_DESC_DATA2); - printk("0x%lx", bar[0]); - printk("%lx ", bar[1]); - foo = vino_reg_read(VINO_A_DESC_DATA3); - printk("0x%lx", bar[0]); - printk("%lx\n", bar[1]); - foo = vino_reg_read(VINO_B_DESC_DATA0); - printk("0x%lx", bar[0]); - printk("%lx ", bar[1]); - foo = vino_reg_read(VINO_B_DESC_DATA1); - printk("0x%lx", bar[0]); - printk("%lx ", bar[1]); - foo = vino_reg_read(VINO_B_DESC_DATA2); - printk("0x%lx", bar[0]); - printk("%lx ", bar[1]); - foo = vino_reg_read(VINO_B_DESC_DATA3); - printk("0x%lx", bar[0]); - printk("%lx\n", bar[1]); + u32 ctrl, intr; + struct sgi_vino_channel *ch; + + ch = (v->chan == VINO_CHAN_A) ? &vino->a : &vino->b; + ch->page_index = 0; + ch->line_count = 0; + /* let VINO know where to transfer data */ + ch->start_desc_tbl = v->dma_desc.dma; + ch->next_4_desc = v->dma_desc.dma; + /* give vino time to fetch the first four descriptors, 5 usec + * should be more than enough time */ + udelay(5); + /* VINO line size register is set 8 bytes less than actual */ + ch->line_size = v->line_size - 8; + /* set the alpha register */ + ch->alpha = v->alpha; + /* set cliping registers */ + ch->clip_start = VINO_CLIP_ODD(v->top) | VINO_CLIP_EVEN(v->top+1) | + VINO_CLIP_X(v->left); + ch->clip_end = VINO_CLIP_ODD(v->bottom) | VINO_CLIP_EVEN(v->bottom+1) | + VINO_CLIP_X(v->right); + /* FIXME: end-of-field bug workaround + VINO_CLIP_X(VINO_PAL_WIDTH); + */ + /* init the frame rate and norm (full frame rate only for now...) */ + ch->frame_rate = VINO_FRAMERT_RT(0x1fff) | + (get_capture_norm(v) == VIDEO_MODE_PAL ? + VINO_FRAMERT_PAL : 0); + ctrl = vino->control; + intr = vino->intr_status; + if (v->chan == VINO_CHAN_A) { + /* All interrupt conditions for this channel was cleared + * so clear the interrupt status register and enable + * interrupts */ + intr &= ~VINO_INTSTAT_A; + ctrl |= VINO_CTRL_A_INT; + /* enable synchronization */ + ctrl |= VINO_CTRL_A_SYNC_ENBL; + /* enable frame assembly */ + ctrl |= VINO_CTRL_A_INTERLEAVE_ENBL; + /* set decimation used */ + if (v->decimation < 2) + ctrl &= ~VINO_CTRL_A_DEC_ENBL; + else { + ctrl |= VINO_CTRL_A_DEC_ENBL; + ctrl &= ~VINO_CTRL_A_DEC_SCALE_MASK; + ctrl |= (v->decimation - 1) << + VINO_CTRL_A_DEC_SCALE_SHIFT; + } + /* select input interface */ + if (v->input == VINO_INPUT_CAMERA) + ctrl |= VINO_CTRL_A_SELECT; + else + ctrl &= ~VINO_CTRL_A_SELECT; + /* palette */ + ctrl &= ~(VINO_CTRL_A_LUMA_ONLY | VINO_CTRL_A_RGB | + VINO_CTRL_A_DITHER); + } else { + intr &= ~VINO_INTSTAT_B; + ctrl |= VINO_CTRL_B_INT; + ctrl |= VINO_CTRL_B_SYNC_ENBL; + ctrl |= VINO_CTRL_B_INTERLEAVE_ENBL; + if (v->decimation < 2) + ctrl &= ~VINO_CTRL_B_DEC_ENBL; + else { + ctrl |= VINO_CTRL_B_DEC_ENBL; + ctrl &= ~VINO_CTRL_B_DEC_SCALE_MASK; + ctrl |= (v->decimation - 1) << + VINO_CTRL_B_DEC_SCALE_SHIFT; + } + if (v->input == VINO_INPUT_CAMERA) + ctrl |= VINO_CTRL_B_SELECT; + else + ctrl &= ~VINO_CTRL_B_SELECT; + ctrl &= ~(VINO_CTRL_B_LUMA_ONLY | VINO_CTRL_B_RGB | + VINO_CTRL_B_DITHER); + } + /* set palette */ + switch (v->picture.palette) { + case VIDEO_PALETTE_GREY: + ctrl |= (v->chan == VINO_CHAN_A) ? + VINO_CTRL_A_LUMA_ONLY : VINO_CTRL_B_LUMA_ONLY; + break; + case VIDEO_PALETTE_RGB32: + ctrl |= (v->chan == VINO_CHAN_A) ? + VINO_CTRL_A_RGB : VINO_CTRL_B_RGB; + break; +#if 0 + /* FIXME: this is NOT in v4l API :-( */ + case VIDEO_PALETTE_RGB332: + ctrl |= (v->chan == VINO_CHAN_A) ? + VINO_CTRL_A_RGB | VINO_CTRL_A_DITHER : + VINO_CTRL_B_RGB | VINO_CTRL_B_DITHER; + break; +#endif + } + vino->control = ctrl; + vino->intr_status = intr; return 0; } -static void vino_dma_go(struct vino_device *v) +/* (execute only with vino_lock locked) */ +static void dma_stop(struct vino_device *v) { - + u32 ctrl = vino->control; + ctrl &= (v->chan == VINO_CHAN_A) ? + ~VINO_CTRL_A_DMA_ENBL : ~VINO_CTRL_B_DMA_ENBL; + vino->control = ctrl; } -/* Reset the vino back to default state */ +/* (execute only with vino_lock locked) */ +static void dma_go(struct vino_device *v) +{ + u32 ctrl = vino->control; + ctrl |= (v->chan == VINO_CHAN_A) ? + VINO_CTRL_A_DMA_ENBL : VINO_CTRL_B_DMA_ENBL; + vino->control = ctrl; +} -static void vino_setup(struct vino_device *v) +/* + * Load dummy page to descriptor registers. This prevents generating of + * spurious interrupts. (execute only with vino_lock locked) + */ +static void clear_eod(struct vino_device *v) { - + struct sgi_vino_channel *ch; + + DEBUG("VINO: chnl %c clear EOD\n", (v->chan == VINO_CHAN_A) ? 'A':'B'); + ch = (v->chan == VINO_CHAN_A) ? &vino->a : &vino->b; + ch->page_index = 0; + ch->line_count = 0; + ch->start_desc_tbl = Vino->dummy_dma.dma; + ch->next_4_desc = Vino->dummy_dma.dma; + udelay(5); } -static int vino_open(struct video_device *dev, int flags) +static void field_done(struct vino_device *v) { - return 0; + spin_lock(&v->state_lock); + if (v->buffer_state == VINO_BUF_GRABBING) + v->buffer_state = VINO_BUF_DONE; + spin_unlock(&v->state_lock); + wake_up(&v->dma_wait); } -static void vino_close(struct video_device *dev) +static void vino_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + u32 intr, ctrl; + + spin_lock(&Vino->vino_lock); + ctrl = vino->control; + intr = vino->intr_status; + DEBUG("VINO: intr status %04x\n", intr); + if (intr & (VINO_INTSTAT_A_FIFO | VINO_INTSTAT_A_EOD)) { + ctrl &= ~VINO_CTRL_A_DMA_ENBL; + vino->control = ctrl; + clear_eod(&Vino->chA); + } + if (intr & (VINO_INTSTAT_B_FIFO | VINO_INTSTAT_B_EOD)) { + ctrl &= ~VINO_CTRL_B_DMA_ENBL; + vino->control = ctrl; + clear_eod(&Vino->chB); + } + vino->intr_status = ~intr; + spin_unlock(&Vino->vino_lock); + /* FIXME: For now we are assuming that interrupt means that frame is + * done. That's not true, but we can live with such brokeness for + * a while ;-) */ + field_done(&Vino->chA); } -static int vino_ioctl(struct video_device *dev, unsigned int cmd, void *arg) +static int vino_grab(struct vino_device *v, int frame) { + int err = 0; + + spin_lock_irq(&v->state_lock); + if (v->buffer_state == VINO_BUF_GRABBING) + err = -EBUSY; + v->buffer_state = VINO_BUF_GRABBING; + spin_unlock_irq(&v->state_lock); + + if (err) + return err; + + spin_lock_irq(&Vino->vino_lock); + dma_setup(v); + dma_go(v); + spin_unlock_irq(&Vino->vino_lock); + return 0; } -static int vino_mmap(struct video_device *dev, const char *adr, - unsigned long size) +static int vino_waitfor(struct vino_device *v, int frame) { + wait_queue_t wait; + int i, err = 0; + + if (frame != 0) + return -EINVAL; + + spin_lock_irq(&v->state_lock); + switch (v->buffer_state) { + case VINO_BUF_GRABBING: + init_waitqueue_entry(&wait, current); + /* add ourselves into wait queue */ + add_wait_queue(&v->dma_wait, &wait); + /* and set current state */ + set_current_state(TASK_INTERRUPTIBLE); + /* before releasing spinlock */ + spin_unlock_irq(&v->state_lock); + /* to ensure that schedule_timeout will return imediately + * if VINO interrupt was triggred meanwhile */ + schedule_timeout(HZ / 10); + if (signal_pending(current)) + err = -EINTR; + spin_lock_irq(&v->state_lock); + remove_wait_queue(&v->dma_wait, &wait); + /* don't rely on schedule_timeout return value and check what + * really happened */ + if (!err && v->buffer_state == VINO_BUF_GRABBING) + err = -EIO; + /* fall through */ + case VINO_BUF_DONE: + for (i = 0; i < v->page_count; i++) + pci_dma_sync_single(NULL, v->dma_desc.cpu[PAGE_RATIO*i], + PAGE_SIZE, PCI_DMA_FROMDEVICE); + v->buffer_state = VINO_BUF_UNUSED; + break; + default: + err = -EINVAL; + } + spin_unlock_irq(&v->state_lock); + + if (err && err != -EINVAL) { + DEBUG("VINO: waiting for frame failed\n"); + spin_lock_irq(&Vino->vino_lock); + dma_stop(v); + clear_eod(v); + spin_unlock_irq(&Vino->vino_lock); + } + + return err; +} + +static int alloc_buffer(struct vino_device *v, int size) +{ + int count, i, j, err; + + err = i = 0; + count = (size / PAGE_SIZE + 4) & ~3; + v->desc = (unsigned long *) kmalloc(count * sizeof(unsigned long), + GFP_KERNEL); + if (!v->desc) + return -ENOMEM; + + v->dma_desc.cpu = pci_alloc_consistent(NULL, PAGE_RATIO * (count+4) * + sizeof(dma_addr_t), + &v->dma_desc.dma); + if (!v->dma_desc.cpu) { + err = -ENOMEM; + goto out_free_desc; + } + while (i < count) { + dma_addr_t dma; + + v->desc[i] = get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!v->desc[i]) + break; + dma = pci_map_single(NULL, (void *)v->desc[i], PAGE_SIZE, + PCI_DMA_FROMDEVICE); + for (j = 0; j < PAGE_RATIO; j++) + v->dma_desc.cpu[PAGE_RATIO * i + j ] = + dma + VINO_PAGE_SIZE * j; + mem_map_reserve(virt_to_page(v->desc[i])); + i++; + } + v->dma_desc.cpu[PAGE_RATIO * count] = VINO_DESC_STOP; + if (i-- < count) { + while (i >= 0) { + mem_map_unreserve(virt_to_page(v->desc[i])); + pci_unmap_single(NULL, v->dma_desc.cpu[PAGE_RATIO * i], + PAGE_SIZE, PCI_DMA_FROMDEVICE); + free_page(v->desc[i]); + i--; + } + pci_free_consistent(NULL, + PAGE_RATIO * (count+4) * sizeof(dma_addr_t), + (void *)v->dma_desc.cpu, v->dma_desc.dma); + err = -ENOBUFS; + goto out_free_desc; + } + v->page_count = count; return 0; + +out_free_desc: + kfree(v->desc); + return err; } -static struct video_device vino_dev = { - owner: THIS_MODULE, - name: "Vino IndyCam/TV", - type: VID_TYPE_CAPTURE, - hardware: VID_HARDWARE_VINO, - open: vino_open, - close: vino_close, - ioctl: vino_ioctl, - mmap: vino_mmap, -}; +static void free_buffer(struct vino_device *v) +{ + int i; + + for (i = 0; i < v->page_count; i++) { + mem_map_unreserve(virt_to_page(v->desc[i])); + pci_unmap_single(NULL, v->dma_desc.cpu[PAGE_RATIO * i], + PAGE_SIZE, PCI_DMA_FROMDEVICE); + free_page(v->desc[i]); + } + pci_free_consistent(NULL, + PAGE_RATIO * (v->page_count+4) * sizeof(dma_addr_t), + (void *)v->dma_desc.cpu, v->dma_desc.dma); + kfree(v->desc); +} -int __init init_vino(struct video_device *dev) +static int vino_open(struct inode *inode, struct file *file) { - int err; + struct video_device *dev = video_devdata(file); + struct vino_device *v = dev->priv; + int err = 0; + + down(&v->sem); + if (v->users) { + err = -EBUSY; + goto out; + } + /* Check for input device (IndyCam, saa7191) availability. + * Both DMA channels can run from the same source, but only + * source owner is allowed to change its parameters */ + spin_lock(&Vino->input_lock); + if (Vino->camera.driver) { + v->input = VINO_INPUT_CAMERA; + if (!Vino->camera.owner) + Vino->camera.owner = v->chan; + } + if (Vino->decoder.driver && Vino->camera.owner != v->chan) { + /* There are two inputs (Composite and SVideo) but only + * one output available to VINO DMA engine */ + if (!Vino->decoder.owner) { + Vino->decoder.owner = v->chan; + v->input = VINO_INPUT_COMP; + i2c_decoder_command(DECODER_SET_INPUT, &v->input); + } else + v->input = (v->chan == VINO_CHAN_A) ? + Vino->chB.input : Vino->chA.input; + } + if (v->input == -1) + err = -ENODEV; + spin_unlock(&Vino->input_lock); - err = vino_init(); if (err) + goto out; + if (alloc_buffer(v, VINO_FBUFSIZE)) { + err = -ENOBUFS; + goto out; + } + v->users++; +out: + up(&v->sem); + return err; +} + +static int vino_close(struct inode *inode, struct file *file) +{ + struct video_device *dev = video_devdata(file); + struct vino_device *v = dev->priv; + + down(&v->sem); + v->users--; + if (!v->users) { + struct vino_device *w = (v->chan == VINO_CHAN_A) ? + &Vino->chB : &Vino->chA; + /* Eventually make other channel owner of input device */ + spin_lock(&Vino->input_lock); + if (Vino->camera.owner == v->chan) + Vino->camera.owner = (w->input == VINO_INPUT_CAMERA) ? + w->chan : 0; + else if (Vino->decoder.owner == v->chan) + Vino->decoder.owner = (w->input == VINO_INPUT_COMP || + w->input == VINO_INPUT_SVIDEO) ? + w->chan : 0; + v->input = -1; + spin_unlock(&Vino->input_lock); + + vino_waitfor(v, 0); + free_buffer(v); + } + up(&v->sem); + return 0; +} + +static int vino_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct video_device *dev = video_devdata(file); + struct vino_device *v = dev->priv; + unsigned long start = vma->vm_start; + unsigned long size = vma->vm_end - vma->vm_start; + int i, err = 0; + + if (down_interruptible(&v->sem)) + return -EINTR; + if (size > v->page_count * PAGE_SIZE) { + err = -EINVAL; + goto out; + } + for (i = 0; i < v->page_count; i++) { + unsigned long page = virt_to_phys((void *)v->desc[i]); + if (remap_page_range(start, page, PAGE_SIZE, PAGE_READONLY)) { + err = -EAGAIN; + goto out; + } + start += PAGE_SIZE; + if (size <= PAGE_SIZE) break; + size -= PAGE_SIZE; + } +out: + up(&v->sem); + return err; + +} + +static int vino_do_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, void *arg) +{ + struct video_device *dev = video_devdata(file); + struct vino_device *v = dev->priv; + + switch (cmd) { + case VIDIOCGCAP: { + struct video_capability *cap = arg; + + strcpy(cap->name, vinostr); + cap->type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE; + cap->channels = VINO_INPUT_CHANNELS; + cap->audios = 0; + cap->maxwidth = VINO_PAL_WIDTH; + cap->maxheight = VINO_PAL_HEIGHT; + cap->minwidth = VINO_MIN_WIDTH; + cap->minheight = VINO_MIN_HEIGHT; + break; + } + case VIDIOCGCHAN: { + struct video_channel *ch = arg; + + ch->flags = 0; + ch->tuners = 0; + switch (ch->channel) { + case VINO_INPUT_COMP: + ch->norm = VIDEO_MODE_PAL | VIDEO_MODE_NTSC; + ch->type = VIDEO_TYPE_TV; + strcpy(ch->name, "Composite"); + break; + case VINO_INPUT_SVIDEO: + ch->norm = VIDEO_MODE_PAL | VIDEO_MODE_NTSC; + ch->type = VIDEO_TYPE_TV; + strcpy(ch->name, "S-Video"); + break; + case VINO_INPUT_CAMERA: + ch->norm = VIDEO_MODE_NTSC; + ch->type = VIDEO_TYPE_CAMERA; + strcpy(ch->name, "IndyCam"); + break; + default: + return -EINVAL; + } + break; + } + case VIDIOCSCHAN: { + struct video_channel *ch = arg; + int err = 0; + struct vino_device *w = (v->chan == VINO_CHAN_A) ? + &Vino->chB : &Vino->chA; + + spin_lock(&Vino->input_lock); + switch (ch->channel) { + case VINO_INPUT_COMP: + case VINO_INPUT_SVIDEO: + if (!Vino->decoder.driver) { + err = -ENODEV; + break; + } + if (!Vino->decoder.owner) + Vino->decoder.owner = v->chan; + if (Vino->decoder.owner == v->chan) + i2c_decoder_command(DECODER_SET_INPUT, + &ch->channel); + else + if (ch->channel != w->input) { + err = -EBUSY; + break; + } + if (Vino->camera.owner == v->chan) + Vino->camera.owner = + (w->input == VINO_INPUT_CAMERA) ? + w->chan : 0; + break; + case VINO_INPUT_CAMERA: + if (!Vino->camera.driver) { + err = -ENODEV; + break; + } + if (!Vino->camera.owner) + Vino->camera.owner = v->chan; + if (Vino->decoder.owner == v->chan) + Vino->decoder.owner = + (w->input == VINO_INPUT_COMP || + w->input == VINO_INPUT_SVIDEO) ? + w->chan : 0; + break; + default: + err = -EINVAL; + } + if (!err) + v->input = ch->channel; + spin_unlock(&Vino->input_lock); + return err; + } + case VIDIOCGPICT: { + struct video_picture *pic = arg; -#if 0 - if (video_register_device(&vinodev, VFL_TYPE_GRABBER) == -1) { - return -ENODEV; + memcpy(pic, &v->picture, sizeof(struct video_picture)); + break; } -#endif + case VIDIOCSPICT: { + struct video_picture *pic = arg; + switch (pic->palette) { + case VIDEO_PALETTE_GREY: + pic->depth = 8; + break; + case VIDEO_PALETTE_YUV422: + pic->depth = 16; + break; + case VIDEO_PALETTE_RGB32: + pic->depth = 24; + break; + default: + return -EINVAL; + } + if (v->picture.palette != pic->palette) { + v->picture.palette = pic->palette; + v->picture.depth = pic->depth; + /* TODO: we need to change line size */ + } + DEBUG("XXX %d, %d\n", v->input, Vino->camera.owner); + spin_lock(&Vino->input_lock); + if (v->input == VINO_INPUT_CAMERA) { + if (Vino->camera.owner == v->chan) { + spin_unlock(&Vino->input_lock); + memcpy(&v->picture, pic, + sizeof(struct video_picture)); + i2c_camera_command(DECODER_SET_PICTURE, pic); + goto out_unlocked; + } + } else { + if (Vino->decoder.owner == v->chan) { + spin_unlock(&Vino->input_lock); + memcpy(&v->picture, pic, + sizeof(struct video_picture)); + i2c_decoder_command(DECODER_SET_PICTURE, pic); + goto out_unlocked; + } + } + spin_unlock(&Vino->input_lock); +out_unlocked: + break; + } + /* get cropping */ + case VIDIOCGCAPTURE: { + struct video_capture *capture = arg; + + capture->x = v->left; + capture->y = v->top; + capture->width = v->right - v->left; + capture->height = v->bottom - v->top; + capture->decimation = v->decimation; + capture->flags = 0; + break; + } + /* set cropping */ + case VIDIOCSCAPTURE: { + struct video_capture *capture = arg; + + return set_clipping(v, capture->x, capture->y, capture->width, + capture->height, capture->decimation); + } + /* get scaling */ + case VIDIOCGWIN: { + struct video_window *win = arg; + + memset(win, 0, sizeof(*win)); + win->width = (v->right - v->left) / v->decimation; + win->height = (v->bottom - v->top) / v->decimation; + break; + } + /* set scaling */ + case VIDIOCSWIN: { + struct video_window *win = arg; + + if (win->x || win->y || win->clipcount || win->clips) + return -EINVAL; + return set_scaling(v, win->width, win->height); + } + case VIDIOCGMBUF: { + struct video_mbuf *buf = arg; + + buf->frames = 1; + buf->offsets[0] = 0; + buf->size = v->page_count * PAGE_SIZE; + break; + } + case VIDIOCMCAPTURE: { + struct video_mmap *mmap = arg; + + if (mmap->width != v->right - v->left || + mmap->height != v->bottom - v->top || + mmap->format != v->picture.palette || + mmap->frame != 0) + return -EINVAL; + + return vino_grab(v, mmap->frame); + } + case VIDIOCSYNC: + return vino_waitfor(v, *((int*)arg)); + default: + return -ENOIOCTLCMD; + } return 0; } -#ifdef MODULE -int init_module(void) +static int vino_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) { + struct video_device *dev = video_devdata(file); + struct vino_device *v = dev->priv; int err; - err = vino_init(); - if (err) - return err; + if (down_interruptible(&v->sem)) + return -EINTR; + err = video_usercopy(inode, file, cmd, arg, vino_do_ioctl); + up(&v->sem); + return err; +} + +static struct file_operations vino_fops = { + .owner = THIS_MODULE, + .open = vino_open, + .release = vino_close, + .ioctl = vino_ioctl, + .mmap = vino_mmap, + .llseek = no_llseek, +}; +static const struct video_device vino_template = { + .owner = THIS_MODULE, + .type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE, + .hardware = VID_HARDWARE_VINO, + .name = "VINO", + .fops = &vino_fops, + .minor = -1, +}; + +static void init_channel_data(struct vino_device *v, int channel) +{ + init_waitqueue_head(&v->dma_wait); + init_MUTEX(&v->sem); + spin_lock_init(&v->state_lock); + memcpy(&v->vdev, &vino_template, sizeof(vino_template)); + v->vdev.priv = v; + v->chan = channel; + v->input = -1; + v->picture.palette = VIDEO_PALETTE_GREY; + v->picture.depth = 8; + v->buffer_state = VINO_BUF_UNUSED; + v->users = 0; + set_clipping(v, 0, 0, VINO_NTSC_WIDTH, VINO_NTSC_HEIGHT, 1); +} + +static int __init vino_init(void) +{ + unsigned long rev; + dma_addr_t dma; + int i, ret = 0; + + /* VINO is Indy specific beast */ + if (ip22_is_fullhouse()) + return -ENODEV; + + /* + * VINO is in the EISA address space, so the sysid register will tell + * us if the EISA_PRESENT pin on MC has been pulled low. + * + * If EISA_PRESENT is not set we definitely don't have a VINO equiped + * system. + */ + if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) { + printk(KERN_ERR "VINO not found\n"); + return -ENODEV; + } + + vino = (struct sgi_vino *)ioremap(VINO_BASE, sizeof(struct sgi_vino)); + if (!vino) + return -EIO; + + /* Okay, once we know that VINO is present we'll read its revision + * safe way. One never knows... */ + if (get_dbe(rev, &(vino->rev_id))) { + printk(KERN_ERR "VINO: failed to read revision register\n"); + ret = -ENODEV; + goto out_unmap; + } + if (VINO_ID_VALUE(rev) != VINO_CHIP_ID) { + printk(KERN_ERR "VINO is not VINO (Rev/ID: 0x%04lx)\n", rev); + ret = -ENODEV; + goto out_unmap; + } + printk(KERN_INFO "VINO Rev: 0x%02lx\n", VINO_REV_NUM(rev)); + + Vino = (struct vino_video *) + kmalloc(sizeof(struct vino_video), GFP_KERNEL); + if (!Vino) { + ret = -ENOMEM; + goto out_unmap; + } + memset(Vino, 0, sizeof(struct vino_video)); + + Vino->dummy_desc = get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!Vino->dummy_desc) { + ret = -ENOMEM; + goto out_free_vino; + } + Vino->dummy_dma.cpu = pci_alloc_consistent(NULL, 4 * sizeof(dma_addr_t), + &Vino->dummy_dma.dma); + if (!Vino->dummy_dma.cpu) { + ret = -ENOMEM; + goto out_free_dummy_desc; + } + dma = pci_map_single(NULL, (void *)Vino->dummy_desc, PAGE_SIZE, + PCI_DMA_FROMDEVICE); + for (i = 0; i < 4; i++) + Vino->dummy_dma.cpu[i] = dma; + + vino->control = 0; + /* prevent VINO from throwing spurious interrupts */ + vino->a.next_4_desc = Vino->dummy_dma.dma; + vino->b.next_4_desc = Vino->dummy_dma.dma; + udelay(5); + vino->intr_status = 0; + /* set threshold level */ + vino->a.fifo_thres = threshold_a; + vino->b.fifo_thres = threshold_b; + + spin_lock_init(&Vino->vino_lock); + spin_lock_init(&Vino->input_lock); + init_channel_data(&Vino->chA, VINO_CHAN_A); + init_channel_data(&Vino->chB, VINO_CHAN_B); + + if (request_irq(SGI_VINO_IRQ, vino_interrupt, 0, vinostr, NULL)) { + printk(KERN_ERR "VINO: request irq%02d failed\n", + SGI_VINO_IRQ); + ret = -EAGAIN; + goto out_unmap_dummy_desc; + } + + ret = vino_i2c_add_bus(); + if (ret) { + printk(KERN_ERR "VINO: I2C bus registration failed\n"); + goto out_free_irq; + } + + if (video_register_device(&Vino->chA.vdev, VFL_TYPE_GRABBER, -1) < 0) { + printk("%s, chnl %d: device registration failed.\n", + Vino->chA.vdev.name, Vino->chA.chan); + ret = -EINVAL; + goto out_i2c_del_bus; + } + if (video_register_device(&Vino->chB.vdev, VFL_TYPE_GRABBER, -1) < 0) { + printk("%s, chnl %d: device registration failed.\n", + Vino->chB.vdev.name, Vino->chB.chan); + ret = -EINVAL; + goto out_unregister_vdev; + } + +#if defined(CONFIG_KMOD) && defined (MODULE) + request_module("saa7191"); + request_module("indycam"); +#endif return 0; + +out_unregister_vdev: + video_unregister_device(&Vino->chA.vdev); +out_i2c_del_bus: + vino_i2c_del_bus(); +out_free_irq: + free_irq(SGI_VINO_IRQ, NULL); +out_unmap_dummy_desc: + pci_unmap_single(NULL, Vino->dummy_dma.dma, PAGE_SIZE, + PCI_DMA_FROMDEVICE); + pci_free_consistent(NULL, 4 * sizeof(dma_addr_t), + (void *)Vino->dummy_dma.cpu, Vino->dummy_dma.dma); +out_free_dummy_desc: + free_page(Vino->dummy_desc); +out_free_vino: + kfree(Vino); +out_unmap: + iounmap(vino); + + return ret; } -void cleanup_module(void) +static void __exit vino_exit(void) { + video_unregister_device(&Vino->chA.vdev); + video_unregister_device(&Vino->chB.vdev); + vino_i2c_del_bus(); + free_irq(SGI_VINO_IRQ, NULL); + pci_unmap_single(NULL, Vino->dummy_dma.dma, PAGE_SIZE, + PCI_DMA_FROMDEVICE); + pci_free_consistent(NULL, 4 * sizeof(dma_addr_t), + (void *)Vino->dummy_dma.cpu, Vino->dummy_dma.dma); + free_page(Vino->dummy_desc); + kfree(Vino); + iounmap(vino); } -#endif + +module_init(vino_init); +module_exit(vino_exit); + +MODULE_AUTHOR("Ladislav Michl "); +MODULE_DESCRIPTION("Video4Linux driver for SGI Indy VINO (IndyCam)"); +MODULE_LICENSE("GPL"); Index: drivers/media/video/vino.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/media/video/vino.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/media/video/vino.h 22 Jul 2004 19:50:19 -0000 1.1 +++ drivers/media/video/vino.h 4 Aug 2004 01:29:03 -0000 1.2 @@ -1,64 +1,85 @@ /* - * Copyright (C) 1999 Ulf Carlsson (ulfc@bun.falkenberg.se) - * Copyright (C) 2001 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999 Ulf Karlsson + * Copyright (C) 2003 Ladislav Michl */ -#define VINO_BASE 0x00080000 /* In EISA address space */ +#ifndef VINO_H +#define VINO_H -#define VINO_REVID 0x0000 -#define VINO_CTRL 0x0008 -#define VINO_INTSTAT 0x0010 /* Interrupt status */ -#define VINO_I2C_CTRL 0x0018 -#define VINO_I2C_DATA 0x0020 -#define VINO_A_ALPHA 0x0028 /* Channel A ... */ -#define VINO_A_CLIPS 0x0030 /* Clipping start */ -#define VINO_A_CLIPE 0x0038 /* Clipping end */ -#define VINO_A_FRAMERT 0x0040 /* Framerate */ -#define VINO_A_FLDCNT 0x0048 /* Field counter */ -#define VINO_A_LNSZ 0x0050 -#define VINO_A_LNCNT 0x0058 -#define VINO_A_PGIX 0x0060 /* Page index */ -#define VINO_A_DESC_PTR 0x0068 /* Ptr to next four descriptors */ -#define VINO_A_DESC_TLB_PTR 0x0070 /* Ptr to start of descriptor table */ -#define VINO_A_DESC_DATA0 0x0078 /* Descriptor data 0 */ -#define VINO_A_DESC_DATA1 0x0080 /* ... */ -#define VINO_A_DESC_DATA2 0x0088 -#define VINO_A_DESC_DATA3 0x0090 -#define VINO_A_FIFO_THRESHOLD 0x0098 /* FIFO threshold */ -#define VINO_A_FIFO_RP 0x00a0 -#define VINO_A_FIFO_WP 0x00a8 -#define VINO_B_ALPHA 0x00b0 /* Channel B ... */ -#define VINO_B_CLIPS 0x00b8 -#define VINO_B_CLIPE 0x00c0 -#define VINO_B_FRAMERT 0x00c8 -#define VINO_B_FLDCNT 0x00d0 -#define VINO_B_LNSZ 0x00d8 -#define VINO_B_LNCNT 0x00e0 -#define VINO_B_PGIX 0x00e8 -#define VINO_B_DESC_PTR 0x00f0 -#define VINO_B_DESC_TLB_PTR 0x00f8 -#define VINO_B_DESC_DATA0 0x0100 -#define VINO_B_DESC_DATA1 0x0108 -#define VINO_B_DESC_DATA2 0x0110 -#define VINO_B_DESC_DATA3 0x0118 -#define VINO_B_FIFO_THRESHOLD 0x0120 -#define VINO_B_FIFO_RP 0x0128 -#define VINO_B_FIFO_WP 0x0130 - -/* Bits in the VINO_REVID register */ - -#define VINO_REVID_REV_MASK 0x000f /* bits 0:3 */ -#define VINO_REVID_ID_MASK 0x00f0 /* bits 4:7 */ - -/* Bits in the VINO_CTRL register */ +#define VINO_BASE 0x00080000 /* Vino is in the EISA address space, + * but it is not an EISA bus card */ +#define VINO_PAGE_SIZE 4096 + +struct sgi_vino_channel { + u32 _pad_alpha; + volatile u32 alpha; + +#define VINO_CLIP_X(x) ((x) & 0x3ff) /* bits 0:9 */ +#define VINO_CLIP_ODD(x) (((x) & 0x1ff) << 10) /* bits 10:18 */ +#define VINO_CLIP_EVEN(x) (((x) & 0x1ff) << 19) /* bits 19:27 */ + u32 _pad_clip_start; + volatile u32 clip_start; + u32 _pad_clip_end; + volatile u32 clip_end; + +#define VINO_FRAMERT_PAL (1<<0) /* 0=NTSC 1=PAL */ +#define VINO_FRAMERT_RT(x) (((x) & 0x1fff) << 1) /* bits 1:12 */ + u32 _pad_frame_rate; + volatile u32 frame_rate; + + u32 _pad_field_counter; + volatile u32 field_counter; + u32 _pad_line_size; + volatile u32 line_size; + u32 _pad_line_count; + volatile u32 line_count; + u32 _pad_page_index; + volatile u32 page_index; + u32 _pad_next_4_desc; + volatile u32 next_4_desc; + u32 _pad_start_desc_tbl; + volatile u32 start_desc_tbl; + +#define VINO_DESC_JUMP (1<<30) +#define VINO_DESC_STOP (1<<31) +#define VINO_DESC_VALID (1<<32) + u32 _pad_desc_0; + volatile u32 desc_0; + u32 _pad_desc_1; + volatile u32 desc_1; + u32 _pad_desc_2; + volatile u32 desc_2; + u32 _pad_Bdesc_3; + volatile u32 desc_3; + + u32 _pad_fifo_thres; + volatile u32 fifo_thres; + u32 _pad_fifo_read; + volatile u32 fifo_read; + u32 _pad_fifo_write; + volatile u32 fifo_write; +}; + +struct sgi_vino { +#define VINO_CHIP_ID 0xb +#define VINO_REV_NUM(x) ((x) & 0x0f) +#define VINO_ID_VALUE(x) (((x) & 0xf0) >> 4) + u32 _pad_rev_id; + volatile u32 rev_id; #define VINO_CTRL_LITTLE_ENDIAN (1<<0) -#define VINO_CTRL_A_FIELD_TRANS_INT (1<<1) /* Field transferred int */ -#define VINO_CTRL_A_FIFO_OF_INT (1<<2) /* FIFO overflow int */ -#define VINO_CTRL_A_END_DESC_TBL_INT (1<<3) /* End of desc table int */ -#define VINO_CTRL_B_FIELD_TRANS_INT (1<<4) /* Field transferred int */ -#define VINO_CTRL_B_FIFO_OF_INT (1<<5) /* FIFO overflow int */ -#define VINO_CTRL_B_END_DESC_TLB_INT (1<<6) /* End of desc table int */ +#define VINO_CTRL_A_EOF_INT (1<<1) /* Field transferred int */ +#define VINO_CTRL_A_FIFO_INT (1<<2) /* FIFO overflow int */ +#define VINO_CTRL_A_EOD_INT (1<<3) /* End of desc table int */ +#define VINO_CTRL_A_INT (VINO_CTRL_A_EOF_INT | \ + VINO_CTRL_A_FIFO_INT | \ + VINO_CTRL_A_EOD_INT) +#define VINO_CTRL_B_EOF_INT (1<<4) /* Field transferred int */ +#define VINO_CTRL_B_FIFO_INT (1<<5) /* FIFO overflow int */ +#define VINO_CTRL_B_EOD_INT (1<<6) /* End of desc table int */ +#define VINO_CTRL_B_INT (VINO_CTRL_B_EOF_INT | \ + VINO_CTRL_B_FIFO_INT | \ + VINO_CTRL_B_EOD_INT) #define VINO_CTRL_A_DMA_ENBL (1<<7) #define VINO_CTRL_A_INTERLEAVE_ENBL (1<<8) #define VINO_CTRL_A_SYNC_ENBL (1<<9) @@ -67,51 +88,45 @@ #define VINO_CTRL_A_LUMA_ONLY (1<<12) #define VINO_CTRL_A_DEC_ENBL (1<<13) /* Decimation */ #define VINO_CTRL_A_DEC_SCALE_MASK 0x1c000 /* bits 14:17 */ +#define VINO_CTRL_A_DEC_SCALE_SHIFT (14) #define VINO_CTRL_A_DEC_HOR_ONLY (1<<17) /* Horizontal only */ #define VINO_CTRL_A_DITHER (1<<18) /* 24 -> 8 bit dither */ #define VINO_CTRL_B_DMA_ENBL (1<<19) #define VINO_CTRL_B_INTERLEAVE_ENBL (1<<20) #define VINO_CTRL_B_SYNC_ENBL (1<<21) #define VINO_CTRL_B_SELECT (1<<22) /* 1=D1 0=Philips */ -#define VINO_CTRL_B_RGB (1<<22) /* 1=RGB 0=YUV */ -#define VINO_CTRL_B_LUMA_ONLY (1<<23) -#define VINO_CTRL_B_DEC_ENBL (1<<24) /* Decimation */ -#define VINO_CTRL_B_DEC_SCALE_MASK 0x1c000000 /* bits 25:28 */ +#define VINO_CTRL_B_RGB (1<<23) /* 1=RGB 0=YUV */ +#define VINO_CTRL_B_LUMA_ONLY (1<<24) +#define VINO_CTRL_B_DEC_ENBL (1<<25) /* Decimation */ +#define VINO_CTRL_B_DEC_SCALE_MASK 0x1c000000 /* bits 26:28 */ +#define VINO_CTRL_B_DEC_SCALE_SHIFT (26) #define VINO_CTRL_B_DEC_HOR_ONLY (1<<29) /* Decimation horizontal only */ #define VINO_CTRL_B_DITHER (1<<30) /* ChanB 24 -> 8 bit dither */ + u32 _pad_control; + volatile u32 control; -/* Bits in the Interrupt and Status register */ - -#define VINO_INTSTAT_A_FIELD_TRANS (1<<0) /* Field transferred int */ -#define VINO_INTSTAT_A_FIFO_OF (1<<1) /* FIFO overflow int */ -#define VINO_INTSTAT_A_END_DESC_TBL (1<<2) /* End of desc table int */ -#define VINO_INTSTAT_B_FIELD_TRANS (1<<3) /* Field transferred int */ -#define VINO_INTSTAT_B_FIFO_OF (1<<4) /* FIFO overflow int */ -#define VINO_INTSTAT_B_END_DESC_TBL (1<<5) /* End of desc table int */ - -/* Bits in the Clipping Start register */ - -#define VINO_CLIPS_START 0x3ff /* bits 0:9 */ -#define VINO_CLIPS_ODD_MASK 0x7fc00 /* bits 10:18 */ -#define VINO_CLIPS_EVEN_MASK 0xff80000 /* bits 19:27 */ - -/* Bits in the Clipping End register */ - -#define VINO_CLIPE_END 0x3ff /* bits 0:9 */ -#define VINO_CLIPE_ODD_MASK 0x7fc00 /* bits 10:18 */ -#define VINO_CLIPE_EVEN_MASK 0xff80000 /* bits 19:27 */ - -/* Bits in the Frame Rate register */ - -#define VINO_FRAMERT_PAL (1<<0) /* 0=NTSC 1=PAL */ -#define VINO_FRAMERT_RT_MASK 0x1ffe /* bits 1:12 */ - -/* Bits in the VINO_I2C_CTRL */ +#define VINO_INTSTAT_A_EOF (1<<0) /* Field transferred int */ +#define VINO_INTSTAT_A_FIFO (1<<1) /* FIFO overflow int */ +#define VINO_INTSTAT_A_EOD (1<<2) /* End of desc table int */ +#define VINO_INTSTAT_A (VINO_INTSTAT_A_EOF | \ + VINO_INTSTAT_A_FIFO | \ + VINO_INTSTAT_A_EOD) +#define VINO_INTSTAT_B_EOF (1<<3) /* Field transferred int */ +#define VINO_INTSTAT_B_FIFO (1<<4) /* FIFO overflow int */ +#define VINO_INTSTAT_B_EOD (1<<5) /* End of desc table int */ +#define VINO_INTSTAT_B (VINO_INTSTAT_B_EOF | \ + VINO_INTSTAT_B_FIFO | \ + VINO_INTSTAT_B_EOD) + u32 _pad_intr_status; + volatile u32 intr_status; + + u32 _pad_i2c_control; + volatile u32 i2c_control; + u32 _pad_i2c_data; + volatile u32 i2c_data; + + struct sgi_vino_channel a; + struct sgi_vino_channel b; +}; -#define VINO_CTRL_I2C_IDLE (1<<0) /* write: 0=force idle - * read: 0=idle 1=not idle */ -#define VINO_CTRL_I2C_DIR (1<<1) /* 0=read 1=write */ -#define VINO_CTRL_I2C_MORE_BYTES (1<<2) /* 0=last byte 1=more bytes */ -#define VINO_CTRL_I2C_TRANS_BUSY (1<<4) /* 0=trans done 1=trans busy */ -#define VINO_CTRL_I2C_ACK (1<<5) /* 0=ack received 1=ack not */ -#define VINO_CTRL_I2C_BUS_ERROR (1<<7) /* 0=no bus err 1=bus err */ +#endif Index: drivers/message/fusion/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/message/fusion/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/message/fusion/Makefile 22 Jul 2004 19:50:24 -0000 1.1 +++ drivers/message/fusion/Makefile 4 Aug 2004 01:29:04 -0000 1.2 @@ -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 # Index: drivers/message/fusion/isense.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/message/fusion/isense.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/message/fusion/isense.c 22 Jul 2004 19:50:24 -0000 1.1 +++ drivers/message/fusion/isense.c 4 Aug 2004 01:29:04 -0000 1.2 @@ -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:mpt_linux_developer@lsil.com) * - * $Id: isense.c,v 1.1 2004/07/22 19:50:24 joff Exp $ + * $Id: isense.c,v 1.2 2004/08/04 01:29:04 joff 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"); Index: drivers/message/fusion/linux_compat.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/message/fusion/linux_compat.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/message/fusion/linux_compat.h 22 Jul 2004 19:50:24 -0000 1.1 +++ drivers/message/fusion/linux_compat.h 4 Aug 2004 01:29:04 -0000 1.2 @@ -11,6 +11,11 @@ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ + +#if (defined(__sparc__) && defined(__sparc_v9__)) || defined(__x86_64__) +#define MPT_CONFIG_COMPAT +#endif + #ifndef rwlock_init #define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0) #endif @@ -75,11 +80,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 @@ -93,7 +98,7 @@ * Used prior to schedule_timeout calls.. */ #define __set_current_state(state_value) do { current->state = state_value; } while (0) -#ifdef __SMP__ +#ifdef CONFIG_SMP #define set_current_state(state_value) do { __set_current_state(state_value); mb(); } while (0) #else #define set_current_state(state_value) __set_current_state(state_value) @@ -247,8 +252,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 @@ -265,11 +272,18 @@ #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,28) -#define mptscsih_sync_irq(_irq) synchronize_irq(_irq) +#define mpt_sync_irq(_irq) synchronize_irq(_irq) #else -#define mptscsih_sync_irq(_irq) synchronize_irq() +#define mpt_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 /*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ Index: drivers/message/fusion/mptbase.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/message/fusion/mptbase.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/message/fusion/mptbase.c 22 Jul 2004 19:50:24 -0000 1.1 +++ drivers/message/fusion/mptbase.c 4 Aug 2004 01:29:04 -0000 1.2 @@ -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:mpt_linux_developer@lsil.com) * - * $Id: mptbase.c,v 1.1 2004/07/22 19:50:24 joff Exp $ + * $Id: mptbase.c,v 1.2 2004/08/04 01:29:04 joff 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 @@ -209,6 +211,7 @@ static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum); static int mpt_findImVolumes(MPT_ADAPTER *ioc); static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc); +static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc); static void mpt_timer_expired(unsigned long data); static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch); static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp); @@ -317,14 +320,14 @@ MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mr; u32 pa; - int req_idx = -1; + int req_idx; int cb_idx; int type; int freeme; - int count = 0; ioc = bus_id; +#ifdef MPT_DEBUG_IRQ /* * Verify ioc pointer is ok */ @@ -339,6 +342,7 @@ return; } } +#endif /* * Drain the reply FIFO! @@ -444,7 +448,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 +456,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; @@ -491,17 +495,7 @@ spin_unlock_irqrestore(&ioc->FreeQlock, flags); } - count++; - dirqprintk((MYIOC_s_INFO_FMT "ISR processed frame #%d\n", ioc->name, count)); mb(); - - if (count >= MPT_MAX_REPLIES_PER_ISR) { - dirqprintk((MYIOC_s_INFO_FMT "ISR processed %d replies.", - ioc->name, count)); - dirqprintk((" Giving this ISR a break!\n")); - return; - } - } /* drain reply FIFO */ } @@ -577,7 +571,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 +594,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 +678,7 @@ MptEvHandlers[i] = NULL; last_drv_idx = i; if (cbfunc != mpt_base_reply) { - MOD_INC_USE_COUNT; + mpt_inc_use_count(); } break; } @@ -704,7 +698,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 +708,7 @@ isense_idx++; if (cb_idx != mpt_base_index) { - MOD_DEC_USE_COUNT; + mpt_dec_use_count(); } } } @@ -812,7 +806,7 @@ MPT_FRAME_HDR* mpt_get_msg_frame(int handle, int iocid) { - MPT_FRAME_HDR *mf = NULL; + MPT_FRAME_HDR *mf; MPT_ADAPTER *iocp; unsigned long flags; @@ -844,6 +838,8 @@ iocp->mfcnt++; #endif } + else + mf = NULL; spin_unlock_irqrestore(&iocp->FreeQlock, flags); #ifdef MFCNT @@ -944,7 +940,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 +970,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 +983,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 +1066,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 +1080,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; } @@ -1112,10 +1108,12 @@ MPT_ADAPTER * mpt_adapter_find_first(void) { - MPT_ADAPTER *this = NULL; + MPT_ADAPTER *this; if (! Q_IS_EMPTY(&MptAdapters)) this = MptAdapters.head; + else + this = NULL; return this; } @@ -1130,10 +1128,12 @@ MPT_ADAPTER * mpt_adapter_find_next(MPT_ADAPTER *prev) { - MPT_ADAPTER *next = NULL; + MPT_ADAPTER *next; if (prev && (prev->forw != (MPT_ADAPTER*)&MptAdapters.head)) next = prev->forw; + else + next = NULL; return next; } @@ -1278,17 +1278,23 @@ 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; + /* For some kernels, broken kernel limits memory allocation for target mode + * driver. Shirron. Fixed in 2.4.20-8 + * if ((sizeof(dma_addr_t) == sizeof(u64)) && (!pci_set_dma_mask(pdev, mask))) { + */ + 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; + } } ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC); @@ -1296,10 +1302,10 @@ printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n"); return -ENOMEM; } - memset(ioc, 0, sizeof(*ioc)); + memset(ioc, 0, sizeof(MPT_ADAPTER)); ioc->alloc_total = sizeof(MPT_ADAPTER); ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */ - ioc->reply_sz = ioc->req_sz; + ioc->reply_sz = MPT_REPLY_FRAME_SIZE; ioc->pcidev = pdev; ioc->diagPending = 0; @@ -1415,13 +1421,12 @@ ioc->prod_name = "LSIFC929X"; { /* 929X Chip Fix. Set Split transactions level - * for PCIX. Set bits 5 - 6 to zero, turn on bit 4. + * for PCIX. Set MOST bits to zero. */ - u16 pcixcmd = 0; - pci_read_config_word(pdev, 0x6a, &pcixcmd); - pcixcmd &= 0xFF9F; - pcixcmd |= 0x0010; - pci_write_config_word(pdev, 0x6a, pcixcmd); + u8 pcixcmd; + pci_read_config_byte(pdev, 0x6a, &pcixcmd); + pcixcmd &= 0x8F; + pci_write_config_byte(pdev, 0x6a, pcixcmd); } } else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) { @@ -1429,13 +1434,12 @@ ioc->prod_name = "LSIFC919X"; { /* 919X Chip Fix. Set Split transactions level - * for PCIX. Set bits 5 - 6 to zero, turn on bit 4. + * for PCIX. Set MOST bits to zero. */ - u16 pcixcmd = 0; - pci_read_config_word(pdev, 0x6a, &pcixcmd); - pcixcmd &= 0xFF9F; - pcixcmd |= 0x0010; - pci_write_config_word(pdev, 0x6a, pcixcmd); + u8 pcixcmd; + pci_read_config_byte(pdev, 0x6a, &pcixcmd); + pcixcmd &= 0x8F; + pci_write_config_byte(pdev, 0x6a, pcixcmd); } } else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) { @@ -1445,14 +1449,14 @@ u8 revision; /* 1030 Chip Fix. Disable Split transactions - * for PCIX. Set bits 4 - 6 to zero if Rev < C0( = 8) + * for PCIX. Set MOST bits to zero if Rev < C0( = 8). */ pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); if (revision < 0x08) { - u16 pcixcmd = 0; - pci_read_config_word(pdev, 0x6a, &pcixcmd); - pcixcmd &= 0xFF8F; - pci_write_config_word(pdev, 0x6a, pcixcmd); + u8 pcixcmd; + pci_read_config_byte(pdev, 0x6a, &pcixcmd); + pcixcmd &= 0x8F; + pci_write_config_byte(pdev, 0x6a, pcixcmd); } } } @@ -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); @@ -1724,6 +1764,8 @@ /* Check, and possibly reset, the coalescing value */ mpt_read_ioc_pg_1(ioc); + + mpt_read_ioc_pg_4(ioc); } GetIoUnitPage2(ioc); @@ -1738,24 +1780,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 +1872,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); } } @@ -1910,6 +1952,15 @@ kfree(this->spi_data.pIocPg3); this->spi_data.pIocPg3 = NULL; } + + if (freeup && this->spi_data.pIocPg4 != NULL) { + sz = this->spi_data.IocPg4Sz; + pci_free_consistent(this->pcidev, sz, + this->spi_data.pIocPg4, + this->spi_data.IocPg4_dma); + this->spi_data.pIocPg4 = NULL; + this->alloc_total -= sz; + } } } @@ -2014,8 +2065,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 +2109,7 @@ else statefault = 4; } - } + } /* * Check to see if IOC is in FAULT state. @@ -2106,9 +2157,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 +2248,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 +2309,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)} */ @@ -2308,7 +2357,7 @@ */ ioc->req_sz = MIN(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4); ioc->req_depth = MIN(MPT_MAX_REQ_DEPTH, facts->GlobalCredits); - ioc->reply_sz = ioc->req_sz; + ioc->reply_sz = MPT_REPLY_FRAME_SIZE; ioc->reply_depth = MIN(MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth); dprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n", @@ -2433,10 +2482,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 +2531,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,17 +2617,17 @@ * 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; + fw_image_t **cached_fw; + u8 *mem; dma_addr_t fw_dma; int alloc_total = 0; 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); @@ -2722,7 +2769,7 @@ u8 reply[sizeof(FWUploadReply_t)]; FWUpload_t *prequest; FWUploadReply_t *preply; - FWUploadTCSGE_t *ptcsge = NULL; + FWUploadTCSGE_t *ptcsge; int sgeoffset; int ii, sz, reply_sz; int cmdStatus, freeMem = 0; @@ -2737,8 +2784,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 +2832,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); @@ -2854,16 +2901,16 @@ static int mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag) { - MpiFwHeader_t *FwHdr = NULL; + MpiFwHeader_t *FwHdr; MpiExtImageHeader_t *ExtHdr; - fw_image_t **pCached = NULL; + fw_image_t **pCached; int fw_sz; u32 diag0val; #ifdef MPT_DEBUG u32 diag1val = 0; #endif int count = 0; - u32 *ptru32 = NULL; + u32 *ptru32; u32 diagRwData; u32 nextImage; u32 ext_offset; @@ -3133,8 +3180,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 +3324,7 @@ /* * Disable the ARM (Bug fix) - * + * */ CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM); mdelay (1); @@ -3326,7 +3373,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 +3390,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 +3519,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 +3819,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 +3863,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 +3879,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 +3886,6 @@ mdelay (1); count++; } - count /= 10; } if (cntdn) { @@ -3869,10 +3914,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 +3929,6 @@ count++; } } else { - cntdn *= 10; /* convert to msec */ while (--cntdn) { intstat = CHIPREG_READ32(&ioc->chip->IntStatus); if (intstat & MPI_HIS_DOORBELL_INTERRUPT) @@ -3891,7 +3936,6 @@ mdelay(1); count++; } - count /= 10; } if (cntdn) { @@ -4268,14 +4312,14 @@ static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum) { - u8 *pbuf = NULL; + u8 *pbuf; dma_addr_t buf_dma; CONFIGPARMS cfg; ConfigPageHeader_t header; int ii; int data, rc = 0; - /* Allocate memory + /* Allocate memory */ if (!ioc->spi_data.nvram) { int sz; @@ -4354,7 +4398,6 @@ } if (pbuf) { pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma); - pbuf = NULL; } } } @@ -4391,6 +4434,8 @@ /* Save the Port Page 2 data * (reformat into a 32bit quantity) */ + data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK; + ioc->spi_data.PortFlags = data; for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { pdevice = &pPP2->DeviceSettings[ii]; data = (le16_to_cpu(pdevice->DeviceFlags) << 16) | @@ -4400,7 +4445,6 @@ } pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma); - pbuf = NULL; } } @@ -4454,12 +4498,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 * @@ -4471,8 +4520,8 @@ static int mpt_findImVolumes(MPT_ADAPTER *ioc) { - IOCPage2_t *pIoc2 = NULL; - ConfigPageIoc2RaidVol_t *pIocRv = NULL; + IOCPage2_t *pIoc2; + ConfigPageIoc2RaidVol_t *pIocRv; dma_addr_t ioc2_dma; CONFIGPARMS cfg; ConfigPageHeader_t header; @@ -4549,10 +4598,7 @@ } done_and_free: - if (pIoc2) { - pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma); - pIoc2 = NULL; - } + pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma); return rc; } @@ -4560,7 +4606,7 @@ int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc) { - IOCPage3_t *pIoc3 = NULL; + IOCPage3_t *pIoc3; u8 *mem; CONFIGPARMS cfg; ConfigPageHeader_t header; @@ -4613,18 +4659,66 @@ } } - if (pIoc3) { - pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma); - pIoc3 = NULL; - } + pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma); return 0; } static void +mpt_read_ioc_pg_4(MPT_ADAPTER *ioc) +{ + IOCPage4_t *pIoc4; + CONFIGPARMS cfg; + ConfigPageHeader_t header; + dma_addr_t ioc4_dma; + int iocpage4sz; + + /* Read and save IOC Page 4 + */ + header.PageVersion = 0; + header.PageLength = 0; + header.PageNumber = 4; + header.PageType = MPI_CONFIG_PAGETYPE_IOC; + cfg.hdr = &header; + cfg.physAddr = -1; + cfg.pageAddr = 0; + cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; + cfg.dir = 0; + cfg.timeout = 0; + if (mpt_config(ioc, &cfg) != 0) + return; + + if (header.PageLength == 0) + return; + + if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) { + iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */ + pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma); + if (!pIoc4) + return; + } else { + ioc4_dma = ioc->spi_data.IocPg4_dma; + iocpage4sz = ioc->spi_data.IocPg4Sz; + } + + /* Read the Page into dma memory. + */ + cfg.physAddr = ioc4_dma; + cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; + if (mpt_config(ioc, &cfg) == 0) { + ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4; + ioc->spi_data.IocPg4_dma = ioc4_dma; + ioc->spi_data.IocPg4Sz = iocpage4sz; + } else { + pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma); + ioc->spi_data.pIocPg4 = NULL; + } +} + +static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc) { - IOCPage1_t *pIoc1 = NULL; + IOCPage1_t *pIoc1; CONFIGPARMS cfg; ConfigPageHeader_t header; dma_addr_t ioc1_dma; @@ -4700,10 +4794,7 @@ } } - if (pIoc1) { - pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma); - pIoc1 = NULL; - } + pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma); return; } @@ -4802,7 +4893,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 +4901,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 +4934,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 +4981,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 +4991,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 +5012,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 +5035,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 +5054,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 */ @@ -5405,7 +5481,7 @@ int rc; unsigned long flags; - dprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name)); + dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name)); #ifdef MFCNT printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name); printk("MF count 0x%x !\n", ioc->mfcnt); @@ -5425,6 +5501,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]) { + dtmprintk((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) { + dtmprintk((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", @@ -5440,7 +5539,7 @@ ioc->alt_ioc->diagPending = 0; spin_unlock_irqrestore(&ioc->diagLock, flags); - dprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc)); + dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc)); return rc; } @@ -5449,7 +5548,7 @@ static char * EventDescriptionStr(u8 event, u32 evData0) { - char *ds = NULL; + char *ds; switch(event) { case MPI_EVENT_NONE: @@ -5836,7 +5935,7 @@ isense_idx = last_drv_idx; r = 1; } - MOD_INC_USE_COUNT; + mpt_inc_use_count(); return r; } @@ -5855,7 +5954,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(); } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -5955,7 +6054,7 @@ fusion_exit(void) { MPT_ADAPTER *this; - struct pci_dev *pdev = NULL; + struct pci_dev *pdev; dprintk((KERN_INFO MYNAM ": fusion_exit() called!\n")); @@ -5975,7 +6074,7 @@ this->active = 0; pdev = (struct pci_dev *)this->pcidev; - mptscsih_sync_irq(pdev->irq); + mpt_sync_irq(pdev->irq); /* Clear any lingering interrupt */ CHIPREG_WRITE32(&this->chip->IntStatus, 0); Index: drivers/message/fusion/mptbase.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/message/fusion/mptbase.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/message/fusion/mptbase.h 22 Jul 2004 19:50:24 -0000 1.1 +++ drivers/message/fusion/mptbase.h 4 Aug 2004 01:29:04 -0000 1.2 @@ -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:mpt_linux_developer@lsil.com) * - * $Id: mptbase.h,v 1.1 2004/07/22 19:50:24 joff Exp $ + * $Id: mptbase.h,v 1.2 2004/08/04 01:29:04 joff Exp $ */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -77,11 +77,11 @@ #endif #ifndef COPYRIGHT -#define COPYRIGHT "Copyright (c) 1999-2002 " MODULEAUTHOR +#define COPYRIGHT "Copyright (c) 1999-2003 " 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.11.03" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-2.05.11.03" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ @@ -93,10 +93,10 @@ */ #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 +#define MPT_LAST_LUN 255 #define MPT_SENSE_BUFFER_ALLOC 64 /* allow for 256 max sense alloc, but only 255 max request */ #if MPT_SENSE_BUFFER_ALLOC >= 256 @@ -127,6 +127,8 @@ #define MPT_MAX_FRAME_SIZE 128 #define MPT_DEFAULT_FRAME_SIZE 128 +#define MPT_REPLY_FRAME_SIZE 0x40 /* Must be a multiple of 8 */ + #define MPT_SG_REQ_128_SCALE 1 #define MPT_SG_REQ_96_SCALE 2 #define MPT_SG_REQ_64_SCALE 4 @@ -245,6 +247,7 @@ MPIHeader_t hdr; SCSIIORequest_t scsireq; SCSIIOReply_t sreply; + ConfigReply_t configreply; MPIDefaultReply_t reply; MPT_FRAME_TRACKER frame; } u; @@ -383,12 +386,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,16 +400,10 @@ ScsiCmndTracker WaitQ; ScsiCmndTracker SentQ; ScsiCmndTracker DoneQ; -//--- 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]; - u8 inq00_data[20]; - u8 pad1[4]; + u32 num_luns; + u32 luns[8]; /* Max LUNs is 256 */ + u8 pad[4]; + u8 inq_data[8]; /* IEEE Registered Extended Identifier obtained via INQUIRY VPD page 0x83 */ /* NOTE: Do not separate uniq_prepad and uniq_data @@ -417,24 +411,22 @@ u8 uniq_prepad[8]; u8 uniq_data[20]; u8 pad2[4]; - u8 inqC3_data[12]; - u8 pad3[4]; - u8 inqC9_data[12]; - u8 pad4[4]; - u8 dev_vol_name[64]; } VirtDevice; /* * 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 +#define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20 +#endif #define MPT_TARGET_NO_NEGO_WIDE 0x01 #define MPT_TARGET_NO_NEGO_SYNC 0x02 @@ -533,8 +525,12 @@ /* #define MPT_SCSICFG_BLK_NEGO 0x10 WriteSDP1 with WDTR and SDTR disabled */ typedef struct _ScsiCfgData { + u32 PortFlags; int *nvram; /* table of device NVRAM values */ IOCPage3_t *pIocPg3; /* table of physical disks */ + IOCPage4_t *pIocPg4; /* SEP devices addressing */ + dma_addr_t IocPg4_dma; /* Phys Addr of IOCPage4 data */ + int IocPg4Sz; /* IOCPage4 size */ u8 dvStatus[MPT_MAX_SCSI_DEVICES]; int isRaid; /* bit field, 1 if RAID */ u8 minSyncFactor; /* 0xFF if async */ @@ -548,7 +544,8 @@ u8 dvScheduled; /* 1 if scheduled */ u8 forceDv; /* 1 to force DV scheduling */ u8 noQas; /* Disable QAS for this adapter */ - u8 rsvd[2]; + u8 Saf_Te; /* 1 to force all Processors as SAF-TE if Inquiry data length is too short to check for SAF-TE */ + u8 rsvd[1]; } ScsiCfgData; typedef struct _fw_image { @@ -603,7 +600,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 +613,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 +659,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 +762,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) ) Index: drivers/message/fusion/mptctl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/message/fusion/mptctl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/message/fusion/mptctl.c 22 Jul 2004 19:50:24 -0000 1.1 +++ drivers/message/fusion/mptctl.c 4 Aug 2004 01:29:04 -0000 1.2 @@ -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:mpt_linux_developer@lsil.com) * - * $Id: mptctl.c,v 1.1 2004/07/22 19:50:24 joff Exp $ + * $Id: mptctl.c,v 1.2 2004/08/04 01:29:04 joff Exp $ */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -82,6 +82,7 @@ #include #include #include +#include #include #include @@ -102,7 +103,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 +139,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); /* @@ -206,14 +209,6 @@ return -EBUSY; } -#if defined(__sparc__) && defined(__sparc_v9__) /*{*/ - if (!nonblock) { - if (down_interruptible(&mptctl_syscall_sem_ioc[ioc->id])) - rc = -ERESTARTSYS; - } else { - rc = -EPERM; - } -#else if (nonblock) { if (down_trylock(&mptctl_syscall_sem_ioc[ioc->id])) rc = -EAGAIN; @@ -221,7 +216,6 @@ if (down_interruptible(&mptctl_syscall_sem_ioc[ioc->id])) rc = -ERESTARTSYS; } -#endif dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down return %d\n", rc)); return rc; } @@ -267,8 +261,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 +332,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 +517,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 +539,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 +629,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 +664,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 +704,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 +873,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 +1227,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; @@ -1259,10 +1267,10 @@ /* Fill in the data and return the structure to the calling * program */ - if (ioc->chip_type == C1030) - karg.adapterType = MPT_IOCTL_INTERFACE_SCSI; - else + if ((int)ioc->chip_type <= (int) FC929) karg.adapterType = MPT_IOCTL_INTERFACE_FC; + else + karg.adapterType = MPT_IOCTL_INTERFACE_SCSI; port = karg.hdr.port; @@ -1313,6 +1321,7 @@ /* Set the Version Strings. */ strncpy (karg.driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH); + karg.driverVersion[MPT_IOCTL_VERSION_LENGTH-1]='\0'; karg.busChangeEvent = 0; karg.hostId = ioc->pfacts[port].PortSCSIID; @@ -1353,7 +1362,8 @@ int iocnum; int numDevices = 0; unsigned int max_id; - int ii, jj, lun; + int ii, jj, indexed_lun, lun_index; + u32 lun; int maxWordsLeft; int numBytes; u8 port; @@ -1412,7 +1422,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; @@ -1427,17 +1437,18 @@ while (ii <= max_id) { if (hd->Targets[ii]) { for (jj = 0; jj <= MPT_LAST_LUN; jj++) { - lun = (1 << jj); - if (hd->Targets[ii]->luns & lun) { + lun_index = (jj >> 5); + indexed_lun = (jj % 32); + lun = (1 << indexed_lun); + if (hd->Targets[ii]->luns[lun_index] & lun) { numDevices++; *pdata = (jj << 16) | ii; --maxWordsLeft; pdata++; - if (maxWordsLeft <= 0) { + if (maxWordsLeft <= 0) break; - } } } } @@ -1514,7 +1525,9 @@ karg.chip_type = ioc->chip_type; #endif strncpy (karg.name, ioc->name, MPT_MAX_NAME); + karg.name[MPT_MAX_NAME-1]='\0'; strncpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH); + karg.product[MPT_PRODUCT_LENGTH-1]='\0'; /* Copy the data from kernel memory to user memory */ @@ -1710,7 +1723,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 +1743,7 @@ } - /* Free the old FW image + /* Free the old FW image */ if (ioc->cached_fw) { mpt_free_fw_memory(ioc, 0); @@ -1812,22 +1825,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 +1865,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 +1908,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: @@ -1933,12 +1948,14 @@ */ if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE) pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE; + else + pScsiReq->SenseBufferLength = karg.maxSenseBytes; pScsiReq->SenseBufferLowAddr = 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; } @@ -1995,6 +2011,8 @@ */ if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE) pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE; + else + pScsiReq->SenseBufferLength = karg.maxSenseBytes; pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma @@ -2006,11 +2024,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 +2047,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 +2055,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 +2080,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 +2112,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 +2129,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 +2137,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 +2157,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 +2184,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 +2192,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 +2203,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 +2227,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 +2235,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 +2327,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 +2371,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 +2382,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 +2423,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; @@ -2486,8 +2473,10 @@ cfg.physAddr = buf_dma; if (mpt_config(ioc, &cfg) == 0) { ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf; - if (strlen(pdata->BoardTracerNumber) > 1) + if (strlen(pdata->BoardTracerNumber) > 1) { strncpy(karg.serial_number, pdata->BoardTracerNumber, 24); + karg.serial_number[24-1]='\0'; + } } pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma); pbuf = NULL; @@ -2524,7 +2513,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 +2607,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 +2686,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 @@ -2720,27 +2709,36 @@ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -#if defined(__sparc__) && defined(__sparc_v9__) /*{*/ - -/* The dynamic ioctl32 compat. registry only exists in >2.3.x sparc64 kernels */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) /*{*/ +#ifdef MPT_CONFIG_COMPAT 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); -extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/* sparc32_XXX functions are used to provide a conversion between +/* compat_XXX functions are used to provide a conversion between * pointers and u32's. If the arg does not contain any pointers, then - * a specialized function (sparc32_XXX) is not needed. If the arg + * a specialized function (compat_XXX) is not needed. If the arg * does contain pointer(s), then the specialized function is used * to ensure the structure contents is properly processed by mptctl. */ static int -sparc32_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd, +compat_mptctl_ioctl(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *filp) +{ + int ret; + + lock_kernel(); + dctlprintk((KERN_INFO MYNAM "::compat_mptctl_ioctl() called\n")); + ret = mptctl_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); + unlock_kernel(); + return ret; +} + +static int +compat_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *filp) { struct mpt_fw_xfer32 kfw32; @@ -2750,7 +2748,7 @@ int nonblock = (filp->f_flags & O_NONBLOCK); int ret; - dctlprintk((KERN_INFO MYNAM "::sparc32_mptfwxfer_ioctl() called\n")); + dctlprintk((KERN_INFO MYNAM "::compat_mptfwxfer_ioctl() called\n")); if (copy_from_user(&kfw32, (char *)arg, sizeof(kfw32))) return -EFAULT; @@ -2759,7 +2757,7 @@ iocnumX = kfw32.iocnum & 0xFF; if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) || (iocp == NULL)) { - dctlprintk((KERN_ERR MYNAM "::sparc32_mptfwxfer_ioctl @%d - ioc%d not found!\n", + dctlprintk((KERN_ERR MYNAM "::compat_mptfwxfer_ioctl @%d - ioc%d not found!\n", __LINE__, iocnumX)); return -ENODEV; } @@ -2779,7 +2777,7 @@ } static int -sparc32_mpt_command(unsigned int fd, unsigned int cmd, +compat_mpt_command(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *filp) { struct mpt_ioctl_command32 karg32; @@ -2790,7 +2788,7 @@ int nonblock = (filp->f_flags & O_NONBLOCK); int ret; - dctlprintk((KERN_INFO MYNAM "::sparc32_mpt_command() called\n")); + dctlprintk((KERN_INFO MYNAM "::compat_mpt_command() called\n")); if (copy_from_user(&karg32, (char *)arg, sizeof(karg32))) return -EFAULT; @@ -2799,7 +2797,7 @@ iocnumX = karg32.hdr.iocnum & 0xFF; if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) || (iocp == NULL)) { - dctlprintk((KERN_ERR MYNAM "::sparc32_mpt_command @%d - ioc%d not found!\n", + dctlprintk((KERN_ERR MYNAM "::compat_mpt_command @%d - ioc%d not found!\n", __LINE__, iocnumX)); return -ENODEV; } @@ -2832,8 +2830,7 @@ return ret; } -#endif /*} linux >= 2.3.x */ -#endif /*} sparc */ +#endif /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ int __init mptctl_init(void) @@ -2879,33 +2876,34 @@ } } -#if defined(__sparc__) && defined(__sparc_v9__) /*{*/ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) /*{*/ - err = register_ioctl32_conversion(MPTIOCINFO, NULL); +#ifdef MPT_CONFIG_COMPAT + err = register_ioctl32_conversion(MPTIOCINFO, compat_mptctl_ioctl); + if (++where && err) goto out_fail; + err = register_ioctl32_conversion(MPTIOCINFO1, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTTARGETINFO, NULL); + err = register_ioctl32_conversion(MPTTARGETINFO, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTTEST, NULL); + err = register_ioctl32_conversion(MPTTEST, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTEVENTQUERY, NULL); + err = register_ioctl32_conversion(MPTEVENTQUERY, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTEVENTENABLE, NULL); + err = register_ioctl32_conversion(MPTEVENTENABLE, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTEVENTREPORT, NULL); + err = register_ioctl32_conversion(MPTEVENTREPORT, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTHARDRESET, NULL); + err = register_ioctl32_conversion(MPTHARDRESET, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTCOMMAND32, sparc32_mpt_command); + err = register_ioctl32_conversion(MPTCOMMAND32, compat_mpt_command); if (++where && err) goto out_fail; err = register_ioctl32_conversion(MPTFWDOWNLOAD32, - sparc32_mptfwxfer_ioctl); + compat_mptfwxfer_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(HP_GETHOSTINFO, NULL); + err = register_ioctl32_conversion(HP_GETHOSTINFO, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(HP_GETTARGETINFO, NULL); + err = register_ioctl32_conversion(HP_GETTARGETINFO, + compat_mptctl_ioctl); if (++where && err) goto out_fail; -#endif /*} linux >= 2.3.x */ -#endif /*} sparc */ +#endif /* Register this device */ err = misc_register(&mptctl_miscdev); @@ -2938,11 +2936,11 @@ out_fail: -#if defined(__sparc__) && defined(__sparc_v9__) /*{*/ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) /*{*/ +#ifdef MPT_CONFIG_COMPAT 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); @@ -2953,8 +2951,7 @@ unregister_ioctl32_conversion(MPTFWDOWNLOAD32); unregister_ioctl32_conversion(HP_GETHOSTINFO); unregister_ioctl32_conversion(HP_GETTARGETINFO); -#endif /*} linux >= 2.3.x */ -#endif /*} sparc */ +#endif for (i=0; ipriv; 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); Index: drivers/message/fusion/mptscsih.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/message/fusion/mptscsih.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/message/fusion/mptscsih.c 22 Jul 2004 19:50:24 -0000 1.1 +++ drivers/message/fusion/mptscsih.c 4 Aug 2004 01:29:04 -0000 1.2 @@ -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:mpt_linux_developer@lsil.com) * - * $Id: mptscsih.c,v 1.1 2004/07/22 19:50:24 joff Exp $ + * $Id: mptscsih.c,v 1.2 2004/08/04 01:29:04 joff Exp $ */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -174,21 +174,19 @@ 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); +static void 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); static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags); +static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus); static int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); static void mptscsih_timer_expired(unsigned long data); static void mptscsih_taskmgmt_timeout(unsigned long data); @@ -200,7 +198,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 +268,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... @@ -437,10 +439,10 @@ static inline int mptscsih_getFreeChainBuffer(MPT_SCSI_HOST *hd, int *retIndex) { - MPT_FRAME_HDR *chainBuf = NULL; + MPT_FRAME_HDR *chainBuf; unsigned long flags; - int rc = FAILED; - int chain_idx = MPT_HOST_NO_CHAIN; + int rc; + int chain_idx; spin_lock_irqsave(&hd->ioc->FreeQlock, flags); if (!Q_IS_EMPTY(&hd->FreeChainQ)) { @@ -453,6 +455,10 @@ chain_idx = offset / hd->ioc->req_sz; rc = SUCCESS; } + else { + rc = FAILED; + chain_idx = MPT_HOST_NO_CHAIN; + } spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); @@ -505,12 +511,13 @@ /* Map the data portion, if any. * sges_left = 0 if no data transfer. */ - sges_left = SCpnt->use_sg; - if (SCpnt->use_sg) { - sges_left = pci_map_sg(hd->ioc->pcidev, + if ( (sges_left = SCpnt->use_sg) ) { + if ( (sges_left = pci_map_sg(hd->ioc->pcidev, (struct scatterlist *) SCpnt->request_buffer, SCpnt->use_sg, - scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); + scsi_to_pci_dma_dir(SCpnt->sc_data_direction))) + == 0 ) + return FAILED; } else if (SCpnt->request_bufflen) { dma_addr_t buf_dma_addr; scPrivate *my_priv; @@ -729,13 +736,6 @@ hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; - if ((mf == NULL) || - (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) { - printk(MYIOC_s_ERR_FMT "%s req frame ptr! (=%p)!\n", - ioc->name, mf?"BAD":"NULL", (void *) mf); - return 0; - } - req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); sc = hd->ScsiLookup[req_idx]; if (sc == NULL) { @@ -743,9 +743,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 +763,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 +794,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; @@ -860,7 +877,6 @@ mptscsih_no_negotiate(hd, sc->target); break; - case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ /* * YIKES! I just discovered that SCSI IO which @@ -871,9 +887,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) { @@ -901,6 +914,9 @@ sc->resid = sc->request_bufflen - xfer_cnt; dprintk((KERN_NOTICE " SET sc->resid=%02xh\n", sc->resid)); #endif + if((xfer_cnt == 0 ) || (sc->underflow > xfer_cnt)) { + sc->result = DID_SOFT_ERROR << 16; + } /* Report Queue Full */ @@ -915,7 +931,7 @@ && xfer_cnt >= SCSI_STD_INQUIRY_BYTES ) { mptscsih_initTarget(hd, - hd->port, + sc->channel, sc->target, pScsiReq->LUN[1], sc->buffer, @@ -926,9 +942,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 +1012,7 @@ && xfer_cnt >= SCSI_STD_INQUIRY_BYTES ) { mptscsih_initTarget(hd, - hd->port, + sc->channel, sc->target, pScsiReq->LUN[1], sc->buffer, @@ -1024,6 +1037,7 @@ case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */ case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */ case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */ + case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */ default: /* @@ -1144,8 +1158,8 @@ static void clean_taskQ(MPT_SCSI_HOST *hd) { - MPT_FRAME_HDR *mf = NULL; - MPT_FRAME_HDR *nextmf = NULL; + MPT_FRAME_HDR *mf; + MPT_FRAME_HDR *nextmf; MPT_ADAPTER *ioc = hd->ioc; unsigned long flags; @@ -1184,7 +1198,7 @@ static void search_taskQ_for_cmd(Scsi_Cmnd *sc, MPT_SCSI_HOST *hd) { - MPT_FRAME_HDR *mf = NULL; + MPT_FRAME_HDR *mf; unsigned long flags; int count = 0; @@ -1238,7 +1252,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 +1319,22 @@ return; } +static void +mptscsih_reset_timeouts (MPT_SCSI_HOST *hd) +{ + Scsi_Cmnd *SCpnt; + 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. @@ -1318,8 +1348,9 @@ static void mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) { - Scsi_Cmnd *SCpnt = NULL; - MPT_FRAME_HDR *mf = NULL; + Scsi_Cmnd *SCpnt; + MPT_FRAME_HDR *mf; + MPT_DONE_Q *buffer; int ii; int max = hd->ioc->req_depth; @@ -1333,7 +1364,6 @@ /* Command found. */ - #ifndef MPT_SCSI_USE_NEW_EH /* Search taskQ, if found, delete. */ @@ -1352,11 +1382,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 +1400,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 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -1473,18 +1459,16 @@ /* ReqToChain size must equal the req_depth * index = req_idx */ - sz = hd->ioc->req_depth * sizeof(int); if (hd->ReqToChain == NULL) { + sz = hd->ioc->req_depth * sizeof(int); mem = kmalloc(sz, GFP_ATOMIC); if (mem == NULL) return -1; hd->ReqToChain = (int *) mem; - } else { - mem = (u8 *) hd->ReqToChain; } - memset(mem, 0xFF, sz); - + for (ii = 0; ii < hd->ioc->req_depth; ii++) + hd->ReqToChain[ii] = MPT_HOST_NO_CHAIN; /* ChainToChain size must equal the total number * of chain buffers to be allocated. @@ -1622,14 +1606,15 @@ int mptscsih_detect(Scsi_Host_Template *tpnt) { - struct Scsi_Host *sh = NULL; - MPT_SCSI_HOST *hd = NULL; - MPT_ADAPTER *this; + struct Scsi_Host *sh; + MPT_SCSI_HOST *hd; + MPT_ADAPTER *ioc; MPT_DONE_Q *freedoneQ; unsigned long flags; int sz, ii; int numSGE = 0; int scale; + int ioc_cap; u8 *mem; if (! BeenHereDoneThat++) { @@ -1666,269 +1651,291 @@ atomic_set(&mpt_taskQdepth, 0); #endif - this = mpt_adapter_find_first(); - while (this != NULL) { - int portnum; - for (portnum=0; portnum < this->facts.NumberOfPorts; portnum++) { - - /* 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; - } + for (ioc = mpt_adapter_find_first(); ioc != NULL; ioc = mpt_adapter_find_next(ioc)) { + /* 20010202 -sralston + * Added sanity check on readiness of the MPT adapter. + */ + if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) { + printk(MYIOC_s_WARN_FMT "Skipping because it's not operational!\n", + ioc->name); + continue; + } + + if (!ioc->active) { + printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n", + ioc->name); + continue; + } + + + /* Sanity check - ensure at least 1 port is INITIATOR capable + */ + ioc_cap = 0; + for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { + if (ioc->pfacts[ii].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) + ioc_cap ++; + } + + if (!ioc_cap) { + printk(MYIOC_s_WARN_FMT "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", + ioc->name, ioc); + 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(&ioc->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)ioc->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 = ioc->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 = ioc->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 = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32)); + if (sizeof(dma_addr_t) == sizeof(u64)) { + numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale + + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32)); + } else { + numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale + + (ioc->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", + ioc->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, ioc->pcidev); - if ((int)this->chip_type > (int)FC929) - hd->is_spi = 1; + spin_unlock_irqrestore(&ioc->FreeQlock, flags); - if (DmpService && - (this->chip_type == FC919 || this->chip_type == FC929)) - hd->is_multipath = 1; + hd = (MPT_SCSI_HOST *) sh->hostdata; + hd->ioc = ioc; + hd->max_sge = sh->sg_tablesize; - hd->port = 0; /* FIXME! */ + if ((int)ioc->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 && + (ioc->chip_type == FC919 || ioc->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", + ioc->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; + hd->resetPending = 0; + hd->abortSCpnt = NULL; + hd->tmPtr = NULL; + hd->numTMrequests = 0; - /* Attach the SCSI Host to the IOC structure - */ - this->sh = sh; + /* Clear the pointer used to store + * single-threaded commands, i.e., those + * issued during a bus scan, dv and + * configuration pages. + */ + hd->cmdPtr = NULL; - /* 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; + /* Attach the SCSI Host to the IOC structure + */ + ioc->sh = sh; - init_timer(&hd->TMtimer); - hd->TMtimer.data = (unsigned long) hd; - hd->TMtimer.function = mptscsih_taskmgmt_timeout; - hd->qtag_tick = jiffies; + /* 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 */ + /* ioc->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 - /* Moved Earlier Pam D */ - /* this->sh = sh; */ + 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->ioc->spi_data.Saf_Te = driver_setup.saf_te; - 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 saf_te %x\n", + hd->ioc->name, driver_setup.dv, + driver_setup.max_width, + driver_setup.min_sync_fac, + driver_setup.saf_te)); } - } /* for each adapter port */ - - this = mpt_adapter_find_next(this); + mpt_scsi_hosts++; + } } done: @@ -2139,8 +2146,8 @@ static int mptscsih_halt(struct notifier_block *nb, ulong event, void *buf) { - MPT_ADAPTER *ioc = NULL; - MPT_SCSI_HOST *hd = NULL; + MPT_ADAPTER *ioc; + MPT_SCSI_HOST *hd; /* Ignore all messages other than reboot message */ @@ -2175,7 +2182,7 @@ const char * mptscsih_info(struct Scsi_Host *SChost) { - MPT_SCSI_HOST *h = NULL; + MPT_SCSI_HOST *h; int size = 0; if (info_kbuf == NULL) @@ -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 + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** @@ -2273,7 +2398,7 @@ int mptscsih_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int func) { - MPT_ADAPTER *ioc = NULL; + MPT_ADAPTER *ioc; MPT_SCSI_HOST *hd = NULL; int size = 0; @@ -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. @@ -2377,7 +2489,7 @@ MPT_FRAME_HDR *mf; SCSIIORequest_t *pScsiReq; VirtDevice *pTarget; - MPT_DONE_Q *buffer = NULL; + MPT_DONE_Q *buffer; unsigned long flags; int target; int lun; @@ -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); @@ -2711,7 +2774,7 @@ static void mptscsih_freeChainBuffers(MPT_SCSI_HOST *hd, int req_idx) { - MPT_FRAME_HDR *chain = NULL; + MPT_FRAME_HDR *chain; unsigned long flags; int chain_idx; int next; @@ -2774,9 +2837,9 @@ * 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; + MPT_ADAPTER *ioc; int rc = -1; int doTask = 1; u32 ioc_raw_state; @@ -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)); @@ -2991,26 +3088,12 @@ search_doneQ_for_cmd(hd, SCpnt); SCpnt->result = DID_RESET << 16; - SCpnt->scsi_done(SCpnt); nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: " "Command not in the active list! (sc=%p)\n", hd->ioc->name, SCpnt)); 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 +3102,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 +3118,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 +3161,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 +3217,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 +3298,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 +3311,8 @@ break; } spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); + //set_current_state(TASK_INTERRUPTIBLE); + //schedule_timeout(HZ/4); mdelay(250); } while (--loop_count); @@ -3282,7 +3344,6 @@ if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL) { printk(KERN_WARNING " WARNING - OldAbort, NULL hostdata ptr!!\n"); SCpnt->result = DID_ERROR << 16; - SCpnt->scsi_done(SCpnt); return SCSI_ABORT_NOT_RUNNING; } @@ -3296,18 +3357,19 @@ */ search_doneQ_for_cmd(hd, SCpnt); - SCpnt->result = DID_RESET << 16; - SCpnt->scsi_done(SCpnt); + SCpnt->result = DID_ABORT << 16; return SCSI_ABORT_SUCCESS; } else { /* If this command is pended, then timeout/hang occurred * during DV. Force bus reset by posting command to F/W * and then following up with the reset request. */ +#ifndef MPTSCSIH_DBG_TIMEOUT if ((mf = mptscsih_search_pendingQ(hd, scpnt_idx)) != NULL) { mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf); post_pendingQ_commands(hd); } +#endif } /* @@ -3379,10 +3441,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); @@ -3417,8 +3475,7 @@ printk(KERN_WARNING " IOs outstanding = %d\n", atomic_read(&queue_depth)); if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL) { - SCpnt->result = DID_RESET << 16; - SCpnt->scsi_done(SCpnt); + SCpnt->result = DID_ERROR << 16; return SCSI_RESET_SUCCESS; } @@ -3433,17 +3490,18 @@ search_doneQ_for_cmd(hd, SCpnt); SCpnt->result = DID_RESET << 16; - SCpnt->scsi_done(SCpnt); return SCSI_RESET_SUCCESS; } else { /* If this command is pended, then timeout/hang occurred * during DV. Force bus reset by posting command to F/W * and then following up with the reset request. */ +#ifndef MPTSCSIH_DBG_TIMEOUT if ((mf = mptscsih_search_pendingQ(hd, scpnt_idx)) != NULL) { mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf); post_pendingQ_commands(hd); } +#endif } /* @@ -3567,6 +3625,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 +3726,12 @@ 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) { +#ifndef MPTSCSIH_DBG_TIMEOUT + post_pendingQ_commands(hd); +#endif + 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. @@ -3714,7 +3786,7 @@ { SCSITaskMgmtReply_t *pScsiTmReply; SCSITaskMgmt_t *pScsiTmReq; - MPT_SCSI_HOST *hd = NULL; + MPT_SCSI_HOST *hd; unsigned long flags; u8 tmType = 0; @@ -3765,10 +3837,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 +3871,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 +3898,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 +3920,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 +3962,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) { + dprintk((MYIOC_s_INFO_FMT + "scsi%d: Id=%d Lun=%d: Queue depth=%d\n", + hd->ioc->name, + 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 +4015,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))) { @@ -4050,11 +4043,10 @@ thisIo.SCSIStatus = pScsiReply->SCSIStatus; thisIo.DoDisplay = 1; if (hd->is_multipath) - sprintf(devFoo, "%d:%d:%d \"%s\"", + sprintf(devFoo, "%d:%d:%d", hd->ioc->id, pReq->TargetID, - pReq->LUN[1], - target->dev_vol_name); + pReq->LUN[1]); else sprintf(devFoo, "%d:%d:%d", hd->ioc->id, sc->target, sc->lun); thisIo.DevIDStr = devFoo; @@ -4111,7 +4103,7 @@ unsigned long flags; MPT_DONE_Q *buffer; MPT_FRAME_HDR *mf = NULL; - MPT_FRAME_HDR *cmdMfPtr = NULL; + MPT_FRAME_HDR *cmdMfPtr; ddvtprintk((MYIOC_s_INFO_FMT ": search_pendingQ ...", hd->ioc->name)); cmdMfPtr = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx); @@ -4199,12 +4191,13 @@ static int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) { - MPT_SCSI_HOST *hd = NULL; + MPT_SCSI_HOST *hd; unsigned long flags; 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 +4208,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 +4257,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; + ScsiCfgData *pSpi; - 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 +4325,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 +4789,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. */ @@ -4980,13 +4972,12 @@ * Allocate and initialize memory for this target. * Save inquiry data. * - * Returns pointer to VirtDevice structure. */ -static VirtDevice * +static void mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen) { + int indexed_lun, lun_index; VirtDevice *vdev; - int sz; dprintk((MYIOC_s_INFO_FMT "initTarget (%d,%d,%d) called, hd=%p\n", hd->ioc->name, bus_id, target_id, lun, hd)); @@ -4995,6 +4986,7 @@ if ((vdev = kmalloc(sizeof(VirtDevice), GFP_ATOMIC)) == NULL) { printk(MYIOC_s_ERR_FMT "initTarget kmalloc(%d) FAILED!\n", hd->ioc->name, (int)sizeof(VirtDevice)); + return; } else { memset(vdev, 0, sizeof(VirtDevice)); rwlock_init(&vdev->VdevLock); @@ -5013,24 +5005,44 @@ } vdev->raidVolume = 0; - if (vdev && hd->is_spi) { + if (hd->is_spi) { if (hd->ioc->spi_data.isRaid & (1 << target_id)) { vdev->raidVolume = 1; ddvtprintk((KERN_INFO "RAID Volume @ id %d\n", target_id)); } } - if (vdev && data) { - if ((!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) || - ((dlen > 56) && (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56)))) { - - /* Copy the inquiry data - if we haven't yet. - */ - sz = MIN(dlen, SCSI_STD_INQUIRY_BYTES); + if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) { + /* Copy the inquiry data - if we haven't yet. + */ - memcpy (vdev->inq_data, data, sz); + memcpy (vdev->inq_data, data, 8); + + if ( (data[0] == SCSI_TYPE_PROC) && + !(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) { + if ( dlen > 49 ) { + vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; + if ( data[44] == 'S' && + data[45] == 'A' && + data[46] == 'F' && + data[47] == '-' && + data[48] == 'T' && + data[49] == 'E' ) { + vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; + mptscsih_writeIOCPage4(hd, target_id, bus_id); + } + } else { + /* Treat all Processors as SAF-TE if + * command line option is set */ + if ( hd->ioc->spi_data.Saf_Te ) { + vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; + mptscsih_writeIOCPage4(hd, target_id, bus_id); + } + } + } else vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; + if ((dlen > 56) && (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) { /* Update the target capabilities */ if (dlen > 56) { @@ -5047,17 +5059,19 @@ pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV; } } - - /* Is LUN supported? If so, upper 3 bits will be 0 - * in first byte of inquiry data. - */ - if ((*data & 0xe0) == 0) - vdev->luns |= (1 << lun); } + /* Is LUN supported? If so, upper 3 bits will be 0 + * in first byte of inquiry data. + */ + if ((*data & 0xe0) == 0) { + lun_index = (lun >> 5); /* 32 luns per lun_index */ + indexed_lun = (lun % 32); + vdev->luns[lun_index] |= (1 << indexed_lun); + } dprintk((KERN_INFO " target = %p\n", vdev)); - return vdev; + return; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -5072,14 +5086,14 @@ int id = (int) target->target_id; int nvram; char canQ = 0; + VirtDevice *vdev; + int ii; u8 width = MPT_NARROW; u8 factor = MPT_ASYNC; u8 offset = 0; u8 version, nfactor; u8 noQas = 1; - ddvtprintk((KERN_INFO "set Target: (id %d) byte56 0x%x\n", id, byte56)); - if (!hd->is_spi) { if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) { if (target->inq_data[7] & 0x02) @@ -5087,6 +5101,14 @@ } return; } + + target->negoFlags = pspi_data->noQas; + + /* 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. + */ + /* Set flags based on Inquiry data */ if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) { @@ -5109,6 +5131,7 @@ factor = MPT_ULTRA160; else factor = MPT_ULTRA320; + offset = pspi_data->maxSyncOffset; /* If RAID, never disable QAS * else if non RAID, do not disable @@ -5118,8 +5141,6 @@ */ if ((target->raidVolume == 1) || ((byte56 & 0x02) != 0)) noQas = 0; - - offset = pspi_data->maxSyncOffset; } else { factor = MPT_ASYNC; offset = 0; @@ -5178,61 +5199,38 @@ /* Disable unused features. */ - target->negoFlags = pspi_data->noQas; if (!width) target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE; if (!offset) target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC; - if (noQas) - target->negoFlags |= MPT_TARGET_NO_NEGO_QAS; - /* GEM, processor WORKAROUND */ - if (((target->inq_data[0] & 0x1F) == 0x03) || ((target->inq_data[0] & 0x1F) > 0x08)){ + if (((target->inq_data[0] & 0x1F) == 0x03) || ((target->inq_data[0] & 0x1F) > 0x08)) { target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC); pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO; - } - - /* Disable QAS if mixed configuration case - */ - if ((noQas) && (!pspi_data->noQas) && ((target->inq_data[0] & 0x1F) == 0x00)){ - VirtDevice *vdev; - int ii; - - ddvtprintk((KERN_INFO "Disabling QAS!\n")); - pspi_data->noQas = MPT_TARGET_NO_NEGO_QAS; - for (ii = 0; ii < id; ii++) { - vdev = hd->Targets[id]; - if (vdev != NULL) - vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS; + } else { + if (noQas && (pspi_data->noQas == 0)) { + pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS; + target->negoFlags |= MPT_TARGET_NO_NEGO_QAS; + + /* Disable QAS in a mixed configuration case + */ + +// ddvtprintk((KERN_INFO "Disabling QAS!\n")); + for (ii = 0; ii < id; ii++) { + if ( (vdev = hd->Targets[ii]) ) { + 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). @@ -5351,9 +5349,9 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags) { MPT_ADAPTER *ioc = hd->ioc; - Config_t *pReq = NULL; - SCSIDevicePage1_t *pData = NULL; - VirtDevice *pTarget = NULL; + Config_t *pReq; + SCSIDevicePage1_t *pData; + VirtDevice *pTarget; MPT_FRAME_HDR *mf; dma_addr_t dataDma; u16 req_idx; @@ -5449,7 +5447,6 @@ factor = pTarget->minSyncFactor; offset = pTarget->maxOffset; negoFlags = pTarget->negoFlags; - pTarget = NULL; } if (flags & MPT_SCSICFG_BLK_NEGO) @@ -5532,6 +5529,86 @@ } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* mptscsih_writeIOCPage4 - write IOC Page 4 + * @hd: Pointer to a SCSI Host Structure + * @target_id: write IOC Page4 for this ID & Bus + * + * Return: -EAGAIN if unable to obtain a Message Frame + * or 0 if success. + * + * Remark: We do not wait for a return, write pages sequentially. + */ +static int +mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus) +{ + MPT_ADAPTER *ioc = hd->ioc; + Config_t *pReq; + IOCPage4_t *IOCPage4Ptr; + MPT_FRAME_HDR *mf; + dma_addr_t dataDma; + u16 req_idx; + u32 frameOffset; + u32 flagsLength; + int ii; + + /* Get a MF for this command. + */ + if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc->id)) == NULL) { + dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n", + ioc->name)); + return -EAGAIN; + } + + ddvprintk((MYIOC_s_INFO_FMT "writeIOCPage4 (mf=%p, id=%d)\n", + ioc->name, mf, target_id)); + + /* Set the request and the data pointers. + * Place data at end of MF. + */ + pReq = (Config_t *)mf; + + req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); + frameOffset = ioc->req_sz - sizeof(IOCPage4_t); + + /* Complete the request frame (same for all requests). + */ + pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; + pReq->Reserved = 0; + pReq->ChainOffset = 0; + pReq->Function = MPI_FUNCTION_CONFIG; + pReq->Reserved1[0] = 0; + pReq->Reserved1[1] = 0; + pReq->Reserved1[2] = 0; + pReq->MsgFlags = 0; + for (ii=0; ii < 8; ii++) { + pReq->Reserved2[ii] = 0; + } + + IOCPage4Ptr = ioc->spi_data.pIocPg4; + dataDma = ioc->spi_data.IocPg4_dma; + ii = IOCPage4Ptr->ActiveSEP++; + IOCPage4Ptr->SEP[ii].SEPTargetID = target_id; + IOCPage4Ptr->SEP[ii].SEPBus = bus; + pReq->Header = IOCPage4Ptr->Header; + pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 )); + + /* Add a SGE to the config request. + */ + flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | + (IOCPage4Ptr->Header.PageLength + ii) * 4; + + mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma); + + dsprintk((MYIOC_s_INFO_FMT + "writeIOCPage4: pgaddr 0x%x\n", + ioc->name, (target_id | (bus<<8)))); + + mptscsih_put_msgframe(ScsiDoneCtx, ioc->id, mf); + + return 0; +} + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* mptscsih_taskmgmt_timeout - Call back for timeout on a * task management request. * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long @@ -5634,10 +5711,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 +5761,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 +5775,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 +5857,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 +5866,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 @@ -6170,7 +6232,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum) { MPT_ADAPTER *ioc= hd->ioc; - VirtDevice *pTarget = NULL; + VirtDevice *pTarget; SCSIDevicePage1_t *pcfg1Data = NULL; INTERNAL_CMD iocmd; CONFIGPARMS cfg; @@ -6178,7 +6240,8 @@ ConfigPageHeader_t header1; int bus = 0; int id = 0; - int lun = 0; + int lun; + int indexed_lun, lun_index; int hostId = ioc->pfacts[portnum].PortSCSIID; int max_id; int requested, configuration, data; @@ -6269,12 +6332,13 @@ /* If target Ptr NULL or if this target is NOT a disk, skip. */ - // if (pTarget && ((pTarget->inq_data[0] & 0x1F) == 0)) { if ((pTarget) && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)){ for (lun=0; lun <= MPT_LAST_LUN; lun++) { /* If LUN present, issue the command */ - if (pTarget->luns & (1<> 5); /* 32 luns per lun_index */ + indexed_lun = (lun % 32); + if (pTarget->luns[lun_index] & (1<Targets == NULL) @@ -6524,15 +6588,15 @@ * 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; - SCSIDevicePage1_t *pcfg1Data = NULL; - SCSIDevicePage0_t *pcfg0Data = NULL; - u8 *pbuf1 = NULL; - u8 *pbuf2 = NULL; - u8 *pDvBuf = NULL; + VirtDevice *pTarget; + SCSIDevicePage1_t *pcfg1Data; + SCSIDevicePage0_t *pcfg0Data; + u8 *pbuf1; + u8 *pbuf2; + u8 *pDvBuf; dma_addr_t dvbuf_dma = -1; dma_addr_t buf1_dma = -1; dma_addr_t buf2_dma = -1; @@ -6552,6 +6616,7 @@ int patt; int repeat; int retcode = 0; + int nfactor = MPT_ULTRA320; char firstPass = 1; char doFallback = 0; char readPage0; @@ -6564,11 +6629,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 +6741,34 @@ /* 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) || + (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) { + + 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 +6890,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 +6907,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 @@ -6904,6 +7018,9 @@ if (inq0 != 0) goto target_done; + if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY ) + goto target_done; + /* Start the Enhanced Test. * 0) issue TUR to clear out check conditions * 1) read capacity of echo (regular) buffer @@ -7320,19 +7437,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 @@ -7363,9 +7477,9 @@ static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) { - VirtDevice *pTarget = NULL; - SCSIDevicePage0_t *pPage0 = NULL; - SCSIDevicePage1_t *pPage1 = NULL; + VirtDevice *pTarget; + SCSIDevicePage0_t *pPage0; + SCSIDevicePage1_t *pPage1; int val = 0, data, configuration; u8 width = 0; u8 offset = 0; @@ -7748,9 +7862,9 @@ /* Commandline Parsing routines and defines. * * insmod format: - * insmod mptscsih mptscsih="width:1 dv:n factor:0x09" + * insmod mptscsih mptscsih="width:1 dv:n factor:0x09 saf-te:1" * boot format: - * mptscsih=width:1,dv:n,factor:0x8 + * mptscsih=width:1,dv:n,factor:0x8,saf-te:1 * */ #ifdef MODULE @@ -7763,11 +7877,13 @@ "dv:" "width:" "factor:" - ; /* DONNOT REMOVE THIS ';' */ + "saf-te:" + ; /* DO NOT REMOVE THIS ';' */ #define OPT_DV 1 #define OPT_MAX_WIDTH 2 #define OPT_MIN_SYNC_FACTOR 3 +#define OPT_SAF_TE 4 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static int @@ -7824,6 +7940,10 @@ driver_setup.min_sync_fac = val; break; + case OPT_SAF_TE: + driver_setup.saf_te = val; + break; + default: printk("mptscsih_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur); break; Index: drivers/message/fusion/mptscsih.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/message/fusion/mptscsih.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/message/fusion/mptscsih.h 22 Jul 2004 19:50:24 -0000 1.1 +++ drivers/message/fusion/mptscsih.h 4 Aug 2004 01:29:04 -0000 1.2 @@ -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:mpt_linux_developer@lsil.com) * - * $Id: mptscsih.h,v 1.1 2004/07/22 19:50:24 joff Exp $ + * $Id: mptscsih.h,v 1.2 2004/08/04 01:29:04 joff 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 @@ -116,12 +116,14 @@ #define MPTSCSIH_DOMAIN_VALIDATION 1 #define MPTSCSIH_MAX_WIDTH 1 #define MPTSCSIH_MIN_SYNC 0x08 +#define MPTSCSIH_SAF_TE 0 struct mptscsih_driver_setup { u8 dv; u8 max_width; u8 min_sync_fac; + u8 saf_te; }; @@ -130,6 +132,7 @@ MPTSCSIH_DOMAIN_VALIDATION, \ MPTSCSIH_MAX_WIDTH, \ MPTSCSIH_MIN_SYNC, \ + MPTSCSIH_SAF_TE, \ } @@ -217,11 +220,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 +240,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 +277,6 @@ .use_new_eh_code = 1 \ } -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1) */ - #else /* MPT_SCSI_USE_NEW_EH */ #define MPT_SCSIHOST { \ Index: drivers/message/fusion/scsi3.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/message/fusion/scsi3.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/message/fusion/scsi3.h 22 Jul 2004 19:50:24 -0000 1.1 +++ drivers/message/fusion/scsi3.h 4 Aug 2004 01:29:04 -0000 1.2 @@ -7,9 +7,9 @@ * Copyright (c) 1996-2002 Steven J. Ralston * Written By: Steven J. Ralston (19960517) * (mailto:sjralston1@netscape.net) - * (mailto:Pam.Delaney@lsil.com) + * (mailto:mpt_linux_developer@lsil.com) * - * $Id: scsi3.h,v 1.1 2004/07/22 19:50:24 joff Exp $ + * $Id: scsi3.h,v 1.2 2004/08/04 01:29:04 joff Exp $ */ #ifndef SCSI3_H_INCLUDED Index: drivers/message/fusion/lsi/fc_log.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/message/fusion/lsi/fc_log.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/message/fusion/lsi/fc_log.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/message/fusion/lsi/fc_log.h 4 Aug 2004 01:29:04 -0000 1.2 @@ -7,7 +7,7 @@ * in the IOCLogInfo field of a MPI Default Reply Message. * * CREATION DATE: 6/02/2000 - * ID: $Id: fc_log.h,v 1.1 2004/07/22 19:50:25 joff Exp $ + * ID: $Id: fc_log.h,v 1.2 2004/08/04 01:29:04 joff Exp $ */ Index: drivers/message/fusion/lsi/mpi.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/message/fusion/lsi/mpi.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/message/fusion/lsi/mpi.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/message/fusion/lsi/mpi.h 4 Aug 2004 01:29:04 -0000 1.2 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2002 LSI Logic Corporation. + * Copyright (c) 2000-2003 LSI Logic Corporation. * * * Name: MPI.H * Title: MPI Message independent structures and definitions * Creation Date: July 27, 2000 * - * MPI.H Version: 01.02.07 + * MPI.H Version: 01.02.10 * * Version History * --------------- @@ -48,6 +48,10 @@ * 05-31-02 01.02.05 Bumped MPI_HEADER_VERSION_UNIT. * 07-12-02 01.02.06 Added define for MPI_FUNCTION_MAILBOX. * 09-16-02 01.02.07 Bumped value for MPI_HEADER_VERSION_UNIT. + * 11-15-02 01.02.08 Added define MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX and + * obsoleted define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX. + * 04-01-03 01.02.09 New IOCStatus code: MPI_IOCSTATUS_FC_EXCHANGE_CANCELED + * 06-26-03 01.02.10 Bumped MPI_HEADER_VERSION_UNIT value. * -------------------------------------------------------------------------- */ @@ -76,7 +80,7 @@ /* Note: The major versions of 0xe0 through 0xff are reserved */ /* versioning for this MPI header set */ -#define MPI_HEADER_VERSION_UNIT (0x09) +#define MPI_HEADER_VERSION_UNIT (0x0C) #define MPI_HEADER_VERSION_DEV (0x00) #define MPI_HEADER_VERSION_UNIT_MASK (0xFF00) #define MPI_HEADER_VERSION_UNIT_SHIFT (8) @@ -618,7 +622,8 @@ #define MPI_IOCSTATUS_TARGET_PRIORITY_IO (0x0060) #define MPI_IOCSTATUS_TARGET_INVALID_PORT (0x0061) -#define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX (0x0062) +#define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX (0x0062) /* obsolete */ +#define MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX (0x0062) #define MPI_IOCSTATUS_TARGET_ABORTED (0x0063) #define MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE (0x0064) #define MPI_IOCSTATUS_TARGET_NO_CONNECTION (0x0065) @@ -642,6 +647,7 @@ #define MPI_IOCSTATUS_FC_RX_ID_INVALID (0x0067) #define MPI_IOCSTATUS_FC_DID_INVALID (0x0068) #define MPI_IOCSTATUS_FC_NODE_LOGGED_OUT (0x0069) +#define MPI_IOCSTATUS_FC_EXCHANGE_CANCELED (0x006C) /****************************************************************************/ /* LAN values */ Index: drivers/message/fusion/lsi/mpi_cnfg.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/message/fusion/lsi/mpi_cnfg.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/message/fusion/lsi/mpi_cnfg.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/message/fusion/lsi/mpi_cnfg.h 4 Aug 2004 01:29:04 -0000 1.2 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2002 LSI Logic Corporation. + * Copyright (c) 2000-2003 LSI Logic Corporation. * * * Name: MPI_CNFG.H * Title: MPI Config message, structures, and Pages * Creation Date: July 27, 2000 * - * MPI_CNFG.H Version: 01.02.09 + * MPI_CNFG.H Version: 01.02.12 * * Version History * --------------- @@ -127,7 +127,24 @@ * MPI_SCSIDEVPAGE1_CONF_EXTENDED_PARAMS_ENABLE. * Added new config page: CONFIG_PAGE_SCSI_DEVICE_3. * Modified MPI_FCPORTPAGE5_FLAGS_ defines. - * 09-16-02 01.02.09 Added more MPI_SCSIDEVPAGE1_CONF_FORCE_PPR_MSG define. + * 09-16-02 01.02.09 Added MPI_SCSIDEVPAGE1_CONF_FORCE_PPR_MSG define. + * 11-15-02 01.02.10 Added ConnectedID defines for CONFIG_PAGE_SCSI_PORT_0. + * Added more Flags defines for CONFIG_PAGE_FC_PORT_1. + * Added more Flags defines for CONFIG_PAGE_FC_DEVICE_0. + * 04-01-03 01.02.11 Added RR_TOV field and additional Flags defines for + * CONFIG_PAGE_FC_PORT_1. + * Added define MPI_FCPORTPAGE5_FLAGS_DISABLE to disable + * an alias. + * Added more device id defines. + * 06-26-03 01.02.12 Added MPI_IOUNITPAGE1_IR_USE_STATIC_VOLUME_ID define. + * Added TargetConfig and IDConfig fields to + * CONFIG_PAGE_SCSI_PORT_1. + * Added more PortFlags defines for CONFIG_PAGE_SCSI_PORT_2 + * to control DV. + * Added more Flags defines for CONFIG_PAGE_FC_PORT_1. + * In CONFIG_PAGE_FC_DEVICE_0, replaced Reserved1 field + * with ADISCHardALPA. + * Added MPI_FC_DEVICE_PAGE0_PROT_FCP_RETRY define. * -------------------------------------------------------------------------- */ @@ -281,6 +298,9 @@ /**************************************************************************** * Manufacturing Config pages ****************************************************************************/ +#define MPI_MANUFACTPAGE_VENDORID_LSILOGIC (0x1000) +#define MPI_MANUFACTPAGE_VENDORID_TREBIA (0x1783) + #define MPI_MANUFACTPAGE_DEVICEID_FC909 (0x0621) #define MPI_MANUFACTPAGE_DEVICEID_FC919 (0x0624) #define MPI_MANUFACTPAGE_DEVICEID_FC929 (0x0622) @@ -299,6 +319,10 @@ #define MPI_MANUFACTPAGE_DEVID_SA2020 (0x0806) #define MPI_MANUFACTPAGE_DEVID_SA2020ZC (0x0807) +#define MPI_MANUFACTPAGE_DEVID_SNP1000 (0x0010) +#define MPI_MANUFACTPAGE_DEVID_SNP500 (0x0020) + + typedef struct _CONFIG_PAGE_MANUFACTURING_0 { @@ -422,6 +446,7 @@ #define MPI_IOUNITPAGE1_SINGLE_FUNCTION (0x00000001) #define MPI_IOUNITPAGE1_MULTI_PATHING (0x00000002) #define MPI_IOUNITPAGE1_SINGLE_PATHING (0x00000000) +#define MPI_IOUNITPAGE1_IR_USE_STATIC_VOLUME_ID (0x00000004) #define MPI_IOUNITPAGE1_DISABLE_IR (0x00000040) #define MPI_IOUNITPAGE1_FORCE_32 (0x00000080) @@ -694,6 +719,10 @@ #define MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD (0x01) #define MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE (0x02) #define MPI_SCSIPORTPAGE0_PHY_SIGNAL_LVD (0x03) +#define MPI_SCSIPORTPAGE0_PHY_MASK_CONNECTED_ID (0xFF000000) +#define MPI_SCSIPORTPAGE0_PHY_SHIFT_CONNECTED_ID (24) +#define MPI_SCSIPORTPAGE0_PHY_BUS_FREE_CONNECTED_ID (0xFE) +#define MPI_SCSIPORTPAGE0_PHY_UNKNOWN_CONNECTED_ID (0xFF) typedef struct _CONFIG_PAGE_SCSI_PORT_1 @@ -701,14 +730,22 @@ fCONFIG_PAGE_HEADER Header; /* 00h */ U32 Configuration; /* 04h */ U32 OnBusTimerValue; /* 08h */ + U8 TargetConfig; /* 0Ch */ + U8 Reserved1; /* 0Dh */ + U16 IDConfig; /* 0Eh */ } fCONFIG_PAGE_SCSI_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_1, SCSIPortPage1_t, MPI_POINTER pSCSIPortPage1_t; #define MPI_SCSIPORTPAGE1_PAGEVERSION (0x02) +/* Configuration values */ #define MPI_SCSIPORTPAGE1_CFG_PORT_SCSI_ID_MASK (0x000000FF) #define MPI_SCSIPORTPAGE1_CFG_PORT_RESPONSE_ID_MASK (0xFFFF0000) +/* TargetConfig values */ +#define MPI_SCSIPORTPAGE1_TARGCONFIG_TARG_ONLY (0x01) +#define MPI_SCSIPORTPAGE1_TARGCONFIG_INIT_TARG (0x02) + typedef struct _MPI_DEVICE_INFO { @@ -727,13 +764,20 @@ } fCONFIG_PAGE_SCSI_PORT_2, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_2, SCSIPortPage2_t, MPI_POINTER pSCSIPortPage2_t; -#define MPI_SCSIPORTPAGE2_PAGEVERSION (0x01) +#define MPI_SCSIPORTPAGE2_PAGEVERSION (0x02) +/* PortFlags values */ #define MPI_SCSIPORTPAGE2_PORT_FLAGS_SCAN_HIGH_TO_LOW (0x00000001) #define MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET (0x00000004) #define MPI_SCSIPORTPAGE2_PORT_FLAGS_ALTERNATE_CHS (0x00000008) #define MPI_SCSIPORTPAGE2_PORT_FLAGS_TERMINATION_DISABLE (0x00000010) +#define MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK (0x00000060) +#define MPI_SCSIPORTPAGE2_PORT_FLAGS_FULL_DV (0x00000000) +#define MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY (0x00000020) +#define MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV (0x00000060) + +/* PortSettings values */ #define MPI_SCSIPORTPAGE2_PORT_HOST_ID_MASK (0x0000000F) #define MPI_SCSIPORTPAGE2_PORT_MASK_INIT_HBA (0x00000030) #define MPI_SCSIPORTPAGE2_PORT_DISABLE_INIT_HBA (0x00000000) @@ -915,7 +959,7 @@ #define MPI_FCPORTPAGE0_FLAGS_ALIAS_ALPA_SUPPORTED (0x00000010) #define MPI_FCPORTPAGE0_FLAGS_ALIAS_WWN_SUPPORTED (0x00000020) -#define MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID (0x00000030) +#define MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID (0x00000040) #define MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK (0x00000F00) #define MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT (0x00000000) @@ -974,15 +1018,23 @@ U8 TopologyConfig; /* 1Ah */ U8 AltConnector; /* 1Bh */ U8 NumRequestedAliases; /* 1Ch */ - U8 Reserved1; /* 1Dh */ + U8 RR_TOV; /* 1Dh */ U16 Reserved2; /* 1Eh */ } fCONFIG_PAGE_FC_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_1, FCPortPage1_t, MPI_POINTER pFCPortPage1_t; -#define MPI_FCPORTPAGE1_PAGEVERSION (0x04) +#define MPI_FCPORTPAGE1_PAGEVERSION (0x05) #define MPI_FCPORTPAGE1_FLAGS_EXT_FCP_STATUS_EN (0x08000000) #define MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY (0x04000000) +#define MPI_FCPORTPAGE1_FLAGS_FORCE_USE_NOSEEPROM_WWNS (0x02000000) +#define MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS (0x01000000) +#define MPI_FCPORTPAGE1_FLAGS_TARGET_MODE_OXID (0x00800000) +#define MPI_FCPORTPAGE1_FLAGS_PORT_OFFLINE (0x00400000) +#define MPI_FCPORTPAGE1_FLAGS_MASK_RR_TOV_UNITS (0x00000070) +#define MPI_FCPORTPAGE1_FLAGS_SUPPRESS_PROT_REG (0x00000008) +#define MPI_FCPORTPAGE1_FLAGS_PLOGI_ON_LOGO (0x00000004) +#define MPI_FCPORTPAGE1_FLAGS_MAINTAIN_LOGINS (0x00000002) #define MPI_FCPORTPAGE1_FLAGS_SORT_BY_DID (0x00000001) #define MPI_FCPORTPAGE1_FLAGS_SORT_BY_WWN (0x00000000) @@ -993,6 +1045,11 @@ #define MPI_FCPORTPAGE1_FLAGS_PROT_LAN ((U32)MPI_PORTFACTS_PROTOCOL_LAN << MPI_FCPORTPAGE1_FLAGS_PROT_SHIFT) #define MPI_FCPORTPAGE1_FLAGS_PROT_LOGBUSADDR ((U32)MPI_PORTFACTS_PROTOCOL_LOGBUSADDR << MPI_FCPORTPAGE1_FLAGS_PROT_SHIFT) +#define MPI_FCPORTPAGE1_FLAGS_NONE_RR_TOV_UNITS (0x00000000) +#define MPI_FCPORTPAGE1_FLAGS_THOUSANDTH_RR_TOV_UNITS (0x00000010) +#define MPI_FCPORTPAGE1_FLAGS_TENTH_RR_TOV_UNITS (0x00000030) +#define MPI_FCPORTPAGE1_FLAGS_TEN_RR_TOV_UNITS (0x00000050) + #define MPI_FCPORTPAGE1_HARD_ALPA_NOT_USED (0xFF) #define MPI_FCPORTPAGE1_LCONFIG_SPEED_MASK (0x0F) @@ -1108,12 +1165,13 @@ } fCONFIG_PAGE_FC_PORT_5, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5, FCPortPage5_t, MPI_POINTER pFCPortPage5_t; -#define MPI_FCPORTPAGE5_PAGEVERSION (0x01) +#define MPI_FCPORTPAGE5_PAGEVERSION (0x02) #define MPI_FCPORTPAGE5_FLAGS_ALPA_ACQUIRED (0x01) #define MPI_FCPORTPAGE5_FLAGS_HARD_ALPA (0x02) #define MPI_FCPORTPAGE5_FLAGS_HARD_WWNN (0x04) #define MPI_FCPORTPAGE5_FLAGS_HARD_WWPN (0x08) +#define MPI_FCPORTPAGE5_FLAGS_DISABLE (0x10) typedef struct _CONFIG_PAGE_FC_PORT_6 { @@ -1322,7 +1380,7 @@ U8 Flags; /* 19h */ U16 BBCredit; /* 1Ah */ U16 MaxRxFrameSize; /* 1Ch */ - U8 Reserved1; /* 1Eh */ + U8 ADISCHardALPA; /* 1Eh */ U8 PortNumber; /* 1Fh */ U8 FcPhLowestVersion; /* 20h */ U8 FcPhHighestVersion; /* 21h */ @@ -1331,13 +1389,16 @@ } fCONFIG_PAGE_FC_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_FC_DEVICE_0, FCDevicePage0_t, MPI_POINTER pFCDevicePage0_t; -#define MPI_FC_DEVICE_PAGE0_PAGEVERSION (0x02) +#define MPI_FC_DEVICE_PAGE0_PAGEVERSION (0x03) #define MPI_FC_DEVICE_PAGE0_FLAGS_TARGETID_BUS_VALID (0x01) +#define MPI_FC_DEVICE_PAGE0_FLAGS_PLOGI_INVALID (0x02) +#define MPI_FC_DEVICE_PAGE0_FLAGS_PRLI_INVALID (0x04) #define MPI_FC_DEVICE_PAGE0_PROT_IP (0x01) #define MPI_FC_DEVICE_PAGE0_PROT_FCP_TARGET (0x02) #define MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR (0x04) +#define MPI_FC_DEVICE_PAGE0_PROT_FCP_RETRY (0x08) #define MPI_FC_DEVICE_PAGE0_PGAD_PORT_MASK (MPI_FC_DEVICE_PGAD_PORT_MASK) #define MPI_FC_DEVICE_PAGE0_PGAD_FORM_MASK (MPI_FC_DEVICE_PGAD_FORM_MASK) @@ -1348,6 +1409,7 @@ #define MPI_FC_DEVICE_PAGE0_PGAD_BUS_SHIFT (MPI_FC_DEVICE_PGAD_BT_BUS_SHIFT) #define MPI_FC_DEVICE_PAGE0_PGAD_TID_MASK (MPI_FC_DEVICE_PGAD_BT_TID_MASK) +#define MPI_FC_DEVICE_PAGE0_HARD_ALPA_UNKNOWN (0xFF) /**************************************************************************** * RAID Volume Config Pages Index: drivers/message/fusion/lsi/mpi_init.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/message/fusion/lsi/mpi_init.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/message/fusion/lsi/mpi_init.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/message/fusion/lsi/mpi_init.h 4 Aug 2004 01:29:04 -0000 1.2 @@ -6,7 +6,7 @@ * Title: MPI initiator mode messages and structures * Creation Date: June 8, 2000 * - * MPI_INIT.H Version: 01.02.05 + * MPI_INIT.H Version: 01.02.07 * * Version History * --------------- @@ -31,6 +31,8 @@ * 10-04-01 01.02.04 Added defines for SEP request Action field. * 05-31-02 01.02.05 Added MPI_SCSIIO_MSGFLGS_CMD_DETERMINES_DATA_DIR define * for SCSI IO requests. + * 11-15-02 01.02.06 Added special extended SCSI Status defines for FCP. + * 06-26-03 01.02.07 Added MPI_SCSI_STATUS_FCPEXT_UNASSIGNED define. * -------------------------------------------------------------------------- */ @@ -153,6 +155,10 @@ #define MPI_SCSI_STATUS_TASK_SET_FULL (0x28) #define MPI_SCSI_STATUS_ACA_ACTIVE (0x30) +#define MPI_SCSI_STATUS_FCPEXT_DEVICE_LOGGED_OUT (0x80) +#define MPI_SCSI_STATUS_FCPEXT_NO_LINK (0x81) +#define MPI_SCSI_STATUS_FCPEXT_UNASSIGNED (0x82) + /* SCSI IO Reply SCSIState values */ Index: drivers/message/fusion/lsi/mpi_ioc.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/message/fusion/lsi/mpi_ioc.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/message/fusion/lsi/mpi_ioc.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/message/fusion/lsi/mpi_ioc.h 4 Aug 2004 01:29:04 -0000 1.2 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2002 LSI Logic Corporation. + * Copyright (c) 2000-2003 LSI Logic Corporation. * * * Name: MPI_IOC.H * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages * Creation Date: August 11, 2000 * - * MPI_IOC.H Version: 01.02.06 + * MPI_IOC.H Version: 01.02.08 * * Version History * --------------- @@ -55,6 +55,8 @@ * 05-31-02 01.02.06 Added define for * MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID. * Added AliasIndex to EVENT_DATA_LOGOUT structure. + * 04-01-03 01.02.07 Added defines for MPI_FW_HEADER_SIGNATURE_. + * 06-26-03 01.02.08 Added new values to the product family defines. * -------------------------------------------------------------------------- */ @@ -654,6 +656,10 @@ #define MPI_FW_HEADER_PID_TYPE_SCSI (0x0000) #define MPI_FW_HEADER_PID_TYPE_FC (0x1000) +#define MPI_FW_HEADER_SIGNATURE_0 (0x5AEAA55A) +#define MPI_FW_HEADER_SIGNATURE_1 (0xA55AEAA5) +#define MPI_FW_HEADER_SIGNATURE_2 (0x5AA55AEA) + #define MPI_FW_HEADER_PID_PROD_MASK (0x0F00) #define MPI_FW_HEADER_PID_PROD_INITIATOR_SCSI (0x0100) #define MPI_FW_HEADER_PID_PROD_TARGET_INITIATOR_SCSI (0x0200) @@ -673,6 +679,8 @@ #define MPI_FW_HEADER_PID_FAMILY_1020C0_SCSI (0x0008) #define MPI_FW_HEADER_PID_FAMILY_1035A0_SCSI (0x0009) #define MPI_FW_HEADER_PID_FAMILY_1035B0_SCSI (0x000A) +#define MPI_FW_HEADER_PID_FAMILY_1030TA0_SCSI (0x000B) +#define MPI_FW_HEADER_PID_FAMILY_1020TA0_SCSI (0x000C) #define MPI_FW_HEADER_PID_FAMILY_909_FC (0x0000) #define MPI_FW_HEADER_PID_FAMILY_919_FC (0x0001) #define MPI_FW_HEADER_PID_FAMILY_919X_FC (0x0002) Index: drivers/message/fusion/lsi/mpi_raid.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/message/fusion/lsi/mpi_raid.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/message/fusion/lsi/mpi_raid.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/message/fusion/lsi/mpi_raid.h 4 Aug 2004 01:29:04 -0000 1.2 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2001-2002 LSI Logic Corporation. + * Copyright (c) 2001-2003 LSI Logic Corporation. * * * Name: MPI_RAID.H * Title: MPI RAID message and structures * Creation Date: February 27, 2001 * - * MPI_RAID.H Version: 01.02.07 + * MPI_RAID.H Version: 01.02.09 * * Version History * --------------- @@ -25,6 +25,9 @@ * MPI_RAID_ACTION_INACTIVATE_VOLUME, and * MPI_RAID_ACTION_ADATA_INACTIVATE_ALL. * 07-12-02 01.02.07 Added structures for Mailbox request and reply. + * 11-15-02 01.02.08 Added missing MsgContext field to MSG_MAILBOX_REQUEST. + * 04-01-03 01.02.09 New action data option flag for + * MPI_RAID_ACTION_DELETE_VOLUME. * -------------------------------------------------------------------------- */ @@ -90,6 +93,9 @@ #define MPI_RAID_ACTION_ADATA_KEEP_PHYS_DISKS (0x00000000) #define MPI_RAID_ACTION_ADATA_DEL_PHYS_DISKS (0x00000001) +#define MPI_RAID_ACTION_ADATA_KEEP_LBA0 (0x00000000) +#define MPI_RAID_ACTION_ADATA_ZERO_LBA0 (0x00000002) + /* ActionDataWord defines for use with MPI_RAID_ACTION_ACTIVATE_VOLUME action */ #define MPI_RAID_ACTION_ADATA_INACTIVATE_ALL (0x00000001) @@ -195,6 +201,7 @@ U16 Reserved2; U8 Reserved3; U8 MsgFlags; + U32 MsgContext; U8 Command[10]; U16 Reserved4; SGE_IO_UNION SGL; Index: drivers/message/fusion/lsi/mpi_targ.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/message/fusion/lsi/mpi_targ.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/message/fusion/lsi/mpi_targ.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/message/fusion/lsi/mpi_targ.h 4 Aug 2004 01:29:04 -0000 1.2 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2002 LSI Logic Corporation. + * Copyright (c) 2000-2003 LSI Logic Corporation. * * * Name: MPI_TARG.H * Title: MPI Target mode messages and structures * Creation Date: June 22, 2000 * - * MPI_TARG.H Version: 01.02.07 + * MPI_TARG.H Version: 01.02.09 * * Version History * --------------- @@ -41,6 +41,8 @@ * Added AliasIndex field to MPI_TARGET_FCP_CMD_BUFFER. * 09-16-02 01.02.07 Added flags for confirmed completion. * Added PRIORITY_REASON_TARGET_BUSY. + * 11-15-02 01.02.08 Added AliasID field to MPI_TARGET_SCSI_SPI_CMD_BUFFER. + * 04-01-03 01.02.09 Added OptionalOxid field to MPI_TARGET_FCP_CMD_BUFFER. * -------------------------------------------------------------------------- */ @@ -171,7 +173,7 @@ U32 FcpDl; /* 1Ch */ U8 AliasIndex; /* 20h */ U8 Reserved1; /* 21h */ - U16 Reserved2; /* 22h */ + U16 OptionalOxid; /* 22h */ } MPI_TARGET_FCP_CMD_BUFFER, MPI_POINTER PTR_MPI_TARGET_FCP_CMD_BUFFER, MpiTargetFcpCmdBuffer, MPI_POINTER pMpiTargetFcpCmdBuffer; @@ -190,6 +192,10 @@ U8 TaskManagementFlags; /* 12h */ U8 AdditionalCDBLength; /* 13h */ U8 CDB[16]; /* 14h */ + /* Alias ID */ + U8 AliasID; /* 24h */ + U8 Reserved1; /* 25h */ + U16 Reserved2; /* 26h */ } MPI_TARGET_SCSI_SPI_CMD_BUFFER, MPI_POINTER PTR_MPI_TARGET_SCSI_SPI_CMD_BUFFER, MpiTargetScsiSpiCmdBuffer, MPI_POINTER pMpiTargetScsiSpiCmdBuffer; Index: drivers/misc/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/misc/Makefile,v retrieving revision 1.1 retrieving revision 1.4 diff -u -r1.1 -r1.4 --- drivers/misc/Makefile 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/misc/Makefile 20 Aug 2004 21:40:24 -0000 1.4 @@ -11,7 +11,7 @@ O_TARGET := misc.o -export-objs := mcp-core.o mcp-sa1100.o ucb1x00-core.o +export-objs := mcp-core.o mcp-sa1100.o ucb1x00-core.o ts_sbcinfo.o obj-$(CONFIG_MCP) += mcp-core.o obj-$(CONFIG_MCP_SA1100) += mcp-sa1100.o @@ -19,6 +19,8 @@ obj-$(CONFIG_MCP_UCB1200_AUDIO) += ucb1x00-audio.o obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o +obj-y := ts_sbcinfo.o + include $(TOPDIR)/Rules.make fastdep: Index: drivers/misc/ts_sbcinfo.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/misc/ts_sbcinfo.c,v retrieving revision 1.1 retrieving revision 1.7 diff -u -r1.1 -r1.7 --- drivers/misc/ts_sbcinfo.c 20 Aug 2004 21:40:24 -0000 1.1 +++ drivers/misc/ts_sbcinfo.c 7 Dec 2006 23:03:46 -0000 1.7 @@ -39,7 +39,6 @@ static int sbc_setinfo ( struct sbc_info *sbc){ unsigned short temp; - memset( sbc, 0, sizeof(struct sbc_info)); temp = inw(TS7XXX_MODEL) & 0x07; @@ -50,26 +49,43 @@ case TS7200: sbc->board_id = 7200; break; + case TS7250: + sbc->board_id = 7250; + break; + case TS7260: + sbc->board_id = 7260; + break; + case TS7300: + sbc->board_id = 7300; + break; + case TS7400: + sbc->board_id = 7400; + break; default: sbc->board_id = 0; break; } + temp = inb(0x02400000 + TS7XXX_IO16_BASE ); + //check for AtoD - temp = inb(0x02000000 + TS7XXX_IO16_BASE ); switch (sbc->board_id) { case 7200: if (temp & 0x01) sbc->AtoD = 1; break; + if ( temp & 0x01) + sbc->AtoD = 1; default: break; } //check for 485 - temp = inb(0x02000000 + TS7XXX_IO16_BASE ); switch (sbc->board_id) { case 7200: + case 7250: + case 7260: + case 7300: if (temp & 0x02) { sbc->RS485 = 1; sbc->auto485 = 1; @@ -134,7 +150,6 @@ return -ENOMEM; } - printk("about to do sbc_setinfo\n"); err = sbc_setinfo (&ts_sbc); if (err < 0 ) { sbc_remove_proc( entry); Index: drivers/misc/ucb1x00-core.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/misc/ucb1x00-core.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/misc/ucb1x00-core.c 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/misc/ucb1x00-core.c 4 Aug 2004 01:29:04 -0000 1.2 @@ -389,8 +389,8 @@ * cerf IRQ_GPIO_UCB1200_IRQ * flexanet IRQ_GPIO_GUI * freebird IRQ_GPIO_FREEBIRD_UCB1300_IRQ - * graphicsclient ADS_EXT_IRQ(8) - * graphicsmaster ADS_EXT_IRQ(8) + * graphicsclient IRQ_GRAPHICSCLIENT_UCB1200 + * graphicsmaster IRQ_GRAPHICSMASTER_UCB1200 * lart LART_IRQ_UCB1200 * omnimeter IRQ_GPIO23 * pfs168 IRQ_GPIO_UCB1300_IRQ @@ -470,9 +470,13 @@ if (machine_is_freebird()) default_irq = IRQ_GPIO_FREEBIRD_UCB1300_IRQ; #endif -#if defined(CONFIG_SA1100_GRAPHICSCLIENT) || defined(CONFIG_SA1100_GRAPICSMASTER) - if (machine_is_graphicsclient() || machine_is_graphicsmaster()) - default_irq = ADS_EXT_IRQ(8); +#if defined(CONFIG_SA1100_GRAPHICSCLIENT) +// if (machine_is_graphicsclient()) +// default_irq = IRQ_GRAPHICSCLIENT_UCB1200; +#endif +#if defined(CONFIG_SA1100_GRAPICSMASTER) + if (machine_is_graphicsmaster()) + default_irq = IRQ_GRAPHICSMASTER_UCB1200; #endif #ifdef CONFIG_SA1100_LART if (machine_is_lart()) { Index: drivers/mtd/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/Config.in,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/Config.in 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/Config.in 3 Nov 2004 00:04:42 -0000 1.3 @@ -1,5 +1,5 @@ -# $Id: Config.in,v 1.1 2004/07/22 19:49:45 joff Exp $ +# $Id: Config.in,v 1.3 2004/11/03 00:04:42 joff Exp $ mainmenu_option next_comment comment 'Memory Technology Devices (MTD)' @@ -11,10 +11,16 @@ if [ "$CONFIG_MTD_DEBUG" = "y" ]; then int ' Debugging verbosity (0 = quiet, 3 = noisy)' CONFIG_MTD_DEBUG_VERBOSE 0 fi - dep_tristate ' MTD partitioning support' CONFIG_MTD_PARTITIONS $CONFIG_MTD + bool ' MTD partitioning support' CONFIG_MTD_PARTITIONS $CONFIG_MTD dep_tristate ' MTD concatenating support' CONFIG_MTD_CONCAT $CONFIG_MTD dep_tristate ' RedBoot partition table parsing' CONFIG_MTD_REDBOOT_PARTS $CONFIG_MTD_PARTITIONS - dep_tristate ' Command line partition table parsing' CONFIG_MTD_CMDLINE_PARTS $CONFIG_MTD_PARTITIONS + if [ "$CONFIG_MTD_REDBOOT_PARTS" = "y" -o "$CONFIG_MTD_REDBOOT_PARTS" = "m" ]; then + bool ' Include unallocated flash space' CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED + bool ' Force read-only for RedBoot system images' CONFIG_MTD_REDBOOT_PARTS_READONLY + fi + if [ "$CONFIG_MTD_PARTITIONS" = "y" ]; then + bool ' Command line partition table parsing' CONFIG_MTD_CMDLINE_PARTS + fi if [ "$CONFIG_ARM" = "y" ]; then dep_tristate ' ARM Firmware Suite partition parsing' CONFIG_MTD_AFS_PARTS $CONFIG_MTD_PARTITIONS fi @@ -30,6 +36,7 @@ if [ "$CONFIG_NFTL" = "y" -o "$CONFIG_NFTL" = "m" ]; then bool ' Write support for NFTL (BETA)' CONFIG_NFTL_RW fi + dep_tristate ' INFTL (Inverse NAND Flash Translation Layer) support' CONFIG_INFTL $CONFIG_MTD source drivers/mtd/chips/Config.in Index: drivers/mtd/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/Makefile,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/Makefile 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/Makefile 3 Nov 2004 00:04:42 -0000 1.3 @@ -1,66 +1,54 @@ # -# Makefile for the memory technology device drivers. +# linux/drivers/Makefile.24 +# Makefile for obsolete kernels. # -# 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 inherited from the -# parent makes.. -# -# $Id: Makefile,v 1.1 2004/07/22 19:49:45 joff Exp $ +# $Id: Makefile,v 1.3 2004/11/03 00:04:42 joff Exp $ +# Core functionality. +mtd-y := mtdcore.o +mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o +obj-$(CONFIG_MTD) += $(mtd-y) -obj-y += chips/chipslink.o maps/mapslink.o \ - devices/devlink.o nand/nandlink.o -obj-m := -obj-n := -obj- := +obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o +obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o +obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o +obj-$(CONFIG_MTD_AFS_PARTS) += afs.o -O_TARGET := mtdlink.o +# 'Users' - code which presents functionality to userspace. +obj-$(CONFIG_MTD_CHAR) += mtdchar.o +obj-$(CONFIG_MTD_BLOCK) += mtdblock.o mtd_blkdevs-24.o +obj-$(CONFIG_MTD_BLOCK_RO) += mtdblock_ro.o mtd_blkdevs-24.o +obj-$(CONFIG_FTL) += ftl.o mtd_blkdevs-24.o +obj-$(CONFIG_NFTL) += nftl.o mtd_blkdevs-24.o +obj-$(CONFIG_INFTL) += inftl.o mtd_blkdevs-24.o + +nftl-objs := nftlcore.o nftlmount.o +inftl-objs := inftlcore.o inftlmount.o -export-objs := mtdcore.o mtdpart.o redboot.o cmdlinepart.o afs.o mtdconcat.o -list-multi := nftl.o +export-objs := mtdcore.o mtdpart.o redboot.o cmdlinepart.o afs.o \ + mtdconcat.o mtd_blkdevs-24.o -mod-subdirs := -subdir-y := chips maps devices nand -subdir-m := $(subdir-y) +mtd_blkdevs-objs := mtd_blkdevs-24.o -# *** BIG UGLY NOTE *** -# -# The shiny new inter_module_xxx has introduced yet another ugly link -# order dependency, which I'd previously taken great care to avoid. -# We now have to ensure that the chip drivers are initialised before the -# map drivers, and that the doc200[01] drivers are initialised before -# docprobe. -# -# We'll hopefully merge the doc200[01] drivers and docprobe back into -# a single driver some time soon, but the CFI drivers are going to have -# to stay like that. -# -# Urgh. -# -# dwmw2 21/11/0 +obj-y += chips/chipslink.o maps/mapslink.o \ + devices/devlink.o nand/nandlink.o -# Core functionality. -obj-$(CONFIG_MTD) += mtdcore.o -obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o -obj-$(CONFIG_MTD_PARTITIONS) += mtdpart.o -obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o -obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o -obj-$(CONFIG_MTD_AFS_PARTS) += afs.o +O_TARGET := mtdlink.o -# 'Users' - code which presents functionality to userspace. -obj-$(CONFIG_MTD_CHAR) += mtdchar.o -obj-$(CONFIG_MTD_BLOCK) += mtdblock.o -obj-$(CONFIG_MTD_BLOCK_RO) += mtdblock_ro.o -obj-$(CONFIG_FTL) += ftl.o -obj-$(CONFIG_NFTL) += nftl.o +list-multi := nftl.o inftl.o mtd_blkdevs-24.o -nftl-objs := nftlcore.o nftlmount.o +mod-subdirs := +subdir-y := chips maps devices nand +subdir-m := $(subdir-y) include $(TOPDIR)/Rules.make nftl.o: $(nftl-objs) $(LD) -r -o $@ $(nftl-objs) +inftl.o: $(inftl-objs) + $(LD) -r -o $@ $(inftl-objs) + +mtd_blkdevs.o: $(mtd_blkdevs-objs) + $(LD) -r -o $@ $(mtd_blkdevs-objs) + Index: drivers/mtd/afs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/afs.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/afs.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/afs.c 3 Nov 2004 00:04:42 -0000 1.3 @@ -21,7 +21,7 @@ This is access code for flashes using ARM's flash partitioning standards. - $Id: afs.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + $Id: afs.c,v 1.3 2004/11/03 00:04:42 joff Exp $ ======================================================================*/ @@ -57,6 +57,17 @@ u32 checksum; /* Image checksum (inc. this struct) */ }; +static u32 word_sum(void *words, int num) +{ + u32 *p = words; + u32 sum = 0; + + while (num--) + sum += *p++; + + return sum; +} + static int afs_read_footer(struct mtd_info *mtd, u_int *img_start, u_int *iis_start, u_int off, u_int mask) @@ -76,17 +87,25 @@ return ret; } + ret = 1; + /* * Does it contain the magic number? */ if (fs.signature != 0xa0ffff9f) - ret = 1; + ret = 0; + + /* + * Check the checksum. + */ + if (word_sum(&fs, sizeof(fs) / sizeof(u32)) != 0xffffffff) + ret = 0; /* * Don't touch the SIB. */ if (fs.type == 2) - ret = 1; + ret = 0; *iis_start = fs.image_info_base & mask; *img_start = fs.image_start & mask; @@ -96,14 +115,14 @@ * be located after the footer structure. */ if (*iis_start >= ptr) - ret = 1; + ret = 0; /* * Check the start of this image. The image * data can not be located after this block. */ if (*img_start > off) - ret = 1; + ret = 0; return ret; } @@ -112,20 +131,41 @@ afs_read_iis(struct mtd_info *mtd, struct image_info_struct *iis, u_int ptr) { size_t sz; - int ret; + int ret, i; memset(iis, 0, sizeof(*iis)); ret = mtd->read(mtd, ptr, sizeof(*iis), &sz, (u_char *) iis); - if (ret >= 0 && sz != sizeof(*iis)) - ret = -EINVAL; if (ret < 0) - printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n", - ptr, ret); + goto failed; + + if (sz != sizeof(*iis)) { + ret = -EINVAL; + goto failed; + } + + ret = 0; + + /* + * Validate the name - it must be NUL terminated. + */ + for (i = 0; i < sizeof(iis->name); i++) + if (iis->name[i] == '\0') + break; + + if (i < sizeof(iis->name)) + ret = 1; return ret; + + failed: + printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n", + ptr, ret); + return ret; } -int parse_afs_partitions(struct mtd_info *mtd, struct mtd_partition **pparts) +static int parse_afs_partitions(struct mtd_info *mtd, + struct mtd_partition **pparts, + unsigned long origin) { struct mtd_partition *parts; u_int mask, off, idx, sz; @@ -150,12 +190,14 @@ ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask); if (ret < 0) break; - if (ret == 1) + if (ret == 0) continue; ret = afs_read_iis(mtd, &iis, iis_ptr); if (ret < 0) break; + if (ret == 0) + continue; sz += sizeof(struct mtd_partition); sz += strlen(iis.name) + 1; @@ -183,13 +225,15 @@ ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask); if (ret < 0) break; - if (ret == 1) + if (ret == 0) continue; /* Read the image info block */ ret = afs_read_iis(mtd, &iis, iis_ptr); if (ret < 0) break; + if (ret == 0) + continue; strcpy(str, iis.name); size = mtd->erasesize + off - img_ptr; @@ -227,7 +271,25 @@ return idx ? idx : ret; } -EXPORT_SYMBOL(parse_afs_partitions); +static struct mtd_part_parser afs_parser = { + .owner = THIS_MODULE, + .parse_fn = parse_afs_partitions, + .name = "afs", +}; + +static int __init afs_parser_init(void) +{ + return register_mtd_parser(&afs_parser); +} + +static void __exit afs_parser_exit(void) +{ + deregister_mtd_parser(&afs_parser); +} + +module_init(afs_parser_init); +module_exit(afs_parser_exit); + MODULE_AUTHOR("ARM Ltd"); MODULE_DESCRIPTION("ARM Firmware Suite partition parser"); Index: drivers/mtd/cmdlinepart.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/cmdlinepart.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/cmdlinepart.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/cmdlinepart.c 3 Nov 2004 00:04:42 -0000 1.3 @@ -1,5 +1,5 @@ /* - * $Id: cmdlinepart.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: cmdlinepart.c,v 1.3 2004/11/03 00:04:42 joff Exp $ * * Read flash partition table from command line * @@ -10,7 +10,7 @@ * mtdparts=[; := :[,] * := [@offset][][ro] - * := unique id used in mapping driver/device + * := unique name used in mapping driver/device (mtd->name) * := standard linux memsize OR "-" to denote all remaining space * := '(' NAME ')' * @@ -28,7 +28,6 @@ #include #include -#include #include /* error message prefix */ @@ -95,7 +94,7 @@ if (size < PAGE_SIZE) { printk(KERN_ERR ERRP "partition size too small (%lx)\n", size); - return 0; + return NULL; } } @@ -122,7 +121,7 @@ if ((p = strchr(name, delim)) == 0) { printk(KERN_ERR ERRP "no closing %c found in partition name\n", delim); - return 0; + return NULL; } name_len = p - name; s = p + 1; @@ -149,12 +148,12 @@ if (size == SIZE_REMAINING) { printk(KERN_ERR ERRP "no partitions allowed after a fill-up partition\n"); - return 0; + return NULL; } /* more partitions follow, parse them */ if ((parts = newpart(s + 1, &s, num_parts, this_part + 1, &extra_mem, extra_mem_size)) == 0) - return 0; + return NULL; } else { /* this is the last partition: allocate space for all */ @@ -167,7 +166,7 @@ if (!parts) { printk(KERN_ERR ERRP "out of memory\n"); - return 0; + return NULL; } memset(parts, 0, alloc_size); extra_mem = (unsigned char *)(parts + *num_parts); @@ -178,8 +177,7 @@ parts[this_part].mask_flags = mask_flags; if (name) { - strncpy(extra_mem, name, name_len); - extra_mem[name_len] = 0; + strlcpy(extra_mem, name, name_len + 1); } else { @@ -258,8 +256,7 @@ this_mtd->parts = parts; this_mtd->num_parts = num_parts; this_mtd->mtd_id = (char*)(this_mtd + 1); - strncpy(this_mtd->mtd_id, mtd_id, mtd_id_len); - this_mtd->mtd_id[mtd_id_len] = 0; + strlcpy(this_mtd->mtd_id, mtd_id, mtd_id_len + 1); /* link into chain */ this_mtd->next = partitions; @@ -291,13 +288,14 @@ * information. It returns partitions for the requested mtd device, or * the first one in the chain if a NULL mtd_id is passed in. */ -int parse_cmdline_partitions(struct mtd_info *master, +static int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, - const char *mtd_id) + unsigned long origin) { unsigned long offset; int i; struct cmdline_mtd_partition *part; + char *mtd_id = master->name; if(!cmdline) return -EINVAL; @@ -341,7 +339,7 @@ * main.c::checksetup(). Note that we can not yet kmalloc() anything, * so we only save the commandline for later processing. */ -static int __init mtdpart_setup(char *s) +int mtdpart_setup(char *s) { cmdline = s; return 1; @@ -349,7 +347,18 @@ __setup("mtdparts=", mtdpart_setup); -EXPORT_SYMBOL(parse_cmdline_partitions); +static struct mtd_part_parser cmdline_parser = { + .owner = THIS_MODULE, + .parse_fn = parse_cmdline_partitions, + .name = "cmdlinepart", +}; + +static int __init cmdline_parser_init(void) +{ + return register_mtd_parser(&cmdline_parser); +} + +module_init(cmdline_parser_init); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Marius Groeger "); Index: drivers/mtd/ftl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/ftl.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/ftl.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/ftl.c 3 Nov 2004 00:04:42 -0000 1.3 @@ -1,5 +1,5 @@ /* This version ported to the Linux-MTD system by dwmw2@infradead.org - * $Id: ftl.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: ftl.c,v 1.3 2004/11/03 00:04:42 joff Exp $ * * Fixes: Arnaldo Carvalho de Melo * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups @@ -55,8 +55,8 @@ contact M-Systems (http://www.m-sys.com) directly. ======================================================================*/ +#include #include -#include #include /*#define PSYCHO_DEBUG */ @@ -68,43 +68,13 @@ #include #include #include -#include +#include #include - -#if (LINUX_VERSION_CODE >= 0x20100) #include -#endif -#if (LINUX_VERSION_CODE >= 0x20303) #include -#endif +#include #include -/*====================================================================*/ -/* Stuff which really ought to be in compatmac.h */ - -#if (LINUX_VERSION_CODE < 0x20328) -#define register_disk(dev, drive, minors, ops, size) \ - do { (dev)->part[(drive)*(minors)].nr_sects = size; \ - if (size == 0) (dev)->part[(drive)*(minors)].start_sect = -1; \ - resetup_one_dev(dev, drive); } while (0) -#endif - -#if (LINUX_VERSION_CODE < 0x20320) -#define BLK_DEFAULT_QUEUE(n) blk_dev[n].request_fn -#define blk_init_queue(q, req) q = (req) -#define blk_cleanup_queue(q) q = NULL -#define request_arg_t void -#else -#define request_arg_t request_queue_t *q -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14) -#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT -#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT -#else -#define BLK_INC_USE_COUNT do {} while(0) -#define BLK_DEC_USE_COUNT do {} while(0) -#endif /*====================================================================*/ @@ -119,19 +89,6 @@ #define FTL_MAJOR 44 #endif -/* Funky stuff for setting up a block device */ -#define MAJOR_NR FTL_MAJOR -#define DEVICE_NAME "ftl" -#define DEVICE_REQUEST do_ftl_request -#define DEVICE_ON(device) -#define DEVICE_OFF(device) - -#define DEVICE_NR(minor) ((minor)>>5) -#define REGION_NR(minor) (((minor)>>3)&3) -#define PART_NR(minor) ((minor)&7) -#define MINOR_NR(dev,reg,part) (((dev)<<5)+((reg)<<3)+(part)) - -#include /*====================================================================*/ @@ -142,8 +99,7 @@ #define MAX_REGION 4 /* Maximum number of partitions in an FTL region */ -#define PART_BITS 3 -#define MAX_PART 8 +#define PART_BITS 4 /* Maximum number of outstanding erase requests per socket */ #define MAX_ERASE 8 @@ -154,7 +110,7 @@ /* Each memory region corresponds to a minor device */ typedef struct partition_t { - struct mtd_info *mtd; + struct mtd_blktrans_dev mbd; u_int32_t state; u_int32_t *VirtualBlockMap; u_int32_t *VirtualPageMap; @@ -179,21 +135,10 @@ region_info_t region; memory_handle_t handle; #endif - atomic_t open; } partition_t; -partition_t *myparts[MAX_MTD_DEVICES]; - -static void ftl_notify_add(struct mtd_info *mtd); -static void ftl_notify_remove(struct mtd_info *mtd); - void ftl_freepart(partition_t *part); -static struct mtd_notifier ftl_notifier = { - add: ftl_notify_add, - remove: ftl_notify_remove, -}; - /* Partition state flags */ #define FTL_FORMATTED 0x01 @@ -204,51 +149,11 @@ #define XFER_PREPARED 0x03 #define XFER_FAILED 0x04 -static struct hd_struct ftl_hd[MINOR_NR(MAX_DEV, 0, 0)]; -static int ftl_sizes[MINOR_NR(MAX_DEV, 0, 0)]; -static int ftl_blocksizes[MINOR_NR(MAX_DEV, 0, 0)]; - -static struct gendisk ftl_gendisk = { - major: FTL_MAJOR, - major_name: "ftl", - minor_shift: PART_BITS, - max_p: MAX_PART, -#if (LINUX_VERSION_CODE < 0x20328) - max_nr: MAX_DEV*MAX_PART, -#endif - part: ftl_hd, - sizes: ftl_sizes, -}; - /*====================================================================*/ -static int ftl_ioctl(struct inode *inode, struct file *file, - u_int cmd, u_long arg); -static int ftl_open(struct inode *inode, struct file *file); -static release_t ftl_close(struct inode *inode, struct file *file); -static int ftl_reread_partitions(int minor); static void ftl_erase_callback(struct erase_info *done); -#if LINUX_VERSION_CODE < 0x20326 -static struct file_operations ftl_blk_fops = { - open: ftl_open, - release: ftl_close, - ioctl: ftl_ioctl, - read: block_read, - write: block_write, - fsync: block_fsync -}; -#else -static struct block_device_operations ftl_blk_fops = { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14) - owner: THIS_MODULE, -#endif - open: ftl_open, - release: ftl_close, - ioctl: ftl_ioctl, -}; -#endif /*====================================================================== @@ -262,19 +167,20 @@ { erase_unit_header_t header; loff_t offset, max_offset; - int ret; + size_t ret; + int err; part->header.FormattedSize = 0; - max_offset = (0x100000mtd->size)?0x100000:part->mtd->size; + max_offset = (0x100000mbd.mtd->size)?0x100000:part->mbd.mtd->size; /* Search first megabyte for a valid FTL header */ for (offset = 0; (offset + sizeof(header)) < max_offset; - offset += part->mtd->erasesize ? : 0x2000) { + offset += part->mbd.mtd->erasesize ? : 0x2000) { - ret = part->mtd->read(part->mtd, offset, sizeof(header), &ret, + err = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &ret, (unsigned char *)&header); - if (ret) - return ret; + if (err) + return err; if (strcmp(header.DataOrgTuple+3, "FTL100") == 0) break; } @@ -283,15 +189,15 @@ printk(KERN_NOTICE "ftl_cs: FTL header not found.\n"); return -ENOENT; } - if ((le16_to_cpu(header.NumEraseUnits) > 65536) || header.BlockSize != 9 || + if (header.BlockSize != 9 || (header.EraseUnitSize < 10) || (header.EraseUnitSize > 31) || (header.NumTransferUnits >= le16_to_cpu(header.NumEraseUnits))) { printk(KERN_NOTICE "ftl_cs: FTL header corrupt!\n"); return -1; } - if ((1 << header.EraseUnitSize) != part->mtd->erasesize) { + if ((1 << header.EraseUnitSize) != part->mbd.mtd->erasesize) { printk(KERN_NOTICE "ftl: FTL EraseUnitSize %x != MTD erasesize %x\n", - 1 << header.EraseUnitSize,part->mtd->erasesize); + 1 << header.EraseUnitSize,part->mbd.mtd->erasesize); return -1; } part->header = header; @@ -326,7 +232,7 @@ for (i = 0; i < le16_to_cpu(part->header.NumEraseUnits); i++) { offset = ((i + le16_to_cpu(part->header.FirstPhysicalEUN)) << part->header.EraseUnitSize); - ret = part->mtd->read(part->mtd, offset, sizeof(header), &retval, + ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &retval, (unsigned char *)&header); if (ret) @@ -391,7 +297,7 @@ part->EUNInfo[i].Deleted = 0; offset = part->EUNInfo[i].Offset + le32_to_cpu(header.BAMOffset); - ret = part->mtd->read(part->mtd, offset, + ret = part->mbd.mtd->read(part->mbd.mtd, offset, part->BlocksPerUnit * sizeof(u_int32_t), &retval, (unsigned char *)part->bam_cache); @@ -456,7 +362,7 @@ erase->len = 1 << part->header.EraseUnitSize; erase->priv = (u_long)part; - ret = part->mtd->erase(part->mtd, erase); + ret = part->mbd.mtd->erase(part->mbd.mtd, erase); if (!ret) xfer->EraseCount++; @@ -523,7 +429,7 @@ header.LogicalEUN = cpu_to_le16(0xffff); header.EraseCount = cpu_to_le32(xfer->EraseCount); - ret = part->mtd->write(part->mtd, xfer->Offset, sizeof(header), + ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset, sizeof(header), &retlen, (u_char *)&header); if (ret) { @@ -539,7 +445,7 @@ for (i = 0; i < nbam; i++, offset += sizeof(u_int32_t)) { - ret = part->mtd->write(part->mtd, offset, sizeof(u_int32_t), + ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t), &retlen, (u_char *)&ctl); if (ret) @@ -586,7 +492,7 @@ offset = eun->Offset + le32_to_cpu(part->header.BAMOffset); - ret = part->mtd->read(part->mtd, offset, + ret = part->mbd.mtd->read(part->mbd.mtd, offset, part->BlocksPerUnit * sizeof(u_int32_t), &retlen, (u_char *) (part->bam_cache)); @@ -604,7 +510,7 @@ offset = xfer->Offset + 20; /* Bad! */ unit = cpu_to_le16(0x7fff); - ret = part->mtd->write(part->mtd, offset, sizeof(u_int16_t), + ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int16_t), &retlen, (u_char *) &unit); if (ret) { @@ -624,7 +530,7 @@ break; case BLOCK_DATA: case BLOCK_REPLACEMENT: - ret = part->mtd->read(part->mtd, src, SECTOR_SIZE, + ret = part->mbd.mtd->read(part->mbd.mtd, src, SECTOR_SIZE, &retlen, (u_char *) buf); if (ret) { printk(KERN_WARNING "ftl: Error reading old xfer unit in copy_erase_unit\n"); @@ -632,7 +538,7 @@ } - ret = part->mtd->write(part->mtd, dest, SECTOR_SIZE, + ret = part->mbd.mtd->write(part->mbd.mtd, dest, SECTOR_SIZE, &retlen, (u_char *) buf); if (ret) { printk(KERN_WARNING "ftl: Error writing new xfer unit in copy_erase_unit\n"); @@ -651,7 +557,7 @@ } /* Write the BAM to the transfer unit */ - ret = part->mtd->write(part->mtd, xfer->Offset + le32_to_cpu(part->header.BAMOffset), + ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + le32_to_cpu(part->header.BAMOffset), part->BlocksPerUnit * sizeof(int32_t), &retlen, (u_char *)part->bam_cache); if (ret) { @@ -661,7 +567,7 @@ /* All clear? Then update the LogicalEUN again */ - ret = part->mtd->write(part->mtd, xfer->Offset + 20, sizeof(u_int16_t), + ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + 20, sizeof(u_int16_t), &retlen, (u_char *)&srcunitswap); if (ret) { @@ -749,8 +655,8 @@ if (queued) { DEBUG(1, "ftl_cs: waiting for transfer " "unit to be prepared...\n"); - if (part->mtd->sync) - part->mtd->sync(part->mtd); + if (part->mbd.mtd->sync) + part->mbd.mtd->sync(part->mbd.mtd); } else { static int ne = 0; if (++ne < 5) @@ -848,7 +754,7 @@ /* Invalidate cache */ part->bam_index = 0xffff; - ret = part->mtd->read(part->mtd, + ret = part->mbd.mtd->read(part->mbd.mtd, part->EUNInfo[eun].Offset + le32_to_cpu(part->header.BAMOffset), part->BlocksPerUnit * sizeof(u_int32_t), &retlen, (u_char *) (part->bam_cache)); @@ -877,78 +783,6 @@ } /* find_free */ -/*====================================================================== - - This gets a memory handle for the region corresponding to the - minor device number. - -======================================================================*/ - -static int ftl_open(struct inode *inode, struct file *file) -{ - int minor = MINOR(inode->i_rdev); - partition_t *partition; - - if (minor>>4 >= MAX_MTD_DEVICES) - return -ENODEV; - - partition = myparts[minor>>4]; - - if (!partition) - return -ENODEV; - - if (partition->state != FTL_FORMATTED) - return -ENXIO; - - if (ftl_gendisk.part[minor].nr_sects == 0) - return -ENXIO; - - BLK_INC_USE_COUNT; - - if (!get_mtd_device(partition->mtd, -1)) { - BLK_DEC_USE_COUNT; - return -ENXIO; - } - - if ((file->f_mode & 2) && !(partition->mtd->flags & MTD_CLEAR_BITS) ) { - put_mtd_device(partition->mtd); - BLK_DEC_USE_COUNT; - return -EROFS; - } - - DEBUG(0, "ftl_cs: ftl_open(%d)\n", minor); - - atomic_inc(&partition->open); - - return 0; -} - -/*====================================================================*/ - -static release_t ftl_close(struct inode *inode, struct file *file) -{ - int minor = MINOR(inode->i_rdev); - partition_t *part = myparts[minor >> 4]; - int i; - - DEBUG(0, "ftl_cs: ftl_close(%d)\n", minor); - - /* Wait for any pending erase operations to complete */ - if (part->mtd->sync) - part->mtd->sync(part->mtd); - - for (i = 0; i < part->header.NumTransferUnits; i++) { - if (part->XferInfo[i].state == XFER_ERASED) - prepare_xfer(part, i); - } - - atomic_dec(&part->open); - - put_mtd_device(part->mtd); - BLK_DEC_USE_COUNT; - release_return(0); -} /* ftl_close */ - /*====================================================================== @@ -983,7 +817,7 @@ else { offset = (part->EUNInfo[log_addr / bsize].Offset + (log_addr % bsize)); - ret = part->mtd->read(part->mtd, offset, SECTOR_SIZE, + ret = part->mbd.mtd->read(part->mbd.mtd, offset, SECTOR_SIZE, &retlen, (u_char *) buffer); if (ret) { @@ -1022,7 +856,7 @@ le32_to_cpu(part->header.BAMOffset)); #ifdef PSYCHO_DEBUG - ret = part->mtd->read(part->mtd, offset, sizeof(u_int32_t), + ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(u_int32_t), &retlen, (u_char *)&old_addr); if (ret) { printk(KERN_WARNING"ftl: Error reading old_addr in set_bam_entry: %d\n",ret); @@ -1059,7 +893,7 @@ #endif part->bam_cache[blk] = le_virt_addr; } - ret = part->mtd->write(part->mtd, offset, sizeof(u_int32_t), + ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t), &retlen, (u_char *)&le_virt_addr); if (ret) { @@ -1119,13 +953,13 @@ part->EUNInfo[part->bam_index].Deleted++; offset = (part->EUNInfo[part->bam_index].Offset + blk * SECTOR_SIZE); - ret = part->mtd->write(part->mtd, offset, SECTOR_SIZE, &retlen, + ret = part->mbd.mtd->write(part->mbd.mtd, offset, SECTOR_SIZE, &retlen, buffer); if (ret) { printk(KERN_NOTICE "ftl_cs: block write failed!\n"); printk(KERN_NOTICE "ftl_cs: log_addr = 0x%x, virt_addr" - " = 0x%x, Offset = 0x%x\n", log_addr, virt_addr, + " = 0x%x, Offset = 0x%zx\n", log_addr, virt_addr, offset); return -EIO; } @@ -1151,164 +985,32 @@ return 0; } /* ftl_write */ -/*====================================================================== - - IOCTL calls for getting device parameters. - -======================================================================*/ - -static int ftl_ioctl(struct inode *inode, struct file *file, - u_int cmd, u_long arg) +static int ftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo) { - struct hd_geometry *geo = (struct hd_geometry *)arg; - int ret = 0, minor = MINOR(inode->i_rdev); - partition_t *part= myparts[minor >> 4]; - u_long sect; - - if (!part) - return -ENODEV; /* How? */ - - switch (cmd) { - case HDIO_GETGEO: - ret = verify_area(VERIFY_WRITE, (long *)arg, sizeof(*geo)); - if (ret) return ret; - /* Sort of arbitrary: round size down to 4K boundary */ - sect = le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE; - put_user(1, (char *)&geo->heads); - put_user(8, (char *)&geo->sectors); - put_user((sect>>3), (short *)&geo->cylinders); - put_user(ftl_hd[minor].start_sect, (u_long *)&geo->start); - break; - case BLKGETSIZE: - ret = put_user(ftl_hd[minor].nr_sects, (unsigned long *)arg); - break; -#ifdef BLKGETSIZE64 - case BLKGETSIZE64: - ret = put_user((u64)ftl_hd[minor].nr_sects << 9, (u64 *)arg); - break; -#endif - case BLKRRPART: - ret = ftl_reread_partitions(minor); - break; -#if (LINUX_VERSION_CODE < 0x20303) - case BLKFLSBUF: -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) - if (!capable(CAP_SYS_ADMIN)) return -EACCES; -#endif - fsync_dev(inode->i_rdev); - invalidate_buffers(inode->i_rdev); - break; - RO_IOCTLS(inode->i_rdev, arg); -#else - case BLKROSET: - case BLKROGET: - case BLKFLSBUF: - ret = blk_ioctl(inode->i_rdev, cmd, arg); - break; -#endif - default: - ret = -EINVAL; - } - - return ret; -} /* ftl_ioctl */ + partition_t *part = (void *)dev; + u_long sect; -/*====================================================================== + /* Sort of arbitrary: round size down to 4KiB boundary */ + sect = le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE; - Handler for block device requests + geo->heads = 1; + geo->sectors = 8; + geo->cylinders = sect >> 3; -======================================================================*/ + return 0; +} -static int ftl_reread_partitions(int minor) +static int ftl_readsect(struct mtd_blktrans_dev *dev, + unsigned long block, char *buf) { - partition_t *part = myparts[minor >> 4]; - int i, whole; - - DEBUG(0, "ftl_cs: ftl_reread_partition(%d)\n", minor); - if ((atomic_read(&part->open) > 1)) { - return -EBUSY; - } - whole = minor & ~(MAX_PART-1); - - i = MAX_PART - 1; - while (i-- > 0) { - if (ftl_hd[whole+i].nr_sects > 0) { - kdev_t rdev = MKDEV(FTL_MAJOR, whole+i); - - invalidate_device(rdev, 1); - } - ftl_hd[whole+i].start_sect = 0; - ftl_hd[whole+i].nr_sects = 0; - } - - scan_header(part); - - register_disk(&ftl_gendisk, whole >> PART_BITS, MAX_PART, - &ftl_blk_fops, le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE); - -#ifdef PCMCIA_DEBUG - for (i = 0; i < MAX_PART; i++) { - if (ftl_hd[whole+i].nr_sects > 0) - printk(KERN_INFO " %d: start %ld size %ld\n", i, - ftl_hd[whole+i].start_sect, - ftl_hd[whole+i].nr_sects); - } -#endif - return 0; + return ftl_read((void *)dev, buf, block, 1); } -/*====================================================================== - - Handler for block device requests - -======================================================================*/ - -static void do_ftl_request(request_arg_t) +static int ftl_writesect(struct mtd_blktrans_dev *dev, + unsigned long block, char *buf) { - int ret, minor; - partition_t *part; - - do { - // sti(); - INIT_REQUEST; - - minor = MINOR(CURRENT->rq_dev); - - part = myparts[minor >> 4]; - if (part) { - ret = 0; - - switch (CURRENT->cmd) { - case READ: - ret = ftl_read(part, CURRENT->buffer, - CURRENT->sector+ftl_hd[minor].start_sect, - CURRENT->current_nr_sectors); - if (ret) printk("ftl_read returned %d\n", ret); - break; - - case WRITE: - ret = ftl_write(part, CURRENT->buffer, - CURRENT->sector+ftl_hd[minor].start_sect, - CURRENT->current_nr_sectors); - if (ret) printk("ftl_write returned %d\n", ret); - break; - - default: - panic("ftl_cs: unknown block command!\n"); - - } - } else { - ret = 1; - printk("NULL part in ftl_request\n"); - } - - if (!ret) { - CURRENT->sector += CURRENT->current_nr_sectors; - } - - end_request((ret == 0) ? 1 : 0); - } while (1); -} /* do_ftl_request */ + return ftl_write((void *)dev, buf, block, 1); +} /*====================================================================*/ @@ -1337,19 +1039,9 @@ } /* ftl_freepart */ -static void ftl_notify_add(struct mtd_info *mtd) +static void ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) { partition_t *partition; - int device; - - for (device=0; device < MAX_MTD_DEVICES && myparts[device]; device++) - ; - - if (device == MAX_MTD_DEVICES) { - printk(KERN_NOTICE "Maximum number of FTL partitions reached\n" - "Not scanning <%s>\n", mtd->name); - return; - } partition = kmalloc(sizeof(partition_t), GFP_KERNEL); @@ -1361,92 +1053,55 @@ memset(partition, 0, sizeof(partition_t)); - partition->mtd = mtd; + partition->mbd.mtd = mtd; if ((scan_header(partition) == 0) && (build_maps(partition) == 0)) { partition->state = FTL_FORMATTED; - atomic_set(&partition->open, 0); - myparts[device] = partition; - ftl_reread_partitions(device << 4); #ifdef PCMCIA_DEBUG - printk(KERN_INFO "ftl_cs: opening %d kb FTL partition\n", + printk(KERN_INFO "ftl_cs: opening %d KiB FTL partition\n", le32_to_cpu(partition->header.FormattedSize) >> 10); #endif + partition->mbd.size = le32_to_cpu(partition->header.FormattedSize) >> 9; + partition->mbd.blksize = SECTOR_SIZE; + partition->mbd.tr = tr; + partition->mbd.devnum = -1; + if (add_mtd_blktrans_dev((void *)partition)) + kfree(partition); + } else kfree(partition); } -static void ftl_notify_remove(struct mtd_info *mtd) +static void ftl_remove_dev(struct mtd_blktrans_dev *dev) { - int i,j; - - /* Q: What happens if you try to remove a device which has - * a currently-open FTL partition on it? - * - * A: You don't. The ftl_open routine is responsible for - * increasing the use count of the driver module which - * it uses. - */ - - /* That's the theory, anyway :) */ - - for (i=0; i< MAX_MTD_DEVICES; i++) - if (myparts[i] && myparts[i]->mtd == mtd) { - - if (myparts[i]->state == FTL_FORMATTED) - ftl_freepart(myparts[i]); - - myparts[i]->state = 0; - for (j=0; j<16; j++) { - ftl_gendisk.part[j].nr_sects=0; - ftl_gendisk.part[j].start_sect=0; - } - kfree(myparts[i]); - myparts[i] = NULL; - } + del_mtd_blktrans_dev(dev); + kfree(dev); } +struct mtd_blktrans_ops ftl_tr = { + .name = "ftl", + .major = FTL_MAJOR, + .part_bits = PART_BITS, + .readsect = ftl_readsect, + .writesect = ftl_writesect, + .getgeo = ftl_getgeo, + .add_mtd = ftl_add_mtd, + .remove_dev = ftl_remove_dev, + .owner = THIS_MODULE, +}; + int init_ftl(void) { - int i; + DEBUG(0, "$Id: ftl.c,v 1.3 2004/11/03 00:04:42 joff Exp $\n"); - memset(myparts, 0, sizeof(myparts)); - - DEBUG(0, "$Id: ftl.c,v 1.1 2004/07/22 19:49:45 joff Exp $\n"); - - if (register_blkdev(FTL_MAJOR, "ftl", &ftl_blk_fops)) { - printk(KERN_NOTICE "ftl_cs: unable to grab major " - "device number!\n"); - return -EAGAIN; - } - - for (i = 0; i < MINOR_NR(MAX_DEV, 0, 0); i++) - ftl_blocksizes[i] = 1024; - for (i = 0; i < MAX_DEV*MAX_PART; i++) { - ftl_hd[i].nr_sects = 0; - ftl_hd[i].start_sect = 0; - } - blksize_size[FTL_MAJOR] = ftl_blocksizes; - ftl_gendisk.major = FTL_MAJOR; - blk_init_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR), &do_ftl_request); - add_gendisk(&ftl_gendisk); - - register_mtd_user(&ftl_notifier); - - return 0; + return register_mtd_blktrans(&ftl_tr); } static void __exit cleanup_ftl(void) { - unregister_mtd_user(&ftl_notifier); - - unregister_blkdev(FTL_MAJOR, "ftl"); - blk_cleanup_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR)); - blksize_size[FTL_MAJOR] = NULL; - - del_gendisk(&ftl_gendisk); + deregister_mtd_blktrans(&ftl_tr); } module_init(init_ftl); Index: drivers/mtd/mtdblock.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/mtdblock.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/mtdblock.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/mtdblock.c 3 Nov 2004 00:04:42 -0000 1.3 @@ -1,52 +1,25 @@ /* * Direct MTD block device access * - * $Id: mtdblock.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: mtdblock.c,v 1.3 2004/11/03 00:04:42 joff Exp $ * - * 02-nov-2000 Nicolas Pitre Added read-modify-write with cache + * (C) 2000-2003 Nicolas Pitre + * (C) 1999-2003 David Woodhouse */ #include #include #include #include +#include +#include #include +#include #include -#include - -#define MAJOR_NR MTD_BLOCK_MAJOR -#define DEVICE_NAME "mtdblock" -#define DEVICE_REQUEST mtdblock_request -#define DEVICE_NR(device) (device) -#define DEVICE_ON(device) -#define DEVICE_OFF(device) -#define DEVICE_NO_RANDOM -#include -/* for old kernels... */ -#ifndef QUEUE_EMPTY -#define QUEUE_EMPTY (!CURRENT) -#endif -#if LINUX_VERSION_CODE < 0x20300 -#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].plug_tq.sync) -#else -#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].request_queue.plugged) -#endif - -#ifdef CONFIG_DEVFS_FS -#include -static void mtd_notify_add(struct mtd_info* mtd); -static void mtd_notify_remove(struct mtd_info* mtd); -static struct mtd_notifier notifier = { - mtd_notify_add, - mtd_notify_remove, - NULL -}; -static devfs_handle_t devfs_dir_handle = NULL; -static devfs_handle_t devfs_rw_handle[MAX_MTD_DEVICES]; -#endif +#include static struct mtdblk_dev { - struct mtd_info *mtd; /* Locked */ + struct mtd_info *mtd; int count; struct semaphore cache_sem; unsigned char *cache_data; @@ -55,19 +28,6 @@ enum { STATE_EMPTY, STATE_CLEAN, STATE_DIRTY } cache_state; } *mtdblks[MAX_MTD_DEVICES]; -static spinlock_t mtdblks_lock; - -static int mtd_sizes[MAX_MTD_DEVICES]; -static int mtd_blksizes[MAX_MTD_DEVICES]; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14) -#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT -#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT -#else -#define BLK_INC_USE_COUNT do {} while(0) -#define BLK_DEC_USE_COUNT do {} while(0) -#endif - /* * Cache stuff... * @@ -151,7 +111,7 @@ return ret; /* - * Here we could argably set the cache state to STATE_CLEAN. + * Here we could argubly set the cache state to STATE_CLEAN. * However this could lead to inconsistency since we will not * be notified if this content is altered on the flash by other * means. Let's declare it empty and leave buffering tasks to @@ -277,57 +237,47 @@ return 0; } +static int mtdblock_readsect(struct mtd_blktrans_dev *dev, + unsigned long block, char *buf) +{ + struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; + return do_cached_read(mtdblk, block<<9, 512, buf); +} +static int mtdblock_writesect(struct mtd_blktrans_dev *dev, + unsigned long block, char *buf) +{ + struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; + if (unlikely(!mtdblk->cache_data)) { + mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize); + if (!mtdblk->cache_data) + return -EINTR; + /* -EINTR is not really correct, but it is the best match + * documented in man 2 write for all cases. We could also + * return -EAGAIN sometimes, but why bother? + */ + } + return do_cached_write(mtdblk, block<<9, 512, buf); +} -static int mtdblock_open(struct inode *inode, struct file *file) +static int mtdblock_open(struct mtd_blktrans_dev *mbd) { struct mtdblk_dev *mtdblk; - struct mtd_info *mtd; - int dev; + struct mtd_info *mtd = mbd->mtd; + int dev = mbd->devnum; DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n"); - if (!inode) - return -EINVAL; - - dev = MINOR(inode->i_rdev); - if (dev >= MAX_MTD_DEVICES) - return -EINVAL; - - BLK_INC_USE_COUNT; - - mtd = get_mtd_device(NULL, dev); - if (!mtd) - return -ENODEV; - if (MTD_ABSENT == mtd->type) { - put_mtd_device(mtd); - BLK_DEC_USE_COUNT; - return -ENODEV; - } - - spin_lock(&mtdblks_lock); - - /* If it's already open, no need to piss about. */ if (mtdblks[dev]) { mtdblks[dev]->count++; - spin_unlock(&mtdblks_lock); - put_mtd_device(mtd); return 0; } - /* OK, it's not open. Try to find it */ - - /* First we have to drop the lock, because we have to - to things which might sleep. - */ - spin_unlock(&mtdblks_lock); - + /* OK, it's not open. Create cache info for it */ mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL); - if (!mtdblk) { - put_mtd_device(mtd); - BLK_DEC_USE_COUNT; + if (!mtdblk) return -ENOMEM; - } + memset(mtdblk, 0, sizeof(*mtdblk)); mtdblk->count = 1; mtdblk->mtd = mtd; @@ -337,336 +287,102 @@ if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM && mtdblk->mtd->erasesize) { mtdblk->cache_size = mtdblk->mtd->erasesize; - mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize); - if (!mtdblk->cache_data) { - put_mtd_device(mtdblk->mtd); - kfree(mtdblk); - BLK_DEC_USE_COUNT; - return -ENOMEM; - } - } - - /* OK, we've created a new one. Add it to the list. */ - - spin_lock(&mtdblks_lock); - - if (mtdblks[dev]) { - /* Another CPU made one at the same time as us. */ - mtdblks[dev]->count++; - spin_unlock(&mtdblks_lock); - put_mtd_device(mtdblk->mtd); - vfree(mtdblk->cache_data); - kfree(mtdblk); - return 0; + mtdblk->cache_data = NULL; } mtdblks[dev] = mtdblk; - mtd_sizes[dev] = mtdblk->mtd->size/1024; - if (mtdblk->mtd->erasesize) - mtd_blksizes[dev] = mtdblk->mtd->erasesize; - if (mtd_blksizes[dev] > PAGE_SIZE) - mtd_blksizes[dev] = PAGE_SIZE; - set_device_ro (inode->i_rdev, !(mtdblk->mtd->flags & MTD_WRITEABLE)); - - spin_unlock(&mtdblks_lock); DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); return 0; } -static release_t mtdblock_release(struct inode *inode, struct file *file) +static int mtdblock_release(struct mtd_blktrans_dev *mbd) { - int dev; - struct mtdblk_dev *mtdblk; - DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n"); - - if (inode == NULL) - release_return(-ENODEV); + int dev = mbd->devnum; + struct mtdblk_dev *mtdblk = mtdblks[dev]; - dev = MINOR(inode->i_rdev); - mtdblk = mtdblks[dev]; + DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n"); down(&mtdblk->cache_sem); write_cached_data(mtdblk); up(&mtdblk->cache_sem); - spin_lock(&mtdblks_lock); if (!--mtdblk->count) { /* It was the last usage. Free the device */ mtdblks[dev] = NULL; - spin_unlock(&mtdblks_lock); if (mtdblk->mtd->sync) mtdblk->mtd->sync(mtdblk->mtd); - put_mtd_device(mtdblk->mtd); vfree(mtdblk->cache_data); kfree(mtdblk); - } else { - spin_unlock(&mtdblks_lock); } - DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); - BLK_DEC_USE_COUNT; - release_return(0); + return 0; } - -/* - * This is a special request_fn because it is executed in a process context - * to be able to sleep independently of the caller. The io_request_lock - * is held upon entry and exit. - * The head of our request queue is considered active so there is no need - * to dequeue requests before we are done. - */ -static void handle_mtdblock_request(void) +static int mtdblock_flush(struct mtd_blktrans_dev *dev) { - struct request *req; - struct mtdblk_dev *mtdblk; - unsigned int res; - - for (;;) { - INIT_REQUEST; - req = CURRENT; - spin_unlock_irq(&io_request_lock); - mtdblk = mtdblks[MINOR(req->rq_dev)]; - res = 0; - - if (MINOR(req->rq_dev) >= MAX_MTD_DEVICES) - panic("%s: minor out of bounds", __FUNCTION__); - - if ((req->sector + req->current_nr_sectors) > (mtdblk->mtd->size >> 9)) - goto end_req; - - // Handle the request - switch (req->cmd) - { - int err; - - case READ: - down(&mtdblk->cache_sem); - err = do_cached_read (mtdblk, req->sector << 9, - req->current_nr_sectors << 9, - req->buffer); - up(&mtdblk->cache_sem); - if (!err) - res = 1; - break; - - case WRITE: - // Read only device - if ( !(mtdblk->mtd->flags & MTD_WRITEABLE) ) - break; - - // Do the write - down(&mtdblk->cache_sem); - err = do_cached_write (mtdblk, req->sector << 9, - req->current_nr_sectors << 9, - req->buffer); - up(&mtdblk->cache_sem); - if (!err) - res = 1; - break; - } - -end_req: - spin_lock_irq(&io_request_lock); - end_request(res); - } -} + struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; -static volatile int leaving = 0; -static DECLARE_MUTEX_LOCKED(thread_sem); -static DECLARE_WAIT_QUEUE_HEAD(thr_wq); - -int mtdblock_thread(void *dummy) -{ - struct task_struct *tsk = current; - DECLARE_WAITQUEUE(wait, tsk); - - /* we might get involved when memory gets low, so use PF_MEMALLOC */ - tsk->flags |= PF_MEMALLOC; - strcpy(tsk->comm, "mtdblockd"); - spin_lock_irq(&tsk->sigmask_lock); - sigfillset(&tsk->blocked); - recalc_sigpending(tsk); - spin_unlock_irq(&tsk->sigmask_lock); - daemonize(); - - while (!leaving) { - add_wait_queue(&thr_wq, &wait); - set_current_state(TASK_INTERRUPTIBLE); - spin_lock_irq(&io_request_lock); - if (QUEUE_EMPTY || QUEUE_PLUGGED) { - spin_unlock_irq(&io_request_lock); - schedule(); - remove_wait_queue(&thr_wq, &wait); - } else { - remove_wait_queue(&thr_wq, &wait); - set_current_state(TASK_RUNNING); - handle_mtdblock_request(); - spin_unlock_irq(&io_request_lock); - } - } + down(&mtdblk->cache_sem); + write_cached_data(mtdblk); + up(&mtdblk->cache_sem); - up(&thread_sem); + if (mtdblk->mtd->sync) + mtdblk->mtd->sync(mtdblk->mtd); return 0; } -#if LINUX_VERSION_CODE < 0x20300 -#define RQFUNC_ARG void -#else -#define RQFUNC_ARG request_queue_t *q -#endif - -static void mtdblock_request(RQFUNC_ARG) +static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) { - /* Don't do anything, except wake the thread if necessary */ - wake_up(&thr_wq); -} + struct mtd_blktrans_dev *dev = kmalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return; -static int mtdblock_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg) -{ - struct mtdblk_dev *mtdblk; - - mtdblk = mtdblks[MINOR(inode->i_rdev)]; + memset(dev, 0, sizeof(*dev)); -#ifdef PARANOIA - if (!mtdblk) - BUG(); -#endif + dev->mtd = mtd; + dev->devnum = mtd->index; + dev->blksize = 512; + dev->size = mtd->size >> 9; + dev->tr = tr; - switch (cmd) { - case BLKGETSIZE: /* Return device size */ - return put_user((mtdblk->mtd->size >> 9), (unsigned long *) arg); - -#ifdef BLKGETSIZE64 - case BLKGETSIZE64: - return put_user((u64)mtdblk->mtd->size, (u64 *)arg); -#endif - - case BLKFLSBUF: -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) - if(!capable(CAP_SYS_ADMIN)) - return -EACCES; -#endif - fsync_dev(inode->i_rdev); - invalidate_buffers(inode->i_rdev); - down(&mtdblk->cache_sem); - write_cached_data(mtdblk); - up(&mtdblk->cache_sem); - if (mtdblk->mtd->sync) - mtdblk->mtd->sync(mtdblk->mtd); - return 0; + if (!(mtd->flags & MTD_WRITEABLE)) + dev->readonly = 1; - default: - return -EINVAL; - } + add_mtd_blktrans_dev(dev); } -#if LINUX_VERSION_CODE < 0x20326 -static struct file_operations mtd_fops = -{ - open: mtdblock_open, - ioctl: mtdblock_ioctl, - release: mtdblock_release, - read: block_read, - write: block_write -}; -#else -static struct block_device_operations mtd_fops = +static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14) - owner: THIS_MODULE, -#endif - open: mtdblock_open, - release: mtdblock_release, - ioctl: mtdblock_ioctl -}; -#endif - -#ifdef CONFIG_DEVFS_FS -/* Notification that a new device has been added. Create the devfs entry for - * it. */ - -static void mtd_notify_add(struct mtd_info* mtd) -{ - char name[8]; - - if (!mtd || mtd->type == MTD_ABSENT) - return; - - sprintf(name, "%d", mtd->index); - devfs_rw_handle[mtd->index] = devfs_register(devfs_dir_handle, name, - DEVFS_FL_DEFAULT, MTD_BLOCK_MAJOR, mtd->index, - S_IFBLK | S_IRUGO | S_IWUGO, - &mtd_fops, NULL); + del_mtd_blktrans_dev(dev); + kfree(dev); } -static void mtd_notify_remove(struct mtd_info* mtd) -{ - if (!mtd || mtd->type == MTD_ABSENT) - return; - - devfs_unregister(devfs_rw_handle[mtd->index]); -} -#endif +struct mtd_blktrans_ops mtdblock_tr = { + .name = "mtdblock", + .major = 31, + .part_bits = 0, + .open = mtdblock_open, + .flush = mtdblock_flush, + .release = mtdblock_release, + .readsect = mtdblock_readsect, + .writesect = mtdblock_writesect, + .add_mtd = mtdblock_add_mtd, + .remove_dev = mtdblock_remove_dev, + .owner = THIS_MODULE, +}; int __init init_mtdblock(void) { - int i; - - spin_lock_init(&mtdblks_lock); -#ifdef CONFIG_DEVFS_FS - if (devfs_register_blkdev(MTD_BLOCK_MAJOR, DEVICE_NAME, &mtd_fops)) - { - printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n", - MTD_BLOCK_MAJOR); - return -EAGAIN; - } - - devfs_dir_handle = devfs_mk_dir(NULL, DEVICE_NAME, NULL); - register_mtd_user(¬ifier); -#else - if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) { - printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n", - MTD_BLOCK_MAJOR); - return -EAGAIN; - } -#endif - - /* We fill it in at open() time. */ - for (i=0; i< MAX_MTD_DEVICES; i++) { - mtd_sizes[i] = 0; - mtd_blksizes[i] = BLOCK_SIZE; - } - init_waitqueue_head(&thr_wq); - /* Allow the block size to default to BLOCK_SIZE. */ - blksize_size[MAJOR_NR] = mtd_blksizes; - blk_size[MAJOR_NR] = mtd_sizes; - - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request); - kernel_thread (mtdblock_thread, NULL, CLONE_FS|CLONE_FILES|CLONE_SIGHAND); - return 0; + return register_mtd_blktrans(&mtdblock_tr); } static void __exit cleanup_mtdblock(void) { - leaving = 1; - wake_up(&thr_wq); - down(&thread_sem); -#ifdef CONFIG_DEVFS_FS - unregister_mtd_user(¬ifier); - devfs_unregister(devfs_dir_handle); - devfs_unregister_blkdev(MTD_BLOCK_MAJOR, DEVICE_NAME); -#else - unregister_blkdev(MAJOR_NR,DEVICE_NAME); -#endif - blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); - blksize_size[MAJOR_NR] = NULL; - blk_size[MAJOR_NR] = NULL; + deregister_mtd_blktrans(&mtdblock_tr); } module_init(init_mtdblock); Index: drivers/mtd/mtdblock_ro.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/mtdblock_ro.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/mtdblock_ro.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/mtdblock_ro.c 3 Nov 2004 00:04:42 -0000 1.3 @@ -1,301 +1,87 @@ /* - * $Id: mtdblock_ro.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: mtdblock_ro.c,v 1.3 2004/11/03 00:04:42 joff Exp $ * - * Read-only version of the mtdblock device, without the - * read/erase/modify/writeback stuff + * (C) 2003 David Woodhouse + * + * Simple read-only (writable only for RAM) mtdblock driver */ -#ifdef MTDBLOCK_DEBUG -#define DEBUGLVL debug -#endif - - -#include -#include - +#include +#include #include -#include +#include -#define MAJOR_NR MTD_BLOCK_MAJOR -#define DEVICE_NAME "mtdblock" -#define DEVICE_REQUEST mtdblock_request -#define DEVICE_NR(device) (device) -#define DEVICE_ON(device) -#define DEVICE_OFF(device) -#define DEVICE_NO_RANDOM -#include - -#if LINUX_VERSION_CODE < 0x20300 -#define RQFUNC_ARG void -#define blkdev_dequeue_request(req) do {CURRENT = req->next;} while (0) -#else -#define RQFUNC_ARG request_queue_t *q -#endif - -#ifdef MTDBLOCK_DEBUG -static int debug = MTDBLOCK_DEBUG; -MODULE_PARM(debug, "i"); -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14) -#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT -#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT -#else -#define BLK_INC_USE_COUNT do {} while(0) -#define BLK_DEC_USE_COUNT do {} while(0) -#endif - -static int mtd_sizes[MAX_MTD_DEVICES]; - - -static int mtdblock_open(struct inode *inode, struct file *file) +static int mtdblock_readsect(struct mtd_blktrans_dev *dev, + unsigned long block, char *buf) { - struct mtd_info *mtd = NULL; - - int dev; - - DEBUG(1,"mtdblock_open\n"); - - if (inode == 0) - return -EINVAL; - - dev = MINOR(inode->i_rdev); - - mtd = get_mtd_device(NULL, dev); - if (!mtd) - return -EINVAL; - if (MTD_ABSENT == mtd->type) { - put_mtd_device(mtd); - return -EINVAL; - } - - BLK_INC_USE_COUNT; - - mtd_sizes[dev] = mtd->size>>9; - - DEBUG(1, "ok\n"); + size_t retlen; + if (dev->mtd->read(dev->mtd, (block * 512), 512, &retlen, buf)) + return 1; return 0; } -static release_t mtdblock_release(struct inode *inode, struct file *file) +static int mtdblock_writesect(struct mtd_blktrans_dev *dev, + unsigned long block, char *buf) { - int dev; - struct mtd_info *mtd; + size_t retlen; - DEBUG(1, "mtdblock_release\n"); - - if (inode == NULL) - release_return(-ENODEV); - - dev = MINOR(inode->i_rdev); - mtd = __get_mtd_device(NULL, dev); - - if (!mtd) { - printk(KERN_WARNING "MTD device is absent on mtd_release!\n"); - BLK_DEC_USE_COUNT; - release_return(-ENODEV); - } - - if (mtd->sync) - mtd->sync(mtd); + if (dev->mtd->write(dev->mtd, (block * 512), 512, &retlen, buf)) + return 1; + return 0; +} - put_mtd_device(mtd); +static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) +{ + struct mtd_blktrans_dev *dev = kmalloc(sizeof(*dev), GFP_KERNEL); - DEBUG(1, "ok\n"); + if (!dev) + return; - BLK_DEC_USE_COUNT; - release_return(0); -} + memset(dev, 0, sizeof(*dev)); + dev->mtd = mtd; + dev->devnum = mtd->index; + dev->blksize = 512; + dev->size = mtd->size >> 9; + dev->tr = tr; + if ((mtd->flags & (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEABLE)) != + (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEABLE)) + dev->readonly = 1; -static void mtdblock_request(RQFUNC_ARG) -{ - struct request *current_request; - unsigned int res = 0; - struct mtd_info *mtd; - - while (1) - { - /* Grab the Request and unlink it from the request list, INIT_REQUEST - will execute a return if we are done. */ - INIT_REQUEST; - current_request = CURRENT; - - if (MINOR(current_request->rq_dev) >= MAX_MTD_DEVICES) - { - printk("mtd: Unsupported device!\n"); - end_request(0); - continue; - } - - // Grab our MTD structure - - mtd = __get_mtd_device(NULL, MINOR(current_request->rq_dev)); - if (!mtd) { - printk("MTD device %d doesn't appear to exist any more\n", CURRENT_DEV); - end_request(0); - } - - if (current_request->sector << 9 > mtd->size || - (current_request->sector + current_request->current_nr_sectors) << 9 > mtd->size) - { - printk("mtd: Attempt to read past end of device!\n"); - printk("size: %x, sector: %lx, nr_sectors %lx\n", mtd->size, - current_request->sector, current_request->current_nr_sectors); - end_request(0); - continue; - } - - /* Remove the request we are handling from the request list so nobody messes - with it */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) - /* Now drop the lock that the ll_rw_blk functions grabbed for us - and process the request. This is necessary due to the extreme time - we spend processing it. */ - spin_unlock_irq(&io_request_lock); -#endif - - // Handle the request - switch (current_request->cmd) - { - size_t retlen; - - case READ: - if (MTD_READ(mtd,current_request->sector<<9, - current_request->current_nr_sectors << 9, - &retlen, current_request->buffer) == 0) - res = 1; - else - res = 0; - break; - - case WRITE: - - /* printk("mtdblock_request WRITE sector=%d(%d)\n",current_request->sector, - current_request->current_nr_sectors); - */ - - // Read only device - if ((mtd->flags & MTD_CAP_RAM) == 0) - { - res = 0; - break; - } - - // Do the write - if (MTD_WRITE(mtd,current_request->sector<<9, - current_request->current_nr_sectors << 9, - &retlen, current_request->buffer) == 0) - res = 1; - else - res = 0; - break; - - // Shouldn't happen - default: - printk("mtd: unknown request\n"); - break; - } - - // Grab the lock and re-thread the item onto the linked list -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) - spin_lock_irq(&io_request_lock); -#endif - end_request(res); - } + add_mtd_blktrans_dev(dev); } - - -static int mtdblock_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg) +static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev) { - struct mtd_info *mtd; - - mtd = __get_mtd_device(NULL, MINOR(inode->i_rdev)); - - if (!mtd) return -EINVAL; - - switch (cmd) { - case BLKGETSIZE: /* Return device size */ - return put_user((mtd->size >> 9), (unsigned long *) arg); - -#ifdef BLKGETSIZE64 - case BLKGETSIZE64: - return put_user((u64)mtd->size, (u64 *)arg); -#endif - - case BLKFLSBUF: -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) - if(!capable(CAP_SYS_ADMIN)) return -EACCES; -#endif - fsync_dev(inode->i_rdev); - invalidate_buffers(inode->i_rdev); - if (mtd->sync) - mtd->sync(mtd); - return 0; - - default: - return -ENOTTY; - } + del_mtd_blktrans_dev(dev); + kfree(dev); } -#if LINUX_VERSION_CODE < 0x20326 -static struct file_operations mtd_fops = -{ - open: mtdblock_open, - ioctl: mtdblock_ioctl, - release: mtdblock_release, - read: block_read, - write: block_write -}; -#else -static struct block_device_operations mtd_fops = -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14) - owner: THIS_MODULE, -#endif - open: mtdblock_open, - release: mtdblock_release, - ioctl: mtdblock_ioctl +struct mtd_blktrans_ops mtdblock_tr = { + .name = "mtdblock", + .major = 31, + .part_bits = 0, + .readsect = mtdblock_readsect, + .writesect = mtdblock_writesect, + .add_mtd = mtdblock_add_mtd, + .remove_dev = mtdblock_remove_dev, + .owner = THIS_MODULE, }; -#endif -int __init init_mtdblock(void) +static int __init mtdblock_init(void) { - int i; - - if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) { - printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n", - MTD_BLOCK_MAJOR); - return -EAGAIN; - } - - /* We fill it in at open() time. */ - for (i=0; i< MAX_MTD_DEVICES; i++) { - mtd_sizes[i] = 0; - } - - /* Allow the block size to default to BLOCK_SIZE. */ - blksize_size[MAJOR_NR] = NULL; - blk_size[MAJOR_NR] = mtd_sizes; - - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request); - return 0; + return register_mtd_blktrans(&mtdblock_tr); } -static void __exit cleanup_mtdblock(void) +static void __exit mtdblock_exit(void) { - unregister_blkdev(MAJOR_NR,DEVICE_NAME); - blk_size[MAJOR_NR] = NULL; - blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); + deregister_mtd_blktrans(&mtdblock_tr); } -module_init(init_mtdblock); -module_exit(cleanup_mtdblock); - +module_init(mtdblock_init); +module_exit(mtdblock_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Erwin Authried et al."); +MODULE_AUTHOR("David Woodhouse "); MODULE_DESCRIPTION("Simple read-only block device emulation access to MTD devices"); Index: drivers/mtd/mtdchar.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/mtdchar.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/mtdchar.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/mtdchar.c 3 Nov 2004 00:04:42 -0000 1.3 @@ -1,8 +1,7 @@ /* - * $Id: mtdchar.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: mtdchar.c,v 1.3 2004/11/03 00:04:42 joff Exp $ * * Character-device access to raw MTD devices. - * Pure 2.4 version - compatibility cruft removed to mtdchar-compat.c * */ @@ -10,21 +9,14 @@ #include #include #include +#include #include +#include +#include +#include #ifdef CONFIG_DEVFS_FS #include -static void mtd_notify_add(struct mtd_info* mtd); -static void mtd_notify_remove(struct mtd_info* mtd); - -static struct mtd_notifier notifier = { - add: mtd_notify_add, - remove: mtd_notify_remove, -}; - -static devfs_handle_t devfs_dir_handle; -static devfs_handle_t devfs_rw_handle[MAX_MTD_DEVICES]; -static devfs_handle_t devfs_ro_handle[MAX_MTD_DEVICES]; #endif static loff_t mtd_lseek (struct file *file, loff_t offset, int orig) @@ -60,7 +52,7 @@ static int mtd_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); int devnum = minor >> 1; struct mtd_info *mtd; @@ -147,7 +139,13 @@ return -ENOMEM; ret = MTD_READ(mtd, *ppos, len, &retlen, kbuf); - if (!ret) { + /* Nand returns -EBADMSG on ecc errors, but it returns + * the data. For our userspace tools it is important + * to dump areas with ecc errors ! + * Userspace software which accesses NAND this way + * must be aware of the fact that it deals with NAND + */ + if (!ret || (ret == -EBADMSG)) { *ppos += retlen; if (copy_to_user(buf, kbuf, retlen)) { kfree(kbuf); @@ -166,7 +164,7 @@ kfree(kbuf); } - + return total_retlen; } /* mtd_read */ @@ -230,7 +228,7 @@ IOCTL calls for getting device parameters. ======================================================================*/ -static void mtd_erase_callback (struct erase_info *instr) +static void mtdchar_erase_callback (struct erase_info *instr) { wake_up((wait_queue_head_t *)instr->priv); } @@ -303,12 +301,12 @@ memset (erase,0,sizeof(struct erase_info)); if (copy_from_user(&erase->addr, (u_long *)arg, - 2 * sizeof(u_long))) { + sizeof(struct erase_info_user))) { kfree(erase); return -EFAULT; } erase->mtd = mtd; - erase->callback = mtd_erase_callback; + erase->callback = mtdchar_erase_callback; erase->priv = (unsigned long)&waitq; /* @@ -416,109 +414,75 @@ case MEMLOCK: { - unsigned long adrs[2]; + struct erase_info_user info; - if (copy_from_user(adrs ,(void *)arg, 2* sizeof(unsigned long))) + if (copy_from_user(&info ,(void *)arg, sizeof(info))) return -EFAULT; if (!mtd->lock) ret = -EOPNOTSUPP; else - ret = mtd->lock(mtd, adrs[0], adrs[1]); + ret = mtd->lock(mtd, info.start, info.length); break; } case MEMUNLOCK: { - unsigned long adrs[2]; + struct erase_info_user info; - if (copy_from_user(adrs, (void *)arg, 2* sizeof(unsigned long))) + if (copy_from_user(&info, (void *)arg, sizeof(info))) return -EFAULT; if (!mtd->unlock) ret = -EOPNOTSUPP; else - ret = mtd->unlock(mtd, adrs[0], adrs[1]); + ret = mtd->unlock(mtd, info.start, info.length); break; } - case MEMWRITEDATA: + case MEMSETOOBSEL: { - struct mtd_oob_buf buf; - void *databuf; - ssize_t retlen; + if (copy_from_user(&mtd->oobinfo ,(void *)arg, sizeof(struct nand_oobinfo))) + return -EFAULT; + break; + } + + case MEMGETOOBSEL: + { + if (copy_to_user((struct nand_oobinfo *) arg, &(mtd->oobinfo), sizeof(struct nand_oobinfo))) + return -EFAULT; + break; + } + + case MEMGETBADBLOCK: + { + loff_t offs; - if (copy_from_user(&buf, (struct mtd_oob_buf *)arg, sizeof(struct mtd_oob_buf))) + if (copy_from_user(&offs ,(void *)arg, sizeof(loff_t))) return -EFAULT; - if (buf.length > 0x4096) - return -EINVAL; - - if (!mtd->write_ecc) + if (!mtd->block_isbad) ret = -EOPNOTSUPP; else - ret = verify_area(VERIFY_READ, (char *)buf.ptr, buf.length); - - if (ret) - return ret; - - databuf = kmalloc(buf.length, GFP_KERNEL); - if (!databuf) - return -ENOMEM; + return mtd->block_isbad(mtd, offs); - if (copy_from_user(databuf, buf.ptr, buf.length)) { - kfree(databuf); - return -EFAULT; - } - - ret = (mtd->write_ecc)(mtd, buf.start, buf.length, &retlen, databuf, NULL, 0); - - if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t))) - ret = -EFAULT; - - kfree(databuf); break; - } - case MEMREADDATA: + case MEMSETBADBLOCK: { - struct mtd_oob_buf buf; - void *databuf; - ssize_t retlen = 0; + loff_t offs; - if (copy_from_user(&buf, (struct mtd_oob_buf *)arg, sizeof(struct mtd_oob_buf))) + if (copy_from_user(&offs ,(void *)arg, sizeof(loff_t))) return -EFAULT; - - if (buf.length > 0x4096) - return -EINVAL; - - if (!mtd->read_ecc) + if (!mtd->block_markbad) ret = -EOPNOTSUPP; else - ret = verify_area(VERIFY_WRITE, (char *)buf.ptr, buf.length); - - if (ret) - return ret; - - databuf = kmalloc(buf.length, GFP_KERNEL); - if (!databuf) - return -ENOMEM; - - ret = (mtd->read_ecc)(mtd, buf.start, buf.length, &retlen, databuf, NULL, 0); - - if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t))) - ret = -EFAULT; - else if (retlen && copy_to_user(buf.ptr, databuf, retlen)) - ret = -EFAULT; - - kfree(databuf); + return mtd->block_markbad(mtd, offs); break; } - default: - DEBUG(MTD_DEBUG_LEVEL0, "Invalid ioctl %x (MEMGETINFO = %x)\n", cmd, MEMGETINFO); ret = -ENOTTY; } @@ -526,17 +490,22 @@ } /* memory_ioctl */ static struct file_operations mtd_fops = { - owner: THIS_MODULE, - llseek: mtd_lseek, /* lseek */ - read: mtd_read, /* read */ - write: mtd_write, /* write */ - ioctl: mtd_ioctl, /* ioctl */ - open: mtd_open, /* open */ - release: mtd_close, /* release */ + .owner = THIS_MODULE, + .llseek = mtd_lseek, + .read = mtd_read, + .write = mtd_write, + .ioctl = mtd_ioctl, + .open = mtd_open, + .release = mtd_close, }; #ifdef CONFIG_DEVFS_FS +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +static devfs_handle_t devfs_dir_handle; +static devfs_handle_t devfs_rw_handle[MAX_MTD_DEVICES]; +static devfs_handle_t devfs_ro_handle[MAX_MTD_DEVICES]; + /* Notification that a new device has been added. Create the devfs entry for * it. */ @@ -547,6 +516,7 @@ if (!mtd) return; + DEBUG(MTD_DEBUG_LEVEL0, "MTD_add, size=%d\n", mtd->size); sprintf(name, "%d", mtd->index); devfs_rw_handle[mtd->index] = devfs_register(devfs_dir_handle, name, DEVFS_FL_DEFAULT, MTD_CHAR_MAJOR, mtd->index*2, @@ -568,30 +538,56 @@ devfs_unregister(devfs_rw_handle[mtd->index]); devfs_unregister(devfs_ro_handle[mtd->index]); } + +#else + +static void mtd_notify_add(struct mtd_info* mtd) +{ + if (!mtd) + return; + + devfs_mk_cdev (MKDEV(MTD_CHAR_MAJOR, mtd->index*2), + S_IFCHR | S_IRUGO | S_IWUGO, + "mtd/%d", mtd->index); + + devfs_mk_cdev (MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1), + S_IFCHR | S_IRUGO, + "mtd/%dro", mtd->index); +} + +static void mtd_notify_remove(struct mtd_info* mtd) +{ + if (!mtd) + return; + + devfs_remove ("mtd/%d", mtd->index*2); + devfs_remove ("mtd/%dro", mtd->index*2); +} + +#endif +static struct mtd_notifier notifier = { + .add = mtd_notify_add, + .remove = mtd_notify_remove, +}; #endif static int __init init_mtdchar(void) { -#ifdef CONFIG_DEVFS_FS - if (devfs_register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops)) + if (register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops)) { printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n", MTD_CHAR_MAJOR); return -EAGAIN; } +#ifdef CONFIG_DEVFS_FS +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) devfs_dir_handle = devfs_mk_dir(NULL, "mtd", NULL); - +#else + devfs_mk_dir("mtd"); +#endif register_mtd_user(¬ifier); -#else - if (register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops)) - { - printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n", - MTD_CHAR_MAJOR); - return -EAGAIN; - } #endif - return 0; } @@ -599,11 +595,13 @@ { #ifdef CONFIG_DEVFS_FS unregister_mtd_user(¬ifier); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) devfs_unregister(devfs_dir_handle); - devfs_unregister_chrdev(MTD_CHAR_MAJOR, "mtd"); -#else - unregister_chrdev(MTD_CHAR_MAJOR, "mtd"); +#else + devfs_remove ("mtd"); +#endif #endif + unregister_chrdev(MTD_CHAR_MAJOR, "mtd"); } module_init(init_mtdchar); Index: drivers/mtd/mtdconcat.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/mtdconcat.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/mtdconcat.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/mtdconcat.c 3 Nov 2004 00:04:42 -0000 1.3 @@ -3,9 +3,11 @@ * * (C) 2002 Robert Kaiser * + * NAND support by Christian Gan + * * This code is GPL * - * $Id: mtdconcat.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: mtdconcat.c,v 1.3 2004/11/03 00:04:42 joff Exp $ */ #include @@ -24,7 +26,7 @@ */ struct mtd_concat { struct mtd_info mtd; - int num_subdev; + int num_subdev; struct mtd_info **subdev; }; @@ -35,21 +37,112 @@ #define SIZEOF_STRUCT_MTD_CONCAT(num_subdev) \ ((sizeof(struct mtd_concat) + (num_subdev) * sizeof(struct mtd_info *))) - /* * Given a pointer to the MTD object in the mtd_concat structure, * we can retrieve the pointer to that structure with this macro. */ #define CONCAT(x) ((struct mtd_concat *)(x)) - /* * MTD methods which look up the relevant subdevice, translate the * effective address and pass through to the subdevice. */ -static int concat_read (struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf) +static int +concat_read(struct mtd_info *mtd, loff_t from, size_t len, + size_t * retlen, u_char * buf) +{ + struct mtd_concat *concat = CONCAT(mtd); + int err = -EINVAL; + int i; + + *retlen = 0; + + for (i = 0; i < concat->num_subdev; i++) { + struct mtd_info *subdev = concat->subdev[i]; + size_t size, retsize; + + if (from >= subdev->size) { + /* Not destined for this subdev */ + size = 0; + from -= subdev->size; + continue; + } + if (from + len > subdev->size) + /* First part goes into this subdev */ + size = subdev->size - from; + else + /* Entire transaction goes into this subdev */ + size = len; + + err = subdev->read(subdev, from, size, &retsize, buf); + + if (err) + break; + + *retlen += retsize; + len -= size; + if (len == 0) + break; + + err = -EINVAL; + buf += size; + from = 0; + } + return err; +} + +static int +concat_write(struct mtd_info *mtd, loff_t to, size_t len, + size_t * retlen, const u_char * buf) +{ + struct mtd_concat *concat = CONCAT(mtd); + int err = -EINVAL; + int i; + + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + + *retlen = 0; + + for (i = 0; i < concat->num_subdev; i++) { + struct mtd_info *subdev = concat->subdev[i]; + size_t size, retsize; + + if (to >= subdev->size) { + size = 0; + to -= subdev->size; + continue; + } + if (to + len > subdev->size) + size = subdev->size - to; + else + size = len; + + if (!(subdev->flags & MTD_WRITEABLE)) + err = -EROFS; + else + err = subdev->write(subdev, to, size, &retsize, buf); + + if (err) + break; + + *retlen += retsize; + len -= size; + if (len == 0) + break; + + err = -EINVAL; + buf += size; + to = 0; + } + return err; +} + +static int +concat_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, + size_t * retlen, u_char * buf, u_char * eccbuf, + struct nand_oobinfo *oobsel) { struct mtd_concat *concat = CONCAT(mtd); int err = -EINVAL; @@ -57,43 +150,56 @@ *retlen = 0; - for(i = 0; i < concat->num_subdev; i++) - { + for (i = 0; i < concat->num_subdev; i++) { struct mtd_info *subdev = concat->subdev[i]; size_t size, retsize; - if (from >= subdev->size) - { - size = 0; + if (from >= subdev->size) { + /* Not destined for this subdev */ + size = 0; from -= subdev->size; + continue; } + + if (from + len > subdev->size) + /* First part goes into this subdev */ + size = subdev->size - from; else - { - if (from + len > subdev->size) - size = subdev->size - from; - else - size = len; - - err = subdev->read(subdev, from, size, &retsize, buf); - - if(err) - break; - - *retlen += retsize; - len -= size; - if(len == 0) - break; + /* Entire transaction goes into this subdev */ + size = len; + if (subdev->read_ecc) + err = subdev->read_ecc(subdev, from, size, + &retsize, buf, eccbuf, oobsel); + else err = -EINVAL; - buf += size; - from = 0; + + if (err) + break; + + *retlen += retsize; + len -= size; + if (len == 0) + break; + + err = -EINVAL; + buf += size; + if (eccbuf) { + eccbuf += subdev->oobsize; + /* in nand.c at least, eccbufs are + tagged with 2 (int)eccstatus'; we + must account for these */ + eccbuf += 2 * (sizeof (int)); } + from = 0; } return err; } -static int concat_write (struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf) +static int +concat_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, + size_t * retlen, const u_char * buf, u_char * eccbuf, + struct nand_oobinfo *oobsel) { struct mtd_concat *concat = CONCAT(mtd); int err = -EINVAL; @@ -104,47 +210,146 @@ *retlen = 0; - for(i = 0; i < concat->num_subdev; i++) - { + for (i = 0; i < concat->num_subdev; i++) { struct mtd_info *subdev = concat->subdev[i]; size_t size, retsize; - if (to >= subdev->size) - { - size = 0; + if (to >= subdev->size) { + size = 0; to -= subdev->size; + continue; } + if (to + len > subdev->size) + size = subdev->size - to; else - { - if (to + len > subdev->size) - size = subdev->size - to; - else - size = len; - - if (!(subdev->flags & MTD_WRITEABLE)) - err = -EROFS; - else - err = subdev->write(subdev, to, size, &retsize, buf); - - if(err) - break; - - *retlen += retsize; - len -= size; - if(len == 0) - break; + size = len; + if (!(subdev->flags & MTD_WRITEABLE)) + err = -EROFS; + else if (subdev->write_ecc) + err = subdev->write_ecc(subdev, to, size, + &retsize, buf, eccbuf, oobsel); + else err = -EINVAL; - buf += size; - to = 0; + + if (err) + break; + + *retlen += retsize; + len -= size; + if (len == 0) + break; + + err = -EINVAL; + buf += size; + if (eccbuf) + eccbuf += subdev->oobsize; + to = 0; + } + return err; +} + +static int +concat_read_oob(struct mtd_info *mtd, loff_t from, size_t len, + size_t * retlen, u_char * buf) +{ + struct mtd_concat *concat = CONCAT(mtd); + int err = -EINVAL; + int i; + + *retlen = 0; + + for (i = 0; i < concat->num_subdev; i++) { + struct mtd_info *subdev = concat->subdev[i]; + size_t size, retsize; + + if (from >= subdev->size) { + /* Not destined for this subdev */ + size = 0; + from -= subdev->size; + continue; } + if (from + len > subdev->size) + /* First part goes into this subdev */ + size = subdev->size - from; + else + /* Entire transaction goes into this subdev */ + size = len; + + if (subdev->read_oob) + err = subdev->read_oob(subdev, from, size, + &retsize, buf); + else + err = -EINVAL; + + if (err) + break; + + *retlen += retsize; + len -= size; + if (len == 0) + break; + + err = -EINVAL; + buf += size; + from = 0; + } + return err; +} + +static int +concat_write_oob(struct mtd_info *mtd, loff_t to, size_t len, + size_t * retlen, const u_char * buf) +{ + struct mtd_concat *concat = CONCAT(mtd); + int err = -EINVAL; + int i; + + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + + *retlen = 0; + + for (i = 0; i < concat->num_subdev; i++) { + struct mtd_info *subdev = concat->subdev[i]; + size_t size, retsize; + + if (to >= subdev->size) { + size = 0; + to -= subdev->size; + continue; + } + if (to + len > subdev->size) + size = subdev->size - to; + else + size = len; + + if (!(subdev->flags & MTD_WRITEABLE)) + err = -EROFS; + else if (subdev->write_oob) + err = subdev->write_oob(subdev, to, size, &retsize, + buf); + else + err = -EINVAL; + + if (err) + break; + + *retlen += retsize; + len -= size; + if (len == 0) + break; + + err = -EINVAL; + buf += size; + to = 0; } return err; } -static void concat_erase_callback (struct erase_info *instr) +static void concat_erase_callback(struct erase_info *instr) { - wake_up((wait_queue_head_t *)instr->priv); + wake_up((wait_queue_head_t *) instr->priv); } static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase) @@ -160,18 +365,18 @@ erase->mtd = mtd; erase->callback = concat_erase_callback; - erase->priv = (unsigned long)&waitq; - + erase->priv = (unsigned long) &waitq; + /* * FIXME: Allow INTERRUPTIBLE. Which means * not having the wait_queue head on the stack. */ err = mtd->erase(mtd, erase); - if (!err) - { + if (!err) { set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(&waitq, &wait); - if (erase->state != MTD_ERASE_DONE && erase->state != MTD_ERASE_FAILED) + if (erase->state != MTD_ERASE_DONE + && erase->state != MTD_ERASE_FAILED) schedule(); remove_wait_queue(&waitq, &wait); set_current_state(TASK_RUNNING); @@ -181,21 +386,21 @@ return err; } -static int concat_erase (struct mtd_info *mtd, struct erase_info *instr) +static int concat_erase(struct mtd_info *mtd, struct erase_info *instr) { struct mtd_concat *concat = CONCAT(mtd); struct mtd_info *subdev; int i, err; - u_int32_t length; + u_int32_t length, offset = 0; struct erase_info *erase; if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; - if(instr->addr > concat->mtd.size) + if (instr->addr > concat->mtd.size) return -EINVAL; - if(instr->len + instr->addr > concat->mtd.size) + if (instr->len + instr->addr > concat->mtd.size) return -EINVAL; /* @@ -204,23 +409,22 @@ * region info rather than looking at each particular sub-device * in turn. */ - if (!concat->mtd.numeraseregions) - { /* the easy case: device has uniform erase block size */ - if(instr->addr & (concat->mtd.erasesize - 1)) + if (!concat->mtd.numeraseregions) { + /* the easy case: device has uniform erase block size */ + if (instr->addr & (concat->mtd.erasesize - 1)) return -EINVAL; - if(instr->len & (concat->mtd.erasesize - 1)) + if (instr->len & (concat->mtd.erasesize - 1)) return -EINVAL; - } - else - { /* device has variable erase size */ - struct mtd_erase_region_info *erase_regions = concat->mtd.eraseregions; + } else { + /* device has variable erase size */ + struct mtd_erase_region_info *erase_regions = + concat->mtd.eraseregions; /* * Find the erase region where the to-be-erased area begins: */ - for(i = 0; i < concat->mtd.numeraseregions && - instr->addr >= erase_regions[i].offset; i++) - ; + for (i = 0; i < concat->mtd.numeraseregions && + instr->addr >= erase_regions[i].offset; i++) ; --i; /* @@ -228,25 +432,28 @@ * to-be-erased area begins. Verify that the starting * offset is aligned to this region's erase size: */ - if (instr->addr & (erase_regions[i].erasesize-1)) + if (instr->addr & (erase_regions[i].erasesize - 1)) return -EINVAL; /* * now find the erase region where the to-be-erased area ends: */ - for(; i < concat->mtd.numeraseregions && - (instr->addr + instr->len) >= erase_regions[i].offset ; ++i) - ; + for (; i < concat->mtd.numeraseregions && + (instr->addr + instr->len) >= erase_regions[i].offset; + ++i) ; --i; /* * check if the ending offset is aligned to this region's erase size */ - if ((instr->addr + instr->len) & (erase_regions[i].erasesize-1)) + if ((instr->addr + instr->len) & (erase_regions[i].erasesize - + 1)) return -EINVAL; } + instr->fail_addr = 0xffffffff; + /* make a local copy of instr to avoid modifying the caller's struct */ - erase = kmalloc(sizeof(struct erase_info),GFP_KERNEL); + erase = kmalloc(sizeof (struct erase_info), GFP_KERNEL); if (!erase) return -ENOMEM; @@ -258,39 +465,44 @@ * find the subdevice where the to-be-erased area begins, adjust * starting offset to be relative to the subdevice start */ - for(i = 0; i < concat->num_subdev; i++) - { + for (i = 0; i < concat->num_subdev; i++) { subdev = concat->subdev[i]; - if(subdev->size <= erase->addr) + if (subdev->size <= erase->addr) { erase->addr -= subdev->size; - else + offset += subdev->size; + } else { break; - } - if(i >= concat->num_subdev) /* must never happen since size */ - BUG(); /* limit has been verified above */ + } + } + + /* must never happen since size limit has been verified above */ + if (i >= concat->num_subdev) + BUG(); /* now do the erase: */ err = 0; - for(;length > 0; i++) /* loop for all subevices affected by this request */ - { - subdev = concat->subdev[i]; /* get current subdevice */ + for (; length > 0; i++) { + /* loop for all subdevices affected by this request */ + subdev = concat->subdev[i]; /* get current subdevice */ /* limit length to subdevice's size: */ - if(erase->addr + length > subdev->size) + if (erase->addr + length > subdev->size) erase->len = subdev->size - erase->addr; else erase->len = length; - if (!(subdev->flags & MTD_WRITEABLE)) - { + if (!(subdev->flags & MTD_WRITEABLE)) { err = -EROFS; break; } length -= erase->len; - if ((err = concat_dev_erase(subdev, erase))) - { - if(err == -EINVAL) /* sanity check: must never happen since */ - BUG(); /* block alignment has been checked above */ + if ((err = concat_dev_erase(subdev, erase))) { + /* sanity check: should never happen since + * block alignment has been checked above */ + if (err == -EINVAL) + BUG(); + if (erase->fail_addr != 0xffffffff) + instr->fail_addr = erase->fail_addr + offset; break; } /* @@ -302,96 +514,91 @@ * current subdevice, i.e. at offset zero. */ erase->addr = 0; + offset += subdev->size; } + instr->state = erase->state; kfree(erase); if (err) return err; - instr->state = MTD_ERASE_DONE; if (instr->callback) instr->callback(instr); return 0; } -static int concat_lock (struct mtd_info *mtd, loff_t ofs, size_t len) +static int concat_lock(struct mtd_info *mtd, loff_t ofs, size_t len) { struct mtd_concat *concat = CONCAT(mtd); int i, err = -EINVAL; - if ((len + ofs) > mtd->size) + if ((len + ofs) > mtd->size) return -EINVAL; - for(i = 0; i < concat->num_subdev; i++) - { + for (i = 0; i < concat->num_subdev; i++) { struct mtd_info *subdev = concat->subdev[i]; size_t size; - if (ofs >= subdev->size) - { - size = 0; + if (ofs >= subdev->size) { + size = 0; ofs -= subdev->size; + continue; } + if (ofs + len > subdev->size) + size = subdev->size - ofs; else - { - if (ofs + len > subdev->size) - size = subdev->size - ofs; - else - size = len; - - err = subdev->lock(subdev, ofs, size); - - if(err) - break; - - len -= size; - if(len == 0) - break; + size = len; - err = -EINVAL; - ofs = 0; - } + err = subdev->lock(subdev, ofs, size); + + if (err) + break; + + len -= size; + if (len == 0) + break; + + err = -EINVAL; + ofs = 0; } + return err; } -static int concat_unlock (struct mtd_info *mtd, loff_t ofs, size_t len) +static int concat_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) { struct mtd_concat *concat = CONCAT(mtd); int i, err = 0; - if ((len + ofs) > mtd->size) + if ((len + ofs) > mtd->size) return -EINVAL; - for(i = 0; i < concat->num_subdev; i++) - { + for (i = 0; i < concat->num_subdev; i++) { struct mtd_info *subdev = concat->subdev[i]; size_t size; - if (ofs >= subdev->size) - { - size = 0; + if (ofs >= subdev->size) { + size = 0; ofs -= subdev->size; + continue; } + if (ofs + len > subdev->size) + size = subdev->size - ofs; else - { - if (ofs + len > subdev->size) - size = subdev->size - ofs; - else - size = len; - - err = subdev->unlock(subdev, ofs, size); - - if(err) - break; - - len -= size; - if(len == 0) - break; + size = len; - err = -EINVAL; - ofs = 0; - } + err = subdev->unlock(subdev, ofs, size); + + if (err) + break; + + len -= size; + if (len == 0) + break; + + err = -EINVAL; + ofs = 0; } + return err; } @@ -400,8 +607,7 @@ struct mtd_concat *concat = CONCAT(mtd); int i; - for(i = 0; i < concat->num_subdev; i++) - { + for (i = 0; i < concat->num_subdev; i++) { struct mtd_info *subdev = concat->subdev[i]; subdev->sync(subdev); } @@ -412,10 +618,9 @@ struct mtd_concat *concat = CONCAT(mtd); int i, rc = 0; - for(i = 0; i < concat->num_subdev; i++) - { + for (i = 0; i < concat->num_subdev; i++) { struct mtd_info *subdev = concat->subdev[i]; - if((rc = subdev->suspend(subdev)) < 0) + if ((rc = subdev->suspend(subdev)) < 0) return rc; } return rc; @@ -426,8 +631,7 @@ struct mtd_concat *concat = CONCAT(mtd); int i; - for(i = 0; i < concat->num_subdev; i++) - { + for (i = 0; i < concat->num_subdev; i++) { struct mtd_info *subdev = concat->subdev[i]; subdev->resume(subdev); } @@ -439,11 +643,10 @@ * stored to *new_dev upon success. This function does _not_ * register any devices: this is the caller's responsibility. */ -struct mtd_info *mtd_concat_create( - struct mtd_info *subdev[], /* subdevices to concatenate */ - int num_devs, /* number of subdevices */ - char *name) /* name for the new device */ -{ +struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to concatenate */ + int num_devs, /* number of subdevices */ + char *name) +{ /* name for the new device */ int i; size_t size; struct mtd_concat *concat; @@ -451,90 +654,103 @@ int num_erase_region; printk(KERN_NOTICE "Concatenating MTD devices:\n"); - for(i = 0; i < num_devs; i++) + for (i = 0; i < num_devs; i++) printk(KERN_NOTICE "(%d): \"%s\"\n", i, subdev[i]->name); printk(KERN_NOTICE "into device \"%s\"\n", name); /* allocate the device structure */ size = SIZEOF_STRUCT_MTD_CONCAT(num_devs); - concat = kmalloc (size, GFP_KERNEL); - if(!concat) - { - printk ("memory allocation error while creating concatenated device \"%s\"\n", - name); - return NULL; + concat = kmalloc(size, GFP_KERNEL); + if (!concat) { + printk + ("memory allocation error while creating concatenated device \"%s\"\n", + name); + return NULL; } memset(concat, 0, size); - concat->subdev = (struct mtd_info **)(concat + 1); + concat->subdev = (struct mtd_info **) (concat + 1); /* * Set up the new "super" device's MTD object structure, check for * incompatibilites between the subdevices. */ - concat->mtd.type = subdev[0]->type; - concat->mtd.flags = subdev[0]->flags; - concat->mtd.size = subdev[0]->size; + concat->mtd.type = subdev[0]->type; + concat->mtd.flags = subdev[0]->flags; + concat->mtd.size = subdev[0]->size; concat->mtd.erasesize = subdev[0]->erasesize; - concat->mtd.oobblock = subdev[0]->oobblock; - concat->mtd.oobsize = subdev[0]->oobsize; - concat->mtd.ecctype = subdev[0]->ecctype; - concat->mtd.eccsize = subdev[0]->eccsize; - - concat->subdev[0] = subdev[0]; - - for(i = 1; i < num_devs; i++) - { - if(concat->mtd.type != subdev[i]->type) - { + concat->mtd.oobblock = subdev[0]->oobblock; + concat->mtd.oobsize = subdev[0]->oobsize; + concat->mtd.ecctype = subdev[0]->ecctype; + concat->mtd.eccsize = subdev[0]->eccsize; + if (subdev[0]->read_ecc) + concat->mtd.read_ecc = concat_read_ecc; + if (subdev[0]->write_ecc) + concat->mtd.write_ecc = concat_write_ecc; + if (subdev[0]->read_oob) + concat->mtd.read_oob = concat_read_oob; + if (subdev[0]->write_oob) + concat->mtd.write_oob = concat_write_oob; + + concat->subdev[0] = subdev[0]; + + for (i = 1; i < num_devs; i++) { + if (concat->mtd.type != subdev[i]->type) { kfree(concat); - printk ("Incompatible device type on \"%s\"\n", subdev[i]->name); + printk("Incompatible device type on \"%s\"\n", + subdev[i]->name); return NULL; } - if(concat->mtd.flags != subdev[i]->flags) - { /* - * Expect all flags except MTD_WRITEABLE to be equal on - * all subdevices. + if (concat->mtd.flags != subdev[i]->flags) { + /* + * Expect all flags except MTD_WRITEABLE to be + * equal on all subdevices. */ - if((concat->mtd.flags ^ subdev[i]->flags) & ~MTD_WRITEABLE) - { + if ((concat->mtd.flags ^ subdev[i]-> + flags) & ~MTD_WRITEABLE) { kfree(concat); - printk ("Incompatible device flags on \"%s\"\n", subdev[i]->name); + printk("Incompatible device flags on \"%s\"\n", + subdev[i]->name); return NULL; - } - else /* if writeable attribute differs, make super device writeable */ - concat->mtd.flags |= subdev[i]->flags & MTD_WRITEABLE; + } else + /* if writeable attribute differs, + make super device writeable */ + concat->mtd.flags |= + subdev[i]->flags & MTD_WRITEABLE; } concat->mtd.size += subdev[i]->size; - if(concat->mtd.oobblock != subdev[i]->oobblock || - concat->mtd.oobsize != subdev[i]->oobsize || - concat->mtd.ecctype != subdev[i]->ecctype || - concat->mtd.eccsize != subdev[i]->eccsize) - { + if (concat->mtd.oobblock != subdev[i]->oobblock || + concat->mtd.oobsize != subdev[i]->oobsize || + concat->mtd.ecctype != subdev[i]->ecctype || + concat->mtd.eccsize != subdev[i]->eccsize || + !concat->mtd.read_ecc != !subdev[i]->read_ecc || + !concat->mtd.write_ecc != !subdev[i]->write_ecc || + !concat->mtd.read_oob != !subdev[i]->read_oob || + !concat->mtd.write_oob != !subdev[i]->write_oob) { kfree(concat); - printk ("Incompatible OOB or ECC data on \"%s\"\n", subdev[i]->name); + printk("Incompatible OOB or ECC data on \"%s\"\n", + subdev[i]->name); return NULL; } concat->subdev[i] = subdev[i]; - + } - concat->num_subdev = num_devs; - concat->mtd.name = name; + concat->num_subdev = num_devs; + concat->mtd.name = name; /* * NOTE: for now, we do not provide any readv()/writev() methods * because they are messy to implement and they are not * used to a great extent anyway. */ - concat->mtd.erase = concat_erase; - concat->mtd.read = concat_read; - concat->mtd.write = concat_write; - concat->mtd.sync = concat_sync; - concat->mtd.lock = concat_lock; - concat->mtd.unlock = concat_unlock; + concat->mtd.erase = concat_erase; + concat->mtd.read = concat_read; + concat->mtd.write = concat_write; + concat->mtd.sync = concat_sync; + concat->mtd.lock = concat_lock; + concat->mtd.unlock = concat_unlock; concat->mtd.suspend = concat_suspend; - concat->mtd.resume = concat_resume; - + concat->mtd.resume = concat_resume; /* * Combine the erase block size info of the subdevices: @@ -544,44 +760,44 @@ */ max_erasesize = curr_erasesize = subdev[0]->erasesize; num_erase_region = 1; - for(i = 0; i < num_devs; i++) - { - if(subdev[i]->numeraseregions == 0) - { /* current subdevice has uniform erase size */ - if(subdev[i]->erasesize != curr_erasesize) - { /* if it differs from the last subdevice's erase size, count it */ + for (i = 0; i < num_devs; i++) { + if (subdev[i]->numeraseregions == 0) { + /* current subdevice has uniform erase size */ + if (subdev[i]->erasesize != curr_erasesize) { + /* if it differs from the last subdevice's erase size, count it */ ++num_erase_region; curr_erasesize = subdev[i]->erasesize; - if(curr_erasesize > max_erasesize) + if (curr_erasesize > max_erasesize) max_erasesize = curr_erasesize; } - } - else - { /* current subdevice has variable erase size */ + } else { + /* current subdevice has variable erase size */ int j; - for(j = 0; j < subdev[i]->numeraseregions; j++) - { /* walk the list of erase regions, count any changes */ - if(subdev[i]->eraseregions[j].erasesize != curr_erasesize) - { + for (j = 0; j < subdev[i]->numeraseregions; j++) { + + /* walk the list of erase regions, count any changes */ + if (subdev[i]->eraseregions[j].erasesize != + curr_erasesize) { ++num_erase_region; - curr_erasesize = subdev[i]->eraseregions[j].erasesize; - if(curr_erasesize > max_erasesize) + curr_erasesize = + subdev[i]->eraseregions[j]. + erasesize; + if (curr_erasesize > max_erasesize) max_erasesize = curr_erasesize; } } } } - if(num_erase_region == 1) - { /* + if (num_erase_region == 1) { + /* * All subdevices have the same uniform erase size. * This is easy: */ concat->mtd.erasesize = curr_erasesize; concat->mtd.numeraseregions = 0; - } - else - { /* + } else { + /* * erase block size varies across the subdevices: allocate * space to store the data describing the variable erase regions */ @@ -590,13 +806,14 @@ concat->mtd.erasesize = max_erasesize; concat->mtd.numeraseregions = num_erase_region; - concat->mtd.eraseregions = erase_region_p = kmalloc ( - num_erase_region * sizeof(struct mtd_erase_region_info), GFP_KERNEL); - if(!erase_region_p) - { + concat->mtd.eraseregions = erase_region_p = + kmalloc(num_erase_region * + sizeof (struct mtd_erase_region_info), GFP_KERNEL); + if (!erase_region_p) { kfree(concat); - printk ("memory allocation error while creating erase region list" - " for device \"%s\"\n", name); + printk + ("memory allocation error while creating erase region list" + " for device \"%s\"\n", name); return NULL; } @@ -606,46 +823,53 @@ */ curr_erasesize = subdev[0]->erasesize; begin = position = 0; - for(i = 0; i < num_devs; i++) - { - if(subdev[i]->numeraseregions == 0) - { /* current subdevice has uniform erase size */ - if(subdev[i]->erasesize != curr_erasesize) - { /* + for (i = 0; i < num_devs; i++) { + if (subdev[i]->numeraseregions == 0) { + /* current subdevice has uniform erase size */ + if (subdev[i]->erasesize != curr_erasesize) { + /* * fill in an mtd_erase_region_info structure for the area * we have walked so far: */ - erase_region_p->offset = begin; - erase_region_p->erasesize = curr_erasesize; - erase_region_p->numblocks = (position - begin) / curr_erasesize; + erase_region_p->offset = begin; + erase_region_p->erasesize = + curr_erasesize; + erase_region_p->numblocks = + (position - begin) / curr_erasesize; begin = position; curr_erasesize = subdev[i]->erasesize; ++erase_region_p; } position += subdev[i]->size; - } - else - { /* current subdevice has variable erase size */ + } else { + /* current subdevice has variable erase size */ int j; - for(j = 0; j < subdev[i]->numeraseregions; j++) - { /* walk the list of erase regions, count any changes */ - if(subdev[i]->eraseregions[j].erasesize != curr_erasesize) - { - erase_region_p->offset = begin; - erase_region_p->erasesize = curr_erasesize; - erase_region_p->numblocks = (position - begin) / curr_erasesize; + for (j = 0; j < subdev[i]->numeraseregions; j++) { + /* walk the list of erase regions, count any changes */ + if (subdev[i]->eraseregions[j]. + erasesize != curr_erasesize) { + erase_region_p->offset = begin; + erase_region_p->erasesize = + curr_erasesize; + erase_region_p->numblocks = + (position - + begin) / curr_erasesize; begin = position; - curr_erasesize = subdev[i]->eraseregions[j].erasesize; + curr_erasesize = + subdev[i]->eraseregions[j]. + erasesize; ++erase_region_p; } - position += subdev[i]->eraseregions[j].numblocks * curr_erasesize; + position += + subdev[i]->eraseregions[j]. + numblocks * curr_erasesize; } } } /* Now write the final entry */ - erase_region_p->offset = begin; + erase_region_p->offset = begin; erase_region_p->erasesize = curr_erasesize; erase_region_p->numblocks = (position - begin) / curr_erasesize; } @@ -660,16 +884,14 @@ void mtd_concat_destroy(struct mtd_info *mtd) { struct mtd_concat *concat = CONCAT(mtd); - if(concat->mtd.numeraseregions) + if (concat->mtd.numeraseregions) kfree(concat->mtd.eraseregions); kfree(concat); } - EXPORT_SYMBOL(mtd_concat_create); EXPORT_SYMBOL(mtd_concat_destroy); - MODULE_LICENSE("GPL"); MODULE_AUTHOR("Robert Kaiser "); MODULE_DESCRIPTION("Generic support for concatenating of MTD devices"); Index: drivers/mtd/mtdcore.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/mtdcore.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/mtdcore.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/mtdcore.c 3 Nov 2004 00:04:42 -0000 1.3 @@ -1,5 +1,5 @@ /* - * $Id: mtdcore.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: mtdcore.c,v 1.3 2004/11/03 00:04:42 joff Exp $ * * Core registration and callback routines for MTD * drivers and users. @@ -17,6 +17,7 @@ #include #include #include +#include #include #ifdef CONFIG_PROC_FS #include @@ -24,9 +25,15 @@ #include -static DECLARE_MUTEX(mtd_table_mutex); -static struct mtd_info *mtd_table[MAX_MTD_DEVICES]; -static struct mtd_notifier *mtd_notifiers = NULL; +/* These are exported solely for the purpose of mtd_blkdevs.c. You + should not use them for _anything_ else */ +DECLARE_MUTEX(mtd_table_mutex); +struct mtd_info *mtd_table[MAX_MTD_DEVICES]; + +EXPORT_SYMBOL_GPL(mtd_table_mutex); +EXPORT_SYMBOL_GPL(mtd_table); + +static LIST_HEAD(mtd_notifiers); /** * add_mtd_device - register an MTD device @@ -44,21 +51,28 @@ down(&mtd_table_mutex); - for (i=0; i< MAX_MTD_DEVICES; i++) - if (!mtd_table[i]) - { - struct mtd_notifier *not=mtd_notifiers; + for (i=0; i < MAX_MTD_DEVICES; i++) + if (!mtd_table[i]) { + struct list_head *this; mtd_table[i] = mtd; mtd->index = i; + mtd->usecount = 0; + DEBUG(0, "mtd: Giving out device %d to %s\n",i, mtd->name); - while (not) - { - (*(not->add))(mtd); - not = not->next; + /* No need to get a refcount on the module containing + the notifier, since we hold the mtd_table_mutex */ + list_for_each(this, &mtd_notifiers) { + struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list); + not->add(mtd); } + up(&mtd_table_mutex); - MOD_INC_USE_COUNT; + /* We _know_ we aren't being removed, because + our caller is still holding us here. So none + of this try_ nonsense, and no bitching about it + either. :) */ + __module_get(THIS_MODULE); return 0; } @@ -78,29 +92,34 @@ int del_mtd_device (struct mtd_info *mtd) { - struct mtd_notifier *not=mtd_notifiers; - int i; + int ret; down(&mtd_table_mutex); - for (i=0; i < MAX_MTD_DEVICES; i++) - { - if (mtd_table[i] == mtd) - { - while (not) - { - (*(not->remove))(mtd); - not = not->next; - } - mtd_table[i] = NULL; - up (&mtd_table_mutex); - MOD_DEC_USE_COUNT; - return 0; + if (mtd_table[mtd->index] != mtd) { + ret = -ENODEV; + } else if (mtd->usecount) { + printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n", + mtd->index, mtd->name, mtd->usecount); + ret = -EBUSY; + } else { + struct list_head *this; + + /* No need to get a refcount on the module containing + the notifier, since we hold the mtd_table_mutex */ + list_for_each(this, &mtd_notifiers) { + struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list); + not->remove(mtd); } + + mtd_table[mtd->index] = NULL; + + module_put(THIS_MODULE); + ret = 0; } up(&mtd_table_mutex); - return 1; + return ret; } /** @@ -118,10 +137,9 @@ down(&mtd_table_mutex); - new->next = mtd_notifiers; - mtd_notifiers = new; + list_add(&new->list, &mtd_notifiers); - MOD_INC_USE_COUNT; + __module_get(THIS_MODULE); for (i=0; i< MAX_MTD_DEVICES; i++) if (mtd_table[i]) @@ -142,34 +160,24 @@ int unregister_mtd_user (struct mtd_notifier *old) { - struct mtd_notifier **prev = &mtd_notifiers; - struct mtd_notifier *cur; int i; down(&mtd_table_mutex); - while ((cur = *prev)) { - if (cur == old) { - *prev = cur->next; - - MOD_DEC_USE_COUNT; - - for (i=0; i< MAX_MTD_DEVICES; i++) - if (mtd_table[i]) - old->remove(mtd_table[i]); + module_put(THIS_MODULE); + + for (i=0; i< MAX_MTD_DEVICES; i++) + if (mtd_table[i]) + old->remove(mtd_table[i]); - up(&mtd_table_mutex); - return 0; - } - prev = &cur->next; - } + list_del(&old->list); up(&mtd_table_mutex); - return 1; + return 0; } /** - * __get_mtd_device - obtain a validated handle for an MTD device + * get_mtd_device - obtain a validated handle for an MTD device * @mtd: last known address of the required MTD device * @num: internal device number of the required MTD device * @@ -177,11 +185,10 @@ * table, if any. Given an address and num == -1, search the device table * for a device with that address and return if it's still present. Given * both, return the num'th driver only if its address matches. Return NULL - * if not. get_mtd_device() increases the use count, but - * __get_mtd_device() doesn't - you should generally use get_mtd_device(). + * if not. */ -struct mtd_info *__get_mtd_device(struct mtd_info *mtd, int num) +struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) { struct mtd_info *ret = NULL; int i; @@ -197,17 +204,34 @@ if (mtd && mtd != ret) ret = NULL; } - + + if (ret && !try_module_get(ret->owner)) + ret = NULL; + + if (ret) + ret->usecount++; + up(&mtd_table_mutex); return ret; } +void put_mtd_device(struct mtd_info *mtd) +{ + int c; + + down(&mtd_table_mutex); + c = --mtd->usecount; + up(&mtd_table_mutex); + BUG_ON(c < 0); + + module_put(mtd->owner); +} /* default_mtd_writev - default mtd writev method for MTD devices that * dont implement their own */ -int default_mtd_writev(struct mtd_info *mtd, const struct iovec *vecs, +int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen) { unsigned long i; @@ -237,7 +261,7 @@ * implement their own */ -int default_mtd_readv(struct mtd_info *mtd, struct iovec *vecs, +int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen) { unsigned long i; @@ -265,7 +289,8 @@ EXPORT_SYMBOL(add_mtd_device); EXPORT_SYMBOL(del_mtd_device); -EXPORT_SYMBOL(__get_mtd_device); +EXPORT_SYMBOL(get_mtd_device); +EXPORT_SYMBOL(put_mtd_device); EXPORT_SYMBOL(register_mtd_user); EXPORT_SYMBOL(unregister_mtd_user); EXPORT_SYMBOL(default_mtd_writev); @@ -308,10 +333,7 @@ /* Support for /proc/mtd */ #ifdef CONFIG_PROC_FS - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) static struct proc_dir_entry *proc_mtd; -#endif static inline int mtd_proc_info (char *buf, int i) { @@ -324,13 +346,8 @@ this->erasesize, this->name); } -static int mtd_read_proc ( char *page, char **start, off_t off,int count -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) - ,int *eof, void *data_unused -#else - ,int unused -#endif - ) +static int mtd_read_proc (char *page, char **start, off_t off, int count, + int *eof, void *data_unused) { int len, l, i; off_t begin = 0; @@ -350,9 +367,7 @@ } } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) *eof = 1; -#endif done: up(&mtd_table_mutex); @@ -362,18 +377,6 @@ return ((count < begin+len-off) ? count : begin+len-off); } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0) -struct proc_dir_entry mtd_proc_entry = { - 0, /* low_ino: the inode -- dynamic */ - 3, "mtd", /* len of name and name */ - S_IFREG | S_IRUGO, /* mode */ - 1, 0, 0, /* nlinks, owner, group */ - 0, NULL, /* size - unused; operations -- use default */ - &mtd_read_proc, /* function used to read data */ - /* nothing more */ - }; -#endif - #endif /* CONFIG_PROC_FS */ /*====================================================================*/ @@ -382,16 +385,8 @@ int __init init_mtd(void) { #ifdef CONFIG_PROC_FS -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) - if ((proc_mtd = create_proc_entry( "mtd", 0, 0 ))) - proc_mtd->read_proc = mtd_read_proc; -#else - proc_register_dynamic(&proc_root,&mtd_proc_entry); -#endif -#endif - -#if LINUX_VERSION_CODE < 0x20212 - init_mtd_devices(); + if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) + proc_mtd->read_proc = mtd_read_proc; #endif #ifdef CONFIG_PM @@ -410,12 +405,8 @@ #endif #ifdef CONFIG_PROC_FS -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) if (proc_mtd) - remove_proc_entry( "mtd", 0); -#else - proc_unregister(&proc_root,mtd_proc_entry.low_ino); -#endif + remove_proc_entry( "mtd", NULL); #endif } Index: drivers/mtd/mtdpart.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/mtdpart.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/mtdpart.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/mtdpart.c 3 Nov 2004 00:04:42 -0000 1.3 @@ -5,7 +5,7 @@ * * This code is GPL * - * $Id: mtdpart.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: mtdpart.c,v 1.3 2004/11/03 00:04:42 joff Exp $ * * 02-21-2002 Thomas Gleixner * added support for read_oob, write_oob @@ -16,10 +16,11 @@ #include #include #include - +#include +#include #include #include - +#include /* Our partition linked list */ static LIST_HEAD(mtd_partitions); @@ -54,8 +55,12 @@ len = 0; else if (from + len > mtd->size) len = mtd->size - from; - return part->master->read (part->master, from + part->offset, + if (part->master->read_ecc == NULL) + return part->master->read (part->master, from + part->offset, len, retlen, buf); + else + return part->master->read_ecc (part->master, from + part->offset, + len, retlen, buf, NULL, &mtd->oobinfo); } static int part_point (struct mtd_info *mtd, loff_t from, size_t len, @@ -78,9 +83,11 @@ static int part_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel) + size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel) { struct mtd_part *part = PART(mtd); + if (oobsel == NULL) + oobsel = &mtd->oobinfo; if (from >= mtd->size) len = 0; else if (from + len > mtd->size) @@ -113,7 +120,7 @@ size_t *retlen, u_char *buf) { struct mtd_part *part = PART(mtd); - return part->master->read_user_prot_reg (part->master, from, + return part->master->read_fact_prot_reg (part->master, from, len, retlen, buf); } @@ -127,17 +134,24 @@ len = 0; else if (to + len > mtd->size) len = mtd->size - to; - return part->master->write (part->master, to + part->offset, + if (part->master->write_ecc == NULL) + return part->master->write (part->master, to + part->offset, len, retlen, buf); + else + return part->master->write_ecc (part->master, to + part->offset, + len, retlen, buf, NULL, &mtd->oobinfo); + } static int part_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, - u_char *eccbuf, int oobsel) + u_char *eccbuf, struct nand_oobinfo *oobsel) { struct mtd_part *part = PART(mtd); if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; + if (oobsel == NULL) + oobsel = &mtd->oobinfo; if (to >= mtd->size) len = 0; else if (to + len > mtd->size) @@ -168,41 +182,55 @@ len, retlen, buf); } -static int part_writev (struct mtd_info *mtd, const struct iovec *vecs, +static int part_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen) { struct mtd_part *part = PART(mtd); if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; - return part->master->writev (part->master, vecs, count, + if (part->master->writev_ecc == NULL) + return part->master->writev (part->master, vecs, count, to + part->offset, retlen); + else + return part->master->writev_ecc (part->master, vecs, count, + to + part->offset, retlen, + NULL, &mtd->oobinfo); } -static int part_readv (struct mtd_info *mtd, struct iovec *vecs, +static int part_readv (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen) { struct mtd_part *part = PART(mtd); - return part->master->readv (part->master, vecs, count, + if (part->master->readv_ecc == NULL) + return part->master->readv (part->master, vecs, count, from + part->offset, retlen); + else + return part->master->readv_ecc (part->master, vecs, count, + from + part->offset, retlen, + NULL, &mtd->oobinfo); } -static int part_writev_ecc (struct mtd_info *mtd, const struct iovec *vecs, +static int part_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen, - u_char *eccbuf, int oobsel) + u_char *eccbuf, struct nand_oobinfo *oobsel) { struct mtd_part *part = PART(mtd); if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; + if (oobsel == NULL) + oobsel = &mtd->oobinfo; return part->master->writev_ecc (part->master, vecs, count, to + part->offset, retlen, eccbuf, oobsel); } -static int part_readv_ecc (struct mtd_info *mtd, struct iovec *vecs, +static int part_readv_ecc (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen, - u_char *eccbuf, int oobsel) + u_char *eccbuf, struct nand_oobinfo *oobsel) { struct mtd_part *part = PART(mtd); + if (oobsel == NULL) + oobsel = &mtd->oobinfo; return part->master->readv_ecc (part->master, vecs, count, from + part->offset, retlen, eccbuf, oobsel); @@ -211,13 +239,29 @@ static int part_erase (struct mtd_info *mtd, struct erase_info *instr) { struct mtd_part *part = PART(mtd); + int ret; if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; if (instr->addr >= mtd->size) return -EINVAL; instr->addr += part->offset; - return part->master->erase(part->master, instr); + ret = part->master->erase(part->master, instr); + return ret; +} + +void mtd_erase_callback(struct erase_info *instr) +{ + if (instr->mtd->erase == part_erase) { + struct mtd_part *part = PART(instr->mtd); + + if (instr->fail_addr != 0xffffffff) + instr->fail_addr -= part->offset; + instr->addr -= part->offset; + } + if (instr->callback) + instr->callback(instr); } +EXPORT_SYMBOL_GPL(mtd_erase_callback); static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len) { @@ -253,6 +297,27 @@ part->master->resume(part->master); } +static int part_block_isbad (struct mtd_info *mtd, loff_t ofs) +{ + struct mtd_part *part = PART(mtd); + if (ofs >= mtd->size) { + return -EINVAL; + } + ofs += part->offset; + return part->master->block_isbad(part->master, ofs); +} + +static int part_block_markbad (struct mtd_info *mtd, loff_t ofs) +{ + struct mtd_part *part = PART(mtd); + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + if (ofs >= mtd->size) + return -EINVAL; + ofs += part->offset; + return part->master->block_markbad(part->master, ofs); +} + /* * This function unregisters and destroy all slave MTD objects which are * attached to the given master MTD object. @@ -288,7 +353,7 @@ */ int add_mtd_partitions(struct mtd_info *master, - struct mtd_partition *parts, + const struct mtd_partition *parts, int nbparts) { struct mtd_part *slave; @@ -321,7 +386,7 @@ slave->mtd.name = parts[i].name; slave->mtd.bank_size = master->bank_size; - slave->mtd.module = master->module; + slave->mtd.owner = master->owner; slave->mtd.read = part_read; slave->mtd.write = part_write; @@ -363,6 +428,10 @@ slave->mtd.lock = part_lock; if (master->unlock) slave->mtd.unlock = part_unlock; + if (master->block_isbad) + slave->mtd.block_isbad = part_block_isbad; + if (master->block_markbad) + slave->mtd.block_markbad = part_block_markbad; slave->mtd.erase = part_erase; slave->master = master; slave->offset = parts[i].offset; @@ -433,6 +502,9 @@ parts[i].name); } + /* copy oobinfo from master */ + memcpy(&slave->mtd.oobinfo, &master->oobinfo, sizeof(slave->mtd.oobinfo)); + if(parts[i].mtdp) { /* store the object pointer (caller may or may not register it */ *parts[i].mtdp = &slave->mtd; @@ -452,6 +524,75 @@ EXPORT_SYMBOL(add_mtd_partitions); EXPORT_SYMBOL(del_mtd_partitions); +static spinlock_t part_parser_lock = SPIN_LOCK_UNLOCKED; +static LIST_HEAD(part_parsers); + +struct mtd_part_parser *get_partition_parser(const char *name) +{ + struct list_head *this; + void *ret = NULL; + spin_lock(&part_parser_lock); + + list_for_each(this, &part_parsers) { + struct mtd_part_parser *p = list_entry(this, struct mtd_part_parser, list); + + if (!strcmp(p->name, name) && try_module_get(p->owner)) { + ret = p; + break; + } + } + spin_unlock(&part_parser_lock); + + return ret; +} + +int register_mtd_parser(struct mtd_part_parser *p) +{ + spin_lock(&part_parser_lock); + list_add(&p->list, &part_parsers); + spin_unlock(&part_parser_lock); + + return 0; +} + +int deregister_mtd_parser(struct mtd_part_parser *p) +{ + spin_lock(&part_parser_lock); + list_del(&p->list); + spin_unlock(&part_parser_lock); + return 0; +} + +int parse_mtd_partitions(struct mtd_info *master, const char **types, + struct mtd_partition **pparts, unsigned long origin) +{ + struct mtd_part_parser *parser; + int ret = 0; + + for ( ; ret <= 0 && *types; types++) { + parser = get_partition_parser(*types); +#ifdef CONFIG_KMOD + if (!parser && !request_module("%s", *types)) + parser = get_partition_parser(*types); +#endif + if (!parser) { + printk(KERN_NOTICE "%s partition parsing not available\n", + *types); + continue; + } + ret = (*parser->parse_fn)(master, pparts, origin); + if (ret > 0) { + printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n", + ret, parser->name, master->name); + } + put_partition_parser(parser); + } + return ret; +} + +EXPORT_SYMBOL_GPL(parse_mtd_partitions); +EXPORT_SYMBOL_GPL(register_mtd_parser); +EXPORT_SYMBOL_GPL(deregister_mtd_parser); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Nicolas Pitre "); Index: drivers/mtd/nftlcore.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/nftlcore.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/nftlcore.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/nftlcore.c 3 Nov 2004 00:04:42 -0000 1.3 @@ -1,7 +1,7 @@ /* Linux driver for NAND Flash Translation Layer */ /* (c) 1999 Machine Vision Holdings, Inc. */ /* Author: David Woodhouse */ -/* $Id: nftlcore.c,v 1.1 2004/07/22 19:49:45 joff Exp $ */ +/* $Id: nftlcore.c,v 1.3 2004/11/03 00:04:42 joff Exp $ */ /* The contents of this file are distributed under the GNU General @@ -23,15 +23,13 @@ #include #include #include -#include +#include -#ifdef CONFIG_KMOD #include -#endif #include #include #include -#include +#include /* maximum number of loops while examining next block, to have a chance to detect consistency problems (they should never happen @@ -39,189 +37,109 @@ #define MAX_LOOPS 10000 -/* NFTL block device stuff */ -#define MAJOR_NR NFTL_MAJOR -#define DEVICE_REQUEST nftl_request -#define DEVICE_OFF(device) - - -#include -#include - -/* Linux-specific block device functions */ - -/* I _HATE_ the Linux block device setup more than anything else I've ever - * encountered, except ... - */ - -static int nftl_sizes[256]; -static int nftl_blocksizes[256]; - -/* .. for the Linux partition table handling. */ -struct hd_struct part_table[256]; - -#if LINUX_VERSION_CODE < 0x20328 -static void dummy_init (struct gendisk *crap) -{} -#endif - -static struct gendisk nftl_gendisk = { - major: MAJOR_NR, - major_name: "nftl", - minor_shift: NFTL_PARTN_BITS, /* Bits to shift to get real from partition */ - max_p: (1<type != MTD_NANDFLASH) + return; + /* OK, this is moderately ugly. But probably safe. Alternatives? */ + if (memcmp(mtd->name, "DiskOnChip", 10)) + return; - for (i = 0; i < MAX_NFTLS; i++) { - if (!NFTLs[i] && firstfree == -1) - firstfree = i; - else if (NFTLs[i] && NFTLs[i]->mtd == mtd) { - /* This is a Spare Media Header for an NFTL we've already found */ - DEBUG(MTD_DEBUG_LEVEL1, "MTD already mounted as NFTL\n"); - return; - } - } - if (firstfree == -1) { - printk(KERN_WARNING "No more NFTL slot available\n"); + if (!mtd->block_isbad) { + printk(KERN_ERR +"NFTL no longer supports the old DiskOnChip drivers loaded via docprobe.\n" +"Please use the new diskonchip driver under the NAND subsystem.\n"); return; - } + } + + DEBUG(MTD_DEBUG_LEVEL1, "NFTL: add_mtd for %s\n", mtd->name); nftl = kmalloc(sizeof(struct NFTLrecord), GFP_KERNEL); + if (!nftl) { - printk(KERN_WARNING "Out of memory for NFTL data structures\n"); + printk(KERN_WARNING "NFTL: out of memory for data structures\n"); return; } + memset(nftl, 0, sizeof(*nftl)); - init_MUTEX(&nftl->mutex); - - nftl->mtd = mtd; + nftl->mbd.mtd = mtd; + nftl->mbd.devnum = -1; + nftl->mbd.blksize = 512; + nftl->mbd.tr = tr; + memcpy(&nftl->oobinfo, &mtd->oobinfo, sizeof(struct nand_oobinfo)); + nftl->oobinfo.useecc = MTD_NANDECC_PLACEONLY; if (NFTL_mount(nftl) < 0) { - printk(KERN_WARNING "Could not mount NFTL device\n"); + printk(KERN_WARNING "NFTL: could not mount device\n"); kfree(nftl); return; } /* OK, it's a new one. Set up all the data structures. */ -#ifdef PSYCHO_DEBUG - printk("Found new NFTL nftl%c\n", firstfree + 'a'); -#endif - /* linux stuff */ - nftl->usecount = 0; + /* Calculate geometry */ nftl->cylinders = 1024; nftl->heads = 16; temp = nftl->cylinders * nftl->heads; - nftl->sectors = nftl->nr_sects / temp; - if (nftl->nr_sects % temp) { + nftl->sectors = nftl->mbd.size / temp; + if (nftl->mbd.size % temp) { nftl->sectors++; temp = nftl->cylinders * nftl->sectors; - nftl->heads = nftl->nr_sects / temp; + nftl->heads = nftl->mbd.size / temp; - if (nftl->nr_sects % temp) { + if (nftl->mbd.size % temp) { nftl->heads++; temp = nftl->heads * nftl->sectors; - nftl->cylinders = nftl->nr_sects / temp; + nftl->cylinders = nftl->mbd.size / temp; } } - if (nftl->nr_sects != nftl->heads * nftl->cylinders * nftl->sectors) { - printk(KERN_WARNING "Cannot calculate an NFTL geometry to " - "match size of 0x%x.\n", nftl->nr_sects); - printk(KERN_WARNING "Using C:%d H:%d S:%d (== 0x%lx sects)\n", - nftl->cylinders, nftl->heads , nftl->sectors, - (long)nftl->cylinders * (long)nftl->heads * (long)nftl->sectors ); + if (nftl->mbd.size != nftl->heads * nftl->cylinders * nftl->sectors) { + /* + Oh no we don't have + mbd.size == heads * cylinders * sectors + */ + printk(KERN_WARNING "NFTL: cannot calculate a geometry to " + "match size of 0x%lx.\n", nftl->mbd.size); + printk(KERN_WARNING "NFTL: using C:%d H:%d S:%d " + "(== 0x%lx sects)\n", + nftl->cylinders, nftl->heads , nftl->sectors, + (long)nftl->cylinders * (long)nftl->heads * + (long)nftl->sectors ); + } - /* Oh no we don't have nftl->nr_sects = nftl->heads * nftl->cylinders * nftl->sectors; */ + if (add_mtd_blktrans_dev(&nftl->mbd)) { + if (nftl->ReplUnitTable) + kfree(nftl->ReplUnitTable); + if (nftl->EUNtable) + kfree(nftl->EUNtable); + kfree(nftl); + return; } - NFTLs[firstfree] = nftl; - /* Finally, set up the block device sizes */ - nftl_sizes[firstfree * 16] = nftl->nr_sects; - //nftl_blocksizes[firstfree*16] = 512; - part_table[firstfree * 16].nr_sects = nftl->nr_sects; - - nftl_gendisk.nr_real++; - - /* partition check ... */ -#if LINUX_VERSION_CODE < 0x20328 - resetup_one_dev(&nftl_gendisk, firstfree); -#else - grok_partitions(&nftl_gendisk, firstfree, 1<nr_sects); +#ifdef PSYCHO_DEBUG + printk(KERN_INFO "NFTL: Found new nftl%c\n", nftl->mbd.devnum + 'a'); #endif } -static void NFTL_unsetup(int i) +static void nftl_remove_dev(struct mtd_blktrans_dev *dev) { - struct NFTLrecord *nftl = NFTLs[i]; + struct NFTLrecord *nftl = (void *)dev; - DEBUG(MTD_DEBUG_LEVEL1, "NFTL_unsetup %d\n", i); - - NFTLs[i] = NULL; - + DEBUG(MTD_DEBUG_LEVEL1, "NFTL: remove_dev (i=%d)\n", dev->devnum); + + del_mtd_blktrans_dev(dev); if (nftl->ReplUnitTable) kfree(nftl->ReplUnitTable); if (nftl->EUNtable) kfree(nftl->EUNtable); - - nftl_gendisk.nr_real--; kfree(nftl); } -/* Search the MTD device for NFTL partitions */ -static void NFTL_notify_add(struct mtd_info *mtd) -{ - DEBUG(MTD_DEBUG_LEVEL1, "NFTL_notify_add for %s\n", mtd->name); - - if (mtd) { - if (!mtd->read_oob) { - /* If this MTD doesn't have out-of-band data, - then there's no point continuing */ - DEBUG(MTD_DEBUG_LEVEL1, "No OOB data, quitting\n"); - return; - } - DEBUG(MTD_DEBUG_LEVEL3, "mtd->read = %p, size = %d, erasesize = %d\n", - mtd->read, mtd->size, mtd->erasesize); - - NFTL_setup(mtd); - } -} - -static void NFTL_notify_remove(struct mtd_info *mtd) -{ - int i; - - for (i = 0; i < MAX_NFTLS; i++) { - if (NFTLs[i] && NFTLs[i]->mtd == mtd) - NFTL_unsetup(i); - } -} - #ifdef CONFIG_NFTL_RW /* Actual NFTL access routines */ @@ -303,7 +221,7 @@ targetEUN = thisEUN; for (block = 0; block < nftl->EraseSize / 512; block ++) { - MTD_READOOB(nftl->mtd, + MTD_READOOB(nftl->mbd.mtd, (thisEUN * nftl->EraseSize) + (block * 512), 16 , &retlen, (char *)&oob); if (block == 2) { @@ -420,7 +338,7 @@ chain by selecting the longer one */ oob.u.c.FoldMark = oob.u.c.FoldMark1 = cpu_to_le16(FOLD_MARK_IN_PROGRESS); oob.u.c.unused = 0xffffffff; - MTD_WRITEOOB(nftl->mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8, + MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8, 8, &retlen, (char *)&oob.u); } @@ -444,17 +362,19 @@ if (BlockMap[block] == BLOCK_NIL) continue; - ret = MTD_READECC(nftl->mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512), - 512, &retlen, movebuf, (char *)&oob, NAND_ECC_DISKONCHIP); + ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512), + 512, &retlen, movebuf); if (ret < 0) { - ret = MTD_READECC(nftl->mtd, (nftl->EraseSize * BlockMap[block]) + ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512), 512, &retlen, - movebuf, (char *)&oob, NAND_ECC_DISKONCHIP); + movebuf); if (ret != -EIO) printk("Error went away on retry.\n"); } - MTD_WRITEECC(nftl->mtd, (nftl->EraseSize * targetEUN) + (block * 512), - 512, &retlen, movebuf, (char *)&oob, NAND_ECC_DISKONCHIP); + memset(&oob, 0xff, sizeof(struct nftl_oob)); + oob.b.Status = oob.b.Status1 = SECTOR_USED; + MTD_WRITEECC(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + (block * 512), + 512, &retlen, movebuf, (char *)&oob, &nftl->oobinfo); } /* add the header so that it is now a valid chain */ @@ -462,7 +382,7 @@ = cpu_to_le16(thisVUC); oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff; - MTD_WRITEOOB(nftl->mtd, (nftl->EraseSize * targetEUN) + 8, + MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 8, 8, &retlen, (char *)&oob.u); /* OK. We've moved the whole lot into the new block. Now we have to free the original blocks. */ @@ -484,7 +404,6 @@ if (NFTL_formatblock(nftl, thisEUN) < 0) { /* could not erase : mark block as reserved - * FixMe: Update Bad Unit Table on disk */ nftl->ReplUnitTable[thisEUN] = BLOCK_RESERVED; } else { @@ -582,7 +501,7 @@ lastEUN = writeEUN; - MTD_READOOB(nftl->mtd, (writeEUN * nftl->EraseSize) + blockofs, + MTD_READOOB(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs, 8, &retlen, (char *)&bci); DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n", @@ -670,12 +589,12 @@ nftl->ReplUnitTable[writeEUN] = BLOCK_NIL; /* ... and on the flash itself */ - MTD_READOOB(nftl->mtd, writeEUN * nftl->EraseSize + 8, 8, + MTD_READOOB(nftl->mbd.mtd, writeEUN * nftl->EraseSize + 8, 8, &retlen, (char *)&oob.u); oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum = cpu_to_le16(thisVUC); - MTD_WRITEOOB(nftl->mtd, writeEUN * nftl->EraseSize + 8, 8, + MTD_WRITEOOB(nftl->mbd.mtd, writeEUN * nftl->EraseSize + 8, 8, &retlen, (char *)&oob.u); /* we link the new block to the chain only after the @@ -685,13 +604,13 @@ /* Both in our cache... */ nftl->ReplUnitTable[lastEUN] = writeEUN; /* ... and on the flash itself */ - MTD_READOOB(nftl->mtd, (lastEUN * nftl->EraseSize) + 8, + MTD_READOOB(nftl->mbd.mtd, (lastEUN * nftl->EraseSize) + 8, 8, &retlen, (char *)&oob.u); oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = cpu_to_le16(writeEUN); - MTD_WRITEOOB(nftl->mtd, (lastEUN * nftl->EraseSize) + 8, + MTD_WRITEOOB(nftl->mbd.mtd, (lastEUN * nftl->EraseSize) + 8, 8, &retlen, (char *)&oob.u); } @@ -704,12 +623,14 @@ return 0xffff; } -static int NFTL_writeblock(struct NFTLrecord *nftl, unsigned block, char *buffer) +static int nftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block, + char *buffer) { + struct NFTLrecord *nftl = (void *)mbd; u16 writeEUN; unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1); size_t retlen; - u8 eccbuf[6]; + struct nftl_oob oob; writeEUN = NFTL_findwriteunit(nftl, block); @@ -720,16 +641,20 @@ return 1; } - MTD_WRITEECC(nftl->mtd, (writeEUN * nftl->EraseSize) + blockofs, - 512, &retlen, (char *)buffer, (char *)eccbuf, NAND_ECC_DISKONCHIP); - /* no need to write SECTOR_USED flags since they are written in mtd_writeecc */ + memset(&oob, 0xff, sizeof(struct nftl_oob)); + oob.b.Status = oob.b.Status1 = SECTOR_USED; + MTD_WRITEECC(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs, + 512, &retlen, (char *)buffer, (char *)&oob, &nftl->oobinfo); + /* need to write SECTOR_USED flags since they are not written in mtd_writeecc */ return 0; } #endif /* CONFIG_NFTL_RW */ -static int NFTL_readblock(struct NFTLrecord *nftl, unsigned block, char *buffer) +static int nftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block, + char *buffer) { + struct NFTLrecord *nftl = (void *)mbd; u16 lastgoodEUN; u16 thisEUN = nftl->EUNtable[block / (nftl->EraseSize / 512)]; unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1); @@ -742,7 +667,7 @@ if (thisEUN != BLOCK_NIL) { while (thisEUN < nftl->nb_blocks) { - if (MTD_READOOB(nftl->mtd, (thisEUN * nftl->EraseSize) + blockofs, + if (MTD_READOOB(nftl->mbd.mtd, (thisEUN * nftl->EraseSize) + blockofs, 8, &retlen, (char *)&bci) < 0) status = SECTOR_IGNORE; else @@ -761,13 +686,13 @@ case SECTOR_IGNORE: break; default: - printk("Unknown status for block %d in EUN %d: %x\n", + printk("Unknown status for block %ld in EUN %d: %x\n", block, thisEUN, status); break; } if (!silly--) { - printk(KERN_WARNING "Infinite loop in Virtual Unit Chain 0x%x\n", + printk(KERN_WARNING "Infinite loop in Virtual Unit Chain 0x%lx\n", block / (nftl->EraseSize / 512)); return 1; } @@ -782,265 +707,22 @@ } else { loff_t ptr = (lastgoodEUN * nftl->EraseSize) + blockofs; size_t retlen; - u_char eccbuf[6]; - if (MTD_READECC(nftl->mtd, ptr, 512, &retlen, buffer, eccbuf, NAND_ECC_DISKONCHIP)) + if (MTD_READ(nftl->mbd.mtd, ptr, 512, &retlen, buffer)) return -EIO; } return 0; } -static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) +static int nftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo) { - struct NFTLrecord *nftl; - int p; + struct NFTLrecord *nftl = (void *)dev; - nftl = NFTLs[MINOR(inode->i_rdev) >> NFTL_PARTN_BITS]; - - if (!nftl) return -EINVAL; - - switch (cmd) { - case HDIO_GETGEO: { - struct hd_geometry g; - - g.heads = nftl->heads; - g.sectors = nftl->sectors; - g.cylinders = nftl->cylinders; - g.start = part_table[MINOR(inode->i_rdev)].start_sect; - return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0; - } - case BLKGETSIZE: /* Return device size */ - return put_user(part_table[MINOR(inode->i_rdev)].nr_sects, - (unsigned long *) arg); - -#ifdef BLKGETSIZE64 - case BLKGETSIZE64: - return put_user((u64)part_table[MINOR(inode->i_rdev)].nr_sects << 9, - (u64 *)arg); -#endif - - case BLKFLSBUF: - if (!capable(CAP_SYS_ADMIN)) return -EACCES; - fsync_dev(inode->i_rdev); - invalidate_buffers(inode->i_rdev); - if (nftl->mtd->sync) - nftl->mtd->sync(nftl->mtd); - return 0; - - case BLKRRPART: - if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if (nftl->usecount > 1) return -EBUSY; - /* - * We have to flush all buffers and invalidate caches, - * or we won't be able to re-use the partitions, - * if there was a change and we don't want to reboot - */ - p = (1< 0) { - kdev_t devp = MKDEV(MAJOR(inode->i_dev), MINOR(inode->i_dev)+p); - if (part_table[p].nr_sects > 0) - invalidate_device (devp, 1); - - part_table[MINOR(inode->i_dev)+p].start_sect = 0; - part_table[MINOR(inode->i_dev)+p].nr_sects = 0; - } - -#if LINUX_VERSION_CODE < 0x20328 - resetup_one_dev(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS); -#else - grok_partitions(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS, - 1<nr_sects); -#endif - return 0; - -#if (LINUX_VERSION_CODE < 0x20303) - RO_IOCTLS(inode->i_rdev, arg); /* ref. linux/blk.h */ -#else - case BLKROSET: - case BLKROGET: - case BLKSSZGET: - return blk_ioctl(inode->i_rdev, cmd, arg); -#endif - - default: - return -EINVAL; - } -} - -void nftl_request(RQFUNC_ARG) -{ - unsigned int dev, block, nsect; - struct NFTLrecord *nftl; - char *buffer; - struct request *req; - int res; - - while (1) { - INIT_REQUEST; /* blk.h */ - req = CURRENT; - - /* We can do this because the generic code knows not to - touch the request at the head of the queue */ - spin_unlock_irq(&io_request_lock); - - DEBUG(MTD_DEBUG_LEVEL2, "NFTL_request\n"); - DEBUG(MTD_DEBUG_LEVEL3, "NFTL %s request, from sector 0x%04lx for 0x%04lx sectors\n", - (req->cmd == READ) ? "Read " : "Write", - req->sector, req->current_nr_sectors); - - dev = MINOR(req->rq_dev); - block = req->sector; - nsect = req->current_nr_sectors; - buffer = req->buffer; - res = 1; /* succeed */ - - if (dev >= MAX_NFTLS * (1<rq_dev)); - res = 0; /* fail */ - goto repeat; - } - - nftl = NFTLs[dev / (1<mutex); - DEBUG(MTD_DEBUG_LEVEL3, "Got mutex\n"); - - if (block + nsect > part_table[dev].nr_sects) { - /* access past the end of device */ - printk("nftl%c%d: bad access: block = %d, count = %d\n", - (MINOR(req->rq_dev)>>6)+'a', dev & 0xf, block, nsect); - up(&nftl->mutex); - res = 0; /* fail */ - goto repeat; - } - - block += part_table[dev].start_sect; - - if (req->cmd == READ) { - DEBUG(MTD_DEBUG_LEVEL2, "NFTL read request of 0x%x sectors @ %x " - "(req->nr_sectors == %lx)\n", nsect, block, req->nr_sectors); - - for ( ; nsect > 0; nsect-- , block++, buffer += 512) { - /* Read a single sector to req->buffer + (512 * i) */ - if (NFTL_readblock(nftl, block, buffer)) { - DEBUG(MTD_DEBUG_LEVEL2, "NFTL read request failed\n"); - up(&nftl->mutex); - res = 0; - goto repeat; - } - } - - DEBUG(MTD_DEBUG_LEVEL2,"NFTL read request completed OK\n"); - up(&nftl->mutex); - goto repeat; - } else if (req->cmd == WRITE) { - DEBUG(MTD_DEBUG_LEVEL2, "NFTL write request of 0x%x sectors @ %x " - "(req->nr_sectors == %lx)\n", nsect, block, - req->nr_sectors); -#ifdef CONFIG_NFTL_RW - for ( ; nsect > 0; nsect-- , block++, buffer += 512) { - /* Read a single sector to req->buffer + (512 * i) */ - if (NFTL_writeblock(nftl, block, buffer)) { - DEBUG(MTD_DEBUG_LEVEL1,"NFTL write request failed\n"); - up(&nftl->mutex); - res = 0; - goto repeat; - } - } - DEBUG(MTD_DEBUG_LEVEL2,"NFTL write request completed OK\n"); -#else - res = 0; /* Writes always fail */ -#endif /* CONFIG_NFTL_RW */ - up(&nftl->mutex); - goto repeat; - } else { - DEBUG(MTD_DEBUG_LEVEL0, "NFTL unknown request\n"); - up(&nftl->mutex); - res = 0; - goto repeat; - } - repeat: - DEBUG(MTD_DEBUG_LEVEL3, "end_request(%d)\n", res); - spin_lock_irq(&io_request_lock); - end_request(res); - } -} - -static int nftl_open(struct inode *ip, struct file *fp) -{ - int nftlnum = MINOR(ip->i_rdev) >> NFTL_PARTN_BITS; - struct NFTLrecord *thisNFTL; - thisNFTL = NFTLs[nftlnum]; - - DEBUG(MTD_DEBUG_LEVEL2,"NFTL_open\n"); - -#ifdef CONFIG_KMOD - if (!thisNFTL && nftlnum == 0) { - request_module("docprobe"); - thisNFTL = NFTLs[nftlnum]; - } -#endif - if (!thisNFTL) { - DEBUG(MTD_DEBUG_LEVEL2,"ENODEV: thisNFTL = %d, minor = %d, ip = %p, fp = %p\n", - nftlnum, ip->i_rdev, ip, fp); - return -ENODEV; - } - -#ifndef CONFIG_NFTL_RW - if (fp->f_mode & FMODE_WRITE) - return -EROFS; -#endif /* !CONFIG_NFTL_RW */ - - thisNFTL->usecount++; - BLK_INC_USE_COUNT; - if (!get_mtd_device(thisNFTL->mtd, -1)) { - BLK_DEC_USE_COUNT; - return -ENXIO; - } - - return 0; -} - -static int nftl_release(struct inode *inode, struct file *fp) -{ - struct NFTLrecord *thisNFTL; - - thisNFTL = NFTLs[MINOR(inode->i_rdev) / 16]; - - DEBUG(MTD_DEBUG_LEVEL2, "NFTL_release\n"); - - if (thisNFTL->mtd->sync) - thisNFTL->mtd->sync(thisNFTL->mtd); - thisNFTL->usecount--; - BLK_DEC_USE_COUNT; - - put_mtd_device(thisNFTL->mtd); + geo->heads = nftl->heads; + geo->sectors = nftl->sectors; + geo->cylinders = nftl->cylinders; return 0; } -#if LINUX_VERSION_CODE < 0x20326 -static struct file_operations nftl_fops = { - read: block_read, - write: block_write, - ioctl: nftl_ioctl, - open: nftl_open, - release: nftl_release, - fsync: block_fsync, -}; -#else -static struct block_device_operations nftl_fops = -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14) - owner: THIS_MODULE, -#endif - open: nftl_open, - release: nftl_release, - ioctl: nftl_ioctl -}; -#endif - - /**************************************************************************** * @@ -1048,49 +730,33 @@ * ****************************************************************************/ -static struct mtd_notifier nftl_notifier = { - add: NFTL_notify_add, - remove: NFTL_notify_remove + +struct mtd_blktrans_ops nftl_tr = { + .name = "nftl", + .major = NFTL_MAJOR, + .part_bits = NFTL_PARTN_BITS, + .getgeo = nftl_getgeo, + .readsect = nftl_readblock, +#ifdef CONFIG_NFTL_RW + .writesect = nftl_writeblock, +#endif + .add_mtd = nftl_add_mtd, + .remove_dev = nftl_remove_dev, + .owner = THIS_MODULE, }; extern char nftlmountrev[]; int __init init_nftl(void) { - int i; - -#ifdef PRERELEASE - printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.1 $, nftlmount.c %s\n", nftlmountrev); -#endif - - if (register_blkdev(MAJOR_NR, "nftl", &nftl_fops)){ - printk("unable to register NFTL block device on major %d\n", MAJOR_NR); - return -EBUSY; - } else { - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &nftl_request); + printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.3 $, nftlmount.c %s\n", nftlmountrev); - /* set block size to 1kB each */ - for (i = 0; i < 256; i++) { - nftl_blocksizes[i] = 1024; - } - blksize_size[MAJOR_NR] = nftl_blocksizes; - - add_gendisk(&nftl_gendisk); - } - - register_mtd_user(&nftl_notifier); - - return 0; + return register_mtd_blktrans(&nftl_tr); } static void __exit cleanup_nftl(void) { - unregister_mtd_user(&nftl_notifier); - unregister_blkdev(MAJOR_NR, "nftl"); - - blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); - - del_gendisk(&nftl_gendisk); + deregister_mtd_blktrans(&nftl_tr); } module_init(init_nftl); Index: drivers/mtd/nftlmount.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/nftlmount.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/nftlmount.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/nftlmount.c 3 Nov 2004 00:04:42 -0000 1.3 @@ -4,7 +4,7 @@ * Author: Fabrice Bellard (fabrice.bellard@netgem.com) * Copyright (C) 2000 Netgem S.A. * - * $Id: nftlmount.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: nftlmount.c,v 1.3 2004/11/03 00:04:42 joff Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,26 +21,17 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define __NO_VERSION__ #include -#include #include -#include -#include -#include -#include #include #include -#include -#include #include #include #include -#include #define SECTORSIZE 512 -char nftlmountrev[]="$Revision: 1.1 $"; +char nftlmountrev[]="$Revision: 1.3 $"; /* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the * various device information of the NFTL partition and Bad Unit Table. Update @@ -50,7 +41,6 @@ static int find_boot_record(struct NFTLrecord *nftl) { struct nftl_uci1 h1; - struct nftl_oob oob; unsigned int block, boot_record_count = 0; size_t retlen; u8 buf[SECTORSIZE]; @@ -59,8 +49,12 @@ /* Assume logical EraseSize == physical erasesize for starting the scan. We'll sort it out later if we find a MediaHeader which says otherwise */ - nftl->EraseSize = nftl->mtd->erasesize; - nftl->nb_blocks = nftl->mtd->size / nftl->EraseSize; + /* Actually, we won't. The new DiskOnChip driver has already scanned + the MediaHeader and adjusted the virtual erasesize it presents in + the mtd device accordingly. We could even get rid of + nftl->EraseSize if there were any point in doing so. */ + nftl->EraseSize = nftl->mbd.mtd->erasesize; + nftl->nb_blocks = nftl->mbd.mtd->size / nftl->EraseSize; nftl->MediaUnit = BLOCK_NIL; nftl->SpareMediaUnit = BLOCK_NIL; @@ -71,12 +65,15 @@ /* Check for ANAND header first. Then can whinge if it's found but later checks fail */ - if ((ret = MTD_READ(nftl->mtd, block * nftl->EraseSize, SECTORSIZE, &retlen, buf))) { + ret = MTD_READ(nftl->mbd.mtd, block * nftl->EraseSize, SECTORSIZE, &retlen, buf); + /* We ignore ret in case the ECC of the MediaHeader is invalid + (which is apparently acceptable) */ + if (retlen != SECTORSIZE) { static int warncount = 5; if (warncount) { printk(KERN_WARNING "Block read at 0x%x of mtd%d failed: %d\n", - block * nftl->EraseSize, nftl->mtd->index, ret); + block * nftl->EraseSize, nftl->mbd.mtd->index, ret); if (!--warncount) printk(KERN_WARNING "Further failures for this block will not be printed\n"); } @@ -87,16 +84,16 @@ /* ANAND\0 not found. Continue */ #if 0 printk(KERN_DEBUG "ANAND header not found at 0x%x in mtd%d\n", - block * nftl->EraseSize, nftl->mtd->index); + block * nftl->EraseSize, nftl->mbd.mtd->index); #endif continue; } /* To be safer with BIOS, also use erase mark as discriminant */ - if ((ret = MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, - 8, &retlen, (char *)&h1)) < 0) { + if ((ret = MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, + 8, &retlen, (char *)&h1) < 0)) { printk(KERN_WARNING "ANAND header found at 0x%x in mtd%d, but OOB data read failed (err %d)\n", - block * nftl->EraseSize, nftl->mtd->index, ret); + block * nftl->EraseSize, nftl->mbd.mtd->index, ret); continue; } @@ -106,23 +103,23 @@ */ if (le16_to_cpu(h1.EraseMark | h1.EraseMark1) != ERASE_MARK) { printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but erase mark not present (0x%04x,0x%04x instead)\n", - block * nftl->EraseSize, nftl->mtd->index, + block * nftl->EraseSize, nftl->mbd.mtd->index, le16_to_cpu(h1.EraseMark), le16_to_cpu(h1.EraseMark1)); continue; } /* Finally reread to check ECC */ - if ((ret = MTD_READECC(nftl->mtd, block * nftl->EraseSize, SECTORSIZE, - &retlen, buf, (char *)&oob, NAND_ECC_DISKONCHIP)) < 0) { + if ((ret = MTD_READECC(nftl->mbd.mtd, block * nftl->EraseSize, SECTORSIZE, + &retlen, buf, (char *)&oob, NULL) < 0)) { printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but ECC read failed (err %d)\n", - block * nftl->EraseSize, nftl->mtd->index, ret); + block * nftl->EraseSize, nftl->mbd.mtd->index, ret); continue; } /* Paranoia. Check the ANAND header is still there after the ECC read */ if (memcmp(buf, "ANAND", 6)) { printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but went away on reread!\n", - block * nftl->EraseSize, nftl->mtd->index); + block * nftl->EraseSize, nftl->mbd.mtd->index); printk(KERN_NOTICE "New data are: %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); continue; @@ -137,7 +134,11 @@ printk(KERN_NOTICE "NFTL Media Headers at 0x%x and 0x%x disagree.\n", nftl->MediaUnit * nftl->EraseSize, block * nftl->EraseSize); /* if (debug) Print both side by side */ - return -1; + if (boot_record_count < 2) { + /* We haven't yet seen two real ones */ + return -1; + } + continue; } if (boot_record_count == 1) nftl->SpareMediaUnit = block; @@ -154,6 +155,10 @@ memcpy(mh, buf, sizeof(struct NFTLMediaHeader)); /* Do some sanity checks on it */ +#if 0 +The new DiskOnChip driver scans the MediaHeader itself, and presents a virtual +erasesize based on UnitSizeFactor. So the erasesize we read from the mtd +device is already correct. if (mh->UnitSizeFactor == 0) { printk(KERN_NOTICE "NFTL: UnitSizeFactor 0x00 detected. This violates the spec but we think we know what it means...\n"); } else if (mh->UnitSizeFactor < 0xfc) { @@ -163,9 +168,10 @@ } else if (mh->UnitSizeFactor != 0xff) { printk(KERN_NOTICE "WARNING: Support for NFTL with UnitSizeFactor 0x%02x is experimental\n", mh->UnitSizeFactor); - nftl->EraseSize = nftl->mtd->erasesize << (0xff - mh->UnitSizeFactor); - nftl->nb_blocks = nftl->mtd->size / nftl->EraseSize; + nftl->EraseSize = nftl->mbd.mtd->erasesize << (0xff - mh->UnitSizeFactor); + nftl->nb_blocks = nftl->mbd.mtd->size / nftl->EraseSize; } +#endif nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN); if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) { printk(KERN_NOTICE "NFTL Media Header sanity check failed:\n"); @@ -182,7 +188,7 @@ return -1; } - nftl->nr_sects = nftl->numvunits * (nftl->EraseSize / SECTORSIZE); + nftl->mbd.size = nftl->numvunits * (nftl->EraseSize / SECTORSIZE); /* If we're not using the last sectors in the device for some reason, reduce nb_blocks accordingly so we forget they're there */ @@ -218,11 +224,13 @@ /* read the Bad Erase Unit Table and modify ReplUnitTable[] accordingly */ for (i = 0; i < nftl->nb_blocks; i++) { +#if 0 +The new DiskOnChip driver already scanned the bad block table. Just query it. if ((i & (SECTORSIZE - 1)) == 0) { /* read one sector for every SECTORSIZE of blocks */ - if ((ret = MTD_READECC(nftl->mtd, block * nftl->EraseSize + + if ((ret = MTD_READECC(nftl->mbd.mtd, block * nftl->EraseSize + i + SECTORSIZE, SECTORSIZE, &retlen, buf, - (char *)&oob, NAND_ECC_DISKONCHIP)) < 0) { + (char *)&oob, NULL)) < 0) { printk(KERN_NOTICE "Read of bad sector table failed (err %d)\n", ret); kfree(nftl->ReplUnitTable); @@ -233,6 +241,9 @@ /* mark the Bad Erase Unit as RESERVED in ReplUnitTable */ if (buf[i & (SECTORSIZE - 1)] != 0xff) nftl->ReplUnitTable[i] = BLOCK_RESERVED; +#endif + if (nftl->mbd.mtd->block_isbad(nftl->mbd.mtd, i * nftl->EraseSize)) + nftl->ReplUnitTable[i] = BLOCK_RESERVED; } nftl->MediaUnit = block; @@ -257,22 +268,18 @@ static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len, int check_oob) { - int i, retlen; - u8 buf[SECTORSIZE]; + int i; + size_t retlen; + u8 buf[SECTORSIZE + nftl->mbd.mtd->oobsize]; for (i = 0; i < len; i += SECTORSIZE) { - /* we want to read the sector without ECC check here since a free - sector does not have ECC syndrome on it yet */ - if (MTD_READ(nftl->mtd, address, SECTORSIZE, &retlen, buf) < 0) + if (MTD_READECC(nftl->mbd.mtd, address, SECTORSIZE, &retlen, buf, &buf[SECTORSIZE], &nftl->oobinfo) < 0) return -1; if (memcmpb(buf, 0xff, SECTORSIZE) != 0) return -1; if (check_oob) { - if (MTD_READOOB(nftl->mtd, address, nftl->mtd->oobsize, - &retlen, buf) < 0) - return -1; - if (memcmpb(buf, 0xff, nftl->mtd->oobsize) != 0) + if (memcmpb(buf + SECTORSIZE, 0xff, nftl->mbd.mtd->oobsize) != 0) return -1; } address += SECTORSIZE; @@ -287,7 +294,6 @@ * Return: 0 when succeed, -1 on error. * * ToDo: 1. Is it neceressary to check_free_sector after erasing ?? - * 2. UnitSizeFactor != 0xFF */ int NFTL_formatblock(struct NFTLrecord *nftl, int block) { @@ -297,7 +303,7 @@ struct erase_info *instr = &nftl->instr; /* Read the Unit Control Information #1 for Wear-Leveling */ - if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, + if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, &retlen, (char *)&uci) < 0) goto default_uci1; @@ -314,14 +320,13 @@ /* XXX: use async erase interface, XXX: test return code */ instr->addr = block * nftl->EraseSize; instr->len = nftl->EraseSize; - MTD_ERASE(nftl->mtd, instr); + MTD_ERASE(nftl->mbd.mtd, instr); if (instr->state == MTD_ERASE_FAILED) { - /* could not format, FixMe: We should update the BadUnitTable - both in memory and on disk */ printk("Error while formatting block %d\n", block); - return -1; - } else { + goto fail; + } + /* increase and write Wear-Leveling info */ nb_erases = le32_to_cpu(uci.WearInfo); nb_erases++; @@ -334,14 +339,18 @@ * FixMe: is this check really necessary ? since we have check the * return code after the erase operation. */ if (check_free_sectors(nftl, instr->addr, nftl->EraseSize, 1) != 0) - return -1; + goto fail; uci.WearInfo = le32_to_cpu(nb_erases); - if (MTD_WRITEOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, + if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, &retlen, (char *)&uci) < 0) - return -1; + goto fail; return 0; - } +fail: + /* could not format, update the bad block table (caller is responsible + for setting the ReplUnitTable to BLOCK_RESERVED on failure) */ + nftl->mbd.mtd->block_markbad(nftl->mbd.mtd, instr->addr); + return -1; } /* check_sectors_in_chain: Check that each sector of a Virtual Unit Chain is correct. @@ -357,13 +366,14 @@ { unsigned int block, i, status; struct nftl_bci bci; - int sectors_per_block, retlen; + int sectors_per_block; + size_t retlen; sectors_per_block = nftl->EraseSize / SECTORSIZE; block = first_block; for (;;) { for (i = 0; i < sectors_per_block; i++) { - if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + i * SECTORSIZE, + if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + i * SECTORSIZE, 8, &retlen, (char *)&bci) < 0) status = SECTOR_IGNORE; else @@ -383,7 +393,7 @@ /* sector not free actually : mark it as SECTOR_IGNORE */ bci.Status = SECTOR_IGNORE; bci.Status1 = SECTOR_IGNORE; - MTD_WRITEOOB(nftl->mtd, + MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + i * SECTORSIZE, 8, &retlen, (char *)&bci); } @@ -446,8 +456,7 @@ printk("Formatting block %d\n", block); if (NFTL_formatblock(nftl, block) < 0) { - /* cannot format !!!! Mark it as Bad Unit, - FixMe: update the BadUnitTable on disk */ + /* cannot format !!!! Mark it as Bad Unit */ nftl->ReplUnitTable[block] = BLOCK_RESERVED; } else { nftl->ReplUnitTable[block] = BLOCK_FREE; @@ -476,7 +485,7 @@ size_t retlen; /* check erase mark. */ - if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, + if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0) return -1; @@ -491,7 +500,7 @@ h1.EraseMark = cpu_to_le16(ERASE_MARK); h1.EraseMark1 = cpu_to_le16(ERASE_MARK); h1.WearInfo = cpu_to_le32(0); - if (MTD_WRITEOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, + if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0) return -1; } else { @@ -503,7 +512,7 @@ SECTORSIZE, 0) != 0) return -1; - if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + i, + if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + i, 16, &retlen, buf) < 0) return -1; if (i == SECTORSIZE) { @@ -533,7 +542,7 @@ struct nftl_uci2 uci; size_t retlen; - if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + 2 * SECTORSIZE + 8, + if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + 2 * SECTORSIZE + 8, 8, &retlen, (char *)&uci) < 0) return 0; @@ -572,9 +581,9 @@ for (;;) { /* read the block header. If error, we format the chain */ - if (MTD_READOOB(s->mtd, block * s->EraseSize + 8, 8, + if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, 8, &retlen, (char *)&h0) < 0 || - MTD_READOOB(s->mtd, block * s->EraseSize + SECTORSIZE + 8, 8, + MTD_READOOB(s->mbd.mtd, block * s->EraseSize + SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0) { s->ReplUnitTable[block] = BLOCK_NIL; do_format_chain = 1; Index: drivers/mtd/redboot.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/redboot.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/redboot.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/redboot.c 3 Nov 2004 00:04:42 -0000 1.3 @@ -1,5 +1,5 @@ /* - * $Id: redboot.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: redboot.c,v 1.3 2004/11/03 00:04:42 joff Exp $ * * Parse RedBoot-style Flash Image System (FIS) tables and * produce a Linux partition array to match. @@ -7,6 +7,8 @@ #include #include +#include +#include #include #include @@ -34,7 +36,9 @@ return 1; } -int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts) +static int parse_redboot_partitions(struct mtd_info *master, + struct mtd_partition **pparts, + unsigned long fis_origin) { int nrparts = 0; struct fis_image_desc *buf; @@ -43,21 +47,26 @@ int ret, i; size_t retlen; char *names; + char *nullname; int namelen = 0; + int nulllen = 0; +#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED + static char nullstring[] = "unallocated"; +#endif - buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + buf = vmalloc(master->erasesize); if (!buf) return -ENOMEM; /* Read the start of the last erase block */ ret = master->read(master, master->size - master->erasesize, - PAGE_SIZE, &retlen, (void *)buf); + master->erasesize, &retlen, (void *)buf); if (ret) goto out; - if (retlen != PAGE_SIZE) { + if (retlen != master->erasesize) { ret = -EIO; goto out; } @@ -75,7 +84,7 @@ goto out; } - for (i = 0; i < PAGE_SIZE / sizeof(struct fis_image_desc); i++) { + for (i = 0; i < master->erasesize / sizeof(struct fis_image_desc); i++) { struct fis_list *new_fl, **prev; if (buf[i].name[0] == 0xff) @@ -90,7 +99,11 @@ goto out; } new_fl->img = &buf[i]; - buf[i].flash_base &= master->size-1; + if (fis_origin) { + buf[i].flash_base -= fis_origin; + } else { + buf[i].flash_base &= master->size-1; + } /* I'm sure the JFFS2 code has done me permanent damage. * I now think the following is _normal_ @@ -103,42 +116,69 @@ nrparts++; } - if (fl->img->flash_base) +#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED + if (fl->img->flash_base) { nrparts++; + nulllen = sizeof(nullstring); + } for (tmp_fl = fl; tmp_fl->next; tmp_fl = tmp_fl->next) { - if (tmp_fl->img->flash_base + tmp_fl->img->size + master->erasesize < tmp_fl->next->img->flash_base) + if (tmp_fl->img->flash_base + tmp_fl->img->size + master->erasesize <= tmp_fl->next->img->flash_base) { nrparts++; + nulllen = sizeof(nullstring); + } } - parts = kmalloc(sizeof(*parts)*nrparts + namelen, GFP_KERNEL); +#endif + parts = kmalloc(sizeof(*parts)*nrparts + nulllen + namelen, GFP_KERNEL); if (!parts) { ret = -ENOMEM; goto out; } - names = (char *)&parts[nrparts]; - memset(parts, 0, sizeof(*parts)*nrparts + namelen); + + memset(parts, 0, sizeof(*parts)*nrparts + nulllen + namelen); + + nullname = (char *)&parts[nrparts]; +#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED + if (nulllen > 0) { + strcpy(nullname, nullstring); + } +#endif + names = nullname + nulllen; + i=0; +#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED if (fl->img->flash_base) { - parts[0].name = "unallocated space"; + parts[0].name = nullname; parts[0].size = fl->img->flash_base; parts[0].offset = 0; + i++; } +#endif for ( ; iimg->size; parts[i].offset = fl->img->flash_base; parts[i].name = names; strcpy(names, fl->img->name); +#ifdef CONFIG_MTD_REDBOOT_PARTS_READONLY + if (!memcmp(names, "RedBoot", 8) || + !memcmp(names, "RedBoot config", 15) || + !memcmp(names, "FIS directory", 14)) { + parts[i].mask_flags = MTD_WRITEABLE; + } +#endif names += strlen(names)+1; - if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize < fl->next->img->flash_base) { +#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED + if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) { i++; parts[i].offset = parts[i-1].size + parts[i-1].offset; parts[i].size = fl->next->img->flash_base - parts[i].offset; - parts[i].name = "unallocated space"; + parts[i].name = nullname; } +#endif tmp_fl = fl; fl = fl->next; kfree(tmp_fl); @@ -151,11 +191,28 @@ fl = fl->next; kfree(old); } - kfree(buf); + vfree(buf); return ret; } -EXPORT_SYMBOL(parse_redboot_partitions); +static struct mtd_part_parser redboot_parser = { + .owner = THIS_MODULE, + .parse_fn = parse_redboot_partitions, + .name = "RedBoot", +}; + +static int __init redboot_parser_init(void) +{ + return register_mtd_parser(&redboot_parser); +} + +static void __exit redboot_parser_exit(void) +{ + deregister_mtd_parser(&redboot_parser); +} + +module_init(redboot_parser_init); +module_exit(redboot_parser_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Red Hat, Inc. - David Woodhouse "); Index: drivers/mtd/chips/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/chips/Config.in,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/chips/Config.in 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/chips/Config.in 3 Nov 2004 00:04:42 -0000 1.3 @@ -1,6 +1,6 @@ # drivers/mtd/chips/Config.in -# $Id: Config.in,v 1.1 2004/07/22 19:49:46 joff Exp $ +# $Id: Config.in,v 1.3 2004/11/03 00:04:42 joff Exp $ mainmenu_option next_comment @@ -18,6 +18,7 @@ define_bool CONFIG_MTD_GEN_PROBE n fi fi + if [ "$CONFIG_MTD_GEN_PROBE" = "y" -o "$CONFIG_MTD_GEN_PROBE" = "m" ]; then bool ' Flash chip driver advanced configuration options' CONFIG_MTD_CFI_ADV_OPTIONS if [ "$CONFIG_MTD_CFI_ADV_OPTIONS" = "y" ]; then @@ -27,11 +28,13 @@ LITTLE_ENDIAN_BYTE CONFIG_MTD_CFI_LE_BYTE_SWAP" NO bool ' Specific CFI Flash geometry selection' CONFIG_MTD_CFI_GEOMETRY if [ "$CONFIG_MTD_CFI_GEOMETRY" = "y" ]; then - bool ' Support 8-bit buswidth' CONFIG_MTD_CFI_B1 - bool ' Support 16-bit buswidth' CONFIG_MTD_CFI_B2 - bool ' Support 32-bit buswidth' CONFIG_MTD_CFI_B4 - bool ' Support 64-bit buswidth' CONFIG_MTD_CFI_B8 - if [ "$CONFIG_MTD_CFI_B1" = "y" ]; then + bool ' Support 8-bit buswidth' CONFIG_MTD_MAP_BANK_WIDTH_1 + bool ' Support 16-bit buswidth' CONFIG_MTD_MAP_BANK_WIDTH_2 + bool ' Support 32-bit buswidth' CONFIG_MTD_MAP_BANK_WIDTH_4 + bool ' Support 64-bit buswidth' CONFIG_MTD_MAP_BANK_WIDTH_8 + bool ' Support 128-bit buswidth' CONFIG_MTD_MAP_BANK_WIDTH_16 + bool ' Support 256-bit buswidth' CONFIG_MTD_MAP_BANK_WIDTH_32 + if [ "$CONFIG_MTD_MAP_BANK_WIDTH_1" = "y" ]; then define_bool CONFIG_MTD_CFI_I1 y else bool ' Support 1-chip flash interleave' CONFIG_MTD_CFI_I1 @@ -46,6 +49,20 @@ dep_tristate ' Support for AMD/Fujitsu flash chips' CONFIG_MTD_CFI_AMDSTD $CONFIG_MTD_GEN_PROBE dep_tristate ' Support for ST (Advanced Architecture) flash chips' CONFIG_MTD_CFI_STAA $CONFIG_MTD_GEN_PROBE +if [ "$CONFIG_MTD_CFI_INTELEXT" = "y" \ + -o "$CONFIG_MTD_CFI_AMDSTD" = "y" \ + -o "$CONFIG_MTD_CFI_STAA" = "y" ]; then + define_bool CONFIG_MTD_CFI_UTIL y +else + if [ "$CONFIG_MTD_CFI_INTELEXT" = "m" \ + -o "$CONFIG_MTD_CFI_AMDSTD" = "m" \ + -o "$CONFIG_MTD_CFI_STAA" = "m" ]; then + define_bool CONFIG_MTD_CFI_UTIL m + else + define_bool CONFIG_MTD_CFI_UTIL n + fi +fi + dep_tristate ' Support for RAM chips in bus mapping' CONFIG_MTD_RAM $CONFIG_MTD dep_tristate ' Support for ROM chips in bus mapping' CONFIG_MTD_ROM $CONFIG_MTD dep_tristate ' Support for absent chips in bus mapping' CONFIG_MTD_ABSENT $CONFIG_MTD Index: drivers/mtd/chips/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/chips/Makefile,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/chips/Makefile 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/chips/Makefile 3 Nov 2004 00:04:42 -0000 1.3 @@ -1,31 +1,12 @@ # -# linux/drivers/chips/Makefile +# linux/drivers/chips/Makefile.24 +# Makefile for obsolete kernels. # -# $Id: Makefile,v 1.1 2004/07/22 19:49:46 joff Exp $ +# $Id: Makefile,v 1.3 2004/11/03 00:04:42 joff Exp $ O_TARGET := chipslink.o +export-objs := chipreg.o gen_probe.o cfi_util.o -export-objs := chipreg.o gen_probe.o - -# *** BIG UGLY NOTE *** -# -# The removal of get_module_symbol() and replacement with -# inter_module_register() et al has introduced a link order dependency -# here where previously there was none. We now have to ensure that -# the CFI command set drivers are linked before cfi_probe.o - -obj-$(CONFIG_MTD) += chipreg.o -obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o -obj-$(CONFIG_MTD_CFI) += cfi_probe.o -obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o -obj-$(CONFIG_MTD_CFI_AMDSTD) += cfi_cmdset_0002.o -obj-$(CONFIG_MTD_CFI_INTELEXT) += cfi_cmdset_0001.o -obj-$(CONFIG_MTD_GEN_PROBE) += gen_probe.o -obj-$(CONFIG_MTD_JEDEC) += jedec.o -obj-$(CONFIG_MTD_JEDECPROBE) += jedec_probe.o -obj-$(CONFIG_MTD_RAM) += map_ram.o -obj-$(CONFIG_MTD_ROM) += map_rom.o -obj-$(CONFIG_MTD_SHARP) += sharp.o -obj-$(CONFIG_MTD_ABSENT) += map_absent.o +include Makefile.common include $(TOPDIR)/Rules.make Index: drivers/mtd/chips/amd_flash.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/chips/amd_flash.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/chips/amd_flash.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/chips/amd_flash.c 3 Nov 2004 00:04:42 -0000 1.3 @@ -3,7 +3,7 @@ * * Author: Jonas Holmberg * - * $Id: amd_flash.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: amd_flash.c,v 1.3 2004/11/03 00:04:42 joff Exp $ * * Copyright (c) 2001 Axis Communications AB * @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -125,10 +126,10 @@ static struct mtd_chip_driver amd_flash_chipdrv = { - probe: amd_flash_probe, - destroy: amd_flash_destroy, - name: "amd_flash", - module: THIS_MODULE + .probe = amd_flash_probe, + .destroy = amd_flash_destroy, + .name = "amd_flash", + .module = THIS_MODULE }; @@ -140,11 +141,11 @@ static inline __u32 wide_read(struct map_info *map, __u32 addr) { if (map->buswidth == 1) { - return map->read8(map, addr); + return map_read8(map, addr); } else if (map->buswidth == 2) { - return map->read16(map, addr); + return map_read16(map, addr); } else if (map->buswidth == 4) { - return map->read32(map, addr); + return map_read32(map, addr); } return 0; @@ -153,11 +154,11 @@ static inline void wide_write(struct map_info *map, __u32 val, __u32 addr) { if (map->buswidth == 1) { - map->write8(map, val, addr); + map_write8(map, val, addr); } else if (map->buswidth == 2) { - map->write16(map, val, addr); + map_write16(map, val, addr); } else if (map->buswidth == 4) { - map->write32(map, val, addr); + map_write32(map, val, addr); } } @@ -424,231 +425,228 @@ static struct mtd_info *amd_flash_probe(struct map_info *map) { - /* Keep this table on the stack so that it gets deallocated after the - * probe is done. - */ - const struct amd_flash_info table[] = { + static const struct amd_flash_info table[] = { { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29LV160DT, - name: "AMD AM29LV160DT", - size: 0x00200000, - numeraseregions: 4, - regions: { - { offset: 0x000000, erasesize: 0x10000, numblocks: 31 }, - { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 }, - { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 }, - { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 } + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29LV160DT, + .name = "AMD AM29LV160DT", + .size = 0x00200000, + .numeraseregions = 4, + .regions = { + { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, + { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 }, + { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 }, + { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 } } }, { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29LV160DB, - name: "AMD AM29LV160DB", - size: 0x00200000, - numeraseregions: 4, - regions: { - { offset: 0x000000, erasesize: 0x04000, numblocks: 1 }, - { offset: 0x004000, erasesize: 0x02000, numblocks: 2 }, - { offset: 0x008000, erasesize: 0x08000, numblocks: 1 }, - { offset: 0x010000, erasesize: 0x10000, numblocks: 31 } + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29LV160DB, + .name = "AMD AM29LV160DB", + .size = 0x00200000, + .numeraseregions = 4, + .regions = { + { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, + { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, + { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, + { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 } } }, { - mfr_id: MANUFACTURER_TOSHIBA, - dev_id: TC58FVT160, - name: "Toshiba TC58FVT160", - size: 0x00200000, - numeraseregions: 4, - regions: { - { offset: 0x000000, erasesize: 0x10000, numblocks: 31 }, - { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 }, - { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 }, - { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 } + .mfr_id = MANUFACTURER_TOSHIBA, + .dev_id = TC58FVT160, + .name = "Toshiba TC58FVT160", + .size = 0x00200000, + .numeraseregions = 4, + .regions = { + { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, + { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 }, + { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 }, + { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 } } }, { - mfr_id: MANUFACTURER_FUJITSU, - dev_id: MBM29LV160TE, - name: "Fujitsu MBM29LV160TE", - size: 0x00200000, - numeraseregions: 4, - regions: { - { offset: 0x000000, erasesize: 0x10000, numblocks: 31 }, - { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 }, - { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 }, - { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 } + .mfr_id = MANUFACTURER_FUJITSU, + .dev_id = MBM29LV160TE, + .name = "Fujitsu MBM29LV160TE", + .size = 0x00200000, + .numeraseregions = 4, + .regions = { + { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, + { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 }, + { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 }, + { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 } } }, { - mfr_id: MANUFACTURER_TOSHIBA, - dev_id: TC58FVB160, - name: "Toshiba TC58FVB160", - size: 0x00200000, - numeraseregions: 4, - regions: { - { offset: 0x000000, erasesize: 0x04000, numblocks: 1 }, - { offset: 0x004000, erasesize: 0x02000, numblocks: 2 }, - { offset: 0x008000, erasesize: 0x08000, numblocks: 1 }, - { offset: 0x010000, erasesize: 0x10000, numblocks: 31 } + .mfr_id = MANUFACTURER_TOSHIBA, + .dev_id = TC58FVB160, + .name = "Toshiba TC58FVB160", + .size = 0x00200000, + .numeraseregions = 4, + .regions = { + { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, + { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, + { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, + { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 } } }, { - mfr_id: MANUFACTURER_FUJITSU, - dev_id: MBM29LV160BE, - name: "Fujitsu MBM29LV160BE", - size: 0x00200000, - numeraseregions: 4, - regions: { - { offset: 0x000000, erasesize: 0x04000, numblocks: 1 }, - { offset: 0x004000, erasesize: 0x02000, numblocks: 2 }, - { offset: 0x008000, erasesize: 0x08000, numblocks: 1 }, - { offset: 0x010000, erasesize: 0x10000, numblocks: 31 } + .mfr_id = MANUFACTURER_FUJITSU, + .dev_id = MBM29LV160BE, + .name = "Fujitsu MBM29LV160BE", + .size = 0x00200000, + .numeraseregions = 4, + .regions = { + { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, + { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, + { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, + { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 } } }, { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29LV800BB, - name: "AMD AM29LV800BB", - size: 0x00100000, - numeraseregions: 4, - regions: { - { offset: 0x000000, erasesize: 0x04000, numblocks: 1 }, - { offset: 0x004000, erasesize: 0x02000, numblocks: 2 }, - { offset: 0x008000, erasesize: 0x08000, numblocks: 1 }, - { offset: 0x010000, erasesize: 0x10000, numblocks: 15 } + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29LV800BB, + .name = "AMD AM29LV800BB", + .size = 0x00100000, + .numeraseregions = 4, + .regions = { + { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, + { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, + { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, + { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 15 } } }, { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29F800BB, - name: "AMD AM29F800BB", - size: 0x00100000, - numeraseregions: 4, - regions: { - { offset: 0x000000, erasesize: 0x04000, numblocks: 1 }, - { offset: 0x004000, erasesize: 0x02000, numblocks: 2 }, - { offset: 0x008000, erasesize: 0x08000, numblocks: 1 }, - { offset: 0x010000, erasesize: 0x10000, numblocks: 15 } + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29F800BB, + .name = "AMD AM29F800BB", + .size = 0x00100000, + .numeraseregions = 4, + .regions = { + { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, + { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, + { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, + { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 15 } } }, { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29LV800BT, - name: "AMD AM29LV800BT", - size: 0x00100000, - numeraseregions: 4, - regions: { - { offset: 0x000000, erasesize: 0x10000, numblocks: 15 }, - { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 }, - { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 }, - { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 } + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29LV800BT, + .name = "AMD AM29LV800BT", + .size = 0x00100000, + .numeraseregions = 4, + .regions = { + { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 }, + { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 }, + { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 }, + { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 } } }, { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29F800BT, - name: "AMD AM29F800BT", - size: 0x00100000, - numeraseregions: 4, - regions: { - { offset: 0x000000, erasesize: 0x10000, numblocks: 15 }, - { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 }, - { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 }, - { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 } + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29F800BT, + .name = "AMD AM29F800BT", + .size = 0x00100000, + .numeraseregions = 4, + .regions = { + { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 }, + { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 }, + { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 }, + { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 } } }, { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29LV800BB, - name: "AMD AM29LV800BB", - size: 0x00100000, - numeraseregions: 4, - regions: { - { offset: 0x000000, erasesize: 0x10000, numblocks: 15 }, - { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 }, - { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 }, - { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 } + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29LV800BB, + .name = "AMD AM29LV800BB", + .size = 0x00100000, + .numeraseregions = 4, + .regions = { + { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 }, + { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 }, + { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 }, + { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 } } }, { - mfr_id: MANUFACTURER_FUJITSU, - dev_id: MBM29LV800BB, - name: "Fujitsu MBM29LV800BB", - size: 0x00100000, - numeraseregions: 4, - regions: { - { offset: 0x000000, erasesize: 0x04000, numblocks: 1 }, - { offset: 0x004000, erasesize: 0x02000, numblocks: 2 }, - { offset: 0x008000, erasesize: 0x08000, numblocks: 1 }, - { offset: 0x010000, erasesize: 0x10000, numblocks: 15 } + .mfr_id = MANUFACTURER_FUJITSU, + .dev_id = MBM29LV800BB, + .name = "Fujitsu MBM29LV800BB", + .size = 0x00100000, + .numeraseregions = 4, + .regions = { + { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, + { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, + { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, + { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 15 } } }, { - mfr_id: MANUFACTURER_ST, - dev_id: M29W800T, - name: "ST M29W800T", - size: 0x00100000, - numeraseregions: 4, - regions: { - { offset: 0x000000, erasesize: 0x10000, numblocks: 15 }, - { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 }, - { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 }, - { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 } + .mfr_id = MANUFACTURER_ST, + .dev_id = M29W800T, + .name = "ST M29W800T", + .size = 0x00100000, + .numeraseregions = 4, + .regions = { + { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 }, + { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 }, + { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 }, + { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 } } }, { - mfr_id: MANUFACTURER_ST, - dev_id: M29W160DT, - name: "ST M29W160DT", - size: 0x00200000, - numeraseregions: 4, - regions: { - { offset: 0x000000, erasesize: 0x10000, numblocks: 31 }, - { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 }, - { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 }, - { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 } + .mfr_id = MANUFACTURER_ST, + .dev_id = M29W160DT, + .name = "ST M29W160DT", + .size = 0x00200000, + .numeraseregions = 4, + .regions = { + { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, + { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 }, + { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 }, + { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 } } }, { - mfr_id: MANUFACTURER_ST, - dev_id: M29W160DB, - name: "ST M29W160DB", - size: 0x00200000, - numeraseregions: 4, - regions: { - { offset: 0x000000, erasesize: 0x04000, numblocks: 1 }, - { offset: 0x004000, erasesize: 0x02000, numblocks: 2 }, - { offset: 0x008000, erasesize: 0x08000, numblocks: 1 }, - { offset: 0x010000, erasesize: 0x10000, numblocks: 31 } + .mfr_id = MANUFACTURER_ST, + .dev_id = M29W160DB, + .name = "ST M29W160DB", + .size = 0x00200000, + .numeraseregions = 4, + .regions = { + { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, + { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, + { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, + { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 } } }, { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29BDS323D, - name: "AMD AM29BDS323D", - size: 0x00400000, - numeraseregions: 3, - regions: { - { offset: 0x000000, erasesize: 0x10000, numblocks: 48 }, - { offset: 0x300000, erasesize: 0x10000, numblocks: 15 }, - { offset: 0x3f0000, erasesize: 0x02000, numblocks: 8 }, + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29BDS323D, + .name = "AMD AM29BDS323D", + .size = 0x00400000, + .numeraseregions = 3, + .regions = { + { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 48 }, + { .offset = 0x300000, .erasesize = 0x10000, .numblocks = 15 }, + { .offset = 0x3f0000, .erasesize = 0x02000, .numblocks = 8 }, } }, { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29BDS643D, - name: "AMD AM29BDS643D", - size: 0x00800000, - numeraseregions: 3, - regions: { - { offset: 0x000000, erasesize: 0x10000, numblocks: 96 }, - { offset: 0x600000, erasesize: 0x10000, numblocks: 31 }, - { offset: 0x7f0000, erasesize: 0x02000, numblocks: 8 }, + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29BDS643D, + .name = "AMD AM29BDS643D", + .size = 0x00800000, + .numeraseregions = 3, + .regions = { + { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 96 }, + { .offset = 0x600000, .erasesize = 0x10000, .numblocks = 31 }, + { .offset = 0x7f0000, .erasesize = 0x02000, .numblocks = 8 }, } }, { - mfr_id: MANUFACTURER_ATMEL, - dev_id: AT49xV16x, - name: "Atmel AT49xV16x", - size: 0x00200000, - numeraseregions: 2, - regions: { - { offset: 0x000000, erasesize: 0x02000, numblocks: 8 }, - { offset: 0x010000, erasesize: 0x10000, numblocks: 31 } + .mfr_id = MANUFACTURER_ATMEL, + .dev_id = AT49xV16x, + .name = "Atmel AT49xV16x", + .size = 0x00200000, + .numeraseregions = 2, + .regions = { + { .offset = 0x000000, .erasesize = 0x02000, .numblocks = 8 }, + { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 } } }, { - mfr_id: MANUFACTURER_ATMEL, - dev_id: AT49xV16xT, - name: "Atmel AT49xV16xT", - size: 0x00200000, - numeraseregions: 2, - regions: { - { offset: 0x000000, erasesize: 0x10000, numblocks: 31 }, - { offset: 0x1F0000, erasesize: 0x02000, numblocks: 8 } + .mfr_id = MANUFACTURER_ATMEL, + .dev_id = AT49xV16xT, + .name = "Atmel AT49xV16xT", + .size = 0x00200000, + .numeraseregions = 2, + .regions = { + { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, + { .offset = 0x1F0000, .erasesize = 0x02000, .numblocks = 8 } } } }; @@ -720,7 +718,7 @@ "memory for MTD erase region info\n", map->name); kfree(mtd); map->fldrv_priv = NULL; - return 0; + return NULL; } reg_idx = 0; @@ -782,8 +780,8 @@ map->fldrv_priv = private; map->fldrv = &amd_flash_chipdrv; - MOD_INC_USE_COUNT; + __module_get(THIS_MODULE); return mtd; } @@ -822,7 +820,7 @@ chip->state = FL_READY; - map->copy_from(map, buf, adr, len); + map_copy_from(map, buf, adr, len); wake_up(&chip->wq); spin_unlock_bh(chip->mutex); @@ -984,7 +982,7 @@ u_char tmp_buf[4]; __u32 datum; - map->copy_from(map, tmp_buf, + map_copy_from(map, tmp_buf, bus_ofs + private->chips[chipnum].start, map->buswidth); while (len && i < map->buswidth) @@ -1057,7 +1055,7 @@ u_char tmp_buf[2]; __u32 datum; - map->copy_from(map, tmp_buf, + map_copy_from(map, tmp_buf, ofs + private->chips[chipnum].start, map->buswidth); while (len--) { @@ -1178,7 +1176,7 @@ __u8 verify; for (address = adr; address < (adr + size); address++) { - if ((verify = map->read8(map, address)) != 0xFF) { + if ((verify = map_read8(map, address)) != 0xFF) { error = 1; break; } @@ -1309,9 +1307,7 @@ } instr->state = MTD_ERASE_DONE; - if (instr->callback) { - instr->callback(instr); - } + mtd_erase_callback(instr); return 0; } Index: drivers/mtd/chips/cfi_cmdset_0001.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/chips/cfi_cmdset_0001.c,v retrieving revision 1.1 retrieving revision 1.4 diff -u -r1.1 -r1.4 --- drivers/mtd/chips/cfi_cmdset_0001.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/chips/cfi_cmdset_0001.c 3 Nov 2004 00:04:42 -0000 1.4 @@ -4,7 +4,7 @@ * * (C) 2000 Red Hat. GPL'd * - * $Id: cfi_cmdset_0001.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: cfi_cmdset_0001.c,v 1.4 2004/11/03 00:04:42 joff Exp $ * * * 10/10/2000 Nicolas Pitre @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include @@ -29,14 +31,24 @@ #include #include #include -#include +#include #include +#include + +/* #define CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE */ + +// debugging, turns off buffer write mode if set to 1 +#define FORCE_WORD_WRITE 0 -// debugging, turns off buffer write mode #define FORCE_WORD_WRITE +#define MANUFACTURER_INTEL 0x0089 +#define I82802AB 0x00ad +#define I82802AC 0x00ac +#define MANUFACTURER_ST 0x0020 +#define M50LPW080 0x002F static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); -static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *); -static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *); +//static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *); +//static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *); @@ -50,38 +62,61 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *, int); -static struct mtd_info *cfi_intelext_setup (struct map_info *); +static struct mtd_info *cfi_intelext_setup (struct mtd_info *); +static int cfi_intelext_partition_fixup(struct map_info *, struct cfi_private **); -static int do_point (struct mtd_info *mtd, loff_t from, size_t len, +static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf); -static void do_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, +static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len); +static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode); +static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr); +#include "fwh_lock.h" + + + +/* + * *********** SETUP AND PROBE BITS *********** + */ + static struct mtd_chip_driver cfi_intelext_chipdrv = { - probe: NULL, /* Not usable directly */ - destroy: cfi_intelext_destroy, - name: "cfi_cmdset_0001", - module: THIS_MODULE + .probe = NULL, /* Not usable directly */ + .destroy = cfi_intelext_destroy, + .name = "cfi_cmdset_0001", + .module = THIS_MODULE }; /* #define DEBUG_LOCK_BITS */ /* #define DEBUG_CFI_FEATURES */ +static inline unsigned long msecs_to_jiffies(unsigned long msecs) +{ + return ((HZ * msecs + 999) / 1000); +} + +static void msleep(unsigned long msecs) +{ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(msecs_to_jiffies(msecs)); +} + #ifdef DEBUG_CFI_FEATURES static void cfi_tell_features(struct cfi_pri_intelext *extp) { int i; - printk(" Feature/Command Support: %4.4X\n", extp->FeatureSupport); - printk(" - Chip Erase: %s\n", extp->FeatureSupport&1?"supported":"unsupported"); - printk(" - Suspend Erase: %s\n", extp->FeatureSupport&2?"supported":"unsupported"); - printk(" - Suspend Program: %s\n", extp->FeatureSupport&4?"supported":"unsupported"); - printk(" - Legacy Lock/Unlock: %s\n", extp->FeatureSupport&8?"supported":"unsupported"); - printk(" - Queued Erase: %s\n", extp->FeatureSupport&16?"supported":"unsupported"); - printk(" - Instant block lock: %s\n", extp->FeatureSupport&32?"supported":"unsupported"); - printk(" - Protection Bits: %s\n", extp->FeatureSupport&64?"supported":"unsupported"); - printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported"); - printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported"); - for (i=9; i<32; i++) { + printk(" Feature/Command Support: %4.4X\n", extp->FeatureSupport); + printk(" - Chip Erase: %s\n", extp->FeatureSupport&1?"supported":"unsupported"); + printk(" - Suspend Erase: %s\n", extp->FeatureSupport&2?"supported":"unsupported"); + printk(" - Suspend Program: %s\n", extp->FeatureSupport&4?"supported":"unsupported"); + printk(" - Legacy Lock/Unlock: %s\n", extp->FeatureSupport&8?"supported":"unsupported"); + printk(" - Queued Erase: %s\n", extp->FeatureSupport&16?"supported":"unsupported"); + printk(" - Instant block lock: %s\n", extp->FeatureSupport&32?"supported":"unsupported"); + printk(" - Protection Bits: %s\n", extp->FeatureSupport&64?"supported":"unsupported"); + printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported"); + printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported"); + printk(" - Simultaneous operations: %s\n", extp->FeatureSupport&512?"supported":"unsupported"); + for (i=10; i<32; i++) { if (extp->FeatureSupport & (1<VccOptimal >> 8, extp->VccOptimal & 0xf); + extp->VccOptimal >> 4, extp->VccOptimal & 0xf); if (extp->VppOptimal) printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", - extp->VppOptimal >> 8, extp->VppOptimal & 0xf); + extp->VppOptimal >> 4, extp->VppOptimal & 0xf); +} +#endif + +#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE +/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */ +static void fixup_intel_strataflash(struct mtd_info *mtd, void* param) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + struct cfi_pri_amdstd *extp = cfi->cmdset_priv; + + printk(KERN_WARNING "cfi_cmdset_0001: Suspend " + "erase on write disabled.\n"); + extp->SuspendCmdSupport &= ~1; } #endif +static void fixup_st_m28w320ct(struct mtd_info *mtd, void* param) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + + cfi->cfiq->BufWriteTimeoutTyp = 0; /* Not supported */ + cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */ +} + +static void fixup_st_m28w320cb(struct mtd_info *mtd, void* param) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + + /* Note this is done after the region info is endian swapped */ + cfi->cfiq->EraseRegionInfo[1] = + (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e; +}; + +static void fixup_use_point(struct mtd_info *mtd, void *param) +{ + struct map_info *map = mtd->priv; + if (!mtd->point && map_is_linear(map)) { + mtd->point = cfi_intelext_point; + mtd->unpoint = cfi_intelext_unpoint; + } +} + +static void fixup_use_write_buffers(struct mtd_info *mtd, void *param) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + if (cfi->cfiq->BufWriteTimeoutTyp) { + printk(KERN_INFO "Using buffer write method\n" ); + mtd->write = cfi_intelext_write_buffers; + } +} + +static struct cfi_fixup cfi_fixup_table[] = { +#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE + { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL }, +#endif +#if !FORCE_WORD_WRITE + { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL }, +#endif + { CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct, NULL }, + { CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb, NULL }, + { 0, 0, NULL, NULL } +}; + +static struct cfi_fixup jedec_fixup_table[] = { + { MANUFACTURER_INTEL, I82802AB, fixup_use_fwh_lock, NULL, }, + { MANUFACTURER_INTEL, I82802AC, fixup_use_fwh_lock, NULL, }, + { MANUFACTURER_ST, M50LPW080, fixup_use_fwh_lock, NULL, }, + { 0, 0, NULL, NULL } +}; +static struct cfi_fixup fixup_table[] = { + /* The CFI vendor ids and the JEDEC vendor IDs appear + * to be common. It is like the devices id's are as + * well. This table is to pick all cases where + * we know that is the case. + */ + { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_point, NULL }, + { 0, 0, NULL, NULL } +}; + /* This routine is made available to other mtd code via * inter_module_register. It must only be accessed through * inter_module_get which will bump the use count of this module. The @@ -119,9 +234,30 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary) { struct cfi_private *cfi = map->fldrv_priv; + struct mtd_info *mtd; int i; - __u32 base = cfi->chips[0].start; + mtd = kmalloc(sizeof(*mtd), GFP_KERNEL); + if (!mtd) { + printk(KERN_ERR "Failed to allocate memory for MTD device\n"); + return NULL; + } + memset(mtd, 0, sizeof(*mtd)); + mtd->priv = map; + mtd->type = MTD_NORFLASH; + + /* Fill in the default mtd operations */ + mtd->erase = cfi_intelext_erase_varsize; + mtd->read = cfi_intelext_read; + mtd->write = cfi_intelext_write_words; + mtd->sync = cfi_intelext_sync; + mtd->lock = cfi_intelext_lock; + mtd->unlock = cfi_intelext_unlock; + mtd->suspend = cfi_intelext_suspend; + mtd->resume = cfi_intelext_resume; + mtd->flags = MTD_CAP_NORFLASH; + mtd->name = map->name; + if (cfi->cfi_mode == CFI_MODE_CFI) { /* * It's a real CFI chip, not one for which the probe @@ -130,33 +266,10 @@ */ __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR; struct cfi_pri_intelext *extp; - int ofs_factor = cfi->interleave * cfi->device_type; - - //printk(" Intel/Sharp Extended Query Table at 0x%4.4X\n", adr); - if (!adr) - return NULL; - - /* Switch it into Query Mode */ - cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); - extp = kmalloc(sizeof(*extp), GFP_KERNEL); + extp = (struct cfi_pri_intelext*)cfi_read_pri(map, adr, sizeof(*extp), "Intel/Sharp"); if (!extp) { - printk(KERN_ERR "Failed to allocate memory\n"); - return NULL; - } - - /* Read in the Extended Query Table */ - for (i=0; iMajorVersion != '1' || - (extp->MinorVersion < '0' || extp->MinorVersion > '3')) { - printk(KERN_WARNING " Unknown IntelExt Extended Query " - "version %c.%c.\n", extp->MajorVersion, - extp->MinorVersion); - kfree(extp); + kfree(mtd); return NULL; } @@ -164,6 +277,11 @@ extp->FeatureSupport = le32_to_cpu(extp->FeatureSupport); extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask); extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr); + + /* Install our own private info structure */ + cfi->cmdset_priv = extp; + + cfi_fixup(mtd, cfi_fixup_table); #ifdef DEBUG_CFI_FEATURES /* Tell the user about it in lots of lovely detail */ @@ -171,19 +289,15 @@ #endif if(extp->SuspendCmdSupport & 1) { -//#define CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE -#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE -/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */ - printk(KERN_WARNING "cfi_cmdset_0001: Suspend " - "erase on write disabled.\n"); - extp->SuspendCmdSupport &= ~1; -#else printk(KERN_NOTICE "cfi_cmdset_0001: Erase suspend on write enabled\n"); -#endif } - /* Install our own private info structure */ - cfi->cmdset_priv = extp; } + else if (cfi->cfi_mode == CFI_MODE_JEDEC) { + /* Apply jedec specific fixups */ + cfi_fixup(mtd, jedec_fixup_table); + } + /* Apply generic fixups */ + cfi_fixup(mtd, fixup_table); for (i=0; i< cfi->numchips; i++) { cfi->chips[i].word_write_time = 1<cfiq->WordWriteTimeoutTyp; @@ -194,30 +308,19 @@ map->fldrv = &cfi_intelext_chipdrv; - /* Make sure it's in read mode */ - cfi_send_gen_cmd(0xff, 0x55, base, map, cfi, cfi->device_type, NULL); - return cfi_intelext_setup(map); + return cfi_intelext_setup(mtd); } -static struct mtd_info *cfi_intelext_setup(struct map_info *map) +static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd) { + struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; - struct mtd_info *mtd; unsigned long offset = 0; int i,j; unsigned long devsize = (1<cfiq->DevSize) * cfi->interleave; - mtd = kmalloc(sizeof(*mtd), GFP_KERNEL); //printk(KERN_DEBUG "number of CFI chips: %d\n", cfi->numchips); - if (!mtd) { - printk(KERN_ERR "Failed to allocate memory for MTD device\n"); - goto setup_err; - } - - memset(mtd, 0, sizeof(*mtd)); - mtd->priv = map; - mtd->type = MTD_NORFLASH; mtd->size = devsize * cfi->numchips; mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; @@ -257,37 +360,17 @@ mtd->eraseregions[i].numblocks); } - /* Also select the correct geometry setup too */ - mtd->erase = cfi_intelext_erase_varsize; - mtd->read = cfi_intelext_read; - - if(map->point && map->unpoint){ - mtd->point = do_point; - mtd->unpoint = do_unpoint; - } - -#ifndef FORCE_WORD_WRITE - if ( cfi->cfiq->BufWriteTimeoutTyp ) { - printk("Using buffer write method\n" ); - mtd->write = cfi_intelext_write_buffers; - } else { -#else - { -#endif - printk("Using word write method\n" ); - mtd->write = cfi_intelext_write_words; - } +#if 0 mtd->read_user_prot_reg = cfi_intelext_read_user_prot_reg; mtd->read_fact_prot_reg = cfi_intelext_read_fact_prot_reg; - mtd->sync = cfi_intelext_sync; - mtd->lock = cfi_intelext_lock; - mtd->unlock = cfi_intelext_unlock; - mtd->suspend = cfi_intelext_suspend; - mtd->resume = cfi_intelext_resume; - mtd->flags = MTD_CAP_NORFLASH; - map->fldrv = &cfi_intelext_chipdrv; - MOD_INC_USE_COUNT; - mtd->name = map->name; +#endif + + /* This function has the potential to distort the reality + a bit and therefore should be called last. */ + if (cfi_intelext_partition_fixup(map, &cfi) != 0) + goto setup_err; + + __module_get(THIS_MODULE); return mtd; setup_err: @@ -297,82 +380,343 @@ kfree(mtd); } kfree(cfi->cmdset_priv); - kfree(cfi->cfiq); return NULL; } -static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len) +static int cfi_intelext_partition_fixup(struct map_info *map, + struct cfi_private **pcfi) { - cfi_word status, status_OK; - unsigned long timeo; - DECLARE_WAITQUEUE(wait, current); - unsigned long cmd_addr; - struct cfi_private *cfi = map->fldrv_priv; + struct cfi_private *cfi = *pcfi; + struct cfi_pri_intelext *extp = cfi->cmdset_priv; - adr += chip->start; + /* + * Probing of multi-partition flash ships. + * + * This is extremely crude at the moment and should probably be + * extracted entirely from the Intel extended query data instead. + * Right now a L18 flash is assumed if multiple operations is + * detected. + * + * To support multiple partitions when available, we simply arrange + * for each of them to have their own flchip structure even if they + * are on the same physical chip. This means completely recreating + * a new cfi_private structure right here which is a blatent code + * layering violation, but this is still the least intrusive + * arrangement at this point. This can be rearranged in the future + * if someone feels motivated enough. --nico + */ + if (extp && extp->FeatureSupport & (1 << 9)) { + struct cfi_private *newcfi; + struct flchip *chip; + struct flchip_shared *shared; + int numparts, partshift, numvirtchips, i, j; - /* Ensure cmd read/writes are aligned. */ - cmd_addr = adr & ~(CFIDEV_BUSWIDTH-1); + /* + * The L18 flash memory array is divided + * into multiple 8-Mbit partitions. + */ + numparts = 1 << (cfi->cfiq->DevSize - 20); + partshift = 20 + ffs(cfi->interleave); + numvirtchips = cfi->numchips * numparts; + + newcfi = kmalloc(sizeof(struct cfi_private) + numvirtchips * sizeof(struct flchip), GFP_KERNEL); + if (!newcfi) + return -ENOMEM; + shared = kmalloc(sizeof(struct flchip_shared) * cfi->numchips, GFP_KERNEL); + if (!shared) { + kfree(newcfi); + return -ENOMEM; + } + memcpy(newcfi, cfi, sizeof(struct cfi_private)); + newcfi->numchips = numvirtchips; + newcfi->chipshift = partshift; + + chip = &newcfi->chips[0]; + for (i = 0; i < cfi->numchips; i++) { + shared[i].writing = shared[i].erasing = NULL; + spin_lock_init(&shared[i].lock); + for (j = 0; j < numparts; j++) { + *chip = cfi->chips[i]; + chip->start += j << partshift; + chip->priv = &shared[i]; + /* those should be reset too since + they create memory references. */ + init_waitqueue_head(&chip->wq); + spin_lock_init(&chip->_spinlock); + chip->mutex = &chip->_spinlock; + chip++; + } + } - /* Let's determine this according to the interleave only once */ - status_OK = CMD(0x80); + printk(KERN_DEBUG "%s: %d sets of %d interleaved chips " + "--> %d partitions of %#x bytes\n", + map->name, cfi->numchips, cfi->interleave, + newcfi->numchips, 1<chipshift); + + map->fldrv_priv = newcfi; + *pcfi = newcfi; + kfree(cfi); + } + + return 0; +} + +/* + * *********** CHIP ACCESS FUNCTIONS *********** + */ +static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode) +{ + DECLARE_WAITQUEUE(wait, current); + struct cfi_private *cfi = map->fldrv_priv; + map_word status, status_OK = CMD(0x80), status_PWS = CMD(0x01); + unsigned long timeo; + struct cfi_pri_intelext *cfip = cfi->cmdset_priv; + + resettime: timeo = jiffies + HZ; retry: - spin_lock(chip->mutex); + if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING)) { + /* + * OK. We have possibility for contension on the write/erase + * operations which are global to the real chip and not per + * partition. So let's fight it over in the partition which + * currently has authority on the operation. + * + * The rules are as follows: + * + * - any write operation must own shared->writing. + * + * - any erase operation must own _both_ shared->writing and + * shared->erasing. + * + * - contension arbitration is handled in the owner's context. + * + * The 'shared' struct can be read when its lock is taken. + * However any writes to it can only be made when the current + * owner's lock is also held. + */ + struct flchip_shared *shared = chip->priv; + struct flchip *contender; + spin_lock(&shared->lock); + contender = shared->writing; + if (contender && contender != chip) { + /* + * The engine to perform desired operation on this + * partition is already in use by someone else. + * Let's fight over it in the context of the chip + * currently using it. If it is possible to suspend, + * that other partition will do just that, otherwise + * it'll happily send us to sleep. In any case, when + * get_chip returns success we're clear to go ahead. + */ + int ret = spin_trylock(contender->mutex); + spin_unlock(&shared->lock); + if (!ret) + goto retry; + spin_unlock(chip->mutex); + ret = get_chip(map, contender, contender->start, mode); + spin_lock(chip->mutex); + if (ret) { + spin_unlock(contender->mutex); + return ret; + } + timeo = jiffies + HZ; + spin_lock(&shared->lock); + } + + /* We now own it */ + shared->writing = chip; + if (mode == FL_ERASING) + shared->erasing = chip; + if (contender && contender != chip) + spin_unlock(contender->mutex); + spin_unlock(&shared->lock); + } - /* Check that the chip's ready to talk to us. - * If it's in FL_ERASING state, suspend it and make it talk now. - */ switch (chip->state) { - case FL_READY: - case FL_POINT: - break; + case FL_STATUS: + for (;;) { + status = map_read(map, adr); + if (map_word_andequal(map, status, status_OK, status_OK)) + break; + + /* At this point we're fine with write operations + in other partitions as they don't conflict. */ + if (chip->priv && map_word_andequal(map, status, status_PWS, status_PWS)) + break; + if (time_after(jiffies, timeo)) { + printk(KERN_ERR "Waiting for chip to be ready timed out. Status %lx\n", + status.x[0]); + return -EIO; + } + spin_unlock(chip->mutex); + cfi_udelay(1); + spin_lock(chip->mutex); + /* Someone else might have been playing with it. */ + goto retry; + } + + case FL_READY: case FL_CFI_QUERY: case FL_JEDEC_QUERY: - cfi_write(map, CMD(0x70), cmd_addr); - chip->state = FL_STATUS; + return 0; + + case FL_ERASING: + if (!cfip || + !(cfip->FeatureSupport & 2) || + !(mode == FL_READY || mode == FL_POINT || + (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1)))) + goto sleep; + + + /* Erase suspend */ + map_write(map, CMD(0xB0), adr); + + /* If the flash has finished erasing, then 'erase suspend' + * appears to make some (28F320) flash devices switch to + * 'read' mode. Make sure that we switch to 'read status' + * mode so we get the right data. --rmk + */ + map_write(map, CMD(0x70), adr); + chip->oldstate = FL_ERASING; + chip->state = FL_ERASE_SUSPENDING; + chip->erase_suspended = 1; + for (;;) { + status = map_read(map, adr); + if (map_word_andequal(map, status, status_OK, status_OK)) + break; + + if (time_after(jiffies, timeo)) { + /* Urgh. Resume and pretend we weren't here. */ + map_write(map, CMD(0xd0), adr); + /* Make sure we're in 'read status' mode if it had finished */ + map_write(map, CMD(0x70), adr); + chip->state = FL_ERASING; + chip->oldstate = FL_READY; + printk(KERN_ERR "Chip not ready after erase " + "suspended: status = 0x%lx\n", status.x[0]); + return -EIO; + } - case FL_STATUS: - status = cfi_read(map, cmd_addr); - if ((status & status_OK) == status_OK) { - cfi_write(map, CMD(0xff), cmd_addr); - chip->state = FL_READY; - break; - } - - /* Urgh. Chip not yet ready to talk to us. */ - if (time_after(jiffies, timeo)) { spin_unlock(chip->mutex); - printk(KERN_ERR "waiting for chip to be ready timed out in read. WSM status = %llx\n", (__u64)status); - return -EIO; + cfi_udelay(1); + spin_lock(chip->mutex); + /* Nobody will touch it while it's in state FL_ERASE_SUSPENDING. + So we can just loop here. */ } + chip->state = FL_STATUS; + return 0; - /* Latency issues. Drop the lock, wait a while and retry */ - spin_unlock(chip->mutex); - cfi_udelay(1); - goto retry; + case FL_POINT: + /* Only if there's no operation suspended... */ + if (mode == FL_READY && chip->oldstate == FL_READY) + return 0; default: - /* Stick ourselves on a wait queue to be woken when - someone changes the status */ + sleep: set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(&chip->wq, &wait); spin_unlock(chip->mutex); schedule(); remove_wait_queue(&chip->wq, &wait); - timeo = jiffies + HZ; - goto retry; + spin_lock(chip->mutex); + goto resettime; + } +} + +static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr) +{ + struct cfi_private *cfi = map->fldrv_priv; + + if (chip->priv) { + struct flchip_shared *shared = chip->priv; + spin_lock(&shared->lock); + if (shared->writing == chip) { + /* We own the ability to write, but we're done */ + shared->writing = shared->erasing; + if (shared->writing && shared->writing != chip) { + /* give back ownership to who we loaned it from */ + struct flchip *loaner = shared->writing; + spin_lock(loaner->mutex); + spin_unlock(&shared->lock); + spin_unlock(chip->mutex); + put_chip(map, loaner, loaner->start); + spin_lock(chip->mutex); + spin_unlock(loaner->mutex); + } else { + if (chip->oldstate != FL_ERASING) { + shared->erasing = NULL; + if (chip->oldstate != FL_WRITING) + shared->writing = NULL; + } + spin_unlock(&shared->lock); + } + } else { + spin_unlock(&shared->lock); + } + } + + switch(chip->oldstate) { + case FL_ERASING: + chip->state = chip->oldstate; + /* What if one interleaved chip has finished and the + other hasn't? The old code would leave the finished + one in READY mode. That's bad, and caused -EROFS + errors to be returned from do_erase_oneblock because + that's the only bit it checked for at the time. + As the state machine appears to explicitly allow + sending the 0x70 (Read Status) command to an erasing + chip and expecting it to be ignored, that's what we + do. */ + map_write(map, CMD(0xd0), adr); + map_write(map, CMD(0x70), adr); + chip->oldstate = FL_READY; + chip->state = FL_ERASING; + break; + + case FL_READY: + case FL_STATUS: + case FL_JEDEC_QUERY: + /* We should really make set_vpp() count, rather than doing this */ + DISABLE_VPP(map); + break; + default: + printk(KERN_ERR "put_chip() called with oldstate %d!!\n", chip->oldstate); } + wake_up(&chip->wq); +} + +static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len) +{ + unsigned long cmd_addr; + struct cfi_private *cfi = map->fldrv_priv; + int ret = 0; + + adr += chip->start; + + /* Ensure cmd read/writes are aligned. */ + cmd_addr = adr & ~(map_bankwidth(map)-1); + + spin_lock(chip->mutex); + + ret = get_chip(map, chip, cmd_addr, FL_POINT); + + if (!ret) { + if (chip->state != FL_POINT && chip->state != FL_READY) + map_write(map, CMD(0xff), cmd_addr); - chip->state = FL_POINT; - chip->ref_point_counter++; + chip->state = FL_POINT; + chip->ref_point_counter++; + } spin_unlock(chip->mutex); - return 0; + + return ret; } -static int do_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf) + +static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -380,19 +724,17 @@ int chipnum; int ret = 0; - if (from + len > mtd->size) + if (!map->virt || (from + len > mtd->size)) return -EINVAL; - *mtdbuf = map->point(map, from, len); - if(*mtdbuf == NULL) - return -EINVAL; /* can not point this region */ + *mtdbuf = (void *)map->virt + from; *retlen = 0; /* Now lock the chip(s) to POINT state */ /* ofs: offset within the first chip that the first read should start */ chipnum = (from >> cfi->chipshift); - ofs = from - (chipnum << cfi->chipshift); + ofs = from - (chipnum << cfi->chipshift); while (len) { unsigned long thislen; @@ -418,14 +760,13 @@ return 0; } -static void do_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) +static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; unsigned long ofs; int chipnum; - map->unpoint(map, addr, from, len); /* Now unlock the chip(s) POINT state */ /* ofs: offset within the first chip that the first read should start */ @@ -446,13 +787,14 @@ thislen = len; spin_lock(chip->mutex); - if(chip->state == FL_POINT){ + if (chip->state == FL_POINT) { chip->ref_point_counter--; if(chip->ref_point_counter == 0) chip->state = FL_READY; } else - printk("Warning: unpoint called on non pointed region\n"); /* Should this give an error? */ - wake_up(&chip->wq); + printk(KERN_ERR "Warning: unpoint called on non pointed region\n"); /* Should this give an error? */ + + put_chip(map, chip, chip->start); spin_unlock(chip->mutex); len -= thislen; @@ -463,136 +805,32 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf) { - cfi_word status, status_OK; - unsigned long timeo; - DECLARE_WAITQUEUE(wait, current); - int suspended = 0; unsigned long cmd_addr; struct cfi_private *cfi = map->fldrv_priv; + int ret; adr += chip->start; /* Ensure cmd read/writes are aligned. */ - cmd_addr = adr & ~(CFIDEV_BUSWIDTH-1); + cmd_addr = adr & ~(map_bankwidth(map)-1); - /* Let's determine this according to the interleave only once */ - status_OK = CMD(0x80); - - timeo = jiffies + HZ; - retry: spin_lock(chip->mutex); - - /* Check that the chip's ready to talk to us. - * If it's in FL_ERASING state, suspend it and make it talk now. - */ - switch (chip->state) { - case FL_ERASING: - if (!cfi->cmdset_priv || - !(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2)) - goto sleep; /* We don't support erase suspend */ - - cfi_write (map, CMD(0xb0), cmd_addr); - /* If the flash has finished erasing, then 'erase suspend' - * appears to make some (28F320) flash devices switch to - * 'read' mode. Make sure that we switch to 'read status' - * mode so we get the right data. --rmk - */ - cfi_write(map, CMD(0x70), cmd_addr); - chip->oldstate = FL_ERASING; - chip->state = FL_ERASE_SUSPENDING; - // printk("Erase suspending at 0x%lx\n", cmd_addr); - for (;;) { - status = cfi_read(map, cmd_addr); - if ((status & status_OK) == status_OK) - break; - - if (time_after(jiffies, timeo)) { - /* Urgh */ - cfi_write(map, CMD(0xd0), cmd_addr); - /* make sure we're in 'read status' mode */ - cfi_write(map, CMD(0x70), cmd_addr); - chip->state = FL_ERASING; - spin_unlock(chip->mutex); - printk(KERN_ERR "Chip not ready after erase " - "suspended: status = 0x%llx\n", (__u64)status); - return -EIO; - } - - spin_unlock(chip->mutex); - cfi_udelay(1); - spin_lock(chip->mutex); - } - - suspended = 1; - cfi_write(map, CMD(0xff), cmd_addr); - chip->state = FL_READY; - break; - -#if 0 - case FL_WRITING: - /* Not quite yet */ -#endif - - case FL_READY: - case FL_POINT: - break; - - case FL_CFI_QUERY: - case FL_JEDEC_QUERY: - cfi_write(map, CMD(0x70), cmd_addr); - chip->state = FL_STATUS; - - case FL_STATUS: - status = cfi_read(map, cmd_addr); - if ((status & status_OK) == status_OK) { - cfi_write(map, CMD(0xff), cmd_addr); - chip->state = FL_READY; - break; - } - - /* Urgh. Chip not yet ready to talk to us. */ - if (time_after(jiffies, timeo)) { - spin_unlock(chip->mutex); - printk(KERN_ERR "waiting for chip to be ready timed out in read. WSM status = %llx\n", (__u64)status); - return -EIO; - } - - /* Latency issues. Drop the lock, wait a while and retry */ - spin_unlock(chip->mutex); - cfi_udelay(1); - goto retry; - - default: - sleep: - /* Stick ourselves on a wait queue to be woken when - someone changes the status */ - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&chip->wq, &wait); + ret = get_chip(map, chip, cmd_addr, FL_READY); + if (ret) { spin_unlock(chip->mutex); - schedule(); - remove_wait_queue(&chip->wq, &wait); - timeo = jiffies + HZ; - goto retry; + return ret; } - map->copy_from(map, buf, adr, len); + if (chip->state != FL_POINT && chip->state != FL_READY) { + map_write(map, CMD(0xff), cmd_addr); - if (suspended) { - chip->state = chip->oldstate; - /* What if one interleaved chip has finished and the - other hasn't? The old code would leave the finished - one in READY mode. That's bad, and caused -EROFS - errors to be returned from do_erase_oneblock because - that's the only bit it checked for at the time. - As the state machine appears to explicitly allow - sending the 0x70 (Read Status) command to an erasing - chip and expecting it to be ignored, that's what we - do. */ - cfi_write(map, CMD(0xd0), cmd_addr); - cfi_write(map, CMD(0x70), cmd_addr); + chip->state = FL_READY; } - wake_up(&chip->wq); + map_copy_from(map, buf, adr, len); + + put_chip(map, chip, cmd_addr); + spin_unlock(chip->mutex); return 0; } @@ -636,74 +874,57 @@ return ret; } +#if 0 static int cfi_intelext_read_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, int base_offst, int reg_sz) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; - struct cfi_pri_intelext *extp=cfi->cmdset_priv; - int ofs_factor = cfi->interleave * cfi->device_type; - int count=len; + struct cfi_pri_intelext *extp = cfi->cmdset_priv; struct flchip *chip; - int chip_num,offst; - unsigned long timeo; - DECLARE_WAITQUEUE(wait, current); + int ofs_factor = cfi->interleave * cfi->device_type; + int count = len; + int chip_num, offst; + int ret; - chip=0; + chip_num = ((unsigned int)from/reg_sz); + offst = from - (reg_sz*chip_num)+base_offst; + + while (count) { /* Calculate which chip & protection register offset we need */ - chip_num=((unsigned int)from/reg_sz); - offst=from-(reg_sz*chip_num)+base_offst; - while(count){ - - if(chip_num>=cfi->numchips) + if (chip_num >= cfi->numchips) goto out; - /* Make sure that the chip is in the right state */ - - timeo = jiffies + HZ; - chip=&cfi->chips[chip_num]; - retry: - spin_lock(chip->mutex); - - switch (chip->state) { - case FL_READY: - case FL_STATUS: - case FL_CFI_QUERY: - case FL_JEDEC_QUERY: - break; + chip = &cfi->chips[chip_num]; - default: - /* Stick ourselves on a wait queue to be woken when - someone changes the status */ - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&chip->wq, &wait); + spin_lock(chip->mutex); + ret = get_chip(map, chip, chip->start, FL_JEDEC_QUERY); + if (ret) { spin_unlock(chip->mutex); - schedule(); - remove_wait_queue(&chip->wq, &wait); - timeo = jiffies + HZ; - goto retry; + return (len-count)?:ret; } - - /* Now read the data required from this flash */ - - cfi_send_gen_cmd(0x90, 0x55,chip->start, map, cfi, cfi->device_type, NULL); - while(count && ((offst-base_offst)read8(map,(chip->start+((extp->ProtRegAddr+1)*ofs_factor)+offst)); + + if (chip->state != FL_JEDEC_QUERY) { + map_write(map, CMD(0x90), chip->start); + chip->state = FL_JEDEC_QUERY; + } + + while (count && ((offst-base_offst) < reg_sz)) { + *buf = map_read8(map,(chip->start+((extp->ProtRegAddr+1)*ofs_factor)+offst)); buf++; offst++; count--; } - - chip->state=FL_CFI_QUERY; + + put_chip(map, chip, chip->start); spin_unlock(chip->mutex); + /* Move on to the next chip */ chip_num++; - offst=base_offst; - + offst = base_offst; } out: - wake_up(&chip->wq); return len-count; } @@ -715,7 +936,7 @@ int base_offst,reg_sz; /* Check that we actually have some protection registers */ - if(!(extp->FeatureSupport&64)){ + if(!extp || !(extp->FeatureSupport&64)){ printk(KERN_WARNING "%s: This flash device has no protection data to read!\n",map->name); return 0; } @@ -734,7 +955,7 @@ int base_offst,reg_sz; /* Check that we actually have some protection registers */ - if(!(extp->FeatureSupport&64)){ + if(!extp || !(extp->FeatureSupport&64)){ printk(KERN_WARNING "%s: This flash device has no protection data to read!\n",map->name); return 0; } @@ -744,116 +965,34 @@ return cfi_intelext_read_prot_reg(mtd, from, len, retlen, buf, base_offst, reg_sz); } +#endif - -static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, cfi_word datum) +static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, map_word datum) { struct cfi_private *cfi = map->fldrv_priv; - struct cfi_pri_intelext *extp = cfi->cmdset_priv; - cfi_word status, status_OK; + map_word status, status_OK; unsigned long timeo; - DECLARE_WAITQUEUE(wait, current); - int z, suspended=0, ret=0; + int z, ret=0; adr += chip->start; /* Let's determine this according to the interleave only once */ status_OK = CMD(0x80); - timeo = jiffies + HZ; - retry: spin_lock(chip->mutex); - - /* Check that the chip's ready to talk to us. - * Later, we can actually think about interrupting it - * if it's in FL_ERASING state. - * Not just yet, though. - */ - switch (chip->state) { - case FL_READY: - break; - - case FL_CFI_QUERY: - case FL_JEDEC_QUERY: - cfi_write(map, CMD(0x70), adr); - chip->state = FL_STATUS; - - case FL_STATUS: - status = cfi_read(map, adr); - if ((status & status_OK) == status_OK) - break; - - /* Urgh. Chip not yet ready to talk to us. */ - if (time_after(jiffies, timeo)) { - spin_unlock(chip->mutex); - printk(KERN_ERR "waiting for chip to be ready timed out in read\n"); - return -EIO; - } - - /* Latency issues. Drop the lock, wait a while and retry */ - spin_unlock(chip->mutex); - cfi_udelay(1); - goto retry; - - case FL_ERASING: - if (!extp || - !((extp->FeatureSupport & 2) && (extp->SuspendCmdSupport & 1))) - goto sleep; /* We don't support erase suspend */ - - cfi_write (map, CMD(0xb0), adr); - - /* If the flash has finished erasing, then 'erase suspend' - * appears to make some (28F320) flash devices switch to - * 'read' mode. Make sure that we switch to 'read status' - * mode so we get the right data. --rmk - */ - cfi_write(map, CMD(0x70), adr); - chip->oldstate = FL_ERASING; - chip->state = FL_ERASE_SUSPENDING; - for (;;) { - status = cfi_read(map, adr); - if ((status & status_OK) == status_OK) - break; - - if (time_after(jiffies, timeo)) { - /* Urgh */ - cfi_write(map, CMD(0xd0), adr); - /* make sure we're in 'read status' mode */ - cfi_write(map, CMD(0x70), adr); - chip->state = FL_ERASING; - spin_unlock(chip->mutex); - printk(KERN_ERR "Chip not ready after erase " - "suspended: status = 0x%x\n", status); - return -EIO; - } - - spin_unlock(chip->mutex); - cfi_udelay(1); - spin_lock(chip->mutex); - } - suspended = 1; - chip->state = FL_STATUS; - break; - - default: - sleep: - /* Stick ourselves on a wait queue to be woken when - someone changes the status */ - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&chip->wq, &wait); + ret = get_chip(map, chip, adr, FL_WRITING); + if (ret) { spin_unlock(chip->mutex); - schedule(); - remove_wait_queue(&chip->wq, &wait); - timeo = jiffies + HZ; - goto retry; + return ret; } ENABLE_VPP(map); - cfi_write(map, CMD(0x40), adr); - cfi_write(map, datum, adr); + map_write(map, CMD(0x40), adr); + map_write(map, datum, adr); chip->state = FL_WRITING; spin_unlock(chip->mutex); + INVALIDATE_CACHED_RANGE(map, adr, map_bankwidth(map)); cfi_udelay(chip->word_write_time); spin_lock(chip->mutex); @@ -862,6 +1001,8 @@ for (;;) { if (chip->state != FL_WRITING) { /* Someone's suspended the write. Sleep */ + DECLARE_WAITQUEUE(wait, current); + set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(&chip->wq, &wait); spin_unlock(chip->mutex); @@ -872,14 +1013,13 @@ continue; } - status = cfi_read(map, adr); - if ((status & status_OK) == status_OK) + status = map_read(map, adr); + if (map_word_andequal(map, status, status_OK, status_OK)) break; /* OK Still waiting */ if (time_after(jiffies, timeo)) { chip->state = FL_STATUS; - DISABLE_VPP(map); printk(KERN_ERR "waiting for chip to be ready timed out in word write\n"); ret = -EIO; goto out; @@ -901,34 +1041,19 @@ /* Done and happy. */ chip->state = FL_STATUS; + /* check for lock bit */ - if (status & CMD(0x02)) { + if (map_word_bitsset(map, status, CMD(0x02))) { /* clear status */ - cfi_write(map, CMD(0x50), adr); + map_write(map, CMD(0x50), adr); /* put back into read status register mode */ - cfi_write(map, CMD(0x70), adr); + map_write(map, CMD(0x70), adr); ret = -EROFS; - goto out; } out: - if (suspended) { - chip->state = chip->oldstate; - /* What if one interleaved chip has finished and the - other hasn't? The old code would leave the finished - one in READY mode. That's bad, and caused -EROFS - errors to be returned from do_erase_oneblock because - that's the only bit it checked for at the time. - As the state machine appears to explicitly allow - sending the 0x70 (Read Status) command to an erasing - chip and expecting it to be ignored, that's what we - do. */ - cfi_write(map, CMD(0xd0), adr); - cfi_write(map, CMD(0x70), adr); - } else - DISABLE_VPP(map); /* must not clear the VPP if there is a suspended erase to be resumed */ - - wake_up(&chip->wq); + put_chip(map, chip, adr); spin_unlock(chip->mutex); + return ret; } @@ -949,35 +1074,22 @@ ofs = to - (chipnum << cfi->chipshift); /* If it's not bus-aligned, do the first byte write */ - if (ofs & (CFIDEV_BUSWIDTH-1)) { - unsigned long bus_ofs = ofs & ~(CFIDEV_BUSWIDTH-1); + if (ofs & (map_bankwidth(map)-1)) { + unsigned long bus_ofs = ofs & ~(map_bankwidth(map)-1); int gap = ofs - bus_ofs; - int i = 0, n = 0; - u_char tmp_buf[8]; - cfi_word datum; - - while (gap--) - tmp_buf[i++] = 0xff; - while (len && i < CFIDEV_BUSWIDTH) - tmp_buf[i++] = buf[n++], len--; - while (i < CFIDEV_BUSWIDTH) - tmp_buf[i++] = 0xff; - - if (cfi_buswidth_is_2()) { - datum = *(__u16*)tmp_buf; - } else if (cfi_buswidth_is_4()) { - datum = *(__u32*)tmp_buf; - } else if (cfi_buswidth_is_8()) { - datum = *(__u64*)tmp_buf; - } else { - return -EINVAL; /* should never happen, but be safe */ - } + int n; + map_word datum; + + n = min_t(int, len, map_bankwidth(map)-gap); + datum = map_word_ff(map); + datum = map_word_load_partial(map, datum, buf, gap, n); ret = do_write_oneword(map, &cfi->chips[chipnum], bus_ofs, datum); if (ret) return ret; - + + len -= n; ofs += n; buf += n; (*retlen) += n; @@ -990,30 +1102,18 @@ } } - while(len >= CFIDEV_BUSWIDTH) { - cfi_word datum; - - if (cfi_buswidth_is_1()) { - datum = *(__u8*)buf; - } else if (cfi_buswidth_is_2()) { - datum = *(__u16*)buf; - } else if (cfi_buswidth_is_4()) { - datum = *(__u32*)buf; - } else if (cfi_buswidth_is_8()) { - datum = *(__u64*)buf; - } else { - return -EINVAL; - } + while(len >= map_bankwidth(map)) { + map_word datum = map_word_load(map, buf); ret = do_write_oneword(map, &cfi->chips[chipnum], ofs, datum); if (ret) return ret; - ofs += CFIDEV_BUSWIDTH; - buf += CFIDEV_BUSWIDTH; - (*retlen) += CFIDEV_BUSWIDTH; - len -= CFIDEV_BUSWIDTH; + ofs += map_bankwidth(map); + buf += map_bankwidth(map); + (*retlen) += map_bankwidth(map); + len -= map_bankwidth(map); if (ofs >> cfi->chipshift) { chipnum ++; @@ -1023,32 +1123,18 @@ } } - if (len & (CFIDEV_BUSWIDTH-1)) { - int i = 0, n = 0; - u_char tmp_buf[8]; - cfi_word datum; - - while (len--) - tmp_buf[i++] = buf[n++]; - while (i < CFIDEV_BUSWIDTH) - tmp_buf[i++] = 0xff; - - if (cfi_buswidth_is_2()) { - datum = *(__u16*)tmp_buf; - } else if (cfi_buswidth_is_4()) { - datum = *(__u32*)tmp_buf; - } else if (cfi_buswidth_is_8()) { - datum = *(__u64*)tmp_buf; - } else { - return -EINVAL; /* should never happen, but be safe */ - } + if (len & (map_bankwidth(map)-1)) { + map_word datum; + + datum = map_word_ff(map); + datum = map_word_load_partial(map, datum, buf, 0, len); ret = do_write_oneword(map, &cfi->chips[chipnum], ofs, datum); if (ret) return ret; - (*retlen) += n; + (*retlen) += len; } return 0; @@ -1059,122 +1145,46 @@ unsigned long adr, const u_char *buf, int len) { struct cfi_private *cfi = map->fldrv_priv; - struct cfi_pri_intelext *extp = cfi->cmdset_priv; - cfi_word status, status_OK; + map_word status, status_OK; unsigned long cmd_adr, timeo; - DECLARE_WAITQUEUE(wait, current); - int wbufsize, z, suspended=0, ret=0; + int wbufsize, z, ret=0, bytes, words; - wbufsize = CFIDEV_INTERLEAVE << cfi->cfiq->MaxBufWriteSize; + wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; adr += chip->start; cmd_adr = adr & ~(wbufsize-1); /* Let's determine this according to the interleave only once */ status_OK = CMD(0x80); - timeo = jiffies + HZ; - retry: spin_lock(chip->mutex); - - /* Check that the chip's ready to talk to us. - * Later, we can actually think about interrupting it - * if it's in FL_ERASING state. - * Not just yet, though. - */ - switch (chip->state) { - case FL_READY: - case FL_CFI_QUERY: - case FL_JEDEC_QUERY: - cfi_write(map, CMD(0x70), cmd_adr); - chip->state = FL_STATUS; - - case FL_STATUS: - status = cfi_read(map, cmd_adr); - if ((status & status_OK) == status_OK) - break; - /* Urgh. Chip not yet ready to talk to us. */ - if (time_after(jiffies, timeo)) { - spin_unlock(chip->mutex); - printk(KERN_ERR "waiting for chip to be ready timed out in buffer write\n"); - return -EIO; - } - - /* Latency issues. Drop the lock, wait a while and retry */ - spin_unlock(chip->mutex); - cfi_udelay(1); - goto retry; - - case FL_ERASING: - if (!extp || - !((extp->FeatureSupport & 2) && (extp->SuspendCmdSupport & 1))) - goto sleep; /* We don't support erase suspend */ - - cfi_write (map, CMD(0xb0), adr); - - /* If the flash has finished erasing, then 'erase suspend' - * appears to make some (28F320) flash devices switch to - * 'read' mode. Make sure that we switch to 'read status' - * mode so we get the right data. --rmk - */ - cfi_write(map, CMD(0x70), adr); - chip->oldstate = FL_ERASING; - chip->state = FL_ERASE_SUSPENDING; - for (;;) { - status = cfi_read(map, adr); - if ((status & status_OK) == status_OK) - break; - - if (time_after(jiffies, timeo)) { - /* Urgh */ - cfi_write(map, CMD(0xd0), adr); - /* make sure we're in 'read status' mode */ - cfi_write(map, CMD(0x70), adr); - chip->state = FL_ERASING; - spin_unlock(chip->mutex); - printk(KERN_ERR "Chip not ready after erase " - "suspended: status = 0x%x\n", status); - return -EIO; - } - - spin_unlock(chip->mutex); - cfi_udelay(1); - spin_lock(chip->mutex); - } - suspended = 1; - chip->state = FL_STATUS; - break; - - default: - sleep: - /* Stick ourselves on a wait queue to be woken when - someone changes the status */ - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&chip->wq, &wait); + ret = get_chip(map, chip, cmd_adr, FL_WRITING); + if (ret) { spin_unlock(chip->mutex); - schedule(); - remove_wait_queue(&chip->wq, &wait); - timeo = jiffies + HZ; - goto retry; + return ret; } - /* We know we're now in FL_STATUS mode, and 'status' is current */ + /* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set [...], the device will not accept any more Write to Buffer commands". So we must check here and reset those bits if they're set. Otherwise we're just pissing in the wind */ - if (status & CMD(0x30)) { - printk(KERN_WARNING "SR.4 or SR.5 bits set in buffer write (status %x). Clearing.\n", status); - cfi_write(map, CMD(0x50), cmd_adr); - cfi_write(map, CMD(0x70), cmd_adr); + if (chip->state != FL_STATUS) + map_write(map, CMD(0x70), cmd_adr); + status = map_read(map, cmd_adr); + if (map_word_bitsset(map, status, CMD(0x30))) { + printk(KERN_WARNING "SR.4 or SR.5 bits set in buffer write (status %lx). Clearing.\n", status.x[0]); + map_write(map, CMD(0x50), cmd_adr); + map_write(map, CMD(0x70), cmd_adr); } + ENABLE_VPP(map); chip->state = FL_WRITING_TO_BUFFER; z = 0; for (;;) { - cfi_write(map, CMD(0xe8), cmd_adr); + map_write(map, CMD(0xe8), cmd_adr); - status = cfi_read(map, cmd_adr); - if ((status & status_OK) == status_OK) + status = map_read(map, cmd_adr); + if (map_word_andequal(map, status, status_OK, status_OK)) break; spin_unlock(chip->mutex); @@ -1183,42 +1193,49 @@ if (++z > 20) { /* Argh. Not ready for write to buffer */ - cfi_write(map, CMD(0x70), cmd_adr); + map_word Xstatus; + map_write(map, CMD(0x70), cmd_adr); chip->state = FL_STATUS; - DISABLE_VPP(map); - printk(KERN_ERR "Chip not ready for buffer write. Xstatus = %llx, status = %llx\n", (__u64)status, (__u64)cfi_read(map, cmd_adr)); + Xstatus = map_read(map, cmd_adr); /* Odd. Clear status bits */ - cfi_write(map, CMD(0x50), cmd_adr); - cfi_write(map, CMD(0x70), cmd_adr); + map_write(map, CMD(0x50), cmd_adr); + map_write(map, CMD(0x70), cmd_adr); + printk(KERN_ERR "Chip not ready for buffer write. status = %lx, Xstatus = %lx\n", + status.x[0], Xstatus.x[0]); ret = -EIO; goto out; } } /* Write length of data to come */ - cfi_write(map, CMD(len/CFIDEV_BUSWIDTH-1), cmd_adr ); + bytes = len & (map_bankwidth(map)-1); + words = len / map_bankwidth(map); + map_write(map, CMD(words - !bytes), cmd_adr ); /* Write data */ - for (z = 0; z < len; z += CFIDEV_BUSWIDTH) { - if (cfi_buswidth_is_1()) { - map->write8 (map, *((__u8*)buf)++, adr+z); - } else if (cfi_buswidth_is_2()) { - map->write16 (map, *((__u16*)buf)++, adr+z); - } else if (cfi_buswidth_is_4()) { - map->write32 (map, *((__u32*)buf)++, adr+z); - } else if (cfi_buswidth_is_8()) { - map->write64 (map, *((__u64*)buf)++, adr+z); - } else { - DISABLE_VPP(map); - ret = -EINVAL; - goto out; - } + z = 0; + while(z < words * map_bankwidth(map)) { + map_word datum = map_word_load(map, buf); + map_write(map, datum, adr+z); + + z += map_bankwidth(map); + buf += map_bankwidth(map); + } + + if (bytes) { + map_word datum; + + datum = map_word_ff(map); + datum = map_word_load_partial(map, datum, buf, 0, bytes); + map_write(map, datum, adr+z); } + /* GO GO GO */ - cfi_write(map, CMD(0xd0), cmd_adr); + map_write(map, CMD(0xd0), cmd_adr); chip->state = FL_WRITING; spin_unlock(chip->mutex); + INVALIDATE_CACHED_RANGE(map, adr, len); cfi_udelay(chip->buffer_write_time); spin_lock(chip->mutex); @@ -1227,6 +1244,7 @@ for (;;) { if (chip->state != FL_WRITING) { /* Someone's suspended the write. Sleep */ + DECLARE_WAITQUEUE(wait, current); set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(&chip->wq, &wait); spin_unlock(chip->mutex); @@ -1237,14 +1255,13 @@ continue; } - status = cfi_read(map, cmd_adr); - if ((status & status_OK) == status_OK) + status = map_read(map, cmd_adr); + if (map_word_andequal(map, status, status_OK, status_OK)) break; /* OK Still waiting */ if (time_after(jiffies, timeo)) { chip->state = FL_STATUS; - DISABLE_VPP(map); printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n"); ret = -EIO; goto out; @@ -1265,34 +1282,19 @@ chip->buffer_write_time++; /* Done and happy. */ - chip->state = FL_STATUS; + chip->state = FL_STATUS; + /* check for lock bit */ - if (status & CMD(0x02)) { + if (map_word_bitsset(map, status, CMD(0x02))) { /* clear status */ - cfi_write(map, CMD(0x50), cmd_adr); + map_write(map, CMD(0x50), cmd_adr); /* put back into read status register mode */ - cfi_write(map, CMD(0x70), adr); + map_write(map, CMD(0x70), adr); ret = -EROFS; - goto out; } - out: - if (suspended) { - chip->state = chip->oldstate; - /* What if one interleaved chip has finished and the - other hasn't? The old code would leave the finished - one in READY mode. That's bad, and caused -EROFS - errors to be returned from do_erase_oneblock because - that's the only bit it checked for at the time. - As the state machine appears to explicitly allow - sending the 0x70 (Read Status) command to an erasing - chip and expecting it to be ignored, that's what we - do. */ - cfi_write(map, CMD(0xd0), adr); - cfi_write(map, CMD(0x70), adr); - } else - DISABLE_VPP(map); /* must not clear the VPP if there is a suspended erase to be resumed */ - wake_up(&chip->wq); + out: + put_chip(map, chip, cmd_adr); spin_unlock(chip->mutex); return ret; } @@ -1302,7 +1304,7 @@ { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; - int wbufsize = CFIDEV_INTERLEAVE << cfi->cfiq->MaxBufWriteSize; + int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; int ret = 0; int chipnum; unsigned long ofs; @@ -1315,8 +1317,8 @@ ofs = to - (chipnum << cfi->chipshift); /* If it's not bus-aligned, do the first word write */ - if (ofs & (CFIDEV_BUSWIDTH-1)) { - size_t local_len = (-ofs)&(CFIDEV_BUSWIDTH-1); + if (ofs & (map_bankwidth(map)-1)) { + size_t local_len = (-ofs)&(map_bankwidth(map)-1); if (local_len > len) local_len = len; ret = cfi_intelext_write_words(mtd, to, local_len, @@ -1335,13 +1337,12 @@ } } - /* Write buffer is worth it only if more than one word to write... */ - while(len > CFIDEV_BUSWIDTH) { + while(len) { /* We must not cross write block boundaries */ int size = wbufsize - (ofs & (wbufsize-1)); if (size > len) - size = len & ~(CFIDEV_BUSWIDTH-1); + size = len; ret = do_write_buffer(map, &cfi->chips[chipnum], ofs, buf, size); if (ret) @@ -1359,116 +1360,14 @@ return 0; } } - - /* ... and write the remaining bytes */ - if (len > 0) { - size_t local_retlen; - ret = cfi_intelext_write_words(mtd, ofs + (chipnum << cfi->chipshift), - len, &local_retlen, buf); - if (ret) - return ret; - (*retlen) += local_retlen; - } - - return 0; -} - -typedef int (*varsize_frob_t)(struct map_info *map, struct flchip *chip, - unsigned long adr, void *thunk); - -static int cfi_intelext_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob, - loff_t ofs, size_t len, void *thunk) -{ - struct map_info *map = mtd->priv; - struct cfi_private *cfi = map->fldrv_priv; - unsigned long adr; - int chipnum, ret = 0; - int i, first; - struct mtd_erase_region_info *regions = mtd->eraseregions; - - if (ofs > mtd->size) - return -EINVAL; - - if ((len + ofs) > mtd->size) - return -EINVAL; - - /* Check that both start and end of the requested erase are - * aligned with the erasesize at the appropriate addresses. - */ - - i = 0; - - /* Skip all erase regions which are ended before the start of - the requested erase. Actually, to save on the calculations, - we skip to the first erase region which starts after the - start of the requested erase, and then go back one. - */ - - while (i < mtd->numeraseregions && ofs >= regions[i].offset) - i++; - i--; - - /* OK, now i is pointing at the erase region in which this - erase request starts. Check the start of the requested - erase range is aligned with the erase size which is in - effect here. - */ - - if (ofs & (regions[i].erasesize-1)) - return -EINVAL; - - /* Remember the erase region we start on */ - first = i; - - /* Next, check that the end of the requested erase is aligned - * with the erase region at that address. - */ - - while (inumeraseregions && (ofs + len) >= regions[i].offset) - i++; - - /* As before, drop back one to point at the region in which - the address actually falls - */ - i--; - - if ((ofs + len) & (regions[i].erasesize-1)) - return -EINVAL; - - chipnum = ofs >> cfi->chipshift; - adr = ofs - (chipnum << cfi->chipshift); - - i=first; - - while(len) { - ret = (*frob)(map, &cfi->chips[chipnum], adr, thunk); - - if (ret) - return ret; - - adr += regions[i].erasesize; - len -= regions[i].erasesize; - - if (adr % (1<< cfi->chipshift) == ((regions[i].offset + (regions[i].erasesize * regions[i].numblocks)) %( 1<< cfi->chipshift))) - i++; - - if (adr >> cfi->chipshift) { - adr = 0; - chipnum++; - - if (chipnum >= cfi->numchips) - break; - } - } - return 0; } - -static int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, void *thunk) +static int do_erase_oneblock(struct map_info *map, struct flchip *chip, + unsigned long adr, int len, void *thunk) { struct cfi_private *cfi = map->fldrv_priv; - cfi_word status, status_OK; + map_word status, status_OK; unsigned long timeo; int retries = 3; DECLARE_WAITQUEUE(wait, current); @@ -1479,60 +1378,27 @@ /* Let's determine this according to the interleave only once */ status_OK = CMD(0x80); - timeo = jiffies + HZ; -retry: + retry: spin_lock(chip->mutex); - - /* Check that the chip's ready to talk to us. */ - switch (chip->state) { - case FL_CFI_QUERY: - case FL_JEDEC_QUERY: - case FL_READY: - cfi_write(map, CMD(0x70), adr); - chip->state = FL_STATUS; - - case FL_STATUS: - status = cfi_read(map, adr); - if ((status & status_OK) == status_OK) - break; - - /* Urgh. Chip not yet ready to talk to us. */ - if (time_after(jiffies, timeo)) { - spin_unlock(chip->mutex); - printk(KERN_ERR "waiting for chip to be ready timed out in erase\n"); - return -EIO; - } - - /* Latency issues. Drop the lock, wait a while and retry */ - spin_unlock(chip->mutex); - cfi_udelay(1); - goto retry; - - default: - /* Stick ourselves on a wait queue to be woken when - someone changes the status */ - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&chip->wq, &wait); + ret = get_chip(map, chip, adr, FL_ERASING); + if (ret) { spin_unlock(chip->mutex); - schedule(); - remove_wait_queue(&chip->wq, &wait); - timeo = jiffies + HZ; - goto retry; + return ret; } ENABLE_VPP(map); /* Clear the status register first */ - cfi_write(map, CMD(0x50), adr); + map_write(map, CMD(0x50), adr); /* Now erase */ - cfi_write(map, CMD(0x20), adr); - cfi_write(map, CMD(0xD0), adr); + map_write(map, CMD(0x20), adr); + map_write(map, CMD(0xD0), adr); chip->state = FL_ERASING; - chip->oldstate = 0; + chip->erase_suspended = 0; spin_unlock(chip->mutex); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((chip->erase_time*HZ)/(2*1000)); + INVALIDATE_CACHED_RANGE(map, adr, len); + msleep(chip->erase_time / 2); spin_lock(chip->mutex); /* FIXME. Use a timer to check this, and return immediately. */ @@ -1550,29 +1416,30 @@ spin_lock(chip->mutex); continue; } - if (chip->oldstate) { + if (chip->erase_suspended) { /* This erase was suspended and resumed. Adjust the timeout */ timeo = jiffies + (HZ*20); /* FIXME */ - chip->oldstate = 0; + chip->erase_suspended = 0; } - status = cfi_read(map, adr); - if ((status & status_OK) == status_OK) + status = map_read(map, adr); + if (map_word_andequal(map, status, status_OK, status_OK)) break; /* OK Still waiting */ if (time_after(jiffies, timeo)) { - cfi_write(map, CMD(0x70), adr); + map_word Xstatus; + map_write(map, CMD(0x70), adr); chip->state = FL_STATUS; - printk(KERN_ERR "waiting for erase at %08lx to complete timed out. Xstatus = %llx, status = %llx.\n", - adr, (__u64)status, (__u64)cfi_read(map, adr)); + Xstatus = map_read(map, adr); /* Clear status bits */ - cfi_write(map, CMD(0x50), adr); - cfi_write(map, CMD(0x70), adr); - DISABLE_VPP(map); - spin_unlock(chip->mutex); - return -EIO; + map_write(map, CMD(0x50), adr); + map_write(map, CMD(0x70), adr); + printk(KERN_ERR "waiting for erase at %08lx to complete timed out. status = %lx, Xstatus = %lx.\n", + adr, status.x[0], Xstatus.x[0]); + ret = -EIO; + goto out; } /* Latency issues. Drop the lock, wait a while and retry */ @@ -1581,53 +1448,58 @@ schedule_timeout(1); spin_lock(chip->mutex); } - - DISABLE_VPP(map); - ret = 0; /* We've broken this before. It doesn't hurt to be safe */ - cfi_write(map, CMD(0x70), adr); + map_write(map, CMD(0x70), adr); chip->state = FL_STATUS; - status = cfi_read(map, adr); + status = map_read(map, adr); /* check for lock bit */ - if (status & CMD(0x3a)) { - unsigned char chipstatus = status; - if (status != CMD(status & 0xff)) { - int i; - for (i = 1; i> (cfi->device_type * 8); + if (map_word_bitsset(map, status, CMD(0x3a))) { + unsigned char chipstatus; + + /* Reset the error bits */ + map_write(map, CMD(0x50), adr); + map_write(map, CMD(0x70), adr); + + chipstatus = status.x[0]; + if (!map_word_equal(map, status, CMD(chipstatus))) { + int i, w; + for (w=0; w> (cfi->device_type * 8); + } } - printk(KERN_WARNING "Status is not identical for all chips: 0x%llx. Merging to give 0x%02x\n", (__u64)status, chipstatus); + printk(KERN_WARNING "Status is not identical for all chips: 0x%lx. Merging to give 0x%02x\n", + status.x[0], chipstatus); } - /* Reset the error bits */ - cfi_write(map, CMD(0x50), adr); - cfi_write(map, CMD(0x70), adr); - + if ((chipstatus & 0x30) == 0x30) { - printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%llx\n", (__u64)status); + printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus); ret = -EIO; } else if (chipstatus & 0x02) { /* Protection bit set */ ret = -EROFS; } else if (chipstatus & 0x8) { /* Voltage */ - printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%llx\n", (__u64)status); + printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%x\n", chipstatus); ret = -EIO; } else if (chipstatus & 0x20) { if (retries--) { - printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%llx. Retrying...\n", adr, (__u64)status); + printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x. Retrying...\n", adr, chipstatus); timeo = jiffies + HZ; - chip->state = FL_STATUS; + put_chip(map, chip, adr); spin_unlock(chip->mutex); goto retry; } - printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%llx\n", adr, (__u64)status); + printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x\n", adr, chipstatus); ret = -EIO; } + } else { + ret = 0; } - wake_up(&chip->wq); + out: put_chip(map, chip, adr); spin_unlock(chip->mutex); return ret; } @@ -1640,13 +1512,12 @@ ofs = instr->addr; len = instr->len; - ret = cfi_intelext_varsize_frob(mtd, do_erase_oneblock, ofs, len, 0); + ret = cfi_varsize_frob(mtd, do_erase_oneblock, ofs, len, NULL); if (ret) return ret; instr->state = MTD_ERASE_DONE; - if (instr->callback) - instr->callback(instr); + mtd_erase_callback(instr); return 0; } @@ -1658,39 +1529,22 @@ int i; struct flchip *chip; int ret = 0; - DECLARE_WAITQUEUE(wait, current); for (i=0; !ret && inumchips; i++) { chip = &cfi->chips[i]; - retry: spin_lock(chip->mutex); + ret = get_chip(map, chip, chip->start, FL_SYNCING); - switch(chip->state) { - case FL_READY: - case FL_STATUS: - case FL_CFI_QUERY: - case FL_JEDEC_QUERY: + if (!ret) { chip->oldstate = chip->state; chip->state = FL_SYNCING; /* No need to wake_up() on this state change - * as the whole point is that nobody can do anything * with the chip now anyway. */ - case FL_SYNCING: - spin_unlock(chip->mutex); - break; - - default: - /* Not an idle state */ - add_wait_queue(&chip->wq, &wait); - - spin_unlock(chip->mutex); - schedule(); - remove_wait_queue(&chip->wq, &wait); - - goto retry; } + spin_unlock(chip->mutex); } /* Unlock the chips again */ @@ -1709,16 +1563,17 @@ } #ifdef DEBUG_LOCK_BITS -static int do_printlockstatus_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, void *thunk) +static int do_printlockstatus_oneblock(struct map_info *map, struct flchip *chip, + unsigned long adr, int len, void *thunk) { struct cfi_private *cfi = map->fldrv_priv; - int ofs_factor = cfi->interleave * cfi->device_type; + int status, ofs_factor = cfi->interleave * cfi->device_type; cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); + chip->state = FL_JEDEC_QUERY; + status = cfi_read_query(map, adr+(2*ofs_factor)); printk(KERN_DEBUG "block status register for 0x%08lx is %x\n", - adr, cfi_read_query(map, adr+(2*ofs_factor))); - cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); - + adr, status); return 0; } #endif @@ -1726,67 +1581,34 @@ #define DO_XXLOCK_ONEBLOCK_LOCK ((void *) 1) #define DO_XXLOCK_ONEBLOCK_UNLOCK ((void *) 2) -static int do_xxlock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, void *thunk) +static int do_xxlock_oneblock(struct map_info *map, struct flchip *chip, + unsigned long adr, int len, void *thunk) { struct cfi_private *cfi = map->fldrv_priv; - cfi_word status, status_OK; + map_word status, status_OK; unsigned long timeo = jiffies + HZ; - DECLARE_WAITQUEUE(wait, current); + int ret; adr += chip->start; /* Let's determine this according to the interleave only once */ status_OK = CMD(0x80); - timeo = jiffies + HZ; -retry: spin_lock(chip->mutex); - - /* Check that the chip's ready to talk to us. */ - switch (chip->state) { - case FL_CFI_QUERY: - case FL_JEDEC_QUERY: - case FL_READY: - cfi_write(map, CMD(0x70), adr); - chip->state = FL_STATUS; - - case FL_STATUS: - status = cfi_read(map, adr); - if ((status & status_OK) == status_OK) - break; - - /* Urgh. Chip not yet ready to talk to us. */ - if (time_after(jiffies, timeo)) { - spin_unlock(chip->mutex); - printk(KERN_ERR "%s: waiting for chip to be ready timed out\n", __FUNCTION__); - return -EIO; - } - - /* Latency issues. Drop the lock, wait a while and retry */ - spin_unlock(chip->mutex); - cfi_udelay(1); - goto retry; - - default: - /* Stick ourselves on a wait queue to be woken when - someone changes the status */ - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&chip->wq, &wait); + ret = get_chip(map, chip, adr, FL_LOCKING); + if (ret) { spin_unlock(chip->mutex); - schedule(); - remove_wait_queue(&chip->wq, &wait); - timeo = jiffies + HZ; - goto retry; + return ret; } ENABLE_VPP(map); - cfi_write(map, CMD(0x60), adr); + map_write(map, CMD(0x60), adr); if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) { - cfi_write(map, CMD(0x01), adr); + map_write(map, CMD(0x01), adr); chip->state = FL_LOCKING; } else if (thunk == DO_XXLOCK_ONEBLOCK_UNLOCK) { - cfi_write(map, CMD(0xD0), adr); + map_write(map, CMD(0xD0), adr); chip->state = FL_UNLOCKING; } else BUG(); @@ -1801,16 +1623,19 @@ timeo = jiffies + (HZ*20); for (;;) { - status = cfi_read(map, adr); - if ((status & status_OK) == status_OK) + status = map_read(map, adr); + if (map_word_andequal(map, status, status_OK, status_OK)) break; /* OK Still waiting */ if (time_after(jiffies, timeo)) { - cfi_write(map, CMD(0x70), adr); + map_word Xstatus; + map_write(map, CMD(0x70), adr); chip->state = FL_STATUS; - printk(KERN_ERR "waiting for unlock to complete timed out. Xstatus = %llx, status = %llx.\n", (__u64)status, (__u64)cfi_read(map, adr)); - DISABLE_VPP(map); + Xstatus = map_read(map, adr); + printk(KERN_ERR "waiting for unlock to complete timed out. status = %lx, Xstatus = %lx.\n", + status.x[0], Xstatus.x[0]); + put_chip(map, chip, adr); spin_unlock(chip->mutex); return -EIO; } @@ -1823,8 +1648,7 @@ /* Done and happy. */ chip->state = FL_STATUS; - DISABLE_VPP(map); - wake_up(&chip->wq); + put_chip(map, chip, adr); spin_unlock(chip->mutex); return 0; } @@ -1836,18 +1660,18 @@ #ifdef DEBUG_LOCK_BITS printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n", __FUNCTION__, ofs, len); - cfi_intelext_varsize_frob(mtd, do_printlockstatus_oneblock, - ofs, len, 0); + cfi_varsize_frob(mtd, do_printlockstatus_oneblock, + ofs, len, 0); #endif - ret = cfi_intelext_varsize_frob(mtd, do_xxlock_oneblock, - ofs, len, DO_XXLOCK_ONEBLOCK_LOCK); + ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, + ofs, len, DO_XXLOCK_ONEBLOCK_LOCK); #ifdef DEBUG_LOCK_BITS - printk(KERN_DEBUG __FUNCTION__ - "%s: lock status after, ret=%d\n", __FUNCTION__, ret); - cfi_intelext_varsize_frob(mtd, do_printlockstatus_oneblock, - ofs, len, 0); + printk(KERN_DEBUG "%s: lock status after, ret=%d\n", + __FUNCTION__, ret); + cfi_varsize_frob(mtd, do_printlockstatus_oneblock, + ofs, len, 0); #endif return ret; @@ -1860,17 +1684,18 @@ #ifdef DEBUG_LOCK_BITS printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n", __FUNCTION__, ofs, len); - cfi_intelext_varsize_frob(mtd, do_printlockstatus_oneblock, - ofs, len, 0); + cfi_varsize_frob(mtd, do_printlockstatus_oneblock, + ofs, len, 0); #endif - ret = cfi_intelext_varsize_frob(mtd, do_xxlock_oneblock, + ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, ofs, len, DO_XXLOCK_ONEBLOCK_UNLOCK); #ifdef DEBUG_LOCK_BITS - printk(KERN_DEBUG "%s: lock status after, ret=%d\n", __FUNCTION__, ret); - cfi_intelext_varsize_frob(mtd, do_printlockstatus_oneblock, - ofs, len, 0); + printk(KERN_DEBUG "%s: lock status after, ret=%d\n", + __FUNCTION__, ret); + cfi_varsize_frob(mtd, do_printlockstatus_oneblock, + ofs, len, 0); #endif return ret; @@ -1889,22 +1714,23 @@ spin_lock(chip->mutex); - switch(chip->state) { + switch (chip->state) { case FL_READY: case FL_STATUS: case FL_CFI_QUERY: case FL_JEDEC_QUERY: - chip->oldstate = chip->state; - chip->state = FL_PM_SUSPENDED; - /* No need to wake_up() on this state change - - * as the whole point is that nobody can do anything - * with the chip now anyway. - */ - case FL_PM_SUSPENDED: + if (chip->oldstate == FL_READY) { + chip->oldstate = chip->state; + chip->state = FL_PM_SUSPENDED; + /* No need to wake_up() on this state change - + * as the whole point is that nobody can do anything + * with the chip now anyway. + */ + } break; - default: ret = -EAGAIN; + case FL_PM_SUSPENDED: break; } spin_unlock(chip->mutex); @@ -1947,7 +1773,7 @@ /* Go to known state. Chip may have been power cycled */ if (chip->state == FL_PM_SUSPENDED) { - cfi_write(map, CMD(0xFF), 0); + map_write(map, CMD(0xFF), cfi->chips[i].start); chip->state = FL_READY; wake_up(&chip->wq); } @@ -1962,6 +1788,7 @@ struct cfi_private *cfi = map->fldrv_priv; kfree(cfi->cmdset_priv); kfree(cfi->cfiq); + kfree(cfi->chips[0].priv); kfree(cfi); kfree(mtd->eraseregions); } Index: drivers/mtd/chips/cfi_cmdset_0002.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/chips/cfi_cmdset_0002.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/chips/cfi_cmdset_0002.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/chips/cfi_cmdset_0002.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -3,19 +3,26 @@ * AMD & Fujitsu Standard Vendor Command Set (ID 0x0002) * * Copyright (C) 2000 Crossnet Co. + * Copyright (C) 2004 Arcom Control Systems Ltd * * 2_by_8 routines added by Simon Munton * + * 4_by_16 work by Carolyn J. Smith + * + * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com + * * This code is GPL * - * $Id: cfi_cmdset_0002.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: cfi_cmdset_0002.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * */ +#include #include #include #include #include +#include #include #include @@ -23,15 +30,24 @@ #include #include #include +#include #include +#include #include #define AMD_BOOTLOC_BUG +#define FORCE_WORD_WRITE 0 + +#define MAX_WORD_RETRIES 3 + +#define MANUFACTURER_AMD 0x0001 +#define MANUFACTURER_SST 0x00BF +#define SST49LF004B 0x0060 static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); -static int cfi_amdstd_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); +static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); +static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); static int cfi_amdstd_erase_chip(struct mtd_info *, struct erase_info *); -static int cfi_amdstd_erase_onesize(struct mtd_info *, struct erase_info *); static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *); static void cfi_amdstd_sync (struct mtd_info *); static int cfi_amdstd_suspend (struct mtd_info *); @@ -41,59 +57,213 @@ static void cfi_amdstd_destroy(struct mtd_info *); struct mtd_info *cfi_cmdset_0002(struct map_info *, int); -static struct mtd_info *cfi_amdstd_setup (struct map_info *); +static struct mtd_info *cfi_amdstd_setup (struct mtd_info *); +static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode); +static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr); +#include "fwh_lock.h" static struct mtd_chip_driver cfi_amdstd_chipdrv = { - probe: NULL, /* Not usable directly */ - destroy: cfi_amdstd_destroy, - name: "cfi_cmdset_0002", - module: THIS_MODULE + .probe = NULL, /* Not usable directly */ + .destroy = cfi_amdstd_destroy, + .name = "cfi_cmdset_0002", + .module = THIS_MODULE +}; + + +/* #define DEBUG_CFI_FEATURES */ + + +#ifdef DEBUG_CFI_FEATURES +static void cfi_tell_features(struct cfi_pri_amdstd *extp) +{ + const char* erase_suspend[3] = { + "Not supported", "Read only", "Read/write" + }; + const char* top_bottom[6] = { + "No WP", "8x8KiB sectors at top & bottom, no WP", + "Bottom boot", "Top boot", + "Uniform, Bottom WP", "Uniform, Top WP" + }; + + printk(" Silicon revision: %d\n", extp->SiliconRevision >> 1); + printk(" Address sensitive unlock: %s\n", + (extp->SiliconRevision & 1) ? "Not required" : "Required"); + + if (extp->EraseSuspend < ARRAY_SIZE(erase_suspend)) + printk(" Erase Suspend: %s\n", erase_suspend[extp->EraseSuspend]); + else + printk(" Erase Suspend: Unknown value %d\n", extp->EraseSuspend); + + if (extp->BlkProt == 0) + printk(" Block protection: Not supported\n"); + else + printk(" Block protection: %d sectors per group\n", extp->BlkProt); + + + printk(" Temporary block unprotect: %s\n", + extp->TmpBlkUnprotect ? "Supported" : "Not supported"); + printk(" Block protect/unprotect scheme: %d\n", extp->BlkProtUnprot); + printk(" Number of simultaneous operations: %d\n", extp->SimultaneousOps); + printk(" Burst mode: %s\n", + extp->BurstMode ? "Supported" : "Not supported"); + if (extp->PageMode == 0) + printk(" Page mode: Not supported\n"); + else + printk(" Page mode: %d word page\n", extp->PageMode << 2); + + printk(" Vpp Supply Minimum Program/Erase Voltage: %d.%d V\n", + extp->VppMin >> 4, extp->VppMin & 0xf); + printk(" Vpp Supply Maximum Program/Erase Voltage: %d.%d V\n", + extp->VppMax >> 4, extp->VppMax & 0xf); + + if (extp->TopBottom < ARRAY_SIZE(top_bottom)) + printk(" Top/Bottom Boot Block: %s\n", top_bottom[extp->TopBottom]); + else + printk(" Top/Bottom Boot Block: Unknown value %d\n", extp->TopBottom); +} +#endif + +#ifdef AMD_BOOTLOC_BUG +/* Wheee. Bring me the head of someone at AMD. */ +static void fixup_amd_bootblock(struct mtd_info *mtd, void* param) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + struct cfi_pri_amdstd *extp = cfi->cmdset_priv; + __u8 major = extp->MajorVersion; + __u8 minor = extp->MinorVersion; + + if (((major << 8) | minor) < 0x3131) { + /* CFI version 1.0 => don't trust bootloc */ + if (cfi->id & 0x80) { + printk(KERN_WARNING "%s: JEDEC Device ID is 0x%02X. Assuming broken CFI table.\n", map->name, cfi->id); + extp->TopBottom = 3; /* top boot */ + } else { + extp->TopBottom = 2; /* bottom boot */ + } + } +} +#endif + +static void fixup_use_write_buffers(struct mtd_info *mtd, void *param) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + if (cfi->cfiq->BufWriteTimeoutTyp) { + DEBUG(MTD_DEBUG_LEVEL1, "Using buffer write method\n" ); + mtd->write = cfi_amdstd_write_buffers; + } +} + +static void fixup_use_secsi(struct mtd_info *mtd, void *param) +{ + /* Setup for chips with a secsi area */ + mtd->read_user_prot_reg = cfi_amdstd_secsi_read; + mtd->read_fact_prot_reg = cfi_amdstd_secsi_read; +} + +static void fixup_use_erase_chip(struct mtd_info *mtd, void *param) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + if ((cfi->cfiq->NumEraseRegions == 1) && + ((cfi->cfiq->EraseRegionInfo[0] & 0xffff) == 0)) { + mtd->erase = cfi_amdstd_erase_chip; + } + +} + +static struct cfi_fixup cfi_fixup_table[] = { +#ifdef AMD_BOOTLOC_BUG + { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock, NULL }, +#endif + { CFI_MFR_AMD, 0x0050, fixup_use_secsi, NULL, }, + { CFI_MFR_AMD, 0x0053, fixup_use_secsi, NULL, }, + { CFI_MFR_AMD, 0x0055, fixup_use_secsi, NULL, }, + { CFI_MFR_AMD, 0x0056, fixup_use_secsi, NULL, }, + { CFI_MFR_AMD, 0x005C, fixup_use_secsi, NULL, }, + { CFI_MFR_AMD, 0x005F, fixup_use_secsi, NULL, }, +#if !FORCE_WORD_WRITE + { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, }, +#endif + { 0, 0, NULL, NULL } +}; +static struct cfi_fixup jedec_fixup_table[] = { + { MANUFACTURER_SST, SST49LF004B, fixup_use_fwh_lock, NULL, }, + { 0, 0, NULL, NULL } +}; + +static struct cfi_fixup fixup_table[] = { + /* The CFI vendor ids and the JEDEC vendor IDs appear + * to be common. It is like the devices id's are as + * well. This table is to pick all cases where + * we know that is the case. + */ + { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_erase_chip, NULL }, + { 0, 0, NULL, NULL } }; + struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) { struct cfi_private *cfi = map->fldrv_priv; - unsigned char bootloc; - int ofs_factor = cfi->interleave * cfi->device_type; + struct mtd_info *mtd; int i; - __u8 major, minor; - __u32 base = cfi->chips[0].start; + + mtd = kmalloc(sizeof(*mtd), GFP_KERNEL); + if (!mtd) { + printk(KERN_WARNING "Failed to allocate memory for MTD device\n"); + return NULL; + } + memset(mtd, 0, sizeof(*mtd)); + mtd->priv = map; + mtd->type = MTD_NORFLASH; + + /* Fill in the default mtd operations */ + mtd->erase = cfi_amdstd_erase_varsize; + mtd->write = cfi_amdstd_write_words; + mtd->read = cfi_amdstd_read; + mtd->sync = cfi_amdstd_sync; + mtd->suspend = cfi_amdstd_suspend; + mtd->resume = cfi_amdstd_resume; + mtd->flags = MTD_CAP_NORFLASH; + mtd->name = map->name; if (cfi->cfi_mode==CFI_MODE_CFI){ + unsigned char bootloc; + /* + * It's a real CFI chip, not one for which the probe + * routine faked a CFI structure. So we read the feature + * table from it. + */ __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR; + struct cfi_pri_amdstd *extp; - cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); - - major = cfi_read_query(map, base + (adr+3)*ofs_factor); - minor = cfi_read_query(map, base + (adr+4)*ofs_factor); - - printk(KERN_NOTICE " Amd/Fujitsu Extended Query Table v%c.%c at 0x%4.4X\n", - major, minor, adr); - cfi_send_gen_cmd(0xf0, 0x55, base, map, cfi, cfi->device_type, NULL); - - cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL); - cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL); - cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL); - cfi->mfr = cfi_read_query(map, base); - cfi->id = cfi_read_query(map, base + ofs_factor); + extp = (struct cfi_pri_amdstd*)cfi_read_pri(map, adr, sizeof(*extp), "Amd/Fujitsu"); + if (!extp) { + kfree(mtd); + return NULL; + } + + /* Install our own private info structure */ + cfi->cmdset_priv = extp; + + /* Apply cfi device specific fixups */ + cfi_fixup(mtd, cfi_fixup_table); + +#ifdef DEBUG_CFI_FEATURES + /* Tell the user about it in lots of lovely detail */ + cfi_tell_features(extp); +#endif + + bootloc = extp->TopBottom; + if ((bootloc != 2) && (bootloc != 3)) { + printk(KERN_WARNING "%s: CFI does not contain boot " + "bank location. Assuming top.\n", map->name); + bootloc = 2; + } - /* Wheee. Bring me the head of someone at AMD. */ -#ifdef AMD_BOOTLOC_BUG - if (((major << 8) | minor) < 0x3131) { - /* CFI version 1.0 => don't trust bootloc */ - if (cfi->id & 0x80) { - printk(KERN_WARNING "%s: JEDEC Device ID is 0x%02X. Assuming broken CFI table.\n", map->name, cfi->id); - bootloc = 3; /* top boot */ - } else { - bootloc = 2; /* bottom boot */ - } - } else -#endif - { - cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); - bootloc = cfi_read_query(map, base + (adr+15)*ofs_factor); - } if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) { printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name); @@ -106,29 +276,28 @@ cfi->cfiq->EraseRegionInfo[j] = swap; } } - switch (cfi->device_type) { - case CFI_DEVICETYPE_X8: - cfi->addr_unlock1 = 0x555; - cfi->addr_unlock2 = 0x2aa; - break; - case CFI_DEVICETYPE_X16: + /* Set the default CFI lock/unlock addresses */ + cfi->addr_unlock1 = 0x555; + cfi->addr_unlock2 = 0x2aa; + /* Modify the unlock address if we are in compatibility mode */ + if ( /* x16 in x8 mode */ + ((cfi->device_type == CFI_DEVICETYPE_X8) && + (cfi->cfiq->InterfaceDesc == 2)) || + /* x32 in x16 mode */ + ((cfi->device_type == CFI_DEVICETYPE_X16) && + (cfi->cfiq->InterfaceDesc == 4))) + { cfi->addr_unlock1 = 0xaaa; - if (map->buswidth == cfi->interleave) { - /* X16 chip(s) in X8 mode */ - cfi->addr_unlock2 = 0x555; - } else { - cfi->addr_unlock2 = 0x554; - } - break; - case CFI_DEVICETYPE_X32: - cfi->addr_unlock1 = 0x1555; - cfi->addr_unlock2 = 0xaaa; - break; - default: - printk(KERN_NOTICE "Eep. Unknown cfi_cmdset_0002 device type %d\n", cfi->device_type); - return NULL; + cfi->addr_unlock2 = 0x555; } + } /* CFI mode */ + else if (cfi->cfi_mode == CFI_MODE_JEDEC) { + /* Apply jedec specific fixups */ + cfi_fixup(mtd, jedec_fixup_table); + } + /* Apply generic fixups */ + cfi_fixup(mtd, fixup_table); for (i=0; i< cfi->numchips; i++) { cfi->chips[i].word_write_time = 1<cfiq->WordWriteTimeoutTyp; @@ -137,136 +306,67 @@ } map->fldrv = &cfi_amdstd_chipdrv; - - cfi_send_gen_cmd(0xf0, 0x55, base, map, cfi, cfi->device_type, NULL); - return cfi_amdstd_setup(map); + + return cfi_amdstd_setup(mtd); } -static struct mtd_info *cfi_amdstd_setup(struct map_info *map) + +static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd) { + struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; - struct mtd_info *mtd; unsigned long devsize = (1<cfiq->DevSize) * cfi->interleave; + unsigned long offset = 0; + int i,j; - mtd = kmalloc(sizeof(*mtd), GFP_KERNEL); printk(KERN_NOTICE "number of %s chips: %d\n", - (cfi->cfi_mode == CFI_MODE_CFI)?"CFI":"JEDEC",cfi->numchips); + (cfi->cfi_mode == CFI_MODE_CFI)?"CFI":"JEDEC",cfi->numchips); + /* Select the correct geometry setup */ + mtd->size = devsize * cfi->numchips; - if (!mtd) { - printk(KERN_WARNING "Failed to allocate memory for MTD device\n"); - goto setup_err; + mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; + mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) + * mtd->numeraseregions, GFP_KERNEL); + if (!mtd->eraseregions) { + printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n"); + goto setup_err; } - - memset(mtd, 0, sizeof(*mtd)); - mtd->priv = map; - mtd->type = MTD_NORFLASH; - /* Also select the correct geometry setup too */ - mtd->size = devsize * cfi->numchips; - - if (cfi->cfiq->NumEraseRegions == 1) { - /* No need to muck about with multiple erase sizes */ - mtd->erasesize = ((cfi->cfiq->EraseRegionInfo[0] >> 8) & ~0xff) * cfi->interleave; - } else { - unsigned long offset = 0; - int i,j; - - mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; - mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * mtd->numeraseregions, GFP_KERNEL); - if (!mtd->eraseregions) { - printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n"); - goto setup_err; - } - for (i=0; icfiq->NumEraseRegions; i++) { - unsigned long ernum, ersize; - ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; - ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1; + for (i=0; icfiq->NumEraseRegions; i++) { + unsigned long ernum, ersize; + ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; + ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1; - if (mtd->erasesize < ersize) { - mtd->erasesize = ersize; - } - for (j=0; jnumchips; j++) { - mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset; - mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize; - mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum; - } - offset += (ersize * ernum); - } - if (offset != devsize) { - /* Argh */ - printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize); - goto setup_err; - } -#if 0 - // debug - for (i=0; inumeraseregions;i++){ - printk("%d: offset=0x%x,size=0x%x,blocks=%d\n", - i,mtd->eraseregions[i].offset, - mtd->eraseregions[i].erasesize, - mtd->eraseregions[i].numblocks); + if (mtd->erasesize < ersize) { + mtd->erasesize = ersize; } -#endif - } - - switch (CFIDEV_BUSWIDTH) - { - case 1: - case 2: - case 4: -#if 1 - if (mtd->numeraseregions > 1) - mtd->erase = cfi_amdstd_erase_varsize; - else -#endif - if (((cfi->cfiq->EraseRegionInfo[0] & 0xffff) + 1) == 1) - mtd->erase = cfi_amdstd_erase_chip; - else - mtd->erase = cfi_amdstd_erase_onesize; - mtd->read = cfi_amdstd_read; - mtd->write = cfi_amdstd_write; - break; - - default: - printk(KERN_WARNING "Unsupported buswidth\n"); + for (j=0; jnumchips; j++) { + mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset; + mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize; + mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum; + } + offset += (ersize * ernum); + } + if (offset != devsize) { + /* Argh */ + printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize); goto setup_err; - break; } - if (cfi->fast_prog) { - /* In cfi_amdstd_write() we frob the protection stuff - without paying any attention to the state machine. - This upsets in-progress erases. So we turn this flag - off for now till the code gets fixed. */ - printk(KERN_NOTICE "cfi_cmdset_0002: Disabling fast programming due to code brokenness.\n"); - cfi->fast_prog = 0; +#if 0 + // debug + for (i=0; inumeraseregions;i++){ + printk("%d: offset=0x%x,size=0x%x,blocks=%d\n", + i,mtd->eraseregions[i].offset, + mtd->eraseregions[i].erasesize, + mtd->eraseregions[i].numblocks); } +#endif + /* FIXME: erase-suspend-program is broken. See + http://lists.infradead.org/pipermail/linux-mtd/2003-December/009001.html */ + printk(KERN_NOTICE "cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.\n"); - /* does this chip have a secsi area? */ - if(cfi->mfr==1){ - - switch(cfi->id){ - case 0x50: - case 0x53: - case 0x55: - case 0x56: - case 0x5C: - case 0x5F: - /* Yes */ - mtd->read_user_prot_reg = cfi_amdstd_secsi_read; - mtd->read_fact_prot_reg = cfi_amdstd_secsi_read; - default: - ; - } - } - - - mtd->sync = cfi_amdstd_sync; - mtd->suspend = cfi_amdstd_suspend; - mtd->resume = cfi_amdstd_resume; - mtd->flags = MTD_CAP_NORFLASH; - map->fldrv = &cfi_amdstd_chipdrv; - mtd->name = map->name; - MOD_INC_USE_COUNT; + __module_get(THIS_MODULE); return mtd; setup_err: @@ -280,46 +380,182 @@ return NULL; } -static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf) +/* + * Return true if the chip is ready. + * + * Ready is one of: read mode, query mode, erase-suspend-read mode (in any + * non-suspended sector) and is indicated by no toggle bits toggling. + * + * Note that anything more complicated than checking if no bits are toggling + * (including checking DQ5 for an error status) is tricky to get working + * correctly and is therefore not done (particulary with interleaved chips + * as each chip must be checked independantly of the others). + */ +static int chip_ready(struct map_info *map, unsigned long addr) +{ + map_word d, t; + + d = map_read(map, addr); + t = map_read(map, addr); + + return map_word_equal(map, d, t); +} + +static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode) { DECLARE_WAITQUEUE(wait, current); - unsigned long timeo = jiffies + HZ; + struct cfi_private *cfi = map->fldrv_priv; + unsigned long timeo; + struct cfi_pri_amdstd *cfip = (struct cfi_pri_amdstd *)cfi->cmdset_priv; + resettime: + timeo = jiffies + HZ; retry: - cfi_spin_lock(chip->mutex); + switch (chip->state) { - if (chip->state != FL_READY){ -#if 0 - printk(KERN_DEBUG "Waiting for chip to read, status = %d\n", chip->state); -#endif + case FL_STATUS: + for (;;) { + if (chip_ready(map, adr)) + break; + + if (time_after(jiffies, timeo)) { + printk(KERN_ERR "Waiting for chip to be ready timed out.\n"); + cfi_spin_unlock(chip->mutex); + return -EIO; + } + cfi_spin_unlock(chip->mutex); + cfi_udelay(1); + cfi_spin_lock(chip->mutex); + /* Someone else might have been playing with it. */ + goto retry; + } + + case FL_READY: + case FL_CFI_QUERY: + case FL_JEDEC_QUERY: + return 0; + + case FL_ERASING: + if (mode == FL_WRITING) /* FIXME: Erase-suspend-program appears broken. */ + goto sleep; + + if (!(mode == FL_READY || mode == FL_POINT + || !cfip + || (mode == FL_WRITING && (cfip->EraseSuspend & 0x2)) + || (mode == FL_WRITING && (cfip->EraseSuspend & 0x1)))) + goto sleep; + + /* We could check to see if we're trying to access the sector + * that is currently being erased. However, no user will try + * anything like that so we just wait for the timeout. */ + + /* Erase suspend */ + /* It's harmless to issue the Erase-Suspend and Erase-Resume + * commands when the erase algorithm isn't in progress. */ + map_write(map, CMD(0xB0), chip->in_progress_block_addr); + chip->oldstate = FL_ERASING; + chip->state = FL_ERASE_SUSPENDING; + chip->erase_suspended = 1; + for (;;) { + if (chip_ready(map, adr)) + break; + + if (time_after(jiffies, timeo)) { + /* Should have suspended the erase by now. + * Send an Erase-Resume command as either + * there was an error (so leave the erase + * routine to recover from it) or we trying to + * use the erase-in-progress sector. */ + map_write(map, CMD(0x30), chip->in_progress_block_addr); + chip->state = FL_ERASING; + chip->oldstate = FL_READY; + printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__); + return -EIO; + } + + cfi_spin_unlock(chip->mutex); + cfi_udelay(1); + cfi_spin_lock(chip->mutex); + /* Nobody will touch it while it's in state FL_ERASE_SUSPENDING. + So we can just loop here. */ + } + chip->state = FL_READY; + return 0; + + case FL_POINT: + /* Only if there's no operation suspended... */ + if (mode == FL_READY && chip->oldstate == FL_READY) + return 0; + + default: + sleep: set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(&chip->wq, &wait); - cfi_spin_unlock(chip->mutex); - schedule(); remove_wait_queue(&chip->wq, &wait); -#if 0 - if(signal_pending(current)) - return -EINTR; -#endif - timeo = jiffies + HZ; + cfi_spin_lock(chip->mutex); + goto resettime; + } +} - goto retry; - } + +static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr) +{ + struct cfi_private *cfi = map->fldrv_priv; + + switch(chip->oldstate) { + case FL_ERASING: + chip->state = chip->oldstate; + map_write(map, CMD(0x30), chip->in_progress_block_addr); + chip->oldstate = FL_READY; + chip->state = FL_ERASING; + break; + + case FL_READY: + case FL_STATUS: + /* We should really make set_vpp() count, rather than doing this */ + DISABLE_VPP(map); + break; + default: + printk(KERN_ERR "MTD: put_chip() called with oldstate %d!!\n", chip->oldstate); + } + wake_up(&chip->wq); +} + + +static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf) +{ + unsigned long cmd_addr; + struct cfi_private *cfi = map->fldrv_priv; + int ret; adr += chip->start; - chip->state = FL_READY; + /* Ensure cmd read/writes are aligned. */ + cmd_addr = adr & ~(map_bankwidth(map)-1); + + cfi_spin_lock(chip->mutex); + ret = get_chip(map, chip, cmd_addr, FL_READY); + if (ret) { + cfi_spin_unlock(chip->mutex); + return ret; + } - map->copy_from(map, buf, adr, len); + if (chip->state != FL_POINT && chip->state != FL_READY) { + map_write(map, CMD(0xf0), cmd_addr); + chip->state = FL_READY; + } - wake_up(&chip->wq); - cfi_spin_unlock(chip->mutex); + map_copy_from(map, buf, adr, len); + + put_chip(map, chip, cmd_addr); + cfi_spin_unlock(chip->mutex); return 0; } + static int cfi_amdstd_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { struct map_info *map = mtd->priv; @@ -361,6 +597,7 @@ return ret; } + static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf) { DECLARE_WAITQUEUE(wait, current); @@ -372,11 +609,11 @@ if (chip->state != FL_READY){ #if 0 - printk(KERN_DEBUG "Waiting for chip to read, status = %d\n", chip->state); + printk(KERN_DEBUG "Waiting for chip to read, status = %d\n", chip->state); #endif set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(&chip->wq, &wait); - + cfi_spin_unlock(chip->mutex); schedule(); @@ -393,12 +630,12 @@ adr += chip->start; chip->state = FL_READY; - + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); - map->copy_from(map, buf, adr, len); + map_copy_from(map, buf, adr, len); cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); @@ -454,125 +691,380 @@ return ret; } -static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, __u32 datum, int fast) + +static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, map_word datum) { - unsigned long timeo = jiffies + HZ; - unsigned int oldstatus, status; - unsigned int dq6, dq5; struct cfi_private *cfi = map->fldrv_priv; - DECLARE_WAITQUEUE(wait, current); + unsigned long timeo = jiffies + HZ; + /* + * We use a 1ms + 1 jiffies generic timeout for writes (most devices + * have a max write time of a few hundreds usec). However, we should + * use the maximum timeout value given by the chip at probe time + * instead. Unfortunately, struct flchip does have a field for + * maximum timeout, only for typical which can be far too short + * depending of the conditions. The ' + 1' is to avoid having a + * timeout of 0 jiffies if HZ is smaller than 1000. + */ + unsigned long uWriteTimeout = ( HZ / 1000 ) + 1; int ret = 0; + map_word oldd, curd; + int retry_cnt = 0; + adr += chip->start; + + cfi_spin_lock(chip->mutex); + ret = get_chip(map, chip, adr, FL_WRITING); + if (ret) { + cfi_spin_unlock(chip->mutex); + return ret; + } + + DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n", + __func__, adr, datum.x[0] ); + + /* + * Check for a NOP for the case when the datum to write is already + * present - it saves time and works around buggy chips that corrupt + * data at other locations when 0xff is written to a location that + * already contains 0xff. + */ + oldd = map_read(map, adr); + if (map_word_equal(map, oldd, datum)) { + DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): NOP\n", + __func__); + goto op_done; + } + + ENABLE_VPP(map); retry: + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); + map_write(map, datum, adr); + chip->state = FL_WRITING; + + cfi_spin_unlock(chip->mutex); + cfi_udelay(chip->word_write_time); cfi_spin_lock(chip->mutex); - if (chip->state != FL_READY) { + /* See comment above for timeout value. */ + timeo = jiffies + uWriteTimeout; + for (;;) { + if (chip->state != FL_WRITING) { + /* Someone's suspended the write. Sleep */ + DECLARE_WAITQUEUE(wait, current); + + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&chip->wq, &wait); + cfi_spin_unlock(chip->mutex); + schedule(); + remove_wait_queue(&chip->wq, &wait); + timeo = jiffies + (HZ / 2); /* FIXME */ + cfi_spin_lock(chip->mutex); + continue; + } + + /* Test to see if toggling has stopped. */ + oldd = map_read(map, adr); + curd = map_read(map, adr); + if (map_word_equal(map, curd, oldd)) { + /* Do we have the correct value? */ + if (map_word_equal(map, curd, datum)) { + goto op_done; + } + /* Nope something has gone wrong. */ + break; + } + + if (time_after(jiffies, timeo)) { + printk(KERN_WARNING "MTD %s(): software timeout\n", + __func__ ); + break; + } + + /* Latency issues. Drop the lock, wait a while and retry */ + cfi_spin_unlock(chip->mutex); + cfi_udelay(1); + cfi_spin_lock(chip->mutex); + } + + /* reset on all failures. */ + map_write( map, CMD(0xF0), chip->start ); + /* FIXME - should have reset delay before continuing */ + if (++retry_cnt <= MAX_WORD_RETRIES) + goto retry; + + ret = -EIO; + op_done: + chip->state = FL_READY; + put_chip(map, chip, adr); + cfi_spin_unlock(chip->mutex); + + return ret; +} + + +static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + int ret = 0; + int chipnum; + unsigned long ofs, chipstart; + DECLARE_WAITQUEUE(wait, current); + + *retlen = 0; + if (!len) + return 0; + + chipnum = to >> cfi->chipshift; + ofs = to - (chipnum << cfi->chipshift); + chipstart = cfi->chips[chipnum].start; + + /* If it's not bus-aligned, do the first byte write */ + if (ofs & (map_bankwidth(map)-1)) { + unsigned long bus_ofs = ofs & ~(map_bankwidth(map)-1); + int i = ofs - bus_ofs; + int n = 0; + map_word tmp_buf; + + retry: + cfi_spin_lock(cfi->chips[chipnum].mutex); + + if (cfi->chips[chipnum].state != FL_READY) { #if 0 - printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", chip->state); + printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", cfi->chips[chipnum].state); #endif - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&chip->wq, &wait); - - cfi_spin_unlock(chip->mutex); + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&cfi->chips[chipnum].wq, &wait); - schedule(); - remove_wait_queue(&chip->wq, &wait); + cfi_spin_unlock(cfi->chips[chipnum].mutex); + + schedule(); + remove_wait_queue(&cfi->chips[chipnum].wq, &wait); #if 0 - printk(KERN_DEBUG "Wake up to write:\n"); - if(signal_pending(current)) - return -EINTR; + if(signal_pending(current)) + return -EINTR; #endif - timeo = jiffies + HZ; + goto retry; + } - goto retry; - } + /* Load 'tmp_buf' with old contents of flash */ + tmp_buf = map_read(map, bus_ofs+chipstart); - chip->state = FL_WRITING; + cfi_spin_unlock(cfi->chips[chipnum].mutex); - adr += chip->start; - ENABLE_VPP(map); - if (fast) { /* Unlock bypass */ - cfi_send_gen_cmd(0xA0, 0, chip->start, map, cfi, cfi->device_type, NULL); + /* Number of bytes to copy from buffer */ + n = min_t(int, len, map_bankwidth(map)-i); + + tmp_buf = map_word_load_partial(map, tmp_buf, buf, i, n); + + ret = do_write_oneword(map, &cfi->chips[chipnum], + bus_ofs, tmp_buf); + if (ret) + return ret; + + ofs += n; + buf += n; + (*retlen) += n; + len -= n; + + if (ofs >> cfi->chipshift) { + chipnum ++; + ofs = 0; + if (chipnum == cfi->numchips) + return 0; + } } - else { - cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); - cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); - cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); + + /* We are now aligned, write as much as possible */ + while(len >= map_bankwidth(map)) { + map_word datum; + + datum = map_word_load(map, buf); + + ret = do_write_oneword(map, &cfi->chips[chipnum], + ofs, datum); + if (ret) + return ret; + + ofs += map_bankwidth(map); + buf += map_bankwidth(map); + (*retlen) += map_bankwidth(map); + len -= map_bankwidth(map); + + if (ofs >> cfi->chipshift) { + chipnum ++; + ofs = 0; + if (chipnum == cfi->numchips) + return 0; + chipstart = cfi->chips[chipnum].start; + } } - cfi_write(map, datum, adr); + /* Write the trailing bytes if any */ + if (len & (map_bankwidth(map)-1)) { + map_word tmp_buf; + + retry1: + cfi_spin_lock(cfi->chips[chipnum].mutex); - cfi_spin_unlock(chip->mutex); - cfi_udelay(chip->word_write_time); - cfi_spin_lock(chip->mutex); + if (cfi->chips[chipnum].state != FL_READY) { +#if 0 + printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", cfi->chips[chipnum].state); +#endif + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&cfi->chips[chipnum].wq, &wait); + + cfi_spin_unlock(cfi->chips[chipnum].mutex); + + schedule(); + remove_wait_queue(&cfi->chips[chipnum].wq, &wait); +#if 0 + if(signal_pending(current)) + return -EINTR; +#endif + goto retry1; + } + + tmp_buf = map_read(map, ofs + chipstart); - /* Polling toggle bits instead of reading back many times - This ensures that write operation is really completed, - or tells us why it failed. */ - dq6 = CMD(1<<6); - dq5 = CMD(1<<5); - timeo = jiffies + (HZ/1000); /* setting timeout to 1ms for now */ + cfi_spin_unlock(cfi->chips[chipnum].mutex); + + tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len); + + ret = do_write_oneword(map, &cfi->chips[chipnum], + ofs, tmp_buf); + if (ret) + return ret; - oldstatus = cfi_read(map, adr); - status = cfi_read(map, adr); + (*retlen) += len; + } - while( (status & dq6) != (oldstatus & dq6) && - (status & dq5) != dq5 && - !time_after(jiffies, timeo) ) { + return 0; +} - if (need_resched()) { - cfi_spin_unlock(chip->mutex); - yield(); - cfi_spin_lock(chip->mutex); - } else - udelay(1); - oldstatus = cfi_read( map, adr ); - status = cfi_read( map, adr ); +/* + * FIXME: interleaved mode not tested, and probably not supported! + */ +static inline int do_write_buffer(struct map_info *map, struct flchip *chip, + unsigned long adr, const u_char *buf, int len) +{ + struct cfi_private *cfi = map->fldrv_priv; + unsigned long timeo = jiffies + HZ; + /* see comments in do_write_oneword() regarding uWriteTimeo. */ + unsigned long uWriteTimeout = ( HZ / 1000 ) + 1; + int ret = -EIO; + unsigned long cmd_adr; + int z, words; + map_word datum; + + adr += chip->start; + cmd_adr = adr; + + cfi_spin_lock(chip->mutex); + ret = get_chip(map, chip, adr, FL_WRITING); + if (ret) { + cfi_spin_unlock(chip->mutex); + return ret; } - - if( (status & dq6) != (oldstatus & dq6) ) { - /* The erasing didn't stop?? */ - if( (status & dq5) == dq5 ) { - /* When DQ5 raises, we must check once again - if DQ6 is toggling. If not, the erase has been - completed OK. If not, reset chip. */ - oldstatus = cfi_read(map, adr); - status = cfi_read(map, adr); - - if ( (oldstatus & 0x00FF) == (status & 0x00FF) ) { - printk(KERN_WARNING "Warning: DQ5 raised while program operation was in progress, however operation completed OK\n" ); - } else { - /* DQ5 is active so we can do a reset and stop the erase */ - cfi_write(map, CMD(0xF0), chip->start); - printk(KERN_WARNING "Internal flash device timeout occurred or write operation was performed while flash was programming.\n" ); - } - } else { - printk(KERN_WARNING "Waiting for write to complete timed out in do_write_oneword."); - - chip->state = FL_READY; - wake_up(&chip->wq); + + datum = map_word_load(map, buf); + + DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n", + __func__, adr, datum.x[0] ); + + ENABLE_VPP(map); + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); + //cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); + + /* Write Buffer Load */ + map_write(map, CMD(0x25), cmd_adr); + + chip->state = FL_WRITING_TO_BUFFER; + + /* Write length of data to come */ + words = len / map_bankwidth(map); + map_write(map, CMD(words - 1), cmd_adr); + /* Write data */ + z = 0; + while(z < words * map_bankwidth(map)) { + datum = map_word_load(map, buf); + map_write(map, datum, adr + z); + + z += map_bankwidth(map); + buf += map_bankwidth(map); + } + z -= map_bankwidth(map); + + adr += z; + + /* Write Buffer Program Confirm: GO GO GO */ + map_write(map, CMD(0x29), cmd_adr); + chip->state = FL_WRITING; + + cfi_spin_unlock(chip->mutex); + cfi_udelay(chip->buffer_write_time); + cfi_spin_lock(chip->mutex); + + timeo = jiffies + uWriteTimeout; + + for (;;) { + if (chip->state != FL_WRITING) { + /* Someone's suspended the write. Sleep */ + DECLARE_WAITQUEUE(wait, current); + + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&chip->wq, &wait); cfi_spin_unlock(chip->mutex); - DISABLE_VPP(map); - ret = -EIO; + schedule(); + remove_wait_queue(&chip->wq, &wait); + timeo = jiffies + (HZ / 2); /* FIXME */ + cfi_spin_lock(chip->mutex); + continue; } + + if (chip_ready(map, adr)) + goto op_done; + + if( time_after(jiffies, timeo)) + break; + + /* Latency issues. Drop the lock, wait a while and retry */ + cfi_spin_unlock(chip->mutex); + cfi_udelay(1); + cfi_spin_lock(chip->mutex); } - DISABLE_VPP(map); + printk(KERN_WARNING "MTD %s(): software timeout\n", + __func__ ); + + /* reset on all failures. */ + map_write( map, CMD(0xF0), chip->start ); + /* FIXME - should have reset delay before continuing */ + + ret = -EIO; + op_done: chip->state = FL_READY; - wake_up(&chip->wq); + put_chip(map, chip, adr); cfi_spin_unlock(chip->mutex); return ret; } -static int cfi_amdstd_write (struct mtd_info *mtd, loff_t to , size_t len, size_t *retlen, const u_char *buf) + +static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; + int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; int ret = 0; int chipnum; - unsigned long ofs, chipstart; + unsigned long ofs; *retlen = 0; if (!len) @@ -580,544 +1072,265 @@ chipnum = to >> cfi->chipshift; ofs = to - (chipnum << cfi->chipshift); - chipstart = cfi->chips[chipnum].start; - - /* If it's not bus-aligned, do the first byte write */ - if (ofs & (CFIDEV_BUSWIDTH-1)) { - unsigned long bus_ofs = ofs & ~(CFIDEV_BUSWIDTH-1); - int i = ofs - bus_ofs; - int n = 0; - u_char tmp_buf[4]; - __u32 datum; - - map->copy_from(map, tmp_buf, bus_ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH); - while (len && i < CFIDEV_BUSWIDTH) - tmp_buf[i++] = buf[n++], len--; - - if (cfi_buswidth_is_2()) { - datum = *(__u16*)tmp_buf; - } else if (cfi_buswidth_is_4()) { - datum = *(__u32*)tmp_buf; - } else { - return -EINVAL; /* should never happen, but be safe */ - } - ret = do_write_oneword(map, &cfi->chips[chipnum], - bus_ofs, datum, 0); - if (ret) + /* If it's not bus-aligned, do the first word write */ + if (ofs & (map_bankwidth(map)-1)) { + size_t local_len = (-ofs)&(map_bankwidth(map)-1); + if (local_len > len) + local_len = len; + ret = cfi_amdstd_write_words(mtd, ofs + (chipnum<chipshift), + local_len, retlen, buf); + if (ret) return ret; - - ofs += n; - buf += n; - (*retlen) += n; + ofs += local_len; + buf += local_len; + len -= local_len; if (ofs >> cfi->chipshift) { - chipnum ++; + chipnum ++; ofs = 0; if (chipnum == cfi->numchips) return 0; } } - - if (cfi->fast_prog) { - /* Go into unlock bypass mode */ - cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL); - cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL); - cfi_send_gen_cmd(0x20, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL); - } - /* We are now aligned, write as much as possible */ - while(len >= CFIDEV_BUSWIDTH) { - __u32 datum; + /* Write buffer is worth it only if more than one word to write... */ + while (len >= map_bankwidth(map) * 2) { + /* We must not cross write block boundaries */ + int size = wbufsize - (ofs & (wbufsize-1)); + + if (size > len) + size = len; + if (size % map_bankwidth(map)) + size -= size % map_bankwidth(map); - if (cfi_buswidth_is_1()) { - datum = *(__u8*)buf; - } else if (cfi_buswidth_is_2()) { - datum = *(__u16*)buf; - } else if (cfi_buswidth_is_4()) { - datum = *(__u32*)buf; - } else { - return -EINVAL; - } - ret = do_write_oneword(map, &cfi->chips[chipnum], - ofs, datum, cfi->fast_prog); - if (ret) { - if (cfi->fast_prog){ - /* Get out of unlock bypass mode */ - cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi, cfi->device_type, NULL); - cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi, cfi->device_type, NULL); - } + ret = do_write_buffer(map, &cfi->chips[chipnum], + ofs, buf, size); + if (ret) return ret; - } - ofs += CFIDEV_BUSWIDTH; - buf += CFIDEV_BUSWIDTH; - (*retlen) += CFIDEV_BUSWIDTH; - len -= CFIDEV_BUSWIDTH; + ofs += size; + buf += size; + (*retlen) += size; + len -= size; if (ofs >> cfi->chipshift) { - if (cfi->fast_prog){ - /* Get out of unlock bypass mode */ - cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi, cfi->device_type, NULL); - cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi, cfi->device_type, NULL); - } - chipnum ++; ofs = 0; if (chipnum == cfi->numchips) return 0; - chipstart = cfi->chips[chipnum].start; - if (cfi->fast_prog){ - /* Go into unlock bypass mode for next set of chips */ - cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL); - cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL); - cfi_send_gen_cmd(0x20, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL); - } } } - if (cfi->fast_prog){ - /* Get out of unlock bypass mode */ - cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi, cfi->device_type, NULL); - cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi, cfi->device_type, NULL); - } + if (len) { + size_t retlen_dregs = 0; - /* Write the trailing bytes if any */ - if (len & (CFIDEV_BUSWIDTH-1)) { - int i = 0, n = 0; - u_char tmp_buf[4]; - __u32 datum; - - map->copy_from(map, tmp_buf, ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH); - while (len--) - tmp_buf[i++] = buf[n++]; - - if (cfi_buswidth_is_2()) { - datum = *(__u16*)tmp_buf; - } else if (cfi_buswidth_is_4()) { - datum = *(__u32*)tmp_buf; - } else { - return -EINVAL; /* should never happen, but be safe */ - } + ret = cfi_amdstd_write_words(mtd, ofs + (chipnum<chipshift), + len, &retlen_dregs, buf); - ret = do_write_oneword(map, &cfi->chips[chipnum], - ofs, datum, 0); - if (ret) - return ret; - - (*retlen) += n; + *retlen += retlen_dregs; + return ret; } return 0; } + +/* + * Handle devices with one erase region, that only implement + * the chip erase command. + */ static inline int do_erase_chip(struct map_info *map, struct flchip *chip) { - unsigned int oldstatus, status; - unsigned int dq6, dq5; - unsigned long timeo = jiffies + HZ; - unsigned int adr; struct cfi_private *cfi = map->fldrv_priv; + unsigned long timeo = jiffies + HZ; + unsigned long int adr; DECLARE_WAITQUEUE(wait, current); + int ret = 0; - retry: - cfi_spin_lock(chip->mutex); + adr = cfi->addr_unlock1; - if (chip->state != FL_READY){ - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&chip->wq, &wait); - + cfi_spin_lock(chip->mutex); + ret = get_chip(map, chip, adr, FL_WRITING); + if (ret) { cfi_spin_unlock(chip->mutex); + return ret; + } - schedule(); - remove_wait_queue(&chip->wq, &wait); -#if 0 - if(signal_pending(current)) - return -EINTR; -#endif - timeo = jiffies + HZ; + DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n", + __func__, chip->start ); - goto retry; - } + ENABLE_VPP(map); + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x10, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); chip->state = FL_ERASING; - - /* Handle devices with one erase region, that only implement - * the chip erase command. - */ - ENABLE_VPP(map); - cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); - cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); - cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); - cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); - cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); - cfi_send_gen_cmd(0x10, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); - timeo = jiffies + (HZ*20); - adr = cfi->addr_unlock1; + chip->erase_suspended = 0; + chip->in_progress_block_addr = adr; - /* Wait for the end of programing/erasure by using the toggle method. - * As long as there is a programming procedure going on, bit 6 of the last - * written byte is toggling it's state with each consectuve read. - * The toggling stops as soon as the procedure is completed. - * - * If the process has gone on for too long on the chip bit 5 gets. - * After bit5 is set you can kill the operation by sending a reset - * command to the chip. - */ - dq6 = CMD(1<<6); - dq5 = CMD(1<<5); + cfi_spin_unlock(chip->mutex); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((chip->erase_time*HZ)/(2*1000)); + cfi_spin_lock(chip->mutex); - oldstatus = cfi_read(map, adr); - status = cfi_read(map, adr); - while( ((status & dq6) != (oldstatus & dq6)) && - ((status & dq5) != dq5) && - !time_after(jiffies, timeo)) { - int wait_reps; + timeo = jiffies + (HZ*20); - /* an initial short sleep */ - cfi_spin_unlock(chip->mutex); - schedule_timeout(HZ/100); - cfi_spin_lock(chip->mutex); - + for (;;) { if (chip->state != FL_ERASING) { /* Someone's suspended the erase. Sleep */ set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(&chip->wq, &wait); - cfi_spin_unlock(chip->mutex); - printk("erase suspended. Sleeping\n"); - schedule(); remove_wait_queue(&chip->wq, &wait); -#if 0 - if (signal_pending(current)) - return -EINTR; -#endif - timeo = jiffies + (HZ*2); /* FIXME */ cfi_spin_lock(chip->mutex); continue; } - - /* Busy wait for 1/10 of a milisecond */ - for(wait_reps = 0; - (wait_reps < 100) && - ((status & dq6) != (oldstatus & dq6)) && - ((status & dq5) != dq5); - wait_reps++) { - - /* Latency issues. Drop the lock, wait a while and retry */ - cfi_spin_unlock(chip->mutex); - - cfi_udelay(1); - - cfi_spin_lock(chip->mutex); - oldstatus = cfi_read(map, adr); - status = cfi_read(map, adr); - } - oldstatus = cfi_read(map, adr); - status = cfi_read(map, adr); - } - if ((status & dq6) != (oldstatus & dq6)) { - /* The erasing didn't stop?? */ - if ((status & dq5) == dq5) { - /* dq5 is active so we can do a reset and stop the erase */ - cfi_write(map, CMD(0xF0), chip->start); + if (chip->erase_suspended) { + /* This erase was suspended and resumed. + Adjust the timeout */ + timeo = jiffies + (HZ*20); /* FIXME */ + chip->erase_suspended = 0; } - chip->state = FL_READY; - wake_up(&chip->wq); + + if (chip_ready(map, adr)) + goto op_done; + + if (time_after(jiffies, timeo)) + break; + + /* Latency issues. Drop the lock, wait a while and retry */ cfi_spin_unlock(chip->mutex); - printk("waiting for erase to complete timed out."); - DISABLE_VPP(map); - return -EIO; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1); + cfi_spin_lock(chip->mutex); } - DISABLE_VPP(map); + + printk(KERN_WARNING "MTD %s(): software timeout\n", + __func__ ); + + /* reset on all failures. */ + map_write( map, CMD(0xF0), chip->start ); + /* FIXME - should have reset delay before continuing */ + + ret = -EIO; + op_done: chip->state = FL_READY; - wake_up(&chip->wq); + put_chip(map, chip, adr); cfi_spin_unlock(chip->mutex); - return 0; + return ret; } -static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr) + +static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, int len, void *thunk) { - unsigned int oldstatus, status; - unsigned int dq6, dq5; - unsigned long timeo = jiffies + HZ; struct cfi_private *cfi = map->fldrv_priv; + unsigned long timeo = jiffies + HZ; DECLARE_WAITQUEUE(wait, current); + int ret = 0; - retry: - cfi_spin_lock(chip->mutex); + adr += chip->start; - if (chip->state != FL_READY){ - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&chip->wq, &wait); - + cfi_spin_lock(chip->mutex); + ret = get_chip(map, chip, adr, FL_ERASING); + if (ret) { cfi_spin_unlock(chip->mutex); + return ret; + } - schedule(); - remove_wait_queue(&chip->wq, &wait); -#if 0 - if(signal_pending(current)) - return -EINTR; -#endif - timeo = jiffies + HZ; + DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n", + __func__, adr ); - goto retry; - } + ENABLE_VPP(map); + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); + map_write(map, CMD(0x30), adr); chip->state = FL_ERASING; - - adr += chip->start; - ENABLE_VPP(map); - cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); - cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); - cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); - cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); - cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); - cfi_write(map, CMD(0x30), adr); + chip->erase_suspended = 0; + chip->in_progress_block_addr = adr; - timeo = jiffies + (HZ*20); - - /* Wait for the end of programing/erasure by using the toggle method. - * As long as there is a programming procedure going on, bit 6 of the last - * written byte is toggling it's state with each consectuve read. - * The toggling stops as soon as the procedure is completed. - * - * If the process has gone on for too long on the chip bit 5 gets. - * After bit5 is set you can kill the operation by sending a reset - * command to the chip. - */ - dq6 = CMD(1<<6); - dq5 = CMD(1<<5); + cfi_spin_unlock(chip->mutex); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((chip->erase_time*HZ)/(2*1000)); + cfi_spin_lock(chip->mutex); - oldstatus = cfi_read(map, adr); - status = cfi_read(map, adr); - while( ((status & dq6) != (oldstatus & dq6)) && - ((status & dq5) != dq5) && - !time_after(jiffies, timeo)) { - int wait_reps; + timeo = jiffies + (HZ*20); - /* an initial short sleep */ - cfi_spin_unlock(chip->mutex); - schedule_timeout(HZ/100); - cfi_spin_lock(chip->mutex); - + for (;;) { if (chip->state != FL_ERASING) { /* Someone's suspended the erase. Sleep */ set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(&chip->wq, &wait); - cfi_spin_unlock(chip->mutex); - printk(KERN_DEBUG "erase suspended. Sleeping\n"); - schedule(); remove_wait_queue(&chip->wq, &wait); -#if 0 - if (signal_pending(current)) - return -EINTR; -#endif - timeo = jiffies + (HZ*2); /* FIXME */ cfi_spin_lock(chip->mutex); continue; } - - /* Busy wait for 1/10 of a milisecond */ - for(wait_reps = 0; - (wait_reps < 100) && - ((status & dq6) != (oldstatus & dq6)) && - ((status & dq5) != dq5); - wait_reps++) { - - /* Latency issues. Drop the lock, wait a while and retry */ - cfi_spin_unlock(chip->mutex); - - cfi_udelay(1); - - cfi_spin_lock(chip->mutex); - oldstatus = cfi_read(map, adr); - status = cfi_read(map, adr); - } - oldstatus = cfi_read(map, adr); - status = cfi_read(map, adr); - } - if( (status & dq6) != (oldstatus & dq6) ) - { - /* The erasing didn't stop?? */ - if( ( status & dq5 ) == dq5 ) - { - /* When DQ5 raises, we must check once again if DQ6 is toggling. - If not, the erase has been completed OK. If not, reset chip. */ - oldstatus = cfi_read( map, adr ); - status = cfi_read( map, adr ); - - if( ( oldstatus & 0x00FF ) == ( status & 0x00FF ) ) - { - printk( "Warning: DQ5 raised while erase operation was in progress, but erase completed OK\n" ); - } - else - { - /* DQ5 is active so we can do a reset and stop the erase */ - cfi_write(map, CMD(0xF0), chip->start); - printk( KERN_WARNING "Internal flash device timeout occured or write operation was performed while flash was erasing\n" ); - } + if (chip->erase_suspended) { + /* This erase was suspended and resumed. + Adjust the timeout */ + timeo = jiffies + (HZ*20); /* FIXME */ + chip->erase_suspended = 0; } - else - { - printk( "Waiting for erase to complete timed out in do_erase_oneblock."); - - chip->state = FL_READY; - wake_up(&chip->wq); - cfi_spin_unlock(chip->mutex); - DISABLE_VPP(map); - return -EIO; - } - } - - DISABLE_VPP(map); - chip->state = FL_READY; - wake_up(&chip->wq); - cfi_spin_unlock(chip->mutex); - return 0; -} - -static int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) -{ - struct map_info *map = mtd->priv; - struct cfi_private *cfi = map->fldrv_priv; - unsigned long adr, len; - int chipnum, ret = 0; - int i, first; - struct mtd_erase_region_info *regions = mtd->eraseregions; - - if (instr->addr > mtd->size) - return -EINVAL; - if ((instr->len + instr->addr) > mtd->size) - return -EINVAL; - - /* Check that both start and end of the requested erase are - * aligned with the erasesize at the appropriate addresses. - */ - - i = 0; - - /* Skip all erase regions which are ended before the start of - the requested erase. Actually, to save on the calculations, - we skip to the first erase region which starts after the - start of the requested erase, and then go back one. - */ - - while (i < mtd->numeraseregions && instr->addr >= regions[i].offset) - i++; - i--; - - /* OK, now i is pointing at the erase region in which this - erase request starts. Check the start of the requested - erase range is aligned with the erase size which is in - effect here. - */ - - if (instr->addr & (regions[i].erasesize-1)) - return -EINVAL; + if (chip_ready(map, adr)) + goto op_done; - /* Remember the erase region we start on */ - first = i; - - /* Next, check that the end of the requested erase is aligned - * with the erase region at that address. - */ - - while (inumeraseregions && (instr->addr + instr->len) >= regions[i].offset) - i++; + if (time_after(jiffies, timeo)) + break; - /* As before, drop back one to point at the region in which - the address actually falls - */ - i--; + /* Latency issues. Drop the lock, wait a while and retry */ + cfi_spin_unlock(chip->mutex); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1); + cfi_spin_lock(chip->mutex); + } - if ((instr->addr + instr->len) & (regions[i].erasesize-1)) - return -EINVAL; + printk(KERN_WARNING "MTD %s(): software timeout\n", + __func__ ); - chipnum = instr->addr >> cfi->chipshift; - adr = instr->addr - (chipnum << cfi->chipshift); - len = instr->len; - - i=first; - - while(len) { - ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr); - - if (ret) - return ret; - - adr += regions[i].erasesize; - len -= regions[i].erasesize; + /* reset on all failures. */ + map_write( map, CMD(0xF0), chip->start ); + /* FIXME - should have reset delay before continuing */ - if (adr % (1<< cfi->chipshift) == ((regions[i].offset + (regions[i].erasesize * regions[i].numblocks)) %( 1<< cfi->chipshift))) - i++; - - if (adr >> cfi->chipshift) { - adr = 0; - chipnum++; - - if (chipnum >= cfi->numchips) - break; - } - } - - instr->state = MTD_ERASE_DONE; - if (instr->callback) - instr->callback(instr); - - return 0; + ret = -EIO; + op_done: + chip->state = FL_READY; + put_chip(map, chip, adr); + cfi_spin_unlock(chip->mutex); + return ret; } -static int cfi_amdstd_erase_onesize(struct mtd_info *mtd, struct erase_info *instr) -{ - struct map_info *map = mtd->priv; - struct cfi_private *cfi = map->fldrv_priv; - unsigned long adr, len; - int chipnum, ret = 0; - - if (instr->addr & (mtd->erasesize - 1)) - return -EINVAL; - - if (instr->len & (mtd->erasesize -1)) - return -EINVAL; - if ((instr->len + instr->addr) > mtd->size) - return -EINVAL; +int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) +{ + unsigned long ofs, len; + int ret; - chipnum = instr->addr >> cfi->chipshift; - adr = instr->addr - (chipnum << cfi->chipshift); + ofs = instr->addr; len = instr->len; - while(len) { - ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr); - - if (ret) - return ret; - - adr += mtd->erasesize; - len -= mtd->erasesize; + ret = cfi_varsize_frob(mtd, do_erase_oneblock, ofs, len, NULL); + if (ret) + return ret; - if (adr >> cfi->chipshift) { - adr = 0; - chipnum++; - - if (chipnum >= cfi->numchips) - break; - } - } - instr->state = MTD_ERASE_DONE; - if (instr->callback) - instr->callback(instr); + mtd_erase_callback(instr); return 0; } + static int cfi_amdstd_erase_chip(struct mtd_info *mtd, struct erase_info *instr) { struct map_info *map = mtd->priv; @@ -1135,12 +1348,12 @@ return ret; instr->state = MTD_ERASE_DONE; - if (instr->callback) - instr->callback(instr); + mtd_erase_callback(instr); return 0; } + static void cfi_amdstd_sync (struct mtd_info *mtd) { struct map_info *map = mtd->priv; @@ -1179,7 +1392,7 @@ schedule(); - remove_wait_queue(&chip->wq, &wait); + remove_wait_queue(&chip->wq, &wait); goto retry; } @@ -1238,7 +1451,7 @@ /* Unlock the chips again */ if (ret) { - for (i--; i >=0; i--) { + for (i--; i >=0; i--) { chip = &cfi->chips[i]; cfi_spin_lock(chip->mutex); @@ -1254,6 +1467,7 @@ return ret; } + static void cfi_amdstd_resume(struct mtd_info *mtd) { struct map_info *map = mtd->priv; @@ -1269,7 +1483,7 @@ if (chip->state == FL_PM_SUSPENDED) { chip->state = FL_READY; - cfi_write(map, CMD(0xF0), chip->start); + map_write(map, CMD(0xF0), chip->start); wake_up(&chip->wq); } else @@ -1291,21 +1505,23 @@ static char im_name[]="cfi_cmdset_0002"; + int __init cfi_amdstd_init(void) { inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0002); return 0; } + static void __exit cfi_amdstd_exit(void) { inter_module_unregister(im_name); } + module_init(cfi_amdstd_init); module_exit(cfi_amdstd_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Crossnet Co. et al."); MODULE_DESCRIPTION("MTD chip driver for AMD/Fujitsu flash chips"); - Index: drivers/mtd/chips/cfi_cmdset_0020.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/chips/cfi_cmdset_0020.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/mtd/chips/cfi_cmdset_0020.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/chips/cfi_cmdset_0020.c 3 Nov 2004 00:04:43 -0000 1.2 @@ -4,6 +4,7 @@ * * (C) 2000 Red Hat. GPL'd * + * $Id: cfi_cmdset_0020.c,v 1.2 2004/11/03 00:04:43 joff Exp $ * * 10/10/2000 Nicolas Pitre * - completely revamped method functions so they are aware and @@ -17,10 +18,12 @@ * - added a writev function */ +#include #include #include #include #include +#include #include #include @@ -30,12 +33,13 @@ #include #include #include +#include #include static int cfi_staa_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int cfi_staa_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); -static int cfi_staa_writev(struct mtd_info *mtd, const struct iovec *vecs, +static int cfi_staa_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); static int cfi_staa_erase_varsize(struct mtd_info *, struct erase_info *); static void cfi_staa_sync (struct mtd_info *); @@ -51,10 +55,10 @@ static struct mtd_info *cfi_staa_setup (struct map_info *); static struct mtd_chip_driver cfi_staa_chipdrv = { - probe: NULL, /* Not usable directly */ - destroy: cfi_staa_destroy, - name: "cfi_cmdset_0020", - module: THIS_MODULE + .probe = NULL, /* Not usable directly */ + .destroy = cfi_staa_destroy, + .name = "cfi_cmdset_0020", + .module = THIS_MODULE }; /* #define DEBUG_LOCK_BITS */ @@ -113,7 +117,6 @@ { struct cfi_private *cfi = map->fldrv_priv; int i; - __u32 base = cfi->chips[0].start; if (cfi->cfi_mode) { /* @@ -123,36 +126,11 @@ */ __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR; struct cfi_pri_intelext *extp; - int ofs_factor = cfi->interleave * cfi->device_type; - printk(" ST Microelectronics Extended Query Table at 0x%4.4X\n", adr); - if (!adr) + extp = (struct cfi_pri_intelext*)cfi_read_pri(map, adr, sizeof(*extp), "ST Microelectronics"); + if (!extp) return NULL; - /* Switch it into Query Mode */ - cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); - - extp = kmalloc(sizeof(*extp), GFP_KERNEL); - if (!extp) { - printk(KERN_ERR "Failed to allocate memory\n"); - return NULL; - } - - /* Read in the Extended Query Table */ - for (i=0; iMajorVersion != '1' || - (extp->MinorVersion < '0' || extp->MinorVersion > '2')) { - printk(KERN_WARNING " Unknown staa Extended Query " - "version %c.%c.\n", extp->MajorVersion, - extp->MinorVersion); - kfree(extp); - return NULL; - } - /* Do some byteswapping if necessary */ extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport); extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask); @@ -172,11 +150,6 @@ cfi->chips[i].erase_time = 1024; } - map->fldrv = &cfi_staa_chipdrv; - MOD_INC_USE_COUNT; - - /* Make sure it's in read mode */ - cfi_send_gen_cmd(0xff, 0x55, base, map, cfi, cfi->device_type, NULL); return cfi_staa_setup(map); } @@ -208,6 +181,7 @@ if (!mtd->eraseregions) { printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n"); kfree(cfi->cmdset_priv); + kfree(mtd); return NULL; } @@ -232,6 +206,7 @@ printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize); kfree(mtd->eraseregions); kfree(cfi->cmdset_priv); + kfree(mtd); return NULL; } @@ -256,7 +231,7 @@ mtd->flags |= MTD_ECC; /* FIXME: Not all STMicro flashes have this */ mtd->eccsize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */ map->fldrv = &cfi_staa_chipdrv; - MOD_INC_USE_COUNT; + __module_get(THIS_MODULE); mtd->name = map->name; return mtd; } @@ -264,7 +239,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf) { - __u32 status, status_OK; + map_word status, status_OK; unsigned long timeo; DECLARE_WAITQUEUE(wait, current); int suspended = 0; @@ -274,7 +249,7 @@ adr += chip->start; /* Ensure cmd read/writes are aligned. */ - cmd_addr = adr & ~(CFIDEV_BUSWIDTH-1); + cmd_addr = adr & ~(map_bankwidth(map)-1); /* Let's determine this according to the interleave only once */ status_OK = CMD(0x80); @@ -288,33 +263,33 @@ */ switch (chip->state) { case FL_ERASING: - if (!((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2) + if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2)) goto sleep; /* We don't support erase suspend */ - cfi_write (map, CMD(0xb0), cmd_addr); + map_write (map, CMD(0xb0), cmd_addr); /* If the flash has finished erasing, then 'erase suspend' * appears to make some (28F320) flash devices switch to * 'read' mode. Make sure that we switch to 'read status' * mode so we get the right data. --rmk */ - cfi_write(map, CMD(0x70), cmd_addr); + map_write(map, CMD(0x70), cmd_addr); chip->oldstate = FL_ERASING; chip->state = FL_ERASE_SUSPENDING; // printk("Erase suspending at 0x%lx\n", cmd_addr); for (;;) { - status = cfi_read(map, cmd_addr); - if ((status & status_OK) == status_OK) + status = map_read(map, cmd_addr); + if (map_word_andequal(map, status, status_OK, status_OK)) break; if (time_after(jiffies, timeo)) { /* Urgh */ - cfi_write(map, CMD(0xd0), cmd_addr); + map_write(map, CMD(0xd0), cmd_addr); /* make sure we're in 'read status' mode */ - cfi_write(map, CMD(0x70), cmd_addr); + map_write(map, CMD(0x70), cmd_addr); chip->state = FL_ERASING; spin_unlock_bh(chip->mutex); printk(KERN_ERR "Chip not ready after erase " - "suspended: status = 0x%x\n", status); + "suspended: status = 0x%lx\n", status.x[0]); return -EIO; } @@ -324,7 +299,7 @@ } suspended = 1; - cfi_write(map, CMD(0xff), cmd_addr); + map_write(map, CMD(0xff), cmd_addr); chip->state = FL_READY; break; @@ -338,13 +313,13 @@ case FL_CFI_QUERY: case FL_JEDEC_QUERY: - cfi_write(map, CMD(0x70), cmd_addr); + map_write(map, CMD(0x70), cmd_addr); chip->state = FL_STATUS; case FL_STATUS: - status = cfi_read(map, cmd_addr); - if ((status & status_OK) == status_OK) { - cfi_write(map, CMD(0xff), cmd_addr); + status = map_read(map, cmd_addr); + if (map_word_andequal(map, status, status_OK, status_OK)) { + map_write(map, CMD(0xff), cmd_addr); chip->state = FL_READY; break; } @@ -352,7 +327,7 @@ /* Urgh. Chip not yet ready to talk to us. */ if (time_after(jiffies, timeo)) { spin_unlock_bh(chip->mutex); - printk(KERN_ERR "waiting for chip to be ready timed out in read. WSM status = %x\n", status); + printk(KERN_ERR "waiting for chip to be ready timed out in read. WSM status = %lx\n", status.x[0]); return -EIO; } @@ -374,7 +349,7 @@ goto retry; } - map->copy_from(map, buf, adr, len); + map_copy_from(map, buf, adr, len); if (suspended) { chip->state = chip->oldstate; @@ -387,8 +362,8 @@ sending the 0x70 (Read Status) command to an erasing chip and expecting it to be ignored, that's what we do. */ - cfi_write(map, CMD(0xd0), cmd_addr); - cfi_write(map, CMD(0x70), cmd_addr); + map_write(map, CMD(0xd0), cmd_addr); + map_write(map, CMD(0x70), cmd_addr); } wake_up(&chip->wq); @@ -439,16 +414,16 @@ unsigned long adr, const u_char *buf, int len) { struct cfi_private *cfi = map->fldrv_priv; - __u32 status, status_OK; + map_word status, status_OK; unsigned long cmd_adr, timeo; DECLARE_WAITQUEUE(wait, current); int wbufsize, z; /* M58LW064A requires bus alignment for buffer wriets -- saw */ - if (adr & (CFIDEV_BUSWIDTH-1)) + if (adr & (map_bankwidth(map)-1)) return -EINVAL; - wbufsize = CFIDEV_INTERLEAVE << cfi->cfiq->MaxBufWriteSize; + wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; adr += chip->start; cmd_adr = adr & ~(wbufsize-1); @@ -474,21 +449,21 @@ case FL_CFI_QUERY: case FL_JEDEC_QUERY: - cfi_write(map, CMD(0x70), cmd_adr); + map_write(map, CMD(0x70), cmd_adr); chip->state = FL_STATUS; #ifdef DEBUG_CFI_FEATURES - printk("%s: 1 status[%x]\n", __FUNCTION__, cfi_read(map, cmd_adr)); + printk("%s: 1 status[%x]\n", __FUNCTION__, map_read(map, cmd_adr)); #endif case FL_STATUS: - status = cfi_read(map, cmd_adr); - if ((status & status_OK) == status_OK) + status = map_read(map, cmd_adr); + if (map_word_andequal(map, status, status_OK, status_OK)) break; /* Urgh. Chip not yet ready to talk to us. */ if (time_after(jiffies, timeo)) { spin_unlock_bh(chip->mutex); - printk(KERN_ERR "waiting for chip to be ready timed out in buffer write Xstatus = %x, status = %x\n", - status, cfi_read(map, cmd_adr)); + printk(KERN_ERR "waiting for chip to be ready timed out in buffer write Xstatus = %lx, status = %lx\n", + status.x[0], map_read(map, cmd_adr).x[0]); return -EIO; } @@ -510,13 +485,13 @@ } ENABLE_VPP(map); - cfi_write(map, CMD(0xe8), cmd_adr); + map_write(map, CMD(0xe8), cmd_adr); chip->state = FL_WRITING_TO_BUFFER; z = 0; for (;;) { - status = cfi_read(map, cmd_adr); - if ((status & status_OK) == status_OK) + status = map_read(map, cmd_adr); + if (map_word_andequal(map, status, status_OK, status_OK)) break; spin_unlock_bh(chip->mutex); @@ -526,32 +501,26 @@ if (++z > 100) { /* Argh. Not ready for write to buffer */ DISABLE_VPP(map); - cfi_write(map, CMD(0x70), cmd_adr); + map_write(map, CMD(0x70), cmd_adr); chip->state = FL_STATUS; spin_unlock_bh(chip->mutex); - printk(KERN_ERR "Chip not ready for buffer write. Xstatus = %x\n", status); + printk(KERN_ERR "Chip not ready for buffer write. Xstatus = %lx\n", status.x[0]); return -EIO; } } /* Write length of data to come */ - cfi_write(map, CMD(len/CFIDEV_BUSWIDTH-1), cmd_adr ); + map_write(map, CMD(len/map_bankwidth(map)-1), cmd_adr ); /* Write data */ - for (z = 0; z < len; z += CFIDEV_BUSWIDTH) { - if (cfi_buswidth_is_1()) { - map->write8 (map, *((__u8*)buf)++, adr+z); - } else if (cfi_buswidth_is_2()) { - map->write16 (map, *((__u16*)buf)++, adr+z); - } else if (cfi_buswidth_is_4()) { - map->write32 (map, *((__u32*)buf)++, adr+z); - } else { - DISABLE_VPP(map); - return -EINVAL; - } + for (z = 0; z < len; + z += map_bankwidth(map), buf += map_bankwidth(map)) { + map_word d; + d = map_word_load(map, buf); + map_write(map, d, adr+z); } /* GO GO GO */ - cfi_write(map, CMD(0xd0), cmd_adr); + map_write(map, CMD(0xd0), cmd_adr); chip->state = FL_WRITING; spin_unlock_bh(chip->mutex); @@ -573,16 +542,16 @@ continue; } - status = cfi_read(map, cmd_adr); - if ((status & status_OK) == status_OK) + status = map_read(map, cmd_adr); + if (map_word_andequal(map, status, status_OK, status_OK)) break; /* OK Still waiting */ if (time_after(jiffies, timeo)) { /* clear status */ - cfi_write(map, CMD(0x50), cmd_adr); + map_write(map, CMD(0x50), cmd_adr); /* put back into read status register mode */ - cfi_write(map, CMD(0x70), adr); + map_write(map, CMD(0x70), adr); chip->state = FL_STATUS; DISABLE_VPP(map); spin_unlock_bh(chip->mutex); @@ -609,19 +578,18 @@ chip->state = FL_STATUS; /* check for errors: 'lock bit', 'VPP', 'dead cell'/'unerased cell' or 'incorrect cmd' -- saw */ - if ((status & CMD(0x02)) || (status & CMD(0x08)) || - (status & CMD(0x10)) || (status & CMD(0x20))) { + if (map_word_bitsset(map, status, CMD(0x3a))) { #ifdef DEBUG_CFI_FEATURES - printk("%s: 2 status[%x]\n", __FUNCTION__, status); + printk("%s: 2 status[%lx]\n", __FUNCTION__, status.x[0]); #endif - /* clear status */ - cfi_write(map, CMD(0x50), cmd_adr); - /* put back into read status register mode */ - cfi_write(map, CMD(0x70), adr); - wake_up(&chip->wq); - spin_unlock_bh(chip->mutex); - return (status & CMD(0x02)) ? -EROFS : -EIO; - } + /* clear status */ + map_write(map, CMD(0x50), cmd_adr); + /* put back into read status register mode */ + map_write(map, CMD(0x70), adr); + wake_up(&chip->wq); + spin_unlock_bh(chip->mutex); + return map_word_bitsset(map, status, CMD(0x02)) ? -EROFS : -EIO; + } wake_up(&chip->wq); spin_unlock_bh(chip->mutex); @@ -633,7 +601,7 @@ { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; - int wbufsize = CFIDEV_INTERLEAVE << cfi->cfiq->MaxBufWriteSize; + int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; int ret = 0; int chipnum; unsigned long ofs; @@ -646,7 +614,7 @@ ofs = to - (chipnum << cfi->chipshift); #ifdef DEBUG_CFI_FEATURES - printk("%s: CFIDEV_BUSWIDTH[%x]\n", __FUNCTION__, CFIDEV_BUSWIDTH); + printk("%s: map_bankwidth(map)[%x]\n", __FUNCTION__, map_bankwidth(map)); printk("%s: chipnum[%x] wbufsize[%x]\n", __FUNCTION__, chipnum, wbufsize); printk("%s: ofs[%x] len[%x]\n", __FUNCTION__, ofs, len); #endif @@ -689,7 +657,7 @@ #define ECCBUF_DIV(x) ((x) & ~(ECCBUF_SIZE - 1)) #define ECCBUF_MOD(x) ((x) & (ECCBUF_SIZE - 1)) static int -cfi_staa_writev(struct mtd_info *mtd, const struct iovec *vecs, +cfi_staa_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen) { unsigned long i; @@ -758,7 +726,7 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr) { struct cfi_private *cfi = map->fldrv_priv; - __u32 status, status_OK; + map_word status, status_OK; unsigned long timeo; int retries = 3; DECLARE_WAITQUEUE(wait, current); @@ -778,12 +746,12 @@ case FL_CFI_QUERY: case FL_JEDEC_QUERY: case FL_READY: - cfi_write(map, CMD(0x70), adr); + map_write(map, CMD(0x70), adr); chip->state = FL_STATUS; case FL_STATUS: - status = cfi_read(map, adr); - if ((status & status_OK) == status_OK) + status = map_read(map, adr); + if (map_word_andequal(map, status, status_OK, status_OK)) break; /* Urgh. Chip not yet ready to talk to us. */ @@ -812,11 +780,11 @@ ENABLE_VPP(map); /* Clear the status register first */ - cfi_write(map, CMD(0x50), adr); + map_write(map, CMD(0x50), adr); /* Now erase */ - cfi_write(map, CMD(0x20), adr); - cfi_write(map, CMD(0xD0), adr); + map_write(map, CMD(0x20), adr); + map_write(map, CMD(0xD0), adr); chip->state = FL_ERASING; spin_unlock_bh(chip->mutex); @@ -840,15 +808,15 @@ continue; } - status = cfi_read(map, adr); - if ((status & status_OK) == status_OK) + status = map_read(map, adr); + if (map_word_andequal(map, status, status_OK, status_OK)) break; /* OK Still waiting */ if (time_after(jiffies, timeo)) { - cfi_write(map, CMD(0x70), adr); + map_write(map, CMD(0x70), adr); chip->state = FL_STATUS; - printk(KERN_ERR "waiting for erase to complete timed out. Xstatus = %x, status = %x.\n", status, cfi_read(map, adr)); + printk(KERN_ERR "waiting for erase to complete timed out. Xstatus = %lx, status = %lx.\n", status.x[0], map_read(map, adr).x[0]); DISABLE_VPP(map); spin_unlock_bh(chip->mutex); return -EIO; @@ -864,43 +832,46 @@ ret = 0; /* We've broken this before. It doesn't hurt to be safe */ - cfi_write(map, CMD(0x70), adr); + map_write(map, CMD(0x70), adr); chip->state = FL_STATUS; - status = cfi_read(map, adr); + status = map_read(map, adr); /* check for lock bit */ - if (status & CMD(0x3a)) { - unsigned char chipstatus = status; - if (status != CMD(status & 0xff)) { - int i; - for (i = 1; i> (cfi->device_type * 8); + if (map_word_bitsset(map, status, CMD(0x3a))) { + unsigned char chipstatus = status.x[0]; + if (!map_word_equal(map, status, CMD(chipstatus))) { + int i, w; + for (w=0; w> (cfi->device_type * 8); + } } - printk(KERN_WARNING "Status is not identical for all chips: 0x%x. Merging to give 0x%02x\n", status, chipstatus); + printk(KERN_WARNING "Status is not identical for all chips: 0x%lx. Merging to give 0x%02x\n", + status.x[0], chipstatus); } /* Reset the error bits */ - cfi_write(map, CMD(0x50), adr); - cfi_write(map, CMD(0x70), adr); + map_write(map, CMD(0x50), adr); + map_write(map, CMD(0x70), adr); if ((chipstatus & 0x30) == 0x30) { - printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", status); + printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus); ret = -EIO; } else if (chipstatus & 0x02) { /* Protection bit set */ ret = -EROFS; } else if (chipstatus & 0x8) { /* Voltage */ - printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%x\n", status); + printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%x\n", chipstatus); ret = -EIO; } else if (chipstatus & 0x20) { if (retries--) { - printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x. Retrying...\n", adr, status); + printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x. Retrying...\n", adr, chipstatus); timeo = jiffies + HZ; chip->state = FL_STATUS; spin_unlock_bh(chip->mutex); goto retry; } - printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x\n", adr, status); + printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x\n", adr, chipstatus); ret = -EIO; } } @@ -995,8 +966,7 @@ } instr->state = MTD_ERASE_DONE; - if (instr->callback) - instr->callback(instr); + mtd_erase_callback(instr); return 0; } @@ -1061,7 +1031,7 @@ static inline int do_lock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr) { struct cfi_private *cfi = map->fldrv_priv; - __u32 status, status_OK; + map_word status, status_OK; unsigned long timeo = jiffies + HZ; DECLARE_WAITQUEUE(wait, current); @@ -1079,12 +1049,12 @@ case FL_CFI_QUERY: case FL_JEDEC_QUERY: case FL_READY: - cfi_write(map, CMD(0x70), adr); + map_write(map, CMD(0x70), adr); chip->state = FL_STATUS; case FL_STATUS: - status = cfi_read(map, adr); - if ((status & status_OK) == status_OK) + status = map_read(map, adr); + if (map_word_andequal(map, status, status_OK, status_OK)) break; /* Urgh. Chip not yet ready to talk to us. */ @@ -1112,8 +1082,8 @@ } ENABLE_VPP(map); - cfi_write(map, CMD(0x60), adr); - cfi_write(map, CMD(0x01), adr); + map_write(map, CMD(0x60), adr); + map_write(map, CMD(0x01), adr); chip->state = FL_LOCKING; spin_unlock_bh(chip->mutex); @@ -1126,15 +1096,15 @@ timeo = jiffies + (HZ*2); for (;;) { - status = cfi_read(map, adr); - if ((status & status_OK) == status_OK) + status = map_read(map, adr); + if (map_word_andequal(map, status, status_OK, status_OK)) break; /* OK Still waiting */ if (time_after(jiffies, timeo)) { - cfi_write(map, CMD(0x70), adr); + map_write(map, CMD(0x70), adr); chip->state = FL_STATUS; - printk(KERN_ERR "waiting for lock to complete timed out. Xstatus = %x, status = %x.\n", status, cfi_read(map, adr)); + printk(KERN_ERR "waiting for lock to complete timed out. Xstatus = %lx, status = %lx.\n", status.x[0], map_read(map, adr).x[0]); DISABLE_VPP(map); spin_unlock_bh(chip->mutex); return -EIO; @@ -1210,7 +1180,7 @@ static inline int do_unlock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr) { struct cfi_private *cfi = map->fldrv_priv; - __u32 status, status_OK; + map_word status, status_OK; unsigned long timeo = jiffies + HZ; DECLARE_WAITQUEUE(wait, current); @@ -1228,12 +1198,12 @@ case FL_CFI_QUERY: case FL_JEDEC_QUERY: case FL_READY: - cfi_write(map, CMD(0x70), adr); + map_write(map, CMD(0x70), adr); chip->state = FL_STATUS; case FL_STATUS: - status = cfi_read(map, adr); - if ((status & status_OK) == status_OK) + status = map_read(map, adr); + if (map_word_andequal(map, status, status_OK, status_OK)) break; /* Urgh. Chip not yet ready to talk to us. */ @@ -1261,8 +1231,8 @@ } ENABLE_VPP(map); - cfi_write(map, CMD(0x60), adr); - cfi_write(map, CMD(0xD0), adr); + map_write(map, CMD(0x60), adr); + map_write(map, CMD(0xD0), adr); chip->state = FL_UNLOCKING; spin_unlock_bh(chip->mutex); @@ -1275,15 +1245,15 @@ timeo = jiffies + (HZ*2); for (;;) { - status = cfi_read(map, adr); - if ((status & status_OK) == status_OK) + status = map_read(map, adr); + if (map_word_andequal(map, status, status_OK, status_OK)) break; /* OK Still waiting */ if (time_after(jiffies, timeo)) { - cfi_write(map, CMD(0x70), adr); + map_write(map, CMD(0x70), adr); chip->state = FL_STATUS; - printk(KERN_ERR "waiting for unlock to complete timed out. Xstatus = %x, status = %x.\n", status, cfi_read(map, adr)); + printk(KERN_ERR "waiting for unlock to complete timed out. Xstatus = %lx, status = %lx.\n", status.x[0], map_read(map, adr).x[0]); DISABLE_VPP(map); spin_unlock_bh(chip->mutex); return -EIO; @@ -1412,7 +1382,7 @@ /* Go to known state. Chip may have been power cycled */ if (chip->state == FL_PM_SUSPENDED) { - cfi_write(map, CMD(0xFF), 0); + map_write(map, CMD(0xFF), 0); chip->state = FL_READY; wake_up(&chip->wq); } @@ -1429,23 +1399,20 @@ kfree(cfi); } -#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE) -#define cfi_staa_init init_module -#define cfi_staa_exit cleanup_module -#endif - static char im_name[]="cfi_cmdset_0020"; -mod_init_t cfi_staa_init(void) +int __init cfi_staa_init(void) { inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0020); return 0; } -mod_exit_t cfi_staa_exit(void) +static void __exit cfi_staa_exit(void) { inter_module_unregister(im_name); } module_init(cfi_staa_init); module_exit(cfi_staa_exit); + +MODULE_LICENSE("GPL"); Index: drivers/mtd/chips/cfi_probe.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/chips/cfi_probe.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/chips/cfi_probe.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/chips/cfi_probe.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,13 +1,14 @@ /* Common Flash Interface probe code. (C) 2000 Red Hat. GPL'd. - $Id: cfi_probe.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + $Id: cfi_probe.c,v 1.3 2004/11/03 00:04:43 joff Exp $ */ #include #include #include #include +#include #include #include #include @@ -25,7 +26,7 @@ #endif static int cfi_probe_chip(struct map_info *map, __u32 base, - struct flchip *chips, struct cfi_private *cfi); + unsigned long *chip_map, struct cfi_private *cfi); static int cfi_chip_setup(struct map_info *map, struct cfi_private *cfi); struct mtd_info *cfi_probe(struct map_info *map); @@ -34,21 +35,36 @@ in: interleave,type,mode ret: table index, <0 for error */ -static inline int qry_present(struct map_info *map, __u32 base, +static int qry_present(struct map_info *map, __u32 base, struct cfi_private *cfi) { int osf = cfi->interleave * cfi->device_type; // scale factor + map_word val; + map_word qry; - if (cfi_read(map,base+osf*0x10)==cfi_build_cmd('Q',map,cfi) && - cfi_read(map,base+osf*0x11)==cfi_build_cmd('R',map,cfi) && - cfi_read(map,base+osf*0x12)==cfi_build_cmd('Y',map,cfi)) - return 1; // ok ! + qry = cfi_build_cmd('Q', map, cfi); + val = map_read(map, base + osf*0x10); - return 0; // nothing found + if (!map_word_equal(map, qry, val)) + return 0; + + qry = cfi_build_cmd('R', map, cfi); + val = map_read(map, base + osf*0x11); + + if (!map_word_equal(map, qry, val)) + return 0; + + qry = cfi_build_cmd('Y', map, cfi); + val = map_read(map, base + osf*0x12); + + if (!map_word_equal(map, qry, val)) + return 0; + + return 1; // nothing found } static int cfi_probe_chip(struct map_info *map, __u32 base, - struct flchip *chips, struct cfi_private *cfi) + unsigned long *chip_map, struct cfi_private *cfi) { int i; @@ -65,10 +81,7 @@ return 0; } cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); - - /* some devices don't respond to 0xF0, so send 0xFF to be sure */ cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); - cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); if (!qry_present(map,base,cfi)) @@ -81,20 +94,25 @@ } /* Check each previous chip to see if it's an alias */ - for (i=0; inumchips; i++) { + for (i=0; i < (base >> cfi->chipshift); i++) { + unsigned long start; + if(!test_bit(i, chip_map)) { + /* Skip location; no valid chip at this address */ + continue; + } + start = i << cfi->chipshift; /* This chip should be in read mode if it's one we've already touched. */ - if (qry_present(map,chips[i].start,cfi)) { + if (qry_present(map, start, cfi)) { /* Eep. This chip also had the QRY marker. * Is it an alias for the new one? */ - cfi_send_gen_cmd(0xF0, 0, chips[i].start, map, cfi, cfi->device_type, NULL); - /* some devices don't respond to 0xF0, so send 0xFF to be sure */ - cfi_send_gen_cmd(0xFF, 0, chips[i].start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0xF0, 0, start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL); /* If the QRY marker goes away, it's an alias */ - if (!qry_present(map, chips[i].start, cfi)) { + if (!qry_present(map, start, cfi)) { printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", - map->name, base, chips[i].start); + map->name, base, start); return 0; } /* Yes, it's actually got QRY for data. Most @@ -102,11 +120,11 @@ * too and if it's the same, assume it's an alias. */ /* FIXME: Use other modes to do a proper check */ cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); - /* some devices don't respond to 0xF0, so send 0xFF to be sure */ - cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL); + if (qry_present(map, base, cfi)) { printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", - map->name, base, chips[i].start); + map->name, base, start); return 0; } } @@ -114,25 +132,16 @@ /* OK, if we got to here, then none of the previous chips appear to be aliases for the current one. */ - if (cfi->numchips == MAX_CFI_CHIPS) { - printk(KERN_WARNING"%s: Too many flash chips detected. Increase MAX_CFI_CHIPS from %d.\n", map->name, MAX_CFI_CHIPS); - /* Doesn't matter about resetting it to Read Mode - we're not going to talk to it anyway */ - return -1; - } - chips[cfi->numchips].start = base; - chips[cfi->numchips].state = FL_READY; + set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */ cfi->numchips++; /* Put it back into Read Mode */ cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); - - /* some devices don't respond to 0xF0, so send 0xFF to be sure */ cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); - - printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit mode\n", + printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", map->name, cfi->interleave, cfi->device_type*8, base, - map->buswidth*8); + map->bankwidth*8); return 1; } @@ -160,36 +169,39 @@ memset(cfi->cfiq,0,sizeof(struct cfi_ident)); cfi->cfi_mode = CFI_MODE_CFI; - cfi->fast_prog=1; /* CFI supports fast programming */ /* Read the CFI info structure */ - for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) { + for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) ((unsigned char *)cfi->cfiq)[i] = cfi_read_query(map,base + (0x10 + i)*ofs_factor); - } - + + /* Note we put the device back into Read Mode BEFORE going into Auto + * Select Mode, as some devices support nesting of modes, others + * don't. This way should always work. + * On cmdset 0001 the writes of 0xaa and 0x55 are not needed, and + * so should be treated as nops or illegal (and so put the device + * back into Read Mode, which is a nop in this case). + */ + cfi_send_gen_cmd(0xf0, 0, base, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL); + cfi->mfr = cfi_read_query(map, base); + cfi->id = cfi_read_query(map, base + ofs_factor); + + /* Put it back into Read Mode */ + cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); + /* ... even if it's an Intel chip */ + cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); + /* Do any necessary byteswapping */ cfi->cfiq->P_ID = le16_to_cpu(cfi->cfiq->P_ID); - + cfi->cfiq->P_ADR = le16_to_cpu(cfi->cfiq->P_ADR); cfi->cfiq->A_ID = le16_to_cpu(cfi->cfiq->A_ID); cfi->cfiq->A_ADR = le16_to_cpu(cfi->cfiq->A_ADR); cfi->cfiq->InterfaceDesc = le16_to_cpu(cfi->cfiq->InterfaceDesc); cfi->cfiq->MaxBufWriteSize = le16_to_cpu(cfi->cfiq->MaxBufWriteSize); - /* - * ST screwed up the CFI interface for buffer writes on their parts, - * so this needs to be fixed up by hand here. - * - * A possible enhancment is that instead of just reverting back - * to word write (as this does), we could use the ST specific double - * word write instead. - */ - - if (cfi_read_query(map,base) == 0x20){ - cfi->cfiq->BufWriteTimeoutTyp = 0; - cfi->cfiq->BufWriteTimeoutMax = 0; - } - #ifdef DEBUG_CFI /* Dump the information therein */ print_cfi_ident(cfi->cfiq); @@ -204,11 +216,10 @@ (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1); #endif } - /* Put it back into Read Mode */ - cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); - /* some devices don't respond to 0xF0, so send 0xFF to be sure */ - cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); + printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", + map->name, cfi->interleave, cfi->device_type*8, base, + map->bankwidth*8); return 1; } @@ -231,12 +242,27 @@ case P_ID_AMD_EXT: return "AMD/Fujitsu Extended"; + + case P_ID_WINBOND: + return "Winbond Standard"; + case P_ID_ST_ADV: + return "ST Advanced"; + case P_ID_MITSUBISHI_STD: return "Mitsubishi Standard"; case P_ID_MITSUBISHI_EXT: return "Mitsubishi Extended"; + + case P_ID_SST_PAGE: + return "SST Page Write"; + + case P_ID_INTEL_PERFORMANCE: + return "Intel Performance Code"; + + case P_ID_INTEL_DATA: + return "Intel Data"; case P_ID_RESERVED: return "Not Allowed / Reserved for Future Use"; @@ -268,11 +294,11 @@ printk("No Alternate Algorithm Table\n"); - printk("Vcc Minimum: %x.%x V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf); - printk("Vcc Maximum: %x.%x V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf); + printk("Vcc Minimum: %2d.%d V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf); + printk("Vcc Maximum: %2d.%d V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf); if (cfip->VppMin) { - printk("Vpp Minimum: %x.%x V\n", cfip->VppMin >> 4, cfip->VppMin & 0xf); - printk("Vpp Maximum: %x.%x V\n", cfip->VppMax >> 4, cfip->VppMax & 0xf); + printk("Vpp Minimum: %2d.%d V\n", cfip->VppMin >> 4, cfip->VppMin & 0xf); + printk("Vpp Maximum: %2d.%d V\n", cfip->VppMax >> 4, cfip->VppMax & 0xf); } else printk("No Vpp line\n"); @@ -315,6 +341,10 @@ printk(" - x32-only asynchronous interface\n"); break; + case 4: + printk(" - supports x16 and x32 via Word# with asynchronous interface\n"); + break; + case 65535: printk(" - Not Allowed / Reserved\n"); break; @@ -331,8 +361,8 @@ #endif /* DEBUG_CFI */ static struct chip_probe cfi_chip_probe = { - name: "CFI", - probe_chip: cfi_probe_chip + .name = "CFI", + .probe_chip = cfi_probe_chip }; struct mtd_info *cfi_probe(struct map_info *map) @@ -345,9 +375,9 @@ } static struct mtd_chip_driver cfi_chipdrv = { - probe: cfi_probe, - name: "cfi_probe", - module: THIS_MODULE + .probe = cfi_probe, + .name = "cfi_probe", + .module = THIS_MODULE }; int __init cfi_probe_init(void) Index: drivers/mtd/chips/chipreg.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/chips/chipreg.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/chips/chipreg.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/chips/chipreg.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,5 +1,5 @@ /* - * $Id: chipreg.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: chipreg.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * * Registration for chip drivers * @@ -7,10 +7,13 @@ #include #include +#include #include #include -#include +#include #include +#include +#include spinlock_t chip_drvs_lock = SPIN_LOCK_UNLOCKED; static LIST_HEAD(chip_drvs_list); @@ -44,10 +47,8 @@ break; } } - if (ret && !try_inc_mod_count(ret->module)) { - /* Eep. Failed. */ + if (ret && !try_module_get(ret->module)) ret = NULL; - } spin_unlock(&chip_drvs_lock); @@ -64,32 +65,46 @@ drv = get_mtd_chip_driver(name); - if (!drv && !request_module(name)) + if (!drv && !request_module("%s", name)) drv = get_mtd_chip_driver(name); if (!drv) return NULL; ret = drv->probe(map); -#ifdef CONFIG_MODULES + /* We decrease the use count here. It may have been a probe-only module, which is no longer required from this point, having given us a handle on (and increased the use count of) the actual driver code. */ - if(drv->module) - __MOD_DEC_USE_COUNT(drv->module); -#endif + module_put(drv->module); if (ret) return ret; return NULL; } +/* + * Destroy an MTD device which was created for a map device. + * Make sure the MTD device is already unregistered before calling this + */ +void map_destroy(struct mtd_info *mtd) +{ + struct map_info *map = mtd->priv; + + if (map->fldrv->destroy) + map->fldrv->destroy(mtd); + + module_put(map->fldrv->module); + + kfree(mtd); +} EXPORT_SYMBOL(register_mtd_chip_driver); EXPORT_SYMBOL(unregister_mtd_chip_driver); EXPORT_SYMBOL(do_map_probe); +EXPORT_SYMBOL(map_destroy); MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Woodhouse "); Index: drivers/mtd/chips/gen_probe.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/chips/gen_probe.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/chips/gen_probe.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/chips/gen_probe.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,11 +1,13 @@ /* * Routines common to all CFI-type probes. - * (C) 2001, 2001 Red Hat, Inc. + * (C) 2001-2003 Red Hat, Inc. * GPL'd - * $Id: gen_probe.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: gen_probe.c,v 1.3 2004/11/03 00:04:43 joff Exp $ */ #include +#include +#include #include #include #include @@ -48,13 +50,13 @@ EXPORT_SYMBOL(mtd_do_chip_probe); -struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chip_probe *cp) +static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chip_probe *cp) { - unsigned long base=0; struct cfi_private cfi; struct cfi_private *retcfi; - struct flchip chip[MAX_CFI_CHIPS]; - int i; + unsigned long *chip_map; + int i, j, mapsize; + int max_chips; memset(&cfi, 0, sizeof(cfi)); @@ -62,7 +64,7 @@ interleave and device type, etc. */ if (!genprobe_new_chip(map, cp, &cfi)) { /* The probe didn't like it */ - printk(KERN_WARNING "%s: Found no %s device at location zero\n", + printk(KERN_DEBUG "%s: Found no %s device at location zero\n", cp->name, map->name); return NULL; } @@ -77,46 +79,47 @@ return NULL; } #endif - chip[0].start = 0; - chip[0].state = FL_READY; cfi.chipshift = cfi.cfiq->DevSize; - switch(cfi.interleave) { -#ifdef CFIDEV_INTERLEAVE_1 - case 1: - break; -#endif -#ifdef CFIDEV_INTERLEAVE_2 - case 2: + if (cfi_interleave_is_1(&cfi)) { + ; + } else if (cfi_interleave_is_2(&cfi)) { cfi.chipshift++; - break; -#endif -#ifdef CFIDEV_INTERLEAVE_4 - case 4: - cfi.chipshift+=2; - break; -#endif - default: + } else if (cfi_interleave_is_4((&cfi))) { + cfi.chipshift += 2; + } else if (cfi_interleave_is_8(&cfi)) { + cfi.chipshift += 3; + } else { BUG(); } cfi.numchips = 1; + /* + * Allocate memory for bitmap of valid chips. + * Align bitmap storage size to full byte. + */ + max_chips = map->size >> cfi.chipshift; + mapsize = (max_chips / 8) + ((max_chips % 8) ? 1 : 0); + chip_map = kmalloc(mapsize, GFP_KERNEL); + if (!chip_map) { + printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name); + kfree(cfi.cfiq); + return NULL; + } + memset (chip_map, 0, mapsize); + + set_bit(0, chip_map); /* Mark first chip valid */ + /* * Now probe for other chips, checking sensibly for aliases while * we're at it. The new_chip probe above should have let the first * chip in read mode. - * - * NOTE: Here, we're checking if there is room for another chip - * the same size within the mapping. Therefore, - * base + chipsize <= map->size is the correct thing to do, - * because, base + chipsize would be the _first_ byte of the - * next chip, not the one we're currently pondering. */ - for (base = (1<size; - base += (1<probe_chip(map, base, &chip[0], &cfi); + for (i = 1; i < max_chips; i++) { + cp->probe_chip(map, i << cfi.chipshift, chip_map, &cfi); + } /* * Now allocate the space for the structures we need to return to @@ -128,19 +131,26 @@ if (!retcfi) { printk(KERN_WARNING "%s: kmalloc failed for CFI private structure\n", map->name); kfree(cfi.cfiq); + kfree(chip_map); return NULL; } memcpy(retcfi, &cfi, sizeof(cfi)); - memcpy(&retcfi->chips[0], chip, sizeof(struct flchip) * cfi.numchips); + memset(&retcfi->chips[0], 0, sizeof(struct flchip) * cfi.numchips); + + for (i = 0, j = 0; (j < cfi.numchips) && (i < max_chips); i++) { + if(test_bit(i, chip_map)) { + struct flchip *pchip = &retcfi->chips[j++]; - /* Fix up the stuff that breaks when you move it */ - for (i=0; i< retcfi->numchips; i++) { - init_waitqueue_head(&retcfi->chips[i].wq); - spin_lock_init(&retcfi->chips[i]._spinlock); - retcfi->chips[i].mutex = &retcfi->chips[i]._spinlock; + pchip->start = (i << cfi.chipshift); + pchip->state = FL_READY; + init_waitqueue_head(&pchip->wq); + spin_lock_init(&pchip->_spinlock); + pchip->mutex = &pchip->_spinlock; + } } + kfree(chip_map); return retcfi; } @@ -148,135 +158,36 @@ static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp, struct cfi_private *cfi) { - switch (map->buswidth) { -#ifdef CFIDEV_BUSWIDTH_1 - case CFIDEV_BUSWIDTH_1: - cfi->interleave = CFIDEV_INTERLEAVE_1; - - cfi->device_type = CFI_DEVICETYPE_X8; - if (cp->probe_chip(map, 0, NULL, cfi)) - return 1; - - cfi->device_type = CFI_DEVICETYPE_X16; - if (cp->probe_chip(map, 0, NULL, cfi)) - return 1; - break; -#endif /* CFIDEV_BUSWITDH_1 */ - -#ifdef CFIDEV_BUSWIDTH_2 - case CFIDEV_BUSWIDTH_2: -#ifdef CFIDEV_INTERLEAVE_1 - cfi->interleave = CFIDEV_INTERLEAVE_1; - - cfi->device_type = CFI_DEVICETYPE_X16; - if (cp->probe_chip(map, 0, NULL, cfi)) - return 1; -#endif /* CFIDEV_INTERLEAVE_1 */ -#ifdef CFIDEV_INTERLEAVE_2 - cfi->interleave = CFIDEV_INTERLEAVE_2; - - cfi->device_type = CFI_DEVICETYPE_X8; - if (cp->probe_chip(map, 0, NULL, cfi)) - return 1; - - cfi->device_type = CFI_DEVICETYPE_X16; - if (cp->probe_chip(map, 0, NULL, cfi)) - return 1; -#endif /* CFIDEV_INTERLEAVE_2 */ - break; -#endif /* CFIDEV_BUSWIDTH_2 */ - -#ifdef CFIDEV_BUSWIDTH_4 - case CFIDEV_BUSWIDTH_4: -#if defined(CFIDEV_INTERLEAVE_1) && defined(SOMEONE_ACTUALLY_MAKES_THESE) - cfi->interleave = CFIDEV_INTERLEAVE_1; - - cfi->device_type = CFI_DEVICETYPE_X32; - if (cp->probe_chip(map, 0, NULL, cfi)) - return 1; -#endif /* CFIDEV_INTERLEAVE_1 */ -#ifdef CFIDEV_INTERLEAVE_2 - cfi->interleave = CFIDEV_INTERLEAVE_2; - -#ifdef SOMEONE_ACTUALLY_MAKES_THESE - cfi->device_type = CFI_DEVICETYPE_X32; - if (cp->probe_chip(map, 0, NULL, cfi)) - return 1; -#endif - cfi->device_type = CFI_DEVICETYPE_X16; - if (cp->probe_chip(map, 0, NULL, cfi)) - return 1; - - cfi->device_type = CFI_DEVICETYPE_X8; - if (cp->probe_chip(map, 0, NULL, cfi)) - return 1; -#endif /* CFIDEV_INTERLEAVE_2 */ -#ifdef CFIDEV_INTERLEAVE_4 - cfi->interleave = CFIDEV_INTERLEAVE_4; - -#ifdef SOMEONE_ACTUALLY_MAKES_THESE - cfi->device_type = CFI_DEVICETYPE_X32; - if (cp->probe_chip(map, 0, NULL, cfi)) - return 1; -#endif - cfi->device_type = CFI_DEVICETYPE_X16; - if (cp->probe_chip(map, 0, NULL, cfi)) - return 1; - - cfi->device_type = CFI_DEVICETYPE_X8; - if (cp->probe_chip(map, 0, NULL, cfi)) - return 1; -#endif /* CFIDEV_INTERLEAVE_4 */ - break; -#endif /* CFIDEV_BUSWIDTH_4 */ - -#ifdef CFIDEV_BUSWIDTH_8 - case CFIDEV_BUSWIDTH_8: -#if defined(CFIDEV_INTERLEAVE_2) && defined(SOMEONE_ACTUALLY_MAKES_THESE) - cfi->interleave = CFIDEV_INTERLEAVE_2; - - cfi->device_type = CFI_DEVICETYPE_X32; - if (cp->probe_chip(map, 0, NULL, cfi)) - return 1; -#endif /* CFIDEV_INTERLEAVE_2 */ -#ifdef CFIDEV_INTERLEAVE_4 - cfi->interleave = CFIDEV_INTERLEAVE_4; - -#ifdef SOMEONE_ACTUALLY_MAKES_THESE - cfi->device_type = CFI_DEVICETYPE_X32; - if (cp->probe_chip(map, 0, NULL, cfi)) - return 1; -#endif - cfi->device_type = CFI_DEVICETYPE_X16; - if (cp->probe_chip(map, 0, NULL, cfi)) - return 1; -#endif /* CFIDEV_INTERLEAVE_4 */ -#ifdef CFIDEV_INTERLEAVE_8 - cfi->interleave = CFIDEV_INTERLEAVE_8; - - cfi->device_type = CFI_DEVICETYPE_X16; - if (cp->probe_chip(map, 0, NULL, cfi)) - return 1; - - cfi->device_type = CFI_DEVICETYPE_X8; - if (cp->probe_chip(map, 0, NULL, cfi)) - return 1; -#endif /* CFIDEV_INTERLEAVE_8 */ - break; -#endif /* CFIDEV_BUSWIDTH_8 */ - - default: - printk(KERN_WARNING "genprobe_new_chip called with unsupported buswidth %d\n", map->buswidth); - return 0; + int min_chips = (map_bankwidth(map)/4?:1); /* At most 4-bytes wide. */ + int max_chips = map_bankwidth(map); /* And minimum 1 */ + int nr_chips, type; + + for (nr_chips = min_chips; nr_chips <= max_chips; nr_chips <<= 1) { + + if (!cfi_interleave_supported(nr_chips)) + continue; + + cfi->interleave = nr_chips; + + /* Minimum device size. Don't look for one 8-bit device + in a 16-bit bus, etc. */ + type = map_bankwidth(map) / nr_chips; + + for (; type <= CFI_DEVICETYPE_X32; type<<=1) { + cfi->device_type = type; + + if (cp->probe_chip(map, 0, NULL, cfi)) + return 1; + } } return 0; } - typedef struct mtd_info *cfi_cmdset_fn_t(struct map_info *, int); 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) Index: drivers/mtd/chips/jedec.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/chips/jedec.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/chips/jedec.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/chips/jedec.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -11,10 +11,16 @@ * not going to guess how to send commands to them, plus I expect they will * all speak CFI.. * - * $Id: jedec.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: jedec.c,v 1.3 2004/11/03 00:04:43 joff Exp $ */ +#include +#include +#include #include +#include +#include +#include static struct mtd_info *jedec_probe(struct map_info *); static int jedec_probe8(struct map_info *map,unsigned long base, @@ -33,14 +39,51 @@ /* Listing of parts and sizes. We need this table to learn the sector size of the chip and the total length */ -static const struct JEDECTable JEDEC_table[] = - {{0x013D,"AMD Am29F017D",2*1024*1024,64*1024,MTD_CAP_NORFLASH}, - {0x01AD,"AMD Am29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH}, - {0x01D5,"AMD Am29F080",1*1024*1024,64*1024,MTD_CAP_NORFLASH}, - {0x01A4,"AMD Am29F040",512*1024,64*1024,MTD_CAP_NORFLASH}, - {0x20E3,"AMD Am29W040B",512*1024,64*1024,MTD_CAP_NORFLASH}, - {0xC2AD,"Macronix MX29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH}, - {}}; +static const struct JEDECTable JEDEC_table[] = { + { + .jedec = 0x013D, + .name = "AMD Am29F017D", + .size = 2*1024*1024, + .sectorsize = 64*1024, + .capabilities = MTD_CAP_NORFLASH + }, + { + .jedec = 0x01AD, + .name = "AMD Am29F016", + .size = 2*1024*1024, + .sectorsize = 64*1024, + .capabilities = MTD_CAP_NORFLASH + }, + { + .jedec = 0x01D5, + .name = "AMD Am29F080", + .size = 1*1024*1024, + .sectorsize = 64*1024, + .capabilities = MTD_CAP_NORFLASH + }, + { + .jedec = 0x01A4, + .name = "AMD Am29F040", + .size = 512*1024, + .sectorsize = 64*1024, + .capabilities = MTD_CAP_NORFLASH + }, + { + .jedec = 0x20E3, + .name = "AMD Am29W040B", + .size = 512*1024, + .sectorsize = 64*1024, + .capabilities = MTD_CAP_NORFLASH + }, + { + .jedec = 0xC2AD, + .name = "Macronix MX29F016", + .size = 2*1024*1024, + .sectorsize = 64*1024, + .capabilities = MTD_CAP_NORFLASH + }, + { .jedec = 0x0 } +}; static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id); static void jedec_sync(struct mtd_info *mtd) {}; @@ -54,9 +97,9 @@ static struct mtd_chip_driver jedec_chipdrv = { - probe: jedec_probe, - name: "jedec", - module: THIS_MODULE + .probe = jedec_probe, + .name = "jedec", + .module = THIS_MODULE }; /* Probe entry point */ @@ -85,7 +128,7 @@ { printk("mtd: Increase MAX_JEDEC_CHIPS, too many banks.\n"); kfree(MTD); - return 0; + return NULL; } for (Base = 0; Base < map->size; Base += my_bank_size) @@ -98,7 +141,7 @@ if (jedec_probe8(map,Base,priv) == 0) { printk("did recognize jedec chip\n"); kfree(MTD); - return 0; + return NULL; } } if (map->buswidth == 2) @@ -124,15 +167,14 @@ { printk("mtd: Failed. Device has incompatible mixed sector sizes\n"); kfree(MTD); - return 0; + return NULL; } } /* Generate a part name that includes the number of different chips and other configuration information */ count = 1; - strncpy(Part,map->name,sizeof(Part)-10); - Part[sizeof(Part)-11] = 0; + strlcpy(Part,map->name,sizeof(Part)-10); strcat(Part," "); Uniq = 0; for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) @@ -151,7 +193,7 @@ { printk("mtd: Internal Error, JEDEC not set\n"); kfree(MTD); - return 0; + return NULL; } if (Uniq != 0) @@ -179,7 +221,7 @@ if (!priv->size) { printk("priv->size is zero\n"); kfree(MTD); - return 0; + return NULL; } if (priv->size/my_bank_size) { if (priv->size/my_bank_size == 1) { @@ -198,7 +240,7 @@ { printk("mtd: Failed. Cannot handle unsymmetric banking\n"); kfree(MTD); - return 0; + return NULL; } } } @@ -209,8 +251,7 @@ // printk("Part: '%s'\n",Part); memset(MTD,0,sizeof(*MTD)); - // strncpy(MTD->name,Part,sizeof(MTD->name)); - // MTD->name[sizeof(MTD->name)-1] = 0; + // strlcpy(MTD->name,Part,sizeof(MTD->name)); MTD->name = map->name; MTD->type = MTD_NORFLASH; MTD->flags = MTD_CAP_NORFLASH; @@ -229,7 +270,7 @@ MTD->priv = map; map->fldrv_priv = priv; map->fldrv = &jedec_chipdrv; - MOD_INC_USE_COUNT; + __module_get(THIS_MODULE); return MTD; } @@ -344,15 +385,15 @@ for (I = 0; JEDEC_table[I].jedec != 0; I++) if (JEDEC_table[I].jedec == Id) return JEDEC_table + I; - return 0; + return NULL; } // Look for flash using an 8 bit bus interface static int jedec_probe8(struct map_info *map,unsigned long base, struct jedec_private *priv) { - #define flread(x) map->read8(map,base+x) - #define flwrite(v,x) map->write8(map,v,base+x) + #define flread(x) map_read8(map,base+x) + #define flwrite(v,x) map_write8(map,v,base+x) const unsigned long AutoSel1 = 0xAA; const unsigned long AutoSel2 = 0x55; @@ -411,8 +452,8 @@ static int jedec_probe32(struct map_info *map,unsigned long base, struct jedec_private *priv) { - #define flread(x) map->read32(map,base+((x)<<2)) - #define flwrite(v,x) map->write32(map,v,base+((x)<<2)) + #define flread(x) map_read32(map,base+((x)<<2)) + #define flwrite(v,x) map_write32(map,v,base+((x)<<2)) const unsigned long AutoSel1 = 0xAAAAAAAA; const unsigned long AutoSel2 = 0x55555555; @@ -490,7 +531,7 @@ { struct map_info *map = (struct map_info *)mtd->priv; - map->copy_from(map, buf, from, len); + map_copy_from(map, buf, from, len); *retlen = len; return 0; } @@ -514,7 +555,7 @@ get = priv->bank_fill[0] - offset; bank /= priv->bank_fill[0]; - map->copy_from(map,buf + *retlen,bank*my_bank_size + offset,get); + map_copy_from(map,buf + *retlen,bank*my_bank_size + offset,get); len -= get; *retlen += get; @@ -545,8 +586,8 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr) { // Does IO to the currently selected chip - #define flread(x) map->read8(map,chip->base+((x)<addrshift)) - #define flwrite(v,x) map->write8(map,v,chip->base+((x)<addrshift)) + #define flread(x) map_read8(map,chip->base+((x)<addrshift)) + #define flwrite(v,x) map_write8(map,v,chip->base+((x)<addrshift)) unsigned long Time = 0; unsigned long NoTime = 0; @@ -608,7 +649,7 @@ /* Poll the flash for erasure completion, specs say this can take as long as 480 seconds to do all the sectors (for a 2 meg flash). - Erasure time is dependant on chip age, temp and wear.. */ + Erasure time is dependent on chip age, temp and wear.. */ /* This being a generic routine assumes a 32 bit bus. It does read32s and bundles interleved chips into the same grouping. This will work @@ -651,19 +692,19 @@ or this is not really flash ;> */ switch (map->buswidth) { case 1: - Last[0] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off); - Last[1] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off); - Last[2] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off); + Last[0] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off); + Last[1] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off); + Last[2] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off); break; case 2: - Last[0] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off); - Last[1] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off); - Last[2] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off); + Last[0] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off); + Last[1] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off); + Last[2] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off); break; case 3: - Last[0] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off); - Last[1] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off); - Last[2] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off); + Last[0] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off); + Last[1] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off); + Last[2] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off); break; } Count = 3; @@ -699,13 +740,13 @@ switch (map->buswidth) { case 1: - Last[Count % 4] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off); + Last[Count % 4] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off); break; case 2: - Last[Count % 4] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off); + Last[Count % 4] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off); break; case 4: - Last[Count % 4] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off); + Last[Count % 4] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off); break; } Count++; @@ -739,8 +780,7 @@ //printk("done\n"); instr->state = MTD_ERASE_DONE; - if (instr->callback) - instr->callback(instr); + mtd_erase_callback(instr); return 0; #undef flread @@ -755,10 +795,10 @@ size_t *retlen, const u_char *buf) { /* Does IO to the currently selected chip. It takes the bank addressing - base (which is divisable by the chip size) adds the necesary lower bits - of addrshift (interleve index) and then adds the control register index. */ - #define flread(x) map->read8(map,base+(off&((1<addrshift)-1))+((x)<addrshift)) - #define flwrite(v,x) map->write8(map,v,base+(off&((1<addrshift)-1))+((x)<addrshift)) + base (which is divisible by the chip size) adds the necessary lower bits + of addrshift (interleave index) and then adds the control register index. */ + #define flread(x) map_read8(map,base+(off&((1<addrshift)-1))+((x)<addrshift)) + #define flwrite(v,x) map_write8(map,v,base+(off&((1<addrshift)-1))+((x)<addrshift)) struct map_info *map = (struct map_info *)mtd->priv; struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv; @@ -794,7 +834,7 @@ // Loop over this page for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++) { - unsigned char oldbyte = map->read8(map,base+off); + unsigned char oldbyte = map_read8(map,base+off); unsigned char Last[4]; unsigned long Count = 0; @@ -809,10 +849,10 @@ flwrite(0xAA,0x555); flwrite(0x55,0x2AA); flwrite(0xA0,0x555); - map->write8(map,*buf,base + off); - Last[0] = map->read8(map,base + off); - Last[1] = map->read8(map,base + off); - Last[2] = map->read8(map,base + off); + map_write8(map,*buf,base + off); + Last[0] = map_read8(map,base + off); + Last[1] = map_read8(map,base + off); + Last[2] = map_read8(map,base + off); /* Wait for the flash to finish the operation. We store the last 4 status bytes that have been retrieved so we can determine why @@ -820,7 +860,7 @@ failure */ for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] && Count < 10000; Count++) - Last[Count % 4] = map->read8(map,base + off); + Last[Count % 4] = map_read8(map,base + off); if (Last[(Count - 1) % 4] != *buf) { jedec_flash_failed(Last[(Count - 3) % 4]); Index: drivers/mtd/chips/jedec_probe.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/chips/jedec_probe.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/chips/jedec_probe.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/chips/jedec_probe.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,13 +1,16 @@ /* Common Flash Interface probe code. (C) 2000 Red Hat. GPL'd. - $Id: jedec_probe.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + $Id: jedec_probe.c,v 1.3 2004/11/03 00:04:43 joff Exp $ See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5) for the standard this probe goes back to. + + Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com */ #include #include +#include #include #include #include @@ -15,7 +18,9 @@ #include #include #include +#include +#include #include #include #include @@ -24,26 +29,35 @@ #define MANUFACTURER_AMD 0x0001 #define MANUFACTURER_ATMEL 0x001f #define MANUFACTURER_FUJITSU 0x0004 +#define MANUFACTURER_HYUNDAI 0x00AD #define MANUFACTURER_INTEL 0x0089 #define MANUFACTURER_MACRONIX 0x00C2 -#define MANUFACTURER_ST 0x0020 +#define MANUFACTURER_PMC 0x009D #define MANUFACTURER_SST 0x00BF +#define MANUFACTURER_ST 0x0020 #define MANUFACTURER_TOSHIBA 0x0098 +#define MANUFACTURER_WINBOND 0x00da /* AMD */ +#define AM29DL800BB 0x22C8 +#define AM29DL800BT 0x224A + #define AM29F800BB 0x2258 #define AM29F800BT 0x22D6 +#define AM29LV400BB 0x22BA +#define AM29LV400BT 0x22B9 #define AM29LV800BB 0x225B #define AM29LV800BT 0x22DA #define AM29LV160DT 0x22C4 #define AM29LV160DB 0x2249 #define AM29F017D 0x003D -#define AM29F016 0x00AD +#define AM29F016D 0x00AD #define AM29F080 0x00D5 #define AM29F040 0x00A4 #define AM29LV040B 0x004F #define AM29F032B 0x0041 +#define AM29F002T 0x00B0 /* Atmel */ #define AT49BV512 0x0003 @@ -54,6 +68,7 @@ #define AT49BV32XT 0x00C9 /* Fujitsu */ +#define MBM29F040C 0x00A4 #define MBM29LV650UE 0x22D7 #define MBM29LV320TE 0x22F6 #define MBM29LV320BE 0x22F9 @@ -61,6 +76,11 @@ #define MBM29LV160BE 0x2249 #define MBM29LV800BA 0x225B #define MBM29LV800TA 0x22DA +#define MBM29LV400TC 0x22B9 +#define MBM29LV400BC 0x22BA + +/* Hyundai */ +#define HY29F002T 0x00B0 /* Intel */ #define I28F004B3T 0x00d4 @@ -87,19 +107,33 @@ #define I82802AC 0x00ac /* Macronix */ +#define MX29LV040C 0x004F #define MX29LV160T 0x22C4 #define MX29LV160B 0x2249 #define MX29F016 0x00AD +#define MX29F002T 0x00B0 #define MX29F004T 0x0045 #define MX29F004B 0x0046 +/* PMC */ +#define PM49FL002 0x006D +#define PM49FL004 0x006E +#define PM49FL008 0x006A + /* ST - www.st.com */ -#define M29W800T 0x00D7 +#define M29W800DT 0x00D7 +#define M29W800DB 0x005B #define M29W160DT 0x22C4 #define M29W160DB 0x2249 #define M29W040B 0x00E3 +#define M50FW040 0x002C +#define M50FW080 0x002D +#define M50FW016 0x002E +#define M50LPW080 0x002F /* SST */ +#define SST29EE020 0x0010 +#define SST29LE020 0x0012 #define SST29EE512 0x005d #define SST29LE512 0x003d #define SST39LF800 0x2781 @@ -110,6 +144,8 @@ #define SST39LF040 0x00D7 #define SST39SF010A 0x00B5 #define SST39SF020A 0x00B6 +#define SST49LF004B 0x0060 +#define SST49LF008A 0x005a #define SST49LF030A 0x001C #define SST49LF040A 0x0051 #define SST49LF080A 0x005B @@ -122,16 +158,88 @@ #define TC58FVT641 0x0093 #define TC58FVB641 0x0095 +/* Winbond */ +#define W49V002A 0x00b0 + + +/* + * Unlock address sets for AMD command sets. + * Intel command sets use the MTD_UADDR_UNNECESSARY. + * Each identifier, except MTD_UADDR_UNNECESSARY, and + * MTD_UADDR_NO_SUPPORT must be defined below in unlock_addrs[]. + * MTD_UADDR_NOT_SUPPORTED must be 0 so that structure + * initialization need not require initializing all of the + * unlock addresses for all bit widths. + */ +enum uaddr { + MTD_UADDR_NOT_SUPPORTED = 0, /* data width not supported */ + MTD_UADDR_0x0555_0x02AA, + MTD_UADDR_0x0555_0x0AAA, + MTD_UADDR_0x5555_0x2AAA, + MTD_UADDR_0x0AAA_0x0555, + MTD_UADDR_DONT_CARE, /* Requires an arbitrary address */ + MTD_UADDR_UNNECESSARY, /* Does not require any address */ +}; + + +struct unlock_addr { + u32 addr1; + u32 addr2; +}; + + +/* + * I don't like the fact that the first entry in unlock_addrs[] + * exists, but is for MTD_UADDR_NOT_SUPPORTED - and, therefore, + * should not be used. The problem is that structures with + * initializers have extra fields initialized to 0. It is _very_ + * desireable to have the unlock address entries for unsupported + * data widths automatically initialized - that means that + * MTD_UADDR_NOT_SUPPORTED must be 0 and the first entry here + * must go unused. + */ +static const struct unlock_addr unlock_addrs[] = { + [MTD_UADDR_NOT_SUPPORTED] = { + .addr1 = 0xffff, + .addr2 = 0xffff + }, + + [MTD_UADDR_0x0555_0x02AA] = { + .addr1 = 0x0555, + .addr2 = 0x02aa + }, + + [MTD_UADDR_0x0555_0x0AAA] = { + .addr1 = 0x0555, + .addr2 = 0x0aaa + }, + + [MTD_UADDR_0x5555_0x2AAA] = { + .addr1 = 0x5555, + .addr2 = 0x2aaa + }, + + [MTD_UADDR_0x0AAA_0x0555] = { + .addr1 = 0x0AAA, + .addr2 = 0x0555 + }, + + [MTD_UADDR_DONT_CARE] = { + .addr1 = 0x0000, /* Doesn't matter which address */ + .addr2 = 0x0000 /* is used - must be last entry */ + } +}; + struct amd_flash_info { const __u16 mfr_id; const __u16 dev_id; const char *name; const int DevSize; - const int InterfaceDesc; const int NumEraseRegions; const int CmdSet; - const ulong regions[4]; + const __u8 uaddr[4]; /* unlock addrs for 8, 16, 32, 64 */ + const ulong regions[6]; }; #define ERASEINFO(size,blocks) (size<<8)|(blocks-1) @@ -145,810 +253,1500 @@ #define SIZE_4MiB 22 #define SIZE_8MiB 23 + +/* + * Please keep this list ordered by manufacturer! + * Fortunately, the list isn't searched often and so a + * slow, linear search isn't so bad. + */ static const struct amd_flash_info jedec_table[] = { { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29F032B, - name: "AMD AM29F032B", - DevSize: SIZE_4MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: {ERASEINFO(0x10000,64) - } - }, { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29LV160DT, - name: "AMD AM29LV160DT", - DevSize: SIZE_2MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 4, - regions: {ERASEINFO(0x10000,31), - ERASEINFO(0x08000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x04000,1) - } - }, { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29LV160DB, - name: "AMD AM29LV160DB", - DevSize: SIZE_2MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 4, - regions: {ERASEINFO(0x04000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x08000,1), - ERASEINFO(0x10000,31) - } - }, { - mfr_id: MANUFACTURER_TOSHIBA, - dev_id: TC58FVT160, - name: "Toshiba TC58FVT160", - DevSize: SIZE_2MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 4, - regions: {ERASEINFO(0x10000,31), - ERASEINFO(0x08000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x04000,1) - } - }, { - mfr_id: MANUFACTURER_TOSHIBA, - dev_id: TC58FVB160, - name: "Toshiba TC58FVB160", - DevSize: SIZE_2MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 4, - regions: {ERASEINFO(0x04000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x08000,1), - ERASEINFO(0x10000,31) - } - }, { - mfr_id: MANUFACTURER_TOSHIBA, - dev_id: TC58FVB321, - name: "Toshiba TC58FVB321", - DevSize: SIZE_4MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 2, - regions: {ERASEINFO(0x02000,8), - ERASEINFO(0x10000,63) - } - }, { - mfr_id: MANUFACTURER_TOSHIBA, - dev_id: TC58FVT321, - name: "Toshiba TC58FVT321", - DevSize: SIZE_4MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 2, - regions: {ERASEINFO(0x10000,63), - ERASEINFO(0x02000,8) - } - }, { - mfr_id: MANUFACTURER_TOSHIBA, - dev_id: TC58FVB641, - name: "Toshiba TC58FVB641", - DevSize: SIZE_8MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 2, - regions: {ERASEINFO(0x02000,8), - ERASEINFO(0x10000,127) - } - }, { - mfr_id: MANUFACTURER_TOSHIBA, - dev_id: TC58FVT641, - name: "Toshiba TC58FVT641", - DevSize: SIZE_8MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 2, - regions: {ERASEINFO(0x10000,127), - ERASEINFO(0x02000,8) - } - }, { - mfr_id: MANUFACTURER_FUJITSU, - dev_id: MBM29LV650UE, - name: "Fujitsu MBM29LV650UE", - DevSize: SIZE_8MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: {ERASEINFO(0x10000,128) - } - }, { - mfr_id: MANUFACTURER_FUJITSU, - dev_id: MBM29LV320TE, - name: "Fujitsu MBM29LV320TE", - DevSize: SIZE_4MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 2, - regions: {ERASEINFO(0x10000,63), - ERASEINFO(0x02000,8) - } - }, { - mfr_id: MANUFACTURER_FUJITSU, - dev_id: MBM29LV320BE, - name: "Fujitsu MBM29LV320BE", - DevSize: SIZE_4MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 2, - regions: {ERASEINFO(0x02000,8), - ERASEINFO(0x10000,63) - } - }, { - mfr_id: MANUFACTURER_FUJITSU, - dev_id: MBM29LV160TE, - name: "Fujitsu MBM29LV160TE", - DevSize: SIZE_2MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 4, - regions: {ERASEINFO(0x10000,31), - ERASEINFO(0x08000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x04000,1) - } - }, { - mfr_id: MANUFACTURER_FUJITSU, - dev_id: MBM29LV160BE, - name: "Fujitsu MBM29LV160BE", - DevSize: SIZE_2MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 4, - regions: {ERASEINFO(0x04000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x08000,1), - ERASEINFO(0x10000,31) - } - }, { - mfr_id: MANUFACTURER_FUJITSU, - dev_id: MBM29LV800BA, - name: "Fujitsu MBM29LV800BA", - DevSize: SIZE_1MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 4, - regions: {ERASEINFO(0x04000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x08000,1), - ERASEINFO(0x10000,15) - } - }, { - mfr_id: MANUFACTURER_FUJITSU, - dev_id: MBM29LV800TA, - name: "Fujitsu MBM29LV800TA", - DevSize: SIZE_1MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 4, - regions: {ERASEINFO(0x10000,15), - ERASEINFO(0x08000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x04000,1) - } - }, { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29LV800BB, - name: "AMD AM29LV800BB", - DevSize: SIZE_1MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 4, - regions: {ERASEINFO(0x04000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x08000,1), - ERASEINFO(0x10000,15), + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29F032B, + .name = "AMD AM29F032B", + .uaddr = { + [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ + }, + .DevSize = SIZE_4MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,64) + } + }, { + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29LV160DT, + .name = "AMD AM29LV160DT", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x10000,31), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1) + } + }, { + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29LV160DB, + .name = "AMD AM29LV160DB", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), + ERASEINFO(0x10000,31) + } + }, { + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29LV400BB, + .name = "AMD AM29LV400BB", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), + ERASEINFO(0x10000,7) + } + }, { + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29LV400BT, + .name = "AMD AM29LV400BT", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x10000,7), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1) + } + }, { + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29LV800BB, + .name = "AMD AM29LV800BB", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), + ERASEINFO(0x10000,15), + } + }, { +/* add DL */ + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29DL800BB, + .name = "AMD AM29DL800BB", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 6, + .regions = { + ERASEINFO(0x04000,1), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,4), + ERASEINFO(0x08000,1), + ERASEINFO(0x04000,1), + ERASEINFO(0x10000,14) + } + }, { + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29DL800BT, + .name = "AMD AM29DL800BT", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 6, + .regions = { + ERASEINFO(0x10000,14), + ERASEINFO(0x04000,1), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,4), + ERASEINFO(0x08000,1), + ERASEINFO(0x04000,1) + } + }, { + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29F800BB, + .name = "AMD AM29F800BB", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), + ERASEINFO(0x10000,15), + } + }, { + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29LV800BT, + .name = "AMD AM29LV800BT", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x10000,15), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1) + } + }, { + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29F800BT, + .name = "AMD AM29F800BT", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x10000,15), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1) + } + }, { + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29F017D, + .name = "AMD AM29F017D", + .uaddr = { + [0] = MTD_UADDR_DONT_CARE /* x8 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,32), + } + }, { + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29F016D, + .name = "AMD AM29F016D", + .uaddr = { + [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,32), + } + }, { + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29F080, + .name = "AMD AM29F080", + .uaddr = { + [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,16), + } + }, { + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29F040, + .name = "AMD AM29F040", + .uaddr = { + [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,8), + } + }, { + .mfr_id = MANUFACTURER_AMD, + .dev_id = AM29LV040B, + .name = "AMD AM29LV040B", + .uaddr = { + [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,8), } }, { mfr_id: MANUFACTURER_AMD, - dev_id: AM29F800BB, - name: "AMD AM29F800BB", - DevSize: SIZE_1MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 4, - regions: {ERASEINFO(0x04000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x08000,1), - ERASEINFO(0x10000,15), - } - }, { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29LV800BT, - name: "AMD AM29LV800BT", - DevSize: SIZE_1MiB, - CmdSet: P_ID_AMD_STD, + dev_id: AM29F002T, + name: "AMD AM29F002T", + DevSize: SIZE_256KiB, NumEraseRegions: 4, - regions: {ERASEINFO(0x10000,15), + regions: {ERASEINFO(0x10000,3), ERASEINFO(0x08000,1), ERASEINFO(0x02000,2), ERASEINFO(0x04000,1) } }, { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29F800BT, - name: "AMD AM29F800BT", - DevSize: SIZE_1MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 4, - regions: {ERASEINFO(0x10000,15), - ERASEINFO(0x08000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x04000,1) + .mfr_id = MANUFACTURER_ATMEL, + .dev_id = AT49BV512, + .name = "Atmel AT49BV512", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ + }, + .DevSize = SIZE_64KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,1) + } + }, { + .mfr_id = MANUFACTURER_ATMEL, + .dev_id = AT29LV512, + .name = "Atmel AT29LV512", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ + }, + .DevSize = SIZE_64KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x80,256), + ERASEINFO(0x80,256) } }, { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29LV800BB, - name: "AMD AM29LV800BB", - DevSize: SIZE_1MiB, - CmdSet: P_ID_AMD_STD, + .mfr_id = MANUFACTURER_ATMEL, + .dev_id = AT49BV16X, + .name = "Atmel AT49BV16X", + .uaddr = { + [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */ + [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 2, + .regions = { + ERASEINFO(0x02000,8), + ERASEINFO(0x10000,31) + } + }, { + .mfr_id = MANUFACTURER_ATMEL, + .dev_id = AT49BV16XT, + .name = "Atmel AT49BV16XT", + .uaddr = { + [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */ + [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 2, + .regions = { + ERASEINFO(0x10000,31), + ERASEINFO(0x02000,8) + } + }, { + .mfr_id = MANUFACTURER_ATMEL, + .dev_id = AT49BV32X, + .name = "Atmel AT49BV32X", + .uaddr = { + [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */ + [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */ + }, + .DevSize = SIZE_4MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 2, + .regions = { + ERASEINFO(0x02000,8), + ERASEINFO(0x10000,63) + } + }, { + .mfr_id = MANUFACTURER_ATMEL, + .dev_id = AT49BV32XT, + .name = "Atmel AT49BV32XT", + .uaddr = { + [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */ + [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */ + }, + .DevSize = SIZE_4MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 2, + .regions = { + ERASEINFO(0x10000,63), + ERASEINFO(0x02000,8) + } + }, { + .mfr_id = MANUFACTURER_FUJITSU, + .dev_id = MBM29F040C, + .name = "Fujitsu MBM29F040C", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,8) + } + }, { + .mfr_id = MANUFACTURER_FUJITSU, + .dev_id = MBM29LV650UE, + .name = "Fujitsu MBM29LV650UE", + .uaddr = { + [0] = MTD_UADDR_DONT_CARE /* x16 */ + }, + .DevSize = SIZE_8MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,128) + } + }, { + .mfr_id = MANUFACTURER_FUJITSU, + .dev_id = MBM29LV320TE, + .name = "Fujitsu MBM29LV320TE", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_4MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 2, + .regions = { + ERASEINFO(0x10000,63), + ERASEINFO(0x02000,8) + } + }, { + .mfr_id = MANUFACTURER_FUJITSU, + .dev_id = MBM29LV320BE, + .name = "Fujitsu MBM29LV320BE", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_4MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 2, + .regions = { + ERASEINFO(0x02000,8), + ERASEINFO(0x10000,63) + } + }, { + .mfr_id = MANUFACTURER_FUJITSU, + .dev_id = MBM29LV160TE, + .name = "Fujitsu MBM29LV160TE", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x10000,31), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1) + } + }, { + .mfr_id = MANUFACTURER_FUJITSU, + .dev_id = MBM29LV160BE, + .name = "Fujitsu MBM29LV160BE", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), + ERASEINFO(0x10000,31) + } + }, { + .mfr_id = MANUFACTURER_FUJITSU, + .dev_id = MBM29LV800BA, + .name = "Fujitsu MBM29LV800BA", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), + ERASEINFO(0x10000,15) + } + }, { + .mfr_id = MANUFACTURER_FUJITSU, + .dev_id = MBM29LV800TA, + .name = "Fujitsu MBM29LV800TA", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x10000,15), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1) + } + }, { + .mfr_id = MANUFACTURER_FUJITSU, + .dev_id = MBM29LV400BC, + .name = "Fujitsu MBM29LV400BC", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), + ERASEINFO(0x10000,7) + } + }, { + .mfr_id = MANUFACTURER_FUJITSU, + .dev_id = MBM29LV400TC, + .name = "Fujitsu MBM29LV400TC", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x10000,7), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1) + } + }, { + mfr_id: MANUFACTURER_HYUNDAI, + dev_id: HY29F002T, + name: "Hyundai HY29F002T", + DevSize: SIZE_256KiB, NumEraseRegions: 4, - regions: {ERASEINFO(0x10000,15), + regions: {ERASEINFO(0x10000,3), ERASEINFO(0x08000,1), ERASEINFO(0x02000,2), ERASEINFO(0x04000,1) } }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F004B3B, - name: "Intel 28F004B3B", - DevSize: SIZE_512KiB, - CmdSet: P_ID_INTEL_STD, - NumEraseRegions: 2, - regions: { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F004B3B, + .name = "Intel 28F004B3B", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 2, + .regions = { ERASEINFO(0x02000, 8), ERASEINFO(0x10000, 7), } }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F004B3T, - name: "Intel 28F004B3T", - DevSize: SIZE_512KiB, - CmdSet: P_ID_INTEL_STD, - NumEraseRegions: 2, - regions: { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F004B3T, + .name = "Intel 28F004B3T", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 2, + .regions = { ERASEINFO(0x10000, 7), ERASEINFO(0x02000, 8), } }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F400B3B, - name: "Intel 28F400B3B", - DevSize: SIZE_512KiB, - CmdSet: P_ID_INTEL_STD, - NumEraseRegions: 2, - regions: { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F400B3B, + .name = "Intel 28F400B3B", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + [1] = MTD_UADDR_UNNECESSARY, /* x16 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 2, + .regions = { ERASEINFO(0x02000, 8), ERASEINFO(0x10000, 7), } }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F400B3T, - name: "Intel 28F400B3T", - DevSize: SIZE_512KiB, - CmdSet: P_ID_INTEL_STD, - NumEraseRegions: 2, - regions: { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F400B3T, + .name = "Intel 28F400B3T", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + [1] = MTD_UADDR_UNNECESSARY, /* x16 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 2, + .regions = { ERASEINFO(0x10000, 7), ERASEINFO(0x02000, 8), } }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F008B3B, - name: "Intel 28F008B3B", - DevSize: SIZE_1MiB, - CmdSet: P_ID_INTEL_STD, - NumEraseRegions: 2, - regions: { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F008B3B, + .name = "Intel 28F008B3B", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 2, + .regions = { ERASEINFO(0x02000, 8), ERASEINFO(0x10000, 15), } }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F008B3T, - name: "Intel 28F008B3T", - DevSize: SIZE_1MiB, - CmdSet: P_ID_INTEL_STD, - NumEraseRegions: 2, - regions: { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F008B3T, + .name = "Intel 28F008B3T", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 2, + .regions = { ERASEINFO(0x10000, 15), ERASEINFO(0x02000, 8), } }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F008S5, - name: "Intel 28F008S5", - DevSize: SIZE_1MiB, - CmdSet: P_ID_INTEL_EXT, - NumEraseRegions: 1, - regions: {ERASEINFO(0x10000,16), - } - }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F016S5, - name: "Intel 28F016S5", - DevSize: SIZE_2MiB, - CmdSet: P_ID_INTEL_EXT, - NumEraseRegions: 1, - regions: {ERASEINFO(0x10000,32), - } - }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F008SA, - name: "Intel 28F008SA", - DevSize: SIZE_1MiB, - CmdSet: P_ID_INTEL_STD, - NumEraseRegions: 1, - regions: { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F008S5, + .name = "Intel 28F008S5", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_INTEL_EXT, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,16), + } + }, { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F016S5, + .name = "Intel 28F016S5", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_INTEL_EXT, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,32), + } + }, { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F008SA, + .name = "Intel 28F008SA", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 1, + .regions = { ERASEINFO(0x10000, 16), } }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F800B3B, - name: "Intel 28F800B3B", - DevSize: SIZE_1MiB, - CmdSet: P_ID_INTEL_STD, - NumEraseRegions: 2, - regions: { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F800B3B, + .name = "Intel 28F800B3B", + .uaddr = { + [1] = MTD_UADDR_UNNECESSARY, /* x16 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 2, + .regions = { ERASEINFO(0x02000, 8), ERASEINFO(0x10000, 15), } }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F800B3T, - name: "Intel 28F800B3T", - DevSize: SIZE_1MiB, - CmdSet: P_ID_INTEL_STD, - NumEraseRegions: 2, - regions: { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F800B3T, + .name = "Intel 28F800B3T", + .uaddr = { + [1] = MTD_UADDR_UNNECESSARY, /* x16 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 2, + .regions = { ERASEINFO(0x10000, 15), ERASEINFO(0x02000, 8), } }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F016B3B, - name: "Intel 28F016B3B", - DevSize: SIZE_2MiB, - CmdSet: P_ID_INTEL_STD, - NumEraseRegions: 2, - regions: { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F016B3B, + .name = "Intel 28F016B3B", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 2, + .regions = { ERASEINFO(0x02000, 8), ERASEINFO(0x10000, 31), } }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F016S3, - name: "Intel I28F016S3", - DevSize: SIZE_2MiB, - CmdSet: P_ID_INTEL_STD, - NumEraseRegions: 1, - regions: { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F016S3, + .name = "Intel I28F016S3", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 1, + .regions = { ERASEINFO(0x10000, 32), } }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F016B3T, - name: "Intel 28F016B3T", - DevSize: SIZE_2MiB, - CmdSet: P_ID_INTEL_STD, - NumEraseRegions: 2, - regions: { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F016B3T, + .name = "Intel 28F016B3T", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 2, + .regions = { ERASEINFO(0x10000, 31), ERASEINFO(0x02000, 8), } }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F160B3B, - name: "Intel 28F160B3B", - DevSize: SIZE_2MiB, - CmdSet: P_ID_INTEL_STD, - NumEraseRegions: 2, - regions: { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F160B3B, + .name = "Intel 28F160B3B", + .uaddr = { + [1] = MTD_UADDR_UNNECESSARY, /* x16 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 2, + .regions = { ERASEINFO(0x02000, 8), ERASEINFO(0x10000, 31), } }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F160B3T, - name: "Intel 28F160B3T", - DevSize: SIZE_2MiB, - CmdSet: P_ID_INTEL_STD, - NumEraseRegions: 2, - regions: { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F160B3T, + .name = "Intel 28F160B3T", + .uaddr = { + [1] = MTD_UADDR_UNNECESSARY, /* x16 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 2, + .regions = { ERASEINFO(0x10000, 31), ERASEINFO(0x02000, 8), } }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F320B3B, - name: "Intel 28F320B3B", - DevSize: SIZE_4MiB, - CmdSet: P_ID_INTEL_STD, - NumEraseRegions: 2, - regions: { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F320B3B, + .name = "Intel 28F320B3B", + .uaddr = { + [1] = MTD_UADDR_UNNECESSARY, /* x16 */ + }, + .DevSize = SIZE_4MiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 2, + .regions = { ERASEINFO(0x02000, 8), ERASEINFO(0x10000, 63), } }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F320B3T, - name: "Intel 28F320B3T", - DevSize: SIZE_4MiB, - CmdSet: P_ID_INTEL_STD, - NumEraseRegions: 2, - regions: { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F320B3T, + .name = "Intel 28F320B3T", + .uaddr = { + [1] = MTD_UADDR_UNNECESSARY, /* x16 */ + }, + .DevSize = SIZE_4MiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 2, + .regions = { ERASEINFO(0x10000, 63), ERASEINFO(0x02000, 8), } }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F640B3B, - name: "Intel 28F640B3B", - DevSize: SIZE_8MiB, - CmdSet: P_ID_INTEL_STD, - NumEraseRegions: 2, - regions: { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F640B3B, + .name = "Intel 28F640B3B", + .uaddr = { + [1] = MTD_UADDR_UNNECESSARY, /* x16 */ + }, + .DevSize = SIZE_8MiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 2, + .regions = { ERASEINFO(0x02000, 8), ERASEINFO(0x10000, 127), } }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I28F640B3T, - name: "Intel 28F640B3T", - DevSize: SIZE_8MiB, - CmdSet: P_ID_INTEL_STD, - NumEraseRegions: 2, - regions: { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I28F640B3T, + .name = "Intel 28F640B3T", + .uaddr = { + [1] = MTD_UADDR_UNNECESSARY, /* x16 */ + }, + .DevSize = SIZE_8MiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 2, + .regions = { ERASEINFO(0x10000, 127), ERASEINFO(0x02000, 8), } }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I82802AB, - name: "Intel 82802AB", - DevSize: SIZE_512KiB, - CmdSet: P_ID_INTEL_EXT, - NumEraseRegions: 1, - regions: {ERASEINFO(0x10000,8), - } - }, { - mfr_id: MANUFACTURER_INTEL, - dev_id: I82802AC, - name: "Intel 82802AC", - DevSize: SIZE_1MiB, - CmdSet: P_ID_INTEL_EXT, - NumEraseRegions: 1, - regions: {ERASEINFO(0x10000,16), - } - }, { - mfr_id: MANUFACTURER_ST, - dev_id: M29W800T, - name: "ST M29W800T", - DevSize: SIZE_1MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 4, - regions: {ERASEINFO(0x10000,15), - ERASEINFO(0x08000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x04000,1) - } - }, { - mfr_id: MANUFACTURER_ST, - dev_id: M29W160DT, - name: "ST M29W160DT", - DevSize: SIZE_2MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 4, - regions: {ERASEINFO(0x10000,31), - ERASEINFO(0x08000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x04000,1) - } - }, { - mfr_id: MANUFACTURER_ST, - dev_id: M29W160DB, - name: "ST M29W160DB", - DevSize: SIZE_2MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 4, - regions: {ERASEINFO(0x04000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x08000,1), - ERASEINFO(0x10000,31) - } - }, { - mfr_id: MANUFACTURER_ATMEL, - dev_id: AT49BV512, - name: "Atmel AT49BV512", - DevSize: SIZE_64KiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: {ERASEINFO(0x10000,1) - } - }, { - mfr_id: MANUFACTURER_ATMEL, - dev_id: AT29LV512, - name: "Atmel AT29LV512", - DevSize: SIZE_64KiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: { - ERASEINFO(0x80,256), - ERASEINFO(0x80,256) + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I82802AB, + .name = "Intel 82802AB", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_INTEL_EXT, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,8), + } + }, { + .mfr_id = MANUFACTURER_INTEL, + .dev_id = I82802AC, + .name = "Intel 82802AC", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_INTEL_EXT, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,16), + } + }, { + .mfr_id = MANUFACTURER_MACRONIX, + .dev_id = MX29LV040C, + .name = "Macronix MX29LV040C", + .uaddr = { + [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,8), + } + }, { + .mfr_id = MANUFACTURER_MACRONIX, + .dev_id = MX29LV160T, + .name = "MXIC MX29LV160T", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x10000,31), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1) + } + }, { + .mfr_id = MANUFACTURER_MACRONIX, + .dev_id = MX29LV160B, + .name = "MXIC MX29LV160B", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), + ERASEINFO(0x10000,31) + } + }, { + .mfr_id = MANUFACTURER_MACRONIX, + .dev_id = MX29F016, + .name = "Macronix MX29F016", + .uaddr = { + [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,32), } - }, { - mfr_id: MANUFACTURER_ATMEL, - dev_id: AT49BV16X, - name: "Atmel AT49BV16X", - DevSize: SIZE_2MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 2, - regions: {ERASEINFO(0x02000,8), - ERASEINFO(0x10000,31) - } - }, { - mfr_id: MANUFACTURER_ATMEL, - dev_id: AT49BV16XT, - name: "Atmel AT49BV16XT", - DevSize: SIZE_2MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 2, - regions: {ERASEINFO(0x10000,31), - ERASEINFO(0x02000,8) - } - }, { - mfr_id: MANUFACTURER_ATMEL, - dev_id: AT49BV32X, - name: "Atmel AT49BV32X", - DevSize: SIZE_4MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 2, - regions: {ERASEINFO(0x02000,8), - ERASEINFO(0x10000,63) - } - }, { - mfr_id: MANUFACTURER_ATMEL, - dev_id: AT49BV32XT, - name: "Atmel AT49BV32XT", - DevSize: SIZE_4MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 2, - regions: {ERASEINFO(0x10000,63), - ERASEINFO(0x02000,8) - } - }, { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29F017D, - name: "AMD AM29F017D", - DevSize: SIZE_2MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: {ERASEINFO(0x10000,32), - } - }, { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29F016, - name: "AMD AM29F016", - DevSize: SIZE_2MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: {ERASEINFO(0x10000,32), - } - }, { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29F080, - name: "AMD AM29F080", - DevSize: SIZE_1MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: {ERASEINFO(0x10000,16), - } - }, { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29F040, - name: "AMD AM29F040", - DevSize: SIZE_512KiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: {ERASEINFO(0x10000,8), - } - }, { - mfr_id: MANUFACTURER_AMD, - dev_id: AM29LV040B, - name: "AMD AM29LV040B", - DevSize: SIZE_512KiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: {ERASEINFO(0x10000,8), + }, { + .mfr_id = MANUFACTURER_MACRONIX, + .dev_id = MX29F004T, + .name = "Macronix MX29F004T", + .uaddr = { + [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x10000,7), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1), } }, { - mfr_id: MANUFACTURER_ST, - dev_id: M29W040B, - name: "ST M29W040B", - DevSize: SIZE_512KiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: {ERASEINFO(0x10000,8), + .mfr_id = MANUFACTURER_MACRONIX, + .dev_id = MX29F004B, + .name = "Macronix MX29F004B", + .uaddr = { + [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), + ERASEINFO(0x10000,7), } }, { mfr_id: MANUFACTURER_MACRONIX, - dev_id: MX29LV160T, - name: "MXIC MX29LV160T", - DevSize: SIZE_2MiB, - CmdSet: P_ID_AMD_STD, + dev_id: MX29F002T, + name: "Macronix MX29F002T", + DevSize: SIZE_256KiB, NumEraseRegions: 4, - regions: {ERASEINFO(0x10000,31), + regions: {ERASEINFO(0x10000,3), ERASEINFO(0x08000,1), ERASEINFO(0x02000,2), ERASEINFO(0x04000,1) } }, { - mfr_id: MANUFACTURER_MACRONIX, - dev_id: MX29LV160B, - name: "MXIC MX29LV160B", - DevSize: SIZE_2MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 4, - regions: {ERASEINFO(0x04000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x08000,1), - ERASEINFO(0x10000,31) + .mfr_id = MANUFACTURER_PMC, + .dev_id = PM49FL002, + .name = "PMC Pm49FL002", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ + }, + .DevSize = SIZE_256KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO( 0x01000, 64 ) + } + }, { + .mfr_id = MANUFACTURER_PMC, + .dev_id = PM49FL004, + .name = "PMC Pm49FL004", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO( 0x01000, 128 ) + } + }, { + .mfr_id = MANUFACTURER_PMC, + .dev_id = PM49FL008, + .name = "PMC Pm49FL008", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO( 0x01000, 256 ) } - }, { - mfr_id: MANUFACTURER_MACRONIX, - dev_id: MX29F016, - name: "Macronix MX29F016", - DevSize: SIZE_2MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: {ERASEINFO(0x10000,32), + }, { + .mfr_id = MANUFACTURER_SST, + .dev_id = SST39LF512, + .name = "SST 39LF512", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ + }, + .DevSize = SIZE_64KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x01000,16), } }, { - mfr_id: MANUFACTURER_MACRONIX, - dev_id: MX29F004T, - name: "Macronix MX29F004T", - DevSize: SIZE_512KiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 4, - regions: {ERASEINFO(0x10000,7), - ERASEINFO(0x08000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x04000,1), + .mfr_id = MANUFACTURER_SST, + .dev_id = SST39LF010, + .name = "SST 39LF010", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ + }, + .DevSize = SIZE_128KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x01000,32), } }, { - mfr_id: MANUFACTURER_MACRONIX, - dev_id: MX29F004B, - name: "Macronix MX29F004B", - DevSize: SIZE_512KiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 4, - regions: {ERASEINFO(0x04000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x08000,1), - ERASEINFO(0x10000,7), + .mfr_id = MANUFACTURER_SST, + .dev_id = SST29EE020, + .name = "SST 29EE020", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ + }, + .DevSize = SIZE_256KiB, + .CmdSet = P_ID_SST_PAGE, + .NumEraseRegions= 1, + regions: {ERASEINFO(0x01000,64), + } + }, { + .mfr_id = MANUFACTURER_SST, + .dev_id = SST29LE020, + .name = "SST 29LE020", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ + }, + .DevSize = SIZE_256KiB, + .CmdSet = P_ID_SST_PAGE, + .NumEraseRegions= 1, + regions: {ERASEINFO(0x01000,64), + } + }, { + .mfr_id = MANUFACTURER_SST, + .dev_id = SST39LF020, + .name = "SST 39LF020", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ + }, + .DevSize = SIZE_256KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x01000,64), } }, { - mfr_id: MANUFACTURER_SST, - dev_id: SST39LF512, - name: "SST 39LF512", - DevSize: SIZE_64KiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: {ERASEINFO(0x01000,16), + .mfr_id = MANUFACTURER_SST, + .dev_id = SST39LF040, + .name = "SST 39LF040", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x01000,128), } }, { - mfr_id: MANUFACTURER_SST, - dev_id: SST39LF010, - name: "SST 39LF010", - DevSize: SIZE_128KiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: {ERASEINFO(0x01000,32), + .mfr_id = MANUFACTURER_SST, + .dev_id = SST39SF010A, + .name = "SST 39SF010A", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ + }, + .DevSize = SIZE_128KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x01000,32), } }, { - mfr_id: MANUFACTURER_SST, - dev_id: SST39LF020, - name: "SST 39LF020", - DevSize: SIZE_256KiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: {ERASEINFO(0x01000,64), + .mfr_id = MANUFACTURER_SST, + .dev_id = SST39SF020A, + .name = "SST 39SF020A", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ + }, + .DevSize = SIZE_256KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x01000,64), + } + }, { + .mfr_id = MANUFACTURER_SST, + .dev_id = SST49LF004B, + .name = "SST 49LF004B", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x01000,128), + } + }, { + .mfr_id = MANUFACTURER_SST, + .dev_id = SST49LF008A, + .name = "SST 49LF008A", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x01000,256), + } + }, { + .mfr_id = MANUFACTURER_SST, + .dev_id = SST49LF030A, + .name = "SST 49LF030A", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x01000,96), + } + }, { + .mfr_id = MANUFACTURER_SST, + .dev_id = SST49LF040A, + .name = "SST 49LF040A", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x01000,128), + } + }, { + .mfr_id = MANUFACTURER_SST, + .dev_id = SST49LF080A, + .name = "SST 49LF080A", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x01000,256), + } + }, { + .mfr_id = MANUFACTURER_SST, /* should be CFI */ + .dev_id = SST39LF160, + .name = "SST 39LF160", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */ + [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 2, + .regions = { + ERASEINFO(0x1000,256), + ERASEINFO(0x1000,256) + } + + }, { + .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */ + .dev_id = M29W800DT, + .name = "ST M29W800DT", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */ + [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x10000,15), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1) + } + }, { + .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */ + .dev_id = M29W800DB, + .name = "ST M29W800DB", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */ + [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), + ERASEINFO(0x10000,15) + } + }, { + .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */ + .dev_id = M29W160DT, + .name = "ST M29W160DT", + .uaddr = { + [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x10000,31), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1) + } + }, { + .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */ + .dev_id = M29W160DB, + .name = "ST M29W160DB", + .uaddr = { + [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), + ERASEINFO(0x10000,31) } }, { - mfr_id: MANUFACTURER_SST, - dev_id: SST39LF040, - name: "SST 39LF040", - DevSize: SIZE_512KiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: {ERASEINFO(0x01000,128), + .mfr_id = MANUFACTURER_ST, + .dev_id = M29W040B, + .name = "ST M29W040B", + .uaddr = { + [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,8), } }, { - mfr_id: MANUFACTURER_SST, - dev_id: SST39SF010A, - name: "SST 39SF010A", - DevSize: SIZE_128KiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: {ERASEINFO(0x01000,32), + .mfr_id = MANUFACTURER_ST, + .dev_id = M50FW040, + .name = "ST M50FW040", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + }, + .DevSize = SIZE_512KiB, + .CmdSet = P_ID_INTEL_EXT, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,8), } }, { - mfr_id: MANUFACTURER_SST, - dev_id: SST39SF020A, - name: "SST 39SF020A", - DevSize: SIZE_256KiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: {ERASEINFO(0x01000,64), - } - }, { - mfr_id: MANUFACTURER_SST, - dev_id: SST49LF030A, - name: "SST 49LF030A", - DevSize: SIZE_512KiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: {ERASEINFO(0x01000,96), - } - }, { - mfr_id: MANUFACTURER_SST, - dev_id: SST49LF040A, - name: "SST 49LF040A", - DevSize: SIZE_512KiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: {ERASEINFO(0x01000,128), - } - }, { - mfr_id: MANUFACTURER_SST, - dev_id: SST49LF080A, - name: "SST 49LF080A", - DevSize: SIZE_1MiB, - CmdSet: P_ID_AMD_STD, - NumEraseRegions: 1, - regions: {ERASEINFO(0x01000,256), + .mfr_id = MANUFACTURER_ST, + .dev_id = M50FW080, + .name = "ST M50FW080", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_INTEL_EXT, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,16), + } + }, { + .mfr_id = MANUFACTURER_ST, + .dev_id = M50FW016, + .name = "ST M50FW016", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_INTEL_EXT, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,32), + } + }, { + .mfr_id = MANUFACTURER_ST, + .dev_id = M50LPW080, + .name = "ST M50LPW080", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + }, + .DevSize = SIZE_1MiB, + .CmdSet = P_ID_INTEL_EXT, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x10000,16), + } + }, { + .mfr_id = MANUFACTURER_TOSHIBA, + .dev_id = TC58FVT160, + .name = "Toshiba TC58FVT160", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x10000,31), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1) + } + }, { + .mfr_id = MANUFACTURER_TOSHIBA, + .dev_id = TC58FVB160, + .name = "Toshiba TC58FVB160", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ + }, + .DevSize = SIZE_2MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), + ERASEINFO(0x10000,31) + } + }, { + .mfr_id = MANUFACTURER_TOSHIBA, + .dev_id = TC58FVB321, + .name = "Toshiba TC58FVB321", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ + }, + .DevSize = SIZE_4MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 2, + .regions = { + ERASEINFO(0x02000,8), + ERASEINFO(0x10000,63) + } + }, { + .mfr_id = MANUFACTURER_TOSHIBA, + .dev_id = TC58FVT321, + .name = "Toshiba TC58FVT321", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ + }, + .DevSize = SIZE_4MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 2, + .regions = { + ERASEINFO(0x10000,63), + ERASEINFO(0x02000,8) + } + }, { + .mfr_id = MANUFACTURER_TOSHIBA, + .dev_id = TC58FVB641, + .name = "Toshiba TC58FVB641", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_8MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 2, + .regions = { + ERASEINFO(0x02000,8), + ERASEINFO(0x10000,127) + } + }, { + .mfr_id = MANUFACTURER_TOSHIBA, + .dev_id = TC58FVT641, + .name = "Toshiba TC58FVT641", + .uaddr = { + [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ + [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ + }, + .DevSize = SIZE_8MiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 2, + .regions = { + ERASEINFO(0x10000,127), + ERASEINFO(0x02000,8) + } + }, { + .mfr_id = MANUFACTURER_WINBOND, + .dev_id = W49V002A, + .name = "Winbond W49V002A", + .uaddr = { + [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ + }, + .DevSize = SIZE_256KiB, + .CmdSet = P_ID_AMD_STD, + .NumEraseRegions= 4, + .regions = { + ERASEINFO(0x10000, 3), + ERASEINFO(0x08000, 1), + ERASEINFO(0x02000, 2), + ERASEINFO(0x04000, 1), } - } + } }; static int cfi_jedec_setup(struct cfi_private *p_cfi, int index); static int jedec_probe_chip(struct map_info *map, __u32 base, - struct flchip *chips, struct cfi_private *cfi); + unsigned long *chip_map, struct cfi_private *cfi); struct mtd_info *jedec_probe(struct map_info *map); static inline u32 jedec_read_mfr(struct map_info *map, __u32 base, struct cfi_private *cfi) { - u32 result, mask; + map_word result; + unsigned long mask; + u32 ofs = cfi_build_cmd_addr(0, cfi_interleave(cfi), cfi->device_type); mask = (1 << (cfi->device_type * 8)) -1; - result = cfi_read(map, base); - result &= mask; - return result; + result = map_read(map, base + ofs); + return result.x[0] & mask; } static inline u32 jedec_read_id(struct map_info *map, __u32 base, struct cfi_private *cfi) { - int osf; - u32 result, mask; - osf = cfi->interleave *cfi->device_type; + map_word result; + unsigned long mask; + u32 ofs = cfi_build_cmd_addr(1, cfi_interleave(cfi), cfi->device_type); mask = (1 << (cfi->device_type * 8)) -1; - result = cfi_read(map, base + osf); - result &= mask; - return result; + result = map_read(map, base + ofs); + return result.x[0] & mask; } static inline void jedec_reset(u32 base, struct map_info *map, struct cfi_private *cfi) { /* Reset */ - cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); + + /* after checking the datasheets for SST, MACRONIX and ATMEL + * (oh and incidentaly the jedec spec - 3.5.3.3) the reset + * sequence is *supposed* to be 0xaa at 0x5555, 0x55 at + * 0x2aaa, 0xF0 at 0x5555 this will not affect the AMD chips + * as they will ignore the writes and dont care what address + * the F0 is written to */ + if(cfi->addr_unlock1) { + DEBUG( MTD_DEBUG_LEVEL3, + "reset unlock called %x %x \n", + cfi->addr_unlock1,cfi->addr_unlock2); + cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL); + } + + cfi_send_gen_cmd(0xF0, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); /* Some misdesigned intel chips do not respond for 0xF0 for a reset, * so ensure we're in read mode. Send both the Intel and the AMD command * for this. Intel uses 0xff for this, AMD uses 0xff for NOP, so * this should be safe. */ cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); + /* FIXME - should have reset delay before continuing */ +} + +static inline __u8 finfo_uaddr(const struct amd_flash_info *finfo, int device_type) +{ + int uaddr_idx; + __u8 uaddr = MTD_UADDR_NOT_SUPPORTED; + + switch ( device_type ) { + case CFI_DEVICETYPE_X8: uaddr_idx = 0; break; + case CFI_DEVICETYPE_X16: uaddr_idx = 1; break; + case CFI_DEVICETYPE_X32: uaddr_idx = 2; break; + default: + printk(KERN_NOTICE "MTD: %s(): unknown device_type %d\n", + __func__, device_type); + goto uaddr_done; + } + + uaddr = finfo->uaddr[uaddr_idx]; + + if (uaddr != MTD_UADDR_NOT_SUPPORTED ) { + /* ASSERT("The unlock addresses for non-8-bit mode + are bollocks. We don't really need an array."); */ + uaddr = finfo->uaddr[0]; + } + + uaddr_done: + return uaddr; } + + static int cfi_jedec_setup(struct cfi_private *p_cfi, int index) { int i,num_erase_regions; + __u8 uaddr; printk("Found: %s\n",jedec_table[index].name); @@ -970,42 +1768,166 @@ for (i=0; icfiq->EraseRegionInfo[i] = jedec_table[index].regions[i]; } - p_cfi->cmdset_priv = 0; + p_cfi->cmdset_priv = NULL; + + /* This may be redundant for some cases, but it doesn't hurt */ + p_cfi->mfr = jedec_table[index].mfr_id; + p_cfi->id = jedec_table[index].dev_id; + + uaddr = finfo_uaddr(&jedec_table[index], p_cfi->device_type); + if ( uaddr == MTD_UADDR_NOT_SUPPORTED ) { + kfree( p_cfi->cfiq ); + return 0; + } + + /* Mask out address bits which are smaller than the device type */ + p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1; + p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2; + return 1; /* ok */ } + +/* + * There is a BIG problem properly ID'ing the JEDEC devic and guaranteeing + * the mapped address, unlock addresses, and proper chip ID. This function + * attempts to minimize errors. It is doubtfull that this probe will ever + * be perfect - consequently there should be some module parameters that + * could be manually specified to force the chip info. + */ +static inline int jedec_match( __u32 base, + struct map_info *map, + struct cfi_private *cfi, + const struct amd_flash_info *finfo ) +{ + int rc = 0; /* failure until all tests pass */ + u32 mfr, id; + __u8 uaddr; + + /* + * The IDs must match. For X16 and X32 devices operating in + * a lower width ( X8 or X16 ), the device ID's are usually just + * the lower byte(s) of the larger device ID for wider mode. If + * a part is found that doesn't fit this assumption (device id for + * smaller width mode is completely unrealated to full-width mode) + * then the jedec_table[] will have to be augmented with the IDs + * for different widths. + */ + switch (cfi->device_type) { + case CFI_DEVICETYPE_X8: + mfr = (__u8)finfo->mfr_id; + id = (__u8)finfo->dev_id; + break; + case CFI_DEVICETYPE_X16: + mfr = (__u16)finfo->mfr_id; + id = (__u16)finfo->dev_id; + break; + case CFI_DEVICETYPE_X32: + mfr = (__u16)finfo->mfr_id; + id = (__u32)finfo->dev_id; + break; + default: + printk(KERN_WARNING + "MTD %s(): Unsupported device type %d\n", + __func__, cfi->device_type); + goto match_done; + } + if ( cfi->mfr != mfr || cfi->id != id ) { + goto match_done; + } + + /* the part size must fit in the memory window */ + DEBUG( MTD_DEBUG_LEVEL3, + "MTD %s(): Check fit 0x%.8x + 0x%.8x = 0x%.8x\n", + __func__, base, 1 << finfo->DevSize, base + (1 << finfo->DevSize) ); + if ( base + cfi_interleave(cfi) * ( 1 << finfo->DevSize ) > map->size ) { + DEBUG( MTD_DEBUG_LEVEL3, + "MTD %s(): 0x%.4x 0x%.4x %dKiB doesn't fit\n", + __func__, finfo->mfr_id, finfo->dev_id, + 1 << finfo->DevSize ); + goto match_done; + } + + uaddr = finfo_uaddr(finfo, cfi->device_type); + if ( uaddr == MTD_UADDR_NOT_SUPPORTED ) { + goto match_done; + } + + DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): check unlock addrs 0x%.4x 0x%.4x\n", + __func__, cfi->addr_unlock1, cfi->addr_unlock2 ); + if ( MTD_UADDR_UNNECESSARY != uaddr && MTD_UADDR_DONT_CARE != uaddr + && ( unlock_addrs[uaddr].addr1 != cfi->addr_unlock1 || + unlock_addrs[uaddr].addr2 != cfi->addr_unlock2 ) ) { + DEBUG( MTD_DEBUG_LEVEL3, + "MTD %s(): 0x%.4x 0x%.4x did not match\n", + __func__, + unlock_addrs[uaddr].addr1, + unlock_addrs[uaddr].addr2); + goto match_done; + } + + /* + * Make sure the ID's dissappear when the device is taken out of + * ID mode. The only time this should fail when it should succeed + * is when the ID's are written as data to the same + * addresses. For this rare and unfortunate case the chip + * cannot be probed correctly. + * FIXME - write a driver that takes all of the chip info as + * module parameters, doesn't probe but forces a load. + */ + DEBUG( MTD_DEBUG_LEVEL3, + "MTD %s(): check ID's disappear when not in ID mode\n", + __func__ ); + jedec_reset( base, map, cfi ); + mfr = jedec_read_mfr( map, base, cfi ); + id = jedec_read_id( map, base, cfi ); + if ( mfr == cfi->mfr && id == cfi->id ) { + DEBUG( MTD_DEBUG_LEVEL3, + "MTD %s(): ID 0x%.2x:0x%.2x did not change after reset:\n" + "You might need to manually specify JEDEC parameters.\n", + __func__, cfi->mfr, cfi->id ); + goto match_done; + } + + /* all tests passed - mark as success */ + rc = 1; + + /* + * Put the device back in ID mode - only need to do this if we + * were truly frobbing a real device. + */ + DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): return to ID mode\n", __func__ ); + if(cfi->addr_unlock1) { + cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL); + } + cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); + /* FIXME - should have a delay before continuing */ + + match_done: + return rc; +} + + static int jedec_probe_chip(struct map_info *map, __u32 base, - struct flchip *chips, struct cfi_private *cfi) + unsigned long *chip_map, struct cfi_private *cfi) { int i; - int unlockpass = 0; + enum uaddr uaddr_idx = MTD_UADDR_NOT_SUPPORTED; + u32 probe_offset1, probe_offset2; + retry: if (!cfi->numchips) { - switch (cfi->device_type) { - case CFI_DEVICETYPE_X8: - cfi->addr_unlock1 = 0x555; - cfi->addr_unlock2 = 0x2aa; - break; - case CFI_DEVICETYPE_X16: - cfi->addr_unlock1 = 0xaaa; - if (map->buswidth == cfi->interleave) { - /* X16 chip(s) in X8 mode */ - cfi->addr_unlock2 = 0x555; - } else { - cfi->addr_unlock2 = 0x554; - } - break; - case CFI_DEVICETYPE_X32: - cfi->addr_unlock1 = 0x1555; - cfi->addr_unlock2 = 0xaaa; - break; - default: - printk(KERN_NOTICE "Eep. Unknown jedec_probe device type %d\n", cfi->device_type); - return 0; - } + uaddr_idx++; + + if (MTD_UADDR_UNNECESSARY == uaddr_idx) + return 0; + + /* Mask out address bits which are smaller than the device type */ + cfi->addr_unlock1 = unlock_addrs[uaddr_idx].addr1; + cfi->addr_unlock2 = unlock_addrs[uaddr_idx].addr2; } - retry: /* Make certain we aren't probing past the end of map */ if (base >= map->size) { printk(KERN_NOTICE @@ -1014,30 +1936,31 @@ return 0; } - if ((base + cfi->addr_unlock1) >= map->size) { - printk(KERN_NOTICE - "Probe at addr_unlock1(0x%08x + 0x%08x) past the end of the map(0x%08lx)\n", - base, cfi->addr_unlock1, map->size -1); - - return 0; + /* Ensure the unlock addresses we try stay inside the map */ + probe_offset1 = cfi_build_cmd_addr( + cfi->addr_unlock1, + cfi_interleave(cfi), + cfi->device_type); + probe_offset2 = cfi_build_cmd_addr( + cfi->addr_unlock1, + cfi_interleave(cfi), + cfi->device_type); + if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) || + ((base + probe_offset2 + map_bankwidth(map)) >= map->size)) + { + goto retry; } - if ((base + cfi->addr_unlock2) >= map->size) { - printk(KERN_NOTICE - "Probe at addr_unlock2(0x%08x + 0x%08x) past the end of the map(0x%08lx)\n", - base, cfi->addr_unlock2, map->size -1); - return 0; - } - /* Reset */ jedec_reset(base, map, cfi); /* Autoselect Mode */ if(cfi->addr_unlock1) { - cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL); - cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL); + cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL); } - cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL); + cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); + /* FIXME - should have a delay before continuing */ if (!cfi->numchips) { /* This is the first time we're called. Set up the CFI @@ -1045,26 +1968,21 @@ cfi->mfr = jedec_read_mfr(map, base, cfi); cfi->id = jedec_read_id(map, base, cfi); - printk(KERN_INFO "Search for id:(%02x %02x) interleave(%d) type(%d)\n", - cfi->mfr, cfi->id, cfi->interleave, cfi->device_type); + DEBUG(MTD_DEBUG_LEVEL3, + "Search for id:(%02x %02x) interleave(%d) type(%d)\n", + cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type); for (i=0; imfr == jedec_table[i].mfr_id && - cfi->id == jedec_table[i].dev_id) { + if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) { + DEBUG( MTD_DEBUG_LEVEL3, + "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n", + __func__, cfi->mfr, cfi->id, + cfi->addr_unlock1, cfi->addr_unlock2 ); if (!cfi_jedec_setup(cfi, i)) return 0; goto ok_out; } } - switch(unlockpass++) { - case 0: - cfi->addr_unlock1 |= cfi->addr_unlock1 << 4; - cfi->addr_unlock2 |= cfi->addr_unlock2 << 4; - goto retry; - case 1: - cfi->addr_unlock1 = cfi->addr_unlock2 = 0; - goto retry; - } - return 0; + goto retry; } else { __u16 mfr; __u16 id; @@ -1081,21 +1999,24 @@ } } - /* Check each previous chip to see if it's an alias */ - for (i=0; inumchips; i++) { - /* This chip should be in read mode if it's one - we've already touched. */ - if (jedec_read_mfr(map, chips[i].start, cfi) == cfi->mfr && - jedec_read_id(map, chips[i].start, cfi) == cfi->id) { + /* Check each previous chip locations to see if it's an alias */ + for (i=0; i < (base >> cfi->chipshift); i++) { + unsigned long start; + if(!test_bit(i, chip_map)) { + continue; /* Skip location; no valid chip at this address */ + } + start = i << cfi->chipshift; + if (jedec_read_mfr(map, start, cfi) == cfi->mfr && + jedec_read_id(map, start, cfi) == cfi->id) { /* Eep. This chip also looks like it's in autoselect mode. Is it an alias for the new one? */ - jedec_reset(chips[i].start, map, cfi); + jedec_reset(start, map, cfi); /* If the device IDs go away, it's an alias */ if (jedec_read_mfr(map, base, cfi) != cfi->mfr || jedec_read_id(map, base, cfi) != cfi->id) { printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", - map->name, base, chips[i].start); + map->name, base, start); return 0; } @@ -1107,7 +2028,7 @@ if (jedec_read_mfr(map, base, cfi) == cfi->mfr && jedec_read_id(map, base, cfi) == cfi->id) { printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", - map->name, base, chips[i].start); + map->name, base, start); return 0; } } @@ -1115,29 +2036,23 @@ /* OK, if we got to here, then none of the previous chips appear to be aliases for the current one. */ - if (cfi->numchips == MAX_CFI_CHIPS) { - printk(KERN_WARNING"%s: Too many flash chips detected. Increase MAX_CFI_CHIPS from %d.\n", map->name, MAX_CFI_CHIPS); - /* Doesn't matter about resetting it to Read Mode - we're not going to talk to it anyway */ - return -1; - } - chips[cfi->numchips].start = base; - chips[cfi->numchips].state = FL_READY; + set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */ cfi->numchips++; ok_out: /* Put it back into Read Mode */ jedec_reset(base, map, cfi); - printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit mode\n", - map->name, cfi->interleave, cfi->device_type*8, base, - map->buswidth*8); + printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", + map->name, cfi_interleave(cfi), cfi->device_type*8, base, + map->bankwidth*8); return 1; } static struct chip_probe jedec_chip_probe = { - name: "JEDEC", - probe_chip: jedec_probe_chip + .name = "JEDEC", + .probe_chip = jedec_probe_chip }; struct mtd_info *jedec_probe(struct map_info *map) @@ -1150,9 +2065,9 @@ } static struct mtd_chip_driver jedec_chipdrv = { - probe: jedec_probe, - name: "jedec_probe", - module: THIS_MODULE + .probe = jedec_probe, + .name = "jedec_probe", + .module = THIS_MODULE }; int __init jedec_probe_init(void) Index: drivers/mtd/chips/map_absent.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/chips/map_absent.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/chips/map_absent.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/chips/map_absent.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,7 +1,7 @@ /* * Common code to handle absent "placeholder" devices * Copyright 2001 Resilience Corporation - * $Id: map_absent.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: map_absent.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * * This map driver is used to allocate "placeholder" MTD * devices on systems that have socketed/removable media. @@ -23,9 +23,10 @@ #include #include #include - +#include +#include #include - +#include static int map_absent_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int map_absent_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *); @@ -36,10 +37,10 @@ static struct mtd_chip_driver map_absent_chipdrv = { - probe: map_absent_probe, - destroy: map_absent_destroy, - name: "map_absent", - module: THIS_MODULE + .probe = map_absent_probe, + .destroy = map_absent_destroy, + .name = "map_absent", + .module = THIS_MODULE }; static struct mtd_info *map_absent_probe(struct map_info *map) @@ -65,7 +66,7 @@ mtd->flags = 0; mtd->erasesize = PAGE_SIZE; - MOD_INC_USE_COUNT; + __module_get(THIS_MODULE); return mtd; } Index: drivers/mtd/chips/map_ram.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/chips/map_ram.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/chips/map_ram.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/chips/map_ram.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,7 +1,7 @@ /* * Common code to handle map devices which are simple RAM * (C) 2000 Red Hat. GPL'd. - * $Id: map_ram.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: map_ram.c,v 1.3 2004/11/03 00:04:43 joff Exp $ */ #include @@ -11,8 +11,10 @@ #include #include #include - +#include +#include #include +#include static int mapram_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); @@ -23,9 +25,9 @@ static struct mtd_chip_driver mapram_chipdrv = { - probe: map_ram_probe, - name: "map_ram", - module: THIS_MODULE + .probe = map_ram_probe, + .name = "map_ram", + .module = THIS_MODULE }; static struct mtd_info *map_ram_probe(struct map_info *map) @@ -34,21 +36,21 @@ /* Check the first byte is RAM */ #if 0 - map->write8(map, 0x55, 0); - if (map->read8(map, 0) != 0x55) + map_write8(map, 0x55, 0); + if (map_read8(map, 0) != 0x55) return NULL; - map->write8(map, 0xAA, 0); - if (map->read8(map, 0) != 0xAA) + map_write8(map, 0xAA, 0); + if (map_read8(map, 0) != 0xAA) return NULL; /* Check the last byte is RAM */ - map->write8(map, 0x55, map->size-1); - if (map->read8(map, map->size-1) != 0x55) + map_write8(map, 0x55, map->size-1); + if (map_read8(map, map->size-1) != 0x55) return NULL; - map->write8(map, 0xAA, map->size-1); - if (map->read8(map, map->size-1) != 0xAA) + map_write8(map, 0xAA, map->size-1); + if (map_read8(map, map->size-1) != 0xAA) return NULL; #endif /* OK. It seems to be RAM. */ @@ -74,7 +76,7 @@ while(mtd->size & (mtd->erasesize - 1)) mtd->erasesize >>= 1; - MOD_INC_USE_COUNT; + __module_get(THIS_MODULE); return mtd; } @@ -83,7 +85,7 @@ { struct map_info *map = (struct map_info *)mtd->priv; - map->copy_from(map, buf, from, len); + map_copy_from(map, buf, from, len); *retlen = len; return 0; } @@ -92,7 +94,7 @@ { struct map_info *map = (struct map_info *)mtd->priv; - map->copy_to(map, to, buf, len); + map_copy_to(map, to, buf, len); *retlen = len; return 0; } @@ -102,13 +104,17 @@ /* Yeah, it's inefficient. Who cares? It's faster than a _real_ flash erase. */ struct map_info *map = (struct map_info *)mtd->priv; + map_word allff; unsigned long i; - for (i=0; ilen; i++) - map->write8(map, 0xFF, instr->addr + i); + allff = map_word_ff(map); + + for (i=0; ilen; i += map_bankwidth(map)) + map_write(map, allff, instr->addr + i); + + instr->state = MTD_ERASE_DONE; - if (instr->callback) - instr->callback(instr); + mtd_erase_callback(instr); return 0; } Index: drivers/mtd/chips/map_rom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/chips/map_rom.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/chips/map_rom.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/chips/map_rom.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,10 +1,9 @@ /* * Common code to handle map devices which are simple ROM * (C) 2000 Red Hat. GPL'd. - * $Id: map_rom.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: map_rom.c,v 1.3 2004/11/03 00:04:43 joff Exp $ */ -#include #include #include #include @@ -12,8 +11,10 @@ #include #include #include - +#include +#include #include +#include static int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *); @@ -21,9 +22,9 @@ struct mtd_info *map_rom_probe(struct map_info *map); static struct mtd_chip_driver maprom_chipdrv = { - probe: map_rom_probe, - name: "map_rom", - module: THIS_MODULE + .probe = map_rom_probe, + .name = "map_rom", + .module = THIS_MODULE }; struct mtd_info *map_rom_probe(struct map_info *map) @@ -49,7 +50,7 @@ while(mtd->size & (mtd->erasesize - 1)) mtd->erasesize >>= 1; - MOD_INC_USE_COUNT; + __module_get(THIS_MODULE); return mtd; } @@ -58,7 +59,7 @@ { struct map_info *map = (struct map_info *)mtd->priv; - map->copy_from(map, buf, from, len); + map_copy_from(map, buf, from, len); *retlen = len; return 0; } Index: drivers/mtd/chips/sharp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/chips/sharp.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/chips/sharp.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/chips/sharp.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -4,7 +4,7 @@ * Copyright 2000,2001 David A. Schleef * 2000,2001 Lineo, Inc. * - * $Id: sharp.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: sharp.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * * Devices supported: * LH28F016SCT Symmetrical block flash memory, 2Mx8 @@ -22,14 +22,15 @@ #include #include -#include #include #include #include #include #include +#include #include #include +#include #define CMD_RESET 0xffffffff #define CMD_READ_ID 0x90909090 @@ -98,10 +99,10 @@ static void sharp_destroy(struct mtd_info *mtd); static struct mtd_chip_driver sharp_chipdrv = { - probe: sharp_probe, - destroy: sharp_destroy, - name: "sharp", - module: THIS_MODULE + .probe = sharp_probe, + .destroy = sharp_destroy, + .name = "sharp", + .module = THIS_MODULE }; @@ -116,8 +117,10 @@ return NULL; sharp = kmalloc(sizeof(*sharp), GFP_KERNEL); - if(!sharp) + if(!sharp) { + kfree(mtd); return NULL; + } memset(mtd, 0, sizeof(*mtd)); @@ -152,7 +155,7 @@ map->fldrv = &sharp_chipdrv; map->fldrv_priv = sharp; - MOD_INC_USE_COUNT; + __module_get(THIS_MODULE); return mtd; } @@ -163,12 +166,12 @@ u32 read0, read4; int width = 4; - tmp = map->read32(map, base+0); + tmp = map_read32(map, base+0); - map->write32(map, CMD_READ_ID, base+0); + map_write32(map, CMD_READ_ID, base+0); - read0=map->read32(map, base+0); - read4=map->read32(map, base+4); + read0=map_read32(map, base+0); + read4=map_read32(map, base+4); if(read0 == 0x89898989){ printk("Looks like sharp flash\n"); switch(read4){ @@ -196,10 +199,10 @@ printk("Sort-of looks like sharp flash, 0x%08x 0x%08x\n", read0,read4); } - }else if((map->read32(map, base+0) == CMD_READ_ID)){ + }else if((map_read32(map, base+0) == CMD_READ_ID)){ /* RAM, probably */ printk("Looks like RAM\n"); - map->write32(map, tmp, base+0); + map_write32(map, tmp, base+0); }else{ printk("Doesn't look like sharp flash, 0x%08x 0x%08x\n", read0,read4); @@ -221,10 +224,10 @@ switch(chip->state){ case FL_READY: - map->write32(map,CMD_READ_STATUS,adr); + map_write32(map,CMD_READ_STATUS,adr); chip->state = FL_STATUS; case FL_STATUS: - status = map->read32(map,adr); + status = map_read32(map,adr); //printk("status=%08x\n",status); udelay(100); @@ -252,7 +255,7 @@ goto retry; } - map->write32(map,CMD_RESET, adr); + map_write32(map,CMD_RESET, adr); chip->state = FL_READY; @@ -293,7 +296,7 @@ if(ret<0) break; - map->copy_from(map,buf,ofs,thislen); + map_copy_from(map,buf,ofs,thislen); sharp_release(&sharp->chips[chipnum]); @@ -354,17 +357,17 @@ ret = sharp_wait(map,chip); for(try=0;try<10;try++){ - map->write32(map,CMD_BYTE_WRITE,adr); + map_write32(map,CMD_BYTE_WRITE,adr); /* cpu_to_le32 -> hack to fix the writel be->le conversion */ - map->write32(map,cpu_to_le32(datum),adr); + map_write32(map,cpu_to_le32(datum),adr); chip->state = FL_WRITING; timeo = jiffies + (HZ/2); - map->write32(map,CMD_READ_STATUS,adr); + map_write32(map,CMD_READ_STATUS,adr); for(i=0;i<100;i++){ - status = map->read32(map,adr); + status = map_read32(map,adr); if((status & SR_READY)==SR_READY) break; } @@ -377,9 +380,9 @@ printk("sharp: error writing byte at addr=%08lx status=%08x\n",adr,status); - map->write32(map,CMD_CLEAR_STATUS,adr); + map_write32(map,CMD_CLEAR_STATUS,adr); } - map->write32(map,CMD_RESET,adr); + map_write32(map,CMD_RESET,adr); chip->state = FL_READY; wake_up(&chip->wq); @@ -422,8 +425,7 @@ } instr->state = MTD_ERASE_DONE; - if(instr->callback) - instr->callback(instr); + mtd_erase_callback(instr); return 0; } @@ -432,18 +434,18 @@ unsigned long adr) { int ret; - int timeo; + unsigned long timeo; int status; DECLARE_WAITQUEUE(wait, current); - map->write32(map,CMD_READ_STATUS,adr); - status = map->read32(map,adr); + map_write32(map,CMD_READ_STATUS,adr); + status = map_read32(map,adr); timeo = jiffies + HZ; while(time_before(jiffies, timeo)){ - map->write32(map,CMD_READ_STATUS,adr); - status = map->read32(map,adr); + map_write32(map,CMD_READ_STATUS,adr); + status = map_read32(map,adr); if((status & SR_READY)==SR_READY){ ret = 0; goto out; @@ -485,26 +487,26 @@ sharp_unlock_oneblock(map,chip,adr); #endif - map->write32(map,CMD_BLOCK_ERASE_1,adr); - map->write32(map,CMD_BLOCK_ERASE_2,adr); + map_write32(map,CMD_BLOCK_ERASE_1,adr); + map_write32(map,CMD_BLOCK_ERASE_2,adr); chip->state = FL_ERASING; ret = sharp_do_wait_for_ready(map,chip,adr); if(ret<0)return ret; - map->write32(map,CMD_READ_STATUS,adr); - status = map->read32(map,adr); + map_write32(map,CMD_READ_STATUS,adr); + status = map_read32(map,adr); if(!(status&SR_ERRORS)){ - map->write32(map,CMD_RESET,adr); + map_write32(map,CMD_RESET,adr); chip->state = FL_READY; //spin_unlock_bh(chip->mutex); return 0; } printk("sharp: error erasing block at addr=%08lx status=%08x\n",adr,status); - map->write32(map,CMD_CLEAR_STATUS,adr); + map_write32(map,CMD_CLEAR_STATUS,adr); //spin_unlock_bh(chip->mutex); @@ -518,17 +520,17 @@ int i; int status; - map->write32(map,CMD_CLEAR_BLOCK_LOCKS_1,adr); - map->write32(map,CMD_CLEAR_BLOCK_LOCKS_2,adr); + map_write32(map,CMD_CLEAR_BLOCK_LOCKS_1,adr); + map_write32(map,CMD_CLEAR_BLOCK_LOCKS_2,adr); udelay(100); - status = map->read32(map,adr); + status = map_read32(map,adr); printk("status=%08x\n",status); for(i=0;i<1000;i++){ - //map->write32(map,CMD_READ_STATUS,adr); - status = map->read32(map,adr); + //map_write32(map,CMD_READ_STATUS,adr); + status = map_read32(map,adr); if((status & SR_READY)==SR_READY) break; udelay(100); @@ -538,13 +540,13 @@ } if(!(status&SR_ERRORS)){ - map->write32(map,CMD_RESET,adr); + map_write32(map,CMD_RESET,adr); chip->state = FL_READY; return; } printk("sharp: error unlocking block at addr=%08lx status=%08x\n",adr,status); - map->write32(map,CMD_CLEAR_STATUS,adr); + map_write32(map,CMD_CLEAR_STATUS,adr); } #endif Index: drivers/mtd/devices/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/devices/Config.in,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/devices/Config.in 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/devices/Config.in 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,6 +1,6 @@ -# drivers/mtd/maps/Config.in +# drivers/mtd/devices/Config.in -# $Id: Config.in,v 1.1 2004/07/22 19:49:46 joff Exp $ +# $Id: Config.in,v 1.3 2004/11/03 00:04:43 joff Exp $ mainmenu_option next_comment @@ -10,22 +10,13 @@ bool ' PMC551 256M DRAM Bugfix' CONFIG_MTD_PMC551_BUGFIX bool ' PMC551 Debugging' CONFIG_MTD_PMC551_DEBUG fi -if [ "$CONFIG_DECSTATION" = "y" ]; then +if [ "$CONFIG_MACH__DECSTATION" = "y" ]; then dep_tristate ' DEC MS02-NV NVRAM module support' CONFIG_MTD_MS02NV $CONFIG_MTD fi dep_tristate ' Uncached system RAM' CONFIG_MTD_SLRAM $CONFIG_MTD if [ "$CONFIG_SA1100_LART" = "y" ]; then dep_tristate ' 28F160xx flash driver for LART' CONFIG_MTD_LART $CONFIG_MTD fi -if [ "$CONFIG_ARCH_MX1ADS" = "y" ]; then - dep_tristate ' SyncFlash driver for MX1ADS' CONFIG_MTD_SYNCFLASH $CONFIG_MTD -fi -if [ "$CONFIG_ARCH_AT91RM9200" = "y" ]; then - dep_tristate ' AT91RM9200 DataFlash support' CONFIG_MTD_AT91_DATAFLASH $CONFIG_MTD - if [ "$CONFIG_MTD_AT91_DATAFLASH" = "y" -o "$CONFIG_MTD_AT91_DATAFLASH" = "m" ]; then - bool ' Enable DataFlash card? ' CONFIG_MTD_AT91_DATAFLASH_CARD - fi -fi dep_tristate ' Test driver using RAM' CONFIG_MTD_MTDRAM $CONFIG_MTD if [ "$CONFIG_MTD_MTDRAM" = "y" -o "$CONFIG_MTD_MTDRAM" = "m" ]; then int 'MTDRAM device size in KiB' CONFIG_MTDRAM_TOTAL_SIZE 4096 @@ -37,19 +28,29 @@ dep_tristate ' MTD emulation using block device' CONFIG_MTD_BLKMTD $CONFIG_MTD comment 'Disk-On-Chip Device Drivers' - dep_tristate ' M-Systems Disk-On-Chip 1000' CONFIG_MTD_DOC1000 $CONFIG_MTD - dep_tristate ' M-Systems Disk-On-Chip 2000 and Millennium' CONFIG_MTD_DOC2000 $CONFIG_MTD - dep_tristate ' M-Systems Disk-On-Chip Millennium-only alternative driver (see help)' CONFIG_MTD_DOC2001 $CONFIG_MTD - if [ "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" ]; then + dep_tristate ' M-Systems Disk-On-Chip 2000 and Millennium (DEPRECATED)' CONFIG_MTD_DOC2000 $CONFIG_MTD + dep_tristate ' M-Systems Disk-On-Chip Millennium-only alternative driver (DEPRECATED)' CONFIG_MTD_DOC2001 $CONFIG_MTD + dep_tristate ' M-Systems Disk-On-Chip Millennium Plus driver (see help)' CONFIG_MTD_DOC2001PLUS $CONFIG_MTD + if [ "$CONFIG_MTD_DOC2001PLUS" = "y" -o "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" ]; then define_bool CONFIG_MTD_DOCPROBE y else - if [ "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" ]; then + if [ "$CONFIG_MTD_DOC2001PLUS" = "m" -o "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" ]; then define_bool CONFIG_MTD_DOCPROBE m else define_bool CONFIG_MTD_DOCPROBE n fi fi + if [ "$CONFIG_MTD_DOCPROBE" = "y" ]; then + define_bool CONFIG_MTD_DOCECC y + else + if [ "$CONFIG_MTD_DOCPROBE" = "m" ]; then + define_bool CONFIG_MTD_DOCECC m + else + define_bool CONFIG_MTD_DOCECC n + fi + fi + if [ "$CONFIG_MTD_DOCPROBE" = "y" -o "$CONFIG_MTD_DOCPROBE" = "m" ]; then bool ' Advanced detection options for DiskOnChip' CONFIG_MTD_DOCPROBE_ADVANCED if [ "$CONFIG_MTD_DOCPROBE_ADVANCED" = "n" ]; then Index: drivers/mtd/devices/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/devices/Makefile,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/devices/Makefile 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/devices/Makefile 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,27 +1,23 @@ # -# linux/drivers/devices/Makefile +# linux/drivers/maps/Makefile.24 +# Makefile for obsolete kernels # -# $Id: Makefile,v 1.1 2004/07/22 19:49:46 joff Exp $ +# $Id: Makefile,v 1.3 2004/11/03 00:04:43 joff Exp $ O_TARGET := devlink.o +export-objs := docecc.o -# *** BIG UGLY NOTE *** -# -# The removal of get_module_symbol() and replacement with -# inter_module_register() et al has introduced a link order dependency -# here where previously there was none. We now have to ensure that -# doc200[01].o are linked before docprobe.o - -obj-$(CONFIG_MTD_DOC1000) += doc1000.o -obj-$(CONFIG_MTD_DOC2000) += doc2000.o -obj-$(CONFIG_MTD_DOC2001) += doc2001.o -obj-$(CONFIG_MTD_DOCPROBE) += docprobe.o docecc.o -obj-$(CONFIG_MTD_SLRAM) += slram.o -obj-$(CONFIG_MTD_PMC551) += pmc551.o -obj-$(CONFIG_MTD_MS02NV) += ms02-nv.o -obj-$(CONFIG_MTD_MTDRAM) += mtdram.o -obj-$(CONFIG_MTD_LART) += lart.o -obj-$(CONFIG_MTD_SYNCFLASH) += syncflash.o -obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o +obj-$(CONFIG_MTD_DOC2000) += doc2000.o +obj-$(CONFIG_MTD_DOC2001) += doc2001.o +obj-$(CONFIG_MTD_DOC2001PLUS) += doc2001plus.o +obj-$(CONFIG_MTD_DOCPROBE) += docprobe.o +obj-$(CONFIG_MTD_DOCECC) += docecc.o +obj-$(CONFIG_MTD_SLRAM) += slram.o +obj-$(CONFIG_MTD_PHRAM) += phram.o +obj-$(CONFIG_MTD_PMC551) += pmc551.o +obj-$(CONFIG_MTD_MS02NV) += ms02-nv.o +obj-$(CONFIG_MTD_MTDRAM) += mtdram.o +obj-$(CONFIG_MTD_LART) += lart.o +obj-$(CONFIG_MTD_BLKMTD) += blkmtd-24.o include $(TOPDIR)/Rules.make Index: drivers/mtd/devices/blkmtd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/devices/blkmtd.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/devices/blkmtd.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/devices/blkmtd.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,5 +1,5 @@ /* - * $Id: blkmtd.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: blkmtd.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * * blkmtd.c - use a block device as a fake MTD * @@ -12,11 +12,8 @@ * How it works: * The driver uses raw/io to read/write the device and the page * cache to cache access. Writes update the page cache with the - * new data and mark it dirty and add the page into a kiobuf. - * When the kiobuf becomes full or the next extry is to an earlier - * block in the kiobuf then it is flushed to disk. This allows - * writes to remained ordered and gives a small and simple outgoing - * write cache. + * new data and mark it dirty and add the page into a BIO which + * is then written out. * * It can be loaded Read-Only to prevent erases and writes to the * medium. @@ -27,20 +24,12 @@ #include #include #include -#include -#include +#include #include #include +#include #include -#ifdef CONFIG_MTD_DEBUG -#ifdef CONFIG_PROC_FS -# include -# define BLKMTD_PROC_DEBUG - static struct proc_dir_entry *blkmtd_proc; -#endif -#endif - #define err(format, arg...) printk(KERN_ERR "blkmtd: " format "\n" , ## arg) #define info(format, arg...) printk(KERN_INFO "blkmtd: " format "\n" , ## arg) @@ -48,17 +37,15 @@ #define crit(format, arg...) printk(KERN_CRIT "blkmtd: " format "\n" , ## arg) -/* Default erase size in KiB, always make it a multiple of PAGE_SIZE */ +/* Default erase size in K, always make it a multiple of PAGE_SIZE */ #define CONFIG_MTD_BLKDEV_ERASESIZE (128 << 10) /* 128KiB */ -#define VERSION "1.10" +#define VERSION "$Revision: 1.3 $" /* Info for the block device */ struct blkmtd_dev { struct list_head list; - struct block_device *binding; + struct block_device *blkdev; struct mtd_info mtd_info; - struct kiobuf *rd_buf, *wr_buf; - long iobuf_locks; struct semaphore wrbuf_mutex; }; @@ -91,136 +78,145 @@ MODULE_PARM_DESC(sync, "1=Synchronous writes"); -/** - * read_pages - read in pages via the page cache - * @dev: device to read from - * @pagenrs: list of page numbers wanted - * @pagelst: storage for struce page * pointers - * @pages: count of pages wanted - * - * Read pages, getting them from the page cache if available - * else reading them in from disk if not. pagelst must be preallocated - * to hold the page count. - */ -static int read_pages(struct blkmtd_dev *dev, int pagenrs[], struct page **pagelst, int pages) +/* completion handler for BIO reads */ +static int bi_read_complete(struct bio *bio, unsigned int bytes_done, int error) { - kdev_t kdev; - struct page *page; - int cnt = 0; - struct kiobuf *iobuf; - int err = 0; + if (bio->bi_size) + return 1; - if(!dev) { - err("read_pages: PANIC dev == NULL"); - return -EIO; - } - kdev = to_kdev_t(dev->binding->bd_dev); - - DEBUG(2, "read_pages: reading %d pages\n", pages); - if(test_and_set_bit(0, &dev->iobuf_locks)) { - err = alloc_kiovec(1, &iobuf); - if (err) { - crit("cant allocate kiobuf"); - return -ENOMEM; - } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4) - iobuf->blocks = kmalloc(KIO_MAX_SECTORS * sizeof(unsigned long), GFP_KERNEL); - if(iobuf->blocks == NULL) { - crit("cant allocate iobuf blocks"); - free_kiovec(1, &iobuf); - return -ENOMEM; - } -#endif - } else { - iobuf = dev->rd_buf; - } + complete((struct completion*)bio->bi_private); + return 0; +} - iobuf->nr_pages = 0; - iobuf->length = 0; - iobuf->offset = 0; - iobuf->locked = 1; - - for(cnt = 0; cnt < pages; cnt++) { - page = grab_cache_page(dev->binding->bd_inode->i_mapping, pagenrs[cnt]); - pagelst[cnt] = page; - if(!PageUptodate(page)) { - iobuf->blocks[iobuf->nr_pages] = pagenrs[cnt]; - iobuf->maplist[iobuf->nr_pages++] = page; + +/* completion handler for BIO writes */ +static int bi_write_complete(struct bio *bio, unsigned int bytes_done, int error) +{ + const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); + struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; + + if (bio->bi_size) + return 1; + + if(!uptodate) + err("bi_write_complete: not uptodate\n"); + + do { + struct page *page = bvec->bv_page; + DEBUG(3, "Cleaning up page %ld\n", page->index); + if (--bvec >= bio->bi_io_vec) + prefetchw(&bvec->bv_page->flags); + + if (uptodate) { + SetPageUptodate(page); + } else { + ClearPageUptodate(page); + SetPageError(page); } + ClearPageDirty(page); + unlock_page(page); + page_cache_release(page); + } while (bvec >= bio->bi_io_vec); + + complete((struct completion*)bio->bi_private); + return 0; +} + + +/* read one page from the block device */ +static int blkmtd_readpage(struct blkmtd_dev *dev, struct page *page) +{ + struct bio *bio; + struct completion event; + int err = -ENOMEM; + + if(PageUptodate(page)) { + DEBUG(2, "blkmtd: readpage page %ld is already upto date\n", page->index); + unlock_page(page); + return 0; } + + ClearPageUptodate(page); + ClearPageError(page); - if(iobuf->nr_pages) { - iobuf->length = iobuf->nr_pages << PAGE_SHIFT; - err = brw_kiovec(READ, 1, &iobuf, kdev, iobuf->blocks, PAGE_SIZE); - DEBUG(3, "blkmtd: read_pages: finished, err = %d\n", err); - if(err < 0) { - while(pages--) { - ClearPageUptodate(pagelst[pages]); - unlock_page(pagelst[pages]); - page_cache_release(pagelst[pages]); - } - } else { - while(iobuf->nr_pages--) { - SetPageUptodate(iobuf->maplist[iobuf->nr_pages]); - } - err = 0; + bio = bio_alloc(GFP_KERNEL, 1); + if(bio) { + init_completion(&event); + bio->bi_bdev = dev->blkdev; + bio->bi_sector = page->index << (PAGE_SHIFT-9); + bio->bi_private = &event; + bio->bi_end_io = bi_read_complete; + if(bio_add_page(bio, page, PAGE_SIZE, 0) == PAGE_SIZE) { + submit_bio(READ_SYNC, bio); + wait_for_completion(&event); + err = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : -EIO; + bio_put(bio); } } + if(err) + SetPageError(page); + else + SetPageUptodate(page); + flush_dcache_page(page); + unlock_page(page); + return err; +} - if(iobuf != dev->rd_buf) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4) - kfree(iobuf->blocks); -#endif - free_kiovec(1, &iobuf); - } else { - clear_bit(0, &dev->iobuf_locks); + +/* write out the current BIO and wait for it to finish */ +static int blkmtd_write_out(struct bio *bio) +{ + struct completion event; + int err; + + if(!bio->bi_vcnt) { + bio_put(bio); + return 0; } - DEBUG(2, "read_pages: done, err = %d\n", err); + + init_completion(&event); + bio->bi_private = &event; + bio->bi_end_io = bi_write_complete; + submit_bio(WRITE_SYNC, bio); + wait_for_completion(&event); + DEBUG(3, "submit_bio completed, bi_vcnt = %d\n", bio->bi_vcnt); + err = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : -EIO; + bio_put(bio); return err; } /** - * commit_pages - commit pages in the writeout kiobuf to disk - * @dev: device to write to + * blkmtd_add_page - add a page to the current BIO + * @bio: bio to add to (NULL to alloc initial bio) + * @blkdev: block device + * @page: page to add + * @pagecnt: pages left to add * - * If the current dev has pages in the dev->wr_buf kiobuf, - * they are written to disk using brw_kiovec() + * Adds a page to the current bio, allocating it if necessary. If it cannot be + * added, the current bio is written out and a new one is allocated. Returns + * the new bio to add or NULL on error */ -static int commit_pages(struct blkmtd_dev *dev) +static struct bio *blkmtd_add_page(struct bio *bio, struct block_device *blkdev, + struct page *page, int pagecnt) { - struct kiobuf *iobuf = dev->wr_buf; - kdev_t kdev = to_kdev_t(dev->binding->bd_dev); - int err = 0; - iobuf->length = iobuf->nr_pages << PAGE_SHIFT; - iobuf->locked = 1; - if(iobuf->length) { - int i; - DEBUG(2, "blkmtd: commit_pages: nrpages = %d\n", iobuf->nr_pages); - /* Check all the pages are dirty and lock them */ - for(i = 0; i < iobuf->nr_pages; i++) { - struct page *page = iobuf->maplist[i]; - BUG_ON(!PageDirty(page)); - lock_page(page); - } - err = brw_kiovec(WRITE, 1, &iobuf, kdev, iobuf->blocks, PAGE_SIZE); - DEBUG(3, "commit_write: committed %d pages err = %d\n", iobuf->nr_pages, err); - while(iobuf->nr_pages) { - struct page *page = iobuf->maplist[--iobuf->nr_pages]; - ClearPageDirty(page); - SetPageUptodate(page); - unlock_page(page); - page_cache_release(page); - } + retry: + if(!bio) { + bio = bio_alloc(GFP_KERNEL, pagecnt); + if(!bio) + return NULL; + bio->bi_sector = page->index << (PAGE_SHIFT-9); + bio->bi_bdev = blkdev; } - DEBUG(2, "blkmtd: sync: end, err = %d\n", err); - iobuf->offset = 0; - iobuf->nr_pages = 0; - iobuf->length = 0; - return err; + if(bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE) { + blkmtd_write_out(bio); + bio = NULL; + goto retry; + } + return bio; } @@ -234,30 +230,25 @@ * * Grab pages from the page cache and fill them with the source data. * Non page aligned start and end result in a readin of the page and - * part of the page being modified. Pages are added to the wr_buf kiobuf - * until this becomes full or the next page written to has a lower pagenr - * then the current max pagenr in the kiobuf. + * part of the page being modified. Pages are added to the bio and then written + * out. */ static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to, - size_t len, int *retlen) + size_t len, size_t *retlen) { int pagenr, offset; size_t start_len = 0, end_len; int pagecnt = 0; - struct kiobuf *iobuf = dev->wr_buf; int err = 0; - struct page *pagelst[2]; - int pagenrs[2]; - int readpages = 0; - int ignorepage = -1; + struct bio *bio = NULL; + size_t thislen = 0; pagenr = to >> PAGE_SHIFT; offset = to & ~PAGE_MASK; - DEBUG(2, "blkmtd: write_pages: buf = %p to = %ld len = %d pagenr = %d offset = %d\n", + DEBUG(2, "blkmtd: write_pages: buf = %p to = %ld len = %zd pagenr = %d offset = %d\n", buf, (long)to, len, pagenr, offset); - *retlen = 0; /* see if we have to do a partial write at the start */ if(offset) { start_len = ((offset + len) > PAGE_SIZE) ? PAGE_SIZE - offset : len; @@ -268,68 +259,48 @@ end_len = len & ~PAGE_MASK; len -= end_len; - if(start_len) { - pagenrs[0] = pagenr; - readpages++; + if(start_len) pagecnt++; - } + if(len) pagecnt += len >> PAGE_SHIFT; - if(end_len) { - pagenrs[readpages] = pagenr + pagecnt; - readpages++; - pagecnt++; - } - DEBUG(3, "blkmtd: write: start_len = %d len = %d end_len = %d pagecnt = %d\n", - start_len, len, end_len, pagecnt); + if(end_len) + pagecnt++; down(&dev->wrbuf_mutex); - if(iobuf->nr_pages && ((pagenr <= iobuf->blocks[iobuf->nr_pages-1]) - || (iobuf->nr_pages + pagecnt) >= KIO_STATIC_PAGES)) { - - if((pagenr == iobuf->blocks[iobuf->nr_pages-1]) - && ((iobuf->nr_pages + pagecnt) < KIO_STATIC_PAGES)) { - iobuf->nr_pages--; - ignorepage = pagenr; - } else { - DEBUG(3, "blkmtd: doing writeout pagenr = %d max_pagenr = %ld pagecnt = %d idx = %d\n", - pagenr, iobuf->blocks[iobuf->nr_pages-1], - pagecnt, iobuf->nr_pages); - commit_pages(dev); - } - } - - if(readpages) { - err = read_pages(dev, pagenrs, pagelst, readpages); - if(err < 0) - goto readin_err; - } + DEBUG(3, "blkmtd: write: start_len = %zd len = %zd end_len = %zd pagecnt = %d\n", + start_len, len, end_len, pagecnt); if(start_len) { /* do partial start region */ struct page *page; - DEBUG(3, "blkmtd: write: doing partial start, page = %d len = %d offset = %d\n", + DEBUG(3, "blkmtd: write: doing partial start, page = %d len = %zd offset = %d\n", pagenr, start_len, offset); - page = pagelst[0]; + BUG_ON(!buf); - if(PageDirty(page) && pagenr != ignorepage) { - err("to = %lld start_len = %d len = %d end_len = %d pagenr = %d ignorepage = %d\n", - to, start_len, len, end_len, pagenr, ignorepage); + page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev); + lock_page(page); + if(PageDirty(page)) { + err("to = %lld start_len = %zd len = %zd end_len = %zd pagenr = %d\n", + to, start_len, len, end_len, pagenr); BUG(); } memcpy(page_address(page)+offset, buf, start_len); SetPageDirty(page); SetPageUptodate(page); - unlock_page(page); buf += start_len; - *retlen = start_len; - err = 0; - iobuf->blocks[iobuf->nr_pages] = pagenr++; - iobuf->maplist[iobuf->nr_pages] = page; - iobuf->nr_pages++; + thislen = start_len; + bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt); + if(!bio) { + err = -ENOMEM; + err("bio_add_page failed\n"); + goto write_err; + } + pagecnt--; + pagenr++; } /* Now do the main loop to a page aligned, n page sized output */ @@ -342,12 +313,12 @@ /* see if page is in the page cache */ DEBUG(3, "blkmtd: write: grabbing page %d from page cache\n", pagenr); - page = grab_cache_page(dev->binding->bd_inode->i_mapping, pagenr); - if(PageDirty(page) && pagenr != ignorepage) { + page = grab_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr); + if(PageDirty(page)) { BUG(); } if(!page) { - warn("write: cant grab cache page %d", pagenr); + warn("write: cannot grab cache page %d", pagenr); err = -ENOMEM; goto write_err; } @@ -357,50 +328,58 @@ memcpy(page_address(page), buf, PAGE_SIZE); buf += PAGE_SIZE; } - iobuf->blocks[iobuf->nr_pages] = pagenr++; - iobuf->maplist[iobuf->nr_pages] = page; - iobuf->nr_pages++; + bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt); + if(!bio) { + err = -ENOMEM; + err("bio_add_page failed\n"); + goto write_err; + } + pagenr++; + pagecnt--; SetPageDirty(page); SetPageUptodate(page); - unlock_page(page); pagesc--; - *retlen += PAGE_SIZE; + thislen += PAGE_SIZE; } } if(end_len) { /* do the third region */ struct page *page; - DEBUG(3, "blkmtd: write: doing partial end, page = %d len = %d\n", + DEBUG(3, "blkmtd: write: doing partial end, page = %d len = %zd\n", pagenr, end_len); - page = pagelst[readpages-1]; BUG_ON(!buf); - if(PageDirty(page) && pagenr != ignorepage) { - err("to = %lld start_len = %d len = %d end_len = %d pagenr = %d ignorepage = %d\n", - to, start_len, len, end_len, pagenr, ignorepage); + page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev); + lock_page(page); + if(PageDirty(page)) { + err("to = %lld start_len = %zd len = %zd end_len = %zd pagenr = %d\n", + to, start_len, len, end_len, pagenr); BUG(); } memcpy(page_address(page), buf, end_len); SetPageDirty(page); SetPageUptodate(page); - unlock_page(page); DEBUG(3, "blkmtd: write: writing out partial end\n"); - *retlen += end_len; - err = 0; - iobuf->blocks[iobuf->nr_pages] = pagenr; - iobuf->maplist[iobuf->nr_pages] = page; - iobuf->nr_pages++; + thislen += end_len; + bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt); + if(!bio) { + err = -ENOMEM; + err("bio_add_page failed\n"); + goto write_err; + } + pagenr++; } - DEBUG(2, "blkmtd: write: end, retlen = %d, err = %d\n", *retlen, err); - - if(sync) { -write_err: - commit_pages(dev); - } + DEBUG(3, "blkmtd: write: got %d vectors to write\n", bio->bi_vcnt); + write_err: + if(bio) + blkmtd_write_out(bio); -readin_err: + DEBUG(2, "blkmtd: write: end, retlen = %zd, err = %d\n", *retlen, err); up(&dev->wrbuf_mutex); + + if(retlen) + *retlen = thislen; return err; } @@ -414,23 +393,15 @@ size_t from; u_long len; int err = -EIO; - int retlen; - - /* check readonly */ - if(!dev->wr_buf) { - err("error: mtd%d trying to erase readonly device %s", - mtd->index, mtd->name); - instr->state = MTD_ERASE_FAILED; - goto erase_callback; - } + size_t retlen; instr->state = MTD_ERASING; from = instr->addr; len = instr->len; /* check erase region has valid start and length */ - DEBUG(2, "blkmtd: erase: dev = `%s' from = 0x%x len = 0x%lx\n", - bdevname(dev->binding->bd_dev), from, len); + DEBUG(2, "blkmtd: erase: dev = `%s' from = 0x%zx len = 0x%lx\n", + mtd->name+9, from, len); while(numregions) { DEBUG(3, "blkmtd: checking erase region = 0x%08X size = 0x%X num = 0x%x\n", einfo->offset, einfo->erasesize, einfo->numblocks); @@ -446,29 +417,25 @@ if(!numregions) { /* Not a valid erase block */ - err("erase: invalid erase request 0x%lX @ 0x%08X", len, from); + err("erase: invalid erase request 0x%lX @ 0x%08zX", len, from); instr->state = MTD_ERASE_FAILED; err = -EIO; } if(instr->state != MTD_ERASE_FAILED) { /* do the erase */ - DEBUG(3, "Doing erase from = %d len = %ld\n", from, len); + DEBUG(3, "Doing erase from = %zd len = %ld\n", from, len); err = write_pages(dev, NULL, from, len, &retlen); - if(err < 0) { + if(err || retlen != len) { err("erase failed err = %d", err); instr->state = MTD_ERASE_FAILED; } else { instr->state = MTD_ERASE_DONE; - err = 0; } } DEBUG(3, "blkmtd: erase: checking callback\n"); - erase_callback: - if (instr->callback) { - (*(instr->callback))(instr); - } + mtd_erase_callback(instr); DEBUG(2, "blkmtd: erase: finished (err = %d)\n", err); return err; } @@ -482,14 +449,15 @@ int err = 0; int offset; int pagenr, pages; - struct page **pagelst; - int *pagenrs; - int i; + size_t thislen = 0; - *retlen = 0; + DEBUG(2, "blkmtd: read: dev = `%s' from = %lld len = %zd buf = %p\n", + mtd->name+9, from, len, buf); - DEBUG(2, "blkmtd: read: dev = `%s' from = %ld len = %d buf = %p\n", - bdevname(dev->binding->bd_dev), (long int)from, len, buf); + if(from > mtd->size) + return -EINVAL; + if(from + len > mtd->size) + len = mtd->size - from; pagenr = from >> PAGE_SHIFT; offset = from - (pagenr << PAGE_SHIFT); @@ -498,48 +466,35 @@ DEBUG(3, "blkmtd: read: pagenr = %d offset = %d, pages = %d\n", pagenr, offset, pages); - pagelst = kmalloc(sizeof(struct page *) * pages, GFP_KERNEL); - if(!pagelst) - return -ENOMEM; - pagenrs = kmalloc(sizeof(int) * pages, GFP_KERNEL); - if(!pagenrs) { - kfree(pagelst); - return -ENOMEM; - } - for(i = 0; i < pages; i++) - pagenrs[i] = pagenr+i; - - err = read_pages(dev, pagenrs, pagelst, pages); - if(err) - goto readerr; - - pagenr = 0; while(pages) { struct page *page; int cpylen; DEBUG(3, "blkmtd: read: looking for page: %d\n", pagenr); - page = pagelst[pagenr]; + page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev); + if(IS_ERR(page)) { + err = -EIO; + goto readerr; + } cpylen = (PAGE_SIZE > len) ? len : PAGE_SIZE; if(offset+cpylen > PAGE_SIZE) cpylen = PAGE_SIZE-offset; - memcpy(buf + *retlen, page_address(page) + offset, cpylen); + memcpy(buf + thislen, page_address(page) + offset, cpylen); offset = 0; len -= cpylen; - *retlen += cpylen; + thislen += cpylen; pagenr++; pages--; - unlock_page(page); if(!PageDirty(page)) page_cache_release(page); } readerr: - kfree(pagelst); - kfree(pagenrs); - DEBUG(2, "blkmtd: end read: retlen = %d, err = %d\n", *retlen, err); + if(retlen) + *retlen = thislen; + DEBUG(2, "blkmtd: end read: retlen = %zd, err = %d\n", thislen, err); return err; } @@ -551,32 +506,22 @@ struct blkmtd_dev *dev = mtd->priv; int err; - *retlen = 0; if(!len) return 0; - DEBUG(2, "blkmtd: write: dev = `%s' to = %ld len = %d buf = %p\n", - bdevname(dev->binding->bd_dev), (long int)to, len, buf); - - /* handle readonly and out of range numbers */ - - if(!dev->wr_buf) { - err("error: trying to write to a readonly device %s", mtd->name); - return -EROFS; - } + DEBUG(2, "blkmtd: write: dev = `%s' to = %lld len = %zd buf = %p\n", + mtd->name+9, to, len, buf); if(to >= mtd->size) { return -ENOSPC; } if(to + len > mtd->size) { - len = (mtd->size - to); + len = mtd->size - to; } err = write_pages(dev, buf, to, len, retlen); - if(err < 0) - *retlen = 0; - else + if(err > 0) err = 0; DEBUG(2, "blkmtd: write: end, err = %d\n", err); return err; @@ -586,124 +531,22 @@ /* sync the device - wait until the write queue is empty */ static void blkmtd_sync(struct mtd_info *mtd) { - struct blkmtd_dev *dev = mtd->priv; - struct kiobuf *iobuf = dev->wr_buf; - - DEBUG(2, "blkmtd: sync: called\n"); - if(iobuf == NULL) - return; - - DEBUG(3, "blkmtd: kiovec: length = %d nr_pages = %d\n", - iobuf->length, iobuf->nr_pages); - down(&dev->wrbuf_mutex); - if(iobuf->nr_pages) - commit_pages(dev); - up(&dev->wrbuf_mutex); + /* Currently all writes are synchronous */ } -#ifdef BLKMTD_PROC_DEBUG -/* procfs stuff */ -static int blkmtd_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len; - struct list_head *temp1, *temp2; - - MOD_INC_USE_COUNT; - - /* Count the size of the page lists */ - - len = sprintf(page, "dev\twr_idx\tmax_idx\tnrpages\tclean\tdirty\tlocked\tlru\n"); - list_for_each_safe(temp1, temp2, &blkmtd_device_list) { - struct blkmtd_dev *dev = list_entry(temp1, struct blkmtd_dev, - list); - struct list_head *temp; - struct page *pagei; - - int clean = 0, dirty = 0, locked = 0, lru = 0; - /* Count the size of the page lists */ - list_for_each(temp, &dev->binding->bd_inode->i_mapping->clean_pages) { - pagei = list_entry(temp, struct page, list); - clean++; - if(PageLocked(pagei)) - locked++; - if(PageDirty(pagei)) - dirty++; - if(PageLRU(pagei)) - lru++; - } - list_for_each(temp, &dev->binding->bd_inode->i_mapping->dirty_pages) { - pagei = list_entry(temp, struct page, list); - if(PageLocked(pagei)) - locked++; - if(PageDirty(pagei)) - dirty++; - if(PageLRU(pagei)) - lru++; - } - list_for_each(temp, &dev->binding->bd_inode->i_mapping->locked_pages) { - pagei = list_entry(temp, struct page, list); - if(PageLocked(pagei)) - locked++; - if(PageDirty(pagei)) - dirty++; - if(PageLRU(pagei)) - lru++; - } - - len += sprintf(page+len, "mtd%d:\t%ld\t%d\t%ld\t%d\t%d\t%d\t%d\n", - dev->mtd_info.index, - (dev->wr_buf && dev->wr_buf->nr_pages) ? - dev->wr_buf->blocks[dev->wr_buf->nr_pages-1] : 0, - (dev->wr_buf) ? dev->wr_buf->nr_pages : 0, - dev->binding->bd_inode->i_mapping->nrpages, - clean, dirty, locked, lru); - } - - if(len <= count) - *eof = 1; - - MOD_DEC_USE_COUNT; - return len; -} -#endif - - static void free_device(struct blkmtd_dev *dev) { DEBUG(2, "blkmtd: free_device() dev = %p\n", dev); if(dev) { - del_mtd_device(&dev->mtd_info); - info("mtd%d: [%s] removed", dev->mtd_info.index, - dev->mtd_info.name + strlen("blkmtd: ")); if(dev->mtd_info.eraseregions) kfree(dev->mtd_info.eraseregions); if(dev->mtd_info.name) kfree(dev->mtd_info.name); - if(dev->rd_buf) { - dev->rd_buf->locked = 0; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4) - if(dev->rd_buf->blocks) - kfree(dev->rd_buf->blocks); -#endif - free_kiovec(1, &dev->rd_buf); - } - if(dev->wr_buf) { - dev->wr_buf->locked = 0; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4) - if(dev->wr_buf->blocks) - kfree(dev->rw_buf->blocks); -#endif - free_kiovec(1, &dev->wr_buf); - } - - if(dev->binding) { - kdev_t kdev = to_kdev_t(dev->binding->bd_dev); - invalidate_inode_pages(dev->binding->bd_inode); - set_blocksize(kdev, 1 << 10); - blkdev_put(dev->binding, BDEV_RAW); + if(dev->blkdev) { + invalidate_inode_pages(dev->blkdev->bd_inode->i_mapping); + close_bdev_excl(dev->blkdev); } kfree(dev); } @@ -720,7 +563,7 @@ { struct mtd_erase_region_info *info = NULL; - DEBUG(2, "calc_erase_regions, es = %d size = %d regions = %d\n", + DEBUG(2, "calc_erase_regions, es = %zd size = %zd regions = %d\n", erase_size, total_size, *regions); /* Make any user specified erasesize be a power of 2 and at least PAGE_SIZE */ @@ -768,119 +611,62 @@ break; } } while(!(*regions)); - DEBUG(2, "calc_erase_regions done, es = %d size = %d regions = %d\n", + DEBUG(2, "calc_erase_regions done, es = %zd size = %zd regions = %d\n", erase_size, total_size, *regions); return info; } -extern kdev_t name_to_kdev_t(char *line) __init; - +extern dev_t __init name_to_dev_t(const char *line); static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size) { - int maj, min; - kdev_t kdev; + struct block_device *bdev; int mode; struct blkmtd_dev *dev; -#ifdef MODULE - struct file *file = NULL; - struct inode *inode; -#endif - if(!devname) return NULL; /* Get a handle on the device */ - mode = (readonly) ? O_RDONLY : O_RDWR; -#ifdef MODULE - file = filp_open(devname, mode, 0); - if(IS_ERR(file)) { - err("error: cant open device %s", devname); - DEBUG(2, "blkmtd: filp_open returned %ld\n", PTR_ERR(file)); - return NULL; - } - - /* determine is this is a block device and - * if so get its major and minor numbers - */ - inode = file->f_dentry->d_inode; - if(!S_ISBLK(inode->i_mode)) { - err("%s not a block device", devname); - filp_close(file, NULL); - return NULL; - } - kdev = inode->i_rdev; - filp_close(file, NULL); +#ifdef MODULE + mode = (readonly) ? O_RDONLY : O_RDWR; + bdev = open_bdev_excl(devname, mode, NULL); #else - kdev = name_to_kdev_t(devname); -#endif /* MODULE */ - - if(!kdev) { - err("bad block device: `%s'", devname); + mode = (readonly) ? FMODE_READ : FMODE_WRITE; + bdev = open_by_devnum(name_to_dev_t(devname), mode); +#endif + if(IS_ERR(bdev)) { + err("error: cannot open device %s", devname); + DEBUG(2, "blkmtd: opening bdev returned %ld\n", PTR_ERR(bdev)); return NULL; } - maj = MAJOR(kdev); - min = MINOR(kdev); DEBUG(1, "blkmtd: found a block device major = %d, minor = %d\n", - maj, min); + MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev)); - if(maj == MTD_BLOCK_MAJOR) { + if(MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) { err("attempting to use an MTD device as a block device"); + blkdev_put(bdev); return NULL; } - DEBUG(1, "blkmtd: devname = %s\n", bdevname(kdev)); - dev = kmalloc(sizeof(struct blkmtd_dev), GFP_KERNEL); - if(dev == NULL) + if(dev == NULL) { + blkdev_put(bdev); return NULL; + } memset(dev, 0, sizeof(struct blkmtd_dev)); - if(alloc_kiovec(1, &dev->rd_buf)) { - err("cant allocate read iobuf"); - goto devinit_err; - } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4) - dev->rd_buf->blocks = kmalloc(KIO_MAX_SECTORS * sizeof(unsigned long), GFP_KERNEL); - if(dev->rd_buf->blocks == NULL) { - crit("cant allocate rd_buf blocks"); - goto devinit_err; - } -#endif - + dev->blkdev = bdev; + atomic_set(&(dev->blkdev->bd_inode->i_mapping->truncate_count), 0); if(!readonly) { - if(alloc_kiovec(1, &dev->wr_buf)) { - err("cant allocate kiobuf - readonly enabled"); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4) - } else { - dev->wr_buf->blocks = kmalloc(KIO_MAX_SECTORS * sizeof(unsigned long), GFP_KERNEL); - if(dev->wr_buf->blocks == NULL) { - crit("cant allocate wr_buf blocks - readonly enabled"); - free_kiovec(1, &iobuf); - } -#endif - } - if(dev->wr_buf) - init_MUTEX(&dev->wrbuf_mutex); - } - - /* get the block device */ - dev->binding = bdget(kdev_t_to_nr(MKDEV(maj, min))); - if(blkdev_get(dev->binding, mode, 0, BDEV_RAW)) - goto devinit_err; - - if(set_blocksize(kdev, PAGE_SIZE)) { - err("cant set block size to PAGE_SIZE on %s", bdevname(kdev)); - goto devinit_err; + init_MUTEX(&dev->wrbuf_mutex); } - dev->mtd_info.size = dev->binding->bd_inode->i_size & PAGE_MASK; + dev->mtd_info.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; /* Setup the MTD structure */ /* make the name contain the block device in */ @@ -904,27 +690,26 @@ } else { dev->mtd_info.type = MTD_RAM; dev->mtd_info.flags = MTD_CAP_RAM; + dev->mtd_info.erase = blkmtd_erase; + dev->mtd_info.write = blkmtd_write; + dev->mtd_info.writev = default_mtd_writev; + dev->mtd_info.sync = blkmtd_sync; } - dev->mtd_info.erase = blkmtd_erase; dev->mtd_info.read = blkmtd_read; - dev->mtd_info.write = blkmtd_write; - dev->mtd_info.sync = blkmtd_sync; - dev->mtd_info.point = 0; - dev->mtd_info.unpoint = 0; + dev->mtd_info.readv = default_mtd_readv; dev->mtd_info.priv = dev; - dev->mtd_info.module = THIS_MODULE; + dev->mtd_info.owner = THIS_MODULE; list_add(&dev->list, &blkmtd_device_list); if (add_mtd_device(&dev->mtd_info)) { /* Device didnt get added, so free the entry */ list_del(&dev->list); - free_device(dev); - return NULL; + goto devinit_err; } else { info("mtd%d: [%s] erase_size = %dKiB %s", dev->mtd_info.index, dev->mtd_info.name + strlen("blkmtd: "), dev->mtd_info.erasesize >> 10, - (dev->wr_buf) ? "" : "(read-only)"); + readonly ? "(read-only)" : ""); } return dev; @@ -939,17 +724,16 @@ static void __devexit cleanup_blkmtd(void) { struct list_head *temp1, *temp2; -#ifdef BLKMTD_PROC_DEBUG - if(blkmtd_proc) { - remove_proc_entry("blkmtd_debug", NULL); - } -#endif /* Remove the MTD devices */ list_for_each_safe(temp1, temp2, &blkmtd_device_list) { struct blkmtd_dev *dev = list_entry(temp1, struct blkmtd_dev, list); blkmtd_sync(&dev->mtd_info); + del_mtd_device(&dev->mtd_info); + info("mtd%d: [%s] removed", dev->mtd_info.index, + dev->mtd_info.name + strlen("blkmtd: ")); + list_del(&dev->list); free_device(dev); } } @@ -1020,6 +804,7 @@ { int i; + info("version " VERSION); /* Check args - device[0] is the bare minimum*/ if(!device[0]) { err("error: missing `device' name\n"); @@ -1030,28 +815,9 @@ add_device(device[i], ro[i], erasesz[i] << 10); if(list_empty(&blkmtd_device_list)) - goto init_err; - - info("version " VERSION); - -#ifdef BLKMTD_PROC_DEBUG - /* create proc entry */ - DEBUG(2, "Creating /proc/blkmtd_debug\n"); - blkmtd_proc = create_proc_read_entry("blkmtd_debug", 0444, - NULL, blkmtd_proc_read, NULL); - if(blkmtd_proc == NULL) { - err("Cant create /proc/blkmtd_debug"); - } else { - blkmtd_proc->owner = THIS_MODULE; - } -#endif - - if(!list_empty(&blkmtd_device_list)) - /* Everything is ok if we got here */ - return 0; + return -EINVAL; - init_err: - return -EINVAL; + return 0; } module_init(init_blkmtd); Index: drivers/mtd/devices/doc1000.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/devices/doc1000.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/mtd/devices/doc1000.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/devices/doc1000.c 4 Aug 2004 01:29:05 -0000 1.2 @@ -1,6 +1,6 @@ /*====================================================================== - $Id: doc1000.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + $Id: doc1000.c,v 1.2 2004/08/04 01:29:05 joff Exp $ ======================================================================*/ Index: drivers/mtd/devices/doc2000.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/devices/doc2000.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/devices/doc2000.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/devices/doc2000.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -4,7 +4,7 @@ * (c) 1999 Machine Vision Holdings, Inc. * (c) 1999, 2000 David Woodhouse * - * $Id: doc2000.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: doc2000.c,v 1.3 2004/11/03 00:04:43 joff Exp $ */ #include @@ -19,12 +19,14 @@ #include #include #include +#include #include #include #include #define DOC_SUPPORT_2000 +#define DOC_SUPPORT_2000TSOP #define DOC_SUPPORT_MILLENNIUM #ifdef DOC_SUPPORT_2000 @@ -33,7 +35,7 @@ #define DoC_is_2000(doc) (0) #endif -#ifdef DOC_SUPPORT_MILLENNIUM +#if defined(DOC_SUPPORT_2000TSOP) || defined(DOC_SUPPORT_MILLENNIUM) #define DoC_is_Millennium(doc) (doc->ChipID == DOC_ChipID_DocMil) #else #define DoC_is_Millennium(doc) (0) @@ -53,9 +55,12 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel); + size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf, u_char *eccbuf, int oobsel); + size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); +static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, + unsigned long count, loff_t to, size_t *retlen, + u_char *eccbuf, struct nand_oobinfo *oobsel); static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, size_t *retlen, u_char *buf); static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, @@ -84,7 +89,7 @@ /* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */ static int _DoC_WaitReady(struct DiskOnChip *doc) { - unsigned long docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; unsigned long timeo = jiffies + (HZ * 10); DEBUG(MTD_DEBUG_LEVEL3, @@ -92,6 +97,10 @@ /* Out-of-line routine to wait for chip response */ while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) { + /* issue 2 read from NOP register after reading from CDSNControl register + see Software Requirement 11.4 item 2. */ + DoC_Delay(doc, 2); + if (time_after(jiffies, timeo)) { DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n"); return -EIO; @@ -105,7 +114,8 @@ static inline int DoC_WaitReady(struct DiskOnChip *doc) { - unsigned long docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; + /* This is inline, to optimise the common case, where it's ready instantly */ int ret = 0; @@ -131,7 +141,7 @@ static inline int DoC_Command(struct DiskOnChip *doc, unsigned char command, unsigned char xtraflags) { - unsigned long docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; if (DoC_is_2000(doc)) xtraflags |= CDSN_CTRL_FLASH_IO; @@ -145,6 +155,8 @@ /* Send the command */ WriteDOC_(command, docptr, doc->ioreg); + if (DoC_is_Millennium(doc)) + WriteDOC(command, docptr, WritePipeTerm); /* Lower the CLE line */ WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl); @@ -161,10 +173,8 @@ static int DoC_Address(struct DiskOnChip *doc, int numbytes, unsigned long ofs, unsigned char xtraflags1, unsigned char xtraflags2) { - unsigned long docptr; int i; - - docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; if (DoC_is_2000(doc)) xtraflags1 |= CDSN_CTRL_FLASH_IO; @@ -206,6 +216,9 @@ } } + if (DoC_is_Millennium(doc)) + WriteDOC(ofs & 0xff, docptr, WritePipeTerm); + DoC_Delay(doc, 2); /* Needed for some slow flash chips. mf. */ /* FIXME: The SlowIO's for millennium could be replaced by @@ -226,11 +239,9 @@ { volatile int dummy; int modulus = 0xffff; - unsigned long docptr; + void __iomem *docptr = doc->virtadr; int i; - docptr = doc->virtadr; - if (len <= 0) return; @@ -257,11 +268,9 @@ /* Write a buffer to DoC, taking care of Millennium odditys */ static void DoC_WriteBuf(struct DiskOnChip *doc, const u_char * buf, int len) { - unsigned long docptr; + void __iomem *docptr = doc->virtadr; int i; - docptr = doc->virtadr; - if (len <= 0) return; @@ -278,7 +287,7 @@ static inline int DoC_SelectChip(struct DiskOnChip *doc, int chip) { - unsigned long docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; /* Software requirement 11.4.4 before writing DeviceSelect */ /* Deassert the CE line to eliminate glitches on the FCE# outputs */ @@ -302,7 +311,7 @@ static inline int DoC_SelectFloor(struct DiskOnChip *doc, int floor) { - unsigned long docptr = doc->virtadr; + void __iomem *docptr = doc->virtadr; /* Select the floor (bank) of chips required */ WriteDOC(floor, docptr, FloorSelect); @@ -344,15 +353,25 @@ /* Read the manufacturer and device id codes from the device */ - /* CDSN Slow IO register see Software Requirement 11.4 item 5. */ - dummy = ReadDOC(doc->virtadr, CDSNSlowIO); - DoC_Delay(doc, 2); - mfr = ReadDOC_(doc->virtadr, doc->ioreg); - - /* CDSN Slow IO register see Software Requirement 11.4 item 5. */ - dummy = ReadDOC(doc->virtadr, CDSNSlowIO); - DoC_Delay(doc, 2); - id = ReadDOC_(doc->virtadr, doc->ioreg); + if (DoC_is_Millennium(doc)) { + DoC_Delay(doc, 2); + dummy = ReadDOC(doc->virtadr, ReadPipeInit); + mfr = ReadDOC(doc->virtadr, LastDataRead); + + DoC_Delay(doc, 2); + dummy = ReadDOC(doc->virtadr, ReadPipeInit); + id = ReadDOC(doc->virtadr, LastDataRead); + } else { + /* CDSN Slow IO register see Software Req 11.4 item 5. */ + dummy = ReadDOC(doc->virtadr, CDSNSlowIO); + DoC_Delay(doc, 2); + mfr = ReadDOC_(doc->virtadr, doc->ioreg); + + /* CDSN Slow IO register see Software Req 11.4 item 5. */ + dummy = ReadDOC(doc->virtadr, CDSNSlowIO); + DoC_Delay(doc, 2); + id = ReadDOC_(doc->virtadr, doc->ioreg); + } /* No response - return failure */ if (mfr == 0xff || mfr == 0) @@ -386,11 +405,10 @@ if (!doc->mfr) { doc->mfr = mfr; doc->id = id; - doc->chipshift = - nand_flash_ids[i].chipshift; - doc->page256 = nand_flash_ids[i].page256; - doc->pageadrlen = - nand_flash_ids[i].chipshift > 25 ? 3 : 2; + doc->chipshift = + ffs((nand_flash_ids[i].chipsize << 20)) - 1; + doc->page256 = (nand_flash_ids[i].pagesize == 256) ? 1 : 0; + doc->pageadrlen = doc->chipshift > 25 ? 3 : 2; doc->erasesize = nand_flash_ids[i].erasesize; return 1; @@ -410,20 +428,16 @@ /* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */ -static void DoC_ScanChips(struct DiskOnChip *this) +static void DoC_ScanChips(struct DiskOnChip *this, int maxchips) { int floor, chip; int numchips[MAX_FLOORS]; - int maxchips = MAX_CHIPS; int ret = 1; this->numchips = 0; this->mfr = 0; this->id = 0; - if (DoC_is_Millennium(this)) - maxchips = MAX_CHIPS_MIL; - /* For each floor, find the number of valid chips it contains */ for (floor = 0; floor < MAX_FLOORS; floor++) { ret = 1; @@ -515,6 +529,7 @@ { struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv; struct DiskOnChip *old = NULL; + int maxchips; /* We must avoid being called twice for the same device. */ @@ -538,14 +553,28 @@ switch (this->ChipID) { + case DOC_ChipID_Doc2kTSOP: + mtd->name = "DiskOnChip 2000 TSOP"; + this->ioreg = DoC_Mil_CDSN_IO; + /* Pretend it's a Millennium */ + this->ChipID = DOC_ChipID_DocMil; + maxchips = MAX_CHIPS; + break; case DOC_ChipID_Doc2k: mtd->name = "DiskOnChip 2000"; this->ioreg = DoC_2k_CDSN_IO; + maxchips = MAX_CHIPS; break; case DOC_ChipID_DocMil: mtd->name = "DiskOnChip Millennium"; this->ioreg = DoC_Mil_CDSN_IO; + maxchips = MAX_CHIPS_MIL; break; + default: + printk("Unknown ChipID 0x%02x\n", this->ChipID); + kfree(mtd); + iounmap((void *) this->virtadr); + return; } printk(KERN_NOTICE "%s found at address 0x%lX\n", mtd->name, @@ -553,11 +582,12 @@ mtd->type = MTD_NANDFLASH; mtd->flags = MTD_CAP_NANDFLASH; + mtd->ecctype = MTD_ECC_RS_DiskOnChip; mtd->size = 0; mtd->erasesize = 0; mtd->oobblock = 512; mtd->oobsize = 16; - mtd->module = THIS_MODULE; + mtd->owner = THIS_MODULE; mtd->erase = doc_erase; mtd->point = NULL; mtd->unpoint = NULL; @@ -565,6 +595,7 @@ mtd->write = doc_write; mtd->read_ecc = doc_read_ecc; mtd->write_ecc = doc_write_ecc; + mtd->writev_ecc = doc_writev_ecc; mtd->read_oob = doc_read_oob; mtd->write_oob = doc_write_oob; mtd->sync = NULL; @@ -577,7 +608,7 @@ init_MUTEX(&this->lock); /* Ident all the chips present. */ - DoC_ScanChips(this); + DoC_ScanChips(this, maxchips); if (!this->totlen) { kfree(mtd); @@ -596,20 +627,19 @@ size_t * retlen, u_char * buf) { /* Just a special case of doc_read_ecc */ - return doc_read_ecc(mtd, from, len, retlen, buf, NULL, 0); + return doc_read_ecc(mtd, from, len, retlen, buf, NULL, NULL); } static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, - size_t * retlen, u_char * buf, u_char * eccbuf, int oobsel) + size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel) { struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv; - unsigned long docptr; + void __iomem *docptr = this->virtadr; struct Nand *mychip; unsigned char syndrome[6]; volatile char dummy; int i, len256 = 0, ret=0; - - docptr = this->virtadr; + size_t left = len; /* Don't allow read past end of device */ if (from >= this->totlen) @@ -617,122 +647,131 @@ down(&this->lock); - /* Don't allow a single read to cross a 512-byte block boundary */ - if (from + len > ((from | 0x1ff) + 1)) - len = ((from | 0x1ff) + 1) - from; - - /* The ECC will not be calculated correctly if less than 512 is read */ - if (len != 0x200 && eccbuf) - printk(KERN_WARNING - "ECC needs a full sector read (adr: %lx size %lx)\n", - (long) from, (long) len); + *retlen = 0; + while (left) { + len = left; + + /* Don't allow a single read to cross a 512-byte block boundary */ + if (from + len > ((from | 0x1ff) + 1)) + len = ((from | 0x1ff) + 1) - from; - /* printk("DoC_Read (adr: %lx size %lx)\n", (long) from, (long) len); */ + /* The ECC will not be calculated correctly if less than 512 is read */ + if (len != 0x200 && eccbuf) + printk(KERN_WARNING + "ECC needs a full sector read (adr: %lx size %lx)\n", + (long) from, (long) len); + /* printk("DoC_Read (adr: %lx size %lx)\n", (long) from, (long) len); */ - /* Find the chip which is to be used and select it */ - mychip = &this->chips[from >> (this->chipshift)]; - if (this->curfloor != mychip->floor) { - DoC_SelectFloor(this, mychip->floor); - DoC_SelectChip(this, mychip->chip); - } else if (this->curchip != mychip->chip) { - DoC_SelectChip(this, mychip->chip); - } + /* Find the chip which is to be used and select it */ + mychip = &this->chips[from >> (this->chipshift)]; - this->curfloor = mychip->floor; - this->curchip = mychip->chip; + if (this->curfloor != mychip->floor) { + DoC_SelectFloor(this, mychip->floor); + DoC_SelectChip(this, mychip->chip); + } else if (this->curchip != mychip->chip) { + DoC_SelectChip(this, mychip->chip); + } - DoC_Command(this, - (!this->page256 - && (from & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0, - CDSN_CTRL_WP); - DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP, - CDSN_CTRL_ECC_IO); - - if (eccbuf) { - /* Prime the ECC engine */ - WriteDOC(DOC_ECC_RESET, docptr, ECCConf); - WriteDOC(DOC_ECC_EN, docptr, ECCConf); - } else { - /* disable the ECC engine */ - WriteDOC(DOC_ECC_RESET, docptr, ECCConf); - WriteDOC(DOC_ECC_DIS, docptr, ECCConf); - } + this->curfloor = mychip->floor; + this->curchip = mychip->chip; - /* treat crossing 256-byte sector for 2M x 8bits devices */ - if (this->page256 && from + len > (from | 0xff) + 1) { - len256 = (from | 0xff) + 1 - from; - DoC_ReadBuf(this, buf, len256); + DoC_Command(this, + (!this->page256 + && (from & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0, + CDSN_CTRL_WP); + DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP, + CDSN_CTRL_ECC_IO); - DoC_Command(this, NAND_CMD_READ0, CDSN_CTRL_WP); - DoC_Address(this, ADDR_COLUMN_PAGE, from + len256, - CDSN_CTRL_WP, CDSN_CTRL_ECC_IO); - } + if (eccbuf) { + /* Prime the ECC engine */ + WriteDOC(DOC_ECC_RESET, docptr, ECCConf); + WriteDOC(DOC_ECC_EN, docptr, ECCConf); + } else { + /* disable the ECC engine */ + WriteDOC(DOC_ECC_RESET, docptr, ECCConf); + WriteDOC(DOC_ECC_DIS, docptr, ECCConf); + } - DoC_ReadBuf(this, &buf[len256], len - len256); + /* treat crossing 256-byte sector for 2M x 8bits devices */ + if (this->page256 && from + len > (from | 0xff) + 1) { + len256 = (from | 0xff) + 1 - from; + DoC_ReadBuf(this, buf, len256); + + DoC_Command(this, NAND_CMD_READ0, CDSN_CTRL_WP); + DoC_Address(this, ADDR_COLUMN_PAGE, from + len256, + CDSN_CTRL_WP, CDSN_CTRL_ECC_IO); + } - /* Let the caller know we completed it */ - *retlen = len; + DoC_ReadBuf(this, &buf[len256], len - len256); - if (eccbuf) { - /* Read the ECC data through the DiskOnChip ECC logic */ - /* Note: this will work even with 2M x 8bit devices as */ - /* they have 8 bytes of OOB per 256 page. mf. */ - DoC_ReadBuf(this, eccbuf, 6); + /* Let the caller know we completed it */ + *retlen += len; - /* Flush the pipeline */ - if (DoC_is_Millennium(this)) { - dummy = ReadDOC(docptr, ECCConf); - dummy = ReadDOC(docptr, ECCConf); - i = ReadDOC(docptr, ECCConf); - } else { - dummy = ReadDOC(docptr, 2k_ECCStatus); - dummy = ReadDOC(docptr, 2k_ECCStatus); - i = ReadDOC(docptr, 2k_ECCStatus); - } + if (eccbuf) { + /* Read the ECC data through the DiskOnChip ECC logic */ + /* Note: this will work even with 2M x 8bit devices as */ + /* they have 8 bytes of OOB per 256 page. mf. */ + DoC_ReadBuf(this, eccbuf, 6); + + /* Flush the pipeline */ + if (DoC_is_Millennium(this)) { + dummy = ReadDOC(docptr, ECCConf); + dummy = ReadDOC(docptr, ECCConf); + i = ReadDOC(docptr, ECCConf); + } else { + dummy = ReadDOC(docptr, 2k_ECCStatus); + dummy = ReadDOC(docptr, 2k_ECCStatus); + i = ReadDOC(docptr, 2k_ECCStatus); + } - /* Check the ECC Status */ - if (i & 0x80) { - int nb_errors; - /* There was an ECC error */ + /* Check the ECC Status */ + if (i & 0x80) { + int nb_errors; + /* There was an ECC error */ #ifdef ECC_DEBUG - printk(KERN_ERR "DiskOnChip ECC Error: Read at %lx\n", (long)from); + printk(KERN_ERR "DiskOnChip ECC Error: Read at %lx\n", (long)from); #endif - /* Read the ECC syndrom through the DiskOnChip ECC logic. - These syndrome will be all ZERO when there is no error */ - for (i = 0; i < 6; i++) { - syndrome[i] = - ReadDOC(docptr, ECCSyndrome0 + i); - } - nb_errors = doc_decode_ecc(buf, syndrome); + /* Read the ECC syndrom through the DiskOnChip ECC logic. + These syndrome will be all ZERO when there is no error */ + for (i = 0; i < 6; i++) { + syndrome[i] = + ReadDOC(docptr, ECCSyndrome0 + i); + } + nb_errors = doc_decode_ecc(buf, syndrome); #ifdef ECC_DEBUG - printk(KERN_ERR "Errors corrected: %x\n", nb_errors); + printk(KERN_ERR "Errors corrected: %x\n", nb_errors); #endif - if (nb_errors < 0) { - /* We return error, but have actually done the read. Not that - this can be told to user-space, via sys_read(), but at least - MTD-aware stuff can know about it by checking *retlen */ - ret = -EIO; - } - } + if (nb_errors < 0) { + /* We return error, but have actually done the read. Not that + this can be told to user-space, via sys_read(), but at least + MTD-aware stuff can know about it by checking *retlen */ + ret = -EIO; + } + } #ifdef PSYCHO_DEBUG - printk(KERN_DEBUG "ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", - (long)from, eccbuf[0], eccbuf[1], eccbuf[2], - eccbuf[3], eccbuf[4], eccbuf[5]); + printk(KERN_DEBUG "ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", + (long)from, eccbuf[0], eccbuf[1], eccbuf[2], + eccbuf[3], eccbuf[4], eccbuf[5]); #endif - /* disable the ECC engine */ - WriteDOC(DOC_ECC_DIS, docptr , ECCConf); - } + /* disable the ECC engine */ + WriteDOC(DOC_ECC_DIS, docptr , ECCConf); + } - /* according to 11.4.1, we need to wait for the busy line - * drop if we read to the end of the page. */ - if(0 == ((from + *retlen) & 0x1ff)) - { - DoC_WaitReady(this); + /* according to 11.4.1, we need to wait for the busy line + * drop if we read to the end of the page. */ + if(0 == ((from + len) & 0x1ff)) + { + DoC_WaitReady(this); + } + + from += len; + left -= len; + buf += len; } up(&this->lock); @@ -744,21 +783,21 @@ size_t * retlen, const u_char * buf) { char eccbuf[6]; - return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf, 0); + return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf, NULL); } static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf, - u_char * eccbuf, int oobsel) + u_char * eccbuf, struct nand_oobinfo *oobsel) { struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv; int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */ - unsigned long docptr; + void __iomem *docptr = this->virtadr; volatile char dummy; int len256 = 0; struct Nand *mychip; - - docptr = this->virtadr; + size_t left = len; + int status; /* Don't allow write past end of device */ if (to >= this->totlen) @@ -766,65 +805,133 @@ down(&this->lock); - /* Don't allow a single write to cross a 512-byte block boundary */ - if (to + len > ((to | 0x1ff) + 1)) - len = ((to | 0x1ff) + 1) - to; - - /* The ECC will not be calculated correctly if less than 512 is written */ - if (len != 0x200 && eccbuf) - printk(KERN_WARNING - "ECC needs a full sector write (adr: %lx size %lx)\n", - (long) to, (long) len); + *retlen = 0; + while (left) { + len = left; + + /* Don't allow a single write to cross a 512-byte block boundary */ + if (to + len > ((to | 0x1ff) + 1)) + len = ((to | 0x1ff) + 1) - to; + + /* The ECC will not be calculated correctly if less than 512 is written */ +/* DBB- + if (len != 0x200 && eccbuf) + printk(KERN_WARNING + "ECC needs a full sector write (adr: %lx size %lx)\n", + (long) to, (long) len); + -DBB */ - /* printk("DoC_Write (adr: %lx size %lx)\n", (long) to, (long) len); */ + /* printk("DoC_Write (adr: %lx size %lx)\n", (long) to, (long) len); */ - /* Find the chip which is to be used and select it */ - mychip = &this->chips[to >> (this->chipshift)]; + /* Find the chip which is to be used and select it */ + mychip = &this->chips[to >> (this->chipshift)]; - if (this->curfloor != mychip->floor) { - DoC_SelectFloor(this, mychip->floor); - DoC_SelectChip(this, mychip->chip); - } else if (this->curchip != mychip->chip) { - DoC_SelectChip(this, mychip->chip); - } + if (this->curfloor != mychip->floor) { + DoC_SelectFloor(this, mychip->floor); + DoC_SelectChip(this, mychip->chip); + } else if (this->curchip != mychip->chip) { + DoC_SelectChip(this, mychip->chip); + } - this->curfloor = mychip->floor; - this->curchip = mychip->chip; + this->curfloor = mychip->floor; + this->curchip = mychip->chip; - /* Set device to main plane of flash */ - DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP); - DoC_Command(this, - (!this->page256 - && (to & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0, - CDSN_CTRL_WP); + /* Set device to main plane of flash */ + DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP); + DoC_Command(this, + (!this->page256 + && (to & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0, + CDSN_CTRL_WP); - DoC_Command(this, NAND_CMD_SEQIN, 0); - DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO); + DoC_Command(this, NAND_CMD_SEQIN, 0); + DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO); - if (eccbuf) { - /* Prime the ECC engine */ - WriteDOC(DOC_ECC_RESET, docptr, ECCConf); - WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf); - } else { - /* disable the ECC engine */ - WriteDOC(DOC_ECC_RESET, docptr, ECCConf); - WriteDOC(DOC_ECC_DIS, docptr, ECCConf); - } + if (eccbuf) { + /* Prime the ECC engine */ + WriteDOC(DOC_ECC_RESET, docptr, ECCConf); + WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf); + } else { + /* disable the ECC engine */ + WriteDOC(DOC_ECC_RESET, docptr, ECCConf); + WriteDOC(DOC_ECC_DIS, docptr, ECCConf); + } - /* treat crossing 256-byte sector for 2M x 8bits devices */ - if (this->page256 && to + len > (to | 0xff) + 1) { - len256 = (to | 0xff) + 1 - to; - DoC_WriteBuf(this, buf, len256); + /* treat crossing 256-byte sector for 2M x 8bits devices */ + if (this->page256 && to + len > (to | 0xff) + 1) { + len256 = (to | 0xff) + 1 - to; + DoC_WriteBuf(this, buf, len256); + + DoC_Command(this, NAND_CMD_PAGEPROG, 0); + + DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP); + /* There's an implicit DoC_WaitReady() in DoC_Command */ + + dummy = ReadDOC(docptr, CDSNSlowIO); + DoC_Delay(this, 2); + + if (ReadDOC_(docptr, this->ioreg) & 1) { + printk(KERN_ERR "Error programming flash\n"); + /* Error in programming */ + *retlen = 0; + up(&this->lock); + return -EIO; + } + + DoC_Command(this, NAND_CMD_SEQIN, 0); + DoC_Address(this, ADDR_COLUMN_PAGE, to + len256, 0, + CDSN_CTRL_ECC_IO); + } + + DoC_WriteBuf(this, &buf[len256], len - len256); + + if (eccbuf) { + WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr, + CDSNControl); + + if (DoC_is_Millennium(this)) { + WriteDOC(0, docptr, NOP); + WriteDOC(0, docptr, NOP); + WriteDOC(0, docptr, NOP); + } else { + WriteDOC_(0, docptr, this->ioreg); + WriteDOC_(0, docptr, this->ioreg); + WriteDOC_(0, docptr, this->ioreg); + } + + WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_FLASH_IO | CDSN_CTRL_CE, docptr, + CDSNControl); + + /* Read the ECC data through the DiskOnChip ECC logic */ + for (di = 0; di < 6; di++) { + eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di); + } + + /* Reset the ECC engine */ + WriteDOC(DOC_ECC_DIS, docptr, ECCConf); + +#ifdef PSYCHO_DEBUG + printk + ("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", + (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], + eccbuf[4], eccbuf[5]); +#endif + } DoC_Command(this, NAND_CMD_PAGEPROG, 0); DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP); /* There's an implicit DoC_WaitReady() in DoC_Command */ - dummy = ReadDOC(docptr, CDSNSlowIO); - DoC_Delay(this, 2); + if (DoC_is_Millennium(this)) { + ReadDOC(docptr, ReadPipeInit); + status = ReadDOC(docptr, LastDataRead); + } else { + dummy = ReadDOC(docptr, CDSNSlowIO); + DoC_Delay(this, 2); + status = ReadDOC_(docptr, this->ioreg); + } - if (ReadDOC_(docptr, this->ioreg) & 1) { + if (status & 1) { printk(KERN_ERR "Error programming flash\n"); /* Error in programming */ *retlen = 0; @@ -832,94 +939,106 @@ return -EIO; } - DoC_Command(this, NAND_CMD_SEQIN, 0); - DoC_Address(this, ADDR_COLUMN_PAGE, to + len256, 0, - CDSN_CTRL_ECC_IO); + /* Let the caller know we completed it */ + *retlen += len; + + if (eccbuf) { + unsigned char x[8]; + size_t dummy; + int ret; + + /* Write the ECC data to flash */ + for (di=0; di<6; di++) + x[di] = eccbuf[di]; + + x[6]=0x55; + x[7]=0x55; + + ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x); + if (ret) { + up(&this->lock); + return ret; + } + } + + to += len; + left -= len; + buf += len; } - DoC_WriteBuf(this, &buf[len256], len - len256); + up(&this->lock); + return 0; +} - if (eccbuf) { - WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr, - CDSNControl); +static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, + unsigned long count, loff_t to, size_t *retlen, + u_char *eccbuf, struct nand_oobinfo *oobsel) +{ + static char static_buf[512]; + static DECLARE_MUTEX(writev_buf_sem); - if (DoC_is_Millennium(this)) { - WriteDOC(0, docptr, NOP); - WriteDOC(0, docptr, NOP); - WriteDOC(0, docptr, NOP); - } else { - WriteDOC_(0, docptr, this->ioreg); - WriteDOC_(0, docptr, this->ioreg); - WriteDOC_(0, docptr, this->ioreg); - } + size_t totretlen = 0; + size_t thisvecofs = 0; + int ret= 0; - /* Read the ECC data through the DiskOnChip ECC logic */ - for (di = 0; di < 6; di++) { - eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di); - } + down(&writev_buf_sem); - /* Reset the ECC engine */ - WriteDOC(DOC_ECC_DIS, docptr, ECCConf); + while(count) { + size_t thislen, thisretlen; + unsigned char *buf; -#ifdef PSYCHO_DEBUG - printk - ("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", - (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], - eccbuf[4], eccbuf[5]); -#endif - } + buf = vecs->iov_base + thisvecofs; + thislen = vecs->iov_len - thisvecofs; - DoC_Command(this, NAND_CMD_PAGEPROG, 0); - DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP); - /* There's an implicit DoC_WaitReady() in DoC_Command */ + if (thislen >= 512) { + thislen = thislen & ~(512-1); + thisvecofs += thislen; + } else { + /* Not enough to fill a page. Copy into buf */ + memcpy(static_buf, buf, thislen); + buf = &static_buf[thislen]; + + while(count && thislen < 512) { + vecs++; + count--; + thisvecofs = min((512-thislen), vecs->iov_len); + memcpy(buf, vecs->iov_base, thisvecofs); + thislen += thisvecofs; + buf += thisvecofs; + } + buf = static_buf; + } + if (count && thisvecofs == vecs->iov_len) { + thisvecofs = 0; + vecs++; + count--; + } + ret = doc_write_ecc(mtd, to, thislen, &thisretlen, buf, eccbuf, oobsel); - dummy = ReadDOC(docptr, CDSNSlowIO); - DoC_Delay(this, 2); + totretlen += thisretlen; - if (ReadDOC_(docptr, this->ioreg) & 1) { - printk(KERN_ERR "Error programming flash\n"); - /* Error in programming */ - *retlen = 0; - up(&this->lock); - return -EIO; - } + if (ret || thisretlen != thislen) + break; - /* Let the caller know we completed it */ - *retlen = len; - - if (eccbuf) { - unsigned char x[8]; - size_t dummy; - int ret; - - /* Write the ECC data to flash */ - for (di=0; di<6; di++) - x[di] = eccbuf[di]; - - x[6]=0x55; - x[7]=0x55; - - ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x); - up(&this->lock); - return ret; - } - up(&this->lock); - return 0; + to += thislen; + } + + up(&writev_buf_sem); + *retlen = totretlen; + return ret; } + static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, size_t * retlen, u_char * buf) { struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv; int len256 = 0, ret; - unsigned long docptr; struct Nand *mychip; down(&this->lock); - docptr = this->virtadr; - mychip = &this->chips[ofs >> this->chipshift]; if (this->curfloor != mychip->floor) { @@ -974,9 +1093,10 @@ { struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv; int len256 = 0; - unsigned long docptr = this->virtadr; + void __iomem *docptr = this->virtadr; struct Nand *mychip = &this->chips[ofs >> this->chipshift]; volatile int dummy; + int status; // printk("doc_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",(long)ofs, len, // buf[0], buf[1], buf[2], buf[3], buf[8], buf[9], buf[14],buf[15]); @@ -1025,10 +1145,16 @@ DoC_Command(this, NAND_CMD_STATUS, 0); /* DoC_WaitReady() is implicit in DoC_Command */ - dummy = ReadDOC(docptr, CDSNSlowIO); - DoC_Delay(this, 2); + if (DoC_is_Millennium(this)) { + ReadDOC(docptr, ReadPipeInit); + status = ReadDOC(docptr, LastDataRead); + } else { + dummy = ReadDOC(docptr, CDSNSlowIO); + DoC_Delay(this, 2); + status = ReadDOC_(docptr, this->ioreg); + } - if (ReadDOC_(docptr, this->ioreg) & 1) { + if (status & 1) { printk(KERN_ERR "Error programming oob data\n"); /* There was an error */ *retlen = 0; @@ -1044,10 +1170,16 @@ DoC_Command(this, NAND_CMD_STATUS, 0); /* DoC_WaitReady() is implicit in DoC_Command */ - dummy = ReadDOC(docptr, CDSNSlowIO); - DoC_Delay(this, 2); + if (DoC_is_Millennium(this)) { + ReadDOC(docptr, ReadPipeInit); + status = ReadDOC(docptr, LastDataRead); + } else { + dummy = ReadDOC(docptr, CDSNSlowIO); + DoC_Delay(this, 2); + status = ReadDOC_(docptr, this->ioreg); + } - if (ReadDOC_(docptr, this->ioreg) & 1) { + if (status & 1) { printk(KERN_ERR "Error programming oob data\n"); /* There was an error */ *retlen = 0; @@ -1078,8 +1210,9 @@ __u32 ofs = instr->addr; __u32 len = instr->len; volatile int dummy; - unsigned long docptr; + void __iomem *docptr = this->virtadr; struct Nand *mychip; + int status; down(&this->lock); @@ -1090,8 +1223,6 @@ instr->state = MTD_ERASING; - docptr = this->virtadr; - /* FIXME: Do this in the background. Use timers or schedule_task() */ while(len) { mychip = &this->chips[ofs >> this->chipshift]; @@ -1111,10 +1242,16 @@ DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP); - dummy = ReadDOC(docptr, CDSNSlowIO); - DoC_Delay(this, 2); - - if (ReadDOC_(docptr, this->ioreg) & 1) { + if (DoC_is_Millennium(this)) { + ReadDOC(docptr, ReadPipeInit); + status = ReadDOC(docptr, LastDataRead); + } else { + dummy = ReadDOC(docptr, CDSNSlowIO); + DoC_Delay(this, 2); + status = ReadDOC_(docptr, this->ioreg); + } + + if (status & 1) { printk(KERN_ERR "Error erasing at 0x%x\n", ofs); /* There was an error */ instr->state = MTD_ERASE_FAILED; @@ -1126,8 +1263,7 @@ instr->state = MTD_ERASE_DONE; callback: - if (instr->callback) - instr->callback(instr); + mtd_erase_callback(instr); up(&this->lock); return 0; Index: drivers/mtd/devices/doc2001.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/devices/doc2001.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/devices/doc2001.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/devices/doc2001.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -4,7 +4,7 @@ * (c) 1999 Machine Vision Holdings, Inc. * (c) 1999, 2000 David Woodhouse * - * $Id: doc2001.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: doc2001.c,v 1.3 2004/11/03 00:04:43 joff Exp $ */ #include @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -37,9 +38,11 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel); + size_t *retlen, u_char *buf, u_char *eccbuf, + struct nand_oobinfo *oobsel); static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf, u_char *eccbuf, int oobsel); + size_t *retlen, const u_char *buf, u_char *eccbuf, + struct nand_oobinfo *oobsel); static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, size_t *retlen, u_char *buf); static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, @@ -49,7 +52,7 @@ static struct mtd_info *docmillist = NULL; /* Perform the required delay cycles by reading from the NOP register */ -static void DoC_Delay(unsigned long docptr, unsigned short cycles) +static void DoC_Delay(void __iomem * docptr, unsigned short cycles) { volatile char dummy; int i; @@ -59,7 +62,7 @@ } /* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */ -static int _DoC_WaitReady(unsigned long docptr) +static int _DoC_WaitReady(void __iomem * docptr) { unsigned short c = 0xffff; @@ -76,7 +79,7 @@ return (c == 0); } -static inline int DoC_WaitReady(unsigned long docptr) +static inline int DoC_WaitReady(void __iomem * docptr) { /* This is inline, to optimise the common case, where it's ready instantly */ int ret = 0; @@ -100,7 +103,7 @@ with the internal pipeline. Each of 4 delay cycles (read from the NOP register) is required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */ -static inline void DoC_Command(unsigned long docptr, unsigned char command, +static inline void DoC_Command(void __iomem * docptr, unsigned char command, unsigned char xtraflags) { /* Assert the CLE (Command Latch Enable) line to the flash chip */ @@ -120,7 +123,7 @@ with the internal pipeline. Each of 4 delay cycles (read from the NOP register) is required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */ -static inline void DoC_Address(unsigned long docptr, int numbytes, unsigned long ofs, +static inline void DoC_Address(void __iomem * docptr, int numbytes, unsigned long ofs, unsigned char xtraflags1, unsigned char xtraflags2) { /* Assert the ALE (Address Latch Enable) line to the flash chip */ @@ -158,7 +161,7 @@ } /* DoC_SelectChip: Select a given flash chip within the current floor */ -static int DoC_SelectChip(unsigned long docptr, int chip) +static int DoC_SelectChip(void __iomem * docptr, int chip) { /* Select the individual flash chip requested */ WriteDOC(chip, docptr, CDSNDeviceSelect); @@ -169,7 +172,7 @@ } /* DoC_SelectFloor: Select a given floor (bank of flash chips) */ -static int DoC_SelectFloor(unsigned long docptr, int floor) +static int DoC_SelectFloor(void __iomem * docptr, int floor) { /* Select the floor (bank) of chips required */ WriteDOC(floor, docptr, FloorSelect); @@ -226,7 +229,7 @@ mfr, id, nand_manuf_ids[j].name, nand_flash_ids[i].name); doc->mfr = mfr; doc->id = id; - doc->chipshift = nand_flash_ids[i].chipshift; + doc->chipshift = ffs((nand_flash_ids[i].chipsize << 20)) - 1; break; } } @@ -359,14 +362,15 @@ mtd->type = MTD_NANDFLASH; mtd->flags = MTD_CAP_NANDFLASH; + mtd->ecctype = MTD_ECC_RS_DiskOnChip; mtd->size = 0; - /* FIXME: erase size is not always 8kB */ + /* FIXME: erase size is not always 8KiB */ mtd->erasesize = 0x2000; mtd->oobblock = 512; mtd->oobsize = 16; - mtd->module = THIS_MODULE; + mtd->owner = THIS_MODULE; mtd->erase = doc_erase; mtd->point = NULL; mtd->unpoint = NULL; @@ -402,17 +406,18 @@ size_t *retlen, u_char *buf) { /* Just a special case of doc_read_ecc */ - return doc_read_ecc(mtd, from, len, retlen, buf, NULL, 0); + return doc_read_ecc(mtd, from, len, retlen, buf, NULL, NULL); } static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel) + size_t *retlen, u_char *buf, u_char *eccbuf, + struct nand_oobinfo *oobsel) { int i, ret; volatile char dummy; unsigned char syndrome[6]; struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; - unsigned long docptr = this->virtadr; + void __iomem *docptr = this->virtadr; struct Nand *mychip = &this->chips[from >> (this->chipshift)]; /* Don't allow read past end of device */ @@ -528,16 +533,17 @@ size_t *retlen, const u_char *buf) { char eccbuf[6]; - return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf, 0); + return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf, NULL); } static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf, u_char *eccbuf, int oobsel) + size_t *retlen, const u_char *buf, u_char *eccbuf, + struct nand_oobinfo *oobsel) { int i,ret = 0; volatile char dummy; struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; - unsigned long docptr = this->virtadr; + void __iomem *docptr = this->virtadr; struct Nand *mychip = &this->chips[to >> (this->chipshift)]; /* Don't allow write past end of device */ @@ -672,7 +678,7 @@ #endif volatile char dummy; struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; - unsigned long docptr = this->virtadr; + void __iomem *docptr = this->virtadr; struct Nand *mychip = &this->chips[ofs >> this->chipshift]; /* Find the chip which is to be used and select it */ @@ -724,7 +730,7 @@ volatile char dummy; int ret = 0; struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; - unsigned long docptr = this->virtadr; + void __iomem *docptr = this->virtadr; struct Nand *mychip = &this->chips[ofs >> this->chipshift]; /* Find the chip which is to be used and select it */ @@ -793,7 +799,7 @@ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; __u32 ofs = instr->addr; __u32 len = instr->len; - unsigned long docptr = this->virtadr; + void __iomem *docptr = this->virtadr; struct Nand *mychip = &this->chips[ofs >> this->chipshift]; if (len != mtd->erasesize) @@ -839,8 +845,7 @@ instr->state = MTD_ERASE_DONE; dummy = ReadDOC(docptr, LastDataRead); - if (instr->callback) - instr->callback(instr); + mtd_erase_callback(instr); return 0; } Index: drivers/mtd/devices/docecc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/devices/docecc.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/devices/docecc.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/devices/docecc.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -7,7 +7,7 @@ * Author: Fabrice Bellard (fabrice.bellard@netgem.com) * Copyright (C) 2000 Netgem S.A. * - * $Id: docecc.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: docecc.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -519,6 +519,8 @@ return nb_errors; } +EXPORT_SYMBOL_GPL(doc_decode_ecc); + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Fabrice Bellard "); MODULE_DESCRIPTION("ECC code for correcting errors detected by DiskOnChip 2000 and Millennium ECC hardware"); Index: drivers/mtd/devices/docprobe.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/devices/docprobe.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/devices/docprobe.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/devices/docprobe.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -4,7 +4,7 @@ /* (C) 1999 Machine Vision Holdings, Inc. */ /* (C) 1999-2003 David Woodhouse */ -/* $Id: docprobe.c,v 1.1 2004/07/22 19:49:46 joff Exp $ */ +/* $Id: docprobe.c,v 1.3 2004/11/03 00:04:43 joff Exp $ */ @@ -31,14 +31,12 @@ /* DOC_SINGLE_DRIVER: Millennium driver has been merged into DOC2000 driver. - The newly-merged driver doesn't appear to work for writing. It's the - same with the DiskOnChip 2000 and the Millennium. If you have a - Millennium and you want write support to work, remove the definition - of DOC_SINGLE_DRIVER below to use the old doc2001-specific driver. - - Otherwise, it's left on in the hope that it'll annoy someone with - a Millennium enough that they go through and work out what the - difference is :) + The old Millennium-only driver has been retained just in case there + are problems with the new code. If the combined driver doesn't work + for you, you can try the old one by undefining DOC_SINGLE_DRIVER + below and also enabling it in your configuration. If this fixes the + problems, please send a report to the MTD mailing list at + . */ #define DOC_SINGLE_DRIVER @@ -47,18 +45,15 @@ #include #include #include -#include -#include -#include #include #include -#include #include #include #include #include #include +#include /* Where to look for the devices? */ #ifndef CONFIG_MTD_DOCPROBE_ADDRESS @@ -95,14 +90,14 @@ ##else #warning Unknown architecture for DiskOnChip. No default probe locations defined #endif - 0 }; + 0xffffffff }; /* doccheck: Probe a given memory window to see if there's a DiskOnChip present */ static inline int __init doccheck(unsigned long potential, unsigned long physadr) { unsigned long window=potential; - unsigned char tmp, ChipID; + unsigned char tmp, tmpb, tmpc, ChipID; #ifndef DOC_PASSIVE_PROBE unsigned char tmp2; #endif @@ -140,26 +135,80 @@ window, DOCControl); #endif /* !DOC_PASSIVE_PROBE */ + /* We need to read the ChipID register four times. For some + newer DiskOnChip 2000 units, the first three reads will + return the DiskOnChip Millennium ident. Don't ask. */ ChipID = ReadDOC(window, ChipID); switch (ChipID) { case DOC_ChipID_Doc2k: /* Check the TOGGLE bit in the ECC register */ - tmp = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT; - if ((ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT) != tmp) + tmp = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT; + tmpb = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT; + tmpc = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT; + if (tmp != tmpb && tmp == tmpc) return ChipID; break; case DOC_ChipID_DocMil: + /* Check for the new 2000 with Millennium ASIC */ + ReadDOC(window, ChipID); + ReadDOC(window, ChipID); + if (ReadDOC(window, ChipID) != DOC_ChipID_DocMil) + ChipID = DOC_ChipID_Doc2kTSOP; + /* Check the TOGGLE bit in the ECC register */ - tmp = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT; - if ((ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT) != tmp) + tmp = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT; + tmpb = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT; + tmpc = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT; + if (tmp != tmpb && tmp == tmpc) return ChipID; break; + case DOC_ChipID_DocMilPlus16: + case DOC_ChipID_DocMilPlus32: + case 0: + /* Possible Millennium+, need to do more checks */ +#ifndef DOC_PASSIVE_PROBE + /* Possibly release from power down mode */ + for (tmp = 0; (tmp < 4); tmp++) + ReadDOC(window, Mplus_Power); + + /* Reset the DiskOnChip ASIC */ + tmp = DOC_MODE_RESET | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | + DOC_MODE_BDECT; + WriteDOC(tmp, window, Mplus_DOCControl); + WriteDOC(~tmp, window, Mplus_CtrlConfirm); + + mdelay(1); + /* Enable the DiskOnChip ASIC */ + tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | + DOC_MODE_BDECT; + WriteDOC(tmp, window, Mplus_DOCControl); + WriteDOC(~tmp, window, Mplus_CtrlConfirm); + mdelay(1); +#endif /* !DOC_PASSIVE_PROBE */ + + ChipID = ReadDOC(window, ChipID); + + switch (ChipID) { + case DOC_ChipID_DocMilPlus16: + case DOC_ChipID_DocMilPlus32: + /* Check the TOGGLE bit in the toggle register */ + tmp = ReadDOC(window, Mplus_Toggle) & DOC_TOGGLE_BIT; + tmpb = ReadDOC(window, Mplus_Toggle) & DOC_TOGGLE_BIT; + tmpc = ReadDOC(window, Mplus_Toggle) & DOC_TOGGLE_BIT; + if (tmp != tmpb && tmp == tmpc) + return ChipID; + default: + break; + } + /* FALL TRHU */ + default: -#ifndef CONFIG_MTD_DOCPROBE_55AA - printk(KERN_WARNING "Possible DiskOnChip with unknown ChipID %2.2X found at 0x%lx\n", + +#ifdef CONFIG_MTD_DOCPROBE_55AA + printk(KERN_DEBUG "Possible DiskOnChip with unknown ChipID %2.2X found at 0x%lx\n", ChipID, physadr); #endif #ifndef DOC_PASSIVE_PROBE @@ -200,6 +249,12 @@ return; if ((ChipID = doccheck(docptr, physadr))) { + if (ChipID == DOC_ChipID_Doc2kTSOP) { + /* Remove this at your own peril. The hardware driver works but nothing prevents you from erasing bad blocks */ + printk(KERN_NOTICE "Refusing to drive DiskOnChip 2000 TSOP until Bad Block Table is correctly supported by INFTL\n"); + iounmap((void *)docptr); + return; + } docfound = 1; mtd = kmalloc(sizeof(struct DiskOnChip) + sizeof(struct mtd_info), GFP_KERNEL); @@ -215,12 +270,18 @@ memset((char *)this, 0, sizeof(struct DiskOnChip)); mtd->priv = this; - this->virtadr = docptr; + this->virtadr = (void __iomem *)docptr; this->physadr = physadr; this->ChipID = ChipID; sprintf(namebuf, "with ChipID %2.2X", ChipID); switch(ChipID) { + case DOC_ChipID_Doc2kTSOP: + name="2000 TSOP"; + im_funcname = "DoC2k_init"; + im_modname = "doc2000"; + break; + case DOC_ChipID_Doc2k: name="2000"; im_funcname = "DoC2k_init"; @@ -237,6 +298,13 @@ im_modname = "doc2001"; #endif /* DOC_SINGLE_DRIVER */ break; + + case DOC_ChipID_DocMilPlus16: + case DOC_ChipID_DocMilPlus32: + name="MillenniumPlus"; + im_funcname = "DoCMilPlus_init"; + im_modname = "doc2001plus"; + break; } if (im_funcname) @@ -248,6 +316,7 @@ return; } printk(KERN_NOTICE "Cannot find driver for DiskOnChip %s at 0x%lX\n", name, physadr); + kfree(mtd); } iounmap((void *)docptr); } @@ -267,7 +336,7 @@ printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location); DoC_Probe(doc_config_location); } else { - for (i=0; doc_locations[i]; i++) { + for (i=0; (doc_locations[i] != 0xffffffff); i++) { DoC_Probe(doc_locations[i]); } } @@ -275,11 +344,7 @@ found, so the user knows we at least tried. */ if (!docfound) printk(KERN_INFO "No recognised DiskOnChip devices found\n"); - /* So it looks like we've been used and we get unloaded */ - MOD_INC_USE_COUNT; - MOD_DEC_USE_COUNT; - return 0; - + return -EAGAIN; } module_init(init_doc); Index: drivers/mtd/devices/lart.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/devices/lart.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/devices/lart.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/devices/lart.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -2,7 +2,7 @@ /* * MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART. * - * $Id: lart.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: lart.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * * Author: Abraham vd Merwe * @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include #include #ifdef HAVE_PARTITIONS @@ -433,7 +433,7 @@ } instr->state = MTD_ERASE_DONE; - if (instr->callback) instr->callback (instr); + mtd_erase_callback(instr); return (0); } @@ -584,46 +584,41 @@ static struct mtd_info mtd; -static struct mtd_erase_region_info erase_regions[] = -{ - /* parameter blocks */ - { - offset: 0x00000000, - erasesize: FLASH_BLOCKSIZE_PARAM, - numblocks: FLASH_NUMBLOCKS_16m_PARAM - }, - /* main blocks */ - { - offset: FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM, - erasesize: FLASH_BLOCKSIZE_MAIN, - numblocks: FLASH_NUMBLOCKS_16m_MAIN - } +static struct mtd_erase_region_info erase_regions[] = { + /* parameter blocks */ + { + .offset = 0x00000000, + .erasesize = FLASH_BLOCKSIZE_PARAM, + .numblocks = FLASH_NUMBLOCKS_16m_PARAM, + }, + /* main blocks */ + { + .offset = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM, + .erasesize = FLASH_BLOCKSIZE_MAIN, + .numblocks = FLASH_NUMBLOCKS_16m_MAIN, + } }; #ifdef HAVE_PARTITIONS -static struct mtd_partition lart_partitions[] = -{ - /* blob */ - { - name: "blob", - offset: BLOB_START, - size: BLOB_LEN, - mask_flags: 0 - }, - /* kernel */ - { - name: "kernel", - offset: KERNEL_START, /* MTDPART_OFS_APPEND */ - size: KERNEL_LEN, - mask_flags: 0 - }, - /* initial ramdisk / file system */ - { - name: "file system", - offset: INITRD_START, /* MTDPART_OFS_APPEND */ - size: INITRD_LEN, /* MTDPART_SIZ_FULL */ - mask_flags: 0 - } +static struct mtd_partition lart_partitions[] = { + /* blob */ + { + .name = "blob", + .offset = BLOB_START, + .size = BLOB_LEN, + }, + /* kernel */ + { + .name = "kernel", + .offset = KERNEL_START, /* MTDPART_OFS_APPEND */ + .size = KERNEL_LEN, + }, + /* initial ramdisk / file system */ + { + .name = "file system", + .offset = INITRD_START, /* MTDPART_OFS_APPEND */ + .size = INITRD_LEN, /* MTDPART_SIZ_FULL */ + } }; #endif @@ -646,10 +641,10 @@ mtd.erasesize = FLASH_BLOCKSIZE_MAIN; mtd.numeraseregions = NB_OF (erase_regions); mtd.eraseregions = erase_regions; - mtd.module = THIS_MODULE; mtd.erase = flash_erase; mtd.read = flash_read; mtd.write = flash_write; + mtd.owner = THIS_MODULE; #ifdef LART_DEBUG printk (KERN_DEBUG Index: drivers/mtd/devices/ms02-nv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/devices/ms02-nv.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/devices/ms02-nv.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/devices/ms02-nv.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2001 Maciej W. Rozycki + * Copyright (c) 2001 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. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. * - * $Id: ms02-nv.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: ms02-nv.c,v 1.3 2004/11/03 00:04:43 joff Exp $ */ #include @@ -29,18 +29,18 @@ static char version[] __initdata = - "ms02-nv.c: v.1.0.0 13 Aug 2001 Maciej W. Rozycki.\n"; + "ms02-nv.c: v.1.0.0 13 Aug 2001 Maciej W. Rozycki.\n"; -MODULE_AUTHOR("Maciej W. Rozycki "); +MODULE_AUTHOR("Maciej W. Rozycki "); MODULE_DESCRIPTION("DEC MS02-NV NVRAM module driver"); MODULE_LICENSE("GPL"); /* * Addresses we probe for an MS02-NV at. Modules may be located - * at any 8MB boundary within a 0MB up to 112MB range or at any 32MB - * boundary within a 0MB up to 448MB range. We don't support a module - * at 0MB, though. + * at any 8MiB boundary within a 0MiB up to 112MiB range or at any 32MiB + * boundary within a 0MiB up to 448MiB range. We don't support a module + * at 0MiB, though. */ static ulong ms02nv_addrs[] __initdata = { 0x07000000, 0x06800000, 0x06000000, 0x05800000, 0x05000000, @@ -130,7 +130,7 @@ int ret = -ENODEV; - /* The module decodes 8MB of address space. */ + /* The module decodes 8MiB of address space. */ mod_res = kmalloc(sizeof(*mod_res), GFP_KERNEL); if (!mod_res) return -ENOMEM; @@ -222,7 +222,7 @@ mtd->flags = MTD_CAP_RAM | MTD_XIP; mtd->size = fixsize; mtd->name = (char *)ms02nv_name; - mtd->module = THIS_MODULE; + mtd->owner = THIS_MODULE; mtd->read = ms02nv_read; mtd->write = ms02nv_write; @@ -233,7 +233,7 @@ goto err_out_csr_res; } - printk(KERN_INFO "mtd%d: %s at 0x%08lx, size %uMB.\n", + printk(KERN_INFO "mtd%d: %s at 0x%08lx, size %uMiB.\n", mtd->index, ms02nv_name, addr, size >> 20); mp->next = root_ms02nv_mtd; @@ -293,12 +293,12 @@ switch (mips_machtype) { case MACH_DS5000_200: - csr = (volatile u32 *)KN02_CSR_ADDR; + csr = (volatile u32 *)KN02_CSR_BASE; if (*csr & KN02_CSR_BNK32M) stride = 2; break; case MACH_DS5000_2X0: - case MACH_DS5000: + case MACH_DS5900: csr = (volatile u32 *)KN03_MCR_BASE; if (*csr & KN03_MCR_BNK32M) stride = 2; Index: drivers/mtd/devices/ms02-nv.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/devices/ms02-nv.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/mtd/devices/ms02-nv.h 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/devices/ms02-nv.h 3 Nov 2004 00:04:43 -0000 1.2 @@ -1,32 +1,96 @@ /* - * Copyright (c) 2001 Maciej W. Rozycki + * Copyright (c) 2001, 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. + * DEC MS02-NV (54-20948-01) battery backed-up NVRAM module for + * DECstation/DECsystem 5000/2x0 and DECsystem 5900 and 5900/260 + * systems. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * $Id: ms02-nv.h,v 1.2 2004/11/03 00:04:43 joff Exp $ */ #include #include +/* + * Addresses are decoded as follows: + * + * 0x000000 - 0x3fffff SRAM + * 0x400000 - 0x7fffff CSR + * + * Within the SRAM area the following ranges are forced by the system + * firmware: + * + * 0x000000 - 0x0003ff diagnostic area, destroyed upon a reboot + * 0x000400 - ENDofRAM storage area, available to operating systems + * + * but we can't really use the available area right from 0x000400 as + * the first word is used by the firmware as a status flag passed + * from an operating system. If anything but the valid data magic + * ID value is found, the firmware considers the SRAM clean, i.e. + * containing no valid data, and disables the battery resulting in + * data being erased as soon as power is switched off. So the choice + * for the start address of the user-available is 0x001000 which is + * nicely page aligned. The area between 0x000404 and 0x000fff may + * be used by the driver for own needs. + * + * The diagnostic area defines two status words to be read by an + * operating system, a magic ID to distinguish a MS02-NV board from + * anything else and a status information providing results of tests + * as well as the size of SRAM available, which can be 1MiB or 2MiB + * (that's what the firmware handles; no idea if 2MiB modules ever + * existed). + * + * The firmware only handles the MS02-NV board if installed in the + * last (15th) slot, so for any other location the status information + * stored in the SRAM cannot be relied upon. But from the hardware + * point of view there is no problem using up to 14 such boards in a + * system -- only the 1st slot needs to be filled with a DRAM module. + * The MS02-NV board is ECC-protected, like other MS02 memory boards. + * + * The state of the battery as provided by the CSR is reflected on + * the two onboard LEDs. When facing the battery side of the board, + * with the LEDs at the top left and the battery at the bottom right + * (i.e. looking from the back side of the system box), their meaning + * is as follows (the system has to be powered on): + * + * left LED battery disable status: lit = enabled + * right LED battery condition status: lit = OK + */ + /* MS02-NV iomem register offsets. */ #define MS02NV_CSR 0x400000 /* control & status register */ +/* MS02-NV CSR status bits. */ +#define MS02NV_CSR_BATT_OK 0x01 /* battery OK */ +#define MS02NV_CSR_BATT_OFF 0x02 /* battery disabled */ + + /* MS02-NV memory offsets. */ #define MS02NV_DIAG 0x0003f8 /* diagnostic status */ #define MS02NV_MAGIC 0x0003fc /* MS02-NV magic ID */ -#define MS02NV_RAM 0x000400 /* general-purpose RAM start */ +#define MS02NV_VALID 0x000400 /* valid data magic ID */ +#define MS02NV_RAM 0x001000 /* user-exposed RAM start */ -/* MS02-NV diagnostic status constants. */ -#define MS02NV_DIAG_SIZE_MASK 0xf0 /* RAM size mask */ -#define MS02NV_DIAG_SIZE_SHIFT 0x10 /* RAM size shift (left) */ +/* MS02-NV diagnostic status bits. */ +#define MS02NV_DIAG_TEST 0x01 /* SRAM test done (?) */ +#define MS02NV_DIAG_RO 0x02 /* SRAM r/o test done */ +#define MS02NV_DIAG_RW 0x04 /* SRAM r/w test done */ +#define MS02NV_DIAG_FAIL 0x08 /* SRAM test failed */ +#define MS02NV_DIAG_SIZE_MASK 0xf0 /* SRAM size mask */ +#define MS02NV_DIAG_SIZE_SHIFT 0x10 /* SRAM size shift (left) */ /* MS02-NV general constants. */ #define MS02NV_ID 0x03021966 /* MS02-NV magic ID value */ +#define MS02NV_VALID_ID 0xbd100248 /* valid data magic ID value */ #define MS02NV_SLOT_SIZE 0x800000 /* size of the address space decoded by the module */ + typedef volatile u32 ms02nv_uint; struct ms02nv_private { Index: drivers/mtd/devices/mtdram.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/devices/mtdram.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/devices/mtdram.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/devices/mtdram.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,6 +1,6 @@ /* * mtdram - a test mtd device - * $Id: mtdram.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: mtdram.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * Author: Alexander Larsson * * Copyright (c) 1999 Alexander Larsson @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include @@ -55,9 +57,8 @@ memset((char *)mtd->priv + instr->addr, 0xff, instr->len); instr->state = MTD_ERASE_DONE; + mtd_erase_callback(instr); - if (instr->callback) - (*(instr->callback))(instr); return 0; } @@ -136,7 +137,7 @@ mtd->erasesize = MTDRAM_ERASE_SIZE; mtd->priv = mapped_address; - mtd->module = THIS_MODULE; + mtd->owner = THIS_MODULE; mtd->erase = ram_erase; mtd->point = ram_point; mtd->unpoint = ram_unpoint; Index: drivers/mtd/devices/pmc551.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/devices/pmc551.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/devices/pmc551.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/devices/pmc551.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,5 +1,5 @@ /* - * $Id: pmc551.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: pmc551.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * * PMC551 PCI Mezzanine Ram Device * @@ -82,6 +82,7 @@ * * Comb the init routine. It's still a bit cludgy on a few things. */ +#include #include #include #include @@ -108,12 +109,6 @@ #include #include -#if LINUX_VERSION_CODE > 0x20300 -#define PCI_BASE_ADDRESS(dev) (dev->resource[0].start) -#else -#define PCI_BASE_ADDRESS(dev) (dev->base_address[0]) -#endif - static struct mtd_info *pmc551list; static int pmc551_erase (struct mtd_info *mtd, struct erase_info *instr) @@ -174,9 +169,7 @@ printk(KERN_DEBUG "pmc551_erase() done\n"); #endif - if (instr->callback) { - (*(instr->callback))(instr); - } + mtd_erase_callback(instr); return 0; } @@ -563,7 +556,7 @@ (size<1024)?size:(size<1048576)?size>>10:size>>20, (size<1024)?'B':(size<1048576)?'K':'M', size, ((dcmd&(0x1<<3)) == 0)?"non-":"", - PCI_BASE_ADDRESS(dev)&PCI_BASE_ADDRESS_MEM_MASK ); + (dev->resource[0].start)&PCI_BASE_ADDRESS_MEM_MASK ); /* * Check to see the state of the memory @@ -681,11 +674,6 @@ printk(KERN_INFO PMC551_VERSION); - if(!pci_present()) { - printk(KERN_NOTICE "pmc551: PCI not enabled.\n"); - return -ENODEV; - } - /* * PCU-bus chipset probe. */ @@ -698,7 +686,7 @@ } printk(KERN_NOTICE "pmc551: Found PCI V370PDC at 0x%lX\n", - PCI_BASE_ADDRESS(PCI_Device)); + PCI_Device->resource[0].start); /* * The PMC551 device acts VERY weird if you don't init it @@ -752,7 +740,7 @@ printk(KERN_NOTICE "pmc551: Using specified aperture size %dM\n", asize>>20); priv->asize = asize; } - priv->start = ioremap((PCI_BASE_ADDRESS(PCI_Device) + priv->start = ioremap(((PCI_Device->resource[0].start) & PCI_BASE_ADDRESS_MEM_MASK), priv->asize); @@ -787,10 +775,10 @@ mtd->write = pmc551_write; mtd->point = pmc551_point; mtd->unpoint = pmc551_unpoint; - mtd->module = THIS_MODULE; mtd->type = MTD_RAM; mtd->name = "PMC551 RAM board"; mtd->erasesize = 0x10000; + mtd->owner = THIS_MODULE; if (add_mtd_device(mtd)) { printk(KERN_NOTICE "pmc551: Failed to register new device\n"); Index: drivers/mtd/devices/slram.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/devices/slram.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/devices/slram.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/devices/slram.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,6 +1,6 @@ /*====================================================================== - $Id: slram.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + $Id: slram.c,v 1.3 2004/11/03 00:04:43 joff Exp $ This driver provides a method to access memory not used by the kernel itself (i.e. if the kernel commandline mem=xxx is used). To actually @@ -98,12 +98,7 @@ instr->state = MTD_ERASE_DONE; - if (instr->callback) { - (*(instr->callback))(instr); - } - else { - kfree(instr); - } + mtd_erase_callback(instr); return(0); } @@ -199,7 +194,7 @@ (*curmtd)->mtdinfo->unpoint = slram_unpoint; (*curmtd)->mtdinfo->read = slram_read; (*curmtd)->mtdinfo->write = slram_write; - (*curmtd)->mtdinfo->module = THIS_MODULE; + (*curmtd)->mtdinfo->owner = THIS_MODULE; (*curmtd)->mtdinfo->type = MTD_RAM; (*curmtd)->mtdinfo->erasesize = 0x0; Index: drivers/mtd/maps/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/Config.in,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/Config.in 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/maps/Config.in 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,16 +1,18 @@ # drivers/mtd/maps/Config.in -# $Id: Config.in,v 1.1 2004/07/22 19:49:46 joff Exp $ +# $Id: Config.in,v 1.3 2004/11/03 00:04:43 joff Exp $ mainmenu_option next_comment comment 'Mapping drivers for chip access' -dep_tristate ' CFI Flash device in physical memory map' CONFIG_MTD_PHYSMAP $CONFIG_MTD_GEN_PROBE -if [ "$CONFIG_MTD_PHYSMAP" = "y" -o "$CONFIG_MTD_PHYSMAP" = "m" ]; then +bool ' Support for non-linear mappings of flash chips' CONFIG_MTD_COMPLEX_MAPPINGS + +bool ' CFI Flash device in physical memory map' CONFIG_MTD_PHYSMAP $CONFIG_MTD_GEN_PROBE +if [ "$CONFIG_MTD_PHYSMAP" = "y" ]; then hex ' Physical start address of flash mapping' CONFIG_MTD_PHYSMAP_START 0x8000000 hex ' Physical length of flash mapping' CONFIG_MTD_PHYSMAP_LEN 0x4000000 - int ' Bus width in octets' CONFIG_MTD_PHYSMAP_BUSWIDTH 2 + int ' Bank width in octets' CONFIG_MTD_PHYSMAP_BANKWIDTH 2 fi if [ "$CONFIG_SPARC" = "y" -o "$CONFIG_SPARC64" = "y" ]; then @@ -21,40 +23,82 @@ dep_tristate ' CFI Flash device mapped on Photron PNC-2000' CONFIG_MTD_PNC2000 $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS dep_tristate ' CFI Flash device mapped on AMD SC520 CDP' CONFIG_MTD_SC520CDP $CONFIG_MTD_CFI dep_tristate ' CFI Flash device mapped on AMD NetSc520' CONFIG_MTD_NETSC520 $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS - dep_tristate ' CFI Flash device mapped on Arcom SBC-GXx boards' CONFIG_MTD_SBC_GXX $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS - dep_tristate ' CFI Flash device mapped on Arcom ELAN-104NC' CONFIG_MTD_ELAN_104NC $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS + dep_tristate ' CFI Flash device mapped on Arcom SBC-GXx boards' CONFIG_MTD_SBC_GXX $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS $CONFIG_MTD_COMPLEX_MAPPINGS + dep_tristate ' CFI Flash device mapped on Arcom ELAN-104NC' CONFIG_MTD_ELAN_104NC $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS $CONFIG_MTD_COMPLEX_MAPPINGS dep_tristate ' CFI Flash device mapped on DIL/Net PC' CONFIG_MTD_DILNETPC $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS $CONFIG_MTD_CONCAT if [ "$CONFIG_MTD_DILNETPC" = "y" -o "$CONFIG_MTD_DILNETPC" = "m" ]; then hex ' Size of boot partition' CONFIG_MTD_DILNETPC_BOOTSIZE 0x80000 fi - dep_tristate ' JEDEC Flash device mapped on Mixcom piggyback card' CONFIG_MTD_MIXMEM $CONFIG_MTD_JEDEC - dep_tristate ' JEDEC Flash device mapped on Octagon 5066 SBC' CONFIG_MTD_OCTAGON $CONFIG_MTD_JEDEC - dep_tristate ' JEDEC Flash device mapped on Tempustech VMAX SBC301' CONFIG_MTD_VMAX $CONFIG_MTD_JEDEC + dep_tristate ' JEDEC Flash device mapped on Octagon 5066 SBC' CONFIG_MTD_OCTAGON $CONFIG_MTD_JEDEC $CONFIG_MTD_COMPLEX_MAPPINGS + dep_tristate ' JEDEC Flash device mapped on Tempustech VMAX SBC301' CONFIG_MTD_VMAX $CONFIG_MTD_JEDEC $CONFIG_MTD_COMPLEX_MAPPINGS dep_tristate ' Flash device mapped with DOCCS on NatSemi SCx200' CONFIG_MTD_SCx200_DOCFLASH $CONFIG_MTD_CFI dep_tristate ' BIOS flash chip on Intel L440GX boards' CONFIG_MTD_L440GX $CONFIG_MTD_JEDECPROBE dep_tristate ' ROM connected to AMD76X southbridge' CONFIG_MTD_AMD76XROM $CONFIG_MTD_GEN_PROBE - dep_tristate ' ROM connected to Intel Hub Controller 2' CONFIG_MTD_ICH2ROM $CONFIG_MTD_JEDECPROBE + dep_tristate ' ROM connected to Intel Hub Controller 2/3/4/5' CONFIG_MTD_ICHXROM $CONFIG_MTD_JEDECPROBE dep_tristate ' CFI Flash device mapped on SnapGear/SecureEdge' CONFIG_MTD_NETtel $CONFIG_MTD_PARTITIONS dep_tristate ' BIOS flash chip on Intel SCB2 boards' CONFIG_MTD_SCB2_FLASH $CONFIG_MTD_GEN_PROBE fi -if [ "$CONFIG_PPC" = "y" ]; then - dep_tristate ' CFI Flash device mapped on TQM8XXL' CONFIG_MTD_TQM8XXL $CONFIG_MTD_CFI $CONFIG_TQM8xxL - dep_tristate ' CFI Flash device mapped on RPX Lite or CLLF' CONFIG_MTD_RPXLITE $CONFIG_MTD_CFI - dep_tristate ' System flash on MBX860 board' CONFIG_MTD_MBX860 $CONFIG_MTD_CFI - dep_tristate ' CFI Flash device mapped on D-Box2' CONFIG_MTD_DBOX2 $CONFIG_MTD_CFI - dep_tristate ' CFI Flash device mapping on FlagaDM' CONFIG_MTD_CFI_FLAGADM $CONFIG_MTD_CFI - dep_tristate ' CFI Flash device mapped on IBM Redwood-4/5' CONFIG_MTD_REDWOOD $CONFIG_MTD_CFI -fi - -if [ "$CONFIG_MIPS" = "y" ]; then - dep_tristate ' Pb1000 MTD support' CONFIG_MTD_PB1000 $CONFIG_MIPS_PB1000 - dep_tristate ' Pb1500 MTD support' CONFIG_MTD_PB1500 $CONFIG_MIPS_PB1500 - dep_tristate ' Pb1100 MTD support' CONFIG_MTD_PB1100 $CONFIG_MIPS_PB1100 - if [ "$CONFIG_MTD_PB1500" = "y" -o "$CONFIG_MTD_PB1500" = "m" \ - -o "$CONFIG_MTD_PB1100" = "y" -o "$CONFIG_MTD_PB1100" = "m" ]; then - bool ' Pb[15]00 boot flash device' CONFIG_MTD_PB1500_BOOT - bool ' Pb[15]00 user flash device (2nd 32MiB bank)' CONFIG_MTD_PB1500_USER +if [ "$CONFIG_PPC32" = "y" ]; then + if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "y" ]; then + dep_tristate ' Flash device on SBC8240' CONFIG_MTD_SBC8240 $CONFIG_MTD_JEDECPROBE + fi + if [ "$CONFIG_8xx" = "y" ]; then + if [ "$CONFIG_TQM8xxL" = "y" ]; then + dep_tristate ' CFI Flash device mapped on TQM8XXL' CONFIG_MTD_TQM8XXL $CONFIG_MTD_CFI + fi + if [ "$CONFIG_RPXLITE" = "y" -o "$CONFIG_RPXCLASSIC" = "y" ]; then + dep_tristate ' CFI Flash device mapped on RPX Lite or CLLF' CONFIG_MTD_RPXLITE $CONFIG_MTD_CFI + fi + if [ "$CONFIG_MBX" = "y" ]; then + dep_tristate ' System flash on MBX860 board' CONFIG_MTD_MBX860 $CONFIG_MTD_CFI + fi + if [ "$CONFIG_DBOX2" = "y" ]; then + dep_tristate ' CFI Flash device mapped on D-Box2' CONFIG_MTD_DBOX2 $CONFIG_MTD_CFI + fi + dep_tristate ' CFI Flash device mapping on FlagaDM' CONFIG_MTD_CFI_FLAGADM $CONFIG_MTD_CFI + fi + if [ "$CONFIG_4xx" = "y" ]; then + if [ "$CONFIG_40x" = "y" ]; then + if [ "$CONFIG_REDWOOD_4" = "y" -o "$CONFIG_REDWOOD_5" = "y" -o "$CONFIG_REDWOOD_6" = "y" ]; then + dep_tristate ' CFI Flash device mapped on IBM Redwood' CONFIG_MTD_REDWOOD $CONFIG_MTD_CFI + fi + dep_tristate ' CFI Flash device mapped on IBM Beech' CONFIG_MTD_BEECH $CONFIG_MTD_CFI $CONFIG_BEECH + dep_tristate ' CFI Flash device mapped on IBM Arctic' CONFIG_MTD_ARCTIC $CONFIG_MTD_CFI $CONFIG_ARCTIC2 + fi + if [ "$CONFIG_440" = "y" ]; then + dep_tristate ' Flash devices mapped on IBM Ebony' CONFIG_MTD_EBONY $CONFIG_MTD_CFI $CONFIG_EBONY + fi + fi +fi + +if [ "$CONFIG_MIPS" = "y" -o "$CONFIG_MIPS64" = "y" ]; then + if [ "$CONFIG_MIPS_PB1000" = "y" -o "$CONFIG_MIPS_PB1100" = "y" -o "$CONFIG_MIPS_PB1500" = "y" ]; then + tristate ' Pb1x00 MTD support' CONFIG_MTD_PB1XXX + fi + if [ "$CONFIG_MTD_PB1XXX" = "y" -o "$CONFIG_MTD_PB1XXX" = "m" ]; then + if [ "$CONFIG_MIPS_PB1500" = "y" -o "$CONFIG_MIPS_PB1100" = "y" ]; then + bool ' Pb1[15]00 boot flash device' CONFIG_MTD_PB1500_BOOT + bool ' Pb1[15]00 user flash device (2nd 32MB bank)' CONFIG_MTD_PB1500_USER + fi + fi + if [ "$CONFIG_MIPS_DB1000" = "y" -o "$CONFIG_MIPS_DB1100" = "y" -o "$CONFIG_MIPS_DB1500" = "y" ]; then + tristate ' Db1x00 MTD support' CONFIG_MTD_DB1X00 + if [ "$CONFIG_MTD_DB1X00" = "y" -o "$CONFIG_MTD_DB1X00" = "m" ]; then + bool ' Db1x00 boot flash device (1st bank)' CONFIG_MTD_DB1X00_BOOT + bool ' Db1x00 user flash device (2nd bank)' CONFIG_MTD_DB1X00_USER + fi + fi + dep_tristate ' Pb1550 MTD support' CONFIG_MTD_PB1550 $CONFIG_MIPS_PB1550 + dep_tristate ' Db1550 MTD support' CONFIG_MTD_DB1550 $CONFIG_MIPS_DB1550 + dep_tristate ' XXS1500 boot flash device' CONFIG_MTD_XXS1500 $CONFIG_MIPS_XXS1500 + if [ "$CONFIG_MTD_PB1550" = "y" -o "$CONFIG_MTD_PB1550" = "m" ]; then + bool ' Pb1550 Boot Flash' CONFIG_MTD_PB1550_BOOT + bool ' Pb1550 User Parameter Flash' CONFIG_MTD_PB1550_USER + fi + if [ "$CONFIG_MTD_DB1550" = "y" -o "$CONFIG_MTD_DB1550" = "m" ]; then + bool ' Db1550 Boot Flash' CONFIG_MTD_DB1550_BOOT + bool ' Db1550 User Parameter Flash' CONFIG_MTD_DB1550_USER fi dep_tristate ' Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board' CONFIG_MTD_CSTM_MIPS_IXX $CONFIG_MTD_CFI $CONFIG_MTD_JEDEC $CONFIG_MTD_PARTITIONS if [ "$CONFIG_MTD_CSTM_MIPS_IXX" = "y" -o "$CONFIG_MTD_CSTM_MIPS_IXX" = "m" ]; then @@ -63,7 +107,7 @@ int ' Bus width in octets' CONFIG_MTD_CSTM_MIPS_IXX_BUSWIDTH 2 fi dep_tristate ' Momenco Ocelot boot flash device' CONFIG_MTD_OCELOT $CONFIG_MOMENCO_OCELOT - dep_tristate ' LASAT flash device' CONFIG_MTD_LASAT $CONFIG_MTD_CFI $CONFIG_LASAT + dep_tristate ' LASAT flash device' CONFIG_MTD_LASAT $CONFIG_LASAT fi if [ "$CONFIG_SUPERH" = "y" ]; then @@ -75,22 +119,25 @@ fi if [ "$CONFIG_ARM" = "y" ]; then - dep_tristate ' CFI Flash device mapped on Nora' CONFIG_MTD_NORA $CONFIG_MTD_CFI dep_tristate ' CFI Flash device mapped on ARM Integrator/P720T' CONFIG_MTD_ARM_INTEGRATOR $CONFIG_MTD_CFI dep_tristate ' Cirrus CDB89712 evaluation board mappings' CONFIG_MTD_CDB89712 $CONFIG_MTD_CFI $CONFIG_ARCH_CDB89712 dep_tristate ' CFI Flash device mapped on StrongARM SA11x0' CONFIG_MTD_SA1100 $CONFIG_MTD_CFI $CONFIG_ARCH_SA1100 $CONFIG_MTD_PARTITIONS - dep_tristate ' CFI Flash device mapped on DC21285 Footbridge' CONFIG_MTD_DC21285 $CONFIG_MTD_CFI $CONFIG_ARCH_FOOTBRIDGE + dep_tristate ' CFI Flash device mapped on DC21285 Footbridge' CONFIG_MTD_DC21285 $CONFIG_MTD_CFI $CONFIG_ARCH_FOOTBRIDGE $CONFIG_MTD_COMPLEX_MAPPINGS dep_tristate ' CFI Flash device mapped on the XScale IQ80310 board' CONFIG_MTD_IQ80310 $CONFIG_MTD_CFI $CONFIG_ARCH_IQ80310 - dep_tristate ' CFI Flash device mapped on the Technologic Systems TS-7XXX board' CONFIG_MTD_TS7XXX $CONFIG_MTD_CFI - dep_tristate ' CFI Flash device mapped on the FortuNet board' CONFIG_MTD_FORTUNET $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS $CONFIG_ARCH_FORTUNET - dep_tristate ' CFI Flash device mapped on Epxa' CONFIG_MTD_EPXA $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS $CONFIG_ARCH_CAMELOT + dep_tristate ' CFI Flash device mapped on the XScale Lubbock board' CONFIG_MTD_LUBBOCK $CONFIG_MTD_CFI $CONFIG_ARCH_LUBBOCK + dep_tristate ' CFI Flash device mapped on XScale IXP425 systems' CONFIG_MTD_IXP425 $CONFIG_MTD_CFI $CONFIG_MTD_COMPLEX_MAPPINGS + dep_tristate ' CFI Flash device mapped on Epxa10db' CONFIG_MTD_EPXA10DB $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS $CONFIG_ARCH_CAMELOT + dep_tristate ' CFI Flash device mapped on the FortuNet board' CONFIG_MTD_FORTUNET $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS $CONFIG_SA1100_FORTUNET dep_tristate ' NV-RAM mapping AUTCPU12 board' CONFIG_MTD_AUTCPU12 $CONFIG_ARCH_AUTCPU12 - dep_tristate ' CFI Flash device mapped on EDB7312' CONFIG_MTD_EDB7312 $CONFIG_ARCH_EDB7212 $CONFIG_MTD_CFI + dep_tristate ' CFI Flash device mapped on EDB7312' CONFIG_MTD_EDB7312 $CONFIG_MTD_CFI + dep_tristate ' CFI Flash device mapped on Hynix evaluation boards' CONFIG_MTD_H720X $CONFIG_MTD_CFI dep_tristate ' JEDEC Flash device mapped on impA7' CONFIG_MTD_IMPA7 $CONFIG_MTD_JEDECPROBE dep_tristate ' JEDEC Flash device mapped on Ceiva/Polaroid PhotoMax Digital Picture Frame' CONFIG_MTD_CEIVA $CONFIG_MTD_JEDECPROBE $CONFIG_ARCH_CEIVA + dep_tristate ' NOR Flash device on TOTO board' CONFIG_MTD_NOR_TOTO $CONFIG_MTD $CONFIG_OMAP_TOTO + dep_tristate ' CFI Flash device mapped on the Technologic Systems TS-7XXX board' CONFIG_MTD_TS7XXX $CONFIG_MTD_CFI fi if [ "$CONFIG_ALPHA" = "y" ]; then - dep_tristate ' Flash chip mapping on TSUNAMI' CONFIG_MTD_TSUNAMI $CONFIG_MTD_GENPROBE + dep_tristate ' Flash chip mapping on TSUNAMI' CONFIG_MTD_TSUNAMI $CONFIG_MTD_GENPROBE $CONFIG_MTD_COMPLEX_MAPPINGS fi if [ "$CONFIG_UCLINUX" = "y" ]; then @@ -98,7 +145,7 @@ fi # This needs CFI or JEDEC, depending on the cards found. -dep_tristate ' PCI MTD driver' CONFIG_MTD_PCI $CONFIG_MTD $CONFIG_PCI -dep_tristate ' PCMCIA MTD driver' CONFIG_MTD_PCMCIA $CONFIG_MTD $CONFIG_PCMCIA +dep_tristate ' PCI MTD driver' CONFIG_MTD_PCI $CONFIG_MTD $CONFIG_PCI $CONFIG_MTD_COMPLEX_MAPPINGS +dep_tristate ' PCMCIA MTD driver' CONFIG_MTD_PCMCIA $CONFIG_MTD $CONFIG_PCMCIA $CONFIG_MTD_COMPLEX_MAPPINGS endmenu Index: drivers/mtd/maps/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/Makefile,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/Makefile 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/Makefile 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,65 +1,11 @@ # -# linux/drivers/maps/Makefile +# linux/drivers/maps/Makefile.24 +# Makefile for obsolete kernels # -# $Id: Makefile,v 1.1 2004/07/22 19:49:45 joff Exp $ +# $Id: Makefile,v 1.3 2004/11/03 00:04:43 joff Exp $ O_TARGET := mapslink.o +export-objs := map_funcs.o -# Chip mappings -obj-$(CONFIG_MTD_CDB89712) += cdb89712.o -obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o -obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o -obj-$(CONFIG_MTD_CSTM_MIPS_IXX) += cstm_mips_ixx.o -obj-$(CONFIG_MTD_DC21285) += dc21285.o -obj-$(CONFIG_MTD_DILNETPC) += dilnetpc.o -obj-$(CONFIG_MTD_ELAN_104NC) += elan-104nc.o -obj-$(CONFIG_MTD_EPXA) += epxa-flash.o -obj-$(CONFIG_MTD_IQ80310) += iq80310.o -obj-$(CONFIG_MTD_L440GX) += l440gx.o -obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o -obj-$(CONFIG_MTD_ICH2ROM) += ich2rom.o -obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o -obj-$(CONFIG_MTD_MBX860) += mbx860.o -obj-$(CONFIG_MTD_NORA) += nora.o -obj-$(CONFIG_MTD_CEIVA) += ceiva.o -obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o -ifneq ($(CONFIG_MTD_PHYSMAP),n) - ifeq ($(CONFIG_MTD_PHYSMAP_BUSWIDTH),8) - obj-$(CONFIG_MTD_PHYSMAP) += physmap64.o - else - obj-$(CONFIG_MTD_PHYSMAP) += physmap.o - endif -endif -obj-$(CONFIG_MTD_PNC2000) += pnc2000.o -obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o -obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o -obj-$(CONFIG_MTD_TQM8XXL) += tqm8xxl.o -obj-$(CONFIG_MTD_SA1100) += sa1100-flash.o -ifeq ($(CONFIG_ASSABET_NEPONSET),y) - obj-$(CONFIG_MTD_SA1100) += neponset-flash.o -endif -obj-$(CONFIG_MTD_SBC_GXX) += sbc_gxx.o -obj-$(CONFIG_MTD_SC520CDP) += sc520cdp.o -obj-$(CONFIG_MTD_NETSC520) += netsc520.o -obj-$(CONFIG_MTD_SUN_UFLASH) += sun_uflash.o -obj-$(CONFIG_MTD_VMAX) += vmax301.o -obj-$(CONFIG_MTD_SCx200_DOCFLASH)+= scx200_docflash.o -obj-$(CONFIG_MTD_DBOX2) += dbox2-flash.o -obj-$(CONFIG_MTD_OCELOT) += ocelot.o -obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o -obj-$(CONFIG_MTD_PCI) += pci.o -obj-$(CONFIG_MTD_PB1000) += pb1xxx-flash.o -obj-$(CONFIG_MTD_PB1100) += pb1xxx-flash.o -obj-$(CONFIG_MTD_PB1500) += pb1xxx-flash.o -obj-$(CONFIG_MTD_LASAT) += lasat.o -obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o -obj-$(CONFIG_MTD_EDB7312) += edb7312.o -obj-$(CONFIG_MTD_IMPA7) += impa7.o -obj-$(CONFIG_MTD_FORTUNET) += fortunet.o -obj-$(CONFIG_MTD_REDWOOD) += redwood.o -obj-$(CONFIG_MTD_UCLINUX) += uclinux.o -obj-$(CONFIG_MTD_NETtel) += nettel.o -obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o -obj-$(CONFIG_MTD_TS7XXX) += ts7xxx.o - +include Makefile.common include $(TOPDIR)/Rules.make Index: drivers/mtd/maps/amd766rom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/amd766rom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/mtd/maps/amd766rom.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/amd766rom.c 4 Aug 2004 01:29:05 -0000 1.2 @@ -2,7 +2,7 @@ * amd766rom.c * * Normal mappings of chips in physical memory - * $Id: amd766rom.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: amd766rom.c,v 1.2 2004/08/04 01:29:05 joff Exp $ */ #include Index: drivers/mtd/maps/amd76xrom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/amd76xrom.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/amd76xrom.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/amd76xrom.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -2,212 +2,288 @@ * amd76xrom.c * * Normal mappings of chips in physical memory - * $Id: amd76xrom.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: amd76xrom.c,v 1.3 2004/11/03 00:04:43 joff Exp $ */ #include #include #include +#include #include #include #include +#include +#include #include #include #include +#include +#define xstr(s) str(s) +#define str(s) #s +#define MOD_NAME xstr(KBUILD_BASENAME) + +#define ADDRESS_NAME_LEN 18 + +#define ROM_PROBE_STEP_SIZE (64*1024) /* 64KiB */ + +struct amd76xrom_window { + void __iomem *virt; + unsigned long phys; + unsigned long size; + struct list_head maps; + struct resource rsrc; + struct pci_dev *pdev; +}; + struct amd76xrom_map_info { + struct list_head list; struct map_info map; struct mtd_info *mtd; - unsigned long window_addr; - u32 window_start, window_size; - struct pci_dev *pdev; + struct resource rsrc; + char map_name[sizeof(MOD_NAME) + 2 + ADDRESS_NAME_LEN]; }; -static __u8 amd76xrom_read8(struct map_info *map, unsigned long ofs) -{ - return __raw_readb(map->map_priv_1 + ofs); -} - -static __u16 amd76xrom_read16(struct map_info *map, unsigned long ofs) -{ - return __raw_readw(map->map_priv_1 + ofs); -} - -static __u32 amd76xrom_read32(struct map_info *map, unsigned long ofs) -{ - return __raw_readl(map->map_priv_1 + ofs); -} - -static void amd76xrom_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy_fromio(to, map->map_priv_1 + from, len); -} +static struct amd76xrom_window amd76xrom_window = { + .maps = LIST_HEAD_INIT(amd76xrom_window.maps), +}; -static void amd76xrom_write8(struct map_info *map, __u8 d, unsigned long adr) +static void amd76xrom_cleanup(struct amd76xrom_window *window) { - __raw_writeb(d, map->map_priv_1 + adr); - mb(); -} + struct amd76xrom_map_info *map, *scratch; + u8 byte; -static void amd76xrom_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - __raw_writew(d, map->map_priv_1 + adr); - mb(); -} + if (window->pdev) { + /* Disable writes through the rom window */ + pci_read_config_byte(window->pdev, 0x40, &byte); + pci_write_config_byte(window->pdev, 0x40, byte & ~1); + } -static void amd76xrom_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - __raw_writel(d, map->map_priv_1 + adr); - mb(); -} + /* Free all of the mtd devices */ + list_for_each_entry_safe(map, scratch, &window->maps, list) { + if (map->rsrc.parent) { + release_resource(&map->rsrc); + } + del_mtd_device(map->mtd); + map_destroy(map->mtd); + list_del(&map->list); + kfree(map); + } + if (window->rsrc.parent) + release_resource(&window->rsrc); -static void amd76xrom_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy_toio(map->map_priv_1 + to, from, len); + if (window->virt) { + iounmap(window->virt); + window->virt = NULL; + window->phys = 0; + window->size = 0; + window->pdev = NULL; + } } -static struct amd76xrom_map_info amd76xrom_map = { - map: { - name: "AMD76X rom", - size: 0, - buswidth: 1, - read8: amd76xrom_read8, - read16: amd76xrom_read16, - read32: amd76xrom_read32, - copy_from: amd76xrom_copy_from, - write8: amd76xrom_write8, - write16: amd76xrom_write16, - write32: amd76xrom_write32, - copy_to: amd76xrom_copy_to, - /* The standard rom socket is for single power supply chips - * that don't have an extra vpp. - */ - }, - mtd: 0, - window_addr: 0, -}; static int __devinit amd76xrom_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { - struct rom_window { - u32 start; - u32 size; - u8 segen_bits; - }; - static struct rom_window rom_window[] = { - { 0xffb00000, 5*1024*1024, (1<<7) | (1<<6), }, - { 0xffc00000, 4*1024*1024, (1<<7), }, - { 0xffff0000, 64*1024, 0 }, - { 0 , 0, 0 }, - }; - static const u32 rom_probe_sizes[] = { - 5*1024*1024, 4*1024*1024, 2*1024*1024, 1024*1024, 512*1024, - 256*1024, 128*1024, 64*1024, 0}; - static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", 0 }; + static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; u8 byte; - struct amd76xrom_map_info *info = &amd76xrom_map; - struct rom_window *window; - int i; - u32 rom_size; + struct amd76xrom_window *window = &amd76xrom_window; + struct amd76xrom_map_info *map = 0; + unsigned long map_top; - window = &rom_window[0]; -#if 0 - while(window->size) { - if (request_mem_region(window->start, window->size, "amd76xrom")) { - break; - } - window++; + /* Remember the pci dev I find the window in */ + window->pdev = pdev; + + /* Assume the rom window is properly setup, and find it's size */ + pci_read_config_byte(pdev, 0x43, &byte); + if ((byte & ((1<<7)|(1<<6))) == ((1<<7)|(1<<6))) { + window->phys = 0xffb00000; /* 5MiB */ } - if (!window->size) { - printk(KERN_ERR "amd76xrom: cannot reserve rom window\n"); - goto err_out_none; + else if ((byte & (1<<7)) == (1<<7)) { + window->phys = 0xffc00000; /* 4MiB */ + } + else { + window->phys = 0xffff0000; /* 64KiB */ + } + window->size = 0xffffffffUL - window->phys + 1UL; + + /* + * Try to reserve the window mem region. If this fails then + * it is likely due to a fragment of the window being + * "reseved" by the BIOS. In the case that the + * request_mem_region() fails then once the rom size is + * discovered we will try to reserve the unreserved fragment. + */ + window->rsrc.name = MOD_NAME; + window->rsrc.start = window->phys; + window->rsrc.end = window->phys + window->size - 1; + window->rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY; + if (request_resource(&iomem_resource, &window->rsrc)) { + window->rsrc.parent = NULL; + printk(KERN_ERR MOD_NAME + " %s(): Unable to register resource" + " 0x%.08lx-0x%.08lx - kernel bug?\n", + __func__, + window->rsrc.start, window->rsrc.end); } -#endif + +#if 0 /* Enable the selected rom window */ pci_read_config_byte(pdev, 0x43, &byte); - pci_write_config_byte(pdev, 0x43, byte | window->segen_bits); + pci_write_config_byte(pdev, 0x43, byte | rwindow->segen_bits); +#endif /* Enable writes through the rom window */ pci_read_config_byte(pdev, 0x40, &byte); pci_write_config_byte(pdev, 0x40, byte | 1); - + /* FIXME handle registers 0x80 - 0x8C the bios region locks */ - printk(KERN_NOTICE "amd76xrom window : %x at %x\n", - window->size, window->start); /* For write accesses caches are useless */ - info->window_addr = (unsigned long)ioremap_nocache(window->start, window->size); + window->virt = ioremap_nocache(window->phys, window->size); + if (!window->virt) { + printk(KERN_ERR MOD_NAME ": ioremap(%08lx, %08lx) failed\n", + window->phys, window->size); + goto out; + } + + /* Get the first address to look for an rom chip at */ + map_top = window->phys; +#if 1 + /* The probe sequence run over the firmware hub lock + * registers sets them to 0x7 (no access). + * Probe at most the last 4M of the address space. + */ + if (map_top < 0xffc00000) { + map_top = 0xffc00000; + } +#endif + /* Loop through and look for rom chips */ + while((map_top - 1) < 0xffffffffUL) { + struct cfi_private *cfi; + unsigned long offset; + int i; - if (!info->window_addr) { - printk(KERN_ERR "Failed to ioremap\n"); - goto err_out_free_mmio_region; - } - info->mtd = 0; - for(i = 0; (rom_size = rom_probe_sizes[i]); i++) { - char **chip_type; - if (rom_size > window->size) { - continue; - } - info->map.map_priv_1 = - info->window_addr + window->size - rom_size; - info->map.size = rom_size; - chip_type = rom_probe_types; - for(; !info->mtd && *chip_type; chip_type++) { - info->mtd = do_map_probe(*chip_type, &amd76xrom_map.map); + if (!map) { + map = kmalloc(sizeof(*map), GFP_KERNEL); } - if (info->mtd) { - break; + if (!map) { + printk(KERN_ERR MOD_NAME ": kmalloc failed"); + goto out; + } + memset(map, 0, sizeof(*map)); + INIT_LIST_HEAD(&map->list); + map->map.name = map->map_name; + map->map.phys = map_top; + offset = map_top - window->phys; + map->map.virt = (void __iomem *) + (((unsigned long)(window->virt)) + offset); + map->map.size = 0xffffffffUL - map_top + 1UL; + /* Set the name of the map to the address I am trying */ + sprintf(map->map_name, "%s @%08lx", + MOD_NAME, map->map.phys); + + /* There is no generic VPP support */ + for(map->map.bankwidth = 32; map->map.bankwidth; + map->map.bankwidth >>= 1) + { + char **probe_type; + /* Skip bankwidths that are not supported */ + if (!map_bankwidth_supported(map->map.bankwidth)) + continue; + + /* Setup the map methods */ + simple_map_init(&map->map); + + /* Try all of the probe methods */ + probe_type = rom_probe_types; + for(; *probe_type; probe_type++) { + map->mtd = do_map_probe(*probe_type, &map->map); + if (map->mtd) + goto found; + } + } + map_top += ROM_PROBE_STEP_SIZE; + continue; + found: + /* Trim the size if we are larger than the map */ + if (map->mtd->size > map->map.size) { + printk(KERN_WARNING MOD_NAME + " rom(%u) larger than window(%lu). fixing...\n", + map->mtd->size, map->map.size); + map->mtd->size = map->map.size; } + if (window->rsrc.parent) { + /* + * Registering the MTD device in iomem may not be possible + * if there is a BIOS "reserved" and BUSY range. If this + * fails then continue anyway. + */ + map->rsrc.name = map->map_name; + map->rsrc.start = map->map.phys; + map->rsrc.end = map->map.phys + map->mtd->size - 1; + map->rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY; + if (request_resource(&window->rsrc, &map->rsrc)) { + printk(KERN_ERR MOD_NAME + ": cannot reserve MTD resource\n"); + map->rsrc.parent = NULL; + } + } + + /* Make the whole region visible in the map */ + map->map.virt = window->virt; + map->map.phys = window->phys; + cfi = map->map.fldrv_priv; + for(i = 0; i < cfi->numchips; i++) { + cfi->chips[i].start += offset; + } + + /* Now that the mtd devices is complete claim and export it */ + map->mtd->owner = THIS_MODULE; + if (add_mtd_device(map->mtd)) { + map_destroy(map->mtd); + map->mtd = 0; + goto out; + } + + + /* Calculate the new value of map_top */ + map_top += map->mtd->size; + + /* File away the map structure */ + list_add(&map->list, &window->maps); + map = 0; } - if (!info->mtd) { - goto err_out_iounmap; + + out: + /* Free any left over map structures */ + if (map) { + kfree(map); + } + /* See if I have any map structures */ + if (list_empty(&window->maps)) { + amd76xrom_cleanup(window); + return -ENODEV; } - printk(KERN_NOTICE "amd76xrom chip at offset: %x\n", - window->size - rom_size); - - info->mtd->module = THIS_MODULE; - add_mtd_device(info->mtd); - info->window_start = window->start; - info->window_size = window->size; return 0; - -err_out_iounmap: - iounmap((void *)(info->window_addr)); -err_out_free_mmio_region: - release_mem_region(window->start, window->size); -err_out_none: - return -ENODEV; } static void __devexit amd76xrom_remove_one (struct pci_dev *pdev) { - struct amd76xrom_map_info *info = &amd76xrom_map; - u8 byte; + struct amd76xrom_window *window = &amd76xrom_window; - del_mtd_device(info->mtd); - map_destroy(info->mtd); - info->mtd = 0; - info->map.map_priv_1 = 0; - - iounmap((void *)(info->window_addr)); - info->window_addr = 0; - - /* Disable writes through the rom window */ - pci_read_config_byte(pdev, 0x40, &byte); - pci_write_config_byte(pdev, 0x40, byte & ~1); - - release_mem_region(info->window_start, info->window_size); + amd76xrom_cleanup(window); } -static struct pci_device_id amd76xrom_pci_tbl[] __devinitdata = { +static struct pci_device_id amd76xrom_pci_tbl[] = { { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7440, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_AMD, 0x7468 }, /* amd8111 support */ { 0, } }; @@ -215,10 +291,10 @@ #if 0 static struct pci_driver amd76xrom_driver = { - name: "amd76xrom", - id_table: amd76xrom_pci_tbl, - probe: amd76xrom_init_one, - remove: amd76xrom_remove_one, + .name = MOD_NAME, + .id_table = amd76xrom_pci_tbl, + .probe = amd76xrom_init_one, + .remove = amd76xrom_remove_one, }; #endif @@ -226,15 +302,14 @@ { struct pci_dev *pdev; struct pci_device_id *id; - pdev = 0; + pdev = NULL; for(id = amd76xrom_pci_tbl; id->vendor; id++) { - pdev = pci_find_device(id->vendor, id->device, 0); + pdev = pci_find_device(id->vendor, id->device, NULL); if (pdev) { break; } } if (pdev) { - amd76xrom_map.pdev = pdev; return amd76xrom_init_one(pdev, &amd76xrom_pci_tbl[0]); } return -ENXIO; @@ -245,7 +320,7 @@ static void __exit cleanup_amd76xrom(void) { - amd76xrom_remove_one(amd76xrom_map.pdev); + amd76xrom_remove_one(amd76xrom_window.pdev); } module_init(init_amd76xrom); Index: drivers/mtd/maps/autcpu12-nvram.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/autcpu12-nvram.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/autcpu12-nvram.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/autcpu12-nvram.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -2,7 +2,7 @@ * NV-RAM memory access on autcpu12 * (C) 2002 Thomas Gleixner (gleixner@autronix.de) * - * $Id: autcpu12-nvram.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: autcpu12-nvram.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -32,81 +33,28 @@ #include #include -__u8 autcpu12_read8(struct map_info *map, unsigned long ofs) -{ - return __raw_readb(map->map_priv_1 + ofs); -} - -__u16 autcpu12_read16(struct map_info *map, unsigned long ofs) -{ - return __raw_readw(map->map_priv_1 + ofs); -} - -__u32 autcpu12_read32(struct map_info *map, unsigned long ofs) -{ - return __raw_readl(map->map_priv_1 + ofs); -} - -void autcpu12_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - __raw_writeb(d, map->map_priv_1 + adr); - mb(); -} - -void autcpu12_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - __raw_writew(d, map->map_priv_1 + adr); - mb(); -} - -void autcpu12_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - __raw_writel(d, map->map_priv_1 + adr); - mb(); -} - -void autcpu12_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy_fromio(to, map->map_priv_1 + from, len); -} - -void autcpu12_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - while(len) { - __raw_writeb(*(unsigned char *) from, map->map_priv_1 + to); - from++; - to++; - len--; - } -} static struct mtd_info *sram_mtd; struct map_info autcpu12_sram_map = { - name: "SRAM", - size: 32768, - buswidth: 8, - read8: autcpu12_read8, - read16: autcpu12_read16, - read32: autcpu12_read32, - copy_from: autcpu12_copy_from, - write8: autcpu12_write8, - write16: autcpu12_write16, - write32: autcpu12_write32, - copy_to: autcpu12_copy_to + .name = "SRAM", + .size = 32768, + .bankwidth = 4, + .phys = 0x12000000, }; static int __init init_autcpu12_sram (void) { int err, save0, save1; - autcpu12_sram_map.map_priv_1 = (unsigned long)ioremap(0x12000000, SZ_128K); - if (!autcpu12_sram_map.map_priv_1) { + autcpu12_sram_map.virt = (void __iomem *)ioremap(0x12000000, SZ_128K); + if (!autcpu12_sram_map.virt) { printk("Failed to ioremap autcpu12 NV-RAM space\n"); err = -EIO; goto out; } - + simple_map_init(&autcpu_sram_map); + /* * Check for 32K/128K * read ofs 0 @@ -115,20 +63,20 @@ * Read and check result on ofs 0x0 * Restore contents */ - save0 = autcpu12_read32(&autcpu12_sram_map,0); - save1 = autcpu12_read32(&autcpu12_sram_map,0x10000); - autcpu12_write32(&autcpu12_sram_map,~save0,0x10000); + save0 = map_read32(&autcpu12_sram_map,0); + save1 = map_read32(&autcpu12_sram_map,0x10000); + map_write32(&autcpu12_sram_map,~save0,0x10000); /* if we find this pattern on 0x0, we have 32K size * restore contents and exit */ - if ( autcpu12_read32(&autcpu12_sram_map,0) != save0) { - autcpu12_write32(&autcpu12_sram_map,save0,0x0); + if ( map_read32(&autcpu12_sram_map,0) != save0) { + map_write32(&autcpu12_sram_map,save0,0x0); goto map; } /* We have a 128K found, restore 0x10000 and set size * to 128K */ - autcpu12_write32(&autcpu12_sram_map,save1,0x10000); + map_write32(&autcpu12_sram_map,save1,0x10000); autcpu12_sram_map.size = SZ_128K; map: @@ -139,7 +87,7 @@ goto out_ioremap; } - sram_mtd->module = THIS_MODULE; + sram_mtd->owner = THIS_MODULE; sram_mtd->erasesize = 16; if (add_mtd_device(sram_mtd)) { @@ -148,7 +96,7 @@ goto out_probe; } - printk("NV-RAM device size %ldK registered on AUTCPU12\n",autcpu12_sram_map.size/SZ_1K); + printk("NV-RAM device size %ldKiB registered on AUTCPU12\n",autcpu12_sram_map.size/SZ_1K); return 0; @@ -157,7 +105,7 @@ sram_mtd = 0; out_ioremap: - iounmap((void *)autcpu12_sram_map.map_priv_1); + iounmap((void *)autcpu12_sram_map.virt); out: return err; } @@ -167,7 +115,7 @@ if (sram_mtd) { del_mtd_device(sram_mtd); map_destroy(sram_mtd); - iounmap((void *)autcpu12_sram_map.map_priv_1); + iounmap((void *)autcpu12_sram_map.virt); } } Index: drivers/mtd/maps/cdb89712.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/cdb89712.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/cdb89712.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/cdb89712.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,13 +1,14 @@ /* * Flash on Cirrus CDB89712 * - * $Id: cdb89712.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: cdb89712.c,v 1.3 2004/11/03 00:04:43 joff Exp $ */ #include #include #include #include +#include #include #include #include @@ -16,77 +17,21 @@ -__u8 cdb89712_read8(struct map_info *map, unsigned long ofs) -{ - return __raw_readb(map->map_priv_1 + ofs); -} - -__u16 cdb89712_read16(struct map_info *map, unsigned long ofs) -{ - return __raw_readw(map->map_priv_1 + ofs); -} - -__u32 cdb89712_read32(struct map_info *map, unsigned long ofs) -{ - return __raw_readl(map->map_priv_1 + ofs); -} - -void cdb89712_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - __raw_writeb(d, map->map_priv_1 + adr); - mb(); -} - -void cdb89712_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - __raw_writew(d, map->map_priv_1 + adr); - mb(); -} - -void cdb89712_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - __raw_writel(d, map->map_priv_1 + adr); - mb(); -} - -void cdb89712_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - // printk ("cdb89712_copy_from: 0x%x@0x%x -> 0x%x\n", len, from, to); - memcpy_fromio(to, map->map_priv_1 + from, len); -} - -void cdb89712_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - while(len) { - __raw_writeb(*(unsigned char *) from, map->map_priv_1 + to); - from++; - to++; - len--; - } -} - static struct mtd_info *flash_mtd; struct map_info cdb89712_flash_map = { - name: "flash", - size: FLASH_SIZE, - buswidth: FLASH_WIDTH, - read8: cdb89712_read8, - read16: cdb89712_read16, - read32: cdb89712_read32, - copy_from: cdb89712_copy_from, - write8: cdb89712_write8, - write16: cdb89712_write16, - write32: cdb89712_write32, - copy_to: cdb89712_copy_to + .name = "flash", + .size = FLASH_SIZE, + .bankwidth = FLASH_WIDTH, + .phys = FLASH_START, }; struct resource cdb89712_flash_resource = { - name: "Flash", - start: FLASH_START, - end: FLASH_START + FLASH_SIZE - 1, - flags: IORESOURCE_IO | IORESOURCE_BUSY, + .name = "Flash", + .start = FLASH_START, + .end = FLASH_START + FLASH_SIZE - 1, + .flags = IORESOURCE_IO | IORESOURCE_BUSY, }; static int __init init_cdb89712_flash (void) @@ -99,13 +44,13 @@ goto out; } - cdb89712_flash_map.map_priv_1 = (unsigned long)ioremap(FLASH_START, FLASH_SIZE); - if (!cdb89712_flash_map.map_priv_1) { + cdb89712_flash_map.virt = (void __iomem *)ioremap(FLASH_START, FLASH_SIZE); + if (!cdb89712_flash_map.virt) { printk(KERN_NOTICE "Failed to ioremap Cdb89712 FLASH space\n"); err = -EIO; goto out_resource; } - + simple_map_init(&cdb89712_flash_map); flash_mtd = do_map_probe("cfi_probe", &cdb89712_flash_map); if (!flash_mtd) { flash_mtd = do_map_probe("map_rom", &cdb89712_flash_map); @@ -118,7 +63,7 @@ goto out_ioremap; } - flash_mtd->module = THIS_MODULE; + flash_mtd->owner = THIS_MODULE; if (add_mtd_device(flash_mtd)) { printk("FLASH device addition failed\n"); @@ -132,7 +77,7 @@ map_destroy(flash_mtd); flash_mtd = 0; out_ioremap: - iounmap((void *)cdb89712_flash_map.map_priv_1); + iounmap((void *)cdb89712_flash_map.virt); out_resource: release_resource (&cdb89712_flash_resource); out: @@ -146,24 +91,17 @@ static struct mtd_info *sram_mtd; struct map_info cdb89712_sram_map = { - name: "SRAM", - size: SRAM_SIZE, - buswidth: SRAM_WIDTH, - read8: cdb89712_read8, - read16: cdb89712_read16, - read32: cdb89712_read32, - copy_from: cdb89712_copy_from, - write8: cdb89712_write8, - write16: cdb89712_write16, - write32: cdb89712_write32, - copy_to: cdb89712_copy_to + .name = "SRAM", + .size = SRAM_SIZE, + .bankwidth = SRAM_WIDTH, + .phys = SRAM_START, }; struct resource cdb89712_sram_resource = { - name: "SRAM", - start: SRAM_START, - end: SRAM_START + SRAM_SIZE - 1, - flags: IORESOURCE_IO | IORESOURCE_BUSY, + .name = "SRAM", + .start = SRAM_START, + .end = SRAM_START + SRAM_SIZE - 1, + .flags = IORESOURCE_IO | IORESOURCE_BUSY, }; static int __init init_cdb89712_sram (void) @@ -176,13 +114,13 @@ goto out; } - cdb89712_sram_map.map_priv_1 = (unsigned long)ioremap(SRAM_START, SRAM_SIZE); - if (!cdb89712_sram_map.map_priv_1) { + cdb89712_sram_map.virt = (void __iomem *)ioremap(SRAM_START, SRAM_SIZE); + if (!cdb89712_sram_map.virt) { printk(KERN_NOTICE "Failed to ioremap Cdb89712 SRAM space\n"); err = -EIO; goto out_resource; } - + simple_map_init(&cdb89712_sram_map); sram_mtd = do_map_probe("map_ram", &cdb89712_sram_map); if (!sram_mtd) { printk("SRAM probe failed\n"); @@ -190,7 +128,7 @@ goto out_ioremap; } - sram_mtd->module = THIS_MODULE; + sram_mtd->owner = THIS_MODULE; sram_mtd->erasesize = 16; if (add_mtd_device(sram_mtd)) { @@ -205,7 +143,7 @@ map_destroy(sram_mtd); sram_mtd = 0; out_ioremap: - iounmap((void *)cdb89712_sram_map.map_priv_1); + iounmap((void *)cdb89712_sram_map.virt); out_resource: release_resource (&cdb89712_sram_resource); out: @@ -221,20 +159,17 @@ static struct mtd_info *bootrom_mtd; struct map_info cdb89712_bootrom_map = { - name: "BootROM", - size: BOOTROM_SIZE, - buswidth: BOOTROM_WIDTH, - read8: cdb89712_read8, - read16: cdb89712_read16, - read32: cdb89712_read32, - copy_from: cdb89712_copy_from, + .name = "BootROM", + .size = BOOTROM_SIZE, + .bankwidth = BOOTROM_WIDTH, + .phys = BOOTROM_START, }; struct resource cdb89712_bootrom_resource = { - name: "BootROM", - start: BOOTROM_START, - end: BOOTROM_START + BOOTROM_SIZE - 1, - flags: IORESOURCE_IO | IORESOURCE_BUSY, + .name = "BootROM", + .start = BOOTROM_START, + .end = BOOTROM_START + BOOTROM_SIZE - 1, + .flags = IORESOURCE_IO | IORESOURCE_BUSY, }; static int __init init_cdb89712_bootrom (void) @@ -247,13 +182,13 @@ goto out; } - cdb89712_bootrom_map.map_priv_1 = (unsigned long)ioremap(BOOTROM_START, BOOTROM_SIZE); - if (!cdb89712_bootrom_map.map_priv_1) { + cdb89712_bootrom_map.virt = (void __iomem *)ioremap(BOOTROM_START, BOOTROM_SIZE); + if (!cdb89712_bootrom_map.virt) { printk(KERN_NOTICE "Failed to ioremap Cdb89712 BootROM space\n"); err = -EIO; goto out_resource; } - + simple_map_init(&cdb89712_bootrom_map); bootrom_mtd = do_map_probe("map_rom", &cdb89712_bootrom_map); if (!bootrom_mtd) { printk("BootROM probe failed\n"); @@ -261,7 +196,7 @@ goto out_ioremap; } - bootrom_mtd->module = THIS_MODULE; + bootrom_mtd->owner = THIS_MODULE; bootrom_mtd->erasesize = 0x10000; if (add_mtd_device(bootrom_mtd)) { @@ -276,7 +211,7 @@ map_destroy(bootrom_mtd); bootrom_mtd = 0; out_ioremap: - iounmap((void *)cdb89712_bootrom_map.map_priv_1); + iounmap((void *)cdb89712_bootrom_map.virt); out_resource: release_resource (&cdb89712_bootrom_resource); out: @@ -306,21 +241,21 @@ if (sram_mtd) { del_mtd_device(sram_mtd); map_destroy(sram_mtd); - iounmap((void *)cdb89712_sram_map.map_priv_1); + iounmap((void *)cdb89712_sram_map.virt); release_resource (&cdb89712_sram_resource); } if (flash_mtd) { del_mtd_device(flash_mtd); map_destroy(flash_mtd); - iounmap((void *)cdb89712_flash_map.map_priv_1); + iounmap((void *)cdb89712_flash_map.virt); release_resource (&cdb89712_flash_resource); } if (bootrom_mtd) { del_mtd_device(bootrom_mtd); map_destroy(bootrom_mtd); - iounmap((void *)cdb89712_bootrom_map.map_priv_1); + iounmap((void *)cdb89712_bootrom_map.virt); release_resource (&cdb89712_bootrom_resource); } } Index: drivers/mtd/maps/ceiva.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/ceiva.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/ceiva.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/maps/ceiva.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -11,7 +11,7 @@ * * (C) 2000 Nicolas Pitre * - * $Id: ceiva.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: ceiva.c,v 1.3 2004/11/03 00:04:43 joff Exp $ */ #include @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -31,62 +32,10 @@ #include /* - * This isnt complete yet, so... + * This isn't complete yet, so... */ #define CONFIG_MTD_CEIVA_STATICMAP -static __u8 clps_read8(struct map_info *map, unsigned long ofs) -{ - return readb(map->map_priv_1 + ofs); -} - -static __u16 clps_read16(struct map_info *map, unsigned long ofs) -{ - return readw(map->map_priv_1 + ofs); -} - -static __u32 clps_read32(struct map_info *map, unsigned long ofs) -{ - return readl(map->map_priv_1 + ofs); -} - -static void clps_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy(to, (void *)(map->map_priv_1 + from), len); -} - -static void clps_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - writeb(d, map->map_priv_1 + adr); -} - -static void clps_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - writew(d, map->map_priv_1 + adr); -} - -static void clps_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - writel(d, map->map_priv_1 + adr); -} - -static void clps_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy((void *)(map->map_priv_1 + to), from, len); -} - -static struct map_info clps_map __initdata = { - name: "clps flash", - read8: clps_read8, - read16: clps_read16, - read32: clps_read32, - copy_from: clps_copy_from, - write8: clps_write8, - write16: clps_write16, - write32: clps_write32, - copy_to: clps_copy_to, -}; - #ifdef CONFIG_MTD_CEIVA_STATICMAP /* * See include/linux/mtd/partitions.h for definition of the mtd_partition @@ -115,23 +64,23 @@ static struct mtd_partition ceiva_partitions[] = { { - name: "Ceiva BOOT partition", - size: BOOT_PARTITION_SIZE_KiB*1024, - offset: 0, + .name = "Ceiva BOOT partition", + .size = BOOT_PARTITION_SIZE_KiB*1024, + .offset = 0, },{ - name: "Ceiva parameters partition", - size: PARAMS_PARTITION_SIZE_KiB*1024, - offset: (16 + 8) * 1024, + .name = "Ceiva parameters partition", + .size = PARAMS_PARTITION_SIZE_KiB*1024, + .offset = (16 + 8) * 1024, },{ - name: "Ceiva kernel partition", - size: (KERNEL_PARTITION_SIZE_KiB)*1024, - offset: 0x20000, + .name = "Ceiva kernel partition", + .size = (KERNEL_PARTITION_SIZE_KiB)*1024, + .offset = 0x20000, },{ - name: "Ceiva root filesystem partition", - offset: MTDPART_OFS_APPEND, - size: (ROOT_PARTITION_SIZE_KiB)*1024, + .name = "Ceiva root filesystem partition", + .offset = MTDPART_OFS_APPEND, + .size = (ROOT_PARTITION_SIZE_KiB)*1024, } }; #endif @@ -176,7 +125,7 @@ maps = kmalloc(sizeof(struct map_info) * nr, GFP_KERNEL); if (!maps) return -ENOMEM; - + memset(maps, 0, sizeof(struct map_info) * nr); /* * Claim and then map the memory regions. */ @@ -191,7 +140,9 @@ } clps[i].map = maps + i; - memcpy(clps[i].map, &clps_map, sizeof(struct map_info)); + + clps[i].map->name = "clps flash"; + clps[i].map->phys = clps[i].base; clps[i].vbase = ioremap(clps[i].base, clps[i].size); if (!clps[i].vbase) { @@ -199,16 +150,18 @@ break; } - clps[i].map->map_priv_1 = (unsigned long)clps[i].vbase; - clps[i].map->buswidth = clps[i].width; + clps[i].map->virt = (void __iomem *)clps[i].vbase; + clps[i].map->bankwidth = clps[i].width; clps[i].map->size = clps[i].size; + simple_map_init(&clps[i].map); + clps[i].mtd = do_map_probe("jedec_probe", clps[i].map); if (clps[i].mtd == NULL) { ret = -ENXIO; break; } - clps[i].mtd->module = THIS_MODULE; + clps[i].mtd->owner = THIS_MODULE; subdev[i] = clps[i].mtd; printk(KERN_INFO "clps flash: JEDEC device at 0x%08lx, %dMiB, " @@ -318,10 +271,8 @@ return nr; } -extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts); -extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, char *); - static struct mtd_partition *parsed_parts; +static const char *probes[] = { "cmdlinepart", "RedBoot", NULL }; static void __init clps_locate_partitions(struct mtd_info *mtd) { @@ -331,20 +282,11 @@ /* * Partition selection stuff. */ -#ifdef CONFIG_MTD_CMDLINE_PARTS - nr_parts = parse_cmdline_partitions(mtd, &parsed_parts, "clps"); + nr_parts = parse_mtd_partitions(mtd, probes, &parsed_parts, 0); if (nr_parts > 0) { part_type = "command line"; break; } -#endif -#ifdef CONFIG_MTD_REDBOOT_PARTS - nr_parts = parse_redboot_partitions(mtd, &parsed_parts); - if (nr_parts > 0) { - part_type = "RedBoot"; - break; - } -#endif #ifdef CONFIG_MTD_CEIVA_STATICMAP nr_parts = clps_static_partitions(&parsed_parts); if (nr_parts > 0) { Index: drivers/mtd/maps/cfi_flagadm.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/cfi_flagadm.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/cfi_flagadm.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/cfi_flagadm.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,7 +1,7 @@ /* * Copyright © 2001 Flaga hf. Medical Devices, Kári Davíđsson * - * $Id: cfi_flagadm.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: cfi_flagadm.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -55,83 +56,33 @@ #define FLASH_PARTITION3_ADDR 0x00240000 #define FLASH_PARTITION3_SIZE 0x001C0000 -__u8 flagadm_read8(struct map_info *map, unsigned long ofs) -{ - return __raw_readb(map->map_priv_1 + ofs); -} - -__u16 flagadm_read16(struct map_info *map, unsigned long ofs) -{ - return __raw_readw(map->map_priv_1 + ofs); -} - -__u32 flagadm_read32(struct map_info *map, unsigned long ofs) -{ - return __raw_readl(map->map_priv_1 + ofs); -} - -void flagadm_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy_fromio(to, map->map_priv_1 + from, len); -} - -void flagadm_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - __raw_writeb(d, map->map_priv_1 + adr); - mb(); -} - -void flagadm_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - __raw_writew(d, map->map_priv_1 + adr); - mb(); -} - -void flagadm_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - __raw_writel(d, map->map_priv_1 + adr); - mb(); -} - -void flagadm_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy_toio(map->map_priv_1 + to, from, len); -} struct map_info flagadm_map = { - name: "FlagaDM flash device", - size: FLASH_SIZE, - buswidth: 2, - read8: flagadm_read8, - read16: flagadm_read16, - read32: flagadm_read32, - copy_from: flagadm_copy_from, - write8: flagadm_write8, - write16: flagadm_write16, - write32: flagadm_write32, - copy_to: flagadm_copy_to + .name = "FlagaDM flash device", + .size = FLASH_SIZE, + .bankwidth = 2, }; struct mtd_partition flagadm_parts[] = { { - name : "Bootloader", - offset : FLASH_PARTITION0_ADDR, - size : FLASH_PARTITION0_SIZE + .name = "Bootloader", + .offset = FLASH_PARTITION0_ADDR, + .size = FLASH_PARTITION0_SIZE }, { - name : "Kernel image", - offset : FLASH_PARTITION1_ADDR, - size : FLASH_PARTITION1_SIZE + .name = "Kernel image", + .offset = FLASH_PARTITION1_ADDR, + .size = FLASH_PARTITION1_SIZE }, { - name : "Initial ramdisk image", - offset : FLASH_PARTITION2_ADDR, - size : FLASH_PARTITION2_SIZE + .name = "Initial ramdisk image", + .offset = FLASH_PARTITION2_ADDR, + .size = FLASH_PARTITION2_SIZE }, { - name : "Persistant storage", - offset : FLASH_PARTITION3_ADDR, - size : FLASH_PARTITION3_SIZE + .name = "Persistant storage", + .offset = FLASH_PARTITION3_ADDR, + .size = FLASH_PARTITION3_SIZE } }; @@ -144,22 +95,26 @@ printk(KERN_NOTICE "FlagaDM flash device: %x at %x\n", FLASH_SIZE, FLASH_PHYS_ADDR); - flagadm_map.map_priv_1 = (unsigned long)ioremap(FLASH_PHYS_ADDR, + flagadm_map.phys = FLASH_PHYS_ADDR; + flagadm_map.virt = (void __iomem *s)ioremap(FLASH_PHYS_ADDR, FLASH_SIZE); - if (!flagadm_map.map_priv_1) { + if (!flagadm_map.virt) { printk("Failed to ioremap\n"); return -EIO; } + + simple_map_init(&flagadm_map); + mymtd = do_map_probe("cfi_probe", &flagadm_map); if (mymtd) { - mymtd->module = THIS_MODULE; + mymtd->owner = THIS_MODULE; add_mtd_partitions(mymtd, flagadm_parts, PARTITION_COUNT); printk(KERN_NOTICE "FlagaDM flash device initialized\n"); return 0; } - iounmap((void *)flagadm_map.map_priv_1); + iounmap((void *)flagadm_map.virt); return -ENXIO; } @@ -169,9 +124,9 @@ del_mtd_partitions(mymtd); map_destroy(mymtd); } - if (flagadm_map.map_priv_1) { - iounmap((void *)flagadm_map.map_priv_1); - flagadm_map.map_priv_1 = 0; + if (flagadm_map.virt) { + iounmap((void *)flagadm_map.virt); + flagadm_map.virt = 0; } } Index: drivers/mtd/maps/cstm_mips_ixx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/cstm_mips_ixx.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/cstm_mips_ixx.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/cstm_mips_ixx.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,5 +1,5 @@ /* - * $Id: cstm_mips_ixx.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: cstm_mips_ixx.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * * Mapping of a custom board with both AMD CFI and JEDEC flash in partitions. * Config with both CFI and JEDEC device support. @@ -33,55 +33,13 @@ #include #include #include +#include #include #include #include #include #include - -#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) #include -#endif - -__u8 cstm_mips_ixx_read8(struct map_info *map, unsigned long ofs) -{ - return *(__u8 *)(map->map_priv_1 + ofs); -} - -__u16 cstm_mips_ixx_read16(struct map_info *map, unsigned long ofs) -{ - return *(__u16 *)(map->map_priv_1 + ofs); -} - -__u32 cstm_mips_ixx_read32(struct map_info *map, unsigned long ofs) -{ - return *(__u32 *)(map->map_priv_1 + ofs); -} - -void cstm_mips_ixx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy_fromio(to, map->map_priv_1 + from, len); -} - -void cstm_mips_ixx_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - *(__u8 *)(map->map_priv_1 + adr) = d; -} - -void cstm_mips_ixx_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - *(__u16 *)(map->map_priv_1 + adr) = d; -} - -void cstm_mips_ixx_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - *(__u32 *)(map->map_priv_1 + adr) = d; -} - -void cstm_mips_ixx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy_toio(map->map_priv_1 + to, from, len); -} #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) #define CC_GCR 0xB4013818 @@ -97,56 +55,47 @@ #define CC_GPAICR 0xB4013804 #endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */ +#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp) { - if (vpp) { -#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) - __u16 data; - __u8 data1; - static u8 first = 1; - - // Set GPIO port B pin3 to high - data = *(__u16 *)(CC_GPBCR); - data = (data & 0xff0f) | 0x0040; - *(__u16 *)CC_GPBCR = data; - *(__u8 *)CC_GPBDR = (*(__u8*)CC_GPBDR) | 0x08; - if (first) { - first = 0; - /* need to have this delay for first - enabling vpp after powerup */ - udelay(40); + static spinlock_t vpp_lock = SPIN_LOCK_UNLOCKED; + static int vpp_count = 0; + unsigned long flags; + + spin_lock_irqsave(&vpp_lock, flags); + + if (vpp) { + if (!vpp_count++) { + __u16 data; + __u8 data1; + static u8 first = 1; + + // Set GPIO port B pin3 to high + data = *(__u16 *)(CC_GPBCR); + data = (data & 0xff0f) | 0x0040; + *(__u16 *)CC_GPBCR = data; + *(__u8 *)CC_GPBDR = (*(__u8*)CC_GPBDR) | 0x08; + if (first) { + first = 0; + /* need to have this delay for first + enabling vpp after powerup */ + udelay(40); + } + } + } else { + if (!--vpp_count) { + __u16 data; + + // Set GPIO port B pin3 to high + data = *(__u16 *)(CC_GPBCR); + data = (data & 0xff3f) | 0x0040; + *(__u16 *)CC_GPBCR = data; + *(__u8 *)CC_GPBDR = (*(__u8*)CC_GPBDR) & 0xf7; + } } -#endif /* CONFIG_MIPS_ITE8172 */ - } - else { -#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) - __u16 data; - - // Set GPIO port B pin3 to high - data = *(__u16 *)(CC_GPBCR); - data = (data & 0xff3f) | 0x0040; - *(__u16 *)CC_GPBCR = data; - *(__u8 *)CC_GPBDR = (*(__u8*)CC_GPBDR) & 0xf7; -#endif /* CONFIG_MIPS_ITE8172 */ - } + spin_unlock_irqrestore(&vpp_lock, flags); } - -const struct map_info basic_cstm_mips_ixx_map = { - NULL, - 0, - 0, - cstm_mips_ixx_read8, - cstm_mips_ixx_read16, - cstm_mips_ixx_read32, - cstm_mips_ixx_copy_from, - cstm_mips_ixx_write8, - cstm_mips_ixx_write16, - cstm_mips_ixx_write32, - cstm_mips_ixx_copy_to, - cstm_mips_ixx_set_vpp, - 0, - 0 -}; +#endif /* board and partition description */ @@ -155,7 +104,7 @@ char *name; unsigned long window_addr; unsigned long window_size; - int buswidth; + int bankwidth; int num_partitions; }; @@ -167,7 +116,7 @@ "big flash", // name 0x08000000, // window_addr 0x02000000, // window_size - 4, // buswidth + 4, // bankwidth 1, // num_partitions } @@ -175,9 +124,9 @@ static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = { { // 28F128J3A in 2x16 configuration { - name: "main partition ", - size: 0x02000000, // 128 x 2 x 128k byte sectors - offset: 0, + .name = "main partition ", + .size = 0x02000000, // 128 x 2 x 128k byte sectors + .offset = 0, }, }, }; @@ -189,7 +138,7 @@ "MTD flash", // name CONFIG_MTD_CSTM_MIPS_IXX_START, // window_addr CONFIG_MTD_CSTM_MIPS_IXX_LEN, // window_size - CONFIG_MTD_CSTM_MIPS_IXX_BUSWIDTH, // buswidth + CONFIG_MTD_CSTM_MIPS_IXX_BUSWIDTH, // bankwidth 1, // num_partitions }, @@ -197,9 +146,9 @@ static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = { { { - name: "main partition", - size: CONFIG_MTD_CSTM_MIPS_IXX_LEN, - offset: 0, + .name = "main partition", + .size = CONFIG_MTD_CSTM_MIPS_IXX_LEN, + .offset = 0, }, }, }; @@ -216,17 +165,24 @@ /* Initialize mapping */ for (i=0;imodule = THIS_MODULE; + mymtd->owner = THIS_MODULE; cstm_mips_ixx_map[i].map_priv_2 = (unsigned long)mymtd; add_mtd_partitions(mymtd, parts, cstm_mips_ixx_board_desc[i].num_partitions); @@ -266,9 +222,9 @@ del_mtd_partitions(mymtd); map_destroy(mymtd); } - if (cstm_mips_ixx_map[i].map_priv_1) { - iounmap((void *)cstm_mips_ixx_map[i].map_priv_1); - cstm_mips_ixx_map[i].map_priv_1 = 0; + if (cstm_mips_ixx_map[i].virt) { + iounmap((void *)cstm_mips_ixx_map[i].virt); + cstm_mips_ixx_map[i].virt = 0; } } } Index: drivers/mtd/maps/dbox2-flash.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/dbox2-flash.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/dbox2-flash.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/dbox2-flash.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,37 +1,61 @@ /* - * $Id: dbox2-flash.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: dbox2-flash.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * - * Nokia / Sagem D-Box 2 flash driver + * D-Box 2 flash driver */ #include #include #include +#include #include #include #include #include #include +#include /* partition_info gives details on the logical partitions that the split the * single flash device into. If the size if zero we use up to the end of the * device. */ -static struct mtd_partition partition_info[]= {{name: "BR bootloader", // raw - size: 128 * 1024, - offset: 0, - mask_flags: MTD_WRITEABLE}, - {name: "PPC bootloader", // flfs - size: 128 * 1024, - offset: MTDPART_OFS_APPEND, - mask_flags: 0}, - {name: "Kernel", // idxfs - size: 768 * 1024, - offset: MTDPART_OFS_APPEND, - mask_flags: 0}, - {name: "System", // jffs - size: MTDPART_SIZ_FULL, - offset: MTDPART_OFS_APPEND, - mask_flags: 0}}; +static struct mtd_partition partition_info[]= { + { + .name = "BR bootloader", + .size = 128 * 1024, + .offset = 0, + .mask_flags = MTD_WRITEABLE + }, + { + .name = "FLFS (U-Boot)", + .size = 128 * 1024, + .offset = MTDPART_OFS_APPEND, + .mask_flags = 0 + }, + { + .name = "Root (SquashFS)", + .size = 7040 * 1024, + .offset = MTDPART_OFS_APPEND, + .mask_flags = 0 + }, + { + .name = "var (JFFS2)", + .size = 896 * 1024, + .offset = MTDPART_OFS_APPEND, + .mask_flags = 0 + }, + { + .name = "Flash without bootloader", + .size = MTDPART_SIZ_FULL, + .offset = 128 * 1024, + .mask_flags = 0 + }, + { + .name = "Complete Flash", + .size = MTDPART_SIZ_FULL, + .offset = 0, + .mask_flags = MTD_WRITEABLE + } +}; #define NUM_PARTITIONS (sizeof(partition_info) / sizeof(partition_info[0])) @@ -40,84 +64,36 @@ static struct mtd_info *mymtd; -__u8 dbox2_flash_read8(struct map_info *map, unsigned long ofs) -{ - return __raw_readb(map->map_priv_1 + ofs); -} - -__u16 dbox2_flash_read16(struct map_info *map, unsigned long ofs) -{ - return __raw_readw(map->map_priv_1 + ofs); -} - -__u32 dbox2_flash_read32(struct map_info *map, unsigned long ofs) -{ - return __raw_readl(map->map_priv_1 + ofs); -} - -void dbox2_flash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy_fromio(to, map->map_priv_1 + from, len); -} - -void dbox2_flash_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - __raw_writeb(d, map->map_priv_1 + adr); - mb(); -} - -void dbox2_flash_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - __raw_writew(d, map->map_priv_1 + adr); - mb(); -} - -void dbox2_flash_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - __raw_writel(d, map->map_priv_1 + adr); - mb(); -} - -void dbox2_flash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy_toio(map->map_priv_1 + to, from, len); -} struct map_info dbox2_flash_map = { - name: "D-Box 2 flash memory", - size: WINDOW_SIZE, - buswidth: 4, - read8: dbox2_flash_read8, - read16: dbox2_flash_read16, - read32: dbox2_flash_read32, - copy_from: dbox2_flash_copy_from, - write8: dbox2_flash_write8, - write16: dbox2_flash_write16, - write32: dbox2_flash_write32, - copy_to: dbox2_flash_copy_to + .name = "D-Box 2 flash memory", + .size = WINDOW_SIZE, + .bankwidth = 4, + .phys = WINDOW_ADDR, }; int __init init_dbox2_flash(void) { printk(KERN_NOTICE "D-Box 2 flash driver (size->0x%X mem->0x%X)\n", WINDOW_SIZE, WINDOW_ADDR); - dbox2_flash_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE); + dbox2_flash_map.virt = (void __iomem *)ioremap(WINDOW_ADDR, WINDOW_SIZE); - if (!dbox2_flash_map.map_priv_1) { + if (!dbox2_flash_map.virt) { printk("Failed to ioremap\n"); return -EIO; } + simple_map_init(&dbox2_flash_map); // Probe for dual Intel 28F320 or dual AMD mymtd = do_map_probe("cfi_probe", &dbox2_flash_map); if (!mymtd) { // Probe for single Intel 28F640 - dbox2_flash_map.buswidth = 2; + dbox2_flash_map.bankwidth = 2; mymtd = do_map_probe("cfi_probe", &dbox2_flash_map); } if (mymtd) { - mymtd->module = THIS_MODULE; + mymtd->owner = THIS_MODULE; /* Create MTD devices for each partition. */ add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS); @@ -125,7 +101,7 @@ return 0; } - iounmap((void *)dbox2_flash_map.map_priv_1); + iounmap((void *)dbox2_flash_map.virt); return -ENXIO; } @@ -135,9 +111,9 @@ del_mtd_partitions(mymtd); map_destroy(mymtd); } - if (dbox2_flash_map.map_priv_1) { - iounmap((void *)dbox2_flash_map.map_priv_1); - dbox2_flash_map.map_priv_1 = 0; + if (dbox2_flash_map.virt) { + iounmap((void *)dbox2_flash_map.virt); + dbox2_flash_map.virt = 0; } } @@ -146,5 +122,5 @@ MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Kári Davíđsson "); -MODULE_DESCRIPTION("MTD map driver for Nokia/Sagem D-Box 2 board"); +MODULE_AUTHOR("Kári Davíđsson , Bastian Blank , Alexander Wild "); +MODULE_DESCRIPTION("MTD map driver for D-Box 2 board"); Index: drivers/mtd/maps/dc21285.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/dc21285.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/dc21285.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/dc21285.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -5,12 +5,14 @@ * * This code is GPL * - * $Id: dc21285.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: dc21285.c,v 1.3 2004/11/03 00:04:43 joff Exp $ */ #include #include #include #include +#include +#include #include #include @@ -18,143 +20,199 @@ #include #include +#include -static struct mtd_info *mymtd; +static struct mtd_info *dc21285_mtd; -__u8 dc21285_read8(struct map_info *map, unsigned long ofs) +#ifdef CONFIG_ARCH_NETWINDER +/* + * This is really ugly, but it seams to be the only + * realiable way to do it, as the cpld state machine + * is unpredictible. So we have a 25us penalty per + * write access. + */ +static void nw_en_write(void) +{ + extern spinlock_t gpio_lock; + unsigned long flags; + + /* + * we want to write a bit pattern XXX1 to Xilinx to enable + * the write gate, which will be open for about the next 2ms. + */ + spin_lock_irqsave(&gpio_lock, flags); + cpld_modify(1, 1); + spin_unlock_irqrestore(&gpio_lock, flags); + + /* + * let the ISA bus to catch on... + */ + udelay(25); +} +#else +#define nw_en_write() do { } while (0) +#endif + +static map_word dc21285_read8(struct map_info *map, unsigned long ofs) { - return *(__u8*)(map->map_priv_1 + ofs); + map_word val; + val.x[0] = *(uint8_t*)(map->virt + ofs); + return val; } -__u16 dc21285_read16(struct map_info *map, unsigned long ofs) +static map_word dc21285_read16(struct map_info *map, unsigned long ofs) { - return *(__u16*)(map->map_priv_1 + ofs); + map_word val; + val.x[0] = *(uint16_t*)(map->virt + ofs); + return val; } -__u32 dc21285_read32(struct map_info *map, unsigned long ofs) +static map_word dc21285_read32(struct map_info *map, unsigned long ofs) { - return *(__u32*)(map->map_priv_1 + ofs); + map_word val; + val.x[0] = *(uint32_t*)(map->virt + ofs); + return val; } -void dc21285_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +static void dc21285_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) { - memcpy(to, (void*)(map->map_priv_1 + from), len); + memcpy(to, (void*)(map->virt + from), len); } -void dc21285_write8(struct map_info *map, __u8 d, unsigned long adr) +static void dc21285_write8(struct map_info *map, const map_word d, unsigned long adr) { + if (machine_is_netwinder()) + nw_en_write(); *CSR_ROMWRITEREG = adr & 3; adr &= ~3; - *(__u8*)(map->map_priv_1 + adr) = d; + *(uint8_t*)(map->virt + adr) = d.x[0]; } -void dc21285_write16(struct map_info *map, __u16 d, unsigned long adr) +static void dc21285_write16(struct map_info *map, const map_word d, unsigned long adr) { + if (machine_is_netwinder()) + nw_en_write(); *CSR_ROMWRITEREG = adr & 3; adr &= ~3; - *(__u16*)(map->map_priv_1 + adr) = d; + *(uint16_t*)(map->virt + adr) = d.x[0]; } -void dc21285_write32(struct map_info *map, __u32 d, unsigned long adr) +static void dc21285_write32(struct map_info *map, const map_word d, unsigned long adr) { - *(__u32*)(map->map_priv_1 + adr) = d; + if (machine_is_netwinder()) + nw_en_write(); + *(uint32_t*)(map->virt + adr) = d.x[0]; } -void dc21285_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +static void dc21285_copy_to_32(struct map_info *map, unsigned long to, const void *from, ssize_t len) { - switch (map->buswidth) { - case 4: - while (len > 0) { - __u32 d = *((__u32*)from)++; - dc21285_write32(map, d, to); - to += 4; - len -= 4; - } - break; - case 2: - while (len > 0) { - __u16 d = *((__u16*)from)++; - dc21285_write16(map, d, to); - to += 2; - len -= 2; - } - break; - case 1: - while (len > 0) { - __u8 d = *((__u8*)from)++; - dc21285_write8(map, d, to); - to++; - len--; - } - break; + while (len > 0) { + map_word d; + d.x[0] = *((uint32_t*)from)++; + dc21285_write32(map, d, to); + to += 4; + len -= 4; } } -struct map_info dc21285_map = { - name: "DC21285 flash", - size: 16*1024*1024, - read8: dc21285_read8, - read16: dc21285_read16, - read32: dc21285_read32, - copy_from: dc21285_copy_from, - write8: dc21285_write8, - write16: dc21285_write16, - write32: dc21285_write32, - copy_to: dc21285_copy_to +static void dc21285_copy_to_16(struct map_info *map, unsigned long to, const void *from, ssize_t len) +{ + while (len > 0) { + map_word d; + d.x[0] = *((uint16_t*)from)++; + dc21285_write16(map, d, to); + to += 2; + len -= 2; + } +} + +static void dc21285_copy_to_8(struct map_info *map, unsigned long to, const void *from, ssize_t len) +{ + map_word d; + d.x[0] = *((uint8_t*)from)++; + dc21285_write8(map, d, to); + to++; + len--; +} + +static struct map_info dc21285_map = { + .name = "DC21285 flash", + .phys = NO_XIP, + .size = 16*1024*1024, + .copy_from = dc21285_copy_from, }; /* Partition stuff */ +#ifdef CONFIG_MTD_PARTITIONS static struct mtd_partition *dc21285_parts; - -extern int parse_redboot_partitions(struct mtd_info *, struct mtd_partition **); - -int __init init_dc21285(void) +static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; +#endif + +static int __init init_dc21285(void) { - /* Determine buswidth */ + +#ifdef CONFIG_MTD_PARTITIONS + int nrparts; +#endif + + /* Determine bankwidth */ switch (*CSR_SA110_CNTL & (3<<14)) { case SA110_CNTL_ROMWIDTH_8: - dc21285_map.buswidth = 1; + dc21285_map.bankwidth = 1; + dc21285_map.read = dc21285_read8; + dc21285_map.write = dc21285_write8; + dc21285_map.copy_to = dc21285_copy_to_8; break; case SA110_CNTL_ROMWIDTH_16: - dc21285_map.buswidth = 2; + dc21285_map.bankwidth = 2; + dc21285_map.read = dc21285_read16; + dc21285_map.write = dc21285_write16; + dc21285_map.copy_to = dc21285_copy_to_16; break; case SA110_CNTL_ROMWIDTH_32: - dc21285_map.buswidth = 4; + dc21285_map.bankwidth = 4; + dc21285_map.read = dc21285_read32; + dc21285_map.write = dc21285_write32; + dc21285_map.copy_to = dc21285_copy_to_32; break; default: - printk (KERN_ERR "DC21285 flash: undefined buswidth\n"); + printk (KERN_ERR "DC21285 flash: undefined bankwidth\n"); return -ENXIO; } - printk (KERN_NOTICE "DC21285 flash support (%d-bit buswidth)\n", - dc21285_map.buswidth*8); + printk (KERN_NOTICE "DC21285 flash support (%d-bit bankwidth)\n", + dc21285_map.bankwidth*8); /* Let's map the flash area */ - dc21285_map.map_priv_1 = (unsigned long)ioremap(DC21285_FLASH, 16*1024*1024); - if (!dc21285_map.map_priv_1) { + dc21285_map.virt = ioremap(DC21285_FLASH, 16*1024*1024); + if (!dc21285_map.virt) { printk("Failed to ioremap\n"); return -EIO; } - mymtd = do_map_probe("cfi_probe", &dc21285_map); - if (mymtd) { - int nrparts = 0; - - mymtd->module = THIS_MODULE; + if (machine_is_ebsa285()) { + dc21285_mtd = do_map_probe("cfi_probe", &dc21285_map); + } else { + dc21285_mtd = do_map_probe("jedec_probe", &dc21285_map); + } + + if (!dc21285_mtd) { + iounmap(dc21285_map.virt); + return -ENXIO; + } + + dc21285_mtd->owner = THIS_MODULE; + +#ifdef CONFIG_MTD_PARTITIONS + nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0); + if (nrparts > 0) + add_mtd_partitions(dc21285_mtd, dc21285_parts, nrparts); + else +#endif + add_mtd_device(dc21285_mtd); - /* partition fixup */ - -#ifdef CONFIG_MTD_REDBOOT_PARTS - nrparts = parse_redboot_partitions(mymtd, &dc21285_parts); -#endif - if (nrparts > 0) { - add_mtd_partitions(mymtd, dc21285_parts, nrparts); - } else if (nrparts == 0) { - printk(KERN_NOTICE "RedBoot partition table failed\n"); - add_mtd_device(mymtd); - } - + if(machine_is_ebsa285()) { /* * Flash timing is determined with bits 19-16 of the * CSR_SA110_CNTL. The value is the number of wait cycles, or @@ -167,27 +225,23 @@ *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x00f00000) | (7 << 20)); /* tristate time */ *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24)); - - return 0; } - - iounmap((void *)dc21285_map.map_priv_1); - return -ENXIO; + + return 0; } static void __exit cleanup_dc21285(void) { - if (mymtd) { - del_mtd_device(mymtd); - map_destroy(mymtd); - mymtd = NULL; - } - if (dc21285_map.map_priv_1) { - iounmap((void *)dc21285_map.map_priv_1); - dc21285_map.map_priv_1 = 0; - } - if(dc21285_parts) +#ifdef CONFIG_MTD_PARTITIONS + if (dc21285_parts) { + del_mtd_partitions(dc21285_mtd); kfree(dc21285_parts); + } else +#endif + del_mtd_device(dc21285_mtd); + + map_destroy(dc21285_mtd); + iounmap(dc21285_map.virt); } module_init(init_dc21285); Index: drivers/mtd/maps/dilnetpc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/dilnetpc.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/dilnetpc.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/dilnetpc.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -14,7 +14,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: dilnetpc.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: dilnetpc.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * * The DIL/Net PC is a tiny embedded PC board made by SSV Embedded Systems * featuring the AMD Elan SC410 processor. There are two variants of this @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -36,7 +37,7 @@ #include /* -** The DIL/NetPC keeps it's BIOS in two distinct flash blocks. +** The DIL/NetPC keeps its BIOS in two distinct flash blocks. ** Destroying any of these blocks transforms the DNPC into ** a paperweight (albeit not a very useful one, considering ** it only weighs a few grams). @@ -189,45 +190,6 @@ } -static __u8 dnpc_read8(struct map_info *map, unsigned long ofs) -{ - return readb(map->map_priv_1 + ofs); -} - -static __u16 dnpc_read16(struct map_info *map, unsigned long ofs) -{ - return readw(map->map_priv_1 + ofs); -} - -static __u32 dnpc_read32(struct map_info *map, unsigned long ofs) -{ - return readl(map->map_priv_1 + ofs); -} - -static void dnpc_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy_fromio(to, (void *)(map->map_priv_1 + from), len); -} - -static void dnpc_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - writeb(d, map->map_priv_1 + adr); -} - -static void dnpc_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - writew(d, map->map_priv_1 + adr); -} - -static void dnpc_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - writel(d, map->map_priv_1 + adr); -} - -static void dnpc_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy_toio((void *)(map->map_priv_1 + to), from, len); -} /* ************************************************************ @@ -285,22 +247,14 @@ #define DNP_WINDOW_SIZE 0x00200000 /* DNP flash size is 2MiB */ #define ADNP_WINDOW_SIZE 0x00400000 /* ADNP flash size is 4MiB */ -#define WINDOW_ADDR FLASH_BASE +#define WINDOW_ADDR FLASH_BASE static struct map_info dnpc_map = { - name: "ADNP Flash Bank", - size: ADNP_WINDOW_SIZE, - buswidth: 1, - read8: dnpc_read8, - read16: dnpc_read16, - read32: dnpc_read32, - copy_from: dnpc_copy_from, - write8: dnpc_write8, - write16: dnpc_write16, - write32: dnpc_write32, - copy_to: dnpc_copy_to, - set_vpp: adnp_set_vpp, - map_priv_2: WINDOW_ADDR + .name = "ADNP Flash Bank", + .size = ADNP_WINDOW_SIZE, + .bankwidth = 1, + .set_vpp = adnp_set_vpp, + .phys = WINDOW_ADDR }; /* @@ -316,29 +270,29 @@ static struct mtd_partition partition_info[]= { { - name: "ADNP boot", - offset: 0, - size: 0xf0000, + .name = "ADNP boot", + .offset = 0, + .size = 0xf0000, }, { - name: "ADNP system BIOS", - offset: MTDPART_OFS_NXTBLK, - size: 0x10000, + .name = "ADNP system BIOS", + .offset = MTDPART_OFS_NXTBLK, + .size = 0x10000, #ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED - mask_flags: MTD_WRITEABLE, + .mask_flags = MTD_WRITEABLE, #endif }, { - name: "ADNP file system", - offset: MTDPART_OFS_NXTBLK, - size: 0x2f0000, + .name = "ADNP file system", + .offset = MTDPART_OFS_NXTBLK, + .size = 0x2f0000, }, { - name: "ADNP system BIOS entry", - offset: MTDPART_OFS_NXTBLK, - size: MTDPART_SIZ_FULL, + .name = "ADNP system BIOS entry", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, #ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED - mask_flags: MTD_WRITEABLE, + .mask_flags = MTD_WRITEABLE, #endif }, }; @@ -369,21 +323,21 @@ static struct mtd_partition higlvl_partition_info[]= { { - name: "ADNP boot block", - offset: 0, - size: CONFIG_MTD_DILNETPC_BOOTSIZE, + .name = "ADNP boot block", + .offset = 0, + .size = CONFIG_MTD_DILNETPC_BOOTSIZE, }, { - name: "ADNP file system space", - offset: MTDPART_OFS_NXTBLK, - size: ADNP_WINDOW_SIZE-CONFIG_MTD_DILNETPC_BOOTSIZE-0x20000, + .name = "ADNP file system space", + .offset = MTDPART_OFS_NXTBLK, + .size = ADNP_WINDOW_SIZE-CONFIG_MTD_DILNETPC_BOOTSIZE-0x20000, }, { - name: "ADNP system BIOS + BIOS Entry", - offset: MTDPART_OFS_NXTBLK, - size: MTDPART_SIZ_FULL, + .name = "ADNP system BIOS + BIOS Entry", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, #ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED - mask_flags: MTD_WRITEABLE, + .mask_flags = MTD_WRITEABLE, #endif }, }; @@ -447,18 +401,19 @@ } printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%lx\n", - is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.map_priv_2); + is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.phys); - dnpc_map.map_priv_1 = (unsigned long)ioremap_nocache(dnpc_map.map_priv_2, dnpc_map.size); + dnpc_map.virt = (void __iomem *)ioremap_nocache(dnpc_map.phys, dnpc_map.size); - dnpc_map_flash(dnpc_map.map_priv_2, dnpc_map.size); + dnpc_map_flash(dnpc_map.phys, dnpc_map.size); - if (!dnpc_map.map_priv_1) { + if (!dnpc_map.virt) { printk("Failed to ioremap_nocache\n"); return -EIO; } + simple_map_init(&dnpc_map); - printk("FLASH virtual address: 0x%lx\n", dnpc_map.map_priv_1); + printk("FLASH virtual address: 0x%p\n", dnpc_map.virt); mymtd = do_map_probe("jedec_probe", &dnpc_map); @@ -475,11 +430,11 @@ mymtd->erasesize = 0x10000; if (!mymtd) { - iounmap((void *)dnpc_map.map_priv_1); + iounmap((void *)dnpc_map.virt); return -ENXIO; } - mymtd->module = THIS_MODULE; + mymtd->owner = THIS_MODULE; /* ** Supply pointers to lowlvl_parts[] array to add_mtd_partitions() @@ -525,10 +480,10 @@ del_mtd_partitions(mymtd); map_destroy(mymtd); } - if (dnpc_map.map_priv_1) { - iounmap((void *)dnpc_map.map_priv_1); + if (dnpc_map.virt) { + iounmap((void *)dnpc_map.virt); dnpc_unmap_flash(); - dnpc_map.map_priv_1 = 0; + dnpc_map.virt = 0; } } Index: drivers/mtd/maps/edb7312.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/edb7312.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/edb7312.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/edb7312.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,5 +1,5 @@ /* - * $Id: edb7312.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: edb7312.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * * Handle mapping of the NOR flash on Cogent EDB7312 boards * @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -27,69 +28,19 @@ #define BUSWIDTH 2 #define FLASH_BLOCKSIZE_MAIN 0x20000 #define FLASH_NUMBLOCKS_MAIN 128 -/* can be "cfi_probe", "jedec_probe", "map_rom", 0 }; */ -#define PROBETYPES { "cfi_probe", 0 } +/* can be "cfi_probe", "jedec_probe", "map_rom", NULL }; */ +#define PROBETYPES { "cfi_probe", NULL } #define MSG_PREFIX "EDB7312-NOR:" /* prefix for our printk()'s */ #define MTDID "edb7312-nor" /* for mtdparts= partitioning */ static struct mtd_info *mymtd; -__u8 edb7312nor_read8(struct map_info *map, unsigned long ofs) -{ - return __raw_readb(map->map_priv_1 + ofs); -} - -__u16 edb7312nor_read16(struct map_info *map, unsigned long ofs) -{ - return __raw_readw(map->map_priv_1 + ofs); -} - -__u32 edb7312nor_read32(struct map_info *map, unsigned long ofs) -{ - return __raw_readl(map->map_priv_1 + ofs); -} - -void edb7312nor_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy_fromio(to, map->map_priv_1 + from, len); -} - -void edb7312nor_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - __raw_writeb(d, map->map_priv_1 + adr); - mb(); -} - -void edb7312nor_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - __raw_writew(d, map->map_priv_1 + adr); - mb(); -} - -void edb7312nor_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - __raw_writel(d, map->map_priv_1 + adr); - mb(); -} - -void edb7312nor_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy_toio(map->map_priv_1 + to, from, len); -} - struct map_info edb7312nor_map = { - name: "NOR flash on EDB7312", - size: WINDOW_SIZE, - buswidth: BUSWIDTH, - read8: edb7312nor_read8, - read16: edb7312nor_read16, - read32: edb7312nor_read32, - copy_from: edb7312nor_copy_from, - write8: edb7312nor_write8, - write16: edb7312nor_write16, - write32: edb7312nor_write32, - copy_to: edb7312nor_copy_to + .name = "NOR flash on EDB7312", + .size = WINDOW_SIZE, + .bankwidth = BUSWIDTH, + .phys = WINDOW_ADDR, }; #ifdef CONFIG_MTD_PARTITIONS @@ -99,30 +50,24 @@ */ static struct mtd_partition static_partitions[3] = { - { - name: "ARMboot", - size: 0x40000, - offset: 0 - }, - { - name: "Kernel", - size: 0x200000, - offset: 0x40000 - }, - { - name: "RootFS", - size: 0xDC0000, - offset: 0x240000 - }, + { + .name = "ARMboot", + .size = 0x40000, + .offset = 0 + }, + { + .name = "Kernel", + .size = 0x200000, + .offset = 0x40000 + }, + { + .name = "RootFS", + .size = 0xDC0000, + .offset = 0x240000 + }, }; -#define NB_OF(x) (sizeof (x) / sizeof (x[0])) - -#ifdef CONFIG_MTD_CMDLINE_PARTS -int parse_cmdline_partitions(struct mtd_info *master, - struct mtd_partition **pparts, - const char *mtd_id); -#endif +static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; #endif @@ -137,13 +82,15 @@ printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n", WINDOW_SIZE, WINDOW_ADDR); - edb7312nor_map.map_priv_1 = (unsigned long) - ioremap(WINDOW_ADDR, WINDOW_SIZE); + edb7312nor_map.virt = (void __iomem *) + ioremap(WINDOW_ADDR, WINDOW_SIZE); - if (!edb7312nor_map.map_priv_1) { + if (!edb7312nor_map.virt) { printk(MSG_PREFIX "failed to ioremap\n"); return -EIO; } + + simple_map_init(&edb7312nor_map); mymtd = 0; type = rom_probe_types; @@ -151,18 +98,17 @@ mymtd = do_map_probe(*type, &edb7312nor_map); } if (mymtd) { - mymtd->module = THIS_MODULE; + mymtd->owner = THIS_MODULE; #ifdef CONFIG_MTD_PARTITIONS -#ifdef CONFIG_MTD_CMDLINE_PARTS - mtd_parts_nb = parse_cmdline_partitions(mymtd, &mtd_parts, MTDID); + mtd_parts_nb = parse_mtd_partitions(mymtd, probes, &mtd_parts, MTDID); if (mtd_parts_nb > 0) - part_type = "command line"; -#endif + part_type = "detected"; + if (mtd_parts_nb == 0) { mtd_parts = static_partitions; - mtd_parts_nb = NB_OF(static_partitions); + mtd_parts_nb = ARRAY_SIZE(static_partitions); part_type = "static"; } #endif @@ -178,7 +124,7 @@ return 0; } - iounmap((void *)edb7312nor_map.map_priv_1); + iounmap((void *)edb7312nor_map.virt); return -ENXIO; } @@ -188,9 +134,9 @@ del_mtd_device(mymtd); map_destroy(mymtd); } - if (edb7312nor_map.map_priv_1) { - iounmap((void *)edb7312nor_map.map_priv_1); - edb7312nor_map.map_priv_1 = 0; + if (edb7312nor_map.virt) { + iounmap((void *)edb7312nor_map.virt); + edb7312nor_map.virt = 0; } } Index: drivers/mtd/maps/elan-104nc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/elan-104nc.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/elan-104nc.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/elan-104nc.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -16,7 +16,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - $Id: elan-104nc.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + $Id: elan-104nc.c,v 1.3 2004/11/03 00:04:43 joff Exp $ The ELAN-104NC has up to 8 Mibyte of Intel StrataFlash (28F320/28F640) in x16 mode. This drivers uses the CFI probe and Intel Extended Command Set drivers. @@ -27,7 +27,7 @@ 16 bit I/O port (0x22) for some sort of paging. -The single flash device is divided into 3 partition which appear as seperate +The single flash device is divided into 3 partition which appear as separate MTD devices. Linux thinks that the I/O port is used by the PIC and hence check_region() will @@ -40,6 +40,7 @@ #include #include +#include #include #define WINDOW_START 0xb0000 @@ -52,21 +53,21 @@ #define PAGE_IO_SIZE 2 static volatile int page_in_window = -1; // Current page in window. -static unsigned long iomapadr; +static void __iomem *iomapadr; static spinlock_t elan_104nc_spin = SPIN_LOCK_UNLOCKED; /* partition_info gives details on the logical partitions that the split the * single flash device into. If the size if zero we use up to the end of the * device. */ static struct mtd_partition partition_info[]={ - { name: "ELAN-104NC flash boot partition", - offset: 0, - size: 640*1024 }, - { name: "ELAN-104NC flash partition 1", - offset: 640*1024, - size: 896*1024 }, - { name: "ELAN-104NC flash partition 2", - offset: (640+896)*1024 } + { .name = "ELAN-104NC flash boot partition", + .offset = 0, + .size = 640*1024 }, + { .name = "ELAN-104NC flash partition 1", + .offset = 640*1024, + .size = 896*1024 }, + { .name = "ELAN-104NC flash partition 2", + .offset = (640+896)*1024 } }; #define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) @@ -106,39 +107,19 @@ } -static __u8 elan_104nc_read8(struct map_info *map, unsigned long ofs) +static map_word elan_104nc_read16(struct map_info *map, unsigned long ofs) { - __u8 ret; + map_word ret; spin_lock(&elan_104nc_spin); elan_104nc_page(map, ofs); - ret = readb(iomapadr + (ofs & WINDOW_MASK)); - spin_unlock(&elan_104nc_spin); - return ret; -} - -static __u16 elan_104nc_read16(struct map_info *map, unsigned long ofs) -{ - __u16 ret; - spin_lock(&elan_104nc_spin); - elan_104nc_page(map, ofs); - ret = readw(iomapadr + (ofs & WINDOW_MASK)); - spin_unlock(&elan_104nc_spin); - return ret; -} - -static __u32 elan_104nc_read32(struct map_info *map, unsigned long ofs) -{ - __u32 ret; - spin_lock(&elan_104nc_spin); - elan_104nc_page(map, ofs); - ret = readl(iomapadr + (ofs & WINDOW_MASK)); + ret.x[0] = readw(iomapadr + (ofs & WINDOW_MASK)); spin_unlock(&elan_104nc_spin); return ret; } static void elan_104nc_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) { - while(len) { + while (len) { unsigned long thislen = len; if (len > (WINDOW_LENGTH - (from & WINDOW_MASK))) thislen = WINDOW_LENGTH-(from & WINDOW_MASK); @@ -147,33 +128,17 @@ elan_104nc_page(map, from); memcpy_fromio(to, iomapadr + (from & WINDOW_MASK), thislen); spin_unlock(&elan_104nc_spin); - (__u8*)to += thislen; + to += thislen; from += thislen; len -= thislen; } } -static void elan_104nc_write8(struct map_info *map, __u8 d, unsigned long adr) +static void elan_104nc_write16(struct map_info *map, map_word d, unsigned long adr) { spin_lock(&elan_104nc_spin); elan_104nc_page(map, adr); - writeb(d, iomapadr + (adr & WINDOW_MASK)); - spin_unlock(&elan_104nc_spin); -} - -static void elan_104nc_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - spin_lock(&elan_104nc_spin); - elan_104nc_page(map, adr); - writew(d, iomapadr + (adr & WINDOW_MASK)); - spin_unlock(&elan_104nc_spin); -} - -static void elan_104nc_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - spin_lock(&elan_104nc_spin); - elan_104nc_page(map, adr); - writel(d, iomapadr + (adr & WINDOW_MASK)); + writew(d.x[0], iomapadr + (adr & WINDOW_MASK)); spin_unlock(&elan_104nc_spin); } @@ -195,19 +160,16 @@ } static struct map_info elan_104nc_map = { - name: "ELAN-104NC flash", - size: 8*1024*1024, /* this must be set to a maximum possible amount + .name = "ELAN-104NC flash", + .phys = NO_XIP, + .size = 8*1024*1024, /* this must be set to a maximum possible amount of flash so the cfi probe routines find all the chips */ - buswidth: 2, - read8: elan_104nc_read8, - read16: elan_104nc_read16, - read32: elan_104nc_read32, - copy_from: elan_104nc_copy_from, - write8: elan_104nc_write8, - write16: elan_104nc_write16, - write32: elan_104nc_write32, - copy_to: elan_104nc_copy_to + .bankwidth = 2, + .read = elan_104nc_read16, + .copy_from = elan_104nc_copy_from, + .write = elan_104nc_write16, + .copy_to = elan_104nc_copy_to }; /* MTD device for all of the flash. */ @@ -221,31 +183,20 @@ } iounmap((void *)iomapadr); - release_region(PAGE_IO,PAGE_IO_SIZE); } int __init init_elan_104nc(void) { - /* Urg! We use I/O port 0x22 without request_region()ing it */ - /* - if (check_region(PAGE_IO,PAGE_IO_SIZE) != 0) { - printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n", - elan_104nc_map.name, - PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 ); - return -EAGAIN; - } - */ - iomapadr = (unsigned long)ioremap(WINDOW_START, WINDOW_LENGTH); + /* Urg! We use I/O port 0x22 without request_region()ing it, + because it's already allocated to the PIC. */ + + iomapadr = (void __iomem *)ioremap(WINDOW_START, WINDOW_LENGTH); if (!iomapadr) { printk( KERN_ERR"%s: failed to ioremap memory region\n", elan_104nc_map.name ); return -EIO; } - /* - request_region( PAGE_IO, PAGE_IO_SIZE, "ELAN-104NC flash" ); - */ - printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n", elan_104nc_map.name, PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1, @@ -260,7 +211,7 @@ return -ENXIO; } - all_mtd->module=THIS_MODULE; + all_mtd->owner = THIS_MODULE; /* Create MTD devices for each partition. */ add_mtd_partitions( all_mtd, partition_info, NUM_PARTITIONS ); Index: drivers/mtd/maps/epxa-flash.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/epxa-flash.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/mtd/maps/epxa-flash.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/epxa-flash.c 4 Aug 2004 01:29:05 -0000 1.2 @@ -5,7 +5,7 @@ * Copyright (C) 2001 Altera Corporation * Copyright (C) 2001 Red Hat, Inc. * - * $Id: epxa-flash.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: epxa-flash.c,v 1.2 2004/08/04 01:29:05 joff Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by Index: drivers/mtd/maps/fortunet.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/fortunet.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/fortunet.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/maps/fortunet.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,11 +1,12 @@ /* fortunet.c memory map * - * $Id: fortunet.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: fortunet.c,v 1.3 2004/11/03 00:04:43 joff Exp $ */ #include #include #include +#include #include #include #include @@ -23,8 +24,8 @@ struct map_region { - int window_addr_phyical; - int altbuswidth; + int window_addr_physical; + int altbankwidth; struct map_info map_info; struct mtd_info *mymtd; struct mtd_partition parts[MAX_NUM_PARTITIONS]; @@ -37,57 +38,10 @@ static int map_regions_parts[MAX_NUM_REGIONS] = {0,0,0,0}; -__u8 fortunet_read8(struct map_info *map, unsigned long ofs) -{ - return *(__u8 *)(map->map_priv_1 + ofs); -} - -__u16 fortunet_read16(struct map_info *map, unsigned long ofs) -{ - return *(__u16 *)(map->map_priv_1 + ofs); -} - -__u32 fortunet_read32(struct map_info *map, unsigned long ofs) -{ - return *(__u32 *)(map->map_priv_1 + ofs); -} - -void fortunet_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy(to, (void *)(map->map_priv_1 + from), len); -} - -void fortunet_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - *(__u8 *)(map->map_priv_1 + adr) = d; -} - -void fortunet_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - *(__u16 *)(map->map_priv_1 + adr) = d; -} - -void fortunet_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - *(__u32 *)(map->map_priv_1 + adr) = d; -} - -void fortunet_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy((void *)(map->map_priv_1 + to), from, len); -} struct map_info default_map = { - size: DEF_WINDOW_SIZE, - buswidth: 4, - read8: fortunet_read8, - read16: fortunet_read16, - read32: fortunet_read32, - copy_from: fortunet_copy_from, - write8: fortunet_write8, - write16: fortunet_write16, - write32: fortunet_write32, - copy_to: fortunet_copy_to + .size = DEF_WINDOW_SIZE, + .bankwidth = 4, }; static char * __init get_string_option(char *dest,int dest_size,char *sor) @@ -147,8 +101,8 @@ get_options (get_string_option(string,sizeof(string),line),6,params); if(params[0]<1) { - printk(MTD_FORTUNET_PK "Bad paramters for MTD Region " - " name,region-number[,base,size,buswidth,altbuswidth]\n"); + printk(MTD_FORTUNET_PK "Bad parameters for MTD Region " + " name,region-number[,base,size,bankwidth,altbankwidth]\n"); return 1; } if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS)) @@ -161,14 +115,14 @@ memcpy(&map_regions[params[1]].map_info, &default_map,sizeof(map_regions[params[1]].map_info)); map_regions_set[params[1]] = 1; - map_regions[params[1]].window_addr_phyical = DEF_WINDOW_ADDR_PHY; - map_regions[params[1]].altbuswidth = 2; + map_regions[params[1]].window_addr_physical = DEF_WINDOW_ADDR_PHY; + map_regions[params[1]].altbankwidth = 2; map_regions[params[1]].mymtd = NULL; map_regions[params[1]].map_info.name = map_regions[params[1]].map_name; strcpy(map_regions[params[1]].map_info.name,string); if(params[0]>1) { - map_regions[params[1]].window_addr_phyical = params[2]; + map_regions[params[1]].window_addr_physical = params[2]; } if(params[0]>2) { @@ -176,23 +130,23 @@ } if(params[0]>3) { - map_regions[params[1]].map_info.buswidth = params[4]; + map_regions[params[1]].map_info.bankwidth = params[4]; } if(params[0]>4) { - map_regions[params[1]].altbuswidth = params[5]; + map_regions[params[1]].altbankwidth = params[5]; } return 1; } -static int __init MTD_New_Partion(char *line) +static int __init MTD_New_Partition(char *line) { char string[MAX_NAME_SIZE]; int params[4]; get_options (get_string_option(string,sizeof(string),line),4,params); if(params[0]<3) { - printk(MTD_FORTUNET_PK "Bad paramters for MTD Partion " + printk(MTD_FORTUNET_PK "Bad parameters for MTD Partition " " name,region-number,size,offset\n"); return 1; } @@ -204,7 +158,7 @@ } if(map_regions_parts[params[1]]>=MAX_NUM_PARTITIONS) { - printk(MTD_FORTUNET_PK "Out of space for partion in this region\n"); + printk(MTD_FORTUNET_PK "Out of space for partition in this region\n"); return 1; } map_regions[params[1]].parts[map_regions_parts[params[1]]].name = @@ -220,7 +174,10 @@ } __setup("MTD_Region=", MTD_New_Region); -__setup("MTD_Partion=", MTD_New_Partion); +__setup("MTD_Partition=", MTD_New_Partition); + +/* Backwards-spelling-compatibility */ +__setup("MTD_Partion=", MTD_New_Partition); int __init init_fortunet(void) { @@ -229,14 +186,14 @@ { if(map_regions_parts[ix]&&(!map_regions_set[ix])) { - printk(MTD_FORTUNET_PK "Region %d is not setup (Seting to default)\n", + printk(MTD_FORTUNET_PK "Region %d is not setup (Setting to default)\n", ix); memset(&map_regions[ix],0,sizeof(map_regions[ix])); memcpy(&map_regions[ix].map_info,&default_map, sizeof(map_regions[ix].map_info)); map_regions_set[ix] = 1; - map_regions[ix].window_addr_phyical = DEF_WINDOW_ADDR_PHY; - map_regions[ix].altbuswidth = 2; + map_regions[ix].window_addr_physical = DEF_WINDOW_ADDR_PHY; + map_regions[ix].altbankwidth = 2; map_regions[ix].mymtd = NULL; map_regions[ix].map_info.name = map_regions[ix].map_name; strcpy(map_regions[ix].map_info.name,"FORTUNET"); @@ -244,38 +201,43 @@ if(map_regions_set[ix]) { iy++; - printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash device at phyicaly " + printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash device at physically " " address %x size %x\n", map_regions[ix].map_info.name, - map_regions[ix].window_addr_phyical, + map_regions[ix].window_addr_physical, map_regions[ix].map_info.size); - map_regions[ix].map_info.map_priv_1 = - (int)ioremap_nocache( - map_regions[ix].window_addr_phyical, + + map_regions[ix].map_info.phys = map_regions[ix].window_addr_physical, + + map_regions[ix].map_info.virt = + (void __iomem *)ioremap_nocache( + map_regions[ix].window_addr_physical, map_regions[ix].map_info.size); - if(!map_regions[ix].map_info.map_priv_1) + if(!map_regions[ix].map_info.virt) { printk(MTD_FORTUNET_PK "%s flash failed to ioremap!\n", map_regions[ix].map_info.name); return -ENXIO; } - printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash is veritualy at: %x\n", + simple_map_init(&map_regions[ix].map_info); + + printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash is virtually at: %x\n", map_regions[ix].map_info.name, - map_regions[ix].map_info.map_priv_1); + map_regions[ix].map_info.virt); map_regions[ix].mymtd = do_map_probe("cfi_probe", &map_regions[ix].map_info); if((!map_regions[ix].mymtd)&&( - map_regions[ix].altbuswidth!=map_regions[ix].map_info.buswidth)) + map_regions[ix].altbankwidth!=map_regions[ix].map_info.bankwidth)) { - printk(KERN_NOTICE MTD_FORTUNET_PK "Trying alternet buswidth " + printk(KERN_NOTICE MTD_FORTUNET_PK "Trying alternate bankwidth " "for %s flash.\n", map_regions[ix].map_info.name); - map_regions[ix].map_info.buswidth = - map_regions[ix].altbuswidth; + map_regions[ix].map_info.bankwidth = + map_regions[ix].altbankwidth; map_regions[ix].mymtd = do_map_probe("cfi_probe", &map_regions[ix].map_info); } - map_regions[ix].mymtd->module = THIS_MODULE; + map_regions[ix].mymtd->owner = THIS_MODULE; add_mtd_partitions(map_regions[ix].mymtd, map_regions[ix].parts,map_regions_parts[ix]); } @@ -297,7 +259,7 @@ del_mtd_partitions( map_regions[ix].mymtd ); map_destroy( map_regions[ix].mymtd ); } - iounmap((void *)map_regions[ix].map_info.map_priv_1); + iounmap((void *)map_regions[ix].map_info.virt); } } } Index: drivers/mtd/maps/ich2rom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/ich2rom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/mtd/maps/ich2rom.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/maps/ich2rom.c 4 Aug 2004 01:29:05 -0000 1.2 @@ -2,7 +2,7 @@ * ich2rom.c * * Normal mappings of chips in physical memory - * $Id: ich2rom.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: ich2rom.c,v 1.2 2004/08/04 01:29:05 joff Exp $ */ #include Index: drivers/mtd/maps/impa7.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/impa7.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/impa7.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/maps/impa7.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,5 +1,5 @@ /* - * $Id: impa7.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: impa7.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * * Handle mapping of the NOR flash on implementa A7 boards * @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -29,83 +30,25 @@ #define NUM_FLASHBANKS 2 #define BUSWIDTH 4 -/* can be { "cfi_probe", "jedec_probe", "map_rom", 0 }; */ -#define PROBETYPES { "jedec_probe", 0 } +/* can be { "cfi_probe", "jedec_probe", "map_rom", NULL } */ +#define PROBETYPES { "jedec_probe", NULL } #define MSG_PREFIX "impA7:" /* prefix for our printk()'s */ #define MTDID "impa7-%d" /* for mtdparts= partitioning */ -static struct mtd_info *impa7_mtd[NUM_FLASHBANKS] = { 0 }; +static struct mtd_info *impa7_mtd[NUM_FLASHBANKS]; -__u8 impa7_read8(struct map_info *map, unsigned long ofs) -{ - return __raw_readb(map->map_priv_1 + ofs); -} - -__u16 impa7_read16(struct map_info *map, unsigned long ofs) -{ - return __raw_readw(map->map_priv_1 + ofs); -} - -__u32 impa7_read32(struct map_info *map, unsigned long ofs) -{ - return __raw_readl(map->map_priv_1 + ofs); -} - -void impa7_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy_fromio(to, map->map_priv_1 + from, len); -} - -void impa7_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - __raw_writeb(d, map->map_priv_1 + adr); - mb(); -} - -void impa7_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - __raw_writew(d, map->map_priv_1 + adr); - mb(); -} - -void impa7_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - __raw_writel(d, map->map_priv_1 + adr); - mb(); -} - -void impa7_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy_toio(map->map_priv_1 + to, from, len); -} static struct map_info impa7_map[NUM_FLASHBANKS] = { { - name: "impA7 NOR Flash Bank #0", - size: WINDOW_SIZE0, - buswidth: BUSWIDTH, - read8: impa7_read8, - read16: impa7_read16, - read32: impa7_read32, - copy_from: impa7_copy_from, - write8: impa7_write8, - write16: impa7_write16, - write32: impa7_write32, - copy_to: impa7_copy_to + .name = "impA7 NOR Flash Bank #0", + .size = WINDOW_SIZE0, + .bankwidth = BUSWIDTH, }, { - name: "impA7 NOR Flash Bank #1", - size: WINDOW_SIZE1, - buswidth: BUSWIDTH, - read8: impa7_read8, - read16: impa7_read16, - read32: impa7_read32, - copy_from: impa7_copy_from, - write8: impa7_write8, - write16: impa7_write16, - write32: impa7_write32, - copy_to: impa7_copy_to + .name = "impA7 NOR Flash Bank #1", + .size = WINDOW_SIZE1, + .bankwidth = BUSWIDTH, }, }; @@ -116,25 +59,19 @@ */ static struct mtd_partition static_partitions[] = { - { - name: "FileSystem", - size: 0x800000, - offset: 0x00000000 - }, + { + .name = "FileSystem", + .size = 0x800000, + .offset = 0x00000000 + }, }; -#define NB_OF(x) (sizeof (x) / sizeof (x[0])) +static int mtd_parts_nb[NUM_FLASHBANKS]; +static struct mtd_partition *mtd_parts[NUM_FLASHBANKS]; -#ifdef CONFIG_MTD_CMDLINE_PARTS -int parse_cmdline_partitions(struct mtd_info *master, - struct mtd_partition **pparts, - const char *mtd_id); #endif -#endif - -static int mtd_parts_nb = 0; -static struct mtd_partition *mtd_parts = 0; +static const char *probes[] = { "cmdlinepart", NULL }; int __init init_impa7(void) { @@ -146,20 +83,21 @@ { WINDOW_ADDR0, WINDOW_SIZE0 }, { WINDOW_ADDR1, WINDOW_SIZE1 }, }; - char mtdid[10]; int devicesfound = 0; for(i=0; imodule = THIS_MODULE; - add_mtd_device(impa7_mtd[i]); + if (impa7_mtd[i]) { + impa7_mtd[i]->owner = THIS_MODULE; devicesfound++; #ifdef CONFIG_MTD_PARTITIONS -#ifdef CONFIG_MTD_CMDLINE_PARTS - sprintf(mtdid, MTDID, i); - mtd_parts_nb = parse_cmdline_partitions(impa7_mtd[i], - &mtd_parts, - mtdid); - if (mtd_parts_nb > 0) - part_type = "command line"; -#endif - if (mtd_parts_nb <= 0) - { - mtd_parts = static_partitions; - mtd_parts_nb = NB_OF(static_partitions); + mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i], + probes, + &mtd_parts[i], + 0); + if (mtd_parts_nb[i] > 0) { + part_type = "command line"; + } else { + mtd_parts[i] = static_partitions; + mtd_parts_nb[i] = ARRAY_SIZE(static_partitions); part_type = "static"; } - if (mtd_parts_nb <= 0) - { - printk(KERN_NOTICE MSG_PREFIX - "no partition info available\n"); - } - else - { - printk(KERN_NOTICE MSG_PREFIX - "using %s partition definition\n", - part_type); - add_mtd_partitions(impa7_mtd[i], - mtd_parts, mtd_parts_nb); - } + + printk(KERN_NOTICE MSG_PREFIX + "using %s partition definition\n", + part_type); + add_mtd_partitions(impa7_mtd[i], + mtd_parts[i], mtd_parts_nb[i]); +#else + add_mtd_device(impa7_mtd[i]); + #endif } else - iounmap((void *)impa7_map[i].map_priv_1); + iounmap((void *)impa7_map[i].virt); } return devicesfound == 0 ? -ENXIO : 0; } @@ -211,17 +140,16 @@ static void __exit cleanup_impa7(void) { int i; - for (i=0; i #include #include +#include #include #include #include #include +#include #include #include #include -extern int parse_afs_partitions(struct mtd_info *, struct mtd_partition **); - -// board specific stuff - sorry, it should be in arch/arm/mach-*. -#ifdef CONFIG_ARCH_INTEGRATOR - -#define FLASH_BASE INTEGRATOR_FLASH_BASE -#define FLASH_SIZE INTEGRATOR_FLASH_SIZE - -#define FLASH_PART_SIZE 0x400000 - -#define SC_CTRLC (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET) -#define SC_CTRLS (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET) -#define EBI_CSR1 (IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_CSR1_OFFSET) -#define EBI_LOCK (IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_LOCK_OFFSET) - -/* - * Initialise the flash access systems: - * - Disable VPP - * - Assert WP - * - Set write enable bit in EBI reg - */ -static void armflash_flash_init(void) -{ - unsigned int tmp; - - __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC); - - tmp = __raw_readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE; - __raw_writel(tmp, EBI_CSR1); - - if (!(__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) { - __raw_writel(0xa05f, EBI_LOCK); - __raw_writel(tmp, EBI_CSR1); - __raw_writel(0, EBI_LOCK); - } -} - -/* - * Shutdown the flash access systems: - * - Disable VPP - * - Assert WP - * - Clear write enable bit in EBI reg - */ -static void armflash_flash_exit(void) -{ - unsigned int tmp; - - __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC); - - /* - * Clear the write enable bit in system controller EBI register. - */ - tmp = __raw_readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE; - __raw_writel(tmp, EBI_CSR1); - - if (__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) { - __raw_writel(0xa05f, EBI_LOCK); - __raw_writel(tmp, EBI_CSR1); - __raw_writel(0, EBI_LOCK); - } -} - -static void armflash_flash_wp(int on) -{ - unsigned int reg; - - if (on) - reg = SC_CTRLC; - else - reg = SC_CTRLS; - - __raw_writel(INTEGRATOR_SC_CTRL_nFLWP, reg); -} - -static void armflash_set_vpp(struct map_info *map, int on) -{ - unsigned int reg; - - if (on) - reg = SC_CTRLS; - else - reg = SC_CTRLC; - - __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg); -} -#endif - #ifdef CONFIG_ARCH_P720T - #define FLASH_BASE (0x04000000) #define FLASH_SIZE (64*1024*1024) - -#define FLASH_PART_SIZE (4*1024*1024) -#define FLASH_BLOCK_SIZE (128*1024) - -static void armflash_flash_init(void) -{ -} - -static void armflash_flash_exit(void) -{ -} - -static void armflash_flash_wp(int on) -{ -} - -static void armflash_set_vpp(struct map_info *map, int on) -{ -} #endif -static __u8 armflash_read8(struct map_info *map, unsigned long ofs) -{ - return readb(ofs + map->map_priv_2); -} - -static __u16 armflash_read16(struct map_info *map, unsigned long ofs) -{ - return readw(ofs + map->map_priv_2); -} - -static __u32 armflash_read32(struct map_info *map, unsigned long ofs) -{ - return readl(ofs + map->map_priv_2); -} +struct armflash_info { + struct flash_platform_data *plat; + struct resource *res; + struct mtd_partition *parts; + struct mtd_info *mtd; + struct map_info map; +}; -static void armflash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +static void armflash_set_vpp(struct map_info *map, int on) { - memcpy(to, (void *) (from + map->map_priv_2), len); -} + struct armflash_info *info = container_of(map, struct armflash_info, map); -static void armflash_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - writeb(d, adr + map->map_priv_2); + if (info->plat && info->plat->set_vpp) + info->plat->set_vpp(on); } -static void armflash_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - writew(d, adr + map->map_priv_2); -} +static const char *probes[] = { "cmdlinepart", "RedBoot", "afs", NULL }; -static void armflash_write32(struct map_info *map, __u32 d, unsigned long adr) +static int armflash_probe(struct device *_dev) { - writel(d, adr + map->map_priv_2); -} + struct platform_device *dev = to_platform_device(_dev); + struct flash_platform_data *plat = dev->dev.platform_data; + struct resource *res = dev->resource; + unsigned int size = res->end - res->start + 1; + struct armflash_info *info; + int err; + void __iomem *base; -static void armflash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy((void *) (to + map->map_priv_2), from, len); -} + info = kmalloc(sizeof(struct armflash_info), GFP_KERNEL); + if (!info) { + err = -ENOMEM; + goto out; + } -static struct map_info armflash_map = -{ - name: "AFS", - read8: armflash_read8, - read16: armflash_read16, - read32: armflash_read32, - copy_from: armflash_copy_from, - write8: armflash_write8, - write16: armflash_write16, - write32: armflash_write32, - copy_to: armflash_copy_to, - set_vpp: armflash_set_vpp, -}; + memset(info, 0, sizeof(struct armflash_info)); -static struct mtd_info *mtd; -static struct mtd_partition *parts; + info->plat = plat; + if (plat && plat->init) { + err = plat->init(); + if (err) + goto no_resource; + } -static int __init armflash_cfi_init(void *base, u_int size) -{ - int ret; + info->res = request_mem_region(res->start, size, "armflash"); + if (!info->res) { + err = -EBUSY; + goto no_resource; + } - armflash_flash_init(); - armflash_flash_wp(1); + base = ioremap(res->start, size); + if (!base) { + err = -ENOMEM; + goto no_mem; + } /* * look for CFI based flash parts fitted to this board */ - armflash_map.size = size; - armflash_map.buswidth = 4; - armflash_map.map_priv_2 = (unsigned long) base; + info->map.size = size; + info->map.bankwidth = plat->width; + info->map.phys = res->start; + info->map.virt = base; + info->map.name = dev->dev.bus_id; + info->map.set_vpp = armflash_set_vpp; + + simple_map_init(&info->map); /* * Also, the CFI layer automatically works out what size * of chips we have, and does the necessary identification * for us automatically. */ - mtd = do_map_probe("cfi_probe", &armflash_map); - if (!mtd) - return -ENXIO; - - mtd->module = THIS_MODULE; - - ret = parse_afs_partitions(mtd, &parts); - if (ret > 0) { - ret = add_mtd_partitions(mtd, parts, ret); - if (ret) - printk(KERN_ERR "mtd partition registration " - "failed: %d\n", ret); + info->mtd = do_map_probe(plat->map_name, &info->map); + if (!info->mtd) { + err = -ENXIO; + goto no_device; } + info->mtd->owner = THIS_MODULE; + + err = parse_mtd_partitions(info->mtd, probes, &info->parts, 0); + if (err > 0) { + err = add_mtd_partitions(info->mtd, info->parts, err); + if (err) + printk(KERN_ERR + "mtd partition registration failed: %d\n", err); + } + + if (err == 0) + dev_set_drvdata(&dev->dev, info); + /* * If we got an error, free all resources. */ - if (ret < 0) { - del_mtd_partitions(mtd); - map_destroy(mtd); - } - - return ret; -} + if (err < 0) { + if (info->mtd) { + del_mtd_partitions(info->mtd); + map_destroy(info->mtd); + } + if (info->parts) + kfree(info->parts); -static void armflash_cfi_exit(void) -{ - if (mtd) { - del_mtd_partitions(mtd); - map_destroy(mtd); + no_device: + iounmap(base); + no_mem: + release_mem_region(res->start, size); + no_resource: + if (plat && plat->exit) + plat->exit(); + kfree(info); } - if (parts) - kfree(parts); + out: + return err; } -static int __init armflash_init(void) +static int armflash_remove(struct device *_dev) { - int err = -EBUSY; - void *base; + struct platform_device *dev = to_platform_device(_dev); + struct armflash_info *info = dev_get_drvdata(&dev->dev); - if (request_mem_region(FLASH_BASE, FLASH_SIZE, "flash") == NULL) - goto out; + dev_set_drvdata(&dev->dev, NULL); - base = ioremap(FLASH_BASE, FLASH_SIZE); - err = -ENOMEM; - if (base == NULL) - goto release; + if (info) { + if (info->mtd) { + del_mtd_partitions(info->mtd); + map_destroy(info->mtd); + } + if (info->parts) + kfree(info->parts); - err = armflash_cfi_init(base, FLASH_SIZE); - if (err) { - iounmap(base); -release: - release_mem_region(FLASH_BASE, FLASH_SIZE); + iounmap(info->map.virt); + release_resource(info->res); + kfree(info->res); + + if (info->plat && info->plat->exit) + info->plat->exit(); + + kfree(info); } -out: - return err; + + return 0; +} + +static struct device_driver armflash_driver = { + .name = "armflash", + .bus = &platform_bus_type, + .probe = armflash_probe, + .remove = armflash_remove, +}; + +static int __init armflash_init(void) +{ + return driver_register(&armflash_driver); } static void __exit armflash_exit(void) { - armflash_cfi_exit(); - iounmap((void *)armflash_map.map_priv_2); - release_mem_region(FLASH_BASE, FLASH_SIZE); - armflash_flash_exit(); + driver_unregister(&armflash_driver); } module_init(armflash_init); Index: drivers/mtd/maps/iq80310.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/iq80310.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/iq80310.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/iq80310.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,5 +1,5 @@ /* - * $Id: iq80310.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: iq80310.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * * Mapping for the Intel XScale IQ80310 evaluation board * @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include #include @@ -26,127 +28,72 @@ static struct mtd_info *mymtd; -static __u8 iq80310_read8(struct map_info *map, unsigned long ofs) -{ - return *(__u8 *)(map->map_priv_1 + ofs); -} - -static __u16 iq80310_read16(struct map_info *map, unsigned long ofs) -{ - return *(__u16 *)(map->map_priv_1 + ofs); -} - -static __u32 iq80310_read32(struct map_info *map, unsigned long ofs) -{ - return *(__u32 *)(map->map_priv_1 + ofs); -} - -static void iq80310_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy(to, (void *)(map->map_priv_1 + from), len); -} - -static void iq80310_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - *(__u8 *)(map->map_priv_1 + adr) = d; -} - -static void iq80310_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - *(__u16 *)(map->map_priv_1 + adr) = d; -} - -static void iq80310_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - *(__u32 *)(map->map_priv_1 + adr) = d; -} - -static void iq80310_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy((void *)(map->map_priv_1 + to), from, len); -} - static struct map_info iq80310_map = { - name: "IQ80310 flash", - size: WINDOW_SIZE, - buswidth: BUSWIDTH, - read8: iq80310_read8, - read16: iq80310_read16, - read32: iq80310_read32, - copy_from: iq80310_copy_from, - write8: iq80310_write8, - write16: iq80310_write16, - write32: iq80310_write32, - copy_to: iq80310_copy_to + .name = "IQ80310 flash", + .size = WINDOW_SIZE, + .bankwidth = BUSWIDTH, + .phys = WINDOW_ADDR }; static struct mtd_partition iq80310_partitions[4] = { { - name: "Firmware", - size: 0x00080000, - offset: 0, - mask_flags: MTD_WRITEABLE /* force read-only */ + .name = "Firmware", + .size = 0x00080000, + .offset = 0, + .mask_flags = MTD_WRITEABLE /* force read-only */ },{ - name: "Kernel", - size: 0x000a0000, - offset: 0x00080000, + .name = "Kernel", + .size = 0x000a0000, + .offset = 0x00080000, },{ - name: "Filesystem", - size: 0x00600000, - offset: 0x00120000 + .name = "Filesystem", + .size = 0x00600000, + .offset = 0x00120000 },{ - name: "RedBoot", - size: 0x000e0000, - offset: 0x00720000, - mask_flags: MTD_WRITEABLE + .name = "RedBoot", + .size = 0x000e0000, + .offset = 0x00720000, + .mask_flags = MTD_WRITEABLE } }; -#define NB_OF(x) (sizeof(x)/sizeof(x[0])) - static struct mtd_info *mymtd; static struct mtd_partition *parsed_parts; - -extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts); +static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; static int __init init_iq80310(void) { struct mtd_partition *parts; int nb_parts = 0; int parsed_nr_parts = 0; - char *part_type = "static"; + int ret; - iq80310_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE); - if (!iq80310_map.map_priv_1) { + iq80310_map.virt = (void __iomem *)ioremap(WINDOW_ADDR, WINDOW_SIZE); + if (!iq80310_map.virt) { printk("Failed to ioremap\n"); return -EIO; } + simple_map_init(&iq80310_map); + mymtd = do_map_probe("cfi_probe", &iq80310_map); if (!mymtd) { - iounmap((void *)iq80310_map.map_priv_1); + iounmap((void *)iq80310_map.virt); return -ENXIO; } - mymtd->module = THIS_MODULE; + mymtd->owner = THIS_MODULE; -#ifdef CONFIG_MTD_REDBOOT_PARTS - if (parsed_nr_parts == 0) { - int ret = parse_redboot_partitions(mymtd, &parsed_parts); - - if (ret > 0) { - part_type = "RedBoot"; - parsed_nr_parts = ret; - } - } -#endif + ret = parse_mtd_partitions(mymtd, probes, &parsed_parts, 0); + + if (ret > 0) + parsed_nr_parts = ret; if (parsed_nr_parts > 0) { parts = parsed_parts; nb_parts = parsed_nr_parts; } else { parts = iq80310_partitions; - nb_parts = NB_OF(iq80310_partitions); + nb_parts = ARRAY_SIZE(iq80310_partitions); } - printk(KERN_NOTICE "Using %s partition definition\n", part_type); add_mtd_partitions(mymtd, parts, nb_parts); return 0; } @@ -159,8 +106,8 @@ if (parsed_parts) kfree(parsed_parts); } - if (iq80310_map.map_priv_1) - iounmap((void *)iq80310_map.map_priv_1); + if (iq80310_map.virt) + iounmap((void *)iq80310_map.virt); } module_init(init_iq80310); Index: drivers/mtd/maps/l440gx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/l440gx.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/l440gx.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/l440gx.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,5 +1,5 @@ /* - * $Id: l440gx.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: l440gx.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * * BIOS Flash chip on Intel 440GX board. * @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -27,48 +28,6 @@ static struct mtd_info *mymtd; -__u8 l440gx_read8(struct map_info *map, unsigned long ofs) -{ - return __raw_readb(map->map_priv_1 + ofs); -} - -__u16 l440gx_read16(struct map_info *map, unsigned long ofs) -{ - return __raw_readw(map->map_priv_1 + ofs); -} - -__u32 l440gx_read32(struct map_info *map, unsigned long ofs) -{ - return __raw_readl(map->map_priv_1 + ofs); -} - -void l440gx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy_fromio(to, map->map_priv_1 + from, len); -} - -void l440gx_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - __raw_writeb(d, map->map_priv_1 + adr); - mb(); -} - -void l440gx_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - __raw_writew(d, map->map_priv_1 + adr); - mb(); -} - -void l440gx_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - __raw_writel(d, map->map_priv_1 + adr); - mb(); -} - -void l440gx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy_toio(map->map_priv_1 + to, from, len); -} /* Is this really the vpp port? */ void l440gx_set_vpp(struct map_info *map, int vpp) @@ -85,22 +44,15 @@ } struct map_info l440gx_map = { - name: "L440GX BIOS", - size: WINDOW_SIZE, - buswidth: BUSWIDTH, - read8: l440gx_read8, - read16: l440gx_read16, - read32: l440gx_read32, - copy_from: l440gx_copy_from, - write8: l440gx_write8, - write16: l440gx_write16, - write32: l440gx_write32, - copy_to: l440gx_copy_to, + .name = "L440GX BIOS", + .size = WINDOW_SIZE, + .bankwidth = BUSWIDTH, + .phys = WINDOW_ADDR, #if 0 /* FIXME verify that this is the * appripriate code for vpp enable/disable */ - set_vpp: l440gx_set_vpp + .set_vpp = l440gx_set_vpp #endif }; @@ -113,7 +65,6 @@ dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, NULL); - pm_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL); @@ -122,15 +73,14 @@ return -ENODEV; } + l440gx_map.virt = (void __iomem *)ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE); - l440gx_map.map_priv_1 = (unsigned long)ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE); - - if (!l440gx_map.map_priv_1) { + if (!l440gx_map.virt) { printk(KERN_WARNING "Failed to ioremap L440GX flash region\n"); return -ENOMEM; } - - printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.map_priv_1); + simple_map_init(&l440gx_map); + printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.virt); /* Setup the pm iobase resource * This code should move into some kind of generic bridge @@ -153,7 +103,7 @@ /* Allocate the resource region */ if (pci_assign_resource(pm_dev, PIIXE_IOBASE_RESOURCE) != 0) { printk(KERN_WARNING "Could not allocate pm iobase resource\n"); - iounmap((void *)l440gx_map.map_priv_1); + iounmap((void *)l440gx_map.virt); return -ENXIO; } } @@ -181,13 +131,13 @@ mymtd = do_map_probe("map_rom", &l440gx_map); } if (mymtd) { - mymtd->module = THIS_MODULE; + mymtd->owner = THIS_MODULE; add_mtd_device(mymtd); return 0; } - iounmap((void *)l440gx_map.map_priv_1); + iounmap((void *)l440gx_map.virt); return -ENXIO; } @@ -196,7 +146,7 @@ del_mtd_device(mymtd); map_destroy(mymtd); - iounmap((void *)l440gx_map.map_priv_1); + iounmap((void *)l440gx_map.virt); } module_init(init_l440gx); Index: drivers/mtd/maps/lasat.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/lasat.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/lasat.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/lasat.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,111 +1,73 @@ /* - * Flash device on lasat 100 and 200 boards + * Flash device on Lasat 100 and 200 boards * - * Presumably (C) 2002 Brian Murphy or whoever he - * works for. + * (C) 2002 Brian Murphy * * 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. * - * $Id: lasat.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: lasat.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * */ #include #include #include +#include #include #include #include #include #include #include -#include -static struct mtd_info *mymtd; +static struct mtd_info *lasat_mtd; -static __u8 sp_read8(struct map_info *map, unsigned long ofs) -{ - return __raw_readb(map->map_priv_1 + ofs); -} - -static __u16 sp_read16(struct map_info *map, unsigned long ofs) -{ - return __raw_readw(map->map_priv_1 + ofs); -} - -static __u32 sp_read32(struct map_info *map, unsigned long ofs) -{ - return __raw_readl(map->map_priv_1 + ofs); -} - -static void sp_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy_fromio(to, map->map_priv_1 + from, len); -} - -static void sp_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - __raw_writeb(d, map->map_priv_1 + adr); - mb(); -} - -static void sp_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - __raw_writew(d, map->map_priv_1 + adr); - mb(); -} - -static void sp_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - __raw_writel(d, map->map_priv_1 + adr); - mb(); -} +static struct mtd_partition partition_info[LASAT_MTD_LAST]; +static char *lasat_mtd_partnames[] = {"Bootloader", "Service", "Normal", "Filesystem", "Config"}; -static void sp_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +static void lasat_set_vpp(struct map_info *map, int vpp) { - memcpy_toio(map->map_priv_1 + to, from, len); + if (vpp) + *lasat_misc->flash_wp_reg |= 1 << lasat_misc->flash_wp_bit; + else + *lasat_misc->flash_wp_reg &= ~(1 << lasat_misc->flash_wp_bit); } -static struct map_info sp_map = { - .name = "SP flash", - .buswidth = 4, - .read8 = sp_read8, - .read16 = sp_read16, - .read32 = sp_read32, - .copy_from = sp_copy_from, - .write8 = sp_write8, - .write16 = sp_write16, - .write32 = sp_write32, - .copy_to = sp_copy_to +static struct map_info lasat_map = { + .name = "LASAT flash", + .bankwidth = 4, + .set_vpp = lasat_set_vpp }; -static struct mtd_partition partition_info[LASAT_MTD_LAST]; -static char *lasat_mtd_partnames[] = {"Bootloader", "Service", "Normal", "Filesystem", "Config"}; - -static int __init init_sp(void) +static int __init init_lasat(void) { int i; - /* this does not play well with the old flash code which - * protects and uprotects the flash when necessary */ - printk(KERN_NOTICE "Unprotecting flash\n"); - *lasat_misc->flash_wp_reg |= 1 << lasat_misc->flash_wp_bit; + /* since we use AMD chips and set_vpp is not implimented + * for these (yet) we still have to permanently enable flash write */ + printk(KERN_NOTICE "Unprotecting flash\n"); + ENABLE_VPP((&lasat_map)); + + lasat_map.phys = lasat_flash_partition_start(LASAT_MTD_BOOTLOADER); + lasat_map.virt = (void __iomem *)ioremap_nocache( + lasat_map.phys, lasat_board_info.li_flash_size); + lasat_map.size = lasat_board_info.li_flash_size; - sp_map.map_priv_1 = lasat_flash_partition_start(LASAT_MTD_BOOTLOADER); - sp_map.size = lasat_board_info.li_flash_size; - - printk(KERN_NOTICE "sp flash device: %lx at %lx\n", - sp_map.size, sp_map.map_priv_1); + simple_map_init(&lasat_map); for (i=0; i < LASAT_MTD_LAST; i++) partition_info[i].name = lasat_mtd_partnames[i]; - mymtd = do_map_probe("cfi_probe", &sp_map); - if (mymtd) { + lasat_mtd = do_map_probe("cfi_probe", &lasat_map); + + if (!lasat_mtd) + lasat_mtd = do_map_probe("jedec_probe", &lasat_map); + + if (lasat_mtd) { u32 size, offset = 0; - mymtd->module = THIS_MODULE; + lasat_mtd->owner = THIS_MODULE; for (i=0; i < LASAT_MTD_LAST; i++) { size = lasat_flash_partition_size(i); @@ -114,26 +76,26 @@ offset += size; } - add_mtd_partitions( mymtd, partition_info, LASAT_MTD_LAST ); + add_mtd_partitions( lasat_mtd, partition_info, LASAT_MTD_LAST ); return 0; } return -ENXIO; } -static void __exit cleanup_sp(void) +static void __exit cleanup_lasat(void) { - if (mymtd) { - del_mtd_partitions(mymtd); - map_destroy(mymtd); + if (lasat_mtd) { + del_mtd_partitions(lasat_mtd); + map_destroy(lasat_mtd); } - if (sp_map.map_priv_1) { - sp_map.map_priv_1 = 0; + if (lasat_map.virt) { + lasat_map.virt = 0; } } -module_init(init_sp); -module_exit(cleanup_sp); +module_init(init_lasat); +module_exit(cleanup_lasat); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Brian Murphy "); Index: drivers/mtd/maps/mbx860.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/mbx860.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/mbx860.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/mbx860.c 3 Nov 2004 00:04:43 -0000 1.3 @@ -1,5 +1,5 @@ /* - * $Id: mbx860.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: mbx860.c,v 1.3 2004/11/03 00:04:43 joff Exp $ * * Handle mapping of the flash on MBX860 boards * @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -36,91 +37,46 @@ * single flash device into. If the size if zero we use up to the end of the * device. */ static struct mtd_partition partition_info[]={ - { name: "MBX flash BOOT partition", - offset: 0, - size: BOOT_PARTITION_SIZE_KiB*1024 }, - { name: "MBX flash DATA partition", - offset: BOOT_PARTITION_SIZE_KiB*1024, - size: (KERNEL_PARTITION_SIZE_KiB)*1024 }, - { name: "MBX flash APPLICATION partition", - offset: (BOOT_PARTITION_SIZE_KiB+KERNEL_PARTITION_SIZE_KiB)*1024 } + { .name = "MBX flash BOOT partition", + .offset = 0, + .size = BOOT_PARTITION_SIZE_KiB*1024 }, + { .name = "MBX flash DATA partition", + .offset = BOOT_PARTITION_SIZE_KiB*1024, + .size = (KERNEL_PARTITION_SIZE_KiB)*1024 }, + { .name = "MBX flash APPLICATION partition", + .offset = (BOOT_PARTITION_SIZE_KiB+KERNEL_PARTITION_SIZE_KiB)*1024 } }; static struct mtd_info *mymtd; -__u8 mbx_read8(struct map_info *map, unsigned long ofs) -{ - return readb(map->map_priv_1 + ofs); -} - -__u16 mbx_read16(struct map_info *map, unsigned long ofs) -{ - return readw(map->map_priv_1 + ofs); -} - -__u32 mbx_read32(struct map_info *map, unsigned long ofs) -{ - return readl(map->map_priv_1 + ofs); -} - -void mbx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy_fromio(to, (void *)(map->map_priv_1 + from), len); -} - -void mbx_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - writeb(d, map->map_priv_1 + adr); -} - -void mbx_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - writew(d, map->map_priv_1 + adr); -} - -void mbx_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - writel(d, map->map_priv_1 + adr); -} - -void mbx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy_toio((void *)(map->map_priv_1 + to), from, len); -} - struct map_info mbx_map = { - name: "MBX flash", - size: WINDOW_SIZE, - buswidth: 4, - read8: mbx_read8, - read16: mbx_read16, - read32: mbx_read32, - copy_from: mbx_copy_from, - write8: mbx_write8, - write16: mbx_write16, - write32: mbx_write32, - copy_to: mbx_copy_to + .name = "MBX flash", + .size = WINDOW_SIZE, + .phys = WINDOW_ADDR, + .bankwidth = 4, }; int __init init_mbx(void) { - printk(KERN_NOTICE "Motorola MBX flash device: %x at %x\n", WINDOW_SIZE*4, WINDOW_ADDR); - mbx_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE * 4); + printk(KERN_NOTICE "Motorola MBX flash device: 0x%x at 0x%x\n", WINDOW_SIZE*4, WINDOW_ADDR); + mbx_map.virt = (void __iomem *)ioremap(WINDOW_ADDR, WINDOW_SIZE * 4); - if (!mbx_map.map_priv_1) { + if (!mbx_map.virt) { printk("Failed to ioremap\n"); return -EIO; } + simple_map_init(&mbx_map); + mymtd = do_map_probe("jedec_probe", &mbx_map); if (mymtd) { - mymtd->module = THIS_MODULE; + mymtd->owner = THIS_MODULE; add_mtd_device(mymtd); add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS); return 0; } - iounmap((void *)mbx_map.map_priv_1); + iounmap((void *)mbx_map.virt); return -ENXIO; } @@ -130,9 +86,9 @@ del_mtd_device(mymtd); map_destroy(mymtd); } - if (mbx_map.map_priv_1) { - iounmap((void *)mbx_map.map_priv_1); - mbx_map.map_priv_1 = 0; + if (mbx_map.virt) { + iounmap((void *)mbx_map.virt); + mbx_map.virt = 0; } } Index: drivers/mtd/maps/neponset-flash.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/neponset-flash.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/mtd/maps/neponset-flash.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/neponset-flash.c 4 Aug 2004 01:29:06 -0000 1.2 @@ -3,7 +3,7 @@ * * (C) 2000 Nicolas Pitre * - * $Id: neponset-flash.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: neponset-flash.c,v 1.2 2004/08/04 01:29:06 joff Exp $ */ #include Index: drivers/mtd/maps/netsc520.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/netsc520.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/netsc520.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/maps/netsc520.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -3,7 +3,7 @@ * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com) * based on sc520cdp.c by Sysgo Real-Time Solutions GmbH * - * $Id: netsc520.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: netsc520.c,v 1.3 2004/11/03 00:04:44 joff Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -50,95 +51,41 @@ ** recoverable afterwards. */ -static __u8 netsc520_read8(struct map_info *map, unsigned long ofs) -{ - return readb(map->map_priv_1 + ofs); -} - -static __u16 netsc520_read16(struct map_info *map, unsigned long ofs) -{ - return readw(map->map_priv_1 + ofs); -} - -static __u32 netsc520_read32(struct map_info *map, unsigned long ofs) -{ - return readl(map->map_priv_1 + ofs); -} - -static void netsc520_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy_fromio(to, (void *)(map->map_priv_1 + from), len); -} - -static void netsc520_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - writeb(d, map->map_priv_1 + adr); -} - -static void netsc520_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - writew(d, map->map_priv_1 + adr); -} - -static void netsc520_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - writel(d, map->map_priv_1 + adr); -} - -static void netsc520_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy_toio((void *)(map->map_priv_1 + to), from, len); -} - /* partition_info gives details on the logical partitions that the split the * single flash device into. If the size if zero we use up to the end of the * device. */ static struct mtd_partition partition_info[]={ { - name: "NetSc520 boot kernel", - offset: 0, - size: 0xc0000 + .name = "NetSc520 boot kernel", + .offset = 0, + .size = 0xc0000 }, { - name: "NetSc520 Low BIOS", - offset: 0xc0000, - size: 0x40000 + .name = "NetSc520 Low BIOS", + .offset = 0xc0000, + .size = 0x40000 }, { - name: "NetSc520 file system", - offset: 0x100000, - size: 0xe80000 + .name = "NetSc520 file system", + .offset = 0x100000, + .size = 0xe80000 }, { - name: "NetSc520 High BIOS", - offset: 0xf80000, - size: 0x80000 + .name = "NetSc520 High BIOS", + .offset = 0xf80000, + .size = 0x80000 }, }; #define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) -/* - * If no idea what is going on here. This is taken from the FlashFX stuff. - */ -#define ROMCS 1 - - #define WINDOW_SIZE 0x00100000 #define WINDOW_ADDR 0x00200000 static struct map_info netsc520_map = { - name: "netsc520 Flash Bank", - size: WINDOW_SIZE, - buswidth: 4, - read8: netsc520_read8, - read16: netsc520_read16, - read32: netsc520_read32, - copy_from: netsc520_copy_from, - write8: netsc520_write8, - write16: netsc520_write16, - write32: netsc520_write32, - copy_to: netsc520_copy_to, - map_priv_2: WINDOW_ADDR + .name = "netsc520 Flash Bank", + .size = WINDOW_SIZE, + .bankwidth = 4, + .phys = WINDOW_ADDR, }; #define NUM_FLASH_BANKS (sizeof(netsc520_map)/sizeof(struct map_info)) @@ -147,13 +94,16 @@ static int __init init_netsc520(void) { - printk(KERN_NOTICE "NetSc520 flash device: %lx at %lx\n", netsc520_map.size, netsc520_map.map_priv_2); - netsc520_map.map_priv_1 = (unsigned long)ioremap_nocache(netsc520_map.map_priv_2, netsc520_map.size); + printk(KERN_NOTICE "NetSc520 flash device: 0x%lx at 0x%lx\n", netsc520_map.size, netsc520_map.phys); + netsc520_map.virt = (void __iomem *)ioremap_nocache(netsc520_map.phys, netsc520_map.size); - if (!netsc520_map.map_priv_1) { + if (!netsc520_map.virt) { printk("Failed to ioremap_nocache\n"); return -EIO; } + + simple_map_init(&netsc520_map); + mymtd = do_map_probe("cfi_probe", &netsc520_map); if(!mymtd) mymtd = do_map_probe("map_ram", &netsc520_map); @@ -161,11 +111,11 @@ mymtd = do_map_probe("map_rom", &netsc520_map); if (!mymtd) { - iounmap((void *)netsc520_map.map_priv_1); + iounmap((void *)netsc520_map.virt); return -ENXIO; } - mymtd->module = THIS_MODULE; + mymtd->owner = THIS_MODULE; add_mtd_partitions( mymtd, partition_info, NUM_PARTITIONS ); return 0; } @@ -176,9 +126,9 @@ del_mtd_partitions(mymtd); map_destroy(mymtd); } - if (netsc520_map.map_priv_1) { - iounmap((void *)netsc520_map.map_priv_1); - netsc520_map.map_priv_1 = 0; + if (netsc520_map.virt) { + iounmap((void *)netsc520_map.virt); + netsc520_map.virt = 0; } } Index: drivers/mtd/maps/nettel.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/nettel.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/nettel.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/nettel.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -6,7 +6,7 @@ * (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com) * (C) Copyright 2001-2002, SnapGear (www.snapgear.com) * - * $Id: nettel.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: nettel.c,v 1.3 2004/11/03 00:04:44 joff Exp $ */ /****************************************************************************/ @@ -59,128 +59,72 @@ /****************************************************************************/ -static __u8 nettel_read8(struct map_info *map, unsigned long ofs) -{ - return(readb(map->map_priv_1 + ofs)); -} - -static __u16 nettel_read16(struct map_info *map, unsigned long ofs) -{ - return(readw(map->map_priv_1 + ofs)); -} - -static __u32 nettel_read32(struct map_info *map, unsigned long ofs) -{ - return(readl(map->map_priv_1 + ofs)); -} - -static void nettel_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy_fromio(to, map->map_priv_1 + from, len); -} - -static void nettel_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - writeb(d, map->map_priv_1 + adr); -} - -static void nettel_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - writew(d, map->map_priv_1 + adr); -} - -static void nettel_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - writel(d, map->map_priv_1 + adr); -} - -static void nettel_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy_toio(map->map_priv_1 + to, from, len); -} - /****************************************************************************/ #ifdef CONFIG_MTD_CFI_INTELEXT static struct map_info nettel_intel_map = { - name: "SnapGear Intel", - size: 0, - buswidth: INTEL_BUSWIDTH, - read8: nettel_read8, - read16: nettel_read16, - read32: nettel_read32, - copy_from: nettel_copy_from, - write8: nettel_write8, - write16: nettel_write16, - write32: nettel_write32, - copy_to: nettel_copy_to + .name = "SnapGear Intel", + .size = 0, + .bankwidth = INTEL_BUSWIDTH, }; static struct mtd_partition nettel_intel_partitions[] = { { - name: "SnapGear kernel", - offset: 0, - size: 0x000e0000 + .name = "SnapGear kernel", + .offset = 0, + .size = 0x000e0000 }, { - name: "SnapGear filesystem", - offset: 0x00100000, + .name = "SnapGear filesystem", + .offset = 0x00100000, }, { - name: "SnapGear config", - offset: 0x000e0000, - size: 0x00020000 + .name = "SnapGear config", + .offset = 0x000e0000, + .size = 0x00020000 }, { - name: "SnapGear Intel", - offset: 0 + .name = "SnapGear Intel", + .offset = 0 }, { - name: "SnapGear BIOS Config", - offset: 0x007e0000, - size: 0x00020000 + .name = "SnapGear BIOS Config", + .offset = 0x007e0000, + .size = 0x00020000 }, { - name: "SnapGear BIOS", - offset: 0x007e0000, - size: 0x00020000 + .name = "SnapGear BIOS", + .offset = 0x007e0000, + .size = 0x00020000 }, }; #endif static struct map_info nettel_amd_map = { - name: "SnapGear AMD", - size: AMD_WINDOW_MAXSIZE, - buswidth: AMD_BUSWIDTH, - read8: nettel_read8, - read16: nettel_read16, - read32: nettel_read32, - copy_from: nettel_copy_from, - write8: nettel_write8, - write16: nettel_write16, - write32: nettel_write32, - copy_to: nettel_copy_to + .name = "SnapGear AMD", + .size = AMD_WINDOW_MAXSIZE, + .bankwidth = AMD_BUSWIDTH, }; static struct mtd_partition nettel_amd_partitions[] = { { - name: "SnapGear BIOS config", - offset: 0x000e0000, - size: 0x00010000 + .name = "SnapGear BIOS config", + .offset = 0x000e0000, + .size = 0x00010000 }, { - name: "SnapGear BIOS", - offset: 0x000f0000, - size: 0x00010000 + .name = "SnapGear BIOS", + .offset = 0x000f0000, + .size = 0x00010000 }, { - name: "SnapGear AMD", - offset: 0 + .name = "SnapGear AMD", + .offset = 0 }, { - name: "SnapGear high BIOS", - offset: 0x001f0000, - size: 0x00010000 + .name = "SnapGear high BIOS", + .offset = 0x001f0000, + .size = 0x00010000 } }; @@ -236,7 +180,7 @@ if (mtd) { nettel_erase.mtd = mtd; nettel_erase.callback = nettel_erasecallback; - nettel_erase.callback = 0; + nettel_erase.callback = NULL; nettel_erase.addr = 0; nettel_erase.len = mtd->size; nettel_erase.priv = (u_long) &wait_q; @@ -328,18 +272,19 @@ *amdpar = SC520_PAR(SC520_PAR_BOOTCS, amdaddr, maxsize); __asm__ ("wbinvd"); - nettel_amd_map.map_priv_1 = (unsigned long) - ioremap_nocache(amdaddr, maxsize); - if (!nettel_amd_map.map_priv_1) { + nettel_amd_map.phys = amdaddr; + nettel_amd_map.virt = (void __iomem *) ioremap_nocache(amdaddr, maxsize); + if (!nettel_amd_map.virt) { printk("SNAPGEAR: failed to ioremap() BOOTCS\n"); return(-EIO); } + simple_map_init(&nettel_amd_map); if ((amd_mtd = do_map_probe("jedec_probe", &nettel_amd_map))) { printk(KERN_NOTICE "SNAPGEAR: AMD flash device size = %dK\n", amd_mtd->size>>10); - amd_mtd->module = THIS_MODULE; + amd_mtd->owner = THIS_MODULE; /* The high BIOS partition is only present for 2MB units */ num_amd_partitions = NUM_AMD_PARTITIONS; @@ -387,8 +332,8 @@ /* Destroy useless AMD MTD mapping */ amd_mtd = NULL; - iounmap((void *) nettel_amd_map.map_priv_1); - nettel_amd_map.map_priv_1 = (unsigned long) NULL; + iounmap((void *) nettel_amd_map.virt); + nettel_amd_map.virt = (unsigned long) NULL; #else /* Only AMD flash supported */ return(-ENXIO); @@ -411,16 +356,18 @@ /* Probe for the the size of the first Intel flash */ nettel_intel_map.size = maxsize; - nettel_intel_map.map_priv_1 = (unsigned long) + nettel_intel_map.phys = intel0addr; + nettel_intel_map.virt = (unsigned long) ioremap_nocache(intel0addr, maxsize); - if (!nettel_intel_map.map_priv_1) { + if (!nettel_intel_map.virt) { printk("SNAPGEAR: failed to ioremap() ROMCS1\n"); return(-EIO); } + simple_map_init(&nettel_intel_map); intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map); if (! intel_mtd) { - iounmap((void *) nettel_intel_map.map_priv_1); + iounmap((void *) nettel_intel_map.virt); return(-ENXIO); } @@ -441,19 +388,19 @@ /* Delete the old map and probe again to do both chips */ map_destroy(intel_mtd); intel_mtd = NULL; - iounmap((void *) nettel_intel_map.map_priv_1); + iounmap((void *) nettel_intel_map.virt); nettel_intel_map.size = maxsize; - nettel_intel_map.map_priv_1 = (unsigned long) + nettel_intel_map.virt = (unsigned long) ioremap_nocache(intel0addr, maxsize); - if (!nettel_intel_map.map_priv_1) { + if (!nettel_intel_map.virt) { printk("SNAPGEAR: failed to ioremap() ROMCS1/2\n"); return(-EIO); } intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map); if (! intel_mtd) { - iounmap((void *) nettel_intel_map.map_priv_1); + iounmap((void *) nettel_intel_map.virt); return(-ENXIO); } @@ -468,7 +415,7 @@ printk(KERN_NOTICE "SNAPGEAR: Intel flash device size = %dK\n", (intel_mtd->size >> 10)); - intel_mtd->module = THIS_MODULE; + intel_mtd->owner = THIS_MODULE; #ifndef CONFIG_BLK_DEV_INITRD ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 1); @@ -523,18 +470,18 @@ del_mtd_partitions(amd_mtd); map_destroy(amd_mtd); } - if (nettel_amd_map.map_priv_1) { - iounmap((void *)nettel_amd_map.map_priv_1); - nettel_amd_map.map_priv_1 = 0; + if (nettel_amd_map.virt) { + iounmap((void *)nettel_amd_map.virt); + nettel_amd_map.virt = 0; } #ifdef CONFIG_MTD_CFI_INTELEXT if (intel_mtd) { del_mtd_partitions(intel_mtd); map_destroy(intel_mtd); } - if (nettel_intel_map.map_priv_1) { - iounmap((void *)nettel_intel_map.map_priv_1); - nettel_intel_map.map_priv_1 = 0; + if (nettel_intel_map.virt) { + iounmap((void *)nettel_intel_map.virt); + nettel_intel_map.virt = 0; } #endif } Index: drivers/mtd/maps/nora.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/nora.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/mtd/maps/nora.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/nora.c 4 Aug 2004 01:29:06 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: nora.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: nora.c,v 1.2 2004/08/04 01:29:06 joff Exp $ * * This is so simple I love it. */ Index: drivers/mtd/maps/ocelot.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/ocelot.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/ocelot.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/ocelot.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -1,5 +1,5 @@ /* - * $Id: ocelot.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: ocelot.c,v 1.3 2004/11/03 00:04:44 joff Exp $ * * Flash on Momenco Ocelot */ @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -20,47 +21,23 @@ #define NVRAM_WINDOW_SIZE 0x00007FF0 #define NVRAM_BUSWIDTH 1 -extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts); - static unsigned int cacheflush = 0; static struct mtd_info *flash_mtd; static struct mtd_info *nvram_mtd; -__u8 ocelot_read8(struct map_info *map, unsigned long ofs) -{ - return __raw_readb(map->map_priv_1 + ofs); -} - -void ocelot_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - cacheflush = 1; - __raw_writeb(d, map->map_priv_1 + adr); - mb(); -} - -void ocelot_copy_from_cache(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - if (cacheflush) { - dma_cache_inv(map->map_priv_2, map->size); - cacheflush = 0; - } - memcpy_fromio(to, map->map_priv_1 + from, len); -} - -void ocelot_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +static void ocelot_ram_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { - memcpy_fromio(to, map->map_priv_1 + from, len); -} + struct map_info *map = (struct map_info *)mtd->priv; + size_t done = 0; -void ocelot_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ /* If we use memcpy, it does word-wide writes. Even though we told the GT64120A that it's an 8-bit wide region, word-wide writes don't work. We end up just writing the first byte of the four to all four bytes. So we have this loop instead */ + *retlen = len; while(len) { - __raw_writeb(*(unsigned char *) from, map->map_priv_1 + to); + __raw_writeb(*(unsigned char *) from, map->virt + to); from++; to++; len--; @@ -70,24 +47,21 @@ static struct mtd_partition *parsed_parts; struct map_info ocelot_flash_map = { - name: "Ocelot boot flash", - size: FLASH_WINDOW_SIZE, - buswidth: FLASH_BUSWIDTH, - read8: ocelot_read8, - copy_from: ocelot_copy_from_cache, - write8: ocelot_write8, + .name = "Ocelot boot flash", + .size = FLASH_WINDOW_SIZE, + .bankwidth = FLASH_BUSWIDTH, + .phys = FLASH_WINDOW_ADDR, }; struct map_info ocelot_nvram_map = { - name: "Ocelot NVRAM", - size: NVRAM_WINDOW_SIZE, - buswidth: NVRAM_BUSWIDTH, - read8: ocelot_read8, - copy_from: ocelot_copy_from, - write8: ocelot_write8, - copy_to: ocelot_copy_to + .name = "Ocelot NVRAM", + .size = NVRAM_WINDOW_SIZE, + .bankwidth = NVRAM_BUSWIDTH, + .phys = NVRAM_WINDOW_ADDR, }; +static const char *probes[] = { "RedBoot", NULL }; + static int __init init_ocelot_maps(void) { void *pld; @@ -107,12 +81,13 @@ iounmap(pld); /* Now ioremap the NVRAM space */ - ocelot_nvram_map.map_priv_1 = (unsigned long)ioremap_nocache(NVRAM_WINDOW_ADDR, NVRAM_WINDOW_SIZE); - if (!ocelot_nvram_map.map_priv_1) { + ocelot_nvram_map.virt = (void __iomem *)ioremap_nocache(NVRAM_WINDOW_ADDR, NVRAM_WINDOW_SIZE); + if (!ocelot_nvram_map.virt) { printk(KERN_NOTICE "Failed to ioremap Ocelot NVRAM space\n"); return -EIO; } - // ocelot_nvram_map.map_priv_2 = ocelot_nvram_map.map_priv_1; + + simple_map_init(&ocelot_nvram_map); /* And do the RAM probe on it to get an MTD device */ nvram_mtd = do_map_probe("map_ram", &ocelot_nvram_map); @@ -120,22 +95,21 @@ printk("NVRAM probe failed\n"); goto fail_1; } - nvram_mtd->module = THIS_MODULE; + nvram_mtd->owner = THIS_MODULE; nvram_mtd->erasesize = 16; + /* Override the write() method */ + nvram_mtd->write = ocelot_ram_write; /* Now map the flash space */ - ocelot_flash_map.map_priv_1 = (unsigned long)ioremap_nocache(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE); - if (!ocelot_flash_map.map_priv_1) { + ocelot_flash_map.virt = (void __iomem *)ioremap_nocache(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE); + if (!ocelot_flash_map.virt) { printk(KERN_NOTICE "Failed to ioremap Ocelot flash space\n"); goto fail_2; } /* Now the cached version */ - ocelot_flash_map.map_priv_2 = (unsigned long)__ioremap(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE, 0); + ocelot_flash_map.cached = (unsigned long)__ioremap(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE, 0); - if (!ocelot_flash_map.map_priv_2) { - /* Doesn't matter if it failed. Just use the uncached version */ - ocelot_flash_map.map_priv_2 = ocelot_flash_map.map_priv_1; - } + simple_map_init(&ocelot_flash_map); /* Only probe for flash if the write jumper is present */ if (brd_status & 0x40) { @@ -155,10 +129,10 @@ add_mtd_device(nvram_mtd); - flash_mtd->module = THIS_MODULE; - nr_parts = parse_redboot_partitions(flash_mtd, &parsed_parts); + flash_mtd->owner = THIS_MODULE; + nr_parts = parse_mtd_partitions(flash_mtd, probes, &parsed_parts, 0); - if (nr_parts) + if (nr_parts > 0) add_mtd_partitions(flash_mtd, parsed_parts, nr_parts); else add_mtd_device(flash_mtd); @@ -166,14 +140,13 @@ return 0; fail3: - iounmap((void *)ocelot_flash_map.map_priv_1); - if (ocelot_flash_map.map_priv_2 && - ocelot_flash_map.map_priv_2 != ocelot_flash_map.map_priv_1) - iounmap((void *)ocelot_flash_map.map_priv_2); + iounmap((void *)ocelot_flash_map.virt); + if (ocelot_flash_map.cached) + iounmap((void *)ocelot_flash_map.cached); fail_2: map_destroy(nvram_mtd); fail_1: - iounmap((void *)ocelot_nvram_map.map_priv_1); + iounmap((void *)ocelot_nvram_map.virt); return -ENXIO; } @@ -182,16 +155,16 @@ { del_mtd_device(nvram_mtd); map_destroy(nvram_mtd); - iounmap((void *)ocelot_nvram_map.map_priv_1); + iounmap((void *)ocelot_nvram_map.virt); if (parsed_parts) del_mtd_partitions(flash_mtd); else del_mtd_device(flash_mtd); map_destroy(flash_mtd); - iounmap((void *)ocelot_flash_map.map_priv_1); - if (ocelot_flash_map.map_priv_2 != ocelot_flash_map.map_priv_1) - iounmap((void *)ocelot_flash_map.map_priv_2); + iounmap((void *)ocelot_flash_map.virt); + if (ocelot_flash_map.cached) + iounmap((void *)ocelot_flash_map.cached); } module_init(init_ocelot_maps); Index: drivers/mtd/maps/octagon-5066.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/octagon-5066.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/octagon-5066.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/octagon-5066.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -1,4 +1,4 @@ -// $Id: octagon-5066.c,v 1.1 2004/07/22 19:49:45 joff Exp $ +// $Id: octagon-5066.c,v 1.3 2004/11/03 00:04:44 joff Exp $ /* ###################################################################### Octagon 5066 MTD Driver. @@ -31,6 +31,7 @@ #include #include +#include #define WINDOW_START 0xe8000 #define WINDOW_LENGTH 0x8000 @@ -61,32 +62,12 @@ } -static __u8 oct5066_read8(struct map_info *map, unsigned long ofs) +static map_word oct5066_read8(struct map_info *map, unsigned long ofs) { - __u8 ret; + map_word ret; spin_lock(&oct5066_spin); oct5066_page(map, ofs); - ret = readb(iomapadr + (ofs & WINDOW_MASK)); - spin_unlock(&oct5066_spin); - return ret; -} - -static __u16 oct5066_read16(struct map_info *map, unsigned long ofs) -{ - __u16 ret; - spin_lock(&oct5066_spin); - oct5066_page(map, ofs); - ret = readw(iomapadr + (ofs & WINDOW_MASK)); - spin_unlock(&oct5066_spin); - return ret; -} - -static __u32 oct5066_read32(struct map_info *map, unsigned long ofs) -{ - __u32 ret; - spin_lock(&oct5066_spin); - oct5066_page(map, ofs); - ret = readl(iomapadr + (ofs & WINDOW_MASK)); + ret.x[0] = readb(iomapadr + (ofs & WINDOW_MASK)); spin_unlock(&oct5066_spin); return ret; } @@ -108,27 +89,11 @@ } } -static void oct5066_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - spin_lock(&oct5066_spin); - oct5066_page(map, adr); - writeb(d, iomapadr + (adr & WINDOW_MASK)); - spin_unlock(&oct5066_spin); -} - -static void oct5066_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - spin_lock(&oct5066_spin); - oct5066_page(map, adr); - writew(d, iomapadr + (adr & WINDOW_MASK)); - spin_unlock(&oct5066_spin); -} - -static void oct5066_write32(struct map_info *map, __u32 d, unsigned long adr) +static void oct5066_write8(struct map_info *map, map_word d, unsigned long adr) { spin_lock(&oct5066_spin); oct5066_page(map, adr); - writel(d, iomapadr + (adr & WINDOW_MASK)); + writeb(d.x[0], iomapadr + (adr & WINDOW_MASK)); spin_unlock(&oct5066_spin); } @@ -151,32 +116,26 @@ static struct map_info oct5066_map[2] = { { - name: "Octagon 5066 Socket", - size: 512 * 1024, - buswidth: 1, - read8: oct5066_read8, - read16: oct5066_read16, - read32: oct5066_read32, - copy_from: oct5066_copy_from, - write8: oct5066_write8, - write16: oct5066_write16, - write32: oct5066_write32, - copy_to: oct5066_copy_to, - map_priv_1: 1<<6 + .name = "Octagon 5066 Socket", + .phys = NO_XIP, + .size = 512 * 1024, + .bankwidth = 1, + .read = oct5066_read8, + .copy_from = oct5066_copy_from, + .write = oct5066_write8, + .copy_to = oct5066_copy_to, + .map_priv_1 = 1<<6 }, { - name: "Octagon 5066 Internal Flash", - size: 2 * 1024 * 1024, - buswidth: 1, - read8: oct5066_read8, - read16: oct5066_read16, - read32: oct5066_read32, - copy_from: oct5066_copy_from, - write8: oct5066_write8, - write16: oct5066_write16, - write32: oct5066_write32, - copy_to: oct5066_copy_to, - map_priv_1: 2<<6 + .name = "Octagon 5066 Internal Flash", + .phys = NO_XIP, + .size = 2 * 1024 * 1024, + .bankwidth = 1, + .read = oct5066_read8, + .copy_from = oct5066_copy_from, + .write = oct5066_write8, + .copy_to = oct5066_copy_to, + .map_priv_1 = 2<<6 } }; @@ -262,7 +221,7 @@ if (!oct5066_mtd[i]) oct5066_mtd[i] = do_map_probe("map_rom", &oct5066_map[i]); if (oct5066_mtd[i]) { - oct5066_mtd[i]->module = THIS_MODULE; + oct5066_mtd[i]->owner = THIS_MODULE; add_mtd_device(oct5066_mtd[i]); } } Index: drivers/mtd/maps/pb1xxx-flash.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/pb1xxx-flash.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/pb1xxx-flash.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/pb1xxx-flash.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -3,12 +3,13 @@ * * (C) 2001 Pete Popov * - * $Id: pb1xxx-flash.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: pb1xxx-flash.c,v 1.3 2004/11/03 00:04:44 joff Exp $ */ #include #include #include +#include #include #include @@ -16,7 +17,6 @@ #include #include -#include #ifdef DEBUG_RW #define DBG(x...) printk(x) @@ -25,168 +25,87 @@ #endif #ifdef CONFIG_MIPS_PB1000 + #define WINDOW_ADDR 0x1F800000 #define WINDOW_SIZE 0x800000 -#endif - -__u8 physmap_read8(struct map_info *map, unsigned long ofs) -{ - __u8 ret; - ret = __raw_readb(map->map_priv_1 + ofs); - DBG("read8 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); - return ret; -} - -__u16 physmap_read16(struct map_info *map, unsigned long ofs) -{ - __u16 ret; - ret = __raw_readw(map->map_priv_1 + ofs); - DBG("read16 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); - return ret; -} - -__u32 physmap_read32(struct map_info *map, unsigned long ofs) -{ - __u32 ret; - ret = __raw_readl(map->map_priv_1 + ofs); - DBG("read32 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); - return ret; -} - -void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - DBG("physmap_copy from %x to %x\n", (unsigned)from, (unsigned)to); - memcpy_fromio(to, map->map_priv_1 + from, len); -} - -void physmap_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - DBG("write8 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); - __raw_writeb(d, map->map_priv_1 + adr); - mb(); -} - -void physmap_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - DBG("write16 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); - __raw_writew(d, map->map_priv_1 + adr); - mb(); -} - -void physmap_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - DBG("write32 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); - __raw_writel(d, map->map_priv_1 + adr); - mb(); -} -void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - DBG("physmap_copy_to %x from %x\n", (unsigned)to, (unsigned)from); - memcpy_toio(map->map_priv_1 + to, from, len); -} - - - -static struct map_info pb1xxx_map = { - name: "Pb1xxx flash", - read8: physmap_read8, - read16: physmap_read16, - read32: physmap_read32, - copy_from: physmap_copy_from, - write8: physmap_write8, - write16: physmap_write16, - write32: physmap_write32, - copy_to: physmap_copy_to, -}; - - -#ifdef CONFIG_MIPS_PB1000 - -static unsigned long flash_size = 0x00800000; -static unsigned char flash_buswidth = 4; static struct mtd_partition pb1xxx_partitions[] = { { - name: "yamon env", - size: 0x00020000, - offset: 0, - mask_flags: MTD_WRITEABLE - },{ - name: "User FS", - size: 0x003e0000, - offset: 0x20000, - },{ - name: "boot code", - size: 0x100000, - offset: 0x400000, - mask_flags: MTD_WRITEABLE - },{ - name: "raw/kernel", - size: 0x300000, - offset: 0x500000 - } + .name = "yamon env", + .size = 0x00020000, + .offset = 0, + .mask_flags = MTD_WRITEABLE}, + { + .name = "User FS", + .size = 0x003e0000, + .offset = 0x20000,}, + { + .name = "boot code", + .size = 0x100000, + .offset = 0x400000, + .mask_flags = MTD_WRITEABLE}, + { + .name = "raw/kernel", + .size = 0x300000, + .offset = 0x500000} }; #elif defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100) -static unsigned char flash_buswidth = 4; #if defined(CONFIG_MTD_PB1500_BOOT) && defined(CONFIG_MTD_PB1500_USER) -/* both 32MiB banks will be used. Combine the first 32MiB bank and the - * first 28MiB of the second bank together into a single jffs/jffs2 +/* both 32MB banks will be used. Combine the first 32MB bank and the + * first 28MB of the second bank together into a single jffs/jffs2 * partition. */ -static unsigned long flash_size = 0x04000000; #define WINDOW_ADDR 0x1C000000 #define WINDOW_SIZE 0x4000000 static struct mtd_partition pb1xxx_partitions[] = { { - name: "User FS", - size: 0x3c00000, - offset: 0x0000000 - },{ - name: "yamon", - size: 0x0100000, - offset: 0x3c00000, - mask_flags: MTD_WRITEABLE - },{ - name: "raw kernel", - size: 0x02c0000, - offset: 0x3d00000 + .name = "User FS", + .size = 0x3c00000, + .offset = 0x0000000 + },{ + .name = "yamon", + .size = 0x0100000, + .offset = 0x3c00000, + .mask_flags = MTD_WRITEABLE + },{ + .name = "raw kernel", + .size = 0x02c0000, + .offset = 0x3d00000 } }; #elif defined(CONFIG_MTD_PB1500_BOOT) && !defined(CONFIG_MTD_PB1500_USER) -static unsigned long flash_size = 0x02000000; #define WINDOW_ADDR 0x1E000000 #define WINDOW_SIZE 0x2000000 static struct mtd_partition pb1xxx_partitions[] = { { - name: "User FS", - size: 0x1c00000, - offset: 0x0000000 - },{ - name: "yamon", - size: 0x0100000, - offset: 0x1c00000, - mask_flags: MTD_WRITEABLE - },{ - name: "raw kernel", - size: 0x02c0000, - offset: 0x1d00000 + .name = "User FS", + .size = 0x1c00000, + .offset = 0x0000000 + },{ + .name = "yamon", + .size = 0x0100000, + .offset = 0x1c00000, + .mask_flags = MTD_WRITEABLE + },{ + .name = "raw kernel", + .size = 0x02c0000, + .offset = 0x1d00000 } }; #elif !defined(CONFIG_MTD_PB1500_BOOT) && defined(CONFIG_MTD_PB1500_USER) -static unsigned long flash_size = 0x02000000; #define WINDOW_ADDR 0x1C000000 #define WINDOW_SIZE 0x2000000 static struct mtd_partition pb1xxx_partitions[] = { { - name: "User FS", - size: 0x1e00000, - offset: 0x0000000 - },{ - name: "raw kernel", - size: 0x0200000, - offset: 0x1e00000, + .name = "User FS", + .size = 0x1e00000, + .offset = 0x0000000 + },{ + .name = "raw kernel", + .size = 0x0200000, + .offset = 0x1e00000, } }; #else @@ -196,11 +115,20 @@ #error Unsupported board #endif +#define NAME "Pb1x00 Linux Flash" +#define PADDR WINDOW_ADDR +#define BUSWIDTH 4 +#define SIZE WINDOW_SIZE +#define PARTITIONS 4 + +static struct map_info pb1xxx_mtd_map = { + .name = NAME, + .size = SIZE, + .bankwidth = BUSWIDTH, + .phys = PADDR, +}; -#define NB_OF(x) (sizeof(x)/sizeof(x[0])) - -static struct mtd_partition *parsed_parts; -static struct mtd_info *mymtd; +static struct mtd_info *pb1xxx_mtd; int __init pb1xxx_mtd_init(void) { @@ -208,40 +136,37 @@ int nb_parts = 0; char *part_type; - /* Default flash buswidth */ - pb1xxx_map.buswidth = flash_buswidth; - /* * Static partition definition selection */ part_type = "static"; parts = pb1xxx_partitions; - nb_parts = NB_OF(pb1xxx_partitions); - pb1xxx_map.size = flash_size; + nb_parts = ARRAY_SIZE(pb1xxx_partitions); /* * Now let's probe for the actual flash. Do it here since * specific machine settings might have been set above. */ printk(KERN_NOTICE "Pb1xxx flash: probing %d-bit flash bus\n", - pb1xxx_map.buswidth*8); - pb1xxx_map.map_priv_1 = - (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE); - mymtd = do_map_probe("cfi_probe", &pb1xxx_map); - if (!mymtd) return -ENXIO; - mymtd->module = THIS_MODULE; + BUSWIDTH*8); + pb1xxx_mtd_map.virt = (void __iomem *)ioremap(WINDOW_ADDR, WINDOW_SIZE); + + simple_map_init(&pb1xxx_mtd_map); + + pb1xxx_mtd = do_map_probe("cfi_probe", &pb1xxx_mtd_map); + if (!pb1xxx_mtd) return -ENXIO; + pb1xxx_mtd->owner = THIS_MODULE; - add_mtd_partitions(mymtd, parts, nb_parts); + add_mtd_partitions(pb1xxx_mtd, parts, nb_parts); return 0; } static void __exit pb1xxx_mtd_cleanup(void) { - if (mymtd) { - del_mtd_partitions(mymtd); - map_destroy(mymtd); - if (parsed_parts) - kfree(parsed_parts); + if (pb1xxx_mtd) { + del_mtd_partitions(pb1xxx_mtd); + map_destroy(pb1xxx_mtd); + iounmap((void *) pb1xxx_mtd_map.virt); } } Index: drivers/mtd/maps/pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/pci.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/pci.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/pci.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -7,7 +7,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * - * $Id: pci.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: pci.c,v 1.3 2004/11/03 00:04:44 joff Exp $ * * Generic PCI memory map driver. We support the following boards: * - Intel IQ80310 ATU. @@ -39,6 +39,74 @@ struct pci_dev *dev; }; +static map_word mtd_pci_read8(struct map_info *_map, unsigned long ofs) +{ + struct map_pci_info *map = (struct map_pci_info *)_map; + map_word val; + val.x[0]= readb(map->base + map->translate(map, ofs)); +// printk("read8 : %08lx => %02x\n", ofs, val.x[0]); + return val; +} + +#if 0 +static map_word mtd_pci_read16(struct map_info *_map, unsigned long ofs) +{ + struct map_pci_info *map = (struct map_pci_info *)_map; + map_word val; + val.x[0] = readw(map->base + map->translate(map, ofs)); +// printk("read16: %08lx => %04x\n", ofs, val.x[0]); + return val; +} +#endif +static map_word mtd_pci_read32(struct map_info *_map, unsigned long ofs) +{ + struct map_pci_info *map = (struct map_pci_info *)_map; + map_word val; + val.x[0] = readl(map->base + map->translate(map, ofs)); +// printk("read32: %08lx => %08x\n", ofs, val.x[0]); + return val; +} + +static void mtd_pci_copyfrom(struct map_info *_map, void *to, unsigned long from, ssize_t len) +{ + struct map_pci_info *map = (struct map_pci_info *)_map; + memcpy_fromio(to, map->base + map->translate(map, from), len); +} + +static void mtd_pci_write8(struct map_info *_map, map_word val, unsigned long ofs) +{ + struct map_pci_info *map = (struct map_pci_info *)_map; +// printk("write8 : %08lx <= %02x\n", ofs, val.x[0]); + writeb(val.x[0], map->base + map->translate(map, ofs)); +} + +#if 0 +static void mtd_pci_write16(struct map_info *_map, map_word val, unsigned long ofs) +{ + struct map_pci_info *map = (struct map_pci_info *)_map; +// printk("write16: %08lx <= %04x\n", ofs, val.x[0]); + writew(val.x[0], map->base + map->translate(map, ofs)); +} +#endif +static void mtd_pci_write32(struct map_info *_map, map_word val, unsigned long ofs) +{ + struct map_pci_info *map = (struct map_pci_info *)_map; +// printk("write32: %08lx <= %08x\n", ofs, val.x[0]); + writel(val.x[0], map->base + map->translate(map, ofs)); +} + +static void mtd_pci_copyto(struct map_info *_map, unsigned long to, const void *from, ssize_t len) +{ + struct map_pci_info *map = (struct map_pci_info *)_map; + memcpy_toio(map->base + map->translate(map, to), from, len); +} + +static struct map_info mtd_pci_map = { + .phys = NO_XIP, + .copy_from = mtd_pci_copyfrom, + .copy_to = mtd_pci_copyto, +}; + /* * Intel IOP80310 Flash driver */ @@ -48,7 +116,10 @@ { u32 win_base; - map->map.buswidth = 1; + map->map.bankwidth = 1; + map->map.read = mtd_pci_read8, + map->map.write = mtd_pci_write8, + map->map.size = 0x00800000; map->base = ioremap_nocache(pci_resource_start(dev, 0), pci_resource_len(dev, 0)); @@ -98,10 +169,10 @@ } static struct mtd_pci_info intel_iq80310_info = { - init: intel_iq80310_init, - exit: intel_iq80310_exit, - translate: intel_iq80310_translate, - map_name: "cfi_probe", + .init = intel_iq80310_init, + .exit = intel_iq80310_exit, + .translate = intel_iq80310_translate, + .map_name = "cfi_probe", }; /* @@ -140,14 +211,16 @@ pci_read_config_dword(dev, PCI_ROM_ADDRESS, &val); val |= PCI_ROM_ADDRESS_ENABLE; pci_write_config_dword(dev, PCI_ROM_ADDRESS, val); - printk("%s: enabling expansion ROM\n", dev->slot_name); + printk("%s: enabling expansion ROM\n", pci_name(dev)); } } if (!len || !base) return -ENXIO; - map->map.buswidth = 4; + map->map.bankwidth = 4; + map->map.read = mtd_pci_read32, + map->map.write = mtd_pci_write32, map->map.size = len; map->base = ioremap_nocache(base, len); @@ -181,34 +254,32 @@ } static struct mtd_pci_info intel_dc21285_info = { - init: intel_dc21285_init, - exit: intel_dc21285_exit, - translate: intel_dc21285_translate, - map_name: "jedec_probe", + .init = intel_dc21285_init, + .exit = intel_dc21285_exit, + .translate = intel_dc21285_translate, + .map_name = "jedec_probe", }; /* * PCI device ID table */ -static struct pci_device_id mtd_pci_ids[] __devinitdata = { +static struct pci_device_id mtd_pci_ids[] = { { - vendor: PCI_VENDOR_ID_INTEL, - device: 0x530d, - subvendor: PCI_ANY_ID, - subdevice: PCI_ANY_ID, - class: PCI_CLASS_MEMORY_OTHER << 8, - class_mask: 0xffff00, - driver_data: (unsigned long)&intel_iq80310_info, + .vendor = PCI_VENDOR_ID_INTEL, + .device = 0x530d, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .class = PCI_CLASS_MEMORY_OTHER << 8, + .class_mask = 0xffff00, + .driver_data = (unsigned long)&intel_iq80310_info, }, { - vendor: PCI_VENDOR_ID_DEC, - device: PCI_DEVICE_ID_DEC_21285, - subvendor: 0, /* DC21285 defaults to 0 on reset */ - subdevice: 0, /* DC21285 defaults to 0 on reset */ - class: 0, - class_mask: 0, - driver_data: (unsigned long)&intel_dc21285_info, + .vendor = PCI_VENDOR_ID_DEC, + .device = PCI_DEVICE_ID_DEC_21285, + .subvendor = 0, /* DC21285 defaults to 0 on reset */ + .subdevice = 0, /* DC21285 defaults to 0 on reset */ + .driver_data = (unsigned long)&intel_dc21285_info, }, { 0, } }; @@ -217,74 +288,6 @@ * Generic code follows. */ -static u8 mtd_pci_read8(struct map_info *_map, unsigned long ofs) -{ - struct map_pci_info *map = (struct map_pci_info *)_map; - u8 val = readb(map->base + map->translate(map, ofs)); -// printk("read8 : %08lx => %02x\n", ofs, val); - return val; -} - -static u16 mtd_pci_read16(struct map_info *_map, unsigned long ofs) -{ - struct map_pci_info *map = (struct map_pci_info *)_map; - u16 val = readw(map->base + map->translate(map, ofs)); -// printk("read16: %08lx => %04x\n", ofs, val); - return val; -} - -static u32 mtd_pci_read32(struct map_info *_map, unsigned long ofs) -{ - struct map_pci_info *map = (struct map_pci_info *)_map; - u32 val = readl(map->base + map->translate(map, ofs)); -// printk("read32: %08lx => %08x\n", ofs, val); - return val; -} - -static void mtd_pci_copyfrom(struct map_info *_map, void *to, unsigned long from, ssize_t len) -{ - struct map_pci_info *map = (struct map_pci_info *)_map; - memcpy_fromio(to, map->base + map->translate(map, from), len); -} - -static void mtd_pci_write8(struct map_info *_map, u8 val, unsigned long ofs) -{ - struct map_pci_info *map = (struct map_pci_info *)_map; -// printk("write8 : %08lx <= %02x\n", ofs, val); - writeb(val, map->base + map->translate(map, ofs)); -} - -static void mtd_pci_write16(struct map_info *_map, u16 val, unsigned long ofs) -{ - struct map_pci_info *map = (struct map_pci_info *)_map; -// printk("write16: %08lx <= %04x\n", ofs, val); - writew(val, map->base + map->translate(map, ofs)); -} - -static void mtd_pci_write32(struct map_info *_map, u32 val, unsigned long ofs) -{ - struct map_pci_info *map = (struct map_pci_info *)_map; -// printk("write32: %08lx <= %08x\n", ofs, val); - writel(val, map->base + map->translate(map, ofs)); -} - -static void mtd_pci_copyto(struct map_info *_map, unsigned long to, const void *from, ssize_t len) -{ - struct map_pci_info *map = (struct map_pci_info *)_map; - memcpy_toio(map->base + map->translate(map, to), from, len); -} - -static struct map_info mtd_pci_map = { - read8: mtd_pci_read8, - read16: mtd_pci_read16, - read32: mtd_pci_read32, - copy_from: mtd_pci_copyfrom, - write8: mtd_pci_write8, - write16: mtd_pci_write16, - write32: mtd_pci_write32, - copy_to: mtd_pci_copyto, -}; - static int __devinit mtd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { @@ -307,7 +310,7 @@ goto release; map->map = mtd_pci_map; - map->map.name = dev->slot_name; + map->map.name = pci_name(dev); map->dev = dev; map->exit = info->exit; map->translate = info->translate; @@ -322,7 +325,7 @@ if (!mtd) goto release; - mtd->module = THIS_MODULE; + mtd->owner = THIS_MODULE; add_mtd_device(mtd); pci_set_drvdata(dev, mtd); @@ -359,10 +362,10 @@ } static struct pci_driver mtd_pci_driver = { - name: "MTD PCI", - probe: mtd_pci_probe, - remove: __devexit_p(mtd_pci_remove), - id_table: mtd_pci_ids, + .name = "MTD PCI", + .probe = mtd_pci_probe, + .remove = __devexit_p(mtd_pci_remove), + .id_table = mtd_pci_ids, }; static int __init mtd_pci_maps_init(void) Index: drivers/mtd/maps/pcmciamtd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/pcmciamtd.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/pcmciamtd.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/pcmciamtd.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -1,5 +1,5 @@ /* - * $Id: pcmciamtd.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: pcmciamtd.c,v 1.3 2004/11/03 00:04:44 joff Exp $ * * pcmciamtd.c - MTD driver for PCMCIA flash memory cards * @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -24,6 +25,7 @@ #include #include +#include #ifdef CONFIG_MTD_DEBUG static int debug = CONFIG_MTD_DEBUG_VERBOSE; @@ -47,7 +49,7 @@ #define DRIVER_DESC "PCMCIA Flash memory card driver" -#define DRIVER_VERSION "$Revision: 1.1 $" +#define DRIVER_VERSION "$Revision: 1.3 $" /* Size of the PCMCIA address space: 26 bits = 64 MB */ #define MAX_PCMCIA_ADDR 0x4000000 @@ -71,7 +73,7 @@ /* Module parameters */ /* 2 = do 16-bit transfers, 1 = do 8-bit transfers */ -static int buswidth = 2; +static int bankwidth = 2; /* Speed of memory accesses, in ns */ static int mem_speed; @@ -91,12 +93,12 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Simon Evans "); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_PARM(buswidth, "i"); -MODULE_PARM_DESC(buswidth, "Set buswidth (1=8 bit, 2=16 bit, default=2)"); +MODULE_PARM(bankwidth, "i"); +MODULE_PARM_DESC(bankwidth, "Set bankwidth (1=8 bit, 2=16 bit, default=2)"); MODULE_PARM(mem_speed, "i"); MODULE_PARM_DESC(mem_speed, "Set memory access speed in ns"); MODULE_PARM(force_size, "i"); -MODULE_PARM_DESC(force_size, "Force size of card in MB (1-64)"); +MODULE_PARM_DESC(force_size, "Force size of card in MiB (1-64)"); MODULE_PARM(setvpp, "i"); MODULE_PARM_DESC(setvpp, "Set Vpp (0=Never, 1=On writes, 2=Always on, default=0)"); MODULE_PARM(vpp, "i"); @@ -105,16 +107,7 @@ MODULE_PARM_DESC(mem_type, "Set Memory type (0=Flash, 1=RAM, 2=ROM, default=0)"); - -static inline void cs_error(client_handle_t handle, int func, int ret) -{ - error_info_t err = { func, ret }; - CardServices(ReportError, handle, &err); -} - - /* read/write{8,16} copy_{from,to} routines with window remapping to access whole card */ - static caddr_t remap_window(struct map_info *map, unsigned long to) { struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1; @@ -132,7 +125,7 @@ DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x", dev->offset, mrq.CardOffset); mrq.Page = 0; - if( (ret = CardServices(MapMemPage, win, &mrq)) != CS_SUCCESS) { + if( (ret = pcmcia_map_mem_page(win, &mrq)) != CS_SUCCESS) { cs_error(dev->link.handle, MapMemPage, ret); return NULL; } @@ -142,32 +135,32 @@ } -static u8 pcmcia_read8_remap(struct map_info *map, unsigned long ofs) +static map_word pcmcia_read8_remap(struct map_info *map, unsigned long ofs) { caddr_t addr; - u8 d; + map_word d = {{0}}; addr = remap_window(map, ofs); if(!addr) - return 0; + return d; - d = readb(addr); - DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%02x", ofs, addr, d); + d.x[0] = readb(addr); + DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%02x", ofs, addr, d.x[0]); return d; } -static u16 pcmcia_read16_remap(struct map_info *map, unsigned long ofs) +static map_word pcmcia_read16_remap(struct map_info *map, unsigned long ofs) { caddr_t addr; - u16 d; + map_word d = {{0}}; addr = remap_window(map, ofs); if(!addr) - return 0; + return d; - d = readw(addr); - DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%04x", ofs, addr, d); + d.x[0] = readw(addr); + DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%04x", ofs, addr, d.x[0]); return d; } @@ -198,26 +191,26 @@ } -static void pcmcia_write8_remap(struct map_info *map, u8 d, unsigned long adr) +static void pcmcia_write8_remap(struct map_info *map, map_word d, unsigned long adr) { caddr_t addr = remap_window(map, adr); if(!addr) return; - DEBUG(3, "adr = 0x%08lx (%p) data = 0x%02x", adr, addr, d); - writeb(d, addr); + DEBUG(3, "adr = 0x%08lx (%p) data = 0x%02x", adr, addr, d.x[0]); + writeb(d.x[0], addr); } -static void pcmcia_write16_remap(struct map_info *map, u16 d, unsigned long adr) +static void pcmcia_write16_remap(struct map_info *map, map_word d, unsigned long adr) { caddr_t addr = remap_window(map, adr); if(!addr) return; - DEBUG(3, "adr = 0x%08lx (%p) data = 0x%04x", adr, addr, d); - writew(d, addr); + DEBUG(3, "adr = 0x%08lx (%p) data = 0x%04x", adr, addr, d.x[0]); + writew(d.x[0], addr); } @@ -251,30 +244,30 @@ #define DEV_REMOVED(x) (!(*(u_int *)x->map_priv_1 & DEV_PRESENT)) -static u8 pcmcia_read8(struct map_info *map, unsigned long ofs) +static map_word pcmcia_read8(struct map_info *map, unsigned long ofs) { caddr_t win_base = (caddr_t)map->map_priv_2; - u8 d; + map_word d = {{0}}; if(DEV_REMOVED(map)) - return 0; + return d; - d = readb(win_base + ofs); - DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%02x", ofs, win_base + ofs, d); + d.x[0] = readb(win_base + ofs); + DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%02x", ofs, win_base + ofs, d.x[0]); return d; } -static u16 pcmcia_read16(struct map_info *map, unsigned long ofs) +static map_word pcmcia_read16(struct map_info *map, unsigned long ofs) { caddr_t win_base = (caddr_t)map->map_priv_2; - u16 d; + map_word d = {{0}}; if(DEV_REMOVED(map)) - return 0; + return d; - d = readw(win_base + ofs); - DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%04x", ofs, win_base + ofs, d); + d.x[0] = readw(win_base + ofs); + DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%04x", ofs, win_base + ofs, d.x[0]); return d; } @@ -339,7 +332,7 @@ mod.Vpp1 = mod.Vpp2 = on ? dev->vpp : 0; DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp); - ret = CardServices(ModifyConfiguration, link->handle, &mod); + ret = pcmcia_modify_configuration(link->handle, &mod); if(ret != CS_SUCCESS) { cs_error(link->handle, ModifyConfiguration, ret); } @@ -351,9 +344,8 @@ * still open, this will be postponed until it is closed. */ -static void pcmciamtd_release(u_long arg) +static void pcmciamtd_release(dev_link_t *link) { - dev_link_t *link = (dev_link_t *)arg; struct pcmciamtd_dev *dev = link->priv; DEBUG(3, "link = 0x%p", link); @@ -363,9 +355,9 @@ iounmap(dev->win_base); dev->win_base = NULL; } - CardServices(ReleaseWindow, link->win); + pcmcia_release_window(link->win); } - CardServices(ReleaseConfiguration, link->handle); + pcmcia_release_configuration(link->handle); link->state &= ~DEV_CONFIG; } @@ -383,14 +375,14 @@ tuple.TupleOffset = 0; tuple.DesiredTuple = RETURN_FIRST_TUPLE; - rc = CardServices(GetFirstTuple, link->handle, &tuple); + rc = pcmcia_get_first_tuple(link->handle, &tuple); while(rc == CS_SUCCESS) { - rc = CardServices(GetTupleData, link->handle, &tuple); + rc = pcmcia_get_tuple_data(link->handle, &tuple); if(rc != CS_SUCCESS) { cs_error(link->handle, GetTupleData, rc); break; } - rc = CardServices(ParseTuple, link->handle, &tuple, &parse); + rc = pcmcia_parse_tuple(link->handle, &tuple, &parse); if(rc != CS_SUCCESS) { cs_error(link->handle, ParseTuple, rc); break; @@ -447,9 +439,9 @@ case CISTPL_DEVICE_GEO: { cistpl_device_geo_t *t = &parse.device_geo; int i; - dev->pcmcia_map.buswidth = t->geo[0].buswidth; + dev->pcmcia_map.bankwidth = t->geo[0].buswidth; for(i = 0; i < t->ngeo; i++) { - DEBUG(2, "region: %d buswidth = %u", i, t->geo[i].buswidth); + DEBUG(2, "region: %d bankwidth = %u", i, t->geo[i].buswidth); DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block); DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block); DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block); @@ -463,22 +455,22 @@ DEBUG(2, "Unknown tuple code %d", tuple.TupleCode); } - rc = CardServices(GetNextTuple, link->handle, &tuple, &parse); + rc = pcmcia_get_next_tuple(link->handle, &tuple); } if(!dev->pcmcia_map.size) dev->pcmcia_map.size = MAX_PCMCIA_ADDR; - if(!dev->pcmcia_map.buswidth) - dev->pcmcia_map.buswidth = 2; + if(!dev->pcmcia_map.bankwidth) + dev->pcmcia_map.bankwidth = 2; if(force_size) { dev->pcmcia_map.size = force_size << 20; DEBUG(2, "size forced to %dM", force_size); } - if(buswidth) { - dev->pcmcia_map.buswidth = buswidth; - DEBUG(2, "buswidth forced to %d", buswidth); + if(bankwidth) { + dev->pcmcia_map.bankwidth = bankwidth; + DEBUG(2, "bankwidth forced to %d", bankwidth); } dev->pcmcia_map.name = dev->mtd_name; @@ -488,7 +480,7 @@ } DEBUG(1, "Device: Size: %lu Width:%d Name: %s", - dev->pcmcia_map.size, dev->pcmcia_map.buswidth << 3, dev->mtd_name); + dev->pcmcia_map.size, dev->pcmcia_map.bankwidth << 3, dev->mtd_name); } @@ -497,8 +489,8 @@ * MTD device available to the system. */ -#define CS_CHECK(fn, args...) \ -while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed +#define CS_CHECK(fn, ret) \ +do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) static void pcmciamtd_config(dev_link_t *link) { @@ -520,7 +512,7 @@ link->state |= DEV_CONFIG; DEBUG(2, "Validating CIS"); - ret = CardServices(ValidateCIS, link->handle, &cisinfo); + ret = pcmcia_validate_cis(link->handle, &cisinfo); if(ret != CS_SUCCESS) { cs_error(link->handle, GetTupleData, ret); } else { @@ -529,21 +521,25 @@ card_settings(dev, link, &new_name); - dev->pcmcia_map.read8 = pcmcia_read8_remap; - dev->pcmcia_map.read16 = pcmcia_read16_remap; + dev->pcmcia_map.phys = NO_XIP; dev->pcmcia_map.copy_from = pcmcia_copy_from_remap; - dev->pcmcia_map.write8 = pcmcia_write8_remap; - dev->pcmcia_map.write16 = pcmcia_write16_remap; dev->pcmcia_map.copy_to = pcmcia_copy_to_remap; + if (dev->pcmcia_map.bankwidth == 1) { + dev->pcmcia_map.read = pcmcia_read8_remap; + dev->pcmcia_map.write = pcmcia_write8_remap; + } else { + dev->pcmcia_map.read = pcmcia_read16_remap; + dev->pcmcia_map.write = pcmcia_write16_remap; + } if(setvpp == 1) dev->pcmcia_map.set_vpp = pcmciamtd_set_vpp; /* Request a memory window for PCMCIA. Some architeures can map windows upto the maximum - that PCMCIA can support (64Mb) - this is ideal and we aim for a window the size of the + that PCMCIA can support (64MiB) - this is ideal and we aim for a window the size of the whole card - otherwise we try smaller windows until we succeed */ req.Attributes = WIN_MEMORY_TYPE_CM | WIN_ENABLE; - req.Attributes |= (dev->pcmcia_map.buswidth == 1) ? WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16; + req.Attributes |= (dev->pcmcia_map.bankwidth == 1) ? WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16; req.Base = 0; req.AccessSpeed = mem_speed; link->win = (window_handle_t)link->handle; @@ -552,15 +548,14 @@ do { int ret; - DEBUG(2, "requesting window with size = %dKB memspeed = %d", + DEBUG(2, "requesting window with size = %dKiB memspeed = %d", req.Size >> 10, req.AccessSpeed); - link->win = (window_handle_t)link->handle; - ret = CardServices(RequestWindow, &link->win, &req); + ret = pcmcia_request_window(&link->handle, &req, &link->win); DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size); if(ret) { req.Size >>= 1; } else { - DEBUG(2, "Got window of size %dKB", req.Size >> 10); + DEBUG(2, "Got window of size %dKiB", req.Size >> 10); dev->win_size = req.Size; break; } @@ -570,19 +565,19 @@ if(!dev->win_size) { err("Cant allocate memory window"); - pcmciamtd_release((u_long)link); + pcmciamtd_release(link); return; } - DEBUG(1, "Allocated a window of %dKB", dev->win_size >> 10); + DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10); /* Get write protect status */ - CS_CHECK(GetStatus, link->handle, &status); + CS_CHECK(GetStatus, pcmcia_get_status(link->handle, &status)); DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx", status.CardState, (unsigned long)link->win); dev->win_base = ioremap(req.Base, req.Size); if(!dev->win_base) { err("ioremap(%lu, %u) failed", req.Base, req.Size); - pcmciamtd_release((u_long)link); + pcmciamtd_release(link); return; } DEBUG(1, "mapped window dev = %p req.base = 0x%lx base = %p size = 0x%x", @@ -593,7 +588,7 @@ dev->pcmcia_map.map_priv_2 = (unsigned long)link->win; DEBUG(2, "Getting configuration"); - CS_CHECK(GetConfigurationInfo, link->handle, &t); + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link->handle, &t)); DEBUG(2, "Vcc = %d Vpp1 = %d Vpp2 = %d", t.Vcc, t.Vpp1, t.Vpp2); dev->vpp = (vpp) ? vpp : t.Vpp1; link->conf.Attributes = 0; @@ -615,7 +610,7 @@ link->conf.ConfigIndex = 0; link->conf.Present = t.Present; DEBUG(2, "Setting Configuration"); - ret = CardServices(RequestConfiguration, link->handle, &link->conf); + ret = pcmcia_request_configuration(link->handle, &link->conf); if(ret != CS_SUCCESS) { cs_error(link->handle, RequestConfiguration, ret); } @@ -637,26 +632,26 @@ if(!mtd) { DEBUG(1, "Cant find an MTD"); - pcmciamtd_release((u_long)link); + pcmciamtd_release(link); return; } dev->mtd_info = mtd; - mtd->module = THIS_MODULE; + mtd->owner = THIS_MODULE; if(new_name) { int size = 0; char unit = ' '; /* Since we are using a default name, make it better by adding in the size */ - if(mtd->size < 1048576) { /* <1MB in size, show size in K */ + if(mtd->size < 1048576) { /* <1MiB in size, show size in KiB */ size = mtd->size >> 10; unit = 'K'; } else { size = mtd->size >> 20; unit = 'M'; } - snprintf(dev->mtd_name, sizeof(dev->mtd_name), "%d%cB %s", size, unit, "PCMCIA Memory card"); + snprintf(dev->mtd_name, sizeof(dev->mtd_name), "%d%ciB %s", size, unit, "PCMCIA Memory card"); } /* If the memory found is fits completely into the mapped PCMCIA window, @@ -665,11 +660,14 @@ DEBUG(1, "Using non remapping memory functions"); dev->pcmcia_map.map_priv_1 = (unsigned long)&(dev->link.state); dev->pcmcia_map.map_priv_2 = (unsigned long)dev->win_base; - dev->pcmcia_map.read8 = pcmcia_read8; - dev->pcmcia_map.read16 = pcmcia_read16; + if (dev->pcmcia_map.bankwidth == 1) { + dev->pcmcia_map.read = pcmcia_read8; + dev->pcmcia_map.write = pcmcia_write8; + } else { + dev->pcmcia_map.read = pcmcia_read16; + dev->pcmcia_map.write = pcmcia_write16; + } dev->pcmcia_map.copy_from = pcmcia_copy_from; - dev->pcmcia_map.write8 = pcmcia_write8; - dev->pcmcia_map.write16 = pcmcia_write16; dev->pcmcia_map.copy_to = pcmcia_copy_to; } @@ -677,7 +675,7 @@ map_destroy(mtd); dev->mtd_info = NULL; err("Couldnt register MTD device"); - pcmciamtd_release((u_long)link); + pcmciamtd_release(link); return; } snprintf(dev->node.dev_name, sizeof(dev->node.dev_name), "mtd%d", mtd->index); @@ -689,7 +687,7 @@ cs_failed: cs_error(link->handle, last_fn, last_ret); err("CS Error, exiting"); - pcmciamtd_release((u_long)link); + pcmciamtd_release(link); return; } @@ -716,7 +714,7 @@ del_mtd_device(dev->mtd_info); info("mtd%d: Removed", dev->mtd_info->index); } - mod_timer(&link->release, jiffies + HZ/20); + pcmciamtd_release(link); } break; case CS_EVENT_CARD_INSERTION: @@ -757,16 +755,14 @@ { DEBUG(3, "link=0x%p", link); - del_timer(&link->release); - if(link->state & DEV_CONFIG) { - pcmciamtd_release((u_long)link); + pcmciamtd_release(link); } if (link->handle) { int ret; DEBUG(2, "Deregistering with card services"); - ret = CardServices(DeregisterClient, link->handle); + ret = pcmcia_deregister_client(link->handle); if (ret != CS_SUCCESS) cs_error(link->handle, DeregisterClient, ret); } @@ -796,10 +792,6 @@ link = &dev->link; link->priv = dev; - init_timer(&link->release); - link->release.function = &pcmciamtd_release; - link->release.data = (u_long)link; - link->conf.Attributes = 0; link->conf.IntType = INT_MEMORY; @@ -817,7 +809,7 @@ client_reg.Version = 0x0210; client_reg.event_callback_args.client_data = link; DEBUG(2, "Calling RegisterClient"); - ret = CardServices(RegisterClient, &link->handle, &client_reg); + ret = pcmcia_register_client(&link->handle, &client_reg); if (ret != 0) { cs_error(link->handle, RegisterClient, ret); pcmciamtd_detach(link); @@ -828,20 +820,23 @@ } +static struct pcmcia_driver pcmciamtd_driver = { + .drv = { + .name = "pcmciamtd" + }, + .attach = pcmciamtd_attach, + .detach = pcmciamtd_detach, + .owner = THIS_MODULE +}; + + static int __init init_pcmciamtd(void) { - servinfo_t serv; - info(DRIVER_DESC " " DRIVER_VERSION); - CardServices(GetCardServicesInfo, &serv); - if (serv.Revision != CS_RELEASE_CODE) { - err("Card Services release does not match!"); - return -1; - } - if(buswidth && buswidth != 1 && buswidth != 2) { - info("bad buswidth (%d), using default", buswidth); - buswidth = 2; + if(bankwidth && bankwidth != 1 && bankwidth != 2) { + info("bad bankwidth (%d), using default", bankwidth); + bankwidth = 2; } if(force_size && (force_size < 1 || force_size > 64)) { info("bad force_size (%d), using default", force_size); @@ -851,15 +846,14 @@ info("bad mem_type (%d), using default", mem_type); mem_type = 0; } - register_pccard_driver(&dev_info, &pcmciamtd_attach, &pcmciamtd_detach); - return 0; + return pcmcia_register_driver(&pcmciamtd_driver); } static void __exit exit_pcmciamtd(void) { DEBUG(1, DRIVER_DESC " unloading"); - unregister_pccard_driver(&dev_info); + pcmcia_unregister_driver(&pcmciamtd_driver); while(dev_list) { dev_link_t *link = dev_list; Index: drivers/mtd/maps/physmap.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/physmap.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/physmap.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/physmap.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -1,179 +1,119 @@ /* - * $Id: physmap.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: physmap.c,v 1.3 2004/11/03 00:04:44 joff Exp $ * * Normal mappings of chips in physical memory + * + * Copyright (C) 2003 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * 031022 - [jsun] add run-time configure and partition setup */ #include #include #include +#include +#include #include #include #include #include - -#ifdef CONFIG_MTD_PARTITIONS #include -#endif - -#define WINDOW_ADDR CONFIG_MTD_PHYSMAP_START -#define WINDOW_SIZE CONFIG_MTD_PHYSMAP_LEN -#define BUSWIDTH CONFIG_MTD_PHYSMAP_BUSWIDTH static struct mtd_info *mymtd; -__u8 physmap_read8(struct map_info *map, unsigned long ofs) -{ - return __raw_readb(map->map_priv_1 + ofs); -} - -__u16 physmap_read16(struct map_info *map, unsigned long ofs) -{ - return __raw_readw(map->map_priv_1 + ofs); -} - -__u32 physmap_read32(struct map_info *map, unsigned long ofs) -{ - return __raw_readl(map->map_priv_1 + ofs); -} - -void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy_fromio(to, map->map_priv_1 + from, len); -} - -void physmap_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - __raw_writeb(d, map->map_priv_1 + adr); - mb(); -} - -void physmap_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - __raw_writew(d, map->map_priv_1 + adr); - mb(); -} - -void physmap_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - __raw_writel(d, map->map_priv_1 + adr); - mb(); -} - -void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy_toio(map->map_priv_1 + to, from, len); -} - struct map_info physmap_map = { - name: "Physically mapped flash", - size: WINDOW_SIZE, - buswidth: BUSWIDTH, - read8: physmap_read8, - read16: physmap_read16, - read32: physmap_read32, - copy_from: physmap_copy_from, - write8: physmap_write8, - write16: physmap_write16, - write32: physmap_write32, - copy_to: physmap_copy_to + .name = "phys_mapped_flash", + .phys = CONFIG_MTD_PHYSMAP_START, + .size = CONFIG_MTD_PHYSMAP_LEN, + .bankwidth = CONFIG_MTD_PHYSMAP_BANKWIDTH, }; #ifdef CONFIG_MTD_PARTITIONS -#ifdef CONFIG_MTD_CMDLINE_PARTS -static struct mtd_partition *mtd_parts = 0; -static int mtd_parts_nb = 0; -#else -static struct mtd_partition physmap_partitions[] = { -/* Put your own partition definitions here */ -#if 0 - { - name: "bootROM", - size: 0x80000, - offset: 0, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "zImage", - size: 0x100000, - offset: MTDPART_OFS_APPEND, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "ramdisk.gz", - size: 0x300000, - offset: MTDPART_OFS_APPEND, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "User FS", - size: MTDPART_SIZ_FULL, - offset: MTDPART_OFS_APPEND, - } -#endif -}; +static struct mtd_partition *mtd_parts; +static int mtd_parts_nb; -#define NUM_PARTITIONS (sizeof(physmap_partitions)/sizeof(struct mtd_partition)) +static int num_physmap_partitions; +static struct mtd_partition *physmap_partitions; -#endif -#endif +static const char *part_probes[] __initdata = {"cmdlinepart", "RedBoot", NULL}; + +void physmap_set_partitions(struct mtd_partition *parts, int num_parts) +{ + physmap_partitions=parts; + num_physmap_partitions=num_parts; +} +#endif /* CONFIG_MTD_PARTITIONS */ -int __init init_physmap(void) +static int __init init_physmap(void) { - static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", 0 }; + static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL }; const char **type; - printk(KERN_NOTICE "physmap flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR); - physmap_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE); + printk(KERN_NOTICE "physmap flash device: %lx at %lx\n", physmap_map.size, physmap_map.phys); + physmap_map.virt = (void __iomem *)ioremap(physmap_map.phys, physmap_map.size); - if (!physmap_map.map_priv_1) { + if (!physmap_map.virt) { printk("Failed to ioremap\n"); return -EIO; } - - mymtd = 0; + + simple_map_init(&physmap_map); + + mymtd = NULL; type = rom_probe_types; for(; !mymtd && *type; type++) { mymtd = do_map_probe(*type, &physmap_map); } if (mymtd) { - mymtd->module = THIS_MODULE; + mymtd->owner = THIS_MODULE; - add_mtd_device(mymtd); #ifdef CONFIG_MTD_PARTITIONS -#ifdef CONFIG_MTD_CMDLINE_PARTS - mtd_parts_nb = parse_cmdline_partitions(mymtd, &mtd_parts, - "phys"); + mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes, + &mtd_parts, 0); + if (mtd_parts_nb > 0) { - printk(KERN_NOTICE - "Using command line partition definition\n"); add_mtd_partitions (mymtd, mtd_parts, mtd_parts_nb); + return 0; } -#else - if (NUM_PARTITIONS != 0) + + if (num_physmap_partitions != 0) { printk(KERN_NOTICE "Using physmap partition definition\n"); - add_mtd_partitions (mymtd, physmap_partitions, NUM_PARTITIONS); + add_mtd_partitions (mymtd, physmap_partitions, num_physmap_partitions); + return 0; } #endif -#endif + add_mtd_device(mymtd); + return 0; } - iounmap((void *)physmap_map.map_priv_1); + iounmap((void *)physmap_map.virt); return -ENXIO; } static void __exit cleanup_physmap(void) { - if (mymtd) { +#ifdef CONFIG_MTD_PARTITIONS + if (mtd_parts_nb) { + del_mtd_partitions(mymtd); + kfree(mtd_parts); + } else if (num_physmap_partitions) { + del_mtd_partitions(mymtd); + } else { del_mtd_device(mymtd); - map_destroy(mymtd); - } - if (physmap_map.map_priv_1) { - iounmap((void *)physmap_map.map_priv_1); - physmap_map.map_priv_1 = 0; } +#else + del_mtd_device(mymtd); +#endif + map_destroy(mymtd); + + iounmap((void *)physmap_map.virt); + physmap_map.virt = 0; } module_init(init_physmap); Index: drivers/mtd/maps/physmap64.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/physmap64.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/mtd/maps/physmap64.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/physmap64.c 4 Aug 2004 01:29:06 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: physmap64.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: physmap64.c,v 1.2 2004/08/04 01:29:06 joff Exp $ * * Normal mappings of chips in physical memory */ Index: drivers/mtd/maps/pnc2000.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/pnc2000.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/pnc2000.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/pnc2000.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -5,12 +5,13 @@ * * This code is GPL * - * $Id: pnc2000.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: pnc2000.c,v 1.3 2004/11/03 00:04:44 joff Exp $ */ #include #include #include +#include #include #include @@ -24,58 +25,13 @@ * MAP DRIVER STUFF */ -__u8 pnc_read8(struct map_info *map, unsigned long ofs) -{ - return *(__u8 *)(WINDOW_ADDR + ofs); -} - -__u16 pnc_read16(struct map_info *map, unsigned long ofs) -{ - return *(__u16 *)(WINDOW_ADDR + ofs); -} - -__u32 pnc_read32(struct map_info *map, unsigned long ofs) -{ - return *(volatile unsigned int *)(WINDOW_ADDR + ofs); -} - -void pnc_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy(to, (void *)(WINDOW_ADDR + from), len); -} - -void pnc_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - *(__u8 *)(WINDOW_ADDR + adr) = d; -} - -void pnc_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - *(__u16 *)(WINDOW_ADDR + adr) = d; -} - -void pnc_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - *(__u32 *)(WINDOW_ADDR + adr) = d; -} - -void pnc_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy((void *)(WINDOW_ADDR + to), from, len); -} struct map_info pnc_map = { - name: "PNC-2000", - size: WINDOW_SIZE, - buswidth: 4, - read8: pnc_read8, - read16: pnc_read16, - read32: pnc_read32, - copy_from: pnc_copy_from, - write8: pnc_write8, - write16: pnc_write16, - write32: pnc_write32, - copy_to: pnc_copy_to + .name = "PNC-2000", + .size = WINDOW_SIZE, + .bankwidth = 4, + .phys = 0xFFFFFFFF, + .virt = (void __iomem *)WINDOW_ADDR, }; @@ -84,19 +40,19 @@ */ static struct mtd_partition pnc_partitions[3] = { { - name: "PNC-2000 boot firmware", - size: 0x20000, - offset: 0 + .name = "PNC-2000 boot firmware", + .size = 0x20000, + .offset = 0 }, { - name: "PNC-2000 kernel", - size: 0x1a0000, - offset: 0x20000 + .name = "PNC-2000 kernel", + .size = 0x1a0000, + .offset = 0x20000 }, { - name: "PNC-2000 filesystem", - size: 0x240000, - offset: 0x1c0000 + .name = "PNC-2000 filesystem", + .size = 0x240000, + .offset = 0x1c0000 } }; @@ -110,9 +66,11 @@ { printk(KERN_NOTICE "Photron PNC-2000 flash mapping: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR); + simple_map_init(&pnc_map); + mymtd = do_map_probe("cfi_probe", &pnc_map); if (mymtd) { - mymtd->module = THIS_MODULE; + mymtd->owner = THIS_MODULE; return add_mtd_partitions(mymtd, pnc_partitions, 3); } Index: drivers/mtd/maps/redwood.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/redwood.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/mtd/maps/redwood.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/redwood.c 3 Nov 2004 00:04:44 -0000 1.2 @@ -1,38 +1,23 @@ /* - * $Id: + * $Id: redwood.c,v 1.2 2004/11/03 00:04:44 joff Exp $ * - * redwood.c - mapper for IBM Redwood-4/5 board. - * - * 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. + * drivers/mtd/maps/redwood.c * - * History: 12/17/2001 - Armin - * migrated to use do_map_probe + * FLASH map for the IBM Redwood 4/5/6 boards. * + * Author: MontaVista Software, Inc. + * + * 2001-2003 (c) MontaVista, Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. */ +#include #include #include #include +#include #include #include @@ -40,134 +25,146 @@ #include +#if !defined (CONFIG_REDWOOD_6) + #define WINDOW_ADDR 0xffc00000 #define WINDOW_SIZE 0x00400000 -__u8 redwood_flash_read8(struct map_info *map, unsigned long ofs) -{ - return *(__u8 *)(map->map_priv_1 + ofs); -} - -__u16 redwood_flash_read16(struct map_info *map, unsigned long ofs) -{ - return *(__u16 *)(map->map_priv_1 + ofs); -} - -__u32 redwood_flash_read32(struct map_info *map, unsigned long ofs) -{ - return *(volatile unsigned int *)(map->map_priv_1 + ofs); -} +#define RW_PART0_OF 0 +#define RW_PART0_SZ 0x10000 +#define RW_PART1_OF RW_PART0_SZ +#define RW_PART1_SZ 0x200000 - 0x10000 +#define RW_PART2_OF 0x200000 +#define RW_PART2_SZ 0x10000 +#define RW_PART3_OF 0x210000 +#define RW_PART3_SZ 0x200000 - (0x10000 + 0x20000) +#define RW_PART4_OF 0x3e0000 +#define RW_PART4_SZ 0x20000 -void redwood_flash_copy_from(struct map_info *map, void *to, - unsigned long from, ssize_t len) -{ - memcpy(to, (void *)(map->map_priv_1 + from), len); -} - -void redwood_flash_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - *(__u8 *)(map->map_priv_1 + adr) = d; -} +static struct mtd_partition redwood_flash_partitions[] = { + { + .name = "Redwood OpenBIOS Vital Product Data", + .offset = RW_PART0_OF, + .size = RW_PART0_SZ, + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .name = "Redwood kernel", + .offset = RW_PART1_OF, + .size = RW_PART1_SZ + }, + { + .name = "Redwood OpenBIOS non-volatile storage", + .offset = RW_PART2_OF, + .size = RW_PART2_SZ, + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .name = "Redwood filesystem", + .offset = RW_PART3_OF, + .size = RW_PART3_SZ + }, + { + .name = "Redwood OpenBIOS", + .offset = RW_PART4_OF, + .size = RW_PART4_SZ, + .mask_flags = MTD_WRITEABLE /* force read-only */ + } +}; -void redwood_flash_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - *(__u16 *)(map->map_priv_1 + adr) = d; -} +#else /* CONFIG_REDWOOD_6 */ +/* FIXME: the window is bigger - armin */ +#define WINDOW_ADDR 0xff800000 +#define WINDOW_SIZE 0x00800000 + +#define RW_PART0_OF 0 +#define RW_PART0_SZ 0x400000 /* 4 MiB data */ +#define RW_PART1_OF RW_PART0_OF + RW_PART0_SZ +#define RW_PART1_SZ 0x10000 /* 64K VPD */ +#define RW_PART2_OF RW_PART1_OF + RW_PART1_SZ +#define RW_PART2_SZ 0x400000 - (0x10000 + 0x20000) +#define RW_PART3_OF RW_PART2_OF + RW_PART2_SZ +#define RW_PART3_SZ 0x20000 -void redwood_flash_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - *(__u32 *)(map->map_priv_1 + adr) = d; -} +static struct mtd_partition redwood_flash_partitions[] = { + { + .name = "Redwood filesystem", + .offset = RW_PART0_OF, + .size = RW_PART0_SZ + }, + { + .name = "Redwood OpenBIOS Vital Product Data", + .offset = RW_PART1_OF, + .size = RW_PART1_SZ, + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .name = "Redwood kernel", + .offset = RW_PART2_OF, + .size = RW_PART2_SZ + }, + { + .name = "Redwood OpenBIOS", + .offset = RW_PART3_OF, + .size = RW_PART3_SZ, + .mask_flags = MTD_WRITEABLE /* force read-only */ + } +}; -void redwood_flash_copy_to(struct map_info *map, unsigned long to, - const void *from, ssize_t len) -{ - memcpy((void *)(map->map_priv_1 + to), from, len); -} +#endif /* CONFIG_REDWOOD_6 */ struct map_info redwood_flash_map = { - name: "IBM Redwood", - size: WINDOW_SIZE, - buswidth: 2, - read8: redwood_flash_read8, - read16: redwood_flash_read16, - read32: redwood_flash_read32, - copy_from: redwood_flash_copy_from, - write8: redwood_flash_write8, - write16: redwood_flash_write16, - write32: redwood_flash_write32, - copy_to: redwood_flash_copy_to + .name = "IBM Redwood", + .size = WINDOW_SIZE, + .bankwidth = 2, + .phys = WINDOW_ADDR, }; -static struct mtd_partition redwood_flash_partitions[] = { - { - name: "Redwood OpenBIOS Vital Product Data", - offset: 0, - size: 0x10000, - mask_flags: MTD_WRITEABLE /* force read-only */ - }, - { - name: "Redwood kernel", - offset: 0x10000, - size: 0x200000 - 0x10000 - }, - { - name: "Redwood OpenBIOS non-volatile storage", - offset: 0x200000, - size: 0x10000, - mask_flags: MTD_WRITEABLE /* force read-only */ - }, - { - name: "Redwood filesystem", - offset: 0x210000, - size: 0x200000 - (0x10000 + 0x20000) - }, - { - name: "Redwood OpenBIOS", - offset: 0x3e0000, - size: 0x20000, - mask_flags: MTD_WRITEABLE /* force read-only */ - } -}; #define NUM_REDWOOD_FLASH_PARTITIONS \ - (sizeof(redwood_flash_partitions)/sizeof(redwood_flash_partitions[0])) + (sizeof(redwood_flash_partitions)/sizeof(redwood_flash_partitions[0])) static struct mtd_info *redwood_mtd; int __init init_redwood_flash(void) { - printk(KERN_NOTICE "redwood: flash mapping: %x at %x\n", - WINDOW_SIZE, WINDOW_ADDR); + printk(KERN_NOTICE "redwood: flash mapping: %x at %x\n", + WINDOW_SIZE, WINDOW_ADDR); - redwood_flash_map.map_priv_1 = - (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE); + redwood_flash_map.virt = + (void __iomem *)ioremap(WINDOW_ADDR, WINDOW_SIZE); - if (!redwood_flash_map.map_priv_1) { - printk("init_redwood_flash: failed to ioremap\n"); - return -EIO; - } - - redwood_mtd = do_map_probe("cfi_probe",&redwood_flash_map); - - if (redwood_mtd) { - redwood_mtd->module = THIS_MODULE; - return add_mtd_partitions(redwood_mtd, - redwood_flash_partitions, - NUM_REDWOOD_FLASH_PARTITIONS); - } + if (!redwood_flash_map.virt) { + printk("init_redwood_flash: failed to ioremap\n"); + return -EIO; + } + simple_map_init(&redwood_flash_map); + + redwood_mtd = do_map_probe("cfi_probe",&redwood_flash_map); + + if (redwood_mtd) { + redwood_mtd->owner = THIS_MODULE; + return add_mtd_partitions(redwood_mtd, + redwood_flash_partitions, + NUM_REDWOOD_FLASH_PARTITIONS); + } - return -ENXIO; + return -ENXIO; } static void __exit cleanup_redwood_flash(void) { - if (redwood_mtd) { - del_mtd_partitions(redwood_mtd); - iounmap((void *)redwood_flash_map.map_priv_1); - map_destroy(redwood_mtd); - } + if (redwood_mtd) { + del_mtd_partitions(redwood_mtd); + /* moved iounmap after map_destroy - armin */ + map_destroy(redwood_mtd); + iounmap((void *)redwood_flash_map.virt); + } } module_init(init_redwood_flash); module_exit(cleanup_redwood_flash); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("MontaVista Software "); +MODULE_DESCRIPTION("MTD map driver for the IBM Redwood reference boards"); Index: drivers/mtd/maps/rpxlite.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/rpxlite.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/rpxlite.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/rpxlite.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -1,5 +1,5 @@ /* - * $Id: rpxlite.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: rpxlite.c,v 1.3 2004/11/03 00:04:44 joff Exp $ * * Handle mapping of the flash on the RPX Lite and CLLF boards */ @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -17,80 +18,31 @@ static struct mtd_info *mymtd; -__u8 rpxlite_read8(struct map_info *map, unsigned long ofs) -{ - return __raw_readb(map->map_priv_1 + ofs); -} - -__u16 rpxlite_read16(struct map_info *map, unsigned long ofs) -{ - return __raw_readw(map->map_priv_1 + ofs); -} - -__u32 rpxlite_read32(struct map_info *map, unsigned long ofs) -{ - return __raw_readl(map->map_priv_1 + ofs); -} - -void rpxlite_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy_fromio(to, (void *)(map->map_priv_1 + from), len); -} - -void rpxlite_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - __raw_writeb(d, map->map_priv_1 + adr); - mb(); -} - -void rpxlite_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - __raw_writew(d, map->map_priv_1 + adr); - mb(); -} - -void rpxlite_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - __raw_writel(d, map->map_priv_1 + adr); - mb(); -} - -void rpxlite_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy_toio((void *)(map->map_priv_1 + to), from, len); -} - -struct map_info rpxlite_map = { - name: "RPX", - size: WINDOW_SIZE, - buswidth: 4, - read8: rpxlite_read8, - read16: rpxlite_read16, - read32: rpxlite_read32, - copy_from: rpxlite_copy_from, - write8: rpxlite_write8, - write16: rpxlite_write16, - write32: rpxlite_write32, - copy_to: rpxlite_copy_to +static struct map_info rpxlite_map = { + .name = "RPX", + .size = WINDOW_SIZE, + .bankwidth = 4, + .phys = WINDOW_ADDR, }; int __init init_rpxlite(void) { printk(KERN_NOTICE "RPX Lite or CLLF flash device: %x at %x\n", WINDOW_SIZE*4, WINDOW_ADDR); - rpxlite_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE * 4); + rpxlite_map.virt = (void __iomem *)ioremap(WINDOW_ADDR, WINDOW_SIZE * 4); - if (!rpxlite_map.map_priv_1) { + if (!rpxlite_map.virt) { printk("Failed to ioremap\n"); return -EIO; } + simple_map_init(&rpxlite_map); mymtd = do_map_probe("cfi_probe", &rpxlite_map); if (mymtd) { - mymtd->module = THIS_MODULE; + mymtd->owner = THIS_MODULE; add_mtd_device(mymtd); return 0; } - iounmap((void *)rpxlite_map.map_priv_1); + iounmap((void *)rpxlite_map.virt); return -ENXIO; } @@ -100,9 +52,9 @@ del_mtd_device(mymtd); map_destroy(mymtd); } - if (rpxlite_map.map_priv_1) { - iounmap((void *)rpxlite_map.map_priv_1); - rpxlite_map.map_priv_1 = 0; + if (rpxlite_map.virt) { + iounmap((void *)rpxlite_map.virt); + rpxlite_map.virt = 0; } } Index: drivers/mtd/maps/sa1100-flash.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/sa1100-flash.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/sa1100-flash.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/sa1100-flash.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -3,7 +3,7 @@ * * (C) 2000 Nicolas Pitre * - * $Id: sa1100-flash.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: sa1100-flash.c,v 1.3 2004/11/03 00:04:44 joff Exp $ */ #include @@ -11,330 +11,212 @@ #include #include #include +#include +#include +#include #include #include #include +#include #include +#include #include +#include +#include #ifndef CONFIG_ARCH_SA1100 #error This is for SA1100 architecture only #endif +/* + * This isnt complete yet, so... + */ +#define CONFIG_MTD_SA1100_STATICMAP 1 -#define WINDOW_ADDR 0xe8000000 - -static __u8 sa1100_read8(struct map_info *map, unsigned long ofs) -{ - return readb(map->map_priv_1 + ofs); -} - -static __u16 sa1100_read16(struct map_info *map, unsigned long ofs) -{ - return readw(map->map_priv_1 + ofs); -} - -static __u32 sa1100_read32(struct map_info *map, unsigned long ofs) -{ - return readl(map->map_priv_1 + ofs); -} - -static void sa1100_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy(to, (void *)(map->map_priv_1 + from), len); -} - -static void sa1100_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - writeb(d, map->map_priv_1 + adr); -} - -static void sa1100_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - writew(d, map->map_priv_1 + adr); -} - -static void sa1100_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - writel(d, map->map_priv_1 + adr); -} - -static void sa1100_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy((void *)(map->map_priv_1 + to), from, len); -} - -static struct map_info sa1100_map = { - name: "SA1100 flash", - read8: sa1100_read8, - read16: sa1100_read16, - read32: sa1100_read32, - copy_from: sa1100_copy_from, - write8: sa1100_write8, - write16: sa1100_write16, - write32: sa1100_write32, - copy_to: sa1100_copy_to, - - map_priv_1: WINDOW_ADDR, - map_priv_2: -1, -}; - - +#ifdef CONFIG_MTD_SA1100_STATICMAP /* * Here are partition information for all known SA1100-based devices. * See include/linux/mtd/partitions.h for definition of the mtd_partition * structure. * - * The *_max_flash_size is the maximum possible mapped flash size which - * is not necessarily the actual flash size. It must be no more than - * the value specified in the "struct map_desc *_io_desc" mapping - * definition for the corresponding machine. + * Please note: + * 1. We no longer support static flash mappings via the machine io_desc + * structure. + * 2. The flash size given should be the largest flash size that can + * be accommodated. + * + * The MTD layer will detect flash chip aliasing and reduce the size of + * the map accordingly. * * Please keep these in alphabetical order, and formatted as per existing * entries. Thanks. */ -#ifdef CONFIG_SA1100_ADSAGC -#define ADSAGC_FLASH_SIZE 0x02000000 -static struct mtd_partition adsagc_partitions[] = { - { - name: "bootROM", - size: 0x80000, - offset: 0, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "zImage", - size: 0x100000, - offset: MTDPART_OFS_APPEND, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "ramdisk.gz", - size: 0x300000, - offset: MTDPART_OFS_APPEND, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "User FS", - size: MTDPART_SIZ_FULL, - offset: MTDPART_OFS_APPEND, - } -}; -#endif - #ifdef CONFIG_SA1100_ADSBITSY -#define ADSBITSY_FLASH_SIZE 0x02000000 static struct mtd_partition adsbitsy_partitions[] = { { - name: "bootROM", - size: 0x80000, - offset: 0, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "zImage", - size: 0x100000, - offset: MTDPART_OFS_APPEND, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "ramdisk.gz", - size: 0x300000, - offset: MTDPART_OFS_APPEND, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "User FS", - size: MTDPART_SIZ_FULL, - offset: MTDPART_OFS_APPEND, - } -}; -#endif - -#ifdef CONFIG_SA1100_ADSBITSYPLUS -#define ADSBITSYPLUS_FLASH_SIZE 0x02000000 -static struct mtd_partition adsbitsyplus_partitions[] = { - { - name: "bootROM", - size: 0x80000, - offset: 0, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "zImage", - size: 0x100000, - offset: MTDPART_OFS_APPEND, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "ramdisk.gz", - size: 0x300000, - offset: MTDPART_OFS_APPEND, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "User FS", - size: MTDPART_SIZ_FULL, - offset: MTDPART_OFS_APPEND, + .name = "bootROM", + .size = 0x80000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "zImage", + .size = 0x100000, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "ramdisk.gz", + .size = 0x300000, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "User FS", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; #endif #ifdef CONFIG_SA1100_ASSABET /* Phase 4 Assabet has two 28F160B3 flash parts in bank 0: */ -#define ASSABET4_FLASH_SIZE 0x00400000 static struct mtd_partition assabet4_partitions[] = { { - name: "bootloader", - size: 0x00020000, - offset: 0, - mask_flags: MTD_WRITEABLE, - }, { - name: "bootloader params", - size: 0x00020000, - offset: MTDPART_OFS_APPEND, - mask_flags: MTD_WRITEABLE, - }, { - name: "jffs", - size: MTDPART_SIZ_FULL, - offset: MTDPART_OFS_APPEND, + .name = "bootloader", + .size = 0x00020000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "bootloader params", + .size = 0x00020000, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "jffs", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; /* Phase 5 Assabet has two 28F128J3A flash parts in bank 0: */ -#define ASSABET5_FLASH_SIZE 0x02000000 static struct mtd_partition assabet5_partitions[] = { { - name: "bootloader", - size: 0x00040000, - offset: 0, - mask_flags: MTD_WRITEABLE, - }, { - name: "bootloader params", - size: 0x00040000, - offset: MTDPART_OFS_APPEND, - mask_flags: MTD_WRITEABLE, - }, { - name: "jffs", - size: MTDPART_SIZ_FULL, - offset: MTDPART_OFS_APPEND, + .name = "bootloader", + .size = 0x00040000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "bootloader params", + .size = 0x00040000, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "jffs", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; -#define ASSABET_FLASH_SIZE ASSABET5_FLASH_SIZE #define assabet_partitions assabet5_partitions #endif #ifdef CONFIG_SA1100_BADGE4 - /* - * 1 x Intel 28F320C3BA100 Advanced+ Boot Block Flash (32 Mi bit) + * 1 x Intel 28F320C3 Advanced+ Boot Block Flash (32 Mi bit) * Eight 4 KiW Parameter Bottom Blocks (64 KiB) * Sixty-three 32 KiW Main Blocks (4032 Ki b) + * + * + * + * 1 x Intel 28F640C3 Advanced+ Boot Block Flash (64 Mi bit) + * Eight 4 KiW Parameter Bottom Blocks (64 KiB) + * One-hundred-twenty-seven 32 KiW Main Blocks (8128 Ki b) */ -#define BADGE4_FLASH_SIZE 0x00400000 static struct mtd_partition badge4_partitions[] = { { - name: "BLOB boot loader", - offset: 0, - size: 0x0000A000 - }, { - name: "params", - offset: MTDPART_OFS_APPEND, - size: 0x00006000 - }, { - name: "kernel", - offset: MTDPART_OFS_APPEND, - size: 0x00100000 - }, { - name: "root", - offset: MTDPART_OFS_APPEND, - size: MTDPART_SIZ_FULL + .name = "BLOB boot loader", + .offset = 0, + .size = 0x0000A000 + }, { + .name = "params", + .offset = MTDPART_OFS_APPEND, + .size = 0x00006000 + }, { + .name = "root", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL } }; - #endif #ifdef CONFIG_SA1100_CERF #ifdef CONFIG_SA1100_CERF_FLASH_32MB -#define CERF_FLASH_SIZE 0x02000000 -static struct mtd_partition cerf_partitions[] = { - { - name: "firmware", - size: 0x00040000, - offset: 0, - }, { - name: "params", - size: 0x00040000, - offset: 0x00040000, - }, { - name: "kernel", - size: 0x00100000, - offset: 0x00080000, - }, { - name: "rootdisk", - size: 0x01E80000, - offset: 0x00180000, - } -}; +# define CERF_FLASH_SIZE 0x02000000 #elif defined CONFIG_SA1100_CERF_FLASH_16MB -#define CERF_FLASH_SIZE 0x01000000 +# define CERF_FLASH_SIZE 0x01000000 +#elif defined CONFIG_SA1100_CERF_FLASH_8MB +# define CERF_FLASH_SIZE 0x00800000 +#else +# error "Undefined flash size for CERF in sa1100-flash.c" +#endif + static struct mtd_partition cerf_partitions[] = { { - name: "firmware", - size: 0x00020000, - offset: 0, - }, { - name: "params", - size: 0x00020000, - offset: 0x00020000, - }, { - name: "kernel", - size: 0x00100000, - offset: 0x00040000, - }, { - name: "rootdisk", - size: 0x00EC0000, - offset: 0x00140000, + .name = "Bootloader", + .size = 0x00020000, + .offset = 0x00000000, + }, { + .name = "Params", + .size = 0x00040000, + .offset = 0x00020000, + }, { + .name = "Kernel", + .size = 0x00100000, + .offset = 0x00060000, + }, { + .name = "Filesystem", + .size = CERF_FLASH_SIZE-0x00160000, + .offset = 0x00160000, } }; -#elif defined CONFIG_SA1100_CERF_FLASH_8MB -# error "Unwritten type definition" -#else -# error "Undefined memory orientation for CERF in sa1100-flash.c" -#endif #endif #ifdef CONFIG_SA1100_CONSUS -#define CONSUS_FLASH_SIZE 0x02000000 static struct mtd_partition consus_partitions[] = { { - name: "Consus boot firmware", - offset: 0, - size: 0x00040000, - mask_flags: MTD_WRITABLE, /* force read-only */ - }, { - name: "Consus kernel", - offset: 0x00040000, - size: 0x00100000, - mask_flags: 0, + .name = "Consus boot firmware", + .offset = 0, + .size = 0x00040000, + .mask_flags = MTD_WRITABLE, /* force read-only */ + }, { + .name = "Consus kernel", + .offset = 0x00040000, + .size = 0x00100000, + .mask_flags = 0, }, { - name: "Consus disk", - offset: 0x00140000, + .name = "Consus disk", + .offset = 0x00140000, /* The rest (up to 16M) for jffs. We could put 0 and make it find the size automatically, but right now i have 32 megs. jffs will use all 32 megs if given the chance, and this leads to horrible problems when you try to re-flash the image because blob won't erase the whole partition. */ - size: 0x01000000 - 0x00140000, - mask_flags: 0, + .size = 0x01000000 - 0x00140000, + .mask_flags = 0, }, { /* this disk is a secondary disk, which can be used as needed, for simplicity, make it the size of the other consus partition, although realistically it could be the remainder of the disk (depending on the file system used) */ - name: "Consus disk2", - offset: 0x01000000, - size: 0x01000000 - 0x00140000, - mask_flags: 0, + .name = "Consus disk2", + .offset = 0x01000000, + .size = 0x01000000 - 0x00140000, + .mask_flags = 0, } }; #endif @@ -344,96 +226,95 @@ #define FLEXANET_FLASH_SIZE 0x02000000 static struct mtd_partition flexanet_partitions[] = { { - name: "bootloader", - size: 0x00040000, - offset: 0, - mask_flags: MTD_WRITEABLE, - }, { - name: "bootloader params", - size: 0x00040000, - offset: MTDPART_OFS_APPEND, - mask_flags: MTD_WRITEABLE, - }, { - name: "kernel", - size: 0x000C0000, - offset: MTDPART_OFS_APPEND, - mask_flags: MTD_WRITEABLE, - }, { - name: "altkernel", - size: 0x000C0000, - offset: MTDPART_OFS_APPEND, - mask_flags: MTD_WRITEABLE, - }, { - name: "root", - size: 0x00400000, - offset: MTDPART_OFS_APPEND, - mask_flags: MTD_WRITEABLE, - }, { - name: "free1", - size: 0x00300000, - offset: MTDPART_OFS_APPEND, - mask_flags: MTD_WRITEABLE, - }, { - name: "free2", - size: 0x00300000, - offset: MTDPART_OFS_APPEND, - mask_flags: MTD_WRITEABLE, - }, { - name: "free3", - size: MTDPART_SIZ_FULL, - offset: MTDPART_OFS_APPEND, - mask_flags: MTD_WRITEABLE, + .name = "bootloader", + .size = 0x00040000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "bootloader params", + .size = 0x00040000, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "kernel", + .size = 0x000C0000, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "altkernel", + .size = 0x000C0000, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "root", + .size = 0x00400000, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "free1", + .size = 0x00300000, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "free2", + .size = 0x00300000, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "free3", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, } }; #endif #ifdef CONFIG_SA1100_FREEBIRD -#define FREEBIRD_FLASH_SIZE 0x02000000 static struct mtd_partition freebird_partitions[] = { -#if CONFIG_SA1100_FREEBIRD_NEW +#ifdef CONFIG_SA1100_FREEBIRD_NEW { - name: "firmware", - size: 0x00040000, - offset: 0, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "kernel", - size: 0x00080000, - offset: 0x00040000, - }, { - name: "params", - size: 0x00040000, - offset: 0x000C0000, - }, { - name: "initrd", - size: 0x00100000, - offset: 0x00100000, - }, { - name: "root cramfs", - size: 0x00300000, - offset: 0x00200000, - }, { - name: "usr cramfs", - size: 0x00C00000, - offset: 0x00500000, - }, { - name: "local", - size: MTDPART_SIZ_FULL, - offset: 0x01100000, + .name = "firmware", + .size = 0x00040000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "kernel", + .size = 0x00080000, + .offset = 0x00040000, + }, { + .name = "params", + .size = 0x00040000, + .offset = 0x000C0000, + }, { + .name = "initrd", + .size = 0x00100000, + .offset = 0x00100000, + }, { + .name = "root cramfs", + .size = 0x00300000, + .offset = 0x00200000, + }, { + .name = "usr cramfs", + .size = 0x00C00000, + .offset = 0x00500000, + }, { + .name = "local", + .size = MTDPART_SIZ_FULL, + .offset = 0x01100000, } #else { - size: 0x00040000, - offset: 0, + .size = 0x00040000, + .offset = 0, }, { - size: 0x000c0000, - offset: MTDPART_OFS_APPEND, + .size = 0x000c0000, + .offset = MTDPART_OFS_APPEND, }, { - size: 0x00400000, - offset: MTDPART_OFS_APPEND, + .size = 0x00400000, + .offset = MTDPART_OFS_APPEND, }, { - size: MTDPART_SIZ_FULL, - offset: MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } #endif }; @@ -441,206 +322,237 @@ #ifdef CONFIG_SA1100_FRODO /* Frodo has 2 x 16M 28F128J3A flash chips in bank 0: */ -#define FRODO_FLASH_SIZE 0x02000000 static struct mtd_partition frodo_partitions[] = { { - name: "Boot Loader", - size: 0x00040000, - offset: 0x00000000 - }, { - name: "Parameter Block", - size: 0x00040000, - offset: MTDPART_OFS_APPEND - }, { - name: "Linux Kernel", - size: 0x00100000, - offset: MTDPART_OFS_APPEND - }, { - name: "Ramdisk", - size: 0x00680000, - offset: MTDPART_OFS_APPEND - }, { - name: "Flash File System", - size: MTDPART_SIZ_FULL, - offset: MTDPART_OFS_APPEND + .name = "bootloader", + .size = 0x00040000, + .offset = 0x00000000, + .mask_flags = MTD_WRITEABLE + }, { + .name = "bootloader params", + .size = 0x00040000, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE + }, { + .name = "kernel", + .size = 0x00100000, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE + }, { + .name = "ramdisk", + .size = 0x00400000, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE + }, { + .name = "file system", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND } }; #endif #ifdef CONFIG_SA1100_GRAPHICSCLIENT -#define GRAPHICSCLIENT_FLASH_SIZE 0x02000000 static struct mtd_partition graphicsclient_partitions[] = { { - name: "zImage", - size: 0x100000, - offset: 0, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "ramdisk.gz", - size: 0x300000, - offset: MTDPART_OFS_APPEND, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "User FS", - size: MTDPART_SIZ_FULL, - offset: MTDPART_OFS_APPEND, + .name = "zImage", + .size = 0x100000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "ramdisk.gz", + .size = 0x300000, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "User FS", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; #endif #ifdef CONFIG_SA1100_GRAPHICSMASTER -#define GRAPHICSMASTER_FLASH_SIZE 0x02000000 static struct mtd_partition graphicsmaster_partitions[] = { { - name: "zImage", - size: 0x100000, - offset: 0, - mask_flags: MTD_WRITEABLE, /* force read-only */ + .name = "zImage", + .size = 0x100000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ }, { - name: "ramdisk.gz", - size: 0x300000, - offset: MTDPART_OFS_APPEND, - mask_flags: MTD_WRITEABLE, /* force read-only */ + .name = "ramdisk.gz", + .size = 0x300000, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, /* force read-only */ }, { - name: "User FS", - size: MTDPART_SIZ_FULL, - offset: MTDPART_OFS_APPEND, + .name = "User FS", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; #endif -#ifdef CONFIG_SA1100_H3600 -#define H3600_FLASH_SIZE 0x02000000 -static struct mtd_partition h3600_partitions[] = { +#ifdef CONFIG_SA1100_H3XXX +static struct mtd_partition h3xxx_partitions[] = { { - name: "H3600 boot firmware", - size: 0x00040000, - offset: 0, - mask_flags: MTD_WRITEABLE, /* force read-only */ + .name = "H3XXX boot firmware", + .size = 0x00040000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ }, { - name: "H3600 kernel", - size: 0x00080000, - offset: 0x00040000, - }, { - name: "H3600 params", - size: 0x00040000, - offset: 0x000C0000, +#ifdef CONFIG_MTD_2PARTS_IPAQ + .name = "H3XXX root jffs2", + .size = MTDPART_SIZ_FULL, + .offset = 0x00040000, +#else + .name = "H3XXX kernel", + .size = 0x00080000, + .offset = 0x00040000, + }, { + .name = "H3XXX params", + .size = 0x00040000, + .offset = 0x000C0000, }, { #ifdef CONFIG_JFFS2_FS - name: "H3600 root jffs2", - size: MTDPART_SIZ_FULL, - offset: 0x00100000, + .name = "H3XXX root jffs2", + .size = MTDPART_SIZ_FULL, + .offset = 0x00100000, #else - name: "H3600 initrd", - size: 0x00100000, - offset: 0x00100000, + .name = "H3XXX initrd", + .size = 0x00100000, + .offset = 0x00100000, }, { - name: "H3600 root cramfs", - size: 0x00300000, - offset: 0x00200000, + .name = "H3XXX root cramfs", + .size = 0x00300000, + .offset = 0x00200000, }, { - name: "H3600 usr cramfs", - size: 0x00800000, - offset: 0x00500000, + .name = "H3XXX usr cramfs", + .size = 0x00800000, + .offset = 0x00500000, }, { - name: "H3600 usr local", - size: MTDPART_SIZ_FULL, - offset: 0x00d00000, + .name = "H3XXX usr local", + .size = MTDPART_SIZ_FULL, + .offset = 0x00d00000, +#endif #endif } }; -static void h3600_set_vpp(struct map_info *map, int vpp) +static void h3xxx_set_vpp(struct map_info *map, int vpp) { assign_h3600_egpio(IPAQ_EGPIO_VPP_ON, vpp); } +#else +#define h3xxx_set_vpp NULL #endif #ifdef CONFIG_SA1100_HACKKIT -#define HACKKIT_FLASH_SIZE 0x01000000 static struct mtd_partition hackkit_partitions[] = { { - name: "BLOB", - size: 0x00040000, - offset: 0x00000000, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "config", - size: 0x00040000, - offset: MTDPART_OFS_APPEND, - }, { - name: "kernel", - size: 0x00100000, - offset: MTDPART_OFS_APPEND, - }, { - name: "initrd", - size: 0x00180000, - offset: MTDPART_OFS_APPEND, - }, { - name: "rootfs", - size: 0x700000, - offset: MTDPART_OFS_APPEND, - }, { - name: "data", - size: MTDPART_SIZ_FULL, - offset: MTDPART_OFS_APPEND, + .name = "BLOB", + .size = 0x00040000, + .offset = 0x00000000, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "config", + .size = 0x00040000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "kernel", + .size = 0x00100000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "initrd", + .size = 0x00180000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "rootfs", + .size = 0x700000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "data", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; #endif #ifdef CONFIG_SA1100_HUW_WEBPANEL -#define HUW_WEBPANEL_FLASH_SIZE 0x01000000 static struct mtd_partition huw_webpanel_partitions[] = { { - name: "Loader", - size: 0x00040000, - offset: 0, - }, { - name: "Sector 1", - size: 0x00040000, - offset: MTDPART_OFS_APPEND, + .name = "Loader", + .size = 0x00040000, + .offset = 0, }, { - size: MTDPART_SIZ_FULL, - offset: MTDPART_OFS_APPEND, + .name = "Sector 1", + .size = 0x00040000, + .offset = MTDPART_OFS_APPEND, + }, { + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; #endif +#ifdef CONFIG_SA1100_JORNADA56X +static struct mtd_partition jornada56x_partitions[] = { + { + .name = "bootldr", + .size = 0x00040000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "rootfs", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; + +static void jornada56x_set_vpp(struct map_info *map, int vpp) +{ + if (vpp) + GPSR = GPIO_GPIO26; + else + GPCR = GPIO_GPIO26; + GPDR |= GPIO_GPIO26; +} +#else +#define jornada56x_set_vpp NULL +#endif + #ifdef CONFIG_SA1100_JORNADA720 -#define JORNADA720_FLASH_SIZE 0x02000000 static struct mtd_partition jornada720_partitions[] = { { - name: "JORNADA720 boot firmware", - size: 0x00040000, - offset: 0, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "JORNADA720 kernel", - size: 0x000c0000, - offset: 0x00040000, - }, { - name: "JORNADA720 params", - size: 0x00040000, - offset: 0x00100000, - }, { - name: "JORNADA720 initrd", - size: 0x00100000, - offset: 0x00140000, - }, { - name: "JORNADA720 root cramfs", - size: 0x00300000, - offset: 0x00240000, - }, { - name: "JORNADA720 usr cramfs", - size: 0x00800000, - offset: 0x00540000, - }, { - name: "JORNADA720 usr local", - size: 0, /* will expand to the end of the flash */ - offset: 0x00d00000, + .name = "JORNADA720 boot firmware", + .size = 0x00040000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "JORNADA720 kernel", + .size = 0x000c0000, + .offset = 0x00040000, + }, { + .name = "JORNADA720 params", + .size = 0x00040000, + .offset = 0x00100000, + }, { + .name = "JORNADA720 initrd", + .size = 0x00100000, + .offset = 0x00140000, + }, { + .name = "JORNADA720 root cramfs", + .size = 0x00300000, + .offset = 0x00240000, + }, { + .name = "JORNADA720 usr cramfs", + .size = 0x00800000, + .offset = 0x00540000, + }, { + .name = "JORNADA720 usr local", + .size = 0, /* will expand to the end of the flash */ + .offset = 0x00d00000, } }; @@ -652,540 +564,820 @@ PPSR &= ~0x80; PPDR |= 0x80; } - -#endif - -#ifdef CONFIG_SA1100_NANOENGINE -/* nanoEngine has one 28F320B3B Flash part in bank 0: */ -#define NANOENGINE_FLASH_SIZE 0x00400000 -static struct mtd_partition nanoengine_partitions[] = { - { - name: "nanoEngine boot firmware and parameter table", - size: 0x00010000, /* 32K */ - offset: 0x00000000, - mask_flags: MTD_WRITEABLE, /* force read-only */ - },{ - name: "kernel/initrd reserved", - size: 0x002f0000, - offset: 0x00010000, - },{ - name: "experimental filesystem allocation", - size: 0x00100000, - offset: 0x00300000, - } -}; +#else +#define jornada720_set_vpp NULL #endif #ifdef CONFIG_SA1100_PANGOLIN -#define PANGOLIN_FLASH_SIZE 0x04000000 static struct mtd_partition pangolin_partitions[] = { { - name: "boot firmware", - size: 0x00080000, - offset: 0x00000000, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "kernel", - size: 0x00100000, - offset: 0x00080000, - }, { - name: "initrd", - size: 0x00280000, - offset: 0x00180000, - }, { - name: "initrd-test", - size: 0x03C00000, - offset: 0x00400000, + .name = "boot firmware", + .size = 0x00080000, + .offset = 0x00000000, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "kernel", + .size = 0x00100000, + .offset = 0x00080000, + }, { + .name = "initrd", + .size = 0x00280000, + .offset = 0x00180000, + }, { + .name = "initrd-test", + .size = 0x03C00000, + .offset = 0x00400000, } }; #endif #ifdef CONFIG_SA1100_PT_SYSTEM3 /* erase size is 0x40000 == 256k partitions have to have this boundary */ -#define SYSTEM3_FLASH_SIZE 0x01000000 static struct mtd_partition system3_partitions[] = { { - name: "BLOB", - size: 0x00040000, - offset: 0x00000000, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "config", - size: 0x00040000, - offset: MTDPART_OFS_APPEND, - }, { - name: "kernel", - size: 0x00100000, - offset: MTDPART_OFS_APPEND, - }, { - name: "root", - size: MTDPART_SIZ_FULL, - offset: MTDPART_OFS_APPEND, + .name = "BLOB", + .size = 0x00040000, + .offset = 0x00000000, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "config", + .size = 0x00040000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "kernel", + .size = 0x00100000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "root", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; #endif #ifdef CONFIG_SA1100_SHANNON -#define SHANNON_FLASH_SIZE 0x00400000 static struct mtd_partition shannon_partitions[] = { { - name: "BLOB boot loader", - offset: 0, - size: 0x20000 + .name = "BLOB boot loader", + .offset = 0, + .size = 0x20000 }, { - name: "kernel", - offset: MTDPART_OFS_APPEND, - size: 0xe0000 + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = 0xe0000 }, { - name: "initrd", - offset: MTDPART_OFS_APPEND, - size: MTDPART_SIZ_FULL + .name = "initrd", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL } }; #endif #ifdef CONFIG_SA1100_SHERMAN -#define SHERMAN_FLASH_SIZE 0x02000000 static struct mtd_partition sherman_partitions[] = { { - size: 0x50000, - offset: 0, + .size = 0x50000, + .offset = 0, }, { - size: 0x70000, - offset: MTDPART_OFS_APPEND, + .size = 0x70000, + .offset = MTDPART_OFS_APPEND, }, { - size: 0x600000, - offset: MTDPART_OFS_APPEND, + .size = 0x600000, + .offset = MTDPART_OFS_APPEND, }, { - size: 0xA0000, - offset: MTDPART_OFS_APPEND, + .size = 0xA0000, + .offset = MTDPART_OFS_APPEND, } }; #endif #ifdef CONFIG_SA1100_SIMPAD -#define SIMPAD_FLASH_SIZE 0x02000000 static struct mtd_partition simpad_partitions[] = { { - name: "SIMpad boot firmware", - size: 0x00080000, - offset: 0, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "SIMpad kernel", - size: 0x00100000, - offset: 0x00080000, - }, { -#ifdef CONFIG_JFFS2_FS - name: "SIMpad root jffs2", - size: MTDPART_SIZ_FULL, - offset: 0x00180000, + .name = "SIMpad boot firmware", + .size = 0x00080000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "SIMpad kernel", + .size = 0x00100000, + .offset = MTDPART_OFS_APPEND, + }, { +#ifdef CONFIG_ROOT_CRAMFS + .name = "SIMpad root cramfs", + .size =0x00D80000, + .offset = MTDPART_OFS_APPEND + + }, { + .name = "SIMpad local jffs2", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND #else - name: "SIMpad initrd", - size: 0x00300000, - offset: 0x00180000, - }, { - name: "SIMpad root cramfs", - size: 0x00300000, - offset: 0x00480000, - }, { - name: "SIMpad usr cramfs", - size: 0x005c0000, - offset: 0x00780000, - }, { - name: "SIMpad usr local", - size: MTDPART_SIZ_FULL, - offset: 0x00d40000, + .name = "SIMpad root jffs2", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND #endif } }; #endif /* CONFIG_SA1100_SIMPAD */ -#ifdef CONFIG_SA1100_SIMPUTER -#define SIMPUTER_FLASH_SIZE 0x02000000 -static struct mtd_partition simputer_partitions[] = { - { - name: "blob+logo", - offset: 0, - size: 0x00040000 - }, - { - name: "kernel", - offset: MTDPART_OFS_APPEND, - size: 0x000C0000 - }, - { - name: "/(cramfs)", - offset: MTDPART_OFS_APPEND, - size: 0x00200000 - }, - { - name: "/usr/local(jffs2)", - offset: MTDPART_OFS_APPEND, - size: MTDPART_SIZ_FULL /* expand till the end */ - } -}; -#endif - #ifdef CONFIG_SA1100_STORK -#define STORK_FLASH_SIZE 0x02000000 static struct mtd_partition stork_partitions[] = { { - name: "STORK boot firmware", - size: 0x00040000, - offset: 0, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "STORK params", - size: 0x00040000, - offset: 0x00040000, - }, { - name: "STORK kernel", - size: 0x00100000, - offset: 0x00080000, + .name = "STORK boot firmware", + .size = 0x00040000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "STORK params", + .size = 0x00040000, + .offset = 0x00040000, + }, { + .name = "STORK kernel", + .size = 0x00100000, + .offset = 0x00080000, }, { #ifdef CONFIG_JFFS2_FS - name: "STORK root jffs2", - offset: 0x00180000, - size: MTDPART_SIZ_FULL, + .name = "STORK root jffs2", + .offset = 0x00180000, + .size = MTDPART_SIZ_FULL, #else - name: "STORK initrd", - size: 0x00100000, - offset: 0x00180000, - }, { - name: "STORK root cramfs", - size: 0x00300000, - offset: 0x00280000, - }, { - name: "STORK usr cramfs", - size: 0x00800000, - offset: 0x00580000, - }, { - name: "STORK usr local", - offset: 0x00d80000, - size: MTDPART_SIZ_FULL, + .name = "STORK initrd", + .size = 0x00100000, + .offset = 0x00180000, + }, { + .name = "STORK root cramfs", + .size = 0x00300000, + .offset = 0x00280000, + }, { + .name = "STORK usr cramfs", + .size = 0x00800000, + .offset = 0x00580000, + }, { + .name = "STORK usr local", + .offset = 0x00d80000, + .size = MTDPART_SIZ_FULL, #endif } }; #endif +#ifdef CONFIG_SA1100_TRIZEPS +static struct mtd_partition trizeps_partitions[] = { + { + .name = "Bootloader", + .size = 0x00100000, + .offset = 0, + }, { + .name = "Kernel", + .size = 0x00100000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "root", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; +#endif + #ifdef CONFIG_SA1100_YOPY -#define YOPY_FLASH_SIZE 0x08000000 static struct mtd_partition yopy_partitions[] = { { - name: "boot firmware", - size: 0x00040000, - offset: 0x00000000, - mask_flags: MTD_WRITEABLE, /* force read-only */ + .name = "boot firmware", + .size = 0x00040000, + .offset = 0x00000000, + .mask_flags = MTD_WRITEABLE, /* force read-only */ }, { - name: "kernel", - size: 0x00080000, - offset: 0x00080000, + .name = "kernel", + .size = 0x00080000, + .offset = 0x00080000, }, { - name: "initrd", - size: 0x00300000, - offset: 0x00100000, + .name = "initrd", + .size = 0x00300000, + .offset = 0x00100000, }, { - name: "root", - size: 0x01000000, - offset: 0x00400000, + .name = "root", + .size = 0x01000000, + .offset = 0x00400000, } }; #endif -extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts); -extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, char *); - -static struct mtd_partition *parsed_parts; -static struct mtd_info *mymtd; - -int __init sa1100_mtd_init(void) +static int __init sa1100_static_partitions(struct mtd_partition **parts) { - struct mtd_partition *parts; - int nb_parts = 0, ret; - int parsed_nr_parts = 0; - const char *part_type; - unsigned long base = -1UL; - - /* Default flash buswidth */ - sa1100_map.buswidth = (MSC0 & MSC_RBW) ? 2 : 4; + int nb_parts = 0; - /* - * Static partition definition selection - */ - part_type = "static"; - -#ifdef CONFIG_SA1100_ADSAGC - if (machine_is_adsagc()) { - parts = adsagc_partitions; - nb_parts = ARRAY_SIZE(adsagc_partitions); - sa1100_map.size = ADSAGC_FLASH_SIZE; - sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2 : 4; - } -#endif #ifdef CONFIG_SA1100_ADSBITSY if (machine_is_adsbitsy()) { - parts = adsbitsy_partitions; - nb_parts = ARRAY_SIZE(adsbitsy_partitions); - sa1100_map.size = ADSBITSY_FLASH_SIZE; - sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2 : 4; - } -#endif -#ifdef CONFIG_SA1100_ADSBITSYPLUS - if (machine_is_adsbitsyplus()) { - parts = adsbitsyplus_partitions; - nb_parts = ARRAY_SIZE(adsbitsyplus_partitions); - sa1100_map.size = ADSBITSYPLUS_FLASH_SIZE; - sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2 : 4; + *parts = adsbitsy_partitions; + nb_parts = ARRAY_SIZE(adsbitsy_partitions); } #endif #ifdef CONFIG_SA1100_ASSABET if (machine_is_assabet()) { - parts = assabet_partitions; - nb_parts = ARRAY_SIZE(assabet_partitions); - sa1100_map.size = ASSABET_FLASH_SIZE; + *parts = assabet_partitions; + nb_parts = ARRAY_SIZE(assabet_partitions); } #endif #ifdef CONFIG_SA1100_BADGE4 if (machine_is_badge4()) { - parts = badge4_partitions; - nb_parts = ARRAY_SIZE(badge4_partitions); - sa1100_map.size = BADGE4_FLASH_SIZE; + *parts = badge4_partitions; + nb_parts = ARRAY_SIZE(badge4_partitions); } #endif #ifdef CONFIG_SA1100_CERF if (machine_is_cerf()) { - parts = cerf_partitions; - nb_parts = ARRAY_SIZE(cerf_partitions); - sa1100_map.size = CERF_FLASH_SIZE; + *parts = cerf_partitions; + nb_parts = ARRAY_SIZE(cerf_partitions); } #endif #ifdef CONFIG_SA1100_CONSUS if (machine_is_consus()) { - parts = consus_partitions; - nb_parts = ARRAY_SIZE(consus_partitions); - sa1100_map.size = CONSUS_FLASH_SIZE; + *parts = consus_partitions; + nb_parts = ARRAY_SIZE(consus_partitions); } #endif #ifdef CONFIG_SA1100_FLEXANET if (machine_is_flexanet()) { - parts = flexanet_partitions; - nb_parts = ARRAY_SIZE(flexanet_partitions); - sa1100_map.size = FLEXANET_FLASH_SIZE; + *parts = flexanet_partitions; + nb_parts = ARRAY_SIZE(flexanet_partitions); } #endif #ifdef CONFIG_SA1100_FREEBIRD if (machine_is_freebird()) { - parts = freebird_partitions; - nb_parts = ARRAY_SIZE(freebird_partitions); - sa1100_map.size = FREEBIRD_FLASH_SIZE; + *parts = freebird_partitions; + nb_parts = ARRAY_SIZE(freebird_partitions); } #endif #ifdef CONFIG_SA1100_FRODO if (machine_is_frodo()) { - parts = frodo_partitions; - nb_parts = ARRAY_SIZE(frodo_partitions); - sa1100_map.size = FRODO_FLASH_SIZE; - base = 0x00000000; + *parts = frodo_partitions; + nb_parts = ARRAY_SIZE(frodo_partitions); } -#endif +#endif #ifdef CONFIG_SA1100_GRAPHICSCLIENT if (machine_is_graphicsclient()) { - parts = graphicsclient_partitions; - nb_parts = ARRAY_SIZE(graphicsclient_partitions); - sa1100_map.size = GRAPHICSCLIENT_FLASH_SIZE; - sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2:4; + *parts = graphicsclient_partitions; + nb_parts = ARRAY_SIZE(graphicsclient_partitions); } #endif #ifdef CONFIG_SA1100_GRAPHICSMASTER if (machine_is_graphicsmaster()) { - parts = graphicsmaster_partitions; - nb_parts = ARRAY_SIZE(graphicsmaster_partitions); - sa1100_map.size = GRAPHICSMASTER_FLASH_SIZE; - sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2:4; + *parts = graphicsmaster_partitions; + nb_parts = ARRAY_SIZE(graphicsmaster_partitions); } #endif -#ifdef CONFIG_SA1100_H3600 - if (machine_is_h3600()) { - parts = h3600_partitions; - nb_parts = ARRAY_SIZE(h3600_partitions); - sa1100_map.size = H3600_FLASH_SIZE; - sa1100_map.set_vpp = h3600_set_vpp; +#ifdef CONFIG_SA1100_H3XXX + if (machine_is_h3xxx()) { + *parts = h3xxx_partitions; + nb_parts = ARRAY_SIZE(h3xxx_partitions); } #endif #ifdef CONFIG_SA1100_HACKKIT if (machine_is_hackkit()) { - parts = hackkit_partitions; + *parts = hackkit_partitions; nb_parts = ARRAY_SIZE(hackkit_partitions); - sa1100_map.size = HACKKIT_FLASH_SIZE; } #endif #ifdef CONFIG_SA1100_HUW_WEBPANEL if (machine_is_huw_webpanel()) { - parts = huw_webpanel_partitions; - nb_parts = ARRAY_SIZE(huw_webpanel_partitions); - sa1100_map.size = HUW_WEBPANEL_FLASH_SIZE; + *parts = huw_webpanel_partitions; + nb_parts = ARRAY_SIZE(huw_webpanel_partitions); } #endif -#ifdef CONFIG_SA1100_JORNADA720 - if (machine_is_jornada720()) { - parts = jornada720_partitions; - nb_parts = ARRAY_SIZE(jornada720_partitions); - sa1100_map.size = JORNADA720_FLASH_SIZE; - sa1100_map.set_vpp = jornada720_set_vpp; +#ifdef CONFIG_SA1100_JORNADA56X + if (machine_is_jornada56x()) { + *parts = jornada56x_partitions; + nb_parts = ARRAY_SIZE(jornada56x_partitions); } #endif -#ifdef CONFIG_SA1100_NANOENGINE - if (machine_is_nanoengine()) { - parts = nanoengine_partitions; - nb_parts = ARRAY_SIZE(nanoengine_partitions); - sa1100_map.size = NANOENGINE_FLASH_SIZE; +#ifdef CONFIG_SA1100_JORNADA720 + if (machine_is_jornada720()) { + *parts = jornada720_partitions; + nb_parts = ARRAY_SIZE(jornada720_partitions); } #endif #ifdef CONFIG_SA1100_PANGOLIN if (machine_is_pangolin()) { - parts = pangolin_partitions; - nb_parts = ARRAY_SIZE(pangolin_partitions); - sa1100_map.size = PANGOLIN_FLASH_SIZE; + *parts = pangolin_partitions; + nb_parts = ARRAY_SIZE(pangolin_partitions); } #endif #ifdef CONFIG_SA1100_PT_SYSTEM3 if (machine_is_pt_system3()) { - parts = system3_partitions; - nb_parts = ARRAY_SIZE(system3_partitions); - sa1100_map.size = SYSTEM3_FLASH_SIZE; + *parts = system3_partitions; + nb_parts = ARRAY_SIZE(system3_partitions); } #endif #ifdef CONFIG_SA1100_SHANNON if (machine_is_shannon()) { - parts = shannon_partitions; - nb_parts = ARRAY_SIZE(shannon_partitions); - sa1100_map.size = SHANNON_FLASH_SIZE; + *parts = shannon_partitions; + nb_parts = ARRAY_SIZE(shannon_partitions); } #endif #ifdef CONFIG_SA1100_SHERMAN if (machine_is_sherman()) { - parts = sherman_partitions; - nb_parts = ARRAY_SIZE(sherman_partitions); - sa1100_map.size = SHERMAN_FLASH_SIZE; + *parts = sherman_partitions; + nb_parts = ARRAY_SIZE(sherman_partitions); } #endif #ifdef CONFIG_SA1100_SIMPAD if (machine_is_simpad()) { - parts = simpad_partitions; - nb_parts = ARRAY_SIZE(simpad_partitions); - sa1100_map.size = SIMPAD_FLASH_SIZE; - } -#endif -#ifdef CONFIG_SA1100_SIMPUTER - if (machine_is_simputer()) { - parts = simputer_partitions; - nb_parts = ARRAY_SIZE(simputer_partitions); - sa1100_map.size = SIMPUTER_FLASH_SIZE; + *parts = simpad_partitions; + nb_parts = ARRAY_SIZE(simpad_partitions); } #endif #ifdef CONFIG_SA1100_STORK if (machine_is_stork()) { - parts = stork_partitions; - nb_parts = ARRAY_SIZE(stork_partitions); - sa1100_map.size = STORK_FLASH_SIZE; + *parts = stork_partitions; + nb_parts = ARRAY_SIZE(stork_partitions); + } +#endif +#ifdef CONFIG_SA1100_TRIZEPS + if (machine_is_trizeps()) { + *parts = trizeps_partitions; + nb_parts = ARRAY_SIZE(trizeps_partitions); } #endif #ifdef CONFIG_SA1100_YOPY if (machine_is_yopy()) { - parts = yopy_partitions; - nb_parts = ARRAY_SIZE(yopy_partitions); - sa1100_map.size = YOPY_FLASH_SIZE; + *parts = yopy_partitions; + nb_parts = ARRAY_SIZE(yopy_partitions); } #endif + return nb_parts; +} +#endif + +struct sa_info { + unsigned long base; + unsigned long size; + int width; + void (*set_vpp)(struct map_info *, int); + char name[16]; + struct map_info *map; + struct mtd_info *mtd; +}; + +#define NR_SUBMTD 4 + +static struct sa_info info[NR_SUBMTD]; + +static int __init sa1100_setup_mtd(struct sa_info *sa, int nr, struct mtd_info **rmtd) +{ + struct mtd_info *subdev[nr]; + struct map_info *maps; + int i, found = 0, ret = 0; + /* - * For simple flash devices, use ioremap to map the flash. + * Allocate the map_info structs in one go. */ - if (base != (unsigned long)-1) { - if (!request_mem_region(base, sa1100_map.size, "flash")) - return -EBUSY; - sa1100_map.map_priv_2 = base; - sa1100_map.map_priv_1 = (unsigned long) - ioremap(base, sa1100_map.size); - ret = -ENOMEM; - if (!sa1100_map.map_priv_1) - goto out_err; - } + maps = kmalloc(sizeof(struct map_info) * nr, GFP_KERNEL); + if (!maps) + return -ENOMEM; + + memset(maps, 0, sizeof(struct map_info) * nr); /* - * Now let's probe for the actual flash. Do it here since - * specific machine settings might have been set above. + * Claim and then map the memory regions. */ - printk(KERN_NOTICE "SA1100 flash: probing %d-bit flash bus\n", sa1100_map.buswidth*8); - mymtd = do_map_probe("jedec_probe", &sa1100_map); - if (!mymtd) - mymtd = do_map_probe("cfi_probe", &sa1100_map); - ret = -ENXIO; - if (!mymtd) - goto out_err; - mymtd->module = THIS_MODULE; + for (i = 0; i < nr; i++) { + if (sa[i].base == (unsigned long)-1) + break; + + sa[i].map = maps + i; + sa[i].map->name = sa[i].name; + sprintf(sa[i].name, "sa1100-%d", i); + + if (!request_mem_region(sa[i].base, sa[i].size, sa[i].name)) { + i -= 1; + ret = -EBUSY; + break; + } + + sa[i].map->virt = ioremap(sa[i].base, sa[i].size); + if (!sa[i].map->virt) { + ret = -ENOMEM; + break; + } + + sa[i].map->phys = sa[i].base; + sa[i].map->set_vpp = sa[i].set_vpp; + sa[i].map->bankwidth = sa[i].width; + sa[i].map->size = sa[i].size; + + simple_map_init(sa[i].map); + + /* + * Now let's probe for the actual flash. Do it here since + * specific machine settings might have been set above. + */ + sa[i].mtd = do_map_probe("cfi_probe", sa[i].map); + if (sa[i].mtd == NULL) { + ret = -ENXIO; + break; + } + sa[i].mtd->owner = THIS_MODULE; + subdev[i] = sa[i].mtd; + + printk(KERN_INFO "SA1100 flash: CFI device at 0x%08lx, %dMiB, " + "%d-bit\n", sa[i].base, sa[i].mtd->size >> 20, + sa[i].width * 8); + found += 1; + } /* - * Dynamic partition selection stuff (might override the static ones) + * ENXIO is special. It means we didn't find a chip when + * we probed. We need to tear down the mapping, free the + * resource and mark it as such. */ -#ifdef CONFIG_MTD_REDBOOT_PARTS - if (parsed_nr_parts == 0) { - int ret = parse_redboot_partitions(mymtd, &parsed_parts); - - if (ret > 0) { - part_type = "RedBoot"; - parsed_nr_parts = ret; - } + if (ret == -ENXIO) { + iounmap(sa[i].map->virt); + sa[i].map->virt = NULL; + release_mem_region(sa[i].base, sa[i].size); } + + /* + * If we found one device, don't bother with concat support. + * If we found multiple devices, use concat if we have it + * available, otherwise fail. + */ + if (ret == 0 || ret == -ENXIO) { + if (found == 1) { + *rmtd = subdev[0]; + ret = 0; + } else if (found > 1) { + /* + * We detected multiple devices. Concatenate + * them together. + */ +#ifdef CONFIG_MTD_CONCAT + *rmtd = mtd_concat_create(subdev, found, + "sa1100"); + if (*rmtd == NULL) + ret = -ENXIO; +#else + printk(KERN_ERR "SA1100 flash: multiple devices " + "found but MTD concat support disabled.\n"); + ret = -ENXIO; #endif -#ifdef CONFIG_MTD_CMDLINE_PARTS - if (parsed_nr_parts == 0) { - int ret = parse_cmdline_partitions(mymtd, &parsed_parts, "sa1100"); - if (ret > 0) { - part_type = "Command Line"; - parsed_nr_parts = ret; } } + + /* + * If we failed, clean up. + */ + if (ret) { + do { + if (sa[i].mtd) + map_destroy(sa[i].mtd); + if (sa[i].map->virt) + iounmap(sa[i].map->virt); + release_mem_region(sa[i].base, sa[i].size); + } while (i-- > 0); + + kfree(maps); + } + + return ret; +} + +static void __exit sa1100_destroy_mtd(struct sa_info *sa, struct mtd_info *mtd) +{ + int i; + + del_mtd_partitions(mtd); + +#ifdef CONFIG_MTD_CONCAT + if (mtd != sa[0].mtd) + mtd_concat_destroy(mtd); #endif - if (parsed_nr_parts > 0) { - parts = parsed_parts; - nb_parts = parsed_nr_parts; + for (i = NR_SUBMTD; i >= 0; i--) { + if (sa[i].mtd) + map_destroy(sa[i].mtd); + if (sa[i].map->virt) + iounmap(sa[i].map->virt); + release_mem_region(sa[i].base, sa[i].size); } + kfree(sa[0].map); +} - if (nb_parts == 0) { - printk(KERN_NOTICE "SA1100 flash: no partition info available, registering whole flash at once\n"); - add_mtd_device(mymtd); - } else { - printk(KERN_NOTICE "Using %s partition definition\n", part_type); - add_mtd_partitions(mymtd, parts, nb_parts); +/* + * A Thought: can we automatically detect the flash? + * - Check to see if the region is busy (yes -> failure) + * - Is the MSC setup for flash (no -> failure) + * - Probe for flash + */ +static void __init sa1100_probe_one_cs(unsigned int msc, unsigned long phys) +{ + struct map_info map; + struct mtd_info *mtd; + + printk(KERN_INFO "* Probing 0x%08lx: MSC = 0x%04x %d bit ", + phys, msc & 0xffff, msc & MSC_RBW ? 16 : 32); + + if (check_mem_region(phys, 0x08000000)) { + printk("busy\n"); + return; } - return 0; - out_err: - if (sa1100_map.map_priv_2 != -1) { - iounmap((void *)sa1100_map.map_priv_1); - release_mem_region(sa1100_map.map_priv_2, sa1100_map.size); + if ((msc & 3) == 1) { + printk("wrong type\n"); + return; + } + + memset(&map, 0, sizeof(struct map_info)); + + map.name = "Probe"; + map.bankwidth = msc & MSC_RBW ? 2 : 4; + map.size = SZ_1M; + map.phys = phys; + map.virt = ioremap(phys, SZ_1M); + if (map.virt == NULL) + goto fail; + + simple_map_init(&map); + + /* Shame cfi_probe blurts out kernel messages... */ + mtd = do_map_probe("cfi_probe", &map); + if (mtd) + map_destroy(mtd); + iounmap(map.virt); + + if (!mtd) + goto fail; + + printk("pass\n"); + return; + + fail: + printk("failed\n"); +} + +static void __init sa1100_probe_flash(void) +{ + printk(KERN_INFO "-- SA11xx Flash probe. Please report results.\n"); + sa1100_probe_one_cs(MSC0, SA1100_CS0_PHYS); + sa1100_probe_one_cs(MSC0 >> 16, SA1100_CS1_PHYS); + sa1100_probe_one_cs(MSC1, SA1100_CS2_PHYS); + sa1100_probe_one_cs(MSC1 >> 16, SA1100_CS3_PHYS); + sa1100_probe_one_cs(MSC2, SA1100_CS4_PHYS); + sa1100_probe_one_cs(MSC2 >> 16, SA1100_CS5_PHYS); + printk(KERN_INFO "-- SA11xx Flash probe complete.\n"); +} + +static int __init sa1100_locate_flash(void) +{ + int i, nr = -ENODEV; + + sa1100_probe_flash(); + + if (machine_is_adsbitsy()) { + info[0].base = SA1100_CS1_PHYS; + info[0].size = SZ_32M; + nr = 1; + } + if (machine_is_assabet()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_32M; + info[1].base = SA1100_CS1_PHYS; /* neponset */ + info[1].size = SZ_32M; + nr = 2; + } + if (machine_is_badge4()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_64M; + nr = 1; + } + if (machine_is_cerf()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_32M; + nr = 1; } + if (machine_is_consus()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_32M; + nr = 1; + } + if (machine_is_flexanet()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_32M; + nr = 1; + } + if (machine_is_freebird()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_32M; + nr = 1; + } + if (machine_is_frodo()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_32M; + nr = 1; + } + if (machine_is_graphicsclient()) { + info[0].base = SA1100_CS1_PHYS; + info[0].size = SZ_32M; + nr = 1; + } + if (machine_is_graphicsmaster()) { + info[0].base = SA1100_CS1_PHYS; + info[0].size = SZ_16M; + nr = 1; + } + if (machine_is_h3xxx()) { + info[0].set_vpp = h3xxx_set_vpp; + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_32M; + nr = 1; + } + if (machine_is_huw_webpanel()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_16M; + nr = 1; + } + if (machine_is_itsy()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_32M; + nr = 1; + } + if (machine_is_jornada56x()) { + info[0].set_vpp = jornada56x_set_vpp; + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_32M; + nr = 1; + } + if (machine_is_jornada720()) { + info[0].set_vpp = jornada720_set_vpp; + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_32M; + nr = 1; + } + if (machine_is_nanoengine()) { + info[0].base = SA1100_CS0_PHYS; + info[1].size = SZ_32M; + nr = 1; + } + if (machine_is_pangolin()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_64M; + nr = 1; + } + if (machine_is_pfs168()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_32M; + nr = 1; + } + if (machine_is_pleb()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_4M; + info[1].base = SA1100_CS1_PHYS; + info[1].size = SZ_4M; + nr = 2; + } + if (machine_is_pt_system3()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_16M; + nr = 1; + } + if (machine_is_shannon()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_4M; + nr = 1; + } + if (machine_is_sherman()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_32M; + nr = 1; + } + if (machine_is_simpad()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_16M; + info[1].base = SA1100_CS1_PHYS; + info[1].size = SZ_16M; + nr = 2; + } + if (machine_is_stork()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_32M; + nr = 1; + } + if (machine_is_trizeps()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_16M; + nr = 1; + } + if (machine_is_victor()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_2M; + nr = 1; + } + if (machine_is_yopy()) { + info[0].base = SA1100_CS0_PHYS; + info[0].size = SZ_64M; + info[1].base = SA1100_CS1_PHYS; + info[1].size = SZ_64M; + nr = 2; + } + + if (nr < 0) + return nr; + + /* + * Retrieve the bankwidth from the MSC registers. + * We currently only implement CS0 and CS1 here. + */ + for (i = 0; i < nr; i++) { + switch (info[i].base) { + default: + printk(KERN_WARNING "SA1100 flash: unknown base address " + "0x%08lx, assuming CS0\n", info[i].base); + case SA1100_CS0_PHYS: + info[i].width = (MSC0 & MSC_RBW) ? 2 : 4; + break; + + case SA1100_CS1_PHYS: + info[i].width = ((MSC0 >> 16) & MSC_RBW) ? 2 : 4; + break; + } + } + + return nr; +} + +static struct mtd_partition *parsed_parts; +const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; + +static void __init sa1100_locate_partitions(struct mtd_info *mtd) +{ + const char *part_type = NULL; + int nr_parts = 0; + + do { + /* + * Partition selection stuff. + */ +#ifdef CONFIG_MTD_PARTITIONS + nr_parts = parse_mtd_partitions(mtd, part_probes, &parsed_parts, 0); + if (nr_parts > 0) { + part_type = "dynamic"; + break; + } +#endif +#ifdef CONFIG_MTD_SA1100_STATICMAP + nr_parts = sa1100_static_partitions(&parsed_parts); + if (nr_parts > 0) { + part_type = "static"; + break; + } +#endif + } while (0); + + if (nr_parts == 0) { + printk(KERN_NOTICE "SA1100 flash: no partition info " + "available, registering whole flash\n"); + add_mtd_device(mtd); + } else { + printk(KERN_NOTICE "SA1100 flash: using %s partition " + "definition\n", part_type); + add_mtd_partitions(mtd, parsed_parts, nr_parts); + } + + /* Always succeeds. */ +} + +static void __exit sa1100_destroy_partitions(void) +{ + if (parsed_parts) + kfree(parsed_parts); +} + +static struct mtd_info *mymtd; + +static int __init sa1100_mtd_init(void) +{ + int ret; + int nr; + + nr = sa1100_locate_flash(); + if (nr < 0) + return nr; + + ret = sa1100_setup_mtd(info, nr, &mymtd); + if (ret == 0) + sa1100_locate_partitions(mymtd); + return ret; } static void __exit sa1100_mtd_cleanup(void) { - if (mymtd) { - del_mtd_partitions(mymtd); - map_destroy(mymtd); - if (parsed_parts) - kfree(parsed_parts); - } - if (sa1100_map.map_priv_2 != -1) { - iounmap((void *)sa1100_map.map_priv_1); - release_mem_region(sa1100_map.map_priv_2, sa1100_map.size); - } + sa1100_destroy_mtd(info, mymtd); + sa1100_destroy_partitions(); } module_init(sa1100_mtd_init); Index: drivers/mtd/maps/sbc_gxx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/sbc_gxx.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/sbc_gxx.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/maps/sbc_gxx.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - $Id: sbc_gxx.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + $Id: sbc_gxx.c,v 1.3 2004/11/03 00:04:44 joff Exp $ The SBC-MediaGX / SBC-GXx has up to 16 MiB of Intel StrataFlash (28F320/28F640) in x8 mode. @@ -84,21 +84,21 @@ // Globals static volatile int page_in_window = -1; // Current page in window. -static unsigned long iomapadr; +static void __iomem *iomapadr; static spinlock_t sbc_gxx_spin = SPIN_LOCK_UNLOCKED; /* partition_info gives details on the logical partitions that the split the * single flash device into. If the size if zero we use up to the end of the * device. */ static struct mtd_partition partition_info[]={ - { name: "SBC-GXx flash boot partition", - offset: 0, - size: BOOT_PARTITION_SIZE_KiB*1024 }, - { name: "SBC-GXx flash data partition", - offset: BOOT_PARTITION_SIZE_KiB*1024, - size: (DATA_PARTITION_SIZE_KiB)*1024 }, - { name: "SBC-GXx flash application partition", - offset: (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 } + { .name = "SBC-GXx flash boot partition", + .offset = 0, + .size = BOOT_PARTITION_SIZE_KiB*1024 }, + { .name = "SBC-GXx flash data partition", + .offset = BOOT_PARTITION_SIZE_KiB*1024, + .size = (DATA_PARTITION_SIZE_KiB)*1024 }, + { .name = "SBC-GXx flash application partition", + .offset = (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 } }; #define NUM_PARTITIONS 3 @@ -114,32 +114,12 @@ } -static __u8 sbc_gxx_read8(struct map_info *map, unsigned long ofs) +static map_word sbc_gxx_read8(struct map_info *map, unsigned long ofs) { - __u8 ret; + map_word ret; spin_lock(&sbc_gxx_spin); sbc_gxx_page(map, ofs); - ret = readb(iomapadr + (ofs & WINDOW_MASK)); - spin_unlock(&sbc_gxx_spin); - return ret; -} - -static __u16 sbc_gxx_read16(struct map_info *map, unsigned long ofs) -{ - __u16 ret; - spin_lock(&sbc_gxx_spin); - sbc_gxx_page(map, ofs); - ret = readw(iomapadr + (ofs & WINDOW_MASK)); - spin_unlock(&sbc_gxx_spin); - return ret; -} - -static __u32 sbc_gxx_read32(struct map_info *map, unsigned long ofs) -{ - __u32 ret; - spin_lock(&sbc_gxx_spin); - sbc_gxx_page(map, ofs); - ret = readl(iomapadr + (ofs & WINDOW_MASK)); + ret.x[0] = readb(iomapadr + (ofs & WINDOW_MASK)); spin_unlock(&sbc_gxx_spin); return ret; } @@ -155,33 +135,17 @@ sbc_gxx_page(map, from); memcpy_fromio(to, iomapadr + (from & WINDOW_MASK), thislen); spin_unlock(&sbc_gxx_spin); - (__u8*)to += thislen; + to += thislen; from += thislen; len -= thislen; } } -static void sbc_gxx_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - spin_lock(&sbc_gxx_spin); - sbc_gxx_page(map, adr); - writeb(d, iomapadr + (adr & WINDOW_MASK)); - spin_unlock(&sbc_gxx_spin); -} - -static void sbc_gxx_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - spin_lock(&sbc_gxx_spin); - sbc_gxx_page(map, adr); - writew(d, iomapadr + (adr & WINDOW_MASK)); - spin_unlock(&sbc_gxx_spin); -} - -static void sbc_gxx_write32(struct map_info *map, __u32 d, unsigned long adr) +static void sbc_gxx_write8(struct map_info *map, map_word d, unsigned long adr) { spin_lock(&sbc_gxx_spin); sbc_gxx_page(map, adr); - writel(d, iomapadr + (adr & WINDOW_MASK)); + writeb(d.x[0], iomapadr + (adr & WINDOW_MASK)); spin_unlock(&sbc_gxx_spin); } @@ -203,19 +167,16 @@ } static struct map_info sbc_gxx_map = { - name: "SBC-GXx flash", - size: MAX_SIZE_KiB*1024, /* this must be set to a maximum possible amount + .name = "SBC-GXx flash", + .phys = NO_XIP, + .size = MAX_SIZE_KiB*1024, /* this must be set to a maximum possible amount of flash so the cfi probe routines find all the chips */ - buswidth: 1, - read8: sbc_gxx_read8, - read16: sbc_gxx_read16, - read32: sbc_gxx_read32, - copy_from: sbc_gxx_copy_from, - write8: sbc_gxx_write8, - write16: sbc_gxx_write16, - write32: sbc_gxx_write32, - copy_to: sbc_gxx_copy_to + .bankwidth = 1, + .read = sbc_gxx_read8, + .copy_from = sbc_gxx_copy_from, + .write = sbc_gxx_write8, + .copy_to = sbc_gxx_copy_to }; /* MTD device for all of the flash. */ @@ -234,20 +195,21 @@ int __init init_sbc_gxx(void) { - if (check_region(PAGE_IO,PAGE_IO_SIZE) != 0) { - printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n", - sbc_gxx_map.name, - PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 ); - return -EAGAIN; - } - iomapadr = (unsigned long)ioremap(WINDOW_START, WINDOW_LENGTH); + iomapadr = (void __iomem *)ioremap(WINDOW_START, WINDOW_LENGTH); if (!iomapadr) { printk( KERN_ERR"%s: failed to ioremap memory region\n", sbc_gxx_map.name ); return -EIO; } - request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash" ); + if (!request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash")) { + printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n", + sbc_gxx_map.name, + PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 ); + iounmap((void *)iomapadr); + return -EAGAIN; + } + printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n", sbc_gxx_map.name, @@ -261,7 +223,7 @@ return -ENXIO; } - all_mtd->module=THIS_MODULE; + all_mtd->owner = THIS_MODULE; /* Create MTD devices for each partition. */ add_mtd_partitions(all_mtd, partition_info, NUM_PARTITIONS ); Index: drivers/mtd/maps/sc520cdp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/sc520cdp.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/sc520cdp.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/maps/sc520cdp.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: sc520cdp.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: sc520cdp.c,v 1.3 2004/11/03 00:04:44 joff Exp $ * * * The SC520CDP is an evaluation board for the Elan SC520 processor available @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -84,88 +85,25 @@ #define WINDOW_SIZE_1 0x00800000 #define WINDOW_SIZE_2 0x00080000 -static __u8 sc520cdp_read8(struct map_info *map, unsigned long ofs) -{ - return readb(map->map_priv_1 + ofs); -} - -static __u16 sc520cdp_read16(struct map_info *map, unsigned long ofs) -{ - return readw(map->map_priv_1 + ofs); -} - -static __u32 sc520cdp_read32(struct map_info *map, unsigned long ofs) -{ - return readl(map->map_priv_1 + ofs); -} - -static void sc520cdp_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy_fromio(to, (void *)(map->map_priv_1 + from), len); -} - -static void sc520cdp_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - writeb(d, map->map_priv_1 + adr); -} - -static void sc520cdp_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - writew(d, map->map_priv_1 + adr); -} - -static void sc520cdp_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - writel(d, map->map_priv_1 + adr); -} - -static void sc520cdp_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy_toio((void *)(map->map_priv_1 + to), from, len); -} static struct map_info sc520cdp_map[] = { { - name: "SC520CDP Flash Bank #0", - size: WINDOW_SIZE_0, - buswidth: 4, - read8: sc520cdp_read8, - read16: sc520cdp_read16, - read32: sc520cdp_read32, - copy_from: sc520cdp_copy_from, - write8: sc520cdp_write8, - write16: sc520cdp_write16, - write32: sc520cdp_write32, - copy_to: sc520cdp_copy_to, - map_priv_2: WINDOW_ADDR_0 + .name = "SC520CDP Flash Bank #0", + .size = WINDOW_SIZE_0, + .bankwidth = 4, + .phys = WINDOW_ADDR_0 }, { - name: "SC520CDP Flash Bank #1", - size: WINDOW_SIZE_1, - buswidth: 4, - read8: sc520cdp_read8, - read16: sc520cdp_read16, - read32: sc520cdp_read32, - copy_from: sc520cdp_copy_from, - write8: sc520cdp_write8, - write16: sc520cdp_write16, - write32: sc520cdp_write32, - copy_to: sc520cdp_copy_to, - map_priv_2: WINDOW_ADDR_1 + .name = "SC520CDP Flash Bank #1", + .size = WINDOW_SIZE_1, + .bankwidth = 4, + .phys = WINDOW_ADDR_1 }, { - name: "SC520CDP DIL Flash", - size: WINDOW_SIZE_2, - buswidth: 1, - read8: sc520cdp_read8, - read16: sc520cdp_read16, - read32: sc520cdp_read32, - copy_from: sc520cdp_copy_from, - write8: sc520cdp_write8, - write16: sc520cdp_write16, - write32: sc520cdp_write32, - copy_to: sc520cdp_copy_to, - map_priv_2: WINDOW_ADDR_2 + .name = "SC520CDP DIL Flash", + .size = WINDOW_SIZE_2, + .bankwidth = 1, + .phys = WINDOW_ADDR_2 }, }; @@ -255,9 +193,9 @@ /* map in SC520's MMCR area */ mmcr = (unsigned long *)ioremap_nocache(SC520_MMCR_BASE, SC520_MMCR_EXTENT); if(!mmcr) { /* ioremap_nocache failed: skip the PAR reprogramming */ - /* force map_priv_2 fields to BIOS defaults: */ + /* force physical address fields to BIOS defaults: */ for(i = 0; i < NUM_FLASH_BANKS; i++) - sc520cdp_map[i].map_priv_2 = par_table[i].default_address; + sc520cdp_map[i].phys = par_table[i].default_address; return; } @@ -282,7 +220,7 @@ sc520cdp_map[i].name); printk(KERN_NOTICE "Trying default address 0x%lx\n", par_table[i].default_address); - sc520cdp_map[i].map_priv_2 = par_table[i].default_address; + sc520cdp_map[i].phys = par_table[i].default_address; } } iounmap((void *)mmcr); @@ -300,13 +238,18 @@ #endif for (i = 0; i < NUM_FLASH_BANKS; i++) { - printk(KERN_NOTICE "SC520 CDP flash device: %lx at %lx\n", sc520cdp_map[i].size, sc520cdp_map[i].map_priv_2); - sc520cdp_map[i].map_priv_1 = (unsigned long)ioremap_nocache(sc520cdp_map[i].map_priv_2, sc520cdp_map[i].size); + printk(KERN_NOTICE "SC520 CDP flash device: 0x%lx at 0x%lx\n", + sc520cdp_map[i].size, sc520cdp_map[i].phys); - if (!sc520cdp_map[i].map_priv_1) { + sc520cdp_map[i].virt = (void __iomem *)ioremap_nocache(sc520cdp_map[i].phys, sc520cdp_map[i].size); + + if (!sc520cdp_map[i].virt) { printk("Failed to ioremap_nocache\n"); return -EIO; } + + simple_map_init(&sc520cdp_map[i]); + mymtd[i] = do_map_probe("cfi_probe", &sc520cdp_map[i]); if(!mymtd[i]) mymtd[i] = do_map_probe("jedec_probe", &sc520cdp_map[i]); @@ -314,11 +257,11 @@ mymtd[i] = do_map_probe("map_rom", &sc520cdp_map[i]); if (mymtd[i]) { - mymtd[i]->module = THIS_MODULE; + mymtd[i]->owner = THIS_MODULE; ++devices_found; } else { - iounmap((void *)sc520cdp_map[i].map_priv_1); + iounmap((void *)sc520cdp_map[i].virt); } } if(devices_found >= 2) { @@ -346,9 +289,9 @@ for (i = 0; i < NUM_FLASH_BANKS; i++) { if (mymtd[i]) map_destroy(mymtd[i]); - if (sc520cdp_map[i].map_priv_1) { - iounmap((void *)sc520cdp_map[i].map_priv_1); - sc520cdp_map[i].map_priv_1 = 0; + if (sc520cdp_map[i].virt) { + iounmap((void *)sc520cdp_map[i].virt); + sc520cdp_map[i].virt = 0; } } } Index: drivers/mtd/maps/scb2_flash.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/scb2_flash.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/scb2_flash.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/scb2_flash.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -1,6 +1,6 @@ /* * MTD map driver for BIOS Flash on Intel SCB2 boards - * $Id: scb2_flash.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: scb2_flash.c,v 1.3 2004/11/03 00:04:44 joff Exp $ * Copyright (C) 2002 Sun Microsystems, Inc. * Tim Hockin * @@ -14,7 +14,7 @@ * try to request it here, but if it fails, we carry on anyway. * * This is how the chip is attached, so said the schematic: - * * a 4 MiB (32 Mb) 16 bit chip + * * a 4 MiB (32 Mib) 16 bit chip * * a 1 MiB memory region * * A20 and A21 pulled up * * D8-D15 ignored @@ -31,23 +31,24 @@ * * The actual BIOS layout has been mostly reverse engineered. Intel BIOS * updates for this board include 10 related (*.bio - &.bi9) binary files and - * another seperate (*.bbo) binary file. The 10 files are 64k of data + a + * another separate (*.bbo) binary file. The 10 files are 64k of data + a * small header. If the headers are stripped off, the 10 64k files can be * concatenated into a 640k image. This is your BIOS image, proper. The - * seperate .bbo file also has a small header. It is the 'Boot Block' + * separate .bbo file also has a small header. It is the 'Boot Block' * recovery BIOS. Once the header is stripped, no further prep is needed. * As best I can tell, the BIOS is arranged as such: * offset 0x00000 to 0x4ffff (320k): unknown - SCSI BIOS, etc? * offset 0x50000 to 0xeffff (640k): BIOS proper * offset 0xf0000 ty 0xfffff (64k): Boot Block region * - * Intel's BIOS update program flashes the BIOS and Boot Block in seperate + * Intel's BIOS update program flashes the BIOS and Boot Block in separate * steps. Probably a wise thing to do. */ #include #include #include +#include #include #include #include @@ -60,65 +61,13 @@ #define SCB2_ADDR 0xfff00000 #define SCB2_WINDOW 0x00100000 -static __u8 scb2_read8(struct map_info *map, unsigned long ofs) -{ - return __raw_readb(map->map_priv_1 + ofs); -} - -static __u16 scb2_read16(struct map_info *map, unsigned long ofs) -{ - return __raw_readw(map->map_priv_1 + ofs); -} - -static __u32 scb2_read32(struct map_info *map, unsigned long ofs) -{ - return __raw_readl(map->map_priv_1 + ofs); -} - -static void scb2_copy_from(struct map_info *map, void *to, - unsigned long from, ssize_t len) -{ - memcpy_fromio(to, map->map_priv_1 + from, len); -} - -static void scb2_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - __raw_writeb(d, map->map_priv_1 + adr); - mb(); -} - -static void scb2_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - __raw_writew(d, map->map_priv_1 + adr); - mb(); -} - -static void scb2_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - __raw_writel(d, map->map_priv_1 + adr); - mb(); -} - -static void scb2_copy_to(struct map_info *map, unsigned long to, - const void *from, ssize_t len) -{ - memcpy_toio(map->map_priv_1 + to, from, len); -} static void *scb2_ioaddr; static struct mtd_info *scb2_mtd; struct map_info scb2_map = { - name: "SCB2 BIOS Flash", - size: 0, - buswidth: 1, - read8: scb2_read8, - read16: scb2_read16, - read32: scb2_read32, - copy_from: scb2_copy_from, - write8: scb2_write8, - write16: scb2_write16, - write32: scb2_write32, - copy_to: scb2_copy_to, + .name = "SCB2 BIOS Flash", + .size = 0, + .bankwidth = 1, }; static int region_fail; @@ -137,6 +86,8 @@ return -1; } + /* I wasn't here. I didn't see. dwmw2. */ + /* the chip is sometimes bigger than the map - what a waste */ mtd->size = map->size; @@ -211,9 +162,12 @@ return -ENOMEM; } - scb2_map.map_priv_1 = (unsigned long)scb2_ioaddr; + scb2_map.phys = SCB2_ADDR; + scb2_map.virt = (void __iomem *)scb2_ioaddr; scb2_map.size = SCB2_WINDOW; + simple_map_init(&scb2_map); + /* try to find a chip */ scb2_mtd = do_map_probe("cfi_probe", &scb2_map); @@ -225,7 +179,7 @@ return -ENODEV; } - scb2_mtd->module = THIS_MODULE; + scb2_mtd->owner = THIS_MODULE; if (scb2_fixup_mtd(scb2_mtd) < 0) { del_mtd_device(scb2_mtd); map_destroy(scb2_mtd); @@ -235,7 +189,7 @@ return -ENODEV; } - printk(KERN_NOTICE MODNAME ": chip size %x at offset %x\n", + printk(KERN_NOTICE MODNAME ": chip size 0x%x at offset 0x%x\n", scb2_mtd->size, SCB2_WINDOW - scb2_mtd->size); add_mtd_device(scb2_mtd); @@ -264,21 +218,21 @@ pci_set_drvdata(dev, NULL); } -static struct pci_device_id scb2_flash_pci_ids[] __devinitdata = { +static struct pci_device_id scb2_flash_pci_ids[] = { { - vendor: PCI_VENDOR_ID_SERVERWORKS, - device: PCI_DEVICE_ID_SERVERWORKS_CSB5, - subvendor: PCI_ANY_ID, - subdevice: PCI_ANY_ID + .vendor = PCI_VENDOR_ID_SERVERWORKS, + .device = PCI_DEVICE_ID_SERVERWORKS_CSB5, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID }, { 0, } }; static struct pci_driver scb2_flash_driver = { - name: "Intel SCB2 BIOS Flash", - id_table: scb2_flash_pci_ids, - probe: scb2_flash_probe, - remove: __devexit_p(scb2_flash_remove), + .name = "Intel SCB2 BIOS Flash", + .id_table = scb2_flash_pci_ids, + .probe = scb2_flash_probe, + .remove = __devexit_p(scb2_flash_remove), }; static int __init Index: drivers/mtd/maps/scx200_docflash.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/scx200_docflash.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/scx200_docflash.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/scx200_docflash.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -2,7 +2,7 @@ Copyright (c) 2001,2002 Christer Weinigel - $Id: scx200_docflash.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + $Id: scx200_docflash.c,v 1.3 2004/11/03 00:04:44 joff Exp $ National Semiconductor SCx200 flash mapped with DOCCS */ @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -75,46 +76,9 @@ #define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) #endif -static __u8 scx200_docflash_read8(struct map_info *map, unsigned long ofs) -{ - return __raw_readb(map->map_priv_1 + ofs); -} - -static __u16 scx200_docflash_read16(struct map_info *map, unsigned long ofs) -{ - return __raw_readw(map->map_priv_1 + ofs); -} - -static void scx200_docflash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy_fromio(to, map->map_priv_1 + from, len); -} - -static void scx200_docflash_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - __raw_writeb(d, map->map_priv_1 + adr); - mb(); -} - -static void scx200_docflash_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - __raw_writew(d, map->map_priv_1 + adr); - mb(); -} - -static void scx200_docflash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy_toio(map->map_priv_1 + to, from, len); -} static struct map_info scx200_docflash_map = { .name = "NatSemi SCx200 DOCCS Flash", - .read8 = scx200_docflash_read8, - .read16 = scx200_docflash_read16, - .copy_from = scx200_docflash_copy_from, - .write8 = scx200_docflash_write8, - .write16 = scx200_docflash_write16, - .copy_to = scx200_docflash_copy_to }; int __init init_scx200_docflash(void) @@ -209,12 +173,15 @@ scx200_docflash_map.size = size; if (width == 8) - scx200_docflash_map.buswidth = 1; + scx200_docflash_map.bankwidth = 1; else - scx200_docflash_map.buswidth = 2; + scx200_docflash_map.bankwidth = 2; + + simple_map_init(&scx200_docflash_map); - scx200_docflash_map.map_priv_1 = (unsigned long)ioremap(docmem.start, scx200_docflash_map.size); - if (!scx200_docflash_map.map_priv_1) { + scx200_docflash_map.phys = docmem.start; + scx200_docflash_map.virt = (void __iomem *)ioremap(docmem.start, scx200_docflash_map.size); + if (!scx200_docflash_map.virt) { printk(KERN_ERR NAME ": failed to ioremap the flash\n"); release_resource(&docmem); return -EIO; @@ -223,7 +190,7 @@ mymtd = do_map_probe(flashtype, &scx200_docflash_map); if (!mymtd) { printk(KERN_ERR NAME ": unable to detect flash\n"); - iounmap((void *)scx200_docflash_map.map_priv_1); + iounmap((void *)scx200_docflash_map.virt); release_resource(&docmem); return -ENXIO; } @@ -231,7 +198,7 @@ if (size < mymtd->size) printk(KERN_WARNING NAME ": warning, flash mapping is smaller than flash size\n"); - mymtd->module = THIS_MODULE; + mymtd->owner = THIS_MODULE; #if PARTITION partition_info[3].offset = mymtd->size-partition_info[3].size; @@ -253,8 +220,8 @@ #endif map_destroy(mymtd); } - if (scx200_docflash_map.map_priv_1) { - iounmap((void *)scx200_docflash_map.map_priv_1); + if (scx200_docflash_map.virt) { + iounmap((void *)scx200_docflash_map.virt); release_resource(&docmem); } } Index: drivers/mtd/maps/solutionengine.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/solutionengine.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/solutionengine.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/solutionengine.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -1,5 +1,5 @@ /* - * $Id: solutionengine.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: solutionengine.c,v 1.3 2004/11/03 00:04:44 joff Exp $ * * Flash and EPROM on Hitachi Solution Engine and similar boards. * @@ -11,31 +11,13 @@ #include #include #include +#include #include #include #include #include #include - - -extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts); - -__u32 soleng_read32(struct map_info *map, unsigned long ofs) -{ - return __raw_readl(map->map_priv_1 + ofs); -} - -void soleng_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - __raw_writel(d, map->map_priv_1 + adr); - mb(); -} - -void soleng_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy_fromio(to, map->map_priv_1 + from, len); -} - +#include static struct mtd_info *flash_mtd; static struct mtd_info *eprom_mtd; @@ -43,35 +25,33 @@ static struct mtd_partition *parsed_parts; struct map_info soleng_eprom_map = { - name: "Solution Engine EPROM", - size: 0x400000, - buswidth: 4, - copy_from: soleng_copy_from, + .name = "Solution Engine EPROM", + .size = 0x400000, + .bankwidth = 4, }; struct map_info soleng_flash_map = { - name: "Solution Engine FLASH", - size: 0x400000, - buswidth: 4, - read32: soleng_read32, - copy_from: soleng_copy_from, - write32: soleng_write32, + .name = "Solution Engine FLASH", + .size = 0x400000, + .bankwidth = 4, }; +static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; + #ifdef CONFIG_MTD_SUPERH_RESERVE static struct mtd_partition superh_se_partitions[] = { /* Reserved for boot code, read-only */ { - name: "flash_boot", - offset: 0x00000000, - size: CONFIG_MTD_SUPERH_RESERVE, - mask_flags: MTD_WRITEABLE, + .name = "flash_boot", + .offset = 0x00000000, + .size = CONFIG_MTD_SUPERH_RESERVE, + .mask_flags = MTD_WRITEABLE, }, /* All else is writable (e.g. JFFS) */ { - name: "Flash FS", - offset: MTDPART_OFS_NXTBLK, - size: MTDPART_SIZ_FULL, + .name = "Flash FS", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, } }; #endif /* CONFIG_MTD_SUPERH_RESERVE */ @@ -81,16 +61,22 @@ int nr_parts = 0; /* First probe at offset 0 */ - soleng_flash_map.map_priv_1 = P2SEGADDR(0); - soleng_eprom_map.map_priv_1 = P1SEGADDR(0x01000000); - + soleng_flash_map.phys = 0; + soleng_flash_map.virt = (void __iomem *)P2SEGADDR(0); + soleng_eprom_map.phys = 0x01000000; + soleng_eprom_map.virt = (void __iomem *)P1SEGADDR(0x01000000); + simple_map_init(&soleng_eprom_map); + simple_map_init(&soleng_flash_map); + printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n"); flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map); if (!flash_mtd) { /* Not there. Try swapping */ printk(KERN_NOTICE "Probing for flash chips at 0x01000000:\n"); - soleng_flash_map.map_priv_1 = P2SEGADDR(0x01000000); - soleng_eprom_map.map_priv_1 = P1SEGADDR(0); + soleng_flash_map.phys = 0x01000000; + soleng_flash_map.virt = P2SEGADDR(0x01000000); + soleng_eprom_map.phys = 0; + soleng_eprom_map.virt = P1SEGADDR(0); flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map); if (!flash_mtd) { /* Eep. */ @@ -99,25 +85,20 @@ } } printk(KERN_NOTICE "Solution Engine: Flash at 0x%08lx, EPROM at 0x%08lx\n", - soleng_flash_map.map_priv_1 & 0x1fffffff, - soleng_eprom_map.map_priv_1 & 0x1fffffff); - flash_mtd->module = THIS_MODULE; + soleng_flash_map.phys & 0x1fffffff, + soleng_eprom_map.phys & 0x1fffffff); + flash_mtd->owner = THIS_MODULE; eprom_mtd = do_map_probe("map_rom", &soleng_eprom_map); if (eprom_mtd) { - eprom_mtd->module = THIS_MODULE; + eprom_mtd->owner = THIS_MODULE; add_mtd_device(eprom_mtd); } -#ifdef CONFIG_MTD_REDBOOT_PARTS - nr_parts = parse_redboot_partitions(flash_mtd, &parsed_parts); - if (nr_parts > 0) - printk(KERN_NOTICE "Found RedBoot partition table.\n"); - else if (nr_parts < 0) - printk(KERN_NOTICE "Error looking for RedBoot partitions.\n"); -#endif /* CONFIG_MTD_REDBOOT_PARTS */ -#if CONFIG_MTD_SUPERH_RESERVE - if (nr_parts == 0) { + nr_parts = parse_mtd_partitions(flash_mtd, probes, &parsed_parts, 0); + +#ifdef CONFIG_MTD_SUPERH_RESERVE + if (nr_parts <= 0) { printk(KERN_NOTICE "Using configured partition at 0x%08x.\n", CONFIG_MTD_SUPERH_RESERVE); parsed_parts = superh_se_partitions; Index: drivers/mtd/maps/sun_uflash.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/sun_uflash.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/sun_uflash.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/sun_uflash.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -1,4 +1,4 @@ -/* $Id: sun_uflash.c,v 1.1 2004/07/22 19:49:45 joff Exp $ +/* $Id: sun_uflash.c,v 1.3 2004/11/03 00:04:44 joff Exp $ * * sun_uflash - Driver implementation for user-programmable flash * present on many Sun Microsystems SME boardsets. @@ -12,7 +12,6 @@ #include #include -#include #include #include #include @@ -48,60 +47,11 @@ struct list_head list; }; -__u8 uflash_read8(struct map_info *map, unsigned long ofs) -{ - return(__raw_readb(map->map_priv_1 + ofs)); -} - -__u16 uflash_read16(struct map_info *map, unsigned long ofs) -{ - return(__raw_readw(map->map_priv_1 + ofs)); -} - -__u32 uflash_read32(struct map_info *map, unsigned long ofs) -{ - return(__raw_readl(map->map_priv_1 + ofs)); -} - -void uflash_copy_from(struct map_info *map, void *to, unsigned long from, - ssize_t len) -{ - memcpy_fromio(to, map->map_priv_1 + from, len); -} - -void uflash_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - __raw_writeb(d, map->map_priv_1 + adr); -} - -void uflash_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - __raw_writew(d, map->map_priv_1 + adr); -} - -void uflash_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - __raw_writel(d, map->map_priv_1 + adr); -} - -void uflash_copy_to(struct map_info *map, unsigned long to, const void *from, - ssize_t len) -{ - memcpy_toio(map->map_priv_1 + to, from, len); -} struct map_info uflash_map_templ = { - name: "SUNW,???-????", - size: UFLASH_WINDOW_SIZE, - buswidth: UFLASH_BUSWIDTH, - read8: uflash_read8, - read16: uflash_read16, - read32: uflash_read32, - copy_from: uflash_copy_from, - write8: uflash_write8, - write16: uflash_write16, - write32: uflash_write32, - copy_to: uflash_copy_to + .name = "SUNW,???-????", + .size = UFLASH_WINDOW_SIZE, + .bankwidth = UFLASH_BUSWIDTH, }; int uflash_devinit(struct linux_ebus_device* edev) @@ -145,20 +95,22 @@ if(0 != pdev->name && 0 < strlen(pdev->name)) { pdev->map.name = pdev->name; } - - pdev->map.map_priv_1 = - (unsigned long)ioremap_nocache(edev->resource[0].start, pdev->map.size); - if(0 == pdev->map.map_priv_1) { + pdev->map.phys = edev->resource[0].start; + pdev->map.virt = + (void __iomem *)ioremap_nocache(edev->resource[0].start, pdev->map.size); + if(0 == pdev->map.virt) { printk("%s: failed to map device\n", __FUNCTION__); kfree(pdev->name); kfree(pdev); return(-1); } + simple_map_init(&pdev->map); + /* MTD registration */ pdev->mtd = do_map_probe("cfi_probe", &pdev->map); if(0 == pdev->mtd) { - iounmap((void *)pdev->map.map_priv_1); + iounmap((void *)pdev->map.virt); kfree(pdev->name); kfree(pdev); return(-ENXIO); @@ -166,7 +118,7 @@ list_add(&pdev->list, &device_list); - pdev->mtd->module = THIS_MODULE; + pdev->mtd->owner = THIS_MODULE; add_mtd_device(pdev->mtd); return(0); @@ -211,9 +163,9 @@ del_mtd_device(udev->mtd); map_destroy(udev->mtd); } - if(0 != udev->map.map_priv_1) { - iounmap((void*)udev->map.map_priv_1); - udev->map.map_priv_1 = 0; + if(0 != udev->map.virt) { + iounmap((void*)udev->map.virt); + udev->map.virt = 0; } if(0 != udev->name) { kfree(udev->name); Index: drivers/mtd/maps/tqm8xxl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/tqm8xxl.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/tqm8xxl.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/tqm8xxl.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -2,7 +2,7 @@ * Handle mapping of the flash memory access routines * on TQM8xxL based devices. * - * $Id: tqm8xxl.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: tqm8xxl.c,v 1.3 2004/11/03 00:04:44 joff Exp $ * * based on rpxlite.c * @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -49,47 +50,7 @@ static struct map_info* map_banks[FLASH_BANK_MAX]; static struct mtd_part_def part_banks[FLASH_BANK_MAX]; static unsigned long num_banks; -static unsigned long start_scan_addr; - -__u8 tqm8xxl_read8(struct map_info *map, unsigned long ofs) -{ - return *((__u8 *)(map->map_priv_1 + ofs)); -} - -__u16 tqm8xxl_read16(struct map_info *map, unsigned long ofs) -{ - return *((__u16 *)(map->map_priv_1 + ofs)); -} - -__u32 tqm8xxl_read32(struct map_info *map, unsigned long ofs) -{ - return *((__u32 *)(map->map_priv_1 + ofs)); -} - -void tqm8xxl_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy_fromio(to, (void *)(map->map_priv_1 + from), len); -} - -void tqm8xxl_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - *((__u8 *)(map->map_priv_1 + adr)) = d; -} - -void tqm8xxl_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - *((__u16 *)( map->map_priv_1 + adr)) = d; -} - -void tqm8xxl_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - *((__u32 *)(map->map_priv_1 + adr)) = d; -} - -void tqm8xxl_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy_toio((void *)(map->map_priv_1 + to), from, len); -} +static void __iomem *start_scan_addr; /* * Here are partition information for all known TQM8xxL series devices. @@ -107,50 +68,48 @@ static unsigned long tqm8xxl_max_flash_size = 0x00800000; /* partition definition for first flash bank - * also ref. to "drivers\char\flash_config.c" + * (cf. "drivers/char/flash_config.c") */ static struct mtd_partition tqm8xxl_partitions[] = { { - name: "ppcboot", - offset: 0x00000000, - size: 0x00020000, /* 128KB */ - mask_flags: MTD_WRITEABLE, /* force read-only */ + .name = "ppcboot", + .offset = 0x00000000, + .size = 0x00020000, /* 128KB */ + .mask_flags = MTD_WRITEABLE, /* force read-only */ }, { - name: "kernel", /* default kernel image */ - offset: 0x00020000, - size: 0x000e0000, - mask_flags: MTD_WRITEABLE, /* force read-only */ + .name = "kernel", /* default kernel image */ + .offset = 0x00020000, + .size = 0x000e0000, + .mask_flags = MTD_WRITEABLE, /* force read-only */ }, { - name: "user", - offset: 0x00100000, - size: 0x00100000, + .name = "user", + .offset = 0x00100000, + .size = 0x00100000, }, { - name: "initrd", - offset: 0x00200000, - size: 0x00200000, + .name = "initrd", + .offset = 0x00200000, + .size = 0x00200000, } }; -/* partition definition for second flahs bank */ +/* partition definition for second flash bank */ static struct mtd_partition tqm8xxl_fs_partitions[] = { { - name: "cramfs", - offset: 0x00000000, - size: 0x00200000, + .name = "cramfs", + .offset = 0x00000000, + .size = 0x00200000, }, { - name: "jffs", - offset: 0x00200000, - size: 0x00200000, - //size: MTDPART_SIZ_FULL, + .name = "jffs", + .offset = 0x00200000, + .size = 0x00200000, + //.size = MTDPART_SIZ_FULL, } }; #endif -#define NB_OF(x) (sizeof(x)/sizeof(x[0])) - int __init init_tqm_mtd(void) { int idx = 0, ret = 0; @@ -160,67 +119,73 @@ flash_addr = bd->bi_flashstart; flash_size = bd->bi_flashsize; - //request maximum flash size address spzce - start_scan_addr = (unsigned long)ioremap(flash_addr, flash_size); + + //request maximum flash size address space + start_scan_addr = ioremap(flash_addr, flash_size); if (!start_scan_addr) { - //printk("%s:Failed to ioremap address:0x%x\n", __FUNCTION__, FLASH_ADDR); - printk("%s:Failed to ioremap address:0x%x\n", __FUNCTION__, flash_addr); + printk(KERN_WARNING "%s:Failed to ioremap address:0x%x\n", __FUNCTION__, flash_addr); return -EIO; } - for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) - { + + for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) { if(mtd_size >= flash_size) break; - printk("%s: chip probing count %d\n", __FUNCTION__, idx); + printk(KERN_INFO "%s: chip probing count %d\n", __FUNCTION__, idx); map_banks[idx] = (struct map_info *)kmalloc(sizeof(struct map_info), GFP_KERNEL); - if(map_banks[idx] == NULL) - { - //return -ENOMEM; + if(map_banks[idx] == NULL) { ret = -ENOMEM; + /* FIXME: What if some MTD devices were probed already? */ goto error_mem; } + memset((void *)map_banks[idx], 0, sizeof(struct map_info)); map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL); - if(map_banks[idx]->name == NULL) - { - //return -ENOMEM; + + if (!map_banks[idx]->name) { ret = -ENOMEM; + /* FIXME: What if some MTD devices were probed already? */ goto error_mem; } - memset((void *)map_banks[idx]->name, 0, 16); - sprintf(map_banks[idx]->name, "TQM8xxL%d", idx); + map_banks[idx]->size = flash_size; - map_banks[idx]->buswidth = 4; - map_banks[idx]->read8 = tqm8xxl_read8; - map_banks[idx]->read16 = tqm8xxl_read16; - map_banks[idx]->read32 = tqm8xxl_read32; - map_banks[idx]->copy_from = tqm8xxl_copy_from; - map_banks[idx]->write8 = tqm8xxl_write8; - map_banks[idx]->write16 = tqm8xxl_write16; - map_banks[idx]->write32 = tqm8xxl_write32; - map_banks[idx]->copy_to = tqm8xxl_copy_to; - map_banks[idx]->map_priv_1 = - start_scan_addr + ((idx > 0) ? + map_banks[idx]->bankwidth = 4; + + simple_map_init(map_banks[idx]); + + map_banks[idx]->virt = start_scan_addr; + map_banks[idx]->phys = flash_addr; + /* FIXME: This looks utterly bogus, but I'm trying to + preserve the behaviour of the original (shown here)... + + map_banks[idx]->map_priv_1 = + start_scan_addr + ((idx > 0) ? (mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0); + */ + + if (idx && mtd_banks[idx-1]) { + map_banks[idx]->virt += mtd_banks[idx-1]->size; + map_banks[idx]->phys += mtd_banks[idx-1]->size; + } + //start to probe flash chips mtd_banks[idx] = do_map_probe("cfi_probe", map_banks[idx]); - if(mtd_banks[idx]) - { - mtd_banks[idx]->module = THIS_MODULE; + + if (mtd_banks[idx]) { + mtd_banks[idx]->owner = THIS_MODULE; mtd_size += mtd_banks[idx]->size; num_banks++; - printk("%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks, + + printk(KERN_INFO "%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks, mtd_banks[idx]->name, mtd_banks[idx]->size); } } /* no supported flash chips found */ - if(!num_banks) - { - printk("TQM8xxL: No support flash chips found!\n"); + if (!num_banks) { + printk(KERN_NOTICE "TQM8xxL: No support flash chips found!\n"); ret = -ENXIO; goto error_mem; } @@ -231,12 +196,13 @@ */ part_banks[0].mtd_part = tqm8xxl_partitions; part_banks[0].type = "Static image"; - part_banks[0].nums = NB_OF(tqm8xxl_partitions); + part_banks[0].nums = ARRAY_SIZE(tqm8xxl_partitions); + part_banks[1].mtd_part = tqm8xxl_fs_partitions; part_banks[1].type = "Static file system"; - part_banks[1].nums = NB_OF(tqm8xxl_fs_partitions); - for(idx = 0; idx < num_banks ; idx++) - { + part_banks[1].nums = ARRAY_SIZE(tqm8xxl_fs_partitions); + + for(idx = 0; idx < num_banks ; idx++) { if (part_banks[idx].nums == 0) { printk(KERN_NOTICE "TQM flash%d: no partition info available, registering whole flash at once\n", idx); add_mtd_device(mtd_banks[idx]); @@ -254,12 +220,9 @@ #endif return 0; error_mem: - for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) - { - if(map_banks[idx] != NULL) - { - if(map_banks[idx]->name != NULL) - { + for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) { + if(map_banks[idx] != NULL) { + if(map_banks[idx]->name != NULL) { kfree(map_banks[idx]->name); map_banks[idx]->name = NULL; } @@ -267,18 +230,15 @@ map_banks[idx] = NULL; } } - //return -ENOMEM; error: - iounmap((void *)start_scan_addr); - //return -ENXIO; + iounmap(start_scan_addr); return ret; } static void __exit cleanup_tqm_mtd(void) { unsigned int idx = 0; - for(idx = 0 ; idx < num_banks ; idx++) - { + for(idx = 0 ; idx < num_banks ; idx++) { /* destroy mtd_info previously allocated */ if (mtd_banks[idx]) { del_mtd_partitions(mtd_banks[idx]); @@ -288,8 +248,9 @@ kfree(map_banks[idx]->name); kfree(map_banks[idx]); } + if (start_scan_addr) { - iounmap((void *)start_scan_addr); + iounmap(start_scan_addr); start_scan_addr = 0; } } Index: drivers/mtd/maps/ts7xxx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/ts7xxx.c,v retrieving revision 1.1 retrieving revision 1.8 diff -u -r1.1 -r1.8 --- drivers/mtd/maps/ts7xxx.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/ts7xxx.c 7 Mar 2005 19:21:53 -0000 1.8 @@ -1,7 +1,7 @@ /* - * $Id: ts7xxx.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: ts7xxx.c,v 1.8 2005/03/07 19:21:53 joff Exp $ * - * Mapping for the Intel XScale IQ80310 evaluation board + * Mapping for the Technologic Systems TS-7200 board * * Author: Nicolas Pitre * Copyright: (C) 2001 MontaVista Software Inc. @@ -12,91 +12,69 @@ */ #include +#include +#include #include +#include #include +#include +#include #include #include #include #include - #define BUSWIDTH 2 static struct mtd_info *mymtd; -static __u8 ts7xxx_read8(struct map_info *map, unsigned long ofs) -{ - return *(__u8 *)(map->map_priv_1 + ofs); -} - -static __u16 ts7xxx_read16(struct map_info *map, unsigned long ofs) -{ - return *(__u16 *)(map->map_priv_1 + ofs); -} - -static __u32 ts7xxx_read32(struct map_info *map, unsigned long ofs) -{ - return *(__u32 *)(map->map_priv_1 + ofs); -} - -static void ts7xxx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy(to, (void *)(map->map_priv_1 + from), len); -} - -static void ts7xxx_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - *(__u8 *)(map->map_priv_1 + adr) = d; -} - -static void ts7xxx_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - *(__u16 *)(map->map_priv_1 + adr) = d; -} - -static void ts7xxx_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - *(__u32 *)(map->map_priv_1 + adr) = d; -} - -static void ts7xxx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy((void *)(map->map_priv_1 + to), from, len); -} - static struct map_info hiflash_map = { - name: "TS-7XXX high flash", - size: 0x00800000, - buswidth: BUSWIDTH, - read8: ts7xxx_read8, - read16: ts7xxx_read16, - read32: ts7xxx_read32, - copy_from: ts7xxx_copy_from, - write8: ts7xxx_write8, - write16: ts7xxx_write16, - write32: ts7xxx_write32, - copy_to: ts7xxx_copy_to + .name = "TS-7200 high flash", + .size = 0x01000000, + .bankwidth = BUSWIDTH, + .phys = 0x61000000 }; static struct map_info loflash_map = { - name: "TS-7XXX flash", - size: 0x00800000, - buswidth: BUSWIDTH, - read8: ts7xxx_read8, - read16: ts7xxx_read16, - read32: ts7xxx_read32, - copy_from: ts7xxx_copy_from, - write8: ts7xxx_write8, - write16: ts7xxx_write16, - write32: ts7xxx_write32, - copy_to: ts7xxx_copy_to + .name = "TS-7200 flash", + .size = 0x01000000, + .bankwidth = BUSWIDTH, + .phys = 0x60000000 +}; + +static struct mtd_partition ts7xxx_parts[3] = { + { + name: "TS-BOOTROM", + size: 0x00020000, + offset: 0, + }, + { + name: "Linux", + size: 0x00600000, + offset: 0x00020000, + }, + { + name: "RedBoot", + size: 0x001e0000, + offset: 0x00620000, + } }; -static struct mtd_partition ts7xxx_parts[1] = { +static struct mtd_partition ts7xxx_16mb_parts[3] = { { - name: "entire chip", - size: 0x00800000, + name: "TS-BOOTROM", + size: 0x00020000, offset: 0, + }, + { + name: "Linux", + size: 0x00e00000, + offset: 0x00020000, + }, + { + name: "RedBoot", + size: 0x001e0000, + offset: 0x00e20000, } }; @@ -109,22 +87,24 @@ static int __init init_ts7xxx(void) { - struct mtd_partition *parts; - int nb_parts = 0; - int ret; - loflash_map.map_priv_1 = (unsigned long)IO_ADDRESS(TS7XXX_FLASH_BASE); - hiflash_map.map_priv_1 = (unsigned long)IO_ADDRESS(TS7XXX_FLASH2_BASE); + loflash_map.virt = (void *)IO_ADDRESS(TS7XXX_FLASH_BASE); + simple_map_init(&loflash_map); lomtd = do_map_probe("cfi_probe", &loflash_map); if (!lomtd) { return -ENXIO; } - lomtd->module = THIS_MODULE; - himtd = do_map_probe("cfi_probe", &hiflash_map); - if (himtd) { - himtd->module = THIS_MODULE; + lomtd->owner = THIS_MODULE; + if (inb(TS7XXX_STATUS2) & 0x4) { + hiflash_map.virt = (void *)IO_ADDRESS(TS7XXX_FLASH2_BASE); + simple_map_init(&hiflash_map); + himtd = do_map_probe("cfi_probe", &hiflash_map); + if (himtd) { + himtd->owner = THIS_MODULE; + } } + #ifdef CONFIG_MTD_REDBOOT_PARTS ret = parse_redboot_partitions(lomtd, &loparsed_parts); @@ -141,8 +121,17 @@ } } #else - add_mtd_partitions(lomtd, ts7xxx_parts, NB_OF(ts7xxx_parts)); - if (himtd) add_mtd_partitions(himtd, ts7xxx_parts, NB_OF(ts7xxx_parts)); + if (lomtd->size > 0x800000) + add_mtd_partitions(lomtd, ts7xxx_16mb_parts, NB_OF(ts7xxx_16mb_parts)); + else + add_mtd_partitions(lomtd, ts7xxx_parts, NB_OF(ts7xxx_parts)); + + if (himtd) { + if (himtd->size > 0x800000) + add_mtd_partitions(himtd, ts7xxx_16mb_parts, NB_OF(ts7xxx_16mb_parts)); + else + add_mtd_partitions(himtd, ts7xxx_parts, NB_OF(ts7xxx_parts)); + } #endif return 0; Index: drivers/mtd/maps/tsunami_flash.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/tsunami_flash.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/tsunami_flash.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/tsunami_flash.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -2,25 +2,29 @@ * tsunami_flash.c * * flash chip on alpha ds10... - * $Id: tsunami_flash.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: tsunami_flash.c,v 1.3 2004/11/03 00:04:44 joff Exp $ */ #include #include +#include #include +#include #define FLASH_ENABLE_PORT 0x00C00001 #define FLASH_ENABLE_BYTE 0x01 #define FLASH_DISABLE_BYTE 0x00 #define MAX_TIG_FLASH_SIZE (12*1024*1024) -static inline __u8 tsunami_flash_read8(struct map_info *map, unsigned long offset) +static inline map_word tsunami_flash_read8(struct map_info *map, unsigned long offset) { - return tsunami_tig_readb(offset); + map_word val; + val.x[0] = tsunami_tig_readb(offset); + return val; } -static void tsunami_flash_write8(struct map_info *map, __u8 value, unsigned long offset) +static void tsunami_flash_write8(struct map_info *map, map_word value, unsigned long offset) { - tsunami_tig_writeb(value, offset); + tsunami_tig_writeb(value.x[0], offset); } static void tsunami_flash_copy_from( @@ -58,18 +62,12 @@ static struct map_info tsunami_flash_map = { .name = "flash chip on the Tsunami TIG bus", .size = MAX_TIG_FLASH_SIZE, - .buswidth = 1, - .read8 = tsunami_flash_read8, - .read16 = 0, - .read32 = 0, + .phys = NO_XIP; + .bankwidth = 1, + .read = tsunami_flash_read8, .copy_from = tsunami_flash_copy_from, - .write8 = tsunami_flash_write8, - .write16 = 0, - .write32 = 0, + .write = tsunami_flash_write8, .copy_to = tsunami_flash_copy_to, - .set_vpp = 0, - .map_priv_1 = 0, - }; static struct mtd_info *tsunami_flash_mtd; @@ -88,7 +86,7 @@ static int __init init_tsunami_flash(void) { - static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", 0 }; + static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL }; char **type; tsunami_tig_writeb(FLASH_ENABLE_BYTE, FLASH_ENABLE_PORT); @@ -99,7 +97,7 @@ tsunami_flash_mtd = do_map_probe(*type, &tsunami_flash_map); } if (tsunami_flash_mtd) { - tsunami_flash_mtd->module = THIS_MODULE; + tsunami_flash_mtd->owner = THIS_MODULE; add_mtd_device(tsunami_flash_mtd); return 0; } Index: drivers/mtd/maps/uclinux.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/uclinux.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/uclinux.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/uclinux.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -5,7 +5,7 @@ * * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) * - * $Id: uclinux.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: uclinux.c,v 1.3 2004/11/03 00:04:44 joff Exp $ */ /****************************************************************************/ @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -24,58 +25,11 @@ /****************************************************************************/ -__u8 uclinux_read8(struct map_info *map, unsigned long ofs) -{ - return(*((__u8 *) (map->map_priv_1 + ofs))); -} - -__u16 uclinux_read16(struct map_info *map, unsigned long ofs) -{ - return(*((__u16 *) (map->map_priv_1 + ofs))); -} - -__u32 uclinux_read32(struct map_info *map, unsigned long ofs) -{ - return(*((__u32 *) (map->map_priv_1 + ofs))); -} - -void uclinux_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - memcpy(to, (void *)(map->map_priv_1 + from), len); -} - -void uclinux_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - *((__u8 *) (map->map_priv_1 + adr)) = d; -} - -void uclinux_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - *((__u16 *) (map->map_priv_1 + adr)) = d; -} - -void uclinux_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - *((__u32 *) (map->map_priv_1 + adr)) = d; -} - -void uclinux_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - memcpy((void *) (map->map_priv_1 + to), from, len); -} /****************************************************************************/ struct map_info uclinux_ram_map = { - name: "RAM", - read8: uclinux_read8, - read16: uclinux_read16, - read32: uclinux_read32, - copy_from: uclinux_copy_from, - write8: uclinux_write8, - write16: uclinux_write16, - write32: uclinux_write32, - copy_to: uclinux_copy_to, + .name = "RAM", }; struct mtd_info *uclinux_ram_mtdinfo; @@ -83,7 +37,7 @@ /****************************************************************************/ struct mtd_partition uclinux_romfs[] = { - { name: "ROMfs", offset: 0 } + { .name = "ROMfs" } }; #define NUM_PARTITIONS (sizeof(uclinux_romfs) / sizeof(uclinux_romfs[0])) @@ -94,7 +48,7 @@ size_t *retlen, u_char **mtdbuf) { struct map_info *map = (struct map_info *) mtd->priv; - *mtdbuf = (u_char *) (map->map_priv_1 + ((int) from)); + *mtdbuf = (u_char *) (map->virt + ((int) from)); *retlen = len; return(0); } @@ -108,29 +62,31 @@ extern char _ebss; mapp = &uclinux_ram_map; - mapp->map_priv_2 = (unsigned long) &_ebss; + mapp->phys = (unsigned long) &_ebss; mapp->size = PAGE_ALIGN(*((unsigned long *)((&_ebss) + 8))); - mapp->buswidth = 4; + mapp->bankwidth = 4; printk("uclinux[mtd]: RAM probe address=0x%x size=0x%x\n", (int) mapp->map_priv_2, (int) mapp->size); - mapp->map_priv_1 = (unsigned long) - ioremap_nocache(mapp->map_priv_2, mapp->size); + mapp->virt = (void __iomem *) + ioremap_nocache(mapp->phys, mapp->size); - if (mapp->map_priv_1 == 0) { + if (mapp->virt == 0) { printk("uclinux[mtd]: ioremap_nocache() failed\n"); return(-EIO); } + simple_map_init(mapp); + mtd = do_map_probe("map_ram", mapp); if (!mtd) { printk("uclinux[mtd]: failed to find a mapping?\n"); - iounmap((void *) mapp->map_priv_1); + iounmap((void *) mapp->virt); return(-ENXIO); } - mtd->module = THIS_MODULE; + mtd->owner = THIS_MODULE; mtd->point = uclinux_point; mtd->priv = mapp; @@ -155,8 +111,8 @@ uclinux_ram_mtdinfo = NULL; } if (uclinux_ram_map.map_priv_1) { - iounmap((void *) uclinux_ram_map.map_priv_1); - uclinux_ram_map.map_priv_1 = 0; + iounmap((void *) uclinux_ram_map.virt); + uclinux_ram_map.virt = 0; } } Index: drivers/mtd/maps/vmax301.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/maps/vmax301.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/maps/vmax301.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/mtd/maps/vmax301.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -1,4 +1,4 @@ -// $Id: vmax301.c,v 1.1 2004/07/22 19:49:45 joff Exp $ +// $Id: vmax301.c,v 1.3 2004/11/03 00:04:44 joff Exp $ /* ###################################################################### Tempustech VMAX SBC301 MTD Driver. @@ -24,6 +24,7 @@ #include #include +#include #define WINDOW_START 0xd8000 @@ -53,32 +54,12 @@ __vmax301_page(map, page); } -static __u8 vmax301_read8(struct map_info *map, unsigned long ofs) +static map_word vmax301_read8(struct map_info *map, unsigned long ofs) { - __u8 ret; + map_word ret; spin_lock(&vmax301_spin); vmax301_page(map, ofs); - ret = readb(map->map_priv_2 + (ofs & WINDOW_MASK)); - spin_unlock(&vmax301_spin); - return ret; -} - -static __u16 vmax301_read16(struct map_info *map, unsigned long ofs) -{ - __u16 ret; - spin_lock(&vmax301_spin); - vmax301_page(map, ofs); - ret = readw(map->map_priv_2 + (ofs & WINDOW_MASK)); - spin_unlock(&vmax301_spin); - return ret; -} - -static __u32 vmax301_read32(struct map_info *map, unsigned long ofs) -{ - __u32 ret; - spin_lock(&vmax301_spin); - vmax301_page(map, ofs); - ret = readl(map->map_priv_2 + (ofs & WINDOW_MASK)); + ret.x[0] = readb(map->map_priv_2 + (ofs & WINDOW_MASK)); spin_unlock(&vmax301_spin); return ret; } @@ -99,27 +80,11 @@ } } -static void vmax301_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - spin_lock(&vmax301_spin); - vmax301_page(map, adr); - writeb(d, map->map_priv_2 + (adr & WINDOW_MASK)); - spin_unlock(&vmax301_spin); -} - -static void vmax301_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - spin_lock(&vmax301_spin); - vmax301_page(map, adr); - writew(d, map->map_priv_2 + (adr & WINDOW_MASK)); - spin_unlock(&vmax301_spin); -} - -static void vmax301_write32(struct map_info *map, __u32 d, unsigned long adr) +static void vmax301_write8(struct map_info *map, map_word d, unsigned long adr) { spin_lock(&vmax301_spin); vmax301_page(map, adr); - writel(d, map->map_priv_2 + (adr & WINDOW_MASK)); + writeb(d.x[0], map->map_priv_2 + (adr & WINDOW_MASK)); spin_unlock(&vmax301_spin); } @@ -142,34 +107,28 @@ static struct map_info vmax_map[2] = { { - name: "VMAX301 Internal Flash", - size: 3*2*1024*1024, - buswidth: 1, - read8: vmax301_read8, - read16: vmax301_read16, - read32: vmax301_read32, - copy_from: vmax301_copy_from, - write8: vmax301_write8, - write16: vmax301_write16, - write32: vmax301_write32, - copy_to: vmax301_copy_to, - map_priv_1: WINDOW_START + WINDOW_LENGTH, - map_priv_2: 0xFFFFFFFF + .name = "VMAX301 Internal Flash", + .phys = NO_XIP, + .size = 3*2*1024*1024, + .bankwidth = 1, + .read = vmax301_read8, + .copy_from = vmax301_copy_from, + .write = vmax301_write8, + .copy_to = vmax301_copy_to, + .map_priv_1 = WINDOW_START + WINDOW_LENGTH, + .map_priv_2 = 0xFFFFFFFF }, { - name: "VMAX301 Socket", - size: 0, - buswidth: 1, - read8: vmax301_read8, - read16: vmax301_read16, - read32: vmax301_read32, - copy_from: vmax301_copy_from, - write8: vmax301_write8, - write16: vmax301_write16, - write32: vmax301_write32, - copy_to: vmax301_copy_to, - map_priv_1: WINDOW_START + (3*WINDOW_LENGTH), - map_priv_2: 0xFFFFFFFF + .name = "VMAX301 Socket", + .phys = NO_XIP, + .size = 0, + .bankwidth = 1, + .read = vmax301_read8, + .copy_from = vmax301_copy_from, + .write = vmax301_write8, + .copy_to = vmax301_copy_to, + .map_priv_1 = WINDOW_START + (3*WINDOW_LENGTH), + .map_priv_2 = 0xFFFFFFFF } }; @@ -206,8 +165,8 @@ address of the first half, because it's used more often. */ - vmax_map[0].map_priv_1 = iomapadr + WINDOW_START; - vmax_map[1].map_priv_1 = iomapadr + (3*WINDOW_START); + vmax_map[0].map_priv_2 = iomapadr + WINDOW_START; + vmax_map[1].map_priv_2 = iomapadr + (3*WINDOW_START); for (i=0; i<2; i++) { vmax_mtd[i] = do_map_probe("cfi_probe", &vmax_map[i]); @@ -218,7 +177,7 @@ if (!vmax_mtd[i]) vmax_mtd[i] = do_map_probe("map_rom", &vmax_map[i]); if (vmax_mtd[i]) { - vmax_mtd[i]->module = THIS_MODULE; + vmax_mtd[i]->owner = THIS_MODULE; add_mtd_device(vmax_mtd[i]); } } Index: drivers/mtd/maps/x =================================================================== RCS file: drivers/mtd/maps/x diff -N drivers/mtd/maps/x --- drivers/mtd/maps/x 22 Jul 2004 19:49:45 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,21 +0,0 @@ -static struct mtd_partition iq80310_partitions[4] = { - { - name: "Firmware", - size: 0x00080000, - offset: 0, - mask_flags: MTD_WRITEABLE /* force read-only */ - },{ - name: "Kernel", - size: 0x000a0000, - offset: 0x00080000, - },{ - name: "Filesystem", - size: 0x00600000, - offset: 0x00120000 - },{ - name: "RedBoot", - size: 0x000e0000, - offset: 0x00720000, - mask_flags: MTD_WRITEABLE - } -}; Index: drivers/mtd/nand/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/nand/Config.in,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/nand/Config.in 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/nand/Config.in 3 Nov 2004 00:04:44 -0000 1.3 @@ -1,6 +1,6 @@ # drivers/mtd/nand/Config.in -# $Id: Config.in,v 1.1 2004/07/22 19:49:46 joff Exp $ +# $Id: Config.in,v 1.3 2004/11/03 00:04:44 joff Exp $ mainmenu_option next_comment @@ -11,26 +11,48 @@ bool ' Verify NAND page writes' CONFIG_MTD_NAND_VERIFY_WRITE fi -if [ "$CONFIG_ARM" = "y" -a "$CONFIG_ARCH_P720T" = "y" ]; then - dep_tristate ' NAND Flash device on SPIA board' CONFIG_MTD_NAND_SPIA $CONFIG_MTD_NAND +if [ "$CONFIG_ARM" = "y" ]; then + dep_tristate ' NAND Flash device on SPIA board' CONFIG_MTD_NAND_SPIA $CONFIG_MTD_NAND $CONFIG_ARCH_P720T + dep_tristate ' NAND Flash device on TOTO board' CONFIG_MTD_NAND_TOTO $CONFIG_MTD_NAND $CONFIG_ARCH_OMAP + dep_tristate ' SmartMedia Card on AUTCPU12 board' CONFIG_MTD_NAND_AUTCPU12 $CONFIG_MTD_NAND $CONFIG_ARCH_AUTCPU12 + dep_tristate ' NAND Flash device on EDP7312 board' CONFIG_MTD_NAND_EDB7312 $CONFIG_MTD_NAND $CONFIG_ARCH_EDB7312 + dep_tristate ' NAND Flash device on TS-7250 board' CONFIG_MTD_NAND_TS7250 $CONFIG_MTD_NAND fi -if [ "$CONFIG_ARCH_AUTCPU12" = "y" ]; then - dep_tristate ' SmartMedia Card on AUTCPU12 board' CONFIG_MTD_NAND_AUTCPU12 $CONFIG_MTD_NAND +if [ "$CONFIG_MTD_DOC2001PLUS" = "y" -o "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" -o "$CONFIG_MTD_NAND" = "y" ]; then + define_bool CONFIG_MTD_NAND_IDS y +else + if [ "$CONFIG_MTD_DOC2001PLUS" = "m" -o "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" -o "$CONFIG_MTD_NAND" = "m" ]; then + define_bool CONFIG_MTD_NAND_IDS m + fi fi -if [ "$CONFIG_ARCH_EDB7312" = "y" ]; then - dep_tristate ' NAND Flash device on EDP7312 board' CONFIG_MTD_NAND_EDB7312 $CONFIG_MTD_NAND +if [ "$CONFIG_TOSHIBA_RBTX4925" = "y" ]; then + dep_tristate ' SmartMedia Card on Toshiba RBTX4925 reference board' CONFIG_MTD_NAND_TX4925NDFMC $CONFIG_MTD_NAND $CONFIG_TOSHIBA_RBTX4925_MPLEX_NAND fi -if [ "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" -o "$CONFIG_MTD_NAND" = "y" ]; then - define_bool CONFIG_MTD_NAND_IDS y +if [ "$CONFIG_TOSHIBA_RBTX4938" = "y" ]; then + dep_tristate ' NAND Flash device on Toshiba RBTX4938 reference board' CONFIG_MTD_NAND_TX4938NDFMC $CONFIG_MTD_NAND $CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND +fi + +if [ "$CONFIG_PPCHAMELEONEVB" = "y" ]; then + dep_tristate ' NAND Flash device on PPChameleonEVB board' CONFIG_MTD_NAND_PPCHAMELEONEVB $CONFIG_MTD_NAND fi -if [ "$CONFIG_MTD_NAND_IDS" != "y" ]; then -if [ "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" -o "$CONFIG_MTD_NAND" = "m" ]; then - define_bool CONFIG_MTD_NAND_IDS m +if [ "$CONFIG_SOC_AU1550" = "y" ]; then + dep_tristate ' NAND Flash Driver for Au1550 controller' CONFIG_MTD_NAND_AU1550 $CONFIG_MTD_NAND fi + +if [ "$CONFIG_SH_SOLUTION_ENGINE" = "y" ]; then + dep_tristate ' Renesas Flash ROM 4-slot interface board (FROM_BOARD4)' CONFIG_MTD_NAND_RTC_FROM4 $CONFIG_MTD_NAND +fi + +dep_tristate ' DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation) (EXPERIMENTAL)' CONFIG_MTD_NAND_DISKONCHIP $CONFIG_MTD_NAND $CONFIG_EXPERIMENTAL +if [ "$CONFIG_MTD_NAND_DISKONCHIP" = "y" -o "$CONFIG_MTD_NAND_DISKONCHIP" = "m" ]; then + bool ' Advanced detection options for DiskOnChip' CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED + hex ' Physical address of DiskOnChip' CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS + bool ' Probe high addresses' CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH $CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED + bool ' Allow BBT write on DiskOnChip Millennium and 2000TSOP' CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE fi endmenu Index: drivers/mtd/nand/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/nand/Makefile,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/nand/Makefile 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/nand/Makefile 3 Nov 2004 00:04:44 -0000 1.3 @@ -1,16 +1,16 @@ # -# linux/drivers/nand/Makefile +# linux/drivers/nand/Makefile.24 +# Makefile for obsolete kernels. # -# $Id: Makefile,v 1.1 2004/07/22 19:49:46 joff Exp $ +# $Id: Makefile,v 1.3 2004/11/03 00:04:44 joff Exp $ O_TARGET := nandlink.o +export-objs := nand_base.o nand_bbt.o nand_ecc.o nand_ids.o +list-multi := nand.o -export-objs := nand.o nand_ecc.o nand_ids.o - -obj-$(CONFIG_MTD_NAND) += nand.o nand_ecc.o -obj-$(CONFIG_MTD_NAND_SPIA) += spia.o -obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o -obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o -obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o +include Makefile.common include $(TOPDIR)/Rules.make + +nand.o: $(nand-objs) + $(LD) -r -o $@ $(nand-objs) Index: drivers/mtd/nand/autcpu12.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/nand/autcpu12.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/nand/autcpu12.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/nand/autcpu12.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -4,9 +4,9 @@ * Copyright (c) 2002 Thomas Gleixner * * Derived from drivers/mtd/spia.c - * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com) + * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) * - * $Id: autcpu12.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: autcpu12.c,v 1.3 2004/11/03 00:04:44 joff 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 @@ -15,7 +15,7 @@ * Overview: * This is a device driver for the NAND flash device found on the * autronix autcpu12 board, which is a SmartMediaCard. It supports - * 16MB, 32MB and 64MB cards. + * 16MiB, 32MiB and 64MiB cards. * * * 02-12-2002 TG Cleanup of module params @@ -25,10 +25,11 @@ * added page_cache * * 10-06-2002 TG 128K card support added - * */ +#include #include +#include #include #include #include @@ -43,19 +44,11 @@ */ static struct mtd_info *autcpu12_mtd = NULL; -/* - * Module stuff - */ -#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE) -#define autcpu12_init init_module -#define autcpu12_cleanup cleanup_module -#endif - static int autcpu12_io_base = CS89712_VIRT_BASE; static int autcpu12_fio_pbase = AUTCPU12_PHYS_SMC; static int autcpu12_fio_ctrl = AUTCPU12_SMC_SELECT_OFFSET; static int autcpu12_pedr = AUTCPU12_SMC_PORT_OFFSET; -static int autcpu12_fio_base; +static void __iomem * autcpu12_fio_base; #ifdef MODULE MODULE_PARM(autcpu12_fio_pbase, "i"); @@ -70,41 +63,40 @@ /* * Define partitions for flash devices */ - static struct mtd_partition partition_info16k[] = { - { name: "AUTCPU12 flash partition 1", - offset: 0, - size: 8 * SZ_1M }, - { name: "AUTCPU12 flash partition 2", - offset: 8 * SZ_1M, - size: 8 * SZ_1M }, + { .name = "AUTCPU12 flash partition 1", + .offset = 0, + .size = 8 * SZ_1M }, + { .name = "AUTCPU12 flash partition 2", + .offset = 8 * SZ_1M, + .size = 8 * SZ_1M }, }; static struct mtd_partition partition_info32k[] = { - { name: "AUTCPU12 flash partition 1", - offset: 0, - size: 8 * SZ_1M }, - { name: "AUTCPU12 flash partition 2", - offset: 8 * SZ_1M, - size: 24 * SZ_1M }, + { .name = "AUTCPU12 flash partition 1", + .offset = 0, + .size = 8 * SZ_1M }, + { .name = "AUTCPU12 flash partition 2", + .offset = 8 * SZ_1M, + .size = 24 * SZ_1M }, }; static struct mtd_partition partition_info64k[] = { - { name: "AUTCPU12 flash partition 1", - offset: 0, - size: 16 * SZ_1M }, - { name: "AUTCPU12 flash partition 2", - offset: 16 * SZ_1M, - size: 48 * SZ_1M}, + { .name = "AUTCPU12 flash partition 1", + .offset = 0, + .size = 16 * SZ_1M }, + { .name = "AUTCPU12 flash partition 2", + .offset = 16 * SZ_1M, + .size = 48 * SZ_1M }, }; static struct mtd_partition partition_info128k[] = { - { name: "AUTCPU12 flash partition 1", - offset: 0, - size: 16 * SZ_1M }, - { name: "AUTCPU12 flash partition 2", - offset: 16 * SZ_1M, - size: 112 * SZ_1M}, + { .name = "AUTCPU12 flash partition 1", + .offset = 0, + .size = 16 * SZ_1M }, + { .name = "AUTCPU12 flash partition 2", + .offset = 16 * SZ_1M, + .size = 112 * SZ_1M }, }; #define NUM_PARTITIONS16K 2 @@ -114,7 +106,7 @@ /* * hardware specific access to control-lines */ -void autcpu12_hwcontrol(int cmd) +static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd) { switch(cmd){ @@ -133,12 +125,13 @@ /* * read device ready pin */ -int autcpu12_device_ready(void) +int autcpu12_device_ready(struct mtd_info *mtd) { return ( (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) & AUTCPU12_SMC_RDY) ? 1 : 0; } + /* * Main initialization routine */ @@ -157,7 +150,7 @@ } /* map physical adress */ - autcpu12_fio_base=(unsigned long)ioremap(autcpu12_fio_pbase,SZ_1K); + autcpu12_fio_base=(void __iomem *)ioremap(autcpu12_fio_pbase,SZ_1K); if(!autcpu12_fio_base){ printk("Ioremap autcpu12 SmartMedia Card failed\n"); err = -EIO; @@ -183,29 +176,18 @@ this->chip_delay = 20; this->eccmode = NAND_ECC_SOFT; + /* Enable the following for a flash based bad block table */ + /* + this->options = NAND_USE_FLASH_BBT; + */ + this->options = NAND_USE_FLASH_BBT; + /* Scan to find existance of the device */ - if (nand_scan (autcpu12_mtd)) { + if (nand_scan (autcpu12_mtd, 1)) { err = -ENXIO; goto out_ior; } - - /* Allocate memory for internal data buffer */ - this->data_buf = kmalloc (sizeof(u_char) * (autcpu12_mtd->oobblock + autcpu12_mtd->oobsize), GFP_KERNEL); - if (!this->data_buf) { - printk ("Unable to allocate NAND data buffer for AUTCPU12.\n"); - err = -ENOMEM; - goto out_ior; - } - - /* Allocate memory for internal data buffer */ - this->data_cache = kmalloc (sizeof(u_char) * (autcpu12_mtd->oobblock + autcpu12_mtd->oobsize), GFP_KERNEL); - if (!this->data_cache) { - printk ("Unable to allocate NAND data cache for AUTCPU12.\n"); - err = -ENOMEM; - goto out_buf; - } - this->cache_page = -1; - + /* Register the partitions */ switch(autcpu12_mtd->size){ case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break; @@ -215,15 +197,11 @@ default: { printk ("Unsupported SmartMedia device\n"); err = -ENXIO; - goto out_cac; + goto out_ior; } } goto out; -out_cac: - kfree (this->data_cache); -out_buf: - kfree (this->data_buf); out_ior: iounmap((void *)autcpu12_fio_base); out_mtd: @@ -240,21 +218,12 @@ #ifdef MODULE static void __exit autcpu12_cleanup (void) { - struct nand_chip *this = (struct nand_chip *) &autcpu12_mtd[1]; - - /* Unregister partitions */ - del_mtd_partitions(autcpu12_mtd); - - /* Unregister the device */ - del_mtd_device (autcpu12_mtd); - - /* Free internal data buffers */ - kfree (this->data_buf); - kfree (this->data_cache); + /* Release resources, unregister device */ + nand_release (autcpu12_mtd); /* unmap physical adress */ iounmap((void *)autcpu12_fio_base); - + /* Free the MTD device structure */ kfree (autcpu12_mtd); } Index: drivers/mtd/nand/edb7312.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/nand/edb7312.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/nand/edb7312.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/nand/edb7312.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -6,7 +6,7 @@ * Derived from drivers/mtd/nand/autcpu12.c * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) * - * $Id: edb7312.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: edb7312.c,v 1.3 2004/11/03 00:04:44 joff 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 @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -52,9 +53,9 @@ * Module stuff */ -static int ep7312_fio_pbase = EP7312_FIO_PBASE; -static int ep7312_pxdr = EP7312_PXDR; -static int ep7312_pxddr = EP7312_PXDDR; +static unsigned long ep7312_fio_pbase = EP7312_FIO_PBASE; +static void __iomem * ep7312_pxdr = (void __iomem *) EP7312_PXDR; +static void __iomem * ep7312_pxddr = (void __iomem *) EP7312_PXDDR; #ifdef MODULE MODULE_PARM(ep7312_fio_pbase, "i"); @@ -71,22 +72,19 @@ * Define static partitions for flash device */ static struct mtd_partition partition_info[] = { - { name: "EP7312 Nand Flash", - offset: 0, - size: 8*1024*1024 } + { .name = "EP7312 Nand Flash", + .offset = 0, + .size = 8*1024*1024 } }; #define NUM_PARTITIONS 1 -extern int parse_cmdline_partitions(struct mtd_info *master, - struct mtd_partition **pparts, - const char *mtd_id); #endif /* * hardware specific access to control-lines */ -static void ep7312_hwcontrol(int cmd) +static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd) { switch(cmd) { @@ -116,10 +114,13 @@ /* * read device ready pin */ -static int ep7312_device_ready(void) +static int ep7312_device_ready(struct mtd_info *mtd) { return 1; } +#ifdef CONFIG_MTD_PARTITIONS +const char *part_probes[] = { "cmdlinepart", NULL }; +#endif /* * Main initialization routine @@ -130,7 +131,7 @@ const char *part_type = 0; int mtd_parts_nb = 0; struct mtd_partition *mtd_parts = 0; - int ep7312_fio_base; + void __iomem * ep7312_fio_base; /* Allocate memory for MTD device structure and private data */ ep7312_mtd = kmalloc(sizeof(struct mtd_info) + @@ -142,7 +143,7 @@ } /* map physical adress */ - ep7312_fio_base = (unsigned long)ioremap(ep7312_fio_pbase, SZ_1K); + ep7312_fio_base = (void __iomem *)ioremap(ep7312_fio_pbase, SZ_1K); if(!ep7312_fio_base) { printk("ioremap EDB7312 NAND flash failed\n"); kfree(ep7312_mtd); @@ -174,42 +175,22 @@ this->chip_delay = 15; /* Scan to find existence of the device */ - if (nand_scan (ep7312_mtd)) { + if (nand_scan (ep7312_mtd, 1)) { iounmap((void *)ep7312_fio_base); kfree (ep7312_mtd); return -ENXIO; } - /* Allocate memory for internal data buffer */ - this->data_buf = kmalloc (sizeof(u_char) * (ep7312_mtd->oobblock + ep7312_mtd->oobsize), GFP_KERNEL); - if (!this->data_buf) { - printk("Unable to allocate NAND data buffer for EDB7312.\n"); - iounmap((void *)ep7312_fio_base); - kfree (ep7312_mtd); - return -ENOMEM; - } - - /* Allocate memory for internal data buffer */ - this->data_cache = kmalloc (sizeof(u_char) * (ep7312_mtd->oobblock + ep7312_mtd->oobsize), GFP_KERNEL); - if (!this->data_cache) { - printk("Unable to allocate NAND data cache for EDB7312.\n"); - kfree (this->data_buf); - iounmap((void *)ep7312_fio_base); - kfree (ep7312_mtd); - return -ENOMEM; - } - this->cache_page = -1; - -#ifdef CONFIG_MTD_CMDLINE_PARTS - mtd_parts_nb = parse_cmdline_partitions(ep7312_mtd, &mtd_parts, - "edb7312-nand"); +#ifdef CONFIG_MTD_PARTITIONS + ep7312_mtd->name = "edb7312-nand"; + mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes, + &mtd_parts, 0); if (mtd_parts_nb > 0) - part_type = "command line"; + part_type = "command line"; else - mtd_parts_nb = 0; + mtd_parts_nb = 0; #endif - if (mtd_parts_nb == 0) - { + if (mtd_parts_nb == 0) { mtd_parts = partition_info; mtd_parts_nb = NUM_PARTITIONS; part_type = "static"; @@ -231,12 +212,11 @@ { struct nand_chip *this = (struct nand_chip *) &ep7312_mtd[1]; - /* Unregister the device */ - del_mtd_device (ep7312_mtd); + /* Release resources, unregister device */ + nand_release (ap7312_mtd); /* Free internal data buffer */ kfree (this->data_buf); - kfree (this->data_cache); /* Free the MTD device structure */ kfree (ep7312_mtd); Index: drivers/mtd/nand/nand.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/nand/nand.c,v retrieving revision 1.1 retrieving revision 1.4 diff -u -r1.1 -r1.4 --- drivers/mtd/nand/nand.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/nand/nand.c 29 Sep 2006 22:26:17 -0000 1.4 @@ -115,7 +115,7 @@ * 12-05-2000 tglx: Dave Ellis (DGE@sixnetio) provided the fix for * WRITE_VERIFY long time ago. Thanks for remembering me. * - * $Id: nand.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: nand.c,v 1.4 2006/09/29 22:26:17 joff 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 @@ -316,9 +316,10 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) { - unsigned long timeo = jiffies; + unsigned long start, timeo; int status; + start = timeo = jiffies; if (state == FL_ERASING) timeo += (HZ * 400) / 1000; else @@ -341,7 +342,7 @@ break; spin_unlock_bh (&this->chip_lock); - yield (); + if ((jiffies - start) > ((HZ * 20) / 1000)) yield (); spin_lock_bh (&this->chip_lock); } status = (int) readb (this->IO_ADDR_R); @@ -1142,13 +1143,14 @@ while (len) { /* Check if we have a bad block, we do not erase bad blocks ! */ + /* Allow us to erase bad blocks this->cmdfunc (mtd, NAND_CMD_READOOB, NAND_BADBLOCK_POS, page); if (readb (this->IO_ADDR_R) != 0xff) { printk (KERN_WARNING "nand_erase: attempt to erase a bad block at page 0x%08x\n", page); instr->state = MTD_ERASE_FAILED; goto erase_exit; } - + */ /* Send commands to erase a page */ this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page); this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1); Index: drivers/mtd/nand/nand_base.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/nand/nand_base.c,v retrieving revision 1.1 retrieving revision 1.5 diff -u -r1.1 -r1.5 --- drivers/mtd/nand/nand_base.c 3 Nov 2004 00:04:44 -0000 1.1 +++ drivers/mtd/nand/nand_base.c 29 Sep 2006 22:26:17 -0000 1.5 @@ -41,7 +41,7 @@ * The AG-AND chips have nice features for speed improvement, * which are not supported yet. Read / program 4 pages in one go. * - * $Id: nand_base.c,v 1.1 2004/11/03 00:04:44 joff Exp $ + * $Id: nand_base.c,v 1.5 2006/09/29 22:26:17 joff 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 @@ -277,8 +277,9 @@ int i; struct nand_chip *this = mtd->priv; - for (i=0; iIO_ADDR_W); + } } /** @@ -291,11 +292,12 @@ */ static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) { - int i; + int i; struct nand_chip *this = mtd->priv; - for (i=0; iIO_ADDR_R); + for (i=0; iIO_ADDR_R); + } } /** @@ -422,7 +424,6 @@ /* Deselect and wake up anyone waiting on the device */ nand_release_device(mtd); } - return res; } @@ -756,9 +757,10 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) { - unsigned long timeo = jiffies; + unsigned long start, timeo; int status; + start = timeo = jiffies; if (state == FL_ERASING) timeo += (HZ * 400) / 1000; else @@ -785,7 +787,12 @@ if (this->read_byte(mtd) & NAND_STATUS_READY) break; } - yield (); + /* XXX: Only yield when we've polled for more than 10 ms. + * This prevents drastic slowdown in write speed if first poll + * is false. --joff + */ + if ((jiffies - start) > ((HZ * 10)/ 1000)) + yield (); } status = (int) this->read_byte(mtd); return status; @@ -806,6 +813,7 @@ * * Cached programming is not supported yet. */ + static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, struct nand_oobinfo *oobsel, int cached) { @@ -815,7 +823,6 @@ int *oob_config = oobsel->eccpos; int datidx = 0, eccidx = 0, eccsteps = this->eccsteps; int eccbytes = 0; - /* FIXME: Enable cached programming */ cached = 0; @@ -834,8 +841,9 @@ case NAND_ECC_SOFT: for (; eccsteps; eccsteps--) { this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code); - for (i = 0; i < 3; i++, eccidx++) + for (i = 0; i < 3; i++, eccidx++) { oob_buf[oob_config[eccidx]] = ecc_code[i]; + } datidx += this->eccsize; } this->write_buf(mtd, this->data_poi, mtd->oobblock); @@ -847,8 +855,10 @@ this->enable_hwecc(mtd, NAND_ECC_WRITE); this->write_buf(mtd, &this->data_poi[datidx], this->eccsize); this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code); - for (i = 0; i < eccbytes; i++, eccidx++) + + for (i = 0; i < eccbytes; i++, eccidx++) oob_buf[oob_config[eccidx]] = ecc_code[i]; + /* If the hardware ecc provides syndromes then * the ecc code must be written immidiately after * the data bytes (words) */ @@ -1040,7 +1050,6 @@ int compareecc = 1; int oobreadlen; - DEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); /* Do not allow reads past end of device */ @@ -1135,9 +1144,13 @@ } case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */ + this->read_buf(mtd, data_poi, end); - for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc) + + for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc) { this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); + } + break; default: @@ -1175,8 +1188,9 @@ goto readoob; /* Pick the ECC bytes out of the oob data */ - for (j = 0; j < oobsel->eccbytes; j++) + for (j = 0; j < oobsel->eccbytes; j++) { ecc_code[j] = oob_data[oob_config[j]]; + } /* correct data, if neccecary */ for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) { @@ -1271,7 +1285,7 @@ * fs driver will take care of that, because * retlen == desired len and result == -EBADMSG */ - *retlen = read; + *retlen = ecc_failed ? -1 : read; return ecc_failed ? -EBADMSG : 0; } @@ -2051,11 +2065,13 @@ while (len) { /* Check if we have a bad block, we do not erase bad blocks ! */ + /* Allow us to erase bad blocks if (nand_block_checkbad(mtd, ((loff_t) page) << this->page_shift, 0, allowbbt)) { printk (KERN_WARNING "nand_erase: attempt to erase a bad block at page 0x%08x\n", page); instr->state = MTD_ERASE_FAILED; goto erase_exit; } + */ /* Invalidate the page cache, if we erase the block which contains the current cached page */ Index: drivers/mtd/nand/nand_bbt.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/nand/nand_bbt.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/mtd/nand/nand_bbt.c 3 Nov 2004 00:04:44 -0000 1.1 +++ drivers/mtd/nand/nand_bbt.c 16 Nov 2004 17:16:52 -0000 1.2 @@ -6,7 +6,7 @@ * * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) * - * $Id: nand_bbt.c,v 1.1 2004/11/03 00:04:44 joff Exp $ + * $Id: nand_bbt.c,v 1.2 2004/11/16 17:16:52 joff 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 @@ -1001,25 +1001,27 @@ return nand_scan_bbt (mtd, &agand_flashbased); } + /* Is a flash based bad block table requested ? */ if (this->options & NAND_USE_FLASH_BBT) { /* Use the default pattern descriptors */ if (!this->bbt_td) { this->bbt_td = &bbt_main_descr; this->bbt_md = &bbt_mirror_descr; - } - if (mtd->oobblock > 512) - return nand_scan_bbt (mtd, &largepage_flashbased); - else - return nand_scan_bbt (mtd, &smallpage_flashbased); + } + if (!this->badblock_pattern) { + this->badblock_pattern = (mtd->oobblock > 512) ? + &largepage_flashbased : &smallpage_flashbased; + } } else { this->bbt_td = NULL; this->bbt_md = NULL; - if (mtd->oobblock > 512) - return nand_scan_bbt (mtd, &largepage_memorybased); - else - return nand_scan_bbt (mtd, &smallpage_memorybased); + if (!this->badblock_pattern) { + this->badblock_pattern = (mtd->oobblock > 512) ? + &largepage_memorybased : &smallpage_memorybased; + } } + return nand_scan_bbt (mtd, this->badblock_pattern); } /** Index: drivers/mtd/nand/nand_ecc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/nand/nand_ecc.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/nand/nand_ecc.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/nand/nand_ecc.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -1,22 +1,44 @@ /* - * drivers/mtd/nand_ecc.c + * This file contains an ECC algorithm from Toshiba that detects and + * corrects 1 bit errors in a 256 byte block of data. * - * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com) - * Toshiba America Electronics Components, Inc. + * drivers/mtd/nand/nand_ecc.c * - * $Id: nand_ecc.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com) + * Toshiba America Electronics Components, Inc. * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. + * $Id: nand_ecc.c,v 1.3 2004/11/03 00:04:44 joff Exp $ * - * This file contains an ECC algorithm from Toshiba that detects and - * corrects 1 bit errors in a 256 byte block of data. + * This file is free software; you can redistribute 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 file is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this file; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * As a special exception, if other files instantiate templates or use + * macros or inline functions from these files, or you compile these + * files and link them with other works to produce a work based on these + * files, these files do not by themselves cause the resulting work to be + * covered by the GNU General Public License. However the source code for + * these files must still be made available in accordance with section (3) + * of the GNU General Public License. + * + * This exception does not invalidate any other reasons why a work based on + * this file might be covered by the GNU General Public License. */ #include #include #include +#include /* * Pre-calculated 256-way 1 byte column parity @@ -41,7 +63,12 @@ }; -/* +/** + * nand_trans_result - [GENERIC] create non-inverted ECC + * @reg2: line parity reg 2 + * @reg3: line parity reg 3 + * @ecc_code: ecc + * * Creates non-inverted ECC code from line parity */ static void nand_trans_result(u_char reg2, u_char reg3, @@ -81,10 +108,13 @@ ecc_code[1] = tmp2; } -/* - * Calculate 3 byte ECC code for 256 byte block +/** + * nand_calculate_ecc - [NAND Interface] Calculate 3 byte ECC code for 256 byte block + * @mtd: MTD block structure + * @dat: raw data + * @ecc_code: buffer for ECC */ -void nand_calculate_ecc (const u_char *dat, u_char *ecc_code) +int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) { u_char idx, reg1, reg2, reg3; int j; @@ -114,12 +144,19 @@ ecc_code[0] = ~ecc_code[0]; ecc_code[1] = ~ecc_code[1]; ecc_code[2] = ((~reg1) << 2) | 0x03; + return 0; } -/* +/** + * nand_correct_data - [NAND Interface] Detect and correct bit error(s) + * @mtd: MTD block structure + * @dat: raw data read from the chip + * @read_ecc: ECC from the chip + * @calc_ecc: the ECC calculated from raw data + * * Detect and correct a 1 bit error for 256 byte block */ -int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc) +int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) { u_char a, b, c, d1, d2, d3, add, bit, i; @@ -209,5 +246,5 @@ EXPORT_SYMBOL(nand_correct_data); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Steven J. Hill "); +MODULE_AUTHOR("Steven J. Hill "); MODULE_DESCRIPTION("Generic NAND ECC support"); Index: drivers/mtd/nand/nand_ids.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/nand/nand_ids.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/nand/nand_ids.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/nand/nand_ids.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -2,9 +2,8 @@ * drivers/mtd/nandids.c * * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de) - * - * - * $Id: nand_ids.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * + * $Id: nand_ids.c,v 1.3 2004/11/03 00:04:44 joff 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 @@ -13,26 +12,99 @@ */ #include #include - /* * Chip ID list +* +* Name. ID code, pagesize, chipsize in MegaByte, eraseblock size, +* options +* +* Pagesize; 0, 256, 512 +* 0 get this information from the extended chip ID ++ 256 256 Byte page size +* 512 512 Byte page size */ struct nand_flash_dev nand_flash_ids[] = { - {"NAND 1MB 5V", 0x6e, 20, 0x1000, 1}, // 1Mb 5V - {"NAND 2MB 5V", 0x64, 21, 0x1000, 1}, // 2Mb 5V - {"NAND 4MB 5V", 0x6b, 22, 0x2000, 0}, // 4Mb 5V - {"NAND 1MB 3,3V", 0xe8, 20, 0x1000, 1}, // 1Mb 3.3V - {"NAND 1MB 3,3V", 0xec, 20, 0x1000, 1}, // 1Mb 3.3V - {"NAND 2MB 3,3V", 0xea, 21, 0x1000, 1}, // 2Mb 3.3V - {"NAND 4MB 3,3V", 0xd5, 22, 0x2000, 0}, // 4Mb 3.3V - {"NAND 4MB 3,3V", 0xe3, 22, 0x2000, 0}, // 4Mb 3.3V - {"NAND 4MB 3,3V", 0xe5, 22, 0x2000, 0}, // 4Mb 3.3V - {"NAND 8MB 3,3V", 0xd6, 23, 0x2000, 0}, // 8Mb 3.3V - {"NAND 8MB 3,3V", 0xe6, 23, 0x2000, 0}, // 8Mb 3.3V - {"NAND 16MB 3,3V", 0x73, 24, 0x4000, 0},// 16Mb 3,3V - {"NAND 32MB 3,3V", 0x75, 25, 0x4000, 0}, // 32Mb 3,3V - {"NAND 64MB 3,3V", 0x76, 26, 0x4000, 0}, // 64Mb 3,3V - {"NAND 128MB 3,3V", 0x79, 27, 0x4000, 0}, // 128Mb 3,3V + {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0}, + {"NAND 2MiB 5V 8-bit", 0x64, 256, 2, 0x1000, 0}, + {"NAND 4MiB 5V 8-bit", 0x6b, 512, 4, 0x2000, 0}, + {"NAND 1MiB 3,3V 8-bit", 0xe8, 256, 1, 0x1000, 0}, + {"NAND 1MiB 3,3V 8-bit", 0xec, 256, 1, 0x1000, 0}, + {"NAND 2MiB 3,3V 8-bit", 0xea, 256, 2, 0x1000, 0}, + {"NAND 4MiB 3,3V 8-bit", 0xd5, 512, 4, 0x2000, 0}, + {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0}, + {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0}, + {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0}, + + {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0}, + {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0}, + {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16}, + {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16}, + + {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0}, + {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0}, + {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16}, + {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16}, + + {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0}, + {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0}, + {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16}, + {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16}, + + {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0}, + {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0}, + {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16}, + {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16}, + + {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0}, + {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0}, + {"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16}, + {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16}, + + {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0}, + + {"NAND 512MiB 3,3V 8-bit", 0xDC, 512, 512, 0x4000, 0}, + + /* These are the new chips with large page size. The pagesize + * and the erasesize is determined from the extended id bytes + */ + /* 1 Gigabit */ + {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 128MiB 1,8V 16-bit", 0xB1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + {"NAND 128MiB 3,3V 16-bit", 0xC1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + + /* 2 Gigabit */ + {"NAND 256MiB 1,8V 8-bit", 0xAA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + {"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + + /* 4 Gigabit */ + {"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + {"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + + /* 8 Gigabit */ + {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 1GiB 1,8V 16-bit", 0xB3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + {"NAND 1GiB 3,3V 16-bit", 0xC3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + + /* 16 Gigabit */ + {"NAND 2GiB 1,8V 8-bit", 0xA5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 2GiB 3,3V 8-bit", 0xD5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, + {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + + /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout ! + * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes + * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7 + * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go + * There are more speed improvements for reads and writes possible, but not implemented now + */ + {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY}, + {NULL,} }; @@ -44,10 +116,11 @@ {NAND_MFR_SAMSUNG, "Samsung"}, {NAND_MFR_FUJITSU, "Fujitsu"}, {NAND_MFR_NATIONAL, "National"}, + {NAND_MFR_RENESAS, "Renesas"}, + {NAND_MFR_STMICRO, "ST Micro"}, {0x0, "Unknown"} }; - EXPORT_SYMBOL (nand_manuf_ids); EXPORT_SYMBOL (nand_flash_ids); Index: drivers/mtd/nand/spia.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd/nand/spia.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd/nand/spia.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/mtd/nand/spia.c 3 Nov 2004 00:04:44 -0000 1.3 @@ -1,14 +1,14 @@ /* * drivers/mtd/nand/spia.c * - * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com) + * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) * * * 10-29-2001 TG change to support hardwarespecific access * to controllines (due to change in nand.c) * page_cache added * - * $Id: spia.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: spia.c,v 1.3 2004/11/03 00:04:44 joff 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 @@ -20,6 +20,8 @@ * a 64Mibit (8MiB x 8 bits) NAND flash device. */ +#include +#include #include #include #include @@ -35,14 +37,14 @@ /* * Values specific to the SPIA board (used with EP7212 processor) */ -#define SPIA_IO_ADDR = 0xd0000000 /* Start of EP7212 IO address space */ -#define SPIA_FIO_ADDR = 0xf0000000 /* Address where flash is mapped */ -#define SPIA_PEDR = 0x0080 /* +#define SPIA_IO_BASE 0xd0000000 /* Start of EP7212 IO address space */ +#define SPIA_FIO_BASE 0xf0000000 /* Address where flash is mapped */ +#define SPIA_PEDR 0x0080 /* * IO offset to Port E data register * where the CLE, ALE and NCE pins * are wired to. */ -#define SPIA_PEDDR = 0x00c0 /* +#define SPIA_PEDDR 0x00c0 /* * IO offset to Port E data direction * register so we can control the IO * lines. @@ -62,21 +64,20 @@ MODULE_PARM(spia_pedr, "i"); MODULE_PARM(spia_peddr, "i"); -__setup("spia_io_base=",spia_io_base); -__setup("spia_fio_base=",spia_fio_base); -__setup("spia_pedr=",spia_pedr); -__setup("spia_peddr=",spia_peddr); - /* * Define partitions for flash device */ const static struct mtd_partition partition_info[] = { - { name: "SPIA flash partition 1", - offset: 0, - size: 2*1024*1024 }, - { name: "SPIA flash partition 2", - offset: 2*1024*1024, - size: 6*1024*1024 } + { + .name = "SPIA flash partition 1", + .offset = 0, + .size = 2*1024*1024 + }, + { + .name = "SPIA flash partition 2", + .offset = 2*1024*1024, + .size = 6*1024*1024 + } }; #define NUM_PARTITIONS 2 @@ -84,7 +85,7 @@ /* * hardware specific access to control-lines */ -void spia_hwcontrol(int cmd){ +static void spia_hwcontrol(struct mtd_info *mtd, int cmd){ switch(cmd){ @@ -131,37 +132,19 @@ (*(volatile unsigned char *) (spia_io_base + spia_peddr)) = 0x07; /* Set address of NAND IO lines */ - this->IO_ADDR_R = spia_fio_base; - this->IO_ADDR_W = spia_fio_base; + this->IO_ADDR_R = (void __iomem *) spia_fio_base; + this->IO_ADDR_W = (void __iomem *) spia_fio_base; /* Set address of hardware control function */ this->hwcontrol = spia_hwcontrol; /* 15 us command delay time */ this->chip_delay = 15; /* Scan to find existence of the device */ - if (nand_scan (spia_mtd)) { + if (nand_scan (spia_mtd, 1)) { kfree (spia_mtd); return -ENXIO; } - /* Allocate memory for internal data buffer */ - this->data_buf = kmalloc (sizeof(u_char) * (spia_mtd->oobblock + spia_mtd->oobsize), GFP_KERNEL); - if (!this->data_buf) { - printk ("Unable to allocate NAND data buffer for SPIA.\n"); - kfree (spia_mtd); - return -ENOMEM; - } - - /* Allocate memory for internal data buffer */ - this->data_cache = kmalloc (sizeof(u_char) * (spia_mtd->oobblock + spia_mtd->oobsize), GFP_KERNEL); - if (!this->data_cache) { - printk ("Unable to allocate NAND data cache for SPIA.\n"); - kfree (this->data_buf); - kfree (spia_mtd); - return = -ENOMEM; - } - this->cache_page = -1; - /* Register the partitions */ add_mtd_partitions(spia_mtd, partition_info, NUM_PARTITIONS); @@ -176,14 +159,8 @@ #ifdef MODULE static void __exit spia_cleanup (void) { - struct nand_chip *this = (struct nand_chip *) &spia_mtd[1]; - - /* Unregister the device */ - del_mtd_device (spia_mtd); - - /* Free internal data buffer */ - kfree (this->data_buf); - kfree (this->page_cache); + /* Release resources, unregister device */ + nand_release (spia_mtd); /* Free the MTD device structure */ kfree (spia_mtd); @@ -192,5 +169,5 @@ #endif MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Steven J. Hill #include +struct partition_info { // little-endian format + unsigned int bootable:8; // 0x80 = active, 0x00 = don't use for booting + unsigned int starting_head:8; + unsigned int starting_csect:8; + unsigned int starting_xcyl:8; + // MSB bits 0-5 are sector + unsigned int system_id:8; // format of partition + unsigned int ending_head:8; + unsigned int ending_csect:8; + unsigned int ending_xcyl:8; + unsigned int relative_sector:32; // sector offset from start of disk to start of volume + unsigned int total_sectors:32; +} __attribute__((packed)); + +struct partition_table { + struct partition_info part[4]; +} __attribute__((__packed__)); + +struct MBR { + char bootcode[446]; + struct partition_table pt; + unsigned int sig55:8; + unsigned int sigAA:8; +} __attribute__((__packed__)); + /* * MTD structure for TS7250 board */ @@ -40,24 +65,56 @@ * Module stuff */ -static unsigned int ts7250_fio_pbase = TS7XXX_FLASH3_BASE; +static unsigned int ts7250_nandctrl = IO_ADDRESS(TS7XXX_NAND_FLASH_CTRL); +static unsigned int ts7250_nandbusy = IO_ADDRESS(TS7XXX_NAND_FLASH_BUSY); #ifdef CONFIG_MTD_PARTITIONS /* * Define static partitions for flash device */ -static struct mtd_partition partition_info[] = { - { .name= "TS-BOOTROM", +static struct mtd_partition partition_info32[] = { + { .name= "TS-BOOTROM", + .offset= 0, + .size= 0x4000 }, + { .name= "Linux", + .offset= 0x4000, + .size= 0x1d00000 }, + { .name= "RedBoot", + .offset= 0x1d04000, + .size= 0x2fc000 }, +}; +/* + * Define static partitions for flash device + */ +static struct mtd_partition partition_info128[] = { + { .name= "TS-BOOTROM", + .offset= 0, + .size= 0x4000 }, + { .name= "Linux", + .offset= 0x4000, + .size= 0x7d00000 }, + { .name= "RedBoot", + .offset= 0x7d04000, + .size= 0x2fc000 }, +}; + +static struct mtd_partition partition_mbr[] = { + { .name= "whole chip", .offset= 0, - .size= 0x20000 }, - { .name= "Linux", - .offset= 0x20000, - .size= 0x1e00000 }, - { .name= "RedBoot", - .offset= 0x1e20000, - .size= 0x1e0000 }, + .size= 0x2000000 }, + { .name= "kernel", + .offset= 0x4000, + .size= 0x200000 }, + { .name= "initrd", + .offset= 0x204000, + .size= 0x200000 }, + { .name= "rootfs", + .offset= 0x404000, + .size= 0x2000000 - 0x404000 }, + { .name= "part4", + .offset= 0x2000000, + .size= 0 }, }; -#define NUM_PARTITIONS 3 extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, @@ -73,36 +130,72 @@ switch(cmd) { case NAND_CTL_SETCLE: - writeb(readb(IO_ADDRESS(TS7XXX_NAND_FLASH2_CTRL)) | 0x2, IO_ADDRESS(TS7XXX_NAND_FLASH2_CTRL)); + writeb(readb(ts7250_nandctrl) | 0x2, ts7250_nandctrl); break; case NAND_CTL_CLRCLE: - writeb(readb(IO_ADDRESS(TS7XXX_NAND_FLASH2_CTRL)) & ~0x2, IO_ADDRESS(TS7XXX_NAND_FLASH2_CTRL)); + writeb(readb(ts7250_nandctrl) & ~0x2, ts7250_nandctrl); break; case NAND_CTL_SETALE: - writeb(readb(IO_ADDRESS(TS7XXX_NAND_FLASH2_CTRL)) | 0x1, IO_ADDRESS(TS7XXX_NAND_FLASH2_CTRL)); + writeb(readb(ts7250_nandctrl) | 0x1, ts7250_nandctrl); break; case NAND_CTL_CLRALE: - writeb(readb(IO_ADDRESS(TS7XXX_NAND_FLASH2_CTRL)) & ~0x1, IO_ADDRESS(TS7XXX_NAND_FLASH2_CTRL)); + writeb(readb(ts7250_nandctrl) & ~0x1, ts7250_nandctrl); break; case NAND_CTL_SETNCE: - writeb(readb(IO_ADDRESS(TS7XXX_NAND_FLASH2_CTRL)) | 0x4, IO_ADDRESS(TS7XXX_NAND_FLASH2_CTRL)); + writeb(readb(ts7250_nandctrl) | 0x4, ts7250_nandctrl); break; case NAND_CTL_CLRNCE: - writeb(readb(IO_ADDRESS(TS7XXX_NAND_FLASH2_CTRL)) & ~0x4, IO_ADDRESS(TS7XXX_NAND_FLASH2_CTRL)); + writeb(readb(ts7250_nandctrl) & ~0x4, ts7250_nandctrl); break; } } +static void ts7250_enable_hwecc(struct mtd_info *mtd,int dir) { + volatile int *ts7x = (void *)IO_ADDRESS(TS7XXX_NAND_FLASH_CTRL); + int dummy; + + dummy = *ts7x; + //printk("enable_hwecc\n"); +} + +static int ts7250_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) { + volatile int *ts7x = (void *)IO_ADDRESS(TS7XXX_NAND_FLASH_CTRL); + int dummy; + + dummy = 0xFFFFFF & ((*ts7x >> 6) | 3); + //printk("Hardware ECC: %06X ",dummy); + ecc_code[0] = (dummy >> 16) & 0xFF; + ecc_code[1] = (dummy >> 8) & 0xFF; + ecc_code[2] = (dummy >> 0) & 0xFF; + //printk("(%02X %02X %02X)\n",ecc_code[0],ecc_code[1],ecc_code[2]); + return dummy; +} + +static int detect_hwecc(struct nand_chip *this) { + volatile int *ts7x = (void *)IO_ADDRESS(TS7XXX_NAND_FLASH_CTRL); + int dummy; + + dummy = *ts7x; + dummy = *ts7x; + if ((dummy >> 8) != -1) { + return 0; + } + writeb(0x1, this->IO_ADDR_W); + dummy = *ts7x; + return ((dummy >> 8) != -1); +} + /* * read device ready pin */ static int ts7250_device_ready(struct mtd_info *mtd) { - return readb(IO_ADDRESS(TS7XXX_NAND_FLASH2_BUSY)) & 0x20; + return readb(ts7250_nandbusy) & 0x20; } +extern int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); /* * Main initialization routine */ @@ -112,6 +205,14 @@ const char *part_type = 0; int mtd_parts_nb = 0; struct mtd_partition *mtd_parts = 0; + char buf[512]; + int i,got = 0,parts=0,hwecc = 0; + unsigned ofs=0; + volatile unsigned short *tsmodel; + struct MBR *mbr = (struct MBR *)buf; + + if (readb(IO_ADDRESS(TS7XXX_MODEL)) == 0x0) /* is TS-7200 */ + return -ENXIO; /* Allocate memory for MTD device structure and private data */ ts7250_mtd = kmalloc(sizeof(struct mtd_info) + @@ -134,20 +235,79 @@ /* insert callbacks */ - this->IO_ADDR_R = IO_ADDRESS(TS7XXX_NAND_FLASH2_DATA); - this->IO_ADDR_W = IO_ADDRESS(TS7XXX_NAND_FLASH2_DATA); + if (readb(IO_ADDRESS(TS7XXX_STATUS2)) & 0x4) { + this->IO_ADDR_R = (void *)IO_ADDRESS(TS7XXX_NAND_FLASH2_DATA); + this->IO_ADDR_W = (void *)IO_ADDRESS(TS7XXX_NAND_FLASH2_DATA); + ts7250_nandbusy = IO_ADDRESS(TS7XXX_NAND_FLASH2_BUSY); + ts7250_nandctrl = IO_ADDRESS(TS7XXX_NAND_FLASH2_CTRL); + } else { + this->IO_ADDR_R = (void *)IO_ADDRESS(TS7XXX_NAND_FLASH_DATA); + this->IO_ADDR_W = (void *)IO_ADDRESS(TS7XXX_NAND_FLASH_DATA); + ts7250_nandbusy = IO_ADDRESS(TS7XXX_NAND_FLASH_BUSY); + ts7250_nandctrl = IO_ADDRESS(TS7XXX_NAND_FLASH_CTRL); + } + this->hwcontrol = ts7250_hwcontrol; this->dev_ready = ts7250_device_ready; this->chip_delay = 15; this->eccmode = NAND_ECC_SOFT; - + this->options = 0; + + tsmodel = (short *)__ioremap(0x22000000, 2, 0); + printk("Searching for NAND flash...\n"); /* Scan to find existence of the device */ if (nand_scan (ts7250_mtd, 1)) { kfree (ts7250_mtd); return -ENXIO; } - + for (i=0;i<512;i++) { + buf[i] = 0; + } + + if((*tsmodel & 0x07) != 0x04) { //if the current board isn't a TS-7400 + if (ts7250_mtd->size >= (128 * 0x100000)) { + mtd_parts = partition_info128; + } else { + mtd_parts = partition_info32; + } + parts = 3; + } else { + hwecc = detect_hwecc(this); + printk("Hardware ECC "); + if (!hwecc) { + printk("NOT "); + } else { + this->eccmode = NAND_ECC_HW3_256; + this->enable_hwecc = ts7250_enable_hwecc; + this->calculate_ecc = ts7250_calculate_ecc; + this->correct_data = nand_correct_data; + } + printk("detected\n"); + + if (mbr->sigAA == 0xAA && mbr->sig55 == 0x55) { + for (i=0;i<4;i++) { + if (mbr->pt.part[i].total_sectors) { + parts++; + partition_mbr[i+1].offset = + 512 * mbr->pt.part[i].relative_sector; + if (i < 2) { + partition_mbr[i+1].size = + 512 * mbr->pt.part[i+1].relative_sector - + 512 * mbr->pt.part[i].relative_sector; + } else { + partition_mbr[i+1].size = + 512 * mbr->pt.part[i].total_sectors; + } + ofs = partition_mbr[i+1].offset + + partition_mbr[i+1].size; + } + } + } else { + parts = 4; + } + mtd_parts = partition_mbr; + } #ifdef CONFIG_MTD_CMDLINE_PARTS mtd_parts_nb = parse_cmdline_partitions(ts7250_mtd, &mtd_parts, "ts7250-nand"); @@ -158,9 +318,17 @@ #endif if (mtd_parts_nb == 0) { - mtd_parts = partition_info; - mtd_parts_nb = NUM_PARTITIONS; - part_type = "static"; + //mtd_parts = partition_info32; + /* + if (ts7250_mtd->size >= (128 * 0x100000)) + mtd_parts = partition_info128; + */ + mtd_parts_nb = parts; + if (parts > 0) { + part_type = "MBR"; + } else { + part_type = "static"; + } } /* Register the partitions */ @@ -177,9 +345,10 @@ */ static void __exit ts7250_cleanup (void) { - struct nand_chip *this = (struct nand_chip *) &ts7250_mtd[1]; + // struct nand_chip *this = (struct nand_chip *) &ts7250_mtd[1]; /* Unregister the device */ + del_mtd_partitions(ts7250_mtd); del_mtd_device (ts7250_mtd); /* Free the MTD device structure */ Index: drivers/mtd2k/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd2k/Config.in,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd2k/Config.in 9 Feb 2006 21:51:44 -0000 1.1 +++ drivers/mtd2k/Config.in 29 Sep 2006 22:31:03 -0000 1.3 @@ -1,12 +1,12 @@ -# $Id: Config.in,v 1.1 2006/02/09 21:51:44 michael Exp $ +# $Id: Config.in,v 1.3 2006/09/29 22:31:03 joff Exp $ mainmenu_option next_comment -comment 'Memory Technology Devices (MTD)' +comment 'Memory Technology Devices (MTD) for 2k NAND flash' -tristate 'Memory Technology Device (MTD) support' CONFIG_MTD +tristate 'Memory Technology Device (MTD) support for 2k NAND flash' CONFIG_MTD2K -if [ "$CONFIG_MTD" = "y" -o "$CONFIG_MTD" = "m" ]; then +if [ "$CONFIG_MTD2K" = "y" -o "$CONFIG_MTD2K" = "m" ]; then bool 'Debugging' CONFIG_MTD_DEBUG if [ "$CONFIG_MTD_DEBUG" = "y" ]; then int ' Debugging verbosity (0 = quiet, 3 = noisy)' CONFIG_MTD_DEBUG_VERBOSE 0 @@ -26,25 +26,25 @@ fi comment 'User Modules And Translation Layers' - dep_tristate ' Direct char device access to MTD devices' CONFIG_MTD_CHAR $CONFIG_MTD - dep_tristate ' Caching block device access to MTD devices' CONFIG_MTD_BLOCK $CONFIG_MTD + dep_tristate ' Direct char device access to MTD devices' CONFIG_MTD_CHAR $CONFIG_MTD2K + dep_tristate ' Caching block device access to MTD devices' CONFIG_MTD_BLOCK $CONFIG_MTD2K if [ "$CONFIG_MTD_BLOCK" = "n" -o "$CONFIG_MTD_BLOCK" = "m" ]; then - dep_tristate ' Readonly block device access to MTD devices' CONFIG_MTD_BLOCK_RO $CONFIG_MTD + dep_tristate ' Readonly block device access to MTD devices' CONFIG_MTD_BLOCK_RO $CONFIG_MTD2K fi - dep_tristate ' FTL (Flash Translation Layer) support' CONFIG_FTL $CONFIG_MTD - dep_tristate ' NFTL (NAND Flash Translation Layer) support' CONFIG_NFTL $CONFIG_MTD + dep_tristate ' FTL (Flash Translation Layer) support' CONFIG_FTL $CONFIG_MTD2K + dep_tristate ' NFTL (NAND Flash Translation Layer) support' CONFIG_NFTL $CONFIG_MTD2K if [ "$CONFIG_NFTL" = "y" -o "$CONFIG_NFTL" = "m" ]; then bool ' Write support for NFTL (BETA)' CONFIG_NFTL_RW fi - dep_tristate ' INFTL (Inverse NAND Flash Translation Layer) support' CONFIG_INFTL $CONFIG_MTD + dep_tristate ' INFTL (Inverse NAND Flash Translation Layer) support' CONFIG_INFTL $CONFIG_MTD2K - source drivers/mtd/chips/Config.in + source drivers/mtd2k/chips/Config.in - source drivers/mtd/maps/Config.in + source drivers/mtd2k/maps/Config.in - source drivers/mtd/devices/Config.in + source drivers/mtd2k/devices/Config.in - source drivers/mtd/nand/Config.in + source drivers/mtd2k/nand/Config.in fi Index: drivers/mtd2k/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd2k/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/mtd2k/Makefile 9 Feb 2006 21:51:44 -0000 1.1 +++ drivers/mtd2k/Makefile 9 Feb 2006 23:21:28 -0000 1.2 @@ -2,12 +2,12 @@ # linux/drivers/Makefile.24 # Makefile for obsolete kernels. # -# $Id: Makefile,v 1.1 2006/02/09 21:51:44 michael Exp $ +# $Id: Makefile,v 1.2 2006/02/09 23:21:28 michael Exp $ # Core functionality. mtd-y := mtdcore.o mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o -obj-$(CONFIG_MTD) += $(mtd-y) +obj-$(CONFIG_MTD2K) += $(mtd-y) obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o Index: drivers/mtd2k/chips/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd2k/chips/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/mtd2k/chips/Config.in 9 Feb 2006 21:52:09 -0000 1.1 +++ drivers/mtd2k/chips/Config.in 9 Feb 2006 23:23:12 -0000 1.2 @@ -1,13 +1,13 @@ # drivers/mtd/chips/Config.in -# $Id: Config.in,v 1.1 2006/02/09 21:52:09 michael Exp $ +# $Id: Config.in,v 1.2 2006/02/09 23:23:12 michael Exp $ mainmenu_option next_comment comment 'RAM/ROM/Flash chip drivers' -dep_tristate ' Detect flash chips by Common Flash Interface (CFI) probe' CONFIG_MTD_CFI $CONFIG_MTD -dep_tristate ' Detect JEDEC JESD21c compatible flash chips' CONFIG_MTD_JEDECPROBE $CONFIG_MTD +dep_tristate ' Detect flash chips by Common Flash Interface (CFI) probe' CONFIG_MTD_CFI $CONFIG_MTD2K +dep_tristate ' Detect JEDEC JESD21c compatible flash chips' CONFIG_MTD_JEDECPROBE $CONFIG_MTD2K if [ "$CONFIG_MTD_CFI" = "y" -o "$CONFIG_MTD_JEDECPROBE" = "y" ]; then define_bool CONFIG_MTD_GEN_PROBE y @@ -69,8 +69,8 @@ bool ' Older (theoretically obsoleted now) drivers for non-CFI chips' CONFIG_MTD_OBSOLETE_CHIPS dep_tristate ' AMD compatible flash chip support (non-CFI)' CONFIG_MTD_AMDSTD $CONFIG_MTD $CONFIG_MTD_OBSOLETE_CHIPS -dep_tristate ' pre-CFI Sharp chip support' CONFIG_MTD_SHARP $CONFIG_MTD $CONFIG_MTD_OBSOLETE_CHIPS -dep_tristate ' JEDEC device support' CONFIG_MTD_JEDEC $CONFIG_MTD $CONFIG_MTD_OBSOLETE_CHIPS +dep_tristate ' pre-CFI Sharp chip support' CONFIG_MTD_SHARP $CONFIG_MTD2K $CONFIG_MTD_OBSOLETE_CHIPS +dep_tristate ' JEDEC device support' CONFIG_MTD_JEDEC $CONFIG_MTD2K $CONFIG_MTD_OBSOLETE_CHIPS endmenu Index: drivers/mtd2k/chips/Makefile.common =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd2k/chips/Makefile.common,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/mtd2k/chips/Makefile.common 9 Feb 2006 21:52:09 -0000 1.1 +++ drivers/mtd2k/chips/Makefile.common 9 Feb 2006 23:26:31 -0000 1.2 @@ -1,7 +1,7 @@ # # linux/drivers/chips/Makefile # -# $Id: Makefile.common,v 1.1 2006/02/09 21:52:09 michael Exp $ +# $Id: Makefile.common,v 1.2 2006/02/09 23:26:31 michael Exp $ # *** BIG UGLY NOTE *** # @@ -10,7 +10,7 @@ # here where previously there was none. We now have to ensure that # the CFI command set drivers are linked before gen_probe.o -obj-$(CONFIG_MTD) += chipreg.o +obj-$(CONFIG_MTD2K) += chipreg.o obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o obj-$(CONFIG_MTD_CFI) += cfi_probe.o obj-$(CONFIG_MTD_CFI_UTIL) += cfi_util.o Index: drivers/mtd2k/nand/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd2k/nand/Config.in,v retrieving revision 1.1 retrieving revision 1.5 diff -u -r1.1 -r1.5 --- drivers/mtd2k/nand/Config.in 9 Feb 2006 21:53:06 -0000 1.1 +++ drivers/mtd2k/nand/Config.in 16 Jan 2009 18:48:36 -0000 1.5 @@ -1,12 +1,12 @@ # drivers/mtd/nand/Config.in -# $Id: Config.in,v 1.1 2006/02/09 21:53:06 michael Exp $ +# $Id: Config.in,v 1.5 2009/01/16 18:48:36 eddie Exp $ mainmenu_option next_comment comment 'NAND Flash Device Drivers' -dep_tristate ' NAND Device Support' CONFIG_MTD_NAND $CONFIG_MTD +dep_tristate ' NAND Device Support' CONFIG_MTD_NAND $CONFIG_MTD2K if [ "$CONFIG_MTD_NAND" = "y" -o "$CONFIG_MTD_NAND" = "m" ]; then bool ' Verify NAND page writes' CONFIG_MTD_NAND_VERIFY_WRITE fi @@ -17,6 +17,9 @@ dep_tristate ' SmartMedia Card on AUTCPU12 board' CONFIG_MTD_NAND_AUTCPU12 $CONFIG_MTD_NAND $CONFIG_ARCH_AUTCPU12 dep_tristate ' NAND Flash device on EDP7312 board' CONFIG_MTD_NAND_EDB7312 $CONFIG_MTD_NAND $CONFIG_ARCH_EDB7312 dep_tristate ' NAND Flash device on TS-7250 board' CONFIG_MTD_NAND_TS7250 $CONFIG_MTD_NAND + dep_tristate ' NAND Flash device on TS-7400 board' CONFIG_MTD_NAND_TS7400 $CONFIG_MTD_NAND + dep_tristate ' NAND Flash device on BT200 board' CONFIG_MTD_NAND_BT200 $CONFIG_MTD_NAND + dep_tristate ' NAND Flash device on Prosoft 8000 board' CONFIG_MTD_NAND_PROSOFT $CONFIG_MTD_NAND fi if [ "$CONFIG_MTD_DOC2001PLUS" = "y" -o "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" -o "$CONFIG_MTD_NAND" = "y" ]; then Index: drivers/mtd2k/nand/Makefile.common =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd2k/nand/Makefile.common,v retrieving revision 1.1 retrieving revision 1.4 diff -u -r1.1 -r1.4 --- drivers/mtd2k/nand/Makefile.common 9 Feb 2006 21:53:06 -0000 1.1 +++ drivers/mtd2k/nand/Makefile.common 16 Jan 2009 18:50:18 -0000 1.4 @@ -1,7 +1,7 @@ # # linux/drivers/nand/Makefile # -# $Id: Makefile.common,v 1.1 2006/02/09 21:53:06 michael Exp $ +# $Id: Makefile.common,v 1.4 2009/01/16 18:50:18 eddie Exp $ obj-$(CONFIG_MTD_NAND) += nand.o nand_ecc.o obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o @@ -19,6 +19,9 @@ obj-$(CONFIG_MTD_NAND_H1900) += h1910.o obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o obj-$(CONFIG_MTD_NAND_TS7250) += ts7250.o +obj-$(CONFIG_MTD_NAND_BT200) += ts7400.o +obj-$(CONFIG_MTD_NAND_TS7400) += ts7400.o +obj-$(CONFIG_MTD_NAND_PROSOFT) += ts7350.o nand-objs = nand_ecc.o nand_ids.o Index: drivers/mtd2k/nand/makeModules =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd2k/nand/makeModules,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/mtd2k/nand/makeModules 9 Feb 2006 21:53:06 -0000 1.1 +++ drivers/mtd2k/nand/makeModules 19 Oct 2006 17:34:17 -0000 1.3 @@ -1,6 +1,10 @@ CMD="/home/michael/ts-7200/tools/crosstool/arm-9tdmi-linux-gnu/gcc-3.3.4-glibc-2.3.2/bin/arm-9tdmi-linux-gnu-gcc -D__KERNEL__ -I/home/michael/ts-7200/dist/linux24/include -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -Uarm -fno-common -pipe -mapcs-32 -D__LINUX_ARM_ARCH__=4 -march=armv4 -mtune=arm9tdmi -msoft-float -Uarm -DMODULE -nostdinc -iwithprefix include -DKBUILD_BASENAME=p80211mod -DEXPORT_SYMTAB -c" -`$CMD nand_ecc.c` -`$CMD nand_ids.c` -`$CMD nand.c` -`$CMD ts7250.c` -cp *.o /mnt/tmp +`$CMD nand_ecc2k.c` +`$CMD nand_ids2k.c` +`$CMD nand2k.c` +`$CMD ts72502k.c` +sudo cp nand_ecc2k.o /u/x/lib/modules/2.4.26-ts11/kernel/drivers/mtd2k/nand/ +sudo cp nand_ids2k.o /u/x/lib/modules/2.4.26-ts11/kernel/drivers/mtd2k/nand/ +sudo cp nand2k.o /u/x/lib/modules/2.4.26-ts11/kernel/drivers/mtd2k/nand/ +sudo cp ts72502k.o /u/x/lib/modules/2.4.26-ts11/kernel/drivers/mtd2k/nand/ + Index: drivers/mtd2k/nand/nand.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd2k/nand/nand.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/mtd2k/nand/nand.c 9 Feb 2006 21:53:06 -0000 1.1 +++ drivers/mtd2k/nand/nand.c 22 Jan 2009 18:14:20 -0000 1.2 @@ -34,7 +34,7 @@ * Check if buffering the last not aligned read can speed up * performance * - * $Id: nand.c,v 1.1 2006/02/09 21:53:06 michael Exp $ + * $Id: nand.c,v 1.2 2009/01/22 18:14:20 eddie 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 @@ -1737,7 +1737,7 @@ instr->state = MTD_ERASING; while (len) { - /* Check if we have a bad block, we do not erase bad blocks ! */ + /* Check if we have a bad block, we do not erase bad blocks ! if (this->block_bad(mtd, (loff_t) page, 0)) { // COMMENT THIS OUT TO ENABLE ERASURE OF BAD BLOCKS // Only useful for erasing accidentally marked bad blocks @@ -1747,6 +1747,7 @@ goto erase_exit; } + */ /* Send commands to erase a page */ this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page); @@ -1958,10 +1959,18 @@ extid >>= 2; /* Get buswidth information */ busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; - +/* +printk("page size = 0x%x\n", mtd->oobblock); +printk("oob size = 0x%x\n", mtd->oobsize); +printk("erase size = 0x%x\n", mtd->erasesize); +printk("busw= 0x%x\n", busw); +*/ + + /* Do not replace user supplied command function ! */ - if (this->cmdfunc == nand_command) + if (this->cmdfunc == nand_command) { this->cmdfunc = nand_command_lp; + } } else { /* Old devices have this data hardcoded in the * device id table */ @@ -2028,11 +2037,13 @@ } if (i > 1) printk(KERN_INFO "%d NAND chips detected\n", i); - + + /* if (!this->oob_buf || !this->data_buf) { printk (KERN_WARNING "nand_scan(): Buffers not set. Scan aborted\n"); return 1; } + */ /* Store the number of chips and calc total size for mtd */ this->numchips = i; Index: drivers/mtd2k/nand/nand_ecc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd2k/nand/nand_ecc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/mtd2k/nand/nand_ecc.c 9 Feb 2006 21:53:06 -0000 1.1 +++ drivers/mtd2k/nand/nand_ecc.c 27 Apr 2006 21:14:31 -0000 1.2 @@ -4,7 +4,7 @@ * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) * Toshiba America Electronics Components, Inc. * - * $Id: nand_ecc.c,v 1.1 2006/02/09 21:53:06 michael Exp $ + * $Id: nand_ecc.c,v 1.2 2006/04/27 21:14:31 eddie Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -85,7 +85,7 @@ /* * Calculate 3 byte ECC code for 256 byte block */ -void nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) +int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) { u_char idx, reg1, reg2, reg3; int j; @@ -115,6 +115,8 @@ ecc_code[0] = ~ecc_code[0]; ecc_code[1] = ~ecc_code[1]; ecc_code[2] = ((~reg1) << 2) | 0x03; + + return 0; } /* Index: drivers/mtd2k/nand/ts7250.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/mtd2k/nand/ts7250.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/mtd2k/nand/ts7250.c 9 Feb 2006 21:53:06 -0000 1.1 +++ drivers/mtd2k/nand/ts7250.c 6 Mar 2007 22:26:40 -0000 1.2 @@ -9,7 +9,7 @@ * Derived from drivers/mtd/nand/autcpu12.c * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) * - * $Id: ts7250.c,v 1.1 2006/02/09 21:53:06 michael Exp $ + * $Id: ts7250.c,v 1.2 2007/03/06 22:26:40 eddie 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 @@ -290,6 +290,7 @@ // struct nand_chip *this = (struct nand_chip *) &ts7250_mtd[1]; /* Unregister the device */ + del_mtd_partitions(ts7250_mtd); del_mtd_device (ts7250_mtd); /* Free the MTD device structure */ Index: drivers/net/3c501.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/3c501.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/3c501.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/3c501.c 4 Aug 2004 01:29:06 -0000 1.2 @@ -148,7 +148,7 @@ static int el1_close(struct net_device *dev); static struct net_device_stats *el1_get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; #define EL1_IO_EXTENT 16 @@ -388,7 +388,7 @@ dev->stop = &el1_close; dev->get_stats = &el1_get_stats; dev->set_multicast_list = &set_multicast_list; - dev->do_ioctl = netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; /* * Setup the generic properties @@ -939,86 +939,31 @@ } } -/** - * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls - * @dev: network interface on which out-of-band action is to be performed - * @useraddr: userspace address to which data is to be read and returned - * - * Process the various commands of the SIOCETHTOOL interface. - */ -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "ISA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } - - default: - break; - } - - return -EOPNOTSUPP; + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr); } -/** - * netdev_ioctl: Handle network interface ioctls - * @dev: network interface on which out-of-band action is to be performed - * @rq: user request data - * @cmd: command issued by user - * - * Process the various out-of-band ioctls passed to this driver. - */ - -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +static u32 netdev_get_msglevel(struct net_device *dev) { - int rc = 0; + return debug; +} - switch (cmd) { - case SIOCETHTOOL: - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - break; +static void netdev_set_msglevel(struct net_device *dev, u32 level) +{ + debug = level; +} - default: - rc = -EOPNOTSUPP; - break; - } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +}; - return rc; -} - #ifdef MODULE static struct net_device dev_3c501 = { Index: drivers/net/3c503.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/3c503.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/3c503.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/3c503.c 4 Aug 2004 01:29:06 -0000 1.2 @@ -82,7 +82,7 @@ int ring_offset); static void el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; /* This routine probes for a memory-mapped 3c503 board by looking for @@ -310,7 +310,7 @@ dev->open = &el2_open; dev->stop = &el2_close; - dev->do_ioctl = &netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; if (dev->mem_start) printk("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n", @@ -619,69 +619,18 @@ return; } -/** - * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls - * @dev: network interface on which out-of-band action is to be performed - * @useraddr: userspace address to which data is to be read and returned - * - * Process the various commands of the SIOCETHTOOL interface. - */ -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "ISA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - default: - break; - } - - return -EOPNOTSUPP; + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr); } -/** - * netdev_ioctl: Handle network interface ioctls - * @dev: network interface on which out-of-band action is to be performed - * @rq: user request data - * @cmd: command issued by user - * - * Process the various out-of-band ioctls passed to this driver. - */ - -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) -{ - int rc = 0; - - switch (cmd) { - case SIOCETHTOOL: - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - break; - - default: - rc = -EOPNOTSUPP; - break; - } - - return rc; -} - +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; #ifdef MODULE #define MAX_EL2_CARDS 4 /* Max number of EL2 cards per module */ Index: drivers/net/3c505.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/3c505.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/3c505.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/3c505.c 4 Aug 2004 01:29:06 -0000 1.2 @@ -10,7 +10,7 @@ * be here without 3C505 technical reference provided by * 3Com. * - * $Id: 3c505.c,v 1.1 2004/07/22 19:49:34 joff Exp $ + * $Id: 3c505.c,v 1.2 2004/08/04 01:29:06 joff Exp $ * * Authors: Linux 3c505 device driver by * Craig Southeren, @@ -1270,86 +1270,30 @@ } } -/** - * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls - * @dev: network interface on which out-of-band action is to be performed - * @useraddr: userspace address to which data is to be read and returned - * - * Process the various commands of the SIOCETHTOOL interface. - */ -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "ISA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } - - default: - break; - } - - return -EOPNOTSUPP; + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr); } -/** - * netdev_ioctl: Handle network interface ioctls - * @dev: network interface on which out-of-band action is to be performed - * @rq: user request data - * @cmd: command issued by user - * - * Process the various out-of-band ioctls passed to this driver. - */ - -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +static u32 netdev_get_msglevel(struct net_device *dev) { - int rc = 0; - - switch (cmd) { - case SIOCETHTOOL: - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - break; - - default: - rc = -EOPNOTSUPP; - break; - } + return debug; +} - return rc; +static void netdev_set_msglevel(struct net_device *dev, u32 level) +{ + debug = level; } - + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +}; /****************************************************** * @@ -1371,7 +1315,7 @@ dev->tx_timeout = elp_timeout; /* local */ dev->watchdog_timeo = 10*HZ; dev->set_multicast_list = elp_set_mc_list; /* local */ - dev->do_ioctl = netdev_ioctl; /* local */ + dev->ethtool_ops = &netdev_ethtool_ops; /* local */ /* Setup the generic properties */ ether_setup(dev); Index: drivers/net/3c507.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/3c507.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/3c507.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/3c507.c 4 Aug 2004 01:29:06 -0000 1.2 @@ -305,7 +305,7 @@ static void hardware_send_packet(struct net_device *dev, void *buf, short length, short pad); static void init_82586_mem(struct net_device *dev); -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; /* Check for a network adaptor of this type, and return '0' iff one exists. @@ -437,7 +437,7 @@ dev->get_stats = el16_get_stats; dev->tx_timeout = el16_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; - dev->do_ioctl = netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; ether_setup(dev); /* Generic ethernet behaviour */ @@ -879,86 +879,29 @@ lp->rx_tail = rx_tail; } -/** - * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls - * @dev: network interface on which out-of-band action is to be performed - * @useraddr: userspace address to which data is to be read and returned - * - * Process the various commands of the SIOCETHTOOL interface. - */ - -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "ISA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } - - default: - break; - } - - return -EOPNOTSUPP; + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr); } -/** - * netdev_ioctl: Handle network interface ioctls - * @dev: network interface on which out-of-band action is to be performed - * @rq: user request data - * @cmd: command issued by user - * - * Process the various out-of-band ioctls passed to this driver. - */ - -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +static u32 netdev_get_msglevel(struct net_device *dev) { - int rc = 0; - - switch (cmd) { - case SIOCETHTOOL: - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - break; - - default: - rc = -EOPNOTSUPP; - break; - } + return debug; +} - return rc; +static void netdev_set_msglevel(struct net_device *dev, u32 level) +{ + debug = level; } - + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +}; #ifdef MODULE static struct net_device dev_3c507; Index: drivers/net/3c515.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/3c515.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/3c515.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/3c515.c 4 Aug 2004 01:29:06 -0000 1.2 @@ -406,7 +406,7 @@ static void update_stats(int addr, struct net_device *dev); static struct net_device_stats *corkscrew_get_stats(struct net_device *dev); static void set_rx_mode(struct net_device *dev); -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; /* @@ -736,7 +736,7 @@ dev->stop = &corkscrew_close; dev->get_stats = &corkscrew_get_stats; dev->set_multicast_list = &set_rx_mode; - dev->do_ioctl = netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; return 0; } @@ -1608,86 +1608,30 @@ outw(new_mode, ioaddr + EL3_CMD); } -/** - * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls - * @dev: network interface on which out-of-band action is to be performed - * @useraddr: userspace address to which data is to be read and returned - * - * Process the various commands of the SIOCETHTOOL interface. - */ - -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "ISA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = corkscrew_debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - corkscrew_debug = edata.data; - return 0; - } - - default: - break; - } - - return -EOPNOTSUPP; + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr); } -/** - * netdev_ioctl: Handle network interface ioctls - * @dev: network interface on which out-of-band action is to be performed - * @rq: user request data - * @cmd: command issued by user - * - * Process the various out-of-band ioctls passed to this driver. - */ - -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +static u32 netdev_get_msglevel(struct net_device *dev) { - int rc = 0; + return corkscrew_debug; +} - switch (cmd) { - case SIOCETHTOOL: - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - break; +static void netdev_set_msglevel(struct net_device *dev, u32 level) +{ + corkscrew_debug = level; +} - default: - rc = -EOPNOTSUPP; - break; - } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +}; - return rc; -} - #ifdef MODULE void cleanup_module(void) Index: drivers/net/3c523.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/3c523.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/3c523.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/3c523.c 4 Aug 2004 01:29:06 -0000 1.2 @@ -84,7 +84,7 @@ Nov 2001 added support for ethtool (jgarzik) - $Header: /cvsroot/ts-7200/dist/linux24/drivers/net/3c523.c,v 1.1 2004/07/22 19:49:34 joff Exp $ + $Header: /cvsroot/ts-7200/dist/linux24/drivers/net/3c523.c,v 1.2 2004/08/04 01:29:06 joff Exp $ */ #define DRV_NAME "3c523" @@ -190,7 +190,7 @@ #ifdef ELMC_MULTICAST static void set_multicast_list(struct net_device *dev); #endif -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; /* helper-functions */ static int init586(struct net_device *dev); @@ -573,7 +573,7 @@ #else dev->set_multicast_list = NULL; #endif - dev->do_ioctl = netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; ether_setup(dev); @@ -1228,70 +1228,17 @@ } #endif -/** - * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls - * @dev: network interface on which out-of-band action is to be performed - * @useraddr: userspace address to which data is to be read and returned - * - * Process the various commands of the SIOCETHTOOL interface. - */ - -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "MCA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - default: - break; - } - - return -EOPNOTSUPP; + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "MCA 0x%lx", dev->base_addr); } -/** - * netdev_ioctl: Handle network interface ioctls - * @dev: network interface on which out-of-band action is to be performed - * @rq: user request data - * @cmd: command issued by user - * - * Process the various out-of-band ioctls passed to this driver. - */ - -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) -{ - int rc = 0; - - switch (cmd) { - case SIOCETHTOOL: - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - break; - - default: - rc = -EOPNOTSUPP; - break; - } - - return rc; -} - -/*************************************************************************/ +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; #ifdef MODULE Index: drivers/net/3c523.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/3c523.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/3c523.h 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/3c523.h 4 Aug 2004 01:29:06 -0000 1.2 @@ -15,7 +15,7 @@ * * See 3c523.c for details. * - * $Header: /cvsroot/ts-7200/dist/linux24/drivers/net/3c523.h,v 1.1 2004/07/22 19:49:34 joff Exp $ + * $Header: /cvsroot/ts-7200/dist/linux24/drivers/net/3c523.h,v 1.2 2004/08/04 01:29:06 joff Exp $ */ /* Index: drivers/net/3c527.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/3c527.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/3c527.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/3c527.c 4 Aug 2004 01:29:06 -0000 1.2 @@ -111,6 +111,8 @@ #include "3c527.h" +MODULE_LICENSE("GPL"); + /* * The name of the card. Is used for messages and in the requests for * io regions, irqs and dma channels @@ -220,7 +222,7 @@ static struct net_device_stats *mc32_get_stats(struct net_device *dev); static void mc32_set_multicast_list(struct net_device *dev); static void mc32_reset_multicast_list(struct net_device *dev); -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; /** * mc32_probe - Search for supported boards @@ -510,7 +512,7 @@ dev->set_multicast_list = mc32_set_multicast_list; dev->tx_timeout = mc32_timeout; dev->watchdog_timeo = HZ*5; /* Board does all the work */ - dev->do_ioctl = netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; lp->xceiver_state = HALTED; @@ -1083,15 +1085,16 @@ /* NP is the buffer we will be loading */ np=lp->tx_ring[lp->tx_ring_head].p; - /* We will need this to flush the buffer out */ - lp->tx_ring[lp->tx_ring_head].skb=skb; - if(skb->len < ETH_ZLEN) { skb = skb_padto(skb, ETH_ZLEN); if(skb == NULL) goto out; } + + /* We will need this to flush the buffer out */ + lp->tx_ring[lp->tx_ring_head].skb=skb; + np->length = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len; np->data = virt_to_bus(skb->data); @@ -1658,86 +1661,30 @@ do_mc32_set_multicast_list(dev,1); } -/** - * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls - * @dev: network interface on which out-of-band action is to be performed - * @useraddr: userspace address to which data is to be read and returned - * - * Process the various commands of the SIOCETHTOOL interface. - */ - -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "MCA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = mc32_debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - mc32_debug = edata.data; - return 0; - } - - default: - break; - } - - return -EOPNOTSUPP; + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "MCA 0x%lx", dev->base_addr); } -/** - * netdev_ioctl: Handle network interface ioctls - * @dev: network interface on which out-of-band action is to be performed - * @rq: user request data - * @cmd: command issued by user - * - * Process the various out-of-band ioctls passed to this driver. - */ - -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +static u32 netdev_get_msglevel(struct net_device *dev) { - int rc = 0; + return mc32_debug; +} - switch (cmd) { - case SIOCETHTOOL: - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - break; +static void netdev_set_msglevel(struct net_device *dev, u32 level) +{ + mc32_debug = level; +} - default: - rc = -EOPNOTSUPP; - break; - } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +}; - return rc; -} - #ifdef MODULE static struct net_device this_device; Index: drivers/net/3c59x.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/3c59x.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/3c59x.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/3c59x.c 4 Aug 2004 01:29:07 -0000 1.2 @@ -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, @@ -442,6 +447,11 @@ CH_3CCFEM656_1, CH_3C450, CH_3C920, + CH_3C982A, + CH_3C982B, + + CH_905BT4, + CH_920B_EMB_WNM, }; @@ -497,8 +507,8 @@ 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,16 @@ 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, }, + + {"3c905B-T4", + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, + {"3c920B-EMB-WNM Tornado", + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, + {0,}, /* 0 terminated list. */ }; @@ -579,6 +599,12 @@ { 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 }, + + { 0x10B7, 0x9056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_905BT4 }, + { 0x10B7, 0x9210, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_920B_EMB_WNM }, + {0,} /* 0 terminated list. */ }; MODULE_DEVICE_TABLE(pci, vortex_pci_tbl); @@ -848,6 +874,7 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static void vortex_tx_timeout(struct net_device *dev); static void acpi_set_WOL(struct net_device *dev); +static struct ethtool_ops vortex_ethtool_ops; /* This driver uses 'options' to pass the media type, full-duplex flag, etc. */ /* Option count limit only -- unlimited interfaces are supported. */ @@ -1190,6 +1217,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. */ @@ -1308,6 +1339,7 @@ dev->stop = vortex_close; dev->get_stats = vortex_get_stats; dev->do_ioctl = vortex_ioctl; + dev->ethtool_ops = &vortex_ethtool_ops; dev->set_multicast_list = set_rx_mode; dev->tx_timeout = vortex_tx_timeout; dev->watchdog_timeo = (watchdog * HZ) / 1000; @@ -2668,35 +2700,24 @@ return; } - -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void vortex_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { struct vortex_private *vp = dev->priv; - 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_NAME); - strcpy(info.version, DRV_VERSION); - if (vp->pdev) - strcpy(info.bus_info, vp->pdev->slot_name); - else - sprintf(info.bus_info, "EISA 0x%lx %d", - dev->base_addr, dev->irq); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - } - - return -EOPNOTSUPP; + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + if (vp->pdev) + strcpy(info->bus_info, pci_name(vp->pdev)); + else + sprintf(info->bus_info, "EISA 0x%lx %d", + dev->base_addr, dev->irq); } +static struct ethtool_ops vortex_ethtool_ops = { + .get_drvinfo = vortex_get_drvinfo, +}; + static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct vortex_private *vp = (struct vortex_private *)dev->priv; @@ -2706,9 +2727,6 @@ int retval; switch(cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - case SIOCGMIIPHY: /* Get address of MII PHY in use. */ case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */ data->phy_id = phy; Index: drivers/net/8139cp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/8139cp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/8139cp.c 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/8139cp.c 4 Aug 2004 01:29:07 -0000 1.2 @@ -24,15 +24,13 @@ PCI suspend/resume - Felipe Damasio LinkChg interrupt - Felipe Damasio - TODO, in rough priority order: + TODO: * Test Tx checksumming thoroughly - * dev->tx_timeout - * Constants (module parms?) for Rx work limit + * Implement dev->tx_timeout + + Low priority TODO: * Complete reset on PciErr * Consider Rx interrupt mitigation using TimerIntr - * Implement 8139C+ statistics dump; maybe not... - h/w stats can be reset only by software reset - * Handle netif_rx return value * Investigate using skb->priority with h/w VLAN priority * Investigate using High Priority Tx Queue with skb->priority * Adjust Rx FIFO threshold and Max Rx DMA burst on Rx FIFO error @@ -41,14 +39,17 @@ Tx descriptor bit * The real minimum of CP_MIN_MTU is 4 bytes. However, for this to be supported, one must(?) turn on packet padding. - * Support 8169 GMII - * Support external MII transceivers + * Support external MII transceivers (patch available) + + NOTES: + * TX checksumming is considered experimental. It is off by + default, use ethtool to turn it on. */ #define DRV_NAME "8139cp" -#define DRV_VERSION "0.3.0" -#define DRV_RELDATE "Sep 29, 2002" +#define DRV_VERSION "1.1" +#define DRV_RELDATE "Aug 30, 2003" #include @@ -71,9 +72,6 @@ #include #include -/* experimental TX checksumming feature enable/disable */ -#undef CP_TX_CHECKSUM - /* VLAN tagging feature enable/disable */ #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #define CP_VLAN_TAG_USED 1 @@ -86,7 +84,7 @@ #endif /* These identify the driver base version and may not be removed. */ -static char version[] __devinitdata = +static char version[] = KERN_INFO DRV_NAME ": 10/100 PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n"; MODULE_AUTHOR("Jeff Garzik "); @@ -160,6 +158,7 @@ TxConfig = 0x40, /* Tx configuration */ ChipVersion = 0x43, /* 8-bit chip version, inside TxConfig */ RxConfig = 0x44, /* Rx configuration */ + RxMissed = 0x4C, /* 24 bits valid, write clears */ Cfg9346 = 0x50, /* EEPROM select/control; Cfg reg [un]lock */ Config1 = 0x52, /* Config1 */ Config3 = 0x59, /* Config3 */ @@ -292,12 +291,11 @@ UWF = (1 << 4), /* Accept Unicast wakeup frame */ LANWake = (1 << 1), /* Enable LANWake signal */ PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ -}; -static const unsigned int cp_intr_mask = - PciErr | LinkChg | - RxOK | RxErr | RxEmpty | RxFIFOOvr | - TxOK | TxErr | TxEmpty; + cp_norx_intr_mask = PciErr | LinkChg | TxOK | TxErr | TxEmpty, + cp_rx_intr_mask = RxOK | RxErr | RxEmpty | RxFIFOOvr, + cp_intr_mask = cp_rx_intr_mask | cp_norx_intr_mask, +}; static const unsigned int cp_rx_config = (RX_FIFO_THRESH << RxCfgFIFOShift) | @@ -364,11 +362,7 @@ struct pci_dev *pdev; u32 rx_config; - - struct sk_buff *frag_skb; - unsigned dropping_frag : 1; - unsigned pci_using_dac : 1; - unsigned int board_type; + u16 cpcmd; unsigned int wol_enabled : 1; /* Is Wake-on-LAN enabled? */ u32 power_state[16]; @@ -400,28 +394,9 @@ static void cp_tx (struct cp_private *cp); static void cp_clean_rings (struct cp_private *cp); -enum board_type { - RTL8139Cp, - RTL8169, -}; - -static struct cp_board_info { - const char *name; -} cp_board_tbl[] __devinitdata = { - /* RTL8139Cp */ - { "RTL-8139C+" }, - - /* RTL8169 */ - { "RTL-8169" }, -}; - -static struct pci_device_id cp_pci_tbl[] __devinitdata = { +static struct pci_device_id cp_pci_tbl[] = { { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139Cp }, -#if 0 - { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8169, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8169 }, -#endif + PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, { }, }; MODULE_DEVICE_TABLE(pci, cp_pci_tbl); @@ -446,6 +421,31 @@ }; +#if CP_VLAN_TAG_USED +static void cp_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) +{ + struct cp_private *cp = dev->priv; + + spin_lock_irq(&cp->lock); + cp->vlgrp = grp; + cp->cpcmd |= RxVlanOn; + cpw16(CpCmd, cp->cpcmd); + spin_unlock_irq(&cp->lock); +} + +static void cp_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) +{ + struct cp_private *cp = dev->priv; + + spin_lock_irq(&cp->lock); + cp->cpcmd &= ~RxVlanOn; + cpw16(CpCmd, cp->cpcmd); + if (cp->vlgrp) + cp->vlgrp->vlan_devices[vid] = NULL; + spin_unlock_irq(&cp->lock); +} +#endif /* CP_VLAN_TAG_USED */ + static inline void cp_set_rxbufsize (struct cp_private *cp) { unsigned int mtu = cp->dev->mtu; @@ -468,10 +468,11 @@ #if CP_VLAN_TAG_USED if (cp->vlgrp && (desc->opts2 & RxVlanTagged)) { - vlan_hwaccel_rx(skb, cp->vlgrp, desc->opts2 & 0xffff); + vlan_hwaccel_receive_skb(skb, cp->vlgrp, + be16_to_cpu(desc->opts2 & 0xffff)); } else #endif - netif_rx(skb); + netif_receive_skb(skb); } static void cp_rx_err_acct (struct cp_private *cp, unsigned rx_tail, @@ -486,81 +487,14 @@ cp->net_stats.rx_frame_errors++; if (status & RxErrCRC) cp->net_stats.rx_crc_errors++; - if (status & RxErrRunt) + if ((status & RxErrRunt) || (status & RxErrLong)) cp->net_stats.rx_length_errors++; - if (status & RxErrLong) + if ((status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag)) cp->net_stats.rx_length_errors++; if (status & RxErrFIFO) cp->net_stats.rx_fifo_errors++; } -static void cp_rx_frag (struct cp_private *cp, unsigned rx_tail, - struct sk_buff *skb, u32 status, u32 len) -{ - struct sk_buff *copy_skb, *frag_skb = cp->frag_skb; - unsigned orig_len = frag_skb ? frag_skb->len : 0; - unsigned target_len = orig_len + len; - unsigned first_frag = status & FirstFrag; - unsigned last_frag = status & LastFrag; - - if (netif_msg_rx_status (cp)) - printk (KERN_DEBUG "%s: rx %s%sfrag, slot %d status 0x%x len %d\n", - cp->dev->name, - cp->dropping_frag ? "dropping " : "", - first_frag ? "first " : - last_frag ? "last " : "", - rx_tail, status, len); - - cp->cp_stats.rx_frags++; - - if (!frag_skb && !first_frag) - cp->dropping_frag = 1; - if (cp->dropping_frag) - goto drop_frag; - - copy_skb = dev_alloc_skb (target_len + RX_OFFSET); - if (!copy_skb) { - printk(KERN_WARNING "%s: rx slot %d alloc failed\n", - cp->dev->name, rx_tail); - - cp->dropping_frag = 1; -drop_frag: - if (frag_skb) { - dev_kfree_skb_irq(frag_skb); - cp->frag_skb = NULL; - } - if (last_frag) { - cp->net_stats.rx_dropped++; - cp->dropping_frag = 0; - } - return; - } - - copy_skb->dev = cp->dev; - skb_reserve(copy_skb, RX_OFFSET); - skb_put(copy_skb, target_len); - if (frag_skb) { - memcpy(copy_skb->data, frag_skb->data, orig_len); - dev_kfree_skb_irq(frag_skb); - } - pci_dma_sync_single(cp->pdev, cp->rx_skb[rx_tail].mapping, - len, PCI_DMA_FROMDEVICE); - memcpy(copy_skb->data + orig_len, skb->data, len); - - copy_skb->ip_summed = CHECKSUM_NONE; - - if (last_frag) { - if (status & (RxError | RxErrFIFO)) { - cp_rx_err_acct(cp, rx_tail, status, len); - dev_kfree_skb_irq(copy_skb); - } else - cp_rx_skb(cp, copy_skb, &cp->rx_ring[rx_tail]); - cp->frag_skb = NULL; - } else { - cp->frag_skb = copy_skb; - } -} - static inline unsigned int cp_rx_csum_ok (u32 status) { unsigned int protocol = (status >> 16) & 0x3; @@ -574,12 +508,18 @@ return 0; } -static void cp_rx (struct cp_private *cp) +static int cp_rx_poll (struct net_device *dev, int *budget) { + struct cp_private *cp = dev->priv; unsigned rx_tail = cp->rx_tail; - unsigned rx_work = 100; + unsigned rx_work = dev->quota; + unsigned rx; + +rx_status_loop: + rx = 0; + cpw16(IntrStatus, cp_rx_intr_mask); - while (rx_work--) { + while (1) { u32 status, len; dma_addr_t mapping; struct sk_buff *skb, *new_skb; @@ -599,7 +539,14 @@ mapping = cp->rx_skb[rx_tail].mapping; if ((status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag)) { - cp_rx_frag(cp, rx_tail, skb, status, len); + /* we don't support incoming fragmented frames. + * instead, we attempt to ensure that the + * pre-allocated RX skbs are properly sized such + * that RX fragments are never encountered + */ + cp_rx_err_acct(cp, rx_tail, status, len); + cp->net_stats.rx_dropped++; + cp->cp_stats.rx_frags++; goto rx_next; } @@ -640,6 +587,7 @@ cp->rx_skb[rx_tail].skb = new_skb; cp_rx_skb(cp, skb, desc); + rx++; rx_next: cp->rx_ring[rx_tail].opts2 = 0; @@ -650,15 +598,36 @@ else desc->opts1 = cpu_to_le32(DescOwn | cp->rx_buf_sz); rx_tail = NEXT_RX(rx_tail); - } - if (!rx_work) - printk(KERN_WARNING "%s: rx work limit reached\n", cp->dev->name); + if (!rx_work--) + break; + } cp->rx_tail = rx_tail; + + dev->quota -= rx; + *budget -= rx; + + /* if we did not reach work limit, then we're done with + * this round of polling + */ + if (rx_work) { + if (cpr16(IntrStatus) & cp_rx_intr_mask) + goto rx_status_loop; + + local_irq_disable(); + cpw16_f(IntrMask, cp_intr_mask); + __netif_rx_complete(dev); + local_irq_enable(); + + return 0; /* done */ + } + + return 1; /* not done */ } -static void cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs) +static irqreturn_t +cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = dev_instance; struct cp_private *cp = dev->priv; @@ -666,18 +635,28 @@ status = cpr16(IntrStatus); if (!status || (status == 0xFFFF)) - return; + return IRQ_NONE; if (netif_msg_intr(cp)) printk(KERN_DEBUG "%s: intr, status %04x cmd %02x cpcmd %04x\n", dev->name, status, cpr8(Cmd), cpr16(CpCmd)); - cpw16_f(IntrStatus, status); + cpw16(IntrStatus, status & ~cp_rx_intr_mask); spin_lock(&cp->lock); - if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr)) - cp_rx(cp); + /* close possible race's with dev_close */ + if (unlikely(!netif_running(dev))) { + cpw16(IntrMask, 0); + goto out; + } + + if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr)) { + if (netif_rx_schedule_prep(dev)) { + cpw16_f(IntrMask, cp_norx_intr_mask); + __netif_rx_schedule(dev); + } + } if (status & (TxOK | TxErr | TxEmpty | SWInt)) cp_tx(cp); if (status & LinkChg) @@ -690,9 +669,12 @@ pci_write_config_word(cp->pdev, PCI_STATUS, pci_status); printk(KERN_ERR "%s: PCI bus error, status=%04x, PCI status=%04x\n", dev->name, status, pci_status); - } + /* TODO: reset hardware */ + } +out: spin_unlock(&cp->lock); + return IRQ_HANDLED; } static void cp_tx (struct cp_private *cp) @@ -748,7 +730,7 @@ cp->tx_tail = tx_tail; - if (netif_queue_stopped(cp->dev) && (TX_BUFFS_AVAIL(cp) > (MAX_SKB_FRAGS + 1))) + if (TX_BUFFS_AVAIL(cp) > (MAX_SKB_FRAGS + 1)) netif_wake_queue(cp->dev); } @@ -774,7 +756,7 @@ #if CP_VLAN_TAG_USED if (cp->vlgrp && vlan_tx_tag_present(skb)) - vlan_tag = TxVlanTag | vlan_tx_tag_get(skb); + vlan_tag = TxVlanTag | cpu_to_be16(vlan_tx_tag_get(skb)); #endif entry = cp->tx_head; @@ -790,7 +772,6 @@ txd->addr = cpu_to_le64(mapping); wmb(); -#ifdef CP_TX_CHECKSUM if (skb->ip_summed == CHECKSUM_HW) { const struct iphdr *ip = skb->nh.iph; if (ip->protocol == IPPROTO_TCP) @@ -804,7 +785,6 @@ else BUG(); } else -#endif txd->opts1 = cpu_to_le32(eor | len | DescOwn | FirstFrag | LastFrag); wmb(); @@ -818,15 +798,13 @@ u32 first_len, first_eor; dma_addr_t first_mapping; int frag, first_entry = entry; -#ifdef CP_TX_CHECKSUM const struct iphdr *ip = skb->nh.iph; -#endif /* We must give this initial chunk to the device last. * Otherwise we could race with the device. */ first_eor = eor; - first_len = skb->len - skb->data_len; + first_len = skb_headlen(skb); first_mapping = pci_map_single(cp->pdev, skb->data, first_len, PCI_DMA_TODEVICE); cp->tx_skb[entry].skb = skb; @@ -846,7 +824,7 @@ this_frag->page_offset), len, PCI_DMA_TODEVICE); eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; -#ifdef CP_TX_CHECKSUM + if (skb->ip_summed == CHECKSUM_HW) { ctrl = eor | len | DescOwn | IPCS; if (ip->protocol == IPPROTO_TCP) @@ -856,7 +834,6 @@ else BUG(); } else -#endif ctrl = eor | len | DescOwn; if (frag == skb_shinfo(skb)->nr_frags - 1) @@ -881,7 +858,6 @@ txd->addr = cpu_to_le64(first_mapping); wmb(); -#ifdef CP_TX_CHECKSUM if (skb->ip_summed == CHECKSUM_HW) { if (ip->protocol == IPPROTO_TCP) txd->opts1 = cpu_to_le32(first_eor | first_len | @@ -894,7 +870,6 @@ else BUG(); } else -#endif txd->opts1 = cpu_to_le32(first_eor | first_len | FirstFrag | DescOwn); wmb(); @@ -973,7 +948,9 @@ static void __cp_get_stats(struct cp_private *cp) { - /* XXX implement */ + /* only lower 24 bits valid; write any value to clear */ + cp->net_stats.rx_missed_errors += (cpr32 (RxMissed) & 0xffffff); + cpw32 (RxMissed, 0); } static struct net_device_stats *cp_get_stats(struct net_device *dev) @@ -991,17 +968,22 @@ static void cp_stop_hw (struct cp_private *cp) { - cpw16(IntrMask, 0); - cpr16(IntrMask); + struct net_device *dev = cp->dev; + + cpw16(IntrStatus, ~(cpr16(IntrStatus))); + cpw16_f(IntrMask, 0); cpw8(Cmd, 0); - cpw16(CpCmd, 0); - cpr16(CpCmd); + cpw16_f(CpCmd, 0); cpw16(IntrStatus, ~(cpr16(IntrStatus))); synchronize_irq(); udelay(10); cp->rx_tail = 0; cp->tx_head = cp->tx_tail = 0; + + (void) dev; /* avoid compiler warning when synchronize_irq() + * disappears during !CONFIG_SMP + */ } static void cp_reset_hw (struct cp_private *cp) @@ -1023,11 +1005,7 @@ static inline void cp_start_hw (struct cp_private *cp) { - u16 pci_dac = cp->pci_using_dac ? PCIDAC : 0; - if (cp->board_type == RTL8169) - cpw16(CpCmd, pci_dac | PCIMulRW | RxChkSum); - else - cpw16(CpCmd, pci_dac | PCIMulRW | RxChkSum | CpRxOn | CpTxOn); + cpw16(CpCmd, cp->cpcmd); cpw8(Cmd, RxOn | TxOn); } @@ -1051,13 +1029,10 @@ cpw8(Config1, cpr8(Config1) | DriverLoaded | PMEnable); /* Disable Wake-on-LAN. Can be turned on with ETHTOOL_SWOL */ - if (cp->board_type == RTL8139Cp) { - cpw8(Config3, PARMEnable); - cp->wol_enabled = 0; - } + cpw8(Config3, PARMEnable); + cp->wol_enabled = 0; + cpw8(Config5, cpr8(Config5) & PMEStatus); - if (cp->board_type == RTL8169) - cpw16(RxMaxSize, cp->rx_buf_sz); cpw32_f(HiTxRingAddr, 0); cpw32_f(HiTxRingAddr + 4, 0); @@ -1250,8 +1225,6 @@ dev->mtu = new_mtu; cp_set_rxbufsize(cp); /* set new rx buf size */ - if (cp->board_type == RTL8169) - cpw16(RxMaxSize, cp->rx_buf_sz); rc = cp_init_rings(cp); /* realloc and restart h/w */ cp_start_hw(cp); @@ -1296,8 +1269,8 @@ } /* Set the ethtool Wake-on-LAN settings */ -static void netdev_set_wol (struct cp_private *cp, - const struct ethtool_wolinfo *wol) +static int netdev_set_wol (struct cp_private *cp, + const struct ethtool_wolinfo *wol) { u8 options; @@ -1324,6 +1297,8 @@ cpw8 (Config5, options); cp->wol_enabled = (wol->wolopts) ? 1 : 0; + + return 0; } /* Get the ethtool Wake-on-LAN settings */ @@ -1349,308 +1324,205 @@ if (options & MWF) wol->wolopts |= WAKE_MCAST; } -static int cp_ethtool_ioctl (struct cp_private *cp, void *useraddr) +static void cp_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info) { - u32 ethcmd; + struct cp_private *cp = dev->priv; - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ + strcpy (info->driver, DRV_NAME); + strcpy (info->version, DRV_VERSION); + strcpy (info->bus_info, pci_name(cp->pdev)); +} - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - strcpy (info.bus_info, cp->pdev->slot_name); - info.regdump_len = CP_REGS_SIZE; - info.n_stats = CP_NUM_STATS; - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } +static int cp_get_regs_len(struct net_device *dev) +{ + return CP_REGS_SIZE; +} - /* get settings */ - case ETHTOOL_GSET: { - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - spin_lock_irq(&cp->lock); - mii_ethtool_gset(&cp->mii_if, &ecmd); - spin_unlock_irq(&cp->lock); - if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } - /* set settings */ - case ETHTOOL_SSET: { - int r; - struct ethtool_cmd ecmd; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - spin_lock_irq(&cp->lock); - r = mii_ethtool_sset(&cp->mii_if, &ecmd); - spin_unlock_irq(&cp->lock); - return r; - } - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - return mii_nway_restart(&cp->mii_if); - } - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = {ETHTOOL_GLINK}; - edata.data = mii_link_ok(&cp->mii_if); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } +static int cp_get_stats_count (struct net_device *dev) +{ + return CP_NUM_STATS; +} - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = cp->msg_enable; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - cp->msg_enable = edata.data; - return 0; - } +static int cp_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct cp_private *cp = dev->priv; + int rc; - /* NIC register dump */ - case ETHTOOL_GREGS: { - struct ethtool_regs regs; - u8 *regbuf = kmalloc(CP_REGS_SIZE, GFP_KERNEL); - int rc; - - if (!regbuf) - return -ENOMEM; - memset(regbuf, 0, CP_REGS_SIZE); + spin_lock_irq(&cp->lock); + rc = mii_ethtool_gset(&cp->mii_if, cmd); + spin_unlock_irq(&cp->lock); - rc = copy_from_user(®s, useraddr, sizeof(regs)); - if (rc) { - rc = -EFAULT; - goto err_out_gregs; - } - - if (regs.len > CP_REGS_SIZE) - regs.len = CP_REGS_SIZE; - if (regs.len < CP_REGS_SIZE) { - rc = -EINVAL; - goto err_out_gregs; - } + return rc; +} - regs.version = CP_REGS_VER; - rc = copy_to_user(useraddr, ®s, sizeof(regs)); - if (rc) { - rc = -EFAULT; - goto err_out_gregs; - } +static int cp_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct cp_private *cp = dev->priv; + int rc; - useraddr += offsetof(struct ethtool_regs, data); + spin_lock_irq(&cp->lock); + rc = mii_ethtool_sset(&cp->mii_if, cmd); + spin_unlock_irq(&cp->lock); - spin_lock_irq(&cp->lock); - memcpy_fromio(regbuf, cp->regs, CP_REGS_SIZE); - spin_unlock_irq(&cp->lock); + return rc; +} - if (copy_to_user(useraddr, regbuf, regs.len)) - rc = -EFAULT; +static int cp_nway_reset(struct net_device *dev) +{ + struct cp_private *cp = dev->priv; + return mii_nway_restart(&cp->mii_if); +} -err_out_gregs: - kfree(regbuf); - return rc; - } +static u32 cp_get_msglevel(struct net_device *dev) +{ + struct cp_private *cp = dev->priv; + return cp->msg_enable; +} - /* get/set RX checksumming */ - case ETHTOOL_GRXCSUM: { - struct ethtool_value edata = { ETHTOOL_GRXCSUM }; - u16 cmd = cpr16(CpCmd) & RxChkSum; - - edata.data = cmd ? 1 : 0; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - case ETHTOOL_SRXCSUM: { - struct ethtool_value edata; - u16 cmd = cpr16(CpCmd), newcmd; +static void cp_set_msglevel(struct net_device *dev, u32 value) +{ + struct cp_private *cp = dev->priv; + cp->msg_enable = value; +} - newcmd = cmd; +static u32 cp_get_rx_csum(struct net_device *dev) +{ + struct cp_private *cp = dev->priv; + return (cpr16(CpCmd) & RxChkSum) ? 1 : 0; +} - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; +static int cp_set_rx_csum(struct net_device *dev, u32 data) +{ + struct cp_private *cp = dev->priv; + u16 cmd = cp->cpcmd, newcmd; - if (edata.data) - newcmd |= RxChkSum; - else - newcmd &= ~RxChkSum; + newcmd = cmd; - if (newcmd == cmd) - return 0; + if (data) + newcmd |= RxChkSum; + else + newcmd &= ~RxChkSum; + if (newcmd != cmd) { spin_lock_irq(&cp->lock); + cp->cpcmd = newcmd; cpw16_f(CpCmd, newcmd); spin_unlock_irq(&cp->lock); } - /* get/set TX checksumming */ - case ETHTOOL_GTXCSUM: { - struct ethtool_value edata = { ETHTOOL_GTXCSUM }; - - edata.data = (cp->dev->features & NETIF_F_IP_CSUM) != 0; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - case ETHTOOL_STXCSUM: { - struct ethtool_value edata; - - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - - if (edata.data) - cp->dev->features |= NETIF_F_IP_CSUM; - else - cp->dev->features &= ~NETIF_F_IP_CSUM; - - return 0; - } + return 0; +} - /* get/set scatter-gather */ - case ETHTOOL_GSG: { - struct ethtool_value edata = { ETHTOOL_GSG }; - - edata.data = (cp->dev->features & NETIF_F_SG) != 0; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - case ETHTOOL_SSG: { - struct ethtool_value edata; +static void cp_get_regs(struct net_device *dev, struct ethtool_regs *regs, + void *p) +{ + struct cp_private *cp = dev->priv; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; + if (regs->len < CP_REGS_SIZE) + return /* -EINVAL */; - if (edata.data) - cp->dev->features |= NETIF_F_SG; - else - cp->dev->features &= ~NETIF_F_SG; + regs->version = CP_REGS_VER; - return 0; - } + spin_lock_irq(&cp->lock); + memcpy_fromio(p, cp->regs, CP_REGS_SIZE); + spin_unlock_irq(&cp->lock); +} - /* get string list(s) */ - case ETHTOOL_GSTRINGS: { - struct ethtool_gstrings estr = { ETHTOOL_GSTRINGS }; - - if (copy_from_user(&estr, useraddr, sizeof(estr))) - return -EFAULT; - if (estr.string_set != ETH_SS_STATS) - return -EINVAL; - - estr.len = CP_NUM_STATS; - if (copy_to_user(useraddr, &estr, sizeof(estr))) - return -EFAULT; - if (copy_to_user(useraddr + sizeof(estr), - ðtool_stats_keys, - sizeof(ethtool_stats_keys))) - return -EFAULT; - return 0; - } +static void cp_get_wol (struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct cp_private *cp = dev->priv; - /* get NIC-specific statistics */ - case ETHTOOL_GSTATS: { - struct ethtool_stats estats = { ETHTOOL_GSTATS }; - u64 *tmp_stats; - unsigned int work = 100; - const unsigned int sz = sizeof(u64) * CP_NUM_STATS; - int i; - - /* begin NIC statistics dump */ - cpw32(StatsAddr + 4, 0); /* FIXME: 64-bit PCI */ - cpw32(StatsAddr, cp->nic_stats_dma | DumpStats); - cpr32(StatsAddr); - - estats.n_stats = CP_NUM_STATS; - if (copy_to_user(useraddr, &estats, sizeof(estats))) - return -EFAULT; - - while (work-- > 0) { - if ((cpr32(StatsAddr) & DumpStats) == 0) - break; - cpu_relax(); - } + spin_lock_irq (&cp->lock); + netdev_get_wol (cp, wol); + spin_unlock_irq (&cp->lock); +} - if (cpr32(StatsAddr) & DumpStats) - return -EIO; +static int cp_set_wol (struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct cp_private *cp = dev->priv; + int rc; - tmp_stats = kmalloc(sz, GFP_KERNEL); - if (!tmp_stats) - return -ENOMEM; - memset(tmp_stats, 0, sz); - - i = 0; - tmp_stats[i++] = le64_to_cpu(cp->nic_stats->tx_ok); - tmp_stats[i++] = le64_to_cpu(cp->nic_stats->rx_ok); - tmp_stats[i++] = le64_to_cpu(cp->nic_stats->tx_err); - tmp_stats[i++] = le32_to_cpu(cp->nic_stats->rx_err); - tmp_stats[i++] = le16_to_cpu(cp->nic_stats->rx_fifo); - tmp_stats[i++] = le16_to_cpu(cp->nic_stats->frame_align); - tmp_stats[i++] = le32_to_cpu(cp->nic_stats->tx_ok_1col); - tmp_stats[i++] = le32_to_cpu(cp->nic_stats->tx_ok_mcol); - tmp_stats[i++] = le64_to_cpu(cp->nic_stats->rx_ok_phys); - tmp_stats[i++] = le64_to_cpu(cp->nic_stats->rx_ok_bcast); - tmp_stats[i++] = le32_to_cpu(cp->nic_stats->rx_ok_mcast); - tmp_stats[i++] = le16_to_cpu(cp->nic_stats->tx_abort); - tmp_stats[i++] = le16_to_cpu(cp->nic_stats->tx_underrun); - tmp_stats[i++] = cp->cp_stats.rx_frags; - if (i != CP_NUM_STATS) - BUG(); + spin_lock_irq (&cp->lock); + rc = netdev_set_wol (cp, wol); + spin_unlock_irq (&cp->lock); - i = copy_to_user(useraddr + sizeof(estats), - tmp_stats, sz); - kfree(tmp_stats); + return rc; +} - if (i) - return -EFAULT; - return 0; +static void cp_get_strings (struct net_device *dev, u32 stringset, u8 *buf) +{ + switch (stringset) { + case ETH_SS_STATS: + memcpy(buf, ðtool_stats_keys, sizeof(ethtool_stats_keys)); + break; + default: + BUG(); + break; } +} - /* get/set Wake-on-LAN settings */ - case ETHTOOL_GWOL: { - struct ethtool_wolinfo wol = { ETHTOOL_GWOL }; - - spin_lock_irq (&cp->lock); - netdev_get_wol (cp, &wol); - spin_unlock_irq (&cp->lock); - return ((copy_to_user (useraddr, &wol, sizeof (wol)))? -EFAULT : 0); - } - - case ETHTOOL_SWOL: { - struct ethtool_wolinfo wol; +static void cp_get_ethtool_stats (struct net_device *dev, + struct ethtool_stats *estats, u64 *tmp_stats) +{ + struct cp_private *cp = dev->priv; + unsigned int work = 100; + int i; - if (copy_from_user (&wol, useraddr, sizeof (wol))) - return -EFAULT; - spin_lock_irq (&cp->lock); - netdev_set_wol (cp, &wol); - spin_unlock_irq (&cp->lock); - return 0; - } + /* begin NIC statistics dump */ + cpw32(StatsAddr + 4, 0); /* FIXME: 64-bit PCI */ + cpw32(StatsAddr, cp->nic_stats_dma | DumpStats); + cpr32(StatsAddr); - default: - break; + while (work-- > 0) { + if ((cpr32(StatsAddr) & DumpStats) == 0) + break; + cpu_relax(); } - return -EOPNOTSUPP; + if (cpr32(StatsAddr) & DumpStats) + return /* -EIO */; + + i = 0; + tmp_stats[i++] = le64_to_cpu(cp->nic_stats->tx_ok); + tmp_stats[i++] = le64_to_cpu(cp->nic_stats->rx_ok); + tmp_stats[i++] = le64_to_cpu(cp->nic_stats->tx_err); + tmp_stats[i++] = le32_to_cpu(cp->nic_stats->rx_err); + tmp_stats[i++] = le16_to_cpu(cp->nic_stats->rx_fifo); + tmp_stats[i++] = le16_to_cpu(cp->nic_stats->frame_align); + tmp_stats[i++] = le32_to_cpu(cp->nic_stats->tx_ok_1col); + tmp_stats[i++] = le32_to_cpu(cp->nic_stats->tx_ok_mcol); + tmp_stats[i++] = le64_to_cpu(cp->nic_stats->rx_ok_phys); + tmp_stats[i++] = le64_to_cpu(cp->nic_stats->rx_ok_bcast); + tmp_stats[i++] = le32_to_cpu(cp->nic_stats->rx_ok_mcast); + tmp_stats[i++] = le16_to_cpu(cp->nic_stats->tx_abort); + tmp_stats[i++] = le16_to_cpu(cp->nic_stats->tx_underrun); + tmp_stats[i++] = cp->cp_stats.rx_frags; + if (i != CP_NUM_STATS) + BUG(); } +static struct ethtool_ops cp_ethtool_ops = { + .get_drvinfo = cp_get_drvinfo, + .get_regs_len = cp_get_regs_len, + .get_stats_count = cp_get_stats_count, + .get_settings = cp_get_settings, + .set_settings = cp_set_settings, + .nway_reset = cp_nway_reset, + .get_link = ethtool_op_get_link, + .get_msglevel = cp_get_msglevel, + .set_msglevel = cp_set_msglevel, + .get_rx_csum = cp_get_rx_csum, + .set_rx_csum = cp_set_rx_csum, + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = ethtool_op_set_tx_csum, /* local! */ + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, + .get_regs = cp_get_regs, + .get_wol = cp_get_wol, + .set_wol = cp_set_wol, + .get_strings = cp_get_strings, + .get_ethtool_stats = cp_get_ethtool_stats, +}; static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) { @@ -1661,38 +1533,12 @@ if (!netif_running(dev)) return -EINVAL; - if (cmd == SIOCETHTOOL) - return cp_ethtool_ioctl(cp, (void *) rq->ifr_data); - spin_lock_irq(&cp->lock); rc = generic_mii_ioctl(&cp->mii_if, mii, cmd, NULL); spin_unlock_irq(&cp->lock); return rc; } -#if CP_VLAN_TAG_USED -static void cp_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -{ - struct cp_private *cp = dev->priv; - - spin_lock_irq(&cp->lock); - cp->vlgrp = grp; - cpw16(CpCmd, cpr16(CpCmd) | RxVlanOn); - spin_unlock_irq(&cp->lock); -} - -static void cp_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) -{ - struct cp_private *cp = dev->priv; - - spin_lock_irq(&cp->lock); - cpw16(CpCmd, cpr16(CpCmd) & ~RxVlanOn); - if (cp->vlgrp) - cp->vlgrp->vlan_devices[vid] = NULL; - spin_unlock_irq(&cp->lock); -} -#endif - /* Serial EEPROM section. */ /* EEPROM_Ctrl bits. */ @@ -1715,7 +1561,7 @@ #define EE_READ_CMD (6) #define EE_ERASE_CMD (7) -static int __devinit read_eeprom (void *ioaddr, int location, int addr_len) +static int read_eeprom (void *ioaddr, int location, int addr_len) { int i; unsigned retval = 0; @@ -1761,18 +1607,15 @@ pci_set_power_state (cp->pdev, 3); } -static int __devinit cp_init_one (struct pci_dev *pdev, - const struct pci_device_id *ent) +static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *dev; struct cp_private *cp; int rc; void *regs; long pciaddr; - unsigned int addr_len, i; - u8 pci_rev, cache_size; - u16 pci_command; - unsigned int board_type = (unsigned int) ent->driver_data; + unsigned int addr_len, i, pci_using_dac; + u8 pci_rev; #ifndef MODULE static int version_printed; @@ -1785,7 +1628,7 @@ if (pdev->vendor == PCI_VENDOR_ID_REALTEK && pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pci_rev < 0x20) { printk(KERN_ERR PFX "pci dev %s (id %04x:%04x rev %02x) is not an 8139C+ compatible chip\n", - pdev->slot_name, pdev->vendor, pdev->device, pci_rev); + pci_name(pdev), pdev->vendor, pdev->device, pci_rev); printk(KERN_ERR PFX "Try the \"8139too\" driver instead.\n"); return -ENODEV; } @@ -1796,7 +1639,6 @@ SET_MODULE_OWNER(dev); cp = dev->priv; cp->pdev = pdev; - cp->board_type = board_type; cp->dev = dev; cp->msg_enable = (debug < 0 ? CP_DEF_MSG_ENABLE : debug); spin_lock_init (&cp->lock); @@ -1812,48 +1654,56 @@ if (rc) goto err_out_free; - rc = pci_request_regions(pdev, DRV_NAME); + rc = pci_set_mwi(pdev); if (rc) goto err_out_disable; + rc = pci_request_regions(pdev, DRV_NAME); + if (rc) + goto err_out_mwi; + if (pdev->irq < 2) { rc = -EIO; printk(KERN_ERR PFX "invalid irq (%d) for pci dev %s\n", - pdev->irq, pdev->slot_name); + pdev->irq, pci_name(pdev)); goto err_out_res; } pciaddr = pci_resource_start(pdev, 1); if (!pciaddr) { rc = -EIO; printk(KERN_ERR PFX "no MMIO resource for pci dev %s\n", - pdev->slot_name); + pci_name(pdev)); goto err_out_res; } if (pci_resource_len(pdev, 1) < CP_REGS_SIZE) { rc = -EIO; printk(KERN_ERR PFX "MMIO resource (%lx) too small on pci dev %s\n", - pci_resource_len(pdev, 1), pdev->slot_name); + pci_resource_len(pdev, 1), pci_name(pdev)); goto err_out_res; } /* Configure DMA attributes. */ - if (!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff)) { - cp->pci_using_dac = 1; + if ((sizeof(dma_addr_t) > 32) && + !pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) { + pci_using_dac = 1; } else { - rc = pci_set_dma_mask(pdev, (u64) 0xffffffff); + rc = pci_set_dma_mask(pdev, 0xffffffffULL); if (rc) { printk(KERN_ERR PFX "No usable DMA configuration, " "aborting.\n"); goto err_out_res; } - cp->pci_using_dac = 0; + pci_using_dac = 0; } + cp->cpcmd = (pci_using_dac ? PCIDAC : 0) | + PCIMulRW | RxChkSum | CpRxOn | CpTxOn; + regs = ioremap_nocache(pciaddr, CP_REGS_SIZE); if (!regs) { rc = -EIO; printk(KERN_ERR PFX "Cannot map PCI MMIO (%lx@%lx) on pci dev %s\n", - pci_resource_len(pdev, 1), pciaddr, pdev->slot_name); + pci_resource_len(pdev, 1), pciaddr, pci_name(pdev)); goto err_out_res; } dev->base_addr = (unsigned long) regs; @@ -1873,16 +1723,17 @@ dev->hard_start_xmit = cp_start_xmit; dev->get_stats = cp_get_stats; dev->do_ioctl = cp_ioctl; + dev->poll = cp_rx_poll; + dev->weight = 16; /* arbitrary? from NAPI_HOWTO.txt. */ #ifdef BROKEN dev->change_mtu = cp_change_mtu; #endif + dev->ethtool_ops = &cp_ethtool_ops; #if 0 dev->tx_timeout = cp_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; #endif -#ifdef CP_TX_CHECKSUM - dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; -#endif + #if CP_VLAN_TAG_USED dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; dev->vlan_rx_register = cp_vlan_rx_register; @@ -1895,11 +1746,10 @@ if (rc) goto err_out_iomap; - printk (KERN_INFO "%s: %s at 0x%lx, " + printk (KERN_INFO "%s: RTL-8139C+ at 0x%lx, " "%02x:%02x:%02x:%02x:%02x:%02x, " "IRQ %d\n", dev->name, - cp_board_tbl[board_type].name, dev->base_addr, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], @@ -1908,32 +1758,7 @@ pci_set_drvdata(pdev, dev); - /* - * Looks like this is necessary to deal with on all architectures, - * even this %$#%$# N440BX Intel based thing doesn't get it right. - * Ie. having two NICs in the machine, one will have the cache - * line set at boot time, the other will not. - */ - pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_size); - cache_size <<= 2; - if (cache_size != SMP_CACHE_BYTES) { - printk(KERN_INFO "%s: PCI cache line size set incorrectly " - "(%i bytes) by BIOS/FW, ", dev->name, cache_size); - if (cache_size > SMP_CACHE_BYTES) - printk("expecting %i\n", SMP_CACHE_BYTES); - else { - printk("correcting to %i\n", SMP_CACHE_BYTES); - pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, - SMP_CACHE_BYTES >> 2); - } - } - /* 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); if (cp->wol_enabled) cp_set_d3_state (cp); @@ -1944,6 +1769,8 @@ iounmap(regs); err_out_res: pci_release_regions(pdev); +err_out_mwi: + pci_clear_mwi(pdev); err_out_disable: pci_disable_device(pdev); err_out_free: @@ -1951,7 +1778,7 @@ return rc; } -static void __devexit cp_remove_one (struct pci_dev *pdev) +static void cp_remove_one (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct cp_private *cp = dev->priv; @@ -1962,6 +1789,7 @@ iounmap(cp->regs); if (cp->wol_enabled) pci_set_power_state (pdev, 0); pci_release_regions(pdev); + pci_clear_mwi(pdev); pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); kfree(dev); @@ -2024,7 +1852,7 @@ .name = DRV_NAME, .id_table = cp_pci_tbl, .probe = cp_init_one, - .remove = __devexit_p(cp_remove_one), + .remove = cp_remove_one, #ifdef CONFIG_PM .resume = cp_resume, .suspend = cp_suspend, Index: drivers/net/8139too.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/8139too.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/8139too.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/net/8139too.c 4 Aug 2004 01:29:07 -0000 1.2 @@ -116,12 +116,22 @@ #define RTL8139_DRIVER_NAME DRV_NAME " Fast Ethernet driver " DRV_VERSION #define PFX DRV_NAME ": " +/* Default Message level */ +#define RTL8139_DEF_MSG_ENABLE (NETIF_MSG_DRV | \ + NETIF_MSG_PROBE | \ + NETIF_MSG_LINK) + /* enable PIO instead of MMIO, if CONFIG_8139TOO_PIO is selected */ #ifdef CONFIG_8139TOO_PIO #define USE_IO_OPS 1 #endif +/* use a 16K rx ring buffer instead of the default 32K */ +#ifdef CONFIG_SH_DREAMCAST +#define USE_BUF16K 1 +#endif + /* define to 1 to enable copious debugging info */ #undef RTL8139_DEBUG @@ -164,7 +174,11 @@ static int debug = -1; /* Size of the in-memory receive ring. */ +#ifdef USE_BUF16K +#define RX_BUF_LEN_IDX 1 /* 0==8K, 1==16K, 2==32K, 3==64K */ +#else #define RX_BUF_LEN_IDX 2 /* 0==8K, 1==16K, 2==32K, 3==64K */ +#endif #define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX) #define RX_BUF_PAD 16 #define RX_BUF_WRAP_PAD 2048 /* spare padding to handle lack of packet wrap */ @@ -211,18 +225,7 @@ typedef enum { RTL8139 = 0, - RTL8139_CB, - SMC1211TX, - /*MPX5030,*/ - DELTA8139, - ADDTRON8139, - DFE538TX, - DFE690TXD, - FE2000VX, - ALLIED8139, RTL8129, - FNW3603TX, - FNW3800TX, } board_t; @@ -231,36 +234,36 @@ const char *name; u32 hw_flags; } board_info[] __devinitdata = { - { "RealTek RTL8139 Fast Ethernet", RTL8139_CAPS }, - { "RealTek RTL8139B PCI/CardBus", RTL8139_CAPS }, - { "SMC1211TX EZCard 10/100 (RealTek RTL8139)", RTL8139_CAPS }, -/* { MPX5030, "Accton MPX5030 (RealTek RTL8139)", RTL8139_CAPS },*/ - { "Delta Electronics 8139 10/100BaseTX", RTL8139_CAPS }, - { "Addtron Technolgy 8139 10/100BaseTX", RTL8139_CAPS }, - { "D-Link DFE-538TX (RealTek RTL8139)", RTL8139_CAPS }, - { "D-Link DFE-690TXD (RealTek RTL8139)", RTL8139_CAPS }, - { "AboCom FE2000VX (RealTek RTL8139)", RTL8139_CAPS }, - { "Allied Telesyn 8139 CardBus", RTL8139_CAPS }, + { "RealTek RTL8139", RTL8139_CAPS }, { "RealTek RTL8129", RTL8129_CAPS }, - { "Planex FNW-3603-TX 10/100 CardBus", RTL8139_CAPS }, - { "Planex FNW-3800-TX 10/100 CardBus", RTL8139_CAPS }, }; -static struct pci_device_id rtl8139_pci_tbl[] __devinitdata = { +static struct pci_device_id rtl8139_pci_tbl[] = { {0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, - {0x10ec, 0x8138, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139_CB }, - {0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SMC1211TX }, -/* {0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MPX5030 },*/ - {0x1500, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DELTA8139 }, - {0x4033, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ADDTRON8139 }, - {0x1186, 0x1300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DFE538TX }, - {0x1186, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DFE690TXD }, - {0x13d1, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, FE2000VX }, - {0x1259, 0xa117, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ALLIED8139 }, - {0x14ea, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, FNW3603TX }, - {0x14ea, 0xab07, PCI_ANY_ID, PCI_ANY_ID, 0, 0, FNW3800TX }, - + {0x10ec, 0x8138, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x1500, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x4033, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x1186, 0x1300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x1186, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x13d1, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x1259, 0xa117, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x1259, 0xa11e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x14ea, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x14ea, 0xab07, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x11db, 0x1234, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x1432, 0x9130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x02ac, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x018a, 0x0106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x126c, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x1743, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x021b, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + +#ifdef CONFIG_SH_SECUREEDGE5410 + /* Bogus 8139 silicon reports 8129 without external PROM :-( */ + {0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, +#endif #ifdef CONFIG_8139TOO_8129 {0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8129 }, #endif @@ -270,8 +273,8 @@ * so we simply don't match on the main vendor id. */ {PCI_ANY_ID, 0x8139, 0x10ec, 0x8139, 0, 0, RTL8139 }, - {PCI_ANY_ID, 0x8139, 0x1186, 0x1300, 0, 0, DFE538TX }, - {PCI_ANY_ID, 0x8139, 0x13d1, 0xab06, 0, 0, FE2000VX }, + {PCI_ANY_ID, 0x8139, 0x1186, 0x1300, 0, 0, RTL8139 }, + {PCI_ANY_ID, 0x8139, 0x13d1, 0xab06, 0, 0, RTL8139 }, {0,} }; @@ -301,7 +304,6 @@ IntrMask = 0x3C, IntrStatus = 0x3E, TxConfig = 0x40, - ChipVersion = 0x43, RxConfig = 0x44, Timer = 0x48, /* A general-purpose counter. */ RxMissed = 0x4C, /* 24 bits valid, write clears. */ @@ -460,7 +462,6 @@ RxNoWrap = (1 << 7), }; - /* Twister tuning parameters from RealTek. Completely undocumented, but required to tune bad links on some boards. */ enum CSCRBits { @@ -471,36 +472,22 @@ CSCR_LinkDownCmd = 0x0f3c0, }; - enum Cfg9346Bits { Cfg9346_Lock = 0x00, Cfg9346_Unlock = 0xC0, }; -#ifdef CONFIG_8139TOO_TUNE_TWISTER - -enum TwisterParamVals { - PARA78_default = 0x78fa8388, - PARA7c_default = 0xcb38de43, /* param[0][3] */ - PARA7c_xxx = 0xcb38de43, -}; - -static const unsigned long param[4][4] = { - {0xcb39de43, 0xcb39ce43, 0xfb38de03, 0xcb38de43}, - {0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83}, - {0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83}, - {0xbb39de43, 0xbb39ce43, 0xbb39ce83, 0xbb39ce83} -}; - -#endif /* CONFIG_8139TOO_TUNE_TWISTER */ - typedef enum { CH_8139 = 0, CH_8139_K, CH_8139A, + CH_8139A_G, CH_8139B, CH_8130, CH_8139C, + CH_8100, + CH_8100B_8139D, + CH_8101, } chip_t; enum chip_flags { @@ -508,50 +495,65 @@ HasLWake = (1 << 1), }; +#define HW_REVID(b30, b29, b28, b27, b26, b23, b22) \ + (b30<<30 | b29<<29 | b28<<28 | b27<<27 | b26<<26 | b23<<23 | b22<<22) +#define HW_REVID_MASK HW_REVID(1, 1, 1, 1, 1, 1, 1) /* directly indexed by chip_t, above */ const static struct { const char *name; - u8 version; /* from RTL8139C docs */ - u32 RxConfigMask; /* should clear the bits supported by this chip */ + u32 version; /* from RTL8139C/RTL8139D docs */ u32 flags; } rtl_chip_info[] = { { "RTL-8139", - 0x40, - 0xf0fe0040, /* XXX copied from RTL8139A, verify */ + HW_REVID(1, 0, 0, 0, 0, 0, 0), HasHltClk, }, { "RTL-8139 rev K", - 0x60, - 0xf0fe0040, + HW_REVID(1, 1, 0, 0, 0, 0, 0), HasHltClk, }, { "RTL-8139A", - 0x70, - 0xf0fe0040, + HW_REVID(1, 1, 1, 0, 0, 0, 0), + HasHltClk, /* XXX undocumented? */ + }, + + { "RTL-8139A rev G", + HW_REVID(1, 1, 1, 0, 0, 1, 0), HasHltClk, /* XXX undocumented? */ }, { "RTL-8139B", - 0x78, - 0xf0fc0040, + HW_REVID(1, 1, 1, 1, 0, 0, 0), HasLWake, }, { "RTL-8130", - 0x7C, - 0xf0fe0040, /* XXX copied from RTL8139A, verify */ + HW_REVID(1, 1, 1, 1, 1, 0, 0), HasLWake, }, { "RTL-8139C", - 0x74, - 0xf0fc0040, /* XXX copied from RTL8139B, verify */ + HW_REVID(1, 1, 1, 0, 1, 0, 0), + HasLWake, + }, + + { "RTL-8100", + HW_REVID(1, 1, 1, 1, 0, 1, 0), + HasLWake, + }, + + { "RTL-8100B/8139D", + HW_REVID(1, 1, 1, 0, 1, 0, 1), HasLWake, }, + { "RTL-8101", + HW_REVID(1, 1, 1, 0, 1, 1, 1), + HasLWake, + }, }; struct rtl_extra_stats { @@ -565,6 +567,8 @@ void *mmio_addr; int drv_flags; struct pci_dev *pci_dev; + u32 pci_state[16]; + u32 msg_enable; struct net_device_stats stats; unsigned char *rx_ring; unsigned int cur_rx; /* Index into the Rx buffer of next Rx pkt. */ @@ -610,12 +614,12 @@ static int mdio_read (struct net_device *dev, int phy_id, int location); static void mdio_write (struct net_device *dev, int phy_id, int location, int val); -static int rtl8139_thread (void *data); +static inline void rtl8139_start_thread(struct net_device *dev); static void rtl8139_tx_timeout (struct net_device *dev); static void rtl8139_init_ring (struct net_device *dev); static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev); -static void rtl8139_interrupt (int irq, void *dev_instance, +static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance, struct pt_regs *regs); static int rtl8139_close (struct net_device *dev); static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); @@ -623,6 +627,7 @@ static void rtl8139_set_rx_mode (struct net_device *dev); static void __set_rx_mode (struct net_device *dev); static void rtl8139_hw_start (struct net_device *dev); +static struct ethtool_ops rtl8139_ethtool_ops; #ifdef USE_IO_OPS @@ -686,10 +691,17 @@ PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK; +#ifdef USE_BUF16K +static const unsigned int rtl8139_rx_config = + RxCfgRcv16K | RxNoWrap | + (RX_FIFO_THRESH << RxCfgFIFOShift) | + (RX_DMA_BURST << RxCfgDMAShift); +#else static const unsigned int rtl8139_rx_config = RxCfgRcv32K | RxNoWrap | (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); +#endif static const unsigned int rtl8139_tx_config = (TX_DMA_BURST << TxDMAShift) | (TX_RETRY << TxRetryShift); @@ -714,13 +726,6 @@ /* it's ok to call this even if we have no regions to free */ pci_release_regions (pdev); -#ifndef RTL8139_NDEBUG - /* poison memory before freeing */ - memset (dev, 0xBC, - sizeof (struct net_device) + - sizeof (struct rtl8139_private)); -#endif /* RTL8139_NDEBUG */ - kfree (dev); pci_set_drvdata (pdev, NULL); @@ -755,7 +760,7 @@ unsigned int i; u32 pio_start, pio_end, pio_flags, pio_len; unsigned long mmio_start, mmio_end, mmio_flags, mmio_len; - u32 tmp; + u32 version; assert (pdev != NULL); @@ -764,10 +769,11 @@ /* dev and dev->priv zeroed in alloc_etherdev */ dev = alloc_etherdev (sizeof (*tp)); if (dev == NULL) { - printk (KERN_ERR PFX "%s: Unable to alloc new net device\n", pdev->slot_name); + printk (KERN_ERR PFX "%s: Unable to alloc new net device\n", pci_name(pdev)); return -ENOMEM; } SET_MODULE_OWNER(dev); + tp = dev->priv; tp->pci_dev = pdev; @@ -794,25 +800,25 @@ #ifdef USE_IO_OPS /* make sure PCI base addr 0 is PIO */ if (!(pio_flags & IORESOURCE_IO)) { - printk (KERN_ERR PFX "%s: region #0 not a PIO resource, aborting\n", pdev->slot_name); + printk (KERN_ERR PFX "%s: region #0 not a PIO resource, aborting\n", pci_name(pdev)); rc = -ENODEV; goto err_out; } /* check for weird/broken PCI region reporting */ if (pio_len < RTL_MIN_IO_SIZE) { - printk (KERN_ERR PFX "%s: Invalid PCI I/O region size(s), aborting\n", pdev->slot_name); + printk (KERN_ERR PFX "%s: Invalid PCI I/O region size(s), aborting\n", pci_name(pdev)); rc = -ENODEV; goto err_out; } #else /* make sure PCI base addr 1 is MMIO */ if (!(mmio_flags & IORESOURCE_MEM)) { - printk (KERN_ERR PFX "%s: region #1 not an MMIO resource, aborting\n", pdev->slot_name); + printk (KERN_ERR PFX "%s: region #1 not an MMIO resource, aborting\n", pci_name(pdev)); rc = -ENODEV; goto err_out; } if (mmio_len < RTL_MIN_IO_SIZE) { - printk (KERN_ERR PFX "%s: Invalid PCI mem region size(s), aborting\n", pdev->slot_name); + printk (KERN_ERR PFX "%s: Invalid PCI mem region size(s), aborting\n", pci_name(pdev)); rc = -ENODEV; goto err_out; } @@ -834,7 +840,7 @@ /* ioremap MMIO region */ ioaddr = ioremap (mmio_start, mmio_len); if (ioaddr == NULL) { - printk (KERN_ERR PFX "%s: cannot remap MMIO, aborting\n", pdev->slot_name); + printk (KERN_ERR PFX "%s: cannot remap MMIO, aborting\n", pci_name(pdev)); rc = -EIO; goto err_out; } @@ -849,23 +855,23 @@ /* check for missing/broken hardware */ if (RTL_R32 (TxConfig) == 0xFFFFFFFF) { printk (KERN_ERR PFX "%s: Chip not responding, ignoring board\n", - pdev->slot_name); + pci_name(pdev)); rc = -EIO; goto err_out; } /* identify chip attached to board */ - tmp = RTL_R8 (ChipVersion); + version = RTL_R32 (TxConfig) & HW_REVID_MASK; for (i = 0; i < ARRAY_SIZE (rtl_chip_info); i++) - if (tmp == rtl_chip_info[i].version) { + if (version == rtl_chip_info[i].version) { tp->chipset = i; goto match; } /* if unknown chip, assume array element #0, original RTL-8139 in this case */ printk (KERN_DEBUG PFX "%s: unknown chip version, assuming RTL-8139\n", - pdev->slot_name); - printk (KERN_DEBUG PFX "%s: TxConfig = 0x%lx\n", pdev->slot_name, RTL_R32 (TxConfig)); + pci_name(pdev)); + printk (KERN_DEBUG PFX "%s: TxConfig = 0x%lx\n", pci_name(pdev), RTL_R32 (TxConfig)); tp->chipset = 0; match: @@ -888,8 +894,11 @@ } if (rtl_chip_info[tp->chipset].flags & HasLWake) { tmp8 = RTL_R8 (Config4); - if (tmp8 & LWPTN) + if (tmp8 & LWPTN) { + RTL_W8 (Cfg9346, Cfg9346_Unlock); RTL_W8 (Config4, tmp8 & ~LWPTN); + RTL_W8 (Cfg9346, Cfg9346_Lock); + } } } else { DPRINTK("Old chip wakeup\n"); @@ -940,7 +949,7 @@ if (pdev->vendor == PCI_VENDOR_ID_REALTEK && pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pci_rev >= 0x20) { printk(KERN_INFO PFX "pci dev %s (id %04x:%04x rev %02x) is an enhanced 8139C+ chip\n", - pdev->slot_name, pdev->vendor, pdev->device, pci_rev); + pci_name(pdev), pdev->vendor, pdev->device, pci_rev); printk(KERN_INFO PFX "Use the \"8139cp\" driver for improved performance and stability.\n"); } @@ -948,12 +957,11 @@ if (i < 0) return i; + assert (dev != NULL); tp = dev->priv; + assert (tp != NULL); ioaddr = tp->mmio_addr; - assert (ioaddr != NULL); - assert (dev != NULL); - assert (tp != NULL); addr_len = read_eeprom (ioaddr, 0, 8) == 0x8129 ? 8 : 6; for (i = 0; i < 3; i++) @@ -967,6 +975,7 @@ dev->get_stats = rtl8139_get_stats; dev->set_multicast_list = rtl8139_set_rx_mode; dev->do_ioctl = netdev_ioctl; + dev->ethtool_ops = &rtl8139_ethtool_ops; dev->tx_timeout = rtl8139_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; @@ -978,12 +987,14 @@ 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 */ tp->drv_flags = board_info[ent->driver_data].hw_flags; tp->mmio_addr = ioaddr; + tp->msg_enable = + (debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1)); spin_lock_init (&tp->lock); init_waitqueue_head (&tp->thr_wait); init_completion (&tp->thr_exited); @@ -1286,9 +1297,7 @@ { struct rtl8139_private *tp = dev->priv; int retval; -#ifdef RTL8139_DEBUG void *ioaddr = tp->mmio_addr; -#endif retval = request_irq (dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev); if (retval) @@ -1314,44 +1323,29 @@ tp->mii.full_duplex = tp->mii.force_media; tp->tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000; - tp->twistie = (tp->chipset == CH_8139_K) ? 1 : 0; - tp->time_to_die = 0; rtl8139_init_ring (dev); rtl8139_hw_start (dev); - DPRINTK ("%s: rtl8139_open() ioaddr %#lx IRQ %d" + if (netif_msg_ifup(tp)) + printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#lx IRQ %d" " GP Pins %2.2x %s-duplex.\n", dev->name, pci_resource_start (tp->pci_dev, 1), dev->irq, RTL_R8 (MediaStatus), tp->mii.full_duplex ? "full" : "half"); - tp->thr_pid = kernel_thread (rtl8139_thread, dev, CLONE_FS | CLONE_FILES); - if (tp->thr_pid < 0) - printk (KERN_WARNING "%s: unable to start kernel thread\n", - dev->name); + rtl8139_start_thread(dev); return 0; } -static void rtl_check_media (struct net_device *dev) +static void rtl_check_media (struct net_device *dev, unsigned int init_media) { struct rtl8139_private *tp = dev->priv; if (tp->phys[0] >= 0) { - u16 mii_lpa = mdio_read(dev, tp->phys[0], MII_LPA); - if (mii_lpa == 0xffff) - ; /* Not there */ - else if ((mii_lpa & LPA_100FULL) == LPA_100FULL - || (mii_lpa & 0x00C0) == LPA_10FULL) - tp->mii.full_duplex = 1; - - printk (KERN_INFO"%s: Setting %s%s-duplex based on" - " auto-negotiated partner ability %4.4x.\n", - dev->name, mii_lpa == 0 ? "" : - (mii_lpa & 0x0180) ? "100mbps " : "10mbps ", - tp->mii.full_duplex ? "full" : "half", mii_lpa); + mii_check_media(&tp->mii, netif_msg_link(tp), init_media); } } @@ -1386,7 +1380,7 @@ tp->cur_rx = 0; - rtl_check_media (dev); + rtl_check_media (dev, 1); if (tp->chipset >= CH_8139B) { /* Disable magic packet scanning, which is enabled @@ -1448,6 +1442,19 @@ static inline void rtl8139_tune_twister (struct net_device *dev, struct rtl8139_private *tp) {} #else +enum TwisterParamVals { + PARA78_default = 0x78fa8388, + PARA7c_default = 0xcb38de43, /* param[0][3] */ + PARA7c_xxx = 0xcb38de43, +}; + +static const unsigned long param[4][4] = { + {0xcb39de43, 0xcb39ce43, 0xfb38de03, 0xcb38de43}, + {0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83}, + {0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83}, + {0xbb39de43, 0xbb39ce43, 0xbb39ce83, 0xbb39ce83} +}; + static void rtl8139_tune_twister (struct net_device *dev, struct rtl8139_private *tp) { @@ -1534,7 +1541,6 @@ } #endif /* CONFIG_8139TOO_TUNE_TWISTER */ - static inline void rtl8139_thread_iter (struct net_device *dev, struct rtl8139_private *tp, void *ioaddr) @@ -1581,7 +1587,6 @@ RTL_R8 (Config1)); } - static int rtl8139_thread (void *data) { struct net_device *dev = data; @@ -1621,6 +1626,24 @@ complete_and_exit (&tp->thr_exited, 0); } +static inline void rtl8139_start_thread(struct net_device *dev) +{ + struct rtl8139_private *tp = dev->priv; + + tp->thr_pid = -1; + tp->twistie = 0; + tp->time_to_die = 0; + if (tp->chipset == CH_8139_K) + tp->twistie = 1; + else if (tp->drv_flags & HAS_LNK_CHNG) + return; + + tp->thr_pid = kernel_thread(rtl8139_thread, dev, CLONE_FS|CLONE_FILES); + if (tp->thr_pid < 0) { + printk (KERN_WARNING "%s: unable to start kernel thread\n", + dev->name); + } +} static void rtl8139_tx_clear (struct rtl8139_private *tp) { @@ -1687,7 +1710,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); @@ -1711,8 +1734,9 @@ netif_stop_queue (dev); spin_unlock_irq(&tp->lock); - DPRINTK ("%s: Queued Tx packet size %u to slot %d.\n", - dev->name, len, entry); + if (netif_msg_tx_queued(tp)) + printk (KERN_DEBUG "%s: Queued Tx packet size %u to slot %d.\n", + dev->name, len, entry); return 0; } @@ -1742,8 +1766,9 @@ /* Note: TxCarrierLost is always asserted at 100mbps. */ if (txstatus & (TxOutOfWindow | TxAborted)) { /* There was an major error, log it. */ - DPRINTK ("%s: Transmit error, Tx status %8.8x.\n", - dev->name, txstatus); + if (netif_msg_tx_err(tp)) + printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n", + dev->name, txstatus); tp->stats.tx_errors++; if (txstatus & TxAborted) { tp->stats.tx_aborted_errors++; @@ -1798,8 +1823,9 @@ int tmp_work; #endif - DPRINTK ("%s: Ethernet frame had errors, status %8.8x.\n", - dev->name, rx_status); + if (netif_msg_rx_err (tp)) + printk(KERN_DEBUG "%s: Ethernet frame had errors, status %8.8x.\n", + dev->name, rx_status); tp->stats.rx_errors++; if (!(rx_status & RxStatusOK)) { if (rx_status & RxTooLong) { @@ -1903,8 +1929,9 @@ rx_size = rx_status >> 16; pkt_size = rx_size - 4; - DPRINTK ("%s: rtl8139_rx() status %4.4x, size %4.4x," - " cur %4.4x.\n", dev->name, rx_status, + if (netif_msg_rx_status(tp)) + printk(KERN_DEBUG "%s: rtl8139_rx() status %4.4x, size %4.4x," + " cur %4.4x.\n", dev->name, rx_status, rx_size, cur_rx); #if RTL8139_DEBUG > 2 { @@ -2001,18 +2028,7 @@ if ((status & RxUnderrun) && link_changed && (tp->drv_flags & HAS_LNK_CHNG)) { - /* Really link-change on new chips. */ - int lpar = RTL_R16 (NWayLPAR); - int duplex = (lpar & LPA_100FULL) || (lpar & 0x01C0) == 0x0040 - || tp->mii.force_media; - if (tp->mii.full_duplex != duplex) { - tp->mii.full_duplex = duplex; -#if 0 - RTL_W8 (Cfg9346, Cfg9346_Unlock); - RTL_W8 (Config1, tp->mii.full_duplex ? 0x60 : 0x20); - RTL_W8 (Cfg9346, Cfg9346_Lock); -#endif - } + rtl_check_media(dev, 0); status &= ~RxUnderrun; } @@ -2038,7 +2054,7 @@ /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static void rtl8139_interrupt (int irq, void *dev_instance, +static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_instance; @@ -2047,6 +2063,7 @@ void *ioaddr = tp->mmio_addr; int ackstat, status; int link_changed = 0; /* avoid bogus "uninit" warning */ + int handled = 0; spin_lock (&tp->lock); @@ -2062,6 +2079,8 @@ RxFIFOOver | TxErr | TxOK | RxErr | RxOK)) == 0) break; + handled = 1; + /* Acknowledge all of the current interrupt sources ASAP, but an first get an additional status bit from CSCR. */ if (status & RxUnderrun) @@ -2073,8 +2092,9 @@ ackstat = status & ~(RxAckBits | TxErr); 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)); + if (netif_msg_intr(tp)) + printk (KERN_DEBUG "%s: interrupt status=%#4.4x ackstat=%#4.4x new intstat=%#4.4x.\n", + dev->name, status, ackstat, RTL_R16 (IntrStatus)); if (netif_running (dev) && (status & RxAckBits)) rtl8139_rx_interrupt (dev, tp, ioaddr); @@ -2106,6 +2126,7 @@ DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n", dev->name, RTL_R16 (IntrStatus)); + return IRQ_RETVAL(handled); } @@ -2128,8 +2149,9 @@ } wait_for_completion (&tp->thr_exited); } - - DPRINTK ("%s: Shutting down ethercard, status was 0x%4.4x.\n", + + if (netif_msg_ifdown(tp)) + printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n", dev->name, RTL_R16 (IntrStatus)); spin_lock_irqsave (&tp->lock, flags); @@ -2146,7 +2168,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); @@ -2171,11 +2193,12 @@ /* Get the ethtool Wake-on-LAN settings. Assumes that wol points to kernel memory, *wol has been initialized as {ETHTOOL_GWOL}, and other threads or interrupts aren't messing with the 8139. */ -static void netdev_get_wol (struct net_device *dev, struct ethtool_wolinfo *wol) +static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct rtl8139_private *np = dev->priv; void *ioaddr = np->mmio_addr; + spin_lock_irq(&np->lock); if (rtl_chip_info[np->chipset].flags & HasLWake) { u8 cfg3 = RTL_R8 (Config3); u8 cfg5 = RTL_R8 (Config5); @@ -2197,14 +2220,14 @@ if (cfg5 & Cfg5_BWF) wol->wolopts |= WAKE_BCAST; } + spin_unlock_irq(&np->lock); } /* Set the ethtool Wake-on-LAN settings. Return 0 or -errno. Assumes that wol points to kernel memory and other threads or interrupts aren't messing with the 8139. */ -static int netdev_set_wol (struct net_device *dev, - const struct ethtool_wolinfo *wol) +static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct rtl8139_private *np = dev->priv; void *ioaddr = np->mmio_addr; @@ -2218,6 +2241,7 @@ if (wol->wolopts & ~support) return -EINVAL; + spin_lock_irq(&np->lock); cfg3 = RTL_R8 (Config3) & ~(Cfg3_LinkUp | Cfg3_Magic); if (wol->wolopts & WAKE_PHY) cfg3 |= Cfg3_LinkUp; @@ -2238,213 +2262,122 @@ if (wol->wolopts & WAKE_BCAST) cfg5 |= Cfg5_BWF; RTL_W8 (Config5, cfg5); /* need not unlock via Cfg9346 */ + spin_unlock_irq(&np->lock); return 0; } -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void rtl8139_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { struct rtl8139_private *np = dev->priv; - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + strcpy(info->bus_info, pci_name(np->pci_dev)); + info->regdump_len = np->regs_len; +} - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; +static int rtl8139_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct rtl8139_private *np = dev->priv; + spin_lock_irq(&np->lock); + mii_ethtool_gset(&np->mii, cmd); + spin_unlock_irq(&np->lock); + return 0; +} - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - strcpy (info.bus_info, np->pci_dev->slot_name); - info.regdump_len = np->regs_len; - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } +static int rtl8139_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct rtl8139_private *np = dev->priv; + int rc; + spin_lock_irq(&np->lock); + rc = mii_ethtool_sset(&np->mii, cmd); + spin_unlock_irq(&np->lock); + return rc; +} - /* get settings */ - case ETHTOOL_GSET: { - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - spin_lock_irq(&np->lock); - mii_ethtool_gset(&np->mii, &ecmd); - spin_unlock_irq(&np->lock); - if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } - /* set settings */ - case ETHTOOL_SSET: { - int r; - struct ethtool_cmd ecmd; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - spin_lock_irq(&np->lock); - r = mii_ethtool_sset(&np->mii, &ecmd); - spin_unlock_irq(&np->lock); - return r; - } - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - return mii_nway_restart(&np->mii); - } - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = {ETHTOOL_GLINK}; - edata.data = mii_link_ok(&np->mii); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } +static int rtl8139_nway_reset(struct net_device *dev) +{ + struct rtl8139_private *np = dev->priv; + return mii_nway_restart(&np->mii); +} - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } +static u32 rtl8139_get_link(struct net_device *dev) +{ + struct rtl8139_private *np = dev->priv; + return mii_link_ok(&np->mii); +} - case ETHTOOL_GWOL: - { - struct ethtool_wolinfo wol = { ETHTOOL_GWOL }; - spin_lock_irq (&np->lock); - netdev_get_wol (dev, &wol); - spin_unlock_irq (&np->lock); - if (copy_to_user (useraddr, &wol, sizeof (wol))) - return -EFAULT; - return 0; - } +static u32 rtl8139_get_msglevel(struct net_device *dev) +{ + struct rtl8139_private *np = dev->priv; + return np->msg_enable; +} - case ETHTOOL_SWOL: - { - struct ethtool_wolinfo wol; - int rc; - if (copy_from_user (&wol, useraddr, sizeof (wol))) - return -EFAULT; - spin_lock_irq (&np->lock); - rc = netdev_set_wol (dev, &wol); - spin_unlock_irq (&np->lock); - return rc; - } +static void rtl8139_set_msglevel(struct net_device *dev, u32 datum) +{ + struct rtl8139_private *np = dev->priv; + np->msg_enable = datum; +} /* TODO: we are too slack to do reg dumping for pio, for now */ -#ifndef CONFIG_8139TOO_PIO - /* NIC register dump */ - case ETHTOOL_GREGS: { - struct ethtool_regs regs; - unsigned int regs_len = np->regs_len; - u8 *regbuf = kmalloc(regs_len, GFP_KERNEL); - int rc; - - if (!regbuf) - return -ENOMEM; - memset(regbuf, 0, regs_len); - - rc = copy_from_user(®s, useraddr, sizeof(regs)); - if (rc) { - rc = -EFAULT; - goto err_out_gregs; - } - - if (regs.len > regs_len) - regs.len = regs_len; - if (regs.len < regs_len) { - rc = -EINVAL; - goto err_out_gregs; - } - - regs.version = RTL_REGS_VER; - rc = copy_to_user(useraddr, ®s, sizeof(regs)); - if (rc) { - rc = -EFAULT; - goto err_out_gregs; - } - - useraddr += offsetof(struct ethtool_regs, data); - - spin_lock_irq(&np->lock); - memcpy_fromio(regbuf, np->mmio_addr, regs_len); - spin_unlock_irq(&np->lock); - - if (copy_to_user(useraddr, regbuf, regs_len)) - rc = -EFAULT; - -err_out_gregs: - kfree(regbuf); - return rc; - } -#endif /* CONFIG_8139TOO_PIO */ - - /* get string list(s) */ - case ETHTOOL_GSTRINGS: { - struct ethtool_gstrings estr = { ETHTOOL_GSTRINGS }; - - if (copy_from_user(&estr, useraddr, sizeof(estr))) - return -EFAULT; - if (estr.string_set != ETH_SS_STATS) - return -EINVAL; - - estr.len = RTL_NUM_STATS; - if (copy_to_user(useraddr, &estr, sizeof(estr))) - return -EFAULT; - if (copy_to_user(useraddr + sizeof(estr), - ðtool_stats_keys, - sizeof(ethtool_stats_keys))) - return -EFAULT; - return 0; - } +#ifdef CONFIG_8139TOO_PIO +#define rtl8139_get_regs_len NULL +#define rtl8139_get_regs NULL +#else +static int rtl8139_get_regs_len(struct net_device *dev) +{ + struct rtl8139_private *np = dev->priv; + return np->regs_len; +} - /* get NIC-specific statistics */ - case ETHTOOL_GSTATS: { - struct ethtool_stats estats = { ETHTOOL_GSTATS }; - u64 *tmp_stats; - const unsigned int sz = sizeof(u64) * RTL_NUM_STATS; - int i; - - estats.n_stats = RTL_NUM_STATS; - if (copy_to_user(useraddr, &estats, sizeof(estats))) - return -EFAULT; - - tmp_stats = kmalloc(sz, GFP_KERNEL); - if (!tmp_stats) - return -ENOMEM; - memset(tmp_stats, 0, sz); - - i = 0; - tmp_stats[i++] = np->xstats.early_rx; - tmp_stats[i++] = np->xstats.tx_buf_mapped; - tmp_stats[i++] = np->xstats.tx_timeouts; - tmp_stats[i++] = np->xstats.rx_lost_in_ring; - if (i != RTL_NUM_STATS) - BUG(); +static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf) +{ + struct rtl8139_private *np = dev->priv; - i = copy_to_user(useraddr + sizeof(estats), tmp_stats, sz); - kfree(tmp_stats); + regs->version = RTL_REGS_VER; - if (i) - return -EFAULT; - return 0; - } - default: - break; - } + spin_lock_irq(&np->lock); + memcpy_fromio(regbuf, np->mmio_addr, regs->len); + spin_unlock_irq(&np->lock); +} +#endif /* CONFIG_8139TOO_MMIO */ - return -EOPNOTSUPP; +static int rtl8139_get_stats_count(struct net_device *dev) +{ + return RTL_NUM_STATS; } +static void rtl8139_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data) +{ + struct rtl8139_private *np = dev->priv; + + data[0] = np->xstats.early_rx; + data[1] = np->xstats.tx_buf_mapped; + data[2] = np->xstats.tx_timeouts; + data[3] = np->xstats.rx_lost_in_ring; +} + +static void rtl8139_get_strings(struct net_device *dev, u32 stringset, u8 *data) +{ + memcpy(data, ethtool_stats_keys, sizeof(ethtool_stats_keys)); +} + +static struct ethtool_ops rtl8139_ethtool_ops = { + .get_drvinfo = rtl8139_get_drvinfo, + .get_settings = rtl8139_get_settings, + .set_settings = rtl8139_set_settings, + .get_regs_len = rtl8139_get_regs_len, + .get_regs = rtl8139_get_regs, + .nway_reset = rtl8139_nway_reset, + .get_link = rtl8139_get_link, + .get_msglevel = rtl8139_get_msglevel, + .set_msglevel = rtl8139_set_msglevel, + .get_wol = rtl8139_get_wol, + .set_wol = rtl8139_set_wol, + .get_strings = rtl8139_get_strings, + .get_stats_count = rtl8139_get_stats_count, + .get_ethtool_stats = rtl8139_get_ethtool_stats, +}; static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { @@ -2455,14 +2388,9 @@ if (!netif_running(dev)) return -EINVAL; - if (cmd == SIOCETHTOOL) - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - - else { - spin_lock_irq(&np->lock); - rc = generic_mii_ioctl(&np->mii, data, cmd, NULL); - spin_unlock_irq(&np->lock); - } + spin_lock_irq(&np->lock); + rc = generic_mii_ioctl(&np->mii, data, cmd, NULL); + spin_unlock_irq(&np->lock); return rc; } @@ -2569,6 +2497,9 @@ tp->stats.rx_missed_errors += RTL_R32 (RxMissed); RTL_W32 (RxMissed, 0); + pci_set_power_state (pdev, 3); + pci_save_state (pdev, tp->pci_state); + spin_unlock_irqrestore (&tp->lock, flags); return 0; } @@ -2577,11 +2508,15 @@ static int rtl8139_resume (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata (pdev); + struct rtl8139_private *tp = dev->priv; if (!netif_running (dev)) return 0; - netif_device_attach (dev); + pci_restore_state (pdev, tp->pci_state); + pci_set_power_state (pdev, 0); + rtl8139_init_ring (dev); rtl8139_hw_start (dev); + netif_device_attach (dev); return 0; } Index: drivers/net/82596.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/82596.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/82596.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/82596.c 4 Aug 2004 01:29:07 -0000 1.2 @@ -64,7 +64,7 @@ #include static char version[] __initdata = - "82596.c $Revision: 1.1 $\n"; + "82596.c $Revision: 1.2 $\n"; /* DEBUG flags */ Index: drivers/net/8390.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/8390.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/8390.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/8390.c 4 Aug 2004 01:29:07 -0000 1.2 @@ -1000,6 +1000,11 @@ spin_unlock_irqrestore(&ei_local->page_lock, flags); } +static inline void ei_device_init(struct ei_device *ei_local) +{ + spin_lock_init(&ei_local->page_lock); +} + /** * ethdev_init - init rest of 8390 device struct * @dev: network device structure to init @@ -1015,14 +1020,11 @@ if (dev->priv == NULL) { - struct ei_device *ei_local; - dev->priv = kmalloc(sizeof(struct ei_device), GFP_KERNEL); if (dev->priv == NULL) return -ENOMEM; memset(dev->priv, 0, sizeof(struct ei_device)); - ei_local = (struct ei_device *)dev->priv; - spin_lock_init(&ei_local->page_lock); + ei_device_init(dev->priv); } dev->hard_start_xmit = &ei_start_xmit; @@ -1033,6 +1035,29 @@ return 0; } + +/* wrapper to make alloc_netdev happy; probably should just cast... */ +static void __ethdev_init(struct net_device *dev) +{ + ethdev_init(dev); +} + +/** + * alloc_ei_netdev - alloc_etherdev counterpart for 8390 + * + * Allocate 8390-specific net_device. + */ +struct net_device *alloc_ei_netdev(void) +{ + struct net_device *dev; + + dev = alloc_netdev(sizeof(struct ei_device), "eth%d", __ethdev_init); + if (dev) + ei_device_init(dev->priv); + + return dev; +} + @@ -1136,6 +1161,7 @@ EXPORT_SYMBOL(ei_tx_timeout); EXPORT_SYMBOL(ethdev_init); EXPORT_SYMBOL(NS8390_init); +EXPORT_SYMBOL(alloc_ei_netdev); #if defined(MODULE) Index: drivers/net/8390.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/8390.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/8390.h 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/8390.h 4 Aug 2004 01:29:07 -0000 1.2 @@ -50,6 +50,7 @@ extern int ei_open(struct net_device *dev); extern int ei_close(struct net_device *dev); extern void ei_interrupt(int irq, void *dev_id, struct pt_regs *regs); +extern struct net_device *alloc_ei_netdev(void); /* Most of these entries should be in 'struct net_device' (or most of the things in there should be here!) */ @@ -116,7 +117,7 @@ */ #if defined(CONFIG_MAC) || \ - defined(CONFIG_ARIADNE2) || defined(CONFIG_ARIADNE2_MODULE) || \ + defined(CONFIG_ZORRO8390) || defined(CONFIG_ZORRO8390_MODULE) || \ defined(CONFIG_HYDRA) || defined(CONFIG_HYDRA_MODULE) #define EI_SHIFT(x) (ei_local->reg_offset[x]) #undef inb Index: drivers/net/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/Config.in,v retrieving revision 1.1 retrieving revision 1.5 diff -u -r1.1 -r1.5 --- drivers/net/Config.in 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/Config.in 2 Jan 2006 18:36:38 -0000 1.5 @@ -17,7 +17,7 @@ fi # -# Ethernet +# Ethernet # mainmenu_option next_comment @@ -27,6 +27,9 @@ if [ "$CONFIG_ARM" = "y" ]; then dep_bool ' ARM EBSA110 AM79C961A support' CONFIG_ARM_AM79C961A $CONFIG_ARCH_EBSA110 tristate ' Cirrus Logic CS8900A support' CONFIG_ARM_CIRRUS + tristate ' TS-ETH10 support' CONFIG_CS89x0 + tristate ' TS-OpenETH Ethernet MAC 10/100 OpenCore support' CONFIG_OPENETH + tristate ' MicroBee ethernet radio support' CONFIG_NE2000 if [ "$CONFIG_ARCH_EP9301" = "y" -o \ "$CONFIG_ARCH_EP9312" = "y" -o \ "$CONFIG_ARCH_EP9315" = "y" ]; then @@ -43,26 +46,26 @@ fi fi if [ "$CONFIG_ARCH_CAMELOT" = "y" ]; then - tristate ' Altera Ether00 support' CONFIG_ETHER00 + tristate ' Altera Ether00 support' CONFIG_ETHER00 fi if [ "$CONFIG_PPC" = "y" ]; then dep_tristate ' MACE (Power Mac ethernet) support' CONFIG_MACE $CONFIG_ALL_PPC if [ "$CONFIG_MACE" != "n" ]; then - bool ' Use AAUI port instead of TP by default' CONFIG_MACE_AAUI_PORT + bool ' Use AAUI port instead of TP by default' CONFIG_MACE_AAUI_PORT fi dep_tristate ' BMAC (G3 ethernet) support' CONFIG_BMAC $CONFIG_ALL_PPC dep_tristate ' GMAC (G4/iBook ethernet) support (OBSOLETE, use Sun GEM)' CONFIG_GMAC $CONFIG_ALL_PPC if [ "$CONFIG_4xx" = "y" ]; then if [ "$CONFIG_STB03xxx" = "y" -o "$CONFIG_403GCX" = "y" ]; then - tristate ' National DP83902AV (Oak ethernet) support' CONFIG_OAKNET - fi + tristate ' National DP83902AV (Oak ethernet) support' CONFIG_OAKNET + fi fi fi if [ "$CONFIG_ZORRO" = "y" ]; then tristate ' Ariadne support' CONFIG_ARIADNE - tristate ' Ariadne II and X-Surf support' CONFIG_NE2K_ZORRO tristate ' A2065 support' CONFIG_A2065 tristate ' Hydra support' CONFIG_HYDRA + tristate ' Zorro NS8390-based Ethernet support' CONFIG_ZORRO8390 fi if [ "$CONFIG_PARISC" = "y" ]; then dep_tristate ' Lasi ethernet' CONFIG_LASI_82596 $CONFIG_GSC_LASI @@ -70,21 +73,24 @@ if [ "$CONFIG_MIPS_JAZZ" = "y" ]; then tristate ' MIPS JAZZ onboard SONIC Ethernet support' CONFIG_MIPS_JAZZ_SONIC fi + if [ "$CONFIG_MOMENCO_OCELOT_G" = "y" ]; then + bool ' GT-64240 Ethernet support' CONFIG_GALILEO_64240_ETH + fi if [ "$CONFIG_MIPS_GT96100" = "y" ]; then bool ' MIPS GT96100 Ethernet support' CONFIG_MIPS_GT96100ETH fi - if [ "$CONFIG_MIPS_AU1000" = "y" ]; then - bool ' MIPS AU1000 Ethernet support' CONFIG_MIPS_AU1000_ENET + if [ "$CONFIG_SOC_AU1X00" = "y" ]; then + tristate ' MIPS Au1x00 Ethernet support' CONFIG_MIPS_AU1X00_ENET + if [ "$CONFIG_MIPS_AU1X00_ENET" = "y" ]; then + bool ' Broadcom 5222 Dual Phy Support' CONFIG_BCM5222_DUAL_PHY + fi fi - if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then + if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then tristate ' SB1250 Ethernet support' CONFIG_NET_SB1250_MAC fi if [ "$CONFIG_SGI_IP27" = "y" ]; then bool ' SGI IOC3 Ethernet' CONFIG_SGI_IOC3_ETH fi - if [ "$CONFIG_SGI_IP32" = "y" ]; then - tristate ' SGI O2 MACE Fast Ethernet support' CONFIG_SGI_O2MACE_ETH - fi if [ "$CONFIG_IA64_SGI_SN1" = "y" ]; then bool ' SGI IOC3 Ethernet' CONFIG_SGI_IOC3_ETH fi @@ -116,7 +122,7 @@ tristate ' 3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX fi if [ "$CONFIG_PCI" = "y" ]; then - tristate ' 3cr990 series "Typhoon" support' CONFIG_TYPHOON + tristate ' 3cr990 series "Typhoon" support' CONFIG_TYPHOON fi fi dep_tristate ' AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE $CONFIG_ISA @@ -158,7 +164,7 @@ tristate ' ICL EtherTeam 16i/32 support' CONFIG_ETH16I tristate ' NE2000/NE1000 support' CONFIG_NE2000 if [ "$CONFIG_OBSOLETE" = "y" ]; then - dep_tristate ' SEEQ8005 support (EXPERIMENTAL)' CONFIG_SEEQ8005 $CONFIG_EXPERIMENTAL + dep_tristate ' SEEQ8005 support (EXPERIMENTAL)' CONFIG_SEEQ8005 $CONFIG_EXPERIMENTAL fi if [ "$CONFIG_OBSOLETE" = "y" ]; then tristate ' SK_G16 support' CONFIG_SK_G16 @@ -179,10 +185,11 @@ dep_tristate ' AMD 8111 (new PCI lance) support' CONFIG_AMD8111_ETH $CONFIG_PCI dep_tristate ' Adaptec Starfire/DuraLAN support' CONFIG_ADAPTEC_STARFIRE $CONFIG_PCI if [ "$CONFIG_ISA" = "y" -o "$CONFIG_EISA" = "y" ]; then - dep_tristate ' Ansel Communications EISA 3200 support (EXPERIMENTAL)' CONFIG_AC3200 $CONFIG_EXPERIMENTAL + dep_tristate ' Ansel Communications EISA 3200 support (EXPERIMENTAL)' CONFIG_AC3200 $CONFIG_EXPERIMENTAL 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 @@ -205,6 +212,7 @@ dep_tristate ' Myson MTD-8xx PCI Ethernet support' CONFIG_FEALNX $CONFIG_PCI dep_tristate ' National Semiconductor DP8381x series PCI Ethernet support' CONFIG_NATSEMI $CONFIG_PCI dep_tristate ' PCI NE2000 and clones support (see help)' CONFIG_NE2K_PCI $CONFIG_PCI + dep_tristate ' nForce Ethernet support (EXPERIMENTAL)' CONFIG_FORCEDETH $CONFIG_PCI $CONFIG_EXPERIMENTAL dep_tristate ' Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)' CONFIG_NE3210 $CONFIG_EISA $CONFIG_EXPERIMENTAL dep_tristate ' Racal-Interlan EISA ES3210 support (EXPERIMENTAL)' CONFIG_ES3210 $CONFIG_EISA $CONFIG_EXPERIMENTAL dep_tristate ' RealTek RTL-8139 C+ PCI Fast Ethernet Adapter support (EXPERIMENTAL)' CONFIG_8139CP $CONFIG_PCI $CONFIG_EXPERIMENTAL @@ -220,15 +228,17 @@ 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 if [ "$CONFIG_OBSOLETE" = "y" ]; then - dep_bool ' Zenith Z-Note support (OBSOLETE)' CONFIG_ZNET $CONFIG_ISA + dep_bool ' Zenith Z-Note support (OBSOLETE)' CONFIG_ZNET $CONFIG_ISA fi if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_MIPS" = "y" ]; then - bool ' Philips SAA9730 Ethernet support (EXPERIMENTAL)' CONFIG_LAN_SAA9730 + bool ' Philips SAA9730 Ethernet support (EXPERIMENTAL)' CONFIG_LAN_SAA9730 fi fi bool ' Pocket and portable adapters' CONFIG_NET_POCKET @@ -240,7 +250,7 @@ dep_tristate ' D-Link DE620 pocket adapter support' CONFIG_DE620 $CONFIG_ISA fi if [ "$CONFIG_SGI_IP22" = "y" ]; then - bool ' SGI Seeq ethernet controller support' CONFIG_SGISEEQ + tristate ' SGI Seeq ethernet controller support' CONFIG_SGISEEQ fi if [ "$CONFIG_DECSTATION" = "y" ]; then tristate ' DEC LANCE ethernet controller support' CONFIG_DECLANCE @@ -256,7 +266,7 @@ endmenu # -# Gigabit Ethernet +# Gigabit Ethernet # mainmenu_option next_comment @@ -268,20 +278,33 @@ 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 dep_tristate 'Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)' CONFIG_YELLOWFIN $CONFIG_PCI $CONFIG_EXPERIMENTAL dep_tristate 'Realtek 8169 Gigabit Ethernet support' CONFIG_R8169 $CONFIG_PCI -dep_tristate 'SysKonnect SK-98xx and SK-95xx Gigabit Ethernet Adapter family support' CONFIG_SK98LIN $CONFIG_PCI +dep_tristate 'Marvell Yukon Chipset / SysKonnect SK-98xx Support' CONFIG_SK98LIN $CONFIG_PCI dep_tristate 'Broadcom Tigon3 support' CONFIG_TIGON3 $CONFIG_PCI +if [ "$CONFIG_MOMENCO_OCELOT_C" = "y" -o "$CONFIG_MOMENCO_JAGUAR_ATX" = "y" ]; then + bool ' MV-64340 Ethernet support' CONFIG_MV64340_ETH + dep_bool ' MV-64340 Port 0' CONFIG_MV64340_ETH_0 $CONFIG_MV64340_ETH + dep_bool ' MV-64340 Port 1' CONFIG_MV64340_ETH_1 $CONFIG_MV64340_ETH + dep_bool ' MV-64340 Port 2' CONFIG_MV64340_ETH_2 $CONFIG_MV64340_ETH +fi endmenu if [ "$CONFIG_PPC_ISERIES" = "y" ]; then 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 @@ -296,7 +319,7 @@ if [ "$CONFIG_HIPPI" = "y" -a "$CONFIG_PCI" = "y" ]; then dep_tristate ' Essential RoadRunner HIPPI PCI adapter support (EXPERIMENTAL)' CONFIG_ROADRUNNER $CONFIG_PCI if [ "$CONFIG_ROADRUNNER" != "n" ]; then - bool ' Use large TX/RX rings (EXPERIMENTAL)' CONFIG_ROADRUNNER_LARGE_RINGS + bool ' Use large TX/RX rings (EXPERIMENTAL)' CONFIG_ROADRUNNER_LARGE_RINGS fi fi fi @@ -315,8 +338,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 Index: drivers/net/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/Makefile,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/net/Makefile 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/Makefile 2 Jan 2006 18:36:38 -0000 1.3 @@ -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 @@ -107,6 +115,8 @@ # end link order section # +obj-$(CONFIG_GALILEO_64240_ETH) += gt64240eth.o +obj-$(CONFIG_MV64340_ETH) += mv64340_eth.o obj-$(CONFIG_AIRONET4500) += aironet4500_core.o obj-$(CONFIG_AIRONET4500_CS) += aironet4500_core.o obj-$(CONFIG_AIRONET4500_NONCS) += aironet4500_card.o @@ -143,6 +153,8 @@ 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_FORCEDETH) += forcedeth.o obj-$(CONFIG_PPP) += ppp_generic.o slhc.o obj-$(CONFIG_PPP_ASYNC) += ppp_async.o @@ -158,7 +170,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 @@ -167,7 +178,6 @@ obj-$(CONFIG_SUN3LANCE) += sun3lance.o obj-$(CONFIG_DEFXX) += defxx.o obj-$(CONFIG_SGISEEQ) += sgiseeq.o -obj-$(CONFIG_SGI_O2MACE_ETH) += meth.o obj-$(CONFIG_AT1700) += at1700.o obj-$(CONFIG_FMV18X) += fmv18x.o obj-$(CONFIG_EL1) += 3c501.o @@ -204,13 +214,13 @@ obj-$(CONFIG_LP486E) += lp486e.o obj-$(CONFIG_ETH16I) += eth16i.o -obj-$(CONFIG_ARIADNE2) += ariadne2.o 8390.o +obj-$(CONFIG_ZORRO8390) += zorro8390.o 8390.o obj-$(CONFIG_HPLANCE) += hplance.o 7990.o obj-$(CONFIG_MVME147_NET) += mvme147.o 7990.o obj-$(CONFIG_EQUALIZER) += eql.o obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o obj-$(CONFIG_MIPS_GT96100ETH) += gt96100eth.o -obj-$(CONFIG_MIPS_AU1000_ENET) += au1000_eth.o +obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o obj-$(CONFIG_BAGETLANCE) += bagetlance.o obj-$(CONFIG_DECLANCE) += declance.o @@ -230,11 +240,12 @@ 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 +obj-$(CONFIG_OPENETH) += open_eth.o # non-drivers/net drivers who want mii lib obj-$(CONFIG_PCMCIA_SMC91C92) += mii.o - +obj-$(CONFIG_USB_USBNET) += mii.o obj-$(CONFIG_AT91_ETHER) += mii.o ifeq ($(CONFIG_ARCH_ACORN),y) @@ -260,4 +271,3 @@ rcpci.o: $(rcpci-objs) $(LD) -r -o $@ $(rcpci-objs) - Index: drivers/net/Space.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/Space.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/Space.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/Space.c 4 Aug 2004 01:29:07 -0000 1.2 @@ -83,7 +83,6 @@ extern int SK_init(struct net_device *); extern int seeq8005_probe(struct net_device *); extern int smc_init( struct net_device * ); -extern int sgiseeq_probe(struct net_device *); extern int atarilance_probe(struct net_device *); extern int sun3lance_probe(struct net_device *); extern int sun3_82586_probe(struct net_device *); @@ -370,14 +369,6 @@ {NULL, 0}, }; - -static struct devprobe sgi_probes[] __initdata = { -#ifdef CONFIG_SGISEEQ - {sgiseeq_probe, 0}, -#endif - {NULL, 0}, -}; - static struct devprobe mips_probes[] __initdata = { #ifdef CONFIG_MIPS_JAZZ_SONIC {sonic_probe, 0}, @@ -412,8 +403,6 @@ return 0; if (probe_list(dev, mips_probes) == 0) return 0; - if (probe_list(dev, sgi_probes) == 0) - return 0; if (probe_list(dev, eisa_probes) == 0) return 0; if (probe_list(dev, mca_probes) == 0) Index: drivers/net/acenic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/acenic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/acenic.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/acenic.c 4 Aug 2004 01:29:07 -0000 1.2 @@ -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; Index: drivers/net/am79c961a.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/am79c961a.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/am79c961a.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/am79c961a.c 4 Aug 2004 01:29:07 -0000 1.2 @@ -54,25 +54,25 @@ #ifdef __arm__ static void write_rreg(u_long base, u_int reg, u_int val) { - __asm__("str%?h %1, [%2] @ NET_RAP - str%?h %0, [%2, #-4] @ NET_RDP - " : : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464)); + __asm__("str%?h %1, [%2] @ NET_RAP\n\t" + "str%?h %0, [%2, #-4] @ NET_RDP" + : : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464)); } static inline unsigned short read_rreg(u_long base_addr, u_int reg) { unsigned short v; - __asm__("str%?h %1, [%2] @ NET_RAP - ldr%?h %0, [%2, #-4] @ NET_RDP - " : "=r" (v): "r" (reg), "r" (ISAIO_BASE + 0x0464)); + __asm__("str%?h %1, [%2] @ NET_RAP\n\t" + "ldr%?h %0, [%2, #-4] @ NET_RDP" + : "=r" (v): "r" (reg), "r" (ISAIO_BASE + 0x0464)); return v; } static inline void write_ireg(u_long base, u_int reg, u_int val) { - __asm__("str%?h %1, [%2] @ NET_RAP - str%?h %0, [%2, #8] @ NET_IDP - " : : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464)); + __asm__("str%?h %1, [%2] @ NET_RAP\n\t" + "str%?h %0, [%2, #8] @ NET_IDP" + : : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464)); } static inline unsigned short read_ireg(u_long base_addr, u_int reg) @@ -102,16 +102,16 @@ } while (length > 8) { unsigned int tmp, tmp2; - __asm__ __volatile__(" - ldm%?ia %1!, {%2, %3} - str%?h %2, [%0], #4 - mov%? %2, %2, lsr #16 - str%?h %2, [%0], #4 - str%?h %3, [%0], #4 - mov%? %3, %3, lsr #16 - str%?h %3, [%0], #4 - " : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2) - : "0" (offset), "1" (buf)); + __asm__ __volatile__( + "ldm%?ia %1!, {%2, %3}\n\t" + "str%?h %2, [%0], #4\n\t" + "mov%? %2, %2, lsr #16\n\t" + "str%?h %2, [%0], #4\n\t" + "str%?h %3, [%0], #4\n\t" + "mov%? %3, %3, lsr #16\n\t" + "str%?h %3, [%0], #4" + : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2) + : "0" (offset), "1" (buf)); length -= 8; } while (length > 0) { @@ -129,36 +129,36 @@ length = (length + 1) & ~1; if ((int)buf & 2) { unsigned int tmp; - __asm__ __volatile__(" - ldr%?h %2, [%0], #4 - str%?b %2, [%1], #1 - mov%? %2, %2, lsr #8 - str%?b %2, [%1], #1 - " : "=&r" (offset), "=&r" (buf), "=r" (tmp): "0" (offset), "1" (buf)); + __asm__ __volatile__( + "ldr%?h %2, [%0], #4\n\t" + "str%?b %2, [%1], #1\n\t" + "mov%? %2, %2, lsr #8\n\t" + "str%?b %2, [%1], #1" + : "=&r" (offset), "=&r" (buf), "=r" (tmp): "0" (offset), "1" (buf)); length -= 2; } while (length > 8) { unsigned int tmp, tmp2, tmp3; - __asm__ __volatile__(" - ldr%?h %2, [%0], #4 - ldr%?h %3, [%0], #4 - orr%? %2, %2, %3, lsl #16 - ldr%?h %3, [%0], #4 - ldr%?h %4, [%0], #4 - orr%? %3, %3, %4, lsl #16 - stm%?ia %1!, {%2, %3} - " : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2), "=r" (tmp3) - : "0" (offset), "1" (buf)); + __asm__ __volatile__( + "ldr%?h %2, [%0], #4\n\t" + "ldr%?h %3, [%0], #4\n\t" + "orr%? %2, %2, %3, lsl #16\n\t" + "ldr%?h %3, [%0], #4\n\t" + "ldr%?h %4, [%0], #4\n\t" + "orr%? %3, %3, %4, lsl #16\n\t" + "stm%?ia %1!, {%2, %3}" + : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2), "=r" (tmp3) + : "0" (offset), "1" (buf)); length -= 8; } while (length > 0) { unsigned int tmp; - __asm__ __volatile__(" - ldr%?h %2, [%0], #4 - str%?b %2, [%1], #1 - mov%? %2, %2, lsr #8 - str%?b %2, [%1], #1 - " : "=&r" (offset), "=&r" (buf), "=r" (tmp) : "0" (offset), "1" (buf)); + __asm__ __volatile__( + "ldr%?h %2, [%0], #4\n\t" + "str%?b %2, [%1], #1\n\t" + "mov%? %2, %2, lsr #8\n\t" + "str%?b %2, [%1], #1" + : "=&r" (offset), "=&r" (buf), "=r" (tmp) : "0" (offset), "1" (buf)); length -= 2; } } Index: drivers/net/amd8111e.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/amd8111e.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/amd8111e.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/amd8111e.c 4 Aug 2004 01:29:07 -0000 1.2 @@ -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); Index: drivers/net/amd8111e.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/amd8111e.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/amd8111e.h 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/amd8111e.h 4 Aug 2004 01:29:07 -0000 1.2 @@ -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 */ Index: drivers/net/apne.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/apne.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/apne.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/apne.c 4 Aug 2004 01:29:07 -0000 1.2 @@ -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; } Index: drivers/net/ariadne2.c =================================================================== RCS file: drivers/net/ariadne2.c diff -N drivers/net/ariadne2.c --- drivers/net/ariadne2.c 22 Jul 2004 19:49:35 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,427 +0,0 @@ -/* - * Amiga Linux/m68k and Linux/PPC Ariadne II and X-Surf Ethernet Driver - * - * (C) Copyright 1998-2000 by some Elitist 680x0 Users(TM) - * - * --------------------------------------------------------------------------- - * - * This program is based on all the other NE2000 drivers for Linux - * - * --------------------------------------------------------------------------- - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of the Linux - * distribution for more details. - * - * --------------------------------------------------------------------------- - * - * The Ariadne II and X-Surf are Zorro-II boards containing Realtek RTL8019AS - * Ethernet Controllers. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include "8390.h" - - -#define NE_BASE (dev->base_addr) -#define NE_CMD (0x00*2) -#define NE_DATAPORT (0x10*2) /* NatSemi-defined port window offset. */ -#define NE_RESET (0x1f*2) /* Issue a read to reset, a write to clear. */ -#define NE_IO_EXTENT (0x20*2) - -#define NE_EN0_ISR (0x07*2) -#define NE_EN0_DCFG (0x0e*2) - -#define NE_EN0_RSARLO (0x08*2) -#define NE_EN0_RSARHI (0x09*2) -#define NE_EN0_RCNTLO (0x0a*2) -#define NE_EN0_RXCR (0x0c*2) -#define NE_EN0_TXCR (0x0d*2) -#define NE_EN0_RCNTHI (0x0b*2) -#define NE_EN0_IMR (0x0f*2) - -#define NESM_START_PG 0x40 /* First page of TX buffer */ -#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ - - -#define WORDSWAP(a) ((((a)>>8)&0xff) | ((a)<<8)) - -#ifdef MODULE -static struct net_device *root_ariadne2_dev; -#endif - -static const struct card_info { - zorro_id id; - const char *name; - unsigned int offset; -} cards[] __initdata = { - { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, "Ariadne II", 0x0600 }, - { ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, "X-Surf", 0x8600 }, -}; - -static int __init ariadne2_probe(void); -static int __init ariadne2_init(struct net_device *dev, unsigned long board, - const char *name, unsigned long ioaddr); -static int ariadne2_open(struct net_device *dev); -static int ariadne2_close(struct net_device *dev); -static void ariadne2_reset_8390(struct net_device *dev); -static void ariadne2_get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, int ring_page); -static void ariadne2_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset); -static void ariadne2_block_output(struct net_device *dev, const int count, - const unsigned char *buf, - const int start_page); -static void __exit ariadne2_cleanup(void); - -static int __init ariadne2_probe(void) -{ - struct net_device *dev; - struct zorro_dev *z = NULL; - unsigned long board, ioaddr; - int err = -ENODEV; - int i; - - while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { - for (i = ARRAY_SIZE(cards)-1; i >= 0; i--) - if (z->id == cards[i].id) - break; - if (i < 0) - continue; - board = z->resource.start; - ioaddr = board+cards[i].offset; - dev = init_etherdev(0, 0); - SET_MODULE_OWNER(dev); - if (!dev) - return -ENOMEM; - if (!request_mem_region(ioaddr, NE_IO_EXTENT*2, dev->name)) { - kfree(dev); - continue; - } - if ((err = ariadne2_init(dev, board, cards[i].name, - ZTWO_VADDR(ioaddr)))) { - release_mem_region(ioaddr, NE_IO_EXTENT*2); - kfree(dev); - return err; - } - err = 0; - } - - if (err == -ENODEV) - printk("No Ariadne II or X-Surf ethernet card found.\n"); - return err; -} - -static int __init ariadne2_init(struct net_device *dev, unsigned long board, - const char *name, unsigned long ioaddr) -{ - int i; - unsigned char SA_prom[32]; - int start_page, stop_page; - static u32 ariadne2_offsets[16] = { - 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, - 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, - }; - - /* Reset card. Who knows what dain-bramaged state it was left in. */ - { - unsigned long reset_start_time = jiffies; - - z_writeb(z_readb(ioaddr + NE_RESET), ioaddr + NE_RESET); - - while ((z_readb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0) - if (jiffies - reset_start_time > 2*HZ/100) { - printk(" not found (no reset ack).\n"); - return -ENODEV; - } - - z_writeb(0xff, ioaddr + NE_EN0_ISR); /* Ack all intr. */ - } - - /* Read the 16 bytes of station address PROM. - We must first initialize registers, similar to NS8390_init(eifdev, 0). - We can't reliably read the SAPROM address without this. - (I learned the hard way!). */ - { - struct { - u32 value; - u32 offset; - } program_seq[] = { - {E8390_NODMA+E8390_PAGE0+E8390_STOP, NE_CMD}, /* Select page 0*/ - {0x48, NE_EN0_DCFG}, /* Set byte-wide (0x48) access. */ - {0x00, NE_EN0_RCNTLO}, /* Clear the count regs. */ - {0x00, NE_EN0_RCNTHI}, - {0x00, NE_EN0_IMR}, /* Mask completion irq. */ - {0xFF, NE_EN0_ISR}, - {E8390_RXOFF, NE_EN0_RXCR}, /* 0x20 Set to monitor */ - {E8390_TXOFF, NE_EN0_TXCR}, /* 0x02 and loopback mode. */ - {32, NE_EN0_RCNTLO}, - {0x00, NE_EN0_RCNTHI}, - {0x00, NE_EN0_RSARLO}, /* DMA starting at 0x0000. */ - {0x00, NE_EN0_RSARHI}, - {E8390_RREAD+E8390_START, NE_CMD}, - }; - for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++) { - z_writeb(program_seq[i].value, ioaddr + program_seq[i].offset); - } - } - for (i = 0; i < 16; i++) { - SA_prom[i] = z_readb(ioaddr + NE_DATAPORT); - (void)z_readb(ioaddr + NE_DATAPORT); - } - - /* We must set the 8390 for word mode. */ - z_writeb(0x49, ioaddr + NE_EN0_DCFG); - start_page = NESM_START_PG; - stop_page = NESM_STOP_PG; - - dev->base_addr = ioaddr; - dev->irq = IRQ_AMIGA_PORTS; - - /* Install the Interrupt handler */ - i = request_irq(IRQ_AMIGA_PORTS, ei_interrupt, SA_SHIRQ, dev->name, dev); - if (i) return i; - - /* Allocate dev->priv and fill in 8390 specific dev fields. */ - if (ethdev_init(dev)) { - printk("Unable to get memory for dev->priv.\n"); - return -ENOMEM; - } - - for(i = 0; i < ETHER_ADDR_LEN; i++) { -#ifdef DEBUG - printk(" %2.2x", SA_prom[i]); -#endif - dev->dev_addr[i] = SA_prom[i]; - } - - printk("%s: %s at 0x%08lx, Ethernet Address " - "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, name, board, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); - - ei_status.name = name; - ei_status.tx_start_page = start_page; - ei_status.stop_page = stop_page; - ei_status.word16 = 1; - - ei_status.rx_start_page = start_page + TX_PAGES; - - ei_status.reset_8390 = &ariadne2_reset_8390; - ei_status.block_input = &ariadne2_block_input; - ei_status.block_output = &ariadne2_block_output; - ei_status.get_8390_hdr = &ariadne2_get_8390_hdr; - ei_status.reg_offset = ariadne2_offsets; - dev->open = &ariadne2_open; - dev->stop = &ariadne2_close; -#ifdef MODULE - ei_status.priv = (unsigned long)root_ariadne2_dev; - root_ariadne2_dev = dev; -#endif - NS8390_init(dev, 0); - return 0; -} - -static int ariadne2_open(struct net_device *dev) -{ - ei_open(dev); - return 0; -} - -static int ariadne2_close(struct net_device *dev) -{ - if (ei_debug > 1) - printk("%s: Shutting down ethercard.\n", dev->name); - ei_close(dev); - return 0; -} - -/* Hard reset the card. This used to pause for the same period that a - 8390 reset command required, but that shouldn't be necessary. */ -static void ariadne2_reset_8390(struct net_device *dev) -{ - unsigned long reset_start_time = jiffies; - - if (ei_debug > 1) - printk("resetting the 8390 t=%ld...", jiffies); - - z_writeb(z_readb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); - - ei_status.txing = 0; - ei_status.dmaing = 0; - - /* This check _should_not_ be necessary, omit eventually. */ - while ((z_readb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0) - if (jiffies - reset_start_time > 2*HZ/100) { - printk("%s: ne_reset_8390() did not complete.\n", dev->name); - break; - } - z_writeb(ENISR_RESET, NE_BASE + NE_EN0_ISR); /* Ack intr. */ -} - -/* Grab the 8390 specific header. Similar to the block_input routine, but - we don't need to be concerned with ring wrap as the header will be at - the start of a page, so we optimize accordingly. */ - -static void ariadne2_get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, int ring_page) -{ - int nic_base = dev->base_addr; - int cnt; - short *ptrs; - - /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) { - printk("%s: DMAing conflict in ne_get_8390_hdr " - "[DMAstat:%d][irqlock:%d].\n", dev->name, ei_status.dmaing, - ei_status.irqlock); - return; - } - - ei_status.dmaing |= 0x01; - z_writeb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); - z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); - z_writeb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO); - z_writeb(0, nic_base + NE_EN0_RCNTHI); - z_writeb(0, nic_base + NE_EN0_RSARLO); /* On page boundary */ - z_writeb(ring_page, nic_base + NE_EN0_RSARHI); - z_writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD); - - ptrs = (short*)hdr; - for (cnt = 0; cnt < (sizeof(struct e8390_pkt_hdr)>>1); cnt++) - *ptrs++ = z_readw(NE_BASE + NE_DATAPORT); - - z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */ - - hdr->count = WORDSWAP(hdr->count); - - ei_status.dmaing &= ~0x01; -} - -/* Block input and output, similar to the Crynwr packet driver. If you - are porting to a new ethercard, look at the packet driver source for hints. - The NEx000 doesn't share the on-board packet memory -- you have to put - the packet out through the "remote DMA" dataport using z_writeb. */ - -static void ariadne2_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset) -{ - int nic_base = dev->base_addr; - char *buf = skb->data; - short *ptrs; - int cnt; - - /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) { - printk("%s: DMAing conflict in ne_block_input " - "[DMAstat:%d][irqlock:%d].\n", - dev->name, ei_status.dmaing, ei_status.irqlock); - return; - } - ei_status.dmaing |= 0x01; - z_writeb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); - z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); - z_writeb(count & 0xff, nic_base + NE_EN0_RCNTLO); - z_writeb(count >> 8, nic_base + NE_EN0_RCNTHI); - z_writeb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO); - z_writeb(ring_offset >> 8, nic_base + NE_EN0_RSARHI); - z_writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD); - ptrs = (short*)buf; - for (cnt = 0; cnt < (count>>1); cnt++) - *ptrs++ = z_readw(NE_BASE + NE_DATAPORT); - if (count & 0x01) - buf[count-1] = z_readb(NE_BASE + NE_DATAPORT); - - z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x01; -} - -static void ariadne2_block_output(struct net_device *dev, int count, - const unsigned char *buf, - const int start_page) -{ - int nic_base = NE_BASE; - unsigned long dma_start; - short *ptrs; - int cnt; - - /* Round the count up for word writes. Do we need to do this? - What effect will an odd byte count have on the 8390? - I should check someday. */ - if (count & 0x01) - count++; - - /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) { - printk("%s: DMAing conflict in ne_block_output." - "[DMAstat:%d][irqlock:%d]\n", dev->name, ei_status.dmaing, - ei_status.irqlock); - return; - } - ei_status.dmaing |= 0x01; - /* We should already be in page 0, but to be safe... */ - z_writeb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); - - z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); - - /* Now the normal output. */ - z_writeb(count & 0xff, nic_base + NE_EN0_RCNTLO); - z_writeb(count >> 8, nic_base + NE_EN0_RCNTHI); - z_writeb(0x00, nic_base + NE_EN0_RSARLO); - z_writeb(start_page, nic_base + NE_EN0_RSARHI); - - z_writeb(E8390_RWRITE+E8390_START, nic_base + NE_CMD); - ptrs = (short*)buf; - for (cnt = 0; cnt < count>>1; cnt++) - z_writew(*ptrs++, NE_BASE+NE_DATAPORT); - - dma_start = jiffies; - - while ((z_readb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0) - if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ - printk("%s: timeout waiting for Tx RDC.\n", dev->name); - ariadne2_reset_8390(dev); - NS8390_init(dev,1); - break; - } - - z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x01; - return; -} - -static void __exit ariadne2_cleanup(void) -{ -#ifdef MODULE - struct net_device *dev, *next; - - while ((dev = root_ariadne2_dev)) { - next = (struct net_device *)(ei_status.priv); - unregister_netdev(dev); - free_irq(IRQ_AMIGA_PORTS, dev); - release_mem_region(ZTWO_PADDR(dev->base_addr), NE_IO_EXTENT*2); - kfree(dev); - root_ariadne2_dev = next; - } -#endif -} - -module_init(ariadne2_probe); -module_exit(ariadne2_cleanup); - -MODULE_LICENSE("GPL"); Index: drivers/net/atari_pamsnet.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/atari_pamsnet.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/atari_pamsnet.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/atari_pamsnet.c 4 Aug 2004 01:29:07 -0000 1.2 @@ -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) Index: drivers/net/au1000_eth.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/au1000_eth.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/au1000_eth.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/au1000_eth.c 4 Aug 2004 01:29:07 -0000 1.2 @@ -1,8 +1,9 @@ /* * - * Alchemy Semi Au1000 ethernet driver + * Alchemy Au1x00 ethernet driver * - * Copyright 2001 MontaVista Software Inc. + * Copyright 2001,2002,2003 MontaVista Software Inc. + * Copyright 2002 TimeSys Corp. * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com * @@ -22,8 +23,15 @@ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * * ######################################################################## + * + * */ -#include + +#ifndef __mips__ +#error This driver only works with MIPS architectures! +#endif + + #include #include #include @@ -44,22 +52,27 @@ #include #include #include +#include #include +#include #include "au1000_eth.h" + #ifdef AU1000_ETH_DEBUG -static int au1000_debug = 10; +static int au1000_debug = 5; #else static int au1000_debug = 3; #endif +MODULE_LICENSE("GPL"); + // prototypes static void *dma_alloc(size_t, dma_addr_t *); static void dma_free(void *, size_t); static void hard_stop(struct net_device *); static void enable_rx_tx(struct net_device *dev); -static int __init au1000_probe1(struct net_device *, long, int, int); +static struct net_device * au1000_probe(u32 ioaddr, int irq, int port_num); static int au1000_init(struct net_device *); static int au1000_open(struct net_device *); static int au1000_close(struct net_device *); @@ -101,27 +114,8 @@ */ -/* - * Base address and interupt of the Au1xxx ethernet macs - */ -static struct { - unsigned int port; - int irq; -} au1000_iflist[NUM_INTERFACES] = { - {AU1000_ETH0_BASE, AU1000_ETH0_IRQ}, - {AU1000_ETH1_BASE, AU1000_ETH1_IRQ} - }, - au1500_iflist[NUM_INTERFACES] = { - {AU1500_ETH0_BASE, AU1000_ETH0_IRQ}, - {AU1500_ETH1_BASE, AU1000_ETH1_IRQ} - }, - au1100_iflist[NUM_INTERFACES] = { - {AU1000_ETH0_BASE, AU1000_ETH0_IRQ}, - {NULL, NULL} - }; - static char version[] __devinitdata = - "au1000eth.c:1.0 ppopov@mvista.com\n"; + "au1000eth.c:1.4 ppopov@mvista.com\n"; /* These addresses are only used if yamon doesn't tell us what * the mac address is, and the mac address is not passed on the @@ -138,6 +132,7 @@ #define cpu_to_dma32 cpu_to_be32 #define dma32_to_cpu be32_to_cpu +struct au1000_private *au_macs[NUM_ETH_INTERFACES]; /* FIXME * All of the PHY code really should be detached from the MAC @@ -156,7 +151,6 @@ s16 data; /* Stop auto-negotiation */ - //printk("bcm_5201_init\n"); data = mdio_read(dev, phy_addr, MII_CONTROL); mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO); @@ -171,12 +165,8 @@ data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO; mdio_write(dev, phy_addr, MII_CONTROL, data); - /* Enable TX LED instead of FDX */ - data = mdio_read(dev, phy_addr, MII_INT); - data &= ~MII_FDX_LED; - mdio_write(dev, phy_addr, MII_INT, data); - - if (au1000_debug > 4) dump_mii(dev, phy_addr); + if (au1000_debug > 4) + dump_mii(dev, phy_addr); return 0; } @@ -184,7 +174,6 @@ { s16 mii_control, timeout; - //printk("bcm_5201_reset\n"); mii_control = mdio_read(dev, phy_addr, MII_CONTROL); mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); mdelay(1); @@ -247,8 +236,8 @@ printk("lsi_80227_init\n"); /* restart auto-negotiation */ - mdio_write(dev, phy_addr, 0, 0x3200); - + mdio_write(dev, phy_addr, MII_CONTROL, + MII_CNTL_F100 | MII_CNTL_AUTO | MII_CNTL_RST_AUTO); // | MII_CNTL_FDX); mdelay(1); /* set up LEDs to correct display */ @@ -299,9 +288,9 @@ mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); if (mii_data & MII_STAT_LINK) { *link = 1; - mii_data = mdio_read(dev, aup->phy_addr, MII_LSI_STAT); - if (mii_data & MII_LSI_STAT_SPD) { - if (mii_data & MII_LSI_STAT_FDX) { + mii_data = mdio_read(dev, aup->phy_addr, MII_LSI_PHY_STAT); + if (mii_data & MII_LSI_PHY_STAT_SPD) { + if (mii_data & MII_LSI_PHY_STAT_FDX) { *speed = IF_PORT_100BASEFX; dev->if_port = IF_PORT_100BASEFX; } @@ -342,12 +331,303 @@ return 0; } +int am79c874_init(struct net_device *dev, int phy_addr) +{ + s16 data; + + /* 79c874 has quit resembled bit assignments to BCM5201 */ + if (au1000_debug > 4) + printk("am79c847_init\n"); + + /* Stop auto-negotiation */ + data = mdio_read(dev, phy_addr, MII_CONTROL); + mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO); + + /* Set advertisement to 10/100 and Half/Full duplex + * (full capabilities) */ + data = mdio_read(dev, phy_addr, MII_ANADV); + data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T; + mdio_write(dev, phy_addr, MII_ANADV, data); + + /* Restart auto-negotiation */ + data = mdio_read(dev, phy_addr, MII_CONTROL); + data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO; + + mdio_write(dev, phy_addr, MII_CONTROL, data); + + if (au1000_debug > 4) dump_mii(dev, phy_addr); + return 0; +} + +int am79c874_reset(struct net_device *dev, int phy_addr) +{ + s16 mii_control, timeout; + + if (au1000_debug > 4) + printk("am79c874_reset\n"); + + mii_control = mdio_read(dev, phy_addr, MII_CONTROL); + mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); + mdelay(1); + for (timeout = 100; timeout > 0; --timeout) { + mii_control = mdio_read(dev, phy_addr, MII_CONTROL); + if ((mii_control & MII_CNTL_RESET) == 0) + break; + mdelay(1); + } + if (mii_control & MII_CNTL_RESET) { + printk(KERN_ERR "%s PHY reset timeout !\n", dev->name); + return -1; + } + return 0; +} + +int +am79c874_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) +{ + u16 mii_data; + struct au1000_private *aup; + + // printk("am79c874_status\n"); + if (!dev) { + printk(KERN_ERR "am79c874_status error: NULL dev\n"); + return -1; + } + + aup = (struct au1000_private *) dev->priv; + mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); + + if (mii_data & MII_STAT_LINK) { + *link = 1; + mii_data = mdio_read(dev, aup->phy_addr, MII_AMD_PHY_STAT); + if (mii_data & MII_AMD_PHY_STAT_SPD) { + if (mii_data & MII_AMD_PHY_STAT_FDX) { + *speed = IF_PORT_100BASEFX; + dev->if_port = IF_PORT_100BASEFX; + } + else { + *speed = IF_PORT_100BASETX; + dev->if_port = IF_PORT_100BASETX; + } + } + else { + *speed = IF_PORT_10BASET; + dev->if_port = IF_PORT_10BASET; + } + + } + else { + *link = 0; + *speed = 0; + dev->if_port = IF_PORT_UNKNOWN; + } + return 0; +} + +int lxt971a_init(struct net_device *dev, int phy_addr) +{ + if (au1000_debug > 4) + printk("lxt971a_init\n"); + + /* restart auto-negotiation */ + mdio_write(dev, phy_addr, MII_CONTROL, + MII_CNTL_F100 | MII_CNTL_AUTO | MII_CNTL_RST_AUTO | MII_CNTL_FDX); + + /* set up LEDs to correct display */ + mdio_write(dev, phy_addr, 20, 0x0422); + + if (au1000_debug > 4) + dump_mii(dev, phy_addr); + return 0; +} + +int lxt971a_reset(struct net_device *dev, int phy_addr) +{ + s16 mii_control, timeout; + + if (au1000_debug > 4) { + printk("lxt971a_reset\n"); + dump_mii(dev, phy_addr); + } + + mii_control = mdio_read(dev, phy_addr, MII_CONTROL); + mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); + mdelay(1); + for (timeout = 100; timeout > 0; --timeout) { + mii_control = mdio_read(dev, phy_addr, MII_CONTROL); + if ((mii_control & MII_CNTL_RESET) == 0) + break; + mdelay(1); + } + if (mii_control & MII_CNTL_RESET) { + printk(KERN_ERR "%s PHY reset timeout !\n", dev->name); + return -1; + } + return 0; +} + +int +lxt971a_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) +{ + u16 mii_data; + struct au1000_private *aup; + + if (!dev) { + printk(KERN_ERR "lxt971a_status error: NULL dev\n"); + return -1; + } + aup = (struct au1000_private *) dev->priv; + + mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); + if (mii_data & MII_STAT_LINK) { + *link = 1; + mii_data = mdio_read(dev, aup->phy_addr, MII_INTEL_PHY_STAT); + if (mii_data & MII_INTEL_PHY_STAT_SPD) { + if (mii_data & MII_INTEL_PHY_STAT_FDX) { + *speed = IF_PORT_100BASEFX; + dev->if_port = IF_PORT_100BASEFX; + } + else { + *speed = IF_PORT_100BASETX; + dev->if_port = IF_PORT_100BASETX; + } + } + else { + *speed = IF_PORT_10BASET; + dev->if_port = IF_PORT_10BASET; + } + + } + else { + *link = 0; + *speed = 0; + dev->if_port = IF_PORT_UNKNOWN; + } + return 0; +} + +int ks8995m_init(struct net_device *dev, int phy_addr) +{ + s16 data; + +// printk("ks8995m_init\n"); + /* Stop auto-negotiation */ + data = mdio_read(dev, phy_addr, MII_CONTROL); + mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO); + + /* Set advertisement to 10/100 and Half/Full duplex + * (full capabilities) */ + data = mdio_read(dev, phy_addr, MII_ANADV); + data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T; + mdio_write(dev, phy_addr, MII_ANADV, data); + + /* Restart auto-negotiation */ + data = mdio_read(dev, phy_addr, MII_CONTROL); + data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO; + mdio_write(dev, phy_addr, MII_CONTROL, data); + + if (au1000_debug > 4) dump_mii(dev, phy_addr); + + return 0; +} + +int ks8995m_reset(struct net_device *dev, int phy_addr) +{ + s16 mii_control, timeout; + +// printk("ks8995m_reset\n"); + mii_control = mdio_read(dev, phy_addr, MII_CONTROL); + mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); + mdelay(1); + for (timeout = 100; timeout > 0; --timeout) { + mii_control = mdio_read(dev, phy_addr, MII_CONTROL); + if ((mii_control & MII_CNTL_RESET) == 0) + break; + mdelay(1); + } + if (mii_control & MII_CNTL_RESET) { + printk(KERN_ERR "%s PHY reset timeout !\n", dev->name); + return -1; + } + return 0; +} + +int ks8995m_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) +{ + u16 mii_data; + struct au1000_private *aup; + + if (!dev) { + printk(KERN_ERR "ks8995m_status error: NULL dev\n"); + return -1; + } + aup = (struct au1000_private *) dev->priv; + + mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); + if (mii_data & MII_STAT_LINK) { + *link = 1; + mii_data = mdio_read(dev, aup->phy_addr, MII_AUX_CNTRL); + if (mii_data & MII_AUX_100) { + if (mii_data & MII_AUX_FDX) { + *speed = IF_PORT_100BASEFX; + dev->if_port = IF_PORT_100BASEFX; + } + else { + *speed = IF_PORT_100BASETX; + dev->if_port = IF_PORT_100BASETX; + } + } + else { + *speed = IF_PORT_10BASET; + dev->if_port = IF_PORT_10BASET; + } + + } + else { + *link = 0; + *speed = 0; + dev->if_port = IF_PORT_UNKNOWN; + } + return 0; +} + +#ifdef CONFIG_MIPS_BOSPORUS +int stub_init(struct net_device *dev, int phy_addr) +{ + //printk("PHY stub_init\n"); + return 0; +} + +int stub_reset(struct net_device *dev, int phy_addr) +{ + //printk("PHY stub_reset\n"); + return 0; +} + +int +stub_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) +{ + //printk("PHY stub_status\n"); + *link = 1; + /* hmmm, revisit */ + *speed = IF_PORT_100BASEFX; + dev->if_port = IF_PORT_100BASEFX; + return 0; +} +#endif + struct phy_ops bcm_5201_ops = { bcm_5201_init, bcm_5201_reset, bcm_5201_status, }; +struct phy_ops am79c874_ops = { + am79c874_init, + am79c874_reset, + am79c874_status, +}; + struct phy_ops am79c901_ops = { am79c901_init, am79c901_reset, @@ -360,26 +640,82 @@ lsi_80227_status, }; +struct phy_ops lxt971a_ops = { + lxt971a_init, + lxt971a_reset, + lxt971a_status, +}; + +struct phy_ops ks8995m_ops = { + ks8995m_init, + ks8995m_reset, + ks8995m_status, +}; + +#ifdef CONFIG_MIPS_BOSPORUS +struct phy_ops stub_ops = { + stub_init, + stub_reset, + stub_status, +}; +#endif + static struct mii_chip_info { const char * name; u16 phy_id0; u16 phy_id1; struct phy_ops *phy_ops; + int dual_phy; } mii_chip_table[] = { - {"Broadcom BCM5201 10/100 BaseT PHY", 0x0040, 0x6212, &bcm_5201_ops }, - {"AMD 79C901 HomePNA PHY", 0x0000, 0x35c8, &am79c901_ops }, - {"LSI 80227 10/100 BaseT PHY", 0x0016, 0xf840, &lsi_80227_ops }, - {"Broadcom BCM5221 10/100 BaseT PHY", 0x0040, 0x61e4, &bcm_5201_ops }, + {"Broadcom BCM5201 10/100 BaseT PHY",0x0040,0x6212, &bcm_5201_ops,0}, + {"Broadcom BCM5221 10/100 BaseT PHY",0x0040,0x61e4, &bcm_5201_ops,0}, + {"Broadcom BCM5222 10/100 BaseT PHY",0x0040,0x6322, &bcm_5201_ops,1}, + {"AMD 79C901 HomePNA PHY",0x0000,0x35c8, &am79c901_ops,0}, + {"AMD 79C874 10/100 BaseT PHY",0x0022,0x561b, &am79c874_ops,0}, + {"LSI 80227 10/100 BaseT PHY",0x0016,0xf840, &lsi_80227_ops,0}, + {"Intel LXT971A Dual Speed PHY",0x0013,0x78e2, &lxt971a_ops,0}, + {"Kendin KS8995M 10/100 BaseT PHY",0x0022,0x1450, &ks8995m_ops,0}, +#ifdef CONFIG_MIPS_BOSPORUS + {"Stub", 0x1234, 0x5678, &stub_ops }, +#endif {0,}, }; static int mdio_read(struct net_device *dev, int phy_id, int reg) { struct au1000_private *aup = (struct au1000_private *) dev->priv; + volatile u32 *mii_control_reg; + volatile u32 *mii_data_reg; u32 timedout = 20; u32 mii_control; - while (aup->mac->mii_control & MAC_MII_BUSY) { + #ifdef CONFIG_BCM5222_DUAL_PHY + /* First time we probe, it's for the mac0 phy. + * Since we haven't determined yet that we have a dual phy, + * aup->mii->mii_control_reg won't be setup and we'll + * default to the else statement. + * By the time we probe for the mac1 phy, the mii_control_reg + * will be setup to be the address of the mac0 phy control since + * both phys are controlled through mac0. + */ + if (aup->mii && aup->mii->mii_control_reg) { + mii_control_reg = aup->mii->mii_control_reg; + mii_data_reg = aup->mii->mii_data_reg; + } + else if (au_macs[0]->mii && au_macs[0]->mii->mii_control_reg) { + /* assume both phys are controlled through mac0 */ + mii_control_reg = au_macs[0]->mii->mii_control_reg; + mii_data_reg = au_macs[0]->mii->mii_data_reg; + } + else + #endif + { + /* default control and data reg addresses */ + mii_control_reg = &aup->mac->mii_control; + mii_data_reg = &aup->mac->mii_data; + } + + while (*mii_control_reg & MAC_MII_BUSY) { mdelay(1); if (--timedout == 0) { printk(KERN_ERR "%s: read_MII busy timeout!!\n", @@ -391,10 +727,10 @@ mii_control = MAC_SET_MII_SELECT_REG(reg) | MAC_SET_MII_SELECT_PHY(phy_id) | MAC_MII_READ; - aup->mac->mii_control = mii_control; + *mii_control_reg = mii_control; timedout = 20; - while (aup->mac->mii_control & MAC_MII_BUSY) { + while (*mii_control_reg & MAC_MII_BUSY) { mdelay(1); if (--timedout == 0) { printk(KERN_ERR "%s: mdio_read busy timeout!!\n", @@ -402,16 +738,36 @@ return -1; } } - return (int)aup->mac->mii_data; + return (int)*mii_data_reg; } static void mdio_write(struct net_device *dev, int phy_id, int reg, u16 value) { struct au1000_private *aup = (struct au1000_private *) dev->priv; + volatile u32 *mii_control_reg; + volatile u32 *mii_data_reg; u32 timedout = 20; u32 mii_control; - while (aup->mac->mii_control & MAC_MII_BUSY) { + #ifdef CONFIG_BCM5222_DUAL_PHY + if (aup->mii && aup->mii->mii_control_reg) { + mii_control_reg = aup->mii->mii_control_reg; + mii_data_reg = aup->mii->mii_data_reg; + } + else if (au_macs[0]->mii && au_macs[0]->mii->mii_control_reg) { + /* assume both phys are controlled through mac0 */ + mii_control_reg = au_macs[0]->mii->mii_control_reg; + mii_data_reg = au_macs[0]->mii->mii_data_reg; + } + else + #endif + { + /* default control and data reg addresses */ + mii_control_reg = &aup->mac->mii_control; + mii_data_reg = &aup->mac->mii_data; + } + + while (*mii_control_reg & MAC_MII_BUSY) { mdelay(1); if (--timedout == 0) { printk(KERN_ERR "%s: mdio_write busy timeout!!\n", @@ -423,8 +779,8 @@ mii_control = MAC_SET_MII_SELECT_REG(reg) | MAC_SET_MII_SELECT_PHY(phy_id) | MAC_MII_WRITE; - aup->mac->mii_data = value; - aup->mac->mii_control = mii_control; + *mii_data_reg = value; + *mii_control_reg = mii_control; } @@ -442,12 +798,13 @@ } } -static int __init mii_probe (struct net_device * dev) +static int mii_probe (struct net_device * dev) { struct au1000_private *aup = (struct au1000_private *) dev->priv; int phy_addr; - - aup->mii = NULL; +#ifdef CONFIG_MIPS_BOSPORUS + int phy_found=0; +#endif /* search for total of 32 possible mii phy addresses */ for (phy_addr = 0; phy_addr < 32; phy_addr++) { @@ -455,6 +812,14 @@ u16 phy_id0, phy_id1; int i; + #ifdef CONFIG_BCM5222_DUAL_PHY + /* Mask the already found phy, try next one */ + if (au_macs[0]->mii && au_macs[0]->mii->mii_control_reg) { + if (au_macs[0]->phy_addr == phy_addr) + continue; + } + #endif + mii_status = mdio_read(dev, phy_addr, MII_STATUS); if (mii_status == 0xffff || mii_status == 0x0000) /* the mii is not accessable, try next one */ @@ -467,6 +832,65 @@ for (i = 0; mii_chip_table[i].phy_id1; i++) { if (phy_id0 == mii_chip_table[i].phy_id0 && phy_id1 == mii_chip_table[i].phy_id1) { + struct mii_phy * mii_phy = aup->mii; + + printk(KERN_INFO "%s: %s at phy address %d\n", + dev->name, mii_chip_table[i].name, + phy_addr); +#ifdef CONFIG_MIPS_BOSPORUS + phy_found = 1; +#endif + mii_phy->chip_info = mii_chip_table+i; + aup->phy_addr = phy_addr; + aup->phy_ops = mii_chip_table[i].phy_ops; + aup->phy_ops->phy_init(dev,phy_addr); + + // Check for dual-phy and then store required + // values and set indicators. We need to do + // this now since mdio_{read,write} need the + // control and data register addresses. + #ifdef CONFIG_BCM5222_DUAL_PHY + if ( mii_chip_table[i].dual_phy) { + + /* assume both phys are controlled + * through MAC0. Board specific? */ + + /* sanity check */ + if (!au_macs[0] || !au_macs[0]->mii) + return -1; + aup->mii->mii_control_reg = (u32 *) + &au_macs[0]->mac->mii_control; + aup->mii->mii_data_reg = (u32 *) + &au_macs[0]->mac->mii_data; + } + #endif + goto found; + } + } + } +found: + +#ifdef CONFIG_MIPS_BOSPORUS + /* This is a workaround for the Micrel/Kendin 5 port switch + The second MAC doesn't see a PHY connected... so we need to + trick it into thinking we have one. + + If this kernel is run on another Au1500 development board + the stub will be found as well as the actual PHY. However, + the last found PHY will be used... usually at Addr 31 (Db1500). + */ + if ( (!phy_found) ) + { + u16 phy_id0, phy_id1; + int i; + + phy_id0 = 0x1234; + phy_id1 = 0x5678; + + /* search our mii table for the current mii */ + for (i = 0; mii_chip_table[i].phy_id1; i++) { + if (phy_id0 == mii_chip_table[i].phy_id0 && + phy_id1 == mii_chip_table[i].phy_id1) { struct mii_phy * mii_phy; printk(KERN_INFO "%s: %s at phy address %d\n", @@ -476,31 +900,39 @@ GFP_KERNEL); if (mii_phy) { mii_phy->chip_info = mii_chip_table+i; - mii_phy->phy_addr = phy_addr; + aup->phy_addr = phy_addr; mii_phy->next = aup->mii; aup->phy_ops = mii_chip_table[i].phy_ops; aup->mii = mii_phy; aup->phy_ops->phy_init(dev,phy_addr); } else { - printk(KERN_ERR "%s: out of memory\n", + printk(KERN_ERR "%s: out of memory\n", dev->name); return -1; } - /* the current mii is on our mii_info_table, - try next address */ + mii_phy->chip_info = mii_chip_table+i; + aup->phy_addr = phy_addr; + aup->phy_ops = mii_chip_table[i].phy_ops; + aup->phy_ops->phy_init(dev,phy_addr); break; } } } + if (aup->mac_id == 0) { + /* the Bosporus phy responds to addresses 0-5 but + * 5 is the correct one. + */ + aup->phy_addr = 5; + } +#endif if (aup->mii == NULL) { - printk(KERN_ERR "%s: No MII transceivers found!\n", dev->name); + printk(KERN_ERR "%s: Au1x No MII transceivers found!\n", + dev->name); return -1; } - /* use last PHY */ - aup->phy_addr = aup->mii->phy_addr; printk(KERN_INFO "%s: Using %s as default\n", dev->name, aup->mii->chip_info->name); @@ -521,7 +953,6 @@ if (pDB) { aup->pDBfree = pDB->pnext; } - //printk("GetFreeDB: %x\n", pDB); return pDB; } @@ -587,6 +1018,7 @@ static void reset_mac(struct net_device *dev) { + int i; u32 flags; struct au1000_private *aup = (struct au1000_private *) dev->priv; @@ -597,11 +1029,27 @@ spin_lock_irqsave(&aup->lock, flags); del_timer(&aup->timer); hard_stop(dev); - *aup->enable = MAC_EN_CLOCK_ENABLE; - au_sync_delay(2); - *aup->enable = 0; - au_sync_delay(2); + #ifdef CONFIG_BCM5222_DUAL_PHY + if (aup->mac_id != 0) { + #endif + /* If BCM5222, we can't leave MAC0 in reset because then + * we can't access the dual phy for ETH1 */ + *aup->enable = MAC_EN_CLOCK_ENABLE; + au_sync_delay(2); + *aup->enable = 0; + au_sync_delay(2); + #ifdef CONFIG_BCM5222_DUAL_PHY + } + #endif aup->tx_full = 0; + for (i = 0; i < NUM_RX_DMA; i++) { + /* reset control bits */ + aup->rx_dma_ring[i]->buff_stat &= ~0xf; + } + for (i = 0; i < NUM_TX_DMA; i++) { + /* reset control bits */ + aup->tx_dma_ring[i]->buff_stat &= ~0xf; + } spin_unlock_irqrestore(&aup->lock, flags); } @@ -616,95 +1064,110 @@ { int i; - for (i=0; irx_dma_ring[i] = (volatile rx_dma_t *) (rx_base + sizeof(rx_dma_t)*i); } - for (i=0; itx_dma_ring[i] = (volatile tx_dma_t *) (tx_base + sizeof(tx_dma_t)*i); } } +static struct { + int port; + u32 base_addr; + int irq; + struct net_device *dev; +} iflist[2]; + +static int num_ifs; + +/* + * Setup the base address and interupt of the Au1xxx ethernet macs + * based on cpu type and whether the interface is enabled in sys_pinfunc + * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0. + */ static int __init au1000_init_module(void) { - int i; - int prid; - int base_addr, irq; - - prid = read_32bit_cp0_register(CP0_PRID); - for (i=0; i> 4); + struct net_device *dev; + int i, found_one = 0; + + iflist[0].irq = AU1000_ETH0_IRQ; + iflist[1].irq = AU1000_ETH1_IRQ; + switch (c->cputype) { + case CPU_AU1000: + num_ifs = 2 - ni; + iflist[0].base_addr = AU1000_ETH0_BASE; + iflist[1].base_addr = AU1000_ETH1_BASE; + break; + case CPU_AU1100: + num_ifs = 1 - ni; + iflist[0].base_addr = AU1000_ETH0_BASE; + break; + case CPU_AU1500: + num_ifs = 2 - ni; + iflist[0].base_addr = AU1500_ETH0_BASE; + iflist[1].base_addr = AU1500_ETH1_BASE; + break; + default: + num_ifs = 0; } + for(i = 0; i < num_ifs; i++) { + dev = au1000_probe(iflist[i].base_addr, iflist[i].irq, i); + iflist[i].dev = dev; + if (dev) + found_one++; } + if (!found_one) + return -ENODEV; return 0; } -static int __init -au1000_probe1(struct net_device *dev, long ioaddr, int irq, int port_num) +static struct net_device * +au1000_probe(u32 ioaddr, int irq, int port_num) { static unsigned version_printed = 0; struct au1000_private *aup = NULL; - int i, retval = 0; + struct net_device *dev = NULL; db_dest_t *pDB, *pDBfree; char *pmac, *argptr; char ethaddr[6]; + int i, err; - if (!request_region(ioaddr, MAC_IOSIZE, "Au1000 ENET")) { - return -ENODEV; - } + if (!request_region(ioaddr, MAC_IOSIZE, "Au1x00 ENET")) + return NULL; - if (version_printed++ == 0) printk(version); + if (version_printed++ == 0) + printk(version); + dev = alloc_etherdev(sizeof(struct au1000_private)); if (!dev) { - dev = init_etherdev(0, sizeof(struct au1000_private)); + printk (KERN_ERR "au1000 eth: alloc_etherdev failed\n"); + return NULL; } - if (!dev) { - printk (KERN_ERR "au1000 eth: init_etherdev failed\n"); - return -ENODEV; + + if ((err = register_netdev(dev))) { + printk(KERN_ERR "Au1x_eth Cannot register net device err %d\n", + err); + kfree(dev); + return NULL; } - printk("%s: Au1xxx ethernet found at 0x%lx, irq %d\n", + printk("%s: Au1x Ethernet found at 0x%x, irq %d\n", dev->name, ioaddr, irq); - /* Initialize our private structure */ - if (dev->priv == NULL) { - aup = (struct au1000_private *) - kmalloc(sizeof(*aup), GFP_KERNEL); - if (aup == NULL) { - retval = -ENOMEM; - goto free_region; - } - dev->priv = aup; - } - aup = dev->priv; - memset(aup, 0, sizeof(*aup)); - /* Allocate the data buffers */ aup->vaddr = (u32)dma_alloc(MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS), &aup->dma_addr); if (!aup->vaddr) { - retval = -ENOMEM; - goto free_region; + kfree(dev); + release_region(ioaddr, MAC_IOSIZE); + return NULL; } /* aup->mac is the base address of the MAC's registers */ @@ -737,7 +1200,10 @@ ((unsigned long)AU1500_MAC0_ENABLE); memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr)); setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR); + aup->mac_id = 0; + au_macs[0] = aup; break; + case AU1000_ETH1_BASE: case AU1500_ETH1_BASE: if (ioaddr == AU1000_ETH1_BASE) @@ -749,15 +1215,16 @@ memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr)); dev->dev_addr[4] += 0x10; setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR); + aup->mac_id = 1; + au_macs[1] = aup; break; + default: printk(KERN_ERR "%s: bad ioaddr\n", dev->name); break; } - aup->phy_addr = PHY_ADDRESS; - /* bring the device out of reset, otherwise probing the mii * will hang */ *aup->enable = MAC_EN_CLOCK_ENABLE; @@ -766,14 +1233,22 @@ MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE; au_sync_delay(2); + aup->mii = kmalloc(sizeof(struct mii_phy), GFP_KERNEL); + if (!aup->mii) { + printk(KERN_ERR "%s: out of memory\n", dev->name); + goto err_out; + } + aup->mii->mii_control_reg = 0; + aup->mii->mii_data_reg = 0; + if (mii_probe(dev) != 0) { - goto free_region; + goto err_out; } pDBfree = NULL; /* setup the data buffer descriptors and attach a buffer to each one */ pDB = aup->db; - for (i=0; i<(NUM_TX_BUFFS+NUM_RX_BUFFS); i++) { + for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) { pDB->pnext = pDBfree; pDBfree = pDB; pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i); @@ -782,15 +1257,19 @@ } aup->pDBfree = pDBfree; - for (i=0; irx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr; aup->rx_db_inuse[i] = pDB; } - for (i=0; itx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr; aup->tx_dma_ring[i]->len = 0; aup->tx_db_inuse[i] = pDB; @@ -809,32 +1288,36 @@ dev->tx_timeout = au1000_tx_timeout; dev->watchdog_timeo = ETH_TX_TIMEOUT; - - /* Fill in the fields of the device structure with ethernet values. */ - ether_setup(dev); - /* * The boot code uses the ethernet controller, so reset it to start * fresh. au1000_init() expects that the device is in reset state. */ reset_mac(dev); - return 0; -free_region: - release_region(ioaddr, MAC_IOSIZE); + return dev; + +err_out: + /* here we should have a valid dev plus aup-> register addresses + * so we can reset the mac properly.*/ + reset_mac(dev); + if (aup->mii) + kfree(aup->mii); + for (i = 0; i < NUM_RX_DMA; i++) { + if (aup->rx_db_inuse[i]) + ReleaseDB(aup, aup->rx_db_inuse[i]); + } + for (i = 0; i < NUM_TX_DMA; i++) { + if (aup->tx_db_inuse[i]) + ReleaseDB(aup, aup->tx_db_inuse[i]); + } + dma_free((void *)aup->vaddr, MAX_BUF_SIZE * + (NUM_TX_BUFFS+NUM_RX_BUFFS)); unregister_netdev(dev); - if (aup->vaddr) - dma_free((void *)aup->vaddr, - MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS)); - if (dev->priv != NULL) - kfree(dev->priv); - printk(KERN_ERR "%s: au1000_probe1 failed. Returns %d\n", - dev->name, retval); kfree(dev); - return retval; + release_region(ioaddr, MAC_IOSIZE); + return NULL; } - /* * Initialize the interface. * @@ -852,7 +1335,8 @@ u32 control; u16 link, speed; - if (au1000_debug > 4) printk("%s: au1000_init\n", dev->name); + if (au1000_debug > 4) + printk("%s: au1000_init\n", dev->name); spin_lock_irqsave(&aup->lock, flags); @@ -872,7 +1356,7 @@ aup->mac->mac_addr_low = dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 | dev->dev_addr[1]<<8 | dev->dev_addr[0]; - for (i=0; irx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE; } au_sync(); @@ -992,24 +1476,48 @@ if (au1000_debug > 4) printk("%s: close: dev=%p\n", dev->name, dev); + reset_mac(dev); + spin_lock_irqsave(&aup->lock, flags); /* stop the device */ - if (netif_device_present(dev)) { - netif_stop_queue(dev); - } + netif_stop_queue(dev); /* disable the interrupt */ free_irq(dev->irq, dev); spin_unlock_irqrestore(&aup->lock, flags); - reset_mac(dev); MOD_DEC_USE_COUNT; return 0; } static void __exit au1000_cleanup_module(void) { + int i, j; + struct net_device *dev; + struct au1000_private *aup; + + for (i = 0; i < num_ifs; i++) { + dev = iflist[i].dev; + if (dev) { + aup = (struct au1000_private *) dev->priv; + unregister_netdev(dev); + if (aup->mii) + kfree(aup->mii); + for (j = 0; j < NUM_RX_DMA; j++) { + if (aup->rx_db_inuse[j]) + ReleaseDB(aup, aup->rx_db_inuse[j]); + } + for (j = 0; j < NUM_TX_DMA; j++) { + if (aup->tx_db_inuse[j]) + ReleaseDB(aup, aup->tx_db_inuse[j]); + } + dma_free((void *)aup->vaddr, MAX_BUF_SIZE * + (NUM_TX_BUFFS+NUM_RX_BUFFS)); + kfree(dev); + release_region(iflist[i].base_addr, MAC_IOSIZE); + } + } } @@ -1081,7 +1589,7 @@ db_dest_t *pDB; int i; - if (au1000_debug > 4) + if (au1000_debug > 5) printk("%s: tx: aup %x len=%d, data=%p, head %d\n", dev->name, (unsigned)aup, skb->len, skb->data, aup->tx_head); @@ -1106,11 +1614,11 @@ pDB = aup->tx_db_inuse[aup->tx_head]; memcpy((void *)pDB->vaddr, skb->data, skb->len); - if (skb->len < MAC_MIN_PKT_SIZE) { - for (i=skb->len; ilen < ETH_ZLEN) { + for (i=skb->len; ivaddr)[i] = 0; } - ptxd->len = MAC_MIN_PKT_SIZE; + ptxd->len = ETH_ZLEN; } else ptxd->len = skb->len; @@ -1159,8 +1667,9 @@ volatile rx_dma_t *prxd; u32 buff_stat, status; db_dest_t *pDB; + u32 frmlen; - if (au1000_debug > 4) + if (au1000_debug > 5) printk("%s: au1000_rx head %d\n", dev->name, aup->rx_head); prxd = aup->rx_dma_ring[aup->rx_head]; @@ -1172,7 +1681,9 @@ if (!(status & RX_ERROR)) { /* good frame */ - skb = dev_alloc_skb((status & RX_FRAME_LEN_MASK) + 2); + frmlen = (status & RX_FRAME_LEN_MASK); + frmlen -= 4; /* Remove FCS */ + skb = dev_alloc_skb(frmlen + 2); if (skb == NULL) { printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", @@ -1182,9 +1693,9 @@ } skb->dev = dev; skb_reserve(skb, 2); /* 16 byte IP header align */ - eth_copy_and_sum(skb, (unsigned char *)pDB->vaddr, - status & RX_FRAME_LEN_MASK, 0); - skb_put(skb, status & RX_FRAME_LEN_MASK); + eth_copy_and_sum(skb, + (unsigned char *)pDB->vaddr, frmlen, 0); + skb_put(skb, frmlen); skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); /* pass the packet to upper layers */ } @@ -1236,8 +1747,11 @@ printk(KERN_ERR "%s: isr: null dev ptr\n", dev->name); return; } - au1000_tx_ack(dev); + + /* Handle RX interrupts first to minimize chance of overrun */ + au1000_rx(dev); + au1000_tx_ack(dev); } @@ -1250,6 +1764,8 @@ printk(KERN_ERR "%s: au1000_tx_timeout: dev=%p\n", dev->name, dev); reset_mac(dev); au1000_init(dev); + dev->trans_start = jiffies; + netif_wake_queue(dev); } @@ -1305,27 +1821,19 @@ static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - u16 *data = (u16 *)&rq->ifr_data; + //u16 *data = (u16 *)&rq->ifr_data; /* fixme */ - switch (cmd) { - case SIOCGMIIPHY: /* Get the address of the PHY in use. */ - case SIOCDEVPRIVATE: /* binary compat, remove in 2.5 */ - data[0] = PHY_ADDRESS; - - case SIOCGMIIREG: /* Read the specified MII register. */ - case SIOCDEVPRIVATE+1: /* binary compat, remove in 2.5 */ + switch(cmd) { + case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ + //data[0] = PHY_ADDRESS; + case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ //data[3] = mdio_read(ioaddr, data[0], data[1]); return 0; - - case SIOCSMIIREG: /* Write the specified MII register */ - case SIOCDEVPRIVATE+2: /* binary compat, remove in 2.5 */ - if (!capable(CAP_NET_ADMIN)) - return -EPERM; + case SIOCDEVPRIVATE+2: /* Write the specified MII register */ //mdio_write(ioaddr, data[0], data[1], data[2]); return 0; - - default: + default: return -EOPNOTSUPP; } } @@ -1389,7 +1897,6 @@ /* set Speed to 100Mbps, Half Duplex */ /* disable auto negotiation and enable 100MBit Mode */ control = mdio_read(dev, aup->phy_addr, MII_CONTROL); - printk("read control %x\n", control); control &= ~(MII_CNTL_AUTO | MII_CNTL_FDX); control |= MII_CNTL_F100; mdio_write(dev, aup->phy_addr, MII_CONTROL, control); Index: drivers/net/au1000_eth.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/au1000_eth.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/au1000_eth.h 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/au1000_eth.h 4 Aug 2004 01:29:08 -0000 1.2 @@ -1,10 +1,13 @@ /* - * Alchemy Semi Au1000 ethernet driver include file + * + * Alchemy Au1x00 ethernet driver include file * * Author: Pete Popov * * Copyright 2001 MontaVista Software Inc. * + * ######################################################################## + * * 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,14 +20,16 @@ * You should have received a copy of the GNU General Public 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 -#define NUM_INTERFACES 2 #define MAC_IOSIZE 0x10000 -#define NUM_RX_DMA 4 /* Au1000 has 4 rx hardware descriptors */ -#define NUM_TX_DMA 4 /* Au1000 has 4 tx hardware descriptors */ +#define NUM_RX_DMA 4 /* Au1x00 has 4 rx hardware descriptors */ +#define NUM_TX_DMA 4 /* Au1x00 has 4 tx hardware descriptors */ #define NUM_RX_BUFFS 4 #define NUM_TX_BUFFS 4 @@ -33,12 +38,6 @@ #define ETH_TX_TIMEOUT HZ/4 #define MAC_MIN_PKT_SIZE 64 -#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100) -#define PHY_ADDRESS 0 -#define PHY_CONTROL_DEFAULT 0x3000 -#define PHY_CONTROL_REG_ADDR 0 -#endif - #define MULTICAST_FILTER_LIMIT 64 /* FIXME @@ -54,11 +53,13 @@ #define MII_ANLPAR 0x0005 #define MII_AEXP 0x0006 #define MII_ANEXT 0x0007 -#define MII_LSI_CONFIG 0x0011 -#define MII_LSI_STAT 0x0012 -#define MII_AUX_CNTRL 0x0018 -#define MII_INT 0x001A +#define MII_LSI_PHY_CONFIG 0x0011 +/* Status register */ +#define MII_LSI_PHY_STAT 0x0012 +#define MII_AMD_PHY_STAT MII_LSI_PHY_STAT +#define MII_INTEL_PHY_STAT 0x0011 +#define MII_AUX_CNTRL 0x0018 /* mii registers specific to AMD 79C901 */ #define MII_STATUS_SUMMARY = 0x0018 @@ -121,23 +122,30 @@ #define MII_STSSUM_AUTO 0x0002 #define MII_STSSUM_SPD 0x0001 -/* lsi status register */ - -#define MII_LSI_STAT_FDX 0x0040 -#define MII_LSI_STAT_SPD 0x0080 +/* lsi phy status register */ +#define MII_LSI_PHY_STAT_FDX 0x0040 +#define MII_LSI_PHY_STAT_SPD 0x0080 + +/* amd phy status register */ +#define MII_AMD_PHY_STAT_FDX 0x0800 +#define MII_AMD_PHY_STAT_SPD 0x0400 + +/* intel phy status register */ +#define MII_INTEL_PHY_STAT_FDX 0x0200 +#define MII_INTEL_PHY_STAT_SPD 0x4000 /* Auxilliary Control/Status Register */ #define MII_AUX_FDX 0x0001 #define MII_AUX_100 0x0002 #define MII_AUX_F100 0x0004 #define MII_AUX_ANEG 0x0008 -#define MII_FDX_LED 0x8000 typedef struct mii_phy { struct mii_phy * next; struct mii_chip_info * chip_info; - int phy_addr; u16 status; + u32 *mii_control_reg; + u32 *mii_data_reg; } mii_phy_t; struct phy_ops { @@ -204,6 +212,7 @@ u32 tx_tail; u32 tx_full; + int mac_id; mii_phy_t *mii; struct phy_ops *phy_ops; @@ -217,7 +226,7 @@ u8 *hash_table; u32 hash_mode; u32 intr_work_done; /* number of Rx and Tx pkts processed in the isr */ - u32 phy_addr; /* PHY address */ + int phy_addr; /* phy address */ u32 options; /* User-settable misc. driver options. */ u32 drv_flags; struct net_device_stats stats; Index: drivers/net/bagetlance.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/bagetlance.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/bagetlance.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/bagetlance.c 4 Aug 2004 01:29:08 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: bagetlance.c,v 1.1 2004/07/22 19:49:34 joff Exp $ +/* $Id: bagetlance.c,v 1.2 2004/08/04 01:29:08 joff Exp $ * bagetlance.c: Ethernet driver for VME Lance cards on Baget/MIPS * This code stealed and adopted from linux/drivers/net/atarilance.c * See that for author info Index: drivers/net/bmac.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/bmac.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/bmac.c 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/bmac.c 4 Aug 2004 01:29:08 -0000 1.2 @@ -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; Index: drivers/net/bonding.c =================================================================== RCS file: drivers/net/bonding.c diff -N drivers/net/bonding.c --- drivers/net/bonding.c 22 Jul 2004 19:49:33 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: - */ Index: drivers/net/cirrus.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/cirrus.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/cirrus.c 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/cirrus.c 4 Aug 2004 01:29:08 -0000 1.2 @@ -75,6 +75,7 @@ typedef struct { struct net_device_stats stats; u16 txlen; + u16 txafter; /* Default is After5 (0) */ } cirrus_t; typedef struct { @@ -230,13 +231,19 @@ cirrus_t *priv = (cirrus_t *) dev->priv; u16 status; + /* Tx start must be done with irq disabled + * else status can be wrong */ + disable_irq (dev->irq); + netif_stop_queue (dev); - cirrus_write (dev,PP_TxCMD,TxStart (After5)); + cirrus_write (dev,PP_TxCMD,TxStart (priv->txafter)); cirrus_write (dev,PP_TxLength,skb->len); status = cirrus_read (dev,PP_BusST); + enable_irq (dev->irq); + if ((status & TxBidErr)) { printk (KERN_WARNING "%s: Invalid frame size %d!\n",dev->name,skb->len); priv->stats.tx_errors++; @@ -249,7 +256,6 @@ printk (KERN_WARNING "%s: Transmit buffer not free!\n",dev->name); priv->stats.tx_errors++; priv->txlen = 0; - /* FIXME: store skb and send it in interrupt handler */ return (1); } @@ -310,11 +316,18 @@ } if ((RegContent (status) & TxUnderrun)) { priv->stats.tx_errors++; - priv->stats.tx_fifo_errors++; + /* Shift start tx, if underruns come too often */ + switch (priv->stats.tx_fifo_errors++) { + case 3: priv->txafter = After381; break; + case 6: priv->txafter = After1021; break; + case 9: priv->txafter = AfterAll; break; + } + } + /* Wakeup only for tx events ! */ + if ((RegContent (status) & (TxUnderrun | Rdy4Tx))) { + priv->txlen = 0; + netif_wake_queue (dev); } - /* FIXME: if Rdy4Tx, transmit last sent packet (if any) */ - priv->txlen = 0; - netif_wake_queue (dev); break; case TxCOL: Index: drivers/net/cs89x0.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/cs89x0.c,v retrieving revision 1.1 retrieving revision 1.7 diff -u -r1.1 -r1.7 --- drivers/net/cs89x0.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/cs89x0.c 2 May 2007 22:52:00 -0000 1.7 @@ -98,13 +98,17 @@ * Note that even if DMA is turned off we still support the 'dma' and 'use_dma' * module options so we don't break any startup scripts. */ +#ifdef CONFIG_ARCH_EP9301 +#define ALLOW_DMA 0 +#else #define ALLOW_DMA 1 +#endif /* * Set this to zero to remove all the debug statements via * dead code elimination */ -#define DEBUGGING 1 +#define DEBUGGING 0 /* Sources: @@ -145,6 +149,18 @@ static char version[] __initdata = "cs89x0.c: v2.4.3-pre1 Russell Nelson , Andrew Morton \n"; +/* Globals */ +static unsigned int io; +static int irq; +static int debug; +static char media[8]; +static int duplex=-1; + +static int use_dma; /* These generate unused var warnings if ALLOW_DMA = 0 */ +static int dma; +static int dmasize=16; /* or 64 */ + + /* First, a few definitions that the brave might change. A zero-terminated list of I/O addresses to be probed. Some special flags.. Addr & 1 = Read back the address port, look for signature and reset @@ -164,6 +180,10 @@ static unsigned int netcard_portlist[] __initdata = { 0x0300, 0}; static unsigned int cs8900_irq_map[] = {1,0,0,0}; +#elif defined(CONFIG_ARCH_EP9301) +static unsigned int netcard_portlist[] __initdata = + { 0x8dc00300, 0x8dc00310, 0x8dc00320, 0x8dc00330, 0}; +static unsigned int cs8900_irq_map[] = {0,0,0,33}; #else static unsigned int netcard_portlist[] __initdata = { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0}; @@ -218,7 +238,7 @@ extern int cs89x0_probe(struct net_device *dev); -static int cs89x0_probe1(struct net_device *dev, int ioaddr); +static int cs89x0_probe1(struct net_device *dev, unsigned int ioaddr); static int net_open(struct net_device *dev); static int net_send_packet(struct sk_buff *skb, struct net_device *dev); static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs); @@ -281,7 +301,7 @@ int __init cs89x0_probe(struct net_device *dev) { int i; - int base_addr = dev ? dev->base_addr : 0; + unsigned int base_addr = dev ? dev->base_addr : 0; SET_MODULE_OWNER(dev); @@ -297,7 +317,6 @@ if (cs89x0_probe1(dev, netcard_portlist[i]) == 0) return 0; } - printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected. Be sure to disable PnP with SETUP\n"); return -ENODEV; } @@ -379,7 +398,7 @@ */ static int __init -cs89x0_probe1(struct net_device *dev, int ioaddr) +cs89x0_probe1(struct net_device *dev, unsigned int ioaddr) { struct net_local *lp; static unsigned version_printed; @@ -413,8 +432,6 @@ /* Grab the region so we can find another board if autoIRQ fails. */ if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, dev->name)) { - printk(KERN_ERR "%s: request_region(0x%x, 0x%x) failed\n", - dev->name, ioaddr, NETCARD_IO_EXTENT); retval = -EBUSY; goto out1; } @@ -442,11 +459,8 @@ ioaddr &= ~3; outw(PP_ChipID, ioaddr + ADD_PORT); } -printk("PP_addr=0x%x\n", inw(ioaddr + ADD_PORT)); if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG) { - printk(KERN_ERR "%s: incorrect signature 0x%x\n", - dev->name, inw(ioaddr + DATA_PORT)); retval = -ENODEV; goto out2; } @@ -650,6 +664,22 @@ } else { i = lp->isa_config & INT_NO_MASK; if (lp->chip_type == CS8900) { +#ifdef CONFIG_ARCH_EP9301 + switch(ioaddr & 0xfff) { + case 0x300: + i = 33; + break; + case 0x310: + i = 34; + break; + case 0x320: + i = 33; + break; + case 0x330: + i = 34; + break; + } +#else /* Translate the IRQ using the IRQ mapping table. */ if (i >= sizeof(cs8900_irq_map)/sizeof(cs8900_irq_map[0])) printk("\ncs89x0: invalid ISA interrupt number %d\n", i); @@ -657,6 +687,7 @@ i = cs8900_irq_map[i]; lp->irq_map = CS8900_IRQ_MAP; /* fixed IRQ map for CS8900 */ +#endif } else { int irq_map_buff[IRQ_MAP_LEN/2]; @@ -1146,12 +1177,15 @@ else #endif { + +#ifndef CONFIG_ARCH_EP9301 // need > 32 bits for ARM since IRQ # are > 32, scrap this check... if (((1 << dev->irq) & lp->irq_map) == 0) { printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n", dev->name, dev->irq, lp->irq_map); ret = -EAGAIN; goto bad_out; } +#endif /* FIXME: Cirrus' release had this: */ writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ ); /* And 2.3.47 had this: */ @@ -1159,7 +1193,7 @@ writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON); #endif write_irq(dev, lp->chip_type, dev->irq); - ret = request_irq(dev->irq, &net_interrupt, 0, dev->name, dev); + ret = request_irq(dev->irq, &net_interrupt, SA_SHIRQ, dev->name, dev); if (ret) { if (net_debug) printk(KERN_DEBUG "cs89x0: request_irq(%d) failed\n", dev->irq); @@ -1249,6 +1283,7 @@ printk(KERN_WARNING "%s: 10Base-T (RJ-45) has no cable\n", dev->name); if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */ result = DETECTED_RJ45H; /* Yes! I don't care if I see a link pulse */ + } break; case A_CNF_MEDIA_AUI: @@ -1281,6 +1316,11 @@ printk(KERN_ERR "%s: no media detected\n", dev->name); goto release_irq; } + + //use full duplex if the user forces it. + if(duplex == 1) + result = DETECTED_RJ45F; + switch(result) { case DETECTED_NONE: printk(KERN_ERR "%s: no network cable attached to configured media\n", dev->name); @@ -1630,16 +1670,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 */ @@ -1662,15 +1707,6 @@ * avoid breaking someone's startup scripts */ -static int io; -static int irq; -static int debug; -static char media[8]; -static int duplex=-1; - -static int use_dma; /* These generate unused var warnings if ALLOW_DMA = 0 */ -static int dma; -static int dmasize=16; /* or 64 */ MODULE_PARM(io, "i"); MODULE_PARM(irq, "i"); @@ -1689,7 +1725,7 @@ #endif MODULE_PARM_DESC(media, "Set cs89x0 adapter(s) media type(s) (rj45,bnc,aui)"); /* No other value than -1 for duplex seems to be currently interpreted */ -MODULE_PARM_DESC(duplex, "(ignored)"); +MODULE_PARM_DESC(duplex, "full duplex = 1"); #if ALLOW_DMA MODULE_PARM_DESC(dma , "cs89x0 ISA DMA channel; ignored if use_dma=0"); MODULE_PARM_DESC(dmasize , "cs89x0 DMA size in kB (16,64); ignored if use_dma=0"); @@ -1744,6 +1780,16 @@ debug = 0; #endif +#ifdef CONFIG_ARCH_EP9301 + // Translate x86 ISA io addr to TS-7200 + if ((io & 0xffff0000) != 0x8dc00000 && io != 0) + io |= 0x8dc00000; + + // x86 IRQ --> ARM IRQ + if (irq == 6 || irq == 0) irq = 33; + if (irq == 7) irq = 40; +#endif + dev_cs89x0.irq = irq; dev_cs89x0.base_addr = io; @@ -1779,12 +1825,14 @@ if (duplex==-1) lp->auto_neg_cnf = AUTO_NEG_ENABLE; +#ifndef CONFIG_ARCH_EP9301 if (io == 0) { printk(KERN_ERR "cs89x0.c: Module autoprobing not allowed.\n"); printk(KERN_ERR "cs89x0.c: Append io=0xNNN\n"); ret = -EPERM; goto out; } +#endif #if ALLOW_DMA if (use_dma && dmasize != 16 && dmasize != 64) { Index: drivers/net/de4x5.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/de4x5.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/de4x5.c 22 Jul 2004 19:49:35 -0000 1.1 +++ drivers/net/de4x5.c 4 Aug 2004 01:29:08 -0000 1.2 @@ -999,7 +999,7 @@ static void srom_repair(struct net_device *dev, int card); static int test_bad_enet(struct net_device *dev, int status); static int an_exception(struct de4x5_bus_type *lp); -#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) +#ifdef CONFIG_EISA static void eisa_probe(struct net_device *dev, u_long iobase); #endif static void pci_probe(struct net_device *dev, u_long iobase); @@ -1053,7 +1053,7 @@ #endif /* MODULE */ static char name[DE4X5_NAME_LENGTH + 1]; -#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) +#ifdef CONFIG_EISA static u_char de4x5_irq[] = EISA_ALLOWED_IRQ_LIST; static int lastEISA; # ifdef DE4X5_FORCE_EISA /* Force an EISA bus probe or not */ @@ -1131,7 +1131,7 @@ u_long iobase = dev->base_addr; pci_probe(dev, iobase); -#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) +#ifdef CONFIG_EISA if ((lastPCI == NO_MORE_PCI) && ((num_de4x5s == 0) || forceEISA)) { eisa_probe(dev, iobase); } @@ -2093,7 +2093,7 @@ return; } -#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) +#ifdef CONFIG_EISA /* ** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually ** the motherboard. Upto 15 EISA devices are supported. @@ -5363,7 +5363,7 @@ t = *q; *q = '\0'; -#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) +#ifdef CONFIG_EISA if (strstr(p, "force_eisa") || strstr(p, "FORCE_EISA")) forceEISA = 1; #endif if (strstr(p, "fdx") || strstr(p, "FDX")) lp->params.fdx = 1; @@ -5865,7 +5865,7 @@ u_int class = DE4X5_CLASS_CODE; u_int device; -#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) +#ifdef CONFIG_EISA char name[DE4X5_STRLEN]; u_long iobase = 0x1000; Index: drivers/net/de600.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/de600.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/de600.c 22 Jul 2004 19:49:35 -0000 1.1 +++ drivers/net/de600.c 4 Aug 2004 01:29:08 -0000 1.2 @@ -1,5 +1,5 @@ static const char version[] = - "de600.c: $Revision: 1.1 $, Bjorn Ekwall (bj0rn@blox.se)\n"; + "de600.c: $Revision: 1.2 $, Bjorn Ekwall (bj0rn@blox.se)\n"; /* * de600.c * Index: drivers/net/de620.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/de620.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/de620.c 22 Jul 2004 19:49:35 -0000 1.1 +++ drivers/net/de620.c 4 Aug 2004 01:29:08 -0000 1.2 @@ -1,5 +1,5 @@ /* - * de620.c $Revision: 1.1 $ BETA + * de620.c $Revision: 1.2 $ BETA * * * Linux driver for the D-Link DE-620 Ethernet pocket adapter. @@ -39,7 +39,7 @@ * *****************************************************************************/ static const char version[] = - "de620.c: $Revision: 1.1 $, Bjorn Ekwall \n"; + "de620.c: $Revision: 1.2 $, Bjorn Ekwall \n"; /*********************************************************************** * Index: drivers/net/declance.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/declance.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/declance.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/declance.c 4 Aug 2004 01:29:08 -0000 1.2 @@ -5,7 +5,7 @@ * * adopted from sunlance.c by Richard van den Berg * - * Copyright (C) 2002 Maciej W. Rozycki + * Copyright (C) 2002, 2003 Maciej W. Rozycki * * additional sources: * - PMAD-AA TURBOchannel Ethernet Module Functional Specification, @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -271,7 +272,7 @@ lp->tx_old - lp->tx_new-1) /* The lance control ports are at an absolute address, machine and tc-slot - * dependant. + * dependent. * DECstations do only 32-bit access and the LANCE uses 16 bit addresses, * so we have to give the structure an extra member making rap pointing * at the right address @@ -783,19 +784,29 @@ /* Associate IRQ with lance_interrupt */ if (request_irq(dev->irq, &lance_interrupt, 0, "lance", dev)) { - printk("lance: Can't get IRQ %d\n", dev->irq); + printk("%s: Can't get IRQ %d\n", dev->name, dev->irq); return -EAGAIN; } if (lp->dma_irq >= 0) { + unsigned long flags; + if (request_irq(lp->dma_irq, &lance_dma_merr_int, 0, "lance error", dev)) { free_irq(dev->irq, dev); - printk("lance: Can't get DMA IRQ %d\n", lp->dma_irq); + printk("%s: Can't get DMA IRQ %d\n", dev->name, + lp->dma_irq); return -EAGAIN; } + + spin_lock_irqsave(&ioasic_ssr_lock, flags); + + fast_mb(); /* Enable I/O ASIC LANCE DMA. */ - fast_wmb(); - ioasic_write(SSR, ioasic_read(SSR) | LANCE_DMA_EN); + ioasic_write(IO_REG_SSR, + ioasic_read(IO_REG_SSR) | IO_SSR_LANCE_DMA_EN); + + fast_mb(); + spin_unlock_irqrestore(&ioasic_ssr_lock, flags); } status = init_restart_lance(lp); @@ -821,9 +832,18 @@ writereg(&ll->rdp, LE_C0_STOP); if (lp->dma_irq >= 0) { + unsigned long flags; + + spin_lock_irqsave(&ioasic_ssr_lock, flags); + + fast_mb(); /* Disable I/O ASIC LANCE DMA. */ - ioasic_write(SSR, ioasic_read(SSR) & ~LANCE_DMA_EN); + ioasic_write(IO_REG_SSR, + ioasic_read(IO_REG_SSR) & ~IO_SSR_LANCE_DMA_EN); + fast_iob(); + spin_unlock_irqrestore(&ioasic_ssr_lock, flags); + free_irq(lp->dma_irq, dev); } free_irq(dev->irq, dev); @@ -856,8 +876,8 @@ volatile struct lance_regs *ll = lp->ll; printk(KERN_ERR "%s: transmit timed out, status %04x, reset\n", - dev->name, ll->rdp); - lance_reset(dev); + dev->name, ll->rdp); + lance_reset(dev); netif_wake_queue(dev); } @@ -872,10 +892,9 @@ len = skblen; - if(len < ETH_ZLEN) - { + if (len < ETH_ZLEN) { skb = skb_padto(skb, ETH_ZLEN); - if(skb == NULL) + if (skb == NULL) return 0; len = ETH_ZLEN; } @@ -890,7 +909,7 @@ skblen); /* Clear the slack of the packet, do I need this? */ - /* For a firewall its a good idea - AC */ + /* For a firewall it's a good idea - AC */ /* if (len != skblen) memset ((char *) &ib->tx_buf [entry][skblen], 0, (len - skblen) << 1); @@ -927,7 +946,7 @@ volatile u16 *mcast_table = (u16 *) & ib->filter; struct dev_mc_list *dmi = dev->mc_list; char *addrs; - int i, j, bit, byte; + int i; u32 crc; /* set all multicast bits */ @@ -1005,6 +1024,8 @@ static int __init dec_lance_init(const int type, const int slot) { static unsigned version_printed; + static const char fmt[] = "declance%d"; + char name[10]; struct net_device *dev; struct lance_private *lp; volatile struct lance_regs *ll; @@ -1019,13 +1040,26 @@ if (dec_lance_debug && version_printed++ == 0) printk(version); - dev = init_etherdev(NULL, sizeof(struct lance_private)); - if (!dev) - return -ENOMEM; + i = 0; + dev = root_lance_dev; + while (dev) { + i++; + lp = (struct lance_private *)dev->priv; + dev = lp->next; + } + snprintf(name, sizeof(name), fmt, i); + + dev = alloc_etherdev(sizeof(struct lance_private)); + if (!dev) { + printk(KERN_ERR "%s: Unable to allocate etherdev, aborting.\n", + name); + ret = -ENOMEM; + goto err_out; + } SET_MODULE_OWNER(dev); /* - * init_etherdev ensures the data structures used by the LANCE + * alloc_etherdev ensures the data structures used by the LANCE * are aligned. */ lp = (struct lance_private *) dev->priv; @@ -1036,7 +1070,7 @@ switch (type) { #ifdef CONFIG_TC case ASIC_LANCE: - dev->base_addr = system_base + LANCE; + dev->base_addr = system_base + IOASIC_LANCE; /* buffer space for the on-board LANCE shared memory */ /* @@ -1045,7 +1079,7 @@ dev->mem_start = KSEG1ADDR(0x00020000); dev->mem_end = dev->mem_start + 0x00020000; dev->irq = dec_interrupt[DEC_IRQ_LANCE]; - esar_base = system_base + ESAR; + esar_base = system_base + IOASIC_ESAR; /* Workaround crash with booting KN04 2.1k from Disk */ memset((void *)dev->mem_start, 0, @@ -1074,7 +1108,8 @@ /* Setup I/O ASIC LANCE DMA. */ lp->dma_irq = dec_interrupt[DEC_IRQ_LANCE_MERR]; - ioasic_write(LANCE_DMA_P, PHYSADDR(dev->mem_start) << 3); + ioasic_write(IO_REG_LANCE_DMA_P, + PHYSADDR(dev->mem_start) << 3); break; @@ -1139,9 +1174,10 @@ break; default: - printk("declance_init called with unknown type\n"); + printk(KERN_ERR "%s: declance_init called with unknown type\n", + name); ret = -ENODEV; - goto err_out; + goto err_out_free_dev; } ll = (struct lance_regs *) dev->base_addr; @@ -1151,19 +1187,21 @@ /* First, check for test pattern */ if (esar[0x60] != 0xff && esar[0x64] != 0x00 && esar[0x68] != 0x55 && esar[0x6c] != 0xaa) { - printk("Ethernet station address prom not found!\n"); + printk(KERN_ERR + "%s: Ethernet station address prom not found!\n", + name); ret = -ENODEV; - goto err_out; + goto err_out_free_dev; } /* Check the prom contents */ for (i = 0; i < 8; i++) { if (esar[i * 4] != esar[0x3c - i * 4] && esar[i * 4] != esar[0x40 + i * 4] && esar[0x3c - i * 4] != esar[0x40 + i * 4]) { - printk("Something is wrong with the ethernet " - "station address prom!\n"); + printk(KERN_ERR "%s: Something is wrong with the " + "ethernet station address prom!\n", name); ret = -ENODEV; - goto err_out; + goto err_out_free_dev; } } @@ -1176,13 +1214,13 @@ */ switch (type) { case ASIC_LANCE: - printk("%s: IOASIC onboard LANCE, addr = ", dev->name); + printk("%s: IOASIC onboard LANCE, addr = ", name); break; case PMAD_LANCE: - printk("%s: PMAD-AA, addr = ", dev->name); + printk("%s: PMAD-AA, addr = ", name); break; case PMAX_LANCE: - printk("%s: PMAX onboard LANCE, addr = ", dev->name); + printk("%s: PMAX onboard LANCE, addr = ", name); break; } for (i = 0; i < 6; i++) { @@ -1219,11 +1257,20 @@ lp->multicast_timer.data = (unsigned long) dev; lp->multicast_timer.function = &lance_set_multicast_retry; + ret = register_netdev(dev); + if (ret) { + printk(KERN_ERR + "%s: Unable to register netdev, aborting.\n", name); + goto err_out_free_dev; + } + + printk("%s: registered as %s.\n", name, dev->name); return 0; -err_out: - unregister_netdev(dev); +err_out_free_dev: kfree(dev); + +err_out: return ret; } Index: drivers/net/dgrs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/dgrs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/dgrs.c 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/dgrs.c 4 Aug 2004 01:29:08 -0000 1.2 @@ -104,7 +104,7 @@ #include static char version[] __initdata = - "$Id: dgrs.c,v 1.1 2004/07/22 19:49:33 joff Exp $"; + "$Id: dgrs.c,v 1.2 2004/08/04 01:29:08 joff Exp $"; /* * DGRS include files @@ -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; Index: drivers/net/dgrs_asstruct.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/dgrs_asstruct.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/dgrs_asstruct.h 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/dgrs_asstruct.h 4 Aug 2004 01:29:08 -0000 1.2 @@ -1,7 +1,7 @@ /* * For declaring structures shared with assembly routines * - * $Id: dgrs_asstruct.h,v 1.1 2004/07/22 19:49:33 joff Exp $ + * $Id: dgrs_asstruct.h,v 1.2 2004/08/04 01:29:08 joff Exp $ */ #if ASSEMBLER Index: drivers/net/dgrs_es4h.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/dgrs_es4h.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/dgrs_es4h.h 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/dgrs_es4h.h 4 Aug 2004 01:29:08 -0000 1.2 @@ -6,7 +6,7 @@ /* board. Everything that says "es4h" should really be */ /* "se4". But we'll keep the old name for now. */ /* */ -/* $Id: dgrs_es4h.h,v 1.1 2004/07/22 19:49:31 joff Exp $ */ +/* $Id: dgrs_es4h.h,v 1.2 2004/08/04 01:29:08 joff Exp $ */ /* */ /************************************************************************/ Index: drivers/net/dgrs_i82596.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/dgrs_i82596.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/dgrs_i82596.h 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/dgrs_i82596.h 4 Aug 2004 01:29:08 -0000 1.2 @@ -1,7 +1,7 @@ /* * i82596 ethernet controller bits and structures (little endian) * - * $Id: dgrs_i82596.h,v 1.1 2004/07/22 19:49:33 joff Exp $ + * $Id: dgrs_i82596.h,v 1.2 2004/08/04 01:29:08 joff Exp $ */ /************************************************************************/ Index: drivers/net/dl2k.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/dl2k.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/dl2k.h 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/dl2k.h 4 Aug 2004 01:29:08 -0000 1.2 @@ -243,7 +243,6 @@ VLANTagInsert = 0x0000000010000000, TFDDone = 0x80000000, VIDShift = 32, - CFI = 0x0000100000000000, UsePriorityShift = 48, }; Index: drivers/net/dmfe.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/dmfe.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/dmfe.c 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/dmfe.c 4 Aug 2004 01:29:08 -0000 1.2 @@ -299,7 +299,7 @@ static int dmfe_stop(struct DEVICE *); static struct net_device_stats * dmfe_get_stats(struct DEVICE *); static void dmfe_set_filter_mode(struct DEVICE *); -static int dmfe_do_ioctl(struct DEVICE *, struct ifreq *, int); +static struct ethtool_ops netdev_ethtool_ops; static u16 read_srom_word(long ,int); static void dmfe_interrupt(int , void *, struct pt_regs *); static void dmfe_descriptor_init(struct dmfe_board_info *, unsigned long); @@ -419,7 +419,7 @@ dev->stop = &dmfe_stop; dev->get_stats = &dmfe_get_stats; dev->set_multicast_list = &dmfe_set_filter_mode; - dev->do_ioctl = &dmfe_do_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; spin_lock_init(&db->lock); pci_read_config_dword(pdev, 0x50, &pci_pmr); @@ -1002,54 +1002,23 @@ } -/* - * Process the ethtool ioctl command - */ - -static int dmfe_ethtool_ioctl(struct net_device *dev, void *useraddr) -{ - struct dmfe_board_info *db = dev->priv; - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: - strcpy(info.driver, DRV_NAME); - strcpy(info.version, DRV_VERSION); - if (db->pdev) - strcpy(info.bus_info, db->pdev->slot_name); - else - sprintf(info.bus_info, "EISA 0x%lx %d", - dev->base_addr, dev->irq); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - - return -EOPNOTSUPP; -} - - -/* - * Process the upper socket ioctl command - */ - -static int dmfe_do_ioctl(struct DEVICE *dev, struct ifreq *ifr, int cmd) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - int retval = -EOPNOTSUPP; - DMFE_DBUG(0, "dmfe_do_ioctl()", 0); - - switch(cmd) { - case SIOCETHTOOL: - return dmfe_ethtool_ioctl(dev, (void*)ifr->ifr_data); - } + struct dmfe_board_info *np = dev->priv; - return retval; + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + if (np->pdev) + strcpy(info->bus_info, pci_name(np->pdev)); + else + sprintf(info->bus_info, "EISA 0x%lx %d", + dev->base_addr, dev->irq); } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; /* * A periodic timer routine Index: drivers/net/dummy.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/dummy.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/dummy.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/dummy.c 4 Aug 2004 01:29:08 -0000 1.2 @@ -28,8 +28,6 @@ Alan Cox, 30th May 1994 */ -/* To have statistics (just packets sent) define this */ - #include #include #include Index: drivers/net/eepro.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/eepro.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/eepro.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/eepro.c 4 Aug 2004 01:29:08 -0000 1.2 @@ -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"); Index: drivers/net/eepro100.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/eepro100.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/eepro100.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/eepro100.c 4 Aug 2004 01:29:08 -0000 1.2 @@ -29,7 +29,7 @@ static const char *version = "eepro100.c:v1.09j-t 9/29/99 Donald Becker http://www.scyld.com/network/eepro100.html\n" -"eepro100.c: $Revision: 1.1 $ 2000/11/17 Modified by Andrey V. Savochkin and others\n"; +"eepro100.c: $Revision: 1.2 $ 2000/11/17 Modified by Andrey V. Savochkin and others\n"; /* A few user-configurable values that apply to all boards. First set is undocumented and spelled per Intel recommendations. */ @@ -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, }, Index: drivers/net/eexpress.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/eexpress.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/eexpress.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/eexpress.c 4 Aug 2004 01:29:08 -0000 1.2 @@ -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); Index: drivers/net/ep93xx_eth.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/ep93xx_eth.c,v retrieving revision 1.1 retrieving revision 1.8 diff -u -r1.1 -r1.8 --- drivers/net/ep93xx_eth.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/ep93xx_eth.c 3 Apr 2006 22:17:59 -0000 1.8 @@ -85,13 +85,17 @@ * calling. * Return: none *--------------------------------------------------------------------------*/ -#define GET_MAC_ADDR(pD, pMac) \ - (pMac)[0] = *(unsigned char *)(IO_ADDRESS(TS7XXX_FLASH_BASE) + 0x7c030a); \ - (pMac)[1] = *(unsigned char *)(IO_ADDRESS(TS7XXX_FLASH_BASE) + 0x7c030b); \ - (pMac)[2] = *(unsigned char *)(IO_ADDRESS(TS7XXX_FLASH_BASE) + 0x7c030c); \ - (pMac)[3] = *(unsigned char *)(IO_ADDRESS(TS7XXX_FLASH_BASE) + 0x7c030d); \ - (pMac)[4] = *(unsigned char *)(IO_ADDRESS(TS7XXX_FLASH_BASE) + 0x7c030e); \ - (pMac)[5] = *(unsigned char *)(IO_ADDRESS(TS7XXX_FLASH_BASE) + 0x7c030f); + + +#define GET_MAC_ADDR(pD, pMac) { \ + *(unsigned long *)0xE001004C = 0x00; \ + (pMac)[0] = *(unsigned char *)(0xE0010050); \ + (pMac)[1] = *(unsigned char *)(0xE0010051); \ + (pMac)[2] = *(unsigned char *)(0xE0010052); \ + (pMac)[3] = *(unsigned char *)(0xE0010053); \ + (pMac)[4] = *(unsigned char *)(0xE0010054); \ + (pMac)[5] = *(unsigned char *)(0xE0010055); \ +} @@ -169,7 +173,7 @@ * 2 for interrupt tracking, status flags * 3 for packet dumps, etc. *--------------------------------------------------------------------------*/ -//#define _DBG 3 +#undef _DBG #if (_DBG > 2 ) #define PRINTK3(x) printk x @@ -206,9 +210,7 @@ #define _PRTK_INFO_ISR PRINTK3 /*general informations from ISR*/ #define _PRTK_ PRINTK /*for temporary print out*/ -#if 0 -# define _PRTK_DUMP PRINTK1 /*to dump large amount of debug info*/ -#endif +#define _PRTK_DUMP PRINTK1 /*to dump large amount of debug info*/ @@ -396,6 +398,8 @@ U16 val; U16 oldVal; +// XXX Already init'ed from RedBoot, don't waste time renegotiating +#if 0 phy_wr(4, 0x01e1); /*Set 802.3, 100M/10M Full/Half ability*/ phy_wr(0,(1<<12)|(1<<9)); /* enable auto negotiation*/ while (1) { @@ -408,6 +412,7 @@ //PHY needs the delay. Otherwise it won't send the 1st frame. mdelay(1000);//delay 1 second. +#endif val = phy_rd(5); /* read ANLPAR Reg*/ if ( val&0x0140) /* if 100M_FDX or 10M_FDX?*/ @@ -432,7 +437,7 @@ _PRTK_ENTRY(("phy_init(pD:0x%x)\n", (unsigned int)pD)); oldVal = RegRd32(REG_SelfCTL); - RegWr32(REG_SelfCTL,0x0e00);/*Set MDC clock to be divided by 8 + RegWr32(REG_SelfCTL,0x6200);/*Set MDC clock to be divided by 32 and disable PreambleSuppress bit*/ phy_autoNegotiation(pD); @@ -475,7 +480,7 @@ * _dbg_ep9312Eth_dumpQueues() *****************************************************************************/ static void _dbg_ep9312Eth_dumpQueues(struct net_device *pD) { -// struct ep9213Eth_info *pP=pD->priv; + struct ep9213Eth_info *pP=pD->priv; int i; _PRTK_DUMP(("Dumping Descriptor/Status Queues\n")); @@ -720,7 +725,7 @@ * _dbg_ep9312eth_dumpReg() *****************************************************************************/ static void _dbg_ep9312eth_dumpReg(struct net_device *pD) { -// struct ep9213Eth_info *pP = pD->priv; + struct ep9213Eth_info *pP = pD->priv; _PRTK_DUMP(("Dumping registers of Ethernet Module Embedded within EP9312\n")); _PRTK_DUMP((" pD:0x%p, Base Address:0x%x\n",pD,(unsigned int)pD->base_addr)); @@ -1130,7 +1135,7 @@ phy_init(pD); /*init MAC*/ - RegWr32(REG_SelfCTL,0x0f00);/*Set MDC clock to be divided by 8 + RegWr32(REG_SelfCTL,0x6300);/*Set MDC clock to be divided by 32 and enable PreambleSuppress bit*/ RegWr32(REG_GIntMsk,0x00); /*mask Interrupt*/ RegWr32(REG_RxCTL,RxCTL_BA|RxCTL_IA0); /*no Rx on at this point*/ @@ -1245,7 +1250,7 @@ /*Grab the region so that no one else tries to probe this device*/ err=(int)request_region(baseA,DEV_REG_SPACE,cardname); - if(err) { + if(err == 0) { _PRTK_SYSFAIL((cardname " initDriver(): unable to get region 0x%x-0x%x (err=%d)\n", (int)baseA,(int)(baseA+DEV_REG_SPACE-1),err)); return -EAGAIN; @@ -1449,7 +1454,7 @@ tog=tog?0:1; if(tog) { _dbg_ep9312Eth_dumpQueues(pD); - /*_dbg_phy_dumpReg(pD);*/ + _dbg_phy_dumpReg(pD); _dbg_ep9312eth_dumpReg(pD); }/*if*/ } @@ -1598,7 +1603,6 @@ _PRTK_ENTRY(("ep9213Eth_close(pD:0x%x)\n", (unsigned int)pD)); - disable_irq(pD->irq); /*request system to disable INT*/ netif_stop_queue(pD); eth_shutDown(pD); /*shut device down*/ @@ -1634,7 +1638,6 @@ /*turn on INT, turn on Rx*/ eth_enable(pD); - enable_irq(pD->irq); /*ask system to enable INT*/ #if 0 /*@*/ Index: drivers/net/epic100.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/epic100.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/epic100.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/epic100.c 4 Aug 2004 01:29:09 -0000 1.2 @@ -69,10 +69,9 @@ */ -#define DRV_NAME "epic100" -#define DRV_VERSION "1.11+LK1.1.14" -#define DRV_RELDATE "Aug 4, 2002" - +#define DRV_NAME "epic100" +#define DRV_VERSION "1.11+LK1.1.14" +#define DRV_RELDATE "Aug 4, 2002" /* The user-configurable values. These may be modified when a driver module is loaded.*/ @@ -243,7 +242,7 @@ }; -static struct pci_device_id epic_pci_tbl[] __devinitdata = { +static struct pci_device_id epic_pci_tbl[] = { { 0x10B8, 0x0005, 0x1092, 0x0AB4, 0, 0, SMSC_83C170_0 }, { 0x10B8, 0x0005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SMSC_83C170 }, { 0x10B8, 0x0006, PCI_ANY_ID, PCI_ANY_ID, @@ -361,8 +360,9 @@ static void epic_init_ring(struct net_device *dev); static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev); static int epic_rx(struct net_device *dev); -static void epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs); +static irqreturn_t epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; static int epic_close(struct net_device *dev); static struct net_device_stats *epic_get_stats(struct net_device *dev); static void set_rx_mode(struct net_device *dev); @@ -479,7 +479,7 @@ if (debug > 2) { printk(KERN_DEBUG DRV_NAME "(%s): EEPROM contents\n", - pdev->slot_name); + pci_name(pdev)); for (i = 0; i < 64; i++) printk(" %4.4x%s", read_eeprom(ioaddr, i), i % 16 == 15 ? "\n" : ""); @@ -500,7 +500,7 @@ ep->phys[phy_idx++] = phy; printk(KERN_INFO DRV_NAME "(%s): MII transceiver #%d control " "%4.4x status %4.4x.\n", - pdev->slot_name, phy, mdio_read(dev, phy, 0), mii_status); + pci_name(pdev), phy, mdio_read(dev, phy, 0), mii_status); } } ep->mii_phy_cnt = phy_idx; @@ -509,10 +509,10 @@ ep->mii.advertising = mdio_read(dev, phy, MII_ADVERTISE); printk(KERN_INFO DRV_NAME "(%s): Autonegotiation advertising %4.4x link " "partner %4.4x.\n", - pdev->slot_name, ep->mii.advertising, mdio_read(dev, phy, 5)); + pci_name(pdev), ep->mii.advertising, mdio_read(dev, phy, 5)); } else if ( ! (ep->chip_flags & NO_MII)) { printk(KERN_WARNING DRV_NAME "(%s): ***WARNING***: No MII transceiver found!\n", - pdev->slot_name); + pci_name(pdev)); /* Use the known PHY address of the EPII. */ ep->phys[0] = 3; } @@ -528,7 +528,7 @@ if (duplex) { ep->mii.force_media = ep->mii.full_duplex = 1; printk(KERN_INFO DRV_NAME "(%s): Forced full duplex operation requested.\n", - pdev->slot_name); + pci_name(pdev)); } dev->if_port = ep->default_port = option; @@ -539,6 +539,7 @@ dev->get_stats = &epic_get_stats; dev->set_multicast_list = &set_rx_mode; dev->do_ioctl = &netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; dev->watchdog_timeo = TX_TIMEOUT; dev->tx_timeout = &epic_tx_timeout; @@ -974,12 +975,11 @@ struct epic_private *ep = dev->priv; int entry, free_count; u32 ctrl_word; - long flags; + unsigned long flags; - if(skb->len < ETH_ZLEN) - { + if (skb->len < ETH_ZLEN) { skb = skb_padto(skb, ETH_ZLEN); - if(skb == NULL) + if (skb == NULL) return 0; } @@ -1030,12 +1030,13 @@ /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static void epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs) +static irqreturn_t epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = dev_instance; struct epic_private *ep = dev->priv; long ioaddr = dev->base_addr; int status, boguscnt = max_interrupt_work; + unsigned int handled = 0; do { status = inl(ioaddr + INTSTAT); @@ -1049,6 +1050,7 @@ if ((status & IntrSummary) == 0) break; + handled = 1; if (status & (RxDone | RxStarted | RxEarlyWarn | RxOverflow)) epic_rx(dev); @@ -1158,7 +1160,7 @@ printk(KERN_DEBUG "%s: exiting interrupt, intr_status=%#4.4x.\n", dev->name, status); - return; + return IRQ_RETVAL(handled); } static int epic_rx(struct net_device *dev) @@ -1345,9 +1347,11 @@ memset(mc_filter, 0, sizeof(mc_filter)); for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; - i++, mclist = mclist->next) - set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f, - mc_filter); + i++, mclist = mclist->next) { + unsigned int bit_nr = + ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f; + mc_filter[bit_nr >> 3] |= (1 << bit_nr); + } } /* ToDo: perhaps we need to stop the Tx and Rx process here? */ if (memcmp(mc_filter, ep->mc_filter, sizeof(mc_filter))) { @@ -1358,82 +1362,73 @@ return; } -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info) { struct epic_private *np = dev->priv; - u32 ethcmd; - if (copy_from_user (ðcmd, useraddr, sizeof (ethcmd))) - return -EFAULT; + strcpy (info->driver, DRV_NAME); + strcpy (info->version, DRV_VERSION); + strcpy (info->bus_info, pci_name(np->pci_dev)); +} - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - strcpy (info.bus_info, np->pci_dev->slot_name); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } +static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct epic_private *np = dev->priv; + int rc; - /* get settings */ - case ETHTOOL_GSET: { - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - spin_lock_irq(&np->lock); - mii_ethtool_gset(&np->mii, &ecmd); - spin_unlock_irq(&np->lock); - if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } - /* set settings */ - case ETHTOOL_SSET: { - int r; - struct ethtool_cmd ecmd; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - spin_lock_irq(&np->lock); - r = mii_ethtool_sset(&np->mii, &ecmd); - spin_unlock_irq(&np->lock); - return r; - } - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - return mii_nway_restart(&np->mii); - } - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = {ETHTOOL_GLINK}; - edata.data = mii_link_ok(&np->mii); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } + spin_lock_irq(&np->lock); + rc = mii_ethtool_gset(&np->mii, cmd); + spin_unlock_irq(&np->lock); - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } - default: - break; - } + return rc; +} - return -EOPNOTSUPP; +static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct epic_private *np = dev->priv; + int rc; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_sset(&np->mii, cmd); + spin_unlock_irq(&np->lock); + + return rc; +} + +static int netdev_nway_reset(struct net_device *dev) +{ + struct epic_private *np = dev->priv; + return mii_nway_restart(&np->mii); +} + +static u32 netdev_get_link(struct net_device *dev) +{ + struct epic_private *np = dev->priv; + return mii_link_ok(&np->mii); +} + +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return debug; } +static void netdev_set_msglevel(struct net_device *dev, u32 value) +{ + debug = value; +} + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_settings = netdev_get_settings, + .set_settings = netdev_set_settings, + .nway_reset = netdev_nway_reset, + .get_link = netdev_get_link, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, + .get_sg = ethtool_op_get_sg, + .get_tx_csum = ethtool_op_get_tx_csum, +}; + static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct epic_private *np = dev->priv; @@ -1447,16 +1442,10 @@ outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL); } - /* ethtool commands */ - if (cmd == SIOCETHTOOL) - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - - /* all other ioctls (the SIOC[GS]MIIxxx ioctls) */ - else { - spin_lock_irq(&np->lock); - rc = generic_mii_ioctl(&np->mii, data, cmd, NULL); - spin_unlock_irq(&np->lock); - } + /* all non-ethtool ioctls (the SIOC[GS]MIIxxx ioctls) */ + spin_lock_irq(&np->lock); + rc = generic_mii_ioctl(&np->mii, data, cmd, NULL); + spin_unlock_irq(&np->lock); /* power-down, if interface is down */ if (! netif_running(dev)) { @@ -1517,13 +1506,13 @@ static struct pci_driver epic_driver = { - name: DRV_NAME, - id_table: epic_pci_tbl, - probe: epic_init_one, - remove: __devexit_p(epic_remove_one), + .name = DRV_NAME, + .id_table = epic_pci_tbl, + .probe = epic_init_one, + .remove = __devexit_p(epic_remove_one), #ifdef CONFIG_PM - suspend: epic_suspend, - resume: epic_resume, + .suspend = epic_suspend, + .resume = epic_resume, #endif /* CONFIG_PM */ }; Index: drivers/net/eql.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/eql.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/eql.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/eql.c 4 Aug 2004 01:29:09 -0000 1.2 @@ -28,8 +28,8 @@ /* * $Log: eql.c,v $ - * Revision 1.1 2004/07/22 19:49:31 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:09 joff + * merging 2.4.26-vrs1 * * Revision 1.2 1996/04/11 17:51:52 guru * Added one-line eql_remove_slave patch. @@ -125,7 +125,7 @@ #include static char version[] __initdata = - "Equalizer1996: $Revision: 1.1 $ $Date: 2004/07/22 19:49:31 $ Simon Janes (simon@ncm.com)\n"; + "Equalizer1996: $Revision: 1.2 $ $Date: 2004/08/04 01:29:09 $ Simon Janes (simon@ncm.com)\n"; #ifndef EQL_DEBUG /* #undef EQL_DEBUG -* print nothing at all, not even a boot-banner */ Index: drivers/net/eth16i.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/eth16i.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/eth16i.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/eth16i.c 4 Aug 2004 01:29:09 -0000 1.2 @@ -1057,7 +1057,7 @@ int ioaddr = dev->base_addr; int status = 0; ushort length = skb->len; - unsigned char *buf = skb->data; + unsigned char *buf; unsigned long flags; if(length < ETH_ZLEN) @@ -1067,6 +1067,7 @@ return 0; length = ETH_ZLEN; } + buf = skb->data; netif_stop_queue(dev); Index: drivers/net/fealnx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/fealnx.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/fealnx.c 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/fealnx.c 4 Aug 2004 01:29:09 -0000 1.2 @@ -85,6 +85,7 @@ #include #include #include + #include /* Processor type for cache alignment. */ #include #include @@ -438,11 +439,12 @@ static void tx_timeout(struct net_device *dev); static void init_ring(struct net_device *dev); static int start_tx(struct sk_buff *skb, struct net_device *dev); -static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs); +static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs); static int netdev_rx(struct net_device *dev); static void set_rx_mode(struct net_device *dev); static struct net_device_stats *get_stats(struct net_device *dev); static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; static int netdev_close(struct net_device *dev); static void reset_rx_descriptors(struct net_device *dev); @@ -666,6 +668,7 @@ dev->get_stats = &get_stats; dev->set_multicast_list = &set_rx_mode; dev->do_ioctl = &mii_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; dev->tx_timeout = tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; @@ -1412,12 +1415,13 @@ /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) +static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) { struct net_device *dev = (struct net_device *) dev_instance; struct netdev_private *np = dev->priv; long ioaddr, boguscnt = max_interrupt_work; unsigned int num_tx = 0; + int handled = 0; writel(0, dev->base_addr + IMR); @@ -1437,6 +1441,8 @@ if (!(intr_status & np->imrvalue)) break; + handled = 1; + // 90/1/16 delete, // // if (intr_status & FBE) @@ -1559,11 +1565,11 @@ writel(np->imrvalue, ioaddr + IMR); - return; + return IRQ_RETVAL(handled); } -/* This routine is logically part of the interrupt handler, but seperated +/* This routine is logically part of the interrupt handler, but separated for clarity and better register allocation. */ static int netdev_rx(struct net_device *dev) { @@ -1739,8 +1745,9 @@ memset(mc_filter, 0, sizeof(mc_filter)); for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) { - set_bit((ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26) ^ 0x3F, - mc_filter); + unsigned int bit; + bit = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26) ^ 0x3F; + mc_filter[bit >> 5] |= (1 << bit); } rx_mode = AB | AM; } @@ -1755,82 +1762,72 @@ writel(np->crvalue, ioaddr + TCRRCR); } -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info) { struct netdev_private *np = dev->priv; - u32 ethcmd; - if (copy_from_user (ðcmd, useraddr, sizeof (ethcmd))) - return -EFAULT; + strcpy (info->driver, DRV_NAME); + strcpy (info->version, DRV_VERSION); + strcpy (info->bus_info, pci_name(np->pci_dev)); +} - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - strcpy (info.bus_info, np->pci_dev->slot_name); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - /* get settings */ - case ETHTOOL_GSET: { - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - spin_lock_irq(&np->lock); - mii_ethtool_gset(&np->mii, &ecmd); - spin_unlock_irq(&np->lock); - if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } - /* set settings */ - case ETHTOOL_SSET: { - int r; - struct ethtool_cmd ecmd; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - spin_lock_irq(&np->lock); - r = mii_ethtool_sset(&np->mii, &ecmd); - spin_unlock_irq(&np->lock); - return r; - } - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - return mii_nway_restart(&np->mii); - } - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = {ETHTOOL_GLINK}; - edata.data = mii_link_ok(&np->mii); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } - default: - break; - } +static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct netdev_private *np = dev->priv; + int rc; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_gset(&np->mii, cmd); + spin_unlock_irq(&np->lock); - return -EOPNOTSUPP; + return rc; } +static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct netdev_private *np = dev->priv; + int rc; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_sset(&np->mii, cmd); + spin_unlock_irq(&np->lock); + + return rc; +} + +static int netdev_nway_reset(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + return mii_nway_restart(&np->mii); +} + +static u32 netdev_get_link(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + return mii_link_ok(&np->mii); +} + +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return debug; +} + +static void netdev_set_msglevel(struct net_device *dev, u32 value) +{ + debug = value; +} + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_settings = netdev_get_settings, + .set_settings = netdev_set_settings, + .nway_reset = netdev_nway_reset, + .get_link = netdev_get_link, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, + .get_sg = ethtool_op_get_sg, + .get_tx_csum = ethtool_op_get_tx_csum, +}; static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { @@ -1841,14 +1838,9 @@ if (!netif_running(dev)) return -EINVAL; - if (cmd == SIOCETHTOOL) - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - - else { - spin_lock_irq(&np->lock); - rc = generic_mii_ioctl(&np->mii, data, cmd, NULL); - spin_unlock_irq(&np->lock); - } + spin_lock_irq(&np->lock); + rc = generic_mii_ioctl(&np->mii, data, cmd, NULL); + spin_unlock_irq(&np->lock); return rc; } @@ -1900,7 +1892,7 @@ return 0; } -static struct pci_device_id fealnx_pci_tbl[] __devinitdata = { +static struct pci_device_id fealnx_pci_tbl[] = { {0x1516, 0x0800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0x1516, 0x0803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, {0x1516, 0x0891, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, @@ -1910,10 +1902,10 @@ static struct pci_driver fealnx_driver = { - name: "fealnx", - id_table: fealnx_pci_tbl, - probe: fealnx_init_one, - remove: __devexit_p(fealnx_remove_one), + .name = "fealnx", + .id_table = fealnx_pci_tbl, + .probe = fealnx_init_one, + .remove = __devexit_p(fealnx_remove_one), }; static int __init fealnx_init(void) Index: drivers/net/fmv18x.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/fmv18x.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/fmv18x.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/net/fmv18x.c 4 Aug 2004 01:29:09 -0000 1.2 @@ -370,7 +370,7 @@ struct net_local *lp = dev->priv; int ioaddr = dev->base_addr; short length = skb->len; - unsigned char *buf = skb->data; + unsigned char *buf; unsigned long flags; /* Block a transmit from overlapping. */ @@ -389,6 +389,7 @@ return 0; length = ETH_ZLEN; } + buf = skb->data; if (net_debug > 4) printk("%s: Transmitting a packet of length %lu.\n", dev->name, Index: drivers/net/gmac.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/gmac.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/gmac.c 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/gmac.c 4 Aug 2004 01:29:09 -0000 1.2 @@ -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; Index: drivers/net/gt96100eth.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/gt96100eth.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/gt96100eth.c 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/gt96100eth.c 4 Aug 2004 01:29:09 -0000 1.2 @@ -700,7 +700,8 @@ struct net_device *dev = NULL; if (gtif->irq < 0) { - printk(KERN_ERR "%s: irq unknown - probing not supported\n", __FUNCTION_); + printk(KERN_ERR "%s: irq unknown - probing not supported\n", + __FUNCTION__); return -ENODEV; } @@ -1363,7 +1364,8 @@ gp->tx_full = 0; if (gp->last_psr & psrLink) { netif_wake_queue(dev); - dbg(2, "%s: Tx Ring was full, queue waked\n", __FUNCTION_); + dbg(2, "%s: Tx Ring was full, queue waked\n", + __FUNCTION__); } } @@ -1444,7 +1446,7 @@ if ((psr & psrLink) && !gp->tx_full && netif_queue_stopped(dev)) { dbg(0, ": Link up, waking queue.\n", - __FUNCTION_); + __FUNCTION__); netif_wake_queue(dev); } else if (!(psr & psrLink) && !netif_queue_stopped(dev)) { Index: drivers/net/hp100.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/hp100.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/hp100.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/hp100.c 4 Aug 2004 01:29:09 -0000 1.2 @@ -2,7 +2,7 @@ ** hp100.c ** HP CASCADE Architecture Driver for 100VG-AnyLan Network Adapters ** -** $Id: hp100.c,v 1.1 2004/07/22 19:49:34 joff Exp $ +** $Id: hp100.c,v 1.2 2004/08/04 01:29:09 joff Exp $ ** ** Based on the HP100 driver written by Jaroslav Kysela ** Extended for new busmaster capable chipsets by Index: drivers/net/hp100.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/hp100.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/hp100.h 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/hp100.h 4 Aug 2004 01:29:09 -0000 1.2 @@ -1,7 +1,7 @@ /* * hp100.h: Hewlett Packard HP10/100VG ANY LAN ethernet driver for Linux. * - * $Id: hp100.h,v 1.1 2004/07/22 19:49:34 joff Exp $ + * $Id: hp100.h,v 1.2 2004/08/04 01:29:09 joff Exp $ * * Authors: Jaroslav Kysela, * Siegfried Loeffler Index: drivers/net/ioc3-eth.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/ioc3-eth.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/ioc3-eth.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/ioc3-eth.c 4 Aug 2004 01:29:09 -0000 1.2 @@ -377,82 +377,6 @@ ip->dev->dev_addr[i - 2] = nic[i]; } -#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_SGI_SN2) -/* - * Get the ether-address on SN1 nodes - */ -static void ioc3_get_eaddr_sn(struct ioc3_private *ip) -{ - int ibrick_mac_addr_get(nasid_t, char *); - struct ioc3 *ioc3 = ip->regs; - nasid_t nasid_of_ioc3; - char io7eaddr[20]; - long mac; - int err_val; - - /* - * err_val = ibrick_mac_addr_get(get_nasid(), io7eaddr ); - * - * BAD!! The above call uses get_nasid() and assumes that - * the ioc3 pointed to by struct ioc3 is hooked up to the - * cbrick that we're running on. The proper way to make this call - * is to figure out which nasid the ioc3 is connected to - * and use that to call ibrick_mac_addr_get. Below is - * a hack to do just that. - */ - - /* - * Get the nasid of the ioc3 from the ioc3's base addr. - * FIXME: the 8 at the end assumes we're in memory mode, - * not node mode (for that, we'd change it to a 9). - * Is there a call to extract this info from a physical - * addr somewhere in an sn header file already? If so, - * we should probably use that, or restructure this routine - * to use pci_dev and generic numa nodeid getting stuff. - */ - nasid_of_ioc3 = (((unsigned long)ioc3 >> 33) & ~(-1 << 8)); - err_val = ibrick_mac_addr_get(nasid_of_ioc3, io7eaddr ); - - - if (err_val) { - /* Couldn't read the eeprom; try OSLoadOptions. */ - printk("WARNING: ibrick_mac_addr_get failed: %d\n", err_val); - - /* this is where we hardwire the mac address - * 1st ibrick had 08:00:69:11:34:75 - * 2nd ibrick had 08:00:69:11:35:35 - * - * Eagan Machines: - * mankato1 08:00:69:11:BE:95 - * warroad 08:00:69:11:bd:60 - * duron 08:00:69:11:34:60 - * - * an easy way to get the mac address is to hook - * up an ip35, then from L1 do 'cti serial' - * and then look for MAC line XXX THIS DOESN"T QUITE WORK!! - */ - printk("ioc3_get_eaddr: setting ethernet address to:\n -----> "); - ip->dev->dev_addr[0] = 0x8; - ip->dev->dev_addr[1] = 0x0; - ip->dev->dev_addr[2] = 0x69; - ip->dev->dev_addr[3] = 0x11; - ip->dev->dev_addr[4] = 0x34; - ip->dev->dev_addr[5] = 0x60; - } - else { - long simple_strtol(const char *,char **,unsigned int); - - mac = simple_strtol(io7eaddr, (char **)0, 16); - ip->dev->dev_addr[0] = (mac >> 40) & 0xff; - ip->dev->dev_addr[1] = (mac >> 32) & 0xff; - ip->dev->dev_addr[2] = (mac >> 24) & 0xff; - ip->dev->dev_addr[3] = (mac >> 16) & 0xff; - ip->dev->dev_addr[4] = (mac >> 8) & 0xff; - ip->dev->dev_addr[5] = mac & 0xff; - } -} -#endif - /* * Ok, this is hosed by design. It's necessary to know what machine the * NIC is in in order to know how to read the NIC address. We also have @@ -460,30 +384,15 @@ */ static void ioc3_get_eaddr(struct ioc3_private *ip) { - void (*do_get_eaddr)(struct ioc3_private *ip) = NULL; int i; - /* - * We should also use this code for PCI cards, no matter what host - * machine but how to know that we're a PCI card? - */ -#ifdef CONFIG_SGI_IP27 - do_get_eaddr = ioc3_get_eaddr_nic; -#endif -#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_SGI_SN2) - do_get_eaddr = ioc3_get_eaddr_sn; -#endif - if (!do_get_eaddr) { - printk(KERN_ERR "Don't know how to read MAC address of this " - "IOC3 NIC\n"); - return; - } + ioc3_get_eaddr_nic(ip); printk("Ethernet address is "); for (i = 0; i < 6; i++) { printk("%02x", ip->dev->dev_addr[i]); - if (i < 7) + if (i < 5) printk(":"); } printk(".\n"); @@ -588,7 +497,7 @@ ip->stats.rx_frame_errors++; next: ip->rx_skbs[n_entry] = new_skb; - rxr[n_entry] = cpu_to_be32((0xa5UL << 56) | + rxr[n_entry] = cpu_to_be64((0xa5UL << 56) | ((unsigned long) rxb & TO_PHYS_MASK)); rxb->w0 = 0; /* Clear valid flag */ n_entry = (n_entry + 1) & 511; /* Update erpir */ @@ -1552,11 +1461,11 @@ #endif spin_lock_init(&ip->ioc3_lock); + init_timer(&ip->ioc3_timer); ioc3_stop(ip); ioc3_init(ip); - init_timer(&ip->ioc3_timer); ioc3_mii_init(ip); if (ip->phy == -1) { @@ -1610,6 +1519,7 @@ struct ioc3_private *ip = dev->priv; struct ioc3 *ioc3 = ip->regs; + unregister_netdev(dev); iounmap(ioc3); pci_release_regions(pdev); kfree(dev); @@ -1622,10 +1532,10 @@ MODULE_DEVICE_TABLE(pci, ioc3_pci_tbl); static struct pci_driver ioc3_driver = { - name: "ioc3-eth", - id_table: ioc3_pci_tbl, - probe: ioc3_probe, - remove: __devexit_p(ioc3_remove_one), + .name = "ioc3-eth", + .id_table = ioc3_pci_tbl, + .probe = ioc3_probe, + .remove = __devexit_p(ioc3_remove_one), }; static int __init ioc3_init_module(void) @@ -1841,9 +1751,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) Index: drivers/net/lasi_82596.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/lasi_82596.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/lasi_82596.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/lasi_82596.c 4 Aug 2004 01:29:10 -0000 1.2 @@ -97,7 +97,7 @@ #include static char version[] __devinitdata = - "82596.c $Revision: 1.1 $\n"; + "82596.c $Revision: 1.2 $\n"; /* DEBUG flags */ Index: drivers/net/mac8390.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/mac8390.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/mac8390.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/mac8390.c 4 Aug 2004 01:29:10 -0000 1.2 @@ -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) Index: drivers/net/mac89x0.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/mac89x0.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/mac89x0.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/mac89x0.c 4 Aug 2004 01:29:10 -0000 1.2 @@ -128,7 +128,7 @@ extern void reset_chip(struct net_device *dev); #endif static int net_open(struct net_device *dev); -static int net_send_packet(struct sk_buff *skb, struct net_device *dev); +static int net_send_packet(struct sk_buff *skb, struct net_device *dev); static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void set_multicast_list(struct net_device *dev); static void net_rx(struct net_device *dev); @@ -368,57 +368,38 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) { - if (dev->tbusy) { - /* If we get here, some higher level has decided we are broken. - There should really be a "kick me" function call instead. */ - int tickssofar = jiffies - dev->trans_start; - if (tickssofar < 5) - return 1; - if (net_debug > 0) printk("%s: transmit timed out, %s?\n", dev->name, - tx_done(dev) ? "IRQ conflict" : "network cable problem"); - /* Try to restart the adaptor. */ - dev->tbusy=0; - dev->trans_start = jiffies; - } - - /* 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); - else { - struct net_local *lp = (struct net_local *)dev->priv; - unsigned long flags; - - if (net_debug > 3) - printk("%s: sent %d byte packet of type %x\n", - dev->name, skb->len, - (skb->data[ETH_ALEN+ETH_ALEN] << 8) - | skb->data[ETH_ALEN+ETH_ALEN+1]); - - /* keep the upload from being interrupted, since we - ask the chip to start transmitting before the - whole packet has been completely uploaded. */ - save_flags(flags); - cli(); - - /* initiate a transmit sequence */ - writereg(dev, PP_TxCMD, lp->send_cmd); - writereg(dev, PP_TxLength, skb->len); - - /* Test to see if the chip has allocated memory for the packet */ - if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) { - /* Gasp! It hasn't. But that shouldn't happen since - we're waiting for TxOk, so return 1 and requeue this packet. */ - restore_flags(flags); - return 1; - } + struct net_local *lp = (struct net_local *)dev->priv; + unsigned long flags; - /* Write the contents of the packet */ - memcpy_toio(dev->mem_start + PP_TxFrame, skb->data, skb->len+1); + if (net_debug > 3) + printk("%s: sent %d byte packet of type %x\n", + dev->name, skb->len, + (skb->data[ETH_ALEN+ETH_ALEN] << 8) + | skb->data[ETH_ALEN+ETH_ALEN+1]); + + /* keep the upload from being interrupted, since we + ask the chip to start transmitting before the + whole packet has been completely uploaded. */ + save_flags(flags); + cli(); + /* initiate a transmit sequence */ + writereg(dev, PP_TxCMD, lp->send_cmd); + writereg(dev, PP_TxLength, skb->len); + + /* Test to see if the chip has allocated memory for the packet */ + if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) { + /* Gasp! It hasn't. But that shouldn't happen since + we're waiting for TxOk, so return 1 and requeue this packet. */ restore_flags(flags); - dev->trans_start = jiffies; + return 1; } + + /* Write the contents of the packet */ + memcpy((void *)(dev->mem_start + PP_TxFrame), skb->data, skb->len+1); + + restore_flags(flags); + dev->trans_start = jiffies; dev_kfree_skb (skb); return 0; @@ -436,9 +417,6 @@ printk ("net_interrupt(): irq %d for unknown device.\n", irq); return; } - if (dev->interrupt) - printk("%s: Re-entering the interrupt handler.\n", dev->name); - dev->interrupt = 1; ioaddr = dev->base_addr; lp = (struct net_local *)dev->priv; @@ -459,8 +437,7 @@ break; case ISQ_TRANSMITTER_EVENT: lp->stats.tx_packets++; - dev->tbusy = 0; - mark_bh(NET_BH); /* Inform upper layers. */ + netif_wake_queue(dev); if ((status & TX_OK) == 0) lp->stats.tx_errors++; if (status & TX_LOST_CRS) lp->stats.tx_carrier_errors++; if (status & TX_SQE_ERROR) lp->stats.tx_heartbeat_errors++; @@ -474,8 +451,7 @@ That shouldn't happen since we only ever load one packet. Shrug. Do the right thing anyway. */ - dev->tbusy = 0; - mark_bh(NET_BH); /* Inform upper layers. */ + netif_wake_queue(dev); } if (status & TX_UNDERRUN) { if (net_debug > 0) printk("%s: transmit underrun\n", dev->name); @@ -492,7 +468,6 @@ break; } } - dev->interrupt = 0; return; } @@ -527,7 +502,7 @@ skb_put(skb, length); skb->dev = dev; - memcpy_fromio(skb->data, dev->mem_start + PP_RxFrame, length); + memcpy(skb->data, (void *)(dev->mem_start + PP_RxFrame), length); if (net_debug > 3)printk("%s: received %d byte packet of type %x\n", dev->name, length, @@ -607,8 +582,6 @@ static int set_mac_address(struct net_device *dev, void *addr) { int i; - if (dev->start) - return -EBUSY; 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]); Index: drivers/net/mace.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/mace.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/mace.c 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/mace.c 4 Aug 2004 01:29:10 -0000 1.2 @@ -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); } Index: drivers/net/macmace.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/macmace.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/macmace.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/macmace.c 4 Aug 2004 01:29:10 -0000 1.2 @@ -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); Index: drivers/net/macsonic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/macsonic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/macsonic.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/macsonic.c 4 Aug 2004 01:29:10 -0000 1.2 @@ -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. Index: drivers/net/meth.c =================================================================== RCS file: drivers/net/meth.c diff -N drivers/net/meth.c --- drivers/net/meth.c 22 Jul 2004 19:49:33 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,863 +0,0 @@ -/* - * meth.c -- O2 Builtin 10/100 Ethernet driver - * - * Copyright (C) 2001 Ilya Volynets - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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 /* printk() */ -#include -#include -#include /* error codes */ -#include /* size_t */ -#include /* mark_bh */ -#include - -#include -#include /* struct device, and other headers */ -#include /* eth_type_trans */ -#include /* struct iphdr */ -#include /* struct tcphdr */ -#include -#include /*MII definitions */ - -#include -#include -#include - -#include "meth.h" - -#include -#include - -#ifndef MFE_DEBUG -#define MFE_DEBUG 0 -#endif - -#if MFE_DEBUG>=1 -#define DPRINTK(str,args...) printk (KERN_DEBUG "meth(%ld): %s: " str, jiffies, __FUNCTION__ , ## args) -#define MFE_RX_DEBUG 2 -#else -#define DPRINTK(str,args...) -#define MFE_RX_DEBUG 0 -#endif - - -static const char *version="meth.c: Ilya Volynets (ilya@theIlya.com)"; -static const char *meth_str="SGI O2 Fast Ethernet"; -MODULE_AUTHOR("Ilya Volynets"); -MODULE_DESCRIPTION("SGI O2 Builtin Fast Ethernet driver"); - -/* This is a load-time options */ -/*static int eth = 0; -MODULE_PARM(eth, "i");*/ - -#define HAVE_TX_TIMEOUT -/* The maximum time waited (in jiffies) before assuming a Tx failed. (400ms) */ -#define TX_TIMEOUT (400*HZ/1000) - -#ifdef HAVE_TX_TIMEOUT -static int timeout = TX_TIMEOUT; -MODULE_PARM(timeout, "i"); -#endif - -int meth_eth; - - -/* - * This structure is private to each device. It is used to pass - * packets in and out, so there is place for a packet - */ - -typedef struct meth_private { - struct net_device_stats stats; - volatile struct meth_regs *regs; - u64 mode; /* in-memory copy of MAC control register */ - int phy_addr; /* address of phy, used by mdio_* functions, initialized in mdio_probe*/ - tx_packet *tx_ring; - dma_addr_t tx_ring_dma; - int free_space; - struct sk_buff *tx_skbs[TX_RING_ENTRIES]; - dma_addr_t tx_skb_dmas[TX_RING_ENTRIES]; - int tx_read,tx_write; - int tx_count; - - rx_packet *rx_ring[RX_RING_ENTRIES]; - dma_addr_t rx_ring_dmas[RX_RING_ENTRIES]; - int rx_write; - - spinlock_t meth_lock; -} meth_private; - -extern struct net_device meth_devs[]; -void meth_tx_timeout (struct net_device *dev); -void meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs); - -/* global, initialized in ip32-setup.c */ -char o2meth_eaddr[8]={0,0,0,0,0,0,0,0}; - -static inline void load_eaddr(struct net_device *dev, - volatile struct meth_regs *regs) -{ - int i; - DPRINTK("Loading MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", - (int)o2meth_eaddr[0]&0xFF,(int)o2meth_eaddr[1]&0xFF,(int)o2meth_eaddr[2]&0xFF, - (int)o2meth_eaddr[3]&0xFF,(int)o2meth_eaddr[4]&0xFF,(int)o2meth_eaddr[5]&0xFF); - //memcpy(dev->dev_addr,o2meth_eaddr+2,6); - for (i=0; i<6; i++) - dev->dev_addr[i]=o2meth_eaddr[i]; - regs->mac_addr= //dev->dev_addr[0]|(dev->dev_addr[1]<<8)| - //dev->dev_addr[2]<<16|(dev->dev_addr[3]<<24)| - //dev->dev_addr[4]<<32|(dev->dev_addr[5]<<40); - (*(u64*)o2meth_eaddr)>>16; - DPRINTK("MAC, finally is %0lx\n",regs->mac_addr); -} - -/* - *Waits for BUSY status of mdio bus to clear - */ -#define WAIT_FOR_PHY(___regs, ___rval) \ - while((___rval=___regs->phy_data)&MDIO_BUSY){ \ - udelay(25); \ - } -/*read phy register, return value read */ -static int mdio_read(meth_private *priv,int phyreg) -{ - volatile meth_regs* regs=priv->regs; - volatile u32 rval; - WAIT_FOR_PHY(regs,rval) - regs->phy_registers=(priv->phy_addr<<5)|(phyreg&0x1f); - udelay(25); - regs->phy_trans_go=1; - udelay(25); - WAIT_FOR_PHY(regs,rval) - return rval&MDIO_DATA_MASK; -} - -/*write phy register */ -static void mdio_write(meth_private* priv,int pfyreg,int val) -{ - volatile meth_regs* regs=priv->regs; - int rval; -/// DPRINTK("Trying to write value %i to reguster %i\n",val, pfyreg); - spin_lock_irq(&priv->meth_lock); - WAIT_FOR_PHY(regs,rval) - regs->phy_registers=(priv->phy_addr<<5)|(pfyreg&0x1f); - regs->phy_data=val; - udelay(25); - WAIT_FOR_PHY(regs,rval) - spin_unlock_irq(&priv->meth_lock); -} - -/* Modify phy register using given mask and value */ -static void mdio_update(meth_private* priv,int phyreg, int val, int mask) -{ - int rval; - DPRINTK("RMW value %i to PHY register %i with mask %i\n",val,phyreg,mask); - rval=mdio_read(priv,phyreg); - rval=(rval&~mask)|(val&mask); - mdio_write(priv,phyreg,rval); -} - -/* handle errata data on MDIO bus */ -//static void mdio_errata(meth_private *priv) -//{ - /* Hmmm... what the hell is phyerrata? does it come from sys init parameters in IRIX */ -//} -static int mdio_probe(meth_private *priv) -{ - int i, p2, p3; - DPRINTK("Detecting PHY kind\n"); - /* check if phy is detected already */ - if(priv->phy_addr>=0&&priv->phy_addr<32) - return 0; - spin_lock_irq(&priv->meth_lock); - for (i=0;i<32;++i){ - priv->phy_addr=(char)i; - p2=mdio_read(priv,2); -#ifdef MFE_DEBUG - p3=mdio_read(priv,3); - switch ((p2<<12)|(p3>>4)){ - case PHY_QS6612X: - DPRINTK("PHY is QS6612X\n"); - break; - case PHY_ICS1889: - DPRINTK("PHY is ICS1889\n"); - break; - case PHY_ICS1890: - DPRINTK("PHY is ICS1890\n"); - break; - case PHY_DP83840: - DPRINTK("PHY is DP83840\n"); - break; - } -#endif - if(p2!=0xffff&&p2!=0x0000){ - DPRINTK("PHY code: %x\n",(p2<<12)|(p3>>4)); - break; - } - } - spin_unlock_irq(&priv->meth_lock); - if(priv->phy_addr<32) { - return 0; - } - DPRINTK("Oopsie! PHY is not known!\n"); - priv->phy_addr=-1; - return -ENODEV; -} - -static void meth_check_link(struct net_device *dev) -{ - struct meth_private *priv = (struct meth_private *) dev->priv; - int mii_partner = mdio_read(priv, 5); - int mii_advertising = mdio_read(priv, 4); - int negotiated = mii_advertising & mii_partner; - int duplex, speed; - - if (mii_partner == 0xffff) - return; - - duplex = ((negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040)?METH_PHY_FDX:0; - speed = (negotiated & 0x0380)?METH_100MBIT:0; - - if ((priv->mode & METH_PHY_FDX) ^ duplex) - { - DPRINTK("Setting %s-duplex\n", duplex ? "full" : "half"); - if (duplex) - priv->mode |= METH_PHY_FDX; - else - priv->mode &= ~METH_PHY_FDX; - priv->regs->mac_ctrl = priv->mode; - } - - if ((priv->mode & METH_100MBIT) ^ speed) - { - DPRINTK("Setting %dMbs mode\n", speed ? 100 : 10); - if (duplex) - priv->mode |= METH_100MBIT; - else - priv->mode &= ~METH_100MBIT; - priv->regs->mac_ctrl = priv->mode; - } -} - - -static int meth_init_tx_ring(meth_private *priv) -{ - /* Init TX ring */ - DPRINTK("Initializing TX ring\n"); - priv->tx_ring = (tx_packet *) pci_alloc_consistent(NULL,TX_RING_BUFFER_SIZE,&(priv->tx_ring_dma)); - if(!priv->tx_ring) - return -ENOMEM; - memset(priv->tx_ring, 0, TX_RING_BUFFER_SIZE); - priv->tx_count = priv->tx_read = priv->tx_write = 0; - priv->regs->tx_ring_base = priv->tx_ring_dma; - priv->free_space = TX_RING_ENTRIES; - /* Now init skb save area */ - memset(priv->tx_skbs,0,sizeof(priv->tx_skbs)); - memset(priv->tx_skb_dmas,0,sizeof(priv->tx_skb_dmas)); - DPRINTK("Done with TX ring init\n"); - return 0; -} - -static int meth_init_rx_ring(meth_private *priv) -{ - int i; - DPRINTK("Initializing RX ring\n"); - for(i=0;irx_ring[i]=get_free_page(GFP_KERNEL))) - return -ENOMEM; - DPRINTK("\t2:\t%i\n",i);*/ - priv->rx_ring[i]=(rx_packet*)pci_alloc_consistent(NULL,METH_RX_BUFF_SIZE,&(priv->rx_ring_dmas[i])); - /* I'll need to re-sync it after each RX */ - DPRINTK("\t%p\n",priv->rx_ring[i]); - priv->regs->rx_fifo=priv->rx_ring_dmas[i]; - } - priv->rx_write = 0; - DPRINTK("Done with RX ring\n"); - return 0; -} -static void meth_free_tx_ring(meth_private *priv) -{ - int i; - - /* Remove any pending skb */ - for (i = 0; i < TX_RING_ENTRIES; i++) { - if (priv->tx_skbs[i]) - dev_kfree_skb(priv->tx_skbs[i]); - priv->tx_skbs[i] = NULL; - } - pci_free_consistent(NULL, - TX_RING_BUFFER_SIZE, - priv->tx_ring, - priv->tx_ring_dma); -} -static void meth_free_rx_ring(meth_private *priv) -{ - int i; - - for(i=0;irx_ring[i], - priv->rx_ring_dmas[i]); -} - -int meth_reset(struct net_device *dev) -{ - struct meth_private *priv = (struct meth_private *) dev->priv; - - /* Reset card */ - priv->regs->mac_ctrl = SGI_MAC_RESET; - priv->regs->mac_ctrl = 0; - udelay(25); - DPRINTK("MAC control after reset: %016lx\n", priv->regs->mac_ctrl); - - /* Load ethernet address */ - load_eaddr(dev, priv->regs); - /* Should load some "errata", but later */ - - /* Check for device */ - if(mdio_probe(priv) < 0) { - DPRINTK("Unable to find PHY\n"); - return -ENODEV; - } - - /* Initial mode -- 10|Half-duplex|Accept normal packets */ - priv->mode=METH_ACCEPT_MCAST|METH_DEFAULT_IPG; - if(dev->flags | IFF_PROMISC) - priv->mode |= METH_PROMISC; - priv->regs->mac_ctrl = priv->mode; - - /* Autonegociate speed and duplex mode */ - meth_check_link(dev); - - /* Now set dma control, but don't enable DMA, yet */ - priv->regs->dma_ctrl= (4 << METH_RX_OFFSET_SHIFT) | - (RX_RING_ENTRIES << METH_RX_DEPTH_SHIFT); - - return(0); -} - -/*============End Helper Routines=====================*/ - -/* - * Open and close - */ - -int meth_open(struct net_device *dev) -{ - meth_private *priv=dev->priv; - volatile meth_regs *regs=priv->regs; - - MOD_INC_USE_COUNT; - - /* Start DMA */ - regs->dma_ctrl|= - METH_DMA_TX_EN|/*METH_DMA_TX_INT_EN|*/ - METH_DMA_RX_EN|METH_DMA_RX_INT_EN; - - if(request_irq(dev->irq,meth_interrupt,SA_SHIRQ,meth_str,dev)){ - printk(KERN_ERR "%s: Can't get irq %d\n", dev->name, dev->irq); - return -EAGAIN; - } - netif_start_queue(dev); - DPRINTK("Opened... DMA control=0x%08lx\n", regs->dma_ctrl); - return 0; -} - -int meth_release(struct net_device *dev) -{ - netif_stop_queue(dev); /* can't transmit any more */ - /* shut down dma */ - ((meth_private*)(dev->priv))->regs->dma_ctrl&= - ~(METH_DMA_TX_EN|METH_DMA_TX_INT_EN| - METH_DMA_RX_EN|METH_DMA_RX_INT_EN); - free_irq(dev->irq, dev); - MOD_DEC_USE_COUNT; - return 0; -} - -/* - * Configuration changes (passed on by ifconfig) - */ -int meth_config(struct net_device *dev, struct ifmap *map) -{ - if (dev->flags & IFF_UP) /* can't act on a running interface */ - return -EBUSY; - - /* Don't allow changing the I/O address */ - if (map->base_addr != dev->base_addr) { - printk(KERN_WARNING "meth: Can't change I/O address\n"); - return -EOPNOTSUPP; - } - - /* Allow changing the IRQ */ - if (map->irq != dev->irq) { - printk(KERN_WARNING "meth: Can't change IRQ\n"); - return -EOPNOTSUPP; - } - DPRINTK("Configured\n"); - - /* ignore other fields */ - return 0; -} - -/* - * Receive a packet: retrieve, encapsulate and pass over to upper levels - */ -void meth_rx(struct net_device* dev) -{ - struct sk_buff *skb; - struct meth_private *priv = (struct meth_private *) dev->priv; - rx_packet *rxb; - DPRINTK("RX...\n"); - // TEMP while((rxb=priv->rx_ring[priv->rx_write])->status.raw&0x8000000000000000){ - while((rxb=priv->rx_ring[priv->rx_write])->status.raw&0x8000000000000000){ - int len=rxb->status.parsed.rx_len - 4; /* omit CRC */ - DPRINTK("(%i)\n",priv->rx_write); - /* length sanity check */ - if(len < 60 || len > 1518) { - printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2x.\n", - dev->name, priv->rx_write, rxb->status.raw); - priv->stats.rx_errors++; - priv->stats.rx_length_errors++; - } - if(!(rxb->status.raw&METH_RX_STATUS_ERRORS)){ - skb=alloc_skb(len+2,GFP_ATOMIC);/* Should be atomic -- we are in interrupt */ - if(!skb){ - /* Ouch! No memory! Drop packet on the floor */ - DPRINTK("!!!>>>Ouch! Not enough Memory for RX buffer!\n"); - priv->stats.rx_dropped++; - } else { - skb_reserve(skb, 2); /* align IP on 16B boundary */ - memcpy(skb_put(skb, len), rxb->buf, len); - /* Write metadata, and then pass to the receive level */ - skb->dev = dev; - skb->protocol = eth_type_trans(skb, dev); - //skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */ - - DPRINTK("passing packet\n"); - DPRINTK("len = %d rxb->status = %x\n", - len, rxb->status.raw); - netif_rx(skb); - dev->last_rx = jiffies; - priv->stats.rx_packets++; - priv->stats.rx_bytes+=len; - DPRINTK("There we go... Whew...\n"); - } - } - priv->regs->rx_fifo=priv->rx_ring_dmas[priv->rx_write]; - rxb->status.raw=0; - priv->rx_write=(priv->rx_write+1)&(RX_RING_ENTRIES-1); - } -} - -static int meth_tx_full(struct net_device *dev) -{ - struct meth_private *priv = (struct meth_private *) dev->priv; - - return(priv->tx_count >= TX_RING_ENTRIES-1); -} - -void meth_tx_cleanup(struct net_device* dev, int rptr) -{ - meth_private *priv=dev->priv; - tx_packet* status; - struct sk_buff *skb; - - spin_lock(&priv->meth_lock); - - /* Stop DMA */ - priv->regs->dma_ctrl &= ~(METH_DMA_TX_INT_EN); - - while(priv->tx_read != rptr){ - skb = priv->tx_skbs[priv->tx_read]; - status = &priv->tx_ring[priv->tx_read]; - if(!status->header.res.sent) - break; - if(status->header.raw & METH_TX_STATUS_DONE) { - priv->stats.tx_packets++; - priv->stats.tx_bytes += skb->len; - } - dev_kfree_skb_irq(skb); - priv->tx_skbs[priv->tx_read] = NULL; - status->header.raw = 0; - priv->tx_read = (priv->tx_read+1)&(TX_RING_ENTRIES-1); - priv->tx_count --; - } - - /* wake up queue if it was stopped */ - if (netif_queue_stopped(dev) && ! meth_tx_full(dev)) { - netif_wake_queue(dev); - } - - spin_unlock(priv->meth_lock); -} - -/* - * The typical interrupt entry point - */ -void meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs) -{ - struct meth_private *priv; - union { - u32 reg; /*Whole status register */ - struct { - u32 : 2, - rx_seq : 5, - tx_read : 9, - - rx_read : 8, - int_mask: 8; - } parsed; - } status; - /* - * As usual, check the "device" pointer for shared handlers. - * Then assign "struct device *dev" - */ - struct net_device *dev = (struct net_device *)dev_id; - /* ... and check with hw if it's really ours */ - - if (!dev /*paranoid*/ ) return; - - /* Lock the device */ - priv = (struct meth_private *) dev->priv; - - status.reg = priv->regs->int_flags; - - DPRINTK("Interrupt, status %08x...\n",status.reg); - if (status.parsed.int_mask & METH_INT_RX_THRESHOLD) { - /* send it to meth_rx for handling */ - meth_rx(dev); - } - - if (status.parsed.int_mask & (METH_INT_TX_EMPTY|METH_INT_TX_PKT)) { - /* a transmission is over: free the skb */ - meth_tx_cleanup(dev, status.parsed.tx_read); - } - /* check for errors too... */ - if (status.parsed.int_mask & (METH_INT_TX_LINK_FAIL)) - printk(KERN_WARNING "meth: link failure\n"); - if (status.parsed.int_mask & (METH_INT_MEM_ERROR)) - printk(KERN_WARNING "meth: memory error\n"); - if (status.parsed.int_mask & (METH_INT_TX_ABORT)) - printk(KERN_WARNING "meth: aborted\n"); - DPRINTK("Interrupt handling done...\n"); - - priv->regs->int_flags=status.reg&0xff; /* clear interrupts */ -} - -/* - * Transmits packets that fit into TX descriptor (are <=120B) - */ -static void meth_tx_short_prepare(meth_private* priv, struct sk_buff* skb) -{ - tx_packet *desc=&priv->tx_ring[priv->tx_write]; - int len = (skb->lenlen; - - DPRINTK("preparing short packet\n"); - /* maybe I should set whole thing to 0 first... */ - memcpy(desc->data.dt+(120-len),skb->data,skb->len); - if(skb->len < len) - memset(desc->data.dt+120-len+skb->len,0,len-skb->len); - desc->header.raw=METH_TX_CMD_INT_EN|(len-1)|((128-len)<<16); - DPRINTK("desc=%016lx\n",desc->header.raw); -} -#define TX_CATBUF1 BIT(25) -static void meth_tx_1page_prepare(meth_private* priv, struct sk_buff* skb) -{ - tx_packet *desc=&priv->tx_ring[priv->tx_write]; - void *buffer_data = (void *)(((u64)skb->data + 7ULL) & (~7ULL)); - int unaligned_len = (int)((u64)buffer_data - (u64)skb->data); - int buffer_len = skb->len - unaligned_len; - dma_addr_t catbuf; - - DPRINTK("preparing 1 page...\n"); - DPRINTK("length=%d data=%p\n", skb->len, skb->data); - DPRINTK("unaligned_len=%d\n", unaligned_len); - DPRINTK("buffer_data=%p buffer_len=%d\n", - buffer_data, - buffer_len); - - desc->header.raw=METH_TX_CMD_INT_EN|TX_CATBUF1|(skb->len-1); - - /* unaligned part */ - if(unaligned_len){ - memcpy(desc->data.dt+(120-unaligned_len), - skb->data, unaligned_len); - desc->header.raw |= (128-unaligned_len) << 16; - } - - /* first page */ - catbuf = pci_map_single(NULL, - buffer_data, - buffer_len, - PCI_DMA_TODEVICE); - DPRINTK("catbuf=%x\n", catbuf); - desc->data.cat_buf[0].form.start_addr = catbuf >> 3; - desc->data.cat_buf[0].form.len = buffer_len-1; - DPRINTK("desc=%016lx\n",desc->header.raw); - DPRINTK("cat_buf[0].raw=%016lx\n",desc->data.cat_buf[0].raw); -} -#define TX_CATBUF2 BIT(26) -static void meth_tx_2page_prepare(meth_private* priv, struct sk_buff* skb) -{ - tx_packet *desc=&priv->tx_ring[priv->tx_write]; - void *buffer1_data = (void *)(((u64)skb->data + 7ULL) & (~7ULL)); - void *buffer2_data = (void *)PAGE_ALIGN((u64)skb->data); - int unaligned_len = (int)((u64)buffer1_data - (u64)skb->data); - int buffer1_len = (int)((u64)buffer2_data - (u64)buffer1_data); - int buffer2_len = skb->len - buffer1_len - unaligned_len; - dma_addr_t catbuf1, catbuf2; - - DPRINTK("preparing 2 pages... \n"); - DPRINTK("length=%d data=%p\n", skb->len, skb->data); - DPRINTK("unaligned_len=%d\n", unaligned_len); - DPRINTK("buffer1_data=%p buffer1_len=%d\n", - buffer1_data, - buffer1_len); - DPRINTK("buffer2_data=%p buffer2_len=%d\n", - buffer2_data, - buffer2_len); - - desc->header.raw=METH_TX_CMD_INT_EN|TX_CATBUF1|TX_CATBUF2|(skb->len-1); - /* unaligned part */ - if(unaligned_len){ - memcpy(desc->data.dt+(120-unaligned_len), - skb->data, unaligned_len); - desc->header.raw |= (128-unaligned_len) << 16; - } - - /* first page */ - catbuf1 = pci_map_single(NULL, - buffer1_data, - buffer1_len, - PCI_DMA_TODEVICE); - DPRINTK("catbuf1=%x\n", catbuf1); - desc->data.cat_buf[0].form.start_addr = catbuf1 >> 3; - desc->data.cat_buf[0].form.len = buffer1_len-1; - /* second page */ - catbuf2 = pci_map_single(NULL, - buffer2_data, - buffer2_len, - PCI_DMA_TODEVICE); - DPRINTK("catbuf2=%x\n", catbuf2); - desc->data.cat_buf[1].form.start_addr = catbuf2 >> 3; - desc->data.cat_buf[1].form.len = buffer2_len-1; - DPRINTK("desc=%016lx\n",desc->header.raw); - DPRINTK("cat_buf[0].raw=%016lx\n",desc->data.cat_buf[0].raw); - DPRINTK("cat_buf[1].raw=%016lx\n",desc->data.cat_buf[1].raw); -} - - -void meth_add_to_tx_ring(meth_private *priv, struct sk_buff* skb) -{ - DPRINTK("Transmitting data...\n"); - if(skb->len <= 120) { - /* Whole packet fits into descriptor */ - meth_tx_short_prepare(priv,skb); - } else if(PAGE_ALIGN((u64)skb->data) != - PAGE_ALIGN((u64)skb->data+skb->len-1)) { - /* Packet crosses page boundary */ - meth_tx_2page_prepare(priv,skb); - } else { - /* Packet is in one page */ - meth_tx_1page_prepare(priv,skb); - } - - /* Remember the skb, so we can free it at interrupt time */ - priv->tx_skbs[priv->tx_write] = skb; - priv->tx_write = (priv->tx_write+1) & (TX_RING_ENTRIES-1); - priv->regs->tx_info.wptr = priv->tx_write; - priv->tx_count ++; - /* Enable DMA transfer */ - priv->regs->dma_ctrl |= METH_DMA_TX_INT_EN; -} - -/* - * Transmit a packet (called by the kernel) - */ -int meth_tx(struct sk_buff *skb, struct net_device *dev) -{ - struct meth_private *priv = (struct meth_private *) dev->priv; - - spin_lock_irq(&priv->meth_lock); - - meth_add_to_tx_ring(priv, skb); - dev->trans_start = jiffies; /* save the timestamp */ - - /* If TX ring is full, tell the upper layer to stop sending packets */ - if (meth_tx_full(dev)) { - DPRINTK("TX full: stopping\n"); - netif_stop_queue(dev); - } - - spin_unlock_irq(&priv->meth_lock); - - return 0; -} - -/* - * Deal with a transmit timeout. - */ - -void meth_tx_timeout (struct net_device *dev) -{ - struct meth_private *priv = (struct meth_private *) dev->priv; - - printk(KERN_WARNING "%s: transmit timed out\n", dev->name); - - /* Protect against concurrent rx interrupts */ - spin_lock_irq(&priv->meth_lock); - - /* Try to reset the adaptor. */ - meth_reset(dev); - - priv->stats.tx_errors++; - - /* Clear all rings */ - meth_free_tx_ring(priv); - meth_free_rx_ring(priv); - meth_init_tx_ring(priv); - meth_init_rx_ring(priv); - - /* Restart dma */ - priv->regs->dma_ctrl|=METH_DMA_TX_EN|METH_DMA_RX_EN|METH_DMA_RX_INT_EN; - - /* Enable interrupt */ - spin_unlock_irq(&priv->meth_lock); - - dev->trans_start = jiffies; - netif_wake_queue(dev); - - return; -} - -/* - * Ioctl commands - */ -int meth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - - DPRINTK("ioctl\n"); - return 0; -} - -/* - * Return statistics to the caller - */ -struct net_device_stats *meth_stats(struct net_device *dev) -{ - struct meth_private *priv = (struct meth_private *) dev->priv; - return &priv->stats; -} - -/* - * The init function (sometimes called probe). - * It is invoked by register_netdev() - */ -int meth_init(struct net_device *dev) -{ - meth_private *priv; - int ret; - /* - * Then, assign other fields in dev, using ether_setup() and some - * hand assignments - */ - ether_setup(dev); /* assign some of the fields */ - - dev->open = meth_open; - dev->stop = meth_release; - dev->set_config = meth_config; - dev->hard_start_xmit = meth_tx; - dev->do_ioctl = meth_ioctl; - dev->get_stats = meth_stats; -#ifdef HAVE_TX_TIMEOUT - dev->tx_timeout = meth_tx_timeout; - dev->watchdog_timeo = timeout; -#endif - dev->irq = MACE_ETHERNET_IRQ; - SET_MODULE_OWNER(dev); - - /* - * Then, allocate the priv field. This encloses the statistics - * and a few private fields. - */ - priv = kmalloc(sizeof(struct meth_private), GFP_KERNEL); - if (priv == NULL) - return -ENOMEM; - dev->priv=priv; - memset(priv, 0, sizeof(struct meth_private)); - spin_lock_init(&((struct meth_private *) dev->priv)->meth_lock); - /* - * Make the usual checks: check_region(), probe irq, ... -ENODEV - * should be returned if no device found. No resource should be - * grabbed: this is done on open(). - */ - priv->regs=(meth_regs*)SGI_MFE; - dev->base_addr=SGI_MFE; - priv->phy_addr = -1; /* No phy is known yet... */ - - /* Initialize the hardware */ - if((ret=meth_reset(dev)) < 0) - return ret; - - /* Allocate the ring buffers */ - if((ret=meth_init_tx_ring(priv))<0||(ret=meth_init_rx_ring(priv))<0){ - meth_free_tx_ring(priv); - meth_free_rx_ring(priv); - return ret; - } - - printk("SGI O2 Fast Ethernet rev. %ld\n", priv->regs->mac_ctrl >> 29); - - return 0; -} - -/* - * The devices - */ - -struct net_device meth_devs[1] = { - { init: meth_init, } /* init, nothing more */ -}; - -/* - * Finally, the module stuff - */ - -int meth_init_module(void) -{ - int result, device_present = 0; - - strcpy(meth_devs[0].name, "eth%d"); - - if ( (result = register_netdev(meth_devs)) ) - printk("meth: error %i registering device \"%s\"\n", - result, meth_devs->name); - else device_present++; -#ifndef METH_DEBUG - EXPORT_NO_SYMBOLS; -#endif - - return device_present ? 0 : -ENODEV; -} - -void meth_cleanup(void) -{ - kfree(meth_devs->priv); - unregister_netdev(meth_devs); - return; -} - -module_init(meth_init_module); -module_exit(meth_cleanup); Index: drivers/net/meth.h =================================================================== RCS file: drivers/net/meth.h diff -N drivers/net/meth.h --- drivers/net/meth.h 22 Jul 2004 19:49:33 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,273 +0,0 @@ - -/* - * snull.h -- definitions for the network module - * - * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet - * Copyright (C) 2001 O'Reilly & Associates - * - * The source code in this file can be freely used, adapted, - * and redistributed in source or binary form, so long as an - * acknowledgment appears in derived source files. The citation - * should list that the code comes from the book "Linux Device - * Drivers" by Alessandro Rubini and Jonathan Corbet, published - * by O'Reilly & Associates. No warranty is attached; - * we cannot take responsibility for errors or fitness for use. - */ - -/* version dependencies have been confined to a separate file */ - -#define SGI_MFE (MACE_BASE+MACE_ENET) -/* (0xBF280000)*/ - -/* Tunable parameters */ -#define TX_RING_ENTRIES 64 /* 64-512?*/ - -#define RX_RING_ENTRIES 16 /* Do not change */ -/* Internal constants */ -#define TX_RING_BUFFER_SIZE (TX_RING_ENTRIES*sizeof(tx_packet)) -#define RX_BUFFER_SIZE 1546 /* ethenet packet size */ -#define METH_RX_BUFF_SIZE 4096 -#define RX_BUFFER_OFFSET (sizeof(rx_status_vector)+2) /* staus vector + 2 bytes of padding */ -#define RX_BUCKET_SIZE 256 - - - -/* For more detailed explanations of what each field menas, - see Nick's great comments to #defines below (or docs, if - you are lucky enough toget hold of them :)*/ - -/* tx status vector is written over tx command header upon - dma completion. */ - -typedef struct tx_status_vector { - u64 sent:1; /* always set to 1...*/ - u64 pad0:34;/* always set to 0 */ - u64 flags:9; /*I'm too lazy to specify each one separately at the moment*/ - u64 col_retry_cnt:4; /*collision retry count*/ - u64 len:16; /*Transmit length in bytes*/ -} tx_status_vector; - -/* - * Each packet is 128 bytes long. - * It consists of header, 0-3 concatination - * buffer pointers and up to 120 data bytes. - */ -typedef struct tx_packet_hdr { - u64 pad1:36; /*should be filled with 0 */ - u64 cat_ptr3_valid:1, /*Concatination pointer valid flags*/ - cat_ptr2_valid:1, - cat_ptr1_valid:1; - u64 tx_int_flag:1; /*Generate TX intrrupt when packet has been sent*/ - u64 term_dma_flag:1; /*Terminate transmit DMA on transmit abort conditions*/ - u64 data_offset:7; /*Starting byte offset in ring data block*/ - u64 data_len:16; /*Length of valid data in bytes-1*/ -} tx_packet_hdr; -typedef union tx_cat_ptr { - struct { - u64 pad2:16; /* should be 0 */ - u64 len:16; /*length of buffer data - 1*/ - u64 start_addr:29; /*Physical starting address*/ - u64 pad1:3; /* should be zero */ - } form; - u64 raw; -} tx_cat_ptr; - -typedef struct tx_packet { - union { - tx_packet_hdr header; - tx_status_vector res; - u64 raw; - }header; - union { - tx_cat_ptr cat_buf[3]; - char dt[120]; - } data; -} tx_packet; - -typedef union rx_status_vector { - struct { - u64 pad1:1;/*fill it with ones*/ - u64 pad2:15;/*fill with 0*/ - u64 ip_chk_sum:16; - u64 seq_num:5; - u64 mac_addr_match:1; - u64 mcast_addr_match:1; - u64 carrier_event_seen:1; - u64 bad_packet:1; - u64 long_event_seen:1; - u64 invalid_preamble:1; - u64 broadcast:1; - u64 multicast:1; - u64 crc_error:1; - u64 huh:1;/*???*/ - u64 rx_code_violation:1; - u64 rx_len:16; - } parsed; - u64 raw; -} rx_status_vector; - -typedef struct rx_packet { - rx_status_vector status; - u64 pad[3]; /* For whatever reason, there needs to be 4 double-word offset */ - u16 pad2; - char buf[METH_RX_BUFF_SIZE-sizeof(rx_status_vector)-3*sizeof(u64)-sizeof(u16)];/* data */ -} rx_packet; - -typedef struct meth_regs { - u64 mac_ctrl; /*0x00,rw,31:0*/ - u64 int_flags; /*0x08,rw,30:0*/ - u64 dma_ctrl; /*0x10,rw,15:0*/ - u64 timer; /*0x18,rw,5:0*/ - u64 int_tx; /*0x20,wo,0:0*/ - u64 int_rx; /*0x28,wo,9:4*/ - struct { - u32 tx_info_pad; - u32 rptr:16,wptr:16; - } tx_info; /*0x30,rw,31:0*/ - u64 tx_info_al; /*0x38,rw,31:0*/ - struct { - u32 rx_buff_pad1; - u32 rx_buff_pad2:8, - wptr:8, - rptr:8, - depth:8; - } rx_buff; /*0x40,ro,23:0*/ - u64 rx_buff_al1; /*0x48,ro,23:0*/ - u64 rx_buff_al2; /*0x50,ro,23:0*/ - u64 int_update; /*0x58,wo,31:0*/ - u32 phy_data_pad; - u32 phy_data; /*0x60,rw,16:0*/ - u32 phy_reg_pad; - u32 phy_registers; /*0x68,rw,9:0*/ - u64 phy_trans_go; /*0x70,wo,0:0*/ - u64 backoff_seed; /*0x78,wo,10:0*/ - u64 imq_reserved[4];/*0x80,ro,64:0(x4)*/ - /*===================================*/ - u64 mac_addr; /*0xA0,rw,47:0, I think it's MAC address, but I'm not sure*/ - u64 mcast_addr; /*0xA8,rw,47:0, This seems like secondary MAC address*/ - u64 mcast_filter; /*0xB0,rw,63:0*/ - u64 tx_ring_base; /*0xB8,rw,31:13*/ - /* Following are read-only debugging info register */ - u64 tx_pkt1_hdr; /*0xC0,ro,63:0*/ - u64 tx_pkt1_ptr[3]; /*0xC8,ro,63:0(x3)*/ - u64 tx_pkt2_hdr; /*0xE0,ro,63:0*/ - u64 tx_pkt2_ptr[3]; /*0xE8,ro,63:0(x3)*/ - /*===================================*/ - u32 rx_pad; - u32 rx_fifo; - u64 reserved[31]; -}meth_regs; - - /* Bits in METH_MAC */ - -#define SGI_MAC_RESET BIT(0) /* 0: MAC110 active in run mode, 1: Global reset signal to MAC110 core is active */ -#define METH_PHY_FDX BIT(1) /* 0: Disable full duplex, 1: Enable full duplex */ -#define METH_PHY_LOOP BIT(2) /* 0: Normal operation, follows 10/100mbit and M10T/MII select, 1: loops internal MII bus */ - /* selects ignored */ -#define METH_100MBIT BIT(3) /* 0: 10meg mode, 1: 100meg mode */ -#define METH_PHY_MII BIT(4) /* 0: MII selected, 1: SIA selected */ - /* Note: when loopback is set this bit becomes collision control. Setting this bit will */ - /* cause a collision to be reported. */ - - /* Bits 5 and 6 are used to determine the the Destination address filter mode */ -#define METH_ACCEPT_MY 0 /* 00: Accept PHY address only */ -#define METH_ACCEPT_MCAST 0x20 /* 01: Accept physical, broadcast, and multicast filter matches only */ -#define METH_ACCEPT_AMCAST 0x40 /* 10: Accept physical, broadcast, and all multicast packets */ -#define METH_PROMISC 0x60 /* 11: Promiscious mode */ - -#define METH_PHY_LINK_FAIL BIT(7) /* 0: Link failure detection disabled, 1: Hardware scans for link failure in PHY */ - -#define METH_MAC_IPG 0x1ffff00 - -#define METH_DEFAULT_IPG ((17<<15) | (11<<22) | (21<<8)) - /* 0x172e5c00 */ /* 23, 23, 23 */ /*0x54A9500 *//*21,21,21*/ - /* Bits 8 through 14 are used to determine Inter-Packet Gap between "Back to Back" packets */ - /* The gap depends on the clock speed of the link, 80ns per increment for 100baseT, 800ns */ - /* per increment for 10BaseT */ - - /* Bits 15 through 21 are used to determine IPGR1 */ - - /* Bits 22 through 28 are used to determine IPGR2 */ - -#define METH_REV_SHIFT 29 /* Bits 29 through 31 are used to determine the revision */ - /* 000: Inital revision */ - /* 001: First revision, Improved TX concatenation */ - - -/* DMA control bits */ -#define METH_RX_OFFSET_SHIFT 12 /* Bits 12:14 of DMA control register indicate starting offset of packet data for RX operation */ -#define METH_RX_DEPTH_SHIFT 4 /* Bits 8:4 define RX fifo depth -- when # of RX fifo entries != depth, interrupt is generted */ - -#define METH_DMA_TX_EN BIT(1) /* enable TX DMA */ -#define METH_DMA_TX_INT_EN BIT(0) /* enable TX Buffer Empty interrupt */ -#define METH_DMA_RX_EN BIT(15) /* Enable RX */ -#define METH_DMA_RX_INT_EN BIT(9) /* Enable interrupt on RX packet */ - - -/* RX status bits */ - -#define METH_RX_ST_RCV_CODE_VIOLATION BIT(16) -#define METH_RX_ST_DRBL_NBL BIT(17) -#define METH_RX_ST_CRC_ERR BIT(18) -#define METH_RX_ST_MCAST_PKT BIT(19) -#define METH_RX_ST_BCAST_PKT BIT(20) -#define METH_RX_ST_INV_PREAMBLE_CTX BIT(21) -#define METH_RX_ST_LONG_EVT_SEEN BIT(22) -#define METH_RX_ST_BAD_PACKET BIT(23) -#define METH_RX_ST_CARRIER_EVT_SEEN BIT(24) -#define METH_RX_ST_MCAST_FILTER_MATCH BIT(25) -#define METH_RX_ST_PHYS_ADDR_MATCH BIT(26) - -#define METH_RX_STATUS_ERRORS \ - ( \ - METH_RX_ST_RCV_CODE_VIOLATION| \ - METH_RX_ST_CRC_ERR| \ - METH_RX_ST_INV_PREAMBLE_CTX| \ - METH_RX_ST_LONG_EVT_SEEN| \ - METH_RX_ST_BAD_PACKET| \ - METH_RX_ST_CARRIER_EVT_SEEN \ - ) - /* Bits in METH_INT */ - /* Write _1_ to corresponding bit to clear */ -#define METH_INT_TX_EMPTY BIT(0) /* 0: No interrupt pending, 1: The TX ring buffer is empty */ -#define METH_INT_TX_PKT BIT(1) /* 0: No interrupt pending */ - /* 1: A TX message had the INT request bit set, the packet has been sent. */ -#define METH_INT_TX_LINK_FAIL BIT(2) /* 0: No interrupt pending, 1: PHY has reported a link failure */ -#define METH_INT_MEM_ERROR BIT(3) /* 0: No interrupt pending */ - /* 1: A memory error occurred durring DMA, DMA stopped, Fatal */ -#define METH_INT_TX_ABORT BIT(4) /* 0: No interrupt pending, 1: The TX aborted operation, DMA stopped, FATAL */ -#define METH_INT_RX_THRESHOLD BIT(5) /* 0: No interrupt pending, 1: Selected receive threshold condition Valid */ -#define METH_INT_RX_UNDERFLOW BIT(6) /* 0: No interrupt pending, 1: FIFO was empty, packet could not be queued */ -#define METH_INT_RX_OVERFLOW BIT(7) /* 0: No interrupt pending, 1: DMA FIFO Overflow, DMA stopped, FATAL */ - -#define METH_INT_RX_RPTR_MASK 0x0001F00 /* Bits 8 through 12 alias of RX read-pointer */ - - /* Bits 13 through 15 are always 0. */ - -#define METH_INT_TX_RPTR_MASK 0x1FF0000 /* Bits 16 through 24 alias of TX read-pointer */ - -#define METH_INT_SEQ_MASK 0x2E000000 /* Bits 25 through 29 are the starting seq number for the message at the */ - /* top of the queue */ - -#define METH_ERRORS ( \ - METH_INT_RX_OVERFLOW| \ - METH_INT_RX_UNDERFLOW| \ - METH_INT_MEM_ERROR| \ - METH_INT_TX_ABORT) - -#define METH_INT_MCAST_HASH BIT(30) /* If RX DMA is enabled the hash select logic output is latched here */ - -/* TX status bits */ -#define METH_TX_STATUS_DONE BIT(23) /* Packet was transmitted successfully */ - -/* Tx command header bits */ -#define METH_TX_CMD_INT_EN BIT(24) /* Generate TX interrupt when packet is sent */ - -/* Phy MDIO interface busy flag */ -#define MDIO_BUSY BIT(16) -#define MDIO_DATA_MASK 0xFFFF -/* PHY defines */ -#define PHY_QS6612X 0x0181441 /* Quality TX */ -#define PHY_ICS1889 0x0015F41 /* ICS FX */ -#define PHY_ICS1890 0x0015F42 /* ICS TX */ -#define PHY_DP83840 0x20005C0 /* National TX */ Index: drivers/net/myri_sbus.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/myri_sbus.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/myri_sbus.c 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/myri_sbus.c 4 Aug 2004 01:29:10 -0000 1.2 @@ -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) Index: drivers/net/natsemi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/natsemi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/natsemi.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/natsemi.c 4 Aug 2004 01:29:10 -0000 1.2 @@ -164,6 +164,7 @@ #include #include #include +#include #include /* Processor type for cache alignment. */ #include #include @@ -174,6 +175,8 @@ #define DRV_VERSION "1.07+LK1.0.17" #define DRV_RELDATE "Sep 27, 2002" +#define RX_OFFSET 2 + /* Updated to recommendations in pci-skeleton v2.03. */ /* The user-configurable values. @@ -365,7 +368,7 @@ { "NatSemi DP8381[56]", PCI_IOTYPE }, }; -static struct pci_device_id natsemi_pci_tbl[] __devinitdata = { +static struct pci_device_id natsemi_pci_tbl[] = { { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815, PCI_ANY_ID, PCI_ANY_ID, }, { 0, }, }; @@ -695,7 +698,7 @@ static void reinit_ring(struct net_device *dev); static void init_registers(struct net_device *dev); static int start_tx(struct sk_buff *skb, struct net_device *dev); -static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs); +static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs); static void netdev_error(struct net_device *dev, int intr_status); static void netdev_rx(struct net_device *dev); static void netdev_tx_done(struct net_device *dev); @@ -763,19 +766,13 @@ SET_MODULE_OWNER(dev); i = pci_request_regions(pdev, dev->name); - if (i) { - kfree(dev); - return i; - } + if (i) + goto err_pci_request_regions; - { - void *mmio = ioremap (ioaddr, iosize); - if (!mmio) { - pci_release_regions(pdev); - kfree(dev); - return -ENOMEM; - } - ioaddr = (unsigned long) mmio; + ioaddr = (unsigned long) ioremap (ioaddr, iosize); + if (!ioaddr) { + i = -ENOMEM; + goto err_ioremap; } /* Work around the dropped serial bit. */ @@ -833,13 +830,9 @@ dev->mtu = mtu; i = register_netdev(dev); - if (i) { - pci_release_regions(pdev); - unregister_netdev(dev); - kfree(dev); - pci_set_drvdata(pdev, NULL); - return i; - } + if (i) + goto err_register_netdev; + netif_carrier_off(dev); if (netif_msg_drv(np)) { @@ -876,6 +869,17 @@ return 0; + + err_register_netdev: + iounmap ((void *) dev->base_addr); + + err_ioremap: + pci_release_regions(pdev); + pci_set_drvdata(pdev, NULL); + + err_pci_request_regions: + free_netdev(dev); + return i; } @@ -1464,13 +1468,14 @@ struct sk_buff *skb; int entry = np->dirty_rx % RX_RING_SIZE; if (np->rx_skbuff[entry] == NULL) { - skb = dev_alloc_skb(np->rx_buf_sz); + unsigned int buflen = np->rx_buf_sz + RX_OFFSET; + skb = dev_alloc_skb(buflen); np->rx_skbuff[entry] = skb; if (skb == NULL) break; /* Better luck next round. */ skb->dev = dev; /* Mark as being used by this device. */ np->rx_dma[entry] = pci_map_single(np->pci_dev, - skb->data, skb->len, PCI_DMA_FROMDEVICE); + skb->tail, buflen, PCI_DMA_FROMDEVICE); np->rx_ring[entry].addr = cpu_to_le32(np->rx_dma[entry]); } np->rx_ring[entry].cmd_status = cpu_to_le32(np->rx_buf_sz); @@ -1528,7 +1533,7 @@ for (i = 0; i < TX_RING_SIZE; i++) { if (np->tx_skbuff[i]) { pci_unmap_single(np->pci_dev, - np->rx_dma[i], np->rx_skbuff[i]->len, + np->tx_dma[i], np->tx_skbuff[i]->len, PCI_DMA_TODEVICE); dev_kfree_skb(np->tx_skbuff[i]); np->stats.tx_dropped++; @@ -1540,6 +1545,7 @@ static void drain_ring(struct net_device *dev) { struct netdev_private *np = dev->priv; + unsigned int buflen = np->rx_buf_sz + RX_OFFSET; int i; /* Free all the skbuffs in the Rx queue. */ @@ -1548,7 +1554,7 @@ np->rx_ring[i].addr = 0xBADF00D0; /* An invalid address. */ if (np->rx_skbuff[i]) { pci_unmap_single(np->pci_dev, - np->rx_dma[i], np->rx_skbuff[i]->len, + np->rx_dma[i], buflen, PCI_DMA_FROMDEVICE); dev_kfree_skb(np->rx_skbuff[i]); } @@ -1679,15 +1685,16 @@ /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) +static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) { struct net_device *dev = dev_instance; struct netdev_private *np = dev->priv; long ioaddr = dev->base_addr; int boguscnt = max_interrupt_work; + unsigned int handled = 0; if (np->hands_off) - return; + return IRQ_NONE; do { /* Reading automatically acknowledges all int sources. */ u32 intr_status = readl(ioaddr + IntrStatus); @@ -1700,6 +1707,7 @@ if (intr_status == 0) break; + handled = 1; if (intr_status & (IntrRxDone | IntrRxIntr | RxStatusFIFOOver | @@ -1730,6 +1738,8 @@ if (netif_msg_intr(np)) printk(KERN_DEBUG "%s: exiting interrupt.\n", dev->name); + + return IRQ_RETVAL(handled); } /* This routine is logically part of the interrupt handler, but separated @@ -1740,6 +1750,7 @@ int entry = np->cur_rx % RX_RING_SIZE; int boguscnt = np->dirty_rx + RX_RING_SIZE - np->cur_rx; s32 desc_status = le32_to_cpu(np->rx_head_desc->cmd_status); + unsigned int buflen = np->rx_buf_sz + RX_OFFSET; /* If the driver owns the next entry it's a new packet. Send it up. */ while (desc_status < 0) { /* e.g. & DescOwn */ @@ -1778,13 +1789,13 @@ /* Check if the packet is long enough to accept * without copying to a minimally-sized skbuff. */ if (pkt_len < rx_copybreak - && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { + && (skb = dev_alloc_skb(pkt_len + RX_OFFSET)) != NULL) { skb->dev = dev; /* 16 byte align the IP header */ - skb_reserve(skb, 2); + skb_reserve(skb, RX_OFFSET); pci_dma_sync_single(np->pci_dev, np->rx_dma[entry], - np->rx_skbuff[entry]->len, + buflen, PCI_DMA_FROMDEVICE); #if HAS_IP_COPYSUM eth_copy_and_sum(skb, @@ -1796,8 +1807,7 @@ #endif } else { pci_unmap_single(np->pci_dev, np->rx_dma[entry], - np->rx_skbuff[entry]->len, - PCI_DMA_FROMDEVICE); + buflen, PCI_DMA_FROMDEVICE); skb_put(skb = np->rx_skbuff[entry], pkt_len); np->rx_skbuff[entry] = NULL; } @@ -1898,44 +1908,6 @@ return &np->stats; } -/** - * dp83815_crc - computer CRC for hash table entries - * - * Note - this is, for some reason, *not* the same function - * as ether_crc_le() or ether_crc(), though it uses the - * same big-endian polynomial. - */ -#define DP_POLYNOMIAL 0x04C11DB7 -static unsigned dp83815_crc(int length, unsigned char *data) -{ - u32 crc; - u8 cur_byte; - u8 msb; - u8 byte, bit; - - crc = ~0; - for (byte=0; byte> 31; - crc <<= 1; - if (msb ^ (cur_byte & 1)) { - crc ^= DP_POLYNOMIAL; - crc |= 1; - } - cur_byte >>= 1; - } - } - crc >>= 23; - - return (crc); -} - - -void set_bit_le(int offset, unsigned char * data) -{ - data[offset >> 3] |= (1 << (offset & 0x07)); -} #define HASH_TABLE 0x200 static void __set_rx_mode(struct net_device *dev) { @@ -1960,9 +1932,8 @@ memset(mc_filter, 0, sizeof(mc_filter)); for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) { - set_bit_le( - dp83815_crc(ETH_ALEN, mclist->dmi_addr) & 0x1ff, - mc_filter); + int i = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 23) & 0x1ff; + mc_filter[i/8] |= (1 << (i & 0x07)); } rx_mode = RxFilterEnable | AcceptBroadcast | AcceptMulticast | AcceptMyPhys; @@ -2000,7 +1971,7 @@ strncpy(info.driver, DRV_NAME, ETHTOOL_BUSINFO_LEN); strncpy(info.version, DRV_VERSION, ETHTOOL_BUSINFO_LEN); info.fw_version[0] = '\0'; - strncpy(info.bus_info, np->pci_dev->slot_name, + strncpy(info.bus_info, pci_name(np->pci_dev), ETHTOOL_BUSINFO_LEN); info.eedump_len = NATSEMI_EEPROM_SIZE; info.regdump_len = NATSEMI_REGS_SIZE; @@ -2585,7 +2556,7 @@ unregister_netdev (dev); pci_release_regions (pdev); iounmap ((char *) dev->base_addr); - kfree (dev); + free_netdev (dev); pci_set_drvdata(pdev, NULL); } @@ -2646,7 +2617,7 @@ if (wol) { /* restart the NIC in WOL mode. * The nic must be stopped for this. - * FIXME: use the WOL interupt + * FIXME: use the WOL interrupt */ enable_wol_mode(dev, 0); } else { Index: drivers/net/ne.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/ne.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/net/ne.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/ne.c 30 Jun 2005 23:06:13 -0000 1.3 @@ -104,6 +104,7 @@ {"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */ {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */ {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */ + {"MicroBee", "PCFW-104-ETH", {0x00, 0x50, 0xc2}}, /* MicroBee Ethernet Radio */ {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */ {0,} }; @@ -123,7 +124,7 @@ #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ int ne_probe(struct net_device *dev); -static int ne_probe1(struct net_device *dev, int ioaddr); +static int ne_probe1(struct net_device *dev, unsigned int ioaddr); static int ne_probe_isapnp(struct net_device *dev); static int ne_open(struct net_device *dev); @@ -166,9 +167,9 @@ SET_MODULE_OWNER(dev); /* First check any supplied i/o locations. User knows best. */ - if (base_addr > 0x1ff) /* Check a single specified location. */ + if ((base_addr & 0xffff) > 0x1ff) /* Check a single specified location. */ return ne_probe1(dev, base_addr); - else if (base_addr != 0) /* Don't probe at all. */ + else if ((base_addr & 0xffff) != 0) /* Don't probe at all. */ return -ENXIO; /* Then look for any installed ISAPnP clones */ @@ -228,7 +229,7 @@ return -ENODEV; } -static int __init ne_probe1(struct net_device *dev, int ioaddr) +static int __init ne_probe1(struct net_device *dev, unsigned int ioaddr) { int i; unsigned char SA_prom[32]; @@ -753,7 +754,15 @@ struct net_device *dev = &dev_ne[this_dev]; dev->irq = irq[this_dev]; dev->mem_end = bad[this_dev]; - dev->base_addr = io[this_dev]; + /* 0x89e00000 is magic for TS-72xx. Its not a physical addr, its + * not a virtual addr, its a magic number that after about 4 layers of + * valueless abstractions which add and subtract various values, it gets + * to the right kernel virtual address for TS-72xx 8bit ISA IO. + * Linux has no ISA bus space abstraction beyond inb() outb() macros + * and those are already overloaded for ep93xx internal SoC AMBA bus + * so we have to do crap like this to get into the TS-72xx 8bit ISA IO space. + * --JO */ + dev->base_addr = io[this_dev] + 0x89e00000; dev->init = ne_probe; if (register_netdev(dev) == 0) { found++; Index: drivers/net/ne2k-pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/ne2k-pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/ne2k-pci.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/ne2k-pci.c 4 Aug 2004 01:29:10 -0000 1.2 @@ -50,15 +50,16 @@ #include #include #include +#include #include +#include +#include #include #include #include #include -#include -#include #include "8390.h" /* These identify the driver base version and may not be removed. */ @@ -115,6 +116,7 @@ CH_Winbond_W89C940F, CH_Holtek_HT80232, CH_Holtek_HT80229, + CH_Winbond_89C940_8c4a, }; @@ -132,11 +134,12 @@ {"Winbond W89C940F", 0}, {"Holtek HT80232", ONLY_16BIT_IO | HOLTEK_FDX}, {"Holtek HT80229", ONLY_32BIT_IO | HOLTEK_FDX | STOP_PG_0x60 }, + {"Winbond W89C940(misprogrammed)", 0}, {0,} }; -static struct pci_device_id ne2k_pci_tbl[] __devinitdata = { +static struct pci_device_id ne2k_pci_tbl[] = { { 0x10ec, 0x8029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RealTek_RTL_8029 }, { 0x1050, 0x0940, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_89C940 }, { 0x11f6, 0x1401, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Compex_RL2000 }, @@ -147,6 +150,7 @@ { 0x1050, 0x5a5a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_W89C940F }, { 0x12c3, 0x0058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Holtek_HT80232 }, { 0x12c3, 0x5598, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Holtek_HT80229 }, + { 0x8c4a, 0x1980, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_89C940_8c4a }, { 0, } }; MODULE_DEVICE_TABLE(pci, ne2k_pci_tbl); @@ -174,7 +178,7 @@ struct sk_buff *skb, int ring_offset); static void ne2k_pci_block_output(struct net_device *dev, const int count, const unsigned char *buf, const int start_page); -static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops ne2k_pci_ethtool_ops; @@ -259,7 +263,8 @@ } } - dev = alloc_etherdev(0); + /* Allocate net_device, dev->priv; fill in 8390 specific dev fields. */ + dev = alloc_ei_netdev(); if (!dev) { printk (KERN_ERR PFX "cannot allocate ethernet device\n"); goto err_out_free_res; @@ -330,13 +335,6 @@ dev->base_addr = ioaddr; pci_set_drvdata(pdev, dev); - /* Allocate dev->priv and fill in 8390 specific dev fields. */ - if (ethdev_init(dev)) { - printk (KERN_ERR "ne2kpci(%s): unable to get memory for dev->priv.\n", - pdev->slot_name); - goto err_out_free_netdev; - } - ei_status.name = pci_clone_list[chip_idx].name; ei_status.tx_start_page = start_page; ei_status.stop_page = stop_page; @@ -360,12 +358,12 @@ ei_status.priv = (unsigned long) pdev; dev->open = &ne2k_pci_open; dev->stop = &ne2k_pci_close; - dev->do_ioctl = &netdev_ioctl; + dev->ethtool_ops = &ne2k_pci_ethtool_ops; NS8390_init(dev, 0); i = register_netdev(dev); if (i) - goto err_out_free_8390; + goto err_out_free_netdev; printk("%s: %s found at %#lx, IRQ %d, ", dev->name, pci_clone_list[chip_idx].name, ioaddr, dev->irq); @@ -376,8 +374,6 @@ return 0; -err_out_free_8390: - kfree(dev->priv); err_out_free_netdev: kfree (dev); err_out_free_res: @@ -590,41 +586,23 @@ return; } -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void ne2k_pci_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { struct ei_device *ei = dev->priv; struct pci_dev *pci_dev = (struct pci_dev *) ei->priv; - 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_NAME); - strcpy(info.version, DRV_VERSION); - strcpy(info.bus_info, pci_dev->slot_name); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - - } - - return -EOPNOTSUPP; -} - -static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - switch(cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - default: - return -EOPNOTSUPP; - } + + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + strcpy(info->bus_info, pci_name(pci_dev)); } +static struct ethtool_ops ne2k_pci_ethtool_ops = { + .get_drvinfo = ne2k_pci_get_drvinfo, + .get_tx_csum = ethtool_op_get_tx_csum, + .get_sg = ethtool_op_get_sg, +}; + static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); @@ -635,15 +613,16 @@ unregister_netdev(dev); release_region(dev->base_addr, NE_IO_EXTENT); kfree(dev); + pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); } static struct pci_driver ne2k_driver = { - name: DRV_NAME, - probe: ne2k_pci_init_one, - remove: __devexit_p(ne2k_pci_remove_one), - id_table: ne2k_pci_tbl, + .name = DRV_NAME, + .probe = ne2k_pci_init_one, + .remove = __devexit_p(ne2k_pci_remove_one), + .id_table = ne2k_pci_tbl, }; Index: drivers/net/net_init.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/net_init.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/net_init.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/net_init.c 4 Aug 2004 01:29:10 -0000 1.2 @@ -71,7 +71,7 @@ */ -static struct net_device *alloc_netdev(int sizeof_priv, const char *mask, +struct net_device *alloc_netdev(int sizeof_priv, const char *mask, void (*setup)(struct net_device *)) { struct net_device *dev; @@ -97,6 +97,7 @@ return dev; } +EXPORT_SYMBOL(alloc_netdev); static struct net_device *init_alloc_dev(int sizeof_priv) { @@ -419,7 +420,7 @@ dev->hard_header_len = ETH_HLEN; dev->mtu = 1500; /* eth_mtu */ dev->addr_len = ETH_ALEN; - dev->tx_queue_len = 100; /* Ethernet wants good queues */ + dev->tx_queue_len = 1000; /* Ethernet wants good queues */ memset(dev->broadcast,0xFF, ETH_ALEN); Index: drivers/net/ns83820.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/ns83820.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/ns83820.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/ns83820.c 4 Aug 2004 01:29:10 -0000 1.2 @@ -3,7 +3,7 @@ * * Questions/comments/discussion to linux-ns83820@kvack.org. * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * * Copyright 2001 Benjamin LaHaise. * Copyright 2001, 2002 Red Hat. @@ -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; @@ -1790,7 +1790,7 @@ dev->net_dev.owner = THIS_MODULE; dev->net_dev.priv = dev; - PREPARE_TQUEUE(&dev->tq_refill, queue_refill, dev); + INIT_TQUEUE(&dev->tq_refill, queue_refill, dev); tasklet_init(&dev->rx_tasklet, rx_action, (unsigned long)dev); err = pci_enable_device(pci_dev); Index: drivers/net/open_eth.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/open_eth.c,v retrieving revision 1.1 retrieving revision 1.14 diff -u -r1.1 -r1.14 --- drivers/net/open_eth.c 2 Jan 2006 18:36:38 -0000 1.1 +++ drivers/net/open_eth.c 16 Mar 2009 19:23:39 -0000 1.14 @@ -11,28 +11,11 @@ * * Copyright (C) 1999 Aplio S.A. Written by Vadim Lebedev * - * Rigt now XXBUFF_PREALLOC must be used, bacause MAC does not - * handle unaligned buffers yet. Also the cache inhibit calls - * should be used some day. - * */ #include #include #include - -/* - * Set this to zero to disable DMA code - * - * Note that even if DMA is turned off we still support the 'dma' and 'use_dma' - * module options so we don't break any startup scripts. - */ -#ifdef CONFIG_ARCH_EP9301 -#define ALLOW_DMA 0 -#else -#define ALLOW_DMA 1 -#endif - #include #include #include @@ -41,6 +24,7 @@ #include #include #include +#include #include #include @@ -52,74 +36,49 @@ #include #include #include -///?#include +#include +#include #include "open_eth.h" -#include -#define TS7XXX_BASE_IO 0x01E00000 -/*? -#define net_device device -#define __pa(x) (x) -#define __va(x) (x) -*/ #define __clear_user(add,len) memset((add),0,(len)) - -///? _print #define _print printk -#define DEBUG 1 +#undef DEBUG -#define RXBUFF_PREALLOC 1 -#define TXBUFF_PREALLOC 1 +static const char* cardname = "ts7300-openeth"; /* The transmitter timeout */ #define TX_TIMEOUT (2*HZ) -/* Buffer number (must be 2^n) +/* Buffer number */ -#define OETH_RXBD_NUM 8 -#define OETH_TXBD_NUM 8 -#define OETH_RXBD_NUM_MASK (OETH_RXBD_NUM-1) -#define OETH_TXBD_NUM_MASK (OETH_TXBD_NUM-1) +#define OETH_TXBD_NUM 2 +#define OETH_RXBD_NUM 3 /* Buffer size */ -#define OETH_RX_BUFF_SIZE 2048 -#define OETH_TX_BUFF_SIZE 2048 - -/* How many buffers per page - */ -#define OETH_RX_BUFF_PPGAE (PAGE_SIZE/OETH_RX_BUFF_SIZE) -#define OETH_TX_BUFF_PPGAE (PAGE_SIZE/OETH_TX_BUFF_SIZE) +#define OETH_TX_BUFF_SIZE OETH_MAXBUF_LEN +#define OETH_RX_BUFF_SIZE OETH_MAXBUF_LEN -/* How many pages is needed for buffers - */ -#define OETH_RX_BUFF_PAGE_NUM (OETH_RXBD_NUM/OETH_RX_BUFF_PPGAE) -#define OETH_TX_BUFF_PAGE_NUM (OETH_TXBD_NUM/OETH_TX_BUFF_PPGAE) - -/* Buffer size (if not XXBUF_PREALLOC - */ -#define MAX_FRAME_SIZE 1518 /* The buffer descriptors track the ring buffers. */ struct oeth_private { - struct sk_buff* rx_skbuff[OETH_RXBD_NUM]; - struct sk_buff* tx_skbuff[OETH_TXBD_NUM]; - - ushort tx_next; /* Next buffer to be sent */ - ushort tx_last; /* Next buffer to be checked if packet sent */ - ushort tx_full; /* Buffer ring fuul indicator */ - ushort rx_cur; /* Next buffer to be checked if packet received */ + volatile int tx_head; /* TX FIFO head*/ + volatile int tx_tail; /* TX FIFO tail*/ + volatile int tx_goingfull; /* TX FIFO full/empty indicator for when head == tail*/ + volatile int tx_lock; + volatile int txq_stopped; /* TX halted temporarily */ + volatile int rx_cur; /* Next buffer to be checked if packet received */ oeth_regs *regs; /* Address of controller registers. */ - oeth_bd *rx_bd_base; /* Address of Rx BDs. */ - oeth_bd *tx_bd_base; /* Address of Tx BDs. */ + oeth_bd *rx_bd_base; /* Address of Rx BDs. */ + oeth_bd *tx_bd_base; /* Address of Tx BDs. */ struct net_device_stats stats; - ///? struct enet_statistics stats; + struct mii_if_info mii_if; }; static int oeth_open(struct net_device *dev); @@ -129,80 +88,210 @@ static void oeth_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int oeth_close(struct net_device *dev); static struct net_device_stats *oeth_get_stats(struct net_device *dev); -///?static struct enet_statistics *oeth_get_stats(struct net_device *dev); static void oeth_set_multicast_list(struct net_device *dev); static int oeth_set_mac_add(struct net_device *dev, void *addr); static int calc_crc(char *mac_addr); -unsigned long getmappedaddr(unsigned long address); -void write_reg(unsigned long data, unsigned long address); -unsigned long read_reg(unsigned long address); - -/* __PHX__ fixme for more ehternet drivers */ -#ifdef CONFIG_OETH_UNKNOWN_TX_NEXT -static int tx_next = -1; +static int mdio_read(struct net_device *dev, int phy_id, int reg) +{ + oeth_regs *regs = (oeth_regs *)(dev->base_addr + OETH_REG_OFFSET); + u32 timeout; + int rxdata; + + timeout = 10; + while (regs->miistatus & OETH_MIISTATUS_BUSY) { + mdelay(1); + if (--timeout < 0) { + printk(KERN_ERR "%s: read_MII busy timeout!!\n", dev->name); + return -1; + } + } + + regs->miiaddress = (((reg<<8)&OETH_MIIADDRESS_RGAD) | (phy_id&OETH_MIIADDRESS_FIAD)); + regs->miicommand = OETH_MIICOMMAND_RSTAT; + + timeout = 10; + do { + mdelay(1); + if (--timeout < 0) { + printk(KERN_ERR "%s: mdio_read busy timeout!!\n", dev->name); + return -1; + } + } while (regs->miistatus & OETH_MIISTATUS_BUSY); + + rxdata = (int)regs->miirx_data; + +#if DEBUG + printk("%s: mdio_read: miiaddress 0x%x rxdata 0x%x\n", dev->name, regs->miiaddress, rxdata); #endif + + return rxdata; +} + +static void mdio_write(struct net_device *dev, int phy_id, int reg, int value) +{ + oeth_regs *regs = (oeth_regs *)(dev->base_addr + OETH_REG_OFFSET); + u32 timeout; + + timeout = 10; + while (regs->miistatus & OETH_MIISTATUS_BUSY) { + mdelay(1); + if (--timeout < 0) { + printk(KERN_ERR "%s: mdio_write busy timeout!!\n", dev->name); + return; + } + } + + regs->miiaddress = (((reg<<8)&OETH_MIIADDRESS_RGAD) | (phy_id&OETH_MIIADDRESS_FIAD)); + regs->miitx_data = value; + regs->miicommand = OETH_MIICOMMAND_WCTRLDATA; + + timeout = 10; + do { + mdelay(1); + if (--timeout < 0) { + printk(KERN_ERR "%s: mdio_write busy timeout!!\n", dev->name); + return; + } + } while (regs->miistatus & OETH_MIISTATUS_BUSY); + +#if DEBUG + printk("%s: mdio_write: miiaddress 0x%x txdata 0x%x\n", dev->name, regs->miiaddress, value); +#endif + +} + +int ks8721_reset(struct net_device *dev, int phy_addr) +{ + s16 mii_control, timeout; + + mii_control = mdio_read(dev, phy_addr, MII_BMCR); + mdio_write(dev, phy_addr, MII_BMCR, mii_control | BMCR_RESET); + for (timeout = 1000; timeout > 0; --timeout) { + mdelay(1); + mii_control = mdio_read(dev, phy_addr, MII_BMCR); + if ((mii_control & BMCR_RESET) == 0) + break; + } + if (mii_control & BMCR_RESET) { + printk(KERN_ERR "%s PHY reset timeout BMCR:0x%08x!\n", dev->name, mii_control); + return -1; + } + return 0; +} + +int ks8721_init(struct net_device *dev, int phy_addr) +{ + s16 data; + + /* Stop auto-negotiation */ + data = mdio_read(dev, phy_addr, MII_BMCR); + mdio_write(dev, phy_addr, MII_BMCR, data & ~BMCR_ANENABLE); + + /* Set advertisement to 10/100 and Half/Full duplex (full capabilities) */ + data = mdio_read(dev, phy_addr, MII_ADVERTISE); + data |= ADVERTISE_CSMA | ADVERTISE_100HALF | ADVERTISE_100FULL | ADVERTISE_10FULL | ADVERTISE_10HALF; + mdio_write(dev, phy_addr, MII_ADVERTISE, data); + + /* Restart auto-negotiation */ + data = mdio_read(dev, phy_addr, MII_BMCR); + data |= BMCR_ANRESTART | BMCR_ANENABLE; + mdio_write(dev, phy_addr, MII_BMCR, data); + + return 0; +} #if DEBUG static void oeth_print_packet(unsigned long add, int len) +{ + int i; + unsigned int *buf = (unsigned int *)add; + int n = len / 4 + ((len & 0x3) ? 1 : 0); + + _print("ipacket: add = %lx len = %d\n", add, len); + for(i = 0; i < n; i++) { + if(!(i % 4)) + _print("\n"); + _print(" %.8x", buf[i]); + } + _print("\n"); +} + +static void +oeth_print_packet_bytes(unsigned long add, int len) { int i; + unsigned char *buf = (unsigned char *)add; _print("ipacket: add = %lx len = %d\n", add, len); for(i = 0; i < len; i++) { if(!(i % 16)) _print("\n"); - _print(" %.2x", *(((unsigned char *)add) + i)); + _print(" %.2x", buf[i]); } _print("\n"); } #endif -static int -oeth_open(struct net_device *dev) +static void oeth2cpu_memcpy(unsigned char *dest, unsigned int *src, int nbytes) { + unsigned int dat; - oeth_regs *regs = (oeth_regs *)dev->base_addr; - - struct oeth_private *cep = (struct oeth_private *)dev->priv; -#ifdef CONFIG_OETH_UNKNOWN_TX_NEXT - if (tx_next != -1) { - cep->tx_next = tx_next; - } -#endif - -#ifndef RXBUFF_PREALLOC - struct sk_buff *skb; - volatile oeth_bd *rx_bd; - int i; - - rx_bd = cep->rx_bd_base; - - for(i = 0; i < OETH_RXBD_NUM; i++) { - - skb = dev_alloc_skb(MAX_FRAME_SIZE); - - if (skb == NULL) - rx_bd[i].len_status = (0 << 16) | OETH_RX_BD_IRQ; - else - rx_bd[i].len_status = (0 << 16) | OETH_RX_BD_EMPTY | OETH_RX_BD_IRQ; + // XXX: memcpy() can't be used because it uses the load/store multiple opcodes + // which asynchronously change the address of the ep93xx SMC without + // initiating another cycle by toggling the read strobe. --joff + while(nbytes > 0) { + dat = *(src++); + *(unsigned int *)(dest) = dat; + nbytes -= 4; + dest += 4; + } +} - cep->rx_skbuff[i] = skb; +static void cpu2oeth_memcpy(unsigned int *dest, unsigned char *src, int nbytes) +{ + unsigned int dat, i; + // supposedly we can be guaranteed of at least 16-bit alignment + unsigned short *src16 = (unsigned short *)src; - rx_bd[i].addr = (unsigned long)skb->tail; + while(nbytes > 0) { + dat = *(src16++); + dat |= *(src16++) << 16; + *(dest++) = dat; + nbytes -= 4; } - rx_bd[OETH_RXBD_NUM - 1].len_status |= OETH_RX_BD_WRAP; -#endif +} + +static int +oeth_open(struct net_device *dev) +{ + struct oeth_private *cep = (struct oeth_private *)dev->priv; + oeth_regs *regs = (oeth_regs *)(dev->base_addr + OETH_REG_OFFSET); + u32 timeout; + int ret; + + timeout = 1000; + while (timeout-- && + !(mdio_read(dev, cep->mii_if.phy_id, MII_BMSR) & BMSR_ANEGCOMPLETE)) + mdelay(1); + + if (!(mdio_read(dev, cep->mii_if.phy_id, MII_BMSR)&BMSR_ANEGCOMPLETE) ) + printk(KERN_ERR "%s BMSR_ANEGCOMPLETE timeout !\n", dev->name); + else if (mdio_read(dev, cep->mii_if.phy_id, MII_LPA)&LPA_DUPLEX) + regs->moder |= OETH_MODER_FULLD; /* Install our interrupt handler. */ - request_irq(IRQ_ETH_0, oeth_interrupt, 0, "eth", (void *)dev); - + ret = request_irq(IRQ_ETH_0, oeth_interrupt, SA_SHIRQ, cardname, (void *)dev); + if (0 != ret) { + printk("Unable to allocate IRQ %d\n",IRQ_ETH_0); + return ret; + } /* Enable receiver and transmiter */ - write_reg(read_reg(regs->moder) | OETH_MODER_RXEN | OETH_MODER_TXEN, regs->moder); - + regs->moder |= OETH_MODER_RXEN | OETH_MODER_TXEN; + return 0; } @@ -210,7 +299,7 @@ oeth_close(struct net_device *dev) { struct oeth_private *cep = (struct oeth_private *)dev->priv; - oeth_regs *regs = (oeth_regs *)dev->base_addr; + oeth_regs *regs = (oeth_regs *)(dev->base_addr + OETH_REG_OFFSET); volatile oeth_bd *bdp; int i; @@ -219,8 +308,8 @@ free_irq(IRQ_ETH_0, (void *)dev); /* Disable receiver and transmitesr - *////?w - write_reg(read_reg(regs->moder) & ~(OETH_MODER_RXEN | OETH_MODER_TXEN), regs->moder); + */ + regs->moder &= ~(OETH_MODER_RXEN | OETH_MODER_TXEN); bdp = cep->rx_bd_base; for (i = 0; i < OETH_RXBD_NUM; i++) { @@ -234,31 +323,6 @@ bdp++; } -#ifndef RXBUFF_PREALLOC - - /* Free all alocated rx buffers - */ - for (i = 0; i < OETH_RXBD_NUM; i++) { - - if (cep->rx_skbuff[i] != NULL) - dev_kfree_skb(cep->rx_skbuff[i], FREE_READ); - - } -#endif -#ifndef TXBUFF_PREALLOC - - /* Free all alocated tx buffers - */ - for (i = 0; i < OETH_TXBD_NUM; i++) { - - if (cep->tx_skbuff[i] != NULL) - dev_kfree_skb(cep->tx_skbuff[i], FREE_WRITE); - } -#endif - -#ifdef CONFIG_OETH_UNKNOWN_TX_NEXT - tx_next = cep->tx_next; -#endif return 0; } @@ -266,77 +330,69 @@ oeth_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct oeth_private *cep = (struct oeth_private *)dev->priv; + oeth_regs *regs = (oeth_regs *)(dev->base_addr + OETH_REG_OFFSET); volatile oeth_bd *bdp; - unsigned long flags; - - /* Fill in a Tx ring entry - */ - bdp = cep->tx_bd_base + cep->tx_next; + unsigned int len_status; - if (cep->tx_full) { + cep->tx_lock = 1; - /* All transmit buffers are full. Bail out. - */ - printk("%s: tx queue full!.\n", dev->name); + if ((cep->tx_head == cep->tx_tail) && cep->tx_goingfull) { + netif_stop_queue(dev); + cep->txq_stopped = 1; + if (cep->tx_lock == 0) oeth_tx(dev); + else cep->tx_lock = 0; return 1; } + /* Fill in a Tx ring entry + */ + bdp = cep->tx_bd_base + cep->tx_tail; + /* Clear all of the status flags. */ - bdp->len_status &= ~OETH_TX_BD_STATS; + len_status = bdp->len_status; + len_status &= ~OETH_TX_BD_STATS; /* If the frame is short, tell CPM to pad it. */ if (skb->len <= ETH_ZLEN) - bdp->len_status |= OETH_TX_BD_PAD; + len_status |= OETH_TX_BD_PAD; else - bdp->len_status &= ~OETH_TX_BD_PAD; - -#if DEBUG - _print("TX\n"); - oeth_print_packet(skb->data, skb->len); -#endif - -#ifdef TXBUFF_PREALLOC + len_status &= ~OETH_TX_BD_PAD; /* Copy data in preallocated buffer */ if (skb->len > OETH_TX_BUFF_SIZE) { printk("%s: tx frame too long!.\n", dev->name); - return 1; + if (cep->tx_lock == 0) oeth_tx(dev); + else cep->tx_lock = 0; + return 1; //? } else - memcpy((unsigned char *)bdp->addr, skb->data, skb->len); + cpu2oeth_memcpy((int *)(dev->base_addr + bdp->addr), skb->data, skb->len); - bdp->len_status = (bdp->len_status & 0x0000ffff) | (skb->len << 16); +#if DEBUG + _print("TX\n"); + oeth_print_packet((unsigned long)(dev->base_addr + bdp->addr), skb->len); + oeth_print_packet_bytes((unsigned long)(skb->data), skb->len); +#endif + len_status = (len_status & 0x0000ffff) | (skb->len << 16); - ///?dev_kfree_skb(skb, FREE_WRITE); dev_kfree_skb(skb); -#else - /* Set buffer length and buffer pointer. - */ - bdp->len_status = (bdp->len_status & 0x0000ffff) | (skb->len << 16); - bdp->addr = (uint)__pa(skb->data); - /* Save skb pointer. - */ - cep->tx_skbuff[cep->tx_next] = skb; -#endif - - cep->tx_next = (cep->tx_next + 1) & OETH_TXBD_NUM_MASK; - - save_flags(flags); cli(); + if ((cep->tx_tail == cep->tx_head) && !cep->tx_goingfull) + regs->moder |= OETH_MODER_TXEN; - if (cep->tx_next == cep->tx_last) - cep->tx_full = 1; + cep->tx_tail = (cep->tx_tail+1 == OETH_TXBD_NUM) ? 0 : (cep->tx_tail+1); + cep->tx_goingfull = 1; /* Send it on its way. Tell controller its ready, interrupt when done, * and to put the CRC on the end. */ - bdp->len_status |= (OETH_TX_BD_READY | OETH_TX_BD_IRQ | OETH_TX_BD_CRC); - - dev->trans_start = jiffies; + len_status |= (OETH_TX_BD_READY | OETH_TX_BD_IRQ | OETH_TX_BD_CRC); + bdp->len_status = len_status; - restore_flags(flags); + if (cep->tx_lock == 0) oeth_tx(dev); + else cep->tx_lock = 0; return 0; } @@ -348,33 +404,42 @@ { struct net_device *dev = dev_id; volatile struct oeth_private *cep; - uint int_events; + uint int_events; cep = (struct oeth_private *)dev->priv; /* Get the interrupt events that caused us to be here. */ - int_events = read_reg(cep->regs->int_src); - write_reg(int_events, cep->regs->int_src); + int_events = cep->regs->int_src; + +#if DEBUG + printk("%s: interrupt handler: int_events = 0x%x\n", dev->name, int_events); +#endif + /* Check for receive busy, i.e. packets coming but no place to + * put them. + */ + + if (int_events & OETH_INT_BUSY) { + cep->regs->moder &= ~OETH_MODER_RXEN; + oeth_rx(dev_id); + cep->regs->moder |= OETH_MODER_RXEN; + cep->rx_cur = 0; + } else + /* Handle receive event in its own function. */ if (int_events & (OETH_INT_RXF | OETH_INT_RXE)) oeth_rx(dev_id); + cep->regs->int_src = OETH_INT_BUSY | OETH_INT_RXE | OETH_INT_RXF; + /* Handle transmit event in its own function. */ if (int_events & (OETH_INT_TXB | OETH_INT_TXE)) { - oeth_tx(dev_id); - ///?mark_bh(NET_BH); - } - - /* Check for receive busy, i.e. packets coming but no place to - * put them. - */ - if (int_events & OETH_INT_BUSY) { - if (!(int_events & (OETH_INT_RXF | OETH_INT_RXE))) - oeth_rx(dev_id); + if (cep->tx_lock) cep->tx_lock = 0; + else oeth_tx(dev_id); + cep->regs->int_src = OETH_INT_TXB | OETH_INT_TXE; } return; @@ -386,47 +451,33 @@ { struct oeth_private *cep; volatile oeth_bd *bdp; - -#ifndef TXBUFF_PREALLOC - struct sk_buff *skb; -#endif + unsigned int len_status; cep = (struct oeth_private *)dev->priv; - for (;; cep->tx_last = (cep->tx_last + 1) & OETH_TXBD_NUM_MASK) { + for (;; cep->tx_head = (cep->tx_head+1 == OETH_TXBD_NUM) ? 0 : (cep->tx_head+1)) { - bdp = cep->tx_bd_base + cep->tx_last; + bdp = cep->tx_bd_base + cep->tx_head; - if ((bdp->len_status & OETH_TX_BD_READY) || - ((cep->tx_last == cep->tx_next) && !cep->tx_full)) + // disable transmitter if empty + if ((cep->tx_tail == cep->tx_head) && !cep->tx_goingfull) { + cep->regs->moder &= ~OETH_MODER_TXEN; + cep->tx_head = cep->tx_tail = 0; break; + } + + len_status = bdp->len_status; + if (len_status & OETH_TX_BD_READY) break; /* Check status for errors */ - if (bdp->len_status & OETH_TX_BD_LATECOL) - cep->stats.tx_window_errors++; - if (bdp->len_status & OETH_TX_BD_RETLIM) - cep->stats.tx_aborted_errors++; - if (bdp->len_status & OETH_TX_BD_UNDERRUN) - cep->stats.tx_fifo_errors++; - if (bdp->len_status & OETH_TX_BD_CARRIER) - cep->stats.tx_carrier_errors++; - if (bdp->len_status & (OETH_TX_BD_LATECOL | OETH_TX_BD_RETLIM | OETH_TX_BD_UNDERRUN)) + if (len_status & OETH_TX_BD_STATS) cep->stats.tx_errors++; cep->stats.tx_packets++; - cep->stats.collisions += (bdp->len_status >> 4) & 0x000f; -#ifndef TXBUFF_PREALLOC - skb = cep->tx_skbuff[cep->tx_last]; - - /* Free the sk buffer associated with this last transmit. - */ - dev_kfree_skb(skb, FREE_WRITE); -#endif - - if (cep->tx_full) - cep->tx_full = 0; + if (cep->txq_stopped) netif_wake_queue(dev); + cep->txq_stopped = cep->tx_goingfull = 0; } } @@ -436,152 +487,66 @@ struct oeth_private *cep; volatile oeth_bd *bdp; struct sk_buff *skb; - int pkt_len; - int bad = 0; -#ifndef RXBUFF_PREALLOC - struct sk_buff *small_skb; -#endif + int pkt_len, len_status; cep = (struct oeth_private *)dev->priv; +#if DEBUG + printk("%s: oeth_rx call: rxcur 0x%x\n", dev->name, cep->rx_cur); +#endif + /* First, grab all of the stats for the incoming packet. * These get messed up if we get called due to a busy condition. */ - for (;;cep->rx_cur = (cep->rx_cur + 1) & OETH_RXBD_NUM_MASK) { + for (;; cep->rx_cur = (cep->rx_cur+1 == OETH_RXBD_NUM) ? 0 : (cep->rx_cur+1)) { bdp = cep->rx_bd_base + cep->rx_cur; -#ifndef RXBUFF_PREALLOC - skb = cep->rx_skbuff[cep->rx_cur]; - - if (skb == NULL) { - - skb = dev_alloc_skb(MAX_FRAME_SIZE); +#if DEBUG + printk("%s: oeth_rx loop: bdp 0x%x len_stat 0x%x rx_cur 0x%x\n", dev->name, bdp, bdp->len_status, cep->rx_cur); +#endif - if (skb != NULL) - { - bdp->addr = (unsigned long) skb->tail; - bdp->len_status |= OETH_RX_BD_EMPTY; - } + len_status = bdp->len_status; - continue; - } -#endif - - if (bdp->len_status & OETH_RX_BD_EMPTY) + if (len_status & OETH_RX_BD_EMPTY) break; - /* Check status for errors. - */ - if (bdp->len_status & (OETH_RX_BD_TOOLONG | OETH_RX_BD_SHORT)) { - cep->stats.rx_length_errors++; - bad = 1; - } - if (bdp->len_status & OETH_RX_BD_DRIBBLE) { - cep->stats.rx_frame_errors++; - bad = 1; - } - if (bdp->len_status & OETH_RX_BD_CRCERR) { - cep->stats.rx_crc_errors++; - bad = 1; - } - if (bdp->len_status & OETH_RX_BD_OVERRUN) { - cep->stats.rx_crc_errors++; - bad = 1; - } - if (bdp->len_status & OETH_RX_BD_MISS) { - - } - if (bdp->len_status & OETH_RX_BD_LATECOL) { - cep->stats.rx_frame_errors++; - bad = 1; - } - - if (bad) { - - bdp->len_status &= ~OETH_RX_BD_STATS; - bdp->len_status |= OETH_RX_BD_EMPTY; + if (len_status & OETH_RX_BD_STATS) { + len_status &= ~OETH_RX_BD_STATS; + len_status |= OETH_RX_BD_EMPTY; + bdp->len_status = len_status; continue; } /* Process the incoming frame. */ - pkt_len = bdp->len_status >> 16; + pkt_len = len_status >> 16; -#ifdef RXBUFF_PREALLOC - skb = dev_alloc_skb(pkt_len); + skb = dev_alloc_skb(pkt_len + 5); if (skb == NULL) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); cep->stats.rx_dropped++; } else { + skb_reserve(skb, 2); /*odd 16 bit alignment to make protocal stack happy*/ skb->dev = dev; + oeth2cpu_memcpy(skb_put(skb, pkt_len), (unsigned int *)(dev->base_addr + bdp->addr), pkt_len); #if DEBUG _print("RX\n"); - oeth_print_packet(bdp->addr, pkt_len); + oeth_print_packet((unsigned long)(dev->base_addr + bdp->addr), pkt_len); + oeth_print_packet_bytes((unsigned long)(skb->data), skb->len); #endif - memcpy(skb_put(skb, pkt_len), (unsigned char *)__va(bdp->addr), pkt_len); skb->protocol = eth_type_trans(skb,dev); netif_rx(skb); cep->stats.rx_packets++; } - bdp->len_status &= ~OETH_RX_BD_STATS; - bdp->len_status |= OETH_RX_BD_EMPTY; -#else - - if (pkt_len < 128) { - - small_skb = dev_alloc_skb(pkt_len); - - if (small_skb) { - small_skb->dev = dev; -#if DEBUG - _print("RX short\n"); - oeth_print_packet(bdp->addr, bdp->len_status >> 16); -#endif - memcpy(skb_put(small_skb, pkt_len), (unsigned char *)__va(bdp->addr), pkt_len); - small_skb->protocol = eth_type_trans(small_skb,dev); - netif_rx(small_skb); - cep->stats.rx_packets++; - } - else { - printk("%s: Memory squeeze, dropping packet.\n", dev->name); - cep->stats.rx_dropped++; - } - - bdp->len_status &= ~OETH_RX_BD_STATS; - bdp->len_status |= OETH_RX_BD_EMPTY; - } - else { - skb->dev = dev; - skb_put(skb, bdp->len_status >> 16); - skb->protocol = eth_type_trans(skb,dev); - netif_rx(skb); - cep->stats.rx_packets++; -#if DEBUG - _print("RX long\n"); - oeth_print_packet(bdp->addr, bdp->len_status >> 16); -#endif - - skb = dev_alloc_skb(MAX_FRAME_SIZE); - - bdp->len_status &= ~OETH_RX_BD_STATS; - - if (skb) { - cep->rx_skbuff[cep->rx_cur] = skb; - - bdp->addr = (unsigned long)skb->tail; - bdp->len_status |= OETH_RX_BD_EMPTY; - } - else { - cep->rx_skbuff[cep->rx_cur] = NULL; - } - } -#endif + len_status &= ~OETH_RX_BD_STATS; + len_status |= OETH_RX_BD_EMPTY; + bdp->len_status = len_status; } } @@ -592,11 +557,9 @@ } static struct net_device_stats *oeth_get_stats(struct net_device *dev) -///?static struct enet_statistics *oeth_get_stats(struct net_device *dev) { - struct oeth_private *cep = (struct oeth_private *)dev->priv; - - return &cep->stats; + struct oeth_private *cep = (struct oeth_private *)dev->priv; + return &cep->stats; } static void oeth_set_multicast_list(struct net_device *dev) @@ -610,32 +573,31 @@ /* Get pointer of controller registers. */ - regs = (oeth_regs *)dev->base_addr; + regs = (oeth_regs *)(dev->base_addr + OETH_REG_OFFSET); if (dev->flags & IFF_PROMISC) { /* Log any net taps. */ - printk("%s: Promiscuous mode enabled.\n", dev->name); - write_reg(read_reg(regs->moder) | OETH_MODER_PRO, regs->moder); + regs->moder |= OETH_MODER_PRO; } else { - write_reg(read_reg(regs->moder) & ~OETH_MODER_PRO, regs->moder); - + regs->moder &= ~OETH_MODER_PRO; + if (dev->flags & IFF_ALLMULTI) { /* Catch all multicast addresses, so set the * filter to all 1's. */ - write_reg(0xffffffff, regs->hash_addr0); - write_reg(0xffffffff, regs->hash_addr1); + regs->hash_addr0 = 0xffffffff; + regs->hash_addr1 = 0xffffffff; } else if (dev->mc_count) { /* Clear filter and add the addresses in the list. */ - write_reg(0x00000000, regs->hash_addr0); - write_reg(0x00000000, regs->hash_addr1); + regs->hash_addr0 = 0x00000000; + regs->hash_addr0 = 0x00000000; dmi = dev->mc_list; @@ -650,9 +612,10 @@ hash_b = calc_crc(dmi->dmi_addr); if(hash_b >= 32) - write_reg(read_reg(regs->hash_addr1) | 1 << (hash_b - 32), regs->hash_addr1); + regs->hash_addr1 |= 1 << (hash_b - 32); else - write_reg(read_reg(regs->hash_addr0) | 1 << hash_b, regs->hash_addr0); + regs->hash_addr0 |= 1 << hash_b; + } } } @@ -663,30 +626,31 @@ struct sockaddr *addr=p; volatile oeth_regs *regs; - memcpy(dev->dev_addr, addr->sa_data,dev->addr_len); + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - regs = (oeth_regs *)dev->base_addr; + regs = (oeth_regs *)(dev->base_addr + OETH_REG_OFFSET); - write_reg(addr->sa_data[0] << 8 | addr->sa_data[1], regs->mac_addr1); - write_reg(addr->sa_data[2] << 24 | addr->sa_data[3] << 16 | addr->sa_data[4] << 8 | - addr->sa_data[5], regs->mac_addr0); - + regs->mac_addr1 = addr->sa_data[0] << 8 | + addr->sa_data[1]; + regs->mac_addr0 = addr->sa_data[2] << 24 | + addr->sa_data[3] << 16 | + addr->sa_data[4] << 8 | + addr->sa_data[5]; + return 0; } /* Initialize the Open Ethernet MAC. */ -int oeth_probe(struct net_device *dev) +static int __init oeth_probe(struct net_device *dev) { struct oeth_private *cep; volatile oeth_regs *regs; volatile oeth_bd *tx_bd, *rx_bd; - int i, j, k; -#ifdef SRAM_BUFF - unsigned long mem_addr = SRAM_BUFF_BASE; -#else + int i; unsigned long mem_addr; -#endif + + SET_MODULE_OWNER(dev); cep = (struct oeth_private *)dev->priv; @@ -712,199 +676,158 @@ return -ENOMEM; } - __clear_user(cep,sizeof(*cep)); + __clear_user(cep, sizeof(*cep)); + + if (dev->base_addr == 0x0) + dev->base_addr = (unsigned long)__ioremap(ETH_BASE_ADD, OETH_TOTAL_SIZE, 0); + else + dev->base_addr = (unsigned long)__ioremap((unsigned long)dev->base_addr, OETH_TOTAL_SIZE, 0); + if(request_region(dev->base_addr, OETH_TOTAL_SIZE, cardname) == 0) { + printk("%s: unable to request region!\n", dev->name); + return -EAGAIN; + } + /* Get pointer ethernet controller configuration registers. */ - /* - cep->regs = (oeth_regs *)(OETH_REG_BASE); - regs = (oeth_regs *)(OETH_REG_BASE); - */ - cep->regs = (oeth_regs *)getmappedaddr(OETH_REG_BASE); - regs = (oeth_regs *)getmappedaddr(OETH_REG_BASE); - + cep->regs = (oeth_regs *)(dev->base_addr + OETH_REG_OFFSET); + regs = (oeth_regs *)(dev->base_addr + OETH_REG_OFFSET); /* Reset the controller. */ - write_reg(OETH_MODER_RST, regs->moder); /* Reset ON */ - write_reg(read_reg(regs->moder)&~OETH_MODER_RST, regs->moder); - - /* Setting TXBD base to OETH_TXBD_NUM. - write_reg(OETH_TXBD_NUM, regs->tx_bd_num); + regs->moder = OETH_MODER_RST; /* Reset ON */ + regs->moder &= ~OETH_MODER_RST; /* Reset OFF */ + + /* Setting TXBD base to OETH_TXBD_NUM. + */ + regs->tx_bd_num = OETH_TXBD_NUM; /* Initialize TXBD pointer - *////?w talvez endereco da RAM do FPGA - cep->tx_bd_base = (oeth_bd *)OETH_BD_BASE; - tx_bd = (volatile oeth_bd *)OETH_BD_BASE; - + */ + cep->tx_bd_base = (oeth_bd *)(dev->base_addr + OETH_BD_OFFSET); + tx_bd = (volatile oeth_bd *)(dev->base_addr + OETH_BD_OFFSET); + /* Initialize RXBD pointer - *////?w talvez endereco da RAM do FPGA - cep->rx_bd_base = ((oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM; - rx_bd = ((volatile oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM; - + */ + cep->rx_bd_base = ((oeth_bd *)(dev->base_addr + OETH_BD_OFFSET)) + OETH_TXBD_NUM; + rx_bd = ((volatile oeth_bd *)(dev->base_addr + OETH_BD_OFFSET)) + OETH_TXBD_NUM; + /* Initialize transmit pointers. */ cep->rx_cur = 0; -#ifdef CONFIG_OETH_UNKNOWN_TX_NEXT - /* the first time use value passed by bootloader - * __PHX__ fixme, this woun't work if you have this compiled as module - */ - { - int tmp_next = *((int *)(0x00000000)); - - /* sanity check */ - if ((tmp_next >= 0) && (tmp_next < OETH_TXBD_NUM)) - cep->tx_next = tmp_next; - else { - printk(KERN_WARNING "open_eth: illegal number of TX buffer descriptors passed (%d), using default (if you did not use ethernet before starting linux this is ok)\n", - tmp_next); - cep->tx_next = 0; - } - } -#else - /* or read it from eth register, or set it to 0 in eth */ - cep->tx_next = 0; -#endif - cep->tx_last = 0; - cep->tx_full = 0; - /* Set min/max packet length - *////?w perguntar pro jesse - write_reg(0x00400600, regs->packet_len); + /* or read it from eth register, or set it to 0 in eth */ + cep->tx_head = 0; + cep->tx_tail = 0; + cep->tx_goingfull = 0; + cep->tx_lock = 0; + cep->txq_stopped = 0; + + /* Set min/max packet length + */ + regs->packet_len = 0x00400600; /* Set IPGT register to recomended value */ - write_reg(0x00000012, regs->ipgt); + regs->ipgt = 0x00000015; /* Set IPGR1 register to recomended value */ - write_reg(0x0000000c, regs->ipgr1); + regs->ipgr1 = 0x0000000c; /* Set IPGR2 register to recomended value */ - write_reg(0x00000012, regs->ipgr2); + regs->ipgr2 = 0x00000012; /* Set COLLCONF register to recomended value */ - write_reg(0x000f003f, regs->collconf); - + regs->collconf = 0x000f003f; + /* Set control module mode */ #if 0 - write_reg(OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW, regs->ctrlmoder); + regs->ctrlmoder = OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW; #else - write_reg(0, regs->ctrlmoder); + regs->ctrlmoder = 0; #endif - /* Set PHY to show Tx status, Rx status and Link status *////?w - regs->miiaddress = 20<<8; - regs->miitx_data = 0x1422; - regs->miicommand = OETH_MIICOMMAND_WCTRLDATA; - - - ///?nao entendi como funciona isso - -#ifdef TXBUFF_PREALLOC + /* Configure Micrel KS8721BL PHY + */ + cep->mii_if.dev = dev; + cep->mii_if.phy_id = MICREL_PHY; + cep->mii_if.phy_id_mask = OETH_MIIADDRESS_FIAD; + cep->mii_if.reg_num_mask = OETH_MIIADDRESS_RGAD; + cep->mii_if.mdio_read = mdio_read; + cep->mii_if.mdio_write = mdio_write; + ks8721_reset(dev, cep->mii_if.phy_id); + ks8721_init(dev, cep->mii_if.phy_id); + + regs->miimoder = 0x164; + /* Initialize TXBDs. */ - for(i = 0, k = 0; i < OETH_TX_BUFF_PAGE_NUM; i++) { - -#ifndef SRAM_BUFF - mem_addr = __get_free_page(GFP_KERNEL); -#endif - - for(j = 0; j < OETH_TX_BUFF_PPGAE; j++, k++) { - tx_bd[k].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC | OETH_RX_BD_IRQ; - tx_bd[k].addr = __pa(mem_addr); - mem_addr += OETH_TX_BUFF_SIZE; - } - } - tx_bd[OETH_TXBD_NUM - 1].len_status |= OETH_TX_BD_WRAP; -#else - - /* Initialize TXBDs. - */ + mem_addr = OETH_BUF_OFFSET; for(i = 0; i < OETH_TXBD_NUM; i++) { - - cep->tx_skbuff[i] = NULL; - - tx_bd[i].len_status = (0 << 16) | OETH_TX_BD_PAD | OETH_TX_BD_CRC | OETH_RX_BD_IRQ; - tx_bd[i].addr = 0; + tx_bd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC | OETH_RX_BD_IRQ; + tx_bd[i].addr = mem_addr; + mem_addr += OETH_TX_BUFF_SIZE; } tx_bd[OETH_TXBD_NUM - 1].len_status |= OETH_TX_BD_WRAP; -#endif - -#ifdef RXBUFF_PREALLOC - - /* Initialize RXBDs. - */ - for(i = 0, k = 0; i < OETH_RX_BUFF_PAGE_NUM; i++) { -#ifndef SRAM_BUFF - mem_addr = __get_free_page(GFP_KERNEL); -#endif - for(j = 0; j < OETH_RX_BUFF_PPGAE; j++, k++) { - rx_bd[k].len_status = OETH_RX_BD_EMPTY | OETH_RX_BD_IRQ; - rx_bd[k].addr = __pa(mem_addr); - mem_addr += OETH_RX_BUFF_SIZE; - } - } - rx_bd[OETH_RXBD_NUM - 1].len_status |= OETH_RX_BD_WRAP; - -#else /* Initialize RXBDs. */ + mem_addr = OETH_BUF_OFFSET + (OETH_TX_BUFF_SIZE*OETH_TXBD_NUM); for(i = 0; i < OETH_RXBD_NUM; i++) { - - - rx_bd[i].len_status = (0 << 16) | OETH_RX_BD_IRQ; - - cep->rx_skbuff[i] = NULL; - - rx_bd[i].addr = 0; + rx_bd[i].len_status = OETH_RX_BD_EMPTY | OETH_RX_BD_IRQ; + rx_bd[i].addr = mem_addr; + mem_addr += OETH_RX_BUFF_SIZE; } rx_bd[OETH_RXBD_NUM - 1].len_status |= OETH_RX_BD_WRAP; -#endif - /* Set default ethernet station address. + /* Set default ethernet station address to ep93xx eth addr + 1. */ - dev->dev_addr[0] = MACADDR0; - dev->dev_addr[1] = MACADDR1; - dev->dev_addr[2] = MACADDR2; - dev->dev_addr[3] = MACADDR3; - dev->dev_addr[4] = MACADDR4; - dev->dev_addr[5] = MACADDR5; - - write_reg(MACADDR0 << 8 | MACADDR1, regs->mac_addr1); - write_reg( MACADDR2 << 24 | MACADDR3 << 16 | MACADDR4 << 8 | MACADDR5, regs->mac_addr0); + { + unsigned char *epmac = (unsigned char *)IO_ADDRESS(MAC_INDAD); + unsigned long mac = epmac[5] | (epmac[4] << 8) | (epmac[3] << 16); + + mac++; + + *(unsigned long *)IO_ADDRESS(MAC_AFP) = 0x00; + dev->dev_addr[0] = epmac[0]; + dev->dev_addr[1] = epmac[1]; + dev->dev_addr[2] = epmac[2]; + dev->dev_addr[3] = (mac >> 16) & 0xff; + dev->dev_addr[4] = (mac >> 8) & 0xff; + dev->dev_addr[5] = mac & 0xff; + } + + regs->mac_addr1 = dev->dev_addr[0] << 8 | dev->dev_addr[1]; + regs->mac_addr0 = dev->dev_addr[2] << 24 | dev->dev_addr[3] << 16 | + dev->dev_addr[4] << 8 | dev->dev_addr[5]; /* Clear all pending interrupts */ - write_reg(0xffffffff, regs->int_src); + regs->int_src = 0xffffffff; /* Promisc, IFG, CRCEn */ - write_reg(read_reg(regs->moder) | OETH_MODER_PAD | OETH_MODER_IFG | OETH_MODER_CRCEN, regs->moder); + regs->moder |= OETH_MODER_PAD | OETH_MODER_IFG | OETH_MODER_CRCEN; /* Enable interrupt sources. */ - write_reg(OETH_INT_MASK_TXB | - OETH_INT_MASK_TXE | + regs->int_mask = OETH_INT_MASK_TXE | + OETH_INT_MASK_TXB | + OETH_INT_MASK_RXE | OETH_INT_MASK_RXF | - OETH_INT_MASK_RXE | - OETH_INT_MASK_BUSY | - OETH_INT_MASK_TXC | - OETH_INT_MASK_RXC, regs->int_mask); + OETH_INT_MASK_BUSY; /* Fill in the fields of the device structure with ethernet values. */ ether_setup(dev); - dev->base_addr = (unsigned long)OETH_REG_BASE; - /* The Open Ethernet specific entries in the device structure. */ dev->open = oeth_open; @@ -914,28 +837,61 @@ dev->set_multicast_list = oeth_set_multicast_list; dev->set_mac_address = oeth_set_mac_add; + +#if DEBUG + printk("%s: Open Ethernet Memory Map:\n", dev->name); + printk("\tRegister Base=0x%x \n\tTXBD=0x%x TXBUF=0x%x \n\tRXBD=0x%x RXBUF=0x%x\n", + (uint)cep->regs, (uint)cep->tx_bd_base, tx_bd[0].addr, (uint)cep->rx_bd_base, rx_bd[0].addr); +#endif + printk("%s: Open Ethernet Core Version 1.0\n", dev->name); return 0; } -unsigned long getmappedaddr(unsigned long address) -{ - return TS7XXX_IO16_BASE + address; -} -void write_reg(unsigned long data, unsigned long address) +#ifdef MODULE + +static struct net_device dev_openeth = { + init: oeth_probe + }; + +static int io = ETH_BASE_ADD; +static int irq = IRQ_ETH_0; + +MODULE_PARM(io, "i"); +MODULE_PARM(irq, "i"); + +MODULE_LICENSE("GPL"); + +int init_module(void) { - outw((unsigned short)data>>16, &address); - outw((unsigned short)data, &address); + int result; + + dev_openeth.base_addr = io; + dev_openeth.irq = irq; + dev_openeth.init = oeth_probe; + + if ((result = register_netdev(&dev_openeth)) != 0) + return result; + + return 0; } -unsigned long read_reg(unsigned long address) +void cleanup_module(void) { - unsigned long data; - data = inw(&address); - data = data<<16 | inw(&address); - return data; + free_irq(dev_openeth.irq, &dev_openeth); + release_region(dev_openeth.base_addr, OETH_TOTAL_SIZE); + + if (dev_openeth.priv) + kfree(dev_openeth.priv); + + unregister_netdev(&dev_openeth); } +#endif /* MODULE */ + + + + Index: drivers/net/open_eth.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/open_eth.h,v retrieving revision 1.1 retrieving revision 1.6 diff -u -r1.1 -r1.6 --- drivers/net/open_eth.h 2 Jan 2006 18:36:38 -0000 1.1 +++ drivers/net/open_eth.h 27 Mar 2006 18:22:45 -0000 1.6 @@ -1,14 +1,28 @@ -///? -//#define SRAM_BUFF 1 -//#define SRAM_BUFF_BASE (FBMEM_BASE_ADD + 0x80000) -#define IRQ_ETH_0 0 -#define ETH_BASE_ADD 0x0 -#define MACADDR0 0x0 -#define MACADDR1 0x0 -#define MACADDR2 0x0 -#define MACADDR3 0x0 -#define MACADDR4 0x0 -#define MACADDR5 0x0 + +#ifndef _OPEN_ETH_H_ +#define _OPEN_ETH_H_ + +#define MICREL_PHY 0x1 + +#define IRQ_ETH_0 40 +#define ETH_BASE_ADD 0x72100000 + +#define OETH_REG_OFFSET 0x2000 +#define OETH_REG_BASE (ETH_BASE_ADD + OETH_REG_OFFSET) +#define OETH_REG_SIZE 0x400 + +#define OETH_BD_OFFSET 0x2400 +#define OETH_BD_BASE (ETH_BASE_ADD + OETH_BD_OFFSET) +#define OETH_BD_SIZE 0x400 + +#define OETH_BUF_OFFSET 0x0 +#define OETH_BUF_BASE (ETH_BASE_ADD + OETH_BUF_OFFSET) +#define OETH_BUF_SIZE 0x2000 + +#define OETH_TOTAL_SIZE (OETH_REG_SIZE + OETH_BD_SIZE + OETH_BUF_SIZE) + +#define OETH_TOTAL_BD 128 +#define OETH_MAXBUF_LEN 0x600 /* Ethernet configuration registers */ typedef struct _oeth_regs { @@ -36,19 +50,10 @@ /* Ethernet buffer descriptor */ typedef struct _oeth_bd { -#if 0 - ushort len; /* Buffer length */ - ushort status; /* Buffer status */ -#else uint len_status; -#endif uint addr; /* Buffer address */ } oeth_bd; -#define OETH_REG_BASE ETH_BASE_ADD -#define OETH_BD_BASE (ETH_BASE_ADD + 0x400) -#define OETH_TOTAL_BD 128 -#define OETH_MAXBUF_LEN 0x600 /* Tx BD */ #define OETH_TX_BD_READY 0x8000 /* Tx BD Ready */ @@ -92,6 +97,7 @@ OETH_RX_BD_CRCERR | \ OETH_RX_BD_LATECOL) + /* MODER Register */ #define OETH_MODER_RXEN 0x00000001 /* Receive Enable */ #define OETH_MODER_TXEN 0x00000002 /* Transmit Enable */ @@ -133,7 +139,7 @@ #define OETH_CTRLMODER_PASSALL 0x00000001 /* Pass Control Frames */ #define OETH_CTRLMODER_RXFLOW 0x00000002 /* Receive Control Flow Enable */ #define OETH_CTRLMODER_TXFLOW 0x00000004 /* Transmit Control Flow Enable */ - + /* MII Mode Register */ #define OETH_MIIMODER_CLKDIV 0x000000FF /* Clock Divider */ #define OETH_MIIMODER_NOPRE 0x00000100 /* No Preamble */ @@ -153,3 +159,5 @@ #define OETH_MIISTATUS_BUSY 0x00000002 /* MII Busy */ #define OETH_MIISTATUS_NVALID 0x00000004 /* Data in MII Status Register is invalid */ +#endif /* _OPEN_ETH_H_ */ + Index: drivers/net/pci-skeleton.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/pci-skeleton.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/pci-skeleton.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/pci-skeleton.c 4 Aug 2004 01:29:10 -0000 1.2 @@ -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 */ Index: drivers/net/pcnet32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/pcnet32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/pcnet32.c 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/pcnet32.c 4 Aug 2004 01:29:10 -0000 1.2 @@ -22,8 +22,8 @@ *************************************************************************/ #define DRV_NAME "pcnet32" -#define DRV_VERSION "1.27a" -#define DRV_RELDATE "10.02.2002" +#define DRV_VERSION "1.28" +#define DRV_RELDATE "02.20.2004" #define PFX DRV_NAME ": " static const char *version = @@ -61,12 +61,18 @@ static struct pci_device_id pcnet32_pci_tbl[] __devinitdata = { { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE_HOME, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + /* + * Adapters that were sold with IBM's RS/6000 or pSeries hardware have + * the incorrect vendor id. + */ + { PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_AMD_LANCE, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, 0 }, { 0, } }; MODULE_DEVICE_TABLE (pci, pcnet32_pci_tbl); -int cards_found __initdata; +static int cards_found __devinitdata; /* * VLB I/O addresses @@ -76,7 +82,7 @@ -static int pcnet32_debug = 1; +static int pcnet32_debug = 0; static int tx_start = 1; /* Mapping -- 0:20, 1:64, 2:128, 3:~220 (depends on chip vers) */ static int pcnet32vlb; /* check for VLB cards ? */ @@ -120,6 +126,11 @@ PCNET32_PORT_ASEL /* 15 not supported */ }; +static const char pcnet32_gstrings_test[][ETH_GSTRING_LEN] = { + "Loopback test (offline)" +}; +#define PCNET32_TEST_LEN (sizeof(pcnet32_gstrings_test) / ETH_GSTRING_LEN) + #define MAX_UNITS 8 /* More are supported, limit only on options */ static int options[MAX_UNITS]; static int full_duplex[MAX_UNITS]; @@ -212,6 +223,13 @@ * fix pci probe not increment cards_found * FD auto negotiate error workaround for xSeries250 * clean up and using new mii module + * v1.28 20 Feb 2004 Don Fry + * Jon Mason , Chinmay Albal + * Now uses ethtool_ops, netif_msg_* and generic_mii_ioctl. + * Fixes bogus 'Bus master arbitration failure', pci_[un]map_single + * length errors, and transmit hangs. Cleans up after errors in open. + * Jim Lewis added ethernet loopback test. + * Thomas Munck Steenholdt non-mii ioctl corrections. */ @@ -319,6 +337,7 @@ mii:1; /* mii port available */ struct net_device *next; struct mii_if_info mii_if; + u32 msg_enable; /* debug message level */ }; static void pcnet32_probe_vlbus(void); @@ -336,6 +355,10 @@ static int pcnet32_ioctl(struct net_device *, struct ifreq *, int); static int mdio_read(struct net_device *dev, int phy_id, int reg_num); static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val); +static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits); +static void pcnet32_ethtool_test(struct net_device *dev, + struct ethtool_test *eth_test, u64 *data); +static int pcnet32_loopback_test(struct net_device *dev, uint64_t *data1); enum pci_flags_bit { PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, @@ -389,13 +412,13 @@ } static struct pcnet32_access pcnet32_wio = { - read_csr: pcnet32_wio_read_csr, - write_csr: pcnet32_wio_write_csr, - read_bcr: pcnet32_wio_read_bcr, - write_bcr: pcnet32_wio_write_bcr, - read_rap: pcnet32_wio_read_rap, - write_rap: pcnet32_wio_write_rap, - reset: pcnet32_wio_reset + .read_csr = pcnet32_wio_read_csr, + .write_csr = pcnet32_wio_write_csr, + .read_bcr = pcnet32_wio_read_bcr, + .write_bcr = pcnet32_wio_write_bcr, + .read_rap = pcnet32_wio_read_rap, + .write_rap = pcnet32_wio_write_rap, + .reset = pcnet32_wio_reset }; static u16 pcnet32_dwio_read_csr (unsigned long addr, int index) @@ -444,17 +467,283 @@ } static struct pcnet32_access pcnet32_dwio = { - read_csr: pcnet32_dwio_read_csr, - write_csr: pcnet32_dwio_write_csr, - read_bcr: pcnet32_dwio_read_bcr, - write_bcr: pcnet32_dwio_write_bcr, - read_rap: pcnet32_dwio_read_rap, - write_rap: pcnet32_dwio_write_rap, - reset: pcnet32_dwio_reset + .read_csr = pcnet32_dwio_read_csr, + .write_csr = pcnet32_dwio_write_csr, + .read_bcr = pcnet32_dwio_read_bcr, + .write_bcr = pcnet32_dwio_write_bcr, + .read_rap = pcnet32_dwio_read_rap, + .write_rap = pcnet32_dwio_write_rap, + .reset = pcnet32_dwio_reset }; +static int pcnet32_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct pcnet32_private *lp = dev->priv; + unsigned long flags; + int r = -EOPNOTSUPP; + + if (lp->mii) { + spin_lock_irqsave(&lp->lock, flags); + mii_ethtool_gset(&lp->mii_if, cmd); + spin_unlock_irqrestore(&lp->lock, flags); + r = 0; + } + return r; +} + +static int pcnet32_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct pcnet32_private *lp = dev->priv; + unsigned long flags; + int r = -EOPNOTSUPP; + + if (lp->mii) { + spin_lock_irqsave(&lp->lock, flags); + r = mii_ethtool_sset(&lp->mii_if, cmd); + spin_unlock_irqrestore(&lp->lock, flags); + } + return r; +} + +static void pcnet32_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct pcnet32_private *lp = dev->priv; + + strcpy (info->driver, DRV_NAME); + strcpy (info->version, DRV_VERSION); + if (lp->pci_dev) + strcpy (info->bus_info, pci_name(lp->pci_dev)); + else + sprintf(info->bus_info, "VLB 0x%lx", dev->base_addr); +} + +static u32 pcnet32_get_link(struct net_device *dev) +{ + struct pcnet32_private *lp = dev->priv; + unsigned long flags; + int r; + + spin_lock_irqsave(&lp->lock, flags); + if (lp->mii) { + r = mii_link_ok(&lp->mii_if); + } else { + ulong ioaddr = dev->base_addr; /* card base I/O address */ + r = (lp->a.read_bcr(ioaddr, 4) != 0xc0); + } + spin_unlock_irqrestore(&lp->lock, flags); + + return r; +} + +static u32 pcnet32_get_msglevel(struct net_device *dev) +{ + struct pcnet32_private *lp = dev->priv; + return lp->msg_enable; +} + +static void pcnet32_set_msglevel(struct net_device *dev, u32 value) +{ + struct pcnet32_private *lp = dev->priv; + lp->msg_enable = value; +} + +static int pcnet32_nway_reset(struct net_device *dev) +{ + struct pcnet32_private *lp = dev->priv; + unsigned long flags; + int r = -EOPNOTSUPP; + + if (lp->mii) { + spin_lock_irqsave(&lp->lock, flags); + r = mii_nway_restart(&lp->mii_if); + spin_unlock_irqrestore(&lp->lock, flags); + } + return r; +} + +static void pcnet32_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) +{ + struct pcnet32_private *lp = dev->priv; + + ering->tx_max_pending = TX_RING_SIZE - 1; + ering->tx_pending = lp->cur_tx - lp->dirty_tx; + ering->rx_max_pending = RX_RING_SIZE - 1; + ering->rx_pending = lp->cur_rx & RX_RING_MOD_MASK; +} + +static void pcnet32_get_strings(struct net_device *dev, u32 stringset, u8 *data) +{ + memcpy(data, pcnet32_gstrings_test, sizeof(pcnet32_gstrings_test)); +} + +static int pcnet32_self_test_count(struct net_device *dev) +{ + return PCNET32_TEST_LEN; +} + +static void pcnet32_ethtool_test(struct net_device *dev, + struct ethtool_test *test, u64 *data) +{ + struct pcnet32_private *lp = dev->priv; + int rc; + + if (test->flags == ETH_TEST_FL_OFFLINE) { + rc = pcnet32_loopback_test(dev, data); + if (rc) { + if (netif_msg_hw(lp)) + printk(KERN_DEBUG "%s: Loopback test failed.\n", dev->name); + test->flags |= ETH_TEST_FL_FAILED; + } else if (netif_msg_hw(lp)) + printk(KERN_DEBUG "%s: Loopback test passed.\n", dev->name); + } else + printk(KERN_DEBUG "%s: No tests to run (specify 'Offline' on ethtool).", dev->name); +} /* end pcnet32_ethtool_test */ + +static int pcnet32_loopback_test(struct net_device *dev, uint64_t *data1) +{ + struct pcnet32_private *lp = dev->priv; + struct pcnet32_access *a = &lp->a; /* access to registers */ + ulong ioaddr = dev->base_addr; /* card base I/O address */ + struct sk_buff *skb; /* sk buff */ + int x, y, i; /* counters */ + int numbuffs = 4; /* number of TX/RX buffers and descs */ + u16 status = 0x8300; /* TX ring status */ + int rc; /* return code */ + int size; /* size of packets */ + unsigned char *packet; /* source packet data */ + static int data_len = 60; /* length of source packets */ + unsigned long flags; + + *data1 = 1; /* status of test, default to fail */ + rc = 1; /* default to fail */ + + spin_lock_irqsave(&lp->lock, flags); + lp->a.write_csr(ioaddr, 0, 0x7904); + + netif_stop_queue(dev); + + /* purge & init rings but don't actually restart */ + pcnet32_restart(dev, 0x0000); + + lp->a.write_csr(ioaddr, 0, 0x0004); /* Set STOP bit */ + + x = a->read_bcr(ioaddr, 32); /* set internal loopback in BSR32 */ + x = x | 0x00000002; + a->write_bcr(ioaddr, 32, x); + + /* Initialize Transmit buffers. */ + size = data_len + 15; + for (x=0; xname, __LINE__); + goto clean_up; + } else { + packet = skb->data; + skb_put(skb, size); /* create space for data */ + lp->tx_skbuff[x] = skb; + lp->tx_ring[x].length = le16_to_cpu(-skb->len); + lp->tx_ring[x].misc = 0x00000000; + + /* put DA and SA into the skb */ + for (i=0; i<12; i++) + *packet++ = 0xff; + /* type */ + *packet++ = 0x08; + *packet++ = 0x06; + /* packet number */ + *packet++ = x; + /* fill packet with data */ + for (y=0; ytx_dma_addr[x] = pci_map_single(lp->pci_dev, skb->data, + skb->len, PCI_DMA_TODEVICE); + lp->tx_ring[x].base = (u32)le32_to_cpu(lp->tx_dma_addr[x]); + wmb(); /* Make sure owner changes after all others are visible */ + lp->tx_ring[x].status = le16_to_cpu(status); + } + } + + lp->a.write_csr(ioaddr, 0, 0x0002); /* Set STRT bit */ + spin_unlock_irqrestore(&lp->lock, flags); + + mdelay(50); /* wait a bit */ + + spin_lock_irqsave(&lp->lock, flags); + lp->a.write_csr(ioaddr, 0, 0x0004); /* Set STOP bit */ + + if (netif_msg_hw(lp) && netif_msg_pktdata(lp)) { + printk(KERN_DEBUG "%s: RX loopback packets:\n", dev->name); + + for (x=0; xname, x); + skb=lp->rx_skbuff[x]; + for (i=0; idata+i)); + } + printk("\n"); + } + } + + x = 0; + rc = 0; + while (xrx_skbuff[x]; + packet = lp->tx_skbuff[x]->data; + for (i=0; idata+i) != packet[i]) { + if (netif_msg_hw(lp)) + printk(KERN_DEBUG "%s: Error in compare! %2x - %02x %02x\n", + dev->name, i, *(skb->data+i), packet[i]); + rc = 1; + break; + } + } + x++; + } + if (!rc) { + *data1 = 0; + } + +clean_up: + x = a->read_csr(ioaddr, 15) & 0xFFFF; + a->write_csr(ioaddr, 15, (x & ~0x0044)); /* reset bits 6 and 2 */ + + x = a->read_bcr(ioaddr, 32); /* reset internal loopback */ + x = x & ~0x00000002; + a->write_bcr(ioaddr, 32, x); + + pcnet32_restart(dev, 0x0042); /* resume normal operation */ + + netif_wake_queue(dev); + + /* Clear interrupts, and set interrupt enable. */ + lp->a.write_csr(ioaddr, 0, 0x7940); + spin_unlock_irqrestore(&lp->lock, flags); + + return(rc); +} /* end pcnet32_loopback_test */ + +static struct ethtool_ops pcnet32_ethtool_ops = { + .get_settings = pcnet32_get_settings, + .set_settings = pcnet32_set_settings, + .get_drvinfo = pcnet32_get_drvinfo, + .get_msglevel = pcnet32_get_msglevel, + .set_msglevel = pcnet32_set_msglevel, + .nway_reset = pcnet32_nway_reset, + .get_link = pcnet32_get_link, + .get_ringparam = pcnet32_get_ringparam, + .get_tx_csum = ethtool_op_get_tx_csum, + .get_sg = ethtool_op_get_sg, + .get_strings = pcnet32_get_strings, + .self_test_count = pcnet32_self_test_count, + .self_test = pcnet32_ethtool_test, +}; + /* only probes for non-PCI devices, the rest are handled by * pci_register_driver via pcnet32_probe_pci */ @@ -535,10 +824,12 @@ } chip_version = a->read_csr(ioaddr, 88) | (a->read_csr(ioaddr,89) << 16); - if (pcnet32_debug > 2) + if (pcnet32_debug & NETIF_MSG_PROBE) printk(KERN_INFO " PCnet chip version is %#x.\n", chip_version); - if ((chip_version & 0xfff) != 0x003) + if ((chip_version & 0xfff) != 0x003) { + printk(KERN_INFO PFX "Unsupported chip version.\n"); return -ENODEV; + } /* initialize variables */ fdx = mii = fset = dxsuflo = ltint = 0; @@ -589,7 +880,7 @@ media &= ~3; media |= 1; #endif - if (pcnet32_debug > 2) + if (pcnet32_debug & NETIF_MSG_PROBE) printk(KERN_DEBUG PFX "media reset to %#x.\n", media); a->write_bcr(ioaddr, 49, media); break; @@ -619,8 +910,10 @@ } dev = alloc_etherdev(0); - if(!dev) + if (!dev) { + printk(KERN_ERR PFX "Memory allocation failed.\n"); return -ENOMEM; + } printk(KERN_INFO PFX "%s at %#3lx,", chipname, ioaddr); @@ -693,6 +986,7 @@ /* pci_alloc_consistent returns page-aligned memory, so we do not have to check the alignment */ if ((lp = pci_alloc_consistent(pdev, sizeof(*lp), &lp_dma_addr)) == NULL) { + printk(KERN_ERR PFX "Consistent memory allocation failed.\n"); release_region(ioaddr, PCNET32_TOTAL_SIZE); return -ENOMEM; } @@ -707,9 +1001,12 @@ lp->name = chipname; lp->shared_irq = shared; lp->mii_if.full_duplex = fdx; + lp->mii_if.phy_id_mask = 0x1f; + lp->mii_if.reg_num_mask = 0x1f; lp->dxsuflo = dxsuflo; lp->ltint = ltint; lp->mii = mii; + lp->msg_enable = pcnet32_debug; if ((cards_found >= MAX_UNITS) || (options[cards_found] > sizeof(options_mapping))) lp->options = PCNET32_PORT_ASEL; else @@ -778,6 +1075,9 @@ } } + /* Set the mii phy_id so that we can query the link state */ + if (lp->mii) + lp->mii_if.phy_id = ((lp->a.read_bcr (ioaddr, 33)) >> 5) & 0x1f; /* The PCNET32-specific entries in the device structure. */ dev->open = &pcnet32_open; @@ -786,11 +1086,16 @@ dev->get_stats = &pcnet32_get_stats; dev->set_multicast_list = &pcnet32_set_multicast_list; dev->do_ioctl = &pcnet32_ioctl; + dev->ethtool_ops = &pcnet32_ethtool_ops; dev->tx_timeout = pcnet32_tx_timeout; dev->watchdog_timeo = (5*HZ); - lp->next = pcnet32_dev; - pcnet32_dev = dev; + if (pdev) { + pci_set_drvdata(pdev, dev); + } else { + lp->next = pcnet32_dev; + pcnet32_dev = dev; + } /* Fill in the generic fields of the device structure. */ register_netdev(dev); @@ -807,6 +1112,7 @@ unsigned long ioaddr = dev->base_addr; u16 val; int i; + int rc; if (dev->irq == 0 || request_irq(dev->irq, &pcnet32_interrupt, @@ -815,8 +1121,10 @@ } /* Check for a valid station address */ - if( !is_valid_ether_addr(dev->dev_addr) ) - return -EINVAL; + if (!is_valid_ether_addr(dev->dev_addr)) { + rc = -EINVAL; + goto err_free_irq; + } /* Reset the PCNET32 */ lp->a.reset (ioaddr); @@ -824,7 +1132,7 @@ /* switch pcnet32 to 32bit mode */ lp->a.write_bcr (ioaddr, 20, 2); - if (pcnet32_debug > 1) + if (netif_msg_ifup(lp)) printk(KERN_DEBUG "%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n", dev->name, dev->irq, (u32) (lp->dma_addr + offsetof(struct pcnet32_private, tx_ring)), @@ -890,8 +1198,10 @@ lp->init_block.mode = le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7); lp->init_block.filter[0] = 0x00000000; lp->init_block.filter[1] = 0x00000000; - if (pcnet32_init_ring(dev)) - return -ENOMEM; + if (pcnet32_init_ring(dev)) { + rc = -ENOMEM; + goto err_free_ring; + } /* Re-initialize the PCNET32, and start it when done. */ lp->a.write_csr (ioaddr, 1, (lp->dma_addr + offsetof(struct pcnet32_private, init_block)) &0xffff); @@ -912,7 +1222,7 @@ */ lp->a.write_csr (ioaddr, 0, 0x0042); - if (pcnet32_debug > 2) + if (netif_msg_ifup(lp)) printk(KERN_DEBUG "%s: pcnet32 open after %d ticks, init block %#x csr0 %4.4x.\n", dev->name, i, (u32) (lp->dma_addr + offsetof(struct pcnet32_private, init_block)), lp->a.read_csr(ioaddr, 0)); @@ -921,6 +1231,28 @@ MOD_INC_USE_COUNT; return 0; /* Always succeed */ + +err_free_ring: + /* free any allocated skbuffs */ + for (i = 0; i < RX_RING_SIZE; i++) { + lp->rx_ring[i].status = 0; + if (lp->rx_skbuff[i]) { + pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], PKT_BUF_SZ-2, + PCI_DMA_FROMDEVICE); + dev_kfree_skb(lp->rx_skbuff[i]); + } + lp->rx_skbuff[i] = NULL; + lp->rx_dma_addr[i] = 0; + } + /* + * Switch back to 16bit mode to avoid problems with dumb + * DOS packet driver after a warm reboot + */ + lp->a.write_bcr (ioaddr, 20, 4); + +err_free_irq: + free_irq(dev->irq, dev); + return rc; } /* @@ -974,9 +1306,12 @@ } 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, PKT_BUF_SZ-2, 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].buf_length = le16_to_cpu(2-PKT_BUF_SZ); lp->rx_ring[i].status = le16_to_cpu(0x8000); } /* The Tx buffer address is filled in as needed, but we do need to clear @@ -986,6 +1321,7 @@ lp->tx_ring[i].status = 0; lp->tx_dma_addr[i] = 0; } + wmb(); /* Make sure all changes are visible */ lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS); for (i = 0; i < 6; i++) @@ -1009,7 +1345,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; @@ -1029,7 +1365,7 @@ dev->name, lp->a.read_csr(ioaddr, 0)); lp->a.write_csr (ioaddr, 0, 0x0004); lp->stats.tx_errors++; - if (pcnet32_debug > 2) { + if (netif_msg_tx_err(lp)) { int i; printk(KERN_DEBUG " Ring data dump: dirty_tx %d cur_tx %d%s cur_rx %d.", lp->dirty_tx, lp->cur_tx, lp->tx_full ? " (full)" : "", @@ -1047,7 +1383,7 @@ pcnet32_restart(dev, 0x0042); dev->trans_start = jiffies; - netif_start_queue(dev); + netif_wake_queue(dev); spin_unlock_irqrestore(&lp->lock, flags); } @@ -1062,7 +1398,7 @@ int entry; unsigned long flags; - if (pcnet32_debug > 3) { + if (netif_msg_tx_queued(lp)) { printk(KERN_DEBUG "%s: pcnet32_start_xmit() called, csr0 %4.4x.\n", dev->name, lp->a.read_csr(ioaddr, 0)); } @@ -1073,12 +1409,14 @@ * interrupt when that option is available to us. */ status = 0x8300; + entry = (lp->cur_tx - lp->dirty_tx) & TX_RING_MOD_MASK; if ((lp->ltint) && - ((lp->cur_tx - lp->dirty_tx == TX_RING_SIZE/2) || - (lp->cur_tx - lp->dirty_tx >= TX_RING_SIZE-2))) + ((entry == TX_RING_SIZE/3) || + (entry == (TX_RING_SIZE*2)/3) || + (entry >= TX_RING_SIZE-2))) { /* Enable Successful-TxDone interrupt if we have - * 1/2 of, or nearly all of, our ring buffer Tx'd + * 1/3, 2/3 or nearly all of, our ring buffer Tx'd * but not yet cleaned up. Thus, most of the time, * we will not enable Successful-TxDone interrupts. */ @@ -1090,7 +1428,7 @@ /* Mask to ring buffer boundary. */ entry = lp->cur_tx & TX_RING_MOD_MASK; - /* Caution: the write order is important here, set the base address + /* Caution: the write order is important here, set the status with the "ownership" bits last. */ lp->tx_ring[entry].length = le16_to_cpu(-skb->len); @@ -1100,6 +1438,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++; @@ -1110,9 +1449,7 @@ dev->trans_start = jiffies; - if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base == 0) - netif_start_queue(dev); - else { + if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base != 0) { lp->tx_full = 1; netif_stop_queue(dev); } @@ -1144,12 +1481,15 @@ rap = lp->a.read_rap(ioaddr); while ((csr0 = lp->a.read_csr (ioaddr, 0)) & 0x8600 && --boguscnt >= 0) { + if (csr0 == 0xffff) { + break; /* PCMCIA remove happened */ + } /* Acknowledge all of the current interrupt sources ASAP. */ lp->a.write_csr (ioaddr, 0, csr0 & ~0x004f); must_restart = 0; - if (pcnet32_debug > 5) + if (netif_msg_intr(lp)) printk(KERN_DEBUG "%s: interrupt csr0=%#2.2x new csr=%#2.2x.\n", dev->name, csr0, lp->a.read_csr (ioaddr, 0)); @@ -1158,8 +1498,9 @@ if (csr0 & 0x0200) { /* Tx-done interrupt */ unsigned int dirty_tx = lp->dirty_tx; + int delta; - while (dirty_tx < lp->cur_tx) { + while (dirty_tx != lp->cur_tx) { int entry = dirty_tx & TX_RING_MOD_MASK; int status = (short)le16_to_cpu(lp->tx_ring[entry].status); @@ -1213,15 +1554,17 @@ dirty_tx++; } - if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) { + delta = (lp->cur_tx - dirty_tx) & (TX_RING_MOD_MASK + TX_RING_SIZE); + if (delta >= TX_RING_SIZE) { printk(KERN_ERR "%s: out-of-sync dirty pointer, %d vs. %d, full=%d.\n", dev->name, dirty_tx, lp->cur_tx, lp->tx_full); dirty_tx += TX_RING_SIZE; + delta -= TX_RING_SIZE; } if (lp->tx_full && netif_queue_stopped(dev) && - dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) { + delta < TX_RING_SIZE - 2) { /* The ring is no longer full, clear tbusy. */ lp->tx_full = 0; netif_wake_queue (dev); @@ -1261,7 +1604,7 @@ lp->a.write_csr (ioaddr, 0, 0x7940); lp->a.write_rap (ioaddr,rap); - if (pcnet32_debug > 4) + if (netif_msg_intr(lp)) printk(KERN_DEBUG "%s: exiting interrupt, csr0=%#4.4x.\n", dev->name, lp->a.read_csr (ioaddr, 0)); @@ -1309,13 +1652,14 @@ if ((newskb = dev_alloc_skb (PKT_BUF_SZ))) { skb_reserve (newskb, 2); skb = lp->rx_skbuff[entry]; - pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[entry], skb->len, PCI_DMA_FROMDEVICE); + pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[entry], + PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE); skb_put (skb, pkt_len); lp->rx_skbuff[entry] = newskb; newskb->dev = dev; lp->rx_dma_addr[entry] = pci_map_single(lp->pci_dev, newskb->tail, - newskb->len, PCI_DMA_FROMDEVICE); + PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE); lp->rx_ring[entry].base = le32_to_cpu(lp->rx_dma_addr[entry]); rx_in_place = 1; } else @@ -1342,6 +1686,10 @@ if (!rx_in_place) { skb_reserve(skb,2); /* 16 byte align */ skb_put(skb,pkt_len); /* Make room */ + pci_dma_sync_single(lp->pci_dev, + lp->rx_dma_addr[entry], + PKT_BUF_SZ-2, + PCI_DMA_FROMDEVICE); eth_copy_and_sum(skb, (unsigned char *)(lp->rx_skbuff[entry]->tail), pkt_len,0); @@ -1357,7 +1705,8 @@ * The docs say that the buffer length isn't touched, but Andrew Boyd * of QNX reports that some revs of the 79C965 clear it. */ - lp->rx_ring[entry].buf_length = le16_to_cpu(-PKT_BUF_SZ); + lp->rx_ring[entry].buf_length = le16_to_cpu(2-PKT_BUF_SZ); + wmb(); /* Make sure owner changes after all others are visible */ lp->rx_ring[entry].status |= le16_to_cpu(0x8000); entry = (++lp->cur_rx) & RX_RING_MOD_MASK; } @@ -1376,7 +1725,7 @@ lp->stats.rx_missed_errors = lp->a.read_csr (ioaddr, 112); - if (pcnet32_debug > 1) + if (netif_msg_ifdown(lp)) printk(KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n", dev->name, lp->a.read_csr (ioaddr, 0)); @@ -1395,7 +1744,8 @@ for (i = 0; i < RX_RING_SIZE; i++) { lp->rx_ring[i].status = 0; if (lp->rx_skbuff[i]) { - pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], lp->rx_skbuff[i]->len, PCI_DMA_FROMDEVICE); + pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], PKT_BUF_SZ-2, + PCI_DMA_FROMDEVICE); dev_kfree_skb(lp->rx_skbuff[i]); } lp->rx_skbuff[i] = NULL; @@ -1465,7 +1815,9 @@ crc = ether_crc_le(6, addrs); crc = crc >> 26; - mcast_table [crc >> 4] |= cpu_to_le16(1 << (crc & 0xf)); + mcast_table [crc >> 4] = le16_to_cpu( + le16_to_cpu(mcast_table [crc >> 4]) | (1 << (crc & 0xf)) + ); } return; } @@ -1530,136 +1882,49 @@ lp->a.write_bcr(ioaddr, 33, phyaddr); } -static int pcnet32_ethtool_ioctl (struct net_device *dev, void *useraddr) +static int pcnet32_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct pcnet32_private *lp = dev->priv; - u32 ethcmd; - int phyaddr = 0; - int phy_id = 0; - unsigned long ioaddr = dev->base_addr; - - if (lp->mii) { - phyaddr = lp->a.read_bcr (ioaddr, 33); - phy_id = (phyaddr >> 5) & 0x1f; - lp->mii_if.phy_id = phy_id; - } - - 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_NAME); - strcpy (info.version, DRV_VERSION); - if (lp->pci_dev) - strcpy (info.bus_info, lp->pci_dev->slot_name); - else - sprintf(info.bus_info, "VLB 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - /* 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: { - int r; - struct ethtool_cmd ecmd; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - spin_lock_irq(&lp->lock); - r = mii_ethtool_sset(&lp->mii_if, &ecmd); - spin_unlock_irq(&lp->lock); - return r; - } - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - return mii_nway_restart(&lp->mii_if); - } - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = {ETHTOOL_GLINK}; - edata.data = mii_link_ok(&lp->mii_if); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } + struct pcnet32_private *lp = dev->priv; + struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data; + int rc; + unsigned long flags; - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = pcnet32_debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - pcnet32_debug = edata.data; - return 0; - } - default: - break; - } + /* SIOC[GS]MIIxxx ioctls */ + if (lp->mii) { + spin_lock_irqsave(&lp->lock, flags); + rc = generic_mii_ioctl(&lp->mii_if, data, cmd, NULL); + spin_unlock_irqrestore(&lp->lock, flags); + } else { + rc = -EOPNOTSUPP; + } - return -EOPNOTSUPP; + return rc; } -static int pcnet32_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +static void __devexit pcnet32_remove_one(struct pci_dev *pdev) { - unsigned long ioaddr = dev->base_addr; - struct pcnet32_private *lp = dev->priv; - struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data; - int phyaddr = lp->a.read_bcr (ioaddr, 33); + struct net_device *dev = pci_get_drvdata(pdev); - if (cmd == SIOCETHTOOL) - return pcnet32_ethtool_ioctl(dev, (void *) rq->ifr_data); + if (dev) { + struct pcnet32_private *lp = dev->priv; - if (lp->mii) { - switch(cmd) { - case SIOCGMIIPHY: /* Get address of MII PHY in use. */ - data->phy_id = (phyaddr >> 5) & 0x1f; - /* Fall Through */ - case SIOCGMIIREG: /* Read MII PHY register. */ - lp->a.write_bcr (ioaddr, 33, ((data->phy_id & 0x1f) << 5) | (data->reg_num & 0x1f)); - data->val_out = lp->a.read_bcr (ioaddr, 34); - lp->a.write_bcr (ioaddr, 33, phyaddr); - return 0; - case SIOCSMIIREG: /* Write MII PHY register. */ - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - lp->a.write_bcr (ioaddr, 33, ((data->phy_id & 0x1f) << 5) | (data->reg_num & 0x1f)); - lp->a.write_bcr (ioaddr, 34, data->val_in); - lp->a.write_bcr (ioaddr, 33, phyaddr); - return 0; - default: - return -EOPNOTSUPP; - } + unregister_netdev(dev); + release_region(dev->base_addr, PCNET32_TOTAL_SIZE); + pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); + free_netdev(dev); + pci_set_drvdata(pdev, NULL); } - return -EOPNOTSUPP; } static struct pci_driver pcnet32_driver = { - name: DRV_NAME, - probe: pcnet32_probe_pci, - id_table: pcnet32_pci_tbl, + .name = DRV_NAME, + .probe = pcnet32_probe_pci, + .remove = __devexit_p(pcnet32_remove_one), + .id_table = pcnet32_pci_tbl, }; MODULE_PARM(debug, "i"); -MODULE_PARM_DESC(debug, DRV_NAME " debug level (0-6)"); +MODULE_PARM_DESC(debug, DRV_NAME " debug level"); MODULE_PARM(max_interrupt_work, "i"); MODULE_PARM_DESC(max_interrupt_work, DRV_NAME " maximum events handled per interrupt"); MODULE_PARM(rx_copybreak, "i"); @@ -1680,19 +1945,21 @@ /* An additional parameter that may be passed in... */ static int debug = -1; static int tx_start_pt = -1; +static int pcnet32_have_pci; static int __init pcnet32_init_module(void) { printk(KERN_INFO "%s", version); - if (debug > 0) - pcnet32_debug = debug; + if (debug >= 0 && debug < (sizeof(int) - 1)) + pcnet32_debug = 1 << debug; if ((tx_start_pt >= 0) && (tx_start_pt <= 3)) tx_start = tx_start_pt; /* find the PCI devices */ - pci_module_init(&pcnet32_driver); + if (!pci_module_init(&pcnet32_driver)) + pcnet32_have_pci = 1; /* should we find any remaining VLbus devices ? */ if (pcnet32vlb) @@ -1701,7 +1968,7 @@ if (cards_found) printk(KERN_INFO PFX "%d cards_found.\n", cards_found); - return cards_found ? 0 : -ENODEV; + return (pcnet32_have_pci + cards_found) ? 0 : -ENODEV; } static void __exit pcnet32_cleanup_module(void) @@ -1714,12 +1981,12 @@ next_dev = lp->next; unregister_netdev(pcnet32_dev); release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE); - if (lp->pci_dev) - pci_unregister_driver(&pcnet32_driver); pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); - kfree(pcnet32_dev); + free_netdev(pcnet32_dev); pcnet32_dev = next_dev; } + if (pcnet32_have_pci) + pci_unregister_driver(&pcnet32_driver); } module_init(pcnet32_init_module); Index: drivers/net/plip.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/plip.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/plip.c 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/plip.c 4 Aug 2004 01:29:10 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: plip.c,v 1.1 2004/07/22 19:49:33 joff Exp $ */ +/* $Id: plip.c,v 1.2 2004/08/04 01:29:10 joff Exp $ */ /* PLIP: A parallel port "network" driver for Linux. */ /* This driver is for parallel port with 5-bit cable (LapLink (R) cable). */ /* @@ -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) Index: drivers/net/ppp_deflate.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/ppp_deflate.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/ppp_deflate.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/ppp_deflate.c 4 Aug 2004 01:29:11 -0000 1.2 @@ -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; Index: drivers/net/ppp_generic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/ppp_generic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/ppp_generic.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/ppp_generic.c 4 Aug 2004 01:29:11 -0000 1.2 @@ -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); Index: drivers/net/pppoe.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/pppoe.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/pppoe.c 22 Jul 2004 19:49:35 -0000 1.1 +++ drivers/net/pppoe.c 4 Aug 2004 01:29:11 -0000 1.2 @@ -365,7 +365,8 @@ if (!__pppoe_xmit( relay_po->sk , skb)) goto abort_put; } else { - sock_queue_rcv_skb(sk, skb); + if (sock_queue_rcv_skb(sk, skb)) + goto abort_kfree; } return NET_RX_SUCCESS; @@ -605,7 +606,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; @@ -653,8 +655,10 @@ release_sock(sk); return error; err_put: - dev_put(po->pppoe_dev); - po->pppoe_dev = NULL; + if (po->pppoe_dev) { + dev_put(po->pppoe_dev); + po->pppoe_dev = NULL; + } goto end; } Index: drivers/net/ptifddi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/ptifddi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/ptifddi.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/ptifddi.c 4 Aug 2004 01:29:11 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ptifddi.c,v 1.1 2004/07/22 19:49:31 joff Exp $ +/* $Id: ptifddi.c,v 1.2 2004/08/04 01:29:11 joff Exp $ * ptifddi.c: Network driver for Performance Technologies single-attach * and dual-attach FDDI sbus cards. * Index: drivers/net/ptifddi.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/ptifddi.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/ptifddi.h 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/ptifddi.h 4 Aug 2004 01:29:11 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ptifddi.h,v 1.1 2004/07/22 19:49:31 joff Exp $ +/* $Id: ptifddi.h,v 1.2 2004/08/04 01:29:11 joff Exp $ * ptifddi.c: Defines for Performance Technologies FDDI sbus cards. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) Index: drivers/net/ptifddi_asm.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/ptifddi_asm.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/ptifddi_asm.h 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/ptifddi_asm.h 4 Aug 2004 01:29:11 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ptifddi_asm.h,v 1.1 2004/07/22 19:49:32 joff Exp $ */ +/* $Id: ptifddi_asm.h,v 1.2 2004/08/04 01:29:11 joff Exp $ */ #ifndef _PTIFDDI_ASM_H #define _PTIFDDI_ASM_H Index: drivers/net/r8169.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/r8169.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/r8169.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/r8169.c 4 Aug 2004 01:29:11 -0000 1.2 @@ -42,6 +42,7 @@ #include #include #include + #include #define RTL8169_VERSION "1.2" @@ -291,6 +292,7 @@ MODULE_AUTHOR("Realtek"); MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver"); MODULE_PARM(media, "1-" __MODULE_STRING(MAX_UNITS) "i"); +MODULE_LICENSE("GPL"); static int rtl8169_open(struct net_device *dev); static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev); @@ -364,8 +366,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 +391,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 +450,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 +466,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 +479,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 +507,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 +632,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 +645,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 +833,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; } @@ -863,7 +874,6 @@ void *ioaddr) { unsigned long dirty_tx, tx_left = 0; - int entry = tp->cur_tx % NUM_TX_DESC; assert(dev != NULL); assert(tp != NULL); @@ -873,14 +883,18 @@ tx_left = tp->cur_tx - dirty_tx; while (tx_left > 0) { + int entry = dirty_tx % NUM_TX_DESC; + if ((tp->TxDescArray[entry].status & OWNbit) == 0) { - dev_kfree_skb_irq(tp-> - Tx_skbuff[dirty_tx % NUM_TX_DESC]); - tp->Tx_skbuff[dirty_tx % NUM_TX_DESC] = NULL; + struct sk_buff *skb = tp->Tx_skbuff[entry]; + + tp->stats.tx_bytes += skb->len >= ETH_ZLEN ? + skb->len : ETH_ZLEN; tp->stats.tx_packets++; + dev_kfree_skb_irq(skb); + tp->Tx_skbuff[entry] = NULL; dirty_tx++; tx_left--; - entry++; } } Index: drivers/net/rclanmtl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/rclanmtl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/rclanmtl.c 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/rclanmtl.c 4 Aug 2004 01:29:11 -0000 1.2 @@ -2,7 +2,7 @@ ** ************************************************************************* ** ** -** R C L A N M T L . C $Revision: 1.1 $ +** R C L A N M T L . C $Revision: 1.2 $ ** ** ** RedCreek I2O LAN Message Transport Layer program module. Index: drivers/net/rclanmtl.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/rclanmtl.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/rclanmtl.h 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/rclanmtl.h 4 Aug 2004 01:29:11 -0000 1.2 @@ -2,7 +2,7 @@ ** ************************************************************************* ** ** -** R C L A N M T L . H $Revision: 1.1 $ +** R C L A N M T L . H $Revision: 1.2 $ ** ** ** RedCreek I2O LAN Message Transport Layer header file. Index: drivers/net/rcpci45.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/rcpci45.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/rcpci45.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/rcpci45.c 4 Aug 2004 01:29:11 -0000 1.2 @@ -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", Index: drivers/net/sb1250-mac.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sb1250-mac.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sb1250-mac.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/sb1250-mac.c 4 Aug 2004 01:29:11 -0000 1.2 @@ -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 @@ -17,10 +17,10 @@ */ /* - This driver is designed for the Broadcom BCM12500 SOC chip's built-in + This driver is designed for the Broadcom SiByte SOC built-in Ethernet controllers. - The author may be reached as mpl@broadcom.com + Written by Mitch Lichtenberg at Broadcom Corp. */ @@ -31,6 +31,7 @@ These may be modified when a driver module is loaded. */ static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */ +static int noisy_mii = 1; /* mii status msgs */ /* Used to pass the media type, etc. Both 'options[]' and 'full_duplex[]' should exist for driver @@ -44,8 +45,10 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1}; #endif +#ifdef CONFIG_SBMAC_COALESCE static int int_pktcnt = 0; static int int_timeout = 0; +#endif /* Operational parameters that usually are not changed. */ @@ -74,8 +77,7 @@ #include /* Processor type for cache alignment. */ #include #include -#include -#include +#include /* This is only here until the firmware is ready. In that case, the firmware leaves the ethernet address in the register for us. */ @@ -89,26 +91,29 @@ /* These identify the driver base version and may not be removed. */ #if 0 static char version1[] __devinitdata = -"sb1250-mac.c:1.00 1/11/2001 Written by Mitch Lichtenberg (mpl@broadcom.com)\n"; +"sb1250-mac.c:1.00 1/11/2001 Written by Mitch Lichtenberg\n"; #endif -MODULE_AUTHOR("Mitch Lichtenberg (mpl@broadcom.com)"); -MODULE_DESCRIPTION("Broadcom BCM12500 SOC GB Ethernet driver"); +MODULE_AUTHOR("Mitch Lichtenberg (Broadcom Corp.)"); +MODULE_DESCRIPTION("Broadcom SiByte SOC GB Ethernet driver"); MODULE_PARM(debug, "i"); +MODULE_PARM(noisy_mii, "i"); MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i"); MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); MODULE_PARM(int_pktcnt, "i"); MODULE_PARM(int_timeout, "i"); +#include #include #include #include #include #include -#include /* Only to check SOC part number. */ +#include +#include /********************************************************************** @@ -117,8 +122,6 @@ typedef unsigned long sbmac_port_t; -typedef uint64_t sbmac_physaddr_t; -typedef uint64_t sbmac_enetaddr_t; typedef enum { sbmac_speed_auto, sbmac_speed_10, sbmac_speed_100, sbmac_speed_1000 } sbmac_speed_t; @@ -142,17 +145,11 @@ (d)->sbdma_dscrtable : (d)->f+1) -#define CACHELINESIZE 32 -#define NUMCACHEBLKS(x) (((x)+CACHELINESIZE-1)/CACHELINESIZE) -#define KMALLOC(x) kmalloc((x),GFP_KERNEL) -#define KFREE(x) kfree(x) -#define KVTOPHYS(x) virt_to_bus((void *)(x)) +#define NUMCACHEBLKS(x) (((x)+SMP_CACHE_BYTES-1)/SMP_CACHE_BYTES) +#define SBMAC_READCSR(t) in64((unsigned long)t) +#define SBMAC_WRITECSR(t,v) out64(v, (unsigned long)t) -#define SBMAC_READCSR(t) (in64((unsigned long)(t))) -#define SBMAC_WRITECSR(t,v) (out64(v, (unsigned long)(t))) - -#define PKSEG1(x) ((sbmac_port_t) KSEG1ADDR(x)) #define SBMAC_MAX_TXDESCR 32 #define SBMAC_MAX_RXDESCR 32 @@ -172,7 +169,6 @@ } sbdmadscr_t; typedef unsigned long paddr_t; -typedef unsigned long vaddr_t; /********************************************************************** * DMA Controller structure @@ -190,8 +186,8 @@ int sbdma_txdir; /* direction (1=transmit) */ int sbdma_maxdescr; /* total # of descriptors in ring */ #ifdef CONFIG_SBMAC_COALESCE - int sbdma_int_pktcnt; /* # descriptors rx before interrupt*/ - int sbdma_int_timeout; /* # usec rx interrupt */ + int sbdma_int_pktcnt; /* # descriptors rx/tx before interrupt*/ + int sbdma_int_timeout; /* # usec rx/tx interrupt */ #endif sbmac_port_t sbdma_config0; /* DMA config register 0 */ @@ -212,7 +208,6 @@ paddr_t sbdma_dscrtable_phys; /* and also the phys addr */ sbdmadscr_t *sbdma_addptr; /* next dscr for sw to add */ sbdmadscr_t *sbdma_remptr; /* next dscr for sw to remove */ - } sbmacdma_t; @@ -232,10 +227,10 @@ struct net_device_stats sbm_stats; int sbm_devflags; /* current device flags */ - int sbm_phy_oldbmsr; - int sbm_phy_oldanlpar; - int sbm_phy_oldk1stsr; - int sbm_phy_oldlinkstat; + int sbm_phy_oldbmsr; + int sbm_phy_oldanlpar; + int sbm_phy_oldk1stsr; + int sbm_phy_oldlinkstat; int sbm_buffersize; unsigned char sbm_phys[2]; @@ -244,7 +239,7 @@ * Controller-specific things */ - sbmac_port_t sbm_base; /* MAC's base address */ + unsigned long sbm_base; /* MAC's base address */ sbmac_state_t sbm_state; /* current state */ sbmac_port_t sbm_macenable; /* MAC Enable Register */ @@ -260,13 +255,12 @@ sbmac_duplex_t sbm_duplex; /* current duplex */ sbmac_fc_t sbm_fc; /* current flow control setting */ - u_char sbm_hwaddr[ETHER_ADDR_LEN]; + unsigned char sbm_hwaddr[ETHER_ADDR_LEN]; sbmacdma_t sbm_txdma; /* for now, only use channel 0 */ sbmacdma_t sbm_rxdma; int rx_hw_checksum; int sbe_idx; - }; @@ -295,12 +289,11 @@ static void sbmac_channel_stop(struct sbmac_softc *s); static sbmac_state_t sbmac_set_channel_state(struct sbmac_softc *,sbmac_state_t); static void sbmac_promiscuous_mode(struct sbmac_softc *sc,int onoff); -/*static void sbmac_init_and_start(struct sbmac_softc *sc);*/ static uint64_t sbmac_addr2reg(unsigned char *ptr); static void sbmac_intr(int irq,void *dev_instance,struct pt_regs *rgs); static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev); static void sbmac_setmulti(struct sbmac_softc *sc); -static int sbmac_init(struct net_device *dev); +static int sbmac_init(struct net_device *dev, int idx); static int sbmac_set_speed(struct sbmac_softc *s,sbmac_speed_t speed); static int sbmac_set_duplex(struct sbmac_softc *s,sbmac_duplex_t duplex,sbmac_fc_t fc); @@ -325,7 +318,6 @@ ********************************************************************* */ static uint64_t sbmac_orig_hwaddr[MAX_UNITS]; -static uint64_t chip_revision; /********************************************************************** @@ -347,8 +339,8 @@ #define BMCR_DUPLEX 0x0100 #define BMCR_COLTEST 0x0080 #define BMCR_SPEED1 0x0040 -#define BMCR_SPEED1000 (BMCR_SPEED1) -#define BMCR_SPEED100 (BMCR_SPEED0) +#define BMCR_SPEED1000 BMCR_SPEED1 +#define BMCR_SPEED100 BMCR_SPEED0 #define BMCR_SPEED10 0 #define BMSR_100BT4 0x8000 @@ -511,7 +503,8 @@ curmask = 1 << (bitcnt - 1); for (i = 0; i < bitcnt; i++) { - if (data & curmask) bits |= M_MAC_MDIO_OUT; + if (data & curmask) + bits |= M_MAC_MDIO_OUT; else bits &= ~M_MAC_MDIO_OUT; SBMAC_WRITECSR(s->sbm_mdio,bits); SBMAC_WRITECSR(s->sbm_mdio,bits | M_MAC_MDC); @@ -533,7 +526,7 @@ * regidx = index of register to read * * Return value: - * value read, or 0 if an error occured. + * value read, or 0 if an error occurred. ********************************************************************* */ static unsigned int sbmac_mii_read(struct sbmac_softc *s,int phyaddr,int regidx) @@ -575,7 +568,7 @@ SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT); /* - * If an error occured, the PHY will signal '1' back + * If an error occurred, the PHY will signal '1' back */ error = SBMAC_READCSR(s->sbm_mdio) & M_MAC_MDIO_IN; @@ -592,7 +585,8 @@ regval <<= 1; if (error == 0) { - if (SBMAC_READCSR(s->sbm_mdio) & M_MAC_MDIO_IN) regval |= 1; + if (SBMAC_READCSR(s->sbm_mdio) & M_MAC_MDIO_IN) + regval |= 1; } SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT | M_MAC_MDC); @@ -602,7 +596,8 @@ /* Switch back to output */ SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_OUTPUT); - if (error == 0) return regval; + if (error == 0) + return regval; return 0; } @@ -672,66 +667,68 @@ d->sbdma_channel = chan; d->sbdma_txdir = txrx; +#if 0 /* RMON clearing */ s->sbe_idx =(s->sbm_base - A_MAC_BASE_0)/MAC_SPACING; +#endif - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BYTES)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_COLLISIONS)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_LATE_COL)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_EX_COL)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_FCS_ERROR)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_ABORT)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BAD)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_GOOD)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_RUNT)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_OVERSIZE)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BYTES)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_MCAST)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BCAST)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BAD)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_GOOD)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_RUNT)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_OVERSIZE)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_FCS_ERROR)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_LENGTH_ERROR)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_CODE_ERROR)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_ALIGN_ERROR)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BYTES)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_COLLISIONS)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_LATE_COL)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_EX_COL)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_FCS_ERROR)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_ABORT)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BAD)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_GOOD)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_RUNT)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_OVERSIZE)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BYTES)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_MCAST)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BCAST)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BAD)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_GOOD)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_RUNT)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_OVERSIZE)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_FCS_ERROR)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_LENGTH_ERROR)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_CODE_ERROR)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_ALIGN_ERROR)), 0); /* * initialize register pointers */ d->sbdma_config0 = - PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG0)); + s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG0); d->sbdma_config1 = - PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG1)); + s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG1); d->sbdma_dscrbase = - PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_BASE)); + s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_BASE); d->sbdma_dscrcnt = - PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_CNT)); + s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_CNT); d->sbdma_curdscr = - PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CUR_DSCRADDR)); + s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CUR_DSCRADDR); /* * Allocate memory for the ring @@ -740,47 +737,39 @@ d->sbdma_maxdescr = maxdescr; d->sbdma_dscrtable = (sbdmadscr_t *) - KMALLOC(d->sbdma_maxdescr*sizeof(sbdmadscr_t)); + kmalloc(d->sbdma_maxdescr*sizeof(sbdmadscr_t), GFP_KERNEL); memset(d->sbdma_dscrtable,0,d->sbdma_maxdescr*sizeof(sbdmadscr_t)); d->sbdma_dscrtable_end = d->sbdma_dscrtable + d->sbdma_maxdescr; - d->sbdma_dscrtable_phys = KVTOPHYS(d->sbdma_dscrtable); + d->sbdma_dscrtable_phys = virt_to_phys(d->sbdma_dscrtable); /* * And context table */ d->sbdma_ctxtable = (struct sk_buff **) - KMALLOC(d->sbdma_maxdescr*sizeof(struct sk_buff *)); + kmalloc(d->sbdma_maxdescr*sizeof(struct sk_buff *), GFP_KERNEL); memset(d->sbdma_ctxtable,0,d->sbdma_maxdescr*sizeof(struct sk_buff *)); #ifdef CONFIG_SBMAC_COALESCE - /* - * Setup Rx DMA coalescing defaults - */ - - if ( txrx == DMA_RX ) { - if ( int_pktcnt ) { - d->sbdma_int_pktcnt = int_pktcnt; - } - else { - d->sbdma_int_pktcnt = 1; - } + /* + * Setup Rx/Tx DMA coalescing defaults + */ - if ( int_timeout ) { - d->sbdma_int_timeout = int_timeout; - } - else { - d->sbdma_int_timeout = 0; - } - } - else { - d->sbdma_int_pktcnt = 0; - d->sbdma_int_timeout = 0; - } + if ( int_pktcnt ) { + d->sbdma_int_pktcnt = int_pktcnt; + } else { + d->sbdma_int_pktcnt = 1; + } + + if ( int_timeout ) { + d->sbdma_int_timeout = int_timeout; + } else { + d->sbdma_int_timeout = 0; + } #endif } @@ -800,43 +789,34 @@ static void sbdma_channel_start(sbmacdma_t *d, int rxtx ) { - /* - * Turn on the DMA channel - */ + /* + * Turn on the DMA channel + */ #ifdef CONFIG_SBMAC_COALESCE - if (rxtx == DMA_RX) { - SBMAC_WRITECSR(d->sbdma_config1, + SBMAC_WRITECSR(d->sbdma_config1, V_DMA_INT_TIMEOUT(d->sbdma_int_timeout) | 0); - SBMAC_WRITECSR(d->sbdma_config0, - M_DMA_EOP_INT_EN | - V_DMA_RINGSZ(d->sbdma_maxdescr) | - V_DMA_INT_PKTCNT(d->sbdma_int_pktcnt) | - 0); - } - else { - SBMAC_WRITECSR(d->sbdma_config1,0); SBMAC_WRITECSR(d->sbdma_config0, + M_DMA_EOP_INT_EN | V_DMA_RINGSZ(d->sbdma_maxdescr) | + V_DMA_INT_PKTCNT(d->sbdma_int_pktcnt) | 0); - } #else - SBMAC_WRITECSR(d->sbdma_config1,0); - SBMAC_WRITECSR(d->sbdma_config0, - V_DMA_RINGSZ(d->sbdma_maxdescr) | - 0); + SBMAC_WRITECSR(d->sbdma_config1,0); + SBMAC_WRITECSR(d->sbdma_config0, + V_DMA_RINGSZ(d->sbdma_maxdescr) | + 0); #endif - - SBMAC_WRITECSR(d->sbdma_dscrbase,d->sbdma_dscrtable_phys); - - /* - * Initialize ring pointers - */ - - d->sbdma_addptr = d->sbdma_dscrtable; - d->sbdma_remptr = d->sbdma_dscrtable; + SBMAC_WRITECSR(d->sbdma_dscrbase,d->sbdma_dscrtable_phys); + + /* + * Initialize ring pointers + */ + + d->sbdma_addptr = d->sbdma_dscrtable; + d->sbdma_remptr = d->sbdma_dscrtable; } /********************************************************************** @@ -921,7 +901,7 @@ if (nextdsc == d->sbdma_remptr) { return -ENOSPC; } - + /* * Allocate a sk_buff if we don't already have one. * If we do have an sk_buff, reset it so that it's empty. @@ -935,22 +915,22 @@ * 3. The buffer can be aligned such that the IP addresses are * naturally aligned. * - * Remember, the SB1250's MAC writes whole cache lines at a time, + * Remember, the SOCs MAC writes whole cache lines at a time, * without reading the old contents first. So, if the sk_buff's - * data portion starts in the middle of a cache line, the SB1250 + * data portion starts in the middle of a cache line, the SOC * DMA will trash the beginning (and ending) portions. */ if (sb == NULL) { - sb_new = dev_alloc_skb(ENET_PACKET_SIZE + CACHELINESIZE*2 + ETHER_ALIGN); + sb_new = dev_alloc_skb(ENET_PACKET_SIZE + SMP_CACHE_BYTES * 2 + ETHER_ALIGN); if (sb_new == NULL) { printk(KERN_INFO "%s: sk_buff allocation failed\n", d->sbdma_eth->sbm_dev->name); return -ENOBUFS; } - - sbdma_align_skb(sb_new,CACHELINESIZE,ETHER_ALIGN); - + + sbdma_align_skb(sb_new, SMP_CACHE_BYTES, ETHER_ALIGN); + /* mark skbuff owned by our device */ sb_new->dev = d->sbdma_eth->sbm_dev; } @@ -958,7 +938,7 @@ sb_new = sb; /* * nothing special to reinit buffer, it's already aligned - * and sb->tail already points to a good place. + * and sb->data already points to a good place. */ } @@ -967,18 +947,18 @@ */ #ifdef CONFIG_SBMAC_COALESCE - /* - * Do not interrupt per DMA transfer. - */ - dsc->dscr_a = KVTOPHYS(sb_new->tail) | - V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | - 0; + /* + * Do not interrupt per DMA transfer. + */ + dsc->dscr_a = virt_to_phys(sb_new->tail) | + V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | + 0; #else - dsc->dscr_a = KVTOPHYS(sb_new->tail) | + dsc->dscr_a = virt_to_phys(sb_new->tail) | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | M_DMA_DSCRA_INTERRUPT; #endif - + /* receiving: no options */ dsc->dscr_b = 0; @@ -1057,12 +1037,14 @@ * while doing the calculation. */ - phys = KVTOPHYS(sb->data); - ncb = NUMCACHEBLKS(length+(phys & (CACHELINESIZE-1))); - + phys = virt_to_phys(sb->data); + ncb = NUMCACHEBLKS(length+(phys & (SMP_CACHE_BYTES - 1))); + dsc->dscr_a = phys | V_DMA_DSCRA_A_SIZE(ncb) | +#ifndef CONFIG_SBMAC_COALESCE M_DMA_DSCRA_INTERRUPT | +#endif M_DMA_ETHTX_SOP; /* transmitting: set outbound options and length */ @@ -1139,7 +1121,8 @@ int idx; for (idx = 0; idx < SBMAC_MAX_RXDESCR-1; idx++) { - if (sbdma_add_rcvbuffer(d,NULL) != 0) break; + if (sbdma_add_rcvbuffer(d,NULL) != 0) + break; } } @@ -1190,7 +1173,8 @@ * the hardware is working on right now. */ - if (curidx == hwidx) break; + if (curidx == hwidx) + break; /* * Otherwise, get the packet's sk_buff ptr back @@ -1211,49 +1195,47 @@ if (!(dsc->dscr_a & M_DMA_ETHRX_BAD)) { /* - * Set length into the packet - */ - skb_put(sb,len); - - /* * Add a new buffer to replace the old one. If we fail * to allocate a buffer, we're going to drop this * packet and put it right back on the receive ring. */ if (sbdma_add_rcvbuffer(d,NULL) == -ENOBUFS) { - sbdma_add_rcvbuffer(d,sb); /* re-add old buffer */ - } - else { - /* - * Buffer has been replaced on the receive ring. - * Pass the buffer to the kernel - */ - sc->sbm_stats.rx_bytes += len; - sc->sbm_stats.rx_packets++; - sb->protocol = eth_type_trans(sb,d->sbdma_eth->sbm_dev); - if (sc->rx_hw_checksum == ENABLE) { - /* if the ip checksum is good indicate in skb. - else set CHECKSUM_NONE as device failed to - checksum the packet */ - - if (((dsc->dscr_b) |M_DMA_ETHRX_BADTCPCS) || - ((dsc->dscr_a)| M_DMA_ETHRX_BADIP4CS)){ - sb->ip_summed = CHECKSUM_NONE; - } else { - printk(KERN_DEBUG "hw checksum fail .\n"); - sb->ip_summed = CHECKSUM_UNNECESSARY; - } - } /*rx_hw_checksum */ - - netif_rx(sb); - } - } - else { + sc->sbm_stats.rx_dropped++; + sbdma_add_rcvbuffer(d,sb); /* re-add old buffer */ + } else { + /* + * Set length into the packet + */ + skb_put(sb,len); + + /* + * Buffer has been replaced on the + * receive ring. Pass the buffer to + * the kernel + */ + sc->sbm_stats.rx_bytes += len; + sc->sbm_stats.rx_packets++; + sb->protocol = eth_type_trans(sb,d->sbdma_eth->sbm_dev); + /* Check hw IPv4/TCP checksum if supported */ + if (sc->rx_hw_checksum == ENABLE) { + if (!((dsc->dscr_a) & M_DMA_ETHRX_BADIP4CS) && + !((dsc->dscr_a) & M_DMA_ETHRX_BADTCPCS)) { + sb->ip_summed = CHECKSUM_UNNECESSARY; + /* don't need to set sb->csum */ + } else { + sb->ip_summed = CHECKSUM_NONE; + } + } + + netif_rx(sb); + } + } else { /* * Packet was mangled somehow. Just drop it and * put it back on the receive ring. */ + sc->sbm_stats.rx_errors++; sbdma_add_rcvbuffer(d,sb); } @@ -1309,36 +1291,17 @@ */ curidx = d->sbdma_remptr - d->sbdma_dscrtable; - { - /* XXX This is gross, ugly, and only here because justin hacked it - in to fix a problem without really understanding it. - - It seems that, for whatever reason, this routine is invoked immediately upon the enabling of interrupts. - So then the Read below returns zero, making hwidx a negative number, and anti-hilarity - ensues. - - I'm guessing there's a proper fix involving clearing out interrupt state from old packets - before enabling interrupts, but I'm not sure. - - Anyways, this hack seems to work, and is Good Enough for 11 PM. :) - - -Justin - */ - - uint64_t tmp = SBMAC_READCSR(d->sbdma_curdscr); - if (!tmp) { - break; - } - hwidx = (int) (((tmp & M_DMA_CURDSCR_ADDR) - - d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t)); - } + hwidx = (int) (((SBMAC_READCSR(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) - + d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t)); + /* * If they're the same, that means we've processed all * of the descriptors up to (but not including) the one that * the hardware is working on right now. */ - if (curidx == hwidx) break; + if (curidx == hwidx) + break; /* * Otherwise, get the packet's sk_buff ptr back @@ -1405,14 +1368,14 @@ * figure out the addresses of some ports */ - s->sbm_macenable = PKSEG1(s->sbm_base + R_MAC_ENABLE); - s->sbm_maccfg = PKSEG1(s->sbm_base + R_MAC_CFG); - s->sbm_fifocfg = PKSEG1(s->sbm_base + R_MAC_THRSH_CFG); - s->sbm_framecfg = PKSEG1(s->sbm_base + R_MAC_FRAMECFG); - s->sbm_rxfilter = PKSEG1(s->sbm_base + R_MAC_ADFILTER_CFG); - s->sbm_isr = PKSEG1(s->sbm_base + R_MAC_STATUS); - s->sbm_imr = PKSEG1(s->sbm_base + R_MAC_INT_MASK); - s->sbm_mdio = PKSEG1(s->sbm_base + R_MAC_MDIO); + s->sbm_macenable = s->sbm_base + R_MAC_ENABLE; + s->sbm_maccfg = s->sbm_base + R_MAC_CFG; + s->sbm_fifocfg = s->sbm_base + R_MAC_THRSH_CFG; + s->sbm_framecfg = s->sbm_base + R_MAC_FRAMECFG; + s->sbm_rxfilter = s->sbm_base + R_MAC_ADFILTER_CFG; + s->sbm_isr = s->sbm_base + R_MAC_STATUS; + s->sbm_imr = s->sbm_base + R_MAC_INT_MASK; + s->sbm_mdio = s->sbm_base + R_MAC_MDIO; s->sbm_phys[0] = 1; s->sbm_phys[1] = 0; @@ -1451,12 +1414,12 @@ static void sbdma_uninitctx(struct sbmacdma_s *d) { if (d->sbdma_dscrtable) { - KFREE(d->sbdma_dscrtable); + kfree(d->sbdma_dscrtable); d->sbdma_dscrtable = NULL; } if (d->sbdma_ctxtable) { - KFREE(d->sbdma_ctxtable); + kfree(d->sbdma_ctxtable); d->sbdma_ctxtable = NULL; } } @@ -1486,13 +1449,14 @@ uint64_t reg; sbmac_port_t port; uint64_t cfg,fifo,framecfg; - int idx; + int idx, th_value; /* * Don't do this if running */ - if (s->sbm_state == sbmac_state_on) return; + if (s->sbm_state == sbmac_state_on) + return; /* * Bring the controller out of reset, but leave it off. @@ -1519,31 +1483,35 @@ 0; /* - * Be sure that RD_THRSH+WR_THRSH <= 32 + * Be sure that RD_THRSH+WR_THRSH <= 32 for pass1 pars + * and make sure that RD_THRSH + WR_THRSH <=128 for pass2 and above * Use a larger RD_THRSH for gigabit */ + if (periph_rev >= 2) + th_value = 64; + else + th_value = 28; fifo = V_MAC_TX_WR_THRSH(4) | /* Must be '4' or '8' */ ((s->sbm_speed == sbmac_speed_1000) - ? V_MAC_TX_RD_THRSH(28) : V_MAC_TX_RD_THRSH(4)) | + ? V_MAC_TX_RD_THRSH(th_value) : V_MAC_TX_RD_THRSH(4)) | V_MAC_TX_RL_THRSH(4) | V_MAC_RX_PL_THRSH(4) | V_MAC_RX_RD_THRSH(4) | /* Must be '4' */ V_MAC_RX_PL_THRSH(4) | V_MAC_RX_RL_THRSH(8) | 0; - + framecfg = V_MAC_MIN_FRAMESZ_DEFAULT | V_MAC_MAX_FRAMESZ_DEFAULT | V_MAC_BACKOFF_SEL(1); - - + /* * Clear out the hash address map */ - port = PKSEG1(s->sbm_base + R_MAC_HASH_BASE); - for (idx = 0; idx < MAC_HASH_COUNT; idx++) { + port = s->sbm_base + R_MAC_HASH_BASE; + for (idx = 0; idx < MAC_HASH_COUNT; idx++) { SBMAC_WRITECSR(port,0); port += sizeof(uint64_t); } @@ -1552,7 +1520,7 @@ * Clear out the exact-match table */ - port = PKSEG1(s->sbm_base + R_MAC_ADDR_BASE); + port = s->sbm_base + R_MAC_ADDR_BASE; for (idx = 0; idx < MAC_ADDR_COUNT; idx++) { SBMAC_WRITECSR(port,0); port += sizeof(uint64_t); @@ -1562,14 +1530,14 @@ * Clear out the DMA Channel mapping table registers */ - port = PKSEG1(s->sbm_base + R_MAC_CHUP0_BASE); + port = s->sbm_base + R_MAC_CHUP0_BASE; for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) { SBMAC_WRITECSR(port,0); port += sizeof(uint64_t); } - port = PKSEG1(s->sbm_base + R_MAC_CHLO0_BASE); + port = s->sbm_base + R_MAC_CHLO0_BASE; for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) { SBMAC_WRITECSR(port,0); port += sizeof(uint64_t); @@ -1582,13 +1550,13 @@ reg = sbmac_addr2reg(s->sbm_hwaddr); - port = PKSEG1(s->sbm_base + R_MAC_ADDR_BASE); + port = s->sbm_base + R_MAC_ADDR_BASE; SBMAC_WRITECSR(port,reg); - port = PKSEG1(s->sbm_base + R_MAC_ETHERNET_ADDR); + port = s->sbm_base + R_MAC_ETHERNET_ADDR; #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS /* - * Pass1 SB1250s do not receive packets addressed to the + * Pass1 SOCs do not receive packets addressed to the * destination address in the R_MAC_ETHERNET_ADDR register. * Set the value to zero. */ @@ -1646,7 +1614,7 @@ * Accept any TX interrupt and EOP count/timer RX interrupts on ch 0 */ SBMAC_WRITECSR(s->sbm_imr, - (M_MAC_INT_CHANNEL << S_MAC_TX_CH0) | + ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) | ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0)); #else /* @@ -1702,7 +1670,8 @@ { /* don't do this if already stopped */ - if (s->sbm_state == sbmac_state_off) return; + if (s->sbm_state == sbmac_state_off) + return; /* don't accept any packets, disable all interrupts */ @@ -1795,7 +1764,8 @@ { uint64_t reg; - if (sc->sbm_state != sbmac_state_on) return; + if (sc->sbm_state != sbmac_state_on) + return; if (onoff) { reg = SBMAC_READCSR(sc->sbm_rxfilter); @@ -1825,15 +1795,15 @@ { uint64_t reg; - reg = SBMAC_READCSR(sc->sbm_rxfilter); - reg &= ~M_MAC_IPHDR_OFFSET; /* Hard code the off set to 15 for now */ - reg |= 15 << S_MAC_IPHDR_OFFSET; + reg = SBMAC_READCSR(sc->sbm_rxfilter); + reg &= ~M_MAC_IPHDR_OFFSET | V_MAC_IPHDR_OFFSET(15); SBMAC_WRITECSR(sc->sbm_rxfilter,reg); /* read system identification to determine revision */ - if (sb1250_pass >= K_SYS_REVISION_PASS2) { - printk(KERN_INFO "pass2 - enabling Rx rcv tcp checksum\n"); + if (periph_rev >= 2) { + printk(KERN_INFO "%s: enabling TCP rcv checksum\n", + sc->sbm_dev->name); sc->rx_hw_checksum = ENABLE; } else { sc->rx_hw_checksum = DISABLE; @@ -1841,31 +1811,6 @@ } -#if 0 -/********************************************************************** - * SBMAC_INIT_AND_START(sc) - * - * Stop the channel and restart it. This is generally used - * when we have to do something to the channel that requires - * a swift kick. - * - * Input parameters: - * sc - softc - ********************************************************************* */ - -static void sbmac_init_and_start(struct sbmac_softc *sc) -{ - unsigned long flags; - - spin_lock_irqsave(&(sc->sbm_lock),flags); - - sbmac_set_channel_state(sc,sbmac_state_on); - - spin_unlock_irqrestore(&(sc->sbm_lock),flags); -} -#endif - - /********************************************************************** * SBMAC_ADDR2REG(ptr) * @@ -1927,7 +1872,8 @@ s->sbm_speed = speed; - if (s->sbm_state == sbmac_state_on) return 0; /* save for next restart */ + if (s->sbm_state == sbmac_state_on) + return 0; /* save for next restart */ /* * Read current register values @@ -1987,7 +1933,6 @@ SBMAC_WRITECSR(s->sbm_maccfg,cfg); return 1; - } /********************************************************************** @@ -2017,7 +1962,8 @@ s->sbm_duplex = duplex; s->sbm_fc = fc; - if (s->sbm_state == sbmac_state_on) return 0; /* save for next restart */ + if (s->sbm_state == sbmac_state_on) + return 0; /* save for next restart */ /* * Read current register values @@ -2116,7 +2062,8 @@ isr = SBMAC_READCSR(sc->sbm_isr) & ~M_MAC_COUNTER_ADDR; - if (isr == 0) break; + if (isr == 0) + break; /* * Transmits on channel 0 @@ -2151,7 +2098,6 @@ sbdma_rx_process(sc,&(sc->sbm_rxdma)); } } - } @@ -2224,12 +2170,12 @@ */ for (idx = 1; idx < MAC_ADDR_COUNT; idx++) { - port = PKSEG1(sc->sbm_base + R_MAC_ADDR_BASE+(idx*sizeof(uint64_t))); + port = sc->sbm_base + R_MAC_ADDR_BASE+(idx*sizeof(uint64_t)); SBMAC_WRITECSR(port,0); } for (idx = 0; idx < MAC_HASH_COUNT; idx++) { - port = PKSEG1(sc->sbm_base + R_MAC_HASH_BASE+(idx*sizeof(uint64_t))); + port = sc->sbm_base + R_MAC_HASH_BASE+(idx*sizeof(uint64_t)); SBMAC_WRITECSR(port,0); } @@ -2266,8 +2212,7 @@ mclist = dev->mc_list; while (mclist && (idx < MAC_ADDR_COUNT)) { reg = sbmac_addr2reg(mclist->dmi_addr); - port = PKSEG1(sc->sbm_base + - R_MAC_ADDR_BASE+(idx*sizeof(uint64_t))); + port = sc->sbm_base + R_MAC_ADDR_BASE+(idx * sizeof(uint64_t)); SBMAC_WRITECSR(port,reg); idx++; mclist = mclist->next; @@ -2304,10 +2249,14 @@ { int digit; - if ((str >= '0') && (str <= '9')) digit = str - '0'; - else if ((str >= 'a') && (str <= 'f')) digit = str - 'a' + 10; - else if ((str >= 'A') && (str <= 'F')) digit = str - 'A' + 10; - else return -1; + if ((str >= '0') && (str <= '9')) + digit = str - '0'; + else if ((str >= 'a') && (str <= 'f')) + digit = str - 'a' + 10; + else if ((str >= 'A') && (str <= 'F')) + digit = str - 'A' + 10; + else + return -1; return digit; } @@ -2326,16 +2275,18 @@ * 0 if ok, else -1 ********************************************************************* */ -static int sbmac_parse_hwaddr(char *str,u_char *hwaddr) +static int sbmac_parse_hwaddr(char *str, unsigned char *hwaddr) { int digit1,digit2; int idx = 6; while (*str && (idx > 0)) { digit1 = sbmac_parse_xdigit(*str); - if (digit1 < 0) return -1; + if (digit1 < 0) + return -1; str++; - if (!*str) return -1; + if (!*str) + return -1; if ((*str == ':') || (*str == '-')) { digit2 = digit1; @@ -2343,15 +2294,18 @@ } else { digit2 = sbmac_parse_xdigit(*str); - if (digit2 < 0) return -1; + if (digit2 < 0) + return -1; str++; } *hwaddr++ = (digit1 << 4) | digit2; idx--; - if (*str == '-') str++; - if (*str == ':') str++; + if (*str == '-') + str++; + if (*str == ':') + str++; } return 0; } @@ -2359,11 +2313,11 @@ static int sb1250_change_mtu(struct net_device *_dev, int new_mtu) { - if (new_mtu > ENET_PACKET_SIZE) - return -EINVAL; - _dev->mtu = new_mtu; + if (new_mtu > ENET_PACKET_SIZE) + return -EINVAL; + _dev->mtu = new_mtu; printk(KERN_INFO "changing the mtu to %d\n", new_mtu); - return 0; + return 0; } /********************************************************************** @@ -2378,19 +2332,20 @@ * status ********************************************************************* */ -static int sbmac_init(struct net_device *dev) +static int sbmac_init(struct net_device *dev, int idx) { struct sbmac_softc *sc; - u_char *eaddr; + unsigned char *eaddr; uint64_t ea_reg; - int idx; + int i; sc = (struct sbmac_softc *)dev->priv; /* Determine controller base address */ - sc->sbm_base = (sbmac_port_t) dev->base_addr; + sc->sbm_base = KSEG1ADDR(dev->base_addr); sc->sbm_dev = dev; + sc->sbe_idx = idx; eaddr = sc->sbm_hwaddr; @@ -2399,16 +2354,15 @@ * for us in the ethernet address register for each mac. */ - ea_reg = SBMAC_READCSR(PKSEG1(sc->sbm_base + R_MAC_ETHERNET_ADDR)); - SBMAC_WRITECSR(PKSEG1(sc->sbm_base + R_MAC_ETHERNET_ADDR), 0); - for (idx = 0; idx < 6; idx++) { - eaddr[idx] = (uint8_t) (ea_reg & 0xFF); + ea_reg = SBMAC_READCSR(sc->sbm_base + R_MAC_ETHERNET_ADDR); + SBMAC_WRITECSR(sc->sbm_base + R_MAC_ETHERNET_ADDR, 0); + for (i = 0; i < 6; i++) { + eaddr[i] = (uint8_t) (ea_reg & 0xFF); ea_reg >>= 8; } - - for (idx = 0; idx < 6; idx++) { - dev->dev_addr[idx] = eaddr[idx]; + for (i = 0; i < 6; i++) { + dev->dev_addr[i] = eaddr[i]; } @@ -2416,8 +2370,8 @@ * Init packet size */ - sc->sbm_buffersize = ENET_PACKET_SIZE + CACHELINESIZE*2 + ETHER_ALIGN; - + sc->sbm_buffersize = ENET_PACKET_SIZE + SMP_CACHE_BYTES * 2 + ETHER_ALIGN; + /* * Initialize context (get pointers to registers and stuff), then * allocate the memory for the descriptor tables. @@ -2427,13 +2381,13 @@ /* - * Display Ethernet address (this is called during the config process - * so we need to finish off the config message that was being displayed) + * Display Ethernet address (this is called during the config + * process so we need to finish off the config message that + * was being displayed) */ printk(KERN_INFO - "%s: SB1250 Ethernet at 0x%08lX, address: %02X-%02X-%02X-%02X-%02X-%02X\n", - dev->name, - (unsigned long) sc->sbm_base, + "%s: SiByte Ethernet at 0x%08lX, address: %02X-%02X-%02X-%02X-%02X-%02X\n", + dev->name, dev->base_addr, eaddr[0],eaddr[1],eaddr[2],eaddr[3],eaddr[4],eaddr[5]); /* @@ -2454,16 +2408,10 @@ dev->change_mtu = sb1250_change_mtu; - if (sb1250_pass >= K_SYS_REVISION_PASS3) { - /* In pass3 we do dumb checksum in TX */ - dev->features |= NETIF_F_IP_CSUM; - } - - /* This is needed for PASS2 for Rx H/W checksum feature */ - sbmac_set_iphdr_offset( sc); + /* This is needed for PASS2 for Rx H/W checksum feature */ + sbmac_set_iphdr_offset(sc); return 0; - } @@ -2478,9 +2426,12 @@ } /* - * map/route interrupt + * map/route interrupt (clear status first, in case something + * weird is pending; we haven't initialized the mac registers + * yet) */ - + + SBMAC_READCSR(sc->sbm_isr); if (request_irq(dev->irq, &sbmac_intr, SA_SHIRQ, dev->name, dev)) { MOD_DEC_USE_COUNT; return -EBUSY; @@ -2490,7 +2441,7 @@ * Configure default speed */ - sbmac_mii_poll(sc,1); + sbmac_mii_poll(sc,noisy_mii); /* * Turn on the channel @@ -2572,7 +2523,8 @@ chg = 1; } - if (chg == 0) return 0; + if (chg == 0) + return 0; p += sprintf(p,"Link speed: "); @@ -2616,9 +2568,6 @@ p += sprintf(p,"Unknown"); } -#ifdef CONFIG_NET_SB1250_MAC_QUIET - noisy = 0; -#endif if (noisy) { printk(KERN_INFO "%s: %s\n",s->sbm_dev->name,buffer); } @@ -2627,8 +2576,6 @@ } - - static void sbmac_timer(unsigned long data) { struct net_device *dev = (struct net_device *)data; @@ -2655,19 +2602,19 @@ * Poll the PHY to see what speed we should be running at */ - if (sbmac_mii_poll(sc,1)) { - if (sc->sbm_state != sbmac_state_off) { - /* - * something changed, restart the channel - */ - if (debug > 1) { - printk("%s: restarting channel because speed changed\n", - sc->sbm_dev->name); - } - sbmac_channel_stop(sc); - sbmac_channel_start(sc); + if (sbmac_mii_poll(sc,noisy_mii)) { + if (sc->sbm_state != sbmac_state_off) { + /* + * something changed, restart the channel + */ + if (debug > 1) { + printk("%s: restarting channel because speed changed\n", + sc->sbm_dev->name); + } + sbmac_channel_stop(sc); + sbmac_channel_start(sc); } - } + } spin_unlock_irq (&sc->sbm_lock); @@ -2735,7 +2682,8 @@ spin_unlock_irqrestore(&sc->sbm_lock, flags); if (msg_flag) { - printk(KERN_NOTICE "%s: Promiscuous mode %sabled.\n", dev->name,(msg_flag==1)?"en":"dis"); + printk(KERN_NOTICE "%s: Promiscuous mode %sabled.\n", + dev->name,(msg_flag==1)?"en":"dis"); } /* @@ -2786,31 +2734,29 @@ { struct sbmac_softc *sc = (struct sbmac_softc *)dev->priv; unsigned long flags; - + sbmac_set_channel_state(sc,sbmac_state_off); - + del_timer_sync(&sc->sbm_timer); - + spin_lock_irqsave(&sc->sbm_lock, flags); - + netif_stop_queue(dev); - + if (debug > 1) { printk(KERN_DEBUG "%s: Shutting down ethercard\n",dev->name); } - + spin_unlock_irqrestore(&sc->sbm_lock, flags); - - /* Make sure there is no irq-handler running on a different CPU. */ + synchronize_irq(); - free_irq(dev->irq, dev); - + sbdma_emptyring(&(sc->sbm_txdma)); sbdma_emptyring(&(sc->sbm_rxdma)); MOD_DEC_USE_COUNT; - + return 0; } @@ -2827,8 +2773,8 @@ port = A_MAC_CHANNEL_BASE(chan); sbmac_parse_hwaddr(addr,eaddr); val = sbmac_addr2reg(eaddr); - SBMAC_WRITECSR(PKSEG1(port+R_MAC_ETHERNET_ADDR),val); - val = SBMAC_READCSR(PKSEG1(port+R_MAC_ETHERNET_ADDR)); + SBMAC_WRITECSR(KSEG1ADDR(port+R_MAC_ETHERNET_ADDR),val); + val = SBMAC_READCSR(KSEG1ADDR(port+R_MAC_ETHERNET_ADDR)); } #endif @@ -2862,15 +2808,15 @@ * Walk through the Ethernet controllers and find * those who have their MAC addresses set. */ - chip_revision = SBMAC_READCSR(PKSEG1(A_SCD_SYSTEM_REVISION)); - switch ((int)G_SYS_PART(chip_revision)) { - case 0x1150: - case 0x1250: + switch (soc_type) { + case K_SYS_SOC_TYPE_BCM1250: + case K_SYS_SOC_TYPE_BCM1250_ALT: chip_max_units = 3; break; - case 0x1120: - case 0x1125: - case 0x1126: + case K_SYS_SOC_TYPE_BCM1120: + case K_SYS_SOC_TYPE_BCM1125: + case K_SYS_SOC_TYPE_BCM1125H: + case K_SYS_SOC_TYPE_BCM1250_ALT2: /* Hybrid */ chip_max_units = 2; break; default: @@ -2894,9 +2840,10 @@ * If we find a zero, skip this MAC. */ - sbmac_orig_hwaddr[idx] = SBMAC_READCSR(PKSEG1(port+R_MAC_ETHERNET_ADDR)); + sbmac_orig_hwaddr[idx] = SBMAC_READCSR(KSEG1ADDR(port+R_MAC_ETHERNET_ADDR)); if (sbmac_orig_hwaddr[idx] == 0) { - printk( KERN_DEBUG "sbmac: not configuring MAC at %x\n",(uint32_t)port); + printk(KERN_DEBUG "sbmac: not configuring MAC at " + "%lx\n", port); continue; } @@ -2908,15 +2855,16 @@ if (!dev) return -ENOMEM; /* return ENOMEM */ + printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port); + dev->irq = K_INT_MAC_0 + idx; dev->base_addr = port; dev->mem_end = 0; /*dev->init = sbmac_init;*/ - sbmac_init(dev); + sbmac_init(dev, macidx); dev_sbmac[macidx] = dev; macidx++; - } /* @@ -2935,7 +2883,8 @@ sbmac_port_t port; for (idx = 0; idx < MAX_UNITS; idx++) { dev = dev_sbmac[idx]; - if (dev == NULL) continue; + if (dev == NULL) + continue; if (dev->priv != NULL) { struct sbmac_softc *sc = (struct sbmac_softc *) dev->priv; @@ -2946,8 +2895,8 @@ } port = A_MAC_CHANNEL_BASE(idx); - SBMAC_WRITECSR(PKSEG1(port+R_MAC_ETHERNET_ADDR), sbmac_orig_hwaddr[idx] ); - KFREE(dev); + SBMAC_WRITECSR(KSEG1ADDR(port+R_MAC_ETHERNET_ADDR), sbmac_orig_hwaddr[idx] ); + kfree(dev); dev_sbmac[idx] = NULL; } } Index: drivers/net/seeq8005.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/seeq8005.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/seeq8005.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/seeq8005.c 4 Aug 2004 01:29:11 -0000 1.2 @@ -379,7 +379,7 @@ { struct net_local *lp = (struct net_local *)dev->priv; short length = skb->len; - unsigned char *buf = skb->data; + unsigned char *buf; if(length < ETH_ZLEN) { @@ -388,6 +388,8 @@ return 0; length = ETH_ZLEN; } + buf = skb->data; + /* Block a timer-based transmit from overlapping */ netif_stop_queue(dev); Index: drivers/net/sgiseeq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sgiseeq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sgiseeq.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/sgiseeq.c 4 Aug 2004 01:29:11 -0000 1.2 @@ -5,51 +5,45 @@ */ #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 "sgiseeq.h" -static char *version = - "sgiseeq.c: David S. Miller (dm@engr.sgi.com)\n"; +static char *version = "sgiseeq.c: David S. Miller (dm@engr.sgi.com)\n"; static char *sgiseeqstr = "SGI Seeq8003"; -/* If you want speed, you do something silly, it always has worked - * for me. So, with that in mind, I've decided to make this driver - * look completely like a stupid Lance from a driver architecture - * perspective. Only difference is that here our "ring buffer" looks - * and acts like a real Lance one does but is layed out like how the - * HPC DMA and the Seeq want it to. You'd be surprised how a stupid - * idea like this can pay off in performance, not to mention making - * this driver 2,000 times easier to write. ;-) +/* + * If you want speed, you do something silly, it always has worked for me. So, + * with that in mind, I've decided to make this driver look completely like a + * stupid Lance from a driver architecture perspective. Only difference is that + * here our "ring buffer" looks and acts like a real Lance one does but is + * layed out like how the HPC DMA and the Seeq want it to. You'd be surprised + * how a stupid idea like this can pay off in performance, not to mention + * making this driver 2,000 times easier to write. ;-) */ /* Tune these if we tend to run out often etc. */ @@ -79,9 +73,10 @@ signed int buf_vaddr; }; -/* Warning: This structure is layed out in a certain way because - * HPC dma descriptors must be 8-byte aligned. So don't - * touch this without some care. +/* + * Warning: This structure is layed out in a certain way because HPC dma + * descriptors must be 8-byte aligned. So don't touch this without + * some care. */ struct sgiseeq_init_block { /* Note the name ;-) */ /* Ptrs to the descriptors in KSEG1 uncached space. */ @@ -96,8 +91,8 @@ struct sgiseeq_private { volatile struct sgiseeq_init_block srings; char *name; - volatile struct hpc3_ethregs *hregs; - volatile struct sgiseeq_regs *sregs; + struct hpc3_ethregs *hregs; + struct sgiseeq_regs *sregs; /* Ring entry counters. */ unsigned int rx_new, tx_new; @@ -108,17 +103,23 @@ unsigned char mode; struct net_device_stats stats; + + struct net_device *next_module; + spinlock_t tx_lock; }; -static inline void hpc3_eth_reset(volatile struct hpc3_ethregs *hregs) +/* A list of all installed seeq devices, for removing the driver module. */ +static struct net_device *root_sgiseeq_dev; + +static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs) { - hregs->rx_reset = (HPC3_ERXRST_CRESET | HPC3_ERXRST_CLRIRQ); + hregs->rx_reset = HPC3_ERXRST_CRESET | HPC3_ERXRST_CLRIRQ; udelay(20); hregs->rx_reset = 0; } -static inline void reset_hpc3_and_seeq(volatile struct hpc3_ethregs *hregs, - volatile struct sgiseeq_regs *sregs) +static inline void reset_hpc3_and_seeq(struct hpc3_ethregs *hregs, + struct sgiseeq_regs *sregs) { hregs->rx_ctrl = hregs->tx_ctrl = 0; hpc3_eth_reset(hregs); @@ -128,15 +129,15 @@ SEEQ_RCMD_IDRIB | SEEQ_RCMD_ICRC) static inline void seeq_go(struct sgiseeq_private *sp, - volatile struct hpc3_ethregs *hregs, - volatile struct sgiseeq_regs *sregs) + struct hpc3_ethregs *hregs, + struct sgiseeq_regs *sregs) { sregs->rstat = sp->mode | RSTAT_GO_BITS; hregs->rx_ctrl = HPC3_ERXCTRL_ACTIVE; } static inline void seeq_load_eaddr(struct net_device *dev, - volatile struct sgiseeq_regs *sregs) + struct sgiseeq_regs *sregs) { int i; @@ -169,7 +170,7 @@ /* Setup tx ring. */ for(i = 0; i < SEEQ_TX_BUFFERS; i++) { - if(!ib->tx_desc[i].tdma.pbuf) { + if (!ib->tx_desc[i].tdma.pbuf) { unsigned long buffer; buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL); @@ -177,9 +178,8 @@ return -ENOMEM; ib->tx_desc[i].buf_vaddr = KSEG1ADDR(buffer); ib->tx_desc[i].tdma.pbuf = PHYSADDR(buffer); -// flush_cache_all(); } - ib->tx_desc[i].tdma.cntinfo = (TCNTINFO_INIT); + ib->tx_desc[i].tdma.cntinfo = TCNTINFO_INIT; } /* And now the rx ring. */ @@ -192,11 +192,10 @@ return -ENOMEM; ib->rx_desc[i].buf_vaddr = KSEG1ADDR(buffer); ib->rx_desc[i].rdma.pbuf = PHYSADDR(buffer); -// flush_cache_all(); } - ib->rx_desc[i].rdma.cntinfo = (RCNTINFO_INIT); + ib->rx_desc[i].rdma.cntinfo = RCNTINFO_INIT; } - ib->rx_desc[i - 1].rdma.cntinfo |= (HPCDMA_EOR); + ib->rx_desc[i - 1].rdma.cntinfo |= HPCDMA_EOR; return 0; } @@ -209,10 +208,10 @@ static int once; struct sgiseeq_rx_desc *r = gpriv->srings.rx_desc; struct sgiseeq_tx_desc *t = gpriv->srings.tx_desc; - volatile struct hpc3_ethregs *hregs = gpriv->hregs; + struct hpc3_ethregs *hregs = gpriv->hregs; int i; - if(once) + if (once) return; once++; printk("RING DUMP:\n"); @@ -248,9 +247,9 @@ #define RDMACFG_INIT (HPC3_ERXDCFG_FRXDC | HPC3_ERXDCFG_FEOP | HPC3_ERXDCFG_FIRQ) static int init_seeq(struct net_device *dev, struct sgiseeq_private *sp, - volatile struct sgiseeq_regs *sregs) + struct sgiseeq_regs *sregs) { - volatile struct hpc3_ethregs *hregs = sp->hregs; + struct hpc3_ethregs *hregs = sp->hregs; int err; reset_hpc3_and_seeq(hregs, sregs); @@ -260,11 +259,11 @@ /* Setup to field the proper interrupt types. */ if (sp->is_edlc) { - sregs->tstat = (TSTAT_INIT_EDLC); + sregs->tstat = TSTAT_INIT_EDLC; sregs->rw.wregs.control = sp->control; sregs->rw.wregs.frame_gap = 0; } else { - sregs->tstat = (TSTAT_INIT_SEEQ); + sregs->tstat = TSTAT_INIT_SEEQ; } hregs->rx_dconfig |= RDMACFG_INIT; @@ -291,8 +290,8 @@ } static inline void rx_maybe_restart(struct sgiseeq_private *sp, - volatile struct hpc3_ethregs *hregs, - volatile struct sgiseeq_regs *sregs) + struct hpc3_ethregs *hregs, + struct sgiseeq_regs *sregs) { if (!(hregs->rx_ctrl & HPC3_ERXCTRL_ACTIVE)) { hregs->rx_ndptr = PHYSADDR(&sp->srings.rx_desc[sp->rx_new]); @@ -305,8 +304,8 @@ (rd) = &(sp)->srings.rx_desc[(sp)->rx_new]) static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp, - volatile struct hpc3_ethregs *hregs, - volatile struct sgiseeq_regs *sregs) + struct hpc3_ethregs *hregs, + struct sgiseeq_regs *sregs) { struct sgiseeq_rx_desc *rd; struct sk_buff *skb = 0; @@ -317,7 +316,7 @@ /* Service every received packet. */ for_each_rx(rd, sp) { - len = (PKT_BUF_SZ - (rd->rdma.cntinfo & HPCDMA_BCNT) - 3); + len = PKT_BUF_SZ - (rd->rdma.cntinfo & HPCDMA_BCNT) - 3; pkt_pointer = (unsigned char *)(long)rd->buf_vaddr; pkt_status = pkt_pointer[len + 2]; @@ -338,7 +337,7 @@ sp->stats.rx_packets++; sp->stats.rx_bytes += len; } else { - printk ("%s: Memory squeeze, deferring packet.\n", + printk (KERN_NOTICE "%s: Memory squeeze, deferring packet.\n", dev->name); sp->stats.rx_dropped++; } @@ -347,7 +346,7 @@ } /* Return the entry to the ring pool. */ - rd->rdma.cntinfo = (RCNTINFO_INIT); + rd->rdma.cntinfo = RCNTINFO_INIT; sp->rx_new = NEXT_RX(sp->rx_new); } sp->srings.rx_desc[orig_end].rdma.cntinfo &= ~(HPCDMA_EOR); @@ -356,7 +355,7 @@ } static inline void tx_maybe_reset_collisions(struct sgiseeq_private *sp, - volatile struct sgiseeq_regs *sregs) + struct sgiseeq_regs *sregs) { if (sp->is_edlc) { sregs->rw.wregs.control = sp->control & ~(SEEQ_CTRL_XCNT); @@ -365,7 +364,7 @@ } static inline void kick_tx(struct sgiseeq_tx_desc *td, - volatile struct hpc3_ethregs *hregs) + struct hpc3_ethregs *hregs) { /* If the HPC aint doin nothin, and there are more packets * with ETXD cleared and XIU set we must make very certain @@ -383,8 +382,8 @@ } static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp, - volatile struct hpc3_ethregs *hregs, - volatile struct sgiseeq_regs *sregs) + struct hpc3_ethregs *hregs, + struct sgiseeq_regs *sregs) { struct sgiseeq_tx_desc *td; unsigned long status = hregs->tx_ctrl; @@ -409,7 +408,7 @@ if (!(td->tdma.cntinfo & (HPCDMA_XIU))) break; if (!(td->tdma.cntinfo & (HPCDMA_ETXD))) { - if(!(status & HPC3_ETXCTRL_ACTIVE)) { + if (!(status & HPC3_ETXCTRL_ACTIVE)) { hregs->tx_ndptr = PHYSADDR(td); hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE; } @@ -426,8 +425,10 @@ { struct net_device *dev = (struct net_device *) dev_id; struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; - volatile struct hpc3_ethregs *hregs = sp->hregs; - volatile struct sgiseeq_regs *sregs = sp->sregs; + struct hpc3_ethregs *hregs = sp->hregs; + struct sgiseeq_regs *sregs = sp->sregs; + + spin_lock(&sp->tx_lock); /* Ack the IRQ and set software state. */ hregs->rx_reset = HPC3_ERXRST_CLRIRQ; @@ -435,59 +436,47 @@ /* Always check for received packets. */ sgiseeq_rx(dev, sp, hregs, sregs); - /* Only check for tx acks iff we have something queued. */ + /* Only check for tx acks if we have something queued. */ if (sp->tx_old != sp->tx_new) sgiseeq_tx(dev, sp, hregs, sregs); if ((TX_BUFFS_AVAIL(sp) > 0) && netif_queue_stopped(dev)) { netif_wake_queue(dev); } + spin_unlock(&sp->tx_lock); } static int sgiseeq_open(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *)dev->priv; - volatile struct sgiseeq_regs *sregs = sp->sregs; - unsigned long flags; - int err; - - __save_and_cli(flags); + struct sgiseeq_regs *sregs = sp->sregs; - err = -EAGAIN; - if (request_irq(dev->irq, sgiseeq_interrupt, 0, sgiseeqstr, dev)) { - printk("Seeq8003: Can't get irq %d\n", dev->irq); - goto out; - } - err = init_seeq(dev, sp, sregs); + int err = init_seeq(dev, sp, sregs); if (err) - goto out; + return err; netif_start_queue(dev); -out: - __restore_flags(flags); - return err; + return 0; } static int sgiseeq_close(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; - volatile struct sgiseeq_regs *sregs = sp->sregs; + struct sgiseeq_regs *sregs = sp->sregs; netif_stop_queue(dev); /* Shutdown the Seeq. */ reset_hpc3_and_seeq(sp->hregs, sregs); - free_irq(dev->irq, dev); - return 0; } static inline int sgiseeq_reset(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; - volatile struct sgiseeq_regs *sregs = sp->sregs; + struct sgiseeq_regs *sregs = sp->sregs; int err; err = init_seeq(dev, sp, sregs); @@ -509,12 +498,12 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; - volatile struct hpc3_ethregs *hregs = sp->hregs; + struct hpc3_ethregs *hregs = sp->hregs; unsigned long flags; struct sgiseeq_tx_desc *td; int skblen, len, entry; - save_and_cli(flags); + spin_lock_irqsave(&sp->tx_lock, flags); /* Setup... */ skblen = skb->len; @@ -530,22 +519,22 @@ * 2) Do no allow the HPC to look at a new descriptor until * we have completely set up it's state. This means, do * not clear HPCDMA_EOX in the current last descritptor - * until the one we are adding looks consistant and could + * until the one we are adding looks consistent and could * be processes right now. * 3) The tx interrupt code must notice when we've added a new * entry and the HPC got to the end of the chain before we * added this new entry and restarted it. */ memcpy((char *)(long)td->buf_vaddr, skb->data, skblen); - if(len != skblen) + if (len != skblen) memset((char *)(long)td->buf_vaddr + skb->len, 0, len-skblen); td->tdma.cntinfo = (len & HPCDMA_BCNT) | - (HPCDMA_XIU | HPCDMA_EOXP | HPCDMA_XIE | HPCDMA_EOX); + HPCDMA_XIU | HPCDMA_EOXP | HPCDMA_XIE | HPCDMA_EOX; if (sp->tx_old != sp->tx_new) { struct sgiseeq_tx_desc *backend; backend = &sp->srings.tx_desc[PREV_TX(sp->tx_new)]; - backend->tdma.cntinfo &= ~(HPCDMA_EOX); + backend->tdma.cntinfo &= ~HPCDMA_EOX; } sp->tx_new = NEXT_TX(sp->tx_new); /* Advance. */ @@ -558,14 +547,14 @@ if (!TX_BUFFS_AVAIL(sp)) netif_stop_queue(dev); - restore_flags(flags); + spin_unlock_irqrestore(&sp->tx_lock, flags); return 0; } static void timeout(struct net_device *dev) { - printk("%s: transmit timed out, resetting\n", dev->name); + printk(KERN_NOTICE "%s: transmit timed out, resetting\n", dev->name); sgiseeq_reset(dev); dev->trans_start = jiffies; @@ -608,49 +597,56 @@ buf[i].rdma.pnext = PHYSADDR(&buf[0]); } -static char onboard_eth_addr[6]; - #define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf)) -int sgiseeq_init(struct net_device *dev, struct sgiseeq_regs *sregs, - struct hpc3_ethregs *hregs, int irq) +int sgiseeq_init(struct hpc3_regs* regs, int irq) { - static unsigned version_printed; - int i; + struct net_device *dev; struct sgiseeq_private *sp; + int err, i; - dev->priv = (struct sgiseeq_private *) get_free_page(GFP_KERNEL); - if (dev->priv == NULL) - return -ENOMEM; - - if (!version_printed++) - printk(version); - - printk("%s: SGI Seeq8003 ", dev->name); + dev = alloc_etherdev(0); + if (!dev) { + printk(KERN_ERR "Sgiseeq: Etherdev alloc failed, aborting.\n"); + err = -ENOMEM; + goto err_out; + } + /* Make private data page aligned */ + sp = (struct sgiseeq_private *) get_zeroed_page(GFP_KERNEL); + if (!sp) { + printk(KERN_ERR "Sgiseeq: Page alloc failed, aborting.\n"); + err = -ENOMEM; + goto err_out_free_dev; + } + + if (request_irq(irq, sgiseeq_interrupt, 0, sgiseeqstr, dev)) { + printk(KERN_ERR "Seeq8003: Can't get irq %d\n", dev->irq); + err = -EAGAIN; + goto err_out_free_page; + } + +#define EADDR_NVOFS 250 + for (i = 0; i < 3; i++) { + unsigned short tmp = ip22_nvram_read(EADDR_NVOFS / 2 + i); - for (i = 0; i < 6; i++) - printk("%2.2x%c", - dev->dev_addr[i] = onboard_eth_addr[i], - i == 5 ? ' ': ':'); - - printk("\n"); + dev->dev_addr[2 * i] = tmp >> 8; + dev->dev_addr[2 * i + 1] = tmp & 0xff; + } - sp = (struct sgiseeq_private *) dev->priv; #ifdef DEBUG gpriv = sp; gdev = dev; #endif - memset((char *)dev->priv, 0, sizeof(struct sgiseeq_private)); - sp->sregs = sregs; - sp->hregs = hregs; + sp->sregs = (struct sgiseeq_regs *) &hpc3c0->eth_ext[0]; + sp->hregs = &hpc3c0->ethregs; sp->name = sgiseeqstr; sp->srings.rx_desc = (struct sgiseeq_rx_desc *) - (KSEG1ADDR(ALIGNED(&sp->srings.rxvector[0]))); + KSEG1ADDR(ALIGNED(&sp->srings.rxvector[0])); dma_cache_wback_inv((unsigned long)&sp->srings.rxvector, sizeof(sp->srings.rxvector)); sp->srings.tx_desc = (struct sgiseeq_tx_desc *) - (KSEG1ADDR(ALIGNED(&sp->srings.txvector[0]))); + KSEG1ADDR(ALIGNED(&sp->srings.txvector[0])); dma_cache_wback_inv((unsigned long)&sp->srings.txvector, sizeof(sp->srings.txvector)); @@ -659,71 +655,78 @@ setup_tx_ring(sp->srings.tx_desc, SEEQ_TX_BUFFERS); /* Reset the chip. */ - hpc3_eth_reset((volatile struct hpc3_ethregs *) hregs); + hpc3_eth_reset(sp->hregs); - sp->is_edlc = !(sregs->rw.rregs.collision_tx[0] & 0xff); - if (sp->is_edlc) { - sp->control = (SEEQ_CTRL_XCNT | SEEQ_CTRL_ACCNT | - SEEQ_CTRL_SFLAG | SEEQ_CTRL_ESHORT | - SEEQ_CTRL_ENCARR); + sp->is_edlc = !(sp->sregs->rw.rregs.collision_tx[0] & 0xff); + if (sp->is_edlc) + sp->control = SEEQ_CTRL_XCNT | SEEQ_CTRL_ACCNT | + SEEQ_CTRL_SFLAG | SEEQ_CTRL_ESHORT | + SEEQ_CTRL_ENCARR; + + dev->open = sgiseeq_open; + dev->stop = sgiseeq_close; + dev->hard_start_xmit = sgiseeq_start_xmit; + dev->tx_timeout = timeout; + dev->watchdog_timeo = (200 * HZ) / 1000; + dev->get_stats = sgiseeq_get_stats; + dev->set_multicast_list = sgiseeq_set_multicast; + dev->irq = irq; + dev->dma = 0; + dev->priv = sp; + + if (register_netdev(dev)) { + printk(KERN_ERR "Sgiseeq: Cannot register net device, " + "aborting.\n"); + err = -ENODEV; + goto err_out_free_irq; } - dev->open = sgiseeq_open; - dev->stop = sgiseeq_close; - dev->hard_start_xmit = sgiseeq_start_xmit; - dev->tx_timeout = timeout; - dev->watchdog_timeo = (200 * HZ) / 1000; - dev->get_stats = sgiseeq_get_stats; - dev->set_multicast_list = sgiseeq_set_multicast; - dev->irq = irq; - dev->dma = 0; - ether_setup(dev); + printk(KERN_INFO "%s: SGI Seeq8003 ", dev->name); + for (i = 0; i < 6; i++) + printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); + + sp->next_module = root_sgiseeq_dev; + root_sgiseeq_dev = dev; return 0; -} -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 */ +err_out_free_irq: + free_irq(irq, dev); +err_out_free_page: + free_page((unsigned long) sp); +err_out_free_dev: + kfree(dev); + +err_out: + return err; } -static inline void str2eaddr(unsigned char *ea, unsigned char *str) +static int __init sgiseeq_probe(void) { - int i; - - for (i = 0; i < 6; i++) { - unsigned char num; + printk(version); - if(*str == ':') - str++; - num = str2hexnum(*str++) << 4; - num |= (str2hexnum(*str++)); - ea[i] = num; - } + /* On board adapter on 1st HPC is always present */ + return sgiseeq_init(hpc3c0, SGI_ENET_IRQ); } -int sgiseeq_probe(struct net_device *dev) +static void __exit sgiseeq_exit(void) { - static int initialized; - char *ep; - - if (initialized) /* Already initialized? */ - return 1; - initialized++; + struct net_device *next, *dev; + struct sgiseeq_private *sp; + int irq; - /* First get the ethernet address of the onboard interface from ARCS. - * This is fragile; PROM doesn't like running from cache. - * On MIPS64 it crashes for some other, yet unknown reason ... - */ - ep = ArcGetEnvironmentVariable("eaddr"); - str2eaddr(onboard_eth_addr, ep); - return sgiseeq_init(dev, - (struct sgiseeq_regs *) (KSEG1ADDR(0x1fbd4000)), - &hpc3c0->ethregs, SGI_ENET_IRQ); + for (dev = root_sgiseeq_dev; dev; dev = next) { + sp = (struct sgiseeq_private *) dev->priv; + next = sp->next_module; + irq = dev->irq; + unregister_netdev(dev); + free_irq(irq, dev); + free_page((unsigned long) dev->priv); + kfree(dev); + } } +module_init(sgiseeq_probe); +module_exit(sgiseeq_exit); + MODULE_LICENSE("GPL"); Index: drivers/net/sis900.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sis900.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sis900.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/sis900.c 4 Aug 2004 01:29:11 -0000 1.2 @@ -98,7 +98,7 @@ "SiS 900 PCI Fast Ethernet", "SiS 7016 PCI Fast Ethernet" }; -static struct pci_device_id sis900_pci_tbl [] __devinitdata = { +static struct pci_device_id sis900_pci_tbl [] = { {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_900}, {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7016, @@ -170,6 +170,7 @@ dma_addr_t rx_ring_dma; unsigned int tx_full; /* The Tx queue is full. */ + u8 host_bridge_rev; }; MODULE_AUTHOR("Jim Huang , Ollie Lho "); @@ -197,11 +198,11 @@ static int sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev); static int sis900_rx(struct net_device *net_dev); static void sis900_finish_xmit (struct net_device *net_dev); -static void sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs); +static irqreturn_t sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs); 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); @@ -211,9 +212,10 @@ static u16 sis900_reset_phy(struct net_device *net_dev, int phy_addr); static void sis900_auto_negotiate(struct net_device *net_dev, int phy_addr); static void sis900_set_mode (long ioaddr, int speed, int duplex); +static struct ethtool_ops sis900_ethtool_ops; /** - * 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 +245,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 +278,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 +314,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 +356,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 * @@ -368,6 +370,7 @@ { struct sis900_private *sis_priv; struct net_device *net_dev; + struct pci_dev *dev; dma_addr_t ring_dma; void *ring_space; long ioaddr; @@ -440,6 +443,7 @@ net_dev->do_ioctl = &mii_ioctl; net_dev->tx_timeout = sis900_tx_timeout; net_dev->watchdog_timeo = TX_TIMEOUT; + net_dev->ethtool_ops = &sis900_ethtool_ops; ret = register_netdev(net_dev); if (ret) @@ -473,6 +477,11 @@ goto err_out_unregister; } + /* save our host bridge revision */ + dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630, NULL); + if (dev) + pci_read_config_byte(dev, PCI_CLASS_REVISION, &sis_priv->host_bridge_rev); + /* print some information about our NIC */ printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ", net_dev->name, card_name, ioaddr, net_dev->irq); @@ -499,7 +508,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 +537,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 +602,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 +628,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 +681,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 +711,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 +761,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 +786,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 +828,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 +882,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 +905,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 +962,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 +1000,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 +1033,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 +1087,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 * @@ -1108,18 +1117,12 @@ { struct sis900_private *sis_priv = net_dev->priv; u16 reg14h, eq_value=0, max_value=0, min_value=0; - u8 host_bridge_rev; int i, maxcount=10; - struct pci_dev *dev=NULL; if ( !(revision == SIS630E_900_REV || revision == SIS630EA1_900_REV || revision == SIS630A_900_REV || revision == SIS630ET_900_REV) ) return; - dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630, dev); - if (dev) - pci_read_config_byte(dev, PCI_CLASS_REVISION, &host_bridge_rev); - if (netif_carrier_ok(net_dev)) { reg14h=mdio_read(net_dev, sis_priv->cur_phy, MII_RESV); mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (0x2200 | reg14h) & 0xBFFF); @@ -1142,7 +1145,8 @@ } /* 630B0&B1 rule to determine the equalizer value */ if (revision == SIS630A_900_REV && - (host_bridge_rev == SIS630B0 || host_bridge_rev == SIS630B1)) { + (sis_priv->host_bridge_rev == SIS630B0 || + sis_priv->host_bridge_rev == SIS630B1)) { if (max_value == 0) eq_value=3; else @@ -1157,7 +1161,8 @@ else { reg14h=mdio_read(net_dev, sis_priv->cur_phy, MII_RESV); if (revision == SIS630A_900_REV && - (host_bridge_rev == SIS630B0 || host_bridge_rev == SIS630B1)) + (sis_priv->host_bridge_rev == SIS630B0 || + sis_priv->host_bridge_rev == SIS630B1)) mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (reg14h | 0x2200) & 0xBFFF); else mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (reg14h | 0x2000) & 0xBFFF); @@ -1166,7 +1171,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 +1241,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 +1272,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 +1316,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 +1350,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 +1407,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 @@ -1434,7 +1439,7 @@ pci_unmap_single(sis_priv->pci_dev, sis_priv->tx_ring[i].bufptr, skb->len, PCI_DMA_TODEVICE); - dev_kfree_skb(skb); + dev_kfree_skb_irq(skb); sis_priv->tx_skbuff[i] = 0; sis_priv->tx_ring[i].cmdsts = 0; sis_priv->tx_ring[i].bufptr = 0; @@ -1457,7 +1462,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 +1532,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 @@ -1536,13 +1541,14 @@ * and cleans up after the Tx thread */ -static void sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs) +static irqreturn_t sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *net_dev = dev_instance; struct sis900_private *sis_priv = net_dev->priv; int boguscnt = max_interrupt_work; long ioaddr = net_dev->base_addr; u32 status; + unsigned int handled = 0; spin_lock (&sis_priv->lock); @@ -1552,6 +1558,7 @@ if ((status & (HIBERR|TxURN|TxERR|TxIDLE|RxORN|RxERR|RxOK)) == 0) /* nothing intresting happened */ break; + handled = 1; /* why dow't we break after Tx/Rx case ?? keyword: full-duplex */ if (status & (RxORN | RxERR | RxOK)) @@ -1582,11 +1589,11 @@ net_dev->name, inl(ioaddr + isr)); spin_unlock (&sis_priv->lock); - return; + return IRQ_RETVAL(handled); } /** - * sis900_rx: - sis900 receive routine + * sis900_rx - sis900 receive routine * @net_dev: the net device which receives data * * Process receive interrupt events, @@ -1725,7 +1732,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 +1802,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,41 +1858,29 @@ } /** - * netdev_ethtool_ioctl: - For the basic support of ethtool - * @net_dev: the net device to command for - * @useraddr: start address of interface request + * sis900_get_drvinfo - Return information about driver + * @net_dev: the net device to probe + * @info: container for info returned * * Process ethtool command such as "ehtool -i" to show information */ - -static int netdev_ethtool_ioctl (struct net_device *net_dev, void *useraddr) + +static void sis900_get_drvinfo(struct net_device *net_dev, + struct ethtool_drvinfo *info) { struct sis900_private *sis_priv = net_dev->priv; - 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, SIS900_MODULE_NAME); - strcpy (info.version, SIS900_DRV_VERSION); - strcpy (info.bus_info, sis_priv->pci_dev->slot_name); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - default: - break; - } - - return -EOPNOTSUPP; + strcpy (info->driver, SIS900_MODULE_NAME); + strcpy (info->version, SIS900_DRV_VERSION); + strcpy (info->bus_info, pci_name(sis_priv->pci_dev)); } +static struct ethtool_ops sis900_ethtool_ops = { + .get_drvinfo = sis900_get_drvinfo, +}; + /** - * 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 @@ -1899,9 +1894,6 @@ struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data; switch(cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(net_dev, (void *) rq->ifr_data); - case SIOCGMIIPHY: /* Get address of MII PHY in use. */ case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */ data->phy_id = sis_priv->mii->phy_addr; @@ -1924,7 +1916,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 +1931,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 +1968,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 +2028,7 @@ } /** - * sis900_compute_hashtable_index: - compute hashtable index + * sis900_mcast_bitnr - compute hashtable index * @addr: multicast address * @revision: revision id of chip * @@ -2046,7 +2038,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 +2051,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 +2092,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 & 0xf)); + } } /* update Multicast Hash Table in Receive Filter */ @@ -2131,7 +2125,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 +2160,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 +2189,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) Index: drivers/net/sk_g16.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk_g16.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk_g16.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/sk_g16.c 4 Aug 2004 01:29:11 -0000 1.2 @@ -6,12 +6,12 @@ * * Module : sk_g16.c * - * Version : $Revision: 1.1 $ + * Version : $Revision: 1.2 $ * * Author : Patrick J.D. Weichmann * * Date Created : 94/05/26 - * Last Updated : $Date: 2004/07/22 19:49:32 $ + * Last Updated : $Date: 2004/08/04 01:29:11 $ * * Description : Schneider & Koch G16 Ethernet Device Driver for * Linux Kernel >= 1.1.22 @@ -23,7 +23,7 @@ * -*/ -static const char rcsid[] = "$Id: sk_g16.c,v 1.1 2004/07/22 19:49:32 joff Exp $"; +static const char rcsid[] = "$Id: sk_g16.c,v 1.2 2004/08/04 01:29:11 joff Exp $"; /* * The Schneider & Koch (SK) G16 Network device driver is based Index: drivers/net/sk_g16.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk_g16.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk_g16.h 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/sk_g16.h 4 Aug 2004 01:29:11 -0000 1.2 @@ -4,7 +4,7 @@ * of the GNU General Public License, incorporated herein by reference. * * Module : sk_g16.h - * Version : $Revision: 1.1 $ + * Version : $Revision: 1.2 $ * * Author : M.Hipp (mhipp@student.uni-tuebingen.de) * changes by : Patrick J.D. Weichmann @@ -16,8 +16,8 @@ * network device driver which uses this chip * * $Log: sk_g16.h,v $ - * Revision 1.1 2004/07/22 19:49:32 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:11 joff + * merging 2.4.26-vrs1 * -*/ Index: drivers/net/sk_mca.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk_mca.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk_mca.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/sk_mca.c 4 Aug 2004 01:29:11 -0000 1.2 @@ -1048,13 +1048,13 @@ block.Mode &= ~LANCE_INIT_PROM; if (dev->flags & IFF_ALLMULTI) { /* get all multicasts */ - memset(block.LAdrF, 8, 0xff); + memset(block.LAdrF, 0xff, sizeof(block.LAdrF)); } else { /* get selected/no multicasts */ struct dev_mc_list *mptr; int code; - memset(block.LAdrF, 8, 0x00); + memset(block.LAdrF, 0, sizeof(block.LAdrF)); for (mptr = dev->mc_list; mptr != NULL; mptr = mptr->next) { code = GetHash(mptr->dmi_addr); block.LAdrF[(code >> 3) & 7] |= 1 << (code & 7); Index: drivers/net/sonic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sonic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sonic.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/sonic.c 4 Aug 2004 01:29:12 -0000 1.2 @@ -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 */ @@ -232,7 +223,7 @@ /* We must free the original skb */ if (lp->tx_skb[entry]) { - dev_kfree_skb(lp->tx_skb[entry]); + dev_kfree_skb_irq(lp->tx_skb[entry]); lp->tx_skb[entry] = 0; } /* and the VDMA address */ Index: drivers/net/starfire.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/starfire.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/starfire.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/starfire.c 4 Aug 2004 01:29:12 -0000 1.2 @@ -1121,15 +1121,9 @@ TX_DESC_SPACING | TX_DESC_TYPE, ioaddr + TxDescCtrl); -#if defined(ADDR_64BITS) - writel(np->queue_mem_dma >> 32, ioaddr + RxDescQHiAddr); - writel(np->queue_mem_dma >> 32, ioaddr + TxRingHiAddr); - writel(np->queue_mem_dma >> 32, ioaddr + CompletionHiAddr); -#else - writel(0, ioaddr + RxDescQHiAddr); - writel(0, ioaddr + TxRingHiAddr); - writel(0, ioaddr + CompletionHiAddr); -#endif + writel( (np->queue_mem_dma >> 16) >> 16, ioaddr + RxDescQHiAddr); + writel( (np->queue_mem_dma >> 16) >> 16, ioaddr + TxRingHiAddr); + writel( (np->queue_mem_dma >> 16) >> 16, ioaddr + CompletionHiAddr); writel(np->rx_ring_dma, ioaddr + RxDescQAddr); writel(np->tx_ring_dma, ioaddr + TxRingPtr); Index: drivers/net/sunbmac.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sunbmac.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sunbmac.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/sunbmac.c 4 Aug 2004 01:29:12 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sunbmac.c,v 1.1 2004/07/22 19:49:31 joff Exp $ +/* $Id: sunbmac.c,v 1.2 2004/08/04 01:29:12 joff Exp $ * sunbmac.c: Driver for Sparc BigMAC 100baseT ethernet adapters. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) Index: drivers/net/sunbmac.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sunbmac.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sunbmac.h 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/sunbmac.h 4 Aug 2004 01:29:12 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sunbmac.h,v 1.1 2004/07/22 19:49:31 joff Exp $ +/* $Id: sunbmac.h,v 1.2 2004/08/04 01:29:12 joff Exp $ * sunbmac.h: Defines for the Sun "Big MAC" 100baseT ethernet cards. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) Index: drivers/net/sundance.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sundance.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sundance.c 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/sundance.c 4 Aug 2004 01:29:12 -0000 1.2 @@ -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) Index: drivers/net/sungem.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sungem.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sungem.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/net/sungem.c 4 Aug 2004 01:29:12 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sungem.c,v 1.1 2004/07/22 19:49:30 joff Exp $ +/* $Id: sungem.c,v 1.2 2004/08/04 01:29:12 joff Exp $ * sungem.c: Sun GEM ethernet driver. * * Copyright (C) 2000, 2001, 2002 David S. Miller (davem@redhat.com) @@ -651,6 +651,7 @@ cluster_start = curr = (gp->rx_new & ~(4 - 1)); count = 0; kick = -1; + wmb(); while (curr != limit) { curr = NEXT_RX(curr); if (++count == 4) { @@ -667,13 +668,16 @@ count = 0; } } - if (kick >= 0) + if (kick >= 0) { + mb(); writel(kick, gp->regs + RXDMA_KICK); + } } static void gem_rx(struct gem *gp) { int entry, drops; + u32 done; if (netif_msg_intr(gp)) printk(KERN_DEBUG "%s: rx interrupt, done: %d, rx_new: %d\n", @@ -681,6 +685,7 @@ entry = gp->rx_new; drops = 0; + done = readl(gp->regs + RXDMA_DONE); for (;;) { struct gem_rxd *rxd = &gp->init_block->rxd[entry]; struct sk_buff *skb; @@ -691,6 +696,19 @@ if ((status & RXDCTRL_OWN) != 0) break; + /* When writing back RX descriptor, GEM writes status + * then buffer address, possibly in seperate transactions. + * If we don't wait for the chip to write both, we could + * post a new buffer to this descriptor then have GEM spam + * on the buffer address. We sync on the RX completion + * register to prevent this from happening. + */ + if (entry == done) { + done = readl(gp->regs + RXDMA_DONE); + if (entry == done) + break; + } + skb = gp->rx_skbs[entry]; len = (status & RXDCTRL_BUFSZ) >> 16; @@ -877,6 +895,7 @@ if (gem_intme(entry)) ctrl |= TXDCTRL_INTME; txd->buffer = cpu_to_le64(mapping); + wmb(); txd->control_word = cpu_to_le64(ctrl); entry = NEXT_TX(entry); } else { @@ -916,6 +935,7 @@ txd = &gp->init_block->txd[entry]; txd->buffer = cpu_to_le64(mapping); + wmb(); txd->control_word = cpu_to_le64(this_ctrl | len); if (gem_intme(entry)) @@ -925,6 +945,7 @@ } txd = &gp->init_block->txd[first_entry]; txd->buffer = cpu_to_le64(first_mapping); + wmb(); txd->control_word = cpu_to_le64(ctrl | TXDCTRL_SOF | intme | first_len); } @@ -936,6 +957,7 @@ if (netif_msg_tx_queued(gp)) printk(KERN_DEBUG "%s: tx queued, slot %d, skblen %d\n", dev->name, entry, skb->len); + mb(); writel(gp->tx_new, gp->regs + TXDMA_KICK); spin_unlock_irq(&gp->lock); @@ -1430,6 +1452,7 @@ gp->rx_skbs[i] = NULL; } rxd->status_word = 0; + wmb(); rxd->buffer = 0; } @@ -1491,6 +1514,7 @@ RX_BUF_ALLOC_SIZE(gp), PCI_DMA_FROMDEVICE); rxd->buffer = cpu_to_le64(dma_addr); + wmb(); rxd->status_word = cpu_to_le64(RXDCTRL_FRESH(gp)); skb_reserve(skb, RX_OFFSET); } @@ -1499,8 +1523,10 @@ struct gem_txd *txd = &gb->txd[i]; txd->control_word = 0; + wmb(); txd->buffer = 0; } + wmb(); } /* Must be invoked under gp->lock. */ @@ -2330,17 +2356,14 @@ gp->hw_running = 1; } - spin_lock_irq(&gp->lock); - /* We can now request the interrupt as we know it's masked * on the controller */ if (request_irq(gp->pdev->irq, gem_interrupt, SA_SHIRQ, dev->name, (void *)dev)) { - spin_unlock_irq(&gp->lock); - printk(KERN_ERR "%s: failed to request irq !\n", gp->dev->name); + spin_lock_irq(&gp->lock); #ifdef CONFIG_ALL_PPC if (!hw_was_up && gp->pdev->vendor == PCI_VENDOR_ID_APPLE) gem_apple_powerdown(gp); @@ -2349,10 +2372,13 @@ gp->pm_timer.expires = jiffies + 10*HZ; add_timer(&gp->pm_timer); up(&gp->pm_sem); + spin_unlock_irq(&gp->lock); return -EAGAIN; } + spin_lock_irq(&gp->lock); + /* Allocate & setup ring buffers */ gem_init_rings(gp); @@ -2616,9 +2642,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) Index: drivers/net/sungem.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sungem.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sungem.h 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/net/sungem.h 4 Aug 2004 01:29:12 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sungem.h,v 1.1 2004/07/22 19:49:30 joff Exp $ +/* $Id: sungem.h,v 1.2 2004/08/04 01:29:12 joff Exp $ * sungem.h: Definitions for Sun GEM ethernet driver. * * Copyright (C) 2000 David S. Miller (davem@redhat.com) Index: drivers/net/sunhme.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sunhme.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sunhme.c 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/net/sunhme.c 4 Aug 2004 01:29:12 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sunhme.c,v 1.1 2004/07/22 19:49:30 joff Exp $ +/* $Id: sunhme.c,v 1.2 2004/08/04 01:29:12 joff Exp $ * sunhme.c: Sparc HME/BigMac 10/100baseT half/full duplex auto switching, * auto carrier detecting ethernet driver. Also known as the * "Happy Meal Ethernet" found on SunSwift SBUS cards. @@ -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]; @@ -2971,7 +2968,7 @@ dev_addr[0] = 0x08; dev_addr[1] = 0x00; dev_addr[2] = 0x20; - get_random_bytes(dev_addr, 3); + get_random_bytes(&dev_addr[3], 3); return; } #endif /* !(__sparc__) */ @@ -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) Index: drivers/net/sunhme.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sunhme.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sunhme.h 22 Jul 2004 19:49:30 -0000 1.1 +++ drivers/net/sunhme.h 4 Aug 2004 01:29:12 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sunhme.h,v 1.1 2004/07/22 19:49:30 joff Exp $ +/* $Id: sunhme.h,v 1.2 2004/08/04 01:29:12 joff Exp $ * sunhme.h: Definitions for Sparc HME/BigMac 10/100baseT ethernet driver. * Also known as the "Happy Meal". * Index: drivers/net/sunlance.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sunlance.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sunlance.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/sunlance.c 4 Aug 2004 01:29:12 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sunlance.c,v 1.1 2004/07/22 19:49:34 joff Exp $ +/* $Id: sunlance.c,v 1.2 2004/08/04 01:29:12 joff Exp $ * lance.c: Linux/Sparc/Lance driver * * Written 1995, 1996 by Miguel de Icaza Index: drivers/net/sunqe.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sunqe.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sunqe.c 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/sunqe.c 4 Aug 2004 01:29:12 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sunqe.c,v 1.1 2004/07/22 19:49:33 joff Exp $ +/* $Id: sunqe.c,v 1.2 2004/08/04 01:29:12 joff Exp $ * sunqe.c: Sparc QuadEthernet 10baseT SBUS card driver. * Once again I am out to prove that every ethernet * controller out there can be most efficiently programmed Index: drivers/net/sunqe.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sunqe.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sunqe.h 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/sunqe.h 4 Aug 2004 01:29:12 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sunqe.h,v 1.1 2004/07/22 19:49:33 joff Exp $ +/* $Id: sunqe.h,v 1.2 2004/08/04 01:29:12 joff Exp $ * sunqe.h: Definitions for the Sun QuadEthernet driver. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) Index: drivers/net/tc35815.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/tc35815.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/tc35815.c 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/tc35815.c 4 Aug 2004 01:29:12 -0000 1.2 @@ -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 Index: drivers/net/tg3.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/tg3.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/tg3.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/tg3.c 4 Aug 2004 01:29:12 -0000 1.2 @@ -1,8 +1,8 @@ /* * tg3.c: Broadcom Tigon3 ethernet driver. * - * Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com) - * Copyright (C) 2001, 2002 Jeff Garzik (jgarzik@pobox.com) + * Copyright (C) 2001, 2002, 2003 David S. Miller (davem@redhat.com) + * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com) */ #include @@ -23,14 +23,20 @@ #include #include #include +#include +#include + +#include #include #include #include #include -#ifndef PCI_DMA_BUS_IS_PHYS -#define PCI_DMA_BUS_IS_PHYS 1 +#ifdef CONFIG_SPARC64 +#include +#include +#include #endif #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) @@ -40,18 +46,17 @@ #endif #ifdef NETIF_F_TSO -/* XXX some bug in tso firmware hangs tx cpu, disabled until fixed */ -#define TG3_DO_TSO 0 +#define TG3_TSO_SUPPORT 1 #else -#define TG3_DO_TSO 0 +#define TG3_TSO_SUPPORT 0 #endif #include "tg3.h" #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 "2.9" +#define DRV_MODULE_RELDATE "March 8, 2004" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -73,7 +78,8 @@ /* hardware minimum and maximum for a single frame's data payload */ #define TG3_MIN_MTU 60 -#define TG3_MAX_MTU 9000 +#define TG3_MAX_MTU(tp) \ + (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 ? 9000 : 1500) /* These numbers seem to be hard coded in the NIC firmware somehow. * You can't change the ring sizes, but you can change where you place @@ -83,7 +89,17 @@ #define TG3_DEF_RX_RING_PENDING 200 #define TG3_RX_JUMBO_RING_SIZE 256 #define TG3_DEF_RX_JUMBO_RING_PENDING 100 -#define TG3_RX_RCB_RING_SIZE 1024 + +/* Do not place this n-ring entries value into the tp struct itself, + * we really want to expose these constants to GCC so that modulo et + * al. operations are done with shifts and masks instead of with + * hw multiply/modulo instructions. Another solution would be to + * replace things like '% foo' with '& (foo - 1)'. + */ +#define TG3_RX_RCB_RING_SIZE(tp) \ + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 ? \ + 512 : 1024) + #define TG3_TX_RING_SIZE 512 #define TG3_DEF_TX_RING_PENDING (TG3_TX_RING_SIZE - 1) @@ -91,8 +107,8 @@ TG3_RX_RING_SIZE) #define TG3_RX_JUMBO_RING_BYTES (sizeof(struct tg3_rx_buffer_desc) * \ TG3_RX_JUMBO_RING_SIZE) -#define TG3_RX_RCB_RING_BYTES (sizeof(struct tg3_rx_buffer_desc) * \ - TG3_RX_RCB_RING_SIZE) +#define TG3_RX_RCB_RING_BYTES(tp) (sizeof(struct tg3_rx_buffer_desc) * \ + TG3_RX_RCB_RING_SIZE(tp)) #define TG3_TX_RING_BYTES (sizeof(struct tg3_tx_buffer_desc) * \ TG3_TX_RING_SIZE) #define TX_RING_GAP(TP) \ @@ -120,7 +136,7 @@ static int tg3_debug = -1; /* -1 == use TG3_DEF_MSG_ENABLE as value */ -static struct pci_device_id tg3_pci_tbl[] __devinitdata = { +static struct pci_device_id tg3_pci_tbl[] = { { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5701, @@ -133,6 +149,14 @@ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702FE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705_2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705M, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705M_2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702X, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703X, @@ -143,12 +167,32 @@ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703A3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, - { PCI_VENDOR_ID_SYSKONNECT, 0x4400, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5782, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5788, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901_2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704S_2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705F, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1001, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1003, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_TIGON3, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { 0, } }; @@ -170,8 +214,46 @@ } } +static void _tw32_flush(struct tg3 *tp, u32 off, u32 val) +{ + if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { + unsigned long flags; + + spin_lock_irqsave(&tp->indirect_lock, flags); + pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); + pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); + spin_unlock_irqrestore(&tp->indirect_lock, flags); + } else { + unsigned long dest = tp->regs + off; + writel(val, dest); + readl(dest); /* always flush PCI write */ + } +} + +static inline void _tw32_rx_mbox(struct tg3 *tp, u32 off, u32 val) +{ + unsigned long mbox = tp->regs + off; + writel(val, mbox); + if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) + readl(mbox); +} + +static inline void _tw32_tx_mbox(struct tg3 *tp, u32 off, u32 val) +{ + unsigned long mbox = tp->regs + off; + writel(val, mbox); + if (tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG) + writel(val, mbox); + if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) + readl(mbox); +} + +#define tw32_mailbox(reg, val) writel(((val) & 0xffffffff), tp->regs + (reg)) +#define tw32_rx_mbox(reg, val) _tw32_rx_mbox(tp, reg, val) +#define tw32_tx_mbox(reg, val) _tw32_tx_mbox(tp, reg, val) + #define tw32(reg,val) tg3_write_indirect_reg32(tp,(reg),(val)) -#define tw32_mailbox(reg, val) writel(((val) & 0xffffffff), tp->regs + (reg)) +#define tw32_f(reg,val) _tw32_flush(tp,(reg),(val)) #define tw16(reg,val) writew(((val) & 0xffff), tp->regs + (reg)) #define tw8(reg,val) writeb(((val) & 0xff), tp->regs + (reg)) #define tr32(reg) readl(tp->regs + (reg)) @@ -228,37 +310,6 @@ tg3_cond_int(tp); } -/* these netif_xxx funcs should be moved into generic net layer */ -static void netif_poll_disable(struct net_device *dev) -{ - while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state)) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); - } -} - -static inline void netif_poll_enable(struct net_device *dev) -{ - clear_bit(__LINK_STATE_RX_SCHED, &dev->state); -} - -/* same as netif_rx_complete, except that local_irq_save(flags) - * has already been issued - */ -static inline void __netif_rx_complete(struct net_device *dev) -{ - if (!test_bit(__LINK_STATE_RX_SCHED, &dev->state)) BUG(); - list_del(&dev->poll_list); - clear_bit(__LINK_STATE_RX_SCHED, &dev->state); -} - -static inline void netif_tx_disable(struct net_device *dev) -{ - spin_lock_bh(&dev->xmit_lock); - netif_stop_queue(dev); - spin_unlock_bh(&dev->xmit_lock); -} - static inline void tg3_netif_stop(struct tg3 *tp) { netif_poll_disable(tp->dev); @@ -278,18 +329,26 @@ static void tg3_switch_clocks(struct tg3 *tp) { - if (tr32(TG3PCI_CLOCK_CTRL) & CLOCK_CTRL_44MHZ_CORE) { - tw32(TG3PCI_CLOCK_CTRL, + u32 clock_ctrl = tr32(TG3PCI_CLOCK_CTRL); + u32 orig_clock_ctrl; + + orig_clock_ctrl = clock_ctrl; + clock_ctrl &= (CLOCK_CTRL_FORCE_CLKRUN | + CLOCK_CTRL_CLKRUN_OENABLE | + 0x1f); + tp->pci_clock_ctrl = clock_ctrl; + + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 && + (orig_clock_ctrl & CLOCK_CTRL_44MHZ_CORE) != 0) { + tw32_f(TG3PCI_CLOCK_CTRL, + clock_ctrl | (CLOCK_CTRL_44MHZ_CORE | CLOCK_CTRL_ALTCLK)); - tr32(TG3PCI_CLOCK_CTRL); udelay(40); - tw32(TG3PCI_CLOCK_CTRL, - (CLOCK_CTRL_ALTCLK)); - tr32(TG3PCI_CLOCK_CTRL); + tw32_f(TG3PCI_CLOCK_CTRL, + clock_ctrl | (CLOCK_CTRL_ALTCLK)); udelay(40); } - tw32(TG3PCI_CLOCK_CTRL, 0); - tr32(TG3PCI_CLOCK_CTRL); + tw32_f(TG3PCI_CLOCK_CTRL, clock_ctrl); udelay(40); } @@ -301,9 +360,8 @@ int loops, ret; if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) { - tw32(MAC_MI_MODE, + tw32_f(MAC_MI_MODE, (tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL)); - tr32(MAC_MI_MODE); udelay(40); } @@ -315,8 +373,7 @@ MI_COM_REG_ADDR_MASK); frame_val |= (MI_COM_CMD_READ | MI_COM_START); - tw32(MAC_MI_COM, frame_val); - tr32(MAC_MI_COM); + tw32_f(MAC_MI_COM, frame_val); loops = PHY_BUSY_LOOPS; while (loops-- > 0) { @@ -337,8 +394,7 @@ } if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) { - tw32(MAC_MI_MODE, tp->mi_mode); - tr32(MAC_MI_MODE); + tw32_f(MAC_MI_MODE, tp->mi_mode); udelay(40); } @@ -351,9 +407,8 @@ int loops, ret; if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) { - tw32(MAC_MI_MODE, + tw32_f(MAC_MI_MODE, (tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL)); - tr32(MAC_MI_MODE); udelay(40); } @@ -364,8 +419,7 @@ frame_val |= (val & MI_COM_DATA_MASK); frame_val |= (MI_COM_CMD_WRITE | MI_COM_START); - tw32(MAC_MI_COM, frame_val); - tr32(MAC_MI_COM); + tw32_f(MAC_MI_COM, frame_val); loops = PHY_BUSY_LOOPS; while (loops-- > 0) { @@ -383,32 +437,29 @@ ret = 0; if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) { - tw32(MAC_MI_MODE, tp->mi_mode); - tr32(MAC_MI_MODE); + tw32_f(MAC_MI_MODE, tp->mi_mode); udelay(40); } return ret; } -/* This will reset the tigon3 PHY if there is no valid - * link unless the FORCE argument is non-zero. - */ -static int tg3_phy_reset(struct tg3 *tp, int force) +static void tg3_phy_set_wirespeed(struct tg3 *tp) { - u32 phy_status, phy_control; - int err, limit; + u32 val; - err = tg3_readphy(tp, MII_BMSR, &phy_status); - err |= tg3_readphy(tp, MII_BMSR, &phy_status); - if (err != 0) - return -EBUSY; + if (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) + return; - /* If we have link, and not forcing a reset, then nothing - * to do. - */ - if ((phy_status & BMSR_LSTATUS) != 0 && (force == 0)) - return 0; + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x7007); + tg3_readphy(tp, MII_TG3_AUX_CTRL, &val); + tg3_writephy(tp, MII_TG3_AUX_CTRL, (val | (1 << 15) | (1 << 4))); +} + +static int tg3_bmcr_reset(struct tg3 *tp) +{ + u32 phy_control; + int limit, err; /* OK, reset it, and poll the BMCR_RESET bit until it * clears or we time out. @@ -426,15 +477,311 @@ if ((phy_control & BMCR_RESET) == 0) { udelay(40); - return 0; + break; } udelay(10); } + if (limit <= 0) + return -EBUSY; + + return 0; +} + +static int tg3_wait_macro_done(struct tg3 *tp) +{ + int limit = 100; + + while (limit--) { + u32 tmp32; + + tg3_readphy(tp, 0x16, &tmp32); + if ((tmp32 & 0x1000) == 0) + break; + } + if (limit <= 0) + return -EBUSY; + + return 0; +} + +static int tg3_phy_write_and_check_testpat(struct tg3 *tp, int *resetp) +{ + static const u32 test_pat[4][6] = { + { 0x00005555, 0x00000005, 0x00002aaa, 0x0000000a, 0x00003456, 0x00000003 }, + { 0x00002aaa, 0x0000000a, 0x00003333, 0x00000003, 0x0000789a, 0x00000005 }, + { 0x00005a5a, 0x00000005, 0x00002a6a, 0x0000000a, 0x00001bcd, 0x00000003 }, + { 0x00002a5a, 0x0000000a, 0x000033c3, 0x00000003, 0x00002ef1, 0x00000005 } + }; + int chan; + + for (chan = 0; chan < 4; chan++) { + int i; + + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, + (chan * 0x2000) | 0x0200); + tg3_writephy(tp, 0x16, 0x0002); + + for (i = 0; i < 6; i++) + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, + test_pat[chan][i]); + + tg3_writephy(tp, 0x16, 0x0202); + if (tg3_wait_macro_done(tp)) { + *resetp = 1; + return -EBUSY; + } + + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, + (chan * 0x2000) | 0x0200); + tg3_writephy(tp, 0x16, 0x0082); + if (tg3_wait_macro_done(tp)) { + *resetp = 1; + return -EBUSY; + } + + tg3_writephy(tp, 0x16, 0x0802); + if (tg3_wait_macro_done(tp)) { + *resetp = 1; + return -EBUSY; + } + + for (i = 0; i < 6; i += 2) { + u32 low, high; + + tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &low); + tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &high); + if (tg3_wait_macro_done(tp)) { + *resetp = 1; + return -EBUSY; + } + low &= 0x7fff; + high &= 0x000f; + if (low != test_pat[chan][i] || + high != test_pat[chan][i+1]) { + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000b); + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x4001); + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x4005); + + return -EBUSY; + } + } + } + + return 0; +} + +static int tg3_phy_reset_chanpat(struct tg3 *tp) +{ + int chan; + + for (chan = 0; chan < 4; chan++) { + int i; + + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, + (chan * 0x2000) | 0x0200); + tg3_writephy(tp, 0x16, 0x0002); + for (i = 0; i < 6; i++) + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x000); + tg3_writephy(tp, 0x16, 0x0202); + if (tg3_wait_macro_done(tp)) + return -EBUSY; + } + + return 0; +} + +static int tg3_phy_reset_5703_4_5(struct tg3 *tp) +{ + u32 reg32, phy9_orig; + int retries, do_phy_reset, err; + + retries = 10; + do_phy_reset = 1; + do { + if (do_phy_reset) { + err = tg3_bmcr_reset(tp); + if (err) + return err; + do_phy_reset = 0; + } + + /* Disable transmitter and interrupt. */ + tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32); + reg32 |= 0x3000; + tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32); + + /* Set full-duplex, 1000 mbps. */ + tg3_writephy(tp, MII_BMCR, + BMCR_FULLDPLX | TG3_BMCR_SPEED1000); + + /* Set to master mode. */ + tg3_readphy(tp, MII_TG3_CTRL, &phy9_orig); + tg3_writephy(tp, MII_TG3_CTRL, + (MII_TG3_CTRL_AS_MASTER | + MII_TG3_CTRL_ENABLE_AS_MASTER)); + + /* Enable SM_DSP_CLOCK and 6dB. */ + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00); + + /* Block the PHY control access. */ + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8005); + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0800); + + err = tg3_phy_write_and_check_testpat(tp, &do_phy_reset); + if (!err) + break; + } while (--retries); + + err = tg3_phy_reset_chanpat(tp); + if (err) + return err; + + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8005); + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0000); + + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200); + tg3_writephy(tp, 0x16, 0x0000); + + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400); + + tg3_writephy(tp, MII_TG3_CTRL, phy9_orig); + + tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32); + reg32 &= ~0x3000; + tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32); + + return err; +} + +/* This will reset the tigon3 PHY if there is no valid + * link unless the FORCE argument is non-zero. + */ +static int tg3_phy_reset(struct tg3 *tp, int force) +{ + u32 phy_status; + int err; + + err = tg3_readphy(tp, MII_BMSR, &phy_status); + err |= tg3_readphy(tp, MII_BMSR, &phy_status); + if (err != 0) + return -EBUSY; + + /* If we have link, and not forcing a reset, then nothing + * to do. + */ + if ((phy_status & BMSR_LSTATUS) != 0 && (force == 0)) + return 0; + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + err = tg3_phy_reset_5703_4_5(tp); + if (err) + return err; + goto out; + } + + err = tg3_bmcr_reset(tp); + if (err) + return err; + +out: + if (tp->tg3_flags2 & TG3_FLG2_PHY_ADC_BUG) { + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00); + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x201f); + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x2aaa); + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a); + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0323); + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400); + } + if (tp->tg3_flags2 & TG3_FLG2_PHY_5704_A0_BUG) { + tg3_writephy(tp, 0x1c, 0x8d68); + tg3_writephy(tp, 0x1c, 0x8d68); + } + tg3_phy_set_wirespeed(tp); + return 0; +} + +static void tg3_frob_aux_power(struct tg3 *tp) +{ + struct tg3 *tp_peer = tp; + + if ((tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) != 0) + return; + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { + tp_peer = pci_get_drvdata(tp->pdev_peer); + if (!tp_peer) + BUG(); + } + + + if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 || + (tp_peer->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { + tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | + (GRC_LCLCTRL_GPIO_OE0 | + GRC_LCLCTRL_GPIO_OE1 | + GRC_LCLCTRL_GPIO_OE2 | + GRC_LCLCTRL_GPIO_OUTPUT0 | + GRC_LCLCTRL_GPIO_OUTPUT1)); + udelay(100); + } else { + if (tp_peer != tp && + (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) != 0) + return; - return -EBUSY; + tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | + (GRC_LCLCTRL_GPIO_OE0 | + GRC_LCLCTRL_GPIO_OE1 | + GRC_LCLCTRL_GPIO_OE2 | + GRC_LCLCTRL_GPIO_OUTPUT1 | + GRC_LCLCTRL_GPIO_OUTPUT2)); + udelay(100); + + tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | + (GRC_LCLCTRL_GPIO_OE0 | + GRC_LCLCTRL_GPIO_OE1 | + GRC_LCLCTRL_GPIO_OE2 | + GRC_LCLCTRL_GPIO_OUTPUT0 | + GRC_LCLCTRL_GPIO_OUTPUT1 | + GRC_LCLCTRL_GPIO_OUTPUT2)); + udelay(100); + + tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | + (GRC_LCLCTRL_GPIO_OE0 | + GRC_LCLCTRL_GPIO_OE1 | + GRC_LCLCTRL_GPIO_OE2 | + GRC_LCLCTRL_GPIO_OUTPUT0 | + GRC_LCLCTRL_GPIO_OUTPUT1)); + udelay(100); + } + } else { + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) { + if (tp_peer != tp && + (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) != 0) + return; + + tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | + (GRC_LCLCTRL_GPIO_OE1 | + GRC_LCLCTRL_GPIO_OUTPUT1)); + udelay(100); + + tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | + (GRC_LCLCTRL_GPIO_OE1)); + udelay(100); + + tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | + (GRC_LCLCTRL_GPIO_OE1 | + GRC_LCLCTRL_GPIO_OUTPUT1)); + udelay(100); + } + } } -static int tg3_setup_phy(struct tg3 *); +static int tg3_setup_phy(struct tg3 *, int); static int tg3_set_power_state(struct tg3 *tp, int state) { @@ -460,8 +807,7 @@ pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control); - tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl); - tr32(GRC_LOCAL_CTRL); + tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); udelay(100); return 0; @@ -502,7 +848,7 @@ tp->link_config.speed = SPEED_10; tp->link_config.duplex = DUPLEX_HALF; tp->link_config.autoneg = AUTONEG_ENABLE; - tg3_setup_phy(tp); + tg3_setup_phy(tp, 0); } pci_read_config_word(tp->pdev, pm + PCI_PM_PMC, &power_caps); @@ -528,98 +874,69 @@ (tp->tg3_flags & TG3_FLAG_WOL_ENABLE))) mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE; - tw32(MAC_MODE, mac_mode); - tr32(MAC_MODE); + tw32_f(MAC_MODE, mac_mode); udelay(100); - tw32(MAC_RX_MODE, RX_MODE_ENABLE); - tr32(MAC_RX_MODE); + tw32_f(MAC_RX_MODE, RX_MODE_ENABLE); udelay(10); } - if (tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB) { + if (!(tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB) && + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) { u32 base_val; - base_val = 0; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) - base_val |= (CLOCK_CTRL_RXCLK_DISABLE | - CLOCK_CTRL_TXCLK_DISABLE); - - tw32(TG3PCI_CLOCK_CTRL, base_val | - CLOCK_CTRL_ALTCLK); - tr32(TG3PCI_CLOCK_CTRL); - udelay(40); + base_val = tp->pci_clock_ctrl; + base_val |= (CLOCK_CTRL_RXCLK_DISABLE | + CLOCK_CTRL_TXCLK_DISABLE); - tw32(TG3PCI_CLOCK_CTRL, base_val | + tw32_f(TG3PCI_CLOCK_CTRL, base_val | CLOCK_CTRL_ALTCLK | - CLOCK_CTRL_44MHZ_CORE); - tr32(TG3PCI_CLOCK_CTRL); - udelay(40); - - tw32(TG3PCI_CLOCK_CTRL, base_val | - CLOCK_CTRL_44MHZ_CORE); - tr32(TG3PCI_CLOCK_CTRL); + CLOCK_CTRL_PWRDOWN_PLL133); udelay(40); } else { - u32 base_val; + u32 newbits1, newbits2; - base_val = 0; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) - base_val |= (CLOCK_CTRL_RXCLK_DISABLE | - CLOCK_CTRL_TXCLK_DISABLE); + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { + newbits1 = (CLOCK_CTRL_RXCLK_DISABLE | + CLOCK_CTRL_TXCLK_DISABLE | + CLOCK_CTRL_ALTCLK); + newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE; + } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + newbits1 = CLOCK_CTRL_625_CORE; + newbits2 = newbits1 | CLOCK_CTRL_ALTCLK; + } else { + newbits1 = CLOCK_CTRL_ALTCLK; + newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE; + } - tw32(TG3PCI_CLOCK_CTRL, base_val | - CLOCK_CTRL_ALTCLK | - CLOCK_CTRL_PWRDOWN_PLL133); - tr32(TG3PCI_CLOCK_CTRL); + tw32_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits1); udelay(40); - } - if (!(tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) && - (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) { - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { - tw32(GRC_LOCAL_CTRL, - (GRC_LCLCTRL_GPIO_OE0 | - GRC_LCLCTRL_GPIO_OE1 | - GRC_LCLCTRL_GPIO_OE2 | - GRC_LCLCTRL_GPIO_OUTPUT0 | - GRC_LCLCTRL_GPIO_OUTPUT1)); - tr32(GRC_LOCAL_CTRL); - udelay(100); - } else { - tw32(GRC_LOCAL_CTRL, - (GRC_LCLCTRL_GPIO_OE0 | - GRC_LCLCTRL_GPIO_OE1 | - GRC_LCLCTRL_GPIO_OE2 | - GRC_LCLCTRL_GPIO_OUTPUT1 | - GRC_LCLCTRL_GPIO_OUTPUT2)); - tr32(GRC_LOCAL_CTRL); - udelay(100); + tw32_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits2); + udelay(40); - tw32(GRC_LOCAL_CTRL, - (GRC_LCLCTRL_GPIO_OE0 | - GRC_LCLCTRL_GPIO_OE1 | - GRC_LCLCTRL_GPIO_OE2 | - GRC_LCLCTRL_GPIO_OUTPUT0 | - GRC_LCLCTRL_GPIO_OUTPUT1 | - GRC_LCLCTRL_GPIO_OUTPUT2)); - tr32(GRC_LOCAL_CTRL); - udelay(100); + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + u32 newbits3; - tw32(GRC_LOCAL_CTRL, - (GRC_LCLCTRL_GPIO_OE0 | - GRC_LCLCTRL_GPIO_OE1 | - GRC_LCLCTRL_GPIO_OE2 | - GRC_LCLCTRL_GPIO_OUTPUT0 | - GRC_LCLCTRL_GPIO_OUTPUT1)); - tr32(GRC_LOCAL_CTRL); - udelay(100); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { + newbits3 = (CLOCK_CTRL_RXCLK_DISABLE | + CLOCK_CTRL_TXCLK_DISABLE | + CLOCK_CTRL_44MHZ_CORE); + } else { + newbits3 = CLOCK_CTRL_44MHZ_CORE; + } + + tw32_f(TG3PCI_CLOCK_CTRL, + tp->pci_clock_ctrl | newbits3); + udelay(40); } } + tg3_frob_aux_power(tp); + /* Finally, set the new power state. */ pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control); @@ -727,7 +1044,7 @@ }; } -static int tg3_phy_copper_begin(struct tg3 *tp, int wait_for_link) +static int tg3_phy_copper_begin(struct tg3 *tp) { u32 new_adv; int i; @@ -845,7 +1162,7 @@ tg3_readphy(tp, MII_BMCR, &orig_bmcr); if (bmcr != orig_bmcr) { tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK); - for (i = 0; i < 15000; i++) { + for (i = 0; i < 1500; i++) { u32 tmp; udelay(10); @@ -864,27 +1181,6 @@ BMCR_ANENABLE | BMCR_ANRESTART); } - if (wait_for_link) { - tp->link_config.active_speed = SPEED_INVALID; - tp->link_config.active_duplex = DUPLEX_INVALID; - for (i = 0; i < 300000; i++) { - u32 tmp; - - udelay(10); - tg3_readphy(tp, MII_BMSR, &tmp); - tg3_readphy(tp, MII_BMSR, &tmp); - if (!(tmp & BMSR_LSTATUS)) - continue; - - tg3_readphy(tp, MII_TG3_AUX_STAT, &tmp); - tg3_aux_stat_to_speed_duplex(tp, tmp, - &tp->link_config.active_speed, - &tp->link_config.active_duplex); - } - if (tp->link_config.active_speed == SPEED_INVALID) - return -EINVAL; - } - return 0; } @@ -915,7 +1211,7 @@ return err; } -static int tg3_setup_copper_phy(struct tg3 *tp) +static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) { int current_link_up; u32 bmsr, dummy; @@ -923,32 +1219,35 @@ u8 current_duplex; int i, err; - tw32(MAC_STATUS, + tw32(MAC_EVENT, 0); + + tw32_f(MAC_STATUS, (MAC_STATUS_SYNC_CHANGED | - MAC_STATUS_CFG_CHANGED)); - tr32(MAC_STATUS); + MAC_STATUS_CFG_CHANGED | + MAC_STATUS_MI_COMPLETION | + MAC_STATUS_LNKSTATE_CHANGED)); udelay(40); tp->mi_mode = MAC_MI_MODE_BASE; - tw32(MAC_MI_MODE, tp->mi_mode); - tr32(MAC_MI_MODE); + tw32_f(MAC_MI_MODE, tp->mi_mode); udelay(40); tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x02); /* Some third-party PHYs need to be reset on link going * down. - * - * XXX 5705 note: This workaround also applies to 5705_a0 */ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) && + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || + tp->pci_chip_rev_id == CHIPREV_ID_5705_A0) && netif_carrier_ok(tp->dev)) { tg3_readphy(tp, MII_BMSR, &bmsr); tg3_readphy(tp, MII_BMSR, &bmsr); if (!(bmsr & BMSR_LSTATUS)) - tg3_phy_reset(tp, 1); + force_reset = 1; } + if (force_reset) + tg3_phy_reset(tp, 1); if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) { tg3_readphy(tp, MII_BMSR, &bmsr); @@ -1084,7 +1383,7 @@ if (current_link_up == 0) { u32 tmp; - tg3_phy_copper_begin(tp, 0); + tg3_phy_copper_begin(tp); tg3_readphy(tp, MII_BMSR, &tmp); tg3_readphy(tp, MII_BMSR, &tmp); @@ -1124,24 +1423,19 @@ if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5411 && tp->pci_chip_rev_id == CHIPREV_ID_5700_ALTIMA) { tp->mi_mode |= MAC_MI_MODE_AUTO_POLL; - tw32(MAC_MI_MODE, tp->mi_mode); - tr32(MAC_MI_MODE); + tw32_f(MAC_MI_MODE, tp->mi_mode); udelay(40); } - tw32(MAC_MODE, tp->mac_mode); - tr32(MAC_MODE); + tw32_f(MAC_MODE, tp->mac_mode); udelay(40); - if (tp->tg3_flags & - (TG3_FLAG_USE_LINKCHG_REG | - TG3_FLAG_POLL_SERDES)) { + if (tp->tg3_flags & (TG3_FLAG_USE_LINKCHG_REG | TG3_FLAG_POLL_SERDES)) { /* Polled via timer. */ - tw32(MAC_EVENT, 0); + tw32_f(MAC_EVENT, 0); } else { - tw32(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED); + tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED); } - tr32(MAC_EVENT); udelay(40); if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 && @@ -1150,10 +1444,9 @@ ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) || (tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED))) { udelay(120); - tw32(MAC_STATUS, + tw32_f(MAC_STATUS, (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)); - tr32(MAC_STATUS); udelay(40); tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX, @@ -1315,8 +1608,7 @@ ap->txconfig = 0; tw32(MAC_TX_AUTO_NEG, 0); tp->mac_mode |= MAC_MODE_SEND_CONFIGS; - tw32(MAC_MODE, tp->mac_mode); - tr32(MAC_MODE); + tw32_f(MAC_MODE, tp->mac_mode); udelay(40); ret = ANEG_TIMER_ENAB; @@ -1341,8 +1633,7 @@ ap->txconfig = (ANEG_CFG_FD | ANEG_CFG_PS1); tw32(MAC_TX_AUTO_NEG, ap->txconfig); tp->mac_mode |= MAC_MODE_SEND_CONFIGS; - tw32(MAC_MODE, tp->mac_mode); - tr32(MAC_MODE); + tw32_f(MAC_MODE, tp->mac_mode); udelay(40); ap->state = ANEG_STATE_ABILITY_DETECT; @@ -1358,8 +1649,7 @@ ap->txconfig |= ANEG_CFG_ACK; tw32(MAC_TX_AUTO_NEG, ap->txconfig); tp->mac_mode |= MAC_MODE_SEND_CONFIGS; - tw32(MAC_MODE, tp->mac_mode); - tr32(MAC_MODE); + tw32_f(MAC_MODE, tp->mac_mode); udelay(40); ap->state = ANEG_STATE_ACK_DETECT; @@ -1445,8 +1735,7 @@ case ANEG_STATE_IDLE_DETECT_INIT: ap->link_time = ap->cur_time; tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS; - tw32(MAC_MODE, tp->mac_mode); - tr32(MAC_MODE); + tw32_f(MAC_MODE, tp->mac_mode); udelay(40); ap->state = ANEG_STATE_IDLE_DETECT; @@ -1487,7 +1776,7 @@ return ret; } -static int tg3_setup_fiber_phy(struct tg3 *tp) +static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset) { u32 orig_pause_cfg; u16 orig_active_speed; @@ -1503,8 +1792,7 @@ tp->mac_mode &= ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX); tp->mac_mode |= MAC_MODE_PORT_MODE_TBI; - tw32(MAC_MODE, tp->mac_mode); - tr32(MAC_MODE); + tw32_f(MAC_MODE, tp->mac_mode); udelay(40); /* Reset when initting first time or we have a link. */ @@ -1552,10 +1840,9 @@ /* Enable link change interrupt unless serdes polling. */ if (!(tp->tg3_flags & TG3_FLAG_POLL_SERDES)) - tw32(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED); + tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED); else - tw32(MAC_EVENT, 0); - tr32(MAC_EVENT); + tw32_f(MAC_EVENT, 0); udelay(40); current_link_up = 0; @@ -1573,12 +1860,10 @@ tw32(MAC_TX_AUTO_NEG, 0); tmp = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK; - tw32(MAC_MODE, tmp | MAC_MODE_PORT_MODE_GMII); - tr32(MAC_MODE); + tw32_f(MAC_MODE, tmp | MAC_MODE_PORT_MODE_GMII); udelay(40); - tw32(MAC_MODE, tp->mac_mode | MAC_MODE_SEND_CONFIGS); - tr32(MAC_MODE); + tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_SEND_CONFIGS); udelay(40); aninfo.state = ANEG_STATE_UNKNOWN; @@ -1594,8 +1879,7 @@ } tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS; - tw32(MAC_MODE, tp->mac_mode); - tr32(MAC_MODE); + tw32_f(MAC_MODE, tp->mac_mode); udelay(40); if (status == ANEG_DONE && @@ -1619,10 +1903,9 @@ } for (i = 0; i < 60; i++) { udelay(20); - tw32(MAC_STATUS, + tw32_f(MAC_STATUS, (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)); - tr32(MAC_STATUS); udelay(40); if ((tr32(MAC_STATUS) & (MAC_STATUS_SYNC_CHANGED | @@ -1640,8 +1923,7 @@ } tp->mac_mode &= ~MAC_MODE_LINK_POLARITY; - tw32(MAC_MODE, tp->mac_mode); - tr32(MAC_MODE); + tw32_f(MAC_MODE, tp->mac_mode); udelay(40); tp->hw_status->status = @@ -1650,10 +1932,9 @@ for (i = 0; i < 100; i++) { udelay(20); - tw32(MAC_STATUS, + tw32_f(MAC_STATUS, (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)); - tr32(MAC_STATUS); udelay(40); if ((tr32(MAC_STATUS) & (MAC_STATUS_SYNC_CHANGED | @@ -1689,12 +1970,10 @@ } if ((tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED) == 0) { - tw32(MAC_MODE, tp->mac_mode | MAC_MODE_LINK_POLARITY); - tr32(MAC_MODE); + tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_LINK_POLARITY); udelay(40); if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) { - tw32(MAC_MODE, tp->mac_mode); - tr32(MAC_MODE); + tw32_f(MAC_MODE, tp->mac_mode); udelay(40); } } @@ -1702,14 +1981,14 @@ return 0; } -static int tg3_setup_phy(struct tg3 *tp) +static int tg3_setup_phy(struct tg3 *tp, int force_reset) { int err; if (tp->phy_id == PHY_ID_SERDES) { - err = tg3_setup_fiber_phy(tp); + err = tg3_setup_fiber_phy(tp, force_reset); } else { - err = tg3_setup_copper_phy(tp); + err = tg3_setup_copper_phy(tp, force_reset); } if (tp->link_config.active_speed == SPEED_1000 && @@ -1746,7 +2025,7 @@ pci_unmap_single(tp->pdev, pci_unmap_addr(ri, mapping), - (skb->len - skb->data_len), + skb_headlen(skb), PCI_DMA_TODEVICE); ri->skb = NULL; @@ -1917,7 +2196,7 @@ * Each TG3_BDINFO specifies a MAXLEN field and the first TG3_BDINFO * which is within the range of the new packet's length is chosen. * - * The "seperate ring for rx status" scheme may sound queer, but it makes + * The "separate ring for rx status" scheme may sound queer, but it makes * sense from a cache coherency perspective. If only the host writes * to the buffer post rings, and only the chip writes to the rx status * rings, then cache lines never move beyond shared-modified state. @@ -1932,7 +2211,7 @@ int received; hw_idx = tp->hw_status->idx[0].rx_producer; - sw_idx = rx_rcb_ptr % TG3_RX_RCB_RING_SIZE; + sw_idx = rx_rcb_ptr % TG3_RX_RCB_RING_SIZE(tp); work_mask = 0; received = 0; while (sw_idx != hw_idx && budget > 0) { @@ -2033,30 +2312,24 @@ (*post_ptr)++; next_pkt_nopost: rx_rcb_ptr++; - sw_idx = rx_rcb_ptr % TG3_RX_RCB_RING_SIZE; + sw_idx = rx_rcb_ptr % TG3_RX_RCB_RING_SIZE(tp); } /* ACK the status ring. */ tp->rx_rcb_ptr = rx_rcb_ptr; - tw32_mailbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, - (rx_rcb_ptr % TG3_RX_RCB_RING_SIZE)); - if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) - tr32(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW); + tw32_rx_mbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, + (rx_rcb_ptr % TG3_RX_RCB_RING_SIZE(tp))); /* Refill RX ring(s). */ if (work_mask & RXD_OPAQUE_RING_STD) { sw_idx = tp->rx_std_ptr % TG3_RX_RING_SIZE; - tw32_mailbox(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW, + tw32_rx_mbox(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW, sw_idx); - if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) - tr32(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW); } if (work_mask & RXD_OPAQUE_RING_JUMBO) { sw_idx = tp->rx_jumbo_ptr % TG3_RX_JUMBO_RING_SIZE; - tw32_mailbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW, + tw32_rx_mbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW, sw_idx); - if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) - tr32(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW); } return received; @@ -2078,7 +2351,7 @@ if (sblk->status & SD_STATUS_LINK_CHG) { sblk->status = SD_STATUS_UPDATED | (sblk->status & ~SD_STATUS_LINK_CHG); - tg3_setup_phy(tp); + tg3_setup_phy(tp, 0); } } @@ -2143,12 +2416,13 @@ return work_exists; } -static void tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct tg3 *tp = dev->priv; struct tg3_hw_status *sblk = tp->hw_status; unsigned long flags; + unsigned int handled = 1; spin_lock_irqsave(&tp->lock, flags); @@ -2179,12 +2453,15 @@ 0x00000000); tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); } + } else { /* shared interrupt */ + handled = 0; } spin_unlock_irqrestore(&tp->lock, flags); + + return IRQ_RETVAL(handled); } -static void tg3_init_rings(struct tg3 *); static int tg3_init_hw(struct tg3 *); static int tg3_halt(struct tg3 *); @@ -2202,7 +2479,6 @@ tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; tg3_halt(tp); - tg3_init_rings(tp); tg3_init_hw(tp); spin_unlock(&tp->tx_lock); @@ -2224,79 +2500,23 @@ 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; } - /* New SKB is guarenteed to be linear. */ + /* New SKB is guaranteed to be linear. */ entry = *start; new_addr = pci_map_single(tp->pdev, new_skb->data, new_skb->len, PCI_DMA_TODEVICE); @@ -2311,7 +2531,7 @@ int len; if (i == 0) - len = skb->len - skb->data_len; + len = skb_headlen(skb); else len = skb_shinfo(skb)->frags[i-1].size; pci_unmap_single(tp->pdev, @@ -2327,7 +2547,6 @@ } dev_kfree_skb(skb); -#endif return 0; } @@ -2396,7 +2615,7 @@ int would_hit_hwbug; unsigned long flags; - len = (skb->len - skb->data_len); + len = skb_headlen(skb); /* No BH disabling for tx_lock here. We are running in BH disabled * context and TX reclaim runs via tp->poll inside of a software @@ -2432,10 +2651,42 @@ base_flags = 0; if (skb->ip_summed == CHECKSUM_HW) base_flags |= TXD_FLAG_TCPUDP_CSUM; -#if TG3_DO_TSO != 0 - if ((mss = skb_shinfo(skb)->tso_size) != 0) +#if TG3_TSO_SUPPORT != 0 + mss = 0; + if (skb->len > (tp->dev->mtu + ETH_HLEN) && + (mss = skb_shinfo(skb)->tso_size) != 0) { + int tcp_opt_len, ip_tcp_len; + + tcp_opt_len = ((skb->h.th->doff - 5) * 4); + ip_tcp_len = (skb->nh.iph->ihl * 4) + sizeof(struct tcphdr); + base_flags |= (TXD_FLAG_CPU_PRE_DMA | TXD_FLAG_CPU_POST_DMA); + + skb->nh.iph->check = 0; + skb->nh.iph->tot_len = ntohs(mss + ip_tcp_len + tcp_opt_len); + skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr, + skb->nh.iph->daddr, + 0, IPPROTO_TCP, 0); + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + if (tcp_opt_len || skb->nh.iph->ihl > 5) { + int tsflags; + + tsflags = ((skb->nh.iph->ihl - 5) + + (tcp_opt_len >> 2)); + mss |= (tsflags << 11); + } + } else { + if (tcp_opt_len || skb->nh.iph->ihl > 5) { + int tsflags; + + tsflags = ((skb->nh.iph->ihl - 5) + + (tcp_opt_len >> 2)); + base_flags |= tsflags << 12; + } + } + } #else mss = 0; #endif @@ -2486,7 +2737,7 @@ } tg3_set_txd(tp, entry, mapping, len, - base_flags, (i == last) | (mss << 1)); + base_flags, (i == last)); entry = NEXT_TX(entry); } @@ -2504,7 +2755,7 @@ i = 0; while (entry != last_plus_one) { if (i == 0) - len = skb->len - skb->data_len; + len = skb_headlen(skb); else len = skb_shinfo(skb)->frags[i-1].size; @@ -2530,32 +2781,17 @@ /* Packets are ready, update Tx producer idx local and on card. */ if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) { - tw32_mailbox((MAILBOX_SNDHOST_PROD_IDX_0 + + tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry); - if (tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG) - tw32_mailbox((MAILBOX_SNDHOST_PROD_IDX_0 + - TG3_64BIT_REG_LOW), entry); - if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) - tr32(MAILBOX_SNDHOST_PROD_IDX_0 + - TG3_64BIT_REG_LOW); } else { /* First, make sure tg3 sees last descriptor fully * in SRAM. */ if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) - tr32(MAILBOX_SNDNIC_PROD_IDX_0 + - TG3_64BIT_REG_LOW); + tr32(MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW); - tw32_mailbox((MAILBOX_SNDNIC_PROD_IDX_0 + + tw32_tx_mbox((MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry); - if (tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG) - tw32_mailbox((MAILBOX_SNDNIC_PROD_IDX_0 + - TG3_64BIT_REG_LOW), entry); - - /* Now post the mailbox write itself. */ - if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) - tr32(MAILBOX_SNDNIC_PROD_IDX_0 + - TG3_64BIT_REG_LOW); } tp->tx_prod = entry; @@ -2577,7 +2813,7 @@ u32 len, entry, base_flags, mss; unsigned long flags; - len = (skb->len - skb->data_len); + len = skb_headlen(skb); /* No BH disabling for tx_lock here. We are running in BH disabled * context and TX reclaim runs via tp->poll inside of a software @@ -2613,10 +2849,42 @@ base_flags = 0; if (skb->ip_summed == CHECKSUM_HW) base_flags |= TXD_FLAG_TCPUDP_CSUM; -#if TG3_DO_TSO != 0 - if ((mss = skb_shinfo(skb)->tso_size) != 0) +#if TG3_TSO_SUPPORT != 0 + mss = 0; + if (skb->len > (tp->dev->mtu + ETH_HLEN) && + (mss = skb_shinfo(skb)->tso_size) != 0) { + int tcp_opt_len, ip_tcp_len; + + tcp_opt_len = ((skb->h.th->doff - 5) * 4); + ip_tcp_len = (skb->nh.iph->ihl * 4) + sizeof(struct tcphdr); + base_flags |= (TXD_FLAG_CPU_PRE_DMA | TXD_FLAG_CPU_POST_DMA); + + skb->nh.iph->check = 0; + skb->nh.iph->tot_len = ntohs(mss + ip_tcp_len + tcp_opt_len); + skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr, + skb->nh.iph->daddr, + 0, IPPROTO_TCP, 0); + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + if (tcp_opt_len || skb->nh.iph->ihl > 5) { + int tsflags; + + tsflags = ((skb->nh.iph->ihl - 5) + + (tcp_opt_len >> 2)); + mss |= (tsflags << 11); + } + } else { + if (tcp_opt_len || skb->nh.iph->ihl > 5) { + int tsflags; + + tsflags = ((skb->nh.iph->ihl - 5) + + (tcp_opt_len >> 2)); + base_flags |= tsflags << 12; + } + } + } #else mss = 0; #endif @@ -2656,7 +2924,7 @@ pci_unmap_addr_set(&tp->tx_buffers[entry], mapping, mapping); tg3_set_txd(tp, entry, mapping, len, - base_flags, (i == last) | (mss << 1)); + base_flags, (i == last)); entry = NEXT_TX(entry); } @@ -2668,11 +2936,8 @@ * the double-write bug tests. */ if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) { - tw32_mailbox((MAILBOX_SNDHOST_PROD_IDX_0 + + tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry); - if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) - tr32(MAILBOX_SNDHOST_PROD_IDX_0 + - TG3_64BIT_REG_LOW); } else { /* First, make sure tg3 sees last descriptor fully * in SRAM. @@ -2681,13 +2946,8 @@ tr32(MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW); - tw32_mailbox((MAILBOX_SNDNIC_PROD_IDX_0 + + tw32_tx_mbox((MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry); - - /* Now post the mailbox write itself. */ - if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) - tr32(MAILBOX_SNDNIC_PROD_IDX_0 + - TG3_64BIT_REG_LOW); } tp->tx_prod = entry; @@ -2716,7 +2976,7 @@ { struct tg3 *tp = dev->priv; - if (new_mtu < TG3_MIN_MTU || new_mtu > TG3_MAX_MTU) + if (new_mtu < TG3_MIN_MTU || new_mtu > TG3_MAX_MTU(tp)) return -EINVAL; if (!netif_running(dev)) { @@ -2735,7 +2995,6 @@ tg3_set_mtu(dev, tp, new_mtu); - tg3_init_rings(tp); tg3_init_hw(tp); spin_unlock(&tp->tx_lock); @@ -2798,7 +3057,7 @@ pci_unmap_single(tp->pdev, pci_unmap_addr(txp, mapping), - (skb->len - skb->data_len), + skb_headlen(skb), PCI_DMA_TODEVICE); txp->skb = NULL; @@ -2821,8 +3080,8 @@ * * 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. tp->{tx,}lock is not held and we are not - * in an interrupt context and thus may sleep. + * end up in the driver. tp->{tx,}lock are held and thus + * we may not sleep. */ static void tg3_init_rings(struct tg3 *tp) { @@ -2835,7 +3094,7 @@ /* Zero out all descriptors. */ memset(tp->rx_std, 0, TG3_RX_RING_BYTES); memset(tp->rx_jumbo, 0, TG3_RX_JUMBO_RING_BYTES); - memset(tp->rx_rcb, 0, TG3_RX_RCB_RING_BYTES); + memset(tp->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp)); if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) { memset(tp->tx_ring, 0, TG3_TX_RING_BYTES); @@ -2918,7 +3177,7 @@ tp->rx_jumbo = NULL; } if (tp->rx_rcb) { - pci_free_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES, + pci_free_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp), tp->rx_rcb, tp->rx_rcb_mapping); tp->rx_rcb = NULL; } @@ -2976,7 +3235,7 @@ if (!tp->rx_jumbo) goto err_out; - tp->rx_rcb = pci_alloc_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES, + tp->rx_rcb = pci_alloc_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp), &tp->rx_rcb_mapping); if (!tp->rx_rcb) goto err_out; @@ -3023,10 +3282,26 @@ unsigned int i; u32 val; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + switch (ofs) { + case RCVLSC_MODE: + case DMAC_MODE: + case MBFREE_MODE: + case BUFMGR_MODE: + case MEMARB_MODE: + /* We can't enable/disable these bits of the + * 5705, just say success. + */ + return 0; + + default: + break; + }; + } + val = tr32(ofs); val &= ~enable_bit; - tw32(ofs, val); - tr32(ofs); + tw32_f(ofs, val); for (i = 0; i < MAX_WAIT_CNT; i++) { udelay(100); @@ -3053,8 +3328,7 @@ tg3_disable_ints(tp); tp->rx_mode &= ~RX_MODE_ENABLE; - tw32(MAC_RX_MODE, tp->rx_mode); - tr32(MAC_RX_MODE); + tw32_f(MAC_RX_MODE, tp->rx_mode); udelay(10); err = tg3_stop_block(tp, RCVBDI_MODE, RCVBDI_MODE_ENABLE); @@ -3075,13 +3349,11 @@ goto out; tp->mac_mode &= ~MAC_MODE_TDE_ENABLE; - tw32(MAC_MODE, tp->mac_mode); - tr32(MAC_MODE); + tw32_f(MAC_MODE, tp->mac_mode); udelay(40); tp->tx_mode &= ~TX_MODE_ENABLE; - tw32(MAC_TX_MODE, tp->tx_mode); - tr32(MAC_TX_MODE); + tw32_f(MAC_TX_MODE, tp->tx_mode); for (i = 0; i < MAX_WAIT_CNT; i++) { udelay(100); @@ -3107,7 +3379,10 @@ if (err) goto out; - memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE); + if (tp->hw_status) + memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE); + if (tp->hw_stats) + memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats)); out: return err; @@ -3119,18 +3394,20 @@ u32 val; u32 flags_save; - /* Force NVRAM to settle. - * This deals with a chip bug which can result in EEPROM - * corruption. - */ - if (tp->tg3_flags & TG3_FLAG_NVRAM) { - int i; + if (!(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) { + /* Force NVRAM to settle. + * This deals with a chip bug which can result in EEPROM + * corruption. + */ + if (tp->tg3_flags & TG3_FLAG_NVRAM) { + int i; - tw32(NVRAM_SWARB, SWARB_REQ_SET1); - for (i = 0; i < 100000; i++) { - if (tr32(NVRAM_SWARB) & SWARB_GNT1) - break; - udelay(10); + tw32(NVRAM_SWARB, SWARB_REQ_SET1); + for (i = 0; i < 100000; i++) { + if (tr32(NVRAM_SWARB) & SWARB_GNT1) + break; + udelay(10); + } } } @@ -3144,7 +3421,10 @@ tp->tg3_flags &= ~TG3_FLAG_5701_REG_WRITE_BUG; /* do the reset */ - tw32(GRC_MISC_CFG, GRC_MISC_CFG_CORECLK_RESET); + val = GRC_MISC_CFG_CORECLK_RESET; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) + val |= GRC_MISC_CFG_KEEP_GPHY_POWER; + tw32(GRC_MISC_CFG, val); /* restore 5701 hardware bug workaround flag */ tp->tg3_flags = flags_save; @@ -3180,6 +3460,13 @@ tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); + if ((tp->nic_sram_data_cfg & NIC_SRAM_DATA_CFG_MINI_PCI) != 0 && + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + tp->pci_clock_ctrl |= + (CLOCK_CTRL_FORCE_CLKRUN | CLOCK_CTRL_CLKRUN_OENABLE); + tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl); + } + tw32(TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl); } @@ -3223,7 +3510,8 @@ udelay(10); } - if (i >= 100000) { + if (i >= 100000 && + !(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) { printk(KERN_ERR PFX "tg3_halt timed out for %s, " "firmware will not restart magic=%08x\n", tp->dev->name, val); @@ -3361,7 +3649,7 @@ 0x00000000 }; -#if 0 /* All zeros, dont eat up space with it. */ +#if 0 /* All zeros, don't eat up space with it. */ u32 tg3FwData[(TG3_FW_DATA_LEN / sizeof(u32)) + 1] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 @@ -3374,28 +3662,31 @@ #define TX_CPU_SCRATCH_SIZE 0x04000 /* tp->lock is held. */ -static int tg3_reset_cpu(struct tg3 *tp, u32 offset) +static int tg3_halt_cpu(struct tg3 *tp, u32 offset) { int i; - tw32(offset + CPU_STATE, 0xffffffff); - tw32(offset + CPU_MODE, CPU_MODE_RESET); + if (offset == TX_CPU_BASE && + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) + BUG(); + if (offset == RX_CPU_BASE) { - for (i = 0; i < 10000; i++) - if (!(tr32(offset + CPU_MODE) & CPU_MODE_RESET)) + for (i = 0; i < 10000; i++) { + tw32(offset + CPU_STATE, 0xffffffff); + tw32(offset + CPU_MODE, CPU_MODE_HALT); + if (tr32(offset + CPU_MODE) & CPU_MODE_HALT) break; + } + tw32(offset + CPU_STATE, 0xffffffff); - tw32(offset + CPU_MODE, CPU_MODE_RESET); - tr32(offset + CPU_MODE); + tw32_f(offset + CPU_MODE, CPU_MODE_HALT); udelay(10); } else { for (i = 0; i < 10000; i++) { - if (!(tr32(offset + CPU_MODE) & CPU_MODE_RESET)) - break; tw32(offset + CPU_STATE, 0xffffffff); - tw32(offset + CPU_MODE, CPU_MODE_RESET); - tr32(offset + CPU_MODE); - udelay(10); + tw32(offset + CPU_MODE, CPU_MODE_HALT); + if (tr32(offset + CPU_MODE) & CPU_MODE_HALT) + break; } } @@ -3427,38 +3718,52 @@ { int err, i; u32 orig_tg3_flags = tp->tg3_flags; + void (*write_op)(struct tg3 *, u32, u32); + + if (cpu_base == TX_CPU_BASE && + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + printk(KERN_ERR PFX "tg3_load_firmware_cpu: Trying to load " + "TX cpu firmware on %s which is 5705.\n", + tp->dev->name); + return -EINVAL; + } + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) + write_op = tg3_write_mem; + else + write_op = tg3_write_indirect_reg32; /* Force use of PCI config space for indirect register * write calls. */ tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG; - err = tg3_reset_cpu(tp, cpu_base); + err = tg3_halt_cpu(tp, cpu_base); if (err) goto out; for (i = 0; i < cpu_scratch_size; i += sizeof(u32)) - tg3_write_indirect_reg32(tp, cpu_scratch_base + i, 0); + write_op(tp, cpu_scratch_base + i, 0); tw32(cpu_base + CPU_STATE, 0xffffffff); tw32(cpu_base + CPU_MODE, tr32(cpu_base+CPU_MODE)|CPU_MODE_HALT); for (i = 0; i < (info->text_len / sizeof(u32)); i++) - tg3_write_indirect_reg32(tp, (cpu_scratch_base + - (info->text_base & 0xffff) + - (i * sizeof(u32))), - (info->text_data ? - info->text_data[i] : 0)); + write_op(tp, (cpu_scratch_base + + (info->text_base & 0xffff) + + (i * sizeof(u32))), + (info->text_data ? + info->text_data[i] : 0)); for (i = 0; i < (info->rodata_len / sizeof(u32)); i++) - tg3_write_indirect_reg32(tp, (cpu_scratch_base + - (info->rodata_base & 0xffff) + - (i * sizeof(u32))), - (info->rodata_data ? - info->rodata_data[i] : 0)); + write_op(tp, (cpu_scratch_base + + (info->rodata_base & 0xffff) + + (i * sizeof(u32))), + (info->rodata_data ? + info->rodata_data[i] : 0)); for (i = 0; i < (info->data_len / sizeof(u32)); i++) - tg3_write_indirect_reg32(tp, (cpu_scratch_base + - (info->data_base & 0xffff) + - (i * sizeof(u32))), - (info->data_data ? - info->data_data[i] : 0)); + write_op(tp, (cpu_scratch_base + + (info->data_base & 0xffff) + + (i * sizeof(u32))), + (info->data_data ? + info->data_data[i] : 0)); err = 0; @@ -3497,20 +3802,14 @@ /* Now startup only the RX cpu. */ tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff); - tw32(RX_CPU_BASE + CPU_PC, TG3_FW_TEXT_ADDR); + tw32_f(RX_CPU_BASE + CPU_PC, TG3_FW_TEXT_ADDR); - /* Flush posted writes. */ - tr32(RX_CPU_BASE + CPU_PC); for (i = 0; i < 5; i++) { if (tr32(RX_CPU_BASE + CPU_PC) == TG3_FW_TEXT_ADDR) break; tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff); tw32(RX_CPU_BASE + CPU_MODE, CPU_MODE_HALT); - tw32(RX_CPU_BASE + CPU_PC, TG3_FW_TEXT_ADDR); - - /* Flush posted writes. */ - tr32(RX_CPU_BASE + CPU_PC); - + tw32_f(RX_CPU_BASE + CPU_PC, TG3_FW_TEXT_ADDR); udelay(1000); } if (i >= 5) { @@ -3521,343 +3820,587 @@ return -ENODEV; } tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff); - tw32(RX_CPU_BASE + CPU_MODE, 0x00000000); - - /* Flush posted writes. */ - tr32(RX_CPU_BASE + CPU_MODE); + tw32_f(RX_CPU_BASE + CPU_MODE, 0x00000000); return 0; } -#if TG3_DO_TSO != 0 +#if TG3_TSO_SUPPORT != 0 #define TG3_TSO_FW_RELEASE_MAJOR 0x1 -#define TG3_TSO_FW_RELASE_MINOR 0x8 +#define TG3_TSO_FW_RELASE_MINOR 0x4 #define TG3_TSO_FW_RELEASE_FIX 0x0 #define TG3_TSO_FW_START_ADDR 0x08000000 #define TG3_TSO_FW_TEXT_ADDR 0x08000000 -#define TG3_TSO_FW_TEXT_LEN 0x1650 -#define TG3_TSO_FW_RODATA_ADDR 0x08001650 -#define TG3_TSO_FW_RODATA_LEN 0x30 -#define TG3_TSO_FW_DATA_ADDR 0x080016a0 +#define TG3_TSO_FW_TEXT_LEN 0x1a90 +#define TG3_TSO_FW_RODATA_ADDR 0x08001a900 +#define TG3_TSO_FW_RODATA_LEN 0x60 +#define TG3_TSO_FW_DATA_ADDR 0x08001b20 #define TG3_TSO_FW_DATA_LEN 0x20 -#define TG3_TSO_FW_SBSS_ADDR 0x080016c0 -#define TG3_TSO_FW_SBSS_LEN 0x14 -#define TG3_TSO_FW_BSS_ADDR 0x080016e0 -#define TG3_TSO_FW_BSS_LEN 0x8fc +#define TG3_TSO_FW_SBSS_ADDR 0x08001b40 +#define TG3_TSO_FW_SBSS_LEN 0x2c +#define TG3_TSO_FW_BSS_ADDR 0x08001b70 +#define TG3_TSO_FW_BSS_LEN 0x894 static u32 tg3TsoFwText[] = { 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c1d0800, 0x37bd4000, 0x03a0f021, 0x3c100800, 0x26100000, 0x0e000010, 0x00000000, - 0x0000000d, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe0, 0x3c1bc000, - 0xafbf0018, 0x0e000058, 0xaf60680c, 0x3c040800, 0x24841650, 0x03602821, - 0x24060001, 0x24070004, 0xafa00010, 0x0e00006c, 0xafa00014, 0x8f625c50, - 0x34420001, 0xaf625c50, 0x8f625c90, 0x34420001, 0xaf625c90, 0x2402ffff, - 0x0e000098, 0xaf625404, 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x00000000, - 0x00000000, 0x00000000, 0x24030b60, 0x24050fff, 0xac000b50, 0x00002021, - 0xac640000, 0x24630004, 0x0065102b, 0x1440fffc, 0x24840001, 0x24030b60, - 0x0065102b, 0x10400011, 0x00002021, 0x24090b54, 0x3c06dead, 0x34c6beef, - 0x24080b58, 0x24070b5c, 0x8c620000, 0x50440006, 0x24630004, 0xad260000, - 0x8c620000, 0xace40000, 0xad020000, 0x24630004, 0x0065102b, 0x1440fff6, - 0x24840001, 0x03e00008, 0x00000000, 0x27bdfff8, 0x18800009, 0x00002821, - 0x8f63680c, 0x8f62680c, 0x1043fffe, 0x00000000, 0x24a50001, 0x00a4102a, - 0x1440fff9, 0x00000000, 0x03e00008, 0x27bd0008, 0x3c020800, 0x34423000, - 0x3c030800, 0x34633000, 0x3c040800, 0x348437ff, 0x3c010800, 0xac2216c4, - 0x24020040, 0x3c010800, 0xac2216c8, 0x3c010800, 0xac2016c0, 0xac600000, - 0x24630004, 0x0083102b, 0x5040fffd, 0xac600000, 0x03e00008, 0x00000000, - 0x00804821, 0x8faa0010, 0x3c020800, 0x8c4216c0, 0x3c040800, 0x8c8416c8, - 0x8fab0014, 0x24430001, 0x0044102b, 0x3c010800, 0xac2316c0, 0x14400003, - 0x00004021, 0x3c010800, 0xac2016c0, 0x3c020800, 0x8c4216c0, 0x3c030800, - 0x8c6316c4, 0x91240000, 0x00021140, 0x00431021, 0x00481021, 0x25080001, - 0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, 0x3c020800, 0x8c4216c0, - 0x3c030800, 0x8c6316c4, 0x8f64680c, 0x00021140, 0x00431021, 0xac440008, - 0xac45000c, 0xac460010, 0xac470014, 0xac4a0018, 0x03e00008, 0xac4b001c, - 0x00000000, 0x00000000, 0x27bdffe0, 0xafbf0018, 0xafb10014, 0x0e0000b6, - 0xafb00010, 0x24110001, 0x8f706820, 0x32020100, 0x10400003, 0x00000000, - 0x0e000127, 0x00000000, 0x8f706820, 0x32022000, 0x10400004, 0x32020001, - 0x0e00025a, 0x24040001, 0x32020001, 0x10400003, 0x00000000, 0x0e0000e6, - 0x00000000, 0x0a00009e, 0xaf715028, 0x8fbf0018, 0x8fb10014, 0x8fb00010, - 0x03e00008, 0x27bd0020, 0x27bdffe0, 0x3c040800, 0x24841660, 0x00002821, - 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, 0x0e00006c, 0xafa00014, - 0x3c010800, 0xa4201fb8, 0x3c010800, 0xa02016f8, 0x3c010800, 0xac2016fc, - 0x3c010800, 0xac201700, 0x3c010800, 0xac201704, 0x3c010800, 0xac20170c, - 0x3c010800, 0xac201718, 0x3c010800, 0xac20171c, 0x8f624434, 0x3c010800, - 0xac2216e8, 0x8f624438, 0x3c010800, 0xac2216ec, 0x8f624410, 0x3c010800, - 0xac2016e0, 0x3c010800, 0xac2016e4, 0x3c010800, 0xac201fc0, 0x3c010800, - 0xac201f68, 0x3c010800, 0xac201f6c, 0x3c010800, 0xac2216f0, 0x8fbf0018, - 0x03e00008, 0x27bd0020, 0x27bdffe0, 0x3c040800, 0x2484166c, 0x00002821, - 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, 0x0e00006c, 0xafa00014, - 0x3c040800, 0x24841660, 0x00002821, 0x00003021, 0x00003821, 0xafa00010, - 0x0e00006c, 0xafa00014, 0x3c010800, 0xa4201fb8, 0x3c010800, 0xa02016f8, - 0x3c010800, 0xac2016fc, 0x3c010800, 0xac201700, 0x3c010800, 0xac201704, - 0x3c010800, 0xac20170c, 0x3c010800, 0xac201718, 0x3c010800, 0xac20171c, - 0x8f624434, 0x3c010800, 0xac2216e8, 0x8f624438, 0x3c010800, 0xac2216ec, - 0x8f624410, 0x3c010800, 0xac2016e0, 0x3c010800, 0xac2016e4, 0x3c010800, - 0xac201fc0, 0x3c010800, 0xac201f68, 0x3c010800, 0xac201f6c, 0x3c010800, - 0xac2216f0, 0x0e000120, 0x00002021, 0x8fbf0018, 0x03e00008, 0x27bd0020, + 0x0000000d, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe0, 0x3c04fefe, + 0xafbf0018, 0x0e0005d4, 0x34840002, 0x0e000664, 0x00000000, 0x3c030800, + 0x90631b58, 0x24020002, 0x3c040800, 0x24841a9c, 0x14620003, 0x24050001, + 0x3c040800, 0x24841a90, 0x24060003, 0x00003821, 0xafa00010, 0x0e000678, + 0xafa00014, 0x8f625c50, 0x34420001, 0xaf625c50, 0x8f625c90, 0x34420001, + 0xaf625c90, 0x2402ffff, 0x0e000034, 0xaf625404, 0x8fbf0018, 0x03e00008, + 0x27bd0020, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe0, 0xafbf001c, + 0xafb20018, 0xafb10014, 0x0e00005b, 0xafb00010, 0x24120002, 0x24110001, + 0x8f706820, 0x32020100, 0x10400003, 0x00000000, 0x0e0000bb, 0x00000000, + 0x8f706820, 0x32022000, 0x10400004, 0x32020001, 0x0e0001ef, 0x24040001, + 0x32020001, 0x10400003, 0x00000000, 0x0e0000a3, 0x00000000, 0x3c020800, + 0x90421b88, 0x14520003, 0x00000000, 0x0e0004bf, 0x00000000, 0x0a00003c, + 0xaf715028, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, + 0x27bd0020, 0x27bdffe0, 0x3c040800, 0x24841ab0, 0x00002821, 0x00003021, + 0x00003821, 0xafbf0018, 0xafa00010, 0x0e000678, 0xafa00014, 0x3c040800, + 0x248423c8, 0xa4800000, 0x3c010800, 0xa0201b88, 0x3c010800, 0xac201b8c, + 0x3c010800, 0xac201b90, 0x3c010800, 0xac201b94, 0x3c010800, 0xac201b9c, + 0x3c010800, 0xac201ba8, 0x3c010800, 0xac201bac, 0x8f624434, 0x3c010800, + 0xac221b78, 0x8f624438, 0x3c010800, 0xac221b7c, 0x8f624410, 0xac80f7a8, + 0x3c010800, 0xac201b74, 0x3c010800, 0xac2023d0, 0x3c010800, 0xac2023b8, + 0x3c010800, 0xac2023bc, 0x3c010800, 0xac2023f0, 0x3c010800, 0xac221b80, + 0x8f620068, 0x24030007, 0x00021702, 0x10430005, 0x00000000, 0x8f620068, + 0x00021702, 0x14400004, 0x24020001, 0x3c010800, 0x0a000097, 0xac2023fc, + 0xac820034, 0x3c040800, 0x24841abc, 0x3c050800, 0x8ca523fc, 0x00003021, + 0x00003821, 0xafa00010, 0x0e000678, 0xafa00014, 0x8fbf0018, 0x03e00008, + 0x27bd0020, 0x27bdffe0, 0x3c040800, 0x24841ac8, 0x00002821, 0x00003021, + 0x00003821, 0xafbf0018, 0xafa00010, 0x0e000678, 0xafa00014, 0x0e00005b, + 0x00000000, 0x0e0000b4, 0x00002021, 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x24020001, 0x8f636820, 0x00821004, 0x00021027, 0x00621824, 0x03e00008, - 0xaf636820, 0x27bdffd0, 0x3c0300ff, 0xafbf002c, 0xafb60028, 0xafb50024, - 0xafb40020, 0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, 0x8f665c5c, - 0x3c040800, 0x2484171c, 0x8c820000, 0x3463fff8, 0x14460005, 0x00c38824, - 0x3c020800, 0x904216f8, 0x14400115, 0x00000000, 0x00111902, 0x306300ff, - 0x30c20003, 0x000211c0, 0x00623825, 0x00e02821, 0x00061602, 0xac860000, - 0x3c030800, 0x906316f8, 0x3044000f, 0x1460002b, 0x00804021, 0x24020001, - 0x3c010800, 0xa02216f8, 0x00071100, 0x00821025, 0x3c010800, 0xac2016fc, - 0x3c010800, 0xac201700, 0x3c010800, 0xac201704, 0x3c010800, 0xac20170c, - 0x3c010800, 0xac201718, 0x3c010800, 0xac201710, 0x3c010800, 0xac201714, - 0x3c010800, 0xa4221fb8, 0x9623000c, 0x30628000, 0x10400008, 0x30627fff, - 0x2442003e, 0x3c010800, 0xa42216f6, 0x24020001, 0x3c010800, 0x0a00016e, - 0xac221fd4, 0x24620036, 0x3c010800, 0xa42216f6, 0x3c010800, 0xac201fd4, - 0x3c010800, 0xac201fd0, 0x3c010800, 0x0a000176, 0xac201fd8, 0x9622000c, - 0x3c010800, 0xa4221fcc, 0x3c040800, 0x248416fc, 0x8c820000, 0x00021100, - 0x3c010800, 0x00220821, 0xac311728, 0x8c820000, 0x00021100, 0x3c010800, - 0x00220821, 0xac26172c, 0x8c820000, 0x24a30001, 0x306701ff, 0x00021100, - 0x3c010800, 0x00220821, 0xac271730, 0x8c820000, 0x00021100, 0x3c010800, - 0x00220821, 0xac281734, 0x96230008, 0x3c020800, 0x8c42170c, 0x00432821, - 0x3c010800, 0xac25170c, 0x9622000a, 0x30420004, 0x14400019, 0x00071100, - 0x3c02c000, 0x00c21825, 0xaf635c5c, 0x8f625c50, 0x30420002, 0x1440fffc, - 0x00000000, 0x8f630c14, 0x3063000f, 0x2c620002, 0x1440001e, 0x00000000, - 0x8f630c14, 0x3c020800, 0x8c4216b4, 0x3063000f, 0x24420001, 0x3c010800, - 0xac2216b4, 0x2c620002, 0x1040fff7, 0x00000000, 0x0a0001c1, 0x00000000, - 0x3c030800, 0x8c6316e0, 0x3c040800, 0x948416f4, 0x01021025, 0x3c010800, - 0xa4221fba, 0x24020001, 0x3c010800, 0xac221718, 0x24630001, 0x0085202a, - 0x3c010800, 0x10800003, 0xac2316e0, 0x3c010800, 0xa42516f4, 0x3c030800, - 0x246316fc, 0x8c620000, 0x24420001, 0xac620000, 0x28420080, 0x14400005, - 0x24020001, 0x0e0002df, 0x24040002, 0x0a000250, 0x00000000, 0x3c030800, - 0x906316f8, 0x1462007c, 0x24020003, 0x3c160800, 0x96d616f6, 0x3c050800, - 0x8ca5170c, 0x32c4ffff, 0x00a4102a, 0x14400078, 0x00000000, 0x3c020800, - 0x8c421718, 0x10400005, 0x32c2ffff, 0x14a40003, 0x00000000, 0x3c010800, - 0xac231fd0, 0x10400062, 0x00009021, 0x0040a021, 0x3c150800, 0x26b51700, - 0x26b30010, 0x8ea20000, 0x00028100, 0x3c110800, 0x02308821, 0x0e0002e1, - 0x8e311728, 0x00403021, 0x10c00059, 0x00000000, 0x9628000a, 0x31020040, - 0x10400004, 0x2407180c, 0x8e22000c, 0x2407188c, 0xacc20018, 0x31021000, - 0x10400004, 0x34e32000, 0x00081040, 0x3042c000, 0x00623825, 0x3c030800, - 0x00701821, 0x8c631730, 0x3c020800, 0x00501021, 0x8c421734, 0x00031d00, - 0x00021400, 0x00621825, 0xacc30014, 0x8ea30004, 0x96220008, 0x00432023, - 0x3242ffff, 0x3083ffff, 0x00431021, 0x0282102a, 0x14400002, 0x02d22823, - 0x00802821, 0x8e620000, 0x30a4ffff, 0x00441021, 0xae620000, 0x8e220000, - 0xacc20000, 0x8e220004, 0x8e63fff4, 0x00431021, 0xacc20004, 0xa4c5000e, - 0x8e62fff4, 0x00441021, 0xae62fff4, 0x96230008, 0x0043102a, 0x14400005, - 0x02459021, 0x8e62fff0, 0xae60fff4, 0x24420001, 0xae62fff0, 0xacc00008, - 0x3242ffff, 0x14540008, 0x24020305, 0x31020080, 0x54400001, 0x34e70010, - 0x24020905, 0xa4c2000c, 0x0a000233, 0x34e70020, 0xa4c2000c, 0x30e2ffff, - 0xacc20010, 0x3c020800, 0x8c421fd0, 0x10400003, 0x3c024b65, 0x0a00023d, - 0x34427654, 0x3c02b49a, 0x344289ab, 0xacc2001c, 0x0e000560, 0x00c02021, - 0x3242ffff, 0x0054102b, 0x1440ffa4, 0x00000000, 0x24020002, 0x3c010800, - 0x0a000250, 0xa02216f8, 0x8ea208bc, 0x24420001, 0x0a000250, 0xaea208bc, - 0x14620003, 0x00000000, 0x0e000450, 0x00000000, 0x8fbf002c, 0x8fb60028, - 0x8fb50024, 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, - 0x03e00008, 0x27bd0030, 0x27bdffd8, 0xafb3001c, 0x00809821, 0xafbf0020, - 0xafb20018, 0xafb10014, 0xafb00010, 0x8f725c9c, 0x3c0200ff, 0x3442fff8, - 0x3c040800, 0x24841714, 0x02428824, 0x9623000e, 0x8c820000, 0x00431021, - 0xac820000, 0x8e220010, 0x30420020, 0x14400011, 0x00000000, 0x0e0002f7, + 0xaf636820, 0x27bdffd0, 0xafbf002c, 0xafb60028, 0xafb50024, 0xafb40020, + 0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, 0x8f675c5c, 0x3c030800, + 0x24631bac, 0x8c620000, 0x14470005, 0x3c0200ff, 0x3c020800, 0x90421b88, + 0x14400118, 0x3c0200ff, 0x3442fff8, 0x00e28824, 0xac670000, 0x00111902, + 0x306300ff, 0x30e20003, 0x000211c0, 0x00622825, 0x00a04021, 0x00071602, + 0x3c030800, 0x90631b88, 0x3044000f, 0x14600036, 0x00804821, 0x24020001, + 0x3c010800, 0xa0221b88, 0x00051100, 0x00821025, 0x3c010800, 0xac201b8c, + 0x3c010800, 0xac201b90, 0x3c010800, 0xac201b94, 0x3c010800, 0xac201b9c, + 0x3c010800, 0xac201ba8, 0x3c010800, 0xac201ba0, 0x3c010800, 0xac201ba4, + 0x3c010800, 0xa42223c8, 0x9622000c, 0x30437fff, 0x3c010800, 0xa4222400, + 0x30428000, 0x3c010800, 0xa4231bb6, 0x10400005, 0x24020001, 0x3c010800, + 0xac2223e4, 0x0a000102, 0x2406003e, 0x24060036, 0x3c010800, 0xac2023e4, + 0x9622000a, 0x3c030800, 0x94631bb6, 0x3c010800, 0xac2023e0, 0x3c010800, + 0xac2023e8, 0x00021302, 0x00021080, 0x00c21021, 0x00621821, 0x3c010800, + 0xa42223c0, 0x3c010800, 0x0a000115, 0xa4231b86, 0x9622000c, 0x3c010800, + 0xa42223dc, 0x3c040800, 0x24841b8c, 0x8c820000, 0x00021100, 0x3c010800, + 0x00220821, 0xac311bb8, 0x8c820000, 0x00021100, 0x3c010800, 0x00220821, + 0xac271bbc, 0x8c820000, 0x25030001, 0x306601ff, 0x00021100, 0x3c010800, + 0x00220821, 0xac261bc0, 0x8c820000, 0x00021100, 0x3c010800, 0x00220821, + 0xac291bc4, 0x96230008, 0x3c020800, 0x8c421b9c, 0x00432821, 0x3c010800, + 0xac251b9c, 0x9622000a, 0x30420004, 0x14400018, 0x00061100, 0x8f630c14, + 0x3063000f, 0x2c620002, 0x1440000b, 0x3c02c000, 0x8f630c14, 0x3c020800, + 0x8c421b30, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b30, 0x2c620002, + 0x1040fff7, 0x3c02c000, 0x00e21825, 0xaf635c5c, 0x8f625c50, 0x30420002, + 0x10400014, 0x00000000, 0x0a000147, 0x00000000, 0x3c030800, 0x8c631b70, + 0x3c040800, 0x94841b84, 0x01221025, 0x3c010800, 0xa42223ca, 0x24020001, + 0x3c010800, 0xac221ba8, 0x24630001, 0x0085202a, 0x3c010800, 0x10800003, + 0xac231b70, 0x3c010800, 0xa4251b84, 0x3c060800, 0x24c61b8c, 0x8cc20000, + 0x24420001, 0xacc20000, 0x28420080, 0x14400005, 0x00000000, 0x0e000652, + 0x24040002, 0x0a0001e5, 0x00000000, 0x3c020800, 0x8c421ba8, 0x10400077, + 0x24020001, 0x3c050800, 0x90a51b88, 0x14a20071, 0x00000000, 0x3c150800, + 0x96b51b86, 0x3c040800, 0x8c841b9c, 0x32a3ffff, 0x0083102a, 0x1440006b, + 0x00000000, 0x14830003, 0x00000000, 0x3c010800, 0xac2523e0, 0x1060005b, + 0x00009021, 0x24d60004, 0x0060a021, 0x24d30014, 0x8ec20000, 0x00028100, + 0x3c110800, 0x02308821, 0x0e000621, 0x8e311bb8, 0x00402821, 0x10a00053, + 0x00000000, 0x9628000a, 0x31020040, 0x10400004, 0x2407180c, 0x8e22000c, + 0x2407188c, 0xaca20018, 0x3c030800, 0x00701821, 0x8c631bc0, 0x3c020800, + 0x00501021, 0x8c421bc4, 0x00031d00, 0x00021400, 0x00621825, 0xaca30014, + 0x8ec30004, 0x96220008, 0x00432023, 0x3242ffff, 0x3083ffff, 0x00431021, + 0x0282102a, 0x14400002, 0x02b23023, 0x00803021, 0x8e620000, 0x30c4ffff, + 0x00441021, 0xae620000, 0x8e220000, 0xaca20000, 0x8e220004, 0x8e63fff4, + 0x00431021, 0xaca20004, 0xa4a6000e, 0x8e62fff4, 0x00441021, 0xae62fff4, + 0x96230008, 0x0043102a, 0x14400005, 0x02469021, 0x8e62fff0, 0xae60fff4, + 0x24420001, 0xae62fff0, 0xaca00008, 0x3242ffff, 0x14540008, 0x24020305, + 0x31020080, 0x54400001, 0x34e70010, 0x24020905, 0xa4a2000c, 0x0a0001ca, + 0x34e70020, 0xa4a2000c, 0x3c020800, 0x8c4223e0, 0x10400003, 0x3c024b65, + 0x0a0001d2, 0x34427654, 0x3c02b49a, 0x344289ab, 0xaca2001c, 0x30e2ffff, + 0xaca20010, 0x0e00059f, 0x00a02021, 0x3242ffff, 0x0054102b, 0x1440ffaa, + 0x00000000, 0x24020002, 0x3c010800, 0x0a0001e5, 0xa0221b88, 0x8ec2083c, + 0x24420001, 0x0a0001e5, 0xaec2083c, 0x0e0004bf, 0x00000000, 0x8fbf002c, + 0x8fb60028, 0x8fb50024, 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, + 0x8fb00010, 0x03e00008, 0x27bd0030, 0x27bdffd0, 0xafbf0028, 0xafb30024, + 0xafb20020, 0xafb1001c, 0xafb00018, 0x8f725c9c, 0x3c0200ff, 0x3442fff8, + 0x3c060800, 0x24c61ba4, 0x02428824, 0x9623000e, 0x8cc20000, 0x00431021, + 0xacc20000, 0x8e220010, 0x30420020, 0x14400011, 0x00809821, 0x0e000637, 0x02202021, 0x3c02c000, 0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002, - 0x10400061, 0x00000000, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x1040005c, - 0x00000000, 0x0a000278, 0x00000000, 0x8e220008, 0x00021c02, 0x000321c0, - 0x3042ffff, 0x3c030800, 0x906316f8, 0x000229c0, 0x24020002, 0x14620003, - 0x3c034b65, 0x0a000290, 0x00008021, 0x8e22001c, 0x34637654, 0x10430002, - 0x24100002, 0x24100001, 0x0e000300, 0x02003021, 0x24020003, 0x3c010800, - 0xa02216f8, 0x24020002, 0x1202000a, 0x24020001, 0x3c030800, 0x8c631fd0, - 0x10620006, 0x00000000, 0x3c020800, 0x94421fb8, 0x00021400, 0x0a0002cd, - 0xae220014, 0x3c040800, 0x24841fba, 0x94820000, 0x00021400, 0xae220014, - 0x3c020800, 0x8c42171c, 0x3c03c000, 0x3c010800, 0xa02016f8, 0x00431025, - 0xaf625c5c, 0x8f625c50, 0x30420002, 0x10400009, 0x00000000, 0x2484f762, + 0x10400121, 0x00000000, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x1040011c, + 0x00000000, 0x0a00020c, 0x00000000, 0x8e240008, 0x8e230014, 0x00041402, + 0x000241c0, 0x00031502, 0x304201ff, 0x2442ffff, 0x3042007f, 0x00031942, + 0x30637800, 0x00021100, 0x24424000, 0x00625021, 0x9542000a, 0x3084ffff, + 0x30420008, 0x104000b3, 0x000429c0, 0x3c020800, 0x8c4223f0, 0x1440002d, + 0x25050008, 0x95020014, 0x3c010800, 0xa42223c0, 0x8d070010, 0x00071402, + 0x3c010800, 0xa42223c2, 0x3c010800, 0xa42723c4, 0x9502000e, 0x30e3ffff, + 0x00431023, 0x3c010800, 0xac2223f8, 0x8f626800, 0x3c030010, 0x00431024, + 0x10400005, 0x00000000, 0x9503001a, 0x9502001c, 0x0a000241, 0x00431021, + 0x9502001a, 0x3c010800, 0xac2223ec, 0x3c02c000, 0x02421825, 0x3c010800, + 0xac2823f0, 0x3c010800, 0xac3223f4, 0xaf635c9c, 0x8f625c90, 0x30420002, + 0x104000df, 0x00000000, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x104000da, + 0x00000000, 0x0a00024e, 0x00000000, 0x9502000e, 0x3c030800, 0x946323c4, + 0x00434823, 0x3123ffff, 0x2c620008, 0x1040001c, 0x00000000, 0x95020014, + 0x24420028, 0x00a22821, 0x00031042, 0x1840000b, 0x00002021, 0x24c60848, + 0x00403821, 0x94a30000, 0x8cc20000, 0x24840001, 0x00431021, 0xacc20000, + 0x0087102a, 0x1440fff9, 0x24a50002, 0x31220001, 0x1040001f, 0x3c024000, + 0x3c040800, 0x248423ec, 0xa0a00001, 0x94a30000, 0x8c820000, 0x00431021, + 0x0a00028d, 0xac820000, 0x8f626800, 0x3c030010, 0x00431024, 0x10400009, + 0x00000000, 0x9502001a, 0x3c030800, 0x8c6323ec, 0x00431021, 0x3c010800, + 0xac2223ec, 0x0a00028e, 0x3c024000, 0x9502001a, 0x9504001c, 0x3c030800, + 0x8c6323ec, 0x00441023, 0x00621821, 0x3c010800, 0xac2323ec, 0x3c024000, + 0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x1440fffc, 0x00000000, + 0x9542000a, 0x30420010, 0x10400095, 0x00000000, 0x3c060800, 0x24c623f0, + 0x3c020800, 0x944223c4, 0x8cc50000, 0x3c040800, 0x8c8423f8, 0x24420030, + 0x00a22821, 0x94a20004, 0x3c030800, 0x8c6323ec, 0x00441023, 0x00621821, + 0x00603821, 0x00032402, 0x30e2ffff, 0x00823821, 0x00071402, 0x00e23821, + 0x00071027, 0x3c010800, 0xac2323ec, 0xa4a20006, 0x3c030800, 0x8c6323f4, + 0x3c0200ff, 0x3442fff8, 0x00628824, 0x96220008, 0x24040001, 0x24034000, + 0x000241c0, 0x00e01021, 0xa502001a, 0xa500001c, 0xacc00000, 0x3c010800, + 0xac241b50, 0xaf635cb8, 0x8f625cb0, 0x30420002, 0x10400003, 0x00000000, + 0x3c010800, 0xac201b50, 0x8e220008, 0xaf625cb8, 0x8f625cb0, 0x30420002, + 0x10400003, 0x00000000, 0x3c010800, 0xac201b50, 0x3c020800, 0x8c421b50, + 0x1040ffec, 0x00000000, 0x3c040800, 0x0e000637, 0x8c8423f4, 0x0a00032c, + 0x00000000, 0x3c030800, 0x90631b88, 0x24020002, 0x14620003, 0x3c034b65, + 0x0a0002e3, 0x00008021, 0x8e22001c, 0x34637654, 0x10430002, 0x24100002, + 0x24100001, 0x01002021, 0x0e000352, 0x02003021, 0x24020003, 0x3c010800, + 0xa0221b88, 0x24020002, 0x1202000a, 0x24020001, 0x3c030800, 0x8c6323e0, + 0x10620006, 0x00000000, 0x3c020800, 0x944223c8, 0x00021400, 0x0a000321, + 0xae220014, 0x3c040800, 0x248423ca, 0x94820000, 0x00021400, 0xae220014, + 0x3c020800, 0x8c421bac, 0x3c03c000, 0x3c010800, 0xa0201b88, 0x00431025, + 0xaf625c5c, 0x8f625c50, 0x30420002, 0x10400009, 0x00000000, 0x2484f7e2, 0x8c820000, 0x00431025, 0xaf625c5c, 0x8f625c50, 0x30420002, 0x1440fffa, - 0x00000000, 0x3c020800, 0x244216e4, 0x8c430000, 0x24630001, 0xac430000, - 0x8f630c14, 0x3063000f, 0x2c620002, 0x1440000b, 0x00009821, 0x8f630c14, - 0x3c020800, 0x8c4216b4, 0x3063000f, 0x24420001, 0x3c010800, 0xac2216b4, - 0x2c620002, 0x1040fff7, 0x00009821, 0x3c024000, 0x02421825, 0xaf635c9c, + 0x00000000, 0x3c020800, 0x24421b74, 0x8c430000, 0x24630001, 0xac430000, + 0x8f630c14, 0x3063000f, 0x2c620002, 0x1440000c, 0x3c024000, 0x8f630c14, + 0x3c020800, 0x8c421b30, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b30, + 0x2c620002, 0x1040fff7, 0x00000000, 0x3c024000, 0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x1440fffc, 0x00000000, 0x12600003, 0x00000000, - 0x0e000450, 0x00000000, 0x8fbf0020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, - 0x8fb00010, 0x03e00008, 0x27bd0028, 0x0a0002df, 0x00000000, 0x8f634450, - 0x3c040800, 0x248416e8, 0x8c820000, 0x00031c02, 0x0043102b, 0x14400007, - 0x3c038000, 0x8c840004, 0x8f624450, 0x00021c02, 0x0083102b, 0x1040fffc, - 0x3c038000, 0xaf634444, 0x8f624444, 0x00431024, 0x1440fffd, 0x00000000, - 0x8f624448, 0x03e00008, 0x3042ffff, 0x3c024000, 0x00822025, 0xaf645c38, - 0x8f625c30, 0x30420002, 0x1440fffc, 0x00000000, 0x03e00008, 0x00000000, - 0x27bdffe0, 0x00805021, 0x14c00017, 0x254c0008, 0x3c020800, 0x8c421fd4, - 0x1040000a, 0x2402003e, 0x3c010800, 0xa4221fb0, 0x24020016, 0x3c010800, - 0xa4221fb2, 0x2402002a, 0x3c010800, 0x0a00031a, 0xa4221fb4, 0x95420014, - 0x3c010800, 0xa4221fb0, 0x8d430010, 0x00031402, 0x3c010800, 0xa4221fb2, - 0x3c010800, 0xa4231fb4, 0x3c040800, 0x94841fb4, 0x3c030800, 0x94631fb2, - 0x958d0006, 0x3c020800, 0x94421fb0, 0x00832023, 0x01a27023, 0x3065ffff, - 0x24a20028, 0x01824021, 0x3082ffff, 0x14c0001a, 0x01025821, 0x9562000c, - 0x3042003f, 0x3c010800, 0xa4221fb6, 0x95620004, 0x95630006, 0x3c010800, - 0xac201fc4, 0x3c010800, 0xac201fc8, 0x00021400, 0x00431025, 0x3c010800, - 0xac221720, 0x95020004, 0x3c010800, 0xa4221724, 0x95030002, 0x01a51023, - 0x0043102a, 0x10400010, 0x24020001, 0x3c010800, 0x0a00034e, 0xac221fd8, - 0x3c030800, 0x8c631fc8, 0x3c020800, 0x94421724, 0x00431021, 0xa5020004, - 0x3c020800, 0x94421720, 0xa5620004, 0x3c020800, 0x8c421720, 0xa5620006, - 0x3c020800, 0x8c421fd0, 0x3c070800, 0x8ce71fc4, 0x3c050800, 0x144000c7, - 0x8ca51fc8, 0x3c020800, 0x94421724, 0x00451821, 0x3063ffff, 0x0062182b, - 0x24020002, 0x10c2000d, 0x00a32823, 0x3c020800, 0x94421fb6, 0x30420009, - 0x10400008, 0x00000000, 0x9562000c, 0x3042fff6, 0xa562000c, 0x3c020800, - 0x94421fb6, 0x30420009, 0x00e23823, 0x3c020800, 0x8c421fd8, 0x1040004b, - 0x24020002, 0x01003021, 0x3c020800, 0x94421fb2, 0x00003821, 0xa500000a, - 0x01a21023, 0xa5020002, 0x3082ffff, 0x00021042, 0x18400008, 0x00002821, - 0x00401821, 0x94c20000, 0x24e70001, 0x00a22821, 0x00e3102a, 0x1440fffb, - 0x24c60002, 0x00051c02, 0x30a2ffff, 0x00622821, 0x00051402, 0x00a22821, - 0x00a04821, 0x00051027, 0xa502000a, 0x00002821, 0x2506000c, 0x00003821, - 0x94c20000, 0x24e70001, 0x00a22821, 0x2ce20004, 0x1440fffb, 0x24c60002, - 0x95020002, 0x00003821, 0x91030009, 0x00442023, 0x01603021, 0x3082ffff, - 0xa4c00010, 0x00621821, 0x00021042, 0x18400010, 0x00a32821, 0x00404021, - 0x94c20000, 0x24c60002, 0x00a22821, 0x30c2007f, 0x14400006, 0x24e70001, - 0x8d430000, 0x3c02007f, 0x3442ff80, 0x00625024, 0x25460008, 0x00e8102a, - 0x1440fff3, 0x00000000, 0x30820001, 0x10400005, 0x00051c02, 0xa0c00001, - 0x94c20000, 0x00a22821, 0x00051c02, 0x30a2ffff, 0x00622821, 0x00051402, - 0x00a22821, 0x0a000415, 0x30a5ffff, 0x14c20063, 0x00000000, 0x3c090800, - 0x95291fb2, 0x95030002, 0x01a91023, 0x1062005d, 0x01003021, 0x00003821, - 0x00002821, 0x01a91023, 0xa5020002, 0x3082ffff, 0x00021042, 0x18400008, - 0xa500000a, 0x00401821, 0x94c20000, 0x24e70001, 0x00a22821, 0x00e3102a, - 0x1440fffb, 0x24c60002, 0x00051c02, 0x30a2ffff, 0x00622821, 0x00051402, - 0x00a22821, 0x00a04821, 0x00051027, 0xa502000a, 0x00002821, 0x2506000c, - 0x00003821, 0x94c20000, 0x24e70001, 0x00a22821, 0x2ce20004, 0x1440fffb, - 0x24c60002, 0x95020002, 0x00003821, 0x91030009, 0x00442023, 0x01603021, - 0x3082ffff, 0xa4c00010, 0x3c040800, 0x94841fb4, 0x00621821, 0x00a32821, - 0x00051c02, 0x30a2ffff, 0x00622821, 0x00051c02, 0x3c020800, 0x94421fb0, - 0x00a34021, 0x00441023, 0x00021fc2, 0x00431021, 0x00021043, 0x18400010, - 0x00002821, 0x00402021, 0x94c20000, 0x24c60002, 0x00a22821, 0x30c2007f, - 0x14400006, 0x24e70001, 0x8d430000, 0x3c02007f, 0x3442ff80, 0x00625024, - 0x25460008, 0x00e4102a, 0x1440fff3, 0x00000000, 0x3c020800, 0x94421fcc, - 0x00a22821, 0x00051c02, 0x30a2ffff, 0x00622821, 0x00051402, 0x00a22821, - 0x3102ffff, 0x00a22821, 0x00051c02, 0x30a2ffff, 0x00622821, 0x00051402, - 0x00a22821, 0x00a02021, 0x00051027, 0xa5620010, 0xad800014, 0x0a000435, - 0xad800000, 0x8d830010, 0x00602021, 0x10a00007, 0x00034c02, 0x01252821, - 0x00051402, 0x30a3ffff, 0x00432821, 0x00051402, 0x00a24821, 0x00091027, - 0xa502000a, 0x3c030800, 0x94631fb4, 0x3082ffff, 0x01a21021, 0x00432823, - 0x00a72821, 0x00051c02, 0x30a2ffff, 0x00622821, 0x00051402, 0x00a22821, - 0x00a02021, 0x00051027, 0xa5620010, 0x3082ffff, 0x00091c00, 0x00431025, - 0xad820010, 0x3c020800, 0x8c421fd4, 0x10400002, 0x25a2fff2, 0xa5820034, - 0x3c020800, 0x8c421fc8, 0x3c030800, 0x8c631720, 0x24420001, 0x3c010800, - 0xac221fc8, 0x3c020800, 0x8c421fc4, 0x31c4ffff, 0x00641821, 0x3c010800, - 0xac231720, 0x00441021, 0x3c010800, 0xac221fc4, 0x03e00008, 0x27bd0020, - 0x27bdffc8, 0x3c040800, 0x248416f8, 0xafbf0034, 0xafbe0030, 0xafb7002c, - 0xafb60028, 0xafb50024, 0xafb40020, 0xafb3001c, 0xafb20018, 0xafb10014, - 0xafb00010, 0x90830000, 0x24020003, 0x146200f4, 0x00000000, 0x3c020800, - 0x8c421710, 0x3c030800, 0x8c63170c, 0x3c1e0800, 0x97de16f6, 0x0043102a, - 0x104000eb, 0x3c168000, 0x249708c4, 0x33d5ffff, 0x24920018, 0x3c020800, - 0x8c421718, 0x104000e4, 0x00000000, 0x3c140800, 0x96941fb0, 0x3282ffff, - 0x104000d6, 0x00008021, 0x00409821, 0x00008821, 0x8f634450, 0x3c020800, - 0x8c4216e8, 0x00031c02, 0x0043102b, 0x14400008, 0x00000000, 0x3c040800, - 0x8c8416ec, 0x8f624450, 0x00021c02, 0x0083102b, 0x1040fffc, 0x00000000, - 0xaf764444, 0x8f624444, 0x00561024, 0x10400006, 0x00000000, 0x3c038000, - 0x8f624444, 0x00431024, 0x1440fffd, 0x00000000, 0x8f624448, 0x3046ffff, - 0x10c0005f, 0x00000000, 0x3c090800, 0x01314821, 0x8d291728, 0x9528000a, - 0x31020040, 0x10400004, 0x2407180c, 0x8d22000c, 0x2407188c, 0xacc20018, - 0x31021000, 0x10400004, 0x34e32000, 0x00081040, 0x3042c000, 0x00623825, - 0x31020080, 0x54400001, 0x34e70010, 0x3c020800, 0x00511021, 0x8c421730, - 0x3c030800, 0x00711821, 0x8c631734, 0x00021500, 0x00031c00, 0x00431025, - 0xacc20014, 0x95240008, 0x3202ffff, 0x00821021, 0x0262102a, 0x14400002, - 0x02902823, 0x00802821, 0x8d220000, 0x02058021, 0xacc20000, 0x8d220004, - 0x00c02021, 0x26310010, 0xac820004, 0x30e2ffff, 0xac800008, 0xa485000e, - 0xac820010, 0x24020305, 0x0e000560, 0xa482000c, 0x3202ffff, 0x0053102b, - 0x1440ffaf, 0x3202ffff, 0x0a00054c, 0x00000000, 0x8e420000, 0x8e43fffc, - 0x0043102a, 0x10400084, 0x00000000, 0x8e45fff0, 0x8f644450, 0x3c030800, - 0x8c6316e8, 0x00051100, 0x3c090800, 0x01224821, 0x8d291728, 0x00041402, - 0x0062182b, 0x14600008, 0x00000000, 0x3c030800, 0x8c6316ec, 0x8f624450, - 0x00021402, 0x0062102b, 0x1040fffc, 0x00000000, 0xaf764444, 0x8f624444, - 0x00561024, 0x10400006, 0x00000000, 0x3c038000, 0x8f624444, 0x00431024, - 0x1440fffd, 0x00000000, 0x8f624448, 0x3046ffff, 0x14c00005, 0x00000000, - 0x8ee20000, 0x24420001, 0x0a000554, 0xaee20000, 0x9528000a, 0x31020040, - 0x10400004, 0x2407180c, 0x8d22000c, 0x2407188c, 0xacc20018, 0x31021000, - 0x10400004, 0x34e32000, 0x00081040, 0x3042c000, 0x00623825, 0x00051900, - 0x3c020800, 0x00431021, 0x8c421730, 0x3c010800, 0x00230821, 0x8c231734, - 0x00021500, 0x00031c00, 0x00431025, 0xacc20014, 0x3c030800, 0x8c631704, - 0x95220008, 0x00432023, 0x3202ffff, 0x3083ffff, 0x00431021, 0x02a2102a, - 0x14400002, 0x03d02823, 0x00802821, 0x8e420000, 0x30a4ffff, 0x00441021, - 0xae420000, 0xa4c5000e, 0x8d220000, 0xacc20000, 0x8d220004, 0x8e43fff4, - 0x00431021, 0xacc20004, 0x8e43fff4, 0x95220008, 0x00641821, 0x0062102a, - 0x14400006, 0x02058021, 0x8e42fff0, 0xae40fff4, 0x24420001, 0x0a000530, - 0xae42fff0, 0xae43fff4, 0xacc00008, 0x3202ffff, 0x10550003, 0x31020004, - 0x10400006, 0x24020305, 0x31020080, 0x54400001, 0x34e70010, 0x34e70020, - 0x24020905, 0xa4c2000c, 0x30e2ffff, 0xacc20010, 0x3c030800, 0x8c63170c, - 0x3c020800, 0x8c421710, 0x54620004, 0x3c02b49a, 0x3c024b65, 0x0a000548, - 0x34427654, 0x344289ab, 0xacc2001c, 0x0e000560, 0x00c02021, 0x3202ffff, - 0x0055102b, 0x1440ff7e, 0x00000000, 0x8e420000, 0x8e43fffc, 0x0043102a, - 0x1440ff1a, 0x00000000, 0x8fbf0034, 0x8fbe0030, 0x8fb7002c, 0x8fb60028, - 0x8fb50024, 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, - 0x03e00008, 0x27bd0038, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x8f624450, - 0x8f634410, 0x0a00056f, 0x00808021, 0x8f626820, 0x30422000, 0x10400003, - 0x00000000, 0x0e00025a, 0x00002021, 0x8f624450, 0x8f634410, 0x3042ffff, - 0x0043102b, 0x1440fff5, 0x00000000, 0x8f630c14, 0x3063000f, 0x2c620002, - 0x1440000b, 0x00000000, 0x8f630c14, 0x3c020800, 0x8c4216b4, 0x3063000f, - 0x24420001, 0x3c010800, 0xac2216b4, 0x2c620002, 0x1040fff7, 0x00000000, - 0xaf705c18, 0x8f625c10, 0x30420002, 0x10400009, 0x00000000, 0x8f626820, - 0x30422000, 0x1040fff8, 0x00000000, 0x0e00025a, 0x00002021, 0x0a000582, - 0x00000000, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x00000000, - 0x00000000 + 0x0e0004bf, 0x00000000, 0x8fbf0028, 0x8fb30024, 0x8fb20020, 0x8fb1001c, + 0x8fb00018, 0x03e00008, 0x27bd0030, 0x8f634450, 0x3c040800, 0x24841b78, + 0x8c820000, 0x00031c02, 0x0043102b, 0x14400007, 0x3c038000, 0x8c840004, + 0x8f624450, 0x00021c02, 0x0083102b, 0x1040fffc, 0x3c038000, 0xaf634444, + 0x8f624444, 0x00431024, 0x1440fffd, 0x00000000, 0x8f624448, 0x03e00008, + 0x3042ffff, 0x3c024000, 0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002, + 0x1440fffc, 0x00000000, 0x03e00008, 0x00000000, 0x27bdffe0, 0x00805821, + 0x14c00011, 0x256e0008, 0x3c020800, 0x8c4223e4, 0x10400007, 0x24020016, + 0x3c010800, 0xa42223c2, 0x2402002a, 0x3c010800, 0x0a000366, 0xa42223c4, + 0x8d670010, 0x00071402, 0x3c010800, 0xa42223c2, 0x3c010800, 0xa42723c4, + 0x3c040800, 0x948423c4, 0x3c030800, 0x946323c2, 0x95cf0006, 0x3c020800, + 0x944223c0, 0x00832023, 0x01e2c023, 0x3065ffff, 0x24a20028, 0x01c24821, + 0x3082ffff, 0x14c0001a, 0x01226021, 0x9582000c, 0x3042003f, 0x3c010800, + 0xa42223c6, 0x95820004, 0x95830006, 0x3c010800, 0xac2023d4, 0x3c010800, + 0xac2023d8, 0x00021400, 0x00431025, 0x3c010800, 0xac221bb0, 0x95220004, + 0x3c010800, 0xa4221bb4, 0x95230002, 0x01e51023, 0x0043102a, 0x10400010, + 0x24020001, 0x3c010800, 0x0a00039a, 0xac2223e8, 0x3c030800, 0x8c6323d8, + 0x3c020800, 0x94421bb4, 0x00431021, 0xa5220004, 0x3c020800, 0x94421bb0, + 0xa5820004, 0x3c020800, 0x8c421bb0, 0xa5820006, 0x3c020800, 0x8c4223e0, + 0x3c0d0800, 0x8dad23d4, 0x3c0a0800, 0x144000e5, 0x8d4a23d8, 0x3c020800, + 0x94421bb4, 0x004a1821, 0x3063ffff, 0x0062182b, 0x24020002, 0x10c2000d, + 0x01435023, 0x3c020800, 0x944223c6, 0x30420009, 0x10400008, 0x00000000, + 0x9582000c, 0x3042fff6, 0xa582000c, 0x3c020800, 0x944223c6, 0x30420009, + 0x01a26823, 0x3c020800, 0x8c4223e8, 0x1040004a, 0x01203821, 0x3c020800, + 0x944223c2, 0x00004021, 0xa520000a, 0x01e21023, 0xa5220002, 0x3082ffff, + 0x00021042, 0x18400008, 0x00003021, 0x00401821, 0x94e20000, 0x25080001, + 0x00c23021, 0x0103102a, 0x1440fffb, 0x24e70002, 0x00061c02, 0x30c2ffff, + 0x00623021, 0x00061402, 0x00c23021, 0x00c02821, 0x00061027, 0xa522000a, + 0x00003021, 0x2527000c, 0x00004021, 0x94e20000, 0x25080001, 0x00c23021, + 0x2d020004, 0x1440fffb, 0x24e70002, 0x95220002, 0x00004021, 0x91230009, + 0x00442023, 0x01803821, 0x3082ffff, 0xa4e00010, 0x00621821, 0x00021042, + 0x18400010, 0x00c33021, 0x00404821, 0x94e20000, 0x24e70002, 0x00c23021, + 0x30e2007f, 0x14400006, 0x25080001, 0x8d630000, 0x3c02007f, 0x3442ff80, + 0x00625824, 0x25670008, 0x0109102a, 0x1440fff3, 0x00000000, 0x30820001, + 0x10400005, 0x00061c02, 0xa0e00001, 0x94e20000, 0x00c23021, 0x00061c02, + 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x0a00047f, 0x30c6ffff, + 0x24020002, 0x14c20081, 0x00000000, 0x3c020800, 0x8c4223fc, 0x14400007, + 0x00000000, 0x3c020800, 0x944223c2, 0x95230002, 0x01e21023, 0x10620077, + 0x00000000, 0x3c020800, 0x944223c2, 0x01e21023, 0xa5220002, 0x3c020800, + 0x8c4223fc, 0x1040001a, 0x31e3ffff, 0x8dc70010, 0x3c020800, 0x94421b86, + 0x00e04021, 0x00072c02, 0x00aa2021, 0x00431023, 0x00823823, 0x00072402, + 0x30e2ffff, 0x00823821, 0x00071027, 0xa522000a, 0x3102ffff, 0x3c040800, + 0x948423c4, 0x00453023, 0x00e02821, 0x00641823, 0x006d1821, 0x00c33021, + 0x00061c02, 0x30c2ffff, 0x0a00047f, 0x00623021, 0x01203821, 0x00004021, + 0x3082ffff, 0x00021042, 0x18400008, 0x00003021, 0x00401821, 0x94e20000, + 0x25080001, 0x00c23021, 0x0103102a, 0x1440fffb, 0x24e70002, 0x00061c02, + 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x00c02821, 0x00061027, + 0xa522000a, 0x00003021, 0x2527000c, 0x00004021, 0x94e20000, 0x25080001, + 0x00c23021, 0x2d020004, 0x1440fffb, 0x24e70002, 0x95220002, 0x00004021, + 0x91230009, 0x00442023, 0x01803821, 0x3082ffff, 0xa4e00010, 0x3c040800, + 0x948423c4, 0x00621821, 0x00c33021, 0x00061c02, 0x30c2ffff, 0x00623021, + 0x00061c02, 0x3c020800, 0x944223c0, 0x00c34821, 0x00441023, 0x00021fc2, + 0x00431021, 0x00021043, 0x18400010, 0x00003021, 0x00402021, 0x94e20000, + 0x24e70002, 0x00c23021, 0x30e2007f, 0x14400006, 0x25080001, 0x8d630000, + 0x3c02007f, 0x3442ff80, 0x00625824, 0x25670008, 0x0104102a, 0x1440fff3, + 0x00000000, 0x3c020800, 0x944223dc, 0x00c23021, 0x3122ffff, 0x00c23021, + 0x00061c02, 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x00c04021, + 0x00061027, 0xa5820010, 0xadc00014, 0x0a00049f, 0xadc00000, 0x8dc70010, + 0x00e04021, 0x11400007, 0x00072c02, 0x00aa3021, 0x00061402, 0x30c3ffff, + 0x00433021, 0x00061402, 0x00c22821, 0x00051027, 0xa522000a, 0x3c030800, + 0x946323c4, 0x3102ffff, 0x01e21021, 0x00433023, 0x00cd3021, 0x00061c02, + 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x00c04021, 0x00061027, + 0xa5820010, 0x3102ffff, 0x00051c00, 0x00431025, 0xadc20010, 0x3c020800, + 0x8c4223e4, 0x10400002, 0x25e2fff2, 0xa5c20034, 0x3c020800, 0x8c4223d8, + 0x3c040800, 0x8c8423d4, 0x24420001, 0x3c010800, 0xac2223d8, 0x3c020800, + 0x8c421bb0, 0x3303ffff, 0x00832021, 0x3c010800, 0xac2423d4, 0x00431821, + 0x0062102b, 0x10400003, 0x2482ffff, 0x3c010800, 0xac2223d4, 0x3c010800, + 0xac231bb0, 0x03e00008, 0x27bd0020, 0x27bdffb8, 0x3c050800, 0x24a51b86, + 0xafbf0044, 0xafbe0040, 0xafb7003c, 0xafb60038, 0xafb50034, 0xafb40030, + 0xafb3002c, 0xafb20028, 0xafb10024, 0xafb00020, 0x94a90000, 0x3c020800, + 0x944223c0, 0x3c030800, 0x8c631ba0, 0x3c040800, 0x8c841b9c, 0x01221023, + 0x0064182a, 0xa7a9001e, 0x106000bc, 0xa7a20016, 0x24be0022, 0x97b6001e, + 0x24b3001a, 0x24b70016, 0x8fc20000, 0x14400008, 0x00000000, 0x8fc2fff8, + 0x97a30016, 0x8fc4fff4, 0x00431021, 0x0082202a, 0x148000ae, 0x00000000, + 0x97d50818, 0x32a2ffff, 0x104000a1, 0x00009021, 0x0040a021, 0x00008821, + 0x0e000621, 0x00000000, 0x00403021, 0x14c00007, 0x00000000, 0x3c020800, + 0x8c4223cc, 0x24420001, 0x3c010800, 0x0a000593, 0xac2223cc, 0x3c100800, + 0x02118021, 0x8e101bb8, 0x9608000a, 0x31020040, 0x10400004, 0x2407180c, + 0x8e02000c, 0x2407188c, 0xacc20018, 0x31020080, 0x54400001, 0x34e70010, + 0x3c020800, 0x00511021, 0x8c421bc0, 0x3c030800, 0x00711821, 0x8c631bc4, + 0x00021500, 0x00031c00, 0x00431025, 0xacc20014, 0x96040008, 0x3242ffff, + 0x00821021, 0x0282102a, 0x14400002, 0x02b22823, 0x00802821, 0x8e020000, + 0x02459021, 0xacc20000, 0x8e020004, 0x00c02021, 0x26310010, 0xac820004, + 0x30e2ffff, 0xac800008, 0xa485000e, 0xac820010, 0x24020305, 0x0e00059f, + 0xa482000c, 0x3242ffff, 0x0054102b, 0x1440ffc6, 0x3242ffff, 0x0a00058b, + 0x00000000, 0x8e620000, 0x8e63fffc, 0x0043102a, 0x10400066, 0x00000000, + 0x8e62fff0, 0x00028900, 0x3c100800, 0x02118021, 0x0e000621, 0x8e101bb8, + 0x00403021, 0x14c00005, 0x00000000, 0x8e62082c, 0x24420001, 0x0a000593, + 0xae62082c, 0x9608000a, 0x31020040, 0x10400004, 0x2407180c, 0x8e02000c, + 0x2407188c, 0xacc20018, 0x3c020800, 0x00511021, 0x8c421bc0, 0x3c030800, + 0x00711821, 0x8c631bc4, 0x00021500, 0x00031c00, 0x00431025, 0xacc20014, + 0x8e63fff4, 0x96020008, 0x00432023, 0x3242ffff, 0x3083ffff, 0x00431021, + 0x02c2102a, 0x10400003, 0x00802821, 0x97a9001e, 0x01322823, 0x8e620000, + 0x30a4ffff, 0x00441021, 0xae620000, 0xa4c5000e, 0x8e020000, 0xacc20000, + 0x8e020004, 0x8e63fff4, 0x00431021, 0xacc20004, 0x8e63fff4, 0x96020008, + 0x00641821, 0x0062102a, 0x14400006, 0x02459021, 0x8e62fff0, 0xae60fff4, + 0x24420001, 0x0a00056e, 0xae62fff0, 0xae63fff4, 0xacc00008, 0x3242ffff, + 0x10560003, 0x31020004, 0x10400006, 0x24020305, 0x31020080, 0x54400001, + 0x34e70010, 0x34e70020, 0x24020905, 0xa4c2000c, 0x8ee30000, 0x8ee20004, + 0x14620007, 0x3c02b49a, 0x8ee20860, 0x54400001, 0x34e70400, 0x3c024b65, + 0x0a000585, 0x34427654, 0x344289ab, 0xacc2001c, 0x30e2ffff, 0xacc20010, + 0x0e00059f, 0x00c02021, 0x3242ffff, 0x0056102b, 0x1440ff9c, 0x00000000, + 0x8e620000, 0x8e63fffc, 0x0043102a, 0x1440ff4a, 0x00000000, 0x8fbf0044, + 0x8fbe0040, 0x8fb7003c, 0x8fb60038, 0x8fb50034, 0x8fb40030, 0x8fb3002c, + 0x8fb20028, 0x8fb10024, 0x8fb00020, 0x03e00008, 0x27bd0048, 0x27bdffe8, + 0xafbf0014, 0xafb00010, 0x8f624450, 0x8f634410, 0x0a0005ae, 0x00808021, + 0x8f626820, 0x30422000, 0x10400003, 0x00000000, 0x0e0001ef, 0x00002021, + 0x8f624450, 0x8f634410, 0x3042ffff, 0x0043102b, 0x1440fff5, 0x00000000, + 0x8f630c14, 0x3063000f, 0x2c620002, 0x1440000b, 0x00000000, 0x8f630c14, + 0x3c020800, 0x8c421b30, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b30, + 0x2c620002, 0x1040fff7, 0x00000000, 0xaf705c18, 0x8f625c10, 0x30420002, + 0x10400009, 0x00000000, 0x8f626820, 0x30422000, 0x1040fff8, 0x00000000, + 0x0e0001ef, 0x00002021, 0x0a0005c1, 0x00000000, 0x8fbf0014, 0x8fb00010, + 0x03e00008, 0x27bd0018, 0x00000000, 0x00000000, 0x27bdffe8, 0x3c1bc000, + 0xafbf0014, 0xafb00010, 0xaf60680c, 0x8f626804, 0x34420082, 0xaf626804, + 0x8f634000, 0x24020b50, 0x3c010800, 0xac221b44, 0x24020b78, 0x3c010800, + 0xac221b54, 0x34630002, 0xaf634000, 0x0e000601, 0x00808021, 0x3c010800, + 0xa0221b58, 0x304200ff, 0x24030002, 0x14430005, 0x00000000, 0x3c020800, + 0x8c421b44, 0x0a0005f4, 0xac5000c0, 0x3c020800, 0x8c421b44, 0xac5000bc, + 0x8f624434, 0x8f634438, 0x8f644410, 0x3c010800, 0xac221b4c, 0x3c010800, + 0xac231b5c, 0x3c010800, 0xac241b48, 0x8fbf0014, 0x8fb00010, 0x03e00008, + 0x27bd0018, 0x3c040800, 0x8c870000, 0x3c03aa55, 0x3463aa55, 0x3c06c003, + 0xac830000, 0x8cc20000, 0x14430007, 0x24050002, 0x3c0355aa, 0x346355aa, + 0xac830000, 0x8cc20000, 0x50430001, 0x24050001, 0x3c020800, 0xac470000, + 0x03e00008, 0x00a01021, 0x27bdfff8, 0x18800009, 0x00002821, 0x8f63680c, + 0x8f62680c, 0x1043fffe, 0x00000000, 0x24a50001, 0x00a4102a, 0x1440fff9, + 0x00000000, 0x03e00008, 0x27bd0008, 0x8f634450, 0x3c020800, 0x8c421b4c, + 0x00031c02, 0x0043102b, 0x14400008, 0x3c038000, 0x3c040800, 0x8c841b5c, + 0x8f624450, 0x00021c02, 0x0083102b, 0x1040fffc, 0x3c038000, 0xaf634444, + 0x8f624444, 0x00431024, 0x1440fffd, 0x00000000, 0x8f624448, 0x03e00008, + 0x3042ffff, 0x3082ffff, 0x2442e000, 0x2c422001, 0x14400003, 0x3c024000, + 0x0a000644, 0x2402ffff, 0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002, + 0x1440fffc, 0x00001021, 0x03e00008, 0x00000000, 0x8f624450, 0x3c030800, + 0x8c631b48, 0x0a00064d, 0x3042ffff, 0x8f624450, 0x3042ffff, 0x0043102b, + 0x1440fffc, 0x00000000, 0x03e00008, 0x00000000, 0x27bdffe0, 0x00802821, + 0x3c040800, 0x24841ae0, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, + 0x0e000678, 0xafa00014, 0x0a00065c, 0x00000000, 0x8fbf0018, 0x03e00008, + 0x27bd0020, 0x00000000, 0x00000000, 0x00000000, 0x3c020800, 0x34423000, + 0x3c030800, 0x34633000, 0x3c040800, 0x348437ff, 0x3c010800, 0xac221b64, + 0x24020040, 0x3c010800, 0xac221b68, 0x3c010800, 0xac201b60, 0xac600000, + 0x24630004, 0x0083102b, 0x5040fffd, 0xac600000, 0x03e00008, 0x00000000, + 0x00804821, 0x8faa0010, 0x3c020800, 0x8c421b60, 0x3c040800, 0x8c841b68, + 0x8fab0014, 0x24430001, 0x0044102b, 0x3c010800, 0xac231b60, 0x14400003, + 0x00004021, 0x3c010800, 0xac201b60, 0x3c020800, 0x8c421b60, 0x3c030800, + 0x8c631b64, 0x91240000, 0x00021140, 0x00431021, 0x00481021, 0x25080001, + 0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, 0x3c020800, 0x8c421b60, + 0x3c030800, 0x8c631b64, 0x8f64680c, 0x00021140, 0x00431021, 0xac440008, + 0xac45000c, 0xac460010, 0xac470014, 0xac4a0018, 0x03e00008, 0xac4b001c, + 0x00000000, 0x00000000, }; u32 tg3TsoFwRodata[] = { - 0x4d61696e, 0x43707542, 0x00000000, 0x00000000, 0x74637073, 0x6567496e, - 0x00000000, 0x53774576, 0x656e7430, 0x00000000, 0x00000000, 0x00000000, - 0x00000000 + 0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, 0x00000000, + 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, 0x496e0000, 0x73746b6f, + 0x66662a2a, 0x00000000, 0x53774576, 0x656e7430, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x66617461, 0x6c457272, 0x00000000, 0x00000000, }; -#if 0 /* All zeros, dont eat up space with it. */ +#if 0 /* All zeros, don't eat up space with it. */ u32 tg3TsoFwData[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; #endif +/* 5705 needs a special version of the TSO firmware. */ +#define TG3_TSO5_FW_RELEASE_MAJOR 0x1 +#define TG3_TSO5_FW_RELASE_MINOR 0x1 +#define TG3_TSO5_FW_RELEASE_FIX 0x0 +#define TG3_TSO5_FW_START_ADDR 0x00010000 +#define TG3_TSO5_FW_TEXT_ADDR 0x00010000 +#define TG3_TSO5_FW_TEXT_LEN 0xeb0 +#define TG3_TSO5_FW_RODATA_ADDR 0x00010eb0 +#define TG3_TSO5_FW_RODATA_LEN 0x50 +#define TG3_TSO5_FW_DATA_ADDR 0x00010f20 +#define TG3_TSO5_FW_DATA_LEN 0x20 +#define TG3_TSO5_FW_SBSS_ADDR 0x00010f40 +#define TG3_TSO5_FW_SBSS_LEN 0x28 +#define TG3_TSO5_FW_BSS_ADDR 0x00010f70 +#define TG3_TSO5_FW_BSS_LEN 0x88 + +static u32 tg3Tso5FwText[] = { + 0x0c004003, 0x00000000, 0x00010f30, 0x00000000, 0x10000003, 0x00000000, + 0x0000000d, 0x0000000d, 0x3c1d0001, 0x37bde000, 0x03a0f021, 0x3c100001, + 0x26100000, 0x0c004010, 0x00000000, 0x0000000d, 0x27bdffe0, 0x3c04fefe, + 0xafbf0018, 0x0c0042f0, 0x34840002, 0x0c00436c, 0x00000000, 0x3c030001, + 0x90630f54, 0x24020002, 0x3c040001, 0x24840ebc, 0x14620003, 0x24050001, + 0x3c040001, 0x24840eb0, 0x24060001, 0x00003821, 0xafa00010, 0x0c004380, + 0xafa00014, 0x0c00402c, 0x00000000, 0x8fbf0018, 0x03e00008, 0x27bd0020, + 0x00000000, 0x00000000, 0x27bdffe0, 0xafbf001c, 0xafb20018, 0xafb10014, + 0x0c0042d3, 0xafb00010, 0x3c128000, 0x24110001, 0x8f706810, 0x32020400, + 0x10400007, 0x00000000, 0x8f641008, 0x00921024, 0x14400003, 0x00000000, + 0x0c004064, 0x00000000, 0x3c020001, 0x90420f76, 0x10510003, 0x32020200, + 0x1040fff1, 0x00000000, 0x0c0041b4, 0x00000000, 0x08004034, 0x00000000, + 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, + 0x27bdffe0, 0x3c040001, 0x24840ed0, 0x00002821, 0x00003021, 0x00003821, + 0xafbf0018, 0xafa00010, 0x0c004380, 0xafa00014, 0x0000d021, 0x24020130, + 0xaf625000, 0x3c010001, 0xa4200f70, 0x3c010001, 0xa0200f77, 0x8fbf0018, + 0x03e00008, 0x27bd0020, 0x00000000, 0x00000000, 0x3c030001, 0x24630f80, + 0x90620000, 0x27bdfff0, 0x14400003, 0x0080c021, 0x08004073, 0x00004821, + 0x3c022000, 0x03021024, 0x10400003, 0x24090002, 0x08004073, 0xa0600000, + 0x24090001, 0x00181040, 0x30431f80, 0x346f8008, 0x1520004b, 0x25eb0028, + 0x3c040001, 0x00832021, 0x8c848010, 0x3c050001, 0x24a50f9a, 0x00041402, + 0xa0a20000, 0x3c010001, 0xa0240f9b, 0x3c020001, 0x00431021, 0x94428014, + 0x3c010001, 0xa0220f9c, 0x3c0c0001, 0x01836021, 0x8d8c8018, 0x304200ff, + 0x24420008, 0x000220c3, 0x24020001, 0x3c010001, 0xa0220f80, 0x0124102b, + 0x1040000c, 0x00003821, 0x24a6000e, 0x01602821, 0x8ca20000, 0x8ca30004, + 0x24a50008, 0x24e70001, 0xacc20000, 0xacc30004, 0x00e4102b, 0x1440fff8, + 0x24c60008, 0x00003821, 0x3c080001, 0x25080f9b, 0x91060000, 0x3c020001, + 0x90420f9c, 0x2503000d, 0x00c32821, 0x00461023, 0x00021fc2, 0x00431021, + 0x00021043, 0x1840000c, 0x00002021, 0x91020001, 0x00461023, 0x00021fc2, + 0x00431021, 0x00021843, 0x94a20000, 0x24e70001, 0x00822021, 0x00e3102a, + 0x1440fffb, 0x24a50002, 0x00041c02, 0x3082ffff, 0x00622021, 0x00041402, + 0x00822021, 0x3c02ffff, 0x01821024, 0x3083ffff, 0x00431025, 0x3c010001, + 0x080040fa, 0xac220fa0, 0x3c050001, 0x24a50f9c, 0x90a20000, 0x3c0c0001, + 0x01836021, 0x8d8c8018, 0x000220c2, 0x1080000e, 0x00003821, 0x01603021, + 0x24a5000c, 0x8ca20000, 0x8ca30004, 0x24a50008, 0x24e70001, 0xacc20000, + 0xacc30004, 0x00e4102b, 0x1440fff8, 0x24c60008, 0x3c050001, 0x24a50f9c, + 0x90a20000, 0x30430007, 0x24020004, 0x10620011, 0x28620005, 0x10400005, + 0x24020002, 0x10620008, 0x000710c0, 0x080040fa, 0x00000000, 0x24020006, + 0x1062000e, 0x000710c0, 0x080040fa, 0x00000000, 0x00a21821, 0x9463000c, + 0x004b1021, 0x080040fa, 0xa4430000, 0x000710c0, 0x00a21821, 0x8c63000c, + 0x004b1021, 0x080040fa, 0xac430000, 0x00a21821, 0x8c63000c, 0x004b2021, + 0x00a21021, 0xac830000, 0x94420010, 0xa4820004, 0x95e70006, 0x3c020001, + 0x90420f9c, 0x3c030001, 0x90630f9a, 0x00e2c823, 0x3c020001, 0x90420f9b, + 0x24630028, 0x01e34021, 0x24420028, 0x15200012, 0x01e23021, 0x94c2000c, + 0x3c010001, 0xa4220f98, 0x94c20004, 0x94c30006, 0x3c010001, 0xa4200f96, + 0x3c010001, 0xa4200f92, 0x00021400, 0x00431025, 0x3c010001, 0xac220f8c, + 0x95020004, 0x3c010001, 0x08004124, 0xa4220f90, 0x3c020001, 0x94420f90, + 0x3c030001, 0x94630f92, 0x00431021, 0xa5020004, 0x3c020001, 0x94420f8c, + 0xa4c20004, 0x3c020001, 0x8c420f8c, 0xa4c20006, 0x3c040001, 0x94840f92, + 0x3c020001, 0x94420f90, 0x3c0a0001, 0x954a0f96, 0x00441821, 0x3063ffff, + 0x0062182a, 0x24020002, 0x1122000b, 0x00832023, 0x3c030001, 0x94630f98, + 0x30620009, 0x10400006, 0x3062fff6, 0xa4c2000c, 0x3c020001, 0x94420f98, + 0x30420009, 0x01425023, 0x24020001, 0x1122001b, 0x29220002, 0x50400005, + 0x24020002, 0x11200007, 0x31a2ffff, 0x08004197, 0x00000000, 0x1122001d, + 0x24020016, 0x08004197, 0x31a2ffff, 0x3c0e0001, 0x95ce0fa0, 0x10800005, + 0x01806821, 0x01c42021, 0x00041c02, 0x3082ffff, 0x00627021, 0x000e1027, + 0xa502000a, 0x3c030001, 0x90630f9b, 0x31a2ffff, 0x00e21021, 0x0800418d, + 0x00432023, 0x3c020001, 0x94420fa0, 0x00442021, 0x00041c02, 0x3082ffff, + 0x00622021, 0x00807021, 0x00041027, 0x08004185, 0xa502000a, 0x3c050001, + 0x24a50f9a, 0x90a30000, 0x14620002, 0x24e2fff2, 0xa5e20034, 0x90a20000, + 0x00e21023, 0xa5020002, 0x3c030001, 0x94630fa0, 0x3c020001, 0x94420f7a, + 0x30e5ffff, 0x00641821, 0x00451023, 0x00622023, 0x00041c02, 0x3082ffff, + 0x00622021, 0x00041027, 0xa502000a, 0x3c030001, 0x90630f9c, 0x24620001, + 0x14a20005, 0x00807021, 0x01631021, 0x90420000, 0x08004185, 0x00026200, + 0x24620002, 0x14a20003, 0x306200fe, 0x004b1021, 0x944c0000, 0x3c020001, + 0x94420fa2, 0x3183ffff, 0x3c040001, 0x90840f9b, 0x00431021, 0x00e21021, + 0x00442023, 0x008a2021, 0x00041c02, 0x3082ffff, 0x00622021, 0x00041402, + 0x00822021, 0x00806821, 0x00041027, 0xa4c20010, 0x31a2ffff, 0x000e1c00, + 0x00431025, 0x3c040001, 0x24840f92, 0xade20010, 0x94820000, 0x3c050001, + 0x94a50f96, 0x3c030001, 0x8c630f8c, 0x24420001, 0x00b92821, 0xa4820000, + 0x3322ffff, 0x00622021, 0x0083182b, 0x3c010001, 0xa4250f96, 0x10600003, + 0x24a2ffff, 0x3c010001, 0xa4220f96, 0x3c024000, 0x03021025, 0x3c010001, + 0xac240f8c, 0xaf621008, 0x03e00008, 0x27bd0010, 0x3c030001, 0x90630f76, + 0x27bdffe8, 0x24020001, 0xafbf0014, 0x10620026, 0xafb00010, 0x8f620cf4, + 0x2442ffff, 0x3042007f, 0x00021100, 0x8c434000, 0x3c010001, 0xac230f84, + 0x8c434008, 0x24444000, 0x8c5c4004, 0x30620040, 0x14400002, 0x24020088, + 0x24020008, 0x3c010001, 0xa4220f88, 0x30620004, 0x10400005, 0x24020001, + 0x3c010001, 0xa0220f77, 0x080041d5, 0x00031402, 0x3c010001, 0xa0200f77, + 0x00031402, 0x3c010001, 0xa4220f74, 0x9483000c, 0x24020001, 0x3c010001, + 0xa4200f70, 0x3c010001, 0xa0220f76, 0x3c010001, 0xa4230f82, 0x24020001, + 0x1342001e, 0x00000000, 0x13400005, 0x24020003, 0x13420067, 0x00000000, + 0x080042cf, 0x00000000, 0x3c020001, 0x94420f82, 0x241a0001, 0x3c010001, + 0xa4200f7e, 0x3c010001, 0xa4200f72, 0x304407ff, 0x00021bc2, 0x00031823, + 0x3063003e, 0x34630036, 0x00021242, 0x3042003c, 0x00621821, 0x3c010001, + 0xa4240f78, 0x00832021, 0x24630030, 0x3c010001, 0xa4240f7a, 0x3c010001, + 0xa4230f7c, 0x3c060001, 0x24c60f72, 0x94c50000, 0x94c30002, 0x3c040001, + 0x94840f7a, 0x00651021, 0x0044102a, 0x10400013, 0x3c108000, 0x00a31021, + 0xa4c20000, 0x3c02a000, 0xaf620cf4, 0x3c010001, 0xa0200f76, 0x8f641008, + 0x00901024, 0x14400003, 0x00000000, 0x0c004064, 0x00000000, 0x8f620cf4, + 0x00501024, 0x104000b7, 0x00000000, 0x0800420f, 0x00000000, 0x3c030001, + 0x94630f70, 0x00851023, 0xa4c40000, 0x00621821, 0x3042ffff, 0x3c010001, + 0xa4230f70, 0xaf620ce8, 0x3c020001, 0x94420f88, 0x34420024, 0xaf620cec, + 0x94c30002, 0x3c020001, 0x94420f70, 0x14620012, 0x3c028000, 0x3c108000, + 0x3c02a000, 0xaf620cf4, 0x3c010001, 0xa0200f76, 0x8f641008, 0x00901024, + 0x14400003, 0x00000000, 0x0c004064, 0x00000000, 0x8f620cf4, 0x00501024, + 0x1440fff7, 0x00000000, 0x080042cf, 0x241a0003, 0xaf620cf4, 0x3c108000, + 0x8f641008, 0x00901024, 0x14400003, 0x00000000, 0x0c004064, 0x00000000, + 0x8f620cf4, 0x00501024, 0x1440fff7, 0x00000000, 0x080042cf, 0x241a0003, + 0x3c070001, 0x24e70f70, 0x94e20000, 0x03821021, 0xaf620ce0, 0x3c020001, + 0x8c420f84, 0xaf620ce4, 0x3c050001, 0x94a50f74, 0x94e30000, 0x3c040001, + 0x94840f78, 0x3c020001, 0x94420f7e, 0x00a32823, 0x00822023, 0x30a6ffff, + 0x3083ffff, 0x00c3102b, 0x14400043, 0x00000000, 0x3c020001, 0x94420f7c, + 0x00021400, 0x00621025, 0xaf620ce8, 0x94e20000, 0x3c030001, 0x94630f74, + 0x00441021, 0xa4e20000, 0x3042ffff, 0x14430021, 0x3c020008, 0x3c020001, + 0x90420f77, 0x10400006, 0x3c03000c, 0x3c020001, 0x94420f88, 0x34630624, + 0x0800427c, 0x0000d021, 0x3c020001, 0x94420f88, 0x3c030008, 0x34630624, + 0x00431025, 0xaf620cec, 0x3c108000, 0x3c02a000, 0xaf620cf4, 0x3c010001, + 0xa0200f76, 0x8f641008, 0x00901024, 0x14400003, 0x00000000, 0x0c004064, + 0x00000000, 0x8f620cf4, 0x00501024, 0x10400015, 0x00000000, 0x08004283, + 0x00000000, 0x3c030001, 0x94630f88, 0x34420624, 0x3c108000, 0x00621825, + 0x3c028000, 0xaf630cec, 0xaf620cf4, 0x8f641008, 0x00901024, 0x14400003, + 0x00000000, 0x0c004064, 0x00000000, 0x8f620cf4, 0x00501024, 0x1440fff7, + 0x00000000, 0x3c010001, 0x080042cf, 0xa4200f7e, 0x3c020001, 0x94420f7c, + 0x00021400, 0x00c21025, 0xaf620ce8, 0x3c020001, 0x90420f77, 0x10400009, + 0x3c03000c, 0x3c020001, 0x94420f88, 0x34630624, 0x0000d021, 0x00431025, + 0xaf620cec, 0x080042c1, 0x3c108000, 0x3c020001, 0x94420f88, 0x3c030008, + 0x34630604, 0x00431025, 0xaf620cec, 0x3c020001, 0x94420f7e, 0x00451021, + 0x3c010001, 0xa4220f7e, 0x3c108000, 0x3c02a000, 0xaf620cf4, 0x3c010001, + 0xa0200f76, 0x8f641008, 0x00901024, 0x14400003, 0x00000000, 0x0c004064, + 0x00000000, 0x8f620cf4, 0x00501024, 0x1440fff7, 0x00000000, 0x8fbf0014, + 0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffe0, 0x3c040001, 0x24840ee0, + 0x00002821, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, 0x0c004380, + 0xafa00014, 0x0000d021, 0x24020130, 0xaf625000, 0x3c010001, 0xa4200f70, + 0x3c010001, 0xa0200f77, 0x8f636804, 0x3c020001, 0x3442e000, 0x00621824, + 0x3c020001, 0x14620003, 0x00000000, 0x080042eb, 0x00000000, 0x8fbf0018, + 0x03e00008, 0x27bd0020, 0x27bdffe8, 0x3c1bc000, 0xafbf0014, 0xafb00010, + 0xaf60680c, 0x8f626804, 0x34420082, 0xaf626804, 0x8f634000, 0x24020b50, + 0x3c010001, 0xac220f40, 0x24020b78, 0x3c010001, 0xac220f50, 0x34630002, + 0xaf634000, 0x0c00431d, 0x00808021, 0x3c010001, 0xa0220f54, 0x304200ff, + 0x24030002, 0x14430005, 0x00000000, 0x3c020001, 0x8c420f40, 0x08004310, + 0xac5000c0, 0x3c020001, 0x8c420f40, 0xac5000bc, 0x8f624434, 0x8f634438, + 0x8f644410, 0x3c010001, 0xac220f48, 0x3c010001, 0xac230f58, 0x3c010001, + 0xac240f44, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x03e00008, + 0x24020001, 0x27bdfff8, 0x18800009, 0x00002821, 0x8f63680c, 0x8f62680c, + 0x1043fffe, 0x00000000, 0x24a50001, 0x00a4102a, 0x1440fff9, 0x00000000, + 0x03e00008, 0x27bd0008, 0x8f634450, 0x3c020001, 0x8c420f48, 0x00031c02, + 0x0043102b, 0x14400008, 0x3c038000, 0x3c040001, 0x8c840f58, 0x8f624450, + 0x00021c02, 0x0083102b, 0x1040fffc, 0x3c038000, 0xaf634444, 0x8f624444, + 0x00431024, 0x1440fffd, 0x00000000, 0x8f624448, 0x03e00008, 0x3042ffff, + 0x3082ffff, 0x2442e000, 0x2c422001, 0x14400003, 0x3c024000, 0x0800434f, + 0x2402ffff, 0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002, 0x1440fffc, + 0x00001021, 0x03e00008, 0x00000000, 0x8f624450, 0x3c030001, 0x8c630f44, + 0x08004358, 0x3042ffff, 0x8f624450, 0x3042ffff, 0x0043102b, 0x1440fffc, + 0x00000000, 0x03e00008, 0x00000000, 0x27bdffe0, 0x00802821, 0x3c040001, + 0x24840ef0, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, 0x0c004380, + 0xafa00014, 0x08004367, 0x00000000, 0x8fbf0018, 0x03e00008, 0x27bd0020, + 0x3c020001, 0x3442d600, 0x3c030001, 0x3463d600, 0x3c040001, 0x3484ddff, + 0x3c010001, 0xac220f60, 0x24020040, 0x3c010001, 0xac220f64, 0x3c010001, + 0xac200f5c, 0xac600000, 0x24630004, 0x0083102b, 0x5040fffd, 0xac600000, + 0x03e00008, 0x00000000, 0x00804821, 0x8faa0010, 0x3c020001, 0x8c420f5c, + 0x3c040001, 0x8c840f64, 0x8fab0014, 0x24430001, 0x0044102b, 0x3c010001, + 0xac230f5c, 0x14400003, 0x00004021, 0x3c010001, 0xac200f5c, 0x3c020001, + 0x8c420f5c, 0x3c030001, 0x8c630f60, 0x91240000, 0x00021140, 0x00431021, + 0x00481021, 0x25080001, 0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, + 0x3c020001, 0x8c420f5c, 0x3c030001, 0x8c630f60, 0x8f64680c, 0x00021140, + 0x00431021, 0xac440008, 0xac45000c, 0xac460010, 0xac470014, 0xac4a0018, + 0x03e00008, 0xac4b001c, 0x00000000, 0x00000000, +}; + +u32 tg3Tso5FwRodata[] = { + 0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, 0x00000000, + 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, 0x00000000, 0x00000000, + 0x73746b6f, 0x66666c64, 0x00000000, 0x00000000, 0x66617461, 0x6c457272, + 0x00000000, 0x00000000, 0x00000000 +}; + +u32 tg3Tso5FwData[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x73746b6f, + 0x66666c64, 0x5f76312e, 0x312e3000, 0x00000000 +}; + /* tp->lock is held. */ static int tg3_load_tso_firmware(struct tg3 *tp) { struct fw_info info; + unsigned long cpu_base, cpu_scratch_base, cpu_scratch_size; int err, i; - info.text_base = TG3_TSO_FW_TEXT_ADDR; - info.text_len = TG3_TSO_FW_TEXT_LEN; - info.text_data = &tg3TsoFwText[0]; - info.rodata_base = TG3_TSO_FW_RODATA_ADDR; - info.rodata_len = TG3_TSO_FW_RODATA_LEN; - info.rodata_data = &tg3TsoFwRodata[0]; - info.data_base = TG3_TSO_FW_DATA_ADDR; - info.data_len = TG3_TSO_FW_DATA_LEN; - info.data_data = NULL; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + info.text_base = TG3_TSO5_FW_TEXT_ADDR; + info.text_len = TG3_TSO5_FW_TEXT_LEN; + info.text_data = &tg3Tso5FwText[0]; + info.rodata_base = TG3_TSO5_FW_RODATA_ADDR; + info.rodata_len = TG3_TSO5_FW_RODATA_LEN; + info.rodata_data = &tg3Tso5FwRodata[0]; + info.data_base = TG3_TSO5_FW_DATA_ADDR; + info.data_len = TG3_TSO5_FW_DATA_LEN; + info.data_data = &tg3Tso5FwData[0]; + cpu_base = RX_CPU_BASE; + cpu_scratch_base = NIC_SRAM_MBUF_POOL_BASE5705; + cpu_scratch_size = (info.text_len + + info.rodata_len + + info.data_len + + TG3_TSO5_FW_SBSS_LEN + + TG3_TSO5_FW_BSS_LEN); + } else { + info.text_base = TG3_TSO_FW_TEXT_ADDR; + info.text_len = TG3_TSO_FW_TEXT_LEN; + info.text_data = &tg3TsoFwText[0]; + info.rodata_base = TG3_TSO_FW_RODATA_ADDR; + info.rodata_len = TG3_TSO_FW_RODATA_LEN; + info.rodata_data = &tg3TsoFwRodata[0]; + info.data_base = TG3_TSO_FW_DATA_ADDR; + info.data_len = TG3_TSO_FW_DATA_LEN; + info.data_data = NULL; + cpu_base = TX_CPU_BASE; + cpu_scratch_base = TX_CPU_SCRATCH_BASE; + cpu_scratch_size = TX_CPU_SCRATCH_SIZE; + } - err = tg3_load_firmware_cpu(tp, TX_CPU_BASE, - TX_CPU_SCRATCH_BASE, TX_CPU_SCRATCH_SIZE, + err = tg3_load_firmware_cpu(tp, cpu_base, + cpu_scratch_base, cpu_scratch_size, &info); if (err) return err; - /* Now startup only the TX cpu. */ - tw32(TX_CPU_BASE + CPU_STATE, 0xffffffff); - tw32(TX_CPU_BASE + CPU_PC, TG3_TSO_FW_TEXT_ADDR); + /* Now startup the cpu. */ + tw32(cpu_base + CPU_STATE, 0xffffffff); + tw32_f(cpu_base + CPU_PC, info.text_base); - /* Flush posted writes. */ - tr32(TX_CPU_BASE + CPU_PC); for (i = 0; i < 5; i++) { - if (tr32(TX_CPU_BASE + CPU_PC) == TG3_TSO_FW_TEXT_ADDR) + if (tr32(cpu_base + CPU_PC) == info.text_base) break; - tw32(TX_CPU_BASE + CPU_STATE, 0xffffffff); - tw32(TX_CPU_BASE + CPU_MODE, CPU_MODE_HALT); - tw32(TX_CPU_BASE + CPU_PC, TG3_TSO_FW_TEXT_ADDR); - - /* Flush posted writes. */ - tr32(TX_CPU_BASE + CPU_PC); - + tw32(cpu_base + CPU_STATE, 0xffffffff); + tw32(cpu_base + CPU_MODE, CPU_MODE_HALT); + tw32_f(cpu_base + CPU_PC, info.text_base); udelay(1000); } if (i >= 5) { printk(KERN_ERR PFX "tg3_load_tso_firmware fails for %s " - "to set TX CPU PC, is %08x should be %08x\n", - tp->dev->name, tr32(TX_CPU_BASE + CPU_PC), - TG3_TSO_FW_TEXT_ADDR); + "to set CPU PC, is %08x should be %08x\n", + tp->dev->name, tr32(cpu_base + CPU_PC), + info.text_base); return -ENODEV; } - tw32(TX_CPU_BASE + CPU_STATE, 0xffffffff); - tw32(TX_CPU_BASE + CPU_MODE, 0x00000000); - - /* Flush posted writes. */ - tr32(TX_CPU_BASE + CPU_MODE); - + tw32(cpu_base + CPU_STATE, 0xffffffff); + tw32_f(cpu_base + CPU_MODE, 0x00000000); return 0; } -#endif /* TG3_DO_TSO != 0 */ +#endif /* TG3_TSO_SUPPORT != 0 */ /* tp->lock is held. */ static void __tg3_set_mac_addr(struct tg3 *tp) @@ -3876,6 +4419,15 @@ tw32(MAC_ADDR_0_LOW + (i * 8), addr_low); } + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + for (i = 0; i < 12; i++) { + tw32(MAC_EXTADDR_0_HIGH + (i * 8), addr_high); + tw32(MAC_EXTADDR_0_LOW + (i * 8), addr_low); + } + } + addr_high = (tp->dev->dev_addr[0] + tp->dev->dev_addr[1] + tp->dev->dev_addr[2] + @@ -3891,9 +4443,6 @@ struct tg3 *tp = 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(&tp->lock); @@ -3909,23 +4458,19 @@ u32 nic_addr) { tg3_write_mem(tp, - (bdinfo_addr + - TG3_BDINFO_HOST_ADDR + - TG3_64BIT_REG_HIGH), + (bdinfo_addr + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH), ((u64) mapping >> 32)); tg3_write_mem(tp, - (bdinfo_addr + - TG3_BDINFO_HOST_ADDR + - TG3_64BIT_REG_LOW), + (bdinfo_addr + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW), ((u64) mapping & 0xffffffff)); tg3_write_mem(tp, - (bdinfo_addr + - TG3_BDINFO_MAXLEN_FLAGS), + (bdinfo_addr + TG3_BDINFO_MAXLEN_FLAGS), maxlen_flags); - tg3_write_mem(tp, - (bdinfo_addr + - TG3_BDINFO_NIC_ADDR), - nic_addr); + + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) + tg3_write_mem(tp, + (bdinfo_addr + TG3_BDINFO_NIC_ADDR), + nic_addr); } static void __tg3_set_rx_mode(struct net_device *); @@ -3933,8 +4478,8 @@ /* tp->lock is held. */ static int tg3_reset_hw(struct tg3 *tp) { - u32 val; - int i, err; + u32 val, rdmac_mode; + int i, err, limit; tg3_disable_ints(tp); @@ -3948,16 +4493,18 @@ tg3_chip_reset(tp); - tw32(GRC_MODE, tp->grc_mode); + val = tr32(GRC_MODE); + val &= GRC_MODE_HOST_STACKUP; + tw32(GRC_MODE, val | tp->grc_mode); + tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX, NIC_SRAM_FIRMWARE_MBOX_MAGIC1); if (tp->phy_id == PHY_ID_SERDES) { tp->mac_mode = MAC_MODE_PORT_MODE_TBI; - tw32(MAC_MODE, tp->mac_mode); + tw32_f(MAC_MODE, tp->mac_mode); } else - tw32(MAC_MODE, 0); - tr32(MAC_MODE); + tw32_f(MAC_MODE, 0); udelay(40); /* Wait for firmware initialization to complete. */ @@ -3967,7 +4514,8 @@ break; udelay(10); } - if (i >= 100000) { + if (i >= 100000 && + !(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) { printk(KERN_ERR PFX "tg3_reset_hw timed out for %s, " "firmware will not restart magic=%08x\n", tp->dev->name, val); @@ -3985,10 +4533,8 @@ * B3 tigon3 silicon. This bit has no effect on any * other revision. */ - val = tr32(TG3PCI_CLOCK_CTRL); - val |= CLOCK_CTRL_DELAY_PCI_GRANT; - tw32(TG3PCI_CLOCK_CTRL, val); - tr32(TG3PCI_CLOCK_CTRL); + tp->pci_clock_ctrl |= CLOCK_CTRL_DELAY_PCI_GRANT; + tw32_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl); if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0 && (tp->tg3_flags & TG3_FLAG_PCIX_MODE)) { @@ -3997,14 +4543,12 @@ tw32(TG3PCI_PCISTATE, val); } - /* Clear statistics/status block in chip, and status block in ram. */ - for (i = NIC_SRAM_STATS_BLK; - i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE; - i += sizeof(u32)) { - tg3_write_mem(tp, i, 0); - udelay(40); - } - memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE); + /* Descriptor ring init may make accesses to the + * NIC SRAM area to setup the TX descriptors, so we + * can only do this after the hardware has been + * successfully reset. + */ + tg3_init_rings(tp); /* This value is determined during the probe time DMA * engine test, tg3_test_dma. @@ -4033,13 +4577,31 @@ (65 << GRC_MISC_CFG_PRESCALAR_SHIFT)); /* Initialize MBUF/DESC pool. */ - tw32(BUFMGR_MB_POOL_ADDR, NIC_SRAM_MBUF_POOL_BASE); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) - tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE64); - else - tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE96); - tw32(BUFMGR_DMA_DESC_POOL_ADDR, NIC_SRAM_DMA_DESC_POOL_BASE); - tw32(BUFMGR_DMA_DESC_POOL_SIZE, NIC_SRAM_DMA_DESC_POOL_SIZE); + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + tw32(BUFMGR_MB_POOL_ADDR, NIC_SRAM_MBUF_POOL_BASE); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) + tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE64); + else + tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE96); + tw32(BUFMGR_DMA_DESC_POOL_ADDR, NIC_SRAM_DMA_DESC_POOL_BASE); + tw32(BUFMGR_DMA_DESC_POOL_SIZE, NIC_SRAM_DMA_DESC_POOL_SIZE); + } +#if TG3_TSO_SUPPORT != 0 + else if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) { + int fw_len; + + fw_len = (TG3_TSO5_FW_TEXT_LEN + + TG3_TSO5_FW_RODATA_LEN + + TG3_TSO5_FW_DATA_LEN + + TG3_TSO5_FW_SBSS_LEN + + TG3_TSO5_FW_BSS_LEN); + fw_len = (fw_len + (0x80 - 1)) & ~(0x80 - 1); + tw32(BUFMGR_MB_POOL_ADDR, + NIC_SRAM_MBUF_POOL_BASE5705 + fw_len); + tw32(BUFMGR_MB_POOL_SIZE, + NIC_SRAM_MBUF_POOL_SIZE5705 - fw_len - 0xa00); + } +#endif if (!(tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE)) { tw32(BUFMGR_MB_RDMA_LOW_WATER, @@ -4086,6 +4648,20 @@ return -ENODEV; } + /* Clear statistics/status block in chip, and status block in ram. */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + for (i = NIC_SRAM_STATS_BLK; + i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE; + i += sizeof(u32)) { + tg3_write_mem(tp, i, 0); + udelay(40); + } + } + memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE); + + /* Setup replenish threshold. */ + tw32(RCVBDI_STD_THRESH, tp->rx_pending / 8); + /* Initialize TG3_BDINFO's at: * RCVDBDI_STD_BD: standard eth size rx ring * RCVDBDI_JUMBO_BD: jumbo frame rx ring @@ -4107,42 +4683,55 @@ ((u64) tp->rx_std_mapping >> 32)); tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW, ((u64) tp->rx_std_mapping & 0xffffffff)); - tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, - RX_STD_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT); tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR, NIC_SRAM_RX_BUFFER_DESC); - tw32(RCVDBDI_MINI_BD + TG3_BDINFO_MAXLEN_FLAGS, - BDINFO_FLAGS_DISABLED); - - if (tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE) { - tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH, - ((u64) tp->rx_jumbo_mapping >> 32)); - tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW, - ((u64) tp->rx_jumbo_mapping & 0xffffffff)); - tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS, - RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT); - tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR, - NIC_SRAM_RX_JUMBO_BUFFER_DESC); + /* Don't even try to program the JUMBO/MINI buffer descriptor + * configs on 5705. + */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, + RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT); } else { - tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS, + tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, + RX_STD_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT); + + tw32(RCVDBDI_MINI_BD + TG3_BDINFO_MAXLEN_FLAGS, BDINFO_FLAGS_DISABLED); - } - /* Setup replenish thresholds. */ - tw32(RCVBDI_STD_THRESH, tp->rx_pending / 8); - tw32(RCVBDI_JUMBO_THRESH, tp->rx_jumbo_pending / 8); + /* Setup replenish threshold. */ + tw32(RCVBDI_JUMBO_THRESH, tp->rx_jumbo_pending / 8); + + if (tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE) { + tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH, + ((u64) tp->rx_jumbo_mapping >> 32)); + tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW, + ((u64) tp->rx_jumbo_mapping & 0xffffffff)); + tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS, + RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT); + tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR, + NIC_SRAM_RX_JUMBO_BUFFER_DESC); + } else { + tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS, + BDINFO_FLAGS_DISABLED); + } + + } - /* Clear out send RCB ring in SRAM. */ - for (i = NIC_SRAM_SEND_RCB; i < NIC_SRAM_RCV_RET_RCB; i += TG3_BDINFO_SIZE) - tg3_write_mem(tp, i + TG3_BDINFO_MAXLEN_FLAGS, BDINFO_FLAGS_DISABLED); + /* There is only one send ring on 5705, no need to explicitly + * disable the others. + */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + /* Clear out send RCB ring in SRAM. */ + for (i = NIC_SRAM_SEND_RCB; i < NIC_SRAM_RCV_RET_RCB; i += TG3_BDINFO_SIZE) + tg3_write_mem(tp, i + TG3_BDINFO_MAXLEN_FLAGS, + BDINFO_FLAGS_DISABLED); + } tp->tx_prod = 0; tp->tx_cons = 0; tw32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, 0); - tw32_mailbox(MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW, 0); - if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) - tr32(MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW); + tw32_tx_mbox(MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW, 0); if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) { tg3_set_bdinfo(tp, NIC_SRAM_SEND_RCB, @@ -4157,36 +4746,34 @@ NIC_SRAM_TX_BUFFER_DESC); } - for (i = NIC_SRAM_RCV_RET_RCB; i < NIC_SRAM_STATS_BLK; i += TG3_BDINFO_SIZE) { - tg3_write_mem(tp, i + TG3_BDINFO_MAXLEN_FLAGS, - BDINFO_FLAGS_DISABLED); + /* There is only one receive return ring on 5705, no need to explicitly + * disable the others. + */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + for (i = NIC_SRAM_RCV_RET_RCB; i < NIC_SRAM_STATS_BLK; + i += TG3_BDINFO_SIZE) { + tg3_write_mem(tp, i + TG3_BDINFO_MAXLEN_FLAGS, + BDINFO_FLAGS_DISABLED); + } } tp->rx_rcb_ptr = 0; - tw32_mailbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, 0); - if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) - tr32(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW); + tw32_rx_mbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, 0); tg3_set_bdinfo(tp, NIC_SRAM_RCV_RET_RCB, tp->rx_rcb_mapping, - (TG3_RX_RCB_RING_SIZE << + (TG3_RX_RCB_RING_SIZE(tp) << BDINFO_FLAGS_MAXLEN_SHIFT), 0); tp->rx_std_ptr = tp->rx_pending; - tw32_mailbox(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW, + tw32_rx_mbox(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW, tp->rx_std_ptr); - if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) - tr32(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW); - if (tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE) - tp->rx_jumbo_ptr = tp->rx_jumbo_pending; - else - tp->rx_jumbo_ptr = 0; - tw32_mailbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW, + tp->rx_jumbo_ptr = (tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE) ? + tp->rx_jumbo_pending : 0; + tw32_rx_mbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW, tp->rx_jumbo_ptr); - if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) - tr32(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW); /* Initialize MAC address and backoff seed. */ __tg3_set_mac_addr(tp); @@ -4206,8 +4793,36 @@ tw32(MAC_RCV_RULE_CFG, RCV_RULE_CFG_DEFAULT_CLASS); tw32(RCVLPC_CONFIG, 0x0181); + /* Calculate RDMAC_MODE setting early, we need it to determine + * the RCVLPC_STATE_ENABLE mask. + */ + rdmac_mode = (RDMAC_MODE_ENABLE | RDMAC_MODE_TGTABORT_ENAB | + RDMAC_MODE_MSTABORT_ENAB | RDMAC_MODE_PARITYERR_ENAB | + RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB | + RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB | + RDMAC_MODE_LNGREAD_ENAB); + if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) + rdmac_mode |= RDMAC_MODE_SPLIT_ENABLE; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + if (tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) { + if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) { + rdmac_mode |= RDMAC_MODE_FIFO_SIZE_128; + } else if (!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) && + !(tp->tg3_flags2 & TG3_FLG2_IS_5788)) { + rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST; + } + } + } + /* Receive/send statistics. */ - tw32(RCVLPC_STATS_ENABLE, 0xffffff); + if ((rdmac_mode & RDMAC_MODE_FIFO_SIZE_128) && + (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) { + val = tr32(RCVLPC_STATS_ENABLE); + val &= ~RCVLPC_STATSENAB_LNGBRST_RFIX; + tw32(RCVLPC_STATS_ENABLE, val); + } else { + tw32(RCVLPC_STATS_ENABLE, 0xffffff); + } tw32(RCVLPC_STATSCTRL, RCVLPC_STATSCTRL_ENABLE); tw32(SNDDATAI_STATSENAB, 0xffffff); tw32(SNDDATAI_STATSCTRL, @@ -4223,87 +4838,97 @@ } tw32(HOSTCC_RXCOL_TICKS, 0); - tw32(HOSTCC_RXMAX_FRAMES, 1); - tw32(HOSTCC_RXCOAL_TICK_INT, 0); - tw32(HOSTCC_RXCOAL_MAXF_INT, 1); tw32(HOSTCC_TXCOL_TICKS, LOW_TXCOL_TICKS); + tw32(HOSTCC_RXMAX_FRAMES, 1); tw32(HOSTCC_TXMAX_FRAMES, LOW_RXMAX_FRAMES); - tw32(HOSTCC_TXCOAL_TICK_INT, 0); + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) + tw32(HOSTCC_RXCOAL_TICK_INT, 0); + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) + tw32(HOSTCC_TXCOAL_TICK_INT, 0); + tw32(HOSTCC_RXCOAL_MAXF_INT, 1); tw32(HOSTCC_TXCOAL_MAXF_INT, 0); - tw32(HOSTCC_STAT_COAL_TICKS, - DEFAULT_STAT_COAL_TICKS); - /* Status/statistics block address. */ - tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, - ((u64) tp->stats_mapping >> 32)); - tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW, - ((u64) tp->stats_mapping & 0xffffffff)); + /* set status block DMA address */ tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, ((u64) tp->status_mapping >> 32)); tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW, ((u64) tp->status_mapping & 0xffffffff)); - tw32(HOSTCC_STATS_BLK_NIC_ADDR, NIC_SRAM_STATS_BLK); - tw32(HOSTCC_STATUS_BLK_NIC_ADDR, NIC_SRAM_STATUS_BLK); + + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + /* Status/statistics block address. See tg3_timer, + * the tg3_periodic_fetch_stats call there, and + * tg3_get_stats to see how this works for 5705 chips. + */ + tw32(HOSTCC_STAT_COAL_TICKS, + DEFAULT_STAT_COAL_TICKS); + tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, + ((u64) tp->stats_mapping >> 32)); + tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW, + ((u64) tp->stats_mapping & 0xffffffff)); + tw32(HOSTCC_STATS_BLK_NIC_ADDR, NIC_SRAM_STATS_BLK); + tw32(HOSTCC_STATUS_BLK_NIC_ADDR, NIC_SRAM_STATUS_BLK); + } tw32(HOSTCC_MODE, HOSTCC_MODE_ENABLE | tp->coalesce_mode); tw32(RCVCC_MODE, RCVCC_MODE_ENABLE | RCVCC_MODE_ATTN_ENABLE); tw32(RCVLPC_MODE, RCVLPC_MODE_ENABLE); - tw32(RCVLSC_MODE, RCVLSC_MODE_ENABLE | RCVLSC_MODE_ATTN_ENABLE); + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) + tw32(RCVLSC_MODE, RCVLSC_MODE_ENABLE | RCVLSC_MODE_ATTN_ENABLE); tp->mac_mode = MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE | MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE; - tw32(MAC_MODE, tp->mac_mode | MAC_MODE_RXSTAT_CLEAR | MAC_MODE_TXSTAT_CLEAR); - tr32(MAC_MODE); + tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_RXSTAT_CLEAR | MAC_MODE_TXSTAT_CLEAR); udelay(40); tp->grc_local_ctrl = GRC_LCLCTRL_INT_ON_ATTN | GRC_LCLCTRL_AUTO_SEEPROM; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 | GRC_LCLCTRL_GPIO_OUTPUT1); - tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl); - tr32(GRC_LOCAL_CTRL); + tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); udelay(100); tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0); tr32(MAILBOX_INTERRUPT_0); - tw32(DMAC_MODE, DMAC_MODE_ENABLE); - tr32(DMAC_MODE); - udelay(40); + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + tw32_f(DMAC_MODE, DMAC_MODE_ENABLE); + udelay(40); + } - tw32(WDMAC_MODE, (WDMAC_MODE_ENABLE | WDMAC_MODE_TGTABORT_ENAB | - WDMAC_MODE_MSTABORT_ENAB | WDMAC_MODE_PARITYERR_ENAB | - WDMAC_MODE_ADDROFLOW_ENAB | WDMAC_MODE_FIFOOFLOW_ENAB | - WDMAC_MODE_FIFOURUN_ENAB | WDMAC_MODE_FIFOOREAD_ENAB | - WDMAC_MODE_LNGREAD_ENAB)); - tr32(WDMAC_MODE); + val = (WDMAC_MODE_ENABLE | WDMAC_MODE_TGTABORT_ENAB | + WDMAC_MODE_MSTABORT_ENAB | WDMAC_MODE_PARITYERR_ENAB | + WDMAC_MODE_ADDROFLOW_ENAB | WDMAC_MODE_FIFOOFLOW_ENAB | + WDMAC_MODE_FIFOURUN_ENAB | WDMAC_MODE_FIFOOREAD_ENAB | + WDMAC_MODE_LNGREAD_ENAB); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && + (tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) != 0 && + !(tp->tg3_flags2 & TG3_FLG2_IS_5788)) + val |= WDMAC_MODE_RX_ACCEL; + tw32_f(WDMAC_MODE, val); udelay(40); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 && - (tp->tg3_flags & TG3_FLAG_PCIX_MODE)) { + if ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) { val = tr32(TG3PCI_X_CAPS); - val &= ~(PCIX_CAPS_SPLIT_MASK | PCIX_CAPS_BURST_MASK); - val |= (PCIX_CAPS_MAX_BURST_5704 << PCIX_CAPS_BURST_SHIFT); - if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) - val |= (tp->split_mode_max_reqs << - PCIX_CAPS_SPLIT_SHIFT); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) { + val &= ~PCIX_CAPS_BURST_MASK; + val |= (PCIX_CAPS_MAX_BURST_CPIOB << PCIX_CAPS_BURST_SHIFT); + } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { + val &= ~(PCIX_CAPS_SPLIT_MASK | PCIX_CAPS_BURST_MASK); + val |= (PCIX_CAPS_MAX_BURST_CPIOB << PCIX_CAPS_BURST_SHIFT); + if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) + val |= (tp->split_mode_max_reqs << + PCIX_CAPS_SPLIT_SHIFT); + } tw32(TG3PCI_X_CAPS, val); } - val = (RDMAC_MODE_ENABLE | RDMAC_MODE_TGTABORT_ENAB | - RDMAC_MODE_MSTABORT_ENAB | RDMAC_MODE_PARITYERR_ENAB | - RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB | - RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB | - RDMAC_MODE_LNGREAD_ENAB); - if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) - val |= RDMAC_MODE_SPLIT_ENABLE; - tw32(RDMAC_MODE, val); - tr32(RDMAC_MODE); + tw32_f(RDMAC_MODE, rdmac_mode); udelay(40); tw32(RCVDCC_MODE, RCVDCC_MODE_ENABLE | RCVDCC_MODE_ATTN_ENABLE); - tw32(MBFREE_MODE, MBFREE_MODE_ENABLE); + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) + tw32(MBFREE_MODE, MBFREE_MODE_ENABLE); tw32(SNDDATAC_MODE, SNDDATAC_MODE_ENABLE); tw32(SNDBDC_MODE, SNDBDC_MODE_ENABLE | SNDBDC_MODE_ATTN_ENABLE); tw32(RCVBDI_MODE, RCVBDI_MODE_ENABLE | RCVBDI_MODE_RCB_ATTN_ENAB); @@ -4318,20 +4943,20 @@ return err; } -#if TG3_DO_TSO != 0 - err = tg3_load_tso_firmware(tp); - if (err) - return err; +#if TG3_TSO_SUPPORT != 0 + if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) { + err = tg3_load_tso_firmware(tp); + if (err) + return err; + } #endif tp->tx_mode = TX_MODE_ENABLE; - tw32(MAC_TX_MODE, tp->tx_mode); - tr32(MAC_TX_MODE); + tw32_f(MAC_TX_MODE, tp->tx_mode); udelay(100); tp->rx_mode = RX_MODE_ENABLE; - tw32(MAC_RX_MODE, tp->rx_mode); - tr32(MAC_RX_MODE); + tw32_f(MAC_RX_MODE, tp->rx_mode); udelay(10); if (tp->link_config.phy_is_low_power) { @@ -4342,17 +4967,16 @@ } tp->mi_mode = MAC_MI_MODE_BASE; - tw32(MAC_MI_MODE, tp->mi_mode); - tr32(MAC_MI_MODE); + tw32_f(MAC_MI_MODE, tp->mi_mode); udelay(40); tw32(MAC_LED_CTRL, 0); tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB); - tw32(MAC_RX_MODE, RX_MODE_RESET); - tr32(MAC_RX_MODE); - udelay(10); - tw32(MAC_RX_MODE, tp->rx_mode); - tr32(MAC_RX_MODE); + if (tp->phy_id == PHY_ID_SERDES) { + tw32_f(MAC_RX_MODE, RX_MODE_RESET); + udelay(10); + } + tw32_f(MAC_RX_MODE, tp->rx_mode); udelay(10); if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1) @@ -4361,10 +4985,9 @@ /* Prevent chip from dropping frames when flow control * is enabled. */ - tw32(MAC_LOW_WMARK_MAX_RX_FRAME, 2); - tr32(MAC_LOW_WMARK_MAX_RX_FRAME); + tw32_f(MAC_LOW_WMARK_MAX_RX_FRAME, 2); - err = tg3_setup_phy(tp); + err = tg3_setup_phy(tp, 1); if (err) return err; @@ -4384,22 +5007,48 @@ tw32(MAC_RCV_VALUE_0, 0xffffffff & RCV_RULE_DISABLE_MASK); tw32(MAC_RCV_RULE_1, 0x86000004 & RCV_RULE_DISABLE_MASK); tw32(MAC_RCV_VALUE_1, 0xffffffff & RCV_RULE_DISABLE_MASK); -#if 0 - tw32(MAC_RCV_RULE_2, 0); tw32(MAC_RCV_VALUE_2, 0); - tw32(MAC_RCV_RULE_3, 0); tw32(MAC_RCV_VALUE_3, 0); -#endif - tw32(MAC_RCV_RULE_4, 0); tw32(MAC_RCV_VALUE_4, 0); - tw32(MAC_RCV_RULE_5, 0); tw32(MAC_RCV_VALUE_5, 0); - tw32(MAC_RCV_RULE_6, 0); tw32(MAC_RCV_VALUE_6, 0); - tw32(MAC_RCV_RULE_7, 0); tw32(MAC_RCV_VALUE_7, 0); - tw32(MAC_RCV_RULE_8, 0); tw32(MAC_RCV_VALUE_8, 0); - tw32(MAC_RCV_RULE_9, 0); tw32(MAC_RCV_VALUE_9, 0); - tw32(MAC_RCV_RULE_10, 0); tw32(MAC_RCV_VALUE_10, 0); - tw32(MAC_RCV_RULE_11, 0); tw32(MAC_RCV_VALUE_11, 0); - tw32(MAC_RCV_RULE_12, 0); tw32(MAC_RCV_VALUE_12, 0); - tw32(MAC_RCV_RULE_13, 0); tw32(MAC_RCV_VALUE_13, 0); - tw32(MAC_RCV_RULE_14, 0); tw32(MAC_RCV_VALUE_14, 0); - tw32(MAC_RCV_RULE_15, 0); tw32(MAC_RCV_VALUE_15, 0); + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) + limit = 8; + else + limit = 16; + if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) + limit -= 4; + switch (limit) { + case 16: + tw32(MAC_RCV_RULE_15, 0); tw32(MAC_RCV_VALUE_15, 0); + case 15: + tw32(MAC_RCV_RULE_14, 0); tw32(MAC_RCV_VALUE_14, 0); + case 14: + tw32(MAC_RCV_RULE_13, 0); tw32(MAC_RCV_VALUE_13, 0); + case 13: + tw32(MAC_RCV_RULE_12, 0); tw32(MAC_RCV_VALUE_12, 0); + case 12: + tw32(MAC_RCV_RULE_11, 0); tw32(MAC_RCV_VALUE_11, 0); + case 11: + tw32(MAC_RCV_RULE_10, 0); tw32(MAC_RCV_VALUE_10, 0); + case 10: + tw32(MAC_RCV_RULE_9, 0); tw32(MAC_RCV_VALUE_9, 0); + case 9: + tw32(MAC_RCV_RULE_8, 0); tw32(MAC_RCV_VALUE_8, 0); + case 8: + tw32(MAC_RCV_RULE_7, 0); tw32(MAC_RCV_VALUE_7, 0); + case 7: + tw32(MAC_RCV_RULE_6, 0); tw32(MAC_RCV_VALUE_6, 0); + case 6: + tw32(MAC_RCV_RULE_5, 0); tw32(MAC_RCV_VALUE_5, 0); + case 5: + tw32(MAC_RCV_RULE_4, 0); tw32(MAC_RCV_VALUE_4, 0); + case 4: + /* tw32(MAC_RCV_RULE_3, 0); tw32(MAC_RCV_VALUE_3, 0); */ + case 3: + /* tw32(MAC_RCV_RULE_2, 0); tw32(MAC_RCV_VALUE_2, 0); */ + case 2: + case 1: + + default: + break; + }; if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) tg3_enable_ints(tp); @@ -4429,6 +5078,50 @@ return err; } +#define TG3_STAT_ADD32(PSTAT, REG) \ +do { u32 __val = tr32(REG); \ + (PSTAT)->low += __val; \ + if ((PSTAT)->low < __val) \ + (PSTAT)->high += 1; \ +} while (0) + +static void tg3_periodic_fetch_stats(struct tg3 *tp) +{ + struct tg3_hw_stats *sp = tp->hw_stats; + + if (!netif_carrier_ok(tp->dev)) + return; + + TG3_STAT_ADD32(&sp->tx_octets, MAC_TX_STATS_OCTETS); + TG3_STAT_ADD32(&sp->tx_collisions, MAC_TX_STATS_COLLISIONS); + TG3_STAT_ADD32(&sp->tx_xon_sent, MAC_TX_STATS_XON_SENT); + TG3_STAT_ADD32(&sp->tx_xoff_sent, MAC_TX_STATS_XOFF_SENT); + TG3_STAT_ADD32(&sp->tx_mac_errors, MAC_TX_STATS_MAC_ERRORS); + TG3_STAT_ADD32(&sp->tx_single_collisions, MAC_TX_STATS_SINGLE_COLLISIONS); + TG3_STAT_ADD32(&sp->tx_mult_collisions, MAC_TX_STATS_MULT_COLLISIONS); + TG3_STAT_ADD32(&sp->tx_deferred, MAC_TX_STATS_DEFERRED); + TG3_STAT_ADD32(&sp->tx_excessive_collisions, MAC_TX_STATS_EXCESSIVE_COL); + TG3_STAT_ADD32(&sp->tx_late_collisions, MAC_TX_STATS_LATE_COL); + TG3_STAT_ADD32(&sp->tx_ucast_packets, MAC_TX_STATS_UCAST); + TG3_STAT_ADD32(&sp->tx_mcast_packets, MAC_TX_STATS_MCAST); + TG3_STAT_ADD32(&sp->tx_bcast_packets, MAC_TX_STATS_BCAST); + + TG3_STAT_ADD32(&sp->rx_octets, MAC_RX_STATS_OCTETS); + TG3_STAT_ADD32(&sp->rx_fragments, MAC_RX_STATS_FRAGMENTS); + TG3_STAT_ADD32(&sp->rx_ucast_packets, MAC_RX_STATS_UCAST); + TG3_STAT_ADD32(&sp->rx_mcast_packets, MAC_RX_STATS_MCAST); + TG3_STAT_ADD32(&sp->rx_bcast_packets, MAC_RX_STATS_BCAST); + TG3_STAT_ADD32(&sp->rx_fcs_errors, MAC_RX_STATS_FCS_ERRORS); + TG3_STAT_ADD32(&sp->rx_align_errors, MAC_RX_STATS_ALIGN_ERRORS); + TG3_STAT_ADD32(&sp->rx_xon_pause_rcvd, MAC_RX_STATS_XON_PAUSE_RECVD); + TG3_STAT_ADD32(&sp->rx_xoff_pause_rcvd, MAC_RX_STATS_XOFF_PAUSE_RECVD); + TG3_STAT_ADD32(&sp->rx_mac_ctrl_rcvd, MAC_RX_STATS_MAC_CTRL_RECVD); + TG3_STAT_ADD32(&sp->rx_xoff_entered, MAC_RX_STATS_XOFF_ENTERED); + TG3_STAT_ADD32(&sp->rx_frame_too_long_errors, MAC_RX_STATS_FRAME_TOO_LONG); + TG3_STAT_ADD32(&sp->rx_jabbers, MAC_RX_STATS_JABBERS); + TG3_STAT_ADD32(&sp->rx_undersize_packets, MAC_RX_STATS_UNDERSIZE); +} + static void tg3_timer(unsigned long __opaque) { struct tg3 *tp = (struct tg3 *) __opaque; @@ -4457,6 +5150,9 @@ return; } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) + tg3_periodic_fetch_stats(tp); + /* This part only runs once per second. */ if (!--tp->timer_counter) { if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) { @@ -4473,7 +5169,7 @@ phy_event = 1; if (phy_event) - tg3_setup_phy(tp); + tg3_setup_phy(tp, 0); } else if (tp->tg3_flags & TG3_FLAG_POLL_SERDES) { u32 mac_stat = tr32(MAC_STATUS); int need_setup = 0; @@ -4487,15 +5183,13 @@ need_setup = 1; } if (need_setup) { - tw32(MAC_MODE, + tw32_f(MAC_MODE, (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK)); - tr32(MAC_MODE); udelay(40); - tw32(MAC_MODE, tp->mac_mode); - tr32(MAC_MODE); + tw32_f(MAC_MODE, tp->mac_mode); udelay(40); - tg3_setup_phy(tp); + tg3_setup_phy(tp, 0); } } @@ -4556,8 +5250,6 @@ spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); - tg3_init_rings(tp); - err = tg3_init_hw(tp); if (err) { tg3_halt(tp); @@ -4916,7 +5608,9 @@ get_stat64(&hw_stats->rx_bcast_packets); stats->tx_packets = old_stats->tx_packets + - get_stat64(&hw_stats->COS_out_packets[0]); + get_stat64(&hw_stats->tx_ucast_packets) + + get_stat64(&hw_stats->tx_mcast_packets) + + get_stat64(&hw_stats->tx_bcast_packets); stats->rx_bytes = old_stats->rx_bytes + get_stat64(&hw_stats->rx_octets); @@ -4996,14 +5690,20 @@ rx_mode = tp->rx_mode & ~(RX_MODE_PROMISC | RX_MODE_KEEP_VLAN_TAG); + + /* When ASF is in use, we always keep the RX_MODE_KEEP_VLAN_TAG + * flag clear. + */ #if TG3_VLAN_TAG_USED - if (!tp->vlgrp) + if (!tp->vlgrp && + !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) rx_mode |= RX_MODE_KEEP_VLAN_TAG; #else /* By definition, VLAN is disabled always in this * case. */ - rx_mode |= RX_MODE_KEEP_VLAN_TAG; + if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) + rx_mode |= RX_MODE_KEEP_VLAN_TAG; #endif if (dev->flags & IFF_PROMISC) { @@ -5042,8 +5742,7 @@ if (rx_mode != tp->rx_mode) { tp->rx_mode = rx_mode; - tw32(MAC_RX_MODE, rx_mode); - tr32(MAC_RX_MODE); + tw32_f(MAC_RX_MODE, rx_mode); udelay(10); } } @@ -5059,16 +5758,20 @@ #define TG3_REGDUMP_LEN (32 * 1024) -static u8 *tg3_get_regs(struct tg3 *tp) +static int tg3_get_regs_len(struct net_device *dev) +{ + return TG3_REGDUMP_LEN; +} + +static void tg3_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) { - u8 *orig_p = kmalloc(TG3_REGDUMP_LEN, GFP_KERNEL); - u8 *p; + struct tg3 *tp = dev->priv; + u8 *orig_p = p; int i; - if (orig_p == NULL) - return NULL; + regs->version = 0; - memset(orig_p, 0, TG3_REGDUMP_LEN); + memset(p, 0, TG3_REGDUMP_LEN); spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); @@ -5107,405 +5810,299 @@ GET_REG32_LOOP(BUFMGR_MODE, 0x58); GET_REG32_LOOP(RDMAC_MODE, 0x08); GET_REG32_LOOP(WDMAC_MODE, 0x08); - GET_REG32_LOOP(RX_CPU_BASE, 0x280); - GET_REG32_LOOP(TX_CPU_BASE, 0x280); - GET_REG32_LOOP(GRCMBOX_INTERRUPT_0, 0x110); - GET_REG32_LOOP(FTQ_RESET, 0x120); - GET_REG32_LOOP(MSGINT_MODE, 0x0c); - GET_REG32_1(DMAC_MODE); - GET_REG32_LOOP(GRC_MODE, 0x4c); - GET_REG32_LOOP(NVRAM_CMD, 0x24); - -#undef __GET_REG32 -#undef GET_REG32_LOOP -#undef GET_REG32_1 - - spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); - - return orig_p; -} - -static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr) -{ - struct tg3 *tp = dev->priv; - struct pci_dev *pci_dev = tp->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 = TG3_REGDUMP_LEN; - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - case ETHTOOL_GSET: { - struct ethtool_cmd cmd = { ETHTOOL_GSET }; - - if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) || - tp->link_config.phy_is_low_power) - return -EAGAIN; - cmd.supported = (SUPPORTED_Autoneg); - - if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) - cmd.supported |= (SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full); - - if (tp->phy_id != PHY_ID_SERDES) - cmd.supported |= (SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_MII); - else - cmd.supported |= SUPPORTED_FIBRE; - - cmd.advertising = tp->link_config.advertising; - cmd.speed = tp->link_config.active_speed; - cmd.duplex = tp->link_config.active_duplex; - cmd.port = 0; - cmd.phy_address = PHY_ADDR; - cmd.transceiver = 0; - cmd.autoneg = tp->link_config.autoneg; - 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 (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) || - tp->link_config.phy_is_low_power) - return -EAGAIN; - - if (copy_from_user(&cmd, useraddr, sizeof(cmd))) - return -EFAULT; - - /* Fiber PHY only supports 1000 full/half */ - if (cmd.autoneg == AUTONEG_ENABLE) { - if (tp->phy_id == PHY_ID_SERDES && - (cmd.advertising & - (ADVERTISED_10baseT_Half | - ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | - ADVERTISED_100baseT_Full))) - return -EINVAL; - if ((tp->tg3_flags & TG3_FLAG_10_100_ONLY) && - (cmd.advertising & - (ADVERTISED_1000baseT_Half | - ADVERTISED_1000baseT_Full))) - return -EINVAL; - } else { - if (tp->phy_id == PHY_ID_SERDES && - (cmd.speed == SPEED_10 || - cmd.speed == SPEED_100)) - return -EINVAL; - if ((tp->tg3_flags & TG3_FLAG_10_100_ONLY) && - (cmd.speed == SPEED_10 || - cmd.speed == SPEED_100)) - return -EINVAL; - } - - spin_lock_irq(&tp->lock); - spin_lock(&tp->tx_lock); - - tp->link_config.autoneg = cmd.autoneg; - if (cmd.autoneg == AUTONEG_ENABLE) { - tp->link_config.advertising = cmd.advertising; - tp->link_config.speed = SPEED_INVALID; - tp->link_config.duplex = DUPLEX_INVALID; - } else { - tp->link_config.speed = cmd.speed; - tp->link_config.duplex = cmd.duplex; - } - - tg3_setup_phy(tp); - spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); - - return 0; - } - - case ETHTOOL_GREGS: { - struct ethtool_regs regs; - u8 *regbuf; - int ret; - - if (copy_from_user(®s, useraddr, sizeof(regs))) - return -EFAULT; - if (regs.len > TG3_REGDUMP_LEN) - regs.len = TG3_REGDUMP_LEN; - regs.version = 0; - if (copy_to_user(useraddr, ®s, sizeof(regs))) - return -EFAULT; - - regbuf = tg3_get_regs(tp); - if (!regbuf) - return -ENOMEM; - - useraddr += offsetof(struct ethtool_regs, data); - ret = 0; - if (copy_to_user(useraddr, regbuf, regs.len)) - ret = -EFAULT; - kfree(regbuf); - return ret; - } - case ETHTOOL_GWOL: { - struct ethtool_wolinfo wol = { ETHTOOL_GWOL }; - - wol.supported = WAKE_MAGIC; - wol.wolopts = 0; - if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) - wol.wolopts = WAKE_MAGIC; - memset(&wol.sopass, 0, sizeof(wol.sopass)); - if (copy_to_user(useraddr, &wol, sizeof(wol))) - return -EFAULT; - return 0; - } - case ETHTOOL_SWOL: { - struct ethtool_wolinfo wol; - - if (copy_from_user(&wol, useraddr, sizeof(wol))) - return -EFAULT; - if (wol.wolopts & ~WAKE_MAGIC) - return -EINVAL; - if ((wol.wolopts & WAKE_MAGIC) && - tp->phy_id == PHY_ID_SERDES && - !(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP)) - return -EINVAL; - - spin_lock_irq(&tp->lock); - if (wol.wolopts & WAKE_MAGIC) - tp->tg3_flags |= TG3_FLAG_WOL_ENABLE; - else - tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE; - spin_unlock_irq(&tp->lock); - - return 0; - } - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = { ETHTOOL_GMSGLVL }; - edata.data = tp->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; - tp->msg_enable = edata.data; - return 0; - } - case ETHTOOL_NWAY_RST: { - u32 bmcr; - int r; - - spin_lock_irq(&tp->lock); - tg3_readphy(tp, MII_BMCR, &bmcr); - tg3_readphy(tp, MII_BMCR, &bmcr); - r = -EINVAL; - if (bmcr & BMCR_ANENABLE) { - tg3_writephy(tp, MII_BMCR, - bmcr | BMCR_ANRESTART); - r = 0; - } - spin_unlock_irq(&tp->lock); - - return r; - } - case ETHTOOL_GLINK: { - struct ethtool_value edata = { ETHTOOL_GLINK }; - edata.data = netif_carrier_ok(tp->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 = TG3_RX_RING_SIZE - 1; - ering.rx_mini_max_pending = 0; - ering.rx_jumbo_max_pending = TG3_RX_JUMBO_RING_SIZE - 1; - - ering.rx_pending = tp->rx_pending; - ering.rx_mini_pending = 0; - ering.rx_jumbo_pending = tp->rx_jumbo_pending; - ering.tx_pending = tp->tx_pending; - - 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 > TG3_RX_RING_SIZE - 1) || - (ering.rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || - (ering.tx_pending > TG3_TX_RING_SIZE - 1)) - return -EINVAL; - - tg3_netif_stop(tp); - spin_lock_irq(&tp->lock); - spin_lock(&tp->tx_lock); - - tp->rx_pending = ering.rx_pending; - tp->rx_jumbo_pending = ering.rx_jumbo_pending; - tp->tx_pending = ering.tx_pending; - - tg3_halt(tp); - tg3_init_rings(tp); - tg3_init_hw(tp); - netif_wake_queue(tp->dev); - spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); - tg3_netif_start(tp); - - return 0; - } - case ETHTOOL_GPAUSEPARAM: { - struct ethtool_pauseparam epause = { ETHTOOL_GPAUSEPARAM }; - - epause.autoneg = - (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) != 0; - epause.rx_pause = - (tp->tg3_flags & TG3_FLAG_PAUSE_RX) != 0; - epause.tx_pause = - (tp->tg3_flags & TG3_FLAG_PAUSE_TX) != 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; - - tg3_netif_stop(tp); - spin_lock_irq(&tp->lock); - spin_lock(&tp->tx_lock); - if (epause.autoneg) - tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; - else - tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG; - if (epause.rx_pause) - tp->tg3_flags |= TG3_FLAG_PAUSE_RX; - else - tp->tg3_flags &= ~TG3_FLAG_PAUSE_RX; - if (epause.tx_pause) - tp->tg3_flags |= TG3_FLAG_PAUSE_TX; - else - tp->tg3_flags &= ~TG3_FLAG_PAUSE_TX; - tg3_halt(tp); - tg3_init_rings(tp); - tg3_init_hw(tp); - spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); - tg3_netif_start(tp); - - return 0; - } - case ETHTOOL_GRXCSUM: { - struct ethtool_value edata = { ETHTOOL_GRXCSUM }; - - edata.data = - (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - case ETHTOOL_SRXCSUM: { - struct ethtool_value edata; - - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; + GET_REG32_LOOP(RX_CPU_BASE, 0x280); + GET_REG32_LOOP(TX_CPU_BASE, 0x280); + GET_REG32_LOOP(GRCMBOX_INTERRUPT_0, 0x110); + GET_REG32_LOOP(FTQ_RESET, 0x120); + GET_REG32_LOOP(MSGINT_MODE, 0x0c); + GET_REG32_1(DMAC_MODE); + GET_REG32_LOOP(GRC_MODE, 0x4c); + if (tp->tg3_flags & TG3_FLAG_NVRAM) + GET_REG32_LOOP(NVRAM_CMD, 0x24); - if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) { - if (edata.data != 0) - return -EINVAL; - return 0; - } +#undef __GET_REG32 +#undef GET_REG32_LOOP +#undef GET_REG32_1 - spin_lock_irq(&tp->lock); - if (edata.data) - tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS; - else - tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS; - spin_unlock_irq(&tp->lock); + spin_unlock(&tp->tx_lock); + spin_unlock_irq(&tp->lock); +} - return 0; - } - case ETHTOOL_GTXCSUM: { - struct ethtool_value edata = { ETHTOOL_GTXCSUM }; +static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct tg3 *tp = dev->priv; + + if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) || + tp->link_config.phy_is_low_power) + return -EAGAIN; - edata.data = - (tp->dev->features & NETIF_F_IP_CSUM) != 0; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - case ETHTOOL_STXCSUM: { - struct ethtool_value edata; + cmd->supported = (SUPPORTED_Autoneg); - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; + if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) + cmd->supported |= (SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full); + + if (tp->phy_id != PHY_ID_SERDES) + cmd->supported |= (SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_MII); + else + cmd->supported |= SUPPORTED_FIBRE; + + cmd->advertising = tp->link_config.advertising; + cmd->speed = tp->link_config.active_speed; + cmd->duplex = tp->link_config.active_duplex; + cmd->port = 0; + cmd->phy_address = PHY_ADDR; + cmd->transceiver = 0; + cmd->autoneg = tp->link_config.autoneg; + cmd->maxtxpkt = 0; + cmd->maxrxpkt = 0; + return 0; +} + +static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct tg3 *tp = dev->priv; + + if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) || + tp->link_config.phy_is_low_power) + return -EAGAIN; - if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) { - if (edata.data != 0) - return -EINVAL; - return 0; - } + spin_lock_irq(&tp->lock); + spin_lock(&tp->tx_lock); - if (edata.data) - tp->dev->features |= NETIF_F_IP_CSUM; - else - tp->dev->features &= ~NETIF_F_IP_CSUM; + tp->link_config.autoneg = cmd->autoneg; + if (cmd->autoneg == AUTONEG_ENABLE) { + tp->link_config.advertising = cmd->advertising; + tp->link_config.speed = SPEED_INVALID; + tp->link_config.duplex = DUPLEX_INVALID; + } else { + tp->link_config.speed = cmd->speed; + tp->link_config.duplex = cmd->duplex; + } + + tg3_setup_phy(tp, 1); + spin_unlock(&tp->tx_lock); + spin_unlock_irq(&tp->lock); + + return 0; +} + +static void tg3_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct tg3 *tp = dev->priv; + + strcpy(info->driver, DRV_MODULE_NAME); + strcpy(info->version, DRV_MODULE_VERSION); + strcpy(info->bus_info, pci_name(tp->pdev)); +} + +static void tg3_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct tg3 *tp = dev->priv; + + wol->supported = WAKE_MAGIC; + wol->wolopts = 0; + if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) + wol->wolopts = WAKE_MAGIC; + memset(&wol->sopass, 0, sizeof(wol->sopass)); +} + +static int tg3_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct tg3 *tp = dev->priv; + + if (wol->wolopts & ~WAKE_MAGIC) + return -EINVAL; + if ((wol->wolopts & WAKE_MAGIC) && + tp->phy_id == PHY_ID_SERDES && + !(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP)) + return -EINVAL; + + spin_lock_irq(&tp->lock); + if (wol->wolopts & WAKE_MAGIC) + tp->tg3_flags |= TG3_FLAG_WOL_ENABLE; + else + tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE; + spin_unlock_irq(&tp->lock); + + return 0; +} + +static u32 tg3_get_msglevel(struct net_device *dev) +{ + struct tg3 *tp = dev->priv; + return tp->msg_enable; +} + +static void tg3_set_msglevel(struct net_device *dev, u32 value) +{ + struct tg3 *tp = dev->priv; + tp->msg_enable = value; +} + +#if TG3_TSO_SUPPORT != 0 +static int tg3_set_tso(struct net_device *dev, u32 value) +{ + struct tg3 *tp = dev->priv; + if (!(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) { + if (value) + return -EINVAL; return 0; } - case ETHTOOL_GSG: { - struct ethtool_value edata = { ETHTOOL_GSG }; - - edata.data = - (tp->dev->features & NETIF_F_SG) != 0; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; + return ethtool_op_set_tso(dev, value); +} +#endif + +static int tg3_nway_reset(struct net_device *dev) +{ + struct tg3 *tp = dev->priv; + u32 bmcr; + int r; + + spin_lock_irq(&tp->lock); + tg3_readphy(tp, MII_BMCR, &bmcr); + tg3_readphy(tp, MII_BMCR, &bmcr); + r = -EINVAL; + if (bmcr & BMCR_ANENABLE) { + tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART); + r = 0; } - case ETHTOOL_SSG: { - struct ethtool_value edata; - - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - - if (edata.data) - tp->dev->features |= NETIF_F_SG; - else - tp->dev->features &= ~NETIF_F_SG; + spin_unlock_irq(&tp->lock); + + return r; +} + +static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) +{ + struct tg3 *tp = dev->priv; + + ering->rx_max_pending = TG3_RX_RING_SIZE - 1; + ering->rx_mini_max_pending = 0; + ering->rx_jumbo_max_pending = TG3_RX_JUMBO_RING_SIZE - 1; + + ering->rx_pending = tp->rx_pending; + ering->rx_mini_pending = 0; + ering->rx_jumbo_pending = tp->rx_jumbo_pending; + ering->tx_pending = tp->tx_pending; +} + +static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) +{ + struct tg3 *tp = dev->priv; + + if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) || + (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || + (ering->tx_pending > TG3_TX_RING_SIZE - 1)) + return -EINVAL; + + tg3_netif_stop(tp); + spin_lock_irq(&tp->lock); + spin_lock(&tp->tx_lock); + + tp->rx_pending = ering->rx_pending; - return 0; - } - }; + if ((tp->tg3_flags2 & TG3_FLG2_MAX_RXPEND_64) && + tp->rx_pending > 63) + tp->rx_pending = 63; + tp->rx_jumbo_pending = ering->rx_jumbo_pending; + tp->tx_pending = ering->tx_pending; - return -EOPNOTSUPP; + tg3_halt(tp); + tg3_init_hw(tp); + netif_wake_queue(tp->dev); + spin_unlock(&tp->tx_lock); + spin_unlock_irq(&tp->lock); + tg3_netif_start(tp); + + return 0; } + +static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) +{ + struct tg3 *tp = dev->priv; + + epause->autoneg = (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) != 0; + epause->rx_pause = (tp->tg3_flags & TG3_FLAG_PAUSE_RX) != 0; + epause->tx_pause = (tp->tg3_flags & TG3_FLAG_PAUSE_TX) != 0; +} + +static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) +{ + struct tg3 *tp = dev->priv; + + tg3_netif_stop(tp); + spin_lock_irq(&tp->lock); + spin_lock(&tp->tx_lock); + if (epause->autoneg) + tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; + else + tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG; + if (epause->rx_pause) + tp->tg3_flags |= TG3_FLAG_PAUSE_RX; + else + tp->tg3_flags &= ~TG3_FLAG_PAUSE_RX; + if (epause->tx_pause) + tp->tg3_flags |= TG3_FLAG_PAUSE_TX; + else + tp->tg3_flags &= ~TG3_FLAG_PAUSE_TX; + tg3_halt(tp); + tg3_init_hw(tp); + spin_unlock(&tp->tx_lock); + spin_unlock_irq(&tp->lock); + tg3_netif_start(tp); + + return 0; +} + +static u32 tg3_get_rx_csum(struct net_device *dev) +{ + struct tg3 *tp = dev->priv; + return (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0; +} + +static int tg3_set_rx_csum(struct net_device *dev, u32 data) +{ + struct tg3 *tp = dev->priv; + + if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) { + if (data != 0) + return -EINVAL; + return 0; + } + + spin_lock_irq(&tp->lock); + if (data) + tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS; + else + tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS; + spin_unlock_irq(&tp->lock); + + return 0; +} + +static int tg3_set_tx_csum(struct net_device *dev, u32 data) +{ + struct tg3 *tp = dev->priv; + + if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) { + if (data != 0) + return -EINVAL; + return 0; + } + + if (data) + dev->features |= NETIF_F_IP_CSUM; + else + dev->features &= ~NETIF_F_IP_CSUM; + return 0; +} + static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data; @@ -5513,8 +6110,6 @@ int err; switch(cmd) { - case SIOCETHTOOL: - return tg3_ethtool_ioctl(dev, (void *) ifr->ifr_data); case SIOCGMIIPHY: data->phy_id = PHY_ADDR; @@ -5578,12 +6173,43 @@ } #endif +static struct ethtool_ops tg3_ethtool_ops = { + .get_settings = tg3_get_settings, + .set_settings = tg3_set_settings, + .get_drvinfo = tg3_get_drvinfo, + .get_regs_len = tg3_get_regs_len, + .get_regs = tg3_get_regs, + .get_wol = tg3_get_wol, + .set_wol = tg3_set_wol, + .get_msglevel = tg3_get_msglevel, + .set_msglevel = tg3_set_msglevel, + .nway_reset = tg3_nway_reset, + .get_link = ethtool_op_get_link, + .get_ringparam = tg3_get_ringparam, + .set_ringparam = tg3_set_ringparam, + .get_pauseparam = tg3_get_pauseparam, + .set_pauseparam = tg3_set_pauseparam, + .get_rx_csum = tg3_get_rx_csum, + .set_rx_csum = tg3_set_rx_csum, + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = tg3_set_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, +#if TG3_TSO_SUPPORT != 0 + .get_tso = ethtool_op_get_tso, + .set_tso = tg3_set_tso, +#endif +}; + /* Chips other than 5700/5701 use the NVRAM for fetching info. */ static void __devinit tg3_nvram_init(struct tg3 *tp) { int j; - tw32(GRC_EEPROM_ADDR, + if (tp->tg3_flags2 & TG3_FLG2_SUN_5704) + return; + + tw32_f(GRC_EEPROM_ADDR, (EEPROM_ADDR_FSM_RESET | (EEPROM_DEFAULT_CLOCK_PERIOD << EEPROM_ADDR_CLKPERD_SHIFT))); @@ -5593,9 +6219,8 @@ udelay(10); /* Enable seeprom accesses. */ - tw32(GRC_LOCAL_CTRL, + tw32_f(GRC_LOCAL_CTRL, tr32(GRC_LOCAL_CTRL) | GRC_LCLCTRL_AUTO_SEEPROM); - tr32(GRC_LOCAL_CTRL); udelay(100); if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 && @@ -5655,6 +6280,11 @@ { int i, saw_done_clear; + if (tp->tg3_flags2 & TG3_FLG2_SUN_5704) { + printk(KERN_ERR PFX "Attempt to do nvram_read on Sun 5704\n"); + return -EINVAL; + } + if (!(tp->tg3_flags & TG3_FLAG_NVRAM)) return tg3_nvram_read_using_eeprom(tp, offset, val); @@ -5707,25 +6337,22 @@ static struct subsys_tbl_ent subsys_id_to_phy_id[] = { /* Broadcom boards. */ - { 0x14e4, 0x1644, PHY_ID_BCM5401 }, /* BCM95700A6 */ - { 0x14e4, 0x0001, PHY_ID_BCM5701 }, /* BCM95701A5 */ - { 0x14e4, 0x0002, PHY_ID_BCM8002 }, /* BCM95700T6 */ - { 0x14e4, 0x0003, PHY_ID_SERDES }, /* BCM95700A9 */ - { 0x14e4, 0x0005, PHY_ID_BCM5701 }, /* BCM95701T1 */ - { 0x14e4, 0x0006, PHY_ID_BCM5701 }, /* BCM95701T8 */ - { 0x14e4, 0x0007, PHY_ID_SERDES }, /* BCM95701A7 */ - { 0x14e4, 0x0008, PHY_ID_BCM5701 }, /* BCM95701A10 */ - { 0x14e4, 0x8008, PHY_ID_BCM5701 }, /* BCM95701A12 */ - { 0x14e4, 0x0009, PHY_ID_BCM5701 }, /* BCM95703Ax1 */ - { 0x14e4, 0x8009, PHY_ID_BCM5701 }, /* BCM95703Ax2 */ + { PCI_VENDOR_ID_BROADCOM, 0x1644, PHY_ID_BCM5401 }, /* BCM95700A6 */ + { PCI_VENDOR_ID_BROADCOM, 0x0001, PHY_ID_BCM5701 }, /* BCM95701A5 */ + { PCI_VENDOR_ID_BROADCOM, 0x0002, PHY_ID_BCM8002 }, /* BCM95700T6 */ + { PCI_VENDOR_ID_BROADCOM, 0x0003, PHY_ID_SERDES }, /* BCM95700A9 */ + { PCI_VENDOR_ID_BROADCOM, 0x0005, PHY_ID_BCM5701 }, /* BCM95701T1 */ + { PCI_VENDOR_ID_BROADCOM, 0x0006, PHY_ID_BCM5701 }, /* BCM95701T8 */ + { PCI_VENDOR_ID_BROADCOM, 0x0007, PHY_ID_SERDES }, /* BCM95701A7 */ + { PCI_VENDOR_ID_BROADCOM, 0x0008, PHY_ID_BCM5701 }, /* BCM95701A10 */ + { PCI_VENDOR_ID_BROADCOM, 0x8008, PHY_ID_BCM5701 }, /* BCM95701A12 */ + { PCI_VENDOR_ID_BROADCOM, 0x0009, PHY_ID_BCM5701 }, /* BCM95703Ax1 */ + { PCI_VENDOR_ID_BROADCOM, 0x8009, PHY_ID_BCM5701 }, /* BCM95703Ax2 */ /* 3com boards. */ { PCI_VENDOR_ID_3COM, 0x1000, PHY_ID_BCM5401 }, /* 3C996T */ { PCI_VENDOR_ID_3COM, 0x1006, PHY_ID_BCM5701 }, /* 3C996BT */ - /* { PCI_VENDOR_ID_3COM, 0x1002, PHY_ID_XXX }, 3C996CT */ - /* { PCI_VENDOR_ID_3COM, 0x1003, PHY_ID_XXX }, 3C997T */ { PCI_VENDOR_ID_3COM, 0x1004, PHY_ID_SERDES }, /* 3C996SX */ - /* { PCI_VENDOR_ID_3COM, 0x1005, PHY_ID_XXX }, 3C997SZ */ { PCI_VENDOR_ID_3COM, 0x1007, PHY_ID_BCM5701 }, /* 3C1000T */ { PCI_VENDOR_ID_3COM, 0x1008, PHY_ID_BCM5701 }, /* 3C940BR01 */ @@ -5740,7 +6367,10 @@ { PCI_VENDOR_ID_COMPAQ, 0x009a, PHY_ID_BCM5701 }, /* BANSHEE_2 */ { PCI_VENDOR_ID_COMPAQ, 0x007d, PHY_ID_SERDES }, /* CHANGELING */ { PCI_VENDOR_ID_COMPAQ, 0x0085, PHY_ID_BCM5701 }, /* NC7780 */ - { PCI_VENDOR_ID_COMPAQ, 0x0099, PHY_ID_BCM5701 } /* NC7780_2 */ + { PCI_VENDOR_ID_COMPAQ, 0x0099, PHY_ID_BCM5701 }, /* NC7780_2 */ + + /* IBM boards. */ + { PCI_VENDOR_ID_IBM, 0x0281, PHY_ID_SERDES } /* IBM??? */ }; static int __devinit tg3_phy_probe(struct tg3 *tp) @@ -5770,6 +6400,7 @@ u32 nic_cfg; tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg); + tp->nic_sram_data_cfg = nic_cfg; eeprom_signature_found = 1; @@ -5803,8 +6434,10 @@ eeprom_led_mode = led_mode_auto; break; }; - if ((tp->pci_chip_rev_id == CHIPREV_ID_5703_A1 || - tp->pci_chip_rev_id == CHIPREV_ID_5703_A2) && + + if (((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) && (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP)) tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; @@ -5886,9 +6519,7 @@ } /* Enable Ethernet@WireSpeed */ - tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x7007); - tg3_readphy(tp, MII_TG3_AUX_CTRL, &val); - tg3_writephy(tp, MII_TG3_AUX_CTRL, (val | (1 << 15) | (1 << 4))); + tg3_phy_set_wirespeed(tp); if (!err && ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401)) { err = tg3_init_5401phy_dsp(tp); @@ -5923,6 +6554,14 @@ unsigned char vpd_data[256]; int i; + if (tp->tg3_flags2 & TG3_FLG2_SUN_5704) { + /* Sun decided not to put the necessary bits in the + * NVRAM of their onboard tg3 parts :( + */ + strcpy(tp->board_part_number, "Sun 5704"); + return; + } + for (i = 0; i < 256; i += 4) { u32 tmp; @@ -5979,15 +6618,49 @@ strcpy(tp->board_part_number, "none"); } +#ifdef CONFIG_SPARC64 +static int __devinit tg3_is_sun_5704(struct tg3 *tp) +{ + struct pci_dev *pdev = tp->pdev; + struct pcidev_cookie *pcp = pdev->sysdata; + + if (pcp != NULL) { + int node = pcp->prom_node; + u32 venid, devid; + int err; + + err = prom_getproperty(node, "subsystem-vendor-id", + (char *) &venid, sizeof(venid)); + if (err == 0 || err == -1) + return 0; + err = prom_getproperty(node, "subsystem-id", + (char *) &devid, sizeof(devid)); + if (err == 0 || err == -1) + return 0; + + if (venid == PCI_VENDOR_ID_SUN && + devid == PCI_DEVICE_ID_TIGON3_5704) + return 1; + } + return 0; +} +#endif + static int __devinit tg3_get_invariants(struct tg3 *tp) { u32 misc_ctrl_reg; u32 cacheline_sz_reg; u32 pci_state_reg, grc_misc_cfg; + u32 val; u16 pci_cmd; int err; - /* If we have an AMD 762 or Intel ICH/ICH0 chipset, write +#ifdef CONFIG_SPARC64 + if (tg3_is_sun_5704(tp)) + tp->tg3_flags2 |= TG3_FLG2_SUN_5704; +#endif + + /* If we have an AMD 762 or Intel ICH/ICH0/ICH2 chipset, write * reordering to the mailbox registers done by the host * controller can cause major troubles. We read back from * every mailbox register write to force the writes to be @@ -5997,13 +6670,17 @@ PCI_DEVICE_ID_INTEL_82801AA_8, NULL) || pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_8, NULL) || + pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82801BA_11, NULL) || + pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82801BA_6, NULL) || pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, NULL)) tp->tg3_flags |= TG3_FLAG_MBOX_WRITE_REORDER; /* Force memory write invalidate off. If we leave it on, * then on 5700_BX chips we have to enable a workaround. - * The workaround is to set the TG3PCI_DMA_RW_CTRL boundry + * The workaround is to set the TG3PCI_DMA_RW_CTRL boundary * to match the cacheline size. The Broadcom driver have this * workaround but turns MWI off all the times so never uses * it. This seems to suggest that the workaround is insufficient. @@ -6145,7 +6822,21 @@ tp->tg3_flags |= TG3_FLAG_WOL_SPEED_100MB; } + /* A few boards don't want Ethernet@WireSpeed phy feature */ + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) || + ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) && + (tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) && + (tp->pci_chip_rev_id != CHIPREV_ID_5705_A1))) + tp->tg3_flags2 |= TG3_FLG2_NO_ETH_WIRE_SPEED; + + if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5703_AX || + GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5704_AX) + tp->tg3_flags2 |= TG3_FLG2_PHY_ADC_BUG; + if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0) + tp->tg3_flags2 |= TG3_FLG2_PHY_5704_A0_BUG; + /* Only 5701 and later support tagged irq status mode. + * Also, 5788 chips cannot use tagged irq status. * * However, since we are using NAPI avoid tagged irq status * because the interrupt condition is more difficult to @@ -6158,12 +6849,13 @@ tp->coalesce_mode |= HOSTCC_MODE_32BYTE; /* Initialize MAC MI mode, polling disabled. */ - tw32(MAC_MI_MODE, tp->mi_mode); - tr32(MAC_MI_MODE); + tw32_f(MAC_MI_MODE, tp->mi_mode); udelay(40); /* Initialize data/descriptor byte/word swapping. */ - tw32(GRC_MODE, tp->grc_mode); + val = tr32(GRC_MODE); + val &= GRC_MODE_HOST_STACKUP; + tw32(GRC_MODE, val | tp->grc_mode); tg3_switch_clocks(tp); @@ -6202,7 +6894,8 @@ /* Determine if TX descriptors will reside in * main memory or in the chip SRAM. */ - if (tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) + if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) tp->tg3_flags |= TG3_FLAG_HOST_TXDS; grc_misc_cfg = tr32(GRC_MISC_CFG); @@ -6214,8 +6907,19 @@ tp->split_mode_max_reqs = SPLIT_MODE_5704_MAX_REQ; } - /* this one is limited to 10/100 only */ - if (grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5702FE) + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && + (grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 || + grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M)) + tp->tg3_flags2 |= TG3_FLG2_IS_5788; + + /* these are limited to 10/100 only */ + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 && + (grc_misc_cfg == 0x8000 || grc_misc_cfg == 0x4000)) || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && + tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM && + (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901 || + tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901_2 || + tp->pdev->device == PCI_DEVICE_ID_TIGON3_5705F))) tp->tg3_flags |= TG3_FLAG_10_100_ONLY; err = tg3_phy_probe(tp); @@ -6295,11 +6999,44 @@ return err; } +#ifdef CONFIG_SPARC64 +static int __devinit tg3_get_macaddr_sparc(struct tg3 *tp) +{ + struct net_device *dev = tp->dev; + struct pci_dev *pdev = tp->pdev; + struct pcidev_cookie *pcp = pdev->sysdata; + + if (pcp != NULL) { + int node = pcp->prom_node; + + if (prom_getproplen(node, "local-mac-address") == 6) { + prom_getproperty(node, "local-mac-address", + dev->dev_addr, 6); + return 0; + } + } + return -ENODEV; +} + +static int __devinit tg3_get_default_macaddr_sparc(struct tg3 *tp) +{ + struct net_device *dev = tp->dev; + + memcpy(dev->dev_addr, idprom->id_ethaddr, 6); + return 0; +} +#endif + static int __devinit tg3_get_device_address(struct tg3 *tp) { struct net_device *dev = tp->dev; u32 hi, lo, mac_offset; +#ifdef CONFIG_SPARC64 + if (!tg3_get_macaddr_sparc(tp)) + return 0; +#endif + if (PCI_FUNC(tp->pdev->devfn) == 0) mac_offset = 0x7c; else @@ -6318,7 +7055,8 @@ dev->dev_addr[5] = (lo >> 0) & 0xff; } /* Next, try NVRAM. */ - else if (!tg3_nvram_read(tp, mac_offset + 0, &hi) && + else if (!(tp->tg3_flags & TG3_FLG2_SUN_5704) && + !tg3_nvram_read(tp, mac_offset + 0, &hi) && !tg3_nvram_read(tp, mac_offset + 4, &lo)) { dev->dev_addr[0] = ((hi >> 16) & 0xff); dev->dev_addr[1] = ((hi >> 24) & 0xff); @@ -6340,9 +7078,13 @@ dev->dev_addr[0] = (hi >> 8) & 0xff; } - if (!is_valid_ether_addr(&dev->dev_addr[0])) + if (!is_valid_ether_addr(&dev->dev_addr[0])) { +#ifdef CONFIG_SPARC64 + if (!tg3_get_default_macaddr_sparc(tp)) + return 0; +#endif return -EINVAL; - + } return 0; } @@ -6367,26 +7109,31 @@ test_desc.addr_lo = buf_dma & 0xffffffff; test_desc.nic_mbuf = 0x00002100; test_desc.len = size; + + /* + * HP ZX1 was seeing test failures for 5701 cards running at 33Mhz + * the *second* time the tg3 driver was getting loaded after an + * initial scan. + * + * Broadcom tells me: + * ...the DMA engine is connected to the GRC block and a DMA + * reset may affect the GRC block in some unpredictable way... + * The behavior of resets to individual blocks has not been tested. + * + * Broadcom noted the GRC reset will also reset all sub-components. + */ if (to_device) { test_desc.cqid_sqid = (13 << 8) | 2; - tw32(RDMAC_MODE, RDMAC_MODE_RESET); - tr32(RDMAC_MODE); - udelay(40); - tw32(RDMAC_MODE, RDMAC_MODE_ENABLE); - tr32(RDMAC_MODE); + tw32_f(RDMAC_MODE, RDMAC_MODE_ENABLE); udelay(40); } else { test_desc.cqid_sqid = (16 << 8) | 7; - tw32(WDMAC_MODE, WDMAC_MODE_RESET); - tr32(WDMAC_MODE); - udelay(40); - tw32(WDMAC_MODE, WDMAC_MODE_ENABLE); - tr32(WDMAC_MODE); + tw32_f(WDMAC_MODE, WDMAC_MODE_ENABLE); udelay(40); } - test_desc.flags = 0x00000004; + test_desc.flags = 0x00000005; for (i = 0; i < (sizeof(test_desc) / sizeof(u32)); i++) { u32 val; @@ -6437,8 +7184,6 @@ goto out_nofree; } - tw32(TG3PCI_CLOCK_CTRL, 0); - if ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) == 0) { tp->dma_rwctrl = (0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) | @@ -6446,7 +7191,9 @@ (0x7 << DMA_RWCTRL_WRITE_WATER_SHIFT) | (0x7 << DMA_RWCTRL_READ_WATER_SHIFT) | (0x0f << DMA_RWCTRL_MIN_DMA_SHIFT); - /* XXX 5705 note: set MIN_DMA to zero here */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) + tp->dma_rwctrl &= ~(DMA_RWCTRL_MIN_DMA + << DMA_RWCTRL_MIN_DMA_SHIFT); } else { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) tp->dma_rwctrl = @@ -6545,38 +7292,66 @@ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { /* Remove this if it causes problems for some boards. */ tp->dma_rwctrl |= DMA_RWCTRL_USE_MEM_READ_MULT; + + /* On 5700/5701 chips, we need to set this bit. + * Otherwise the chip will issue cacheline transactions + * to streamable DMA memory with not all the byte + * enables turned on. This is an error on several + * RISC PCI controllers, in particular sparc64. + * + * On 5703/5704 chips, this bit has been reassigned + * a different meaning. In particular, it is used + * on those chips to enable a PCI-X workaround. + */ + tp->dma_rwctrl |= DMA_RWCTRL_ASSERT_ALL_BE; } tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); +#if 0 + /* Unneeded, already done by tg3_get_invariants. */ + tg3_switch_clocks(tp); +#endif + ret = 0; if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) goto out; while (1) { - u32 *p, i; + u32 *p = buf, i; - p = buf; for (i = 0; i < TEST_BUFFER_SIZE / sizeof(u32); i++) p[i] = i; /* Send the buffer to the chip. */ ret = tg3_do_test_dma(tp, buf, buf_dma, TEST_BUFFER_SIZE, 1); - if (ret) + if (ret) { + printk(KERN_ERR "tg3_test_dma() Write the buffer failed %d\n", ret); break; + } - p = buf; - for (i = 0; i < TEST_BUFFER_SIZE / sizeof(u32); i++) +#if 0 + /* validate data reached card RAM correctly. */ + for (i = 0; i < TEST_BUFFER_SIZE / sizeof(u32); i++) { + u32 val; + tg3_read_mem(tp, 0x2100 + (i*4), &val); + if (le32_to_cpu(val) != p[i]) { + printk(KERN_ERR " tg3_test_dma() Card buffer corrupted on write! (%d != %d)\n", val, i); + /* ret = -ENODEV here? */ + } p[i] = 0; - + } +#endif /* Now read it back. */ ret = tg3_do_test_dma(tp, buf, buf_dma, TEST_BUFFER_SIZE, 0); - if (ret) + if (ret) { + printk(KERN_ERR "tg3_test_dma() Read the buffer failed %d\n", ret); + break; + } /* Verify it. */ - p = buf; for (i = 0; i < TEST_BUFFER_SIZE / sizeof(u32); i++) { if (p[i] == i) continue; @@ -6587,6 +7362,7 @@ tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); break; } else { + printk(KERN_ERR "tg3_test_dma() buffer corrupted on read back! (%d != %d)\n", p[i], i); ret = -ENODEV; goto out; } @@ -6653,12 +7429,35 @@ case PHY_ID_BCM5701: return "5701"; case PHY_ID_BCM5703: return "5703"; case PHY_ID_BCM5704: return "5704"; + case PHY_ID_BCM5705: return "5705"; case PHY_ID_BCM8002: return "8002"; case PHY_ID_SERDES: return "serdes"; default: return "unknown"; }; } +static struct pci_dev * __devinit tg3_find_5704_peer(struct tg3 *tp) +{ + struct pci_dev *peer = NULL; + unsigned int func; + + for (func = 0; func < 7; func++) { + unsigned int devfn = tp->pdev->devfn; + + devfn &= ~7; + devfn |= func; + + if (devfn == tp->pdev->devfn) + continue; + peer = pci_find_slot(tp->pdev->bus->number, devfn); + if (peer) + break; + } + if (!peer || peer == tp->pdev) + BUG(); + return peer; +} + static int __devinit tg3_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -6699,14 +7498,16 @@ if (pm_cap == 0) { printk(KERN_ERR PFX "Cannot find PowerManagement capability, " "aborting.\n"); + err = -EIO; goto err_out_free_res; } /* Configure DMA attributes. */ - if (!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff)) { + err = pci_set_dma_mask(pdev, 0xffffffffffffffffULL); + if (!err) { pci_using_dac = 1; } else { - err = pci_set_dma_mask(pdev, (u64) 0xffffffff); + err = pci_set_dma_mask(pdev, 0xffffffffULL); if (err) { printk(KERN_ERR PFX "No usable DMA configuration, " "aborting.\n"); @@ -6734,9 +7535,6 @@ dev->vlan_rx_register = tg3_vlan_rx_register; dev->vlan_rx_kill_vid = tg3_vlan_rx_kill_vid; #endif -#if TG3_DO_TSO != 0 - dev->features |= NETIF_F_TSO; -#endif tp = dev->priv; tp->pdev = pdev; @@ -6775,7 +7573,7 @@ spin_lock_init(&tp->lock); spin_lock_init(&tp->tx_lock); spin_lock_init(&tp->indirect_lock); - PREPARE_TQUEUE(&tp->reset_task, tg3_reset_task, tp); + INIT_TQUEUE(&tp->reset_task, tg3_reset_task, tp); tp->regs = (unsigned long) ioremap(tg3reg_base, tg3reg_len); if (tp->regs == 0UL) { @@ -6801,6 +7599,7 @@ dev->do_ioctl = tg3_ioctl; dev->tx_timeout = tg3_tx_timeout; dev->poll = tg3_poll; + dev->ethtool_ops = &tg3_ethtool_ops; dev->weight = 64; dev->watchdog_timeo = TG3_TX_TIMEOUT; dev->change_mtu = tg3_change_mtu; @@ -6813,6 +7612,44 @@ goto err_out_iounmap; } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + tp->bufmgr_config.mbuf_read_dma_low_water = + DEFAULT_MB_RDMA_LOW_WATER_5705; + tp->bufmgr_config.mbuf_mac_rx_low_water = + DEFAULT_MB_MACRX_LOW_WATER_5705; + tp->bufmgr_config.mbuf_high_water = + DEFAULT_MB_HIGH_WATER_5705; + } + +#if TG3_TSO_SUPPORT != 0 + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 || + tp->pci_chip_rev_id == CHIPREV_ID_5705_A0 || + (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0 || + (tp->tg3_flags2 & TG3_FLG2_IS_5788)) { + tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE; + } else { + tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; + } + + /* TSO is off by default, user can enable using ethtool. */ +#if 0 + if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) + dev->features |= NETIF_F_TSO; +#endif + +#endif + + if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 && + !(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) && + !(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH)) { + tp->tg3_flags2 |= TG3_FLG2_MAX_RXPEND_64; + tp->rx_pending = 63; + } + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) + tp->pdev_peer = tg3_find_5704_peer(tp); + err = tg3_get_device_address(tp); if (err) { printk(KERN_ERR PFX "Could not obtain valid ethernet address, " @@ -6820,6 +7657,18 @@ goto err_out_iounmap; } + /* + * Reset chip in case UNDI or EFI driver did not shutdown + * DMA self test will enable WDMAC and we'll see (spurious) + * pending DMA on the PCI bus at that point. + */ + if ((tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE) || + (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { + pci_save_state(tp->pdev, tp->pci_cfg_state); + tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); + tg3_halt(tp); + } + err = tg3_test_dma(tp); if (err) { printk(KERN_ERR PFX "DMA engine test failed, aborting.\n"); @@ -6835,6 +7684,9 @@ } else tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS; + if (tp->tg3_flags2 & TG3_FLG2_IS_5788) + dev->features &= ~NETIF_F_HIGHDMA; + err = register_netdev(dev); if (err) { printk(KERN_ERR PFX "Cannot register net device, " @@ -6908,6 +7760,8 @@ tg3_netif_stop(tp); + del_timer_sync(&tp->timer); + spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); tg3_disable_ints(tp); @@ -6927,9 +7781,11 @@ spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); - tg3_init_rings(tp); tg3_init_hw(tp); + tp->timer.expires = jiffies + tp->timer_offset; + add_timer(&tp->timer); + spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); @@ -6958,8 +7814,11 @@ spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); - tg3_init_rings(tp); tg3_init_hw(tp); + + tp->timer.expires = jiffies + tp->timer_offset; + add_timer(&tp->timer); + tg3_enable_ints(tp); spin_unlock(&tp->tx_lock); Index: drivers/net/tg3.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/tg3.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/tg3.h 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/tg3.h 4 Aug 2004 01:29:12 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: tg3.h,v 1.1 2004/07/22 19:49:31 joff Exp $ +/* $Id: tg3.h,v 1.2 2004/08/04 01:29:12 joff Exp $ * tg3.h: Definitions for Broadcom Tigon3 ethernet driver. * * Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com) @@ -24,6 +24,7 @@ #define RX_COPY_THRESHOLD 256 #define RX_STD_MAX_SIZE 1536 +#define RX_STD_MAX_SIZE_5705 512 #define RX_JUMBO_MAX_SIZE 0xdeadbeef /* XXX */ /* First 256 bytes are a mirror of PCI config space. */ @@ -59,7 +60,7 @@ #define PCIX_CAPS_SPLIT_SHIFT 20 #define PCIX_CAPS_BURST_MASK 0x000c0000 #define PCIX_CAPS_BURST_SHIFT 18 -#define PCIX_CAPS_MAX_BURST_5704 2 +#define PCIX_CAPS_MAX_BURST_CPIOB 2 #define TG3PCI_PM_CAP_PTR 0x00000041 #define TG3PCI_X_COMMAND 0x00000042 #define TG3PCI_X_STATUS 0x00000044 @@ -115,16 +116,22 @@ #define CHIPREV_ID_5704_A0 0x2000 #define CHIPREV_ID_5704_A1 0x2001 #define CHIPREV_ID_5704_A2 0x2002 +#define CHIPREV_ID_5705_A0 0x3000 +#define CHIPREV_ID_5705_A1 0x3001 #define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12) #define ASIC_REV_5700 0x07 #define ASIC_REV_5701 0x00 #define ASIC_REV_5703 0x01 #define ASIC_REV_5704 0x02 +#define ASIC_REV_5705 0x03 #define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8) #define CHIPREV_5700_AX 0x70 #define CHIPREV_5700_BX 0x71 #define CHIPREV_5700_CX 0x72 #define CHIPREV_5701_AX 0x00 +#define CHIPREV_5703_AX 0x10 +#define CHIPREV_5704_AX 0x20 +#define CHIPREV_5704_BX 0x21 #define GET_METAL_REV(CHIP_REV_ID) ((CHIP_REV_ID) & 0xff) #define METAL_REV_A0 0x00 #define METAL_REV_A1 0x01 @@ -180,6 +187,9 @@ #define CLOCK_CTRL_ALTCLK 0x00001000 #define CLOCK_CTRL_PWRDOWN_PLL133 0x00008000 #define CLOCK_CTRL_44MHZ_CORE 0x00040000 +#define CLOCK_CTRL_625_CORE 0x00100000 +#define CLOCK_CTRL_FORCE_CLKRUN 0x00200000 +#define CLOCK_CTRL_CLKRUN_OENABLE 0x00400000 #define CLOCK_CTRL_DELAY_PCI_GRANT 0x80000000 #define TG3PCI_REG_BASE_ADDR 0x00000078 #define TG3PCI_MEM_WIN_BASE_ADDR 0x0000007c @@ -457,17 +467,89 @@ #define MAC_RCV_RULE_CFG 0x00000500 #define RCV_RULE_CFG_DEFAULT_CLASS 0x00000008 #define MAC_LOW_WMARK_MAX_RX_FRAME 0x00000504 -/* 0x504 --> 0x590 unused */ +/* 0x508 --> 0x520 unused */ +#define MAC_HASHREGU_0 0x00000520 +#define MAC_HASHREGU_1 0x00000524 +#define MAC_HASHREGU_2 0x00000528 +#define MAC_HASHREGU_3 0x0000052c +#define MAC_EXTADDR_0_HIGH 0x00000530 +#define MAC_EXTADDR_0_LOW 0x00000534 +#define MAC_EXTADDR_1_HIGH 0x00000538 +#define MAC_EXTADDR_1_LOW 0x0000053c +#define MAC_EXTADDR_2_HIGH 0x00000540 +#define MAC_EXTADDR_2_LOW 0x00000544 +#define MAC_EXTADDR_3_HIGH 0x00000548 +#define MAC_EXTADDR_3_LOW 0x0000054c +#define MAC_EXTADDR_4_HIGH 0x00000550 +#define MAC_EXTADDR_4_LOW 0x00000554 +#define MAC_EXTADDR_5_HIGH 0x00000558 +#define MAC_EXTADDR_5_LOW 0x0000055c +#define MAC_EXTADDR_6_HIGH 0x00000560 +#define MAC_EXTADDR_6_LOW 0x00000564 +#define MAC_EXTADDR_7_HIGH 0x00000568 +#define MAC_EXTADDR_7_LOW 0x0000056c +#define MAC_EXTADDR_8_HIGH 0x00000570 +#define MAC_EXTADDR_8_LOW 0x00000574 +#define MAC_EXTADDR_9_HIGH 0x00000578 +#define MAC_EXTADDR_9_LOW 0x0000057c +#define MAC_EXTADDR_10_HIGH 0x00000580 +#define MAC_EXTADDR_10_LOW 0x00000584 +#define MAC_EXTADDR_11_HIGH 0x00000588 +#define MAC_EXTADDR_11_LOW 0x0000058c #define MAC_SERDES_CFG 0x00000590 #define MAC_SERDES_STAT 0x00000594 /* 0x598 --> 0x600 unused */ #define MAC_TX_MAC_STATE_BASE 0x00000600 /* 16 bytes */ #define MAC_RX_MAC_STATE_BASE 0x00000610 /* 20 bytes */ /* 0x624 --> 0x800 unused */ -#define MAC_RX_STATS_BASE 0x00000800 /* 26 32-bit words */ -/* 0x868 --> 0x880 unused */ -#define MAC_TX_STATS_BASE 0x00000880 /* 28 32-bit words */ -/* 0x8f0 --> 0xc00 unused */ +#define MAC_TX_STATS_OCTETS 0x00000800 +#define MAC_TX_STATS_RESV1 0x00000804 +#define MAC_TX_STATS_COLLISIONS 0x00000808 +#define MAC_TX_STATS_XON_SENT 0x0000080c +#define MAC_TX_STATS_XOFF_SENT 0x00000810 +#define MAC_TX_STATS_RESV2 0x00000814 +#define MAC_TX_STATS_MAC_ERRORS 0x00000818 +#define MAC_TX_STATS_SINGLE_COLLISIONS 0x0000081c +#define MAC_TX_STATS_MULT_COLLISIONS 0x00000820 +#define MAC_TX_STATS_DEFERRED 0x00000824 +#define MAC_TX_STATS_RESV3 0x00000828 +#define MAC_TX_STATS_EXCESSIVE_COL 0x0000082c +#define MAC_TX_STATS_LATE_COL 0x00000830 +#define MAC_TX_STATS_RESV4_1 0x00000834 +#define MAC_TX_STATS_RESV4_2 0x00000838 +#define MAC_TX_STATS_RESV4_3 0x0000083c +#define MAC_TX_STATS_RESV4_4 0x00000840 +#define MAC_TX_STATS_RESV4_5 0x00000844 +#define MAC_TX_STATS_RESV4_6 0x00000848 +#define MAC_TX_STATS_RESV4_7 0x0000084c +#define MAC_TX_STATS_RESV4_8 0x00000850 +#define MAC_TX_STATS_RESV4_9 0x00000854 +#define MAC_TX_STATS_RESV4_10 0x00000858 +#define MAC_TX_STATS_RESV4_11 0x0000085c +#define MAC_TX_STATS_RESV4_12 0x00000860 +#define MAC_TX_STATS_RESV4_13 0x00000864 +#define MAC_TX_STATS_RESV4_14 0x00000868 +#define MAC_TX_STATS_UCAST 0x0000086c +#define MAC_TX_STATS_MCAST 0x00000870 +#define MAC_TX_STATS_BCAST 0x00000874 +#define MAC_TX_STATS_RESV5_1 0x00000878 +#define MAC_TX_STATS_RESV5_2 0x0000087c +#define MAC_RX_STATS_OCTETS 0x00000880 +#define MAC_RX_STATS_RESV1 0x00000884 +#define MAC_RX_STATS_FRAGMENTS 0x00000888 +#define MAC_RX_STATS_UCAST 0x0000088c +#define MAC_RX_STATS_MCAST 0x00000890 +#define MAC_RX_STATS_BCAST 0x00000894 +#define MAC_RX_STATS_FCS_ERRORS 0x00000898 +#define MAC_RX_STATS_ALIGN_ERRORS 0x0000089c +#define MAC_RX_STATS_XON_PAUSE_RECVD 0x000008a0 +#define MAC_RX_STATS_XOFF_PAUSE_RECVD 0x000008a4 +#define MAC_RX_STATS_MAC_CTRL_RECVD 0x000008a8 +#define MAC_RX_STATS_XOFF_ENTERED 0x000008ac +#define MAC_RX_STATS_FRAME_TOO_LONG 0x000008b0 +#define MAC_RX_STATS_JABBERS 0x000008b4 +#define MAC_RX_STATS_UNDERSIZE 0x000008b8 +/* 0x8bc --> 0xc00 unused */ /* Send data initiator control registers */ #define SNDDATAI_MODE 0x00000c00 @@ -599,6 +681,7 @@ #define RCVLPC_STATSCTRL_ENABLE 0x00000001 #define RCVLPC_STATSCTRL_FASTUPD 0x00000002 #define RCVLPC_STATS_ENABLE 0x00002018 +#define RCVLPC_STATSENAB_LNGBRST_RFIX 0x00400000 #define RCVLPC_STATS_INCMASK 0x0000201c /* 0x2020 --> 0x2100 unused */ #define RCVLPC_SELLST_BASE 0x00002100 /* 16 16-byte entries */ @@ -812,13 +895,16 @@ #define BUFMGR_MB_POOL_ADDR 0x00004408 #define BUFMGR_MB_POOL_SIZE 0x0000440c #define BUFMGR_MB_RDMA_LOW_WATER 0x00004410 -#define DEFAULT_MB_RDMA_LOW_WATER 0x00000040 +#define DEFAULT_MB_RDMA_LOW_WATER 0x00000050 +#define DEFAULT_MB_RDMA_LOW_WATER_5705 0x00000000 #define DEFAULT_MB_RDMA_LOW_WATER_JUMBO 0x00000130 #define BUFMGR_MB_MACRX_LOW_WATER 0x00004414 #define DEFAULT_MB_MACRX_LOW_WATER 0x00000020 +#define DEFAULT_MB_MACRX_LOW_WATER_5705 0x00000010 #define DEFAULT_MB_MACRX_LOW_WATER_JUMBO 0x00000098 #define BUFMGR_MB_HIGH_WATER 0x00004418 #define DEFAULT_MB_HIGH_WATER 0x00000060 +#define DEFAULT_MB_HIGH_WATER_5705 0x00000060 #define DEFAULT_MB_HIGH_WATER_JUMBO 0x0000017c #define BUFMGR_RX_MB_ALLOC_REQ 0x0000441c #define BUFMGR_MB_ALLOC_BIT 0x10000000 @@ -854,6 +940,8 @@ #define RDMAC_MODE_LNGREAD_ENAB 0x00000200 #define RDMAC_MODE_SPLIT_ENABLE 0x00000800 #define RDMAC_MODE_SPLIT_RESET 0x00001000 +#define RDMAC_MODE_FIFO_SIZE_128 0x00020000 +#define RDMAC_MODE_FIFO_LONG_BURST 0x00030000 #define RDMAC_STATUS 0x00004804 #define RDMAC_STATUS_TGTABORT 0x00000004 #define RDMAC_STATUS_MSTABORT 0x00000008 @@ -877,6 +965,7 @@ #define WDMAC_MODE_FIFOURUN_ENAB 0x00000080 #define WDMAC_MODE_FIFOOREAD_ENAB 0x00000100 #define WDMAC_MODE_LNGREAD_ENAB 0x00000200 +#define WDMAC_MODE_RX_ACCEL 0x00000400 #define WDMAC_STATUS 0x00004c04 #define WDMAC_STATUS_TGTABORT 0x00000004 #define WDMAC_STATUS_MSTABORT 0x00000008 @@ -1140,7 +1229,10 @@ #define GRC_MISC_CFG_BOARD_ID_5704 0x00000000 #define GRC_MISC_CFG_BOARD_ID_5704CIOBE 0x00004000 #define GRC_MISC_CFG_BOARD_ID_5704_A2 0x00008000 +#define GRC_MISC_CFG_BOARD_ID_5788 0x00010000 +#define GRC_MISC_CFG_BOARD_ID_5788M 0x00018000 #define GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000 +#define GRC_MISC_CFG_KEEP_GPHY_POWER 0x04000000 #define GRC_LOCAL_CTRL 0x00006808 #define GRC_LCLCTRL_INT_ACTIVE 0x00000001 #define GRC_LCLCTRL_CLEARINT 0x00000002 @@ -1275,6 +1367,7 @@ #define NIC_SRAM_DATA_CFG_WOL_ENABLE 0x00000040 #define NIC_SRAM_DATA_CFG_ASF_ENABLE 0x00000080 #define NIC_SRAM_DATA_CFG_EEPROM_WP 0x00000100 +#define NIC_SRAM_DATA_CFG_MINI_PCI 0x00001000 #define NIC_SRAM_DATA_CFG_FIBER_WOL 0x00004000 #define NIC_SRAM_DATA_PHY_ID 0x00000b74 @@ -1312,6 +1405,8 @@ #define NIC_SRAM_MBUF_POOL_BASE 0x00008000 #define NIC_SRAM_MBUF_POOL_SIZE96 0x00018000 #define NIC_SRAM_MBUF_POOL_SIZE64 0x00010000 +#define NIC_SRAM_MBUF_POOL_BASE5705 0x00010000 +#define NIC_SRAM_MBUF_POOL_SIZE5705 0x0000e000 /* Currently this is fixed. */ #define PHY_ADDR 0x01 @@ -1797,7 +1892,11 @@ #define TG3_FLAG_ENABLE_ASF 0x00000020 #define TG3_FLAG_5701_REG_WRITE_BUG 0x00000040 #define TG3_FLAG_POLL_SERDES 0x00000080 +#if defined(CONFIG_X86) #define TG3_FLAG_MBOX_WRITE_REORDER 0x00000100 +#else +#define TG3_FLAG_MBOX_WRITE_REORDER 0 /* disables code too */ +#endif #define TG3_FLAG_PCIX_TARGET_HWBUG 0x00000200 #define TG3_FLAG_WOL_SPEED_100MB 0x00000400 #define TG3_FLAG_WOL_ENABLE 0x00000800 @@ -1823,6 +1922,13 @@ #define TG3_FLAG_INIT_COMPLETE 0x80000000 u32 tg3_flags2; #define TG3_FLG2_RESTART_TIMER 0x00000001 +#define TG3_FLG2_SUN_5704 0x00000002 +#define TG3_FLG2_NO_ETH_WIRE_SPEED 0x00000004 +#define TG3_FLG2_IS_5788 0x00000008 +#define TG3_FLG2_MAX_RXPEND_64 0x00000010 +#define TG3_FLG2_TSO_CAPABLE 0x00000020 +#define TG3_FLG2_PHY_ADC_BUG 0x00000040 +#define TG3_FLG2_PHY_5704_A0_BUG 0x00000080 u32 split_mode_max_reqs; #define SPLIT_MODE_5704_MAX_REQ 3 @@ -1867,6 +1973,7 @@ #define PHY_ID_BCM5701 0x60008110 #define PHY_ID_BCM5703 0x60008160 #define PHY_ID_BCM5704 0x60008190 +#define PHY_ID_BCM5705 0x600081a0 #define PHY_ID_BCM8002 0x60010140 #define PHY_ID_SERDES 0xfeedbee0 #define PHY_ID_INVALID 0xffffffff @@ -1879,6 +1986,9 @@ enum phy_led_mode led_mode; char board_part_number[24]; + u32 nic_sram_data_cfg; + u32 pci_clock_ctrl; + struct pci_dev *pdev_peer; /* This macro assumes the passed PHY ID is already masked * with PHY_ID_MASK. @@ -1887,6 +1997,7 @@ ((X) == PHY_ID_BCM5400 || (X) == PHY_ID_BCM5401 || \ (X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \ (X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \ + (X) == PHY_ID_BCM5705 || \ (X) == PHY_ID_BCM8002 || (X) == PHY_ID_SERDES) struct tg3_hw_stats *hw_stats; Index: drivers/net/tlan.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/tlan.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/tlan.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/tlan.c 4 Aug 2004 01:29:12 -0000 1.2 @@ -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 && pci_enable_device(pdev)) - return -EIO; + if (pdev) { + rc = pci_enable_device(pdev); + if (rc) + return rc; + + 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; @@ -836,7 +881,9 @@ err ); } dev->addr_len = 6; - + + netif_carrier_off(dev); + /* Device methods */ dev->open = &TLan_Open; dev->hard_start_xmit = &TLan_StartTx; @@ -1003,6 +1050,7 @@ { TLanPrivateInfo *priv = dev->priv; TLanList *tail_list; + dma_addr_t tail_list_phys; u8 *tail_buffer; int pad; unsigned long flags; @@ -1014,6 +1062,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 +1077,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 +1087,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 +1100,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 +1393,7 @@ TLanPrivateInfo *priv = dev->priv; int eoc = 0; TLanList *head_list; + dma_addr_t head_list_phys; u32 ack = 0; u16 tmpCStat; @@ -1353,7 +1403,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 +1427,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 +1522,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 +1554,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 +1574,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 +1584,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 +1601,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 +1668,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 +1681,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 +1742,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 +1791,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 +1803,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 +1946,7 @@ TLanPrivateInfo *priv = dev->priv; int i; TLanList *list; + dma_addr_t list_phys; struct sk_buff *skb; void *t = NULL; @@ -1897,12 +1956,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 +1970,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 +1986,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 +2011,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 */ @@ -2143,6 +2207,8 @@ priv->tlanFullDuplex = FALSE; priv->phyOnline=0; + netif_carrier_off(dev); + /* 1. Assert reset bit. */ data = inl(dev->base_addr + TLAN_HOST_CMD); @@ -2271,8 +2337,8 @@ printk("TLAN: Partner capability: "); for (i = 5; i <= 10; i++) if (partner & (1<base_addr, TLAN_LED_REG, TLAN_LED_LINK ); @@ -2304,8 +2370,9 @@ 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 ); + netif_carrier_on(dev); } else { printk( "TLAN: %s: Link inactive, will retry in 10 secs...\n", dev->name ); TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_FINISH_RESET ); @@ -2376,7 +2443,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 +2559,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 +2579,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 +2694,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 ); Index: drivers/net/tlan.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/tlan.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/tlan.h 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/tlan.h 4 Aug 2004 01:29:12 -0000 1.2 @@ -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; Index: drivers/net/tun.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/tun.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/tun.c 22 Jul 2004 19:49:31 -0000 1.1 +++ drivers/net/tun.c 4 Aug 2004 01:29:12 -0000 1.2 @@ -12,7 +12,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * $Id: tun.c,v 1.1 2004/07/22 19:49:31 joff Exp $ + * $Id: tun.c,v 1.2 2004/08/04 01:29:12 joff Exp $ */ /* Index: drivers/net/typhoon-firmware.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/typhoon-firmware.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/typhoon-firmware.h 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/typhoon-firmware.h 4 Aug 2004 01:29:12 -0000 1.2 @@ -1,7 +1,7 @@ /* - * Copyright 1999-2002 3Com Corporation. All Rights Reserved. + * Copyright 1999-2003 3Com Corporation. All Rights Reserved. * - * Redistribution and use in source and binary forms of the 3CR990img.h + * Redistribution and use in source and binary forms of the 3c990img.h * microcode software are permitted provided that the following conditions * are met: * 1. Redistribution of source code must retain the above copyright @@ -23,385 +23,394 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * USER ACKNOWLEDGES AND AGREES THAT PURCHASE OR USE OF THE 3CR990img.h + * USER ACKNOWLEDGES AND AGREES THAT PURCHASE OR USE OF THE 3c990img.h * MICROCODE 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 3COM HARDWARE OR SOFTWARE EITHER SOLELY OR IN - * COMBINATION WITH THE 3CR990img.h microcode SOFTWARE + * COMBINATION WITH THE 3c990img.h MICROCODE SOFTWARE */ + const u8 typhoon_firmware_image[] = { 0x54, 0x59, 0x50, 0x48, 0x4f, 0x4f, 0x4e, 0x00, 0x02, 0x00, 0x00, 0x00, -0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x40, 0x01, 0x00, 0x00, -0x6c, 0xef, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x39, 0x00, 0x00, 0xea, -0x05, 0x00, 0x00, 0xea, 0x04, 0x00, 0x00, 0xea, 0x03, 0x00, 0x00, 0xea, -0x02, 0x00, 0x00, 0xea, 0x01, 0x00, 0x00, 0xea, 0x32, 0x02, 0x00, 0xea, -0xa5, 0x14, 0x00, 0xea, 0x07, 0x00, 0x2d, 0xe9, 0x0e, 0x00, 0xa0, 0xe1, -0x00, 0x10, 0x0f, 0xe1, 0xd0, 0x20, 0x9f, 0xe5, 0x12, 0xff, 0x2f, 0xe1, -0xfe, 0xff, 0xff, 0xea, 0x01, 0x00, 0x80, 0xe0, 0x04, 0x20, 0x81, 0xe4, -0x01, 0x00, 0x50, 0xe1, 0xfc, 0xff, 0xff, 0x1a, 0x0e, 0xf0, 0xa0, 0xe1, -0x00, 0xa0, 0xa0, 0xe1, 0x0e, 0xb0, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, -0xa8, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0x81, 0xe5, 0xa4, 0x10, 0x9f, 0xe5, -0x00, 0x00, 0x81, 0xe5, 0x01, 0x16, 0xa0, 0xe3, 0x00, 0x00, 0x91, 0xe5, -0x01, 0x00, 0x80, 0xe3, 0x00, 0x00, 0x81, 0xe5, 0xd7, 0x00, 0xa0, 0xe3, -0x00, 0xf0, 0x21, 0xe1, 0x88, 0xd0, 0x9f, 0xe5, 0xdb, 0x00, 0xa0, 0xe3, -0x00, 0xf0, 0x21, 0xe1, 0x7c, 0xd0, 0x9f, 0xe5, 0xd2, 0x00, 0xa0, 0xe3, -0x00, 0xf0, 0x21, 0xe1, 0x74, 0xd0, 0x9f, 0xe5, 0xd1, 0x00, 0xa0, 0xe3, -0x00, 0xf0, 0x21, 0xe1, 0x6c, 0xd0, 0x9f, 0xe5, 0x7b, 0x14, 0x00, 0xeb, -0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x60, 0xd0, 0x9f, 0xe5, -0x60, 0x00, 0x9f, 0xe5, 0x60, 0x10, 0x9f, 0xe5, 0x60, 0x20, 0x9f, 0xe5, -0xdb, 0xff, 0xff, 0xeb, 0x5c, 0x00, 0x9f, 0xe5, 0x5c, 0x10, 0x9f, 0xe5, -0x00, 0x20, 0xa0, 0xe3, 0xd7, 0xff, 0xff, 0xeb, 0x54, 0x00, 0x9f, 0xe5, -0x54, 0x10, 0x9f, 0xe5, 0xd4, 0xff, 0xff, 0xeb, 0x0a, 0x00, 0xa0, 0xe1, -0x0b, 0xf0, 0xa0, 0xe1, 0xd3, 0x10, 0xa0, 0xe3, 0x01, 0xf0, 0x21, 0xe1, -0xd4, 0xff, 0xff, 0xeb, 0x3c, 0xa0, 0x9f, 0xe5, 0x1a, 0xff, 0x2f, 0xe1, -0xc6, 0xff, 0xff, 0xea, 0xbd, 0x20, 0xff, 0xff, 0x0c, 0x00, 0x10, 0x00, -0x1c, 0x00, 0x10, 0x00, 0x3c, 0x38, 0x00, 0x80, 0xfc, 0x37, 0x00, 0x80, -0xfc, 0x3f, 0x00, 0x80, 0x7c, 0x34, 0x00, 0x80, 0x80, 0x0f, 0x00, 0x00, -0x80, 0x30, 0x00, 0x80, 0xad, 0xde, 0xad, 0xde, 0xa8, 0xbc, 0x00, 0x00, -0x24, 0xab, 0x20, 0x40, 0x34, 0x29, 0x00, 0x00, 0xa8, 0x04, 0x00, 0x80, -0x6d, 0xc8, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xd8, 0x56, 0x00, 0x00, 0x06, 0x24, 0x00, 0x00, -0x60, 0x01, 0xff, 0xff, 0xb0, 0xb5, 0x07, 0x1c, 0x12, 0x4c, 0x00, 0x25, -0xe0, 0x6b, 0x00, 0x28, 0x1d, 0xd0, 0x38, 0x1c, 0x10, 0x49, 0x04, 0xf0, -0x37, 0xfd, 0xe1, 0x6b, 0xc0, 0x46, 0x08, 0x60, 0x00, 0x28, 0x14, 0xd0, -0x38, 0x01, 0x0d, 0x49, 0x40, 0x18, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, -0x41, 0x6b, 0x80, 0x29, 0x0b, 0xd2, 0x01, 0x31, 0x41, 0x63, 0xe0, 0x6b, -0xc1, 0x69, 0xc0, 0x46, 0xe1, 0x63, 0x39, 0x07, 0x41, 0x60, 0xc7, 0x62, -0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x28, 0x1c, 0xfa, 0xe7, 0x00, 0x00, -0x28, 0x17, 0x00, 0x80, 0xee, 0x05, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x80, -0x02, 0x49, 0xca, 0x6b, 0xc0, 0x46, 0xc2, 0x61, 0xc8, 0x63, 0x70, 0x47, -0x28, 0x17, 0x00, 0x80, 0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, -0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe1, -0x00, 0x10, 0xa0, 0xe1, 0xc0, 0x10, 0x81, 0xe3, 0x01, 0xf0, 0x21, 0xe1, -0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, -0x00, 0x00, 0x0f, 0xe1, 0xc0, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x21, 0xe1, -0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, 0xc0, 0x00, 0xc0, 0xe3, +0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xbf, 0xcd, 0x57, 0xc3, +0xba, 0x01, 0x2c, 0xe8, 0xcd, 0xef, 0xa9, 0xd9, 0x6f, 0xbb, 0x76, 0x2f, +0x86, 0x49, 0xac, 0x1b, 0x40, 0x01, 0x00, 0x00, 0x8a, 0xe4, 0x00, 0x00, +0x00, 0x00, 0xff, 0xff, 0x39, 0x00, 0x00, 0xea, 0x05, 0x00, 0x00, 0xea, +0x04, 0x00, 0x00, 0xea, 0x03, 0x00, 0x00, 0xea, 0x02, 0x00, 0x00, 0xea, +0x01, 0x00, 0x00, 0xea, 0x32, 0x02, 0x00, 0xea, 0xc0, 0x14, 0x00, 0xea, +0x07, 0x00, 0x2d, 0xe9, 0x0e, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0x0f, 0xe1, +0xd0, 0x20, 0x9f, 0xe5, 0x12, 0xff, 0x2f, 0xe1, 0xfe, 0xff, 0xff, 0xea, +0x01, 0x00, 0x80, 0xe0, 0x04, 0x20, 0x81, 0xe4, 0x01, 0x00, 0x50, 0xe1, +0xfc, 0xff, 0xff, 0x1a, 0x0e, 0xf0, 0xa0, 0xe1, 0x00, 0xa0, 0xa0, 0xe1, +0x0e, 0xb0, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0xa8, 0x10, 0x9f, 0xe5, +0x00, 0x00, 0x81, 0xe5, 0xa4, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0x81, 0xe5, +0x01, 0x16, 0xa0, 0xe3, 0x00, 0x00, 0x91, 0xe5, 0x01, 0x00, 0x80, 0xe3, +0x00, 0x00, 0x81, 0xe5, 0xd7, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, +0x88, 0xd0, 0x9f, 0xe5, 0xdb, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, +0x7c, 0xd0, 0x9f, 0xe5, 0xd2, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, +0x74, 0xd0, 0x9f, 0xe5, 0xd1, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, +0x6c, 0xd0, 0x9f, 0xe5, 0x96, 0x14, 0x00, 0xeb, 0xd3, 0x00, 0xa0, 0xe3, +0x00, 0xf0, 0x21, 0xe1, 0x60, 0xd0, 0x9f, 0xe5, 0x60, 0x00, 0x9f, 0xe5, +0x60, 0x10, 0x9f, 0xe5, 0x60, 0x20, 0x9f, 0xe5, 0xdb, 0xff, 0xff, 0xeb, +0x5c, 0x00, 0x9f, 0xe5, 0x5c, 0x10, 0x9f, 0xe5, 0x00, 0x20, 0xa0, 0xe3, +0xd7, 0xff, 0xff, 0xeb, 0x54, 0x00, 0x9f, 0xe5, 0x54, 0x10, 0x9f, 0xe5, +0xd4, 0xff, 0xff, 0xeb, 0x0a, 0x00, 0xa0, 0xe1, 0x0b, 0xf0, 0xa0, 0xe1, +0xd3, 0x10, 0xa0, 0xe3, 0x01, 0xf0, 0x21, 0xe1, 0xd4, 0xff, 0xff, 0xeb, +0x3c, 0xa0, 0x9f, 0xe5, 0x1a, 0xff, 0x2f, 0xe1, 0xc6, 0xff, 0xff, 0xea, +0x01, 0x21, 0xff, 0xff, 0x0c, 0x00, 0x10, 0x00, 0x1c, 0x00, 0x10, 0x00, +0x3c, 0x38, 0x00, 0x80, 0xfc, 0x37, 0x00, 0x80, 0xfc, 0x3f, 0x00, 0x80, +0x7c, 0x34, 0x00, 0x80, 0x80, 0x0f, 0x00, 0x00, 0x80, 0x30, 0x00, 0x80, +0xad, 0xde, 0xad, 0xde, 0x5c, 0xbc, 0x00, 0x00, 0x24, 0xab, 0x20, 0x40, +0x48, 0x29, 0x00, 0x00, 0x28, 0x05, 0x00, 0x80, 0x8d, 0xd2, 0x21, 0x40, +0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x44, 0x57, 0x00, 0x00, 0x71, 0xaf, 0x00, 0x00, 0x60, 0x01, 0xff, 0xff, +0xb0, 0xb5, 0x07, 0x1c, 0x12, 0x4c, 0x00, 0x25, 0x20, 0x68, 0x00, 0x28, +0x1d, 0xd0, 0x38, 0x1c, 0x10, 0x49, 0x04, 0xf0, 0x71, 0xfd, 0x21, 0x68, +0xc0, 0x46, 0x08, 0x60, 0x00, 0x28, 0x14, 0xd0, 0x38, 0x01, 0x0d, 0x49, +0x40, 0x18, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x41, 0x6b, 0x80, 0x29, +0x0b, 0xd2, 0x01, 0x31, 0x41, 0x63, 0x20, 0x68, 0xc1, 0x69, 0xc0, 0x46, +0x21, 0x60, 0x39, 0x07, 0x41, 0x60, 0xc7, 0x62, 0xb0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x28, 0x1c, 0xfa, 0xe7, 0x00, 0x00, 0xe8, 0x17, 0x00, 0x80, +0xee, 0x05, 0x00, 0x00, 0xa0, 0x1c, 0x00, 0x80, 0x02, 0x49, 0x0a, 0x68, +0xc0, 0x46, 0xc2, 0x61, 0x08, 0x60, 0x70, 0x47, +0xe8, 0x17, 0x00, 0x80, 0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, +0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe1, 0x00, 0x10, 0xa0, 0xe1, +0xc0, 0x10, 0x81, 0xe3, 0x01, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, -0x40, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, -0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0x10, 0xe3, 0x80, 0x00, 0x80, 0xe3, -0x00, 0xf0, 0x21, 0xe1, 0x00, 0x00, 0x00, 0x12, 0x1e, 0xff, 0x2f, 0xe1, -0x00, 0x00, 0x50, 0xe3, 0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0xc0, 0x13, +0xc0, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, +0x00, 0x00, 0x0f, 0xe1, 0xc0, 0x00, 0xc0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, +0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, 0x40, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, -0x80, 0x00, 0xc0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, -0x91, 0x00, 0x00, 0xe0, 0x1e, 0xff, 0x2f, 0xe1, 0x01, 0x20, 0x80, 0xe0, -0x01, 0x00, 0x80, 0xe0, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0xb5, 0x08, 0x4f, -0x64, 0x28, 0x04, 0xd3, 0x64, 0x20, 0x38, 0x63, 0x00, 0x20, 0xc0, 0x43, -0x03, 0xe0, 0x38, 0x63, 0x04, 0x49, 0x05, 0xf0, 0xc1, 0xfa, 0x78, 0x63, -0xb8, 0x63, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, -0x88, 0x13, 0x00, 0x00, 0x80, 0xb4, 0x10, 0x4b, 0x00, 0x22, 0x1f, 0x6b, -0x64, 0x2f, 0x03, 0xd2, 0x09, 0x68, 0x09, 0x68, 0x49, 0x08, 0x02, 0xd2, -0x10, 0x1c, 0x80, 0xbc, 0x70, 0x47, 0x19, 0x1c, 0xdb, 0x6b, 0x4f, 0x6b, -0xbb, 0x42, 0x05, 0xd2, 0x40, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x18, 0x18, -0xc8, 0x63, 0xf1, 0xe7, 0x41, 0x68, 0x05, 0x4b, 0x19, 0x43, 0x41, 0x60, -0x04, 0x48, 0xc1, 0x6b, 0x01, 0x31, 0xc1, 0x63, 0x02, 0x20, 0xe8, 0xe7, -0xe8, 0x0d, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x78, 0x2a, 0x00, 0x80, -0x90, 0xb5, 0x07, 0x1c, 0x15, 0x4c, 0x00, 0x20, 0x21, 0x6b, 0x64, 0x29, -0x0b, 0xd2, 0xb9, 0x6e, 0x49, 0x08, 0x08, 0xd3, 0x21, 0x6c, 0xa2, 0x6b, -0x91, 0x42, 0x07, 0xd2, 0xfa, 0x1d, 0x39, 0x32, 0x52, 0x8b, 0x89, 0x18, -0x21, 0x64, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x78, 0x6a, 0x39, 0x6b, -0xc0, 0x46, 0x48, 0x62, 0x38, 0x6b, 0x02, 0xf0, 0xe7, 0xfd, 0x38, 0x1c, -0x02, 0xf0, 0xa4, 0xfa, 0x01, 0x20, 0xbb, 0x23, 0x1b, 0x01, 0xe1, 0x18, -0xc8, 0x72, 0x05, 0x49, 0x0a, 0x6c, 0x12, 0x18, 0x0a, 0x64, 0x04, 0x49, -0x8a, 0x6d, 0x12, 0x18, 0x8a, 0x65, 0xe4, 0xe7, 0xe8, 0x0d, 0x00, 0x80, -0x78, 0x2a, 0x00, 0x80, 0x10, 0x2a, 0x00, 0x80, 0x80, 0xb4, 0x0a, 0x48, -0xc0, 0x6d, 0x02, 0x23, 0x18, 0x40, 0x09, 0x4a, 0x00, 0x21, 0x00, 0x28, -0x03, 0xd0, 0xd1, 0x63, 0x11, 0x64, 0x80, 0xbc, 0x70, 0x47, 0x06, 0x48, -0x07, 0x68, 0x7b, 0x1c, 0x03, 0x60, 0x0a, 0x2f, 0xf7, 0xd3, 0x01, 0x60, -0xf3, 0xe7, 0x00, 0x00, 0x10, 0x2a, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, -0x60, 0x01, 0x00, 0x80, 0x70, 0x47, 0x02, 0x04, 0x12, 0x0c, 0x00, 0x0c, -0x10, 0x18, 0x0a, 0x04, 0x12, 0x0c, 0x09, 0x0c, 0x51, 0x18, 0x08, 0x18, -0x01, 0x0c, 0x05, 0xd0, 0x01, 0x04, 0x09, 0x0c, 0x00, 0x0c, 0x08, 0x18, -0x01, 0x0c, 0xf9, 0xd1, 0x00, 0x04, 0x00, 0x0c, 0x70, 0x47, 0x80, 0xb4, -0x00, 0x22, 0x00, 0x29, 0x18, 0xd0, 0x4f, 0x08, 0x7b, 0x1e, 0x00, 0x2f, +0x80, 0x00, 0x10, 0xe3, 0x80, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x21, 0xe1, +0x00, 0x00, 0x00, 0x12, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x50, 0xe3, +0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0xc0, 0x13, 0x00, 0xf0, 0x21, 0xe1, +0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0xc0, 0xe3, +0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x91, 0x00, 0x00, 0xe0, +0x1e, 0xff, 0x2f, 0xe1, 0x01, 0x20, 0x80, 0xe0, 0x01, 0x00, 0x80, 0xe0, +0x1e, 0xff, 0x2f, 0xe1, 0x80, 0xb5, 0x08, 0x4f, 0x64, 0x28, 0x04, 0xd3, +0x64, 0x20, 0x38, 0x63, 0x00, 0x20, 0xc0, 0x43, 0x03, 0xe0, 0x38, 0x63, +0x04, 0x49, 0x05, 0xf0, 0xf7, 0xfa, 0x78, 0x63, 0xb8, 0x63, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x88, 0x13, 0x00, 0x00, +0x80, 0xb4, 0x10, 0x4b, 0x00, 0x22, 0x1f, 0x6b, 0x64, 0x2f, 0x03, 0xd2, +0x09, 0x68, 0x09, 0x68, 0x49, 0x08, 0x02, 0xd2, 0x10, 0x1c, 0x80, 0xbc, +0x70, 0x47, 0x19, 0x1c, 0xdb, 0x6b, 0x4f, 0x6b, 0xbb, 0x42, 0x05, 0xd2, +0x40, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x18, 0x18, 0xc8, 0x63, 0xf1, 0xe7, +0x41, 0x68, 0x05, 0x4b, 0x19, 0x43, 0x41, 0x60, 0x04, 0x48, 0xc1, 0x6b, +0x01, 0x31, 0xc1, 0x63, 0x02, 0x20, 0xe8, 0xe7, 0x68, 0x0e, 0x00, 0x80, +0x00, 0x00, 0x00, 0x80, 0x0c, 0x2b, 0x00, 0x80, 0x90, 0xb5, 0x07, 0x1c, +0x15, 0x4c, 0x00, 0x20, 0x21, 0x6b, 0x64, 0x29, 0x0b, 0xd2, 0xb9, 0x6e, +0x49, 0x08, 0x08, 0xd3, 0x21, 0x6c, 0xa2, 0x6b, 0x91, 0x42, 0x07, 0xd2, +0xfa, 0x1d, 0x39, 0x32, 0x52, 0x8b, 0x89, 0x18, 0x21, 0x64, 0x90, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x78, 0x6a, 0x39, 0x6b, 0xc0, 0x46, 0x48, 0x62, +0x38, 0x6b, 0x02, 0xf0, 0x23, 0xfe, 0x38, 0x1c, 0x02, 0xf0, 0xde, 0xfa, +0x01, 0x20, 0xbb, 0x23, 0x1b, 0x01, 0xe1, 0x18, 0xc8, 0x73, 0x05, 0x49, +0x0a, 0x6c, 0x12, 0x18, 0x0a, 0x64, 0x04, 0x49, 0x8a, 0x6d, 0x12, 0x18, +0x8a, 0x65, 0xe4, 0xe7, 0x68, 0x0e, 0x00, 0x80, 0x0c, 0x2b, 0x00, 0x80, +0xa4, 0x2a, 0x00, 0x80, 0x80, 0xb4, 0x0a, 0x48, 0xc0, 0x6d, 0x02, 0x23, +0x18, 0x40, 0x09, 0x4a, 0x00, 0x21, 0x00, 0x28, 0x03, 0xd0, 0xd1, 0x63, +0x11, 0x64, 0x80, 0xbc, 0x70, 0x47, 0x06, 0x48, 0x07, 0x68, 0x7b, 0x1c, +0x03, 0x60, 0x0a, 0x2f, 0xf7, 0xd3, 0x01, 0x60, 0xf3, 0xe7, 0x00, 0x00, +0xa4, 0x2a, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80, 0xe0, 0x01, 0x00, 0x80, +0x70, 0x47, 0x02, 0x04, 0x12, 0x0c, 0x00, 0x0c, 0x10, 0x18, 0x0a, 0x04, +0x12, 0x0c, 0x09, 0x0c, 0x51, 0x18, 0x08, 0x18, 0x01, 0x0c, 0x05, 0xd0, +0x01, 0x04, 0x09, 0x0c, 0x00, 0x0c, 0x08, 0x18, 0x01, 0x0c, 0xf9, 0xd1, +0x00, 0x04, 0x00, 0x0c, 0x70, 0x47, 0x80, 0xb4, 0x00, 0x22, 0x00, 0x29, +0x18, 0xd0, 0x4f, 0x08, 0x7b, 0x1e, 0x00, 0x2f, 0x06, 0xd0, 0x07, 0x88, 0xba, 0x18, 0x02, 0x30, 0x1f, 0x1c, 0x01, 0x3b, -0x00, 0x2f, 0xf8, 0xd1, 0x49, 0x08, 0x03, 0xd3, -0x00, 0x88, 0x00, 0x06, 0x00, 0x0e, 0x82, 0x18, 0x10, 0x0c, 0x05, 0xd0, -0x10, 0x04, 0x00, 0x0c, 0x11, 0x0c, 0x42, 0x18, 0x10, 0x0c, 0xf9, 0xd1, -0x10, 0x04, 0x00, 0x0c, 0x80, 0xbc, 0x70, 0x47, 0x80, 0xb5, 0x83, 0x89, -0xc7, 0x89, 0xfb, 0x18, 0x07, 0x8a, 0xfb, 0x18, 0x47, 0x8a, 0xfb, 0x18, -0x40, 0x7a, 0x00, 0x02, 0xc7, 0x18, 0x38, 0x0c, 0x05, 0xd0, 0x38, 0x04, -0x00, 0x0c, 0x3b, 0x0c, 0xc7, 0x18, 0x38, 0x0c, 0xf9, 0xd1, 0x08, 0x1c, -0x11, 0x1c, 0xff, 0xf7, 0xc8, 0xff, 0x01, 0x1c, 0x38, 0x1c, 0xff, 0xf7, -0xb0, 0xff, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x02, 0x23, -0x82, 0x68, 0x1a, 0x40, 0x00, 0x27, 0x00, 0x2a, 0x0f, 0xd0, 0x0a, 0x4a, -0x93, 0x69, 0x01, 0x33, 0x93, 0x61, 0x0a, 0x68, 0x8b, 0x68, 0x9a, 0x18, -0x00, 0x68, 0x1c, 0x18, 0x57, 0x81, 0x09, 0x69, 0x10, 0x1c, 0xff, 0xf7, -0xac, 0xff, 0xc0, 0x43, 0x60, 0x81, 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x23, -0x82, 0x68, 0x1a, 0x40, 0x00, 0x27, 0x00, 0x2a, 0x11, 0xd0, 0x4a, 0x68, -0x52, 0x09, 0x0e, 0xd3, 0x09, 0x4a, 0x13, 0x6a, 0x01, 0x33, 0x13, 0x62, -0xcb, 0x68, 0x02, 0x68, 0x9c, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x3a, -0x1a, 0x43, 0x12, 0x68, 0x00, 0xf0, 0x2e, 0xf8, 0x20, 0x82, 0x38, 0x1c, -0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, -0x90, 0xb5, 0x80, 0x23, 0x82, 0x68, 0x1a, 0x40, 0x00, 0x24, 0x00, 0x2a, -0x15, 0xd0, 0x4a, 0x68, 0x92, 0x09, 0x12, 0xd3, 0x0b, 0x4a, 0xd3, 0x69, -0x01, 0x33, 0xd3, 0x61, 0xcb, 0x68, 0x02, 0x68, 0x9f, 0x18, 0x01, 0x23, -0x9b, 0x07, 0x08, 0x3a, 0x1a, 0x43, 0x12, 0x68, 0x00, 0xf0, 0x0e, 0xf8, -0x00, 0x28, 0x00, 0xd1, 0x04, 0x48, 0xc0, 0x46, 0xf8, 0x80, 0x20, 0x1c, -0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, -0xff, 0xff, 0x00, 0x00, 0xb0, 0xb5, 0x14, 0x1c, 0x05, 0x1c, 0x0f, 0x1c, -0x38, 0x69, 0xb9, 0x68, 0x41, 0x18, 0x38, 0x68, 0xff, 0xf7, 0x53, 0xff, -0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x20, 0x1c, 0xff, 0xf7, 0x39, 0xff, -0x04, 0x1c, 0xb8, 0x68, 0x79, 0x69, 0x40, 0x18, 0x69, 0x68, 0x88, 0x42, -0x0c, 0xd2, 0x2a, 0x68, 0x12, 0x18, 0x09, 0x1a, 0x10, 0x1c, 0x00, 0xf0, -0x05, 0xf9, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x20, 0x1c, 0xff, 0xf7, -0x26, 0xff, 0x04, 0x1c, 0xe0, 0x43, 0x00, 0x04, 0x00, 0x0c, 0xb0, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x6b, 0xc0, 0x08, -0x1a, 0xd3, 0xb8, 0x6a, 0xf9, 0x6b, 0x40, 0x18, 0x79, 0x6c, 0x00, 0xf0, -0xed, 0xf8, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x0a, 0x48, 0x07, 0xd0, -0x20, 0x23, 0xb9, 0x69, 0x19, 0x43, 0xb9, 0x61, 0x01, 0x6b, 0x01, 0x31, -0x01, 0x63, 0x07, 0xe0, 0xff, 0x23, 0x01, 0x33, 0xb9, 0x69, 0x19, 0x43, -0xb9, 0x61, 0x41, 0x6a, 0x01, 0x31, 0x41, 0x62, 0x00, 0x20, 0x80, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0x80, 0xb5, 0x07, 0x1c, -0xb8, 0x6b, 0x41, 0x09, 0x1c, 0xd3, 0xc0, 0x08, 0x1a, 0xd3, 0xf8, 0x1d, -0x39, 0x30, 0x00, 0x7b, 0x06, 0x28, 0x15, 0xd1, 0x38, 0x1c, 0x00, 0xf0, -0x53, 0xf8, 0x01, 0x1c, 0x0a, 0x48, 0x07, 0xd0, 0x40, 0x23, 0xb9, 0x69, +0x00, 0x2f, 0xf8, 0xd1, 0x49, 0x08, 0x03, 0xd3, 0x00, 0x88, 0x00, 0x06, +0x00, 0x0e, 0x82, 0x18, 0x10, 0x0c, 0x05, 0xd0, 0x10, 0x04, 0x00, 0x0c, +0x11, 0x0c, 0x42, 0x18, 0x10, 0x0c, 0xf9, 0xd1, 0x10, 0x04, 0x00, 0x0c, +0x80, 0xbc, 0x70, 0x47, 0x80, 0xb5, 0x83, 0x89, 0xc7, 0x89, 0xfb, 0x18, +0x07, 0x8a, 0xfb, 0x18, 0x47, 0x8a, 0xfb, 0x18, 0x40, 0x7a, 0x00, 0x02, +0xc7, 0x18, 0x38, 0x0c, 0x05, 0xd0, 0x38, 0x04, 0x00, 0x0c, 0x3b, 0x0c, +0xc7, 0x18, 0x38, 0x0c, 0xf9, 0xd1, 0x08, 0x1c, 0x11, 0x1c, 0xff, 0xf7, +0xc8, 0xff, 0x01, 0x1c, 0x38, 0x1c, 0xff, 0xf7, 0xb0, 0xff, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x02, 0x23, 0x82, 0x68, 0x1a, 0x40, +0x00, 0x27, 0x00, 0x2a, 0x0f, 0xd0, 0x0a, 0x4a, 0x93, 0x69, 0x01, 0x33, +0x93, 0x61, 0x0a, 0x68, 0x8b, 0x68, 0x9a, 0x18, 0x00, 0x68, 0x1c, 0x18, +0x57, 0x81, 0x09, 0x69, 0x10, 0x1c, 0xff, 0xf7, 0xac, 0xff, 0xc0, 0x43, +0x60, 0x81, 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x0c, 0x2b, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x23, 0x82, 0x68, 0x1a, 0x40, +0x00, 0x27, 0x00, 0x2a, 0x11, 0xd0, 0x4a, 0x68, 0x52, 0x09, 0x0e, 0xd3, +0x09, 0x4a, 0x13, 0x6a, 0x01, 0x33, 0x13, 0x62, 0xcb, 0x68, 0x02, 0x68, +0x9c, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x3a, 0x1a, 0x43, 0x12, 0x68, +0x00, 0xf0, 0x2e, 0xf8, 0x20, 0x82, 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x0c, 0x2b, 0x00, 0x80, 0x90, 0xb5, 0x80, 0x23, +0x82, 0x68, 0x1a, 0x40, 0x00, 0x24, 0x00, 0x2a, 0x15, 0xd0, 0x4a, 0x68, +0x92, 0x09, 0x12, 0xd3, 0x0b, 0x4a, 0xd3, 0x69, 0x01, 0x33, 0xd3, 0x61, +0xcb, 0x68, 0x02, 0x68, 0x9f, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x3a, +0x1a, 0x43, 0x12, 0x68, 0x00, 0xf0, 0x0e, 0xf8, 0x00, 0x28, 0x00, 0xd1, +0x04, 0x48, 0xc0, 0x46, 0xf8, 0x80, 0x20, 0x1c, 0x90, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x0c, 0x2b, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, +0xb0, 0xb5, 0x14, 0x1c, 0x05, 0x1c, 0x0f, 0x1c, 0x38, 0x69, 0xb9, 0x68, +0x41, 0x18, 0x38, 0x68, 0xff, 0xf7, 0x53, 0xff, 0xc0, 0x43, 0x01, 0x04, +0x09, 0x0c, 0x20, 0x1c, 0xff, 0xf7, 0x39, 0xff, 0x04, 0x1c, 0xb8, 0x68, +0x79, 0x69, 0x40, 0x18, 0x69, 0x68, 0x88, 0x42, 0x0c, 0xd2, 0x2a, 0x68, +0x12, 0x18, 0x09, 0x1a, 0x10, 0x1c, 0x00, 0xf0, 0x05, 0xf9, 0xc0, 0x43, +0x01, 0x04, 0x09, 0x0c, 0x20, 0x1c, 0xff, 0xf7, 0x26, 0xff, 0x04, 0x1c, +0xe0, 0x43, 0x00, 0x04, 0x00, 0x0c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x6b, 0xc0, 0x08, 0x1a, 0xd3, 0xb8, 0x6a, +0xf9, 0x6b, 0x40, 0x18, 0x79, 0x6c, 0x00, 0xf0, 0xed, 0xf8, 0xc0, 0x43, +0x01, 0x04, 0x09, 0x0c, 0x0a, 0x48, 0x07, 0xd0, 0x20, 0x23, 0xb9, 0x69, +0x19, 0x43, 0xb9, 0x61, 0x01, 0x6b, 0x01, 0x31, 0x01, 0x63, 0x07, 0xe0, +0xff, 0x23, 0x01, 0x33, 0xb9, 0x69, 0x19, 0x43, 0xb9, 0x61, 0x41, 0x6a, +0x01, 0x31, 0x41, 0x62, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x0c, 0x2b, 0x00, 0x80, 0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x6b, 0x41, 0x09, +0x1c, 0xd3, 0xc0, 0x08, 0x1a, 0xd3, 0xf8, 0x1d, 0x39, 0x30, 0x00, 0x7b, +0x06, 0x28, 0x15, 0xd1, 0x38, 0x1c, 0x00, 0xf0, 0x53, 0xf8, 0x01, 0x1c, +0x0a, 0x48, 0x07, 0xd0, 0x40, 0x23, 0xb9, 0x69, 0x19, 0x43, 0xb9, 0x61, 0x81, 0x6b, 0x01, 0x31, 0x81, 0x63, 0x07, 0xe0, -0x01, 0x23, 0x9b, 0x02, 0xb9, 0x69, 0x19, 0x43, -0xb9, 0x61, 0xc1, 0x6a, 0x01, 0x31, 0xc1, 0x62, 0x00, 0x20, 0x80, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0xb0, 0xb5, 0x07, 0x1c, -0xb8, 0x6b, 0x81, 0x09, 0x2c, 0xd3, 0xc0, 0x08, 0x2a, 0xd3, 0xf8, 0x1d, -0x39, 0x30, 0x00, 0x7b, 0x11, 0x28, 0x25, 0xd1, 0xb8, 0x6a, 0x39, 0x6c, -0x40, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x06, 0x30, 0x18, 0x43, 0x00, 0x68, -0x05, 0x04, 0x2d, 0x0c, 0x0f, 0x4c, 0x11, 0xd0, 0x38, 0x1c, 0x00, 0xf0, -0x1f, 0xf8, 0x00, 0x28, 0x0c, 0xd0, 0xa8, 0x42, 0x02, 0xd1, 0x0c, 0x4b, -0x98, 0x42, 0x07, 0xd0, 0x80, 0x23, 0xb8, 0x69, 0x18, 0x43, 0xb8, 0x61, -0x60, 0x6b, 0x01, 0x30, 0x60, 0x63, 0x07, 0xe0, 0x01, 0x23, 0x5b, 0x02, -0xb8, 0x69, 0x18, 0x43, 0xb8, 0x61, 0xa0, 0x6a, 0x01, 0x30, 0xa0, 0x62, -0x00, 0x20, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, -0xff, 0xff, 0x00, 0x00, 0xf0, 0xb5, 0xff, 0xb0, 0x99, 0xb0, 0x04, 0x1c, -0xe0, 0x6b, 0x61, 0x6c, 0x09, 0x18, 0x03, 0xaa, 0x85, 0x18, 0xa3, 0x6a, -0x00, 0x20, 0x8a, 0x08, 0x01, 0x32, 0x97, 0x92, 0x07, 0xd0, 0x82, 0x00, -0x9f, 0x58, 0x03, 0xae, 0xb7, 0x50, 0x97, 0x9a, 0x01, 0x30, 0x82, 0x42, -0xf7, 0xd8, 0x60, 0x6a, 0x01, 0x23, 0x9b, 0x07, 0x04, 0x30, 0x18, 0x43, -0x00, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x02, 0xaf, 0x3f, 0x88, 0x03, 0xa8, -0xff, 0xf7, 0x87, 0xfe, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, -0xff, 0xf7, 0x6d, 0xfe, 0x07, 0x1c, 0xe0, 0x6b, 0xa1, 0x6c, 0x40, 0x18, -0x61, 0x6a, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x31, 0x19, 0x43, 0x09, 0x68, -0xc0, 0x46, 0x01, 0x91, 0x01, 0xa9, 0x09, 0x88, 0x01, 0x31, 0x88, 0x42, -0x0c, 0xd2, 0xa2, 0x6a, 0x12, 0x18, 0x09, 0x1a, 0x10, 0x1c, 0x00, 0xf0, -0x2f, 0xf8, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0xff, 0xf7, -0x50, 0xfe, 0x07, 0x1c, 0xa8, 0x89, 0xe9, 0x89, 0x08, 0x18, 0x29, 0x8a, -0x08, 0x18, 0x69, 0x8a, 0x08, 0x18, 0x69, 0x7a, 0x09, 0x02, 0x08, 0x18, -0xa1, 0x6c, 0x62, 0x6c, 0x89, 0x1a, 0x0a, 0x04, 0x12, 0x0c, 0x11, 0x02, -0x12, 0x0a, 0x11, 0x43, 0x09, 0x04, 0x09, 0x0c, 0x09, 0x18, 0x08, 0x0c, -0x05, 0xd0, 0x08, 0x04, 0x00, 0x0c, 0x09, 0x0c, 0x41, 0x18, 0x08, 0x0c, -0xf9, 0xd1, 0x38, 0x1c, 0xff, 0xf7, 0x2f, 0xfe, 0xc0, 0x43, 0x00, 0x04, -0x00, 0x0c, 0x7f, 0xb0, 0x19, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0xb0, 0xb4, 0x00, 0x22, 0x00, 0x29, 0x2e, 0xd0, 0x83, 0x07, 0x9b, 0x0f, -0xdc, 0x00, 0x47, 0x18, 0x04, 0x25, 0xef, 0x1b, 0xbf, 0x07, 0xbf, 0x0f, -0xff, 0x00, 0x80, 0x08, 0x80, 0x00, 0x59, 0x18, 0x03, 0x31, 0x89, 0x08, -0x4d, 0x1e, 0x02, 0xc8, 0xe1, 0x40, 0xa1, 0x40, 0x6b, 0x1e, 0x00, 0x2d, -0x09, 0xd0, 0x0c, 0x04, 0x24, 0x0c, 0xa2, 0x18, 0x09, 0x0c, 0x8a, 0x18, -0x02, 0xc8, 0x1c, 0x1c, 0x01, 0x3b, 0x00, 0x2c, 0xf5, 0xd1, 0xb9, 0x40, -0x08, 0x1c, 0xf8, 0x40, 0x01, 0x04, 0x09, 0x0c, 0x89, 0x18, 0x00, 0x0c, -0x42, 0x18, 0x10, 0x0c, 0x05, 0xd0, 0x10, 0x04, 0x00, 0x0c, 0x11, 0x0c, -0x42, 0x18, 0x10, 0x0c, 0xf9, 0xd1, 0x10, 0x04, 0x00, 0x0c, 0xb0, 0xbc, -0x70, 0x47, 0x00, 0x00, 0x90, 0xb4, 0x00, 0x20, 0x01, 0x27, 0x11, 0x49, -0x42, 0x00, 0x12, 0x18, 0xd2, 0x00, 0x53, 0x18, 0x9c, 0x68, 0x01, 0x23, +0x01, 0x23, 0x9b, 0x02, 0xb9, 0x69, 0x19, 0x43, 0xb9, 0x61, 0xc1, 0x6a, +0x01, 0x31, 0xc1, 0x62, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x0c, 0x2b, 0x00, 0x80, 0xb0, 0xb5, 0x07, 0x1c, 0xb8, 0x6b, 0x81, 0x09, +0x2c, 0xd3, 0xc0, 0x08, 0x2a, 0xd3, 0xf8, 0x1d, 0x39, 0x30, 0x00, 0x7b, +0x11, 0x28, 0x25, 0xd1, 0xb8, 0x6a, 0x39, 0x6c, 0x40, 0x18, 0x01, 0x23, +0x9b, 0x07, 0x06, 0x30, 0x18, 0x43, 0x00, 0x68, 0x05, 0x04, 0x2d, 0x0c, +0x0f, 0x4c, 0x11, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x1f, 0xf8, 0x00, 0x28, +0x0c, 0xd0, 0xa8, 0x42, 0x02, 0xd1, 0x0c, 0x4b, 0x98, 0x42, 0x07, 0xd0, +0x80, 0x23, 0xb8, 0x69, 0x18, 0x43, 0xb8, 0x61, 0x60, 0x6b, 0x01, 0x30, +0x60, 0x63, 0x07, 0xe0, 0x01, 0x23, 0x5b, 0x02, 0xb8, 0x69, 0x18, 0x43, +0xb8, 0x61, 0xa0, 0x6a, 0x01, 0x30, 0xa0, 0x62, 0x00, 0x20, 0xb0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x0c, 0x2b, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, +0xf0, 0xb5, 0xff, 0xb0, 0x99, 0xb0, 0x04, 0x1c, 0xe0, 0x6b, 0x61, 0x6c, +0x09, 0x18, 0x03, 0xaa, 0x85, 0x18, 0xa3, 0x6a, 0x00, 0x20, 0x8a, 0x08, +0x01, 0x32, 0x97, 0x92, 0x07, 0xd0, 0x82, 0x00, 0x9f, 0x58, 0x03, 0xae, +0xb7, 0x50, 0x97, 0x9a, 0x01, 0x30, 0x82, 0x42, 0xf7, 0xd8, 0x60, 0x6a, +0x01, 0x23, 0x9b, 0x07, 0x04, 0x30, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, +0x02, 0x90, 0x02, 0xaf, 0x3f, 0x88, 0x03, 0xa8, 0xff, 0xf7, 0x87, 0xfe, +0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0xff, 0xf7, 0x6d, 0xfe, +0x07, 0x1c, 0xe0, 0x6b, 0xa1, 0x6c, 0x40, 0x18, 0x61, 0x6a, 0x01, 0x23, +0x9b, 0x07, 0x08, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x01, 0x91, +0x01, 0xa9, 0x09, 0x88, 0x01, 0x31, 0x88, 0x42, 0x0c, 0xd2, 0xa2, 0x6a, +0x12, 0x18, 0x09, 0x1a, 0x10, 0x1c, 0x00, 0xf0, 0x2f, 0xf8, 0xc0, 0x43, +0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0xff, 0xf7, 0x50, 0xfe, 0x07, 0x1c, +0xa8, 0x89, 0xe9, 0x89, 0x08, 0x18, 0x29, 0x8a, 0x08, 0x18, 0x69, 0x8a, +0x08, 0x18, 0x69, 0x7a, 0x09, 0x02, 0x08, 0x18, 0xa1, 0x6c, 0x62, 0x6c, +0x89, 0x1a, 0x0a, 0x04, 0x12, 0x0c, 0x11, 0x02, 0x12, 0x0a, 0x11, 0x43, +0x09, 0x04, 0x09, 0x0c, 0x09, 0x18, 0x08, 0x0c, 0x05, 0xd0, 0x08, 0x04, +0x00, 0x0c, 0x09, 0x0c, 0x41, 0x18, 0x08, 0x0c, 0xf9, 0xd1, 0x38, 0x1c, +0xff, 0xf7, 0x2f, 0xfe, 0xc0, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x7f, 0xb0, +0x19, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb4, 0x00, 0x22, +0x00, 0x29, 0x2e, 0xd0, 0x83, 0x07, 0x9b, 0x0f, 0xdc, 0x00, 0x47, 0x18, +0x04, 0x25, 0xef, 0x1b, 0xbf, 0x07, 0xbf, 0x0f, 0xff, 0x00, 0x80, 0x08, +0x80, 0x00, 0x59, 0x18, 0x03, 0x31, 0x89, 0x08, 0x4d, 0x1e, 0x02, 0xc8, +0xe1, 0x40, 0xa1, 0x40, 0x6b, 0x1e, 0x00, 0x2d, 0x09, 0xd0, 0x0c, 0x04, +0x24, 0x0c, 0xa2, 0x18, 0x09, 0x0c, 0x8a, 0x18, 0x02, 0xc8, 0x1c, 0x1c, +0x01, 0x3b, 0x00, 0x2c, 0xf5, 0xd1, 0xb9, 0x40, 0x08, 0x1c, 0xf8, 0x40, +0x01, 0x04, 0x09, 0x0c, 0x89, 0x18, 0x00, 0x0c, 0x42, 0x18, 0x10, 0x0c, +0x05, 0xd0, 0x10, 0x04, 0x00, 0x0c, 0x11, 0x0c, 0x42, 0x18, 0x10, 0x0c, +0xf9, 0xd1, 0x10, 0x04, 0x00, 0x0c, 0xb0, 0xbc, 0x70, 0x47, 0x00, 0x00, +0x90, 0xb4, 0x00, 0x20, 0x01, 0x27, 0x11, 0x49, 0x42, 0x00, 0x12, 0x18, +0xd2, 0x00, 0x53, 0x18, 0x9c, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x1b, 0x03, 0x1b, 0x0b, 0x8a, 0x58, -0x12, 0x03, 0x12, 0x0b, 0x93, 0x42, 0x0c, 0xd1, -0x01, 0x30, 0x04, 0x28, 0xec, 0xd3, 0x08, 0x48, 0xc0, 0x6a, 0x01, 0x03, -0x09, 0x0b, 0x07, 0x48, 0x00, 0x6f, 0x00, 0x03, 0x00, 0x0b, 0x81, 0x42, -0x02, 0xd0, 0x38, 0x1c, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, 0xfb, 0xe7, -0x28, 0x03, 0x00, 0x80, 0x00, 0x40, 0x14, 0x40, 0xe8, 0x0d, 0x00, 0x80, -0x98, 0xb4, 0x14, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x83, 0x00, 0x13, 0x48, -0xc0, 0x58, 0x07, 0x03, 0x3f, 0x0b, 0x12, 0x48, 0xc0, 0x58, 0x02, 0x03, -0x12, 0x0b, 0x11, 0x48, 0xc0, 0x58, 0x00, 0x03, 0x00, 0x0b, 0x10, 0x4c, -0xe4, 0x58, 0x01, 0x23, 0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x9b, 0x00, -0xcc, 0x00, 0x01, 0x21, 0x98, 0x42, 0x01, 0xd1, 0x08, 0x1c, 0x09, 0xe0, -0x98, 0x42, 0x03, 0xd9, 0x10, 0x1a, 0xda, 0x1b, 0x80, 0x18, 0x00, 0xe0, -0x18, 0x1a, 0x84, 0x42, 0xf4, 0xd3, 0x00, 0x20, 0x98, 0xbc, 0x70, 0x47, -0x55, 0x55, 0x55, 0x55, 0xa0, 0x03, 0x00, 0x80, 0xa8, 0x03, 0x00, 0x80, -0x88, 0x03, 0x00, 0x80, 0x98, 0x03, 0x00, 0x80, 0x80, 0xb4, 0x13, 0x04, -0x00, 0xd0, 0x01, 0x3a, 0x80, 0x00, 0x0b, 0x1c, 0x13, 0x49, 0x0f, 0x58, -0xc0, 0x46, 0x3b, 0x60, 0x0b, 0x58, 0xc0, 0x46, 0x5a, 0x60, 0x0a, 0x58, -0x08, 0x32, 0x10, 0x4b, 0x1b, 0x58, 0x9a, 0x42, 0x01, 0xd3, 0x0f, 0x4a, -0x12, 0x58, 0x0f, 0x4b, 0x1f, 0x58, 0x01, 0x23, 0x9b, 0x07, 0x3b, 0x43, -0x1b, 0x68, 0x9b, 0x00, 0x17, 0x03, 0x3f, 0x0b, 0x9f, 0x42, 0x06, 0xd1, -0x0a, 0x48, 0xc1, 0x68, 0x01, 0x31, 0xc1, 0x60, 0x01, 0x20, 0x80, 0xbc, -0x70, 0x47, 0x08, 0x4b, 0x1b, 0x58, 0xc0, 0x46, 0x1a, 0x60, 0x0a, 0x50, -0x00, 0x20, 0xf6, 0xe7, 0x88, 0x03, 0x00, 0x80, 0xa8, 0x03, 0x00, 0x80, -0xa0, 0x03, 0x00, 0x80, 0x98, 0x03, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, -0x90, 0x03, 0x00, 0x80, 0xff, 0x5f, 0x2d, 0xe9, 0x48, 0xfe, 0xff, 0xeb, -0x01, 0xb6, 0xa0, 0xe3, 0x01, 0xb1, 0x8b, 0xe2, 0x02, 0x8a, 0xa0, 0xe3, -0x01, 0x7a, 0xa0, 0xe3, 0x01, 0xa9, 0xa0, 0xe3, 0x01, 0x56, 0xa0, 0xe3, -0xc8, 0x60, 0x9f, 0xe5, 0xc8, 0x90, 0x9f, 0xe5, 0x14, 0x40, 0x9b, 0xe5, -0x00, 0x00, 0x54, 0xe3, 0x2c, 0x00, 0x00, 0x0a, 0x03, 0x0a, 0x14, 0xe3, -0x11, 0x00, 0x00, 0x0a, 0x0c, 0x00, 0x96, 0xe5, 0x00, 0x00, 0x50, 0xe3, -0x21, 0x00, 0x00, 0x0a, 0x01, 0x0a, 0x14, 0xe3, 0x05, 0x00, 0x00, 0x0a, -0x1c, 0x00, 0x96, 0xe5, 0x01, 0x0a, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, -0x1c, 0x00, 0x85, 0xe5, 0x14, 0x70, 0x85, 0xe5, 0x06, 0x00, 0x00, 0xea, -0x02, 0x0a, 0x14, 0xe3, 0x04, 0x00, 0x00, 0x0a, 0x1c, 0x00, 0x96, 0xe5, -0x02, 0x0a, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5, -0x14, 0x80, 0x85, 0xe5, 0x01, 0x09, 0x14, 0xe3, 0x04, 0x00, 0x00, 0x0a, -0x1c, 0x00, 0x96, 0xe5, 0x01, 0x09, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, -0x1c, 0x00, 0x85, 0xe5, 0x14, 0xa0, 0x85, 0xe5, 0x02, 0x00, 0x14, 0xe3, -0x40, 0x00, 0x00, 0x1b, 0x01, 0x00, 0x14, 0xe3, 0x54, 0x00, 0x00, 0x1b, -0x02, 0x0b, 0x14, 0xe3, 0x67, 0x00, 0x00, 0x1b, 0x01, 0x0b, 0x14, 0xe3, -0x20, 0x00, 0x00, 0x1b, 0x18, 0x00, 0x99, 0xe5, 0x01, 0x00, 0x80, 0xe2, -0x18, 0x00, 0x89, 0xe5, 0xd5, 0xff, 0xff, 0xea, 0x1c, 0x00, 0x96, 0xe5, +0x12, 0x03, 0x12, 0x0b, 0x93, 0x42, 0x0c, 0xd1, 0x01, 0x30, 0x04, 0x28, +0xec, 0xd3, 0x08, 0x48, 0xc0, 0x6a, 0x01, 0x03, 0x09, 0x0b, 0x07, 0x48, +0x00, 0x6f, 0x00, 0x03, 0x00, 0x0b, 0x81, 0x42, 0x02, 0xd0, 0x38, 0x1c, +0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, 0xfb, 0xe7, 0xa8, 0x03, 0x00, 0x80, +0x00, 0x40, 0x14, 0x40, 0x68, 0x0e, 0x00, 0x80, 0x98, 0xb4, 0x14, 0x4a, +0xc0, 0x46, 0x00, 0x92, 0x83, 0x00, 0x13, 0x48, 0xc0, 0x58, 0x07, 0x03, +0x3f, 0x0b, 0x12, 0x48, 0xc0, 0x58, 0x02, 0x03, 0x12, 0x0b, 0x11, 0x48, +0xc0, 0x58, 0x00, 0x03, 0x00, 0x0b, 0x10, 0x4c, 0xe4, 0x58, 0x01, 0x23, +0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x9b, 0x00, 0xcc, 0x00, 0x01, 0x21, +0x98, 0x42, 0x01, 0xd1, 0x08, 0x1c, 0x09, 0xe0, 0x98, 0x42, 0x03, 0xd9, +0x10, 0x1a, 0xda, 0x1b, 0x80, 0x18, 0x00, 0xe0, 0x18, 0x1a, 0x84, 0x42, +0xf4, 0xd3, 0x00, 0x20, 0x98, 0xbc, 0x70, 0x47, 0x55, 0x55, 0x55, 0x55, +0x20, 0x04, 0x00, 0x80, 0x28, 0x04, 0x00, 0x80, 0x08, 0x04, 0x00, 0x80, +0x18, 0x04, 0x00, 0x80, 0x80, 0xb4, 0x13, 0x04, 0x00, 0xd0, 0x01, 0x3a, +0x80, 0x00, 0x0b, 0x1c, 0x13, 0x49, 0x0f, 0x58, 0xc0, 0x46, 0x3b, 0x60, +0x0b, 0x58, 0xc0, 0x46, 0x5a, 0x60, 0x0a, 0x58, 0x08, 0x32, 0x10, 0x4b, +0x1b, 0x58, 0x9a, 0x42, 0x01, 0xd3, 0x0f, 0x4a, 0x12, 0x58, 0x0f, 0x4b, +0x1f, 0x58, 0x01, 0x23, 0x9b, 0x07, 0x3b, 0x43, 0x1b, 0x68, 0x9b, 0x00, +0x17, 0x03, 0x3f, 0x0b, 0x9f, 0x42, 0x06, 0xd1, 0x0a, 0x48, 0xc1, 0x68, +0x01, 0x31, 0xc1, 0x60, 0x01, 0x20, 0x80, 0xbc, 0x70, 0x47, 0x08, 0x4b, +0x1b, 0x58, 0xc0, 0x46, 0x1a, 0x60, 0x0a, 0x50, 0x00, 0x20, 0xf6, 0xe7, +0x08, 0x04, 0x00, 0x80, 0x28, 0x04, 0x00, 0x80, 0x20, 0x04, 0x00, 0x80, +0x18, 0x04, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x10, 0x04, 0x00, 0x80, +0xff, 0x5f, 0x2d, 0xe9, 0x48, 0xfe, 0xff, 0xeb, 0x01, 0xb6, 0xa0, 0xe3, +0x01, 0xb1, 0x8b, 0xe2, 0x02, 0x8a, 0xa0, 0xe3, 0x01, 0x7a, 0xa0, 0xe3, +0x01, 0xa9, 0xa0, 0xe3, 0x01, 0x56, 0xa0, 0xe3, 0xc8, 0x60, 0x9f, 0xe5, +0xc8, 0x90, 0x9f, 0xe5, 0x14, 0x40, 0x9b, 0xe5, 0x00, 0x00, 0x54, 0xe3, +0x2c, 0x00, 0x00, 0x0a, 0x03, 0x0a, 0x14, 0xe3, 0x11, 0x00, 0x00, 0x0a, +0x0c, 0x00, 0x96, 0xe5, 0x00, 0x00, 0x50, 0xe3, 0x21, 0x00, 0x00, 0x0a, +0x01, 0x0a, 0x14, 0xe3, 0x05, 0x00, 0x00, 0x0a, 0x1c, 0x00, 0x96, 0xe5, 0x01, 0x0a, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5, +0x14, 0x70, 0x85, 0xe5, 0x06, 0x00, 0x00, 0xea, 0x02, 0x0a, 0x14, 0xe3, +0x04, 0x00, 0x00, 0x0a, 0x1c, 0x00, 0x96, 0xe5, 0x02, 0x0a, 0xc0, 0xe3, +0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5, 0x14, 0x80, 0x85, 0xe5, +0x01, 0x09, 0x14, 0xe3, 0x04, 0x00, 0x00, 0x0a, 0x1c, 0x00, 0x96, 0xe5, +0x01, 0x09, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5, +0x14, 0xa0, 0x85, 0xe5, 0x02, 0x00, 0x14, 0xe3, 0x40, 0x00, 0x00, 0x1b, +0x01, 0x00, 0x14, 0xe3, 0x54, 0x00, 0x00, 0x1b, 0x02, 0x0b, 0x14, 0xe3, +0x67, 0x00, 0x00, 0x1b, 0x01, 0x0b, 0x14, 0xe3, 0x20, 0x00, 0x00, 0x1b, +0x18, 0x00, 0x99, 0xe5, 0x01, 0x00, 0x80, 0xe2, 0x18, 0x00, 0x89, 0xe5, +0xd5, 0xff, 0xff, 0xea, 0x1c, 0x00, 0x96, 0xe5, 0x01, 0x0a, 0xc0, 0xe3, +0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5, 0x14, 0x70, 0x85, 0xe5, 0xe1, 0xff, 0xff, 0xea, 0xff, 0x5f, 0xbd, 0xe8, -0x04, 0xf0, 0x5e, 0xe2, 0xe8, 0x0d, 0x00, 0x80, -0x08, 0x83, 0x20, 0x40, 0x10, 0x10, 0x1f, 0xe5, 0x14, 0x30, 0x91, 0xe5, -0x00, 0x20, 0xc3, 0xe1, 0x14, 0x20, 0x81, 0xe5, 0x01, 0x16, 0xa0, 0xe3, -0x0c, 0x20, 0x81, 0xe5, 0x0b, 0x12, 0xa0, 0xe3, 0x00, 0x00, 0x81, 0xe5, -0x18, 0x10, 0x9f, 0xe5, 0xb0, 0x24, 0xd1, 0xe1, 0x01, 0x20, 0x82, 0xe2, -0xb0, 0x24, 0xc1, 0xe1, 0x3c, 0x20, 0x91, 0xe5, 0x00, 0x00, 0x82, 0xe1, -0x3c, 0x00, 0x81, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xa0, 0x82, 0x20, 0x40, -0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x01, 0x0b, 0xa0, 0xe3, -0x01, 0x16, 0xa0, 0xe3, 0x14, 0x00, 0x81, 0xe5, 0x00, 0x1a, 0x81, 0xe1, -0x24, 0x20, 0x91, 0xe5, 0x70, 0x00, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, -0x24, 0x20, 0x80, 0xe5, 0x28, 0x10, 0x91, 0xe5, 0x00, 0x00, 0x00, 0x00, -0x28, 0x10, 0x80, 0xe5, 0x2c, 0x20, 0x90, 0xe5, 0x01, 0x20, 0x82, 0xe2, -0x2c, 0x20, 0x80, 0xe5, 0x3f, 0x00, 0x01, 0xe2, 0x3f, 0x00, 0x50, 0xe3, -0x1e, 0xff, 0x2f, 0x11, 0x18, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0x90, 0xe5, -0x01, 0x10, 0x81, 0xe2, 0x00, 0x10, 0x80, 0xe5, 0x02, 0x18, 0xa0, 0xe3, -0x0b, 0x02, 0xa0, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, -0xb0, 0x03, 0x00, 0x80, 0x01, 0x06, 0xa0, 0xe3, 0x01, 0x01, 0x80, 0xe2, -0x00, 0x10, 0x90, 0xe5, 0x01, 0x08, 0x11, 0xe3, 0x0b, 0x10, 0xa0, 0xe3, +0x04, 0xf0, 0x5e, 0xe2, 0x68, 0x0e, 0x00, 0x80, 0x08, 0x83, 0x20, 0x40, +0x10, 0x10, 0x1f, 0xe5, 0x14, 0x30, 0x91, 0xe5, 0x00, 0x20, 0xc3, 0xe1, +0x14, 0x20, 0x81, 0xe5, 0x01, 0x16, 0xa0, 0xe3, 0x0c, 0x20, 0x81, 0xe5, +0x0b, 0x12, 0xa0, 0xe3, 0x00, 0x00, 0x81, 0xe5, 0x18, 0x10, 0x9f, 0xe5, +0xb0, 0x24, 0xd1, 0xe1, 0x01, 0x20, 0x82, 0xe2, 0xb0, 0x24, 0xc1, 0xe1, +0x3c, 0x20, 0x91, 0xe5, 0x00, 0x00, 0x82, 0xe1, 0x3c, 0x00, 0x81, 0xe5, +0x1e, 0xff, 0x2f, 0xe1, 0xa0, 0x82, 0x20, 0x40, 0xff, 0xff, 0xff, 0xea, +0xfe, 0xff, 0xff, 0xea, 0x01, 0x0b, 0xa0, 0xe3, 0x01, 0x16, 0xa0, 0xe3, +0x14, 0x00, 0x81, 0xe5, 0x00, 0x1a, 0x81, 0xe1, 0x24, 0x20, 0x91, 0xe5, +0x70, 0x00, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x24, 0x20, 0x80, 0xe5, +0x28, 0x10, 0x91, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x28, 0x10, 0x80, 0xe5, +0x2c, 0x20, 0x90, 0xe5, 0x01, 0x20, 0x82, 0xe2, 0x2c, 0x20, 0x80, 0xe5, +0x3f, 0x00, 0x01, 0xe2, 0x3f, 0x00, 0x50, 0xe3, 0x1e, 0xff, 0x2f, 0x11, +0x18, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0x90, 0xe5, 0x01, 0x10, 0x81, 0xe2, +0x00, 0x10, 0x80, 0xe5, 0x02, 0x18, 0xa0, 0xe3, 0x0b, 0x02, 0xa0, 0xe3, +0x00, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x30, 0x04, 0x00, 0x80, +0x01, 0x06, 0xa0, 0xe3, 0x01, 0x01, 0x80, 0xe2, 0x00, 0x10, 0x90, 0xe5, +0x01, 0x08, 0x11, 0xe3, 0x0b, 0x10, 0xa0, 0xe3, 0x02, 0x19, 0x81, 0xe2, +0x05, 0x00, 0x00, 0x1a, 0x00, 0x20, 0x90, 0xe5, 0x42, 0x28, 0xb0, 0xe1, +0x05, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x90, 0xe5, 0x02, 0x0c, 0x10, 0xe3, +0x02, 0x00, 0x00, 0x0a, 0x06, 0x07, 0xa0, 0xe3, 0x4c, 0x11, 0x80, 0xe5, +0x03, 0x00, 0x00, 0xea, 0x0c, 0x00, 0x9f, 0xe5, 0x00, 0x00, 0x00, 0x00, +0x40, 0x10, 0x80, 0xe5, 0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea, +0x00, 0x00, 0x00, 0x80, 0x01, 0x06, 0xa0, 0xe3, 0x01, 0x01, 0x80, 0xe2, +0x00, 0x10, 0x90, 0xe5, 0x01, 0x08, 0x11, 0xe3, 0x0c, 0x10, 0xa0, 0xe3, 0x02, 0x19, 0x81, 0xe2, 0x05, 0x00, 0x00, 0x1a, 0x00, 0x20, 0x90, 0xe5, 0x42, 0x28, 0xb0, 0xe1, 0x05, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x90, 0xe5, 0x02, 0x0c, 0x10, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x06, 0x07, 0xa0, 0xe3, -0x4c, 0x11, 0x80, 0xe5, 0x03, 0x00, 0x00, 0xea, 0x0c, 0x00, 0x9f, 0xe5, +0x4c, 0x11, 0x80, 0xe5, 0x03, 0x00, 0x00, 0xea, 0x4c, 0x00, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x80, 0xe5, 0xff, 0xff, 0xff, 0xea, -0xfe, 0xff, 0xff, 0xea, 0x00, 0x00, 0x00, 0x80, 0x01, 0x06, 0xa0, 0xe3, -0x01, 0x01, 0x80, 0xe2, 0x00, 0x10, 0x90, 0xe5, 0x01, 0x08, 0x11, 0xe3, -0x0c, 0x10, 0xa0, 0xe3, 0x02, 0x19, 0x81, 0xe2, 0x05, 0x00, 0x00, 0x1a, -0x00, 0x20, 0x90, 0xe5, 0x42, 0x28, 0xb0, 0xe1, 0x05, 0x00, 0x00, 0x1a, -0x00, 0x00, 0x90, 0xe5, 0x02, 0x0c, 0x10, 0xe3, 0x02, 0x00, 0x00, 0x0a, -0x06, 0x07, 0xa0, 0xe3, 0x4c, 0x11, 0x80, 0xe5, 0x03, 0x00, 0x00, 0xea, -0x4c, 0x00, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x80, 0xe5, -0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x02, 0x1b, 0xa0, 0xe3, -0x01, 0x06, 0xa0, 0xe3, 0x14, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, -0x80, 0x21, 0x1f, 0xe5, 0x14, 0x30, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, -0x00, 0x30, 0x80, 0xe5, 0x1c, 0x00, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x81, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x14, 0x10, 0x82, 0xe5, -0x01, 0x06, 0xa0, 0xe3, 0x1c, 0x10, 0x82, 0xe5, 0x0c, 0x10, 0x80, 0xe5, -0x1c, 0x10, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x10, 0x80, 0xe5, -0x1e, 0xff, 0x2f, 0xe1, 0xc0, 0x21, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, -0x1c, 0x10, 0x82, 0xe5, 0x01, 0x16, 0xa0, 0xe3, 0x14, 0x00, 0x82, 0xe5, -0x0c, 0x00, 0x81, 0xe5, 0x1c, 0x00, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, -0x1c, 0x00, 0x81, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0xb5, 0x0f, 0x1c, -0x38, 0x1c, 0x00, 0xf0, 0x17, 0xf8, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x1c, -0x00, 0xf0, 0x76, 0xf8, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x80, 0xb5, 0x0f, 0x1c, 0x38, 0x1c, 0x00, 0xf0, -0x09, 0xf8, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x68, 0xf8, -0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb4, 0x07, 0x68, -0x3a, 0x78, 0xd2, 0x07, 0xd2, 0x0f, 0x00, 0x24, 0x00, 0x2a, 0x03, 0xd0, -0xff, 0x22, 0x01, 0x32, 0x42, 0x60, 0x00, 0xe0, 0x44, 0x60, 0x3a, 0x7b, -0x7b, 0x7b, 0x1b, 0x02, 0x1a, 0x43, 0x81, 0x2a, 0x08, 0xd1, 0x01, 0x23, -0x5b, 0x02, 0x42, 0x68, 0x1a, 0x43, 0x42, 0x60, 0x04, 0x22, 0xbf, 0x18, -0x82, 0x60, 0x00, 0xe0, 0x84, 0x60, 0x3a, 0x7b, 0x7b, 0x7b, 0x1b, 0x02, -0x1a, 0x43, 0x08, 0x2a, 0x06, 0xd1, 0x06, 0x23, 0x41, 0x68, 0x19, 0x43, -0x41, 0x60, 0x81, 0x68, 0x0e, 0x31, 0x2c, 0xe0, 0x13, 0x02, 0x12, 0x0a, -0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x2e, 0x3a, -0x16, 0x4b, 0x9a, 0x42, 0x24, 0xd8, 0x01, 0x25, 0x42, 0x68, 0x15, 0x43, -0x45, 0x60, 0xba, 0x7b, 0xfb, 0x7b, 0x1b, 0x02, 0x1a, 0x43, 0x12, 0x4b, -0x9a, 0x42, 0x19, 0xd1, 0xfb, 0x1d, 0x09, 0x33, 0x44, 0xcb, 0x9b, 0x07, -0xdb, 0x0e, 0xda, 0x40, 0x5b, 0x42, 0x20, 0x33, 0x9e, 0x40, 0x16, 0x43, -0x03, 0x2e, 0x0f, 0xd1, 0x39, 0x7d, 0x7b, 0x7d, 0x1b, 0x02, 0x19, 0x43, -0x08, 0x29, 0x07, 0xd1, 0x04, 0x21, 0x29, 0x43, 0x41, 0x60, 0x81, 0x68, -0x16, 0x31, 0x81, 0x60, 0x01, 0x21, 0x01, 0xe0, 0x00, 0x21, 0x84, 0x60, -0x08, 0x1c, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0xae, 0x05, 0x00, 0x00, -0xaa, 0xaa, 0x00, 0x00, 0x80, 0xb4, 0x42, 0x68, 0xd1, 0x08, 0x3f, 0xd3, -0x01, 0x68, 0x83, 0x68, 0x59, 0x18, 0x02, 0x39, 0x8f, 0x78, 0x3f, 0x07, -0x3f, 0x0f, 0x05, 0x2f, 0x03, 0xd1, 0xda, 0x1d, 0x0d, 0x32, 0xc2, 0x60, -0x05, 0xe0, 0xbf, 0x00, 0xdb, 0x19, 0xc3, 0x60, 0x08, 0x23, 0x1a, 0x43, -0x42, 0x60, 0x8a, 0x78, 0x12, 0x07, 0x12, 0x0f, 0x92, 0x00, 0x02, 0x61, -0x0a, 0x79, 0x4b, 0x79, 0x1b, 0x02, 0x1a, 0x43, 0x13, 0x02, 0x12, 0x0a, -0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x42, 0x61, -0xca, 0x7a, 0x06, 0x2a, 0x03, 0xd1, 0x10, 0x23, 0x42, 0x68, 0x1a, 0x43, -0x10, 0xe0, 0x11, 0x2a, 0x03, 0xd1, 0x20, 0x23, 0x42, 0x68, 0x1a, 0x43, -0x0a, 0xe0, 0x33, 0x2a, 0x03, 0xd1, 0x40, 0x23, 0x42, 0x68, 0x1a, 0x43, -0x04, 0xe0, 0x32, 0x2a, 0x03, 0xd1, 0x80, 0x23, 0x42, 0x68, 0x1a, 0x43, -0x42, 0x60, 0xc9, 0x7a, 0xc0, 0x46, 0x01, 0x76, 0x80, 0xbc, 0x70, 0x47, -0x0a, 0x78, 0xc0, 0x46, 0x02, 0x60, 0x4b, 0x78, 0x1b, 0x02, 0x1a, 0x43, -0x02, 0x60, 0x8b, 0x78, 0x1b, 0x04, 0x1a, 0x43, 0x02, 0x60, 0xc9, 0x78, -0x09, 0x06, 0x11, 0x43, 0x01, 0x60, 0x70, 0x47, 0x80, 0xb5, 0x07, 0x1c, -0x48, 0x68, 0x80, 0x09, 0x26, 0xd3, 0xb8, 0x6a, 0xc9, 0x68, 0x40, 0x18, -0x01, 0x23, 0x9b, 0x07, 0x02, 0x30, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, -0x00, 0x0c, 0x11, 0x23, 0x9b, 0x02, 0x98, 0x42, 0x18, 0xd1, 0x78, 0x6a, -0x39, 0x6b, 0xc0, 0x46, 0x48, 0x62, 0x38, 0x6b, 0x02, 0xf0, 0xb0, 0xf8, -0x38, 0x1c, 0x01, 0xf0, 0x6d, 0xfd, 0x01, 0x20, 0x07, 0x49, 0xc0, 0x46, -0xc8, 0x72, 0x07, 0x49, 0x4a, 0x6c, 0x12, 0x18, 0x4a, 0x64, 0x06, 0x49, -0x8a, 0x6d, 0x12, 0x18, 0x8a, 0x65, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x00, 0x20, 0xfa, 0xe7, 0x98, 0x19, 0x00, 0x80, 0x78, 0x2a, 0x00, 0x80, -0x10, 0x2a, 0x00, 0x80, 0x81, 0x07, 0x19, 0xd0, 0x80, 0x08, 0x80, 0x00, -0x01, 0x23, 0x9b, 0x07, 0x01, 0x1d, 0x18, 0x43, -0x00, 0x68, 0x19, 0x43, 0x09, 0x68, 0x02, 0x02, 0x12, 0x0e, 0x12, 0x06, -0x00, 0x0a, 0xff, 0x23, 0x1b, 0x04, 0x18, 0x40, 0x10, 0x43, 0x0a, 0x0a, -0x12, 0x06, 0x12, 0x0e, 0x10, 0x43, 0x09, 0x02, 0x1b, 0x0a, 0x19, 0x40, -0x08, 0x43, 0x70, 0x47, 0x01, 0x23, 0x9b, 0x07, 0x18, 0x43, 0x00, 0x68, -0x01, 0x06, 0x02, 0x02, 0xff, 0x23, 0x1b, 0x04, 0x1a, 0x40, 0x11, 0x43, -0x02, 0x0a, 0x1b, 0x0a, 0x1a, 0x40, 0x11, 0x43, 0x00, 0x0e, 0x08, 0x43, -0xed, 0xe7, 0x00, 0x00, 0xf0, 0xb5, 0x04, 0x23, 0x81, 0x6b, 0x19, 0x40, -0x00, 0x22, 0x00, 0x29, 0x46, 0xd0, 0xc7, 0x1d, 0x39, 0x37, 0x39, 0x7b, -0x33, 0x29, 0x01, 0xd0, 0x32, 0x29, 0x3f, 0xd1, 0x01, 0x6b, 0xc0, 0x46, -0x4a, 0x65, 0xc4, 0x1d, 0x2d, 0x34, 0xcd, 0x1d, 0x2d, 0x35, 0x00, 0x22, -0x93, 0x00, 0xe6, 0x58, 0xc0, 0x46, 0xee, 0x50, 0x01, 0x32, 0x07, 0x2a, -0xf8, 0xd3, 0x82, 0x6a, 0xc0, 0x46, 0x4a, 0x63, 0x82, 0x6a, 0xc0, 0x46, -0x8a, 0x62, 0x7a, 0x8b, 0xcb, 0x1d, 0x39, 0x33, 0x5a, 0x83, 0x40, 0x6a, -0xc0, 0x46, 0x48, 0x62, 0x12, 0x48, 0x01, 0x27, 0x42, 0x68, 0x00, 0x2a, -0x10, 0xd1, 0xc2, 0x68, 0x00, 0x2a, 0x13, 0xd1, 0x42, 0x69, 0x00, 0x2a, -0x0d, 0xd1, 0x01, 0x61, 0xc1, 0x60, 0x01, 0x6a, 0x02, 0x29, 0x02, 0xd3, -0x20, 0x30, 0x07, 0x71, 0x0c, 0xe0, 0x00, 0xf0, 0x13, 0xf8, 0x09, 0xe0, -0xc2, 0x68, 0x00, 0x2a, 0x02, 0xd1, 0x01, 0x61, 0xc1, 0x60, 0x03, 0xe0, -0x02, 0x69, 0xc0, 0x46, 0x51, 0x65, 0x01, 0x61, 0x38, 0x1c, 0xf0, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x10, 0x1c, 0xfa, 0xe7, 0xec, 0x05, 0x00, 0x80, -0x80, 0xb5, 0x1e, 0x49, 0x00, 0x22, 0xcb, 0x68, 0x00, 0x2b, 0x34, 0xd0, -0xc8, 0x1d, 0xf9, 0x30, 0x83, 0x62, 0xcb, 0x68, 0x9b, 0x6a, 0xc0, 0x46, -0xc3, 0x62, 0xcf, 0x69, 0x7b, 0x00, 0xdf, 0x19, 0x7f, 0x02, 0x17, 0x4b, -0xff, 0x18, 0xff, 0x37, 0x65, 0x37, 0x83, 0x63, 0x07, 0x63, 0xcb, 0x1d, -0xff, 0x33, 0x5a, 0x33, 0x1a, 0x72, 0xcb, 0x69, 0x00, 0x2b, 0x01, 0xd0, -0xca, 0x61, 0x01, 0xe0, 0x01, 0x23, 0xcb, 0x61, 0x0f, 0x1c, 0xc9, 0x68, -0x49, 0x6a, 0x09, 0x89, 0x01, 0x31, 0x41, 0x63, 0xf8, 0x1d, 0xff, 0x30, -0x3a, 0x30, 0x42, 0x60, 0x02, 0x82, 0x82, 0x60, 0xc2, 0x60, 0x38, 0x1c, -0x00, 0xf0, 0xc4, 0xfa, 0x38, 0x6a, 0x01, 0x30, 0x38, 0x62, 0x38, 0x1c, -0x00, 0xf0, 0x0a, 0xf8, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x10, 0x1c, -0xfa, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0x1c, 0xad, 0x20, 0x40, -0xf0, 0xb5, 0x07, 0x1c, 0xf9, 0x1d, 0xf9, 0x31, 0x88, 0x6a, 0xc2, 0x1d, -0x2d, 0x32, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x32, 0x1a, 0x43, 0xc8, 0x6a, -0x12, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x80, 0x18, 0x82, 0x79, 0xc3, 0x79, -0x1b, 0x02, 0x1a, 0x43, 0x13, 0x02, 0x12, 0x0a, 0x12, 0x06, 0x12, 0x0e, -0x1a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x02, 0x38, 0x92, 0x04, 0x92, 0x0c, -0x00, 0x26, 0x25, 0x4d, 0xec, 0x1d, 0xff, 0x34, 0x3a, 0x34, 0x00, 0x2a, -0x04, 0xd0, 0x20, 0x8a, 0x01, 0x23, 0x9b, 0x02, 0x18, 0x43, 0x2b, 0xe0, -0x01, 0x23, 0x9b, 0x07, 0xc2, 0x1d, 0x0d, 0x32, 0x1a, 0x43, 0x12, 0x68, -0x12, 0x04, 0x12, 0x30, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, -0x10, 0x43, 0x03, 0x1c, 0xf8, 0x1d, 0xff, 0x30, 0x4a, 0x30, 0x82, 0x78, -0xc8, 0x6b, 0x19, 0x1c, 0x01, 0xf0, 0xd8, 0xff, 0x00, 0x28, 0x04, 0xda, -0x20, 0x8a, 0xff, 0x23, 0x01, 0x33, 0x18, 0x43, -0x0e, 0xe0, 0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x08, 0x60, 0x01, 0x04, -0x09, 0x0c, 0x38, 0x1c, 0x00, 0xf0, 0x1c, 0xf8, 0x00, 0x28, 0x14, 0xd1, -0x20, 0x8a, 0x01, 0x23, 0x5b, 0x02, 0x18, 0x43, 0x20, 0x82, 0x21, 0x8a, -0x38, 0x1c, 0x00, 0xf0, 0x98, 0xfb, 0xe8, 0x68, 0x01, 0x23, 0x9b, 0x07, -0x54, 0x30, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xe8, 0x60, 0x30, 0x1c, -0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, 0xfa, 0xe7, 0x00, 0x00, -0xec, 0x05, 0x00, 0x80, 0xf8, 0xb5, 0x07, 0x1c, 0xfc, 0x1d, 0xf9, 0x34, -0xa0, 0x6b, 0xa6, 0x6a, 0xc5, 0x1d, 0x0d, 0x35, 0x33, 0x48, 0xc0, 0x6a, -0x4b, 0x00, 0x59, 0x18, 0x49, 0x01, 0x42, 0x18, 0x01, 0x20, 0x80, 0x07, -0x10, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x90, 0x01, 0x23, -0x9b, 0x07, 0xd0, 0x1d, 0x05, 0x30, 0x18, 0x43, 0x00, 0x68, 0x38, 0x1c, -0x29, 0x1c, 0x00, 0xf0, 0xb8, 0xfa, 0xa8, 0x88, 0x40, 0x07, 0x01, 0xd0, -0x00, 0x20, 0x47, 0xe0, 0x00, 0x98, 0x01, 0x28, 0x25, 0xd1, 0xe0, 0x6a, +0xfe, 0xff, 0xff, 0xea, 0x02, 0x1b, 0xa0, 0xe3, 0x01, 0x06, 0xa0, 0xe3, +0x14, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0x21, 0x1f, 0xe5, +0x14, 0x30, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x80, 0xe5, +0x1c, 0x00, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xe5, +0x00, 0x10, 0xa0, 0xe3, 0x14, 0x10, 0x82, 0xe5, 0x01, 0x06, 0xa0, 0xe3, +0x1c, 0x10, 0x82, 0xe5, 0x0c, 0x10, 0x80, 0xe5, 0x1c, 0x10, 0x92, 0xe5, +0x00, 0x00, 0x00, 0x00, 0x1c, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, +0xc0, 0x21, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x10, 0x82, 0xe5, +0x01, 0x16, 0xa0, 0xe3, 0x14, 0x00, 0x82, 0xe5, 0x0c, 0x00, 0x81, 0xe5, +0x1c, 0x00, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x81, 0xe5, +0x1e, 0xff, 0x2f, 0xe1, 0x80, 0xb5, 0x0f, 0x1c, 0x38, 0x1c, 0x00, 0xf0, +0x17, 0xf8, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x1c, +0x00, 0xf0, 0x92, 0xf8, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x80, 0xb5, 0x0f, 0x1c, 0x38, 0x1c, 0x00, 0xf0, 0x09, 0xf8, 0x00, 0x28, +0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x84, 0xf8, 0x00, 0x20, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb4, 0x07, 0x68, 0x3a, 0x78, 0xd2, 0x07, +0xd2, 0x0f, 0x00, 0x24, 0x00, 0x2a, 0x03, 0xd0, 0xff, 0x22, 0x01, 0x32, +0x42, 0x60, 0x00, 0xe0, 0x44, 0x60, 0x3a, 0x7b, 0x7b, 0x7b, 0x1b, 0x02, +0x1a, 0x43, 0x81, 0x2a, 0x08, 0xd1, 0x01, 0x23, 0x5b, 0x02, 0x42, 0x68, +0x1a, 0x43, 0x42, 0x60, 0x04, 0x22, 0xbf, 0x18, 0x82, 0x60, 0x00, 0xe0, +0x84, 0x60, 0x3a, 0x7b, 0x7b, 0x7b, 0x1b, 0x02, 0x1a, 0x43, 0x08, 0x2a, +0x06, 0xd1, 0x06, 0x23, 0x41, 0x68, 0x19, 0x43, 0x41, 0x60, 0x81, 0x68, +0x0e, 0x31, 0x3c, 0xe0, 0xc1, 0x23, 0xdb, 0x00, 0x9a, 0x42, 0x03, 0xd1, +0x41, 0x68, 0x24, 0x4b, 0x19, 0x43, 0x3e, 0xe0, 0x23, 0x4b, 0x9a, 0x42, +0x04, 0xd1, 0x01, 0x23, 0x1b, 0x03, 0x41, 0x68, 0x19, 0x43, 0x36, 0xe0, +0x13, 0x02, 0x12, 0x0a, 0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04, +0x12, 0x0c, 0x2e, 0x3a, 0x1c, 0x4b, 0x9a, 0x42, 0x2d, 0xd8, 0x01, 0x25, +0x42, 0x68, 0x15, 0x43, 0x45, 0x60, 0xba, 0x7b, 0xfb, 0x7b, 0x1b, 0x02, +0x1a, 0x43, 0x18, 0x4b, 0x9a, 0x42, 0x22, 0xd1, 0xfb, 0x1d, 0x09, 0x33, +0x44, 0xcb, 0x9b, 0x07, 0xdb, 0x0e, 0xda, 0x40, 0x5b, 0x42, 0x20, 0x33, +0x9e, 0x40, 0x16, 0x43, 0x03, 0x2e, 0x18, 0xd1, 0x39, 0x7d, 0x7b, 0x7d, +0x1b, 0x02, 0x19, 0x43, 0x08, 0x29, 0x07, 0xd1, 0x04, 0x21, 0x29, 0x43, +0x41, 0x60, 0x81, 0x68, 0x16, 0x31, 0x81, 0x60, 0x01, 0x21, 0x0a, 0xe0, +0xc1, 0x23, 0xdb, 0x00, 0x99, 0x42, 0x04, 0xd1, 0x01, 0x21, 0x89, 0x03, +0x29, 0x43, 0x41, 0x60, 0x00, 0xe0, 0x84, 0x60, 0x00, 0x21, 0x08, 0x1c, +0xf0, 0xbc, 0x70, 0x47, 0x02, 0x40, 0x00, 0x00, 0x81, 0x80, 0x00, 0x00, +0xae, 0x05, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x80, 0xb4, 0x42, 0x68, +0xd1, 0x08, 0x3f, 0xd3, 0x01, 0x68, 0x83, 0x68, 0x59, 0x18, 0x02, 0x39, +0x8f, 0x78, 0x3f, 0x07, 0x3f, 0x0f, 0x05, 0x2f, 0x03, 0xd1, 0xda, 0x1d, +0x0d, 0x32, 0xc2, 0x60, 0x05, 0xe0, 0xbf, 0x00, 0xdb, 0x19, 0xc3, 0x60, +0x08, 0x23, 0x1a, 0x43, 0x42, 0x60, 0x8a, 0x78, 0x12, 0x07, 0x12, 0x0f, +0x92, 0x00, 0x02, 0x61, 0x0a, 0x79, 0x4b, 0x79, 0x1b, 0x02, 0x1a, 0x43, +0x13, 0x02, 0x12, 0x0a, 0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04, +0x12, 0x0c, 0x42, 0x61, 0xca, 0x7a, 0x06, 0x2a, 0x03, 0xd1, 0x10, 0x23, +0x42, 0x68, 0x1a, 0x43, 0x10, 0xe0, 0x11, 0x2a, 0x03, 0xd1, 0x20, 0x23, +0x42, 0x68, 0x1a, 0x43, 0x0a, 0xe0, 0x33, 0x2a, 0x03, 0xd1, 0x40, 0x23, +0x42, 0x68, 0x1a, 0x43, 0x04, 0xe0, 0x32, 0x2a, 0x03, 0xd1, 0x80, 0x23, +0x42, 0x68, 0x1a, 0x43, 0x42, 0x60, 0xc9, 0x7a, 0xc0, 0x46, 0x01, 0x76, +0x80, 0xbc, 0x70, 0x47, 0x0a, 0x78, 0xc0, 0x46, 0x02, 0x60, 0x4b, 0x78, +0x1b, 0x02, 0x1a, 0x43, 0x02, 0x60, 0x8b, 0x78, 0x1b, 0x04, 0x1a, 0x43, +0x02, 0x60, 0xc9, 0x78, 0x09, 0x06, 0x11, 0x43, 0x01, 0x60, 0x70, 0x47, +0x80, 0xb5, 0x07, 0x1c, 0x48, 0x68, 0x80, 0x09, 0x26, 0xd3, 0xb8, 0x6a, +0xc9, 0x68, 0x40, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x02, 0x30, 0x18, 0x43, +0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x11, 0x23, 0x9b, 0x02, 0x98, 0x42, +0x18, 0xd1, 0x78, 0x6a, 0x39, 0x6b, 0xc0, 0x46, +0x48, 0x62, 0x38, 0x6b, 0x02, 0xf0, 0xd0, 0xf8, 0x38, 0x1c, 0x01, 0xf0, +0x8b, 0xfd, 0x01, 0x20, 0x07, 0x49, 0xc0, 0x46, 0xc8, 0x73, 0x07, 0x49, +0x4a, 0x6c, 0x12, 0x18, 0x4a, 0x64, 0x06, 0x49, 0x8a, 0x6d, 0x12, 0x18, +0x8a, 0x65, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0xfa, 0xe7, +0x18, 0x1a, 0x00, 0x80, 0x0c, 0x2b, 0x00, 0x80, 0xa4, 0x2a, 0x00, 0x80, +0x81, 0x07, 0x19, 0xd0, 0x80, 0x08, 0x80, 0x00, 0x01, 0x23, 0x9b, 0x07, +0x01, 0x1d, 0x18, 0x43, 0x00, 0x68, 0x19, 0x43, 0x09, 0x68, 0x02, 0x02, +0x12, 0x0e, 0x12, 0x06, 0x00, 0x0a, 0xff, 0x23, 0x1b, 0x04, 0x18, 0x40, +0x10, 0x43, 0x0a, 0x0a, 0x12, 0x06, 0x12, 0x0e, 0x10, 0x43, 0x09, 0x02, +0x1b, 0x0a, 0x19, 0x40, 0x08, 0x43, 0x70, 0x47, 0x01, 0x23, 0x9b, 0x07, +0x18, 0x43, 0x00, 0x68, 0x01, 0x06, 0x02, 0x02, 0xff, 0x23, 0x1b, 0x04, +0x1a, 0x40, 0x11, 0x43, 0x02, 0x0a, 0x1b, 0x0a, 0x1a, 0x40, 0x11, 0x43, +0x00, 0x0e, 0x08, 0x43, 0xed, 0xe7, 0x00, 0x00, 0xf0, 0xb5, 0x04, 0x23, +0x81, 0x6b, 0x19, 0x40, 0x00, 0x22, 0x00, 0x29, 0x46, 0xd0, 0xc7, 0x1d, +0x39, 0x37, 0x39, 0x7b, 0x33, 0x29, 0x01, 0xd0, 0x32, 0x29, 0x3f, 0xd1, +0x01, 0x6b, 0xc0, 0x46, 0x4a, 0x65, 0xc4, 0x1d, 0x2d, 0x34, 0xcd, 0x1d, +0x2d, 0x35, 0x00, 0x22, 0x93, 0x00, 0xe6, 0x58, 0xc0, 0x46, 0xee, 0x50, +0x01, 0x32, 0x07, 0x2a, 0xf8, 0xd3, 0x82, 0x6a, 0xc0, 0x46, 0x4a, 0x63, +0x82, 0x6a, 0xc0, 0x46, 0x8a, 0x62, 0x7a, 0x8b, 0xcb, 0x1d, 0x39, 0x33, +0x5a, 0x83, 0x40, 0x6a, 0xc0, 0x46, 0x48, 0x62, 0x12, 0x48, 0x01, 0x27, +0x42, 0x68, 0x00, 0x2a, 0x10, 0xd1, 0xc2, 0x68, 0x00, 0x2a, 0x13, 0xd1, +0x42, 0x69, 0x00, 0x2a, 0x0d, 0xd1, 0x01, 0x61, 0xc1, 0x60, 0x01, 0x6a, +0x02, 0x29, 0x02, 0xd3, 0x20, 0x30, 0x07, 0x71, 0x0c, 0xe0, 0x00, 0xf0, +0x13, 0xf8, 0x09, 0xe0, 0xc2, 0x68, 0x00, 0x2a, 0x02, 0xd1, 0x01, 0x61, +0xc1, 0x60, 0x03, 0xe0, 0x02, 0x69, 0xc0, 0x46, 0x51, 0x65, 0x01, 0x61, +0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x10, 0x1c, 0xfa, 0xe7, +0x6c, 0x06, 0x00, 0x80, 0x80, 0xb5, 0x1e, 0x49, 0x00, 0x22, 0xcb, 0x68, +0x00, 0x2b, 0x34, 0xd0, 0xc8, 0x1d, 0xf9, 0x30, 0x83, 0x62, 0xcb, 0x68, +0x9b, 0x6a, 0xc0, 0x46, 0xc3, 0x62, 0xcf, 0x69, 0x7b, 0x00, 0xdf, 0x19, +0x7f, 0x02, 0x17, 0x4b, 0xff, 0x18, 0xff, 0x37, 0x65, 0x37, 0x83, 0x63, +0x07, 0x63, 0xcb, 0x1d, 0xff, 0x33, 0x5a, 0x33, 0x1a, 0x72, 0xcb, 0x69, +0x00, 0x2b, 0x01, 0xd0, 0xca, 0x61, 0x01, 0xe0, 0x01, 0x23, 0xcb, 0x61, +0x0f, 0x1c, 0xc9, 0x68, 0x49, 0x6a, 0x09, 0x89, 0x01, 0x31, 0x41, 0x63, +0xf8, 0x1d, 0xff, 0x30, 0x3a, 0x30, 0x42, 0x60, 0x02, 0x82, 0x82, 0x60, +0xc2, 0x60, 0x38, 0x1c, 0x00, 0xf0, 0xce, 0xfa, 0x38, 0x6a, 0x01, 0x30, +0x38, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0x0a, 0xf8, 0x80, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x10, 0x1c, 0xfa, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, +0x1c, 0xad, 0x20, 0x40, 0xf0, 0xb5, 0x07, 0x1c, 0xf9, 0x1d, 0xf9, 0x31, +0x88, 0x6a, 0xc2, 0x1d, 0x2d, 0x32, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x32, +0x1a, 0x43, 0xc8, 0x6a, 0x12, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x80, 0x18, +0x82, 0x79, 0xc3, 0x79, 0x1b, 0x02, 0x1a, 0x43, 0x13, 0x02, 0x12, 0x0a, +0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x02, 0x38, +0x92, 0x04, 0x92, 0x0c, 0x00, 0x26, 0x25, 0x4d, +0xec, 0x1d, 0xff, 0x34, 0x3a, 0x34, 0x00, 0x2a, 0x04, 0xd0, 0x20, 0x8a, +0x01, 0x23, 0x9b, 0x02, 0x18, 0x43, 0x2b, 0xe0, 0x01, 0x23, 0x9b, 0x07, +0xc2, 0x1d, 0x0d, 0x32, 0x1a, 0x43, 0x12, 0x68, 0x12, 0x04, 0x12, 0x30, +0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x10, 0x43, 0x03, 0x1c, +0xf8, 0x1d, 0xff, 0x30, 0x4a, 0x30, 0x82, 0x78, 0xc8, 0x6b, 0x19, 0x1c, +0x01, 0xf0, 0xf8, 0xff, 0x00, 0x28, 0x04, 0xda, 0x20, 0x8a, 0xff, 0x23, +0x01, 0x33, 0x18, 0x43, 0x0e, 0xe0, 0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x31, +0x08, 0x60, 0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0x00, 0xf0, 0x1c, 0xf8, +0x00, 0x28, 0x14, 0xd1, 0x20, 0x8a, 0x01, 0x23, 0x5b, 0x02, 0x18, 0x43, +0x20, 0x82, 0x21, 0x8a, 0x38, 0x1c, 0x00, 0xf0, 0xa2, 0xfb, 0xe8, 0x68, +0x01, 0x23, 0x9b, 0x07, 0x54, 0x30, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, +0xe8, 0x60, 0x30, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, +0xfa, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, 0xf8, 0xb5, 0x07, 0x1c, +0xfc, 0x1d, 0xf9, 0x34, 0xa0, 0x6b, 0xa6, 0x6a, 0xc5, 0x1d, 0x0d, 0x35, +0x38, 0x48, 0xc0, 0x6a, 0x4b, 0x00, 0x59, 0x18, 0x49, 0x01, 0x42, 0x18, +0x01, 0x20, 0x80, 0x07, 0x10, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, +0x00, 0x90, 0x01, 0x23, 0x9b, 0x07, 0xd0, 0x1d, 0x05, 0x30, 0x18, 0x43, +0x00, 0x68, 0x38, 0x1c, 0x29, 0x1c, 0x00, 0xf0, 0xc2, 0xfa, 0xa8, 0x88, +0x41, 0x07, 0x01, 0xd0, 0x00, 0x20, 0x51, 0xe0, 0x29, 0x89, 0x09, 0x18, +0x60, 0x6b, 0x81, 0x42, 0xf8, 0xd8, 0x69, 0x89, 0xea, 0x88, 0x89, 0x18, +0x81, 0x42, 0xf3, 0xd8, 0x00, 0x98, 0x01, 0x28, 0x25, 0xd1, 0xe0, 0x6a, 0xf1, 0x6b, 0x40, 0x18, 0x71, 0x6c, 0xfa, 0x1d, 0xcd, 0x32, 0x01, 0xf0, -0x2b, 0xf9, 0xfa, 0x1d, 0xff, 0x32, 0x3a, 0x32, 0xe0, 0x6a, 0x51, 0x69, +0x29, 0xf9, 0xfa, 0x1d, 0xff, 0x32, 0x3a, 0x32, 0xe0, 0x6a, 0x51, 0x69, 0x40, 0x18, 0xc3, 0x1d, 0x03, 0x33, 0x00, 0x20, 0x81, 0x00, 0x5e, 0x58, 0xc9, 0x19, 0xff, 0x31, 0x01, 0x31, 0x4e, 0x61, 0x01, 0x30, 0x04, 0x28, 0xf6, 0xd3, 0xe0, 0x6a, 0x51, 0x69, 0x40, 0x18, 0xc1, 0x1d, 0x05, 0x31, 0x00, 0x20, 0x00, 0x22, 0x43, 0x00, 0xca, 0x52, 0x01, 0x30, 0x06, 0x28, -0xfa, 0xd3, 0x29, 0x1c, 0x11, 0x4a, 0x00, 0x20, 0xff, 0xf7, 0xd4, 0xfb, +0xfa, 0xd3, 0x29, 0x1c, 0x11, 0x4a, 0x00, 0x20, 0xff, 0xf7, 0xae, 0xfb, 0x01, 0x22, 0x52, 0x04, 0x60, 0x6b, 0x02, 0x43, 0x01, 0x20, 0x21, 0x6b, -0xff, 0xf7, 0xcc, 0xfb, 0x01, 0x22, 0x52, 0x04, 0x60, 0x6b, 0x02, 0x43, -0x00, 0x20, 0xe1, 0x6a, 0xff, 0xf7, 0xc4, 0xfb, 0xa1, 0x6b, 0x08, 0x4a, -0x01, 0x20, 0xff, 0xf7, 0xbf, 0xfb, 0x03, 0x20, 0x06, 0x49, 0xc0, 0x46, +0xff, 0xf7, 0xa6, 0xfb, 0x01, 0x22, 0x52, 0x04, 0x60, 0x6b, 0x02, 0x43, +0x00, 0x20, 0xe1, 0x6a, 0xff, 0xf7, 0x9e, 0xfb, 0xa1, 0x6b, 0x08, 0x4a, +0x01, 0x20, 0xff, 0xf7, 0x99, 0xfb, 0x03, 0x20, 0x06, 0x49, 0xc0, 0x46, 0x48, 0x62, 0x01, 0x20, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, -0xc8, 0x29, 0x00, 0x80, 0x54, 0x00, 0x03, 0x00, 0x14, 0x00, 0x0f, 0x00, -0xec, 0x06, 0x00, 0x80, 0xf0, 0xb5, 0x8d, 0xb0, 0x00, 0x20, 0xb5, 0x4a, +0x4c, 0x2a, 0x00, 0x80, 0x54, 0x00, 0x03, 0x00, 0x14, 0x00, 0x0f, 0x00, +0x6c, 0x07, 0x00, 0x80, 0xf0, 0xb5, 0x8d, 0xb0, 0x00, 0x20, 0xb5, 0x4a, 0xd5, 0x1d, 0xf9, 0x35, 0x68, 0x62, 0x01, 0x20, 0x00, 0x05, 0xb3, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xa8, 0x6a, 0xc4, 0x1d, 0x2d, 0x34, 0xb1, 0x48, 0xc0, 0x6a, 0xd7, 0x1d, 0xff, 0x37, 0x3a, 0x37, 0x39, 0x68, 0x4b, 0x00, @@ -409,18 +418,18 @@ 0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0x08, 0x30, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0x09, 0x90, 0xff, 0x23, 0x1b, 0x02, 0x18, 0x40, 0x00, 0x0a, 0x0a, 0x90, 0x0a, 0x98, 0xa4, 0x4e, 0x01, 0x28, 0x59, 0xd1, 0x28, 0x6b, -0xa2, 0x68, 0x80, 0x18, 0xa2, 0x4a, 0x21, 0x69, 0x09, 0x04, 0x09, 0x0c, -0x01, 0xf0, 0x1e, 0xf9, 0x28, 0x6b, 0x79, 0x69, 0x40, 0x18, 0xc1, 0x1d, -0x05, 0x31, 0x00, 0x20, 0x82, 0x00, 0x98, 0x4b, 0xd3, 0x18, 0xff, 0x33, -0x01, 0x33, 0x5b, 0x69, 0xc0, 0x46, 0x8b, 0x50, 0x01, 0x30, 0x04, 0x28, -0xf4, 0xd3, 0x00, 0x20, 0x31, 0x1c, 0x82, 0x00, 0x56, 0x18, 0x01, 0x23, -0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x04, 0xae, 0xb3, 0x50, 0x01, 0x30, -0x03, 0x28, 0xf4, 0xd3, 0x00, 0x20, 0x08, 0x90, 0x90, 0x49, 0x42, 0x00, -0x8b, 0x5a, 0xb2, 0x5a, 0x93, 0x42, 0x13, 0xd0, 0x8e, 0x48, 0xc1, 0x89, -0x01, 0x31, 0xc1, 0x81, 0xb8, 0x68, 0x00, 0x28, +0xa2, 0x68, 0x80, 0x18, 0xa2, 0x4a, 0x21, 0x69, +0x09, 0x04, 0x09, 0x0c, 0x01, 0xf0, 0x1c, 0xf9, 0x28, 0x6b, 0x79, 0x69, +0x40, 0x18, 0xc1, 0x1d, 0x05, 0x31, 0x00, 0x20, 0x82, 0x00, 0x98, 0x4b, +0xd3, 0x18, 0xff, 0x33, 0x01, 0x33, 0x5b, 0x69, 0xc0, 0x46, 0x8b, 0x50, +0x01, 0x30, 0x04, 0x28, 0xf4, 0xd3, 0x00, 0x20, 0x31, 0x1c, 0x82, 0x00, +0x56, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x04, 0xae, +0xb3, 0x50, 0x01, 0x30, 0x03, 0x28, 0xf4, 0xd3, 0x00, 0x20, 0x08, 0x90, +0x90, 0x49, 0x42, 0x00, 0x8b, 0x5a, 0xb2, 0x5a, 0x93, 0x42, 0x13, 0xd0, +0x8e, 0x48, 0xc1, 0x89, 0x01, 0x31, 0xc1, 0x81, 0xb8, 0x68, 0x00, 0x28, 0x03, 0xd1, 0x38, 0x8a, 0x10, 0x23, 0x18, 0x43, 0x71, 0xe0, 0x38, 0x8a, 0x40, 0x23, 0x18, 0x43, 0x6d, 0xe0, 0x00, 0xf0, 0x11, 0xf9, 0x01, 0xf0, -0x47, 0xff, 0xf5, 0xe0, 0x01, 0x30, 0x06, 0x28, 0xe3, 0xd3, 0x08, 0x98, +0x5d, 0xff, 0xf5, 0xe0, 0x01, 0x30, 0x06, 0x28, 0xe3, 0xd3, 0x08, 0x98, 0x00, 0x28, 0x0c, 0xd1, 0xb8, 0x68, 0x41, 0x1c, 0xb9, 0x60, 0x00, 0x28, 0x03, 0xd1, 0x38, 0x8a, 0x01, 0x23, 0x18, 0x43, 0x02, 0xe0, 0x38, 0x8a, 0x04, 0x23, 0x18, 0x43, 0x38, 0x82, 0x78, 0x68, 0x01, 0x30, 0x78, 0x60, @@ -452,20 +461,20 @@ 0x01, 0x23, 0x9b, 0x07, 0xe0, 0x1d, 0x01, 0x30, 0x18, 0x43, 0x00, 0x68, 0xe1, 0x1d, 0x0d, 0x31, 0x19, 0x43, 0x09, 0x68, 0x40, 0x18, 0x00, 0x04, 0x00, 0x0c, 0xf9, 0x68, 0x4a, 0x1c, 0xfa, 0x60, 0x00, 0x29, 0xbc, 0xd1, -0xb6, 0xe7, 0x01, 0x23, 0x9b, 0x07, 0xe1, 0x1d, 0x05, 0x31, 0x19, 0x43, -0x09, 0x68, 0x09, 0x06, 0x09, 0x0e, 0xa1, 0x60, 0xe8, 0x6a, 0xc0, 0x46, -0x20, 0x60, 0x20, 0x1c, 0xff, 0xf7, 0x92, 0xfc, 0x20, 0x7e, 0x33, 0x28, -0x01, 0xd0, 0x32, 0x28, 0x11, 0xd1, 0x01, 0x21, 0x14, 0x4c, 0xc0, 0x46, -0xf9, 0x60, 0xb9, 0x60, 0x20, 0x1c, 0x00, 0xf0, 0x85, 0xf8, 0x28, 0x6b, -0xa9, 0x6a, 0xc0, 0x46, 0x88, 0x62, 0x20, 0x1c, 0xff, 0xf7, 0xca, 0xfd, -0x00, 0x28, 0x11, 0xd1, 0x0e, 0xe0, 0x00, 0x20, 0x30, 0x72, 0x11, 0xe0, -0x33, 0x29, 0x01, 0xd0, 0x32, 0x29, 0x0d, 0xd1, 0x07, 0x1c, 0x00, 0xf0, -0x71, 0xf8, 0x38, 0x1c, 0xff, 0xf7, 0xba, 0xfd, -0x00, 0x28, 0x01, 0xd1, 0x01, 0xf0, 0x50, 0xfe, 0x0d, 0xb0, 0xf0, 0xbc, +0xb6, 0xe7, 0x01, 0x23, 0x9b, 0x07, 0xe1, 0x1d, +0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0x09, 0x06, 0x09, 0x0e, 0xa1, 0x60, +0xe8, 0x6a, 0xc0, 0x46, 0x20, 0x60, 0x20, 0x1c, 0xff, 0xf7, 0x88, 0xfc, +0x20, 0x7e, 0x33, 0x28, 0x01, 0xd0, 0x32, 0x28, 0x11, 0xd1, 0x01, 0x21, +0x14, 0x4c, 0xc0, 0x46, 0xf9, 0x60, 0xb9, 0x60, 0x20, 0x1c, 0x00, 0xf0, +0x85, 0xf8, 0x28, 0x6b, 0xa9, 0x6a, 0xc0, 0x46, 0x88, 0x62, 0x20, 0x1c, +0xff, 0xf7, 0xc0, 0xfd, 0x00, 0x28, 0x11, 0xd1, 0x0e, 0xe0, 0x00, 0x20, +0x30, 0x72, 0x11, 0xe0, 0x33, 0x29, 0x01, 0xd0, 0x32, 0x29, 0x0d, 0xd1, +0x07, 0x1c, 0x00, 0xf0, 0x71, 0xf8, 0x38, 0x1c, 0xff, 0xf7, 0xb0, 0xfd, +0x00, 0x28, 0x01, 0xd1, 0x01, 0xf0, 0x66, 0xfe, 0x0d, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xf0, 0x12, 0xf8, 0xf6, 0xe7, 0x00, 0x00, -0xec, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0xc8, 0x29, 0x00, 0x80, -0x1c, 0xad, 0x20, 0x40, 0xc0, 0x06, 0x00, 0x80, 0x02, 0x07, 0x00, 0x80, -0x78, 0x2a, 0x00, 0x80, 0xec, 0x06, 0x00, 0x80, 0xf0, 0xb5, 0x25, 0x48, +0x6c, 0x06, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0x4c, 0x2a, 0x00, 0x80, +0x1c, 0xad, 0x20, 0x40, 0x40, 0x07, 0x00, 0x80, 0x82, 0x07, 0x00, 0x80, +0x0c, 0x2b, 0x00, 0x80, 0x6c, 0x07, 0x00, 0x80, 0xf0, 0xb5, 0x25, 0x48, 0x41, 0x68, 0x01, 0x31, 0x41, 0x60, 0x24, 0x4f, 0xf9, 0x1d, 0xf9, 0x31, 0x00, 0x24, 0x88, 0x6a, 0xfa, 0x68, 0xc0, 0x46, 0x94, 0x61, 0x04, 0x22, 0xfb, 0x68, 0xc0, 0x46, 0xda, 0x60, 0x10, 0x22, 0xfb, 0x68, 0xc0, 0x46, @@ -476,10 +485,10 @@ 0x4a, 0x6b, 0xfb, 0x68, 0xc0, 0x46, 0xda, 0x81, 0x0a, 0x6b, 0xc0, 0x46, 0x82, 0x62, 0xc4, 0x62, 0xc3, 0x1d, 0x39, 0x33, 0x4a, 0x6b, 0xc0, 0x46, 0x5a, 0x83, 0x04, 0x23, 0x02, 0x68, 0x1a, 0x43, 0x02, 0x60, 0x88, 0x6a, -0x01, 0xf0, 0x14, 0xfa, 0xf8, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x54, 0x30, +0x01, 0xf0, 0x28, 0xfa, 0xf8, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x54, 0x30, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xf8, 0x60, 0xf0, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, -0x2c, 0x07, 0x00, 0x80, 0x80, 0xb5, 0xc1, 0x1d, 0xf9, 0x31, 0x8a, 0x6a, +0x18, 0x47, 0x00, 0x00, 0x0c, 0x2b, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80, +0xac, 0x07, 0x00, 0x80, 0x80, 0xb5, 0xc1, 0x1d, 0xf9, 0x31, 0x8a, 0x6a, 0x01, 0x23, 0x9b, 0x07, 0xd1, 0x1d, 0x45, 0x31, 0x19, 0x43, 0x09, 0x68, 0x0b, 0x06, 0x1b, 0x0e, 0x01, 0x27, 0xc1, 0x1d, 0xff, 0x31, 0x4a, 0x31, 0x33, 0x2b, 0x05, 0xd1, 0x8b, 0x70, 0x01, 0x1c, 0x10, 0x1c, 0x00, 0xf0, @@ -495,15 +504,15 @@ 0xf8, 0x1d, 0x01, 0x30, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0xb9, 0x1d, 0x19, 0x43, 0xd0, 0x63, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x08, 0x43, 0xd0, 0x63, 0x90, 0xbc, 0x70, 0x47, 0xb0, 0xb5, 0xca, 0x1d, 0xf9, 0x32, -0xc5, 0x1d, 0x2d, 0x35, 0x32, 0x20, 0xcf, 0x1d, 0xff, 0x37, 0x4a, 0x37, -0xd3, 0x6a, 0xc0, 0x46, 0xb8, 0x70, 0xcc, 0x1d, 0xff, 0x34, 0x3a, 0x34, -0xe8, 0x68, 0xc0, 0x46, 0x60, 0x61, 0x10, 0x30, 0xe8, 0x60, 0x60, 0x69, -0xc0, 0x18, 0x87, 0x1e, 0x01, 0x23, 0x9b, 0x07, 0x38, 0x1d, 0x18, 0x43, -0x00, 0x68, 0x00, 0x04, 0xb9, 0x1c, 0x19, 0x43, 0xd0, 0x63, 0x09, 0x68, -0x09, 0x04, 0x09, 0x0c, 0x08, 0x43, 0xd0, 0x63, 0xf8, 0x1d, 0x03, 0x30, -0xff, 0xf7, 0x06, 0xfc, 0x20, 0x62, 0xf8, 0x1d, 0x07, 0x30, 0xff, 0xf7, -0x01, 0xfc, 0x60, 0x62, 0x00, 0x20, 0x28, 0x76, 0xb0, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0xf7, 0xb5, 0x81, 0xb0, 0x01, 0x98, +0xc5, 0x1d, 0x2d, 0x35, 0x32, 0x20, 0xcf, 0x1d, +0xff, 0x37, 0x4a, 0x37, 0xd3, 0x6a, 0xc0, 0x46, 0xb8, 0x70, 0xcc, 0x1d, +0xff, 0x34, 0x3a, 0x34, 0xe8, 0x68, 0xc0, 0x46, 0x60, 0x61, 0x10, 0x30, +0xe8, 0x60, 0x60, 0x69, 0xc0, 0x18, 0x87, 0x1e, 0x01, 0x23, 0x9b, 0x07, +0x38, 0x1d, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0xb9, 0x1c, 0x19, 0x43, +0xd0, 0x63, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x08, 0x43, 0xd0, 0x63, +0xf8, 0x1d, 0x03, 0x30, 0xff, 0xf7, 0xfc, 0xfb, 0x20, 0x62, 0xf8, 0x1d, +0x07, 0x30, 0xff, 0xf7, 0xf7, 0xfb, 0x60, 0x62, 0x00, 0x20, 0x28, 0x76, +0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf7, 0xb5, 0x81, 0xb0, 0x01, 0x98, 0xc7, 0x1d, 0xf9, 0x37, 0xb8, 0x6a, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 0x05, 0x34, 0x23, 0x43, 0x1c, 0x68, 0xff, 0x23, 0xfe, 0x33, 0x23, 0x40, 0x7f, 0x6b, 0x3f, 0x04, 0x3b, 0x43, 0x0b, 0x60, 0x34, 0x30, 0x1c, 0x1c, @@ -537,86 +546,85 @@ 0x04, 0x23, 0x90, 0x6a, 0xc0, 0x46, 0xc3, 0x60, 0x10, 0x23, 0x83, 0x61, 0xcb, 0x0a, 0x01, 0xd3, 0x18, 0x23, 0x83, 0x61, 0xc1, 0x83, 0x51, 0x6b, 0xc0, 0x46, 0xc1, 0x81, 0x51, 0x6b, 0xc2, 0x1d, 0x39, 0x32, 0x51, 0x83, -0x04, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x01, 0xf0, 0xa4, 0xf8, -0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0xb0, 0xb5, 0x1b, 0x4c, -0x20, 0x6a, 0x02, 0x28, 0x1b, 0xd2, 0x00, 0x20, 0xe7, 0x1d, 0x19, 0x37, -0x38, 0x71, 0xe1, 0x68, 0xe0, 0x1d, 0xf9, 0x30, 0x00, 0x29, 0x15, 0xd0, -0x42, 0x6a, 0x00, 0x2a, 0x12, 0xd1, 0x01, 0x25, 0x0a, 0xe0, 0xff, 0xf7, -0x93, 0xfb, 0x00, 0x28, 0x09, 0xd1, 0x20, 0x6a, 0x02, 0x28, 0x00, 0xd3, -0x3d, 0x71, 0xe0, 0x68, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x79, 0x00, 0x28, -0xf1, 0xd0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x40, 0x6a, 0x00, 0x28, -0xf9, 0xd1, 0x00, 0x29, 0xf7, 0xd1, 0x60, 0x69, 0x00, 0x28, 0x04, 0xd0, -0x06, 0x48, 0x00, 0x68, 0x03, 0xf0, 0x8e, 0xfc, +0x04, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x01, 0xf0, 0xb8, 0xf8, +0x08, 0xbc, 0x18, 0x47, 0x0c, 0x2b, 0x00, 0x80, +0xb0, 0xb5, 0x1b, 0x4c, 0x20, 0x6a, 0x02, 0x28, 0x1b, 0xd2, 0x00, 0x20, +0xe7, 0x1d, 0x19, 0x37, 0x38, 0x71, 0xe1, 0x68, 0xe0, 0x1d, 0xf9, 0x30, +0x00, 0x29, 0x15, 0xd0, 0x42, 0x6a, 0x00, 0x2a, 0x12, 0xd1, 0x01, 0x25, +0x0a, 0xe0, 0xff, 0xf7, 0x89, 0xfb, 0x00, 0x28, 0x09, 0xd1, 0x20, 0x6a, +0x02, 0x28, 0x00, 0xd3, 0x3d, 0x71, 0xe0, 0x68, 0x00, 0x28, 0x02, 0xd0, +0x38, 0x79, 0x00, 0x28, 0xf1, 0xd0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x40, 0x6a, 0x00, 0x28, 0xf9, 0xd1, 0x00, 0x29, 0xf7, 0xd1, 0x60, 0x69, +0x00, 0x28, 0x04, 0xd0, 0x06, 0x48, 0x00, 0x68, 0x03, 0xf0, 0x9e, 0xfc, 0xef, 0xe7, 0x60, 0x68, 0x00, 0x28, 0xec, 0xd0, 0x00, 0xf0, 0x50, 0xf8, -0xe9, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0xb4, 0x03, 0x00, 0x80, +0xe9, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, 0x34, 0x04, 0x00, 0x80, 0xb0, 0xb5, 0x07, 0x1c, 0x20, 0x23, 0xb8, 0x68, 0x18, 0x40, 0x00, 0x25, 0x00, 0x28, 0x03, 0xd1, 0x28, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xc4, 0x23, 0x48, 0x68, 0x18, 0x40, 0x01, 0x24, 0x00, 0x28, 0x03, 0xd1, -0x38, 0x6a, 0x00, 0xf0, 0x0d, 0xfc, 0x2f, 0xe0, 0x38, 0x1c, 0x00, 0xf0, -0x1d, 0xfc, 0x38, 0x1c, 0x00, 0xf0, 0x7e, 0xfa, 0xb8, 0x68, 0xc0, 0x08, -0x02, 0xd3, 0x38, 0x6a, 0x00, 0xf0, 0xd2, 0xfb, 0xb8, 0x68, 0x39, 0x6a, +0x38, 0x6a, 0x00, 0xf0, 0x09, 0xfc, 0x2f, 0xe0, 0x38, 0x1c, 0x00, 0xf0, +0x19, 0xfc, 0x38, 0x1c, 0x00, 0xf0, 0x78, 0xfa, 0xb8, 0x68, 0xc0, 0x08, +0x02, 0xd3, 0x38, 0x6a, 0x00, 0xf0, 0xce, 0xfb, 0xb8, 0x68, 0x39, 0x6a, 0xc0, 0x46, 0x88, 0x60, 0x38, 0x6a, 0xc0, 0x46, 0xc5, 0x60, 0x0f, 0x48, 0x41, 0x68, 0x00, 0x29, 0x11, 0xd1, 0xc1, 0x68, 0x00, 0x29, 0x09, 0xd1, 0x41, 0x69, 0x00, 0x29, 0x06, 0xd1, 0x39, 0x6a, 0xc0, 0x46, 0x81, 0x60, 0x41, 0x60, 0x00, 0xf0, 0x11, 0xf8, 0x0b, 0xe0, 0x39, 0x6a, 0xc0, 0x46, 0x81, 0x60, 0x41, 0x60, 0x06, 0xe0, 0x39, 0x6a, 0x82, 0x68, 0xc0, 0x46, 0xd1, 0x60, 0x39, 0x6a, 0xc0, 0x46, 0x81, 0x60, 0x20, 0x1c, 0xc0, 0xe7, -0xec, 0x05, 0x00, 0x80, 0x90, 0xb5, 0x0b, 0x4c, 0x67, 0x68, 0x00, 0x2f, +0x6c, 0x06, 0x00, 0x80, 0x90, 0xb5, 0x0b, 0x4c, 0x67, 0x68, 0x00, 0x2f, 0x0f, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x12, 0xf8, 0x00, 0x28, 0x0a, 0xd1, 0x60, 0x68, 0xc0, 0x68, 0xc0, 0x46, 0x60, 0x60, 0x38, 0x1c, 0x00, 0xf0, -0xc7, 0xfb, 0x00, 0x20, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, -0xfa, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0xf0, 0xb5, 0x07, 0x1c, +0xc3, 0xfb, 0x00, 0x20, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, +0xfa, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, 0xf0, 0xb5, 0x07, 0x1c, 0xfe, 0x1d, 0x49, 0x36, 0x30, 0x78, 0x40, 0x00, 0xc0, 0x19, 0x85, 0x8b, -0x2d, 0x4b, 0x9d, 0x42, 0x56, 0xd0, 0x2d, 0x4c, 0x38, 0x1c, 0x21, 0x1c, -0x2a, 0x1c, 0x00, 0xf0, 0x23, 0xf9, 0xa0, 0x88, 0x40, 0x07, 0x4d, 0xd1, -0x29, 0x48, 0x80, 0x6a, 0x58, 0x21, 0x69, 0x43, 0x40, 0x18, 0x01, 0x23, -0x9b, 0x07, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x25, 0x4d, -0x01, 0x28, 0x1a, 0xd1, 0x30, 0x78, 0xc0, 0x19, 0xc1, 0x1d, 0x19, 0x31, -0x08, 0x7a, 0x3a, 0x68, 0x80, 0x18, 0x09, 0x7b, 0xea, 0x1d, 0x21, 0x32, -0x00, 0xf0, 0xe2, 0xfc, 0x30, 0x78, 0xc0, 0x19, 0x20, 0x30, 0x00, 0x79, -0x39, 0x68, 0x40, 0x18, 0xc1, 0x1d, 0x05, 0x31, 0x00, 0x20, 0x00, 0x22, -0x43, 0x00, 0xca, 0x52, 0x01, 0x30, 0x06, 0x28, 0xfa, 0xd3, 0x21, 0x1c, -0x16, 0x4a, 0x00, 0x20, 0xfe, 0xf7, 0x9a, 0xff, 0x01, 0x22, 0x52, 0x04, -0x78, 0x68, 0x02, 0x43, 0x01, 0x20, 0x39, 0x68, 0xfe, 0xf7, 0x92, 0xff, -0x01, 0x22, 0x52, 0x04, 0x78, 0x68, 0x02, 0x43, 0x00, 0x20, 0x39, 0x68, -0xfe, 0xf7, 0x8a, 0xff, 0x0d, 0x49, 0x0e, 0x4a, 0x01, 0x20, 0xfe, 0xf7, -0x85, 0xff, 0x01, 0x20, 0xe9, 0x1d, 0x19, 0x31, 0x48, 0x71, 0x02, 0x21, -0xea, 0x1d, 0xf9, 0x32, 0x51, 0x62, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x00, 0x20, 0xfa, 0xe7, 0xff, 0xff, 0x00, 0x00, 0x98, 0xad, 0x20, 0x40, -0xc8, 0x29, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, 0x54, 0x00, 0x03, 0x00, -0x84, 0xad, 0x20, 0x40, 0x14, 0x00, 0x07, 0x00, 0xf0, 0xb5, 0x83, 0xb0, -0x00, 0x21, 0x58, 0x48, 0xc2, 0x1d, 0xf9, 0x32, 0x51, 0x62, 0x01, 0x21, -0xc9, 0x04, 0x56, 0x4a, 0xc0, 0x46, 0x11, 0x60, 0xc1, 0x1d, 0x19, 0x31, -0x49, 0x79, 0x00, 0x29, 0x04, 0xd1, 0x53, 0x48, 0x00, 0x68, 0x03, 0xf0, -0x97, 0xfb, 0x98, 0xe0, 0x4e, 0x48, 0x47, 0x68, 0xfc, 0x1d, 0x49, 0x34, -0x22, 0x78, 0x50, 0x00, 0xc0, 0x19, 0x80, 0x8b, -0x4d, 0x49, 0x89, 0x6a, 0x58, 0x23, 0x58, 0x43, 0x0d, 0x18, 0x01, 0x23, -0x9b, 0x07, 0xe9, 0x1d, 0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0x08, 0x35, +0x33, 0x4c, 0x34, 0x4b, 0x9d, 0x42, 0x3c, 0xd0, 0x38, 0x1c, 0x21, 0x1c, +0x2a, 0x1c, 0x00, 0xf0, 0x1d, 0xf9, 0x31, 0x48, 0x80, 0x6a, 0x58, 0x21, +0x69, 0x43, 0x40, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x18, 0x43, 0x00, 0x68, +0x00, 0x04, 0x00, 0x0c, 0x2c, 0x4d, 0x01, 0x28, 0x1a, 0xd1, 0x30, 0x78, +0xc0, 0x19, 0xc1, 0x1d, 0x19, 0x31, 0x08, 0x7a, 0x3a, 0x68, 0x80, 0x18, +0x09, 0x7b, 0xea, 0x1d, 0x21, 0x32, 0x00, 0xf0, 0xe3, 0xfc, 0x30, 0x78, +0xc0, 0x19, 0x20, 0x30, 0x00, 0x79, 0x39, 0x68, 0x40, 0x18, 0xc1, 0x1d, +0x05, 0x31, 0x00, 0x20, 0x00, 0x23, 0x42, 0x00, 0x8b, 0x52, 0x01, 0x30, +0x06, 0x28, 0xfa, 0xd3, 0xa0, 0x88, 0x41, 0x07, 0x0b, 0xd1, 0x21, 0x89, +0x09, 0x18, 0x78, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x81, 0x42, 0x04, 0xd8, +0x61, 0x89, 0xe2, 0x88, 0x89, 0x18, 0x81, 0x42, 0x03, 0xd9, 0x00, 0x20, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x21, 0x1c, 0x14, 0x4a, 0x00, 0x20, +0xfe, 0xf7, 0x64, 0xff, 0x01, 0x22, 0x52, 0x04, 0x78, 0x68, 0x02, 0x43, +0x01, 0x20, 0x39, 0x68, 0xfe, 0xf7, 0x5c, 0xff, 0x01, 0x22, 0x52, 0x04, +0x78, 0x68, 0x02, 0x43, 0x00, 0x20, 0x39, 0x68, +0xfe, 0xf7, 0x54, 0xff, 0x0b, 0x49, 0x0c, 0x4a, 0x01, 0x20, 0xfe, 0xf7, +0x4f, 0xff, 0x01, 0x20, 0xe9, 0x1d, 0x19, 0x31, 0x48, 0x71, 0x02, 0x21, +0xea, 0x1d, 0xf9, 0x32, 0x51, 0x62, 0xd9, 0xe7, 0x98, 0xad, 0x20, 0x40, +0xff, 0xff, 0x00, 0x00, 0x4c, 0x2a, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80, +0x54, 0x00, 0x03, 0x00, 0x84, 0xad, 0x20, 0x40, 0x14, 0x00, 0x07, 0x00, +0xf0, 0xb5, 0x83, 0xb0, 0x00, 0x21, 0x4f, 0x48, 0xc2, 0x1d, 0xf9, 0x32, +0x51, 0x62, 0x01, 0x21, 0xc9, 0x04, 0x4d, 0x4a, 0xc0, 0x46, 0x11, 0x60, +0xc1, 0x1d, 0x19, 0x31, 0x49, 0x79, 0x00, 0x29, 0x04, 0xd1, 0x4a, 0x48, +0x00, 0x68, 0x03, 0xf0, 0x9b, 0xfb, 0x87, 0xe0, 0x45, 0x48, 0x47, 0x68, +0xfc, 0x1d, 0x49, 0x34, 0x21, 0x78, 0x48, 0x00, 0xc0, 0x19, 0x80, 0x8b, +0x44, 0x4a, 0x92, 0x6a, 0x58, 0x23, 0x58, 0x43, 0x15, 0x18, 0x01, 0x23, +0x9b, 0x07, 0xea, 0x1d, 0x05, 0x32, 0x1a, 0x43, 0x12, 0x68, 0x08, 0x35, 0x2b, 0x43, 0x1d, 0x68, 0xff, 0x23, 0x1b, 0x02, 0x2b, 0x40, 0x1b, 0x0a, -0x45, 0x4d, 0x01, 0x2b, 0x24, 0xd1, 0xd0, 0x19, 0xc1, 0x1d, 0x19, 0x31, -0x08, 0x7a, 0x3a, 0x68, 0x80, 0x18, 0x42, 0x4a, 0x09, 0x7b, 0x00, 0xf0, -0xd3, 0xfc, 0x20, 0x78, 0xc0, 0x19, 0x20, 0x30, 0x00, 0x79, 0x39, 0x68, +0x3c, 0x4d, 0x01, 0x2b, 0x24, 0xd1, 0xc8, 0x19, 0xc1, 0x1d, 0x19, 0x31, +0x08, 0x7a, 0x3a, 0x68, 0x80, 0x18, 0x39, 0x4a, 0x09, 0x7b, 0x00, 0xf0, +0xc5, 0xfc, 0x20, 0x78, 0xc0, 0x19, 0x20, 0x30, 0x00, 0x79, 0x39, 0x68, 0x41, 0x18, 0x00, 0x20, 0x82, 0x00, 0x53, 0x19, 0x9b, 0x6e, 0x6e, 0x46, 0xb3, 0x50, 0x01, 0x30, 0x03, 0x28, 0xf7, 0xd3, 0xca, 0x1d, 0x05, 0x32, 0x69, 0x46, 0x00, 0x20, 0x43, 0x00, 0xcd, 0x5a, 0xc0, 0x46, 0xd5, 0x52, -0x01, 0x30, 0x06, 0x28, 0xf8, 0xd3, 0x3e, 0xe0, 0x02, 0x2b, 0x3c, 0xd1, -0x09, 0x0a, 0x3a, 0xd3, 0x00, 0x21, 0x8a, 0x00, 0x53, 0x19, 0x9b, 0x6e, +0x01, 0x30, 0x06, 0x28, 0xf8, 0xd3, 0x2d, 0xe0, 0x02, 0x2b, 0x2b, 0xd1, +0x11, 0x0a, 0x29, 0xd3, 0x00, 0x21, 0x8a, 0x00, 0x53, 0x19, 0x9b, 0x6e, 0x6e, 0x46, 0xb3, 0x50, 0x01, 0x31, 0x03, 0x29, 0xf7, 0xd3, 0x21, 0x78, 0x49, 0x00, 0xc9, 0x19, 0x09, 0x8f, 0x3a, 0x68, 0x8b, 0x18, 0x6a, 0x46, 0x00, 0x21, 0x4d, 0x00, 0x56, 0x5b, 0xc0, 0x46, 0x5e, 0x53, 0x01, 0x31, -0x06, 0x29, 0xf8, 0xd3, 0x22, 0x49, 0x8a, 0x6a, 0x12, 0x18, 0x01, 0x23, -0x9b, 0x07, 0xd5, 0x1d, 0x49, 0x35, 0x2b, 0x43, 0x6e, 0x46, 0x1d, 0x68, -0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x6b, 0x40, 0x1e, 0x4d, -0xee, 0x68, 0x73, 0x40, 0x13, 0x65, 0x89, 0x6a, 0x08, 0x18, 0x01, 0x23, -0x9b, 0x07, 0xc1, 0x1d, 0x4d, 0x31, 0x19, 0x43, 0x09, 0x68, 0x6a, 0x46, -0x08, 0x32, 0x1a, 0x43, 0x12, 0x68, 0x51, 0x40, 0xaa, 0x69, 0x51, 0x40, -0x41, 0x65, 0x20, 0x78, 0x41, 0x1e, 0x21, 0x70, 0x00, 0x28, 0x0d, 0xd0, -0x38, 0x1c, 0xff, 0xf7, 0xef, 0xfe, 0x00, 0x28, 0x0d, 0xd1, 0x09, 0x4a, -0x50, 0x68, 0xc0, 0x68, 0xc0, 0x46, 0x50, 0x60, 0x38, 0x1c, 0x00, 0xf0, -0xa3, 0xfa, 0x02, 0xe0, 0x38, 0x1c, 0x00, 0xf0, 0x72, 0xfa, 0x01, 0xf0, -0xc3, 0xfa, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, -0xec, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0xb8, 0x03, 0x00, 0x80, -0xc8, 0x29, 0x00, 0x80, 0x1c, 0xad, 0x20, 0x40, 0x14, 0x06, 0x00, 0x80, +0x06, 0x29, 0xf8, 0xd3, 0x19, 0x49, 0x8a, 0x6a, 0x13, 0x18, 0x1a, 0x6d, +0x00, 0x9d, 0x55, 0x40, 0x19, 0x4a, 0xd6, 0x68, 0x75, 0x40, 0x1d, 0x65, +0x89, 0x6a, 0x08, 0x18, 0x41, 0x6d, 0x02, 0x9b, 0x59, 0x40, 0x92, 0x69, +0x51, 0x40, 0x41, 0x65, 0x20, 0x78, 0x41, 0x1e, 0x21, 0x70, 0x00, 0x28, +0x0d, 0xd0, 0x38, 0x1c, 0xff, 0xf7, 0xf4, 0xfe, 0x00, 0x28, 0x0d, 0xd1, +0x08, 0x4a, 0x50, 0x68, 0xc0, 0x68, 0xc0, 0x46, 0x50, 0x60, 0x38, 0x1c, +0x00, 0xf0, 0xa4, 0xfa, 0x02, 0xe0, 0x38, 0x1c, 0x00, 0xf0, 0x73, 0xfa, +0x01, 0xf0, 0xde, 0xfa, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x6c, 0x06, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0x38, 0x04, 0x00, 0x80, +0x4c, 0x2a, 0x00, 0x80, 0x1c, 0xad, 0x20, 0x40, 0x94, 0x06, 0x00, 0x80, 0x08, 0x83, 0x20, 0x40, 0xf0, 0xb5, 0x82, 0xb0, 0x69, 0x4b, 0x9f, 0x6a, 0x58, 0x23, 0x5a, 0x43, 0xba, 0x18, 0xc3, 0x1d, 0x49, 0x33, 0x1f, 0x78, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 0x01, 0x34, 0x23, 0x43, 0x1d, 0x68, @@ -625,14 +633,14 @@ 0xff, 0x26, 0x36, 0x02, 0x2e, 0x40, 0x01, 0x23, 0x5b, 0x02, 0x9e, 0x42, 0x74, 0xd1, 0x6b, 0x0c, 0x2b, 0xd3, 0xc3, 0x19, 0x20, 0x33, 0x1b, 0x79, 0xc0, 0x46, 0x4b, 0x81, 0x7b, 0x00, 0x1b, 0x18, 0x1b, 0x8f, 0x4c, 0x89, -0x1b, 0x1b, 0xcb, 0x80, 0x00, 0x24, 0xa6, 0x00, 0x01, 0x96, 0xb3, 0x18, -0xde, 0x1d, 0x09, 0x36, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, -0x01, 0x9e, 0x76, 0x18, 0x73, 0x61, 0x01, 0x34, 0x05, 0x2c, 0xf0, 0xd3, -0x00, 0x24, 0xa6, 0x00, 0x00, 0x96, 0xb3, 0x18, 0xde, 0x1d, 0x1d, 0x36, -0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x00, 0x9e, 0x76, 0x18, -0xb3, 0x62, 0x01, 0x34, 0x05, 0x2c, 0xf0, 0xd3, 0x06, 0xe0, 0x00, 0x23, -0x4b, 0x81, 0xcb, 0x80, 0x40, 0x23, 0x9c, 0x43, 0x0c, 0x60, 0x23, 0x1c, -0x6b, 0x0e, 0x4a, 0xd3, 0xc3, 0x19, 0x20, 0x33, +0x1b, 0x1b, 0xcb, 0x80, 0x00, 0x24, 0xa6, 0x00, +0x01, 0x96, 0xb3, 0x18, 0xde, 0x1d, 0x09, 0x36, 0x01, 0x23, 0x9b, 0x07, +0x33, 0x43, 0x1b, 0x68, 0x01, 0x9e, 0x76, 0x18, 0x73, 0x61, 0x01, 0x34, +0x05, 0x2c, 0xf0, 0xd3, 0x00, 0x24, 0xa6, 0x00, 0x00, 0x96, 0xb3, 0x18, +0xde, 0x1d, 0x1d, 0x36, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, +0x00, 0x9e, 0x76, 0x18, 0xb3, 0x62, 0x01, 0x34, 0x05, 0x2c, 0xf0, 0xd3, +0x06, 0xe0, 0x00, 0x23, 0x4b, 0x81, 0xcb, 0x80, 0x40, 0x23, 0x9c, 0x43, +0x0c, 0x60, 0x23, 0x1c, 0x6b, 0x0e, 0x4a, 0xd3, 0xc3, 0x19, 0x20, 0x33, 0x1b, 0x79, 0x10, 0x33, 0x0b, 0x81, 0x7b, 0x00, 0x1b, 0x18, 0x1b, 0x8f, 0x0f, 0x89, 0xdb, 0x1b, 0x8b, 0x80, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 0x35, 0x34, 0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0xcb, 0x63, 0x01, 0x23, @@ -653,29 +661,29 @@ 0x05, 0x28, 0xf2, 0xd3, 0x00, 0x20, 0x87, 0x00, 0xbb, 0x18, 0xdc, 0x1d, 0x1d, 0x34, 0x01, 0x23, 0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x7f, 0x18, 0xbb, 0x62, 0x01, 0x30, 0x05, 0x28, 0xf2, 0xd3, 0x02, 0xb0, 0xf0, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0xc8, 0x29, 0x00, 0x80, 0x80, 0xb4, 0x1f, 0x1c, +0x08, 0xbc, 0x18, 0x47, 0x4c, 0x2a, 0x00, 0x80, 0x80, 0xb4, 0x1f, 0x1c, 0x3b, 0x0c, 0x18, 0xd2, 0x17, 0x6d, 0x11, 0x4b, 0xc0, 0x46, 0xdf, 0x60, 0x52, 0x6d, 0xc0, 0x46, 0x1a, 0x61, 0xc7, 0x60, 0x1a, 0x69, 0xc0, 0x46, 0x02, 0x61, 0xd8, 0x68, 0xc0, 0x46, 0x08, 0x80, 0xd8, 0x68, 0x00, 0x0c, 0x48, 0x80, 0x18, 0x69, 0xc0, 0x46, 0x88, 0x80, 0x18, 0x69, 0x00, 0x0c, 0xc8, 0x80, 0x80, 0xbc, 0x70, 0x47, 0x4a, 0x88, 0x12, 0x04, 0x0b, 0x88, 0x1a, 0x43, 0xc2, 0x60, 0x8a, 0x88, 0xc9, 0x88, 0x09, 0x04, 0x11, 0x43, -0x01, 0x61, 0xf2, 0xe7, 0xac, 0x06, 0x00, 0x80, 0xf1, 0xb5, 0x88, 0xb0, +0x01, 0x61, 0xf2, 0xe7, 0x2c, 0x07, 0x00, 0x80, 0xf1, 0xb5, 0x88, 0xb0, 0x00, 0x22, 0x08, 0x98, 0x00, 0x6a, 0x08, 0x9b, 0x99, 0x68, 0x49, 0x0a, 0x02, 0xd3, 0x01, 0x27, 0xff, 0x03, 0x00, 0xe0, 0x00, 0x27, 0x03, 0x8b, -0x00, 0x2b, 0x19, 0xd0, 0xa2, 0x49, 0x89, 0x6a, 0x1c, 0x1c, 0x58, 0x23, +0x00, 0x2b, 0x19, 0xd0, 0xa3, 0x49, 0x89, 0x6a, 0x1c, 0x1c, 0x58, 0x23, 0x63, 0x43, 0xc9, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x58, 0x39, 0x19, 0x43, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x02, 0x29, 0x02, 0xd1, 0x08, 0x23, 0x1f, 0x43, 0x07, 0xe0, 0x41, 0x8b, 0x00, 0x29, 0x02, 0xd0, 0x0c, 0x23, 0x1f, 0x43, 0x01, 0xe0, 0x04, 0x23, 0x1f, 0x43, 0x83, 0x8a, 0x00, 0x2b, -0x18, 0xd0, 0x94, 0x49, 0x89, 0x6a, 0x1c, 0x1c, 0x58, 0x23, 0x63, 0x43, -0xc9, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x58, 0x39, 0x19, 0x43, 0x09, 0x68, -0x09, 0x04, 0x09, 0x0c, 0x02, 0x29, 0x01, 0xd1, 0x0f, 0x43, 0x07, 0xe0, -0xc1, 0x8a, 0x00, 0x29, 0x02, 0xd0, 0x03, 0x23, 0x1f, 0x43, 0x01, 0xe0, -0x01, 0x23, 0x1f, 0x43, 0xc1, 0x1d, 0x39, 0x31, 0x07, 0x91, 0x4b, 0x89, -0x0c, 0x89, 0x1c, 0x19, 0x24, 0x04, 0x24, 0x0c, 0x08, 0x9d, 0x2d, 0x68, -0xc0, 0x46, 0x01, 0x95, 0xc9, 0x88, 0x7d, 0x08, 0x1a, 0xd3, 0x1a, 0x1c, -0xc3, 0x1d, 0x19, 0x33, 0x1a, 0x72, 0x07, 0x9a, +0x18, 0xd0, 0x95, 0x49, 0x89, 0x6a, 0x1c, 0x1c, +0x58, 0x23, 0x63, 0x43, 0xc9, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x58, 0x39, +0x19, 0x43, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x02, 0x29, 0x01, 0xd1, +0x0f, 0x43, 0x07, 0xe0, 0xc1, 0x8a, 0x00, 0x29, 0x02, 0xd0, 0x03, 0x23, +0x1f, 0x43, 0x01, 0xe0, 0x01, 0x23, 0x1f, 0x43, 0xc1, 0x1d, 0x39, 0x31, +0x07, 0x91, 0x4b, 0x89, 0x0c, 0x89, 0x1c, 0x19, 0x24, 0x04, 0x24, 0x0c, +0x08, 0x9d, 0x2d, 0x68, 0xc0, 0x46, 0x01, 0x95, 0xc9, 0x88, 0x7d, 0x08, +0x1a, 0xd3, 0x1a, 0x1c, 0xc3, 0x1d, 0x19, 0x33, 0x1a, 0x72, 0x07, 0x9a, 0x92, 0x89, 0xc0, 0x46, 0x1a, 0x73, 0x07, 0x9a, 0x12, 0x89, 0xc0, 0x46, 0x02, 0x86, 0x04, 0x87, 0x82, 0x8a, 0x01, 0x3a, 0x82, 0x83, 0x01, 0x22, 0x19, 0x71, 0x08, 0x9b, 0x1b, 0x68, 0x5b, 0x18, 0x5b, 0x78, 0x9b, 0x00, @@ -684,7 +692,7 @@ 0x07, 0x9b, 0x9b, 0x89, 0xc0, 0x46, 0x2b, 0x73, 0x07, 0x9b, 0x1b, 0x89, 0x2e, 0x1c, 0x55, 0x00, 0x2d, 0x18, 0x05, 0x95, 0x2b, 0x86, 0x00, 0x2a, 0x01, 0xd0, 0xc3, 0x8a, 0x00, 0xe0, 0x83, 0x8a, 0x01, 0x3b, 0x05, 0x9d, -0xc0, 0x46, 0xab, 0x83, 0x31, 0x71, 0x64, 0x4b, 0x9d, 0x6a, 0x05, 0x9b, +0xc0, 0x46, 0xab, 0x83, 0x31, 0x71, 0x65, 0x4b, 0x9d, 0x6a, 0x05, 0x9b, 0x9e, 0x8b, 0x58, 0x23, 0x73, 0x43, 0xeb, 0x18, 0xdd, 0x1d, 0x01, 0x35, 0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, 0x1d, 0x68, 0x2b, 0x0e, 0x5b, 0x06, 0x01, 0xd1, 0x08, 0x31, 0x00, 0xe0, 0x10, 0x31, 0x81, 0x23, 0x5b, 0x02, @@ -692,7 +700,7 @@ 0x24, 0x0c, 0x05, 0x9b, 0xc0, 0x46, 0x1c, 0x87, 0x08, 0x9b, 0x1b, 0x68, 0x1b, 0x19, 0x10, 0x3b, 0x9b, 0x7b, 0x06, 0x9d, 0x40, 0x35, 0x2b, 0x70, 0x2b, 0x78, 0x02, 0x33, 0xe3, 0x1a, 0x1c, 0x04, 0x24, 0x0c, 0x01, 0x32, -0xbb, 0x08, 0x9b, 0x07, 0x6b, 0xd0, 0x83, 0x18, 0x20, 0x33, 0x04, 0x93, +0xbb, 0x08, 0x9b, 0x07, 0x6d, 0xd0, 0x83, 0x18, 0x20, 0x33, 0x04, 0x93, 0x19, 0x72, 0x01, 0x9b, 0x5d, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, 0x1b, 0x68, 0x1b, 0x07, 0x1b, 0x0f, 0x9b, 0x00, 0x04, 0x9e, 0xc0, 0x46, 0x33, 0x73, 0x00, 0x95, 0x2b, 0x78, 0x1b, 0x07, 0x1b, 0x0f, 0x9b, 0x00, @@ -701,102 +709,103 @@ 0x2b, 0x43, 0x55, 0x00, 0x2d, 0x18, 0x2b, 0x86, 0x04, 0x9b, 0xc0, 0x46, 0x59, 0x72, 0x04, 0x9b, 0x1b, 0x7b, 0x2e, 0x1c, 0x04, 0x9d, 0xc0, 0x46, 0x6b, 0x73, 0x33, 0x8e, 0xc0, 0x46, 0x73, 0x86, 0x00, 0x9d, 0x2b, 0x78, -0x1b, 0x07, 0x1b, 0x0f, 0x9b, 0x00, 0x59, 0x18, 0x04, 0x25, 0x3d, 0x40, -0x0e, 0xd0, 0x34, 0x87, 0x03, 0x8b, 0x01, 0x3b, 0xb3, 0x83, 0x13, 0x1c, -0x1b, 0x18, 0x20, 0x33, 0x19, 0x71, 0x01, 0x9b, 0x5b, 0x18, 0x5b, 0x78, -0x9b, 0x00, 0x59, 0x18, 0x08, 0x31, 0x01, 0x32, 0x3b, 0x09, 0x37, 0xd3, -0x00, 0x2d, 0x01, 0xd0, 0x43, 0x8b, 0x00, 0xe0, 0x03, 0x8b, 0x55, 0x00, -0x2d, 0x18, 0x01, 0x3b, 0xab, 0x83, 0x83, 0x18, 0x03, 0x93, 0x20, 0x33, -0x19, 0x71, 0x20, 0x4b, 0x9d, 0x6a, 0x53, 0x00, 0x1b, 0x18, 0x02, 0x93, -0x9e, 0x8b, 0x58, 0x23, 0x73, 0x43, 0xeb, 0x18, 0xdd, 0x1d, 0x01, 0x35, -0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, 0x1d, 0x68, 0x2b, 0x0e, 0x5b, 0x06, -0x02, 0xd1, 0x08, 0x31, 0x01, 0xe0, 0x15, 0xe0, 0x10, 0x31, 0x81, 0x23, -0x5b, 0x02, 0x1d, 0x40, 0x9d, 0x42, 0x03, 0xd1, 0xe3, 0x1f, 0x05, 0x3b, -0x1c, 0x04, 0x24, 0x0c, 0x02, 0x9b, 0xc0, 0x46, 0x1c, 0x87, 0x08, 0x9b, -0x1b, 0x68, 0x1b, 0x19, 0x10, 0x3b, 0x9b, 0x7b, 0x03, 0x9c, 0x40, 0x34, -0x23, 0x70, 0x01, 0x32, 0x07, 0x9b, 0xc0, 0x46, 0xd9, 0x80, 0x51, 0x1e, -0xc3, 0x1d, 0x49, 0x33, 0x19, 0x70, 0x07, 0x61, 0x04, 0x2a, 0x06, 0xd2, -0x06, 0x49, 0x53, 0x00, 0x1b, 0x18, 0x99, 0x83, 0x01, 0x32, 0x04, 0x2a, -0xf9, 0xd3, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, -0xc8, 0x29, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, -0x70, 0x47, 0x80, 0xb5, 0x8c, 0xb0, 0x07, 0x1c, 0x12, 0x48, 0x01, 0x68, -0x01, 0x31, 0x01, 0x60, 0x38, 0x68, 0xc0, 0x46, 0x00, 0x90, 0x78, 0x68, -0xc0, 0x46, 0x01, 0x90, 0xb8, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x0d, 0x48, -0x41, 0x68, 0xc9, 0x68, 0xc0, 0x46, 0x41, 0x60, 0x38, 0x1c, 0x00, 0xf0, -0x4f, 0xf8, 0xb8, 0x68, 0x40, 0x09, 0x06, 0xd3, 0x10, 0x23, 0x02, 0x98, -0x18, 0x43, 0x02, 0x90, 0x68, 0x46, 0x02, 0xf0, 0xcd, 0xff, 0x68, 0x46, -0x02, 0xf0, 0x82, 0xfe, 0x0c, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x78, 0x2a, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, 0x00, 0xb5, 0x8c, 0xb0, -0x01, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x68, 0x05, 0x4b, 0x19, 0x43, -0x01, 0x91, 0x00, 0xf0, 0x2f, 0xf8, 0x68, 0x46, 0x02, 0xf0, 0x6c, 0xfe, -0x0c, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, -0x02, 0x6a, 0x03, 0x68, 0xc0, 0x46, 0x13, 0x60, 0x40, 0x68, 0xc0, 0x46, -0x50, 0x60, 0x40, 0x32, 0x48, 0x68, 0xc0, 0x46, 0x90, 0x80, 0xc8, 0x68, -0xc0, 0x46, 0xd0, 0x80, 0x48, 0x69, 0xc0, 0x46, 0x10, 0x81, 0x88, 0x68, -0xc0, 0x46, 0x50, 0x81, 0x08, 0x7e, 0xc0, 0x46, 0x90, 0x73, 0x08, 0x69, -0xc0, 0x46, 0x90, 0x81, 0x70, 0x47, 0x04, 0x49, 0x08, 0x68, 0x00, 0x28, -0x00, 0xd1, 0x70, 0x47, 0xc2, 0x68, 0xc0, 0x46, 0x0a, 0x60, 0xfa, 0xe7, -0xec, 0x05, 0x00, 0x80, 0x02, 0x49, 0x0a, 0x68, 0xc0, 0x46, 0xc2, 0x60, -0x08, 0x60, 0x70, 0x47, 0xec, 0x05, 0x00, 0x80, 0xb0, 0xb4, 0x00, 0x22, -0x12, 0x4f, 0x3b, 0x7f, 0x01, 0x33, 0x3b, 0x77, 0x03, 0x23, 0xfc, 0x1d, -0x19, 0x34, 0x38, 0x62, 0x79, 0x62, 0x23, 0x72, 0x0e, 0x4c, 0x25, 0x68, -0x6b, 0x0c, 0x05, 0xd2, 0x23, 0x68, 0x1b, 0x0c, 0x10, 0xd1, 0x24, 0x68, -0xa3, 0x0a, 0x0d, 0xd3, 0x01, 0x23, 0x0a, 0x4f, 0xc0, 0x46, 0xfb, 0x62, -0x09, 0x4f, 0x0a, 0x4b, 0xc0, 0x46, 0xdf, 0x60, 0x99, 0x60, 0x58, 0x60, -0x10, 0x1c, 0x18, 0x60, 0x01, 0x32, 0xfb, 0xe7, 0x10, 0x1c, 0x38, 0x64, -0x01, 0x32, 0xfb, 0xe7, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, -0xc0, 0x00, 0x18, 0x00, 0x02, 0x81, 0x00, 0x00, 0x40, 0x01, 0x18, 0x00, -0xf0, 0xb5, 0x47, 0x4f, 0x38, 0x68, 0x47, 0x4e, 0x47, 0x4d, 0x07, 0x23, -0x5b, 0x02, 0xec, 0x18, 0x00, 0x28, 0x1d, 0xd1, 0xe0, 0x6a, 0x01, 0x30, -0xe0, 0x62, 0x44, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x43, 0x48, 0x41, 0x69, -0x00, 0x29, 0x13, 0xd0, 0xc1, 0x1d, 0x69, 0x31, 0x09, 0x7b, 0x00, 0x29, -0x0e, 0xd0, 0x01, 0x23, 0x9b, 0x07, 0x01, 0x6d, 0x19, 0x43, 0x09, 0x68, -0xc0, 0x46, 0x81, 0x61, 0xc2, 0x69, 0x91, 0x42, 0x04, 0xd0, 0xf1, 0x6c, -0x01, 0x31, 0xf1, 0x64, 0x01, 0xf0, 0x3a, 0xfe, 0x38, 0x68, 0x01, 0x28, -0x17, 0xd1, 0x37, 0x48, 0x41, 0x69, 0x00, 0x29, 0x13, 0xd0, 0xc1, 0x1d, -0x69, 0x31, 0x09, 0x7b, 0x00, 0x29, 0x0e, 0xd0, 0x01, 0x23, 0x9b, 0x07, -0x01, 0x6d, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x81, 0x61, 0xc2, 0x69, -0x91, 0x42, 0x04, 0xd0, 0xf1, 0x6c, 0x01, 0x31, 0xf1, 0x64, 0x01, 0xf0, -0x1f, 0xfe, 0x38, 0x68, 0x02, 0x28, 0x2f, 0xd1, 0xbb, 0x23, 0x1b, 0x01, -0xee, 0x18, 0x70, 0x7a, 0x00, 0x28, 0x03, 0xd0, 0x00, 0x20, 0x70, 0x72, -0x00, 0xf0, 0x30, 0xfd, 0x30, 0x7a, 0x00, 0x28, 0x02, 0xd0, 0x78, 0x68, -0x02, 0xf0, 0x96, 0xff, 0x1b, 0x23, 0xdb, 0x01, 0xe8, 0x18, 0x40, 0x8b, -0x04, 0x26, 0x06, 0x40, 0xa0, 0x6a, 0xb0, 0x42, -0x14, 0xd0, 0xf8, 0x68, 0x01, 0x30, 0xf8, 0x60, 0x19, 0x28, 0x11, 0xd3, -0x1b, 0x48, 0x01, 0x7b, 0x00, 0x29, 0x0d, 0xd1, 0xff, 0x30, 0x41, 0x30, -0x40, 0x78, 0x00, 0x28, 0x08, 0xd1, 0xb8, 0x68, 0x02, 0xf0, 0x7c, 0xff, -0x00, 0x20, 0xf8, 0x60, 0xa6, 0x62, 0x01, 0xe0, 0x00, 0x20, 0xf8, 0x60, -0x38, 0x68, 0x03, 0x28, 0x0b, 0xd1, 0xec, 0x1d, 0x79, 0x34, 0xa0, 0x6b, -0x80, 0x08, 0x02, 0xd3, 0x02, 0x20, 0x02, 0xf0, 0xef, 0xfb, 0x02, 0x23, -0xa0, 0x6b, 0x98, 0x43, 0xa0, 0x63, 0x38, 0x68, 0x01, 0x30, 0x38, 0x60, -0x03, 0x28, 0x01, 0xd9, 0x00, 0x20, 0x38, 0x60, 0xf0, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0xbc, 0x03, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, -0xe8, 0x0d, 0x00, 0x80, 0x40, 0x01, 0x18, 0x00, 0xd0, 0x2c, 0x00, 0x80, -0x50, 0x2c, 0x00, 0x80, 0xa8, 0x04, 0x00, 0x80, 0x90, 0xb4, 0x1c, 0x48, -0x02, 0x8a, 0x1c, 0x49, 0x0f, 0x8a, 0x01, 0x23, 0xba, 0x42, 0x03, 0xd1, -0xc2, 0x89, 0x4f, 0x8a, 0xba, 0x42, 0x10, 0xd0, 0x02, 0x7b, 0x00, 0x2a, -0x0d, 0xd0, 0x42, 0x7b, 0x00, 0x2a, 0x0a, 0xd0, 0xc7, 0x8a, 0x8a, 0x8a, -0x97, 0x42, 0x04, 0xdc, 0x13, 0x4a, 0xc0, 0x46, 0x53, 0x60, 0x8b, 0x82, -0x01, 0xe0, 0x01, 0x32, 0x8a, 0x82, 0x42, 0x8b, 0x57, 0x1c, 0x47, 0x83, -0x07, 0x8b, 0xba, 0x42, 0x0e, 0xdb, 0x07, 0x8a, 0x84, 0x8a, 0x00, 0x22, -0xa7, 0x42, 0x05, 0xda, 0xc7, 0x89, 0x44, 0x8a, 0xa7, 0x42, 0x01, 0xda, -0x42, 0x73, 0x00, 0xe0, 0x43, 0x73, 0xc2, 0x81, 0x02, 0x82, 0x42, 0x83, -0xc2, 0x89, 0xc0, 0x46, 0x4a, 0x82, 0x00, 0x8a, 0xc0, 0x46, 0x08, 0x82, -0x90, 0xbc, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, 0xbc, 0x03, 0x00, 0x80, -0x40, 0x01, 0x18, 0x00, 0xf7, 0xb5, 0x91, 0xb0, 0x6b, 0x46, 0x84, 0x1e, -0x12, 0x99, 0x14, 0x29, 0x1a, 0xd9, 0x00, 0x20, 0x81, 0x00, 0x67, 0x58, -0xc0, 0x46, 0x57, 0x50, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x10, 0x28, -0xf6, 0xd3, 0x00, 0x21, 0x05, 0x20, 0x87, 0x00, 0xd6, 0x59, 0x4f, 0x1c, -0x3d, 0x06, 0x2d, 0x0e, 0x0f, 0x1c, 0xbf, 0x00, 0xde, 0x51, 0x29, 0x1c, -0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x10, 0x28, 0xf1, 0xd3, 0x09, 0xe0, -0x00, 0x20, 0x81, 0x00, 0x63, 0x58, 0xc0, 0x46, 0x53, 0x50, 0x01, 0x30, -0x00, 0x06, 0x00, 0x0e, 0x06, 0x28, 0xf6, 0xd3, 0x00, 0x20, 0xe0, 0x70, -0x20, 0x72, 0x60, 0x72, 0xa0, 0x72, 0x20, 0x73, 0x60, 0x73, 0x12, 0x99, -0x14, 0x29, 0x37, 0xd9, 0x69, 0x46, 0x8e, 0x1c, 0x91, 0x78, 0x09, 0x07, -0x09, 0x0f, 0x89, 0x00, 0x14, 0x39, 0x0d, 0x06, 0x2d, 0x16, 0x00, 0x27, -0x00, 0x2d, 0x1b, 0xdd, 0xf0, 0x19, 0x10, 0xa9, 0x00, 0xf0, 0x3d, 0xf8, -0x00, 0x28, 0x0e, 0xd0, 0x00, 0x20, 0x10, 0xa9, 0x09, 0x78, 0x00, 0x29, -0x09, 0xdd, 0x00, 0x22, 0x39, 0x18, 0x72, 0x54, 0x01, 0x30, 0x00, 0x06, +0x1b, 0x07, 0x1b, 0x0f, 0x9b, 0x00, 0x1b, 0x04, 0x1b, 0x0c, 0x59, 0x18, +0x04, 0x25, 0x3d, 0x40, 0x0e, 0xd0, 0x34, 0x87, 0x03, 0x8b, 0x01, 0x3b, +0xb3, 0x83, 0x13, 0x1c, 0x1b, 0x18, 0x20, 0x33, 0x19, 0x71, 0x01, 0x9b, +0x5b, 0x18, 0x5b, 0x78, 0x9b, 0x00, 0x59, 0x18, 0x08, 0x31, 0x01, 0x32, +0x3b, 0x09, 0x37, 0xd3, 0x00, 0x2d, 0x01, 0xd0, 0x43, 0x8b, 0x00, 0xe0, +0x03, 0x8b, 0x55, 0x00, 0x2d, 0x18, 0x01, 0x3b, 0xab, 0x83, 0x83, 0x18, +0x03, 0x93, 0x20, 0x33, 0x19, 0x71, 0x20, 0x4b, 0x9d, 0x6a, 0x53, 0x00, +0x1b, 0x18, 0x02, 0x93, 0x9e, 0x8b, 0x58, 0x23, 0x73, 0x43, 0xeb, 0x18, +0xdd, 0x1d, 0x01, 0x35, 0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, 0x1d, 0x68, +0x2b, 0x0e, 0x5b, 0x06, 0x02, 0xd1, 0x08, 0x31, 0x01, 0xe0, 0x15, 0xe0, +0x10, 0x31, 0x81, 0x23, 0x5b, 0x02, 0x1d, 0x40, +0x9d, 0x42, 0x03, 0xd1, 0xe3, 0x1f, 0x05, 0x3b, 0x1c, 0x04, 0x24, 0x0c, +0x02, 0x9b, 0xc0, 0x46, 0x1c, 0x87, 0x08, 0x9b, 0x1b, 0x68, 0x1b, 0x19, +0x10, 0x3b, 0x9b, 0x7b, 0x03, 0x9c, 0x40, 0x34, 0x23, 0x70, 0x01, 0x32, +0x07, 0x9b, 0xc0, 0x46, 0xd9, 0x80, 0x51, 0x1e, 0xc3, 0x1d, 0x49, 0x33, +0x19, 0x70, 0x07, 0x61, 0x04, 0x2a, 0x06, 0xd2, 0x06, 0x49, 0x53, 0x00, +0x1b, 0x18, 0x99, 0x83, 0x01, 0x32, 0x04, 0x2a, 0xf9, 0xd3, 0x09, 0xb0, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x4c, 0x2a, 0x00, 0x80, +0xff, 0xff, 0x00, 0x00, 0x70, 0x47, 0x80, 0xb5, 0x8c, 0xb0, 0x07, 0x1c, +0x12, 0x48, 0x01, 0x68, 0x01, 0x31, 0x01, 0x60, 0x38, 0x68, 0xc0, 0x46, +0x00, 0x90, 0x78, 0x68, 0xc0, 0x46, 0x01, 0x90, 0xb8, 0x68, 0xc0, 0x46, +0x02, 0x90, 0x0d, 0x48, 0x41, 0x68, 0xc9, 0x68, 0xc0, 0x46, 0x41, 0x60, +0x38, 0x1c, 0x00, 0xf0, 0x4f, 0xf8, 0xb8, 0x68, 0x40, 0x09, 0x06, 0xd3, +0x10, 0x23, 0x02, 0x98, 0x18, 0x43, 0x02, 0x90, 0x68, 0x46, 0x02, 0xf0, +0xe1, 0xff, 0x68, 0x46, 0x02, 0xf0, 0x9a, 0xfe, 0x0c, 0xb0, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x0c, 0x2b, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80, +0x00, 0xb5, 0x8c, 0xb0, 0x01, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x68, +0x05, 0x4b, 0x19, 0x43, 0x01, 0x91, 0x00, 0xf0, 0x2f, 0xf8, 0x68, 0x46, +0x02, 0xf0, 0x84, 0xfe, 0x0c, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x00, 0x00, 0x00, 0xa0, 0x02, 0x6a, 0x03, 0x68, 0xc0, 0x46, 0x13, 0x60, +0x40, 0x68, 0xc0, 0x46, 0x50, 0x60, 0x40, 0x32, 0x48, 0x68, 0xc0, 0x46, +0x90, 0x80, 0xc8, 0x68, 0xc0, 0x46, 0xd0, 0x80, 0x48, 0x69, 0xc0, 0x46, +0x10, 0x81, 0x88, 0x68, 0xc0, 0x46, 0x50, 0x81, 0x08, 0x7e, 0xc0, 0x46, +0x90, 0x73, 0x08, 0x69, 0xc0, 0x46, 0x90, 0x81, 0x70, 0x47, 0x04, 0x49, +0x08, 0x68, 0x00, 0x28, 0x00, 0xd1, 0x70, 0x47, 0xc2, 0x68, 0xc0, 0x46, +0x0a, 0x60, 0xfa, 0xe7, 0x6c, 0x06, 0x00, 0x80, 0x02, 0x49, 0x0a, 0x68, +0xc0, 0x46, 0xc2, 0x60, 0x08, 0x60, 0x70, 0x47, 0x6c, 0x06, 0x00, 0x80, +0xb0, 0xb4, 0x00, 0x22, 0x12, 0x4f, 0x7c, 0x7f, 0x01, 0x34, 0x7c, 0x77, +0x03, 0x23, 0xfc, 0x1d, 0x19, 0x34, 0x38, 0x62, 0x79, 0x62, 0x23, 0x72, +0x0e, 0x4c, 0x25, 0x68, 0x6b, 0x0c, 0x05, 0xd2, 0x23, 0x68, 0x1b, 0x0c, +0x10, 0xd1, 0x24, 0x68, 0xa3, 0x0a, 0x0d, 0xd3, 0x01, 0x23, 0x0a, 0x4f, +0xc0, 0x46, 0xfb, 0x62, 0x09, 0x4f, 0x0a, 0x4b, 0xc0, 0x46, 0xdf, 0x60, +0x99, 0x60, 0x58, 0x60, 0x10, 0x1c, 0x18, 0x60, 0x01, 0x32, 0xfb, 0xe7, +0x10, 0x1c, 0x38, 0x64, 0x01, 0x32, 0xfb, 0xe7, 0x00, 0x00, 0x00, 0x80, +0x00, 0x00, 0x10, 0x40, 0xc0, 0x00, 0x18, 0x00, 0x02, 0x81, 0x00, 0x00, +0x40, 0x01, 0x18, 0x00, 0xf0, 0xb5, 0x47, 0x4f, 0x38, 0x68, 0x47, 0x4e, +0x47, 0x4d, 0x07, 0x23, 0x5b, 0x02, 0xec, 0x18, 0x00, 0x28, 0x1d, 0xd1, +0x20, 0x6b, 0x01, 0x30, 0x20, 0x63, 0x44, 0x49, 0xc0, 0x46, 0x08, 0x60, +0x43, 0x48, 0x41, 0x69, 0x00, 0x29, 0x13, 0xd0, 0xc1, 0x1d, 0x69, 0x31, +0x09, 0x7b, 0x00, 0x29, 0x0e, 0xd0, 0x01, 0x23, 0x9b, 0x07, 0x01, 0x6d, +0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x81, 0x61, 0xc2, 0x69, 0x91, 0x42, +0x04, 0xd0, 0xf1, 0x6c, 0x01, 0x31, 0xf1, 0x64, 0x01, 0xf0, 0x50, 0xfe, +0x38, 0x68, 0x01, 0x28, 0x17, 0xd1, 0x37, 0x48, 0x41, 0x69, 0x00, 0x29, +0x13, 0xd0, 0xc1, 0x1d, 0x69, 0x31, 0x09, 0x7b, +0x00, 0x29, 0x0e, 0xd0, 0x01, 0x23, 0x9b, 0x07, 0x01, 0x6d, 0x19, 0x43, +0x09, 0x68, 0xc0, 0x46, 0x81, 0x61, 0xc2, 0x69, 0x91, 0x42, 0x04, 0xd0, +0xf1, 0x6c, 0x01, 0x31, 0xf1, 0x64, 0x01, 0xf0, 0x35, 0xfe, 0x38, 0x68, +0x02, 0x28, 0x2f, 0xd1, 0xbb, 0x23, 0x1b, 0x01, 0xee, 0x18, 0x70, 0x7b, +0x00, 0x28, 0x03, 0xd0, 0x00, 0x20, 0x70, 0x73, 0x00, 0xf0, 0x4a, 0xfd, +0x30, 0x7b, 0x00, 0x28, 0x02, 0xd0, 0x78, 0x68, 0x02, 0xf0, 0xaa, 0xff, +0x1b, 0x23, 0xdb, 0x01, 0xe8, 0x18, 0xc0, 0x8b, 0x04, 0x26, 0x06, 0x40, +0xe0, 0x6a, 0xb0, 0x42, 0x14, 0xd0, 0xf8, 0x68, 0x01, 0x30, 0xf8, 0x60, +0x19, 0x28, 0x11, 0xd3, 0x1b, 0x48, 0x01, 0x7b, 0x00, 0x29, 0x0d, 0xd1, +0xff, 0x30, 0x41, 0x30, 0x40, 0x78, 0x00, 0x28, 0x08, 0xd1, 0xb8, 0x68, +0x02, 0xf0, 0x90, 0xff, 0x00, 0x20, 0xf8, 0x60, 0xe6, 0x62, 0x01, 0xe0, +0x00, 0x20, 0xf8, 0x60, 0x38, 0x68, 0x03, 0x28, 0x0b, 0xd1, 0xec, 0x1d, +0x79, 0x34, 0xe0, 0x6b, 0x80, 0x08, 0x02, 0xd3, 0x02, 0x20, 0x02, 0xf0, +0x07, 0xfc, 0x02, 0x23, 0xe0, 0x6b, 0x98, 0x43, 0xe0, 0x63, 0x38, 0x68, +0x01, 0x30, 0x38, 0x60, 0x03, 0x28, 0x01, 0xd9, 0x00, 0x20, 0x38, 0x60, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x3c, 0x04, 0x00, 0x80, +0xa0, 0x82, 0x20, 0x40, 0x68, 0x0e, 0x00, 0x80, 0x40, 0x01, 0x18, 0x00, +0x64, 0x2d, 0x00, 0x80, 0xe4, 0x2c, 0x00, 0x80, 0x28, 0x05, 0x00, 0x80, +0xb0, 0xb4, 0x1d, 0x48, 0x84, 0x8a, 0x1d, 0x4a, 0x13, 0x8a, 0xc1, 0x1d, +0x09, 0x31, 0x01, 0x27, 0x9c, 0x42, 0x03, 0xd1, 0x43, 0x8a, 0x54, 0x8a, +0xa3, 0x42, 0x10, 0xd0, 0x0b, 0x78, 0x00, 0x2b, 0x0d, 0xd0, 0x4b, 0x78, +0x00, 0x2b, 0x0a, 0xd0, 0x44, 0x8b, 0x93, 0x8a, 0x9c, 0x42, 0x04, 0xdc, +0x13, 0x4b, 0xc0, 0x46, 0x5f, 0x60, 0x97, 0x82, 0x01, 0xe0, 0x01, 0x33, +0x93, 0x82, 0xc3, 0x8b, 0x5c, 0x1c, 0xc4, 0x83, 0x84, 0x8b, 0xa3, 0x42, +0x0e, 0xdb, 0x84, 0x8a, 0x05, 0x8b, 0x00, 0x23, 0xac, 0x42, 0x05, 0xda, +0x44, 0x8a, 0xc5, 0x8a, 0xac, 0x42, 0x01, 0xda, 0x4b, 0x70, 0x00, 0xe0, +0x4f, 0x70, 0x43, 0x82, 0x83, 0x82, 0xc3, 0x83, 0x41, 0x8a, 0xc0, 0x46, +0x51, 0x82, 0x80, 0x8a, 0xc0, 0x46, 0x10, 0x82, 0xb0, 0xbc, 0x70, 0x47, +0xe8, 0x0e, 0x00, 0x80, 0x3c, 0x04, 0x00, 0x80, 0x40, 0x01, 0x18, 0x00, +0xf7, 0xb5, 0x91, 0xb0, 0x6b, 0x46, 0x84, 0x1e, 0x12, 0x99, 0x14, 0x29, +0x1a, 0xd9, 0x00, 0x20, 0x81, 0x00, 0x67, 0x58, 0xc0, 0x46, 0x57, 0x50, +0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x10, 0x28, 0xf6, 0xd3, 0x00, 0x21, +0x05, 0x20, 0x87, 0x00, 0xd6, 0x59, 0x4f, 0x1c, 0x3d, 0x06, 0x2d, 0x0e, +0x0f, 0x1c, 0xbf, 0x00, 0xde, 0x51, 0x29, 0x1c, 0x01, 0x30, 0x00, 0x06, +0x00, 0x0e, 0x10, 0x28, 0xf1, 0xd3, 0x09, 0xe0, 0x00, 0x20, 0x81, 0x00, +0x63, 0x58, 0xc0, 0x46, 0x53, 0x50, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, +0x06, 0x28, 0xf6, 0xd3, 0x00, 0x20, 0xe0, 0x70, 0x20, 0x72, 0x60, 0x72, +0xa0, 0x72, 0x20, 0x73, 0x60, 0x73, 0x12, 0x99, 0x14, 0x29, 0x37, 0xd9, +0x69, 0x46, 0x8e, 0x1c, 0x91, 0x78, 0x09, 0x07, 0x09, 0x0f, 0x89, 0x00, +0x14, 0x39, 0x0d, 0x06, 0x2d, 0x16, 0x00, 0x27, 0x00, 0x2d, 0x1b, 0xdd, +0xf0, 0x19, 0x10, 0xa9, 0x00, 0xf0, 0x3d, 0xf8, 0x00, 0x28, 0x0e, 0xd0, +0x00, 0x20, 0x10, 0xa9, 0x09, 0x78, 0x00, 0x29, 0x09, 0xdd, 0x00, 0x22, +0x39, 0x18, 0x72, 0x54, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x10, 0xa9, 0x09, 0x78, 0x88, 0x42, 0xf6, 0xdb, 0x10, 0xa8, 0x00, 0x78, 0x38, 0x18, 0x07, 0x06, 0x3f, 0x0e, 0xaf, 0x42, 0xe3, 0xdb, 0x68, 0x46, 0xe2, 0x1d, 0x0d, 0x32, 0x00, 0x21, 0xab, 0x08, 0x5f, 0x1c, @@ -804,257 +813,261 @@ 0x09, 0x06, 0x09, 0x0e, 0x8f, 0x42, 0xf6, 0xd8, 0x14, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb4, 0x87, 0x1e, 0x00, 0x20, 0x89, 0x08, 0x4b, 0x1c, 0x08, 0xd0, 0x81, 0x00, 0x54, 0x58, 0xc0, 0x46, 0x7c, 0x50, -0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x83, 0x42, -0xf6, 0xd8, 0x90, 0xbc, 0x70, 0x47, 0x80, 0xb4, 0x02, 0x78, 0xd2, 0x06, -0xd2, 0x0e, 0x00, 0x23, 0x01, 0x27, 0x01, 0x2a, 0x01, 0xdc, 0x0f, 0x70, -0x11, 0xe0, 0x40, 0x78, 0xc0, 0x46, 0x08, 0x70, 0x14, 0x2a, 0x04, 0xd1, -0x08, 0x48, 0x01, 0x7a, 0x01, 0x31, 0x01, 0x72, 0x07, 0xe0, 0x02, 0x2a, -0x05, 0xd0, 0x05, 0x2a, 0x03, 0xd0, 0x06, 0x2a, 0x01, 0xd0, 0x15, 0x2a, -0x02, 0xd1, 0x18, 0x1c, 0x80, 0xbc, 0x70, 0x47, 0x38, 0x1c, 0xfb, 0xe7, -0xe0, 0x82, 0x20, 0x40, 0x00, 0xb5, 0x0f, 0x48, 0x01, 0x23, 0x1b, 0x06, -0x41, 0x69, 0x99, 0x43, 0x1a, 0x09, 0x41, 0x61, 0xd1, 0x60, 0x00, 0x21, -0xa1, 0x22, 0x52, 0x03, 0x91, 0x61, 0x19, 0x1c, 0x09, 0x4a, 0xc0, 0x46, -0x11, 0x60, 0x1b, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x40, 0x69, 0x00, 0x28, -0x03, 0xd0, 0x02, 0xf0, 0x4f, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x04, 0x48, -0x41, 0x88, 0x01, 0x31, 0x41, 0x80, 0xf8, 0xe7, 0xe8, 0x0d, 0x00, 0x80, -0x00, 0x00, 0x00, 0xb0, 0xe0, 0x82, 0x20, 0x40, 0x70, 0x47, 0x00, 0x00, -0xf0, 0xb5, 0x85, 0xb0, 0x94, 0x49, 0xc8, 0x68, 0xcf, 0x1d, 0x79, 0x37, -0x01, 0x28, 0x0b, 0xd1, 0xb8, 0x88, 0x00, 0x28, 0x08, 0xd1, 0xc3, 0x1e, -0xca, 0x6f, 0x1a, 0x40, 0xca, 0x67, 0x8f, 0x48, 0xc0, 0x46, 0x02, 0x60, -0x14, 0x20, 0xb8, 0x80, 0x8d, 0x4c, 0x62, 0x6a, 0x8d, 0x48, 0xc3, 0x6b, -0x9a, 0x18, 0xc2, 0x63, 0xa0, 0x6a, 0x19, 0x23, 0xdb, 0x01, 0xcc, 0x18, -0x60, 0x62, 0xe2, 0x69, 0x12, 0x03, 0x12, 0x0b, 0x82, 0x42, 0x05, 0xd1, -0x01, 0x20, 0x40, 0x04, 0x86, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xef, 0xe0, -0x3b, 0x8a, 0x58, 0x1c, 0x38, 0x82, 0xbd, 0x8a, 0x01, 0x20, 0x00, 0x22, -0xab, 0x42, 0x02, 0xdb, 0x78, 0x73, 0x3a, 0x82, 0x7a, 0x83, 0x33, 0x23, -0x9b, 0x01, 0xcb, 0x18, 0x04, 0x93, 0x1b, 0x69, 0x0f, 0x2b, 0x73, 0xd2, -0x00, 0x22, 0x2f, 0x23, 0x9b, 0x01, 0xcf, 0x18, 0xfa, 0x60, 0xe1, 0x69, -0x8a, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x4b, 0x68, 0x1e, 0x0c, 0x36, 0x04, -0x76, 0x4d, 0x05, 0xd1, 0x3b, 0x2a, 0x03, 0xd3, 0x01, 0x23, 0xdb, 0x02, -0x9a, 0x42, 0x01, 0xd9, 0xa8, 0x72, 0xc7, 0xe0, 0x01, 0x23, 0x9b, 0x07, -0x08, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x03, 0x91, 0x03, 0xa9, -0x09, 0x88, 0x01, 0x31, 0x09, 0x04, 0x09, 0x0c, 0xf9, 0x81, 0x49, 0x09, -0x05, 0x31, 0x09, 0x06, 0x09, 0x0e, 0x6a, 0x4a, 0xc0, 0x46, 0x02, 0x92, -0x06, 0x1c, 0x69, 0x48, 0x43, 0x6a, 0xc0, 0x46, 0x01, 0x93, 0x83, 0x6a, -0xc0, 0x46, 0x00, 0x93, 0xc2, 0x1d, 0x11, 0x32, 0x80, 0x69, 0x00, 0x03, -0x00, 0x0b, 0x92, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x1a, 0x43, 0x12, 0x68, -0x90, 0x42, 0x01, 0xd1, 0x30, 0x1c, 0x0d, 0xe0, 0x90, 0x42, 0x05, 0xd9, -0x00, 0x9b, 0x18, 0x1a, 0x01, 0x9b, 0xd2, 0x1a, 0x82, 0x18, 0x00, 0xe0, -0x12, 0x1a, 0x01, 0x20, 0x09, 0x01, 0x91, 0x42, 0x00, 0xd3, 0x00, 0x20, -0x01, 0x28, 0x62, 0xd1, 0xe0, 0x68, 0x00, 0x28, 0x60, 0xd0, 0x04, 0x99, -0x08, 0x69, 0x01, 0x30, 0x08, 0x61, 0x02, 0x20, 0xe1, 0x69, 0xc0, 0x46, -0x08, 0x60, 0x00, 0xf0, 0x8f, 0xfc, 0x38, 0x63, 0x4e, 0x49, 0xc0, 0x46, -0x79, 0x60, 0xe1, 0x69, 0x62, 0x6b, 0x8a, 0x18, 0x23, 0x6b, 0x9a, 0x42, -0x00, 0xd9, 0xe1, 0x6a, 0xc0, 0x46, 0x79, 0x62, 0x79, 0x6a, 0x0c, 0x31, -0xb9, 0x62, 0x00, 0x21, 0xb9, 0x61, 0x03, 0xa9, 0x49, 0x88, 0xc9, 0x09, -0x03, 0xd3, 0x00, 0xe0, 0x78, 0xe0, 0x31, 0x1c, -0x00, 0xe0, 0x00, 0x21, 0x39, 0x60, 0x39, 0x68, 0xc0, 0x46, 0x01, 0x60, -0xf8, 0x89, 0x41, 0x4e, 0x60, 0x28, 0x04, 0xdc, 0x30, 0x83, 0xf8, 0x89, -0xc0, 0x46, 0x70, 0x83, 0x08, 0xe0, 0x60, 0x20, 0x30, 0x83, 0xf9, 0x89, -0xb8, 0x6a, 0x42, 0x18, 0x23, 0x6b, 0x9a, 0x42, 0x03, 0xd8, 0x71, 0x83, -0x00, 0x21, 0xf9, 0x62, 0x05, 0xe0, 0xe1, 0x6a, 0xc0, 0x46, 0xf9, 0x62, -0x21, 0x6b, 0x08, 0x1a, 0x70, 0x83, 0x38, 0x6b, 0x41, 0x68, 0xc0, 0x46, -0x79, 0x60, 0x81, 0x68, 0xc0, 0x46, 0xb9, 0x60, 0x01, 0x69, 0xc0, 0x46, -0x39, 0x61, 0x40, 0x69, 0xc0, 0x46, 0x78, 0x61, 0x38, 0x1c, 0x00, 0xf0, -0x23, 0xf9, 0x38, 0x1c, 0x00, 0xf0, 0x88, 0xf8, 0x00, 0xf0, 0xe0, 0xfa, -0xf8, 0x89, 0x71, 0x8b, 0x88, 0x42, 0x04, 0xd1, 0xb9, 0x6a, 0x08, 0x18, -0x04, 0xe0, 0x38, 0xe0, 0x32, 0xe0, 0xfa, 0x6a, 0x10, 0x18, 0x40, 0x1a, -0x81, 0x07, 0x02, 0xd0, 0x80, 0x08, 0x80, 0x00, 0x04, 0x30, 0x21, 0x6b, -0x09, 0x1a, 0x62, 0x6b, 0x91, 0x42, 0x00, 0xd2, 0xe0, 0x6a, 0xc0, 0x46, -0xe0, 0x61, 0xe8, 0x7a, 0x00, 0x28, 0x08, 0xd0, 0x00, 0x21, 0xe9, 0x72, -0x04, 0x99, 0x08, 0x69, 0x01, 0x38, 0x08, 0x61, 0x38, 0x6b, 0x00, 0xf0, -0x5d, 0xfa, 0x18, 0x48, 0x80, 0x6a, 0x80, 0x06, 0x80, 0x0e, 0x01, 0x28, -0x0a, 0xd1, 0xe0, 0x69, 0x00, 0x03, 0x00, 0x0b, 0x0c, 0x4c, 0xa1, 0x6a, -0x88, 0x42, 0x03, 0xd0, 0x05, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x01, 0x20, 0x40, 0x04, 0x09, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x05, 0xe0, -0xa0, 0x68, 0x00, 0x28, 0x01, 0xd0, 0x00, 0xf0, 0x9f, 0xfa, 0xae, 0x72, -0xee, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, -0x00, 0x40, 0x14, 0x40, 0x10, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, -0x98, 0x19, 0x00, 0x80, 0x55, 0x55, 0x55, 0x55, 0x28, 0x03, 0x00, 0x80, -0xe8, 0x19, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, 0x80, 0xb5, 0x07, 0x1c, +0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x83, 0x42, 0xf6, 0xd8, 0x90, 0xbc, +0x70, 0x47, 0x80, 0xb4, 0x02, 0x78, 0xd2, 0x06, 0xd2, 0x0e, 0x00, 0x23, +0x01, 0x27, 0x01, 0x2a, 0x01, 0xdc, 0x0f, 0x70, 0x11, 0xe0, 0x40, 0x78, +0xc0, 0x46, 0x08, 0x70, 0x14, 0x2a, 0x04, 0xd1, 0x08, 0x48, 0x01, 0x7a, +0x01, 0x31, 0x01, 0x72, 0x07, 0xe0, 0x02, 0x2a, 0x05, 0xd0, 0x05, 0x2a, +0x03, 0xd0, 0x06, 0x2a, 0x01, 0xd0, 0x15, 0x2a, 0x02, 0xd1, 0x18, 0x1c, +0x80, 0xbc, 0x70, 0x47, 0x38, 0x1c, 0xfb, 0xe7, 0xe0, 0x82, 0x20, 0x40, +0x00, 0xb5, 0x0f, 0x48, 0x01, 0x23, 0x1b, 0x06, 0x41, 0x69, 0x99, 0x43, +0x1a, 0x09, 0x41, 0x61, 0xd1, 0x60, 0x00, 0x21, 0xa1, 0x22, 0x52, 0x03, +0x91, 0x61, 0x19, 0x1c, 0x09, 0x4a, 0xc0, 0x46, 0x11, 0x60, 0x1b, 0x23, +0xdb, 0x01, 0xc0, 0x18, 0x80, 0x69, 0x00, 0x28, 0x03, 0xd0, 0x02, 0xf0, +0x61, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x04, 0x48, 0x41, 0x88, 0x01, 0x31, +0x41, 0x80, 0xf8, 0xe7, 0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, +0xe0, 0x82, 0x20, 0x40, 0x70, 0x47, 0x00, 0x00, 0xf0, 0xb5, 0x86, 0xb0, +0x95, 0x4a, 0xd0, 0x68, 0xd7, 0x1d, 0x79, 0x37, 0x01, 0x28, 0x09, 0xd1, +0x38, 0x89, 0x00, 0x28, 0x06, 0xd1, 0xd0, 0x6f, 0x02, 0x23, 0x01, 0x68, +0x99, 0x43, 0x01, 0x60, 0x14, 0x20, 0x38, 0x81, 0x8e, 0x4c, 0x61, 0x6a, +0x8e, 0x48, 0xc3, 0x6b, 0x59, 0x18, 0xc1, 0x63, 0xa0, 0x6a, 0x19, 0x23, +0xdb, 0x01, 0xd4, 0x18, 0xa0, 0x62, 0x21, 0x6a, 0x09, 0x03, 0x09, 0x0b, +0x81, 0x42, 0x05, 0xd1, 0x01, 0x20, 0x40, 0x04, 0x87, 0x49, 0xc0, 0x46, +0x08, 0x60, 0xf3, 0xe0, 0xbb, 0x8a, 0x58, 0x1c, 0xb8, 0x82, 0x3d, 0x8b, +0x01, 0x20, 0x00, 0x21, 0xab, 0x42, 0x04, 0xdb, 0xd3, 0x1d, 0x89, 0x33, +0x58, 0x70, 0xb9, 0x82, 0xf9, 0x83, 0x33, 0x23, 0x9b, 0x01, 0xd3, 0x18, +0x05, 0x93, 0x5b, 0x69, 0x0f, 0x2b, 0x73, 0xd2, 0x00, 0x21, 0x7c, 0x4f, +0xc0, 0x46, 0x39, 0x61, 0x21, 0x6a, 0x8a, 0x68, 0x12, 0x04, 0x12, 0x0c, +0x4b, 0x68, 0x1e, 0x0c, 0x36, 0x04, 0xfd, 0x1f, 0x09, 0x3d, 0x00, 0x2e, +0x05, 0xd1, 0x3b, 0x2a, 0x03, 0xd3, 0x01, 0x23, 0xdb, 0x02, 0x9a, 0x42, +0x01, 0xd9, 0xa8, 0x73, 0xc8, 0xe0, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x31, +0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x03, 0x91, 0x03, 0xa9, 0x09, 0x88, +0x01, 0x31, 0x09, 0x04, 0x09, 0x0c, 0x79, 0x82, 0x49, 0x09, 0x05, 0x31, +0x09, 0x06, 0x09, 0x0e, 0x69, 0x4e, 0xc0, 0x46, 0x02, 0x96, 0x69, 0x48, +0x43, 0x6a, 0xc0, 0x46, 0x01, 0x93, 0x83, 0x6a, 0xc0, 0x46, 0x00, 0x93, +0xc2, 0x1d, 0x11, 0x32, 0x80, 0x69, 0x00, 0x03, 0x00, 0x0b, 0x92, 0x68, +0xb3, 0x07, 0x1a, 0x43, 0x12, 0x68, 0x90, 0x42, 0x01, 0xd1, 0x01, 0x20, +0x0d, 0xe0, 0x90, 0x42, 0x05, 0xd9, 0x00, 0x9b, 0x18, 0x1a, 0x01, 0x9b, +0xd2, 0x1a, 0x82, 0x18, 0x00, 0xe0, 0x12, 0x1a, +0x01, 0x20, 0x09, 0x01, 0x91, 0x42, 0x00, 0xd3, 0x00, 0x20, 0x01, 0x28, +0x65, 0xd1, 0x51, 0x49, 0x20, 0x69, 0x00, 0x28, 0x62, 0xd0, 0x05, 0x99, +0x48, 0x69, 0x01, 0x30, 0x48, 0x61, 0x02, 0x20, 0x21, 0x6a, 0xc0, 0x46, +0x08, 0x60, 0x00, 0xf0, 0xa7, 0xfc, 0x78, 0x63, 0xbe, 0x60, 0x49, 0x49, +0x22, 0x6a, 0xa3, 0x6b, 0xd3, 0x18, 0x66, 0x6b, 0xb3, 0x42, 0x00, 0xd9, +0x22, 0x6b, 0xc0, 0x46, 0xba, 0x62, 0xba, 0x6a, 0x0c, 0x32, 0xfa, 0x62, +0x00, 0x22, 0xfa, 0x61, 0x03, 0xaa, 0x52, 0x88, 0xd2, 0x09, 0x03, 0xd3, +0x01, 0x22, 0x00, 0xe0, 0x7b, 0xe0, 0x00, 0xe0, 0x00, 0x22, 0x7a, 0x60, +0x7a, 0x68, 0xc0, 0x46, 0x02, 0x60, 0x78, 0x8a, 0x41, 0x4e, 0x60, 0x28, +0x04, 0xdc, 0xb0, 0x83, 0x78, 0x8a, 0xc0, 0x46, 0xf0, 0x83, 0x08, 0xe0, +0x60, 0x20, 0xb0, 0x83, 0x79, 0x8a, 0xf8, 0x6a, 0x42, 0x18, 0x63, 0x6b, +0x9a, 0x42, 0x03, 0xd8, 0xf1, 0x83, 0x00, 0x22, 0x3a, 0x63, 0x05, 0xe0, +0x21, 0x6b, 0xc0, 0x46, 0x39, 0x63, 0x61, 0x6b, 0x08, 0x1a, 0xf0, 0x83, +0x2d, 0x49, 0x78, 0x6b, 0x42, 0x68, 0xc0, 0x46, 0xba, 0x60, 0x82, 0x68, +0xc0, 0x46, 0xfa, 0x60, 0x02, 0x69, 0xc0, 0x46, 0x7a, 0x61, 0x40, 0x69, +0xc0, 0x46, 0xb8, 0x61, 0x2e, 0x4b, 0xc8, 0x18, 0x04, 0x90, 0x00, 0xf0, +0x37, 0xf9, 0x04, 0x98, 0x00, 0xf0, 0x88, 0xf8, 0x00, 0xf0, 0xf6, 0xfa, +0x78, 0x8a, 0xf1, 0x8b, 0x88, 0x42, 0x04, 0xd1, 0xf9, 0x6a, 0x08, 0x18, +0x04, 0xe0, 0x38, 0xe0, 0x32, 0xe0, 0x3a, 0x6b, 0x10, 0x18, 0x40, 0x1a, +0x81, 0x07, 0x02, 0xd0, 0x80, 0x08, 0x80, 0x00, 0x04, 0x30, 0x61, 0x6b, +0x09, 0x1a, 0xa2, 0x6b, 0x91, 0x42, 0x00, 0xd2, 0x20, 0x6b, 0xc0, 0x46, +0x20, 0x62, 0xe8, 0x7b, 0x00, 0x28, 0x08, 0xd0, 0x00, 0x22, 0xea, 0x73, +0x05, 0x99, 0x48, 0x69, 0x01, 0x38, 0x48, 0x61, 0x78, 0x6b, 0x00, 0xf0, +0x73, 0xfa, 0x18, 0x48, 0x80, 0x6a, 0x80, 0x06, 0x80, 0x0e, 0x01, 0x28, +0x0a, 0xd1, 0x20, 0x6a, 0x00, 0x03, 0x00, 0x0b, 0x0b, 0x4c, 0xa1, 0x6a, +0x88, 0x42, 0x03, 0xd0, 0x06, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x01, 0x20, 0x40, 0x04, 0x08, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x06, 0xe0, +0xe0, 0x68, 0x00, 0x28, 0x01, 0xd0, 0x00, 0xf0, 0xb5, 0xfa, 0x01, 0x20, +0xa8, 0x73, 0xed, 0xe7, 0x68, 0x0e, 0x00, 0x80, 0x00, 0x40, 0x14, 0x40, +0xa4, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0x28, 0x1a, 0x00, 0x80, +0x55, 0x55, 0x55, 0x55, 0xa8, 0x03, 0x00, 0x80, 0x68, 0x1a, 0x00, 0x80, +0xc4, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x80, 0xb5, 0x07, 0x1c, 0x78, 0x6a, 0x40, 0x89, 0xff, 0x21, 0x01, 0x31, 0x01, 0x40, 0x10, 0x48, 0x02, 0xd1, 0x81, 0x6c, 0x01, 0x31, 0x81, 0x64, 0x79, 0x6a, 0x49, 0x89, 0x49, 0x0b, 0x02, 0xd2, 0x41, 0x6c, 0x01, 0x31, 0x41, 0x64, 0x0b, 0x48, 0x41, 0x6a, 0x01, 0x31, 0x41, 0x62, 0x78, 0x6a, 0x39, 0x6b, 0xc0, 0x46, -0x48, 0x62, 0x38, 0x6b, 0x00, 0xf0, 0xe2, 0xfb, 0x38, 0x1c, 0x00, 0xf0, -0x9f, 0xf8, 0x01, 0x20, 0x04, 0x49, 0xc0, 0x46, 0xc8, 0x72, 0x80, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x10, 0x2a, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, -0x98, 0x19, 0x00, 0x80, 0xf8, 0xb5, 0x07, 0x1c, 0x00, 0x22, 0xf9, 0x1d, +0x48, 0x62, 0x38, 0x6b, 0x00, 0xf0, 0xf8, 0xfb, 0x38, 0x1c, 0x00, 0xf0, +0xb3, 0xf8, 0x01, 0x20, 0x04, 0x49, 0xc0, 0x46, 0xc8, 0x73, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0xa4, 0x2a, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, +0x18, 0x1a, 0x00, 0x80, 0xf8, 0xb5, 0x07, 0x1c, 0x00, 0x22, 0xf9, 0x1d, 0x61, 0x31, 0x0d, 0x1c, 0x78, 0x6a, 0xc0, 0x46, 0x00, 0x90, 0x40, 0x89, 0x03, 0x0c, 0x01, 0xd2, 0x40, 0x0a, 0x03, 0xd2, 0x38, 0x1c, 0xff, 0xf7, -0xc1, 0xff, 0x54, 0xe0, 0x2b, 0x48, 0x80, 0x6b, 0x00, 0x09, 0x1f, 0xd3, -0x08, 0x78, 0x40, 0x08, 0x1c, 0xd2, 0x00, 0x20, 0x43, 0x00, 0xcc, 0x5a, -0x27, 0x4e, 0x9e, 0x19, 0x65, 0x23, 0x5b, 0x01, 0xf3, 0x18, 0x9b, 0x8b, -0x9c, 0x42, 0x0e, 0xd0, 0xb8, 0x69, 0x39, 0x6b, 0xc0, 0x46, 0x88, 0x61, -0xf8, 0x68, 0x39, 0x6b, 0xc0, 0x46, 0xc8, 0x60, 0x38, 0x1c, 0x00, 0xf0, -0x13, 0xf9, 0x38, 0x1c, 0x00, 0xf0, 0x60, 0xf8, 0x33, 0xe0, 0x01, 0x30, -0x03, 0x28, 0xe3, 0xd3, 0x1a, 0x48, 0x0b, 0x23, 0x1b, 0x02, 0xc1, 0x18, -0x09, 0x69, 0x00, 0x29, 0x24, 0xd0, 0x7d, 0x63, 0x00, 0x99, 0x49, 0x89, -0x09, 0x0c, 0x1f, 0xd2, 0x00, 0x24, 0x2d, 0x23, -0x9b, 0x01, 0xc1, 0x18, 0x89, 0x6b, 0x00, 0x29, 0x18, 0xd0, 0x05, 0x1c, -0xfe, 0x1d, 0x2d, 0x36, 0xa2, 0x00, 0x52, 0x19, 0x2d, 0x23, 0x9b, 0x01, -0xd2, 0x18, 0x92, 0x6b, 0x38, 0x1c, 0x31, 0x1c, 0x02, 0xf0, 0x7e, 0xfc, -0x01, 0x28, 0x0e, 0xd0, 0x01, 0x34, 0xa0, 0x00, 0x40, 0x19, 0x2d, 0x23, -0x9b, 0x01, 0xc0, 0x18, 0x80, 0x6b, 0x00, 0x28, 0xea, 0xd1, 0x01, 0xe0, -0x01, 0x2a, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x07, 0xf8, 0xf8, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x68, 0x1a, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, -0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x69, 0x39, 0x6b, 0xc0, 0x46, 0x88, 0x61, -0xf8, 0x68, 0x39, 0x6b, 0xc0, 0x46, 0xc8, 0x60, 0x78, 0x6a, 0x40, 0x89, -0x01, 0x0c, 0x0e, 0xd2, 0x40, 0x0a, 0x0c, 0xd3, 0x38, 0x68, 0x40, 0x08, -0x02, 0xd3, 0x38, 0x1c, 0x02, 0xf0, 0x10, 0xfc, 0x38, 0x1c, 0x00, 0xf0, -0xbb, 0xf8, 0x38, 0x1c, 0x00, 0xf0, 0x08, 0xf8, 0x02, 0xe0, 0x38, 0x1c, -0xff, 0xf7, 0x44, 0xff, 0x01, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x01, 0x21, 0x00, 0x6b, 0x40, 0x6a, 0xc0, 0x46, 0x01, 0x60, 0x70, 0x47, -0xb0, 0xb4, 0xc1, 0x1d, 0x39, 0x31, 0x09, 0x8b, 0x89, 0x08, 0x09, 0x04, -0x09, 0x0c, 0x84, 0x6a, 0xc2, 0x1d, 0x61, 0x32, 0x00, 0x20, 0x00, 0x29, -0x0c, 0xdd, 0x87, 0x00, 0x3d, 0x19, 0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, -0x1b, 0x68, 0xc0, 0x46, 0xd3, 0x51, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, -0x88, 0x42, 0xf2, 0xdb, 0xb0, 0xbc, 0x70, 0x47, 0xf0, 0xb5, 0xa0, 0xb0, -0x01, 0x23, 0x9b, 0x07, 0xc1, 0x1d, 0x21, 0x31, 0x19, 0x43, 0x09, 0x68, -0xc0, 0x46, 0x0b, 0x91, 0xc1, 0x1d, 0x53, 0x31, 0x19, 0x43, 0x1f, 0x91, -0x09, 0x68, 0x01, 0xaf, 0xfa, 0x1d, 0x39, 0x32, 0x1e, 0x92, 0x17, 0xab, -0x59, 0x80, 0x3a, 0x49, 0x01, 0x23, 0x9b, 0x07, 0x0a, 0x6a, 0x13, 0x43, -0xcc, 0x1d, 0x11, 0x34, 0x89, 0x69, 0x09, 0x03, 0x09, 0x0b, 0x22, 0x69, -0xe5, 0x68, 0xc0, 0x46, 0x1d, 0x95, 0xfc, 0x1d, 0x39, 0x34, 0x64, 0x8b, -0x64, 0x09, 0x05, 0x34, 0x24, 0x06, 0x24, 0x0e, 0x1c, 0x94, 0x56, 0x1a, -0x1b, 0x96, 0x1c, 0x9c, 0x2e, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x01, 0x26, -0x1d, 0x9d, 0x1a, 0x68, 0x91, 0x42, 0x01, 0xd1, 0x32, 0x1c, 0x0b, 0xe0, -0x91, 0x42, 0x03, 0xd9, 0x52, 0x1b, 0x1b, 0x9e, 0xb5, 0x18, 0x00, 0xe0, -0x55, 0x1a, 0x01, 0x22, 0x24, 0x01, 0xac, 0x42, 0x00, 0xd3, 0x00, 0x22, -0x01, 0x2a, 0xe6, 0xd1, 0x91, 0x07, 0x01, 0x43, 0x09, 0x68, 0xc0, 0x46, -0x39, 0x60, 0x93, 0x07, 0x01, 0x1d, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, -0x79, 0x60, 0xc1, 0x1d, 0x01, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, -0xb9, 0x60, 0x1f, 0x99, 0x09, 0x68, 0x1e, 0x9a, 0xc0, 0x46, 0x51, 0x83, -0xc1, 0x1d, 0x1d, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x38, 0x63, -0x79, 0x62, 0xc1, 0x1d, 0x11, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, -0xb9, 0x61, 0xc1, 0x1d, 0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, -0xf9, 0x60, 0xc1, 0x1d, 0x17, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, -0xf9, 0x83, 0x0e, 0x30, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xf8, 0x81, -0x38, 0x68, 0x40, 0x08, 0x02, 0xd3, 0x38, 0x1c, 0x02, 0xf0, 0x60, 0xfb, -0x38, 0x1c, 0x00, 0xf0, 0x0b, 0xf8, 0x38, 0x1c, 0xff, 0xf7, 0x58, 0xff, -0x20, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x28, 0x03, 0x00, 0x80, -0x55, 0x55, 0x55, 0x55, 0xf8, 0xb5, 0x07, 0x1c, -0xf8, 0x1d, 0x39, 0x30, 0x41, 0x8b, 0x38, 0x4a, 0x91, 0x42, 0x00, 0xdd, -0x42, 0x83, 0x42, 0x8b, 0xc0, 0x46, 0x00, 0x92, 0x01, 0x20, 0x3a, 0x1d, -0x06, 0xca, 0xbb, 0x6a, 0x02, 0xf0, 0x12, 0xff, 0x32, 0x4a, 0xc0, 0x46, -0x00, 0x92, 0x32, 0x4e, 0x30, 0x6a, 0x32, 0x4c, 0xe1, 0x6d, 0x41, 0x18, -0x38, 0x6b, 0xc3, 0x1d, 0x05, 0x33, 0x01, 0x20, 0x72, 0x6a, 0x02, 0xf0, -0xff, 0xfe, 0xe0, 0x6d, 0x18, 0x30, 0xb1, 0x6a, 0x81, 0x42, 0x00, 0xd8, -0x00, 0x20, 0xe0, 0x65, 0x17, 0x23, 0xdb, 0x01, 0x20, 0x1c, 0xe1, 0x6d, -0xe4, 0x18, 0xe2, 0x6b, 0x92, 0x00, 0x27, 0x4b, 0xc0, 0x46, 0x99, 0x50, -0x26, 0x4d, 0xa8, 0x6b, 0x41, 0x08, 0x05, 0xd3, 0x40, 0x08, 0x40, 0x00, -0xa8, 0x63, 0x01, 0x20, 0x01, 0xf0, 0xd8, 0xff, 0x22, 0x4a, 0x1f, 0x48, -0x29, 0x7b, 0x00, 0x29, 0x02, 0xd0, 0x69, 0x7b, 0x00, 0x29, 0x00, 0xd1, -0x1f, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x05, 0x1c, 0xe0, 0x6b, 0x80, 0x00, -0x19, 0x4b, 0xc3, 0x18, 0x05, 0xce, 0xc1, 0x1d, 0x11, 0x31, 0x01, 0x20, -0x02, 0xf0, 0xce, 0xfe, 0xe0, 0x6b, 0x01, 0x30, 0xe0, 0x63, 0x17, 0x28, -0x01, 0xd3, 0x00, 0x20, 0xe0, 0x63, 0x00, 0x20, 0x39, 0x6b, 0xc0, 0x46, -0x08, 0x65, 0x78, 0x6a, 0x39, 0x6b, 0xc0, 0x46, 0x48, 0x62, 0x33, 0x23, -0x9b, 0x01, 0xe8, 0x18, 0x41, 0x68, 0x00, 0x29, 0x03, 0xd1, 0x39, 0x6b, -0xc0, 0x46, 0x41, 0x60, 0x04, 0xe0, 0x39, 0x6b, 0x82, 0x68, 0xc0, 0x46, -0x11, 0x65, 0x39, 0x6b, 0xc0, 0x46, 0x81, 0x60, 0xf8, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0xea, 0x05, 0x00, 0x00, 0x18, 0x00, 0x14, 0x02, -0xf8, 0x28, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 0x44, 0x82, 0x20, 0x40, -0x68, 0x0e, 0x00, 0x80, 0x04, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x03, -0xf0, 0xb5, 0x11, 0x4e, 0xff, 0x25, 0x01, 0x35, 0x10, 0x4f, 0xc0, 0x46, -0x35, 0x60, 0x38, 0x69, 0x01, 0x38, 0x38, 0x61, 0x7c, 0x68, 0x00, 0x2c, -0x10, 0xd0, 0x20, 0x6d, 0xc0, 0x46, 0x78, 0x60, 0x20, 0x1c, 0x00, 0xf0, -0x21, 0xf8, 0x20, 0x1c, 0x00, 0xf0, 0x04, 0xfa, 0x08, 0x48, 0x80, 0x6a, -0x00, 0x0c, 0x00, 0x07, 0xe9, 0xd1, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x05, 0x48, 0xc1, 0x79, 0x01, 0x31, 0xc1, 0x71, 0xf7, 0xe7, 0x00, 0x00, -0x00, 0x00, 0x00, 0xb0, 0xa8, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, -0xa0, 0x82, 0x20, 0x40, 0x01, 0x20, 0x80, 0x03, 0x01, 0x49, 0xc0, 0x46, -0x08, 0x60, 0x70, 0x47, 0x00, 0x00, 0x00, 0xb0, 0x90, 0xb5, 0x07, 0x1c, +0xc1, 0xff, 0x67, 0xe0, 0x35, 0x48, 0xc0, 0x6b, +0x00, 0x09, 0x1f, 0xd3, 0x08, 0x78, 0x40, 0x08, 0x1c, 0xd2, 0x00, 0x20, +0x43, 0x00, 0xcc, 0x5a, 0x31, 0x4e, 0x9e, 0x19, 0x33, 0x23, 0x9b, 0x01, +0xf3, 0x18, 0x1b, 0x88, 0x9c, 0x42, 0x0e, 0xd0, 0xb8, 0x69, 0x39, 0x6b, +0xc0, 0x46, 0x88, 0x61, 0xf8, 0x68, 0x39, 0x6b, 0xc0, 0x46, 0xc8, 0x60, +0x38, 0x1c, 0x00, 0xf0, 0x27, 0xf9, 0x38, 0x1c, 0x00, 0xf0, 0x74, 0xf8, +0x46, 0xe0, 0x01, 0x30, 0x03, 0x28, 0xe3, 0xdb, 0x02, 0x20, 0x43, 0x00, +0x5c, 0x18, 0xe4, 0x88, 0x22, 0x4e, 0x9e, 0x19, 0x33, 0x23, 0x9b, 0x01, +0xf3, 0x18, 0x1b, 0x88, 0x9c, 0x42, 0x03, 0xd1, 0x01, 0x23, 0x01, 0x38, +0xd8, 0x42, 0xf0, 0xdc, 0x01, 0x23, 0xd8, 0x42, 0xc4, 0xd0, 0x1b, 0x4e, +0x0b, 0x23, 0x1b, 0x02, 0xf0, 0x18, 0x40, 0x69, 0x00, 0x28, 0x24, 0xd0, +0x7d, 0x63, 0x00, 0x98, 0x40, 0x89, 0x00, 0x0c, 0x1f, 0xd2, 0x00, 0x24, +0x2d, 0x23, 0x9b, 0x01, 0xf0, 0x18, 0xc0, 0x6b, 0x35, 0x1c, 0x00, 0x28, +0x17, 0xd0, 0xfe, 0x1d, 0x2d, 0x36, 0xa2, 0x00, 0x52, 0x19, 0x2d, 0x23, +0x9b, 0x01, 0xd2, 0x18, 0xd2, 0x6b, 0x38, 0x1c, 0x31, 0x1c, 0x02, 0xf0, +0x7b, 0xfc, 0x01, 0x28, 0x0e, 0xd0, 0x01, 0x34, 0xa0, 0x00, 0x40, 0x19, +0x2d, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0xc0, 0x6b, 0x00, 0x28, 0xea, 0xd1, +0x01, 0xe0, 0x01, 0x2a, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x08, 0xf8, +0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe8, 0x1a, 0x00, 0x80, +0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x69, 0x39, 0x6b, +0xc0, 0x46, 0x88, 0x61, 0xf8, 0x68, 0x39, 0x6b, 0xc0, 0x46, 0xc8, 0x60, +0x78, 0x6a, 0x40, 0x89, 0x01, 0x0c, 0x0e, 0xd2, 0x40, 0x0a, 0x0c, 0xd3, +0x38, 0x68, 0x40, 0x08, 0x02, 0xd3, 0x38, 0x1c, 0x02, 0xf0, 0x0c, 0xfc, +0x38, 0x1c, 0x00, 0xf0, 0xbb, 0xf8, 0x38, 0x1c, 0x00, 0xf0, 0x08, 0xf8, +0x02, 0xe0, 0x38, 0x1c, 0xff, 0xf7, 0x30, 0xff, 0x01, 0x20, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x01, 0x21, 0x00, 0x6b, 0x40, 0x6a, 0xc0, 0x46, +0x01, 0x60, 0x70, 0x47, 0xb0, 0xb4, 0xc1, 0x1d, 0x39, 0x31, 0x09, 0x8b, +0x89, 0x08, 0x09, 0x04, 0x09, 0x0c, 0x84, 0x6a, 0xc2, 0x1d, 0x61, 0x32, +0x00, 0x20, 0x00, 0x29, 0x0c, 0xdd, 0x87, 0x00, 0x3d, 0x19, 0x01, 0x23, +0x9b, 0x07, 0x2b, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0xd3, 0x51, 0x01, 0x30, +0x00, 0x04, 0x00, 0x0c, 0x88, 0x42, 0xf2, 0xdb, 0xb0, 0xbc, 0x70, 0x47, +0xf0, 0xb5, 0xa0, 0xb0, 0x01, 0x23, 0x9b, 0x07, 0xc1, 0x1d, 0x21, 0x31, +0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x0b, 0x91, 0xc1, 0x1d, 0x53, 0x31, +0x19, 0x43, 0x1f, 0x91, 0x09, 0x68, 0x01, 0xaf, 0xfa, 0x1d, 0x39, 0x32, +0x1e, 0x92, 0x17, 0xab, 0x59, 0x80, 0x3a, 0x49, 0x01, 0x23, 0x9b, 0x07, +0x0a, 0x6a, 0x13, 0x43, 0xcc, 0x1d, 0x11, 0x34, 0x89, 0x69, 0x09, 0x03, +0x09, 0x0b, 0x22, 0x69, 0xe5, 0x68, 0xc0, 0x46, 0x1d, 0x95, 0xfc, 0x1d, +0x39, 0x34, 0x64, 0x8b, 0x64, 0x09, 0x05, 0x34, 0x24, 0x06, 0x24, 0x0e, +0x1c, 0x94, 0x56, 0x1a, 0x1b, 0x96, 0x1c, 0x9c, 0x2e, 0x4a, 0xc0, 0x46, +0x00, 0x92, 0x01, 0x26, 0x1d, 0x9d, 0x1a, 0x68, 0x91, 0x42, 0x01, 0xd1, +0x32, 0x1c, 0x0b, 0xe0, 0x91, 0x42, 0x03, 0xd9, 0x52, 0x1b, 0x1b, 0x9e, +0xb5, 0x18, 0x00, 0xe0, 0x55, 0x1a, 0x01, 0x22, 0x24, 0x01, 0xac, 0x42, +0x00, 0xd3, 0x00, 0x22, 0x01, 0x2a, 0xe6, 0xd1, 0x91, 0x07, 0x01, 0x43, +0x09, 0x68, 0xc0, 0x46, 0x39, 0x60, 0x93, 0x07, +0x01, 0x1d, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x79, 0x60, 0xc1, 0x1d, +0x01, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0xb9, 0x60, 0x1f, 0x99, +0x09, 0x68, 0x1e, 0x9a, 0xc0, 0x46, 0x51, 0x83, 0xc1, 0x1d, 0x1d, 0x31, +0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x38, 0x63, 0x79, 0x62, 0xc1, 0x1d, +0x11, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0xb9, 0x61, 0xc1, 0x1d, +0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0xf9, 0x60, 0xc1, 0x1d, +0x17, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0xf9, 0x83, 0x0e, 0x30, +0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xf8, 0x81, 0x38, 0x68, 0x40, 0x08, +0x02, 0xd3, 0x38, 0x1c, 0x02, 0xf0, 0x5c, 0xfb, 0x38, 0x1c, 0x00, 0xf0, +0x0b, 0xf8, 0x38, 0x1c, 0xff, 0xf7, 0x58, 0xff, 0x20, 0xb0, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0xa8, 0x03, 0x00, 0x80, 0x55, 0x55, 0x55, 0x55, +0xf8, 0xb5, 0x07, 0x1c, 0xf8, 0x1d, 0x39, 0x30, 0x41, 0x8b, 0x39, 0x4a, +0x91, 0x42, 0x00, 0xdd, 0x42, 0x83, 0x42, 0x8b, 0xc0, 0x46, 0x00, 0x92, +0x01, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0xbb, 0x6a, 0x02, 0xf0, 0x0e, 0xff, +0x33, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x33, 0x4e, 0x30, 0x6a, 0x33, 0x4c, +0xe1, 0x6d, 0x41, 0x18, 0x38, 0x6b, 0xc3, 0x1d, 0x05, 0x33, 0x01, 0x20, +0x72, 0x6a, 0x02, 0xf0, 0xfb, 0xfe, 0xe0, 0x6d, 0x18, 0x30, 0x00, 0x25, +0xb1, 0x6a, 0x81, 0x42, 0x01, 0xd8, 0xe5, 0x65, 0x00, 0xe0, 0xe0, 0x65, +0x2f, 0x23, 0x9b, 0x01, 0x20, 0x1c, 0xe1, 0x6d, 0xe4, 0x18, 0x22, 0x68, +0x92, 0x00, 0x27, 0x4b, 0xc0, 0x46, 0x99, 0x50, 0x26, 0x48, 0xc1, 0x6b, +0x4a, 0x08, 0x05, 0xd3, 0x49, 0x08, 0x49, 0x00, 0xc1, 0x63, 0x01, 0x20, +0x01, 0xf0, 0xd6, 0xff, 0x22, 0x4a, 0x1f, 0x48, 0xc1, 0x1d, 0x89, 0x31, +0x0b, 0x78, 0x00, 0x2b, 0x02, 0xd0, 0x49, 0x78, 0x00, 0x29, 0x00, 0xd1, +0x1e, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x20, 0x68, 0x80, 0x00, 0x19, 0x4b, +0xc3, 0x18, 0x05, 0xce, 0xc1, 0x1d, 0x11, 0x31, 0x01, 0x20, 0x02, 0xf0, +0xc7, 0xfe, 0x14, 0x48, 0x21, 0x68, 0x01, 0x31, 0x21, 0x60, 0x17, 0x29, +0x00, 0xd3, 0x25, 0x60, 0x39, 0x6b, 0xc0, 0x46, 0x0d, 0x65, 0x79, 0x6a, +0x3a, 0x6b, 0xc0, 0x46, 0x51, 0x62, 0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, +0x81, 0x68, 0x00, 0x29, 0x03, 0xd1, 0x39, 0x6b, 0xc0, 0x46, 0x81, 0x60, +0x04, 0xe0, 0x39, 0x6b, 0xc2, 0x68, 0xc0, 0x46, 0x11, 0x65, 0x39, 0x6b, +0xc0, 0x46, 0xc1, 0x60, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0xea, 0x05, 0x00, 0x00, 0x18, 0x00, 0x14, 0x02, 0x7c, 0x29, 0x00, 0x80, +0x68, 0x0e, 0x00, 0x80, 0x44, 0x82, 0x20, 0x40, 0xe8, 0x0e, 0x00, 0x80, +0x04, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x03, 0xf0, 0xb5, 0x11, 0x4e, +0xff, 0x25, 0x01, 0x35, 0x10, 0x4f, 0xc0, 0x46, 0x35, 0x60, 0x78, 0x69, +0x01, 0x38, 0x78, 0x61, 0xbc, 0x68, 0x00, 0x2c, 0x10, 0xd0, 0x20, 0x6d, +0xc0, 0x46, 0xb8, 0x60, 0x20, 0x1c, 0x00, 0xf0, 0x21, 0xf8, 0x20, 0x1c, +0x00, 0xf0, 0x04, 0xfa, 0x08, 0x48, 0x80, 0x6a, 0x00, 0x0c, 0x00, 0x07, +0xe9, 0xd1, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x05, 0x48, 0xc1, 0x79, +0x01, 0x31, 0xc1, 0x71, 0xf7, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, +0x28, 0x1b, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, 0xa0, 0x82, 0x20, 0x40, +0x01, 0x20, 0x80, 0x03, 0x01, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x70, 0x47, +0x00, 0x00, 0x00, 0xb0, 0x90, 0xb5, 0x07, 0x1c, 0x38, 0x68, 0xc0, 0x08, 0x09, 0xd3, 0x1d, 0x48, 0x01, 0x6a, 0x01, 0x39, 0x01, 0x62, 0x20, 0x30, 0x00, 0x79, 0x00, 0x28, 0x01, 0xd0, 0xfe, 0xf7, -0x09, 0xfe, 0x01, 0x23, 0x9b, 0x07, 0xf8, 0x1d, 0x1d, 0x30, 0x18, 0x43, -0x00, 0x68, 0x16, 0x4c, 0x21, 0x6a, 0x81, 0x42, 0x21, 0xd1, 0x01, 0x1c, +0xf3, 0xfd, 0x01, 0x23, 0x9b, 0x07, 0xf8, 0x1d, 0x1d, 0x30, 0x18, 0x43, +0x00, 0x68, 0x16, 0x4c, 0x61, 0x6a, 0x81, 0x42, 0x21, 0xd1, 0x01, 0x1c, 0x19, 0x43, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x01, 0x29, 0x1a, 0xd1, -0x00, 0xf0, 0x22, 0xf8, 0x20, 0x62, 0x20, 0x6a, 0xe1, 0x69, 0x88, 0x42, +0x00, 0xf0, 0x22, 0xf8, 0x60, 0x62, 0x60, 0x6a, 0x21, 0x6a, 0x88, 0x42, 0x05, 0xd0, 0x01, 0x21, 0x89, 0x07, 0x01, 0x43, 0x09, 0x68, 0x09, 0x04, -0xf2, 0xd0, 0x51, 0x21, 0x89, 0x03, 0x22, 0x6a, 0xe3, 0x6a, 0x9a, 0x42, -0x02, 0xd1, 0x20, 0x6b, 0x62, 0x6b, 0x80, 0x1a, 0x04, 0x38, 0xc8, 0x60, +0xf2, 0xd0, 0x51, 0x21, 0x89, 0x03, 0x62, 0x6a, 0x23, 0x6b, 0x9a, 0x42, +0x02, 0xd1, 0x60, 0x6b, 0xa2, 0x6b, 0x80, 0x1a, 0x04, 0x38, 0xc8, 0x60, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0x79, 0x6a, 0xc0, 0x46, -0x08, 0x60, 0xf7, 0xe7, 0xec, 0x05, 0x00, 0x80, 0x68, 0x1a, 0x00, 0x80, -0x01, 0x23, 0x9b, 0x07, 0xc1, 0x1d, 0x01, 0x31, -0x19, 0x43, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x08, 0x18, 0x0d, 0x30, -0x81, 0x07, 0x02, 0xd0, 0x80, 0x08, 0x80, 0x00, 0x04, 0x30, 0x04, 0x49, -0x4a, 0x6b, 0x12, 0x18, 0x0b, 0x6b, 0x9a, 0x42, 0x00, 0xd9, 0xc8, 0x6a, -0x70, 0x47, 0x00, 0x00, 0x68, 0x1a, 0x00, 0x80, 0x00, 0xb5, 0x04, 0x48, -0x80, 0x68, 0x10, 0x28, 0x01, 0xd3, 0x00, 0xf0, 0x05, 0xf8, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0x68, 0x1a, 0x00, 0x80, 0x88, 0xb5, 0x0c, 0x4f, -0x38, 0x78, 0x00, 0x28, 0x11, 0xd1, 0x0b, 0x49, 0x10, 0x20, 0x02, 0xf0, -0xfb, 0xfd, 0x00, 0x28, 0x0b, 0xd0, 0x01, 0x20, 0x38, 0x70, 0x08, 0x4a, -0xc0, 0x46, 0x00, 0x92, 0x07, 0x48, 0x42, 0x68, 0x07, 0x4b, 0x01, 0x68, -0x00, 0x20, 0x02, 0xf0, 0xe5, 0xfd, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x78, 0x1a, 0x00, 0x80, 0x69, 0x2c, 0xff, 0xff, 0x10, 0x00, 0x35, 0x02, -0xf8, 0x28, 0x00, 0x80, 0x44, 0x80, 0x20, 0x40, 0x90, 0xb5, 0x01, 0x20, -0x40, 0x02, 0x10, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x0f, 0x4f, 0x10, 0x21, -0xf8, 0x1d, 0x3d, 0x30, 0x02, 0xf0, 0x52, 0xfc, 0x19, 0x23, 0xdb, 0x01, -0xfc, 0x18, 0xa0, 0x68, 0x00, 0x28, 0x01, 0xd0, 0x00, 0xf0, 0x14, 0xf8, -0x00, 0x20, 0xc9, 0x23, 0x1b, 0x01, 0xf9, 0x18, 0x08, 0x70, 0xa0, 0x68, -0x10, 0x28, 0x04, 0xd3, 0x01, 0x20, 0xbb, 0x23, 0x1b, 0x01, 0xf9, 0x18, -0x48, 0x72, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, -0xe8, 0x0d, 0x00, 0x80, 0xf8, 0xb5, 0x37, 0x48, 0x19, 0x23, 0xdb, 0x01, -0xc1, 0x18, 0x89, 0x68, 0x35, 0x4d, 0x10, 0x29, 0x00, 0xd9, 0x10, 0x21, -0x29, 0x62, 0x32, 0x48, 0xc1, 0x6c, 0x00, 0x6e, 0x81, 0x42, 0x07, 0xd9, -0x08, 0x1a, 0x07, 0x09, 0x00, 0x24, 0x28, 0x6a, 0xb8, 0x42, 0x12, 0xd2, -0x07, 0x1c, 0x10, 0xe0, 0x81, 0x42, 0x2a, 0xd2, 0x2c, 0x4a, 0x52, 0x6b, -0x10, 0x1a, 0x07, 0x09, 0x28, 0x6a, 0xb8, 0x42, 0x05, 0xd9, 0x0c, 0x09, -0x39, 0x19, 0x88, 0x42, 0x03, 0xd2, 0xc4, 0x1b, 0x01, 0xe0, 0x00, 0x24, -0x07, 0x1c, 0x3e, 0x19, 0x30, 0x01, 0x25, 0x49, 0x02, 0xf0, 0x8a, 0xfd, -0x00, 0x28, 0x3d, 0xd0, 0x23, 0x48, 0x00, 0x2c, 0x1a, 0xd1, 0x1e, 0x49, -0x3a, 0x01, 0x2f, 0x62, 0x09, 0x6e, 0x8c, 0x18, 0x1d, 0x4d, 0x6b, 0x6b, -0xa3, 0x42, 0x00, 0xd8, 0xe4, 0x1a, 0x1e, 0x4b, 0x1a, 0x43, 0x00, 0x92, -0xea, 0x6a, 0x51, 0x18, 0x2a, 0x6b, 0x03, 0x1c, 0x20, 0xe0, 0x1b, 0x48, -0x01, 0x6b, 0x01, 0x31, 0x01, 0x63, 0x00, 0x20, 0x28, 0x62, 0xf8, 0xbc, +0x08, 0x60, 0xf7, 0xe7, 0x6c, 0x06, 0x00, 0x80, 0xe8, 0x1a, 0x00, 0x80, +0x01, 0x23, 0x9b, 0x07, 0xc1, 0x1d, 0x01, 0x31, 0x19, 0x43, 0x09, 0x68, +0x09, 0x04, 0x09, 0x0c, 0x08, 0x18, 0x0d, 0x30, 0x81, 0x07, 0x02, 0xd0, +0x80, 0x08, 0x80, 0x00, 0x04, 0x30, 0x04, 0x49, 0x8a, 0x6b, 0x12, 0x18, +0x4b, 0x6b, 0x9a, 0x42, 0x00, 0xd9, 0x08, 0x6b, 0x70, 0x47, 0x00, 0x00, +0xe8, 0x1a, 0x00, 0x80, 0x00, 0xb5, 0x04, 0x48, 0xc0, 0x68, 0x10, 0x28, +0x01, 0xd3, 0x00, 0xf0, 0x05, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0xe8, 0x1a, 0x00, 0x80, 0x88, 0xb5, 0x0c, 0x4f, 0x38, 0x79, 0x00, 0x28, +0x11, 0xd1, 0x0b, 0x49, 0x10, 0x20, 0x02, 0xf0, 0xf5, 0xfd, 0x00, 0x28, +0x0b, 0xd0, 0x01, 0x20, 0x38, 0x71, 0x08, 0x4a, 0xc0, 0x46, 0x00, 0x92, +0x07, 0x48, 0x42, 0x68, 0x07, 0x4b, 0x01, 0x68, 0x00, 0x20, 0x02, 0xf0, +0xdf, 0xfd, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf8, 0x1a, 0x00, 0x80, +0xe1, 0x2c, 0xff, 0xff, 0x10, 0x00, 0x35, 0x02, 0x7c, 0x29, 0x00, 0x80, +0x44, 0x80, 0x20, 0x40, 0x90, 0xb5, 0x01, 0x20, 0x40, 0x02, 0x10, 0x49, +0xc0, 0x46, 0x08, 0x60, 0x0f, 0x4f, 0x10, 0x21, 0xf8, 0x1d, 0x3d, 0x30, +0x02, 0xf0, 0x4c, 0xfc, 0x19, 0x23, 0xdb, 0x01, 0xfc, 0x18, 0xe0, 0x68, +0x00, 0x28, 0x01, 0xd0, 0x00, 0xf0, 0x14, 0xf8, 0x00, 0x20, 0xc9, 0x23, +0x1b, 0x01, 0xf9, 0x18, 0x08, 0x71, 0xe0, 0x68, 0x10, 0x28, 0x04, 0xd3, +0x01, 0x20, 0xbb, 0x23, 0x1b, 0x01, 0xf9, 0x18, 0x48, 0x73, 0x90, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, 0x68, 0x0e, 0x00, 0x80, +0xf8, 0xb5, 0x37, 0x48, 0x19, 0x23, 0xdb, 0x01, 0xc1, 0x18, 0xc9, 0x68, +0x35, 0x4d, 0x10, 0x29, 0x00, 0xd9, 0x10, 0x21, 0x69, 0x62, 0x32, 0x48, +0xc1, 0x6c, 0x00, 0x6e, 0x81, 0x42, 0x07, 0xd9, 0x08, 0x1a, 0x07, 0x09, +0x00, 0x24, 0x68, 0x6a, 0xb8, 0x42, 0x12, 0xd2, 0x07, 0x1c, 0x10, 0xe0, +0x81, 0x42, 0x2a, 0xd2, 0x2c, 0x4a, 0x52, 0x6b, 0x10, 0x1a, 0x07, 0x09, +0x68, 0x6a, 0xb8, 0x42, 0x05, 0xd9, 0x0c, 0x09, 0x39, 0x19, 0x88, 0x42, +0x03, 0xd2, 0xc4, 0x1b, 0x01, 0xe0, 0x00, 0x24, 0x07, 0x1c, 0x3e, 0x19, +0x30, 0x01, 0x25, 0x49, 0x02, 0xf0, 0x84, 0xfd, 0x00, 0x28, 0x3d, 0xd0, +0x23, 0x48, 0x00, 0x2c, 0x1a, 0xd1, 0x1e, 0x49, 0x3a, 0x01, 0x6f, 0x62, +0x09, 0x6e, 0x8c, 0x18, 0x1d, 0x4d, 0x6b, 0x6b, 0xa3, 0x42, 0x00, 0xd8, +0xe4, 0x1a, 0x1e, 0x4b, 0x1a, 0x43, 0x00, 0x92, 0xea, 0x6a, 0x51, 0x18, +0x2a, 0x6b, 0x03, 0x1c, 0x20, 0xe0, 0x1b, 0x48, 0x01, 0x6b, 0x01, 0x31, +0x01, 0x63, 0x00, 0x20, 0x68, 0x62, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x10, 0x49, 0x24, 0x01, 0x3f, 0x01, 0x11, 0x22, -0x52, 0x05, 0x3a, 0x43, 0x2e, 0x62, 0x00, 0x92, 0x0e, 0x4d, 0xea, 0x6a, +0x52, 0x05, 0x3a, 0x43, 0x6e, 0x62, 0x00, 0x92, 0x0e, 0x4d, 0xea, 0x6a, 0x09, 0x6e, 0x51, 0x18, 0x03, 0x1c, 0x06, 0x1c, 0x00, 0x20, 0x2a, 0x6b, -0x02, 0xf0, 0x50, 0xfd, 0x0c, 0x4a, 0x22, 0x43, 0x00, 0x92, 0xbb, 0x19, -0xe9, 0x6a, 0x2a, 0x6b, 0x00, 0x20, 0x02, 0xf0, 0x47, 0xfd, 0x03, 0x48, +0x02, 0xf0, 0x4a, 0xfd, 0x0c, 0x4a, 0x22, 0x43, 0x00, 0x92, 0xbb, 0x19, +0xe9, 0x6a, 0x2a, 0x6b, 0x00, 0x20, 0x02, 0xf0, 0x41, 0xfd, 0x03, 0x48, 0xc0, 0x46, 0x04, 0x66, 0x00, 0xf0, 0x10, 0xf8, 0x01, 0x20, 0xda, 0xe7, -0xe8, 0x0d, 0x00, 0x80, 0xa8, 0x1a, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, -0xd1, 0x2d, 0xff, 0xff, 0x44, 0x80, 0x20, 0x40, 0x00, 0x00, 0x36, 0x02, +0x68, 0x0e, 0x00, 0x80, 0x28, 0x1b, 0x00, 0x80, 0x7c, 0x29, 0x00, 0x80, +0x49, 0x2e, 0xff, 0xff, 0x44, 0x80, 0x20, 0x40, 0x00, 0x00, 0x36, 0x02, 0xa0, 0x82, 0x20, 0x40, 0x04, 0x48, 0x01, 0x6e, 0x04, 0x4a, 0x80, 0x30, -0xd1, 0x60, 0x02, 0x23, 0x81, 0x6b, 0x19, 0x43, 0x81, 0x63, 0x70, 0x47, -0xe8, 0x0d, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, 0xf0, 0xb5, 0x84, 0xb0, -0x01, 0x20, 0x80, 0x02, 0x1c, 0x49, 0xc0, 0x46, -0x08, 0x60, 0x00, 0x27, 0x1b, 0x4e, 0x33, 0x23, 0x9b, 0x01, 0xf5, 0x18, -0x28, 0x6a, 0x00, 0x28, 0x1d, 0xd9, 0x19, 0x4c, 0x68, 0x46, 0x10, 0x21, -0x02, 0xf0, 0x96, 0xfb, 0x68, 0x46, 0x00, 0xf0, 0x33, 0xf8, 0x00, 0x28, -0x04, 0xd0, 0x15, 0x49, 0x48, 0x69, 0x01, 0x30, 0x48, 0x61, 0x0a, 0xe0, -0x13, 0x49, 0x60, 0x7b, 0x01, 0x30, 0x60, 0x73, 0x88, 0x79, 0x01, 0x30, -0x88, 0x71, 0x11, 0x48, 0x00, 0x68, 0x02, 0xf0, 0x6b, 0xf9, 0x28, 0x6a, -0x01, 0x37, 0xb8, 0x42, 0xe2, 0xd8, 0xbb, 0x23, 0x1b, 0x01, 0xf0, 0x18, -0x81, 0x7a, 0x00, 0x29, 0x03, 0xd0, 0x00, 0x21, 0x81, 0x72, 0xff, 0xf7, -0x1d, 0xfb, 0xff, 0xf7, 0xe3, 0xfe, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xe8, 0x0d, 0x00, 0x80, -0xb0, 0x82, 0x20, 0x40, 0x08, 0x83, 0x20, 0x40, 0xa0, 0x82, 0x20, 0x40, -0xd8, 0x03, 0x00, 0x80, 0x90, 0xb4, 0x17, 0x4f, 0x19, 0x23, 0xdb, 0x01, -0xf9, 0x18, 0x00, 0x22, 0x8b, 0x68, 0x00, 0x2b, 0x23, 0xd0, 0x01, 0x3b, -0x8b, 0x60, 0x33, 0x23, 0x9b, 0x01, 0xff, 0x18, 0x7b, 0x69, 0x1c, 0x6d, -0xc0, 0x46, 0x7c, 0x61, 0x04, 0x68, 0xc0, 0x46, 0x5c, 0x60, 0x44, 0x68, -0xc0, 0x46, 0x9c, 0x60, 0x84, 0x68, 0xc0, 0x46, 0x1c, 0x61, 0xc0, 0x68, -0xc0, 0x46, 0x58, 0x61, 0x1a, 0x65, 0xc8, 0x68, 0x42, 0x1c, 0xca, 0x60, -0x00, 0x28, 0x03, 0xd0, 0xf8, 0x69, 0xc0, 0x46, 0x03, 0x65, 0x00, 0xe0, -0xbb, 0x61, 0xfb, 0x61, 0x18, 0x1c, 0x90, 0xbc, 0x70, 0x47, 0x10, 0x1c, -0xfb, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x0a, 0x4a, 0x33, 0x23, -0x9b, 0x01, 0xd1, 0x18, 0x88, 0x69, 0x19, 0x23, 0xdb, 0x01, 0xd2, 0x18, -0xd3, 0x68, 0x00, 0x2b, 0x06, 0xd0, 0x01, 0x3b, 0xd3, 0x60, 0x8a, 0x69, -0x12, 0x6d, 0xc0, 0x46, 0x8a, 0x61, 0x70, 0x47, 0x00, 0x21, 0xd1, 0x60, -0xfb, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x06, 0x4a, 0xd1, 0x68, -0x4b, 0x1c, 0xd3, 0x60, 0x40, 0x32, 0x00, 0x29, 0x01, 0xd0, 0x91, 0x69, -0x00, 0xe0, 0x00, 0x21, 0x01, 0x65, 0x90, 0x61, 0x70, 0x47, 0x00, 0x00, -0x68, 0x1a, 0x00, 0x80, 0x06, 0x4a, 0x91, 0x68, 0x4b, 0x1c, 0x93, 0x60, -0x40, 0x32, 0x00, 0x29, 0x01, 0xd0, 0x51, 0x69, 0x00, 0xe0, 0x00, 0x21, -0x01, 0x65, 0x50, 0x61, 0x70, 0x47, 0x00, 0x00, 0x68, 0x1a, 0x00, 0x80, -0x90, 0xb4, 0x00, 0x21, 0x0f, 0x4a, 0x97, 0x89, 0x92, 0x6a, 0x4b, 0x00, -0x1b, 0x18, 0x9b, 0x8a, 0x00, 0x2b, 0x12, 0xd0, 0xbb, 0x42, 0x10, 0xdc, +0xd1, 0x60, 0x02, 0x23, 0xc1, 0x6b, 0x19, 0x43, 0xc1, 0x63, 0x70, 0x47, +0x68, 0x0e, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, 0xf0, 0xb5, 0x84, 0xb0, +0x01, 0x20, 0x80, 0x02, 0x1c, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x00, 0x27, +0x1b, 0x4e, 0x33, 0x23, 0x9b, 0x01, 0xf5, 0x18, 0x68, 0x6a, 0x00, 0x28, +0x1d, 0xd9, 0x19, 0x4c, 0x68, 0x46, 0x10, 0x21, 0x02, 0xf0, 0x90, 0xfb, +0x68, 0x46, 0x00, 0xf0, 0x33, 0xf8, 0x00, 0x28, 0x04, 0xd0, 0x15, 0x49, +0x48, 0x69, 0x01, 0x30, 0x48, 0x61, 0x0a, 0xe0, 0x13, 0x49, 0x60, 0x7b, +0x01, 0x30, 0x60, 0x73, 0x88, 0x79, 0x01, 0x30, 0x88, 0x71, 0x11, 0x48, +0x00, 0x68, 0x02, 0xf0, 0x65, 0xf9, 0x68, 0x6a, 0x01, 0x37, 0xb8, 0x42, +0xe2, 0xd8, 0xbb, 0x23, 0x1b, 0x01, 0xf0, 0x18, 0x81, 0x7b, 0x00, 0x29, +0x03, 0xd0, 0x00, 0x21, 0x81, 0x73, 0xff, 0xf7, 0x05, 0xfb, 0xff, 0xf7, +0xe3, 0xfe, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x00, 0x00, 0x00, 0xb0, 0x68, 0x0e, 0x00, 0x80, 0xb0, 0x82, 0x20, 0x40, +0x08, 0x83, 0x20, 0x40, 0xa0, 0x82, 0x20, 0x40, 0x58, 0x04, 0x00, 0x80, +0x90, 0xb4, 0x17, 0x4f, 0x19, 0x23, 0xdb, 0x01, 0xf9, 0x18, 0x00, 0x22, +0xcb, 0x68, 0x00, 0x2b, 0x23, 0xd0, 0x01, 0x3b, 0xcb, 0x60, 0x33, 0x23, +0x9b, 0x01, 0xff, 0x18, 0xbb, 0x69, 0x1c, 0x6d, 0xc0, 0x46, 0xbc, 0x61, +0x04, 0x68, 0xc0, 0x46, 0x5c, 0x60, 0x44, 0x68, 0xc0, 0x46, 0x9c, 0x60, +0x84, 0x68, 0xc0, 0x46, 0x1c, 0x61, 0xc0, 0x68, 0xc0, 0x46, 0x58, 0x61, +0x1a, 0x65, 0x08, 0x69, 0x42, 0x1c, 0x0a, 0x61, 0x00, 0x28, 0x03, 0xd0, +0x38, 0x6a, 0xc0, 0x46, 0x03, 0x65, 0x00, 0xe0, 0xfb, 0x61, 0x3b, 0x62, +0x18, 0x1c, 0x90, 0xbc, 0x70, 0x47, 0x10, 0x1c, 0xfb, 0xe7, 0x00, 0x00, +0x68, 0x0e, 0x00, 0x80, 0x0a, 0x4a, 0x33, 0x23, 0x9b, 0x01, 0xd1, 0x18, +0xc8, 0x69, 0x19, 0x23, 0xdb, 0x01, 0xd2, 0x18, 0x13, 0x69, 0x00, 0x2b, +0x06, 0xd0, 0x01, 0x3b, 0x13, 0x61, 0xca, 0x69, 0x12, 0x6d, 0xc0, 0x46, +0xca, 0x61, 0x70, 0x47, 0x00, 0x21, 0x11, 0x61, 0xfb, 0xe7, 0x00, 0x00, +0x68, 0x0e, 0x00, 0x80, 0x06, 0x4a, 0x11, 0x69, 0x4b, 0x1c, 0x13, 0x61, +0x40, 0x32, 0x00, 0x29, 0x01, 0xd0, 0xd1, 0x69, 0x00, 0xe0, 0x00, 0x21, +0x01, 0x65, 0xd0, 0x61, 0x70, 0x47, 0x00, 0x00, 0xe8, 0x1a, 0x00, 0x80, +0x06, 0x4a, 0xd1, 0x68, 0x4b, 0x1c, 0xd3, 0x60, 0x40, 0x32, 0x00, 0x29, +0x01, 0xd0, 0x91, 0x69, 0x00, 0xe0, 0x00, 0x21, 0x01, 0x65, 0x90, 0x61, +0x70, 0x47, 0x00, 0x00, 0xe8, 0x1a, 0x00, 0x80, 0x90, 0xb4, 0x00, 0x21, +0x0f, 0x4a, 0x97, 0x89, 0x92, 0x6a, 0x4b, 0x00, 0x1b, 0x18, 0x9b, 0x8a, +0x00, 0x2b, 0x12, 0xd0, 0xbb, 0x42, 0x10, 0xdc, 0x1c, 0x1c, 0x58, 0x23, 0x63, 0x43, 0xd3, 0x18, 0xdc, 0x1f, 0x49, 0x3c, 0x01, 0x23, 0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x1b, 0x06, 0x1b, 0x0e, 0x03, 0x2b, 0x02, 0xd0, 0x00, 0x20, 0x90, 0xbc, 0x70, 0x47, 0x01, 0x31, -0x04, 0x29, 0xe4, 0xd3, 0x01, 0x20, 0xf8, 0xe7, 0xc8, 0x29, 0x00, 0x80, +0x04, 0x29, 0xe4, 0xd3, 0x01, 0x20, 0xf8, 0xe7, 0x4c, 0x2a, 0x00, 0x80, 0xf7, 0xb5, 0x86, 0xb0, 0x3d, 0x4a, 0x07, 0x1c, 0xd1, 0x69, 0x8f, 0x40, 0x03, 0x1c, 0x14, 0x6a, 0xe3, 0x40, 0x5f, 0x40, 0x07, 0x9e, 0x8e, 0x40, 0x77, 0x40, 0xcf, 0x40, 0x94, 0x69, 0xc0, 0x46, 0x05, 0x94, 0x03, 0x1c, @@ -1062,85 +1075,85 @@ 0x5d, 0xd9, 0x1c, 0x1c, 0x32, 0x4e, 0x26, 0x43, 0x94, 0x69, 0xe6, 0x40, 0x33, 0x1c, 0x03, 0x96, 0x53, 0x6a, 0xc0, 0x46, 0x02, 0x93, 0xd2, 0x6a, 0xc0, 0x46, 0x01, 0x92, 0xbb, 0x00, 0x02, 0x9a, 0xd2, 0x58, 0x13, 0x1c, -0x05, 0x9c, 0xe3, 0x40, 0x03, 0x9c, 0xa3, 0x42, -0x3e, 0xd1, 0x8a, 0x40, 0xca, 0x40, 0x14, 0x1c, 0x63, 0x00, 0x1b, 0x19, -0x5b, 0x01, 0x01, 0x9a, 0xd2, 0x18, 0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, -0x01, 0x36, 0x33, 0x43, 0x1b, 0x68, 0x1b, 0x06, 0x1b, 0x0e, 0x03, 0x2b, -0x2c, 0xd1, 0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x51, 0x36, 0x33, 0x43, -0x1b, 0x68, 0x07, 0x9e, 0x1e, 0x40, 0x00, 0x96, 0x01, 0x23, 0x9b, 0x07, -0xd6, 0x1d, 0x49, 0x36, 0x33, 0x43, 0x1b, 0x68, 0x83, 0x42, 0x1b, 0xd1, -0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x4d, 0x36, 0x33, 0x43, 0x1b, 0x68, -0x00, 0x9e, 0xb3, 0x42, 0x12, 0xd1, 0x01, 0x23, 0x9b, 0x07, 0x1a, 0x43, -0x12, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x08, 0x9b, 0x32, 0x2b, 0x04, 0xd1, -0x02, 0x2a, 0x07, 0xd1, 0x20, 0x04, 0x00, 0x14, 0x0f, 0xe0, 0x08, 0x9b, -0x33, 0x2b, 0x01, 0xd1, 0x01, 0x2a, 0xf7, 0xd0, 0x04, 0x9a, 0x01, 0x37, -0x97, 0x42, 0x00, 0xd3, 0x00, 0x27, 0x04, 0x9a, 0x01, 0x35, 0xaa, 0x42, -0xae, 0xd8, 0x00, 0x20, 0xc0, 0x43, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0xc8, 0x29, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, -0xf0, 0xb5, 0x27, 0x4d, 0x68, 0x69, 0x00, 0x28, 0x06, 0xd0, 0x26, 0x48, -0x00, 0x68, 0x02, 0xf0, 0x31, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x23, 0x4c, 0x00, 0x26, 0xa0, 0x68, 0x23, 0x4f, 0x00, 0x28, 0x16, 0xd0, -0x0f, 0xe0, 0x28, 0x6a, 0x02, 0x28, 0x02, 0xd3, 0x01, 0x20, 0x38, 0x71, -0x0f, 0xe0, 0xa6, 0x60, 0xfd, 0xf7, 0x08, 0xff, 0x00, 0x28, 0xea, 0xd1, -0x28, 0x6a, 0x02, 0x28, 0x01, 0xd3, 0x01, 0x20, 0x38, 0x71, 0xe8, 0x68, -0x00, 0x28, 0x02, 0xd0, 0x38, 0x79, 0x00, 0x28, 0xe9, 0xd0, 0x68, 0x68, -0x00, 0x28, 0x1b, 0xd0, 0x01, 0x20, 0xa0, 0x60, 0xfe, 0xf7, 0xd2, 0xfb, -0x00, 0x28, 0xd6, 0xd1, 0x68, 0x68, 0x00, 0x28, 0xf6, 0xd1, 0x11, 0xe0, -0x00, 0x28, 0xd0, 0xd1, 0x28, 0x6a, 0x02, 0x28, 0x02, 0xd3, 0x01, 0x20, -0x38, 0x71, 0xca, 0xe7, 0xa6, 0x60, 0xfd, 0xf7, 0xe3, 0xfe, 0x00, 0x28, -0xc5, 0xd1, 0x28, 0x6a, 0x02, 0x28, 0x01, 0xd3, 0x01, 0x20, 0x38, 0x71, -0xe8, 0x68, 0x00, 0x28, 0xbd, 0xd0, 0x38, 0x79, 0x00, 0x28, 0xe7, 0xd0, -0xb9, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0xdc, 0x03, 0x00, 0x80, -0xc8, 0x29, 0x00, 0x80, 0x0c, 0x06, 0x00, 0x80, 0x70, 0x47, 0x00, 0x00, -0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, 0x90, 0xb5, 0x40, 0x20, -0x1d, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x01, 0xf0, 0x9f, 0xfc, 0x03, 0x23, +0x05, 0x9c, 0xe3, 0x40, 0x03, 0x9c, 0xa3, 0x42, 0x3e, 0xd1, 0x8a, 0x40, +0xca, 0x40, 0x14, 0x1c, 0x63, 0x00, 0x1b, 0x19, 0x5b, 0x01, 0x01, 0x9a, +0xd2, 0x18, 0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x01, 0x36, 0x33, 0x43, +0x1b, 0x68, 0x1b, 0x06, 0x1b, 0x0e, 0x03, 0x2b, 0x2c, 0xd1, 0x01, 0x23, +0x9b, 0x07, 0xd6, 0x1d, 0x51, 0x36, 0x33, 0x43, 0x1b, 0x68, 0x07, 0x9e, +0x1e, 0x40, 0x00, 0x96, 0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x49, 0x36, +0x33, 0x43, 0x1b, 0x68, 0x83, 0x42, 0x1b, 0xd1, 0x01, 0x23, 0x9b, 0x07, +0xd6, 0x1d, 0x4d, 0x36, 0x33, 0x43, 0x1b, 0x68, 0x00, 0x9e, 0xb3, 0x42, +0x12, 0xd1, 0x01, 0x23, 0x9b, 0x07, 0x1a, 0x43, 0x12, 0x68, 0x12, 0x04, +0x12, 0x0c, 0x08, 0x9b, 0x32, 0x2b, 0x04, 0xd1, 0x02, 0x2a, 0x07, 0xd1, +0x20, 0x04, 0x00, 0x14, 0x0f, 0xe0, 0x08, 0x9b, 0x33, 0x2b, 0x01, 0xd1, +0x01, 0x2a, 0xf7, 0xd0, 0x04, 0x9a, 0x01, 0x37, 0x97, 0x42, 0x00, 0xd3, +0x00, 0x27, 0x04, 0x9a, 0x01, 0x35, 0xaa, 0x42, 0xae, 0xd8, 0x00, 0x20, +0xc0, 0x43, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x4c, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0xf0, 0xb5, 0x27, 0x4d, +0x68, 0x69, 0x00, 0x28, 0x06, 0xd0, 0x26, 0x48, 0x00, 0x68, 0x02, 0xf0, +0x2b, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x23, 0x4c, 0x00, 0x26, +0xa0, 0x68, 0x23, 0x4f, 0x00, 0x28, 0x16, 0xd0, 0x0f, 0xe0, 0x28, 0x6a, +0x02, 0x28, 0x02, 0xd3, 0x01, 0x20, 0x38, 0x71, 0x0f, 0xe0, 0xa6, 0x60, +0xfd, 0xf7, 0xe8, 0xfe, 0x00, 0x28, 0xea, 0xd1, 0x28, 0x6a, 0x02, 0x28, +0x01, 0xd3, 0x01, 0x20, 0x38, 0x71, 0xe8, 0x68, 0x00, 0x28, 0x02, 0xd0, +0x38, 0x79, 0x00, 0x28, 0xe9, 0xd0, 0x68, 0x68, 0x00, 0x28, 0x1b, 0xd0, +0x01, 0x20, 0xa0, 0x60, 0xfe, 0xf7, 0xbc, 0xfb, 0x00, 0x28, 0xd6, 0xd1, +0x68, 0x68, 0x00, 0x28, 0xf6, 0xd1, 0x11, 0xe0, 0x00, 0x28, 0xd0, 0xd1, +0x28, 0x6a, 0x02, 0x28, 0x02, 0xd3, 0x01, 0x20, 0x38, 0x71, 0xca, 0xe7, +0xa6, 0x60, 0xfd, 0xf7, 0xc3, 0xfe, 0x00, 0x28, 0xc5, 0xd1, 0x28, 0x6a, +0x02, 0x28, 0x01, 0xd3, 0x01, 0x20, 0x38, 0x71, 0xe8, 0x68, 0x00, 0x28, +0xbd, 0xd0, 0x38, 0x79, 0x00, 0x28, 0xe7, 0xd0, 0xb9, 0xe7, 0x00, 0x00, +0x6c, 0x06, 0x00, 0x80, 0x5c, 0x04, 0x00, 0x80, 0x4c, 0x2a, 0x00, 0x80, +0x8c, 0x06, 0x00, 0x80, 0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, +0x70, 0x47, 0x00, 0x00, 0x90, 0xb5, 0x40, 0x20, 0x1d, 0x49, 0xc0, 0x46, +0x08, 0x60, 0x01, 0xf0, 0x9d, 0xfc, 0x03, 0x23, 0x1b, 0x07, 0x41, 0x68, 0x19, 0x40, 0x0c, 0x0f, 0x61, 0x01, 0x09, 0x1b, 0x89, 0x00, 0x18, 0x4a, 0x8f, 0x18, 0x01, 0x21, 0x39, 0x80, 0x81, 0x6a, 0xc0, 0x46, 0x79, 0x65, 0x41, 0x6a, 0xc0, 0x46, 0x79, 0x67, 0xb9, 0x6c, 0xfa, 0x6c, 0x89, 0x18, 0xb9, 0x64, 0x00, 0x21, 0xf9, 0x64, 0xba, 0x6b, 0x3b, 0x6d, 0xd2, 0x18, 0xba, 0x63, 0x39, 0x65, 0x42, 0x6a, 0x20, 0x32, 0x51, 0x71, 0x79, 0x6d, 0x7a, 0x6f, 0xd2, 0x6d, 0xc0, 0x46, 0x11, 0x60, -0xfd, 0xf7, 0x10, 0xf8, 0x20, 0x01, 0x09, 0x49, 0x40, 0x18, 0x19, 0x23, +0xfc, 0xf7, 0xd4, 0xff, 0x20, 0x01, 0x09, 0x49, 0x40, 0x18, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x41, 0x6b, 0x01, 0x39, 0x41, 0x63, 0x78, 0x6f, -0x01, 0xf0, 0xc8, 0xfb, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, -0x00, 0x00, 0x00, 0xb0, 0xc8, 0x2a, 0x00, 0x80, 0x1c, 0x1c, 0x00, 0x80, +0x01, 0xf0, 0xc6, 0xfb, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x00, 0x00, 0x00, 0xb0, 0x5c, 0x2b, 0x00, 0x80, 0xa0, 0x1c, 0x00, 0x80, 0xf0, 0xb5, 0x40, 0x20, 0x12, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x01, 0xf0, -0x5b, 0xfc, 0x07, 0x1c, 0x40, 0x68, 0x03, 0x23, -0x1b, 0x07, 0x18, 0x40, 0x06, 0x0f, 0x70, 0x01, 0x80, 0x1b, 0x80, 0x00, -0x0c, 0x49, 0x44, 0x18, 0xb8, 0x6a, 0xc0, 0x46, 0x60, 0x65, 0x78, 0x6a, -0xc0, 0x46, 0x60, 0x67, 0x80, 0x6f, 0x05, 0x1d, 0xe5, 0x63, 0xb9, 0x69, -0x28, 0x1c, 0x02, 0xf0, 0x8f, 0xf9, 0x38, 0x1c, 0x21, 0x1c, 0x32, 0x1c, -0x2b, 0x1c, 0x00, 0xf0, 0x20, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x00, 0x00, 0x00, 0xb0, 0xc8, 0x2a, 0x00, 0x80, 0xf0, 0xb5, 0x4b, 0x6f, -0x9b, 0x6f, 0x1f, 0x1d, 0xcf, 0x63, 0x05, 0x68, 0x00, 0x23, 0x84, 0x69, -0xa4, 0x08, 0x08, 0xd0, 0x9c, 0x00, 0x2e, 0x59, 0xc0, 0x46, 0x3e, 0x51, -0x84, 0x69, 0xa4, 0x08, 0x01, 0x33, 0x9c, 0x42, 0xf6, 0xd8, 0x3b, 0x1c, -0x00, 0xf0, 0x03, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0xb5, -0x81, 0xb0, 0x04, 0x1c, 0x1d, 0x1c, 0x0f, 0x1c, 0x46, 0x48, 0x01, 0x69, -0x01, 0x31, 0x01, 0x61, 0xf9, 0x1d, 0x51, 0x31, 0xbd, 0x65, 0x00, 0x91, -0x20, 0x1c, 0xfd, 0xf7, 0xa3, 0xfc, 0xf8, 0x6d, 0x40, 0x09, 0x36, 0xd2, -0xb8, 0x6d, 0x06, 0x7b, 0x43, 0x7b, 0x1b, 0x02, 0x1e, 0x43, 0x17, 0x21, -0x49, 0x02, 0x01, 0x73, 0x0b, 0x0a, 0x43, 0x73, 0x00, 0x99, 0x20, 0x1c, -0xfd, 0xf7, 0x92, 0xfc, 0xb8, 0x6d, 0xc0, 0x46, 0x06, 0x73, 0x33, 0x0a, -0x43, 0x73, 0xf8, 0x6d, 0x40, 0x09, 0x20, 0xd2, 0x60, 0x68, 0x01, 0x04, -0x09, 0x0c, 0x03, 0x98, 0x01, 0xf0, 0xce, 0xfc, 0x60, 0x68, 0x32, 0x4b, -0x18, 0x43, 0x60, 0x60, 0x20, 0x1c, 0x01, 0xf0, 0x37, 0xfd, 0x00, 0x25, -0x7d, 0x60, 0xbd, 0x60, 0x3d, 0x64, 0x7d, 0x64, 0x20, 0x1c, 0xfc, 0xf7, -0x77, 0xff, 0x38, 0x88, 0x40, 0x23, 0x18, 0x43, 0x38, 0x80, 0x7d, 0x62, -0x29, 0x48, 0xc0, 0x46, 0xb8, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0xa0, 0xfb, -0x44, 0xe0, 0x20, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x38, 0x18, 0x43, -0x00, 0x68, 0xc0, 0x46, 0x78, 0x64, 0x60, 0x68, 0x02, 0x04, 0x12, 0x0c, -0x78, 0x6e, 0x01, 0x26, 0xc1, 0x1d, 0x0d, 0x31, 0x8a, 0x42, 0x02, 0xd2, -0x3a, 0x64, 0x08, 0x1c, 0x0e, 0xe0, 0x41, 0x19, 0x89, 0x89, 0xf0, 0x23, -0x19, 0x40, 0x09, 0x09, 0x89, 0x00, 0x40, 0x18, 0xf8, 0x60, 0xf9, 0x61, -0x61, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x81, 0x42, 0x16, 0xd2, 0x39, 0x64, -0x63, 0x68, 0x19, 0x04, 0x09, 0x0c, 0x40, 0x1a, 0x03, 0x30, 0x80, 0x08, -0x82, 0x00, 0xa0, 0x61, 0x20, 0x68, 0x09, 0x18, 0x9b, 0x18, 0x63, 0x60, -0xc3, 0x1f, 0x05, 0x3b, 0x38, 0x1c, 0x00, 0xf0, 0xb6, 0xfa, 0x7e, 0x80, +0x59, 0xfc, 0x07, 0x1c, 0x40, 0x68, 0x03, 0x23, 0x1b, 0x07, 0x18, 0x40, +0x06, 0x0f, 0x70, 0x01, 0x80, 0x1b, 0x80, 0x00, 0x0c, 0x49, 0x44, 0x18, +0xb8, 0x6a, 0xc0, 0x46, 0x60, 0x65, 0x78, 0x6a, 0xc0, 0x46, 0x60, 0x67, +0x80, 0x6f, 0x05, 0x1d, 0xe5, 0x63, 0xb9, 0x69, 0x28, 0x1c, 0x02, 0xf0, +0x89, 0xf9, 0x38, 0x1c, 0x21, 0x1c, 0x32, 0x1c, 0x2b, 0x1c, 0x00, 0xf0, +0x20, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, +0x5c, 0x2b, 0x00, 0x80, 0xf0, 0xb5, 0x4b, 0x6f, 0x9b, 0x6f, 0x1f, 0x1d, +0xcf, 0x63, 0x05, 0x68, 0x00, 0x23, 0x84, 0x69, 0xa4, 0x08, 0x08, 0xd0, +0x9c, 0x00, 0x2e, 0x59, 0xc0, 0x46, 0x3e, 0x51, 0x84, 0x69, 0xa4, 0x08, +0x01, 0x33, 0x9c, 0x42, 0xf6, 0xd8, 0x3b, 0x1c, 0x00, 0xf0, 0x03, 0xf8, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0xb5, 0x81, 0xb0, 0x04, 0x1c, +0x1d, 0x1c, 0x0f, 0x1c, 0x46, 0x48, 0x01, 0x69, 0x01, 0x31, 0x01, 0x61, +0xf9, 0x1d, 0x51, 0x31, 0xbd, 0x65, 0x00, 0x91, 0x20, 0x1c, 0xfd, 0xf7, +0x67, 0xfc, 0xf8, 0x6d, 0x40, 0x09, 0x36, 0xd2, 0xb8, 0x6d, 0x06, 0x7b, +0x43, 0x7b, 0x1b, 0x02, 0x1e, 0x43, 0x17, 0x21, 0x49, 0x02, 0x01, 0x73, +0x0b, 0x0a, 0x43, 0x73, 0x00, 0x99, 0x20, 0x1c, 0xfd, 0xf7, 0x56, 0xfc, +0xb8, 0x6d, 0xc0, 0x46, 0x06, 0x73, 0x33, 0x0a, 0x43, 0x73, 0xf8, 0x6d, +0x40, 0x09, 0x20, 0xd2, 0x60, 0x68, 0x01, 0x04, 0x09, 0x0c, 0x03, 0x98, +0x01, 0xf0, 0xcc, 0xfc, 0x60, 0x68, 0x32, 0x4b, 0x18, 0x43, 0x60, 0x60, +0x20, 0x1c, 0x01, 0xf0, 0x35, 0xfd, 0x00, 0x25, 0x7d, 0x60, 0xbd, 0x60, +0x3d, 0x64, 0x7d, 0x64, 0x20, 0x1c, 0xfc, 0xf7, 0x3b, 0xff, 0x38, 0x88, +0x40, 0x23, 0x18, 0x43, 0x38, 0x80, 0x7d, 0x62, 0x29, 0x48, 0xc0, 0x46, +0xb8, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0xa0, 0xfb, 0x44, 0xe0, 0x20, 0x68, +0x01, 0x23, 0x9b, 0x07, 0x08, 0x38, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, +0x78, 0x64, 0x60, 0x68, 0x02, 0x04, 0x12, 0x0c, 0x78, 0x6e, 0x01, 0x26, +0xc1, 0x1d, 0x0d, 0x31, 0x8a, 0x42, 0x02, 0xd2, 0x3a, 0x64, 0x08, 0x1c, +0x0e, 0xe0, 0x41, 0x19, 0x89, 0x89, 0xf0, 0x23, 0x19, 0x40, 0x09, 0x09, +0x89, 0x00, 0x40, 0x18, 0xf8, 0x60, 0xf9, 0x61, 0x61, 0x68, 0x09, 0x04, +0x09, 0x0c, 0x81, 0x42, 0x16, 0xd2, 0x39, 0x64, 0x63, 0x68, 0x19, 0x04, +0x09, 0x0c, 0x40, 0x1a, 0x03, 0x30, 0x80, 0x08, 0x82, 0x00, 0xa0, 0x61, +0x20, 0x68, 0x09, 0x18, 0x9b, 0x18, 0x63, 0x60, 0xc3, 0x1f, 0x05, 0x3b, +0x38, 0x1c, 0x00, 0xf0, 0xb6, 0xfa, 0x7e, 0x80, 0x20, 0x1c, 0x00, 0xf0, 0xbf, 0xfb, 0x0b, 0xe0, 0xb9, 0x68, 0x08, 0x1a, 0x00, 0x25, 0x78, 0x62, 0xbd, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0x3c, 0xfc, 0x20, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x64, 0xf8, 0x05, 0xb0, 0xf0, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, +0x08, 0xbc, 0x18, 0x47, 0x0c, 0x2b, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xc0, 0xf0, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0x38, 0x6c, 0xf9, 0x6b, 0x0d, 0x18, 0x21, 0x68, 0x41, 0x18, 0x00, 0x20, 0xa2, 0x69, 0x00, 0x2a, 0x0b, 0xd9, 0x82, 0x00, 0x56, 0x18, 0x01, 0x23, 0x9b, 0x07, @@ -1148,127 +1161,127 @@ 0x82, 0x42, 0xf3, 0xd8, 0x78, 0x6e, 0xf9, 0x6b, 0x09, 0x18, 0x89, 0x89, 0xf0, 0x23, 0x19, 0x40, 0x09, 0x09, 0x89, 0x00, 0x40, 0x18, 0xf8, 0x60, 0xf9, 0x61, 0x20, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x38, 0x18, 0x43, -0x01, 0x68, 0x78, 0x6c, 0xfc, 0xf7, 0xdb, 0xff, -0x78, 0x64, 0x60, 0x68, 0x01, 0x04, 0x09, 0x0c, 0xf8, 0x68, 0x81, 0x42, -0x19, 0xd2, 0x39, 0x64, 0x63, 0x68, 0x19, 0x04, 0x09, 0x0c, 0x40, 0x1a, -0x03, 0x30, 0x80, 0x08, 0x82, 0x00, 0xa0, 0x61, 0x20, 0x68, 0x09, 0x18, -0x9b, 0x18, 0x63, 0x60, 0xc3, 0x1f, 0x05, 0x3b, 0x38, 0x1c, 0x00, 0xf0, -0x56, 0xfa, 0x01, 0x20, 0x78, 0x80, 0x20, 0x1c, 0x00, 0xf0, 0x5e, 0xfb, -0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb9, 0x68, 0x08, 0x1a, 0x78, 0x62, -0x00, 0x20, 0xb8, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0xd9, 0xfb, 0x20, 0x1c, -0x39, 0x1c, 0x00, 0xf0, 0x01, 0xf8, 0xef, 0xe7, 0xf0, 0xb5, 0x84, 0xb0, -0x04, 0x1c, 0x0f, 0x1c, 0x8e, 0x48, 0x41, 0x69, 0x01, 0x31, 0x41, 0x61, -0x03, 0x20, 0x00, 0x07, 0x61, 0x68, 0x08, 0x40, 0x06, 0x0f, 0x0a, 0x04, -0x12, 0x0c, 0x20, 0x68, 0x11, 0x18, 0xfb, 0x68, 0xd2, 0x1a, 0x7b, 0x68, -0x9d, 0x1a, 0xc3, 0x1f, 0x05, 0x3b, 0x38, 0x1c, 0x2a, 0x1c, 0x00, 0xf0, -0x26, 0xfa, 0x00, 0x20, 0x78, 0x80, 0x20, 0x1c, 0x00, 0xf0, 0x2e, 0xfb, -0x60, 0x68, 0x40, 0x19, 0x01, 0x04, 0x09, 0x0c, 0x60, 0x60, 0x30, 0x1c, -0x01, 0xf0, 0xe2, 0xfb, 0x7d, 0x4e, 0x0b, 0x23, 0x1b, 0x02, 0xf0, 0x18, -0xc0, 0x68, 0x00, 0x28, 0x19, 0xd0, 0x00, 0x25, 0x2d, 0x23, 0x9b, 0x01, -0xf0, 0x18, 0x80, 0x68, 0x00, 0x28, 0x12, 0xd0, 0xaa, 0x00, 0x92, 0x19, -0x2d, 0x23, 0x9b, 0x01, 0xd2, 0x18, 0x92, 0x68, 0x20, 0x1c, 0x39, 0x1c, -0x01, 0xf0, 0x22, 0xfe, 0x01, 0x35, 0xa8, 0x00, 0x80, 0x19, 0x2d, 0x23, -0x9b, 0x01, 0xc0, 0x18, 0x80, 0x68, 0x00, 0x28, 0xec, 0xd1, 0xf8, 0x6b, -0x01, 0x1f, 0x8a, 0x1c, 0xfa, 0x63, 0xfa, 0x68, 0x7d, 0x6c, 0x00, 0xf0, -0xbb, 0xf9, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x28, 0x1c, 0xfc, 0xf7, -0x56, 0xff, 0x03, 0x90, 0xf9, 0x6b, 0x3a, 0x6e, 0x8e, 0x18, 0x20, 0x68, -0x12, 0x18, 0x01, 0x92, 0x7a, 0x6e, 0x8d, 0x18, 0x11, 0x18, 0x02, 0x91, -0xc8, 0x1d, 0x09, 0x30, 0xe0, 0x60, 0xb1, 0x88, 0x08, 0x02, 0x09, 0x0a, -0x09, 0x06, 0x09, 0x0e, 0x08, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x78, 0x61, -0x68, 0x68, 0x01, 0x0e, 0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, -0x11, 0x43, 0xff, 0x22, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x11, 0x43, -0x00, 0x06, 0x08, 0x43, 0x38, 0x61, 0xa8, 0x89, 0x09, 0x23, 0x1b, 0x02, -0x18, 0x40, 0xb8, 0x61, 0xa8, 0x89, 0x98, 0x43, 0xa8, 0x81, 0xa8, 0x89, -0x02, 0x99, 0xc0, 0x46, 0x88, 0x81, 0x00, 0x20, 0x70, 0x80, 0xb0, 0x80, +0x01, 0x68, 0x78, 0x6c, 0xfc, 0xf7, 0x9f, 0xff, 0x78, 0x64, 0x60, 0x68, +0x01, 0x04, 0x09, 0x0c, 0xf8, 0x68, 0x81, 0x42, 0x19, 0xd2, 0x39, 0x64, +0x63, 0x68, 0x19, 0x04, 0x09, 0x0c, 0x40, 0x1a, 0x03, 0x30, 0x80, 0x08, +0x82, 0x00, 0xa0, 0x61, 0x20, 0x68, 0x09, 0x18, 0x9b, 0x18, 0x63, 0x60, +0xc3, 0x1f, 0x05, 0x3b, 0x38, 0x1c, 0x00, 0xf0, 0x56, 0xfa, 0x01, 0x20, +0x78, 0x80, 0x20, 0x1c, 0x00, 0xf0, 0x5e, 0xfb, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0xb9, 0x68, 0x08, 0x1a, 0x78, 0x62, 0x00, 0x20, 0xb8, 0x62, +0x38, 0x1c, 0x00, 0xf0, 0xd9, 0xfb, 0x20, 0x1c, 0x39, 0x1c, 0x00, 0xf0, +0x01, 0xf8, 0xef, 0xe7, 0xf0, 0xb5, 0x84, 0xb0, 0x04, 0x1c, 0x0f, 0x1c, +0x8e, 0x48, 0x41, 0x69, 0x01, 0x31, 0x41, 0x61, 0x03, 0x20, 0x00, 0x07, +0x61, 0x68, 0x08, 0x40, 0x06, 0x0f, 0x0a, 0x04, 0x12, 0x0c, 0x20, 0x68, +0x11, 0x18, 0xfb, 0x68, 0xd2, 0x1a, 0x7b, 0x68, 0x9d, 0x1a, 0xc3, 0x1f, +0x05, 0x3b, 0x38, 0x1c, 0x2a, 0x1c, 0x00, 0xf0, 0x26, 0xfa, 0x00, 0x20, +0x78, 0x80, 0x20, 0x1c, 0x00, 0xf0, 0x2e, 0xfb, 0x60, 0x68, 0x40, 0x19, +0x01, 0x04, 0x09, 0x0c, 0x60, 0x60, 0x30, 0x1c, 0x01, 0xf0, 0xe0, 0xfb, +0x7d, 0x4e, 0x0b, 0x23, 0x1b, 0x02, 0xf0, 0x18, 0x00, 0x69, 0x00, 0x28, +0x19, 0xd0, 0x00, 0x25, 0x2d, 0x23, 0x9b, 0x01, 0xf0, 0x18, 0xc0, 0x68, +0x00, 0x28, 0x12, 0xd0, 0xaa, 0x00, 0x92, 0x19, 0x2d, 0x23, 0x9b, 0x01, +0xd2, 0x18, 0xd2, 0x68, 0x20, 0x1c, 0x39, 0x1c, 0x01, 0xf0, 0x1c, 0xfe, +0x01, 0x35, 0xa8, 0x00, 0x80, 0x19, 0x2d, 0x23, 0x9b, 0x01, 0xc0, 0x18, +0xc0, 0x68, 0x00, 0x28, 0xec, 0xd1, 0xf8, 0x6b, 0x01, 0x1f, 0x8a, 0x1c, +0xfa, 0x63, 0xfa, 0x68, 0x7d, 0x6c, 0x00, 0xf0, 0xbb, 0xf9, 0xc0, 0x43, +0x01, 0x04, 0x09, 0x0c, 0x28, 0x1c, 0xfc, 0xf7, 0x1a, 0xff, 0x03, 0x90, +0xf9, 0x6b, 0x3a, 0x6e, 0x8e, 0x18, 0x20, 0x68, 0x12, 0x18, 0x01, 0x92, +0x7a, 0x6e, 0x8d, 0x18, 0x11, 0x18, 0x02, 0x91, 0xc8, 0x1d, 0x09, 0x30, +0xe0, 0x60, 0xb1, 0x88, 0x08, 0x02, 0x09, 0x0a, 0x09, 0x06, 0x09, 0x0e, +0x08, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x78, 0x61, 0x68, 0x68, 0x01, 0x0e, +0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, 0xff, 0x22, +0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06, 0x08, 0x43, +0x38, 0x61, 0xa8, 0x89, 0x09, 0x23, 0x1b, 0x02, 0x18, 0x40, 0xb8, 0x61, +0xa8, 0x89, 0x98, 0x43, 0xa8, 0x81, 0xa8, 0x89, 0x02, 0x99, 0xc0, 0x46, +0x88, 0x81, 0x00, 0x20, 0x70, 0x80, 0xb0, 0x80, 0x70, 0x81, 0x68, 0x60, 0x28, 0x82, 0xb9, 0x6e, 0x30, 0x1c, 0xfc, 0xf7, -0x2e, 0xff, 0x38, 0x86, 0xfa, 0x69, 0x30, 0x1c, 0x29, 0x1c, 0xfc, 0xf7, -0x49, 0xff, 0x78, 0x86, 0x3d, 0x8e, 0x78, 0x8e, 0x03, 0x99, 0xfc, 0xf7, -0x0e, 0xff, 0x00, 0x90, 0x60, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x39, 0x6e, +0xf2, 0xfe, 0x38, 0x86, 0xfa, 0x69, 0x30, 0x1c, 0x29, 0x1c, 0xfc, 0xf7, +0x0d, 0xff, 0x78, 0x86, 0x3d, 0x8e, 0x78, 0x8e, 0x03, 0x99, 0xfc, 0xf7, +0xd2, 0xfe, 0x00, 0x90, 0x60, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x39, 0x6e, 0x41, 0x1a, 0x09, 0x04, 0x09, 0x0c, 0x7a, 0x6e, 0x82, 0x1a, 0x13, 0x04, 0x1b, 0x0c, 0x1a, 0x02, 0x1b, 0x0a, 0x1a, 0x43, 0x16, 0x04, 0x36, 0x0c, 0xba, 0x68, 0x82, 0x42, 0x01, 0xd2, 0x00, 0x20, 0x00, 0xe0, 0x10, 0x1a, 0xb8, 0x60, 0x08, 0x02, 0x09, 0x12, 0x09, 0x06, 0x09, 0x0e, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x01, 0x98, 0xc0, 0x46, 0x41, 0x80, 0x28, 0x1c, -0xfc, 0xf7, 0xe9, 0xfe, 0x05, 0x1c, 0x00, 0x98, 0x31, 0x1c, 0xfc, 0xf7, -0xe4, 0xfe, 0x06, 0x1c, 0x78, 0x69, 0x00, 0x04, 0x00, 0x0c, 0x01, 0x02, -0x00, 0x0a, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, -0x01, 0x98, 0xc0, 0x46, 0x81, 0x80, 0x28, 0x1c, 0xfc, 0xf7, 0xd5, 0xfe, -0x79, 0x69, 0x01, 0x31, 0xc0, 0x43, 0x79, 0x61, 0x01, 0x9a, 0xc0, 0x46, -0x50, 0x81, 0x38, 0x69, 0x01, 0x0e, 0xff, 0x22, 0x12, 0x04, 0x02, 0x40, -0x12, 0x0a, 0x11, 0x43, 0xff, 0x22, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, -0x11, 0x43, 0x00, 0x06, 0x01, 0x43, 0x30, 0x1c, 0xfc, 0xf7, 0xbd, 0xfe, -0x39, 0x69, 0x7a, 0x68, 0x89, 0x18, 0x39, 0x61, 0xb9, 0x68, 0x00, 0x29, -0x09, 0xd1, 0x02, 0x99, 0x89, 0x89, 0xba, 0x69, 0x11, 0x43, 0x02, 0x9a, -0xc0, 0x46, 0x91, 0x81, 0xb9, 0x69, 0xfc, 0xf7, 0xac, 0xfe, 0x20, 0x82, -0x00, 0x20, 0x60, 0x82, 0xf8, 0x6d, 0x41, 0x08, 0x16, 0xd3, 0x80, 0x0a, -0x0a, 0xd3, 0x60, 0x68, 0x10, 0x38, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, -0x09, 0x0a, 0x08, 0x43, 0x21, 0x68, 0xc0, 0x46, 0x08, 0x82, 0x09, 0xe0, -0x60, 0x68, 0x0c, 0x38, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, -0x08, 0x43, 0x21, 0x68, 0xc0, 0x46, 0x88, 0x81, 0x04, 0xb0, 0xf0, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, -0xf1, 0xb5, 0x84, 0xb0, 0x6e, 0x4d, 0x28, 0x69, 0x01, 0x22, 0x04, 0x99, -0x8a, 0x40, 0x90, 0x43, 0x28, 0x61, 0x04, 0x98, 0x43, 0x01, 0x18, 0x1a, -0x80, 0x00, 0x16, 0x1c, 0x69, 0x49, 0x44, 0x18, 0xe0, 0x6b, 0xc0, 0x46, -0x00, 0x90, 0xa0, 0x68, 0x00, 0x28, 0x01, 0xd1, 0x00, 0x26, 0x26, 0xe0, -0x65, 0x48, 0x41, 0x69, 0x01, 0x31, 0x41, 0x61, 0x04, 0x98, 0xfc, 0xf7, -0x4f, 0xfd, 0x07, 0x1c, 0x03, 0xd1, 0x28, 0x69, 0x30, 0x43, 0x28, 0x61, -0xb5, 0xe0, 0xa0, 0x68, 0x65, 0x68, 0xa8, 0x42, 0x00, 0xd2, 0x05, 0x1c, -0xa1, 0x6c, 0xa9, 0x42, 0x16, 0xd2, 0x40, 0x1a, 0x62, 0x6a, 0x10, 0x1a, -0x00, 0x26, 0x60, 0x62, 0xa6, 0x60, 0xa6, 0x62, 0x20, 0x88, 0x48, 0x23, -0x18, 0x43, 0x20, 0x80, 0x0d, 0x1c, 0x09, 0xd1, 0x38, 0x1c, 0xfc, 0xf7, -0x5f, 0xfd, 0x03, 0x20, 0x60, 0x80, 0x66, 0x60, 0x20, 0x1c, 0x00, 0xf0, -0x8d, 0xf9, 0x96, 0xe0, 0xe1, 0x68, 0x38, 0x68, 0x09, 0x18, 0xc3, 0x1f, -0x05, 0x3b, 0x20, 0x1c, 0x02, 0x39, 0x2a, 0x1c, 0x00, 0xf0, 0xcd, 0xf8, -0x38, 0x1c, 0x00, 0xf0, 0xd7, 0xf9, 0xe0, 0x68, 0x46, 0x19, 0x78, 0x68, -0x30, 0x43, 0x78, 0x60, 0x04, 0x98, 0x31, 0x1c, 0x01, 0xf0, 0x8a, 0xfa, -0x21, 0x6e, 0x00, 0x98, 0x08, 0x18, 0x01, 0x90, 0x70, 0x1a, 0x00, 0x04, -0x00, 0x0c, 0x61, 0x6e, 0x71, 0x1a, 0x0a, 0x04, 0x12, 0x0c, 0x11, 0x02, +0xfc, 0xf7, 0xad, 0xfe, 0x05, 0x1c, 0x00, 0x98, 0x31, 0x1c, 0xfc, 0xf7, +0xa8, 0xfe, 0x06, 0x1c, 0x78, 0x69, 0x00, 0x04, 0x00, 0x0c, 0x01, 0x02, +0x00, 0x0a, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x01, 0x98, 0xc0, 0x46, +0x81, 0x80, 0x28, 0x1c, 0xfc, 0xf7, 0x99, 0xfe, 0x79, 0x69, 0x01, 0x31, +0xc0, 0x43, 0x79, 0x61, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x81, 0x38, 0x69, +0x01, 0x0e, 0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, +0xff, 0x22, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06, +0x01, 0x43, 0x30, 0x1c, 0xfc, 0xf7, 0x81, 0xfe, 0x39, 0x69, 0x7a, 0x68, +0x89, 0x18, 0x39, 0x61, 0xb9, 0x68, 0x00, 0x29, 0x09, 0xd1, 0x02, 0x99, +0x89, 0x89, 0xba, 0x69, 0x11, 0x43, 0x02, 0x9a, 0xc0, 0x46, 0x91, 0x81, +0xb9, 0x69, 0xfc, 0xf7, 0x70, 0xfe, 0x20, 0x82, 0x00, 0x20, 0x60, 0x82, +0xf8, 0x6d, 0x41, 0x08, 0x16, 0xd3, 0x80, 0x0a, 0x0a, 0xd3, 0x60, 0x68, +0x10, 0x38, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, +0x21, 0x68, 0xc0, 0x46, 0x08, 0x82, 0x09, 0xe0, 0x60, 0x68, 0x0c, 0x38, +0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x21, 0x68, +0xc0, 0x46, 0x88, 0x81, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x0c, 0x2b, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80, 0xf1, 0xb5, 0x84, 0xb0, +0x6e, 0x4d, 0x28, 0x69, 0x01, 0x22, 0x04, 0x99, 0x8a, 0x40, 0x90, 0x43, +0x28, 0x61, 0x04, 0x98, 0x43, 0x01, 0x18, 0x1a, 0x80, 0x00, 0x16, 0x1c, +0x69, 0x49, 0x44, 0x18, 0xe0, 0x6b, 0xc0, 0x46, 0x00, 0x90, 0xa0, 0x68, +0x00, 0x28, 0x01, 0xd1, 0x00, 0x26, 0x26, 0xe0, 0x65, 0x48, 0x41, 0x69, +0x01, 0x31, 0x41, 0x61, 0x04, 0x98, 0xfc, 0xf7, 0x13, 0xfd, 0x07, 0x1c, +0x03, 0xd1, 0x28, 0x69, 0x30, 0x43, 0x28, 0x61, 0xb5, 0xe0, 0xa0, 0x68, +0x65, 0x68, 0xa8, 0x42, 0x00, 0xd2, 0x05, 0x1c, 0xa1, 0x6c, 0xa9, 0x42, +0x16, 0xd2, 0x40, 0x1a, 0x62, 0x6a, 0x10, 0x1a, 0x00, 0x26, 0x60, 0x62, +0xa6, 0x60, 0xa6, 0x62, 0x20, 0x88, 0x48, 0x23, 0x18, 0x43, 0x20, 0x80, +0x0d, 0x1c, 0x09, 0xd1, 0x38, 0x1c, 0xfc, 0xf7, 0x23, 0xfd, 0x03, 0x20, +0x60, 0x80, 0x66, 0x60, 0x20, 0x1c, 0x00, 0xf0, 0x8d, 0xf9, 0x96, 0xe0, +0xe1, 0x68, 0x38, 0x68, 0x09, 0x18, 0xc3, 0x1f, 0x05, 0x3b, 0x20, 0x1c, +0x02, 0x39, 0x2a, 0x1c, 0x00, 0xf0, 0xcd, 0xf8, 0x38, 0x1c, 0x00, 0xf0, +0xd7, 0xf9, 0xe0, 0x68, 0x46, 0x19, 0x78, 0x68, 0x30, 0x43, 0x78, 0x60, +0x04, 0x98, 0x31, 0x1c, 0x01, 0xf0, 0x88, 0xfa, 0x21, 0x6e, 0x00, 0x98, +0x08, 0x18, 0x01, 0x90, 0x70, 0x1a, 0x00, 0x04, 0x00, 0x0c, 0x61, 0x6e, +0x71, 0x1a, 0x0a, 0x04, 0x12, 0x0c, 0x11, 0x02, 0x12, 0x0a, 0x11, 0x43, 0x09, 0x04, 0x09, 0x0c, 0x02, 0x91, 0x01, 0x02, 0x00, 0x0a, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x01, 0x98, 0xc0, 0x46, -0x41, 0x80, 0x20, 0x8e, 0xfc, 0xf7, 0x11, 0xfe, 0x06, 0x1c, 0x60, 0x8e, -0x02, 0x99, 0xfc, 0xf7, 0x0c, 0xfe, 0x03, 0x90, 0x60, 0x69, 0x01, 0x04, +0x41, 0x80, 0x20, 0x8e, 0xfc, 0xf7, 0xd5, 0xfd, 0x06, 0x1c, 0x60, 0x8e, +0x02, 0x99, 0xfc, 0xf7, 0xd0, 0xfd, 0x03, 0x90, 0x60, 0x69, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, -0x01, 0x98, 0xc0, 0x46, 0x81, 0x80, 0x30, 0x1c, 0xfc, 0xf7, 0xfd, 0xfd, +0x01, 0x98, 0xc0, 0x46, 0x81, 0x80, 0x30, 0x1c, 0xfc, 0xf7, 0xc1, 0xfd, 0x61, 0x69, 0x01, 0x31, 0xc0, 0x43, 0x61, 0x61, 0x01, 0x99, 0xc0, 0x46, 0x48, 0x81, 0x60, 0x6e, 0x00, 0x99, 0x46, 0x18, 0x20, 0x69, 0x01, 0x0e, 0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, 0xff, 0x22, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06, 0x01, 0x43, -0x71, 0x60, 0x03, 0x98, 0xfc, 0xf7, 0xe1, 0xfd, 0x21, 0x69, 0x49, 0x19, -0x21, 0x61, 0xa1, 0x68, 0x49, 0x1b, 0xa1, 0x60, -0x06, 0xd1, 0xb1, 0x89, 0xa2, 0x69, 0x11, 0x43, 0xb1, 0x81, 0xa1, 0x69, -0xfc, 0xf7, 0xd3, 0xfd, 0x38, 0x82, 0x61, 0x6e, 0x38, 0x68, 0x09, 0x18, -0x0e, 0x31, 0xf9, 0x60, 0xe2, 0x68, 0x00, 0x99, 0x04, 0x38, 0x00, 0xf0, -0x4c, 0xf8, 0x02, 0x20, 0x78, 0x82, 0xe0, 0x6d, 0x41, 0x08, 0x16, 0xd3, -0x80, 0x0a, 0x0a, 0xd3, 0x78, 0x68, 0x10, 0x38, 0x01, 0x04, 0x09, 0x0c, -0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x39, 0x68, 0xc0, 0x46, 0xc8, 0x81, -0x09, 0xe0, 0x78, 0x68, 0x0c, 0x38, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, -0x09, 0x0a, 0x08, 0x43, 0x39, 0x68, 0xc0, 0x46, 0x48, 0x81, 0x05, 0xb0, -0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x3c, 0x2c, 0x00, 0x80, -0xc8, 0x2a, 0x00, 0x80, 0x78, 0x2a, 0x00, 0x80, 0xf7, 0xb5, 0x03, 0x1c, -0x0f, 0x1c, 0x00, 0x20, 0x1c, 0x68, 0x26, 0x04, 0x31, 0x1c, 0x1d, 0x1d, -0xfc, 0xf7, 0x97, 0xfd, 0x40, 0xc7, 0x02, 0x9a, 0xd1, 0x1c, 0x89, 0x08, -0x01, 0x39, 0x4a, 0x1e, 0x02, 0x92, 0x00, 0x29, 0x0d, 0xd0, 0x21, 0x0c, -0x10, 0xcd, 0x22, 0x04, 0x0a, 0x43, 0x11, 0x1c, 0x16, 0x1c, 0xfc, 0xf7, -0x86, 0xfd, 0x40, 0xc7, 0x02, 0x99, 0x4a, 0x1e, 0x02, 0x92, 0x00, 0x29, -0xf1, 0xd1, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0x08, -0x80, 0x00, 0x89, 0x08, 0x89, 0x00, 0x03, 0x32, 0x93, 0x08, 0x5a, 0x1e, -0x00, 0x2b, 0x05, 0xd0, 0x08, 0xc9, 0x08, 0xc0, 0x13, 0x1c, 0x01, 0x3a, -0x00, 0x2b, 0xf9, 0xd1, 0x70, 0x47, 0xff, 0xb5, 0x86, 0xb0, 0x17, 0x1c, -0x00, 0x26, 0x06, 0x98, 0x80, 0x6c, 0xc0, 0x1b, 0x06, 0x99, 0xc0, 0x46, -0x88, 0x64, 0x01, 0x20, 0xc0, 0x05, 0x06, 0x99, 0x89, 0x6b, 0xc0, 0x46, -0x01, 0x91, 0x06, 0x99, 0x4c, 0x6b, 0x67, 0xe0, 0x21, 0x68, 0xc0, 0x46, -0x02, 0x91, 0x61, 0x68, 0xc0, 0x46, 0x03, 0x91, 0xa1, 0x68, 0xc0, 0x46, -0x04, 0x91, 0x02, 0xa9, 0x49, 0x88, 0xb9, 0x42, 0x08, 0xd2, 0x02, 0xad, -0x6d, 0x88, 0x02, 0xa9, 0x49, 0x88, 0x7f, 0x1a, 0x00, 0x21, 0x02, 0xab, -0x59, 0x80, 0x19, 0xe0, 0x02, 0xa9, 0x49, 0x88, 0xc9, 0x1b, 0x02, 0xab, -0x59, 0x80, 0x3d, 0x1c, 0x00, 0x27, 0x01, 0x21, 0x49, 0x06, 0x07, 0x9b, -0x9a, 0x07, 0x92, 0x0f, 0x0d, 0xd0, 0xeb, 0x06, 0xdb, 0x0e, 0x08, 0xd0, -0x1e, 0x2b, 0x08, 0xd3, 0x1e, 0x2b, 0x02, 0xd1, 0x03, 0x2a, 0x04, 0xd1, -0x01, 0xe0, 0x02, 0x2a, 0x01, 0xd3, 0x01, 0x26, 0x00, 0x21, 0x29, 0x43, -0x01, 0x43, 0x0a, 0x1c, 0x00, 0x91, 0x00, 0x20, 0x03, 0x99, 0x04, 0x9a, -0x07, 0x9b, 0x01, 0xf0, 0x61, 0xff, 0x07, 0x99, 0x49, 0x19, 0x07, 0x91, +0x71, 0x60, 0x03, 0x98, 0xfc, 0xf7, 0xa5, 0xfd, 0x21, 0x69, 0x49, 0x19, +0x21, 0x61, 0xa1, 0x68, 0x49, 0x1b, 0xa1, 0x60, 0x06, 0xd1, 0xb1, 0x89, +0xa2, 0x69, 0x11, 0x43, 0xb1, 0x81, 0xa1, 0x69, 0xfc, 0xf7, 0x97, 0xfd, +0x38, 0x82, 0x61, 0x6e, 0x38, 0x68, 0x09, 0x18, 0x0e, 0x31, 0xf9, 0x60, +0xe2, 0x68, 0x00, 0x99, 0x04, 0x38, 0x00, 0xf0, 0x4c, 0xf8, 0x02, 0x20, +0x78, 0x82, 0xe0, 0x6d, 0x41, 0x08, 0x16, 0xd3, 0x80, 0x0a, 0x0a, 0xd3, +0x78, 0x68, 0x10, 0x38, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, +0x08, 0x43, 0x39, 0x68, 0xc0, 0x46, 0xc8, 0x81, 0x09, 0xe0, 0x78, 0x68, +0x0c, 0x38, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, +0x39, 0x68, 0xc0, 0x46, 0x48, 0x81, 0x05, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0xd0, 0x2c, 0x00, 0x80, 0x5c, 0x2b, 0x00, 0x80, +0x0c, 0x2b, 0x00, 0x80, 0xf7, 0xb5, 0x03, 0x1c, 0x0f, 0x1c, 0x00, 0x20, +0x1c, 0x68, 0x26, 0x04, 0x31, 0x1c, 0x1d, 0x1d, 0xfc, 0xf7, 0x5b, 0xfd, +0x40, 0xc7, 0x02, 0x9a, 0xd1, 0x1c, 0x89, 0x08, 0x01, 0x39, 0x4a, 0x1e, +0x02, 0x92, 0x00, 0x29, 0x0d, 0xd0, 0x21, 0x0c, 0x10, 0xcd, 0x22, 0x04, +0x0a, 0x43, 0x11, 0x1c, 0x16, 0x1c, 0xfc, 0xf7, 0x4a, 0xfd, 0x40, 0xc7, +0x02, 0x99, 0x4a, 0x1e, 0x02, 0x92, 0x00, 0x29, 0xf1, 0xd1, 0x03, 0xb0, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0x08, 0x80, 0x00, 0x89, 0x08, +0x89, 0x00, 0x03, 0x32, 0x93, 0x08, 0x5a, 0x1e, 0x00, 0x2b, 0x05, 0xd0, +0x08, 0xc9, 0x08, 0xc0, 0x13, 0x1c, 0x01, 0x3a, 0x00, 0x2b, 0xf9, 0xd1, +0x70, 0x47, 0xff, 0xb5, 0x86, 0xb0, 0x17, 0x1c, 0x00, 0x26, 0x06, 0x98, +0x80, 0x6c, 0xc0, 0x1b, 0x06, 0x99, 0xc0, 0x46, 0x88, 0x64, 0x01, 0x20, +0xc0, 0x05, 0x06, 0x99, 0x89, 0x6b, 0xc0, 0x46, 0x01, 0x91, 0x06, 0x99, +0x4c, 0x6b, 0x67, 0xe0, 0x21, 0x68, 0xc0, 0x46, 0x02, 0x91, 0x61, 0x68, +0xc0, 0x46, 0x03, 0x91, 0xa1, 0x68, 0xc0, 0x46, 0x04, 0x91, 0x02, 0xa9, +0x49, 0x88, 0xb9, 0x42, 0x08, 0xd2, 0x02, 0xad, 0x6d, 0x88, 0x02, 0xa9, +0x49, 0x88, 0x7f, 0x1a, 0x00, 0x21, 0x02, 0xab, 0x59, 0x80, 0x19, 0xe0, +0x02, 0xa9, 0x49, 0x88, 0xc9, 0x1b, 0x02, 0xab, 0x59, 0x80, 0x3d, 0x1c, +0x00, 0x27, 0x01, 0x21, 0x49, 0x06, 0x07, 0x9b, 0x9a, 0x07, 0x92, 0x0f, +0x0d, 0xd0, 0xeb, 0x06, 0xdb, 0x0e, 0x08, 0xd0, 0x1e, 0x2b, 0x08, 0xd3, +0x1e, 0x2b, 0x02, 0xd1, 0x03, 0x2a, 0x04, 0xd1, 0x01, 0xe0, 0x02, 0x2a, +0x01, 0xd3, 0x01, 0x26, 0x00, 0x21, 0x29, 0x43, 0x01, 0x43, 0x0a, 0x1c, +0x00, 0x91, 0x00, 0x20, 0x03, 0x99, 0x04, 0x9a, +0x07, 0x9b, 0x01, 0xf0, 0x5b, 0xff, 0x07, 0x99, 0x49, 0x19, 0x07, 0x91, 0x00, 0x2e, 0x0a, 0xd0, 0x1d, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x1d, 0x48, -0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x07, 0x9b, 0x01, 0xf0, 0x52, 0xff, +0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x07, 0x9b, 0x01, 0xf0, 0x4c, 0xff, 0x00, 0x26, 0x02, 0xa8, 0x40, 0x88, 0x00, 0x28, 0x0c, 0xd0, 0x03, 0x98, 0x40, 0x19, 0x03, 0x90, 0x02, 0x98, 0xc0, 0x46, 0x20, 0x60, 0x03, 0x98, 0xc0, 0x46, 0x60, 0x60, 0x04, 0x98, 0xc0, 0x46, 0xa0, 0x60, 0x03, 0xe0, @@ -1276,513 +1289,512 @@ 0x44, 0x63, 0x01, 0x98, 0x06, 0x99, 0xc0, 0x46, 0x88, 0x63, 0x00, 0x20, 0x00, 0x2f, 0x02, 0xd0, 0x01, 0x99, 0x00, 0x29, 0x92, 0xd1, 0x09, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x06, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, -0x09, 0x9b, 0x01, 0xf0, 0x25, 0xff, 0x0a, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, -0xf8, 0x28, 0x00, 0x80, 0x04, 0x00, 0x53, 0x02, 0x90, 0xb5, 0x0c, 0x1c, -0x07, 0x1c, 0x38, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x38, 0x18, 0x43, -0x01, 0x68, 0x38, 0x8a, 0xfc, 0xf7, 0xcb, 0xfc, 0xc0, 0x43, 0xf9, 0x68, -0xc0, 0x46, 0x08, 0x80, 0x78, 0x8a, 0x39, 0x68, 0x08, 0x1a, 0x38, 0x60, -0x38, 0x1c, 0x01, 0xf0, 0x8d, 0xf9, 0x38, 0x1c, 0xfc, 0xf7, 0xd2, 0xfb, -0x20, 0x1c, 0xff, 0xf7, 0x33, 0xfe, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x80, 0xb5, 0x01, 0x88, 0x8a, 0x09, 0x21, 0xd3, 0xca, 0x09, 0x1f, 0xd2, -0x8a, 0x08, 0x1d, 0xd3, 0x00, 0x21, 0x01, 0x80, 0x41, 0x80, 0x47, 0x6f, -0x40, 0x6d, 0xfa, 0x1d, 0x19, 0x32, 0x51, 0x71, 0xfa, 0x6d, 0xc0, 0x46, -0x10, 0x60, 0x3a, 0x6e, 0xc0, 0x46, 0x10, 0x60, 0x0c, 0x48, 0xc0, 0x46, -0x41, 0x63, 0x81, 0x6b, 0x49, 0x08, 0x49, 0x00, 0x81, 0x63, 0x01, 0x20, -0x00, 0xf0, 0xce, 0xff, 0x38, 0x1c, 0x00, 0xf0, 0x6d, 0xff, 0x80, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x80, 0x23, 0x19, 0x43, 0x01, 0x80, 0x01, 0x88, -0x49, 0x09, 0xf6, 0xd2, 0x00, 0xf0, 0xb0, 0xf8, 0xf3, 0xe7, 0x00, 0x00, -0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb5, 0x07, 0x1c, 0x10, 0x1c, 0x0d, 0x1c, -0x00, 0x24, 0x5e, 0x1e, 0x00, 0x2b, 0x19, 0xd0, 0x01, 0x68, 0xc0, 0x46, -0x39, 0x60, 0x41, 0x88, 0x0c, 0x19, 0x41, 0x68, 0xc0, 0x46, 0x79, 0x60, -0x81, 0x68, 0xc0, 0x46, 0xb9, 0x60, 0xc1, 0x68, 0xc0, 0x46, 0xf9, 0x60, -0x10, 0x30, 0x10, 0x37, 0xe9, 0x6a, 0x81, 0x42, 0x02, 0xd8, 0x28, 0x1c, -0x00, 0xf0, 0xee, 0xff, 0x31, 0x1c, 0x01, 0x3e, 0x00, 0x29, 0xe5, 0xd1, -0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x21, 0xc1, 0x61, -0x05, 0x49, 0x0a, 0x68, 0x00, 0x2a, 0x01, 0xd1, 0x08, 0x60, 0x02, 0xe0, -0x4a, 0x68, 0xc0, 0x46, 0xd0, 0x61, 0x48, 0x60, 0x70, 0x47, 0x00, 0x00, -0x3c, 0x2c, 0x00, 0x80, 0x03, 0x49, 0x08, 0x68, 0x00, 0x28, 0x02, 0xd0, -0xc2, 0x69, 0xc0, 0x46, 0x0a, 0x60, 0x70, 0x47, 0x3c, 0x2c, 0x00, 0x80, -0x00, 0x21, 0x81, 0x67, 0x05, 0x49, 0x8a, 0x68, 0x00, 0x2a, 0x01, 0xd1, -0x88, 0x60, 0x02, 0xe0, 0xca, 0x68, 0xc0, 0x46, 0x90, 0x67, 0xc8, 0x60, -0x70, 0x47, 0x00, 0x00, 0x3c, 0x2c, 0x00, 0x80, 0x03, 0x49, 0x88, 0x68, -0x00, 0x28, 0x02, 0xd0, 0x82, 0x6f, 0xc0, 0x46, 0x8a, 0x60, 0x70, 0x47, -0x3c, 0x2c, 0x00, 0x80, 0x00, 0xb5, 0x80, 0x20, 0x13, 0x49, 0xc0, 0x46, -0x08, 0x60, 0xff, 0xf7, 0xd5, 0xff, 0x00, 0x28, 0x1b, 0xd0, 0x03, 0x23, +0x09, 0x9b, 0x01, 0xf0, 0x1f, 0xff, 0x0a, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x7c, 0x29, 0x00, 0x80, +0x04, 0x00, 0x53, 0x02, 0x90, 0xb5, 0x0c, 0x1c, 0x07, 0x1c, 0x38, 0x68, +0x01, 0x23, 0x9b, 0x07, 0x08, 0x38, 0x18, 0x43, 0x01, 0x68, 0x38, 0x8a, +0xfc, 0xf7, 0x8f, 0xfc, 0xc0, 0x43, 0xf9, 0x68, 0xc0, 0x46, 0x08, 0x80, +0x78, 0x8a, 0x39, 0x68, 0x08, 0x1a, 0x38, 0x60, 0x38, 0x1c, 0x01, 0xf0, +0x8b, 0xf9, 0x38, 0x1c, 0xfc, 0xf7, 0x96, 0xfb, 0x20, 0x1c, 0xff, 0xf7, +0x33, 0xfe, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x01, 0x88, +0x8a, 0x09, 0x21, 0xd3, 0xca, 0x09, 0x1f, 0xd2, 0x8a, 0x08, 0x1d, 0xd3, +0x00, 0x21, 0x01, 0x80, 0x41, 0x80, 0x47, 0x6f, 0x40, 0x6d, 0xfa, 0x1d, +0x19, 0x32, 0x51, 0x71, 0xfa, 0x6d, 0xc0, 0x46, 0x10, 0x60, 0x3a, 0x6e, +0xc0, 0x46, 0x10, 0x60, 0x0c, 0x48, 0xc0, 0x46, 0x81, 0x63, 0xc1, 0x6b, +0x49, 0x08, 0x49, 0x00, 0xc1, 0x63, 0x01, 0x20, 0x00, 0xf0, 0xcc, 0xff, +0x38, 0x1c, 0x00, 0xf0, 0x6b, 0xff, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x80, 0x23, 0x19, 0x43, 0x01, 0x80, 0x01, 0x88, 0x49, 0x09, 0xf6, 0xd2, +0x00, 0xf0, 0xb0, 0xf8, 0xf3, 0xe7, 0x00, 0x00, 0xe8, 0x0e, 0x00, 0x80, +0xf0, 0xb5, 0x07, 0x1c, 0x10, 0x1c, 0x0d, 0x1c, 0x00, 0x24, 0x5e, 0x1e, +0x00, 0x2b, 0x19, 0xd0, 0x01, 0x68, 0xc0, 0x46, 0x39, 0x60, 0x41, 0x88, +0x0c, 0x19, 0x41, 0x68, 0xc0, 0x46, 0x79, 0x60, 0x81, 0x68, 0xc0, 0x46, +0xb9, 0x60, 0xc1, 0x68, 0xc0, 0x46, 0xf9, 0x60, 0x10, 0x30, 0x10, 0x37, +0xe9, 0x6a, 0x81, 0x42, 0x02, 0xd8, 0x28, 0x1c, 0x00, 0xf0, 0xec, 0xff, +0x31, 0x1c, 0x01, 0x3e, 0x00, 0x29, 0xe5, 0xd1, 0x20, 0x1c, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x00, 0x21, 0xc1, 0x61, 0x05, 0x49, 0x0a, 0x68, +0x00, 0x2a, 0x01, 0xd1, 0x08, 0x60, 0x02, 0xe0, 0x4a, 0x68, 0xc0, 0x46, +0xd0, 0x61, 0x48, 0x60, 0x70, 0x47, 0x00, 0x00, 0xd0, 0x2c, 0x00, 0x80, +0x03, 0x49, 0x08, 0x68, 0x00, 0x28, 0x02, 0xd0, 0xc2, 0x69, 0xc0, 0x46, +0x0a, 0x60, 0x70, 0x47, 0xd0, 0x2c, 0x00, 0x80, 0x00, 0x21, 0x81, 0x67, +0x05, 0x49, 0x8a, 0x68, 0x00, 0x2a, 0x01, 0xd1, 0x88, 0x60, 0x02, 0xe0, +0xca, 0x68, 0xc0, 0x46, 0x90, 0x67, 0xc8, 0x60, 0x70, 0x47, 0x00, 0x00, +0xd0, 0x2c, 0x00, 0x80, 0x03, 0x49, 0x88, 0x68, 0x00, 0x28, 0x02, 0xd0, +0x82, 0x6f, 0xc0, 0x46, 0x8a, 0x60, 0x70, 0x47, 0xd0, 0x2c, 0x00, 0x80, +0x00, 0xb5, 0x80, 0x20, 0x13, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xff, 0xf7, +0xd5, 0xff, 0x00, 0x28, 0x1b, 0xd0, 0x03, 0x23, 0x1b, 0x07, 0x41, 0x68, 0x19, 0x40, 0x0a, 0x0f, 0x51, 0x01, 0x89, 0x1a, 0x89, 0x00, 0x0d, 0x4b, 0xc9, 0x18, 0x4b, 0x88, 0x00, 0x2b, 0x04, 0xd1, 0x11, 0x1c, 0xff, 0xf7, 0x3b, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x2b, 0x02, 0xd1, 0xff, 0xf7, 0x05, 0xfc, 0xf8, 0xe7, 0x02, 0x2b, 0xf6, 0xd1, 0xff, 0xf7, 0x4e, 0xfb, 0xf3, 0xe7, 0x04, 0x48, 0x01, 0x6d, 0x01, 0x31, -0x01, 0x65, 0xee, 0xe7, 0x00, 0x00, 0x00, 0xb0, 0xc8, 0x2a, 0x00, 0x80, +0x01, 0x65, 0xee, 0xe7, 0x00, 0x00, 0x00, 0xb0, 0x5c, 0x2b, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x00, 0xb5, 0x20, 0x20, 0x0d, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xff, 0xf7, 0xbf, 0xff, 0x00, 0x28, 0x0e, 0xd0, 0x01, 0x88, 0x20, 0x23, 0x19, 0x43, 0x01, 0x80, 0x01, 0x88, 0x10, 0x23, 0x99, 0x43, 0x01, 0x80, 0x01, 0x88, 0x09, 0x0a, 0x01, 0xd3, 0xff, 0xf7, 0x2e, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x03, 0x48, 0x01, 0x6d, 0x01, 0x31, 0x01, 0x65, -0xf8, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, -0xa0, 0x82, 0x20, 0x40, 0x98, 0xb5, 0x07, 0x1c, 0x22, 0x48, 0xc0, 0x46, -0x00, 0x90, 0x22, 0x48, 0xc3, 0x1d, 0x41, 0x33, 0x41, 0x6d, 0x82, 0x6d, -0x80, 0x6c, 0x00, 0x03, 0x00, 0x0b, 0x9c, 0x68, 0x01, 0x23, 0x9b, 0x07, -0x23, 0x43, 0x1b, 0x68, 0x98, 0x42, 0x00, 0xd1, 0x0c, 0xe0, 0x98, 0x42, -0x03, 0xd9, 0x10, 0x1a, 0x59, 0x1a, 0x41, 0x18, 0x00, 0xe0, 0x19, 0x1a, -0x01, 0x20, 0x10, 0x29, 0x00, 0xd8, 0x00, 0x20, 0x00, 0x28, 0x1f, 0xd0, -0x78, 0x6a, 0xf9, 0x6a, 0xc0, 0x46, 0x08, 0x60, 0xb8, 0x6a, 0xf9, 0x6a, -0xc0, 0x46, 0x48, 0x60, 0x10, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0xfb, 0x6a, -0x0f, 0x48, 0x42, 0x6d, 0x03, 0x20, 0x39, 0x6a, 0x01, 0xf0, 0xe8, 0xfd, -0x38, 0x88, 0x10, 0x23, 0x18, 0x43, 0x38, 0x80, 0x38, 0x88, 0x40, 0x23, -0x98, 0x43, 0x38, 0x80, 0x38, 0x1c, 0xff, 0xf7, 0x55, 0xff, 0x98, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x38, 0x88, 0x40, 0x23, 0x18, 0x43, 0x38, 0x80, -0xf7, 0xe7, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x28, 0x03, 0x00, 0x80, -0x08, 0x00, 0x11, 0x02, 0xf8, 0x28, 0x00, 0x80, 0xb0, 0xb5, 0x40, 0x20, -0x2c, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x00, 0xf0, 0xff, 0xfe, 0x07, 0x1c, -0x40, 0x68, 0x03, 0x23, 0x1b, 0x07, 0x18, 0x40, 0x05, 0x0f, 0x68, 0x01, -0x40, 0x1b, 0x80, 0x00, 0x26, 0x49, 0x44, 0x18, 0x20, 0x88, 0x02, 0x23, -0x18, 0x43, 0x20, 0x80, 0x20, 0x88, 0x41, 0x08, 0x34, 0xd3, 0x40, 0x08, -0x40, 0x00, 0x20, 0x80, 0xa0, 0x6c, 0xe1, 0x6c, 0x40, 0x18, 0xa0, 0x64, -0x00, 0x20, 0xe0, 0x64, 0xa1, 0x6b, 0x22, 0x6d, 0x89, 0x18, 0xa1, 0x63, -0x20, 0x65, 0xb8, 0x6a, 0xc0, 0x46, 0x60, 0x65, 0x03, 0x23, 0x1b, 0x07, -0x78, 0x68, 0x18, 0x40, 0x78, 0x60, 0x61, 0x68, 0x36, 0x31, 0x94, 0x29, -0x04, 0xd8, 0x38, 0x23, 0x18, 0x43, 0x78, 0x60, 0x38, 0x20, 0x03, 0xe0, -0x94, 0x23, 0x18, 0x43, 0x78, 0x60, 0x94, 0x20, 0xb8, 0x61, 0x39, 0x68, -0x78, 0x68, 0x02, 0x04, 0x12, 0x0c, 0x20, 0x1c, 0xcb, 0x1f, 0x05, 0x3b, -0xff, 0xf7, 0xd7, 0xfd, 0x02, 0x20, 0x60, 0x80, 0x38, 0x1c, 0xff, 0xf7, -0xdf, 0xfe, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0xfc, 0xf7, -0x4d, 0xfa, 0x28, 0x01, 0x06, 0x49, 0x40, 0x18, 0x19, 0x23, 0xdb, 0x01, -0xc0, 0x18, 0x41, 0x6b, 0x01, 0x39, 0x41, 0x63, 0xef, 0xe7, 0x00, 0x00, -0x00, 0x00, 0x00, 0xb0, 0xc8, 0x2a, 0x00, 0x80, 0x1c, 0x1c, 0x00, 0x80, -0x90, 0xb5, 0x00, 0x27, 0x0f, 0x4c, 0x0d, 0xe0, 0x02, 0x6b, 0x01, 0x3a, -0x02, 0x63, 0x00, 0x2a, 0x05, 0xdc, 0xc2, 0x6a, 0xc0, 0x46, 0x02, 0x63, -0x80, 0x6a, 0x01, 0xf0, 0xcc, 0xf9, 0x01, 0x37, 0x0b, 0x2f, 0x07, 0xd2, -0x38, 0x01, 0x00, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0x41, 0x6a, +0xf8, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xa0, 0x82, 0x20, 0x40, +0x98, 0xb5, 0x07, 0x1c, 0x22, 0x48, 0xc0, 0x46, 0x00, 0x90, 0x22, 0x48, +0xc3, 0x1d, 0x41, 0x33, 0x41, 0x6d, 0x82, 0x6d, 0x80, 0x6c, 0x00, 0x03, +0x00, 0x0b, 0x9c, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, +0x98, 0x42, 0x00, 0xd1, 0x0c, 0xe0, 0x98, 0x42, 0x03, 0xd9, 0x10, 0x1a, +0x59, 0x1a, 0x41, 0x18, 0x00, 0xe0, 0x19, 0x1a, 0x01, 0x20, 0x10, 0x29, +0x00, 0xd8, 0x00, 0x20, 0x00, 0x28, 0x1f, 0xd0, 0x78, 0x6a, 0xf9, 0x6a, +0xc0, 0x46, 0x08, 0x60, 0xb8, 0x6a, 0xf9, 0x6a, 0xc0, 0x46, 0x48, 0x60, +0x10, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0xfb, 0x6a, 0x0f, 0x48, 0x42, 0x6d, +0x03, 0x20, 0x39, 0x6a, 0x01, 0xf0, 0xe2, 0xfd, 0x38, 0x88, 0x10, 0x23, +0x18, 0x43, 0x38, 0x80, 0x38, 0x88, 0x40, 0x23, 0x98, 0x43, 0x38, 0x80, +0x38, 0x1c, 0xff, 0xf7, 0x55, 0xff, 0x98, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x38, 0x88, 0x40, 0x23, 0x18, 0x43, 0x38, 0x80, 0xf7, 0xe7, 0x00, 0x00, +0x55, 0x55, 0x55, 0x55, 0xa8, 0x03, 0x00, 0x80, 0x08, 0x00, 0x11, 0x02, +0x7c, 0x29, 0x00, 0x80, 0xb0, 0xb5, 0x40, 0x20, 0x2c, 0x49, 0xc0, 0x46, +0x08, 0x60, 0x00, 0xf0, 0xfd, 0xfe, 0x07, 0x1c, 0x40, 0x68, 0x03, 0x23, +0x1b, 0x07, 0x18, 0x40, 0x05, 0x0f, 0x68, 0x01, 0x40, 0x1b, 0x80, 0x00, +0x26, 0x49, 0x44, 0x18, 0x20, 0x88, 0x02, 0x23, 0x18, 0x43, 0x20, 0x80, +0x20, 0x88, 0x41, 0x08, 0x34, 0xd3, 0x40, 0x08, 0x40, 0x00, 0x20, 0x80, +0xa0, 0x6c, 0xe1, 0x6c, 0x40, 0x18, 0xa0, 0x64, 0x00, 0x20, 0xe0, 0x64, +0xa1, 0x6b, 0x22, 0x6d, 0x89, 0x18, 0xa1, 0x63, 0x20, 0x65, 0xb8, 0x6a, +0xc0, 0x46, 0x60, 0x65, 0x03, 0x23, 0x1b, 0x07, 0x78, 0x68, 0x18, 0x40, +0x78, 0x60, 0x61, 0x68, 0x36, 0x31, 0x94, 0x29, 0x04, 0xd8, 0x38, 0x23, +0x18, 0x43, 0x78, 0x60, 0x38, 0x20, 0x03, 0xe0, 0x94, 0x23, 0x18, 0x43, +0x78, 0x60, 0x94, 0x20, 0xb8, 0x61, 0x39, 0x68, 0x78, 0x68, 0x02, 0x04, +0x12, 0x0c, 0x20, 0x1c, 0xcb, 0x1f, 0x05, 0x3b, 0xff, 0xf7, 0xd7, 0xfd, +0x02, 0x20, 0x60, 0x80, 0x38, 0x1c, 0xff, 0xf7, 0xdf, 0xfe, 0xb0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0xfc, 0xf7, 0x11, 0xfa, 0x28, 0x01, +0x06, 0x49, 0x40, 0x18, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x41, 0x6b, +0x01, 0x39, 0x41, 0x63, 0xef, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, +0x5c, 0x2b, 0x00, 0x80, 0xa0, 0x1c, 0x00, 0x80, 0x90, 0xb5, 0x00, 0x27, +0x0f, 0x4c, 0x0d, 0xe0, 0x42, 0x6b, 0x01, 0x3a, +0x42, 0x63, 0x00, 0x2a, 0x05, 0xdc, 0x02, 0x6b, 0xc0, 0x46, 0x42, 0x63, +0xc0, 0x6a, 0x01, 0xf0, 0xc6, 0xf9, 0x01, 0x37, 0x0b, 0x2f, 0x07, 0xd2, +0x38, 0x01, 0x00, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0x81, 0x6a, 0x00, 0x29, 0xe9, 0xd1, 0x01, 0x20, 0x40, 0x06, 0x03, 0x49, 0xc0, 0x46, -0x08, 0x60, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, -0x00, 0x00, 0x00, 0xb0, 0x11, 0x48, 0xc1, 0x68, 0x01, 0x31, 0xc1, 0x60, -0x10, 0x49, 0xc8, 0x68, 0x01, 0x28, 0x19, 0xd1, 0xc8, 0x1d, 0x79, 0x30, -0x82, 0x88, 0x00, 0x2a, 0x14, 0xd0, 0x01, 0x3a, 0x82, 0x80, 0x82, 0x88, -0x00, 0x2a, 0x0f, 0xd1, 0xc2, 0x88, 0x00, 0x2a, 0x0a, 0xd1, 0x02, 0x23, -0xca, 0x6f, 0x1a, 0x43, 0xca, 0x67, 0x07, 0x49, 0xc0, 0x46, 0x0a, 0x60, -0x04, 0x21, 0x81, 0x80, 0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, 0xc1, 0x80, -0x70, 0x47, 0x00, 0x00, 0x08, 0x83, 0x20, 0x40, -0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, 0xb0, 0xb5, 0x07, 0x1c, -0x01, 0x23, 0xf8, 0x1d, 0x69, 0x30, 0x03, 0x73, 0x1d, 0x49, 0xca, 0x1d, -0x79, 0x32, 0xd4, 0x89, 0x60, 0x1c, 0xd0, 0x81, 0x55, 0x8a, 0x00, 0x20, -0xac, 0x42, 0x02, 0xdb, 0x53, 0x73, 0xd0, 0x81, 0x50, 0x83, 0x01, 0x23, -0x9b, 0x07, 0x3a, 0x6d, 0x1a, 0x43, 0x12, 0x68, 0xc0, 0x46, 0xba, 0x61, -0xfb, 0x69, 0x9a, 0x42, 0x06, 0xd1, 0xf8, 0x6c, 0x12, 0x49, 0xc0, 0x46, -0x08, 0x60, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x78, 0x61, 0x48, 0x69, -0xfa, 0x6c, 0x90, 0x43, 0x48, 0x61, 0x01, 0x21, 0x09, 0x05, 0xc8, 0x60, -0x38, 0x69, 0x02, 0x28, 0xf1, 0xd0, 0xb8, 0x69, 0xf9, 0x69, 0x41, 0x1a, -0x01, 0xd5, 0x78, 0x6d, 0x41, 0x18, 0x38, 0x1c, 0x00, 0xf0, 0x0e, 0xf8, -0xf9, 0x69, 0x09, 0x18, 0xf9, 0x61, 0x78, 0x6d, 0x81, 0x42, 0xe2, 0xd3, -0x08, 0x1a, 0xf8, 0x61, 0xdf, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, -0x00, 0x00, 0x00, 0xb0, 0xf8, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0xff, 0x23, -0x21, 0x33, 0x9f, 0x42, 0x01, 0xd9, 0xff, 0x27, 0x21, 0x37, 0xe1, 0x6e, -0x38, 0x1c, 0x01, 0xf0, 0xcf, 0xfc, 0x2d, 0x4d, 0x00, 0x28, 0x13, 0xd1, -0xe0, 0x1d, 0x49, 0x30, 0x01, 0x7a, 0x01, 0x23, 0x19, 0x43, 0x01, 0x72, -0x29, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x29, 0x48, 0x01, 0x6d, 0x42, 0x6d, -0x00, 0x20, 0x2b, 0x1c, 0x01, 0xf0, 0xb4, 0xfc, 0x00, 0x20, 0xf8, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x20, 0x69, 0x01, 0x30, 0x20, 0x61, 0x23, 0x49, -0xc8, 0x1d, 0xb9, 0x30, 0xc2, 0x6a, 0x92, 0x00, 0x51, 0x18, 0xc0, 0x31, -0xcf, 0x60, 0xc1, 0x6a, 0x01, 0x31, 0x89, 0x07, 0x89, 0x0f, 0xc1, 0x62, -0x20, 0x6b, 0xc2, 0x19, 0x61, 0x6d, 0x8a, 0x42, 0x03, 0xd8, 0x23, 0x22, -0x12, 0x05, 0x3a, 0x43, 0x05, 0xe0, 0x09, 0x1a, 0x7e, 0x1a, 0x07, 0xd1, -0x23, 0x22, 0x12, 0x05, 0x0a, 0x43, 0x00, 0x92, 0x61, 0x6e, 0x09, 0x18, -0xa2, 0x6e, 0x10, 0xe0, 0x11, 0x22, 0x52, 0x05, 0x0a, 0x43, 0x00, 0x92, -0x61, 0x6e, 0x09, 0x18, 0x00, 0x20, 0xa2, 0x6e, 0x2b, 0x1c, 0x01, 0xf0, -0x81, 0xfc, 0x23, 0x22, 0x12, 0x05, 0x32, 0x43, 0x00, 0x92, 0x61, 0x6e, -0xa2, 0x6e, 0x00, 0x20, 0x2b, 0x1c, 0x01, 0xf0, 0x77, 0xfc, 0x20, 0x6b, -0xc0, 0x19, 0x00, 0x09, 0x00, 0x01, 0x61, 0x6d, 0x81, 0x42, 0x00, 0xd8, -0x40, 0x1a, 0x20, 0x63, 0x38, 0x1c, 0xb8, 0xe7, 0x44, 0x80, 0x20, 0x40, -0x04, 0x00, 0x1b, 0x02, 0xf8, 0x28, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, -0x80, 0xb5, 0x01, 0x20, 0xc0, 0x03, 0x0d, 0x49, 0xc0, 0x46, 0x08, 0x60, -0x0c, 0x49, 0xc8, 0x1d, 0x49, 0x30, 0x02, 0x7a, 0x00, 0x27, 0x00, 0x2a, -0x03, 0xd0, 0x07, 0x72, 0x08, 0x1c, 0xff, 0xf7, 0x39, 0xff, 0x08, 0x49, -0xc8, 0x1d, 0x49, 0x30, 0x02, 0x7a, 0x00, 0x2a, 0x03, 0xd0, 0x07, 0x72, -0x08, 0x1c, 0xff, 0xf7, 0x2f, 0xff, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x00, 0x00, 0x00, 0xb0, 0xd0, 0x2c, 0x00, 0x80, 0x50, 0x2c, 0x00, 0x80, -0x90, 0xb5, 0x07, 0x1c, 0x10, 0x20, 0x18, 0x49, 0xc0, 0x46, 0x08, 0x60, -0xf8, 0x68, 0x01, 0x30, 0xf8, 0x60, 0x16, 0x48, 0xc4, 0x1d, 0xb9, 0x34, -0x21, 0x6b, 0x89, 0x00, 0x09, 0x18, 0xc0, 0x31, 0xc9, 0x68, 0x7a, 0x68, -0x92, 0x00, 0xd2, 0x19, 0x51, 0x64, 0x21, 0x6b, 0x89, 0x00, 0x08, 0x18, -0xc0, 0x30, 0xc1, 0x68, 0x78, 0x68, 0x80, 0x00, 0xc0, 0x19, 0xc0, 0x6b, -0x01, 0xf0, 0xa6, 0xfa, 0x01, 0x23, 0x78, 0x68, -0x58, 0x40, 0x78, 0x60, 0x20, 0x6b, 0x01, 0x30, 0x80, 0x07, 0x80, 0x0f, -0x20, 0x63, 0xf8, 0x1d, 0x19, 0x30, 0x40, 0x79, 0x00, 0x28, 0x02, 0xd1, -0x38, 0x1c, 0x00, 0xf0, 0x07, 0xf8, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x00, 0x00, 0x00, 0xb0, 0xe8, 0x0d, 0x00, 0x80, 0x90, 0xb5, 0x07, 0x1c, -0x39, 0x48, 0x80, 0x68, 0x00, 0x28, 0x05, 0xd0, 0xb8, 0x6a, 0xc0, 0x68, -0x80, 0x09, 0x01, 0xd3, 0x02, 0x20, 0x00, 0xe0, 0x78, 0x6f, 0xfc, 0xf7, -0x9d, 0xf8, 0x04, 0x1c, 0x06, 0xd1, 0x01, 0x20, 0xf9, 0x1d, 0x19, 0x31, -0x08, 0x71, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf8, 0x6c, 0x2f, 0x49, -0xc0, 0x46, 0x08, 0x60, 0xba, 0x6a, 0x38, 0x1c, 0x21, 0x1c, 0x00, 0xf0, -0x59, 0xf8, 0x67, 0x62, 0x00, 0x28, 0x03, 0xd1, 0x20, 0x1c, 0x00, 0xf0, -0x0b, 0xfd, 0xec, 0xe7, 0xf9, 0x6d, 0x09, 0x68, 0x09, 0x18, 0x09, 0x09, -0x09, 0x01, 0x7a, 0x6d, 0x8a, 0x42, 0x00, 0xd8, 0x89, 0x1a, 0xa1, 0x62, -0xb9, 0x68, 0x89, 0x00, 0xc9, 0x19, 0x4a, 0x6c, 0x00, 0x2a, 0x07, 0xd0, -0x4a, 0x6c, 0x12, 0x1a, 0x4a, 0x64, 0x80, 0x08, 0x80, 0x00, 0xb9, 0x6a, -0x08, 0x18, 0xb8, 0x62, 0x38, 0x68, 0xb9, 0x6a, 0x80, 0x00, 0xc0, 0x19, -0x42, 0x6b, 0x91, 0x42, 0x0e, 0xd3, 0x00, 0x21, 0x41, 0x64, 0xb8, 0x6a, -0x39, 0x68, 0x89, 0x00, 0xc9, 0x19, 0x49, 0x6b, 0x40, 0x1a, 0xb8, 0x62, -0xb9, 0x68, 0x89, 0x00, 0xc9, 0x19, 0xc9, 0x6b, 0x40, 0x18, 0xb8, 0x62, -0xb8, 0x68, 0x81, 0x00, 0xc9, 0x19, 0x49, 0x6c, 0x00, 0x29, 0xb8, 0xd1, -0xb9, 0x6a, 0xfa, 0x6b, 0x91, 0x42, 0xb4, 0xd0, 0x3a, 0x6c, 0x91, 0x42, -0xb1, 0xd0, 0x01, 0x23, 0x58, 0x40, 0xb8, 0x60, 0x80, 0x00, 0xc0, 0x19, -0xc0, 0x6b, 0xc0, 0x46, 0xb8, 0x62, 0xf8, 0x68, 0x00, 0x28, 0x01, 0xd0, -0x01, 0x38, 0xf8, 0x60, 0x38, 0x69, 0x00, 0x28, 0xa1, 0xd0, 0x01, 0x38, -0x38, 0x61, 0x9e, 0xe7, 0xe8, 0x18, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, -0xf7, 0xb5, 0x90, 0xb0, 0x04, 0x1c, 0x0d, 0x1c, 0x00, 0x20, 0x05, 0x90, -0x02, 0x90, 0x00, 0x22, 0x01, 0x92, 0xf9, 0x48, 0x80, 0x6a, 0xc0, 0x46, -0xa8, 0x61, 0xa0, 0x68, 0x81, 0x00, 0x09, 0x19, 0x49, 0x6b, 0xc0, 0x46, -0x20, 0x60, 0xe1, 0x62, 0x12, 0x9a, 0xd0, 0x68, 0xc0, 0x46, 0xa8, 0x60, -0x12, 0x9a, 0x51, 0x78, 0xc0, 0x46, 0x0c, 0x91, 0xf0, 0x48, 0xc0, 0x46, -0x03, 0x90, 0xd7, 0x1d, 0x09, 0x37, 0xe0, 0x6a, 0xc1, 0x1b, 0x09, 0x09, -0xe3, 0x1d, 0x19, 0x33, 0x0c, 0x9a, 0xc0, 0x46, 0x0f, 0x93, 0xeb, 0x4b, -0xc0, 0x46, 0x0e, 0x93, 0x91, 0x42, 0x01, 0xd3, 0xb8, 0x42, 0x21, 0xd8, -0xe1, 0x68, 0x02, 0x29, 0x1e, 0xd2, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, -0x48, 0x71, 0x00, 0x20, 0x03, 0x99, 0x01, 0xf0, 0x5b, 0xfb, 0x00, 0x28, -0x03, 0xd1, 0x0e, 0x9b, 0x98, 0x6b, 0x01, 0x30, 0x98, 0x63, 0x01, 0x20, -0x80, 0x06, 0x00, 0x27, 0x68, 0x60, 0xaf, 0x61, 0xdd, 0x4a, 0xc0, 0x46, -0x00, 0x92, 0xdd, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0xdc, 0x4b, 0x00, 0x20, -0x01, 0xf0, 0x3e, 0xfb, 0x38, 0x1c, 0x5c, 0xe3, 0xb8, 0x42, 0x03, 0xd8, -0x20, 0x1c, 0x00, 0xf0, 0x7b, 0xfc, 0x07, 0x1c, 0xd7, 0x48, 0x80, 0x68, -0x00, 0x28, 0x64, 0xd0, 0x38, 0x78, 0x40, 0x07, 0x40, 0x0f, 0x03, 0x28, -0x60, 0xd1, 0x05, 0x98, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x05, 0x90, -0x38, 0x78, 0xf0, 0x23, 0x18, 0x40, 0x58, 0xd1, 0xe0, 0x6a, 0xc0, 0x1b, -0x00, 0x09, 0x0c, 0x99, 0x88, 0x42, 0x02, 0xd2, -0xe0, 0x68, 0x02, 0x28, 0x05, 0xd3, 0xcb, 0x49, 0x88, 0x68, 0x00, 0xf0, -0x87, 0xff, 0x06, 0x1c, 0x06, 0xd1, 0x03, 0x9b, 0x28, 0x1c, 0x39, 0x1c, -0x22, 0x1c, 0x00, 0xf0, 0x8b, 0xfc, 0x16, 0xe1, 0x2e, 0x62, 0xf8, 0x68, -0x00, 0x28, 0x0d, 0xd0, 0xb8, 0x89, 0x00, 0x28, 0x03, 0xd0, 0xc1, 0x49, -0xc9, 0x68, 0x00, 0xf0, 0x74, 0xff, 0xf8, 0x89, 0x00, 0x28, 0x03, 0xd0, -0xbd, 0x49, 0xc9, 0x68, 0x00, 0xf0, 0x6d, 0xff, 0x7a, 0x68, 0xc0, 0x46, -0x72, 0x61, 0xb9, 0x68, 0xc0, 0x46, 0xb1, 0x61, 0x30, 0x1c, 0xb8, 0x49, -0x09, 0x68, 0x00, 0xf0, 0x62, 0xff, 0x00, 0x28, 0x17, 0xd1, 0x30, 0x1c, -0xb4, 0x49, 0x49, 0x68, 0x00, 0xf0, 0x5b, 0xff, 0x10, 0x37, 0xe0, 0x6a, -0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x27, 0xfc, 0x07, 0x1c, -0x68, 0x68, 0xaf, 0x4b, 0x18, 0x43, 0x68, 0x60, 0x00, 0x20, 0xa8, 0x61, -0xac, 0x23, 0xa8, 0x68, 0x98, 0x43, 0xa8, 0x60, 0xb0, 0xe0, 0xa8, 0x69, -0xa8, 0x28, 0x01, 0xd2, 0xa8, 0x20, 0xa8, 0x61, 0x10, 0x37, 0xe0, 0x6a, -0xb8, 0x42, 0x6c, 0xd8, 0x9c, 0xe0, 0xa5, 0xe0, 0xa4, 0xe0, 0x10, 0x28, -0x68, 0xd1, 0x03, 0x23, 0x1b, 0x07, 0x68, 0x68, 0x18, 0x40, 0x01, 0x0f, -0x48, 0x01, 0x40, 0x1a, 0x80, 0x00, 0xa0, 0x4a, 0x82, 0x18, 0x01, 0x92, -0x78, 0x88, 0x42, 0x0b, 0x31, 0xd3, 0x82, 0x0b, 0x2f, 0xd3, 0x9d, 0x48, -0xc0, 0x46, 0x03, 0x90, 0x02, 0x20, 0x01, 0x9a, 0xc0, 0x46, 0x10, 0x80, -0x78, 0x88, 0x00, 0x05, 0x00, 0x0d, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x60, -0xb8, 0x68, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x60, 0x78, 0x68, 0x01, 0x9a, -0xc0, 0x46, 0x10, 0x62, 0x00, 0x20, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x64, -0x01, 0x9a, 0xc0, 0x46, 0x90, 0x63, 0x88, 0x02, 0x8f, 0x49, 0x40, 0x18, -0x01, 0x9a, 0xc0, 0x46, 0x50, 0x63, 0x01, 0x9a, 0x50, 0x68, 0x36, 0x30, -0x94, 0x28, 0x01, 0xd8, 0x38, 0x20, 0x00, 0xe0, 0x94, 0x20, 0xa8, 0x61, -0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x28, 0xd8, 0x58, 0xe0, 0x7a, 0x88, -0x92, 0x0b, 0x03, 0xd3, 0x85, 0x48, 0xc0, 0x46, 0x03, 0x90, 0x23, 0xe0, -0x01, 0x22, 0x12, 0x03, 0x02, 0x40, 0x83, 0x4b, 0x1d, 0xd0, 0x03, 0x93, -0x00, 0x05, 0x00, 0x0d, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x60, 0xb8, 0x68, -0x01, 0x9a, 0xc0, 0x46, 0x90, 0x60, 0x78, 0x68, 0x01, 0x9a, 0xc0, 0x46, -0x10, 0x62, 0x00, 0x20, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x64, 0x01, 0x9a, -0xc0, 0x46, 0x90, 0x63, 0x88, 0x02, 0x75, 0x49, 0x40, 0x18, 0x01, 0x9a, -0xc0, 0x46, 0x50, 0x63, 0x02, 0xe0, 0x33, 0xe0, 0x2a, 0xe0, 0x03, 0x93, -0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, 0x48, 0x71, 0x12, 0x9a, 0x50, 0x78, -0x05, 0x99, 0x43, 0x1a, 0x0b, 0x93, 0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, -0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x92, 0xfb, 0x07, 0x1c, 0x01, 0x9a, -0x50, 0x6b, 0x91, 0x6b, 0x09, 0x01, 0x40, 0x18, 0x0b, 0x9b, 0x21, 0x1c, -0x3a, 0x1c, 0xff, 0xf7, 0x7b, 0xfb, 0x01, 0x9a, 0xc0, 0x46, 0xd0, 0x64, -0x01, 0x9a, 0x0b, 0x9b, 0xc0, 0x46, 0x13, 0x65, 0x01, 0x23, 0x5b, 0x06, -0x68, 0x68, 0x18, 0x43, 0x68, 0x60, 0x00, 0x20, 0xa8, 0x61, 0x0d, 0xe0, +0x08, 0x60, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, +0x00, 0x00, 0x00, 0xb0, 0x10, 0x48, 0xc1, 0x68, 0x01, 0x31, 0xc1, 0x60, +0x0f, 0x49, 0xc8, 0x68, 0x01, 0x28, 0x17, 0xd1, 0xc8, 0x1d, 0x79, 0x30, +0x02, 0x89, 0x00, 0x2a, 0x12, 0xd0, 0x01, 0x3a, 0x02, 0x81, 0x02, 0x89, +0x00, 0x2a, 0x0d, 0xd1, 0x42, 0x89, 0x00, 0x2a, 0x08, 0xd1, 0xc9, 0x6f, +0x02, 0x23, 0x0a, 0x68, 0x1a, 0x43, 0x0a, 0x60, 0x04, 0x21, 0x01, 0x81, +0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, 0x41, 0x81, 0x70, 0x47, 0x00, 0x00, +0x08, 0x83, 0x20, 0x40, 0x68, 0x0e, 0x00, 0x80, 0xb0, 0xb5, 0x07, 0x1c, +0x01, 0x23, 0xf8, 0x1d, 0x69, 0x30, 0x03, 0x73, 0x1e, 0x48, 0xc2, 0x1d, +0x79, 0x32, 0x54, 0x8a, 0x61, 0x1c, 0x51, 0x82, 0xd5, 0x8a, 0x00, 0x21, +0xac, 0x42, 0x04, 0xdb, 0xc4, 0x1d, 0x89, 0x34, 0x63, 0x70, 0x51, 0x82, +0xd1, 0x83, 0x01, 0x23, 0x9b, 0x07, 0x3a, 0x6d, 0x1a, 0x43, 0x12, 0x68, +0xc0, 0x46, 0xba, 0x61, 0xfb, 0x69, 0x9a, 0x42, 0x06, 0xd1, 0xf8, 0x6c, +0x12, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x79, 0x61, 0x41, 0x69, 0xfa, 0x6c, 0x91, 0x43, 0x41, 0x61, 0x01, 0x20, +0x00, 0x05, 0xc1, 0x60, 0x38, 0x69, 0x02, 0x28, 0xf1, 0xd0, 0xb8, 0x69, +0xf9, 0x69, 0x41, 0x1a, 0x01, 0xd5, 0x78, 0x6d, 0x41, 0x18, 0x38, 0x1c, +0x00, 0xf0, 0x0e, 0xf8, 0xf9, 0x69, 0x09, 0x18, 0xf9, 0x61, 0x78, 0x6d, +0x81, 0x42, 0xe2, 0xd3, 0x08, 0x1a, 0xf8, 0x61, 0xdf, 0xe7, 0x00, 0x00, +0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0xf8, 0xb5, 0x04, 0x1c, +0x0f, 0x1c, 0xff, 0x23, 0x21, 0x33, 0x9f, 0x42, 0x01, 0xd9, 0xff, 0x27, +0x21, 0x37, 0xe1, 0x6e, 0x38, 0x1c, 0x01, 0xf0, 0xcb, 0xfc, 0x2d, 0x4d, +0x00, 0x28, 0x13, 0xd1, 0xe0, 0x1d, 0x49, 0x30, 0x01, 0x7a, 0x01, 0x23, +0x19, 0x43, 0x01, 0x72, 0x29, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x29, 0x48, +0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x2b, 0x1c, 0x01, 0xf0, 0xb0, 0xfc, +0x00, 0x20, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x20, 0x69, 0x01, 0x30, +0x20, 0x61, 0x23, 0x49, 0xc8, 0x1d, 0xb9, 0x30, 0x02, 0x6b, 0x92, 0x00, +0x51, 0x18, 0xc0, 0x31, 0x0f, 0x61, 0x01, 0x6b, 0x01, 0x31, 0x89, 0x07, +0x89, 0x0f, 0x01, 0x63, 0x20, 0x6b, 0xc2, 0x19, 0x61, 0x6d, 0x8a, 0x42, +0x03, 0xd8, 0x23, 0x22, 0x12, 0x05, 0x3a, 0x43, 0x05, 0xe0, 0x09, 0x1a, +0x7e, 0x1a, 0x07, 0xd1, 0x23, 0x22, 0x12, 0x05, 0x0a, 0x43, 0x00, 0x92, +0x61, 0x6e, 0x09, 0x18, 0xa2, 0x6e, 0x10, 0xe0, 0x11, 0x22, 0x52, 0x05, +0x0a, 0x43, 0x00, 0x92, 0x61, 0x6e, 0x09, 0x18, 0x00, 0x20, 0xa2, 0x6e, +0x2b, 0x1c, 0x01, 0xf0, 0x7d, 0xfc, 0x23, 0x22, 0x12, 0x05, 0x32, 0x43, +0x00, 0x92, 0x61, 0x6e, 0xa2, 0x6e, 0x00, 0x20, 0x2b, 0x1c, 0x01, 0xf0, +0x73, 0xfc, 0x20, 0x6b, 0xc0, 0x19, 0x00, 0x09, 0x00, 0x01, 0x61, 0x6d, +0x81, 0x42, 0x00, 0xd8, 0x40, 0x1a, 0x20, 0x63, 0x38, 0x1c, 0xb8, 0xe7, +0x44, 0x80, 0x20, 0x40, 0x04, 0x00, 0x1b, 0x02, 0x7c, 0x29, 0x00, 0x80, +0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x01, 0x20, +0xc0, 0x03, 0x0d, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x0c, 0x49, 0xc8, 0x1d, +0x49, 0x30, 0x02, 0x7a, 0x00, 0x27, 0x00, 0x2a, 0x03, 0xd0, 0x07, 0x72, +0x08, 0x1c, 0xff, 0xf7, 0x37, 0xff, 0x08, 0x49, 0xc8, 0x1d, 0x49, 0x30, +0x02, 0x7a, 0x00, 0x2a, 0x03, 0xd0, 0x07, 0x72, 0x08, 0x1c, 0xff, 0xf7, +0x2d, 0xff, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, +0x64, 0x2d, 0x00, 0x80, 0xe4, 0x2c, 0x00, 0x80, 0x90, 0xb5, 0x07, 0x1c, +0x10, 0x20, 0x18, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xf8, 0x68, 0x01, 0x30, +0xf8, 0x60, 0x16, 0x48, 0xc4, 0x1d, 0xb9, 0x34, 0x61, 0x6b, 0x89, 0x00, +0x09, 0x18, 0xc0, 0x31, 0x09, 0x69, 0x7a, 0x68, 0x92, 0x00, 0xd2, 0x19, +0x51, 0x64, 0x61, 0x6b, 0x89, 0x00, 0x08, 0x18, 0xc0, 0x30, 0x01, 0x69, +0x78, 0x68, 0x80, 0x00, 0xc0, 0x19, 0xc0, 0x6b, 0x01, 0xf0, 0xa2, 0xfa, +0x01, 0x23, 0x78, 0x68, 0x58, 0x40, 0x78, 0x60, 0x60, 0x6b, 0x01, 0x30, +0x80, 0x07, 0x80, 0x0f, 0x60, 0x63, 0xf8, 0x1d, 0x19, 0x30, 0x40, 0x79, +0x00, 0x28, 0x02, 0xd1, 0x38, 0x1c, 0x00, 0xf0, 0x07, 0xf8, 0x90, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, 0x68, 0x0e, 0x00, 0x80, +0x90, 0xb5, 0x07, 0x1c, 0x39, 0x48, 0xc0, 0x68, 0x00, 0x28, 0x05, 0xd0, +0xb8, 0x6a, 0xc0, 0x68, 0x80, 0x09, 0x01, 0xd3, 0x02, 0x20, 0x00, 0xe0, +0x78, 0x6f, 0xfc, 0xf7, 0x63, 0xf8, 0x04, 0x1c, 0x06, 0xd1, 0x01, 0x20, +0xf9, 0x1d, 0x19, 0x31, 0x08, 0x71, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0xf8, 0x6c, 0x2f, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xba, 0x6a, 0x38, 0x1c, +0x21, 0x1c, 0x00, 0xf0, 0x59, 0xf8, 0x67, 0x62, 0x00, 0x28, 0x03, 0xd1, +0x20, 0x1c, 0x00, 0xf0, 0x0b, 0xfd, 0xec, 0xe7, 0xf9, 0x6d, 0x09, 0x68, +0x09, 0x18, 0x09, 0x09, 0x09, 0x01, 0x7a, 0x6d, 0x8a, 0x42, 0x00, 0xd8, +0x89, 0x1a, 0xa1, 0x62, 0xb9, 0x68, 0x89, 0x00, 0xc9, 0x19, 0x4a, 0x6c, +0x00, 0x2a, 0x07, 0xd0, 0x4a, 0x6c, 0x12, 0x1a, 0x4a, 0x64, 0x80, 0x08, +0x80, 0x00, 0xb9, 0x6a, 0x08, 0x18, 0xb8, 0x62, 0x38, 0x68, 0xb9, 0x6a, +0x80, 0x00, 0xc0, 0x19, 0x42, 0x6b, 0x91, 0x42, 0x0e, 0xd3, 0x00, 0x21, +0x41, 0x64, 0xb8, 0x6a, 0x39, 0x68, 0x89, 0x00, 0xc9, 0x19, 0x49, 0x6b, +0x40, 0x1a, 0xb8, 0x62, 0xb9, 0x68, 0x89, 0x00, 0xc9, 0x19, 0xc9, 0x6b, +0x40, 0x18, 0xb8, 0x62, 0xb8, 0x68, 0x81, 0x00, 0xc9, 0x19, 0x49, 0x6c, +0x00, 0x29, 0xb8, 0xd1, 0xb9, 0x6a, 0xfa, 0x6b, 0x91, 0x42, 0xb4, 0xd0, +0x3a, 0x6c, 0x91, 0x42, 0xb1, 0xd0, 0x01, 0x23, 0x58, 0x40, 0xb8, 0x60, +0x80, 0x00, 0xc0, 0x19, 0xc0, 0x6b, 0xc0, 0x46, 0xb8, 0x62, 0xf8, 0x68, +0x00, 0x28, 0x01, 0xd0, 0x01, 0x38, 0xf8, 0x60, 0x38, 0x69, 0x00, 0x28, +0xa1, 0xd0, 0x01, 0x38, 0x38, 0x61, 0x9e, 0xe7, 0x68, 0x19, 0x00, 0x80, +0x00, 0x00, 0x00, 0xb0, 0xf7, 0xb5, 0x90, 0xb0, 0x04, 0x1c, 0x0d, 0x1c, +0x00, 0x20, 0x05, 0x90, 0x02, 0x90, 0x00, 0x22, 0x01, 0x92, 0xf9, 0x48, +0xc0, 0x6a, 0xc0, 0x46, 0xa8, 0x61, 0xa0, 0x68, 0x81, 0x00, 0x09, 0x19, +0x49, 0x6b, 0xc0, 0x46, 0x20, 0x60, 0xe1, 0x62, 0x12, 0x9a, 0xd0, 0x68, +0xc0, 0x46, 0xa8, 0x60, 0x12, 0x9a, 0x51, 0x78, 0xc0, 0x46, 0x0c, 0x91, +0xf0, 0x48, 0xc0, 0x46, 0x03, 0x90, 0xd7, 0x1d, 0x09, 0x37, 0xe0, 0x6a, +0xc1, 0x1b, 0x09, 0x09, 0xe3, 0x1d, 0x19, 0x33, 0x0c, 0x9a, 0xc0, 0x46, +0x0f, 0x93, 0xeb, 0x4b, 0xc0, 0x46, 0x0e, 0x93, +0x91, 0x42, 0x01, 0xd3, 0xb8, 0x42, 0x21, 0xd8, 0xe1, 0x68, 0x02, 0x29, +0x1e, 0xd2, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, 0x48, 0x71, 0x00, 0x20, +0x03, 0x99, 0x01, 0xf0, 0x57, 0xfb, 0x00, 0x28, 0x03, 0xd1, 0x0e, 0x9b, +0xd8, 0x6b, 0x01, 0x30, 0xd8, 0x63, 0x01, 0x20, 0x80, 0x06, 0x00, 0x27, +0x68, 0x60, 0xaf, 0x61, 0xdd, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0xdd, 0x48, +0x01, 0x6d, 0x42, 0x6d, 0xdc, 0x4b, 0x00, 0x20, 0x01, 0xf0, 0x3a, 0xfb, +0x38, 0x1c, 0x5c, 0xe3, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, +0x7b, 0xfc, 0x07, 0x1c, 0xd7, 0x48, 0xc0, 0x68, 0x00, 0x28, 0x64, 0xd0, +0x38, 0x78, 0x40, 0x07, 0x40, 0x0f, 0x03, 0x28, 0x60, 0xd1, 0x05, 0x98, +0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x05, 0x90, 0x38, 0x78, 0xf0, 0x23, +0x18, 0x40, 0x58, 0xd1, 0xe0, 0x6a, 0xc0, 0x1b, 0x00, 0x09, 0x0c, 0x99, +0x88, 0x42, 0x02, 0xd2, 0xe0, 0x68, 0x02, 0x28, 0x05, 0xd3, 0xcb, 0x49, +0x88, 0x68, 0x00, 0xf0, 0x83, 0xff, 0x06, 0x1c, 0x06, 0xd1, 0x03, 0x9b, +0x28, 0x1c, 0x39, 0x1c, 0x22, 0x1c, 0x00, 0xf0, 0x8b, 0xfc, 0x16, 0xe1, +0x2e, 0x62, 0xf8, 0x68, 0x00, 0x28, 0x0d, 0xd0, 0xb8, 0x89, 0x00, 0x28, +0x03, 0xd0, 0xc1, 0x49, 0xc9, 0x68, 0x00, 0xf0, 0x70, 0xff, 0xf8, 0x89, +0x00, 0x28, 0x03, 0xd0, 0xbd, 0x49, 0xc9, 0x68, 0x00, 0xf0, 0x69, 0xff, +0x7a, 0x68, 0xc0, 0x46, 0x72, 0x61, 0xb9, 0x68, 0xc0, 0x46, 0xb1, 0x61, +0x30, 0x1c, 0xb8, 0x49, 0x09, 0x68, 0x00, 0xf0, 0x5e, 0xff, 0x00, 0x28, +0x17, 0xd1, 0x30, 0x1c, 0xb4, 0x49, 0x49, 0x68, 0x00, 0xf0, 0x57, 0xff, 0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, -0x71, 0xfb, 0x07, 0x1c, 0x38, 0x78, 0x40, 0x07, 0x40, 0x0f, 0x03, 0x28, -0x00, 0xd1, 0xf8, 0xe6, 0xa8, 0x69, 0x03, 0x99, 0x01, 0xf0, 0x2a, 0xfa, -0x00, 0x28, 0x2a, 0xd1, 0x38, 0x1c, 0x21, 0x1c, -0x00, 0xf0, 0x79, 0xfb, 0xa8, 0x68, 0x80, 0x09, 0x04, 0xd3, 0x30, 0x1c, -0x49, 0x49, 0x49, 0x68, 0x00, 0xf0, 0x85, 0xfe, 0x41, 0x49, 0x00, 0x20, -0x01, 0xf0, 0x18, 0xfa, 0x00, 0x28, 0x04, 0xd1, 0x0e, 0x9b, 0x98, 0x6b, -0x01, 0x30, 0x98, 0x63, 0x11, 0xe0, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, -0x48, 0x71, 0x80, 0x06, 0x00, 0x27, 0x68, 0x60, 0xaf, 0x61, 0x3a, 0x4a, -0xc0, 0x46, 0x00, 0x92, 0x39, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x39, 0x4b, -0x00, 0x20, 0x01, 0xf0, 0xf7, 0xf9, 0x00, 0x20, 0x15, 0xe2, 0x05, 0x98, -0x0c, 0x99, 0x08, 0x1a, 0x00, 0x04, 0x00, 0x0c, 0x0c, 0x90, 0x0b, 0x90, -0x0c, 0x98, 0x00, 0x28, 0x03, 0xd0, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, -0x48, 0x71, 0x28, 0x68, 0xc0, 0x46, 0x04, 0x90, 0x00, 0x26, 0x00, 0x20, -0x08, 0x90, 0x00, 0x22, 0x0a, 0x92, 0x0c, 0x98, 0x01, 0x38, 0x0d, 0x90, -0xa3, 0xe0, 0x78, 0x88, 0x8a, 0x1b, 0x12, 0x04, 0x12, 0x0c, 0x90, 0x42, -0x05, 0xdd, 0x07, 0x92, 0x80, 0x1a, 0x00, 0x04, 0x00, 0x0c, 0x08, 0x90, -0x00, 0xe0, 0x07, 0x90, 0x08, 0x98, 0x00, 0x28, 0x07, 0xd1, 0x0d, 0x98, -0x0a, 0x9a, 0x90, 0x42, 0x07, 0xdd, 0x07, 0x98, 0x30, 0x18, 0x88, 0x42, -0x03, 0xd8, 0x01, 0x20, 0x40, 0x05, 0x06, 0x90, 0x1c, 0xe0, 0x11, 0x20, -0x40, 0x05, 0x06, 0x90, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd1, -0x20, 0x48, 0xc0, 0x46, 0x06, 0x90, 0xb1, 0x07, 0x89, 0x0f, 0x0f, 0xd0, -0x07, 0x98, 0xc0, 0x06, 0xc0, 0x0e, 0x08, 0xd0, 0x1e, 0x28, 0x09, 0xdb, -0x1e, 0x28, 0x02, 0xd1, 0x03, 0x29, 0x05, 0xd1, 0x01, 0xe0, 0x02, 0x29, -0x02, 0xd3, 0x01, 0x20, 0x02, 0x90, 0xde, 0xe7, 0x0a, 0x9a, 0x00, 0x2a, -0x04, 0xd1, 0x01, 0x23, 0xdb, 0x05, 0x06, 0x98, 0x18, 0x43, 0x06, 0x90, -0x07, 0x98, 0x06, 0x99, 0x08, 0x43, 0x02, 0x1c, 0x00, 0x90, 0x04, 0x98, -0x83, 0x19, 0x1d, 0xe0, 0x68, 0x0e, 0x00, 0x80, 0x79, 0x48, 0xff, 0xff, -0xa8, 0x0e, 0x00, 0x80, 0x04, 0x00, 0x12, 0x02, 0xf8, 0x28, 0x00, 0x80, -0x44, 0x80, 0x20, 0x40, 0xe8, 0x18, 0x00, 0x80, 0xe0, 0x03, 0x00, 0x80, -0x00, 0x00, 0x00, 0x80, 0xc8, 0x2a, 0x00, 0x80, 0xc9, 0x31, 0xff, 0xff, -0x58, 0x5f, 0x21, 0x40, 0x81, 0x3c, 0xff, 0xff, 0x41, 0x31, 0xff, 0xff, -0x00, 0x00, 0x32, 0x02, 0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0, -0x6f, 0xf9, 0x07, 0x98, 0x36, 0x18, 0x02, 0x98, 0x00, 0x28, 0x16, 0xd0, -0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x04, 0xd1, 0x09, 0x23, 0x5b, 0x04, -0x06, 0x98, 0x18, 0x43, 0x06, 0x90, 0x06, 0x98, 0xc2, 0x4a, 0x02, 0x43, -0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0xc1, 0x48, 0x01, 0x6d, 0x42, 0x6d, -0x00, 0x20, 0x01, 0xf0, 0x55, 0xf9, 0x00, 0x20, 0x02, 0x90, 0x08, 0x98, -0x00, 0x28, 0x0b, 0xd1, 0x0b, 0x9b, 0x01, 0x3b, 0x0b, 0x93, 0x10, 0x37, -0xe0, 0x6a, 0xb8, 0x42, 0x0c, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x8a, 0xfa, -0x07, 0x1c, 0x07, 0xe0, 0x78, 0x68, 0x07, 0x9a, 0x80, 0x18, 0x78, 0x60, -0x78, 0x88, 0x07, 0x9a, 0x80, 0x1a, 0x78, 0x80, 0x0a, 0x9a, 0x50, 0x1c, -0x02, 0x04, 0x12, 0x0c, 0x0a, 0x92, 0x0c, 0x98, 0x0a, 0x9a, 0x82, 0x42, -0x03, 0xda, 0xa9, 0x69, 0xb1, 0x42, 0x00, 0xd9, 0x53, 0xe7, 0xa8, 0x69, -0xb0, 0x42, 0x6b, 0xd1, 0xa8, 0x68, 0x01, 0x09, 0x69, 0xd2, 0x08, 0x9a, -0x00, 0x2a, 0x56, 0xd0, 0x0c, 0x99, 0x0a, 0x9a, 0x8a, 0x42, 0x3e, 0xdb, -0xb1, 0x07, 0x89, 0x0f, 0x0c, 0xd0, 0x08, 0x9a, -0xd2, 0x06, 0xd2, 0x0e, 0x0b, 0xd0, 0x1e, 0x2a, 0x06, 0xdb, 0x1e, 0x2a, -0x02, 0xd1, 0x03, 0x29, 0x05, 0xd0, 0x01, 0xe0, 0x02, 0x29, 0x02, 0xd2, -0x02, 0x99, 0x00, 0x29, 0x21, 0xd0, 0x08, 0x9a, 0xc0, 0x46, 0x00, 0x92, -0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0, -0x05, 0xf9, 0x08, 0x98, 0x36, 0x18, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, -0x02, 0xd0, 0x01, 0x20, 0x40, 0x06, 0x00, 0xe0, 0x92, 0x48, 0x01, 0x22, -0x02, 0x43, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0x8e, 0x48, 0x01, 0x6d, -0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, 0xf0, 0xf8, 0x00, 0x20, 0x02, 0x90, -0x15, 0xe0, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd0, 0x01, 0x20, 0x40, 0x06, -0x00, 0xe0, 0x88, 0x48, 0x08, 0x9a, 0x02, 0x43, 0x00, 0xe0, 0x08, 0x9a, +0x27, 0xfc, 0x07, 0x1c, 0x68, 0x68, 0xaf, 0x4b, 0x18, 0x43, 0x68, 0x60, +0x00, 0x20, 0xa8, 0x61, 0xac, 0x23, 0xa8, 0x68, 0x98, 0x43, 0xa8, 0x60, +0xb0, 0xe0, 0xa8, 0x69, 0xa8, 0x28, 0x01, 0xd2, 0xa8, 0x20, 0xa8, 0x61, +0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x6c, 0xd8, 0x9c, 0xe0, 0xa5, 0xe0, +0xa4, 0xe0, 0x10, 0x28, 0x68, 0xd1, 0x03, 0x23, 0x1b, 0x07, 0x68, 0x68, +0x18, 0x40, 0x01, 0x0f, 0x48, 0x01, 0x40, 0x1a, 0x80, 0x00, 0xa0, 0x4a, +0x82, 0x18, 0x01, 0x92, 0x78, 0x88, 0x42, 0x0b, 0x31, 0xd3, 0x82, 0x0b, +0x2f, 0xd3, 0x9d, 0x48, 0xc0, 0x46, 0x03, 0x90, 0x02, 0x20, 0x01, 0x9a, +0xc0, 0x46, 0x10, 0x80, 0x78, 0x88, 0x00, 0x05, 0x00, 0x0d, 0x01, 0x9a, +0xc0, 0x46, 0x50, 0x60, 0xb8, 0x68, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x60, +0x78, 0x68, 0x01, 0x9a, 0xc0, 0x46, 0x10, 0x62, 0x00, 0x20, 0x01, 0x9a, +0xc0, 0x46, 0x90, 0x64, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x63, 0x88, 0x02, +0x8f, 0x49, 0x40, 0x18, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x63, 0x01, 0x9a, +0x50, 0x68, 0x36, 0x30, 0x94, 0x28, 0x01, 0xd8, 0x38, 0x20, 0x00, 0xe0, +0x94, 0x20, 0xa8, 0x61, 0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x28, 0xd8, +0x58, 0xe0, 0x7a, 0x88, 0x92, 0x0b, 0x03, 0xd3, 0x85, 0x48, 0xc0, 0x46, +0x03, 0x90, 0x23, 0xe0, 0x01, 0x22, 0x12, 0x03, 0x02, 0x40, 0x83, 0x4b, +0x1d, 0xd0, 0x03, 0x93, 0x00, 0x05, 0x00, 0x0d, 0x01, 0x9a, 0xc0, 0x46, +0x50, 0x60, 0xb8, 0x68, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x60, 0x78, 0x68, +0x01, 0x9a, 0xc0, 0x46, 0x10, 0x62, 0x00, 0x20, 0x01, 0x9a, 0xc0, 0x46, +0x90, 0x64, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x63, 0x88, 0x02, 0x75, 0x49, +0x40, 0x18, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x63, +0x02, 0xe0, 0x33, 0xe0, 0x2a, 0xe0, 0x03, 0x93, 0x01, 0x20, 0x0f, 0x99, +0xc0, 0x46, 0x48, 0x71, 0x12, 0x9a, 0x50, 0x78, 0x05, 0x99, 0x43, 0x1a, +0x0b, 0x93, 0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, +0x00, 0xf0, 0x92, 0xfb, 0x07, 0x1c, 0x01, 0x9a, 0x50, 0x6b, 0x91, 0x6b, +0x09, 0x01, 0x40, 0x18, 0x0b, 0x9b, 0x21, 0x1c, 0x3a, 0x1c, 0xff, 0xf7, +0x7d, 0xfb, 0x01, 0x9a, 0xc0, 0x46, 0xd0, 0x64, 0x01, 0x9a, 0x0b, 0x9b, +0xc0, 0x46, 0x13, 0x65, 0x01, 0x23, 0x5b, 0x06, 0x68, 0x68, 0x18, 0x43, +0x68, 0x60, 0x00, 0x20, 0xa8, 0x61, 0x0d, 0xe0, 0x10, 0x37, 0xe0, 0x6a, +0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x71, 0xfb, 0x07, 0x1c, +0x38, 0x78, 0x40, 0x07, 0x40, 0x0f, 0x03, 0x28, 0x00, 0xd1, 0xf8, 0xe6, +0xa8, 0x69, 0x03, 0x99, 0x01, 0xf0, 0x26, 0xfa, 0x00, 0x28, 0x2a, 0xd1, +0x38, 0x1c, 0x21, 0x1c, 0x00, 0xf0, 0x79, 0xfb, 0xa8, 0x68, 0x80, 0x09, +0x04, 0xd3, 0x30, 0x1c, 0x49, 0x49, 0x49, 0x68, 0x00, 0xf0, 0x81, 0xfe, +0x41, 0x49, 0x00, 0x20, 0x01, 0xf0, 0x14, 0xfa, 0x00, 0x28, 0x04, 0xd1, +0x0e, 0x9b, 0xd8, 0x6b, 0x01, 0x30, 0xd8, 0x63, 0x11, 0xe0, 0x01, 0x20, +0x0f, 0x99, 0xc0, 0x46, 0x48, 0x71, 0x80, 0x06, 0x00, 0x27, 0x68, 0x60, +0xaf, 0x61, 0x3a, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x39, 0x48, 0x01, 0x6d, +0x42, 0x6d, 0x39, 0x4b, 0x00, 0x20, 0x01, 0xf0, 0xf3, 0xf9, 0x00, 0x20, +0x15, 0xe2, 0x05, 0x98, 0x0c, 0x99, 0x08, 0x1a, 0x00, 0x04, 0x00, 0x0c, +0x0c, 0x90, 0x0b, 0x90, 0x0c, 0x98, 0x00, 0x28, 0x03, 0xd0, 0x01, 0x20, +0x0f, 0x99, 0xc0, 0x46, 0x48, 0x71, 0x28, 0x68, 0xc0, 0x46, 0x04, 0x90, +0x00, 0x26, 0x00, 0x20, 0x08, 0x90, 0x00, 0x22, 0x0a, 0x92, 0x0c, 0x98, +0x01, 0x38, 0x0d, 0x90, 0xa3, 0xe0, 0x78, 0x88, 0x8a, 0x1b, 0x12, 0x04, +0x12, 0x0c, 0x90, 0x42, 0x05, 0xdd, 0x07, 0x92, 0x80, 0x1a, 0x00, 0x04, +0x00, 0x0c, 0x08, 0x90, 0x00, 0xe0, 0x07, 0x90, 0x08, 0x98, 0x00, 0x28, +0x07, 0xd1, 0x0d, 0x98, 0x0a, 0x9a, 0x90, 0x42, 0x07, 0xdd, 0x07, 0x98, +0x30, 0x18, 0x88, 0x42, 0x03, 0xd8, 0x01, 0x20, 0x40, 0x05, 0x06, 0x90, +0x1c, 0xe0, 0x11, 0x20, 0x40, 0x05, 0x06, 0x90, 0xa8, 0x68, 0x8c, 0x23, +0x18, 0x40, 0x02, 0xd1, 0x20, 0x48, 0xc0, 0x46, 0x06, 0x90, 0xb1, 0x07, +0x89, 0x0f, 0x0f, 0xd0, 0x07, 0x98, 0xc0, 0x06, 0xc0, 0x0e, 0x08, 0xd0, +0x1e, 0x28, 0x09, 0xdb, 0x1e, 0x28, 0x02, 0xd1, 0x03, 0x29, 0x05, 0xd1, +0x01, 0xe0, 0x02, 0x29, 0x02, 0xd3, 0x01, 0x20, 0x02, 0x90, 0xde, 0xe7, +0x0a, 0x9a, 0x00, 0x2a, 0x04, 0xd1, 0x01, 0x23, 0xdb, 0x05, 0x06, 0x98, +0x18, 0x43, 0x06, 0x90, 0x07, 0x98, 0x06, 0x99, 0x08, 0x43, 0x02, 0x1c, +0x00, 0x90, 0x04, 0x98, 0x83, 0x19, 0x1d, 0xe0, 0xe8, 0x0e, 0x00, 0x80, +0xed, 0x48, 0xff, 0xff, 0x28, 0x0f, 0x00, 0x80, 0x04, 0x00, 0x12, 0x02, +0x7c, 0x29, 0x00, 0x80, 0x44, 0x80, 0x20, 0x40, 0x68, 0x19, 0x00, 0x80, +0x60, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x5c, 0x2b, 0x00, 0x80, +0x41, 0x32, 0xff, 0xff, 0x58, 0x5f, 0x21, 0x40, 0xf9, 0x3c, 0xff, 0xff, +0xb9, 0x31, 0xff, 0xff, 0x00, 0x00, 0x32, 0x02, 0x00, 0x20, 0x3a, 0x1d, +0x06, 0xca, 0x01, 0xf0, 0x6b, 0xf9, 0x07, 0x98, 0x36, 0x18, 0x02, 0x98, +0x00, 0x28, 0x16, 0xd0, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x04, 0xd1, +0x09, 0x23, 0x5b, 0x04, 0x06, 0x98, 0x18, 0x43, +0x06, 0x90, 0x06, 0x98, 0xc2, 0x4a, 0x02, 0x43, 0x00, 0x92, 0x04, 0x98, +0x83, 0x19, 0xc1, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, +0x51, 0xf9, 0x00, 0x20, 0x02, 0x90, 0x08, 0x98, 0x00, 0x28, 0x0b, 0xd1, +0x0b, 0x9b, 0x01, 0x3b, 0x0b, 0x93, 0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, +0x0c, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x8a, 0xfa, 0x07, 0x1c, 0x07, 0xe0, +0x78, 0x68, 0x07, 0x9a, 0x80, 0x18, 0x78, 0x60, 0x78, 0x88, 0x07, 0x9a, +0x80, 0x1a, 0x78, 0x80, 0x0a, 0x9a, 0x50, 0x1c, 0x02, 0x04, 0x12, 0x0c, +0x0a, 0x92, 0x0c, 0x98, 0x0a, 0x9a, 0x82, 0x42, 0x03, 0xda, 0xa9, 0x69, +0xb1, 0x42, 0x00, 0xd9, 0x53, 0xe7, 0xa8, 0x69, 0xb0, 0x42, 0x6b, 0xd1, +0xa8, 0x68, 0x01, 0x09, 0x69, 0xd2, 0x08, 0x9a, 0x00, 0x2a, 0x56, 0xd0, +0x0c, 0x99, 0x0a, 0x9a, 0x8a, 0x42, 0x3e, 0xdb, 0xb1, 0x07, 0x89, 0x0f, +0x0c, 0xd0, 0x08, 0x9a, 0xd2, 0x06, 0xd2, 0x0e, 0x0b, 0xd0, 0x1e, 0x2a, +0x06, 0xdb, 0x1e, 0x2a, 0x02, 0xd1, 0x03, 0x29, 0x05, 0xd0, 0x01, 0xe0, +0x02, 0x29, 0x02, 0xd2, 0x02, 0x99, 0x00, 0x29, 0x21, 0xd0, 0x08, 0x9a, 0xc0, 0x46, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d, -0x06, 0xca, 0x01, 0xf0, 0xd9, 0xf8, 0x08, 0x98, 0x36, 0x18, 0x10, 0x37, -0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x14, 0xfa, -0x07, 0x1c, 0x68, 0x68, 0x80, 0x0e, 0x6b, 0xd2, 0x0a, 0x98, 0xc0, 0x46, -0x09, 0x90, 0x0c, 0x99, 0x88, 0x42, 0x5c, 0xda, 0x0d, 0x98, 0x09, 0x99, -0x88, 0x42, 0x03, 0xd0, 0x7a, 0x88, 0x1e, 0xe0, 0x5f, 0xe0, 0x5e, 0xe0, -0x78, 0x88, 0x01, 0x22, 0x52, 0x06, 0x02, 0x43, 0xa9, 0x68, 0x8c, 0x23, -0x19, 0x40, 0x02, 0xd1, 0x09, 0x23, 0x5b, 0x04, 0x1a, 0x43, 0xb1, 0x07, -0x89, 0x0f, 0x0e, 0xd0, 0xc3, 0x06, 0xdb, 0x0e, 0x08, 0xd0, 0x1e, 0x2b, -0x09, 0xdb, 0x1e, 0x2b, 0x02, 0xd1, 0x03, 0x29, 0x05, 0xd1, 0x01, 0xe0, -0x02, 0x29, 0x02, 0xd3, 0x01, 0x21, 0x02, 0x91, 0x02, 0x1c, 0x09, 0x98, -0x00, 0x28, 0x02, 0xd1, 0x01, 0x23, 0xdb, 0x05, 0x1a, 0x43, 0x00, 0x92, -0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0, -0x93, 0xf8, 0x78, 0x88, 0x86, 0x19, 0x10, 0x37, 0x02, 0x98, 0x00, 0x28, -0x14, 0xd0, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd0, 0x01, 0x20, -0x40, 0x06, 0x00, 0xe0, 0x57, 0x48, 0x01, 0x22, 0x02, 0x43, 0x00, 0x92, -0x04, 0x98, 0x83, 0x19, 0x53, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, -0x01, 0xf0, 0x7a, 0xf8, 0x00, 0x20, 0x02, 0x90, 0xe0, 0x6a, 0xb8, 0x42, -0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0xb6, 0xf9, 0x07, 0x1c, 0x09, 0x98, -0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x09, 0x90, 0x0c, 0x99, 0x88, 0x42, -0xa2, 0xdb, 0x68, 0x68, 0x30, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x68, 0x60, -0xe8, 0x6a, 0x00, 0xf0, 0x7b, 0xfa, 0x28, 0xe0, 0x27, 0xe0, 0xa8, 0x68, -0x00, 0x09, 0x14, 0xd3, 0x68, 0x68, 0x80, 0x0e, 0x15, 0xd2, 0x01, 0x9a, -0x00, 0x2a, 0x12, 0xd0, 0x01, 0x9a, 0x50, 0x6b, 0x0b, 0x9b, 0x21, 0x1c, -0x3a, 0x1c, 0xff, 0xf7, 0x87, 0xf9, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x64, -0x01, 0x9a, 0x0b, 0x9b, 0xc0, 0x46, 0x93, 0x63, 0x03, 0xe0, 0xe8, 0x6a, -0x31, 0x1c, 0x00, 0xf0, 0x5d, 0xfa, 0x68, 0x68, 0x30, 0x43, 0x68, 0x60, -0xa8, 0x69, 0xb0, 0x42, 0x05, 0xd9, 0x00, 0x04, 0x00, 0x0c, 0x80, 0x1b, -0x00, 0xf0, 0xee, 0xf9, 0xae, 0x61, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, -0x0b, 0xd0, 0x2f, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x04, 0x98, 0xc3, 0x1f, -0x05, 0x3b, 0x2a, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, -0x27, 0xf8, 0x01, 0x23, 0x9b, 0x07, 0x20, 0x6d, 0x18, 0x43, 0x00, 0x68, -0xc0, 0x46, 0xa0, 0x61, 0xe1, 0x69, 0x81, 0x42, -0x12, 0xd0, 0x22, 0x69, 0x02, 0x2a, 0x0f, 0xd2, 0x41, 0x1a, 0x01, 0xd5, -0x60, 0x6d, 0x41, 0x18, 0x20, 0x1c, 0xff, 0xf7, 0x3f, 0xfb, 0xe1, 0x69, -0x40, 0x18, 0xe0, 0x61, 0x61, 0x6d, 0x88, 0x42, 0x24, 0xd3, 0x40, 0x1a, -0xe0, 0x61, 0x21, 0xe0, 0x81, 0x42, 0x1f, 0xd1, 0x20, 0x69, 0x02, 0x28, -0x1c, 0xd2, 0x01, 0x20, 0x60, 0x61, 0x18, 0x48, 0x41, 0x69, 0xe2, 0x6c, -0x0a, 0x43, 0x42, 0x61, 0x81, 0x69, 0xe3, 0x6c, 0x99, 0x43, 0x81, 0x61, -0x01, 0x21, 0x09, 0x05, 0xca, 0x60, 0x80, 0x69, 0xc0, 0x46, 0x08, 0x61, -0x8b, 0x02, 0x20, 0x6d, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xa0, 0x61, -0xe1, 0x69, 0x81, 0x42, 0x02, 0xd0, 0x20, 0x1c, 0xff, 0xf7, 0xce, 0xfa, -0x28, 0x1c, 0x00, 0xf0, 0x0f, 0xf9, 0x0c, 0x98, 0x05, 0x99, 0x40, 0x18, -0x00, 0x01, 0x10, 0x30, 0x68, 0x61, 0x13, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xf8, 0x28, 0x00, 0x80, -0x00, 0x00, 0x12, 0x02, 0x04, 0x00, 0x52, 0x02, 0xe8, 0x0d, 0x00, 0x80, -0xf0, 0xb5, 0x40, 0x20, 0x2d, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x00, 0xf0, -0x03, 0xf9, 0x07, 0x1c, 0x81, 0x69, 0x44, 0x6a, 0xa0, 0x6f, 0x00, 0xf0, -0x49, 0xfe, 0x00, 0x20, 0xe1, 0x1d, 0x19, 0x31, 0x48, 0x71, 0x79, 0x68, -0xc9, 0x0e, 0x09, 0xd3, 0xf8, 0x6a, 0x00, 0x01, 0x24, 0x49, 0x40, 0x18, -0x24, 0x4b, 0xc0, 0x18, 0x01, 0x68, 0x01, 0x39, 0x01, 0x60, 0x36, 0xe0, -0xe1, 0x6d, 0x09, 0x68, 0x22, 0x6e, 0xc0, 0x46, 0x11, 0x60, 0x20, 0x4e, -0xf5, 0x1d, 0x79, 0x35, 0x01, 0x23, 0xa9, 0x6b, 0x19, 0x43, 0xa9, 0x63, -0xb9, 0x6a, 0xe2, 0x6d, 0xc0, 0x46, 0x11, 0x60, 0xb9, 0x6a, 0x22, 0x6e, -0xc0, 0x46, 0x11, 0x60, 0x61, 0x69, 0x00, 0x29, 0x04, 0xd1, 0x69, 0x6b, -0x01, 0x31, 0x69, 0x63, 0x08, 0x29, 0x07, 0xd3, 0x68, 0x63, 0x01, 0x20, -0x00, 0xf0, 0x86, 0xf8, 0xa8, 0x6b, 0x40, 0x08, 0x40, 0x00, 0xa8, 0x63, -0x78, 0x68, 0x81, 0x0e, 0x0f, 0xd2, 0x0b, 0x23, 0x1b, 0x02, 0xf1, 0x18, -0x89, 0x68, 0x00, 0x29, 0x06, 0xd0, 0x00, 0x08, 0x04, 0xd2, 0x20, 0x1c, -0x39, 0x1c, 0x00, 0xf0, 0x43, 0xf8, 0x02, 0xe0, 0x38, 0x1c, 0x00, 0xf0, -0x05, 0xfa, 0x38, 0x1c, 0xfb, 0xf7, 0x4a, 0xfc, 0x20, 0x1c, 0x00, 0xf0, -0x0b, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, -0x1c, 0x1c, 0x00, 0x80, 0xb4, 0x0c, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, -0x80, 0xb5, 0x07, 0x1c, 0xf8, 0x1d, 0x19, 0x30, 0x01, 0x79, 0x00, 0x29, -0x04, 0xd0, 0x00, 0x21, 0x01, 0x71, 0x38, 0x1c, 0xff, 0xf7, 0x56, 0xfb, -0xf8, 0x68, 0x02, 0x28, 0x0d, 0xd0, 0xb8, 0x68, 0x80, 0x00, 0xc2, 0x19, -0x50, 0x6c, 0x00, 0x28, 0x11, 0xd0, 0xb8, 0x6a, 0x41, 0x78, 0x09, 0x01, -0x10, 0x31, 0x52, 0x6b, 0x10, 0x1a, 0x88, 0x42, 0x05, 0xd3, 0x38, 0x1c, -0xff, 0xf7, 0x42, 0xfb, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, -0xff, 0xf7, 0x2a, 0xfa, 0xf8, 0xe7, 0x78, 0x68, 0x80, 0x00, 0xc0, 0x19, -0xc0, 0x6b, 0xc0, 0x46, 0xb8, 0x62, 0xf1, 0xe7, 0xb0, 0xb5, 0x87, 0xb0, -0x0f, 0x1c, 0x80, 0x6f, 0xc0, 0x46, 0x00, 0x90, 0x00, 0x24, 0x13, 0x4d, -0x0b, 0x23, 0x1b, 0x02, 0xe8, 0x18, 0x40, 0x69, 0x00, 0x28, 0x17, 0xd0, -0x69, 0x46, 0xa2, 0x00, 0x52, 0x19, 0x0b, 0x23, 0x1b, 0x02, 0xd2, 0x18, -0x52, 0x69, 0x38, 0x1c, 0x00, 0xf0, 0x96, 0xfb, 0x00, 0x28, 0x09, 0xd1, -0x01, 0x34, 0xa0, 0x00, 0x40, 0x19, 0x0b, 0x23, -0x1b, 0x02, 0xc0, 0x18, 0x40, 0x69, 0x00, 0x28, 0xea, 0xd1, 0x01, 0xe0, -0x01, 0x28, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x9d, 0xf9, 0x07, 0xb0, -0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, -0xb8, 0xb5, 0xc2, 0x07, 0xd2, 0x0f, 0x16, 0x4c, 0x16, 0x49, 0x01, 0xd0, -0x08, 0x22, 0x08, 0xe0, 0x82, 0x08, 0x05, 0xd3, 0x0c, 0x22, 0xa4, 0x18, -0x0b, 0x68, 0xdf, 0x1d, 0x15, 0x37, 0x03, 0xe0, 0x1c, 0x22, 0x0b, 0x68, -0xdf, 0x1d, 0x09, 0x37, 0x0f, 0x4b, 0x1d, 0x7b, 0x00, 0x2d, 0x13, 0xd0, -0x5b, 0x7b, 0x00, 0x2b, 0x10, 0xd0, 0x01, 0x23, 0x5b, 0x06, 0x1a, 0x43, -0x00, 0x28, 0x01, 0xd1, 0x5b, 0x08, 0x1a, 0x43, 0x00, 0x92, 0x4a, 0x68, -0x01, 0x20, 0x39, 0x1c, 0x23, 0x1c, 0x00, 0xf0, 0xe3, 0xfe, 0xb8, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x03, 0x23, 0x1b, 0x06, 0x1a, 0x43, 0xf1, 0xe7, -0x3c, 0xef, 0x20, 0x40, 0xf8, 0x28, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80, -0x00, 0x21, 0xc1, 0x61, 0x05, 0x49, 0x4a, 0x68, 0x00, 0x2a, 0x01, 0xd1, -0x48, 0x60, 0x02, 0xe0, 0x8a, 0x68, 0xc0, 0x46, 0xd0, 0x61, 0x88, 0x60, -0x70, 0x47, 0x00, 0x00, 0xa8, 0x0e, 0x00, 0x80, 0x03, 0x49, 0x48, 0x68, -0x00, 0x28, 0x02, 0xd0, 0xc2, 0x69, 0xc0, 0x46, 0x4a, 0x60, 0x70, 0x47, -0xa8, 0x0e, 0x00, 0x80, 0x01, 0x1c, 0x01, 0x23, 0x88, 0x68, 0x58, 0x40, -0x88, 0x60, 0xca, 0x68, 0x01, 0x3a, 0xca, 0x60, 0x0a, 0x69, 0x01, 0x3a, -0x80, 0x00, 0x0a, 0x61, 0x42, 0x18, 0xd0, 0x6b, 0x53, 0x6b, 0xc0, 0x46, -0xcb, 0x62, 0x0b, 0x68, 0x9b, 0x00, 0x59, 0x18, 0x49, 0x6c, 0x53, 0x6c, -0xc9, 0x18, 0x51, 0x64, 0x70, 0x47, 0x8a, 0x68, 0x92, 0x00, 0x52, 0x18, -0xd3, 0x6b, 0x83, 0x42, 0x17, 0xd1, 0xd0, 0x1d, 0x3d, 0x30, 0x0a, 0x68, -0x92, 0x00, 0x52, 0x18, 0x52, 0x6c, 0x03, 0x68, 0x9a, 0x1a, 0x02, 0x60, -0x01, 0x23, 0x88, 0x68, 0x58, 0x40, 0x88, 0x60, 0xca, 0x68, 0x01, 0x32, -0xca, 0x60, 0x0a, 0x69, 0x01, 0x32, 0x80, 0x00, 0x40, 0x18, 0x0a, 0x61, -0x40, 0x6b, 0xc0, 0x46, 0xc8, 0x62, 0x70, 0x47, 0xb8, 0xb5, 0x04, 0x1c, -0x1d, 0x1c, 0x17, 0x1c, 0x08, 0x1c, 0x39, 0x1c, 0xff, 0xf7, 0xd9, 0xff, -0x00, 0x20, 0x29, 0x1c, 0x00, 0xf0, 0x80, 0xfe, 0x01, 0x20, 0xf9, 0x1d, -0x19, 0x31, 0x48, 0x71, 0x80, 0x06, 0x60, 0x60, 0x00, 0x20, 0xa0, 0x61, -0x06, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x06, 0x48, 0x01, 0x6d, 0x42, 0x6d, -0x05, 0x4b, 0x00, 0x20, 0x00, 0xf0, 0x66, 0xfe, 0xb8, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0x04, 0x00, 0x12, 0x02, 0xf8, 0x28, 0x00, 0x80, -0x44, 0x80, 0x20, 0x40, 0x06, 0x49, 0x0a, 0x68, 0x10, 0x18, 0x08, 0x60, +0x06, 0xca, 0x01, 0xf0, 0x01, 0xf9, 0x08, 0x98, 0x36, 0x18, 0xa8, 0x68, +0x8c, 0x23, 0x18, 0x40, 0x02, 0xd0, 0x01, 0x20, 0x40, 0x06, 0x00, 0xe0, +0x92, 0x48, 0x01, 0x22, 0x02, 0x43, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, +0x8e, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, 0xec, 0xf8, +0x00, 0x20, 0x02, 0x90, 0x15, 0xe0, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd0, +0x01, 0x20, 0x40, 0x06, 0x00, 0xe0, 0x88, 0x48, 0x08, 0x9a, 0x02, 0x43, +0x00, 0xe0, 0x08, 0x9a, 0xc0, 0x46, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, +0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0, 0xd5, 0xf8, 0x08, 0x98, +0x36, 0x18, 0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, +0x00, 0xf0, 0x14, 0xfa, 0x07, 0x1c, 0x68, 0x68, 0x80, 0x0e, 0x6b, 0xd2, +0x0a, 0x98, 0xc0, 0x46, 0x09, 0x90, 0x0c, 0x99, 0x88, 0x42, 0x5c, 0xda, +0x0d, 0x98, 0x09, 0x99, 0x88, 0x42, 0x03, 0xd0, 0x7a, 0x88, 0x1e, 0xe0, +0x5f, 0xe0, 0x5e, 0xe0, 0x78, 0x88, 0x01, 0x22, 0x52, 0x06, 0x02, 0x43, +0xa9, 0x68, 0x8c, 0x23, 0x19, 0x40, 0x02, 0xd1, 0x09, 0x23, 0x5b, 0x04, +0x1a, 0x43, 0xb1, 0x07, 0x89, 0x0f, 0x0e, 0xd0, 0xc3, 0x06, 0xdb, 0x0e, +0x08, 0xd0, 0x1e, 0x2b, 0x09, 0xdb, 0x1e, 0x2b, 0x02, 0xd1, 0x03, 0x29, +0x05, 0xd1, 0x01, 0xe0, 0x02, 0x29, 0x02, 0xd3, 0x01, 0x21, 0x02, 0x91, +0x02, 0x1c, 0x09, 0x98, 0x00, 0x28, 0x02, 0xd1, 0x01, 0x23, 0xdb, 0x05, +0x1a, 0x43, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d, +0x06, 0xca, 0x01, 0xf0, 0x8f, 0xf8, 0x78, 0x88, 0x86, 0x19, 0x10, 0x37, +0x02, 0x98, 0x00, 0x28, 0x14, 0xd0, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, +0x02, 0xd0, 0x01, 0x20, 0x40, 0x06, 0x00, 0xe0, 0x57, 0x48, 0x01, 0x22, +0x02, 0x43, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0x53, 0x48, 0x01, 0x6d, +0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, 0x76, 0xf8, 0x00, 0x20, 0x02, 0x90, +0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0xb6, 0xf9, +0x07, 0x1c, 0x09, 0x98, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x09, 0x90, +0x0c, 0x99, 0x88, 0x42, 0xa2, 0xdb, 0x68, 0x68, 0x30, 0x43, 0x01, 0x04, +0x09, 0x0c, 0x68, 0x60, 0xe8, 0x6a, 0x00, 0xf0, +0x7b, 0xfa, 0x28, 0xe0, 0x27, 0xe0, 0xa8, 0x68, 0x00, 0x09, 0x14, 0xd3, +0x68, 0x68, 0x80, 0x0e, 0x15, 0xd2, 0x01, 0x9a, 0x00, 0x2a, 0x12, 0xd0, +0x01, 0x9a, 0x50, 0x6b, 0x0b, 0x9b, 0x21, 0x1c, 0x3a, 0x1c, 0xff, 0xf7, +0x89, 0xf9, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x64, 0x01, 0x9a, 0x0b, 0x9b, +0xc0, 0x46, 0x93, 0x63, 0x03, 0xe0, 0xe8, 0x6a, 0x31, 0x1c, 0x00, 0xf0, +0x5d, 0xfa, 0x68, 0x68, 0x30, 0x43, 0x68, 0x60, 0xa8, 0x69, 0xb0, 0x42, +0x05, 0xd9, 0x00, 0x04, 0x00, 0x0c, 0x80, 0x1b, 0x00, 0xf0, 0xee, 0xf9, +0xae, 0x61, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x0b, 0xd0, 0x2f, 0x4a, +0xc0, 0x46, 0x00, 0x92, 0x04, 0x98, 0xc3, 0x1f, 0x05, 0x3b, 0x2a, 0x48, +0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, 0x23, 0xf8, 0x01, 0x23, +0x9b, 0x07, 0x20, 0x6d, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xa0, 0x61, +0xe1, 0x69, 0x81, 0x42, 0x12, 0xd0, 0x22, 0x69, 0x02, 0x2a, 0x0f, 0xd2, +0x41, 0x1a, 0x01, 0xd5, 0x60, 0x6d, 0x41, 0x18, 0x20, 0x1c, 0xff, 0xf7, +0x3f, 0xfb, 0xe1, 0x69, 0x40, 0x18, 0xe0, 0x61, 0x61, 0x6d, 0x88, 0x42, +0x24, 0xd3, 0x40, 0x1a, 0xe0, 0x61, 0x21, 0xe0, 0x81, 0x42, 0x1f, 0xd1, +0x20, 0x69, 0x02, 0x28, 0x1c, 0xd2, 0x01, 0x20, 0x60, 0x61, 0x18, 0x48, +0x41, 0x69, 0xe2, 0x6c, 0x0a, 0x43, 0x42, 0x61, 0x81, 0x69, 0xe3, 0x6c, +0x99, 0x43, 0x81, 0x61, 0x01, 0x21, 0x09, 0x05, 0xca, 0x60, 0x80, 0x69, +0xc0, 0x46, 0x08, 0x61, 0x8b, 0x02, 0x20, 0x6d, 0x18, 0x43, 0x00, 0x68, +0xc0, 0x46, 0xa0, 0x61, 0xe1, 0x69, 0x81, 0x42, 0x02, 0xd0, 0x20, 0x1c, +0xff, 0xf7, 0xcc, 0xfa, 0x28, 0x1c, 0x00, 0xf0, 0x0f, 0xf9, 0x0c, 0x98, +0x05, 0x99, 0x40, 0x18, 0x00, 0x01, 0x10, 0x30, 0x68, 0x61, 0x13, 0xb0, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, +0x7c, 0x29, 0x00, 0x80, 0x00, 0x00, 0x12, 0x02, 0x04, 0x00, 0x52, 0x02, +0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb5, 0x40, 0x20, 0x2d, 0x49, 0xc0, 0x46, +0x08, 0x60, 0x00, 0xf0, 0x03, 0xf9, 0x07, 0x1c, 0x81, 0x69, 0x44, 0x6a, +0xa0, 0x6f, 0x00, 0xf0, 0x45, 0xfe, 0x00, 0x20, 0xe1, 0x1d, 0x19, 0x31, +0x48, 0x71, 0x79, 0x68, 0xc9, 0x0e, 0x09, 0xd3, 0xf8, 0x6a, 0x00, 0x01, +0x24, 0x49, 0x40, 0x18, 0x24, 0x4b, 0xc0, 0x18, 0x01, 0x68, 0x01, 0x39, +0x01, 0x60, 0x36, 0xe0, 0xe1, 0x6d, 0x09, 0x68, 0x22, 0x6e, 0xc0, 0x46, +0x11, 0x60, 0x20, 0x4e, 0xf5, 0x1d, 0x79, 0x35, 0x01, 0x23, 0xe9, 0x6b, +0x19, 0x43, 0xe9, 0x63, 0xb9, 0x6a, 0xe2, 0x6d, 0xc0, 0x46, 0x11, 0x60, +0xb9, 0x6a, 0x22, 0x6e, 0xc0, 0x46, 0x11, 0x60, 0x61, 0x69, 0x00, 0x29, +0x04, 0xd1, 0xa9, 0x6b, 0x01, 0x31, 0xa9, 0x63, 0x08, 0x29, 0x07, 0xd3, +0xa8, 0x63, 0x01, 0x20, 0x00, 0xf0, 0x86, 0xf8, 0xe8, 0x6b, 0x40, 0x08, +0x40, 0x00, 0xe8, 0x63, 0x78, 0x68, 0x81, 0x0e, 0x0f, 0xd2, 0x0b, 0x23, +0x1b, 0x02, 0xf1, 0x18, 0xc9, 0x68, 0x00, 0x29, 0x06, 0xd0, 0x00, 0x08, +0x04, 0xd2, 0x20, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x43, 0xf8, 0x02, 0xe0, +0x38, 0x1c, 0x00, 0xf0, 0x05, 0xfa, 0x38, 0x1c, 0xfb, 0xf7, 0x10, 0xfc, +0x20, 0x1c, 0x00, 0xf0, 0x0b, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x00, 0x00, 0x00, 0xb0, 0xa0, 0x1c, 0x00, 0x80, 0xb4, 0x0c, 0x00, 0x00, +0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x07, 0x1c, 0xf8, 0x1d, 0x19, 0x30, +0x01, 0x79, 0x00, 0x29, 0x04, 0xd0, 0x00, 0x21, +0x01, 0x71, 0x38, 0x1c, 0xff, 0xf7, 0x56, 0xfb, 0xf8, 0x68, 0x02, 0x28, +0x0d, 0xd0, 0xb8, 0x68, 0x80, 0x00, 0xc2, 0x19, 0x50, 0x6c, 0x00, 0x28, +0x11, 0xd0, 0xb8, 0x6a, 0x41, 0x78, 0x09, 0x01, 0x10, 0x31, 0x52, 0x6b, +0x10, 0x1a, 0x88, 0x42, 0x05, 0xd3, 0x38, 0x1c, 0xff, 0xf7, 0x42, 0xfb, +0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0xff, 0xf7, 0x28, 0xfa, +0xf8, 0xe7, 0x78, 0x68, 0x80, 0x00, 0xc0, 0x19, 0xc0, 0x6b, 0xc0, 0x46, +0xb8, 0x62, 0xf1, 0xe7, 0xb0, 0xb5, 0x87, 0xb0, 0x0f, 0x1c, 0x80, 0x6f, +0xc0, 0x46, 0x00, 0x90, 0x00, 0x24, 0x13, 0x4d, 0x0b, 0x23, 0x1b, 0x02, +0xe8, 0x18, 0x80, 0x69, 0x00, 0x28, 0x17, 0xd0, 0x69, 0x46, 0xa2, 0x00, +0x52, 0x19, 0x0b, 0x23, 0x1b, 0x02, 0xd2, 0x18, 0x92, 0x69, 0x38, 0x1c, +0x00, 0xf0, 0x92, 0xfb, 0x00, 0x28, 0x09, 0xd1, 0x01, 0x34, 0xa0, 0x00, +0x40, 0x19, 0x0b, 0x23, 0x1b, 0x02, 0xc0, 0x18, 0x80, 0x69, 0x00, 0x28, +0xea, 0xd1, 0x01, 0xe0, 0x01, 0x28, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, +0x9d, 0xf9, 0x07, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x68, 0x0e, 0x00, 0x80, 0xb8, 0xb5, 0xc2, 0x07, 0xd2, 0x0f, 0x16, 0x4c, +0x16, 0x49, 0x01, 0xd0, 0x08, 0x22, 0x08, 0xe0, 0x82, 0x08, 0x05, 0xd3, +0x0c, 0x22, 0xa4, 0x18, 0x0b, 0x68, 0xdf, 0x1d, 0x15, 0x37, 0x03, 0xe0, +0x1c, 0x22, 0x0b, 0x68, 0xdf, 0x1d, 0x09, 0x37, 0x0f, 0x4b, 0x1d, 0x78, +0x00, 0x2d, 0x13, 0xd0, 0x5b, 0x78, 0x00, 0x2b, 0x10, 0xd0, 0x01, 0x23, +0x5b, 0x06, 0x1a, 0x43, 0x00, 0x28, 0x01, 0xd1, 0x5b, 0x08, 0x1a, 0x43, +0x00, 0x92, 0x4a, 0x68, 0x01, 0x20, 0x39, 0x1c, 0x23, 0x1c, 0x00, 0xf0, +0xdf, 0xfe, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x03, 0x23, 0x1b, 0x06, +0x1a, 0x43, 0xf1, 0xe7, 0x3c, 0xef, 0x20, 0x40, 0x7c, 0x29, 0x00, 0x80, +0xf8, 0x0e, 0x00, 0x80, 0x00, 0x21, 0xc1, 0x61, 0x05, 0x49, 0x8a, 0x68, +0x00, 0x2a, 0x01, 0xd1, 0x88, 0x60, 0x02, 0xe0, 0xca, 0x68, 0xc0, 0x46, +0xd0, 0x61, 0xc8, 0x60, 0x70, 0x47, 0x00, 0x00, 0x28, 0x0f, 0x00, 0x80, +0x03, 0x49, 0x88, 0x68, 0x00, 0x28, 0x02, 0xd0, 0xc2, 0x69, 0xc0, 0x46, +0x8a, 0x60, 0x70, 0x47, 0x28, 0x0f, 0x00, 0x80, 0x01, 0x1c, 0x01, 0x23, +0x88, 0x68, 0x58, 0x40, 0x88, 0x60, 0xca, 0x68, 0x01, 0x3a, 0xca, 0x60, +0x0a, 0x69, 0x01, 0x3a, 0x80, 0x00, 0x0a, 0x61, 0x42, 0x18, 0xd0, 0x6b, +0x53, 0x6b, 0xc0, 0x46, 0xcb, 0x62, 0x0b, 0x68, 0x9b, 0x00, 0x59, 0x18, +0x49, 0x6c, 0x53, 0x6c, 0xc9, 0x18, 0x51, 0x64, 0x70, 0x47, 0x8a, 0x68, +0x92, 0x00, 0x52, 0x18, 0xd3, 0x6b, 0x83, 0x42, 0x17, 0xd1, 0xd0, 0x1d, +0x3d, 0x30, 0x0a, 0x68, 0x92, 0x00, 0x52, 0x18, 0x52, 0x6c, 0x03, 0x68, +0x9a, 0x1a, 0x02, 0x60, 0x01, 0x23, 0x88, 0x68, 0x58, 0x40, 0x88, 0x60, +0xca, 0x68, 0x01, 0x32, 0xca, 0x60, 0x0a, 0x69, 0x01, 0x32, 0x80, 0x00, +0x40, 0x18, 0x0a, 0x61, 0x40, 0x6b, 0xc0, 0x46, 0xc8, 0x62, 0x70, 0x47, +0xb8, 0xb5, 0x04, 0x1c, 0x1d, 0x1c, 0x17, 0x1c, 0x08, 0x1c, 0x39, 0x1c, +0xff, 0xf7, 0xd9, 0xff, 0x00, 0x20, 0x29, 0x1c, 0x00, 0xf0, 0x7c, 0xfe, +0x01, 0x20, 0xf9, 0x1d, 0x19, 0x31, 0x48, 0x71, 0x80, 0x06, 0x60, 0x60, +0x00, 0x20, 0xa0, 0x61, 0x06, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x06, 0x48, +0x01, 0x6d, 0x42, 0x6d, 0x05, 0x4b, 0x00, 0x20, 0x00, 0xf0, 0x62, 0xfe, +0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x04, 0x00, 0x12, 0x02, 0x7c, 0x29, 0x00, 0x80, 0x44, 0x80, 0x20, 0x40, +0x06, 0x49, 0x0a, 0x68, 0x10, 0x18, 0x08, 0x60, 0x01, 0x23, 0x5b, 0x02, +0x98, 0x42, 0x03, 0xd9, 0x03, 0x49, 0x0a, 0x79, 0x01, 0x32, 0x0a, 0x71, +0x70, 0x47, 0x00, 0x00, 0xe4, 0x2d, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, +0x80, 0x08, 0x80, 0x00, 0x06, 0x49, 0x0a, 0x68, 0x10, 0x18, 0x08, 0x60, 0x01, 0x23, 0x5b, 0x02, 0x98, 0x42, 0x03, 0xd9, 0x03, 0x49, 0x0a, 0x79, -0x01, 0x32, 0x0a, 0x71, 0x70, 0x47, 0x00, 0x00, 0x50, 0x2d, 0x00, 0x80, -0xa0, 0x82, 0x20, 0x40, 0x80, 0x08, 0x80, 0x00, 0x06, 0x49, 0x0a, 0x68, -0x10, 0x18, 0x08, 0x60, 0x01, 0x23, 0x5b, 0x02, 0x98, 0x42, 0x03, 0xd9, -0x03, 0x49, 0x0a, 0x79, 0x01, 0x32, 0x0a, 0x71, 0x70, 0x47, 0x00, 0x00, -0x50, 0x2d, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x03, 0x30, 0x80, 0x08, -0x80, 0x00, 0x06, 0x49, 0x0a, 0x68, 0x10, 0x18, 0x08, 0x60, 0x01, 0x23, -0x5b, 0x02, 0x98, 0x42, 0x03, 0xd9, 0x03, 0x49, 0x0a, 0x79, 0x01, 0x32, -0x0a, 0x71, 0x70, 0x47, 0x50, 0x2d, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, -0x02, 0x48, 0x41, 0x79, 0x01, 0x31, 0x41, 0x71, -0x70, 0x47, 0x00, 0x00, 0xa0, 0x82, 0x20, 0x40, 0x90, 0xb4, 0x82, 0x00, -0x17, 0x4b, 0x9a, 0x58, 0x8b, 0x07, 0x02, 0xd0, 0x89, 0x08, 0x0b, 0x1d, -0x01, 0xe0, 0x89, 0x08, 0xcb, 0x1c, 0x11, 0x69, 0xd7, 0x68, 0x12, 0x4c, -0x80, 0x00, 0x20, 0x58, 0x40, 0x68, 0xb9, 0x42, 0x03, 0xd1, 0x81, 0x42, -0x19, 0xd9, 0x11, 0x68, 0x17, 0xe0, 0x00, 0x24, 0xb9, 0x42, 0x09, 0xd9, -0x81, 0x42, 0x12, 0xd9, 0x11, 0x68, 0x78, 0x1a, 0x00, 0xd5, 0x03, 0x30, -0x80, 0x10, 0x98, 0x42, 0x0b, 0xd8, 0x07, 0xe0, 0x81, 0x42, 0x05, 0xd8, -0x78, 0x1a, 0x00, 0xd5, 0x03, 0x30, 0x80, 0x10, 0x98, 0x42, 0x02, 0xd8, -0x20, 0x1c, 0x90, 0xbc, 0x70, 0x47, 0xc8, 0x1d, 0x05, 0x30, 0xfa, 0xe7, -0xf0, 0x03, 0x00, 0x80, 0x80, 0xb5, 0x80, 0x00, 0x0f, 0x4a, 0x17, 0x58, -0x88, 0x07, 0x02, 0xd0, 0x88, 0x08, 0x04, 0x30, 0x01, 0xe0, 0x88, 0x08, -0x03, 0x30, 0x39, 0x69, 0x7a, 0x68, 0x91, 0x42, 0x09, 0xd9, 0x39, 0x68, -0xc0, 0x46, 0x39, 0x61, 0xf9, 0x68, 0x7a, 0x68, 0x91, 0x42, 0x02, 0xd9, -0x39, 0x68, 0xc0, 0x46, 0xf9, 0x60, 0x81, 0x00, 0x38, 0x69, 0x00, 0xf0, -0xd5, 0xfd, 0x38, 0x61, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, -0xf0, 0x03, 0x00, 0x80, 0x90, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x01, 0x40, -0x0c, 0x0f, 0x01, 0x04, 0x09, 0x0c, 0x01, 0x22, 0x92, 0x07, 0x02, 0x40, -0xa3, 0x00, 0x1c, 0x4f, 0xff, 0x58, 0x89, 0x07, 0x89, 0x0f, 0x00, 0x04, -0x00, 0x0c, 0x80, 0x08, 0x00, 0x29, 0x00, 0xd0, 0x01, 0x30, 0x00, 0x2a, -0x01, 0xd0, 0x02, 0x30, 0x00, 0xe0, 0x03, 0x30, 0xf9, 0x68, 0x7a, 0x68, +0x01, 0x32, 0x0a, 0x71, 0x70, 0x47, 0x00, 0x00, 0xe4, 0x2d, 0x00, 0x80, +0xa0, 0x82, 0x20, 0x40, 0x03, 0x30, 0x80, 0x08, 0x80, 0x00, 0x06, 0x49, +0x0a, 0x68, 0x10, 0x18, 0x08, 0x60, 0x01, 0x23, 0x5b, 0x02, 0x98, 0x42, +0x03, 0xd9, 0x03, 0x49, 0x0a, 0x79, 0x01, 0x32, 0x0a, 0x71, 0x70, 0x47, +0xe4, 0x2d, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x02, 0x48, 0x41, 0x79, +0x01, 0x31, 0x41, 0x71, 0x70, 0x47, 0x00, 0x00, 0xa0, 0x82, 0x20, 0x40, +0x90, 0xb4, 0x82, 0x00, 0x17, 0x4b, 0x9a, 0x58, 0x8b, 0x07, 0x02, 0xd0, +0x89, 0x08, 0x0b, 0x1d, 0x01, 0xe0, 0x89, 0x08, 0xcb, 0x1c, 0x11, 0x69, +0xd7, 0x68, 0x12, 0x4c, 0x80, 0x00, 0x20, 0x58, 0x40, 0x68, 0xb9, 0x42, +0x03, 0xd1, 0x81, 0x42, 0x19, 0xd9, 0x11, 0x68, 0x17, 0xe0, 0x00, 0x24, +0xb9, 0x42, 0x09, 0xd9, 0x81, 0x42, 0x12, 0xd9, 0x11, 0x68, 0x78, 0x1a, +0x00, 0xd5, 0x03, 0x30, 0x80, 0x10, 0x98, 0x42, 0x0b, 0xd8, 0x07, 0xe0, +0x81, 0x42, 0x05, 0xd8, 0x78, 0x1a, 0x00, 0xd5, 0x03, 0x30, 0x80, 0x10, +0x98, 0x42, 0x02, 0xd8, 0x20, 0x1c, 0x90, 0xbc, 0x70, 0x47, 0xc8, 0x1d, +0x05, 0x30, 0xfa, 0xe7, 0x70, 0x04, 0x00, 0x80, 0x80, 0xb5, 0x80, 0x00, +0x0f, 0x4a, 0x17, 0x58, 0x88, 0x07, 0x02, 0xd0, 0x88, 0x08, 0x04, 0x30, +0x01, 0xe0, 0x88, 0x08, 0x03, 0x30, 0x39, 0x69, 0x7a, 0x68, 0x91, 0x42, +0x09, 0xd9, 0x39, 0x68, 0xc0, 0x46, 0x39, 0x61, 0xf9, 0x68, 0x7a, 0x68, 0x91, 0x42, 0x02, 0xd9, 0x39, 0x68, 0xc0, 0x46, 0xf9, 0x60, 0x81, 0x00, -0xf8, 0x68, 0x00, 0xf0, 0xa9, 0xfd, 0xf8, 0x60, 0x0f, 0x48, 0x00, 0x69, -0x00, 0x28, 0x05, 0xd0, 0x01, 0x20, 0xa0, 0x40, 0x02, 0xd0, 0x20, 0x1c, -0xfe, 0xf7, 0xc8, 0xfc, 0x0b, 0x49, 0xc8, 0x1d, 0x19, 0x30, 0x03, 0x79, -0x00, 0x22, 0x00, 0x2b, 0x05, 0xd1, 0x09, 0x49, 0xc8, 0x1d, 0x19, 0x30, -0x03, 0x79, 0x00, 0x2b, 0x03, 0xd0, 0x02, 0x71, 0x08, 0x1c, 0xff, 0xf7, -0x79, 0xf9, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0x03, 0x00, 0x80, -0x3c, 0x2c, 0x00, 0x80, 0xd0, 0x2c, 0x00, 0x80, 0x50, 0x2c, 0x00, 0x80, -0xb0, 0xb5, 0x2b, 0x49, 0x09, 0x78, 0x00, 0x29, 0x03, 0xd1, 0x41, 0x68, -0x29, 0x4b, 0x19, 0x43, 0x41, 0x60, 0x81, 0x68, 0x49, 0x08, 0x02, 0xd3, -0x09, 0x21, 0x09, 0x04, 0x01, 0xe0, 0x0d, 0x21, 0x09, 0x04, 0x0c, 0xc8, -0x08, 0x38, 0x19, 0x43, 0x87, 0x68, 0xbb, 0x0a, 0x03, 0xd3, 0x43, 0x68, -0x5b, 0x08, 0x00, 0xd3, 0x01, 0x31, 0x40, 0x68, 0x03, 0x23, 0x1b, 0x07, -0x18, 0x40, 0x07, 0x0f, 0xf8, 0x00, 0x1d, 0x4c, 0x00, 0x19, 0x23, 0x68, -0xc0, 0x18, 0x50, 0x30, 0x00, 0x79, 0x01, 0x28, 0x10, 0xd1, 0x60, 0x68, -0x01, 0x28, 0x0d, 0xd0, 0x10, 0x1c, 0x00, 0xf0, 0x71, 0xf8, 0x38, 0x01, -0x00, 0x19, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x41, 0x6b, 0x01, 0x39, -0x41, 0x63, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x01, 0x00, 0x19, -0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x03, 0x6b, 0x5d, 0x1c, 0x05, 0x63, -0xbd, 0x02, 0x2d, 0x19, 0xdb, 0x00, 0xeb, 0x18, 0x80, 0x33, 0x19, 0x63, -0xda, 0x62, 0x81, 0x6b, 0x01, 0x31, 0x81, 0x63, 0x01, 0x21, 0xb9, 0x40, -0x22, 0x68, 0x11, 0x43, 0x21, 0x60, 0x01, 0x6b, 0x80, 0x29, 0xe2, 0xd3, -0x00, 0x21, 0x01, 0x63, 0xdf, 0xe7, 0x00, 0x00, -0xa8, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x1c, 0x1c, 0x00, 0x80, -0xf0, 0xb5, 0x1f, 0x4e, 0x70, 0x68, 0x00, 0x28, 0x36, 0xd1, 0x00, 0x24, -0xb1, 0x68, 0x48, 0x1c, 0xc9, 0x00, 0x89, 0x19, 0xb0, 0x60, 0x32, 0x68, -0x89, 0x18, 0x60, 0x31, 0x0d, 0x7b, 0x08, 0x28, 0x00, 0xd3, 0xb4, 0x60, -0x28, 0x01, 0x80, 0x19, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x87, 0x6b, -0x00, 0x2f, 0x21, 0xd0, 0xc1, 0x6a, 0x4b, 0x1c, 0xaa, 0x02, 0x92, 0x19, -0xc9, 0x00, 0x51, 0x18, 0x80, 0x31, 0xc3, 0x62, 0xca, 0x6a, 0x09, 0x6b, -0x01, 0x3f, 0x87, 0x63, 0x80, 0x2b, 0x00, 0xd3, 0xc4, 0x62, 0x00, 0x2f, -0x06, 0xd1, 0x01, 0x27, 0xaf, 0x40, 0x3b, 0x1c, 0xdb, 0x43, 0x37, 0x68, -0x3b, 0x40, 0x33, 0x60, 0x43, 0x6b, 0x01, 0x3b, 0x43, 0x63, 0x10, 0x1c, -0x37, 0x1c, 0x00, 0xf0, 0x09, 0xf8, 0x78, 0x68, 0x00, 0x28, 0xc9, 0xd0, -0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x80, -0xf0, 0xb5, 0xcd, 0x0f, 0xed, 0x07, 0x01, 0x24, 0x00, 0x27, 0x2f, 0x4b, -0x2f, 0x4a, 0x00, 0x2d, 0x1d, 0xd0, 0xd8, 0x6a, 0x01, 0x30, 0xd8, 0x62, -0x10, 0x1c, 0x52, 0x69, 0x00, 0x2a, 0x12, 0xd0, 0x02, 0x69, 0x53, 0x1c, -0x92, 0x00, 0x12, 0x18, 0x03, 0x61, 0x91, 0x61, 0x41, 0x69, 0x01, 0x31, -0x41, 0x61, 0x02, 0x69, 0x0f, 0x2a, 0x00, 0xd3, 0x07, 0x61, 0x0f, 0x29, -0x00, 0xd3, 0x44, 0x60, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x08, 0x1c, -0xff, 0xf7, 0xee, 0xfe, 0xf8, 0xe7, 0x15, 0x69, 0x6e, 0x1c, 0xad, 0x00, -0xad, 0x18, 0x16, 0x61, 0xa9, 0x61, 0x55, 0x69, 0x01, 0x35, 0x55, 0x61, -0x16, 0x69, 0x0f, 0x2e, 0x00, 0xd3, 0x17, 0x61, 0x0f, 0x2d, 0x00, 0xd3, -0x54, 0x60, 0x8c, 0x02, 0xa4, 0x0a, 0x17, 0x4f, 0x3a, 0x6f, 0xfd, 0x68, -0xf9, 0x1d, 0x79, 0x31, 0x01, 0x2d, 0x0e, 0xd1, 0xdb, 0x6d, 0x5b, 0x08, -0x0b, 0xd3, 0x8b, 0x88, 0x00, 0x2b, 0x08, 0xd1, 0x03, 0x3b, 0xfd, 0x6f, -0x2b, 0x40, 0xfb, 0x67, 0x0f, 0x4d, 0xc0, 0x46, 0x2b, 0x60, 0x14, 0x23, -0x8b, 0x80, 0x10, 0x60, 0x80, 0x07, 0x80, 0x0a, 0x20, 0x43, 0x03, 0x04, -0x00, 0xd0, 0x01, 0x38, 0x50, 0x60, 0xc9, 0x69, 0x08, 0x32, 0x91, 0x42, -0x00, 0xd8, 0x08, 0x4a, 0x00, 0x0d, 0x02, 0xd3, 0x51, 0x20, 0x80, 0x03, -0x82, 0x61, 0x3a, 0x67, 0xbc, 0xe7, 0x00, 0x00, 0x10, 0x2a, 0x00, 0x80, -0x1c, 0x1c, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, -0x24, 0xa7, 0x20, 0x40, 0xb0, 0xb5, 0x00, 0x28, 0x04, 0xd1, 0x01, 0x20, -0xc0, 0x05, 0x16, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x15, 0x4c, 0x00, 0x25, +0x38, 0x69, 0x00, 0xf0, 0xd1, 0xfd, 0x38, 0x61, 0x80, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x70, 0x04, 0x00, 0x80, 0x90, 0xb5, 0x03, 0x21, +0x09, 0x07, 0x01, 0x40, 0x0c, 0x0f, 0x01, 0x04, 0x09, 0x0c, 0x01, 0x22, +0x92, 0x07, 0x02, 0x40, 0xa3, 0x00, 0x1c, 0x4f, 0xff, 0x58, 0x89, 0x07, +0x89, 0x0f, 0x00, 0x04, 0x00, 0x0c, 0x80, 0x08, 0x00, 0x29, 0x00, 0xd0, +0x01, 0x30, 0x00, 0x2a, 0x01, 0xd0, 0x02, 0x30, 0x00, 0xe0, 0x03, 0x30, +0xf9, 0x68, 0x7a, 0x68, 0x91, 0x42, 0x02, 0xd9, 0x39, 0x68, 0xc0, 0x46, +0xf9, 0x60, 0x81, 0x00, 0xf8, 0x68, 0x00, 0xf0, 0xa5, 0xfd, 0xf8, 0x60, +0x0f, 0x48, 0x00, 0x69, 0x00, 0x28, 0x05, 0xd0, 0x01, 0x20, 0xa0, 0x40, +0x02, 0xd0, 0x20, 0x1c, 0xfe, 0xf7, 0xca, 0xfc, 0x0b, 0x49, 0xc8, 0x1d, +0x19, 0x30, 0x03, 0x79, 0x00, 0x22, 0x00, 0x2b, 0x05, 0xd1, 0x09, 0x49, +0xc8, 0x1d, 0x19, 0x30, 0x03, 0x79, 0x00, 0x2b, 0x03, 0xd0, 0x02, 0x71, +0x08, 0x1c, 0xff, 0xf7, 0x79, 0xf9, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x70, 0x04, 0x00, 0x80, 0xd0, 0x2c, 0x00, 0x80, 0x64, 0x2d, 0x00, 0x80, +0xe4, 0x2c, 0x00, 0x80, 0xb0, 0xb5, 0x2b, 0x49, 0x09, 0x79, 0x00, 0x29, +0x03, 0xd1, 0x41, 0x68, 0x29, 0x4b, 0x19, 0x43, 0x41, 0x60, 0x81, 0x68, +0x49, 0x08, 0x02, 0xd3, 0x09, 0x21, 0x09, 0x04, 0x01, 0xe0, 0x0d, 0x21, +0x09, 0x04, 0x0c, 0xc8, 0x08, 0x38, 0x19, 0x43, +0x87, 0x68, 0xbb, 0x0a, 0x03, 0xd3, 0x43, 0x68, 0x5b, 0x08, 0x00, 0xd3, +0x01, 0x31, 0x40, 0x68, 0x03, 0x23, 0x1b, 0x07, 0x18, 0x40, 0x07, 0x0f, +0xf8, 0x00, 0x1d, 0x4c, 0x00, 0x19, 0x23, 0x68, 0xc0, 0x18, 0x50, 0x30, +0x00, 0x79, 0x01, 0x28, 0x10, 0xd1, 0x60, 0x68, 0x01, 0x28, 0x0d, 0xd0, +0x10, 0x1c, 0x00, 0xf0, 0x71, 0xf8, 0x38, 0x01, 0x00, 0x19, 0x19, 0x23, +0xdb, 0x01, 0xc0, 0x18, 0x41, 0x6b, 0x01, 0x39, 0x41, 0x63, 0xb0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x38, 0x01, 0x00, 0x19, 0x19, 0x23, 0xdb, 0x01, +0xc0, 0x18, 0x03, 0x6b, 0x5d, 0x1c, 0x05, 0x63, 0xbd, 0x02, 0x2d, 0x19, +0xdb, 0x00, 0xeb, 0x18, 0x80, 0x33, 0x19, 0x63, 0xda, 0x62, 0x81, 0x6b, +0x01, 0x31, 0x81, 0x63, 0x01, 0x21, 0xb9, 0x40, 0x22, 0x68, 0x11, 0x43, +0x21, 0x60, 0x01, 0x6b, 0x80, 0x29, 0xe2, 0xd3, 0x00, 0x21, 0x01, 0x63, +0xdf, 0xe7, 0x00, 0x00, 0x28, 0x0f, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, +0xa0, 0x1c, 0x00, 0x80, 0xf0, 0xb5, 0x1f, 0x4e, 0x70, 0x68, 0x00, 0x28, +0x36, 0xd1, 0x00, 0x24, 0xb1, 0x68, 0x48, 0x1c, 0xc9, 0x00, 0x89, 0x19, +0xb0, 0x60, 0x32, 0x68, 0x89, 0x18, 0x60, 0x31, 0x0d, 0x7b, 0x08, 0x28, +0x00, 0xd3, 0xb4, 0x60, 0x28, 0x01, 0x80, 0x19, 0x19, 0x23, 0xdb, 0x01, +0xc0, 0x18, 0x87, 0x6b, 0x00, 0x2f, 0x21, 0xd0, 0xc1, 0x6a, 0x4b, 0x1c, +0xaa, 0x02, 0x92, 0x19, 0xc9, 0x00, 0x51, 0x18, 0x80, 0x31, 0xc3, 0x62, +0xca, 0x6a, 0x09, 0x6b, 0x01, 0x3f, 0x87, 0x63, 0x80, 0x2b, 0x00, 0xd3, +0xc4, 0x62, 0x00, 0x2f, 0x06, 0xd1, 0x01, 0x27, 0xaf, 0x40, 0x3b, 0x1c, +0xdb, 0x43, 0x37, 0x68, 0x3b, 0x40, 0x33, 0x60, 0x43, 0x6b, 0x01, 0x3b, +0x43, 0x63, 0x10, 0x1c, 0x37, 0x1c, 0x00, 0xf0, 0x09, 0xf8, 0x78, 0x68, +0x00, 0x28, 0xc9, 0xd0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0xa0, 0x1c, 0x00, 0x80, 0xf0, 0xb5, 0xcd, 0x0f, 0xed, 0x07, 0x01, 0x24, +0x00, 0x27, 0x2e, 0x4b, 0x2e, 0x4a, 0x00, 0x2d, 0x1d, 0xd0, 0xd8, 0x6a, +0x01, 0x30, 0xd8, 0x62, 0x10, 0x1c, 0x52, 0x69, 0x00, 0x2a, 0x12, 0xd0, +0x02, 0x69, 0x53, 0x1c, 0x92, 0x00, 0x12, 0x18, 0x03, 0x61, 0x91, 0x61, +0x41, 0x69, 0x01, 0x31, 0x41, 0x61, 0x02, 0x69, 0x0f, 0x2a, 0x00, 0xd3, +0x07, 0x61, 0x0f, 0x29, 0x00, 0xd3, 0x44, 0x60, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x08, 0x1c, 0xff, 0xf7, 0xee, 0xfe, 0xf8, 0xe7, 0x15, 0x69, +0x6e, 0x1c, 0xad, 0x00, 0xad, 0x18, 0x16, 0x61, 0xa9, 0x61, 0x55, 0x69, +0x01, 0x35, 0x55, 0x61, 0x16, 0x69, 0x0f, 0x2e, 0x00, 0xd3, 0x17, 0x61, +0x0f, 0x2d, 0x00, 0xd3, 0x54, 0x60, 0x8c, 0x02, 0xa4, 0x0a, 0x16, 0x4f, +0x3a, 0x6f, 0xfd, 0x68, 0xf9, 0x1d, 0x79, 0x31, 0x01, 0x2d, 0x0c, 0xd1, +0xdb, 0x6d, 0x5b, 0x08, 0x09, 0xd3, 0x0b, 0x89, 0x00, 0x2b, 0x06, 0xd1, +0xfd, 0x6f, 0x03, 0x3b, 0x2e, 0x68, 0x33, 0x40, 0x2b, 0x60, 0x14, 0x23, +0x0b, 0x81, 0x10, 0x60, 0x80, 0x07, 0x80, 0x0a, 0x20, 0x43, 0x03, 0x04, +0x00, 0xd0, 0x01, 0x38, 0x50, 0x60, 0x09, 0x6a, 0x08, 0x32, 0x91, 0x42, +0x00, 0xd8, 0x07, 0x4a, 0x00, 0x0d, 0x02, 0xd3, 0x51, 0x20, 0x80, 0x03, +0x82, 0x61, 0x3a, 0x67, 0xbe, 0xe7, 0x00, 0x00, 0xa4, 0x2a, 0x00, 0x80, +0xa0, 0x1c, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80, 0x24, 0xa7, 0x20, 0x40, +0xb0, 0xb5, 0x00, 0x28, 0x04, 0xd1, 0x01, 0x20, 0xc0, 0x05, 0x16, 0x49, +0xc0, 0x46, 0x08, 0x60, 0x15, 0x4c, 0x00, 0x25, 0x67, 0x69, 0x00, 0x2f, 0x16, 0xd0, 0xe0, 0x68, 0x41, 0x1c, 0x80, 0x00, -0x00, 0x19, 0xe1, 0x60, 0x80, 0x69, 0x01, 0x3f, 0xff, 0xf7, 0x90, 0xfe, +0x00, 0x19, 0xe1, 0x60, 0x80, 0x69, 0x01, 0x3f, 0xff, 0xf7, 0x94, 0xfe, 0xe0, 0x68, 0x0f, 0x28, 0x00, 0xd3, 0xe5, 0x60, 0xe0, 0x68, 0x80, 0x00, 0x00, 0x19, 0x80, 0x69, 0x00, 0x08, 0x01, 0xd3, 0x00, 0x2f, 0xea, 0xd1, 0x67, 0x61, 0x03, 0xe0, 0x08, 0x48, 0x01, 0x6d, 0x01, 0x31, 0x01, 0x65, -0x65, 0x60, 0x20, 0x68, 0x00, 0x28, 0x01, 0xd0, 0xff, 0xf7, 0x22, 0xff, +0x65, 0x60, 0x20, 0x68, 0x00, 0x28, 0x01, 0xd0, 0xff, 0xf7, 0x26, 0xff, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, -0x1c, 0x1c, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x00, 0x20, 0x70, 0x47, +0xa0, 0x1c, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x00, 0x20, 0x70, 0x47, 0xb0, 0xb4, 0x10, 0x23, 0x82, 0x68, 0x13, 0x40, 0x00, 0x21, 0x00, 0x2b, 0x15, 0xd0, 0x0c, 0x4b, 0x1a, 0x40, 0x12, 0x01, 0x81, 0x24, 0x14, 0x43, -0x02, 0x68, 0x15, 0x68, 0x13, 0x1d, 0x80, 0xcb, -0x1b, 0x68, 0x04, 0x3a, 0x02, 0x60, 0x20, 0xc2, 0x80, 0xc2, 0x08, 0xc2, -0x14, 0x60, 0x42, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x04, 0x32, 0x1a, 0x43, -0x42, 0x60, 0x08, 0x1c, 0xb0, 0xbc, 0x70, 0x47, 0x00, 0xf0, 0xff, 0x0f, -0xf0, 0xb4, 0x82, 0x68, 0x53, 0x09, 0x34, 0xd3, 0x1b, 0x4b, 0x1a, 0x40, -0x12, 0x01, 0x81, 0x26, 0x16, 0x43, 0x03, 0x68, 0x1d, 0x68, 0x1f, 0x1d, -0x10, 0xcf, 0x3f, 0x68, 0x04, 0x3b, 0x03, 0x60, 0x20, 0xc3, 0x10, 0xc3, -0x80, 0xc3, 0x1e, 0x60, 0x43, 0x68, 0x1f, 0x1d, 0x01, 0x23, 0x9b, 0x07, -0x3b, 0x43, 0x43, 0x60, 0xcb, 0x6b, 0x18, 0x1f, 0xc8, 0x63, 0x80, 0xcb, -0x80, 0xc0, 0x1c, 0x68, 0x1f, 0x1d, 0x03, 0x1d, 0x04, 0x60, 0x38, 0x1c, -0x3f, 0x68, 0xc0, 0x46, 0x1f, 0x60, 0x1f, 0x1d, 0x43, 0x68, 0x1c, 0x04, -0x24, 0x0c, 0x81, 0x23, 0x23, 0x43, 0x3b, 0x60, 0x40, 0x68, 0x00, 0x0c, -0x00, 0x04, 0x10, 0x43, 0x78, 0x60, 0x08, 0x6e, 0x04, 0x30, 0x08, 0x66, -0x48, 0x6e, 0x04, 0x30, 0x48, 0x66, 0x00, 0x20, 0xf0, 0xbc, 0x70, 0x47, -0x00, 0xf0, 0xff, 0x0f, 0x80, 0xb4, 0x81, 0x6a, 0x01, 0x23, 0x9b, 0x07, -0xca, 0x1d, 0x05, 0x32, 0x1a, 0x43, 0x12, 0x68, 0xcf, 0x1d, 0x01, 0x37, -0x3b, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0xcb, 0x60, 0x01, 0x23, 0x9b, 0x07, -0x0f, 0x1d, 0x3b, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x8b, 0x60, 0x01, 0x23, -0x9b, 0x07, 0x0b, 0x43, 0x1b, 0x68, 0x0c, 0xc1, 0x02, 0x62, 0x01, 0x6b, -0xc0, 0x46, 0x0a, 0x62, 0x04, 0x23, 0x81, 0x69, 0x19, 0x43, 0x81, 0x61, -0x02, 0x6b, 0xc0, 0x46, 0x91, 0x61, 0x81, 0x6a, 0x04, 0x31, 0x81, 0x62, -0x02, 0x6b, 0xc0, 0x46, 0x91, 0x62, 0xc1, 0x1d, 0x39, 0x31, 0x4a, 0x8b, -0x04, 0x3a, 0x4a, 0x83, 0x49, 0x8b, 0x02, 0x6b, 0x40, 0x32, 0x51, 0x83, -0xc1, 0x89, 0x04, 0x39, 0xc1, 0x81, 0xc1, 0x68, 0x00, 0x6b, 0xc0, 0x46, -0xc1, 0x60, 0x00, 0x20, 0x80, 0xbc, 0x70, 0x47, 0x00, 0x47, 0x08, 0x47, -0x10, 0x47, 0x18, 0x47, 0x20, 0x47, 0x28, 0x47, 0x30, 0x47, 0x38, 0x47, -0x30, 0x40, 0x2d, 0xe9, 0x0c, 0xc0, 0x9d, 0xe5, 0x0c, 0x48, 0xa0, 0xe1, -0x24, 0x48, 0xb0, 0xe1, 0x1e, 0x00, 0x00, 0x0a, 0x01, 0xc0, 0x4c, 0xe2, -0x18, 0x40, 0xa0, 0xe3, 0x64, 0x51, 0x9f, 0xe5, 0x94, 0x50, 0x20, 0xe0, -0x00, 0x50, 0x90, 0xe5, 0x14, 0x40, 0x90, 0xe5, 0x00, 0x30, 0x85, 0xe5, -0x04, 0xc0, 0x85, 0xe5, 0x08, 0x10, 0x85, 0xe5, 0x0c, 0x20, 0x85, 0xe5, -0x10, 0x10, 0x90, 0xe5, 0x10, 0x50, 0x85, 0xe2, 0x01, 0x00, 0x55, 0xe1, -0x0c, 0x50, 0x90, 0x55, 0x04, 0x00, 0x55, 0xe1, 0x05, 0x00, 0x00, 0x0a, +0x02, 0x68, 0x15, 0x68, 0x13, 0x1d, 0x80, 0xcb, 0x1b, 0x68, 0x04, 0x3a, +0x02, 0x60, 0x20, 0xc2, 0x80, 0xc2, 0x08, 0xc2, 0x14, 0x60, 0x42, 0x68, +0x01, 0x23, 0x9b, 0x07, 0x04, 0x32, 0x1a, 0x43, 0x42, 0x60, 0x08, 0x1c, +0xb0, 0xbc, 0x70, 0x47, 0x00, 0xf0, 0xff, 0x0f, 0xf0, 0xb4, 0x82, 0x68, +0x53, 0x09, 0x34, 0xd3, 0x1b, 0x4b, 0x1a, 0x40, 0x12, 0x01, 0x81, 0x26, +0x16, 0x43, 0x03, 0x68, 0x1d, 0x68, 0x1f, 0x1d, 0x10, 0xcf, 0x3f, 0x68, +0x04, 0x3b, 0x03, 0x60, 0x20, 0xc3, 0x10, 0xc3, 0x80, 0xc3, 0x1e, 0x60, +0x43, 0x68, 0x1f, 0x1d, 0x01, 0x23, 0x9b, 0x07, 0x3b, 0x43, 0x43, 0x60, +0xcb, 0x6b, 0x18, 0x1f, 0xc8, 0x63, 0x80, 0xcb, 0x80, 0xc0, 0x1c, 0x68, +0x1f, 0x1d, 0x03, 0x1d, 0x04, 0x60, 0x38, 0x1c, 0x3f, 0x68, 0xc0, 0x46, +0x1f, 0x60, 0x1f, 0x1d, 0x43, 0x68, 0x1c, 0x04, 0x24, 0x0c, 0x81, 0x23, +0x23, 0x43, 0x3b, 0x60, 0x40, 0x68, 0x00, 0x0c, 0x00, 0x04, 0x10, 0x43, +0x78, 0x60, 0x08, 0x6e, 0x04, 0x30, 0x08, 0x66, 0x48, 0x6e, 0x04, 0x30, +0x48, 0x66, 0x00, 0x20, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0xf0, 0xff, 0x0f, +0x80, 0xb4, 0x81, 0x6a, 0x01, 0x23, 0x9b, 0x07, 0xca, 0x1d, 0x05, 0x32, +0x1a, 0x43, 0x12, 0x68, 0xcf, 0x1d, 0x01, 0x37, 0x3b, 0x43, 0x1b, 0x68, +0xc0, 0x46, 0xcb, 0x60, 0x01, 0x23, 0x9b, 0x07, 0x0f, 0x1d, 0x3b, 0x43, +0x1b, 0x68, 0xc0, 0x46, 0x8b, 0x60, 0x01, 0x23, 0x9b, 0x07, 0x0b, 0x43, +0x1b, 0x68, 0x0c, 0xc1, 0x02, 0x62, 0x01, 0x6b, 0xc0, 0x46, 0x0a, 0x62, +0x04, 0x23, 0x81, 0x69, 0x19, 0x43, 0x81, 0x61, 0x02, 0x6b, 0xc0, 0x46, +0x91, 0x61, 0x81, 0x6a, 0x04, 0x31, 0x81, 0x62, 0x02, 0x6b, 0xc0, 0x46, +0x91, 0x62, 0xc1, 0x1d, 0x39, 0x31, 0x4a, 0x8b, 0x04, 0x3a, 0x4a, 0x83, +0x49, 0x8b, 0x02, 0x6b, 0x40, 0x32, 0x51, 0x83, 0xc1, 0x89, 0x04, 0x39, +0xc1, 0x81, 0xc1, 0x68, 0x00, 0x6b, 0xc0, 0x46, 0xc1, 0x60, 0x00, 0x20, +0x80, 0xbc, 0x70, 0x47, 0x00, 0x47, 0x08, 0x47, 0x10, 0x47, 0x18, 0x47, +0x20, 0x47, 0x28, 0x47, 0x30, 0x47, 0x38, 0x47, 0x30, 0x40, 0x2d, 0xe9, +0x0c, 0xc0, 0x9d, 0xe5, 0x0c, 0x48, 0xa0, 0xe1, 0x24, 0x48, 0xb0, 0xe1, +0x1e, 0x00, 0x00, 0x0a, 0x01, 0xc0, 0x4c, 0xe2, 0x18, 0x40, 0xa0, 0xe3, +0x64, 0x51, 0x9f, 0xe5, 0x94, 0x50, 0x20, 0xe0, 0x00, 0x50, 0x90, 0xe5, +0x14, 0x40, 0x90, 0xe5, 0x00, 0x30, 0x85, 0xe5, 0x04, 0xc0, 0x85, 0xe5, +0x08, 0x10, 0x85, 0xe5, 0x0c, 0x20, 0x85, 0xe5, 0x10, 0x10, 0x90, 0xe5, +0x10, 0x50, 0x85, 0xe2, 0x01, 0x00, 0x55, 0xe1, 0x0c, 0x50, 0x90, 0x55, +0x04, 0x00, 0x55, 0xe1, 0x05, 0x00, 0x00, 0x0a, 0x04, 0x10, 0x90, 0xe5, 0x00, 0x50, 0x80, 0xe5, 0x00, 0x50, 0x81, 0xe5, 0x00, 0x00, 0xa0, 0xe3, 0x30, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x30, 0x93, 0xe5, 0x08, 0x20, 0x90, 0xe5, 0x01, 0x31, 0x83, 0xe3, @@ -1793,39 +1805,39 @@ 0x50, 0x10, 0x91, 0xe5, 0xd9, 0xff, 0xff, 0xea, 0xf0, 0x47, 0x2d, 0xe9, 0x20, 0xc0, 0x9d, 0xe5, 0x0c, 0x68, 0xa0, 0xe1, 0x26, 0x68, 0xb0, 0xe1, 0x25, 0x00, 0x00, 0x0a, 0x18, 0x40, 0xa0, 0xe3, 0xb8, 0x50, 0x9f, 0xe5, -0x94, 0x00, 0x00, 0xe0, 0x05, 0x00, 0x80, 0xe0, -0x08, 0x40, 0x90, 0xe5, 0x04, 0x80, 0x90, 0xe5, 0x00, 0x70, 0xa0, 0xe3, -0x1f, 0xc0, 0xa0, 0xe3, 0x02, 0xc4, 0x8c, 0xe3, 0x00, 0x50, 0x90, 0xe5, -0x10, 0x90, 0x90, 0xe5, 0x14, 0xa0, 0x90, 0xe5, 0x00, 0x30, 0x85, 0xe5, -0x04, 0xc0, 0x85, 0xe5, 0x08, 0x10, 0x85, 0xe5, 0x0c, 0x20, 0x85, 0xe5, -0x10, 0x50, 0x85, 0xe2, 0x09, 0x00, 0x55, 0xe1, 0x0c, 0x50, 0x90, 0x55, -0x0a, 0x00, 0x55, 0xe1, 0x15, 0x00, 0x00, 0x0a, 0x03, 0x70, 0x17, 0xe2, -0x20, 0x10, 0x81, 0xe2, 0x20, 0x30, 0x83, 0xe2, 0x0a, 0x00, 0x00, 0x0a, -0x00, 0x60, 0x96, 0xe2, 0x01, 0x70, 0x87, 0xe2, 0x09, 0x00, 0x00, 0x0a, -0x20, 0x60, 0x46, 0xe2, 0x20, 0x00, 0x56, 0xe3, 0xec, 0xff, 0xff, 0xca, -0x00, 0x70, 0xa0, 0xe3, 0x01, 0xc0, 0x46, 0xe2, 0x02, 0xc4, 0x8c, 0xe3, -0x00, 0x60, 0xa0, 0xe3, 0xe7, 0xff, 0xff, 0xea, 0x00, 0x50, 0x88, 0xe5, -0xf2, 0xff, 0xff, 0xea, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x50, 0x80, 0xe5, -0x01, 0x00, 0xa0, 0xe1, 0xf0, 0x47, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, -0x00, 0xa0, 0x94, 0xe5, 0x0a, 0x00, 0x55, 0xe1, 0x14, 0xa0, 0x80, 0xe5, -0xe5, 0xff, 0xff, 0x1a, 0x01, 0x10, 0xa0, 0xe3, 0xf5, 0xff, 0xff, 0xea, -0x28, 0x03, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, 0x00, 0x80, 0x20, 0x40, -0x68, 0x82, 0x9f, 0xe5, 0x0b, 0x92, 0xa0, 0xe3, 0x64, 0xa2, 0x9f, 0xe5, -0x58, 0xb0, 0x9a, 0xe5, 0x0e, 0xf0, 0xa0, 0xe1, 0x54, 0xb0, 0x9a, 0xe5, -0x1e, 0xff, 0x2f, 0xe1, 0x3f, 0x40, 0x2d, 0xe9, 0x00, 0x00, 0x4f, 0xe1, -0x1f, 0x00, 0x00, 0xe2, 0x12, 0x00, 0x50, 0xe3, 0x54, 0x00, 0x00, 0x0a, -0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0xc0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, -0x04, 0x50, 0xa0, 0xe3, 0x00, 0x40, 0x99, 0xe5, 0x09, 0x00, 0x00, 0xea, -0x02, 0x00, 0x14, 0xe3, 0x53, 0x00, 0x00, 0x1b, 0x80, 0x00, 0x14, 0xe3, -0x59, 0x00, 0x00, 0x1b, 0x20, 0x00, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b, -0x02, 0x07, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b, 0x01, 0x06, 0x14, 0xe3, -0x59, 0x00, 0x00, 0x1b, 0x08, 0x00, 0x14, 0xe3, 0x45, 0x00, 0x00, 0x1b, -0x02, 0x05, 0x14, 0xe3, 0x4a, 0x00, 0x00, 0x1b, 0x02, 0x08, 0x14, 0xe3, -0x4b, 0x00, 0x00, 0x1b, 0xe5, 0x0e, 0x14, 0xe3, 0x07, 0x00, 0x00, 0x0a, -0x04, 0x20, 0x98, 0xe5, 0x0c, 0x10, 0x98, 0xe5, 0x04, 0x30, 0x52, 0xe2, -0x3c, 0x30, 0xa0, 0xb3, 0x04, 0x30, 0x88, 0xe5, 0x02, 0x00, 0x91, 0xe7, -0x0f, 0xe0, 0xa0, 0xe1, 0x10, 0xff, 0x2f, 0xe1, 0x01, 0x50, 0x55, 0xe2, -0x03, 0x00, 0x00, 0x0a, 0x00, 0x40, 0x99, 0xe5, 0x0c, 0x00, 0x9a, 0xe5, +0x94, 0x00, 0x00, 0xe0, 0x05, 0x00, 0x80, 0xe0, 0x08, 0x40, 0x90, 0xe5, +0x04, 0x80, 0x90, 0xe5, 0x00, 0x70, 0xa0, 0xe3, 0x1f, 0xc0, 0xa0, 0xe3, +0x02, 0xc4, 0x8c, 0xe3, 0x00, 0x50, 0x90, 0xe5, 0x10, 0x90, 0x90, 0xe5, +0x14, 0xa0, 0x90, 0xe5, 0x00, 0x30, 0x85, 0xe5, 0x04, 0xc0, 0x85, 0xe5, +0x08, 0x10, 0x85, 0xe5, 0x0c, 0x20, 0x85, 0xe5, 0x10, 0x50, 0x85, 0xe2, +0x09, 0x00, 0x55, 0xe1, 0x0c, 0x50, 0x90, 0x55, 0x0a, 0x00, 0x55, 0xe1, +0x15, 0x00, 0x00, 0x0a, 0x03, 0x70, 0x17, 0xe2, 0x20, 0x10, 0x81, 0xe2, +0x20, 0x30, 0x83, 0xe2, 0x0a, 0x00, 0x00, 0x0a, 0x00, 0x60, 0x96, 0xe2, +0x01, 0x70, 0x87, 0xe2, 0x09, 0x00, 0x00, 0x0a, 0x20, 0x60, 0x46, 0xe2, +0x20, 0x00, 0x56, 0xe3, 0xec, 0xff, 0xff, 0xca, 0x00, 0x70, 0xa0, 0xe3, +0x01, 0xc0, 0x46, 0xe2, 0x02, 0xc4, 0x8c, 0xe3, 0x00, 0x60, 0xa0, 0xe3, +0xe7, 0xff, 0xff, 0xea, 0x00, 0x50, 0x88, 0xe5, 0xf2, 0xff, 0xff, 0xea, +0x00, 0x10, 0xa0, 0xe3, 0x00, 0x50, 0x80, 0xe5, 0x01, 0x00, 0xa0, 0xe1, +0xf0, 0x47, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xa0, 0x94, 0xe5, +0x0a, 0x00, 0x55, 0xe1, 0x14, 0xa0, 0x80, 0xe5, 0xe5, 0xff, 0xff, 0x1a, +0x01, 0x10, 0xa0, 0xe3, 0xf5, 0xff, 0xff, 0xea, 0xa8, 0x03, 0x00, 0x80, +0x7c, 0x29, 0x00, 0x80, 0x00, 0x80, 0x20, 0x40, 0x68, 0x82, 0x9f, 0xe5, +0x0b, 0x92, 0xa0, 0xe3, 0x64, 0xa2, 0x9f, 0xe5, 0x58, 0xb0, 0x9a, 0xe5, +0x0e, 0xf0, 0xa0, 0xe1, 0x54, 0xb0, 0x9a, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, +0x3f, 0x40, 0x2d, 0xe9, 0x00, 0x00, 0x4f, 0xe1, 0x1f, 0x00, 0x00, 0xe2, +0x12, 0x00, 0x50, 0xe3, 0x54, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0f, 0xe1, +0x80, 0x00, 0xc0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x04, 0x50, 0xa0, 0xe3, +0x00, 0x40, 0x99, 0xe5, 0x09, 0x00, 0x00, 0xea, 0x02, 0x00, 0x14, 0xe3, +0x53, 0x00, 0x00, 0x1b, 0x80, 0x00, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b, +0x20, 0x00, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b, 0x02, 0x07, 0x14, 0xe3, +0x59, 0x00, 0x00, 0x1b, 0x01, 0x06, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b, +0x08, 0x00, 0x14, 0xe3, 0x45, 0x00, 0x00, 0x1b, 0x02, 0x05, 0x14, 0xe3, +0x4a, 0x00, 0x00, 0x1b, 0x02, 0x08, 0x14, 0xe3, 0x4b, 0x00, 0x00, 0x1b, +0xe5, 0x0e, 0x14, 0xe3, 0x07, 0x00, 0x00, 0x0a, 0x04, 0x20, 0x98, 0xe5, +0x0c, 0x10, 0x98, 0xe5, 0x04, 0x30, 0x52, 0xe2, 0x3c, 0x30, 0xa0, 0xb3, +0x04, 0x30, 0x88, 0xe5, 0x02, 0x00, 0x91, 0xe7, 0x0f, 0xe0, 0xa0, 0xe1, +0x10, 0xff, 0x2f, 0xe1, 0x01, 0x50, 0x55, 0xe2, 0x03, 0x00, 0x00, 0x0a, +0x00, 0x40, 0x99, 0xe5, 0x0c, 0x00, 0x9a, 0xe5, 0x00, 0x00, 0x14, 0xe1, 0x1b, 0xff, 0x2f, 0x11, 0x08, 0x00, 0x9a, 0xe5, 0x00, 0x00, 0x14, 0xe1, 0x0b, 0x00, 0x00, 0x0a, 0x01, 0x0c, 0x14, 0xe3, 0x98, 0x01, 0x9f, 0x15, 0x0f, 0xe0, 0xa0, 0x11, 0x10, 0xff, 0x2f, 0x11, @@ -1836,38 +1848,39 @@ 0x04, 0x00, 0x14, 0xe3, 0x40, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 0x02, 0x0a, 0x14, 0xe3, 0x44, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 0x02, 0x09, 0x14, 0xe3, 0x48, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, -0x01, 0x02, 0x14, 0xe3, 0x4c, 0x00, 0x9a, 0x15, -0x10, 0xff, 0x2f, 0x11, 0x01, 0x04, 0x14, 0xe3, 0x50, 0x00, 0x9a, 0x15, -0x10, 0xff, 0x2f, 0x11, 0x01, 0x0a, 0x14, 0xe3, 0x21, 0x00, 0x00, 0x1b, -0x02, 0x00, 0x14, 0xe3, 0x0e, 0x00, 0x00, 0x1b, 0x10, 0x00, 0x9a, 0xe5, -0x00, 0x00, 0x14, 0xe1, 0x1c, 0x00, 0x00, 0x1b, 0x00, 0x40, 0x99, 0xe5, -0x04, 0x50, 0xa0, 0xe3, 0x00, 0x40, 0x94, 0xe2, 0x1b, 0xff, 0x2f, 0x11, -0x3f, 0x40, 0xbd, 0xe8, 0x04, 0xf0, 0x5e, 0xe2, 0xc0, 0x00, 0x80, 0xe3, -0x00, 0xf0, 0x61, 0xe1, 0xfa, 0xff, 0xff, 0xea, 0x18, 0x00, 0x9a, 0xe5, -0x1c, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x54, 0xb0, 0x9a, 0xe5, -0x1c, 0x10, 0x9a, 0xe5, 0x14, 0x00, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, -0x20, 0x10, 0x9a, 0xe5, 0x00, 0x00, 0xa0, 0xe3, 0x11, 0xff, 0x2f, 0xe1, -0x24, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x28, 0x10, 0x9a, 0xe5, -0x11, 0xff, 0x2f, 0xe1, 0x2c, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, -0x30, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x34, 0x10, 0x9a, 0xe5, -0x11, 0xff, 0x2f, 0xe1, 0xfe, 0xff, 0xff, 0xea, 0x38, 0xe0, 0x9a, 0xe5, -0x3c, 0x10, 0x9a, 0xe5, 0x18, 0x00, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, -0x38, 0xe0, 0x9a, 0xe5, 0x3c, 0x10, 0x9a, 0xe5, 0x14, 0x00, 0x9a, 0xe5, -0x11, 0xff, 0x2f, 0xe1, 0x64, 0x20, 0x9f, 0xe5, 0x00, 0x30, 0x92, 0xe5, -0x00, 0x30, 0x53, 0xe0, 0x0a, 0x00, 0x00, 0xba, 0x00, 0x30, 0x82, 0xe5, -0x0c, 0x00, 0x92, 0xe5, 0x08, 0x30, 0x92, 0xe5, 0x00, 0x10, 0x91, 0xe2, -0x03, 0x00, 0x00, 0x0a, 0x03, 0x10, 0x80, 0xe7, 0x04, 0x30, 0x53, 0xe2, -0x3c, 0x30, 0xa0, 0xb3, 0x08, 0x30, 0x82, 0xe5, 0x01, 0x00, 0xa0, 0xe3, -0x1e, 0xff, 0x2f, 0xe1, 0x3c, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5, -0x01, 0x00, 0x80, 0xe2, 0x00, 0x00, 0x81, 0xe5, 0x00, 0x00, 0xa0, 0xe3, -0xf8, 0xff, 0xff, 0xea, 0x10, 0x00, 0x9f, 0xe5, 0x08, 0x10, 0x90, 0xe5, -0x04, 0x10, 0x51, 0xe2, 0x3c, 0x10, 0xa0, 0xb3, 0x08, 0x10, 0x80, 0xe5, -0x1e, 0xff, 0x2f, 0xe1, 0x50, 0x2d, 0x00, 0x80, 0x4c, 0x04, 0x00, 0x80, -0xe5, 0x2a, 0xff, 0xff, 0x45, 0x3d, 0xff, 0xff, 0x3d, 0x2b, 0xff, 0xff, -0xa0, 0x82, 0x20, 0x40, 0xc9, 0x1c, 0x89, 0x08, 0x89, 0x00, 0x01, 0x23, -0x85, 0x4a, 0x5b, 0x07, 0x18, 0x43, 0x13, 0x68, 0x5b, 0x18, 0x13, 0x60, -0x00, 0x1f, 0x81, 0xa3, 0x5b, 0x1a, 0x18, 0x47, 0x04, 0x20, 0xa0, 0xe5, +0x01, 0x02, 0x14, 0xe3, 0x4c, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, +0x01, 0x04, 0x14, 0xe3, 0x50, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, +0x01, 0x0a, 0x14, 0xe3, 0x21, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x14, 0xe3, +0x0e, 0x00, 0x00, 0x1b, 0x10, 0x00, 0x9a, 0xe5, 0x00, 0x00, 0x14, 0xe1, +0x1c, 0x00, 0x00, 0x1b, 0x00, 0x40, 0x99, 0xe5, 0x04, 0x50, 0xa0, 0xe3, +0x00, 0x40, 0x94, 0xe2, 0x1b, 0xff, 0x2f, 0x11, 0x3f, 0x40, 0xbd, 0xe8, +0x04, 0xf0, 0x5e, 0xe2, 0xc0, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x61, 0xe1, +0xfa, 0xff, 0xff, 0xea, 0x18, 0x00, 0x9a, 0xe5, 0x1c, 0x10, 0x9a, 0xe5, +0x11, 0xff, 0x2f, 0xe1, 0x54, 0xb0, 0x9a, 0xe5, 0x1c, 0x10, 0x9a, 0xe5, +0x14, 0x00, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x20, 0x10, 0x9a, 0xe5, +0x00, 0x00, 0xa0, 0xe3, 0x11, 0xff, 0x2f, 0xe1, 0x24, 0x10, 0x9a, 0xe5, +0x11, 0xff, 0x2f, 0xe1, 0x28, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, +0x2c, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x30, 0x10, 0x9a, 0xe5, +0x11, 0xff, 0x2f, 0xe1, 0x34, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, +0xfe, 0xff, 0xff, 0xea, 0x38, 0xe0, 0x9a, 0xe5, 0x3c, 0x10, 0x9a, 0xe5, +0x18, 0x00, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x38, 0xe0, 0x9a, 0xe5, +0x3c, 0x10, 0x9a, 0xe5, 0x14, 0x00, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, +0x64, 0x20, 0x9f, 0xe5, 0x00, 0x30, 0x92, 0xe5, 0x00, 0x30, 0x53, 0xe0, +0x0a, 0x00, 0x00, 0xba, 0x00, 0x30, 0x82, 0xe5, 0x0c, 0x00, 0x92, 0xe5, +0x08, 0x30, 0x92, 0xe5, 0x00, 0x10, 0x91, 0xe2, 0x03, 0x00, 0x00, 0x0a, +0x03, 0x10, 0x80, 0xe7, 0x04, 0x30, 0x53, 0xe2, 0x3c, 0x30, 0xa0, 0xb3, +0x08, 0x30, 0x82, 0xe5, 0x01, 0x00, 0xa0, 0xe3, 0x1e, 0xff, 0x2f, 0xe1, +0x3c, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5, 0x01, 0x00, 0x80, 0xe2, +0x00, 0x00, 0x81, 0xe5, 0x00, 0x00, 0xa0, 0xe3, 0xf8, 0xff, 0xff, 0xea, +0x10, 0x00, 0x9f, 0xe5, 0x08, 0x10, 0x90, 0xe5, 0x04, 0x10, 0x51, 0xe2, +0x3c, 0x10, 0xa0, 0xb3, 0x08, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, +0xe4, 0x2d, 0x00, 0x80, 0xcc, 0x04, 0x00, 0x80, 0x5d, 0x2b, 0xff, 0xff, +0xbd, 0x3d, 0xff, 0xff, 0xb5, 0x2b, 0xff, 0xff, 0xa0, 0x82, 0x20, 0x40, +0xc9, 0x1c, 0x89, 0x08, 0x89, 0x00, 0x01, 0x23, 0x85, 0x4a, 0x5b, 0x07, +0x18, 0x43, 0x13, 0x68, 0x5b, 0x18, 0x13, 0x60, 0x00, 0x1f, 0x81, 0xa3, +0x5b, 0x1a, 0x18, 0x47, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, @@ -1879,7 +1892,6 @@ 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, -0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, @@ -1909,9 +1921,9 @@ 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, -0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, -0x50, 0x2d, 0x00, 0x80, 0x98, 0x00, 0x9f, 0xe5, 0x98, 0x10, 0x9f, 0xe5, -0x01, 0x20, 0x40, 0xe0, 0x94, 0x30, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5, +0x04, 0x20, 0xa0, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xe4, 0x2d, 0x00, 0x80, +0x98, 0x00, 0x9f, 0xe5, 0x98, 0x10, 0x9f, 0xe5, 0x01, 0x20, 0x40, 0xe0, +0x94, 0x30, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5, 0x03, 0x00, 0x50, 0xe1, 0x03, 0x00, 0x00, 0x1a, 0x04, 0x10, 0x81, 0xe2, 0x04, 0x20, 0x52, 0xe2, 0x00, 0x00, 0x00, 0x0a, 0xf8, 0xff, 0xff, 0xea, 0x78, 0x00, 0x9f, 0xe5, 0x00, 0x20, 0x80, 0xe5, 0x74, 0x00, 0x9f, 0xe5, @@ -1922,125 +1934,125 @@ 0x4c, 0x00, 0x9f, 0xe5, 0x4c, 0x10, 0x9f, 0xe5, 0x01, 0x20, 0x40, 0xe0, 0x2c, 0x30, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5, 0x03, 0x00, 0x50, 0xe1, 0x03, 0x00, 0x00, 0x1a, 0x04, 0x10, 0x81, 0xe2, 0x04, 0x20, 0x52, 0xe2, -0x00, 0x00, 0x00, 0x0a, 0xf8, 0xff, 0xff, 0xea, -0x28, 0x00, 0x9f, 0xe5, 0x00, 0x20, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, -0x7c, 0x34, 0x00, 0x80, 0x80, 0x30, 0x00, 0x80, 0xad, 0xde, 0xad, 0xde, -0x40, 0x04, 0x00, 0x80, 0xfc, 0x37, 0x00, 0x80, 0x80, 0x34, 0x00, 0x80, -0x44, 0x04, 0x00, 0x80, 0xfc, 0x3f, 0x00, 0x80, 0x40, 0x38, 0x00, 0x80, -0x48, 0x04, 0x00, 0x80, 0x78, 0x47, 0x00, 0x00, 0x91, 0xea, 0xff, 0xea, -0x78, 0x47, 0x00, 0x00, 0x39, 0xfe, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, -0x63, 0xfe, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x1b, 0xff, 0xff, 0xea, -0x78, 0x47, 0x00, 0x00, 0x8b, 0xea, 0xff, 0xea, 0x00, 0x00, 0x00, 0x00, -0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x28, 0x04, 0x00, 0x00, -0x61, 0x6d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0xff, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xb9, 0x0b, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, -0xd5, 0x0b, 0xff, 0xff, 0x03, 0xff, 0x06, 0x54, 0x03, 0x00, 0x00, 0x00, -0x75, 0x04, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x05, 0xff, 0xff, -0x04, 0xff, 0x07, 0x54, 0x03, 0x00, 0x00, 0x00, 0xb5, 0x04, 0xff, 0xff, -0x00, 0x00, 0x00, 0x00, 0xf1, 0x05, 0xff, 0xff, 0x05, 0xff, 0x05, 0x54, -0x03, 0x00, 0x00, 0x00, 0x39, 0x04, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, -0x55, 0x05, 0xff, 0xff, 0x00, 0xff, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, -0xf5, 0x17, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x29, 0x0e, 0xff, 0xff, -0x01, 0xff, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x02, 0xff, 0xff, -0x00, 0x00, 0x00, 0x00, 0xf1, 0x02, 0xff, 0xff, 0xff, 0xff, 0x01, 0x44, -0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x65, 0x0d, 0xff, 0xff, 0x06, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, -0xbd, 0x4f, 0xff, 0xff, 0x01, 0x50, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, -0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, +0x00, 0x00, 0x00, 0x0a, 0xf8, 0xff, 0xff, 0xea, 0x28, 0x00, 0x9f, 0xe5, +0x00, 0x20, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x7c, 0x34, 0x00, 0x80, +0x80, 0x30, 0x00, 0x80, 0xad, 0xde, 0xad, 0xde, 0xc0, 0x04, 0x00, 0x80, +0xfc, 0x37, 0x00, 0x80, 0x80, 0x34, 0x00, 0x80, 0xc4, 0x04, 0x00, 0x80, +0xfc, 0x3f, 0x00, 0x80, 0x40, 0x38, 0x00, 0x80, 0xc8, 0x04, 0x00, 0x80, +0x78, 0x47, 0x00, 0x00, 0x76, 0xea, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, +0x39, 0xfe, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x63, 0xfe, 0xff, 0xea, +0x78, 0x47, 0x00, 0x00, 0x1b, 0xff, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, +0x70, 0xea, 0xff, 0xea, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, +0x00, 0x00, 0x00, 0x80, 0x28, 0x04, 0x00, 0x00, 0x95, 0x22, 0x00, 0x00, +0x00, 0x01, 0x00, 0x80, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xb9, 0x0b, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xd5, 0x0b, 0xff, 0xff, +0x03, 0xff, 0x06, 0x54, 0x03, 0x00, 0x00, 0x00, 0x75, 0x04, 0xff, 0xff, +0x00, 0x00, 0x00, 0x00, 0xa1, 0x05, 0xff, 0xff, 0x04, 0xff, 0x07, 0x54, +0x03, 0x00, 0x00, 0x00, 0xb5, 0x04, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, +0xf1, 0x05, 0xff, 0xff, 0x05, 0xff, 0x05, 0x54, 0x03, 0x00, 0x00, 0x00, +0x39, 0x04, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x55, 0x05, 0xff, 0xff, +0x01, 0xff, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x41, 0x18, 0xff, 0xff, +0x00, 0x00, 0x00, 0x00, 0x61, 0x0e, 0xff, 0xff, 0x02, 0xff, 0x02, 0x08, +0x00, 0x00, 0x00, 0x00, 0xa1, 0x02, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, +0xf1, 0x02, 0xff, 0xff, 0xff, 0xff, 0x01, 0x44, 0x03, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x0d, 0xff, 0xff, +0x06, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x50, 0xff, 0xff, +0x6d, 0x50, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +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, 0xc8, 0x04, 0x00, 0x80, -0x19, 0x78, 0x21, 0x40, 0x23, 0x78, 0x21, 0x40, 0x39, 0x78, 0x21, 0x40, -0x51, 0x78, 0x21, 0x40, 0x5d, 0x78, 0x21, 0x40, 0x6b, 0x78, 0x21, 0x40, -0x85, 0x78, 0x21, 0x40, 0xb1, 0x78, 0x21, 0x40, 0x75, 0x79, 0x21, 0x40, +0x00, 0x00, 0x00, 0x00, 0x48, 0x05, 0x00, 0x80, 0x19, 0x78, 0x21, 0x40, +0x23, 0x78, 0x21, 0x40, 0x39, 0x78, 0x21, 0x40, 0x51, 0x78, 0x21, 0x40, +0x5d, 0x78, 0x21, 0x40, 0x6b, 0x78, 0x21, 0x40, 0x85, 0x78, 0x21, 0x40, +0xb1, 0x78, 0x21, 0x40, 0x75, 0x79, 0x21, 0x40, 0xcd, 0x79, 0x21, 0x40, 0xdb, 0x79, 0x21, 0x40, 0xe5, 0x79, 0x21, 0x40, -0xef, 0x79, 0x21, 0x40, 0x81, 0x7a, 0x21, 0x40, 0x8f, 0x7a, 0x21, 0x40, -0x9d, 0x7a, 0x21, 0x40, 0x35, 0x7b, 0x21, 0x40, 0x03, 0x7f, 0x21, 0x40, -0x71, 0x7f, 0x21, 0x40, 0x19, 0x80, 0x21, 0x40, 0x4d, 0x81, 0x21, 0x40, -0x59, 0x81, 0x21, 0x40, 0xb9, 0x81, 0x21, 0x40, 0x1d, 0x82, 0x21, 0x40, -0x49, 0x82, 0x21, 0x40, 0x6d, 0x82, 0x21, 0x40, 0xad, 0x82, 0x21, 0x40, -0xd5, 0x82, 0x21, 0x40, 0x1d, 0x83, 0x21, 0x40, 0x2d, 0x83, 0x21, 0x40, -0x55, 0x83, 0x21, 0x40, 0x65, 0x83, 0x21, 0x40, 0xad, 0x83, 0x21, 0x40, -0xeb, 0x83, 0x21, 0x40, 0x41, 0x84, 0x21, 0x40, 0xa1, 0x84, 0x21, 0x40, -0xab, 0x84, 0x21, 0x40, 0xaf, 0x84, 0x21, 0x40, 0x1d, 0x85, 0x21, 0x40, -0x75, 0x85, 0x21, 0x40, 0xcd, 0x85, 0x21, 0x40, -0x09, 0x86, 0x21, 0x40, 0x6d, 0x86, 0x21, 0x40, 0xa5, 0x86, 0x21, 0x40, -0xb5, 0x86, 0x21, 0x40, 0xed, 0x86, 0x21, 0x40, 0xfd, 0x86, 0x21, 0x40, -0x11, 0x87, 0x21, 0x40, 0x39, 0x87, 0x21, 0x40, 0x43, 0x87, 0x21, 0x40, -0x4d, 0x87, 0x21, 0x40, 0x57, 0x87, 0x21, 0x40, 0xc1, 0x87, 0x21, 0x40, -0xcd, 0x87, 0x21, 0x40, 0x41, 0x88, 0x21, 0x40, 0x4b, 0x88, 0x21, 0x40, -0x55, 0x88, 0x21, 0x40, 0x5f, 0x88, 0x21, 0x40, 0x69, 0x88, 0x21, 0x40, -0x73, 0x88, 0x21, 0x40, 0x7d, 0x88, 0x21, 0x40, 0x87, 0x88, 0x21, 0x40, -0x91, 0x88, 0x21, 0x40, 0x9b, 0x88, 0x21, 0x40, 0xa5, 0x88, 0x21, 0x40, -0xaf, 0x88, 0x21, 0x40, 0xb9, 0x88, 0x21, 0x40, 0xc3, 0x88, 0x21, 0x40, -0xeb, 0x88, 0x21, 0x40, 0xf5, 0x88, 0x21, 0x40, 0x51, 0x89, 0x21, 0x40, -0x5b, 0x89, 0x21, 0x40, 0x65, 0x89, 0x21, 0x40, 0x6f, 0x89, 0x21, 0x40, -0x79, 0x89, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, 0x83, 0x89, 0x21, 0x40, -0xe9, 0x89, 0x21, 0x40, 0x35, 0x8a, 0x21, 0x40, 0x81, 0x8a, 0x21, 0x40, -0x91, 0x8a, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, 0xdd, 0x8a, 0x21, 0x40, -0xe1, 0x8a, 0x21, 0x40, 0xe5, 0x8a, 0x21, 0x40, 0x3d, 0x8b, 0x21, 0x40, -0x65, 0x8b, 0x21, 0x40, 0x71, 0x8b, 0x21, 0x40, 0x75, 0x8b, 0x21, 0x40, -0x79, 0x8b, 0x21, 0x40, 0xe9, 0x8b, 0x21, 0x40, 0xed, 0x8b, 0x21, 0x40, -0xf1, 0x8b, 0x21, 0x40, 0x7d, 0x8b, 0x21, 0x40, 0x05, 0x88, 0x21, 0x40, -0xa5, 0x77, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, 0xf5, 0x8b, 0x21, 0x40, -0xe9, 0xc1, 0x21, 0x40, 0xe9, 0x77, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, -0xa5, 0x77, 0x21, 0x40, 0xcd, 0xc2, 0x21, 0x40, 0x03, 0xc3, 0x21, 0x40, -0x35, 0xc3, 0x21, 0x40, 0x4d, 0x8c, 0x21, 0x40, 0x3f, 0x7b, 0x21, 0x40, -0x99, 0x7e, 0x21, 0x40, 0xd5, 0x7e, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x5c, 0x01, 0x18, 0x40, 0x58, 0x01, 0x18, 0x40, 0x24, 0xa3, 0x20, 0x40, -0x24, 0xa7, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x6c, 0x01, 0x18, 0x40, 0x68, 0x01, 0x18, 0x40, 0x24, 0x83, 0x20, 0x40, -0x24, 0xa3, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x7c, 0x01, 0x18, 0x40, 0x78, 0x01, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x8c, 0x01, 0x18, 0x40, 0x88, 0x01, 0x18, 0x40, 0x24, 0xa9, 0x20, 0x40, -0x24, 0xab, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xef, 0x79, 0x21, 0x40, 0x8d, 0x7a, 0x21, 0x40, 0x9b, 0x7a, 0x21, 0x40, +0xa9, 0x7a, 0x21, 0x40, 0x51, 0x7b, 0x21, 0x40, 0x4f, 0x7f, 0x21, 0x40, +0xc9, 0x7f, 0x21, 0x40, 0x69, 0x80, 0x21, 0x40, 0x9d, 0x81, 0x21, 0x40, +0xa9, 0x81, 0x21, 0x40, 0x09, 0x82, 0x21, 0x40, 0x6d, 0x82, 0x21, 0x40, +0x99, 0x82, 0x21, 0x40, 0xbd, 0x82, 0x21, 0x40, 0xfd, 0x82, 0x21, 0x40, +0x25, 0x83, 0x21, 0x40, 0x6d, 0x83, 0x21, 0x40, 0x7d, 0x83, 0x21, 0x40, +0xa5, 0x83, 0x21, 0x40, 0xb5, 0x83, 0x21, 0x40, 0xfd, 0x83, 0x21, 0x40, +0x3b, 0x84, 0x21, 0x40, 0x91, 0x84, 0x21, 0x40, 0xf1, 0x84, 0x21, 0x40, +0xfb, 0x84, 0x21, 0x40, 0xff, 0x84, 0x21, 0x40, 0x6d, 0x85, 0x21, 0x40, +0xb9, 0x85, 0x21, 0x40, 0x11, 0x86, 0x21, 0x40, 0x4d, 0x86, 0x21, 0x40, +0xb1, 0x86, 0x21, 0x40, 0xe9, 0x86, 0x21, 0x40, 0xf9, 0x86, 0x21, 0x40, +0x31, 0x87, 0x21, 0x40, 0x41, 0x87, 0x21, 0x40, 0x55, 0x87, 0x21, 0x40, +0x7d, 0x87, 0x21, 0x40, 0x87, 0x87, 0x21, 0x40, 0x91, 0x87, 0x21, 0x40, +0xf5, 0x87, 0x21, 0x40, 0x25, 0x88, 0x21, 0x40, 0x31, 0x88, 0x21, 0x40, +0xa5, 0x88, 0x21, 0x40, 0xaf, 0x88, 0x21, 0x40, 0xb9, 0x88, 0x21, 0x40, +0xc3, 0x88, 0x21, 0x40, 0xcd, 0x88, 0x21, 0x40, 0xd7, 0x88, 0x21, 0x40, +0xe1, 0x88, 0x21, 0x40, 0xeb, 0x88, 0x21, 0x40, 0xf5, 0x88, 0x21, 0x40, +0xe9, 0x8b, 0x21, 0x40, 0xff, 0x88, 0x21, 0x40, 0x09, 0x89, 0x21, 0x40, +0x13, 0x89, 0x21, 0x40, 0x1d, 0x89, 0x21, 0x40, 0x45, 0x89, 0x21, 0x40, +0x4f, 0x89, 0x21, 0x40, 0xb1, 0x89, 0x21, 0x40, 0xbb, 0x89, 0x21, 0x40, +0xc5, 0x89, 0x21, 0x40, 0xcf, 0x89, 0x21, 0x40, 0xd9, 0x89, 0x21, 0x40, +0xa5, 0x77, 0x21, 0x40, 0xe3, 0x89, 0x21, 0x40, 0x49, 0x8a, 0x21, 0x40, +0x95, 0x8a, 0x21, 0x40, 0xe1, 0x8a, 0x21, 0x40, 0xf1, 0x8a, 0x21, 0x40, +0xa5, 0x77, 0x21, 0x40, 0x3d, 0x8b, 0x21, 0x40, 0x41, 0x8b, 0x21, 0x40, +0x45, 0x8b, 0x21, 0x40, 0x9d, 0x8b, 0x21, 0x40, 0xc5, 0x8b, 0x21, 0x40, +0xd1, 0x8b, 0x21, 0x40, 0xd5, 0x8b, 0x21, 0x40, 0xd9, 0x8b, 0x21, 0x40, +0xdd, 0x8b, 0x21, 0x40, 0xe1, 0x8b, 0x21, 0x40, 0xe5, 0x8b, 0x21, 0x40, +0x0d, 0x88, 0x21, 0x40, 0x69, 0x88, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, +0xa5, 0x77, 0x21, 0x40, 0xf5, 0x8b, 0x21, 0x40, 0xe1, 0xc9, 0x21, 0x40, +0xe9, 0x77, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, +0xdd, 0xca, 0x21, 0x40, 0x13, 0xcb, 0x21, 0x40, 0x45, 0xcb, 0x21, 0x40, +0x4d, 0x8c, 0x21, 0x40, 0x5b, 0x7b, 0x21, 0x40, 0xe5, 0x7e, 0x21, 0x40, +0x21, 0x7f, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x18, 0x40, +0x58, 0x01, 0x18, 0x40, 0x24, 0xa3, 0x20, 0x40, 0x24, 0xa7, 0x20, 0x40, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x01, 0x18, 0x40, +0x68, 0x01, 0x18, 0x40, 0x24, 0x83, 0x20, 0x40, 0x24, 0xa3, 0x20, 0x40, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x01, 0x18, 0x40, +0x78, 0x01, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x01, 0x18, 0x40, +0x88, 0x01, 0x18, 0x40, 0x24, 0xa9, 0x20, 0x40, 0x24, 0xab, 0x20, 0x40, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x12, 0x00, 0x18, 0x00, 0x12, 0x00, 0x0c, 0x00, 0x12, 0x00, 0x1c, 0x00, 0x12, 0x00, 0x24, 0xa8, 0x20, 0x40, 0xa4, 0xa8, 0x20, 0x40, 0xa4, 0xa8, 0x20, 0x40, 0x24, 0xa9, 0x20, 0x40, -0x00, 0x00, 0x00, 0x00, 0x11, 0xb2, 0x21, 0x40, 0x6d, 0xb3, 0x21, 0x40, -0x00, 0x00, 0x00, 0x00, 0x91, 0x73, 0x21, 0x40, 0x89, 0xaa, 0x21, 0x40, +0x00, 0x00, 0x00, 0x00, 0xa5, 0xb9, 0x21, 0x40, 0x01, 0xbb, 0x21, 0x40, +0x00, 0x00, 0x00, 0x00, 0x91, 0x73, 0x21, 0x40, 0x19, 0xb2, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x67, 0x92, 0x21, 0x40, 0x11, 0xb2, 0x21, 0x40, -0x39, 0x2f, 0xff, 0xff, 0xad, 0x20, 0xff, 0xff, 0x97, 0x20, 0xff, 0xff, -0xe9, 0xb0, 0x21, 0x40, 0xa0, 0x2d, 0x00, 0x80, 0xb4, 0x2d, 0x00, 0x80, -0xc8, 0x2d, 0x00, 0x80, 0x30, 0x33, 0x3a, 0x31, 0x31, 0x3a, 0x31, 0x31, -0x00, 0x30, 0x37, 0x2f, 0x32, 0x33, 0x2f, 0x30, -0x31, 0x00, 0x30, 0x30, 0x30, 0x30, 0x31, 0x35, 0x36, 0x39, 0x00, 0x43, -0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, -0x20, 0x32, 0x30, 0x30, 0x31, 0x20, 0x33, 0x43, 0x6f, 0x6d, 0x20, 0x43, -0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x00, -0x17, 0x40, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x0c, 0x53, 0xff, 0xff, 0x27, 0xf0, 0x7d, 0xfd, -0x00, 0x01, 0x00, 0x02, 0xda, 0x0e, 0x82, 0x00, 0x01, 0x40, 0x64, 0x04, -0xd0, 0x2c, 0x00, 0x80, 0x50, 0x2c, 0x00, 0x80, 0xe5, 0x3d, 0xff, 0xff, -0x49, 0x4f, 0xff, 0xff, 0x79, 0x24, 0xff, 0xff, 0x3d, 0x3b, 0xff, 0xff, -0x9d, 0x3b, 0xff, 0xff, 0xa1, 0x19, 0xff, 0xff, 0x19, 0x11, 0xff, 0xff, -0x4c, 0x53, 0xff, 0xff, 0x99, 0x3f, 0xff, 0xff, 0x91, 0x73, 0x21, 0x40, -0x51, 0x75, 0x21, 0x40, 0x51, 0x3f, 0xff, 0xff, 0x11, 0xa3, 0x21, 0x40, -0x29, 0x24, 0xff, 0xff, 0xe4, 0x52, 0xff, 0xff, 0x0c, 0x53, 0xff, 0xff, -0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, 0x30, 0x00, 0x80, -0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, -0xb8, 0x60, 0x00, 0x00, 0x74, 0x6c, 0x00, 0x00, 0x00, 0x6e, 0x21, 0x40, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, -0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, -0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, -0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, -0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, -0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, -0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, -0xfd, 0x92, 0x21, 0x40, 0x9b, 0x92, 0x21, 0x40, 0xc1, 0x95, 0x21, 0x40, -0x21, 0x96, 0x21, 0x40, 0xe9, 0x96, 0x21, 0x40, 0xa7, 0x94, 0x21, 0x40, -0xc5, 0x97, 0x21, 0x40, 0x31, 0x98, 0x21, 0x40, 0x85, 0x94, 0x21, 0x40, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xa7, 0x99, 0x21, 0x40, 0xa5, 0xb9, 0x21, 0x40, +0xb1, 0x2f, 0xff, 0xff, 0xf1, 0x20, 0xff, 0xff, 0xdb, 0x20, 0xff, 0xff, +0x2d, 0xb8, 0x21, 0x40, 0x34, 0x2e, 0x00, 0x80, 0x48, 0x2e, 0x00, 0x80, +0x5c, 0x2e, 0x00, 0x80, 0x30, 0x33, 0x3a, 0x31, 0x31, 0x3a, 0x31, 0x31, +0x00, 0x30, 0x37, 0x2f, 0x32, 0x33, 0x2f, 0x30, 0x31, 0x00, 0x30, 0x30, +0x30, 0x30, 0x31, 0x35, 0x36, 0x39, 0x00, 0x43, 0x6f, 0x70, 0x79, 0x72, +0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, +0x31, 0x20, 0x33, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, +0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x00, 0x02, 0x10, 0x00, 0x03, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x78, 0x53, 0xff, 0xff, 0x27, 0xf0, 0x7d, 0xfd, 0x00, 0x01, 0x00, 0x02, +0xda, 0x0e, 0x82, 0x00, 0x01, 0x40, 0x64, 0x04, 0x64, 0x2d, 0x00, 0x80, +0xe4, 0x2c, 0x00, 0x80, 0x55, 0x3e, 0xff, 0xff, 0xb5, 0x4f, 0xff, 0xff, +0xc1, 0x24, 0xff, 0xff, 0xb5, 0x3b, 0xff, 0xff, 0x15, 0x3c, 0xff, 0xff, +0x05, 0x1a, 0xff, 0xff, 0x65, 0x11, 0xff, 0xff, 0xb8, 0x53, 0xff, 0xff, +0x0d, 0x40, 0xff, 0xff, 0x91, 0x73, 0x21, 0x40, 0x51, 0x75, 0x21, 0x40, +0xc5, 0x3f, 0xff, 0xff, 0x71, 0xaa, 0x21, 0x40, 0x71, 0x24, 0xff, 0xff, +0x50, 0x53, 0xff, 0xff, 0x78, 0x53, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, +0xff, 0xff, 0x00, 0x00, 0x80, 0x30, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, +0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0xec, 0x68, 0x00, 0x00, +0x10, 0x5c, 0x00, 0x00, 0x00, 0x6e, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, +0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, +0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, +0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, +0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, +0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, +0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, +0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, +0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x3d, 0x9a, 0x21, 0x40, +0xdb, 0x99, 0x21, 0x40, 0xf5, 0x9c, 0x21, 0x40, 0x55, 0x9d, 0x21, 0x40, +0x1d, 0x9e, 0x21, 0x40, 0xdb, 0x9b, 0x21, 0x40, 0xf9, 0x9e, 0x21, 0x40, +0x65, 0x9f, 0x21, 0x40, 0xb9, 0x9b, 0x21, 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, @@ -2051,7 +2063,6 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -2084,92 +2095,93 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, -0xb5, 0xce, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0xa9, 0xc3, 0x21, 0x40, -0x45, 0xc5, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xcc, 0x21, 0x40, -0x59, 0xcd, 0x21, 0x40, 0xc5, 0xcd, 0x21, 0x40, 0x09, 0x29, 0x09, 0xd1, +0xe9, 0xd6, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0xb9, 0xcb, 0x21, 0x40, +0x55, 0xcd, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0x25, 0xd5, 0x21, 0x40, +0x8d, 0xd5, 0x21, 0x40, 0xf9, 0xd5, 0x21, 0x40, 0x09, 0x29, 0x09, 0xd1, 0x20, 0x28, 0x07, 0xd2, 0x04, 0x48, 0x01, 0x78, 0x00, 0x29, 0x03, 0xd1, 0x01, 0x21, 0x01, 0x70, 0x02, 0x48, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, 0x00, 0x6e, 0x21, 0x40, 0x24, 0xab, 0x20, 0x40, 0x03, 0x49, 0x88, 0x42, 0x03, 0xd1, 0x00, 0x20, 0x02, 0x49, 0xc0, 0x46, 0x08, 0x70, 0x70, 0x47, -0x24, 0xab, 0x20, 0x40, 0x00, 0x6e, 0x21, 0x40, -0x00, 0xb5, 0x00, 0x20, 0x0b, 0x4a, 0x0b, 0x23, 0x1b, 0x02, 0xd1, 0x18, -0x2d, 0x23, 0x9b, 0x01, 0xd3, 0x18, 0x48, 0x61, 0x98, 0x60, 0x98, 0x63, -0x80, 0x32, 0x88, 0x60, 0xc8, 0x60, 0x08, 0x61, 0x90, 0x62, 0x05, 0x48, -0xc0, 0x46, 0x08, 0x60, 0x48, 0x60, 0x05, 0xf0, 0xc3, 0xf9, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0xfe, 0x03, 0x00, 0x00, -0xf0, 0xb5, 0x84, 0xb0, 0x0c, 0x1c, 0x05, 0x1c, 0x00, 0x23, 0x00, 0x93, -0xff, 0xf7, 0xda, 0xff, 0x68, 0x49, 0x0b, 0x23, 0x1b, 0x02, 0xcf, 0x18, -0x38, 0x68, 0x28, 0x40, 0x00, 0x22, 0xb8, 0x60, 0xfa, 0x60, 0x7a, 0x68, -0x22, 0x40, 0x3a, 0x61, 0x0c, 0x1c, 0x41, 0x09, 0x03, 0xd2, 0x51, 0x09, -0x01, 0xd2, 0x80, 0x0a, 0x02, 0xd3, 0x60, 0x48, 0x00, 0xf0, 0xc2, 0xf8, -0x01, 0x20, 0xb9, 0x68, 0x49, 0x09, 0x03, 0xd2, 0x39, 0x69, 0x49, 0x09, -0x00, 0xd2, 0x00, 0x20, 0x00, 0x06, 0x00, 0x0e, 0x03, 0xf0, 0xf8, 0xfd, -0xb8, 0x68, 0x00, 0x28, 0x70, 0xd0, 0x00, 0x23, 0x02, 0x93, 0x01, 0x93, -0x54, 0x4a, 0x01, 0x23, 0x18, 0x43, 0xb8, 0x60, 0x00, 0x20, 0xd5, 0x1d, -0x79, 0x35, 0x03, 0x95, 0x01, 0x24, 0x00, 0x21, 0x4f, 0x4d, 0xba, 0x68, -0x22, 0x40, 0x39, 0xd0, 0x8a, 0x00, 0x52, 0x18, 0x92, 0x00, 0x4e, 0x4b, -0x9b, 0x5c, 0x1e, 0x1c, 0x83, 0x42, 0x04, 0xd0, 0x4b, 0x4b, 0xd3, 0x18, -0x5b, 0x78, 0x83, 0x42, 0x2c, 0xd1, 0x49, 0x4b, 0xd2, 0x18, 0xd3, 0x78, -0x03, 0x9d, 0xad, 0x6a, 0xab, 0x42, 0x02, 0xd9, 0x03, 0x9d, 0xc0, 0x46, -0xab, 0x62, 0x53, 0x68, 0x5b, 0x08, 0x01, 0xd3, 0x01, 0x23, 0x00, 0x93, -0x86, 0x42, 0x0a, 0xd1, 0x95, 0x68, 0x02, 0x9b, 0x5e, 0x1c, 0x02, 0x96, -0x9b, 0x00, 0x3c, 0x4e, 0x9e, 0x19, 0x0b, 0x23, 0x1b, 0x02, 0xf3, 0x18, -0x5d, 0x61, 0x53, 0x78, 0x83, 0x42, 0x0d, 0xd1, 0xd2, 0x68, 0x01, 0x9b, -0x5d, 0x1c, 0x01, 0x95, 0x9b, 0x00, 0x35, 0x4d, 0x5d, 0x19, 0x2d, 0x23, -0x9b, 0x01, 0xeb, 0x18, 0x9a, 0x60, 0xfa, 0x68, 0x01, 0x32, 0xfa, 0x60, -0x64, 0x00, 0x01, 0x31, 0x0b, 0x29, 0xbd, 0xd3, 0x01, 0x30, 0x09, 0x28, -0xb8, 0xd3, 0x00, 0x20, 0x02, 0x9b, 0x99, 0x00, 0x2b, 0x4a, 0x89, 0x18, -0x0b, 0x23, 0x1b, 0x02, 0xc9, 0x18, 0x48, 0x61, 0x01, 0x9b, 0x99, 0x00, -0x89, 0x18, 0x2d, 0x23, 0x9b, 0x01, 0xc9, 0x18, 0x88, 0x60, 0x00, 0x9b, -0x00, 0x2b, 0x0c, 0xd1, 0x81, 0x00, 0x89, 0x18, 0x0b, 0x23, 0x1b, 0x02, -0xc9, 0x18, 0x8b, 0x69, 0xc0, 0x46, 0x4b, 0x61, 0x01, 0x30, 0x0b, 0x28, -0xf4, 0xd3, 0x08, 0xe0, 0x07, 0xe0, 0x03, 0x9d, 0xa8, 0x6a, 0x30, 0x28, -0x03, 0xd2, 0x30, 0x20, 0x03, 0x9d, 0xc0, 0x46, 0xa8, 0x62, 0x19, 0x4a, -0x38, 0x69, 0x00, 0x28, 0x2a, 0xd0, 0x00, 0x21, 0x01, 0x23, 0x18, 0x43, -0x38, 0x61, 0x00, 0x20, 0x01, 0x24, 0x00, 0x22, 0x13, 0x4e, 0x3b, 0x69, +0x24, 0xab, 0x20, 0x40, 0x00, 0x6e, 0x21, 0x40, 0x00, 0xb5, 0x00, 0x20, +0x0b, 0x4a, 0x0b, 0x23, 0x1b, 0x02, 0xd1, 0x18, 0x2d, 0x23, 0x9b, 0x01, +0xd3, 0x18, 0x88, 0x61, 0xd8, 0x60, 0xd8, 0x63, 0x80, 0x32, 0xc8, 0x60, +0x08, 0x61, 0x48, 0x61, 0xd0, 0x62, 0x05, 0x48, 0xc0, 0x46, 0x48, 0x60, +0x88, 0x60, 0x05, 0xf0, 0xcb, 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x68, 0x0e, 0x00, 0x80, 0xfe, 0x03, 0x00, 0x00, 0xf0, 0xb5, 0x84, 0xb0, +0x0c, 0x1c, 0x05, 0x1c, 0x00, 0x23, 0x00, 0x93, 0xff, 0xf7, 0xda, 0xff, +0x68, 0x49, 0x0b, 0x23, 0x1b, 0x02, 0xcf, 0x18, 0x78, 0x68, 0x28, 0x40, +0x00, 0x22, 0xf8, 0x60, 0x3a, 0x61, 0xba, 0x68, 0x22, 0x40, 0x7a, 0x61, +0x0c, 0x1c, 0x41, 0x09, 0x03, 0xd2, 0x51, 0x09, 0x01, 0xd2, 0x80, 0x0a, +0x02, 0xd3, 0x60, 0x48, 0x00, 0xf0, 0xc2, 0xf8, 0x01, 0x20, 0xf9, 0x68, +0x49, 0x09, 0x03, 0xd2, 0x79, 0x69, 0x49, 0x09, 0x00, 0xd2, 0x00, 0x20, +0x00, 0x06, 0x00, 0x0e, 0x04, 0xf0, 0xc8, 0xf9, 0xf8, 0x68, 0x00, 0x28, +0x70, 0xd0, 0x00, 0x23, 0x02, 0x93, 0x01, 0x93, 0x54, 0x4a, 0x01, 0x23, +0x18, 0x43, 0xf8, 0x60, 0x00, 0x20, 0xd5, 0x1d, 0x79, 0x35, 0x03, 0x95, +0x01, 0x24, 0x00, 0x21, 0x4f, 0x4d, 0xfa, 0x68, 0x22, 0x40, 0x39, 0xd0, +0x8a, 0x00, 0x52, 0x18, 0x92, 0x00, 0x4e, 0x4b, 0x9b, 0x5c, 0x1e, 0x1c, +0x83, 0x42, 0x04, 0xd0, 0x4b, 0x4b, 0xd3, 0x18, 0x5b, 0x78, 0x83, 0x42, +0x2c, 0xd1, 0x49, 0x4b, 0xd2, 0x18, 0xd3, 0x78, 0x03, 0x9d, 0xed, 0x6a, +0xab, 0x42, 0x02, 0xd9, 0x03, 0x9d, 0xc0, 0x46, 0xeb, 0x62, 0x53, 0x68, +0x5b, 0x08, 0x01, 0xd3, 0x01, 0x23, 0x00, 0x93, 0x86, 0x42, 0x0a, 0xd1, +0x95, 0x68, 0x02, 0x9b, 0x5e, 0x1c, 0x02, 0x96, 0x9b, 0x00, 0x3c, 0x4e, +0x9e, 0x19, 0x0b, 0x23, 0x1b, 0x02, 0xf3, 0x18, 0x9d, 0x61, 0x53, 0x78, +0x83, 0x42, 0x0d, 0xd1, 0xd2, 0x68, 0x01, 0x9b, 0x5d, 0x1c, 0x01, 0x95, +0x9b, 0x00, 0x35, 0x4d, 0x5d, 0x19, 0x2d, 0x23, 0x9b, 0x01, 0xeb, 0x18, +0xda, 0x60, 0x3a, 0x69, 0x01, 0x32, 0x3a, 0x61, 0x64, 0x00, 0x01, 0x31, +0x0b, 0x29, 0xbd, 0xd3, 0x01, 0x30, 0x09, 0x28, 0xb8, 0xd3, 0x00, 0x20, +0x02, 0x9b, 0x99, 0x00, 0x2b, 0x4a, 0x89, 0x18, 0x0b, 0x23, 0x1b, 0x02, +0xc9, 0x18, 0x88, 0x61, 0x01, 0x9b, 0x99, 0x00, 0x89, 0x18, 0x2d, 0x23, +0x9b, 0x01, 0xc9, 0x18, 0xc8, 0x60, 0x00, 0x9b, 0x00, 0x2b, 0x0c, 0xd1, +0x81, 0x00, 0x89, 0x18, 0x0b, 0x23, 0x1b, 0x02, 0xc9, 0x18, 0xcb, 0x69, +0xc0, 0x46, 0x8b, 0x61, 0x01, 0x30, 0x0b, 0x28, 0xf4, 0xd3, 0x08, 0xe0, +0x07, 0xe0, 0x03, 0x9d, 0xe8, 0x6a, 0x30, 0x28, +0x03, 0xd2, 0x30, 0x20, 0x03, 0x9d, 0xc0, 0x46, 0xe8, 0x62, 0x19, 0x4a, +0x78, 0x69, 0x00, 0x28, 0x2a, 0xd0, 0x00, 0x21, 0x01, 0x23, 0x18, 0x43, +0x78, 0x61, 0x00, 0x20, 0x01, 0x24, 0x00, 0x22, 0x13, 0x4e, 0x7b, 0x69, 0x23, 0x40, 0x10, 0xd0, 0x93, 0x00, 0x9b, 0x18, 0x9b, 0x00, 0x12, 0x4d, 0x5b, 0x19, 0x9d, 0x78, 0x85, 0x42, 0x08, 0xd1, 0x1d, 0x69, 0x0b, 0x1c, -0x9b, 0x00, 0x9e, 0x19, 0x2d, 0x23, 0x9b, 0x01, 0xf3, 0x18, 0x9d, 0x63, +0x9b, 0x00, 0x9e, 0x19, 0x2d, 0x23, 0x9b, 0x01, 0xf3, 0x18, 0xdd, 0x63, 0x01, 0x31, 0x64, 0x00, 0x01, 0x32, 0x0b, 0x2a, 0xe6, 0xd3, 0x01, 0x30, 0x09, 0x28, 0xe1, 0xd3, 0x00, 0x20, 0x89, 0x00, 0x04, 0x4a, 0x89, 0x18, -0x2d, 0x23, 0x9b, 0x01, 0xc9, 0x18, 0x88, 0x63, 0x04, 0xb0, 0xf0, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0xb0, 0x52, 0xff, 0xff, -0x80, 0x00, 0x00, 0x80, 0x00, 0x47, 0x08, 0x47, -0x10, 0x47, 0x18, 0x47, 0x78, 0x47, 0xc0, 0x46, 0x34, 0xc0, 0x9f, 0xe5, -0x1c, 0xff, 0x2f, 0xe1, 0x78, 0x47, 0xc0, 0x46, 0x2c, 0xc0, 0x9f, 0xe5, -0x1c, 0xff, 0x2f, 0xe1, 0x78, 0x47, 0xc0, 0x46, 0x24, 0xc0, 0x9f, 0xe5, -0x1c, 0xff, 0x2f, 0xe1, 0xc0, 0x46, 0xff, 0xb4, 0x75, 0x46, 0x20, 0xb4, -0x01, 0x21, 0x08, 0x43, 0x01, 0xa4, 0xa6, 0x46, 0x00, 0x47, 0xc0, 0x46, -0x20, 0xbc, 0xae, 0x46, 0xff, 0xbc, 0xf7, 0x46, 0xb8, 0x51, 0xff, 0xff, -0x08, 0x51, 0xff, 0xff, 0xd7, 0xb7, 0x21, 0x40, 0xf0, 0xb5, 0x04, 0x20, -0x1a, 0x49, 0x01, 0x25, 0x08, 0x60, 0x1a, 0x4f, 0xbb, 0x23, 0x1b, 0x01, -0xf8, 0x18, 0x05, 0x72, 0x18, 0x48, 0x41, 0x6b, 0x2c, 0x05, 0x00, 0x20, -0x7a, 0x6e, 0x17, 0x4b, 0x8a, 0x42, 0x1d, 0xd0, 0x19, 0x7b, 0x00, 0x29, -0x17, 0xd1, 0xd9, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x49, 0x78, 0x1e, 0x1c, -0x00, 0x29, 0x10, 0xd1, 0xb0, 0x60, 0x10, 0x20, 0x70, 0x60, 0x10, 0x4a, -0x10, 0x49, 0xff, 0xf7, 0xb5, 0xff, 0x00, 0x28, 0x07, 0xd0, 0x35, 0x73, -0x04, 0x23, 0xb8, 0x69, 0x18, 0x43, 0xb8, 0x61, 0x20, 0x61, 0x00, 0xf0, -0x17, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x18, 0x73, 0x04, 0x23, -0xb8, 0x69, 0x98, 0x43, 0xb8, 0x61, 0x20, 0x61, 0xf5, 0xe7, 0x00, 0x00, -0x00, 0x00, 0x00, 0xb0, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x18, 0x40, -0xa8, 0x04, 0x00, 0x80, 0xa0, 0x54, 0xff, 0xff, 0x85, 0x74, 0x21, 0x40, -0xf8, 0xb5, 0x15, 0x4f, 0x39, 0x6c, 0x15, 0x48, 0x40, 0x6e, 0x0c, 0x1a, -0x14, 0x4e, 0x71, 0x68, 0x14, 0x4d, 0xa1, 0x42, 0x06, 0xd8, 0x14, 0x4a, -0x0a, 0x43, 0x00, 0x92, 0xb9, 0x6b, 0x09, 0x18, 0xfa, 0x6b, 0x11, 0xe0, -0x11, 0x22, 0x52, 0x05, 0x22, 0x43, 0x00, 0x92, 0xb9, 0x6b, 0x09, 0x18, -0x00, 0x20, 0xfa, 0x6b, 0x2b, 0x1c, 0xff, 0xf7, 0x7f, 0xff, 0x70, 0x68, -0x00, 0x1b, 0x0a, 0x4a, 0x02, 0x43, 0x00, 0x92, 0xb9, 0x6b, 0xfa, 0x6b, -0x00, 0x20, 0x2b, 0x1c, 0xff, 0xf7, 0x74, 0xff, 0xf8, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0xf8, 0x28, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, -0xa8, 0x04, 0x00, 0x80, 0x44, 0x80, 0x20, 0x40, 0x00, 0x00, 0x37, 0x02, -0xf0, 0xb5, 0x2b, 0x4f, 0xb8, 0x68, 0x79, 0x68, 0xc0, 0x19, 0x20, 0x30, -0x29, 0x4a, 0xff, 0xf7, 0x55, 0xff, 0x01, 0x20, 0xc0, 0x02, 0x28, 0x49, -0xc0, 0x46, 0x08, 0x60, 0xb9, 0x68, 0x38, 0x1c, 0x26, 0x4d, 0x00, 0x24, -0x26, 0x4e, 0xef, 0x1d, 0x79, 0x37, 0x00, 0x29, 0x31, 0xd1, 0x31, 0x68, -0x0a, 0x78, 0x12, 0x0a, 0x03, 0xd2, 0x04, 0x73, 0xf0, 0xbc, 0x08, 0xbc, +0x2d, 0x23, 0x9b, 0x01, 0xc9, 0x18, 0xc8, 0x63, 0x04, 0xb0, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x1c, 0x53, 0xff, 0xff, +0x00, 0x01, 0x00, 0x80, 0x00, 0x47, 0x08, 0x47, 0x10, 0x47, 0x18, 0x47, +0x78, 0x47, 0xc0, 0x46, 0x34, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, +0x78, 0x47, 0xc0, 0x46, 0x2c, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, +0x78, 0x47, 0xc0, 0x46, 0x24, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, +0xc0, 0x46, 0xff, 0xb4, 0x75, 0x46, 0x20, 0xb4, 0x01, 0x21, 0x08, 0x43, +0x01, 0xa4, 0xa6, 0x46, 0x00, 0x47, 0xc0, 0x46, 0x20, 0xbc, 0xae, 0x46, +0xff, 0xbc, 0xf7, 0x46, 0x24, 0x52, 0xff, 0xff, 0x74, 0x51, 0xff, 0xff, +0x51, 0xc0, 0x21, 0x40, 0xf0, 0xb5, 0x04, 0x20, 0x1a, 0x49, 0x01, 0x25, +0x08, 0x60, 0x1a, 0x4f, 0xbb, 0x23, 0x1b, 0x01, 0xf8, 0x18, 0x05, 0x73, +0x18, 0x48, 0x41, 0x6b, 0x2c, 0x05, 0x00, 0x20, 0x7a, 0x6e, 0x17, 0x4b, +0x8a, 0x42, 0x1d, 0xd0, 0x19, 0x7b, 0x00, 0x29, 0x17, 0xd1, 0xd9, 0x1d, +0xff, 0x31, 0x3a, 0x31, 0x49, 0x78, 0x1e, 0x1c, 0x00, 0x29, 0x10, 0xd1, +0xb0, 0x60, 0x10, 0x20, 0x70, 0x60, 0x10, 0x4a, 0x10, 0x49, 0xff, 0xf7, +0xb5, 0xff, 0x00, 0x28, 0x07, 0xd0, 0x35, 0x73, 0x04, 0x23, 0xb8, 0x69, +0x18, 0x43, 0xb8, 0x61, 0x20, 0x61, 0x00, 0xf0, 0x17, 0xf8, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x18, 0x73, 0x04, 0x23, 0xb8, 0x69, 0x98, 0x43, +0xb8, 0x61, 0x20, 0x61, 0xf5, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, +0x68, 0x0e, 0x00, 0x80, 0x00, 0x01, 0x18, 0x40, 0x28, 0x05, 0x00, 0x80, +0x0c, 0x55, 0xff, 0xff, 0x85, 0x74, 0x21, 0x40, 0xf8, 0xb5, 0x15, 0x4f, +0x39, 0x6c, 0x15, 0x48, 0x40, 0x6e, 0x0c, 0x1a, 0x14, 0x4e, 0x71, 0x68, +0x14, 0x4d, 0xa1, 0x42, 0x06, 0xd8, 0x14, 0x4a, 0x0a, 0x43, 0x00, 0x92, +0xb9, 0x6b, 0x09, 0x18, 0xfa, 0x6b, 0x11, 0xe0, 0x11, 0x22, 0x52, 0x05, +0x22, 0x43, 0x00, 0x92, 0xb9, 0x6b, 0x09, 0x18, 0x00, 0x20, 0xfa, 0x6b, +0x2b, 0x1c, 0xff, 0xf7, 0x7f, 0xff, 0x70, 0x68, 0x00, 0x1b, 0x0a, 0x4a, +0x02, 0x43, 0x00, 0x92, 0xb9, 0x6b, 0xfa, 0x6b, 0x00, 0x20, 0x2b, 0x1c, +0xff, 0xf7, 0x74, 0xff, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x7c, 0x29, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80, 0x28, 0x05, 0x00, 0x80, +0x44, 0x80, 0x20, 0x40, 0x00, 0x00, 0x37, 0x02, 0xf0, 0xb5, 0x2b, 0x4f, +0xb8, 0x68, 0x79, 0x68, 0xc0, 0x19, 0x20, 0x30, 0x29, 0x4a, 0xff, 0xf7, +0x55, 0xff, 0x01, 0x20, 0xc0, 0x02, 0x28, 0x49, 0xc0, 0x46, 0x08, 0x60, +0xb9, 0x68, 0x38, 0x1c, 0x26, 0x4d, 0x00, 0x24, 0x26, 0x4e, 0xef, 0x1d, +0x79, 0x37, 0x00, 0x29, 0x31, 0xd1, 0x31, 0x68, 0x0a, 0x78, 0x12, 0x0a, +0x03, 0xd2, 0x04, 0x73, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x49, 0x78, 0x00, 0x29, 0x0c, 0xd1, 0x05, 0x1c, 0x40, 0x68, 0x00, 0xf0, 0x3e, 0xf9, 0x30, 0x68, 0x00, 0xf0, 0x67, 0xf8, 0x00, 0x28, 0x26, 0xd1, 0x2c, 0x73, 0xff, 0xf7, 0x58, 0xff, 0x22, 0xe0, 0x09, 0x01, @@ -2178,85 +2190,85 @@ 0x98, 0x43, 0x99, 0x04, 0xa8, 0x61, 0x08, 0x61, 0xda, 0xe7, 0x10, 0x20, 0x00, 0xf0, 0x20, 0xf9, 0x10, 0x20, 0xb8, 0x60, 0xff, 0xf7, 0x82, 0xff, 0xd2, 0xe7, 0x05, 0x1c, 0x40, 0x68, 0x00, 0xf0, 0x17, 0xf9, 0x30, 0x68, -0x00, 0xf0, 0x40, 0xf8, 0x00, 0x28, 0xd8, 0xd0, 0x02, 0x23, 0xb8, 0x6b, -0x18, 0x43, 0xb8, 0x63, 0xc4, 0xe7, 0x00, 0x00, 0xa8, 0x04, 0x00, 0x80, -0x25, 0x55, 0xff, 0xff, 0x00, 0x00, 0x00, 0xb0, -0xe8, 0x0d, 0x00, 0x80, 0x64, 0x01, 0x00, 0x80, 0xa0, 0x54, 0xff, 0xff, -0x85, 0x74, 0x21, 0x40, 0x90, 0xb5, 0x01, 0x20, 0x40, 0x03, 0x10, 0x49, -0x00, 0x27, 0x08, 0x60, 0x0f, 0x4c, 0xe0, 0x1d, 0xff, 0x30, 0x3a, 0x30, -0x47, 0x70, 0xe0, 0x69, 0x80, 0x00, 0x00, 0x19, 0x00, 0x69, 0x00, 0xf0, -0xd7, 0xf8, 0xe0, 0x69, 0x00, 0x28, 0x01, 0xd0, 0xe7, 0x61, 0x01, 0xe0, -0x01, 0x20, 0xe0, 0x61, 0x07, 0x48, 0x02, 0x23, 0x81, 0x6b, 0x19, 0x43, -0x81, 0x63, 0x27, 0x73, 0xff, 0xf7, 0x00, 0xff, 0x90, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xa8, 0x04, 0x00, 0x80, -0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x78, 0x88, -0x6d, 0x28, 0x03, 0xdb, 0x38, 0x1c, 0x00, 0xf0, 0xf7, 0xf8, 0x17, 0xe0, -0x80, 0x00, 0x0d, 0x49, 0x09, 0x58, 0x38, 0x1c, 0xff, 0xf7, 0xbd, 0xfe, -0x00, 0x28, 0x0f, 0xd1, 0x39, 0x78, 0xc9, 0x09, 0x0c, 0xd3, 0x69, 0x46, -0x38, 0x1c, 0x00, 0xf0, 0xcf, 0xf8, 0x68, 0x46, 0x00, 0x21, 0x00, 0xf0, -0x0b, 0xf8, 0x00, 0x28, 0x01, 0xd1, 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, -0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x01, 0x00, 0x80, -0xf0, 0xb5, 0x82, 0xb0, 0x02, 0x1c, 0x41, 0x4b, 0xdd, 0x1d, 0xff, 0x35, -0x3a, 0x35, 0x2f, 0x78, 0x00, 0x2f, 0x01, 0xd0, 0x00, 0x27, 0x00, 0xe0, -0x01, 0x27, 0x2f, 0x70, 0x2f, 0x78, 0xfb, 0x00, 0xdb, 0x19, 0x5b, 0x01, -0x3a, 0x4f, 0xdc, 0x19, 0x40, 0x78, 0x00, 0x01, 0xc7, 0x1d, 0x09, 0x37, -0x00, 0x20, 0x83, 0x00, 0xd6, 0x58, 0xc0, 0x46, 0xe6, 0x50, 0x01, 0x30, -0x04, 0x28, 0xf8, 0xd3, 0x00, 0x29, 0x0f, 0xd0, 0x00, 0x22, 0xbb, 0x08, -0x01, 0x93, 0x83, 0x42, 0x0b, 0xd9, 0x13, 0x1c, 0x9b, 0x00, 0xcb, 0x58, -0x86, 0x00, 0xa3, 0x51, 0x01, 0x9b, 0x01, 0x30, 0x01, 0x32, 0x83, 0x42, -0xf5, 0xd8, 0x00, 0xe0, 0x10, 0x27, 0x2b, 0x48, 0x02, 0x6d, 0x80, 0x6e, -0x2a, 0x49, 0x82, 0x42, 0x03, 0xd8, 0x82, 0x1a, 0xcb, 0x6c, 0x9a, 0x1a, -0x00, 0xe0, 0x12, 0x1a, 0xba, 0x42, 0x05, 0xd8, 0x26, 0x48, 0x81, 0x6b, -0x01, 0x31, 0x81, 0x63, 0x01, 0x20, 0x37, 0xe0, 0xc3, 0x19, 0xca, 0x6c, -0x93, 0x42, 0x08, 0xd8, 0x22, 0x4a, 0x3a, 0x43, 0x00, 0x92, 0x0a, 0x1c, -0x49, 0x6c, 0x09, 0x18, 0x92, 0x6c, 0x23, 0x1c, 0x12, 0xe0, 0x16, 0x1a, -0x00, 0x96, 0x1b, 0x49, 0x49, 0x6c, 0x09, 0x18, 0x19, 0x48, 0x82, 0x6c, -0x03, 0x20, 0x23, 0x1c, 0xff, 0xf7, 0x50, 0xfe, 0xb8, 0x1b, 0x18, 0x4a, -0x02, 0x43, 0x00, 0x92, 0xa3, 0x19, 0x14, 0x48, 0x82, 0x6c, 0x41, 0x6c, +0x00, 0xf0, 0x40, 0xf8, 0x00, 0x28, 0xd8, 0xd0, 0x02, 0x23, 0xf8, 0x6b, +0x18, 0x43, 0xf8, 0x63, 0xc4, 0xe7, 0x00, 0x00, 0x28, 0x05, 0x00, 0x80, +0x91, 0x55, 0xff, 0xff, 0x00, 0x00, 0x00, 0xb0, 0x68, 0x0e, 0x00, 0x80, +0xe4, 0x01, 0x00, 0x80, 0x0c, 0x55, 0xff, 0xff, 0x85, 0x74, 0x21, 0x40, +0x90, 0xb5, 0x01, 0x20, 0x40, 0x03, 0x10, 0x49, 0x00, 0x27, 0x08, 0x60, +0x0f, 0x4c, 0xe0, 0x1d, 0xff, 0x30, 0x3a, 0x30, 0x47, 0x70, 0xe0, 0x69, +0x80, 0x00, 0x00, 0x19, 0x00, 0x69, 0x00, 0xf0, 0xd7, 0xf8, 0xe0, 0x69, +0x00, 0x28, 0x01, 0xd0, 0xe7, 0x61, 0x01, 0xe0, 0x01, 0x20, 0xe0, 0x61, +0x07, 0x48, 0x02, 0x23, 0xc1, 0x6b, 0x19, 0x43, 0xc1, 0x63, 0x27, 0x73, +0xff, 0xf7, 0x00, 0xff, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x00, 0x00, 0x00, 0xb0, 0x28, 0x05, 0x00, 0x80, 0xe8, 0x0e, 0x00, 0x80, +0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x78, 0x88, 0x6d, 0x28, 0x03, 0xdb, +0x38, 0x1c, 0x00, 0xf0, 0xf7, 0xf8, 0x17, 0xe0, 0x80, 0x00, 0x0d, 0x49, +0x09, 0x58, 0x38, 0x1c, 0xff, 0xf7, 0xbd, 0xfe, 0x00, 0x28, 0x0f, 0xd1, +0x39, 0x78, 0xc9, 0x09, 0x0c, 0xd3, 0x69, 0x46, 0x38, 0x1c, 0x00, 0xf0, +0xcf, 0xf8, 0x68, 0x46, 0x00, 0x21, 0x00, 0xf0, 0x0b, 0xf8, 0x00, 0x28, +0x01, 0xd1, 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, 0x04, 0xb0, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0xe8, 0x01, 0x00, 0x80, 0xf0, 0xb5, 0x82, 0xb0, +0x02, 0x1c, 0x41, 0x4b, 0xdd, 0x1d, 0xff, 0x35, 0x3a, 0x35, 0x2f, 0x78, +0x00, 0x2f, 0x01, 0xd0, 0x00, 0x27, 0x00, 0xe0, 0x01, 0x27, 0x2f, 0x70, +0x2f, 0x78, 0xfb, 0x00, 0xdb, 0x19, 0x5b, 0x01, 0x3a, 0x4f, 0xdc, 0x19, +0x40, 0x78, 0x00, 0x01, 0xc7, 0x1d, 0x09, 0x37, 0x00, 0x20, 0x83, 0x00, +0xd6, 0x58, 0xc0, 0x46, 0xe6, 0x50, 0x01, 0x30, 0x04, 0x28, 0xf8, 0xd3, +0x00, 0x29, 0x0f, 0xd0, 0x00, 0x22, 0xbb, 0x08, 0x01, 0x93, 0x83, 0x42, +0x0b, 0xd9, 0x13, 0x1c, 0x9b, 0x00, 0xcb, 0x58, 0x86, 0x00, 0xa3, 0x51, +0x01, 0x9b, 0x01, 0x30, 0x01, 0x32, 0x83, 0x42, 0xf5, 0xd8, 0x00, 0xe0, +0x10, 0x27, 0x2b, 0x48, 0x02, 0x6d, 0x80, 0x6e, 0x2a, 0x49, 0x82, 0x42, +0x03, 0xd8, 0x82, 0x1a, 0xcb, 0x6c, 0x9a, 0x1a, 0x00, 0xe0, 0x12, 0x1a, +0xba, 0x42, 0x05, 0xd8, 0x26, 0x48, 0x81, 0x6b, 0x01, 0x31, 0x81, 0x63, +0x01, 0x20, 0x37, 0xe0, 0xc3, 0x19, 0xca, 0x6c, 0x93, 0x42, 0x08, 0xd8, +0x22, 0x4a, 0x3a, 0x43, 0x00, 0x92, 0x0a, 0x1c, 0x49, 0x6c, 0x09, 0x18, +0x92, 0x6c, 0x23, 0x1c, 0x12, 0xe0, 0x16, 0x1a, 0x00, 0x96, 0x1b, 0x49, +0x49, 0x6c, 0x09, 0x18, 0x19, 0x48, 0x82, 0x6c, 0x03, 0x20, 0x23, 0x1c, +0xff, 0xf7, 0x50, 0xfe, 0xb8, 0x1b, 0x18, 0x4a, 0x02, 0x43, 0x00, 0x92, +0xa3, 0x19, 0x14, 0x48, 0x82, 0x6c, 0x41, 0x6c, 0x03, 0x20, 0xff, 0xf7, 0x45, 0xfe, 0x01, 0x20, 0x0d, 0x49, 0xc0, 0x46, 0x68, 0x70, 0x8a, 0x69, 0x92, 0x00, 0x52, 0x18, 0x17, 0x61, 0x8a, 0x69, 0x00, 0x2a, 0x02, 0xd0, 0x00, 0x27, 0x8f, 0x61, 0x00, 0xe0, 0x88, 0x61, -0x0c, 0x48, 0x02, 0x23, 0x81, 0x6b, 0x19, 0x43, 0x81, 0x63, 0x00, 0x20, -0x01, 0x27, 0x0a, 0x49, 0xc0, 0x46, 0x4f, 0x72, 0x02, 0xb0, 0xf0, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0xa8, 0x04, 0x00, 0x80, 0xfc, 0xba, 0x20, 0x40, -0xe8, 0x0d, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, -0x00, 0x00, 0x19, 0x02, 0x68, 0x0e, 0x00, 0x80, 0x98, 0x19, 0x00, 0x80, +0x0c, 0x48, 0x02, 0x23, 0xc1, 0x6b, 0x19, 0x43, 0xc1, 0x63, 0x00, 0x20, +0x01, 0x27, 0x0a, 0x49, 0xc0, 0x46, 0x4f, 0x73, 0x02, 0xb0, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x28, 0x05, 0x00, 0x80, 0xfc, 0xba, 0x20, 0x40, +0x68, 0x0e, 0x00, 0x80, 0x7c, 0x29, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, +0x00, 0x00, 0x19, 0x02, 0xe8, 0x0e, 0x00, 0x80, 0x18, 0x1a, 0x00, 0x80, 0x07, 0x49, 0x8a, 0x6e, 0x10, 0x18, 0x07, 0x4a, 0xd2, 0x6c, 0x13, 0x04, 0x1b, 0x0c, 0x83, 0x42, 0x00, 0xd8, 0x80, 0x1a, 0x88, 0x66, 0x88, 0x6e, -0x03, 0x49, 0xc0, 0x46, 0x48, 0x61, 0x70, 0x47, -0xe8, 0x0d, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, -0x06, 0x49, 0x4a, 0x6e, 0x10, 0x18, 0x06, 0x4a, 0x12, 0x6c, 0x82, 0x42, -0x00, 0xd8, 0x80, 0x1a, 0x48, 0x66, 0x48, 0x6e, 0x03, 0x49, 0xc0, 0x46, -0x08, 0x61, 0x70, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, -0x3c, 0xef, 0x20, 0x40, 0x05, 0x22, 0x0a, 0x60, 0x82, 0x88, 0xc0, 0x46, -0x8a, 0x80, 0x00, 0x22, 0x4a, 0x70, 0x40, 0x88, 0xc0, 0x46, 0x48, 0x80, -0xca, 0x80, 0x8a, 0x60, 0xca, 0x60, 0x70, 0x47, 0x05, 0x22, 0x02, 0x60, -0x00, 0x22, 0x82, 0x80, 0x42, 0x70, 0x41, 0x80, 0xc2, 0x80, 0x82, 0x60, -0xc2, 0x60, 0x70, 0x47, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x0e, 0x48, -0x41, 0x6b, 0x01, 0x31, 0x41, 0x63, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, -0xdd, 0xff, 0x38, 0x68, 0xc0, 0x46, 0x00, 0x90, 0x45, 0x20, 0x00, 0xab, -0x18, 0x70, 0x01, 0x27, 0xdf, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, -0x11, 0xff, 0x00, 0x28, 0x01, 0xd1, 0x38, 0x1c, 0x00, 0xe0, 0x00, 0x20, -0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xa0, 0x82, 0x20, 0x40, -0x00, 0xb5, 0x84, 0xb0, 0xc1, 0x88, 0x09, 0x4a, 0xc0, 0x46, 0x11, 0x81, -0x69, 0x46, 0xff, 0xf7, 0xbd, 0xff, 0x01, 0x20, 0x40, 0x02, 0x01, 0xab, -0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0xf5, 0xfe, 0x01, 0x20, -0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, -0x00, 0xb5, 0xff, 0xf7, 0xc3, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, -0x03, 0x49, 0xc0, 0x46, 0x08, 0x70, 0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, -0x00, 0x20, 0x70, 0x47, 0xa8, 0x0e, 0x00, 0x80, 0x00, 0x20, 0x04, 0x49, -0xc0, 0x46, 0x08, 0x70, 0xff, 0x21, 0xa1, 0x22, 0x52, 0x03, 0x01, 0x31, -0x91, 0x60, 0x70, 0x47, 0xa8, 0x0e, 0x00, 0x80, 0x02, 0x20, 0xa1, 0x21, -0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0x70, 0x47, 0x01, 0x20, 0x40, 0x02, -0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0x70, 0x47, 0xc0, 0x88, -0xc0, 0x06, 0xc0, 0x0e, 0xa1, 0x21, 0x49, 0x03, 0x48, 0x61, 0x02, 0x49, -0xc0, 0x46, 0x88, 0x63, 0x00, 0x20, 0x70, 0x47, 0x68, 0x1a, 0x00, 0x80, -0x80, 0xb5, 0x84, 0xb0, 0x08, 0x49, 0x0f, 0x6b, 0x69, 0x46, 0xff, 0xf7, -0x71, 0xff, 0xf8, 0x06, 0xc0, 0x0e, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, -0x00, 0x21, 0xff, 0xf7, 0xa9, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x80, 0x00, 0x14, 0x40, 0x80, 0xb5, 0x85, 0xb0, -0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, 0x5b, 0xff, 0xf8, 0x88, -0x04, 0xa9, 0x04, 0xf0, 0xef, 0xfd, 0x01, 0xab, 0x58, 0x80, 0x01, 0xa8, +0x03, 0x49, 0xc0, 0x46, 0x48, 0x61, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, +0x7c, 0x29, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, 0x06, 0x49, 0x4a, 0x6e, +0x10, 0x18, 0x06, 0x4a, 0x12, 0x6c, 0x82, 0x42, 0x00, 0xd8, 0x80, 0x1a, +0x48, 0x66, 0x48, 0x6e, 0x03, 0x49, 0xc0, 0x46, 0x08, 0x61, 0x70, 0x47, +0x68, 0x0e, 0x00, 0x80, 0x7c, 0x29, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, +0x05, 0x22, 0x0a, 0x60, 0x82, 0x88, 0xc0, 0x46, 0x8a, 0x80, 0x00, 0x22, +0x4a, 0x70, 0x40, 0x88, 0xc0, 0x46, 0x48, 0x80, 0xca, 0x80, 0x8a, 0x60, +0xca, 0x60, 0x70, 0x47, 0x05, 0x22, 0x02, 0x60, 0x00, 0x22, 0x82, 0x80, +0x42, 0x70, 0x41, 0x80, 0xc2, 0x80, 0x82, 0x60, 0xc2, 0x60, 0x70, 0x47, +0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x0e, 0x48, 0x41, 0x6b, 0x01, 0x31, +0x41, 0x63, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, 0xdd, 0xff, 0x38, 0x68, +0xc0, 0x46, 0x00, 0x90, 0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x01, 0x27, +0xdf, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x11, 0xff, 0x00, 0x28, +0x01, 0xd1, 0x38, 0x1c, 0x00, 0xe0, 0x00, 0x20, 0x04, 0xb0, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0xa0, 0x82, 0x20, 0x40, 0x00, 0xb5, 0x84, 0xb0, +0xc1, 0x88, 0x09, 0x4a, 0xc0, 0x46, 0x91, 0x81, 0x69, 0x46, 0xff, 0xf7, +0xbd, 0xff, 0x01, 0x20, 0x40, 0x02, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, +0x00, 0x21, 0xff, 0xf7, 0xf5, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0xe8, 0x0e, 0x00, 0x80, 0x00, 0xb5, 0xff, 0xf7, +0xc3, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, 0x03, 0x49, 0xc0, 0x46, +0x08, 0x71, 0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0x70, 0x47, +0x28, 0x0f, 0x00, 0x80, 0x00, 0x20, 0x04, 0x49, 0xc0, 0x46, 0x08, 0x71, +0xff, 0x21, 0xa1, 0x22, 0x52, 0x03, 0x01, 0x31, 0x91, 0x60, 0x70, 0x47, +0x28, 0x0f, 0x00, 0x80, 0x02, 0x20, 0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, +0x00, 0x20, 0x70, 0x47, 0x01, 0x20, 0x40, 0x02, 0xa1, 0x21, 0x49, 0x03, +0x88, 0x60, 0x00, 0x20, 0x70, 0x47, 0xc0, 0x88, 0xc0, 0x06, 0xc0, 0x0e, +0xa1, 0x21, 0x49, 0x03, 0x48, 0x61, 0x02, 0x49, 0xc0, 0x46, 0xc8, 0x63, +0x00, 0x20, 0x70, 0x47, 0xe8, 0x1a, 0x00, 0x80, 0x80, 0xb5, 0x84, 0xb0, +0x08, 0x49, 0x0f, 0x6b, 0x69, 0x46, 0xff, 0xf7, 0x71, 0xff, 0xf8, 0x06, +0xc0, 0x0e, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, +0xa9, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x80, 0x00, 0x14, 0x40, 0x80, 0xb5, 0x85, 0xb0, 0x07, 0x1c, 0x69, 0x46, +0x38, 0x1c, 0xff, 0xf7, 0x5b, 0xff, 0xf8, 0x88, +0x04, 0xa9, 0x05, 0xf0, 0xf7, 0xf9, 0x01, 0xab, 0x58, 0x80, 0x01, 0xa8, 0x40, 0x88, 0x00, 0x28, 0x0f, 0xd0, 0x01, 0xa8, 0x40, 0x88, 0x80, 0x08, 0x03, 0x38, 0x80, 0x08, 0x01, 0x30, 0x04, 0x3b, 0x58, 0x70, 0x04, 0x98, 0x01, 0x68, 0xc0, 0x46, 0x02, 0x91, 0x40, 0x68, 0xc0, 0x46, 0x03, 0x90, @@ -2266,52 +2278,54 @@ 0x90, 0xb5, 0x84, 0xb0, 0x14, 0x4f, 0x39, 0x7b, 0x00, 0x29, 0x20, 0xd1, 0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x49, 0x78, 0x00, 0x29, 0x1a, 0xd1, 0x10, 0x49, 0x05, 0x22, 0x00, 0x92, 0x08, 0x22, 0x00, 0xab, 0x5a, 0x80, -0x98, 0x80, 0x06, 0x20, 0x00, 0xab, 0x58, 0x70, -0x00, 0x24, 0xdc, 0x80, 0x08, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x48, 0x68, -0xc0, 0x46, 0x03, 0x90, 0x01, 0x20, 0x38, 0x73, 0x68, 0x46, 0x08, 0x31, -0xff, 0xf7, 0x4c, 0xfe, 0x00, 0x28, 0x00, 0xd0, 0x3c, 0x73, 0x04, 0xb0, -0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xa8, 0x04, 0x00, 0x80, -0x10, 0x2a, 0x00, 0x80, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, -0x38, 0x1c, 0xff, 0xf7, 0xf9, 0xfe, 0xba, 0x68, 0x0d, 0x4c, 0x0e, 0x48, -0x00, 0x2a, 0x05, 0xd1, 0x0d, 0x49, 0xff, 0xf7, 0xd6, 0xfc, 0x00, 0x28, -0x0c, 0xda, 0x05, 0xe0, 0xb9, 0x88, 0x0b, 0x4b, 0xff, 0xf7, 0xd1, 0xfc, -0x00, 0x28, 0x05, 0xda, 0x01, 0xab, 0x5c, 0x80, 0x68, 0x46, 0x00, 0x21, -0xff, 0xf7, 0x22, 0xfe, 0x00, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x15, 0x79, 0x21, 0x40, -0x59, 0xcd, 0x21, 0x40, 0xf1, 0xcc, 0x21, 0x40, 0x00, 0xb5, 0xc0, 0x88, -0x04, 0xf0, 0x54, 0xfd, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, -0xff, 0xf7, 0xe2, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, -0xdd, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, 0x1c, 0x02, 0x20, -0x00, 0xf0, 0x02, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0xc6, 0xb0, -0x04, 0x1c, 0x08, 0x1c, 0x69, 0x46, 0xff, 0xf7, 0xb5, 0xfe, 0x1b, 0x48, -0xff, 0xf7, 0x96, 0xfc, 0x07, 0x1c, 0x00, 0x21, 0x20, 0x1c, 0x03, 0xf0, -0x4f, 0xff, 0x00, 0x28, 0x1c, 0xd0, 0x20, 0x1c, 0x04, 0xa9, 0x03, 0xf0, -0x2d, 0xfe, 0x04, 0x98, 0x04, 0x28, 0x05, 0xd9, 0x04, 0x98, 0x80, 0x08, +0x98, 0x80, 0x06, 0x20, 0x00, 0xab, 0x58, 0x70, 0x00, 0x24, 0xdc, 0x80, +0x08, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x48, 0x68, 0xc0, 0x46, 0x03, 0x90, +0x01, 0x20, 0x38, 0x73, 0x68, 0x46, 0x08, 0x31, 0xff, 0xf7, 0x4c, 0xfe, +0x00, 0x28, 0x00, 0xd0, 0x3c, 0x73, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x28, 0x05, 0x00, 0x80, 0xa4, 0x2a, 0x00, 0x80, +0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, +0xf9, 0xfe, 0xba, 0x68, 0x0d, 0x4c, 0x0e, 0x48, 0x00, 0x2a, 0x05, 0xd1, +0x0d, 0x49, 0xff, 0xf7, 0xd6, 0xfc, 0x00, 0x28, 0x0c, 0xda, 0x05, 0xe0, +0xb9, 0x88, 0x0b, 0x4b, 0xff, 0xf7, 0xd1, 0xfc, 0x00, 0x28, 0x05, 0xda, +0x01, 0xab, 0x5c, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x22, 0xfe, +0x00, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0xff, 0xff, 0x00, 0x00, 0x15, 0x79, 0x21, 0x40, 0x8d, 0xd5, 0x21, 0x40, +0x25, 0xd5, 0x21, 0x40, 0x00, 0xb5, 0xc0, 0x88, 0x05, 0xf0, 0x5c, 0xf9, +0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, 0xe2, 0xfe, +0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, 0xdd, 0xfe, 0x08, 0xbc, +0x18, 0x47, 0x00, 0xb5, 0x01, 0x1c, 0x02, 0x20, 0x00, 0xf0, 0x02, 0xf8, +0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0xc6, 0xb0, 0x04, 0x1c, 0x08, 0x1c, +0x69, 0x46, 0xff, 0xf7, 0xb5, 0xfe, 0x1c, 0x48, 0xff, 0xf7, 0x96, 0xfc, +0x07, 0x1c, 0x1b, 0x4a, 0x00, 0x21, 0x20, 0x1c, 0xff, 0xf7, 0x92, 0xfc, +0x00, 0x28, 0x1d, 0xd0, 0x04, 0xa9, 0x18, 0x4a, 0x20, 0x1c, 0xff, 0xf7, +0x8b, 0xfc, 0x04, 0x98, 0x04, 0x28, 0x05, 0xd9, 0x04, 0x98, 0x80, 0x08, 0x03, 0x38, 0x80, 0x08, 0x01, 0x30, 0x00, 0xe0, 0x00, 0x20, 0x00, 0xab, 0x58, 0x70, 0x06, 0xa8, 0x00, 0x78, 0xc0, 0x46, 0xd8, 0x80, 0x04, 0x98, 0xc0, 0x46, 0x02, 0x90, 0x07, 0x98, 0xc0, 0x46, 0x03, 0x90, 0x04, 0x33, -0x08, 0xad, 0x02, 0xe0, 0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x07, 0x49, -0x38, 0x1c, 0xff, 0xf7, 0x6c, 0xfc, 0x68, 0x46, 0x29, 0x1c, 0xff, 0xf7, -0xc3, 0xfd, 0x01, 0x20, 0x46, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0x01, 0x1c, -0x02, 0x20, 0x00, 0xf0, 0x10, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, -0x01, 0x1c, 0x01, 0x20, 0xff, 0xf7, 0xb2, 0xff, 0x08, 0xbc, 0x18, 0x47, -0x00, 0xb5, 0x01, 0x1c, 0x01, 0x20, 0x00, 0xf0, 0x02, 0xf8, 0x08, 0xbc, -0x18, 0x47, 0xf3, 0xb5, 0xc6, 0xb0, 0x0f, 0x1c, 0x69, 0x46, 0x38, 0x1c, -0xff, 0xf7, 0x5e, 0xfe, 0x1c, 0x48, 0xff, 0xf7, 0x3f, 0xfc, 0xba, 0x68, -0x04, 0x1c, 0xfc, 0x2a, 0x1f, 0xd8, 0xfd, 0x88, 0xf8, 0x68, 0xc0, 0x46, -0x04, 0x90, 0xf9, 0x1d, 0x09, 0x31, 0x05, 0xab, 0x00, 0x20, 0x7e, 0x78, -0x00, 0x2e, 0x0d, 0xdd, 0x40, 0xc9, 0x40, 0xc3, 0x40, 0xc9, 0x40, 0xc3, -0x40, 0xc9, 0x40, 0xc3, 0x40, 0xc9, 0x40, 0xc3, 0x01, 0x30, 0x00, 0x04, -0x00, 0x0c, 0x7e, 0x78, 0x86, 0x42, 0xf1, 0xdc, 0x46, 0x98, 0x04, 0xa9, -0x2b, 0x1c, 0xff, 0xf7, 0x2d, 0xfc, 0x00, 0x28, 0x05, 0xd0, 0x00, 0xa8, -0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x07, 0x49, -0x20, 0x1c, 0xff, 0xf7, 0x12, 0xfc, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, -0x69, 0xfd, 0x01, 0x20, 0x48, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0xff, 0xf7, -0x35, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, +0x08, 0xad, 0x02, 0xe0, 0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x09, 0x49, +0x38, 0x1c, 0xff, 0xf7, 0x6a, 0xfc, 0x68, 0x46, 0x29, 0x1c, 0xff, 0xf7, +0xc1, 0xfd, 0x01, 0x20, 0x46, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x24, 0x02, 0xff, 0xff, 0xcd, 0xc0, 0x21, 0x40, 0x29, 0xbf, 0x21, 0x40, +0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0x01, 0x1c, 0x02, 0x20, 0x00, 0xf0, +0x10, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, 0x1c, 0x01, 0x20, +0xff, 0xf7, 0xac, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, 0x1c, +0x01, 0x20, 0x00, 0xf0, 0x02, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0xf3, 0xb5, +0xc6, 0xb0, 0x0f, 0x1c, 0x69, 0x46, 0x38, 0x1c, +0xff, 0xf7, 0x58, 0xfe, 0x20, 0x48, 0xff, 0xf7, 0x39, 0xfc, 0x04, 0x1c, +0x78, 0x78, 0x00, 0x01, 0xba, 0x68, 0x04, 0x30, 0xfc, 0x2a, 0x23, 0xd8, +0xff, 0x23, 0x09, 0x33, 0x98, 0x42, 0x1f, 0xd8, 0xfd, 0x88, 0xf8, 0x68, +0xc0, 0x46, 0x04, 0x90, 0x05, 0xa9, 0xfb, 0x1d, 0x09, 0x33, 0x00, 0x20, +0x7e, 0x78, 0x00, 0x2e, 0x0d, 0xdd, 0x40, 0xcb, 0x40, 0xc1, 0x40, 0xcb, +0x40, 0xc1, 0x40, 0xcb, 0x40, 0xc1, 0x40, 0xcb, 0x40, 0xc1, 0x01, 0x30, +0x00, 0x04, 0x00, 0x0c, 0x7e, 0x78, 0x86, 0x42, 0xf1, 0xdc, 0x46, 0x98, +0x04, 0xa9, 0x2b, 0x1c, 0xff, 0xf7, 0x20, 0xfc, 0x00, 0x28, 0x05, 0xd0, +0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, +0x07, 0x49, 0x20, 0x1c, 0xff, 0xf7, 0x05, 0xfc, 0x68, 0x46, 0x00, 0x21, +0xff, 0xf7, 0x5c, 0xfd, 0x01, 0x20, 0x48, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, +0x00, 0xb5, 0xff, 0xf7, 0x27, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0xc6, 0xb0, 0x07, 0x1c, 0xfc, 0x88, 0x25, 0x4d, 0x68, 0x68, 0x01, 0x30, -0x69, 0x46, 0x68, 0x60, 0x38, 0x1c, 0xff, 0xf7, 0x0f, 0xfe, 0x10, 0x2c, +0x69, 0x46, 0x68, 0x60, 0x38, 0x1c, 0xff, 0xf7, 0x01, 0xfe, 0x10, 0x2c, 0x08, 0xd3, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x17, 0xe0, 0x78, 0x78, 0x82, 0x00, 0xfb, 0x1d, 0x09, 0x33, 0x00, 0x20, 0xb9, 0x68, 0x00, 0x2a, 0x15, 0xd9, @@ -2322,1121 +2336,1275 @@ 0x02, 0x94, 0x69, 0x68, 0xc0, 0x46, 0x03, 0x91, 0xa2, 0x00, 0x00, 0x20, 0x10, 0x33, 0x00, 0x2a, 0x05, 0xd9, 0x0f, 0x1c, 0x80, 0xc3, 0x01, 0x30, 0x01, 0x31, 0x90, 0x42, 0xf9, 0xd3, 0x68, 0x46, 0x04, 0xa9, 0xff, 0xf7, -0x11, 0xfd, 0x01, 0x20, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x1c, 0x03, 0x00, 0x80, 0x90, 0xb4, 0x22, 0x48, 0x00, 0x68, 0x01, 0x21, +0x03, 0xfd, 0x01, 0x20, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x9c, 0x03, 0x00, 0x80, 0x90, 0xb4, 0x23, 0x48, 0x00, 0x68, 0x01, 0x21, 0x42, 0x09, 0x00, 0xd3, 0x00, 0x21, 0x00, 0x27, 0x3a, 0x1c, 0x43, 0x0b, -0x00, 0xd2, 0x02, 0x22, 0x11, 0x43, 0x1d, 0x4a, 0x20, 0x24, 0xd3, 0x68, -0x01, 0x2b, 0x2c, 0xd1, 0x80, 0x0a, 0x00, 0xd2, 0x00, 0x24, 0x0c, 0x43, -0x20, 0x1c, 0x1b, 0x23, 0xdb, 0x01, 0xd1, 0x18, 0x09, 0x8b, 0x09, 0x0b, -0x00, 0xd2, 0x04, 0x27, 0x38, 0x43, 0xd1, 0x6f, 0x09, 0x0a, 0x06, 0xd2, -0xd1, 0x1d, 0x79, 0x31, 0x09, 0x68, 0x09, 0x0a, 0x01, 0xd3, 0x08, 0x23, -0x18, 0x43, 0xe3, 0x23, 0x1b, 0x01, 0xd1, 0x18, 0x89, 0x78, 0x03, 0x29, -0x02, 0xd1, 0xff, 0x23, 0x01, 0x33, 0x18, 0x43, 0x0b, 0x49, 0x09, 0x6a, -0x10, 0x22, 0x4b, 0x0a, 0x00, 0xd2, 0x00, 0x22, 0x10, 0x43, 0x89, 0x07, -0x89, 0x0f, 0x89, 0x01, 0x08, 0x43, 0x90, 0xbc, 0x70, 0x47, 0x40, 0x0c, -0x00, 0xd2, 0x00, 0x24, 0x0c, 0x43, 0x20, 0x1c, 0xec, 0xe7, 0x00, 0x00, -0x00, 0x00, 0x10, 0x40, 0xe8, 0x0d, 0x00, 0x80, 0xc0, 0x00, 0x18, 0x40, -0xf0, 0xb5, 0x33, 0x4d, 0x28, 0x1c, 0x05, 0xf0, 0x6b, 0xf8, 0x32, 0x49, -0xe3, 0x23, 0x1b, 0x01, 0xcf, 0x18, 0xba, 0x78, 0x30, 0x4e, 0x00, 0x20, -0xcc, 0x1d, 0x79, 0x34, 0x05, 0x2a, 0x53, 0xd2, 0x01, 0xa3, 0x9b, 0x5c, -0x5b, 0x00, 0x9f, 0x44, 0x02, 0x0e, 0x23, 0x3c, 0x3e, 0x00, 0x01, 0x21, -0xb9, 0x70, 0xb0, 0x60, 0xff, 0xf7, 0x98, 0xff, 0x04, 0x23, 0x98, 0x43, -0x00, 0xf0, 0x62, 0xf8, 0x14, 0x22, 0x28, 0x1c, 0x0e, 0xe0, 0xff, 0xf7, -0x8f, 0xff, 0xc0, 0x08, 0x06, 0xd3, 0xb1, 0x68, 0x48, 0x1c, 0xb0, 0x60, -0x0a, 0x29, 0x03, 0xd9, 0x04, 0x20, 0x00, 0xe0, 0x02, 0x20, 0xb8, 0x70, -0x02, 0x22, 0x28, 0x1c, 0x00, 0x21, 0x05, 0xf0, 0x07, 0xf8, 0xf0, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x80, 0x23, 0xc8, 0x6f, 0x18, 0x43, 0xc8, 0x67, -0x18, 0x4e, 0xc0, 0x46, 0x30, 0x60, 0x03, 0x20, 0xb8, 0x70, 0x28, 0x1c, -0x16, 0x4a, 0x00, 0x21, 0x04, 0xf0, 0xf6, 0xff, 0x11, 0x48, 0x04, 0x23, -0xc1, 0x6f, 0x99, 0x43, 0xc1, 0x67, 0x31, 0x60, 0x20, 0x68, 0x18, 0x43, -0x20, 0x60, 0x70, 0x60, 0xe3, 0xe7, 0x05, 0x21, 0xb9, 0x70, 0x51, 0x21, -0x89, 0x03, 0x08, 0x62, 0x04, 0x23, 0x20, 0x68, 0x98, 0x43, 0x20, 0x60, -0x09, 0x4e, 0xc0, 0x46, 0x70, 0x60, 0xff, 0xf7, 0x55, 0xff, 0x04, 0x23, -0x18, 0x43, 0x00, 0xf0, 0x1f, 0xf8, 0xd0, 0xe7, -0x06, 0x20, 0xb8, 0x70, 0xcd, 0xe7, 0x00, 0x00, 0x79, 0x7c, 0x21, 0x40, -0xe8, 0x0d, 0x00, 0x80, 0x1c, 0x03, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, -0x88, 0x13, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x20, 0x04, 0x49, 0xc0, 0x46, -0x88, 0x70, 0x04, 0x48, 0x01, 0x22, 0x00, 0x21, 0x04, 0xf0, 0xc0, 0xff, -0x08, 0xbc, 0x18, 0x47, 0x18, 0x1c, 0x00, 0x80, 0x79, 0x7c, 0x21, 0x40, -0x90, 0xb5, 0x07, 0x1c, 0x30, 0x48, 0x00, 0x68, 0x01, 0x1c, 0x7a, 0x08, -0x02, 0xd3, 0x10, 0x23, 0x98, 0x43, 0x01, 0xe0, 0x10, 0x23, 0x18, 0x43, -0xba, 0x08, 0x03, 0xd3, 0x01, 0x23, 0x1b, 0x03, 0x98, 0x43, 0x02, 0xe0, -0x01, 0x23, 0x1b, 0x03, 0x18, 0x43, 0x88, 0x42, 0x02, 0xd0, 0x01, 0x21, -0x09, 0x05, 0x08, 0x60, 0x25, 0x4c, 0xe0, 0x68, 0x01, 0x28, 0x1e, 0xd1, -0x1b, 0x23, 0xdb, 0x01, 0xe0, 0x18, 0x00, 0x8b, 0xf9, 0x08, 0x04, 0xd3, -0x01, 0x23, 0xdb, 0x02, 0x01, 0x1c, 0x99, 0x43, 0x01, 0xe0, 0x01, 0x21, -0xc9, 0x02, 0x81, 0x42, 0x02, 0xd0, 0x00, 0x20, 0x02, 0xf0, 0x20, 0xfe, -0x08, 0x21, 0x39, 0x40, 0x1a, 0x48, 0x03, 0xd0, 0x80, 0x23, 0xe1, 0x6f, -0x99, 0x43, 0x02, 0xe0, 0x80, 0x23, 0xe1, 0x6f, 0x19, 0x43, 0xe1, 0x67, -0x01, 0x60, 0x16, 0x48, 0x01, 0x6a, 0x78, 0x09, 0x03, 0xd3, 0xff, 0x20, +0x00, 0xd2, 0x02, 0x22, 0x11, 0x43, 0x1e, 0x4a, 0x20, 0x24, 0xd3, 0x68, +0x01, 0x2b, 0x2e, 0xd1, 0x80, 0x0a, 0x00, 0xd2, 0x00, 0x24, 0x0c, 0x43, +0x20, 0x1c, 0x1b, 0x23, 0xdb, 0x01, 0xd1, 0x18, 0x89, 0x8b, 0x09, 0x0b, +0x00, 0xd2, 0x04, 0x27, 0x38, 0x43, 0xd1, 0x6f, 0x09, 0x68, 0x09, 0x0a, +0x07, 0xd2, 0xd1, 0x1d, 0x79, 0x31, 0x09, 0x68, 0x09, 0x68, 0x09, 0x0a, +0x01, 0xd3, 0x08, 0x23, 0x18, 0x43, 0xe3, 0x23, 0x1b, 0x01, 0xd1, 0x18, +0x89, 0x79, 0x03, 0x29, 0x02, 0xd1, 0xff, 0x23, 0x01, 0x33, 0x18, 0x43, +0x0b, 0x49, 0x09, 0x6a, 0x10, 0x22, 0x4b, 0x0a, 0x00, 0xd2, 0x00, 0x22, +0x10, 0x43, 0x89, 0x07, 0x89, 0x0f, 0x89, 0x01, 0x08, 0x43, 0x90, 0xbc, +0x70, 0x47, 0x40, 0x0c, 0x00, 0xd2, 0x00, 0x24, 0x0c, 0x43, 0x20, 0x1c, +0xec, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x68, 0x0e, 0x00, 0x80, +0xc0, 0x00, 0x18, 0x40, 0xf0, 0xb5, 0x3a, 0x4c, 0x20, 0x1c, 0x05, 0xf0, +0x75, 0xfc, 0x39, 0x48, 0xe3, 0x23, 0x1b, 0x01, 0xc7, 0x18, 0xb9, 0x79, +0x37, 0x4e, 0xc5, 0x1d, 0x79, 0x35, 0x06, 0x29, 0x62, 0xd2, 0x02, 0xa3, +0x5b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, +0x03, 0x0e, 0x1e, 0x37, 0x4e, 0x55, 0x01, 0x20, 0xb8, 0x71, 0x00, 0x20, +0xb0, 0x60, 0xff, 0xf7, 0x95, 0xff, 0x05, 0x23, 0x98, 0x43, 0x00, 0xf0, +0x6f, 0xf8, 0x0c, 0xe0, 0xff, 0xf7, 0x8e, 0xff, 0xc0, 0x08, 0x06, 0xd3, +0xb0, 0x68, 0x41, 0x1c, 0xb1, 0x60, 0x0a, 0x28, 0x03, 0xd9, 0x04, 0x20, +0x00, 0xe0, 0x02, 0x20, 0xb8, 0x71, 0x64, 0x22, 0x20, 0x1c, 0x2b, 0xe0, +0x06, 0x1c, 0xc0, 0x6f, 0x80, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, +0x03, 0x20, 0xb8, 0x71, 0x20, 0x1c, 0x20, 0x4a, 0x00, 0x21, 0x05, 0xf0, +0x07, 0xfc, 0xf0, 0x6f, 0x04, 0x23, 0x01, 0x68, 0x99, 0x43, 0x01, 0x60, +0x28, 0x68, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x05, 0x21, 0xb9, 0x71, 0x29, 0x68, 0x04, 0x23, 0x0a, 0x68, +0x9a, 0x43, 0x0a, 0x60, 0xc0, 0x6f, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, +0xff, 0xf7, 0x5a, 0xff, 0x08, 0x23, 0x18, 0x43, 0x00, 0xf0, 0x34, 0xf8, +0x20, 0x1c, 0x10, 0x4a, 0x00, 0x21, 0x05, 0xf0, 0xe5, 0xfb, 0xe5, 0xe7, +0xff, 0xf7, 0x4e, 0xff, 0x04, 0x23, 0x18, 0x43, 0x00, 0xf0, 0x28, 0xf8, +0xde, 0xe7, 0x00, 0x20, 0x29, 0x68, 0x60, 0x23, 0x0a, 0x68, 0x9a, 0x43, +0x0a, 0x60, 0xff, 0xf7, 0xe1, 0xfa, 0xd5, 0xe7, 0x06, 0x20, 0xb8, 0x71, +0xd2, 0xe7, 0x00, 0x00, 0x99, 0x7c, 0x21, 0x40, 0x68, 0x0e, 0x00, 0x80, +0x9c, 0x03, 0x00, 0x80, 0x30, 0x75, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, +0x00, 0xb5, 0x00, 0x20, 0x04, 0x49, 0xc0, 0x46, 0x88, 0x71, 0x04, 0x48, +0x01, 0x22, 0x00, 0x21, 0x05, 0xf0, 0xbc, 0xfb, 0x08, 0xbc, 0x18, 0x47, +0x98, 0x1c, 0x00, 0x80, 0x99, 0x7c, 0x21, 0x40, 0x90, 0xb5, 0x07, 0x1c, +0x31, 0x48, 0x00, 0x68, 0x79, 0x08, 0x03, 0xd3, 0x10, 0x23, 0x01, 0x1c, +0x99, 0x43, 0x01, 0xe0, 0x10, 0x21, 0x01, 0x43, 0x2d, 0x4c, 0xe2, 0x68, +0x01, 0x2a, 0x05, 0xd1, 0x22, 0x79, 0x00, 0x2a, 0x02, 0xd0, 0x01, 0x23, +0x9b, 0x02, 0x19, 0x43, 0x81, 0x42, 0x02, 0xd0, 0x01, 0x20, 0x00, 0x05, +0x01, 0x60, 0xe0, 0x68, 0x01, 0x28, 0x20, 0xd1, 0x1b, 0x23, 0xdb, 0x01, +0xe0, 0x18, 0x80, 0x8b, 0xf9, 0x08, 0x04, 0xd3, 0x01, 0x23, 0xdb, 0x02, +0x01, 0x1c, 0x99, 0x43, 0x01, 0xe0, 0x01, 0x21, 0xc9, 0x02, 0x81, 0x42, +0x02, 0xd0, 0x00, 0x20, 0x03, 0xf0, 0xca, 0xf9, 0x38, 0x09, 0x07, 0xd3, +0xe0, 0x6f, 0x80, 0x23, 0x01, 0x68, 0x99, 0x43, 0x01, 0x60, 0xe0, 0x18, +0x00, 0x68, 0x00, 0xe0, 0xe0, 0x6f, 0x80, 0x23, 0x01, 0x68, 0x19, 0x43, +0x01, 0x60, 0x15, 0x48, 0x01, 0x6a, 0x78, 0x09, 0x03, 0xd3, 0xff, 0x20, 0x01, 0x30, 0x08, 0x43, 0x03, 0xe0, 0xff, 0x23, 0x08, 0x1c, 0x01, 0x33, 0x98, 0x43, 0x80, 0x08, 0x80, 0x00, 0xba, 0x09, 0x92, 0x07, 0x92, 0x0f, -0x10, 0x43, 0x88, 0x42, 0x02, 0xd0, 0x0d, 0x49, 0xc0, 0x46, 0x08, 0x62, +0x10, 0x43, 0x88, 0x42, 0x02, 0xd0, 0x0c, 0x49, 0xc0, 0x46, 0x08, 0x62, 0xe1, 0x68, 0x01, 0x29, 0x08, 0xd1, 0x79, 0x0a, 0x06, 0xd3, 0xff, 0x23, -0x04, 0x33, 0x18, 0x40, 0x03, 0x28, 0x01, 0xd1, 0xff, 0xf7, 0x90, 0xff, +0x04, 0x33, 0x18, 0x40, 0x03, 0x28, 0x01, 0xd1, 0xff, 0xf7, 0x8e, 0xff, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, -0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, 0xc0, 0x00, 0x18, 0x40, -0xc0, 0x00, 0x18, 0x00, 0x80, 0xb5, 0xff, 0xf7, 0xc1, 0xfe, 0x80, 0x09, -0x12, 0xd2, 0x0b, 0x48, 0x41, 0x78, 0x00, 0x29, 0x0e, 0xd1, 0x01, 0x21, -0x41, 0x70, 0x00, 0x27, 0x08, 0x48, 0x06, 0xe0, 0x02, 0x20, 0x03, 0xf0, -0x03, 0xf8, 0x07, 0x20, 0x02, 0xf0, 0xd2, 0xff, 0x38, 0x1c, 0xff, 0xf7, -0x5b, 0xfa, 0xf5, 0xe7, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, -0x18, 0x1c, 0x00, 0x80, 0xf4, 0x01, 0xff, 0xff, 0x00, 0xb5, 0x84, 0xb0, -0x69, 0x46, 0xff, 0xf7, 0x69, 0xfc, 0xff, 0xf7, 0x9d, 0xfe, 0x01, 0xab, -0x58, 0x80, 0x08, 0x48, 0x00, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x07, 0x48, -0x00, 0x6a, 0xc0, 0x46, 0x03, 0x90, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, -0x99, 0xfb, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, -0x00, 0x00, 0x10, 0x40, 0xc0, 0x00, 0x18, 0x40, 0x80, 0xb5, 0x84, 0xb0, -0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, 0x49, 0xfc, 0xf8, 0x88, -0xff, 0xf7, 0x4a, 0xff, 0xff, 0xf7, 0x7a, 0xfe, 0x01, 0xab, 0x58, 0x80, -0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x7e, 0xfb, 0x01, 0x20, 0x04, 0xb0, -0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0xc6, 0xb0, 0xc7, 0x88, -0x69, 0x46, 0xff, 0xf7, 0x33, 0xfc, 0x01, 0x24, 0x63, 0x02, 0x9f, 0x42, -0x0a, 0xd3, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, -0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x68, 0x46, 0x00, 0x21, 0x16, 0xe0, -0x0e, 0x48, 0xff, 0xf7, 0x05, 0xfa, 0x05, 0x1c, 0x38, 0x1c, 0x04, 0xa9, -0x03, 0xf0, 0xa2, 0xfb, 0x0b, 0x49, 0x28, 0x1c, -0xff, 0xf7, 0xfd, 0xf9, 0x10, 0x20, 0x00, 0xab, 0x58, 0x70, 0x04, 0x98, -0xc0, 0x46, 0x02, 0x90, 0x05, 0x98, 0xc0, 0x46, 0x03, 0x90, 0x68, 0x46, -0x06, 0xa9, 0xff, 0xf7, 0x4b, 0xfb, 0x20, 0x1c, 0x46, 0xb0, 0xb0, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, +0x68, 0x0e, 0x00, 0x80, 0xc0, 0x00, 0x18, 0x40, 0xc0, 0x00, 0x18, 0x00, +0x80, 0xb5, 0xff, 0xf7, 0xb1, 0xfe, 0x80, 0x09, 0x1b, 0xd2, 0x0f, 0x48, +0xe3, 0x23, 0x1b, 0x01, 0xc1, 0x18, 0x4a, 0x79, 0x00, 0x2a, 0x14, 0xd1, +0x01, 0x22, 0x4a, 0x71, 0x00, 0x27, 0x80, 0x30, 0x00, 0x68, 0x60, 0x23, +0x01, 0x68, 0x99, 0x43, 0x01, 0x60, 0x08, 0x48, +0x06, 0xe0, 0x02, 0x20, 0x03, 0xf0, 0x7e, 0xfb, 0x07, 0x20, 0x03, 0xf0, +0x4d, 0xfb, 0x38, 0x1c, 0xff, 0xf7, 0x34, 0xfa, 0xf5, 0xe7, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0xf4, 0x01, 0xff, 0xff, +0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xff, 0xf7, 0x43, 0xfc, 0xff, 0xf7, +0x85, 0xfe, 0x01, 0xab, 0x58, 0x80, 0x08, 0x48, 0x00, 0x68, 0xc0, 0x46, +0x02, 0x90, 0x07, 0x48, 0x00, 0x6a, 0xc0, 0x46, 0x03, 0x90, 0x68, 0x46, +0x00, 0x21, 0xff, 0xf7, 0x73, 0xfb, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0xc0, 0x00, 0x18, 0x40, +0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, +0x23, 0xfc, 0xf8, 0x88, 0xff, 0xf7, 0x42, 0xff, 0xff, 0xf7, 0x62, 0xfe, +0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x58, 0xfb, +0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, +0xc6, 0xb0, 0xc7, 0x88, 0x69, 0x46, 0xff, 0xf7, 0x0d, 0xfc, 0x01, 0x24, +0x16, 0x4b, 0x9f, 0x42, 0x0a, 0xd9, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, +0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x68, 0x46, +0x00, 0x21, 0x17, 0xe0, 0x10, 0x48, 0xff, 0xf7, 0xdf, 0xf9, 0x05, 0x1c, +0x0f, 0x4a, 0x38, 0x1c, 0x04, 0xa9, 0xff, 0xf7, 0xdb, 0xf9, 0x0e, 0x49, +0x28, 0x1c, 0xff, 0xf7, 0xd6, 0xf9, 0x10, 0x20, 0x00, 0xab, 0x58, 0x70, +0x04, 0x98, 0xc0, 0x46, 0x02, 0x90, 0x05, 0x98, 0xc0, 0x46, 0x03, 0x90, +0x68, 0x46, 0x06, 0xa9, 0xff, 0xf7, 0x24, 0xfb, 0x20, 0x1c, 0x46, 0xb0, +0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, +0x24, 0x02, 0xff, 0xff, 0x29, 0xbf, 0x21, 0x40, 0x3c, 0x02, 0xff, 0xff, 0xf0, 0xb5, 0xc6, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, -0xfb, 0xfb, 0xfc, 0x88, 0x78, 0x78, 0x01, 0x25, 0x10, 0x28, 0x02, 0xd1, +0xcf, 0xfb, 0xfc, 0x88, 0x78, 0x78, 0x01, 0x25, 0x10, 0x28, 0x02, 0xd1, 0x43, 0x01, 0x9c, 0x42, 0x09, 0xd3, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x04, 0x33, -0x2c, 0xe0, 0xb8, 0x68, 0xc0, 0x46, 0x04, 0x90, 0xf8, 0x68, 0xc0, 0x46, +0x27, 0xe0, 0xb8, 0x68, 0xc0, 0x46, 0x04, 0x90, 0xf8, 0x68, 0xc0, 0x46, 0x05, 0x90, 0x06, 0xaa, 0xfb, 0x1d, 0x09, 0x33, 0x00, 0x21, 0x78, 0x78, 0x00, 0x28, 0x0d, 0xdd, 0x00, 0x20, 0x40, 0xcb, 0x40, 0xc2, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x04, 0x28, 0xf8, 0xdb, 0x48, 0x1c, 0x01, 0x04, -0x09, 0x0c, 0x78, 0x78, 0x88, 0x42, 0xf1, 0xdc, 0x0d, 0x48, 0xff, 0xf7, -0xaf, 0xf9, 0x06, 0x1c, 0x20, 0x1c, 0x04, 0xa9, 0x03, 0xf0, 0x76, 0xfb, -0x0a, 0x49, 0x30, 0x1c, 0xff, 0xf7, 0xa7, 0xf9, 0x38, 0x68, 0xc0, 0x46, -0x00, 0x90, 0x00, 0x20, 0x00, 0xab, 0x58, 0x70, 0x68, 0x46, 0x00, 0x21, -0xff, 0xf7, 0xf8, 0xfa, 0x28, 0x1c, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, -0xf0, 0xb5, 0x84, 0xb0, 0x04, 0x1c, 0x00, 0x27, 0xe6, 0x88, 0xa2, 0x68, -0x47, 0x49, 0x08, 0x79, 0x00, 0x28, 0x08, 0xd0, 0x00, 0x2e, 0x01, 0xd0, -0x01, 0x2e, 0x01, 0xd1, 0x01, 0x27, 0x01, 0xe0, 0x04, 0x2e, 0x00, 0xd1, -0x03, 0x26, 0x01, 0x25, 0x41, 0x48, 0x05, 0x2e, 0x66, 0xd2, 0x02, 0xa3, -0x9b, 0x5d, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, 0x03, 0x06, 0x08, 0x0c, -0x10, 0x00, 0x85, 0x83, 0x00, 0x23, 0x03, 0xe0, 0x85, 0x83, 0x05, 0xe0, -0x00, 0x23, 0x83, 0x83, 0xc3, 0x83, 0x06, 0xe0, 0x00, 0x23, 0x83, 0x83, -0xc5, 0x83, 0x02, 0xe0, 0xff, 0x23, 0x01, 0x33, 0x83, 0x83, 0xcb, 0x1d, -0x79, 0x33, 0x1e, 0x89, 0x01, 0x23, 0x5b, 0x02, 0x9e, 0x42, 0x02, 0xdb, -0xd2, 0x07, 0xd2, 0x0f, 0x00, 0xe0, 0x01, 0x22, 0x6d, 0x23, 0x5b, 0x01, -0xc9, 0x18, 0x09, 0x88, 0xff, 0x23, 0xe1, 0x33, 0x99, 0x43, 0x01, 0x23, -0x19, 0x43, 0x86, 0x8b, 0xff, 0x33, 0x9e, 0x42, 0x0d, 0xd1, 0xff, 0x20, -0xe1, 0x30, 0x08, 0x43, 0x00, 0x2a, 0x04, 0xd1, 0x01, 0x23, 0x9b, 0x02, -0x98, 0x43, 0x01, 0x1c, 0x20, 0xe0, 0x01, 0x21, 0x89, 0x02, 0x01, 0x43, -0x1c, 0xe0, 0x01, 0x2e, 0x0a, 0xd1, 0xc0, 0x8b, 0x01, 0x28, 0x04, 0xd1, -0x60, 0x23, 0x19, 0x43, 0x00, 0x2a, 0x13, 0xd0, 0x0c, 0xe0, 0x20, 0x23, -0x19, 0x43, 0x0f, 0xe0, 0x00, 0x2e, 0x0d, 0xd1, 0xc0, 0x8b, 0x01, 0x28, -0x08, 0xd1, 0xff, 0x23, 0x81, 0x33, 0x19, 0x43, 0x00, 0x2a, 0x05, 0xd0, -0x01, 0x23, 0x9b, 0x02, 0x19, 0x43, 0x01, 0xe0, 0x80, 0x23, 0x19, 0x43, -0x04, 0x20, 0x02, 0xf0, 0x8d, 0xfc, 0x09, 0x21, 0x49, 0x02, 0x00, 0x20, -0x02, 0xf0, 0x88, 0xfc, 0x00, 0x2f, 0x02, 0xd1, 0x00, 0x20, 0x12, 0xe0, -0xff, 0xe7, 0x69, 0x46, 0x20, 0x1c, 0xff, 0xf7, 0x2b, 0xfb, 0x00, 0xa8, -0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, -0xd8, 0x80, 0x68, 0x46, 0x00, 0x21, 0x04, 0x33, 0xff, 0xf7, 0x5e, 0xfa, -0x28, 0x1c, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0xe8, 0x1b, 0x00, 0x80, -0xc0, 0x88, 0x51, 0x21, 0x89, 0x03, 0x08, 0x62, 0x00, 0x20, 0x70, 0x47, -0x80, 0xb5, 0x16, 0x4f, 0xf8, 0x68, 0x01, 0x28, 0x07, 0xd1, 0x37, 0x23, -0x9b, 0x01, 0xf8, 0x18, 0xc0, 0x89, 0x80, 0x21, 0x01, 0x43, 0x1b, 0x20, -0x07, 0xe0, 0x6d, 0x23, 0x5b, 0x01, 0xf8, 0x18, 0x00, 0x8b, 0x01, 0x21, -0x49, 0x03, 0x01, 0x43, 0x10, 0x20, 0x02, 0xf0, 0x4b, 0xfc, 0x01, 0x20, -0x07, 0x23, 0x5b, 0x02, 0xf9, 0x18, 0x88, 0x83, 0xc8, 0x83, 0x1b, 0x23, -0xdb, 0x01, 0xf8, 0x18, 0x00, 0x8b, 0x01, 0x23, 0x1b, 0x03, 0x98, 0x43, -0x41, 0x21, 0x09, 0x02, 0x01, 0x43, 0x00, 0x20, 0x02, 0xf0, 0x38, 0xfc, -0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, -0x80, 0xb5, 0x17, 0x4f, 0xf8, 0x68, 0x01, 0x28, 0x08, 0xd1, 0x37, 0x23, -0x9b, 0x01, 0xf8, 0x18, 0xc0, 0x89, 0x80, 0x23, 0x98, 0x43, 0x01, 0x1c, -0x1b, 0x20, 0x08, 0xe0, 0x6d, 0x23, 0x5b, 0x01, 0xf8, 0x18, 0x00, 0x8b, -0x01, 0x23, 0x5b, 0x03, 0x98, 0x43, 0x01, 0x1c, 0x10, 0x20, 0x02, 0xf0, -0x19, 0xfc, 0xff, 0x20, 0x07, 0x23, 0x5b, 0x02, 0xf9, 0x18, 0x01, 0x30, -0x88, 0x83, 0x1b, 0x23, 0xdb, 0x01, 0xf8, 0x18, 0x00, 0x8b, 0x41, 0x23, -0x1b, 0x02, 0x98, 0x43, 0x09, 0x21, 0x49, 0x02, 0x01, 0x43, 0x00, 0x20, -0x02, 0xf0, 0x06, 0xfc, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0xe8, 0x0d, 0x00, 0x80, 0x80, 0xb5, 0x84, 0xb0, 0x08, 0x49, 0xcf, 0x6a, -0x69, 0x46, 0xff, 0xf7, 0xa5, 0xfa, 0xb8, 0x05, 0x80, 0x0d, 0x01, 0xab, -0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0xdd, 0xf9, 0x01, 0x20, -0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x40, 0x00, 0x14, 0x40, -0xc0, 0x88, 0x9f, 0x23, 0x18, 0x40, 0x05, 0x49, 0xc9, 0x6a, 0x1b, 0x23, -0x5b, 0x01, 0x19, 0x40, 0x08, 0x43, 0x03, 0x49, 0xc0, 0x46, 0xc8, 0x62, -0x00, 0x20, 0x70, 0x47, 0x40, 0x00, 0x14, 0x40, 0x40, 0x00, 0x14, 0x00, -0x80, 0xb5, 0x84, 0xb0, 0x0d, 0x49, 0x0f, 0x6a, 0x01, 0x2f, 0x01, 0xd1, -0xff, 0x03, 0x07, 0xe0, 0x02, 0x2f, 0x01, 0xd1, 0x3f, 0x03, 0x03, 0xe0, -0x00, 0x2f, 0x01, 0xd1, 0x01, 0x27, 0xff, 0x02, 0x69, 0x46, 0xff, 0xf7, -0x71, 0xfa, 0x01, 0xab, 0x5f, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, -0xab, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x00, 0x20, 0x14, 0x40, 0xc2, 0x88, 0xa1, 0x20, 0x40, 0x03, 0x00, 0x21, -0x01, 0x23, 0x5b, 0x03, 0x9a, 0x42, 0x01, 0xd1, 0x02, 0x22, 0x04, 0xe0, -0x01, 0x23, 0xdb, 0x03, 0x9a, 0x42, 0x02, 0xd1, 0x01, 0x22, 0x02, 0x62, -0x00, 0xe0, 0x01, 0x62, 0x08, 0x1c, 0x70, 0x47, 0x90, 0xb5, 0x84, 0xb0, -0x07, 0x1c, 0x02, 0xf0, 0xb7, 0xfb, 0x69, 0x46, 0x04, 0x1c, 0x38, 0x1c, -0xff, 0xf7, 0x46, 0xfa, 0x01, 0xab, 0x5c, 0x80, 0x09, 0x4f, 0xf8, 0x6d, -0xc0, 0x46, 0x02, 0x90, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x7c, 0xf9, -0xf8, 0x6d, 0xc0, 0x07, 0xc0, 0x0f, 0x05, 0x49, 0xc0, 0x46, 0x88, 0x62, +0x09, 0x0c, 0x78, 0x78, 0x88, 0x42, 0xf1, 0xdc, 0x0a, 0x48, 0xff, 0xf7, +0x83, 0xf9, 0x07, 0x1c, 0x09, 0x4a, 0x20, 0x1c, 0x04, 0xa9, 0xff, 0xf7, +0x7f, 0xf9, 0x08, 0x49, 0x38, 0x1c, 0xff, 0xf7, 0x7a, 0xf9, 0x68, 0x46, +0x00, 0x21, 0xff, 0xf7, 0xd1, 0xfa, 0x28, 0x1c, 0x46, 0xb0, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x24, 0x02, 0xff, 0xff, 0x51, 0xbf, 0x21, 0x40, +0x3c, 0x02, 0xff, 0xff, 0xf0, 0xb5, 0x84, 0xb0, 0x04, 0x1c, 0x00, 0x27, +0xe6, 0x88, 0xa2, 0x68, 0x47, 0x49, 0x08, 0x79, 0x00, 0x28, 0x08, 0xd0, +0x00, 0x2e, 0x01, 0xd0, 0x01, 0x2e, 0x01, 0xd1, 0x01, 0x27, 0x01, 0xe0, +0x04, 0x2e, 0x00, 0xd1, 0x03, 0x26, 0x01, 0x25, 0x41, 0x48, 0x05, 0x2e, +0x66, 0xd2, 0x02, 0xa3, 0x9b, 0x5d, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, +0x03, 0x06, 0x08, 0x0c, 0x10, 0x00, 0x05, 0x80, 0x00, 0x23, 0x03, 0xe0, +0x05, 0x80, 0x05, 0xe0, 0x00, 0x23, 0x03, 0x80, 0x43, 0x80, 0x06, 0xe0, +0x00, 0x23, 0x03, 0x80, 0x45, 0x80, 0x02, 0xe0, +0xff, 0x23, 0x01, 0x33, 0x03, 0x80, 0xcb, 0x1d, 0x79, 0x33, 0x9e, 0x89, +0x01, 0x23, 0x5b, 0x02, 0x9e, 0x42, 0x02, 0xdb, 0xd2, 0x07, 0xd2, 0x0f, +0x00, 0xe0, 0x01, 0x22, 0x6d, 0x23, 0x5b, 0x01, 0xc9, 0x18, 0x89, 0x88, +0xff, 0x23, 0xe1, 0x33, 0x99, 0x43, 0x01, 0x23, 0x19, 0x43, 0x06, 0x88, +0xff, 0x33, 0x9e, 0x42, 0x0d, 0xd1, 0xff, 0x20, 0xe1, 0x30, 0x08, 0x43, +0x00, 0x2a, 0x04, 0xd1, 0x01, 0x23, 0x9b, 0x02, 0x98, 0x43, 0x01, 0x1c, +0x20, 0xe0, 0x01, 0x21, 0x89, 0x02, 0x01, 0x43, 0x1c, 0xe0, 0x01, 0x2e, +0x0a, 0xd1, 0x40, 0x88, 0x01, 0x28, 0x04, 0xd1, 0x60, 0x23, 0x19, 0x43, +0x00, 0x2a, 0x13, 0xd0, 0x0c, 0xe0, 0x20, 0x23, 0x19, 0x43, 0x0f, 0xe0, +0x00, 0x2e, 0x0d, 0xd1, 0x40, 0x88, 0x01, 0x28, 0x08, 0xd1, 0xff, 0x23, +0x81, 0x33, 0x19, 0x43, 0x00, 0x2a, 0x05, 0xd0, 0x01, 0x23, 0x9b, 0x02, +0x19, 0x43, 0x01, 0xe0, 0x80, 0x23, 0x19, 0x43, 0x04, 0x20, 0x03, 0xf0, +0x2d, 0xf8, 0x09, 0x21, 0x49, 0x02, 0x00, 0x20, 0x03, 0xf0, 0x28, 0xf8, +0x00, 0x2f, 0x02, 0xd1, 0x00, 0x20, 0x12, 0xe0, 0xff, 0xe7, 0x69, 0x46, +0x20, 0x1c, 0xff, 0xf7, 0x03, 0xfb, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, +0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x68, 0x46, +0x00, 0x21, 0x04, 0x33, 0xff, 0xf7, 0x36, 0xfa, 0x28, 0x1c, 0x04, 0xb0, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, +0x88, 0x1c, 0x00, 0x80, 0xc0, 0x88, 0x51, 0x21, 0x89, 0x03, 0x08, 0x62, +0x00, 0x20, 0x70, 0x47, 0x80, 0xb5, 0x16, 0x4f, 0xf8, 0x68, 0x01, 0x28, +0x07, 0xd1, 0x37, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x40, 0x8a, 0x80, 0x21, +0x01, 0x43, 0x1b, 0x20, 0x07, 0xe0, 0x6d, 0x23, 0x5b, 0x01, 0xf8, 0x18, +0x80, 0x8b, 0x01, 0x21, 0x49, 0x03, 0x01, 0x43, 0x10, 0x20, 0x02, 0xf0, +0xeb, 0xff, 0x01, 0x20, 0x71, 0x23, 0x5b, 0x01, 0xf9, 0x18, 0x08, 0x80, +0x48, 0x80, 0x1b, 0x23, 0xdb, 0x01, 0xf8, 0x18, 0x80, 0x8b, 0x01, 0x23, +0x1b, 0x03, 0x98, 0x43, 0x41, 0x21, 0x09, 0x02, 0x01, 0x43, 0x00, 0x20, +0x02, 0xf0, 0xd8, 0xff, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x17, 0x4f, 0xf8, 0x68, 0x01, 0x28, +0x08, 0xd1, 0x37, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x40, 0x8a, 0x80, 0x23, +0x98, 0x43, 0x01, 0x1c, 0x1b, 0x20, 0x08, 0xe0, 0x6d, 0x23, 0x5b, 0x01, +0xf8, 0x18, 0x80, 0x8b, 0x01, 0x23, 0x5b, 0x03, 0x98, 0x43, 0x01, 0x1c, +0x10, 0x20, 0x02, 0xf0, 0xb9, 0xff, 0xff, 0x20, 0x71, 0x23, 0x5b, 0x01, +0xf9, 0x18, 0x01, 0x30, 0x08, 0x80, 0x1b, 0x23, 0xdb, 0x01, 0xf8, 0x18, +0x80, 0x8b, 0x41, 0x23, 0x1b, 0x02, 0x98, 0x43, 0x09, 0x21, 0x49, 0x02, +0x01, 0x43, 0x00, 0x20, 0x02, 0xf0, 0xa6, 0xff, 0x00, 0x20, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x84, 0xb0, +0x08, 0x49, 0xcf, 0x6a, 0x69, 0x46, 0xff, 0xf7, 0x7d, 0xfa, 0xb8, 0x05, +0x80, 0x0d, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, +0xb5, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x40, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x9f, 0x23, 0x18, 0x40, 0x05, 0x49, +0xc9, 0x6a, 0x1b, 0x23, 0x5b, 0x01, 0x19, 0x40, 0x08, 0x43, 0x03, 0x49, +0xc0, 0x46, 0xc8, 0x62, 0x00, 0x20, 0x70, 0x47, 0x40, 0x00, 0x14, 0x40, +0x40, 0x00, 0x14, 0x00, 0x80, 0xb5, 0x84, 0xb0, +0x0d, 0x49, 0x0f, 0x6a, 0x01, 0x2f, 0x01, 0xd1, 0xff, 0x03, 0x07, 0xe0, +0x02, 0x2f, 0x01, 0xd1, 0x3f, 0x03, 0x03, 0xe0, 0x00, 0x2f, 0x01, 0xd1, +0x01, 0x27, 0xff, 0x02, 0x69, 0x46, 0xff, 0xf7, 0x49, 0xfa, 0x01, 0xab, +0x5f, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x83, 0xf9, 0x01, 0x20, +0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0x14, 0x40, +0xc2, 0x88, 0xa1, 0x20, 0x40, 0x03, 0x00, 0x21, 0x01, 0x23, 0x5b, 0x03, +0x9a, 0x42, 0x01, 0xd1, 0x02, 0x22, 0x04, 0xe0, 0x01, 0x23, 0xdb, 0x03, +0x9a, 0x42, 0x02, 0xd1, 0x01, 0x22, 0x02, 0x62, 0x00, 0xe0, 0x01, 0x62, +0x08, 0x1c, 0x70, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x02, 0xf0, +0x57, 0xff, 0x69, 0x46, 0x04, 0x1c, 0x38, 0x1c, 0xff, 0xf7, 0x1e, 0xfa, +0x01, 0xab, 0x5c, 0x80, 0x09, 0x4f, 0xf8, 0x6d, 0xc0, 0x46, 0x02, 0x90, +0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x54, 0xf9, 0xf8, 0x6d, 0xc0, 0x07, +0xc0, 0x0f, 0x05, 0x49, 0xc0, 0x46, 0xc8, 0x62, 0x01, 0x20, 0x04, 0xb0, +0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xa4, 0x2a, 0x00, 0x80, +0x68, 0x1c, 0x00, 0x80, 0xc0, 0x88, 0x02, 0x49, 0xc0, 0x46, 0x48, 0x61, +0x00, 0x20, 0x70, 0x47, 0x80, 0x00, 0x14, 0x00, 0x00, 0xb5, 0x84, 0xb0, +0x69, 0x46, 0xff, 0xf7, 0xf7, 0xf9, 0x06, 0x48, 0xc0, 0x68, 0x01, 0xab, +0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x2f, 0xf9, 0x01, 0x20, +0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x40, +0xc0, 0x88, 0x02, 0x49, 0xc0, 0x46, 0xc8, 0x60, 0x00, 0x20, 0x70, 0x47, +0x80, 0x00, 0x14, 0x00, 0x80, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0x87, 0x68, +0xff, 0xf7, 0xda, 0xf9, 0x20, 0x2f, 0x07, 0xd2, 0x78, 0x00, 0x0c, 0x49, +0x40, 0x18, 0x1b, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x80, 0x8b, 0x06, 0xe0, +0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, +0x02, 0x20, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, +0x03, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x68, 0x0e, 0x00, 0x80, 0x00, 0xb5, 0x84, 0xb0, 0xc1, 0x88, 0x82, 0x68, +0x20, 0x2a, 0x04, 0xd2, 0x10, 0x1c, 0x02, 0xf0, 0xcf, 0xfe, 0x00, 0x20, +0x10, 0xe0, 0x69, 0x46, 0xff, 0xf7, 0xae, 0xf9, 0x00, 0xa8, 0x00, 0x78, +0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, +0x68, 0x46, 0x00, 0x21, 0x04, 0x33, 0xff, 0xf7, 0xe1, 0xf8, 0x01, 0x20, +0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0xc7, 0x88, +0x69, 0x46, 0xff, 0xf7, 0x97, 0xf9, 0x10, 0x48, 0xfe, 0xf7, 0x78, 0xff, +0x02, 0x20, 0x39, 0x1c, 0x03, 0xf0, 0x3c, 0xfe, 0x00, 0x28, 0x06, 0xd0, +0x02, 0x20, 0x39, 0x1c, 0x03, 0xf0, 0x8c, 0xfd, 0x01, 0xab, 0x58, 0x80, +0x02, 0xe0, 0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x07, 0x49, 0x20, 0x1c, +0xfe, 0xf7, 0x65, 0xff, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0xbc, 0xf8, 0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, -0x10, 0x2a, 0x00, 0x80, 0xe8, 0x1b, 0x00, 0x80, 0xc0, 0x88, 0x02, 0x49, -0xc0, 0x46, 0x48, 0x61, 0x00, 0x20, 0x70, 0x47, 0x80, 0x00, 0x14, 0x00, -0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xff, 0xf7, 0x1f, 0xfa, 0x06, 0x48, -0xc0, 0x68, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, -0x00, 0x21, 0xff, 0xf7, 0x57, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x02, 0x49, -0xc0, 0x46, 0xc8, 0x60, 0x00, 0x20, 0x70, 0x47, 0x80, 0x00, 0x14, 0x00, -0x80, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0x87, 0x68, 0xff, 0xf7, 0x02, 0xfa, -0x20, 0x2f, 0x07, 0xd2, 0x78, 0x00, 0x0c, 0x49, 0x40, 0x18, 0x1b, 0x23, -0xdb, 0x01, 0xc0, 0x18, 0x00, 0x8b, 0x06, 0xe0, 0x00, 0xa8, 0x00, 0x78, -0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0x01, 0xab, -0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x2b, 0xf9, 0x01, 0x20, -0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, -0x00, 0xb5, 0x84, 0xb0, 0xc1, 0x88, 0x82, 0x68, 0x20, 0x2a, 0x04, 0xd2, -0x10, 0x1c, 0x02, 0xf0, 0x2f, 0xfb, 0x00, 0x20, 0x10, 0xe0, 0x69, 0x46, -0xff, 0xf7, 0xd6, 0xf9, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, -0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x68, 0x46, 0x00, 0x21, -0x04, 0x33, 0xff, 0xf7, 0x09, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, -0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0xc7, 0x88, 0x69, 0x46, 0xff, 0xf7, -0xbf, 0xf9, 0x10, 0x48, 0xfe, 0xf7, 0xa0, 0xff, 0x02, 0x20, 0x39, 0x1c, -0x03, 0xf0, 0x5a, 0xfa, 0x00, 0x28, 0x06, 0xd0, 0x02, 0x20, 0x39, 0x1c, -0x03, 0xf0, 0x94, 0xf9, 0x01, 0xab, 0x58, 0x80, 0x02, 0xe0, 0x45, 0x20, -0x00, 0xab, 0x18, 0x70, 0x07, 0x49, 0x20, 0x1c, 0xfe, 0xf7, 0x8d, 0xff, -0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0xe4, 0xf8, 0x01, 0x20, 0x04, 0xb0, -0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x24, 0x02, 0xff, 0xff, -0x3c, 0x02, 0xff, 0xff, 0xb0, 0xb5, 0x84, 0xb0, 0xc7, 0x88, 0x69, 0x46, -0x84, 0x68, 0xff, 0xf7, 0x93, 0xf9, 0x10, 0x48, 0xfe, 0xf7, 0x74, 0xff, -0x0f, 0x4a, 0x02, 0x20, 0x39, 0x1c, 0xfe, 0xf7, 0x71, 0xff, 0x00, 0x28, -0x06, 0xd0, 0x0d, 0x4b, 0x02, 0x20, 0x39, 0x1c, 0x22, 0x1c, 0xfe, 0xf7, -0x6a, 0xff, 0x02, 0xe0, 0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x09, 0x49, -0x28, 0x1c, 0xfe, 0xf7, 0x60, 0xff, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, -0xb7, 0xf8, 0x01, 0x20, 0x04, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x24, 0x02, 0xff, 0xff, 0xb9, 0xb8, 0x21, 0x40, 0x7b, 0xb7, 0x21, 0x40, -0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0xff, 0xf7, 0x7f, 0xf9, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x20, 0x70, 0x47, 0x80, 0xb4, 0xc2, 0x88, 0x19, 0x4b, -0xa1, 0x21, 0x49, 0x03, 0x00, 0x2a, 0x03, 0xd1, 0x18, 0x6b, 0x10, 0x23, -0x98, 0x43, 0x04, 0xe0, 0x01, 0x2a, 0x04, 0xd1, 0x18, 0x6b, 0x10, 0x23, -0x18, 0x43, 0x48, 0x61, 0x1f, 0xe0, 0x02, 0x2a, 0x1d, 0xd1, 0xc2, 0x68, -0x87, 0x68, 0x00, 0x20, 0x3b, 0x1c, 0xc3, 0x40, 0xdb, 0x07, 0xdb, 0x0f, -0x9b, 0x02, 0x03, 0x43, 0x0b, 0x61, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, -0x20, 0x28, 0xf3, 0xdb, 0x00, 0x20, 0x13, 0x1c, 0xc3, 0x40, 0xdb, 0x07, -0xdb, 0x0f, 0x9b, 0x02, 0xc7, 0x1d, 0x19, 0x37, 0x3b, 0x43, 0x0b, 0x61, -0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x20, 0x28, 0xf1, 0xdb, 0x00, 0x20, -0x80, 0xbc, 0x70, 0x47, 0x80, 0x00, 0x14, 0x40, 0x90, 0xb4, 0xc2, 0x88, -0x81, 0x68, 0x10, 0x02, 0x12, 0x0a, 0x10, 0x43, 0x02, 0x04, 0x12, 0x0c, -0x0f, 0x48, 0xc0, 0x46, 0x02, 0x60, 0x0f, 0x4f, 0x65, 0x23, 0x5b, 0x01, -0xfb, 0x18, 0x9a, 0x83, 0x0a, 0x0c, 0x14, 0x02, -0x12, 0x12, 0x22, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x42, 0x60, 0xda, 0x83, +0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, 0xb0, 0xb5, 0x84, 0xb0, +0xc7, 0x88, 0x69, 0x46, 0x84, 0x68, 0xff, 0xf7, 0x6b, 0xf9, 0x10, 0x48, +0xfe, 0xf7, 0x4c, 0xff, 0x0f, 0x4a, 0x02, 0x20, 0x39, 0x1c, 0xfe, 0xf7, +0x49, 0xff, 0x00, 0x28, 0x06, 0xd0, 0x0d, 0x4b, 0x02, 0x20, 0x39, 0x1c, +0x22, 0x1c, 0xfe, 0xf7, 0x42, 0xff, 0x02, 0xe0, +0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x09, 0x49, 0x28, 0x1c, 0xfe, 0xf7, +0x38, 0xff, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x8f, 0xf8, 0x01, 0x20, +0x04, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x24, 0x02, 0xff, 0xff, +0xcd, 0xc0, 0x21, 0x40, 0xd9, 0xbf, 0x21, 0x40, 0x3c, 0x02, 0xff, 0xff, +0x00, 0xb5, 0xff, 0xf7, 0x57, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, +0x70, 0x47, 0x80, 0xb4, 0xc2, 0x88, 0x19, 0x4b, 0xa1, 0x21, 0x49, 0x03, +0x00, 0x2a, 0x03, 0xd1, 0x18, 0x6b, 0x10, 0x23, 0x98, 0x43, 0x04, 0xe0, +0x01, 0x2a, 0x04, 0xd1, 0x18, 0x6b, 0x10, 0x23, 0x18, 0x43, 0x48, 0x61, +0x1f, 0xe0, 0x02, 0x2a, 0x1d, 0xd1, 0xc2, 0x68, 0x87, 0x68, 0x00, 0x20, +0x3b, 0x1c, 0xc3, 0x40, 0xdb, 0x07, 0xdb, 0x0f, 0x9b, 0x02, 0x03, 0x43, +0x0b, 0x61, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x20, 0x28, 0xf3, 0xdb, +0x00, 0x20, 0x13, 0x1c, 0xc3, 0x40, 0xdb, 0x07, 0xdb, 0x0f, 0x9b, 0x02, +0xc7, 0x1d, 0x19, 0x37, 0x3b, 0x43, 0x0b, 0x61, 0x01, 0x30, 0x00, 0x04, +0x00, 0x0c, 0x20, 0x28, 0xf1, 0xdb, 0x00, 0x20, 0x80, 0xbc, 0x70, 0x47, +0x80, 0x00, 0x14, 0x40, 0x80, 0xb4, 0xc2, 0x88, 0x81, 0x68, 0x10, 0x02, +0x12, 0x0a, 0x10, 0x43, 0x02, 0x04, 0x12, 0x0c, 0x0c, 0x48, 0xc0, 0x46, +0x02, 0x60, 0x0c, 0x4b, 0xc0, 0x46, 0x1a, 0x80, 0x0a, 0x0c, 0x17, 0x02, +0x12, 0x12, 0x3a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x42, 0x60, 0x5a, 0x80, 0x09, 0x04, 0x09, 0x0c, 0x0a, 0x02, 0x09, 0x0a, 0x11, 0x43, 0x09, 0x04, -0x09, 0x0c, 0x81, 0x60, 0x33, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x01, 0x80, -0x00, 0x20, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x40, 0x00, 0x14, 0x00, -0xe8, 0x0d, 0x00, 0x80, 0xb0, 0xb5, 0x84, 0xb0, 0x13, 0x49, 0x0a, 0x68, -0x12, 0x04, 0x12, 0x0c, 0x13, 0x02, 0x12, 0x12, 0x13, 0x43, 0x4a, 0x68, -0x12, 0x04, 0x12, 0x0c, 0x1f, 0x1c, 0x13, 0x02, 0x12, 0x12, 0x13, 0x43, -0x89, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x0a, 0x02, 0x09, 0x12, 0x11, 0x43, -0x0c, 0x04, 0x24, 0x0c, 0x69, 0x46, 0x1d, 0x1c, 0xff, 0xf7, 0xe4, 0xf8, -0x01, 0xab, 0x5f, 0x80, 0x28, 0x04, 0x20, 0x43, 0x02, 0x90, 0x68, 0x46, -0x00, 0x21, 0xff, 0xf7, 0x1b, 0xf8, 0x01, 0x20, 0x04, 0xb0, 0xb0, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x40, 0x00, 0x14, 0x40, 0xc1, 0x88, 0x82, 0x68, -0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x0a, 0x49, -0xc0, 0x46, 0xc8, 0x60, 0x10, 0x0c, 0x03, 0x02, 0x00, 0x12, 0x18, 0x43, -0x00, 0x04, 0x00, 0x0c, 0x08, 0x61, 0x10, 0x04, 0x00, 0x0c, 0x02, 0x02, -0x00, 0x0a, 0x10, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x48, 0x61, 0x00, 0x20, -0x70, 0x47, 0x00, 0x00, 0x40, 0x00, 0x14, 0x00, 0x90, 0xb5, 0x84, 0xb0, -0x16, 0x4b, 0xd9, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x0a, 0x02, 0x09, 0x12, -0x11, 0x43, 0x1a, 0x69, 0x12, 0x04, 0x12, 0x0c, 0x17, 0x02, 0x12, 0x12, -0x3a, 0x43, 0x5b, 0x69, 0x1b, 0x04, 0x1b, 0x0c, 0x1f, 0x02, 0x1b, 0x12, -0x3b, 0x43, 0x1f, 0x04, 0x3f, 0x0c, 0x05, 0x23, 0x00, 0x93, 0x84, 0x88, -0x01, 0xab, 0x1c, 0x80, 0x00, 0x24, 0x04, 0x3b, 0x5c, 0x70, 0x40, 0x88, -0x00, 0xab, 0x58, 0x80, 0xd9, 0x80, 0x10, 0x04, 0x38, 0x43, 0x02, 0x90, -0x03, 0x94, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xcb, 0xff, 0x01, 0x20, -0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x40, 0x00, 0x14, 0x40, -0x00, 0xb5, 0x84, 0xb0, 0x0b, 0x49, 0x8a, 0x6a, 0x05, 0x21, 0x00, 0x91, -0x81, 0x88, 0x01, 0xab, 0x19, 0x80, 0x00, 0x21, 0x04, 0x3b, 0x59, 0x70, -0x40, 0x88, 0x00, 0xab, 0x58, 0x80, 0xda, 0x80, 0x02, 0x91, 0x03, 0x91, -0x68, 0x46, 0xfe, 0xf7, 0xaf, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0xc0, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x02, 0x49, -0xc0, 0x46, 0x88, 0x62, 0x00, 0x20, 0x70, 0x47, 0xc0, 0x00, 0x14, 0x00, -0x00, 0xb5, 0x84, 0xb0, 0x0b, 0x49, 0x0a, 0x6a, 0x05, 0x21, 0x00, 0x91, -0x81, 0x88, 0x01, 0xab, 0x19, 0x80, 0x00, 0x21, 0x04, 0x3b, 0x59, 0x70, -0x40, 0x88, 0x00, 0xab, 0x58, 0x80, 0xda, 0x80, 0x02, 0x91, 0x03, 0x91, -0x68, 0x46, 0xfe, 0xf7, 0x8b, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0xc0, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x02, 0x49, -0xc0, 0x46, 0x08, 0x62, 0x00, 0x20, 0x70, 0x47, 0xc0, 0x00, 0x14, 0x00, -0x00, 0xb5, 0xc0, 0x88, 0x02, 0x49, 0xfe, 0xf7, 0x1c, 0xfe, 0x00, 0x20, -0x08, 0xbc, 0x18, 0x47, 0x75, 0x02, 0xff, 0xff, 0x00, 0xb5, 0x84, 0xb0, -0x69, 0x46, 0xff, 0xf7, 0x2d, 0xf8, 0x06, 0x48, 0x00, 0x6b, 0x01, 0xab, -0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x65, 0xff, 0x01, 0x20, -0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, -0x00, 0xb5, 0xff, 0xf7, 0x33, 0xf8, 0x08, 0xbc, -0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, 0x2e, 0xf8, 0x08, 0xbc, 0x18, 0x47, -0x00, 0xb5, 0xff, 0xf7, 0x29, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, -0x01, 0x20, 0x14, 0x4f, 0x71, 0x23, 0x5b, 0x01, 0xf9, 0x18, 0x08, 0x71, -0x12, 0x48, 0xfe, 0xf7, 0xe9, 0xfd, 0x01, 0x20, 0x40, 0x02, 0xa1, 0x21, -0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0xf9, 0x1d, 0xb9, 0x31, 0x08, 0x70, -0x0d, 0x4a, 0x01, 0x23, 0x1b, 0x04, 0x11, 0x68, 0x0b, 0x40, 0x12, 0x21, -0x00, 0x2b, 0x05, 0xd1, 0x13, 0x68, 0x1b, 0x0c, 0x08, 0xd1, 0x12, 0x68, -0x92, 0x0a, 0x05, 0xd3, 0x07, 0x4a, 0xc0, 0x46, 0xd1, 0x60, 0x80, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x05, 0x4a, 0xc0, 0x46, 0x11, 0x64, 0xf8, 0xe7, -0xe8, 0x0d, 0x00, 0x80, 0xa9, 0x9d, 0x21, 0x40, 0x00, 0x00, 0x10, 0x40, -0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xb5, 0x02, 0xf0, -0x83, 0xfb, 0x01, 0x20, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x84, 0xb0, -0x07, 0x1c, 0xf8, 0x88, 0x02, 0xf0, 0x88, 0xfc, 0x00, 0x28, 0x0c, 0xd1, -0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0xc8, 0xff, 0x06, 0x48, 0x01, 0xab, -0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x01, 0xff, 0x01, 0x20, +0x09, 0x0c, 0x81, 0x60, 0x99, 0x80, 0x00, 0x20, 0x80, 0xbc, 0x70, 0x47, +0x40, 0x00, 0x14, 0x00, 0x28, 0x1b, 0x00, 0x80, 0xb0, 0xb5, 0x84, 0xb0, +0x13, 0x49, 0x0a, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x13, 0x02, 0x12, 0x12, +0x13, 0x43, 0x4a, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x1f, 0x1c, 0x13, 0x02, +0x12, 0x12, 0x13, 0x43, 0x89, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x0a, 0x02, +0x09, 0x12, 0x11, 0x43, 0x0c, 0x04, 0x24, 0x0c, 0x69, 0x46, 0x1d, 0x1c, +0xff, 0xf7, 0xc2, 0xf8, 0x01, 0xab, 0x5f, 0x80, 0x28, 0x04, 0x20, 0x43, +0x02, 0x90, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xf9, 0xff, 0x01, 0x20, +0x04, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x40, 0x00, 0x14, 0x40, +0xc1, 0x88, 0x82, 0x68, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x00, 0x04, +0x00, 0x0c, 0x0a, 0x49, 0xc0, 0x46, 0xc8, 0x60, 0x10, 0x0c, 0x03, 0x02, +0x00, 0x12, 0x18, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x08, 0x61, 0x10, 0x04, +0x00, 0x0c, 0x02, 0x02, 0x00, 0x0a, 0x10, 0x43, 0x00, 0x04, 0x00, 0x0c, +0x48, 0x61, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, 0x40, 0x00, 0x14, 0x00, +0x90, 0xb5, 0x84, 0xb0, 0x16, 0x4b, 0xd9, 0x68, 0x09, 0x04, 0x09, 0x0c, +0x0a, 0x02, 0x09, 0x12, 0x11, 0x43, 0x1a, 0x69, 0x12, 0x04, 0x12, 0x0c, +0x17, 0x02, 0x12, 0x12, 0x3a, 0x43, 0x5b, 0x69, 0x1b, 0x04, 0x1b, 0x0c, +0x1f, 0x02, 0x1b, 0x12, 0x3b, 0x43, 0x1f, 0x04, 0x3f, 0x0c, 0x05, 0x23, +0x00, 0x93, 0x84, 0x88, 0x01, 0xab, 0x1c, 0x80, 0x00, 0x24, 0x04, 0x3b, +0x5c, 0x70, 0x40, 0x88, 0x00, 0xab, 0x58, 0x80, 0xd9, 0x80, 0x10, 0x04, +0x38, 0x43, 0x02, 0x90, 0x03, 0x94, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, +0xa9, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x40, 0x00, 0x14, 0x40, 0x00, 0xb5, 0x84, 0xb0, 0x0b, 0x49, 0x8a, 0x6a, +0x05, 0x21, 0x00, 0x91, 0x81, 0x88, 0x01, 0xab, +0x19, 0x80, 0x00, 0x21, 0x04, 0x3b, 0x59, 0x70, 0x40, 0x88, 0x00, 0xab, +0x58, 0x80, 0xda, 0x80, 0x02, 0x91, 0x03, 0x91, 0x68, 0x46, 0xfe, 0xf7, +0x8d, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0xc0, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x02, 0x49, 0xc0, 0x46, 0x88, 0x62, +0x00, 0x20, 0x70, 0x47, 0xc0, 0x00, 0x14, 0x00, 0x00, 0xb5, 0x84, 0xb0, +0x0b, 0x49, 0x0a, 0x6a, 0x05, 0x21, 0x00, 0x91, 0x81, 0x88, 0x01, 0xab, +0x19, 0x80, 0x00, 0x21, 0x04, 0x3b, 0x59, 0x70, 0x40, 0x88, 0x00, 0xab, +0x58, 0x80, 0xda, 0x80, 0x02, 0x91, 0x03, 0x91, 0x68, 0x46, 0xfe, 0xf7, +0x69, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0xc0, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x02, 0x49, 0xc0, 0x46, 0x08, 0x62, +0x00, 0x20, 0x70, 0x47, 0xc0, 0x00, 0x14, 0x00, 0x00, 0xb5, 0xc0, 0x88, +0x02, 0x49, 0xfe, 0xf7, 0xfa, 0xfd, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, +0x75, 0x02, 0xff, 0xff, 0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xff, 0xf7, +0x0b, 0xf8, 0x06, 0x48, 0x00, 0x6b, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, +0x00, 0x21, 0xfe, 0xf7, 0x43, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0x00, 0xb5, 0xff, 0xf7, +0x11, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, 0x0c, 0xf8, +0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, 0x07, 0xf8, 0x08, 0xbc, +0x18, 0x47, 0x80, 0xb5, 0x07, 0x1c, 0x10, 0x48, 0xfe, 0xf7, 0xcc, 0xfd, +0x01, 0x20, 0x40, 0x02, 0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 0x00, 0x21, +0x0c, 0x48, 0xc0, 0x46, 0x01, 0x71, 0x0c, 0x48, 0x02, 0x68, 0x52, 0x0c, +0x05, 0xd2, 0x02, 0x68, 0x12, 0x0c, 0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a, +0x03, 0xd3, 0x08, 0x48, 0xc0, 0x46, 0xc7, 0x60, 0x02, 0xe0, 0x07, 0x48, +0xc0, 0x46, 0x07, 0x64, 0x08, 0x1c, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x21, 0xa5, 0x21, 0x40, 0x28, 0x0f, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, +0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xb5, 0x01, 0x20, +0x03, 0x49, 0xc0, 0x46, 0x08, 0x72, 0x12, 0x20, 0xff, 0xf7, 0xcb, 0xff, +0x08, 0xbc, 0x18, 0x47, 0x88, 0x1c, 0x00, 0x80, 0x00, 0xb5, 0x01, 0x20, +0x03, 0x49, 0xc0, 0x46, 0x48, 0x72, 0x15, 0x20, 0xff, 0xf7, 0xbf, 0xff, +0x08, 0xbc, 0x18, 0x47, 0x88, 0x1c, 0x00, 0x80, 0x00, 0xb5, 0x02, 0xf0, +0xf3, 0xfe, 0x01, 0x20, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x84, 0xb0, +0x07, 0x1c, 0xf8, 0x88, 0x02, 0xf0, 0xf8, 0xff, 0x00, 0x28, 0x0c, 0xd1, +0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0x96, 0xff, 0x06, 0x48, 0x01, 0xab, +0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xcf, 0xfe, 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0xff, 0x00, 0x00, 0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xfe, 0xf7, -0xb3, 0xff, 0x03, 0xf0, 0x71, 0xfe, 0x01, 0xab, 0x58, 0x80, 0x09, 0x48, +0x81, 0xff, 0x04, 0xf0, 0x47, 0xfa, 0x01, 0xab, 0x58, 0x80, 0x09, 0x48, 0x81, 0x89, 0x09, 0x04, 0xc2, 0x89, 0x11, 0x43, 0x02, 0x91, 0x81, 0x88, 0x09, 0x04, 0xc0, 0x88, 0x08, 0x43, 0x03, 0x90, 0x68, 0x46, 0x00, 0x21, -0xfe, 0xf7, 0xe0, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, -0xc8, 0x29, 0x00, 0x80, 0x00, 0xb5, 0xfe, 0xf7, 0xaf, 0xff, 0x08, 0xbc, -0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0xaa, 0xff, 0x08, 0xbc, 0x18, 0x47, -0x00, 0xb5, 0xfe, 0xf7, 0xa5, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, -0xfe, 0xf7, 0xa0, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, -0x9b, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x96, 0xff, -0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x91, 0xff, 0x08, 0xbc, -0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x8c, 0xff, 0x08, 0xbc, 0x18, 0x47, -0x00, 0xb5, 0xfe, 0xf7, 0x87, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, -0xfe, 0xf7, 0x82, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, -0x7d, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x78, 0xff, -0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x73, 0xff, 0x08, 0xbc, -0x18, 0x47, 0x00, 0xb5, 0x8c, 0xb0, 0x08, 0xa9, 0xfe, 0xf7, 0x54, 0xff, -0x69, 0x46, 0x08, 0xa8, 0x03, 0xf0, 0xba, 0xfe, 0x02, 0x20, 0x08, 0xab, -0x58, 0x70, 0x69, 0x46, 0x08, 0xa8, 0xfe, 0xf7, 0x89, 0xfe, 0x01, 0x20, -0x0c, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x5a, 0xff, -0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, -0x38, 0x1c, 0xfe, 0xf7, 0x39, 0xff, 0xf9, 0x88, 0x10, 0x48, 0x01, 0x24, -0x00, 0x29, 0x0e, 0xd0, 0x04, 0x73, 0x44, 0x73, 0xb9, 0x68, 0x09, 0x0c, -0x41, 0x82, 0xb9, 0x68, 0xc0, 0x46, 0x81, 0x82, 0xf9, 0x68, 0x09, 0x0c, -0xc1, 0x82, 0xf9, 0x68, 0xc0, 0x46, 0x01, 0x83, 0x02, 0xe0, 0x00, 0x21, -0x01, 0x73, 0x41, 0x73, 0x06, 0x48, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, -0x00, 0x21, 0xfe, 0xf7, 0x5b, 0xfe, 0x20, 0x1c, -0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, -0xff, 0xff, 0x00, 0x00, 0x00, 0xb5, 0xfe, 0xf7, 0x27, 0xff, 0x08, 0xbc, -0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x22, 0xff, 0x08, 0xbc, 0x18, 0x47, -0x00, 0xb5, 0xfe, 0xf7, 0x1d, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, -0xfe, 0xf7, 0x18, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, -0x13, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, -0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0xf2, 0xfe, 0xf8, 0x88, 0x03, 0x24, -0xe4, 0x04, 0x04, 0x43, 0x03, 0x23, 0xdb, 0x04, 0x9c, 0x42, 0x02, 0xd3, -0x0f, 0x4b, 0x9c, 0x42, 0x06, 0xd9, 0x0f, 0x48, 0x01, 0xab, 0x58, 0x80, -0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x20, 0xfe, 0x01, 0x20, 0x80, 0x07, -0x20, 0x43, 0x00, 0x68, 0x00, 0x21, 0x00, 0xab, 0x59, 0x70, 0xfa, 0x88, -0xc0, 0x46, 0xda, 0x80, 0x02, 0x90, 0x03, 0x91, 0x68, 0x46, 0x04, 0x33, -0xfe, 0xf7, 0x10, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, +0xfe, 0xf7, 0xae, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, +0x4c, 0x2a, 0x00, 0x80, 0x00, 0xb5, 0xfe, 0xf7, 0x7d, 0xff, 0x08, 0xbc, +0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x78, 0xff, 0x08, 0xbc, 0x18, 0x47, +0x00, 0xb5, 0xfe, 0xf7, 0x73, 0xff, 0x08, 0xbc, +0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x6e, 0xff, 0x08, 0xbc, 0x18, 0x47, +0x00, 0xb5, 0xfe, 0xf7, 0x69, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, +0xfe, 0xf7, 0x64, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, +0x5f, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x5a, 0xff, +0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x55, 0xff, 0x08, 0xbc, +0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x50, 0xff, 0x08, 0xbc, 0x18, 0x47, +0x00, 0xb5, 0xfe, 0xf7, 0x4b, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, +0xfe, 0xf7, 0x46, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x8c, 0xb0, +0x08, 0xa9, 0xfe, 0xf7, 0x27, 0xff, 0x69, 0x46, 0x08, 0xa8, 0x04, 0xf0, +0x75, 0xfa, 0x02, 0x20, 0x08, 0xab, 0x58, 0x70, 0x69, 0x46, 0x08, 0xa8, +0xfe, 0xf7, 0x5c, 0xfe, 0x01, 0x20, 0x0c, 0xb0, 0x08, 0xbc, 0x18, 0x47, +0x00, 0xb5, 0xfe, 0xf7, 0x2d, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, +0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0x0c, 0xff, +0xfa, 0x88, 0x12, 0x49, 0x01, 0x24, 0xc8, 0x1d, 0x89, 0x30, 0x00, 0x2a, +0x0f, 0xd0, 0x04, 0x70, 0x44, 0x70, 0xb8, 0x68, 0x00, 0x0c, 0x80, 0x31, +0xc8, 0x82, 0xb8, 0x68, 0xc0, 0x46, 0x08, 0x83, 0xf8, 0x68, 0x00, 0x0c, +0x48, 0x83, 0xf8, 0x68, 0xc0, 0x46, 0x88, 0x83, 0x02, 0xe0, 0x00, 0x21, +0x01, 0x70, 0x41, 0x70, 0x06, 0x48, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, +0x00, 0x21, 0xfe, 0xf7, 0x2b, 0xfe, 0x20, 0x1c, 0x04, 0xb0, 0x90, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, +0x00, 0xb5, 0xfe, 0xf7, 0xf7, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, +0xfe, 0xf7, 0xf2, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, +0xed, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0xe8, 0xfe, +0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0xe3, 0xfe, 0x08, 0xbc, +0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, +0xfe, 0xf7, 0xc2, 0xfe, 0xf8, 0x88, 0x03, 0x24, 0xe4, 0x04, 0x04, 0x43, +0x03, 0x23, 0xdb, 0x04, 0x9c, 0x42, 0x02, 0xd3, 0x0f, 0x4b, 0x9c, 0x42, +0x06, 0xd9, 0x0f, 0x48, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21, +0xfe, 0xf7, 0xf0, 0xfd, 0x01, 0x20, 0x80, 0x07, 0x20, 0x43, 0x00, 0x68, +0x00, 0x21, 0x00, 0xab, 0x59, 0x70, 0xfa, 0x88, 0xc0, 0x46, 0xda, 0x80, +0x02, 0x90, 0x03, 0x91, 0x68, 0x46, 0x04, 0x33, 0xfe, 0xf7, 0xe0, 0xfd, +0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0xe0, 0x00, 0x18, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, 0xb5, 0x84, 0xb0, +0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0x8f, 0xfe, 0xf8, 0x88, +0x03, 0x23, 0xdb, 0x04, 0x18, 0x43, 0x98, 0x42, 0x02, 0xd3, 0x0a, 0x4b, +0x98, 0x42, 0x08, 0xd9, 0x09, 0x48, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, +0x00, 0x21, 0xfe, 0xf7, 0xbf, 0xfd, 0x01, 0x20, 0x03, 0xe0, 0xb9, 0x68, +0xc0, 0x46, 0x01, 0x60, 0x00, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe0, 0x00, 0x18, 0x00, 0xff, 0xff, 0x00, 0x00, -0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, -0xbf, 0xfe, 0xf8, 0x88, 0x03, 0x23, 0xdb, 0x04, 0x18, 0x43, 0x98, 0x42, -0x02, 0xd3, 0x0a, 0x4b, 0x98, 0x42, 0x08, 0xd9, 0x09, 0x48, 0x01, 0xab, -0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xef, 0xfd, 0x01, 0x20, -0x03, 0xe0, 0xb9, 0x68, 0xc0, 0x46, 0x01, 0x60, 0x00, 0x20, 0x04, 0xb0, -0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe0, 0x00, 0x18, 0x00, -0xff, 0xff, 0x00, 0x00, 0x80, 0xb5, 0x86, 0xb0, 0x07, 0x1c, 0x03, 0xf0, -0x5b, 0xfd, 0x38, 0x1c, 0x02, 0xa9, 0xfe, 0xf7, 0x97, 0xfe, 0x01, 0x27, -0x02, 0xab, 0x5f, 0x70, 0x00, 0x20, 0xd8, 0x80, 0x0a, 0x48, 0x01, 0x68, -0xc0, 0x46, 0x04, 0x91, 0x41, 0x68, 0xc0, 0x46, 0x05, 0x91, 0x81, 0x68, -0xc0, 0x46, 0x00, 0x91, 0x00, 0x69, 0xc0, 0x46, 0x01, 0x90, 0x69, 0x46, -0x02, 0xa8, 0xfe, 0xf7, 0xc1, 0xfd, 0x38, 0x1c, 0x06, 0xb0, 0x80, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0xe8, 0x18, 0x00, 0x80, 0x00, 0xb5, 0xc1, 0x68, -0x80, 0x68, 0xfe, 0xf7, 0x79, 0xfb, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, +0x80, 0xb5, 0x86, 0xb0, 0x07, 0x1c, 0x04, 0xf0, 0x33, 0xf9, 0x38, 0x1c, +0x02, 0xa9, 0xfe, 0xf7, 0x67, 0xfe, 0x01, 0x27, 0x02, 0xab, 0x5f, 0x70, +0x00, 0x20, 0xd8, 0x80, 0x0a, 0x48, 0x41, 0x68, 0xc0, 0x46, 0x04, 0x91, +0x81, 0x68, 0xc0, 0x46, 0x05, 0x91, 0xc1, 0x68, +0xc0, 0x46, 0x00, 0x91, 0x40, 0x69, 0xc0, 0x46, 0x01, 0x90, 0x69, 0x46, +0x02, 0xa8, 0xfe, 0xf7, 0x91, 0xfd, 0x38, 0x1c, 0x06, 0xb0, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x68, 0x19, 0x00, 0x80, 0x00, 0xb5, 0xc1, 0x68, +0x80, 0x68, 0xfe, 0xf7, 0x49, 0xfb, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0x70, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x04, 0x1c, 0x0f, 0x1c, -0x68, 0x46, 0x50, 0x21, 0xfe, 0xf7, 0x76, 0xfe, 0x01, 0xab, 0x5c, 0x80, -0x02, 0x97, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xa1, 0xfd, 0x04, 0xb0, +0x68, 0x46, 0x50, 0x21, 0xfe, 0xf7, 0x46, 0xfe, 0x01, 0xab, 0x5c, 0x80, +0x02, 0x97, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x71, 0xfd, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, -0x68, 0x46, 0x51, 0x21, 0xfe, 0xf7, 0x64, 0xfe, 0x01, 0xab, 0x5f, 0x80, -0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x90, 0xfd, 0x04, 0xb0, 0x80, 0xbc, +0x68, 0x46, 0x51, 0x21, 0xfe, 0xf7, 0x34, 0xfe, 0x01, 0xab, 0x5f, 0x80, +0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x60, 0xfd, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x00, 0x27, 0x12, 0x49, 0x09, 0x68, 0x12, 0x4a, 0x12, 0x6b, 0x10, 0x23, 0x1a, 0x40, 0x01, 0x24, 0x00, 0x2a, 0x00, 0xd0, 0x01, 0x27, 0x8a, 0x0c, 0x03, 0xd3, 0x3a, 0x04, 0x12, 0x0c, 0x02, 0x27, 0x17, 0x43, 0xc9, 0x0c, 0x03, 0xd3, 0x39, 0x04, 0x09, 0x0c, 0x04, 0x27, -0x0f, 0x43, 0x69, 0x46, 0xfe, 0xf7, 0x2c, 0xfe, 0x01, 0xab, 0x5f, 0x80, -0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x66, 0xfd, 0x20, 0x1c, 0x04, 0xb0, +0x0f, 0x43, 0x69, 0x46, 0xfe, 0xf7, 0xfc, 0xfd, 0x01, 0xab, 0x5f, 0x80, +0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x36, 0xfd, 0x20, 0x1c, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, -0xc0, 0x00, 0x18, 0x40, 0x00, 0xb5, 0x84, 0xb0, -0x69, 0x46, 0xfe, 0xf7, 0x17, 0xfe, 0x06, 0x48, 0xc0, 0x6d, 0x01, 0xab, -0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x4f, 0xfd, 0x01, 0x20, -0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x10, 0x2a, 0x00, 0x80, -0x00, 0xb5, 0xfe, 0xf7, 0x1d, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x70, 0x47, -0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, -0x80, 0xb5, 0x01, 0x20, 0x14, 0x4f, 0x71, 0x23, 0x5b, 0x01, 0xf9, 0x18, -0x48, 0x71, 0x13, 0x48, 0xfe, 0xf7, 0xd6, 0xfb, 0x01, 0x20, 0x40, 0x02, -0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0xf9, 0x1d, 0xb9, 0x31, -0x08, 0x70, 0x0e, 0x4a, 0x01, 0x23, 0x1b, 0x04, 0x11, 0x68, 0x0b, 0x40, -0x15, 0x21, 0x00, 0x2b, 0x05, 0xd1, 0x13, 0x68, 0x1b, 0x0c, 0x08, 0xd1, -0x12, 0x68, 0x92, 0x0a, 0x05, 0xd3, 0x08, 0x4a, 0xc0, 0x46, 0xd1, 0x60, -0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x06, 0x4a, 0xc0, 0x46, 0x11, 0x64, -0xf8, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0xa9, 0x9d, 0x21, 0x40, -0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, +0xc0, 0x00, 0x18, 0x40, 0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xfe, 0xf7, +0xe7, 0xfd, 0x06, 0x48, 0xc0, 0x6d, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, +0x00, 0x21, 0xfe, 0xf7, 0x1f, 0xfd, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0xa4, 0x2a, 0x00, 0x80, 0x00, 0xb5, 0xfe, 0xf7, +0xed, 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, -0x80, 0xb5, 0x85, 0xb0, 0x01, 0xa9, 0xfe, 0xf7, 0xbb, 0xfd, 0x00, 0x20, -0x01, 0xab, 0x58, 0x70, 0x10, 0x49, 0xc9, 0x68, 0x01, 0x27, 0x01, 0x29, -0x0a, 0xd1, 0x03, 0xf0, 0xb9, 0xfc, 0x03, 0x90, 0x04, 0x97, 0x03, 0x98, -0x00, 0x28, 0x06, 0xd0, 0x68, 0x46, 0x02, 0xf0, 0x15, 0xf8, 0x04, 0xe0, -0x03, 0x97, 0x04, 0x90, 0xf8, 0xe7, 0x00, 0x20, 0x00, 0x90, 0x02, 0xab, -0x00, 0x98, 0xc0, 0x46, 0x58, 0x80, 0x00, 0x21, 0x01, 0xa8, 0xfe, 0xf7, -0xdb, 0xfc, 0x38, 0x1c, 0x05, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0xe8, 0x0d, 0x00, 0x80, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, -0x38, 0x1c, 0xfe, 0xf7, 0x8d, 0xfd, 0x00, 0x20, 0x00, 0xab, 0x58, 0x70, -0x01, 0x24, 0x20, 0x1c, 0x12, 0x49, 0xc9, 0x68, 0x01, 0x29, 0x00, 0xd0, -0x00, 0x20, 0x00, 0x06, 0x00, 0x0e, 0x13, 0xd0, 0xf8, 0x88, 0x0f, 0x4a, -0x90, 0x42, 0x02, 0xd0, 0x0e, 0x4b, 0x98, 0x42, 0x08, 0xd1, 0xb9, 0x68, -0x27, 0x1c, 0x90, 0x42, 0x00, 0xd0, 0x00, 0x27, 0x38, 0x06, 0x00, 0x0e, -0x03, 0xf0, 0xa0, 0xfc, 0x03, 0xf0, 0x76, 0xfc, 0x02, 0x90, 0x00, 0xe0, -0x02, 0x94, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xa7, 0xfc, 0x20, 0x1c, -0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, -0xed, 0xfe, 0x00, 0x00, 0xfe, 0xca, 0x00, 0x00, 0x90, 0xb5, 0x07, 0x1c, -0x00, 0x24, 0x00, 0x2f, 0x04, 0xd3, 0x04, 0xf0, 0x9b, 0xf8, 0x01, 0x34, -0xbc, 0x42, 0xfa, 0xd9, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, -0x14, 0x1c, 0x0d, 0x1c, 0x06, 0x1c, 0x1f, 0x1c, 0x1b, 0x4b, 0x32, 0x04, -0x12, 0x0c, 0x3c, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0x2a, 0xfb, 0x32, 0x0c, -0x17, 0x4b, 0x3e, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0x24, 0xfb, 0x15, 0x4b, -0x2a, 0x04, 0x12, 0x0c, 0x40, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0x1d, 0xfb, -0x2a, 0x0c, 0x11, 0x4b, 0x42, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0x17, 0xfb, -0x0e, 0x4b, 0x22, 0x04, 0x12, 0x0c, 0x44, 0x21, 0x02, 0x20, 0xfe, 0xf7, -0x10, 0xfb, 0x22, 0x0c, 0x0a, 0x4b, 0x46, 0x21, 0x02, 0x20, 0xfe, 0xf7, -0x0a, 0xfb, 0x08, 0x4b, 0x3a, 0x04, 0x12, 0x0c, 0x48, 0x21, 0x02, 0x20, -0xfe, 0xf7, 0x03, 0xfb, 0x3a, 0x0c, 0x04, 0x4b, -0x4a, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0xfd, 0xfa, 0xf0, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0x7b, 0xb7, 0x21, 0x40, 0x88, 0xb5, 0x11, 0x27, -0x3f, 0x04, 0x38, 0x62, 0x79, 0x62, 0xba, 0x62, 0xfb, 0x62, 0x04, 0x20, -0xff, 0xf7, 0xaa, 0xff, 0x07, 0x48, 0x40, 0x6b, 0xc0, 0x46, 0x00, 0x90, -0x00, 0x98, 0x80, 0x07, 0x80, 0x0f, 0x03, 0x28, 0x01, 0xd1, 0x01, 0x20, -0x00, 0xe0, 0x00, 0x20, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, -0x00, 0x00, 0x11, 0x40, 0xf0, 0xb5, 0x8a, 0xb0, 0x00, 0x24, 0x05, 0x94, -0x69, 0x49, 0xc9, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x68, 0x4a, 0x11, 0x68, -0x01, 0x22, 0x12, 0x04, 0x0a, 0x40, 0x17, 0x21, 0x66, 0x4e, 0x00, 0x2a, -0x06, 0xd1, 0x64, 0x4a, 0x13, 0x68, 0x1b, 0x0c, 0x04, 0xd1, 0x12, 0x68, -0x92, 0x0a, 0x01, 0xd3, 0xf1, 0x60, 0x02, 0xe0, 0x61, 0x4a, 0xc0, 0x46, -0x11, 0x64, 0x61, 0x49, 0x89, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x03, 0x29, -0x54, 0xd1, 0xe9, 0x21, 0x01, 0x91, 0x02, 0x99, 0xc0, 0x46, 0xb1, 0x60, -0x06, 0x94, 0x06, 0x99, 0x8a, 0x00, 0x5b, 0x49, 0x8a, 0x58, 0x00, 0x2a, -0x73, 0xd0, 0x80, 0x20, 0x02, 0x90, 0x06, 0x98, 0x81, 0x00, 0x57, 0x48, -0x41, 0x58, 0x02, 0x9a, 0x11, 0x43, 0x02, 0x91, 0x00, 0x24, 0x00, 0x27, -0x25, 0x02, 0x28, 0x1c, 0x38, 0x43, 0x09, 0x90, 0x09, 0x98, 0x00, 0x04, -0x51, 0x4b, 0x18, 0x43, 0x04, 0x90, 0x09, 0x98, 0xef, 0x23, 0xdb, 0x05, -0x18, 0x43, 0x03, 0x90, 0x06, 0x98, 0x80, 0x00, 0x4b, 0x49, 0x08, 0x58, -0x00, 0x04, 0x03, 0x99, 0x08, 0x43, 0x03, 0x90, 0x00, 0x2f, 0x02, 0xd1, -0x03, 0x98, 0xc0, 0x46, 0x70, 0x60, 0x01, 0x9b, 0x03, 0x9a, 0x02, 0x99, -0x04, 0x98, 0xff, 0xf7, 0x89, 0xff, 0x00, 0x28, 0x06, 0xd0, 0x02, 0x99, -0xc0, 0x46, 0xb1, 0x60, 0x03, 0x99, 0xc0, 0x46, 0x71, 0x60, 0x5c, 0xe0, -0x79, 0x1c, 0x0f, 0x04, 0x3f, 0x0c, 0x17, 0x2f, 0xd1, 0xdd, 0x61, 0x1c, -0x0c, 0x04, 0x24, 0x0c, 0x16, 0x2c, 0xca, 0xdd, 0x06, 0x99, 0x01, 0x31, -0x06, 0x91, 0x06, 0x99, 0x89, 0x00, 0x37, 0x4a, 0x51, 0x58, 0x00, 0x29, -0xb7, 0xd1, 0x48, 0xe0, 0xbf, 0x21, 0xc9, 0x43, 0x04, 0x91, 0xff, 0x21, -0x02, 0x91, 0x97, 0x21, 0x01, 0x91, 0x06, 0x94, 0x06, 0x99, 0x89, 0x00, -0x31, 0x4f, 0x79, 0x58, 0x00, 0x29, 0x1c, 0xd0, 0x09, 0x94, 0x08, 0x94, -0x06, 0x98, 0x80, 0x00, 0x38, 0x58, 0xc0, 0x46, 0x07, 0x90, 0x07, 0x98, -0x00, 0x04, 0x26, 0xe0, 0x05, 0x98, 0x15, 0x23, 0x1b, 0x06, 0x18, 0x43, -0x03, 0x90, 0x01, 0x9b, 0x03, 0x9a, 0x02, 0x99, 0x04, 0x98, 0xff, 0xf7, -0x49, 0xff, 0x00, 0x28, 0x23, 0xd1, 0x09, 0x99, 0x01, 0x31, 0x09, 0x91, -0x17, 0x29, 0x06, 0xd8, 0x00, 0xe0, 0x1c, 0xe0, 0x08, 0x98, 0x00, 0x02, -0x09, 0x99, 0x08, 0x43, 0x07, 0xe0, 0x08, 0x99, 0x01, 0x31, 0x08, 0x91, -0x17, 0x29, 0x0a, 0xd8, 0x09, 0x94, 0x08, 0x98, 0x00, 0x02, 0x07, 0x99, -0x09, 0x04, 0x08, 0x43, 0x15, 0x23, 0x1b, 0x06, 0x18, 0x43, 0x05, 0x90, -0xd6, 0xe7, 0x06, 0x99, 0x01, 0x31, 0x06, 0x91, 0x06, 0x99, 0x89, 0x00, -0x79, 0x58, 0x00, 0x29, 0xc4, 0xd1, 0x0c, 0x4a, 0x11, 0x68, 0x49, 0x0c, -0x05, 0xd2, 0x11, 0x68, 0x09, 0x0c, 0x06, 0xd1, 0x11, 0x68, 0x89, 0x0a, -0x03, 0xd3, 0x00, 0x99, 0xc0, 0x46, 0xf1, 0x60, 0x03, 0xe0, 0x00, 0x99, -0x06, 0x4a, 0xc0, 0x46, 0x11, 0x64, 0x0a, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0x40, 0x01, 0x18, 0x40, -0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, -0x00, 0x00, 0x18, 0x40, 0x30, 0x6e, 0x21, 0x40, 0x43, 0xff, 0x00, 0x00, -0x0c, 0x6e, 0x21, 0x40, 0x80, 0xb5, 0x82, 0xb0, 0x00, 0x20, 0x01, 0x90, -0x1e, 0x48, 0xc1, 0x68, 0x01, 0x29, 0x1b, 0xd1, 0x40, 0x88, 0x00, 0x28, -0x18, 0xd1, 0x68, 0x46, 0x01, 0xf0, 0x6a, 0xfe, 0x00, 0x28, 0x13, 0xd1, -0xa8, 0x20, 0x01, 0xf0, 0xab, 0xfe, 0x18, 0x4f, 0x00, 0x28, 0x11, 0xd0, -0x04, 0x20, 0xff, 0xf7, 0x97, 0xfe, 0x78, 0x6b, 0xc0, 0x46, 0x01, 0x90, -0x01, 0x98, 0x80, 0x07, 0x80, 0x0f, 0x03, 0x28, 0x06, 0xd1, 0x00, 0x20, -0x01, 0xf0, 0x9a, 0xfe, 0x02, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x00, 0x23, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0xff, 0xf7, 0x8f, 0xfe, -0x00, 0x23, 0xdb, 0x43, 0x18, 0x1c, 0x19, 0x1c, 0x1a, 0x1c, 0xff, 0xf7, -0xc7, 0xfe, 0x00, 0x28, 0x03, 0xd1, 0xff, 0xf7, 0xdf, 0xfe, 0x00, 0x28, -0xe5, 0xd0, 0x38, 0x6a, 0x79, 0x6a, 0xba, 0x6a, 0xfb, 0x6a, 0xff, 0xf7, -0x7c, 0xfe, 0xde, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x00, 0x11, 0x40, -0xff, 0xb5, 0x85, 0xb0, 0x14, 0x1c, 0x1f, 0x1c, 0x00, 0x20, 0x01, 0x90, -0x01, 0x23, 0x5b, 0x04, 0x9f, 0x42, 0x01, 0xd9, 0x0f, 0x20, 0x82, 0xe0, -0x26, 0x1c, 0x43, 0x4d, 0xaf, 0x42, 0x00, 0xd2, 0x3d, 0x1c, 0x21, 0x0d, -0x09, 0x05, 0x41, 0x48, 0x41, 0x4b, 0x99, 0x42, 0x04, 0xd0, 0x80, 0x25, -0x06, 0x1c, 0x80, 0x2f, 0x00, 0xd8, 0x3d, 0x1c, 0x3e, 0x4a, 0x51, 0x69, -0xc0, 0x46, 0x03, 0x91, 0x92, 0x69, 0xc0, 0x46, 0x02, 0x92, 0xff, 0x23, -0x01, 0x33, 0x19, 0x43, 0x39, 0x4b, 0xc0, 0x46, 0x59, 0x61, 0xff, 0x23, -0x01, 0x33, 0x9a, 0x43, 0x36, 0x4b, 0xc0, 0x46, 0x9a, 0x61, 0x01, 0x22, -0x12, 0x05, 0xd1, 0x60, 0x33, 0x4a, 0x91, 0x69, 0x01, 0x22, 0x12, 0x05, -0x11, 0x61, 0x31, 0x4a, 0xff, 0x23, 0x01, 0x33, 0x91, 0x69, 0x19, 0x43, -0x91, 0x61, 0x01, 0x22, 0x12, 0x05, 0x11, 0x61, 0x85, 0x21, 0x89, 0x04, -0x04, 0x91, 0x00, 0x2f, 0x34, 0xd0, 0x28, 0x48, 0x86, 0x42, 0x04, 0xd1, -0x30, 0x1c, 0x21, 0x1c, 0x2a, 0x1c, 0x03, 0xf0, 0xd5, 0xfe, 0x2a, 0x1c, -0x04, 0x98, 0x02, 0x43, 0x00, 0x92, 0x01, 0x20, 0x06, 0x99, 0x05, 0x9a, -0x33, 0x1c, 0xfe, 0xf7, 0x5d, 0xf9, 0x22, 0x48, 0x22, 0x49, 0x4a, 0x68, -0x52, 0x0a, 0x09, 0xd3, 0xff, 0x21, 0x01, 0x31, 0x20, 0x4a, 0xc0, 0x46, -0x11, 0x60, 0x00, 0x28, 0x05, 0xd1, 0x11, 0x20, 0x01, 0x90, 0x13, 0xe0, -0x01, 0x38, 0xf0, 0xd1, 0xf9, 0xe7, 0x7f, 0x1b, 0x0e, 0xd0, 0x15, 0x48, -0x86, 0x42, 0x01, 0xd1, 0x64, 0x19, 0x00, 0xe0, 0x76, 0x19, 0x06, 0x99, -0x49, 0x19, 0x06, 0x91, 0x38, 0x1c, 0xaf, 0x42, 0x00, 0xd3, 0x28, 0x1c, -0x05, 0x1c, 0xca, 0xe7, 0x0f, 0x48, 0x41, 0x69, 0x03, 0x9b, 0x19, 0x43, -0x41, 0x61, 0x82, 0x69, 0x03, 0x9b, 0x9a, 0x43, 0x82, 0x61, 0x01, 0x22, -0x12, 0x05, 0xd1, 0x60, 0x81, 0x69, 0xc0, 0x46, 0x11, 0x61, 0x81, 0x69, -0x02, 0x9b, 0x19, 0x43, 0x81, 0x61, 0x11, 0x61, 0x01, 0x98, 0x09, 0xb0, -0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, -0x50, 0xab, 0x20, 0x40, 0x00, 0x00, 0x20, 0x40, 0xe8, 0x0d, 0x00, 0x80, +0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0xb5, 0xfe, 0xf7, +0xdb, 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x80, 0xb5, 0x85, 0xb0, +0x01, 0xa9, 0xfe, 0xf7, 0xbb, 0xfd, 0x00, 0x20, 0x01, 0xab, 0x58, 0x70, +0x10, 0x49, 0xc9, 0x68, 0x01, 0x27, 0x01, 0x29, 0x0a, 0xd1, 0x04, 0xf0, +0xc7, 0xf8, 0x03, 0x90, 0x04, 0x97, 0x03, 0x98, 0x00, 0x28, 0x06, 0xd0, +0x68, 0x46, 0x02, 0xf0, 0xe5, 0xfb, 0x04, 0xe0, 0x03, 0x97, 0x04, 0x90, +0xf8, 0xe7, 0x00, 0x20, 0x00, 0x90, 0x02, 0xab, 0x00, 0x98, 0xc0, 0x46, +0x58, 0x80, 0x00, 0x21, 0x01, 0xa8, 0xfe, 0xf7, 0xdb, 0xfc, 0x38, 0x1c, +0x05, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, +0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, +0x8d, 0xfd, 0x00, 0x20, 0x00, 0xab, 0x58, 0x70, 0x01, 0x24, 0x20, 0x1c, +0x12, 0x49, 0xc9, 0x68, 0x01, 0x29, 0x00, 0xd0, 0x00, 0x20, 0x00, 0x06, +0x00, 0x0e, 0x13, 0xd0, 0xf8, 0x88, 0x0f, 0x4a, 0x90, 0x42, 0x02, 0xd0, +0x0e, 0x4b, 0x98, 0x42, 0x08, 0xd1, 0xb9, 0x68, 0x27, 0x1c, 0x90, 0x42, +0x00, 0xd0, 0x00, 0x27, 0x38, 0x06, 0x00, 0x0e, 0x04, 0xf0, 0x88, 0xf8, +0x04, 0xf0, 0x84, 0xf8, 0x02, 0x90, 0x00, 0xe0, 0x02, 0x94, 0x68, 0x46, +0x00, 0x21, 0xfe, 0xf7, 0xa7, 0xfc, 0x20, 0x1c, 0x04, 0xb0, 0x90, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0xed, 0xfe, 0x00, 0x00, +0xfe, 0xca, 0x00, 0x00, 0xf1, 0xb5, 0xd6, 0xb0, +0x00, 0x20, 0x81, 0x00, 0x56, 0x9c, 0x0a, 0x19, 0x12, 0x6a, 0x6b, 0x46, +0x5a, 0x50, 0x01, 0x30, 0x10, 0x28, 0xf6, 0xdb, 0x10, 0x20, 0x82, 0x00, +0x11, 0x1c, 0x69, 0x44, 0x40, 0x39, 0x4b, 0x6b, 0x0f, 0x6a, 0x7b, 0x40, +0x8f, 0x68, 0x7b, 0x40, 0x09, 0x68, 0x59, 0x40, 0x4b, 0x00, 0xc9, 0x0f, +0x19, 0x43, 0x6b, 0x46, 0x99, 0x50, 0x01, 0x30, 0x50, 0x28, 0xec, 0xdb, +0x56, 0x98, 0x01, 0x68, 0xc0, 0x46, 0x55, 0x91, 0x42, 0x68, 0xc0, 0x46, +0x54, 0x92, 0x86, 0x68, 0xc0, 0x46, 0x53, 0x96, 0xc5, 0x68, 0xc0, 0x46, +0x52, 0x95, 0x04, 0x69, 0xc0, 0x46, 0x51, 0x94, 0x48, 0x01, 0xcb, 0x0e, +0x18, 0x43, 0x13, 0x1c, 0x33, 0x40, 0x07, 0x1c, 0x28, 0x1c, 0x90, 0x43, +0x18, 0x43, 0x38, 0x18, 0x00, 0x19, 0x00, 0x9b, 0xc0, 0x18, 0xcf, 0x4b, +0xc0, 0x18, 0x93, 0x07, 0x92, 0x08, 0x13, 0x43, 0x42, 0x01, 0x1f, 0x1c, +0xc3, 0x0e, 0x1a, 0x43, 0x0b, 0x1c, 0x3b, 0x40, 0x14, 0x1c, 0x32, 0x1c, +0x8a, 0x43, 0x1a, 0x43, 0xa2, 0x18, 0x52, 0x19, 0x01, 0x9b, 0xd2, 0x18, +0xc5, 0x4b, 0xd4, 0x18, 0x8a, 0x07, 0x89, 0x08, 0x11, 0x43, 0x62, 0x01, +0xe3, 0x0e, 0x1a, 0x43, 0x03, 0x1c, 0x0b, 0x40, 0x15, 0x1c, 0x3a, 0x1c, +0x82, 0x43, 0x1a, 0x43, 0xaa, 0x18, 0x92, 0x19, 0x02, 0x9b, 0xd2, 0x18, +0xbc, 0x4b, 0xd2, 0x18, 0x3b, 0x1c, 0x87, 0x07, 0x80, 0x08, 0x38, 0x43, +0x57, 0x01, 0xd5, 0x0e, 0x3d, 0x43, 0x27, 0x1c, 0x07, 0x40, 0x0e, 0x1c, +0xa6, 0x43, 0x37, 0x43, 0xed, 0x19, 0xeb, 0x18, 0x03, 0x9f, 0xdf, 0x19, +0xb3, 0x4b, 0xff, 0x18, 0xa3, 0x07, 0xa4, 0x08, 0x1c, 0x43, 0x7b, 0x01, +0xfd, 0x0e, 0x2b, 0x43, 0x15, 0x1c, 0x25, 0x40, 0x1e, 0x1c, 0x03, 0x1c, +0x93, 0x43, 0x2b, 0x43, 0xf3, 0x18, 0x59, 0x18, 0x04, 0x9b, 0xc9, 0x18, +0xaa, 0x4b, 0xc9, 0x18, 0x93, 0x07, 0x92, 0x08, 0x1a, 0x43, 0x4b, 0x01, +0xcd, 0x0e, 0x1d, 0x43, 0x3e, 0x1c, 0x16, 0x40, 0x23, 0x1c, 0xbb, 0x43, +0x33, 0x43, 0xeb, 0x18, 0x18, 0x18, 0x05, 0x9b, 0xc0, 0x18, 0xa2, 0x4b, +0xc0, 0x18, 0xbb, 0x07, 0xbf, 0x08, 0x1f, 0x43, 0x43, 0x01, 0xc5, 0x0e, +0x2b, 0x43, 0x0d, 0x1c, 0x3d, 0x40, 0x1e, 0x1c, 0x13, 0x1c, 0x8b, 0x43, +0x2b, 0x43, 0xf3, 0x18, 0x1b, 0x19, 0x06, 0x9c, 0x1c, 0x19, 0x99, 0x4b, +0xe4, 0x18, 0x8b, 0x07, 0x89, 0x08, 0x19, 0x43, 0x63, 0x01, 0xe5, 0x0e, +0x1d, 0x43, 0x03, 0x1c, 0x0b, 0x40, 0x3e, 0x1c, 0x86, 0x43, 0x33, 0x43, +0xeb, 0x18, 0x9a, 0x18, 0x07, 0x9b, 0xd2, 0x18, 0x90, 0x4b, 0xd2, 0x18, +0x3b, 0x1c, 0x87, 0x07, 0x80, 0x08, 0x38, 0x43, 0x57, 0x01, 0xd5, 0x0e, +0x2f, 0x43, 0x25, 0x1c, 0x05, 0x40, 0x3e, 0x1c, 0x0f, 0x1c, 0xa7, 0x43, +0x2f, 0x43, 0xf5, 0x19, 0xeb, 0x18, 0x08, 0x9f, 0xdf, 0x19, 0x87, 0x4b, +0xff, 0x18, 0xa3, 0x07, 0xa4, 0x08, 0x1c, 0x43, 0x7b, 0x01, 0xfd, 0x0e, +0x1d, 0x43, 0x16, 0x1c, 0x26, 0x40, 0x03, 0x1c, 0x93, 0x43, 0x33, 0x43, +0xeb, 0x18, 0x59, 0x18, 0x09, 0x9b, 0xc9, 0x18, 0x7e, 0x4b, 0xc9, 0x18, +0x93, 0x07, 0x92, 0x08, 0x1a, 0x43, 0x4b, 0x01, 0xcd, 0x0e, 0x1d, 0x43, +0x3b, 0x1c, 0x13, 0x40, 0x26, 0x1c, 0xbe, 0x43, 0x33, 0x43, 0xeb, 0x18, +0x18, 0x18, 0x0a, 0x9b, 0xc0, 0x18, 0x76, 0x4b, 0xc0, 0x18, 0x23, 0x1c, +0xbc, 0x07, 0xbf, 0x08, 0x27, 0x43, 0x44, 0x01, 0xc5, 0x0e, 0x2c, 0x43, +0x0d, 0x1c, 0x3d, 0x40, 0x26, 0x1c, 0x14, 0x1c, 0x8c, 0x43, 0x2c, 0x43, +0x35, 0x19, 0xeb, 0x18, 0x0b, 0x9c, 0x1c, 0x19, +0x6c, 0x4b, 0xe4, 0x18, 0x8b, 0x07, 0x89, 0x08, 0x19, 0x43, 0x63, 0x01, +0xe5, 0x0e, 0x1d, 0x43, 0x03, 0x1c, 0x0b, 0x40, 0x3e, 0x1c, 0x86, 0x43, +0x33, 0x43, 0xeb, 0x18, 0x9a, 0x18, 0x0c, 0x9b, 0xd2, 0x18, 0x64, 0x4b, +0xd2, 0x18, 0x3b, 0x1c, 0x87, 0x07, 0x80, 0x08, 0x38, 0x43, 0x57, 0x01, +0xd5, 0x0e, 0x3d, 0x43, 0x27, 0x1c, 0x07, 0x40, 0x0e, 0x1c, 0xa6, 0x43, +0x37, 0x43, 0xed, 0x19, 0xeb, 0x18, 0x0d, 0x9f, 0xdf, 0x19, 0x5b, 0x4b, +0xff, 0x18, 0xa3, 0x07, 0xa4, 0x08, 0x1c, 0x43, 0x7b, 0x01, 0xfd, 0x0e, +0x1d, 0x43, 0x13, 0x1c, 0x23, 0x40, 0x06, 0x1c, 0x96, 0x43, 0x33, 0x43, +0xeb, 0x18, 0x59, 0x18, 0x0e, 0x9b, 0xc9, 0x18, 0x52, 0x4b, 0xc9, 0x18, +0x93, 0x07, 0x92, 0x08, 0x1a, 0x43, 0x4b, 0x01, 0xcd, 0x0e, 0x2b, 0x43, +0x3d, 0x1c, 0x15, 0x40, 0x1e, 0x1c, 0x23, 0x1c, 0xbb, 0x43, 0x2b, 0x43, +0xf3, 0x18, 0x18, 0x18, 0x0f, 0x9b, 0xc0, 0x18, 0x49, 0x4b, 0xc0, 0x18, +0x23, 0x1c, 0xbc, 0x07, 0xbf, 0x08, 0x27, 0x43, 0x10, 0x24, 0x50, 0x94, +0x44, 0x01, 0xc5, 0x0e, 0x25, 0x43, 0x0e, 0x1c, 0x3e, 0x40, 0x14, 0x1c, +0x8c, 0x43, 0x34, 0x43, 0x2c, 0x19, 0xe3, 0x18, 0x50, 0x9c, 0xa5, 0x00, +0x6c, 0x46, 0x64, 0x59, 0x1c, 0x19, 0x3e, 0x4b, 0xe4, 0x18, 0x13, 0x1c, +0x3a, 0x1c, 0x8f, 0x07, 0x89, 0x08, 0x0f, 0x43, 0x01, 0x1c, 0x20, 0x1c, +0x50, 0x9c, 0x01, 0x34, 0x50, 0x94, 0x14, 0x2c, 0xe2, 0xdb, 0x14, 0x24, +0x45, 0x01, 0xc6, 0x0e, 0x2e, 0x43, 0x0d, 0x1c, 0x7d, 0x40, 0x55, 0x40, +0x75, 0x19, 0xeb, 0x18, 0xa5, 0x00, 0x6e, 0x46, 0x75, 0x59, 0x5d, 0x19, +0x31, 0x4b, 0xed, 0x18, 0x13, 0x1c, 0x3a, 0x1c, 0x8f, 0x07, 0x89, 0x08, +0x0f, 0x43, 0x01, 0x1c, 0x28, 0x1c, 0x01, 0x34, 0x28, 0x2c, 0xe7, 0xdb, +0x28, 0x24, 0x50, 0x94, 0x44, 0x01, 0xc5, 0x0e, 0x25, 0x43, 0x3c, 0x1c, +0x14, 0x43, 0x0c, 0x40, 0x3e, 0x1c, 0x16, 0x40, 0x34, 0x43, 0x2c, 0x19, +0xe3, 0x18, 0x50, 0x9c, 0xa5, 0x00, 0x6c, 0x46, 0x64, 0x59, 0x1c, 0x19, +0x23, 0x4b, 0xe4, 0x18, 0x13, 0x1c, 0x3a, 0x1c, 0x8f, 0x07, 0x89, 0x08, +0x0f, 0x43, 0x01, 0x1c, 0x20, 0x1c, 0x50, 0x9c, 0x01, 0x34, 0x50, 0x94, +0x3c, 0x2c, 0xe1, 0xdb, 0x3c, 0x24, 0x45, 0x01, 0xc6, 0x0e, 0x2e, 0x43, +0x0d, 0x1c, 0x7d, 0x40, 0x55, 0x40, 0x75, 0x19, 0xeb, 0x18, 0xa6, 0x00, +0x6d, 0x46, 0xad, 0x59, 0x5d, 0x19, 0x17, 0x4b, 0xed, 0x18, 0x13, 0x1c, +0x3a, 0x1c, 0x8f, 0x07, 0x89, 0x08, 0x0f, 0x43, 0x01, 0x1c, 0x28, 0x1c, +0x01, 0x34, 0x50, 0x2c, 0xe7, 0xdb, 0x55, 0x9c, 0x20, 0x18, 0x56, 0x9c, +0xc0, 0x46, 0x20, 0x60, 0x54, 0x98, 0x40, 0x18, 0x56, 0x9c, 0xc0, 0x46, +0x60, 0x60, 0x53, 0x9e, 0xf0, 0x19, 0x56, 0x9c, 0xc0, 0x46, 0xa0, 0x60, +0x52, 0x9d, 0xa8, 0x18, 0x56, 0x9c, 0xc0, 0x46, 0xe0, 0x60, 0x51, 0x9c, +0xe0, 0x18, 0x56, 0x9c, 0xc0, 0x46, 0x20, 0x61, 0x57, 0xb0, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x99, 0x79, 0x82, 0x5a, 0xa1, 0xeb, 0xd9, 0x6e, +0xdc, 0xbc, 0x1b, 0x8f, 0xd6, 0xc1, 0x62, 0xca, 0x88, 0xb4, 0x8a, 0x08, +0x89, 0x07, 0x00, 0xd0, 0x01, 0x32, 0x00, 0x21, 0x00, 0x2a, 0x1e, 0xdd, +0x07, 0x78, 0x00, 0xab, 0x1f, 0x70, 0x47, 0x78, 0xc0, 0x46, 0x5f, 0x70, +0x87, 0x78, 0xc0, 0x46, 0x9f, 0x70, 0xc7, 0x78, 0xc0, 0x46, 0xdf, 0x70, +0xdb, 0x78, 0xc0, 0x46, 0x03, 0x70, 0x00, 0xab, 0x9b, 0x78, 0xc0, 0x46, +0x43, 0x70, 0x00, 0xab, 0x5b, 0x78, 0xc0, 0x46, +0x83, 0x70, 0x00, 0xab, 0x1b, 0x78, 0xc0, 0x46, 0xc3, 0x70, 0x04, 0x30, +0x01, 0x31, 0x91, 0x42, 0xe0, 0xdb, 0x88, 0xbc, 0x70, 0x47, 0x00, 0x21, +0xc1, 0x61, 0x09, 0x4a, 0xc0, 0x46, 0x02, 0x60, 0x08, 0x4a, 0xc0, 0x46, +0x42, 0x60, 0x08, 0x4a, 0xc0, 0x46, 0x82, 0x60, 0x07, 0x4a, 0xc0, 0x46, +0xc2, 0x60, 0x07, 0x4a, 0xc0, 0x46, 0x02, 0x61, 0x41, 0x61, 0x81, 0x61, +0x70, 0x47, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, +0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xf0, 0xe1, 0xd2, 0xc3, +0xf0, 0xb5, 0x14, 0x1c, 0x0d, 0x1c, 0x07, 0x1c, 0xe1, 0x00, 0x78, 0x69, +0x41, 0x18, 0x81, 0x42, 0x02, 0xd2, 0xb8, 0x69, 0x01, 0x30, 0xb8, 0x61, +0x79, 0x61, 0x61, 0x0f, 0xb8, 0x69, 0x40, 0x18, 0xb8, 0x61, 0x40, 0x2c, +0x14, 0xdb, 0xfe, 0x1d, 0x19, 0x36, 0x00, 0x20, 0x29, 0x78, 0x3a, 0x18, +0x20, 0x32, 0x11, 0x70, 0x01, 0x35, 0x01, 0x30, 0x40, 0x28, 0xf7, 0xd3, +0x40, 0x21, 0x30, 0x1c, 0xff, 0xf7, 0x96, 0xff, 0x38, 0x1c, 0xff, 0xf7, +0xaf, 0xfd, 0x40, 0x3c, 0x40, 0x2c, 0xec, 0xda, 0x00, 0x20, 0x00, 0x2c, +0x07, 0xd9, 0x29, 0x78, 0x3a, 0x18, 0x20, 0x32, 0x11, 0x70, 0x01, 0x35, +0x01, 0x30, 0xa0, 0x42, 0xf7, 0xd3, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0xf8, 0xb5, 0x07, 0x1c, 0xd3, 0x00, 0x78, 0x69, 0xc6, 0x18, 0x86, 0x42, +0x02, 0xd2, 0xb8, 0x69, 0x01, 0x30, 0xb8, 0x61, 0x7e, 0x61, 0x53, 0x0f, +0xb8, 0x69, 0xc0, 0x18, 0xb8, 0x61, 0x00, 0x90, 0x00, 0x20, 0x00, 0x2a, +0x07, 0xdd, 0x0b, 0x78, 0x3c, 0x18, 0x20, 0x34, 0x23, 0x70, 0x01, 0x31, +0x01, 0x30, 0x90, 0x42, 0xf7, 0xdb, 0x80, 0x20, 0xd1, 0x19, 0x20, 0x31, +0x08, 0x70, 0x54, 0x1c, 0xfd, 0x1d, 0x19, 0x35, 0x38, 0x2c, 0x1c, 0xdd, +0x38, 0x19, 0x20, 0x30, 0x00, 0x21, 0x40, 0x22, 0x12, 0x1b, 0x00, 0x2a, +0x05, 0xdd, 0x00, 0x23, 0x03, 0x70, 0x01, 0x30, 0x01, 0x31, 0x8a, 0x42, +0xfa, 0xdc, 0x28, 0x1c, 0x21, 0x1c, 0xff, 0xf7, 0x4d, 0xff, 0x38, 0x1c, +0xff, 0xf7, 0x66, 0xfd, 0x28, 0x1c, 0x00, 0x21, 0x00, 0x23, 0x03, 0x70, +0x01, 0x30, 0x01, 0x31, 0x38, 0x29, 0xfa, 0xdb, 0x0c, 0xe0, 0x38, 0x19, +0x20, 0x30, 0x00, 0x21, 0x38, 0x22, 0x12, 0x1b, 0x00, 0x2a, 0x05, 0xdd, +0x00, 0x23, 0x03, 0x70, 0x01, 0x30, 0x01, 0x31, 0x8a, 0x42, 0xfa, 0xdc, +0x28, 0x1c, 0x21, 0x1c, 0xff, 0xf7, 0x30, 0xff, 0x00, 0x98, 0xc0, 0x46, +0xb8, 0x65, 0xfe, 0x65, 0x38, 0x1c, 0xff, 0xf7, 0x45, 0xfd, 0x01, 0x20, +0xf8, 0x61, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x0c, 0x1c, +0x05, 0x1c, 0x17, 0x1c, 0x38, 0x1c, 0x00, 0x2f, 0x04, 0xda, 0x40, 0x42, +0x80, 0x06, 0x80, 0x0e, 0x40, 0x42, 0x01, 0xe0, 0x80, 0x06, 0x80, 0x0e, +0x00, 0x28, 0x07, 0xd1, 0x28, 0x1c, 0x21, 0x1c, 0x3a, 0x1c, 0xff, 0xf7, +0x57, 0xff, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0x00, 0x2f, +0x00, 0xda, 0x3f, 0x30, 0x80, 0x11, 0x00, 0x28, 0x07, 0xdd, 0x86, 0x01, +0x28, 0x1c, 0x21, 0x1c, 0x32, 0x1c, 0xff, 0xf7, 0x47, 0xff, 0xa4, 0x19, +0xbf, 0x1b, 0x00, 0x2f, 0xeb, 0xd0, 0x28, 0x1c, 0x21, 0x1c, 0x3a, 0x1c, +0xff, 0xf7, 0x74, 0xff, 0xe5, 0xe7, 0x98, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, +0x30, 0x20, 0x00, 0xab, 0x18, 0x70, 0xf8, 0x69, 0x00, 0x28, 0x04, 0xd1, +0x69, 0x46, 0x00, 0x22, 0x38, 0x1c, 0xff, 0xf7, 0x65, 0xff, 0x14, 0x21, +0x38, 0x1c, 0xff, 0xf7, 0xe3, 0xfe, 0x00, 0x20, +0x81, 0x00, 0x79, 0x58, 0x02, 0xc4, 0x01, 0x30, 0x05, 0x28, 0xf9, 0xdb, +0x98, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0x98, 0xb0, 0x07, 0x1c, +0x78, 0x68, 0x40, 0x28, 0x10, 0xd9, 0x68, 0x46, 0xff, 0xf7, 0xf9, 0xfe, +0x68, 0x46, 0x06, 0xcf, 0x08, 0x3f, 0xff, 0xf7, 0xa7, 0xff, 0xf8, 0x1d, +0xc5, 0x30, 0x69, 0x46, 0x04, 0x1c, 0xff, 0xf7, 0xd0, 0xff, 0x14, 0x20, +0x78, 0x60, 0x3c, 0x60, 0x00, 0x20, 0x00, 0x24, 0x39, 0x18, 0xca, 0x1d, +0x39, 0x32, 0x14, 0x72, 0x80, 0x31, 0x4c, 0x72, 0x7b, 0x68, 0x83, 0x42, +0x06, 0xd9, 0x3b, 0x68, 0x5d, 0x1c, 0x3d, 0x60, 0x1b, 0x78, 0xc0, 0x46, +0x13, 0x72, 0x4b, 0x72, 0x15, 0x7a, 0x36, 0x23, 0x6b, 0x40, 0x13, 0x72, +0x4a, 0x7a, 0x5c, 0x23, 0x5a, 0x40, 0x4a, 0x72, 0x01, 0x30, 0x40, 0x28, +0xe4, 0xd3, 0x18, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf7, 0xb5, +0xe0, 0xb0, 0x14, 0x1c, 0x0f, 0x1c, 0x00, 0x25, 0xae, 0x00, 0x01, 0x20, +0xf1, 0x1d, 0x1d, 0x31, 0x02, 0xf0, 0x10, 0xfe, 0x01, 0x04, 0x00, 0x91, +0x01, 0x20, 0xf1, 0x1d, 0x1b, 0x31, 0x02, 0xf0, 0x09, 0xfe, 0x00, 0x99, +0x08, 0x43, 0x19, 0xa9, 0x71, 0x18, 0x88, 0x60, 0x01, 0x35, 0x10, 0x2d, +0xea, 0xd3, 0x1b, 0xa8, 0x19, 0x90, 0x40, 0x20, 0x1a, 0x90, 0x19, 0xa8, +0xff, 0xf7, 0xa7, 0xff, 0x01, 0xa8, 0xff, 0xf7, 0xa6, 0xfe, 0x40, 0x22, +0x01, 0xa8, 0x2b, 0xa9, 0xff, 0xf7, 0x54, 0xff, 0x00, 0x2f, 0x0b, 0xd0, +0x40, 0x2f, 0x01, 0xd9, 0x40, 0x25, 0x00, 0xe0, 0x3d, 0x1c, 0x60, 0x99, +0x01, 0xa8, 0x2a, 0x1c, 0xff, 0xf7, 0x48, 0xff, 0x7f, 0x1b, 0xf3, 0xd1, +0x51, 0xa8, 0x01, 0xa9, 0x07, 0x1c, 0xff, 0xf7, 0x70, 0xff, 0x01, 0xa8, +0xff, 0xf7, 0x8b, 0xfe, 0x40, 0x22, 0x01, 0xa8, 0x3b, 0xa9, 0x01, 0x31, +0xff, 0xf7, 0x38, 0xff, 0x14, 0x22, 0x01, 0xa8, 0x39, 0x1c, 0xff, 0xf7, +0x33, 0xff, 0x56, 0xa8, 0x01, 0xa9, 0xff, 0xf7, 0x5e, 0xff, 0x00, 0x20, +0x82, 0x00, 0x19, 0xa9, 0x51, 0x18, 0xc0, 0x31, 0x49, 0x6b, 0x02, 0xc4, +0x01, 0x30, 0x05, 0x28, 0xf6, 0xd3, 0x63, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x90, 0xb5, 0x07, 0x1c, 0x00, 0x24, 0x00, 0x2f, +0x04, 0xd3, 0x04, 0xf0, 0x15, 0xf9, 0x01, 0x34, 0xbc, 0x42, 0xfa, 0xd9, +0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x14, 0x1c, 0x0d, 0x1c, +0x06, 0x1c, 0x1f, 0x1c, 0x1b, 0x4b, 0x32, 0x04, 0x12, 0x0c, 0x3c, 0x21, +0x02, 0x20, 0xfd, 0xf7, 0x8a, 0xff, 0x32, 0x0c, 0x17, 0x4b, 0x3e, 0x21, +0x02, 0x20, 0xfd, 0xf7, 0x84, 0xff, 0x15, 0x4b, 0x2a, 0x04, 0x12, 0x0c, +0x40, 0x21, 0x02, 0x20, 0xfd, 0xf7, 0x7d, 0xff, 0x2a, 0x0c, 0x11, 0x4b, +0x42, 0x21, 0x02, 0x20, 0xfd, 0xf7, 0x77, 0xff, 0x0e, 0x4b, 0x22, 0x04, +0x12, 0x0c, 0x44, 0x21, 0x02, 0x20, 0xfd, 0xf7, 0x70, 0xff, 0x22, 0x0c, +0x0a, 0x4b, 0x46, 0x21, 0x02, 0x20, 0xfd, 0xf7, 0x6a, 0xff, 0x08, 0x4b, +0x3a, 0x04, 0x12, 0x0c, 0x48, 0x21, 0x02, 0x20, 0xfd, 0xf7, 0x63, 0xff, +0x3a, 0x0c, 0x04, 0x4b, 0x4a, 0x21, 0x02, 0x20, 0xfd, 0xf7, 0x5d, 0xff, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xd9, 0xbf, 0x21, 0x40, +0x88, 0xb5, 0x11, 0x27, 0x3f, 0x04, 0x38, 0x62, 0x79, 0x62, 0xba, 0x62, +0xfb, 0x62, 0x04, 0x20, 0xff, 0xf7, 0xaa, 0xff, 0x07, 0x48, 0x40, 0x6b, +0xc0, 0x46, 0x00, 0x90, 0x00, 0x98, 0x80, 0x07, 0x80, 0x0f, 0x03, 0x28, +0x01, 0xd1, 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, +0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x11, 0x40, +0xf0, 0xb5, 0x8a, 0xb0, 0x00, 0x24, 0x05, 0x94, 0x69, 0x49, 0xc9, 0x68, +0xc0, 0x46, 0x00, 0x91, 0x68, 0x4a, 0x11, 0x68, 0x01, 0x22, 0x12, 0x04, +0x0a, 0x40, 0x17, 0x21, 0x66, 0x4e, 0x00, 0x2a, 0x06, 0xd1, 0x64, 0x4a, +0x13, 0x68, 0x1b, 0x0c, 0x04, 0xd1, 0x12, 0x68, 0x92, 0x0a, 0x01, 0xd3, +0xf1, 0x60, 0x02, 0xe0, 0x61, 0x4a, 0xc0, 0x46, 0x11, 0x64, 0x61, 0x49, +0x89, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x03, 0x29, 0x54, 0xd1, 0xe9, 0x21, +0x01, 0x91, 0x02, 0x99, 0xc0, 0x46, 0xb1, 0x60, 0x06, 0x94, 0x06, 0x99, +0x8a, 0x00, 0x5b, 0x49, 0x8a, 0x58, 0x00, 0x2a, 0x73, 0xd0, 0x80, 0x20, +0x02, 0x90, 0x06, 0x98, 0x81, 0x00, 0x57, 0x48, 0x41, 0x58, 0x02, 0x9a, +0x11, 0x43, 0x02, 0x91, 0x00, 0x24, 0x00, 0x27, 0x25, 0x02, 0x28, 0x1c, +0x38, 0x43, 0x09, 0x90, 0x09, 0x98, 0x00, 0x04, 0x51, 0x4b, 0x18, 0x43, +0x04, 0x90, 0x09, 0x98, 0xef, 0x23, 0xdb, 0x05, 0x18, 0x43, 0x03, 0x90, +0x06, 0x98, 0x80, 0x00, 0x4b, 0x49, 0x08, 0x58, 0x00, 0x04, 0x03, 0x99, +0x08, 0x43, 0x03, 0x90, 0x00, 0x2f, 0x02, 0xd1, 0x03, 0x98, 0xc0, 0x46, +0x70, 0x60, 0x01, 0x9b, 0x03, 0x9a, 0x02, 0x99, 0x04, 0x98, 0xff, 0xf7, +0x89, 0xff, 0x00, 0x28, 0x06, 0xd0, 0x02, 0x99, 0xc0, 0x46, 0xb1, 0x60, +0x03, 0x99, 0xc0, 0x46, 0x71, 0x60, 0x5c, 0xe0, 0x79, 0x1c, 0x0f, 0x04, +0x3f, 0x0c, 0x17, 0x2f, 0xd1, 0xdd, 0x61, 0x1c, 0x0c, 0x04, 0x24, 0x0c, +0x16, 0x2c, 0xca, 0xdd, 0x06, 0x99, 0x01, 0x31, 0x06, 0x91, 0x06, 0x99, +0x89, 0x00, 0x37, 0x4a, 0x51, 0x58, 0x00, 0x29, 0xb7, 0xd1, 0x48, 0xe0, +0xbf, 0x21, 0xc9, 0x43, 0x04, 0x91, 0xff, 0x21, 0x02, 0x91, 0x97, 0x21, +0x01, 0x91, 0x06, 0x94, 0x06, 0x99, 0x89, 0x00, 0x31, 0x4f, 0x79, 0x58, +0x00, 0x29, 0x1c, 0xd0, 0x09, 0x94, 0x08, 0x94, 0x06, 0x98, 0x80, 0x00, +0x38, 0x58, 0xc0, 0x46, 0x07, 0x90, 0x07, 0x98, 0x00, 0x04, 0x26, 0xe0, +0x05, 0x98, 0x15, 0x23, 0x1b, 0x06, 0x18, 0x43, 0x03, 0x90, 0x01, 0x9b, +0x03, 0x9a, 0x02, 0x99, 0x04, 0x98, 0xff, 0xf7, 0x49, 0xff, 0x00, 0x28, +0x23, 0xd1, 0x09, 0x99, 0x01, 0x31, 0x09, 0x91, 0x17, 0x29, 0x06, 0xd8, +0x00, 0xe0, 0x1c, 0xe0, 0x08, 0x98, 0x00, 0x02, 0x09, 0x99, 0x08, 0x43, +0x07, 0xe0, 0x08, 0x99, 0x01, 0x31, 0x08, 0x91, 0x17, 0x29, 0x0a, 0xd8, +0x09, 0x94, 0x08, 0x98, 0x00, 0x02, 0x07, 0x99, 0x09, 0x04, 0x08, 0x43, +0x15, 0x23, 0x1b, 0x06, 0x18, 0x43, 0x05, 0x90, 0xd6, 0xe7, 0x06, 0x99, +0x01, 0x31, 0x06, 0x91, 0x06, 0x99, 0x89, 0x00, 0x79, 0x58, 0x00, 0x29, +0xc4, 0xd1, 0x0c, 0x4a, 0x11, 0x68, 0x49, 0x0c, 0x05, 0xd2, 0x11, 0x68, +0x09, 0x0c, 0x06, 0xd1, 0x11, 0x68, 0x89, 0x0a, 0x03, 0xd3, 0x00, 0x99, +0xc0, 0x46, 0xf1, 0x60, 0x03, 0xe0, 0x00, 0x99, 0x06, 0x4a, 0xc0, 0x46, +0x11, 0x64, 0x0a, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x40, 0x01, 0x18, 0x40, 0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, +0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x18, 0x40, 0x30, 0x6e, 0x21, 0x40, +0x43, 0xff, 0x00, 0x00, 0x0c, 0x6e, 0x21, 0x40, 0x80, 0xb5, 0x82, 0xb0, +0x00, 0x20, 0x01, 0x90, 0x1e, 0x48, 0xc1, 0x68, 0x01, 0x29, 0x1b, 0xd1, +0x40, 0x88, 0x00, 0x28, 0x18, 0xd1, 0x68, 0x46, 0x01, 0xf0, 0x9a, 0xfe, +0x00, 0x28, 0x13, 0xd1, 0xa8, 0x20, 0x01, 0xf0, +0xdb, 0xfe, 0x18, 0x4f, 0x00, 0x28, 0x11, 0xd0, 0x04, 0x20, 0xff, 0xf7, +0x97, 0xfe, 0x78, 0x6b, 0xc0, 0x46, 0x01, 0x90, 0x01, 0x98, 0x80, 0x07, +0x80, 0x0f, 0x03, 0x28, 0x06, 0xd1, 0x00, 0x20, 0x01, 0xf0, 0xca, 0xfe, +0x02, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x23, 0x00, 0x22, +0x00, 0x21, 0x00, 0x20, 0xff, 0xf7, 0x8f, 0xfe, 0x00, 0x23, 0xdb, 0x43, +0x18, 0x1c, 0x19, 0x1c, 0x1a, 0x1c, 0xff, 0xf7, 0xc7, 0xfe, 0x00, 0x28, +0x03, 0xd1, 0xff, 0xf7, 0xdf, 0xfe, 0x00, 0x28, 0xe5, 0xd0, 0x38, 0x6a, +0x79, 0x6a, 0xba, 0x6a, 0xfb, 0x6a, 0xff, 0xf7, 0x7c, 0xfe, 0xde, 0xe7, +0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x11, 0x40, 0xff, 0xb5, 0x85, 0xb0, +0x14, 0x1c, 0x1f, 0x1c, 0x00, 0x20, 0x01, 0x90, 0x01, 0x23, 0x5b, 0x04, +0x9f, 0x42, 0x01, 0xd9, 0x0f, 0x20, 0x82, 0xe0, 0x26, 0x1c, 0x43, 0x4d, +0xaf, 0x42, 0x00, 0xd2, 0x3d, 0x1c, 0x21, 0x0d, 0x09, 0x05, 0x41, 0x48, +0x41, 0x4b, 0x99, 0x42, 0x04, 0xd0, 0x80, 0x25, 0x06, 0x1c, 0x80, 0x2f, +0x00, 0xd8, 0x3d, 0x1c, 0x3e, 0x4a, 0x51, 0x69, 0xc0, 0x46, 0x03, 0x91, +0x92, 0x69, 0xc0, 0x46, 0x02, 0x92, 0xff, 0x23, 0x01, 0x33, 0x19, 0x43, +0x39, 0x4b, 0xc0, 0x46, 0x59, 0x61, 0xff, 0x23, 0x01, 0x33, 0x9a, 0x43, +0x36, 0x4b, 0xc0, 0x46, 0x9a, 0x61, 0x01, 0x22, 0x12, 0x05, 0xd1, 0x60, +0x33, 0x4a, 0x91, 0x69, 0x01, 0x22, 0x12, 0x05, 0x11, 0x61, 0x31, 0x4a, +0xff, 0x23, 0x01, 0x33, 0x91, 0x69, 0x19, 0x43, 0x91, 0x61, 0x01, 0x22, +0x12, 0x05, 0x11, 0x61, 0x85, 0x21, 0x89, 0x04, 0x04, 0x91, 0x00, 0x2f, +0x34, 0xd0, 0x28, 0x48, 0x86, 0x42, 0x04, 0xd1, 0x30, 0x1c, 0x21, 0x1c, +0x2a, 0x1c, 0x03, 0xf0, 0x4f, 0xff, 0x2a, 0x1c, 0x04, 0x98, 0x02, 0x43, +0x00, 0x92, 0x01, 0x20, 0x06, 0x99, 0x05, 0x9a, 0x33, 0x1c, 0xfd, 0xf7, +0xbd, 0xfd, 0x22, 0x48, 0x22, 0x49, 0x4a, 0x68, 0x52, 0x0a, 0x09, 0xd3, +0xff, 0x21, 0x01, 0x31, 0x20, 0x4a, 0xc0, 0x46, 0x11, 0x60, 0x00, 0x28, +0x05, 0xd1, 0x11, 0x20, 0x01, 0x90, 0x13, 0xe0, 0x01, 0x38, 0xf0, 0xd1, +0xf9, 0xe7, 0x7f, 0x1b, 0x0e, 0xd0, 0x15, 0x48, 0x86, 0x42, 0x01, 0xd1, +0x64, 0x19, 0x00, 0xe0, 0x76, 0x19, 0x06, 0x99, 0x49, 0x19, 0x06, 0x91, +0x38, 0x1c, 0xaf, 0x42, 0x00, 0xd3, 0x28, 0x1c, 0x05, 0x1c, 0xca, 0xe7, +0x0f, 0x48, 0x41, 0x69, 0x03, 0x9b, 0x19, 0x43, 0x41, 0x61, 0x82, 0x69, +0x03, 0x9b, 0x9a, 0x43, 0x82, 0x61, 0x01, 0x22, 0x12, 0x05, 0xd1, 0x60, +0x81, 0x69, 0xc0, 0x46, 0x11, 0x61, 0x81, 0x69, 0x02, 0x9b, 0x19, 0x43, +0x81, 0x61, 0x11, 0x61, 0x01, 0x98, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x50, 0xab, 0x20, 0x40, +0x00, 0x00, 0x20, 0x40, 0x68, 0x0e, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, +0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x00, 0xb0, 0xff, 0xb5, 0x85, 0xb0, +0x04, 0x1c, 0x1f, 0x1c, 0x00, 0x20, 0x01, 0x90, 0x01, 0x23, 0x5b, 0x04, +0x9f, 0x42, 0x01, 0xd9, 0x0f, 0x20, 0x7d, 0xe0, 0x26, 0x1c, 0x40, 0x4d, +0xaf, 0x42, 0x00, 0xd2, 0x3d, 0x1c, 0x21, 0x0d, 0x09, 0x05, 0x3e, 0x48, +0x3e, 0x4b, 0x99, 0x42, 0x04, 0xd0, 0x80, 0x25, 0x06, 0x1c, 0x80, 0x2f, +0x00, 0xd8, 0x3d, 0x1c, 0x3b, 0x4a, 0x51, 0x69, 0xc0, 0x46, 0x03, 0x91, +0x92, 0x69, 0xc0, 0x46, 0x02, 0x92, 0x10, 0x23, 0x19, 0x43, 0x37, 0x4b, +0xc0, 0x46, 0x59, 0x61, 0x10, 0x23, 0x9a, 0x43, +0x34, 0x4b, 0xc0, 0x46, 0x9a, 0x61, 0x01, 0x22, 0x12, 0x05, 0xd1, 0x60, +0x31, 0x4a, 0x91, 0x69, 0x01, 0x22, 0x12, 0x05, 0x11, 0x61, 0x2f, 0x4a, +0x10, 0x23, 0x91, 0x69, 0x19, 0x43, 0x91, 0x61, 0x1a, 0x04, 0x11, 0x61, +0x21, 0x21, 0x09, 0x05, 0x04, 0x91, 0x00, 0x2f, 0x33, 0xd0, 0x2a, 0x1c, +0x04, 0x98, 0x02, 0x43, 0x00, 0x92, 0x00, 0x20, 0x06, 0x99, 0x07, 0x9a, +0x33, 0x1c, 0xfd, 0xf7, 0x27, 0xfd, 0x25, 0x48, 0x25, 0x49, 0x4a, 0x68, +0x52, 0x09, 0x08, 0xd3, 0x10, 0x21, 0x24, 0x4a, 0xc0, 0x46, 0x11, 0x60, +0x00, 0x28, 0x05, 0xd1, 0x11, 0x20, 0x01, 0x90, 0x1b, 0xe0, 0x01, 0x38, +0xf1, 0xd1, 0xf9, 0xe7, 0x19, 0x48, 0x86, 0x42, 0x04, 0xd1, 0x20, 0x1c, +0x31, 0x1c, 0x2a, 0x1c, 0x03, 0xf0, 0x96, 0xfe, 0x7f, 0x1b, 0x0e, 0xd0, +0x14, 0x48, 0x86, 0x42, 0x01, 0xd0, 0x76, 0x19, 0x00, 0xe0, 0x64, 0x19, +0x06, 0x99, 0x49, 0x19, 0x06, 0x91, 0x38, 0x1c, 0xaf, 0x42, 0x00, 0xd3, +0x28, 0x1c, 0x05, 0x1c, 0xcb, 0xe7, 0x0f, 0x48, 0x41, 0x69, 0x03, 0x9b, +0x19, 0x43, 0x41, 0x61, 0x82, 0x69, 0x03, 0x9b, 0x9a, 0x43, 0x82, 0x61, +0x01, 0x22, 0x12, 0x05, 0xd1, 0x60, 0x81, 0x69, 0xc0, 0x46, 0x11, 0x61, +0x81, 0x69, 0x02, 0x9b, 0x19, 0x43, 0x81, 0x61, 0x11, 0x61, 0x01, 0x98, +0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xff, 0x00, 0x00, +0x50, 0xab, 0x20, 0x40, 0x00, 0x00, 0x20, 0x40, 0x68, 0x0e, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x00, 0xb0, -0xff, 0xb5, 0x85, 0xb0, 0x04, 0x1c, 0x1f, 0x1c, 0x00, 0x20, 0x01, 0x90, -0x01, 0x23, 0x5b, 0x04, 0x9f, 0x42, 0x01, 0xd9, -0x0f, 0x20, 0x7d, 0xe0, 0x26, 0x1c, 0x40, 0x4d, 0xaf, 0x42, 0x00, 0xd2, -0x3d, 0x1c, 0x21, 0x0d, 0x09, 0x05, 0x3e, 0x48, 0x3e, 0x4b, 0x99, 0x42, -0x04, 0xd0, 0x80, 0x25, 0x06, 0x1c, 0x80, 0x2f, 0x00, 0xd8, 0x3d, 0x1c, -0x3b, 0x4a, 0x51, 0x69, 0xc0, 0x46, 0x03, 0x91, 0x92, 0x69, 0xc0, 0x46, -0x02, 0x92, 0x10, 0x23, 0x19, 0x43, 0x37, 0x4b, 0xc0, 0x46, 0x59, 0x61, -0x10, 0x23, 0x9a, 0x43, 0x34, 0x4b, 0xc0, 0x46, 0x9a, 0x61, 0x01, 0x22, -0x12, 0x05, 0xd1, 0x60, 0x31, 0x4a, 0x91, 0x69, 0x01, 0x22, 0x12, 0x05, -0x11, 0x61, 0x2f, 0x4a, 0x10, 0x23, 0x91, 0x69, 0x19, 0x43, 0x91, 0x61, -0x1a, 0x04, 0x11, 0x61, 0x21, 0x21, 0x09, 0x05, 0x04, 0x91, 0x00, 0x2f, -0x33, 0xd0, 0x2a, 0x1c, 0x04, 0x98, 0x02, 0x43, 0x00, 0x92, 0x00, 0x20, -0x06, 0x99, 0x07, 0x9a, 0x33, 0x1c, 0xfe, 0xf7, 0xc7, 0xf8, 0x25, 0x48, -0x25, 0x49, 0x4a, 0x68, 0x52, 0x09, 0x08, 0xd3, 0x10, 0x21, 0x24, 0x4a, -0xc0, 0x46, 0x11, 0x60, 0x00, 0x28, 0x05, 0xd1, 0x11, 0x20, 0x01, 0x90, -0x1b, 0xe0, 0x01, 0x38, 0xf1, 0xd1, 0xf9, 0xe7, 0x19, 0x48, 0x86, 0x42, -0x04, 0xd1, 0x20, 0x1c, 0x31, 0x1c, 0x2a, 0x1c, 0x03, 0xf0, 0x1c, 0xfe, -0x7f, 0x1b, 0x0e, 0xd0, 0x14, 0x48, 0x86, 0x42, 0x01, 0xd0, 0x76, 0x19, -0x00, 0xe0, 0x64, 0x19, 0x06, 0x99, 0x49, 0x19, 0x06, 0x91, 0x38, 0x1c, -0xaf, 0x42, 0x00, 0xd3, 0x28, 0x1c, 0x05, 0x1c, 0xcb, 0xe7, 0x0f, 0x48, -0x41, 0x69, 0x03, 0x9b, 0x19, 0x43, 0x41, 0x61, 0x82, 0x69, 0x03, 0x9b, -0x9a, 0x43, 0x82, 0x61, 0x01, 0x22, 0x12, 0x05, 0xd1, 0x60, 0x81, 0x69, -0xc0, 0x46, 0x11, 0x61, 0x81, 0x69, 0x02, 0x9b, 0x19, 0x43, 0x81, 0x61, -0x11, 0x61, 0x01, 0x98, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0xf0, 0xff, 0x00, 0x00, 0x50, 0xab, 0x20, 0x40, 0x00, 0x00, 0x20, 0x40, -0xe8, 0x0d, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, -0x00, 0x00, 0x00, 0xb0, 0x70, 0x47, 0x04, 0x49, 0x00, 0x20, 0x00, 0x22, -0x0a, 0x70, 0x01, 0x30, 0x01, 0x31, 0x68, 0x28, 0xfa, 0xd3, 0x70, 0x47, -0xa0, 0x82, 0x20, 0x40, 0x00, 0x22, 0x88, 0x42, 0x03, 0xd3, 0x40, 0x1a, -0x01, 0x32, 0x88, 0x42, 0xfb, 0xd2, 0x10, 0x1c, 0x70, 0x47, 0x88, 0x42, -0x02, 0xd3, 0x40, 0x1a, 0x88, 0x42, 0xfc, 0xd2, 0x70, 0x47, 0x90, 0xb4, -0x01, 0x1c, 0xff, 0x27, 0x04, 0x29, 0x27, 0xda, 0x00, 0x20, 0x14, 0x4a, -0x43, 0x00, 0x1b, 0x18, 0xdb, 0x00, 0xd4, 0x58, 0x63, 0x0c, 0x1a, 0xd2, -0x4b, 0x00, 0x59, 0x18, 0xc9, 0x00, 0x57, 0x58, 0x43, 0x00, 0x1b, 0x18, -0xdb, 0x00, 0xd7, 0x50, 0x89, 0x18, 0x9a, 0x18, 0x4f, 0x68, 0xc0, 0x46, -0x57, 0x60, 0x8b, 0x68, 0xc0, 0x46, 0x93, 0x60, 0x0b, 0x69, 0xc0, 0x46, -0x13, 0x61, 0x4b, 0x69, 0xc0, 0x46, 0x53, 0x61, 0xc9, 0x68, 0xc0, 0x46, -0xd1, 0x60, 0x90, 0xbc, 0x70, 0x47, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, -0x04, 0x28, 0xd9, 0xdb, 0x38, 0x1c, 0xf6, 0xe7, 0xd0, 0xab, 0x20, 0x40, -0xf7, 0xb5, 0xc5, 0xb0, 0x14, 0x1c, 0x00, 0x20, 0x11, 0x21, 0x21, 0x40, -0x5f, 0xd0, 0x00, 0x27, 0x79, 0x00, 0xc9, 0x19, 0xc9, 0x00, 0x5b, 0x4a, -0x51, 0x58, 0x49, 0x0c, 0x03, 0xd2, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, -0x04, 0xe0, 0x79, 0x1c, 0x0f, 0x06, 0x3f, 0x0e, 0x04, 0x2f, 0xef, 0xdb, -0x00, 0x28, 0x4c, 0xd0, 0x00, 0x22, 0x01, 0x92, 0x00, 0x92, 0x40, 0x23, -0x00, 0x21, 0x00, 0x20, 0x03, 0xaa, 0x00, 0xf0, -0x8f, 0xfa, 0x05, 0xa9, 0x00, 0x20, 0x82, 0x00, 0x8a, 0x58, 0x12, 0x06, -0x12, 0x0e, 0x45, 0x9b, 0x9a, 0x42, 0x05, 0xd1, 0x01, 0x9a, 0x01, 0x32, -0x12, 0x06, 0x12, 0x0e, 0x01, 0x92, 0x04, 0xe0, 0x01, 0x30, 0x00, 0x06, -0x00, 0x0e, 0x10, 0x28, 0xed, 0xdb, 0x01, 0x9a, 0x00, 0x2a, 0x4f, 0xd0, -0x45, 0x9b, 0x04, 0x2b, 0x3e, 0xd1, 0x80, 0x00, 0x08, 0x58, 0x40, 0x01, -0x80, 0x0d, 0x00, 0x22, 0x00, 0x92, 0x10, 0x23, 0x00, 0x21, 0x03, 0xaa, -0x00, 0xf0, 0x6a, 0xfa, 0x00, 0x21, 0x01, 0x91, 0x03, 0xa8, 0x06, 0x99, -0x49, 0x0c, 0x89, 0x05, 0x2a, 0xd0, 0xc1, 0x68, 0x0a, 0x06, 0x12, 0x0e, -0x46, 0x9b, 0x9a, 0x42, 0x12, 0xd1, 0xc0, 0x68, 0x40, 0x01, 0x86, 0x0d, -0x00, 0x22, 0x00, 0x92, 0x0c, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x03, 0xaa, -0x00, 0xf0, 0x52, 0xfa, 0x01, 0x99, 0x03, 0x9d, 0x48, 0x1c, 0x01, 0x06, -0x09, 0x0e, 0x01, 0x91, 0x0f, 0xe0, 0x57, 0xe0, 0x48, 0x01, 0x86, 0x0d, -0x00, 0x22, 0x00, 0x92, 0x10, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x03, 0xaa, -0x00, 0xf0, 0x40, 0xfa, 0x03, 0xa8, 0x06, 0x99, 0x49, 0x0c, 0x89, 0x05, -0xd7, 0xd1, 0x01, 0x99, 0x00, 0x29, 0x11, 0xd1, 0xff, 0x20, 0x3f, 0xe0, +0x70, 0x47, 0x04, 0x49, 0x00, 0x20, 0x00, 0x22, 0x0a, 0x70, 0x01, 0x30, +0x01, 0x31, 0x68, 0x28, 0xfa, 0xd3, 0x70, 0x47, 0xa0, 0x82, 0x20, 0x40, +0x00, 0x22, 0x88, 0x42, 0x03, 0xd3, 0x40, 0x1a, 0x01, 0x32, 0x88, 0x42, +0xfb, 0xd2, 0x10, 0x1c, 0x70, 0x47, 0x88, 0x42, 0x02, 0xd3, 0x40, 0x1a, +0x88, 0x42, 0xfc, 0xd2, 0x70, 0x47, 0x90, 0xb4, 0x01, 0x1c, 0xff, 0x27, +0x04, 0x29, 0x27, 0xda, 0x00, 0x20, 0x14, 0x4a, 0x43, 0x00, 0x1b, 0x18, +0xdb, 0x00, 0xd4, 0x58, 0x63, 0x0c, 0x1a, 0xd2, 0x4b, 0x00, 0x59, 0x18, +0xc9, 0x00, 0x57, 0x58, 0x43, 0x00, 0x1b, 0x18, 0xdb, 0x00, 0xd7, 0x50, +0x89, 0x18, 0x9a, 0x18, 0x4f, 0x68, 0xc0, 0x46, 0x57, 0x60, 0x8b, 0x68, +0xc0, 0x46, 0x93, 0x60, 0x0b, 0x69, 0xc0, 0x46, 0x13, 0x61, 0x4b, 0x69, +0xc0, 0x46, 0x53, 0x61, 0xc9, 0x68, 0xc0, 0x46, 0xd1, 0x60, 0x90, 0xbc, +0x70, 0x47, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x04, 0x28, 0xd9, 0xdb, +0x38, 0x1c, 0xf6, 0xe7, 0xd0, 0xab, 0x20, 0x40, 0xf7, 0xb5, 0xc4, 0xb0, +0x04, 0x1c, 0x00, 0x20, 0x46, 0x9a, 0x11, 0x21, 0x11, 0x40, 0x6e, 0xd0, +0x00, 0x27, 0x79, 0x00, 0xc9, 0x19, 0xc9, 0x00, 0x57, 0x4a, 0x51, 0x58, +0x49, 0x0c, 0x03, 0xd2, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x04, 0xe0, +0x79, 0x1c, 0x0f, 0x06, 0x3f, 0x0e, 0x04, 0x2f, 0xef, 0xdb, 0x00, 0x28, +0x5b, 0xd0, 0x00, 0x26, 0x00, 0x22, 0x00, 0x92, 0x40, 0x23, 0x00, 0x21, +0x00, 0x20, 0x02, 0xaa, 0x00, 0xf0, 0x88, 0xfa, 0x04, 0xa9, 0x00, 0x20, +0x82, 0x00, 0x8a, 0x58, 0x12, 0x06, 0x12, 0x0e, 0xa2, 0x42, 0x03, 0xd1, +0x72, 0x1c, 0x16, 0x06, 0x36, 0x0e, 0x04, 0xe0, 0x01, 0x30, 0x00, 0x06, +0x00, 0x0e, 0x10, 0x28, 0xf0, 0xdb, 0x00, 0x2e, 0x3d, 0xd0, 0x04, 0x2c, +0x3e, 0xd1, 0x80, 0x00, 0x08, 0x58, 0x40, 0x01, 0x80, 0x0d, 0x00, 0x22, +0x00, 0x92, 0x10, 0x23, 0x00, 0x21, 0x02, 0xaa, +0x00, 0xf0, 0x68, 0xfa, 0x00, 0x21, 0x01, 0x91, 0x02, 0xa8, 0x05, 0x99, +0x49, 0x0c, 0x89, 0x05, 0x29, 0xd0, 0xc1, 0x68, 0x0a, 0x06, 0x12, 0x0e, +0x45, 0x9b, 0x9a, 0x42, 0x11, 0xd1, 0xc0, 0x68, 0x40, 0x01, 0x86, 0x0d, +0x00, 0x22, 0x00, 0x92, 0x0c, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x02, 0xaa, +0x00, 0xf0, 0x50, 0xfa, 0x01, 0x99, 0x02, 0x9d, 0x48, 0x1c, 0x01, 0x06, +0x09, 0x0e, 0x01, 0x91, 0x0e, 0xe0, 0x48, 0x01, 0x86, 0x0d, 0x00, 0x22, +0x00, 0x92, 0x10, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x02, 0xaa, 0x00, 0xf0, +0x3f, 0xfa, 0x02, 0xa8, 0x05, 0x99, 0x49, 0x0c, 0x89, 0x05, 0xd8, 0xd1, +0x01, 0x99, 0x00, 0x29, 0x0f, 0xd1, 0xff, 0x20, 0x3d, 0xe0, 0x40, 0xe0, 0x80, 0x00, 0x08, 0x58, 0x40, 0x01, 0x86, 0x0d, 0x00, 0x22, 0x00, 0x92, -0x0c, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x03, 0xaa, 0x00, 0xf0, 0x2a, 0xfa, -0x03, 0x9d, 0x01, 0xe0, 0x20, 0x0a, 0xed, 0xd2, 0x01, 0x20, 0x00, 0x04, -0x20, 0x43, 0x79, 0x00, 0xc9, 0x19, 0xc9, 0x00, 0x17, 0x4a, 0xc0, 0x46, -0x50, 0x50, 0x30, 0x1c, 0x8e, 0x18, 0x70, 0x60, 0x10, 0x20, 0x45, 0x9b, -0x04, 0x2b, 0x00, 0xd0, 0x0c, 0x20, 0x02, 0x90, 0xb0, 0x60, 0x00, 0x20, -0x20, 0x21, 0x21, 0x40, 0x20, 0x29, 0x00, 0xd0, 0x28, 0x1c, 0x30, 0x61, -0x02, 0x98, 0x28, 0x18, 0xff, 0x21, 0xff, 0x30, 0x08, 0x30, 0x09, 0x31, -0xff, 0xf7, 0x12, 0xff, 0x43, 0x01, 0x18, 0x18, 0xc0, 0x00, 0x02, 0x99, -0x40, 0x1a, 0x70, 0x61, 0x00, 0x20, 0x50, 0x21, 0x21, 0x40, 0x50, 0x29, -0x00, 0xd1, 0x28, 0x1c, 0xf0, 0x60, 0x38, 0x1c, 0x48, 0xb0, 0xf0, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0xff, 0x20, 0xf9, 0xe7, 0xd0, 0xab, 0x20, 0x40, -0x80, 0xb4, 0x00, 0x23, 0x00, 0x22, 0x00, 0x29, 0x06, 0xd9, 0x87, 0x5c, -0x7b, 0x40, 0x1b, 0x06, 0x1b, 0x0e, 0x01, 0x32, 0x8a, 0x42, 0xf8, 0xd3, -0xd8, 0x43, 0x00, 0x06, 0x00, 0x0e, 0x80, 0xbc, 0x70, 0x47, 0xf0, 0xb5, -0xc6, 0xb0, 0x04, 0x28, 0x07, 0xda, 0x41, 0x00, 0x09, 0x18, 0xc9, 0x00, -0x45, 0x91, 0x41, 0x4a, 0x51, 0x58, 0x4b, 0x0c, 0x02, 0xd2, 0x00, 0x20, -0xc0, 0x43, 0x76, 0xe0, 0x01, 0x23, 0x5b, 0x04, 0x19, 0x40, 0x43, 0x00, -0x18, 0x18, 0xc0, 0x00, 0x3a, 0x4a, 0x14, 0x18, 0x00, 0x29, 0x61, 0xd0, -0x00, 0x21, 0x02, 0x91, 0x20, 0x69, 0xa1, 0x68, 0x45, 0x18, 0x30, 0xd0, -0xff, 0x21, 0x68, 0x1e, 0x09, 0x31, 0xff, 0xf7, 0xc7, 0xfe, 0x61, 0x68, -0x40, 0x18, 0x01, 0x90, 0x01, 0x98, 0x81, 0x42, 0x02, 0xd1, 0xa6, 0x68, -0xaf, 0x1b, 0x09, 0xe0, 0x00, 0x26, 0xff, 0x21, 0x28, 0x1c, 0x09, 0x31, -0xff, 0xf7, 0xc1, 0xfe, 0x07, 0x1c, 0x01, 0xd1, 0xff, 0x27, 0x09, 0x37, -0x00, 0x22, 0x00, 0x92, 0x01, 0x98, 0x31, 0x1c, 0x03, 0xaa, 0x3b, 0x1c, -0x00, 0xf0, 0x9e, 0xf9, 0x03, 0xa8, 0x39, 0x1c, 0xff, 0xf7, 0xac, 0xff, -0xc0, 0x43, 0x02, 0x99, 0x48, 0x40, 0x01, 0x06, 0x09, 0x0e, 0x02, 0x91, -0xed, 0x1b, 0xa0, 0x68, 0xa8, 0x42, 0x00, 0xd1, -0x00, 0x25, 0x00, 0x2d, 0xce, 0xd8, 0x02, 0x99, 0xcf, 0x43, 0x00, 0x22, -0x00, 0x92, 0x0c, 0x23, 0x00, 0x21, 0x60, 0x68, 0x03, 0xaa, 0x00, 0xf0, -0x83, 0xf9, 0x20, 0x69, 0xc0, 0x46, 0x03, 0x90, 0x05, 0x98, 0x00, 0x0a, -0x00, 0x02, 0x39, 0x06, 0x09, 0x0e, 0x08, 0x43, 0x05, 0x90, 0xff, 0x23, -0x1b, 0x02, 0x98, 0x43, 0x05, 0x90, 0x0c, 0x21, 0x03, 0xa8, 0xff, 0xf7, -0x83, 0xff, 0xff, 0x23, 0x1b, 0x02, 0x05, 0x99, 0x99, 0x43, 0x00, 0x06, -0x00, 0x0e, 0x00, 0x02, 0x08, 0x43, 0x05, 0x90, 0x0c, 0x23, 0x00, 0x21, -0x60, 0x68, 0x03, 0xaa, 0x00, 0xf0, 0xbb, 0xf9, 0x00, 0x20, 0x45, 0x99, -0x06, 0x4a, 0xc0, 0x46, 0x50, 0x50, 0xc1, 0x43, 0x61, 0x60, 0xa1, 0x60, -0xe1, 0x60, 0x21, 0x61, 0x61, 0x61, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0xd0, 0xab, 0x20, 0x40, 0xb0, 0xb4, 0x4c, 0x42, -0x00, 0x29, 0x00, 0xdb, 0x0c, 0x1c, 0x00, 0x27, 0xff, 0x43, 0x04, 0x28, -0x21, 0xda, 0x12, 0x4d, 0x43, 0x00, 0x18, 0x18, 0xc0, 0x00, 0x40, 0x19, -0x01, 0x2a, 0x05, 0xd0, 0x02, 0x2a, 0x09, 0xd0, 0x03, 0x2a, 0x16, 0xd1, -0x01, 0x69, 0x0b, 0xe0, 0x00, 0x29, 0x12, 0xdb, 0x02, 0x69, 0x8a, 0x42, -0x0f, 0xd3, 0x05, 0xe0, 0x00, 0x29, 0x07, 0xda, 0xc1, 0x68, 0xa1, 0x42, -0x09, 0xd3, 0x09, 0x1b, 0xc1, 0x60, 0xc0, 0x68, 0xb0, 0xbc, 0x70, 0x47, -0xc1, 0x68, 0x09, 0x19, 0x02, 0x69, 0x91, 0x42, 0xf6, 0xd9, 0x38, 0x1c, -0xf6, 0xe7, 0x00, 0x00, 0xd0, 0xab, 0x20, 0x40, 0xf0, 0xb5, 0x84, 0xb0, -0x17, 0x1c, 0x0d, 0x1c, 0x00, 0x21, 0x02, 0x91, 0x42, 0x00, 0x12, 0x18, -0xd2, 0x00, 0x2c, 0x49, 0x8b, 0x58, 0x1b, 0x06, 0x1b, 0x0e, 0x01, 0x93, -0x00, 0x23, 0xdb, 0x43, 0x04, 0x28, 0x02, 0xda, 0x01, 0x98, 0x40, 0x08, -0x01, 0xd2, 0x18, 0x1c, 0x46, 0xe0, 0x54, 0x18, 0xe0, 0x68, 0xc2, 0x19, -0x21, 0x69, 0x8a, 0x42, 0x00, 0xd9, 0x0f, 0x1a, 0x00, 0x2f, 0x3c, 0xd9, -0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, -0x07, 0xfe, 0x61, 0x68, 0x46, 0x18, 0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, -0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, 0x07, 0xfe, 0xc2, 0x19, 0xff, 0x21, -0x09, 0x31, 0x8a, 0x42, 0x14, 0xd9, 0x01, 0x9a, 0xc0, 0x46, 0x00, 0x92, -0x0b, 0x1a, 0x03, 0x93, 0x01, 0x1c, 0x30, 0x1c, 0x2a, 0x1c, 0x00, 0xf0, -0xe1, 0xf8, 0xe0, 0x68, 0x03, 0x9b, 0xc0, 0x18, 0xe0, 0x60, 0x03, 0x9b, -0x5d, 0x19, 0xff, 0x1a, 0x02, 0x98, 0x18, 0x18, 0x02, 0x90, 0x10, 0xe0, -0x01, 0x9a, 0xc0, 0x46, 0x00, 0x92, 0x01, 0x1c, 0x30, 0x1c, 0x2a, 0x1c, -0x3b, 0x1c, 0x00, 0xf0, 0xcd, 0xf8, 0xe0, 0x68, 0xc0, 0x19, 0xed, 0x19, -0xe0, 0x60, 0x02, 0x98, 0xc0, 0x19, 0x02, 0x90, 0x00, 0x27, 0x00, 0x2f, -0xc2, 0xd8, 0x02, 0x98, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0xd0, 0xab, 0x20, 0x40, 0xf0, 0xb5, 0x83, 0xb0, 0x17, 0x1c, 0x0d, 0x1c, -0x00, 0x21, 0x01, 0x91, 0x42, 0x00, 0x12, 0x18, 0xd2, 0x00, 0x02, 0x92, -0x30, 0x49, 0x8a, 0x58, 0x12, 0x06, 0x12, 0x0e, 0x00, 0x24, 0xe4, 0x43, -0x04, 0x28, 0x01, 0xda, 0x50, 0x09, 0x01, 0xd2, 0x20, 0x1c, 0x51, 0xe0, -0x02, 0x9a, 0x54, 0x18, 0xe0, 0x68, 0xc2, 0x19, 0x60, 0x69, 0x82, 0x42, -0x01, 0xd9, 0x22, 0x69, 0x87, 0x1a, 0x00, 0x2f, 0x45, 0xd9, 0x25, 0x4e, -0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, -0xa1, 0xfd, 0x61, 0x68, 0x40, 0x18, 0x00, 0x90, -0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, -0xa0, 0xfd, 0x02, 0x9a, 0xb1, 0x58, 0x01, 0x23, 0x5b, 0x04, 0x19, 0x43, -0xb1, 0x50, 0xc1, 0x19, 0xff, 0x22, 0x09, 0x32, 0x91, 0x42, 0x13, 0xd9, -0x13, 0x1a, 0x01, 0x1c, 0x00, 0x98, 0x2a, 0x1c, 0x1e, 0x1c, 0x00, 0xf0, -0xd0, 0xf8, 0xe0, 0x68, 0x80, 0x19, 0x75, 0x19, 0xe0, 0x60, 0x21, 0x69, -0x88, 0x42, 0x00, 0xd9, 0x20, 0x61, 0xbf, 0x1b, 0x01, 0x98, 0x30, 0x18, -0x01, 0x90, 0x12, 0xe0, 0x01, 0x1c, 0x00, 0x9e, 0x30, 0x1c, 0x2a, 0x1c, -0x3b, 0x1c, 0x00, 0xf0, 0xbc, 0xf8, 0xe0, 0x68, 0xc0, 0x19, 0xed, 0x19, -0xe0, 0x60, 0x21, 0x69, 0x88, 0x42, 0x00, 0xd9, 0x20, 0x61, 0x01, 0x98, -0xc0, 0x19, 0x01, 0x90, 0x00, 0x27, 0x00, 0x2f, 0xb9, 0xd8, 0x01, 0x98, -0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xd0, 0xab, 0x20, 0x40, -0xb0, 0xb5, 0xc3, 0xb0, 0x0c, 0x1c, 0x00, 0x27, 0xfa, 0x43, 0x04, 0x28, -0x06, 0xda, 0x41, 0x00, 0x09, 0x18, 0xc9, 0x00, 0x14, 0x48, 0x45, 0x58, -0x6b, 0x0c, 0x04, 0xd2, 0x10, 0x1c, 0x43, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x62, 0x09, 0x1b, 0xd3, 0x00, 0x22, 0x00, 0x92, 0x08, 0x18, -0x40, 0x68, 0x0c, 0x23, 0x00, 0x21, 0x01, 0xaa, 0x00, 0xf0, 0x30, 0xf8, -0x11, 0x2c, 0x0d, 0xd0, 0x12, 0x2c, 0x0d, 0xd0, 0x13, 0x2c, 0x05, 0xd0, -0x14, 0x2c, 0x0a, 0xd1, 0x03, 0x98, 0x00, 0x04, 0x07, 0x0e, 0x06, 0xe0, -0x03, 0x98, 0x07, 0x06, 0x3f, 0x0e, 0x02, 0xe0, 0x01, 0x9f, 0x00, 0xe0, -0x02, 0x9f, 0x38, 0x1c, 0xdb, 0xe7, 0x00, 0x00, 0xd0, 0xab, 0x20, 0x40, -0x03, 0x49, 0x00, 0x20, 0x00, 0x22, 0x0a, 0x54, 0x01, 0x30, 0x60, 0x28, -0xfb, 0xd3, 0x70, 0x47, 0xd0, 0xab, 0x20, 0x40, 0x00, 0xb5, 0x02, 0xf0, -0x9f, 0xf9, 0x57, 0x20, 0x02, 0xf0, 0xfc, 0xf8, 0x02, 0xf0, 0x70, 0xf8, -0x00, 0x0a, 0xfb, 0xd3, 0x02, 0xf0, 0x7e, 0xf9, 0x08, 0xbc, 0x18, 0x47, -0xf0, 0xb5, 0x82, 0xb0, 0x14, 0x1c, 0x07, 0x9a, 0x1f, 0x1c, 0xff, 0x23, -0x01, 0x33, 0x1a, 0x40, 0x40, 0x02, 0x08, 0x43, 0x05, 0x0a, 0x06, 0x1c, -0x00, 0x0c, 0x01, 0x90, 0x00, 0x2a, 0x20, 0xd0, 0x02, 0xf0, 0x82, 0xf9, -0x53, 0x20, 0x02, 0xf0, 0xdf, 0xf8, 0x01, 0x98, 0xc0, 0x46, 0x00, 0x90, -0x02, 0xf0, 0xda, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 0xd7, 0xf8, 0x30, 0x1c, -0x02, 0xf0, 0xd4, 0xf8, 0x02, 0xf0, 0x5a, 0xf9, 0xff, 0xf7, 0xce, 0xff, -0x02, 0xf0, 0x6e, 0xf9, 0x54, 0x20, 0x02, 0xf0, 0xcb, 0xf8, 0x00, 0x98, -0x02, 0xf0, 0xc8, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 0xc5, 0xf8, 0x30, 0x1c, -0x14, 0xe0, 0x02, 0xf0, 0x61, 0xf9, 0x52, 0x20, 0x02, 0xf0, 0xbe, 0xf8, -0x01, 0x98, 0x02, 0xf0, 0xbb, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 0xb8, 0xf8, -0x30, 0x1c, 0x02, 0xf0, 0xb5, 0xf8, 0x00, 0x20, 0x02, 0xf0, 0xb2, 0xf8, -0x00, 0x20, 0x02, 0xf0, 0xaf, 0xf8, 0x00, 0x20, 0x02, 0xf0, 0xac, 0xf8, -0x00, 0x20, 0x02, 0xf0, 0xa9, 0xf8, 0x00, 0x2f, 0x05, 0xd9, 0x02, 0xf0, -0x1b, 0xf8, 0x20, 0x70, 0x01, 0x34, 0x01, 0x3f, 0xf9, 0xd1, 0x02, 0xf0, -0x27, 0xf9, 0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, -0x82, 0xb0, 0x14, 0x1c, 0x1f, 0x1c, 0x40, 0x02, 0x08, 0x43, 0x05, 0x1c, -0x02, 0xf0, 0x32, 0xf9, 0x53, 0x20, 0x02, 0xf0, 0x8f, 0xf8, 0x28, 0x0c, -0x06, 0x1c, 0x02, 0xf0, 0x8b, 0xf8, 0x28, 0x0a, 0x01, 0x90, 0x00, 0x90, -0x02, 0xf0, 0x86, 0xf8, 0x28, 0x1c, 0x02, 0xf0, -0x83, 0xf8, 0x02, 0xf0, 0x09, 0xf9, 0xff, 0xf7, 0x7d, 0xff, 0x02, 0xf0, -0x1d, 0xf9, 0x84, 0x20, 0x02, 0xf0, 0x7a, 0xf8, 0x30, 0x1c, 0x02, 0xf0, -0x77, 0xf8, 0x00, 0x98, 0x02, 0xf0, 0x74, 0xf8, 0x28, 0x1c, 0x02, 0xf0, -0x71, 0xf8, 0x00, 0x2f, 0x05, 0xd9, 0x20, 0x78, 0x01, 0x34, 0x02, 0xf0, -0x6b, 0xf8, 0x01, 0x3f, 0xf9, 0xd1, 0x02, 0xf0, 0xef, 0xf8, 0x02, 0xf0, -0x05, 0xf9, 0x83, 0x20, 0x02, 0xf0, 0x62, 0xf8, 0x30, 0x1c, 0x02, 0xf0, -0x5f, 0xf8, 0x01, 0x98, 0x02, 0xf0, 0x5c, 0xf8, 0x28, 0x1c, 0x02, 0xf0, -0x59, 0xf8, 0x02, 0xf0, 0xdf, 0xf8, 0xff, 0xf7, 0x53, 0xff, 0x02, 0xb0, -0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, -0x80, 0xb5, 0x01, 0xf0, 0x89, 0xf8, 0x06, 0x4f, 0xc0, 0x46, 0xf8, 0x60, -0x01, 0xf0, 0xe4, 0xf8, 0x78, 0x80, 0x01, 0xf0, 0xa5, 0xf8, 0x38, 0x71, -0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, -0x00, 0xb5, 0x01, 0xf0, 0xf7, 0xf8, 0x02, 0x49, 0xc0, 0x46, 0x08, 0x80, -0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x0b, 0x48, 0xc1, 0x68, -0x01, 0x29, 0x11, 0xd1, 0x02, 0x22, 0xc1, 0x6f, 0x0a, 0x43, 0xc2, 0x67, -0x08, 0x49, 0xc0, 0x46, 0x0a, 0x60, 0x80, 0x23, 0xc2, 0x6f, 0x1a, 0x43, -0xc2, 0x67, 0x0a, 0x60, 0x82, 0x22, 0x80, 0x30, 0x02, 0x60, 0x4a, 0x60, -0x00, 0x21, 0x81, 0x80, 0x70, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, -0x00, 0x01, 0x11, 0x00, 0xf0, 0xb4, 0x49, 0x49, 0xca, 0x1d, 0x99, 0x32, -0x00, 0x20, 0x00, 0x27, 0x83, 0x00, 0xd7, 0x50, 0x01, 0x30, 0x17, 0x28, -0xfa, 0xd3, 0x45, 0x4c, 0x00, 0x20, 0x82, 0x00, 0xa7, 0x50, 0x01, 0x30, -0x20, 0x28, 0xfa, 0xd3, 0x42, 0x4a, 0x00, 0x20, 0x83, 0x00, 0xd7, 0x50, -0x01, 0x30, 0x20, 0x28, 0xfa, 0xd3, 0xa7, 0x61, 0x97, 0x61, 0x4f, 0x65, -0x8f, 0x65, 0x3e, 0x4d, 0xc0, 0x46, 0x2f, 0x60, 0x6f, 0x60, 0xaf, 0x60, -0xaf, 0x61, 0xef, 0x60, 0x2f, 0x61, 0x6f, 0x61, 0x00, 0x20, 0xc1, 0x00, -0x09, 0x18, 0x49, 0x01, 0x34, 0x4b, 0xc9, 0x18, 0x86, 0x00, 0xcb, 0x1d, -0xf5, 0x33, 0x33, 0x4c, 0x34, 0x19, 0xe3, 0x63, 0x87, 0x23, 0x9b, 0x00, -0xcb, 0x18, 0x63, 0x63, 0xcf, 0x23, 0x9b, 0x00, 0xcb, 0x18, 0xb4, 0x18, -0xe3, 0x63, 0x30, 0x4b, 0xc9, 0x18, 0x61, 0x63, 0x01, 0x30, 0x02, 0x28, -0xe5, 0xdb, 0x29, 0x48, 0xc1, 0x1d, 0xf5, 0x31, 0x28, 0x4c, 0xc0, 0x46, -0xa1, 0x62, 0x61, 0x6b, 0xcf, 0x23, 0x9b, 0x00, 0xe1, 0x62, 0xc1, 0x18, -0x91, 0x62, 0x51, 0x6b, 0xc0, 0x46, 0xd1, 0x62, 0x08, 0x21, 0xe1, 0x64, -0x25, 0x49, 0xc0, 0x46, 0x21, 0x65, 0x25, 0x49, 0x0b, 0x69, 0xc0, 0x46, -0x63, 0x65, 0xc3, 0x1d, 0x4d, 0x33, 0xe3, 0x65, 0x25, 0x66, 0x8b, 0x68, -0xc0, 0x46, 0x63, 0x66, 0xcb, 0x68, 0xc0, 0x46, 0xa3, 0x66, 0x1f, 0x4b, -0xc0, 0x46, 0xe3, 0x66, 0x27, 0x67, 0x67, 0x67, 0x1d, 0x4b, 0xc3, 0x18, -0x01, 0x26, 0xa3, 0x67, 0x66, 0x61, 0xe7, 0x61, 0xe3, 0x1d, 0x69, 0x33, -0x1f, 0x73, 0x02, 0x23, 0xd3, 0x64, 0x19, 0x4b, 0xc0, 0x46, 0x13, 0x65, +0x0c, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x02, 0xaa, 0x00, 0xf0, 0x28, 0xfa, +0x02, 0x9d, 0x01, 0x20, 0x00, 0x04, 0x46, 0x9a, 0x10, 0x43, 0x79, 0x00, +0xc9, 0x19, 0xc9, 0x00, 0x17, 0x4a, 0xc0, 0x46, 0x50, 0x50, 0x30, 0x1c, +0x8e, 0x18, 0x70, 0x60, 0x10, 0x20, 0x04, 0x2c, 0x00, 0xd0, 0x0c, 0x20, +0x04, 0x1c, 0xb0, 0x60, 0x00, 0x20, 0x20, 0x21, 0x46, 0x9a, 0x11, 0x40, +0x20, 0x29, 0x00, 0xd0, 0x28, 0x1c, 0x30, 0x61, 0x28, 0x19, 0xff, 0x21, +0xff, 0x30, 0x08, 0x30, 0x09, 0x31, 0xff, 0xf7, 0x19, 0xff, 0x43, 0x01, +0x18, 0x18, 0xc0, 0x00, 0x00, 0x1b, 0x70, 0x61, 0x00, 0x20, 0x50, 0x21, +0x46, 0x9a, 0x11, 0x40, 0x50, 0x29, 0x00, 0xd1, 0x28, 0x1c, 0xf0, 0x60, +0x38, 0x1c, 0x47, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0x20, +0xf9, 0xe7, 0x00, 0x00, 0xd0, 0xab, 0x20, 0x40, 0x80, 0xb4, 0x00, 0x23, +0x00, 0x22, 0x00, 0x29, 0x06, 0xd9, 0x87, 0x5c, 0x7b, 0x40, 0x1b, 0x06, +0x1b, 0x0e, 0x01, 0x32, 0x8a, 0x42, 0xf8, 0xd3, 0xd8, 0x43, 0x00, 0x06, +0x00, 0x0e, 0x80, 0xbc, 0x70, 0x47, 0xf0, 0xb5, 0xc6, 0xb0, 0x04, 0x28, +0x07, 0xda, 0x41, 0x00, 0x09, 0x18, 0xc9, 0x00, 0x45, 0x91, 0x41, 0x4a, +0x51, 0x58, 0x4b, 0x0c, 0x02, 0xd2, 0x00, 0x20, 0xc0, 0x43, 0x76, 0xe0, +0x01, 0x23, 0x5b, 0x04, 0x19, 0x40, 0x43, 0x00, 0x18, 0x18, 0xc0, 0x00, +0x3a, 0x4a, 0x14, 0x18, 0x00, 0x29, 0x61, 0xd0, 0x00, 0x21, 0x02, 0x91, +0x20, 0x69, 0xa1, 0x68, 0x45, 0x18, 0x30, 0xd0, 0xff, 0x21, 0x68, 0x1e, +0x09, 0x31, 0xff, 0xf7, 0xcd, 0xfe, 0x61, 0x68, 0x40, 0x18, 0x01, 0x90, +0x01, 0x98, 0x81, 0x42, 0x02, 0xd1, 0xa6, 0x68, 0xaf, 0x1b, 0x09, 0xe0, +0x00, 0x26, 0xff, 0x21, 0x28, 0x1c, 0x09, 0x31, 0xff, 0xf7, 0xc7, 0xfe, +0x07, 0x1c, 0x01, 0xd1, 0xff, 0x27, 0x09, 0x37, 0x00, 0x22, 0x00, 0x92, +0x01, 0x98, 0x31, 0x1c, 0x03, 0xaa, 0x3b, 0x1c, 0x00, 0xf0, 0x9e, 0xf9, +0x03, 0xa8, 0x39, 0x1c, 0xff, 0xf7, 0xac, 0xff, 0xc0, 0x43, 0x02, 0x99, +0x48, 0x40, 0x01, 0x06, 0x09, 0x0e, 0x02, 0x91, 0xed, 0x1b, 0xa0, 0x68, +0xa8, 0x42, 0x00, 0xd1, 0x00, 0x25, 0x00, 0x2d, 0xce, 0xd8, 0x02, 0x99, +0xcf, 0x43, 0x00, 0x22, 0x00, 0x92, 0x0c, 0x23, 0x00, 0x21, 0x60, 0x68, +0x03, 0xaa, 0x00, 0xf0, 0x83, 0xf9, 0x20, 0x69, 0xc0, 0x46, 0x03, 0x90, +0x05, 0x98, 0x00, 0x0a, 0x00, 0x02, 0x39, 0x06, 0x09, 0x0e, 0x08, 0x43, +0x05, 0x90, 0xff, 0x23, 0x1b, 0x02, 0x98, 0x43, 0x05, 0x90, 0x0c, 0x21, +0x03, 0xa8, 0xff, 0xf7, 0x83, 0xff, 0xff, 0x23, 0x1b, 0x02, 0x05, 0x99, +0x99, 0x43, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x02, +0x08, 0x43, 0x05, 0x90, 0x0c, 0x23, 0x00, 0x21, 0x60, 0x68, 0x03, 0xaa, +0x00, 0xf0, 0xca, 0xf9, 0x00, 0x20, 0x45, 0x99, 0x06, 0x4a, 0xc0, 0x46, +0x50, 0x50, 0xc1, 0x43, 0x61, 0x60, 0xa1, 0x60, 0xe1, 0x60, 0x21, 0x61, +0x61, 0x61, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0xd0, 0xab, 0x20, 0x40, 0xb0, 0xb4, 0x4c, 0x42, 0x00, 0x29, 0x00, 0xdb, +0x0c, 0x1c, 0x00, 0x27, 0xff, 0x43, 0x04, 0x28, 0x21, 0xda, 0x12, 0x4d, +0x43, 0x00, 0x18, 0x18, 0xc0, 0x00, 0x40, 0x19, 0x01, 0x2a, 0x05, 0xd0, +0x02, 0x2a, 0x09, 0xd0, 0x03, 0x2a, 0x16, 0xd1, 0x01, 0x69, 0x0b, 0xe0, +0x00, 0x29, 0x12, 0xdb, 0x02, 0x69, 0x8a, 0x42, 0x0f, 0xd3, 0x05, 0xe0, +0x00, 0x29, 0x07, 0xda, 0xc1, 0x68, 0xa1, 0x42, 0x09, 0xd3, 0x09, 0x1b, +0xc1, 0x60, 0xc0, 0x68, 0xb0, 0xbc, 0x70, 0x47, 0xc1, 0x68, 0x09, 0x19, +0x02, 0x69, 0x91, 0x42, 0xf6, 0xd9, 0x38, 0x1c, 0xf6, 0xe7, 0x00, 0x00, +0xd0, 0xab, 0x20, 0x40, 0xf0, 0xb5, 0x84, 0xb0, 0x17, 0x1c, 0x0d, 0x1c, +0x00, 0x21, 0x02, 0x91, 0x42, 0x00, 0x12, 0x18, 0xd2, 0x00, 0x2c, 0x49, +0x8b, 0x58, 0x1b, 0x06, 0x1b, 0x0e, 0x01, 0x93, 0x00, 0x23, 0xdb, 0x43, +0x04, 0x28, 0x02, 0xda, 0x01, 0x98, 0x40, 0x08, 0x01, 0xd2, 0x18, 0x1c, +0x46, 0xe0, 0x54, 0x18, 0xe0, 0x68, 0xc2, 0x19, 0x21, 0x69, 0x8a, 0x42, +0x00, 0xd9, 0x0f, 0x1a, 0x00, 0x2f, 0x3c, 0xd9, 0xa0, 0x68, 0xe1, 0x68, +0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, 0x0d, 0xfe, 0x61, 0x68, +0x46, 0x18, 0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21, 0x09, 0x31, +0xff, 0xf7, 0x0d, 0xfe, 0xc2, 0x19, 0xff, 0x21, 0x09, 0x31, 0x8a, 0x42, +0x14, 0xd9, 0x01, 0x9a, 0xc0, 0x46, 0x00, 0x92, 0x0b, 0x1a, 0x03, 0x93, +0x01, 0x1c, 0x30, 0x1c, 0x2a, 0x1c, 0x00, 0xf0, 0xe1, 0xf8, 0xe0, 0x68, +0x03, 0x9b, 0xc0, 0x18, 0xe0, 0x60, 0x03, 0x9b, 0x5d, 0x19, 0xff, 0x1a, +0x02, 0x98, 0x18, 0x18, 0x02, 0x90, 0x10, 0xe0, 0x01, 0x9a, 0xc0, 0x46, +0x00, 0x92, 0x01, 0x1c, 0x30, 0x1c, 0x2a, 0x1c, 0x3b, 0x1c, 0x00, 0xf0, +0xcd, 0xf8, 0xe0, 0x68, 0xc0, 0x19, 0xed, 0x19, 0xe0, 0x60, 0x02, 0x98, +0xc0, 0x19, 0x02, 0x90, 0x00, 0x27, 0x00, 0x2f, 0xc2, 0xd8, 0x02, 0x98, +0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xd0, 0xab, 0x20, 0x40, +0xf0, 0xb5, 0x83, 0xb0, 0x17, 0x1c, 0x0d, 0x1c, 0x00, 0x21, 0x01, 0x91, +0x42, 0x00, 0x12, 0x18, 0xd2, 0x00, 0x02, 0x92, 0x30, 0x49, 0x8a, 0x58, +0x12, 0x06, 0x12, 0x0e, 0x00, 0x24, 0xe4, 0x43, 0x04, 0x28, 0x01, 0xda, +0x50, 0x09, 0x01, 0xd2, 0x20, 0x1c, 0x51, 0xe0, 0x02, 0x9a, 0x54, 0x18, +0xe0, 0x68, 0xc2, 0x19, 0x60, 0x69, 0x82, 0x42, 0x01, 0xd9, 0x22, 0x69, +0x87, 0x1a, 0x00, 0x2f, 0x45, 0xd9, 0x25, 0x4e, 0xa0, 0x68, 0xe1, 0x68, +0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, 0xa7, 0xfd, 0x61, 0x68, +0x40, 0x18, 0x00, 0x90, 0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21, +0x09, 0x31, 0xff, 0xf7, 0xa6, 0xfd, 0x02, 0x9a, 0xb1, 0x58, 0x01, 0x23, +0x5b, 0x04, 0x19, 0x43, 0xb1, 0x50, 0xc1, 0x19, 0xff, 0x22, 0x09, 0x32, +0x91, 0x42, 0x13, 0xd9, 0x13, 0x1a, 0x01, 0x1c, 0x00, 0x98, 0x2a, 0x1c, +0x1e, 0x1c, 0x00, 0xf0, 0xdf, 0xf8, 0xe0, 0x68, 0x80, 0x19, 0x75, 0x19, +0xe0, 0x60, 0x21, 0x69, 0x88, 0x42, 0x00, 0xd9, 0x20, 0x61, 0xbf, 0x1b, +0x01, 0x98, 0x30, 0x18, 0x01, 0x90, 0x12, 0xe0, +0x01, 0x1c, 0x00, 0x9e, 0x30, 0x1c, 0x2a, 0x1c, 0x3b, 0x1c, 0x00, 0xf0, +0xcb, 0xf8, 0xe0, 0x68, 0xc0, 0x19, 0xed, 0x19, 0xe0, 0x60, 0x21, 0x69, +0x88, 0x42, 0x00, 0xd9, 0x20, 0x61, 0x01, 0x98, 0xc0, 0x19, 0x01, 0x90, +0x00, 0x27, 0x00, 0x2f, 0xb9, 0xd8, 0x01, 0x98, 0x03, 0xb0, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0xd0, 0xab, 0x20, 0x40, 0xb0, 0xb5, 0xc3, 0xb0, +0x0c, 0x1c, 0x00, 0x27, 0xfa, 0x43, 0x04, 0x28, 0x06, 0xda, 0x41, 0x00, +0x09, 0x18, 0xc9, 0x00, 0x14, 0x48, 0x45, 0x58, 0x6b, 0x0c, 0x04, 0xd2, +0x10, 0x1c, 0x43, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x62, 0x09, +0x1b, 0xd3, 0x00, 0x22, 0x00, 0x92, 0x08, 0x18, 0x40, 0x68, 0x0c, 0x23, +0x00, 0x21, 0x01, 0xaa, 0x00, 0xf0, 0x30, 0xf8, 0x11, 0x2c, 0x0d, 0xd0, +0x12, 0x2c, 0x0d, 0xd0, 0x13, 0x2c, 0x05, 0xd0, 0x14, 0x2c, 0x0a, 0xd1, +0x03, 0x98, 0x00, 0x04, 0x07, 0x0e, 0x06, 0xe0, 0x03, 0x98, 0x07, 0x06, +0x3f, 0x0e, 0x02, 0xe0, 0x01, 0x9f, 0x00, 0xe0, 0x02, 0x9f, 0x38, 0x1c, +0xdb, 0xe7, 0x00, 0x00, 0xd0, 0xab, 0x20, 0x40, 0x03, 0x49, 0x00, 0x20, +0x00, 0x22, 0x0a, 0x54, 0x01, 0x30, 0x60, 0x28, 0xfb, 0xd3, 0x70, 0x47, +0xd0, 0xab, 0x20, 0x40, 0x00, 0xb5, 0x02, 0xf0, 0x01, 0xfa, 0x57, 0x20, +0x02, 0xf0, 0x5e, 0xf9, 0x02, 0xf0, 0xd2, 0xf8, 0x00, 0x0a, 0xfb, 0xd3, +0x02, 0xf0, 0xe0, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x82, 0xb0, +0x07, 0x9d, 0x14, 0x1c, 0x1f, 0x1c, 0x30, 0x4a, 0xd2, 0x6f, 0x20, 0x23, +0x16, 0x68, 0x9e, 0x43, 0x16, 0x60, 0x33, 0x1c, 0xff, 0x22, 0x01, 0x32, +0x2a, 0x40, 0x40, 0x02, 0x08, 0x43, 0x05, 0x0a, 0x06, 0x1c, 0x00, 0x0c, +0x01, 0x90, 0x00, 0x2a, 0x20, 0xd0, 0x02, 0xf0, 0xdd, 0xf9, 0x53, 0x20, +0x02, 0xf0, 0x3a, 0xf9, 0x01, 0x98, 0xc0, 0x46, 0x00, 0x90, 0x02, 0xf0, +0x35, 0xf9, 0x28, 0x1c, 0x02, 0xf0, 0x32, 0xf9, 0x30, 0x1c, 0x02, 0xf0, +0x2f, 0xf9, 0x02, 0xf0, 0xb5, 0xf9, 0xff, 0xf7, 0xc7, 0xff, 0x02, 0xf0, +0xc9, 0xf9, 0x54, 0x20, 0x02, 0xf0, 0x26, 0xf9, 0x00, 0x98, 0x02, 0xf0, +0x23, 0xf9, 0x28, 0x1c, 0x02, 0xf0, 0x20, 0xf9, 0x30, 0x1c, 0x14, 0xe0, +0x02, 0xf0, 0xbc, 0xf9, 0x52, 0x20, 0x02, 0xf0, 0x19, 0xf9, 0x01, 0x98, +0x02, 0xf0, 0x16, 0xf9, 0x28, 0x1c, 0x02, 0xf0, 0x13, 0xf9, 0x30, 0x1c, +0x02, 0xf0, 0x10, 0xf9, 0x00, 0x20, 0x02, 0xf0, 0x0d, 0xf9, 0x00, 0x20, +0x02, 0xf0, 0x0a, 0xf9, 0x00, 0x20, 0x02, 0xf0, 0x07, 0xf9, 0x00, 0x20, +0x02, 0xf0, 0x04, 0xf9, 0x00, 0x2f, 0x05, 0xd9, 0x02, 0xf0, 0x76, 0xf8, +0x20, 0x70, 0x01, 0x34, 0x01, 0x3f, 0xf9, 0xd1, 0x02, 0xf0, 0x82, 0xf9, +0x04, 0x4a, 0xd0, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, +0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, +0xf0, 0xb5, 0x82, 0xb0, 0x14, 0x1c, 0x1f, 0x1c, 0x40, 0x02, 0x08, 0x43, +0x05, 0x1c, 0x2c, 0x49, 0xc8, 0x6f, 0x20, 0x23, 0x02, 0x68, 0x9a, 0x43, +0x02, 0x60, 0xc8, 0x6f, 0x40, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, +0x02, 0xf0, 0x7a, 0xf9, 0x53, 0x20, 0x02, 0xf0, 0xd7, 0xf8, 0x28, 0x0c, +0x06, 0x1c, 0x02, 0xf0, 0xd3, 0xf8, 0x28, 0x0a, 0x01, 0x90, 0x00, 0x90, +0x02, 0xf0, 0xce, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 0xcb, 0xf8, 0x02, 0xf0, +0x51, 0xf9, 0xff, 0xf7, 0x63, 0xff, 0x02, 0xf0, 0x65, 0xf9, 0x84, 0x20, +0x02, 0xf0, 0xc2, 0xf8, 0x30, 0x1c, 0x02, 0xf0, +0xbf, 0xf8, 0x00, 0x98, 0x02, 0xf0, 0xbc, 0xf8, 0x28, 0x1c, 0x02, 0xf0, +0xb9, 0xf8, 0x00, 0x2f, 0x05, 0xd9, 0x20, 0x78, 0x01, 0x34, 0x02, 0xf0, +0xb3, 0xf8, 0x01, 0x3f, 0xf9, 0xd1, 0x02, 0xf0, 0x37, 0xf9, 0x02, 0xf0, +0x4d, 0xf9, 0x83, 0x20, 0x02, 0xf0, 0xaa, 0xf8, 0x30, 0x1c, 0x02, 0xf0, +0xa7, 0xf8, 0x01, 0x98, 0x02, 0xf0, 0xa4, 0xf8, 0x28, 0x1c, 0x02, 0xf0, +0xa1, 0xf8, 0x02, 0xf0, 0x27, 0xf9, 0xff, 0xf7, 0x39, 0xff, 0x07, 0x49, +0xc8, 0x6f, 0x40, 0x23, 0x02, 0x68, 0x9a, 0x43, 0x02, 0x60, 0xc8, 0x6f, +0x20, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x02, 0xb0, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x70, 0x47, 0x00, 0x00, +0x80, 0xb5, 0x01, 0xf0, 0x91, 0xf8, 0x06, 0x4f, 0xc0, 0x46, 0xf8, 0x60, +0x01, 0xf0, 0xf4, 0xf8, 0x78, 0x80, 0x01, 0xf0, 0xb3, 0xf8, 0x38, 0x71, +0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, +0x00, 0xb5, 0x01, 0xf0, 0x07, 0xf9, 0x02, 0x49, 0xc0, 0x46, 0x08, 0x80, +0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x0b, 0x48, 0xc1, 0x68, +0x01, 0x29, 0x11, 0xd1, 0xc1, 0x6f, 0x02, 0x23, 0x0a, 0x68, 0x1a, 0x43, +0x0a, 0x60, 0xc1, 0x6f, 0x80, 0x23, 0x0a, 0x68, 0x1a, 0x43, 0x0a, 0x60, +0xc1, 0x18, 0x08, 0x68, 0x82, 0x23, 0x02, 0x68, 0x1a, 0x43, 0x02, 0x60, +0x00, 0x20, 0x08, 0x81, 0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, +0xf0, 0xb4, 0x4a, 0x49, 0xca, 0x1d, 0x9d, 0x32, 0x00, 0x20, 0x00, 0x27, +0x83, 0x00, 0xd7, 0x50, 0x01, 0x30, 0x17, 0x28, 0xfa, 0xd3, 0x46, 0x4c, +0x00, 0x20, 0x82, 0x00, 0xa7, 0x50, 0x01, 0x30, 0x20, 0x28, 0xfa, 0xd3, +0x43, 0x4a, 0x00, 0x20, 0x83, 0x00, 0xd7, 0x50, 0x01, 0x30, 0x20, 0x28, +0xfa, 0xd3, 0xa7, 0x61, 0x97, 0x61, 0x4f, 0x65, 0x8f, 0x65, 0x3f, 0x4d, +0xc0, 0x46, 0x2f, 0x60, 0x6f, 0x60, 0xaf, 0x60, 0xaf, 0x61, 0xef, 0x60, +0x2f, 0x61, 0x6f, 0x61, 0x00, 0x20, 0xc1, 0x00, 0x09, 0x18, 0x49, 0x01, +0x35, 0x4b, 0xc9, 0x18, 0x86, 0x00, 0xcb, 0x1d, 0xf9, 0x33, 0x34, 0x4c, +0x34, 0x19, 0xe3, 0x63, 0x11, 0x23, 0x5b, 0x01, 0xcb, 0x18, 0x63, 0x63, +0x0d, 0x23, 0x9b, 0x01, 0xcb, 0x18, 0xb4, 0x18, 0xe3, 0x63, 0x23, 0x23, +0x5b, 0x01, 0xc9, 0x18, 0x61, 0x63, 0x01, 0x30, 0x02, 0x28, 0xe4, 0xdb, +0x29, 0x48, 0xc1, 0x1d, 0xf9, 0x31, 0x29, 0x4c, 0xc0, 0x46, 0xa1, 0x62, +0x61, 0x6b, 0x0d, 0x23, 0x9b, 0x01, 0xe1, 0x62, 0xc1, 0x18, 0x91, 0x62, +0x51, 0x6b, 0xc0, 0x46, 0xd1, 0x62, 0x08, 0x21, 0xe1, 0x64, 0x25, 0x49, +0xc0, 0x46, 0x21, 0x65, 0x24, 0x49, 0x0b, 0x69, 0xc0, 0x46, 0x63, 0x65, +0xc3, 0x1d, 0x4d, 0x33, 0xe3, 0x65, 0x25, 0x66, 0x8b, 0x68, 0xc0, 0x46, +0x63, 0x66, 0xcb, 0x68, 0xc0, 0x46, 0xa3, 0x66, 0x1e, 0x4b, 0xc0, 0x46, +0xe3, 0x66, 0x27, 0x67, 0x0b, 0x23, 0xdb, 0x01, 0xc3, 0x18, 0xa3, 0x67, +0x67, 0x67, 0x01, 0x26, 0xe3, 0x1d, 0x69, 0x33, 0x66, 0x61, 0xe7, 0x61, +0x1f, 0x73, 0x02, 0x23, 0xd3, 0x64, 0x17, 0x4b, 0xc0, 0x46, 0x13, 0x65, 0xcb, 0x69, 0xc0, 0x46, 0x53, 0x65, 0xc3, 0x1d, 0x51, 0x33, 0xd3, 0x65, 0x2b, 0x1d, 0x13, 0x66, 0x4b, 0x69, 0xc0, 0x46, 0x53, 0x66, 0x89, 0x69, -0xc0, 0x46, 0x91, 0x66, 0x11, 0x49, 0xc0, 0x46, 0xd1, 0x66, 0x16, 0x67, -0x56, 0x67, 0x10, 0x4b, 0xc0, 0x18, 0x90, 0x67, 0x56, 0x61, 0xd7, 0x61, -0xd0, 0x1d, 0x69, 0x30, 0x07, 0x73, 0xf0, 0xbc, -0x70, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x50, 0x2c, 0x00, 0x80, -0xd0, 0x2c, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, 0x5c, 0x04, 0x00, 0x00, -0x30, 0x01, 0x18, 0x00, 0xf8, 0x28, 0x00, 0x80, 0x80, 0x54, 0xff, 0xff, -0x7c, 0x05, 0x00, 0x00, 0x38, 0x01, 0x18, 0x00, 0x90, 0x54, 0xff, 0xff, -0x7c, 0x07, 0x00, 0x00, 0x90, 0xb4, 0x00, 0x21, 0x1c, 0x4a, 0xbb, 0x23, -0x1b, 0x01, 0xd7, 0x18, 0xf9, 0x72, 0x19, 0x23, 0xdb, 0x01, 0xd0, 0x18, -0x33, 0x23, 0x9b, 0x01, 0xd3, 0x18, 0x81, 0x61, 0x59, 0x60, 0xb9, 0x72, -0x01, 0x27, 0x1f, 0x73, 0x19, 0x61, 0x17, 0x23, 0xdb, 0x01, 0xd3, 0x18, -0xd9, 0x63, 0x13, 0x4b, 0x51, 0x27, 0xbf, 0x03, 0xc3, 0x62, 0x3b, 0x60, -0x44, 0x69, 0xe4, 0x18, 0x04, 0x63, 0x04, 0x3c, 0x7c, 0x60, 0x01, 0x24, -0xe4, 0x02, 0x44, 0x63, 0x0d, 0x4c, 0xc0, 0x46, 0xbc, 0x60, 0xc4, 0x6a, -0xc0, 0x46, 0x04, 0x62, 0x44, 0x69, 0xe4, 0x18, 0x0a, 0x4b, 0xe3, 0x18, -0xfb, 0x60, 0xc3, 0x6a, 0xc0, 0x46, 0x43, 0x62, 0x03, 0x6a, 0xc0, 0x46, -0xc3, 0x61, 0x81, 0x63, 0x51, 0x64, 0x91, 0x64, 0xd1, 0x65, 0xd1, 0x66, -0x90, 0xbc, 0x70, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40, -0xfc, 0x07, 0x00, 0x00, 0xfc, 0xf7, 0xff, 0xff, 0x90, 0xb4, 0x00, 0x22, -0x1c, 0x49, 0xc9, 0x23, 0x1b, 0x01, 0xc8, 0x18, 0x02, 0x70, 0x01, 0x20, -0xbb, 0x23, 0x1b, 0x01, 0xcb, 0x18, 0x58, 0x72, 0x18, 0x48, 0x03, 0x1c, -0x00, 0x27, 0xdc, 0x1d, 0xc1, 0x34, 0x1c, 0x65, 0x23, 0x1c, 0x01, 0x37, -0x3f, 0x2f, 0xf8, 0xd3, 0x1a, 0x65, 0x19, 0x23, 0xdb, 0x01, 0xcf, 0x18, -0x33, 0x23, 0x9b, 0x01, 0xcc, 0x18, 0xfa, 0x60, 0x60, 0x61, 0x40, 0x20, -0xb8, 0x60, 0xa2, 0x61, 0xe2, 0x61, 0xca, 0x64, 0x0a, 0x66, 0x0d, 0x48, -0xc0, 0x46, 0xc2, 0x60, 0x0c, 0x48, 0x00, 0x6b, 0xc0, 0x06, 0xc0, 0x0e, -0xb8, 0x63, 0x0b, 0x48, 0x65, 0x23, 0x5b, 0x01, 0xc9, 0x18, 0x02, 0x68, -0xc0, 0x46, 0x8a, 0x83, 0x42, 0x68, 0xc0, 0x46, 0xca, 0x83, 0x80, 0x68, -0xc0, 0x46, 0x20, 0x80, 0x90, 0xbc, 0x70, 0x47, 0xe8, 0x0d, 0x00, 0x80, -0x3c, 0xbd, 0x20, 0x40, 0x3c, 0xef, 0x20, 0x40, 0x80, 0x00, 0x14, 0x40, -0x40, 0x00, 0x14, 0x40, 0x00, 0x20, 0x0a, 0x49, 0xc0, 0x46, 0x08, 0x73, -0xcb, 0x1d, 0xff, 0x33, 0x3a, 0x33, 0x88, 0x61, 0xc8, 0x61, 0x18, 0x70, -0x06, 0x4a, 0xc0, 0x46, 0x10, 0x65, 0x50, 0x66, 0x90, 0x66, 0x08, 0x70, -0x58, 0x70, 0xbb, 0x23, 0x1b, 0x01, 0xd1, 0x18, 0x08, 0x72, 0x70, 0x47, -0xa8, 0x04, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 0xf0, 0xb4, 0x2f, 0x49, -0x2f, 0x4a, 0xc0, 0x46, 0x11, 0x61, 0x01, 0x23, 0x9b, 0x02, 0xc8, 0x18, -0x50, 0x61, 0x2d, 0x48, 0xc0, 0x46, 0x10, 0x62, 0xdb, 0x00, 0xc3, 0x18, -0x53, 0x62, 0x00, 0x23, 0x13, 0x63, 0x53, 0x63, 0x29, 0x4a, 0x2a, 0x4f, -0xd4, 0x1d, 0xff, 0x34, 0xfa, 0x34, 0x14, 0xc7, 0x08, 0x3f, 0x3b, 0x61, -0x1c, 0x1f, 0x7c, 0x61, 0x26, 0x4f, 0xc0, 0x46, 0x39, 0x60, 0xb8, 0x61, -0x79, 0x61, 0xf8, 0x62, 0x3b, 0x63, 0x7b, 0x64, 0xba, 0x64, 0xfa, 0x65, -0x22, 0x4f, 0xfe, 0x1d, 0xf9, 0x36, 0x22, 0x4d, 0xec, 0x1d, 0x79, 0x34, -0xe6, 0x61, 0x51, 0x26, 0xb6, 0x03, 0x37, 0x61, 0xe4, 0x69, 0xc0, 0x46, -0x74, 0x61, 0x2f, 0x67, 0x1d, 0x4d, 0x09, 0x27, 0x7f, 0x04, 0xec, 0x1d, -0x75, 0x34, 0x7c, 0x60, 0x3d, 0x60, 0x1b, 0x4c, 0xc0, 0x46, 0x3c, 0x61, -0xe6, 0x1d, 0x75, 0x36, 0x7e, 0x61, 0x19, 0x4f, -0xc0, 0x46, 0x7c, 0x60, 0x3d, 0x60, 0x0f, 0x1c, 0x00, 0x21, 0xff, 0x24, -0x01, 0x34, 0x1d, 0x1c, 0x8b, 0x00, 0xfd, 0x50, 0x01, 0x31, 0xa1, 0x42, -0xfa, 0xd3, 0x01, 0x1c, 0x00, 0x20, 0x01, 0x27, 0xff, 0x02, 0x83, 0x00, -0xcd, 0x50, 0x01, 0x30, 0xb8, 0x42, 0xfa, 0xd3, 0x00, 0x20, 0x81, 0x00, -0x55, 0x50, 0x01, 0x30, 0x80, 0x28, 0xfa, 0xd3, 0xf0, 0xbc, 0x70, 0x47, -0x24, 0xa3, 0x20, 0x40, 0x40, 0x01, 0x18, 0x00, 0x24, 0x83, 0x20, 0x40, -0x24, 0xa9, 0x20, 0x40, 0x80, 0x01, 0x18, 0x00, 0x28, 0x03, 0x00, 0x80, -0x24, 0xa7, 0x20, 0x40, 0xe8, 0x0d, 0x00, 0x80, 0x24, 0xa8, 0x20, 0x40, -0xa4, 0xa8, 0x20, 0x40, 0x88, 0x03, 0x00, 0x80, 0xb8, 0xb5, 0x2d, 0x48, -0xfd, 0xf7, 0xc6, 0xfa, 0x01, 0x20, 0x2c, 0x49, 0x0a, 0x68, 0x52, 0x0c, -0x06, 0xd2, 0x0a, 0x68, 0x12, 0x0c, 0x02, 0xd1, 0x0a, 0x68, 0x92, 0x0a, -0x00, 0xd2, 0x00, 0x20, 0x04, 0x06, 0x24, 0x0e, 0x26, 0x4a, 0xd7, 0x1d, -0x0d, 0x37, 0x00, 0x23, 0x00, 0x20, 0x9d, 0x00, 0x78, 0x51, 0x01, 0x33, -0x04, 0x2b, 0xfa, 0xd3, 0x01, 0x27, 0x3f, 0x05, 0x50, 0x61, 0xf8, 0x60, -0xd0, 0x61, 0xf8, 0x61, 0x00, 0x23, 0xdb, 0x43, 0x93, 0x61, 0x3b, 0x61, -0x13, 0x62, 0x3b, 0x62, 0x00, 0x27, 0x1c, 0x4b, 0x8d, 0x68, 0xc0, 0x46, -0x00, 0x95, 0x8d, 0x69, 0xc0, 0x46, 0x00, 0x95, 0x00, 0x2c, 0x0b, 0xd0, -0xdd, 0x6b, 0xc0, 0x46, 0x00, 0x95, 0x9d, 0x6b, 0xc0, 0x46, 0x00, 0x95, -0x5d, 0x6b, 0xc0, 0x46, 0x00, 0x95, 0x1d, 0x6b, 0xc0, 0x46, 0x00, 0x95, -0x01, 0x37, 0x40, 0x2f, 0xe8, 0xd3, 0x00, 0x27, 0x6c, 0x46, 0x01, 0x23, -0x5b, 0x07, 0x1c, 0x43, 0x01, 0xe0, 0x20, 0x60, 0x01, 0x37, 0x0d, 0x68, -0x2b, 0x09, 0x02, 0xd2, 0x80, 0x2f, 0xf8, 0xd3, 0x01, 0xe0, 0x80, 0x2f, -0x03, 0xd3, 0x09, 0x49, 0x4b, 0x6e, 0x01, 0x33, 0x4b, 0x66, 0xd0, 0x62, -0x07, 0x48, 0xfd, 0xf7, 0x71, 0xfa, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0xf4, 0x01, 0xff, 0xff, 0x00, 0x00, 0x10, 0x40, 0xe8, 0x0d, 0x00, 0x80, -0x00, 0x01, 0x18, 0x40, 0xa0, 0x82, 0x20, 0x40, 0x04, 0x02, 0xff, 0xff, -0x90, 0xb4, 0x00, 0x21, 0x0e, 0x4f, 0x0f, 0x4a, 0x00, 0x20, 0x4c, 0x01, -0x64, 0x1a, 0xa4, 0x00, 0xa3, 0x18, 0x58, 0x60, 0x98, 0x60, 0x18, 0x64, -0x58, 0x64, 0x10, 0x53, 0x58, 0x80, 0xcc, 0x00, 0xe4, 0x19, 0x98, 0x67, -0xdc, 0x62, 0x01, 0x31, 0x03, 0x29, 0xee, 0xd3, 0x06, 0x49, 0xc0, 0x46, -0x08, 0x60, 0x48, 0x60, 0x88, 0x60, 0xc8, 0x60, 0x08, 0x61, 0x90, 0xbc, -0x70, 0x47, 0x00, 0x00, 0x58, 0x67, 0x21, 0x40, 0xc8, 0x2a, 0x00, 0x80, -0x3c, 0x2c, 0x00, 0x80, 0x00, 0xb5, 0x64, 0x21, 0x07, 0x48, 0xc0, 0x46, -0x01, 0x63, 0x00, 0x21, 0xc9, 0x43, 0x41, 0x63, 0x81, 0x63, 0x00, 0x21, -0xc1, 0x63, 0x01, 0x64, 0x03, 0x48, 0x28, 0x22, 0x02, 0xf0, 0x06, 0xff, -0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x59, 0x03, 0xff, 0xff, -0x80, 0xb4, 0x01, 0x20, 0x40, 0x02, 0x0a, 0x49, 0xc0, 0x46, 0x08, 0x60, -0x3c, 0x20, 0x48, 0x60, 0x88, 0x60, 0x08, 0x48, 0xc0, 0x46, 0xc8, 0x60, -0x00, 0x20, 0x07, 0x4a, 0x87, 0x00, 0xcb, 0x68, 0xc0, 0x46, 0xda, 0x51, -0x01, 0x30, 0x10, 0x28, 0xf8, 0xd3, 0x80, 0xbc, 0x70, 0x47, 0x00, 0x00, -0x50, 0x2d, 0x00, 0x80, 0x60, 0x2d, 0x00, 0x80, 0xd5, 0x4b, 0xff, 0xff, -0x12, 0x49, 0x13, 0x48, 0x67, 0x23, 0x9b, 0x01, 0xca, 0x18, 0x06, 0xc0, -0x08, 0x38, 0x11, 0x4b, 0xca, 0x18, 0xc1, 0x60, +0xc0, 0x46, 0x91, 0x66, 0x0f, 0x49, 0xc0, 0x46, 0xd1, 0x66, 0x16, 0x67, +0x0f, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x90, 0x67, 0x56, 0x67, 0xd7, 0x61, +0xd0, 0x1d, 0x69, 0x30, 0x56, 0x61, 0x07, 0x73, +0xf0, 0xbc, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, 0xe4, 0x2c, 0x00, 0x80, +0x64, 0x2d, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, 0x30, 0x01, 0x18, 0x00, +0x7c, 0x29, 0x00, 0x80, 0xec, 0x54, 0xff, 0xff, 0x38, 0x01, 0x18, 0x00, +0xfc, 0x54, 0xff, 0xff, 0x90, 0xb4, 0x00, 0x21, 0x1e, 0x4a, 0xbb, 0x23, +0x1b, 0x01, 0xd7, 0x18, 0xf9, 0x73, 0x19, 0x23, 0xdb, 0x01, 0xd0, 0x18, +0x01, 0x24, 0xcd, 0x23, 0x1b, 0x01, 0xd3, 0x18, 0xc1, 0x61, 0x1c, 0x70, +0x33, 0x23, 0x9b, 0x01, 0xd3, 0x18, 0x99, 0x60, 0xb9, 0x73, 0x59, 0x61, +0x2f, 0x23, 0x9b, 0x01, 0xd3, 0x18, 0x19, 0x60, 0x13, 0x4b, 0x51, 0x27, +0xbf, 0x03, 0x03, 0x63, 0x3b, 0x60, 0x84, 0x69, 0xe4, 0x18, 0x44, 0x63, +0x04, 0x3c, 0x7c, 0x60, 0x01, 0x24, 0xe4, 0x02, 0x84, 0x63, 0x0e, 0x4c, +0xc0, 0x46, 0xbc, 0x60, 0x04, 0x6b, 0xc0, 0x46, 0x44, 0x62, 0x84, 0x69, +0xe4, 0x18, 0x0b, 0x4b, 0xe3, 0x18, 0xfb, 0x60, 0x03, 0x6b, 0xc0, 0x46, +0x83, 0x62, 0x43, 0x6a, 0xc0, 0x46, 0x03, 0x62, 0xc1, 0x63, 0x51, 0x64, +0x91, 0x64, 0xd1, 0x65, 0xd1, 0x66, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x00, +0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40, 0xfc, 0x07, 0x00, 0x00, +0xfc, 0xf7, 0xff, 0xff, 0x90, 0xb4, 0x00, 0x22, 0x1b, 0x49, 0xc9, 0x23, +0x1b, 0x01, 0xc8, 0x18, 0x02, 0x71, 0x01, 0x20, 0xbb, 0x23, 0x1b, 0x01, +0xcb, 0x18, 0x58, 0x73, 0x17, 0x48, 0x03, 0x1c, 0x00, 0x27, 0xdc, 0x1d, +0xc1, 0x34, 0x1c, 0x65, 0x23, 0x1c, 0x01, 0x37, 0x3f, 0x2f, 0xf8, 0xd3, +0x1a, 0x65, 0x19, 0x23, 0xdb, 0x01, 0xcf, 0x18, 0x33, 0x23, 0x9b, 0x01, +0xcb, 0x18, 0x3a, 0x61, 0x98, 0x61, 0x40, 0x20, 0xf8, 0x60, 0xda, 0x61, +0x1a, 0x62, 0xca, 0x64, 0x0a, 0x66, 0x0c, 0x48, 0xc0, 0x46, 0xc2, 0x60, +0x0b, 0x48, 0x00, 0x6b, 0xc0, 0x06, 0xc0, 0x0e, 0xf8, 0x63, 0x0a, 0x48, +0x01, 0x68, 0xc0, 0x46, 0x19, 0x80, 0x41, 0x68, 0xc0, 0x46, 0x59, 0x80, +0x80, 0x68, 0xc0, 0x46, 0x98, 0x80, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x00, +0x68, 0x0e, 0x00, 0x80, 0x3c, 0xbd, 0x20, 0x40, 0x3c, 0xef, 0x20, 0x40, +0x80, 0x00, 0x14, 0x40, 0x40, 0x00, 0x14, 0x40, 0x00, 0x20, 0x0a, 0x49, +0xc0, 0x46, 0x08, 0x73, 0xcb, 0x1d, 0xff, 0x33, 0x3a, 0x33, 0x88, 0x61, +0xc8, 0x61, 0x18, 0x70, 0x06, 0x4a, 0xc0, 0x46, 0x10, 0x65, 0x50, 0x66, +0x90, 0x66, 0x08, 0x70, 0x58, 0x70, 0xbb, 0x23, 0x1b, 0x01, 0xd1, 0x18, +0x08, 0x73, 0x70, 0x47, 0x28, 0x05, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80, +0xf0, 0xb4, 0x2f, 0x49, 0x2f, 0x4a, 0xc0, 0x46, 0x11, 0x61, 0x01, 0x23, +0x9b, 0x02, 0xc8, 0x18, 0x50, 0x61, 0x2d, 0x48, 0xc0, 0x46, 0x10, 0x62, +0xdb, 0x00, 0xc3, 0x18, 0x53, 0x62, 0x00, 0x23, 0x13, 0x63, 0x53, 0x63, +0x29, 0x4a, 0x2a, 0x4f, 0xd4, 0x1d, 0xff, 0x34, 0xfa, 0x34, 0x14, 0xc7, +0x08, 0x3f, 0x3b, 0x61, 0x1c, 0x1f, 0x7c, 0x61, 0x26, 0x4f, 0xc0, 0x46, +0x39, 0x60, 0xb8, 0x61, 0x79, 0x61, 0xf8, 0x62, 0x3b, 0x63, 0x7b, 0x64, +0xba, 0x64, 0xfa, 0x65, 0x22, 0x4f, 0xfe, 0x1d, 0xf9, 0x36, 0x22, 0x4d, +0xec, 0x1d, 0x79, 0x34, 0x26, 0x62, 0x51, 0x26, 0xb6, 0x03, 0x37, 0x61, +0x24, 0x6a, 0xc0, 0x46, 0x74, 0x61, 0x2f, 0x67, 0x1d, 0x4d, 0x09, 0x27, +0x7f, 0x04, 0xec, 0x1d, 0x75, 0x34, 0x7c, 0x60, 0x3d, 0x60, 0x1b, 0x4c, +0xc0, 0x46, 0x3c, 0x61, 0xe6, 0x1d, 0x75, 0x36, 0x7e, 0x61, 0x19, 0x4f, +0xc0, 0x46, 0x7c, 0x60, 0x3d, 0x60, 0x0f, 0x1c, +0x00, 0x21, 0xff, 0x24, 0x01, 0x34, 0x1d, 0x1c, 0x8b, 0x00, 0xfd, 0x50, +0x01, 0x31, 0xa1, 0x42, 0xfa, 0xd3, 0x01, 0x1c, 0x00, 0x20, 0x01, 0x27, +0xff, 0x02, 0x83, 0x00, 0xcd, 0x50, 0x01, 0x30, 0xb8, 0x42, 0xfa, 0xd3, +0x00, 0x20, 0x81, 0x00, 0x55, 0x50, 0x01, 0x30, 0x80, 0x28, 0xfa, 0xd3, +0xf0, 0xbc, 0x70, 0x47, 0x24, 0xa3, 0x20, 0x40, 0x40, 0x01, 0x18, 0x00, +0x24, 0x83, 0x20, 0x40, 0x24, 0xa9, 0x20, 0x40, 0x80, 0x01, 0x18, 0x00, +0xa8, 0x03, 0x00, 0x80, 0x24, 0xa7, 0x20, 0x40, 0x68, 0x0e, 0x00, 0x80, +0x24, 0xa8, 0x20, 0x40, 0xa4, 0xa8, 0x20, 0x40, 0x08, 0x04, 0x00, 0x80, +0xb8, 0xb5, 0x2c, 0x48, 0xfc, 0xf7, 0x0a, 0xff, 0x01, 0x20, 0x2b, 0x49, +0x0a, 0x68, 0x52, 0x0c, 0x06, 0xd2, 0x0a, 0x68, 0x12, 0x0c, 0x02, 0xd1, +0x0a, 0x68, 0x92, 0x0a, 0x00, 0xd2, 0x00, 0x20, 0x04, 0x06, 0x24, 0x0e, +0x25, 0x4a, 0xd7, 0x1d, 0x0d, 0x37, 0x00, 0x23, 0x00, 0x20, 0x9d, 0x00, +0x78, 0x51, 0x01, 0x33, 0x04, 0x2b, 0xfa, 0xd3, 0x01, 0x27, 0x3f, 0x05, +0x50, 0x61, 0xf8, 0x60, 0xd0, 0x61, 0xf8, 0x61, 0x00, 0x23, 0xdb, 0x43, +0x93, 0x61, 0x3b, 0x61, 0x13, 0x62, 0x3b, 0x62, 0x00, 0x27, 0x1b, 0x4b, +0x8d, 0x68, 0xc0, 0x46, 0x00, 0x95, 0x8d, 0x69, 0xc0, 0x46, 0x00, 0x95, +0x00, 0x2c, 0x0b, 0xd0, 0xdd, 0x6b, 0xc0, 0x46, 0x00, 0x95, 0x9d, 0x6b, +0xc0, 0x46, 0x00, 0x95, 0x5d, 0x6b, 0xc0, 0x46, 0x00, 0x95, 0x1d, 0x6b, +0xc0, 0x46, 0x00, 0x95, 0x01, 0x37, 0x40, 0x2f, 0xe8, 0xd3, 0x00, 0x27, +0x6c, 0x46, 0x01, 0x23, 0x5b, 0x07, 0x1c, 0x43, 0x01, 0xe0, 0x20, 0x60, +0x01, 0x37, 0x0d, 0x68, 0x2b, 0x09, 0x02, 0xd2, 0x80, 0x2f, 0xf8, 0xd3, +0x01, 0xe0, 0x80, 0x2f, 0x03, 0xd3, 0x08, 0x49, 0x4b, 0x6e, 0x01, 0x33, +0x4b, 0x66, 0xd0, 0x62, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0xf4, 0x01, 0xff, 0xff, 0x00, 0x00, 0x10, 0x40, 0x68, 0x0e, 0x00, 0x80, +0x00, 0x01, 0x18, 0x40, 0xa0, 0x82, 0x20, 0x40, 0x90, 0xb4, 0x00, 0x21, +0x0e, 0x4f, 0x0f, 0x4a, 0x00, 0x20, 0x4c, 0x01, 0x64, 0x1a, 0xa4, 0x00, +0xa3, 0x18, 0x58, 0x60, 0x98, 0x60, 0x18, 0x64, 0x58, 0x64, 0x10, 0x53, +0x58, 0x80, 0xcc, 0x00, 0xe4, 0x19, 0x98, 0x67, 0xdc, 0x62, 0x01, 0x31, +0x03, 0x29, 0xee, 0xd3, 0x06, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x48, 0x60, +0x88, 0x60, 0xc8, 0x60, 0x08, 0x61, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x00, +0x58, 0x67, 0x21, 0x40, 0x5c, 0x2b, 0x00, 0x80, 0xd0, 0x2c, 0x00, 0x80, +0x64, 0x21, 0x05, 0x48, 0xc0, 0x46, 0x01, 0x63, 0x00, 0x21, 0xc9, 0x43, +0x41, 0x63, 0x81, 0x63, 0x00, 0x21, 0xc1, 0x63, 0x01, 0x64, 0x70, 0x47, +0x68, 0x0e, 0x00, 0x80, 0x80, 0xb4, 0x01, 0x20, 0x40, 0x02, 0x0a, 0x49, +0xc0, 0x46, 0x08, 0x60, 0x3c, 0x20, 0x48, 0x60, 0x88, 0x60, 0x08, 0x48, +0xc0, 0x46, 0xc8, 0x60, 0x00, 0x20, 0x07, 0x4a, 0x87, 0x00, 0xcb, 0x68, +0xc0, 0x46, 0xda, 0x51, 0x01, 0x30, 0x10, 0x28, 0xf8, 0xd3, 0x80, 0xbc, +0x70, 0x47, 0x00, 0x00, 0xe4, 0x2d, 0x00, 0x80, 0xf4, 0x2d, 0x00, 0x80, +0x49, 0x4c, 0xff, 0xff, 0x12, 0x49, 0x13, 0x48, 0x67, 0x23, 0x9b, 0x01, +0xca, 0x18, 0x06, 0xc0, 0x08, 0x38, 0x11, 0x4b, 0xca, 0x18, 0xc1, 0x60, 0x82, 0x60, 0x01, 0x61, 0x0f, 0x49, 0x10, 0x48, 0xa7, 0x23, 0x9b, 0x01, 0xca, 0x18, 0x06, 0xc0, 0x08, 0x38, 0x0e, 0x4b, 0xca, 0x18, 0xc1, 0x60, -0x82, 0x60, 0x01, 0x61, 0x0c, 0x48, 0x0d, 0x49, 0x67, 0x23, 0x9b, 0x01, -0xc2, 0x18, 0x05, 0xc1, 0x08, 0x39, 0x05, 0x4b, 0xc2, 0x18, 0xc8, 0x60, -0x8a, 0x60, 0x08, 0x61, 0x70, 0x47, 0x00, 0x00, 0x58, 0x1f, 0x21, 0x40, -0xb4, 0x2d, 0x00, 0x80, 0xfc, 0x1f, 0x00, 0x00, 0x58, 0xef, 0x20, 0x40, -0xa0, 0x2d, 0x00, 0x80, 0xfc, 0x2f, 0x00, 0x00, 0x58, 0x3f, 0x21, 0x40, -0xc8, 0x2d, 0x00, 0x80, 0x90, 0xb4, 0x00, 0x21, 0x40, 0x4c, 0x00, 0x20, -0x0a, 0x01, 0x12, 0x19, 0x19, 0x23, 0xdb, 0x01, 0xd2, 0x18, 0xd0, 0x62, -0x10, 0x63, 0x50, 0x63, 0x90, 0x63, 0x01, 0x31, 0x03, 0x29, 0xf3, 0xd3, -0x3a, 0x49, 0xc0, 0x46, 0xc8, 0x62, 0x08, 0x63, 0x48, 0x63, 0x20, 0x60, -0x01, 0x21, 0xe3, 0x1d, 0x59, 0x33, 0x60, 0x60, 0x19, 0x71, 0x18, 0x72, -0x98, 0x71, 0x98, 0x72, 0x59, 0x71, 0x58, 0x72, 0xd8, 0x71, 0xd8, 0x72, -0xe2, 0x1d, 0x49, 0x32, 0x11, 0x73, 0x19, 0x70, 0x90, 0x73, 0x98, 0x70, -0x51, 0x73, 0x59, 0x70, 0xd0, 0x73, 0xd8, 0x70, 0x11, 0x71, 0x11, 0x72, -0x90, 0x71, 0x90, 0x72, 0x50, 0x71, 0x50, 0x72, 0xd0, 0x71, 0xd0, 0x72, -0x18, 0x73, 0x02, 0x22, 0xe7, 0x1d, 0x69, 0x37, 0x3a, 0x70, 0x99, 0x73, -0xba, 0x70, 0x58, 0x73, 0x78, 0x70, 0xd8, 0x73, 0xf8, 0x70, 0x39, 0x71, -0x3a, 0x72, 0xb9, 0x71, 0xb9, 0x72, 0x78, 0x71, 0x7a, 0x72, 0xf9, 0x71, -0xf9, 0x72, 0x39, 0x73, 0xe3, 0x1d, 0x79, 0x33, 0x1a, 0x70, 0xb9, 0x73, -0x99, 0x70, 0x78, 0x73, 0x5a, 0x70, 0xf9, 0x73, 0xd9, 0x70, 0x1a, 0x71, -0x1a, 0x72, 0x99, 0x71, 0x9a, 0x72, 0x58, 0x71, 0x5a, 0x72, 0xd9, 0x71, -0xda, 0x72, 0x19, 0x73, 0xe7, 0x1d, 0x89, 0x37, 0x3a, 0x70, 0x99, 0x73, -0xb9, 0x70, 0x58, 0x73, 0x7a, 0x70, 0xd9, 0x73, 0xf9, 0x70, 0x39, 0x71, -0x3a, 0x72, 0xb9, 0x71, 0xb9, 0x72, 0x78, 0x71, 0x7a, 0x72, 0xf9, 0x71, -0xf9, 0x72, 0x3a, 0x73, 0xe3, 0x1d, 0x99, 0x33, 0x1a, 0x70, 0xb9, 0x73, -0x9a, 0x70, 0x78, 0x73, 0x5a, 0x70, 0xf9, 0x73, 0xda, 0x70, 0x19, 0x71, -0x1a, 0x72, 0x99, 0x71, 0x99, 0x72, 0x58, 0x71, 0x5a, 0x72, 0xd9, 0x71, -0xd9, 0x72, 0x20, 0x61, 0xe0, 0x60, 0x60, 0x61, 0xa0, 0x60, 0x90, 0xbc, -0x70, 0x47, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x80, 0x68, 0x19, 0x00, 0x80, -0x81, 0x20, 0x00, 0x02, 0x01, 0x49, 0xc0, 0x46, 0x88, 0x62, 0x70, 0x47, -0xc0, 0x00, 0x14, 0x00, 0x0a, 0x49, 0x13, 0x23, 0xdb, 0x01, 0xc8, 0x18, -0x25, 0x23, 0x9b, 0x01, 0xc9, 0x18, 0xc8, 0x63, 0x00, 0x21, 0xc2, 0x1d, +0x82, 0x60, 0x01, 0x61, 0x0c, 0x48, 0x0d, 0x49, +0x67, 0x23, 0x9b, 0x01, 0xc2, 0x18, 0x05, 0xc1, 0x08, 0x39, 0x05, 0x4b, +0xc2, 0x18, 0xc8, 0x60, 0x8a, 0x60, 0x08, 0x61, 0x70, 0x47, 0x00, 0x00, +0x58, 0x1f, 0x21, 0x40, 0x48, 0x2e, 0x00, 0x80, 0xfc, 0x1f, 0x00, 0x00, +0x58, 0xef, 0x20, 0x40, 0x34, 0x2e, 0x00, 0x80, 0xfc, 0x2f, 0x00, 0x00, +0x58, 0x3f, 0x21, 0x40, 0x5c, 0x2e, 0x00, 0x80, 0x90, 0xb4, 0x00, 0x21, +0x40, 0x4c, 0x00, 0x20, 0x0a, 0x01, 0x12, 0x19, 0x19, 0x23, 0xdb, 0x01, +0xd2, 0x18, 0xd0, 0x62, 0x10, 0x63, 0x50, 0x63, 0x90, 0x63, 0x01, 0x31, +0x03, 0x29, 0xf3, 0xd3, 0x3a, 0x49, 0xc0, 0x46, 0x08, 0x63, 0x48, 0x63, +0x88, 0x63, 0x20, 0x60, 0x01, 0x21, 0xe3, 0x1d, 0x59, 0x33, 0x60, 0x60, +0x19, 0x71, 0x18, 0x72, 0x98, 0x71, 0x98, 0x72, 0x59, 0x71, 0x58, 0x72, +0xd8, 0x71, 0xd8, 0x72, 0xe2, 0x1d, 0x49, 0x32, 0x11, 0x73, 0x19, 0x70, +0x90, 0x73, 0x98, 0x70, 0x51, 0x73, 0x59, 0x70, 0xd0, 0x73, 0xd8, 0x70, +0x11, 0x71, 0x11, 0x72, 0x90, 0x71, 0x90, 0x72, 0x50, 0x71, 0x50, 0x72, +0xd0, 0x71, 0xd0, 0x72, 0x18, 0x73, 0x02, 0x22, 0xe7, 0x1d, 0x69, 0x37, +0x3a, 0x70, 0x99, 0x73, 0xba, 0x70, 0x58, 0x73, 0x78, 0x70, 0xd8, 0x73, +0xf8, 0x70, 0x39, 0x71, 0x3a, 0x72, 0xb9, 0x71, 0xb9, 0x72, 0x78, 0x71, +0x7a, 0x72, 0xf9, 0x71, 0xf9, 0x72, 0x39, 0x73, 0xe3, 0x1d, 0x79, 0x33, +0x1a, 0x70, 0xb9, 0x73, 0x99, 0x70, 0x78, 0x73, 0x5a, 0x70, 0xf9, 0x73, +0xd9, 0x70, 0x1a, 0x71, 0x1a, 0x72, 0x99, 0x71, 0x9a, 0x72, 0x58, 0x71, +0x5a, 0x72, 0xd9, 0x71, 0xda, 0x72, 0x19, 0x73, 0xe7, 0x1d, 0x89, 0x37, +0x3a, 0x70, 0x99, 0x73, 0xb9, 0x70, 0x58, 0x73, 0x7a, 0x70, 0xd9, 0x73, +0xf9, 0x70, 0x39, 0x71, 0x3a, 0x72, 0xb9, 0x71, 0xb9, 0x72, 0x78, 0x71, +0x7a, 0x72, 0xf9, 0x71, 0xf9, 0x72, 0x3a, 0x73, 0xe3, 0x1d, 0x99, 0x33, +0x1a, 0x70, 0xb9, 0x73, 0x9a, 0x70, 0x78, 0x73, 0x5a, 0x70, 0xf9, 0x73, +0xda, 0x70, 0x19, 0x71, 0x1a, 0x72, 0x99, 0x71, 0x99, 0x72, 0x58, 0x71, +0x5a, 0x72, 0xd9, 0x71, 0xd9, 0x72, 0x20, 0x61, 0xe0, 0x60, 0x60, 0x61, +0xa0, 0x60, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x00, 0xa0, 0x1c, 0x00, 0x80, +0xe8, 0x19, 0x00, 0x80, 0x81, 0x20, 0x00, 0x02, 0x01, 0x49, 0xc0, 0x46, +0x88, 0x62, 0x70, 0x47, 0xc0, 0x00, 0x14, 0x00, 0x09, 0x49, 0x0a, 0x4b, +0xc8, 0x18, 0x04, 0x3b, 0xc9, 0x18, 0x08, 0x60, 0x00, 0x21, 0xc2, 0x1d, 0x29, 0x32, 0xc2, 0x61, 0x10, 0x1c, 0x01, 0x31, 0x08, 0x29, 0xf8, 0xd3, 0xc1, 0x1f, 0x29, 0x39, 0x00, 0x20, 0xc8, 0x61, 0x70, 0x47, 0x00, 0x00, -0xe8, 0x0d, 0x00, 0x80, 0x06, 0x48, 0x07, 0x49, 0xc0, 0x46, 0x08, 0x80, -0x48, 0x80, 0x00, 0x20, 0x88, 0x80, 0xc8, 0x80, 0x88, 0x60, 0x04, 0x49, -0xc0, 0x46, 0x48, 0x61, 0x88, 0x61, 0x70, 0x47, 0xff, 0xff, 0x00, 0x00, -0xc8, 0x29, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, 0x00, 0x21, 0x06, 0x48, -0xc2, 0x1d, 0x19, 0x32, 0xc1, 0x60, 0x01, 0x61, 0xc1, 0x61, 0x01, 0x62, -0x11, 0x71, 0xff, 0x30, 0x01, 0x30, 0x41, 0x62, 0x70, 0x47, 0x00, 0x00, -0xec, 0x05, 0x00, 0x80, 0x09, 0x48, 0x0a, 0x4b, 0xc0, 0x46, 0x18, 0x60, -0x00, 0x21, 0xc2, 0x1d, 0x4d, 0x32, 0xc2, 0x60, +0x68, 0x0e, 0x00, 0x80, 0x84, 0x09, 0x00, 0x00, 0x06, 0x48, 0x07, 0x49, +0xc0, 0x46, 0x08, 0x80, 0x48, 0x80, 0x00, 0x20, 0x88, 0x80, 0xc8, 0x80, +0x88, 0x60, 0x04, 0x49, 0xc0, 0x46, 0x48, 0x61, 0x88, 0x61, 0x70, 0x47, +0xff, 0xff, 0x00, 0x00, 0x4c, 0x2a, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80, +0x00, 0x21, 0x06, 0x48, 0xc2, 0x1d, 0x19, 0x32, 0xc1, 0x60, 0x01, 0x61, +0xc1, 0x61, 0x01, 0x62, 0x11, 0x71, 0xff, 0x30, 0x01, 0x30, 0x41, 0x62, +0x70, 0x47, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, 0x09, 0x48, 0x0a, 0x4b, +0xc0, 0x46, 0x18, 0x60, 0x00, 0x21, 0xc2, 0x1d, 0x4d, 0x32, 0xc2, 0x60, 0x10, 0x1c, 0x01, 0x31, 0x14, 0x29, 0xf8, 0xd3, 0xc1, 0x1f, 0x4d, 0x39, 0x00, 0x20, 0xc8, 0x60, 0x58, 0x60, 0x98, 0x60, 0x70, 0x47, 0x00, 0x00, -0x58, 0x07, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, 0x00, 0xb5, 0x0c, 0x49, -0x0c, 0x48, 0xfd, 0xf7, 0xea, 0xf8, 0x0c, 0x48, 0x00, 0x6a, 0x01, 0x23, -0xdb, 0x03, 0x98, 0x43, 0x0a, 0x49, 0xc0, 0x46, 0x08, 0x62, 0x0a, 0x48, -0xc1, 0x68, 0x01, 0x29, 0x06, 0xd1, 0x80, 0x23, 0xc1, 0x6f, 0x19, 0x43, -0xc1, 0x67, 0x07, 0x48, 0xc0, 0x46, 0x01, 0x60, 0x08, 0xbc, 0x18, 0x47, -0x59, 0xcd, 0x21, 0x40, 0x61, 0xa1, 0x21, 0x40, 0xc0, 0x00, 0x18, 0x40, -0xc0, 0x00, 0x18, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, -0x00, 0xb5, 0x10, 0x48, 0xc1, 0x68, 0x01, 0x29, 0x06, 0xd1, 0x80, 0x23, -0xc1, 0x6f, 0x99, 0x43, 0xc1, 0x67, 0x0d, 0x48, 0xc0, 0x46, 0x01, 0x60, -0x0c, 0x4b, 0x0d, 0x48, 0x0d, 0x4a, 0x00, 0x21, 0xfd, 0xf7, 0xb9, 0xf8, -0x0c, 0x48, 0x41, 0x8d, 0x01, 0x31, 0x41, 0x85, 0x00, 0x21, 0xc1, 0x85, -0x0a, 0x48, 0x00, 0x6a, 0x01, 0x23, 0xdb, 0x03, 0x18, 0x43, 0x09, 0x49, -0xc0, 0x46, 0x08, 0x62, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, -0x00, 0x01, 0x11, 0x00, 0xf1, 0xcc, 0x21, 0x40, 0x61, 0xa1, 0x21, 0x40, +0xd8, 0x07, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80, +0x00, 0xb5, 0x0b, 0x49, 0x0b, 0x48, 0xfc, 0xf7, 0x3a, 0xfd, 0x0b, 0x48, +0x00, 0x6a, 0x01, 0x23, 0xdb, 0x03, 0x98, 0x43, 0x09, 0x49, 0xc0, 0x46, +0x08, 0x62, 0x09, 0x48, 0xc1, 0x68, 0x01, 0x29, 0x04, 0xd1, 0xc0, 0x6f, +0x80, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x08, 0xbc, 0x18, 0x47, +0x8d, 0xd5, 0x21, 0x40, 0xc1, 0xa8, 0x21, 0x40, 0xc0, 0x00, 0x18, 0x40, +0xc0, 0x00, 0x18, 0x00, 0x68, 0x0e, 0x00, 0x80, 0x00, 0xb5, 0x0f, 0x48, +0xc1, 0x68, 0x01, 0x29, 0x04, 0xd1, 0xc0, 0x6f, 0x80, 0x23, 0x01, 0x68, +0x99, 0x43, 0x01, 0x60, 0x0b, 0x4b, 0x0c, 0x48, 0x0c, 0x4a, 0x00, 0x21, +0xfc, 0xf7, 0x0f, 0xfd, 0x0b, 0x48, 0x41, 0x8d, 0x01, 0x31, 0x41, 0x85, +0x00, 0x21, 0xc1, 0x85, 0x09, 0x48, 0x00, 0x6a, 0x01, 0x23, 0xdb, 0x03, +0x18, 0x43, 0x08, 0x49, 0xc0, 0x46, 0x08, 0x62, 0x08, 0xbc, 0x18, 0x47, +0x68, 0x0e, 0x00, 0x80, 0x25, 0xd5, 0x21, 0x40, 0xc1, 0xa8, 0x21, 0x40, 0xb8, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x00, 0x18, 0x40, -0xc0, 0x00, 0x18, 0x00, 0xf0, 0xb5, 0xfe, 0xf7, 0xa3, 0xfe, 0x19, 0x4c, -0x10, 0x26, 0xe0, 0x68, 0x01, 0x28, 0x05, 0xd1, 0x60, 0x88, 0x00, 0x28, -0x02, 0xd1, 0x19, 0x20, 0xa0, 0x67, 0x00, 0xe0, 0xa6, 0x67, 0x00, 0x20, -0x07, 0x23, 0x5b, 0x02, 0xe5, 0x18, 0xc1, 0x43, 0xa8, 0x61, 0x29, 0x62, -0x59, 0x08, 0xa1, 0x27, 0x7f, 0x03, 0x79, 0x60, 0x0f, 0x21, 0x79, 0x60, -0xe1, 0x1d, 0xb9, 0x31, 0x08, 0x70, 0x01, 0x20, 0xb8, 0x60, 0x40, 0x02, -0xb8, 0x60, 0x00, 0xf0, 0x47, 0xfa, 0x00, 0xf0, 0xd9, 0xfa, 0x04, 0x20, -0xb8, 0x60, 0x07, 0x20, 0x78, 0x61, 0x7e, 0x60, 0x1b, 0x23, 0xdb, 0x01, -0xe0, 0x18, 0x40, 0x8b, 0x04, 0x23, 0x18, 0x40, 0xa8, 0x62, 0xf0, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x80, 0xb4, 0x02, 0x1c, -0x00, 0x20, 0xff, 0x23, 0x01, 0x33, 0x9a, 0x42, 0x08, 0xd0, 0x01, 0x29, -0x00, 0xd1, 0x01, 0x20, 0x00, 0x2a, 0x01, 0xd1, 0x02, 0x23, 0x18, 0x43, -0x80, 0xbc, 0x70, 0x47, 0x18, 0x49, 0xca, 0x68, 0x18, 0x4b, 0x01, 0x2a, -0x0b, 0xd1, 0x4a, 0x88, 0x00, 0x2a, 0x08, 0xd1, 0xd9, 0x8a, 0x0a, 0x09, -0x00, 0xd3, 0x02, 0x20, 0x49, 0x09, 0xef, 0xd3, 0x01, 0x23, 0x18, 0x43, -0xec, 0xe7, 0x0a, 0x79, 0x00, 0x2a, 0x03, 0xd0, 0x18, 0x8a, 0x80, 0x07, -0x80, 0x0f, 0xe5, 0xe7, 0x6d, 0x23, 0x5b, 0x01, 0xc9, 0x18, 0x0a, 0x88, -0xff, 0x27, 0x01, 0x37, 0x17, 0x40, 0x0b, 0x49, 0x49, 0x88, 0x03, 0xd0, -0x4b, 0x0a, 0x01, 0xd3, 0x03, 0x20, 0xd7, 0xe7, 0x13, 0x0a, 0x03, 0xd3, -0x0b, 0x0a, 0x01, 0xd3, 0x02, 0x20, 0xd1, 0xe7, 0xd2, 0x09, 0xcf, 0xd3, -0xc9, 0x09, 0xcd, 0xd3, 0x01, 0x20, 0xcb, 0xe7, 0xe8, 0x0d, 0x00, 0x80, -0xa8, 0x1b, 0x00, 0x80, 0x88, 0x1b, 0x00, 0x80, 0xf0, 0xb5, 0xc1, 0xb0, -0x01, 0x20, 0x00, 0x07, 0x52, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x52, 0x48, -0x42, 0x69, 0x40, 0x0d, 0xa1, 0x21, 0x49, 0x03, 0x48, 0x60, 0x50, 0x48, -0xc0, 0x6a, 0x50, 0x4b, 0x18, 0x43, 0x00, 0x21, 0x03, 0x03, 0x1b, 0x0b, -0x4e, 0x4c, 0x27, 0x6f, 0x3d, 0x03, 0x2d, 0x0b, +0xc0, 0x00, 0x18, 0x00, 0xf0, 0xb5, 0xfe, 0xf7, 0x9b, 0xfe, 0x1b, 0x4c, +0x10, 0x26, 0xe0, 0x68, 0x01, 0x28, 0x08, 0xd1, 0x60, 0x88, 0x00, 0x28, +0x05, 0xd1, 0x20, 0x79, 0x00, 0x28, 0x02, 0xd1, 0x19, 0x20, 0xa0, 0x67, +0x00, 0xe0, 0xa6, 0x67, 0x00, 0x20, 0x07, 0x23, 0x5b, 0x02, 0xe5, 0x18, +0xc1, 0x43, 0xe8, 0x61, 0x69, 0x62, 0x59, 0x08, 0xa1, 0x27, 0x7f, 0x03, +0x79, 0x60, 0x0f, 0x21, 0x79, 0x60, 0xe1, 0x1d, 0xb9, 0x31, 0x08, 0x71, +0x01, 0x20, 0xb8, 0x60, 0x40, 0x02, 0xb8, 0x60, 0x00, 0xf0, 0x4c, 0xfa, +0x00, 0xf0, 0xf0, 0xfa, 0x04, 0x20, 0xb8, 0x60, 0x07, 0x20, 0x78, 0x61, +0x7e, 0x60, 0x1b, 0x23, 0xdb, 0x01, 0xe0, 0x18, 0xc0, 0x8b, 0x04, 0x23, +0x18, 0x40, 0xe8, 0x62, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x68, 0x0e, 0x00, 0x80, 0x90, 0xb4, 0x02, 0x1c, 0x00, 0x20, 0xff, 0x23, +0x01, 0x33, 0x9a, 0x42, 0x08, 0xd0, 0x01, 0x29, 0x00, 0xd1, 0x01, 0x20, +0x00, 0x2a, 0x01, 0xd1, 0x02, 0x23, 0x18, 0x43, 0x90, 0xbc, 0x70, 0x47, +0x1b, 0x4a, 0xd7, 0x68, 0x1a, 0x4b, 0x19, 0x79, 0x1c, 0x1c, 0x37, 0x23, +0x9b, 0x01, 0xe3, 0x18, 0x01, 0x2f, 0x0d, 0xd1, 0x57, 0x88, 0x00, 0x2f, +0x0a, 0xd1, 0x00, 0x29, 0x0a, 0xd1, 0x59, 0x8b, 0x0a, 0x09, 0x00, 0xd3, +0x02, 0x20, 0x49, 0x09, 0xe8, 0xd3, 0x01, 0x23, 0x18, 0x43, 0xe5, 0xe7, +0x00, 0x29, 0x03, 0xd0, 0x98, 0x8a, 0x80, 0x07, 0x80, 0x0f, 0xdf, 0xe7, +0x6d, 0x23, 0x5b, 0x01, 0xd1, 0x18, 0x8a, 0x88, 0xff, 0x27, 0x01, 0x37, +0x17, 0x40, 0x0a, 0x49, 0xc9, 0x88, 0x03, 0xd0, 0x4b, 0x0a, 0x01, 0xd3, +0x03, 0x20, 0xd1, 0xe7, 0x13, 0x0a, 0x03, 0xd3, 0x0b, 0x0a, 0x01, 0xd3, +0x02, 0x20, 0xcb, 0xe7, 0xd2, 0x09, 0xc9, 0xd3, 0xc9, 0x09, 0xc7, 0xd3, +0x01, 0x20, 0xc5, 0xe7, 0x68, 0x0e, 0x00, 0x80, 0x08, 0x1c, 0x00, 0x80, +0xf0, 0xb5, 0xc1, 0xb0, 0x01, 0x20, 0x00, 0x07, 0x52, 0x49, 0xc0, 0x46, +0x08, 0x60, 0x52, 0x48, 0x42, 0x69, 0x40, 0x0d, 0xa1, 0x21, 0x49, 0x03, +0x48, 0x60, 0x50, 0x48, 0xc0, 0x6a, 0x50, 0x4b, 0x18, 0x43, 0x00, 0x21, +0x03, 0x03, 0x1b, 0x0b, 0x4e, 0x4c, 0x27, 0x6f, 0x3d, 0x03, 0x2d, 0x0b, 0xe7, 0x1d, 0x79, 0x37, 0xab, 0x42, 0x1c, 0xd0, 0xe3, 0x1d, 0x79, 0x33, -0xdb, 0x69, 0xc0, 0x46, 0x40, 0x93, 0x01, 0x23, 0x9b, 0x07, 0x03, 0x43, -0x1b, 0x68, 0xcc, 0x00, 0x6e, 0x46, 0x33, 0x51, 0x01, 0x23, 0x9b, 0x07, -0x06, 0x1d, 0x33, 0x43, 0x1b, 0x68, 0x6c, 0x44, 0x63, 0x60, 0x08, 0x30, -0x01, 0x31, 0x40, 0x9b, 0x83, 0x42, 0x00, 0xd8, 0x3f, 0x48, 0x03, 0x03, -0x1b, 0x0b, 0xab, 0x42, 0xe7, 0xd1, 0x00, 0x20, 0x01, 0x23, 0x1b, 0x03, -0x13, 0x40, 0x3c, 0x4c, 0x03, 0xd0, 0x63, 0x6a, 0x01, 0x33, 0x63, 0x62, -0x09, 0xe0, 0x13, 0x0b, 0x03, 0xd3, 0x23, 0x6a, 0x01, 0x33, 0x23, 0x62, -0x03, 0xe0, 0x37, 0x4b, 0x5c, 0x6d, 0x01, 0x34, 0x5c, 0x65, 0x00, 0x29, -0x09, 0xd0, 0x03, 0x1c, 0xdc, 0x00, 0x23, 0x1c, 0x6b, 0x44, 0x5c, 0x68, -0x01, 0x30, 0x23, 0x0d, 0x01, 0xd2, 0x88, 0x42, 0xf5, 0xd1, 0x30, 0x4c, -0x25, 0x68, 0x6b, 0x0c, 0x05, 0xd2, 0x23, 0x68, 0x1b, 0x0c, 0x08, 0xd1, -0x24, 0x68, 0xa3, 0x0a, 0x05, 0xd3, 0x20, 0x24, 0x2b, 0x4b, 0xc0, 0x46, -0x5c, 0x62, 0x00, 0x24, 0x5c, 0x62, 0x25, 0x4b, 0x23, 0x4c, 0x51, 0x26, -0xb6, 0x03, 0x23, 0x67, 0x33, 0x61, 0xfd, 0x69, 0xc0, 0x46, 0x75, 0x61, -0x02, 0x25, 0xa1, 0x26, 0x76, 0x03, 0x75, 0x60, 0x01, 0x25, 0xb5, 0x60, -0xe6, 0x1d, 0xb9, 0x36, 0x35, 0x70, 0x88, 0x42, 0x21, 0xd0, 0x25, 0x1c, -0xc3, 0x00, 0x6c, 0x46, 0xe4, 0x58, 0x2e, 0x6f, 0x6b, 0x44, 0x34, 0x60, -0x5b, 0x68, 0x2c, 0x6f, 0xc0, 0x46, 0x63, 0x60, 0x2b, 0x6f, 0x08, 0x33, -0x2b, 0x67, 0xfc, 0x69, 0xa3, 0x42, 0x02, 0xd3, 0x12, 0x4b, 0xc0, 0x46, -0x2b, 0x67, 0x03, 0x1c, 0xdb, 0x00, 0x6b, 0x44, 0x5c, 0x68, 0x01, 0x30, -0x23, 0x0d, 0x04, 0xd3, 0x51, 0x24, 0xa4, 0x03, 0x2b, 0x6f, 0xc0, 0x46, -0xa3, 0x61, 0x88, 0x42, 0xde, 0xd1, 0x10, 0x0b, 0x03, 0xd3, 0x0e, 0x49, -0x01, 0x20, 0xfc, 0xf7, 0x72, 0xff, 0x41, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x01, 0x14, 0x40, -0x00, 0x40, 0x14, 0x40, 0x00, 0x00, 0x20, 0x40, 0xe8, 0x0d, 0x00, 0x80, -0x24, 0xa7, 0x20, 0x40, 0x10, 0x2a, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, -0x00, 0x00, 0x10, 0x40, 0xc0, 0x00, 0x18, 0x00, 0x49, 0x4f, 0xff, 0xff, -0xf0, 0xb4, 0x00, 0x21, 0x00, 0x23, 0x07, 0x22, 0x06, 0x24, 0x47, 0x4f, -0xc0, 0x46, 0x3c, 0x61, 0x3a, 0x61, 0x01, 0x33, 0x20, 0x2b, 0xf9, 0xd3, -0x04, 0x25, 0x3d, 0x61, 0x05, 0x23, 0x3b, 0x61, 0x3c, 0x61, 0x3a, 0x61, -0x3c, 0x61, 0x3a, 0x61, 0x3d, 0x61, 0x3b, 0x61, 0x3f, 0x4d, 0xab, 0x6f, -0xde, 0x08, 0x02, 0x23, 0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, 0x3b, 0x61, -0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f, 0x9e, 0x08, 0x02, 0x23, +0x1b, 0x6a, 0xc0, 0x46, 0x40, 0x93, 0x01, 0x23, 0x9b, 0x07, 0x03, 0x43, +0x1b, 0x68, 0xcc, 0x00, 0x6e, 0x46, 0x33, 0x51, +0x01, 0x23, 0x9b, 0x07, 0x06, 0x1d, 0x33, 0x43, 0x1b, 0x68, 0x6c, 0x44, +0x63, 0x60, 0x08, 0x30, 0x01, 0x31, 0x40, 0x9b, 0x83, 0x42, 0x00, 0xd8, +0x3f, 0x48, 0x03, 0x03, 0x1b, 0x0b, 0xab, 0x42, 0xe7, 0xd1, 0x00, 0x20, +0x01, 0x23, 0x1b, 0x03, 0x13, 0x40, 0x3c, 0x4c, 0x03, 0xd0, 0x63, 0x6a, +0x01, 0x33, 0x63, 0x62, 0x09, 0xe0, 0x13, 0x0b, 0x03, 0xd3, 0x23, 0x6a, +0x01, 0x33, 0x23, 0x62, 0x03, 0xe0, 0x37, 0x4b, 0x5c, 0x6d, 0x01, 0x34, +0x5c, 0x65, 0x00, 0x29, 0x09, 0xd0, 0x03, 0x1c, 0xdc, 0x00, 0x23, 0x1c, +0x6b, 0x44, 0x5c, 0x68, 0x01, 0x30, 0x23, 0x0d, 0x01, 0xd2, 0x88, 0x42, +0xf5, 0xd1, 0x30, 0x4c, 0x25, 0x68, 0x6b, 0x0c, 0x05, 0xd2, 0x23, 0x68, +0x1b, 0x0c, 0x08, 0xd1, 0x24, 0x68, 0xa3, 0x0a, 0x05, 0xd3, 0x20, 0x24, +0x2b, 0x4b, 0xc0, 0x46, 0x5c, 0x62, 0x00, 0x24, 0x5c, 0x62, 0x25, 0x4b, +0x23, 0x4c, 0x51, 0x26, 0xb6, 0x03, 0x23, 0x67, 0x33, 0x61, 0x3d, 0x6a, +0xc0, 0x46, 0x75, 0x61, 0x02, 0x25, 0xa1, 0x26, 0x76, 0x03, 0x75, 0x60, +0x01, 0x25, 0xb5, 0x60, 0xe6, 0x1d, 0xb9, 0x36, 0x35, 0x71, 0x88, 0x42, +0x21, 0xd0, 0x25, 0x1c, 0xc3, 0x00, 0x6c, 0x46, 0xe4, 0x58, 0x2e, 0x6f, +0x6b, 0x44, 0x34, 0x60, 0x5b, 0x68, 0x2c, 0x6f, 0xc0, 0x46, 0x63, 0x60, +0x2b, 0x6f, 0x08, 0x33, 0x2b, 0x67, 0x3c, 0x6a, 0xa3, 0x42, 0x02, 0xd3, +0x12, 0x4b, 0xc0, 0x46, 0x2b, 0x67, 0x03, 0x1c, 0xdb, 0x00, 0x6b, 0x44, +0x5c, 0x68, 0x01, 0x30, 0x23, 0x0d, 0x04, 0xd3, 0x51, 0x24, 0xa4, 0x03, +0x2b, 0x6f, 0xc0, 0x46, 0xa3, 0x61, 0x88, 0x42, 0xde, 0xd1, 0x10, 0x0b, +0x03, 0xd3, 0x0e, 0x49, 0x01, 0x20, 0xfc, 0xf7, 0xc2, 0xfb, 0x41, 0xb0, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, +0x00, 0x01, 0x14, 0x40, 0x00, 0x40, 0x14, 0x40, 0x00, 0x00, 0x20, 0x40, +0x68, 0x0e, 0x00, 0x80, 0x24, 0xa7, 0x20, 0x40, 0xa4, 0x2a, 0x00, 0x80, +0xa0, 0x82, 0x20, 0x40, 0x00, 0x00, 0x10, 0x40, 0xc0, 0x00, 0x18, 0x00, +0xb5, 0x4f, 0xff, 0xff, 0xf0, 0xb4, 0x00, 0x21, 0x00, 0x23, 0x07, 0x22, +0x06, 0x24, 0x47, 0x4f, 0xc0, 0x46, 0x3c, 0x61, 0x3a, 0x61, 0x01, 0x33, +0x20, 0x2b, 0xf9, 0xd3, 0x04, 0x25, 0x3d, 0x61, 0x05, 0x23, 0x3b, 0x61, +0x3c, 0x61, 0x3a, 0x61, 0x3c, 0x61, 0x3a, 0x61, 0x3d, 0x61, 0x3b, 0x61, +0x3f, 0x4d, 0xab, 0x6f, 0xde, 0x08, 0x02, 0x23, 0x1e, 0x40, 0x04, 0x23, +0x33, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f, +0x9e, 0x08, 0x02, 0x23, 0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, 0x3b, 0x61, +0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f, 0x5e, 0x08, 0x02, 0x23, 0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x33, 0x43, -0x3b, 0x61, 0xab, 0x6f, 0x5e, 0x08, 0x02, 0x23, 0x1e, 0x40, 0x04, 0x23, -0x33, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0x02, 0x23, -0xae, 0x6f, 0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, 0x3b, 0x61, 0x05, 0x23, -0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f, 0x5d, 0x00, 0x02, 0x23, 0x1d, 0x40, -0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, -0xc5, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, -0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x85, 0x08, 0x02, 0x23, 0x1d, 0x40, -0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, +0x3b, 0x61, 0x02, 0x23, 0xae, 0x6f, 0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, +0x3b, 0x61, 0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f, 0x5d, 0x00, +0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, +0x2b, 0x43, 0x3b, 0x61, 0xc5, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, +0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x85, 0x08, +0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x45, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x02, 0x25, -0x05, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43, -0x3b, 0x61, 0x40, 0x00, 0x02, 0x23, 0x18, 0x40, 0x04, 0x23, 0x03, 0x43, -0x3b, 0x61, 0x05, 0x23, 0x18, 0x43, 0x38, 0x61, 0x00, 0x25, 0x3d, 0x61, -0x01, 0x23, 0x3b, 0x61, 0x3d, 0x61, 0x3b, 0x61, 0x00, 0x20, 0x3d, 0x61, -0x0d, 0x4b, 0x1b, 0x69, 0x49, 0x00, 0x1e, 0x1c, 0x02, 0x23, 0x33, 0x40, -0x19, 0x43, 0x01, 0x23, 0x3b, 0x61, 0x01, 0x30, 0x10, 0x28, 0xf2, 0xd3, -0x02, 0x20, 0x38, 0x61, 0x03, 0x20, 0x38, 0x61, 0x3c, 0x61, 0x3a, 0x61, -0x3c, 0x61, 0x3a, 0x61, 0x38, 0x61, 0x48, 0x08, 0xf0, 0xbc, 0x70, 0x47, -0x80, 0x00, 0x14, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x80, 0x00, 0x14, 0x40, -0xf0, 0xb4, 0x00, 0x24, 0x07, 0x23, 0x06, 0x27, 0x44, 0x4a, 0xc0, 0x46, -0x17, 0x61, 0x13, 0x61, 0x01, 0x34, 0x20, 0x2c, 0xf9, 0xd3, 0x04, 0x26, -0x16, 0x61, 0x05, 0x24, 0x14, 0x61, 0x17, 0x61, 0x07, 0x23, 0x13, 0x61, -0x16, 0x61, 0x14, 0x61, 0x17, 0x61, 0x13, 0x61, 0x3c, 0x4b, 0x9b, 0x6f, -0xdd, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, -0x25, 0x43, 0x15, 0x61, 0x37, 0x4b, 0x9b, 0x6f, 0x9d, 0x08, 0x02, 0x23, +0x05, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, +0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x40, 0x00, 0x02, 0x23, 0x18, 0x40, +0x04, 0x23, 0x03, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x18, 0x43, 0x38, 0x61, +0x00, 0x25, 0x3d, 0x61, 0x01, 0x23, 0x3b, 0x61, 0x3d, 0x61, 0x3b, 0x61, +0x00, 0x20, 0x3d, 0x61, 0x0d, 0x4b, 0x1b, 0x69, 0x49, 0x00, 0x1e, 0x1c, +0x02, 0x23, 0x33, 0x40, 0x19, 0x43, 0x01, 0x23, 0x3b, 0x61, 0x01, 0x30, +0x10, 0x28, 0xf2, 0xd3, 0x02, 0x20, 0x38, 0x61, 0x03, 0x20, 0x38, 0x61, +0x3c, 0x61, 0x3a, 0x61, 0x3c, 0x61, 0x3a, 0x61, 0x38, 0x61, 0x48, 0x08, +0xf0, 0xbc, 0x70, 0x47, 0x80, 0x00, 0x14, 0x00, 0x68, 0x0e, 0x00, 0x80, +0x80, 0x00, 0x14, 0x40, 0xf0, 0xb4, 0x00, 0x24, 0x07, 0x23, 0x06, 0x27, +0x44, 0x4a, 0xc0, 0x46, 0x17, 0x61, 0x13, 0x61, 0x01, 0x34, 0x20, 0x2c, +0xf9, 0xd3, 0x04, 0x26, 0x16, 0x61, 0x05, 0x24, 0x14, 0x61, 0x17, 0x61, +0x07, 0x23, 0x13, 0x61, 0x16, 0x61, 0x14, 0x61, 0x17, 0x61, 0x13, 0x61, +0x3c, 0x4b, 0x9b, 0x6f, 0xdd, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, +0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x37, 0x4b, 0x9b, 0x6f, +0x9d, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, +0x25, 0x43, 0x15, 0x61, 0x32, 0x4b, 0x9b, 0x6f, 0x5d, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, -0x32, 0x4b, 0x9b, 0x6f, 0x5d, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, -0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x2d, 0x4b, 0x9d, 0x6f, +0x2d, 0x4b, 0x9d, 0x6f, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, +0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x29, 0x4b, 0x9b, 0x6f, 0x5d, 0x00, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, -0x15, 0x61, 0x29, 0x4b, 0x9b, 0x6f, 0x5d, 0x00, 0x02, 0x23, 0x1d, 0x40, -0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0xc5, 0x08, +0x15, 0x61, 0xc5, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, +0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x85, 0x08, 0x02, 0x23, 0x1d, 0x40, +0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x45, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, -0x15, 0x61, 0x85, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, -0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x45, 0x08, 0x02, 0x23, 0x1d, 0x40, -0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x02, 0x25, -0x05, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, -0x40, 0x00, 0x02, 0x23, 0x18, 0x40, 0x03, 0x1c, 0x33, 0x43, 0x13, 0x61, -0x20, 0x43, 0x10, 0x61, 0x17, 0x61, 0x07, 0x23, 0x13, 0x61, 0x16, 0x61, -0x14, 0x61, 0x4c, 0x00, 0x00, 0x20, 0x0f, 0x21, 0x25, 0x1c, 0xcd, 0x40, -0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x13, 0x61, 0x05, 0x23, -0x2b, 0x43, 0x13, 0x61, 0x01, 0x30, 0x01, 0x39, 0x10, 0x28, 0xf1, 0xd3, -0x17, 0x61, 0x07, 0x23, 0x13, 0x61, 0x17, 0x61, 0x13, 0x61, 0x03, 0x20, -0x10, 0x61, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x00, -0xe8, 0x0d, 0x00, 0x80, 0xf0, 0xb5, 0x47, 0x48, 0x01, 0x89, 0x47, 0x4d, -0x07, 0x23, 0x5b, 0x02, 0xef, 0x18, 0xb9, 0x83, 0x40, 0x8b, 0xc0, 0x46, -0xf8, 0x83, 0x28, 0x79, 0x00, 0x28, 0x01, 0xd0, 0x00, 0x20, 0xb8, 0x83, -0xe8, 0x68, 0x01, 0x28, 0x06, 0xd1, 0x68, 0x88, 0x00, 0x28, 0x03, 0xd1, -0xf9, 0x21, 0x12, 0x20, 0xff, 0xf7, 0x54, 0xff, 0x01, 0x21, 0xc9, 0x03, -0x00, 0x20, 0xff, 0xf7, 0x4f, 0xff, 0x00, 0x24, 0x7d, 0x26, 0xf6, 0x00, -0x00, 0xe0, 0x01, 0x34, 0x00, 0x20, 0xff, 0xf7, 0xad, 0xfe, 0x00, 0x0c, -0x01, 0xd3, 0xb4, 0x42, 0xf7, 0xd3, 0x00, 0x24, -0x05, 0xe0, 0x03, 0x21, 0x09, 0x03, 0x00, 0x20, 0xff, 0xf7, 0x3c, 0xff, -0x01, 0x34, 0x00, 0x20, 0xff, 0xf7, 0x9e, 0xfe, 0x40, 0x0b, 0x01, 0xd2, -0xb4, 0x42, 0xf2, 0xd3, 0x04, 0x20, 0xff, 0xf7, 0x97, 0xfe, 0xff, 0x23, -0xe1, 0x33, 0x98, 0x43, 0x01, 0x21, 0x01, 0x43, 0xb8, 0x8b, 0xff, 0x23, -0x01, 0x33, 0x98, 0x42, 0x03, 0xd1, 0x2f, 0x23, 0x5b, 0x01, 0x19, 0x43, -0x16, 0xe0, 0x01, 0x28, 0x09, 0xd1, 0xf8, 0x8b, 0x01, 0x28, 0x03, 0xd1, -0x23, 0x23, 0x5b, 0x01, 0x19, 0x43, 0x0d, 0xe0, 0x20, 0x23, 0x19, 0x43, -0x0a, 0xe0, 0x00, 0x28, 0x08, 0xd1, 0xf8, 0x8b, 0x01, 0x28, 0x03, 0xd1, -0x0b, 0x23, 0xdb, 0x01, 0x19, 0x43, 0x01, 0xe0, 0x80, 0x23, 0x19, 0x43, -0x04, 0x20, 0xff, 0xf7, 0x09, 0xff, 0x09, 0x21, 0x49, 0x02, 0x00, 0x20, -0xff, 0xf7, 0x04, 0xff, 0xe8, 0x68, 0x00, 0x28, 0x0c, 0xd1, 0x00, 0x21, -0x1b, 0x20, 0xff, 0xf7, 0xfd, 0xfe, 0x1a, 0x20, 0xff, 0xf7, 0x60, 0xfe, -0x01, 0x21, 0xc9, 0x03, 0x01, 0x43, 0x1a, 0x20, 0xff, 0xf7, 0xf4, 0xfe, -0x00, 0x27, 0x03, 0xe0, 0x08, 0x2f, 0x01, 0xd3, 0x0f, 0x2f, 0x08, 0xd9, -0x38, 0x1c, 0xff, 0xf7, 0x51, 0xfe, 0x79, 0x00, 0x49, 0x19, 0x1b, 0x23, -0xdb, 0x01, 0xc9, 0x18, 0x08, 0x83, 0x01, 0x37, 0x20, 0x2f, 0xef, 0xd3, -0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x70, 0x67, 0x21, 0x40, -0xe8, 0x0d, 0x00, 0x80, 0x81, 0xb0, 0x13, 0x48, 0x01, 0x68, 0xc0, 0x46, -0x00, 0x91, 0x41, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x81, 0x68, 0xc0, 0x46, -0x00, 0x91, 0xc1, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x01, 0x69, 0xc0, 0x46, -0x00, 0x91, 0x41, 0x69, 0xc0, 0x46, 0x00, 0x91, 0x81, 0x69, 0xc0, 0x46, -0x00, 0x91, 0xc1, 0x69, 0xc0, 0x46, 0x00, 0x91, 0x01, 0x6a, 0xc0, 0x46, -0x00, 0x91, 0x41, 0x6a, 0xc0, 0x46, 0x00, 0x91, 0x81, 0x6a, 0xc0, 0x46, -0x00, 0x91, 0xc0, 0x6a, 0xc0, 0x46, 0x00, 0x90, 0x01, 0xb0, 0x70, 0x47, -0x00, 0x08, 0x14, 0x40, 0xf0, 0xb5, 0x83, 0xb0, 0x66, 0x4e, 0x1b, 0x23, -0xdb, 0x01, 0xf7, 0x18, 0x78, 0x8b, 0x04, 0x22, 0x02, 0x40, 0x02, 0x92, -0x07, 0x23, 0x5b, 0x02, 0xf4, 0x18, 0xa0, 0x8b, 0xc0, 0x46, 0x01, 0x90, -0xe0, 0x8b, 0xc0, 0x46, 0x00, 0x90, 0x00, 0x25, 0x03, 0xe0, 0x08, 0x2d, -0x01, 0xd3, 0x0f, 0x2d, 0x08, 0xd9, 0x28, 0x1c, 0xff, 0xf7, 0xfa, 0xfd, -0x69, 0x00, 0x89, 0x19, 0x1b, 0x23, 0xdb, 0x01, 0xc9, 0x18, 0x08, 0x83, -0x01, 0x35, 0x20, 0x2d, 0xef, 0xd3, 0xa0, 0x69, 0x00, 0x28, 0x15, 0xd0, -0x54, 0x4e, 0x20, 0x25, 0x01, 0x3d, 0x52, 0x49, 0xa0, 0x69, 0x30, 0x40, -0x0b, 0xd0, 0x68, 0x00, 0x40, 0x18, 0x37, 0x23, 0x9b, 0x01, 0xc0, 0x18, -0x01, 0x8b, 0x28, 0x1c, 0xff, 0xf7, 0x78, 0xfe, 0xa0, 0x69, 0xb0, 0x43, -0xa0, 0x61, 0x76, 0x08, 0x00, 0x2d, 0xeb, 0xd1, 0x01, 0x20, 0xff, 0xf7, -0xd5, 0xfd, 0x01, 0x1c, 0x46, 0x48, 0xc0, 0x46, 0x79, 0x83, 0x79, 0x8b, -0xca, 0x08, 0x22, 0xd3, 0xc2, 0x68, 0x01, 0x2a, 0x10, 0xd1, 0x40, 0x88, -0x00, 0x28, 0x1c, 0xd1, 0x01, 0x98, 0x42, 0x4a, 0x00, 0x28, 0x05, 0xd0, -0x01, 0x28, 0x16, 0xd1, 0xd0, 0x8a, 0xc0, 0x08, 0x13, 0xd2, 0x0f, 0xe0, -0xd0, 0x8a, 0x00, 0x09, 0x0f, 0xd2, 0x0b, 0xe0, 0x02, 0x79, 0x00, 0x2a, -0x0b, 0xd1, 0x6d, 0x23, 0x5b, 0x01, 0xc0, 0x18, 0x02, 0x88, 0x40, 0x88, -0x10, 0x40, 0x40, 0x09, 0x00, 0x07, 0x02, 0xd1, 0x04, 0x23, 0x99, 0x43, -0x79, 0x83, 0x78, 0x8b, 0x04, 0x21, 0x01, 0x40, -0x02, 0x9a, 0x1f, 0xd0, 0x39, 0x8b, 0x4a, 0x0b, 0x27, 0xd3, 0x80, 0x09, -0x25, 0xd3, 0xff, 0x23, 0x01, 0x98, 0x01, 0x33, 0x98, 0x42, 0x20, 0xd0, -0x00, 0x25, 0x00, 0x98, 0x01, 0x28, 0x00, 0xd1, 0x05, 0x02, 0x01, 0x98, -0x00, 0x28, 0x02, 0xd1, 0x01, 0x23, 0x5b, 0x03, 0x1d, 0x43, 0xa9, 0x42, -0x13, 0xd0, 0x00, 0x20, 0x29, 0x1c, 0xff, 0xf7, 0x25, 0xfe, 0x3d, 0x83, -0x00, 0x20, 0xc0, 0x43, 0x20, 0x62, 0x0a, 0xe0, 0x38, 0x8b, 0x40, 0x0b, -0x07, 0xd2, 0x09, 0x21, 0x49, 0x02, 0x00, 0x20, 0xff, 0xf7, 0x18, 0xfe, -0x09, 0x20, 0x40, 0x02, 0x38, 0x83, 0x78, 0x8b, 0xc0, 0x08, 0x2d, 0xd3, -0x1b, 0x48, 0xc7, 0x6a, 0x01, 0x98, 0x00, 0x99, 0xff, 0xf7, 0x6a, 0xfc, -0xc2, 0x07, 0xd2, 0x0f, 0x18, 0x49, 0x03, 0xd0, 0x04, 0x23, 0xcd, 0x6d, -0x2b, 0x43, 0x03, 0xe0, 0x04, 0x23, 0xcd, 0x6d, 0x9d, 0x43, 0x2b, 0x1c, -0xcb, 0x65, 0x83, 0x08, 0x03, 0xd3, 0x02, 0x23, 0xcd, 0x6d, 0x2b, 0x43, -0x03, 0xe0, 0x02, 0x23, 0xcd, 0x6d, 0x9d, 0x43, 0x2b, 0x1c, 0xcb, 0x65, -0x21, 0x6a, 0x81, 0x42, 0x0c, 0xd0, 0x20, 0x62, 0x0c, 0x48, 0x00, 0x2a, -0x03, 0xd0, 0xff, 0x21, 0x21, 0x31, 0x39, 0x43, 0x03, 0xe0, 0xff, 0x23, -0x21, 0x33, 0x9f, 0x43, 0x39, 0x1c, 0xc1, 0x62, 0x03, 0xb0, 0xf0, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, -0xa8, 0x1b, 0x00, 0x80, 0x40, 0x00, 0x14, 0x40, 0x10, 0x2a, 0x00, 0x80, -0x40, 0x00, 0x14, 0x00, 0x90, 0xb4, 0x01, 0x22, 0x20, 0x28, 0x0f, 0xd2, -0x43, 0x00, 0x0f, 0x1c, 0x07, 0x49, 0x5c, 0x18, 0x37, 0x23, 0x9b, 0x01, -0xe3, 0x18, 0x1f, 0x83, 0x82, 0x40, 0x07, 0x23, 0x5b, 0x02, 0xc9, 0x18, -0x10, 0x1c, 0x8a, 0x69, 0x10, 0x43, 0x88, 0x61, 0x90, 0xbc, 0x70, 0x47, -0xe8, 0x0d, 0x00, 0x80, 0x0b, 0x48, 0x40, 0x69, 0x0b, 0x49, 0x49, 0x8b, -0x04, 0x22, 0x0a, 0x40, 0x0a, 0x49, 0x06, 0xd0, 0x01, 0x23, 0xdb, 0x02, -0x98, 0x43, 0x01, 0x23, 0xca, 0x6d, 0x1a, 0x43, 0x05, 0xe0, 0x01, 0x23, -0xdb, 0x02, 0x18, 0x43, 0xca, 0x6d, 0x52, 0x08, 0x52, 0x00, 0xca, 0x65, -0x70, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x40, 0x68, 0x1b, 0x00, 0x80, -0x10, 0x2a, 0x00, 0x80, 0x00, 0xb5, 0x84, 0xb0, 0xff, 0xf7, 0xde, 0xff, -0x01, 0x1c, 0x05, 0x20, 0x00, 0x90, 0x00, 0x20, 0x01, 0xab, 0x18, 0x80, -0x04, 0x3b, 0x58, 0x70, 0x1b, 0x22, 0x00, 0xab, 0x5a, 0x80, 0xd9, 0x80, -0x05, 0x49, 0xc9, 0x6d, 0xc0, 0x46, 0x02, 0x91, 0x03, 0x90, 0x68, 0x46, -0x00, 0x21, 0xfc, 0xf7, 0x9d, 0xfd, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, -0x10, 0x2a, 0x00, 0x80, 0x0d, 0x48, 0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2, -0x01, 0x68, 0x09, 0x0c, 0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x03, 0xd3, -0x09, 0x48, 0x00, 0x68, 0x00, 0x0c, 0x01, 0xe0, 0x08, 0x48, 0x80, 0x6c, -0x00, 0x04, 0x00, 0x0c, 0x07, 0x4b, 0x98, 0x42, 0x02, 0xd0, 0x02, 0x33, -0x98, 0x42, 0x01, 0xd1, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, +0x15, 0x61, 0x02, 0x25, 0x05, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, +0x25, 0x43, 0x15, 0x61, 0x40, 0x00, 0x02, 0x23, 0x18, 0x40, 0x03, 0x1c, +0x33, 0x43, 0x13, 0x61, 0x20, 0x43, 0x10, 0x61, 0x17, 0x61, 0x07, 0x23, +0x13, 0x61, 0x16, 0x61, 0x14, 0x61, 0x4c, 0x00, 0x00, 0x20, 0x0f, 0x21, +0x25, 0x1c, 0xcd, 0x40, 0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43, +0x13, 0x61, 0x05, 0x23, 0x2b, 0x43, 0x13, 0x61, 0x01, 0x30, 0x01, 0x39, +0x10, 0x28, 0xf1, 0xd3, 0x17, 0x61, 0x07, 0x23, 0x13, 0x61, 0x17, 0x61, +0x13, 0x61, 0x03, 0x20, 0x10, 0x61, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00, +0x80, 0x00, 0x14, 0x00, 0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb5, 0x4f, 0x4d, +0x08, 0x21, 0x02, 0x20, 0x2a, 0x1c, 0xfc, 0xf7, 0x75, 0xfa, 0x4d, 0x4c, +0x71, 0x23, 0x5b, 0x01, 0xe7, 0x18, 0x38, 0x80, 0x1a, 0x21, 0x02, 0x20, +0x2a, 0x1c, 0xfc, 0xf7, 0x6b, 0xfa, 0x78, 0x80, 0x20, 0x79, 0x00, 0x28, +0x0b, 0xd0, 0x00, 0x20, 0x38, 0x80, 0xe0, 0x68, 0x01, 0x28, 0x10, 0xd1, +0x44, 0x48, 0x00, 0x68, 0x01, 0x23, 0x9b, 0x02, 0x18, 0x43, 0x99, 0x02, +0x08, 0x60, 0xe0, 0x68, 0x01, 0x28, 0x06, 0xd1, 0x60, 0x88, 0x00, 0x28, +0x03, 0xd1, 0xf9, 0x21, 0x12, 0x20, 0xff, 0xf7, 0x43, 0xff, 0x01, 0x21, +0xc9, 0x03, 0x00, 0x20, 0xff, 0xf7, 0x3e, 0xff, 0x00, 0x25, 0x7d, 0x26, +0xf6, 0x00, 0x00, 0xe0, 0x01, 0x35, 0x00, 0x20, 0xff, 0xf7, 0x9c, 0xfe, +0x00, 0x0c, 0x01, 0xd3, 0xb5, 0x42, 0xf7, 0xd3, +0x00, 0x25, 0x05, 0xe0, 0x03, 0x21, 0x09, 0x03, 0x00, 0x20, 0xff, 0xf7, +0x2b, 0xff, 0x01, 0x35, 0x00, 0x20, 0xff, 0xf7, 0x8d, 0xfe, 0x40, 0x0b, +0x01, 0xd2, 0xb5, 0x42, 0xf2, 0xd3, 0x04, 0x20, 0xff, 0xf7, 0x86, 0xfe, +0xff, 0x23, 0xe1, 0x33, 0x98, 0x43, 0x01, 0x21, 0x01, 0x43, 0x38, 0x88, +0xff, 0x23, 0x01, 0x33, 0x98, 0x42, 0x03, 0xd1, 0x2f, 0x23, 0x5b, 0x01, +0x19, 0x43, 0x16, 0xe0, 0x01, 0x28, 0x09, 0xd1, 0x78, 0x88, 0x01, 0x28, +0x03, 0xd1, 0x23, 0x23, 0x5b, 0x01, 0x19, 0x43, 0x0d, 0xe0, 0x20, 0x23, +0x19, 0x43, 0x0a, 0xe0, 0x00, 0x28, 0x08, 0xd1, 0x78, 0x88, 0x01, 0x28, +0x03, 0xd1, 0x0b, 0x23, 0xdb, 0x01, 0x19, 0x43, 0x01, 0xe0, 0x80, 0x23, +0x19, 0x43, 0x04, 0x20, 0xff, 0xf7, 0xf8, 0xfe, 0x09, 0x21, 0x49, 0x02, +0x00, 0x20, 0xff, 0xf7, 0xf3, 0xfe, 0xe0, 0x68, 0x00, 0x28, 0x0c, 0xd1, +0x00, 0x21, 0x1b, 0x20, 0xff, 0xf7, 0xec, 0xfe, 0x1a, 0x20, 0xff, 0xf7, +0x4f, 0xfe, 0x01, 0x21, 0xc9, 0x03, 0x01, 0x43, 0x1a, 0x20, 0xff, 0xf7, +0xe3, 0xfe, 0x00, 0x27, 0x03, 0xe0, 0x08, 0x2f, 0x01, 0xd3, 0x0f, 0x2f, +0x08, 0xd9, 0x38, 0x1c, 0xff, 0xf7, 0x40, 0xfe, 0x79, 0x00, 0x09, 0x19, +0x1b, 0x23, 0xdb, 0x01, 0xc9, 0x18, 0x88, 0x83, 0x01, 0x37, 0x20, 0x2f, +0xef, 0xd3, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x79, 0xbf, 0x21, 0x40, +0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb0, 0x13, 0x48, +0x01, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x68, 0xc0, 0x46, 0x00, 0x91, +0x81, 0x68, 0xc0, 0x46, 0x00, 0x91, 0xc1, 0x68, 0xc0, 0x46, 0x00, 0x91, +0x01, 0x69, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x69, 0xc0, 0x46, 0x00, 0x91, +0x81, 0x69, 0xc0, 0x46, 0x00, 0x91, 0xc1, 0x69, 0xc0, 0x46, 0x00, 0x91, +0x01, 0x6a, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x6a, 0xc0, 0x46, 0x00, 0x91, +0x81, 0x6a, 0xc0, 0x46, 0x00, 0x91, 0xc0, 0x6a, 0xc0, 0x46, 0x00, 0x90, +0x01, 0xb0, 0x70, 0x47, 0x00, 0x08, 0x14, 0x40, 0xf0, 0xb5, 0x83, 0xb0, +0x68, 0x4d, 0x1b, 0x23, 0xdb, 0x01, 0xef, 0x18, 0xf8, 0x8b, 0x04, 0x22, +0x02, 0x40, 0x02, 0x92, 0x71, 0x23, 0x5b, 0x01, 0xe8, 0x18, 0x01, 0x88, +0xc0, 0x46, 0x01, 0x91, 0x40, 0x88, 0xc0, 0x46, 0x00, 0x90, 0x00, 0x24, +0x03, 0xe0, 0x08, 0x2c, 0x01, 0xd3, 0x0f, 0x2c, 0x08, 0xd9, 0x20, 0x1c, +0xff, 0xf7, 0xe8, 0xfd, 0x61, 0x00, 0x49, 0x19, 0x1b, 0x23, 0xdb, 0x01, +0xc9, 0x18, 0x88, 0x83, 0x01, 0x34, 0x20, 0x2c, 0xef, 0xd3, 0x58, 0x4c, +0xe0, 0x69, 0x00, 0x28, 0x15, 0xd0, 0x57, 0x4e, 0x20, 0x25, 0x01, 0x3d, +0x53, 0x49, 0xe0, 0x69, 0x30, 0x40, 0x0b, 0xd0, 0x68, 0x00, 0x40, 0x18, +0x37, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0x81, 0x8b, 0x28, 0x1c, 0xff, 0xf7, +0x65, 0xfe, 0xe0, 0x69, 0xb0, 0x43, 0xe0, 0x61, 0x76, 0x08, 0x00, 0x2d, +0xeb, 0xd1, 0x01, 0x20, 0xff, 0xf7, 0xc2, 0xfd, 0x48, 0x49, 0xc0, 0x46, +0xf8, 0x83, 0xf8, 0x8b, 0xc2, 0x08, 0x25, 0xd3, 0xca, 0x68, 0x01, 0x2a, +0x13, 0xd1, 0x0a, 0x79, 0x00, 0x2a, 0x1f, 0xd1, 0x49, 0x88, 0x00, 0x29, +0x1c, 0xd1, 0x01, 0x99, 0x43, 0x4a, 0x00, 0x29, 0x05, 0xd0, 0x01, 0x29, +0x16, 0xd1, 0x51, 0x8b, 0xc9, 0x08, 0x13, 0xd2, 0x0f, 0xe0, 0x51, 0x8b, +0x09, 0x09, 0x0f, 0xd2, 0x0b, 0xe0, 0x0a, 0x79, 0x00, 0x2a, 0x0b, 0xd1, +0x6d, 0x23, 0x5b, 0x01, 0xc9, 0x18, 0x8a, 0x88, 0xc9, 0x88, 0x11, 0x40, +0x49, 0x09, 0x09, 0x07, 0x02, 0xd1, 0x04, 0x23, +0x98, 0x43, 0xf8, 0x83, 0xf8, 0x8b, 0x04, 0x21, 0x01, 0x40, 0x02, 0x9a, +0x1f, 0xd0, 0xb9, 0x8b, 0x4a, 0x0b, 0x27, 0xd3, 0x80, 0x09, 0x25, 0xd3, +0xff, 0x23, 0x01, 0x98, 0x01, 0x33, 0x98, 0x42, 0x20, 0xd0, 0x00, 0x25, +0x00, 0x98, 0x01, 0x28, 0x00, 0xd1, 0x05, 0x02, 0x01, 0x98, 0x00, 0x28, +0x02, 0xd1, 0x01, 0x23, 0x5b, 0x03, 0x1d, 0x43, 0xa9, 0x42, 0x13, 0xd0, +0x00, 0x20, 0x29, 0x1c, 0xff, 0xf7, 0x10, 0xfe, 0xbd, 0x83, 0x00, 0x20, +0xc0, 0x43, 0x60, 0x62, 0x0a, 0xe0, 0xb8, 0x8b, 0x40, 0x0b, 0x07, 0xd2, +0x09, 0x21, 0x49, 0x02, 0x00, 0x20, 0xff, 0xf7, 0x03, 0xfe, 0x09, 0x20, +0x40, 0x02, 0xb8, 0x83, 0xf8, 0x8b, 0xc0, 0x08, 0x2d, 0xd3, 0x1d, 0x48, +0xc7, 0x6a, 0x01, 0x98, 0x00, 0x99, 0xff, 0xf7, 0x51, 0xfc, 0xc2, 0x07, +0xd2, 0x0f, 0x1a, 0x49, 0x03, 0xd0, 0x04, 0x23, 0xcd, 0x6d, 0x2b, 0x43, +0x03, 0xe0, 0x04, 0x23, 0xcd, 0x6d, 0x9d, 0x43, 0x2b, 0x1c, 0xcb, 0x65, +0x83, 0x08, 0x03, 0xd3, 0x02, 0x23, 0xcd, 0x6d, 0x2b, 0x43, 0x03, 0xe0, +0x02, 0x23, 0xcd, 0x6d, 0x9d, 0x43, 0x2b, 0x1c, 0xcb, 0x65, 0x61, 0x6a, +0x81, 0x42, 0x0c, 0xd0, 0x60, 0x62, 0x0e, 0x48, 0x00, 0x2a, 0x03, 0xd0, +0xff, 0x21, 0x21, 0x31, 0x39, 0x43, 0x03, 0xe0, 0xff, 0x23, 0x21, 0x33, +0x9f, 0x43, 0x39, 0x1c, 0xc1, 0x62, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0x68, 0x1c, 0x00, 0x80, +0x00, 0x00, 0x00, 0x80, 0x28, 0x1c, 0x00, 0x80, 0x40, 0x00, 0x14, 0x40, +0xa4, 0x2a, 0x00, 0x80, 0x40, 0x00, 0x14, 0x00, 0x90, 0xb4, 0x01, 0x22, +0x20, 0x28, 0x0f, 0xd2, 0x43, 0x00, 0x0f, 0x1c, 0x07, 0x49, 0x5c, 0x18, +0x37, 0x23, 0x9b, 0x01, 0xe3, 0x18, 0x9f, 0x83, 0x82, 0x40, 0x07, 0x23, +0x5b, 0x02, 0xc9, 0x18, 0x10, 0x1c, 0xca, 0x69, 0x10, 0x43, 0xc8, 0x61, +0x90, 0xbc, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x0b, 0x48, 0x40, 0x69, +0x0b, 0x49, 0xc9, 0x8b, 0x04, 0x22, 0x0a, 0x40, 0x0a, 0x49, 0x06, 0xd0, +0x01, 0x23, 0xdb, 0x02, 0x98, 0x43, 0x01, 0x23, 0xca, 0x6d, 0x1a, 0x43, +0x05, 0xe0, 0x01, 0x23, 0xdb, 0x02, 0x18, 0x43, 0xca, 0x6d, 0x52, 0x08, +0x52, 0x00, 0xca, 0x65, 0x70, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x40, +0xe8, 0x1b, 0x00, 0x80, 0xa4, 0x2a, 0x00, 0x80, 0x00, 0xb5, 0x84, 0xb0, +0xff, 0xf7, 0xde, 0xff, 0x01, 0x1c, 0x05, 0x20, 0x00, 0x90, 0x00, 0x20, +0x01, 0xab, 0x18, 0x80, 0x04, 0x3b, 0x58, 0x70, 0x1b, 0x22, 0x00, 0xab, +0x5a, 0x80, 0xd9, 0x80, 0x05, 0x49, 0xc9, 0x6d, 0xc0, 0x46, 0x02, 0x91, +0x03, 0x90, 0x68, 0x46, 0x00, 0x21, 0xfc, 0xf7, 0xd5, 0xf9, 0x04, 0xb0, +0x08, 0xbc, 0x18, 0x47, 0xa4, 0x2a, 0x00, 0x80, 0x0f, 0x48, 0x01, 0x68, +0x49, 0x0c, 0x05, 0xd2, 0x01, 0x68, 0x09, 0x0c, 0x06, 0xd1, 0x00, 0x68, +0x80, 0x0a, 0x03, 0xd3, 0x0b, 0x48, 0x00, 0x68, 0x00, 0x0c, 0x01, 0xe0, +0x0a, 0x48, 0x80, 0x6c, 0x00, 0x04, 0x00, 0x0c, 0x09, 0x4b, 0x98, 0x42, +0x05, 0xd0, 0x02, 0x33, 0x98, 0x42, 0x02, 0xd0, 0x07, 0x4b, 0x98, 0x42, +0x01, 0xd1, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, -0x04, 0x99, 0x00, 0x00, 0x90, 0xb4, 0x01, 0x24, 0x21, 0x1c, 0x17, 0x48, -0x02, 0x68, 0x52, 0x0c, 0x06, 0xd2, 0x02, 0x68, 0x12, 0x0c, 0x02, 0xd1, -0x00, 0x68, 0x80, 0x0a, 0x00, 0xd2, 0x00, 0x21, 0x09, 0x06, 0x09, 0x0e, -0x11, 0x4f, 0x12, 0x4a, 0x02, 0xd0, 0x38, 0x68, 0x00, 0x0c, 0x00, 0xe0, -0x90, 0x6c, 0x00, 0x04, 0x00, 0x0c, 0x0f, 0x4b, -0x98, 0x42, 0x05, 0xd0, 0x02, 0x33, 0x98, 0x42, 0x02, 0xd0, 0x0d, 0x4b, -0x98, 0x42, 0x0c, 0xd1, 0x00, 0x29, 0x02, 0xd0, 0xf8, 0x6a, 0x00, 0x0c, -0x00, 0xe0, 0xd0, 0x6c, 0x40, 0x0a, 0x00, 0xd2, 0x00, 0x24, 0x20, 0x06, -0x00, 0x0e, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, 0xfb, 0xe7, 0x00, 0x00, -0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, -0x04, 0x99, 0x00, 0x00, 0x05, 0x99, 0x00, 0x00, 0x0c, 0x48, 0x01, 0x68, -0x49, 0x0c, 0x05, 0xd2, 0x01, 0x68, 0x09, 0x0c, 0x05, 0xd1, 0x00, 0x68, -0x80, 0x0a, 0x02, 0xd3, 0x08, 0x48, 0x80, 0x68, 0x01, 0xe0, 0x08, 0x48, -0x40, 0x6c, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x21, 0x03, 0x28, 0x03, 0xd0, -0x40, 0x08, 0x01, 0xd3, 0x01, 0x20, 0x70, 0x47, 0x08, 0x1c, 0xfc, 0xe7, -0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, -0xf0, 0xb5, 0x01, 0x27, 0x1a, 0x4c, 0x25, 0x68, 0xff, 0xf7, 0x7a, 0xff, -0x03, 0x1c, 0x19, 0x4a, 0x02, 0x21, 0x01, 0x26, 0x18, 0x48, 0x01, 0x2b, -0x1b, 0xd1, 0xcb, 0x04, 0x1e, 0x60, 0x55, 0x23, 0x03, 0x60, 0x00, 0x23, -0x43, 0x60, 0x06, 0x68, 0x55, 0x2e, 0x1b, 0xd1, 0xaa, 0x26, 0x06, 0x60, -0x43, 0x60, 0x03, 0x68, 0xaa, 0x2b, 0x15, 0xd1, 0x09, 0x23, 0x03, 0x60, -0x05, 0x23, 0x0f, 0x4f, 0xc0, 0x46, 0x3b, 0x60, 0x03, 0x23, 0x0e, 0x4f, -0xc0, 0x46, 0x3b, 0x60, 0x11, 0x60, 0x07, 0x68, 0x08, 0xe0, 0x08, 0x23, -0x23, 0x60, 0x04, 0x23, 0x0a, 0x4f, 0xc0, 0x46, 0x3b, 0x60, 0x11, 0x60, -0x06, 0x60, 0x27, 0x68, 0xc0, 0x46, 0x25, 0x60, 0x38, 0x1c, 0xf0, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x20, 0x40, 0x00, 0x00, 0x24, 0x40, -0x00, 0x00, 0x22, 0x40, 0x00, 0x00, 0x2a, 0x40, 0x00, 0x00, 0x26, 0x40, -0x00, 0x00, 0x28, 0x40, 0x80, 0xb5, 0x07, 0x1c, 0xff, 0xf7, 0x38, 0xff, -0x01, 0x28, 0x05, 0xd1, 0x19, 0x48, 0x00, 0x68, 0x19, 0x49, 0x49, 0x6b, -0x08, 0x40, 0x22, 0xe0, 0x18, 0x48, 0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2, -0x01, 0x68, 0x09, 0x0c, 0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x03, 0xd3, -0x14, 0x48, 0x00, 0x68, 0x00, 0x0c, 0x01, 0xe0, 0x13, 0x48, 0x80, 0x6c, -0x00, 0x04, 0x00, 0x0c, 0x12, 0x4b, 0xc0, 0x18, 0x08, 0x28, 0x0b, 0xd2, -0x01, 0xa3, 0x1b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x05, 0x03, 0x07, 0x03, -0x07, 0x07, 0x05, 0x03, 0x03, 0x20, 0x02, 0xe0, 0x01, 0x20, 0x00, 0xe0, -0x00, 0x20, 0x01, 0x21, 0x38, 0x60, 0x80, 0x07, 0x00, 0xd1, 0x00, 0x21, -0x08, 0x06, 0x00, 0x0e, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, -0x98, 0x6e, 0x21, 0x40, 0x00, 0x00, 0x11, 0x40, 0x00, 0x00, 0x10, 0x40, -0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, 0xfe, 0x66, 0xff, 0xff, -0xf0, 0xb5, 0x83, 0xb0, 0x07, 0x1c, 0x01, 0x20, 0x02, 0x90, 0x01, 0x25, -0x02, 0x24, 0x10, 0x26, 0x20, 0x21, 0x00, 0x91, 0xff, 0xf7, 0xea, 0xfe, -0x01, 0x28, 0x4d, 0xd1, 0x38, 0x2f, 0x01, 0xd0, 0xa8, 0x2f, 0x3a, 0xd1, -0x2e, 0x4e, 0x3c, 0x21, 0x02, 0x20, 0x32, 0x1c, 0xfc, 0xf7, 0x1c, 0xfb, -0x3e, 0x21, 0x05, 0x1c, 0x02, 0x20, 0x32, 0x1c, 0xfc, 0xf7, 0x16, 0xfb, -0x00, 0x04, 0x05, 0x43, 0x40, 0x21, 0x02, 0x20, 0x32, 0x1c, 0xfc, 0xf7, -0x0f, 0xfb, 0x01, 0x90, 0x42, 0x21, 0x02, 0x20, 0x32, 0x1c, 0xfc, 0xf7, -0x09, 0xfb, 0x00, 0x04, 0x01, 0x99, 0x08, 0x43, 0x06, 0x1c, 0xa8, 0x2f, -0x1b, 0xd1, 0x1f, 0x4a, 0x44, 0x21, 0x02, 0x20, -0xfc, 0xf7, 0xfe, 0xfa, 0x04, 0x1c, 0x1c, 0x4a, 0x46, 0x21, 0x02, 0x20, -0xfc, 0xf7, 0xf8, 0xfa, 0x00, 0x04, 0x04, 0x43, 0x18, 0x4a, 0x48, 0x21, -0x02, 0x20, 0xfc, 0xf7, 0xf1, 0xfa, 0x00, 0x90, 0x15, 0x4a, 0x4a, 0x21, -0x02, 0x20, 0xfc, 0xf7, 0xeb, 0xfa, 0x00, 0x04, 0x00, 0x99, 0x01, 0x43, -0x00, 0x91, 0x28, 0x1c, 0x30, 0x43, 0x20, 0x43, 0x00, 0x99, 0x08, 0x43, -0x00, 0xd1, 0x16, 0xe0, 0x11, 0x20, 0x00, 0x04, 0x05, 0x62, 0x46, 0x62, -0x84, 0x62, 0x00, 0x99, 0xc0, 0x46, 0xc1, 0x62, 0x00, 0x21, 0x0a, 0x48, -0xc0, 0x46, 0x01, 0x60, 0x38, 0x2f, 0x01, 0xd0, 0xa8, 0x2f, 0x05, 0xd1, -0x01, 0x21, 0x01, 0x60, 0xa8, 0x2f, 0x01, 0xd1, 0x03, 0x21, 0x01, 0x60, -0x02, 0x98, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, -0x39, 0xb7, 0x21, 0x40, 0x98, 0x6e, 0x21, 0x40, 0x80, 0xb5, 0x07, 0x1c, -0xff, 0xf7, 0x7e, 0xfe, 0x01, 0x28, 0x19, 0xd1, 0x01, 0x05, 0x11, 0x48, -0x00, 0x2f, 0x18, 0xd0, 0x0b, 0x0a, 0x02, 0x68, 0x9a, 0x43, 0x0a, 0x60, -0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2, 0x01, 0x68, 0x09, 0x0c, 0x0b, 0xd1, -0x00, 0x68, 0x80, 0x0a, 0x08, 0xd3, 0x0a, 0x48, 0x40, 0x6a, 0xff, 0x22, -0x01, 0x32, 0x02, 0x43, 0x08, 0x49, 0xc0, 0x46, 0x4a, 0x62, 0x48, 0x62, -0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x68, 0x01, 0x23, 0x1b, 0x03, -0x18, 0x43, 0x08, 0x60, 0xf6, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, -0xc0, 0x00, 0x18, 0x40, 0xc0, 0x00, 0x18, 0x00, 0x70, 0x47, 0x00, 0x00, +0x04, 0x99, 0x00, 0x00, 0x07, 0x99, 0x00, 0x00, 0x90, 0xb4, 0x01, 0x24, +0x21, 0x1c, 0x18, 0x48, 0x02, 0x68, 0x52, 0x0c, 0x06, 0xd2, 0x02, 0x68, +0x12, 0x0c, 0x02, 0xd1, 0x00, 0x68, 0x80, 0x0a, +0x00, 0xd2, 0x00, 0x21, 0x09, 0x06, 0x09, 0x0e, 0x12, 0x4f, 0x13, 0x4a, +0x02, 0xd0, 0x38, 0x68, 0x00, 0x0c, 0x00, 0xe0, 0x90, 0x6c, 0x00, 0x04, +0x00, 0x0c, 0x10, 0x4b, 0x98, 0x42, 0x08, 0xd0, 0x02, 0x33, 0x98, 0x42, +0x05, 0xd0, 0x0e, 0x4b, 0x98, 0x42, 0x02, 0xd0, 0x02, 0x3b, 0x98, 0x42, +0x0c, 0xd1, 0x00, 0x29, 0x02, 0xd0, 0xf8, 0x6a, 0x00, 0x0c, 0x00, 0xe0, +0xd0, 0x6c, 0x40, 0x0a, 0x00, 0xd2, 0x00, 0x24, 0x20, 0x06, 0x00, 0x0e, +0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, 0xfb, 0xe7, 0x00, 0x00, 0x10, 0x40, +0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, 0x04, 0x99, 0x00, 0x00, +0x07, 0x99, 0x00, 0x00, 0x0c, 0x48, 0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2, +0x01, 0x68, 0x09, 0x0c, 0x05, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x02, 0xd3, +0x08, 0x48, 0x80, 0x68, 0x01, 0xe0, 0x08, 0x48, 0x40, 0x6c, 0x00, 0x04, +0x00, 0x0c, 0x00, 0x21, 0x03, 0x28, 0x03, 0xd0, 0x40, 0x08, 0x01, 0xd3, +0x01, 0x20, 0x70, 0x47, 0x08, 0x1c, 0xfc, 0xe7, 0x00, 0x00, 0x10, 0x40, +0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, 0xf0, 0xb5, 0x01, 0x27, +0x1a, 0x4c, 0x25, 0x68, 0xff, 0xf7, 0x72, 0xff, 0x03, 0x1c, 0x19, 0x4a, +0x02, 0x21, 0x01, 0x26, 0x18, 0x48, 0x01, 0x2b, 0x1b, 0xd1, 0xcb, 0x04, +0x1e, 0x60, 0x55, 0x23, 0x03, 0x60, 0x00, 0x23, 0x43, 0x60, 0x06, 0x68, +0x55, 0x2e, 0x1b, 0xd1, 0xaa, 0x26, 0x06, 0x60, 0x43, 0x60, 0x03, 0x68, +0xaa, 0x2b, 0x15, 0xd1, 0x09, 0x23, 0x03, 0x60, 0x05, 0x23, 0x0f, 0x4f, +0xc0, 0x46, 0x3b, 0x60, 0x03, 0x23, 0x0e, 0x4f, 0xc0, 0x46, 0x3b, 0x60, +0x11, 0x60, 0x07, 0x68, 0x08, 0xe0, 0x08, 0x23, 0x23, 0x60, 0x04, 0x23, +0x0a, 0x4f, 0xc0, 0x46, 0x3b, 0x60, 0x11, 0x60, 0x06, 0x60, 0x27, 0x68, +0xc0, 0x46, 0x25, 0x60, 0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x00, 0x00, 0x20, 0x40, 0x00, 0x00, 0x24, 0x40, 0x00, 0x00, 0x22, 0x40, +0x00, 0x00, 0x2a, 0x40, 0x00, 0x00, 0x26, 0x40, 0x00, 0x00, 0x28, 0x40, +0x80, 0xb5, 0x07, 0x1c, 0xff, 0xf7, 0x30, 0xff, 0x01, 0x28, 0x05, 0xd1, +0x19, 0x48, 0x00, 0x68, 0x19, 0x49, 0x49, 0x6b, 0x08, 0x40, 0x22, 0xe0, +0x18, 0x48, 0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2, 0x01, 0x68, 0x09, 0x0c, +0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x03, 0xd3, 0x14, 0x48, 0x00, 0x68, +0x00, 0x0c, 0x01, 0xe0, 0x13, 0x48, 0x80, 0x6c, 0x00, 0x04, 0x00, 0x0c, +0x12, 0x4b, 0xc0, 0x18, 0x08, 0x28, 0x0b, 0xd2, 0x01, 0xa3, 0x1b, 0x5c, +0x5b, 0x00, 0x9f, 0x44, 0x05, 0x03, 0x07, 0x03, 0x07, 0x07, 0x05, 0x03, +0x03, 0x20, 0x02, 0xe0, 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, 0x01, 0x21, +0x38, 0x60, 0x80, 0x07, 0x00, 0xd1, 0x00, 0x21, 0x08, 0x06, 0x00, 0x0e, +0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x98, 0x6e, 0x21, 0x40, +0x00, 0x00, 0x11, 0x40, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x18, 0x40, +0x00, 0x00, 0x00, 0x80, 0xfe, 0x66, 0xff, 0xff, 0xf0, 0xb5, 0x83, 0xb0, +0x07, 0x1c, 0x01, 0x20, 0x02, 0x90, 0x01, 0x25, 0x02, 0x24, 0x10, 0x26, +0x20, 0x21, 0x00, 0x91, 0xff, 0xf7, 0xe2, 0xfe, 0x01, 0x28, 0x4d, 0xd1, +0x38, 0x2f, 0x01, 0xd0, 0xa8, 0x2f, 0x3a, 0xd1, 0x2e, 0x4e, 0x3c, 0x21, +0x02, 0x20, 0x32, 0x1c, 0xfb, 0xf7, 0x4c, 0xff, 0x3e, 0x21, 0x05, 0x1c, +0x02, 0x20, 0x32, 0x1c, 0xfb, 0xf7, 0x46, 0xff, 0x00, 0x04, 0x05, 0x43, +0x40, 0x21, 0x02, 0x20, 0x32, 0x1c, 0xfb, 0xf7, +0x3f, 0xff, 0x01, 0x90, 0x42, 0x21, 0x02, 0x20, 0x32, 0x1c, 0xfb, 0xf7, +0x39, 0xff, 0x00, 0x04, 0x01, 0x99, 0x08, 0x43, 0x06, 0x1c, 0xa8, 0x2f, +0x1b, 0xd1, 0x1f, 0x4a, 0x44, 0x21, 0x02, 0x20, 0xfb, 0xf7, 0x2e, 0xff, +0x04, 0x1c, 0x1c, 0x4a, 0x46, 0x21, 0x02, 0x20, 0xfb, 0xf7, 0x28, 0xff, +0x00, 0x04, 0x04, 0x43, 0x18, 0x4a, 0x48, 0x21, 0x02, 0x20, 0xfb, 0xf7, +0x21, 0xff, 0x00, 0x90, 0x15, 0x4a, 0x4a, 0x21, 0x02, 0x20, 0xfb, 0xf7, +0x1b, 0xff, 0x00, 0x04, 0x00, 0x99, 0x01, 0x43, 0x00, 0x91, 0x28, 0x1c, +0x30, 0x43, 0x20, 0x43, 0x00, 0x99, 0x08, 0x43, 0x00, 0xd1, 0x16, 0xe0, +0x11, 0x20, 0x00, 0x04, 0x05, 0x62, 0x46, 0x62, 0x84, 0x62, 0x00, 0x99, +0xc0, 0x46, 0xc1, 0x62, 0x00, 0x21, 0x0a, 0x48, 0xc0, 0x46, 0x01, 0x60, +0x38, 0x2f, 0x01, 0xd0, 0xa8, 0x2f, 0x05, 0xd1, 0x01, 0x21, 0x01, 0x60, +0xa8, 0x2f, 0x01, 0xd1, 0x03, 0x21, 0x01, 0x60, 0x02, 0x98, 0x03, 0xb0, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x79, 0xbf, 0x21, 0x40, +0x98, 0x6e, 0x21, 0x40, 0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, 0x90, 0xb5, 0x07, 0x1c, 0x12, 0x4c, 0x21, 0x68, 0x12, 0x48, 0x81, 0x42, -0x0b, 0xd0, 0x00, 0x23, 0x21, 0x1c, 0xe2, 0x1d, 0x6d, 0x32, 0x00, 0xe0, -0x08, 0xc1, 0x91, 0x42, 0xfc, 0xd3, 0x20, 0x60, 0x74, 0x20, 0xa0, 0x80, +0x0b, 0xd0, 0x00, 0x23, 0x21, 0x1c, 0xe2, 0x1d, 0xc5, 0x32, 0x00, 0xe0, +0x08, 0xc1, 0x91, 0x42, 0xfc, 0xd3, 0x20, 0x60, 0xcc, 0x20, 0xa0, 0x80, 0x67, 0x72, 0x38, 0x01, 0x00, 0xf0, 0x18, 0xf8, 0x27, 0x72, 0x0a, 0x48, -0xc0, 0x46, 0xe0, 0x60, 0x08, 0x2f, 0x00, 0xdb, 0x00, 0x27, 0xe0, 0x19, +0xc0, 0x46, 0xe0, 0x60, 0x09, 0x2f, 0x00, 0xdb, 0x00, 0x27, 0xe0, 0x19, 0x01, 0x7d, 0x01, 0x31, 0x01, 0x75, 0xe0, 0x88, 0x01, 0x30, 0xe0, 0x80, 0x01, 0x20, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x80, -0xfe, 0xca, 0x01, 0x20, 0x17, 0x40, 0x00, 0x02, 0x80, 0xb4, 0x08, 0x4a, -0xd1, 0x1d, 0x49, 0x31, 0x0b, 0x78, 0x20, 0x2b, 0x01, 0xd3, 0x00, 0x23, -0x0b, 0x70, 0x07, 0x1c, 0x08, 0x78, 0x43, 0x1c, 0x0b, 0x70, 0x80, 0x18, -0x50, 0x30, 0x47, 0x70, 0x80, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x00, 0x80, +0xee, 0xff, 0xc0, 0xd0, 0x02, 0x10, 0x00, 0x03, 0x80, 0xb4, 0x08, 0x4a, +0xd1, 0x1d, 0x89, 0x31, 0x0b, 0x7b, 0x20, 0x2b, 0x01, 0xd3, 0x00, 0x23, +0x0b, 0x73, 0x07, 0x1c, 0x08, 0x7b, 0x43, 0x1c, 0x0b, 0x73, 0x80, 0x18, +0x90, 0x30, 0x47, 0x73, 0x80, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x00, 0x80, 0x07, 0x49, 0x01, 0x22, 0x12, 0x04, 0x08, 0x68, 0x02, 0x40, 0x01, 0x20, 0x00, 0x2a, 0x06, 0xd1, 0x0a, 0x68, 0x12, 0x0c, 0x02, 0xd1, 0x09, 0x68, 0x89, 0x0a, 0x00, 0xd2, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, 0x10, 0x40, 0x90, 0xb5, 0x07, 0x1c, 0x09, 0x4c, 0x38, 0x1c, 0x21, 0x1c, 0xfc, 0xf7, -0x4d, 0xfc, 0x38, 0x1c, 0x00, 0xf0, 0x0e, 0xf8, 0x01, 0x23, 0xd8, 0x42, -0x01, 0xd1, 0x00, 0x0c, 0xe0, 0x80, 0x00, 0x21, 0x20, 0x1c, 0xfc, 0xf7, -0x81, 0xfb, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xbc, 0x67, 0x21, 0x40, +0xab, 0xf8, 0x38, 0x1c, 0x00, 0xf0, 0x0e, 0xf8, 0x01, 0x23, 0xd8, 0x42, +0x01, 0xd1, 0x00, 0x0c, 0xe0, 0x80, 0x00, 0x21, 0x20, 0x1c, 0xfb, 0xf7, +0xdf, 0xff, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x70, 0x67, 0x21, 0x40, 0xf8, 0xb5, 0x07, 0x1c, 0x79, 0x7a, 0x76, 0x48, 0x00, 0x23, 0x76, 0x4c, 0x01, 0x29, 0x5d, 0xd1, 0xa2, 0x88, 0xc0, 0x46, 0x00, 0x92, 0xa1, 0x89, 0x8a, 0x42, 0x74, 0xda, 0xfa, 0x7a, 0x00, 0x2a, 0x15, 0xd0, 0x7a, 0x6c, 0x00, 0x2a, 0x12, 0xd0, 0x8a, 0x42, 0x10, 0xd8, 0x00, 0x9a, 0x51, 0x1c, 0xa1, 0x80, 0xa1, 0x88, 0xc0, 0x46, 0x41, 0x81, 0x78, 0x6c, 0x6b, 0x4e, -0xc0, 0x46, 0xf0, 0x80, 0xa0, 0x6a, 0x58, 0x23, -0x79, 0x6c, 0x59, 0x43, 0x40, 0x18, 0xc1, 0x1a, 0x28, 0xe0, 0x22, 0x88, -0x01, 0x32, 0x12, 0x04, 0x12, 0x0c, 0x22, 0x80, 0x8a, 0x42, 0x00, 0xdb, -0x23, 0x80, 0x00, 0x22, 0x00, 0x29, 0x69, 0xdd, 0x5f, 0x4c, 0xa4, 0x6a, -0x5e, 0x4b, 0x1d, 0x88, 0x58, 0x23, 0x6b, 0x43, 0xe3, 0x18, 0xde, 0x1d, -0x01, 0x36, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x1b, 0x06, +0xc0, 0x46, 0xf0, 0x80, 0xa0, 0x6a, 0x58, 0x23, 0x79, 0x6c, 0x59, 0x43, +0x40, 0x18, 0xc1, 0x1a, 0x28, 0xe0, 0x22, 0x88, 0x01, 0x32, 0x12, 0x04, +0x12, 0x0c, 0x22, 0x80, 0x8a, 0x42, 0x00, 0xdb, 0x23, 0x80, 0x00, 0x22, +0x00, 0x29, 0x69, 0xdd, 0x5f, 0x4c, 0xa4, 0x6a, 0x5e, 0x4b, 0x1d, 0x88, +0x58, 0x23, 0x6b, 0x43, 0xe3, 0x18, 0xde, 0x1d, 0x01, 0x36, 0x01, 0x23, +0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x1b, 0x06, 0x15, 0xd1, 0x58, 0x49, 0x00, 0x9a, 0x01, 0x32, 0x8a, 0x80, 0x8a, 0x88, 0xc0, 0x46, 0x42, 0x81, 0x08, 0x88, 0x01, 0x30, 0x54, 0x4e, 0xc0, 0x46, 0xf0, 0x80, 0x58, 0x20, 0x68, 0x43, 0x21, 0x18, 0x38, 0x1c, 0x00, 0xf0, -0x65, 0xfa, 0xf0, 0x88, 0x00, 0x04, 0x00, 0x14, 0x95, 0xe0, 0x4d, 0x4b, +0x8d, 0xfa, 0xf0, 0x88, 0x00, 0x04, 0x00, 0x14, 0x95, 0xe0, 0x4d, 0x4b, 0x01, 0x35, 0x2d, 0x04, 0x2d, 0x0c, 0x1d, 0x80, 0x8d, 0x42, 0x01, 0xdb, 0x00, 0x25, 0x1d, 0x80, 0x01, 0x32, 0x12, 0x04, 0x12, 0x14, 0x91, 0x42, 0xce, 0xdc, 0x81, 0xe0, 0xe1, 0x88, 0xe2, 0x89, 0x91, 0x42, 0x18, 0xda, @@ -3446,9 +3614,9 @@ 0xdb, 0x03, 0x78, 0x6c, 0x18, 0x43, 0x3a, 0x4e, 0xc0, 0x46, 0xf0, 0x80, 0x00, 0xe0, 0x63, 0xe0, 0xe0, 0x6a, 0x79, 0x6c, 0x4b, 0x00, 0x59, 0x18, 0x49, 0x01, 0x40, 0x18, 0xc1, 0x1f, 0x59, 0x39, 0x38, 0x1c, 0x00, 0xf0, -0x4b, 0xfa, 0xe0, 0x6a, 0x79, 0x6c, 0x4a, 0x00, 0x52, 0x18, 0x52, 0x01, +0x79, 0xfa, 0xe0, 0x6a, 0x79, 0x6c, 0x4a, 0x00, 0x52, 0x18, 0x52, 0x01, 0x80, 0x18, 0x01, 0x39, 0x09, 0x04, 0x09, 0x0c, 0x60, 0x38, 0x00, 0xf0, -0xc5, 0xfa, 0xb6, 0xe7, 0x4a, 0xe0, 0x61, 0x88, 0x01, 0x31, 0x09, 0x04, +0xf3, 0xfa, 0xb6, 0xe7, 0x4a, 0xe0, 0x61, 0x88, 0x01, 0x31, 0x09, 0x04, 0x09, 0x0c, 0x61, 0x80, 0xe2, 0x89, 0x91, 0x42, 0x00, 0xdb, 0x63, 0x80, 0x00, 0x21, 0x00, 0x2a, 0x3e, 0xdd, 0x24, 0x4c, 0xe4, 0x6a, 0x23, 0x4b, 0x5d, 0x88, 0x6b, 0x00, 0x5b, 0x19, 0x5b, 0x01, 0xe3, 0x18, 0xde, 0x1d, @@ -3456,193 +3624,208 @@ 0x20, 0xd1, 0x1c, 0x4e, 0xf1, 0x88, 0x01, 0x31, 0xf1, 0x80, 0xf1, 0x88, 0xc0, 0x46, 0x81, 0x81, 0x70, 0x88, 0x01, 0x23, 0xdb, 0x03, 0x01, 0x30, 0x18, 0x43, 0x17, 0x49, 0xc0, 0x46, 0xc8, 0x80, 0x68, 0x00, 0x40, 0x19, -0x40, 0x01, 0x21, 0x18, 0x38, 0x1c, 0x00, 0xf0, 0x0b, 0xfa, 0x71, 0x88, +0x40, 0x01, 0x21, 0x18, 0x38, 0x1c, 0x00, 0xf0, 0x39, 0xfa, 0x71, 0x88, 0x4a, 0x00, 0x52, 0x18, 0x52, 0x01, 0xf0, 0x6a, 0x80, 0x18, 0x00, 0xf0, -0x89, 0xfa, 0x0e, 0x49, 0xc8, 0x88, 0x79, 0xe7, 0x0b, 0x4b, 0x01, 0x35, +0xb7, 0xfa, 0x0e, 0x49, 0xc8, 0x88, 0x79, 0xe7, 0x0b, 0x4b, 0x01, 0x35, 0x2d, 0x04, 0x2d, 0x0c, 0x5d, 0x80, 0x95, 0x42, 0x01, 0xdb, 0x00, 0x25, 0x5d, 0x80, 0x01, 0x31, 0x09, 0x04, 0x09, 0x14, 0x8a, 0x42, 0xc2, 0xdc, 0x01, 0x89, 0x01, 0x31, 0x01, 0x81, 0x00, 0x20, 0xc0, 0x43, 0xf8, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0xb8, 0x2a, 0x00, 0x80, 0xc8, 0x29, 0x00, 0x80, -0xbc, 0x67, 0x21, 0x40, 0xf0, 0xb4, 0x06, 0x1c, 0x01, 0x23, 0xdb, 0x03, -0x33, 0x40, 0x01, 0x24, 0x30, 0x4f, 0x00, 0x20, 0x30, 0x4a, 0x31, 0x4d, -0xd1, 0x1d, 0x39, 0x31, 0x00, 0x2b, 0x2f, 0xd0, 0xe3, 0x03, 0xf3, 0x1a, -0x51, 0xd0, 0xee, 0x89, 0x9e, 0x42, 0x4e, 0xd3, 0xee, 0x88, 0x00, 0x2e, -0x4b, 0xd0, 0xee, 0x6a, 0x5d, 0x1e, 0x6b, 0x00, 0x5d, 0x19, 0x6d, 0x01, -0x73, 0x19, 0x9e, 0x68, 0x36, 0x06, 0x36, 0x0e, 0x03, 0x2e, 0x02, 0xd0, -0xce, 0x89, 0x01, 0x36, 0xce, 0x81, 0x40, 0x33, 0x9b, 0x8b, 0x9b, 0x00, -0x21, 0x4e, 0x76, 0x6a, 0xc0, 0x46, 0xf0, 0x50, -0x53, 0x89, 0x01, 0x33, 0x53, 0x81, 0x1e, 0x4e, 0xf2, 0x6a, 0x52, 0x19, -0x90, 0x60, 0xf0, 0x88, 0x01, 0x38, 0xf0, 0x80, 0xf0, 0x88, 0xc0, 0x46, -0x88, 0x81, 0x19, 0x49, 0x00, 0x28, 0x23, 0xd1, 0x4f, 0x80, 0x21, 0xe0, -0x00, 0x2e, 0x22, 0xd9, 0xab, 0x89, 0xb3, 0x42, 0x1f, 0xd3, 0xab, 0x88, -0x00, 0x2b, 0x1c, 0xd0, 0x53, 0x89, 0x01, 0x33, 0x53, 0x81, 0x58, 0x23, -0x01, 0x3e, 0x73, 0x43, 0xaa, 0x6a, 0xd2, 0x18, 0x93, 0x68, 0x1b, 0x06, -0x1b, 0x0e, 0x03, 0x2b, 0x02, 0xd0, 0xcb, 0x89, 0x01, 0x33, 0xcb, 0x81, -0x90, 0x60, 0xa8, 0x88, 0x01, 0x38, 0xa8, 0x80, 0xa8, 0x88, 0xc0, 0x46, -0x48, 0x81, 0x00, 0x28, 0x00, 0xd1, 0x2f, 0x80, 0x20, 0x1c, 0xf0, 0xbc, -0x70, 0x47, 0xca, 0x89, 0x01, 0x32, 0xca, 0x81, 0xf9, 0xe7, 0x00, 0x00, -0xff, 0xff, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, 0xc8, 0x29, 0x00, 0x80, -0x00, 0xb5, 0x00, 0x21, 0x41, 0x60, 0x10, 0x49, 0x4a, 0x68, 0x00, 0x2a, -0x10, 0xd1, 0xca, 0x68, 0x00, 0x2a, 0x04, 0xd0, 0xca, 0x1d, 0x19, 0x32, -0x12, 0x79, 0x00, 0x2a, 0x08, 0xd0, 0x4a, 0x69, 0x00, 0x2a, 0x0b, 0xd1, -0x88, 0x61, 0x48, 0x61, 0x00, 0xf0, 0x10, 0xf8, 0x08, 0xbc, 0x18, 0x47, -0x4a, 0x69, 0x00, 0x2a, 0x02, 0xd1, 0x88, 0x61, 0x48, 0x61, 0xf7, 0xe7, -0x8a, 0x69, 0xc0, 0x46, 0x50, 0x60, 0x88, 0x61, 0xf2, 0xe7, 0x00, 0x00, -0xec, 0x05, 0x00, 0x80, 0xb0, 0xb5, 0x2a, 0x48, 0x40, 0x69, 0x00, 0x28, -0x4c, 0xd0, 0x08, 0x22, 0xc1, 0x68, 0x0a, 0x40, 0x00, 0x27, 0x27, 0x4b, -0xd9, 0x1d, 0xb9, 0x31, 0x00, 0x2a, 0x11, 0xd0, 0x04, 0x22, 0x25, 0x4c, -0xc0, 0x46, 0x0c, 0x61, 0x24, 0x4c, 0xc0, 0x46, 0x4c, 0x62, 0x24, 0x4c, -0xc0, 0x46, 0x8c, 0x62, 0x23, 0x4c, 0xc0, 0x46, 0xcc, 0x62, 0x23, 0x4c, -0xc0, 0x46, 0x0c, 0x63, 0x4f, 0x63, 0x12, 0xe0, 0x05, 0x22, 0x21, 0x4c, -0xc0, 0x46, 0x0c, 0x61, 0x20, 0x4c, 0xc0, 0x46, 0x4c, 0x62, 0x20, 0x4c, -0xc0, 0x46, 0x8c, 0x62, 0x1f, 0x4c, 0xc0, 0x46, 0xcc, 0x62, 0x1f, 0x4c, -0xc0, 0x46, 0x0c, 0x63, 0x1e, 0x4c, 0xc0, 0x46, 0x4c, 0x63, 0x40, 0x24, -0xcc, 0x82, 0x4f, 0x83, 0x1c, 0x4f, 0x00, 0x21, 0x00, 0x2a, 0x0c, 0xd9, -0x8c, 0x00, 0x05, 0x19, 0x6d, 0x6a, 0x7d, 0x40, 0xe4, 0x18, 0xff, 0x34, -0x01, 0x34, 0x65, 0x62, 0x01, 0x31, 0x91, 0x42, 0xf4, 0xd3, 0x10, 0x29, -0x07, 0xd2, 0x8a, 0x00, 0xd2, 0x18, 0xff, 0x32, 0x01, 0x32, 0x57, 0x62, -0x01, 0x31, 0x10, 0x29, 0xf7, 0xd3, 0x11, 0x49, 0x00, 0xf0, 0x22, 0xf8, -0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, -0x1c, 0xad, 0x20, 0x40, 0x28, 0x01, 0x40, 0x00, 0x01, 0x23, 0x45, 0x67, -0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, -0x20, 0x01, 0x40, 0x00, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, -0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0, -0x36, 0x36, 0x36, 0x36, 0x30, 0x80, 0x20, 0x40, 0xb0, 0xb5, 0x0f, 0x1c, -0x15, 0x4d, 0xe9, 0x1d, 0xc9, 0x31, 0x15, 0x4c, 0x23, 0x1c, 0x15, 0x4a, -0x00, 0x20, 0xfc, 0xf7, 0x1a, 0xf8, 0xe9, 0x1d, 0xff, 0x31, 0x1e, 0x31, -0x23, 0x1c, 0x0d, 0x1c, 0x11, 0x4a, 0x01, 0x20, 0xfc, 0xf7, 0x11, 0xf8, -0x29, 0x1c, 0x23, 0x1c, 0x0e, 0x4a, 0x00, 0x20, 0xfc, 0xf7, 0x0b, 0xf8, -0x39, 0x1c, 0x23, 0x1c, 0x0c, 0x4a, 0x01, 0x20, 0xfc, 0xf7, 0x05, 0xf8, -0x00, 0x21, 0x0b, 0x48, 0xc2, 0x1d, 0x19, 0x32, -0x51, 0x71, 0x01, 0x21, 0xff, 0x30, 0x01, 0x30, 0x41, 0x62, 0x08, 0x1c, -0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x1c, 0xad, 0x20, 0x40, -0x75, 0x08, 0xff, 0xff, 0x28, 0x00, 0x03, 0x00, 0x40, 0x00, 0x02, 0x00, -0x14, 0x00, 0x07, 0x00, 0xec, 0x05, 0x00, 0x80, 0xf0, 0xb5, 0x37, 0x4a, -0x50, 0x69, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x30, 0x18, 0x43, 0x00, 0x68, -0x01, 0x06, 0x09, 0x0e, 0x33, 0x4b, 0x01, 0x29, 0x49, 0xd1, 0x1f, 0x68, -0x19, 0x1c, 0x32, 0x4b, 0x9f, 0x42, 0x04, 0xd1, 0xff, 0xf7, 0x3e, 0xff, -0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x23, 0x9f, 0x00, 0xcc, 0x59, -0x55, 0x69, 0xef, 0x19, 0x3c, 0x61, 0x01, 0x33, 0x05, 0x2b, 0xf7, 0xd3, -0x00, 0x0a, 0x00, 0x02, 0x02, 0x23, 0x18, 0x43, 0x53, 0x69, 0xc0, 0x46, -0x98, 0x60, 0x50, 0x69, 0x08, 0x23, 0xc2, 0x68, 0x13, 0x40, 0x25, 0x4f, -0xfa, 0x1d, 0xb9, 0x32, 0x00, 0x2b, 0x02, 0xd0, 0x04, 0x23, 0x23, 0x4c, -0x01, 0xe0, 0x05, 0x23, 0x22, 0x4c, 0xc0, 0x46, 0x14, 0x61, 0x40, 0x24, -0xd4, 0x82, 0x00, 0x24, 0x54, 0x83, 0x20, 0x4c, 0x00, 0x22, 0x00, 0x2b, -0x0c, 0xd9, 0x95, 0x00, 0x46, 0x19, 0x76, 0x6a, 0x66, 0x40, 0xed, 0x19, -0xff, 0x35, 0x01, 0x35, 0x6e, 0x62, 0x01, 0x32, 0x9a, 0x42, 0xf4, 0xd3, -0x10, 0x2a, 0x07, 0xd2, 0x93, 0x00, 0xdb, 0x19, 0xff, 0x33, 0x01, 0x33, -0x5c, 0x62, 0x01, 0x32, 0x10, 0x2a, 0xf7, 0xd3, 0xff, 0xf7, 0x70, 0xff, -0xbc, 0xe7, 0x00, 0x21, 0x8f, 0x00, 0xdc, 0x59, 0x55, 0x69, 0xef, 0x19, -0x7c, 0x62, 0x01, 0x31, 0x05, 0x29, 0xf7, 0xd3, 0x00, 0x0a, 0x00, 0x02, -0x03, 0x23, 0x18, 0x43, 0x51, 0x69, 0xc0, 0x46, 0x88, 0x60, 0x50, 0x69, -0x40, 0x68, 0xc0, 0x46, 0x50, 0x61, 0x09, 0x48, 0xfb, 0xf7, 0x7a, 0xff, -0xa4, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0x30, 0x80, 0x20, 0x40, -0x67, 0x45, 0x23, 0x01, 0x1c, 0xad, 0x20, 0x40, 0x28, 0x01, 0x40, 0x00, -0x20, 0x01, 0x40, 0x00, 0x5c, 0x5c, 0x5c, 0x5c, 0x85, 0x30, 0xff, 0xff, -0x80, 0xb5, 0x0f, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x43, 0xf8, 0xb9, 0x6b, -0x0b, 0x48, 0xc2, 0x68, 0x12, 0x04, 0x51, 0x40, 0x82, 0x69, 0x51, 0x40, -0x39, 0x65, 0xf9, 0x6b, 0x82, 0x69, 0x12, 0x04, 0xd2, 0x43, 0x51, 0x40, -0xc0, 0x68, 0xc0, 0x43, 0x48, 0x40, 0x78, 0x65, 0x04, 0x48, 0x01, 0x89, -0x01, 0x31, 0x01, 0x81, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, -0x08, 0x83, 0x20, 0x40, 0x78, 0x2a, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x1c, -0x0f, 0x1c, 0x20, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x1f, 0xf8, 0xe0, 0x68, -0x01, 0x0e, 0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, -0xff, 0x22, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06, -0x08, 0x43, 0x38, 0x65, 0x20, 0x69, 0xc0, 0x46, 0x78, 0x65, 0x60, 0x69, -0xc0, 0x46, 0xb8, 0x65, 0x03, 0x48, 0x01, 0x89, 0x01, 0x31, 0x01, 0x81, -0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, -0x90, 0xb5, 0x00, 0x22, 0x93, 0x00, 0x1f, 0x18, 0xbf, 0x69, 0x5b, 0x18, -0x5f, 0x62, 0x01, 0x32, 0x05, 0x2a, 0xf7, 0xd3, 0x07, 0x7a, 0xfb, 0x08, -0x03, 0xd3, 0x00, 0x23, 0x92, 0x00, 0x52, 0x18, 0x13, 0x62, 0x07, 0x6b, +0x08, 0xbc, 0x18, 0x47, 0x4c, 0x2b, 0x00, 0x80, 0x4c, 0x2a, 0x00, 0x80, +0x70, 0x67, 0x21, 0x40, 0xf0, 0xb4, 0x06, 0x1c, 0x01, 0x23, 0xdb, 0x03, +0x33, 0x40, 0x01, 0x24, 0x44, 0x4f, 0x00, 0x20, 0x44, 0x4a, 0x45, 0x4d, +0xd1, 0x1d, 0x39, 0x31, 0x00, 0x2b, 0x41, 0xd0, 0xe3, 0x03, 0xf3, 0x1a, +0x73, 0xd0, 0xee, 0x89, 0x9e, 0x42, 0x71, 0xd3, 0xee, 0x88, 0x00, 0x2e, +0x6d, 0xd0, 0xed, 0x6a, 0x5e, 0x1e, 0x73, 0x00, 0x9b, 0x19, 0x5b, 0x01, +0xed, 0x18, 0xae, 0x68, 0x36, 0x06, 0x36, 0x0e, 0x03, 0x2e, 0x02, 0xd0, +0xce, 0x89, 0x01, 0x36, 0xce, 0x81, 0x40, 0x35, 0xad, 0x8b, 0xad, 0x00, +0x35, 0x4e, 0x76, 0x6a, 0xc0, 0x46, 0x70, 0x51, 0x55, 0x89, 0x01, 0x35, +0x55, 0x81, 0x32, 0x4e, 0xf2, 0x6a, 0xd2, 0x18, 0x90, 0x60, 0xf2, 0x6a, +0xd2, 0x18, 0x90, 0x63, 0xf2, 0x6a, 0xd2, 0x18, 0xd0, 0x63, 0xf2, 0x6a, +0xd2, 0x18, 0x10, 0x64, 0xf2, 0x6a, 0xd2, 0x18, 0x50, 0x64, 0xf2, 0x6a, +0xd2, 0x18, 0x90, 0x64, 0xf2, 0x6a, 0xd2, 0x18, 0xd0, 0x64, 0xf0, 0x88, +0x01, 0x38, 0xf0, 0x80, 0xf0, 0x88, 0xc0, 0x46, +0x88, 0x81, 0x24, 0x49, 0x00, 0x28, 0x39, 0xd1, 0x4f, 0x80, 0x37, 0xe0, +0x00, 0x2e, 0x38, 0xd9, 0xab, 0x89, 0xb3, 0x42, 0x30, 0xd3, 0xab, 0x88, +0x00, 0x2b, 0x2c, 0xd0, 0x53, 0x89, 0x01, 0x33, 0x53, 0x81, 0x2a, 0x1c, +0xad, 0x6a, 0x58, 0x23, 0x01, 0x3e, 0x73, 0x43, 0xed, 0x18, 0xae, 0x68, +0x36, 0x06, 0x36, 0x0e, 0x03, 0x2e, 0x02, 0xd0, 0xce, 0x89, 0x01, 0x36, +0xce, 0x81, 0xa8, 0x60, 0x95, 0x6a, 0xed, 0x18, 0xa8, 0x63, 0x95, 0x6a, +0xed, 0x18, 0xe8, 0x63, 0x95, 0x6a, 0xed, 0x18, 0x28, 0x64, 0x95, 0x6a, +0xed, 0x18, 0x68, 0x64, 0x95, 0x6a, 0xed, 0x18, 0xa8, 0x64, 0x95, 0x6a, +0xeb, 0x18, 0xd8, 0x64, 0x90, 0x88, 0x01, 0x38, 0x90, 0x80, 0x90, 0x88, +0xc0, 0x46, 0x48, 0x81, 0x00, 0x28, 0x03, 0xd1, 0x01, 0xe0, 0x04, 0xe0, +0x03, 0xe0, 0x17, 0x80, 0x20, 0x1c, 0xf0, 0xbc, 0x70, 0x47, 0xca, 0x89, +0x01, 0x32, 0xca, 0x81, 0xf9, 0xe7, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, +0x0c, 0x2b, 0x00, 0x80, 0x4c, 0x2a, 0x00, 0x80, 0x00, 0xb5, 0x00, 0x21, +0x41, 0x60, 0x10, 0x49, 0x4a, 0x68, 0x00, 0x2a, 0x10, 0xd1, 0xca, 0x68, +0x00, 0x2a, 0x04, 0xd0, 0xca, 0x1d, 0x19, 0x32, 0x12, 0x79, 0x00, 0x2a, +0x08, 0xd0, 0x4a, 0x69, 0x00, 0x2a, 0x0b, 0xd1, 0x88, 0x61, 0x48, 0x61, +0x00, 0xf0, 0x10, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x4a, 0x69, 0x00, 0x2a, +0x02, 0xd1, 0x88, 0x61, 0x48, 0x61, 0xf7, 0xe7, 0x8a, 0x69, 0xc0, 0x46, +0x50, 0x60, 0x88, 0x61, 0xf2, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, +0xb0, 0xb5, 0x2a, 0x48, 0x40, 0x69, 0x00, 0x28, 0x4c, 0xd0, 0x08, 0x22, +0xc1, 0x68, 0x0a, 0x40, 0x00, 0x27, 0x27, 0x4b, 0xd9, 0x1d, 0xb9, 0x31, +0x00, 0x2a, 0x11, 0xd0, 0x04, 0x22, 0x25, 0x4c, 0xc0, 0x46, 0x0c, 0x61, +0x24, 0x4c, 0xc0, 0x46, 0x4c, 0x62, 0x24, 0x4c, 0xc0, 0x46, 0x8c, 0x62, +0x23, 0x4c, 0xc0, 0x46, 0xcc, 0x62, 0x23, 0x4c, 0xc0, 0x46, 0x0c, 0x63, +0x4f, 0x63, 0x12, 0xe0, 0x05, 0x22, 0x21, 0x4c, 0xc0, 0x46, 0x0c, 0x61, +0x20, 0x4c, 0xc0, 0x46, 0x4c, 0x62, 0x20, 0x4c, 0xc0, 0x46, 0x8c, 0x62, +0x1f, 0x4c, 0xc0, 0x46, 0xcc, 0x62, 0x1f, 0x4c, 0xc0, 0x46, 0x0c, 0x63, +0x1e, 0x4c, 0xc0, 0x46, 0x4c, 0x63, 0x40, 0x24, 0xcc, 0x82, 0x4f, 0x83, +0x1c, 0x4f, 0x00, 0x21, 0x00, 0x2a, 0x0c, 0xd9, 0x8c, 0x00, 0x05, 0x19, +0x6d, 0x6a, 0x7d, 0x40, 0xe4, 0x18, 0xff, 0x34, 0x01, 0x34, 0x65, 0x62, +0x01, 0x31, 0x91, 0x42, 0xf4, 0xd3, 0x10, 0x29, 0x07, 0xd2, 0x8a, 0x00, +0xd2, 0x18, 0xff, 0x32, 0x01, 0x32, 0x57, 0x62, 0x01, 0x31, 0x10, 0x29, +0xf7, 0xd3, 0x11, 0x49, 0x00, 0xf0, 0x22, 0xf8, 0xb0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, 0x1c, 0xad, 0x20, 0x40, +0x28, 0x01, 0x40, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, +0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x20, 0x01, 0x40, 0x00, +0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x98, 0xba, 0xdc, 0xfe, +0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0, 0x36, 0x36, 0x36, 0x36, +0x30, 0x80, 0x20, 0x40, 0xb0, 0xb5, 0x0f, 0x1c, 0x15, 0x4d, 0xe9, 0x1d, +0xc9, 0x31, 0x15, 0x4c, 0x23, 0x1c, 0x15, 0x4a, 0x00, 0x20, 0xfb, 0xf7, +0x50, 0xfc, 0xe9, 0x1d, 0xff, 0x31, 0x1e, 0x31, 0x23, 0x1c, 0x0d, 0x1c, +0x11, 0x4a, 0x01, 0x20, 0xfb, 0xf7, 0x47, 0xfc, 0x29, 0x1c, 0x23, 0x1c, +0x0e, 0x4a, 0x00, 0x20, 0xfb, 0xf7, 0x41, 0xfc, +0x39, 0x1c, 0x23, 0x1c, 0x0c, 0x4a, 0x01, 0x20, 0xfb, 0xf7, 0x3b, 0xfc, +0x00, 0x21, 0x0b, 0x48, 0xc2, 0x1d, 0x19, 0x32, 0x51, 0x71, 0x01, 0x21, +0xff, 0x30, 0x01, 0x30, 0x41, 0x62, 0x08, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x1c, 0xad, 0x20, 0x40, 0x75, 0x08, 0xff, 0xff, +0x28, 0x00, 0x03, 0x00, 0x40, 0x00, 0x02, 0x00, 0x14, 0x00, 0x07, 0x00, +0x6c, 0x06, 0x00, 0x80, 0xf0, 0xb5, 0x37, 0x4a, 0x50, 0x69, 0x01, 0x23, +0x9b, 0x07, 0x08, 0x30, 0x18, 0x43, 0x00, 0x68, 0x01, 0x06, 0x09, 0x0e, +0x33, 0x4b, 0x01, 0x29, 0x49, 0xd1, 0x1f, 0x68, 0x19, 0x1c, 0x32, 0x4b, +0x9f, 0x42, 0x04, 0xd1, 0xff, 0xf7, 0x3e, 0xff, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x23, 0x9f, 0x00, 0xcc, 0x59, 0x55, 0x69, 0xef, 0x19, +0x3c, 0x61, 0x01, 0x33, 0x05, 0x2b, 0xf7, 0xd3, 0x00, 0x0a, 0x00, 0x02, +0x02, 0x23, 0x18, 0x43, 0x53, 0x69, 0xc0, 0x46, 0x98, 0x60, 0x50, 0x69, +0x08, 0x23, 0xc2, 0x68, 0x13, 0x40, 0x25, 0x4f, 0xfa, 0x1d, 0xb9, 0x32, +0x00, 0x2b, 0x02, 0xd0, 0x04, 0x23, 0x23, 0x4c, 0x01, 0xe0, 0x05, 0x23, +0x22, 0x4c, 0xc0, 0x46, 0x14, 0x61, 0x40, 0x24, 0xd4, 0x82, 0x00, 0x24, +0x54, 0x83, 0x20, 0x4c, 0x00, 0x22, 0x00, 0x2b, 0x0c, 0xd9, 0x95, 0x00, +0x46, 0x19, 0x76, 0x6a, 0x66, 0x40, 0xed, 0x19, 0xff, 0x35, 0x01, 0x35, +0x6e, 0x62, 0x01, 0x32, 0x9a, 0x42, 0xf4, 0xd3, 0x10, 0x2a, 0x07, 0xd2, +0x93, 0x00, 0xdb, 0x19, 0xff, 0x33, 0x01, 0x33, 0x5c, 0x62, 0x01, 0x32, +0x10, 0x2a, 0xf7, 0xd3, 0xff, 0xf7, 0x70, 0xff, 0xbc, 0xe7, 0x00, 0x21, +0x8f, 0x00, 0xdc, 0x59, 0x55, 0x69, 0xef, 0x19, 0x7c, 0x62, 0x01, 0x31, +0x05, 0x29, 0xf7, 0xd3, 0x00, 0x0a, 0x00, 0x02, 0x03, 0x23, 0x18, 0x43, +0x51, 0x69, 0xc0, 0x46, 0x88, 0x60, 0x50, 0x69, 0x40, 0x68, 0xc0, 0x46, +0x50, 0x61, 0x09, 0x48, 0xfb, 0xf7, 0xb0, 0xfb, 0xa4, 0xe7, 0x00, 0x00, +0x6c, 0x06, 0x00, 0x80, 0x30, 0x80, 0x20, 0x40, 0x67, 0x45, 0x23, 0x01, +0x1c, 0xad, 0x20, 0x40, 0x28, 0x01, 0x40, 0x00, 0x20, 0x01, 0x40, 0x00, +0x5c, 0x5c, 0x5c, 0x5c, 0xfd, 0x30, 0xff, 0xff, 0x80, 0xb5, 0x87, 0xb0, +0x0f, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x48, 0xf8, 0x0e, 0x49, 0xc8, 0x68, +0x02, 0x04, 0x89, 0x69, 0x4a, 0x40, 0x05, 0x92, 0x09, 0x04, 0xc9, 0x43, +0xc0, 0x43, 0x48, 0x40, 0x06, 0x90, 0x08, 0x21, 0x6a, 0x46, 0x05, 0xa8, +0xfd, 0xf7, 0x8b, 0xfb, 0x00, 0x98, 0xc0, 0x46, 0x38, 0x65, 0x03, 0x98, +0xc0, 0x46, 0x78, 0x65, 0x04, 0x48, 0x01, 0x89, 0x01, 0x31, 0x01, 0x81, +0x07, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x08, 0x83, 0x20, 0x40, +0x0c, 0x2b, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0x20, 0x1c, +0x39, 0x1c, 0x00, 0xf0, 0x1f, 0xf8, 0xe0, 0x68, 0x01, 0x0e, 0xff, 0x22, +0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, 0xff, 0x22, 0x12, 0x02, +0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06, 0x08, 0x43, 0x38, 0x65, +0x20, 0x69, 0xc0, 0x46, 0x78, 0x65, 0x60, 0x69, 0xc0, 0x46, 0xb8, 0x65, +0x03, 0x48, 0x01, 0x89, 0x01, 0x31, 0x01, 0x81, 0x90, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x0c, 0x2b, 0x00, 0x80, 0x90, 0xb5, 0x00, 0x22, +0x93, 0x00, 0x1f, 0x18, 0xbf, 0x69, 0x5b, 0x18, 0x5f, 0x62, 0x01, 0x32, +0x05, 0x2a, 0xf7, 0xd3, 0x07, 0x7a, 0xfb, 0x08, 0x03, 0xd3, 0x00, 0x23, +0x92, 0x00, 0x52, 0x18, 0x13, 0x62, 0x07, 0x6b, 0xc0, 0x46, 0x8f, 0x63, 0xc7, 0x6a, 0xc0, 0x46, 0xcf, 0x63, 0x87, 0x6b, 0xc0, 0x46, 0x0f, 0x64, 0x47, 0x6b, 0xc0, 0x46, 0x4f, 0x64, 0x07, 0x6c, -0xc0, 0x46, 0x8f, 0x64, 0xc2, 0x6b, 0xc0, 0x46, -0xca, 0x64, 0xc2, 0x88, 0xc0, 0x46, 0x0a, 0x80, 0x82, 0x7a, 0x12, 0x06, -0x03, 0x7a, 0x1b, 0x04, 0x1a, 0x43, 0xc3, 0x88, 0x1b, 0x02, 0x1a, 0x43, -0x43, 0x7a, 0xdb, 0x07, 0x1a, 0x43, 0x8a, 0x60, 0x17, 0x1c, 0x83, 0x7a, -0x5a, 0x08, 0x05, 0xd3, 0x14, 0x22, 0x1c, 0x1c, 0xa3, 0x08, 0x02, 0xd2, -0x15, 0x22, 0x00, 0xe0, 0x00, 0x22, 0x00, 0x7a, 0x43, 0x08, 0x10, 0xd3, -0xc0, 0x08, 0x02, 0xd3, 0x88, 0x20, 0x10, 0x43, 0x01, 0xe0, 0x80, 0x20, -0x10, 0x43, 0x3a, 0x0a, 0x12, 0x02, 0x01, 0x23, 0x1a, 0x43, 0xc8, 0x60, -0x8a, 0x60, 0x08, 0x1c, 0xff, 0xf7, 0x14, 0xfe, 0x05, 0xe0, 0x38, 0x0a, -0x00, 0x02, 0x03, 0x23, 0x18, 0x43, 0x88, 0x60, 0xca, 0x60, 0x03, 0x48, -0x01, 0x89, 0x01, 0x31, 0x01, 0x81, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x78, 0x2a, 0x00, 0x80, 0xf0, 0xb4, 0x02, 0x6d, 0x14, 0x4c, 0x15, 0x1c, -0xe7, 0x69, 0xbd, 0x40, 0x13, 0x1c, 0x26, 0x6a, 0xf3, 0x40, 0x5d, 0x40, -0x2e, 0x1c, 0x45, 0x6d, 0xbd, 0x40, 0x6e, 0x40, 0x2b, 0x1c, 0x35, 0x1c, -0xfd, 0x40, 0x2f, 0x1c, 0xbb, 0x00, 0x65, 0x6a, 0xeb, 0x58, 0x00, 0x2b, -0x08, 0xd0, 0x23, 0x69, 0x01, 0x37, 0x9f, 0x42, 0x00, 0xd3, 0x00, 0x27, -0xbe, 0x00, 0xae, 0x59, 0x00, 0x2e, 0xf7, 0xd1, 0xa4, 0x69, 0xa2, 0x40, -0x11, 0x43, 0x05, 0x4b, 0x19, 0x43, 0xba, 0x00, 0xa9, 0x50, 0x40, 0x30, -0x87, 0x83, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0xc8, 0x29, 0x00, 0x80, -0x00, 0x00, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0x00, 0xf0, -0xb1, 0xfa, 0x20, 0x1c, 0x00, 0xf0, 0x0e, 0xfa, 0x38, 0x0c, 0x00, 0xf0, -0x0b, 0xfa, 0x38, 0x0a, 0x00, 0xf0, 0x08, 0xfa, 0x38, 0x1c, 0x00, 0xf0, -0x05, 0xfa, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x07, 0x1c, -0x00, 0xf0, 0x9e, 0xfa, 0x54, 0x20, 0x00, 0xf0, 0xfb, 0xf9, 0x38, 0x0c, -0x00, 0xf0, 0xf8, 0xf9, 0x38, 0x0a, 0x00, 0xf0, 0xf5, 0xf9, 0x38, 0x1c, -0x00, 0xf0, 0xf2, 0xf9, 0x00, 0x20, 0x00, 0xf0, 0xef, 0xf9, 0x80, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0xf0, 0x89, 0xfa, 0x57, 0x20, -0x00, 0xf0, 0xe6, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0xf3, 0xb5, 0x81, 0xb0, -0x41, 0x02, 0x53, 0x20, 0xff, 0xf7, 0xc8, 0xff, 0x00, 0xf0, 0x64, 0xfa, -0x00, 0xf0, 0xf5, 0xf8, 0x00, 0x24, 0x00, 0x26, 0x00, 0x25, 0x00, 0x27, -0x30, 0x1c, 0x01, 0x36, 0xff, 0xf7, 0xd0, 0xff, 0x00, 0xf0, 0x46, 0xf9, -0x00, 0x90, 0x00, 0xf0, 0x55, 0xfa, 0xf8, 0x00, 0x00, 0x99, 0x81, 0x40, -0x0d, 0x43, 0x01, 0x34, 0x01, 0x37, 0x04, 0x2f, 0xee, 0xd3, 0x02, 0x99, -0x20, 0xc1, 0x02, 0x91, 0xff, 0x23, 0x09, 0x33, 0x9c, 0x42, 0xe5, 0xd3, -0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x04, 0x1c, -0x0f, 0x1c, 0x00, 0x26, 0x20, 0xcf, 0xb1, 0x00, 0x84, 0x20, 0xff, 0xf7, -0x9b, 0xff, 0x28, 0x1c, 0x00, 0xf0, 0xae, 0xf9, 0x28, 0x0a, 0x00, 0xf0, -0xab, 0xf9, 0x28, 0x0c, 0x00, 0xf0, 0xa8, 0xf9, 0x28, 0x0e, 0x00, 0xf0, -0xa5, 0xf9, 0x00, 0xf0, 0x2b, 0xfa, 0x01, 0x36, 0x42, 0x2e, 0xe9, 0xd3, -0x61, 0x02, 0x83, 0x20, 0xff, 0xf7, 0x86, 0xff, 0x00, 0xf0, 0x22, 0xfa, -0x00, 0xf0, 0xb3, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, -0x41, 0x02, 0x60, 0x20, 0xff, 0xf7, 0x7a, 0xff, 0x00, 0xf0, 0x16, 0xfa, -0x00, 0xf0, 0xa7, 0xf8, 0x38, 0x1c, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x90, 0xb5, 0x0f, 0x1c, 0x41, 0x02, 0x53, 0x20, -0xff, 0xf7, 0x6c, 0xff, 0x00, 0xf0, 0x08, 0xfa, 0x00, 0xf0, 0x99, 0xf8, -0xf8, 0x1d, 0x05, 0x30, 0x44, 0x1c, 0xff, 0xf7, 0x77, 0xff, 0x00, 0xf0, -0xed, 0xf8, 0x07, 0x1c, 0x00, 0xf0, 0xfc, 0xf9, 0x20, 0x1c, 0xff, 0xf7, -0x6f, 0xff, 0x00, 0xf0, 0xe5, 0xf8, 0x04, 0x1c, 0x00, 0xf0, 0xf4, 0xf9, -0x20, 0x02, 0x38, 0x43, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, -0xc2, 0xb0, 0x04, 0x1c, 0x0d, 0x1c, 0x17, 0x1c, 0x61, 0x02, 0x53, 0x20, -0xff, 0xf7, 0x48, 0xff, 0x00, 0xf0, 0xe4, 0xf9, 0x00, 0xf0, 0x75, 0xf8, -0x68, 0x46, 0x00, 0xf0, 0x5c, 0xf8, 0x6a, 0x46, 0xe8, 0x1d, 0x05, 0x30, -0x17, 0x54, 0x39, 0x0a, 0x68, 0x44, 0x41, 0x70, 0x68, 0x46, 0x00, 0x99, -0x0c, 0x30, 0x00, 0xf0, 0x73, 0xf8, 0x02, 0xab, 0x18, 0x70, 0x00, 0x20, -0x58, 0x70, 0x68, 0x46, 0x0c, 0x21, 0x00, 0xf0, 0x6b, 0xf8, 0x02, 0xab, -0x58, 0x70, 0x69, 0x46, 0x20, 0x1c, 0xff, 0xf7, 0x83, 0xff, 0x42, 0xb0, -0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0xc2, 0xb0, 0x04, 0x1c, -0x1f, 0x1c, 0x6b, 0x46, 0x00, 0x20, 0xc5, 0x43, 0x20, 0xc3, 0x01, 0x30, -0x42, 0x28, 0xfb, 0xd3, 0x68, 0x46, 0x0c, 0x30, 0x03, 0x1c, 0x00, 0x25, -0x00, 0x2a, 0x0a, 0xd9, 0x0e, 0x88, 0xc0, 0x46, 0x06, 0x70, 0x0e, 0x88, -0x36, 0x12, 0x46, 0x70, 0x02, 0x30, 0x02, 0x31, 0x02, 0x35, 0x95, 0x42, -0xf4, 0xd3, 0x00, 0x92, 0x18, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x40, 0xf8, -0x00, 0x26, 0x01, 0x96, 0x02, 0xab, 0x18, 0x70, 0x5e, 0x70, 0x9e, 0x70, -0xde, 0x70, 0x05, 0x1c, 0x68, 0x46, 0x0c, 0x21, 0x00, 0xf0, 0x34, 0xf8, -0x02, 0xab, 0x58, 0x70, 0x38, 0x06, 0x00, 0x0e, 0x85, 0x42, 0x05, 0xd1, -0x69, 0x46, 0x20, 0x1c, 0xff, 0xf7, 0x48, 0xff, 0x30, 0x1c, 0x00, 0xe0, -0x01, 0x20, 0x42, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, -0x07, 0x1c, 0x00, 0x24, 0xff, 0x26, 0x09, 0x36, 0x20, 0x1c, 0xff, 0xf7, -0xf1, 0xfe, 0x00, 0xf0, 0x67, 0xf8, 0x05, 0x1c, 0x00, 0xf0, 0x76, 0xf9, -0x3d, 0x70, 0x28, 0x1c, 0x01, 0x37, 0x01, 0x34, 0xb4, 0x42, 0xf1, 0xd3, -0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0xff, 0xf7, 0xf6, 0xfe, -0x00, 0xf0, 0x56, 0xf8, 0x07, 0x1c, 0x00, 0xf0, 0x65, 0xf9, 0x38, 0x0a, -0xf6, 0xd3, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb4, 0x00, 0x22, -0x00, 0x23, 0x00, 0x29, 0x05, 0xd9, 0x07, 0x78, 0x7a, 0x40, 0x01, 0x30, -0x01, 0x33, 0x8b, 0x42, 0xf9, 0xd3, 0xd0, 0x43, 0x00, 0x06, 0x00, 0x0e, -0x80, 0xbc, 0x70, 0x47, 0xb0, 0xb5, 0xc2, 0xb0, 0x0f, 0x1c, 0x41, 0x02, -0x53, 0x20, 0xff, 0xf7, 0xab, 0xfe, 0x00, 0xf0, 0x47, 0xf9, 0xff, 0xf7, -0xd8, 0xff, 0x68, 0x46, 0xff, 0xf7, 0xbf, 0xff, 0x02, 0xad, 0x6d, 0x78, -0x00, 0x24, 0x02, 0xab, 0x5c, 0x70, 0x68, 0x46, 0x0c, 0x21, 0xff, 0xf7, -0xd9, 0xff, 0xa8, 0x42, 0x02, 0xd1, 0x00, 0x98, 0x87, 0x42, 0x01, 0xd3, -0x20, 0x1c, 0x00, 0xe0, 0x01, 0x20, 0x42, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x80, 0xb5, 0xc2, 0xb0, 0x69, 0x46, 0x02, 0x20, 0xff, 0xf7, -0xbb, 0xfe, 0x68, 0x46, 0xc1, 0x1d, 0x05, 0x31, 0x00, 0x20, 0x07, 0x4a, -0x0f, 0x88, 0x43, 0x00, 0xd7, 0x52, 0x02, 0x31, 0x01, 0x30, 0x00, 0x04, -0x00, 0x0c, 0x25, 0x28, 0xf6, 0xdb, 0x42, 0xb0, 0x80, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0x70, 0x67, 0x21, 0x40, 0xfc, 0x46, 0x60, 0x47, -0x00, 0x00, 0xa0, 0xe3, 0xb4, 0x22, 0x9f, 0xe5, +0xc0, 0x46, 0x8f, 0x64, 0xc2, 0x6b, 0xc0, 0x46, 0xca, 0x64, 0xc2, 0x88, +0xc0, 0x46, 0x0a, 0x80, 0x82, 0x7a, 0x12, 0x06, 0x03, 0x7a, 0x1b, 0x04, +0x1a, 0x43, 0xc3, 0x88, 0x1b, 0x02, 0x1a, 0x43, 0x43, 0x7a, 0xdb, 0x07, +0x1a, 0x43, 0x8a, 0x60, 0x17, 0x1c, 0x83, 0x7a, 0x5a, 0x08, 0x05, 0xd3, +0x14, 0x22, 0x1c, 0x1c, 0xa3, 0x08, 0x02, 0xd2, 0x15, 0x22, 0x00, 0xe0, +0x00, 0x22, 0x00, 0x7a, 0x43, 0x08, 0x10, 0xd3, 0xc0, 0x08, 0x02, 0xd3, +0x88, 0x20, 0x10, 0x43, 0x01, 0xe0, 0x80, 0x20, 0x10, 0x43, 0x3a, 0x0a, +0x12, 0x02, 0x01, 0x23, 0x1a, 0x43, 0xc8, 0x60, 0x8a, 0x60, 0x08, 0x1c, +0xff, 0xf7, 0x0e, 0xfe, 0x05, 0xe0, 0x38, 0x0a, 0x00, 0x02, 0x03, 0x23, +0x18, 0x43, 0x88, 0x60, 0xca, 0x60, 0x03, 0x48, 0x01, 0x89, 0x01, 0x31, +0x01, 0x81, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x0c, 0x2b, 0x00, 0x80, +0xf0, 0xb4, 0x02, 0x6d, 0x14, 0x4c, 0x15, 0x1c, 0xe7, 0x69, 0xbd, 0x40, +0x13, 0x1c, 0x26, 0x6a, 0xf3, 0x40, 0x5d, 0x40, 0x2e, 0x1c, 0x45, 0x6d, +0xbd, 0x40, 0x6e, 0x40, 0x2b, 0x1c, 0x35, 0x1c, 0xfd, 0x40, 0x2f, 0x1c, +0xbb, 0x00, 0x65, 0x6a, 0xeb, 0x58, 0x00, 0x2b, 0x08, 0xd0, 0x23, 0x69, +0x01, 0x37, 0x9f, 0x42, 0x00, 0xd3, 0x00, 0x27, 0xbe, 0x00, 0xae, 0x59, +0x00, 0x2e, 0xf7, 0xd1, 0xa4, 0x69, 0xa2, 0x40, 0x11, 0x43, 0x05, 0x4b, +0x19, 0x43, 0xba, 0x00, 0xa9, 0x50, 0x40, 0x30, 0x87, 0x83, 0xf0, 0xbc, +0x70, 0x47, 0x00, 0x00, 0x4c, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, +0x80, 0xb4, 0x00, 0x22, 0x00, 0x23, 0x00, 0x29, 0x05, 0xd9, 0x07, 0x78, +0x7a, 0x40, 0x01, 0x30, 0x01, 0x33, 0x8b, 0x42, 0xf9, 0xd3, 0xd0, 0x43, +0x00, 0x06, 0x00, 0x0e, 0x80, 0xbc, 0x70, 0x47, 0xf0, 0xb5, 0x07, 0x1c, +0x00, 0x24, 0xff, 0x26, 0x09, 0x36, 0x20, 0x1c, 0x00, 0xf0, 0x8c, 0xf8, +0x00, 0xf0, 0x9e, 0xf9, 0x05, 0x1c, 0x00, 0xf0, 0xad, 0xfa, 0x3d, 0x70, +0x28, 0x1c, 0x01, 0x37, 0x01, 0x34, 0xb4, 0x42, 0xf1, 0xd3, 0xf0, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x00, 0xf0, 0x85, 0xf8, 0x00, 0xf0, +0x8d, 0xf9, 0x07, 0x1c, 0x00, 0xf0, 0x9c, 0xfa, 0x38, 0x0a, 0xf6, 0xd3, +0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf3, 0xb5, 0x81, 0xb0, 0x41, 0x02, +0x53, 0x20, 0x00, 0xf0, 0x57, 0xf8, 0x00, 0xf0, 0x8f, 0xfa, 0xff, 0xf7, +0xe9, 0xff, 0x00, 0x24, 0x00, 0x26, 0x00, 0x25, 0x00, 0x27, 0x30, 0x1c, +0x01, 0x36, 0x00, 0xf0, 0x5f, 0xf8, 0x00, 0xf0, 0x71, 0xf9, 0x00, 0x90, +0x00, 0xf0, 0x80, 0xfa, 0xf8, 0x00, 0x00, 0x99, 0x81, 0x40, 0x0d, 0x43, +0x01, 0x34, 0x01, 0x37, 0x04, 0x2f, 0xee, 0xd3, 0x02, 0x99, 0x20, 0xc1, +0x02, 0x91, 0xff, 0x23, 0x09, 0x33, 0x9c, 0x42, 0xe5, 0xd3, 0x03, 0xb0, +0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, +0x16, 0x48, 0xc0, 0x6f, 0x40, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, +0x00, 0x26, 0x20, 0xcf, 0xb1, 0x00, 0x84, 0x20, 0x00, 0xf0, 0x24, 0xf8, +0x28, 0x1c, 0x00, 0xf0, 0xd3, 0xf9, 0x28, 0x0a, 0x00, 0xf0, 0xd0, 0xf9, +0x28, 0x0c, 0x00, 0xf0, 0xcd, 0xf9, 0x28, 0x0e, 0x00, 0xf0, 0xca, 0xf9, +0x00, 0xf0, 0x50, 0xfa, 0x01, 0x36, 0x42, 0x2e, 0xe9, 0xd3, 0x61, 0x02, +0x83, 0x20, 0x00, 0xf0, 0x0f, 0xf8, 0x00, 0xf0, +0x47, 0xfa, 0xff, 0xf7, 0xa1, 0xff, 0x04, 0x48, 0xc0, 0x6f, 0x40, 0x23, +0x01, 0x68, 0x99, 0x43, 0x01, 0x60, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x68, 0x0e, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0x00, 0xf0, +0x4d, 0xfa, 0x20, 0x1c, 0x00, 0xf0, 0xaa, 0xf9, 0x38, 0x0c, 0x00, 0xf0, +0xa7, 0xf9, 0x38, 0x0a, 0x00, 0xf0, 0xa4, 0xf9, 0x38, 0x1c, 0x00, 0xf0, +0xa1, 0xf9, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, 0x1c, +0x54, 0x20, 0xff, 0xf7, 0xe7, 0xff, 0x00, 0x20, 0x00, 0xf0, 0x96, 0xf9, +0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0xf0, 0x31, 0xfa, 0x57, 0x20, +0x00, 0xf0, 0x8e, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x08, 0x4f, +0xfa, 0x6f, 0x20, 0x23, 0x14, 0x68, 0x9c, 0x43, 0x14, 0x60, 0x23, 0x1c, +0xff, 0xf7, 0x73, 0xff, 0xf8, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43, +0x01, 0x60, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, +0x90, 0xb5, 0x08, 0x4f, 0xfa, 0x6f, 0x20, 0x23, 0x14, 0x68, 0x9c, 0x43, +0x14, 0x60, 0x23, 0x1c, 0xff, 0xf7, 0x89, 0xff, 0xf8, 0x6f, 0x20, 0x23, +0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x68, 0x0e, 0x00, 0x80, 0xb0, 0xb5, 0x0f, 0x1c, 0x15, 0x4d, 0xe9, 0x6f, +0x20, 0x23, 0x0a, 0x68, 0x9a, 0x43, 0x0a, 0x60, 0x41, 0x02, 0x53, 0x20, +0xff, 0xf7, 0xa6, 0xff, 0x00, 0xf0, 0xde, 0xf9, 0xff, 0xf7, 0x38, 0xff, +0xf8, 0x1d, 0x05, 0x30, 0x44, 0x1c, 0xff, 0xf7, 0xb1, 0xff, 0x00, 0xf0, +0xc3, 0xf8, 0x07, 0x1c, 0x00, 0xf0, 0xd2, 0xf9, 0x20, 0x1c, 0xff, 0xf7, +0xa9, 0xff, 0x00, 0xf0, 0xbb, 0xf8, 0x04, 0x1c, 0x00, 0xf0, 0xca, 0xf9, +0xe8, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x21, 0x02, +0x39, 0x43, 0x08, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb5, 0xc2, 0xb0, 0x04, 0x1c, 0x0d, 0x1c, +0x17, 0x1c, 0x61, 0x02, 0x19, 0x4e, 0xf0, 0x6f, 0x20, 0x23, 0x02, 0x68, +0x9a, 0x43, 0x02, 0x60, 0x53, 0x20, 0xff, 0xf7, 0x73, 0xff, 0x00, 0xf0, +0xab, 0xf9, 0xff, 0xf7, 0x05, 0xff, 0x68, 0x46, 0xff, 0xf7, 0xec, 0xfe, +0x6a, 0x46, 0xe8, 0x1d, 0x05, 0x30, 0x17, 0x54, 0x39, 0x0a, 0x68, 0x44, +0x41, 0x70, 0x68, 0x46, 0x00, 0x99, 0x0c, 0x30, 0xff, 0xf7, 0xd0, 0xfe, +0x02, 0xab, 0x18, 0x70, 0x00, 0x20, 0x58, 0x70, 0x68, 0x46, 0x0c, 0x21, +0xff, 0xf7, 0xc8, 0xfe, 0x02, 0xab, 0x58, 0x70, 0x69, 0x46, 0x20, 0x1c, +0xff, 0xf7, 0x1f, 0xff, 0xf0, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43, +0x01, 0x60, 0x42, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x68, 0x0e, 0x00, 0x80, 0xff, 0xb5, 0xc2, 0xb0, 0x07, 0x1c, 0x6b, 0x46, +0x00, 0x20, 0xc4, 0x43, 0x10, 0xc3, 0x01, 0x30, 0x42, 0x28, 0xfb, 0xd3, +0x68, 0x46, 0x0c, 0x30, 0x03, 0x1c, 0x00, 0x24, 0x00, 0x2a, 0x0a, 0xd9, +0x0e, 0x88, 0xc0, 0x46, 0x06, 0x70, 0x0e, 0x88, 0x36, 0x12, 0x46, 0x70, +0x02, 0x30, 0x02, 0x31, 0x02, 0x34, 0x94, 0x42, 0xf4, 0xd3, 0x00, 0x92, +0x18, 0x1c, 0x11, 0x1c, 0xff, 0xf7, 0x96, 0xfe, 0x04, 0x1c, 0x00, 0x20, +0x01, 0x90, 0x02, 0xab, 0x1c, 0x70, 0x58, 0x70, 0x9d, 0x70, 0x68, 0x46, +0x0c, 0x21, 0xff, 0xf7, 0x8b, 0xfe, 0x02, 0xab, 0x58, 0x70, 0x45, 0x9b, +0x1d, 0x06, 0x2d, 0x0e, 0xac, 0x42, 0x03, 0xd1, 0x69, 0x46, 0x38, 0x1c, +0xff, 0xf7, 0x4a, 0xff, 0x01, 0x20, 0xac, 0x42, +0x00, 0xd1, 0x00, 0x20, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0xb0, 0xb5, 0xc2, 0xb0, 0x0f, 0x1c, 0x41, 0x02, 0x14, 0x4c, 0xe0, 0x6f, +0x20, 0x23, 0x02, 0x68, 0x9a, 0x43, 0x02, 0x60, 0x53, 0x20, 0xff, 0xf7, +0xfb, 0xfe, 0x00, 0xf0, 0x33, 0xf9, 0xff, 0xf7, 0x8d, 0xfe, 0x68, 0x46, +0xff, 0xf7, 0x74, 0xfe, 0xe0, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43, +0x02, 0xad, 0x01, 0x60, 0x6d, 0x78, 0x00, 0x24, 0x02, 0xab, 0x5c, 0x70, +0x68, 0x46, 0x0c, 0x21, 0xff, 0xf7, 0x56, 0xfe, 0xa8, 0x42, 0x02, 0xd1, +0x00, 0x98, 0x87, 0x42, 0x01, 0xd3, 0x20, 0x1c, 0x00, 0xe0, 0x01, 0x20, +0x42, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, +0xfc, 0x46, 0x60, 0x47, 0x00, 0x00, 0xa0, 0xe3, 0xb4, 0x22, 0x9f, 0xe5, 0xb4, 0x32, 0x9f, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5, 0x81, 0x03, 0x80, 0xe1, @@ -3675,17 +3858,17 @@ 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x20, 0x12, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, +0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, +0xa0, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, -0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0xa0, 0x11, 0xa0, 0xe1, +0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x20, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, -0x00, 0x10, 0x82, 0xe5, 0x20, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, +0x00, 0x10, 0x82, 0xe5, 0xa0, 0x10, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, -0xa0, 0x10, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, -0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, -0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe1, -0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, +0x00, 0x10, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xfc, 0x46, 0x60, 0x47, 0xa0, 0x30, 0x9f, 0xe5, 0x01, 0x10, 0xa0, 0xe3, @@ -3714,82 +3897,82 @@ 0x0a, 0x60, 0x70, 0x47, 0xb0, 0x6e, 0x21, 0x40, 0xf0, 0xb5, 0x07, 0x1c, 0x00, 0x24, 0x00, 0x2f, 0x21, 0xd0, 0x00, 0x26, 0xf8, 0x79, 0x00, 0x28, 0x1b, 0xdd, 0x30, 0x01, 0xc0, 0x19, 0xc5, 0x1d, 0x05, 0x35, 0x00, 0x7b, -0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 0x92, 0xfb, 0x01, 0x1c, 0x8b, 0x68, +0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 0x9e, 0xfb, 0x01, 0x1c, 0x8b, 0x68, 0x00, 0x2b, 0x08, 0xd0, 0x68, 0x68, 0x00, 0x28, 0x05, 0xd0, 0xca, 0x68, -0xa9, 0x68, 0xfb, 0xf7, 0x4a, 0xfb, 0x00, 0x20, 0x68, 0x60, 0x70, 0x1c, +0xa9, 0x68, 0xfa, 0xf7, 0x4e, 0xff, 0x00, 0x20, 0x68, 0x60, 0x70, 0x1c, 0x06, 0x06, 0x36, 0x0e, 0xf8, 0x79, 0xb0, 0x42, 0xe3, 0xdc, 0xff, 0x20, -0x38, 0x72, 0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf3, 0xb5, -0x81, 0xb0, 0x0f, 0x1c, 0x68, 0x46, 0xff, 0xf7, 0xbd, 0xff, 0x00, 0x28, -0x01, 0xd1, 0x0d, 0x20, 0x37, 0xe0, 0xb9, 0x88, 0xc0, 0x46, 0x01, 0x80, -0xf9, 0x88, 0xc0, 0x46, 0x41, 0x80, 0xb9, 0x7a, 0xc0, 0x46, 0x41, 0x71, -0xf9, 0x7a, 0xc0, 0x46, 0x81, 0x71, 0x8c, 0x21, 0x01, 0x71, 0x3d, 0x7e, -0x00, 0x21, 0x00, 0x23, 0x00, 0x2d, 0x1f, 0xdd, 0x1a, 0x01, 0xd2, 0x19, -0x1c, 0x32, 0x16, 0x78, 0x05, 0x2e, 0x0d, 0xdc, 0x0c, 0x01, 0x24, 0x18, -0x26, 0x73, 0x96, 0x68, 0xc0, 0x46, 0x66, 0x61, 0xd6, 0x68, 0xc0, 0x46, -0x26, 0x61, 0x00, 0x24, 0x01, 0x31, 0x09, 0x06, 0x09, 0x0e, 0xd4, 0x60, -0x5a, 0x1c, 0x13, 0x06, 0x1b, 0x0e, 0xab, 0x42, 0xe6, 0xdb, 0x00, 0x29, -0x04, 0xd0, 0xc1, 0x71, 0x00, 0x99, 0xc0, 0x46, +0x38, 0x72, 0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0xf3, 0xb5, 0x81, 0xb0, 0x0f, 0x1c, 0x68, 0x46, 0xff, 0xf7, +0xbd, 0xff, 0x00, 0x28, 0x01, 0xd1, 0x0d, 0x20, 0x37, 0xe0, 0xb9, 0x88, +0xc0, 0x46, 0x01, 0x80, 0xf9, 0x88, 0xc0, 0x46, 0x41, 0x80, 0xb9, 0x7a, +0xc0, 0x46, 0x41, 0x71, 0xf9, 0x7a, 0xc0, 0x46, 0x81, 0x71, 0x8c, 0x21, +0x01, 0x71, 0x3d, 0x7e, 0x00, 0x21, 0x00, 0x23, 0x00, 0x2d, 0x1f, 0xdd, +0x1a, 0x01, 0xd2, 0x19, 0x1c, 0x32, 0x16, 0x78, 0x05, 0x2e, 0x0d, 0xdc, +0x0c, 0x01, 0x24, 0x18, 0x26, 0x73, 0x96, 0x68, 0xc0, 0x46, 0x66, 0x61, +0xd6, 0x68, 0xc0, 0x46, 0x26, 0x61, 0x00, 0x24, 0x01, 0x31, 0x09, 0x06, +0x09, 0x0e, 0xd4, 0x60, 0x5a, 0x1c, 0x13, 0x06, 0x1b, 0x0e, 0xab, 0x42, +0xe6, 0xdb, 0x00, 0x29, 0x04, 0xd0, 0xc1, 0x71, 0x00, 0x99, 0xc0, 0x46, 0x01, 0x72, 0x00, 0xe0, 0x00, 0x20, 0x01, 0x99, 0xc0, 0x46, 0x08, 0x60, 0x00, 0x20, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x07, 0x1c, 0x38, 0x7e, 0x00, 0x28, 0x28, 0xd0, 0x01, 0x38, 0x05, 0x06, 0x2d, 0x0e, 0x00, 0x26, 0xff, 0x2d, 0x21, 0xd0, 0x28, 0x01, 0xc0, 0x19, 0xc4, 0x1d, 0x15, 0x34, 0x00, 0x7f, 0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, -0x1f, 0xfb, 0x01, 0x1c, 0x11, 0xd0, 0x8a, 0x68, 0x00, 0x2a, 0x0c, 0xd0, +0x2b, 0xfb, 0x01, 0x1c, 0x11, 0xd0, 0x8a, 0x68, 0x00, 0x2a, 0x0c, 0xd0, 0xe0, 0x68, 0x00, 0x28, 0x09, 0xd0, 0x00, 0x23, 0xcb, 0x56, 0x05, 0x2b, -0x05, 0xdc, 0x13, 0x1c, 0xca, 0x68, 0xa1, 0x68, 0xfb, 0xf7, 0xd1, 0xfa, +0x05, 0xdc, 0x13, 0x1c, 0xca, 0x68, 0xa1, 0x68, 0xfa, 0xf7, 0xd5, 0xfe, 0xe6, 0x60, 0xff, 0x20, 0x20, 0x70, 0x68, 0x1e, 0x05, 0x06, 0x2d, 0x0e, 0xff, 0x2d, 0xdd, 0xd1, 0x3e, 0x76, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x13, 0x20, 0x70, 0x47, 0xf0, 0xb5, 0x82, 0xb0, 0x07, 0x1c, 0xf8, 0x1d, 0xd5, 0x30, 0x39, 0x1c, 0xff, 0xf7, 0x7f, 0xff, 0x00, 0x90, 0x00, 0x98, 0x00, 0x28, 0x3b, 0xd1, 0x38, 0x7e, 0xc0, 0x46, 0x01, 0x90, 0x00, 0x26, 0x01, 0x98, 0x00, 0x28, 0x2d, 0xdd, 0x30, 0x01, 0xc0, 0x19, 0xc5, 0x1d, -0x15, 0x35, 0x00, 0x7f, 0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 0xe4, 0xfa, +0x15, 0x35, 0x00, 0x7f, 0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 0xf0, 0xfa, 0x04, 0x1c, 0x20, 0x69, 0x00, 0x28, 0x17, 0xd0, 0x28, 0x78, 0x05, 0x28, 0x0d, 0xdd, 0xe9, 0x68, 0xaa, 0x68, 0x60, 0x68, 0x40, 0x08, 0x40, 0x00, -0x01, 0xf0, 0x0e, 0xf8, 0x09, 0x22, 0xe8, 0x68, 0xa9, 0x68, 0xfb, 0xf7, -0x87, 0xf9, 0x00, 0x20, 0xe8, 0x60, 0x21, 0x69, 0x28, 0x1c, 0xfb, 0xf7, -0x8c, 0xfa, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x90, 0x00, 0x98, 0x00, 0x28, +0x01, 0xf0, 0x2c, 0xf8, 0x09, 0x22, 0xe8, 0x68, 0xa9, 0x68, 0xfa, 0xf7, +0x8b, 0xfd, 0x00, 0x20, 0xe8, 0x60, 0x21, 0x69, 0x28, 0x1c, 0xfa, 0xf7, +0x90, 0xfe, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x90, 0x00, 0x98, 0x00, 0x28, 0x0c, 0xd1, 0x70, 0x1c, 0x06, 0x06, 0x36, 0x0e, 0x01, 0x98, 0x86, 0x42, 0xd1, 0xdb, 0x00, 0x20, 0x38, 0x76, 0x00, 0x98, 0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0xff, 0xf7, 0x82, 0xff, 0xf6, 0xe7, 0xc1, 0x1d, 0x79, 0x31, 0x4a, 0x6b, 0xc0, 0x46, 0xca, 0x63, 0xc1, 0x1d, 0xb9, 0x31, 0x0a, 0x60, 0x00, 0x22, 0x8a, 0x60, 0x04, 0x4a, 0xc0, 0x46, 0x4a, 0x61, 0x8a, 0x61, 0x01, 0x21, 0xd0, 0x30, 0x41, 0x70, 0x08, 0x1c, -0x70, 0x47, 0x00, 0x00, 0xb9, 0xbd, 0x21, 0x40, 0xf8, 0xb5, 0x07, 0x1c, +0x70, 0x47, 0x00, 0x00, 0xb1, 0xc5, 0x21, 0x40, 0xf8, 0xb5, 0x07, 0x1c, 0x00, 0x20, 0x00, 0x90, 0xfe, 0x1d, 0xc9, 0x36, 0x30, 0x78, 0x00, 0x01, 0xc0, 0x19, 0xc4, 0x1d, 0x15, 0x34, 0x80, 0x6a, 0x45, 0x08, 0x6d, 0x00, 0x04, 0x21, 0x38, 0x1c, 0xff, 0xf7, 0xb2, 0xfe, 0x31, 0x78, 0x40, 0x18, 0x01, 0x06, 0x09, 0x0e, 0x00, 0x20, 0xa2, 0x68, 0x00, 0x2a, 0x0a, 0xd9, 0x2a, 0x78, 0x4a, 0x40, 0x2a, 0x70, 0x01, 0x30, 0x09, 0x18, 0x09, 0x06, -0x09, 0x0e, 0xa2, 0x68, 0x01, 0x35, 0x82, 0x42, 0xf4, 0xd8, 0xe0, 0x68, -0xa1, 0x68, 0x40, 0x08, 0x40, 0x00, 0xff, 0xf7, 0x99, 0xfe, 0x61, 0x78, -0x81, 0x42, 0x0a, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x0f, 0xf8, 0xf8, 0x1d, -0x79, 0x30, 0x80, 0x6b, 0xf9, 0x1d, 0xb9, 0x31, 0xc8, 0x60, 0x0c, 0x20, -0x00, 0x90, 0x30, 0x78, 0x01, 0x30, 0x30, 0x70, 0x00, 0x98, 0xf8, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0xc2, 0x1d, 0xc9, 0x32, 0x11, 0x78, 0x09, 0x01, -0x09, 0x18, 0x09, 0x6a, 0xc3, 0x1d, 0x79, 0x33, 0xd9, 0x63, 0x13, 0x78, -0x1b, 0x01, 0x1b, 0x18, 0x5b, 0x6a, 0xcb, 0x18, 0xc1, 0x1d, 0xb9, 0x31, -0x0b, 0x60, 0x13, 0x78, 0x1b, 0x01, 0x1b, 0x18, 0x9b, 0x6a, 0xc0, 0x46, -0x8b, 0x60, 0x07, 0x4b, 0xc0, 0x46, 0x4b, 0x61, 0x12, 0x78, 0x00, 0x7e, -0x01, 0x32, 0x82, 0x42, 0x01, 0xdb, 0x04, 0x48, +0x09, 0x0e, 0xa2, 0x68, 0x01, 0x35, 0x82, 0x42, +0xf4, 0xd8, 0xe0, 0x68, 0xa1, 0x68, 0x40, 0x08, 0x40, 0x00, 0xff, 0xf7, +0x99, 0xfe, 0x61, 0x78, 0x81, 0x42, 0x0a, 0xd0, 0x38, 0x1c, 0x00, 0xf0, +0x0f, 0xf8, 0xf8, 0x1d, 0x79, 0x30, 0x80, 0x6b, 0xf9, 0x1d, 0xb9, 0x31, +0xc8, 0x60, 0x0c, 0x20, 0x00, 0x90, 0x30, 0x78, 0x01, 0x30, 0x30, 0x70, +0x00, 0x98, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xc2, 0x1d, 0xc9, 0x32, +0x11, 0x78, 0x09, 0x01, 0x09, 0x18, 0x09, 0x6a, 0xc3, 0x1d, 0x79, 0x33, +0xd9, 0x63, 0x13, 0x78, 0x1b, 0x01, 0x1b, 0x18, 0x5b, 0x6a, 0xcb, 0x18, +0xc1, 0x1d, 0xb9, 0x31, 0x0b, 0x60, 0x13, 0x78, 0x1b, 0x01, 0x1b, 0x18, +0x9b, 0x6a, 0xc0, 0x46, 0x8b, 0x60, 0x07, 0x4b, 0xc0, 0x46, 0x4b, 0x61, +0x12, 0x78, 0x00, 0x7e, 0x01, 0x32, 0x82, 0x42, 0x01, 0xdb, 0x04, 0x48, 0x00, 0xe0, 0x04, 0x48, 0xc0, 0x46, 0x88, 0x61, 0x00, 0x20, 0x70, 0x47, -0x81, 0xbe, 0x21, 0x40, 0x55, 0xbe, 0x21, 0x40, 0x01, 0xbf, 0x21, 0x40, +0x79, 0xc6, 0x21, 0x40, 0x4d, 0xc6, 0x21, 0x40, 0xf9, 0xc6, 0x21, 0x40, 0xf8, 0xb5, 0x04, 0x1c, 0x00, 0x20, 0x00, 0x90, 0x25, 0x7e, 0x29, 0x01, 0xe0, 0x1d, 0x15, 0x30, 0xff, 0xf7, 0x4e, 0xfe, 0xa1, 0x7e, 0x81, 0x42, 0x0a, 0xd0, 0x20, 0x1c, 0x00, 0xf0, 0x61, 0xf8, 0xe0, 0x1d, 0x79, 0x30, 0x80, 0x6b, 0xe1, 0x1d, 0xb9, 0x31, 0xc8, 0x60, 0x0b, 0x20, 0x55, 0xe0, 0x00, 0x27, 0x00, 0x2d, 0x0f, 0xdd, 0x38, 0x01, 0x00, 0x19, 0x00, 0x7f, -0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 0x10, 0xfa, 0x00, 0x28, 0x01, 0xd1, +0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 0x1c, 0xfa, 0x00, 0x28, 0x01, 0xd1, 0x09, 0x20, 0x47, 0xe0, 0x78, 0x1c, 0x07, 0x06, 0x3f, 0x0e, 0xaf, 0x42, 0xef, 0xdb, 0x00, 0x26, 0x00, 0x2d, 0x38, 0xdd, 0x30, 0x01, 0x00, 0x19, 0xc7, 0x1d, 0x15, 0x37, 0x00, 0x7f, 0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, -0xfb, 0xf9, 0x00, 0x23, 0xc1, 0x56, 0x05, 0x29, 0x0c, 0xdc, 0x42, 0x68, -0x00, 0x2a, 0x04, 0xd0, 0xc1, 0x68, 0xb8, 0x68, 0xfb, 0xf7, 0xb2, 0xf9, +0x07, 0xfa, 0x00, 0x23, 0xc1, 0x56, 0x05, 0x29, 0x0c, 0xdc, 0x42, 0x68, +0x00, 0x2a, 0x04, 0xd0, 0xc1, 0x68, 0xb8, 0x68, 0xfa, 0xf7, 0xb6, 0xfd, 0xf8, 0x60, 0xf8, 0x68, 0x00, 0x28, 0x1b, 0xd1, 0x0e, 0x20, 0x17, 0xe0, -0xc0, 0x68, 0x00, 0x28, 0x07, 0xd0, 0xfb, 0xf7, 0xa5, 0xf9, 0x00, 0x28, +0xc0, 0x68, 0x00, 0x28, 0x07, 0xd0, 0xfa, 0xf7, 0xa9, 0xfd, 0x00, 0x28, 0x05, 0xda, 0x40, 0x42, 0xb9, 0x68, 0x81, 0x42, 0x04, 0xd0, 0x05, 0x20, 0x0a, 0xe0, 0xb9, 0x68, 0x81, 0x42, 0xfa, 0xd8, 0x09, 0x21, 0xb8, 0x68, -0xfb, 0xf7, 0x7a, 0xf8, 0xf8, 0x60, 0x00, 0x28, 0x02, 0xd1, 0x06, 0x20, +0xfa, 0xf7, 0x7e, 0xfc, 0xf8, 0x60, 0x00, 0x28, 0x02, 0xd1, 0x06, 0x20, 0x00, 0x90, 0x07, 0xe0, 0x70, 0x1c, 0x06, 0x06, 0x36, 0x0e, 0xae, 0x42, 0xc6, 0xdb, 0x00, 0x98, 0x00, 0x28, 0x02, 0xd0, 0x20, 0x1c, 0xff, 0xf7, 0x92, 0xfe, 0x00, 0x98, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xc2, 0x1d, @@ -3797,25 +3980,25 @@ 0x8a, 0x18, 0xc1, 0x1d, 0xb9, 0x31, 0x0a, 0x60, 0xc2, 0x1d, 0x15, 0x32, 0x8a, 0x60, 0x05, 0x4a, 0xc0, 0x46, 0x4a, 0x61, 0x04, 0x4a, 0xc0, 0x46, 0x8a, 0x61, 0x00, 0x21, 0xd0, 0x30, 0x01, 0x70, 0x08, 0x1c, 0x70, 0x47, -0x59, 0xbf, 0x21, 0x40, 0x01, 0xbf, 0x21, 0x40, 0x90, 0xb5, 0x07, 0x1c, +0x51, 0xc7, 0x21, 0x40, 0xf9, 0xc6, 0x21, 0x40, 0x90, 0xb5, 0x07, 0x1c, 0x38, 0x68, 0x1d, 0x4b, 0x98, 0x42, 0x03, 0xd0, 0x03, 0x20, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x1c, 0x21, 0x38, 0x1c, 0xff, 0xf7, 0xbc, 0xfd, 0xfc, 0x1d, 0x79, 0x34, 0x00, 0x28, 0x09, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x2d, 0xf8, 0xf9, 0x1d, 0xb9, 0x31, 0xa0, 0x6b, 0xc0, 0x46, 0xc8, 0x60, 0x0a, 0x20, 0xea, 0xe7, 0x38, 0x7a, 0x1c, 0x28, 0x04, 0xd0, 0x78, 0x7a, 0x10, 0x28, 0x01, 0xd0, 0x04, 0x20, 0xe2, 0xe7, 0xb8, 0x7a, 0x01, 0x28, -0x01, 0xd0, 0x07, 0x20, 0xdd, 0xe7, 0x60, 0x6b, 0xf9, 0x68, 0x88, 0x42, -0x01, 0xd0, 0x05, 0x20, 0xd7, 0xe7, 0x38, 0x69, 0x00, 0x28, 0x04, 0xd0, -0x06, 0x4b, 0x98, 0x42, 0x01, 0xd0, 0x08, 0x20, 0xcf, 0xe7, 0x38, 0x7e, -0x08, 0x28, 0x01, 0xdd, 0x12, 0x20, 0xca, 0xe7, 0x00, 0x20, 0xc8, 0xe7, -0x73, 0x6e, 0x69, 0x70, 0x17, 0x40, 0x00, 0x02, 0xb8, 0xb5, 0x07, 0x1c, -0x38, 0x1c, 0xff, 0xf7, 0x2a, 0xfe, 0x00, 0x25, 0xf8, 0x1d, 0xc9, 0x30, -0x45, 0x70, 0xfc, 0x1d, 0xb9, 0x34, 0xe5, 0x61, 0x68, 0x46, 0xff, 0xf7, -0x9d, 0xfd, 0x00, 0x28, 0x01, 0xd1, 0x0d, 0x20, 0x0d, 0xe0, 0xf8, 0x1d, -0x79, 0x30, 0x85, 0x63, 0xc5, 0x63, 0x1b, 0x20, 0x20, 0x60, 0xa7, 0x60, -0x04, 0x48, 0xc0, 0x46, 0x60, 0x61, 0x04, 0x48, 0xc0, 0x46, 0xa0, 0x61, -0x28, 0x1c, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0x75, 0xc0, 0x21, 0x40, 0x3b, 0xc0, 0x21, 0x40, 0xf0, 0xb5, 0x82, 0xb0, +0x01, 0xd0, 0x07, 0x20, 0xdd, 0xe7, 0x60, 0x6b, +0xf9, 0x68, 0x88, 0x42, 0x01, 0xd0, 0x05, 0x20, 0xd7, 0xe7, 0x38, 0x69, +0x00, 0x28, 0x04, 0xd0, 0x06, 0x4b, 0x98, 0x42, 0x01, 0xd0, 0x08, 0x20, +0xcf, 0xe7, 0x38, 0x7e, 0x08, 0x28, 0x01, 0xdd, 0x12, 0x20, 0xca, 0xe7, +0x00, 0x20, 0xc8, 0xe7, 0x73, 0x6e, 0x69, 0x70, 0x02, 0x10, 0x00, 0x03, +0xb8, 0xb5, 0x07, 0x1c, 0x38, 0x1c, 0xff, 0xf7, 0x2a, 0xfe, 0x00, 0x25, +0xf8, 0x1d, 0xc9, 0x30, 0x45, 0x70, 0xfc, 0x1d, 0xb9, 0x34, 0xe5, 0x61, +0x68, 0x46, 0xff, 0xf7, 0x9d, 0xfd, 0x00, 0x28, 0x01, 0xd1, 0x0d, 0x20, +0x0d, 0xe0, 0xf8, 0x1d, 0x79, 0x30, 0x85, 0x63, 0xc5, 0x63, 0x1b, 0x20, +0x20, 0x60, 0xa7, 0x60, 0x04, 0x48, 0xc0, 0x46, 0x60, 0x61, 0x04, 0x48, +0xc0, 0x46, 0xa0, 0x61, 0x28, 0x1c, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x6d, 0xc8, 0x21, 0x40, 0x33, 0xc8, 0x21, 0x40, 0xf0, 0xb5, 0x82, 0xb0, 0x07, 0x1c, 0x00, 0x20, 0xfd, 0x1d, 0x79, 0x35, 0xfc, 0x1d, 0xb9, 0x34, 0xe9, 0x6a, 0xc0, 0x46, 0x61, 0x60, 0x62, 0x68, 0xe9, 0x6b, 0x8a, 0x42, 0x03, 0xd2, 0x61, 0x60, 0x2a, 0x6b, 0x91, 0x42, 0x34, 0xd2, 0x66, 0x68, @@ -3823,52 +4006,54 @@ 0x26, 0x68, 0x2a, 0x6b, 0x96, 0x42, 0x00, 0xd2, 0x32, 0x1c, 0x01, 0x9e, 0x96, 0x1b, 0xa2, 0x68, 0xc0, 0x46, 0x00, 0x92, 0x00, 0x2a, 0x09, 0xd0, 0x28, 0x6a, 0x6a, 0x6a, 0x41, 0x18, 0x00, 0x98, 0xc0, 0x18, 0x33, 0x1c, -0xfc, 0xf7, 0xc4, 0xff, 0x00, 0x28, 0x1b, 0xd1, 0x61, 0x68, 0x89, 0x19, +0xfc, 0xf7, 0x68, 0xff, 0x00, 0x28, 0x1b, 0xd1, 0x61, 0x68, 0x89, 0x19, 0x61, 0x60, 0x22, 0x68, 0x91, 0x42, 0x0d, 0xd1, 0x61, 0x69, 0x38, 0x1c, -0xfb, 0xf7, 0xc1, 0xf8, 0x00, 0x06, 0x00, 0x0e, 0x0e, 0xd1, 0xa1, 0x69, -0x38, 0x1c, 0xfb, 0xf7, 0xba, 0xf8, 0x00, 0x06, 0x00, 0x0e, 0x07, 0xd1, +0xfa, 0xf7, 0xc5, 0xfc, 0x00, 0x06, 0x00, 0x0e, 0x0e, 0xd1, 0xa1, 0x69, +0x38, 0x1c, 0xfa, 0xf7, 0xbe, 0xfc, 0x00, 0x06, 0x00, 0x0e, 0x07, 0xd1, 0x61, 0x68, 0x2a, 0x6b, 0x91, 0x42, 0xc2, 0xd3, 0xa9, 0x6b, 0xaa, 0x6a, 0x89, 0x18, 0xa9, 0x63, 0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0xb0, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xfb, 0xf7, -0xbf, 0xfa, 0xfa, 0x1d, 0x09, 0x32, 0x32, 0x48, 0x00, 0x21, 0xc9, 0x43, -0xc4, 0x1d, 0xb9, 0x34, 0xe1, 0x60, 0xf9, 0x88, 0xc3, 0x1d, 0x89, 0x33, -0x19, 0x73, 0xc1, 0x1d, 0x79, 0x31, 0xbd, 0x68, 0xc0, 0x46, 0x0d, 0x62, -0xff, 0x68, 0xc0, 0x46, 0x4f, 0x62, 0x17, 0x68, 0xc0, 0x46, 0x8f, 0x62, -0x57, 0x68, 0xc0, 0x46, 0xcf, 0x62, 0x92, 0x68, 0xc0, 0x46, 0x4a, 0x63, -0xca, 0x6a, 0x8f, 0x6a, 0xd2, 0x19, 0x0a, 0x63, 0x1a, 0x7b, 0x01, 0x2a, -0x0d, 0xd0, 0x02, 0x2a, 0x1a, 0xd0, 0x03, 0x2a, 0x2e, 0xd1, 0xc2, 0x1d, -0xc9, 0x32, 0x52, 0x78, 0x00, 0x2a, 0x07, 0xd1, 0x10, 0x20, 0x89, 0x6b, -0xc0, 0x46, 0xe1, 0x60, 0x25, 0xe0, 0xff, 0xf7, 0x4d, 0xff, 0x22, 0xe0, -0xff, 0xf7, 0xac, 0xfd, 0x00, 0x28, 0x1e, 0xd1, 0xe1, 0x69, 0x00, 0x29, -0x1b, 0xd0, 0x09, 0x7a, 0x15, 0x4b, 0xc9, 0x18, 0x02, 0x91, 0x16, 0xe0, -0x8a, 0x6a, 0xcb, 0x6a, 0x9f, 0x18, 0x4d, 0x6b, 0xaf, 0x42, 0x05, 0xd8, -0x00, 0x2a, 0x03, 0xd0, 0x9f, 0x07, 0x01, 0xd1, 0x92, 0x07, 0x01, 0xd0, -0x0f, 0x20, 0x08, 0xe0, 0x89, 0x6b, 0x99, 0x42, 0x01, 0xd0, 0xe1, 0x60, -0xf8, 0xe7, 0xff, 0xf7, 0x53, 0xff, 0x00, 0xe0, 0x10, 0x20, 0x01, 0xab, -0x58, 0x80, 0xe0, 0x68, 0xc0, 0x46, 0x03, 0x90, 0x68, 0x46, 0x00, 0x21, -0xfb, 0xf7, 0x9e, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0x3c, 0xac, 0x20, 0x40, 0x0d, 0xf0, 0xfe, 0xca, -0x80, 0xb5, 0x85, 0xb0, 0x07, 0x1c, 0x38, 0x1c, 0x01, 0xa9, 0xfb, 0xf7, -0x4d, 0xfa, 0x68, 0x46, 0xb9, 0x68, 0xff, 0xf7, 0xa0, 0xfc, 0x00, 0x28, -0x02, 0xd1, 0x00, 0x98, 0xff, 0xf7, 0xc4, 0xfc, 0x02, 0xab, 0x58, 0x80, -0x00, 0x21, 0x01, 0xa8, 0xfb, 0xf7, 0x7e, 0xf9, 0x01, 0x20, 0x05, 0xb0, -0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x85, 0xb0, 0x07, 0x1c, -0x38, 0x1c, 0x01, 0xa9, 0xfb, 0xf7, 0x32, 0xfa, 0x68, 0x46, 0xb9, 0x68, -0xff, 0xf7, 0x85, 0xfc, 0x00, 0x28, 0x00, 0xd1, 0x02, 0x20, 0x02, 0xab, -0x58, 0x80, 0x00, 0x21, 0x01, 0xa8, 0xfb, 0xf7, 0x65, 0xf9, 0x01, 0x20, -0x05, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x85, 0xb0, -0x07, 0x1c, 0x38, 0x1c, 0x01, 0xa9, 0xfb, 0xf7, -0x19, 0xfa, 0x3c, 0x69, 0x38, 0x1c, 0x01, 0xa9, 0xfb, 0xf7, 0x14, 0xfa, -0x68, 0x46, 0x21, 0x1c, 0xff, 0xf7, 0x67, 0xfc, 0x8c, 0x24, 0x00, 0x28, +0xf0, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xfa, 0xf7, +0xc3, 0xfe, 0xfa, 0x1d, 0x09, 0x32, 0x37, 0x49, 0x00, 0x20, 0xc0, 0x43, +0xcc, 0x1d, 0xb9, 0x34, 0xe0, 0x60, 0xf8, 0x88, 0xcb, 0x1d, 0x89, 0x33, +0x18, 0x73, 0xc8, 0x1d, 0x79, 0x30, 0xbd, 0x68, 0xc0, 0x46, 0x05, 0x62, +0xff, 0x68, 0xc0, 0x46, 0x47, 0x62, 0x17, 0x68, 0xc0, 0x46, 0x87, 0x62, +0x57, 0x68, 0xc0, 0x46, 0xc7, 0x62, 0x92, 0x68, 0xc0, 0x46, 0x42, 0x63, +0xc2, 0x6a, 0x87, 0x6a, 0xd2, 0x19, 0x02, 0x63, 0x1a, 0x7b, 0x28, 0x4d, +0x01, 0x2a, 0x0d, 0xd0, 0x02, 0x2a, 0x1c, 0xd0, 0x03, 0x2a, 0x35, 0xd1, +0xca, 0x1d, 0xc9, 0x32, 0x52, 0x78, 0x00, 0x2a, 0x08, 0xd1, 0x10, 0x27, +0x80, 0x6b, 0xc0, 0x46, 0xe0, 0x60, 0x2c, 0xe0, 0x08, 0x1c, 0xff, 0xf7, +0x4b, 0xff, 0x22, 0xe0, 0x08, 0x1c, 0xff, 0xf7, 0xa9, 0xfd, 0x07, 0x1c, +0x23, 0xd1, 0xe0, 0x69, 0x00, 0x28, 0x1c, 0xd0, 0x00, 0x7a, 0x1a, 0x4b, +0xc0, 0x18, 0x02, 0x90, 0x17, 0xe0, 0x82, 0x6a, 0xc3, 0x6a, 0x9f, 0x18, +0x46, 0x6b, 0xb7, 0x42, 0x05, 0xd8, 0x00, 0x2a, 0x03, 0xd0, 0x9f, 0x07, +0x01, 0xd1, 0x92, 0x07, 0x01, 0xd0, 0x0f, 0x27, 0x0d, 0xe0, 0x80, 0x6b, +0x98, 0x42, 0x01, 0xd0, 0xe0, 0x60, 0xf8, 0xe7, 0x08, 0x1c, 0xff, 0xf7, +0x4f, 0xff, 0x07, 0x1c, 0x03, 0xd1, 0x00, 0xf0, 0x1f, 0xfe, 0x01, 0xe0, +0x10, 0x27, 0x00, 0x20, 0x28, 0x65, 0x01, 0xab, 0x5f, 0x80, 0xe0, 0x68, +0xc0, 0x46, 0x03, 0x90, 0x68, 0x46, 0x00, 0x21, +0xfa, 0xf7, 0x98, 0xfd, 0x01, 0x20, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x3c, 0xac, 0x20, 0x40, 0x00, 0x00, 0x00, 0x80, +0x0d, 0xf0, 0xfe, 0xca, 0x80, 0xb5, 0x85, 0xb0, 0x07, 0x1c, 0x38, 0x1c, +0x01, 0xa9, 0xfa, 0xf7, 0x45, 0xfe, 0x68, 0x46, 0xb9, 0x68, 0xff, 0xf7, +0x94, 0xfc, 0x00, 0x28, 0x02, 0xd1, 0x00, 0x98, 0xff, 0xf7, 0xb8, 0xfc, +0x02, 0xab, 0x58, 0x80, 0x00, 0x21, 0x01, 0xa8, 0xfa, 0xf7, 0x76, 0xfd, +0x01, 0x20, 0x05, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, +0x85, 0xb0, 0x07, 0x1c, 0x38, 0x1c, 0x01, 0xa9, 0xfa, 0xf7, 0x2a, 0xfe, +0x68, 0x46, 0xb9, 0x68, 0xff, 0xf7, 0x79, 0xfc, 0x00, 0x28, 0x00, 0xd1, +0x02, 0x20, 0x02, 0xab, 0x58, 0x80, 0x00, 0x21, 0x01, 0xa8, 0xfa, 0xf7, +0x5d, 0xfd, 0x01, 0x20, 0x05, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x90, 0xb5, 0x85, 0xb0, 0x07, 0x1c, 0x38, 0x1c, 0x01, 0xa9, 0xfa, 0xf7, +0x11, 0xfe, 0x3c, 0x69, 0x38, 0x1c, 0x01, 0xa9, 0xfa, 0xf7, 0x0c, 0xfe, +0x68, 0x46, 0x21, 0x1c, 0xff, 0xf7, 0x5b, 0xfc, 0x8c, 0x24, 0x00, 0x28, 0x0e, 0xd1, 0xb9, 0x68, 0x00, 0x29, 0x02, 0xd1, 0xfa, 0x68, 0x00, 0x2a, 0x08, 0xd0, 0xf8, 0x88, 0x23, 0x1c, 0x8c, 0x28, 0x00, 0xd8, 0x03, 0x1c, -0xf8, 0x68, 0x00, 0x9a, 0xfc, 0xf7, 0x38, 0xfe, 0x02, 0xab, 0x58, 0x80, -0x03, 0x94, 0x00, 0x21, 0x01, 0xa8, 0xfb, 0xf7, 0x37, 0xf9, 0x01, 0x20, +0xf8, 0x68, 0x00, 0x9a, 0xfc, 0xf7, 0xd0, 0xfd, 0x02, 0xab, 0x58, 0x80, +0x03, 0x94, 0x00, 0x21, 0x01, 0xa8, 0xfa, 0xf7, 0x2f, 0xfd, 0x01, 0x20, 0x05, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x21, 0x04, 0x48, 0xff, 0x22, 0x02, 0x72, 0x8c, 0x30, 0x01, 0x31, 0x04, 0x29, 0xfa, 0xd3, 0x70, 0x47, 0x00, 0x00, 0xb0, 0x6e, 0x21, 0x40, 0x02, 0x48, 0x03, 0x49, -0x40, 0x1a, 0x40, 0x42, 0x70, 0x47, 0x00, 0x00, 0xb9, 0xce, 0x21, 0x40, -0xb5, 0xce, 0x21, 0x40, 0x00, 0x21, 0x08, 0x4a, 0x8b, 0x00, 0x5b, 0x18, +0x40, 0x1a, 0x40, 0x42, 0x70, 0x47, 0x00, 0x00, 0xed, 0xd6, 0x21, 0x40, +0xe9, 0xd6, 0x21, 0x40, 0x00, 0x21, 0x08, 0x4a, 0x8b, 0x00, 0x5b, 0x18, 0x9b, 0x00, 0xd3, 0x56, 0x83, 0x42, 0x04, 0xd1, 0x88, 0x00, 0x40, 0x18, 0x80, 0x00, 0x80, 0x18, 0x70, 0x47, 0x01, 0x31, 0x01, 0x29, 0xf1, 0xd3, 0x00, 0x20, 0xf9, 0xe7, 0xe0, 0x70, 0x21, 0x40, 0x80, 0xb5, 0x00, 0xf0, @@ -3883,212 +4068,215 @@ 0x02, 0x6b, 0xcb, 0x69, 0xd2, 0x18, 0x02, 0x63, 0x4a, 0x6a, 0x43, 0x6b, 0x9b, 0x18, 0x43, 0x63, 0x93, 0x42, 0x02, 0xd2, 0x82, 0x6b, 0x01, 0x32, 0x82, 0x63, 0xc2, 0x6b, 0x4b, 0x69, 0xd2, 0x18, 0xc2, 0x63, 0x02, 0x6c, -0xc9, 0x6a, 0x51, 0x18, 0x01, 0x64, 0x70, 0x47, 0x10, 0x2a, 0x00, 0x80, +0xc9, 0x6a, 0x51, 0x18, 0x01, 0x64, 0x70, 0x47, 0xa4, 0x2a, 0x00, 0x80, 0x00, 0x08, 0x14, 0x40, 0x88, 0xb5, 0x69, 0x46, 0x00, 0xf0, 0x17, 0xf8, 0x81, 0x08, 0x0a, 0xd0, 0x00, 0x20, 0x00, 0x29, 0x07, 0xd9, 0x00, 0x22, 0x83, 0x00, 0x00, 0x9f, 0xc0, 0x46, 0xfa, 0x50, 0x01, 0x30, 0x88, 0x42, 0xf8, 0xd3, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0xf0, -0x04, 0xf8, 0x00, 0x04, 0x00, 0x0c, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x22, -0x00, 0x28, 0x0a, 0xd0, 0x01, 0x28, 0x0a, 0xd0, 0x02, 0x28, 0x0c, 0xd0, -0x03, 0x28, 0x02, 0xd1, 0x07, 0x48, 0x1c, 0x22, 0x08, 0x60, 0x10, 0x1c, -0x70, 0x47, 0x06, 0x48, 0x04, 0xe0, 0x06, 0x48, 0x50, 0x22, 0x08, 0x60, -0xf7, 0xe7, 0x05, 0x48, 0x68, 0x22, 0x08, 0x60, 0xf3, 0xe7, 0x00, 0x00, -0x08, 0x83, 0x20, 0x40, 0x10, 0x2a, 0x00, 0x80, 0x78, 0x2a, 0x00, 0x80, -0xa0, 0x82, 0x20, 0x40, 0x98, 0xb5, 0x00, 0x27, 0x68, 0x46, 0xfe, 0xf7, -0xa7, 0xfb, 0x10, 0x4c, 0x00, 0x28, 0x0b, 0xd0, 0x00, 0xf0, 0x3e, 0xf8, -0x00, 0x28, 0x07, 0xd0, 0x01, 0x27, 0x10, 0x23, 0x20, 0x68, 0x18, 0x43, -0x20, 0x60, 0x60, 0x68, 0x18, 0x43, 0x0b, 0xe0, 0x10, 0x23, 0xa0, 0x68, -0x98, 0x43, 0xa0, 0x60, 0x20, 0x69, 0x98, 0x43, 0x20, 0x61, 0x20, 0x68, -0x98, 0x43, 0x20, 0x60, 0x60, 0x68, 0x98, 0x43, 0x60, 0x60, 0x38, 0x1c, -0x98, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, -0xe8, 0x18, 0x00, 0x80, 0x00, 0xb5, 0x00, 0xf0, 0xb5, 0xfc, 0xfe, 0xf7, -0xc5, 0xfb, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x14, 0x24, +0x04, 0xf8, 0x00, 0x04, 0x00, 0x0c, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x22, 0x00, 0x28, 0x0a, 0xd0, 0x01, 0x28, 0x0a, 0xd0, +0x02, 0x28, 0x0c, 0xd0, 0x03, 0x28, 0x02, 0xd1, 0x07, 0x48, 0x1c, 0x22, +0x08, 0x60, 0x10, 0x1c, 0x70, 0x47, 0x06, 0x48, 0x04, 0xe0, 0x06, 0x48, +0x50, 0x22, 0x08, 0x60, 0xf7, 0xe7, 0x05, 0x48, 0x68, 0x22, 0x08, 0x60, +0xf3, 0xe7, 0x00, 0x00, 0x08, 0x83, 0x20, 0x40, 0xa4, 0x2a, 0x00, 0x80, +0x0c, 0x2b, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x98, 0xb5, 0x00, 0x27, +0x68, 0x46, 0xfe, 0xf7, 0x6f, 0xfb, 0x10, 0x4c, 0x00, 0x28, 0x0b, 0xd0, +0x00, 0xf0, 0x44, 0xf8, 0x00, 0x28, 0x07, 0xd0, 0x01, 0x27, 0x10, 0x23, +0x60, 0x68, 0x18, 0x43, 0x60, 0x60, 0xa0, 0x68, 0x18, 0x43, 0x0b, 0xe0, +0x10, 0x23, 0xe0, 0x68, 0x98, 0x43, 0xe0, 0x60, 0x60, 0x69, 0x98, 0x43, +0x60, 0x61, 0x60, 0x68, 0x98, 0x43, 0x60, 0x60, 0xa0, 0x68, 0x98, 0x43, +0xa0, 0x60, 0x38, 0x1c, 0x98, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, +0x68, 0x19, 0x00, 0x80, 0x00, 0xb5, 0x00, 0xf0, 0xc7, 0xfc, 0x04, 0x49, +0x09, 0x6d, 0x08, 0x43, 0xfe, 0xf7, 0x8a, 0xfb, 0x00, 0x20, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf0, 0xb5, 0x14, 0x24, 0x00, 0x25, 0x00, 0x27, 0x08, 0x4e, 0x02, 0x20, 0x21, 0x1c, 0x32, 0x1c, -0xfa, 0xf7, 0xec, 0xfe, 0x78, 0x40, 0x07, 0x04, 0x3f, 0x0c, 0x02, 0x34, +0xfa, 0xf7, 0xde, 0xfa, 0x78, 0x40, 0x07, 0x04, 0x3f, 0x0c, 0x02, 0x34, 0x01, 0x35, 0x03, 0x2d, 0xf3, 0xd3, 0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0x39, 0xb7, 0x21, 0x40, 0x90, 0xb5, 0x01, 0x24, -0x20, 0x1c, 0x10, 0x49, 0xc9, 0x68, 0x01, 0x29, 0x00, 0xd0, 0x00, 0x20, -0x00, 0x06, 0x00, 0x0e, 0x16, 0xd0, 0x0d, 0x4a, 0x3a, 0x21, 0x02, 0x20, -0xfa, 0xf7, 0xce, 0xfe, 0x07, 0x04, 0x3f, 0x0c, 0x03, 0xd1, 0x00, 0x20, -0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0xf7, 0xcf, 0xff, 0xc0, 0x43, -0x00, 0x04, 0x00, 0x0c, 0xb8, 0x42, 0x00, 0xd0, 0x00, 0x24, 0x20, 0x06, -0x00, 0x0e, 0xf1, 0xe7, 0x20, 0x1c, 0xef, 0xe7, 0xe8, 0x0d, 0x00, 0x80, -0x39, 0xb7, 0x21, 0x40, 0xb0, 0xb5, 0x01, 0x27, 0x3a, 0x1c, 0x18, 0x4b, -0xdb, 0x68, 0x01, 0x2b, 0x00, 0xd0, 0x00, 0x22, 0x12, 0x06, 0x12, 0x0e, -0x00, 0x24, 0x00, 0x2a, 0x23, 0xd0, 0x14, 0x4a, 0x53, 0x68, 0x1b, 0x04, -0x1b, 0x0c, 0x1d, 0x02, 0x1b, 0x12, 0x2b, 0x43, 0x92, 0x68, 0x12, 0x04, -0x12, 0x0c, 0x15, 0x02, 0x12, 0x12, 0x2a, 0x43, 0x12, 0x04, 0x12, 0x0c, -0x1b, 0x04, 0x1a, 0x43, 0x51, 0x40, 0x01, 0x31, 0x0f, 0xd1, 0x00, 0x28, -0x02, 0xd0, 0xff, 0xf7, 0x9b, 0xff, 0xc4, 0x43, 0x22, 0x04, 0x12, 0x0c, -0x07, 0x4b, 0x3a, 0x21, 0x02, 0x20, 0xfa, 0xf7, 0x8a, 0xfe, 0x38, 0x1c, -0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x20, 0x1c, 0xfa, 0xe7, 0x00, 0x00, -0xe8, 0x0d, 0x00, 0x80, 0x40, 0x00, 0x14, 0x40, 0x7b, 0xb7, 0x21, 0x40, -0x80, 0xb4, 0x03, 0x22, 0xc2, 0x80, 0x15, 0x4a, 0xc0, 0x46, 0x82, 0x60, -0x14, 0x4a, 0x12, 0x88, 0x01, 0x32, 0xc2, 0x60, 0x00, 0x20, 0x13, 0x4a, -0x13, 0x5c, 0xc0, 0x46, 0x0b, 0x70, 0x01, 0x30, 0x01, 0x31, 0x08, 0x28, -0xf8, 0xd3, 0x20, 0x22, 0x0a, 0x70, 0x01, 0x31, 0x00, 0x20, 0x0e, 0x4b, -0x1f, 0x5c, 0xc0, 0x46, 0x0f, 0x70, 0x01, 0x30, 0x01, 0x31, 0x08, 0x28, -0xf8, 0xd3, 0x0a, 0x70, 0x01, 0x31, 0x00, 0x20, 0x09, 0x4a, 0x13, 0x5c, -0xc0, 0x46, 0x0b, 0x70, 0x01, 0x30, 0x01, 0x31, 0x08, 0x28, 0xf8, 0xd3, -0x00, 0x20, 0x08, 0x70, 0x80, 0xbc, 0x70, 0x47, 0x17, 0x40, 0x00, 0x02, -0xe8, 0x0d, 0x00, 0x80, 0xfc, 0x03, 0x00, 0x80, 0x05, 0x04, 0x00, 0x80, -0x0e, 0x04, 0x00, 0x80, 0xf0, 0xb5, 0x01, 0x21, 0x45, 0x4d, 0xe8, 0x1d, -0x79, 0x30, 0x41, 0x73, 0x01, 0x73, 0x64, 0x22, 0x42, 0x82, 0x82, 0x82, -0xc1, 0x82, 0x7d, 0x21, 0xc9, 0x00, 0x01, 0x83, 0x00, 0x21, 0x41, 0x83, -0x3f, 0x48, 0x01, 0x22, 0x00, 0xf0, 0x08, 0xfb, 0x00, 0x26, 0xf6, 0x43, -0x3d, 0x4c, 0xe7, 0x1d, 0x39, 0x37, 0xb0, 0x42, 0x07, 0xd1, 0xf8, 0x88, -0x01, 0x30, 0xf8, 0x80, 0xa0, 0x79, 0x01, 0x30, 0xa0, 0x71, 0xfc, 0xf7, -0xb3, 0xfd, 0x38, 0x48, 0x02, 0x22, 0x00, 0x21, 0x00, 0xf0, 0xf4, 0xfa, -0xb0, 0x42, 0x07, 0xd1, 0xf8, 0x88, 0x01, 0x30, 0xf8, 0x80, 0xa0, 0x79, -0x01, 0x30, 0xa0, 0x71, 0xfc, 0xf7, 0xa4, 0xfd, 0xe8, 0x68, 0x2f, 0x1c, -0x01, 0x28, 0x05, 0xd1, 0x2f, 0x48, 0x7d, 0x22, 0xd2, 0x00, 0x00, 0x21, -0x00, 0xf0, 0xe0, 0xfa, 0x2d, 0x4d, 0x28, 0x1c, 0xfa, 0xf7, 0x02, 0xfe, -0x2c, 0x48, 0xfa, 0xf7, 0xff, 0xfd, 0x2c, 0x48, -0xfa, 0xf7, 0xfc, 0xfd, 0x2b, 0x4e, 0x71, 0x23, 0x5b, 0x01, 0xfc, 0x18, -0x2a, 0x4f, 0x20, 0x79, 0x00, 0x28, 0x0f, 0xd0, 0x28, 0x1c, 0xfa, 0xf7, -0xf1, 0xfd, 0x38, 0x1c, 0xfa, 0xf7, 0xee, 0xfd, 0x00, 0x28, 0x04, 0xd0, -0x38, 0x1c, 0xfa, 0xf7, 0xe9, 0xfd, 0x00, 0x28, 0xfa, 0xd1, 0x30, 0x1c, -0xfa, 0xf7, 0xe4, 0xfd, 0x60, 0x79, 0x00, 0x28, 0x23, 0xd0, 0x28, 0x1c, -0xfa, 0xf7, 0xde, 0xfd, 0x38, 0x1c, 0xfa, 0xf7, 0xdb, 0xfd, 0x00, 0x28, -0x04, 0xd0, 0x38, 0x1c, 0xfa, 0xf7, 0xd6, 0xfd, 0x00, 0x28, 0xfa, 0xd1, -0x19, 0x49, 0x01, 0x22, 0x12, 0x04, 0x08, 0x68, 0x02, 0x40, 0x14, 0x20, -0x00, 0x2a, 0x05, 0xd1, 0x0a, 0x68, 0x12, 0x0c, 0x06, 0xd1, 0x09, 0x68, -0x89, 0x0a, 0x03, 0xd3, 0x13, 0x49, 0xc0, 0x46, 0xc8, 0x60, 0x03, 0xe0, -0x12, 0x49, 0xc0, 0x46, 0x08, 0x64, 0xff, 0xe7, 0xfe, 0xe7, 0xff, 0xf7, -0x1e, 0xfe, 0x10, 0x48, 0xfa, 0xf7, 0xb8, 0xfd, 0x0f, 0x48, 0xfa, 0xf7, -0xb5, 0xfd, 0xbc, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 0x5d, 0x22, 0xff, 0xff, -0xa0, 0x82, 0x20, 0x40, 0x21, 0x21, 0xff, 0xff, 0x59, 0x7e, 0x21, 0x40, -0xf4, 0x01, 0xff, 0xff, 0x09, 0x2c, 0xff, 0xff, 0x04, 0x02, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xb5, 0x07, 0xff, 0xff, 0x00, 0x00, 0x10, 0x40, -0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0x65, 0xa8, 0x21, 0x40, -0x48, 0x57, 0xff, 0xff, 0x00, 0xb5, 0x10, 0x20, 0x0f, 0x49, 0xc0, 0x46, -0x08, 0x60, 0x0f, 0x4a, 0x0f, 0x48, 0x64, 0x21, 0xfa, 0xf7, 0x8e, 0xfd, -0x0e, 0x48, 0x01, 0x22, 0x12, 0x04, 0x01, 0x68, 0x0a, 0x40, 0x08, 0x21, -0x00, 0x2a, 0x05, 0xd1, 0x02, 0x68, 0x12, 0x0c, 0x07, 0xd1, 0x00, 0x68, -0x80, 0x0a, 0x04, 0xd3, 0x08, 0x48, 0xc0, 0x46, 0xc1, 0x60, 0x08, 0xbc, -0x18, 0x47, 0x07, 0x48, 0xc0, 0x46, 0x01, 0x64, 0xf9, 0xe7, 0x00, 0x00, -0x00, 0x00, 0x00, 0xb0, 0x25, 0x55, 0xff, 0xff, 0xf8, 0x28, 0x00, 0x80, +0x18, 0x47, 0x00, 0x00, 0x79, 0xbf, 0x21, 0x40, 0x01, 0x20, 0x70, 0x47, +0xb0, 0xb5, 0x01, 0x27, 0x3a, 0x1c, 0x18, 0x4b, 0xdb, 0x68, 0x01, 0x2b, +0x00, 0xd0, 0x00, 0x22, 0x12, 0x06, 0x12, 0x0e, 0x00, 0x24, 0x00, 0x2a, +0x23, 0xd0, 0x14, 0x4a, 0x53, 0x68, 0x1b, 0x04, 0x1b, 0x0c, 0x1d, 0x02, +0x1b, 0x12, 0x2b, 0x43, 0x92, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x15, 0x02, +0x12, 0x12, 0x2a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x1b, 0x04, 0x1a, 0x43, +0x51, 0x40, 0x01, 0x31, 0x0f, 0xd1, 0x00, 0x28, 0x02, 0xd0, 0xff, 0xf7, +0xc1, 0xff, 0xc4, 0x43, 0x22, 0x04, 0x12, 0x0c, 0x07, 0x4b, 0x3a, 0x21, +0x02, 0x20, 0xfa, 0xf7, 0xa2, 0xfa, 0x38, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x20, 0x1c, 0xfa, 0xe7, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, +0x40, 0x00, 0x14, 0x40, 0xd9, 0xbf, 0x21, 0x40, 0x80, 0xb4, 0x03, 0x22, +0xc2, 0x80, 0x15, 0x4a, 0xc0, 0x46, 0x82, 0x60, 0x14, 0x4a, 0x12, 0x88, +0x01, 0x32, 0xc2, 0x60, 0x00, 0x20, 0x13, 0x4a, 0x13, 0x5c, 0xc0, 0x46, +0x0b, 0x70, 0x01, 0x30, 0x01, 0x31, 0x08, 0x28, 0xf8, 0xd3, 0x20, 0x22, +0x0a, 0x70, 0x01, 0x31, 0x00, 0x20, 0x0e, 0x4b, 0x1f, 0x5c, 0xc0, 0x46, +0x0f, 0x70, 0x01, 0x30, 0x01, 0x31, 0x08, 0x28, 0xf8, 0xd3, 0x0a, 0x70, +0x01, 0x31, 0x00, 0x20, 0x09, 0x4a, 0x13, 0x5c, 0xc0, 0x46, 0x0b, 0x70, +0x01, 0x30, 0x01, 0x31, 0x08, 0x28, 0xf8, 0xd3, 0x00, 0x20, 0x08, 0x70, +0x80, 0xbc, 0x70, 0x47, 0x02, 0x10, 0x00, 0x03, 0x68, 0x0e, 0x00, 0x80, +0x7c, 0x04, 0x00, 0x80, 0x85, 0x04, 0x00, 0x80, 0x8e, 0x04, 0x00, 0x80, +0x00, 0xb5, 0x01, 0x23, 0x0a, 0x48, 0xc1, 0x1d, 0x89, 0x31, 0x4b, 0x70, +0x00, 0x22, 0x0a, 0x70, 0x64, 0x21, 0x80, 0x30, 0xc1, 0x82, 0x01, 0x83, +0x43, 0x83, 0x7d, 0x21, 0xc9, 0x00, 0x81, 0x83, 0xc2, 0x83, 0x04, 0x48, +0x01, 0x22, 0x00, 0x21, 0x00, 0xf0, 0x38, 0xfb, 0x08, 0xbc, 0x18, 0x47, +0x68, 0x0e, 0x00, 0x80, 0xa1, 0x22, 0xff, 0xff, +0x00, 0xb5, 0xff, 0xf7, 0xe1, 0xff, 0x13, 0x48, 0x02, 0x22, 0x00, 0x21, +0x00, 0xf0, 0x2a, 0xfb, 0x01, 0x23, 0xd8, 0x42, 0x0a, 0xd1, 0x10, 0x48, +0xc1, 0x1d, 0x39, 0x31, 0xca, 0x88, 0x01, 0x32, 0xca, 0x80, 0x81, 0x79, +0x01, 0x31, 0x81, 0x71, 0xfc, 0xf7, 0x5c, 0xfd, 0x0b, 0x48, 0xc0, 0x68, +0x01, 0x28, 0x05, 0xd1, 0x0a, 0x48, 0x7d, 0x22, 0xd2, 0x00, 0x00, 0x21, +0x00, 0xf0, 0x12, 0xfb, 0x08, 0x48, 0xfa, 0xf7, 0x1b, 0xfa, 0x08, 0x48, +0x28, 0x22, 0x00, 0x21, 0x00, 0xf0, 0x0a, 0xfb, 0x08, 0xbc, 0x18, 0x47, +0x65, 0x21, 0xff, 0xff, 0xa0, 0x82, 0x20, 0x40, 0x68, 0x0e, 0x00, 0x80, +0x95, 0x7e, 0x21, 0x40, 0x81, 0x2c, 0xff, 0xff, 0x59, 0x03, 0xff, 0xff, +0x00, 0xb5, 0x10, 0x20, 0x0f, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x0f, 0x4a, +0x0f, 0x48, 0x64, 0x21, 0xfa, 0xf7, 0x00, 0xfa, 0x0e, 0x48, 0x01, 0x22, +0x12, 0x04, 0x01, 0x68, 0x0a, 0x40, 0x08, 0x21, 0x00, 0x2a, 0x05, 0xd1, +0x02, 0x68, 0x12, 0x0c, 0x07, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x04, 0xd3, +0x08, 0x48, 0xc0, 0x46, 0xc1, 0x60, 0x08, 0xbc, 0x18, 0x47, 0x07, 0x48, +0xc0, 0x46, 0x01, 0x64, 0xf9, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, +0x91, 0x55, 0xff, 0xff, 0x7c, 0x29, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, +0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf8, 0xb5, 0x27, 0x48, +0x01, 0x22, 0x12, 0x04, 0x01, 0x68, 0x0a, 0x40, 0x07, 0x21, 0x00, 0x2a, +0x05, 0xd1, 0x02, 0x68, 0x12, 0x0c, 0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a, +0x03, 0xd3, 0x21, 0x48, 0xc0, 0x46, 0xc1, 0x60, 0x02, 0xe0, 0x20, 0x48, +0xc0, 0x46, 0x01, 0x64, 0x1f, 0x48, 0xfa, 0xf7, 0xc1, 0xf9, 0x1f, 0x48, +0xc1, 0x6b, 0xff, 0x29, 0xfc, 0xd1, 0x81, 0x6b, 0x42, 0x6b, 0x16, 0x1c, +0x0f, 0x1c, 0x1c, 0x4c, 0x10, 0x23, 0x60, 0x69, 0x18, 0x43, 0x60, 0x61, +0xa1, 0x69, 0x99, 0x43, 0x1d, 0x04, 0xa1, 0x61, 0xe8, 0x60, 0xa0, 0x69, +0xc0, 0x46, 0x28, 0x61, 0x16, 0x4a, 0x17, 0x49, 0x64, 0x20, 0xfa, 0xf7, +0xa9, 0xf9, 0x16, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x15, 0x4b, 0x00, 0x20, +0x39, 0x1c, 0x32, 0x1c, 0xfa, 0xf7, 0xa8, 0xf9, 0x13, 0x48, 0xc1, 0x68, +0x08, 0x29, 0xfc, 0xd1, 0x12, 0x48, 0xfa, 0xf7, 0x97, 0xf9, 0x10, 0x23, +0x60, 0x69, 0x98, 0x43, 0x60, 0x61, 0xe8, 0x60, 0x01, 0x20, 0xe3, 0x23, +0x1b, 0x01, 0xe1, 0x18, 0xc8, 0x71, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, +0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, +0x04, 0x02, 0xff, 0xff, 0x00, 0x01, 0x18, 0x40, 0x68, 0x0e, 0x00, 0x80, +0x0c, 0x55, 0xff, 0xff, 0x2d, 0xcf, 0x21, 0x40, 0x64, 0x00, 0x30, 0x02, +0x44, 0x80, 0x20, 0x40, 0x40, 0x01, 0x18, 0x40, 0xf4, 0x01, 0xff, 0xff, +0x00, 0xb5, 0xfd, 0xf7, 0xeb, 0xfa, 0x06, 0x48, 0xfa, 0xf7, 0x6c, 0xf9, +0xfd, 0xf7, 0xc0, 0xfa, 0xfd, 0xf7, 0xee, 0xfb, 0xfd, 0xf7, 0x00, 0xfc, +0xfd, 0xf7, 0x0e, 0xfc, 0x08, 0xbc, 0x18, 0x47, 0x91, 0x03, 0xff, 0xff, +0x90, 0xb5, 0xfd, 0xf7, 0x55, 0xf8, 0x34, 0x4f, 0x00, 0x24, 0xf9, 0x68, +0xf8, 0x1d, 0x79, 0x30, 0x01, 0x29, 0x0f, 0xd1, 0x31, 0x49, 0xc0, 0x46, +0xf9, 0x67, 0x31, 0x49, 0xc0, 0x46, 0x01, 0x60, 0x30, 0x49, 0xc0, 0x46, +0x0c, 0x60, 0x4c, 0x60, 0x8c, 0x60, 0xcc, 0x60, 0x0c, 0x61, 0x4c, 0x61, +0x8c, 0x61, 0x04, 0xe0, 0xf9, 0x1d, 0x7d, 0x31, 0xf9, 0x67, 0x12, 0xc0, +0x08, 0x38, 0x00, 0x68, 0x60, 0x23, 0x01, 0x68, +0x19, 0x43, 0x01, 0x60, 0xf8, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43, +0x01, 0x60, 0xf8, 0x6f, 0x40, 0x23, 0x01, 0x68, 0x99, 0x43, 0x01, 0x60, +0x00, 0xf0, 0x54, 0xf8, 0xfd, 0xf7, 0x38, 0xf8, 0x00, 0xf0, 0x08, 0xf9, +0xfc, 0xf7, 0x5f, 0xfc, 0xff, 0xf7, 0x84, 0xfd, 0xfd, 0xf7, 0x18, 0xfa, +0xfd, 0xf7, 0xa0, 0xf9, 0xfd, 0xf7, 0xac, 0xfa, 0xfd, 0xf7, 0x3e, 0xf9, +0xfd, 0xf7, 0xf4, 0xf8, 0xfd, 0xf7, 0x7e, 0xf9, 0x00, 0xf0, 0xc4, 0xf9, +0xfd, 0xf7, 0x86, 0xfb, 0xfd, 0xf7, 0xf4, 0xfa, 0xfd, 0xf7, 0xbc, 0xfa, +0xfd, 0xf7, 0x26, 0xf8, 0xfa, 0xf7, 0x12, 0xf8, 0xff, 0xf7, 0x40, 0xfd, +0x00, 0x20, 0xff, 0xf7, 0x17, 0xfe, 0xff, 0xf7, 0x97, 0xff, 0x71, 0x23, +0x5b, 0x01, 0xf8, 0x18, 0x04, 0x72, 0x44, 0x72, 0x07, 0x23, 0x5b, 0x02, +0xf8, 0x18, 0x04, 0x63, 0x09, 0x48, 0xc0, 0x46, 0x44, 0x62, 0x00, 0xf0, +0xc3, 0xf9, 0x08, 0x48, 0xfa, 0xf7, 0xf8, 0xf8, 0x90, 0xbc, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0x00, 0x01, 0x11, 0x40, +0x04, 0x01, 0x11, 0x40, 0x00, 0x01, 0x11, 0x00, 0xc0, 0x00, 0x18, 0x00, +0x65, 0x9f, 0x21, 0x40, 0x00, 0xb5, 0x04, 0x48, 0xfa, 0xf7, 0xe4, 0xf8, +0xfd, 0xf7, 0x48, 0xfb, 0xfd, 0xf7, 0x0e, 0xf8, 0x08, 0xbc, 0x18, 0x47, +0x61, 0xa9, 0x21, 0x40, 0xfa, 0x21, 0x03, 0x48, 0xc0, 0x46, 0x41, 0x62, +0x40, 0x21, 0x41, 0x62, 0x70, 0x47, 0x00, 0x00, 0xc0, 0x00, 0x18, 0x00, +0x07, 0x48, 0x41, 0x69, 0x07, 0x4b, 0x19, 0x43, 0x41, 0x61, 0x82, 0x69, +0x9a, 0x43, 0x82, 0x61, 0x01, 0x22, 0x12, 0x05, 0xd1, 0x60, 0x80, 0x69, +0xc0, 0x46, 0x10, 0x61, 0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, +0xfe, 0xaf, 0x9a, 0x10, 0x00, 0xb5, 0x02, 0x48, 0xfa, 0xf7, 0xba, 0xf8, +0x08, 0xbc, 0x18, 0x47, 0xb4, 0x57, 0xff, 0xff, 0xf0, 0xb5, 0x24, 0x4c, +0x01, 0x21, 0x09, 0x04, 0x20, 0x68, 0x01, 0x40, 0x09, 0x20, 0x22, 0x4e, +0x22, 0x4d, 0x00, 0x29, 0x05, 0xd1, 0x21, 0x68, 0x09, 0x0c, 0x04, 0xd1, +0x21, 0x68, 0x89, 0x0a, 0x01, 0xd3, 0xf0, 0x60, 0x00, 0xe0, 0x28, 0x64, +0x1d, 0x48, 0xfa, 0xf7, 0x9f, 0xf8, 0x1d, 0x4f, 0x1d, 0x49, 0x88, 0x69, +0x01, 0x30, 0x88, 0x61, 0x38, 0x7a, 0x00, 0x28, 0x02, 0xd1, 0x78, 0x7a, +0x00, 0x28, 0x1f, 0xd0, 0x19, 0x48, 0xfa, 0xf7, 0x91, 0xf8, 0x19, 0x48, +0xfa, 0xf7, 0x8e, 0xf8, 0x00, 0x28, 0xfa, 0xd1, 0x38, 0x7a, 0x00, 0x28, +0x02, 0xd0, 0x16, 0x48, 0xfa, 0xf7, 0x86, 0xf8, 0x01, 0x21, 0x09, 0x04, +0x20, 0x68, 0x01, 0x40, 0x14, 0x20, 0x00, 0x29, 0x05, 0xd1, 0x21, 0x68, +0x09, 0x0c, 0x04, 0xd1, 0x21, 0x68, 0x89, 0x0a, 0x01, 0xd3, 0xf0, 0x60, +0x01, 0xe0, 0x28, 0x64, 0xff, 0xe7, 0xfe, 0xe7, 0xff, 0xf7, 0xdd, 0xfc, +0x0b, 0x48, 0xfa, 0xf7, 0x6f, 0xf8, 0xff, 0xf7, 0xaf, 0xff, 0xcd, 0xe7, 0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, -0xb0, 0xb5, 0x24, 0x4f, 0x01, 0x21, 0x09, 0x04, 0x38, 0x68, 0x01, 0x40, -0x06, 0x20, 0x22, 0x4d, 0x22, 0x4c, 0x00, 0x29, 0x05, 0xd1, 0x39, 0x68, -0x09, 0x0c, 0x04, 0xd1, 0x39, 0x68, 0x89, 0x0a, 0x01, 0xd3, 0xe8, 0x60, -0x00, 0xe0, 0x20, 0x64, 0x03, 0x20, 0xfe, 0xf7, 0xc5, 0xfa, 0xfb, 0xf7, -0xa1, 0xf9, 0x01, 0x23, 0x18, 0x43, 0xfb, 0xf7, 0x6b, 0xfa, 0x00, 0xf0, -0x31, 0xf8, 0x01, 0x21, 0x09, 0x04, 0x38, 0x68, 0x01, 0x40, 0x07, 0x20, -0x00, 0x29, 0x05, 0xd1, 0x39, 0x68, 0x09, 0x0c, 0x04, 0xd1, 0x39, 0x68, -0x89, 0x0a, 0x01, 0xd3, 0xe8, 0x60, 0x00, 0xe0, 0x20, 0x64, 0x00, 0xf0, -0x89, 0xf8, 0x00, 0xf0, 0x69, 0xf8, 0x00, 0xf0, 0xd3, 0xf8, 0x01, 0x21, -0x09, 0x04, 0x38, 0x68, 0x01, 0x40, 0x09, 0x20, 0x00, 0x29, 0x05, 0xd1, -0x39, 0x68, 0x09, 0x0c, 0x04, 0xd1, 0x39, 0x68, 0x89, 0x0a, 0x01, 0xd3, -0xe8, 0x60, 0x00, 0xe0, 0x20, 0x64, 0xff, 0xf7, 0xdf, 0xfe, 0xb0, 0xbc, -0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, -0x00, 0x00, 0x00, 0x80, 0x00, 0xb5, 0x21, 0x48, 0xfa, 0xf7, 0x14, 0xfd, -0xfd, 0xf7, 0x4a, 0xf8, 0x00, 0xf0, 0xa6, 0xf8, 0xfd, 0xf7, 0x58, 0xf8, -0x00, 0xf0, 0xc0, 0xf8, 0xfc, 0xf7, 0x9f, 0xfc, 0xff, 0xf7, 0x5c, 0xfd, -0xfd, 0xf7, 0x3c, 0xfa, 0xfd, 0xf7, 0xc4, 0xf9, 0xfd, 0xf7, 0xdc, 0xfa, -0xfd, 0xf7, 0x60, 0xf9, 0xfd, 0xf7, 0x1a, 0xf9, -0xfd, 0xf7, 0xa2, 0xf9, 0x00, 0xf0, 0x8a, 0xf9, 0xfd, 0xf7, 0xb6, 0xfb, -0xfd, 0xf7, 0x24, 0xfb, 0xfd, 0xf7, 0xec, 0xfa, 0xfd, 0xf7, 0x46, 0xf8, -0xfa, 0xf7, 0xf2, 0xfb, 0xff, 0xf7, 0x18, 0xfd, 0x00, 0x20, 0xff, 0xf7, -0xef, 0xfd, 0x00, 0xf0, 0x29, 0xf8, 0x00, 0x20, 0x0a, 0x49, 0x71, 0x23, -0x5b, 0x01, 0xca, 0x18, 0x10, 0x71, 0x50, 0x71, 0x07, 0x23, 0x5b, 0x02, -0xc9, 0x18, 0xc8, 0x62, 0x06, 0x49, 0xc0, 0x46, 0x48, 0x62, 0x00, 0xf0, -0x87, 0xf9, 0x05, 0x48, 0xfa, 0xf7, 0xd6, 0xfc, 0x08, 0xbc, 0x18, 0x47, -0xff, 0xb8, 0x21, 0x40, 0xe8, 0x0d, 0x00, 0x80, 0xc0, 0x00, 0x18, 0x00, -0x31, 0x98, 0x21, 0x40, 0x00, 0xb5, 0x04, 0x48, 0xfa, 0xf7, 0xc8, 0xfc, -0xfd, 0xf7, 0x7c, 0xfb, 0xfd, 0xf7, 0x34, 0xf8, 0x08, 0xbc, 0x18, 0x47, -0x11, 0xa2, 0x21, 0x40, 0x00, 0xb5, 0xfd, 0xf7, 0x81, 0xfa, 0x06, 0x48, -0xfa, 0xf7, 0xba, 0xfc, 0xfd, 0xf7, 0x56, 0xfa, 0xfd, 0xf7, 0x8c, 0xfb, -0xfd, 0xf7, 0x9e, 0xfb, 0xfd, 0xf7, 0xac, 0xfb, 0x08, 0xbc, 0x18, 0x47, -0x91, 0x03, 0xff, 0xff, 0xf8, 0xb5, 0x1a, 0x48, 0xc1, 0x6b, 0xff, 0x29, -0xfc, 0xd1, 0x81, 0x6b, 0x42, 0x6b, 0x0d, 0x1c, 0x16, 0x1c, 0x17, 0x4c, -0x10, 0x23, 0x60, 0x69, 0x18, 0x43, 0x60, 0x61, 0xa1, 0x69, 0x99, 0x43, -0x1f, 0x04, 0xa1, 0x61, 0xf8, 0x60, 0xa0, 0x69, 0xc0, 0x46, 0x38, 0x61, -0x11, 0x4a, 0x12, 0x49, 0x64, 0x20, 0xfa, 0xf7, 0x95, 0xfc, 0x11, 0x4a, -0xc0, 0x46, 0x00, 0x92, 0x10, 0x4b, 0x00, 0x20, 0x29, 0x1c, 0x32, 0x1c, -0xfa, 0xf7, 0x94, 0xfc, 0x0e, 0x48, 0xc1, 0x68, 0x08, 0x29, 0xfc, 0xd1, -0x10, 0x23, 0x60, 0x69, 0x98, 0x43, 0x60, 0x61, 0xf8, 0x60, 0x01, 0x20, -0xe3, 0x23, 0x1b, 0x01, 0xe1, 0x18, 0xc8, 0x70, 0xf8, 0xbc, 0x08, 0xbc, -0x18, 0x47, 0x00, 0x00, 0x00, 0x01, 0x18, 0x40, 0xe8, 0x0d, 0x00, 0x80, -0xa0, 0x54, 0xff, 0xff, 0x11, 0xc8, 0x21, 0x40, 0x64, 0x00, 0x30, 0x02, -0x44, 0x80, 0x20, 0x40, 0x40, 0x01, 0x18, 0x40, 0xfa, 0x21, 0x03, 0x48, -0xc0, 0x46, 0x41, 0x62, 0x40, 0x21, 0x41, 0x62, 0x70, 0x47, 0x00, 0x00, -0xc0, 0x00, 0x18, 0x00, 0x07, 0x48, 0x41, 0x69, 0x07, 0x4b, 0x19, 0x43, -0x41, 0x61, 0x82, 0x69, 0x9a, 0x43, 0x82, 0x61, 0x01, 0x22, 0x12, 0x05, -0xd1, 0x60, 0x80, 0x69, 0xc0, 0x46, 0x10, 0x61, 0x70, 0x47, 0x00, 0x00, -0xe8, 0x0d, 0x00, 0x80, 0xfe, 0xaf, 0x9a, 0x10, 0xf0, 0xb4, 0x4b, 0x4a, -0x4b, 0x48, 0x00, 0x68, 0x00, 0x0c, 0x4b, 0x4d, 0x4b, 0x4b, 0x98, 0x42, -0x02, 0xd0, 0x01, 0x33, 0x98, 0x42, 0x01, 0xd1, 0x01, 0x20, 0x28, 0x80, -0x01, 0x21, 0xc9, 0x03, 0x19, 0x23, 0xdb, 0x01, 0xec, 0x18, 0x61, 0x61, -0x28, 0x88, 0x40, 0x04, 0x44, 0x4b, 0xc0, 0x18, 0x87, 0x1a, 0x06, 0x20, -0xaf, 0x60, 0x43, 0x4e, 0xc0, 0x46, 0xb0, 0x61, 0x20, 0x20, 0xc8, 0x23, -0x43, 0x43, 0xbb, 0x42, 0x21, 0xd9, 0x41, 0x00, 0x3e, 0x4e, 0xc0, 0x46, -0x31, 0x61, 0xb6, 0x69, 0x20, 0x23, 0x9b, 0x1b, 0x3b, 0x4e, 0xc0, 0x46, -0xf3, 0x61, 0x10, 0x3b, 0x33, 0x62, 0x8b, 0x00, 0xff, 0x1a, 0x40, 0x08, -0x81, 0x42, 0x17, 0xd3, 0xb8, 0x23, 0x43, 0x43, 0xbb, 0x42, 0x08, 0xd9, -0x41, 0x1e, 0x34, 0x4b, 0xc0, 0x46, 0x99, 0x81, 0xd9, 0x81, 0x40, 0x00, -0x02, 0x38, 0x58, 0x61, 0x0a, 0xe0, 0x01, 0x30, 0x81, 0x42, 0xef, 0xd2, -0x06, 0xe0, 0x2e, 0x4e, 0xb3, 0x69, 0x01, 0x33, 0xb3, 0x61, 0x40, 0x00, -0x88, 0x42, 0xd2, 0xd9, 0x2b, 0x49, 0x00, 0x20, -0x63, 0x69, 0x9b, 0x08, 0x07, 0xd0, 0x2a, 0x4b, 0x87, 0x00, 0xcb, 0x51, -0x67, 0x69, 0xbf, 0x08, 0x01, 0x30, 0x87, 0x42, 0xf8, 0xd8, 0x24, 0x49, -0xc0, 0x46, 0x8a, 0x62, 0x8c, 0x89, 0x58, 0x20, 0x60, 0x43, 0x87, 0x18, -0x00, 0x20, 0x00, 0x22, 0x00, 0x2c, 0x0a, 0xdd, 0x58, 0x23, 0x43, 0x43, -0x8c, 0x6a, 0xe3, 0x18, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x9a, 0x60, -0x8b, 0x89, 0x83, 0x42, 0xf4, 0xdc, 0xcf, 0x62, 0xcc, 0x89, 0x60, 0x00, -0x00, 0x19, 0x40, 0x01, 0xc7, 0x19, 0x00, 0x20, 0x00, 0x2c, 0x0b, 0xdd, -0x43, 0x00, 0x1b, 0x18, 0x5b, 0x01, 0xcc, 0x6a, 0xe3, 0x18, 0x01, 0x30, -0x00, 0x04, 0x00, 0x0c, 0x9a, 0x60, 0xcb, 0x89, 0x83, 0x42, 0xf3, 0xdc, -0x4f, 0x62, 0x00, 0x20, 0x0b, 0x69, 0x00, 0x2b, 0x07, 0xd9, 0x87, 0x00, -0x4b, 0x6a, 0xc0, 0x46, 0xda, 0x51, 0x0b, 0x69, 0x01, 0x30, 0x83, 0x42, -0xf7, 0xd8, 0x49, 0x6a, 0x80, 0x00, 0x08, 0x18, 0x04, 0x38, 0x28, 0x61, -0xf0, 0xbc, 0x70, 0x47, 0xb8, 0xce, 0x21, 0x40, 0x00, 0x00, 0x18, 0x40, -0xe8, 0x0d, 0x00, 0x80, 0x02, 0x99, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, -0xc8, 0x29, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40, 0x00, 0xad, 0xde, 0x00, +0x04, 0x02, 0xff, 0xff, 0x88, 0x1c, 0x00, 0x80, 0x08, 0x83, 0x20, 0x40, +0xf4, 0x01, 0xff, 0xff, 0xb5, 0x07, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, +0xe9, 0xaf, 0x21, 0x40, 0x00, 0xb5, 0x16, 0x49, 0x01, 0x22, 0x12, 0x04, +0x08, 0x68, 0x02, 0x40, 0x06, 0x20, 0x00, 0x2a, 0x05, 0xd1, 0x0a, 0x68, +0x12, 0x0c, 0x06, 0xd1, 0x09, 0x68, 0x89, 0x0a, 0x03, 0xd3, 0x10, 0x49, +0xc0, 0x46, 0xc8, 0x60, 0x02, 0xe0, 0x0f, 0x49, 0xc0, 0x46, 0x08, 0x64, +0x03, 0x20, 0xfe, 0xf7, 0x55, 0xf9, 0xfa, 0xf7, +0x9d, 0xfc, 0x01, 0x23, 0x18, 0x43, 0xfa, 0xf7, 0x77, 0xfd, 0xff, 0xf7, +0xd7, 0xfe, 0xff, 0xf7, 0x5b, 0xfe, 0xff, 0xf7, 0x4b, 0xff, 0xff, 0xf7, +0x5f, 0xff, 0xff, 0xf7, 0xf1, 0xfd, 0xff, 0xf7, 0x77, 0xff, 0x08, 0xbc, +0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, +0x00, 0x00, 0x00, 0x80, 0xf0, 0xb4, 0x46, 0x4a, 0x01, 0x21, 0xc9, 0x03, +0x45, 0x4d, 0x19, 0x23, 0xdb, 0x01, 0xec, 0x18, 0xa1, 0x61, 0x28, 0x88, +0x40, 0x04, 0x43, 0x4b, 0xc0, 0x18, 0x87, 0x1a, 0x04, 0x20, 0xaf, 0x60, +0x41, 0x4e, 0xc0, 0x46, 0xb0, 0x61, 0x08, 0x20, 0xc8, 0x23, 0x43, 0x43, +0xbb, 0x42, 0x21, 0xd9, 0x41, 0x00, 0x3d, 0x4e, 0xc0, 0x46, 0x31, 0x61, +0xb6, 0x69, 0x20, 0x23, 0x9b, 0x1b, 0x3a, 0x4e, 0xc0, 0x46, 0xf3, 0x61, +0x10, 0x3b, 0x33, 0x62, 0x8b, 0x00, 0xff, 0x1a, 0x40, 0x08, 0x81, 0x42, +0x17, 0xd3, 0xb8, 0x23, 0x43, 0x43, 0xbb, 0x42, 0x08, 0xd9, 0x41, 0x1e, +0x32, 0x4b, 0xc0, 0x46, 0x99, 0x81, 0xd9, 0x81, 0x40, 0x00, 0x02, 0x38, +0x58, 0x61, 0x0a, 0xe0, 0x01, 0x30, 0x81, 0x42, 0xef, 0xd2, 0x06, 0xe0, +0x2c, 0x4e, 0xb3, 0x69, 0x01, 0x33, 0xb3, 0x61, 0x40, 0x00, 0x88, 0x42, +0xd2, 0xd9, 0x2a, 0x49, 0x00, 0x20, 0xa3, 0x69, 0x9b, 0x08, 0x07, 0xd0, +0x28, 0x4b, 0x87, 0x00, 0xcb, 0x51, 0xa7, 0x69, 0xbf, 0x08, 0x01, 0x30, +0x87, 0x42, 0xf8, 0xd8, 0x22, 0x49, 0xc0, 0x46, 0x8a, 0x62, 0x8c, 0x89, +0x58, 0x20, 0x60, 0x43, 0x87, 0x18, 0x00, 0x20, 0x00, 0x22, 0x00, 0x2c, +0x0a, 0xdd, 0x58, 0x23, 0x43, 0x43, 0x8c, 0x6a, 0xe3, 0x18, 0x01, 0x30, +0x00, 0x04, 0x00, 0x0c, 0x9a, 0x60, 0x8b, 0x89, 0x83, 0x42, 0xf4, 0xdc, +0xcf, 0x62, 0xcc, 0x89, 0x60, 0x00, 0x00, 0x19, 0x40, 0x01, 0xc7, 0x19, +0x00, 0x20, 0x00, 0x2c, 0x0b, 0xdd, 0x43, 0x00, 0x1b, 0x18, 0x5b, 0x01, +0xcc, 0x6a, 0xe3, 0x18, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x9a, 0x60, +0xcb, 0x89, 0x83, 0x42, 0xf3, 0xdc, 0x4f, 0x62, 0x00, 0x20, 0x0b, 0x69, +0x00, 0x2b, 0x07, 0xd9, 0x87, 0x00, 0x4b, 0x6a, 0xc0, 0x46, 0xda, 0x51, +0x0b, 0x69, 0x01, 0x30, 0x83, 0x42, 0xf7, 0xd8, 0x49, 0x6a, 0x80, 0x00, +0x08, 0x18, 0x04, 0x38, 0x28, 0x61, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00, +0xec, 0xd6, 0x21, 0x40, 0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40, +0x4c, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40, 0x00, 0xad, 0xde, 0x00, 0x0a, 0x48, 0x01, 0x23, 0x1b, 0x06, 0x41, 0x69, 0x99, 0x43, 0x1a, 0x09, 0x41, 0x61, 0xd1, 0x60, 0x00, 0x21, 0xa1, 0x22, 0x52, 0x03, 0x91, 0x61, -0x1b, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x41, 0x61, 0x01, 0x20, 0x00, 0x06, -0x59, 0x05, 0x08, 0x60, 0x70, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, +0x1b, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x81, 0x61, 0x01, 0x20, 0x00, 0x06, +0x59, 0x05, 0x08, 0x60, 0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0x80, 0xb4, 0x02, 0x1c, 0x0b, 0x48, 0x1b, 0x23, 0xdb, 0x01, 0xc3, 0x18, -0x5a, 0x61, 0x01, 0x23, 0x1b, 0x06, 0x42, 0x69, 0x1a, 0x43, 0x42, 0x61, +0x9a, 0x61, 0x01, 0x23, 0x1b, 0x06, 0x42, 0x69, 0x1a, 0x43, 0x42, 0x61, 0x87, 0x69, 0x9f, 0x43, 0x01, 0x23, 0x1b, 0x05, 0x87, 0x61, 0xda, 0x60, 0x80, 0x69, 0xc0, 0x46, 0x18, 0x61, 0xa1, 0x20, 0x40, 0x03, 0x81, 0x61, -0x80, 0xbc, 0x70, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x80, 0xb5, 0xff, 0xf7, +0x80, 0xbc, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0xff, 0xf7, 0xc9, 0xff, 0x00, 0x20, 0x00, 0xf0, 0x20, 0xf8, 0x00, 0x20, 0x09, 0x49, 0x00, 0x22, 0x03, 0x01, 0x5f, 0x18, 0x33, 0x23, 0x9b, 0x01, 0xfb, 0x18, -0x5a, 0x62, 0x01, 0x30, 0x0b, 0x28, 0xf6, 0xd3, 0x04, 0x48, 0x01, 0x22, -0x00, 0x21, 0x00, 0xf0, 0x33, 0xf8, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, -0xe8, 0x0d, 0x00, 0x80, 0x91, 0x3d, 0xff, 0xff, 0x00, 0xb5, 0x02, 0x48, -0x00, 0xf0, 0x04, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0xa8, 0x61, 0x00, 0x00, -0x80, 0xb4, 0x01, 0x22, 0x12, 0x05, 0x0f, 0x4b, 0xa1, 0x21, 0x49, 0x03, -0x00, 0x28, 0x0e, 0xd0, 0xc8, 0x61, 0x18, 0x1c, 0x59, 0x69, 0x53, 0x01, -0x19, 0x43, 0x41, 0x61, 0x87, 0x69, 0x9f, 0x43, 0x87, 0x61, 0xd1, 0x60, -0x80, 0x69, 0xc0, 0x46, 0x10, 0x61, 0x80, 0xbc, 0x70, 0x47, 0x18, 0x1c, -0x5f, 0x69, 0x01, 0x23, 0x5b, 0x06, 0x9f, 0x43, 0x47, 0x61, 0xd7, 0x60, -0x00, 0x20, 0xc8, 0x61, 0xf3, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, -0xb0, 0xb4, 0x07, 0x1c, 0x00, 0x20, 0x17, 0x4c, 0x03, 0x01, 0x1d, 0x19, -0x33, 0x23, 0x9b, 0x01, 0xeb, 0x18, 0x5d, 0x6a, 0xbd, 0x42, 0x05, 0xd1, -0xdd, 0x6a, 0x95, 0x42, 0x02, 0xd1, 0x9b, 0x6a, 0x8b, 0x42, 0x1c, 0xd0, -0x01, 0x30, 0x0b, 0x28, 0xee, 0xd3, 0x00, 0x20, 0x03, 0x01, 0x1d, 0x19, -0x33, 0x23, 0x9b, 0x01, 0xeb, 0x18, 0x5b, 0x6a, 0x00, 0x2b, 0x09, 0xd1, -0x03, 0x01, 0x1c, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xe3, 0x18, 0xda, 0x62, -0x99, 0x62, 0x1a, 0x63, 0x5f, 0x62, 0x02, 0xe0, +0x9a, 0x62, 0x01, 0x30, 0x0b, 0x28, 0xf6, 0xd3, 0x04, 0x48, 0x01, 0x22, +0x00, 0x21, 0x00, 0xf0, 0x33, 0xf8, 0x80, 0xbc, +0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x09, 0x3e, 0xff, 0xff, +0x00, 0xb5, 0x02, 0x48, 0x00, 0xf0, 0x04, 0xf8, 0x08, 0xbc, 0x18, 0x47, +0xa8, 0x61, 0x00, 0x00, 0x80, 0xb4, 0x01, 0x22, 0x12, 0x05, 0x0f, 0x4b, +0xa1, 0x21, 0x49, 0x03, 0x00, 0x28, 0x0e, 0xd0, 0xc8, 0x61, 0x18, 0x1c, +0x59, 0x69, 0x53, 0x01, 0x19, 0x43, 0x41, 0x61, 0x87, 0x69, 0x9f, 0x43, +0x87, 0x61, 0xd1, 0x60, 0x80, 0x69, 0xc0, 0x46, 0x10, 0x61, 0x80, 0xbc, +0x70, 0x47, 0x18, 0x1c, 0x5f, 0x69, 0x01, 0x23, 0x5b, 0x06, 0x9f, 0x43, +0x47, 0x61, 0xd7, 0x60, 0x00, 0x20, 0xc8, 0x61, 0xf3, 0xe7, 0x00, 0x00, +0x68, 0x0e, 0x00, 0x80, 0xb0, 0xb4, 0x07, 0x1c, 0x00, 0x20, 0x17, 0x4c, +0x03, 0x01, 0x1d, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xeb, 0x18, 0x9d, 0x6a, +0xbd, 0x42, 0x05, 0xd1, 0x1d, 0x6b, 0x95, 0x42, 0x02, 0xd1, 0xdb, 0x6a, +0x8b, 0x42, 0x1c, 0xd0, 0x01, 0x30, 0x0b, 0x28, 0xee, 0xd3, 0x00, 0x20, +0x03, 0x01, 0x1d, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xeb, 0x18, 0x9b, 0x6a, +0x00, 0x2b, 0x09, 0xd1, 0x03, 0x01, 0x1c, 0x19, 0x33, 0x23, 0x9b, 0x01, +0xe3, 0x18, 0x1a, 0x63, 0xd9, 0x62, 0x5a, 0x63, 0x9f, 0x62, 0x02, 0xe0, 0x01, 0x30, 0x0b, 0x28, 0xea, 0xd3, 0x0b, 0x28, 0x01, 0xd1, 0x00, 0x20, -0xc0, 0x43, 0xb0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, +0xc0, 0x43, 0xb0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0x90, 0xb4, 0x01, 0x1c, 0x00, 0x22, 0x01, 0x20, 0x16, 0x4f, 0x01, 0xe0, 0x00, 0x2a, 0x07, 0xd1, 0x03, 0x01, 0xdc, 0x19, 0x33, 0x23, 0x9b, 0x01, -0xe3, 0x18, 0x5b, 0x69, 0x8b, 0x42, 0x11, 0xd1, 0x02, 0x01, 0xd2, 0x19, -0x33, 0x23, 0x9b, 0x01, 0xd2, 0x18, 0x53, 0x6a, 0xc0, 0x46, 0x53, 0x61, -0x93, 0x6a, 0xc0, 0x46, 0x93, 0x61, 0xd3, 0x6a, 0xc0, 0x46, 0xd3, 0x61, -0x13, 0x6b, 0xc0, 0x46, 0x13, 0x62, 0x01, 0x22, 0x01, 0x30, 0x0b, 0x28, -0xe0, 0xd3, 0x07, 0x4b, 0x00, 0x2a, 0x02, 0xd1, 0x5a, 0x68, 0x8a, 0x42, -0x03, 0xd1, 0x00, 0x21, 0x59, 0x60, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, -0xc0, 0x43, 0xfa, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 0x68, 0x1b, 0x00, 0x80, +0xe3, 0x18, 0x9b, 0x69, 0x8b, 0x42, 0x11, 0xd1, 0x02, 0x01, 0xd2, 0x19, +0x33, 0x23, 0x9b, 0x01, 0xd2, 0x18, 0x93, 0x6a, 0xc0, 0x46, 0x93, 0x61, +0xd3, 0x6a, 0xc0, 0x46, 0xd3, 0x61, 0x13, 0x6b, 0xc0, 0x46, 0x13, 0x62, +0x53, 0x6b, 0xc0, 0x46, 0x53, 0x62, 0x01, 0x22, 0x01, 0x30, 0x0b, 0x28, +0xe0, 0xd3, 0x07, 0x4b, 0x00, 0x2a, 0x02, 0xd1, 0x9a, 0x68, 0x8a, 0x42, +0x03, 0xd1, 0x00, 0x21, 0x99, 0x60, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, +0xc0, 0x43, 0xfa, 0xe7, 0x68, 0x0e, 0x00, 0x80, 0xe8, 0x1b, 0x00, 0x80, 0x0b, 0x28, 0x17, 0xda, 0x0c, 0x49, 0x01, 0x23, 0x5b, 0x06, 0x8a, 0x69, 0x13, 0x43, 0x01, 0x22, 0x12, 0x05, 0x8b, 0x61, 0x13, 0x61, 0x00, 0x01, -0x40, 0x18, 0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0xc3, 0x6a, 0xc0, 0x46, -0x03, 0x63, 0x53, 0x01, 0x88, 0x69, 0x98, 0x43, 0x88, 0x61, 0x10, 0x61, -0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, 0xe8, 0x0d, 0x00, 0x80, +0x40, 0x18, 0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0x03, 0x6b, 0xc0, 0x46, +0x43, 0x63, 0x53, 0x01, 0x88, 0x69, 0x98, 0x43, 0x88, 0x61, 0x10, 0x61, +0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, 0x68, 0x0e, 0x00, 0x80, 0x90, 0xb4, 0x08, 0x4a, 0xd0, 0x69, 0x00, 0x21, 0x07, 0x4f, 0xd3, 0x69, 0x83, 0x42, 0x02, 0xd9, 0xfc, 0x1a, 0x20, 0x18, 0x00, 0xe0, 0xc0, 0x1a, 0x09, 0x18, 0x18, 0x1c, 0xb9, 0x42, 0xf4, 0xd9, 0x90, 0xbc, 0x70, 0x47, @@ -4100,9 +4288,9 @@ 0x08, 0xc9, 0x08, 0xc0, 0x12, 0x1f, 0xfb, 0xd2, 0x0a, 0xe0, 0x08, 0xc9, 0x03, 0x70, 0x1b, 0x0a, 0x43, 0x70, 0x1b, 0x0a, 0x83, 0x70, 0x1b, 0x0a, 0xc3, 0x70, 0x00, 0x1d, 0x12, 0x1f, 0xf4, 0xd2, 0xd2, 0x1c, 0x05, 0xd3, -0x0b, 0x78, 0x03, 0x70, 0x49, 0x1c, 0x40, 0x1c, 0x52, 0x1e, 0xf9, 0xd2, -0x60, 0x46, 0x70, 0x47, 0x03, 0x1c, 0x0b, 0x43, 0x13, 0x43, 0x9b, 0x07, -0x04, 0xd1, 0x12, 0x1f, 0x8b, 0x58, 0x83, 0x50, 0xfb, 0xd1, 0x70, 0x47, -0x52, 0x1e, 0x8b, 0x5c, 0x83, 0x54, 0xfb, 0xd1, 0x70, 0x47, 0x00, 0x00, -0x00, 0x20, 0x70, 0x47, +0x0b, 0x78, 0x03, 0x70, 0x49, 0x1c, 0x40, 0x1c, +0x52, 0x1e, 0xf9, 0xd2, 0x60, 0x46, 0x70, 0x47, 0x03, 0x1c, 0x0b, 0x43, +0x13, 0x43, 0x9b, 0x07, 0x04, 0xd1, 0x12, 0x1f, 0x8b, 0x58, 0x83, 0x50, +0xfb, 0xd1, 0x70, 0x47, 0x52, 0x1e, 0x8b, 0x5c, 0x83, 0x54, 0xfb, 0xd1, +0x70, 0x47, 0x00, 0x00, 0x00, 0x20, 0x70, 0x47, }; Index: drivers/net/typhoon.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/typhoon.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/typhoon.c 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/typhoon.c 4 Aug 2004 01:29:13 -0000 1.2 @@ -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.3" +#define DRV_MODULE_RELDATE "03/12/15" #define PFX DRV_MODULE_NAME ": " #define ERR_PFX KERN_ERR PFX @@ -127,7 +127,7 @@ static char version[] __devinitdata = "typhoon.c: version " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; -MODULE_AUTHOR("David Dillow "); +MODULE_AUTHOR("David Dillow "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("3Com Typhoon Family (3C990, 3CR990, and variants)"); MODULE_PARM(rx_copybreak, "i"); @@ -146,16 +146,18 @@ int capabilities; }; -#define TYPHOON_CRYPTO_NONE 0 -#define TYPHOON_CRYPTO_DES 1 -#define TYPHOON_CRYPTO_3DES 2 -#define TYPHOON_CRYPTO_VARIABLE 4 -#define TYPHOON_FIBER 5 +#define TYPHOON_CRYPTO_NONE 0x00 +#define TYPHOON_CRYPTO_DES 0x01 +#define TYPHOON_CRYPTO_3DES 0x02 +#define TYPHOON_CRYPTO_VARIABLE 0x04 +#define TYPHOON_FIBER 0x08 +#define TYPHOON_WAKEUP_NEEDS_RESET 0x10 enum typhoon_cards { TYPHOON_TX = 0, TYPHOON_TX95, TYPHOON_TX97, TYPHOON_SVR, TYPHOON_SVR95, TYPHOON_SVR97, TYPHOON_TXM, TYPHOON_BSVR, TYPHOON_FX95, TYPHOON_FX97, TYPHOON_FX95SVR, TYPHOON_FX97SVR, + TYPHOON_FXM, }; /* directly indexed by enum typhoon_cards, above */ @@ -184,6 +186,8 @@ TYPHOON_CRYPTO_DES | TYPHOON_FIBER}, { "3Com Typhoon (3CR990-FX-97 Server)", TYPHOON_CRYPTO_DES | TYPHOON_CRYPTO_3DES | TYPHOON_FIBER}, + { "3Com Typhoon2 (3C990B-FX-97)", + TYPHOON_CRYPTO_VARIABLE | TYPHOON_FIBER}, }; /* Notes on the new subsystem numbering scheme: @@ -202,6 +206,8 @@ { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990B, PCI_ANY_ID, 0x1000, 0, 0, TYPHOON_TXM }, { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990B, + PCI_ANY_ID, 0x1102, 0, 0, TYPHOON_FXM }, + { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990B, PCI_ANY_ID, 0x2000, 0, 0, TYPHOON_BSVR }, { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_FX, PCI_ANY_ID, 0x1101, 0, 0, TYPHOON_FX95 }, @@ -307,7 +313,8 @@ /* We'll wait up to six seconds for a reset, and half a second normally. */ #define TYPHOON_UDELAY 50 -#define TYPHOON_RESET_TIMEOUT (6 * HZ) +#define TYPHOON_RESET_TIMEOUT_SLEEP (6 * HZ) +#define TYPHOON_RESET_TIMEOUT_NOSLEEP ((6 * 1000000) / TYPHOON_UDELAY) #define TYPHOON_WAIT_TIMEOUT ((1000000 / 2) / TYPHOON_UDELAY) #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 28) @@ -375,10 +382,12 @@ typhoon_reset(unsigned long ioaddr, int wait_type) { int i, err = 0; - int timeout = TYPHOON_RESET_TIMEOUT; + int timeout; if(wait_type == WaitNoSleep) - timeout = (timeout * 1000000) / (HZ * TYPHOON_UDELAY); + timeout = TYPHOON_RESET_TIMEOUT_NOSLEEP; + else + timeout = TYPHOON_RESET_TIMEOUT_SLEEP; writel(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK); writel(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_STATUS); @@ -1359,6 +1368,7 @@ u32 section_len; u32 len; u32 load_addr; + u32 hmac; int i; int err; @@ -1402,6 +1412,16 @@ writel(TYPHOON_INTR_BOOTCMD, ioaddr + TYPHOON_REG_INTR_STATUS); writel(load_addr, ioaddr + TYPHOON_REG_DOWNLOAD_BOOT_ADDR); + hmac = le32_to_cpu(fHdr->hmacDigest[0]); + writel(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_0); + hmac = le32_to_cpu(fHdr->hmacDigest[1]); + writel(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_1); + hmac = le32_to_cpu(fHdr->hmacDigest[2]); + writel(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_2); + hmac = le32_to_cpu(fHdr->hmacDigest[3]); + writel(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_3); + hmac = le32_to_cpu(fHdr->hmacDigest[4]); + writel(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_4); typhoon_post_pci_writes(ioaddr); writel(TYPHOON_BOOTCMD_RUNTIME_IMAGE, ioaddr + TYPHOON_REG_COMMAND); @@ -1798,7 +1818,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); @@ -1857,6 +1877,11 @@ if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_SLEEPING) < 0) return -ETIMEDOUT; + /* Since we cannot monitor the status of the link while sleeping, + * tell the world it went away. + */ + netif_carrier_off(tp->dev); + pci_enable_wake(tp->pdev, state, 1); pci_disable_device(pdev); return pci_set_power_state(pdev, state); @@ -1871,8 +1896,13 @@ pci_set_power_state(pdev, 0); pci_restore_state(pdev, tp->pci_state); + /* Post 2.x.x versions of the Sleep Image require a reset before + * we can download the Runtime Image. But let's not make users of + * the old firmware pay for the reset. + */ writel(TYPHOON_BOOTCMD_WAKEUP, ioaddr + TYPHOON_REG_COMMAND); - if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) + if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_HOST) < 0 || + (tp->capabilities & TYPHOON_WAKEUP_NEEDS_RESET)) return typhoon_reset(ioaddr, wait_type); return 0; @@ -2134,7 +2164,7 @@ return 0; } -#if CONFIG_PM +#ifdef CONFIG_PM static int typhoon_resume(struct pci_dev *pdev) { @@ -2250,7 +2280,7 @@ void *shared; dma_addr_t shared_dma; struct cmd_desc xp_cmd; - struct resp_desc xp_resp; + struct resp_desc xp_resp[3]; int i; int err = 0; @@ -2378,15 +2408,15 @@ } INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_MAC_ADDRESS); - if(typhoon_issue_command(tp, 1, &xp_cmd, 1, &xp_resp) < 0) { + if(typhoon_issue_command(tp, 1, &xp_cmd, 1, xp_resp) < 0) { printk(ERR_PFX "%s: cannot read MAC address\n", pdev->slot_name); err = -EIO; goto error_out_reset; } - *(u16 *)&dev->dev_addr[0] = htons(le16_to_cpu(xp_resp.parm1)); - *(u32 *)&dev->dev_addr[2] = htonl(le32_to_cpu(xp_resp.parm2)); + *(u16 *)&dev->dev_addr[0] = htons(le16_to_cpu(xp_resp[0].parm1)); + *(u32 *)&dev->dev_addr[2] = htonl(le32_to_cpu(xp_resp[0].parm2)); if(!is_valid_ether_addr(dev->dev_addr)) { printk(ERR_PFX "%s: Could not obtain valid ethernet address, " @@ -2394,6 +2424,28 @@ goto error_out_reset; } + /* Read the Sleep Image version last, so the response is valid + * later when we print out the version reported. + */ + INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_VERSIONS); + if(typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp) < 0) { + printk(ERR_PFX "%s: Could not get Sleep Image version\n", + pdev->slot_name); + goto error_out_reset; + } + + tp->capabilities = typhoon_card_info[card_id].capabilities; + tp->xcvr_select = TYPHOON_XCVR_AUTONEG; + + /* Typhoon 1.0 Sleep Images return one response descriptor to the + * READ_VERSIONS command. Those versions are OK after waking up + * from sleep without needing a reset. Typhoon 1.1+ Sleep Images + * seem to need a little extra help to get started. Since we don't + * know how to nudge it along, just kick it. + */ + if(xp_resp[0].numDesc != 0) + tp->capabilities |= TYPHOON_WAKEUP_NEEDS_RESET; + if(typhoon_sleep(tp, 3, 0) < 0) { printk(ERR_PFX "%s: cannot put adapter to sleep\n", pdev->slot_name); @@ -2401,9 +2453,6 @@ goto error_out_reset; } - tp->capabilities = typhoon_card_info[card_id].capabilities; - tp->xcvr_select = TYPHOON_XCVR_AUTONEG; - /* The chip-specific entries in the device structure. */ dev->open = typhoon_open; dev->hard_start_xmit = typhoon_start_tx; @@ -2440,6 +2489,32 @@ printk("%2.2x:", dev->dev_addr[i]); printk("%2.2x\n", dev->dev_addr[i]); + /* xp_resp still contains the response to the READ_VERSIONS command. + * For debugging, let the user know what version he has. + */ + if(xp_resp[0].numDesc == 0) { + /* This is the Typhoon 1.0 type Sleep Image, last 16 bits + * of version is Month/Day of build. + */ + u16 monthday = le32_to_cpu(xp_resp[0].parm2) & 0xffff; + printk(KERN_INFO "%s: Typhoon 1.0 Sleep Image built " + "%02u/%02u/2000\n", dev->name, monthday >> 8, + monthday & 0xff); + } else if(xp_resp[0].numDesc == 2) { + /* This is the Typhoon 1.1+ type Sleep Image + */ + u32 sleep_ver = le32_to_cpu(xp_resp[0].parm2); + u8 *ver_string = (u8 *) &xp_resp[1]; + ver_string[25] = 0; + printk(KERN_INFO "%s: Typhoon 1.1+ Sleep Image version " + "%u.%u.%u.%u %s\n", dev->name, HIPQUAD(sleep_ver), + ver_string); + } else { + printk(KERN_WARNING "%s: Unknown Sleep Image version " + "(%u:%04x)\n", dev->name, xp_resp[0].numDesc, + le32_to_cpu(xp_resp[0].parm2)); + } + return 0; error_out_reset: @@ -2482,7 +2557,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, Index: drivers/net/typhoon.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/typhoon.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/typhoon.h 22 Jul 2004 19:49:32 -0000 1.1 +++ drivers/net/typhoon.h 4 Aug 2004 01:29:13 -0000 1.2 @@ -512,6 +512,7 @@ u32 version; u32 numSections; u32 startAddr; + u32 hmacDigest[5]; } __attribute__ ((packed)); struct typhoon_section_header { @@ -548,6 +549,11 @@ #define TYPHOON_REG_BOOT_LENGTH TYPHOON_REG_HOST2ARM1 #define TYPHOON_REG_DOWNLOAD_BOOT_ADDR TYPHOON_REG_HOST2ARM1 +#define TYPHOON_REG_DOWNLOAD_HMAC_0 TYPHOON_REG_HOST2ARM2 +#define TYPHOON_REG_DOWNLOAD_HMAC_1 TYPHOON_REG_HOST2ARM3 +#define TYPHOON_REG_DOWNLOAD_HMAC_2 TYPHOON_REG_HOST2ARM4 +#define TYPHOON_REG_DOWNLOAD_HMAC_3 TYPHOON_REG_HOST2ARM5 +#define TYPHOON_REG_DOWNLOAD_HMAC_4 TYPHOON_REG_HOST2ARM6 #define TYPHOON_REG_BOOT_RECORD_ADDR_HI TYPHOON_REG_HOST2ARM2 #define TYPHOON_REG_BOOT_RECORD_ADDR_LO TYPHOON_REG_HOST2ARM1 Index: drivers/net/via-rhine.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/via-rhine.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/via-rhine.c 22 Jul 2004 19:49:33 -0000 1.1 +++ drivers/net/via-rhine.c 4 Aug 2004 01:29:13 -0000 1.2 @@ -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 = +static struct pci_device_id via_rhine_pci_tbl[] = { {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. */ @@ -530,13 +540,14 @@ static void via_rhine_timer(unsigned long data); static void via_rhine_tx_timeout(struct net_device *dev); static int via_rhine_start_tx(struct sk_buff *skb, struct net_device *dev); -static void via_rhine_interrupt(int irq, void *dev_instance, struct pt_regs *regs); +static irqreturn_t via_rhine_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static void via_rhine_tx(struct net_device *dev); static void via_rhine_rx(struct net_device *dev); static void via_rhine_error(struct net_device *dev, int intr_status); static void via_rhine_set_rx_mode(struct net_device *dev); static struct net_device_stats *via_rhine_get_stats(struct net_device *dev); static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; static int via_rhine_close(struct net_device *dev); static inline u32 get_intr_status(struct net_device *dev) @@ -671,7 +682,7 @@ ioaddr = (long) ioremap (memaddr, io_size); if (!ioaddr) { printk (KERN_ERR "ioremap failed for device %s, region 0x%X @ 0x%lX\n", - pdev->slot_name, io_size, memaddr); + pci_name(pdev), io_size, memaddr); goto err_out_free_res; } @@ -769,6 +780,7 @@ dev->get_stats = via_rhine_get_stats; dev->set_multicast_list = via_rhine_set_rx_mode; dev->do_ioctl = netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; dev->tx_timeout = via_rhine_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; if (np->drv_flags & ReqTxAlign) @@ -1144,7 +1156,7 @@ /* Set the timer to check for link beat. */ init_timer(&np->timer); - np->timer.expires = jiffies + 2; + np->timer.expires = jiffies + 2 * HZ/100; np->timer.data = (unsigned long)dev; np->timer.function = &via_rhine_timer; /* timer handler */ add_timer(&np->timer); @@ -1264,7 +1276,7 @@ if (skb->len < ETH_ZLEN) { skb = skb_padto(skb, ETH_ZLEN); - if(skb == NULL) + if (skb == NULL) return 0; } @@ -1330,16 +1342,19 @@ /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static void via_rhine_interrupt(int irq, void *dev_instance, struct pt_regs *rgs) +static irqreturn_t via_rhine_interrupt(int irq, void *dev_instance, struct pt_regs *rgs) { struct net_device *dev = dev_instance; long ioaddr; u32 intr_status; int boguscnt = max_interrupt_work; + int handled = 0; ioaddr = dev->base_addr; while ((intr_status = get_intr_status(dev))) { + handled = 1; + /* Acknowledge all of the current interrupt sources ASAP. */ if (intr_status & IntrTxDescRace) writeb(0x08, ioaddr + IntrStatus2); @@ -1385,6 +1400,7 @@ if (debug > 3) printk(KERN_DEBUG "%s: exiting interrupt, status=%8.8x.\n", dev->name, readw(ioaddr + IntrStatus)); + return IRQ_RETVAL(handled); } /* This routine is logically part of the interrupt handler, but isolated @@ -1650,11 +1666,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 +1717,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. */ @@ -1713,90 +1742,87 @@ writeb(np->rx_thresh | rx_mode, ioaddr + RxConfig); } -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info) { struct netdev_private *np = dev->priv; - u32 ethcmd; - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; + strcpy (info->driver, DRV_NAME); + strcpy (info->version, DRV_VERSION); + strcpy (info->bus_info, pci_name(np->pdev)); +} - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - strcpy (info.bus_info, np->pdev->slot_name); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } +static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct netdev_private *np = dev->priv; + int rc; - /* get settings */ - case ETHTOOL_GSET: { - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - if (!(np->drv_flags & CanHaveMII)) - break; - spin_lock_irq(&np->lock); - mii_ethtool_gset(&np->mii_if, &ecmd); - spin_unlock_irq(&np->lock); - if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } - /* set settings */ - case ETHTOOL_SSET: { - int r; - struct ethtool_cmd ecmd; - if (!(np->drv_flags & CanHaveMII)) - break; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - spin_lock_irq(&np->lock); - r = mii_ethtool_sset(&np->mii_if, &ecmd); - spin_unlock_irq(&np->lock); - return r; - } - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - if (!(np->drv_flags & CanHaveMII)) - break; - return mii_nway_restart(&np->mii_if); - } - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = {ETHTOOL_GLINK}; - if (!(np->drv_flags & CanHaveMII)) - break; - edata.data = mii_link_ok(&np->mii_if); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } - default: - break; - } + if (!(np->drv_flags & CanHaveMII)) + return -EINVAL; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_gset(&np->mii_if, cmd); + spin_unlock_irq(&np->lock); + + return rc; +} + +static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct netdev_private *np = dev->priv; + int rc; + + if (!(np->drv_flags & CanHaveMII)) + return -EINVAL; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_sset(&np->mii_if, cmd); + spin_unlock_irq(&np->lock); + + return rc; +} + +static int netdev_nway_reset(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; - return -EOPNOTSUPP; + if (!(np->drv_flags & CanHaveMII)) + return -EINVAL; + + return mii_nway_restart(&np->mii_if); } +static u32 netdev_get_link(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + + if (!(np->drv_flags & CanHaveMII)) + return 0; /* -EINVAL */ + + return mii_link_ok(&np->mii_if); +} + +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return debug; +} + +static void netdev_set_msglevel(struct net_device *dev, u32 value) +{ + debug = value; +} + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_settings = netdev_get_settings, + .set_settings = netdev_set_settings, + .nway_reset = netdev_nway_reset, + .get_link = netdev_get_link, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, + .get_sg = ethtool_op_get_sg, + .get_tx_csum = ethtool_op_get_tx_csum, +}; + static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct netdev_private *np = dev->priv; @@ -1806,14 +1832,9 @@ if (!netif_running(dev)) return -EINVAL; - if (cmd == SIOCETHTOOL) - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - - else { - spin_lock_irq(&np->lock); - rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL); - spin_unlock_irq(&np->lock); - } + spin_lock_irq(&np->lock); + rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL); + spin_unlock_irq(&np->lock); return rc; } Index: drivers/net/winbond-840.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/winbond-840.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/winbond-840.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/winbond-840.c 4 Aug 2004 01:29:13 -0000 1.2 @@ -17,7 +17,7 @@ Support and updates available at http://www.scyld.com/network/drivers.html - Do not remove the copyright infomation. + Do not remove the copyright information. Do not change the version information unless an improvement has been made. Merely removing my name, as Compex has done in the past, does not count as an improvement. @@ -234,7 +234,7 @@ #define W840_FLAGS (PCI_USES_MEM | PCI_ADDR1 | PCI_USES_MASTER) #endif -static struct pci_device_id w840_pci_tbl[] __devinitdata = { +static struct pci_device_id w840_pci_tbl[] = { { 0x1050, 0x0840, PCI_ANY_ID, 0x8153, 0, 0, 0 }, { 0x1050, 0x0840, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, { 0x11f6, 0x2011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, @@ -341,7 +341,6 @@ DescIntr=0x80000000, }; -#define PRIV_ALIGN 15 /* Required alignment mask */ #define MII_CNT 1 /* winbond only supports one MII */ struct netdev_private { struct w840_rx_desc *rx_ring; @@ -386,13 +385,14 @@ static int alloc_ringdesc(struct net_device *dev); static void free_ringdesc(struct netdev_private *np); static int start_tx(struct sk_buff *skb, struct net_device *dev); -static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs); +static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs); static void netdev_error(struct net_device *dev, int intr_status); static int netdev_rx(struct net_device *dev); static u32 __set_rx_mode(struct net_device *dev); static void set_rx_mode(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 struct ethtool_ops netdev_ethtool_ops; static int netdev_close(struct net_device *dev); @@ -417,7 +417,7 @@ if (pci_set_dma_mask(pdev,0xFFFFffff)) { printk(KERN_WARNING "Winbond-840: Device %s disabled due to DMA limitations.\n", - pdev->slot_name); + pci_name(pdev)); return -EIO; } dev = alloc_etherdev(sizeof(*np)); @@ -482,6 +482,7 @@ dev->get_stats = &get_stats; dev->set_multicast_list = &set_rx_mode; dev->do_ioctl = &netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; dev->tx_timeout = &tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; @@ -598,7 +599,7 @@ #define mdio_delay(mdio_addr) readl(mdio_addr) /* Set iff a MII transceiver on any interface requires mdio preamble. - This only set with older tranceivers, so the extra + This only set with older transceivers, so the extra code size of a per-interface flag is not worthwhile. */ static char mii_preamble_required = 1; @@ -1078,7 +1079,7 @@ np->tx_ring[entry].length |= DescEndRing; /* Now acquire the irq spinlock. - * The difficult race is the ordering between + * The difficult race is the the ordering between * increasing np->cur_tx and setting DescOwn: * - if np->cur_tx is increased first the interrupt * handler could consider the packet as transmitted @@ -1166,15 +1167,16 @@ /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) +static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) { struct net_device *dev = (struct net_device *)dev_instance; struct netdev_private *np = dev->priv; long ioaddr = dev->base_addr; int work_limit = max_interrupt_work; + int handled = 0; if (!netif_device_present(dev)) - return; + return IRQ_NONE; do { u32 intr_status = readl(ioaddr + IntrStatus); @@ -1188,6 +1190,8 @@ if ((intr_status & (NormalIntr|AbnormalIntr)) == 0) break; + handled = 1; + if (intr_status & (IntrRxDone | RxNoBuf)) netdev_rx(dev); if (intr_status & RxNoBuf) @@ -1223,6 +1227,7 @@ if (debug > 3) printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n", dev->name, (int)readl(ioaddr + IntrStatus)); + return IRQ_RETVAL(handled); } /* This routine is logically part of the interrupt handler, but separated @@ -1428,8 +1433,9 @@ memset(mc_filter, 0, sizeof(mc_filter)); for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) { - set_bit((ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26) ^ 0x3F, - mc_filter); + int filterbit = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26) ^ 0x3F; + filterbit &= 0x3f; + mc_filter[filterbit >> 5] |= cpu_to_le32(1 << (filterbit & 31)); } rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; } @@ -1447,88 +1453,79 @@ spin_unlock_irq(&np->lock); } -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info) { struct netdev_private *np = dev->priv; - 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_NAME); - strcpy(info.version, DRV_VERSION); - strcpy(info.bus_info, np->pci_dev->slot_name); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - /* get settings */ - case ETHTOOL_GSET: { - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - spin_lock_irq(&np->lock); - mii_ethtool_gset(&np->mii_if, &ecmd); - spin_unlock_irq(&np->lock); - if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } - /* set settings */ - case ETHTOOL_SSET: { - int r; - struct ethtool_cmd ecmd; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - spin_lock_irq(&np->lock); - r = mii_ethtool_sset(&np->mii_if, &ecmd); - spin_unlock_irq(&np->lock); - return r; - } - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - return mii_nway_restart(&np->mii_if); - } - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = {ETHTOOL_GLINK}; - edata.data = mii_link_ok(&np->mii_if); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } + strcpy (info->driver, DRV_NAME); + strcpy (info->version, DRV_VERSION); + strcpy (info->bus_info, pci_name(np->pci_dev)); +} - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } - } - - return -EOPNOTSUPP; +static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct netdev_private *np = dev->priv; + int rc; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_gset(&np->mii_if, cmd); + spin_unlock_irq(&np->lock); + + return rc; } +static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct netdev_private *np = dev->priv; + int rc; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_sset(&np->mii_if, cmd); + spin_unlock_irq(&np->lock); + + return rc; +} + +static int netdev_nway_reset(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + return mii_nway_restart(&np->mii_if); +} + +static u32 netdev_get_link(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + return mii_link_ok(&np->mii_if); +} + +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return debug; +} + +static void netdev_set_msglevel(struct net_device *dev, u32 value) +{ + debug = value; +} + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_settings = netdev_get_settings, + .set_settings = netdev_set_settings, + .nway_reset = netdev_nway_reset, + .get_link = netdev_get_link, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, + .get_sg = ethtool_op_get_sg, + .get_tx_csum = ethtool_op_get_tx_csum, +}; + static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data; struct netdev_private *np = dev->priv; switch(cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); case SIOCGMIIPHY: /* Get address of MII PHY in use. */ case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */ data->phy_id = ((struct netdev_private *)dev->priv)->phys[0] & 0x1f; @@ -1587,10 +1584,10 @@ if (debug > 2) { int i; - printk("\n"KERN_DEBUG" Tx ring at %8.8x:\n", + printk(KERN_DEBUG" Tx ring at %8.8x:\n", (int)np->tx_ring); for (i = 0; i < TX_RING_SIZE; i++) - printk(" #%d desc. %4.4x %4.4x %8.8x.\n", + printk(KERN_DEBUG " #%d desc. %4.4x %4.4x %8.8x.\n", i, np->tx_ring[i].length, np->tx_ring[i].status, np->tx_ring[i].buffer1); printk("\n"KERN_DEBUG " Rx ring %8.8x:\n", @@ -1690,7 +1687,6 @@ return 0; } - static int w840_resume (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata (pdev); @@ -1714,8 +1710,7 @@ netif_wake_queue(dev); - np->timer.expires = jiffies + 1*HZ; - add_timer(&np->timer); + mod_timer(&np->timer, jiffies + 1*HZ); } else { netif_device_attach(dev); } @@ -1726,13 +1721,13 @@ #endif static struct pci_driver w840_driver = { - name: DRV_NAME, - id_table: w840_pci_tbl, - probe: w840_probe1, - remove: __devexit_p(w840_remove1), + .name = DRV_NAME, + .id_table = w840_pci_tbl, + .probe = w840_probe1, + .remove = __devexit_p(w840_remove1), #ifdef CONFIG_PM - suspend: w840_suspend, - resume: w840_resume, + .suspend = w840_suspend, + .resume = w840_resume, #endif }; Index: drivers/net/yellowfin.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/yellowfin.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/yellowfin.c 22 Jul 2004 19:49:34 -0000 1.1 +++ drivers/net/yellowfin.c 4 Aug 2004 01:29:13 -0000 1.2 @@ -867,8 +867,6 @@ /* Calculate the next Tx descriptor entry. */ entry = yp->cur_tx % TX_RING_SIZE; - yp->tx_skbuff[entry] = skb; - if (gx_fix) { /* Note: only works for paddable protocols e.g. IP. */ int cacheline_end = ((unsigned long)skb->data + skb->len) % 32; /* Fix GX chipset errata. */ @@ -885,6 +883,8 @@ return 0; } } + yp->tx_skbuff[entry] = skb; + #ifdef NO_TXSTATS yp->tx_ring[entry].addr = cpu_to_le32(pci_map_single(yp->pci_dev, skb->data, len, PCI_DMA_TODEVICE)); Index: drivers/net/appletalk/ltpc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/appletalk/ltpc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/appletalk/ltpc.c 22 Jul 2004 19:49:43 -0000 1.1 +++ drivers/net/appletalk/ltpc.c 4 Aug 2004 01:29:13 -0000 1.2 @@ -62,8 +62,8 @@ /*** * * $Log: ltpc.c,v $ - * Revision 1.1 2004/07/22 19:49:43 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:13 joff + * merging 2.4.26-vrs1 * * Revision 1.1.2.1 2000/03/01 05:35:07 jgarzik * at and tr cleanup Index: drivers/net/arcnet/arcnet.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/arcnet/arcnet.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/arcnet/arcnet.c 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/arcnet/arcnet.c 4 Aug 2004 01:29:13 -0000 1.2 @@ -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; Index: drivers/net/arcnet/rfc1201.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/arcnet/rfc1201.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/arcnet/rfc1201.c 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/arcnet/rfc1201.c 4 Aug 2004 01:29:13 -0000 1.2 @@ -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; Index: drivers/net/e100/e100.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/e100/e100.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/e100/e100.h 22 Jul 2004 19:49:37 -0000 1.1 +++ drivers/net/e100/e100.h 4 Aug 2004 01:29:13 -0000 1.2 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 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 @@ -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 Index: drivers/net/e100/e100_config.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/e100/e100_config.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/e100/e100_config.c 22 Jul 2004 19:49:37 -0000 1.1 +++ drivers/net/e100/e100_config.c 4 Aug 2004 01:29:13 -0000 1.2 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 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 @@ -60,7 +60,7 @@ * All other init functions will only set values that are * different from the 82557 default. */ -static void __devinit +void e100_config_init_82557(struct e100_private *bdp) { /* initialize config block */ @@ -104,7 +104,7 @@ e100_config_mulcast_enbl(bdp, false); } -static void __devinit +static void e100_config_init_82558(struct e100_private *bdp) { /* MWI enable. This should be turned on only if the adapter is a 82558/9 @@ -136,7 +136,7 @@ e100_config_long_rx(bdp, true); } -static void __devinit +static void e100_config_init_82550(struct e100_private *bdp) { /* The D102 chip allows for 32 config bytes. This value is @@ -160,7 +160,7 @@ } /* Initialize the adapter's configure block */ -void __devinit +void e100_config_init(struct e100_private *bdp) { e100_config_init_82557(bdp); Index: drivers/net/e100/e100_config.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/e100/e100_config.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/e100/e100_config.h 22 Jul 2004 19:49:37 -0000 1.1 +++ drivers/net/e100/e100_config.h 4 Aug 2004 01:29:14 -0000 1.2 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 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 @@ -151,6 +151,7 @@ /* function prototypes */ extern void e100_config_init(struct e100_private *bdp); +extern void e100_config_init_82557(struct e100_private *bdp); extern unsigned char e100_force_config(struct e100_private *bdp); extern unsigned char e100_config(struct e100_private *bdp); extern void e100_config_fc(struct e100_private *bdp); Index: drivers/net/e100/e100_eeprom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/e100/e100_eeprom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/e100/e100_eeprom.c 22 Jul 2004 19:49:37 -0000 1.1 +++ drivers/net/e100/e100_eeprom.c 4 Aug 2004 01:29:14 -0000 1.2 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 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 Index: drivers/net/e100/e100_main.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/e100/e100_main.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/e100/e100_main.c 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/e100/e100_main.c 4 Aug 2004 01:29:14 -0000 1.2 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 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 @@ -46,36 +46,20 @@ /* 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.38 12/14/03 + * o Added netpoll support. + * o Added ICH6 device ID support + * o Moved to 2.6 APIs: pci_name() and free_netdev(). + * o Removed some __devinit from some functions that shouldn't be marked + * as such (Anton Blanchard [anton@samba.org]). * - * 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.33 10/21/03 + * o Bug fix (Bugzilla 97908): Loading e100 was causing crash on Itanium2 + * with HP chipset + * o Bug fix (Bugzilla 101583): e100 can't pass traffic with ipv6 + * o Bug fix (Bugzilla 101360): PRO/10+ can't pass traffic + * + * 2.3.27 08/08/03 */ #include @@ -96,7 +80,14 @@ "rx_frame_errors", "rx_fifo_errors", "rx_missed_errors", "tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors", "tx_heartbeat_errors", "tx_window_errors", + /* device-specific stats */ + "tx_late_collision_errors", "tx_deferred", + "tx_single_collisions", "tx_multi_collisions", + "rx_collision_detected_errors", "tx_flow_control_pause", + "rx_flow_control_pause", "rx_flow_control_unsupported", + "tx_tco_packets", "rx_tco_packets", }; +#define E100_NET_STATS_LEN 21 #define E100_STATS_LEN sizeof(e100_gstrings_stats) / ETH_GSTRING_LEN static int e100_do_ethtool_ioctl(struct net_device *, struct ifreq *); @@ -121,14 +112,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 +129,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_copyright[] __devinitdata = "Copyright (c) 2004 Intel Corporation"; +char e100_driver_version[]="2.3.38-k1"; const char *e100_full_driver_name = "Intel(R) PRO/100 Network Driver"; char e100_short_driver_name[] = "e100"; static int e100nics = 0; @@ -151,10 +141,16 @@ static void e100_vlan_rx_add_vid(struct net_device *netdev, u16 vid); static void e100_vlan_rx_kill_vid(struct net_device *netdev, u16 vid); +#ifdef CONFIG_NET_POLL_CONTROLLER +/* for netdump / net console */ +static void e100_netpoll (struct net_device *dev); +#endif + #ifdef CONFIG_PM 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,18 +178,15 @@ 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 *); static int e100_set_mac(struct net_device *, void *); struct net_device_stats *e100_get_stats(struct net_device *); -static void e100intr(int, void *, struct pt_regs *); +static irqreturn_t 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 @@ -592,10 +583,6 @@ pci_set_drvdata(pcid, dev); - if ((rc = e100_alloc_space(bdp)) != 0) { - goto err_dev; - } - bdp->flags = 0; bdp->ifs_state = 0; bdp->ifs_value = 0; @@ -612,13 +599,19 @@ bdp->watchdog_timer.function = (void *) &e100_watchdog; if ((rc = e100_pci_setup(pcid, bdp)) != 0) { - goto err_dealloc; + goto err_dev; + } + + if ((rc = e100_alloc_space(bdp)) != 0) { + goto err_pci; } if (((bdp->pdev->device > 0x1030) && (bdp->pdev->device < 0x103F)) || ((bdp->pdev->device >= 0x1050) && (bdp->pdev->device <= 0x1057)) + || ((bdp->pdev->device >= 0x1064) + && (bdp->pdev->device <= 0x106B)) || (bdp->pdev->device == 0x2449) || (bdp->pdev->device == 0x2459) || (bdp->pdev->device == 0x245D)) { @@ -638,25 +631,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; @@ -670,19 +645,40 @@ dev->set_mac_address = &e100_set_mac; dev->do_ioctl = &e100_ioctl; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = e100_netpoll; +#endif + if (bdp->flags & USE_IPCB) - dev->features = NETIF_F_SG | NETIF_F_HW_CSUM | + dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; - e100nics++; + if ((rc = register_netdev(dev)) != 0) { + goto err_dealloc; + } - e100_get_speed_duplex_caps(bdp); + e100_check_options(e100nics, bdp); - if ((rc = register_netdev(dev)) != 0) { - goto err_pci; + 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; } - memcpy(bdp->ifname, dev->name, IFNAMSIZ); - bdp->ifname[IFNAMSIZ-1] = 0; + + e100nics++; + + e100_get_speed_duplex_caps(bdp); printk(KERN_NOTICE "e100: %s: %s\n", @@ -691,32 +687,33 @@ 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_dealloc: + e100_dealloc_space(bdp); err_pci: iounmap(bdp->scb); pci_release_regions(pcid); pci_disable_device(pcid); -err_dealloc: - e100_dealloc_space(bdp); err_dev: pci_set_drvdata(pcid, NULL); - kfree(dev); + free_netdev(dev); out: return rc; } @@ -738,7 +735,7 @@ e100_dealloc_space(bdp); pci_set_drvdata(bdp->pdev, NULL); - kfree(dev); + free_netdev(dev); } static void __devexit @@ -767,7 +764,7 @@ --e100nics; } -static struct pci_device_id e100_id_table[] __devinitdata = { +static struct pci_device_id e100_id_table[] = { {0x8086, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, {0x8086, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, {0x8086, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, @@ -791,6 +788,14 @@ {0x8086, 0x1053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, {0x8086, 0x1054, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, {0x8086, 0x1055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + {0x8086, 0x1064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + {0x8086, 0x1065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + {0x8086, 0x1066, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + {0x8086, 0x1067, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + {0x8086, 0x1068, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + {0x8086, 0x1069, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + {0x8086, 0x106A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + {0x8086, 0x106B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, {0x8086, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, {0x8086, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, {0,} /* This has to be the last entry*/ @@ -973,7 +978,7 @@ } } -static int +int e100_open(struct net_device *dev) { struct e100_private *bdp; @@ -1011,7 +1016,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 +1041,7 @@ return rc; } -static int +int e100_close(struct net_device *dev) { struct e100_private *bdp = dev->priv; @@ -1073,17 +1082,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 +1294,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,11 +1337,13 @@ 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; } -static void __devinit +static void e100_tco_workaround(struct e100_private *bdp) { int i; @@ -1383,11 +1393,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 +1407,28 @@ /* 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 ((u8) bdp->rev_id < D101A4_REV_ID) + e100_config_init_82557(bdp); + + 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 +1441,9 @@ } return true; +err: + printk(KERN_ERR "e100: hw init failed\n"); + return false; } /** @@ -1590,9 +1604,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 +1773,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(); @@ -1837,7 +1862,7 @@ * the RX & TX queues & starts the RU if it has stopped due * to no resources. */ -void +irqreturn_t e100intr(int irq, void *dev_inst, struct pt_regs *regs) { struct net_device *dev; @@ -1850,7 +1875,7 @@ intr_status = readw(&bdp->scb->scb_status); /* If not my interrupt, just return */ if (!(intr_status & SCB_STATUS_ACK_MASK) || (intr_status == 0xffff)) { - return; + return IRQ_NONE; } /* disable and ack intr */ @@ -1859,7 +1884,7 @@ /* the device is closed, don't continue or else bad things may happen. */ if (!netif_running(dev)) { e100_set_intr_mask(bdp); - return; + return IRQ_NONE; } /* SWI intr (triggered by watchdog) is signal to allocate new skb buffers */ @@ -1877,6 +1902,7 @@ e100_tx_srv(bdp); e100_set_intr_mask(bdp); + return IRQ_HANDLED; } /** @@ -2050,13 +2076,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 +2226,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++) { @@ -2506,7 +2533,7 @@ * true: if successfully cleared stat counters * false: otherwise */ -static unsigned char __devinit +static unsigned char e100_clr_cntrs(struct e100_private *bdp) { volatile u32 *pcmd_complete; @@ -2542,6 +2569,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 +3067,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) { @@ -3191,9 +3202,19 @@ void *addr = ifr->ifr_data; int i; - for(i = 0; i < E100_STATS_LEN; i++) + for(i = 0; i < E100_NET_STATS_LEN; i++) stats.data[i] = ((unsigned long *)&bdp->drv_stats.net_stats)[i]; + stats.data[i++] = bdp->drv_stats.tx_late_col; + stats.data[i++] = bdp->drv_stats.tx_ok_defrd; + stats.data[i++] = bdp->drv_stats.tx_one_retry; + stats.data[i++] = bdp->drv_stats.tx_mt_one_retry; + stats.data[i++] = bdp->drv_stats.rcv_cdt_frames; + stats.data[i++] = bdp->drv_stats.xmt_fc_pkts; + stats.data[i++] = bdp->drv_stats.rcv_fc_pkts; + stats.data[i++] = bdp->drv_stats.rcv_fc_unsupported; + stats.data[i++] = bdp->drv_stats.xmt_tco_pkts; + stats.data[i++] = bdp->drv_stats.rcv_tco_pkts; if(copy_to_user(addr, &stats, sizeof(stats))) return -EFAULT; return 0; @@ -3211,6 +3232,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 +3443,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 +3451,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 +3488,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 +3529,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 +3544,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 +3558,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 +3569,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 +3587,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; } @@ -3447,12 +3618,12 @@ strncpy(info.version, e100_driver_version, sizeof (info.version) - 1); strncpy(info.fw_version, "N/A", sizeof (info.fw_version) - 1); - strncpy(info.bus_info, bdp->pdev->slot_name, + strncpy(info.bus_info, pci_name(bdp->pdev), sizeof (info.bus_info) - 1); 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 +3642,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 +3919,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 +3967,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 +4044,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 +4276,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 +4333,6 @@ return 0; } -#endif /* CONFIG_PM */ /** * e100_asf_enabled - checks if ASF is configured on the current adaper @@ -4188,6 +4358,7 @@ } return false; } +#endif /* CONFIG_PM */ #ifdef E100_CU_DEBUG unsigned char @@ -4205,3 +4376,18 @@ } #endif +#ifdef CONFIG_NET_POLL_CONTROLLER +/* + * Polling 'interrupt' - used by things like netconsole to send skbs + * without having to re-enable interrupts. It's not called while + * the interrupt routine is executing. + */ + +static void e100_netpoll (struct net_device *dev) +{ + struct e100_private *adapter = dev->priv; + disable_irq(adapter->pdev->irq); + e100intr (adapter->pdev->irq, dev, NULL); + enable_irq(adapter->pdev->irq); +} +#endif Index: drivers/net/e100/e100_phy.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/e100/e100_phy.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/e100/e100_phy.c 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/e100/e100_phy.c 4 Aug 2004 01:29:14 -0000 1.2 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 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 @@ -132,7 +132,7 @@ } } -static unsigned char __devinit +static unsigned char e100_phy_valid(struct e100_private *bdp, unsigned int phy_address) { u16 ctrl_reg, stat_reg; @@ -150,7 +150,7 @@ return true; } -static void __devinit +static void e100_phy_address_detect(struct e100_private *bdp) { unsigned int addr; @@ -180,7 +180,7 @@ } } -static void __devinit +static void e100_phy_id_detect(struct e100_private *bdp) { u16 low_id_reg, high_id_reg; @@ -204,7 +204,7 @@ ((unsigned int) high_id_reg << 16)); } -static void __devinit +static void e100_phy_isolate(struct e100_private *bdp) { unsigned int phy_address; @@ -227,7 +227,7 @@ } } -static unsigned char __devinit +static unsigned char e100_phy_specific_setup(struct e100_private *bdp) { u16 misc_reg; @@ -380,7 +380,7 @@ * Returns: * NOTHING */ -static void __devinit +static void e100_fix_polarity(struct e100_private *bdp) { u16 status; @@ -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 +unsigned char 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); Index: drivers/net/e100/e100_phy.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/e100/e100_phy.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/e100/e100_phy.h 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/e100/e100_phy.h 4 Aug 2004 01:29:14 -0000 1.2 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 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 Index: drivers/net/e100/e100_test.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/e100/e100_test.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/e100/e100_test.c 22 Jul 2004 19:49:37 -0000 1.1 +++ drivers/net/e100/e100_test.c 4 Aug 2004 01:29:14 -0000 1.2 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 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 @@ -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; +} + Index: drivers/net/e100/e100_ucode.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/e100/e100_ucode.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/e100/e100_ucode.h 22 Jul 2004 19:49:37 -0000 1.1 +++ drivers/net/e100/e100_ucode.h 4 Aug 2004 01:29:14 -0000 1.2 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 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 Index: drivers/net/e1000/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/e1000/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/e1000/Makefile 22 Jul 2004 19:49:43 -0000 1.1 +++ drivers/net/e1000/Makefile 4 Aug 2004 01:29:14 -0000 1.2 @@ -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 Index: drivers/net/e1000/e1000.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/e1000/e1000.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/e1000/e1000.h 22 Jul 2004 19:49:43 -0000 1.1 +++ drivers/net/e1000/e1000.h 4 Aug 2004 01:29:14 -0000 1.2 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 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 @@ -63,6 +63,9 @@ #include #include #include +#ifdef NETIF_F_TSO +#include +#endif #include #include #include @@ -89,6 +92,16 @@ #define E1000_MAX_INTR 10 +/* How many descriptors for TX and RX ? */ +#define E1000_DEFAULT_TXD 256 +#define E1000_MAX_TXD 256 +#define E1000_MIN_TXD 80 +#define E1000_MAX_82544_TXD 4096 +#define E1000_DEFAULT_RXD 256 +#define E1000_MAX_RXD 256 +#define E1000_MIN_RXD 80 +#define E1000_MAX_82544_RXD 4096 + /* Supported Rx Buffer Sizes */ #define E1000_RXBUFFER_2048 2048 #define E1000_RXBUFFER_4096 4096 @@ -104,11 +117,11 @@ #define E1000_TX_HEAD_ADDR_SHIFT 7 #define E1000_PBA_TX_MASK 0xFFFF0000 -/* Flow Control High-Watermark: 43464 bytes */ -#define E1000_FC_HIGH_THRESH 0xA9C8 +/* Flow Control High-Watermark: 5688 bytes below Rx FIFO size */ +#define E1000_FC_HIGH_DIFF 0x1638 -/* Flow Control Low-Watermark: 43456 bytes */ -#define E1000_FC_LOW_THRESH 0xA9C0 +/* Flow Control Low-Watermark: 5696 bytes below Rx FIFO size */ +#define E1000_FC_LOW_DIFF 0x1640 /* Flow Control Pause Time: 858 usec */ #define E1000_FC_PAUSE_TIME 0x0680 @@ -119,7 +132,12 @@ #define E1000_RX_BUFFER_WRITE 16 /* Must be power of 2 */ #define AUTO_ALL_MODES 0 -#define E1000_EEPROM_APME 4 +#define E1000_EEPROM_APME 0x0400 + +#ifndef E1000_MASTER_SLAVE +/* Switch to override PHY master/slave setting */ +#define E1000_MASTER_SLAVE e1000_ms_hw_default +#endif /* only works for sizes that are powers of 2 */ #define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1))) @@ -131,6 +149,7 @@ uint64_t dma; unsigned long length; unsigned long time_stamp; + unsigned int next_to_watch; }; struct e1000_desc_ring { @@ -166,7 +185,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; @@ -177,20 +195,26 @@ spinlock_t stats_lock; atomic_t irq_sem; struct tq_struct tx_timeout_task; + uint8_t fc_autoneg; struct timer_list blink_timer; unsigned long led_status; /* TX */ struct e1000_desc_ring tx_ring; + spinlock_t tx_lock; uint32_t txd_cmd; uint32_t tx_int_delay; uint32_t tx_abs_int_delay; uint32_t gotcl; + uint64_t gotcl_old; + uint64_t tpt_old; + uint64_t colc_old; uint32_t tx_fifo_head; uint32_t tx_head_addr; uint32_t tx_fifo_size; atomic_t tx_fifo_stall; + boolean_t pcix_82544; /* RX */ struct e1000_desc_ring rx_ring; @@ -200,6 +224,7 @@ uint32_t rx_abs_int_delay; boolean_t rx_csum; uint32_t gorcl; + uint64_t gorcl_old; /* Interrupt Throttle Rate */ uint32_t itr; @@ -215,9 +240,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_ */ Index: drivers/net/e1000/e1000_ethtool.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/e1000/e1000_ethtool.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/e1000/e1000_ethtool.c 22 Jul 2004 19:49:43 -0000 1.1 +++ drivers/net/e1000/e1000_ethtool.c 4 Aug 2004 01:29:14 -0000 1.2 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 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 @@ -39,16 +39,66 @@ extern void e1000_down(struct e1000_adapter *adapter); extern void e1000_reset(struct e1000_adapter *adapter); extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx); +extern int e1000_setup_rx_resources(struct e1000_adapter *adapter); +extern int e1000_setup_tx_resources(struct e1000_adapter *adapter); +extern void e1000_free_rx_resources(struct e1000_adapter *adapter); +extern void e1000_free_tx_resources(struct e1000_adapter *adapter); +extern void e1000_update_stats(struct e1000_adapter *adapter); + +struct e1000_stats { + char stat_string[ETH_GSTRING_LEN]; + int sizeof_stat; + int stat_offset; +}; -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", +#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_STATS_LEN sizeof(e1000_gstrings_stats) / ETH_GSTRING_LEN +#define E1000_TEST_LEN sizeof(e1000_gstrings_test) / ETH_GSTRING_LEN static void e1000_ethtool_gset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd) @@ -145,6 +195,59 @@ return 0; } +static int +e1000_ethtool_gpause(struct e1000_adapter *adapter, + struct ethtool_pauseparam *epause) +{ + struct e1000_hw *hw = &adapter->hw; + + epause->autoneg = + (adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE); + + if(hw->fc == e1000_fc_rx_pause) + epause->rx_pause = 1; + else if(hw->fc == e1000_fc_tx_pause) + epause->tx_pause = 1; + else if(hw->fc == e1000_fc_full) { + epause->rx_pause = 1; + epause->tx_pause = 1; + } + + return 0; +} + +static int +e1000_ethtool_spause(struct e1000_adapter *adapter, + struct ethtool_pauseparam *epause) +{ + struct e1000_hw *hw = &adapter->hw; + + adapter->fc_autoneg = epause->autoneg; + + if(epause->rx_pause && epause->tx_pause) + hw->fc = e1000_fc_full; + else if(epause->rx_pause && !epause->tx_pause) + hw->fc = e1000_fc_rx_pause; + else if(!epause->rx_pause && epause->tx_pause) + hw->fc = e1000_fc_tx_pause; + else if(!epause->rx_pause && !epause->tx_pause) + hw->fc = e1000_fc_none; + + hw->original_fc = hw->fc; + + if(adapter->fc_autoneg == AUTONEG_ENABLE) { + if(netif_running(adapter->netdev)) { + e1000_down(adapter); + e1000_up(adapter); + } else + e1000_reset(adapter); + } + else + return e1000_force_mac_fc(hw); + + return 0; +} + static void e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter, struct ethtool_drvinfo *drvinfo) @@ -152,8 +255,9 @@ strncpy(drvinfo->driver, e1000_driver_name, 32); strncpy(drvinfo->version, e1000_driver_version, 32); strncpy(drvinfo->fw_version, "N/A", 32); - strncpy(drvinfo->bus_info, adapter->pdev->slot_name, 32); + strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 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 +268,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 +287,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 +380,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 +410,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 +445,776 @@ 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 irqreturn_t +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 IRQ_HANDLED; +} + +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(adapter->pdev->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(adapter->pdev->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 |= cpu_to_le32(E1000_TXD_CMD_EOP | + E1000_TXD_CMD_IFCS | + 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_82545_rev_3: + case e1000_82546: + case e1000_82546_rev_3: + case e1000_82541: + case e1000_82541_rev_2: + case e1000_82547: + case e1000_82547_rev_2: + 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 || + adapter->hw.media_type == e1000_media_type_internal_serdes) { + if(adapter->hw.mac_type == e1000_82545 || + adapter->hw.mac_type == e1000_82546 || + adapter->hw.mac_type == e1000_82545_rev_3 || + adapter->hw.mac_type == e1000_82546_rev_3) + 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.media_type == e1000_media_type_internal_serdes) && + (adapter->hw.mac_type == e1000_82545 || + adapter->hw.mac_type == e1000_82546 || + adapter->hw.mac_type == e1000_82545_rev_3 || + adapter->hw.mac_type == e1000_82546_rev_3))) { + 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) { @@ -299,6 +1230,7 @@ return; case E1000_DEV_ID_82546EB_FIBER: + case E1000_DEV_ID_82546GB_FIBER: /* Wake events only supported on port A for dual fiber */ if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) { wol->supported = 0; @@ -337,6 +1269,7 @@ return wol->wolopts ? -EOPNOTSUPP : 0; case E1000_DEV_ID_82546EB_FIBER: + case E1000_DEV_ID_82546GB_FIBER: /* Wake events only supported on port A for dual fiber */ if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) return wol->wolopts ? -EOPNOTSUPP : 0; @@ -427,8 +1360,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 +1374,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 +1432,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 +1460,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 +1471,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,29 +1501,165 @@ case ETHTOOL_SEEPROM: { struct ethtool_eeprom eeprom; - if(!capable(CAP_NET_ADMIN)) - return -EPERM; - if(copy_from_user(&eeprom, addr, sizeof(eeprom))) return -EFAULT; addr += offsetof(struct ethtool_eeprom, data); return e1000_ethtool_seeprom(adapter, &eeprom, addr); } + case ETHTOOL_GPAUSEPARAM: { + struct ethtool_pauseparam epause = {ETHTOOL_GPAUSEPARAM}; + e1000_ethtool_gpause(adapter, &epause); + if(copy_to_user(addr, &epause, sizeof(epause))) + return -EFAULT; + return 0; + } + case ETHTOOL_SPAUSEPARAM: { + struct ethtool_pauseparam epause; + if(copy_from_user(&epause, addr, sizeof(epause))) + return -EFAULT; + return e1000_ethtool_spause(adapter, &epause); + } 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; + e1000_update_stats(adapter); 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; + } + case ETHTOOL_GRXCSUM: { + struct ethtool_value edata = { ETHTOOL_GRXCSUM }; + + edata.data = adapter->rx_csum; + if (copy_to_user(addr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + case ETHTOOL_SRXCSUM: { + struct ethtool_value edata; + + if (copy_from_user(&edata, addr, sizeof(edata))) + return -EFAULT; + adapter->rx_csum = edata.data; + if(netif_running(netdev)) { + e1000_down(adapter); + e1000_up(adapter); + } else + e1000_reset(adapter); + return 0; + } + case ETHTOOL_GTXCSUM: { + struct ethtool_value edata = { ETHTOOL_GTXCSUM }; + + edata.data = + (netdev->features & NETIF_F_HW_CSUM) != 0; + if (copy_to_user(addr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + case ETHTOOL_STXCSUM: { + struct ethtool_value edata; + + if (copy_from_user(&edata, addr, sizeof(edata))) + return -EFAULT; + + if(adapter->hw.mac_type < e1000_82543) { + if (edata.data != 0) + return -EINVAL; + return 0; + } + + if (edata.data) + netdev->features |= NETIF_F_HW_CSUM; + else + netdev->features &= ~NETIF_F_HW_CSUM; + + return 0; + } + case ETHTOOL_GSG: { + struct ethtool_value edata = { ETHTOOL_GSG }; + + edata.data = + (netdev->features & NETIF_F_SG) != 0; + if (copy_to_user(addr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + case ETHTOOL_SSG: { + struct ethtool_value edata; + + if (copy_from_user(&edata, addr, sizeof(edata))) + return -EFAULT; + + if (edata.data) + netdev->features |= NETIF_F_SG; + else + netdev->features &= ~NETIF_F_SG; + + return 0; + } +#ifdef NETIF_F_TSO + case ETHTOOL_GTSO: { + struct ethtool_value edata = { ETHTOOL_GTSO }; + + edata.data = (netdev->features & NETIF_F_TSO) != 0; + if (copy_to_user(addr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + case ETHTOOL_STSO: { + struct ethtool_value edata; + + if (copy_from_user(&edata, addr, sizeof(edata))) + return -EFAULT; + + if ((adapter->hw.mac_type < e1000_82544) || + (adapter->hw.mac_type == e1000_82547)) { + if (edata.data != 0) + return -EINVAL; + return 0; + } + + if (edata.data) + netdev->features |= NETIF_F_TSO; + else + netdev->features &= ~NETIF_F_TSO; + + return 0; + } +#endif default: return -EOPNOTSUPP; } Index: drivers/net/e1000/e1000_hw.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/e1000/e1000_hw.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/e1000/e1000_hw.c 22 Jul 2004 19:49:43 -0000 1.1 +++ drivers/net/e1000/e1000_hw.c 4 Aug 2004 01:29:14 -0000 1.2 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 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 @@ -34,14 +34,15 @@ static int32_t e1000_set_phy_type(struct e1000_hw *hw); static void e1000_phy_init_script(struct e1000_hw *hw); -static int32_t e1000_setup_fiber_link(struct e1000_hw *hw); static int32_t e1000_setup_copper_link(struct e1000_hw *hw); +static int32_t e1000_setup_fiber_serdes_link(struct e1000_hw *hw); +static int32_t e1000_adjust_serdes_amplitude(struct e1000_hw *hw); static int32_t e1000_phy_force_speed_duplex(struct e1000_hw *hw); static int32_t e1000_config_mac_to_phy(struct e1000_hw *hw); -static int32_t e1000_force_mac_fc(struct e1000_hw *hw); static void e1000_raise_mdi_clk(struct e1000_hw *hw, uint32_t *ctrl); static void e1000_lower_mdi_clk(struct e1000_hw *hw, uint32_t *ctrl); -static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, uint32_t data, uint16_t count); +static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, uint32_t data, + uint16_t count); static uint16_t e1000_shift_in_mdi_bits(struct e1000_hw *hw); static int32_t e1000_phy_reset_dsp(struct e1000_hw *hw); static int32_t e1000_write_eeprom_spi(struct e1000_hw *hw, uint16_t offset, @@ -52,13 +53,30 @@ static int32_t e1000_spi_eeprom_ready(struct e1000_hw *hw); static void e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t *eecd); static void e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t *eecd); -static void e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data, uint16_t count); +static void e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data, + uint16_t count); +static int32_t e1000_write_phy_reg_ex(struct e1000_hw *hw, uint32_t reg_addr, + uint16_t phy_data); +static int32_t e1000_read_phy_reg_ex(struct e1000_hw *hw,uint32_t reg_addr, + uint16_t *phy_data); static uint16_t e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count); static int32_t e1000_acquire_eeprom(struct e1000_hw *hw); static void e1000_release_eeprom(struct e1000_hw *hw); static void e1000_standby_eeprom(struct e1000_hw *hw); static int32_t e1000_id_led_init(struct e1000_hw * hw); +static int32_t e1000_set_vco_speed(struct e1000_hw *hw); +/* IGP cable length table */ +static const +uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] = + { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 25, 25, 25, + 25, 25, 25, 25, 30, 30, 30, 30, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 50, 50, 50, 50, 50, 50, 50, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 70, 70, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120}; /****************************************************************************** @@ -78,8 +96,14 @@ hw->phy_type = e1000_phy_m88; break; case IGP01E1000_I_PHY_ID: - hw->phy_type = e1000_phy_igp; - break; + if(hw->mac_type == e1000_82541 || + hw->mac_type == e1000_82541_rev_2 || + hw->mac_type == e1000_82547 || + hw->mac_type == e1000_82547_rev_2) { + hw->phy_type = e1000_phy_igp; + break; + } + /* Fall Through */ default: /* Should never have loaded on this device */ hw->phy_type = e1000_phy_undefined; @@ -100,41 +124,63 @@ DEBUGFUNC("e1000_phy_init_script"); if(hw->phy_init_script) { - msec_delay(10); + msec_delay(20); - e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000); e1000_write_phy_reg(hw,0x0000,0x0140); msec_delay(5); - e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F95); - e1000_write_phy_reg(hw,0x0015,0x0001); - e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F71); - e1000_write_phy_reg(hw,0x0011,0xBD21); + if(hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547) { + e1000_write_phy_reg(hw, 0x1F95, 0x0001); + + e1000_write_phy_reg(hw, 0x1F71, 0xBD21); + + e1000_write_phy_reg(hw, 0x1F79, 0x0018); + + e1000_write_phy_reg(hw, 0x1F30, 0x1600); + + e1000_write_phy_reg(hw, 0x1F31, 0x0014); - e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F79); - e1000_write_phy_reg(hw,0x0019,0x0018); + e1000_write_phy_reg(hw, 0x1F32, 0x161C); - e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F30); - e1000_write_phy_reg(hw,0x0010,0x1600); + e1000_write_phy_reg(hw, 0x1F94, 0x0003); - e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F31); - e1000_write_phy_reg(hw,0x0011,0x0014); + e1000_write_phy_reg(hw, 0x1F96, 0x003F); - e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F32); - e1000_write_phy_reg(hw,0x0012,0x161C); + e1000_write_phy_reg(hw, 0x2010, 0x0008); + } else { + e1000_write_phy_reg(hw, 0x1F73, 0x0099); + } + + e1000_write_phy_reg(hw, 0x0000, 0x3300); + + if(hw->mac_type == e1000_82547) { + uint16_t fused, fine, coarse; - e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F94); - e1000_write_phy_reg(hw,0x0014,0x0003); + /* Move to analog registers page */ + e1000_read_phy_reg(hw, IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused); - e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F96); - e1000_write_phy_reg(hw,0x0016,0x003F); + if(!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) { + e1000_read_phy_reg(hw, IGP01E1000_ANALOG_FUSE_STATUS, &fused); - e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x2010); - e1000_write_phy_reg(hw,0x0010,0x0008); + fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK; + coarse = fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK; - e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000); - e1000_write_phy_reg(hw,0x0000,0x3300); + 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); + } + } } } @@ -183,31 +229,89 @@ case E1000_DEV_ID_82545EM_FIBER: hw->mac_type = e1000_82545; break; + case E1000_DEV_ID_82545GM_COPPER: + case E1000_DEV_ID_82545GM_FIBER: + case E1000_DEV_ID_82545GM_SERDES: + hw->mac_type = e1000_82545_rev_3; + 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_82546GB_COPPER: + case E1000_DEV_ID_82546GB_FIBER: + case E1000_DEV_ID_82546GB_SERDES: + hw->mac_type = e1000_82546_rev_3; + break; case E1000_DEV_ID_82541EI: - case E1000_DEV_ID_82541EP: + case E1000_DEV_ID_82541EI_MOBILE: hw->mac_type = e1000_82541; break; + case E1000_DEV_ID_82541ER: + case E1000_DEV_ID_82541GI: + case E1000_DEV_ID_82541GI_MOBILE: + hw->mac_type = e1000_82541_rev_2; + break; case E1000_DEV_ID_82547EI: hw->mac_type = e1000_82547; break; + case E1000_DEV_ID_82547GI: + hw->mac_type = e1000_82547_rev_2; + break; default: /* Should never have loaded on this device */ return -E1000_ERR_MAC_TYPE; } - return E1000_SUCCESS; } + +/***************************************************************************** + * Set media type and TBI compatibility. + * + * hw - Struct containing variables accessed by shared code + * **************************************************************************/ +void +e1000_set_media_type(struct e1000_hw *hw) +{ + uint32_t status; + + DEBUGFUNC("e1000_set_media_type"); + + if(hw->mac_type != e1000_82543) { + /* tbi_compatibility is only valid on 82543 */ + hw->tbi_compatibility_en = FALSE; + } + + switch (hw->device_id) { + case E1000_DEV_ID_82545GM_SERDES: + case E1000_DEV_ID_82546GB_SERDES: + hw->media_type = e1000_media_type_internal_serdes; + break; + default: + if(hw->mac_type >= e1000_82543) { + status = E1000_READ_REG(hw, STATUS); + if(status & E1000_STATUS_TBIMODE) { + hw->media_type = e1000_media_type_fiber; + /* tbi_compatibility not valid on fiber */ + hw->tbi_compatibility_en = FALSE; + } else { + hw->media_type = e1000_media_type_copper; + } + } else { + /* This is an 82542 (fiber only) */ + hw->media_type = e1000_media_type_fiber; + } + } +} + /****************************************************************************** * Reset the transmit and receive units; mask and clear all interrupts. * * hw - Struct containing variables accessed by shared code *****************************************************************************/ -void +int32_t e1000_reset_hw(struct e1000_hw *hw) { uint32_t ctrl; @@ -244,39 +348,75 @@ */ msec_delay(10); + ctrl = E1000_READ_REG(hw, CTRL); + + /* Must reset the PHY before resetting the MAC */ + if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { + E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST)); + msec_delay(5); + } + /* Issue a global reset to the MAC. This will reset the chip's * transmit, receive, DMA, and link units. It will not effect * the current PCI configuration. The global reset bit is self- * clearing, and should clear within a microsecond. */ DEBUGOUT("Issuing a global reset to MAC\n"); - ctrl = E1000_READ_REG(hw, CTRL); - /* Must reset the PHY before resetting the MAC */ - if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { - E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST)); - msec_delay(5); + switch(hw->mac_type) { + case e1000_82544: + case e1000_82540: + case e1000_82545: + case e1000_82546: + case e1000_82541: + case e1000_82541_rev_2: + /* 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; + case e1000_82545_rev_3: + case e1000_82546_rev_3: + /* Reset is performed on a shadow of the control register */ + E1000_WRITE_REG(hw, CTRL_DUP, (ctrl | E1000_CTRL_RST)); + break; + default: + E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST)); + break; } - 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)); + /* After MAC reset, force reload of EEPROM to restore power-on settings to + * device. Later controllers reload the EEPROM automatically, so just wait + * for reload to complete. + */ + switch(hw->mac_type) { + case e1000_82542_rev2_0: + case e1000_82542_rev2_1: + case e1000_82543: + case e1000_82544: + /* Wait for reset to complete */ + udelay(10); + ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); + ctrl_ext |= E1000_CTRL_EXT_EE_RST; + E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); + E1000_WRITE_FLUSH(hw); + /* Wait for EEPROM reload */ + msec_delay(2); + break; + case e1000_82541: + case e1000_82541_rev_2: + case e1000_82547: + case e1000_82547_rev_2: + /* Wait for EEPROM reload */ + msec_delay(20); + break; + default: + /* Wait for EEPROM reload (it happens automatically) */ + msec_delay(5); + break; + } - /* Force a reload from the EEPROM if necessary */ - if(hw->mac_type < e1000_82540) { - /* Wait for reset to complete */ - udelay(10); - ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); - ctrl_ext |= E1000_CTRL_EXT_EE_RST; - E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); - E1000_WRITE_FLUSH(hw); - /* Wait for EEPROM reload */ - msec_delay(2); - } else { - /* Wait for EEPROM reload (it happens automatically) */ - msec_delay(5); - /* Dissable HW ARPs on ASF enabled adapters */ + /* Disable HW ARPs on ASF enabled adapters */ + if(hw->mac_type >= e1000_82540) { manc = E1000_READ_REG(hw, MANC); manc &= ~(E1000_MANC_ARP_EN); E1000_WRITE_REG(hw, MANC, manc); @@ -288,9 +428,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); } @@ -306,6 +444,8 @@ if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE) e1000_pci_set_mwi(hw); } + + return E1000_SUCCESS; } /****************************************************************************** @@ -322,7 +462,7 @@ int32_t e1000_init_hw(struct e1000_hw *hw) { - uint32_t ctrl, status; + uint32_t ctrl; uint32_t i; int32_t ret_val; uint16_t pcix_cmd_word; @@ -333,31 +473,13 @@ DEBUGFUNC("e1000_init_hw"); /* Initialize Identification LED */ - ret_val = e1000_id_led_init(hw); - if(ret_val < 0) { + if((ret_val = e1000_id_led_init(hw))) { DEBUGOUT("Error Initializing Identification LED\n"); return ret_val; } - /* Set the Media Type and exit with error if it is not valid. */ - if(hw->mac_type != e1000_82543) { - /* tbi_compatibility is only valid on 82543 */ - hw->tbi_compatibility_en = FALSE; - } - - if(hw->mac_type >= e1000_82543) { - status = E1000_READ_REG(hw, STATUS); - if(status & E1000_STATUS_TBIMODE) { - hw->media_type = e1000_media_type_fiber; - /* tbi_compatibility not valid on fiber */ - hw->tbi_compatibility_en = FALSE; - } else { - hw->media_type = e1000_media_type_copper; - } - } else { - /* This is an 82542 (fiber only) */ - hw->media_type = e1000_media_type_fiber; - } + /* Set the media type and TBI compatibility */ + e1000_set_media_type(hw); /* Disabling VLAN filtering. */ DEBUGOUT("Initializing the IEEE VLAN\n"); @@ -402,21 +524,30 @@ E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR); } - /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */ - if(hw->bus_type == e1000_bus_type_pcix) { - e1000_read_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd_word); - e1000_read_pci_cfg(hw, PCIX_STATUS_REGISTER_HI, &pcix_stat_hi_word); - cmd_mmrbc = (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >> - PCIX_COMMAND_MMRBC_SHIFT; - stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >> - PCIX_STATUS_HI_MMRBC_SHIFT; - if(stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K) - stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K; - if(cmd_mmrbc > stat_mmrbc) { - pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK; - pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT; - e1000_write_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd_word); + switch(hw->mac_type) { + case e1000_82545_rev_3: + case e1000_82546_rev_3: + break; + default: + /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */ + if(hw->bus_type == e1000_bus_type_pcix) { + e1000_read_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd_word); + e1000_read_pci_cfg(hw, PCIX_STATUS_REGISTER_HI, + &pcix_stat_hi_word); + cmd_mmrbc = (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >> + PCIX_COMMAND_MMRBC_SHIFT; + stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >> + PCIX_STATUS_HI_MMRBC_SHIFT; + if(stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K) + stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K; + if(cmd_mmrbc > stat_mmrbc) { + pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK; + pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT; + e1000_write_pci_cfg(hw, PCIX_COMMAND_REGISTER, + &pcix_cmd_word); + } } + break; } /* Call a subroutine to configure the link and setup flow control. */ @@ -440,6 +571,46 @@ } /****************************************************************************** + * Adjust SERDES output amplitude based on EEPROM setting. + * + * hw - Struct containing variables accessed by shared code. + *****************************************************************************/ +static int32_t +e1000_adjust_serdes_amplitude(struct e1000_hw *hw) +{ + uint16_t eeprom_data; + int32_t ret_val; + + DEBUGFUNC("e1000_adjust_serdes_amplitude"); + + if(hw->media_type != e1000_media_type_internal_serdes) + return E1000_SUCCESS; + + switch(hw->mac_type) { + case e1000_82545_rev_3: + case e1000_82546_rev_3: + break; + default: + return E1000_SUCCESS; + } + + if ((ret_val = e1000_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1, + &eeprom_data))) { + return ret_val; + } + + if(eeprom_data != EEPROM_RESERVED_WORD) { + /* Adjust SERDES output amplitude only. */ + eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK; + if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL, + eeprom_data))) + return ret_val; + } + + return E1000_SUCCESS; +} + +/****************************************************************************** * Configures flow control and link settings. * * hw - Struct containing variables accessed by shared code @@ -510,9 +681,9 @@ } /* Call the necessary subroutine to configure the link. */ - ret_val = (hw->media_type == e1000_media_type_fiber) ? - e1000_setup_fiber_link(hw) : - e1000_setup_copper_link(hw); + ret_val = (hw->media_type == e1000_media_type_copper) ? + e1000_setup_copper_link(hw) : + e1000_setup_fiber_serdes_link(hw); /* Initialize the flow control address, type, and PAUSE timer * registers to their default values. This is done even if flow @@ -551,7 +722,7 @@ } /****************************************************************************** - * Sets up link for a fiber based adapter + * Sets up link for a fiber based or serdes based adapter * * hw - Struct containing variables accessed by shared code * @@ -560,28 +731,37 @@ * and receiver are not enabled. *****************************************************************************/ static int32_t -e1000_setup_fiber_link(struct e1000_hw *hw) +e1000_setup_fiber_serdes_link(struct e1000_hw *hw) { uint32_t ctrl; uint32_t status; uint32_t txcw = 0; uint32_t i; - uint32_t signal; + uint32_t signal = 0; int32_t ret_val; - DEBUGFUNC("e1000_setup_fiber_link"); + DEBUGFUNC("e1000_setup_fiber_serdes_link"); - /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be + /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be * set when the optics detect a signal. On older adapters, it will be - * cleared when there is a signal + * cleared when there is a signal. This applies to fiber media only. + * If we're on serdes media, adjust the output amplitude to value set in + * the EEPROM. */ ctrl = E1000_READ_REG(hw, CTRL); - if(hw->mac_type > e1000_82544) signal = E1000_CTRL_SWDPIN1; - else signal = 0; + if(hw->media_type == e1000_media_type_fiber) + signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0; + + if((ret_val = e1000_adjust_serdes_amplitude(hw))) + return ret_val; /* Take the link out of reset */ ctrl &= ~(E1000_CTRL_LRST); + /* Adjust VCO speed to improve BER performance */ + if((ret_val = e1000_set_vco_speed(hw))) + return ret_val; + e1000_config_collision_dist(hw); /* Check for a software override of the flow control settings, and setup @@ -648,8 +828,10 @@ * indication in the Device Status Register. Time-out if a link isn't * seen in 500 milliseconds seconds (Auto-negotiation should complete in * less than 500 milliseconds even if the other end is doing it in SW). + * For internal serdes, we just assume a signal is present, then poll. */ - if((E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) { + if(hw->media_type == e1000_media_type_internal_serdes || + (E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) { DEBUGOUT("Looking for Link\n"); for(i = 0; i < (LINK_UP_TIMEOUT / 10); i++) { msec_delay(10); @@ -657,15 +839,14 @@ if(status & E1000_STATUS_LU) break; } if(i == (LINK_UP_TIMEOUT / 10)) { + DEBUGOUT("Never got a valid link from auto-neg!!!\n"); + hw->autoneg_failed = 1; /* AutoNeg failed to achieve a link, so we'll call - * e1000_check_for_link. This routine will force the link up if we - * detect a signal. This will allow us to communicate with + * e1000_check_for_link. This routine will force the link up if + * we detect a signal. This will allow us to communicate with * non-autonegotiating link partners. */ - DEBUGOUT("Never got a valid link from auto-neg!!!\n"); - hw->autoneg_failed = 1; - ret_val = e1000_check_for_link(hw); - if(ret_val < 0) { + if((ret_val = e1000_check_for_link(hw))) { DEBUGOUT("Error while checking for link\n"); return ret_val; } @@ -677,7 +858,7 @@ } else { DEBUGOUT("No Signal Detected\n"); } - return 0; + return E1000_SUCCESS; } /****************************************************************************** @@ -688,7 +869,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; @@ -711,237 +893,283 @@ } /* Make sure we have a valid PHY */ - ret_val = e1000_detect_gig_phy(hw); - if(ret_val < 0) { + if((ret_val = e1000_detect_gig_phy(hw))) { DEBUGOUT("Error, did not detect valid phy.\n"); return ret_val; } DEBUGOUT1("Phy ID = %x \n", hw->phy_id); - if (hw->phy_type == e1000_phy_igp) { - - ret_val = e1000_phy_reset(hw); - if(ret_val < 0) { - DEBUGOUT("Error Resetting the PHY\n"); - return ret_val; - } + if(hw->mac_type <= e1000_82543 || + hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 || + hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2) + hw->phy_reset_disable = FALSE; - /* Wait 10ms for MAC to configure PHY from eeprom settings */ - msec_delay(15); + if(!hw->phy_reset_disable) { + if (hw->phy_type == e1000_phy_igp) { - if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0000) < 0) { - DEBUGOUT("PHY Write Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_phy_reset(hw))) { + DEBUGOUT("Error Resetting the PHY\n"); + return ret_val; + } - /* 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; - E1000_WRITE_REG(hw, LEDCTL, led_ctrl); + /* Wait 10ms for MAC to configure PHY from eeprom settings */ + msec_delay(15); - if(hw->autoneg_advertised == ADVERTISE_1000_FULL) { - /* Disable SmartSpeed */ - if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, - &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; - if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, - phy_data) < 0) { - DEBUGOUT("PHY Write Error\n"); - return -E1000_ERR_PHY; - } - /* Set auto Master/Slave resolution process */ - if(e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; + /* 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 | IGP_LED3_MODE); + E1000_WRITE_REG(hw, LEDCTL, led_ctrl); + + /* disable lplu d3 during driver init */ + if((ret_val = e1000_set_d3_lplu_state(hw, FALSE))) { + DEBUGOUT("Error Disabling LPLU D3\n"); + return ret_val; } - phy_data &= ~CR_1000T_MS_ENABLE; - if(e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data) < 0) { - DEBUGOUT("PHY Write Error\n"); - return -E1000_ERR_PHY; + + /* Configure mdi-mdix settings */ + if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, + &phy_data))) + return ret_val; + + if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { + hw->dsp_config_state = e1000_dsp_config_disabled; + /* Force MDI for IGP B-0 PHY */ + phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX | + IGP01E1000_PSCR_FORCE_MDI_MDIX); + hw->mdix = 1; + + } else { + hw->dsp_config_state = e1000_dsp_config_enabled; + phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX; + + switch (hw->mdix) { + case 1: + phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX; + break; + case 2: + phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX; + break; + case 0: + default: + phy_data |= IGP01E1000_PSCR_AUTO_MDIX; + break; + } } - } + if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, + phy_data))) + return ret_val; - if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + /* set auto-master slave resolution settings */ + if(hw->autoneg) { + e1000_ms_type phy_ms_setting = hw->master_slave; + + if(hw->ffe_config_state == e1000_ffe_config_active) + hw->ffe_config_state = e1000_ffe_config_enabled; + + if(hw->dsp_config_state == e1000_dsp_config_activated) + hw->dsp_config_state = e1000_dsp_config_enabled; + + /* when autonegotiation advertisment is only 1000Mbps then we + * should disable SmartSpeed and enable Auto MasterSlave + * resolution as hardware default. */ + if(hw->autoneg_advertised == ADVERTISE_1000_FULL) { + /* Disable SmartSpeed */ + if((ret_val = e1000_read_phy_reg(hw, + IGP01E1000_PHY_PORT_CONFIG, + &phy_data))) + return ret_val; + phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; + if((ret_val = e1000_write_phy_reg(hw, + IGP01E1000_PHY_PORT_CONFIG, + phy_data))) + return ret_val; + /* Set auto Master/Slave resolution process */ + if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, + &phy_data))) + return ret_val; + phy_data &= ~CR_1000T_MS_ENABLE; + if((ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, + phy_data))) + return ret_val; + } - /* Force MDI for IGP PHY */ - phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX | - IGP01E1000_PSCR_FORCE_MDI_MDIX); + if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, + &phy_data))) + return ret_val; - hw->mdix = 1; + /* load defaults for future use */ + hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ? + ((phy_data & CR_1000T_MS_VALUE) ? + e1000_ms_force_master : + e1000_ms_force_slave) : + e1000_ms_auto; + + switch (phy_ms_setting) { + case e1000_ms_force_master: + phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE); + break; + case e1000_ms_force_slave: + phy_data |= CR_1000T_MS_ENABLE; + phy_data &= ~(CR_1000T_MS_VALUE); + break; + case e1000_ms_auto: + phy_data &= ~CR_1000T_MS_ENABLE; + default: + break; + } + if((ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, + phy_data))) + return ret_val; + } + } else { + /* Enable CRS on TX. This must be set for half-duplex operation. */ + if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, + &phy_data))) + return ret_val; - if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data) < 0) { - DEBUGOUT("PHY Write Error\n"); - return -E1000_ERR_PHY; - } + phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; - } else { - /* Enable CRS on TX. This must be set for half-duplex operation. */ - if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; + /* Options: + * MDI/MDI-X = 0 (default) + * 0 - Auto for all speeds + * 1 - MDI mode + * 2 - MDI-X mode + * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) + */ + phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; - /* Options: - * MDI/MDI-X = 0 (default) - * 0 - Auto for all speeds - * 1 - MDI mode - * 2 - MDI-X mode - * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) - */ - phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; + switch (hw->mdix) { + case 1: + phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE; + break; + case 2: + phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE; + break; + case 3: + phy_data |= M88E1000_PSCR_AUTO_X_1000T; + break; + case 0: + default: + phy_data |= M88E1000_PSCR_AUTO_X_MODE; + break; + } - switch (hw->mdix) { - case 1: - phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE; - break; - case 2: - phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE; - break; - case 3: - phy_data |= M88E1000_PSCR_AUTO_X_1000T; - break; - case 0: - default: - phy_data |= M88E1000_PSCR_AUTO_X_MODE; - break; - } + /* Options: + * disable_polarity_correction = 0 (default) + * Automatic Correction for Reversed Cable Polarity + * 0 - Disabled + * 1 - Enabled + */ + phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL; + if(hw->disable_polarity_correction == 1) + phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; + if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, + phy_data))) + return ret_val; - /* Options: - * disable_polarity_correction = 0 (default) - * Automatic Correction for Reversed Cable Polarity - * 0 - Disabled - * 1 - Enabled - */ - phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL; - if(hw->disable_polarity_correction == 1) - phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; - if(e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) { - DEBUGOUT("PHY Write Error\n"); - return -E1000_ERR_PHY; - } + /* Force TX_CLK in the Extended PHY Specific Control Register + * to 25MHz clock. + */ + if((ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, + &phy_data))) + return ret_val; - /* Force TX_CLK in the Extended PHY Specific Control Register - * to 25MHz clock. - */ - if(e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - phy_data |= M88E1000_EPSCR_TX_CLK_25; + phy_data |= M88E1000_EPSCR_TX_CLK_25; - if (hw->phy_revision < M88E1011_I_REV_4) { - /* Configure Master and Slave downshift values */ - phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK | - M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK); - phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X | - M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X); - if(e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, - phy_data) < 0) { - DEBUGOUT("PHY Write Error\n"); - return -E1000_ERR_PHY; + if (hw->phy_revision < M88E1011_I_REV_4) { + /* Configure Master and Slave downshift values */ + phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK | + M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK); + phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X | + M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X); + if((ret_val = e1000_write_phy_reg(hw, + M88E1000_EXT_PHY_SPEC_CTRL, + phy_data))) + return ret_val; } - } - /* SW Reset the PHY so all changes take effect */ - ret_val = e1000_phy_reset(hw); - if(ret_val < 0) { - DEBUGOUT("Error Resetting the PHY\n"); - return ret_val; + /* SW Reset the PHY so all changes take effect */ + if((ret_val = e1000_phy_reset(hw))) { + DEBUGOUT("Error Resetting the PHY\n"); + return ret_val; + } } - } - /* Options: - * autoneg = 1 (default) - * PHY will advertise value(s) parsed from - * autoneg_advertised and fc - * autoneg = 0 - * PHY will be set to 10H, 10F, 100H, or 100F - * depending on value parsed from forced_speed_duplex. - */ + /* Options: + * autoneg = 1 (default) + * PHY will advertise value(s) parsed from + * autoneg_advertised and fc + * autoneg = 0 + * PHY will be set to 10H, 10F, 100H, or 100F + * depending on value parsed from forced_speed_duplex. + */ + + /* Is autoneg enabled? This is enabled by default or by software + * override. If so, call e1000_phy_setup_autoneg routine to parse the + * autoneg_advertised and fc options. If autoneg is NOT enabled, then + * the user should have provided a speed/duplex override. If so, then + * call e1000_phy_force_speed_duplex to parse and set this up. + */ + if(hw->autoneg) { + /* Perform some bounds checking on the hw->autoneg_advertised + * parameter. If this variable is zero, then set it to the default. + */ + hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT; - /* Is autoneg enabled? This is enabled by default or by software override. - * If so, call e1000_phy_setup_autoneg routine to parse the - * autoneg_advertised and fc options. If autoneg is NOT enabled, then the - * user should have provided a speed/duplex override. If so, then call - * e1000_phy_force_speed_duplex to parse and set this up. - */ - if(hw->autoneg) { - /* Perform some bounds checking on the hw->autoneg_advertised - * parameter. If this variable is zero, then set it to the default. - */ - hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT; + /* If autoneg_advertised is zero, we assume it was not defaulted + * by the calling code so we set to advertise full capability. + */ + if(hw->autoneg_advertised == 0) + hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT; - /* If autoneg_advertised is zero, we assume it was not defaulted - * by the calling code so we set to advertise full capability. - */ - if(hw->autoneg_advertised == 0) - hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT; + DEBUGOUT("Reconfiguring auto-neg advertisement params\n"); + if((ret_val = e1000_phy_setup_autoneg(hw))) { + DEBUGOUT("Error Setting up Auto-Negotiation\n"); + return ret_val; + } + DEBUGOUT("Restarting Auto-Neg\n"); - DEBUGOUT("Reconfiguring auto-neg advertisement params\n"); - ret_val = e1000_phy_setup_autoneg(hw); - if(ret_val < 0) { - DEBUGOUT("Error Setting up Auto-Negotiation\n"); - return ret_val; - } - DEBUGOUT("Restarting Auto-Neg\n"); + /* Restart auto-negotiation by setting the Auto Neg Enable bit and + * the Auto Neg Restart bit in the PHY control register. + */ + if((ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data))) + return ret_val; - /* Restart auto-negotiation by setting the Auto Neg Enable bit and - * the Auto Neg Restart bit in the PHY control register. - */ - if(e1000_read_phy_reg(hw, PHY_CTRL, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG); - if(e1000_write_phy_reg(hw, PHY_CTRL, phy_data) < 0) { - DEBUGOUT("PHY Write Error\n"); - return -E1000_ERR_PHY; - } + phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG); + if((ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data))) + return ret_val; - /* Does the user want to wait for Auto-Neg to complete here, or - * check at a later time (for example, callback routine). - */ - if(hw->wait_autoneg_complete) { - ret_val = e1000_wait_autoneg(hw); - if(ret_val < 0) { - DEBUGOUT("Error while waiting for autoneg to complete\n"); + /* Does the user want to wait for Auto-Neg to complete here, or + * check at a later time (for example, callback routine). + */ + if(hw->wait_autoneg_complete) { + if((ret_val = e1000_wait_autoneg(hw))) { + DEBUGOUT("Error while waiting for autoneg to complete\n"); + return ret_val; + } + } + hw->get_link_status = TRUE; + } else { + DEBUGOUT("Forcing speed and duplex\n"); + if((ret_val = e1000_phy_force_speed_duplex(hw))) { + DEBUGOUT("Error Forcing Speed and Duplex\n"); return ret_val; } } - hw->get_link_status = TRUE; - } else { - DEBUGOUT("Forcing speed and duplex\n"); - ret_val = e1000_phy_force_speed_duplex(hw); - if(ret_val < 0) { - DEBUGOUT("Error Forcing Speed and Duplex\n"); - return ret_val; - } - } + } /* !hw->phy_reset_disable */ /* Check link status. Wait up to 100 microseconds for link to become * valid. */ for(i = 0; i < 10; i++) { - if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - if(phy_data & MII_SR_LINK_STATUS) { - /* We have link, so we need to finish the config process: + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data))) + return ret_val; + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data))) + return ret_val; + + if(phy_data & MII_SR_LINK_STATUS) { + /* We have link, so we need to finish the config process: * 1) Set up the MAC to the current PHY speed/duplex * if we are on 82543. If we * are on newer silicon, we only need to configure @@ -952,25 +1180,31 @@ if(hw->mac_type >= e1000_82544) { e1000_config_collision_dist(hw); } else { - ret_val = e1000_config_mac_to_phy(hw); - if(ret_val < 0) { + if((ret_val = e1000_config_mac_to_phy(hw))) { DEBUGOUT("Error configuring MAC to PHY settings\n"); return ret_val; - } + } } - ret_val = e1000_config_fc_after_link_up(hw); - if(ret_val < 0) { + if((ret_val = e1000_config_fc_after_link_up(hw))) { DEBUGOUT("Error Configuring Flow Control\n"); return ret_val; } DEBUGOUT("Valid link established!!!\n"); - return 0; + + if(hw->phy_type == e1000_phy_igp) { + if((ret_val = e1000_config_dsp_after_link_change(hw, TRUE))) { + DEBUGOUT("Error Configuring DSP after link up\n"); + return ret_val; + } + } + DEBUGOUT("Valid link established!!!\n"); + return E1000_SUCCESS; } udelay(10); } DEBUGOUT("Unable to establish link!!!\n"); - return 0; + return E1000_SUCCESS; } /****************************************************************************** @@ -981,22 +1215,20 @@ int32_t e1000_phy_setup_autoneg(struct e1000_hw *hw) { + int32_t ret_val; uint16_t mii_autoneg_adv_reg; uint16_t mii_1000t_ctrl_reg; DEBUGFUNC("e1000_phy_setup_autoneg"); /* Read the MII Auto-Neg Advertisement Register (Address 4). */ - if(e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, + &mii_autoneg_adv_reg))) + return ret_val; /* Read the MII 1000Base-T Control Register (Address 9). */ - if(e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg))) + return ret_val; /* Need to parse both autoneg_advertised and fc and set up * the appropriate PHY registers. First we will parse for @@ -1102,18 +1334,16 @@ return -E1000_ERR_CONFIG; } - if(e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg) < 0) { - DEBUGOUT("PHY Write Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, + mii_autoneg_adv_reg))) + return ret_val; DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg); - if(e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg) < 0) { - DEBUGOUT("PHY Write Error\n"); - return -E1000_ERR_PHY; - } - return 0; + if((ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg))) + return ret_val; + + return E1000_SUCCESS; } /****************************************************************************** @@ -1149,10 +1379,8 @@ ctrl &= ~E1000_CTRL_ASDE; /* Read the MII Control Register. */ - if(e1000_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg))) + return ret_val; /* We need to disable autoneg in order to force link and duplex. */ @@ -1198,19 +1426,18 @@ E1000_WRITE_REG(hw, CTRL, ctrl); if (hw->phy_type == e1000_phy_m88) { - if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, + &phy_data))) + return ret_val; /* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI * forced whenever speed are duplex are forced. */ phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; - if(e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) { - DEBUGOUT("PHY Write Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, + phy_data))) + return ret_val; + DEBUGOUT1("M88E1000 PSCR: %x \n", phy_data); /* Need to reset the PHY or these changes will be ignored */ @@ -1219,25 +1446,22 @@ /* Clear Auto-Crossover to force MDI manually. IGP requires MDI * forced whenever speed or duplex are forced. */ - if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, + &phy_data))) + return ret_val; phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX; phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX; - if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data) < 0) { - DEBUGOUT("PHY Write Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, + phy_data))) + return ret_val; } /* Write back the modified PHY MII control register. */ - if(e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg) < 0) { - DEBUGOUT("PHY Write Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg))) + return ret_val; + udelay(1); /* The wait_autoneg_complete flag may be a little misleading here. @@ -1257,22 +1481,18 @@ /* Read the MII Status Register and wait for Auto-Neg Complete bit * to be set. */ - if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg))) + return ret_val; + + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg))) + return ret_val; + if(mii_status_reg & MII_SR_LINK_STATUS) break; msec_delay(100); } - if(i == 0) { /* We didn't get link */ - /* Reset the DSP and wait again for link. */ - - ret_val = e1000_phy_reset_dsp(hw); - if(ret_val < 0) { + if((i == 0) && (hw->phy_type == e1000_phy_m88)) { + /* We didn't get link. Reset the DSP and wait again for link. */ + if((ret_val = e1000_phy_reset_dsp(hw))) { DEBUGOUT("Error Resetting PHY DSP\n"); return ret_val; } @@ -1284,14 +1504,11 @@ /* Read the MII Status Register and wait for Auto-Neg Complete bit * to be set. */ - if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg))) + return ret_val; + + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg))) + return ret_val; } } @@ -1300,30 +1517,48 @@ * Extended PHY Specific Control Register to 25MHz clock. This value * defaults back to a 2.5MHz clock when the PHY is reset. */ - if(e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, + &phy_data))) + return ret_val; + phy_data |= M88E1000_EPSCR_TX_CLK_25; - if(e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data) < 0) { - DEBUGOUT("PHY Write Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, + phy_data))) + return ret_val; /* 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. */ - if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, + &phy_data))) + return ret_val; + phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; - if(e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) { - DEBUGOUT("PHY Write Error\n"); - return -E1000_ERR_PHY; + if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, + phy_data))) + return ret_val; + + /* Polarity reversal workaround for forced 10F/10H links. */ + if(hw->mac_type <= e1000_82544 && + (hw->forced_speed_duplex == e1000_10_full || + hw->forced_speed_duplex == e1000_10_half)) { + if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, + 0x0019))) + return ret_val; + if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, + 0x8F0F))) + return ret_val; + /* IEEE requirement is 150ms */ + msec_delay(200); + if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, + 0x0019))) + return ret_val; + if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, + 0x8F00))) + return ret_val; } } - return 0; + return E1000_SUCCESS; } /****************************************************************************** @@ -1363,6 +1598,7 @@ e1000_config_mac_to_phy(struct e1000_hw *hw) { uint32_t ctrl; + int32_t ret_val; uint16_t phy_data; DEBUGFUNC("e1000_config_mac_to_phy"); @@ -1378,10 +1614,10 @@ * registers depending on negotiated values. */ if (hw->phy_type == e1000_phy_igp) { - if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, + &phy_data))) + return ret_val; + if(phy_data & IGP01E1000_PSSR_FULL_DUPLEX) ctrl |= E1000_CTRL_FD; else ctrl &= ~E1000_CTRL_FD; @@ -1397,10 +1633,10 @@ IGP01E1000_PSSR_SPEED_100MBPS) ctrl |= E1000_CTRL_SPD_100; } else { - if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, + &phy_data))) + return ret_val; + if(phy_data & M88E1000_PSSR_DPLX) ctrl |= E1000_CTRL_FD; else ctrl &= ~E1000_CTRL_FD; @@ -1416,7 +1652,7 @@ } /* Write the configured values back to the Device Control Reg. */ E1000_WRITE_REG(hw, CTRL, ctrl); - return 0; + return E1000_SUCCESS; } /****************************************************************************** @@ -1430,7 +1666,7 @@ * by the PHY rather than the MAC. Software must also configure these * bits when link is forced on a fiber connection. *****************************************************************************/ -static int32_t +int32_t e1000_force_mac_fc(struct e1000_hw *hw) { uint32_t ctrl; @@ -1483,7 +1719,7 @@ ctrl &= (~E1000_CTRL_TFCE); E1000_WRITE_REG(hw, CTRL, ctrl); - return 0; + return E1000_SUCCESS; } /****************************************************************************** @@ -1514,9 +1750,9 @@ * configuration of the MAC to match the "fc" parameter. */ if(((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed)) || + ((hw->media_type == e1000_media_type_internal_serdes) && (hw->autoneg_failed)) || ((hw->media_type == e1000_media_type_copper) && (!hw->autoneg))) { - ret_val = e1000_force_mac_fc(hw); - if(ret_val < 0) { + if((ret_val = e1000_force_mac_fc(hw))) { DEBUGOUT("Error forcing flow control settings\n"); return ret_val; } @@ -1532,14 +1768,10 @@ * has completed. We read this twice because this reg has * some "sticky" (latched) bits. */ - if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) { - DEBUGOUT("PHY Read Error \n"); - return -E1000_ERR_PHY; - } - if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) { - DEBUGOUT("PHY Read Error \n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg))) + return ret_val; + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg))) + return ret_val; if(mii_status_reg & MII_SR_AUTONEG_COMPLETE) { /* The AutoNeg process has completed, so we now need to @@ -1548,14 +1780,12 @@ * Register (Address 5) to determine how flow control was * negotiated. */ - if(e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - if(e1000_read_phy_reg(hw, PHY_LP_ABILITY, &mii_nway_lp_ability_reg) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, + &mii_nway_adv_reg))) + return ret_val; + if((ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY, + &mii_nway_lp_ability_reg))) + return ret_val; /* Two bits in the Auto Negotiation Advertisement Register * (Address 4) and two bits in the Auto Negotiation Base @@ -1657,8 +1887,9 @@ * be asked to delay transmission of packets than asking * our link partner to pause transmission of frames. */ - else if(hw->original_fc == e1000_fc_none || - hw->original_fc == e1000_fc_tx_pause) { + else if((hw->original_fc == e1000_fc_none || + hw->original_fc == e1000_fc_tx_pause) || + hw->fc_strict_ieee) { hw->fc = e1000_fc_none; DEBUGOUT("Flow Control = NONE.\r\n"); } else { @@ -1670,7 +1901,10 @@ * negotiated to HALF DUPLEX, flow control should not be * enabled per IEEE 802.3 spec. */ - e1000_get_speed_and_duplex(hw, &speed, &duplex); + if((ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex))) { + DEBUGOUT("Error getting link speed and duplex\n"); + return ret_val; + } if(duplex == HALF_DUPLEX) hw->fc = e1000_fc_none; @@ -1678,16 +1912,15 @@ /* Now we call a subroutine to actually force the MAC * controller to use the correct flow control settings. */ - ret_val = e1000_force_mac_fc(hw); - if(ret_val < 0) { + if((ret_val = e1000_force_mac_fc(hw))) { DEBUGOUT("Error forcing flow control settings\n"); return ret_val; - } + } } else { DEBUGOUT("Copper PHY and Auto Neg has not completed.\r\n"); } } - return 0; + return E1000_SUCCESS; } /****************************************************************************** @@ -1704,19 +1937,18 @@ uint32_t ctrl; uint32_t status; uint32_t rctl; - uint32_t signal; + uint32_t signal = 0; int32_t ret_val; uint16_t phy_data; - uint16_t lp_capability; DEBUGFUNC("e1000_check_for_link"); - /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be + /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be * set when the optics detect a signal. On older adapters, it will be - * cleared when there is a signal + * cleared when there is a signal. This applies to fiber media only. */ - if(hw->mac_type > e1000_82544) signal = E1000_CTRL_SWDPIN1; - else signal = 0; + if(hw->media_type == e1000_media_type_fiber) + signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0; ctrl = E1000_READ_REG(hw, CTRL); status = E1000_READ_REG(hw, STATUS); @@ -1734,14 +1966,10 @@ * of the PHY. * Read the register twice since the link bit is sticky. */ - if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data))) + return ret_val; + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data))) + return ret_val; if(phy_data & MII_SR_LINK_STATUS) { hw->get_link_status = FALSE; @@ -1751,6 +1979,7 @@ } else { /* No link detected */ + e1000_config_dsp_after_link_change(hw, FALSE); return 0; } @@ -1759,6 +1988,9 @@ */ if(!hw->autoneg) return -E1000_ERR_CONFIG; + /* optimize the dsp settings for the igp phy */ + e1000_config_dsp_after_link_change(hw, TRUE); + /* We have a M88E1000 PHY and Auto-Neg is enabled. If we * have Si on board that is 82544 or newer, Auto * Speed Detection takes care of MAC speed/duplex @@ -1770,8 +2002,7 @@ if(hw->mac_type >= e1000_82544) e1000_config_collision_dist(hw); else { - ret_val = e1000_config_mac_to_phy(hw); - if(ret_val < 0) { + if((ret_val = e1000_config_mac_to_phy(hw))) { DEBUGOUT("Error configuring MAC to PHY settings\n"); return ret_val; } @@ -1781,33 +2012,24 @@ * need to restore the desired flow control settings because we may * have had to re-autoneg with a different link partner. */ - ret_val = e1000_config_fc_after_link_up(hw); - if(ret_val < 0) { + if((ret_val = e1000_config_fc_after_link_up(hw))) { DEBUGOUT("Error configuring flow control\n"); return ret_val; } /* At this point we know that we are on copper and we have * auto-negotiated link. These are conditions for checking the link - * parter capability register. We use the link partner capability to - * determine if TBI Compatibility needs to be turned on or off. If - * the link partner advertises any speed in addition to Gigabit, then - * we assume that they are GMII-based, and TBI compatibility is not - * needed. If no other speeds are advertised, we assume the link - * partner is TBI-based, and we turn on TBI Compatibility. - */ - if(hw->tbi_compatibility_en) { - if(e1000_read_phy_reg(hw, PHY_LP_ABILITY, &lp_capability) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - if(lp_capability & (NWAY_LPAR_10T_HD_CAPS | - NWAY_LPAR_10T_FD_CAPS | - NWAY_LPAR_100TX_HD_CAPS | - NWAY_LPAR_100TX_FD_CAPS | - NWAY_LPAR_100T4_CAPS)) { - /* If our link partner advertises anything in addition to - * gigabit, we do not need to enable TBI compatibility. + * partner capability register. We use the link speed to determine if + * TBI compatibility needs to be turned on or off. If the link is not + * at gigabit speed, then TBI compatibility is not needed. If we are + * at gigabit speed, we turn on TBI compatibility. + */ + if(hw->tbi_compatibility_en) { + uint16_t speed, duplex; + e1000_get_speed_and_duplex(hw, &speed, &duplex); + if(speed != SPEED_1000) { + /* If link speed is not set to gigabit speed, we do not need + * to enable TBI compatibility. */ if(hw->tbi_compatibility_on) { /* If we previously were in the mode, turn it off. */ @@ -1838,9 +2060,10 @@ * auto-negotiation time to complete, in case the cable was just plugged * in. The autoneg_failed flag does this. */ - else if((hw->media_type == e1000_media_type_fiber) && + else if((((hw->media_type == e1000_media_type_fiber) && + ((ctrl & E1000_CTRL_SWDPIN1) == signal)) || + (hw->media_type == e1000_media_type_internal_serdes)) && (!(status & E1000_STATUS_LU)) && - ((ctrl & E1000_CTRL_SWDPIN1) == signal) && (!(rxcw & E1000_RXCW_C))) { if(hw->autoneg_failed == 0) { hw->autoneg_failed = 1; @@ -1857,8 +2080,7 @@ E1000_WRITE_REG(hw, CTRL, ctrl); /* Configure Flow Control after forcing link up. */ - ret_val = e1000_config_fc_after_link_up(hw); - if(ret_val < 0) { + if((ret_val = e1000_config_fc_after_link_up(hw))) { DEBUGOUT("Error configuring flow control\n"); return ret_val; } @@ -1868,14 +2090,38 @@ * Device Control register in an attempt to auto-negotiate with our link * partner. */ - else if((hw->media_type == e1000_media_type_fiber) && + else if(((hw->media_type == e1000_media_type_fiber) || + (hw->media_type == e1000_media_type_internal_serdes)) && (ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\r\n"); E1000_WRITE_REG(hw, TXCW, hw->txcw); E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU)); + + hw->serdes_link_down = FALSE; + } + /* If we force link for non-auto-negotiation switch, check link status + * based on MAC synchronization for internal serdes media type. + */ + else if((hw->media_type == e1000_media_type_internal_serdes) && + !(E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) { + /* SYNCH bit and IV bit are sticky. */ + udelay(10); + if(E1000_RXCW_SYNCH & E1000_READ_REG(hw, RXCW)) { + if(!(rxcw & E1000_RXCW_IV)) { + hw->serdes_link_down = FALSE; + DEBUGOUT("SERDES: Link is up.\n"); + } + } else { + hw->serdes_link_down = TRUE; + DEBUGOUT("SERDES: Link is down.\n"); + } + } + if((hw->media_type == e1000_media_type_internal_serdes) && + (E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) { + hw->serdes_link_down = !(E1000_STATUS_LU & E1000_READ_REG(hw, STATUS)); } - return 0; + return E1000_SUCCESS; } /****************************************************************************** @@ -1885,12 +2131,14 @@ * speed - Speed of the connection * duplex - Duplex setting of the connection *****************************************************************************/ -void +int32_t e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t *speed, uint16_t *duplex) { uint32_t status; + int32_t ret_val; + uint16_t phy_data; DEBUGFUNC("e1000_get_speed_and_duplex"); @@ -1919,6 +2167,27 @@ *speed = SPEED_1000; *duplex = FULL_DUPLEX; } + + /* IGP01 PHY may advertise full duplex operation after speed downgrade even + * if it is operating at half duplex. Here we set the duplex settings to + * match the duplex in the link partner's capabilities. + */ + if(hw->phy_type == e1000_phy_igp && hw->speed_downgraded) { + if((ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data))) + return ret_val; + + if(!(phy_data & NWAY_ER_LP_NWAY_CAPS)) + *duplex = HALF_DUPLEX; + else { + if((ret_val == e1000_read_phy_reg(hw, PHY_LP_ABILITY, &phy_data))) + return ret_val; + if((*speed == SPEED_100 && !(phy_data & NWAY_LPAR_100TX_FD_CAPS)) || + (*speed == SPEED_10 && !(phy_data & NWAY_LPAR_10T_FD_CAPS))) + *duplex = HALF_DUPLEX; + } + } + + return E1000_SUCCESS; } /****************************************************************************** @@ -1929,6 +2198,7 @@ int32_t e1000_wait_autoneg(struct e1000_hw *hw) { + int32_t ret_val; uint16_t i; uint16_t phy_data; @@ -1940,20 +2210,16 @@ /* Read the MII Status Register and wait for Auto-Neg * Complete bit to be set. */ - if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data))) + return ret_val; + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data))) + return ret_val; if(phy_data & MII_SR_AUTONEG_COMPLETE) { - return 0; + return E1000_SUCCESS; } msec_delay(100); } - return 0; + return E1000_SUCCESS; } /****************************************************************************** @@ -1967,11 +2233,11 @@ uint32_t *ctrl) { /* Raise the clock input to the Management Data Clock (by setting the MDC - * bit), and then delay 2 microseconds. + * bit), and then delay 10 microseconds. */ E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC)); E1000_WRITE_FLUSH(hw); - udelay(2); + udelay(10); } /****************************************************************************** @@ -1985,11 +2251,11 @@ uint32_t *ctrl) { /* Lower the clock input to the Management Data Clock (by clearing the MDC - * bit), and then delay 2 microseconds. + * bit), and then delay 10 microseconds. */ E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC)); E1000_WRITE_FLUSH(hw); - udelay(2); + udelay(10); } /****************************************************************************** @@ -2033,7 +2299,7 @@ E1000_WRITE_REG(hw, CTRL, ctrl); E1000_WRITE_FLUSH(hw); - udelay(2); + udelay(10); e1000_raise_mdi_clk(hw, &ctrl); e1000_lower_mdi_clk(hw, &ctrl); @@ -2095,8 +2361,8 @@ } /***************************************************************************** -* Reads the value from a PHY register -* +* Reads the value from a PHY register, if the value is on a specific non zero +* page, sets the page first. * hw - Struct containing variables accessed by shared code * reg_addr - address of the PHY register to read ******************************************************************************/ @@ -2105,11 +2371,33 @@ uint32_t reg_addr, uint16_t *phy_data) { + uint32_t ret_val; + + DEBUGFUNC("e1000_read_phy_reg"); + + if(hw->phy_type == e1000_phy_igp && + (reg_addr > MAX_PHY_MULTI_PAGE_REG)) { + if((ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT, + (uint16_t)reg_addr))) + return ret_val; + } + + ret_val = e1000_read_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr, + phy_data); + + return ret_val; +} + +int32_t +e1000_read_phy_reg_ex(struct e1000_hw *hw, + uint32_t reg_addr, + uint16_t *phy_data) +{ uint32_t i; uint32_t mdic = 0; const uint32_t phy_addr = 1; - DEBUGFUNC("e1000_read_phy_reg"); + DEBUGFUNC("e1000_read_phy_reg_ex"); if(reg_addr > MAX_PHY_REG_ADDRESS) { DEBUGOUT1("PHY Address %d is out of range\n", reg_addr); @@ -2129,7 +2417,7 @@ /* Poll the ready bit to see if the MDI read completed */ for(i = 0; i < 64; i++) { - udelay(10); + udelay(50); mdic = E1000_READ_REG(hw, MDIC); if(mdic & E1000_MDIC_READY) break; } @@ -2171,7 +2459,7 @@ */ *phy_data = e1000_shift_in_mdi_bits(hw); } - return 0; + return E1000_SUCCESS; } /****************************************************************************** @@ -2186,11 +2474,33 @@ uint32_t reg_addr, uint16_t phy_data) { + uint32_t ret_val; + + DEBUGFUNC("e1000_write_phy_reg"); + + if(hw->phy_type == e1000_phy_igp && + (reg_addr > MAX_PHY_MULTI_PAGE_REG)) { + if((ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT, + (uint16_t)reg_addr))) + return ret_val; + } + + ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr, + phy_data); + + return ret_val; +} + +int32_t +e1000_write_phy_reg_ex(struct e1000_hw *hw, + uint32_t reg_addr, + uint16_t phy_data) +{ uint32_t i; uint32_t mdic = 0; const uint32_t phy_addr = 1; - DEBUGFUNC("e1000_write_phy_reg"); + DEBUGFUNC("e1000_write_phy_reg_ex"); if(reg_addr > MAX_PHY_REG_ADDRESS) { DEBUGOUT1("PHY Address %d is out of range\n", reg_addr); @@ -2210,8 +2520,8 @@ E1000_WRITE_REG(hw, MDIC, mdic); /* Poll the ready bit to see if the MDI read completed */ - for(i = 0; i < 64; i++) { - udelay(10); + for(i = 0; i < 640; i++) { + udelay(5); mdic = E1000_READ_REG(hw, MDIC); if(mdic & E1000_MDIC_READY) break; } @@ -2241,7 +2551,7 @@ e1000_shift_out_mdi_bits(hw, mdic, 32); } - return 0; + return E1000_SUCCESS; } /****************************************************************************** @@ -2252,7 +2562,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"); @@ -2285,17 +2596,10 @@ udelay(150); if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { - if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0000) < 0) { - DEBUGOUT("PHY Write Error\n"); - return; - } - /* 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); } } @@ -2310,24 +2614,26 @@ int32_t e1000_phy_reset(struct e1000_hw *hw) { + int32_t ret_val; uint16_t phy_data; DEBUGFUNC("e1000_phy_reset"); - if(e1000_read_phy_reg(hw, PHY_CTRL, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - phy_data |= MII_CR_RESET; - if(e1000_write_phy_reg(hw, PHY_CTRL, phy_data) < 0) { - DEBUGOUT("PHY Write Error\n"); - return -E1000_ERR_PHY; - } - udelay(1); - if (hw->phy_type == e1000_phy_igp) { + if(hw->mac_type != e1000_82541_rev_2) { + if((ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data))) + return ret_val; + + phy_data |= MII_CR_RESET; + if((ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data))) + return ret_val; + + udelay(1); + } else e1000_phy_hw_reset(hw); + + if(hw->phy_type == e1000_phy_igp) e1000_phy_init_script(hw); - } - return 0; + + return E1000_SUCCESS; } /****************************************************************************** @@ -2338,23 +2644,21 @@ int32_t e1000_detect_gig_phy(struct e1000_hw *hw) { + int32_t phy_init_status, ret_val; uint16_t phy_id_high, phy_id_low; boolean_t match = FALSE; - int32_t phy_init_status; DEBUGFUNC("e1000_detect_gig_phy"); /* Read the PHY ID Registers to identify which PHY is onboard. */ - if(e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high))) + return ret_val; + hw->phy_id = (uint32_t) (phy_id_high << 16); udelay(20); - if(e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low))) + return ret_val; + hw->phy_id |= (uint32_t) (phy_id_low & PHY_REVISION_MASK); hw->phy_revision = (uint32_t) phy_id_low & ~PHY_REVISION_MASK; @@ -2367,11 +2671,15 @@ break; case e1000_82540: case e1000_82545: + case e1000_82545_rev_3: case e1000_82546: + case e1000_82546_rev_3: if(hw->phy_id == M88E1011_I_PHY_ID) match = TRUE; break; case e1000_82541: + case e1000_82541_rev_2: case e1000_82547: + case e1000_82547_rev_2: if(hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE; break; default: @@ -2382,7 +2690,7 @@ if ((match) && (phy_init_status == E1000_SUCCESS)) { DEBUGOUT1("PHY ID 0x%X detected\n", hw->phy_id); - return 0; + return E1000_SUCCESS; } DEBUGOUT1("Invalid PHY ID 0x%X\n", hw->phy_id); return -E1000_ERR_PHY; @@ -2396,17 +2704,16 @@ static int32_t e1000_phy_reset_dsp(struct e1000_hw *hw) { - int32_t ret_val = -E1000_ERR_PHY; + int32_t ret_val; DEBUGFUNC("e1000_phy_reset_dsp"); do { - if(e1000_write_phy_reg(hw, 29, 0x001d) < 0) break; - if(e1000_write_phy_reg(hw, 30, 0x00c1) < 0) break; - if(e1000_write_phy_reg(hw, 30, 0x0000) < 0) break; - ret_val = 0; + if((ret_val = e1000_write_phy_reg(hw, 29, 0x001d))) break; + if((ret_val = e1000_write_phy_reg(hw, 30, 0x00c1))) break; + if((ret_val = e1000_write_phy_reg(hw, 30, 0x0000))) break; + ret_val = E1000_SUCCESS; } while(0); - if(ret_val < 0) DEBUGOUT("PHY Write Error\n"); return ret_val; } @@ -2417,8 +2724,10 @@ * phy_info - PHY information structure ******************************************************************************/ int32_t -e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info) +e1000_phy_igp_get_info(struct e1000_hw *hw, + struct e1000_phy_info *phy_info) { + int32_t ret_val; uint16_t phy_data, polarity, min_length, max_length, average; DEBUGFUNC("e1000_phy_igp_get_info"); @@ -2434,13 +2743,14 @@ phy_info->polarity_correction = e1000_polarity_reversal_enabled; /* Check polarity status */ - if(e1000_check_polarity(hw, &polarity) < 0) - return -E1000_ERR_PHY; + if((ret_val = e1000_check_polarity(hw, &polarity))) + return ret_val; phy_info->cable_polarity = polarity; - if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data) < 0) - return -E1000_ERR_PHY; + if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, + &phy_data))) + return ret_val; phy_info->mdix_mode = (phy_data & IGP01E1000_PSSR_MDIX) >> IGP01E1000_PSSR_MDIX_SHIFT; @@ -2448,8 +2758,8 @@ if((phy_data & IGP01E1000_PSSR_SPEED_MASK) == IGP01E1000_PSSR_SPEED_1000MBPS) { /* Local/Remote Receiver Information are only valid at 1000 Mbps */ - if(e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data) < 0) - return -E1000_ERR_PHY; + if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data))) + return ret_val; phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >> SR_1000T_LOCAL_RX_STATUS_SHIFT; @@ -2457,8 +2767,8 @@ SR_1000T_REMOTE_RX_STATUS_SHIFT; /* Get cable length */ - if(e1000_get_cable_length(hw, &min_length, &max_length) < 0) - return -E1000_ERR_PHY; + if((ret_val = e1000_get_cable_length(hw, &min_length, &max_length))) + return ret_val; /* transalte to old method */ average = (max_length + min_length) / 2; @@ -2485,8 +2795,10 @@ * phy_info - PHY information structure ******************************************************************************/ int32_t -e1000_phy_m88_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info) +e1000_phy_m88_get_info(struct e1000_hw *hw, + struct e1000_phy_info *phy_info) { + int32_t ret_val; uint16_t phy_data, polarity; DEBUGFUNC("e1000_phy_m88_get_info"); @@ -2495,8 +2807,8 @@ * and it stored in the hw->speed_downgraded parameter. */ phy_info->downshift = hw->speed_downgraded; - if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) - return -E1000_ERR_PHY; + if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data))) + return ret_val; phy_info->extended_10bt_distance = (phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >> @@ -2506,13 +2818,13 @@ M88E1000_PSCR_POLARITY_REVERSAL_SHIFT; /* Check polarity status */ - if(e1000_check_polarity(hw, &polarity) < 0) - return -E1000_ERR_PHY; + if((ret_val = e1000_check_polarity(hw, &polarity))) + return ret_val; phy_info->cable_polarity = polarity; - if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) - return -E1000_ERR_PHY; + if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data))) + return ret_val; phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >> M88E1000_PSSR_MDIX_SHIFT; @@ -2524,8 +2836,8 @@ phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >> M88E1000_PSSR_CABLE_LENGTH_SHIFT); - if(e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data) < 0) - return -E1000_ERR_PHY; + if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data))) + return ret_val; phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >> SR_1000T_LOCAL_RX_STATUS_SHIFT; @@ -2547,6 +2859,7 @@ e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info) { + int32_t ret_val; uint16_t phy_data; DEBUGFUNC("e1000_phy_get_info"); @@ -2565,20 +2878,18 @@ return -E1000_ERR_CONFIG; } - if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data))) + return ret_val; + + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data))) + return ret_val; + if((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) { DEBUGOUT("PHY info is only valid if link is up\n"); return -E1000_ERR_CONFIG; } - if (hw->phy_type == e1000_phy_igp) + if(hw->phy_type == e1000_phy_igp) return e1000_phy_igp_get_info(hw, phy_info); else return e1000_phy_m88_get_info(hw, phy_info); @@ -2594,7 +2905,7 @@ hw->mdix = 1; return -E1000_ERR_CONFIG; } - return 0; + return E1000_SUCCESS; } @@ -2626,7 +2937,9 @@ break; case e1000_82540: case e1000_82545: + case e1000_82545_rev_3: case e1000_82546: + case e1000_82546_rev_3: eeprom->type = e1000_eeprom_microwire; eeprom->opcode_bits = 3; eeprom->delay_usec = 50; @@ -2639,8 +2952,9 @@ } break; case e1000_82541: + case e1000_82541_rev_2: case e1000_82547: - default: + case e1000_82547_rev_2: if (eecd & E1000_EECD_TYPE) { eeprom->type = e1000_eeprom_spi; eeprom->opcode_bits = 8; @@ -2665,6 +2979,18 @@ } } break; + default: + eeprom->type = e1000_eeprom_spi; + eeprom->opcode_bits = 8; + eeprom->delay_usec = 1; + if (eecd & E1000_EECD_ADDR_BITS) { + eeprom->page_size = 32; + eeprom->address_bits = 16; + } else { + eeprom->page_size = 8; + eeprom->address_bits = 8; + } + break; } if (eeprom->type == e1000_eeprom_spi) { @@ -2673,28 +2999,28 @@ eeprom_size &= EEPROM_SIZE_MASK; switch (eeprom_size) { - case EEPROM_SIZE_16KB: - eeprom->word_size = 8192; - break; - case EEPROM_SIZE_8KB: - eeprom->word_size = 4096; - break; - case EEPROM_SIZE_4KB: - eeprom->word_size = 2048; - break; - case EEPROM_SIZE_2KB: - eeprom->word_size = 1024; - break; - case EEPROM_SIZE_1KB: - eeprom->word_size = 512; - break; - case EEPROM_SIZE_512B: - eeprom->word_size = 256; - break; - case EEPROM_SIZE_128B: - default: - eeprom->word_size = 64; - break; + case EEPROM_SIZE_16KB: + eeprom->word_size = 8192; + break; + case EEPROM_SIZE_8KB: + eeprom->word_size = 4096; + break; + case EEPROM_SIZE_4KB: + eeprom->word_size = 2048; + break; + case EEPROM_SIZE_2KB: + eeprom->word_size = 1024; + break; + case EEPROM_SIZE_1KB: + eeprom->word_size = 512; + break; + case EEPROM_SIZE_512B: + eeprom->word_size = 256; + break; + case EEPROM_SIZE_128B: + default: + eeprom->word_size = 64; + break; } } } @@ -2799,7 +3125,8 @@ * hw - Struct containing variables accessed by shared code *****************************************************************************/ static uint16_t -e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count) +e1000_shift_in_ee_bits(struct e1000_hw *hw, + uint16_t count) { uint32_t eecd; uint32_t i; @@ -3059,13 +3386,17 @@ } /* Prepare the EEPROM for reading */ - if (e1000_acquire_eeprom(hw) != E1000_SUCCESS) + if(e1000_acquire_eeprom(hw) != E1000_SUCCESS) return -E1000_ERR_EEPROM; if(eeprom->type == e1000_eeprom_spi) { + uint16_t word_in; uint8_t read_opcode = EEPROM_READ_OPCODE_SPI; - if(e1000_spi_eeprom_ready(hw)) return -E1000_ERR_EEPROM; + if(e1000_spi_eeprom_ready(hw)) { + e1000_release_eeprom(hw); + return -E1000_ERR_EEPROM; + } e1000_standby_eeprom(hw); @@ -3076,30 +3407,35 @@ /* Send the READ command (opcode + addr) */ e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits); e1000_shift_out_ee_bits(hw, (uint16_t)(offset*2), eeprom->address_bits); - } - else if(eeprom->type == e1000_eeprom_microwire) { - /* Send the READ command (opcode + addr) */ - e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE_MICROWIRE, - eeprom->opcode_bits); - e1000_shift_out_ee_bits(hw, offset, eeprom->address_bits); - } - /* Read the data. The address of the eeprom internally increments with - * each word (microwire) or byte (spi) being read, saving on the overhead - * of eeprom setup and tear-down. The address counter will roll over if - * reading beyond the size of the eeprom, thus allowing the entire memory - * to be read starting from any offset. */ - for (i = 0; i < words; i++) { - uint16_t word_in = e1000_shift_in_ee_bits(hw, 16); - if (eeprom->type == e1000_eeprom_spi) - word_in = (word_in >> 8) | (word_in << 8); - data[i] = word_in; + /* Read the data. The address of the eeprom internally increments with + * each byte (spi) being read, saving on the overhead of eeprom setup + * and tear-down. The address counter will roll over if reading beyond + * the size of the eeprom, thus allowing the entire memory to be read + * starting from any offset. */ + for (i = 0; i < words; i++) { + word_in = e1000_shift_in_ee_bits(hw, 16); + data[i] = (word_in >> 8) | (word_in << 8); + } + } else if(eeprom->type == e1000_eeprom_microwire) { + for (i = 0; i < words; i++) { + /* Send the READ command (opcode + addr) */ + e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE_MICROWIRE, + eeprom->opcode_bits); + e1000_shift_out_ee_bits(hw, (uint16_t)(offset + i), + eeprom->address_bits); + + /* Read the data. For microwire, each word requires the overhead + * of eeprom setup and tear-down. */ + data[i] = e1000_shift_in_ee_bits(hw, 16); + e1000_standby_eeprom(hw); + } } /* End this read operation */ e1000_release_eeprom(hw); - return 0; + return E1000_SUCCESS; } /****************************************************************************** @@ -3127,9 +3463,9 @@ checksum += eeprom_data; } - if(checksum == (uint16_t) EEPROM_SUM) { - return 0; - } else { + if(checksum == (uint16_t) EEPROM_SUM) + return E1000_SUCCESS; + else { DEBUGOUT("EEPROM Checksum Invalid\n"); return -E1000_ERR_EEPROM; } @@ -3163,7 +3499,7 @@ DEBUGOUT("EEPROM Write Error\n"); return -E1000_ERR_EEPROM; } - return 0; + return E1000_SUCCESS; } /****************************************************************************** @@ -3201,10 +3537,12 @@ if (e1000_acquire_eeprom(hw) != E1000_SUCCESS) return -E1000_ERR_EEPROM; - if(eeprom->type == e1000_eeprom_microwire) + if(eeprom->type == e1000_eeprom_microwire) { status = e1000_write_eeprom_microwire(hw, offset, words, data); - else + } else { status = e1000_write_eeprom_spi(hw, offset, words, data); + msec_delay(10); + } /* Done with writing */ e1000_release_eeprom(hw); @@ -3361,7 +3699,7 @@ e1000_shift_out_ee_bits(hw, 0, (uint16_t)(eeprom->address_bits - 2)); - return 0; + return E1000_SUCCESS; } /****************************************************************************** @@ -3395,7 +3733,7 @@ /* Save word 1 in lower half of part_num */ *part_num |= eeprom_data; - return 0; + return E1000_SUCCESS; } /****************************************************************************** @@ -3421,16 +3759,13 @@ hw->perm_mac_addr[i] = (uint8_t) (eeprom_data & 0x00FF); hw->perm_mac_addr[i+1] = (uint8_t) (eeprom_data >> 8); } - if((hw->mac_type == e1000_82546) && - (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) { - if(hw->perm_mac_addr[5] & 0x01) - hw->perm_mac_addr[5] &= ~(0x01); - else - hw->perm_mac_addr[5] |= 0x01; - } + if(((hw->mac_type == e1000_82546) || (hw->mac_type == e1000_82546_rev_3)) && + (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) + hw->perm_mac_addr[5] ^= 0x01; + for(i = 0; i < NODE_ADDRESS_SIZE; i++) hw->mac_addr[i] = hw->perm_mac_addr[i]; - return 0; + return E1000_SUCCESS; } /****************************************************************************** @@ -3446,22 +3781,13 @@ e1000_init_rx_addrs(struct e1000_hw *hw) { uint32_t i; - uint32_t addr_low; - uint32_t addr_high; DEBUGFUNC("e1000_init_rx_addrs"); /* Setup the receive address. */ DEBUGOUT("Programming MAC Address into RAR[0]\n"); - addr_low = (hw->mac_addr[0] | - (hw->mac_addr[1] << 8) | - (hw->mac_addr[2] << 16) | (hw->mac_addr[3] << 24)); - addr_high = (hw->mac_addr[4] | - (hw->mac_addr[5] << 8) | E1000_RAH_AV); - - E1000_WRITE_REG_ARRAY(hw, RA, 0, addr_low); - E1000_WRITE_REG_ARRAY(hw, RA, 1, addr_high); + e1000_rar_set(hw, hw->mac_addr, 0); /* Zero out the other 15 receive addresses. */ DEBUGOUT("Clearing RAR[1-15]\n"); @@ -3478,6 +3804,7 @@ * mc_addr_list - the list of new multicast addresses * mc_addr_count - number of addresses * pad - number of bytes between addresses in the list + * rar_used_count - offset where to start adding mc addresses into the RAR's * * The given list replaces any existing list. Clears the last 15 receive * address registers and the multicast table. Uses receive address registers @@ -3488,11 +3815,11 @@ e1000_mc_addr_list_update(struct e1000_hw *hw, uint8_t *mc_addr_list, uint32_t mc_addr_count, - uint32_t pad) + uint32_t pad, + uint32_t rar_used_count) { uint32_t hash_value; uint32_t i; - uint32_t rar_used_count = 1; /* RAR[0] is used for our MAC address */ DEBUGFUNC("e1000_mc_addr_list_update"); @@ -3706,7 +4033,7 @@ if(hw->mac_type < e1000_82540) { /* Nothing to do */ - return 0; + return E1000_SUCCESS; } ledctl = E1000_READ_REG(hw, LEDCTL); @@ -3757,7 +4084,7 @@ break; } } - return 0; + return E1000_SUCCESS; } /****************************************************************************** @@ -3769,48 +4096,48 @@ e1000_setup_led(struct e1000_hw *hw) { uint32_t ledctl; + int32_t ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_setup_led"); - switch(hw->device_id) { - case E1000_DEV_ID_82542: - case E1000_DEV_ID_82543GC_FIBER: - case E1000_DEV_ID_82543GC_COPPER: - case E1000_DEV_ID_82544EI_COPPER: - case E1000_DEV_ID_82544EI_FIBER: - case E1000_DEV_ID_82544GC_COPPER: - case E1000_DEV_ID_82544GC_LOM: + switch(hw->mac_type) { + case e1000_82542_rev2_0: + case e1000_82542_rev2_1: + case e1000_82543: + case e1000_82544: /* No setup necessary */ break; - case E1000_DEV_ID_82545EM_FIBER: - case E1000_DEV_ID_82546EB_FIBER: - ledctl = E1000_READ_REG(hw, LEDCTL); - /* Save current LEDCTL settings */ - hw->ledctl_default = ledctl; - /* Turn off LED0 */ - ledctl &= ~(E1000_LEDCTL_LED0_IVRT | - E1000_LEDCTL_LED0_BLINK | - E1000_LEDCTL_LED0_MODE_MASK); - ledctl |= (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED0_MODE_SHIFT); - E1000_WRITE_REG(hw, LEDCTL, ledctl); - break; - case E1000_DEV_ID_82540EP: - case E1000_DEV_ID_82540EP_LOM: - case E1000_DEV_ID_82540EP_LP: - case E1000_DEV_ID_82540EM: - case E1000_DEV_ID_82540EM_LOM: - case E1000_DEV_ID_82545EM_COPPER: - case E1000_DEV_ID_82546EB_COPPER: - case E1000_DEV_ID_82541EI: - case E1000_DEV_ID_82541EP: - case E1000_DEV_ID_82547EI: - E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1); - break; + case e1000_82541: + case e1000_82547: + case e1000_82541_rev_2: + case e1000_82547_rev_2: + /* Turn off PHY Smart Power Down (if enabled) */ + if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, + &hw->phy_spd_default))) + return ret_val; + if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, + (uint16_t)(hw->phy_spd_default & + ~IGP01E1000_GMII_SPD)))) + return ret_val; + /* Fall Through */ default: - DEBUGOUT("Invalid device ID\n"); - return -E1000_ERR_CONFIG; + if(hw->media_type == e1000_media_type_fiber) { + ledctl = E1000_READ_REG(hw, LEDCTL); + /* Save current LEDCTL settings */ + hw->ledctl_default = ledctl; + /* Turn off LED0 */ + ledctl &= ~(E1000_LEDCTL_LED0_IVRT | + E1000_LEDCTL_LED0_BLINK | + E1000_LEDCTL_LED0_MODE_MASK); + ledctl |= (E1000_LEDCTL_MODE_LED_OFF << + E1000_LEDCTL_LED0_MODE_SHIFT); + E1000_WRITE_REG(hw, LEDCTL, ledctl); + } else if(hw->media_type == e1000_media_type_copper) + E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1); + break; } - return 0; + + return E1000_SUCCESS; } /****************************************************************************** @@ -3821,38 +4148,33 @@ int32_t e1000_cleanup_led(struct e1000_hw *hw) { + int32_t ret_val = E1000_SUCCESS; + DEBUGFUNC("e1000_cleanup_led"); - switch(hw->device_id) { - case E1000_DEV_ID_82542: - case E1000_DEV_ID_82543GC_FIBER: - case E1000_DEV_ID_82543GC_COPPER: - case E1000_DEV_ID_82544EI_COPPER: - case E1000_DEV_ID_82544EI_FIBER: - case E1000_DEV_ID_82544GC_COPPER: - case E1000_DEV_ID_82544GC_LOM: + switch(hw->mac_type) { + case e1000_82542_rev2_0: + case e1000_82542_rev2_1: + case e1000_82543: + case e1000_82544: /* No cleanup necessary */ break; - case E1000_DEV_ID_82540EP: - case E1000_DEV_ID_82540EP_LOM: - case E1000_DEV_ID_82540EP_LP: - case E1000_DEV_ID_82540EM: - case E1000_DEV_ID_82540EM_LOM: - case E1000_DEV_ID_82545EM_COPPER: - case E1000_DEV_ID_82545EM_FIBER: - case E1000_DEV_ID_82546EB_COPPER: - case E1000_DEV_ID_82546EB_FIBER: - case E1000_DEV_ID_82541EI: - case E1000_DEV_ID_82541EP: - case E1000_DEV_ID_82547EI: + case e1000_82541: + case e1000_82547: + case e1000_82541_rev_2: + case e1000_82547_rev_2: + /* Turn on PHY Smart Power Down (if previously enabled) */ + if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, + hw->phy_spd_default))) + return ret_val; + /* Fall Through */ + default: /* Restore LEDCTL settings */ E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_default); break; - default: - DEBUGOUT("Invalid device ID\n"); - return -E1000_ERR_CONFIG; } - return 0; + + return E1000_SUCCESS; } /****************************************************************************** @@ -3863,49 +4185,44 @@ int32_t e1000_led_on(struct e1000_hw *hw) { - uint32_t ctrl; + uint32_t ctrl = E1000_READ_REG(hw, CTRL); DEBUGFUNC("e1000_led_on"); - switch(hw->device_id) { - case E1000_DEV_ID_82542: - case E1000_DEV_ID_82543GC_FIBER: - case E1000_DEV_ID_82543GC_COPPER: - case E1000_DEV_ID_82544EI_FIBER: - ctrl = E1000_READ_REG(hw, CTRL); + switch(hw->mac_type) { + case e1000_82542_rev2_0: + case e1000_82542_rev2_1: + case e1000_82543: /* Set SW Defineable Pin 0 to turn on the LED */ ctrl |= E1000_CTRL_SWDPIN0; ctrl |= E1000_CTRL_SWDPIO0; - E1000_WRITE_REG(hw, CTRL, ctrl); break; - case E1000_DEV_ID_82544EI_COPPER: - case E1000_DEV_ID_82544GC_COPPER: - case E1000_DEV_ID_82544GC_LOM: - case E1000_DEV_ID_82545EM_FIBER: - case E1000_DEV_ID_82546EB_FIBER: - ctrl = E1000_READ_REG(hw, CTRL); - /* Clear SW Defineable Pin 0 to turn on the LED */ - ctrl &= ~E1000_CTRL_SWDPIN0; - ctrl |= E1000_CTRL_SWDPIO0; - E1000_WRITE_REG(hw, CTRL, ctrl); - break; - case E1000_DEV_ID_82540EP: - case E1000_DEV_ID_82540EP_LOM: - case E1000_DEV_ID_82540EP_LP: - case E1000_DEV_ID_82540EM: - case E1000_DEV_ID_82540EM_LOM: - case E1000_DEV_ID_82545EM_COPPER: - case E1000_DEV_ID_82546EB_COPPER: - case E1000_DEV_ID_82541EI: - case E1000_DEV_ID_82541EP: - case E1000_DEV_ID_82547EI: - E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode2); + case e1000_82544: + if(hw->media_type == e1000_media_type_fiber) { + /* Set SW Defineable Pin 0 to turn on the LED */ + ctrl |= E1000_CTRL_SWDPIN0; + ctrl |= E1000_CTRL_SWDPIO0; + } else { + /* Clear SW Defineable Pin 0 to turn on the LED */ + ctrl &= ~E1000_CTRL_SWDPIN0; + ctrl |= E1000_CTRL_SWDPIO0; + } break; default: - DEBUGOUT("Invalid device ID\n"); - return -E1000_ERR_CONFIG; + if(hw->media_type == e1000_media_type_fiber) { + /* Clear SW Defineable Pin 0 to turn on the LED */ + ctrl &= ~E1000_CTRL_SWDPIN0; + ctrl |= E1000_CTRL_SWDPIO0; + } else if(hw->media_type == e1000_media_type_copper) { + E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode2); + return E1000_SUCCESS; + } + break; } - return 0; + + E1000_WRITE_REG(hw, CTRL, ctrl); + + return E1000_SUCCESS; } /****************************************************************************** @@ -3916,49 +4233,44 @@ int32_t e1000_led_off(struct e1000_hw *hw) { - uint32_t ctrl; + uint32_t ctrl = E1000_READ_REG(hw, CTRL); DEBUGFUNC("e1000_led_off"); - switch(hw->device_id) { - case E1000_DEV_ID_82542: - case E1000_DEV_ID_82543GC_FIBER: - case E1000_DEV_ID_82543GC_COPPER: - case E1000_DEV_ID_82544EI_FIBER: - ctrl = E1000_READ_REG(hw, CTRL); + switch(hw->mac_type) { + case e1000_82542_rev2_0: + case e1000_82542_rev2_1: + case e1000_82543: /* Clear SW Defineable Pin 0 to turn off the LED */ ctrl &= ~E1000_CTRL_SWDPIN0; ctrl |= E1000_CTRL_SWDPIO0; - E1000_WRITE_REG(hw, CTRL, ctrl); break; - case E1000_DEV_ID_82544EI_COPPER: - case E1000_DEV_ID_82544GC_COPPER: - case E1000_DEV_ID_82544GC_LOM: - case E1000_DEV_ID_82545EM_FIBER: - case E1000_DEV_ID_82546EB_FIBER: - ctrl = E1000_READ_REG(hw, CTRL); - /* Set SW Defineable Pin 0 to turn off the LED */ - ctrl |= E1000_CTRL_SWDPIN0; - ctrl |= E1000_CTRL_SWDPIO0; - E1000_WRITE_REG(hw, CTRL, ctrl); - break; - case E1000_DEV_ID_82540EP: - case E1000_DEV_ID_82540EP_LOM: - case E1000_DEV_ID_82540EP_LP: - case E1000_DEV_ID_82540EM: - case E1000_DEV_ID_82540EM_LOM: - case E1000_DEV_ID_82545EM_COPPER: - case E1000_DEV_ID_82546EB_COPPER: - case E1000_DEV_ID_82541EI: - case E1000_DEV_ID_82541EP: - case E1000_DEV_ID_82547EI: - E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1); + case e1000_82544: + if(hw->media_type == e1000_media_type_fiber) { + /* Clear SW Defineable Pin 0 to turn off the LED */ + ctrl &= ~E1000_CTRL_SWDPIN0; + ctrl |= E1000_CTRL_SWDPIO0; + } else { + /* Set SW Defineable Pin 0 to turn off the LED */ + ctrl |= E1000_CTRL_SWDPIN0; + ctrl |= E1000_CTRL_SWDPIO0; + } break; default: - DEBUGOUT("Invalid device ID\n"); - return -E1000_ERR_CONFIG; + if(hw->media_type == e1000_media_type_fiber) { + /* Set SW Defineable Pin 0 to turn off the LED */ + ctrl |= E1000_CTRL_SWDPIN0; + ctrl |= E1000_CTRL_SWDPIO0; + } else if(hw->media_type == e1000_media_type_copper) { + E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1); + return E1000_SUCCESS; + } + break; } - return 0; + + E1000_WRITE_REG(hw, CTRL, ctrl); + + return E1000_SUCCESS; } /****************************************************************************** @@ -4081,8 +4393,7 @@ DEBUGFUNC("e1000_update_adaptive"); if(hw->adaptive_ifs) { - if((hw->collision_delta * hw->ifs_ratio) > - hw->tx_packet_delta) { + if((hw->collision_delta * hw->ifs_ratio) > hw->tx_packet_delta) { if(hw->tx_packet_delta > MIN_NUM_XMITS) { hw->in_ifs_mode = TRUE; if(hw->current_ifs_val < hw->ifs_max_val) { @@ -4094,8 +4405,7 @@ } } } else { - if((hw->in_ifs_mode == TRUE) && - (hw->tx_packet_delta <= MIN_NUM_XMITS)) { + if(hw->in_ifs_mode && (hw->tx_packet_delta <= MIN_NUM_XMITS)) { hw->current_ifs_val = 0; hw->in_ifs_mode = FALSE; E1000_WRITE_REG(hw, AIT, 0); @@ -4206,7 +4516,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 { @@ -4239,8 +4553,8 @@ e1000_read_reg_io(struct e1000_hw *hw, uint32_t offset) { - uint32_t io_addr = hw->io_base; - uint32_t io_data = hw->io_base + 4; + unsigned long io_addr = hw->io_base; + unsigned long io_data = hw->io_base + 4; e1000_io_write(hw, io_addr, offset); return e1000_io_read(hw, io_data); @@ -4259,8 +4573,8 @@ uint32_t offset, uint32_t value) { - uint32_t io_addr = hw->io_base; - uint32_t io_data = hw->io_base + 4; + unsigned long io_addr = hw->io_base; + unsigned long io_data = hw->io_base + 4; e1000_io_write(hw, io_addr, offset); e1000_io_write(hw, io_data, value); @@ -4274,7 +4588,8 @@ * min_length - The estimated minimum length * max_length - The estimated maximum length * - * returns: E1000_SUCCESS / -E1000_ERR_XXX + * returns: - E1000_ERR_XXX + * E1000_SUCCESS * * This function always returns a ranged length (minimum & maximum). * So for M88 phy's, this function interprets the one value returned from the @@ -4282,9 +4597,11 @@ * For IGP phy's, the function calculates the range by the AGC registers. *****************************************************************************/ int32_t -e1000_get_cable_length(struct e1000_hw *hw, uint16_t *min_length, +e1000_get_cable_length(struct e1000_hw *hw, + uint16_t *min_length, uint16_t *max_length) { + int32_t ret_val; uint16_t agc_value = 0; uint16_t cur_agc, min_agc = IGP01E1000_AGC_LENGTH_TABLE_SIZE; uint16_t i, phy_data; @@ -4295,8 +4612,9 @@ /* Use old method for Phy older than IGP */ if(hw->phy_type == e1000_phy_m88) { - if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) - return -E1000_ERR_PHY; + if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, + &phy_data))) + return ret_val; /* Convert the enum value to ranged values */ switch((phy_data & M88E1000_PSSR_CABLE_LENGTH) >> @@ -4326,19 +4644,16 @@ break; } } else if(hw->phy_type == e1000_phy_igp) { /* For IGP PHY */ - uint16_t agc_reg_array[IGP01E1000_PHY_AGC_NUM] = {IGP01E1000_PHY_AGC_A, + uint16_t agc_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = + {IGP01E1000_PHY_AGC_A, IGP01E1000_PHY_AGC_B, IGP01E1000_PHY_AGC_C, IGP01E1000_PHY_AGC_D}; /* Read the AGC registers for all channels */ - for(i = 0; i < IGP01E1000_PHY_AGC_NUM; i++) { - if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, - agc_reg_array[i]) != E1000_SUCCESS) - return -E1000_ERR_PHY; - if(e1000_read_phy_reg(hw, agc_reg_array[i] & - IGP01E1000_PHY_PAGE_SELECT, &phy_data) != - E1000_SUCCESS) - return -E1000_ERR_PHY; + for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) { + + if((ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data))) + return ret_val; cur_agc = phy_data >> IGP01E1000_AGC_LENGTH_SHIFT; @@ -4354,20 +4669,15 @@ min_agc = cur_agc; } - /* Return to page 0 */ - if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0) != - E1000_SUCCESS) - return -E1000_ERR_PHY; - /* Remove the minimal AGC result for length < 50m */ - if(agc_value < IGP01E1000_PHY_AGC_NUM * e1000_igp_cable_length_50) { + if(agc_value < IGP01E1000_PHY_CHANNEL_NUM * e1000_igp_cable_length_50) { agc_value -= min_agc; /* Get the average length of the remaining 3 channels */ - agc_value /= (IGP01E1000_PHY_AGC_NUM - 1); + agc_value /= (IGP01E1000_PHY_CHANNEL_NUM - 1); } else { /* Get the average length of all the 4 channels. */ - agc_value /= IGP01E1000_PHY_AGC_NUM; + agc_value /= IGP01E1000_PHY_CHANNEL_NUM; } /* Set the range of the calculated length. */ @@ -4389,7 +4699,8 @@ * polarity - output parameter : 0 - Polarity is not reversed * 1 - Polarity is reversed. * - * returns: E1000_SUCCESS / -E1000_ERR_XXX + * returns: - E1000_ERR_XXX + * E1000_SUCCESS * * For phy's older then IGP, this function simply reads the polarity bit in the * Phy Status register. For IGP phy's, this bit is valid only if link speed is @@ -4398,22 +4709,26 @@ * IGP01E1000_PHY_PCS_INIT_REG. *****************************************************************************/ int32_t -e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity) +e1000_check_polarity(struct e1000_hw *hw, + uint16_t *polarity) { + int32_t ret_val; uint16_t phy_data; DEBUGFUNC("e1000_check_polarity"); if(hw->phy_type == e1000_phy_m88) { /* return the Polarity bit in the Status register. */ - if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) - return -E1000_ERR_PHY; + if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, + &phy_data))) + return ret_val; *polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >> M88E1000_PSSR_REV_POLARITY_SHIFT; } else if(hw->phy_type == e1000_phy_igp) { /* Read the Status register to check the speed */ - if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data) < 0) - return -E1000_ERR_PHY; + if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, + &phy_data))) + return ret_val; /* If speed is 1000 Mbps, must read the IGP01E1000_PHY_PCS_INIT_REG to * find the polarity status */ @@ -4421,18 +4736,9 @@ IGP01E1000_PSSR_SPEED_1000MBPS) { /* Read the GIG initialization PCS register (0x00B4) */ - if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, - IGP01E1000_PHY_PCS_INIT_REG) < 0) - return -E1000_ERR_PHY; - - if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG & - IGP01E1000_PHY_PAGE_SELECT, &phy_data) < 0) - return -E1000_ERR_PHY; - - /* Return to page 0 */ - if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0) != - E1000_SUCCESS) - return -E1000_ERR_PHY; + if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG, + &phy_data))) + return ret_val; /* Check the polarity bits */ *polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ? 1 : 0; @@ -4452,7 +4758,8 @@ * downshift - output parameter : 0 - No Downshift ocured. * 1 - Downshift ocured. * - * returns: E1000_SUCCESS / -E1000_ERR_XXX + * returns: - E1000_ERR_XXX + * E1000_SUCCESS * * For phy's older then IGP, this function reads the Downshift bit in the Phy * Specific Status register. For IGP phy's, it reads the Downgrade bit in the @@ -4462,25 +4769,287 @@ int32_t e1000_check_downshift(struct e1000_hw *hw) { + int32_t ret_val; uint16_t phy_data; DEBUGFUNC("e1000_check_downshift"); if(hw->phy_type == e1000_phy_igp) { - if(e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH, + &phy_data))) + return ret_val; + hw->speed_downgraded = (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0; } else if(hw->phy_type == e1000_phy_m88) { - if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } + if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, + &phy_data))) + return ret_val; + hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >> - M88E1000_PSSR_DOWNSHIFT_SHIFT; + M88E1000_PSSR_DOWNSHIFT_SHIFT; + } + return E1000_SUCCESS; +} + +/***************************************************************************** + * + * 82541_rev_2 & 82547_rev_2 have the capability to configure the DSP when a + * gigabit link is achieved to improve link quality. + * + * hw: Struct containing variables accessed by shared code + * + * returns: - E1000_ERR_PHY if fail to read/write the PHY + * E1000_SUCCESS at any other case. + * + ****************************************************************************/ + +int32_t +e1000_config_dsp_after_link_change(struct e1000_hw *hw, + boolean_t link_up) +{ + int32_t ret_val; + uint16_t phy_data, speed, duplex, i; + uint16_t dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = + {IGP01E1000_PHY_AGC_PARAM_A, + IGP01E1000_PHY_AGC_PARAM_B, + IGP01E1000_PHY_AGC_PARAM_C, + IGP01E1000_PHY_AGC_PARAM_D}; + uint16_t min_length, max_length; + + DEBUGFUNC("e1000_config_dsp_after_link_change"); + + if(hw->phy_type != e1000_phy_igp) + return E1000_SUCCESS; + + if(link_up) { + if((ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex))) { + DEBUGOUT("Error getting link speed and duplex\n"); + return ret_val; + } + + if(speed == SPEED_1000) { + + e1000_get_cable_length(hw, &min_length, &max_length); + + if((hw->dsp_config_state == e1000_dsp_config_enabled) && + min_length >= e1000_igp_cable_length_50) { + + for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) { + if((ret_val = e1000_read_phy_reg(hw, dsp_reg_array[i], + &phy_data))) + return ret_val; + + phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX; + + if((ret_val = e1000_write_phy_reg(hw, dsp_reg_array[i], + phy_data))) + return ret_val; + } + hw->dsp_config_state = e1000_dsp_config_activated; + } + + if((hw->ffe_config_state == e1000_ffe_config_enabled) && + (min_length < e1000_igp_cable_length_50)) { + + uint16_t ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_20; + uint32_t idle_errs = 0; + + /* clear previous idle error counts */ + if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, + &phy_data))) + return ret_val; + + for(i = 0; i < ffe_idle_err_timeout; i++) { + udelay(1000); + if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, + &phy_data))) + return ret_val; + + idle_errs += (phy_data & SR_1000T_IDLE_ERROR_CNT); + if(idle_errs > SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT) { + hw->ffe_config_state = e1000_ffe_config_active; + + if((ret_val = e1000_write_phy_reg(hw, + IGP01E1000_PHY_DSP_FFE, + IGP01E1000_PHY_DSP_FFE_CM_CP))) + return ret_val; + break; + } + + if(idle_errs) + ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_100; + } + } + } + } else { + if(hw->dsp_config_state == e1000_dsp_config_activated) { + if((ret_val = e1000_write_phy_reg(hw, 0x0000, + IGP01E1000_IEEE_FORCE_GIGA))) + return ret_val; + for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) { + if((ret_val = e1000_read_phy_reg(hw, dsp_reg_array[i], + &phy_data))) + return ret_val; + + phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX; + phy_data |= IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS; + + if((ret_val = e1000_write_phy_reg(hw,dsp_reg_array[i], + phy_data))) + return ret_val; + } + + if((ret_val = e1000_write_phy_reg(hw, 0x0000, + IGP01E1000_IEEE_RESTART_AUTONEG))) + return ret_val; + + hw->dsp_config_state = e1000_dsp_config_enabled; + } + + if(hw->ffe_config_state == e1000_ffe_config_active) { + if((ret_val = e1000_write_phy_reg(hw, 0x0000, + IGP01E1000_IEEE_FORCE_GIGA))) + return ret_val; + if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_DSP_FFE, + IGP01E1000_PHY_DSP_FFE_DEFAULT))) + return ret_val; + + if((ret_val = e1000_write_phy_reg(hw, 0x0000, + IGP01E1000_IEEE_RESTART_AUTONEG))) + return ret_val; + hw->ffe_config_state = e1000_ffe_config_enabled; + } + } + return E1000_SUCCESS; +} + +/***************************************************************************** + * + * This function sets the lplu state according to the active flag. When + * activating lplu this function also disables smart speed and vise versa. + * lplu will not be activated unless the device autonegotiation advertisment + * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes. + * hw: Struct containing variables accessed by shared code + * active - true to enable lplu false to disable lplu. + * + * returns: - E1000_ERR_PHY if fail to read/write the PHY + * E1000_SUCCESS at any other case. + * + ****************************************************************************/ + +int32_t +e1000_set_d3_lplu_state(struct e1000_hw *hw, + boolean_t active) +{ + int32_t ret_val; + uint16_t phy_data; + DEBUGFUNC("e1000_set_d3_lplu_state"); + + if(!((hw->mac_type == e1000_82541_rev_2) || + (hw->mac_type == e1000_82547_rev_2))) + return E1000_SUCCESS; + + /* During driver activity LPLU should not be used or it will attain link + * from the lowest speeds starting from 10Mbps. The capability is used for + * Dx transitions and states */ + if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data))) + return ret_val; + + if(!active) { + phy_data &= ~IGP01E1000_GMII_FLEX_SPD; + if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data))) + return ret_val; + + /* LPLU and SmartSpeed are mutually exclusive. LPLU is used during + * Dx states where the power conservation is most important. During + * driver activity we should enable SmartSpeed, so performance is + * maintained. */ + if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, + &phy_data))) + return ret_val; + + phy_data |= IGP01E1000_PSCFR_SMART_SPEED; + if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, + phy_data))) + return ret_val; + + } else if((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT) || + (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL ) || + (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) { + + phy_data |= IGP01E1000_GMII_FLEX_SPD; + if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data))) + return ret_val; + + /* When LPLU is enabled we should disable SmartSpeed */ + if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, + &phy_data))) + return ret_val; + + phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; + if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, + phy_data))) + return ret_val; + + } + return E1000_SUCCESS; +} + +/****************************************************************************** + * Change VCO speed register to improve Bit Error Rate performance of SERDES. + * + * hw - Struct containing variables accessed by shared code + *****************************************************************************/ +static int32_t +e1000_set_vco_speed(struct e1000_hw *hw) +{ + int32_t ret_val; + uint16_t default_page = 0; + uint16_t phy_data; + + DEBUGFUNC("e1000_set_vco_speed"); + + switch(hw->mac_type) { + case e1000_82545_rev_3: + case e1000_82546_rev_3: + break; + default: + return E1000_SUCCESS; } + + /* Set PHY register 30, page 5, bit 8 to 0 */ + + if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, + &default_page))) + return ret_val; + + if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005))) + return ret_val; + + if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data))) + return ret_val; + + phy_data &= ~M88E1000_PHY_VCO_REG_BIT8; + if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data))) + return ret_val; + + /* Set PHY register 30, page 4, bit 11 to 1 */ + + if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004))) + return ret_val; + + if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data))) + return ret_val; + + phy_data |= M88E1000_PHY_VCO_REG_BIT11; + if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data))) + return ret_val; + + if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, + default_page))) + return ret_val; + return E1000_SUCCESS; } Index: drivers/net/e1000/e1000_hw.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/e1000/e1000_hw.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/e1000/e1000_hw.h 22 Jul 2004 19:49:43 -0000 1.1 +++ drivers/net/e1000/e1000_hw.h 4 Aug 2004 01:29:14 -0000 1.2 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 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 @@ -33,9 +33,9 @@ #ifndef _E1000_HW_H_ #define _E1000_HW_H_ - #include "e1000_osdep.h" + /* Forward declarations of structures used by the shared code */ struct e1000_hw; struct e1000_hw_stats; @@ -50,9 +50,13 @@ e1000_82544, e1000_82540, e1000_82545, + e1000_82545_rev_3, e1000_82546, + e1000_82546_rev_3, e1000_82541, + e1000_82541_rev_2, e1000_82547, + e1000_82547_rev_2, e1000_num_macs } e1000_mac_type; @@ -67,6 +71,7 @@ typedef enum { e1000_media_type_copper = 0, e1000_media_type_fiber = 1, + e1000_media_type_internal_serdes = 2, e1000_num_media_types } e1000_media_type; @@ -90,7 +95,8 @@ typedef enum { e1000_bus_type_unknown = 0, e1000_bus_type_pci, - e1000_bus_type_pcix + e1000_bus_type_pcix, + e1000_bus_type_reserved } e1000_bus_type; /* PCI bus speeds */ @@ -99,6 +105,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; @@ -107,7 +114,8 @@ typedef enum { e1000_bus_width_unknown = 0, e1000_bus_width_32, - e1000_bus_width_64 + e1000_bus_width_64, + e1000_bus_width_reserved } e1000_bus_width; /* PHY status info structure and supporting enums */ @@ -185,6 +193,26 @@ e1000_phy_undefined = 0xFF } e1000_phy_type; +typedef enum { + e1000_ms_hw_default = 0, + e1000_ms_force_master, + e1000_ms_force_slave, + e1000_ms_auto +} e1000_ms_type; + +typedef enum { + e1000_ffe_config_enabled = 0, + e1000_ffe_config_active, + e1000_ffe_config_blocked +} e1000_ffe_config; + +typedef enum { + e1000_dsp_config_disabled = 0, + e1000_dsp_config_enabled, + e1000_dsp_config_activated, + e1000_dsp_config_undefined = 0xFF +} e1000_dsp_config; + struct e1000_phy_info { e1000_cable_length cable_length; e1000_10bt_ext_dist_enable extended_10bt_distance; @@ -223,9 +251,10 @@ /* Function prototypes */ /* Initialization */ -void e1000_reset_hw(struct e1000_hw *hw); +int32_t e1000_reset_hw(struct e1000_hw *hw); int32_t e1000_init_hw(struct e1000_hw *hw); int32_t e1000_set_mac_type(struct e1000_hw *hw); +void e1000_set_media_type(struct e1000_hw *hw); /* Link Configuration */ int32_t e1000_setup_link(struct e1000_hw *hw); @@ -233,8 +262,9 @@ void e1000_config_collision_dist(struct e1000_hw *hw); int32_t e1000_config_fc_after_link_up(struct e1000_hw *hw); int32_t e1000_check_for_link(struct e1000_hw *hw); -void e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, uint16_t * duplex); +int32_t e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, uint16_t * duplex); int32_t e1000_wait_autoneg(struct e1000_hw *hw); +int32_t e1000_force_mac_fc(struct e1000_hw *hw); /* PHY */ int32_t e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *phy_data); @@ -261,7 +291,7 @@ /* Filters (multicast, vlan, receive) */ void e1000_init_rx_addrs(struct e1000_hw *hw); -void e1000_mc_addr_list_update(struct e1000_hw *hw, uint8_t * mc_addr_list, uint32_t mc_addr_count, uint32_t pad); +void e1000_mc_addr_list_update(struct e1000_hw *hw, uint8_t * mc_addr_list, uint32_t mc_addr_count, uint32_t pad, uint32_t rar_used_count); uint32_t e1000_hash_mc_addr(struct e1000_hw *hw, uint8_t * mc_addr); void e1000_mta_set(struct e1000_hw *hw, uint32_t hash_value); void e1000_rar_set(struct e1000_hw *hw, uint8_t * mc_addr, uint32_t rar_index); @@ -287,10 +317,12 @@ void e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value); void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value); /* Port I/O is only supported on 82544 and newer */ -uint32_t e1000_io_read(struct e1000_hw *hw, uint32_t port); +uint32_t e1000_io_read(struct e1000_hw *hw, unsigned long port); uint32_t e1000_read_reg_io(struct e1000_hw *hw, uint32_t offset); -void e1000_io_write(struct e1000_hw *hw, uint32_t port, uint32_t value); +void e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value); void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value); +int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw, boolean_t link_up); +int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active); #define E1000_READ_REG_IO(a, reg) \ e1000_read_reg_io((a), E1000_##reg) @@ -312,12 +344,22 @@ #define E1000_DEV_ID_82540EP_LP 0x101E #define E1000_DEV_ID_82545EM_COPPER 0x100F #define E1000_DEV_ID_82545EM_FIBER 0x1011 +#define E1000_DEV_ID_82545GM_COPPER 0x1026 +#define E1000_DEV_ID_82545GM_FIBER 0x1027 +#define E1000_DEV_ID_82545GM_SERDES 0x1028 #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_82541EI_MOBILE 0x1018 +#define E1000_DEV_ID_82541ER 0x1078 +#define E1000_DEV_ID_82547GI 0x1075 +#define E1000_DEV_ID_82541GI 0x1076 +#define E1000_DEV_ID_82541GI_MOBILE 0x1077 +#define E1000_DEV_ID_82546GB_COPPER 0x1079 +#define E1000_DEV_ID_82546GB_FIBER 0x107A +#define E1000_DEV_ID_82546GB_SERDES 0x107B #define E1000_DEV_ID_82547EI 0x1019 -#define NUM_DEV_IDS 19 #define NODE_ADDRESS_SIZE 6 #define ETH_LENGTH_OF_ADDRESS 6 @@ -383,7 +425,7 @@ E1000_IMS_RXSEQ | \ E1000_IMS_LSC) -/* The number of high/low register pairs in the RAR. The RAR (Receive Address +/* Number of high/low register pairs in the RAR. The RAR (Receive Address * Registers) holds the directed and multicast addresses that we monitor. We * reserve one of these spots for our directed address, allowing us room for * E1000_RAR_ENTRIES - 1 multicast addresses. @@ -537,7 +579,7 @@ volatile uint32_t high; /* receive address high */ }; -/* The number of entries in the Multicast Table Array (MTA). */ +/* Number of entries in the Multicast Table Array (MTA). */ #define E1000_NUM_MTA_REGISTERS 128 /* IPv4 Address Table Entry */ @@ -597,11 +639,12 @@ * A - register array */ #define E1000_CTRL 0x00000 /* Device Control - RW */ +#define E1000_CTRL_DUP 0x00004 /* Device Control Duplicate (Shadow) - RW */ #define E1000_STATUS 0x00008 /* Device Status - RO */ #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 +773,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 @@ -931,7 +975,10 @@ e1000_bus_width bus_width; e1000_bus_type bus_type; struct e1000_eeprom_info eeprom; - uint32_t io_base; + e1000_ms_type master_slave; + e1000_ms_type original_master_slave; + e1000_ffe_config ffe_config_state; + unsigned long io_base; uint32_t phy_id; uint32_t phy_revision; uint32_t phy_addr; @@ -947,6 +994,7 @@ uint32_t ledctl_default; uint32_t ledctl_mode1; uint32_t ledctl_mode2; + uint16_t phy_spd_default; uint16_t autoneg_advertised; uint16_t pci_cmd_word; uint16_t fc_high_water; @@ -971,10 +1019,14 @@ uint8_t perm_mac_addr[NODE_ADDRESS_SIZE]; boolean_t disable_polarity_correction; boolean_t speed_downgraded; + e1000_dsp_config dsp_config_state; boolean_t get_link_status; + boolean_t serdes_link_down; boolean_t tbi_compatibility_en; boolean_t tbi_compatibility_on; + boolean_t phy_reset_disable; boolean_t fc_send_xon; + boolean_t fc_strict_ieee; boolean_t report_tx_early; boolean_t adaptive_ifs; boolean_t ifs_params_forced; @@ -1056,7 +1108,7 @@ #define E1000_EECD_PRES 0x00000100 /* EEPROM Present */ #define E1000_EECD_SIZE 0x00000200 /* EEPROM Size (0=64 word 1=256 word) */ #define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on type - * (0-small, 1-large) */ + * (0-small, 1-large) */ #define E1000_EECD_TYPE 0x00002000 /* EEPROM Type (1-SPI, 0-Microwire) */ #ifndef E1000_EEPROM_GRANT_ATTEMPTS #define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */ @@ -1118,22 +1170,22 @@ #define E1000_MDIC_ERROR 0x40000000 /* LED Control */ -#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F -#define E1000_LEDCTL_LED0_MODE_SHIFT 0 -#define E1000_LEDCTL_LED0_IVRT 0x00000040 -#define E1000_LEDCTL_LED0_BLINK 0x00000080 -#define E1000_LEDCTL_LED1_MODE_MASK 0x00000F00 -#define E1000_LEDCTL_LED1_MODE_SHIFT 8 -#define E1000_LEDCTL_LED1_IVRT 0x00004000 -#define E1000_LEDCTL_LED1_BLINK 0x00008000 -#define E1000_LEDCTL_LED2_MODE_MASK 0x000F0000 -#define E1000_LEDCTL_LED2_MODE_SHIFT 16 -#define E1000_LEDCTL_LED2_IVRT 0x00400000 -#define E1000_LEDCTL_LED2_BLINK 0x00800000 -#define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000 -#define E1000_LEDCTL_LED3_MODE_SHIFT 24 -#define E1000_LEDCTL_LED3_IVRT 0x40000000 -#define E1000_LEDCTL_LED3_BLINK 0x80000000 +#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F +#define E1000_LEDCTL_LED0_MODE_SHIFT 0 +#define E1000_LEDCTL_LED0_IVRT 0x00000040 +#define E1000_LEDCTL_LED0_BLINK 0x00000080 +#define E1000_LEDCTL_LED1_MODE_MASK 0x00000F00 +#define E1000_LEDCTL_LED1_MODE_SHIFT 8 +#define E1000_LEDCTL_LED1_IVRT 0x00004000 +#define E1000_LEDCTL_LED1_BLINK 0x00008000 +#define E1000_LEDCTL_LED2_MODE_MASK 0x000F0000 +#define E1000_LEDCTL_LED2_MODE_SHIFT 16 +#define E1000_LEDCTL_LED2_IVRT 0x00400000 +#define E1000_LEDCTL_LED2_BLINK 0x00800000 +#define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000 +#define E1000_LEDCTL_LED3_MODE_SHIFT 24 +#define E1000_LEDCTL_LED3_IVRT 0x40000000 +#define E1000_LEDCTL_LED3_BLINK 0x80000000 #define E1000_LEDCTL_MODE_LINK_10_1000 0x0 #define E1000_LEDCTL_MODE_LINK_100_1000 0x1 @@ -1156,109 +1208,110 @@ #define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */ /* Interrupt Cause Read */ -#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */ -#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */ -#define E1000_ICR_LSC 0x00000004 /* Link Status Change */ -#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */ -#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */ -#define E1000_ICR_RXO 0x00000040 /* rx overrun */ -#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */ -#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */ -#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */ -#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */ -#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */ -#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */ -#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */ -#define E1000_ICR_TXD_LOW 0x00008000 -#define E1000_ICR_SRPD 0x00010000 +#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */ +#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */ +#define E1000_ICR_LSC 0x00000004 /* Link Status Change */ +#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */ +#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */ +#define E1000_ICR_RXO 0x00000040 /* rx overrun */ +#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */ +#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */ +#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */ +#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */ +#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */ +#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */ +#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */ +#define E1000_ICR_TXD_LOW 0x00008000 +#define E1000_ICR_SRPD 0x00010000 /* Interrupt Cause Set */ -#define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ -#define E1000_ICS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ -#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */ -#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ -#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ -#define E1000_ICS_RXO E1000_ICR_RXO /* rx overrun */ -#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* rx timer intr */ -#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */ -#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ -#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ -#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ -#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ -#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ -#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW -#define E1000_ICS_SRPD E1000_ICR_SRPD +#define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ +#define E1000_ICS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ +#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */ +#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ +#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ +#define E1000_ICS_RXO E1000_ICR_RXO /* rx overrun */ +#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* rx timer intr */ +#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */ +#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ +#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ +#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ +#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ +#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ +#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW +#define E1000_ICS_SRPD E1000_ICR_SRPD /* Interrupt Mask Set */ -#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ -#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ -#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */ -#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ -#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ -#define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */ -#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */ -#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */ -#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ -#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ -#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ -#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ -#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ -#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW -#define E1000_IMS_SRPD E1000_ICR_SRPD +#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ +#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ +#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */ +#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ +#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ +#define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */ +#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */ +#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */ +#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ +#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ +#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ +#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ +#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ +#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW +#define E1000_IMS_SRPD E1000_ICR_SRPD /* Interrupt Mask Clear */ -#define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written back */ -#define E1000_IMC_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ -#define E1000_IMC_LSC E1000_ICR_LSC /* Link Status Change */ -#define E1000_IMC_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ -#define E1000_IMC_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ -#define E1000_IMC_RXO E1000_ICR_RXO /* rx overrun */ -#define E1000_IMC_RXT0 E1000_ICR_RXT0 /* rx timer intr */ -#define E1000_IMC_MDAC E1000_ICR_MDAC /* MDIO access complete */ -#define E1000_IMC_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ -#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ -#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ -#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ -#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ -#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW -#define E1000_IMC_SRPD E1000_ICR_SRPD +#define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written back */ +#define E1000_IMC_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ +#define E1000_IMC_LSC E1000_ICR_LSC /* Link Status Change */ +#define E1000_IMC_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ +#define E1000_IMC_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ +#define E1000_IMC_RXO E1000_ICR_RXO /* rx overrun */ +#define E1000_IMC_RXT0 E1000_ICR_RXT0 /* rx timer intr */ +#define E1000_IMC_MDAC E1000_ICR_MDAC /* MDIO access complete */ +#define E1000_IMC_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ +#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ +#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ +#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ +#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ +#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW +#define E1000_IMC_SRPD E1000_ICR_SRPD /* Receive Control */ -#define E1000_RCTL_RST 0x00000001 /* Software reset */ -#define E1000_RCTL_EN 0x00000002 /* enable */ -#define E1000_RCTL_SBP 0x00000004 /* store bad packet */ -#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */ -#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */ -#define E1000_RCTL_LPE 0x00000020 /* long packet enable */ -#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */ -#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */ -#define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */ -#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */ -#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */ -#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */ -#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */ -#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */ -#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */ -#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */ -#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 13:2 */ -#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */ -#define E1000_RCTL_MDR 0x00004000 /* multicast desc ring 0 */ -#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */ +#define E1000_RCTL_RST 0x00000001 /* Software reset */ +#define E1000_RCTL_EN 0x00000002 /* enable */ +#define E1000_RCTL_SBP 0x00000004 /* store bad packet */ +#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */ +#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */ +#define E1000_RCTL_LPE 0x00000020 /* long packet enable */ +#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */ +#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */ +#define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */ +#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */ +#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */ +#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */ +#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */ +#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */ +#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */ +#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */ +#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 13:2 */ +#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */ +#define E1000_RCTL_MDR 0x00004000 /* multicast desc ring 0 */ +#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */ /* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */ -#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */ -#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */ -#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */ -#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */ +#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */ +#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */ +#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */ +#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */ /* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */ -#define E1000_RCTL_SZ_16384 0x00010000 /* rx buffer size 16384 */ -#define E1000_RCTL_SZ_8192 0x00020000 /* rx buffer size 8192 */ -#define E1000_RCTL_SZ_4096 0x00030000 /* rx buffer size 4096 */ -#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */ -#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */ -#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */ -#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */ -#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */ -#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */ +#define E1000_RCTL_SZ_16384 0x00010000 /* rx buffer size 16384 */ +#define E1000_RCTL_SZ_8192 0x00020000 /* rx buffer size 8192 */ +#define E1000_RCTL_SZ_4096 0x00030000 /* rx buffer size 4096 */ +#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */ +#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */ +#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */ +#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */ +#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */ +#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */ +#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */ /* Receive Descriptor */ #define E1000_RDT_DELAY 0x0000ffff /* Delay timer (1=1024us) */ @@ -1423,15 +1476,17 @@ #define EEPROM_SIZE_128B 0x0000 #define EEPROM_SIZE_MASK 0x1C00 - /* EEPROM Word Offsets */ -#define EEPROM_COMPAT 0x0003 -#define EEPROM_ID_LED_SETTINGS 0x0004 -#define EEPROM_INIT_CONTROL1_REG 0x000A -#define EEPROM_INIT_CONTROL2_REG 0x000F -#define EEPROM_CFG 0x0012 -#define EEPROM_FLASH_VERSION 0x0032 -#define EEPROM_CHECKSUM_REG 0x003F +#define EEPROM_COMPAT 0x0003 +#define EEPROM_ID_LED_SETTINGS 0x0004 +#define EEPROM_SERDES_AMPLITUDE 0x0006 /* For SERDES output amplitude adjustment. */ +#define EEPROM_INIT_CONTROL1_REG 0x000A +#define EEPROM_INIT_CONTROL2_REG 0x000F +#define EEPROM_INIT_CONTROL3_PORT_B 0x0014 +#define EEPROM_INIT_CONTROL3_PORT_A 0x0024 +#define EEPROM_CFG 0x0012 +#define EEPROM_FLASH_VERSION 0x0032 +#define EEPROM_CHECKSUM_REG 0x003F /* Word definitions for ID LED Settings */ #define ID_LED_RESERVED_0000 0x0000 @@ -1455,6 +1510,9 @@ #define IGP_LED3_MODE 0x07000000 +/* Mask bits for SERDES amplitude adjustment in Word 6 of the EEPROM */ +#define EEPROM_SERDES_AMPLITUDE_MASK 0x000F + /* Mask bits for fields in Word 0x0a of the EEPROM */ #define EEPROM_WORD0A_ILOS 0x0010 #define EEPROM_WORD0A_SWDPIO 0x01E0 @@ -1476,6 +1534,8 @@ #define EEPROM_NODE_ADDRESS_BYTE_0 0 #define EEPROM_PBA_BYTE_1 8 +#define EEPROM_RESERVED_WORD 0xFFFF + /* EEPROM Map Sizes (Byte Counts) */ #define PBA_SIZE 4 @@ -1485,10 +1545,9 @@ #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 */ +/* Number of Transmit and Receive Descriptors must be a multiple of 8 */ #define REQ_TX_DESCRIPTOR_MULTIPLE 8 #define REQ_RX_DESCRIPTOR_MULTIPLE 8 @@ -1555,35 +1614,30 @@ #define PCIX_STATUS_HI_MMRBC_2K 0x2 -/* The number of bits that we need to shift right to move the "pause" - * bits from the EEPROM (bits 13:12) to the "pause" (bits 8:7) field - * in the TXCW register +/* Number of bits required to shift right the "pause" bits from the + * EEPROM (bits 13:12) to the "pause" (bits 8:7) field in the TXCW register. */ #define PAUSE_SHIFT 5 -/* The number of bits that we need to shift left to move the "SWDPIO" - * bits from the EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field - * in the CTRL register +/* Number of bits required to shift left the "SWDPIO" bits from the + * EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field in the CTRL register. */ #define SWDPIO_SHIFT 17 -/* The number of bits that we need to shift left to move the "SWDPIO_EXT" - * bits from the EEPROM word F (bits 7:4) to the bits 11:8 of The - * Extended CTRL register. - * in the CTRL register +/* Number of bits required to shift left the "SWDPIO_EXT" bits from the + * EEPROM word F (bits 7:4) to the bits 11:8 of The Extended CTRL register. */ #define SWDPIO__EXT_SHIFT 4 -/* The number of bits that we need to shift left to move the "ILOS" - * bit from the EEPROM (bit 4) to the "ILOS" (bit 7) field - * in the CTRL register +/* Number of bits required to shift left the "ILOS" bit from the EEPROM + * (bit 4) to the "ILOS" (bit 7) field in the CTRL register. */ #define ILOS_SHIFT 3 #define RECEIVE_BUFFER_ALIGN_SIZE (256) -/* The number of milliseconds we wait for auto-negotiation to complete */ +/* Number of milliseconds we wait for auto-negotiation to complete */ #define LINK_UP_TIMEOUT 500 #define E1000_TX_BUFFER_SIZE ((uint32_t)1514) @@ -1666,6 +1720,16 @@ #define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */ #define M88E1000_RX_ERR_CNTR 0x15 /* Receive Error Counter */ +#define M88E1000_PHY_EXT_CTRL 0x1A /* PHY extend control register */ +#define M88E1000_PHY_PAGE_SELECT 0x1D /* Reg 29 for page number setting */ +#define M88E1000_PHY_GEN_CONTROL 0x1E /* Its meaning depends on reg 29 */ +#define M88E1000_PHY_VCO_REG_BIT8 0x100 /* Bits 8 & 11 are adjusted for */ +#define M88E1000_PHY_VCO_REG_BIT11 0x800 /* improved BER performance */ + +#define IGP01E1000_IEEE_REGS_PAGE 0x0000 +#define IGP01E1000_IEEE_RESTART_AUTONEG 0x3300 +#define IGP01E1000_IEEE_FORCE_GIGA 0x0140 + /* IGP01E1000 Specific Registers */ #define IGP01E1000_PHY_PORT_CONFIG 0x10 /* PHY Specific Port Config Register */ #define IGP01E1000_PHY_PORT_STATUS 0x11 /* PHY Specific Status Register */ @@ -1681,16 +1745,35 @@ #define IGP01E1000_PHY_AGC_C 0x1472 #define IGP01E1000_PHY_AGC_D 0x1872 -/* Number of AGC registers */ -#define IGP01E1000_PHY_AGC_NUM 4 +/* IGP01E1000 DSP Reset Register */ +#define IGP01E1000_PHY_DSP_RESET 0x1F33 +#define IGP01E1000_PHY_DSP_SET 0x1F71 +#define IGP01E1000_PHY_DSP_FFE 0x1F35 + +#define IGP01E1000_PHY_CHANNEL_NUM 4 +#define IGP01E1000_PHY_AGC_PARAM_A 0x1171 +#define IGP01E1000_PHY_AGC_PARAM_B 0x1271 +#define IGP01E1000_PHY_AGC_PARAM_C 0x1471 +#define IGP01E1000_PHY_AGC_PARAM_D 0x1871 + +#define IGP01E1000_PHY_EDAC_MU_INDEX 0xC000 +#define IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS 0x8000 + +#define IGP01E1000_PHY_ANALOG_TX_STATE 0x2890 +#define IGP01E1000_PHY_ANALOG_CLASS_A 0x2000 +#define IGP01E1000_PHY_FORCE_ANALOG_ENABLE 0x0004 +#define IGP01E1000_PHY_DSP_FFE_CM_CP 0x0069 +#define IGP01E1000_PHY_DSP_FFE_DEFAULT 0x002A /* IGP01E1000 PCS Initialization register - stores the polarity status when * speed = 1000 Mbps. */ #define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 +#define IGP01E1000_PHY_PCS_CTRL_REG 0x00B5 +#define IGP01E1000_ANALOG_REGS_PAGE 0x20C0 #define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ - +#define MAX_PHY_MULTI_PAGE_REG 0xF /*Registers that are equal on all pages*/ /* PHY Control Register */ #define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */ #define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */ @@ -1804,8 +1887,11 @@ #define SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */ #define SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local TX is Master, 0=Slave */ #define SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */ -#define SR_1000T_REMOTE_RX_STATUS_SHIFT 12 -#define SR_1000T_LOCAL_RX_STATUS_SHIFT 13 +#define SR_1000T_REMOTE_RX_STATUS_SHIFT 12 +#define SR_1000T_LOCAL_RX_STATUS_SHIFT 13 +#define SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT 5 +#define FFE_IDLE_ERR_COUNT_TIMEOUT_20 20 +#define FFE_IDLE_ERR_COUNT_TIMEOUT_100 100 /* Extended Status Register */ #define IEEE_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */ @@ -1897,7 +1983,6 @@ #define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */ #define M88E1000_EPSCR_TX_CLK_0 0x0000 /* NO TX_CLK */ - /* IGP01E1000 Specific Port Config Register - R/W */ #define IGP01E1000_PSCFR_AUTO_MDIX_PAR_DETECT 0x0010 #define IGP01E1000_PSCFR_PRE_EN 0x0020 @@ -1948,6 +2033,11 @@ #define IGP01E1000_MSE_CHANNEL_B 0x0F00 #define IGP01E1000_MSE_CHANNEL_A 0xF000 +/* IGP01E1000 DSP reset macros */ +#define DSP_RESET_ENABLE 0x0 +#define DSP_RESET_DISABLE 0x2 +#define E1000_MAX_DSP_RESETS 10 + /* IGP01E1000 AGC Registers */ #define IGP01E1000_AGC_LENGTH_SHIFT 7 /* Coarse - 13:11, Fine - 10:7 */ @@ -1958,18 +2048,6 @@ /* The precision of the length is +/- 10 meters */ #define IGP01E1000_AGC_RANGE 10 -/* IGP cable length table */ -static const -uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] = - { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 25, 25, 25, - 25, 25, 25, 25, 30, 30, 30, 30, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 50, 50, 50, 50, 50, 50, 50, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 70, 70, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120}; - /* IGP01E1000 PCS Initialization register */ /* bits 3:6 in the PCS registers stores the channels polarity */ #define IGP01E1000_PHY_POLARITY_MASK 0x0078 @@ -1979,6 +2057,23 @@ * on Link-Up */ #define IGP01E1000_GMII_SPD 0x20 /* Enable SPD */ +/* IGP01E1000 Analog Register */ +#define IGP01E1000_ANALOG_SPARE_FUSE_STATUS 0x20D1 +#define IGP01E1000_ANALOG_FUSE_STATUS 0x20D0 +#define IGP01E1000_ANALOG_FUSE_CONTROL 0x20DC +#define IGP01E1000_ANALOG_FUSE_BYPASS 0x20DE + +#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 #define M88E1000_I_PHY_ID 0x01410C30 @@ -2012,5 +2107,7 @@ #define ADVERTISE_1000_HALF 0x0010 #define ADVERTISE_1000_FULL 0x0020 #define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F /* Everything but 1000-Half */ +#define AUTONEG_ADVERTISE_10_100_ALL 0x000F /* All 10/100 speeds*/ +#define AUTONEG_ADVERTISE_10_ALL 0x0003 /* 10Mbps Full & Half speeds*/ #endif /* _E1000_HW_H_ */ Index: drivers/net/e1000/e1000_main.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/e1000/e1000_main.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/e1000/e1000_main.c 22 Jul 2004 19:49:43 -0000 1.1 +++ drivers/net/e1000/e1000_main.c 4 Aug 2004 01:29:14 -0000 1.2 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 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 @@ -30,67 +30,55 @@ /* 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.2.30.1 1/29/03 + * o Set VLAN filtering to IEEE 802.1Q after reset so we don't break + * SoL connections that use VLANs. + * o Allow 1000/Full setting for AutoNeg param for Fiber connections + * Jon D Mason [jonmason@us.ibm.com]. + * o Race between Tx queue and Tx clean fixed with a spin lock. + * o Added netpoll support. + * o Fixed endianess bug causing ethtool loopback diags to fail on ppc. + * o Use pdev->irq rather than netdev->irq in preparation for MSI support. + * o Report driver message on user override of InterruptThrottleRate + * module parameter. + * o Change I/O address storage from uint32_t to unsigned long. + * + * 5.2.22 10/15/03 + * o Bug fix: SERDES devices might be connected to a back-plane + * switch that doesn't support auto-neg, so add the capability + * to force 1000/Full. Also, since forcing 1000/Full, sample + * RxSynchronize bit to detect link state. + * o Bug fix: Flow control settings for hi/lo watermark didn't + * consider changes in the Rx FIFO size, which could occur with + * Jumbo Frames or with the reduced FIFO in 82547. + * o Better propagation of error codes. [Janice Girouard + * (janiceg@us.ibm.com)]. + * o Bug fix: hang under heavy Tx stress when running out of Tx + * descriptors; wasn't clearing context descriptor when backing + * out of send because of no-resource condition. + * o Bug fix: check netif_running in dev->poll so we don't have to + * hang in dev->close until all polls are finished. [Robert + * Ollson (robert.olsson@data.slu.se)]. + * o Revert TxDescriptor ring size back to 256 since change to 1024 + * wasn't accepted into the kernel. + * + * 5.2.16 8/8/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_copyright[] = "Copyright (c) 1999-2003 Intel Corporation."; +char e1000_driver_version[] = "5.2.30.1-k1"; +char e1000_copyright[] = "Copyright (c) 1999-2004 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 */ +static struct pci_device_id e1000_pci_tbl[] = { {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}, @@ -100,49 +88,57 @@ {0x8086, 0x100D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0x8086, 0x100E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0x8086, 0x100F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0x8086, 0x1011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0x8086, 0x1010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x8086, 0x1011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0x8086, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x8086, 0x1013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x8086, 0x1015, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {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, 0x1013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x8086, 0x1018, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0x8086, 0x1019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x8086, 0x101D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x8086, 0x101E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x8086, 0x1026, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x8086, 0x1027, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x8086, 0x1028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x8086, 0x1075, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x8086, 0x1076, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x8086, 0x1077, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x8086, 0x1078, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x8086, 0x1079, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x8086, 0x107A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x8086, 0x107B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* required last entry */ {0,} }; 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); void e1000_down(struct e1000_adapter *adapter); void e1000_reset(struct e1000_adapter *adapter); int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx); +int e1000_setup_tx_resources(struct e1000_adapter *adapter); +int e1000_setup_rx_resources(struct e1000_adapter *adapter); +void e1000_free_tx_resources(struct e1000_adapter *adapter); +void e1000_free_rx_resources(struct e1000_adapter *adapter); +void e1000_update_stats(struct e1000_adapter *adapter); + +/* Local Function Prototypes */ 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); -static int e1000_setup_tx_resources(struct e1000_adapter *adapter); -static int e1000_setup_rx_resources(struct e1000_adapter *adapter); static void e1000_configure_tx(struct e1000_adapter *adapter); static void e1000_configure_rx(struct e1000_adapter *adapter); static void e1000_setup_rctl(struct e1000_adapter *adapter); static void e1000_clean_tx_ring(struct e1000_adapter *adapter); static void e1000_clean_rx_ring(struct e1000_adapter *adapter); -static void e1000_free_tx_resources(struct e1000_adapter *adapter); -static void e1000_free_rx_resources(struct e1000_adapter *adapter); static void e1000_set_multi(struct net_device *netdev); static void e1000_update_phy_info(unsigned long data); static void e1000_watchdog(unsigned long data); @@ -151,12 +147,17 @@ static struct net_device_stats * e1000_get_stats(struct net_device *netdev); static int e1000_change_mtu(struct net_device *netdev, int new_mtu); static int e1000_set_mac(struct net_device *netdev, void *p); -static void e1000_update_stats(struct e1000_adapter *adapter); static inline void e1000_irq_disable(struct e1000_adapter *adapter); static inline void e1000_irq_enable(struct e1000_adapter *adapter); -static void e1000_intr(int irq, void *data, struct pt_regs *regs); +static irqreturn_t 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, @@ -183,13 +184,17 @@ static int e1000_resume(struct pci_dev *pdev); #endif +#ifdef CONFIG_NET_POLL_CONTROLLER +/* for netdump / net console */ +static void e1000_netpoll (struct net_device *dev); +#endif + struct notifier_block e1000_notifier_reboot = { .notifier_call = e1000_notify_reboot, .next = NULL, .priority = 0 }; - /* Exported from other modules */ extern void e1000_check_options(struct e1000_adapter *adapter); @@ -228,8 +233,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; } @@ -256,6 +262,7 @@ e1000_up(struct e1000_adapter *adapter) { struct net_device *netdev = adapter->netdev; + int err; /* hardware has been reset, we need to reload some things */ @@ -268,13 +275,10 @@ e1000_configure_rx(adapter); 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); - return -1; - } + if((err = request_irq(adapter->pdev->irq, &e1000_intr, + SA_SHIRQ | SA_SAMPLE_RANDOM, + netdev->name, netdev))) + return err; mod_timer(&adapter->watchdog_timer, jiffies); e1000_irq_enable(adapter); @@ -288,7 +292,7 @@ struct net_device *netdev = adapter->netdev; e1000_irq_disable(adapter); - free_irq(netdev->irq, netdev); + free_irq(adapter->pdev->irq, netdev); del_timer_sync(&adapter->tx_fifo_stall_timer); del_timer_sync(&adapter->watchdog_timer); del_timer_sync(&adapter->phy_info_timer); @@ -328,11 +332,21 @@ } E1000_WRITE_REG(&adapter->hw, PBA, pba); + /* flow control settings */ + adapter->hw.fc_high_water = pba - E1000_FC_HIGH_DIFF; + adapter->hw.fc_low_water = pba - E1000_FC_LOW_DIFF; + adapter->hw.fc_pause_time = E1000_FC_PAUSE_TIME; + adapter->hw.fc_send_xon = 1; adapter->hw.fc = adapter->hw.original_fc; + e1000_reset_hw(&adapter->hw); if(adapter->hw.mac_type >= e1000_82544) E1000_WRITE_REG(&adapter->hw, WUC, 0); e1000_init_hw(&adapter->hw); + + /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ + E1000_WRITE_REG(&adapter->hw, VET, ETHERNET_IEEE_VLAN_TYPE); + e1000_reset_adaptive(&adapter->hw); e1000_phy_get_info(&adapter->hw, &adapter->phy_info); } @@ -360,29 +374,32 @@ int mmio_len; int pci_using_dac; int i; + int err; uint16_t eeprom_data; - if((i = pci_enable_device(pdev))) - return i; + if((err = pci_enable_device(pdev))) + return err; - if(!(i = pci_set_dma_mask(pdev, PCI_DMA_64BIT))) { + if(!(err = pci_set_dma_mask(pdev, PCI_DMA_64BIT))) { pci_using_dac = 1; } else { - if((i = pci_set_dma_mask(pdev, PCI_DMA_32BIT))) { + if((err = pci_set_dma_mask(pdev, PCI_DMA_32BIT))) { E1000_ERR("No usable DMA configuration, aborting\n"); - return i; + return err; } pci_using_dac = 0; } - if((i = pci_request_regions(pdev, e1000_driver_name))) - return i; + if((err = pci_request_regions(pdev, e1000_driver_name))) + return err; pci_set_master(pdev); netdev = alloc_etherdev(sizeof(struct e1000_adapter)); - if(!netdev) + if(!netdev) { + err = -ENOMEM; goto err_alloc_etherdev; + } SET_MODULE_OWNER(netdev); @@ -396,8 +413,10 @@ mmio_len = pci_resource_len(pdev, BAR_0); adapter->hw.hw_addr = ioremap(mmio_start, mmio_len); - if(!adapter->hw.hw_addr) + if(!adapter->hw.hw_addr) { + err = -EIO; goto err_ioremap; + } for(i = BAR_1; i <= BAR_5; i++) { if(pci_resource_len(pdev, i) == 0) @@ -418,21 +437,26 @@ 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; +#ifdef CONFIG_NET_POLL_CONTROLLER + netdev->poll_controller = e1000_netpoll; +#endif - netdev->irq = pdev->irq; netdev->mem_start = mmio_start; netdev->mem_end = mmio_start + mmio_len; netdev->base_addr = adapter->hw.io_base; adapter->bd_number = cards_found; - adapter->id_string = e1000_strings[ent->driver_data]; /* setup the private structure */ - if(e1000_sw_init(adapter)) + if((err = e1000_sw_init(adapter))) goto err_sw_init; if(adapter->hw.mac_type >= e1000_82543) { @@ -445,13 +469,25 @@ 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; + /* before reading the EEPROM, reset the controller to + * put the device in a known good starting state */ + + e1000_reset_hw(&adapter->hw); + /* make sure the EEPROM is good */ if(e1000_validate_eeprom_checksum(&adapter->hw) < 0) { printk(KERN_ERR "The EEPROM Checksum Is Not Valid\n"); + err = -EIO; goto err_eeprom; } @@ -460,8 +496,10 @@ e1000_read_mac_addr(&adapter->hw); memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len); - if(!is_valid_ether_addr(netdev->dev_addr)) + if(!is_valid_ether_addr(netdev->dev_addr)) { + err = -EIO; goto err_eeprom; + } e1000_read_part_num(&adapter->hw, &(adapter->part_num)); @@ -483,15 +521,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 @@ -499,12 +536,28 @@ * enable the ACPI Magic Packet filter */ - e1000_read_eeprom(&adapter->hw, EEPROM_INIT_CONTROL2_REG,1, &eeprom_data); - if((adapter->hw.mac_type >= e1000_82544) && - (eeprom_data & E1000_EEPROM_APME)) + switch(adapter->hw.mac_type) { + case e1000_82542_rev2_0: + case e1000_82542_rev2_1: + case e1000_82543: + break; + case e1000_82546: + case e1000_82546_rev_3: + if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1) + && (adapter->hw.media_type == e1000_media_type_copper)) { + e1000_read_eeprom(&adapter->hw, + EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data); + break; + } + /* Fall Through */ + default: + e1000_read_eeprom(&adapter->hw, + EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data); + break; + } + if(eeprom_data & E1000_EEPROM_APME) adapter->wol |= E1000_WUFC_MAG; - /* reset the hardware with the new settings */ e1000_reset(adapter); @@ -516,10 +569,10 @@ err_eeprom: iounmap(adapter->hw.hw_addr); err_ioremap: - pci_release_regions(pdev); - kfree(netdev); + free_netdev(netdev); err_alloc_etherdev: - return -ENOMEM; + pci_release_regions(pdev); + return err; } /** @@ -539,7 +592,8 @@ struct e1000_adapter *adapter = netdev->priv; uint32_t manc; - if(adapter->hw.mac_type >= e1000_82540) { + if(adapter->hw.mac_type >= e1000_82540 && + adapter->hw.media_type == e1000_media_type_copper) { manc = E1000_READ_REG(&adapter->hw, MANC); if(manc & E1000_MANC_SMBUS_EN) { manc |= E1000_MANC_ARP_EN; @@ -551,11 +605,10 @@ e1000_phy_hw_reset(&adapter->hw); - iounmap(adapter->hw.hw_addr); pci_release_regions(pdev); - kfree(netdev); + free_netdev(netdev); } /** @@ -594,35 +647,20 @@ if (e1000_set_mac_type(hw)) { E1000_ERR("Unknown MAC Type\n"); - return -1; + return -EIO; } /* initialize eeprom parameters */ e1000_init_eeprom_params(hw); - /* flow control settings */ - - hw->fc_high_water = E1000_FC_HIGH_THRESH; - hw->fc_low_water = E1000_FC_LOW_THRESH; - hw->fc_pause_time = E1000_FC_PAUSE_TIME; - hw->fc_send_xon = 1; - - if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) + if((hw->mac_type == e1000_82541) || + (hw->mac_type == e1000_82547) || + (hw->mac_type == e1000_82541_rev_2) || + (hw->mac_type == e1000_82547_rev_2)) hw->phy_init_script = 1; - /* Media type - copper or fiber */ - - if(hw->mac_type >= e1000_82543) { - uint32_t status = E1000_READ_REG(hw, STATUS); - - if(status & E1000_STATUS_TBIMODE) - hw->media_type = e1000_media_type_fiber; - else - hw->media_type = e1000_media_type_copper; - } else { - hw->media_type = e1000_media_type_fiber; - } + e1000_set_media_type(hw); if(hw->mac_type < e1000_82543) hw->report_tx_early = 0; @@ -638,10 +676,12 @@ if(hw->media_type == e1000_media_type_copper) { hw->mdix = AUTO_ALL_MODES; hw->disable_polarity_correction = FALSE; + hw->master_slave = E1000_MASTER_SLAVE; } atomic_set(&adapter->irq_sem, 1); spin_lock_init(&adapter->stats_lock); + spin_lock_init(&adapter->tx_lock); return 0; } @@ -663,18 +703,19 @@ e1000_open(struct net_device *netdev) { struct e1000_adapter *adapter = netdev->priv; + int err; /* allocate transmit descriptors */ - if(e1000_setup_tx_resources(adapter)) + if((err = e1000_setup_tx_resources(adapter))) goto err_setup_tx; /* allocate receive descriptors */ - if(e1000_setup_rx_resources(adapter)) + if((err = e1000_setup_rx_resources(adapter))) goto err_setup_rx; - if(e1000_up(adapter)) + if((err = e1000_up(adapter))) goto err_up; return 0; @@ -686,7 +727,7 @@ err_setup_tx: e1000_reset(adapter); - return -EBUSY; + return err; } /** @@ -721,7 +762,7 @@ * Return 0 on success, negative on failure **/ -static int +int e1000_setup_tx_resources(struct e1000_adapter *adapter) { struct e1000_desc_ring *txdr = &adapter->tx_ring; @@ -787,7 +828,8 @@ tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT; break; default: - if(adapter->hw.media_type == e1000_media_type_fiber) + if(adapter->hw.media_type == e1000_media_type_fiber || + adapter->hw.media_type == e1000_media_type_internal_serdes) tipg = DEFAULT_82543_TIPG_IPGT_FIBER; else tipg = DEFAULT_82543_TIPG_IPGT_COPPER; @@ -814,13 +856,20 @@ 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; else adapter->txd_cmd |= E1000_TXD_CMD_RPS; + + /* Cache if we're 82544 running in PCI-X because we'll + * need this to apply a workaround later in the send path. */ + if(adapter->hw.mac_type == e1000_82544 && + adapter->hw.bus_type == e1000_bus_type_pcix) + adapter->pcix_82544 = 1; } /** @@ -830,7 +879,7 @@ * Returns 0 on success, negative on failure **/ -static int +int e1000_setup_rx_resources(struct e1000_adapter *adapter) { struct e1000_desc_ring *rxdr = &adapter->rx_ring; @@ -969,7 +1018,7 @@ * Free all transmit software resources **/ -static void +void e1000_free_tx_resources(struct e1000_adapter *adapter) { struct pci_dev *pdev = adapter->pdev; @@ -993,35 +1042,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); @@ -1034,20 +1086,20 @@ * Free all receive software resources **/ -static void +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 +1110,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); @@ -1239,41 +1294,6 @@ e1000_leave_82542_rst(adapter); } -static void -e1000_tx_flush(struct e1000_adapter *adapter) -{ - uint32_t ctrl, tctl, txcw, icr; - - e1000_irq_disable(adapter); - - if(adapter->hw.mac_type < e1000_82543) { - /* Transmit Unit Reset */ - tctl = E1000_READ_REG(&adapter->hw, TCTL); - E1000_WRITE_REG(&adapter->hw, TCTL, tctl | E1000_TCTL_RST); - E1000_WRITE_REG(&adapter->hw, TCTL, tctl); - e1000_clean_tx_ring(adapter); - e1000_configure_tx(adapter); - } else { - txcw = E1000_READ_REG(&adapter->hw, TXCW); - E1000_WRITE_REG(&adapter->hw, TXCW, txcw & ~E1000_TXCW_ANE); - - ctrl = E1000_READ_REG(&adapter->hw, CTRL); - E1000_WRITE_REG(&adapter->hw, CTRL, ctrl | E1000_CTRL_SLU | - E1000_CTRL_ILOS); - - mdelay(10); - - e1000_clean_tx_irq(adapter); - E1000_WRITE_REG(&adapter->hw, CTRL, ctrl); - E1000_WRITE_REG(&adapter->hw, TXCW, txcw); - - /* clear the link status change interrupts this caused */ - icr = E1000_READ_REG(&adapter->hw, ICR); - } - - e1000_irq_enable(adapter); -} - /* need to wait a few seconds after link up to get diagnostic information from the phy */ static void @@ -1336,11 +1356,18 @@ 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; + uint32_t link; e1000_check_for_link(&adapter->hw); - if(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU) { + if((adapter->hw.media_type == e1000_media_type_internal_serdes) && + !(E1000_READ_REG(&adapter->hw, TXCW) & E1000_TXCW_ANE)) + link = !adapter->hw.serdes_link_down; + else + link = E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU; + + if(link) { if(!netif_carrier_ok(netdev)) { e1000_get_speed_and_duplex(&adapter->hw, &adapter->link_speed, @@ -1373,14 +1400,26 @@ } e1000_update_stats(adapter); + + adapter->hw.tx_packet_delta = adapter->stats.tpt - adapter->tpt_old; + adapter->tpt_old = adapter->stats.tpt; + adapter->hw.collision_delta = adapter->stats.colc - adapter->colc_old; + adapter->colc_old = adapter->stats.colc; + + adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old; + adapter->gorcl_old = adapter->stats.gorcl; + adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old; + adapter->gotcl_old = adapter->stats.gotcl; + e1000_update_adaptive(&adapter->hw); if(!netif_carrier_ok(netdev)) { if(E1000_DESC_UNUSED(txdr) + 1 < txdr->count) { - unsigned long flags; - spin_lock_irqsave(&netdev->xmit_lock, flags); - e1000_tx_flush(adapter); - spin_unlock_irqrestore(&netdev->xmit_lock, flags); + /* We've lost link, so the controller stops DMA, + * but we've got queued Tx work that's never going + * to get done, so reset controller to flush Tx. + * (Do the reset outside of interrupt context). */ + schedule_task(&adapter->tx_timeout_task); } } @@ -1413,14 +1452,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 +1526,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 +1541,59 @@ #define E1000_MAX_DATA_PER_TXD (1<tx_ring; - int len = skb->len, offset = 0, size, count = 0, i; + struct e1000_tx_desc *tx_desc; + struct e1000_buffer *buffer_info; + unsigned int len = skb->len, max_per_txd = E1000_MAX_DATA_PER_TXD; + unsigned int offset = 0, size, count = 0, i; +#ifdef NETIF_F_TSO + unsigned int mss; +#endif + unsigned int nr_frags; + unsigned int f; - int f; +#ifdef NETIF_F_TSO + mss = skb_shinfo(skb)->tso_size; + /* The controller does a simple calculation to + * make sure there is enough room in the FIFO before + * initiating the DMA for each buffer. The calc is: + * 4 = ceil(buffer len/mss). To make sure we don't + * overrun the FIFO, adjust the max buffer len if mss + * drops. */ + if(mss) + max_per_txd = min(mss << 2, max_per_txd); +#endif + nr_frags = skb_shinfo(skb)->nr_frags; len -= skb->data_len; i = tx_ring->next_to_use; while(len) { - size = min(len, E1000_MAX_DATA_PER_TXD); - tx_ring->buffer_info[i].length = size; - tx_ring->buffer_info[i].dma = + buffer_info = &tx_ring->buffer_info[i]; + size = min(len, max_per_txd); +#ifdef NETIF_F_TSO + /* Workaround for premature desc write-backs + * in TSO mode. Append 4-byte sentinel desc */ + if(mss && !nr_frags && size == len && size > 8) + size -= 4; +#endif + /* Workaround for potential 82544 hang in PCI-X. Avoid + * terminating buffers within evenly-aligned dwords. */ + if(adapter->pcix_82544 && + !((unsigned long)(skb->data + offset + size - 1) & 4) && + size > 4) + size -= 4; + + 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,23 +1601,38 @@ 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]; len = frag->size; - offset = 0; + offset = frag->page_offset; while(len) { - size = min(len, E1000_MAX_DATA_PER_TXD); - tx_ring->buffer_info[i].length = size; - tx_ring->buffer_info[i].dma = + buffer_info = &tx_ring->buffer_info[i]; + size = min(len, max_per_txd); +#ifdef NETIF_F_TSO + /* Workaround for premature desc write-backs + * in TSO mode. Append 4-byte sentinel desc */ + if(mss && f == (nr_frags-1) && size == len && size > 8) + size -= 4; +#endif + /* Workaround for potential 82544 hang in PCI-X. + * Avoid terminating buffers within evenly-aligned + * dwords. */ + if(adapter->pcix_82544 && + !((unsigned long)(frag->page+offset+size-1) & 4) && + size > 4) + size -= 4; + + buffer_info->length = size; + buffer_info->dma = pci_map_page(adapter->pdev, frag->page, - frag->page_offset + offset, + offset, size, PCI_DMA_TODEVICE); - tx_ring->buffer_info[i].time_stamp = jiffies; + buffer_info->time_stamp = jiffies; len -= size; offset += size; @@ -1500,9 +1640,50 @@ if(++i == tx_ring->count) i = 0; } } - if(--i < 0) i = tx_ring->count - 1; - tx_ring->buffer_info[i].skb = skb; + if(E1000_DESC_UNUSED(&adapter->tx_ring) < count + 2) { + + /* There aren't enough descriptors available to queue up + * this send (need: count + 1 context desc + 1 desc gap + * to keep tail from touching head), so undo the mapping + * and abort the send. We could have done the check before + * we mapped the skb, but because of all the workarounds + * (above), it's too difficult to predict how many we're + * going to need.*/ + i = adapter->tx_ring.next_to_use; + + if(i == first) { + /* Cleanup after e1000_tx_[csum|tso] scribbling + * on descriptors. */ + tx_desc = E1000_TX_DESC(*tx_ring, first); + tx_desc->buffer_addr = 0; + tx_desc->lower.data = 0; + tx_desc->upper.data = 0; + } + + while(count--) { + buffer_info = &tx_ring->buffer_info[i]; + + if(buffer_info->dma) { + pci_unmap_page(adapter->pdev, + buffer_info->dma, + buffer_info->length, + PCI_DMA_TODEVICE); + buffer_info->dma = 0; + } + + if(++i == tx_ring->count) i = 0; + } + + adapter->tx_ring.next_to_use = first; + + return 0; + } + + 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 +1692,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 +1715,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 @@ -1588,32 +1774,27 @@ return 0; } -/* Tx Descriptors needed, worst case */ -#define TXD_USE_COUNT(S) (((S) >> E1000_MAX_TXD_PWR) + \ - (((S) & (E1000_MAX_DATA_PER_TXD - 1)) ? 1 : 0)) -#define DESC_NEEDED TXD_USE_COUNT(MAX_JUMBO_FRAME_SIZE) + \ - MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1 - static int 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; + unsigned long flags; + int count; if(skb->len <= 0) { dev_kfree_skb_any(skb); return 0; } - if(E1000_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED) { - netif_stop_queue(netdev); - return 1; - } + spin_lock_irqsave(&adapter->tx_lock, flags); if(adapter->hw.mac_type == e1000_82547) { if(e1000_82547_fifo_workaround(adapter, skb)) { netif_stop_queue(netdev); mod_timer(&adapter->tx_fifo_stall_timer, jiffies); + spin_unlock_irqrestore(&adapter->tx_lock, flags); return 1; } } @@ -1623,13 +1804,25 @@ 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); + if((count = e1000_tx_map(adapter, skb, first))) + e1000_tx_queue(adapter, count, tx_flags); + else { + netif_stop_queue(netdev); + spin_unlock_irqrestore(&adapter->tx_lock, flags); + return 1; + } netdev->trans_start = jiffies; + spin_unlock_irqrestore(&adapter->tx_lock, flags); + return 0; } @@ -1671,6 +1864,7 @@ { struct e1000_adapter *adapter = netdev->priv; + e1000_update_stats(adapter); return &adapter->net_stats; } @@ -1729,7 +1923,7 @@ * @adapter: board private structure **/ -static void +void e1000_update_stats(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; @@ -1747,8 +1941,7 @@ adapter->stats.crcerrs += E1000_READ_REG(hw, CRCERRS); adapter->stats.gprc += E1000_READ_REG(hw, GPRC); - adapter->gorcl = E1000_READ_REG(hw, GORCL); - adapter->stats.gorcl += adapter->gorcl; + adapter->stats.gorcl += E1000_READ_REG(hw, GORCL); adapter->stats.gorch += E1000_READ_REG(hw, GORCH); adapter->stats.bprc += E1000_READ_REG(hw, BPRC); adapter->stats.mprc += E1000_READ_REG(hw, MPRC); @@ -1760,8 +1953,6 @@ adapter->stats.prc1023 += E1000_READ_REG(hw, PRC1023); adapter->stats.prc1522 += E1000_READ_REG(hw, PRC1522); - spin_unlock_irqrestore(&adapter->stats_lock, flags); - /* the rest of the counters are only modified here */ adapter->stats.symerrs += E1000_READ_REG(hw, SYMERRS); @@ -1779,8 +1970,7 @@ adapter->stats.xofftxc += E1000_READ_REG(hw, XOFFTXC); adapter->stats.fcruc += E1000_READ_REG(hw, FCRUC); adapter->stats.gptc += E1000_READ_REG(hw, GPTC); - adapter->gotcl = E1000_READ_REG(hw, GOTCL); - adapter->stats.gotcl += adapter->gotcl; + adapter->stats.gotcl += E1000_READ_REG(hw, GOTCL); adapter->stats.gotch += E1000_READ_REG(hw, GOTCH); adapter->stats.rnbc += E1000_READ_REG(hw, RNBC); adapter->stats.ruc += E1000_READ_REG(hw, RUC); @@ -1858,9 +2048,12 @@ } 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; } + + spin_unlock_irqrestore(&adapter->stats_lock, flags); } /** @@ -1898,29 +2091,90 @@ * @pt_regs: CPU registers structure **/ -static void +static irqreturn_t e1000_intr(int irq, void *data, struct pt_regs *regs) { struct net_device *netdev = data; struct e1000_adapter *adapter = netdev->priv; + struct e1000_hw *hw = &adapter->hw; 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 */ + return IRQ_NONE; /* Not our interrupt */ if(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { - adapter->hw.get_link_status = 1; + hw->get_link_status = 1; 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(hw, IMC, ~0); + __netif_rx_schedule(netdev); + } +#else + /* Writing IMC and IMS is needed for 82547. + Due to Hub Link bus being occupied, an interrupt + de-assertion message is not able to be sent. + When an interrupt assertion message is generated later, + two messages are re-ordered and sent out. + That causes APIC to think 82547 is in de-assertion + state, while 82547 is in assertion state, resulting + in dead lock. Writing IMC forces 82547 into + de-assertion state. + */ + if(hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2) + e1000_irq_disable(adapter); + 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; + if(hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2) + e1000_irq_enable(adapter); +#endif + + return IRQ_HANDLED; } +#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_running(netdev)) { + netif_rx_complete(netdev); + e1000_irq_enable(adapter); + } + + return (work_done >= work_to_do); +} +#endif + /** * e1000_clean_tx_irq - Reclaim resources after transmit completes * @adapter: board private structure @@ -1932,39 +2186,50 @@ 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; + + spin_lock(&adapter->tx_lock); 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; @@ -1972,6 +2237,8 @@ if(cleaned && netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) netif_wake_queue(netdev); + spin_unlock(&adapter->tx_lock); + return cleaned; } @@ -1981,31 +2248,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 +2298,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 +2326,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 +2342,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; @@ -2085,7 +2378,7 @@ /** * e1000_alloc_rx_buffers - Replace used receive buffers - * @data: address of board private structure + * @adapter: address of board private structure **/ static void @@ -2095,13 +2388,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 +2414,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 +2435,7 @@ } if(++i == rx_ring->count) i = 0; + buffer_info = &rx_ring->buffer_info[i]; } rx_ring->next_to_use = i; @@ -2238,7 +2534,7 @@ uint16_t mii_reg; uint16_t spddplx; - if(adapter->hw.media_type == e1000_media_type_fiber) + if(adapter->hw.media_type != e1000_media_type_copper) return -EOPNOTSUPP; switch (cmd) { @@ -2370,13 +2666,13 @@ } uint32_t -e1000_io_read(struct e1000_hw *hw, uint32_t port) +e1000_io_read(struct e1000_hw *hw, unsigned long port) { return inl(port); } void -e1000_io_write(struct e1000_hw *hw, uint32_t port, uint32_t value) +e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value) { outl(value, port); } @@ -2393,8 +2689,6 @@ if(grp) { /* enable VLAN tag insert/strip */ - E1000_WRITE_REG(&adapter->hw, VET, ETHERNET_IEEE_VLAN_TYPE); - ctrl = E1000_READ_REG(&adapter->hw, CTRL); ctrl |= E1000_CTRL_VME; E1000_WRITE_REG(&adapter->hw, CTRL, ctrl); @@ -2510,7 +2804,7 @@ 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))) { if(pci_dev_driver(pdev) == &e1000_driver) e1000_suspend(pdev, 3); } @@ -2518,7 +2812,6 @@ return NOTIFY_DONE; } - static int e1000_suspend(struct pci_dev *pdev, uint32_t state) { @@ -2558,7 +2851,8 @@ E1000_WRITE_REG(&adapter->hw, CTRL, ctrl); } - if(adapter->hw.media_type == e1000_media_type_fiber) { + if(adapter->hw.media_type == e1000_media_type_fiber || + adapter->hw.media_type == e1000_media_type_internal_serdes) { /* keep the laser running in D3 */ ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT); ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA; @@ -2578,7 +2872,8 @@ pci_save_state(pdev, adapter->pci_state); - if(adapter->hw.mac_type >= e1000_82540) { + if(adapter->hw.mac_type >= e1000_82540 && + adapter->hw.media_type == e1000_media_type_copper) { manc = E1000_READ_REG(&adapter->hw, MANC); if(manc & E1000_MANC_SMBUS_EN) { manc |= E1000_MANC_ARP_EN; @@ -2616,7 +2911,8 @@ netif_device_attach(netdev); - if(adapter->hw.mac_type >= e1000_82540) { + if(adapter->hw.mac_type >= e1000_82540 && + adapter->hw.media_type == e1000_media_type_copper) { manc = E1000_READ_REG(&adapter->hw, MANC); manc &= ~(E1000_MANC_ARP_EN); E1000_WRITE_REG(&adapter->hw, MANC, manc); @@ -2626,4 +2922,20 @@ } #endif +#ifdef CONFIG_NET_POLL_CONTROLLER +/* + * Polling 'interrupt' - used by things like netconsole to send skbs + * without having to re-enable interrupts. It's not called while + * the interrupt routine is executing. + */ + +static void e1000_netpoll (struct net_device *dev) +{ + struct e1000_adapter *adapter = dev->priv; + disable_irq(adapter->pdev->irq); + e1000_intr (adapter->pdev->irq, dev, NULL); + enable_irq(adapter->pdev->irq); +} +#endif + /* e1000_main.c */ Index: drivers/net/e1000/e1000_osdep.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/e1000/e1000_osdep.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/e1000/e1000_osdep.h 22 Jul 2004 19:49:43 -0000 1.1 +++ drivers/net/e1000/e1000_osdep.h 4 Aug 2004 01:29:14 -0000 1.2 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 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 @@ -27,7 +27,7 @@ *******************************************************************************/ -/* glue for the OS independant part of e1000 +/* glue for the OS independent part of e1000 * includes register access macros */ @@ -55,11 +55,12 @@ #define CMD_MEM_WRT_INVALIDATE PCI_COMMAND_INVALIDATE typedef enum { +#undef FALSE FALSE = 0, +#undef TRUE TRUE = 1 } boolean_t; -#define ASSERT(x) if(!(x)) BUG() #define MSGOUT(S, A, B) printk(KERN_DEBUG S "\n", A, B) #if DBG Index: drivers/net/e1000/e1000_param.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/e1000/e1000_param.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/e1000/e1000_param.c 22 Jul 2004 19:49:43 -0000 1.1 +++ drivers/net/e1000/e1000_param.c 4 Aug 2004 01:29:14 -0000 1.2 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 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 @@ -63,7 +63,7 @@ /* Transmit Descriptor Count * * Valid Range: 80-256 for 82542 and 82543 gigabit ethernet controllers - * Valid Range: 80-4096 for 82544 + * Valid Range: 80-4096 for 82544 and newer * * Default Value: 256 */ @@ -73,7 +73,7 @@ /* Receive Descriptor Count * * Valid Range: 80-256 for 82542 and 82543 gigabit ethernet controllers - * Valid Range: 80-4096 for 82544 + * Valid Range: 80-4096 for 82544 and newer * * Default Value: 256 */ @@ -140,7 +140,7 @@ * Valid Range: 0, 1 * - 0 - disables all checksum offload * - 1 - enables receive IP/TCP/UDP checksum offload - * on 82543 based NICs + * on 82543 and newer -based NICs * * Default Value: 1 */ @@ -196,16 +196,6 @@ #define AUTONEG_ADV_MASK 0x2F #define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL -#define DEFAULT_TXD 256 -#define MAX_TXD 256 -#define MIN_TXD 80 -#define MAX_82544_TXD 4096 - -#define DEFAULT_RXD 256 -#define MAX_RXD 256 -#define MIN_RXD 80 -#define MAX_82544_RXD 4096 - #define DEFAULT_RDTR 0 #define MAX_RXDELAY 0xFFFF #define MIN_RXDELAY 0 @@ -299,7 +289,7 @@ * e1000_check_options - Range Checking for Command Line Parameters * @adapter: board private structure * - * This routine checks all command line paramters for valid user + * This routine checks all command line parameters for valid user * input. If an invalid value is given, or if no user specified * value exists, a default value is used. The final value is stored * in a variable in the adapter structure. @@ -320,14 +310,15 @@ struct e1000_option opt = { .type = range_option, .name = "Transmit Descriptors", - .err = "using default of " __MODULE_STRING(DEFAULT_TXD), - .def = DEFAULT_TXD, - .arg = { .r = { .min = MIN_TXD }} + .err = "using default of " + __MODULE_STRING(E1000_DEFAULT_TXD), + .def = E1000_DEFAULT_TXD, + .arg = { .r = { .min = E1000_MIN_TXD }} }; struct e1000_desc_ring *tx_ring = &adapter->tx_ring; e1000_mac_type mac_type = adapter->hw.mac_type; opt.arg.r.max = mac_type < e1000_82544 ? - MAX_TXD : MAX_82544_TXD; + E1000_MAX_TXD : E1000_MAX_82544_TXD; tx_ring->count = TxDescriptors[bd]; e1000_validate_option(&tx_ring->count, &opt); @@ -337,13 +328,15 @@ struct e1000_option opt = { .type = range_option, .name = "Receive Descriptors", - .err = "using default of " __MODULE_STRING(DEFAULT_RXD), - .def = DEFAULT_RXD, - .arg = { .r = { .min = MIN_RXD }} + .err = "using default of " + __MODULE_STRING(E1000_DEFAULT_RXD), + .def = E1000_DEFAULT_RXD, + .arg = { .r = { .min = E1000_MIN_RXD }} }; struct e1000_desc_ring *rx_ring = &adapter->rx_ring; e1000_mac_type mac_type = adapter->hw.mac_type; - opt.arg.r.max = mac_type < e1000_82544 ? MAX_RXD : MAX_82544_RXD; + opt.arg.r.max = mac_type < e1000_82544 ? E1000_MAX_RXD : + E1000_MAX_82544_RXD; rx_ring->count = RxDescriptors[bd]; e1000_validate_option(&rx_ring->count, &opt); @@ -446,18 +439,25 @@ }; adapter->itr = InterruptThrottleRate[bd]; - if(adapter->itr == 0) { - printk(KERN_INFO "%s turned off\n", opt.name); - } else if(adapter->itr == 1 || adapter->itr == -1) { - /* Dynamic mode */ + switch(adapter->itr) { + case -1: adapter->itr = 1; - } else { + break; + case 0: + printk(KERN_INFO "%s turned off\n", opt.name); + break; + case 1: + printk(KERN_INFO "%s set to dynamic mode\n", opt.name); + break; + default: e1000_validate_option(&adapter->itr, &opt); + break; } } switch(adapter->hw.media_type) { case e1000_media_type_fiber: + case e1000_media_type_internal_serdes: e1000_check_fiber_options(adapter); break; case e1000_media_type_copper: @@ -489,9 +489,9 @@ printk(KERN_INFO "Duplex not valid for fiber adapters, " "parameter ignored\n"); } - if((AutoNeg[bd] != OPTION_UNSET)) { - printk(KERN_INFO "AutoNeg not valid for fiber adapters, " - "parameter ignored\n"); + if((AutoNeg[bd] != OPTION_UNSET) && (AutoNeg[bd] != 0x20)) { + printk(KERN_INFO "AutoNeg other than Full/1000 is " + "not valid for fiber adapters, parameter ignored\n"); } } @@ -601,7 +601,7 @@ switch (speed + dplx) { case 0: - adapter->hw.autoneg = 1; + adapter->hw.autoneg = adapter->fc_autoneg = 1; if(Speed[bd] != OPTION_UNSET || Duplex[bd] != OPTION_UNSET) printk(KERN_INFO "Speed and duplex autonegotiation enabled\n"); @@ -609,14 +609,14 @@ case HALF_DUPLEX: printk(KERN_INFO "Half Duplex specified without Speed\n"); printk(KERN_INFO "Using Autonegotiation at Half Duplex only\n"); - adapter->hw.autoneg = 1; + adapter->hw.autoneg = adapter->fc_autoneg = 1; adapter->hw.autoneg_advertised = ADVERTISE_10_HALF | ADVERTISE_100_HALF; break; case FULL_DUPLEX: printk(KERN_INFO "Full Duplex specified without Speed\n"); printk(KERN_INFO "Using Autonegotiation at Full Duplex only\n"); - adapter->hw.autoneg = 1; + adapter->hw.autoneg = adapter->fc_autoneg = 1; adapter->hw.autoneg_advertised = ADVERTISE_10_FULL | ADVERTISE_100_FULL | ADVERTISE_1000_FULL; @@ -624,38 +624,38 @@ case SPEED_10: printk(KERN_INFO "10 Mbps Speed specified without Duplex\n"); printk(KERN_INFO "Using Autonegotiation at 10 Mbps only\n"); - adapter->hw.autoneg = 1; + adapter->hw.autoneg = adapter->fc_autoneg = 1; adapter->hw.autoneg_advertised = ADVERTISE_10_HALF | ADVERTISE_10_FULL; break; case SPEED_10 + HALF_DUPLEX: printk(KERN_INFO "Forcing to 10 Mbps Half Duplex\n"); - adapter->hw.autoneg = 0; + adapter->hw.autoneg = adapter->fc_autoneg = 0; adapter->hw.forced_speed_duplex = e1000_10_half; adapter->hw.autoneg_advertised = 0; break; case SPEED_10 + FULL_DUPLEX: printk(KERN_INFO "Forcing to 10 Mbps Full Duplex\n"); - adapter->hw.autoneg = 0; + adapter->hw.autoneg = adapter->fc_autoneg = 0; adapter->hw.forced_speed_duplex = e1000_10_full; adapter->hw.autoneg_advertised = 0; break; case SPEED_100: printk(KERN_INFO "100 Mbps Speed specified without Duplex\n"); printk(KERN_INFO "Using Autonegotiation at 100 Mbps only\n"); - adapter->hw.autoneg = 1; + adapter->hw.autoneg = adapter->fc_autoneg = 1; adapter->hw.autoneg_advertised = ADVERTISE_100_HALF | ADVERTISE_100_FULL; break; case SPEED_100 + HALF_DUPLEX: printk(KERN_INFO "Forcing to 100 Mbps Half Duplex\n"); - adapter->hw.autoneg = 0; + adapter->hw.autoneg = adapter->fc_autoneg = 0; adapter->hw.forced_speed_duplex = e1000_100_half; adapter->hw.autoneg_advertised = 0; break; case SPEED_100 + FULL_DUPLEX: printk(KERN_INFO "Forcing to 100 Mbps Full Duplex\n"); - adapter->hw.autoneg = 0; + adapter->hw.autoneg = adapter->fc_autoneg = 0; adapter->hw.forced_speed_duplex = e1000_100_full; adapter->hw.autoneg_advertised = 0; break; @@ -663,20 +663,20 @@ printk(KERN_INFO "1000 Mbps Speed specified without Duplex\n"); printk(KERN_INFO "Using Autonegotiation at 1000 Mbps Full Duplex only\n"); - adapter->hw.autoneg = 1; + adapter->hw.autoneg = adapter->fc_autoneg = 1; adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL; break; case SPEED_1000 + HALF_DUPLEX: printk(KERN_INFO "Half Duplex is not supported at 1000 Mbps\n"); printk(KERN_INFO "Using Autonegotiation at 1000 Mbps Full Duplex only\n"); - adapter->hw.autoneg = 1; + adapter->hw.autoneg = adapter->fc_autoneg = 1; adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL; break; case SPEED_1000 + FULL_DUPLEX: printk(KERN_INFO "Using Autonegotiation at 1000 Mbps Full Duplex only\n"); - adapter->hw.autoneg = 1; + adapter->hw.autoneg = adapter->fc_autoneg = 1; adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL; break; default: Index: drivers/net/hamradio/dmascc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/hamradio/dmascc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/hamradio/dmascc.c 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/hamradio/dmascc.c 4 Aug 2004 01:29:18 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: dmascc.c,v 1.1 2004/07/22 19:49:44 joff Exp $ + * $Id: dmascc.c,v 1.2 2004/08/04 01:29:18 joff Exp $ * * Driver for high-speed SCC boards (those with DMA support) * Copyright (C) 1997-2000 Klaus Kudielka Index: drivers/net/hamradio/mkiss.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/hamradio/mkiss.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/hamradio/mkiss.c 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/hamradio/mkiss.c 4 Aug 2004 01:29:18 -0000 1.2 @@ -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; } } Index: drivers/net/hamradio/scc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/hamradio/scc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/hamradio/scc.c 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/hamradio/scc.c 4 Aug 2004 01:29:18 -0000 1.2 @@ -1,4 +1,4 @@ -#define RCS_ID "$Id: scc.c,v 1.1 2004/07/22 19:49:44 joff Exp $" +#define RCS_ID "$Id: scc.c,v 1.2 2004/08/04 01:29:18 joff Exp $" #define VERSION "3.0" Index: drivers/net/irda/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/irda/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/irda/Config.in 22 Jul 2004 19:49:37 -0000 1.1 +++ drivers/net/irda/Config.in 4 Aug 2004 01:29:20 -0000 1.2 @@ -42,6 +42,7 @@ dep_tristate 'SMC IrCC (Experimental)' CONFIG_SMC_IRCC_FIR $CONFIG_IRDA dep_tristate 'ALi M5123 FIR (Experimental)' CONFIG_ALI_FIR $CONFIG_IRDA dep_tristate 'VLSI 82C147 SIR/MIR/FIR (Experimental)' CONFIG_VLSI_FIR $CONFIG_IRDA +dep_tristate 'VIA IrCC (Experimental)' CONFIG_VIA_IRCC_FIR $CONFIG_IRDA fi if [ "$CONFIG_ARCH_SA1100" = "y" ]; then dep_tristate 'SA1100 Internal IR' CONFIG_SA1100_FIR $CONFIG_IRDA $CONFIG_EXPERIMENTAL Index: drivers/net/irda/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/irda/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/irda/Makefile 22 Jul 2004 19:49:37 -0000 1.1 +++ drivers/net/irda/Makefile 4 Aug 2004 01:29:20 -0000 1.2 @@ -22,6 +22,7 @@ obj-$(CONFIG_SMC_IRCC_FIR) += smc-ircc.o irport.o obj-$(CONFIG_ALI_FIR) += ali-ircc.o obj-$(CONFIG_VLSI_FIR) += vlsi_ir.o +obj-$(CONFIG_VIA_IRCC_FIR) += via-ircc.o obj-$(CONFIG_ESI_DONGLE) += esi.o obj-$(CONFIG_TEKRAM_DONGLE) += tekram.o obj-$(CONFIG_ACTISYS_DONGLE) += actisys.o Index: drivers/net/irda/act200l.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/irda/act200l.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/irda/act200l.c 22 Jul 2004 19:49:37 -0000 1.1 +++ drivers/net/irda/act200l.c 4 Aug 2004 01:29:20 -0000 1.2 @@ -94,19 +94,19 @@ act200l_change_speed, }; -int __init act200l_init(void) +static int __init act200l_init(void) { return irda_device_register_dongle(&dongle); } -void __exit act200l_cleanup(void) +static void __exit act200l_cleanup(void) { irda_device_unregister_dongle(&dongle); } static void act200l_open(dongle_t *self, struct qos_info *qos) { - IRDA_DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, "%s()\n", __FUNCTION__); /* Power on the dongle */ self->set_dtr_rts(self->dev, TRUE, TRUE); @@ -120,7 +120,7 @@ static void act200l_close(dongle_t *self) { - IRDA_DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, "%s()\n", __FUNCTION__); /* Power off the dongle */ self->set_dtr_rts(self->dev, FALSE, FALSE); @@ -141,7 +141,7 @@ __u8 control[3]; int ret = 0; - IRDA_DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, "%s()\n", __FUNCTION__); self->speed_task = task; @@ -158,7 +158,7 @@ } break; case IRDA_TASK_CHILD_WAIT: - WARNING(__FUNCTION__ "(), resetting dongle timed out!\n"); + WARNING("%s(), resetting dongle timed out!\n", __FUNCTION__); ret = -1; break; case IRDA_TASK_CHILD_DONE: @@ -203,7 +203,7 @@ self->speed_task = NULL; break; default: - ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + ERROR("%s(), unknown state %d\n", __FUNCTION__, task->state); irda_task_next_state(task, IRDA_TASK_DONE); self->speed_task = NULL; ret = -1; @@ -233,7 +233,7 @@ }; int ret = 0; - IRDA_DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, "%s()\n", __FUNCTION__); self->reset_task = task; @@ -269,7 +269,7 @@ self->reset_task = NULL; break; default: - ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + ERROR("%s(), unknown state %d\n", __FUNCTION__, task->state); irda_task_next_state(task, IRDA_TASK_DONE); self->reset_task = NULL; ret = -1; Index: drivers/net/irda/au1k_ir.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/irda/au1k_ir.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/irda/au1k_ir.c 22 Jul 2004 19:49:37 -0000 1.1 +++ drivers/net/irda/au1k_ir.c 4 Aug 2004 01:29:20 -0000 1.2 @@ -46,7 +46,13 @@ #include #include #include +#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) #include +#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) +#include +#else +#error au1k_ir: unsupported board +#endif #include #include @@ -71,10 +77,16 @@ static int qos_mtt_bits = 0x07; /* 1 ms or more */ static struct net_device *ir_devs[NUM_IR_IFF]; static char version[] __devinitdata = - "au1k_ircc:1.0 ppopov@mvista.com\n"; + "au1k_ircc:1.2 ppopov@mvista.com\n"; #define RUN_AT(x) (jiffies + (x)) +#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) +static BCSR * const bcsr = (BCSR *)0xAE000000; +#endif + +static spinlock_t ir_lock = SPIN_LOCK_UNLOCKED; + /* * IrDA peripheral bug. You have to read the register * twice to get the right value. @@ -126,7 +138,7 @@ if (ret != NULL) { memset(ret, 0, size); *dma_handle = virt_to_bus(ret); - ret = KSEG0ADDR(ret); + ret = (void *)KSEG0ADDR(ret); } return ret; } @@ -134,7 +146,7 @@ static void dma_free(void *vaddr, size_t size) { - vaddr = KSEG0ADDR(vaddr); + vaddr = (void *)KSEG0ADDR(vaddr); free_pages((unsigned long) vaddr, get_order(size)); } @@ -211,7 +223,7 @@ struct au1k_private *aup = NULL; int i, retval = 0, err; db_dest_t *pDB, *pDBfree; - unsigned long temp; + dma_addr_t temp; dev->priv = kmalloc(sizeof(struct au1k_private), GFP_KERNEL); if (dev->priv == NULL) { @@ -292,6 +304,14 @@ aup->tx_ring[i]->flags = 0; aup->tx_db_inuse[i] = pDB; } + +#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) + /* power on */ + bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK; + bcsr->resets |= BCSR_RESETS_IRDA_MODE_FULL; + au_sync(); +#endif + return 0; out: @@ -532,13 +552,13 @@ flags = ptxd->flags; if (flags & AU_OWN) { - printk(KERN_INFO "%s: tx_full\n", dev->name); + printk(KERN_DEBUG "%s: tx_full\n", dev->name); netif_stop_queue(dev); aup->tx_full = 1; return 1; } else if (((aup->tx_head + 1) & (NUM_IR_DESC - 1)) == aup->tx_tail) { - printk(KERN_INFO "%s: tx_full\n", dev->name); + printk(KERN_DEBUG "%s: tx_full\n", dev->name); netif_stop_queue(dev); aup->tx_full = 1; return 1; @@ -558,6 +578,7 @@ memcpy((void *)pDB->vaddr, skb->data, skb->len); ptxd->count_0 = skb->len & 0xff; ptxd->count_1 = (skb->len >> 8) & 0xff; + } else { /* SIR */ @@ -565,6 +586,7 @@ ptxd->count_0 = len & 0xff; ptxd->count_1 = (len >> 8) & 0xff; ptxd->flags |= IR_DIS_CRC; + au_writel(au_readl(0xae00000c) & ~(1<<13), 0xae00000c); } ptxd->flags |= AU_OWN; au_sync(); @@ -699,12 +721,14 @@ u32 control; int ret = 0, timeout = 10, i; volatile ring_dest_t *ptxd; +#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) + unsigned long irda_resets; +#endif if (speed == aup->speed) return ret; - save_flags(flags); - cli(); + spin_lock_irqsave(&ir_lock, flags); /* disable PHY first */ writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE); @@ -745,10 +769,20 @@ ptxd->flags = AU_OWN; } - if (speed == 4000000) + if (speed == 4000000) { +#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) + bcsr->resets |= BCSR_RESETS_FIR_SEL; +#else /* Pb1000 and Pb1100 */ writel(1<<13, CPLD_AUX1); - else +#endif + } + else { +#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) + bcsr->resets &= ~BCSR_RESETS_FIR_SEL; +#else /* Pb1000 and Pb1100 */ writel(readl(CPLD_AUX1) & ~(1<<13), CPLD_AUX1); +#endif + } switch (speed) { case 9600: @@ -794,18 +828,18 @@ } else { if (control & (1<<11)) - printk(KERN_INFO "%s Valid SIR config\n", dev->name); + printk(KERN_DEBUG "%s Valid SIR config\n", dev->name); if (control & (1<<12)) - printk(KERN_INFO "%s Valid MIR config\n", dev->name); + printk(KERN_DEBUG "%s Valid MIR config\n", dev->name); if (control & (1<<13)) - printk(KERN_INFO "%s Valid FIR config\n", dev->name); + printk(KERN_DEBUG "%s Valid FIR config\n", dev->name); if (control & (1<<10)) - printk(KERN_INFO "%s TX enabled\n", dev->name); + printk(KERN_DEBUG "%s TX enabled\n", dev->name); if (control & (1<<9)) - printk(KERN_INFO "%s RX enabled\n", dev->name); + printk(KERN_DEBUG "%s RX enabled\n", dev->name); } - restore_flags(flags); + spin_unlock_irqrestore(&ir_lock, flags); return ret; } Index: drivers/net/irda/donauboe.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/irda/donauboe.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/irda/donauboe.c 22 Jul 2004 19:49:37 -0000 1.1 +++ drivers/net/irda/donauboe.c 4 Aug 2004 01:29:20 -0000 1.2 @@ -48,7 +48,7 @@ static char *rcsid = - "$Id: donauboe.c,v 1.1 2004/07/22 19:49:37 joff Exp $"; + "$Id: donauboe.c,v 1.2 2004/08/04 01:29:20 joff Exp $"; /* See below for a description of the logic in this driver */ Index: drivers/net/irda/irda-usb.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/irda/irda-usb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/irda/irda-usb.c 22 Jul 2004 19:49:37 -0000 1.1 +++ drivers/net/irda/irda-usb.c 4 Aug 2004 01:29:20 -0000 1.2 @@ -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, "%s() on %s\n", __FUNCTION__, 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, "%s(), Changing speed now...\n", __FUNCTION__); + 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); @@ -1590,7 +1584,7 @@ /* * Module insertion */ -int __init usb_irda_init(void) +static int __init usb_irda_init(void) { if (usb_register(&irda_driver) < 0) return -1; @@ -1604,7 +1598,7 @@ /* * Module removal */ -void __exit usb_irda_cleanup(void) +static void __exit usb_irda_cleanup(void) { struct irda_usb_cb *irda = NULL; int i; Index: drivers/net/irda/ma600.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/irda/ma600.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/irda/ma600.c 22 Jul 2004 19:49:37 -0000 1.1 +++ drivers/net/irda/ma600.c 4 Aug 2004 01:29:20 -0000 1.2 @@ -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 */ @@ -84,15 +84,15 @@ ma600_change_speed, }; -int __init ma600_init(void) +static int __init ma600_init(void) { - IRDA_DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, "%s()\n", __FUNCTION__); return irda_device_register_dongle(&dongle); } -void __exit ma600_cleanup(void) +static void __exit ma600_cleanup(void) { - IRDA_DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, "%s()\n", __FUNCTION__); irda_device_unregister_dongle(&dongle); } @@ -105,7 +105,7 @@ */ static void ma600_open(dongle_t *self, struct qos_info *qos) { - IRDA_DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, "%s()\n", __FUNCTION__); qos->baud_rate.bits &= IR_2400|IR_9600|IR_19200|IR_38400 |IR_57600|IR_115200; @@ -123,7 +123,7 @@ static void ma600_close(dongle_t *self) { - IRDA_DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, "%s()\n", __FUNCTION__); /* Power off dongle */ self->set_dtr_rts(self->dev, FALSE, FALSE); @@ -184,12 +184,12 @@ __u8 byte_echo; int ret = 0; - IRDA_DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, "%s()\n", __FUNCTION__); ASSERT(task != NULL, return -1;); if (self->speed_task && self->speed_task != task) { - IRDA_DEBUG(0, __FUNCTION__ "(), busy!\n"); + IRDA_DEBUG(0, "%s(), busy!\n", __FUNCTION__); return MSECS_TO_JIFFIES(10); } else { self->speed_task = task; @@ -215,7 +215,7 @@ break; case IRDA_TASK_CHILD_WAIT: - WARNING(__FUNCTION__ "(), resetting dongle timed out!\n"); + WARNING("%s(), resetting dongle timed out!\n", __FUNCTION__); ret = -1; break; @@ -246,7 +246,7 @@ if(byte != byte_echo) { /* if control byte != echo, I don't know what to do */ - printk(KERN_WARNING __FUNCTION__ "() control byte written != read!\n"); + printk(KERN_WARNING "%s() control byte written != read!\n", __FUNCTION__); printk(KERN_WARNING "control byte = 0x%c%c\n", hexTbl[(byte>>4)&0x0f], hexTbl[byte&0x0f]); printk(KERN_WARNING "byte echo = 0x%c%c\n", @@ -254,7 +254,7 @@ hexTbl[byte_echo & 0x0f]); #ifndef NDEBUG } else { - IRDA_DEBUG(2, __FUNCTION__ "() control byte write read OK\n"); + IRDA_DEBUG(2, "%s() control byte write read OK\n", __FUNCTION__); #endif } @@ -273,7 +273,7 @@ break; default: - ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + ERROR("%s(), unknown state %d\n", __FUNCTION__, task->state); irda_task_next_state(task, IRDA_TASK_DONE); self->speed_task = NULL; ret = -1; @@ -298,12 +298,12 @@ dongle_t *self = (dongle_t *) task->instance; int ret = 0; - IRDA_DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, "%s()\n", __FUNCTION__); ASSERT(task != NULL, return -1;); if (self->reset_task && self->reset_task != task) { - IRDA_DEBUG(0, __FUNCTION__ "(), busy!\n"); + IRDA_DEBUG(0, "%s(), busy!\n", __FUNCTION__); return MSECS_TO_JIFFIES(10); } else self->reset_task = task; @@ -326,7 +326,7 @@ self->reset_task = NULL; break; default: - ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + ERROR("%s(), unknown state %d\n", __FUNCTION__, task->state); irda_task_next_state(task, IRDA_TASK_DONE); self->reset_task = NULL; ret = -1; Index: drivers/net/irda/mcp2120.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/irda/mcp2120.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/irda/mcp2120.c 22 Jul 2004 19:49:37 -0000 1.1 +++ drivers/net/irda/mcp2120.c 4 Aug 2004 01:29:20 -0000 1.2 @@ -110,7 +110,7 @@ } break; case IRDA_TASK_CHILD_WAIT: - WARNING(__FUNCTION__ "(), resetting dongle timed out!\n"); + WARNING("%s(), resetting dongle timed out!\n", __FUNCTION__); ret = -1; break; case IRDA_TASK_CHILD_DONE: @@ -158,7 +158,7 @@ //printk("mcp2120_change_speed irda_task_wait\n"); break; default: - ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + ERROR("%s(), unknown state %d\n", __FUNCTION__, task->state); irda_task_next_state(task, IRDA_TASK_DONE); self->speed_task = NULL; ret = -1; @@ -213,7 +213,7 @@ self->reset_task = NULL; break; default: - ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + ERROR("%s(), unknown state %d\n", __FUNCTION__ , task->state); irda_task_next_state(task, IRDA_TASK_DONE); self->reset_task = NULL; ret = -1; Index: drivers/net/irda/nsc-ircc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/irda/nsc-ircc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/irda/nsc-ircc.c 22 Jul 2004 19:49:37 -0000 1.1 +++ drivers/net/irda/nsc-ircc.c 4 Aug 2004 01:29:20 -0000 1.2 @@ -83,8 +83,10 @@ static int nsc_ircc_probe_108(nsc_chip_t *chip, chipio_t *info); static int nsc_ircc_probe_338(nsc_chip_t *chip, chipio_t *info); +static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info); static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info); static int nsc_ircc_init_338(nsc_chip_t *chip, chipio_t *info); +static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info); /* These are the known NSC chips */ static nsc_chip_t chips[] = { @@ -93,10 +95,16 @@ nsc_ircc_probe_108, nsc_ircc_init_108 }, { "PC87338", { 0x398, 0x15c, 0x2e }, 0x08, 0xb0, 0xf8, nsc_ircc_probe_338, nsc_ircc_init_338 }, + /* Contributed by Jan Frey - IBM A30/A31 */ + { "PC8739x", { 0x2e, 0x4e, 0x0 }, 0x20, 0xea, 0xff, + nsc_ircc_probe_39x, nsc_ircc_init_39x }, + { NULL } +#if 0 + /* Probably bogus, "PC8739x" should be the real thing. Jean II */ /* Contributed by Kevin Thayer - OmniBook 6100 */ { "PC87338?", { 0x2e, 0x15c, 0x398 }, 0x08, 0x00, 0xf8, nsc_ircc_probe_338, nsc_ircc_init_338 }, - { NULL } +#endif }; /* Max 4 instances for now */ @@ -439,7 +447,7 @@ outb(0x00, cfg_base+1); /* Disable device */ /* Base Address and Interrupt Control Register (BAIC) */ - outb(0, cfg_base); + outb(CFG_108_BAIC, cfg_base); switch (info->fir_base) { case 0x3e8: outb(0x14, cfg_base+1); break; case 0x2e8: outb(0x15, cfg_base+1); break; @@ -459,7 +467,7 @@ case 15: temp = 0x07; break; default: ERROR("%s(), invalid irq", __FUNCTION__); } - outb(1, cfg_base); + outb(CFG_108_CSRT, cfg_base); switch (info->dma) { case 0: outb(0x08+temp, cfg_base+1); break; @@ -468,7 +476,7 @@ default: ERROR("%s(), invalid dma", __FUNCTION__); } - outb(2, cfg_base); /* Mode Control Register (MCTL) */ + outb(CFG_108_MCTL, cfg_base); /* Mode Control Register (MCTL) */ outb(0x03, cfg_base+1); /* Enable device */ return 0; @@ -486,7 +494,7 @@ int reg; /* Read address and interrupt control register (BAIC) */ - outb(CFG_BAIC, cfg_base); + outb(CFG_108_BAIC, cfg_base); reg = inb(cfg_base+1); switch (reg & 0x03) { @@ -508,7 +516,7 @@ __FUNCTION__, info->fir_base); /* Read control signals routing register (CSRT) */ - outb(CFG_CSRT, cfg_base); + outb(CFG_108_CSRT, cfg_base); reg = inb(cfg_base+1); switch (reg & 0x07) { @@ -557,7 +565,7 @@ IRDA_DEBUG(2, "%s(), probing dma=%d\n", __FUNCTION__, info->dma); /* Read mode control register (MCTL) */ - outb(CFG_MCTL, cfg_base); + outb(CFG_108_MCTL, cfg_base); reg = inb(cfg_base+1); info->enabled = reg & 0x01; @@ -594,13 +602,13 @@ int pnp; /* Read funtion enable register (FER) */ - outb(CFG_FER, cfg_base); + outb(CFG_338_FER, cfg_base); reg = inb(cfg_base+1); info->enabled = (reg >> 2) & 0x01; /* Check if we are in Legacy or PnP mode */ - outb(CFG_PNP0, cfg_base); + outb(CFG_338_PNP0, cfg_base); reg = inb(cfg_base+1); pnp = (reg >> 3) & 0x01; @@ -615,7 +623,7 @@ info->fir_base = reg; } else { /* Read function address register (FAR) */ - outb(CFG_FAR, cfg_base); + outb(CFG_338_FAR, cfg_base); reg = inb(cfg_base+1); switch ((reg >> 4) & 0x03) { @@ -665,19 +673,19 @@ info->sir_base = info->fir_base; /* Read PnP register 1 (PNP1) */ - outb(CFG_PNP1, cfg_base); + outb(CFG_338_PNP1, cfg_base); reg = inb(cfg_base+1); info->irq = reg >> 4; /* Read PnP register 3 (PNP3) */ - outb(CFG_PNP3, cfg_base); + outb(CFG_338_PNP3, cfg_base); reg = inb(cfg_base+1); info->dma = (reg & 0x07) - 1; /* Read power and test register (PTR) */ - outb(CFG_PTR, cfg_base); + outb(CFG_338_PTR, cfg_base); reg = inb(cfg_base+1); info->suspended = reg & 0x01; @@ -685,6 +693,130 @@ return 0; } + +/* + * Function nsc_ircc_init_39x (chip, info) + * + * Now that we know it's a '39x (see probe below), we need to + * configure it so we can use it. + * + * The NSC '338 chip is a Super I/O chip with a "bank" architecture, + * the configuration of the different functionality (serial, parallel, + * floppy...) are each in a different bank (Logical Device Number). + * The base address, irq and dma configuration registers are common + * to all functionalities (index 0x30 to 0x7F). + * There is only one configuration register specific to the + * serial port, CFG_39X_SPC. + * JeanII + * + * Note : this code was written by Jan Frey + */ +static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info) +{ + int cfg_base = info->cfg_base; + int enabled; + + /* User is shure about his config... accept it. */ + IRDA_DEBUG(2, "%s(): nsc_ircc_init_39x (user settings): " + "io=0x%04x, irq=%d, dma=%d\n", + __FUNCTION__, info->fir_base, info->irq, info->dma); + + /* Access bank for SP2 */ + outb(CFG_39X_LDN, cfg_base); + outb(0x02, cfg_base+1); + + /* Configure SP2 */ + + /* We want to enable the device if not enabled */ + outb(CFG_39X_ACT, cfg_base); + enabled = inb(cfg_base+1) & 0x01; + + if (!enabled) { + /* Enable the device */ + outb(CFG_39X_SIOCF1, cfg_base); + outb(0x01, cfg_base+1); + /* May want to update info->enabled. Jean II */ + } + + /* Enable UART bank switching (bit 7) ; Sets the chip to normal + * power mode (wake up from sleep mode) (bit 1) */ + outb(CFG_39X_SPC, cfg_base); + outb(0x82, cfg_base+1); + + return 0; +} + +/* + * Function nsc_ircc_probe_39x (chip, info) + * + * Test if we really have a '39x chip at the given address + * + * Note : this code was written by Jan Frey + */ +static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info) +{ + int cfg_base = info->cfg_base; + int reg1, reg2, irq, irqt, dma1, dma2; + int enabled, susp; + + IRDA_DEBUG(2, "%s(), nsc_ircc_probe_39x, base=%d\n", + __FUNCTION__, cfg_base); + + /* This function should be executed with irq off to avoid + * another driver messing with the Super I/O bank - Jean II */ + + /* Access bank for SP2 */ + outb(CFG_39X_LDN, cfg_base); + outb(0x02, cfg_base+1); + + /* Read infos about SP2 ; store in info struct */ + outb(CFG_39X_BASEH, cfg_base); + reg1 = inb(cfg_base+1); + outb(CFG_39X_BASEL, cfg_base); + reg2 = inb(cfg_base+1); + info->fir_base = (reg1 << 8) | reg2; + + outb(CFG_39X_IRQNUM, cfg_base); + irq = inb(cfg_base+1); + outb(CFG_39X_IRQSEL, cfg_base); + irqt = inb(cfg_base+1); + info->irq = irq; + + outb(CFG_39X_DMA0, cfg_base); + dma1 = inb(cfg_base+1); + outb(CFG_39X_DMA1, cfg_base); + dma2 = inb(cfg_base+1); + info->dma = dma1 -1; + + outb(CFG_39X_ACT, cfg_base); + info->enabled = enabled = inb(cfg_base+1) & 0x01; + + outb(CFG_39X_SPC, cfg_base); + susp = 1 - ((inb(cfg_base+1) & 0x02) >> 1); + + IRDA_DEBUG(2, "%s(): io=0x%02x%02x, irq=%d (type %d), rxdma=%d, txdma=%d, enabled=%d (suspended=%d)\n", __FUNCTION__, reg1,reg2,irq,irqt,dma1,dma2,enabled,susp); + + /* Configure SP2 */ + + /* We want to enable the device if not enabled */ + outb(CFG_39X_ACT, cfg_base); + enabled = inb(cfg_base+1) & 0x01; + + if (!enabled) { + /* Enable the device */ + outb(CFG_39X_SIOCF1, cfg_base); + outb(0x01, cfg_base+1); + /* May want to update info->enabled. Jean II */ + } + + /* Enable UART bank switching (bit 7) ; Sets the chip to normal + * power mode (wake up from sleep mode) (bit 1) */ + outb(CFG_39X_SPC, cfg_base); + outb(0x82, cfg_base+1); + + return 0; +} + /* * Function nsc_ircc_setup (info) * @@ -700,7 +832,7 @@ switch_bank(iobase, BANK3); version = inb(iobase+MID); - IRDA_DEBUG(2, __FUNCTION__ "() Driver %s Found chip version %02x\n", + IRDA_DEBUG(2, "%s() Driver %s Found chip version %02x\n", __FUNCTION__, driver_name, version); /* Should be 0x2? */ Index: drivers/net/irda/smc-ircc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/irda/smc-ircc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/irda/smc-ircc.c 22 Jul 2004 19:49:37 -0000 1.1 +++ drivers/net/irda/smc-ircc.c 4 Aug 2004 01:29:20 -0000 1.2 @@ -1210,7 +1210,7 @@ return ircc_init(); } -void __exit smc_cleanup(void) +static void __exit smc_cleanup(void) { int i; Index: drivers/net/irda/toshoboe.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/irda/toshoboe.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/irda/toshoboe.c 22 Jul 2004 19:49:37 -0000 1.1 +++ drivers/net/irda/toshoboe.c 4 Aug 2004 01:29:20 -0000 1.2 @@ -30,7 +30,7 @@ /* an olivetti notebook which doesn't have FIR, a toshiba libretto, and */ /* an hp printer, this works fine at 4MBPS with my HP printer */ -static char *rcsid = "$Id: toshoboe.c,v 1.1 2004/07/22 19:49:37 joff Exp $"; +static char *rcsid = "$Id: toshoboe.c,v 1.2 2004/08/04 01:29:20 joff Exp $"; /* Define this to have only one frame in the XMIT or RECV queue */ /* Toshiba's drivers do this, but it disables back to back tansfers */ Index: drivers/net/pcmcia/3c574_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/pcmcia/3c574_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/pcmcia/3c574_cs.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/pcmcia/3c574_cs.c 4 Aug 2004 01:29:21 -0000 1.2 @@ -253,6 +253,7 @@ static int el3_close(struct net_device *dev); static void el3_tx_timeout(struct net_device *dev); static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; static void set_rx_mode(struct net_device *dev); static dev_info_t dev_info = "3c574_cs"; @@ -328,6 +329,7 @@ dev->hard_start_xmit = &el3_start_xmit; dev->get_stats = &el3_get_stats; dev->do_ioctl = &el3_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); dev->set_multicast_list = &set_rx_mode; ether_setup(dev); dev->open = &el3_open; @@ -1191,26 +1193,16 @@ return worklimit; } -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strncpy(info.driver, "3c574_cs", sizeof(info.driver)-1); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - } - - return -EOPNOTSUPP; + strcpy(info->driver, "3c574_cs"); } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; + /* Provide ioctl() calls to examine the MII xcvr state. */ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { @@ -1224,11 +1216,11 @@ data[0], data[1], data[2], data[3]); switch(cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *)rq->ifr_data); - case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ + case SIOCGMIIPHY: /* Get the address of the PHY in use. */ + case SIOCDEVPRIVATE: data[0] = phy; - case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ + case SIOCGMIIREG: /* Read the specified MII register. */ + case SIOCDEVPRIVATE+1: { int saved_window; unsigned long flags; @@ -1242,7 +1234,8 @@ restore_flags(flags); return 0; } - case SIOCDEVPRIVATE+2: /* Write the specified MII register */ + case SIOCSMIIREG: /* Write the specified MII register */ + case SIOCDEVPRIVATE+2: { int saved_window; unsigned long flags; Index: drivers/net/pcmcia/3c589_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/pcmcia/3c589_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/pcmcia/3c589_cs.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/pcmcia/3c589_cs.c 4 Aug 2004 01:29:21 -0000 1.2 @@ -165,7 +165,7 @@ static int el3_close(struct net_device *dev); static void el3_tx_timeout(struct net_device *dev); static void set_multicast_list(struct net_device *dev); -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; static dev_info_t dev_info = "3c589_cs"; @@ -256,7 +256,7 @@ dev->tx_timeout = el3_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; #endif - dev->do_ioctl = netdev_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); /* Register with Card Services */ link->next = dev_list; @@ -648,70 +648,33 @@ | AdapterFailure, ioaddr + EL3_CMD); } -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "PCMCIA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr); +} #ifdef PCMCIA_DEBUG - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = pc_debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - pc_debug = edata.data; - return 0; - } -#endif - - default: - break; - } - - return -EOPNOTSUPP; +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return pc_debug; } -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +static void netdev_set_msglevel(struct net_device *dev, u32 level) { - int rc; - - switch (cmd) { - case SIOCETHTOOL: - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - break; - - default: - rc = -EOPNOTSUPP; - break; - } - - return rc; + pc_debug = level; } +#endif /* PCMCIA_DEBUG */ + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +#ifdef PCMCIA_DEBUG + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +#endif /* PCMCIA_DEBUG */ +}; static int el3_config(struct net_device *dev, struct ifmap *map) { Index: drivers/net/pcmcia/aironet4500_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/pcmcia/aironet4500_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/pcmcia/aironet4500_cs.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/pcmcia/aironet4500_cs.c 4 Aug 2004 01:29:21 -0000 1.2 @@ -165,65 +165,33 @@ return ret; } -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "PCMCIA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr); +} #ifdef PCMCIA_DEBUG - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = pc_debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - pc_debug = edata.data; - return 0; - } -#endif - - default: - break; - } - - return -EOPNOTSUPP; +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return pc_debug; } -static int awc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +static void netdev_set_msglevel(struct net_device *dev, u32 level) { - switch (cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - - default: - return -EOPNOTSUPP; - } - return 0; + pc_debug = level; } +#endif /* PCMCIA_DEBUG */ + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +#ifdef PCMCIA_DEBUG + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +#endif /* PCMCIA_DEBUG */ +}; /* awc_attach() creates an "instance" of the driver, allocating @@ -282,7 +250,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; @@ -296,7 +264,7 @@ // dev->set_config = &awc_config_misiganes,aga mitte awc_config; dev->get_stats = &awc_get_stats; // dev->set_multicast_list = &awc_set_multicast_list; - dev->do_ioctl = &awc_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); strcpy(dev->name, ((struct awc_private *)dev->priv)->node.dev_name); Index: drivers/net/pcmcia/axnet_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/pcmcia/axnet_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/pcmcia/axnet_cs.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/pcmcia/axnet_cs.c 4 Aug 2004 01:29:21 -0000 1.2 @@ -99,6 +99,8 @@ static int axnet_open(struct net_device *dev); static int axnet_close(struct net_device *dev); static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; + static void ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs); static void ei_watchdog(u_long arg); static void axnet_reset_8390(struct net_device *dev); @@ -221,6 +223,7 @@ dev->open = &axnet_open; dev->stop = &axnet_close; dev->do_ioctl = &axnet_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); /* Register with Card Services */ link->next = dev_list; @@ -822,26 +825,16 @@ add_timer(&info->watchdog); } -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strncpy(info.driver, "axnet_cs", sizeof(info.driver)-1); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - } - - return -EOPNOTSUPP; + strcpy(info->driver, "axnet_cs"); } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; + /*====================================================================*/ static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) @@ -850,13 +843,14 @@ u16 *data = (u16 *)&rq->ifr_data; ioaddr_t mii_addr = dev->base_addr + AXNET_MII_EEP; switch (cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); + case SIOCGMIIPHY: case SIOCDEVPRIVATE: data[0] = info->phy_id; + case SIOCGMIIREG: /* Read MII PHY register. */ case SIOCDEVPRIVATE+1: data[3] = mdio_read(mii_addr, data[0], data[1] & 0x1f); return 0; + case SIOCSMIIREG: /* Write MII PHY register. */ case SIOCDEVPRIVATE+2: if (!capable(CAP_NET_ADMIN)) return -EPERM; Index: drivers/net/pcmcia/fmvj18x_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/pcmcia/fmvj18x_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/pcmcia/fmvj18x_cs.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/pcmcia/fmvj18x_cs.c 4 Aug 2004 01:29:21 -0000 1.2 @@ -115,7 +115,7 @@ static struct net_device_stats *fjn_get_stats(struct net_device *dev); static void set_rx_mode(struct net_device *dev); static void fjn_tx_timeout(struct net_device *dev); -static int fjn_ioctl(struct net_device *, struct ifreq *, int); +static struct ethtool_ops netdev_ethtool_ops; static dev_info_t dev_info = "fmvj18x_cs"; static dev_link_t *dev_list; @@ -326,7 +326,7 @@ dev->tx_timeout = fjn_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; #endif - dev->do_ioctl = fjn_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); /* Register with Card Services */ link->next = dev_list; @@ -536,6 +536,8 @@ } if (link->io.NumPorts2 != 0) { + link->irq.Attributes = + IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT; ret = mfc_try_io_port(link); if (ret != CS_SUCCESS) goto cs_failed; } else if (cardtype == UNGERMANN) { @@ -1205,64 +1207,33 @@ /*====================================================================*/ -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "PCMCIA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr); +} #ifdef PCMCIA_DEBUG - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = pc_debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - pc_debug = edata.data; - return 0; - } -#endif - - default: - break; - } - - return -EOPNOTSUPP; +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return pc_debug; } -static int fjn_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +static void netdev_set_msglevel(struct net_device *dev, u32 level) { - switch (cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - - default: - return -EOPNOTSUPP; - } + pc_debug = level; } +#endif /* PCMCIA_DEBUG */ + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +#ifdef PCMCIA_DEBUG + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +#endif /* PCMCIA_DEBUG */ +}; static int fjn_config(struct net_device *dev, struct ifmap *map){ return 0; Index: drivers/net/pcmcia/ibmtr_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/pcmcia/ibmtr_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/pcmcia/ibmtr_cs.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/pcmcia/ibmtr_cs.c 4 Aug 2004 01:29:21 -0000 1.2 @@ -166,36 +166,15 @@ CardServices(ReportError, handle, &err); } -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strncpy(info.driver, "ibmtr_cs", sizeof(info.driver)-1); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - } - - return -EOPNOTSUPP; + strcpy(info->driver, "ibmtr_cs"); } -static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - - switch(cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - default: - return -EOPNOTSUPP; - } -} +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; /*====================================================================== @@ -249,7 +228,7 @@ link->irq.Instance = info->dev = dev; dev->init = &ibmtr_probe; - dev->do_ioctl = &private_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); /* Register with Card Services */ link->next = dev_list; Index: drivers/net/pcmcia/netwave_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/pcmcia/netwave_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/pcmcia/netwave_cs.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/pcmcia/netwave_cs.c 4 Aug 2004 01:29:21 -0000 1.2 @@ -247,6 +247,8 @@ #endif static int netwave_ioctl(struct net_device *, struct ifreq *, int); +static struct ethtool_ops netdev_ethtool_ops; + static void set_multicast_list(struct net_device *dev); /* @@ -493,6 +495,7 @@ dev->get_wireless_stats = &netwave_get_wireless_stats; #endif dev->do_ioctl = &netwave_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); dev->tx_timeout = &netwave_watchdog; dev->watchdog_timeo = TX_TIMEOUT; @@ -603,53 +606,34 @@ } } /* netwave_flush_stale_links */ -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr); +} - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; +#ifdef PCMCIA_DEBUG +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return pc_debug; +} - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "PCMCIA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } +static void netdev_set_msglevel(struct net_device *dev, u32 level) +{ + pc_debug = level; +} +#endif /* PCMCIA_DEBUG */ +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, #ifdef PCMCIA_DEBUG - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = pc_debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - pc_debug = edata.data; - return 0; - } -#endif - - default: - break; - } + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +#endif /* PCMCIA_DEBUG */ +}; - return -EOPNOTSUPP; -} /* * Function netwave_ioctl (dev, rq, cmd) * @@ -672,9 +656,6 @@ DEBUG(0, "%s: ->netwave_ioctl(cmd=0x%X)\n", dev->name, cmd); - if (cmd == SIOCETHTOOL) - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - /* Disable interrupts & save flags */ save_flags(flags); cli(); Index: drivers/net/pcmcia/nmclan_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/pcmcia/nmclan_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/pcmcia/nmclan_cs.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/pcmcia/nmclan_cs.c 4 Aug 2004 01:29:21 -0000 1.2 @@ -438,7 +438,8 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt); static void restore_multicast_list(struct net_device *dev); static void set_multicast_list(struct net_device *dev); -static int mace_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; + static dev_link_t *nmclan_attach(void); static void nmclan_detach(dev_link_t *); @@ -520,7 +521,7 @@ dev->set_config = &mace_config; dev->get_stats = &mace_get_stats; dev->set_multicast_list = &set_multicast_list; - dev->do_ioctl = &mace_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); ether_setup(dev); dev->open = &mace_open; dev->stop = &mace_close; @@ -1010,65 +1011,33 @@ return 0; } /* mace_close */ -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "PCMCIA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr); +} #ifdef PCMCIA_DEBUG - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = pc_debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - pc_debug = edata.data; - return 0; - } -#endif - - default: - break; - } - - return -EOPNOTSUPP; +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return pc_debug; } -static int mace_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +static void netdev_set_msglevel(struct net_device *dev, u32 level) { - switch (cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - - default: - return -EOPNOTSUPP; - } - return 0; + pc_debug = level; } +#endif /* PCMCIA_DEBUG */ + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +#ifdef PCMCIA_DEBUG + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +#endif /* PCMCIA_DEBUG */ +}; /* ---------------------------------------------------------------------------- mace_start_xmit Index: drivers/net/pcmcia/pcnet_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/pcmcia/pcnet_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/pcmcia/pcnet_cs.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/pcmcia/pcnet_cs.c 4 Aug 2004 01:29:21 -0000 1.2 @@ -11,7 +11,7 @@ Copyright (C) 1999 David A. Hinds -- dahinds@users.sourceforge.net - pcnet_cs.c 1.149 2002/06/29 06:27:37 + pcnet_cs.c 1.153 2003/11/09 18:53:09 The network driver code is based on Donald Becker's NE2000 code: @@ -75,7 +75,7 @@ MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static char *version = -"pcnet_cs.c 1.149 2002/06/29 06:27:37 (David Hinds)"; +"pcnet_cs.c 1.153 2003/11/09 18:53:09 (David Hinds)"; #else #define DEBUG(n, args...) #endif @@ -117,7 +117,9 @@ static int pcnet_open(struct net_device *dev); static int pcnet_close(struct net_device *dev); static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static int do_ioctl_light(struct net_device *dev, struct ifreq *rq, int cmd); + +static struct ethtool_ops netdev_ethtool_ops; + static void ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs); static void ei_watchdog(u_long arg); static void pcnet_reset_8390(struct net_device *dev); @@ -301,7 +303,8 @@ memset(info, 0, sizeof(*info)); link = &info->link; dev = &info->dev; link->priv = info; - + + init_timer(&link->release); link->release.function = &pcnet_release; link->release.data = (u_long)link; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; @@ -765,6 +768,7 @@ strcpy(info->node.dev_name, dev->name); link->dev = &info->node; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); if (info->flags & (IS_DL10019|IS_DL10022)) { u_char id = inb(dev->base_addr + 0x1a); @@ -778,7 +782,6 @@ printk("PNA, "); } else { printk(KERN_INFO "%s: NE2000 Compatible: ", dev->name); - dev->do_ioctl = &do_ioctl_light; } printk("io %#3lx, irq %d,", dev->base_addr, dev->irq); if (info->flags & USE_SHMEM) @@ -893,13 +896,15 @@ MII interface support for DL10019 and DL10022 based cards - On the DL10019, the MII IO direction bit is 0x10; on the DL10022 + On the DL10019, the MII IO direction bit is 0x10; on the DL10022 it is 0x20. Setting both bits seems to work on both card types. ======================================================================*/ #define DLINK_GPIO 0x1c #define DLINK_DIAG 0x1d +#define DLINK_EEPROM 0x1e + #define MDIO_SHIFT_CLK 0x80 #define MDIO_DATA_OUT 0x40 #define MDIO_DIR_WRITE 0x30 @@ -962,6 +967,98 @@ outb_p(0x00, addr); } +/*====================================================================== + + EEPROM access routines for DL10019 and DL10022 based cards + +======================================================================*/ + +#define EE_EEP 0x40 +#define EE_ASIC 0x10 +#define EE_CS 0x08 +#define EE_CK 0x04 +#define EE_DO 0x02 +#define EE_DI 0x01 +#define EE_ADOT 0x01 /* DataOut for ASIC */ +#define EE_READ_CMD 0x06 + +#define DL19FDUPLX 0x0400 /* DL10019 Full duplex mode */ + +static int read_eeprom(ioaddr_t ioaddr, int location) +{ + int i, retval = 0; + ioaddr_t ee_addr = ioaddr + DLINK_EEPROM; + int read_cmd = location | (EE_READ_CMD << 8); + + outb(0, ee_addr); + outb(EE_EEP|EE_CS, ee_addr); + + /* Shift the read command bits out. */ + for (i = 10; i >= 0; i--) { + short dataval = (read_cmd & (1 << i)) ? EE_DO : 0; + outb_p(EE_EEP|EE_CS|dataval, ee_addr); + outb_p(EE_EEP|EE_CS|dataval|EE_CK, ee_addr); + } + outb(EE_EEP|EE_CS, ee_addr); + + for (i = 16; i > 0; i--) { + outb_p(EE_EEP|EE_CS | EE_CK, ee_addr); + retval = (retval << 1) | ((inb(ee_addr) & EE_DI) ? 1 : 0); + outb_p(EE_EEP|EE_CS, ee_addr); + } + + /* Terminate the EEPROM access. */ + outb(0, ee_addr); + return retval; +} + +/* + The internal ASIC registers can be changed by EEPROM READ access + with EE_ASIC bit set. + In ASIC mode, EE_ADOT is used to output the data to the ASIC. +*/ + +static void write_asic(ioaddr_t ioaddr, int location, short asic_data) +{ + int i; + ioaddr_t ee_addr = ioaddr + DLINK_EEPROM; + short dataval; + int read_cmd = location | (EE_READ_CMD << 8); + + asic_data |= read_eeprom(ioaddr, location); + + outb(0, ee_addr); + outb(EE_ASIC|EE_CS|EE_DI, ee_addr); + + read_cmd = read_cmd >> 1; + + /* Shift the read command bits out. */ + for (i = 9; i >= 0; i--) { + dataval = (read_cmd & (1 << i)) ? EE_DO : 0; + outb_p(EE_ASIC|EE_CS|EE_DI|dataval, ee_addr); + outb_p(EE_ASIC|EE_CS|EE_DI|dataval|EE_CK, ee_addr); + outb_p(EE_ASIC|EE_CS|EE_DI|dataval, ee_addr); + } + // sync + outb(EE_ASIC|EE_CS, ee_addr); + outb(EE_ASIC|EE_CS|EE_CK, ee_addr); + outb(EE_ASIC|EE_CS, ee_addr); + + for (i = 15; i >= 0; i--) { + dataval = (asic_data & (1 << i)) ? EE_ADOT : 0; + outb_p(EE_ASIC|EE_CS|dataval, ee_addr); + outb_p(EE_ASIC|EE_CS|dataval|EE_CK, ee_addr); + outb_p(EE_ASIC|EE_CS|dataval, ee_addr); + } + + /* Terminate the ASIC access. */ + outb(EE_ASIC|EE_DI, ee_addr); + outb(EE_ASIC|EE_DI| EE_CK, ee_addr); + outb(EE_ASIC|EE_DI, ee_addr); + + outb(0, ee_addr); +} + /*====================================================================*/ static void set_misc_reg(struct net_device *dev) @@ -1176,6 +1273,9 @@ if (link && (info->flags & IS_DL10022)) { /* Disable collision detection on full duplex links */ outb((p & 0x0140) ? 4 : 0, nic_base + DLINK_DIAG); + } else if (link && (info->flags & IS_DL10019)) { + /* Disable collision detection on full duplex links */ + write_asic(dev->base_addr, 4, (p & 0x140) ? DL19FDUPLX : 0); } if (link) { if (info->phy_id == info->eth_phy) { @@ -1215,26 +1315,16 @@ /*====================================================================*/ -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strncpy(info.driver, "pcnet_cs", sizeof(info.driver)-1); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - } - - return -EOPNOTSUPP; + strcpy(info->driver, "pcnet_cs"); } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; + /*====================================================================*/ @@ -1244,13 +1334,14 @@ u16 *data = (u16 *)&rq->ifr_data; ioaddr_t mii_addr = dev->base_addr + DLINK_GPIO; switch (cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); + case SIOCGMIIPHY: case SIOCDEVPRIVATE: data[0] = info->phy_id; + case SIOCGMIIREG: /* Read MII PHY register. */ case SIOCDEVPRIVATE+1: data[3] = mdio_read(mii_addr, data[0], data[1] & 0x1f); return 0; + case SIOCSMIIREG: /* Write MII PHY register. */ case SIOCDEVPRIVATE+2: if (!capable(CAP_NET_ADMIN)) return -EPERM; @@ -1262,17 +1353,6 @@ /*====================================================================*/ -static int do_ioctl_light(struct net_device *dev, struct ifreq *rq, int cmd) -{ - switch (cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - } - return -EOPNOTSUPP; -} - -/*====================================================================*/ - static void dma_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) Index: drivers/net/pcmcia/ray_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/pcmcia/ray_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/pcmcia/ray_cs.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/pcmcia/ray_cs.c 4 Aug 2004 01:29:21 -0000 1.2 @@ -105,6 +105,9 @@ static struct net_device_stats *ray_get_stats(struct net_device *dev); static int ray_dev_init(struct net_device *dev); static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); + +static struct ethtool_ops netdev_ethtool_ops; + static int ray_open(struct net_device *dev); static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev); static void set_multicast_list(struct net_device *dev); @@ -417,6 +420,7 @@ dev->set_config = &ray_dev_config; dev->get_stats = &ray_get_stats; dev->do_ioctl = &ray_dev_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); #if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */ dev->get_wireless_stats = ray_get_wireless_stats; #endif @@ -1236,26 +1240,16 @@ /*===========================================================================*/ -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strncpy(info.driver, "ray_cs", sizeof(info.driver)-1); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - } - - return -EOPNOTSUPP; + strcpy(info->driver, "ray_cs"); } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; + /*====================================================================*/ static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) @@ -1275,10 +1269,6 @@ /* Validate the command */ switch (cmd) { - case SIOCETHTOOL: - err = netdev_ethtool_ioctl(dev, (void *) ifr->ifr_data); - break; - #if WIRELESS_EXT > 7 /* --------------- WIRELESS EXTENSIONS --------------- */ /* Get name */ Index: drivers/net/pcmcia/wavelan_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/pcmcia/wavelan_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/pcmcia/wavelan_cs.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/pcmcia/wavelan_cs.c 4 Aug 2004 01:29:21 -0000 1.2 @@ -1890,27 +1890,17 @@ } #endif /* HISTOGRAM */ -static inline int -wl_netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) + +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strncpy(info.driver, "wavelan_cs", sizeof(info.driver)-1); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - } - - return -EOPNOTSUPP; + strcpy(info->driver, "wavelan_cs"); } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; + /*------------------------------------------------------------------*/ /* * Perform ioctl : config & info stuff @@ -1933,9 +1923,6 @@ printk(KERN_DEBUG "%s: ->wavelan_ioctl(cmd=0x%X)\n", dev->name, cmd); #endif - if (cmd == SIOCETHTOOL) - return wl_netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - /* Disable interrupts & save flags */ wv_splhi(lp, &flags); @@ -4568,6 +4555,7 @@ dev->do_ioctl = wavelan_ioctl; /* wireless extensions */ dev->get_wireless_stats = wavelan_get_wireless_stats; #endif + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); /* Other specific data */ dev->mtu = WAVELAN_MTU; Index: drivers/net/pcmcia/wavelan_cs.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/pcmcia/wavelan_cs.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/pcmcia/wavelan_cs.h 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/pcmcia/wavelan_cs.h 4 Aug 2004 01:29:21 -0000 1.2 @@ -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 */ Index: drivers/net/pcmcia/xirc2ps_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/pcmcia/xirc2ps_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/pcmcia/xirc2ps_cs.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/pcmcia/xirc2ps_cs.c 4 Aug 2004 01:29:21 -0000 1.2 @@ -386,6 +386,7 @@ static int do_config(struct net_device *dev, struct ifmap *map); static int do_open(struct net_device *dev); static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; static void hardreset(struct net_device *dev); static void do_reset(struct net_device *dev, int full); static int init_mii(struct net_device *dev); @@ -650,6 +651,7 @@ dev->set_config = &do_config; dev->get_stats = &do_get_stats; dev->do_ioctl = &do_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); dev->set_multicast_list = &set_multicast_list; ether_setup(dev); dev->open = &do_open; @@ -1722,26 +1724,16 @@ return 0; } -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strncpy(info.driver, "xirc2ps_cs", sizeof(info.driver)-1); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - } - - return -EOPNOTSUPP; + strcpy(info->driver, "xirc2ps_cs"); } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; + static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { @@ -1757,15 +1749,16 @@ return -EOPNOTSUPP; switch(cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ + case SIOCGMIIPHY: /* Get the address of the PHY in use. */ + case SIOCDEVPRIVATE: data[0] = 0; /* we have only this address */ /* fall trough */ - case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ + case SIOCGMIIREG: /* Read the specified MII register. */ + case SIOCDEVPRIVATE+1: data[3] = mii_rd(ioaddr, data[0] & 0x1f, data[1] & 0x1f); break; - case SIOCDEVPRIVATE+2: /* Write the specified MII register */ + case SIOCSMIIREG: /* Write the specified MII register */ + case SIOCDEVPRIVATE+2: if (!capable(CAP_NET_ADMIN)) return -EPERM; mii_wr(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2], 16); Index: drivers/net/pcmcia/xircom_cb.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/pcmcia/xircom_cb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/pcmcia/xircom_cb.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/pcmcia/xircom_cb.c 4 Aug 2004 01:29:21 -0000 1.2 @@ -11,13 +11,11 @@ * of the GNU General Public License, incorporated herein by reference. * * - * $Id: xircom_cb.c,v 1.1 2004/07/22 19:49:45 joff Exp $ + * $Id: xircom_cb.c,v 1.2 2004/08/04 01:29:21 joff Exp $ */ - #include #include -#include #include #include #include @@ -30,12 +28,11 @@ #include #include #include + #include #include #include - - #ifdef DEBUG #define enter(x) printk("Enter: %s, %s line %i\n",x,__FILE__,__LINE__) #define leave(x) printk("Leave: %s, %s line %i\n",x,__FILE__,__LINE__) @@ -114,7 +111,7 @@ /* Function prototypes */ static int xircom_probe(struct pci_dev *pdev, const struct pci_device_id *id); static void xircom_remove(struct pci_dev *pdev); -static void xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs); +static irqreturn_t xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev); static int xircom_open(struct net_device *dev); static int xircom_close(struct net_device *dev); @@ -124,7 +121,7 @@ static void investigate_read_descriptor(struct net_device *dev,struct xircom_private *card, int descnr, unsigned int bufferoffset); static void investigate_write_descriptor(struct net_device *dev, struct xircom_private *card, int descnr, unsigned int bufferoffset); static void read_mac_address(struct xircom_private *card); -static void tranceiver_voodoo(struct xircom_private *card); +static void transceiver_voodoo(struct xircom_private *card); static void initialize_card(struct xircom_private *card); static void trigger_transmit(struct xircom_private *card); static void trigger_receive(struct xircom_private *card); @@ -143,17 +140,19 @@ -static struct pci_device_id xircom_pci_table[] __devinitdata = { +static struct pci_device_id xircom_pci_table[] = { {0x115D, 0x0003, PCI_ANY_ID, PCI_ANY_ID,}, {0,}, }; MODULE_DEVICE_TABLE(pci, xircom_pci_table); static struct pci_driver xircom_ops = { - name: "xircom_cb", - id_table: xircom_pci_table, - probe: xircom_probe, - remove: __devexit_p(xircom_remove), + .name = "xircom_cb", + .id_table = xircom_pci_table, + .probe = xircom_probe, + .remove = xircom_remove, + .suspend =NULL, + .resume =NULL }; @@ -176,37 +175,19 @@ } #endif -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) -{ - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strncpy(info.driver, "xircom_cb", sizeof(info.driver)-1); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - } - - return -EOPNOTSUPP; -} - -static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { + struct xircom_private *private = dev->priv; - switch(cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - default: - return -EOPNOTSUPP; - } + strcpy(info->driver, "xircom_cb"); + strcpy(info->bus_info, pci_name(private->pdev)); } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; + /* xircom_probe is the code that gets called on device insertion. it sets up the hardware and registers the device to the networklayer. @@ -244,40 +225,32 @@ return -ENODEV; } - /* Before changing the hardware, allocate the memory. This way, we can fail gracefully if not enough memory is available. */ - private = kmalloc(sizeof(*private),GFP_KERNEL); - memset(private, 0, sizeof(struct xircom_private)); + dev = alloc_etherdev(sizeof(struct xircom_private)); + if (!dev) { + printk(KERN_ERR "xircom_probe: failed to allocate etherdev\n"); + goto device_fail; + } + private = dev->priv; /* Allocate the send/receive buffers */ private->rx_buffer = pci_alloc_consistent(pdev,8192,&private->rx_dma_handle); - if (private->rx_buffer == NULL) { printk(KERN_ERR "xircom_probe: no memory for rx buffer \n"); - kfree(private); - return -ENODEV; + goto rx_buf_fail; } private->tx_buffer = pci_alloc_consistent(pdev,8192,&private->tx_dma_handle); if (private->tx_buffer == NULL) { printk(KERN_ERR "xircom_probe: no memory for tx buffer \n"); - kfree(private->rx_buffer); - kfree(private); - return -ENODEV; - } - dev = init_etherdev(dev, 0); - if (dev == NULL) { - printk(KERN_ERR "xircom_probe: failed to allocate etherdev\n"); - kfree(private->rx_buffer); - kfree(private->tx_buffer); - kfree(private); - return -ENODEV; + goto tx_buf_fail; } + SET_MODULE_OWNER(dev); - printk(KERN_INFO "%s: Xircom cardbus revision %i at irq %i \n", dev->name, chip_rev, pdev->irq); + private->dev = dev; private->pdev = pdev; @@ -285,32 +258,47 @@ private->lock = SPIN_LOCK_UNLOCKED; dev->irq = pdev->irq; dev->base_addr = private->io_port; - + initialize_card(private); read_mac_address(private); setup_descriptors(private); - + dev->open = &xircom_open; dev->hard_start_xmit = &xircom_start_xmit; dev->stop = &xircom_close; dev->get_stats = &xircom_get_stats; dev->priv = private; - dev->do_ioctl = &private_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); pci_set_drvdata(pdev, dev); + if (register_netdev(dev)) { + printk(KERN_ERR "xircom_probe: netdevice registration failed.\n"); + goto reg_fail; + } + + printk(KERN_INFO "%s: Xircom cardbus revision %i at irq %i \n", dev->name, chip_rev, pdev->irq); /* start the transmitter to get a heartbeat */ /* TODO: send 2 dummy packets here */ - tranceiver_voodoo(private); - + transceiver_voodoo(private); + spin_lock_irqsave(&private->lock,flags); - activate_transmitter(private); - activate_receiver(private); + activate_transmitter(private); + activate_receiver(private); spin_unlock_irqrestore(&private->lock,flags); - + trigger_receive(private); - + leave("xircom_probe"); return 0; + +reg_fail: + kfree(private->tx_buffer); +tx_buf_fail: + kfree(private->rx_buffer); +rx_buf_fail: + free_netdev(dev); +device_fail: + return -ENODEV; } @@ -323,27 +311,20 @@ static void __devexit xircom_remove(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); - struct xircom_private *card; + struct xircom_private *card = dev->priv; + enter("xircom_remove"); - if (dev!=NULL) { - card=dev->priv; - if (card!=NULL) { - if (card->rx_buffer!=NULL) - pci_free_consistent(pdev,8192,card->rx_buffer,card->rx_dma_handle); - card->rx_buffer = NULL; - if (card->tx_buffer!=NULL) - pci_free_consistent(pdev,8192,card->tx_buffer,card->tx_dma_handle); - card->tx_buffer = NULL; - } - kfree(card); - } + pci_free_consistent(pdev,8192,card->rx_buffer,card->rx_dma_handle); + pci_free_consistent(pdev,8192,card->tx_buffer,card->tx_dma_handle); + release_region(dev->base_addr, 128); unregister_netdev(dev); - kfree(dev); + free_netdev(dev); + pci_set_drvdata(pdev, NULL); leave("xircom_remove"); } -static void xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs) +static irqreturn_t xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_instance; struct xircom_private *card = (struct xircom_private *) dev->priv; @@ -360,6 +341,11 @@ printk("tx status 0x%08x 0x%08x \n",card->tx_buffer[0],card->tx_buffer[4]); printk("rx status 0x%08x 0x%08x \n",card->rx_buffer[0],card->rx_buffer[4]); #endif + /* Handle shared irq and hotplug */ + if (status == 0 || status == 0xffffffff) { + spin_unlock(&card->lock); + return; + } if (link_status_changed(card)) { int newlink; @@ -387,6 +373,7 @@ spin_unlock(&card->lock); leave("xircom_interrupt"); + return IRQ_HANDLED; } static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev) @@ -1040,7 +1027,7 @@ /* -link_status() checks the link's status and will return 0 for no link, 10 for 10mbit link and 100 for.. guess what. +link_status() checks the the links status and will return 0 for no link, 10 for 10mbit link and 100 for.. guess what. Must be called in locked state with interrupts disabled */ @@ -1115,15 +1102,15 @@ /* - tranceiver_voodoo() enables the external UTP plug thingy. + transceiver_voodoo() enables the external UTP plug thingy. it's called voodoo as I stole this code and cannot cross-reference it with the specification. */ -static void tranceiver_voodoo(struct xircom_private *card) +static void transceiver_voodoo(struct xircom_private *card) { unsigned long flags; - enter("tranceiver_voodoo"); + enter("transceiver_voodoo"); /* disable all powermanagement */ pci_write_config_dword(card->pdev, PCI_POWERMGMT, 0x0000); @@ -1142,7 +1129,7 @@ spin_unlock_irqrestore(&card->lock, flags); netif_start_queue(card->dev); - leave("tranceiver_voodoo"); + leave("transceiver_voodoo"); } Index: drivers/net/sk98lin/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/Makefile 22 Jul 2004 19:49:43 -0000 1.1 +++ drivers/net/sk98lin/Makefile 4 Aug 2004 01:29:22 -0000 1.2 @@ -3,11 +3,32 @@ # Makefile for the SysKonnect SK-98xx device driver. # +# +# Standalone driver params +# SKPARAM += -DSK_KERNEL_24 +# SKPARAM += -DSK_KERNEL_24_26 +# SKPARAM += -DSK_KERNEL_26 +# SKPARAM += -DSK_KERNEL_22_24 + O_TARGET := sk98lin.o -obj-y := skge.o skaddr.o skgehwt.o skgeinit.o skgepnmi.o skgesirq.o \ - ski2c.o sklm80.o skqueue.o skrlmt.o sktimer.o skvpd.o \ - skxmac2.o skproc.o skcsum.o +obj-y := \ + skge.o \ + skdim.o \ + skaddr.o \ + skgehwt.o \ + skgeinit.o \ + skgepnmi.o \ + skgesirq.o \ + ski2c.o \ + sklm80.o \ + skqueue.o \ + skrlmt.o \ + sktimer.o \ + skvpd.o \ + skxmac2.o \ + skproc.o \ + skcsum.o obj-m := $(O_TARGET) # DBGDEF = \ @@ -57,7 +78,7 @@ # SK_DBGCAT_DRV_INT_SRC 0x04000000 interrupts sources # SK_DBGCAT_DRV_EVENT 0x08000000 driver events -EXTRA_CFLAGS += -I. -DSK_USE_CSUM $(DBGDEF) +EXTRA_CFLAGS += -I. -DSK_DIAG_SUPPORT -DSK_USE_CSUM -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM) include $(TOPDIR)/Rules.make Index: drivers/net/sk98lin/skaddr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/skaddr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/skaddr.c 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/skaddr.c 4 Aug 2004 01:29:22 -0000 1.2 @@ -1,9 +1,7 @@ /****************************************************************************** * * Name: skaddr.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ + * Project: Gigabit Ethernet Adapters, ADDR-Module * Purpose: Manage Addresses (Multicast and Unicast) and Promiscuous Mode. * ******************************************************************************/ @@ -11,6 +9,7 @@ /****************************************************************************** * * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,182 +22,6 @@ /****************************************************************************** * - * History: - * - * $Log: skaddr.c,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.47 2002/09/17 06:31:10 tschilli - * Handling of SK_PROM_MODE_ALL_MC flag in SkAddrGmacMcUpdate() - * and SkAddrGmacPromiscuousChange() fixed. - * Editorial changes. - * - * Revision 1.46 2002/08/22 07:55:41 tschilli - * New function SkGmacMcHash() for GMAC multicast hashing algorithm added. - * Editorial changes. - * - * Revision 1.45 2002/08/15 12:29:35 tschilli - * SkAddrGmacMcUpdate() and SkAddrGmacPromiscuousChange() changed. - * - * Revision 1.44 2002/08/14 12:18:03 rschmidt - * Replaced direct handling of MAC Hashing (XMAC and GMAC) - * with routine SkMacHashing(). - * Replaced wrong 3rd para 'i' with 'PortNumber' in SkMacPromiscMode(). - * - * Revision 1.43 2002/08/13 09:37:43 rschmidt - * Corrected some SK_DBG_MSG outputs. - * Replaced wrong 2nd para pAC with IoC in SkMacPromiscMode(). - * Editorial changes. - * - * Revision 1.42 2002/08/12 11:24:36 rschmidt - * Remove setting of logical MAC address GM_SRC_ADDR_2 in SkAddrInit(). - * Replaced direct handling of MAC Promiscuous Mode (XMAC and GMAC) - * with routine SkMacPromiscMode(). - * Editorial changes. - * - * Revision 1.41 2002/06/10 13:52:18 tschilli - * Changes for handling YUKON. - * All changes are internally and not visible to the programmer - * using this module. - * - * Revision 1.40 2001/02/14 14:04:59 rassmann - * Editorial changes. - * - * Revision 1.39 2001/01/30 10:30:04 rassmann - * Editorial changes. - * - * Revision 1.38 2001/01/25 16:26:52 rassmann - * Ensured that logical address overrides are done on net's active port. - * - * Revision 1.37 2001/01/22 13:41:34 rassmann - * Supporting two nets on dual-port adapters. - * - * Revision 1.36 2000/08/07 11:10:39 rassmann - * Editorial changes. - * - * Revision 1.35 2000/05/04 09:38:41 rassmann - * Editorial changes. - * Corrected multicast address hashing. - * - * Revision 1.34 1999/11/22 13:23:44 cgoos - * Changed license header to GPL. - * - * Revision 1.33 1999/05/28 10:56:06 rassmann - * Editorial changes. - * - * Revision 1.32 1999/03/31 10:59:20 rassmann - * Returning Success instead of DupAddr if address shall be overridden - * with same value. - * - * Revision 1.31 1999/01/14 16:18:17 rassmann - * Corrected multicast initialization. - * - * Revision 1.30 1999/01/04 10:30:35 rassmann - * SkAddrOverride only possible after SK_INIT_IO phase. - * - * Revision 1.29 1998/12/29 13:13:10 rassmann - * An address override is now preserved in the SK_INIT_IO phase. - * All functions return an int now. - * Extended parameter checking. - * - * Revision 1.28 1998/12/01 11:45:53 rassmann - * Code cleanup. - * - * Revision 1.27 1998/12/01 09:22:49 rassmann - * SkAddrMcAdd and SkAddrMcUpdate returned SK_MC_FILTERING_INEXACT - * too often. - * - * Revision 1.26 1998/11/24 12:39:44 rassmann - * Reserved multicast entry for BPDU address. - * 13 multicast entries left for protocol. - * - * Revision 1.25 1998/11/17 16:54:23 rassmann - * Using exact match for up to 14 multicast addresses. - * Still receiving all multicasts if more addresses are added. - * - * Revision 1.24 1998/11/13 17:24:31 rassmann - * Changed return value of SkAddrOverride to int. - * - * Revision 1.23 1998/11/13 16:56:18 rassmann - * Added macro SK_ADDR_COMPARE. - * Changed return type of SkAddrOverride to SK_BOOL. - * - * Revision 1.22 1998/11/04 17:06:17 rassmann - * Corrected McUpdate and PromiscuousChange functions. - * - * Revision 1.21 1998/10/29 14:34:04 rassmann - * Clearing SK_ADDR struct at startup. - * - * Revision 1.20 1998/10/28 18:16:34 rassmann - * Avoiding I/Os before SK_INIT_RUN level. - * Aligning InexactFilter. - * - * Revision 1.19 1998/10/28 11:29:28 rassmann - * Programming physical address in SkAddrMcUpdate. - * Corrected programming of exact match entries. - * - * Revision 1.18 1998/10/28 10:34:48 rassmann - * Corrected reading of physical addresses. - * - * Revision 1.17 1998/10/28 10:26:13 rassmann - * Getting ports' current MAC addresses from EPROM now. - * Added debug output. - * - * Revision 1.16 1998/10/27 16:20:12 rassmann - * Reading MAC address byte by byte. - * - * Revision 1.15 1998/10/22 11:39:09 rassmann - * Corrected signed/unsigned mismatches. - * - * Revision 1.14 1998/10/19 17:12:35 rassmann - * Syntax corrections. - * - * Revision 1.13 1998/10/19 17:02:19 rassmann - * Now reading permanent MAC addresses from CRF. - * - * Revision 1.12 1998/10/15 15:15:48 rassmann - * Changed Flags Parameters from SK_U8 to int. - * Checked with lint. - * - * Revision 1.11 1998/09/24 19:15:12 rassmann - * Code cleanup. - * - * Revision 1.10 1998/09/18 20:18:54 rassmann - * Added HW access. - * Implemented swapping. - * - * Revision 1.9 1998/09/16 11:32:00 rassmann - * Including skdrv1st.h again. :( - * - * Revision 1.8 1998/09/16 11:09:34 rassmann - * Syntax corrections. - * - * Revision 1.7 1998/09/14 17:06:34 rassmann - * Minor changes. - * - * Revision 1.6 1998/09/07 08:45:41 rassmann - * Syntax corrections. - * - * Revision 1.5 1998/09/04 19:40:19 rassmann - * Interface enhancements. - * - * Revision 1.4 1998/09/04 12:14:12 rassmann - * Interface cleanup. - * - * Revision 1.3 1998/09/02 16:56:40 rassmann - * Updated interface. - * - * Revision 1.2 1998/08/27 14:26:09 rassmann - * Updated interface. - * - * Revision 1.1 1998/08/21 08:30:22 rassmann - * First public version. - * - ******************************************************************************/ - -/****************************************************************************** - * * Description: * * This module is intended to manage multicast addresses, address override, @@ -217,15 +40,14 @@ * ******************************************************************************/ -#ifndef lint +#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "@(#) $Id: skaddr.c,v 1.1 2004/07/22 19:49:44 joff Exp $ (C) SysKonnect."; -#endif /* !defined(lint) */ + "@(#) $Id: skaddr.c,v 1.2 2004/08/04 01:29:22 joff Exp $ (C) Marvell."; +#endif /* DEBUG ||!LINT || !SK_SLIM */ #define __SKADDR_C #ifdef __cplusplus -#error C++ is not yet supported. extern "C" { #endif /* cplusplus */ @@ -260,7 +82,7 @@ /* local variables ************************************************************/ #ifdef DEBUG -static int Next0[SK_MAX_MACS] = {0, 0}; +static int Next0[SK_MAX_MACS] = {0}; #endif /* DEBUG */ /* functions ******************************************************************/ @@ -312,7 +134,8 @@ switch (Level) { case SK_INIT_DATA: - SK_MEMSET((char *) &pAC->Addr, 0, sizeof(SK_ADDR)); + SK_MEMSET((char *) &pAC->Addr, (SK_U8) 0, + (SK_U16) sizeof(SK_ADDR)); for (i = 0; i < SK_MAX_MACS; i++) { pAPort = &pAC->Addr.Port[i]; @@ -334,10 +157,12 @@ /* pAC->Addr.InitDone = SK_INIT_DATA; */ break; - case SK_INIT_IO: + case SK_INIT_IO: +#ifndef SK_NO_RLMT for (i = 0; i < SK_MAX_NETS; i++) { pAC->Addr.Net[i].ActivePort = pAC->Rlmt.Net[i].ActivePort; } +#endif /* !SK_NO_RLMT */ #ifdef xDEBUG for (i = 0; i < SK_MAX_MACS; i++) { if (pAC->Addr.Port[i].NextExactMatchRlmt < @@ -421,13 +246,16 @@ /* Set port's current physical MAC address. */ OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0]; - - if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { +#ifdef GENESIS + if (pAC->GIni.GIGenesis) { XM_OUTADDR(IoC, i, XM_SA, OutAddr); } - else { +#endif /* GENESIS */ +#ifdef YUKON + if (!pAC->GIni.GIGenesis) { GM_OUTADDR(IoC, i, GM_SRC_ADDR_1L, OutAddr); } +#endif /* YUKON */ #ifdef DEBUG SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, ("SkAddrInit: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", @@ -446,7 +274,7 @@ pAPort->CurrentMacAddress.a[3], pAPort->CurrentMacAddress.a[4], pAPort->CurrentMacAddress.a[5])) -#endif /* DEBUG */ +#endif /* DEBUG */ } /* pAC->Addr.InitDone = SK_INIT_IO; */ break; @@ -472,6 +300,7 @@ } /* SkAddrInit */ +#ifndef SK_SLIM /****************************************************************************** * @@ -507,7 +336,7 @@ return (SK_ADDR_ILLEGAL_PORT); } - if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { + if (pAC->GIni.GIGenesis) { ReturnCode = SkAddrXmacMcClear(pAC, IoC, PortNumber, Flags); } else { @@ -518,6 +347,9 @@ } /* SkAddrMcClear */ +#endif /* !SK_SLIM */ + +#ifndef SK_SLIM /****************************************************************************** * @@ -571,6 +403,9 @@ } /* SkAddrXmacMcClear */ +#endif /* !SK_SLIM */ + +#ifndef SK_SLIM /****************************************************************************** * @@ -761,7 +596,7 @@ } /* SkGmacMcHash */ -#endif /* not SK_ADDR_CHEAT */ +#endif /* !SK_ADDR_CHEAT */ /****************************************************************************** * @@ -800,7 +635,7 @@ return (SK_ADDR_ILLEGAL_PORT); } - if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { + if (pAC->GIni.GIGenesis) { ReturnCode = SkAddrXmacMcAdd(pAC, IoC, PortNumber, pMc, Flags); } else { @@ -891,7 +726,7 @@ } else { if (!(pMc->a[0] & SK_MC_BIT)) { - /* Hashing only possible with multicast addresses. */ + /* Hashing only possible with multicast addresses */ return (SK_MC_ILLEGAL_ADDRESS); } #ifndef SK_ADDR_CHEAT @@ -954,7 +789,7 @@ #endif /* !defined(SK_ADDR_CHEAT) */ if (!(pMc->a[0] & SK_MC_BIT)) { - /* Hashing only possible with multicast addresses. */ + /* Hashing only possible with multicast addresses */ return (SK_MC_ILLEGAL_ADDRESS); } @@ -1024,6 +859,7 @@ } /* SkAddrGmacMcAdd */ +#endif /* !SK_SLIM */ /****************************************************************************** * @@ -1055,23 +891,29 @@ SK_U32 PortNumber) /* Port Number */ { int ReturnCode; - +#if (!defined(SK_SLIM) || defined(DEBUG)) if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { return (SK_ADDR_ILLEGAL_PORT); } - - if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { +#endif /* !SK_SLIM || DEBUG */ + +#ifdef GENESIS + if (pAC->GIni.GIGenesis) { ReturnCode = SkAddrXmacMcUpdate(pAC, IoC, PortNumber); } - else { +#endif /* GENESIS */ +#ifdef YUKON + if (!pAC->GIni.GIGenesis) { ReturnCode = SkAddrGmacMcUpdate(pAC, IoC, PortNumber); } - +#endif /* YUKON */ return (ReturnCode); } /* SkAddrMcUpdate */ +#ifdef GENESIS + /****************************************************************************** * * SkAddrXmacMcUpdate - update the HW MC address table and set the MAC address @@ -1111,7 +953,7 @@ #ifdef DEBUG SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber])) -#endif /* DEBUG */ +#endif /* DEBUG */ /* Start with 0 to also program the logical MAC address. */ for (i = 0; i < pAPort->NextExactMatchRlmt; i++) { @@ -1149,7 +991,7 @@ XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash); /* Enable Hashing */ - SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); + SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); } else if (Inexact != 0) { @@ -1157,11 +999,11 @@ XM_OUTHASH(IoC, PortNumber, XM_HSM, &pAPort->InexactFilter.Bytes[0]); /* Enable Hashing */ - SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); + SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); } else { /* Disable Hashing */ - SkMacHashing(pAC, IoC, PortNumber, SK_FALSE); + SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE); } if (pAPort->PromMode != SK_PROM_MODE_NONE) { @@ -1201,7 +1043,7 @@ pAPort->Exact[i].a[4], pAPort->Exact[i].a[5])) } -#endif /* DEBUG */ +#endif /* DEBUG */ /* Determine return value. */ if (Inexact == 0 && pAPort->PromMode == 0) { @@ -1213,6 +1055,9 @@ } /* SkAddrXmacMcUpdate */ +#endif /* GENESIS */ + +#ifdef YUKON /****************************************************************************** * @@ -1240,8 +1085,10 @@ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber) /* Port Number */ { +#ifndef SK_SLIM SK_U32 i; SK_U8 Inexact; +#endif /* not SK_SLIM */ SK_U16 *OutAddr; SK_ADDR_PORT *pAPort; @@ -1253,8 +1100,9 @@ #ifdef DEBUG SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber])) -#endif /* DEBUG */ +#endif /* DEBUG */ +#ifndef SK_SLIM for (Inexact = 0, i = 0; i < 8; i++) { Inexact |= pAPort->InexactFilter.Bytes[i]; } @@ -1269,16 +1117,27 @@ GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash); /* Enable Hashing */ - SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); + SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); } else { /* Enable Hashing. */ - SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); + SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); } if (pAPort->PromMode != SK_PROM_MODE_NONE) { (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode); } +#else /* SK_SLIM */ + + /* Set all bits in 64-bit hash register. */ + GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash); + + /* Enable Hashing */ + SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); + + (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode); + +#endif /* SK_SLIM */ /* Set port's current physical MAC address. */ OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0]; @@ -1306,8 +1165,9 @@ pAPort->CurrentMacAddress.a[3], pAPort->CurrentMacAddress.a[4], pAPort->CurrentMacAddress.a[5])) -#endif /* DEBUG */ +#endif /* DEBUG */ +#ifndef SK_SLIM /* Determine return value. */ if (Inexact == 0 && pAPort->PromMode == 0) { return (SK_MC_FILTERING_EXACT); @@ -1315,9 +1175,15 @@ else { return (SK_MC_FILTERING_INEXACT); } +#else /* SK_SLIM */ + return (SK_MC_FILTERING_INEXACT); +#endif /* SK_SLIM */ } /* SkAddrGmacMcUpdate */ +#endif /* YUKON */ + +#ifndef SK_NO_MAO /****************************************************************************** * @@ -1337,23 +1203,29 @@ * SK_ADDR_TOO_EARLY if SK_INIT_IO was not executed before. */ int SkAddrOverride( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* I/O context */ -SK_U32 PortNumber, /* Port Number */ -SK_MAC_ADDR *pNewAddr, /* new MAC address */ -int Flags) /* logical/physical MAC address */ +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* I/O context */ +SK_U32 PortNumber, /* Port Number */ +SK_MAC_ADDR SK_FAR *pNewAddr, /* new MAC address */ +int Flags) /* logical/physical MAC address */ { +#ifndef SK_NO_RLMT SK_EVPARA Para; +#endif /* !SK_NO_RLMT */ SK_U32 NetNumber; SK_U32 i; - SK_U16 *OutAddr; + SK_U16 SK_FAR *OutAddr; +#ifndef SK_NO_RLMT NetNumber = pAC->Rlmt.Port[PortNumber].Net->NetNumber; - +#else + NetNumber = 0; +#endif /* SK_NO_RLMT */ +#if (!defined(SK_SLIM) || defined(DEBUG)) if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { return (SK_ADDR_ILLEGAL_PORT); } - +#endif /* !SK_SLIM || DEBUG */ if (pNewAddr != NULL && (pNewAddr->a[0] & SK_MC_BIT) != 0) { return (SK_ADDR_MULTICAST_ADDRESS); } @@ -1369,11 +1241,11 @@ return (SK_ADDR_TOO_EARLY); } } - +#ifndef SK_NO_RLMT /* Set PortNumber to number of net's active port. */ PortNumber = pAC->Rlmt.Net[NetNumber]. Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber; - +#endif /* !SK_NO_RLMT */ pAC->Addr.Port[PortNumber].Exact[0] = pAC->Addr.Net[NetNumber].CurrentMacAddress; @@ -1388,11 +1260,11 @@ return (SK_ADDR_TOO_EARLY); } } - +#ifndef SK_NO_RLMT /* Set PortNumber to number of net's active port. */ PortNumber = pAC->Rlmt.Net[NetNumber]. Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber; - +#endif /* !SK_NO_RLMT */ for (i = 0; i < SK_MAC_ADDR_LEN; i++ ) { pAC->Addr.Port[PortNumber].Exact[0].a[i] = 0; } @@ -1427,19 +1299,24 @@ pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr; /* Change port's physical MAC address. */ - OutAddr = (SK_U16 *) pNewAddr; - - if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { + OutAddr = (SK_U16 SK_FAR *) pNewAddr; +#ifdef GENESIS + if (pAC->GIni.GIGenesis) { XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr); } - else { +#endif /* GENESIS */ +#ifdef YUKON + if (!pAC->GIni.GIGenesis) { GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr); } +#endif /* YUKON */ +#ifndef SK_NO_RLMT /* Report address change to RLMT. */ Para.Para32[0] = PortNumber; Para.Para32[0] = -1; SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para); +#endif /* !SK_NO_RLMT */ } else { /* Logical MAC address. */ if (SK_ADDR_EQUAL(pNewAddr->a, @@ -1457,11 +1334,33 @@ return (SK_ADDR_DUPLICATE_ADDRESS); } } - + + /* + * In case that the physical and the logical MAC addresses are equal + * we must also change the physical MAC address here. + * In this case we have an adapter which initially was programmed with + * two identical MAC addresses. + */ + if (SK_ADDR_EQUAL(pAC->Addr.Port[PortNumber].CurrentMacAddress.a, + pAC->Addr.Port[PortNumber].Exact[0].a)) { + + pAC->Addr.Port[PortNumber].PreviousMacAddress = + pAC->Addr.Port[PortNumber].CurrentMacAddress; + pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr; + +#ifndef SK_NO_RLMT + /* Report address change to RLMT. */ + Para.Para32[0] = PortNumber; + Para.Para32[0] = -1; + SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para); +#endif /* !SK_NO_RLMT */ + } + +#ifndef SK_NO_RLMT /* Set PortNumber to number of net's active port. */ PortNumber = pAC->Rlmt.Net[NetNumber]. Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber; - +#endif /* !SK_NO_RLMT */ pAC->Addr.Net[NetNumber].CurrentMacAddress = *pNewAddr; pAC->Addr.Port[PortNumber].Exact[0] = *pNewAddr; #ifdef DEBUG @@ -1482,9 +1381,9 @@ pAC->Addr.Net[NetNumber].CurrentMacAddress.a[3], pAC->Addr.Net[NetNumber].CurrentMacAddress.a[4], pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5])) -#endif /* DEBUG */ +#endif /* DEBUG */ - /* Write address to first exact match entry of active port. */ + /* Write address to first exact match entry of active port. */ (void) SkAddrMcUpdate(pAC, IoC, PortNumber); } @@ -1493,6 +1392,8 @@ } /* SkAddrOverride */ +#endif /* SK_NO_MAO */ + /****************************************************************************** * * SkAddrPromiscuousChange - set promiscuous mode for given port @@ -1522,22 +1423,30 @@ int NewPromMode) /* new promiscuous mode */ { int ReturnCode; - +#if (!defined(SK_SLIM) || defined(DEBUG)) if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { return (SK_ADDR_ILLEGAL_PORT); } - - if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { - ReturnCode = SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode); - } - else { - ReturnCode = SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode); +#endif /* !SK_SLIM || DEBUG */ + +#ifdef GENESIS + if (pAC->GIni.GIGenesis) { + ReturnCode = + SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode); + } +#endif /* GENESIS */ +#ifdef YUKON + if (!pAC->GIni.GIGenesis) { + ReturnCode = + SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode); } +#endif /* YUKON */ return (ReturnCode); } /* SkAddrPromiscuousChange */ +#ifdef GENESIS /****************************************************************************** * @@ -1616,7 +1525,7 @@ XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash); /* Enable Hashing */ - SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); + SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); } else if ((CurPromMode & SK_PROM_MODE_ALL_MC) && !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm MC. */ @@ -1625,7 +1534,7 @@ } if (Inexact == 0) { /* Disable Hashing */ - SkMacHashing(pAC, IoC, PortNumber, SK_FALSE); + SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE); } else { /* Set 64-bit hash register to InexactFilter. */ @@ -1633,25 +1542,28 @@ &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]); /* Enable Hashing */ - SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); + SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); } } if ((NewPromMode & SK_PROM_MODE_LLC) && !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */ /* Set the MAC in Promiscuous Mode */ - SkMacPromiscMode(pAC, IoC, PortNumber, SK_TRUE); + SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE); } else if ((CurPromMode & SK_PROM_MODE_LLC) && !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC. */ /* Clear Promiscuous Mode */ - SkMacPromiscMode(pAC, IoC, PortNumber, SK_FALSE); + SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE); } return (SK_ADDR_SUCCESS); } /* SkAddrXmacPromiscuousChange */ +#endif /* GENESIS */ + +#ifdef YUKON /****************************************************************************** * @@ -1706,7 +1618,7 @@ GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash); /* Enable Hashing */ - SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); + SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); } if ((CurPromMode & SK_PROM_MODE_ALL_MC) && @@ -1717,26 +1629,29 @@ &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]); /* Enable Hashing. */ - SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); + SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); } if ((NewPromMode & SK_PROM_MODE_LLC) && !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */ /* Set the MAC to Promiscuous Mode. */ - SkMacPromiscMode(pAC, IoC, PortNumber, SK_TRUE); + SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE); } else if ((CurPromMode & SK_PROM_MODE_LLC) && !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC */ /* Clear Promiscuous Mode. */ - SkMacPromiscMode(pAC, IoC, PortNumber, SK_FALSE); + SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE); } return (SK_ADDR_SUCCESS); } /* SkAddrGmacPromiscuousChange */ +#endif /* YUKON */ + +#ifndef SK_SLIM /****************************************************************************** * @@ -1808,7 +1723,7 @@ pAC->Addr.Port[FromPortNumber].PromMode = pAC->Addr.Port[ToPortNumber].PromMode; pAC->Addr.Port[ToPortNumber].PromMode = i; - if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { + if (pAC->GIni.GIGenesis) { DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt; pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt = pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt; @@ -1848,6 +1763,8 @@ } /* SkAddrSwap */ +#endif /* !SK_SLIM */ + #ifdef __cplusplus } #endif /* __cplusplus */ Index: drivers/net/sk98lin/skcsum.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/skcsum.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/skcsum.c 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/skcsum.c 4 Aug 2004 01:29:22 -0000 1.2 @@ -2,15 +2,13 @@ * * Name: skcsum.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ * Purpose: Store/verify Internet checksum in send/receive packets. * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2001 SysKonnect GmbH. + * (C)Copyright 1998-2003 SysKonnect GmbH. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,64 +19,11 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: skcsum.c,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.10 2002/04/11 10:02:04 rwahl - * Fix in SkCsGetSendInfo(): - * - function did not return ProtocolFlags in every case. - * - pseudo header csum calculated wrong for big endian. - * - * Revision 1.9 2001/06/13 07:42:08 gklug - * fix: NetNumber was wrong in CLEAR_STAT event - * add: check for good NetNumber in Clear STAT - * - * Revision 1.8 2001/02/06 11:15:36 rassmann - * Supporting two nets on dual-port adapters. - * - * Revision 1.7 2000/06/29 13:17:05 rassmann - * Corrected reception of a packet with UDP checksum == 0 (which means there - * is no UDP checksum). - * - * Revision 1.6 2000/02/21 12:35:10 cgoos - * Fixed license header comment. - * - * Revision 1.5 2000/02/21 11:05:19 cgoos - * Merged changes back to common source. - * Fixed rx path for BIG ENDIAN architecture. - * - * Revision 1.1 1999/07/26 15:28:12 mkarl - * added return SKCS_STATUS_IP_CSUM_ERROR_UDP and - * SKCS_STATUS_IP_CSUM_ERROR_TCP to pass the NidsTester - * changed from common source to windows specific source - * therefore restarting with v1.0 - * - * Revision 1.3 1999/05/10 08:39:33 mkarl - * prevent overflows in SKCS_HTON16 - * fixed a bug in pseudo header checksum calculation - * added some comments - * - * Revision 1.2 1998/10/22 11:53:28 swolf - * Now using SK_DBG_MSG. - * - * Revision 1.1 1998/09/01 15:35:41 swolf - * initial revision - * - * 13-May-1998 sw Created. - * - ******************************************************************************/ - #ifdef SK_USE_CSUM /* Check if CSUM is to be used. */ #ifndef lint -static const char SysKonnectFileId[] = "@(#)" - "$Id: skcsum.c,v 1.1 2004/07/22 19:49:44 joff Exp $" - " (C) SysKonnect."; +static const char SysKonnectFileId[] = + "@(#) $Id: skcsum.c,v 1.2 2004/08/04 01:29:22 joff Exp $ (C) SysKonnect."; #endif /* !lint */ /****************************************************************************** @@ -110,8 +55,8 @@ * * "h/skdrv1st.h" * "h/skcsum.h" - * "h/sktypes.h" - * "h/skqueue.h" + * "h/sktypes.h" + * "h/skqueue.h" * "h/skdrv2nd.h" * ******************************************************************************/ @@ -176,7 +121,7 @@ * little/big endian conversion on little endian machines only. */ #ifdef SK_LITTLE_ENDIAN -#define SKCS_HTON16(Val16) (((unsigned) (Val16) >> 8) | (((Val16) & 0xFF) << 8)) +#define SKCS_HTON16(Val16) (((unsigned) (Val16) >> 8) | (((Val16) & 0xff) << 8)) #endif /* SK_LITTLE_ENDIAN */ #ifdef SK_BIG_ENDIAN #define SKCS_HTON16(Val16) (Val16) @@ -207,7 +152,7 @@ * zero.) * * Note: - * There is a bug in the ASIC which may lead to wrong checksums. + * There is a bug in the GENESIS ASIC which may lead to wrong checksums. * * Arguments: * pAc - A pointer to the adapter context struct. @@ -606,7 +551,7 @@ NextLevelProtocol = *(SK_U8 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL); - if (IpHeaderChecksum != 0xFFFF) { + if (IpHeaderChecksum != 0xffff) { pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxErrCts++; /* the NDIS tester wants to know the upper level protocol too */ if (NextLevelProtocol == SKCS_PROTO_ID_TCP) { @@ -724,7 +669,7 @@ /* Check if the TCP/UDP checksum is ok. */ - if ((unsigned) NextLevelProtocolChecksum == 0xFFFF) { + if ((unsigned) NextLevelProtocolChecksum == 0xffff) { /* TCP/UDP checksum ok. */ @@ -791,7 +736,7 @@ *pChecksum2Offset = SKCS_MAC_HEADER_SIZE + SKCS_IP_HEADER_SIZE; } /* SkCsSetReceiveFlags */ -#ifndef SkCsCalculateChecksum +#ifndef SK_CS_CALCULATE_CHECKSUM /****************************************************************************** * @@ -856,7 +801,7 @@ return ((unsigned) Checksum); } /* SkCsCalculateChecksum */ -#endif /* SkCsCalculateChecksum */ +#endif /* SK_CS_CALCULATE_CHECKSUM */ /****************************************************************************** * @@ -906,12 +851,12 @@ NetNumber = (int)Param.Para32[0]; if (ProtoIndex < 0) { /* Clear for all protocols. */ if (NetNumber >= 0) { - memset(&pAc->Csum.ProtoStats[NetNumber][0], 0, + SK_MEMSET(&pAc->Csum.ProtoStats[NetNumber][0], 0, sizeof(pAc->Csum.ProtoStats[NetNumber])); } } else { /* Clear for individual protocol. */ - memset(&pAc->Csum.ProtoStats[NetNumber][ProtoIndex], 0, + SK_MEMSET(&pAc->Csum.ProtoStats[NetNumber][ProtoIndex], 0, sizeof(pAc->Csum.ProtoStats[NetNumber][ProtoIndex])); } break; Index: drivers/net/sk98lin/skge.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/skge.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/skge.c 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/skge.c 4 Aug 2004 01:29:22 -0000 1.2 @@ -1,37 +1,22 @@ /****************************************************************************** * - * Name: skge.c + * Name: skge.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ + * Version: $Revision: 1.2 $ + * Date: $Date: 2004/08/04 01:29:22 $ * Purpose: The main driver source module * ******************************************************************************/ - + /****************************************************************************** * * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * - * Driver for SysKonnect Gigabit Ethernet Server Adapters: - * - * SK-9871 (single link 1000Base-ZX) - * SK-9872 (dual link 1000Base-ZX) - * SK-9861 (single link 1000Base-SX, VF45 Volition Plug) - * SK-9862 (dual link 1000Base-SX, VF45 Volition Plug) - * SK-9841 (single link 1000Base-LX) - * SK-9842 (dual link 1000Base-LX) - * SK-9843 (single link 1000Base-SX) - * SK-9844 (dual link 1000Base-SX) - * SK-9821 (single link 1000Base-T) - * SK-9822 (dual link 1000Base-T) - * SK-9881 (single link 1000Base-SX V2 LC) - * SK-9871 (single link 1000Base-ZX V2) - * SK-9861 (single link 1000Base-SX V2, VF45 Volition Plug) - * SK-9841 (single link 1000Base-LX V2) - * SK-9843 (single link 1000Base-SX V2) - * SK-9821 (single link 1000Base-T V2) + * Driver for Marvell Yukon chipset and SysKonnect Gigabit Ethernet + * Server Adapters. * - * Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and + * Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and * SysKonnects GEnesis Solaris driver * Author: Christoph Goos (cgoos@syskonnect.de) * Mirko Lindner (mlindner@syskonnect.de) @@ -53,223 +38,13 @@ /****************************************************************************** * - * History: - * - * $Log: skge.c,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.43 2002/11/29 08:42:41 mlindner - * Fix: Boot message - * - * Revision 1.42 2002/11/28 13:30:23 mlindner - * Add: New frame check - * - * Revision 1.41 2002/11/27 13:55:18 mlindner - * Fix: Drop wrong csum packets - * Fix: Initialize proc_entry after hw check - * - * Revision 1.40 2002/10/31 07:50:37 tschilli - * Function SkGeInitAssignRamToQueues() from common module inserted. - * Autonegotiation is set to ON for all adapters. - * LinkSpeedUsed is used in link up status report. - * Role parameter will show up for 1000 Mbps links only. - * GetConfiguration() inserted after init level 1 in SkGeChangeMtu(). - * All return values of SkGeInit() and SkGeInitPort() are checked. - * - * Revision 1.39 2002/10/02 12:56:05 mlindner - * Add: Support for Yukon - * Add: Support for ZEROCOPY, scatter-gather and hw checksum - * Add: New transmit ring function (use SG and TCP/UDP hardware checksumming) - * Add: New init function - * Add: Speed check and setup - * Add: Merge source for kernel 2.2.x and 2.4.x - * Add: Opcode check for tcp - * Add: Frame length check - * Fix: Transmit complete interrupt - * Fix: Interrupt moderation - * - * Revision 1.29.2.13 2002/01/14 12:44:52 mlindner - * Fix: Rlmt modes - * - * Revision 1.29.2.12 2001/12/07 12:06:18 mlindner - * Fix: malloc -> slab changes - * - * Revision 1.29.2.11 2001/12/06 15:19:20 mlindner - * Add: DMA attributes - * Fix: Module initialisation - * Fix: pci_map_single and pci_unmap_single replaced - * - * Revision 1.29.2.10 2001/12/06 09:56:50 mlindner - * Corrected some printk's - * - * Revision 1.29.2.9 2001/09/05 12:15:34 mlindner - * Add: LBFO Changes - * Fix: Counter Errors (Jumbo == to long errors) - * Fix: Changed pAC->PciDev declaration - * Fix: too short counters - * - * Revision 1.29.2.8 2001/06/25 12:10:44 mlindner - * fix: ReceiveIrq() changed. - * - * Revision 1.29.2.7 2001/06/25 08:07:05 mlindner - * fix: RLMT locking in ReceiveIrq() changed. - * - * Revision 1.29.2.6 2001/05/21 07:59:29 mlindner - * fix: MTU init problems - * - * Revision 1.29.2.5 2001/05/08 11:25:08 mlindner - * fix: removed VLAN error message - * - * Revision 1.29.2.4 2001/05/04 13:31:43 gklug - * fix: do not handle eth_copy on bad fragments received. - * - * Revision 1.29.2.3 2001/04/23 08:06:43 mlindner - * Fix: error handling - * - * Revision 1.29.2.2 2001/03/15 12:04:54 mlindner - * Fixed memory problem - * - * Revision 1.29.2.1 2001/03/12 16:41:44 mlindner - * add: procfs function - * add: dual-net function - * add: RLMT networks - * add: extended PNMI features - * - * Kernel 2.4.x specific: - * Revision 1.xx 2000/09/12 13:31:56 cgoos - * Fixed missign "dev=NULL in skge_probe. - * Added counting for jumbo frames (corrects error statistic). - * Removed VLAN tag check (enables VLAN support). - * - * Kernel 2.2.x specific: - * Revision 1.29 2000/02/21 13:31:56 cgoos - * Fixed "unused" warning for UltraSPARC change. - * - * Partially kernel 2.2.x specific: - * Revision 1.28 2000/02/21 10:32:36 cgoos - * Added fixes for UltraSPARC. - * Now printing RlmtMode and PrefPort setting at startup. - * Changed XmitFrame return value. - * Fixed rx checksum calculation for BIG ENDIAN systems. - * Fixed rx jumbo frames counted as ierrors. - * - * - * Revision 1.27 1999/11/25 09:06:28 cgoos - * Changed base_addr to unsigned long. - * - * Revision 1.26 1999/11/22 13:29:16 cgoos - * Changed license header to GPL. - * Changes for inclusion in linux kernel (2.2.13). - * Removed 2.0.x defines. - * Changed SkGeProbe to skge_probe. - * Added checks in SkGeIoctl. - * - * Revision 1.25 1999/10/07 14:47:52 cgoos - * Changed 984x to 98xx. - * - * Revision 1.24 1999/09/30 07:21:01 cgoos - * Removed SK_RLMT_SLOW_LOOKAHEAD option. - * Giving spanning tree packets also to OS now. - * - * Revision 1.23 1999/09/29 07:36:50 cgoos - * Changed assignment for IsBc/IsMc. - * - * Revision 1.22 1999/09/28 12:57:09 cgoos - * Added CheckQueue also to Single-Port-ISR. - * - * Revision 1.21 1999/09/28 12:42:41 cgoos - * Changed parameter strings for RlmtMode. - * - * Revision 1.20 1999/09/28 12:37:57 cgoos - * Added CheckQueue for fast delivery of RLMT frames. - * - * Revision 1.19 1999/09/16 07:57:25 cgoos - * Copperfield changes. - * - * Revision 1.18 1999/09/03 13:06:30 cgoos - * Fixed RlmtMode=CheckSeg bug: wrong DEV_KFREE_SKB in RLMT_SEND caused - * double allocated skb's. - * FrameStat in ReceiveIrq was accessed via wrong Rxd. - * Queue size for async. standby Tx queue was zero. - * FillRxLimit of 0 could cause problems with ReQueue, changed to 1. - * Removed debug output of checksum statistic. - * - * Revision 1.17 1999/08/11 13:55:27 cgoos - * Transmit descriptor polling was not reenabled after SkGePortInit. - * - * Revision 1.16 1999/07/27 15:17:29 cgoos - * Added some "\n" in output strings (removed while debuging...). - * - * Revision 1.15 1999/07/23 12:09:30 cgoos - * Performance optimization, rx checksumming, large frame support. - * - * Revision 1.14 1999/07/14 11:26:27 cgoos - * Removed Link LED settings (now in RLMT). - * Added status output at NET UP. - * Fixed SMP problems with Tx and SWITCH running in parallel. - * Fixed return code problem at RLMT_SEND event. - * - * Revision 1.13 1999/04/07 10:11:42 cgoos - * Fixed Single Port problems. - * Fixed Multi-Adapter problems. - * Always display startup string. - * - * Revision 1.12 1999/03/29 12:26:37 cgoos - * Reversed locking to fine granularity. - * Fixed skb double alloc problem (caused by incorrect xmit return code). - * Enhanced function descriptions. - * - * Revision 1.11 1999/03/15 13:10:51 cgoos - * Changed device identifier in output string to ethX. - * - * Revision 1.10 1999/03/15 12:12:34 cgoos - * Changed copyright notice. - * - * Revision 1.9 1999/03/15 12:10:17 cgoos - * Changed locking to one driver lock. - * Added check of SK_AC-size (for consistency with library). - * - * Revision 1.8 1999/03/08 11:44:02 cgoos - * Fixed missing dev->tbusy in SkGeXmit. - * Changed large frame (jumbo) buffer number. - * Added copying of short frames. - * - * Revision 1.7 1999/03/04 13:26:57 cgoos - * Fixed spinlock calls for SMP. - * - * Revision 1.6 1999/03/02 09:53:51 cgoos - * Added descriptor revertion for big endian machines. - * - * Revision 1.5 1999/03/01 08:50:59 cgoos - * Fixed SkGeChangeMtu. - * Fixed pci config space accesses. - * - * Revision 1.4 1999/02/18 15:48:44 cgoos - * Corrected some printk's. - * - * Revision 1.3 1999/02/18 12:45:55 cgoos - * Changed SK_MAX_CARD_PARAM to default 16 - * - * Revision 1.2 1999/02/18 10:55:32 cgoos - * Removed SkGeDrvTimeStamp function. - * Printing "ethX:" before adapter type at adapter init. - * - * - * 10-Feb-1999 cg Created, based on Linux' acenic.c, 3c59x.c and - * SysKonnects GEnesis Solaris driver - * - ******************************************************************************/ - -/****************************************************************************** - * * Possible compiler options (#define xxx / -Dxxx): * - * debugging can be enable by changing SK_DEBUG_CHKMOD and + * debugging can be enable by changing SK_DEBUG_CHKMOD and * SK_DEBUG_CHKCAT in makefile (described there). * ******************************************************************************/ - + /****************************************************************************** * * Description: @@ -289,7 +64,6 @@ * * * "h/skdrv1st.h" - * * * * @@ -333,39 +107,51 @@ ******************************************************************************/ #include "h/skversion.h" + #include #include + +#ifdef CONFIG_PROC_FS #include +#endif + #include "h/skdrv1st.h" #include "h/skdrv2nd.h" +/******************************************************************************* + * + * Defines + * + ******************************************************************************/ -/* defines ******************************************************************/ /* for debuging on x86 only */ /* #define BREAKPOINT() asm(" int $3"); */ +/* use the transmit hw checksum driver functionality */ +#define USE_SK_TX_CHECKSUM + +/* use the receive hw checksum driver functionality */ +#define USE_SK_RX_CHECKSUM + /* use the scatter-gather functionality with sendfile() */ #define SK_ZEROCOPY /* use of a transmit complete interrupt */ #define USE_TX_COMPLETE -/* use interrupt moderation (for tx complete only) */ -#define USE_INT_MOD -#define INTS_PER_SEC 1800 - /* * threshold for copying small receive frames * set to 0 to avoid copying, set to 9001 to copy all frames */ -#define SK_COPY_THRESHOLD 200 +#define SK_COPY_THRESHOLD 50 /* number of adapters that can be configured via command line params */ #define SK_MAX_CARD_PARAM 16 + /* - * use those defines for a compile-in version of the driver instead + * use those defines for a compile-in version of the driver instead * of command line parameters */ // #define LINK_SPEED_A {"Auto", } @@ -379,23 +165,40 @@ // #define ROLE_A {"Auto", } // #define ROLE_B {"Auto", } // #define PREF_PORT {"A", } +// #define CON_TYPE {"Auto", } // #define RLMT_MODE {"CheckLinkState", } #define DEV_KFREE_SKB(skb) dev_kfree_skb(skb) #define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb) #define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb) -/* function prototypes ******************************************************/ + +/* Set blink mode*/ +#define OEM_CONFIG_VALUE ( SK_ACT_LED_BLINK | \ + SK_DUP_LED_NORMAL | \ + SK_LED_LINK100_ON) + + +/* Isr return value */ +#define SkIsrRetVar void +#define SkIsrRetNone NULL +#define SkIsrRetHandled NULL + + +/******************************************************************************* + * + * Local Function Prototypes + * + ******************************************************************************/ + static void FreeResources(struct SK_NET_DEVICE *dev); static int SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC); static SK_BOOL BoardAllocMem(SK_AC *pAC); static void BoardFreeMem(SK_AC *pAC); static void BoardInitMem(SK_AC *pAC); -static void SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, - int*, SK_BOOL); - -static void SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs); -static void SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs); +static void SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, SK_BOOL); +static SkIsrRetVar SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs); +static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs); static int SkGeOpen(struct SK_NET_DEVICE *dev); static int SkGeClose(struct SK_NET_DEVICE *dev); static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev); @@ -410,48 +213,66 @@ static void FillRxRing(SK_AC*, RX_PORT*); static SK_BOOL FillRxDescriptor(SK_AC*, RX_PORT*); static void ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL); -static void ClearAndStartRx(SK_AC*, int); +static void ClearAndStartRx(SK_AC*, int); static void ClearTxIrq(SK_AC*, int, int); static void ClearRxRing(SK_AC*, RX_PORT*); static void ClearTxRing(SK_AC*, TX_PORT*); -static void SetQueueSizes(SK_AC *pAC); static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int new_mtu); static void PortReInitBmu(SK_AC*, int); static int SkGeIocMib(DEV_NET*, unsigned int, int); +static int SkGeInitPCI(SK_AC *pAC); +static void StartDrvCleanupTimer(SK_AC *pAC); +static void StopDrvCleanupTimer(SK_AC *pAC); static int XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*); -/*Extern */ +#ifdef SK_DIAG_SUPPORT +static SK_U32 ParseDeviceNbrFromSlotName(const char *SlotName); +static int SkDrvInitAdapter(SK_AC *pAC, int devNbr); +static int SkDrvDeInitAdapter(SK_AC *pAC, int devNbr); +#endif + +/******************************************************************************* + * + * Extern Function Prototypes + * + ******************************************************************************/ + +#ifdef CONFIG_PROC_FS +static const char SK_Root_Dir_entry[] = "sk98lin"; +static struct proc_dir_entry *pSkRootDir = NULL; +extern int sk_proc_read( char *buffer, + char **buffer_location, + off_t offset, + int buffer_length, + int *eof, + void *data); +#endif -/* external Proc function */ -extern int proc_read( - char *buffer, - char **buffer_location, - off_t offset, - int buffer_length, - int *eof, - void *data); +extern void SkDimEnableModerationIfNeeded(SK_AC *pAC); +extern void SkDimDisplayModerationSettings(SK_AC *pAC); +extern void SkDimStartModerationTimer(SK_AC *pAC); +extern void SkDimModerate(SK_AC *pAC); #ifdef DEBUG static void DumpMsg(struct sk_buff*, char*); static void DumpData(char*, int); static void DumpLong(char*, int); #endif -void dump_frag( SK_U8 *data, int length); /* global variables *********************************************************/ static const char *BootString = BOOT_STRING; struct SK_NET_DEVICE *SkGeRootDev = NULL; static int probed __initdata = 0; +static SK_BOOL DoPrintInterfaceChange = SK_TRUE; /* local variables **********************************************************/ static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}}; static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480}; -/* local variables **********************************************************/ -const char SK_Root_Dir_entry[8]; - +#ifdef CONFIG_PROC_FS static struct proc_dir_entry *pSkRootDir; +#endif @@ -470,38 +291,40 @@ */ static int __init skge_probe (void) { - int proc_root_initialized = 0; int boards_found = 0; + int vendor_flag = SK_FALSE; SK_AC *pAC; DEV_NET *pNet = NULL; - struct proc_dir_entry *pProcFile; struct pci_dev *pdev = NULL; - unsigned long base_address; struct SK_NET_DEVICE *dev = NULL; SK_BOOL DeviceFound = SK_FALSE; SK_BOOL BootStringCount = SK_FALSE; + int retval; +#ifdef CONFIG_PROC_FS + int proc_root_initialized = 0; + struct proc_dir_entry *pProcFile; +#endif if (probed) return -ENODEV; probed++; - if (!pci_present()) /* is PCI support present? */ + if (!pci_present()) { /* is PCI support present? */ return -ENODEV; + } - while((pdev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET << 8, pdev))) - { + while((pdev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET << 8, pdev))) { dev = NULL; pNet = NULL; - if ((pdev->vendor != PCI_VENDOR_ID_SYSKONNECT) && - ((pdev->device != PCI_DEVICE_ID_SYSKONNECT_GE) || - (pdev->device != PCI_DEVICE_ID_SYSKONNECT_YU))){ + + SK_PCI_ISCOMPLIANT(vendor_flag, pdev); + if (!vendor_flag) continue; - } /* 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; @@ -512,15 +335,11 @@ break; } - if (dev->priv == NULL) { - printk(KERN_ERR "Unable to allocate adapter " - "structure!\n"); - break; - } - pNet = dev->priv; pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL); if (pNet->pAC == NULL){ + unregister_netdev(dev); + dev->get_stats = NULL; kfree(dev->priv); printk(KERN_ERR "Unable to allocate adapter " "structure!\n"); @@ -547,6 +366,14 @@ pNet->Mtu = 1500; pNet->Up = 0; dev->irq = pdev->irq; + retval = SkGeInitPCI(pAC); + if (retval) { + printk("SKGE: PCI setup failed: %i\n", retval); + unregister_netdev(dev); + dev->get_stats = NULL; + kfree(dev); + continue; + } dev->open = &SkGeOpen; dev->stop = &SkGeClose; @@ -559,59 +386,46 @@ dev->flags &= ~IFF_RUNNING; #ifdef SK_ZEROCOPY - if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { +#ifdef USE_SK_TX_CHECKSUM + + if (pAC->ChipsetType) { /* Use only if yukon hardware */ /* SK and ZEROCOPY - fly baby... */ dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; } #endif - - /* - * Dummy value. - */ - dev->base_addr = 42; - pci_set_master(pdev); - - pci_set_master(pdev); - base_address = pci_resource_start (pdev, 0); - -#ifdef SK_BIG_ENDIAN - /* - * On big endian machines, we use the adapter's aibility of - * reading the descriptors as big endian. - */ - { - SK_U32 our2; - SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2); - our2 |= PCI_REV_DESC; - SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2); - } #endif - /* - * Remap the regs into kernel space. - */ - pAC->IoBase = (char*)ioremap(base_address, 0x4000); - - if (!pAC->IoBase){ - printk(KERN_ERR "%s: Unable to map I/O register, " - "SK 98xx No. %i will be disabled.\n", - dev->name, boards_found); - kfree(dev); - break; - } - pAC->Index = boards_found; + if (SkGeBoardInit(dev, pAC)) { - FreeResources(dev); + unregister_netdev(dev); kfree(dev); continue; } + + /* Print adapter specific string from vpd */ + ProductStr(pAC); + printk("%s: %s\n", dev->name, pAC->DeviceStr); + + /* Print configuration settings */ + printk(" PrefPort:%c RlmtMode:%s\n", + 'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber, + (pAC->RlmtMode==0) ? "Check Link State" : + ((pAC->RlmtMode==1) ? "Check Link State" : + ((pAC->RlmtMode==3) ? "Check Local Port" : + ((pAC->RlmtMode==7) ? "Check Segmentation" : + ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error"))))); + + SkGeYellowLED(pAC, pAC->IoBase, 1); + + memcpy((caddr_t) &dev->dev_addr, (caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6); /* First adapter... Create proc and print message */ +#ifdef CONFIG_PROC_FS if (!DeviceFound) { DeviceFound = SK_TRUE; SK_MEMCPY(&SK_Root_Dir_entry, BootString, @@ -621,35 +435,26 @@ if(!proc_root_initialized) { pSkRootDir = create_proc_entry(SK_Root_Dir_entry, S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, proc_net); + pSkRootDir->owner = THIS_MODULE; proc_root_initialized = 1; } - - pSkRootDir->owner = THIS_MODULE; } - - /* Create proc file */ pProcFile = create_proc_entry(dev->name, S_IFREG | S_IXUSR | S_IWGRP | S_IROTH, pSkRootDir); - - pProcFile->read_proc = proc_read; - pProcFile->write_proc = NULL; - pProcFile->nlink = 1; - pProcFile->size = sizeof(dev->name + 1); - pProcFile->data = (void *)pProcFile; + pProcFile->read_proc = sk_proc_read; + pProcFile->write_proc = NULL; + pProcFile->nlink = 1; + pProcFile->size = sizeof(dev->name + 1); + pProcFile->data = (void *)pProcFile; + pProcFile->owner = THIS_MODULE; +#endif pNet->PortNr = 0; - pNet->NetNr = 0; - -#ifdef SK_ZEROCOPY - if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { - /* SG and ZEROCOPY - fly baby... */ - dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; - } -#endif + pNet->NetNr = 0; boards_found++; @@ -661,55 +466,64 @@ break; } - pAC->dev[1] = dev; - pNet = dev->priv; - pNet->PortNr = 1; - pNet->NetNr = 1; - pNet->pAC = pAC; - pNet->Mtu = 1500; - pNet->Up = 0; - - dev->open = &SkGeOpen; - dev->stop = &SkGeClose; - dev->hard_start_xmit = &SkGeXmit; - dev->get_stats = &SkGeStats; + pAC->dev[1] = dev; + pNet = dev->priv; + pNet->PortNr = 1; + pNet->NetNr = 1; + pNet->pAC = pAC; + pNet->Mtu = 1500; + pNet->Up = 0; + + dev->open = &SkGeOpen; + dev->stop = &SkGeClose; + dev->hard_start_xmit = &SkGeXmit; + dev->get_stats = &SkGeStats; dev->set_multicast_list = &SkGeSetRxMode; - dev->set_mac_address = &SkGeSetMacAddr; - dev->do_ioctl = &SkGeIoctl; - dev->change_mtu = &SkGeChangeMtu; - dev->flags &= ~IFF_RUNNING; + dev->set_mac_address = &SkGeSetMacAddr; + dev->do_ioctl = &SkGeIoctl; + dev->change_mtu = &SkGeChangeMtu; + dev->flags &= ~IFF_RUNNING; #ifdef SK_ZEROCOPY - if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { +#ifdef USE_SK_TX_CHECKSUM + if (pAC->ChipsetType) { /* SG and ZEROCOPY - fly baby... */ dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; } #endif +#endif +#ifdef CONFIG_PROC_FS pProcFile = create_proc_entry(dev->name, S_IFREG | S_IXUSR | S_IWGRP | S_IROTH, pSkRootDir); - - - pProcFile->read_proc = proc_read; + pProcFile->read_proc = sk_proc_read; pProcFile->write_proc = NULL; - pProcFile->nlink = 1; - pProcFile->size = sizeof(dev->name + 1); - pProcFile->data = (void *)pProcFile; + pProcFile->nlink = 1; + pProcFile->size = sizeof(dev->name + 1); + pProcFile->data = (void *)pProcFile; + pProcFile->owner = THIS_MODULE; +#endif memcpy((caddr_t) &dev->dev_addr, (caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6); printk("%s: %s\n", dev->name, pAC->DeviceStr); printk(" PrefPort:B RlmtMode:Dual Check Link State\n"); - } - /* Save the hardware revision */ pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) + (pAC->GIni.GIPciHwRev & 0x0F); + /* Set driver globals */ + pAC->Pnmi.pDriverFileName = DRIVER_FILE_NAME; + pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE; + + SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA)); + SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), + sizeof(SK_PNMI_STRUCT_DATA)); + /* * This is bollocks, but we need to tell the net-init * code that it shall go for the next device. @@ -731,6 +545,67 @@ /***************************************************************************** * + * SkGeInitPCI - Init the PCI resources + * + * Description: + * This function initialize the PCI resources and IO + * + * Returns: N/A + * + */ +int SkGeInitPCI(SK_AC *pAC) +{ + struct SK_NET_DEVICE *dev = pAC->dev[0]; + struct pci_dev *pdev = pAC->PciDev; + int retval; + + if (pci_enable_device(pdev) != 0) { + return 1; + } + + dev->mem_start = pci_resource_start (pdev, 0); + pci_set_master(pdev); + + if (pci_request_regions(pdev, pAC->Name) != 0) { + retval = 2; + goto out_disable; + } + +#ifdef SK_BIG_ENDIAN + /* + * On big endian machines, we use the adapter's aibility of + * reading the descriptors as big endian. + */ + { + SK_U32 our2; + SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2); + our2 |= PCI_REV_DESC; + SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2); + } +#endif + + /* + * Remap the regs into kernel space. + */ + pAC->IoBase = (char*)ioremap_nocache(dev->mem_start, 0x4000); + + if (!pAC->IoBase){ + retval = 3; + goto out_release; + } + + return 0; + + out_release: + pci_release_regions(pdev); + out_disable: + pci_disable_device(pdev); + return retval; +} + + +/***************************************************************************** + * * FreeResources - release resources allocated for adapter * * Description: @@ -750,6 +625,9 @@ pNet = (DEV_NET*) dev->priv; pAC = pNet->pAC; AllocFlag = pAC->AllocFlag; + if (pAC->PciDev) { + pci_release_regions(pAC->PciDev); + } if (AllocFlag & SK_ALLOC_IRQ) { free_irq(dev->irq, dev); } @@ -774,13 +652,20 @@ MODULE_PARM(DupCap_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); MODULE_PARM(FlowCtrl_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); MODULE_PARM(FlowCtrl_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -MODULE_PARM(Role_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -MODULE_PARM(Role_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(Role_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(Role_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(ConType, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); MODULE_PARM(PrefPort, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); MODULE_PARM(RlmtMode, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); /* not used, just there because every driver should have them: */ MODULE_PARM(options, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "i"); MODULE_PARM(debug, "i"); +/* used for interrupt moderation */ +MODULE_PARM(IntsPerSec, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "i"); +MODULE_PARM(Moderation, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(Stats, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(ModerationMask, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(AutoSizing, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); #ifdef LINK_SPEED_A @@ -843,6 +728,12 @@ static char *Role_B[SK_MAX_CARD_PARAM] = {"", }; #endif +#ifdef CON_TYPE +static char *ConType[SK_MAX_CARD_PARAM] = CON_TYPE; +#else +static char *ConType[SK_MAX_CARD_PARAM] = {"", }; +#endif + #ifdef PREF_PORT static char *PrefPort[SK_MAX_CARD_PARAM] = PREF_PORT; #else @@ -858,6 +749,12 @@ static int debug = 0; /* not used */ static int options[SK_MAX_CARD_PARAM] = {0, }; /* not used */ +static int IntsPerSec[SK_MAX_CARD_PARAM]; +static char *Moderation[SK_MAX_CARD_PARAM]; +static char *ModerationMask[SK_MAX_CARD_PARAM]; +static char *AutoSizing[SK_MAX_CARD_PARAM]; +static char *Stats[SK_MAX_CARD_PARAM]; + /***************************************************************************** * @@ -881,7 +778,7 @@ cards = skge_probe(); if (cards == 0) { - printk("No adapter found.\n"); + printk("sk98lin: No adapter found.\n"); } return cards ? 0 : -ENODEV; } /* skge_init_module */ @@ -913,7 +810,7 @@ netif_stop_queue(SkGeRootDev); SkGeYellowLED(pAC, pAC->IoBase, 0); - if(pAC->BoardLevel == 2) { + if(pAC->BoardLevel == SK_INIT_RUN) { /* board is still alive */ spin_lock_irqsave(&pAC->SlowPathLock, Flags); EvPara.Para32[0] = 0; @@ -925,16 +822,16 @@ SkEventDispatcher(pAC, pAC->IoBase); /* disable interrupts */ SK_OUT32(pAC->IoBase, B0_IMSK, 0); - SkGeDeInit(pAC, pAC->IoBase); + SkGeDeInit(pAC, pAC->IoBase); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - pAC->BoardLevel = 0; + pAC->BoardLevel = SK_INIT_DATA; /* We do NOT check here, if IRQ was pending, of course*/ } - if(pAC->BoardLevel == 1) { + if(pAC->BoardLevel == SK_INIT_IO) { /* board is still alive */ - SkGeDeInit(pAC, pAC->IoBase); - pAC->BoardLevel = 0; + SkGeDeInit(pAC, pAC->IoBase); + pAC->BoardLevel = SK_INIT_DATA; } if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){ @@ -945,7 +842,7 @@ FreeResources(SkGeRootDev); SkGeRootDev->get_stats = NULL; - /* + /* * otherwise unregister_netdev calls get_stats with * invalid IO ... :-( */ @@ -955,14 +852,17 @@ SkGeRootDev = next; } +#ifdef CONFIG_PROC_FS /* clear proc-dir */ remove_proc_entry(pSkRootDir->name, proc_net); +#endif } /* skge_cleanup_module */ module_init(skge_init_module); module_exit(skge_cleanup_module); + /***************************************************************************** * * SkGeBoardInit - do level 0 and 1 initialization @@ -1005,20 +905,20 @@ spin_lock_irqsave(&pAC->SlowPathLock, Flags); /* Does a RESET on board ...*/ - if (SkGeInit(pAC, pAC->IoBase, 0) != 0) { + if (SkGeInit(pAC, pAC->IoBase, SK_INIT_DATA) != 0) { printk("HWInit (0) failed.\n"); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); return(-EAGAIN); } - SkI2cInit( pAC, pAC->IoBase, 0); - SkEventInit(pAC, pAC->IoBase, 0); - SkPnmiInit( pAC, pAC->IoBase, 0); - SkAddrInit( pAC, pAC->IoBase, 0); - SkRlmtInit( pAC, pAC->IoBase, 0); - SkTimerInit(pAC, pAC->IoBase, 0); - - pAC->BoardLevel = 0; - pAC->RxBufSize = ETH_BUF_SIZE; + SkI2cInit( pAC, pAC->IoBase, SK_INIT_DATA); + SkEventInit(pAC, pAC->IoBase, SK_INIT_DATA); + SkPnmiInit( pAC, pAC->IoBase, SK_INIT_DATA); + SkAddrInit( pAC, pAC->IoBase, SK_INIT_DATA); + SkRlmtInit( pAC, pAC->IoBase, SK_INIT_DATA); + SkTimerInit(pAC, pAC->IoBase, SK_INIT_DATA); + + pAC->BoardLevel = SK_INIT_DATA; + pAC->RxBufSize = ETH_BUF_SIZE; SK_PNMI_SET_DRIVER_DESCR(pAC, DescrString); SK_PNMI_SET_DRIVER_VER(pAC, VerStr); @@ -1027,24 +927,31 @@ /* level 1 init common modules here (HW init) */ spin_lock_irqsave(&pAC->SlowPathLock, Flags); - if (SkGeInit(pAC, pAC->IoBase, 1) != 0) { - printk("HWInit (1) failed.\n"); + if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) { + printk("sk98lin: HWInit (1) failed.\n"); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); return(-EAGAIN); } - SkI2cInit( pAC, pAC->IoBase, 1); - SkEventInit(pAC, pAC->IoBase, 1); - SkPnmiInit( pAC, pAC->IoBase, 1); - SkAddrInit( pAC, pAC->IoBase, 1); - SkRlmtInit( pAC, pAC->IoBase, 1); - SkTimerInit(pAC, pAC->IoBase, 1); + SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO); + SkEventInit(pAC, pAC->IoBase, SK_INIT_IO); + SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO); + SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO); + SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO); + SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO); + + /* Set chipset type support */ + pAC->ChipsetType = 0; + if ((pAC->GIni.GIChipId == CHIP_ID_YUKON) || + (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE)) { + pAC->ChipsetType = 1; + } GetConfiguration(pAC); if (pAC->RlmtNets == 2) { pAC->GIni.GIPortUsage = SK_MUL_LINK; } - pAC->BoardLevel = 1; + pAC->BoardLevel = SK_INIT_IO; spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); if (pAC->GIni.GIMacsFound == 2) { @@ -1053,14 +960,14 @@ Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, pAC->Name, dev); } else { - printk(KERN_WARNING "%s: Illegal number of ports: %d\n", - dev->name, pAC->GIni.GIMacsFound); + printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n", + pAC->GIni.GIMacsFound); return -EAGAIN; } if (Ret) { - printk(KERN_WARNING "%s: Requested IRQ %d is busy.\n", - dev->name, dev->irq); + printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n", + dev->irq); return -EAGAIN; } pAC->AllocFlag |= SK_ALLOC_IRQ; @@ -1077,9 +984,6 @@ pAC->CsOfs = (pAC->CsOfs2 << 16) | pAC->CsOfs1; BoardInitMem(pAC); -#if 0 - SetQueueSizes(pAC); -#else /* tschilling: New common function with minimum size check. */ DualNet = SK_FALSE; if (pAC->RlmtNets == 2) { @@ -1091,25 +995,9 @@ pAC->ActivePort, DualNet)) { BoardFreeMem(pAC); - printk("SkGeInitAssignRamToQueues failed.\n"); + printk("sk98lin: SkGeInitAssignRamToQueues failed.\n"); return(-EAGAIN); } -#endif - - /* Print adapter specific string from vpd */ - ProductStr(pAC); - printk("%s: %s\n", dev->name, pAC->DeviceStr); - - /* Print configuration settings */ - printk(" PrefPort:%c RlmtMode:%s\n", - 'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber, - (pAC->RlmtMode==0) ? "Check Link State" : - ((pAC->RlmtMode==1) ? "Check Link State" : - ((pAC->RlmtMode==3) ? "Check Local Port" : - ((pAC->RlmtMode==7) ? "Check Segmentation" : - ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error"))))); - - SkGeYellowLED(pAC, pAC->IoBase, 1); /* * Register the device here @@ -1309,7 +1197,7 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("Descriptor size: %d Descriptor Number: %d\n", DescrSize,DescrNum)); - + pDescr = (RXD*) pMemArea; pPrevDescr = NULL; pNextDescr = (RXD*) (((char*)pDescr) + DescrSize); @@ -1356,24 +1244,22 @@ ("PortReInitBmu ")); /* set address of first descriptor of ring in BMU */ - SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ - TX_Q_CUR_DESCR_LOW, + SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_L, (uint32_t)(((caddr_t) (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) - pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing + pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) & 0xFFFFFFFF)); - SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ - TX_Q_DESCR_HIGH, + SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_H, (uint32_t)(((caddr_t) (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) - pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing + pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) >> 32)); - SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+RX_Q_CUR_DESCR_LOW, + SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_L, (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) - pAC->RxPort[PortIndex].pRxDescrRing + pAC->RxPort[PortIndex].VRxDescrRing) & 0xFFFFFFFF)); - SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+RX_Q_DESCR_HIGH, + SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_H, (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) - pAC->RxPort[PortIndex].pRxDescrRing + pAC->RxPort[PortIndex].VRxDescrRing) >> 32)); @@ -1392,7 +1278,7 @@ * Returns: N/A * */ -static void SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs) +static SkIsrRetVar SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs) { struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id; DEV_NET *pNet; @@ -1412,20 +1298,20 @@ while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) { #if 0 /* software irq currently not used */ - if (IntSrc & IRQ_SW) { + if (IntSrc & IS_IRQ_SW) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("Software IRQ\n")); } #endif - if (IntSrc & IRQ_EOF_RX1) { + if (IntSrc & IS_R1_F) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF RX1 IRQ\n")); ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); SK_PNMI_CNT_RX_INTR(pAC, 0); } - if (IntSrc & IRQ_EOF_RX2) { + if (IntSrc & IS_R2_F) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF RX2 IRQ\n")); @@ -1433,7 +1319,7 @@ SK_PNMI_CNT_RX_INTR(pAC, 1); } #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ - if (IntSrc & IRQ_EOF_AS_TX1) { + if (IntSrc & IS_XA1_F) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF AS TX1 IRQ\n")); @@ -1442,7 +1328,7 @@ FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]); spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); } - if (IntSrc & IRQ_EOF_AS_TX2) { + if (IntSrc & IS_XA2_F) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF AS TX2 IRQ\n")); @@ -1452,7 +1338,7 @@ spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock); } #if 0 /* only if sync. queues used */ - if (IntSrc & IRQ_EOF_SY_TX1) { + if (IntSrc & IS_XS1_F) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF SY TX1 IRQ\n")); @@ -1462,7 +1348,7 @@ spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); ClearTxIrq(pAC, 0, TX_PRIO_HIGH); } - if (IntSrc & IRQ_EOF_SY_TX2) { + if (IntSrc & IS_XS2_F) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF SY TX2 IRQ\n")); @@ -1476,19 +1362,20 @@ #endif /* do all IO at once */ - if (IntSrc & IRQ_EOF_RX1) + if (IntSrc & IS_R1_F) ClearAndStartRx(pAC, 0); - if (IntSrc & IRQ_EOF_RX2) + if (IntSrc & IS_R2_F) ClearAndStartRx(pAC, 1); #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ - if (IntSrc & IRQ_EOF_AS_TX1) + if (IntSrc & IS_XA1_F) ClearTxIrq(pAC, 0, TX_PRIO_LOW); - if (IntSrc & IRQ_EOF_AS_TX2) + if (IntSrc & IS_XA2_F) ClearTxIrq(pAC, 1, TX_PRIO_LOW); #endif SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc); } /* while (IntSrc & IRQ_MASK != 0) */ + IntSrc &= pAC->GIni.GIValIrqMask; if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("SPECIAL IRQ DP-Cards => %x\n", IntSrc)); @@ -1501,13 +1388,17 @@ spin_unlock(&pAC->SlowPathLock); } /* - * do it all again is case we cleared an interrupt that + * do it all again is case we cleared an interrupt that * came in after handling the ring (OUTs may be delayed * in hardware buffers, but are through after IN) - */ - + * + * rroesler: has been commented out and shifted to + * SkGeDrvEvent(), because it is timer + * guarded now + * ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE); + */ if (pAC->CheckQueue) { pAC->CheckQueue = SK_FALSE; @@ -1516,11 +1407,10 @@ spin_unlock(&pAC->SlowPathLock); } - /* IRQ is processed - Enable IRQs again*/ - SK_OUT32(pAC->IoBase, B0_IMSK, IRQ_MASK); + SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); - return; + return; } /* SkGeIsr */ @@ -1537,7 +1427,7 @@ * Returns: N/A * */ -static void SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs) +static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs) { struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id; DEV_NET *pNet; @@ -1557,13 +1447,13 @@ while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) { #if 0 /* software irq currently not used */ - if (IntSrc & IRQ_SW) { + if (IntSrc & IS_IRQ_SW) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("Software IRQ\n")); } #endif - if (IntSrc & IRQ_EOF_RX1) { + if (IntSrc & IS_R1_F) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF RX1 IRQ\n")); @@ -1571,7 +1461,7 @@ SK_PNMI_CNT_RX_INTR(pAC, 0); } #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ - if (IntSrc & IRQ_EOF_AS_TX1) { + if (IntSrc & IS_XA1_F) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF AS TX1 IRQ\n")); @@ -1581,7 +1471,7 @@ spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); } #if 0 /* only if sync. queues used */ - if (IntSrc & IRQ_EOF_SY_TX1) { + if (IntSrc & IS_XS1_F) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF SY TX1 IRQ\n")); @@ -1595,15 +1485,16 @@ #endif /* do all IO at once */ - if (IntSrc & IRQ_EOF_RX1) + if (IntSrc & IS_R1_F) ClearAndStartRx(pAC, 0); #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ - if (IntSrc & IRQ_EOF_AS_TX1) + if (IntSrc & IS_XA1_F) ClearTxIrq(pAC, 0, TX_PRIO_LOW); #endif SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc); } /* while (IntSrc & IRQ_MASK != 0) */ + IntSrc &= pAC->GIni.GIValIrqMask; if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("SPECIAL IRQ SP-Cards => %x\n", IntSrc)); @@ -1616,16 +1507,21 @@ spin_unlock(&pAC->SlowPathLock); } /* - * do it all again is case we cleared an interrupt that + * do it all again is case we cleared an interrupt that * came in after handling the ring (OUTs may be delayed * in hardware buffers, but are through after IN) - */ + * + * rroesler: has been commented out and shifted to + * SkGeDrvEvent(), because it is timer + * guarded now + * ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); + */ /* IRQ is processed - Enable IRQs again*/ - SK_OUT32(pAC->IoBase, B0_IMSK, IRQ_MASK); + SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); - return; + return; } /* SkGeIsrOnePort */ @@ -1660,34 +1556,47 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC)); - if (pAC->BoardLevel == 0) { +#ifdef SK_DIAG_SUPPORT + if (pAC->DiagModeActive == DIAG_ACTIVE) { + if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { + return (-1); /* still in use by diag; deny actions */ + } + } +#endif + + + /* Set blink mode */ + if ((pAC->PciDev->vendor == 0x1186) || (pAC->PciDev->vendor == 0x11ab )) + pAC->GIni.GILedBlinkCtrl = OEM_CONFIG_VALUE; + + if (pAC->BoardLevel == SK_INIT_DATA) { /* level 1 init common modules here */ - if (SkGeInit(pAC, pAC->IoBase, 1) != 0) { + if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) { printk("%s: HWInit (1) failed.\n", pAC->dev[pNet->PortNr]->name); return (-1); } - SkI2cInit (pAC, pAC->IoBase, 1); - SkEventInit (pAC, pAC->IoBase, 1); - SkPnmiInit (pAC, pAC->IoBase, 1); - SkAddrInit (pAC, pAC->IoBase, 1); - SkRlmtInit (pAC, pAC->IoBase, 1); - SkTimerInit (pAC, pAC->IoBase, 1); - pAC->BoardLevel = 1; + SkI2cInit (pAC, pAC->IoBase, SK_INIT_IO); + SkEventInit (pAC, pAC->IoBase, SK_INIT_IO); + SkPnmiInit (pAC, pAC->IoBase, SK_INIT_IO); + SkAddrInit (pAC, pAC->IoBase, SK_INIT_IO); + SkRlmtInit (pAC, pAC->IoBase, SK_INIT_IO); + SkTimerInit (pAC, pAC->IoBase, SK_INIT_IO); + pAC->BoardLevel = SK_INIT_IO; } - if (pAC->BoardLevel != 2) { + if (pAC->BoardLevel != SK_INIT_RUN) { /* tschilling: Level 2 init modules here, check return value. */ - if (SkGeInit(pAC, pAC->IoBase, 2) != 0) { + if (SkGeInit(pAC, pAC->IoBase, SK_INIT_RUN) != 0) { printk("%s: HWInit (2) failed.\n", pAC->dev[pNet->PortNr]->name); return (-1); } - SkI2cInit (pAC, pAC->IoBase, 2); - SkEventInit (pAC, pAC->IoBase, 2); - SkPnmiInit (pAC, pAC->IoBase, 2); - SkAddrInit (pAC, pAC->IoBase, 2); - SkRlmtInit (pAC, pAC->IoBase, 2); - SkTimerInit (pAC, pAC->IoBase, 2); - pAC->BoardLevel = 2; + SkI2cInit (pAC, pAC->IoBase, SK_INIT_RUN); + SkEventInit (pAC, pAC->IoBase, SK_INIT_RUN); + SkPnmiInit (pAC, pAC->IoBase, SK_INIT_RUN); + SkAddrInit (pAC, pAC->IoBase, SK_INIT_RUN); + SkRlmtInit (pAC, pAC->IoBase, SK_INIT_RUN); + SkTimerInit (pAC, pAC->IoBase, SK_INIT_RUN); + pAC->BoardLevel = SK_INIT_RUN; } for (i=0; iGIni.GIMacsFound; i++) { @@ -1697,20 +1606,14 @@ } SkGeYellowLED(pAC, pAC->IoBase, 1); -#ifdef USE_INT_MOD -/* moderate only TX complete interrupts (these are not time critical) */ -#define IRQ_MOD_MASK (IRQ_EOF_AS_TX1 | IRQ_EOF_AS_TX2) - { - unsigned long ModBase; - ModBase = 53125000 / INTS_PER_SEC; - SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase); - SK_OUT32(pAC->IoBase, B2_IRQM_MSK, IRQ_MOD_MASK); - SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START); - } -#endif + StartDrvCleanupTimer(pAC); + SkDimEnableModerationIfNeeded(pAC); + SkDimDisplayModerationSettings(pAC); + + pAC->GIni.GIValIrqMask &= IRQ_MASK; /* enable Interrupts */ - SK_OUT32(pAC->IoBase, B0_IMSK, IRQ_MASK); + SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK); spin_lock_irqsave(&pAC->SlowPathLock, Flags); @@ -1758,27 +1661,53 @@ static int SkGeClose( struct SK_NET_DEVICE *dev) { - DEV_NET *pNet; - SK_AC *pAC; + DEV_NET *pNet; + DEV_NET *newPtrNet; + SK_AC *pAC; unsigned long Flags; /* for spin lock */ - int i; - int PortIdx; - SK_EVPARA EvPara; + int i; + int PortIdx; + SK_EVPARA EvPara; + + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, + ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC)); - netif_stop_queue(dev); pNet = (DEV_NET*) dev->priv; pAC = pNet->pAC; +#ifdef SK_DIAG_SUPPORT + if (pAC->DiagModeActive == DIAG_ACTIVE) { + if (pAC->DiagFlowCtrl == SK_FALSE) { + MOD_DEC_USE_COUNT; + /* + ** notify that the interface which has been closed + ** by operator interaction must not be started up + ** again when the DIAG has finished. + */ + newPtrNet = (DEV_NET *) pAC->dev[0]->priv; + if (newPtrNet == pNet) { + pAC->WasIfUp[0] = SK_FALSE; + } else { + pAC->WasIfUp[1] = SK_FALSE; + } + return 0; /* return to system everything is fine... */ + } else { + pAC->DiagFlowCtrl = SK_FALSE; + } + } +#endif + + netif_stop_queue(dev); + if (pAC->RlmtNets == 1) PortIdx = pAC->ActivePort; else PortIdx = pNet->NetNr; - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC)); + StopDrvCleanupTimer(pAC); - /* + /* * Clear multicast table, promiscuous mode .... */ SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0); @@ -1796,7 +1725,7 @@ SK_OUT32(pAC->IoBase, B0_IMSK, 0); /* stop the hardware */ SkGeDeInit(pAC, pAC->IoBase); - pAC->BoardLevel = 0; + pAC->BoardLevel = SK_INIT_DATA; spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); } else { @@ -1804,13 +1733,14 @@ EvPara.Para32[0] = pNet->NetNr; EvPara.Para32[1] = -1; SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); + SkPnmiEvent(pAC, pAC->IoBase, SK_PNMI_EVT_XMAC_RESET, EvPara); SkEventDispatcher(pAC, pAC->IoBase); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); /* Stop port */ spin_lock_irqsave(&pAC->TxPort[pNet->PortNr] [TX_PRIO_LOW].TxDesRingLock, Flags); - SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr, + SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr, SK_STOP_ALL, SK_HARD_RST); spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr] [TX_PRIO_LOW].TxDesRingLock, Flags); @@ -1833,10 +1763,14 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("SkGeClose: done ")); + SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA)); + SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), + sizeof(SK_PNMI_STRUCT_DATA)); + pAC->MaxPorts--; pNet->Up = 0; + MOD_DEC_USE_COUNT; - return (0); } /* SkGeClose */ @@ -1865,7 +1799,7 @@ pNet = (DEV_NET*) dev->priv; pAC = pNet->pAC; - if ((!skb_shinfo(skb)->nr_frags) || + if ((!skb_shinfo(skb)->nr_frags) || (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) { /* Don't activate scatter-gather and hardware checksum */ @@ -1932,24 +1866,29 @@ * < 0 - on failure: other problems ( -> return failure to upper layers) */ static int XmitFrame( -SK_AC *pAC, /* pointer to adapter context */ +SK_AC *pAC, /* pointer to adapter context */ TX_PORT *pTxPort, /* pointer to struct of port to send to */ -struct sk_buff *pMessage) /* pointer to send-message */ +struct sk_buff *pMessage) /* pointer to send-message */ { -TXD *pTxd; /* the rxd to fill */ -unsigned long Flags; -SK_U64 PhysAddr; -int BytesSend; + TXD *pTxd; /* the rxd to fill */ + TXD *pOldTxd; + unsigned long Flags; + SK_U64 PhysAddr; + int Protocol; + int IpHeaderLength; + int BytesSend = pMessage->len; - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, - ("X")); + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("X")); spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags); #ifndef USE_TX_COMPLETE FreeTxDescriptors(pAC, pTxPort); #endif if (pTxPort->TxdRingFree == 0) { - /* no enough free descriptors in ring at the moment */ + /* + ** no enough free descriptors in ring at the moment. + ** Maybe free'ing some old one help? + */ FreeTxDescriptors(pAC, pTxPort); if (pTxPort->TxdRingFree == 0) { spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); @@ -1957,59 +1896,107 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("XmitFrame failed\n")); - /* this message can not be sent now */ - /* Because tbusy seems to be set, the message should not be freed here */ - /* It will be used by the scheduler of the ethernet handler */ + /* + ** the desired message can not be sent + ** Because tbusy seems to be set, the message + ** should not be freed here. It will be used + ** by the scheduler of the ethernet handler + */ return (-1); } } - /* advance head counter behind descriptor needed for this frame */ + + /* + ** If the passed socket buffer is of smaller MTU-size than 60, + ** copy everything into new buffer and fill all bytes between + ** the original packet end and the new packet end of 60 with 0x00. + ** This is to resolve faulty padding by the HW with 0xaa bytes. + */ + if (BytesSend < C_LEN_ETHERNET_MINSIZE) { + if ((pMessage = skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) == NULL) { + return 0; + } + pMessage->len = C_LEN_ETHERNET_MINSIZE; + } + + /* + ** advance head counter behind descriptor needed for this frame, + ** so that needed descriptor is reserved from that on. The next + ** action will be to add the passed buffer to the TX-descriptor + */ pTxd = pTxPort->pTxdRingHead; pTxPort->pTxdRingHead = pTxd->pNextTxd; pTxPort->TxdRingFree--; - /* the needed descriptor is reserved now */ - - /* - * everything allocated ok, so add buffer to descriptor - */ #ifdef SK_DUMP_TX DumpMsg(pMessage, "XmitFrame"); #endif - /* set up descriptor and CONTROL dword */ + /* + ** First step is to map the data to be sent via the adapter onto + ** the DMA memory. Kernel 2.2 uses virt_to_bus(), but kernels 2.4 + ** and 2.6 need to use pci_map_page() for that mapping. + */ PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, - virt_to_page(pMessage->data), - ((unsigned long) pMessage->data & - ~PAGE_MASK), - pMessage->len, - PCI_DMA_TODEVICE); - pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); + virt_to_page(pMessage->data), + ((unsigned long) pMessage->data & ~PAGE_MASK), + pMessage->len, + PCI_DMA_TODEVICE); + pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32); - pTxd->pMBuf = pMessage; - pTxd->TBControl = TX_CTRL_OWN_BMU | TX_CTRL_STF | - TX_CTRL_CHECK_DEFAULT | TX_CTRL_SOFTWARE | + pTxd->pMBuf = pMessage; + + if (pMessage->ip_summed == CHECKSUM_HW) { + Protocol = ((SK_U8)pMessage->data[C_OFFSET_IPPROTO] & 0xff); + if ((Protocol == C_PROTO_ID_UDP) && + (pAC->GIni.GIChipRev == 0) && + (pAC->GIni.GIChipId == CHIP_ID_YUKON)) { + pTxd->TBControl = BMU_TCP_CHECK; + } else { + pTxd->TBControl = BMU_UDP_CHECK; + } + + IpHeaderLength = (SK_U8)pMessage->data[C_OFFSET_IPHEADER]; + IpHeaderLength = (IpHeaderLength & 0xf) * 4; + pTxd->TcpSumOfs = 0; /* PH-Checksum already calculated */ + pTxd->TcpSumSt = C_LEN_ETHERMAC_HEADER + IpHeaderLength + + (Protocol == C_PROTO_ID_UDP ? + C_OFFSET_UDPHEADER_UDPCS : + C_OFFSET_TCPHEADER_TCPCS); + pTxd->TcpSumWr = C_LEN_ETHERMAC_HEADER + IpHeaderLength; + + pTxd->TBControl |= BMU_OWN | BMU_STF | + BMU_SW | BMU_EOF | #ifdef USE_TX_COMPLETE - TX_CTRL_EOF | TX_CTRL_EOF_IRQ | pMessage->len; -#else - TX_CTRL_EOF | pMessage->len; + BMU_IRQ_EOF | #endif - - if ((pTxPort->pTxdRingPrev->TBControl & TX_CTRL_OWN_BMU) == 0) { - /* previous descriptor already done, so give tx start cmd */ - /* StartTx(pAC, pTxPort->HwAddr); */ - SK_OUT8(pTxPort->HwAddr, TX_Q_CTRL, TX_Q_CTRL_START); + pMessage->len; + } else { + pTxd->TBControl = BMU_OWN | BMU_STF | BMU_CHECK | + BMU_SW | BMU_EOF | +#ifdef USE_TX_COMPLETE + BMU_IRQ_EOF | +#endif + pMessage->len; } - pTxPort->pTxdRingPrev = pTxd; - - - BytesSend = pMessage->len; + + /* + ** If previous descriptor already done, give TX start cmd + */ + pOldTxd = xchg(&pTxPort->pTxdRingPrev, pTxd); + if ((pOldTxd->TBControl & BMU_OWN) == 0) { + SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START); + } + + /* + ** after releasing the lock, the skb may immediately be free'd + */ spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); - /* after releasing the lock, the skb may be immidiately freed */ - if (pTxPort->TxdRingFree != 0) + if (pTxPort->TxdRingFree != 0) { return (BytesSend); - else + } else { return (0); + } } /* XmitFrame */ @@ -2029,21 +2016,21 @@ * < 0 - on failure: other problems ( -> return failure to upper layers) */ static int XmitFrameSG( -SK_AC *pAC, /* pointer to adapter context */ -TX_PORT *pTxPort, /* pointer to struct of port to send to */ -struct sk_buff *pMessage) /* pointer to send-message */ +SK_AC *pAC, /* pointer to adapter context */ +TX_PORT *pTxPort, /* pointer to struct of port to send to */ +struct sk_buff *pMessage) /* pointer to send-message */ { - int i; - int BytesSend; - int hlength; - int protocol; - skb_frag_t *sk_frag; - TXD *pTxd; - TXD *pTxdFst; - TXD *pTxdLst; - SK_U64 PhysAddr; - unsigned long Flags; + TXD *pTxd; + TXD *pTxdFst; + TXD *pTxdLst; + int CurrFrag; + int BytesSend; + int IpHeaderLength; + int Protocol; + skb_frag_t *sk_frag; + SK_U64 PhysAddr; + unsigned long Flags; spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags); #ifndef USE_TX_COMPLETE @@ -2062,114 +2049,123 @@ } } - - pTxd = pTxPort->pTxdRingHead; - pTxdFst = pTxd; - pTxdLst = pTxd; + pTxd = pTxPort->pTxdRingHead; + pTxdFst = pTxd; + pTxdLst = pTxd; BytesSend = 0; - protocol = 0; + Protocol = 0; - /* map first fragment (header) */ + /* + ** Map the first fragment (header) into the DMA-space + */ PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, virt_to_page(pMessage->data), ((unsigned long) pMessage->data & ~PAGE_MASK), skb_headlen(pMessage), PCI_DMA_TODEVICE); - pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); + pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32); - /* HW checksum? */ + /* + ** Does the HW need to evaluate checksum for TCP or UDP packets? + */ if (pMessage->ip_summed == CHECKSUM_HW) { - pTxd->TBControl = TX_CTRL_STF | - TX_CTRL_ST_FWD | - skb_headlen(pMessage); - - /* We have to use the opcode for tcp here because the opcode for - udp is not working in the hardware yet (revision 2.0)*/ - protocol = ((SK_U8)pMessage->data[23] & 0xf); - if ((protocol == 17) && (pAC->GIni.GIChipRev != 0)) - pTxd->TBControl |= BMU_UDP_CHECK; - else - pTxd->TBControl |= BMU_TCP_CHECK ; + pTxd->TBControl = BMU_STF | BMU_STFWD | skb_headlen(pMessage); + /* + ** We have to use the opcode for tcp here, because the + ** opcode for udp is not working in the hardware yet + ** (Revision 2.0) + */ + Protocol = ((SK_U8)pMessage->data[C_OFFSET_IPPROTO] & 0xff); + if ((Protocol == C_PROTO_ID_UDP) && + (pAC->GIni.GIChipRev == 0) && + (pAC->GIni.GIChipId == CHIP_ID_YUKON)) { + pTxd->TBControl |= BMU_TCP_CHECK; + } else { + pTxd->TBControl |= BMU_UDP_CHECK; + } - hlength = ((SK_U8)pMessage->data[14] & 0xf) * 4; + IpHeaderLength = ((SK_U8)pMessage->data[C_OFFSET_IPHEADER] & 0xf)*4; pTxd->TcpSumOfs = 0; /* PH-Checksum already claculated */ - pTxd->TcpSumSt = 14+hlength+16; - pTxd->TcpSumWr = 14+hlength; - + pTxd->TcpSumSt = C_LEN_ETHERMAC_HEADER + IpHeaderLength + + (Protocol == C_PROTO_ID_UDP ? + C_OFFSET_UDPHEADER_UDPCS : + C_OFFSET_TCPHEADER_TCPCS); + pTxd->TcpSumWr = C_LEN_ETHERMAC_HEADER + IpHeaderLength; } else { - pTxd->TBControl = TX_CTRL_CHECK_DEFAULT | - TX_CTRL_SOFTWARE | - TX_CTRL_STF | - skb_headlen(pMessage); + pTxd->TBControl = BMU_CHECK | BMU_SW | BMU_STF | + skb_headlen(pMessage); } pTxd = pTxd->pNextTxd; pTxPort->TxdRingFree--; BytesSend += skb_headlen(pMessage); - - /* Map SG fragments */ - for (i = 0; i < skb_shinfo(pMessage)->nr_frags; i++) { - sk_frag = &skb_shinfo(pMessage)->frags[i]; - - /* we already have the proper value in entry */ + /* + ** Browse over all SG fragments and map each of them into the DMA space + */ + for (CurrFrag = 0; CurrFrag < skb_shinfo(pMessage)->nr_frags; CurrFrag++) { + sk_frag = &skb_shinfo(pMessage)->frags[CurrFrag]; + /* + ** we already have the proper value in entry + */ PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, sk_frag->page, sk_frag->page_offset, sk_frag->size, PCI_DMA_TODEVICE); - pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); + pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32); - pTxd->pMBuf = pMessage; + pTxd->pMBuf = pMessage; - /* HW checksum */ + /* + ** Does the HW need to evaluate checksum for TCP or UDP packets? + */ if (pMessage->ip_summed == CHECKSUM_HW) { - pTxd->TBControl = TX_CTRL_OWN_BMU | - TX_CTRL_SOFTWARE | - TX_CTRL_ST_FWD; - - /* We have to use the opcode for tcp here because the opcode for - udp is not working in the hardware yet (revision 2.0)*/ - if ((protocol == 17) && (pAC->GIni.GIChipRev != 0)) - pTxd->TBControl |= BMU_UDP_CHECK ; - else - pTxd->TBControl |= BMU_TCP_CHECK ; - + pTxd->TBControl = BMU_OWN | BMU_SW | BMU_STFWD; + /* + ** We have to use the opcode for tcp here because the + ** opcode for udp is not working in the hardware yet + ** (revision 2.0) + */ + if ((Protocol == C_PROTO_ID_UDP) && + (pAC->GIni.GIChipRev == 0) && + (pAC->GIni.GIChipId == CHIP_ID_YUKON)) { + pTxd->TBControl |= BMU_TCP_CHECK; + } else { + pTxd->TBControl |= BMU_UDP_CHECK; + } } else { - pTxd->TBControl = TX_CTRL_CHECK_DEFAULT | - TX_CTRL_SOFTWARE | - TX_CTRL_OWN_BMU; + pTxd->TBControl = BMU_CHECK | BMU_SW | BMU_OWN; } - /* Last fragment */ - if( (i+1) == skb_shinfo(pMessage)->nr_frags ) { + /* + ** Do we have the last fragment? + */ + if( (CurrFrag+1) == skb_shinfo(pMessage)->nr_frags ) { #ifdef USE_TX_COMPLETE - pTxd->TBControl |= TX_CTRL_EOF | - TX_CTRL_EOF_IRQ | - sk_frag->size; + pTxd->TBControl |= BMU_EOF | BMU_IRQ_EOF | sk_frag->size; #else - pTxd->TBControl |= TX_CTRL_EOF | - sk_frag->size; + pTxd->TBControl |= BMU_EOF | sk_frag->size; #endif - pTxdFst->TBControl |= TX_CTRL_OWN_BMU | - TX_CTRL_SOFTWARE; + pTxdFst->TBControl |= BMU_OWN | BMU_SW; } else { pTxd->TBControl |= sk_frag->size; } pTxdLst = pTxd; - pTxd = pTxd->pNextTxd; + pTxd = pTxd->pNextTxd; pTxPort->TxdRingFree--; BytesSend += sk_frag->size; } - if ((pTxPort->pTxdRingPrev->TBControl & TX_CTRL_OWN_BMU) == 0) { - /* previous descriptor already done, so give tx start cmd */ - /* StartTx(pAC, pTxPort->HwAddr); */ - SK_OUT8(pTxPort->HwAddr, TX_Q_CTRL, TX_Q_CTRL_START); + /* + ** If previous descriptor already done, give TX start cmd + */ + if ((pTxPort->pTxdRingPrev->TBControl & BMU_OWN) == 0) { + SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START); } pTxPort->pTxdRingPrev = pTxdLst; @@ -2177,28 +2173,13 @@ spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); - if (pTxPort->TxdRingFree > 0) + if (pTxPort->TxdRingFree > 0) { return (BytesSend); - else + } else { return (0); + } } - -void dump_frag( SK_U8 *data, int length) -{ - int i; - - printk("Length: %d\n", length); - for( i=0; i < length; i++ ) { - printk(" %02x", (SK_U8)*(data + i) ); - if( !((i+1) % 20) ) - printk("\n"); - } - printk("\n\n"); - -} - - /***************************************************************************** * * FreeTxDescriptors - release descriptors from the descriptor ring @@ -2227,44 +2208,48 @@ SK_U64 PhysAddr; /* address of DMA mapping */ pNewTail = pTxPort->pTxdRingTail; - pTxd = pNewTail; - /* - * loop forever; exits if TX_CTRL_SOFTWARE bit not set in start frame - * or TX_CTRL_OWN_BMU bit set in any frame - */ + pTxd = pNewTail; + /* + ** loop forever; exits if BMU_SW bit not set in start frame + ** or BMU_OWN bit set in any frame + */ while (1) { Control = pTxd->TBControl; - if ((Control & TX_CTRL_SOFTWARE) == 0) { - /* - * software controllable bit is set in first - * fragment when given to BMU. Not set means that - * this fragment was never sent or is already - * freed ( -> ring completely free now). - */ + if ((Control & BMU_SW) == 0) { + /* + ** software controllable bit is set in first + ** fragment when given to BMU. Not set means that + ** this fragment was never sent or is already + ** freed ( -> ring completely free now). + */ pTxPort->pTxdRingTail = pTxd; - netif_start_queue(pAC->dev[pTxPort->PortIndex]); + netif_wake_queue(pAC->dev[pTxPort->PortIndex]); return; } - if (Control & TX_CTRL_OWN_BMU) { + if (Control & BMU_OWN) { pTxPort->pTxdRingTail = pTxd; if (pTxPort->TxdRingFree > 0) { - netif_start_queue(pAC->dev[pTxPort->PortIndex]); + netif_wake_queue(pAC->dev[pTxPort->PortIndex]); } return; } - /* release the DMA mapping */ + /* + ** release the DMA mapping, because until not unmapped + ** this buffer is considered being under control of the + ** adapter card! + */ PhysAddr = ((SK_U64) pTxd->VDataHigh) << (SK_U64) 32; PhysAddr |= (SK_U64) pTxd->VDataLow; pci_unmap_page(pAC->PciDev, PhysAddr, pTxd->pMBuf->len, PCI_DMA_TODEVICE); - if (Control & TX_CTRL_EOF) + if (Control & BMU_EOF) DEV_KFREE_SKB_ANY(pTxd->pMBuf); /* free message */ pTxPort->TxdRingFree++; - pTxd->TBControl &= ~TX_CTRL_SOFTWARE; + pTxd->TBControl &= ~BMU_SW; pTxd = pTxd->pNextTxd; /* point behind fragment with EOF */ } /* while(forever) */ } /* FreeTxDescriptors */ @@ -2343,11 +2328,15 @@ ~PAGE_MASK), pAC->RxBufSize - 2, PCI_DMA_FROMDEVICE); - pRxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); + + pRxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); pRxd->VDataHigh = (SK_U32) (PhysAddr >> 32); - pRxd->pMBuf = pMsgBlock; - pRxd->RBControl = RX_CTRL_OWN_BMU | RX_CTRL_STF | - RX_CTRL_EOF_IRQ | RX_CTRL_CHECK_CSUM | Length; + pRxd->pMBuf = pMsgBlock; + pRxd->RBControl = BMU_OWN | + BMU_STF | + BMU_IRQ_EOF | + BMU_TCP_CHECK | + Length; return (SK_TRUE); } /* FillRxDescriptor */ @@ -2378,15 +2367,18 @@ pRxPort->pRxdRingTail = pRxd->pNextRxd; pRxPort->RxdRingFree--; Length = pAC->RxBufSize; - pRxd->VDataLow = PhysLow; + + pRxd->VDataLow = PhysLow; pRxd->VDataHigh = PhysHigh; - pRxd->pMBuf = pMsg; - pRxd->RBControl = RX_CTRL_OWN_BMU | RX_CTRL_STF | - RX_CTRL_EOF_IRQ | RX_CTRL_CHECK_CSUM | Length; + pRxd->pMBuf = pMsg; + pRxd->RBControl = BMU_OWN | + BMU_STF | + BMU_IRQ_EOF | + BMU_TCP_CHECK | + Length; return; } /* ReQueueRxBuffer */ - /***************************************************************************** * * ReceiveIrq - handle a receive IRQ @@ -2408,6 +2400,7 @@ struct sk_buff *pMsg; /* pointer to message holding frame */ struct sk_buff *pNewMsg; /* pointer to a new message for copying frame */ int FrameLength; /* total length of received frame */ +int IpFrameLength; SK_MBUF *pRlmtMbuf; /* ptr to a buffer for giving a frame to rlmt */ SK_EVPARA EvPara; /* an event parameter union */ unsigned long Flags; /* for spin lock */ @@ -2427,7 +2420,7 @@ SK_U64 PhysAddr; rx_start: - /* do forever; exit if RX_CTRL_OWN_BMU found */ + /* do forever; exit if BMU_OWN found */ for ( pRxd = pRxPort->pRxdRingHead ; pRxPort->RxdRingFree < pAC->RxDescrPerRing ; pRxd = pRxd->pNextRxd, @@ -2435,8 +2428,8 @@ pRxPort->RxdRingFree ++) { /* - * For a better understanding of this loop - * Go through every descriptor beginning at the head + * For a better understanding of this loop + * Go through every descriptor beginning at the head * Please note: the ring might be completely received so the OWN bit * set is not a good crirteria to leave that loop. * Therefore the RingFree counter is used. @@ -2447,23 +2440,23 @@ Control = pRxd->RBControl; /* check if this descriptor is ready */ - if ((Control & RX_CTRL_OWN_BMU) != 0) { + if ((Control & BMU_OWN) != 0) { /* this descriptor is not yet ready */ /* This is the usual end of the loop */ /* We don't need to start the ring again */ FillRxRing(pAC, pRxPort); return; } + pAC->DynIrqModInfo.NbrProcessedDescr++; /* get length of frame and check it */ - FrameLength = Control & RX_CTRL_LEN_MASK; + FrameLength = Control & BMU_BBC; if (FrameLength > pAC->RxBufSize) { goto rx_failed; } /* check for STF and EOF */ - if ((Control & (RX_CTRL_STF | RX_CTRL_EOF)) != - (RX_CTRL_STF | RX_CTRL_EOF)) { + if ((Control & (BMU_STF | BMU_EOF)) != (BMU_STF | BMU_EOF)) { goto rx_failed; } @@ -2500,7 +2493,7 @@ if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { IsBc = (FrameStat & XMR_FS_BC) != 0; IsMc = (FrameStat & XMR_FS_MC) != 0; - IsBadFrame = (FrameStat & + IsBadFrame = (FrameStat & (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0; } else { IsBc = (FrameStat & GMR_FS_BC) != 0; @@ -2517,8 +2510,7 @@ pRxPort->RxdRingFree)); /* DumpMsg(pMsg, "Rx"); */ - if ((Control & RX_CTRL_STAT_VALID) != RX_CTRL_STAT_VALID || - (IsBadFrame)) { + if ((Control & BMU_STAT_VAL) != BMU_STAT_VAL || (IsBadFrame)) { #if 0 (FrameStat & (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0) { #endif @@ -2563,6 +2555,7 @@ FrameLength, 0); ReQueueRxBuffer(pAC, pRxPort, pMsg, pRxd->VDataHigh, pRxd->VDataLow); + pMsg = pNewMsg; } @@ -2585,33 +2578,65 @@ skb_put(pMsg, FrameLength); /* hardware checksum */ Type = ntohs(*((short*)&pMsg->data[12])); + +#ifdef USE_SK_RX_CHECKSUM if (Type == 0x800) { Csum1=le16_to_cpu(pRxd->TcpSums & 0xffff); Csum2=le16_to_cpu((pRxd->TcpSums >> 16) & 0xffff); - if ((((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) && - (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) || - (pAC->GIni.GIChipId == CHIP_ID_YUKON)) { - Result = SkCsGetReceiveInfo(pAC, - &pMsg->data[14], - Csum1, Csum2, pRxPort->PortIndex); - if (Result == - SKCS_STATUS_IP_FRAGMENT || - Result == - SKCS_STATUS_IP_CSUM_OK || - Result == - SKCS_STATUS_TCP_CSUM_OK || - Result == - SKCS_STATUS_UDP_CSUM_OK) { - pMsg->ip_summed = - CHECKSUM_UNNECESSARY; - } else { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_RX_PROGRESS, - ("skge: CRC error. Frame dropped!\n")); - goto rx_failed; - } - }/* checksumControl calculation valid */ + IpFrameLength = (int) ntohs((unsigned short) + ((unsigned short *) pMsg->data)[8]); + + /* + * Test: If frame is padded, a check is not possible! + * Frame not padded? Length difference must be 14 (0xe)! + */ + if ((FrameLength - IpFrameLength) != 0xe) { + /* Frame padded => TCP offload not possible! */ + pMsg->ip_summed = CHECKSUM_NONE; + } else { + /* Frame not padded => TCP offload! */ + if ((((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) && + (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) || + (pAC->ChipsetType)) { + Result = SkCsGetReceiveInfo(pAC, + &pMsg->data[14], + Csum1, Csum2, pRxPort->PortIndex); + if (Result == + SKCS_STATUS_IP_FRAGMENT || + Result == + SKCS_STATUS_IP_CSUM_OK || + Result == + SKCS_STATUS_TCP_CSUM_OK || + Result == + SKCS_STATUS_UDP_CSUM_OK) { + pMsg->ip_summed = + CHECKSUM_UNNECESSARY; + } + else if (Result == + SKCS_STATUS_TCP_CSUM_ERROR || + Result == + SKCS_STATUS_UDP_CSUM_ERROR || + Result == + SKCS_STATUS_IP_CSUM_ERROR_UDP || + Result == + SKCS_STATUS_IP_CSUM_ERROR_TCP || + Result == + SKCS_STATUS_IP_CSUM_ERROR ) { + /* HW Checksum error */ + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_RX_PROGRESS, + ("skge: CRC error. Frame dropped!\n")); + goto rx_failed; + } else { + pMsg->ip_summed = + CHECKSUM_NONE; + } + }/* checksumControl calculation valid */ + } /* Frame length check */ } /* IP frame */ +#else + pMsg->ip_summed = CHECKSUM_NONE; +#endif } /* frame > SK_COPY_TRESHOLD */ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V")); @@ -2625,7 +2650,7 @@ #if 0 IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC; #endif - SK_RLMT_LOOKAHEAD(pAC, PortIndex, + SK_RLMT_LOOKAHEAD(pAC, PortIndex, &pMsg->data[Offset], IsBc, IsMc, &ForRlmt); } @@ -2650,7 +2675,7 @@ } else { /* drop frame */ - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ("D")); DEV_KFREE_SKB(pMsg); @@ -2659,7 +2684,7 @@ } /* if not for rlmt */ else { /* packet for rlmt */ - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ("R")); pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC, pAC->IoBase, FrameLength); @@ -2687,14 +2712,14 @@ pAC->CheckQueue = SK_TRUE; } - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ("Q")); } - if ((pAC->dev[pRxPort->PortIndex]->flags & + if ((pAC->dev[pRxPort->PortIndex]->flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0 || - (ForRlmt & SK_RLMT_RX_PROTOCOL) == - SK_RLMT_RX_PROTOCOL) { + (ForRlmt & SK_RLMT_RX_PROTOCOL) == + SK_RLMT_RX_PROTOCOL) { pMsg->dev = pAC->dev[pRxPort->PortIndex]; pMsg->protocol = eth_type_trans(pMsg, pAC->dev[pRxPort->PortIndex]); @@ -2711,7 +2736,7 @@ /* RXD ring is empty -> fill and restart */ FillRxRing(pAC, pRxPort); /* do not start if called from Close */ - if (pAC->BoardLevel > 0) { + if (pAC->BoardLevel > SK_INIT_DATA) { ClearAndStartRx(pAC, PortIndex); } return; @@ -2753,8 +2778,9 @@ SK_AC *pAC, /* pointer to the adapter context */ int PortIndex) /* index of the receive port (XMAC) */ { - SK_OUT8(pAC->IoBase, RxQueueAddr[PortIndex]+RX_Q_CTRL, - RX_Q_CTRL_START | RX_Q_CTRL_CLR_I_EOF); + SK_OUT8(pAC->IoBase, + RxQueueAddr[PortIndex]+Q_CSR, + CSR_START | CSR_IRQ_CL_F); } /* ClearAndStartRx */ @@ -2773,8 +2799,9 @@ int PortIndex, /* index of the transmit port (XMAC) */ int Prio) /* priority or normal queue */ { - SK_OUT8(pAC->IoBase, TxQueueAddr[PortIndex][Prio]+TX_Q_CTRL, - TX_Q_CTRL_CLR_I_EOF); + SK_OUT8(pAC->IoBase, + TxQueueAddr[PortIndex][Prio]+Q_CSR, + CSR_IRQ_CL_F); } /* ClearTxIrq */ @@ -2813,7 +2840,7 @@ DEV_KFREE_SKB(pRxd->pMBuf); pRxd->pMBuf = NULL; } - pRxd->RBControl &= RX_CTRL_OWN_BMU; + pRxd->RBControl &= BMU_OWN; pRxd = pRxd->pNextRxd; pRxPort->RxdRingFree++; } while (pRxd != pRxPort->pRxdRingTail); @@ -2821,7 +2848,6 @@ spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags); } /* ClearRxRing */ - /***************************************************************************** * * ClearTxRing - remove all buffers from the transmit ring @@ -2846,107 +2872,13 @@ spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags); pTxd = pTxPort->pTxdRingHead; for (i=0; iTxDescrPerRing; i++) { - pTxd->TBControl &= ~TX_CTRL_OWN_BMU; + pTxd->TBControl &= ~BMU_OWN; pTxd = pTxd->pNextTxd; } FreeTxDescriptors(pAC, pTxPort); spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); } /* ClearTxRing */ - -/***************************************************************************** - * - * SetQueueSizes - configure the sizes of rx and tx queues - * - * Description: - * This function assigns the sizes for active and passive port - * to the appropriate HWinit structure variables. - * The passive port(s) get standard values, all remaining RAM - * is given to the active port. - * The queue sizes are in kbyte and must be multiple of 8. - * The limits for the number of buffers filled into the rx rings - * is also set in this routine. - * - * Returns: - * none - */ -static void SetQueueSizes( -SK_AC *pAC) /* pointer to the adapter context */ -{ -int StandbyRam; /* adapter RAM used for a standby port */ -int RemainingRam; /* adapter RAM available for the active port */ -int RxRam; /* RAM used for the active port receive queue */ -int i; /* loop counter */ - -if (pAC->RlmtNets == 1) { - StandbyRam = SK_RLMT_STANDBY_QRXSIZE + SK_RLMT_STANDBY_QXASIZE + - SK_RLMT_STANDBY_QXSSIZE; - RemainingRam = pAC->GIni.GIRamSize - - (pAC->GIni.GIMacsFound-1) * StandbyRam; - for (i=0; iGIni.GIMacsFound; i++) { - pAC->GIni.GP[i].PRxQSize = SK_RLMT_STANDBY_QRXSIZE; - pAC->GIni.GP[i].PXSQSize = SK_RLMT_STANDBY_QXSSIZE; - pAC->GIni.GP[i].PXAQSize = SK_RLMT_STANDBY_QXASIZE; - } - RxRam = (RemainingRam * 8 / 10) & ~7; - pAC->GIni.GP[pAC->ActivePort].PRxQSize = RxRam; - pAC->GIni.GP[pAC->ActivePort].PXSQSize = 0; - pAC->GIni.GP[pAC->ActivePort].PXAQSize = - (RemainingRam - RxRam) & ~7; - pAC->RxQueueSize = RxRam; - pAC->TxSQueueSize = 0; - pAC->TxAQueueSize = (RemainingRam - RxRam) & ~7; - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("queue sizes settings - rx:%d txA:%d txS:%d\n", - pAC->RxQueueSize,pAC->TxAQueueSize, pAC->TxSQueueSize)); -} else { - RemainingRam = pAC->GIni.GIRamSize/pAC->GIni.GIMacsFound; - RxRam = (RemainingRam * 8 / 10) & ~7; - for (i=0; iGIni.GIMacsFound; i++) { - pAC->GIni.GP[i].PRxQSize = RxRam; - pAC->GIni.GP[i].PXSQSize = 0; - pAC->GIni.GP[i].PXAQSize = (RemainingRam - RxRam) & ~7; - } - - pAC->RxQueueSize = RxRam; - pAC->TxSQueueSize = 0; - pAC->TxAQueueSize = (RemainingRam - RxRam) & ~7; -} - for (i=0; iRxPort[i].RxFillLimit = pAC->RxDescrPerRing; - } - - if (pAC->RlmtNets == 2) { - for (i=0; iGIni.GIMacsFound; i++) { - pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 100; - } - } else { - for (i=0; iGIni.GIMacsFound; i++) { - pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 100; - } - /* - * Do not set the Limit to 0, because this could cause - * wrap around with ReQueue'ed buffers (a buffer could - * be requeued in the same position, made accessable to - * the hardware, and the hardware could change its - * contents! - */ - pAC->RxPort[pAC->ActivePort].RxFillLimit = 1; - } - -#ifdef DEBUG - for (i=0; iGIni.GIMacsFound; i++) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, - ("i: %d, RxQSize: %d, PXSQsize: %d, PXAQSize: %d\n", - i, - pAC->GIni.GP[i].PRxQSize, - pAC->GIni.GP[i].PXSQSize, - pAC->GIni.GP[i].PXAQSize)); - } -#endif -} /* SetQueueSizes */ - - /***************************************************************************** * * SkGeSetMacAddr - Set the hardware MAC address @@ -3091,49 +3023,62 @@ ("SkGeChangeMtu starts now...\n")); pNet = (DEV_NET*) dev->priv; - pAC = pNet->pAC; + pAC = pNet->pAC; if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) { return -EINVAL; } - if(pAC->BoardLevel != 2) { + if(pAC->BoardLevel != SK_INIT_RUN) { return -EINVAL; } +#ifdef SK_DIAG_SUPPORT + if (pAC->DiagModeActive == DIAG_ACTIVE) { + if (pAC->DiagFlowCtrl == SK_FALSE) { + return -1; /* still in use, deny any actions of MTU */ + } else { + pAC->DiagFlowCtrl = SK_FALSE; + } + } +#endif + pNet->Mtu = NewMtu; pOtherNet = (DEV_NET*)pAC->dev[1 - pNet->NetNr]->priv; - if ((pOtherNet->Mtu > 1500) && (NewMtu <= 1500) && (pOtherNet->Up==1)) { + if ((pOtherNet->Mtu>1500) && (NewMtu<=1500) && (pOtherNet->Up==1)) { return(0); } - EvPara.Para32[0] = pNet->NetNr; - EvPara.Para32[1] = -1; - pAC->RxBufSize = NewMtu + 32; dev->mtu = NewMtu; SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("New MTU: %d\n", NewMtu)); - /* prevent reconfiguration while changing the MTU */ - - /* disable interrupts */ + /* + ** Prevent any reconfiguration while changing the MTU + ** by disabling any interrupts + */ SK_OUT32(pAC->IoBase, B0_IMSK, 0); spin_lock_irqsave(&pAC->SlowPathLock, Flags); - /* Found more than one port */ - if ((pAC->GIni.GIMacsFound == 2 ) && - (pAC->RlmtNets == 2)) { - /* Stop both ports */ - EvPara.Para32[0] = 0; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); - EvPara.Para32[0] = 1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); + /* + ** Notify RLMT that any ports are to be stopped + */ + EvPara.Para32[0] = 0; + EvPara.Para32[1] = -1; + if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { + SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); + EvPara.Para32[0] = 1; + SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); } else { SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); } + /* + ** After calling the SkEventDispatcher(), RLMT is aware about + ** the stopped ports -> configuration can take place! + */ SkEventDispatcher(pAC, pAC->IoBase); for (i=0; iGIni.GIMacsFound; i++) { @@ -3143,140 +3088,132 @@ } - /* - * adjust number of rx buffers allocated - */ + /* + ** Depending on the desired MTU size change, a different number of + ** RX buffers need to be allocated + */ if (NewMtu > 1500) { - /* use less rx buffers */ - for (i=0; iGIni.GIMacsFound; i++) { - /* Found more than one port */ - if ((pAC->GIni.GIMacsFound == 2 ) && - (pAC->RlmtNets == 2)) { - pAC->RxPort[i].RxFillLimit = - pAC->RxDescrPerRing - 100; - } else { - if (i == pAC->ActivePort) - pAC->RxPort[i].RxFillLimit = - pAC->RxDescrPerRing - 100; - else - pAC->RxPort[i].RxFillLimit = - pAC->RxDescrPerRing - 10; - } + /* + ** Use less rx buffers + */ + for (i=0; iGIni.GIMacsFound; i++) { + if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { + pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - + (pAC->RxDescrPerRing / 4); + } else { + if (i == pAC->ActivePort) { + pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - + (pAC->RxDescrPerRing / 4); + } else { + pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - + (pAC->RxDescrPerRing / 10); + } } - } - else { - /* use normal amount of rx buffers */ - for (i=0; iGIni.GIMacsFound; i++) { - /* Found more than one port */ - if ((pAC->GIni.GIMacsFound == 2 ) && - (pAC->RlmtNets == 2)) { - pAC->RxPort[i].RxFillLimit = 1; - } else { - if (i == pAC->ActivePort) - pAC->RxPort[i].RxFillLimit = 1; - else - pAC->RxPort[i].RxFillLimit = - pAC->RxDescrPerRing - 100; - } + } + } else { + /* + ** Use the normal amount of rx buffers + */ + for (i=0; iGIni.GIMacsFound; i++) { + if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { + pAC->RxPort[i].RxFillLimit = 1; + } else { + if (i == pAC->ActivePort) { + pAC->RxPort[i].RxFillLimit = 1; + } else { + pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - + (pAC->RxDescrPerRing / 4); + } } + } } - - SkGeDeInit(pAC, pAC->IoBase); + + SkGeDeInit(pAC, pAC->IoBase); - /* - * enable/disable hardware support for long frames - */ + /* + ** enable/disable hardware support for long frames + */ if (NewMtu > 1500) { -// pAC->JumboActivated = SK_TRUE; /* is never set back !!! */ +// pAC->JumboActivated = SK_TRUE; /* is never set back !!! */ pAC->GIni.GIPortUsage = SK_JUMBO_LINK; - } - else { - if ((pAC->GIni.GIMacsFound == 2 ) && - (pAC->RlmtNets == 2)) { - pAC->GIni.GIPortUsage = SK_MUL_LINK; - } else { - pAC->GIni.GIPortUsage = SK_RED_LINK; - } + } else { + if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { + pAC->GIni.GIPortUsage = SK_MUL_LINK; + } else { + pAC->GIni.GIPortUsage = SK_RED_LINK; + } } - SkGeInit( pAC, pAC->IoBase, 1); - SkI2cInit( pAC, pAC->IoBase, 1); - SkEventInit(pAC, pAC->IoBase, 1); - SkPnmiInit( pAC, pAC->IoBase, 1); - SkAddrInit( pAC, pAC->IoBase, 1); - SkRlmtInit( pAC, pAC->IoBase, 1); - SkTimerInit(pAC, pAC->IoBase, 1); + SkGeInit( pAC, pAC->IoBase, SK_INIT_IO); + SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO); + SkEventInit(pAC, pAC->IoBase, SK_INIT_IO); + SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO); + SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO); + SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO); + SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO); /* - * tschilling: - * Speed and others are set back to default in level 1 init! - */ + ** tschilling: + ** Speed and others are set back to default in level 1 init! + */ GetConfiguration(pAC); - SkGeInit( pAC, pAC->IoBase, 2); - SkI2cInit( pAC, pAC->IoBase, 2); - SkEventInit(pAC, pAC->IoBase, 2); - SkPnmiInit( pAC, pAC->IoBase, 2); - SkAddrInit( pAC, pAC->IoBase, 2); - SkRlmtInit( pAC, pAC->IoBase, 2); - SkTimerInit(pAC, pAC->IoBase, 2); + SkGeInit( pAC, pAC->IoBase, SK_INIT_RUN); + SkI2cInit( pAC, pAC->IoBase, SK_INIT_RUN); + SkEventInit(pAC, pAC->IoBase, SK_INIT_RUN); + SkPnmiInit( pAC, pAC->IoBase, SK_INIT_RUN); + SkAddrInit( pAC, pAC->IoBase, SK_INIT_RUN); + SkRlmtInit( pAC, pAC->IoBase, SK_INIT_RUN); + SkTimerInit(pAC, pAC->IoBase, SK_INIT_RUN); - /* - * clear and reinit the rx rings here - */ + /* + ** clear and reinit the rx rings here + */ for (i=0; iGIni.GIMacsFound; i++) { ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE); ClearRxRing(pAC, &pAC->RxPort[i]); FillRxRing(pAC, &pAC->RxPort[i]); - /* Enable transmit descriptor polling. */ + /* + ** Enable transmit descriptor polling + */ SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE); FillRxRing(pAC, &pAC->RxPort[i]); }; SkGeYellowLED(pAC, pAC->IoBase, 1); - -#ifdef USE_INT_MOD - { - unsigned long ModBase; - ModBase = 53125000 / INTS_PER_SEC; - SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase); - SK_OUT32(pAC->IoBase, B2_IRQM_MSK, IRQ_MOD_MASK); - SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START); - } -#endif + SkDimEnableModerationIfNeeded(pAC); + SkDimDisplayModerationSettings(pAC); netif_start_queue(pAC->dev[pNet->PortNr]); for (i=pAC->GIni.GIMacsFound-1; i>=0; i--) { spin_unlock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock); } - /* enable Interrupts */ - SK_OUT32(pAC->IoBase, B0_IMSK, IRQ_MASK); + /* + ** Enable Interrupts again + */ + SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK); SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); SkEventDispatcher(pAC, pAC->IoBase); - /* Found more than one port */ - if ((pAC->GIni.GIMacsFound == 2 ) && - (pAC->RlmtNets == 2)) { - /* Start both ports */ - EvPara.Para32[0] = pAC->RlmtNets; - EvPara.Para32[1] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS, - EvPara); - + /* + ** Notify RLMT about the changing and restarting one (or more) ports + */ + if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { + EvPara.Para32[0] = pAC->RlmtNets; + EvPara.Para32[1] = -1; + SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS, EvPara); + EvPara.Para32[0] = pNet->PortNr; + EvPara.Para32[1] = -1; + SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); - EvPara.Para32[1] = -1; - EvPara.Para32[0] = pNet->PortNr; + if (pOtherNet->Up) { + EvPara.Para32[0] = pOtherNet->PortNr; SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); - - if (pOtherNet->Up) { - EvPara.Para32[0] = pOtherNet->PortNr; - SkEventQueue(pAC, SKGE_RLMT, - SK_RLMT_START, EvPara); - } + } } else { SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); } @@ -3284,7 +3221,20 @@ SkEventDispatcher(pAC, pAC->IoBase); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); + /* + ** While testing this driver with latest kernel 2.5 (2.5.70), it + ** seems as if upper layers have a problem to handle a successful + ** return value of '0'. If such a zero is returned, the complete + ** system hangs for several minutes (!), which is in acceptable. + ** + ** Currently it is not clear, what the exact reason for this problem + ** is. The implemented workaround for 2.5 is to return the desired + ** new MTU size if all needed changes for the new MTU size where + ** performed. In kernels 2.2 and 2.4, a zero value is returned, + ** which indicates the successful change of the mtu-size. + */ return 0; + } /* SkGeChangeMtu */ @@ -3312,11 +3262,20 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("SkGeStats starts now...\n")); pPnmiStruct = &pAC->PnmiStruct; - memset(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA)); + +#ifdef SK_DIAG_SUPPORT + if ((pAC->DiagModeActive == DIAG_NOTACTIVE) && + (pAC->BoardLevel == SK_INIT_RUN)) { +#endif + SK_MEMSET(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA)); spin_lock_irqsave(&pAC->SlowPathLock, Flags); Size = SK_PNMI_STRUCT_SIZE; SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); +#ifdef SK_DIAG_SUPPORT + } +#endif + pPnmiStat = &pPnmiStruct->Stat[0]; pPnmiConf = &pPnmiStruct->Conf[0]; @@ -3378,10 +3337,14 @@ { DEV_NET *pNet; SK_AC *pAC; - +void *pMemBuf; +struct pci_dev *pdev = NULL; SK_GE_IOCTL Ioctl; unsigned int Err = 0; -int Size; +int Size = 0; +int Ret = 0; +unsigned int Length = 0; +int HeaderLength = sizeof(SK_U32) + sizeof(SK_U32); SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("SkGeIoctl starts now...\n")); @@ -3398,7 +3361,7 @@ case SK_IOCTL_PRESETMIB: if (!capable(CAP_NET_ADMIN)) return -EPERM; case SK_IOCTL_GETMIB: - if(copy_from_user(&pAC->PnmiStruct, Ioctl.pData, + if(copy_from_user(&pAC->PnmiStruct, Ioctl.pData, Ioctl.LenPnmiStruct)? Ioctl.Len : sizeof(pAC->PnmiStruct))) { return -EFAULT; @@ -3413,10 +3376,80 @@ return -EFAULT; } break; + case SK_IOCTL_GEN: + if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) { + Length = Ioctl.Len; + } else { + Length = sizeof(pAC->PnmiStruct) + HeaderLength; + } + if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) { + return -ENOMEM; + } + if(copy_from_user(pMemBuf, Ioctl.pData, Length)) { + Err = -EFAULT; + goto fault_gen; + } + if ((Ret = SkPnmiGenIoctl(pAC, pAC->IoBase, pMemBuf, &Length, 0)) < 0) { + Err = -EFAULT; + goto fault_gen; + } + if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) { + Err = -EFAULT; + goto fault_gen; + } + Ioctl.Len = Length; + if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) { + Err = -EFAULT; + goto fault_gen; + } +fault_gen: + kfree(pMemBuf); /* cleanup everything */ + break; +#ifdef SK_DIAG_SUPPORT + case SK_IOCTL_DIAG: + if (!capable(CAP_NET_ADMIN)) return -EPERM; + if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) { + Length = Ioctl.Len; + } else { + Length = sizeof(pAC->PnmiStruct) + HeaderLength; + } + if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) { + return -ENOMEM; + } + if(copy_from_user(pMemBuf, Ioctl.pData, Length)) { + Err = -EFAULT; + goto fault_diag; + } + pdev = pAC->PciDev; + Length = 3 * sizeof(SK_U32); /* Error, Bus and Device */ + /* + ** While coding this new IOCTL interface, only a few lines of code + ** are to to be added. Therefore no dedicated function has been + ** added. If more functionality is added, a separate function + ** should be used... + */ + * ((SK_U32 *)pMemBuf) = 0; + * ((SK_U32 *)pMemBuf + 1) = pdev->bus->number; + * ((SK_U32 *)pMemBuf + 2) = ParseDeviceNbrFromSlotName(pdev->slot_name); + if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) { + Err = -EFAULT; + goto fault_diag; + } + Ioctl.Len = Length; + if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) { + Err = -EFAULT; + goto fault_diag; + } +fault_diag: + kfree(pMemBuf); /* cleanup everything */ + break; +#endif default: Err = -EOPNOTSUPP; } + return(Err); + } /* SkGeIoctl */ @@ -3488,12 +3521,19 @@ SK_AC *pAC) /* pointer to the adapter context structure */ { SK_I32 Port; /* preferred port */ -int LinkSpeed; /* Link speed */ -int AutoNeg; /* auto negotiation off (0) or on (1) */ -int DuplexCap; /* duplex capabilities (0=both, 1=full, 2=half */ -int MSMode; /* master / slave mode selection */ SK_BOOL AutoSet; SK_BOOL DupSet; +int LinkSpeed = SK_LSPEED_AUTO; /* Link speed */ +int AutoNeg = 1; /* autoneg off (0) or on (1) */ +int DuplexCap = 0; /* 0=both,1=full,2=half */ +int FlowCtrl = SK_FLOW_MODE_SYM_OR_REM; /* FlowControl */ +int MSMode = SK_MS_MODE_AUTO; /* master/slave mode */ + +SK_BOOL IsConTypeDefined = SK_TRUE; +SK_BOOL IsLinkSpeedDefined = SK_TRUE; +SK_BOOL IsFlowCtrlDefined = SK_TRUE; +SK_BOOL IsRoleDefined = SK_TRUE; +SK_BOOL IsModeDefined = SK_TRUE; /* * The two parameters AutoNeg. and DuplexCap. map to one configuration * parameter. The mapping is described by this table: @@ -3506,362 +3546,540 @@ * ----------------------------------------------------------------- * Sense | AutoSense | AutoSense | AutoSense | */ -int Capabilities[3][3] = - { { -1, SK_LMODE_FULL, SK_LMODE_HALF}, - {SK_LMODE_AUTOBOTH, SK_LMODE_AUTOFULL, SK_LMODE_AUTOHALF}, +int Capabilities[3][3] = + { { -1, SK_LMODE_FULL , SK_LMODE_HALF }, + {SK_LMODE_AUTOBOTH , SK_LMODE_AUTOFULL , SK_LMODE_AUTOHALF }, {SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE} }; + #define DC_BOTH 0 #define DC_FULL 1 #define DC_HALF 2 #define AN_OFF 0 #define AN_ON 1 #define AN_SENS 2 +#define M_CurrPort pAC->GIni.GP[Port] + + + /* + ** Set the default values first for both ports! + */ + for (Port = 0; Port < SK_MAX_MACS; Port++) { + M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH]; + M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM; + M_CurrPort.PMSMode = SK_MS_MODE_AUTO; + M_CurrPort.PLinkSpeed = SK_LSPEED_AUTO; + } + + /* + ** Check merged parameter ConType. If it has not been used, + ** verify any other parameter (e.g. AutoNeg) and use default values. + ** + ** Stating both ConType and other lowlevel link parameters is also + ** possible. If this is the case, the passed ConType-parameter is + ** overwritten by the lowlevel link parameter. + ** + ** The following settings are used for a merged ConType-parameter: + ** + ** ConType DupCap AutoNeg FlowCtrl Role Speed + ** ------- ------ ------- -------- ---------- ----- + ** Auto Both On SymOrRem Auto Auto + ** 100FD Full Off None 100 + ** 100HD Half Off None 100 + ** 10FD Full Off None 10 + ** 10HD Half Off None 10 + ** + ** This ConType parameter is used for all ports of the adapter! + */ + if ( (ConType != NULL) && + (pAC->Index < SK_MAX_CARD_PARAM) && + (ConType[pAC->Index] != NULL) ) { + + /* Check chipset family */ + if ((!pAC->ChipsetType) && + (strcmp(ConType[pAC->Index],"Auto")!=0) && + (strcmp(ConType[pAC->Index],"")!=0)) { + /* Set the speed parameter back */ + printk("sk98lin: Illegal value \"%s\" " + "for ConType." + " Using Auto.\n", + ConType[pAC->Index]); - /* settings for port A */ - /* settings link speed */ - LinkSpeed = SK_LSPEED_AUTO; /* default: do auto select */ + sprintf(ConType[pAC->Index], "Auto"); + } + + if (strcmp(ConType[pAC->Index],"")==0) { + IsConTypeDefined = SK_FALSE; /* No ConType defined */ + } else if (strcmp(ConType[pAC->Index],"Auto")==0) { + for (Port = 0; Port < SK_MAX_MACS; Port++) { + M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH]; + M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM; + M_CurrPort.PMSMode = SK_MS_MODE_AUTO; + M_CurrPort.PLinkSpeed = SK_LSPEED_AUTO; + } + } else if (strcmp(ConType[pAC->Index],"100FD")==0) { + for (Port = 0; Port < SK_MAX_MACS; Port++) { + M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL]; + M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE; + M_CurrPort.PMSMode = SK_MS_MODE_AUTO; + M_CurrPort.PLinkSpeed = SK_LSPEED_100MBPS; + } + } else if (strcmp(ConType[pAC->Index],"100HD")==0) { + for (Port = 0; Port < SK_MAX_MACS; Port++) { + M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF]; + M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE; + M_CurrPort.PMSMode = SK_MS_MODE_AUTO; + M_CurrPort.PLinkSpeed = SK_LSPEED_100MBPS; + } + } else if (strcmp(ConType[pAC->Index],"10FD")==0) { + for (Port = 0; Port < SK_MAX_MACS; Port++) { + M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL]; + M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE; + M_CurrPort.PMSMode = SK_MS_MODE_AUTO; + M_CurrPort.PLinkSpeed = SK_LSPEED_10MBPS; + } + } else if (strcmp(ConType[pAC->Index],"10HD")==0) { + for (Port = 0; Port < SK_MAX_MACS; Port++) { + M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF]; + M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE; + M_CurrPort.PMSMode = SK_MS_MODE_AUTO; + M_CurrPort.PLinkSpeed = SK_LSPEED_10MBPS; + } + } else { + printk("sk98lin: Illegal value \"%s\" for ConType\n", + ConType[pAC->Index]); + IsConTypeDefined = SK_FALSE; /* Wrong ConType defined */ + } + } else { + IsConTypeDefined = SK_FALSE; /* No ConType defined */ + } + + /* + ** Parse any parameter settings for port A: + ** a) any LinkSpeed stated? + */ if (Speed_A != NULL && pAC->IndexIndex] != NULL) { if (strcmp(Speed_A[pAC->Index],"")==0) { - LinkSpeed = SK_LSPEED_AUTO; - } - else if (strcmp(Speed_A[pAC->Index],"Auto")==0) { - LinkSpeed = SK_LSPEED_AUTO; - } - else if (strcmp(Speed_A[pAC->Index],"10")==0) { - LinkSpeed = SK_LSPEED_10MBPS; - } - else if (strcmp(Speed_A[pAC->Index],"100")==0) { - LinkSpeed = SK_LSPEED_100MBPS; - } - else if (strcmp(Speed_A[pAC->Index],"1000")==0) { - LinkSpeed = SK_LSPEED_1000MBPS; + IsLinkSpeedDefined = SK_FALSE; + } else if (strcmp(Speed_A[pAC->Index],"Auto")==0) { + LinkSpeed = SK_LSPEED_AUTO; + } else if (strcmp(Speed_A[pAC->Index],"10")==0) { + LinkSpeed = SK_LSPEED_10MBPS; + } else if (strcmp(Speed_A[pAC->Index],"100")==0) { + LinkSpeed = SK_LSPEED_100MBPS; + } else if (strcmp(Speed_A[pAC->Index],"1000")==0) { + LinkSpeed = SK_LSPEED_1000MBPS; + } else { + printk("sk98lin: Illegal value \"%s\" for Speed_A\n", + Speed_A[pAC->Index]); + IsLinkSpeedDefined = SK_FALSE; } - else printk("%s: Illegal value for Speed_A\n", - pAC->dev[0]->name); + } else { + IsLinkSpeedDefined = SK_FALSE; } - /* Check speed parameter */ - /* Only copper type adapter and GE V2 cards */ - if (((pAC->GIni.GIChipId != CHIP_ID_YUKON) || - (pAC->GIni.GICopperType != SK_TRUE)) && - ((LinkSpeed != SK_LSPEED_AUTO) && + /* + ** Check speed parameter: + ** Only copper type adapter and GE V2 cards + */ + if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) && + ((LinkSpeed != SK_LSPEED_AUTO) && (LinkSpeed != SK_LSPEED_1000MBPS))) { - printk("%s: Illegal value for Speed_A. " + printk("sk98lin: Illegal value for Speed_A. " "Not a copper card or GE V2 card\n Using " - "speed 1000\n", pAC->dev[0]->name); + "speed 1000\n"); LinkSpeed = SK_LSPEED_1000MBPS; } - pAC->GIni.GP[0].PLinkSpeed = LinkSpeed; + + /* + ** Decide whether to set new config value if somethig valid has + ** been received. + */ + if (IsLinkSpeedDefined) { + pAC->GIni.GP[0].PLinkSpeed = LinkSpeed; + } - /* Autonegotiation */ + /* + ** b) Any Autonegotiation and DuplexCapabilities set? + ** Please note that both belong together... + */ AutoNeg = AN_ON; /* tschilling: Default: Autonegotiation on! */ AutoSet = SK_FALSE; if (AutoNeg_A != NULL && pAC->IndexIndex] != NULL) { AutoSet = SK_TRUE; if (strcmp(AutoNeg_A[pAC->Index],"")==0) { - AutoSet = SK_FALSE; - } - else if (strcmp(AutoNeg_A[pAC->Index],"On")==0) { - AutoNeg = AN_ON; - } - else if (strcmp(AutoNeg_A[pAC->Index],"Off")==0) { - AutoNeg = AN_OFF; - } - else if (strcmp(AutoNeg_A[pAC->Index],"Sense")==0) { - AutoNeg = AN_SENS; + AutoSet = SK_FALSE; + } else if (strcmp(AutoNeg_A[pAC->Index],"On")==0) { + AutoNeg = AN_ON; + } else if (strcmp(AutoNeg_A[pAC->Index],"Off")==0) { + AutoNeg = AN_OFF; + } else if (strcmp(AutoNeg_A[pAC->Index],"Sense")==0) { + AutoNeg = AN_SENS; + } else { + printk("sk98lin: Illegal value \"%s\" for AutoNeg_A\n", + AutoNeg_A[pAC->Index]); } - else printk("%s: Illegal value for AutoNeg_A\n", - pAC->dev[0]->name); } DuplexCap = DC_BOTH; - DupSet = SK_FALSE; + DupSet = SK_FALSE; if (DupCap_A != NULL && pAC->IndexIndex] != NULL) { DupSet = SK_TRUE; if (strcmp(DupCap_A[pAC->Index],"")==0) { - DupSet = SK_FALSE; - } - else if (strcmp(DupCap_A[pAC->Index],"Both")==0) { - DuplexCap = DC_BOTH; - } - else if (strcmp(DupCap_A[pAC->Index],"Full")==0) { - DuplexCap = DC_FULL; - } - else if (strcmp(DupCap_A[pAC->Index],"Half")==0) { - DuplexCap = DC_HALF; + DupSet = SK_FALSE; + } else if (strcmp(DupCap_A[pAC->Index],"Both")==0) { + DuplexCap = DC_BOTH; + } else if (strcmp(DupCap_A[pAC->Index],"Full")==0) { + DuplexCap = DC_FULL; + } else if (strcmp(DupCap_A[pAC->Index],"Half")==0) { + DuplexCap = DC_HALF; + } else { + printk("sk98lin: Illegal value \"%s\" for DupCap_A\n", + DupCap_A[pAC->Index]); } - else printk("%s: Illegal value for DupCap_A\n", - pAC->dev[0]->name); } - - /* check for illegal combinations */ - if (AutoSet && AutoNeg==AN_SENS && DupSet) { - printk("%s, Port A: DuplexCapabilities" - " ignored using Sense mode\n", pAC->dev[0]->name); + + /* + ** Check for illegal combinations + */ + if ((LinkSpeed == SK_LSPEED_1000MBPS) && + ((DuplexCap == SK_LMODE_STAT_AUTOHALF) || + (DuplexCap == SK_LMODE_STAT_HALF)) && + (pAC->ChipsetType)) { + printk("sk98lin: Half Duplex not possible with Gigabit speed!\n" + " Using Full Duplex.\n"); + DuplexCap = DC_FULL; } + + if ( AutoSet && AutoNeg==AN_SENS && DupSet) { + printk("sk98lin, Port A: DuplexCapabilities" + " ignored using Sense mode\n"); + } + if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){ - printk("%s, Port A: Illegal combination" + printk("sk98lin: Port A: Illegal combination" " of values AutoNeg. and DuplexCap.\n Using " - "Full Duplex\n", pAC->dev[0]->name); - + "Full Duplex\n"); DuplexCap = DC_FULL; } + if (AutoSet && AutoNeg==AN_OFF && !DupSet) { DuplexCap = DC_FULL; } if (!AutoSet && DupSet) { - printk("%s, Port A: Duplex setting not" + printk("sk98lin: Port A: Duplex setting not" " possible in\n default AutoNegotiation mode" - " (Sense).\n Using AutoNegotiation On\n", - pAC->dev[0]->name); + " (Sense).\n Using AutoNegotiation On\n"); AutoNeg = AN_ON; } - /* set the desired mode */ - pAC->GIni.GP[0].PLinkModeConf = - Capabilities[AutoNeg][DuplexCap]; + /* + ** set the desired mode + */ + if (AutoSet || DupSet) { + pAC->GIni.GP[0].PLinkModeConf = Capabilities[AutoNeg][DuplexCap]; + } - pAC->GIni.GP[0].PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM; + /* + ** c) Any Flowcontrol-parameter set? + */ if (FlowCtrl_A != NULL && pAC->IndexIndex] != NULL) { if (strcmp(FlowCtrl_A[pAC->Index],"") == 0) { + IsFlowCtrlDefined = SK_FALSE; + } else if (strcmp(FlowCtrl_A[pAC->Index],"SymOrRem") == 0) { + FlowCtrl = SK_FLOW_MODE_SYM_OR_REM; + } else if (strcmp(FlowCtrl_A[pAC->Index],"Sym")==0) { + FlowCtrl = SK_FLOW_MODE_SYMMETRIC; + } else if (strcmp(FlowCtrl_A[pAC->Index],"LocSend")==0) { + FlowCtrl = SK_FLOW_MODE_LOC_SEND; + } else if (strcmp(FlowCtrl_A[pAC->Index],"None")==0) { + FlowCtrl = SK_FLOW_MODE_NONE; + } else { + printk("sk98lin: Illegal value \"%s\" for FlowCtrl_A\n", + FlowCtrl_A[pAC->Index]); + IsFlowCtrlDefined = SK_FALSE; } - else if (strcmp(FlowCtrl_A[pAC->Index],"SymOrRem") == 0) { - pAC->GIni.GP[0].PFlowCtrlMode = - SK_FLOW_MODE_SYM_OR_REM; - } - else if (strcmp(FlowCtrl_A[pAC->Index],"Sym")==0) { - pAC->GIni.GP[0].PFlowCtrlMode = - SK_FLOW_MODE_SYMMETRIC; - } - else if (strcmp(FlowCtrl_A[pAC->Index],"LocSend")==0) { - pAC->GIni.GP[0].PFlowCtrlMode = - SK_FLOW_MODE_LOC_SEND; - } - else if (strcmp(FlowCtrl_A[pAC->Index],"None")==0) { - pAC->GIni.GP[0].PFlowCtrlMode = - SK_FLOW_MODE_NONE; - } - else printk("Illegal value for FlowCtrl_A\n"); - } - if (AutoNeg==AN_OFF && pAC->GIni.GP[0].PFlowCtrlMode!= - SK_FLOW_MODE_NONE) { - printk("%s, Port A: FlowControl" + } else { + IsFlowCtrlDefined = SK_FALSE; + } + + if (IsFlowCtrlDefined) { + if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) { + printk("sk98lin: Port A: FlowControl" " impossible without AutoNegotiation," - " disabled\n", pAC->dev[0]->name); - pAC->GIni.GP[0].PFlowCtrlMode = SK_FLOW_MODE_NONE; + " disabled\n"); + FlowCtrl = SK_FLOW_MODE_NONE; + } + pAC->GIni.GP[0].PFlowCtrlMode = FlowCtrl; } - MSMode = SK_MS_MODE_AUTO; /* default: do auto select */ + /* + ** d) What is with the RoleParameter? + */ if (Role_A != NULL && pAC->IndexIndex] != NULL) { if (strcmp(Role_A[pAC->Index],"")==0) { + IsRoleDefined = SK_FALSE; + } else if (strcmp(Role_A[pAC->Index],"Auto")==0) { + MSMode = SK_MS_MODE_AUTO; + } else if (strcmp(Role_A[pAC->Index],"Master")==0) { + MSMode = SK_MS_MODE_MASTER; + } else if (strcmp(Role_A[pAC->Index],"Slave")==0) { + MSMode = SK_MS_MODE_SLAVE; + } else { + printk("sk98lin: Illegal value \"%s\" for Role_A\n", + Role_A[pAC->Index]); + IsRoleDefined = SK_FALSE; } - else if (strcmp(Role_A[pAC->Index],"Auto")==0) { - MSMode = SK_MS_MODE_AUTO; - } - else if (strcmp(Role_A[pAC->Index],"Master")==0) { - MSMode = SK_MS_MODE_MASTER; - } - else if (strcmp(Role_A[pAC->Index],"Slave")==0) { - MSMode = SK_MS_MODE_SLAVE; - } - else printk("%s: Illegal value for Role_A\n", - pAC->dev[0]->name); + } else { + IsRoleDefined = SK_FALSE; + } + + if (IsRoleDefined == SK_TRUE) { + pAC->GIni.GP[0].PMSMode = MSMode; } - pAC->GIni.GP[0].PMSMode = MSMode; + - /* settings for port B */ - /* settings link speed */ - LinkSpeed = SK_LSPEED_AUTO; /* default: do auto select */ + /* + ** Parse any parameter settings for port B: + ** a) any LinkSpeed stated? + */ + IsConTypeDefined = SK_TRUE; + IsLinkSpeedDefined = SK_TRUE; + IsFlowCtrlDefined = SK_TRUE; + IsModeDefined = SK_TRUE; + if (Speed_B != NULL && pAC->IndexIndex] != NULL) { if (strcmp(Speed_B[pAC->Index],"")==0) { - LinkSpeed = SK_LSPEED_AUTO; - } - else if (strcmp(Speed_B[pAC->Index],"Auto")==0) { - LinkSpeed = SK_LSPEED_AUTO; - } - else if (strcmp(Speed_B[pAC->Index],"10")==0) { - LinkSpeed = SK_LSPEED_10MBPS; - } - else if (strcmp(Speed_B[pAC->Index],"100")==0) { - LinkSpeed = SK_LSPEED_100MBPS; - } - else if (strcmp(Speed_B[pAC->Index],"1000")==0) { - LinkSpeed = SK_LSPEED_1000MBPS; + IsLinkSpeedDefined = SK_FALSE; + } else if (strcmp(Speed_B[pAC->Index],"Auto")==0) { + LinkSpeed = SK_LSPEED_AUTO; + } else if (strcmp(Speed_B[pAC->Index],"10")==0) { + LinkSpeed = SK_LSPEED_10MBPS; + } else if (strcmp(Speed_B[pAC->Index],"100")==0) { + LinkSpeed = SK_LSPEED_100MBPS; + } else if (strcmp(Speed_B[pAC->Index],"1000")==0) { + LinkSpeed = SK_LSPEED_1000MBPS; + } else { + printk("sk98lin: Illegal value \"%s\" for Speed_B\n", + Speed_B[pAC->Index]); + IsLinkSpeedDefined = SK_FALSE; } - else printk("%s: Illegal value for Speed_B\n", - pAC->dev[1]->name); + } else { + IsLinkSpeedDefined = SK_FALSE; } - /* Check speed parameter */ - /* Only copper type adapter and GE V2 cards */ - if (((pAC->GIni.GIChipId != CHIP_ID_YUKON) || - (pAC->GIni.GICopperType != SK_TRUE)) && - ((LinkSpeed != SK_LSPEED_AUTO) && + /* + ** Check speed parameter: + ** Only copper type adapter and GE V2 cards + */ + if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) && + ((LinkSpeed != SK_LSPEED_AUTO) && (LinkSpeed != SK_LSPEED_1000MBPS))) { - printk("%s: Illegal value for Speed_B. " + printk("sk98lin: Illegal value for Speed_B. " "Not a copper card or GE V2 card\n Using " - "speed 1000\n", pAC->dev[1]->name); + "speed 1000\n"); LinkSpeed = SK_LSPEED_1000MBPS; } - pAC->GIni.GP[1].PLinkSpeed = LinkSpeed; - /* Auto negotiation */ + /* + ** Decide whether to set new config value if somethig valid has + ** been received. + */ + if (IsLinkSpeedDefined) { + pAC->GIni.GP[1].PLinkSpeed = LinkSpeed; + } + + /* + ** b) Any Autonegotiation and DuplexCapabilities set? + ** Please note that both belong together... + */ AutoNeg = AN_SENS; /* default: do auto Sense */ AutoSet = SK_FALSE; if (AutoNeg_B != NULL && pAC->IndexIndex] != NULL) { AutoSet = SK_TRUE; if (strcmp(AutoNeg_B[pAC->Index],"")==0) { - AutoSet = SK_FALSE; - } - else if (strcmp(AutoNeg_B[pAC->Index],"On")==0) { - AutoNeg = AN_ON; - } - else if (strcmp(AutoNeg_B[pAC->Index],"Off")==0) { - AutoNeg = AN_OFF; - } - else if (strcmp(AutoNeg_B[pAC->Index],"Sense")==0) { - AutoNeg = AN_SENS; + AutoSet = SK_FALSE; + } else if (strcmp(AutoNeg_B[pAC->Index],"On")==0) { + AutoNeg = AN_ON; + } else if (strcmp(AutoNeg_B[pAC->Index],"Off")==0) { + AutoNeg = AN_OFF; + } else if (strcmp(AutoNeg_B[pAC->Index],"Sense")==0) { + AutoNeg = AN_SENS; + } else { + printk("sk98lin: Illegal value \"%s\" for AutoNeg_B\n", + AutoNeg_B[pAC->Index]); } - else printk("Illegal value for AutoNeg_B\n"); } DuplexCap = DC_BOTH; - DupSet = SK_FALSE; + DupSet = SK_FALSE; if (DupCap_B != NULL && pAC->IndexIndex] != NULL) { DupSet = SK_TRUE; if (strcmp(DupCap_B[pAC->Index],"")==0) { - DupSet = SK_FALSE; - } - else if (strcmp(DupCap_B[pAC->Index],"Both")==0) { - DuplexCap = DC_BOTH; - } - else if (strcmp(DupCap_B[pAC->Index],"Full")==0) { - DuplexCap = DC_FULL; - } - else if (strcmp(DupCap_B[pAC->Index],"Half")==0) { - DuplexCap = DC_HALF; + DupSet = SK_FALSE; + } else if (strcmp(DupCap_B[pAC->Index],"Both")==0) { + DuplexCap = DC_BOTH; + } else if (strcmp(DupCap_B[pAC->Index],"Full")==0) { + DuplexCap = DC_FULL; + } else if (strcmp(DupCap_B[pAC->Index],"Half")==0) { + DuplexCap = DC_HALF; + } else { + printk("sk98lin: Illegal value \"%s\" for DupCap_B\n", + DupCap_B[pAC->Index]); } - else printk("Illegal value for DupCap_B\n"); } + - /* check for illegal combinations */ + /* + ** Check for illegal combinations + */ + if ((LinkSpeed == SK_LSPEED_1000MBPS) && + ((DuplexCap == SK_LMODE_STAT_AUTOHALF) || + (DuplexCap == SK_LMODE_STAT_HALF)) && + (pAC->ChipsetType)) { + printk("sk98lin: Half Duplex not possible with Gigabit speed!\n" + " Using Full Duplex.\n"); + DuplexCap = DC_FULL; + } + if (AutoSet && AutoNeg==AN_SENS && DupSet) { - printk("%s, Port B: DuplexCapabilities" - " ignored using Sense mode\n", pAC->dev[1]->name); + printk("sk98lin, Port B: DuplexCapabilities" + " ignored using Sense mode\n"); } + if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){ - printk("%s, Port B: Illegal combination" + printk("sk98lin: Port B: Illegal combination" " of values AutoNeg. and DuplexCap.\n Using " - "Full Duplex\n", pAC->dev[1]->name); - + "Full Duplex\n"); DuplexCap = DC_FULL; } + if (AutoSet && AutoNeg==AN_OFF && !DupSet) { DuplexCap = DC_FULL; } if (!AutoSet && DupSet) { - printk("%s, Port B: Duplex setting not" + printk("sk98lin: Port B: Duplex setting not" " possible in\n default AutoNegotiation mode" - " (Sense).\n Using AutoNegotiation On\n", - pAC->dev[1]->name); + " (Sense).\n Using AutoNegotiation On\n"); AutoNeg = AN_ON; } - /* set the desired mode */ - pAC->GIni.GP[1].PLinkModeConf = - Capabilities[AutoNeg][DuplexCap]; + /* + ** set the desired mode + */ + if (AutoSet || DupSet) { + pAC->GIni.GP[1].PLinkModeConf = Capabilities[AutoNeg][DuplexCap]; + } - pAC->GIni.GP[1].PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM; + /* + ** c) Any FlowCtrl parameter set? + */ if (FlowCtrl_B != NULL && pAC->IndexIndex] != NULL) { if (strcmp(FlowCtrl_B[pAC->Index],"") == 0) { + IsFlowCtrlDefined = SK_FALSE; + } else if (strcmp(FlowCtrl_B[pAC->Index],"SymOrRem") == 0) { + FlowCtrl = SK_FLOW_MODE_SYM_OR_REM; + } else if (strcmp(FlowCtrl_B[pAC->Index],"Sym")==0) { + FlowCtrl = SK_FLOW_MODE_SYMMETRIC; + } else if (strcmp(FlowCtrl_B[pAC->Index],"LocSend")==0) { + FlowCtrl = SK_FLOW_MODE_LOC_SEND; + } else if (strcmp(FlowCtrl_B[pAC->Index],"None")==0) { + FlowCtrl = SK_FLOW_MODE_NONE; + } else { + printk("sk98lin: Illegal value \"%s\" for FlowCtrl_B\n", + FlowCtrl_B[pAC->Index]); + IsFlowCtrlDefined = SK_FALSE; } - else if (strcmp(FlowCtrl_B[pAC->Index],"SymOrRem") == 0) { - pAC->GIni.GP[1].PFlowCtrlMode = - SK_FLOW_MODE_SYM_OR_REM; - } - else if (strcmp(FlowCtrl_B[pAC->Index],"Sym")==0) { - pAC->GIni.GP[1].PFlowCtrlMode = - SK_FLOW_MODE_SYMMETRIC; - } - else if (strcmp(FlowCtrl_B[pAC->Index],"LocSend")==0) { - pAC->GIni.GP[1].PFlowCtrlMode = - SK_FLOW_MODE_LOC_SEND; - } - else if (strcmp(FlowCtrl_B[pAC->Index],"None")==0) { - pAC->GIni.GP[1].PFlowCtrlMode = - SK_FLOW_MODE_NONE; - } - else printk("Illegal value for FlowCtrl_B\n"); - } - if (AutoNeg==AN_OFF && pAC->GIni.GP[1].PFlowCtrlMode!= - SK_FLOW_MODE_NONE) { - printk("%s, Port B: FlowControl" + } else { + IsFlowCtrlDefined = SK_FALSE; + } + + if (IsFlowCtrlDefined) { + if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) { + printk("sk98lin: Port B: FlowControl" " impossible without AutoNegotiation," - " disabled\n", pAC->dev[1]->name); - pAC->GIni.GP[1].PFlowCtrlMode = SK_FLOW_MODE_NONE; + " disabled\n"); + FlowCtrl = SK_FLOW_MODE_NONE; + } + pAC->GIni.GP[1].PFlowCtrlMode = FlowCtrl; } - MSMode = SK_MS_MODE_AUTO; /* default: do auto select */ + /* + ** d) What is the RoleParameter? + */ if (Role_B != NULL && pAC->IndexIndex] != NULL) { if (strcmp(Role_B[pAC->Index],"")==0) { + IsRoleDefined = SK_FALSE; + } else if (strcmp(Role_B[pAC->Index],"Auto")==0) { + MSMode = SK_MS_MODE_AUTO; + } else if (strcmp(Role_B[pAC->Index],"Master")==0) { + MSMode = SK_MS_MODE_MASTER; + } else if (strcmp(Role_B[pAC->Index],"Slave")==0) { + MSMode = SK_MS_MODE_SLAVE; + } else { + printk("sk98lin: Illegal value \"%s\" for Role_B\n", + Role_B[pAC->Index]); + IsRoleDefined = SK_FALSE; } - else if (strcmp(Role_B[pAC->Index],"Auto")==0) { - MSMode = SK_MS_MODE_AUTO; - } - else if (strcmp(Role_B[pAC->Index],"Master")==0) { - MSMode = SK_MS_MODE_MASTER; - } - else if (strcmp(Role_B[pAC->Index],"Slave")==0) { - MSMode = SK_MS_MODE_SLAVE; - } - else printk("%s: Illegal value for Role_B\n", - pAC->dev[1]->name); + } else { + IsRoleDefined = SK_FALSE; + } + + if (IsRoleDefined) { + pAC->GIni.GP[1].PMSMode = MSMode; } - pAC->GIni.GP[1].PMSMode = MSMode; - - /* settings for both ports */ + /* + ** Evaluate settings for both ports + */ pAC->ActivePort = 0; if (PrefPort != NULL && pAC->IndexIndex] != NULL) { if (strcmp(PrefPort[pAC->Index],"") == 0) { /* Auto */ - pAC->ActivePort = 0; + pAC->ActivePort = 0; pAC->Rlmt.Net[0].Preference = -1; /* auto */ - pAC->Rlmt.Net[0].PrefPort = 0; - } - else if (strcmp(PrefPort[pAC->Index],"A") == 0) { + pAC->Rlmt.Net[0].PrefPort = 0; + } else if (strcmp(PrefPort[pAC->Index],"A") == 0) { /* - * do not set ActivePort here, thus a port - * switch is issued after net up. - */ - Port = 0; + ** do not set ActivePort here, thus a port + ** switch is issued after net up. + */ + Port = 0; pAC->Rlmt.Net[0].Preference = Port; - pAC->Rlmt.Net[0].PrefPort = Port; - } - else if (strcmp(PrefPort[pAC->Index],"B") == 0) { + pAC->Rlmt.Net[0].PrefPort = Port; + } else if (strcmp(PrefPort[pAC->Index],"B") == 0) { /* - * do not set ActivePort here, thus a port - * switch is issued after net up. - */ - Port = 1; - pAC->Rlmt.Net[0].Preference = Port; - pAC->Rlmt.Net[0].PrefPort = Port; + ** do not set ActivePort here, thus a port + ** switch is issued after net up. + */ + if (pAC->GIni.GIMacsFound == 1) { + printk("sk98lin: Illegal value \"B\" for PrefPort.\n" + " Port B not available on single port adapters.\n"); + + pAC->ActivePort = 0; + pAC->Rlmt.Net[0].Preference = -1; /* auto */ + pAC->Rlmt.Net[0].PrefPort = 0; + } else { + Port = 1; + pAC->Rlmt.Net[0].Preference = Port; + pAC->Rlmt.Net[0].PrefPort = Port; + } + } else { + printk("sk98lin: Illegal value \"%s\" for PrefPort\n", + PrefPort[pAC->Index]); } - else printk("%s: Illegal value for PrefPort\n", - pAC->dev[0]->name); } pAC->RlmtNets = 1; @@ -3870,33 +4088,140 @@ RlmtMode[pAC->Index] != NULL) { if (strcmp(RlmtMode[pAC->Index], "") == 0) { pAC->RlmtMode = 0; - } - else if (strcmp(RlmtMode[pAC->Index], "CheckLinkState") == 0) { + } else if (strcmp(RlmtMode[pAC->Index], "CheckLinkState") == 0) { pAC->RlmtMode = SK_RLMT_CHECK_LINK; - } - else if (strcmp(RlmtMode[pAC->Index], "CheckLocalPort") == 0) { + } else if (strcmp(RlmtMode[pAC->Index], "CheckLocalPort") == 0) { pAC->RlmtMode = SK_RLMT_CHECK_LINK | - SK_RLMT_CHECK_LOC_LINK; + SK_RLMT_CHECK_LOC_LINK; + } else if (strcmp(RlmtMode[pAC->Index], "CheckSeg") == 0) { + pAC->RlmtMode = SK_RLMT_CHECK_LINK | + SK_RLMT_CHECK_LOC_LINK | + SK_RLMT_CHECK_SEG; + } else if ((strcmp(RlmtMode[pAC->Index], "DualNet") == 0) && + (pAC->GIni.GIMacsFound == 2)) { + pAC->RlmtMode = SK_RLMT_CHECK_LINK; + pAC->RlmtNets = 2; + } else { + printk("sk98lin: Illegal value \"%s\" for" + " RlmtMode, using default\n", + RlmtMode[pAC->Index]); + pAC->RlmtMode = 0; } - else if (strcmp(RlmtMode[pAC->Index], "CheckSeg") == 0) { - pAC->RlmtMode = SK_RLMT_CHECK_LINK | - SK_RLMT_CHECK_LOC_LINK | - SK_RLMT_CHECK_SEG; + } else { + pAC->RlmtMode = 0; + } + + /* + ** Check the interrupt moderation parameters + */ + if (Moderation[pAC->Index] != NULL) { + if (strcmp(Moderation[pAC->Index], "") == 0) { + pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; + } else if (strcmp(Moderation[pAC->Index], "Static") == 0) { + pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC; + } else if (strcmp(Moderation[pAC->Index], "Dynamic") == 0) { + pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_DYNAMIC; + } else if (strcmp(Moderation[pAC->Index], "None") == 0) { + pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; + } else { + printk("sk98lin: Illegal value \"%s\" for Moderation.\n" + " Disable interrupt moderation.\n", + Moderation[pAC->Index]); + pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; } - else if ((strcmp(RlmtMode[pAC->Index], "DualNet") == 0) && - (pAC->GIni.GIMacsFound == 2)) { - pAC->RlmtMode = SK_RLMT_CHECK_LINK; - pAC->RlmtNets = 2; + } else { + pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; + } + + if (Stats[pAC->Index] != NULL) { + if (strcmp(Stats[pAC->Index], "Yes") == 0) { + pAC->DynIrqModInfo.DisplayStats = SK_TRUE; + } else { + pAC->DynIrqModInfo.DisplayStats = SK_FALSE; } - else { - printk("%s: Illegal value for" - " RlmtMode, using default\n", pAC->dev[0]->name); - pAC->RlmtMode = 0; + } else { + pAC->DynIrqModInfo.DisplayStats = SK_FALSE; + } + + if (ModerationMask[pAC->Index] != NULL) { + if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY; + } else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY; + } else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY; + } else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX; + } else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX; + } else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; + } else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; + } else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX; + } else if (strcmp(ModerationMask[pAC->Index], "SpTx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX; + } else if (strcmp(ModerationMask[pAC->Index], "RxTxSp") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; + } else if (strcmp(ModerationMask[pAC->Index], "RxSpTx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; + } else if (strcmp(ModerationMask[pAC->Index], "TxRxSp") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; + } else if (strcmp(ModerationMask[pAC->Index], "TxSpRx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; + } else if (strcmp(ModerationMask[pAC->Index], "SpTxRx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; + } else if (strcmp(ModerationMask[pAC->Index], "SpRxTx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; + } else { /* some rubbish */ + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY; + } + } else { /* operator has stated nothing */ + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; + } + + if (AutoSizing[pAC->Index] != NULL) { + if (strcmp(AutoSizing[pAC->Index], "On") == 0) { + pAC->DynIrqModInfo.AutoSizing = SK_FALSE; + } else { + pAC->DynIrqModInfo.AutoSizing = SK_FALSE; } + } else { /* operator has stated nothing */ + pAC->DynIrqModInfo.AutoSizing = SK_FALSE; } - else { - pAC->RlmtMode = 0; + + if (IntsPerSec[pAC->Index] != 0) { + if ((IntsPerSec[pAC->Index]< C_INT_MOD_IPS_LOWER_RANGE) || + (IntsPerSec[pAC->Index] > C_INT_MOD_IPS_UPPER_RANGE)) { + printk("sk98lin: Illegal value \"%d\" for IntsPerSec. (Range: %d - %d)\n" + " Using default value of %i.\n", + IntsPerSec[pAC->Index], + C_INT_MOD_IPS_LOWER_RANGE, + C_INT_MOD_IPS_UPPER_RANGE, + C_INTS_PER_SEC_DEFAULT); + pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT; + } else { + pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index]; + } + } else { + pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT; } + + /* + ** Evaluate upper and lower moderation threshold + */ + pAC->DynIrqModInfo.MaxModIntsPerSecUpperLimit = + pAC->DynIrqModInfo.MaxModIntsPerSec + + (pAC->DynIrqModInfo.MaxModIntsPerSec / 2); + + pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit = + pAC->DynIrqModInfo.MaxModIntsPerSec - + (pAC->DynIrqModInfo.MaxModIntsPerSec / 2); + + pAC->DynIrqModInfo.PrevTimeVal = jiffies; /* initial value */ + + } /* GetConfiguration */ @@ -3931,8 +4256,44 @@ } } /* ProductStr */ +/***************************************************************************** + * + * StartDrvCleanupTimer - Start timer to check for descriptors which + * might be placed in descriptor ring, but + * havent been handled up to now + * + * Description: + * This function requests a HW-timer fo the Yukon card. The actions to + * perform when this timer expires, are located in the SkDrvEvent(). + * + * Returns: N/A + */ +static void +StartDrvCleanupTimer(SK_AC *pAC) { + SK_EVPARA EventParam; /* Event struct for timer event */ + + SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam)); + EventParam.Para32[0] = SK_DRV_RX_CLEANUP_TIMER; + SkTimerStart(pAC, pAC->IoBase, &pAC->DrvCleanupTimer, + SK_DRV_RX_CLEANUP_TIMER_LENGTH, + SKGE_DRV, SK_DRV_TIMER, EventParam); +} - +/***************************************************************************** + * + * StopDrvCleanupTimer - Stop timer to check for descriptors + * + * Description: + * This function requests a HW-timer fo the Yukon card. The actions to + * perform when this timer expires, are located in the SkDrvEvent(). + * + * Returns: N/A + */ +static void +StopDrvCleanupTimer(SK_AC *pAC) { + SkTimerStop(pAC, pAC->IoBase, &pAC->DrvCleanupTimer); + SK_MEMSET((char *) &pAC->DrvCleanupTimer, 0, sizeof(SK_TIMER)); +} /****************************************************************************/ /* functions for common modules *********************************************/ @@ -3991,8 +4352,8 @@ * Nothing */ void SkDrvFreeRlmtMbuf( -SK_AC *pAC, /* pointer to adapter context */ -SK_IOC IoC, /* the IO-context */ +SK_AC *pAC, /* pointer to adapter context */ +SK_IOC IoC, /* the IO-context */ SK_MBUF *pMbuf) /* size of the requested buffer */ { SK_MBUF *pFreeMbuf; @@ -4021,7 +4382,9 @@ */ SK_U64 SkOsGetTime(SK_AC *pAC) { - return jiffies; + SK_U64 PrivateJiffies; + SkOsGetTimeCurrent(pAC, &PrivateJiffies); + return PrivateJiffies; } /* SkOsGetTime */ @@ -4219,6 +4582,7 @@ spin_lock_irqsave( &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, Flags); + SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST); pAC->dev[Param.Para32[0]]->flags &= ~IFF_RUNNING; spin_unlock_irqrestore( @@ -4254,6 +4618,10 @@ FromPort = Param.Para32[0]; SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, ("NET UP EVENT, Port: %d ", Param.Para32[0])); + /* Mac update */ + SkAddrMcUpdate(pAC,IoC, FromPort); + + if (DoPrintInterfaceChange) { printk("%s: network connection up using" " port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]); @@ -4269,6 +4637,7 @@ printk(" speed: unknown\n"); } + Stat = pAC->GIni.GP[FromPort].PLinkModeStatus; if (Stat == SK_LMODE_STAT_AUTOHALF || Stat == SK_LMODE_STAT_AUTOFULL) { @@ -4314,17 +4683,42 @@ } } + /* + Display dim (dynamic interrupt moderation) + informations + */ + if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) + printk(" irq moderation: static (%d ints/sec)\n", + pAC->DynIrqModInfo.MaxModIntsPerSec); + else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) + printk(" irq moderation: dynamic (%d ints/sec)\n", + pAC->DynIrqModInfo.MaxModIntsPerSec); + else + printk(" irq moderation: disabled\n"); + + #ifdef SK_ZEROCOPY - if (pAC->GIni.GIChipId == CHIP_ID_YUKON) + if (pAC->ChipsetType) +#ifdef USE_SK_TX_CHECKSUM printk(" scatter-gather: enabled\n"); +#else + printk(" tx-checksum: disabled\n"); +#endif else printk(" scatter-gather: disabled\n"); - #else printk(" scatter-gather: disabled\n"); #endif - - if ((Param.Para32[0] != pAC->ActivePort) && + +#ifndef USE_SK_RX_CHECKSUM + printk(" rx-checksum: disabled\n"); +#endif + + } else { + DoPrintInterfaceChange = SK_TRUE; + } + + if ((Param.Para32[0] != pAC->ActivePort) && (pAC->RlmtNets == 1)) { NewPara.Para32[0] = pAC->ActivePort; NewPara.Para32[1] = Param.Para32[0]; @@ -4340,7 +4734,12 @@ /* action list 7 */ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, ("NET DOWN EVENT ")); - printk("%s: network connection down\n", pAC->dev[Param.Para32[1]]->name); + if (DoPrintInterfaceChange) { + printk("%s: network connection down\n", + pAC->dev[Param.Para32[1]]->name); + } else { + DoPrintInterfaceChange = SK_TRUE; + } pAC->dev[Param.Para32[1]]->flags &= ~IFF_RUNNING; break; case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */ @@ -4379,7 +4778,7 @@ ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]); ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]); spin_lock_irqsave( - &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, + &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, Flags); spin_lock_irqsave( &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags); @@ -4441,6 +4840,31 @@ DEV_KFREE_SKB_ANY(pMsg); break; + case SK_DRV_TIMER: + if (Param.Para32[0] == SK_DRV_MODERATION_TIMER) { + /* + ** expiration of the moderation timer implies that + ** dynamic moderation is to be applied + */ + SkDimStartModerationTimer(pAC); + SkDimModerate(pAC); + if (pAC->DynIrqModInfo.DisplayStats) { + SkDimDisplayModerationSettings(pAC); + } + } else if (Param.Para32[0] == SK_DRV_RX_CLEANUP_TIMER) { + /* + ** check if we need to check for descriptors which + ** haven't been handled the last millisecs + */ + StartDrvCleanupTimer(pAC); + if (pAC->GIni.GIMacsFound == 2) { + ReceiveIrq(pAC, &pAC->RxPort[1], SK_FALSE); + } + ReceiveIrq(pAC, &pAC->RxPort[0], SK_FALSE); + } else { + printk("Expiration of unknown timer\n"); + } + break; default: break; } @@ -4500,6 +4924,229 @@ } /* SkErrorLog */ +#ifdef SK_DIAG_SUPPORT + +/***************************************************************************** + * + * SkDrvEnterDiagMode - handles DIAG attach request + * + * Description: + * Notify the kernel to NOT access the card any longer due to DIAG + * Deinitialize the Card + * + * Returns: + * int + */ +int SkDrvEnterDiagMode( +SK_AC *pAc) /* pointer to adapter context */ +{ + SK_AC *pAC = NULL; + DEV_NET *pNet = NULL; + + pNet = (DEV_NET *) pAc->dev[0]->priv; + pAC = pNet->pAC; + + SK_MEMCPY(&(pAc->PnmiBackup), &(pAc->PnmiStruct), + sizeof(SK_PNMI_STRUCT_DATA)); + + pAC->DiagModeActive = DIAG_ACTIVE; + if (pAC->BoardLevel > SK_INIT_DATA) { + if (pNet->Up) { + pAC->WasIfUp[0] = SK_TRUE; + pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ + DoPrintInterfaceChange = SK_FALSE; + SkDrvDeInitAdapter(pAC, 0); /* performs SkGeClose */ + } else { + pAC->WasIfUp[0] = SK_FALSE; + } + if (pNet != (DEV_NET *) pAc->dev[1]->priv) { + pNet = (DEV_NET *) pAc->dev[1]->priv; + if (pNet->Up) { + pAC->WasIfUp[1] = SK_TRUE; + pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ + DoPrintInterfaceChange = SK_FALSE; + SkDrvDeInitAdapter(pAC, 1); /* do SkGeClose */ + } else { + pAC->WasIfUp[1] = SK_FALSE; + } + } + pAC->BoardLevel = SK_INIT_DATA; + } + return(0); +} + +/***************************************************************************** + * + * SkDrvLeaveDiagMode - handles DIAG detach request + * + * Description: + * Notify the kernel to may access the card again after use by DIAG + * Initialize the Card + * + * Returns: + * int + */ +int SkDrvLeaveDiagMode( +SK_AC *pAc) /* pointer to adapter control context */ +{ + SK_MEMCPY(&(pAc->PnmiStruct), &(pAc->PnmiBackup), + sizeof(SK_PNMI_STRUCT_DATA)); + pAc->DiagModeActive = DIAG_NOTACTIVE; + pAc->Pnmi.DiagAttached = SK_DIAG_IDLE; + if (pAc->WasIfUp[0] == SK_TRUE) { + pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ + DoPrintInterfaceChange = SK_FALSE; + SkDrvInitAdapter(pAc, 0); /* first device */ + } + if (pAc->WasIfUp[1] == SK_TRUE) { + pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ + DoPrintInterfaceChange = SK_FALSE; + SkDrvInitAdapter(pAc, 1); /* second device */ + } + return(0); +} + +/***************************************************************************** + * + * ParseDeviceNbrFromSlotName - Evaluate PCI device number + * + * Description: + * This function parses the PCI slot name information string and will + * retrieve the devcie number out of it. The slot_name maintianed by + * linux is in the form of '02:0a.0', whereas the first two characters + * represent the bus number in hex (in the sample above this is + * pci bus 0x02) and the next two characters the device number (0x0a). + * + * Returns: + * SK_U32: The device number from the PCI slot name + */ + +static SK_U32 ParseDeviceNbrFromSlotName( +const char *SlotName) /* pointer to pci slot name eg. '02:0a.0' */ +{ + char *CurrCharPos = (char *) SlotName; + int FirstNibble = -1; + int SecondNibble = -1; + SK_U32 Result = 0; + + while (*CurrCharPos != '\0') { + if (*CurrCharPos == ':') { + while (*CurrCharPos != '.') { + CurrCharPos++; + if ( (*CurrCharPos >= '0') && + (*CurrCharPos <= '9')) { + if (FirstNibble == -1) { + /* dec. value for '0' */ + FirstNibble = *CurrCharPos - 48; + } else { + SecondNibble = *CurrCharPos - 48; + } + } else if ( (*CurrCharPos >= 'a') && + (*CurrCharPos <= 'f') ) { + if (FirstNibble == -1) { + FirstNibble = *CurrCharPos - 87; + } else { + SecondNibble = *CurrCharPos - 87; + } + } else { + Result = 0; + } + } + + Result = FirstNibble; + Result = Result << 4; /* first nibble is higher one */ + Result = Result | SecondNibble; + } + CurrCharPos++; /* next character */ + } + return (Result); +} + +/**************************************************************************** + * + * SkDrvDeInitAdapter - deinitialize adapter (this function is only + * called if Diag attaches to that card) + * + * Description: + * Close initialized adapter. + * + * Returns: + * 0 - on success + * error code - on error + */ +static int SkDrvDeInitAdapter( +SK_AC *pAC, /* pointer to adapter context */ +int devNbr) /* what device is to be handled */ +{ + struct SK_NET_DEVICE *dev; + + dev = pAC->dev[devNbr]; + + /* + ** Function SkGeClose() uses MOD_DEC_USE_COUNT (2.2/2.4) + ** or module_put() (2.6) to decrease the number of users for + ** a device, but if a device is to be put under control of + ** the DIAG, that count is OK already and does not need to + ** be adapted! Hence the opposite MOD_INC_USE_COUNT or + ** try_module_get() needs to be used again to correct that. + */ + MOD_INC_USE_COUNT; + + if (SkGeClose(dev) != 0) { + MOD_DEC_USE_COUNT; + return (-1); + } + return (0); + +} /* SkDrvDeInitAdapter() */ + +/**************************************************************************** + * + * SkDrvInitAdapter - Initialize adapter (this function is only + * called if Diag deattaches from that card) + * + * Description: + * Close initialized adapter. + * + * Returns: + * 0 - on success + * error code - on error + */ +static int SkDrvInitAdapter( +SK_AC *pAC, /* pointer to adapter context */ +int devNbr) /* what device is to be handled */ +{ + struct SK_NET_DEVICE *dev; + + dev = pAC->dev[devNbr]; + + if (SkGeOpen(dev) != 0) { + return (-1); + } else { + /* + ** Function SkGeOpen() uses MOD_INC_USE_COUNT (2.2/2.4) + ** or try_module_get() (2.6) to increase the number of + ** users for a device, but if a device was just under + ** control of the DIAG, that count is OK already and + ** does not need to be adapted! Hence the opposite + ** MOD_DEC_USE_COUNT or module_put() needs to be used + ** again to correct that. + */ + MOD_DEC_USE_COUNT; + } + + /* + ** Use correct MTU size and indicate to kernel TX queue can be started + */ + if (SkGeChangeMtu(dev, dev->mtu) != 0) { + return (-1); + } + return (0); + +} /* SkDrvInitAdapter */ + +#endif + #ifdef DEBUG /****************************************************************************/ /* "debug only" section *****************************************************/ @@ -4548,7 +5195,7 @@ * DumpData - print a data area * * Description: - * This function prints a area of data to the system logfile/to the + * This function prints a area of data to the system logfile/to the * console. * * Returns: N/A @@ -4596,7 +5243,7 @@ * DumpLong - print a data area as long values * * Description: - * This function prints a area of data to the system logfile/to the + * This function prints a area of data to the system logfile/to the * console. * * Returns: N/A @@ -4650,9 +5297,8 @@ #endif -/* - * Local variables: - * compile-command: "make" - * End: - */ - +/******************************************************************************* + * + * End of file + * + ******************************************************************************/ Index: drivers/net/sk98lin/skgehwt.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/skgehwt.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/skgehwt.c 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/skgehwt.c 4 Aug 2004 01:29:22 -0000 1.2 @@ -1,17 +1,15 @@ /****************************************************************************** * * Name: skgehwt.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ - * Purpose: Hardware Timer. + * Project: Gigabit Ethernet Adapters, Event Scheduler Module + * Purpose: Hardware Timer * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998,1999 SysKonnect, - * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,75 +20,20 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: skgehwt.c,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.13 1999/11/22 13:31:12 cgoos - * Changed license header to GPL. - * - * Revision 1.12 1998/10/15 15:11:34 gklug - * fix: ID_sccs to SysKonnectFileId - * - * Revision 1.11 1998/10/08 15:27:51 gklug - * chg: correction factor is host clock dependent - * - * Revision 1.10 1998/09/15 14:18:31 cgoos - * Changed more BOOLEANs to SK_xxx - * - * Revision 1.9 1998/09/15 14:16:06 cgoos - * Changed line 107: FALSE to SK_FALSE - * - * Revision 1.8 1998/08/24 13:04:44 gklug - * fix: typo - * - * Revision 1.7 1998/08/19 09:50:49 gklug - * fix: remove struct keyword from c-code (see CCC) add typedefs - * - * Revision 1.6 1998/08/17 09:59:02 gklug - * fix: typos - * - * Revision 1.5 1998/08/14 07:09:10 gklug - * fix: chg pAc -> pAC - * - * Revision 1.4 1998/08/10 14:14:52 gklug - * rmv: unneccessary SK_ADDR macro - * - * Revision 1.3 1998/08/07 12:53:44 gklug - * fix: first compiled version - * - * Revision 1.2 1998/08/07 09:19:29 gklug - * adapt functions to the C coding conventions - * rmv unneccessary functions. - * - * Revision 1.1 1998/08/05 11:28:36 gklug - * first version: adapted from SMT/FDDI - * - * - * - * - ******************************************************************************/ - - /* - Event queue and dispatcher -*/ + * Event queue and dispatcher + */ +#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "$Header: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/skgehwt.c,v 1.1 2004/07/22 19:49:44 joff Exp $" ; + "@(#) $Id: skgehwt.c,v 1.2 2004/08/04 01:29:22 joff Exp $ (C) Marvell."; +#endif #include "h/skdrv1st.h" /* Driver Specific Definitions */ #include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ #ifdef __C2MAN__ /* - Hardware Timer function queue management. - - General Description: - + * Hardware Timer function queue management. */ intro() {} @@ -115,9 +58,9 @@ { pAC->Hwt.TStart = 0 ; pAC->Hwt.TStop = 0 ; - pAC->Hwt.TActive = SK_FALSE ; + pAC->Hwt.TActive = SK_FALSE; - SkHwtStop(pAC,Ioc) ; + SkHwtStop(pAC, Ioc); } /* @@ -130,28 +73,29 @@ SK_IOC Ioc, /* IoContext */ SK_U32 Time) /* Time in units of 16us to load the timer with. */ { - SK_U32 Cnt ; + SK_U32 Cnt; if (Time > SK_HWT_MAX) - Time = SK_HWT_MAX ; + Time = SK_HWT_MAX; - pAC->Hwt.TStart = Time ; - pAC->Hwt.TStop = 0L ; + pAC->Hwt.TStart = Time; + pAC->Hwt.TStop = 0L; - Cnt = Time ; + Cnt = Time; /* * if time < 16 us * time = 16 us */ if (!Cnt) { - Cnt++ ; + Cnt++; } - SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC) ; - SK_OUT16(Ioc, B2_TI_CRTL, TIM_START) ; /* Start timer. */ + SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC); + + SK_OUT16(Ioc, B2_TI_CTRL, TIM_START); /* Start timer. */ - pAC->Hwt.TActive = SK_TRUE ; + pAC->Hwt.TActive = SK_TRUE; } /* @@ -162,10 +106,11 @@ SK_AC *pAC, /* Adapters context */ SK_IOC Ioc) /* IoContext */ { - SK_OUT16(Ioc, B2_TI_CRTL, TIM_STOP) ; - SK_OUT16(Ioc, B2_TI_CRTL, TIM_CLR_IRQ) ; + SK_OUT16(Ioc, B2_TI_CTRL, TIM_STOP); + + SK_OUT16(Ioc, B2_TI_CTRL, TIM_CLR_IRQ); - pAC->Hwt.TActive = SK_FALSE ; + pAC->Hwt.TActive = SK_FALSE; } @@ -180,26 +125,31 @@ SK_AC *pAC, /* Adapters context */ SK_IOC Ioc) /* IoContext */ { - SK_U32 TRead ; - SK_U32 IStatus ; + SK_U32 TRead; + SK_U32 IStatus; if (pAC->Hwt.TActive) { - SkHwtStop(pAC,Ioc) ; + + SkHwtStop(pAC, Ioc); SK_IN32(Ioc, B2_TI_VAL, &TRead); TRead /= SK_HWT_FAC; SK_IN32(Ioc, B0_ISRC, &IStatus); - /* Check if timer expired (or wraparound). */ + /* Check if timer expired (or wraped around) */ if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) { - SkHwtStop(pAC,Ioc) ; - pAC->Hwt.TStop = pAC->Hwt.TStart ; - } else { - pAC->Hwt.TStop = pAC->Hwt.TStart - TRead ; + + SkHwtStop(pAC, Ioc); + + pAC->Hwt.TStop = pAC->Hwt.TStart; + } + else { + + pAC->Hwt.TStop = pAC->Hwt.TStart - TRead; } } - return (pAC->Hwt.TStop) ; + return(pAC->Hwt.TStop); } /* @@ -209,9 +159,11 @@ SK_AC *pAC, /* Adapters context */ SK_IOC Ioc) /* IoContext */ { - SkHwtStop(pAC,Ioc); + SkHwtStop(pAC, Ioc); + pAC->Hwt.TStop = pAC->Hwt.TStart; - SkTimerDone(pAC,Ioc) ; + + SkTimerDone(pAC, Ioc); } /* End of file */ Index: drivers/net/sk98lin/skgeinit.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/skgeinit.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/skgeinit.c 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/skgeinit.c 4 Aug 2004 01:29:22 -0000 1.2 @@ -1,16 +1,15 @@ /****************************************************************************** * * Name: skgeinit.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ - * Purpose: Contains functions to initialize the GE HW + * Project: Gigabit Ethernet Adapters, Common Modules + * Purpose: Contains functions to initialize the adapter * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,363 +20,6 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: skgeinit.c,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.82 2002/12/05 13:40:21 rschmidt - * Added setting of Rx GMAC FIFO Flush Mask register. - * Corrected PhyType with new define SK_PHY_MARV_FIBER when - * YUKON Fiber board was found. - * Editorial changes. - * - * Revision 1.81 2002/11/15 12:48:35 rschmidt - * Replaced message SKERR_HWI_E018 with SKERR_HWI_E024 for Rx queue error - * in SkGeStopPort(). - * Added init for pAC->GIni.GIGenesis with SK_FALSE in YUKON-branch. - * Editorial changes. - * - * Revision 1.80 2002/11/12 17:28:30 rschmidt - * Initialized GIPciSlot64 and GIPciClock66 in SkGeInit1(). - * Reduced PCI FIFO watermarks for 32bit/33MHz bus in SkGeInitBmu(). - * Editorial changes. - * - * Revision 1.79 2002/10/21 09:31:02 mkarl - * Changed SkGeInitAssignRamToQueues(), removed call to - * SkGeInitAssignRamToQueues in SkGeInit1 and fixed compiler warning in - * SkGeInit1. - * - * Revision 1.78 2002/10/16 15:55:07 mkarl - * Fixed a bug in SkGeInitAssignRamToQueues. - * - * Revision 1.77 2002/10/14 15:07:22 rschmidt - * Corrected timeout handling for Rx queue in SkGeStopPort() (#10748) - * Editorial changes. - * - * Revision 1.76 2002/10/11 09:24:38 mkarl - * Added check for HW self test results. - * - * Revision 1.75 2002/10/09 16:56:44 mkarl - * Now call SkGeInitAssignRamToQueues() in Init Level 1 in order to assign - * the adapter memory to the queues. This default assignment is not suitable - * for dual net mode. - * - * Revision 1.74 2002/09/12 08:45:06 rwahl - * Set defaults for PMSCap, PLinkSpeed & PLinkSpeedCap dependent on PHY. - * - * Revision 1.73 2002/08/16 15:19:45 rschmidt - * Corrected check for Tx queues in SkGeCheckQSize(). - * Added init for new entry GIGenesis and GICopperType - * Replaced all if(GIChipId == CHIP_ID_GENESIS) with new entry GIGenesis. - * Replaced wrong 1st para pAC with IoC in SK_IN/OUT macros. - * - * Revision 1.72 2002/08/12 13:38:55 rschmidt - * Added check if VAUX is available (stored in GIVauxAvail) - * Initialized PLinkSpeedCap in Port struct with SK_LSPEED_CAP_1000MBPS - * Editorial changes. - * - * Revision 1.71 2002/08/08 16:32:58 rschmidt - * Added check for Tx queues in SkGeCheckQSize(). - * Added start of Time Stamp Timer (YUKON) in SkGeInit2(). - * Editorial changes. - * - * Revision 1.70 2002/07/23 16:04:26 rschmidt - * Added init for GIWolOffs (HW-Bug in YUKON 1st rev.) - * Minor changes - * - * Revision 1.69 2002/07/17 17:07:08 rwahl - * - SkGeInit1(): fixed PHY type debug output; corrected init of GIFunc - * table & GIMacType. - * - Editorial changes. - * - * Revision 1.68 2002/07/15 18:38:31 rwahl - * Added initialization for MAC type dependent function table. - * - * Revision 1.67 2002/07/15 15:45:39 rschmidt - * Added Tx Store & Forward for YUKON (GMAC Tx FIFO is only 1 kB) - * Replaced SK_PHY_MARV by SK_PHY_MARV_COPPER - * Editorial changes - * - * Revision 1.66 2002/06/10 09:35:08 rschmidt - * Replaced C++ comments (//) - * Editorial changes - * - * Revision 1.65 2002/06/05 08:33:37 rschmidt - * Changed GIRamSize and Reset sequence for YUKON. - * SkMacInit() replaced by SkXmInitMac() resp. SkGmInitMac() - * - * Revision 1.64 2002/04/25 13:03:20 rschmidt - * Changes for handling YUKON. - * Removed reference to xmac_ii.h (not necessary). - * Moved all defines into header file. - * Replaced all SkXm...() functions with SkMac...() to handle also - * YUKON's GMAC. - * Added handling for GMAC FIFO in SkGeInitMacFifo(), SkGeStopPort(). - * Removed 'goto'-directive from SkGeCfgSync(), SkGeCheckQSize(). - * Replaced all XMAC-access macros by functions: SkMacRxTxDisable(), - * SkMacFlushTxFifo(). - * Optimized timeout handling in SkGeStopPort(). - * Initialized PLinkSpeed in Port struct with SK_LSPEED_AUTO. - * Release of GMAC Link Control reset in SkGeInit1(). - * Initialized GIChipId and GIChipRev in GE Init structure. - * Added GIRamSize and PhyType values for YUKON. - * Removed use of PRxCmd to setup XMAC. - * Moved setting of XM_RX_DIS_CEXT to SkXmInitMac(). - * Use of SkGeXmitLED() only for GENESIS. - * Changes for V-CPU support. - * Editorial changes. - * - * Revision 1.63 2001/04/05 11:02:09 rassmann - * Stop Port check of the STOP bit did not take 2/18 sec as wanted. - * - * Revision 1.62 2001/02/07 07:54:21 rassmann - * Corrected copyright. - * - * Revision 1.61 2001/01/31 15:31:40 gklug - * fix: problem with autosensing an SR8800 switch - * - * Revision 1.60 2000/10/18 12:22:21 cgoos - * Added workaround for half duplex hangup. - * - * Revision 1.59 2000/10/10 11:22:06 gklug - * add: in manual half duplex mode ignore carrier extension errors - * - * Revision 1.58 2000/10/02 14:10:27 rassmann - * Reading BCOM PHY after releasing reset until it returns a valid value. - * - * Revision 1.57 2000/08/03 14:55:28 rassmann - * Waiting for I2C to be ready before de-initializing adapter - * (prevents sensors from hanging up). - * - * Revision 1.56 2000/07/27 12:16:48 gklug - * fix: Stop Port check of the STOP bit does now take 2/18 sec as wanted - * - * Revision 1.55 1999/11/22 13:32:26 cgoos - * Changed license header to GPL. - * - * Revision 1.54 1999/10/26 07:32:54 malthoff - * Initialize PHWLinkUp with SK_FALSE. Required for Diagnostics. - * - * Revision 1.53 1999/08/12 19:13:50 malthoff - * Fix for 1000BT. Do not owerwrite XM_MMU_CMD when - * disabling receiver and transmitter. Other bits - * may be lost. - * - * Revision 1.52 1999/07/01 09:29:54 gklug - * fix: DoInitRamQueue needs pAC - * - * Revision 1.51 1999/07/01 08:42:21 gklug - * chg: use Store & forward for RAM buffer when Jumbos are used - * - * Revision 1.50 1999/05/27 13:19:38 cgoos - * Added Tx PCI watermark initialization. - * Removed Tx RAM queue Store & Forward setting. - * - * Revision 1.49 1999/05/20 14:32:45 malthoff - * SkGeLinkLED() is completly removed now. - * - * Revision 1.48 1999/05/19 07:28:24 cgoos - * SkGeLinkLED no more available for drivers. - * Changes for 1000Base-T. - * - * Revision 1.47 1999/04/08 13:57:45 gklug - * add: Init of new port struct fiels PLinkResCt - * chg: StopPort Timer check - * - * Revision 1.46 1999/03/25 07:42:15 malthoff - * SkGeStopPort(): Add workaround for cache incoherency. - * Create error log entry, disable port, and - * exit loop if it does not terminate. - * Add XM_RX_LENERR_OK to the default value for the - * XMAC receive command register. - * - * Revision 1.45 1999/03/12 16:24:47 malthoff - * Remove PPollRxD and PPollTxD. - * Add check for GIPollTimerVal. - * - * Revision 1.44 1999/03/12 13:40:23 malthoff - * Fix: SkGeXmitLED(), SK_LED_TST mode does not work. - * Add: Jumbo frame support. - * Chg: Resolution of parameter IntTime in SkGeCfgSync(). - * - * Revision 1.43 1999/02/09 10:29:46 malthoff - * Bugfix: The previous modification again also for the second location. - * - * Revision 1.42 1999/02/09 09:35:16 malthoff - * Bugfix: The bits '66 MHz Capable' and 'NEWCAP are reset while - * clearing the error bits in the PCI status register. - * - * Revision 1.41 1999/01/18 13:07:02 malthoff - * Bugfix: Do not use CFG cycles after during Init- or Runtime, because - * they may not be available after Boottime. - * - * Revision 1.40 1999/01/11 12:40:49 malthoff - * Bug fix: PCI_STATUS: clearing error bits sets the UDF bit. - * - * Revision 1.39 1998/12/11 15:17:33 gklug - * chg: Init LipaAutoNeg with Unknown - * - * Revision 1.38 1998/12/10 11:02:57 malthoff - * Disable Error Log Message when calling SkGeInit(level 2) - * more than once. - * - * Revision 1.37 1998/12/07 12:18:25 gklug - * add: refinement of autosense mode: take into account the autoneg cap of LiPa - * - * Revision 1.36 1998/12/07 07:10:39 gklug - * fix: init values of LinkBroken/ Capabilities for management - * - * Revision 1.35 1998/12/02 10:56:20 gklug - * fix: do NOT init LoinkSync Counter. - * - * Revision 1.34 1998/12/01 10:53:21 gklug - * add: init of additional Counters for workaround - * - * Revision 1.33 1998/12/01 10:00:49 gklug - * add: init PIsave var in Port struct - * - * Revision 1.32 1998/11/26 14:50:40 gklug - * chg: Default is autosensing with AUTOFULL mode - * - * Revision 1.31 1998/11/25 15:36:16 gklug - * fix: do NOT stop LED Timer when port should be stopped - * - * Revision 1.30 1998/11/24 13:15:28 gklug - * add: Init PCkeckPar struct member - * - * Revision 1.29 1998/11/18 13:19:27 malthoff - * Disable packet arbiter timeouts on receive side. - * Use maximum timeout value for packet arbiter - * transmit timeouts. - * Add TestStopBit() function to handle stop RX/TX - * problem with active descriptor poll timers. - * Bug Fix: Descriptor Poll Timer not started, because - * GIPollTimerVal was initialized with 0. - * - * Revision 1.28 1998/11/13 14:24:26 malthoff - * Bug Fix: SkGeStopPort() may hang if a Packet Arbiter Timout - * is pending or occurs while waiting for TX_STOP and RX_STOP. - * The PA timeout is cleared now while waiting for TX- or RX_STOP. - * - * Revision 1.27 1998/11/02 11:04:36 malthoff - * fix the last fix - * - * Revision 1.26 1998/11/02 10:37:03 malthoff - * Fix: SkGePollTxD() enables always the synchronounous poll timer. - * - * Revision 1.25 1998/10/28 07:12:43 cgoos - * Fixed "LED_STOP" in SkGeLnkSyncCnt, "== SK_INIT_IO" in SkGeInit. - * Removed: Reset of RAM Interface in SkGeStopPort. - * - * Revision 1.24 1998/10/27 08:13:12 malthoff - * Remove temporary code. - * - * Revision 1.23 1998/10/26 07:45:03 malthoff - * Add Address Calculation Workaround: If the EPROM byte - * Id is 3, the address offset is 512 kB. - * Initialize default values for PLinkMode and PFlowCtrlMode. - * - * Revision 1.22 1998/10/22 09:46:47 gklug - * fix SysKonnectFileId typo - * - * Revision 1.21 1998/10/20 12:11:56 malthoff - * Don't dendy the Queue config if the size of the unused - * Rx qeueu is zero. - * - * Revision 1.20 1998/10/19 07:27:58 malthoff - * SkGeInitRamIface() is public to be called by diagnostics. - * - * Revision 1.19 1998/10/16 13:33:45 malthoff - * Fix: enabling descriptor polling is not allowed until - * the descriptor addresses are set. Descriptor polling - * must be handled by the driver. - * - * Revision 1.18 1998/10/16 10:58:27 malthoff - * Remove temp. code for Diag prototype. - * Remove lint warning for dummy reads. - * Call SkGeLoadLnkSyncCnt() during SkGeInitPort(). - * - * Revision 1.17 1998/10/14 09:16:06 malthoff - * Change parameter LimCount and programming of - * the limit counter in SkGeCfgSync(). - * - * Revision 1.16 1998/10/13 09:21:16 malthoff - * Don't set XM_RX_SELF_RX in RxCmd Reg, because it's - * like a Loopback Mode in half duplex. - * - * Revision 1.15 1998/10/09 06:47:40 malthoff - * SkGeInitMacArb(): set recovery counters init value - * to zero although this counters are not uesd. - * Bug fix in Rx Upper/Lower Pause Threshold calculation. - * Add XM_RX_SELF_RX to RxCmd. - * - * Revision 1.14 1998/10/06 15:15:53 malthoff - * Make sure no pending IRQ is cleared in SkGeLoadLnkSyncCnt(). - * - * Revision 1.13 1998/10/06 14:09:36 malthoff - * Add SkGeLoadLnkSyncCnt(). Modify - * the 'port stopped' condition according - * to the current problem report. - * - * Revision 1.12 1998/10/05 08:17:21 malthoff - * Add functions: SkGePollRxD(), SkGePollTxD(), - * DoCalcAddr(), SkGeCheckQSize(), - * DoInitRamQueue(), and SkGeCfgSync(). - * Add coding for SkGeInitMacArb(), SkGeInitPktArb(), - * SkGeInitMacFifo(), SkGeInitRamBufs(), - * SkGeInitRamIface(), and SkGeInitBmu(). - * - * Revision 1.11 1998/09/29 08:26:29 malthoff - * bug fix: SkGeInit0() 'i' should be increment. - * - * Revision 1.10 1998/09/28 13:19:01 malthoff - * Coding time: Save the done work. - * Modify SkGeLinkLED(), add SkGeXmitLED(), - * define SkGeCheckQSize(), SkGeInitMacArb(), - * SkGeInitPktArb(), SkGeInitMacFifo(), - * SkGeInitRamBufs(), SkGeInitRamIface(), - * and SkGeInitBmu(). Do coding for SkGeStopPort(), - * SkGeInit1(), SkGeInit2(), and SkGeInit3(). - * Do coding for SkGeDinit() and SkGeInitPort(). - * - * Revision 1.9 1998/09/16 14:29:05 malthoff - * Some minor changes. - * - * Revision 1.8 1998/09/11 05:29:14 gklug - * add: init state of a port - * - * Revision 1.7 1998/09/04 09:26:25 malthoff - * Short temporary modification. - * - * Revision 1.6 1998/09/04 08:27:59 malthoff - * Remark the do-while in StopPort() because it never ends - * without a GE adapter. - * - * Revision 1.5 1998/09/03 14:05:45 malthoff - * Change comment for SkGeInitPort(). Do not - * repair the queue sizes if invalid. - * - * Revision 1.4 1998/09/03 10:03:19 malthoff - * Implement the new interface according to the - * reviewed interface specification. - * - * Revision 1.3 1998/08/19 09:11:25 gklug - * fix: struct are removed from c-source (see CCC) - * - * Revision 1.2 1998/07/28 12:33:58 malthoff - * Add 'IoC' parameter in function declaration and SK IO macros. - * - * Revision 1.1 1998/07/23 09:48:57 malthoff - * Creation. First dummy 'C' file. - * SkGeInit(Level 0) is card_start for GE. - * SkGeDeInit() is card_stop for GE. - * - * - ******************************************************************************/ #include "h/skdrv1st.h" #include "h/skdrv2nd.h" @@ -386,8 +28,10 @@ /* local variables ************************************************************/ +#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "@(#)$Id: skgeinit.c,v 1.1 2004/07/22 19:49:44 joff Exp $ (C) SK "; + "@(#) $Id: skgeinit.c,v 1.2 2004/08/04 01:29:22 joff Exp $ (C) Marvell."; +#endif struct s_QOffTab { int RxQOff; /* Receive Queue Address Offset */ @@ -398,14 +42,27 @@ {Q_R1, Q_XS1, Q_XA1}, {Q_R2, Q_XS2, Q_XA2} }; +struct s_Config { + char ScanString[8]; + SK_U32 Value; +}; + +static struct s_Config OemConfig = { + {'O','E','M','_','C','o','n','f'}, +#ifdef SK_OEM_CONFIG + OEM_CONFIG_VALUE, +#else + 0, +#endif +}; /****************************************************************************** * * SkGePollRxD() - Enable / Disable Descriptor Polling of RxD Ring * * Description: - * Enable or disable the descriptor polling the receive descriptor - * ring (RxD) of port 'Port'. + * Enable or disable the descriptor polling of the receive descriptor + * ring (RxD) for port 'Port'. * The new configuration is *not* saved over any SkGeStopPort() and * SkGeInitPort() calls. * @@ -432,8 +89,8 @@ * SkGePollTxD() - Enable / Disable Descriptor Polling of TxD Rings * * Description: - * Enable or disable the descriptor polling the transmit descriptor - * ring(s) (TxD) of port 'Port'. + * Enable or disable the descriptor polling of the transmit descriptor + * ring(s) (TxD) for port 'Port'. * The new configuration is *not* saved over any SkGeStopPort() and * SkGeInitPort() calls. * @@ -451,7 +108,7 @@ pPrt = &pAC->GIni.GP[Port]; - DWord = (PollTxD) ? CSR_ENA_POL : CSR_DIS_POL; + DWord = (SK_U32)(PollTxD ? CSR_ENA_POL : CSR_DIS_POL); if (pPrt->PXSQSize != 0) { SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), DWord); @@ -492,6 +149,7 @@ } /* SkGeYellowLED */ +#if (!defined(SK_SLIM) || defined(GENESIS)) /****************************************************************************** * * SkGeXmitLED() - Modify the Operational Mode of a transmission LED. @@ -547,6 +205,7 @@ * (In this case it has to be added here. But we will see. XXX) */ } /* SkGeXmitLED */ +#endif /* !SK_SLIM || GENESIS */ /****************************************************************************** @@ -567,12 +226,12 @@ * 1: configuration error */ static int DoCalcAddr( -SK_AC *pAC, /* adapter context */ -SK_GEPORT *pPrt, /* port index */ -int QuSize, /* size of the queue to configure in kB */ -SK_U32 *StartVal, /* start value for address calculation */ -SK_U32 *QuStartAddr, /* start addr to calculate */ -SK_U32 *QuEndAddr) /* end address to calculate */ +SK_AC *pAC, /* adapter context */ +SK_GEPORT SK_FAR *pPrt, /* port index */ +int QuSize, /* size of the queue to configure in kB */ +SK_U32 SK_FAR *StartVal, /* start value for address calculation */ +SK_U32 SK_FAR *QuStartAddr,/* start addr to calculate */ +SK_U32 SK_FAR *QuEndAddr) /* end address to calculate */ { SK_U32 EndVal; SK_U32 NextStart; @@ -647,7 +306,6 @@ return(2); } - if (DualNet) { /* every port gets the same amount of memory */ ActivePortKilobytes = pAC->GIni.GIRamSize / pAC->GIni.GIMacsFound; @@ -749,14 +407,19 @@ int Port) /* port index */ { SK_GEPORT *pPrt; - int UsedMem; /* total memory used (max. found ports) */ int i; int Rtv; int Rtv2; SK_U32 StartAddr; +#ifndef SK_SLIM + int UsedMem; /* total memory used (max. found ports) */ +#endif - UsedMem = 0; Rtv = 0; + +#ifndef SK_SLIM + + UsedMem = 0; for (i = 0; i < pAC->GIni.GIMacsFound; i++) { pPrt = &pAC->GIni.GP[i]; @@ -792,6 +455,7 @@ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG); return(1); } +#endif /* !SK_SLIM */ /* Now start address calculation */ StartAddr = pAC->GIni.GIRamOffs; @@ -823,6 +487,7 @@ } /* SkGeCheckQSize */ +#ifdef GENESIS /****************************************************************************** * * SkGeInitMacArb() - Initialize the MAC Arbiter @@ -857,7 +522,7 @@ /* Fast Output Enable Mode was intended to use with Rev. B2, but now? */ /* - * There is not start or enable button to push, therefore + * There is no start or enable button to push, therefore * the MAC arbiter is configured and enabled now. */ } /* SkGeInitMacArb */ @@ -902,6 +567,7 @@ } } } /* SkGeInitPktArb */ +#endif /* GENESIS */ /****************************************************************************** @@ -919,6 +585,7 @@ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ { + SK_U16 Word; #ifdef VCPU SK_U32 DWord; #endif /* VCPU */ @@ -930,6 +597,7 @@ * - enable the FIFO */ +#ifdef GENESIS if (pAC->GIni.GIGenesis) { /* Configure Rx MAC FIFO */ SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_CLR); @@ -946,20 +614,31 @@ SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH); } } - else { - /* Configure Rx MAC FIFO */ - SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR); - SK_OUT32(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), GMF_RX_CTRL_DEF | - GMF_RX_F_FL_ON); /* enable Rx GMAC FIFO Flush */ +#endif /* GENESIS */ +#ifdef YUKON + if (pAC->GIni.GIYukon) { /* set Rx GMAC FIFO Flush Mask */ SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK); - /* use Rx GMAC FIFO Flush Threshold default value (0x0a == 56 bytes) */ + Word = (SK_U16)GMF_RX_CTRL_DEF; + + /* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */ + if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipId == CHIP_ID_YUKON) { + + Word &= ~GMF_RX_F_FL_ON; + } + + /* Configure Rx MAC FIFO */ + SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR); + SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), Word); + + /* set Rx GMAC FIFO Flush Threshold (default: 0x0a -> 56 bytes) */ + SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF); /* Configure Tx MAC FIFO */ SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR); - SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), GMF_TX_CTRL_DEF); + SK_OUT16(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U16)GMF_TX_CTRL_DEF); #ifdef VCPU SK_IN32(IoC, MR_ADDR(Port, RX_GMF_AF_THR), &DWord); @@ -969,9 +648,11 @@ /* set Tx GMAC FIFO Almost Empty Threshold */ /* SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), 0); */ } -} /* SkGeInitMacFifo */ +#endif /* YUKON */ +} /* SkGeInitMacFifo */ +#ifdef SK_LNK_SYNC_CNT /****************************************************************************** * * SkGeLoadLnkSyncCnt() - Load the Link Sync Counter and starts counting @@ -1044,8 +725,9 @@ SK_OUT32(IoC, B0_IMSK, OrgIMsk); } } /* SkGeLoadLnkSyncCnt*/ +#endif /* SK_LNK_SYNC_CNT */ - +#if defined(SK_DIAG) || defined(SK_CFG_SYNC) /****************************************************************************** * * SkGeCfgSync() - Configure synchronous bandwidth for this port. @@ -1134,6 +816,7 @@ return(0); } /* SkGeCfgSync */ +#endif /* SK_DIAG || SK_CFG_SYNC*/ /****************************************************************************** @@ -1199,7 +882,7 @@ * we NEED Store & Forward of the RAM buffer. */ if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK || - !pAC->GIni.GIGenesis) { + pAC->GIni.GIYukon) { /* enable Store & Forward Mode for the Tx Side */ SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_STFWD); } @@ -1404,7 +1087,7 @@ * Example: * 1) A Link Down event was signaled for a port. Therefore the activity * of this port should be stopped and a hardware reset should be issued - * to enable the workaround of XMAC errata #2. But the received frames + * to enable the workaround of XMAC Errata #2. But the received frames * should not be discarded. * ... * SkGeStopPort(pAC, IoC, Port, SK_STOP_TX, SK_HARD_RST); @@ -1471,8 +1154,8 @@ SK_U32 DWord; SK_U32 XsCsr; SK_U32 XaCsr; - int i; SK_U64 ToutStart; + int i; int ToutCnt; pPrt = &pAC->GIni.GP[Port]; @@ -1496,8 +1179,8 @@ * Clear packet arbiter timeout to make sure * this loop will terminate. */ - SK_OUT16(IoC, B3_PA_CTRL, (Port == MAC_1) ? PA_CLR_TO_TX1 : - PA_CLR_TO_TX2); + SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ? + PA_CLR_TO_TX1 : PA_CLR_TO_TX2)); /* * If the transfer stucks at the MAC the STOP command will not @@ -1577,6 +1260,7 @@ SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff, RB_CTRL), RB_RST_SET); /* Reset Tx MAC FIFO */ +#ifdef GENESIS if (pAC->GIni.GIGenesis) { /* Note: MFF_RST_SET does NOT reset the XMAC ! */ SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_SET); @@ -1585,10 +1269,14 @@ /* Link LED is switched off by the RLMT and the Diag itself */ SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS); } - else { +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { /* Reset TX MAC FIFO */ SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET); } +#endif /* YUKON */ } if ((Dir & SK_STOP_RX) != 0) { @@ -1607,9 +1295,9 @@ * Clear packet arbiter timeout to make sure * this loop will terminate */ - SK_OUT16(IoC, B3_PA_CTRL, (Port == MAC_1) ? PA_CLR_TO_RX1 : - PA_CLR_TO_RX2); - + SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ? + PA_CLR_TO_RX1 : PA_CLR_TO_RX2)); + DWord = TestStopBit(pAC, IoC, pPrt->PRxQOff); /* timeout if i==0 (bug fix for #10748) */ @@ -1635,6 +1323,7 @@ SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_RST_SET); /* Reset Rx MAC FIFO */ +#ifdef GENESIS if (pAC->GIni.GIGenesis) { SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET); @@ -1642,10 +1331,14 @@ /* switch Rx LED off, stop the LED counter */ SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS); } - else { +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { /* Reset Rx MAC FIFO */ SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_SET); } +#endif /* YUKON */ } } /* SkGeStopPort */ @@ -1682,27 +1375,36 @@ pPrt->PPrevRx = 0; pPrt->PPrevFcs = 0; pPrt->PRxLim = SK_DEF_RX_WA_LIM; - pPrt->PLinkMode = SK_LMODE_AUTOFULL; - pPrt->PLinkSpeedCap = SK_LSPEED_CAP_1000MBPS; - pPrt->PLinkSpeed = SK_LSPEED_1000MBPS; - pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_UNKNOWN; - pPrt->PLinkModeConf = SK_LMODE_AUTOSENSE; - pPrt->PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM; - pPrt->PLinkBroken = SK_TRUE; /* See WA code */ - pPrt->PLinkCap = (SK_LMODE_CAP_HALF | SK_LMODE_CAP_FULL | - SK_LMODE_CAP_AUTOHALF | SK_LMODE_CAP_AUTOFULL); - pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN; - pPrt->PFlowCtrlCap = SK_FLOW_MODE_SYM_OR_REM; - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; + pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL; + pPrt->PLinkSpeedCap = (SK_U8)SK_LSPEED_CAP_1000MBPS; + pPrt->PLinkSpeed = (SK_U8)SK_LSPEED_1000MBPS; + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_UNKNOWN; + pPrt->PLinkModeConf = (SK_U8)SK_LMODE_AUTOSENSE; + pPrt->PFlowCtrlMode = (SK_U8)SK_FLOW_MODE_SYM_OR_REM; + pPrt->PLinkCap = (SK_U8)(SK_LMODE_CAP_HALF | SK_LMODE_CAP_FULL | + SK_LMODE_CAP_AUTOHALF | SK_LMODE_CAP_AUTOFULL); + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; + pPrt->PFlowCtrlCap = (SK_U8)SK_FLOW_MODE_SYM_OR_REM; + pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE; pPrt->PMSCap = 0; - pPrt->PMSMode = SK_MS_MODE_AUTO; - pPrt->PMSStatus = SK_MS_STAT_UNSET; + pPrt->PMSMode = (SK_U8)SK_MS_MODE_AUTO; + pPrt->PMSStatus = (SK_U8)SK_MS_STAT_UNSET; + pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_UNKNOWN; pPrt->PAutoNegFail = SK_FALSE; - pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN; pPrt->PHWLinkUp = SK_FALSE; + pPrt->PLinkBroken = SK_TRUE; /* See WA code */ + pPrt->PPhyPowerState = PHY_PM_OPERATIONAL_MODE; + pPrt->PMacColThres = TX_COL_DEF; + pPrt->PMacJamLen = TX_JAM_LEN_DEF; + pPrt->PMacJamIpgVal = TX_JAM_IPG_DEF; + pPrt->PMacJamIpgData = TX_IPG_JAM_DEF; + pPrt->PMacIpgData = IPG_DATA_DEF; + pPrt->PMacLimit4 = SK_FALSE; } pAC->GIni.GIPortUsage = SK_RED_LINK; + pAC->GIni.GILedBlinkCtrl = (SK_U16)OemConfig.Value; + pAC->GIni.GIValIrqMask = IS_ALL_MSK; } /* SkGeInit0*/ @@ -1769,8 +1471,8 @@ SkPciReadCfgDWord(pAC, PCI_BASE_2ND, &Bp2); SkPciReadCfgByte(pAC, PCI_LAT_TIM, &Lat); - if (PciCmd != 0 || Cls != 0 || (Bp1 & 0xfffffff0L) != 0 || Bp2 != 1 || - Lat != 0) { + if (PciCmd != 0 || Cls != (SK_U8)0 || Lat != (SK_U8)0 || + (Bp1 & 0xfffffff0L) != 0 || Bp2 != 1) { return(1); } @@ -1782,7 +1484,7 @@ return(0); } /* SkGePciReset */ -#endif /* SK_PCI_RESET */ +#endif /* SK_PCI_RESET */ /****************************************************************************** * @@ -1811,22 +1513,27 @@ { SK_U8 Byte; SK_U16 Word; + SK_U16 CtrlStat; + SK_U32 DWord; int RetVal; int i; RetVal = 0; + /* save CLK_RUN bits (YUKON-Lite) */ + SK_IN16(IoC, B0_CTST, &CtrlStat); + #ifdef SK_PCI_RESET (void)SkGePciReset(pAC, IoC); -#endif /* SK_PCI_RESET */ +#endif /* SK_PCI_RESET */ - /* Do the SW-reset */ + /* do the SW-reset */ SK_OUT8(IoC, B0_CTST, CS_RST_SET); - /* Release the SW-reset */ + /* release the SW-reset */ SK_OUT8(IoC, B0_CTST, CS_RST_CLR); - /* Reset all error bits in the PCI STATUS register */ + /* reset all error bits in the PCI STATUS register */ /* * Note: PCI Cfg cycles cannot be used, because they are not * available on some platforms after 'boot time'. @@ -1834,31 +1541,47 @@ SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); - SK_OUT16(IoC, PCI_C(PCI_STATUS), Word | PCI_ERRBITS); + SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS)); SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); - /* Release Master Reset */ + /* release Master Reset */ SK_OUT8(IoC, B0_CTST, CS_MRST_CLR); - /* Read Chip Identification Number */ +#ifdef CLK_RUN + CtrlStat |= CS_CLK_RUN_ENA; +#endif /* CLK_RUN */ + + /* restore CLK_RUN bits */ + SK_OUT16(IoC, B0_CTST, (SK_U16)(CtrlStat & + (CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA))); + + /* read Chip Identification Number */ SK_IN8(IoC, B2_CHIP_ID, &Byte); pAC->GIni.GIChipId = Byte; - /* Read number of MACs */ + /* read number of MACs */ SK_IN8(IoC, B2_MAC_CFG, &Byte); pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2; - /* Get Chip Revision Number */ + /* get Chip Revision Number */ pAC->GIni.GIChipRev = (SK_U8)((Byte & CFG_CHIP_R_MSK) >> 4); - /* Read the adapters external SRAM size */ + /* get diff. PCI parameters */ + SK_IN16(IoC, B0_CTST, &CtrlStat); + + /* read the adapters RAM size */ SK_IN8(IoC, B2_E_0, &Byte); + pAC->GIni.GIGenesis = SK_FALSE; + pAC->GIni.GIYukon = SK_FALSE; + pAC->GIni.GIYukonLite = SK_FALSE; + +#ifdef GENESIS if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { pAC->GIni.GIGenesis = SK_TRUE; - if (Byte == 3) { + if (Byte == (SK_U8)3) { /* special case: 4 x 64k x 36, offset = 0x80000 */ pAC->GIni.GIRamSize = 1024; pAC->GIni.GIRamOffs = (SK_U32)512 * 1024; @@ -1867,19 +1590,76 @@ pAC->GIni.GIRamSize = (int)Byte * 512; pAC->GIni.GIRamOffs = 0; } + /* all GE adapters work with 53.125 MHz host clock */ + pAC->GIni.GIHstClkFact = SK_FACT_53; + + /* set Descr. Poll Timer Init Value to 250 ms */ + pAC->GIni.GIPollTimerVal = + SK_DPOLL_DEF * (SK_U32)pAC->GIni.GIHstClkFact / 100; } - else { +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) { + + pAC->GIni.GIYukon = SK_TRUE; + + pAC->GIni.GIRamSize = (Byte == (SK_U8)0) ? 128 : (int)Byte * 4; - pAC->GIni.GIGenesis = SK_FALSE; - -#ifndef VCPU - pAC->GIni.GIRamSize = (Byte == 0) ? 128 : (int)Byte * 4; -#else - pAC->GIni.GIRamSize = 128; -#endif pAC->GIni.GIRamOffs = 0; - pAC->GIni.GIWolOffs = (pAC->GIni.GIChipRev == 0) ? WOL_REG_OFFS : 0; + /* WA for chip Rev. A */ + pAC->GIni.GIWolOffs = (pAC->GIni.GIChipId == CHIP_ID_YUKON && + pAC->GIni.GIChipRev == 0) ? WOL_REG_OFFS : 0; + + /* get PM Capabilities of PCI config space */ + SK_IN16(IoC, PCI_C(PCI_PM_CAP_REG), &Word); + + /* check if VAUX is available */ + if (((CtrlStat & CS_VAUX_AVAIL) != 0) && + /* check also if PME from D3cold is set */ + ((Word & PCI_PME_D3C_SUP) != 0)) { + /* set entry in GE init struct */ + pAC->GIni.GIVauxAvail = SK_TRUE; + } + + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) { + /* this is Rev. A1 */ + pAC->GIni.GIYukonLite = SK_TRUE; + } + else { + /* save Flash-Address Register */ + SK_IN32(IoC, B2_FAR, &DWord); + + /* test Flash-Address Register */ + SK_OUT8(IoC, B2_FAR + 3, 0xff); + SK_IN8(IoC, B2_FAR + 3, &Byte); + + if (Byte != 0) { + /* this is Rev. A0 */ + pAC->GIni.GIYukonLite = SK_TRUE; + + /* restore Flash-Address Register */ + SK_OUT32(IoC, B2_FAR, DWord); + } + } + + /* switch power to VCC (WA for VAUX problem) */ + SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA | + PC_VAUX_OFF | PC_VCC_ON)); + + /* read the Interrupt source */ + SK_IN32(IoC, B0_ISRC, &DWord); + + if ((DWord & IS_HW_ERR) != 0) { + /* read the HW Error Interrupt source */ + SK_IN32(IoC, B0_HWE_ISRC, &DWord); + + if ((DWord & IS_IRQ_SENSOR) != 0) { + /* disable HW Error IRQ */ + pAC->GIni.GIValIrqMask &= ~IS_HW_ERR; + } + } for (i = 0; i < pAC->GIni.GIMacsFound; i++) { /* set GMAC Link Control reset */ @@ -1888,90 +1668,100 @@ /* clear GMAC Link Control reset */ SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_CLR); } + /* all YU chips work with 78.125 MHz host clock */ + pAC->GIni.GIHstClkFact = SK_FACT_78; + + pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; /* 215 ms */ } +#endif /* YUKON */ - /* get diff. PCI parameters */ - SK_IN16(IoC, B0_CTST, &Word); - - /* Check if 64-bit PCI Slot is present */ - pAC->GIni.GIPciSlot64 = (SK_BOOL)((Word & CS_BUS_SLOT_SZ) != 0); + /* check if 64-bit PCI Slot is present */ + pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0); - /* Check if 66 MHz PCI Clock is active */ - pAC->GIni.GIPciClock66 = (SK_BOOL)((Word & CS_BUS_CLOCK) != 0); - - /* Check if VAUX is available */ - pAC->GIni.GIVauxAvail = (SK_BOOL)((Word & CS_VAUX_AVAIL) != 0); + /* check if 66 MHz PCI Clock is active */ + pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0); - /* Read PCI HW Revision Id. */ + /* read PCI HW Revision Id. */ SK_IN8(IoC, PCI_C(PCI_REV_ID), &Byte); pAC->GIni.GIPciHwRev = Byte; - /* All known GE Adapters work with 53.125 MHz host clock */ - pAC->GIni.GIHstClkFact = SK_FACT_53; - pAC->GIni.GIPollTimerVal = - SK_DPOLL_DEF * (SK_U32)pAC->GIni.GIHstClkFact / 100; - - /* Read the PMD type */ + /* read the PMD type */ SK_IN8(IoC, B2_PMD_TYP, &Byte); pAC->GIni.GICopperType = (SK_U8)(Byte == 'T'); - /* Read the PHY type */ + /* read the PHY type */ SK_IN8(IoC, B2_E_1, &Byte); -#ifdef VCPU - if (!pAC->GIni.GIGenesis) { - pAC->GIni.GICopperType = SK_TRUE; - Byte = SK_PHY_MARV_COPPER; /* this field is not initialized */ - } -#endif - Byte &= 0x0f; /* the PHY type is stored in the lower nibble */ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { - pAC->GIni.GP[i].PhyType = Byte; - switch (Byte) { - case SK_PHY_XMAC: - pAC->GIni.GP[i].PhyAddr = PHY_ADDR_XMAC; - break; - case SK_PHY_BCOM: - pAC->GIni.GP[i].PhyAddr = PHY_ADDR_BCOM; - pAC->GIni.GP[i].PMSCap = - SK_MS_CAP_AUTO | SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE; - break; - case SK_PHY_MARV_COPPER: + +#ifdef GENESIS + if (pAC->GIni.GIGenesis) { + switch (Byte) { + case SK_PHY_XMAC: + pAC->GIni.GP[i].PhyAddr = PHY_ADDR_XMAC; + break; + case SK_PHY_BCOM: + pAC->GIni.GP[i].PhyAddr = PHY_ADDR_BCOM; + pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO | + SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE); + break; +#ifdef OTHER_PHY + case SK_PHY_LONE: + pAC->GIni.GP[i].PhyAddr = PHY_ADDR_LONE; + break; + case SK_PHY_NAT: + pAC->GIni.GP[i].PhyAddr = PHY_ADDR_NAT; + break; +#endif /* OTHER_PHY */ + default: + /* ERROR: unexpected PHY type detected */ + RetVal = 5; + break; + } + } +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { + + if (Byte < (SK_U8)SK_PHY_MARV_COPPER) { + /* if this field is not initialized */ + Byte = (SK_U8)SK_PHY_MARV_COPPER; + + pAC->GIni.GICopperType = SK_TRUE; + } + pAC->GIni.GP[i].PhyAddr = PHY_ADDR_MARV; + if (pAC->GIni.GICopperType) { - pAC->GIni.GP[i].PLinkSpeedCap = SK_LSPEED_CAP_AUTO | + + pAC->GIni.GP[i].PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_AUTO | SK_LSPEED_CAP_10MBPS | SK_LSPEED_CAP_100MBPS | - SK_LSPEED_CAP_1000MBPS; - pAC->GIni.GP[i].PLinkSpeed = SK_LSPEED_AUTO; - pAC->GIni.GP[i].PMSCap = - SK_MS_CAP_AUTO | SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE; + SK_LSPEED_CAP_1000MBPS); + + pAC->GIni.GP[i].PLinkSpeed = (SK_U8)SK_LSPEED_AUTO; + + pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO | + SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE); } else { - pAC->GIni.GP[i].PhyType = SK_PHY_MARV_FIBER; + Byte = (SK_U8)SK_PHY_MARV_FIBER; } - break; -#ifdef OTHER_PHY - case SK_PHY_LONE: - pAC->GIni.GP[i].PhyAddr = PHY_ADDR_LONE; - break; - case SK_PHY_NAT: - pAC->GIni.GP[i].PhyAddr = PHY_ADDR_NAT; - break; -#endif /* OTHER_PHY */ - default: - /* ERROR: unexpected PHY type detected */ - RetVal = 5; - break; } +#endif /* YUKON */ + + pAC->GIni.GP[i].PhyType = (int)Byte; SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, - ("PHY type: %d PHY addr: %04x\n", pAC->GIni.GP[i].PhyType, + ("PHY type: %d PHY addr: %04x\n", Byte, pAC->GIni.GP[i].PhyAddr)); } - /* Get Mac Type & set function pointers dependent on */ + /* get MAC Type & set function pointers dependent on */ +#ifdef GENESIS if (pAC->GIni.GIGenesis) { + pAC->GIni.GIMacType = SK_MAC_XMAC; pAC->GIni.GIFunc.pFnMacUpdateStats = SkXmUpdateStats; @@ -1979,24 +1769,30 @@ pAC->GIni.GIFunc.pFnMacResetCounter = SkXmResetCounter; pAC->GIni.GIFunc.pFnMacOverflow = SkXmOverflowStatus; } - else { +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { + pAC->GIni.GIMacType = SK_MAC_GMAC; pAC->GIni.GIFunc.pFnMacUpdateStats = SkGmUpdateStats; pAC->GIni.GIFunc.pFnMacStatistic = SkGmMacStatistic; pAC->GIni.GIFunc.pFnMacResetCounter = SkGmResetCounter; pAC->GIni.GIFunc.pFnMacOverflow = SkGmOverflowStatus; - -#ifndef VCPU + +#ifdef SPECIAL_HANDLING if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { /* check HW self test result */ SK_IN8(IoC, B2_E_3, &Byte); - if ((Byte & B2_E3_RES_MASK) != 0) { + if (Byte & B2_E3_RES_MASK) { RetVal = 6; } } #endif } +#endif /* YUKON */ + return(RetVal); } /* SkGeInit1 */ @@ -2020,7 +1816,9 @@ SK_AC *pAC, /* adapter context */ SK_IOC IoC) /* IO context */ { +#ifdef GENESIS SK_U32 DWord; +#endif /* GENESIS */ int i; /* start the Descriptor Poll Timer */ @@ -2034,6 +1832,7 @@ SK_OUT8(IoC, B28_DPT_CTRL, DPT_START); } +#ifdef GENESIS if (pAC->GIni.GIGenesis) { /* start the Blink Source Counter */ DWord = SK_BLK_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100; @@ -2049,10 +1848,14 @@ SkGeInitPktArb(pAC, IoC); } - else { - /* Start Time Stamp Timer */ +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { + /* start Time Stamp Timer */ SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_START); } +#endif /* YUKON */ /* enable the Tx Arbiters */ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { @@ -2124,17 +1927,17 @@ break; } - /* Check if the adapter seems to be accessible */ - SK_OUT32(IoC, B2_IRQM_INI, 0x11335577L); + /* check if the adapter seems to be accessible */ + SK_OUT32(IoC, B2_IRQM_INI, SK_TEST_VAL); SK_IN32(IoC, B2_IRQM_INI, &DWord); SK_OUT32(IoC, B2_IRQM_INI, 0L); - if (DWord != 0x11335577L) { + if (DWord != SK_TEST_VAL) { RetVal = 2; break; } - /* Check if the number of GIMacsFound matches SK_MAX_MACS */ + /* check if the number of GIMacsFound matches SK_MAX_MACS */ if (pAC->GIni.GIMacsFound > SK_MAX_MACS) { RetVal = 1; break; @@ -2171,7 +1974,7 @@ /****************************************************************************** * - * SkGeDeInit() - Deinitialize the adapter. + * SkGeDeInit() - Deinitialize the adapter * * Description: * All ports of the adapter will be stopped if not already done. @@ -2187,12 +1990,17 @@ int i; SK_U16 Word; -#ifndef VCPU - /* Ensure I2C is ready */ +#ifdef SK_PHY_LP_MODE + SK_U8 Byte; + SK_U16 PmCtlSts; +#endif /* SK_PHY_LP_MODE */ + +#if (!defined(SK_SLIM) && !defined(VCPU)) + /* ensure I2C is ready */ SkI2cWaitIrq(pAC, IoC); -#endif +#endif - /* Stop all current transfer activity */ + /* stop all current transfer activity */ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { if (pAC->GIni.GP[i].PState != SK_PRT_STOP && pAC->GIni.GP[i].PState != SK_PRT_RESET) { @@ -2201,6 +2009,38 @@ } } +#ifdef SK_PHY_LP_MODE + /* + * for power saving purposes within mobile environments + * we set the PHY to coma mode and switch to D3 power state. + */ + if (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { + + /* for all ports switch PHY to coma mode */ + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + + SkGmEnterLowPowerMode(pAC, IoC, i, PHY_PM_DEEP_SLEEP); + } + + if (pAC->GIni.GIVauxAvail) { + /* switch power to VAUX */ + Byte = PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF; + + SK_OUT8(IoC, B0_POWER_CTRL, Byte); + } + + /* switch to D3 state */ + SK_IN16(IoC, PCI_C(PCI_PM_CTL_STS), &PmCtlSts); + + PmCtlSts |= PCI_PM_STATE_D3; + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); + + SK_OUT16(IoC, PCI_C(PCI_PM_CTL_STS), PmCtlSts); + } +#endif /* SK_PHY_LP_MODE */ + /* Reset all bits in the PCI STATUS register */ /* * Note: PCI Cfg cycles cannot be used, because they are not @@ -2209,11 +2049,13 @@ SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); - SK_OUT16(IoC, PCI_C(PCI_STATUS), Word | PCI_ERRBITS); + SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS)); SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); - /* Do the reset, all LEDs are switched off now */ + /* do the reset, all LEDs are switched off now */ SK_OUT8(IoC, B0_CTST, CS_RST_SET); + + pAC->GIni.GILevel = SK_INIT_DATA; } /* SkGeDeInit */ @@ -2264,10 +2106,11 @@ return(2); } - /* Configuration ok, initialize the Port now */ + /* configuration ok, initialize the Port now */ +#ifdef GENESIS if (pAC->GIni.GIGenesis) { - /* Initialize Rx, Tx and Link LED */ + /* initialize Rx, Tx and Link LED */ /* * If 1000BT Phy needs LED initialization than swap * LED and XMAC initialization order @@ -2278,12 +2121,16 @@ SkXmInitMac(pAC, IoC, Port); } - else { +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { SkGmInitMac(pAC, IoC, Port); } +#endif /* YUKON */ - /* Do NOT initialize the Link Sync Counter */ + /* do NOT initialize the Link Sync Counter */ SkGeInitMacFifo(pAC, IoC, Port); @@ -2296,7 +2143,7 @@ SkGeInitBmu(pAC, IoC, Port); - /* Mark port as initialized */ + /* mark port as initialized */ pPrt->PState = SK_PRT_INIT; return(0); Index: drivers/net/sk98lin/skgemib.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/skgemib.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/skgemib.c 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/skgemib.c 4 Aug 2004 01:29:22 -0000 1.2 @@ -2,15 +2,14 @@ * * Name: skgemib.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ * Purpose: Private Network Management Interface Management Database * ****************************************************************************/ /****************************************************************************** * - * (C)Copyright 2002 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,38 +20,6 @@ * ******************************************************************************/ -/***************************************************************************** - * - * History: - * - * $Log: skgemib.c,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.7 2002/12/16 09:04:34 tschilli - * Code for VCT handling added. - * - * Revision 1.6 2002/08/09 15:40:21 rwahl - * Editorial change (renamed ConfSpeedCap). - * - * Revision 1.5 2002/08/09 11:05:34 rwahl - * Added oid handling for link speed cap. - * - * Revision 1.4 2002/08/09 09:40:27 rwahl - * Added support for NDIS OID_PNP_xxx. - * - * Revision 1.3 2002/07/17 19:39:54 rwahl - * Added handler for OID_SKGE_SPEED_MODE & OID_SKGE_SPEED_STATUS. - * - * Revision 1.2 2002/05/22 08:59:00 rwahl - * - static functions only for release build. - * - Source file must be included. - * - * Revision 1.1 2002/05/22 08:12:42 rwahl - * Initial version. - * - ****************************************************************************/ - /* * PRIVATE OID handler function prototypes */ @@ -103,8 +70,13 @@ PNMI_STATIC int PowerManagement(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex); -#endif +#endif /* SK_POWER_MGMT */ +#ifdef SK_DIAG_SUPPORT +PNMI_STATIC int DiagActions(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +#endif /* SK_DIAG_SUPPORT */ /* defines *******************************************************************/ @@ -270,6 +242,13 @@ 0, SK_PNMI_RW, PowerManagement, 0}, #endif /* SK_POWER_MGMT */ +#ifdef SK_DIAG_SUPPORT + {OID_SKGE_DIAG_MODE, + 0, + 0, + 0, + SK_PNMI_RW, DiagActions, 0}, +#endif /* SK_DIAG_SUPPORT */ {OID_SKGE_MDB_VERSION, 1, 0, @@ -340,6 +319,16 @@ 0, SK_PNMI_MAI_OFF(DriverVersion), SK_PNMI_RO, General, 0}, + {OID_SKGE_DRIVER_RELDATE, + 1, + 0, + SK_PNMI_MAI_OFF(DriverReleaseDate), + SK_PNMI_RO, General, 0}, + {OID_SKGE_DRIVER_FILENAME, + 1, + 0, + SK_PNMI_MAI_OFF(DriverFileName), + SK_PNMI_RO, General, 0}, {OID_SKGE_HW_DESCR, 1, 0, @@ -355,6 +344,21 @@ 0, SK_PNMI_MAI_OFF(Chipset), SK_PNMI_RO, General, 0}, + {OID_SKGE_CHIPID, + 1, + 0, + SK_PNMI_MAI_OFF(ChipId), + SK_PNMI_RO, General, 0}, + {OID_SKGE_RAMSIZE, + 1, + 0, + SK_PNMI_MAI_OFF(RamSize), + SK_PNMI_RO, General, 0}, + {OID_SKGE_VAUXAVAIL, + 1, + 0, + SK_PNMI_MAI_OFF(VauxAvail), + SK_PNMI_RO, General, 0}, {OID_SKGE_ACTION, 1, 0, @@ -860,6 +864,18 @@ sizeof(SK_PNMI_CONF), SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfConnector), SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_PHY_TYPE, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyType), + SK_PNMI_RO, MacPrivateConf, 0}, +#ifdef SK_PHY_LP_MODE + {OID_SKGE_PHY_LP_MODE, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyMode), + SK_PNMI_RW, MacPrivateConf, 0}, +#endif {OID_SKGE_LINK_CAP, SK_PNMI_MAC_ENTRIES, sizeof(SK_PNMI_CONF), @@ -1055,5 +1071,10 @@ 0, 0, SK_PNMI_RO, Vct, 0}, + {OID_SKGE_BOARDLEVEL, + 0, + 0, + 0, + SK_PNMI_RO, General, 0}, }; Index: drivers/net/sk98lin/skgepnmi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/skgepnmi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/skgepnmi.c 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/skgepnmi.c 4 Aug 2004 01:29:22 -0000 1.2 @@ -2,8 +2,6 @@ * * Name: skgepnmi.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ * Purpose: Private Network Management Interface * ****************************************************************************/ @@ -11,6 +9,7 @@ /****************************************************************************** * * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,423 +20,10 @@ * ******************************************************************************/ -/***************************************************************************** - * - * History: - * - * $Log: skgepnmi.c,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.102 2002/12/16 14:03:24 tschilli - * VCT code in Vct() changed. - * - * Revision 1.101 2002/12/16 09:04:10 tschilli - * Code for VCT handling added. - * - * Revision 1.100 2002/09/26 14:28:13 tschilli - * For XMAC the values in the SK_PNMI_PORT Port struct are copied to - * the new SK_PNMI_PORT BufPort struct during a MacUpdate() call. - * These values are used when GetPhysStatVal() is called. With this - * mechanism you get the best results when software corrections for - * counters are needed. Example: RX_LONGFRAMES. - * - * Revision 1.99 2002/09/17 12:31:19 tschilli - * OID_SKGE_TX_HW_ERROR_CTS, OID_SKGE_OUT_ERROR_CTS, OID_GEN_XMIT_ERROR: - * Double count of SK_PNMI_HTX_EXCESS_COL in function General() removed. - * OID_PNP_CAPABILITIES: sizeof(SK_PM_WAKE_UP_CAPABILITIES) changed to - * sizeof(SK_PNP_CAPABILITIES) in function PowerManagement(). - * - * Revision 1.98 2002/09/10 09:00:03 rwahl - * Adapted boolean definitions according sktypes. - * - * Revision 1.97 2002/09/05 15:07:03 rwahl - * Editorial changes. - * - * Revision 1.96 2002/09/05 11:04:14 rwahl - * - Rx/Tx packets statistics of virtual port were zero on link down (#10750) - * - For GMAC the overflow IRQ for Rx longframe counter was not counted. - * - Incorrect calculation for oids OID_SKGE_RX_HW_ERROR_CTS, - * OID_SKGE_IN_ERRORS_CTS, OID_GEN_RCV_ERROR. - * - Moved correction for OID_SKGE_STAT_RX_TOO_LONG to GetPhysStatVal(). - * - Editorial changes. - * - * Revision 1.95 2002/09/04 08:53:37 rwahl - * - Incorrect statistics for Rx_too_long counter with jumbo frame (#10751) - * - StatRxFrameTooLong & StatRxPMaccErr counters were not reset. - * - Fixed compiler warning for debug msg arg types. - * - * Revision 1.94 2002/08/09 15:42:14 rwahl - * - Fixed StatAddr table for GMAC. - * - VirtualConf(): returned indeterminated status for speed oids if no - * active port. - * - * Revision 1.93 2002/08/09 11:04:59 rwahl - * Added handler for link speed caps. - * - * Revision 1.92 2002/08/09 09:43:03 rwahl - * - Added handler for NDIS OID_PNP_xxx ids. - * - * Revision 1.91 2002/07/17 19:53:03 rwahl - * - Added StatOvrflwBit table for XMAC & GMAC. - * - Extended StatAddr table for GMAC. Added check of number of counters - * in enumeration and size of StatAddr table on init level. - * - Added use of GIFunc table. - * - ChipSet is not static anymore, - * - Extended SIRQ event handler for both mac types. - * - Fixed rx short counter bug (#10620) - * - Added handler for oids SKGE_SPEED_MODE & SKGE_SPEED_STATUS. - * - Extendet GetPhysStatVal() for GMAC. - * - Editorial changes. - * - * Revision 1.90 2002/05/22 08:56:25 rwahl - * - Moved OID table to separate source file. - * - Fix: TX_DEFFERAL counter incremented in full-duplex mode. - * - Use string definitions for error msgs. - * - * Revision 1.89 2001/09/18 10:01:30 mkunz - * some OID's fixed for dualnetmode - * - * Revision 1.88 2001/08/02 07:58:08 rwahl - * - Fixed NetIndex to csum module at ResetCounter(). - * - * Revision 1.87 2001/04/06 13:35:09 mkunz - * -Bugs fixed in handling of OID_SKGE_MTU and the VPD OID's - * - * Revision 1.86 2001/03/09 09:18:03 mkunz - * Changes in SK_DBG_MSG - * - * Revision 1.85 2001/03/08 09:37:31 mkunz - * Bugfix in ResetCounter for Pnmi.Port structure - * - * Revision 1.84 2001/03/06 09:04:55 mkunz - * Made some changes in instance calculation - * - * Revision 1.83 2001/02/15 09:15:32 mkunz - * Necessary changes for dual net mode added - * - * Revision 1.82 2001/02/07 08:24:19 mkunz - * -Made changes in handling of OID_SKGE_MTU - * - * Revision 1.81 2001/02/06 09:58:00 mkunz - * -Vpd bug fixed - * -OID_SKGE_MTU added - * -pnmi support for dual net mode. Interface function and macros extended - * - * Revision 1.80 2001/01/22 13:41:35 rassmann - * Supporting two nets on dual-port adapters. - * - * Revision 1.79 2000/12/05 14:57:40 cgoos - * SetStruct failed before first Link Up (link mode of virtual - * port "INDETERMINATED"). - * - * Revision 1.78 2000/09/12 10:44:58 cgoos - * Fixed SK_PNMI_STORE_U32 calls with typecasted argument. - * - * Revision 1.77 2000/09/07 08:10:19 rwahl - * - Modified algorithm for 64bit NDIS statistic counters; - * returns 64bit or 32bit value depending on passed buffer - * size. Indicate capability for 64bit NDIS counter, if passed - * buffer size is zero. OID_GEN_XMIT_ERROR, OID_GEN_RCV_ERROR, - * and OID_GEN_RCV_NO_BUFFER handled as 64bit counter, too. - * - corrected OID_SKGE_RLMT_PORT_PREFERRED. - * - * Revision 1.76 2000/08/03 15:23:39 rwahl - * - Correction for FrameTooLong counter has to be moved to OID handling - * routines (instead of statistic counter routine). - * - Fix in XMAC Reset Event handling: Only offset counter for hardware - * statistic registers are updated. - * - * Revision 1.75 2000/08/01 16:46:05 rwahl - * - Added StatRxLongFrames counter and correction of FrameTooLong counter. - * - Added directive to control width (default = 32bit) of NDIS statistic - * counters (SK_NDIS_64BIT_CTR). - * - * Revision 1.74 2000/07/04 11:41:53 rwahl - * - Added volition connector type. - * - * Revision 1.73 2000/03/15 16:33:10 rwahl - * Fixed bug 10510; wrong reset of virtual port statistic counters. - * - * Revision 1.72 1999/12/06 16:15:53 rwahl - * Fixed problem of instance range for current and factory MAC address. - * - * Revision 1.71 1999/12/06 10:14:20 rwahl - * Fixed bug 10476; set operation for PHY_OPERATION_MODE. - * - * Revision 1.70 1999/11/22 13:33:34 cgoos - * Changed license header to GPL. - * - * Revision 1.69 1999/10/18 11:42:15 rwahl - * Added typecasts for checking event dependent param (debug only). - * - * Revision 1.68 1999/10/06 09:35:59 cgoos - * Added state check to PHY_READ call (hanged if called during startup). - * - * Revision 1.67 1999/09/22 09:53:20 rwahl - * - Read Broadcom register for updating fcs error counter (1000Base-T). - * - * Revision 1.66 1999/08/26 13:47:56 rwahl - * Added SK_DRIVER_SENDEVENT when queueing RLMT_CHANGE_THRES trap. - * - * Revision 1.65 1999/07/26 07:49:35 cgoos - * Added two typecasts to avoid compiler warnings. - * - * Revision 1.64 1999/05/20 09:24:12 cgoos - * Changes for 1000Base-T (sensors, Master/Slave). - * - * Revision 1.63 1999/04/13 15:11:58 mhaveman - * Moved include of rlmt.h to header skgepnmi.h because some macros - * are needed there. - * - * Revision 1.62 1999/04/13 15:08:07 mhaveman - * Replaced again SK_RLMT_CHECK_LINK with SK_PNMI_RLMT_MODE_CHK_LINK - * to grant unified interface by only using the PNMI header file. - * SK_PNMI_RLMT_MODE_CHK_LINK is defined the same as SK_RLMT_CHECK_LINK. - * - * Revision 1.61 1999/04/13 15:02:48 mhaveman - * Changes caused by review: - * -Changed some comments - * -Removed redundant check for OID_SKGE_PHYS_FAC_ADDR - * -Optimized PRESET check. - * -Meaning of error SK_ADDR_DUPLICATE_ADDRESS changed. Set of same - * address will now not cause this error. Removed corresponding check. - * - * Revision 1.60 1999/03/23 10:41:23 mhaveman - * Added comments. - * - * Revision 1.59 1999/02/19 08:01:28 mhaveman - * Fixed bug 10372 that after counter reset all ports were displayed - * as inactive. - * - * Revision 1.58 1999/02/16 18:04:47 mhaveman - * Fixed problem of twisted OIDs SENSOR_WAR_TIME and SENSOR_ERR_TIME. - * - * Revision 1.56 1999/01/27 12:29:11 mhaveman - * SkTimerStart was called with time value in milli seconds but needs - * micro seconds. - * - * Revision 1.55 1999/01/25 15:00:38 mhaveman - * Added support to allow multiple ports to be active. If this feature in - * future will be used, the Management Data Base variables PORT_ACTIVE - * and PORT_PREFERED should be moved to the port specific part of RLMT. - * Currently they return the values of the first active physical port - * found. A set to the virtual port will actually change all active - * physical ports. A get returns the melted values of all active physical - * ports. If the port values differ a return value INDETERMINATED will - * be returned. This effects especially the CONF group. - * - * Revision 1.54 1999/01/19 10:10:22 mhaveman - * -Fixed bug 10354: Counter values of virtual port were wrong after port - * switches - * -Added check if a switch to the same port is notified. - * - * Revision 1.53 1999/01/07 09:25:21 mhaveman - * Forgot to initialize a variable. - * - * Revision 1.52 1999/01/05 10:34:33 mhaveman - * Fixed little error in RlmtChangeEstimate calculation. - * - * Revision 1.51 1999/01/05 09:59:07 mhaveman - * -Moved timer start to init level 2 - * -Redesigned port switch average calculation to avoid 64bit - * arithmetic. - * - * Revision 1.50 1998/12/10 15:13:59 mhaveman - * -Fixed: PHYS_CUR_ADDR returned wrong addresses - * -Fixed: RLMT_PORT_PREFERED and RLMT_CHANGE_THRES preset returned - * always BAD_VALUE. - * -Fixed: TRAP buffer seemed to sometimes suddenly empty - * - * Revision 1.49 1998/12/09 16:17:07 mhaveman - * Fixed: Couldnot delete VPD keys on UNIX. - * - * Revision 1.48 1998/12/09 14:11:10 mhaveman - * -Add: Debugmessage for XMAC_RESET supressed to minimize output. - * -Fixed: RlmtChangeThreshold will now be initialized. - * -Fixed: VPD_ENTRIES_LIST extended value with unnecessary space char. - * -Fixed: On VPD key creation an invalid key name could be created - * (e.g. A5) - * -Some minor changes in comments and code. - * - * Revision 1.47 1998/12/08 16:00:31 mhaveman - * -Fixed: For RLMT_PORT_ACTIVE will now be returned a 0 if no port - * is active. - * -Fixed: For the RLMT statistics group only the last value was - * returned and the rest of the buffer was filled with 0xff - * -Fixed: Mysteriously the preset on RLMT_MODE still returned - * BAD_VALUE. - * Revision 1.46 1998/12/08 10:04:56 mhaveman - * -Fixed: Preset on RLMT_MODE returned always BAD_VALUE error. - * -Fixed: Alignment error in GetStruct - * -Fixed: If for Get/Preset/SetStruct the buffer size is equal or - * larger than SK_PNMI_MIN_STRUCT_SIZE the return value is stored - * to the buffer. In this case the caller should always return - * ok to its upper routines. Only if the buffer size is less - * than SK_PNMI_MIN_STRUCT_SIZE and the return value is unequal - * to 0, an error should be returned by the caller. - * -Fixed: Wrong number of instances with RLMT statistic. - * -Fixed: Return now SK_LMODE_STAT_UNKNOWN if the LinkModeStatus is 0. - * - * Revision 1.45 1998/12/03 17:17:24 mhaveman - * -Removed for VPD create action the buffer size limitation to 4 bytes. - * -Pass now physical/active physical port to ADDR for CUR_ADDR set - * - * Revision 1.44 1998/12/03 15:14:35 mhaveman - * Another change to Vpd instance evaluation. - * - * Revision 1.43 1998/12/03 14:18:10 mhaveman - * -Fixed problem in PnmiSetStruct. It was impossible to set any value. - * -Removed VPD key evaluation for VPD_FREE_BYTES and VPD_ACTION. - * - * Revision 1.42 1998/12/03 11:31:47 mhaveman - * Inserted cast to satisfy lint. - * - * Revision 1.41 1998/12/03 11:28:16 mhaveman - * Removed SK_PNMI_CHECKPTR - * - * Revision 1.40 1998/12/03 11:19:07 mhaveman - * Fixed problems - * -A set to virtual port will now be ignored. A set with broadcast - * address to any port will be ignored. - * -GetStruct function made VPD instance calculation wrong. - * -Prefered port returned -1 instead of 0. - * - * Revision 1.39 1998/11/26 15:30:29 mhaveman - * Added sense mode to link mode. - * - * Revision 1.38 1998/11/23 15:34:00 mhaveman - * -Fixed bug for RX counters. On an RX overflow interrupt the high - * words of all RX counters were incremented. - * -SET operations on FLOWCTRL_MODE and LINK_MODE accept now the - * value 0, which has no effect. It is usefull for multiple instance - * SETs. - * - * Revision 1.37 1998/11/20 08:02:04 mhaveman - * -Fixed: Ports were compared with MAX_SENSORS - * -Fixed: Crash in GetTrapEntry with MEMSET macro - * -Fixed: Conversions between physical, logical port index and instance - * - * Revision 1.36 1998/11/16 07:48:53 mhaveman - * Casted SK_DRIVER_SENDEVENT with (void) to eleminate compiler warnings - * on Solaris. - * - * Revision 1.35 1998/11/16 07:45:34 mhaveman - * SkAddrOverride now returns value and will be checked. - * - * Revision 1.34 1998/11/10 13:40:37 mhaveman - * Needed to change interface, because NT driver needs a return value - * of needed buffer space on TOO_SHORT errors. Therefore all - * SkPnmiGet/Preset/Set functions now have a pointer to the length - * parameter, where the needed space on error is returned. - * - * Revision 1.33 1998/11/03 13:52:46 mhaveman - * Made file lint conform. - * - * Revision 1.32 1998/11/03 13:19:07 mhaveman - * The events SK_HWEV_SET_LMODE and SK_HWEV_SET_FLOWMODE pass now in - * Para32[0] the physical MAC index and in Para32[1] the new mode. - * - * Revision 1.31 1998/11/03 12:30:40 gklug - * fix: compiler warning memset - * - * Revision 1.30 1998/11/03 12:04:46 mhaveman - * Fixed problem in SENSOR_VALUE, which wrote beyond the buffer end - * Fixed alignment problem with CHIPSET. - * - * Revision 1.29 1998/11/02 11:23:54 mhaveman - * Corrected SK_ERROR_LOG to SK_ERR_LOG. Sorry. - * - * Revision 1.28 1998/11/02 10:47:16 mhaveman - * Added syslog messages for internal errors. - * - * Revision 1.27 1998/10/30 15:48:06 mhaveman - * Fixed problems after simulation of SK_PNMI_EVT_CHG_EST_TIMER and - * RlmtChangeThreshold calculation. - * - * Revision 1.26 1998/10/29 15:36:55 mhaveman - * -Fixed bug in trap buffer handling. - * -OID_SKGE_DRIVER_DESCR, OID_SKGE_DRIVER_VERSION, OID_SKGE_HW_DESCR, - * OID_SKGE_HW_VERSION, OID_SKGE_VPD_ENTRIES_LIST, OID_SKGE_VPD_KEY, - * OID_SKGE_VPD_VALUE, and OID_SKGE_SENSOR_DESCR return values with - * a leading octet before each string storing the string length. - * -Perform a RlmtUpdate during SK_PNMI_EVT_XMAC_RESET to minimize - * RlmtUpdate calls in GetStatVal. - * -Inserted SK_PNMI_CHECKFLAGS macro increase readability. - * - * Revision 1.25 1998/10/29 08:50:36 mhaveman - * Fixed problems after second event simulation. - * - * Revision 1.24 1998/10/28 08:44:37 mhaveman - * -Fixed alignment problem - * -Fixed problems during event simulation - * -Fixed sequence of error return code (INSTANCE -> ACCESS -> SHORT) - * -Changed type of parameter Instance back to SK_U32 because of VPD - * -Updated new VPD function calls - * - * Revision 1.23 1998/10/23 10:16:37 mhaveman - * Fixed bugs after buffer test simulation. - * - * Revision 1.22 1998/10/21 13:23:52 mhaveman - * -Call syntax of SkOsGetTime() changed to SkOsGetTime(pAc). - * -Changed calculation of hundrets of seconds. - * - * Revision 1.20 1998/10/20 07:30:45 mhaveman - * Made type changes to unsigned integer where possible. - * - * Revision 1.19 1998/10/19 10:51:30 mhaveman - * -Made Bug fixes after simulation run - * -Renamed RlmtMAC... to RlmtPort... - * -Marked workarounds with Errata comments - * - * Revision 1.18 1998/10/14 07:50:08 mhaveman - * -For OID_SKGE_LINK_STATUS the link down detection has moved from RLMT - * to HWACCESS. - * -Provided all MEMCPY/MEMSET macros with (char *) pointers, because - * Solaris throwed warnings when mapping to bcopy/bset. - * - * Revision 1.17 1998/10/13 07:42:01 mhaveman - * -Added OIDs OID_SKGE_TRAP_NUMBER and OID_SKGE_ALL_DATA - * -Removed old cvs history entries - * -Renamed MacNumber to PortNumber - * - * Revision 1.16 1998/10/07 10:52:49 mhaveman - * -Inserted handling of some OID_GEN_ Ids for windows - * -Fixed problem with 803.2 statistic. - * - * Revision 1.15 1998/10/01 09:16:29 mhaveman - * Added Debug messages for function call and UpdateFlag tracing. - * - * Revision 1.14 1998/09/30 13:39:09 mhaveman - * -Reduced namings of 'MAC' by replacing them with 'PORT'. - * -Completed counting of OID_SKGE_RX_HW_ERROR_CTS, - * OID_SKGE_TX_HW_ERROR_CTS, - * OID_SKGE_IN_ERRORS_CTS, and OID_SKGE_OUT_ERROR_CTS. - * -SET check for RlmtMode - * - * Revision 1.13 1998/09/28 13:13:08 mhaveman - * Hide strcmp, strlen, and strncpy behind macros SK_STRCMP, SK_STRLEN, - * and SK_STRNCPY. (Same reasons as for mem.. and MEM..) - * - * Revision 1.12 1998/09/16 08:18:36 cgoos - * Fix: XM_INxx and XM_OUTxx called with different parameter order: - * sometimes IoC,Mac,... sometimes Mac,IoC,... Now always first variant. - * Fix: inserted "Pnmi." into some pAC->pDriverDescription / Version. - * Change: memset, memcpy to makros SK_MEMSET, SK_MEMCPY - * - * Revision 1.11 1998/09/04 17:01:45 mhaveman - * Added SyncCounter as macro and OID_SKGE_.._NO_DESCR_CTS to - * OID_SKGE_RX_NO_BUF_CTS. - * - * Revision 1.10 1998/09/04 14:35:35 mhaveman - * Added macro counters, that are counted by driver. - * - ****************************************************************************/ - - +#ifndef _lint static const char SysKonnectFileId[] = - "@(#) $Id: skgepnmi.c,v 1.1 2004/07/22 19:49:44 joff Exp $" - " (C) SysKonnect."; + "@(#) $Id: skgepnmi.c,v 1.2 2004/08/04 01:29:22 joff Exp $ (C) Marvell."; +#endif /* !_lint */ #include "h/skdrv1st.h" #include "h/sktypes.h" @@ -475,11 +61,13 @@ unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, unsigned int *pLen, SK_U32 NetIndex); -int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, +int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, unsigned int *pLen, SK_U32 NetIndex); -int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, +int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, unsigned int *pLen, SK_U32 NetIndex); int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param); +int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf, + unsigned int * pLen, SK_U32 NetIndex); /* @@ -533,7 +121,7 @@ /* * Overflow status register bit table and corresponding counter * dependent on MAC type - the number relates to the size of overflow - * mask returned by the pFnMacOverflow function + * mask returned by the pFnMacOverflow function */ PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = { /* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST}, @@ -697,7 +285,7 @@ /* SK_PNMI_HRX_FRAMING */ {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}}, /* SK_PNMI_HRX_UNDERSIZE */ - {{0, SK_FALSE},{GM_RXF_SHT, SK_TRUE}}, + {{0, SK_FALSE}, {GM_RXF_SHT, SK_TRUE}}, /* SK_PNMI_HRX_OVERFLOW */ {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}}, /* SK_PNMI_HRX_JABBER */ @@ -771,7 +359,6 @@ SK_U16 Val16; /* Multiple purpose 16 bit variable */ SK_U8 Val8; /* Mulitple purpose 8 bit variable */ SK_EVPARA EventParam; /* Event struct for timer event */ - SK_GEPORT *pPrt; SK_PNMI_VCT *pVctBackupData; @@ -800,7 +387,6 @@ ("CounterOffset struct size (%d) differs from" "SK_PNMI_MAX_IDX (%d)\n", SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX)); - BRK; } if (SK_PNMI_MAX_IDX != @@ -811,10 +397,9 @@ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL, ("StatAddr table size (%d) differs from " "SK_PNMI_MAX_IDX (%d)\n", - (sizeof(StatAddr) / + (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)), SK_PNMI_MAX_IDX)); - BRK; } #endif /* SK_PNMI_CHECK */ break; @@ -832,8 +417,7 @@ /* Initialize DSP variables for Vct() to 0xff => Never written! */ for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) { - pPrt = &pAC->GIni.GP[PortIndex]; - pPrt->PCableLen =0xff; + pAC->GIni.GP[PortIndex].PCableLen = 0xff; pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex]; pVctBackupData->PCableLen = 0xff; } @@ -961,14 +545,14 @@ default: pAC->Pnmi.Connector = 1; break; - } + } break; - + case SK_INIT_RUN: /* * Start timer for RLMT change counter */ - SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam)); + SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer, 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER, EventParam); @@ -997,17 +581,17 @@ * the data. * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port + * exist (e.g. port instance 3 on a two port * adapter. */ int SkPnmiGetVar( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ SK_U32 Id, /* Object ID that is to be processed */ -void *pBuf, /* Buffer to which to mgmt data will be retrieved */ +void *pBuf, /* Buffer to which the management data will be copied */ unsigned int *pLen, /* On call: buffer length. On return: used buffer */ SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n", @@ -1025,8 +609,8 @@ * Calls a general sub-function for all this stuff. The preset does * the same as a set, but returns just before finally setting the * new value. This is usefull to check if a set might be successfull. - * If as instance a -1 is passed, an array of values is supposed and - * all instance of the OID will be set. + * If the instance -1 is passed, an array of values is supposed and + * all instances of the OID will be set. * * Returns: * SK_PNMI_ERR_OK The request was successfully performed. @@ -1039,17 +623,17 @@ * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port + * exist (e.g. port instance 3 on a two port * adapter. */ int SkPnmiPreSetVar( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ SK_U32 Id, /* Object ID that is to be processed */ -void *pBuf, /* Buffer which stores the mgmt data to be set */ -unsigned int *pLen, /* Total length of mgmt data */ +void *pBuf, /* Buffer to which the management data will be copied */ +unsigned int *pLen, /* Total length of management data */ SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n", @@ -1068,8 +652,8 @@ * Calls a general sub-function for all this stuff. The preset does * the same as a set, but returns just before finally setting the * new value. This is usefull to check if a set might be successfull. - * If as instance a -1 is passed, an array of values is supposed and - * all instance of the OID will be set. + * If the instance -1 is passed, an array of values is supposed and + * all instances of the OID will be set. * * Returns: * SK_PNMI_ERR_OK The request was successfully performed. @@ -1082,17 +666,17 @@ * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port + * exist (e.g. port instance 3 on a two port * adapter. */ int SkPnmiSetVar( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ SK_U32 Id, /* Object ID that is to be processed */ -void *pBuf, /* Buffer which stores the mgmt data to be set */ -unsigned int *pLen, /* Total length of mgmt data */ +void *pBuf, /* Buffer to which the management data will be copied */ +unsigned int *pLen, /* Total length of management data */ SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n", @@ -1119,14 +703,14 @@ * SK_PNMI_ERR_GENERAL A general severe internal error occured * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take * the data. - * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist + * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist */ int SkPnmiGetStruct( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ -void *pBuf, /* Buffer which will store the retrieved data */ +void *pBuf, /* Buffer to which the management data will be copied. */ unsigned int *pLen, /* Length of buffer */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { int Ret; unsigned int TableIndex; @@ -1304,13 +888,13 @@ SK_IOC IoC, /* IO context handle */ void *pBuf, /* Buffer which contains the data to be set */ unsigned int *pLen, /* Length of buffer */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n", *pLen, NetIndex)); - return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf, + return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf, pLen, NetIndex)); } @@ -1342,13 +926,13 @@ SK_IOC IoC, /* IO context handle */ void *pBuf, /* Buffer which contains the data to be set */ unsigned int *pLen, /* Length of buffer */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n", *pLen, NetIndex)); - return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf, + return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf, pLen, NetIndex)); } @@ -1395,9 +979,9 @@ * is now an active port. PNMI will now * add the statistic data of this port to * the virtual port. - * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first Parameter + * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first parameter * contains the number of nets. 1 means single net, 2 means - * dual net. The second Parameter is -1 + * dual net. The second parameter is -1 * * Returns: * Always 0 @@ -1409,7 +993,7 @@ SK_EVPARA Param) /* Event dependent parameter */ { unsigned int PhysPortIndex; - unsigned int MaxNetNumber; + unsigned int MaxNetNumber; int CounterIndex; int Ret; SK_U16 MacStatus; @@ -1439,7 +1023,7 @@ ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n", (unsigned int)Event, (unsigned int)Param.Para64)); } -#endif +#endif /* DEBUG */ SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call"); MacType = pAC->GIni.GIMacType; @@ -1458,18 +1042,18 @@ PhysPortIndex)); return (0); } -#endif +#endif /* DEBUG */ OverflowStatus = 0; /* * Check which source caused an overflow interrupt. */ - if ((pAC->GIni.GIFunc.pFnMacOverflow( - pAC, IoC, PhysPortIndex, MacStatus, &OverflowStatus) != 0) || + if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex, + MacStatus, &OverflowStatus) != 0) || (OverflowStatus == 0)) { SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); - return (0); + return (0); } /* @@ -1489,20 +1073,20 @@ case SK_PNMI_HTX_UTILUNDER: case SK_PNMI_HTX_UTILOVER: - XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, - &Register); - Register |= XM_TX_SAM_LINE; - XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, - Register); + if (MacType == SK_MAC_XMAC) { + XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register); + Register |= XM_TX_SAM_LINE; + XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register); + } break; case SK_PNMI_HRX_UTILUNDER: case SK_PNMI_HRX_UTILOVER: - XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, - &Register); - Register |= XM_RX_SAM_LINE; - XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, - Register); + if (MacType == SK_MAC_XMAC) { + XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register); + Register |= XM_RX_SAM_LINE; + XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register); + } break; case SK_PNMI_HTX_OCTETHIGH: @@ -1543,7 +1127,8 @@ (unsigned int)Param.Para64)); return (0); } -#endif +#endif /* DEBUG */ + /* * Store a trap message in the trap buffer and generate * an event for user space applications with the @@ -1559,11 +1144,12 @@ if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) { SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR:SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n", + ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n", (unsigned int)Param.Para64)); return (0); } -#endif +#endif /* DEBUG */ + /* * Store a trap message in the trap buffer and generate * an event for user space applications with the @@ -1583,7 +1169,8 @@ (unsigned int)Param.Para64)); return (0); } -#endif +#endif /* DEBUG */ + /* * Store a trap message in the trap buffer and generate * an event for user space applications with the @@ -1603,7 +1190,8 @@ (unsigned int)Param.Para64)); return (0); } -#endif +#endif /* DEBUG */ + /* * Store a trap message in the trap buffer and generate * an event for user space applications with the @@ -1623,7 +1211,7 @@ * Be careful in changing these values, on change check * - typedef of SK_PNMI_ESTIMATE (Size of EstValue * array one less than value number) - * - Timer initilization SkTimerStart() in SkPnmiInit + * - Timer initialization SkTimerStart() in SkPnmiInit * - Delta value below must be multiplicated with * power of 2 * @@ -1674,7 +1262,7 @@ (void)SK_DRIVER_SENDEVENT(pAC, IoC); } - SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam)); + SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer, 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER, EventParam); @@ -1696,20 +1284,21 @@ return (0); } -#endif +#endif /* DEBUG */ /* - * Set all counters and timestamps to zero + * Set all counters and timestamps to zero. + * The according NetIndex is required as a + * parameter of the event. */ - ResetCounter(pAC, IoC, NetIndex); /* the according NetIndex is required - as a Parameter of the Event */ + ResetCounter(pAC, IoC, NetIndex); break; case SK_PNMI_EVT_XMAC_RESET: /* * To grant continuous counter values store the current * XMAC statistic values to the entries 1..n of the - * CounterOffset array. XMAC Errata #2 + * CounterOffset array. XMAC Errata #2 */ #ifdef DEBUG if ((unsigned int)Param.Para64 >= SK_MAX_MACS) { @@ -1745,11 +1334,10 @@ continue; } - pAC->Pnmi.Port[PhysPortIndex]. - CounterOffset[CounterIndex] = GetPhysStatVal( - pAC, IoC, PhysPortIndex, CounterIndex); - pAC->Pnmi.Port[PhysPortIndex]. - CounterHigh[CounterIndex] = 0; + pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] = + GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex); + + pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0; } pAC->Pnmi.MacUpdatedFlag --; @@ -1766,7 +1354,8 @@ return (0); } -#endif +#endif /* DEBUG */ + /* * Store a trap message in the trap buffer and generate an event for * user space applications with the SK_DRIVER_SENDEVENT macro. @@ -1775,8 +1364,7 @@ (void)SK_DRIVER_SENDEVENT(pAC, IoC); /* Bugfix for XMAC errata (#10620)*/ - if (pAC->GIni.GIMacType == SK_MAC_XMAC){ - + if (MacType == SK_MAC_XMAC) { /* Add incremental difference to offset (#10620)*/ (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex, XM_RXE_SHT_ERR, &Val32); @@ -1803,20 +1391,22 @@ return (0); } -#endif +#endif /* DEBUG */ + /* * Store a trap message in the trap buffer and generate an event for * user space applications with the SK_DRIVER_SENDEVENT macro. */ QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex); (void)SK_DRIVER_SENDEVENT(pAC, IoC); - + /* Bugfix #10620 - get zero level for incremental difference */ - if ((pAC->GIni.GIMacType == SK_MAC_XMAC)) { + if (MacType == SK_MAC_XMAC) { (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex, XM_RXE_SHT_ERR, &Val32); - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark = + + pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex]. CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32); } @@ -1840,7 +1430,8 @@ ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n", NetIndex)); } -#endif +#endif /* DEBUG */ + /* * For now, ignore event if NetIndex != 0. */ @@ -1917,7 +1508,8 @@ ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n", NetIndex)); } -#endif +#endif /* DEBUG */ + /* * For now, ignore event if NetIndex != 0. */ @@ -1979,9 +1571,7 @@ pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value; } - /* - * Set port to active - */ + /* Set port to active */ pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE; pAC->Pnmi.MacUpdatedFlag --; @@ -2023,47 +1613,56 @@ break; case SK_PNMI_EVT_VCT_RESET: - PhysPortIndex = Param.Para32[0]; - pPrt = &pAC->GIni.GP[PhysPortIndex]; - pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex]; - - if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) { - RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE); - if (RetCode == 2) { - /* - * VCT test is still running. - * Start VCT timer counter again. - */ - SK_MEMSET((char *) &Param, 0, sizeof(Param)); - Param.Para32[0] = PhysPortIndex; - Param.Para32[1] = -1; - SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer, - 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param); - break; - } - pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING; - pAC->Pnmi.VctStatus[PhysPortIndex] |= - (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE); + PhysPortIndex = Param.Para32[0]; + pPrt = &pAC->GIni.GP[PhysPortIndex]; + pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex]; - /* Copy results for later use to PNMI struct. */ - for (i = 0; i < 4; i++) { - if (pPrt->PMdiPairLen[i] > 35) { - CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28); + if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) { + RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE); + if (RetCode == 2) { + /* + * VCT test is still running. + * Start VCT timer counter again. + */ + SK_MEMSET((char *) &Param, 0, sizeof(Param)); + Param.Para32[0] = PhysPortIndex; + Param.Para32[1] = -1; + SkTimerStart(pAC, IoC, + &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer, + 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param); + break; } - else { - CableLength = 0; + pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING; + pAC->Pnmi.VctStatus[PhysPortIndex] |= + (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE); + + /* Copy results for later use to PNMI struct. */ + for (i = 0; i < 4; i++) { + if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) { + if ((pPrt->PMdiPairLen[i] > 35) && + (pPrt->PMdiPairLen[i] < 0xff)) { + pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH; + } + } + if ((pPrt->PMdiPairLen[i] > 35) && + (pPrt->PMdiPairLen[i] != 0xff)) { + CableLength = 1000 * + (((175 * pPrt->PMdiPairLen[i]) / 210) - 28); + } + else { + CableLength = 0; + } + pVctBackupData->PMdiPairLen[i] = CableLength; + pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i]; } - pVctBackupData->PMdiPairLen[i] = CableLength; - pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i]; + + Param.Para32[0] = PhysPortIndex; + Param.Para32[1] = -1; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param); + SkEventDispatcher(pAC, IoC); } - Param.Para32[0] = PhysPortIndex; - Param.Para32[1] = -1; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param); - SkEventDispatcher(pAC, IoC); - } - - break; + break; default: break; @@ -2091,19 +1690,19 @@ * SkGePnmiPreSetVar, or SkGePnmiSetVar. * * Returns: - * SK_PNMI_ERR_XXX. For details have a look to the description of the + * SK_PNMI_ERR_XXX. For details have a look at the description of the * calling functions. - * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist + * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist */ PNMI_STATIC int PnmiVar( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ -int Action, /* Get/PreSet/Set action */ +int Action, /* GET/PRESET/SET action */ SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer which stores the mgmt data to be set */ -unsigned int *pLen, /* Total length of mgmt data */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* Total length of pBuf management data */ SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { unsigned int TableIndex; int Ret; @@ -2115,9 +1714,7 @@ return (SK_PNMI_ERR_UNKNOWN_OID); } - /* - * Check NetIndex - */ + /* Check NetIndex */ if (NetIndex >= pAC->Rlmt.NumNets) { return (SK_PNMI_ERR_UNKNOWN_NET); } @@ -2148,15 +1745,15 @@ * * Returns: * SK_PNMI_ERR_XXX. The codes are described in the calling functions. - * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist + * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist */ PNMI_STATIC int PnmiStruct( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ -int Action, /* Set action to be performed */ -char *pBuf, /* Buffer which contains the data to be set */ -unsigned int *pLen, /* Length of buffer */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +int Action, /* PRESET/SET action to be performed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* Length of pBuf management data buffer */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { int Ret; unsigned int TableIndex; @@ -2182,9 +1779,7 @@ return (SK_PNMI_ERR_TOO_SHORT); } - /* - * Check NetIndex - */ + /* Check NetIndex */ if (NetIndex >= pAC->Rlmt.NumNets) { return (SK_PNMI_ERR_UNKNOWN_NET); } @@ -2351,19 +1946,19 @@ * value range. * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port + * exist (e.g. port instance 3 on a two port * adapter. */ PNMI_STATIC int OidStruct( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ -int Action, /* Get/PreSet/Set action */ +int Action, /* GET/PRESET/SET action */ SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer to which to mgmt data will be retrieved */ -unsigned int *pLen, /* On call: buffer length. On return: used buffer */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { if (Id != OID_SKGE_ALL_DATA) { @@ -2418,19 +2013,19 @@ * value range. * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port + * exist (e.g. port instance 3 on a two port * adapter. */ PNMI_STATIC int Perform( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ -int Action, /* Get/PreSet/Set action */ +int Action, /* GET/PRESET/SET action */ SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer to which to mgmt data will be retrieved */ -unsigned int *pLen, /* On call: buffer length. On return: used buffer */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { int Ret; SK_U32 ActionOp; @@ -2549,19 +2144,19 @@ * the correct data (e.g. a 32bit value is * needed, but a 16 bit value was passed). * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port + * exist (e.g. port instance 3 on a two port * adapter. */ PNMI_STATIC int Mac8023Stat( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ -int Action, /* Get/PreSet/Set action */ +int Action, /* GET/PRESET/SET action */ SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer to which to mgmt data will be retrieved */ -unsigned int *pLen, /* On call: buffer length. On return: used buffer */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { int Ret; SK_U64 StatVal; @@ -2586,9 +2181,7 @@ return (SK_PNMI_ERR_READ_ONLY); } - /* - * Check length - */ + /* Check length */ switch (Id) { case OID_802_3_PERMANENT_ADDRESS: @@ -2609,9 +2202,7 @@ #else /* SK_NDIS_64BIT_CTR */ - /* - * for compatibility, at least 32bit are required for oid - */ + /* for compatibility, at least 32bit are required for OID */ if (*pLen < sizeof(SK_U32)) { /* * but indicate handling for 64bit values, @@ -2657,9 +2248,7 @@ default: StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex); - /* - * by default 32bit values are evaluated - */ + /* by default 32bit values are evaluated */ if (!Is64BitReq) { StatVal32 = (SK_U32)StatVal; SK_PNMI_STORE_U32(pBuf, StatVal32); @@ -2682,7 +2271,7 @@ * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX * * Description: - * Retrieves the XMAC statistic data. + * Retrieves the MAC statistic data. * * Returns: * SK_PNMI_ERR_OK The request was successfully performed. @@ -2691,35 +2280,36 @@ * the correct data (e.g. a 32bit value is * needed, but a 16 bit value was passed). * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port + * exist (e.g. port instance 3 on a two port * adapter. */ PNMI_STATIC int MacPrivateStat( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ -int Action, /* Get/PreSet/Set action */ +int Action, /* GET/PRESET/SET action */ SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer to which to mgmt data will be retrieved */ -unsigned int *pLen, /* On call: buffer length. On return: used buffer */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { unsigned int LogPortMax; unsigned int LogPortIndex; unsigned int PhysPortMax; unsigned int Limit; unsigned int Offset; + int MacType; int Ret; SK_U64 StatVal; + + - - /* - * Calculate instance if wished. MAC index 0 is the virtual - * MAC. - */ + /* Calculate instance if wished. MAC index 0 is the virtual MAC */ PhysPortMax = pAC->GIni.GIMacsFound; LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); + + MacType = pAC->GIni.GIMacType; if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ LogPortMax--; @@ -2742,19 +2332,14 @@ Limit = LogPortMax; } - - /* - * Check action - */ + /* Check action */ if (Action != SK_PNMI_GET) { *pLen = 0; return (SK_PNMI_ERR_READ_ONLY); } - /* - * Check length - */ + /* Check length */ if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) { *pLen = (Limit - LogPortIndex) * sizeof(SK_U64); @@ -2762,7 +2347,7 @@ } /* - * Update XMAC statistic and increment semaphore to indicate that + * Update MAC statistic and increment semaphore to indicate that * an update was already done. */ Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1); @@ -2773,9 +2358,7 @@ } pAC->Pnmi.MacUpdatedFlag ++; - /* - * Get value - */ + /* Get value */ Offset = 0; for (; LogPortIndex < Limit; LogPortIndex ++) { @@ -2790,51 +2373,44 @@ return (SK_PNMI_ERR_GENERAL); */ case OID_SKGE_STAT_RX: - case OID_SKGE_STAT_TX: - switch (pAC->GIni.GIMacType) { - case SK_MAC_XMAC: + if (MacType == SK_MAC_GMAC) { + StatVal = + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HRX_BROADCAST, NetIndex) + + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HRX_MULTICAST, NetIndex) + + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HRX_UNICAST, NetIndex) + + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HRX_UNDERSIZE, NetIndex); + } + else { StatVal = GetStatVal(pAC, IoC, LogPortIndex, IdTable[TableIndex].Param, NetIndex); - break; - - case SK_MAC_GMAC: - if (Id == OID_SKGE_STAT_TX) { - - StatVal = - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HTX_BROADCAST, NetIndex) + - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HTX_MULTICAST, NetIndex) + - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HTX_UNICAST, NetIndex); - } - else { - StatVal = - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HRX_BROADCAST, NetIndex) + - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HRX_MULTICAST, NetIndex) + - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HRX_UNICAST, NetIndex) + - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HRX_UNDERSIZE, NetIndex); - } - break; - - default: - StatVal = 0; - break; } + break; - SK_PNMI_STORE_U64(pBuf + Offset, StatVal); + case OID_SKGE_STAT_TX: + if (MacType == SK_MAC_GMAC) { + StatVal = + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HTX_BROADCAST, NetIndex) + + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HTX_MULTICAST, NetIndex) + + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HTX_UNICAST, NetIndex); + } + else { + StatVal = GetStatVal(pAC, IoC, LogPortIndex, + IdTable[TableIndex].Param, NetIndex); + } break; default: StatVal = GetStatVal(pAC, IoC, LogPortIndex, IdTable[TableIndex].Param, NetIndex); - SK_PNMI_STORE_U64(pBuf + Offset, StatVal); - break; } + SK_PNMI_STORE_U64(pBuf + Offset, StatVal); Offset += sizeof(SK_U64); } @@ -2866,19 +2442,19 @@ * value range. * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port + * exist (e.g. port instance 3 on a two port * adapter. */ PNMI_STATIC int Addr( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ -int Action, /* Get/PreSet/Set action */ +int Action, /* GET/PRESET/SET action */ SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer to which to mgmt data will be retrieved */ -unsigned int *pLen, /* On call: buffer length. On return: used buffer */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { int Ret; unsigned int LogPortMax; @@ -2909,7 +2485,6 @@ LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance); Limit = LogPortIndex + 1; } - else { /* Instance == (SK_U32)(-1), get all Instances of that OID */ LogPortIndex = 0; @@ -2921,9 +2496,7 @@ */ if (Action == SK_PNMI_GET) { - /* - * Check length - */ + /* Check length */ if (*pLen < (Limit - LogPortIndex) * 6) { *pLen = (Limit - LogPortIndex) * 6; @@ -2999,9 +2572,7 @@ return (SK_PNMI_ERR_GENERAL); } - /* - * Check length - */ + /* Check length */ if (*pLen < (Limit - LogPortIndex) * 6) { *pLen = (Limit - LogPortIndex) * 6; @@ -3072,19 +2643,19 @@ * the correct data (e.g. a 32bit value is * needed, but a 16 bit value was passed). * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port + * exist (e.g. port instance 3 on a two port * adapter. */ PNMI_STATIC int CsumStat( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ -int Action, /* Get/PreSet/Set action */ +int Action, /* GET/PRESET/SET action */ SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer to which to mgmt data will be retrieved */ -unsigned int *pLen, /* On call: buffer length. On return: used buffer */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { unsigned int Index; unsigned int Limit; @@ -3119,9 +2690,7 @@ return (SK_PNMI_ERR_READ_ONLY); } - /* - * Check length - */ + /* Check length */ if (*pLen < (Limit - Index) * sizeof(SK_U64)) { *pLen = (Limit - Index) * sizeof(SK_U64); @@ -3190,19 +2759,19 @@ * the correct data (e.g. a 32bit value is * needed, but a 16 bit value was passed). * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port + * exist (e.g. port instance 3 on a two port * adapter. */ PNMI_STATIC int SensorStat( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ -int Action, /* Get/PreSet/Set action */ +int Action, /* GET/PRESET/SET action */ SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer to which to mgmt data will be retrieved */ -unsigned int *pLen, /* On call: buffer length. On return: used buffer */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { unsigned int i; unsigned int Index; @@ -3241,9 +2810,7 @@ return (SK_PNMI_ERR_READ_ONLY); } - /* - * Check length - */ + /* Check length */ switch (Id) { case OID_SKGE_SENSOR_VALUE: @@ -3437,19 +3004,19 @@ * value range. * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port + * exist (e.g. port instance 3 on a two port * adapter. */ PNMI_STATIC int Vpd( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ -int Action, /* Get/PreSet/Set action */ +int Action, /* GET/PRESET/SET action */ SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer to which to mgmt data will be retrieved */ -unsigned int *pLen, /* On call: buffer length. On return: used buffer */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { SK_VPD_STATUS *pVpdStatus; unsigned int BufLen; @@ -3468,8 +3035,7 @@ /* * Get array of all currently stored VPD keys */ - Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), - &KeyNo); + Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo); if (Ret != SK_PNMI_ERR_OK) { *pLen = 0; return (Ret); @@ -3715,7 +3281,7 @@ *pLen = 0; return (SK_PNMI_ERR_GENERAL); } - } + } else { /* The only OID which can be set is VPD_ACTION */ if (Id != OID_SKGE_VPD_ACTION) { @@ -3912,19 +3478,19 @@ * the correct data (e.g. a 32bit value is * needed, but a 16 bit value was passed). * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port + * exist (e.g. port instance 3 on a two port * adapter. */ PNMI_STATIC int General( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ -int Action, /* Get/PreSet/Set action */ +int Action, /* GET/PRESET/SET action */ SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer to which to mgmt data will be retrieved */ +char *pBuf, /* Buffer used for the management data transfer */ unsigned int *pLen, /* On call: buffer length. On return: used buffer */ SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { int Ret; unsigned int Index; @@ -3942,7 +3508,7 @@ int MacType; /* - * Check instance. We only handle single instance variables + * Check instance. We only handle single instance variables. */ if (Instance != (SK_U32)(-1) && Instance != 1) { @@ -4000,6 +3566,9 @@ case OID_GEN_TRANSMIT_QUEUE_LENGTH: case OID_SKGE_TRAP_NUMBER: case OID_SKGE_MDB_VERSION: + case OID_SKGE_BOARDLEVEL: + case OID_SKGE_CHIPID: + case OID_SKGE_RAMSIZE: if (*pLen < sizeof(SK_U32)) { *pLen = sizeof(SK_U32); @@ -4020,6 +3589,7 @@ case OID_SKGE_BUS_WIDTH: case OID_SKGE_SENSOR_NUMBER: case OID_SKGE_CHKSM_NUMBER: + case OID_SKGE_VAUXAVAIL: if (*pLen < sizeof(SK_U8)) { *pLen = sizeof(SK_U8); @@ -4088,10 +3658,10 @@ Val64RxHwErrs = GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex)+ + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex)+ + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) + @@ -4105,8 +3675,8 @@ case OID_GEN_XMIT_ERROR: Val64TxHwErrs = GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex)+ - GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex)+ + GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) + + GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) + GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex); break; } @@ -4133,6 +3703,12 @@ *pLen = Len; break; + case OID_SKGE_BOARDLEVEL: + Val32 = (SK_U32)pAC->GIni.GILevel; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + case OID_SKGE_PORT_NUMBER: Val32 = (SK_U32)pAC->GIni.GIMacsFound; SK_PNMI_STORE_U32(pBuf, Val32); @@ -4205,65 +3781,142 @@ *pLen = Len; break; - case OID_SKGE_HW_DESCR: - /* - * The hardware description is located in the VPD. This - * query may move to the initialisation routine. But - * the VPD data is cached and therefore a call here - * will not make much difference. - */ - Len = 256; - if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) { + case OID_SKGE_DRIVER_RELDATE: + if (pAC->Pnmi.pDriverReleaseDate == NULL) { - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032, - SK_PNMI_ERR032MSG); + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, + SK_PNMI_ERR053MSG); *pLen = 0; return (SK_PNMI_ERR_GENERAL); } - Len ++; + + Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1; if (Len > SK_PNMI_STRINGLEN1) { - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033, - SK_PNMI_ERR033MSG); + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, + SK_PNMI_ERR054MSG); *pLen = 0; return (SK_PNMI_ERR_GENERAL); } + if (*pLen < Len) { *pLen = Len; return (SK_PNMI_ERR_TOO_SHORT); } *pBuf = (char)(Len - 1); - SK_MEMCPY(pBuf + 1, Buf, Len - 1); + SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1); *pLen = Len; break; - case OID_SKGE_HW_VERSION: - /* Oh, I love to do some string manipulation */ - if (*pLen < 5) { + case OID_SKGE_DRIVER_FILENAME: + if (pAC->Pnmi.pDriverFileName == NULL) { - *pLen = 5; - return (SK_PNMI_ERR_TOO_SHORT); + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, + SK_PNMI_ERR055MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); } - Val8 = (SK_U8)pAC->GIni.GIPciHwRev; - pBuf[0] = 4; - pBuf[1] = 'v'; - pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F)); - pBuf[3] = '.'; - pBuf[4] = (char)(0x30 | (Val8 & 0x0F)); - *pLen = 5; - break; - case OID_SKGE_CHIPSET: - Val16 = pAC->Pnmi.Chipset; + Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1; + if (Len > SK_PNMI_STRINGLEN1) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, + SK_PNMI_ERR056MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + if (*pLen < Len) { + + *pLen = Len; + return (SK_PNMI_ERR_TOO_SHORT); + } + *pBuf = (char)(Len - 1); + SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1); + *pLen = Len; + break; + + case OID_SKGE_HW_DESCR: + /* + * The hardware description is located in the VPD. This + * query may move to the initialisation routine. But + * the VPD data is cached and therefore a call here + * will not make much difference. + */ + Len = 256; + if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032, + SK_PNMI_ERR032MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + Len ++; + if (Len > SK_PNMI_STRINGLEN1) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033, + SK_PNMI_ERR033MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + if (*pLen < Len) { + + *pLen = Len; + return (SK_PNMI_ERR_TOO_SHORT); + } + *pBuf = (char)(Len - 1); + SK_MEMCPY(pBuf + 1, Buf, Len - 1); + *pLen = Len; + break; + + case OID_SKGE_HW_VERSION: + /* Oh, I love to do some string manipulation */ + if (*pLen < 5) { + + *pLen = 5; + return (SK_PNMI_ERR_TOO_SHORT); + } + Val8 = (SK_U8)pAC->GIni.GIPciHwRev; + pBuf[0] = 4; + pBuf[1] = 'v'; + pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F)); + pBuf[3] = '.'; + pBuf[4] = (char)(0x30 | (Val8 & 0x0F)); + *pLen = 5; + break; + + case OID_SKGE_CHIPSET: + Val16 = pAC->Pnmi.Chipset; SK_PNMI_STORE_U16(pBuf, Val16); *pLen = sizeof(SK_U16); break; + case OID_SKGE_CHIPID: + Val32 = pAC->GIni.GIChipId; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + + case OID_SKGE_RAMSIZE: + Val32 = pAC->GIni.GIRamSize; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + + case OID_SKGE_VAUXAVAIL: + *pBuf = (char) pAC->GIni.GIVauxAvail; + *pLen = sizeof(char); + break; + case OID_SKGE_BUS_TYPE: - *pBuf = (char)SK_PNMI_BUS_PCI; + *pBuf = (char) SK_PNMI_BUS_PCI; *pLen = sizeof(char); break; @@ -4319,7 +3972,7 @@ break; case OID_SKGE_TX_SW_QUEUE_LEN: - /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ if (MacType == SK_MAC_XMAC) { /* Dual net mode */ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { @@ -4348,7 +4001,7 @@ case OID_SKGE_TX_SW_QUEUE_MAX: - /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ if (MacType == SK_MAC_XMAC) { /* Dual net mode */ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { @@ -4376,7 +4029,7 @@ break; case OID_SKGE_TX_RETRY: - /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ if (MacType == SK_MAC_XMAC) { /* Dual net mode */ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { @@ -4404,7 +4057,7 @@ break; case OID_SKGE_RX_INTR_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ if (MacType == SK_MAC_XMAC) { /* Dual net mode */ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { @@ -4432,7 +4085,7 @@ break; case OID_SKGE_TX_INTR_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ if (MacType == SK_MAC_XMAC) { /* Dual net mode */ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { @@ -4460,7 +4113,7 @@ break; case OID_SKGE_RX_NO_BUF_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ if (MacType == SK_MAC_XMAC) { /* Dual net mode */ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { @@ -4488,7 +4141,7 @@ break; case OID_SKGE_TX_NO_BUF_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ if (MacType == SK_MAC_XMAC) { /* Dual net mode */ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { @@ -4516,7 +4169,7 @@ break; case OID_SKGE_TX_USED_DESCR_NO: - /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ if (MacType == SK_MAC_XMAC) { /* Dual net mode */ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { @@ -4544,7 +4197,7 @@ break; case OID_SKGE_RX_DELIVERED_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ if (MacType == SK_MAC_XMAC) { /* Dual net mode */ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { @@ -4572,7 +4225,7 @@ break; case OID_SKGE_RX_OCTETS_DELIV_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ if (MacType == SK_MAC_XMAC) { /* Dual net mode */ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { @@ -4610,7 +4263,7 @@ break; case OID_SKGE_IN_ERRORS_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ if (MacType == SK_MAC_XMAC) { /* Dual net mode */ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { @@ -4618,7 +4271,7 @@ } /* Single net mode */ else { - Val64 = Val64RxHwErrs + + Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[0].RxNoBufCts + pAC->Pnmi.BufPort[1].RxNoBufCts; } @@ -4630,7 +4283,7 @@ } /* Single net mode */ else { - Val64 = Val64RxHwErrs + + Val64 = Val64RxHwErrs + pAC->Pnmi.Port[0].RxNoBufCts + pAC->Pnmi.Port[1].RxNoBufCts; } @@ -4640,7 +4293,7 @@ break; case OID_SKGE_OUT_ERROR_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ if (MacType == SK_MAC_XMAC) { /* Dual net mode */ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { @@ -4648,7 +4301,7 @@ } /* Single net mode */ else { - Val64 = Val64TxHwErrs + + Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[0].TxNoBufCts + pAC->Pnmi.BufPort[1].TxNoBufCts; } @@ -4660,7 +4313,7 @@ } /* Single net mode */ else { - Val64 = Val64TxHwErrs + + Val64 = Val64TxHwErrs + pAC->Pnmi.Port[0].TxNoBufCts + pAC->Pnmi.Port[1].TxNoBufCts; } @@ -4670,7 +4323,7 @@ break; case OID_SKGE_ERR_RECOVERY_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ if (MacType == SK_MAC_XMAC) { /* Dual net mode */ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { @@ -4711,7 +4364,7 @@ break; case OID_GEN_RCV_ERROR: - /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ if (MacType == SK_MAC_XMAC) { Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; } @@ -4734,7 +4387,7 @@ break; case OID_GEN_XMIT_ERROR: - /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ if (MacType == SK_MAC_XMAC) { Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts; } @@ -4757,7 +4410,7 @@ break; case OID_GEN_RCV_NO_BUFFER: - /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ if (MacType == SK_MAC_XMAC) { Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; } @@ -4823,19 +4476,19 @@ * value range. * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port + * exist (e.g. port instance 3 on a two port * adapter. */ PNMI_STATIC int Rlmt( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ -int Action, /* Get/PreSet/Set action */ +int Action, /* GET/PRESET/SET action */ SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer to which to mgmt data will be retrieved */ -unsigned int *pLen, /* On call: buffer length. On return: used buffer */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { int Ret; unsigned int PhysPortIndex; @@ -4855,7 +4508,7 @@ } /* - * Perform the requested action + * Perform the requested action. */ if (Action == SK_PNMI_GET) { @@ -5128,19 +4781,19 @@ * the correct data (e.g. a 32bit value is * needed, but a 16 bit value was passed). * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port + * exist (e.g. port instance 3 on a two port * adapter. */ PNMI_STATIC int RlmtStat( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ -int Action, /* Get/PreSet/Set action */ +int Action, /* GET/PRESET/SET action */ SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer to which to mgmt data will be retrieved */ -unsigned int *pLen, /* On call: buffer length. On return: used buffer */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { unsigned int PhysPortMax; unsigned int PhysPortIndex; @@ -5151,7 +4804,7 @@ SK_U64 Val64; /* - * Calculate the port indexes from the instance + * Calculate the port indexes from the instance. */ PhysPortMax = pAC->GIni.GIMacsFound; @@ -5330,19 +4983,19 @@ * value range. * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port + * exist (e.g. port instance 3 on a two port * adapter. */ PNMI_STATIC int MacPrivateConf( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ -int Action, /* Get/PreSet/Set action */ +int Action, /* GET/PRESET/SET action */ SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer to which to mgmt data will be retrieved */ -unsigned int *pLen, /* On call: buffer length. On return: used buffer */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { unsigned int PhysPortMax; unsigned int PhysPortIndex; @@ -5351,14 +5004,13 @@ unsigned int Limit; unsigned int Offset; char Val8; - int Ret; + char *pBufPtr; + int Ret; SK_EVPARA EventParam; SK_U32 Val32; - /* - * Calculate instance if wished. MAC index 0 is the virtual - * MAC. + * Calculate instance if wished. MAC index 0 is the virtual MAC. */ PhysPortMax = pAC->GIni.GIMacsFound; LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); @@ -5389,9 +5041,7 @@ */ if (Action == SK_PNMI_GET) { - /* - * Check length - */ + /* Check length */ switch (Id) { case OID_SKGE_PMD: @@ -5409,18 +5059,21 @@ case OID_SKGE_SPEED_CAP: case OID_SKGE_SPEED_MODE: case OID_SKGE_SPEED_STATUS: +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: +#endif if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) { - *pLen = (Limit - LogPortIndex) * - sizeof(SK_U8); + *pLen = (Limit - LogPortIndex) * sizeof(SK_U8); return (SK_PNMI_ERR_TOO_SHORT); } break; case OID_SKGE_MTU: - if (*pLen < sizeof(SK_U32)) { + case OID_SKGE_PHY_TYPE: + if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) { - *pLen = sizeof(SK_U32); + *pLen = (Limit - LogPortIndex) * sizeof(SK_U32); return (SK_PNMI_ERR_TOO_SHORT); } break; @@ -5449,343 +5102,340 @@ Offset = 0; for (; LogPortIndex < Limit; LogPortIndex ++) { + pBufPtr = pBuf + Offset; + switch (Id) { case OID_SKGE_PMD: - *(pBuf + Offset) = pAC->Pnmi.PMD; + *pBufPtr = pAC->Pnmi.PMD; Offset += sizeof(char); break; case OID_SKGE_CONNECTOR: - *(pBuf + Offset) = pAC->Pnmi.Connector; + *pBufPtr = pAC->Pnmi.Connector; Offset += sizeof(char); break; + case OID_SKGE_PHY_TYPE: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + continue; + } + else { + /* Get value for physical ports */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + Val32 = pAC->GIni.GP[PhysPortIndex].PhyType; + SK_PNMI_STORE_U32(pBufPtr, Val32); + } + } + else { /* DualNetMode */ + + Val32 = pAC->GIni.GP[NetIndex].PhyType; + SK_PNMI_STORE_U32(pBufPtr, Val32); + } + Offset += sizeof(SK_U32); + break; + +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + continue; + } + else { + /* Get value for physical ports */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); + Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState; + *pBufPtr = Val8; + } + } + else { /* DualNetMode */ + + Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState; + *pBufPtr = Val8; + } + Offset += sizeof(SK_U8); + break; +#endif + case OID_SKGE_LINK_CAP: if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + - Offset); + VirtualConf(pAC, IoC, Id, pBufPtr); } else { /* Get value for physical ports */ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( pAC, LogPortIndex); - *(pBuf + Offset) = pAC->GIni.GP[ - PhysPortIndex].PLinkCap; + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap; } - Offset += sizeof(char); } else { /* DualNetMode */ - *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkCap; - Offset += sizeof(char); + *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap; } + Offset += sizeof(char); break; case OID_SKGE_LINK_MODE: if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + - Offset); + VirtualConf(pAC, IoC, Id, pBufPtr); } else { /* Get value for physical ports */ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( pAC, LogPortIndex); - *(pBuf + Offset) = pAC->GIni.GP[ - PhysPortIndex].PLinkModeConf; + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf; } - Offset += sizeof(char); } - else { /* DualNetMode */ + else { /* DualNetMode */ - *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkModeConf; - Offset += sizeof(char); + *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf; } + Offset += sizeof(char); break; case OID_SKGE_LINK_MODE_STATUS: if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + - Offset); + VirtualConf(pAC, IoC, Id, pBufPtr); } else { /* Get value for physical port */ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( pAC, LogPortIndex); - *(pBuf + Offset) = - CalculateLinkModeStatus(pAC, - IoC, PhysPortIndex); + *pBufPtr = + CalculateLinkModeStatus(pAC, IoC, PhysPortIndex); } - Offset += sizeof(char); } else { /* DualNetMode */ - *(pBuf + Offset) = CalculateLinkModeStatus(pAC, IoC, NetIndex); - Offset += sizeof(char); + + *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex); } + Offset += sizeof(char); break; case OID_SKGE_LINK_STATUS: if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + - Offset); + VirtualConf(pAC, IoC, Id, pBufPtr); } else { /* Get value for physical ports */ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( pAC, LogPortIndex); - *(pBuf + Offset) = - CalculateLinkStatus(pAC, - IoC, PhysPortIndex); + *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex); } - Offset += sizeof(char); } else { /* DualNetMode */ - *(pBuf + Offset) = CalculateLinkStatus(pAC, IoC, NetIndex); - Offset += sizeof(char); + *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex); } + Offset += sizeof(char); break; case OID_SKGE_FLOWCTRL_CAP: if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + - Offset); + VirtualConf(pAC, IoC, Id, pBufPtr); } else { /* Get value for physical ports */ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( pAC, LogPortIndex); - *(pBuf + Offset) = pAC->GIni.GP[ - PhysPortIndex].PFlowCtrlCap; + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap; } - Offset += sizeof(char); } else { /* DualNetMode */ - *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlCap; - Offset += sizeof(char); + *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap; } + Offset += sizeof(char); break; case OID_SKGE_FLOWCTRL_MODE: if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + - Offset); + VirtualConf(pAC, IoC, Id, pBufPtr); } else { /* Get value for physical port */ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( pAC, LogPortIndex); - *(pBuf + Offset) = pAC->GIni.GP[ - PhysPortIndex].PFlowCtrlMode; + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode; } - Offset += sizeof(char); } else { /* DualNetMode */ - *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlMode; - Offset += sizeof(char); + *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode; } + Offset += sizeof(char); break; case OID_SKGE_FLOWCTRL_STATUS: if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + - Offset); + VirtualConf(pAC, IoC, Id, pBufPtr); } else { /* Get value for physical port */ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( pAC, LogPortIndex); - *(pBuf + Offset) = pAC->GIni.GP[ - PhysPortIndex].PFlowCtrlStatus; + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus; } - Offset += sizeof(char); } else { /* DualNetMode */ - *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlStatus; - Offset += sizeof(char); + *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus; } + Offset += sizeof(char); break; case OID_SKGE_PHY_OPERATION_CAP: if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + - Offset); + VirtualConf(pAC, IoC, Id, pBufPtr); } else { /* Get value for physical ports */ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( pAC, LogPortIndex); - *(pBuf + Offset) = pAC->GIni.GP[ - PhysPortIndex].PMSCap; + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap; } - Offset += sizeof(char); } else { /* DualNetMode */ - *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSCap; - Offset += sizeof(char); + *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap; } + Offset += sizeof(char); break; case OID_SKGE_PHY_OPERATION_MODE: if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + Offset); + VirtualConf(pAC, IoC, Id, pBufPtr); } else { /* Get value for physical port */ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( pAC, LogPortIndex); - *(pBuf + Offset) = pAC->GIni.GP[ - PhysPortIndex].PMSMode; + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode; } - Offset += sizeof(char); } else { /* DualNetMode */ - *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSMode; - Offset += sizeof(char); + *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode; } + Offset += sizeof(char); break; case OID_SKGE_PHY_OPERATION_STATUS: if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + Offset); + VirtualConf(pAC, IoC, Id, pBufPtr); } else { /* Get value for physical port */ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( pAC, LogPortIndex); - *(pBuf + Offset) = pAC->GIni.GP[ - PhysPortIndex].PMSStatus; + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus; } - Offset += sizeof(char); } else { - *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSStatus; - Offset += sizeof(char); + *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus; } + Offset += sizeof(char); break; case OID_SKGE_SPEED_CAP: if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + - Offset); + VirtualConf(pAC, IoC, Id, pBufPtr); } else { /* Get value for physical ports */ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( pAC, LogPortIndex); - *(pBuf + Offset) = pAC->GIni.GP[ - PhysPortIndex].PLinkSpeedCap; + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap; } - Offset += sizeof(char); } else { /* DualNetMode */ - *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedCap; - Offset += sizeof(char); + *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap; } + Offset += sizeof(char); break; case OID_SKGE_SPEED_MODE: if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + Offset); + VirtualConf(pAC, IoC, Id, pBufPtr); } else { /* Get value for physical port */ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( pAC, LogPortIndex); - *(pBuf + Offset) = pAC->GIni.GP[ - PhysPortIndex].PLinkSpeed; + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed; } - Offset += sizeof(char); } else { /* DualNetMode */ - *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeed; - Offset += sizeof(char); + *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed; } + Offset += sizeof(char); break; case OID_SKGE_SPEED_STATUS: if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBuf + Offset); + VirtualConf(pAC, IoC, Id, pBufPtr); } else { /* Get value for physical port */ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( pAC, LogPortIndex); - *(pBuf + Offset) = pAC->GIni.GP[ - PhysPortIndex].PLinkSpeedUsed; + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed; } - Offset += sizeof(char); } else { /* DualNetMode */ - *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedUsed; - Offset += sizeof(char); + *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed; } + Offset += sizeof(char); break; case OID_SKGE_MTU: Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex); - SK_PNMI_STORE_U32(pBuf + Offset, Val32); + SK_PNMI_STORE_U32(pBufPtr, Val32); Offset += sizeof(SK_U32); break; @@ -5825,6 +5475,16 @@ } break; +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: + if (*pLen < Limit - LogPortIndex) { + + *pLen = Limit - LogPortIndex; + return (SK_PNMI_ERR_TOO_SHORT); + } + break; +#endif + case OID_SKGE_MTU: if (*pLen < sizeof(SK_U32)) { @@ -6181,6 +5841,116 @@ Offset += sizeof(SK_U32); break; + +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: + /* The preset ends here */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + Offset = 0; + continue; + } + else { + /* Set value for physical ports */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); + + switch (*(pBuf + Offset)) { + case 0: + /* If LowPowerMode is active, we can leave it. */ + if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { + + Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex); + + if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) { + + SkDrvInitAdapter(pAC); + } + break; + } + else { + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + case 1: + case 2: + case 3: + case 4: + /* If no LowPowerMode is active, we can enter it. */ + if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { + + if ((*(pBuf + Offset)) < 3) { + + SkDrvDeInitAdapter(pAC); + } + + Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf); + break; + } + else { + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + default: + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + } + } + else { /* DualNetMode */ + + switch (*(pBuf + Offset)) { + case 0: + /* If we are in a LowPowerMode, we can leave it. */ + if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { + + Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex); + + if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) { + + SkDrvInitAdapter(pAC); + } + break; + } + else { + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + case 1: + case 2: + case 3: + case 4: + /* If we are not already in LowPowerMode, we can enter it. */ + if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { + + if ((*(pBuf + Offset)) < 3) { + + SkDrvDeInitAdapter(pAC); + } + else { + + Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf); + } + break; + } + else { + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + default: + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + } + Offset += sizeof(SK_U8); + break; +#endif default: SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, @@ -6212,19 +5982,19 @@ * value range. * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port + * exist (e.g. port instance 3 on a two port * adapter. */ PNMI_STATIC int Monitor( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ -int Action, /* Get/PreSet/Set action */ +int Action, /* GET/PRESET/SET action */ SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer to which to mgmt data will be retrieved */ -unsigned int *pLen, /* On call: buffer length. On return: used buffer */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { unsigned int Index; unsigned int Limit; @@ -6235,7 +6005,7 @@ /* * Calculate instance if wished. */ -/* XXX Not yet implemented. Return always an empty table. */ + /* XXX Not yet implemented. Return always an empty table. */ Entries = 0; if ((Instance != (SK_U32)(-1))) { @@ -6334,21 +6104,24 @@ SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf) /* Buffer to which to mgmt data will be retrieved */ +char *pBuf) /* Buffer used for the management data transfer */ { unsigned int PhysPortMax; unsigned int PhysPortIndex; SK_U8 Val8; + SK_U32 Val32; SK_BOOL PortActiveFlag; - + SK_GEPORT *pPrt; *pBuf = 0; PortActiveFlag = SK_FALSE; PhysPortMax = pAC->GIni.GIMacsFound; - + for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; PhysPortIndex ++) { + pPrt = &pAC->GIni.GP[PhysPortIndex]; + /* Check if the physical port is active */ if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { @@ -6359,6 +6132,14 @@ switch (Id) { + case OID_SKGE_PHY_TYPE: + /* Check if it is the first active port */ + if (*pBuf == 0) { + Val32 = pPrt->PhyType; + SK_PNMI_STORE_U32(pBuf, Val32); + continue; + } + case OID_SKGE_LINK_CAP: /* @@ -6367,14 +6148,14 @@ * From a curious point of view the virtual port * is capable of all found capabilities. */ - *pBuf |= pAC->GIni.GP[PhysPortIndex].PLinkCap; + *pBuf |= pPrt->PLinkCap; break; case OID_SKGE_LINK_MODE: /* Check if it is the first active port */ if (*pBuf == 0) { - *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkModeConf; + *pBuf = pPrt->PLinkModeConf; continue; } @@ -6383,8 +6164,7 @@ * mode than the first one we return a value that * indicates that the link mode is indeterminated. */ - if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkModeConf - ) { + if (*pBuf != pPrt->PLinkModeConf) { *pBuf = SK_LMODE_INDETERMINATED; } @@ -6440,7 +6220,7 @@ /* Check if it is the first active port */ if (*pBuf == 0) { - *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap; + *pBuf = pPrt->PFlowCtrlCap; continue; } @@ -6448,14 +6228,14 @@ * From a curious point of view the virtual port * is capable of all found capabilities. */ - *pBuf |= pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap; + *pBuf |= pPrt->PFlowCtrlCap; break; case OID_SKGE_FLOWCTRL_MODE: /* Check if it is the first active port */ if (*pBuf == 0) { - *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode; + *pBuf = pPrt->PFlowCtrlMode; continue; } @@ -6464,7 +6244,7 @@ * control mode than the first one, we return a value * that indicates that the mode is indeterminated. */ - if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode) { + if (*pBuf != pPrt->PFlowCtrlMode) { *pBuf = SK_FLOW_MODE_INDETERMINATED; } @@ -6474,7 +6254,7 @@ /* Check if it is the first active port */ if (*pBuf == 0) { - *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus; + *pBuf = pPrt->PFlowCtrlStatus; continue; } @@ -6484,7 +6264,7 @@ * value that indicates that the status is * indeterminated. */ - if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus) { + if (*pBuf != pPrt->PFlowCtrlStatus) { *pBuf = SK_FLOW_STAT_INDETERMINATED; } @@ -6494,7 +6274,7 @@ /* Check if it is the first active port */ if (*pBuf == 0) { - *pBuf = pAC->GIni.GP[PhysPortIndex].PMSCap; + *pBuf = pPrt->PMSCap; continue; } @@ -6502,14 +6282,14 @@ * From a curious point of view the virtual port * is capable of all found capabilities. */ - *pBuf |= pAC->GIni.GP[PhysPortIndex].PMSCap; + *pBuf |= pPrt->PMSCap; break; case OID_SKGE_PHY_OPERATION_MODE: /* Check if it is the first active port */ if (*pBuf == 0) { - *pBuf = pAC->GIni.GP[PhysPortIndex].PMSMode; + *pBuf = pPrt->PMSMode; continue; } @@ -6518,7 +6298,7 @@ * slave mode than the first one, we return a value * that indicates that the mode is indeterminated. */ - if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSMode) { + if (*pBuf != pPrt->PMSMode) { *pBuf = SK_MS_MODE_INDETERMINATED; } @@ -6528,7 +6308,7 @@ /* Check if it is the first active port */ if (*pBuf == 0) { - *pBuf = pAC->GIni.GP[PhysPortIndex].PMSStatus; + *pBuf = pPrt->PMSStatus; continue; } @@ -6538,7 +6318,7 @@ * value that indicates that the status is * indeterminated. */ - if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSStatus) { + if (*pBuf != pPrt->PMSStatus) { *pBuf = SK_MS_STAT_INDETERMINATED; } @@ -6548,7 +6328,7 @@ /* Check if it is the first active port */ if (*pBuf == 0) { - *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeed; + *pBuf = pPrt->PLinkSpeed; continue; } @@ -6557,7 +6337,7 @@ * control mode than the first one, we return a value * that indicates that the mode is indeterminated. */ - if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeed) { + if (*pBuf != pPrt->PLinkSpeed) { *pBuf = SK_LSPEED_INDETERMINATED; } @@ -6567,7 +6347,7 @@ /* Check if it is the first active port */ if (*pBuf == 0) { - *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed; + *pBuf = pPrt->PLinkSpeedUsed; continue; } @@ -6577,7 +6357,7 @@ * value that indicates that the status is * indeterminated. */ - if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed) { + if (*pBuf != pPrt->PLinkSpeedUsed) { *pBuf = SK_LSPEED_STAT_INDETERMINATED; } @@ -6665,7 +6445,6 @@ { SK_U8 Result; - if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) { Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN; @@ -6705,7 +6484,6 @@ { SK_U8 Result; - /* Get the current mode, which can be full or half duplex */ Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus; @@ -6713,7 +6491,7 @@ if (Result < SK_LMODE_STAT_HALF) { Result = SK_LMODE_STAT_UNKNOWN; - } + } else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) { /* @@ -6916,8 +6694,8 @@ * * Description: * The XMAC holds its statistic internally. To obtain the current - * values we send a command so that the statistic data will - * be written to apredefined memory area on the adapter. + * values we must send a command so that the statistic data will + * be written to a predefined memory area on the adapter. * * Returns: * SK_PNMI_ERR_OK Task successfully performed. @@ -6944,16 +6722,16 @@ for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) { /* - * 2002-09-13 pweber: Freeze the current sw counters. - * (That should be done as close as - * possible to the update of the - * hw counters) + * 2002-09-13 pweber: Freeze the current SW counters. + * (That should be done as close as + * possible to the update of the + * HW counters) */ if (pAC->GIni.GIMacType == SK_MAC_XMAC) { pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex]; } - /* 2002-09-13 pweber: Update the hw counter */ + /* 2002-09-13 pweber: Update the HW counter */ if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) { return (SK_PNMI_ERR_GENERAL); @@ -6994,6 +6772,7 @@ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ PhysPortIndex = NetIndex; + Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex); } else { /* Single Net mode */ @@ -7008,8 +6787,7 @@ if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { - Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, - StatIndex); + Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex); } } @@ -7019,6 +6797,7 @@ else { /* Get counter value of physical port */ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); + Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex); } } @@ -7052,14 +6831,18 @@ SK_U32 HighVal = 0; SK_U16 Word; int MacType; + unsigned int HelpIndex; + SK_GEPORT *pPrt; SK_PNMI_PORT *pPnmiPrt; SK_GEMACFUNC *pFnMac; + pPrt = &pAC->GIni.GP[PhysPortIndex]; + MacType = pAC->GIni.GIMacType; - /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */ - if (pAC->GIni.GIMacType == SK_MAC_XMAC) { + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ + if (MacType == SK_MAC_XMAC) { pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex]; } else { @@ -7070,15 +6853,46 @@ switch (StatIndex) { case SK_PNMI_HTX: - case SK_PNMI_HRX: - /* Not supported by GMAC */ if (MacType == SK_MAC_GMAC) { - return (Val); + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg, + &LowVal); + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg, + &HighVal); + LowVal += HighVal; + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg, + &HighVal); + LowVal += HighVal; + } + else { + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + } + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + break; + + case SK_PNMI_HRX: + if (MacType == SK_MAC_GMAC) { + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg, + &LowVal); + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg, + &HighVal); + LowVal += HighVal; + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg, + &HighVal); + LowVal += HighVal; + } + else { + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); } - - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); HighVal = pPnmiPrt->CounterHigh[StatIndex]; break; @@ -7109,14 +6923,16 @@ case SK_PNMI_HTX_MACC: /* GMAC only supports PAUSE MAC control frames */ if (MacType == SK_MAC_GMAC) { - Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, SK_PNMI_HTX_PMACC); - - return (Val); + HelpIndex = SK_PNMI_HTX_PMACC; } - + else { + HelpIndex = StatIndex; + } + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); + StatAddr[HelpIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; break; @@ -7133,12 +6949,10 @@ HighVal = pPnmiPrt->CounterHigh[StatIndex]; break; - - case SK_PNMI_HTX_DEFFERAL: /* Not supported by GMAC */ if (MacType == SK_MAC_GMAC) { - return (Val); + return (Val); } /* @@ -7147,16 +6961,16 @@ * * In full-duplex mode the counter remains constant! */ - if ((pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) || - (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_FULL)) { + if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) || + (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) { LowVal = 0; HighVal = 0; } else { - /* Otherwise get contents of hardware register. */ + /* Otherwise get contents of hardware register */ (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[SK_PNMI_HTX_DEFFERAL][MacType].Reg, + StatAddr[StatIndex][MacType].Reg, &LowVal); HighVal = pPnmiPrt->CounterHigh[StatIndex]; } @@ -7184,7 +6998,7 @@ case SK_PNMI_HRX_LONGFRAMES: /* For XMAC the SW counter is managed by PNMI */ if (MacType == SK_MAC_XMAC) { - return (pPnmiPrt->StatRxLongFrameCts); + return (pPnmiPrt->StatRxLongFrameCts); } (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, @@ -7195,19 +7009,17 @@ case SK_PNMI_HRX_TOO_LONG: (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, + StatAddr[StatIndex][MacType].Reg, &LowVal); HighVal = pPnmiPrt->CounterHigh[StatIndex]; Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal); - switch (MacType) { - case SK_MAC_GMAC: + if (MacType == SK_MAC_GMAC) { /* For GMAC the SW counter is additionally managed by PNMI */ Val += pPnmiPrt->StatRxFrameTooLongCts; - break; - - case SK_MAC_XMAC: + } + else { /* * Frames longer than IEEE 802.3 frame max size are counted * by XMAC in frame_too_long counter even reception of long @@ -7215,10 +7027,6 @@ * So correct the value by subtracting RxLongFrame counter. */ Val -= pPnmiPrt->StatRxLongFrameCts; - break; - - default: - break; } LowVal = (SK_U32)Val; @@ -7229,7 +7037,7 @@ /* Not supported by GMAC */ if (MacType == SK_MAC_GMAC) { /* GM_RXE_FRAG?? */ - return (Val); + return (Val); } /* @@ -7237,7 +7045,7 @@ * * If link-down the counter remains constant */ - if (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) { + if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) { /* Otherwise get incremental difference */ (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, @@ -7264,8 +7072,7 @@ case SK_PNMI_HRX_CEXT: /* Not supported by GMAC */ if (MacType == SK_MAC_GMAC) { - /* GM_RXE_FRAG?? */ - return (Val); + return (Val); } (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, @@ -7277,7 +7084,7 @@ case SK_PNMI_HRX_PMACC_ERR: /* For GMAC the SW counter is managed by PNMI */ if (MacType == SK_MAC_GMAC) { - return (pPnmiPrt->StatRxPMaccErr); + return (pPnmiPrt->StatRxPMaccErr); } (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, @@ -7299,16 +7106,14 @@ break; case SK_PNMI_HRX_FCS: - /* - * Broadcom filters fcs errors and counts it in + /* + * Broadcom filters FCS errors and counts it in * Receive Error Counter register */ - if (pAC->GIni.GP[PhysPortIndex].PhyType == SK_PHY_BCOM) { + if (pPrt->PhyType == SK_PHY_BCOM) { /* do not read while not initialized (PHY_READ hangs!)*/ - if (pAC->GIni.GP[PhysPortIndex].PState) { - PHY_READ(IoC, &pAC->GIni.GP[PhysPortIndex], - PhysPortIndex, PHY_BCOM_RE_CTR, - &Word); + if (pPrt->PState != SK_PRT_RESET) { + SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word); LowVal = Word; } @@ -7378,8 +7183,8 @@ EventParam.Para32[1] = (SK_U32)-1; SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS, EventParam); -#endif - +#endif /* SK_USE_CSUM */ + /* Clear XMAC statistic */ for (PhysPortIndex = 0; PhysPortIndex < (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) { @@ -7495,18 +7300,18 @@ End -= EntrySize; #ifdef DEBUG SK_MEMSET(pBuf + End, (char)(-1), EntrySize); -#endif +#endif /* DEBUG */ if (End == BufPad) { #ifdef DEBUG SK_MEMSET(pBuf, (char)(-1), End); -#endif +#endif /* DEBUG */ BufFree += End; End = 0; BufPad = 0; } } - /* + /* * Insert new entry as first entry. Newest entries are * stored at the beginning of the queue. */ @@ -7775,7 +7580,6 @@ } } - #ifdef SK_POWER_MGMT /***************************************************************************** * @@ -7817,45 +7621,50 @@ *pLen = 0; return (SK_PNMI_ERR_UNKNOWN_INST); } + + + /* Check length */ + switch (Id) { - /* - * Perform action - */ - if (Action == SK_PNMI_GET) { + case OID_PNP_CAPABILITIES: + if (*pLen < sizeof(SK_PNP_CAPABILITIES)) { - /* - * Check length - */ - switch (Id) { + *pLen = sizeof(SK_PNP_CAPABILITIES); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; - case OID_PNP_CAPABILITIES: - if (*pLen < sizeof(SK_PNP_CAPABILITIES)) { + case OID_PNP_SET_POWER: + case OID_PNP_QUERY_POWER: + if (*pLen < sizeof(SK_DEVICE_POWER_STATE)) + { + *pLen = sizeof(SK_DEVICE_POWER_STATE); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; - *pLen = sizeof(SK_PNP_CAPABILITIES); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; + case OID_PNP_ADD_WAKE_UP_PATTERN: + case OID_PNP_REMOVE_WAKE_UP_PATTERN: + if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) { - case OID_PNP_QUERY_POWER: - case OID_PNP_ENABLE_WAKE_UP: - if (*pLen < sizeof(SK_U32)) { + *pLen = sizeof(SK_PM_PACKET_PATTERN); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; + case OID_PNP_ENABLE_WAKE_UP: + if (*pLen < sizeof(SK_U32)) { - case OID_PNP_SET_POWER: - case OID_PNP_ADD_WAKE_UP_PATTERN: - case OID_PNP_REMOVE_WAKE_UP_PATTERN: - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, - SK_PNMI_ERR040MSG); - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } + *pLen = sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + } + + /* + * Perform action + */ + if (Action == SK_PNMI_GET) { /* * Get value @@ -7868,11 +7677,12 @@ case OID_PNP_QUERY_POWER: /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests - the miniport to indicate whether it can transition its NIC - to the low-power state. + the miniport to indicate whether it can transition its NIC + to the low-power state. A miniport driver must always return NDIS_STATUS_SUCCESS to a query of OID_PNP_QUERY_POWER. */ - RetCode = SK_PNMI_ERR_OK; + *pLen = sizeof(SK_DEVICE_POWER_STATE);; + RetCode = SK_PNMI_ERR_OK; break; /* NDIS handles these OIDs as write-only. @@ -7883,7 +7693,7 @@ case OID_PNP_ADD_WAKE_UP_PATTERN: case OID_PNP_REMOVE_WAKE_UP_PATTERN: *pLen = 0; - RetCode = SK_PNMI_ERR_OK; + RetCode = SK_PNMI_ERR_NOT_SUPPORTED; break; case OID_PNP_ENABLE_WAKE_UP: @@ -7895,41 +7705,9 @@ break; } - return (RetCode); + return (RetCode); } - /* - * From here SET or PRESET action. Check if the passed - * buffer length is plausible. - */ - switch (Id) { - case OID_PNP_SET_POWER: - case OID_PNP_ENABLE_WAKE_UP: - if (*pLen < sizeof(SK_U32)) { - - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - if (*pLen != sizeof(SK_U32)) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - break; - - case OID_PNP_ADD_WAKE_UP_PATTERN: - case OID_PNP_REMOVE_WAKE_UP_PATTERN: - if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - break; - - default: - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } /* * Perform preset or set @@ -7937,7 +7715,7 @@ /* POWER module does not support PRESET action */ if (Action == SK_PNMI_PRESET) { - return (SK_PNMI_ERR_OK); + return (SK_PNMI_ERR_OK); } switch (Id) { @@ -7958,13 +7736,210 @@ break; default: - RetCode = SK_PNMI_ERR_GENERAL; + RetCode = SK_PNMI_ERR_READ_ONLY; } return (RetCode); } #endif /* SK_POWER_MGMT */ +#ifdef SK_DIAG_SUPPORT +/***************************************************************************** + * + * DiagActions - OID handler function of Diagnostic driver + * + * Description: + * The code is simple. No description necessary. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ + +PNMI_STATIC int DiagActions( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* GET/PRESET/SET action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + + SK_U32 DiagStatus; + SK_U32 RetCode = SK_PNMI_ERR_GENERAL; + + /* + * Check instance. We only handle single instance variables. + */ + if (Instance != (SK_U32)(-1) && Instance != 1) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + + /* + * Check length. + */ + switch (Id) { + + case OID_SKGE_DIAG_MODE: + if (*pLen < sizeof(SK_U32)) { + + *pLen = sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG); + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + /* Perform action. */ + + /* GET value. */ + if (Action == SK_PNMI_GET) { + + switch (Id) { + + case OID_SKGE_DIAG_MODE: + DiagStatus = pAC->Pnmi.DiagAttached; + SK_PNMI_STORE_U32(pBuf, DiagStatus); + *pLen = sizeof(SK_U32); + RetCode = SK_PNMI_ERR_OK; + break; + + default: + *pLen = 0; + RetCode = SK_PNMI_ERR_GENERAL; + break; + } + return (RetCode); + } + + /* From here SET or PRESET value. */ + + /* PRESET value is not supported. */ + if (Action == SK_PNMI_PRESET) { + return (SK_PNMI_ERR_OK); + } + + /* SET value. */ + switch (Id) { + case OID_SKGE_DIAG_MODE: + + /* Handle the SET. */ + switch (*pBuf) { + + /* Attach the DIAG to this adapter. */ + case SK_DIAG_ATTACHED: + /* Check if we come from running */ + if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { + + RetCode = SkDrvLeaveDiagMode(pAC); + + } + else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) { + + RetCode = SK_PNMI_ERR_OK; + } + + else { + + RetCode = SK_PNMI_ERR_GENERAL; + + } + + if (RetCode == SK_PNMI_ERR_OK) { + + pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED; + } + break; + + /* Enter the DIAG mode in the driver. */ + case SK_DIAG_RUNNING: + RetCode = SK_PNMI_ERR_OK; + + /* + * If DiagAttached is set, we can tell the driver + * to enter the DIAG mode. + */ + if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) { + /* If DiagMode is not active, we can enter it. */ + if (!pAC->DiagModeActive) { + + RetCode = SkDrvEnterDiagMode(pAC); + } + else { + + RetCode = SK_PNMI_ERR_GENERAL; + } + } + else { + + RetCode = SK_PNMI_ERR_GENERAL; + } + + if (RetCode == SK_PNMI_ERR_OK) { + + pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING; + } + break; + + case SK_DIAG_IDLE: + /* Check if we come from running */ + if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { + + RetCode = SkDrvLeaveDiagMode(pAC); + + } + else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) { + + RetCode = SK_PNMI_ERR_OK; + } + + else { + + RetCode = SK_PNMI_ERR_GENERAL; + + } + + if (RetCode == SK_PNMI_ERR_OK) { + + pAC->Pnmi.DiagAttached = SK_DIAG_IDLE; + } + break; + + default: + RetCode = SK_PNMI_ERR_BAD_VALUE; + break; + } + break; + + default: + RetCode = SK_PNMI_ERR_GENERAL; + } + + if (RetCode == SK_PNMI_ERR_OK) { + *pLen = sizeof(SK_U32); + } + else { + + *pLen = 0; + } + return (RetCode); +} +#endif /* SK_DIAG_SUPPORT */ /***************************************************************************** * @@ -7980,7 +7955,7 @@ * the correct data (e.g. a 32bit value is * needed, but a 16 bit value was passed). * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port + * exist (e.g. port instance 3 on a two port * adapter). * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed. * @@ -7989,10 +7964,10 @@ PNMI_STATIC int Vct( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ -int Action, /* Get/PreSet/Set action */ +int Action, /* GET/PRESET/SET action */ SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer to which the mgmt data will be copied */ -unsigned int *pLen, /* On call: buffer length. On return: used buffer */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */ unsigned int TableIndex, /* Index to the Id table */ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ @@ -8004,7 +7979,6 @@ SK_U32 PhysPortIndex; SK_U32 Limit; SK_U32 Offset; - SK_BOOL Link; SK_U32 RetCode = SK_PNMI_ERR_GENERAL; int i; @@ -8037,7 +8011,8 @@ } Limit = PhysPortIndex + 1; } - else { /* + else { + /* * Instance == (SK_U32) (-1), get all Instances of that OID. * * Not implemented yet. May be used in future releases. @@ -8054,9 +8029,7 @@ Link = SK_FALSE; } - /* - * Check MAC type. - */ + /* Check MAC type */ if (pPrt->PhyType != SK_PHY_MARV_COPPER) { *pLen = 0; return (SK_PNMI_ERR_GENERAL); @@ -8065,13 +8038,9 @@ /* Initialize backup data pointer. */ pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex]; - /* - * Check action type. - */ + /* Check action type */ if (Action == SK_PNMI_GET) { - /* - * Check length. - */ + /* Check length */ switch (Id) { case OID_SKGE_VCT_GET: @@ -8093,14 +8062,12 @@ return (SK_PNMI_ERR_GENERAL); } - /* - * Get value. - */ + /* Get value */ Offset = 0; for (; PhysPortIndex < Limit; PhysPortIndex++) { switch (Id) { - case OID_SKGE_VCT_GET: + case OID_SKGE_VCT_GET: if ((Link == SK_FALSE) && (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) { RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE); @@ -8174,9 +8141,7 @@ * buffer length is plausible. */ - /* - * Check length. - */ + /* Check length */ switch (Id) { case OID_SKGE_VCT_SET: if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) { @@ -8257,7 +8222,6 @@ SK_GEPORT *pPrt; SK_PNMI_VCT *pVctData; SK_U32 RetCode; - SK_U8 LinkSpeedUsed; pPrt = &pAC->GIni.GP[PhysPortIndex]; @@ -8300,10 +8264,93 @@ } /* DSP only valid in 100/1000 modes. */ - LinkSpeedUsed = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed; - if (LinkSpeedUsed != SK_LSPEED_STAT_10MBPS) { + if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed != + SK_LSPEED_STAT_10MBPS) { pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA; } } - } /* CheckVctStatus */ + + +/***************************************************************************** + * + * SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed + * PNMI function depending on the subcommand and + * returns all data belonging to the complete database + * or OID request. + * + * Description: + * Looks up the requested subcommand, calls the corresponding handler + * function and passes all required parameters to it. + * The function is called by the driver. It is needed to handle the new + * generic PNMI IOCTL. This IOCTL is given to the driver and contains both + * the OID and a subcommand to decide what kind of request has to be done. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed + * SK_PNMI_ERR_GENERAL A general severe internal error occured + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take + * the data. + * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ +int SkPnmiGenIoctl( +SK_AC *pAC, /* Pointer to adapter context struct */ +SK_IOC IoC, /* I/O context */ +void *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* Length of buffer */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ +SK_I32 Mode; /* Store value of subcommand. */ +SK_U32 Oid; /* Store value of OID. */ +int ReturnCode; /* Store return value to show status of PNMI action. */ +int HeaderLength; /* Length of desired action plus OID. */ + + ReturnCode = SK_PNMI_ERR_GENERAL; + + SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32)); + SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32)); + HeaderLength = sizeof(SK_I32) + sizeof(SK_U32); + *pLen = *pLen - HeaderLength; + SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen); + + switch(Mode) { + case SK_GET_SINGLE_VAR: + ReturnCode = SkPnmiGetVar(pAC, IoC, Oid, + (char *) pBuf + sizeof(SK_I32), pLen, + ((SK_U32) (-1)), NetIndex); + SK_PNMI_STORE_U32(pBuf, ReturnCode); + *pLen = *pLen + sizeof(SK_I32); + break; + case SK_PRESET_SINGLE_VAR: + ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid, + (char *) pBuf + sizeof(SK_I32), pLen, + ((SK_U32) (-1)), NetIndex); + SK_PNMI_STORE_U32(pBuf, ReturnCode); + *pLen = *pLen + sizeof(SK_I32); + break; + case SK_SET_SINGLE_VAR: + ReturnCode = SkPnmiSetVar(pAC, IoC, Oid, + (char *) pBuf + sizeof(SK_I32), pLen, + ((SK_U32) (-1)), NetIndex); + SK_PNMI_STORE_U32(pBuf, ReturnCode); + *pLen = *pLen + sizeof(SK_I32); + break; + case SK_GET_FULL_MIB: + ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex); + break; + case SK_PRESET_FULL_MIB: + ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex); + break; + case SK_SET_FULL_MIB: + ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex); + break; + default: + break; + } + + return (ReturnCode); + +} /* SkGeIocGen */ Index: drivers/net/sk98lin/skgesirq.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/skgesirq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/skgesirq.c 22 Jul 2004 19:49:43 -0000 1.1 +++ drivers/net/sk98lin/skgesirq.c 4 Aug 2004 01:29:22 -0000 1.2 @@ -1,16 +1,15 @@ /****************************************************************************** * * Name: skgesirq.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:43 $ + * Project: Gigabit Ethernet Adapters, Common Modules * Purpose: Special IRQ module * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,317 +20,6 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: skgesirq.c,v $ - * Revision 1.1 2004/07/22 19:49:43 joff - * Initial revision - * - * Revision 1.81 2002/12/05 10:49:51 rschmidt - * Fixed missing Link Down Event for fiber (Bug Id #10768) - * Added reading of cable length when link is up - * Removed testing of unused error bits in PHY ISR - * Editorial changes. - * - * Revision 1.80 2002/11/12 17:15:21 rschmidt - * Replaced SkPnmiGetVar() by ...MacStatistic() in SkMacParity(). - * Editorial changes. - * - * Revision 1.79 2002/10/14 15:14:51 rschmidt - * Changed clearing of IS_M1_PAR_ERR (MAC 1 Parity Error) in - * SkMacParity() depending on GIChipRev (HW-Bug #8). - * Added error messages for GPHY Auto-Negotiation Error and - * FIFO Overflow/Underrun in SkPhyIsrGmac(). - * Editorial changes. - * - * Revision 1.78 2002/10/10 15:54:29 mkarl - * changes for PLinkSpeedUsed - * - * Revision 1.77 2002/09/12 08:58:51 rwahl - * Retrieve counters needed for XMAC errata workarounds directly because - * PNMI returns corrected counter values (e.g. #10620). - * - * Revision 1.76 2002/08/16 15:21:54 rschmidt - * Replaced all if(GIChipId == CHIP_ID_GENESIS) with new entry GIGenesis. - * Replaced wrong 1st para pAC with IoC in SK_IN/OUT macros. - * Editorial changes. - * - * Revision 1.75 2002/08/12 13:50:47 rschmidt - * Changed clearing of IS_M1_PAR_ERR (MAC 1 Parity Error) in - * SkMacParity() by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE (HW-Bug #8). - * Added clearing of IS_IRQ_TIST_OV and IS_IRQ_SENSOR in SkGeHwErr(). - * Corrected handling of Link Up and Auto-Negotiation Over for GPHY. - * in SkGePortCheckUpGmac(). - * Editorial changes. - * - * Revision 1.74 2002/08/08 16:17:04 rschmidt - * Added PhyType check for SK_HWEV_SET_ROLE event (copper only) - * Changed Link Up check reading PHY Specific Status (YUKON) - * Editorial changes - * - * Revision 1.73 2002/07/15 18:36:53 rwahl - * Editorial changes. - * - * Revision 1.72 2002/07/15 15:46:26 rschmidt - * Added new event: SK_HWEV_SET_SPEED - * Editorial changes - * - * Revision 1.71 2002/06/10 09:34:19 rschmidt - * Editorial changes - * - * Revision 1.70 2002/06/05 08:29:18 rschmidt - * SkXmRxTxEnable() replaced by SkMacRxTxEnable(). - * Editorial changes. - * - * Revision 1.69 2002/04/25 13:03:49 rschmidt - * Changes for handling YUKON. - * Use of #ifdef OTHER_PHY to eliminate code for unused Phy types. - * Replaced all XMAC-access macros by functions: SkMacRxTxDisable(), - * SkMacIrqDisable(). - * Added handling for GMAC FIFO in SkMacParity(). - * Replaced all SkXm...() functions with SkMac...() to handle also - * YUKON's GMAC. - * Macros for XMAC PHY access PHY_READ(), PHY_WRITE() replaced - * by functions SkXmPhyRead(), SkXmPhyWrite(). - * Disabling all PHY interrupts moved to SkMacIrqDisable(). - * Added handling for GPHY IRQ in SkGeSirqIsr(). - * Removed status parameter from MAC IRQ handler SkMacIrq(). - * Added SkGePortCheckUpGmac(), SkPhyIsrGmac() for GMAC. - * Editorial changes - * - * Revision 1.68 2002/02/26 15:24:53 rwahl - * Fix: no link with manual configuration (#10673). The previous fix for - * #10639 was removed. So for RLMT mode = CLS the RLMT may switch to - * misconfigured port. It should not occur for the other RLMT modes. - * - * Revision 1.67 2001/11/20 09:19:58 rwahl - * Reworked bugfix #10639 (no dependency to RLMT mode). - * - * Revision 1.66 2001/10/26 07:52:53 afischer - * Port switching bug in `check local link` mode - * - * Revision 1.65 2001/02/23 13:41:51 gklug - * fix: PHYS2INST should be used correctly for Dual Net operation - * chg: do no longer work with older PNMI - * - * Revision 1.64 2001/02/15 11:27:04 rassmann - * Working with RLMT v1 if SK_MAX_NETS undefined. - * - * Revision 1.63 2001/02/06 10:44:23 mkunz - * - NetIndex added to interface functions of pnmi V4 with dual net support - * - * Revision 1.62 2001/01/31 15:31:41 gklug - * fix: problem with autosensing an SR8800 switch - * - * Revision 1.61 2000/11/09 11:30:09 rassmann - * WA: Waiting after releasing reset until BCom chip is accessible. - * - * Revision 1.60 2000/10/18 12:37:48 cgoos - * Reinserted the comment for version 1.56. - * - * Revision 1.59 2000/10/18 12:22:20 cgoos - * Added workaround for half duplex hangup. - * - * Revision 1.58 2000/09/28 13:06:04 gklug - * fix: BCOM may NOT be touched if XMAC is in RESET state - * - * Revision 1.57 2000/09/08 12:38:39 cgoos - * Added forgotten variable declaration. - * - * Revision 1.56 2000/09/08 08:12:13 cgoos - * Changed handling of parity errors in SkGeHwErr (correct reset of error). - * - * Revision 1.55 2000/06/19 08:36:25 cgoos - * Changed comment. - * - * Revision 1.54 2000/05/22 08:45:57 malthoff - * Fix: #10523 is valid for all BCom PHYs. - * - * Revision 1.53 2000/05/19 10:20:30 cgoos - * Removed Solaris debug output code. - * - * Revision 1.52 2000/05/19 10:19:37 cgoos - * Added PHY state check in HWLinkDown. - * Move PHY interrupt code to IS_EXT_REG case in SkGeSirqIsr. - * - * Revision 1.51 2000/05/18 05:56:20 cgoos - * Fixed typo. - * - * Revision 1.50 2000/05/17 12:49:49 malthoff - * Fixes BCom link bugs (#10523). - * - * Revision 1.49 1999/12/17 11:02:50 gklug - * fix: read PHY_STAT of Broadcom chip more often to assure good status - * - * Revision 1.48 1999/12/06 10:01:17 cgoos - * Added SET function for Role. - * - * Revision 1.47 1999/11/22 13:34:24 cgoos - * Changed license header to GPL. - * - * Revision 1.46 1999/09/16 10:30:07 cgoos - * Removed debugging output statement from Linux. - * - * Revision 1.45 1999/09/16 07:32:55 cgoos - * Fixed dual-port copperfield bug (PHY_READ from resetted port). - * Removed some unused variables. - * - * Revision 1.44 1999/08/03 15:25:04 cgoos - * Removed workaround for disabled interrupts in half duplex mode. - * - * Revision 1.43 1999/08/03 14:27:58 cgoos - * Removed SENSE mode code from SkGePortCheckUpBcom. - * - * Revision 1.42 1999/07/26 09:16:54 cgoos - * Added some typecasts to avoid compiler warnings. - * - * Revision 1.41 1999/05/19 07:28:59 cgoos - * Changes for 1000Base-T. - * - * Revision 1.40 1999/04/08 13:59:39 gklug - * fix: problem with 3Com switches endless RESTARTs - * - * Revision 1.39 1999/03/08 10:10:52 gklug - * fix: AutoSensing did switch to next mode even if LiPa indicated offline - * - * Revision 1.38 1999/03/08 09:49:03 gklug - * fix: Bug using pAC instead of IoC, causing AIX problems - * fix: change compare for Linux compiler bug workaround - * - * Revision 1.37 1999/01/28 14:51:33 gklug - * fix: monitor for autosensing and extra RESETS the RX on wire counters - * - * Revision 1.36 1999/01/22 09:19:55 gklug - * fix: Init DupMode and InitPauseMd are now called in RxTxEnable - * - * Revision 1.35 1998/12/11 15:22:59 gklug - * chg: autosensing: check for receive if manual mode was guessed - * chg: simplified workaround for XMAC errata - * chg: wait additional 100 ms before link goes up. - * chg: autoneg timeout to 600 ms - * chg: restart autoneg even if configured to autonegotiation - * - * Revision 1.34 1998/12/10 10:33:14 gklug - * add: more debug messages - * fix: do a new InitPhy if link went down (AutoSensing problem) - * chg: Check for zero shorts if link is NOT up - * chg: reset Port if link goes down - * chg: wait additional 100 ms when link comes up to check shorts - * fix: dummy read extended autoneg status to prevent link going down immediately - * - * Revision 1.33 1998/12/07 12:18:29 gklug - * add: refinement of autosense mode: take into account the autoneg cap of LiPa - * - * Revision 1.32 1998/12/07 07:11:21 gklug - * fix: compiler warning - * - * Revision 1.31 1998/12/02 09:29:05 gklug - * fix: WA XMAC Errata: FCSCt check was not correct. - * fix: WA XMAC Errata: Prec Counter were NOT updated in case of short checks. - * fix: Clear Stat : now clears the Prev counters of all known Ports - * - * Revision 1.30 1998/12/01 10:54:15 gklug - * dd: workaround for XMAC errata changed. Check RX count and CRC err Count, too. - * - * Revision 1.29 1998/12/01 10:01:53 gklug - * fix: if MAC IRQ occurs during port down, this will be handled correctly - * - * Revision 1.28 1998/11/26 16:22:11 gklug - * fix: bug in autosense if manual modes are used - * - * Revision 1.27 1998/11/26 15:50:06 gklug - * fix: PNMI needs to set PLinkModeConf - * - * Revision 1.26 1998/11/26 14:51:58 gklug - * add: AutoSensing functionalty - * - * Revision 1.25 1998/11/26 07:34:37 gklug - * fix: Init PrevShorts when restarting port due to Link connection - * - * Revision 1.24 1998/11/25 10:57:32 gklug - * fix: remove unreferenced local vars - * - * Revision 1.23 1998/11/25 08:26:40 gklug - * fix: don't do a RESET on a starting or stopping port - * - * Revision 1.22 1998/11/24 13:29:44 gklug - * add: Workaround for MAC parity errata - * - * Revision 1.21 1998/11/18 15:31:06 gklug - * fix: lint bugs - * - * Revision 1.20 1998/11/18 12:58:54 gklug - * fix: use PNMI query instead of hardware access - * - * Revision 1.19 1998/11/18 12:54:55 gklug - * chg: add new workaround for XMAC Errata - * add: short event counter monitoring on active link too - * - * Revision 1.18 1998/11/13 14:27:41 malthoff - * Bug Fix: Packet Arbiter Timeout was not cleared correctly - * for timeout on TX1 and TX2. - * - * Revision 1.17 1998/11/04 07:01:59 cgoos - * Moved HW link poll sequence. - * Added call to SkXmRxTxEnable. - * - * Revision 1.16 1998/11/03 13:46:03 gklug - * add: functionality of SET_LMODE and SET_FLOW_MODE - * fix: send RLMT LinkDown event when Port stop is given with LinkUp - * - * Revision 1.15 1998/11/03 12:56:47 gklug - * fix: Needs more events - * - * Revision 1.14 1998/10/30 07:36:35 gklug - * rmv: unnecessary code - * - * Revision 1.13 1998/10/29 15:21:57 gklug - * add: Poll link feature for activating HW link - * fix: Deactivate HWLink when Port STOP is given - * - * Revision 1.12 1998/10/28 07:38:57 cgoos - * Checking link status at begin of SkHWLinkUp. - * - * Revision 1.11 1998/10/22 09:46:50 gklug - * fix SysKonnectFileId typo - * - * Revision 1.10 1998/10/14 13:57:47 gklug - * add: Port start/stop event - * - * Revision 1.9 1998/10/14 05:48:29 cgoos - * Added definition for Para. - * - * Revision 1.8 1998/10/14 05:40:09 gklug - * add: Hardware Linkup signal used - * - * Revision 1.7 1998/10/09 06:50:20 malthoff - * Remove ID_sccs by SysKonnectFileId. - * - * Revision 1.6 1998/10/08 09:11:49 gklug - * add: clear IRQ commands - * - * Revision 1.5 1998/10/02 14:27:35 cgoos - * Fixed some typos and wrong event names. - * - * Revision 1.4 1998/10/02 06:24:17 gklug - * add: HW error function - * fix: OUT macros - * - * Revision 1.3 1998/10/01 07:03:00 gklug - * add: ISR for the usual interrupt source register - * - * Revision 1.2 1998/09/03 13:50:33 gklug - * add: function prototypes - * - * Revision 1.1 1998/08/27 11:50:21 gklug - * initial revision - * - * - * - ******************************************************************************/ - /* * Special Interrupt handler * @@ -356,26 +44,35 @@ * */ +#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "$Id: skgesirq.c,v 1.1 2004/07/22 19:49:43 joff Exp $" ; + "@(#) $Id: skgesirq.c,v 1.2 2004/08/04 01:29:22 joff Exp $ (C) Marvell."; +#endif #include "h/skdrv1st.h" /* Driver Specific Definitions */ +#ifndef SK_SLIM #include "h/skgepnmi.h" /* PNMI Definitions */ #include "h/skrlmt.h" /* RLMT Definitions */ +#endif #include "h/skdrv2nd.h" /* Adapter Control and Driver specific Def. */ /* local function prototypes */ -static int SkGePortCheckUpXmac(SK_AC*, SK_IOC, int); -static int SkGePortCheckUpBcom(SK_AC*, SK_IOC, int); -static int SkGePortCheckUpGmac(SK_AC*, SK_IOC, int); +#ifdef GENESIS +static int SkGePortCheckUpXmac(SK_AC*, SK_IOC, int, SK_BOOL); +static int SkGePortCheckUpBcom(SK_AC*, SK_IOC, int, SK_BOOL); static void SkPhyIsrBcom(SK_AC*, SK_IOC, int, SK_U16); +#endif /* GENESIS */ +#ifdef YUKON +static int SkGePortCheckUpGmac(SK_AC*, SK_IOC, int, SK_BOOL); static void SkPhyIsrGmac(SK_AC*, SK_IOC, int, SK_U16); +#endif /* YUKON */ #ifdef OTHER_PHY -static int SkGePortCheckUpLone(SK_AC*, SK_IOC, int); -static int SkGePortCheckUpNat(SK_AC*, SK_IOC, int); +static int SkGePortCheckUpLone(SK_AC*, SK_IOC, int, SK_BOOL); +static int SkGePortCheckUpNat(SK_AC*, SK_IOC, int, SK_BOOL); static void SkPhyIsrLone(SK_AC*, SK_IOC, int, SK_U16); #endif /* OTHER_PHY */ +#ifdef GENESIS /* * array of Rx counter from XMAC which are checked * in AutoSense mode to check whether a link is not able to auto-negotiate. @@ -388,6 +85,7 @@ XM_RXF_1023B, XM_RXF_MAX_SZ } ; +#endif /* GENESIS */ #ifdef __C2MAN__ /* @@ -400,20 +98,13 @@ {} #endif -/* Define return codes of SkGePortCheckUp and CheckShort */ -#define SK_HW_PS_NONE 0 /* No action needed */ -#define SK_HW_PS_RESTART 1 /* Restart needed */ -#define SK_HW_PS_LINK 2 /* Link Up actions needed */ - /****************************************************************************** * * SkHWInitDefSense() - Default Autosensing mode initialization * - * Description: - * This function sets the PLinkMode for HWInit - * - * Note: + * Description: sets the PLinkMode for HWInit * + * Returns: N/A */ static void SkHWInitDefSense( SK_AC *pAC, /* adapter context */ @@ -435,23 +126,23 @@ ("AutoSensing: First mode %d on Port %d\n", (int)SK_LMODE_AUTOFULL, Port)); - pPrt->PLinkMode = SK_LMODE_AUTOFULL; + pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL; return; } /* SkHWInitDefSense */ +#ifdef GENESIS /****************************************************************************** * - * SkHWSenseGetNext() - GetNextAutosensing Mode + * SkHWSenseGetNext() - Get Next Autosensing Mode * - * Description: - * This function handles the AutoSensing + * Description: gets the appropriate next mode * * Note: * */ -SK_U8 SkHWSenseGetNext( +static SK_U8 SkHWSenseGetNext( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -462,18 +153,18 @@ pPrt->PAutoNegTimeOut = 0; - if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) { + if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) { /* Leave all as configured */ return(pPrt->PLinkModeConf); } - if (pPrt->PLinkMode == SK_LMODE_AUTOFULL) { + if (pPrt->PLinkMode == (SK_U8)SK_LMODE_AUTOFULL) { /* Return next mode AUTOBOTH */ - return(SK_LMODE_AUTOBOTH); + return ((SK_U8)SK_LMODE_AUTOBOTH); } /* Return default autofull */ - return(SK_LMODE_AUTOFULL); + return ((SK_U8)SK_LMODE_AUTOFULL); } /* SkHWSenseGetNext */ @@ -481,13 +172,11 @@ * * SkHWSenseSetNext() - Autosensing Set next mode * - * Description: - * This function sets the appropriate next mode. - * - * Note: + * Description: sets the appropriate next mode * + * Returns: N/A */ -void SkHWSenseSetNext( +static void SkHWSenseSetNext( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port, /* Port Index (MAC_1 + n) */ @@ -499,7 +188,7 @@ pPrt->PAutoNegTimeOut = 0; - if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) { + if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) { return; } @@ -511,17 +200,16 @@ return; } /* SkHWSenseSetNext */ +#endif /* GENESIS */ /****************************************************************************** * * SkHWLinkDown() - Link Down handling * - * Description: - * This function handles the Hardware link down signal - * - * Note: + * Description: handles the hardware link down signal * + * Returns: N/A */ void SkHWLinkDown( SK_AC *pAC, /* adapter context */ @@ -541,7 +229,7 @@ /* Init default sense mode */ SkHWInitDefSense(pAC, IoC, Port); - if (!pPrt->PHWLinkUp) { + if (pPrt->PHWLinkUp == SK_FALSE) { return; } @@ -552,9 +240,9 @@ pPrt->PHWLinkUp = SK_FALSE; /* Reset Port stati */ - pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN; - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; - pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_INDETERMINATED; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; + pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE; + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_INDETERMINATED; /* Re-init Phy especially when the AutoSense default is set now */ SkMacInitPhy(pAC, IoC, Port, SK_FALSE); @@ -571,11 +259,9 @@ * * SkHWLinkUp() - Link Up handling * - * Description: - * This function handles the Hardware link up signal - * - * Note: + * Description: handles the hardware link up signal * + * Returns: N/A */ void SkHWLinkUp( SK_AC *pAC, /* adapter context */ @@ -593,39 +279,52 @@ pPrt->PHWLinkUp = SK_TRUE; pPrt->PAutoNegFail = SK_FALSE; - pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; - if (pPrt->PLinkMode != SK_LMODE_AUTOHALF && - pPrt->PLinkMode != SK_LMODE_AUTOFULL && - pPrt->PLinkMode != SK_LMODE_AUTOBOTH) { + if (pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOHALF && + pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOFULL && + pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOBOTH) { /* Link is up and no Auto-negotiation should be done */ - /* Configure Port */ - - /* link speed should be the configured one */ - pPrt->PLinkSpeedUsed = pPrt->PLinkSpeed; + /* Link speed should be the configured one */ + switch (pPrt->PLinkSpeed) { + case SK_LSPEED_AUTO: + /* default is 1000 Mbps */ + case SK_LSPEED_1000MBPS: + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; + break; + case SK_LSPEED_100MBPS: + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS; + break; + case SK_LSPEED_10MBPS: + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS; + break; + } /* Set Link Mode Status */ if (pPrt->PLinkMode == SK_LMODE_FULL) { - pPrt->PLinkModeStatus = SK_LMODE_STAT_FULL; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_FULL; } else { - pPrt->PLinkModeStatus = SK_LMODE_STAT_HALF; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_HALF; } /* No flow control without auto-negotiation */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; + pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE; /* enable Rx/Tx */ - SkMacRxTxEnable(pAC, IoC, Port); + (void)SkMacRxTxEnable(pAC, IoC, Port); } } /* SkHWLinkUp */ /****************************************************************************** * - * SkMacParity - does everything to handle MAC parity errors correctly + * SkMacParity() - MAC parity workaround * + * Description: handles MAC parity errors correctly + * + * Returns: N/A */ static void SkMacParity( SK_AC *pAC, /* adapter context */ @@ -634,21 +333,29 @@ { SK_EVPARA Para; SK_GEPORT *pPrt; /* GIni Port struct pointer */ - SK_U32 TxMax; /* TxMax Counter */ + SK_U32 TxMax; /* Tx Max Size Counter */ pPrt = &pAC->GIni.GP[Port]; /* Clear IRQ Tx Parity Error */ +#ifdef GENESIS if (pAC->GIni.GIGenesis) { + SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_PERR); } - else { +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */ SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), - (SK_U8)((pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE)); + (SK_U8)((pAC->GIni.GIChipId == CHIP_ID_YUKON && + pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE)); } - +#endif /* YUKON */ + if (pPrt->PCheckPar) { + if (Port == MAC_1) { SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E016, SKERR_SIRQ_E016MSG); } @@ -657,6 +364,7 @@ } Para.Para64 = Port; SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); + Para.Para32[0] = Port; SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); @@ -664,15 +372,21 @@ } /* Check whether frames with a size of 1k were sent */ +#ifdef GENESIS if (pAC->GIni.GIGenesis) { /* Snap statistic counters */ (void)SkXmUpdateStats(pAC, IoC, Port); (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXF_MAX_SZ, &TxMax); } - else { +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { + (void)SkGmMacStatistic(pAC, IoC, Port, GM_TXF_1518B, &TxMax); } +#endif /* YUKON */ if (TxMax > 0) { /* From now on check the parity */ @@ -683,11 +397,11 @@ /****************************************************************************** * - * Hardware Error service routine + * SkGeHwErr() - Hardware Error service routine * - * Description: + * Description: handles all HW Error interrupts * - * Notes: + * Returns: N/A */ static void SkGeHwErr( SK_AC *pAC, /* adapter context */ @@ -710,50 +424,62 @@ SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); - SK_OUT16(IoC, PCI_C(PCI_STATUS), Word | PCI_ERRBITS); + SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS)); SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); Para.Para64 = 0; SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para); } +#ifdef GENESIS if (pAC->GIni.GIGenesis) { + if ((HwStatus & IS_NO_STAT_M1) != 0) { /* Ignore it */ /* This situation is also indicated in the descriptor */ SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INSTAT); } - + if ((HwStatus & IS_NO_STAT_M2) != 0) { /* Ignore it */ /* This situation is also indicated in the descriptor */ SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INSTAT); } - + if ((HwStatus & IS_NO_TIST_M1) != 0) { /* Ignore it */ /* This situation is also indicated in the descriptor */ SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INTIST); } - + if ((HwStatus & IS_NO_TIST_M2) != 0) { /* Ignore it */ /* This situation is also indicated in the descriptor */ SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INTIST); } } - else { /* YUKON */ +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { /* This is necessary only for Rx timing measurements */ if ((HwStatus & IS_IRQ_TIST_OV) != 0) { + /* increment Time Stamp Timer counter (high) */ + pAC->GIni.GITimeStampCnt++; + /* Clear Time Stamp Timer IRQ */ SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_CLR_IRQ); } if ((HwStatus & IS_IRQ_SENSOR) != 0) { - /* Clear I2C IRQ */ - SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); + /* no sensors on 32-bit Yukon */ + if (pAC->GIni.GIYukon32Bit) { + /* disable HW Error IRQ */ + pAC->GIni.GIValIrqMask &= ~IS_HW_ERR; + } } } +#endif /* YUKON */ if ((HwStatus & IS_RAM_RD_PAR) != 0) { SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR); @@ -784,6 +510,7 @@ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG); Para.Para64 = MAC_1; SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); + Para.Para32[0] = MAC_1; SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); } @@ -795,6 +522,7 @@ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG); Para.Para64 = MAC_2; SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); + Para.Para32[0] = MAC_2; SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); } @@ -803,11 +531,11 @@ /****************************************************************************** * - * Interrupt service routine + * SkGeSirqIsr() - Special Interrupt Service Routine * - * Description: + * Description: handles all non data transfer specific interrupts (slow path) * - * Notes: + * Returns: N/A */ void SkGeSirqIsr( SK_AC *pAC, /* adapter context */ @@ -817,13 +545,10 @@ SK_EVPARA Para; SK_U32 RegVal32; /* Read register value */ SK_GEPORT *pPrt; /* GIni Port struct pointer */ - unsigned Len; - SK_U64 Octets; SK_U16 PhyInt; - SK_U16 PhyIMsk; int i; - if ((Istatus & IS_HW_ERR) != 0) { + if (((Istatus & IS_HW_ERR) & pAC->GIni.GIValIrqMask) != 0) { /* read the HW Error Interrupt source */ SK_IN32(IoC, B0_HWE_ISRC, &RegVal32); @@ -869,32 +594,47 @@ /* May be a normal situation in a server with a slow network */ SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1); - /* - * workaround: if in half duplex mode, check for Tx hangup. - * Read number of TX'ed bytes, wait for 10 ms, then compare - * the number with current value. If nothing changed, we assume - * that Tx is hanging and do a FIFO flush (see event routine). - */ - if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || - pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) && - !pPrt->HalfDupTimerActive) { +#ifdef GENESIS + if (pAC->GIni.GIGenesis) { /* - * many more pack. arb. timeouts may come in between, - * we ignore those + * workaround: if in half duplex mode, check for Tx hangup. + * Read number of TX'ed bytes, wait for 10 ms, then compare + * the number with current value. If nothing changed, we assume + * that Tx is hanging and do a FIFO flush (see event routine). */ - pPrt->HalfDupTimerActive = SK_TRUE; + if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || + pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) && + !pPrt->HalfDupTimerActive) { + /* + * many more pack. arb. timeouts may come in between, + * we ignore those + */ + pPrt->HalfDupTimerActive = SK_TRUE; +#ifdef XXX + Len = sizeof(SK_U64); + SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, + &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, 0), + pAC->Rlmt.Port[0].Net->NetNumber); + + pPrt->LastOctets = Octets; +#endif /* XXX */ + /* Snap statistic counters */ + (void)SkXmUpdateStats(pAC, IoC, 0); - Len = sizeof(SK_U64); - SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, - &Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(pAC, 0), - pAC->Rlmt.Port[0].Net->NetNumber); - - pPrt->LastOctets = Octets; - - Para.Para32[0] = 0; - SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME, - SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para); + (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_HI, &RegVal32); + + pPrt->LastOctets = (SK_U64)RegVal32 << 32; + + (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_LO, &RegVal32); + + pPrt->LastOctets += RegVal32; + + Para.Para32[0] = 0; + SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME, + SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para); + } } +#endif /* GENESIS */ } if ((Istatus & IS_PA_TO_TX2) != 0) { @@ -904,23 +644,38 @@ /* May be a normal situation in a server with a slow network */ SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2); - /* workaround: see above */ - if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || - pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) && - !pPrt->HalfDupTimerActive) { - pPrt->HalfDupTimerActive = SK_TRUE; - - Len = sizeof(SK_U64); - SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, - &Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(pAC, 1), - pAC->Rlmt.Port[1].Net->NetNumber); - - pPrt->LastOctets = Octets; - - Para.Para32[0] = 1; - SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME, - SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para); +#ifdef GENESIS + if (pAC->GIni.GIGenesis) { + /* workaround: see above */ + if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || + pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) && + !pPrt->HalfDupTimerActive) { + pPrt->HalfDupTimerActive = SK_TRUE; +#ifdef XXX + Len = sizeof(SK_U64); + SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, + &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, 1), + pAC->Rlmt.Port[1].Net->NetNumber); + + pPrt->LastOctets = Octets; +#endif /* XXX */ + /* Snap statistic counters */ + (void)SkXmUpdateStats(pAC, IoC, 1); + + (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_HI, &RegVal32); + + pPrt->LastOctets = (SK_U64)RegVal32 << 32; + + (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_LO, &RegVal32); + + pPrt->LastOctets += RegVal32; + + Para.Para32[0] = 1; + SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME, + SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para); + } } +#endif /* GENESIS */ } /* Check interrupts of the particular queues */ @@ -1001,59 +756,69 @@ continue; } - switch (pPrt->PhyType) { - - case SK_PHY_XMAC: - break; - - case SK_PHY_BCOM: - SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt); - SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_MASK, &PhyIMsk); - - if ((PhyInt & ~PhyIMsk) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("Port %d Bcom Int: 0x%04X Mask: 0x%04X\n", - i, PhyInt, PhyIMsk)); - SkPhyIsrBcom(pAC, IoC, i, PhyInt); +#ifdef GENESIS + if (pAC->GIni.GIGenesis) { + + switch (pPrt->PhyType) { + + case SK_PHY_XMAC: + break; + + case SK_PHY_BCOM: + SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt); + + if ((PhyInt & ~PHY_B_DEF_MSK) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("Port %d Bcom Int: 0x%04X\n", + i, PhyInt)); + SkPhyIsrBcom(pAC, IoC, i, PhyInt); + } + break; +#ifdef OTHER_PHY + case SK_PHY_LONE: + SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt); + + if ((PhyInt & PHY_L_DEF_MSK) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("Port %d Lone Int: %x\n", + i, PhyInt)); + SkPhyIsrLone(pAC, IoC, i, PhyInt); + } + break; +#endif /* OTHER_PHY */ } - break; - - case SK_PHY_MARV_COPPER: - case SK_PHY_MARV_FIBER: + } +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { + /* Read PHY Interrupt Status */ SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_STAT, &PhyInt); - SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_MASK, &PhyIMsk); - if ((PhyInt & PhyIMsk) != 0) { + if ((PhyInt & PHY_M_DEF_MSK) != 0) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("Port %d Marv Int: 0x%04X Mask: 0x%04X\n", - i, PhyInt, PhyIMsk)); + ("Port %d Marv Int: 0x%04X\n", + i, PhyInt)); SkPhyIsrGmac(pAC, IoC, i, PhyInt); } - break; - -#ifdef OTHER_PHY - case SK_PHY_LONE: - SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt); - SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_ENAB, &PhyIMsk); - - if ((PhyInt & PhyIMsk) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("Port %d Lone Int: %x Mask: %x\n", - i, PhyInt, PhyIMsk)); - SkPhyIsrLone(pAC, IoC, i, PhyInt); - } - break; - case SK_PHY_NAT: - /* todo: National */ - break; -#endif /* OTHER_PHY */ } +#endif /* YUKON */ } } /* I2C Ready interrupt */ if ((Istatus & IS_I2C_READY) != 0) { +#ifdef SK_SLIM + SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); +#else SkI2cIsr(pAC, IoC); +#endif + } + + /* SW forced interrupt */ + if ((Istatus & IS_IRQ_SW) != 0) { + /* clear the software IRQ */ + SK_OUT8(IoC, B0_CTST, CS_CL_SW_IRQ); } if ((Istatus & IS_LNK_SYNC_M1) != 0) { @@ -1088,20 +853,30 @@ /* Timer interrupt (served last) */ if ((Istatus & IS_TIMINT) != 0) { + /* check for HW Errors */ + if (((Istatus & IS_HW_ERR) & ~pAC->GIni.GIValIrqMask) != 0) { + /* read the HW Error Interrupt source */ + SK_IN32(IoC, B0_HWE_ISRC, &RegVal32); + + SkGeHwErr(pAC, IoC, RegVal32); + } + SkHwtIsr(pAC, IoC); } + } /* SkGeSirqIsr */ +#ifdef GENESIS /****************************************************************************** * - * SkGePortCheckShorts - Implementing XMAC Workaround Errata # 2 + * SkGePortCheckShorts() - Implementing XMAC Workaround Errata # 2 * * return: * 0 o.k. nothing needed * 1 Restart needed on this port */ -static int SkGePortCheckShorts( +static int SkGePortCheckShorts( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* IO Context */ int Port) /* Which port should be checked */ @@ -1126,13 +901,15 @@ (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts); /* - * Read Rx counter (packets seen on the network and not necessarily + * Read Rx counters (packets seen on the network and not necessarily * really received. */ RxCts = 0; for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) { + (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp); + RxCts += (SK_U64)RxTmp; } @@ -1202,44 +979,76 @@ return(Rtv); } /* SkGePortCheckShorts */ +#endif /* GENESIS */ /****************************************************************************** * - * SkGePortCheckUp - Implementation of the Workaround for Errata #2 + * SkGePortCheckUp() - Check if the link is up * * return: * 0 o.k. nothing needed * 1 Restart needed on this port * 2 Link came up */ -static int SkGePortCheckUp( +static int SkGePortCheckUp( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* IO Context */ int Port) /* Which port should be checked */ { - switch (pAC->GIni.GP[Port].PhyType) { - case SK_PHY_XMAC: - return(SkGePortCheckUpXmac(pAC, IoC, Port)); - case SK_PHY_BCOM: - return(SkGePortCheckUpBcom(pAC, IoC, Port)); - case SK_PHY_MARV_COPPER: - case SK_PHY_MARV_FIBER: - return(SkGePortCheckUpGmac(pAC, IoC, Port)); + SK_GEPORT *pPrt; /* GIni Port struct pointer */ + SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */ + int Rtv; /* Return value */ + + Rtv = SK_HW_PS_NONE; + + pPrt = &pAC->GIni.GP[Port]; + + if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { + AutoNeg = SK_FALSE; + } + else { + AutoNeg = SK_TRUE; + } + +#ifdef GENESIS + if (pAC->GIni.GIGenesis) { + + switch (pPrt->PhyType) { + + case SK_PHY_XMAC: + Rtv = SkGePortCheckUpXmac(pAC, IoC, Port, AutoNeg); + break; + case SK_PHY_BCOM: + Rtv = SkGePortCheckUpBcom(pAC, IoC, Port, AutoNeg); + break; #ifdef OTHER_PHY - case SK_PHY_LONE: - return(SkGePortCheckUpLone(pAC, IoC, Port)); - case SK_PHY_NAT: - return(SkGePortCheckUpNat(pAC, IoC, Port)); + case SK_PHY_LONE: + Rtv = SkGePortCheckUpLone(pAC, IoC, Port, AutoNeg); + break; + case SK_PHY_NAT: + Rtv = SkGePortCheckUpNat(pAC, IoC, Port, AutoNeg); + break; #endif /* OTHER_PHY */ + } } - return(SK_HW_PS_NONE); +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { + + Rtv = SkGePortCheckUpGmac(pAC, IoC, Port, AutoNeg); + } +#endif /* YUKON */ + + return(Rtv); } /* SkGePortCheckUp */ +#ifdef GENESIS /****************************************************************************** * - * SkGePortCheckUpXmac - Implementing of the Workaround Errata # 2 + * SkGePortCheckUpXmac() - Implementing of the Workaround Errata # 2 * * return: * 0 o.k. nothing needed @@ -1249,7 +1058,8 @@ static int SkGePortCheckUpXmac( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* IO Context */ -int Port) /* Which port should be checked */ +int Port, /* Which port should be checked */ +SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ { SK_U32 Shorts; /* Short Event Counter */ SK_GEPORT *pPrt; /* GIni Port struct pointer */ @@ -1260,7 +1070,6 @@ SK_U16 LpAb; /* Link Partner Ability */ SK_U16 ResAb; /* Resolved Ability */ SK_U16 ExtStat; /* Extended Status Register */ - SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */ SK_U8 NextMode; /* Next AutoSensing Mode */ pPrt = &pAC->GIni.GP[Port]; @@ -1278,13 +1087,6 @@ pPrt->PIsave = 0; /* Now wait for each port's link */ - if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { - AutoNeg = SK_FALSE; - } - else { - AutoNeg = SK_TRUE; - } - if (pPrt->PLinkBroken) { /* Link was broken */ XM_IN32(IoC, Port, XM_GP_PORT, &GpReg); @@ -1294,6 +1096,7 @@ XM_IN16(IoC, Port, XM_ISRC, &Isrc); IsrcSum |= Isrc; SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum); + if ((Isrc & XM_IS_INP_ASS) == 0) { /* It has been in sync since last time */ /* Restart the PORT */ @@ -1332,7 +1135,7 @@ ("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum)); } else { - pPrt->PIsave = IsrcSum & XM_IS_AND; + pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum)); @@ -1373,6 +1176,7 @@ } else { SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc); + if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) { return(SK_HW_PS_RESTART); } @@ -1392,7 +1196,7 @@ if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) { if ((GpReg & XM_GP_INP_ASS) == 0) { /* Save Auto-negotiation Done interrupt only if link is in sync */ - pPrt->PIsave = IsrcSum & XM_IS_AND; + pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND); } #ifdef DEBUG if ((pPrt->PIsave & XM_IS_AND) != 0) { @@ -1430,8 +1234,7 @@ * (clear Page Received bit if set) */ SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg done Port %d\n", Port)); + return(SK_HW_PS_LINK); } @@ -1500,7 +1303,7 @@ /****************************************************************************** * - * SkGePortCheckUpBcom - Check, if the link is up + * SkGePortCheckUpBcom() - Check if the link is up on Bcom PHY * * return: * 0 o.k. nothing needed @@ -1508,9 +1311,10 @@ * 2 Link came up */ static int SkGePortCheckUpBcom( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO Context */ -int Port) /* Which port should be checked */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* IO Context */ +int Port, /* Which port should be checked */ +SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ { SK_GEPORT *pPrt; /* GIni Port struct pointer */ int Done; @@ -1522,7 +1326,6 @@ SK_U16 LpAb; SK_U16 ExtStat; #endif /* DEBUG */ - SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */ pPrt = &pAC->GIni.GP[Port]; @@ -1599,7 +1402,7 @@ if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) { /* - * Workaround BCOM Errata: + * Workaround BCom Errata: * enable and disable loopback mode if "NO HCD" occurs. */ SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Ctrl); @@ -1692,14 +1495,6 @@ } #endif /* DEBUG */ - /* Now wait for each port's link */ - if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { - AutoNeg = SK_FALSE; - } - else { - AutoNeg = SK_TRUE; - } - /* * Here we usually can check whether the link is in sync and * auto-negotiation is done. @@ -1710,7 +1505,7 @@ SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat)); + ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat)); SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb); @@ -1718,6 +1513,7 @@ /* Error */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("Master/Slave Fault port %d\n", Port)); + pPrt->PAutoNegFail = SK_TRUE; pPrt->PMSStatus = SK_MS_STAT_FAULT; @@ -1732,12 +1528,15 @@ SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat)); + ("Port %d, ResAb: 0x%04X\n", Port, ResAb)); if (AutoNeg) { if ((PhyStat & PHY_ST_AN_OVER) != 0) { + SkHWLinkUp(pAC, IoC, Port); + Done = SkMacAutoNegDone(pAC, IoC, Port); + if (Done != SK_AND_OK) { #ifdef DEBUG /* Get PHY parameters, for debugging only */ @@ -1763,9 +1562,6 @@ (void *)NULL); } #endif /* DEBUG */ - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg done Port %d\n", Port)); return(SK_HW_PS_LINK); } } @@ -1796,16 +1592,19 @@ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Link sync(GP), Port %d\n", Port)); SkHWLinkUp(pAC, IoC, Port); + return(SK_HW_PS_LINK); } return(SK_HW_PS_NONE); } /* SkGePortCheckUpBcom */ +#endif /* GENESIS */ +#ifdef YUKON /****************************************************************************** * - * SkGePortCheckUpGmac - Check, if the link is up + * SkGePortCheckUpGmac() - Check if the link is up on Marvell PHY * * return: * 0 o.k. nothing needed @@ -1813,44 +1612,46 @@ * 2 Link came up */ static int SkGePortCheckUpGmac( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO Context */ -int Port) /* Which port should be checked */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* IO Context */ +int Port, /* Which port should be checked */ +SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ { SK_GEPORT *pPrt; /* GIni Port struct pointer */ int Done; - SK_U16 Isrc; /* Interrupt source */ - SK_U16 PhyStat; /* Phy Status */ - SK_U16 PhySpecStat;/* Phy Specific Status */ + SK_U16 PhyIsrc; /* PHY Interrupt source */ + SK_U16 PhyStat; /* PPY Status */ + SK_U16 PhySpecStat;/* PHY Specific Status */ SK_U16 ResAb; /* Master/Slave resolution */ - SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */ + SK_EVPARA Para; +#ifdef DEBUG + SK_U16 Word; /* I/O helper */ +#endif /* DEBUG */ pPrt = &pAC->GIni.GP[Port]; - /* Read PHY Interrupt Status */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &Isrc); - - if ((Isrc & PHY_M_IS_AN_COMPL) != 0) { - /* TBD */ - } - if (pPrt->PHWLinkUp) { return(SK_HW_PS_NONE); } - /* Now wait for each port's link */ - if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { - AutoNeg = SK_FALSE; - } - else { - AutoNeg = SK_TRUE; - } - /* Read PHY Status */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat)); + ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat)); + + /* Read PHY Interrupt Status */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyIsrc); + + if ((PhyIsrc & PHY_M_IS_AN_COMPL) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Auto-Negotiation Completed, PhyIsrc: 0x%04X\n", PhyIsrc)); + } + + if ((PhyIsrc & PHY_M_IS_LSP_CHANGE) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Link Speed Changed, PhyIsrc: 0x%04X\n", PhyIsrc)); + } SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); @@ -1860,6 +1661,7 @@ /* Error */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("Master/Slave Fault port %d\n", Port)); + pPrt->PAutoNegFail = SK_TRUE; pPrt->PMSStatus = SK_MS_STAT_FAULT; @@ -1870,12 +1672,37 @@ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg: %d, PhySpecStat: 0x%04x\n", AutoNeg, PhySpecStat)); + ("Phy1000BT: 0x%04X, PhySpecStat: 0x%04X\n", ResAb, PhySpecStat)); + +#ifdef DEBUG + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_EXP, &Word); + + if ((PhyIsrc & PHY_M_IS_AN_PR) != 0 || (Word & PHY_ANE_RX_PG) != 0 || + (PhySpecStat & PHY_M_PS_PAGE_REC) != 0) { + /* Read PHY Next Page Link Partner */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_NEPG_LP, &Word); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Page Received, NextPage: 0x%04X\n", Word)); + } +#endif /* DEBUG */ if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) { return(SK_HW_PS_NONE); } + if ((PhySpecStat & PHY_M_PS_DOWNS_STAT) != 0 || + (PhyIsrc & PHY_M_IS_DOWNSH_DET) != 0) { + /* Downshift detected */ + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E025, SKERR_SIRQ_E025MSG); + + Para.Para64 = Port; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_DOWNSHIFT_DET, Para); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Downshift detected, PhyIsrc: 0x%04X\n", PhyIsrc)); + } + pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; @@ -1893,8 +1720,6 @@ return(SK_HW_PS_RESTART); } - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg done Port %d\n", Port)); return(SK_HW_PS_LINK); } } @@ -1916,12 +1741,13 @@ return(SK_HW_PS_NONE); } /* SkGePortCheckUpGmac */ +#endif /* YUKON */ #ifdef OTHER_PHY /****************************************************************************** * - * SkGePortCheckUpLone - Check if the link is up + * SkGePortCheckUpLone() - Check if the link is up on Level One PHY * * return: * 0 o.k. nothing needed @@ -1931,7 +1757,8 @@ static int SkGePortCheckUpLone( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* IO Context */ -int Port) /* Which port should be checked */ +int Port, /* Which port should be checked */ +SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ { SK_GEPORT *pPrt; /* GIni Port struct pointer */ int Done; @@ -1940,7 +1767,6 @@ SK_U16 ExtStat; /* Extended Status Register */ SK_U16 PhyStat; /* Phy Status Register */ SK_U16 StatSum; - SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */ SK_U8 NextMode; /* Next AutoSensing Mode */ pPrt = &pAC->GIni.GP[Port]; @@ -1952,14 +1778,6 @@ StatSum = pPrt->PIsave; pPrt->PIsave = 0; - /* Now wait for each ports link */ - if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { - AutoNeg = SK_FALSE; - } - else { - AutoNeg = SK_TRUE; - } - /* * here we usually can check whether the link is in sync and * auto-negotiation is done. @@ -2010,8 +1828,6 @@ * extra link down/ups */ SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg done Port %d\n", Port)); return(SK_HW_PS_LINK); } } @@ -2052,6 +1868,7 @@ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Link sync(GP), Port %d\n", Port)); SkHWLinkUp(pAC, IoC, Port); + return(SK_HW_PS_LINK); } @@ -2061,7 +1878,7 @@ /****************************************************************************** * - * SkGePortCheckUpNat - Check if the link is up + * SkGePortCheckUpNat() - Check if the link is up on National PHY * * return: * 0 o.k. nothing needed @@ -2071,7 +1888,8 @@ static int SkGePortCheckUpNat( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* IO Context */ -int Port) /* Which port should be checked */ +int Port, /* Which port should be checked */ +SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ { /* todo: National */ return(SK_HW_PS_NONE); @@ -2081,7 +1899,7 @@ /****************************************************************************** * - * Event service routine + * SkGeSirqEvent() - Event Service Routine * * Description: * @@ -2093,29 +1911,34 @@ SK_U32 Event, /* Module specific Event */ SK_EVPARA Para) /* Event specific Parameter */ { - SK_U64 Octets; SK_GEPORT *pPrt; /* GIni Port struct pointer */ SK_U32 Port; - SK_U32 Time; - unsigned Len; + SK_U32 Val32; int PortStat; SK_U8 Val8; +#ifdef GENESIS + SK_U64 Octets; +#endif /* GENESIS */ Port = Para.Para32[0]; pPrt = &pAC->GIni.GP[Port]; switch (Event) { case SK_HWEV_WATIM: - /* Check whether port came up */ - PortStat = SkGePortCheckUp(pAC, IoC, Port); + if (pPrt->PState == SK_PRT_RESET) { + + PortStat = SK_HW_PS_NONE; + } + else { + /* Check whether port came up */ + PortStat = SkGePortCheckUp(pAC, IoC, (int)Port); + } switch (PortStat) { case SK_HW_PS_RESTART: if (pPrt->PHWLinkUp) { - /* - * Set Link to down. - */ - SkHWLinkDown(pAC, IoC, Port); + /* Set Link to down */ + SkHWLinkDown(pAC, IoC, (int)Port); /* * Signal directly to RLMT to ensure correct @@ -2132,20 +1955,19 @@ /* Signal to RLMT */ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_UP, Para); break; - } /* Start again the check Timer */ if (pPrt->PHWLinkUp) { - Time = SK_WA_ACT_TIME; + Val32 = SK_WA_ACT_TIME; } else { - Time = SK_WA_INA_TIME; + Val32 = SK_WA_INA_TIME; } /* Todo: still needed for non-XMAC PHYs??? */ /* Start workaround Errata #2 timer */ - SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Time, + SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Val32, SKGE_HWAC, SK_HWEV_WATIM, Para); break; @@ -2158,7 +1980,7 @@ SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para); } - SkHWLinkDown(pAC, IoC, Port); + SkHWLinkDown(pAC, IoC, (int)Port); /* Schedule Port RESET */ SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para); @@ -2180,7 +2002,7 @@ /* Stop Workaround Timer */ SkTimerStop(pAC, IoC, &pPrt->PWaTimer); - SkHWLinkDown(pAC, IoC, Port); + SkHWLinkDown(pAC, IoC, (int)Port); break; case SK_HWEV_UPDATE_STAT: @@ -2227,7 +2049,7 @@ } Val8 = (SK_U8)Para.Para32[1]; if (pPrt->PMSMode != Val8) { - /* Set New link mode */ + /* Set New Role (Master/Slave) mode */ pPrt->PMSMode = Val8; /* Restart Port */ @@ -2251,26 +2073,41 @@ } break; +#ifdef GENESIS case SK_HWEV_HALFDUP_CHK: - /* - * half duplex hangup workaround. - * See packet arbiter timeout interrupt for description - */ - pPrt->HalfDupTimerActive = SK_FALSE; - if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || - pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) { - - Len = sizeof(SK_U64); - SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, - &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port), - pAC->Rlmt.Port[Port].Net->NetNumber); - - if (pPrt->LastOctets == Octets) { - /* Tx hanging, a FIFO flush restarts it */ - SkMacFlushTxFifo(pAC, IoC, Port); + if (pAC->GIni.GIGenesis) { + /* + * half duplex hangup workaround. + * See packet arbiter timeout interrupt for description + */ + pPrt->HalfDupTimerActive = SK_FALSE; + if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || + pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) { +#ifdef XXX + Len = sizeof(SK_U64); + SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, + &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port), + pAC->Rlmt.Port[Port].Net->NetNumber); +#endif /* XXX */ + /* Snap statistic counters */ + (void)SkXmUpdateStats(pAC, IoC, Port); + + (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_HI, &Val32); + + Octets = (SK_U64)Val32 << 32; + + (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_LO, &Val32); + + Octets += Val32; + + if (pPrt->LastOctets == Octets) { + /* Tx hanging, a FIFO flush restarts it */ + SkMacFlushTxFifo(pAC, IoC, Port); + } } } break; +#endif /* GENESIS */ default: SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG); @@ -2281,11 +2118,12 @@ } /* SkGeSirqEvent */ +#ifdef GENESIS /****************************************************************************** * - * SkPhyIsrBcom - PHY interrupt service routine + * SkPhyIsrBcom() - PHY interrupt service routine * - * Description: handle all interrupts from BCOM PHY + * Description: handles all interrupts from BCom PHY * * Returns: N/A */ @@ -2302,15 +2140,15 @@ if ((IStatus & PHY_B_IS_PSE) != 0) { /* Incorrectable pair swap error */ - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E022, + SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E022, SKERR_SIRQ_E022MSG); } if ((IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) != 0) { - Para.Para32[0] = (SK_U32)Port; SkHWLinkDown(pAC, IoC, Port); + Para.Para32[0] = (SK_U32)Port; /* Signal to RLMT */ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); @@ -2320,13 +2158,15 @@ } } /* SkPhyIsrBcom */ +#endif /* GENESIS */ +#ifdef YUKON /****************************************************************************** * - * SkPhyIsrGmac - PHY interrupt service routine + * SkPhyIsrGmac() - PHY interrupt service routine * - * Description: handle all interrupts from Marvell PHY + * Description: handles all interrupts from Marvell PHY * * Returns: N/A */ @@ -2338,14 +2178,27 @@ { SK_GEPORT *pPrt; /* GIni Port struct pointer */ SK_EVPARA Para; + SK_U16 Word; pPrt = &pAC->GIni.GP[Port]; if ((IStatus & (PHY_M_IS_AN_PR | PHY_M_IS_LST_CHANGE)) != 0) { - Para.Para32[0] = (SK_U32)Port; SkHWLinkDown(pAC, IoC, Port); + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &Word); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNeg.Adv: 0x%04X\n", Word)); + + /* Set Auto-negotiation advertisement */ + if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) { + /* restore Asymmetric Pause bit */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, + (SK_U16)(Word | PHY_M_AN_ASP)); + } + + Para.Para32[0] = (SK_U32)Port; /* Signal to RLMT */ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); } @@ -2355,23 +2208,21 @@ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG); } - if ((IStatus & PHY_M_IS_LSP_CHANGE) != 0) { - /* TBD */ - } - if ((IStatus & PHY_M_IS_FIFO_ERROR) != 0) { /* FIFO Overflow/Underrun Error */ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E024, SKERR_SIRQ_E024MSG); } + } /* SkPhyIsrGmac */ +#endif /* YUKON */ #ifdef OTHER_PHY /****************************************************************************** * - * SkPhyIsrLone - PHY interrupt service routine + * SkPhyIsrLone() - PHY interrupt service routine * - * Description: handle all interrupts from LONE PHY + * Description: handles all interrupts from LONE PHY * * Returns: N/A */ @@ -2384,10 +2235,11 @@ SK_EVPARA Para; if (IStatus & (PHY_L_IS_DUP | PHY_L_IS_ISOL)) { + SkHWLinkDown(pAC, IoC, Port); - /* Signal to RLMT */ Para.Para32[0] = (SK_U32)Port; + /* Signal to RLMT */ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); } Index: drivers/net/sk98lin/ski2c.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/ski2c.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/ski2c.c 22 Jul 2004 19:49:43 -0000 1.1 +++ drivers/net/sk98lin/ski2c.c 4 Aug 2004 01:29:22 -0000 1.2 @@ -1,16 +1,15 @@ /****************************************************************************** * * Name: ski2c.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:43 $ + * Project: Gigabit Ethernet Adapters, TWSI-Module * Purpose: Functions to access Voltage and Temperature Sensor * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,217 +20,13 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: ski2c.c,v $ - * Revision 1.1 2004/07/22 19:49:43 joff - * Initial revision - * - * Revision 1.56 2002/12/19 14:20:41 rschmidt - * Added debugging code in SkI2cWait(). - * Replaced all I2C-write operations with function SkI2cWrite(). - * Fixed compiler warning because of uninitialized 'Time' in SkI2cEvent(). - * Editorial changes. - * - * Revision 1.55 2002/10/15 07:23:55 rschmidt - * Added setting of the GIYukon32Bit bool variable to distinguish - * 32-bit adapters. - * Editorial changes (TWSI). - * - * Revision 1.54 2002/08/13 09:05:06 rschmidt - * Added new thresholds if VAUX is not available (GIVauxAvail). - * Merged defines for PHY PLL 3V3 voltage (A and B). - * Editorial changes. - * - * Revision 1.53 2002/08/08 11:04:53 rwahl - * Added missing comment for revision 1.51 - * - * Revision 1.52 2002/08/08 10:09:02 jschmalz - * Sensor init state caused wrong error log entry - * - * Revision 1.51 2002/08/06 09:43:03 jschmalz - * Extensions and changes for Yukon - * - * Revision 1.50 2002/08/02 12:09:22 rschmidt - * Added support for YUKON sensors. - * Editorial changes. - * - * Revision 1.49 2002/07/30 11:07:52 rschmidt - * Replaced MaxSens init by update for Copper in SkI2cInit1(), - * because it was already initialized in SkI2cInit0(). - * Editorial changes. - * - * Revision 1.48 2001/08/16 12:44:33 afischer - * LM80 sensor init values corrected - * - * Revision 1.47 2001/04/05 11:38:09 rassmann - * Set SenState to idle in SkI2cWaitIrq(). - * Changed error message in SkI2cWaitIrq(). - * - * Revision 1.46 2001/04/02 14:03:35 rassmann - * Changed pAC to IoC in SK_IN32(). - * - * Revision 1.45 2001/03/21 12:12:49 rassmann - * Resetting I2C_READY interrupt in SkI2cInit1(). - * - * Revision 1.44 2000/08/07 15:49:03 gklug - * Fix: SK_INFAST only in NetWare driver. - * - * Revision 1.43 2000/08/03 14:28:17 rassmann - * Added function to wait for I2C being ready before resetting the board. - * Replaced one duplicate "out of range" message with correct one. - * - * Revision 1.42 1999/11/22 13:35:12 cgoos - * Changed license header to GPL. - * - * Revision 1.41 1999/09/14 14:11:30 malthoff - * The 1000BT Dual Link adapter has got only one Fan. - * The second Fan has been removed. - * - * Revision 1.40 1999/05/27 13:37:27 malthoff - * Set divisor of 1 for fan count calculation. - * - * Revision 1.39 1999/05/20 14:54:43 malthoff - * I2c.DummyReads is not used in Diagnostics. - * - * Revision 1.38 1999/05/20 09:20:56 cgoos - * Changes for 1000Base-T (up to 9 sensors and fans). - * - * Revision 1.37 1999/03/25 15:11:36 gklug - * fix: reset error flag if sensor reads correct value - * - * Revision 1.36 1999/01/07 14:11:16 gklug - * fix: break added - * - * Revision 1.35 1999/01/05 15:31:49 gklug - * fix: CLEAR STAT command is now added correctly - * - * Revision 1.34 1998/12/01 13:45:16 gklug - * fix: introduced Init level, because we don't need reinits - * - * Revision 1.33 1998/11/09 14:54:25 malthoff - * Modify I2C Transfer Timeout handling for Diagnostics. - * - * Revision 1.32 1998/11/03 06:54:35 gklug - * fix: Need dummy reads at the beginning to init sensors - * - * Revision 1.31 1998/11/03 06:42:42 gklug - * fix: select correctVIO range only if between warning levels - * - * Revision 1.30 1998/11/02 07:36:53 gklug - * fix: Error should not include WARNING message - * - * Revision 1.29 1998/10/30 15:07:43 malthoff - * Disable 'I2C does not compelete' error log for diagnostics. - * - * Revision 1.28 1998/10/22 09:48:11 gklug - * fix: SysKonnectFileId typo - * - * Revision 1.27 1998/10/20 09:59:46 gklug - * add: parameter to SkOsGetTime - * - * Revision 1.26 1998/10/09 06:10:59 malthoff - * Remove ID_sccs by SysKonnectFileId. - * - * Revision 1.25 1998/09/08 12:40:26 gklug - * fix: syntax error in if clause - * - * Revision 1.24 1998/09/08 12:19:42 gklug - * chg: INIT Level checking - * - * Revision 1.23 1998/09/08 07:37:20 gklug - * fix: log error if PCI_IO voltage sensor could not be initialized - * - * Revision 1.22 1998/09/04 08:30:03 malthoff - * Bugfixes during SK_DIAG testing: - * - correct NS2BCLK() macro - * - correct SkI2cSndDev() - * - correct SkI2cWait() loop waiting for an event - * - * Revision 1.21 1998/08/27 14:46:01 gklug - * chg: if-then-else replaced by switch - * - * Revision 1.20 1998/08/27 14:40:07 gklug - * test: integral types - * - * Revision 1.19 1998/08/25 07:51:54 gklug - * fix: typos for compiling - * - * Revision 1.18 1998/08/25 06:12:24 gklug - * add: count errors and warnings - * fix: check not the sensor state but the ErrFlag! - * - * Revision 1.17 1998/08/25 05:56:48 gklug - * add: CheckSensor function - * - * Revision 1.16 1998/08/20 11:41:10 gklug - * chg: omit STRCPY macro by using char * as Sensor Description - * - * Revision 1.15 1998/08/20 11:37:35 gklug - * chg: change Ioc to IoC - * - * Revision 1.14 1998/08/20 11:32:52 gklug - * fix: Para compile error - * - * Revision 1.13 1998/08/20 11:27:41 gklug - * fix: Compile bugs with new awrning constants - * - * Revision 1.12 1998/08/20 08:53:05 gklug - * fix: compiler errors - * add: Threshold values - * - * Revision 1.11 1998/08/19 12:39:22 malthoff - * Compiler Fix: Some names have changed. - * - * Revision 1.10 1998/08/19 12:20:56 gklug - * fix: remove struct from C files (see CCC) - * - * Revision 1.9 1998/08/19 06:28:46 malthoff - * SkOsGetTime returns SK_U64 now. - * - * Revision 1.8 1998/08/17 13:53:33 gklug - * fix: Parameter of event function and its result - * - * Revision 1.7 1998/08/17 07:02:15 malthoff - * Modify the functions for accessing the I2C SW Registers. - * Modify SkI2cWait(). - * Put Lm80RcvReg into sklm80.c - * Remove Compiler Errors. - * - * Revision 1.6 1998/08/14 07:13:20 malthoff - * remove pAc with pAC - * remove smc with pAC - * change names to new convention - * - * Revision 1.5 1998/08/14 06:24:49 gklug - * add: init level 1 and 2 - * - * Revision 1.4 1998/08/12 14:31:12 gklug - * add: error log for unknown event - * - * Revision 1.3 1998/08/12 13:37:04 gklug - * add: Init 0 function - * - * Revision 1.2 1998/08/11 07:27:15 gklug - * add: functions of the interface - * adapt rest of source to C coding Conventions - * rmv: unnecessary code taken from Mona Lisa - * - * Revision 1.1 1998/06/19 14:28:43 malthoff - * Created. Sources taken from ML Projekt. - * Sources have to be reworked for GE. - * - * - ******************************************************************************/ - - /* * I2C Protocol */ +#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "$Id: ski2c.c,v 1.1 2004/07/22 19:49:43 joff Exp $"; + "@(#) $Id: ski2c.c,v 1.2 2004/08/04 01:29:22 joff Exp $ (C) Marvell. "; +#endif #include "h/skdrv1st.h" /* Driver Specific Definitions */ #include "h/lm80.h" @@ -252,7 +47,7 @@ The Genesis has 2 I2C buses. One for the EEPROM which holds the VPD Data and one for temperature and voltage sensor. The following picture shows the I2C buses, I2C devices and - there control registers. + their control registers. Note: The VPD functions are in skvpd.c . @@ -311,29 +106,29 @@ {} #endif -#ifdef SK_DIAG +#ifdef SK_DIAG /* * I2C Fast Mode timing values used by the LM80. * If new devices are added to the I2C bus the timing values have to be checked. */ #ifndef I2C_SLOW_TIMING -#define T_CLK_LOW 1300L /* clock low time in ns */ -#define T_CLK_HIGH 600L /* clock high time in ns */ +#define T_CLK_LOW 1300L /* clock low time in ns */ +#define T_CLK_HIGH 600L /* clock high time in ns */ #define T_DATA_IN_SETUP 100L /* data in Set-up Time */ #define T_START_HOLD 600L /* start condition hold time */ #define T_START_SETUP 600L /* start condition Set-up time */ #define T_STOP_SETUP 600L /* stop condition Set-up time */ -#define T_BUS_IDLE 1300L /* time the bus must free after Tx */ +#define T_BUS_IDLE 1300L /* time the bus must free after Tx */ #define T_CLK_2_DATA_OUT 900L /* max. clock low to data output valid */ #else /* I2C_SLOW_TIMING */ /* I2C Standard Mode Timing */ -#define T_CLK_LOW 4700L /* clock low time in ns */ -#define T_CLK_HIGH 4000L /* clock high time in ns */ +#define T_CLK_LOW 4700L /* clock low time in ns */ +#define T_CLK_HIGH 4000L /* clock high time in ns */ #define T_DATA_IN_SETUP 250L /* data in Set-up Time */ #define T_START_HOLD 4000L /* start condition hold time */ #define T_START_SETUP 4700L /* start condition Set-up time */ #define T_STOP_SETUP 4000L /* stop condition Set-up time */ -#define T_BUS_IDLE 4700L /* time the bus must free after Tx */ +#define T_BUS_IDLE 4700L /* time the bus must free after Tx */ #endif /* !I2C_SLOW_TIMING */ #define NS2BCLK(x) (((x)*125)/10000) @@ -515,7 +310,6 @@ { /* * Received bit must be zero. - * */ SkI2cSndBit(IoC, 0); } /* SkI2cSndAck */ @@ -589,7 +383,7 @@ return(SkI2cSndByte(IoC, (Addr<<1) | Rw)); } /* SkI2cSndDev */ -#endif /* SK_DIAG */ +#endif /* SK_DIAG */ /*----------------- I2C CTRL Register Functions ----------*/ @@ -619,7 +413,7 @@ SK_I2C_STOP(IoC); #ifndef SK_DIAG SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG); -#endif /* !SK_DIAG */ +#endif /* !SK_DIAG */ return(1); } @@ -660,15 +454,19 @@ } StartTime = SkOsGetTime(pAC); + do { if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) { + SK_I2C_STOP(IoC); #ifndef SK_DIAG SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG); -#endif /* !SK_DIAG */ +#endif /* !SK_DIAG */ return; } + SK_IN32(IoC, B0_ISRC, &IrqSrc); + } while ((IrqSrc & IS_I2C_READY) == 0); pSen->SenState = SK_SEN_IDLE; @@ -686,18 +484,19 @@ SK_IOC IoC, /* I/O Context */ SK_U32 I2cData, /* I2C Data to write */ int I2cDev, /* I2C Device Address */ +int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */ int I2cReg, /* I2C Device Register Address */ int I2cBurst) /* I2C Burst Flag */ { SK_OUT32(IoC, B2_I2C_DATA, I2cData); - SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cReg, I2cBurst); + + SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cDevSize, I2cReg, I2cBurst); return(SkI2cWait(pAC, IoC, I2C_WRITE)); } /* SkI2cWrite*/ #ifdef SK_DIAG - /* * reads a single byte or 4 bytes from the I2C device * @@ -707,23 +506,24 @@ SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ int I2cDev, /* I2C Device Address */ +int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */ int I2cReg, /* I2C Device Register Address */ int I2cBurst) /* I2C Burst Flag */ { SK_U32 Data; SK_OUT32(IoC, B2_I2C_DATA, 0); - SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cReg, I2cBurst); + SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cDevSize, I2cReg, I2cBurst); if (SkI2cWait(pAC, IoC, I2C_READ) != 0) { w_print("%s\n", SKERR_I2C_E002MSG); } SK_IN32(IoC, B2_I2C_DATA, &Data); + return(Data); } /* SkI2cRead */ - -#endif /* SK_DIAG */ +#endif /* SK_DIAG */ /* @@ -744,9 +544,10 @@ if (pSen->SenRead != NULL) { return((*pSen->SenRead)(pAC, IoC, pSen)); } - else + else { return(0); /* no success */ -} /* SkI2cReadSensor*/ + } +} /* SkI2cReadSensor */ /* * Do the Init state 0 initialization @@ -760,12 +561,12 @@ pAC->I2c.CurrSens = 0; /* Begin with timeout control for state machine */ - pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE; + pAC->I2c.TimerMode = SK_TIMER_WATCH_SM; /* Set sensor number to zero */ pAC->I2c.MaxSens = 0; -#ifndef SK_DIAG +#ifndef SK_DIAG /* Initialize Number of Dummy Reads */ pAC->I2c.DummyReads = SK_MAX_SENSORS; #endif @@ -839,19 +640,20 @@ } /* Check for 64 Bit Yukon without sensors */ - if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_CFG, 0) != 0) { + if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_CFG, 0) != 0) { return(0); } - (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_1, 0); + (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_1, 0); - (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_2, 0); + (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_2, 0); - (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_FAN_CTRL, 0); + (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_FAN_CTRL, 0); - (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_TEMP_CTRL, 0); + (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_TEMP_CTRL, 0); - (void)SkI2cWrite(pAC, IoC, LM80_CFG_START, LM80_ADDR, LM80_CFG, 0); + (void)SkI2cWrite(pAC, IoC, (SK_U32)LM80_CFG_START, LM80_ADDR, I2C_025K_DEV, + LM80_CFG, 0); /* * MaxSens has to be updated here, because PhyType is not @@ -861,18 +663,18 @@ pPrt = &pAC->GIni.GP[0]; - switch (pPrt->PhyType) { - case SK_PHY_BCOM: - if (pAC->GIni.GIMacsFound == 1) { - pAC->I2c.MaxSens += 1; - } - else { - pAC->I2c.MaxSens += 3; + if (pAC->GIni.GIGenesis) { + if (pPrt->PhyType == SK_PHY_BCOM) { + if (pAC->GIni.GIMacsFound == 1) { + pAC->I2c.MaxSens += 1; + } + else { + pAC->I2c.MaxSens += 3; + } } - break; - case SK_PHY_MARV_COPPER: + } + else { pAC->I2c.MaxSens += 3; - break; } for (i = 0; i < pAC->I2c.MaxSens; i++) { @@ -915,14 +717,23 @@ pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN; break; case 4: - if (pPrt->PhyType == SK_PHY_BCOM) { - pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL"; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; + if (pAC->GIni.GIGenesis) { + if (pPrt->PhyType == SK_PHY_BCOM) { + pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL"; + pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; + pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; + } + else { + pAC->I2c.SenTable[i].SenDesc = "Voltage PMA"; + pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; + pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; + } } - else if (pPrt->PhyType == SK_PHY_MARV_COPPER) { + else { pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX"; pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR; pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN; @@ -935,40 +746,33 @@ pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR; } } - else { - pAC->I2c.SenTable[i].SenDesc = "Voltage PMA"; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; - } pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN; break; case 5: - if (pPrt->PhyType == SK_PHY_MARV_COPPER) { - pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC-Co 1V5"; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR; - } - else { + if (pAC->GIni.GIGenesis) { pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5"; pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR; pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN; pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN; pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR; } + else { + pAC->I2c.SenTable[i].SenDesc = "Voltage Core 1V5"; + pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR; + pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN; + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR; + } pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN; break; case 6: - if (pPrt->PhyType == SK_PHY_MARV_COPPER) { - pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3"; + if (pAC->GIni.GIGenesis) { + pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL"; } else { - pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL"; + pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3"; } pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; @@ -978,16 +782,7 @@ pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN; break; case 7: - if (pPrt->PhyType == SK_PHY_MARV_COPPER) { - pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5"; - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR; - pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN; - } - else { + if (pAC->GIni.GIGenesis) { pAC->I2c.SenTable[i].SenDesc = "Speed Fan"; pAC->I2c.SenTable[i].SenType = SK_SEN_FAN; pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR; @@ -996,6 +791,15 @@ pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR; pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN; } + else { + pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5"; + pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; + pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR; + pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN; + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR; + pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN; + } break; default: SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW, @@ -1012,9 +816,9 @@ pAC->I2c.SenTable[i].SenDev = LM80_ADDR; } -#ifndef SK_DIAG +#ifndef SK_DIAG pAC->I2c.DummyReads = pAC->I2c.MaxSens; -#endif /* !SK_DIAG */ +#endif /* !SK_DIAG */ /* Clear I2C IRQ */ SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); @@ -1205,15 +1009,13 @@ pSen->SenLastErrLogTS = CurrTime; if (pSen->SenType == SK_SEN_TEMP) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, - SKERR_I2C_E011MSG); - } else if (pSen->SenType == SK_SEN_VOLT) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, - SKERR_I2C_E012MSG); - } else - { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, - SKERR_I2C_E015MSG); + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG); + } + else if (pSen->SenType == SK_SEN_VOLT) { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG); + } + else { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG); } } } @@ -1232,8 +1034,7 @@ /* This state is the former one */ /* So check first whether we have to send a trap */ - if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > - CurrTime) { + if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) { /* * Do NOT send the Trap. The hold back time * has to run out first. @@ -1242,8 +1043,7 @@ } /* Check now whether we have to log an Error */ - if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > - CurrTime) { + if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) { /* * Do NOT log the error. The hold back time * has to run out first. @@ -1274,15 +1074,13 @@ pSen->SenLastWarnLogTS = CurrTime; if (pSen->SenType == SK_SEN_TEMP) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, - SKERR_I2C_E009MSG); - } else if (pSen->SenType == SK_SEN_VOLT) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, - SKERR_I2C_E010MSG); - } else - { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, - SKERR_I2C_E014MSG); + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG); + } + else if (pSen->SenType == SK_SEN_VOLT) { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG); + } + else { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG); } } } @@ -1314,7 +1112,7 @@ } } -#if 0 +#ifdef TEST_ONLY /* Dynamic thresholds also for VAUX of LM80 sensor */ if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) { @@ -1356,7 +1154,7 @@ if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) { SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG); } -} /* SkI2cCheckSensor*/ +} /* SkI2cCheckSensor */ /* @@ -1387,7 +1185,7 @@ if (ReadComplete) { /* Check sensor against defined thresholds */ - SkI2cCheckSensor (pAC, pSen); + SkI2cCheckSensor(pAC, pSen); /* Increment Current sensor and set appropriate Timeout */ pAC->I2c.CurrSens++; @@ -1411,7 +1209,7 @@ /* Start Timer */ ParaLocal.Para64 = (SK_U64)0; - pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE; + pAC->I2c.TimerMode = SK_TIMER_WATCH_SM; SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH, SKGE_I2C, SK_I2CEV_TIM, ParaLocal); @@ -1428,7 +1226,7 @@ if (ReadComplete) { /* Check sensor against defined thresholds */ - SkI2cCheckSensor (pAC, pSen); + SkI2cCheckSensor(pAC, pSen); /* Increment Current sensor and set appropriate Timeout */ pAC->I2c.CurrSens++; @@ -1493,4 +1291,4 @@ return(0); } /* SkI2cEvent*/ -#endif /* !SK_DIAG */ +#endif /* !SK_DIAG */ Index: drivers/net/sk98lin/sklm80.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/sklm80.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/sklm80.c 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/sklm80.c 4 Aug 2004 01:29:22 -0000 1.2 @@ -1,16 +1,15 @@ /****************************************************************************** * * Name: sklm80.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ - * Purpose: Funktions to access Voltage and Temperature Sensor (LM80) + * Project: Gigabit Ethernet Adapters, TWSI-Module + * Purpose: Functions to access Voltage and Temperature Sensor (LM80) * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,91 +20,13 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: sklm80.c,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.20 2002/08/13 09:16:27 rschmidt - * Changed return value for SkLm80ReadSensor() back to 'int' - * Editorial changes - * - * Revision 1.19 2002/08/06 09:43:31 jschmalz - * Extensions and changes for Yukon - * - * Revision 1.18 2002/08/02 12:26:57 rschmidt - * Editorial changes - * - * Revision 1.17 1999/11/22 13:35:51 cgoos - * Changed license header to GPL. - * - * Revision 1.16 1999/05/27 14:05:47 malthoff - * Fans: Set SenVal to 0 if the fan value is 0 or 0xff. Both values - * are outside the limits (0: div zero error, 0xff: value not in - * range, assume 0). - * - * Revision 1.15 1999/05/27 13:38:51 malthoff - * Pervent from Division by zero errors. - * - * Revision 1.14 1999/05/20 09:20:01 cgoos - * Changes for 1000Base-T (Fan sensors). - * - * Revision 1.13 1998/10/22 09:48:14 gklug - * fix: SysKonnectFileId typo - * - * Revision 1.12 1998/10/09 06:12:06 malthoff - * Remove ID_sccs by SysKonnectFileId. - * - * Revision 1.11 1998/09/04 08:33:48 malthoff - * bug fix: SenState = SK_SEN_IDLE when - * leaving SK_SEN_VALEXT state - * - * Revision 1.10 1998/08/20 12:02:10 gklug - * fix: compiler warnings type mismatch - * - * Revision 1.9 1998/08/20 11:37:38 gklug - * chg: change Ioc to IoC - * - * Revision 1.8 1998/08/19 12:20:58 gklug - * fix: remove struct from C files (see CCC) - * - * Revision 1.7 1998/08/17 07:04:57 malthoff - * Take SkLm80RcvReg() function from ski2c.c. - * Add IoC parameter to BREAK_OR_WAIT() macro. - * - * Revision 1.6 1998/08/14 07:11:28 malthoff - * remove pAc with pAC. - * - * Revision 1.5 1998/08/14 06:46:55 gklug - * fix: temperature can get negative - * - * Revision 1.4 1998/08/13 08:27:04 gklug - * add: temperature reading now o.k. - * fix: pSen declaration, SK_ERR_LOG call, ADDR macro - * - * Revision 1.3 1998/08/13 07:28:21 gklug - * fix: pSen was wrong initialized - * add: correct conversion for voltage readings - * - * Revision 1.2 1998/08/11 07:52:14 gklug - * add: Lm80 read sensor function - * - * Revision 1.1 1998/07/17 09:57:12 gklug - * initial version - * - * - * - ******************************************************************************/ - - /* LM80 functions */ +#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "$Id: sklm80.c,v 1.1 2004/07/22 19:49:44 joff Exp $" ; + "@(#) $Id: sklm80.c,v 1.2 2004/08/04 01:29:22 joff Exp $ (C) Marvell. "; +#endif #include "h/skdrv1st.h" /* Driver Specific Definitions */ #include "h/lm80.h" @@ -205,7 +126,7 @@ switch (pSen->SenState) { case SK_SEN_IDLE: /* Send address to ADDR register */ - SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, pSen->SenReg, 0); + SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, pSen->SenReg, 0); pSen->SenState = SK_SEN_VALUE ; BREAK_OR_WAIT(pAC, IoC, I2C_READ); @@ -253,7 +174,7 @@ (pSen->SenValue % SK_LM80_TEMP_LSB); /* Send address to ADDR register */ - SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, LM80_TEMP_CTRL, 0); + SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, LM80_TEMP_CTRL, 0); pSen->SenState = SK_SEN_VALEXT ; BREAK_OR_WAIT(pAC, IoC, I2C_READ); @@ -287,3 +208,4 @@ /* Not completed */ return(0); } + Index: drivers/net/sk98lin/skproc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/skproc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/skproc.c 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/skproc.c 4 Aug 2004 01:29:22 -0000 1.2 @@ -1,9 +1,7 @@ /****************************************************************************** * - * Name: skproc.c + * Name: skproc.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ * Purpose: Funktions to display statictic data * ******************************************************************************/ @@ -11,6 +9,7 @@ /****************************************************************************** * * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,113 +22,88 @@ * The information in this file is provided "AS IS" without warranty. * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: skproc.c,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.3 2002/10/02 12:59:51 mlindner - * Add: Support for Yukon - * Add: Speed check and setup - * Add: Merge source for kernel 2.2.x and 2.4.x - * Add: Read sensor names directly from VPD - * Fix: Volt values - * - * Revision 1.2.2.7 2002/01/14 12:45:15 mlindner - * Fix: Editorial changes - * - * Revision 1.2.2.6 2001/12/06 15:26:07 mlindner - * Fix: Return value of proc_read - * - * Revision 1.2.2.5 2001/12/06 09:57:39 mlindner - * New ProcFs entries - * - * Revision 1.2.2.4 2001/09/05 12:16:02 mlindner - * Add: New ProcFs entries - * Fix: Counter Errors (Jumbo == to long errors) - * Fix: Kernel error compilation - * Fix: too short counters - * - * Revision 1.2.2.3 2001/06/25 07:26:26 mlindner - * Add: More error messages - * - * Revision 1.2.2.2 2001/03/15 12:50:13 mlindner - * fix: ProcFS owner protection - * - * Revision 1.2.2.1 2001/03/12 16:43:48 mlindner - * chg: 2.4 requirements for procfs - * - * Revision 1.1 2001/01/22 14:15:31 mlindner - * added ProcFs functionality - * Dual Net functionality integrated - * Rlmt networks added - * - * - ******************************************************************************/ #include #include "h/skdrv1st.h" #include "h/skdrv2nd.h" -#define ZEROPAD 1 /* pad with zero */ -#define SIGN 2 /* unsigned/signed long */ -#define PLUS 4 /* show plus */ -#define SPACE 8 /* space if plus */ -#define LEFT 16 /* left justified */ -#define SPECIALX 32 /* 0x */ -#define LARGE 64 - -extern SK_AC *pACList; -extern struct net_device *SkGeRootDev; - -extern char * SkNumber( - char * str, - long long num, - int base, - int size, - int precision, - int type); +#include "h/skversion.h" +extern struct SK_NET_DEVICE *SkGeRootDev; +static int sk_proc_print(void *writePtr, char *format, ...); +static void sk_gen_browse(void *buffer); +int len; + +struct proc_dir_entry *file = NULL; /***************************************************************************** * - * proc_read - print "summaries" entry + * sk_proc_read - show proc information of a particular adapter * * Description: * This function fills the proc entry with statistic data about - * the ethernet device. + * the ethernet device. It invokes the generic sk_gen_browse() to + * print out all items one per one. * + * Returns: number of bytes written + * + */ +int sk_proc_read(char *buffer, + char **buffer_location, + off_t offset, + int buffer_length, + int *eof, + void *data) +{ + void *castedBuffer = (void *) buffer; + file = (struct proc_dir_entry*) data; + len = 0; /* initial value */ + sk_gen_browse(castedBuffer); + + if (offset >= len) { + *eof = 1; + return 0; + } + + *buffer_location = buffer + offset; + if (buffer_length >= len - offset) { + *eof = 1; + } + return (min_t(int, buffer_length, len - offset)); +} + +/***************************************************************************** * - * Returns: buffer with statistic data + * sk_gen_browse -generic print "summaries" entry + * + * Description: + * This function fills the proc entry with statistic data about + * the ethernet device. + * + * Returns: - * */ -int proc_read(char *buffer, -char **buffer_location, -off_t offset, -int buffer_length, -int *eof, -void *data) +static void sk_gen_browse(void *buffer) { - int len = 0; - int t; - int i; - DEV_NET *pNet; - SK_AC *pAC; - char test_buf[100]; - char sens_msg[50]; - unsigned long Flags; - unsigned int Size; - struct SK_NET_DEVICE *next; - struct SK_NET_DEVICE *SkgeProcDev = SkGeRootDev; - + struct SK_NET_DEVICE *SkgeProcDev = SkGeRootDev; + struct SK_NET_DEVICE *next; SK_PNMI_STRUCT_DATA *pPnmiStruct; SK_PNMI_STAT *pPnmiStat; - struct proc_dir_entry *file = (struct proc_dir_entry*) data; + unsigned long Flags; + unsigned int Size; + DEV_NET *pNet; + SK_AC *pAC; + char sens_msg[50]; + int MaxSecurityCount = 0; + int t; + int i; while (SkgeProcDev) { + MaxSecurityCount++; + if (MaxSecurityCount > 100) { + printk("Max limit for sk_proc_read security counter!\n"); + return; + } pNet = (DEV_NET*) SkgeProcDev->priv; pAC = pNet->pAC; next = pAC->Next; @@ -142,38 +116,52 @@ spin_lock_irqsave(&pAC->SlowPathLock, Flags); Size = SK_PNMI_STRUCT_SIZE; +#ifdef SK_DIAG_SUPPORT + if (pAC->BoardLevel == SK_INIT_DATA) { + SK_MEMCPY(&(pAC->PnmiStruct), &(pAC->PnmiBackup), sizeof(SK_PNMI_STRUCT_DATA)); + if (pAC->DiagModeActive == DIAG_NOTACTIVE) { + pAC->Pnmi.DiagAttached = SK_DIAG_IDLE; + } + } else { + SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1); + } +#else SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1); +#endif spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); if (strcmp(pAC->dev[t-1]->name, file->name) == 0) { pPnmiStat = &pPnmiStruct->Stat[0]; - len = sprintf(buffer, + len = sk_proc_print(buffer, "\nDetailed statistic for device %s\n", pAC->dev[t-1]->name); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "=======================================\n"); /* Board statistics */ - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "\nBoard statistics\n\n"); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "Active Port %c\n", 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt. Net[t-1].PrefPort]->PortNumber); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "Preferred Port %c\n", 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt. Net[t-1].PrefPort]->PortNumber); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "Bus speed (MHz) %d\n", pPnmiStruct->BusSpeed); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "Bus width (Bit) %d\n", pPnmiStruct->BusWidth); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, + "Driver version %s\n", + VER_STRING); + len += sk_proc_print(buffer, "Hardware revision v%d.%d\n", (pAC->GIni.GIPciHwRev >> 4) & 0x0F, pAC->GIni.GIPciHwRev & 0x0F); @@ -185,7 +173,7 @@ case 1: strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); strcat(sens_msg, " (C)"); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "%-25s %d.%02d\n", sens_msg, pAC->I2c.SenTable[i].SenValue / 10, @@ -193,7 +181,7 @@ strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); strcat(sens_msg, " (F)"); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "%-25s %d.%02d\n", sens_msg, ((((pAC->I2c.SenTable[i].SenValue) @@ -204,7 +192,7 @@ case 2: strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); strcat(sens_msg, " (V)"); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "%-25s %d.%03d\n", sens_msg, pAC->I2c.SenTable[i].SenValue / 1000, @@ -213,7 +201,7 @@ case 3: strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); strcat(sens_msg, " (rpm)"); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "%-25s %d\n", sens_msg, pAC->I2c.SenTable[i].SenValue); @@ -224,17 +212,15 @@ } /*Receive statistics */ - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "\nReceive statistics\n\n"); - len += sprintf(buffer + len, - "Received bytes %s\n", - SkNumber(test_buf, pPnmiStat->StatRxOctetsOkCts, - 10,0,-1,0)); - len += sprintf(buffer + len, - "Received packets %s\n", - SkNumber(test_buf, pPnmiStat->StatRxOkCts, - 10,0,-1,0)); + len += sk_proc_print(buffer, + "Received bytes %Lu\n", + (unsigned long long) pPnmiStat->StatRxOctetsOkCts); + len += sk_proc_print(buffer, + "Received packets %Lu\n", + (unsigned long long) pPnmiStat->StatRxOkCts); #if 0 if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && pAC->HWRevision < 12) { @@ -247,269 +233,138 @@ pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - pPnmiStat->StatRxTooLongCts; - len += sprintf(buffer + len, - "Receive errors %s\n", - SkNumber(test_buf, pPnmiStruct->InErrorsCts, - 10,0,-1,0)); - len += sprintf(buffer + len, - "Receive drops %s\n", - SkNumber(test_buf, pPnmiStruct->RxNoBufCts, - 10,0,-1,0)); - len += sprintf(buffer + len, - "Received multicast %s\n", - SkNumber(test_buf, pPnmiStat->StatRxMulticastOkCts, - 10,0,-1,0)); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, + "Receive errors %Lu\n", + (unsigned long long) pPnmiStruct->InErrorsCts); + len += sk_proc_print(buffer, + "Receive dropped %Lu\n", + (unsigned long long) pPnmiStruct->RxNoBufCts); + len += sk_proc_print(buffer, + "Received multicast %Lu\n", + (unsigned long long) pPnmiStat->StatRxMulticastOkCts); + len += sk_proc_print(buffer, "Receive error types\n"); - len += sprintf(buffer + len, - " length %s\n", - SkNumber(test_buf, pPnmiStat->StatRxRuntCts, - 10, 0, -1, 0)); - len += sprintf(buffer + len, - " buffer overflow %s\n", - SkNumber(test_buf, pPnmiStat->StatRxFifoOverflowCts, - 10, 0, -1, 0)); - len += sprintf(buffer + len, - " bad crc %s\n", - SkNumber(test_buf, pPnmiStat->StatRxFcsCts, - 10, 0, -1, 0)); - len += sprintf(buffer + len, - " framing %s\n", - SkNumber(test_buf, pPnmiStat->StatRxFramingCts, - 10, 0, -1, 0)); - len += sprintf(buffer + len, - " missed frames %s\n", - SkNumber(test_buf, pPnmiStat->StatRxMissedCts, - 10, 0, -1, 0)); + len += sk_proc_print(buffer, + " length %Lu\n", + (unsigned long long) pPnmiStat->StatRxRuntCts); + len += sk_proc_print(buffer, + " buffer overflow %Lu\n", + (unsigned long long) pPnmiStat->StatRxFifoOverflowCts); + len += sk_proc_print(buffer, + " bad crc %Lu\n", + (unsigned long long) pPnmiStat->StatRxFcsCts); + len += sk_proc_print(buffer, + " framing %Lu\n", + (unsigned long long) pPnmiStat->StatRxFramingCts); + len += sk_proc_print(buffer, + " missed frames %Lu\n", + (unsigned long long) pPnmiStat->StatRxMissedCts); if (pNet->Mtu > 1500) pPnmiStat->StatRxTooLongCts = 0; - len += sprintf(buffer + len, - " too long %s\n", - SkNumber(test_buf, pPnmiStat->StatRxTooLongCts, - 10, 0, -1, 0)); - len += sprintf(buffer + len, - " carrier extension %s\n", - SkNumber(test_buf, pPnmiStat->StatRxCextCts, - 10, 0, -1, 0)); - len += sprintf(buffer + len, - " too short %s\n", - SkNumber(test_buf, pPnmiStat->StatRxShortsCts, - 10, 0, -1, 0)); - len += sprintf(buffer + len, - " symbol %s\n", - SkNumber(test_buf, pPnmiStat->StatRxSymbolCts, - 10, 0, -1, 0)); - len += sprintf(buffer + len, - " LLC MAC size %s\n", - SkNumber(test_buf, pPnmiStat->StatRxIRLengthCts, - 10, 0, -1, 0)); - len += sprintf(buffer + len, - " carrier event %s\n", - SkNumber(test_buf, pPnmiStat->StatRxCarrierCts, - 10, 0, -1, 0)); - len += sprintf(buffer + len, - " jabber %s\n", - SkNumber(test_buf, pPnmiStat->StatRxJabberCts, - 10, 0, -1, 0)); + len += sk_proc_print(buffer, + " too long %Lu\n", + (unsigned long long) pPnmiStat->StatRxTooLongCts); + len += sk_proc_print(buffer, + " carrier extension %Lu\n", + (unsigned long long) pPnmiStat->StatRxCextCts); + len += sk_proc_print(buffer, + " too short %Lu\n", + (unsigned long long) pPnmiStat->StatRxShortsCts); + len += sk_proc_print(buffer, + " symbol %Lu\n", + (unsigned long long) pPnmiStat->StatRxSymbolCts); + len += sk_proc_print(buffer, + " LLC MAC size %Lu\n", + (unsigned long long) pPnmiStat->StatRxIRLengthCts); + len += sk_proc_print(buffer, + " carrier event %Lu\n", + (unsigned long long) pPnmiStat->StatRxCarrierCts); + len += sk_proc_print(buffer, + " jabber %Lu\n", + (unsigned long long) pPnmiStat->StatRxJabberCts); /*Transmit statistics */ - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "\nTransmit statistics\n\n"); - len += sprintf(buffer + len, - "Transmited bytes %s\n", - SkNumber(test_buf, pPnmiStat->StatTxOctetsOkCts, - 10,0,-1,0)); - len += sprintf(buffer + len, - "Transmited packets %s\n", - SkNumber(test_buf, pPnmiStat->StatTxOkCts, - 10,0,-1,0)); - len += sprintf(buffer + len, - "Transmit errors %s\n", - SkNumber(test_buf, pPnmiStat->StatTxSingleCollisionCts, - 10,0,-1,0)); - len += sprintf(buffer + len, - "Transmit dropped %s\n", - SkNumber(test_buf, pPnmiStruct->TxNoBufCts, - 10,0,-1,0)); - len += sprintf(buffer + len, - "Transmit collisions %s\n", - SkNumber(test_buf, pPnmiStat->StatTxSingleCollisionCts, - 10,0,-1,0)); - len += sprintf(buffer + len, - "Transmit errors types\n"); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, + "Transmited bytes %Lu\n", + (unsigned long long) pPnmiStat->StatTxOctetsOkCts); + len += sk_proc_print(buffer, + "Transmited packets %Lu\n", + (unsigned long long) pPnmiStat->StatTxOkCts); + len += sk_proc_print(buffer, + "Transmit errors %Lu\n", + (unsigned long long) pPnmiStat->StatTxSingleCollisionCts); + len += sk_proc_print(buffer, + "Transmit dropped %Lu\n", + (unsigned long long) pPnmiStruct->TxNoBufCts); + len += sk_proc_print(buffer, + "Transmit collisions %Lu\n", + (unsigned long long) pPnmiStat->StatTxSingleCollisionCts); + len += sk_proc_print(buffer, + "Transmit error types\n"); + len += sk_proc_print(buffer, " excessive collision %ld\n", pAC->stats.tx_aborted_errors); - len += sprintf(buffer + len, - " carrier %s\n", - SkNumber(test_buf, pPnmiStat->StatTxCarrierCts, - 10, 0, -1, 0)); - len += sprintf(buffer + len, - " fifo underrun %s\n", - SkNumber(test_buf, pPnmiStat->StatTxFifoUnderrunCts, - 10, 0, -1, 0)); - len += sprintf(buffer + len, - " heartbeat %s\n", - SkNumber(test_buf, pPnmiStat->StatTxCarrierCts, - 10, 0, -1, 0)); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, + " carrier %Lu\n", + (unsigned long long) pPnmiStat->StatTxCarrierCts); + len += sk_proc_print(buffer, + " fifo underrun %Lu\n", + (unsigned long long) pPnmiStat->StatTxFifoUnderrunCts); + len += sk_proc_print(buffer, + " heartbeat %Lu\n", + (unsigned long long) pPnmiStat->StatTxCarrierCts); + len += sk_proc_print(buffer, " window %ld\n", pAC->stats.tx_window_errors); - } + } /* if (strcmp(pACname, currDeviceName) == 0) */ } SkgeProcDev = next; } - if (offset >= len) { - *eof = 1; - return 0; - } - - *buffer_location = buffer + offset; - if (buffer_length >= len - offset) { - *eof = 1; - } - return (min_t(int, buffer_length, len - offset)); } - - - - /***************************************************************************** * - * SkDoDiv - convert 64bit number + * sk_proc_print -generic line print * * Description: - * This function "converts" a long long number. - * - * Returns: - * remainder of division - */ -static long SkDoDiv (long long Dividend, int Divisor, long long *pErg) -{ - long Rest; - long long Ergebnis; - long Akku; - - - Akku = Dividend >> 32; - - Ergebnis = ((long long) (Akku / Divisor)) << 32; - Rest = Akku % Divisor ; - - Akku = Rest << 16; - Akku |= ((Dividend & 0xFFFF0000) >> 16); - - - Ergebnis += ((long long) (Akku / Divisor)) << 16; - Rest = Akku % Divisor ; - - Akku = Rest << 16; - Akku |= (Dividend & 0xFFFF); + * This function fills the proc entry with statistic data about + * the ethernet device. + * + * Returns: number of bytes written + * + */ +static int sk_proc_print(void *writePtr, char *format, ...) +{ +#define MAX_LEN_SINGLE_LINE 256 + char str[MAX_LEN_SINGLE_LINE]; + va_list a_start; + int lenght = 0; + + char *buffer = (char *) writePtr; + buffer = buffer + len; /* plus global variable len for current location */ + + SK_MEMSET(str, 0, MAX_LEN_SINGLE_LINE); + + va_start(a_start, format); + vsprintf(str, format, a_start); + va_end(a_start); - Ergebnis += (Akku / Divisor); - Rest = Akku % Divisor ; + lenght = strlen(str); - *pErg = Ergebnis; - return (Rest); + sprintf(buffer, str); + return lenght; } -#if 0 -#define do_div(n,base) ({ \ -long long __res; \ -__res = ((unsigned long long) n) % (unsigned) base; \ -n = ((unsigned long long) n) / (unsigned) base; \ -__res; }) - -#endif - - -/***************************************************************************** +/******************************************************************************* * - * SkNumber - Print results + * End of file * - * Description: - * This function converts a long long number into a string. - * - * Returns: - * number as string - */ -char * SkNumber(char * str, long long num, int base, int size, int precision - ,int type) -{ - char c,sign,tmp[66], *strorg = str; - const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; - int i; - - if (type & LARGE) - digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - if (type & LEFT) - type &= ~ZEROPAD; - if (base < 2 || base > 36) - return 0; - c = (type & ZEROPAD) ? '0' : ' '; - sign = 0; - if (type & SIGN) { - if (num < 0) { - sign = '-'; - num = -num; - size--; - } else if (type & PLUS) { - sign = '+'; - size--; - } else if (type & SPACE) { - sign = ' '; - size--; - } - } - if (type & SPECIALX) { - if (base == 16) - size -= 2; - else if (base == 8) - size--; - } - i = 0; - if (num == 0) - tmp[i++]='0'; - else while (num != 0) - tmp[i++] = digits[SkDoDiv(num,base, &num)]; - - if (i > precision) - precision = i; - size -= precision; - if (!(type&(ZEROPAD+LEFT))) - while(size-->0) - *str++ = ' '; - if (sign) - *str++ = sign; - if (type & SPECIALX) { - if (base==8) - *str++ = '0'; - else if (base==16) { - *str++ = '0'; - *str++ = digits[33]; - } - } - if (!(type & LEFT)) - while (size-- > 0) - *str++ = c; - while (i < precision--) - *str++ = '0'; - while (i-- > 0) - *str++ = tmp[i]; - while (size-- > 0) - *str++ = ' '; - - str[0] = '\0'; - - return strorg; -} - - - + ******************************************************************************/ Index: drivers/net/sk98lin/skqueue.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/skqueue.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/skqueue.c 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/skqueue.c 4 Aug 2004 01:29:22 -0000 1.2 @@ -1,17 +1,15 @@ /****************************************************************************** * * Name: skqueue.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ + * Project: Gigabit Ethernet Adapters, Event Scheduler Module * Purpose: Management of an event queue. * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998,1999 SysKonnect, - * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,79 +20,13 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: skqueue.c,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.18 2002/05/07 14:11:11 rwahl - * Fixed Watcom Precompiler error. - * - * Revision 1.17 2002/03/25 10:06:41 mkunz - * SkIgnoreEvent deleted - * - * Revision 1.16 2002/03/15 10:51:59 mkunz - * Added event classes for link aggregation - * - * Revision 1.15 1999/11/22 13:36:29 cgoos - * Changed license header to GPL. - * - * Revision 1.14 1998/10/15 15:11:35 gklug - * fix: ID_sccs to SysKonnectFileId - * - * Revision 1.13 1998/09/08 08:47:52 gklug - * add: init level handling - * - * Revision 1.12 1998/09/08 07:43:20 gklug - * fix: Sirq Event function name - * - * Revision 1.11 1998/09/08 05:54:34 gklug - * chg: define SK_CSUM is replaced by SK_USE_CSUM - * - * Revision 1.10 1998/09/03 14:14:49 gklug - * add: CSUM and HWAC Eventclass and function. - * - * Revision 1.9 1998/08/19 09:50:50 gklug - * fix: remove struct keyword from c-code (see CCC) add typedefs - * - * Revision 1.8 1998/08/17 13:43:11 gklug - * chg: Parameter will be union of 64bit para, 2 times SK_U32 or SK_PTR - * - * Revision 1.7 1998/08/14 07:09:11 gklug - * fix: chg pAc -> pAC - * - * Revision 1.6 1998/08/11 12:13:14 gklug - * add: return code feature of Event service routines - * add: correct Error log calls - * - * Revision 1.5 1998/08/07 12:53:45 gklug - * fix: first compiled version - * - * Revision 1.4 1998/08/07 09:20:48 gklug - * adapt functions to C coding conventions. - * - * Revision 1.3 1998/08/05 11:29:32 gklug - * rmv: Timer event entry. Timer will queue event directly - * - * Revision 1.2 1998/07/31 11:22:40 gklug - * Initial version - * - * Revision 1.1 1998/07/30 15:14:01 gklug - * Initial version. Adapted from SMT - * - * - * - ******************************************************************************/ - - /* - Event queue and dispatcher -*/ + * Event queue and dispatcher + */ +#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "$Header: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/skqueue.c,v 1.1 2004/07/22 19:49:44 joff Exp $" ; + "@(#) $Id: skqueue.c,v 1.2 2004/08/04 01:29:22 joff Exp $ (C) Marvell."; +#endif #include "h/skdrv1st.h" /* Driver Specific Definitions */ #include "h/skqueue.h" /* Queue Definitions */ @@ -121,11 +53,11 @@ void SkEventInit( SK_AC *pAC, /* Adapter context */ SK_IOC Ioc, /* IO context */ -int Level) /* Init level */ +int Level) /* Init level */ { switch (Level) { case SK_INIT_DATA: - pAC->Event.EvPut = pAC->Event.EvGet = pAC->Event.EvQueue ; + pAC->Event.EvPut = pAC->Event.EvGet = pAC->Event.EvQueue; break; default: break; @@ -141,14 +73,15 @@ SK_U32 Event, /* Event to be queued */ SK_EVPARA Para) /* Event parameter */ { - pAC->Event.EvPut->Class = Class ; - pAC->Event.EvPut->Event = Event ; - pAC->Event.EvPut->Para = Para ; + pAC->Event.EvPut->Class = Class; + pAC->Event.EvPut->Event = Event; + pAC->Event.EvPut->Para = Para; + if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT]) - pAC->Event.EvPut = pAC->Event.EvQueue ; + pAC->Event.EvPut = pAC->Event.EvQueue; if (pAC->Event.EvPut == pAC->Event.EvGet) { - SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG) ; + SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG); } } @@ -165,75 +98,79 @@ SK_AC *pAC, /* Adapters Context */ SK_IOC Ioc) /* Io context */ { - SK_EVENTELEM *pEv ; /* pointer into queue */ - SK_U32 Class ; - int Rtv ; - - pEv = pAC->Event.EvGet ; - PRINTF("dispatch get %x put %x\n",pEv,pAC->Event.ev_put) ; + SK_EVENTELEM *pEv; /* pointer into queue */ + SK_U32 Class; + int Rtv; + + pEv = pAC->Event.EvGet; + + PRINTF("dispatch get %x put %x\n", pEv, pAC->Event.ev_put); + while (pEv != pAC->Event.EvPut) { - PRINTF("dispatch Class %d Event %d\n",pEv->Class,pEv->Event) ; - switch(Class = pEv->Class) { -#ifndef SK_USE_LAC_EV - case SKGE_RLMT : /* RLMT Event */ - Rtv = SkRlmtEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; - case SKGE_I2C : /* I2C Event */ - Rtv = SkI2cEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; - case SKGE_PNMI : - Rtv = SkPnmiEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; -#endif /* SK_USE_LAC_EV */ - case SKGE_DRV : /* Driver Event */ - Rtv = SkDrvEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; -#ifndef SK_USE_SW_TIMER - case SKGE_HWAC : - Rtv = SkGeSirqEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; + PRINTF("dispatch Class %d Event %d\n", pEv->Class, pEv->Event); + + switch (Class = pEv->Class) { +#ifndef SK_USE_LAC_EV +#ifndef SK_SLIM + case SKGE_RLMT: /* RLMT Event */ + Rtv = SkRlmtEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; + case SKGE_I2C: /* I2C Event */ + Rtv = SkI2cEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; + case SKGE_PNMI: /* PNMI Event */ + Rtv = SkPnmiEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; +#endif /* not SK_SLIM */ +#endif /* not SK_USE_LAC_EV */ + case SKGE_DRV: /* Driver Event */ + Rtv = SkDrvEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; +#ifndef SK_USE_SW_TIMER + case SKGE_HWAC: + Rtv = SkGeSirqEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; #else /* !SK_USE_SW_TIMER */ - case SKGE_SWT : - Rtv = SkSwtEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; + case SKGE_SWT : + Rtv = SkSwtEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; #endif /* !SK_USE_SW_TIMER */ -#ifdef SK_USE_LAC_EV +#ifdef SK_USE_LAC_EV case SKGE_LACP : - Rtv = SkLacpEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; + Rtv = SkLacpEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; case SKGE_RSF : - Rtv = SkRsfEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; + Rtv = SkRsfEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; case SKGE_MARKER : - Rtv = SkMarkerEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; + Rtv = SkMarkerEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; case SKGE_FD : - Rtv = SkFdEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; + Rtv = SkFdEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; #endif /* SK_USE_LAC_EV */ #ifdef SK_USE_CSUM case SKGE_CSUM : - Rtv = SkCsEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; + Rtv = SkCsEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; #endif /* SK_USE_CSUM */ default : - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E002, - SKERR_Q_E002MSG) ; + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E002, SKERR_Q_E002MSG); Rtv = 0; } if (Rtv != 0) { - return(Rtv) ; + return(Rtv); } if (++pEv == &pAC->Event.EvQueue[SK_MAX_EVENT]) - pEv = pAC->Event.EvQueue ; + pEv = pAC->Event.EvQueue; /* Renew get: it is used in queue_events to detect overruns */ pAC->Event.EvGet = pEv; } - return(0) ; + return(0); } /* End of file */ Index: drivers/net/sk98lin/skrlmt.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/skrlmt.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/skrlmt.c 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/skrlmt.c 4 Aug 2004 01:29:22 -0000 1.2 @@ -2,15 +2,14 @@ * * Name: skrlmt.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ * Purpose: Manage links on SK-NET Adapters, esp. redundant ones. * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2001 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,243 +22,6 @@ /****************************************************************************** * - * History: - * - * $Log: skrlmt.c,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.65 2002/07/22 14:29:48 rwahl - * - Removed BRK statement from debug check. - * - * Revision 1.64 2001/11/28 19:36:14 rwahl - * - RLMT Packets sent to an invalid MAC address in CLP/CLPSS mode - * (#10650). - * - Reworked fix for port switching in CLS mode (#10639) - * (no dependency to RLMT module). - * - Enabled dbg output for entry/exit of event functions. - * - Editorial changes. - * - * Revision 1.63 2001/10/26 07:53:18 afischer - * Port switching bug in `check local link` mode - * - * Revision 1.62 2001/07/03 12:16:30 mkunz - * New Flag ChgBcPrio (Change priority of last broadcast received) - * - * Revision 1.61 2001/03/14 12:52:08 rassmann - * Fixed reporting of active port up/down to PNMI. - * - * Revision 1.60 2001/02/21 16:02:25 gklug - * fix: when RLMT starts set Active Port for PNMI - * - * Revision 1.59 2001/02/16 14:38:19 rassmann - * Initializing some pointers earlier in the init phase. - * Rx Mbufs are freed if the net which they belong to is stopped. - * - * Revision 1.58 2001/02/14 14:06:31 rassmann - * Editorial changes. - * - * Revision 1.57 2001/02/05 14:25:26 rassmann - * Prepared RLMT for transparent operation. - * - * Revision 1.56 2001/01/30 10:29:09 rassmann - * Not checking switching befor RlmtStart. - * Editorial changes. - * - * Revision 1.55 2001/01/22 13:41:38 rassmann - * Supporting two nets on dual-port adapters. - * - * Revision 1.54 2000/11/30 13:25:07 rassmann - * Setting SK_TICK_INCR to 1 by default. - * - * Revision 1.53 2000/11/30 10:48:07 cgoos - * Changed definition of SK_RLMT_BC_DELTA. - * - * Revision 1.52 2000/11/27 12:50:03 rassmann - * Checking ports after receiving broadcasts. - * - * Revision 1.51 2000/11/17 08:58:00 rassmann - * Moved CheckSwitch from SK_RLMT_PACKET_RECEIVED to SK_RLMT_TIM event. - * - * Revision 1.50 2000/11/09 12:24:34 rassmann - * Indicating that segmentation check is not running anymore after - * SkRlmtCheckSeg(). - * Restarting segmentation timer after segmentation log. - * Editorial changes. - * - * Revision 1.49 1999/11/22 13:38:02 cgoos - * Changed license header to GPL. - * Added initialization to some variables to avoid compiler warnings. - * - * Revision 1.48 1999/10/04 14:01:17 rassmann - * Corrected reaction to reception of BPDU frames (#10441). - * - * Revision 1.47 1999/07/20 12:53:36 rassmann - * Fixed documentation errors for lookahead macros. - * - * Revision 1.46 1999/05/28 13:29:16 rassmann - * Replaced C++-style comment. - * - * Revision 1.45 1999/05/28 13:28:08 rassmann - * Corrected syntax error (xxx). - * - * Revision 1.44 1999/05/28 11:15:54 rassmann - * Changed behaviour to reflect Design Spec v1.2. - * Controlling Link LED(s). - * Introduced RLMT Packet Version field in RLMT Packet. - * Newstyle lookahead macros (checking meta-information before looking at - * the packet). - * - * Revision 1.43 1999/01/28 13:12:43 rassmann - * Corrected Lookahead (bug introduced in previous Rev.). - * - * Revision 1.42 1999/01/28 12:50:41 rassmann - * Not using broadcast time stamps in CheckLinkState mode. - * - * Revision 1.41 1999/01/27 14:13:02 rassmann - * Monitoring broadcast traffic. - * Switching more reliably and not too early if switch is - * configured for spanning tree. - * - * Revision 1.40 1999/01/22 13:17:30 rassmann - * Informing PNMI of NET_UP. - * Clearing RLMT multicast addresses before setting them for the first time. - * Reporting segmentation earlier, setting a "quiet time" - * after a report. - * - * Revision 1.39 1998/12/10 15:29:53 rassmann - * Corrected SuspectStatus in SkRlmtBuildCheckChain(). - * Corrected CHECK_SEG mode. - * - * Revision 1.38 1998/12/08 13:11:23 rassmann - * Stopping SegTimer at RlmtStop. - * - * Revision 1.37 1998/12/07 16:51:42 rassmann - * Corrected comments. - * - * Revision 1.36 1998/12/04 10:58:56 rassmann - * Setting next pointer to NULL when receiving. - * - * Revision 1.35 1998/12/03 16:12:42 rassmann - * Ignoring/correcting illegal PrefPort values. - * - * Revision 1.34 1998/12/01 11:45:35 rassmann - * Code cleanup. - * - * Revision 1.33 1998/12/01 10:29:32 rassmann - * Starting standby ports before getting the net up. - * Checking if a port is started when the link comes up. - * - * Revision 1.32 1998/11/30 16:19:50 rassmann - * New default for PortNoRx. - * - * Revision 1.31 1998/11/27 19:17:13 rassmann - * Corrected handling of LINK_DOWN coming shortly after LINK_UP. - * - * Revision 1.30 1998/11/24 12:37:31 rassmann - * Implemented segmentation check. - * - * Revision 1.29 1998/11/18 13:04:32 rassmann - * Secured PortUpTimer event. - * Waiting longer before starting standby port(s). - * - * Revision 1.28 1998/11/17 13:43:04 rassmann - * Handling (logical) tx failure. - * Sending packet on logical address after PORT_SWITCH. - * - * Revision 1.27 1998/11/13 17:09:50 rassmann - * Secured some events against being called in wrong state. - * - * Revision 1.26 1998/11/13 16:56:54 rassmann - * Added macro version of SkRlmtLookaheadPacket. - * - * Revision 1.25 1998/11/06 18:06:04 rassmann - * Corrected timing when RLMT checks fail. - * Clearing tx counter earlier in periodical checks. - * - * Revision 1.24 1998/11/05 10:37:27 rassmann - * Checking destination address in Lookahead. - * - * Revision 1.23 1998/11/03 13:53:49 rassmann - * RLMT should switch now (at least in mode 3). - * - * Revision 1.22 1998/10/29 14:34:49 rassmann - * Clearing SK_RLMT struct at startup. - * Initializing PortsUp during SK_RLMT_START. - * - * Revision 1.21 1998/10/28 11:30:17 rassmann - * Default mode is now SK_RLMT_CHECK_LOC_LINK. - * - * Revision 1.20 1998/10/26 16:02:03 rassmann - * Ignoring LINK_DOWN for links that are down. - * - * Revision 1.19 1998/10/22 15:54:01 rassmann - * Corrected EtherLen. - * Starting Link Check when second port comes up. - * - * Revision 1.18 1998/10/22 11:39:50 rassmann - * Corrected signed/unsigned mismatches. - * Corrected receive list handling and address recognition. - * - * Revision 1.17 1998/10/19 17:01:20 rassmann - * More detailed checking of received packets. - * - * Revision 1.16 1998/10/15 15:16:34 rassmann - * Finished Spanning Tree checking. - * Checked with lint. - * - * Revision 1.15 1998/09/24 19:16:07 rassmann - * Code cleanup. - * Introduced Timer for PORT_DOWN due to no RX. - * - * Revision 1.14 1998/09/18 20:27:14 rassmann - * Added address override. - * - * Revision 1.13 1998/09/16 11:31:48 rassmann - * Including skdrv1st.h again. :( - * - * Revision 1.12 1998/09/16 11:09:50 rassmann - * Syntax corrections. - * - * Revision 1.11 1998/09/15 12:32:03 rassmann - * Syntax correction. - * - * Revision 1.10 1998/09/15 11:28:49 rassmann - * Syntax corrections. - * - * Revision 1.9 1998/09/14 17:07:37 rassmann - * Added code for port checking via LAN. - * Changed Mbuf definition. - * - * Revision 1.8 1998/09/07 11:14:14 rassmann - * Syntax corrections. - * - * Revision 1.7 1998/09/07 09:06:07 rassmann - * Syntax corrections. - * - * Revision 1.6 1998/09/04 19:41:33 rassmann - * Syntax corrections. - * Started entering code for checking local links. - * - * Revision 1.5 1998/09/04 12:14:27 rassmann - * Interface cleanup. - * - * Revision 1.4 1998/09/02 16:55:28 rassmann - * Updated to reflect new DRV/HWAC/RLMT interface. - * - * Revision 1.3 1998/08/27 14:29:03 rassmann - * Code cleanup. - * - * Revision 1.2 1998/08/27 14:26:24 rassmann - * Updated interface. - * - * Revision 1.1 1998/08/21 08:26:49 rassmann - * First public version. - * - ******************************************************************************/ - -/****************************************************************************** - * * Description: * * This module contains code for Link ManagemenT (LMT) of SK-NET Adapters. @@ -275,13 +37,12 @@ #ifndef lint static const char SysKonnectFileId[] = - "@(#) $Id: skrlmt.c,v 1.1 2004/07/22 19:49:44 joff Exp $ (C) SysKonnect."; + "@(#) $Id: skrlmt.c,v 1.2 2004/08/04 01:29:22 joff Exp $ (C) Marvell."; #endif /* !defined(lint) */ #define __SKRLMT_C #ifdef __cplusplus -#error C++ is not yet supported. extern "C" { #endif /* cplusplus */ @@ -581,6 +342,10 @@ SK_U32 i, j; SK_U64 Random; SK_EVPARA Para; + SK_MAC_ADDR VirtualMacAddress; + SK_MAC_ADDR PhysicalAMacAddress; + SK_BOOL VirtualMacAddressSet; + SK_BOOL PhysicalAMacAddressSet; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT, ("RLMT Init level %d.\n", Level)) @@ -628,7 +393,7 @@ pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound; /* Initialize HW registers? */ - if (pAC->GIni.GIMacsFound < 2) { + if (pAC->GIni.GIMacsFound == 1) { Para.Para32[0] = SK_RLMT_MODE_CLS; Para.Para32[1] = 0; (void)SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE, Para); @@ -664,6 +429,38 @@ (void)SkAddrMcUpdate(pAC, IoC, i); } + + VirtualMacAddressSet = SK_FALSE; + /* Read virtual MAC address from Control Register File. */ + for (j = 0; j < SK_MAC_ADDR_LEN; j++) { + + SK_IN8(IoC, B2_MAC_1 + j, &VirtualMacAddress.a[j]); + VirtualMacAddressSet |= VirtualMacAddress.a[j]; + } + + PhysicalAMacAddressSet = SK_FALSE; + /* Read physical MAC address for MAC A from Control Register File. */ + for (j = 0; j < SK_MAC_ADDR_LEN; j++) { + + SK_IN8(IoC, B2_MAC_2 + j, &PhysicalAMacAddress.a[j]); + PhysicalAMacAddressSet |= PhysicalAMacAddress.a[j]; + } + + /* check if the two mac addresses contain reasonable values */ + if (!VirtualMacAddressSet || !PhysicalAMacAddressSet) { + + pAC->Rlmt.RlmtOff = SK_TRUE; + } + + /* if the two mac addresses are equal switch off the RLMT_PRE_LOOKAHEAD + and the RLMT_LOOKAHEAD macros */ + else if (SK_ADDR_EQUAL(PhysicalAMacAddress.a, VirtualMacAddress.a)) { + + pAC->Rlmt.RlmtOff = SK_TRUE; + } + else { + pAC->Rlmt.RlmtOff = SK_FALSE; + } break; default: /* error */ @@ -763,7 +560,7 @@ } #endif /* DEBUG */ - return; + return; } /* SkRlmtBuildCheckChain */ @@ -850,7 +647,7 @@ } } - return (pMb); + return (pMb); } /* SkRlmtBuildPacket */ @@ -932,7 +729,7 @@ pAC->Rlmt.Port[PortNumber].TxSpHelloReqCts++; } - return (pMb); + return (pMb); } /* SkRlmtBuildSpanningTreePacket */ @@ -999,8 +796,8 @@ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_TX, ("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber)) } - } - return; + } + return; } /* SkRlmtSend */ @@ -1340,7 +1137,7 @@ pRPort->Root.Id[0], pRPort->Root.Id[1], pRPort->Root.Id[2], pRPort->Root.Id[3], pRPort->Root.Id[4], pRPort->Root.Id[5], - pRPort->Root.Id[6], pRPort->Root.Id[7])) + pRPort->Root.Id[6], pRPort->Root.Id[7])) } SkDrvFreeRlmtMbuf(pAC, IoC, pMb); @@ -1503,10 +1300,10 @@ SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); } - NewTimeout = SK_RLMT_DEF_TO_VAL; + NewTimeout = SK_RLMT_DEF_TO_VAL; } - return (NewTimeout); + return (NewTimeout); } /* SkRlmtCheckPort */ @@ -1540,13 +1337,14 @@ /* Select port with the latest TimeStamp. */ for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { -#ifdef DEBUG + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("TimeStamp Port %d: %08x %08x.\n", + ("TimeStamp Port %d (Down: %d, NoRx: %d): %08x %08x.\n", i, + pAC->Rlmt.Port[i].PortDown, pAC->Rlmt.Port[i].PortNoRx, *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_HI32), *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32))) -#endif /* DEBUG */ + if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx) { if (!PortFound || pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp) { BcTimeStamp = pAC->Rlmt.Port[i].BcTimeStamp; @@ -1571,10 +1369,9 @@ pAC->Rlmt.Port[i].BcTimeStamp + SK_RLMT_BC_DELTA > BcTimeStamp)) { PortFound = SK_FALSE; -#ifdef DEBUG + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Port %d received a broadcast at a similar time.\n", i)) -#endif /* DEBUG */ break; } } @@ -1583,8 +1380,8 @@ #ifdef DEBUG if (PortFound) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_CHECK_SWITCH found Port %d receiving the substantially " - "latest broadcast (%d).\n", + ("SK_RLMT_SELECT_BCRX found Port %d receiving the substantially " + "latest broadcast (%u).\n", *pSelect, BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp)) } @@ -1634,7 +1431,7 @@ } PortFound = SK_TRUE; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_CHECK_SWITCH found Port %d up and not check RX.\n", + ("SK_RLMT_SELECT_NOTSUSPECT found Port %d up and not check RX.\n", *pSelect)) break; } @@ -1684,7 +1481,7 @@ } PortFound = SK_TRUE; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_CHECK_SWITCH found Port %d up.\n", *pSelect)) + ("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect)) break; } } @@ -1745,7 +1542,7 @@ } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_CHECK_SWITCH found Port %d going up.\n", *pSelect)) + ("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect)) return (SK_TRUE); } /* SkRlmtSelectGoingUp */ @@ -1791,7 +1588,7 @@ } PortFound = SK_TRUE; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_CHECK_SWITCH found Port %d down.\n", *pSelect)) + ("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect)) break; } } @@ -2429,6 +2226,7 @@ pRPort->PacketsPerTimeSlot = 0; /* pRPort->DataPacketsPerTimeSlot = 0; */ pRPort->BpduPacketsPerTimeSlot = 0; + pRPort->BcTimeStamp = 0; /* * RA;:;: To be checked: @@ -2699,7 +2497,7 @@ } /* Stop RLMT timers. */ - SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer); + SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer); SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer); /* Stop net. */ @@ -2899,7 +2697,7 @@ } } #endif /* xDEBUG */ - + SkRlmtCheckSeg(pAC, IoC, Para.Para32[0]); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, @@ -3287,7 +3085,7 @@ Para.Para32[0] |= SK_RLMT_CHECK_LINK; - if (pAC->Rlmt.Net[Para.Para32[1]].NumPorts < 2 && + if ((pAC->Rlmt.Net[Para.Para32[1]].NumPorts == 1) && Para.Para32[0] != SK_RLMT_MODE_CLS) { pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = SK_RLMT_MODE_CLS; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, @@ -3450,7 +3248,7 @@ break; } /* switch() */ - return (0); + return (0); } /* SkRlmtEvent */ #ifdef __cplusplus Index: drivers/net/sk98lin/sktimer.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/sktimer.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/sktimer.c 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/sktimer.c 4 Aug 2004 01:29:22 -0000 1.2 @@ -1,17 +1,15 @@ /****************************************************************************** * * Name: sktimer.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ + * Project: Gigabit Ethernet Adapters, Event Scheduler Module * Purpose: High level timer functions. * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998,1999 SysKonnect, - * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,64 +20,13 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: sktimer.c,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.12 1999/11/22 13:38:51 cgoos - * Changed license header to GPL. - * - * Revision 1.11 1998/12/17 13:24:13 gklug - * fix: restart problem: do NOT destroy timer queue if init 1 is done - * - * Revision 1.10 1998/10/15 15:11:36 gklug - * fix: ID_sccs to SysKonnectFileId - * - * Revision 1.9 1998/09/15 15:15:04 cgoos - * Changed TRUE/FALSE to SK_TRUE/SK_FALSE - * - * Revision 1.8 1998/09/08 08:47:55 gklug - * add: init level handling - * - * Revision 1.7 1998/08/19 09:50:53 gklug - * fix: remove struct keyword from c-code (see CCC) add typedefs - * - * Revision 1.6 1998/08/17 13:43:13 gklug - * chg: Parameter will be union of 64bit para, 2 times SK_U32 or SK_PTR - * - * Revision 1.5 1998/08/14 07:09:14 gklug - * fix: chg pAc -> pAC - * - * Revision 1.4 1998/08/07 12:53:46 gklug - * fix: first compiled version - * - * Revision 1.3 1998/08/07 09:31:53 gklug - * fix: delta spelling - * - * Revision 1.2 1998/08/07 09:31:02 gklug - * adapt functions to new c coding conventions - * rmv: "fast" handling - * chg: inserting of new timer in queue. - * chg: event queue generation when timer runs out - * - * Revision 1.1 1998/08/05 11:27:55 gklug - * first version: adapted from SMT - * - * - * - * - ******************************************************************************/ - - /* - Event queue and dispatcher -*/ + * Event queue and dispatcher + */ +#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "$Header: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/sktimer.c,v 1.1 2004/07/22 19:49:44 joff Exp $" ; + "@(#) $Id: sktimer.c,v 1.2 2004/08/04 01:29:22 joff Exp $ (C) Marvell."; +#endif #include "h/skdrv1st.h" /* Driver Specific Definitions */ #include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ @@ -108,14 +55,14 @@ void SkTimerInit( SK_AC *pAC, /* Adapters context */ SK_IOC Ioc, /* IoContext */ -int Level) /* Init Level */ +int Level) /* Init Level */ { switch (Level) { case SK_INIT_DATA: - pAC->Tim.StQueue = 0 ; + pAC->Tim.StQueue = 0; break; case SK_INIT_IO: - SkHwtInit(pAC,Ioc) ; + SkHwtInit(pAC, Ioc); SkTimerDone(pAC, Ioc); break; default: @@ -132,31 +79,34 @@ SK_IOC Ioc, /* IoContext */ SK_TIMER *pTimer) /* Timer Pointer to be started */ { - SK_TIMER **ppTimPrev ; - SK_TIMER *pTm ; + SK_TIMER **ppTimPrev; + SK_TIMER *pTm; /* * remove timer from queue */ - pTimer->TmActive = SK_FALSE ; + pTimer->TmActive = SK_FALSE; + if (pAC->Tim.StQueue == pTimer && !pTimer->TmNext) { - SkHwtStop(pAC,Ioc) ; + SkHwtStop(pAC, Ioc); } - for (ppTimPrev = &pAC->Tim.StQueue ; (pTm = *ppTimPrev) ; + + for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev); ppTimPrev = &pTm->TmNext ) { + if (pTm == pTimer) { /* * Timer found in queue * - dequeue it and * - correct delta of the next timer */ - *ppTimPrev = pTm->TmNext ; + *ppTimPrev = pTm->TmNext; if (pTm->TmNext) { /* correct delta of next timer in queue */ - pTm->TmNext->TmDelta += pTm->TmDelta ; + pTm->TmNext->TmDelta += pTm->TmDelta; } - return ; + return; } } } @@ -173,65 +123,67 @@ SK_U32 Event, /* Event Value for this timer */ SK_EVPARA Para) /* Event Parameter for this timer */ { - SK_TIMER **ppTimPrev ; - SK_TIMER *pTm ; - SK_U32 Delta ; + SK_TIMER **ppTimPrev; + SK_TIMER *pTm; + SK_U32 Delta; - Time /= 16 ; /* input is uS, clock ticks are 16uS */ + Time /= 16; /* input is uS, clock ticks are 16uS */ + if (!Time) - Time = 1 ; + Time = 1; - SkTimerStop(pAC,Ioc,pTimer) ; + SkTimerStop(pAC, Ioc, pTimer); - pTimer->TmClass = Class ; - pTimer->TmEvent = Event ; - pTimer->TmPara = Para ; - pTimer->TmActive = SK_TRUE ; + pTimer->TmClass = Class; + pTimer->TmEvent = Event; + pTimer->TmPara = Para; + pTimer->TmActive = SK_TRUE; if (!pAC->Tim.StQueue) { /* First Timer to be started */ - pAC->Tim.StQueue = pTimer ; - pTimer->TmNext = 0 ; - pTimer->TmDelta = Time ; - SkHwtStart(pAC,Ioc,Time) ; - return ; + pAC->Tim.StQueue = pTimer; + pTimer->TmNext = 0; + pTimer->TmDelta = Time; + + SkHwtStart(pAC, Ioc, Time); + + return; } /* * timer correction */ - timer_done(pAC,Ioc,0) ; + timer_done(pAC, Ioc, 0); /* * find position in queue */ - Delta = 0 ; - for (ppTimPrev = &pAC->Tim.StQueue ; (pTm = *ppTimPrev) ; + Delta = 0; + for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev); ppTimPrev = &pTm->TmNext ) { + if (Delta + pTm->TmDelta > Time) { /* Position found */ /* Here the timer needs to be inserted. */ - break ; + break; } - Delta += pTm->TmDelta ; + Delta += pTm->TmDelta; } /* insert in queue */ - *ppTimPrev = pTimer ; - pTimer->TmNext = pTm ; - pTimer->TmDelta = Time - Delta ; + *ppTimPrev = pTimer; + pTimer->TmNext = pTm; + pTimer->TmDelta = Time - Delta; if (pTm) { /* There is a next timer * -> correct its Delta value. */ - pTm->TmDelta -= pTimer->TmDelta ; + pTm->TmDelta -= pTimer->TmDelta; } - /* - * start new with first - */ - SkHwtStart(pAC,Ioc,pAC->Tim.StQueue->TmDelta) ; + /* restart with first */ + SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta); } @@ -239,55 +191,56 @@ SK_AC *pAC, /* Adapters context */ SK_IOC Ioc) /* IoContext */ { - timer_done(pAC,Ioc,1) ; + timer_done(pAC, Ioc, 1); } static void timer_done( SK_AC *pAC, /* Adapters context */ SK_IOC Ioc, /* IoContext */ -int Restart) /* Do we need to restart the Hardware timer ? */ +int Restart) /* Do we need to restart the Hardware timer ? */ { - SK_U32 Delta ; - SK_TIMER *pTm ; - SK_TIMER *pTComp ; /* Timer completed now now */ - SK_TIMER **ppLast ; /* Next field of Last timer to be deq */ - int Done = 0 ; - - Delta = SkHwtRead(pAC,Ioc) ; - ppLast = &pAC->Tim.StQueue ; - pTm = pAC->Tim.StQueue ; + SK_U32 Delta; + SK_TIMER *pTm; + SK_TIMER *pTComp; /* Timer completed now now */ + SK_TIMER **ppLast; /* Next field of Last timer to be deq */ + int Done = 0; + + Delta = SkHwtRead(pAC, Ioc); + + ppLast = &pAC->Tim.StQueue; + pTm = pAC->Tim.StQueue; while (pTm && !Done) { if (Delta >= pTm->TmDelta) { /* Timer ran out */ - pTm->TmActive = SK_FALSE ; - Delta -= pTm->TmDelta ; - ppLast = &pTm->TmNext ; - pTm = pTm->TmNext ; - } else { + pTm->TmActive = SK_FALSE; + Delta -= pTm->TmDelta; + ppLast = &pTm->TmNext; + pTm = pTm->TmNext; + } + else { /* We found the first timer that did not run out */ - pTm->TmDelta -= Delta ; - Delta = 0 ; - Done = 1 ; + pTm->TmDelta -= Delta; + Delta = 0; + Done = 1; } } - *ppLast = 0 ; + *ppLast = 0; /* * pTm points to the first Timer that did not run out. * StQueue points to the first Timer that run out. */ - for ( pTComp = pAC->Tim.StQueue ; pTComp ; pTComp = pTComp->TmNext) { - SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent, - pTComp->TmPara) ; + for ( pTComp = pAC->Tim.StQueue; pTComp; pTComp = pTComp->TmNext) { + SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent, pTComp->TmPara); } /* Set head of timer queue to the first timer that did not run out */ - pAC->Tim.StQueue = pTm ; + pAC->Tim.StQueue = pTm; if (Restart && pAC->Tim.StQueue) { /* Restart HW timer */ - SkHwtStart(pAC,Ioc,pAC->Tim.StQueue->TmDelta) ; + SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta); } } Index: drivers/net/sk98lin/skvpd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/skvpd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/skvpd.c 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/skvpd.c 4 Aug 2004 01:29:22 -0000 1.2 @@ -2,15 +2,13 @@ * * Name: skvpd.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ * Purpose: Shared software to read and write VPD data * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 1998-2003 SysKonnect GmbH. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,138 +19,11 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: skvpd.c,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.32 2002/10/14 16:04:29 rschmidt - * Added saving of VPD ROM Size from PCI_OUR_REG_2 - * Avoid reading of PCI_OUR_REG_2 in VpdTransferBlock() - * Editorial changes - * - * Revision 1.31 2002/09/10 09:21:32 mkarl - * Replaced all if(GIChipId == CHIP_ID_GENESIS) with new entry GIGenesis - * - * Revision 1.30 2002/09/09 14:43:03 mkarl - * changes for diagnostics in order to read VPD data before the adapter - * has been initialized - * editorial changes - * - * Revision 1.29 2002/07/26 13:20:43 mkarl - * added Yukon support - * save size of VPD in pAC->vpd.vpd_size - * - * Revision 1.28 2002/04/02 15:31:47 afischer - * Bug fix in VpdWait() - * - * Revision 1.27 2000/08/10 11:29:06 rassmann - * Editorial changes. - * Preserving 32-bit alignment in structs for the adapter context. - * Removed unused function VpdWriteDword() (#if 0). - * Made VpdReadKeyword() available for SKDIAG only. - * - * Revision 1.26 2000/06/13 08:00:01 mkarl - * additional cast to avoid compile problems in 64 bit environment - * - * Revision 1.25 1999/11/22 13:39:32 cgoos - * Changed license header to GPL. - * - * Revision 1.24 1999/03/11 14:25:49 malthoff - * Replace __STDC__ with SK_KR_PROTO. - * - * Revision 1.23 1999/01/11 15:13:11 gklug - * fix: syntax error - * - * Revision 1.22 1998/10/30 06:41:15 gklug - * rmv: WARNING - * - * Revision 1.21 1998/10/29 07:15:14 gklug - * fix: Write Stream function needs verify. - * - * Revision 1.20 1998/10/28 18:05:08 gklug - * chg: no DEBUG in VpdMayWrite - * - * Revision 1.19 1998/10/28 15:56:11 gklug - * fix: Return len at end of ReadStream - * fix: Write even less than 4 bytes correctly - * - * Revision 1.18 1998/10/28 09:00:47 gklug - * fix: unreferenced local vars - * - * Revision 1.17 1998/10/28 08:25:45 gklug - * fix: WARNING - * - * Revision 1.16 1998/10/28 08:17:30 gklug - * fix: typo - * - * Revision 1.15 1998/10/28 07:50:32 gklug - * fix: typo - * - * Revision 1.14 1998/10/28 07:20:38 gklug - * chg: Interface functions to use IoC as parameter as well - * fix: VpdRead/WriteDWord now returns SK_U32 - * chg: VPD_IN/OUT names conform to SK_IN/OUT - * add: usage of VPD_IN/OUT8 macros - * add: VpdRead/Write Stream functions to r/w a stream of data - * fix: VpdTransferBlock swapped illeagal - * add: VpdMayWrite - * - * Revision 1.13 1998/10/22 10:02:37 gklug - * fix: SysKonnectFileId typo - * - * Revision 1.12 1998/10/20 10:01:01 gklug - * fix: parameter to SkOsGetTime - * - * Revision 1.11 1998/10/15 12:51:48 malthoff - * Remove unrequired parameter p in vpd_setup_para(). - * - * Revision 1.10 1998/10/08 14:52:43 malthoff - * Remove CvsId by SysKonnectFileId. - * - * Revision 1.9 1998/09/16 07:33:52 malthoff - * remove memcmp() by SK_MEMCMP and - * memcpy() by SK_MEMCPY() to be - * independent from the 'C' Standard Library. - * - * Revision 1.8 1998/08/19 12:52:35 malthoff - * compiler fix: use SK_VPD_KEY instead of S_VPD. - * - * Revision 1.7 1998/08/19 08:14:01 gklug - * fix: remove struct keyword as much as possible from the c-code (see CCC) - * - * Revision 1.6 1998/08/18 13:03:58 gklug - * SkOsGetTime now returns SK_U64 - * - * Revision 1.5 1998/08/18 08:17:29 malthoff - * Ensure we issue a VPD read in vpd_read_dword(). - * Discard all VPD keywords other than Vx or Yx, where - * x is '0..9' or 'A..Z'. - * - * Revision 1.4 1998/07/03 14:52:19 malthoff - * Add category SK_DBGCAT_FATAL to some debug macros. - * bug fix: correct the keyword name check in vpd_write(). - * - * Revision 1.3 1998/06/26 11:16:53 malthoff - * Correct the modified File Identifier. - * - * Revision 1.2 1998/06/26 11:13:43 malthoff - * Modify the File Identifier. - * - * Revision 1.1 1998/06/19 14:11:08 malthoff - * Created, Tests with AIX were performed successfully - * - * - ******************************************************************************/ - /* Please refer skvpd.txt for infomation how to include this module */ static const char SysKonnectFileId[] = - "@(#)$Id: skvpd.c,v 1.1 2004/07/22 19:49:44 joff Exp $ (C) SK"; + "@(#)$Id: skvpd.c,v 1.2 2004/08/04 01:29:22 joff Exp $ (C) SK"; #include "h/skdrv1st.h" #include "h/sktypes.h" @@ -165,7 +36,7 @@ #ifndef SK_KR_PROTO static SK_VPD_PARA *vpd_find_para( SK_AC *pAC, - char *key, + const char *key, SK_VPD_PARA *p); #else /* SK_KR_PROTO */ static SK_VPD_PARA *vpd_find_para(); @@ -178,7 +49,7 @@ * returns 0: success, transfer completes * error exit(9) with a error message */ -static int VpdWait( +static int VpdWait( SK_AC *pAC, /* Adapters context */ SK_IOC IoC, /* IO Context */ int event) /* event to wait for (VPD_READ / VPD_write) completion*/ @@ -190,7 +61,7 @@ ("VPD wait for %s\n", event?"Write":"Read")); start_time = SkOsGetTime(pAC); do { - if (SkOsGetTime(pAC) - start_time > SK_TICKS_PER_SEC/16) { + if (SkOsGetTime(pAC) - start_time > SK_TICKS_PER_SEC) { /* Bug fix AF: Thu Mar 28 2002 * Do not call: VPD_STOP(pAC, IoC); @@ -208,7 +79,9 @@ ("ERROR:VPD wait timeout\n")); return(1); } + VPD_IN16(pAC, IoC, PCI_VPD_ADR_REG, &state); + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, ("state = %x, event %x\n",state,event)); } while((int)(state & PCI_VPD_FLAG) == event); @@ -322,7 +195,7 @@ * * Returns number of bytes read / written. */ -static int VpdWriteStream( +static int VpdWriteStream( SK_AC *pAC, /* Adapters context */ SK_IOC IoC, /* IO Context */ char *buf, /* data buffer */ @@ -394,7 +267,9 @@ } for (j = 0; j <= (int)(i%sizeof(SK_U32)); j++, pComp++) { + VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + j, &Data); + if (Data != *pComp) { /* Verify Error */ SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, @@ -415,7 +290,7 @@ * * Returns number of bytes read / written. */ -static int VpdReadStream( +static int VpdReadStream( SK_AC *pAC, /* Adapters context */ SK_IOC IoC, /* IO Context */ char *buf, /* data buffer */ @@ -454,7 +329,7 @@ * * Returns number of bytes read / written. */ -static int VpdTransferBlock( +static int VpdTransferBlock( SK_AC *pAC, /* Adapters context */ SK_IOC IoC, /* IO Context */ char *buf, /* data buffer */ @@ -504,7 +379,7 @@ * * Returns number of bytes read. */ -int VpdReadBlock( +int VpdReadBlock( SK_AC *pAC, /* pAC pointer */ SK_IOC IoC, /* IO Context */ char *buf, /* buffer were the data should be stored */ @@ -519,7 +394,7 @@ * * Returns number of bytes writes. */ -int VpdWriteBlock( +int VpdWriteBlock( SK_AC *pAC, /* pAC pointer */ SK_IOC IoC, /* IO Context */ char *buf, /* buffer, holds the data to write */ @@ -539,7 +414,7 @@ * return 0: success * 1: fatal VPD error */ -static int VpdInit( +static int VpdInit( SK_AC *pAC, /* Adapters context */ SK_IOC IoC) /* IO Context */ { @@ -547,12 +422,12 @@ int i; unsigned char x; int vpd_size; - SK_U16 word; + SK_U16 dev_id; SK_U32 our_reg2; SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("VpdInit .. ")); - VPD_IN16(pAC, IoC, PCI_DEVICE_ID, &word); + VPD_IN16(pAC, IoC, PCI_DEVICE_ID, &dev_id); VPD_IN32(pAC, IoC, PCI_OUR_REG_2, &our_reg2); @@ -563,9 +438,9 @@ * therefore we cannot always trust in GIChipId */ if (((pAC->vpd.v.vpd_status & VPD_VALID) == 0 && - word == VPD_PCI_ID_YUKON) || + dev_id != VPD_DEV_ID_GENESIS) || ((pAC->vpd.v.vpd_status & VPD_VALID) != 0 && - !(pAC->GIni.GIGenesis))) { + !pAC->GIni.GIGenesis)) { /* for Yukon the VPD size is always 256 */ vpd_size = VPD_SIZE_YUKON; @@ -606,7 +481,7 @@ pAC->vpd.v.vpd_free_ro = r->p_len - 1; /* test the checksum */ - for (i = 0, x = 0; (unsigned)i<=(unsigned)vpd_size/2 - r->p_len; i++) { + for (i = 0, x = 0; (unsigned)i <= (unsigned)vpd_size/2 - r->p_len; i++) { x += pAC->vpd.vpd_buf[i]; } @@ -651,9 +526,9 @@ * 0: parameter was not found or VPD encoding error */ static SK_VPD_PARA *vpd_find_para( -SK_AC *pAC, /* common data base */ -char *key, /* keyword to find (e.g. "MN") */ -SK_VPD_PARA *p) /* parameter description struct */ +SK_AC *pAC, /* common data base */ +const char *key, /* keyword to find (e.g. "MN") */ +SK_VPD_PARA *p) /* parameter description struct */ { char *v ; /* points to VPD buffer */ int max; /* Maximum Number of Iterations */ @@ -722,9 +597,9 @@ * returns nothing */ static void vpd_move_para( -char *start, /* start of memory block */ -char *end, /* end of memory block to move */ -int n) /* number of bytes the memory block has to be moved */ +char *start, /* start of memory block */ +char *end, /* end of memory block to move */ +int n) /* number of bytes the memory block has to be moved */ { char *p; int i; /* number of byte copied */ @@ -755,10 +630,10 @@ * returns nothing */ static void vpd_insert_key( -char *key, /* keyword to insert */ -char *buf, /* buffer with the keyword value */ -int len, /* length of the value string */ -char *ip) /* inseration point */ +const char *key, /* keyword to insert */ +const char *buf, /* buffer with the keyword value */ +int len, /* length of the value string */ +char *ip) /* inseration point */ { SK_VPD_KEY *p; @@ -777,8 +652,8 @@ * 1: encoding error */ static int vpd_mod_endtag( -SK_AC *pAC, /* common data base */ -char *etp) /* end pointer input position */ +SK_AC *pAC, /* common data base */ +char *etp) /* end pointer input position */ { SK_VPD_KEY *p; unsigned char x; @@ -842,11 +717,11 @@ */ int VpdSetupPara( SK_AC *pAC, /* common data base */ -char *key, /* keyword to insert */ -char *buf, /* buffer with the keyword value */ -int len, /* length of the keyword value */ -int type, /* VPD_RO_KEY or VPD_RW_KEY */ -int op) /* operation to do: ADD_KEY or OWR_KEY */ +const char *key, /* keyword to insert */ +const char *buf, /* buffer with the keyword value */ +int len, /* length of the keyword value */ +int type, /* VPD_RO_KEY or VPD_RW_KEY */ +int op) /* operation to do: ADD_KEY or OWR_KEY */ { SK_VPD_PARA vp; char *etp; /* end tag position */ @@ -933,12 +808,12 @@ * return: A pointer to the vpd_status structure. The structure contains * this fields. */ -SK_VPD_STATUS *VpdStat( -SK_AC *pAC, /* Adapters context */ -SK_IOC IoC) /* IO Context */ +SK_VPD_STATUS *VpdStat( +SK_AC *pAC, /* Adapters context */ +SK_IOC IoC) /* IO Context */ { - if (!(pAC->vpd.v.vpd_status & VPD_VALID)) { - (void)VpdInit(pAC,IoC); + if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { + (void)VpdInit(pAC, IoC); } return(&pAC->vpd.v); } @@ -966,10 +841,10 @@ * *len = 30 * *elements = 9 */ -int VpdKeys( -SK_AC *pAC, /* common data base */ -SK_IOC IoC, /* IO Context */ -char *buf, /* buffer where to copy the keywords */ +int VpdKeys( +SK_AC *pAC, /* common data base */ +SK_IOC IoC, /* IO Context */ +char *buf, /* buffer where to copy the keywords */ int *len, /* buffer length */ int *elements) /* number of keywords returned */ { @@ -978,8 +853,8 @@ SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("list VPD keys .. ")); *elements = 0; - if (!(pAC->vpd.v.vpd_status & VPD_VALID)) { - if (VpdInit(pAC,IoC) != 0 ) { + if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { + if (VpdInit(pAC, IoC) != 0) { *len = 0; SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("VPD Init Error, terminated\n")); @@ -1052,18 +927,18 @@ * 3: VPD transfer timeout * 6: fatal VPD error */ -int VpdRead( +int VpdRead( SK_AC *pAC, /* common data base */ SK_IOC IoC, /* IO Context */ -char *key, /* keyword to read (e.g. "MN") */ +const char *key, /* keyword to read (e.g. "MN") */ char *buf, /* buffer where to copy the keyword value */ -int *len) /* buffer length */ +int *len) /* buffer length */ { SK_VPD_PARA *p, vp; SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("VPD read %s .. ", key)); - if (!(pAC->vpd.v.vpd_status & VPD_VALID)) { - if (VpdInit(pAC,IoC) != 0 ) { + if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { + if (VpdInit(pAC, IoC) != 0) { *len = 0; SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("VPD init error\n")); @@ -1098,8 +973,8 @@ * SK_TRUE Yes it may be written * SK_FALSE No it may be written */ -SK_BOOL VpdMayWrite( -char *key) /* keyword to write (allowed values "Yx", "Vx") */ +SK_BOOL VpdMayWrite( +char *key) /* keyword to write (allowed values "Yx", "Vx") */ { if ((*key != 'Y' && *key != 'V') || key[1] < '0' || key[1] > 'Z' || @@ -1123,14 +998,14 @@ * 5: keyword cannot be written * 6: fatal VPD error */ -int VpdWrite( +int VpdWrite( SK_AC *pAC, /* common data base */ SK_IOC IoC, /* IO Context */ -char *key, /* keyword to write (allowed values "Yx", "Vx") */ -char *buf) /* buffer where the keyword value can be read from */ +const char *key, /* keyword to write (allowed values "Yx", "Vx") */ +const char *buf) /* buffer where the keyword value can be read from */ { - int len; /* length of the keyword to write */ - int rtv; /* return code */ + int len; /* length of the keyword to write */ + int rtv; /* return code */ int rtv2; SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, @@ -1145,8 +1020,8 @@ return(5); } - if (!(pAC->vpd.v.vpd_status & VPD_VALID)) { - if (VpdInit(pAC,IoC) != 0 ) { + if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { + if (VpdInit(pAC, IoC) != 0) { SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("VPD init error\n")); return(6); @@ -1160,9 +1035,9 @@ len = VPD_MAX_LEN; rtv = 2; SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("keyword to long, cut after %d bytes\n",VPD_MAX_LEN)); + ("keyword too long, cut after %d bytes\n",VPD_MAX_LEN)); } - if ((rtv2 = VpdSetupPara(pAC, key,buf, len, VPD_RW_KEY, OWR_KEY)) != 0) { + if ((rtv2 = VpdSetupPara(pAC, key, buf, len, VPD_RW_KEY, OWR_KEY)) != 0) { SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("VPD write error\n")); return(rtv2); @@ -1183,10 +1058,10 @@ * 5: keyword cannot be deleted * 6: fatal VPD error */ -int VpdDelete( -SK_AC *pAC, /* common data base */ -SK_IOC IoC, /* IO Context */ -char *key) /* keyword to read (e.g. "MN") */ +int VpdDelete( +SK_AC *pAC, /* common data base */ +SK_IOC IoC, /* IO Context */ +char *key) /* keyword to read (e.g. "MN") */ { SK_VPD_PARA *p, vp; char *etp; @@ -1195,8 +1070,8 @@ vpd_size = pAC->vpd.vpd_size; SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("VPD delete key %s\n",key)); - if (!(pAC->vpd.v.vpd_status & VPD_VALID)) { - if (VpdInit(pAC,IoC) != 0 ) { + if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { + if (VpdInit(pAC, IoC) != 0) { SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("VPD init error\n")); return(6); @@ -1238,16 +1113,16 @@ * returns 0: success * 3: VPD transfer timeout */ -int VpdUpdate( -SK_AC *pAC, /* Adapters context */ -SK_IOC IoC) /* IO Context */ +int VpdUpdate( +SK_AC *pAC, /* Adapters context */ +SK_IOC IoC) /* IO Context */ { int vpd_size; vpd_size = pAC->vpd.vpd_size; SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("VPD update .. ")); - if (pAC->vpd.v.vpd_status & VPD_VALID) { + if ((pAC->vpd.v.vpd_status & VPD_VALID) != 0) { if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf + vpd_size/2, vpd_size/2, vpd_size/2, VPD_WRITE) != vpd_size/2) { @@ -1272,18 +1147,18 @@ * * returns nothing, errors will be ignored. */ -void VpdErrLog( -SK_AC *pAC, /* common data base */ -SK_IOC IoC, /* IO Context */ -char *msg) /* error log message */ +void VpdErrLog( +SK_AC *pAC, /* common data base */ +SK_IOC IoC, /* IO Context */ +char *msg) /* error log message */ { SK_VPD_PARA *v, vf; /* VF */ int len; SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, - ("VPD error log msg %s\n",msg)); - if (!(pAC->vpd.v.vpd_status & VPD_VALID)) { - if (VpdInit(pAC,IoC) != 0 ) { + ("VPD error log msg %s\n", msg)); + if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { + if (VpdInit(pAC, IoC) != 0) { SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("VPD init error\n")); return; @@ -1301,7 +1176,7 @@ } else { SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("write VF\n")); - (void)VpdSetupPara(pAC, VPD_VF, msg,len, VPD_RW_KEY, ADD_KEY); + (void)VpdSetupPara(pAC, VPD_VF, msg, len, VPD_RW_KEY, ADD_KEY); } (void)VpdUpdate(pAC, IoC); Index: drivers/net/sk98lin/skxmac2.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/skxmac2.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/skxmac2.c 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/skxmac2.c 4 Aug 2004 01:29:22 -0000 1.2 @@ -1,16 +1,15 @@ /****************************************************************************** * * Name: skxmac2.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ + * Project: Gigabit Ethernet Adapters, Common Modules * Purpose: Contains functions to initialize the MACs and PHYs * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,378 +20,6 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: skxmac2.c,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.87 2002/12/10 14:39:05 rschmidt - * Improved initialization of GPHY in SkGmInitPhyMarv(). - * Editorial changes. - * - * Revision 1.86 2002/12/09 15:01:12 rschmidt - * Added setup of Ext. PHY Specific Ctrl Reg (downshift feature). - * - * Revision 1.85 2002/12/05 14:09:16 rschmidt - * Improved avoiding endless loop in SkGmPhyWrite(), SkGmPhyWrite(). - * Added additional advertising for 10Base-T when 100Base-T is selected. - * Added case SK_PHY_MARV_FIBER for YUKON Fiber adapter. - * Editorial changes. - * - * Revision 1.84 2002/11/15 12:50:09 rschmidt - * Changed SkGmCableDiagStatus() when getting results. - * - * Revision 1.83 2002/11/13 10:28:29 rschmidt - * Added some typecasts to avoid compiler warnings. - * - * Revision 1.82 2002/11/13 09:20:46 rschmidt - * Replaced for(..) with do {} while (...) in SkXmUpdateStats(). - * Replaced 2 macros GM_IN16() with 1 GM_IN32() in SkGmMacStatistic(). - * Added SkGmCableDiagStatus() for Virtual Cable Test (VCT). - * Editorial changes. - * - * Revision 1.81 2002/10/28 14:28:08 rschmidt - * Changed MAC address setup for GMAC in SkGmInitMac(). - * Optimized handling of counter overflow IRQ in SkGmOverflowStatus(). - * Editorial changes. - * - * Revision 1.80 2002/10/14 15:29:44 rschmidt - * Corrected disabling of all PHY IRQs. - * Added WA for deviation #16 (address used for pause packets). - * Set Pause Mode in SkMacRxTxEnable() only for Genesis. - * Added IRQ and counter for Receive FIFO Overflow in DEBUG-mode. - * SkXmTimeStamp() replaced by SkMacTimeStamp(). - * Added clearing of GMAC Tx FIFO Underrun IRQ in SkGmIrq(). - * Editorial changes. - * - * Revision 1.79 2002/10/10 15:55:36 mkarl - * changes for PLinkSpeedUsed - * - * Revision 1.78 2002/09/12 09:39:51 rwahl - * Removed deactivate code for SIRQ overflow event separate for TX/RX. - * - * Revision 1.77 2002/09/09 12:26:37 mkarl - * added handling for Yukon to SkXmTimeStamp - * - * Revision 1.76 2002/08/21 16:41:16 rschmidt - * Added bit GPC_ENA_XC (Enable MDI crossover) in HWCFG_MODE. - * Added forced speed settings in SkGmInitPhyMarv(). - * Added settings of full/half duplex capabilities for YUKON Fiber. - * Editorial changes. - * - * Revision 1.75 2002/08/16 15:12:01 rschmidt - * Replaced all if(GIChipId == CHIP_ID_GENESIS) with new entry GIGenesis. - * Added function SkMacHashing() for ADDR-Module. - * Removed functions SkXmClrSrcCheck(), SkXmClrHashAddr() (calls replaced - * with macros). - * Removed functions SkGmGetMuxConfig(). - * Added HWCFG_MODE init for YUKON Fiber. - * Changed initialization of GPHY in SkGmInitPhyMarv(). - * Changed check of parameter in SkXmMacStatistic(). - * Editorial changes. - * - * Revision 1.74 2002/08/12 14:00:17 rschmidt - * Replaced usage of Broadcom PHY Ids with defines. - * Corrected error messages in SkGmMacStatistic(). - * Made SkMacPromiscMode() public for ADDR-Modul. - * Editorial changes. - * - * Revision 1.73 2002/08/08 16:26:24 rschmidt - * Improved reset sequence for YUKON in SkGmHardRst() and SkGmInitMac(). - * Replaced XMAC Rx High Watermark init value with SK_XM_RX_HI_WM. - * Editorial changes. - * - * Revision 1.72 2002/07/24 15:11:19 rschmidt - * Fixed wrong placement of parenthesis. - * Editorial changes. - * - * Revision 1.71 2002/07/23 16:05:18 rschmidt - * Added global functions for PHY: SkGePhyRead(), SkGePhyWrite(). - * Fixed Tx Counter Overflow IRQ (Bug ID #10730). - * Editorial changes. - * - * Revision 1.70 2002/07/18 14:27:27 rwahl - * Fixed syntax error. - * - * Revision 1.69 2002/07/17 17:08:47 rwahl - * Fixed check in SkXmMacStatistic(). - * - * Revision 1.68 2002/07/16 07:35:24 rwahl - * Removed check for cleared mib counter in SkGmResetCounter(). - * - * Revision 1.67 2002/07/15 18:35:56 rwahl - * Added SkXmUpdateStats(), SkGmUpdateStats(), SkXmMacStatistic(), - * SkGmMacStatistic(), SkXmResetCounter(), SkGmResetCounter(), - * SkXmOverflowStatus(), SkGmOverflowStatus(). - * Changes to SkXmIrq() & SkGmIrq(): Combined SIRQ Overflow for both - * RX & TX. - * Changes to SkGmInitMac(): call to SkGmResetCounter(). - * Editorial changes. - * - * Revision 1.66 2002/07/15 15:59:30 rschmidt - * Added PHY Address in SkXmPhyRead(), SkXmPhyWrite(). - * Added MIB Clear Counter in SkGmInitMac(). - * Added Duplex and Flow-Control settings. - * Reset all Multicast filtering Hash reg. in SkGmInitMac(). - * Added new function: SkGmGetMuxConfig(). - * Editorial changes. - * - * Revision 1.65 2002/06/10 09:35:39 rschmidt - * Replaced C++ comments (//). - * Added #define VCPU around VCPUwaitTime. - * Editorial changes. - * - * Revision 1.64 2002/06/05 08:41:10 rschmidt - * Added function for XMAC2: SkXmTimeStamp(). - * Added function for YUKON: SkGmSetRxCmd(). - * Changed SkGmInitMac() resp. SkGmHardRst(). - * Fixed wrong variable in SkXmAutoNegLipaXmac() (debug mode). - * SkXmRxTxEnable() replaced by SkMacRxTxEnable(). - * Editorial changes. - * - * Revision 1.63 2002/04/25 13:04:44 rschmidt - * Changes for handling YUKON. - * Use of #ifdef OTHER_PHY to eliminate code for unused Phy types. - * Macros for XMAC PHY access PHY_READ(), PHY_WRITE() replaced - * by functions SkXmPhyRead(), SkXmPhyWrite(); - * Removed use of PRxCmd to setup XMAC. - * Added define PHY_B_AS_PAUSE_MSK for BCom Pause Res. - * Added setting of XM_RX_DIS_CEXT in SkXmInitMac(). - * Removed status parameter from MAC IRQ handler SkMacIrq(), - * SkXmIrq() and SkGmIrq(). - * SkXmAutoNegLipa...() for ext. Phy replaced by SkMacAutoNegLipaPhy(). - * Added SkMac...() functions to handle both XMAC and GMAC. - * Added functions for YUKON: SkGmHardRst(), SkGmSoftRst(), - * SkGmSetRxTxEn(), SkGmIrq(), SkGmInitMac(), SkGmInitPhyMarv(), - * SkGmAutoNegDoneMarv(), SkGmPhyRead(), SkGmPhyWrite(). - * Changes for V-CPU support. - * Editorial changes. - * - * Revision 1.62 2001/08/06 09:50:14 rschmidt - * Workaround BCOM Errata #1 for the C5 type. - * Editorial changes. - * - * Revision 1.61 2001/02/09 15:40:59 rassmann - * Editorial changes. - * - * Revision 1.60 2001/02/07 15:02:01 cgoos - * Added workaround for Fujitsu switch link down. - * - * Revision 1.59 2001/01/10 09:38:06 cgoos - * Fixed Broadcom C0/A1 Id check for workaround. - * - * Revision 1.58 2000/11/29 11:30:38 cgoos - * Changed DEBUG sections with NW output to xDEBUG - * - * Revision 1.57 2000/11/27 12:40:40 rassmann - * Suppressing preamble after first access to BCom, not before (#10556). - * - * Revision 1.56 2000/11/09 12:32:48 rassmann - * Renamed variables. - * - * Revision 1.55 2000/11/09 11:30:10 rassmann - * WA: Waiting after releasing reset until BCom chip is accessible. - * - * Revision 1.54 2000/10/02 14:10:27 rassmann - * Reading BCOM PHY after releasing reset until it returns a valid value. - * - * Revision 1.53 2000/07/27 12:22:11 gklug - * fix: possible endless loop in XmHardRst. - * - * Revision 1.52 2000/05/22 08:48:31 malthoff - * Fix: #10523 errata valid for all BCOM PHYs. - * - * Revision 1.51 2000/05/17 12:52:18 malthoff - * Fixes BCom link errata (#10523). - * - * Revision 1.50 1999/11/22 13:40:14 cgoos - * Changed license header to GPL. - * - * Revision 1.49 1999/11/22 08:12:13 malthoff - * Add workaround for power consumption feature of BCom C0 chip. - * - * Revision 1.48 1999/11/16 08:39:01 malthoff - * Fix: MDIO preamble suppression is port dependent. - * - * Revision 1.47 1999/08/27 08:55:35 malthoff - * 1000BT: Optimizing MDIO transfer by oppressing MDIO preamble. - * - * Revision 1.46 1999/08/13 11:01:12 malthoff - * Fix for 1000BT: pFlowCtrlMode was not set correctly. - * - * Revision 1.45 1999/08/12 19:18:28 malthoff - * 1000BT Fixes: Do not owerwrite XM_MMU_CMD. - * Do not execute BCOM A1 workaround for B1 chips. - * Fix pause frame setting. - * Always set PHY_B_AC_TX_TST in PHY_BCOM_AUX_CTRL. - * - * Revision 1.44 1999/08/03 15:23:48 cgoos - * Fixed setting of PHY interrupt mask in half duplex mode. - * - * Revision 1.43 1999/08/03 15:22:17 cgoos - * Added some debug output. - * Disabled XMac GP0 interrupt for external PHYs. - * - * Revision 1.42 1999/08/02 08:39:23 malthoff - * BCOM PHY: TX LED: To get the mono flop behaviour it is required - * to set the LED Traffic Mode bit in PHY_BCOM_P_EXT_CTRL. - * - * Revision 1.41 1999/07/30 06:54:31 malthoff - * Add temp. workarounds for the BCOM Phy revision A1. - * - * Revision 1.40 1999/06/01 07:43:26 cgoos - * Changed Link Mode Status in SkXmAutoNegDone... from FULL/HALF to - * AUTOFULL/AUTOHALF. - * - * Revision 1.39 1999/05/19 07:29:51 cgoos - * Changes for 1000Base-T. - * - * Revision 1.38 1999/04/08 14:35:10 malthoff - * Add code for enabling signal detect. Enabling signal detect is disabled. - * - * Revision 1.37 1999/03/12 13:42:54 malthoff - * Add: Jumbo Frame Support. - * Add: Receive modes SK_LENERR_OK_ON/OFF and - * SK_BIG_PK_OK_ON/OFF in SkXmSetRxCmd(). - * - * Revision 1.36 1999/03/08 10:10:55 gklug - * fix: AutoSensing did switch to next mode even if LiPa indicated offline - * - * Revision 1.35 1999/02/22 15:16:41 malthoff - * Remove some compiler warnings. - * - * Revision 1.34 1999/01/22 09:19:59 gklug - * fix: Init DupMode and InitPauseMd are now called in RxTxEnable - * - * Revision 1.33 1998/12/11 15:19:11 gklug - * chg: lipa autoneg stati - * chg: debug messages - * chg: do NOT use spurious XmIrq - * - * Revision 1.32 1998/12/10 11:08:44 malthoff - * bug fix: pAC has been used for IOs in SkXmHardRst(). - * SkXmInitPhy() is also called for the Diag in SkXmInitMac(). - * - * Revision 1.31 1998/12/10 10:39:11 gklug - * fix: do 4 RESETS of the XMAC at the beginning - * fix: dummy read interrupt source register BEFORE initializing the Phy - * add: debug messages - * fix: Linkpartners autoneg capability cannot be shown by TX_PAGE interrupt - * - * Revision 1.30 1998/12/07 12:18:32 gklug - * add: refinement of autosense mode: take into account the autoneg cap of LiPa - * - * Revision 1.29 1998/12/07 07:12:29 gklug - * fix: if page is received the link is down. - * - * Revision 1.28 1998/12/01 10:12:47 gklug - * chg: if spurious IRQ from XMAC encountered, save it - * - * Revision 1.27 1998/11/26 07:33:38 gklug - * add: InitPhy call is now in XmInit function - * - * Revision 1.26 1998/11/18 13:38:24 malthoff - * 'Imsk' is also unused in SkXmAutoNegDone. - * - * Revision 1.25 1998/11/18 13:28:01 malthoff - * Remove unused variable 'Reg' in SkXmAutoNegDone(). - * - * Revision 1.24 1998/11/18 13:18:45 gklug - * add: workaround for xmac errata #1 - * add: detect Link Down also when Link partner requested config - * chg: XMIrq is only used when link is up - * - * Revision 1.23 1998/11/04 07:07:04 cgoos - * Added function SkXmRxTxEnable. - * - * Revision 1.22 1998/10/30 07:35:54 gklug - * fix: serve LinkDown interrupt when link is already down - * - * Revision 1.21 1998/10/29 15:32:03 gklug - * fix: Link Down signaling - * - * Revision 1.20 1998/10/29 11:17:27 gklug - * fix: AutoNegDone bug - * - * Revision 1.19 1998/10/29 10:14:43 malthoff - * Add endainesss comment for reading/writing MAC addresses. - * - * Revision 1.18 1998/10/28 07:48:55 cgoos - * Fix: ASS somtimes signaled although link is up. - * - * Revision 1.17 1998/10/26 07:55:39 malthoff - * Fix in SkXmInitPauseMd(): Pause Mode - * was disabled and not enabled. - * Fix in SkXmAutoNegDone(): Checking Mode bits - * always failed, becaues of some missing braces. - * - * Revision 1.16 1998/10/22 09:46:52 gklug - * fix SysKonnectFileId typo - * - * Revision 1.15 1998/10/21 05:51:37 gklug - * add: para DoLoop to InitPhy function for loopback set-up - * - * Revision 1.14 1998/10/16 10:59:23 malthoff - * Remove Lint warning for dummy reads. - * - * Revision 1.13 1998/10/15 14:01:20 malthoff - * Fix: SkXmAutoNegDone() is (int) but does not return a value. - * - * Revision 1.12 1998/10/14 14:45:04 malthoff - * Remove SKERR_SIRQ_E0xx and SKERR_SIRQ_E0xxMSG by - * SKERR_HWI_Exx and SKERR_HWI_E0xxMSG to be independent - * from the Sirq module. - * - * Revision 1.11 1998/10/14 13:59:01 gklug - * add: InitPhy function - * - * Revision 1.10 1998/10/14 11:20:57 malthoff - * Make SkXmAutoNegDone() public, because it's - * used in diagnostics, too. - * The Link Up event to the RLMT is issued in SkXmIrq(). - * SkXmIrq() is not available in diagnostics. - * Use PHY_READ when reading PHY registers. - * - * Revision 1.9 1998/10/14 05:50:10 cgoos - * Added definition for Para. - * - * Revision 1.8 1998/10/14 05:41:28 gklug - * add: Xmac IRQ - * add: auto-negotiation done function - * - * Revision 1.7 1998/10/09 06:55:20 malthoff - * The configuration of the XMACs Tx Request Threshold - * depends from the drivers port usage now. The port - * usage is configured in GIPortUsage. - * - * Revision 1.6 1998/10/05 07:48:00 malthoff - * minor changes - * - * Revision 1.5 1998/10/01 07:03:54 gklug - * add: dummy function for XMAC ISR - * - * Revision 1.4 1998/09/30 12:37:44 malthoff - * Add SkXmSetRxCmd() and related code. - * - * Revision 1.3 1998/09/28 13:26:40 malthoff - * Add SkXmInitMac(), SkXmInitDupMd(), and SkXmInitPauseMd() - * - * Revision 1.2 1998/09/16 14:34:21 malthoff - * Add SkXmClrExactAddr(), SkXmClrSrcCheck(), - * SkXmClrHashAddr(), SkXmFlushTxFifo(), - * SkXmFlushRxFifo(), and SkXmHardRst(). - * Finish Coding of SkXmSoftRst(). - * The sources may be compiled now. - * - * Revision 1.1 1998/09/04 10:05:56 malthoff - * Created. - * - * - ******************************************************************************/ - #include "h/skdrv1st.h" #include "h/skdrv2nd.h" @@ -405,9 +32,13 @@ } BCOM_HACK; /* local variables ************************************************************/ + +#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "@(#)$Id: skxmac2.c,v 1.1 2004/07/22 19:49:44 joff Exp $ (C) SK "; + "@(#) $Id: skxmac2.c,v 1.2 2004/08/04 01:29:22 joff Exp $ (C) Marvell."; +#endif +#ifdef GENESIS BCOM_HACK BcomRegA1Hack[] = { { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 }, { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 }, @@ -419,14 +50,19 @@ { 0x15, 0x0A04 }, { 0x18, 0x0420 }, { 0, 0 } }; +#endif /* function prototypes ********************************************************/ +#ifdef GENESIS static void SkXmInitPhyXmac(SK_AC*, SK_IOC, int, SK_BOOL); static void SkXmInitPhyBcom(SK_AC*, SK_IOC, int, SK_BOOL); -static void SkGmInitPhyMarv(SK_AC*, SK_IOC, int, SK_BOOL); static int SkXmAutoNegDoneXmac(SK_AC*, SK_IOC, int); static int SkXmAutoNegDoneBcom(SK_AC*, SK_IOC, int); +#endif /* GENESIS */ +#ifdef YUKON +static void SkGmInitPhyMarv(SK_AC*, SK_IOC, int, SK_BOOL); static int SkGmAutoNegDoneMarv(SK_AC*, SK_IOC, int); +#endif /* YUKON */ #ifdef OTHER_PHY static void SkXmInitPhyLone(SK_AC*, SK_IOC, int, SK_BOOL); static void SkXmInitPhyNat (SK_AC*, SK_IOC, int, SK_BOOL); @@ -435,7 +71,7 @@ #endif /* OTHER_PHY */ - +#ifdef GENESIS /****************************************************************************** * * SkXmPhyRead() - Read from XMAC PHY register @@ -446,11 +82,11 @@ * nothing */ void SkXmPhyRead( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -int Port, /* Port Index (MAC_1 + n) */ -int PhyReg, /* Register Address (Offset) */ -SK_U16 *pVal) /* Pointer to Value */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port Index (MAC_1 + n) */ +int PhyReg, /* Register Address (Offset) */ +SK_U16 SK_FAR *pVal) /* Pointer to Value */ { SK_U16 Mmu; SK_GEPORT *pPrt; @@ -516,8 +152,10 @@ } while ((Mmu & XM_MMU_PHY_BUSY) != 0); } } /* SkXmPhyWrite */ +#endif /* GENESIS */ +#ifdef YUKON /****************************************************************************** * * SkGmPhyRead() - Read from GPHY register @@ -528,11 +166,11 @@ * nothing */ void SkGmPhyRead( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -int Port, /* Port Index (MAC_1 + n) */ -int PhyReg, /* Register Address (Offset) */ -SK_U16 *pVal) /* Pointer to Value */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port Index (MAC_1 + n) */ +int PhyReg, /* Register Address (Offset) */ +SK_U16 SK_FAR *pVal) /* Pointer to Value */ { SK_U16 Ctrl; SK_GEPORT *pPrt; @@ -548,8 +186,8 @@ pPrt = &pAC->GIni.GP[Port]; /* set PHY-Register offset and 'Read' OpCode (= 1) */ - *pVal = GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg) | - GM_SMI_CT_OP_RD; + *pVal = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | + GM_SMI_CT_REG_AD(PhyReg) | GM_SMI_CT_OP_RD); GM_OUT16(IoC, Port, GM_SMI_CTRL, *pVal); @@ -581,6 +219,7 @@ VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n", SimCyle, SimLowTime); #endif /* VCPU */ + } /* SkGmPhyRead */ @@ -649,9 +288,12 @@ VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n", SimCyle, SimLowTime); #endif /* VCPU */ + } /* SkGmPhyWrite */ +#endif /* YUKON */ +#ifdef SK_DIAG /****************************************************************************** * * SkGePhyRead() - Read from PHY register @@ -708,6 +350,7 @@ w_func(pAC, IoC, Port, PhyReg, Val); } /* SkGePhyWrite */ +#endif /* SK_DIAG */ /****************************************************************************** @@ -727,9 +370,14 @@ int Port, /* Port Index (MAC_1 + n) */ SK_BOOL Enable) /* Enable / Disable */ { +#ifdef YUKON SK_U16 RcReg; +#endif +#ifdef GENESIS SK_U32 MdReg; +#endif +#ifdef GENESIS if (pAC->GIni.GIGenesis) { XM_IN32(IoC, Port, XM_MODE, &MdReg); @@ -743,7 +391,10 @@ /* setup Mode Register */ XM_OUT32(IoC, Port, XM_MODE, MdReg); } - else { +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg); @@ -757,6 +408,8 @@ /* setup Receive Control Register */ GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg); } +#endif /* YUKON */ + } /* SkMacPromiscMode*/ @@ -777,9 +430,14 @@ int Port, /* Port Index (MAC_1 + n) */ SK_BOOL Enable) /* Enable / Disable */ { +#ifdef YUKON SK_U16 RcReg; +#endif +#ifdef GENESIS SK_U32 MdReg; +#endif +#ifdef GENESIS if (pAC->GIni.GIGenesis) { XM_IN32(IoC, Port, XM_MODE, &MdReg); @@ -793,7 +451,10 @@ /* setup Mode Register */ XM_OUT32(IoC, Port, XM_MODE, MdReg); } - else { +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg); @@ -807,6 +468,8 @@ /* setup Receive Control Register */ GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg); } +#endif /* YUKON */ + } /* SkMacHashing*/ @@ -906,7 +569,7 @@ * Description: * The features * - FCS (CRC) stripping, SK_STRIP_FCS_ON/OFF - * - don't set XMR_FS_ERR in status SK_BIG_PK_OK_ON/OFF + * - don't set GMR_FS_LONG_ERR SK_BIG_PK_OK_ON/OFF * for frames > 1514 bytes * - enable Rx of own packets SK_SELF_RX_ON/OFF * @@ -989,6 +652,7 @@ SkGmSetRxCmd(pAC, IoC, Port, Mode); } + } /* SkMacSetRxCmd */ @@ -1020,7 +684,7 @@ Word |= XM_TX_NO_CRC; } /* setup Tx Command Register */ - XM_OUT16(pAC, Port, XM_TX_CMD, Word); + XM_OUT16(IoC, Port, XM_TX_CMD, Word); } else { @@ -1035,11 +699,13 @@ /* setup Tx Control Register */ GM_OUT16(IoC, Port, GM_TX_CTRL, Word); } + } /* SkMacCrcGener*/ #endif /* SK_DIAG */ +#ifdef GENESIS /****************************************************************************** * * SkXmClrExactAddr() - Clear Exact Match Address Registers @@ -1073,6 +739,7 @@ XM_OUTADDR(IoC, Port, XM_EXM(i), &ZeroAddr[0]); } } /* SkXmClrExactAddr */ +#endif /* GENESIS */ /****************************************************************************** @@ -1090,6 +757,7 @@ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ { +#ifdef GENESIS SK_U32 MdReg; if (pAC->GIni.GIGenesis) { @@ -1098,10 +766,15 @@ XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FTF); } - else { +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { /* no way to flush the FIFO we have to issue a reset */ /* TBD */ } +#endif /* YUKON */ + } /* SkMacFlushTxFifo */ @@ -1120,6 +793,7 @@ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ { +#ifdef GENESIS SK_U32 MdReg; if (pAC->GIni.GIGenesis) { @@ -1128,13 +802,19 @@ XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FRF); } - else { +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { /* no way to flush the FIFO we have to issue a reset */ /* TBD */ } +#endif /* YUKON */ + } /* SkMacFlushRxFifo */ +#ifdef GENESIS /****************************************************************************** * * SkXmSoftRst() - Do a XMAC software reset @@ -1223,7 +903,7 @@ * Description: * The XMAC of the specified 'Port' and all connected devices * (PHY and SERDES) will receive a reset signal on its *Reset pins. - * External PHYs must be reset be clearing a bit in the GPIO register + * External PHYs must be reset by clearing a bit in the GPIO register * (Timing requirements: Broadcom: 400ns, Level One: none, National: 80ns). * * ATTENTION: @@ -1266,27 +946,68 @@ /* For external PHYs there must be special handling */ if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) { - /* reset external PHY */ + SK_IN32(IoC, B2_GP_IO, &Reg); + if (Port == 0) { - Reg |= GP_DIR_0; /* set to output */ - Reg &= ~GP_IO_0; + Reg |= GP_DIR_0; /* set to output */ + Reg &= ~GP_IO_0; /* set PHY reset (active low) */ } else { - Reg |= GP_DIR_2; /* set to output */ - Reg &= ~GP_IO_2; + Reg |= GP_DIR_2; /* set to output */ + Reg &= ~GP_IO_2; /* set PHY reset (active low) */ } + /* reset external PHY */ SK_OUT32(IoC, B2_GP_IO, Reg); /* short delay */ SK_IN32(IoC, B2_GP_IO, &Reg); } - } /* SkXmHardRst */ /****************************************************************************** * + * SkXmClearRst() - Release the PHY & XMAC reset + * + * Description: + * + * Returns: + * nothing + */ +static void SkXmClearRst( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + SK_U32 DWord; + + /* clear HW reset */ + SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); + + if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) { + + SK_IN32(IoC, B2_GP_IO, &DWord); + + if (Port == 0) { + DWord |= (GP_DIR_0 | GP_IO_0); /* set to output */ + } + else { + DWord |= (GP_DIR_2 | GP_IO_2); /* set to output */ + } + /* Clear PHY reset */ + SK_OUT32(IoC, B2_GP_IO, DWord); + + /* Enable GMII interface */ + XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD); + } +} /* SkXmClearRst */ +#endif /* GENESIS */ + + +#ifdef YUKON +/****************************************************************************** + * * SkGmSoftRst() - Do a GMAC software reset * * Description: @@ -1313,13 +1034,13 @@ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0); /* clear the Hash Register */ - GM_OUTHASH(IoC, Port, GM_MC_ADDR_H1, &EmptyHash); + GM_OUTHASH(IoC, Port, GM_MC_ADDR_H1, EmptyHash); /* Enable Unicast and Multicast filtering */ GM_IN16(IoC, Port, GM_RX_CTRL, &RxCtrl); GM_OUT16(IoC, Port, GM_RX_CTRL, - RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); + (SK_U16)(RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA)); } /* SkGmSoftRst */ @@ -1330,10 +1051,6 @@ * * Description: * - * ATTENTION: - * It is absolutely necessary to reset the SW_RST Bit first - * before calling this function. - * * Returns: * nothing */ @@ -1342,6 +1059,20 @@ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ { + SK_U32 DWord; + + /* WA code for COMA mode */ + if (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { + + SK_IN32(IoC, B2_GP_IO, &DWord); + + DWord |= (GP_DIR_9 | GP_IO_9); + + /* set PHY reset */ + SK_OUT32(IoC, B2_GP_IO, DWord); + } + /* set GPHY Control reset */ SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET); @@ -1353,6 +1084,74 @@ /****************************************************************************** * + * SkGmClearRst() - Release the GPHY & GMAC reset + * + * Description: + * + * Returns: + * nothing + */ +static void SkGmClearRst( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + SK_U32 DWord; + +#ifdef XXX + /* clear GMAC Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR); + + /* set GMAC Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET); +#endif /* XXX */ + + /* WA code for COMA mode */ + if (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { + + SK_IN32(IoC, B2_GP_IO, &DWord); + + DWord |= GP_DIR_9; /* set to output */ + DWord &= ~GP_IO_9; /* clear PHY reset (active high) */ + + /* clear PHY reset */ + SK_OUT32(IoC, B2_GP_IO, DWord); + } + + /* set HWCFG_MODE */ + DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP | + GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE | + (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP : + GPC_HWCFG_GMII_FIB); + + /* set GPHY Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET); + + /* release GPHY Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR); + +#ifdef VCPU + VCpuWait(9000); +#endif /* VCPU */ + + /* clear GMAC Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR); + +#ifdef VCPU + VCpuWait(2000); + + SK_IN32(IoC, MR_ADDR(Port, GPHY_CTRL), &DWord); + + SK_IN32(IoC, B0_ISRC, &DWord); +#endif /* VCPU */ + +} /* SkGmClearRst */ +#endif /* YUKON */ + + +/****************************************************************************** + * * SkMacSoftRst() - Do a MAC software reset * * Description: calls a MAC software reset routine dep. on board type @@ -1372,14 +1171,19 @@ /* disable receiver and transmitter */ SkMacRxTxDisable(pAC, IoC, Port); +#ifdef GENESIS if (pAC->GIni.GIGenesis) { SkXmSoftRst(pAC, IoC, Port); } - else { +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { SkGmSoftRst(pAC, IoC, Port); } +#endif /* YUKON */ /* flush the MAC's Rx and Tx FIFOs */ SkMacFlushTxFifo(pAC, IoC, Port); @@ -1406,21 +1210,58 @@ int Port) /* Port Index (MAC_1 + n) */ { +#ifdef GENESIS if (pAC->GIni.GIGenesis) { SkXmHardRst(pAC, IoC, Port); } - else { +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { SkGmHardRst(pAC, IoC, Port); } +#endif /* YUKON */ pAC->GIni.GP[Port].PState = SK_PRT_RESET; } /* SkMacHardRst */ +/****************************************************************************** + * + * SkMacClearRst() - Clear the MAC reset + * + * Description: calls a clear MAC reset routine dep. on board type + * + * Returns: + * nothing + */ +void SkMacClearRst( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + +#ifdef GENESIS + if (pAC->GIni.GIGenesis) { + + SkXmClearRst(pAC, IoC, Port); + } +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { + + SkGmClearRst(pAC, IoC, Port); + } +#endif /* YUKON */ + +} /* SkMacClearRst */ + +#ifdef GENESIS /****************************************************************************** * * SkXmInitMac() - Initialize the XMAC II @@ -1441,7 +1282,6 @@ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; - SK_U32 Reg; int i; SK_U16 SWord; @@ -1461,32 +1301,10 @@ } if (pPrt->PState == SK_PRT_RESET) { - /* - * clear HW reset - * Note: The SW reset is self clearing, therefore there is - * nothing to do here. - */ - SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); - /* Ensure that XMAC reset release is done (errata from LReinbold?) */ - SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord); + SkXmClearRst(pAC, IoC, Port); - /* Clear PHY reset */ if (pPrt->PhyType != SK_PHY_XMAC) { - - SK_IN32(IoC, B2_GP_IO, &Reg); - - if (Port == 0) { - Reg |= (GP_DIR_0 | GP_IO_0); /* set to output */ - } - else { - Reg |= (GP_DIR_2 | GP_IO_2); /* set to output */ - } - SK_OUT32(IoC, B2_GP_IO, Reg); - - /* Enable GMII interface */ - XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD); - /* read Id from external PHY (all have the same address) */ SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_ID1, &pPrt->PhyId1); @@ -1545,10 +1363,10 @@ */ SkMacInitPhy(pAC, IoC, Port, SK_FALSE); -#if 0 +#ifdef TEST_ONLY /* temp. code: enable signal detect */ /* WARNING: do not override GMII setting above */ - XM_OUT16(pAC, Port, XM_HW_CFG, XM_HW_COM4SIG); + XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_COM4SIG); #endif } @@ -1608,7 +1426,7 @@ SWord |= XM_RX_BIG_PK_OK; } - if (pPrt->PLinkModeConf == SK_LMODE_HALF) { + if (pPrt->PLinkMode == SK_LMODE_HALF) { /* * If in manual half duplex mode the other side might be in * full duplex mode, so ignore if a carrier extension is not seen @@ -1654,7 +1472,10 @@ * has been completed successfully. */ } /* SkXmInitMac */ +#endif /* GENESIS */ + +#ifdef YUKON /****************************************************************************** * * SkGmInitMac() - Initialize the GMAC @@ -1695,34 +1516,71 @@ } if (pPrt->PState == SK_PRT_RESET) { - /* set GPHY Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET); + + SkGmHardRst(pAC, IoC, Port); - /* set GMAC Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET); + SkGmClearRst(pAC, IoC, Port); + + /* Auto-negotiation ? */ + if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { + /* Auto-negotiation disabled */ - /* clear GMAC Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR); + /* get General Purpose Control */ + GM_IN16(IoC, Port, GM_GP_CTRL, &SWord); - /* set GMAC Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET); + /* disable auto-update for speed, duplex and flow-control */ + SWord |= GM_GPCR_AU_ALL_DIS; + + /* setup General Purpose Control Register */ + GM_OUT16(IoC, Port, GM_GP_CTRL, SWord); + + SWord = GM_GPCR_AU_ALL_DIS; + } + else { + SWord = 0; + } - /* set HWCFG_MODE */ - DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP | - GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE | - (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP : - GPC_HWCFG_GMII_FIB); + /* speed settings */ + switch (pPrt->PLinkSpeed) { + case SK_LSPEED_AUTO: + case SK_LSPEED_1000MBPS: + SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100; + break; + case SK_LSPEED_100MBPS: + SWord |= GM_GPCR_SPEED_100; + break; + case SK_LSPEED_10MBPS: + break; + } - /* set GPHY Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET); + /* duplex settings */ + if (pPrt->PLinkMode != SK_LMODE_HALF) { + /* set full duplex */ + SWord |= GM_GPCR_DUP_FULL; + } - /* release GPHY Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR); + /* flow-control settings */ + switch (pPrt->PFlowCtrlMode) { + case SK_FLOW_MODE_NONE: + /* set Pause Off */ + SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_OFF); + /* disable Tx & Rx flow-control */ + SWord |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; + break; + case SK_FLOW_MODE_LOC_SEND: + /* disable Rx flow-control */ + SWord |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; + break; + case SK_FLOW_MODE_SYMMETRIC: + case SK_FLOW_MODE_SYM_OR_REM: + /* enable Tx & Rx flow-control */ + break; + } - /* clear GMAC Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR); + /* setup General Purpose Control Register */ + GM_OUT16(IoC, Port, GM_GP_CTRL, SWord); - /* Dummy read the Interrupt source register */ + /* dummy read the Interrupt Source Register */ SK_IN16(IoC, GMAC_IRQ_SRC, &SWord); #ifndef VCPU @@ -1735,52 +1593,8 @@ (void)SkGmResetCounter(pAC, IoC, Port); - SWord = 0; - - /* speed settings */ - switch (pPrt->PLinkSpeed) { - case SK_LSPEED_AUTO: - /* auto update for speed is already set */ - break; - case SK_LSPEED_1000MBPS: - SWord |= GM_GPCR_SPEED_1000; - break; - case SK_LSPEED_100MBPS: - SWord |= GM_GPCR_SPEED_100; - break; - case SK_LSPEED_10MBPS: - break; - } - - /* duplex settings */ - if (pPrt->PLinkModeConf == SK_LMODE_FULL || - pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE) { - - SWord |= GM_GPCR_DUP_FULL; - } - - /* flow control settings */ - switch (pPrt->PFlowCtrlMode) { - case SK_FLOW_MODE_NONE: - /* disable auto-neg of flow control */ - SWord |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS; - break; - case SK_FLOW_MODE_LOC_SEND: - SWord |= GM_GPCR_FC_RX_DIS; - break; - case SK_FLOW_MODE_SYMMETRIC: - /* TBD */ - case SK_FLOW_MODE_SYM_OR_REM: - /* do nothing means to enable autoneg for flowcontrol and */ - /* enable rx and tx of pause frames */ - break; - } - - /* setup General Purpose Control Register */ - GM_OUT16(IoC, Port, GM_GP_CTRL, SWord); - /* setup Transmit Control Register */ - GM_OUT16(IoC, Port, GM_TX_CTRL, GM_TXCR_COL_THR); + GM_OUT16(IoC, Port, GM_TX_CTRL, TX_COL_THR(pPrt->PMacColThres)); /* setup Receive Control Register */ GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA | @@ -1794,7 +1608,9 @@ GM_IN16(IoC, Port, GM_TX_PARAM, &SWord); #endif /* VCPU */ - SWord = JAM_LEN_VAL(3) | JAM_IPG_VAL(11) | IPG_JAM_DATA(26); + SWord = TX_JAM_LEN_VAL(pPrt->PMacJamLen) | + TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) | + TX_IPG_JAM_DATA(pPrt->PMacJamIpgData); GM_OUT16(IoC, Port, GM_TX_PARAM, SWord); @@ -1803,7 +1619,12 @@ GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord); #endif /* VCPU */ - SWord = GM_SMOD_VLAN_ENA | IPG_VAL_FAST_ETH; + SWord = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData); + + if (pPrt->PMacLimit4) { + /* reset of collision counter after 4 consecutive collisions */ + SWord |= GM_SMOD_LIMIT_4; + } if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { /* enable jumbo mode (Max. Frame Length = 9018) */ @@ -1830,7 +1651,7 @@ #ifdef WA_DEV_16 /* WA for deviation #16 */ - if (pAC->GIni.GIChipRev == 0) { + if (pAC->GIni.GIChipId == CHIP_ID_YUKON && pAC->GIni.GIChipRev == 0) { /* swap the address bytes */ SWord = ((SWord & 0xff00) >> 8) | ((SWord & 0x00ff) << 8); @@ -1848,12 +1669,12 @@ SK_IN16(IoC, (B2_MAC_1 + Port * 8 + i * 2), &SWord); GM_OUT16(IoC, Port, (GM_SRC_ADDR_2L + i * 4), SWord); + + /* reset Multicast filtering Hash registers 1-3 */ + GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + 4*i, 0); } - /* reset all Multicast filtering Hash registers */ - GM_OUT16(IoC, Port, GM_MC_ADDR_H1, 0); - GM_OUT16(IoC, Port, GM_MC_ADDR_H2, 0); - GM_OUT16(IoC, Port, GM_MC_ADDR_H3, 0); + /* reset Multicast filtering Hash register 4 */ GM_OUT16(IoC, Port, GM_MC_ADDR_H4, 0); /* enable interrupt mask for counter overflows */ @@ -1861,13 +1682,23 @@ GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0); GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0); -#ifdef VCPU +#if defined(SK_DIAG) || defined(DEBUG) /* read General Purpose Status */ GM_IN16(IoC, Port, GM_GP_STAT, &SWord); -#endif /* VCPU */ + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("MAC Stat Reg.=0x%04X\n", SWord)); +#endif /* SK_DIAG || DEBUG */ + +#ifdef SK_DIAG + c_print("MAC Stat Reg=0x%04X\n", SWord); +#endif /* SK_DIAG */ + } /* SkGmInitMac */ +#endif /* YUKON */ +#ifdef GENESIS /****************************************************************************** * * SkXmInitDupMd() - Initialize the XMACs Duplex Mode @@ -2058,6 +1889,7 @@ SKERR_HWI_E015MSG); } + /* Set Flow-control capabilities */ switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: Ctrl |= PHY_X_P_NO_PAUSE; @@ -2138,7 +1970,9 @@ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("InitPhyBcom: no auto-negotiation Port %d\n", Port)); /* Set DuplexMode in Config register */ - Ctrl1 |= (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0); + if (pPrt->PLinkMode == SK_LMODE_FULL) { + Ctrl1 |= PHY_CT_DUP_MD; + } /* Determine Master/Slave manually if not already done */ if (pPrt->PMSMode == SK_MS_MODE_AUTO) { @@ -2178,6 +2012,7 @@ SKERR_HWI_E015MSG); } + /* Set Flow-control capabilities */ switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: Ctrl3 |= PHY_B_P_NO_PAUSE; @@ -2207,12 +2042,12 @@ /* Write 1000Base-T Control Register */ SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2)); + ("Set 1000B-T Ctrl Reg=0x%04X\n", Ctrl2)); /* Write AutoNeg Advertisement Register */ SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Auto-Neg. Adv. Reg=0x%04X\n", Ctrl3)); + ("Set Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3)); if (DoLoop) { /* Set the Phy Loopback bit, too */ @@ -2237,6 +2072,283 @@ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("PHY Control Reg=0x%04X\n", Ctrl1)); } /* SkXmInitPhyBcom */ +#endif /* GENESIS */ + + +#ifdef YUKON +#ifndef SK_SLIM +/****************************************************************************** + * + * SkGmEnterLowPowerMode() + * + * Description: + * This function sets the Marvell Alaska PHY to the low power mode + * given by parameter mode. + * The following low power modes are available: + * + * - Coma Mode (Deep Sleep): + * Power consumption: ~15 - 30 mW + * The PHY cannot wake up on its own. + * + * - IEEE 22.2.4.1.5 compatible power down mode + * Power consumption: ~240 mW + * The PHY cannot wake up on its own. + * + * - energy detect mode + * Power consumption: ~160 mW + * The PHY can wake up on its own by detecting activity + * on the CAT 5 cable. + * + * - energy detect plus mode + * Power consumption: ~150 mW + * The PHY can wake up on its own by detecting activity + * on the CAT 5 cable. + * Connected devices can be woken up by sending normal link + * pulses every one second. + * + * Note: + * + * Returns: + * 0: ok + * 1: error + */ +int SkGmEnterLowPowerMode( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (e.g. MAC_1) */ +SK_U8 Mode) /* low power mode */ +{ + SK_U16 Word; + SK_U32 DWord; + SK_U8 LastMode; + int Ret = 0; + + if (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { + + /* save current power mode */ + LastMode = pAC->GIni.GP[Port].PPhyPowerState; + pAC->GIni.GP[Port].PPhyPowerState = Mode; + + switch (Mode) { + /* coma mode (deep sleep) */ + case PHY_PM_DEEP_SLEEP: + /* setup General Purpose Control Register */ + GM_OUT16(IoC, 0, GM_GP_CTRL, GM_GPCR_FL_PASS | + GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS); + + /* apply COMA mode workaround */ + SkGmPhyWrite(pAC, IoC, Port, 29, 0x001f); + SkGmPhyWrite(pAC, IoC, Port, 30, 0xfff3); + + SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); + + /* Set PHY to Coma Mode */ + SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord | PCI_PHY_COMA); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); + + break; + + /* IEEE 22.2.4.1.5 compatible power down mode */ + case PHY_PM_IEEE_POWER_DOWN: + /* + * - disable MAC 125 MHz clock + * - allow MAC power down + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word |= PHY_M_PC_DIS_125CLK; + Word &= ~PHY_M_PC_MAC_POW_UP; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* + * register changes must be followed by a software + * reset to take effect + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word |= PHY_CT_RESET; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + + /* switch IEEE compatible power down mode on */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word |= PHY_CT_PDOWN; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + break; + + /* energy detect and energy detect plus mode */ + case PHY_PM_ENERGY_DETECT: + case PHY_PM_ENERGY_DETECT_PLUS: + /* + * - disable MAC 125 MHz clock + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word |= PHY_M_PC_DIS_125CLK; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* activate energy detect mode 1 */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + + /* energy detect mode */ + if (Mode == PHY_PM_ENERGY_DETECT) { + Word |= PHY_M_PC_EN_DET; + } + /* energy detect plus mode */ + else { + Word |= PHY_M_PC_EN_DET_PLUS; + } + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* + * reinitialize the PHY to force a software reset + * which is necessary after the register settings + * for the energy detect modes. + * Furthermore reinitialisation prevents that the + * PHY is running out of a stable state. + */ + SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE); + break; + + /* don't change current power mode */ + default: + pAC->GIni.GP[Port].PPhyPowerState = LastMode; + Ret = 1; + break; + } + } + /* low power modes are not supported by this chip */ + else { + Ret = 1; + } + + return(Ret); + +} /* SkGmEnterLowPowerMode */ + +/****************************************************************************** + * + * SkGmLeaveLowPowerMode() + * + * Description: + * Leave the current low power mode and switch to normal mode + * + * Note: + * + * Returns: + * 0: ok + * 1: error + */ +int SkGmLeaveLowPowerMode( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (e.g. MAC_1) */ +{ + SK_U32 DWord; + SK_U16 Word; + SK_U8 LastMode; + int Ret = 0; + + if (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { + + /* save current power mode */ + LastMode = pAC->GIni.GP[Port].PPhyPowerState; + pAC->GIni.GP[Port].PPhyPowerState = PHY_PM_OPERATIONAL_MODE; + + switch (LastMode) { + /* coma mode (deep sleep) */ + case PHY_PM_DEEP_SLEEP: + SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); + + /* Release PHY from Coma Mode */ + SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord & ~PCI_PHY_COMA); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); + + SK_IN32(IoC, B2_GP_IO, &DWord); + + /* set to output */ + DWord |= (GP_DIR_9 | GP_IO_9); + + /* set PHY reset */ + SK_OUT32(IoC, B2_GP_IO, DWord); + + DWord &= ~GP_IO_9; /* clear PHY reset (active high) */ + + /* clear PHY reset */ + SK_OUT32(IoC, B2_GP_IO, DWord); + break; + + /* IEEE 22.2.4.1.5 compatible power down mode */ + case PHY_PM_IEEE_POWER_DOWN: + /* + * - enable MAC 125 MHz clock + * - set MAC power up + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word &= ~PHY_M_PC_DIS_125CLK; + Word |= PHY_M_PC_MAC_POW_UP; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* + * register changes must be followed by a software + * reset to take effect + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word |= PHY_CT_RESET; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + + /* switch IEEE compatible power down mode off */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word &= ~PHY_CT_PDOWN; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + break; + + /* energy detect and energy detect plus mode */ + case PHY_PM_ENERGY_DETECT: + case PHY_PM_ENERGY_DETECT_PLUS: + /* + * - enable MAC 125 MHz clock + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word &= ~PHY_M_PC_DIS_125CLK; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* disable energy detect mode */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word &= ~PHY_M_PC_EN_DET_MSK; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* + * reinitialize the PHY to force a software reset + * which is necessary after the register settings + * for the energy detect modes. + * Furthermore reinitialisation prevents that the + * PHY is running out of a stable state. + */ + SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE); + break; + + /* don't change current power mode */ + default: + pAC->GIni.GP[Port].PPhyPowerState = LastMode; + Ret = 1; + break; + } + } + /* low power modes are not supported by this chip */ + else { + Ret = 1; + } + + return(Ret); + +} /* SkGmLeaveLowPowerMode */ +#endif /* !SK_SLIM */ /****************************************************************************** @@ -2258,43 +2370,69 @@ { SK_GEPORT *pPrt; SK_U16 PhyCtrl; - SK_U16 PhyStat; - SK_U16 PhyStat1; - SK_U16 PhySpec; SK_U16 C1000BaseT; SK_U16 AutoNegAdv; SK_U16 ExtPhyCtrl; + SK_U16 LedCtrl; + SK_BOOL AutoNeg; +#if defined(SK_DIAG) || defined(DEBUG) + SK_U16 PhyStat; + SK_U16 PhyStat1; + SK_U16 PhySpecStat; +#endif /* SK_DIAG || DEBUG */ + + pPrt = &pAC->GIni.GP[Port]; + + /* Auto-negotiation ? */ + if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { + AutoNeg = SK_FALSE; + } + else { + AutoNeg = SK_TRUE; + } + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("InitPhyMarv: Port %d, auto-negotiation %s\n", + Port, AutoNeg ? "ON" : "OFF")); #ifdef VCPU VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n", Port, DoLoop); #else /* VCPU */ - - if (!DoLoop) { + if (DoLoop) { + /* Set 'MAC Power up'-bit, set Manual MDI configuration */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, + PHY_M_PC_MAC_POW_UP); + } + else if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO) { /* Read Ext. PHY Specific Control */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl); ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | PHY_M_EC_MAC_S_MSK); - ExtPhyCtrl |= PHY_M_EC_M_DSC(1) | PHY_M_EC_S_DSC(1) | - PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ); + ExtPhyCtrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ) | + PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1); SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Ext.PHYCtrl=0x%04X\n", ExtPhyCtrl)); - - /* Read PHY Control */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl); - - /* Assert software reset */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl | PHY_CT_RESET); + ("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl)); } -#endif /* VCPU */ - pPrt = &pAC->GIni.GP[Port]; + /* Read PHY Control */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl); + + if (!AutoNeg) { + /* Disable Auto-negotiation */ + PhyCtrl &= ~PHY_CT_ANE; + } + + PhyCtrl |= PHY_CT_RESET; + /* Assert software reset */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl); +#endif /* VCPU */ - PhyCtrl = PHY_CT_COL_TST; + PhyCtrl = 0 /* PHY_CT_COL_TST */; C1000BaseT = 0; AutoNegAdv = PHY_SEL_TYPE; @@ -2309,9 +2447,7 @@ } /* Auto-negotiation ? */ - if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("InitPhyMarv: no auto-negotiation Port %d\n", Port)); + if (!AutoNeg) { if (pPrt->PLinkMode == SK_LMODE_FULL) { /* Set Full Duplex Mode */ @@ -2342,16 +2478,9 @@ if (!DoLoop) { PhyCtrl |= PHY_CT_RESET; } - /* - * Do NOT enable Auto-negotiation here. This would hold - * the link down because no IDLES are transmitted - */ } else { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("InitPhyMarv: with auto-negotiation Port %d\n", Port)); - - PhyCtrl |= PHY_CT_ANE; + /* Set Auto-negotiation advertisement */ if (pAC->GIni.GICopperType) { /* Set Speed capabilities */ @@ -2366,6 +2495,7 @@ break; case SK_LSPEED_100MBPS: AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD | + /* advertise 10Base-T also */ PHY_M_AN_10_FD | PHY_M_AN_10_HD; break; case SK_LSPEED_10MBPS: @@ -2393,7 +2523,7 @@ SKERR_HWI_E015MSG); } - /* Set Auto-negotiation advertisement */ + /* Set Flow-control capabilities */ switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: AutoNegAdv |= PHY_B_P_NO_PAUSE; @@ -2430,7 +2560,7 @@ SKERR_HWI_E015MSG); } - /* Set Auto-negotiation advertisement */ + /* Set Flow-control capabilities */ switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: AutoNegAdv |= PHY_M_P_NO_PAUSE_X; @@ -2452,7 +2582,7 @@ if (!DoLoop) { /* Restart Auto-negotiation */ - PhyCtrl |= PHY_CT_RE_CFG; + PhyCtrl |= PHY_CT_ANE | PHY_CT_RE_CFG; } } @@ -2462,12 +2592,7 @@ */ /* Program PHY register 30 as 16'h0708 for simulation speed up */ - SkGmPhyWrite(pAC, IoC, Port, 30, 0x0708); - -#if 0 - /* Program PHY register 20 as 16'h2070 */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, 0x2070); -#endif /* 0 */ + SkGmPhyWrite(pAC, IoC, Port, 30, 0x0700 /* 0x0708 */); VCpuWait(2000); @@ -2476,50 +2601,77 @@ /* Write 1000Base-T Control Register */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("1000B-T Ctrl=0x%04X\n", C1000BaseT)); + ("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT)); /* Write AutoNeg Advertisement Register */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Auto-Neg.Ad.=0x%04X\n", AutoNegAdv)); + ("Set Auto-Neg.Adv.=0x%04X\n", AutoNegAdv)); #endif /* VCPU */ if (DoLoop) { /* Set the PHY Loopback bit */ PhyCtrl |= PHY_CT_LOOP; +#ifdef XXX /* Program PHY register 16 as 16'h0400 to force link good */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_FL_GOOD); +#endif /* XXX */ -#if 0 +#ifndef VCPU if (pPrt->PLinkSpeed != SK_LSPEED_AUTO) { /* Write Ext. PHY Specific Control */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, (SK_U16)((pPrt->PLinkSpeed + 2) << 4)); } +#endif /* VCPU */ } +#ifdef TEST_ONLY else if (pPrt->PLinkSpeed == SK_LSPEED_10MBPS) { /* Write PHY Specific Control */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_EN_DET_MSK); - } -#endif /* 0 */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, + PHY_M_PC_EN_DET_MSK); } +#endif /* Write to the PHY Control register */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Set PHY Ctrl Reg.=0x%04X\n", PhyCtrl)); #ifdef VCPU VCpuWait(2000); -#endif /* VCPU */ +#else + + LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS) | PHY_M_LED_BLINK_RT(BLINK_84MS); + + if ((pAC->GIni.GILedBlinkCtrl & SK_ACT_LED_BLINK) != 0) { + LedCtrl |= PHY_M_LEDC_RX_CTRL | PHY_M_LEDC_TX_CTRL; + } + + if ((pAC->GIni.GILedBlinkCtrl & SK_DUP_LED_NORMAL) != 0) { + LedCtrl |= PHY_M_LEDC_DP_CTRL; + } + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl); + + if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) { + /* only in forced 100 Mbps mode */ + if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) { + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER, + PHY_M_LED_MO_100(MO_LED_ON)); + } + } #ifdef SK_DIAG - c_print("PHY Ctrl Val=0x%04X\n", PhyCtrl); - c_print("1000 B-T Val=0x%04X\n", C1000BaseT); - c_print("Auto-Neg Val=0x%04X\n", AutoNegAdv); - c_print("Ext Ctrl Val=0x%04X\n", ExtPhyCtrl); + c_print("Set PHY Ctrl=0x%04X\n", PhyCtrl); + c_print("Set 1000 B-T=0x%04X\n", C1000BaseT); + c_print("Set Auto-Neg=0x%04X\n", AutoNegAdv); + c_print("Set Ext Ctrl=0x%04X\n", ExtPhyCtrl); #endif /* SK_DIAG */ -#ifndef VCPU +#if defined(SK_DIAG) || defined(DEBUG) /* Read PHY Control */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, @@ -2533,12 +2685,12 @@ /* Read AutoNeg Advertisement Register */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Auto-Neg. Ad.=0x%04X\n", AutoNegAdv)); + ("Auto-Neg.Adv.=0x%04X\n", AutoNegAdv)); /* Read Ext. PHY Specific Control */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Ext PHY Ctrl=0x%04X\n", ExtPhyCtrl)); + ("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl)); /* Read PHY Status */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat); @@ -2549,10 +2701,10 @@ ("PHY Stat Reg.=0x%04X\n", PhyStat1)); /* Read PHY Specific Status */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpec); + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("PHY Spec Stat=0x%04X\n", PhySpec)); -#endif /* VCPU */ + ("PHY Spec Stat=0x%04X\n", PhySpecStat)); +#endif /* SK_DIAG || DEBUG */ #ifdef SK_DIAG c_print("PHY Ctrl Reg=0x%04X\n", PhyCtrl); @@ -2561,10 +2713,13 @@ c_print("Ext Ctrl Reg=0x%04X\n", ExtPhyCtrl); c_print("PHY Stat Reg=0x%04X\n", PhyStat); c_print("PHY Stat Reg=0x%04X\n", PhyStat1); - c_print("PHY Spec Reg=0x%04X\n", PhySpec); + c_print("PHY Spec Reg=0x%04X\n", PhySpecStat); #endif /* SK_DIAG */ +#endif /* VCPU */ + } /* SkGmInitPhyMarv */ +#endif /* YUKON */ #ifdef OTHER_PHY @@ -2607,13 +2762,15 @@ /* Auto-negotiation ? */ if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { /* - * level one spec say: "1000Mbps: manual mode not allowed" + * level one spec say: "1000 Mbps: manual mode not allowed" * but lets see what happens... */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("InitPhyLone: no auto-negotiation Port %d\n", Port)); /* Set DuplexMode in Config register */ - Ctrl1 = (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0); + if (pPrt->PLinkMode == SK_LMODE_FULL) { + Ctrl1 |= PHY_CT_DUP_MD; + } /* Determine Master/Slave manually if not already done */ if (pPrt->PMSMode == SK_MS_MODE_AUTO) { @@ -2646,6 +2803,7 @@ SKERR_HWI_E015MSG); } + /* Set Flow-control capabilities */ switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: Ctrl3 |= PHY_L_P_NO_PAUSE; @@ -2666,13 +2824,8 @@ /* Restart Auto-negotiation */ Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG; - } - /* Initialize LED register here ? */ - /* No. Please do it in SkDgXmitLed() (if required) and swap - init order of LEDs and XMAC. (MAl) */ - /* Write 1000Base-T Control Register */ SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_1000T_CTRL, Ctrl2); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, @@ -2681,8 +2834,7 @@ /* Write AutoNeg Advertisement Register */ SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_AUNE_ADV, Ctrl3); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Auto-Neg. Adv. Reg=0x%04X\n", Ctrl3)); - + ("Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3)); if (DoLoop) { /* Set the Phy Loopback bit, too */ @@ -2739,102 +2891,52 @@ pPrt = &pAC->GIni.GP[Port]; - switch (pPrt->PhyType) { - case SK_PHY_XMAC: - SkXmInitPhyXmac(pAC, IoC, Port, DoLoop); - break; - case SK_PHY_BCOM: - SkXmInitPhyBcom(pAC, IoC, Port, DoLoop); - break; - case SK_PHY_MARV_COPPER: - case SK_PHY_MARV_FIBER: - SkGmInitPhyMarv(pAC, IoC, Port, DoLoop); - break; +#ifdef GENESIS + if (pAC->GIni.GIGenesis) { + + switch (pPrt->PhyType) { + case SK_PHY_XMAC: + SkXmInitPhyXmac(pAC, IoC, Port, DoLoop); + break; + case SK_PHY_BCOM: + SkXmInitPhyBcom(pAC, IoC, Port, DoLoop); + break; #ifdef OTHER_PHY - case SK_PHY_LONE: - SkXmInitPhyLone(pAC, IoC, Port, DoLoop); - break; - case SK_PHY_NAT: - SkXmInitPhyNat(pAC, IoC, Port, DoLoop); - break; + case SK_PHY_LONE: + SkXmInitPhyLone(pAC, IoC, Port, DoLoop); + break; + case SK_PHY_NAT: + SkXmInitPhyNat(pAC, IoC, Port, DoLoop); + break; #endif /* OTHER_PHY */ + } + } +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { + + SkGmInitPhyMarv(pAC, IoC, Port, DoLoop); } +#endif /* YUKON */ + } /* SkMacInitPhy */ -#ifndef SK_DIAG +#ifdef GENESIS /****************************************************************************** * - * SkXmAutoNegLipaXmac() - Decides whether Link Partner could do auto-neg + * SkXmAutoNegDoneXmac() - Auto-negotiation handling * - * This function analyses the Interrupt status word. If any of the - * Auto-negotiating interrupt bits are set, the PLipaAutoNeg variable - * is set true. + * Description: + * This function handles the auto-negotiation if the Done bit is set. + * + * Returns: + * SK_AND_OK o.k. + * SK_AND_DUP_CAP Duplex capability error happened + * SK_AND_OTHER Other error happened */ -void SkXmAutoNegLipaXmac( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_U16 IStatus) /* Interrupt Status word to analyse */ -{ - SK_GEPORT *pPrt; - - pPrt = &pAC->GIni.GP[Port]; - - if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO && - (IStatus & (XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND)) != 0) { - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegLipa: AutoNeg detected on Port %d, IStatus=0x%04x\n", - Port, IStatus)); - pPrt->PLipaAutoNeg = SK_LIPA_AUTO; - } -} /* SkXmAutoNegLipaXmac */ - - -/****************************************************************************** - * - * SkMacAutoNegLipaPhy() - Decides whether Link Partner could do auto-neg - * - * This function analyses the PHY status word. - * If any of the Auto-negotiating bits are set, the PLipaAutoNeg variable - * is set true. - */ -void SkMacAutoNegLipaPhy( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_U16 PhyStat) /* PHY Status word to analyse */ -{ - SK_GEPORT *pPrt; - - pPrt = &pAC->GIni.GP[Port]; - - if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO && - (PhyStat & PHY_ST_AN_OVER) != 0) { - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegLipa: AutoNeg detected on Port %d, PhyStat=0x%04x\n", - Port, PhyStat)); - pPrt->PLipaAutoNeg = SK_LIPA_AUTO; - } -} /* SkMacAutoNegLipaPhy */ -#endif /* SK_DIAG */ - - -/****************************************************************************** - * - * SkXmAutoNegDoneXmac() - Auto-negotiation handling - * - * Description: - * This function handles the auto-negotiation if the Done bit is set. - * - * Returns: - * SK_AND_OK o.k. - * SK_AND_DUP_CAP Duplex capability error happened - * SK_AND_OTHER Other error happened - */ -static int SkXmAutoNegDoneXmac( +static int SkXmAutoNegDoneXmac( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -2844,7 +2946,7 @@ SK_U16 LPAb; /* Link Partner Ability */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegDoneXmac, Port %d\n",Port)); + ("AutoNegDoneXmac, Port %d\n", Port)); pPrt = &pAC->GIni.GP[Port]; @@ -2863,10 +2965,10 @@ /* Check Duplex mismatch */ if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_FD) { - pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL; } else if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_HD) { - pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; } else { /* Error */ @@ -2899,7 +3001,7 @@ /* PAUSE mismatch -> no PAUSE */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; } - pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS; + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; return(SK_AND_OK); } /* SkXmAutoNegDoneXmac */ @@ -2926,7 +3028,7 @@ SK_U16 LPAb; /* Link Partner Ability */ SK_U16 AuxStat; /* Auxiliary Status */ -#if 0 +#ifdef TEST_ONLY 01-Sep-2000 RA;:;: SK_U16 ResAb; /* Resolved Ability */ #endif /* 0 */ @@ -2937,7 +3039,7 @@ /* Get PHY parameters */ SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LPAb); -#if 0 +#ifdef TEST_ONLY 01-Sep-2000 RA;:;: SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb); #endif /* 0 */ @@ -2954,10 +3056,10 @@ /* Check Duplex mismatch */ if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000FD) { - pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL; } else if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000HD) { - pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; } else { /* Error */ @@ -2967,7 +3069,7 @@ return(SK_AND_DUP_CAP); } -#if 0 +#ifdef TEST_ONLY 01-Sep-2000 RA;:;: /* Check Master/Slave resolution */ if ((ResAb & PHY_B_1000S_MSF) != 0) { @@ -2982,7 +3084,7 @@ SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; #endif /* 0 */ - /* Check PAUSE mismatch */ + /* Check PAUSE mismatch ??? */ /* We are using IEEE 802.3z/D5.0 Table 37-4 */ if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PAUSE_MSK) { /* Symmetric PAUSE */ @@ -3000,12 +3102,14 @@ /* PAUSE mismatch -> no PAUSE */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; } - pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS; + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; return(SK_AND_OK); } /* SkXmAutoNegDoneBcom */ +#endif /* GENESIS */ +#ifdef YUKON /****************************************************************************** * * SkGmAutoNegDoneMarv() - Auto-negotiation handling @@ -3034,8 +3138,10 @@ /* Get PHY parameters */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Link P.Abil.=0x%04X\n", LPAb)); - if ((LPAb & PHY_B_AN_RF) != 0) { + if ((LPAb & PHY_M_AN_RF) != 0) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNegFail: Remote fault bit set Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; @@ -3062,20 +3168,20 @@ /* Check Speed & Duplex resolved */ if ((AuxStat & PHY_M_PS_SPDUP_RES) == 0) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegFail: Speed & Duplex not resolved Port %d\n", Port)); + ("AutoNegFail: Speed & Duplex not resolved, Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; - pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; return(SK_AND_DUP_CAP); } if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) { - pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL; } else { - pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; } - /* Check PAUSE mismatch */ + /* Check PAUSE mismatch ??? */ /* We are using IEEE 802.3z/D5.0 Table 37-4 */ if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_PAUSE_MSK) { /* Symmetric PAUSE */ @@ -3097,17 +3203,18 @@ /* set used link speed */ switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) { case (unsigned)PHY_M_PS_SPEED_1000: - pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS; + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; break; case PHY_M_PS_SPEED_100: - pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_100MBPS; + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS; break; default: - pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_10MBPS; + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS; } return(SK_AND_OK); } /* SkGmAutoNegDoneMarv */ +#endif /* YUKON */ #ifdef OTHER_PHY @@ -3134,7 +3241,7 @@ SK_U16 QuickStat; /* Auxiliary Status */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegDoneLone, Port %d\n",Port)); + ("AutoNegDoneLone, Port %d\n", Port)); pPrt = &pAC->GIni.GP[Port]; /* Get PHY parameters */ @@ -3153,10 +3260,10 @@ /* Check Duplex mismatch */ if ((QuickStat & PHY_L_QS_DUP_MOD) != 0) { - pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL; } else { - pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; } /* Check Master/Slave resolution */ @@ -3179,6 +3286,7 @@ /* We are using IEEE 802.3z/D5.0 Table 37-4 */ /* we must manually resolve the abilities here */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; + switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: /* default */ @@ -3258,35 +3366,49 @@ SK_GEPORT *pPrt; int Rtv; + Rtv = SK_AND_OK; + pPrt = &pAC->GIni.GP[Port]; - switch (pPrt->PhyType) { - case SK_PHY_XMAC: - Rtv = SkXmAutoNegDoneXmac(pAC, IoC, Port); - break; - case SK_PHY_BCOM: - Rtv = SkXmAutoNegDoneBcom(pAC, IoC, Port); - break; - case SK_PHY_MARV_COPPER: - case SK_PHY_MARV_FIBER: - Rtv = SkGmAutoNegDoneMarv(pAC, IoC, Port); - break; +#ifdef GENESIS + if (pAC->GIni.GIGenesis) { + + switch (pPrt->PhyType) { + + case SK_PHY_XMAC: + Rtv = SkXmAutoNegDoneXmac(pAC, IoC, Port); + break; + case SK_PHY_BCOM: + Rtv = SkXmAutoNegDoneBcom(pAC, IoC, Port); + break; #ifdef OTHER_PHY - case SK_PHY_LONE: - Rtv = SkXmAutoNegDoneLone(pAC, IoC, Port); - break; - case SK_PHY_NAT: - Rtv = SkXmAutoNegDoneNat(pAC, IoC, Port); - break; + case SK_PHY_LONE: + Rtv = SkXmAutoNegDoneLone(pAC, IoC, Port); + break; + case SK_PHY_NAT: + Rtv = SkXmAutoNegDoneNat(pAC, IoC, Port); + break; #endif /* OTHER_PHY */ - default: - return(SK_AND_OTHER); + default: + return(SK_AND_OTHER); + } } +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { + + Rtv = SkGmAutoNegDoneMarv(pAC, IoC, Port); + } +#endif /* YUKON */ if (Rtv != SK_AND_OK) { return(Rtv); } + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNeg done Port %d\n", Port)); + /* We checked everything and may now enable the link */ pPrt->PAutoNegFail = SK_FALSE; @@ -3296,6 +3418,7 @@ } /* SkMacAutoNegDone */ +#ifdef GENESIS /****************************************************************************** * * SkXmSetRxTxEn() - Special Set Rx/Tx Enable and some features in XMAC @@ -3349,8 +3472,10 @@ XM_IN16(IoC, Port, XM_MMU_CMD, &Word); } /* SkXmSetRxTxEn */ +#endif /* GENESIS */ +#ifdef YUKON /****************************************************************************** * * SkGmSetRxTxEn() - Special Set Rx/Tx Enable and some features in GMAC @@ -3389,14 +3514,17 @@ break; } - GM_OUT16(IoC, Port, GM_GP_CTRL, Ctrl | GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); + GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Ctrl | GM_GPCR_RX_ENA | + GM_GPCR_TX_ENA)); /* dummy read to ensure writing */ GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl); } /* SkGmSetRxTxEn */ +#endif /* YUKON */ +#ifndef SK_SLIM /****************************************************************************** * * SkMacSetRxTxEn() - Special Set Rx/Tx Enable and parameters @@ -3411,16 +3539,22 @@ int Port, /* Port Index (MAC_1 + n) */ int Para) { +#ifdef GENESIS if (pAC->GIni.GIGenesis) { SkXmSetRxTxEn(pAC, IoC, Port, Para); } - else { +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { SkGmSetRxTxEn(pAC, IoC, Port, Para); } +#endif /* YUKON */ } /* SkMacSetRxTxEn */ +#endif /* !SK_SLIM */ /****************************************************************************** @@ -3441,7 +3575,9 @@ SK_GEPORT *pPrt; SK_U16 Reg; /* 16-bit register value */ SK_U16 IntMask; /* MAC interrupt mask */ +#ifdef GENESIS SK_U16 SWord; +#endif pPrt = &pAC->GIni.GP[Port]; @@ -3458,6 +3594,7 @@ return(0); } +#ifdef GENESIS if (pAC->GIni.GIGenesis) { /* set Duplex Mode and Pause Mode */ SkXmInitDupMd(pAC, IoC, Port); @@ -3505,7 +3642,8 @@ SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord); SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, (SK_U16)(SWord & ~PHY_B_AC_DIS_PM)); - SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, + (SK_U16)PHY_B_DEF_MSK); break; #ifdef OTHER_PHY case SK_PHY_LONE: @@ -3522,7 +3660,10 @@ /* enable Rx/Tx */ XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX); } - else { +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { /* * Initialize the Interrupt Mask Register. Default IRQs are... * - Rx Counter Event Overflow @@ -3548,13 +3689,16 @@ } /* enable Rx/Tx */ - GM_OUT16(IoC, Port, GM_GP_CTRL, Reg | GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); + GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Reg | GM_GPCR_RX_ENA | + GM_GPCR_TX_ENA)); #ifndef VCPU /* Enable all PHY interrupts */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, + (SK_U16)PHY_M_DEF_MSK); #endif /* VCPU */ } +#endif /* YUKON */ return(0); @@ -3576,6 +3720,7 @@ { SK_U16 Word; +#ifdef GENESIS if (pAC->GIni.GIGenesis) { XM_IN16(IoC, Port, XM_MMU_CMD, &Word); @@ -3585,15 +3730,21 @@ /* dummy read to ensure writing */ XM_IN16(IoC, Port, XM_MMU_CMD, &Word); } - else { +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { GM_IN16(IoC, Port, GM_GP_CTRL, &Word); - GM_OUT16(IoC, Port, GM_GP_CTRL, Word & ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA)); + GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Word & ~(GM_GPCR_RX_ENA | + GM_GPCR_TX_ENA))); /* dummy read to ensure writing */ GM_IN16(IoC, Port, GM_GP_CTRL, &Word); } +#endif /* YUKON */ + } /* SkMacRxTxDisable */ @@ -3611,10 +3762,13 @@ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; +#ifdef GENESIS SK_U16 Word; +#endif pPrt = &pAC->GIni.GP[Port]; +#ifdef GENESIS if (pAC->GIni.GIGenesis) { /* disable all XMAC IRQs */ @@ -3645,7 +3799,10 @@ #endif /* OTHER_PHY */ } } - else { +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { /* disable all GMAC IRQs */ SK_OUT8(IoC, GMAC_IRQ_MSK, 0); @@ -3654,6 +3811,8 @@ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0); #endif /* VCPU */ } +#endif /* YUKON */ + } /* SkMacIrqDisable */ @@ -3686,7 +3845,8 @@ /* setup Mode Register */ XM_OUT32(IoC, Port, XM_MODE, MdReg); -} /* SkXmSendCont*/ +} /* SkXmSendCont */ + /****************************************************************************** * @@ -3727,12 +3887,74 @@ TimeCtrl = GMT_ST_STOP | GMT_ST_CLR_IRQ; } /* Start/Stop Time Stamp Timer */ - SK_OUT8(pAC, GMAC_TI_ST_CTRL, TimeCtrl); + SK_OUT8(IoC, GMAC_TI_ST_CTRL, TimeCtrl); } + } /* SkMacTimeStamp*/ -#else /* SK_DIAG */ +#else /* !SK_DIAG */ +#ifdef GENESIS +/****************************************************************************** + * + * SkXmAutoNegLipaXmac() - Decides whether Link Partner could do auto-neg + * + * This function analyses the Interrupt status word. If any of the + * Auto-negotiating interrupt bits are set, the PLipaAutoNeg variable + * is set true. + */ +void SkXmAutoNegLipaXmac( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +SK_U16 IStatus) /* Interrupt Status word to analyse */ +{ + SK_GEPORT *pPrt; + + pPrt = &pAC->GIni.GP[Port]; + + if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO && + (IStatus & (XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND)) != 0) { + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNegLipa: AutoNeg detected on Port %d, IStatus=0x%04X\n", + Port, IStatus)); + pPrt->PLipaAutoNeg = SK_LIPA_AUTO; + } +} /* SkXmAutoNegLipaXmac */ +#endif /* GENESIS */ + + +/****************************************************************************** + * + * SkMacAutoNegLipaPhy() - Decides whether Link Partner could do auto-neg + * + * This function analyses the PHY status word. + * If any of the Auto-negotiating bits are set, the PLipaAutoNeg variable + * is set true. + */ +void SkMacAutoNegLipaPhy( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +SK_U16 PhyStat) /* PHY Status word to analyse */ +{ + SK_GEPORT *pPrt; + + pPrt = &pAC->GIni.GP[Port]; + + if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO && + (PhyStat & PHY_ST_AN_OVER) != 0) { + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNegLipa: AutoNeg detected on Port %d, PhyStat=0x%04X\n", + Port, PhyStat)); + pPrt->PLipaAutoNeg = SK_LIPA_AUTO; + } +} /* SkMacAutoNegLipaPhy */ + + +#ifdef GENESIS /****************************************************************************** * * SkXmIrq() - Interrupt Service Routine @@ -3761,6 +3983,9 @@ SK_EVPARA Para; SK_U16 IStatus; /* Interrupt status read from the XMAC */ SK_U16 IStatus2; +#ifdef SK_SLIM + SK_U64 OverflowStatus; +#endif pPrt = &pAC->GIni.GP[Port]; @@ -3778,7 +4003,7 @@ } SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("XmacIrq Port %d Isr 0x%04x\n", Port, IStatus)); + ("XmacIrq Port %d Isr 0x%04X\n", Port, IStatus)); if (!pPrt->PHWLinkUp) { /* Spurious XMAC interrupt */ @@ -3792,7 +4017,7 @@ XM_IN16(IoC, Port, XM_ISRC, &IStatus2); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("SkXmIrq: Link async. Double check Port %d 0x%04x 0x%04x\n", + ("SkXmIrq: Link async. Double check Port %d 0x%04X 0x%04X\n", Port, IStatus, IStatus2)); IStatus &= ~XM_IS_INP_ASS; IStatus |= IStatus2; @@ -3841,14 +4066,20 @@ /* Combined Tx & Rx Counter Overflow SIRQ Event */ if ((IStatus & (XM_IS_RXC_OV | XM_IS_TXC_OV)) != 0) { +#ifdef SK_SLIM + SkXmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus); +#else Para.Para32[0] = (SK_U32)Port; Para.Para32[1] = (SK_U32)IStatus; SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para); +#endif /* SK_SLIM */ } if ((IStatus & XM_IS_RXF_OV) != 0) { /* normal situation -> no effect */ +#ifdef DEBUG pPrt->PRxOverCnt++; +#endif /* DEBUG */ } if ((IStatus & XM_IS_TXF_UR) != 0) { @@ -3864,8 +4095,10 @@ /* not served here */ } } /* SkXmIrq */ +#endif /* GENESIS */ +#ifdef YUKON /****************************************************************************** * * SkGmIrq() - Interrupt Service Routine @@ -3883,32 +4116,43 @@ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; - SK_EVPARA Para; SK_U8 IStatus; /* Interrupt status */ +#ifdef SK_SLIM + SK_U64 OverflowStatus; +#else + SK_EVPARA Para; +#endif pPrt = &pAC->GIni.GP[Port]; SK_IN8(IoC, GMAC_IRQ_SRC, &IStatus); +#ifdef XXX /* LinkPartner Auto-negable? */ SkMacAutoNegLipaPhy(pAC, IoC, Port, IStatus); +#endif /* XXX */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("GmacIrq Port %d Isr 0x%04x\n", Port, IStatus)); + ("GmacIrq Port %d Isr 0x%04X\n", Port, IStatus)); /* Combined Tx & Rx Counter Overflow SIRQ Event */ if (IStatus & (GM_IS_RX_CO_OV | GM_IS_TX_CO_OV)) { /* these IRQs will be cleared by reading GMACs register */ +#ifdef SK_SLIM + SkGmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus); +#else Para.Para32[0] = (SK_U32)Port; Para.Para32[1] = (SK_U32)IStatus; SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para); +#endif } if (IStatus & GM_IS_RX_FF_OR) { /* clear GMAC Rx FIFO Overrun IRQ */ SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_CLI_RX_FO); - +#ifdef DEBUG pPrt->PRxOverCnt++; +#endif /* DEBUG */ } if (IStatus & GM_IS_TX_FF_UR) { @@ -3926,6 +4170,8 @@ /* not served here */ } } /* SkGmIrq */ +#endif /* YUKON */ + /****************************************************************************** * @@ -3941,19 +4187,25 @@ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ { - +#ifdef GENESIS if (pAC->GIni.GIGenesis) { /* IRQ from XMAC */ SkXmIrq(pAC, IoC, Port); } - else { +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { /* IRQ from GMAC */ SkGmIrq(pAC, IoC, Port); } +#endif /* YUKON */ + } /* SkMacIrq */ #endif /* !SK_DIAG */ +#ifdef GENESIS /****************************************************************************** * * SkXmUpdateStats() - Force the XMAC to output the current statistic @@ -4003,24 +4255,6 @@ return(0); } /* SkXmUpdateStats */ -/****************************************************************************** - * - * SkGmUpdateStats() - Force the GMAC to output the current statistic - * - * Description: - * Empty function for GMAC. Statistic data is accessible in direct way. - * - * Returns: - * 0: success - * 1: something went wrong - */ -int SkGmUpdateStats( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -unsigned int Port) /* Port Index (MAC_1 + n) */ -{ - return(0); -} /****************************************************************************** * @@ -4036,11 +4270,11 @@ * 1: something went wrong */ int SkXmMacStatistic( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -unsigned int Port, /* Port Index (MAC_1 + n) */ -SK_U16 StatAddr, /* MIB counter base address */ -SK_U32 *pVal) /* ptr to return statistic value */ +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +unsigned int Port, /* Port Index (MAC_1 + n) */ +SK_U16 StatAddr, /* MIB counter base address */ +SK_U32 SK_FAR *pVal) /* ptr to return statistic value */ { if ((StatAddr < XM_TXF_OK) || (StatAddr > XM_RXF_MAX_SZ)) { @@ -4054,63 +4288,137 @@ return(0); } /* SkXmMacStatistic */ + /****************************************************************************** * - * SkGmMacStatistic() - Get GMAC counter value + * SkXmResetCounter() - Clear MAC statistic counter * * Description: - * Gets the 32bit counter value. Except for the octet counters - * the lower 32bit are counted in hardware and the upper 32bit - * must be counted in software by monitoring counter overflow interrupts. + * Force the XMAC to clear its statistic counter. * * Returns: * 0: success * 1: something went wrong */ -int SkGmMacStatistic( +int SkXmResetCounter( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ -unsigned int Port, /* Port Index (MAC_1 + n) */ -SK_U16 StatAddr, /* MIB counter base address */ -SK_U32 *pVal) /* ptr to return statistic value */ +unsigned int Port) /* Port Index (MAC_1 + n) */ { + XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC); + /* Clear two times according to Errata #3 */ + XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC); - if ((StatAddr < GM_RXF_UC_OK) || (StatAddr > GM_TXE_FIFO_UR)) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG); - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("SkGmMacStat: wrong MIB counter 0x%04X\n", StatAddr)); - return(1); + return(0); +} /* SkXmResetCounter */ + + +/****************************************************************************** + * + * SkXmOverflowStatus() - Gets the status of counter overflow interrupt + * + * Description: + * Checks the source causing an counter overflow interrupt. On success the + * resulting counter overflow status is written to , whereas the + * upper dword stores the XMAC ReceiveCounterEvent register and the lower + * dword the XMAC TransmitCounterEvent register. + * + * Note: + * For XMAC the interrupt source is a self-clearing register, so the source + * must be checked only once. SIRQ module does another check to be sure + * that no interrupt get lost during process time. + * + * Returns: + * 0: success + * 1: something went wrong + */ +int SkXmOverflowStatus( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +unsigned int Port, /* Port Index (MAC_1 + n) */ +SK_U16 IStatus, /* Interupt Status from MAC */ +SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */ +{ + SK_U64 Status; /* Overflow status */ + SK_U32 RegVal; + + Status = 0; + + if ((IStatus & XM_IS_RXC_OV) != 0) { + + XM_IN32(IoC, Port, XM_RX_CNT_EV, &RegVal); + Status |= (SK_U64)RegVal << 32; + } + + if ((IStatus & XM_IS_TXC_OV) != 0) { + + XM_IN32(IoC, Port, XM_TX_CNT_EV, &RegVal); + Status |= (SK_U64)RegVal; } - - GM_IN32(IoC, Port, StatAddr, pVal); + + *pStatus = Status; return(0); -} /* SkGmMacStatistic */ +} /* SkXmOverflowStatus */ +#endif /* GENESIS */ + +#ifdef YUKON /****************************************************************************** * - * SkXmResetCounter() - Clear MAC statistic counter + * SkGmUpdateStats() - Force the GMAC to output the current statistic * * Description: - * Force the XMAC to clear its statistic counter. + * Empty function for GMAC. Statistic data is accessible in direct way. * * Returns: * 0: success * 1: something went wrong */ -int SkXmResetCounter( +int SkGmUpdateStats( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ unsigned int Port) /* Port Index (MAC_1 + n) */ { - XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC); - /* Clear two times according to Errata #3 */ - XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC); + return(0); +} + + +/****************************************************************************** + * + * SkGmMacStatistic() - Get GMAC counter value + * + * Description: + * Gets the 32bit counter value. Except for the octet counters + * the lower 32bit are counted in hardware and the upper 32bit + * must be counted in software by monitoring counter overflow interrupts. + * + * Returns: + * 0: success + * 1: something went wrong + */ +int SkGmMacStatistic( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +unsigned int Port, /* Port Index (MAC_1 + n) */ +SK_U16 StatAddr, /* MIB counter base address */ +SK_U32 SK_FAR *pVal) /* ptr to return statistic value */ +{ + + if ((StatAddr < GM_RXF_UC_OK) || (StatAddr > GM_TXE_FIFO_UR)) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("SkGmMacStat: wrong MIB counter 0x%04X\n", StatAddr)); + return(1); + } + + GM_IN32(IoC, Port, StatAddr, pVal); return(0); -} /* SkXmResetCounter */ +} /* SkGmMacStatistic */ + /****************************************************************************** * @@ -4134,7 +4442,6 @@ GM_IN16(IoC, Port, GM_PHY_ADDR, &Reg); -#ifndef VCPU /* set MIB Clear Counter Mode */ GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg | GM_PAR_MIB_CLR); @@ -4146,59 +4453,10 @@ /* clear MIB Clear Counter Mode */ GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg); -#endif /* !VCPU */ return(0); } /* SkGmResetCounter */ -/****************************************************************************** - * - * SkXmOverflowStatus() - Gets the status of counter overflow interrupt - * - * Description: - * Checks the source causing an counter overflow interrupt. On success the - * resulting counter overflow status is written to , whereas the - * upper dword stores the XMAC ReceiveCounterEvent register and the lower - * dword the XMAC TransmitCounterEvent register. - * - * Note: - * For XMAC the interrupt source is a self-clearing register, so the source - * must be checked only once. SIRQ module does another check to be sure - * that no interrupt get lost during process time. - * - * Returns: - * 0: success - * 1: something went wrong - */ -int SkXmOverflowStatus( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -unsigned int Port, /* Port Index (MAC_1 + n) */ -SK_U16 IStatus, /* Interupt Status from MAC */ -SK_U64 *pStatus) /* ptr for return overflow status value */ -{ - SK_U64 Status; /* Overflow status */ - SK_U32 RegVal; - - Status = 0; - - if ((IStatus & XM_IS_RXC_OV) != 0) { - - XM_IN32(IoC, Port, XM_RX_CNT_EV, &RegVal); - Status |= (SK_U64)RegVal << 32; - } - - if ((IStatus & XM_IS_TXC_OV) != 0) { - - XM_IN32(IoC, Port, XM_TX_CNT_EV, &RegVal); - Status |= (SK_U64)RegVal; - } - - *pStatus = Status; - - return(0); -} /* SkXmOverflowStatus */ - /****************************************************************************** * @@ -4220,11 +4478,11 @@ * 1: something went wrong */ int SkGmOverflowStatus( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -unsigned int Port, /* Port Index (MAC_1 + n) */ -SK_U16 IStatus, /* Interupt Status from MAC */ -SK_U64 *pStatus) /* ptr for return overflow status value */ +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +unsigned int Port, /* Port Index (MAC_1 + n) */ +SK_U16 IStatus, /* Interupt Status from MAC */ +SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */ { SK_U64 Status; /* Overflow status */ SK_U16 RegVal; @@ -4255,6 +4513,8 @@ return(0); } /* SkGmOverflowStatus */ + +#ifndef SK_SLIM /****************************************************************************** * * SkGmCableDiagStatus() - Starts / Gets status of cable diagnostic test @@ -4308,7 +4568,7 @@ /* start Cable Diagnostic Test */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, - RegVal | PHY_M_CABD_ENA_TEST); + (SK_U16)(RegVal | PHY_M_CABD_ENA_TEST)); return(0); } @@ -4339,5 +4599,7 @@ return(0); } /* SkGmCableDiagStatus */ +#endif /* !SK_SLIM */ +#endif /* YUKON */ /* End of file */ Index: drivers/net/sk98lin/h/lm80.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/lm80.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/lm80.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/lm80.h 4 Aug 2004 01:29:22 -0000 1.2 @@ -1,9 +1,7 @@ /****************************************************************************** * * Name: lm80.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ + * Project: Gigabit Ethernet Adapters, Common Modules * Purpose: Contains all defines for the LM80 Chip * (National Semiconductor). * @@ -11,7 +9,8 @@ /****************************************************************************** * - * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,28 +21,6 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * $Log: lm80.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.4 2002/04/25 11:04:10 rschmidt - * Editorial changes - * - * Revision 1.3 1999/11/22 13:41:19 cgoos - * Changed license header to GPL. - * - * Revision 1.2 1999/03/12 13:26:51 malthoff - * remove __STDC__. - * - * Revision 1.1 1998/06/19 09:28:31 malthoff - * created. - * - * - ******************************************************************************/ - #ifndef __INC_LM80_H #define __INC_LM80_H @@ -58,8 +35,8 @@ * * All registers are 8 bit wide */ -#define LM80_CFG 0x00 /* Configuration Register */ -#define LM80_ISRC_1 0x01 /* Interrupt Status Register 1 */ +#define LM80_CFG 0x00 /* Configuration Register */ +#define LM80_ISRC_1 0x01 /* Interrupt Status Register 1 */ #define LM80_ISRC_2 0x02 /* Interrupt Status Register 2 */ #define LM80_IMSK_1 0x03 /* Interrupt Mask Register 1 */ #define LM80_IMSK_2 0x04 /* Interrupt Mask Register 2 */ @@ -96,8 +73,8 @@ #define LM80_THOT_LIM_LO 0x39 /* hot temperature limit (low) */ #define LM80_TOS_LIM_UP 0x3a /* OS temperature limit (high) */ #define LM80_TOS_LIM_LO 0x3b /* OS temperature limit (low) */ -#define LM80_FAN1_COUNT_LIM 0x3c /* Fan 1 count limit (high) */ -#define LM80_FAN2_COUNT_LIM 0x3d /* Fan 2 count limit (low) */ +#define LM80_FAN1_COUNT_LIM 0x3c /* Fan 1 count limit (high) */ +#define LM80_FAN2_COUNT_LIM 0x3d /* Fan 2 count limit (low) */ /* 0x3e - 0x3f reserved */ /* @@ -127,7 +104,7 @@ /* LM80_ISRC_2 Interrupt Status Register 2 */ /* LM80_IMSK_2 Interrupt Mask Register 2 */ -#define LM80_IS_TEMP (1<<0) /* HOT temperature limit exceeded */ +#define LM80_IS_TEMP (1<<0) /* HOT temperature limit exceeded */ #define LM80_IS_BTI (1<<1) /* state of BTI# pin */ #define LM80_IS_FAN1 (1<<2) /* count limit exceeded for Fan 1 */ #define LM80_IS_FAN2 (1<<3) /* count limit exceeded for Fan 2 */ @@ -146,7 +123,7 @@ #define LM80_FAN_RST_ENA (1<<7) /* sets RST_OUT#/OS# pins in RST mode */ /* LM80_TEMP_CTRL OS# Config, Temp Res. Reg */ -#define LM80_TEMP_OS_STAT (1<<0) /* mirrors the state of RST_OUT#/OS# */ +#define LM80_TEMP_OS_STAT (1<<0) /* mirrors the state of RST_OUT#/OS# */ #define LM80_TEMP_OS_POL (1<<1) /* select OS# polarity */ #define LM80_TEMP_OS_MODE (1<<2) /* selects Interrupt mode */ #define LM80_TEMP_RES (1<<3) /* selects 9 or 11 bit temp resulution*/ Index: drivers/net/sk98lin/h/skaddr.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/skaddr.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/skaddr.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/skaddr.h 4 Aug 2004 01:29:22 -0000 1.2 @@ -1,16 +1,15 @@ /****************************************************************************** * * Name: skaddr.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ + * Project: Gigabit Ethernet Adapters, ADDR-Modul * Purpose: Header file for Address Management (MC, UC, Prom). * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2001 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,105 +22,6 @@ /****************************************************************************** * - * History: - * - * $Log: skaddr.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.26 2002/11/15 07:24:42 tschilli - * SK_ADDR_EQUAL macro fixed. - * - * Revision 1.25 2002/06/10 13:55:18 tschilli - * Changes for handling YUKON. - * All changes are internally and not visible to the programmer - * using this module. - * - * Revision 1.24 2001/01/22 13:41:34 rassmann - * Supporting two nets on dual-port adapters. - * - * Revision 1.23 2000/08/10 11:27:50 rassmann - * Editorial changes. - * Preserving 32-bit alignment in structs for the adapter context. - * - * Revision 1.22 2000/08/07 11:10:40 rassmann - * Editorial changes. - * - * Revision 1.21 2000/05/04 09:39:59 rassmann - * Editorial changes. - * Corrected multicast address hashing. - * - * Revision 1.20 1999/11/22 13:46:14 cgoos - * Changed license header to GPL. - * Allowing overwrite for SK_ADDR_EQUAL. - * - * Revision 1.19 1999/05/28 10:56:07 rassmann - * Editorial changes. - * - * Revision 1.18 1999/04/06 17:22:04 rassmann - * Added private "ActivePort". - * - * Revision 1.17 1999/01/14 16:18:19 rassmann - * Corrected multicast initialization. - * - * Revision 1.16 1999/01/04 10:30:36 rassmann - * SkAddrOverride only possible after SK_INIT_IO phase. - * - * Revision 1.15 1998/12/29 13:13:11 rassmann - * An address override is now preserved in the SK_INIT_IO phase. - * All functions return an int now. - * Extended parameter checking. - * - * Revision 1.14 1998/11/24 12:39:45 rassmann - * Reserved multicast entry for BPDU address. - * 13 multicast entries left for protocol. - * - * Revision 1.13 1998/11/13 17:24:32 rassmann - * Changed return value of SkAddrOverride to int. - * - * Revision 1.12 1998/11/13 16:56:19 rassmann - * Added macro SK_ADDR_COMPARE. - * Changed return type of SkAddrOverride to SK_BOOL. - * - * Revision 1.11 1998/10/28 18:16:35 rassmann - * Avoiding I/Os before SK_INIT_RUN level. - * Aligning InexactFilter. - * - * Revision 1.10 1998/10/22 11:39:10 rassmann - * Corrected signed/unsigned mismatches. - * - * Revision 1.9 1998/10/15 15:15:49 rassmann - * Changed Flags Parameters from SK_U8 to int. - * Checked with lint. - * - * Revision 1.8 1998/09/24 19:15:12 rassmann - * Code cleanup. - * - * Revision 1.7 1998/09/18 20:22:13 rassmann - * Added HW access. - * - * Revision 1.6 1998/09/04 19:40:20 rassmann - * Interface enhancements. - * - * Revision 1.5 1998/09/04 12:40:57 rassmann - * Interface cleanup. - * - * Revision 1.4 1998/09/04 12:14:13 rassmann - * Interface cleanup. - * - * Revision 1.3 1998/09/02 16:56:40 rassmann - * Updated interface. - * - * Revision 1.2 1998/08/27 14:26:09 rassmann - * Updated interface. - * - * Revision 1.1 1998/08/21 08:31:08 rassmann - * First public version. - * - ******************************************************************************/ - -/****************************************************************************** - * * Description: * * This module is intended to manage multicast addresses and promiscuous mode @@ -143,7 +43,6 @@ #define __INC_SKADDR_H #ifdef __cplusplus -#error C++ is not yet supported. extern "C" { #endif /* cplusplus */ @@ -209,7 +108,7 @@ /* Macros */ -#if 0 +#ifdef OLD_STUFF #ifndef SK_ADDR_EQUAL /* * "&" instead of "&&" allows better optimization on IA-64. @@ -234,16 +133,18 @@ #ifndef SK_ADDR_EQUAL #ifndef SK_ADDR_DWORD_COMPARE #define SK_ADDR_EQUAL(A1,A2) ( \ - (((SK_U8 *)(A1))[5] == ((SK_U8 *)(A2))[5]) & \ - (((SK_U8 *)(A1))[4] == ((SK_U8 *)(A2))[4]) & \ - (((SK_U8 *)(A1))[3] == ((SK_U8 *)(A2))[3]) & \ - (((SK_U8 *)(A1))[2] == ((SK_U8 *)(A2))[2]) & \ - (((SK_U8 *)(A1))[1] == ((SK_U8 *)(A2))[1]) & \ - (((SK_U8 *)(A1))[0] == ((SK_U8 *)(A2))[0])) + (((SK_U8 SK_FAR *)(A1))[5] == ((SK_U8 SK_FAR *)(A2))[5]) & \ + (((SK_U8 SK_FAR *)(A1))[4] == ((SK_U8 SK_FAR *)(A2))[4]) & \ + (((SK_U8 SK_FAR *)(A1))[3] == ((SK_U8 SK_FAR *)(A2))[3]) & \ + (((SK_U8 SK_FAR *)(A1))[2] == ((SK_U8 SK_FAR *)(A2))[2]) & \ + (((SK_U8 SK_FAR *)(A1))[1] == ((SK_U8 SK_FAR *)(A2))[1]) & \ + (((SK_U8 SK_FAR *)(A1))[0] == ((SK_U8 SK_FAR *)(A2))[0])) #else /* SK_ADDR_DWORD_COMPARE */ #define SK_ADDR_EQUAL(A1,A2) ( \ - (*(SK_U16 *)&(((SK_U8 *)(A1))[4]) == *(SK_U16 *)&(((SK_U8 *)(A2))[4])) && \ - (*(SK_U32 *)&(((SK_U8 *)(A1))[0]) == *(SK_U32 *)&(((SK_U8 *)(A2))[0]))) + (*(SK_U16 SK_FAR *)&(((SK_U8 SK_FAR *)(A1))[4]) == \ + *(SK_U16 SK_FAR *)&(((SK_U8 SK_FAR *)(A2))[4])) && \ + (*(SK_U32 SK_FAR *)&(((SK_U8 SK_FAR *)(A1))[0]) == \ + *(SK_U32 SK_FAR *)&(((SK_U8 SK_FAR *)(A2))[0]))) #endif /* SK_ADDR_DWORD_COMPARE */ #endif /* SK_ADDR_EQUAL */ @@ -385,7 +286,7 @@ SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, - SK_MAC_ADDR *pNewAddr, + SK_MAC_ADDR SK_FAR *pNewAddr, int Flags); extern int SkAddrPromiscuousChange( @@ -406,11 +307,13 @@ SK_U32 PortNumber, int NewPromMode); +#ifndef SK_SLIM extern int SkAddrSwap( SK_AC *pAC, SK_IOC IoC, SK_U32 FromPortNumber, SK_U32 ToPortNumber); +#endif #else /* defined(SK_KR_PROTO)) */ Index: drivers/net/sk98lin/h/skcsum.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/skcsum.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/skcsum.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/skcsum.h 4 Aug 2004 01:29:22 -0000 1.2 @@ -2,8 +2,6 @@ * * Name: skcsum.h * Project: GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx) - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ * Purpose: Store/verify Internet checksum in send/receive packets. * ******************************************************************************/ @@ -23,51 +21,6 @@ /****************************************************************************** * - * History: - * - * $Log: skcsum.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.9 2001/02/06 11:21:39 rassmann - * Editorial changes. - * - * Revision 1.8 2001/02/06 11:15:36 rassmann - * Supporting two nets on dual-port adapters. - * - * Revision 1.7 2000/06/29 13:17:05 rassmann - * Corrected reception of a packet with UDP checksum == 0 (which means there - * is no UDP checksum). - * - * Revision 1.6 2000/02/28 12:33:44 cgoos - * Changed C++ style comments to C style. - * - * Revision 1.5 2000/02/21 12:10:05 cgoos - * Fixed license comment. - * - * Revision 1.4 2000/02/21 11:08:37 cgoos - * Merged changes back into common source. - * - * Revision 1.1 1999/07/26 14:47:49 mkarl - * changed from common source to windows specific source - * added return SKCS_STATUS_IP_CSUM_ERROR_UDP and - * SKCS_STATUS_IP_CSUM_ERROR_TCP to pass the NidsTester - * changes for Tx csum offload - * - * Revision 1.2 1998/09/04 12:16:34 mhaveman - * Checked in for Stephan to allow compilation. - * -Added definition SK_CSUM_EVENT_CLEAR_PROTO_STATS to clear statistic - * -Added prototype for SkCsEvent() - * - * Revision 1.1 1998/09/01 15:36:53 swolf - * initial revision - * - * 01-Sep-1998 sw Created. - * - ******************************************************************************/ - -/****************************************************************************** - * * Description: * * Public header file for the "GEnesis" common module "CSUM". @@ -229,11 +182,11 @@ /* function prototypes ********************************************************/ -#ifndef SkCsCalculateChecksum +#ifndef SK_CS_CALCULATE_CHECKSUM extern unsigned SkCsCalculateChecksum( void *pData, unsigned Length); -#endif +#endif /* SK_CS_CALCULATE_CHECKSUM */ extern int SkCsEvent( SK_AC *pAc, Index: drivers/net/sk98lin/h/skdebug.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/skdebug.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/skdebug.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/skdebug.h 4 Aug 2004 01:29:22 -0000 1.2 @@ -1,16 +1,15 @@ /****************************************************************************** * * Name: skdebug.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ + * Project: Gigabit Ethernet Adapters, Common Modules * Purpose: SK specific DEBUG support * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,55 +20,6 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * $Log: skdebug.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.12 2002/07/15 15:37:13 rschmidt - * Power Management support - * Editorial changes - * - * Revision 1.11 2002/04/25 11:04:39 rschmidt - * Editorial changes - * - * Revision 1.10 1999/11/22 13:47:40 cgoos - * Changed license header to GPL. - * - * Revision 1.9 1999/09/14 14:02:43 rwahl - * Added SK_DBGMOD_PECP. - * - * Revision 1.8 1998/11/25 08:31:54 gklug - * fix: no C++ comments allowed in common sources - * - * Revision 1.7 1998/11/24 16:47:24 swolf - * Driver may now define its own SK_DBG_MSG() (eg. in "h/skdrv1st.h"). - * - * Revision 1.6 1998/10/28 10:23:55 rassmann - * ADDED SK_DBGMOD_ADDR. - * - * Revision 1.5 1998/10/22 09:43:55 gklug - * add: CSUM module - * - * Revision 1.4 1998/10/01 07:54:44 gklug - * add: PNMI debug module - * - * Revision 1.3 1998/09/18 08:32:34 afischer - * Macros changed according ssr-spec.: - * SK_DBG_MODCHK -> SK_DBG_CHKMOD - * SK_DBG_CATCHK -> SK_DBG_CHKCAT - * - * Revision 1.2 1998/07/03 14:38:25 malthoff - * Add category SK_DBGCAT_FATAL. - * - * Revision 1.1 1998/06/19 13:39:01 malthoff - * created. - * - * - ******************************************************************************/ - #ifndef __INC_SKDEBUG_H #define __INC_SKDEBUG_H Index: drivers/net/sk98lin/h/skdrv1st.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/skdrv1st.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/skdrv1st.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/skdrv1st.h 4 Aug 2004 01:29:22 -0000 1.2 @@ -2,16 +2,14 @@ * * Name: skdrv1st.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ * Purpose: First header file for driver and all other modules * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2001 SysKonnect, - * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,57 +22,6 @@ /****************************************************************************** * - * History: - * - * $Log: skdrv1st.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.9.2.2 2001/12/07 12:06:42 mlindner - * Fix: malloc -> slab changes - * - * Revision 1.9.2.1 2001/03/12 16:50:59 mlindner - * chg: kernel 2.4 adaption - * - * Revision 1.9 2001/01/22 14:16:04 mlindner - * added ProcFs functionality - * Dual Net functionality integrated - * Rlmt networks added - * - * Revision 1.8 2000/02/21 12:19:18 cgoos - * Added default for SK_DEBUG_CHKMOD/_CHKCAT - * - * Revision 1.7 1999/11/22 13:50:00 cgoos - * Changed license header to GPL. - * Added overwrite for several functions. - * Removed linux 2.0.x definitions. - * Removed PCI vendor ID definition (now in kernel). - * - * Revision 1.6 1999/07/27 08:03:33 cgoos - * Changed SK_IN/OUT macros to readX/writeX instead of memory - * accesses (necessary for ALPHA). - * - * Revision 1.5 1999/07/23 12:10:21 cgoos - * Removed SK_RLMT_SLOW_LOOKAHEAD define. - * - * Revision 1.4 1999/07/14 12:31:13 cgoos - * Added SK_RLMT_SLOW_LOOKAHEAD define. - * - * Revision 1.3 1999/04/07 10:12:54 cgoos - * Added check for KERNEL and OPTIMIZATION defines. - * - * Revision 1.2 1999/03/01 08:51:47 cgoos - * Fixed pcibios_read/write definitions. - * - * Revision 1.1 1999/02/16 07:40:49 cgoos - * First version. - * - * - * - ******************************************************************************/ - -/****************************************************************************** - * * Description: * * This is the first include file of the driver, which includes all @@ -92,25 +39,23 @@ /* Check kernel version */ #include -#if (LINUX_VERSION_CODE > 0x020300) -#endif typedef struct s_AC SK_AC; +/* Set card versions */ +#define SK_FAR + /* override some default functions with optimized linux functions */ #define SK_PNMI_STORE_U16(p,v) memcpy((char*)(p),(char*)&(v),2) #define SK_PNMI_STORE_U32(p,v) memcpy((char*)(p),(char*)&(v),4) #define SK_PNMI_STORE_U64(p,v) memcpy((char*)(p),(char*)&(v),8) #define SK_PNMI_READ_U16(p,v) memcpy((char*)&(v),(char*)(p),2) -#define SK_PNMI_READ_U32(p,v) memcpy((char*)&(v),(char*)(p),2) -#define SK_PNMI_READ_U64(p,v) memcpy((char*)&(v),(char*)(p),2) - -#define SkCsCalculateChecksum(p,l) ((~ip_compute_csum(p, l)) & 0xffff) +#define SK_PNMI_READ_U32(p,v) memcpy((char*)&(v),(char*)(p),4) +#define SK_PNMI_READ_U64(p,v) memcpy((char*)&(v),(char*)(p),8) #define SK_ADDR_EQUAL(a1,a2) (!memcmp(a1,a2,6)) - #if !defined(__OPTIMIZE__) || !defined(__KERNEL__) #warning You must compile this file with the correct options! #warning See the last lines of the source file. @@ -137,6 +82,13 @@ #include #include +#define SK_CS_CALCULATE_CHECKSUM +#ifndef CONFIG_X86_64 +#define SkCsCalculateChecksum(p,l) ((~ip_compute_csum(p, l)) & 0xffff) +#else +#define SkCsCalculateChecksum(p,l) ((~ip_fast_csum(p, l)) & 0xffff) +#endif + #include "h/sktypes.h" #include "h/skerror.h" #include "h/skdebug.h" @@ -153,7 +105,7 @@ /* we use gethrtime(), return unit: nanoseconds */ -#define SK_TICKS_PER_SEC HZ +#define SK_TICKS_PER_SEC 100 #define SK_MEM_MAPPED_IO Index: drivers/net/sk98lin/h/skdrv2nd.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/skdrv2nd.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/skdrv2nd.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/skdrv2nd.h 4 Aug 2004 01:29:22 -0000 1.2 @@ -2,16 +2,14 @@ * * Name: skdrv2nd.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ * Purpose: Second header file for driver and all other modules * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2001 SysKonnect, - * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,70 +22,6 @@ /****************************************************************************** * - * History: - * - * $Log: skdrv2nd.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.12.2.2 2001/09/05 12:14:50 mlindner - * add: New hardware revision int - * - * Revision 1.12.2.1 2001/03/12 16:50:59 mlindner - * chg: kernel 2.4 adaption - * - * Revision 1.12 2001/03/01 12:52:15 mlindner - * Fixed ring size - * - * Revision 1.11 2001/02/19 13:28:02 mlindner - * Changed PNMI parameter values - * - * Revision 1.10 2001/01/22 14:16:04 mlindner - * added ProcFs functionality - * Dual Net functionality integrated - * Rlmt networks added - * - * Revision 1.1 2000/10/05 19:46:50 phargrov - * Add directory src/vipk_devs_nonlbl/vipk_sk98lin/ - * This is the SysKonnect SK-98xx Gigabit Ethernet driver, - * contributed by SysKonnect. - * - * Revision 1.9 2000/02/21 10:39:55 cgoos - * Added flag for jumbo support usage. - * - * Revision 1.8 1999/11/22 13:50:44 cgoos - * Changed license header to GPL. - * Fixed two comments. - * - * Revision 1.7 1999/09/28 12:38:21 cgoos - * Added CheckQueue to SK_AC. - * - * Revision 1.6 1999/07/27 08:04:05 cgoos - * Added checksumming variables to SK_AC. - * - * Revision 1.5 1999/03/29 12:33:26 cgoos - * Rreversed to fine lock granularity. - * - * Revision 1.4 1999/03/15 12:14:02 cgoos - * Added DriverLock to SK_AC. - * Removed other locks. - * - * Revision 1.3 1999/03/01 08:52:27 cgoos - * Changed pAC->PciDev declaration. - * - * Revision 1.2 1999/02/18 10:57:14 cgoos - * Removed SkDrvTimeStamp prototype. - * Fixed SkGeOsGetTime prototype. - * - * Revision 1.1 1999/02/16 07:41:01 cgoos - * First version. - * - * - * - ******************************************************************************/ - -/****************************************************************************** - * * Description: * * This is the second include file of the driver, which includes all other @@ -117,7 +51,54 @@ #include "h/skrlmt.h" #include "h/skgedrv.h" -/* global function prototypes ******************************************/ +#define SK_PCI_ISCOMPLIANT(result, pdev) { \ + result = SK_FALSE; /* default */ \ + /* 3Com (0x10b7) */ \ + if (pdev->vendor == 0x10b7) { \ + /* Gigabit Ethernet Adapter (0x1700) */ \ + if ((pdev->device == 0x1700)) { \ + result = SK_TRUE; \ + } \ + /* SysKonnect (0x1148) */ \ + } else if (pdev->vendor == 0x1148) { \ + /* SK-98xx Gigabit Ethernet Server Adapter (0x4300) */ \ + /* SK-98xx V2.0 Gigabit Ethernet Adapter (0x4320) */ \ + if ((pdev->device == 0x4300) || \ + (pdev->device == 0x4320)) { \ + result = SK_TRUE; \ + } \ + /* D-Link (0x1186) */ \ + } else if (pdev->vendor == 0x1186) { \ + /* Gigabit Ethernet Adapter (0x4c00) */ \ + if ((pdev->device == 0x4c00)) { \ + result = SK_TRUE; \ + } \ + /* Marvell (0x11ab) */ \ + } else if (pdev->vendor == 0x11ab) { \ + /* Gigabit Ethernet Adapter (0x4320) */ \ + if ((pdev->device == 0x4320)) { \ + result = SK_TRUE; \ + } \ + /* CNet (0x1371) */ \ + } else if (pdev->vendor == 0x1371) { \ + /* GigaCard Network Adapter (0x434e) */ \ + if ((pdev->device == 0x434e)) { \ + result = SK_TRUE; \ + } \ + /* Linksys (0x1737) */ \ + } else if (pdev->vendor == 0x1737) { \ + /* Gigabit Network Adapter (0x1032) */ \ + /* Gigabit Network Adapter (0x1064) */ \ + if ((pdev->device == 0x1032) || \ + (pdev->device == 0x1064)) { \ + result = SK_TRUE; \ + } \ + } else { \ + result = SK_FALSE; \ + } \ +} + + extern SK_MBUF *SkDrvAllocRlmtMbuf(SK_AC*, SK_IOC, unsigned); extern void SkDrvFreeRlmtMbuf(SK_AC*, SK_IOC, SK_MBUF*); extern SK_U64 SkOsGetTime(SK_AC*); @@ -129,6 +110,11 @@ extern int SkPciWriteCfgByte(SK_AC*, int, SK_U8); extern int SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA); +#ifdef SK_DIAG_SUPPORT +extern int SkDrvEnterDiagMode(SK_AC *pAc); +extern int SkDrvLeaveDiagMode(SK_AC *pAc); +#endif + struct s_DrvRlmtMbuf { SK_MBUF *pNext; /* Pointer to next RLMT Mbuf. */ SK_U8 *pData; /* Data buffer (virtually contig.). */ @@ -142,6 +128,25 @@ }; +/* + * Time macros + */ +#if SK_TICKS_PER_SEC == 100 +#define SK_PNMI_HUNDREDS_SEC(t) (t) +#else +#define SK_PNMI_HUNDREDS_SEC(t) ((((unsigned long)t) * 100) / \ + (SK_TICKS_PER_SEC)) +#endif + +/* + * New SkOsGetTime + */ +#define SkOsGetTimeCurrent(pAC, pUsec) {\ + struct timeval t;\ + do_gettimeofday(&t);\ + *pUsec = ((((t.tv_sec) * 1000000L)+t.tv_usec)/10000);\ +} + /* * ioctl definitions @@ -150,6 +155,8 @@ #define SK_IOCTL_GETMIB (SK_IOCTL_BASE + 0) #define SK_IOCTL_SETMIB (SK_IOCTL_BASE + 1) #define SK_IOCTL_PRESETMIB (SK_IOCTL_BASE + 2) +#define SK_IOCTL_GEN (SK_IOCTL_BASE + 3) +#define SK_IOCTL_DIAG (SK_IOCTL_BASE + 4) typedef struct s_IOCTL SK_GE_IOCTL; @@ -184,7 +191,7 @@ /* * alignment of rx/tx descriptors */ -#define DESCR_ALIGN 8 +#define DESCR_ALIGN 64 /* * definitions for pnmi. TODO @@ -197,6 +204,44 @@ #define SK_DRIVER_SET_MTU(pAc,IoC,i,v) 0 #define SK_DRIVER_PRESET_MTU(pAc,IoC,i,v) 0 +/* +** Interim definition of SK_DRV_TIMER placed in this file until +** common modules have boon finallized +*/ +#define SK_DRV_TIMER 11 +#define SK_DRV_MODERATION_TIMER 1 +#define SK_DRV_MODERATION_TIMER_LENGTH 1000000 /* 1 second */ +#define SK_DRV_RX_CLEANUP_TIMER 2 +#define SK_DRV_RX_CLEANUP_TIMER_LENGTH 1000000 /* 100 millisecs */ + +/* +** Definitions regarding transmitting frames +** any calculating any checksum. +*/ +#define C_LEN_ETHERMAC_HEADER_DEST_ADDR 6 +#define C_LEN_ETHERMAC_HEADER_SRC_ADDR 6 +#define C_LEN_ETHERMAC_HEADER_LENTYPE 2 +#define C_LEN_ETHERMAC_HEADER ( (C_LEN_ETHERMAC_HEADER_DEST_ADDR) + \ + (C_LEN_ETHERMAC_HEADER_SRC_ADDR) + \ + (C_LEN_ETHERMAC_HEADER_LENTYPE) ) + +#define C_LEN_ETHERMTU_MINSIZE 46 +#define C_LEN_ETHERMTU_MAXSIZE_STD 1500 +#define C_LEN_ETHERMTU_MAXSIZE_JUMBO 9000 + +#define C_LEN_ETHERNET_MINSIZE ( (C_LEN_ETHERMAC_HEADER) + \ + (C_LEN_ETHERMTU_MINSIZE) ) + +#define C_OFFSET_IPHEADER C_LEN_ETHERMAC_HEADER +#define C_OFFSET_IPHEADER_IPPROTO 9 +#define C_OFFSET_TCPHEADER_TCPCS 16 +#define C_OFFSET_UDPHEADER_UDPCS 6 + +#define C_OFFSET_IPPROTO ( (C_LEN_ETHERMAC_HEADER) + \ + (C_OFFSET_IPHEADER_IPPROTO) ) + +#define C_PROTO_ID_UDP 17 /* refer to RFC 790 or Stevens' */ +#define C_PROTO_ID_TCP 6 /* TCP/IP illustrated for details */ /* TX and RX descriptors *****************************************************/ @@ -231,160 +276,42 @@ struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */ }; +/* Used interrupt bits in the interrupts source register *********************/ -/* definition of flags in descriptor control field */ -#define RX_CTRL_OWN_BMU UINT32_C(0x80000000) -#define RX_CTRL_STF UINT32_C(0x40000000) -#define RX_CTRL_EOF UINT32_C(0x20000000) -#define RX_CTRL_EOB_IRQ UINT32_C(0x10000000) -#define RX_CTRL_EOF_IRQ UINT32_C(0x08000000) -#define RX_CTRL_DEV_NULL UINT32_C(0x04000000) -#define RX_CTRL_STAT_VALID UINT32_C(0x02000000) -#define RX_CTRL_TIME_VALID UINT32_C(0x01000000) -#define RX_CTRL_CHECK_DEFAULT UINT32_C(0x00550000) -#define RX_CTRL_CHECK_CSUM UINT32_C(0x00560000) -#define RX_CTRL_LEN_MASK UINT32_C(0x0000FFFF) - -#define TX_CTRL_OWN_BMU UINT32_C(0x80000000) -#define TX_CTRL_STF UINT32_C(0x40000000) -#define TX_CTRL_EOF UINT32_C(0x20000000) -#define TX_CTRL_EOB_IRQ UINT32_C(0x10000000) -#define TX_CTRL_EOF_IRQ UINT32_C(0x08000000) -#define TX_CTRL_ST_FWD UINT32_C(0x04000000) -#define TX_CTRL_DISAB_CRC UINT32_C(0x02000000) -#define TX_CTRL_SOFTWARE UINT32_C(0x01000000) -#define TX_CTRL_CHECK_DEFAULT UINT32_C(0x00550000) -#define TX_CTRL_CHECK_CSUM UINT32_C(0x00560000) -#define TX_CTRL_LEN_MASK UINT32_C(0x0000FFFF) - - - -/* The offsets of registers in the TX and RX queue control io area ***********/ - -#define RX_Q_BUF_CTRL_CNT 0x00 -#define RX_Q_NEXT_DESCR_LOW 0x04 -#define RX_Q_BUF_ADDR_LOW 0x08 -#define RX_Q_BUF_ADDR_HIGH 0x0c -#define RX_Q_FRAME_STAT 0x10 -#define RX_Q_TIME_STAMP 0x14 -#define RX_Q_CSUM_1_2 0x18 -#define RX_Q_CSUM_START_1_2 0x1c -#define RX_Q_CUR_DESCR_LOW 0x20 -#define RX_Q_DESCR_HIGH 0x24 -#define RX_Q_CUR_ADDR_LOW 0x28 -#define RX_Q_CUR_ADDR_HIGH 0x2c -#define RX_Q_CUR_BYTE_CNT 0x30 -#define RX_Q_CTRL 0x34 -#define RX_Q_FLAG 0x38 -#define RX_Q_TEST1 0x3c -#define RX_Q_TEST2 0x40 -#define RX_Q_TEST3 0x44 - -#define TX_Q_BUF_CTRL_CNT 0x00 -#define TX_Q_NEXT_DESCR_LOW 0x04 -#define TX_Q_BUF_ADDR_LOW 0x08 -#define TX_Q_BUF_ADDR_HIGH 0x0c -#define TX_Q_FRAME_STAT 0x10 -#define TX_Q_CSUM_START 0x14 -#define TX_Q_CSUM_START_POS 0x18 -#define TX_Q_RESERVED 0x1c -#define TX_Q_CUR_DESCR_LOW 0x20 -#define TX_Q_DESCR_HIGH 0x24 -#define TX_Q_CUR_ADDR_LOW 0x28 -#define TX_Q_CUR_ADDR_HIGH 0x2c -#define TX_Q_CUR_BYTE_CNT 0x30 -#define TX_Q_CTRL 0x34 -#define TX_Q_FLAG 0x38 -#define TX_Q_TEST1 0x3c -#define TX_Q_TEST2 0x40 -#define TX_Q_TEST3 0x44 - -/* definition of flags in the queue control field */ -#define RX_Q_CTRL_POLL_ON 0x00000080 -#define RX_Q_CTRL_POLL_OFF 0x00000040 -#define RX_Q_CTRL_STOP 0x00000020 -#define RX_Q_CTRL_START 0x00000010 -#define RX_Q_CTRL_CLR_I_PAR 0x00000008 -#define RX_Q_CTRL_CLR_I_EOB 0x00000004 -#define RX_Q_CTRL_CLR_I_EOF 0x00000002 -#define RX_Q_CTRL_CLR_I_ERR 0x00000001 - -#define TX_Q_CTRL_POLL_ON 0x00000080 -#define TX_Q_CTRL_POLL_OFF 0x00000040 -#define TX_Q_CTRL_STOP 0x00000020 -#define TX_Q_CTRL_START 0x00000010 -#define TX_Q_CTRL_CLR_I_EOB 0x00000004 -#define TX_Q_CTRL_CLR_I_EOF 0x00000002 -#define TX_Q_CTRL_CLR_I_ERR 0x00000001 - - -/* Interrupt bits in the interrupts source register **************************/ -#define IRQ_HW_ERROR 0x80000000 -#define IRQ_RESERVED 0x40000000 -#define IRQ_PKT_TOUT_RX1 0x20000000 -#define IRQ_PKT_TOUT_RX2 0x10000000 -#define IRQ_PKT_TOUT_TX1 0x08000000 -#define IRQ_PKT_TOUT_TX2 0x04000000 -#define IRQ_I2C_READY 0x02000000 -#define IRQ_SW 0x01000000 -#define IRQ_EXTERNAL_REG 0x00800000 -#define IRQ_TIMER 0x00400000 -#define IRQ_MAC1 0x00200000 -#define IRQ_LINK_SYNC_C_M1 0x00100000 -#define IRQ_MAC2 0x00080000 -#define IRQ_LINK_SYNC_C_M2 0x00040000 -#define IRQ_EOB_RX1 0x00020000 -#define IRQ_EOF_RX1 0x00010000 -#define IRQ_CHK_RX1 0x00008000 -#define IRQ_EOB_RX2 0x00004000 -#define IRQ_EOF_RX2 0x00002000 -#define IRQ_CHK_RX2 0x00001000 -#define IRQ_EOB_SY_TX1 0x00000800 -#define IRQ_EOF_SY_TX1 0x00000400 -#define IRQ_CHK_SY_TX1 0x00000200 -#define IRQ_EOB_AS_TX1 0x00000100 -#define IRQ_EOF_AS_TX1 0x00000080 -#define IRQ_CHK_AS_TX1 0x00000040 -#define IRQ_EOB_SY_TX2 0x00000020 -#define IRQ_EOF_SY_TX2 0x00000010 -#define IRQ_CHK_SY_TX2 0x00000008 -#define IRQ_EOB_AS_TX2 0x00000004 -#define IRQ_EOF_AS_TX2 0x00000002 -#define IRQ_CHK_AS_TX2 0x00000001 - -#define DRIVER_IRQS (IRQ_SW | IRQ_EOF_RX1 | IRQ_EOF_RX2 | \ - IRQ_EOF_SY_TX1 | IRQ_EOF_AS_TX1 | \ - IRQ_EOF_SY_TX2 | IRQ_EOF_AS_TX2) - -#define SPECIAL_IRQS (IRQ_HW_ERROR | IRQ_PKT_TOUT_RX1 | IRQ_PKT_TOUT_RX2 | \ - IRQ_PKT_TOUT_TX1 | IRQ_PKT_TOUT_TX2 | \ - IRQ_I2C_READY | IRQ_EXTERNAL_REG | IRQ_TIMER | \ - IRQ_MAC1 | IRQ_LINK_SYNC_C_M1 | \ - IRQ_MAC2 | IRQ_LINK_SYNC_C_M2 | \ - IRQ_CHK_RX1 | IRQ_CHK_RX2 | \ - IRQ_CHK_SY_TX1 | IRQ_CHK_AS_TX1 | \ - IRQ_CHK_SY_TX2 | IRQ_CHK_AS_TX2) - -#define IRQ_MASK (IRQ_SW | IRQ_EOB_RX1 | IRQ_EOF_RX1 | \ - IRQ_EOB_RX2 | IRQ_EOF_RX2 | \ - IRQ_EOB_SY_TX1 | IRQ_EOF_SY_TX1 | \ - IRQ_EOB_AS_TX1 | IRQ_EOF_AS_TX1 | \ - IRQ_EOB_SY_TX2 | IRQ_EOF_SY_TX2 | \ - IRQ_EOB_AS_TX2 | IRQ_EOF_AS_TX2 | \ - IRQ_HW_ERROR | IRQ_PKT_TOUT_RX1 | IRQ_PKT_TOUT_RX2 | \ - IRQ_PKT_TOUT_TX1 | IRQ_PKT_TOUT_TX2 | \ - IRQ_I2C_READY | IRQ_EXTERNAL_REG | IRQ_TIMER | \ - IRQ_MAC1 | \ - IRQ_MAC2 | \ - IRQ_CHK_RX1 | IRQ_CHK_RX2 | \ - IRQ_CHK_SY_TX1 | IRQ_CHK_AS_TX1 | \ - IRQ_CHK_SY_TX2 | IRQ_CHK_AS_TX2) +#define DRIVER_IRQS ((IS_IRQ_SW) | \ + (IS_R1_F) |(IS_R2_F) | \ + (IS_XS1_F) |(IS_XA1_F) | \ + (IS_XS2_F) |(IS_XA2_F)) + +#define SPECIAL_IRQS ((IS_HW_ERR) |(IS_I2C_READY) | \ + (IS_EXT_REG) |(IS_TIMINT) | \ + (IS_PA_TO_RX1) |(IS_PA_TO_RX2) | \ + (IS_PA_TO_TX1) |(IS_PA_TO_TX2) | \ + (IS_MAC1) |(IS_LNK_SYNC_M1)| \ + (IS_MAC2) |(IS_LNK_SYNC_M2)| \ + (IS_R1_C) |(IS_R2_C) | \ + (IS_XS1_C) |(IS_XA1_C) | \ + (IS_XS2_C) |(IS_XA2_C)) + +#define IRQ_MASK ((IS_IRQ_SW) | \ + (IS_R1_B) |(IS_R1_F) |(IS_R2_B) |(IS_R2_F) | \ + (IS_XS1_B) |(IS_XS1_F) |(IS_XA1_B)|(IS_XA1_F)| \ + (IS_XS2_B) |(IS_XS2_F) |(IS_XA2_B)|(IS_XA2_F)| \ + (IS_HW_ERR) |(IS_I2C_READY)| \ + (IS_EXT_REG) |(IS_TIMINT) | \ + (IS_PA_TO_RX1) |(IS_PA_TO_RX2)| \ + (IS_PA_TO_TX1) |(IS_PA_TO_TX2)| \ + (IS_MAC1) |(IS_MAC2) | \ + (IS_R1_C) |(IS_R2_C) | \ + (IS_XS1_C) |(IS_XA1_C) | \ + (IS_XS2_C) |(IS_XA2_C)) -#define IRQ_HWE_MASK 0x00000FFF /* enable all HW irqs */ +#define IRQ_HWE_MASK (IS_ERR_MSK) /* enable all HW irqs */ typedef struct s_DevNet DEV_NET; struct s_DevNet { + struct proc_dir_entry *proc; int PortNr; int NetNr; int Mtu; @@ -423,10 +350,67 @@ int PortIndex; /* index number of port (0 or 1) */ }; +/* Definitions needed for interrupt moderation *******************************/ + +#define IRQ_EOF_AS_TX ((IS_XA1_F) | (IS_XA2_F)) +#define IRQ_EOF_SY_TX ((IS_XS1_F) | (IS_XS2_F)) +#define IRQ_MASK_TX_ONLY ((IRQ_EOF_AS_TX)| (IRQ_EOF_SY_TX)) +#define IRQ_MASK_RX_ONLY ((IS_R1_F) | (IS_R2_F)) +#define IRQ_MASK_SP_ONLY (SPECIAL_IRQS) +#define IRQ_MASK_TX_RX ((IRQ_MASK_TX_ONLY)| (IRQ_MASK_RX_ONLY)) +#define IRQ_MASK_SP_RX ((SPECIAL_IRQS) | (IRQ_MASK_RX_ONLY)) +#define IRQ_MASK_SP_TX ((SPECIAL_IRQS) | (IRQ_MASK_TX_ONLY)) +#define IRQ_MASK_RX_TX_SP ((SPECIAL_IRQS) | (IRQ_MASK_TX_RX)) + +#define C_INT_MOD_NONE 1 +#define C_INT_MOD_STATIC 2 +#define C_INT_MOD_DYNAMIC 4 + +#define C_CLK_FREQ_GENESIS 53215000 /* shorter: 53.125 MHz */ +#define C_CLK_FREQ_YUKON 78215000 /* shorter: 78.125 MHz */ + +#define C_INTS_PER_SEC_DEFAULT 2000 +#define C_INT_MOD_ENABLE_PERCENTAGE 50 /* if higher 50% enable */ +#define C_INT_MOD_DISABLE_PERCENTAGE 50 /* if lower 50% disable */ +#define C_INT_MOD_IPS_LOWER_RANGE 30 +#define C_INT_MOD_IPS_UPPER_RANGE 40000 + + +typedef struct s_DynIrqModInfo DIM_INFO; +struct s_DynIrqModInfo { + unsigned long PrevTimeVal; + unsigned int PrevSysLoad; + unsigned int PrevUsedTime; + unsigned int PrevTotalTime; + int PrevUsedDescrRatio; + int NbrProcessedDescr; + SK_U64 PrevPort0RxIntrCts; + SK_U64 PrevPort1RxIntrCts; + SK_U64 PrevPort0TxIntrCts; + SK_U64 PrevPort1TxIntrCts; + SK_BOOL ModJustEnabled; /* Moderation just enabled yes/no */ + + int MaxModIntsPerSec; /* Moderation Threshold */ + int MaxModIntsPerSecUpperLimit; /* Upper limit for DIM */ + int MaxModIntsPerSecLowerLimit; /* Lower limit for DIM */ + + long MaskIrqModeration; /* ModIrqType (eg. 'TxRx') */ + SK_BOOL DisplayStats; /* Stats yes/no */ + SK_BOOL AutoSizing; /* Resize DIM-timer on/off */ + int IntModTypeSelect; /* EnableIntMod (eg. 'dynamic') */ + + SK_TIMER ModTimer; /* just some timer */ +}; + typedef struct s_PerStrm PER_STRM; #define SK_ALLOC_IRQ 0x00000001 +#ifdef SK_DIAG_SUPPORT +#define DIAG_ACTIVE 1 +#define DIAG_NOTACTIVE 0 +#endif + /**************************************************************************** * Per board structure / Adapter Context structure: * Allocated within attach(9e) and freed within detach(9e). @@ -490,10 +474,24 @@ SK_U32 CsOfs; /* for checksum calculation */ SK_BOOL CheckQueue; /* check event queue soon */ + SK_TIMER DrvCleanupTimer;/* to check for pending descriptors */ + DIM_INFO DynIrqModInfo; /* all data related to DIM */ /* Only for tests */ int PortUp; int PortDown; + int ChipsetType; /* Chipset family type + * 0 == Genesis family support + * 1 == Yukon family support + */ +#ifdef SK_DIAG_SUPPORT + SK_U32 DiagModeActive; /* is diag active? */ + SK_BOOL DiagFlowCtrl; /* for control purposes */ + SK_PNMI_STRUCT_DATA PnmiBackup; /* backup structure for all Pnmi-Data */ + SK_BOOL WasIfUp[SK_MAX_MACS]; /* for OpenClose while + * DIAG is busy with NIC + */ +#endif }; Index: drivers/net/sk98lin/h/skerror.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/skerror.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/skerror.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/skerror.h 4 Aug 2004 01:29:23 -0000 1.2 @@ -1,16 +1,15 @@ /****************************************************************************** * * Name: skerror.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ + * Project: Gigabit Ethernet Adapters, Common Modules * Purpose: SK specific Error log support * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,35 +20,6 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * $Log: skerror.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.5 2002/04/25 11:05:10 rschmidt - * Editorial changes - * - * Revision 1.4 1999/11/22 13:51:59 cgoos - * Changed license header to GPL. - * - * Revision 1.3 1999/09/14 14:04:42 rwahl - * Added error base SK_ERRBASE_PECP. - * Changed error base for driver. - * - * Revision 1.2 1998/08/11 11:15:41 gklug - * chg: comments - * - * Revision 1.1 1998/08/11 11:09:38 gklug - * add: error bases - * add: error Classes - * first version - * - * - * - ******************************************************************************/ - #ifndef _INC_SKERROR_H_ #define _INC_SKERROR_H_ Index: drivers/net/sk98lin/h/skgedrv.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/skgedrv.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/skgedrv.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/skgedrv.h 4 Aug 2004 01:29:23 -0000 1.2 @@ -1,16 +1,15 @@ /****************************************************************************** * * Name: skgedrv.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ + * Project: Gigabit Ethernet Adapters, Common Modules * Purpose: Interface with the driver * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,36 +20,6 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: skgedrv.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.6 2002/07/15 15:38:01 rschmidt - * Power Management support - * Editorial changes - * - * Revision 1.5 2002/04/25 11:05:47 rschmidt - * Editorial changes - * - * Revision 1.4 1999/11/22 13:52:46 cgoos - * Changed license header to GPL. - * - * Revision 1.3 1998/12/01 13:31:39 cgoos - * SWITCH INTERN Event added. - * - * Revision 1.2 1998/11/25 08:28:38 gklug - * rmv: PORT SWITCH Event - * - * Revision 1.1 1998/09/29 06:14:07 gklug - * add: driver events (initial version) - * - * - ******************************************************************************/ - #ifndef __INC_SKGEDRV_H_ #define __INC_SKGEDRV_H_ @@ -71,5 +40,10 @@ #define SK_DRV_PORT_FAIL 8 /* One port fails */ #define SK_DRV_SWITCH_INTERN 9 /* Port switch by the driver itself */ #define SK_DRV_POWER_DOWN 10 /* Power down mode */ - -#endif /* __INC_SKGEDRV_H_ */ +#define SK_DRV_TIMER 11 /* Timer for free use */ +#ifdef SK_NO_RLMT +#define SK_DRV_LINK_UP 12 /* Link Up event for driver */ +#define SK_DRV_LINK_DOWN 13 /* Link Down event for driver */ +#endif +#define SK_DRV_DOWNSHIFT_DET 14 /* Downshift 4-Pair / 2-Pair (YUKON only) */ +#endif /* __INC_SKGEDRV_H_ */ Index: drivers/net/sk98lin/h/skgehw.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/skgehw.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/skgehw.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/skgehw.h 4 Aug 2004 01:29:23 -0000 1.2 @@ -1,16 +1,15 @@ /****************************************************************************** * * Name: skgehw.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ + * Project: Gigabit Ethernet Adapters, Common Modules * Purpose: Defines and Macros for the Gigabit Ethernet Adapter Product Family * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,207 +20,6 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * $Log: skgehw.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.48 2002/12/05 10:25:11 rschmidt - * Added defines for Half Duplex Burst Mode On/Off - * Added defines for Rx GMAC FIFO Flush feature - * Editorial changes - * - * Revision 1.47 2002/11/12 17:01:31 rschmidt - * Added defines for WOL_CTL_DEFAULT - * Editorial changes - * - * Revision 1.46 2002/10/14 14:47:57 rschmidt - * Corrected bit mask for HW self test results - * Added defines for WOL Registers - * Editorial changes - * - * Revision 1.45 2002/10/11 09:25:22 mkarl - * Added bit mask for HW self test results. - * - * Revision 1.44 2002/08/16 14:44:36 rschmidt - * Added define GPC_HWCFG_GMII_FIB for YUKON Fiber - * - * Revision 1.43 2002/08/12 13:31:50 rschmidt - * Corrected macros for GMAC Address Registers: GM_INADDR(), - * GM_OUTADDR(), GM_INHASH, GM_OUTHASH. - * Editorial changes - * - * Revision 1.42 2002/08/08 15:37:56 rschmidt - * Added defines for Power Management Capabilities - * Editorial changes - * - * Revision 1.41 2002/07/23 16:02:25 rschmidt - * Added macro WOL_REG() to access WOL reg. (HW-Bug in YUKON 1st rev.) - * - * Revision 1.40 2002/07/15 15:41:37 rschmidt - * Added new defines for Power Management Cap. & Control - * Editorial changes - * - * Revision 1.39 2002/06/10 09:37:07 rschmidt - * Added macros for the ADDR-Modul - * - * Revision 1.38 2002/06/05 08:15:19 rschmidt - * Added defines for WOL Registers - * Editorial changes - * - * Revision 1.37 2002/04/25 11:39:23 rschmidt - * Added new defines for PCI Our Register 1 - * Added new registers and defines for YUKON (Rx FIFO, Tx FIFO, - * Time Stamp Timer, GMAC Control, GPHY Control,Link Control, - * GMAC IRQ Source and Mask, Wake-up Frame Pattern Match); - * Added new defines for Control/Status (VAUX available) - * Added Chip ID for YUKON - * Added define for descriptors with UDP ext. for YUKON - * Added macros to access the GMAC - * Added new Phy Type for Marvell 88E1011S (GPHY) - * Editorial changes - * - * Revision 1.36 2000/11/09 12:32:49 rassmann - * Renamed variables. - * - * Revision 1.35 2000/05/19 10:17:13 cgoos - * Added inactivity check in PHY_READ (in DEBUG mode only). - * - * Revision 1.34 1999/11/22 13:53:40 cgoos - * Changed license header to GPL. - * - * Revision 1.33 1999/08/27 11:17:10 malthoff - * It's more savely to put brackets around macro parameters. - * Brackets added for PHY_READ and PHY_WRITE. - * - * Revision 1.32 1999/05/19 07:31:01 cgoos - * Changes for 1000Base-T. - * Added HWAC_LINK_LED macro. - * - * Revision 1.31 1999/03/12 13:27:40 malthoff - * Remove __STDC__. - * - * Revision 1.30 1999/02/09 09:28:20 malthoff - * Add PCI_ERRBITS. - * - * Revision 1.29 1999/01/26 08:55:48 malthoff - * Bugfix: The 16 bit field relations inside the descriptor are - * endianess dependend if the descriptor reversal feature - * (PCI_REV_DESC bit in PCI_OUR_REG_2) is enabled. - * Drivers which use this feature has to set the define - * SK_USE_REV_DESC. - * - * Revision 1.28 1998/12/10 11:10:22 malthoff - * bug fix: IS_IRQ_STAT and IS_IRQ_MST_ERR has been twisted. - * - * Revision 1.27 1998/11/13 14:19:21 malthoff - * Bug Fix: The bit definition of B3_PA_CTRL has completely - * changed from HW Spec v1.3 to v1.5. - * - * Revision 1.26 1998/11/04 08:31:48 cgoos - * Fixed byte ordering in XM_OUTADDR/XM_OUTHASH macros. - * - * Revision 1.25 1998/11/04 07:16:25 cgoos - * Changed byte ordering in XM_INADDR/XM_INHASH again. - * - * Revision 1.24 1998/11/02 11:08:43 malthoff - * RxCtrl and TxCtrl must be volatile. - * - * Revision 1.23 1998/10/28 13:50:45 malthoff - * Fix: Endian support missing in XM_IN/OUT-ADDR/HASH macros. - * - * Revision 1.22 1998/10/26 08:01:36 malthoff - * RX_MFF_CTRL1 is split up into RX_MFF_CTRL1, - * RX_MFF_STAT_TO, and RX_MFF_TIST_TO. - * TX_MFF_CTRL1 is split up TX_MFF_CTRL1 and TX_MFF_WAF. - * - * Revision 1.21 1998/10/20 07:43:10 malthoff - * Fix: XM_IN/OUT/ADDR/HASH macros: - * The pointer must be casted. - * - * Revision 1.20 1998/10/19 15:53:59 malthoff - * Remove ML proto definitions. - * - * Revision 1.19 1998/10/16 14:40:17 gklug - * fix: typo B0_XM_IMSK regs - * - * Revision 1.18 1998/10/16 09:46:54 malthoff - * Remove temp defines for ML diag prototype. - * Fix register definition for B0_XM1_PHY_DATA, B0_XM1_PHY_DATA - * B0_XM2_PHY_DATA, B0_XM2_PHY_ADDR, B0_XA1_CSR, B0_XS1_CSR, - * B0_XS2_CSR, and B0_XA2_CSR. - * - * Revision 1.17 1998/10/14 06:03:14 cgoos - * Changed shifted constant to ULONG. - * - * Revision 1.16 1998/10/09 07:05:41 malthoff - * Rename ALL_PA_ENA_TO to PA_ENA_TO_ALL. - * - * Revision 1.15 1998/10/05 07:54:23 malthoff - * Split up RB_CTRL and it's bit definition into - * RB_CTRL, RB_TST1, and RB_TST2. - * Rename RB_RX_HTPP to RB_RX_LTPP. - * Add ALL_PA_ENA_TO. Modify F_WATER_MARK - * according to HW Spec. v1.5. - * Add MFF_TX_CTRL_DEF. - * - * Revision 1.14 1998/09/28 13:31:16 malthoff - * bug fix: B2_MAC_3 is 0x110 not 0x114 - * - * Revision 1.13 1998/09/24 14:42:56 malthoff - * Split the RX_MFF_TST into RX_MFF_CTRL2, - * RX_MFF_TST1, and RX_MFF_TST2. - * Rename RX_MFF_CTRL to RX_MFF_CTRL1. - * Add BMU bit CSR_SV_IDLE. - * Add macros PHY_READ() and PHY_WRITE(). - * Rename macro SK_ADDR() to SK_HW_ADDR() - * because of conflicts with the Address Module. - * - * Revision 1.12 1998/09/16 07:25:33 malthoff - * Change the parameter order in the XM_INxx and XM_OUTxx macros, - * to have the IoC as first parameter. - * - * Revision 1.11 1998/09/03 09:58:41 malthoff - * Rework the XM_xxx macros. Use {} instead of () to - * be compatible with SK_xxx macros which are defined - * with {}. - * - * Revision 1.10 1998/09/02 11:16:39 malthoff - * Temporary modify B2_I2C_SW to make tests with - * the GE/ML prototype. - * - * Revision 1.9 1998/08/19 09:11:49 gklug - * fix: struct are removed from c-source (see CCC) - * add: typedefs for all structs - * - * Revision 1.8 1998/08/18 08:27:27 malthoff - * Add some temporary workarounds to test GE - * sources with the ML. - * - * Revision 1.7 1998/07/03 14:42:26 malthoff - * bug fix: Correct macro XMA(). - * Add temporary workaround to access the PCI config space over I/O - * - * Revision 1.6 1998/06/23 11:30:36 malthoff - * Remove ';' with ',' in macors. - * - * Revision 1.5 1998/06/22 14:20:57 malthoff - * Add macro SK_ADDR(Base,Addr). - * - * Revision 1.4 1998/06/19 13:35:43 malthoff - * change 'pGec' with 'pAC' - * - * Revision 1.3 1998/06/17 14:58:16 cvs - * Lost keywords reinserted. - * - * Revision 1.1 1998/06/17 14:16:36 cvs - * created - * - * - ******************************************************************************/ - #ifndef __INC_SKGEHW_H #define __INC_SKGEHW_H @@ -337,7 +135,7 @@ #define PCI_SUB_ID 0x2e /* 16 bit Subsystem ID */ #define PCI_BASE_ROM 0x30 /* 32 bit Expansion ROM Base Address */ #define PCI_CAP_PTR 0x34 /* 8 bit Capabilities Ptr */ - /* Byte 35..3b: reserved */ + /* Byte 0x35..0x3b: reserved */ #define PCI_IRQ_LINE 0x3c /* 8 bit Interrupt Line */ #define PCI_IRQ_PIN 0x3d /* 8 bit Interrupt Pin */ #define PCI_MIN_GNT 0x3e /* 8 bit Min_Gnt */ @@ -357,7 +155,9 @@ #define PCI_VPD_NITEM 0x51 /* 8 bit Next Item Ptr */ #define PCI_VPD_ADR_REG 0x52 /* 16 bit VPD Address Register */ #define PCI_VPD_DAT_REG 0x54 /* 32 bit VPD Data Register */ - /* Byte 0x58..0xff: reserved */ + /* Byte 0x58..0x59: reserved */ +#define PCI_SER_LD_CTRL 0x5a /* 16 bit SEEPROM Loader Ctrl (YUKON only) */ + /* Byte 0x5c..0xff: reserved */ /* * I2C Address (PCI Config) @@ -365,13 +165,14 @@ * Note: The temperature and voltage sensors are relocated on a different * I2C bus. */ -#define I2C_ADDR_VPD 0xA0 /* I2C address for the VPD EEPROM */ +#define I2C_ADDR_VPD 0xa0 /* I2C address for the VPD EEPROM */ /* * Define Bits and Values of the registers */ /* PCI_COMMAND 16 bit Command */ - /* Bit 15..10: reserved */ + /* Bit 15..11: reserved */ +#define PCI_INT_DIS BIT_10S /* Interrupt INTx# disable (PCI 2.3) */ #define PCI_FBTEN BIT_9S /* Fast Back-To-Back enable */ #define PCI_SERREN BIT_8S /* SERR enable */ #define PCI_ADSTEP BIT_7S /* Address Stepping */ @@ -401,7 +202,8 @@ #define PCI_UDF BIT_6S /* User Defined Features */ #define PCI_66MHZCAP BIT_5S /* 66 MHz PCI bus clock capable */ #define PCI_NEWCAP BIT_4S /* New cap. list implemented */ - /* Bit 3.. 0: reserved */ +#define PCI_INT_STAT BIT_3S /* Interrupt INTx# Status (PCI 2.3) */ + /* Bit 2.. 0: reserved */ #define PCI_ERRBITS (PCI_PERR | PCI_SERR | PCI_RMABORT | PCI_RTABORT |\ PCI_DATAPERR) @@ -430,7 +232,7 @@ #define PCI_MEM32BIT (0L<<1) /* Base addr anywhere in 32 Bit range */ #define PCI_MEM1M (1L<<1) /* Base addr below 1 MegaByte */ #define PCI_MEM64BIT (2L<<1) /* Base addr anywhere in 64 Bit range */ -#define PCI_MEMSPACE BIT_0 /* Memory Space Indic. */ +#define PCI_MEMSPACE BIT_0 /* Memory Space Indicator */ /* PCI_BASE_2ND 32 bit 2nd Base address */ #define PCI_IOBASE 0xffffff00L /* Bit 31.. 8: I/O Base address */ @@ -439,8 +241,8 @@ #define PCI_IOSPACE BIT_0 /* I/O Space Indicator */ /* PCI_BASE_ROM 32 bit Expansion ROM Base Address */ -#define PCI_ROMBASE 0xfffe0000L /* Bit 31..17: ROM BASE address (1st)*/ -#define PCI_ROMBASZ (0x1cL<<14) /* Bit 16..14: Treat as BASE or SIZE */ +#define PCI_ROMBASE_MSK 0xfffe0000L /* Bit 31..17: ROM Base address */ +#define PCI_ROMBASE_SIZ (0x1cL<<14) /* Bit 16..14: Treat as Base or Size */ #define PCI_ROMSIZE (0x38L<<11) /* Bit 13..11: ROM Size Requirements */ /* Bit 10.. 1: reserved */ #define PCI_ROMEN BIT_0 /* Address Decode enable */ @@ -448,15 +250,15 @@ /* Device Dependent Region */ /* PCI_OUR_REG_1 32 bit Our Register 1 */ /* Bit 31..29: reserved */ -#define PCI_PHY_COMA BIT_28 /* Set PHY to Coma Mode */ -#define PCI_EN_CAL BIT_27 /* Enable PCI buffer strength calibr. */ -#define PCI_DIS_CAL BIT_26 /* Disable PCI buffer strength calibr. */ +#define PCI_PHY_COMA BIT_28 /* Set PHY to Coma Mode (YUKON only) */ +#define PCI_TEST_CAL BIT_27 /* Test PCI buffer calib. (YUKON only) */ +#define PCI_EN_CAL BIT_26 /* Enable PCI buffer calib. (YUKON only) */ #define PCI_VIO BIT_25 /* PCI I/O Voltage, 0 = 3.3V, 1 = 5V */ -#define PCI_EN_BOOT BIT_24 /* Enable BOOT via ROM */ +#define PCI_DIS_BOOT BIT_24 /* Disable BOOT via ROM */ #define PCI_EN_IO BIT_23 /* Mapping to I/O space */ -#define PCI_EN_FPROM BIT_22 /* FLASH mapped to mem? */ - /* 1 = Map Flash to Mem */ - /* 0 = Disable addr. dec*/ +#define PCI_EN_FPROM BIT_22 /* Enable FLASH mapping to memory */ + /* 1 = Map Flash to memory */ + /* 0 = Disable addr. dec */ #define PCI_PAGESIZE (3L<<20) /* Bit 21..20: FLASH Page Size */ #define PCI_PAGE_16 (0L<<20) /* 16 k pages */ #define PCI_PAGE_32K (1L<<20) /* 32 k pages */ @@ -499,7 +301,7 @@ /* Power Management Region */ /* PCI_PM_CAP_REG 16 bit Power Management Capabilities */ -#define PCI_PME_SUP (0x1f<<11) /* Bit 15..11: PM Event Support */ +#define PCI_PME_SUP_MSK (0x1f<<11) /* Bit 15..11: PM Event Support Mask */ #define PCI_PME_D3C_SUP BIT_15S /* PME from D3cold Support (if Vaux) */ #define PCI_PME_D3H_SUP BIT_14S /* PME from D3hot Support */ #define PCI_PME_D2_SUP BIT_13S /* PME from D2 Support */ @@ -528,8 +330,8 @@ /* VPD Region */ /* PCI_VPD_ADR_REG 16 bit VPD Address Register */ -#define PCI_VPD_FLAG BIT_15S /* starts VPD rd/wd cycle*/ -#define PCI_VPD_ADDR 0x3fffL /* Bit 14.. 0: VPD address */ +#define PCI_VPD_FLAG BIT_15S /* starts VPD rd/wr cycle */ +#define PCI_VPD_ADR_MSK 0x7fffL /* Bit 14.. 0: VPD address mask */ /* Control Register File (Address Map) */ @@ -605,12 +407,12 @@ #define B2_FAR 0x0120 /* 32 bit Flash-Prom Addr Reg/Cnt */ #define B2_FDP 0x0124 /* 8 bit Flash-Prom Data Port */ /* 0x0125 - 0x0127: reserved */ -#define B2_LD_CRTL 0x0128 /* 8 bit EPROM loader control register */ +#define B2_LD_CTRL 0x0128 /* 8 bit EPROM loader control register */ #define B2_LD_TEST 0x0129 /* 8 bit EPROM loader test register */ /* 0x012a - 0x012f: reserved */ #define B2_TI_INI 0x0130 /* 32 bit Timer Init Value */ #define B2_TI_VAL 0x0134 /* 32 bit Timer Value */ -#define B2_TI_CRTL 0x0138 /* 8 bit Timer Control */ +#define B2_TI_CTRL 0x0138 /* 8 bit Timer Control */ #define B2_TI_TEST 0x0139 /* 8 Bit Timer Test */ /* 0x013a - 0x013f: reserved */ #define B2_IRQM_INI 0x0140 /* 32 bit IRQ Moderation Timer Init Reg.*/ @@ -998,8 +800,11 @@ /* Bit 7: reserved */ #define RAP_RAP 0x3f /* Bit 6..0: 0 = block 0,..,6f = block 6f */ -/* B0_CTST 16 bit Control/Status register */ - /* Bit 15..11: reserved */ +/* B0_CTST 16 bit Control/Status register */ + /* Bit 15..14: reserved */ +#define CS_CLK_RUN_HOT BIT_13S /* CLK_RUN hot m. (YUKON-Lite only) */ +#define CS_CLK_RUN_RST BIT_12S /* CLK_RUN reset (YUKON-Lite only) */ +#define CS_CLK_RUN_ENA BIT_11S /* CLK_RUN enable (YUKON-Lite only) */ #define CS_VAUX_AVAIL BIT_10S /* VAUX available (YUKON only) */ #define CS_BUS_CLOCK BIT_9S /* Bus Clock 0/1 = 33/66 MHz */ #define CS_BUS_SLOT_SZ BIT_8S /* Slot Size 0/1 = 32/64 bit slot */ @@ -1012,7 +817,7 @@ #define CS_RST_CLR BIT_1S /* Clear Software reset */ #define CS_RST_SET BIT_0S /* Set Software reset */ -/* B0_LED 8 Bit LED register */ +/* B0_LED 8 Bit LED register */ /* Bit 7.. 2: reserved */ #define LED_STAT_ON BIT_1S /* Status LED on */ #define LED_STAT_OFF BIT_0S /* Status LED off */ @@ -1027,11 +832,11 @@ #define PC_VCC_ON BIT_1 /* Switch VCC On */ #define PC_VCC_OFF BIT_0 /* Switch VCC Off */ -/* B0_ISRC 32 bit Interrupt Source Register */ -/* B0_IMSK 32 bit Interrupt Mask Register */ -/* B0_SP_ISRC 32 bit Special Interrupt Source Reg */ +/* B0_ISRC 32 bit Interrupt Source Register */ +/* B0_IMSK 32 bit Interrupt Mask Register */ +/* B0_SP_ISRC 32 bit Special Interrupt Source Reg */ /* B2_IRQM_MSK 32 bit IRQ Moderation Mask */ -#define IS_ALL_MSK 0xbfffffffL /* All Interrupt bits */ +#define IS_ALL_MSK 0xbfffffffUL /* All Interrupt bits */ #define IS_HW_ERR BIT_31 /* Interrupt HW Error */ /* Bit 30: reserved */ #define IS_PA_TO_RX1 BIT_29 /* Packet Arb Timeout Rx1 */ @@ -1073,9 +878,9 @@ #define IS_XA2_C BIT_0 /* Q_XA2 Encoding Error */ -/* B0_HWE_ISRC 32 bit HW Error Interrupt Src Reg */ -/* B0_HWE_IMSK 32 bit HW Error Interrupt Mask Reg */ -/* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */ +/* B0_HWE_ISRC 32 bit HW Error Interrupt Src Reg */ +/* B0_HWE_IMSK 32 bit HW Error Interrupt Mask Reg */ +/* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */ #define IS_ERR_MSK 0x00000fffL /* All Error bits */ /* Bit 31..14: reserved */ #define IS_IRQ_TIST_OV BIT_13 /* Time Stamp Timer Overflow (YUKON only) */ @@ -1093,27 +898,32 @@ #define IS_R1_PAR_ERR BIT_1 /* Queue R1 Parity Error */ #define IS_R2_PAR_ERR BIT_0 /* Queue R2 Parity Error */ -/* B2_CONN_TYP 8 bit Connector type */ -/* B2_PMD_TYP 8 bit PMD type */ +/* B2_CONN_TYP 8 bit Connector type */ +/* B2_PMD_TYP 8 bit PMD type */ /* Values of connector and PMD type comply to SysKonnect internal std */ -/* B2_MAC_CFG 8 bit MAC Configuration / Chip Revision */ +/* B2_MAC_CFG 8 bit MAC Configuration / Chip Revision */ #define CFG_CHIP_R_MSK (0xf<<4) /* Bit 7.. 4: Chip Revision */ /* Bit 3.. 2: reserved */ #define CFG_DIS_M2_CLK BIT_1S /* Disable Clock for 2nd MAC */ #define CFG_SNG_MAC BIT_0S /* MAC Config: 0=2 MACs / 1=1 MAC*/ -/* B2_CHIP_ID 8 bit Chip Identification Number */ -#define CHIP_ID_GENESIS 0x0a /* Chip ID for GENESIS */ -#define CHIP_ID_YUKON 0xb0 /* Chip ID for YUKON */ +/* B2_CHIP_ID 8 bit Chip Identification Number */ +#define CHIP_ID_GENESIS 0x0a /* Chip ID for GENESIS */ +#define CHIP_ID_YUKON 0xb0 /* Chip ID for YUKON */ +#define CHIP_ID_YUKON_LITE 0xb1 /* Chip ID for YUKON-Lite (Rev. A1-A3) */ +#define CHIP_ID_YUKON_LP 0xb2 /* Chip ID for YUKON-LP */ -/* B2_FAR 32 bit Flash-Prom Addr Reg/Cnt */ +#define CHIP_REV_YU_LITE_A1 3 /* Chip Rev. for YUKON-Lite A1,A2 */ +#define CHIP_REV_YU_LITE_A3 7 /* Chip Rev. for YUKON-Lite A3 */ + +/* B2_FAR 32 bit Flash-Prom Addr Reg/Cnt */ #define FAR_ADDR 0x1ffffL /* Bit 16.. 0: FPROM Address mask */ -/* B2_LD_CRTL 8 bit EPROM loader control register */ +/* B2_LD_CTRL 8 bit EPROM loader control register */ /* Bits are currently reserved */ -/* B2_LD_TEST 8 bit EPROM loader test register */ +/* B2_LD_TEST 8 bit EPROM loader test register */ /* Bit 7.. 4: reserved */ #define LD_T_ON BIT_3S /* Loader Test mode on */ #define LD_T_OFF BIT_2S /* Loader Test mode off */ @@ -1123,16 +933,16 @@ /* * Timer Section */ -/* B2_TI_CRTL 8 bit Timer control */ +/* B2_TI_CTRL 8 bit Timer control */ /* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */ /* Bit 7.. 3: reserved */ #define TIM_START BIT_2S /* Start Timer */ #define TIM_STOP BIT_1S /* Stop Timer */ #define TIM_CLR_IRQ BIT_0S /* Clear Timer IRQ (!IRQM) */ -/* B2_TI_TEST 8 Bit Timer Test */ +/* B2_TI_TEST 8 Bit Timer Test */ /* B2_IRQM_TEST 8 bit IRQ Moderation Timer Test */ -/* B28_DPT_TST 8 bit Descriptor Poll Timer Test Reg */ +/* B28_DPT_TST 8 bit Descriptor Poll Timer Test Reg */ /* Bit 7.. 3: reserved */ #define TIM_T_ON BIT_2S /* Test mode on */ #define TIM_T_OFF BIT_1S /* Test mode off */ @@ -1169,18 +979,18 @@ #define TST_FRC_APERR_1M64 BIT_1S /* AddrPERR on 1. phase */ #define TST_FRC_APERR_2M64 BIT_0S /* AddrPERR on 2. phase */ -/* B2_GP_IO 32 bit General Purpose I/O Register */ +/* B2_GP_IO 32 bit General Purpose I/O Register */ /* Bit 31..26: reserved */ -#define GP_DIR_9 BIT_25 /* IO_9 direct, 0=I/1=O */ -#define GP_DIR_8 BIT_24 /* IO_8 direct, 0=I/1=O */ -#define GP_DIR_7 BIT_23 /* IO_7 direct, 0=I/1=O */ -#define GP_DIR_6 BIT_22 /* IO_6 direct, 0=I/1=O */ -#define GP_DIR_5 BIT_21 /* IO_5 direct, 0=I/1=O */ -#define GP_DIR_4 BIT_20 /* IO_4 direct, 0=I/1=O */ -#define GP_DIR_3 BIT_19 /* IO_3 direct, 0=I/1=O */ -#define GP_DIR_2 BIT_18 /* IO_2 direct, 0=I/1=O */ -#define GP_DIR_1 BIT_17 /* IO_1 direct, 0=I/1=O */ -#define GP_DIR_0 BIT_16 /* IO_0 direct, 0=I/1=O */ +#define GP_DIR_9 BIT_25 /* IO_9 direct, 0=In/1=Out */ +#define GP_DIR_8 BIT_24 /* IO_8 direct, 0=In/1=Out */ +#define GP_DIR_7 BIT_23 /* IO_7 direct, 0=In/1=Out */ +#define GP_DIR_6 BIT_22 /* IO_6 direct, 0=In/1=Out */ +#define GP_DIR_5 BIT_21 /* IO_5 direct, 0=In/1=Out */ +#define GP_DIR_4 BIT_20 /* IO_4 direct, 0=In/1=Out */ +#define GP_DIR_3 BIT_19 /* IO_3 direct, 0=In/1=Out */ +#define GP_DIR_2 BIT_18 /* IO_2 direct, 0=In/1=Out */ +#define GP_DIR_1 BIT_17 /* IO_1 direct, 0=In/1=Out */ +#define GP_DIR_0 BIT_16 /* IO_0 direct, 0=In/1=Out */ /* Bit 15..10: reserved */ #define GP_IO_9 BIT_9 /* IO_9 pin */ #define GP_IO_8 BIT_8 /* IO_8 pin */ @@ -1193,28 +1003,28 @@ #define GP_IO_1 BIT_1 /* IO_1 pin */ #define GP_IO_0 BIT_0 /* IO_0 pin */ -/* B2_I2C_CTRL 32 bit I2C HW Control Register */ +/* B2_I2C_CTRL 32 bit I2C HW Control Register */ #define I2C_FLAG BIT_31 /* Start read/write if WR */ #define I2C_ADDR (0x7fffL<<16) /* Bit 30..16: Addr to be RD/WR */ #define I2C_DEV_SEL (0x7fL<<9) /* Bit 15.. 9: I2C Device Select */ /* Bit 8.. 5: reserved */ #define I2C_BURST_LEN BIT_4 /* Burst Len, 1/4 bytes */ -#define I2C_DEV_SIZE (7L<<1) /* Bit 3.. 1: I2C Device Size */ -#define I2C_025K_DEV (0L<<1) /* 0: 256 Bytes or smal. */ -#define I2C_05K_DEV (1L<<1) /* 1: 512 Bytes */ -#define I2C_1K_DEV (2L<<1) /* 2: 1024 Bytes */ -#define I2C_2K_DEV (3L<<1) /* 3: 2048 Bytes */ -#define I2C_4K_DEV (4L<<1) /* 4: 4096 Bytes */ -#define I2C_8K_DEV (5L<<1) /* 5: 8192 Bytes */ -#define I2C_16K_DEV (6L<<1) /* 6: 16384 Bytes */ -#define I2C_32K_DEV (7L<<1) /* 7: 32768 Bytes */ +#define I2C_DEV_SIZE (7<<1) /* Bit 3.. 1: I2C Device Size */ +#define I2C_025K_DEV (0<<1) /* 0: 256 Bytes or smal. */ +#define I2C_05K_DEV (1<<1) /* 1: 512 Bytes */ +#define I2C_1K_DEV (2<<1) /* 2: 1024 Bytes */ +#define I2C_2K_DEV (3<<1) /* 3: 2048 Bytes */ +#define I2C_4K_DEV (4<<1) /* 4: 4096 Bytes */ +#define I2C_8K_DEV (5<<1) /* 5: 8192 Bytes */ +#define I2C_16K_DEV (6<<1) /* 6: 16384 Bytes */ +#define I2C_32K_DEV (7<<1) /* 7: 32768 Bytes */ #define I2C_STOP BIT_0 /* Interrupt I2C transfer */ -/* B2_I2C_IRQ 32 bit I2C HW IRQ Register */ +/* B2_I2C_IRQ 32 bit I2C HW IRQ Register */ /* Bit 31.. 1 reserved */ #define I2C_CLR_IRQ BIT_0 /* Clear I2C IRQ */ -/* B2_I2C_SW 32 bit (8 bit access) I2C HW SW Port Register */ +/* B2_I2C_SW 32 bit (8 bit access) I2C HW SW Port Register */ /* Bit 7.. 3: reserved */ #define I2C_DATA_DIR BIT_2S /* direction of I2C_DATA */ #define I2C_DATA BIT_1S /* I2C Data Port */ @@ -1226,27 +1036,27 @@ #define I2C_SENS_ADDR LM80_ADDR /* I2C Sensor Address, (Volt and Temp)*/ -/* B2_BSC_CTRL 8 bit Blink Source Counter Control */ +/* B2_BSC_CTRL 8 bit Blink Source Counter Control */ /* Bit 7.. 2: reserved */ #define BSC_START BIT_1S /* Start Blink Source Counter */ #define BSC_STOP BIT_0S /* Stop Blink Source Counter */ -/* B2_BSC_STAT 8 bit Blink Source Counter Status */ +/* B2_BSC_STAT 8 bit Blink Source Counter Status */ /* Bit 7.. 1: reserved */ #define BSC_SRC BIT_0S /* Blink Source, 0=Off / 1=On */ -/* B2_BSC_TST 16 bit Blink Source Counter Test Reg */ +/* B2_BSC_TST 16 bit Blink Source Counter Test Reg */ #define BSC_T_ON BIT_2S /* Test mode on */ #define BSC_T_OFF BIT_1S /* Test mode off */ #define BSC_T_STEP BIT_0S /* Test step */ -/* B3_RAM_ADDR 32 bit RAM Address, to read or write */ +/* B3_RAM_ADDR 32 bit RAM Address, to read or write */ /* Bit 31..19: reserved */ #define RAM_ADR_RAN 0x0007ffffL /* Bit 18.. 0: RAM Address Range */ /* RAM Interface Registers */ -/* B3_RI_CTRL 16 bit RAM Iface Control Register */ +/* B3_RI_CTRL 16 bit RAM Iface Control Register */ /* Bit 15..10: reserved */ #define RI_CLR_RD_PERR BIT_9S /* Clear IRQ RAM Read Parity Err */ #define RI_CLR_WR_PERR BIT_8S /* Clear IRQ RAM Write Parity Err*/ @@ -1254,7 +1064,7 @@ #define RI_RST_CLR BIT_1S /* Clear RAM Interface Reset */ #define RI_RST_SET BIT_0S /* Set RAM Interface Reset */ -/* B3_RI_TEST 8 bit RAM Iface Test Register */ +/* B3_RI_TEST 8 bit RAM Iface Test Register */ /* Bit 15.. 4: reserved */ #define RI_T_EV BIT_3S /* Timeout Event occured */ #define RI_T_ON BIT_2S /* Timeout Timer Test On */ @@ -1281,7 +1091,7 @@ #define MA_DIS_REC_RX1 BIT_0S /* Disable Recovery Timer RX1 */ /* Packet Arbiter Registers */ -/* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */ +/* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */ /* Bit 15..14: reserved */ #define PA_CLR_TO_TX2 BIT_13S /* Clear IRQ Packet Timeout TX2 */ #define PA_CLR_TO_TX1 BIT_12S /* Clear IRQ Packet Timeout TX1 */ @@ -1304,7 +1114,7 @@ /* Rx/Tx Path related Arbiter Test Registers */ /* B3_MA_TO_TEST 16 bit MAC Arbiter Timeout Test Reg */ /* B3_MA_RC_TEST 16 bit MAC Arbiter Recovery Test Reg */ -/* B3_PA_TEST 16 bit Packet Arbiter Test Register */ +/* B3_PA_TEST 16 bit Packet Arbiter Test Register */ /* Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */ #define TX2_T_EV BIT_15S /* TX2 Timeout/Recv Event occured */ #define TX2_T_ON BIT_14S /* TX2 Timeout/Recv Timer Test On */ @@ -1325,14 +1135,14 @@ /* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */ -/* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */ -/* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */ -/* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */ -/* TXA_LIM_VAL 32 bit Tx Arb Limit Counter Value */ +/* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */ +/* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */ +/* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */ +/* TXA_LIM_VAL 32 bit Tx Arb Limit Counter Value */ /* Bit 31..24: reserved */ -#define TXA_MAX_VAL 0x00ffffffL /* Bit 23.. 0: Max TXA Timer/Cnt Val */ +#define TXA_MAX_VAL 0x00ffffffUL/* Bit 23.. 0: Max TXA Timer/Cnt Val */ -/* TXA_CTRL 8 bit Tx Arbiter Control Register */ +/* TXA_CTRL 8 bit Tx Arbiter Control Register */ #define TXA_ENA_FSYNC BIT_7S /* Enable force of sync Tx queue */ #define TXA_DIS_FSYNC BIT_6S /* Disable force of sync Tx queue */ #define TXA_ENA_ALLOC BIT_5S /* Enable alloc of free bandwidth */ @@ -1342,7 +1152,7 @@ #define TXA_ENA_ARB BIT_1S /* Enable Tx Arbiter */ #define TXA_DIS_ARB BIT_0S /* Disable Tx Arbiter */ -/* TXA_TEST 8 bit Tx Arbiter Test Register */ +/* TXA_TEST 8 bit Tx Arbiter Test Register */ /* Bit 7.. 6: reserved */ #define TXA_INT_T_ON BIT_5S /* Tx Arb Interval Timer Test On */ #define TXA_INT_T_OFF BIT_4S /* Tx Arb Interval Timer Test Off */ @@ -1351,22 +1161,22 @@ #define TXA_LIM_T_OFF BIT_1S /* Tx Arb Limit Timer Test Off */ #define TXA_LIM_T_STEP BIT_0S /* Tx Arb Limit Timer Step */ -/* TXA_STAT 8 bit Tx Arbiter Status Register */ +/* TXA_STAT 8 bit Tx Arbiter Status Register */ /* Bit 7.. 1: reserved */ #define TXA_PRIO_XS BIT_0S /* sync queue has prio to send */ -/* Q_BC 32 bit Current Byte Counter */ +/* Q_BC 32 bit Current Byte Counter */ /* Bit 31..16: reserved */ #define BC_MAX 0xffff /* Bit 15.. 0: Byte counter */ /* BMU Control Status Registers */ -/* B0_R1_CSR 32 bit BMU Ctrl/Stat Rx Queue 1 */ -/* B0_R2_CSR 32 bit BMU Ctrl/Stat Rx Queue 2 */ -/* B0_XA1_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */ -/* B0_XS1_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 1 */ -/* B0_XA2_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 2 */ -/* B0_XS2_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 2 */ -/* Q_CSR 32 bit BMU Control/Status Register */ +/* B0_R1_CSR 32 bit BMU Ctrl/Stat Rx Queue 1 */ +/* B0_R2_CSR 32 bit BMU Ctrl/Stat Rx Queue 2 */ +/* B0_XA1_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */ +/* B0_XS1_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 1 */ +/* B0_XA2_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 2 */ +/* B0_XS2_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 2 */ +/* Q_CSR 32 bit BMU Control/Status Register */ /* Bit 31..25: reserved */ #define CSR_SV_IDLE BIT_24 /* BMU SM Idle */ /* Bit 23..22: reserved */ @@ -1400,7 +1210,7 @@ CSR_SV_RUN | CSR_DREAD_RUN | CSR_DWRITE_RUN |\ CSR_TRANS_RUN) -/* Q_F 32 bit Flag Register */ +/* Q_F 32 bit Flag Register */ /* Bit 31..28: reserved */ #define F_ALM_FULL BIT_27 /* Rx FIFO: almost full */ #define F_EMPTY BIT_27 /* Tx FIFO: empty flag */ @@ -1411,17 +1221,17 @@ /* Bit 15..11: reserved */ #define F_WATER_MARK 0x0007ffL /* Bit 10.. 0: Watermark */ -/* Q_T1 32 bit Test Register 1 */ +/* Q_T1 32 bit Test Register 1 */ /* Holds four State Machine control Bytes */ -#define SM_CRTL_SV_MSK (0xffL<<24) /* Bit 31..24: Control Supervisor SM */ -#define SM_CRTL_RD_MSK (0xffL<<16) /* Bit 23..16: Control Read Desc SM */ -#define SM_CRTL_WR_MSK (0xffL<<8) /* Bit 15.. 8: Control Write Desc SM */ -#define SM_CRTL_TR_MSK 0xffL /* Bit 7.. 0: Control Transfer SM */ - -/* Q_T1_TR 8 bit Test Register 1 Transfer SM */ -/* Q_T1_WR 8 bit Test Register 1 Write Descriptor SM */ -/* Q_T1_RD 8 bit Test Register 1 Read Descriptor SM */ -/* Q_T1_SV 8 bit Test Register 1 Supervisor SM */ +#define SM_CTRL_SV_MSK (0xffL<<24) /* Bit 31..24: Control Supervisor SM */ +#define SM_CTRL_RD_MSK (0xffL<<16) /* Bit 23..16: Control Read Desc SM */ +#define SM_CTRL_WR_MSK (0xffL<<8) /* Bit 15.. 8: Control Write Desc SM */ +#define SM_CTRL_TR_MSK 0xffL /* Bit 7.. 0: Control Transfer SM */ + +/* Q_T1_TR 8 bit Test Register 1 Transfer SM */ +/* Q_T1_WR 8 bit Test Register 1 Write Descriptor SM */ +/* Q_T1_RD 8 bit Test Register 1 Read Descriptor SM */ +/* Q_T1_SV 8 bit Test Register 1 Supervisor SM */ /* The control status byte of each machine looks like ... */ #define SM_STATE 0xf0 /* Bit 7.. 4: State which shall be loaded */ @@ -1431,7 +1241,7 @@ #define SM_STEP BIT_0S /* Step the State Machine */ /* The encoding of the states is not supported by the Diagnostics Tool */ -/* Q_T2 32 bit Test Register 2 */ +/* Q_T2 32 bit Test Register 2 */ /* Bit 31.. 8: reserved */ #define T2_AC_T_ON BIT_7 /* Address Counter Test Mode on */ #define T2_AC_T_OFF BIT_6 /* Address Counter Test Mode off */ @@ -1442,23 +1252,23 @@ #define T2_STEP02 BIT_1 /* Inc AC/Dec BC by 2 */ #define T2_STEP01 BIT_0 /* Inc AC/Dec BC by 1 */ -/* Q_T3 32 bit Test Register 3 */ +/* Q_T3 32 bit Test Register 3 */ /* Bit 31.. 7: reserved */ #define T3_MUX_MSK (7<<4) /* Bit 6.. 4: Mux Position */ /* Bit 3: reserved */ #define T3_VRAM_MSK 7 /* Bit 2.. 0: Virtual RAM Buffer Address */ /* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */ -/* RB_START 32 bit RAM Buffer Start Address */ -/* RB_END 32 bit RAM Buffer End Address */ -/* RB_WP 32 bit RAM Buffer Write Pointer */ -/* RB_RP 32 bit RAM Buffer Read Pointer */ -/* RB_RX_UTPP 32 bit Rx Upper Threshold, Pause Pack */ -/* RB_RX_LTPP 32 bit Rx Lower Threshold, Pause Pack */ -/* RB_RX_UTHP 32 bit Rx Upper Threshold, High Prio */ -/* RB_RX_LTHP 32 bit Rx Lower Threshold, High Prio */ -/* RB_PC 32 bit RAM Buffer Packet Counter */ -/* RB_LEV 32 bit RAM Buffer Level Register */ +/* RB_START 32 bit RAM Buffer Start Address */ +/* RB_END 32 bit RAM Buffer End Address */ +/* RB_WP 32 bit RAM Buffer Write Pointer */ +/* RB_RP 32 bit RAM Buffer Read Pointer */ +/* RB_RX_UTPP 32 bit Rx Upper Threshold, Pause Pack */ +/* RB_RX_LTPP 32 bit Rx Lower Threshold, Pause Pack */ +/* RB_RX_UTHP 32 bit Rx Upper Threshold, High Prio */ +/* RB_RX_LTHP 32 bit Rx Lower Threshold, High Prio */ +/* RB_PC 32 bit RAM Buffer Packet Counter */ +/* RB_LEV 32 bit RAM Buffer Level Register */ /* Bit 31..19: reserved */ #define RB_MSK 0x0007ffff /* Bit 18.. 0: RAM Buffer Pointer Bits */ @@ -1491,17 +1301,17 @@ /* Receive and Transmit MAC FIFO Registers (GENESIS only) */ -/* RX_MFF_EA 32 bit Receive MAC FIFO End Address */ -/* RX_MFF_WP 32 bit Receive MAC FIFO Write Pointer */ -/* RX_MFF_RP 32 bit Receive MAC FIFO Read Pointer */ -/* RX_MFF_PC 32 bit Receive MAC FIFO Packet Counter */ -/* RX_MFF_LEV 32 bit Receive MAC FIFO Level */ -/* TX_MFF_EA 32 bit Transmit MAC FIFO End Address */ -/* TX_MFF_WP 32 bit Transmit MAC FIFO Write Pointer */ -/* TX_MFF_WSP 32 bit Transmit MAC FIFO WR Shadow Pointer */ -/* TX_MFF_RP 32 bit Transmit MAC FIFO Read Pointer */ -/* TX_MFF_PC 32 bit Transmit MAC FIFO Packet Cnt */ -/* TX_MFF_LEV 32 bit Transmit MAC FIFO Level */ +/* RX_MFF_EA 32 bit Receive MAC FIFO End Address */ +/* RX_MFF_WP 32 bit Receive MAC FIFO Write Pointer */ +/* RX_MFF_RP 32 bit Receive MAC FIFO Read Pointer */ +/* RX_MFF_PC 32 bit Receive MAC FIFO Packet Counter */ +/* RX_MFF_LEV 32 bit Receive MAC FIFO Level */ +/* TX_MFF_EA 32 bit Transmit MAC FIFO End Address */ +/* TX_MFF_WP 32 bit Transmit MAC FIFO Write Pointer */ +/* TX_MFF_WSP 32 bit Transmit MAC FIFO WR Shadow Pointer */ +/* TX_MFF_RP 32 bit Transmit MAC FIFO Read Pointer */ +/* TX_MFF_PC 32 bit Transmit MAC FIFO Packet Cnt */ +/* TX_MFF_LEV 32 bit Transmit MAC FIFO Level */ /* Bit 31.. 6: reserved */ #define MFF_MSK 0x007fL /* Bit 5.. 0: MAC FIFO Address/Ptr Bits */ @@ -1649,10 +1459,12 @@ #define GMF_CLI_TX_PE BIT_4 /* Clear IRQ Tx Parity Error */ /* Bits 3..0: same as for RX_GMF_CTRL_T */ -#define GMF_RX_CTRL_DEF GMF_OPER_ON +#define GMF_RX_CTRL_DEF (GMF_OPER_ON | GMF_RX_F_FL_ON) #define GMF_TX_CTRL_DEF GMF_OPER_ON -/* GMAC_TI_ST_CTRL 8 bit Time Stamp Timer Ctrl Reg (YUKON only) */ +#define RX_GMF_FL_THR_DEF 0x0a /* Rx GMAC FIFO Flush Threshold default */ + +/* GMAC_TI_ST_CTRL 8 bit Time Stamp Timer Ctrl Reg (YUKON only) */ /* Bit 7.. 3: reserved */ #define GMT_ST_START BIT_2S /* Start Time Stamp Timer */ #define GMT_ST_STOP BIT_1S /* Stop Time Stamp Timer */ @@ -1736,13 +1548,13 @@ #define GMAC_DEF_MSK (GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | \ GM_IS_TX_FF_UR) -/* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */ +/* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */ /* Bits 15.. 2: reserved */ #define GMLC_RST_CLR BIT_1S /* Clear GMAC Link Reset */ #define GMLC_RST_SET BIT_0S /* Set GMAC Link Reset */ -/* WOL_CTRL_STAT 16 bit WOL Control/Status Reg */ +/* WOL_CTRL_STAT 16 bit WOL Control/Status Reg */ #define WOL_CTL_LINK_CHG_OCC BIT_15S #define WOL_CTL_MAGIC_PKT_OCC BIT_14S #define WOL_CTL_PATTERN_OCC BIT_13S @@ -1770,8 +1582,8 @@ WOL_CTL_DIS_LINK_CHG_UNIT | \ WOL_CTL_DIS_PATTERN_UNIT | \ WOL_CTL_DIS_MAGIC_PKT_UNIT) - -/* WOL_MATCH_CTL 8 bit WOL Match Control Reg */ + +/* WOL_MATCH_CTL 8 bit WOL Match Control Reg */ #define WOL_CTL_PATT_ENA(x) (BIT_0 << (x)) #define SK_NUM_WOL_PATTERN 7 @@ -1814,7 +1626,7 @@ SK_U32 RxAdrHi; /* Physical Rx Buffer Address upper dword */ SK_U32 RxStat; /* Receive Frame Status Word */ SK_U32 RxTiSt; /* Receive Time Stamp (from XMAC on GENESIS) */ -#ifndef SK_USE_REV_DESC +#ifndef SK_USE_REV_DESC SK_U16 RxTcpSum1; /* TCP Checksum 1 */ SK_U16 RxTcpSum2; /* TCP Checksum 2 */ SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */ @@ -1858,7 +1670,7 @@ #define BMU_CHECK (0x55L<<16) /* Default BMU check */ #define BMU_TCP_CHECK (0x56L<<16) /* Descr with TCP ext */ #define BMU_UDP_CHECK (0x57L<<16) /* Descr with UDP ext (YUKON only) */ -#define BMU_BBC 0xFFFFL /* Bit 15.. 0: Buffer Byte Counter */ +#define BMU_BBC 0xffffL /* Bit 15.. 0: Buffer Byte Counter */ /* TxStat Transmit Frame Status Word */ /* RxStat Receive Frame Status Word */ @@ -1869,20 +1681,9 @@ * (see XMR_FS bits) */ -/* other defines *************************************************************/ - -/* - * FlashProm specification - */ -#define MAX_PAGES 0x20000L /* Every byte has a single page */ -#define MAX_FADDR 1 /* 1 byte per page */ -#define SKFDDI_PSZ 8 /* address PROM size */ - /* macros ********************************************************************/ -/* - * Receive and Transmit Queues - */ +/* Receive and Transmit Queues */ #define Q_R1 0x0000 /* Receive Queue 1 */ #define Q_R2 0x0080 /* Receive Queue 2 */ #define Q_XS1 0x0200 /* Synchronous Transmit Queue 1 */ @@ -1895,7 +1696,7 @@ * * Use this macro to access the Receive and Transmit Queue Registers. * - * para: + * para: * Queue Queue to access. * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2 * Offs Queue register offset. @@ -1910,7 +1711,7 @@ * * Use this macro to access the RAM Buffer Registers. * - * para: + * para: * Queue Queue to access. * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2 * Offs Queue register offset. @@ -1921,9 +1722,7 @@ #define RB_ADDR(Queue, Offs) (B16_RAM_REGS + (Queue) + (Offs)) -/* - * MAC Related Registers - */ +/* MAC Related Registers */ #define MAC_1 0 /* belongs to the port near the slot */ #define MAC_2 1 /* belongs to the port far away from the slot */ @@ -1932,7 +1731,7 @@ * * Use this macro to access a MAC Related Registers inside the ASIC. * - * para: + * para: * Mac MAC to access. * Values: MAC_1, MAC_2 * Offs MAC register offset. @@ -1984,9 +1783,9 @@ #define XM_IN32(IoC, Mac, Reg, pVal) { \ SK_IN16((IoC), XMA((Mac), (Reg)), \ - (SK_U16 *)&((SK_U16 *)(pVal))[XM_WORD_LO]); \ + (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]); \ SK_IN16((IoC), XMA((Mac), (Reg+2)), \ - (SK_U16 *)&((SK_U16 *)(pVal))[XM_WORD_HI]); \ + (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]); \ } #define XM_OUT32(IoC, Mac, Reg, Val) { \ @@ -2012,8 +1811,8 @@ } #define XM_OUTADDR(IoC, Mac, Reg, pVal) { \ - SK_U8 *pByte; \ - pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \ + SK_U8 SK_FAR *pByte; \ + pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \ SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16) \ (((SK_U16)(pByte[0]) & 0x00ff) | \ (((SK_U16)(pByte[1]) << 8) & 0xff00))); \ @@ -2027,8 +1826,8 @@ #define XM_INHASH(IoC, Mac, Reg, pVal) { \ SK_U16 Word; \ - SK_U8 *pByte; \ - pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \ + SK_U8 SK_FAR *pByte; \ + pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \ SK_IN16((IoC), XMA((Mac), (Reg)), &Word); \ pByte[0] = (SK_U8)(Word & 0x00ff); \ pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \ @@ -2044,8 +1843,8 @@ } #define XM_OUTHASH(IoC, Mac, Reg, pVal) { \ - SK_U8 *pByte; \ - pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \ + SK_U8 SK_FAR *pByte; \ + pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \ SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16) \ (((SK_U16)(pByte[0]) & 0x00ff)| \ (((SK_U16)(pByte[1]) << 8) & 0xff00))); \ @@ -2092,9 +1891,9 @@ #define GM_IN32(IoC, Mac, Reg, pVal) { \ SK_IN16((IoC), GMA((Mac), (Reg)), \ - (SK_U16 *)&((SK_U16 *)(pVal))[XM_WORD_LO]); \ + (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]); \ SK_IN16((IoC), GMA((Mac), (Reg+4)), \ - (SK_U16 *)&((SK_U16 *)(pVal))[XM_WORD_HI]); \ + (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]); \ } #define GM_OUT32(IoC, Mac, Reg, Val) { \ @@ -2118,8 +1917,8 @@ } #define GM_OUTADDR(IoC, Mac, Reg, pVal) { \ - SK_U8 *pByte; \ - pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \ + SK_U8 SK_FAR *pByte; \ + pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \ SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16) \ (((SK_U16)(pByte[0]) & 0x00ff) | \ (((SK_U16)(pByte[1]) << 8) & 0xff00))); \ @@ -2189,7 +1988,7 @@ #define PHY_ADDR_BCOM (1<<8) #define PHY_ADDR_LONE (3<<8) #define PHY_ADDR_NAT (0<<8) - + /* GPHY address (bits 15..11 of SMI control reg) */ #define PHY_ADDR_MARV 0 @@ -2199,7 +1998,7 @@ * PHY_READ() read a 16 bit value from the PHY * PHY_WRITE() write a 16 bit value to the PHY * - * para: + * para: * IoC I/O context needed for SK I/O macros * pPort Pointer to port struct for PhyAddr * Mac XMAC to access values: MAC_1 or MAC_2 @@ -2271,7 +2070,7 @@ * * para: * Addr PCI configuration register to access. - * Values: PCI_VENDOR_ID ... PCI_VPD_ADDR, + * Values: PCI_VENDOR_ID ... PCI_VPD_ADR_REG, * * usage SK_IN16(pAC, PCI_C(PCI_VENDOR_ID), pVal); */ @@ -2290,12 +2089,12 @@ * #define SK_IN8(pAC, Addr, pVal) ...\ * *pVal = (SK_U8)inp(SK_HW_ADDR(pAC->Hw.Iop, Addr))) */ -#ifdef SK_MEM_MAPPED_IO +#ifdef SK_MEM_MAPPED_IO #define SK_HW_ADDR(Base, Addr) ((Base) + (Addr)) -#else /* SK_MEM_MAPPED_IO */ +#else /* SK_MEM_MAPPED_IO */ #define SK_HW_ADDR(Base, Addr) \ ((Base) + (((Addr) & 0x7f) | (((Addr) >> 7 > 0) ? 0x80 : 0))) -#endif /* SK_MEM_MAPPED_IO */ +#endif /* SK_MEM_MAPPED_IO */ #define SZ_LONG (sizeof(SK_U32)) Index: drivers/net/sk98lin/h/skgehwt.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/skgehwt.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/skgehwt.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/skgehwt.h 4 Aug 2004 01:29:23 -0000 1.2 @@ -1,17 +1,15 @@ /****************************************************************************** * * Name: skhwt.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ + * Project: Gigabit Ethernet Adapters, Event Scheduler Module * Purpose: Defines for the hardware timer functions * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998,1999 SysKonnect, - * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,35 +20,6 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: skgehwt.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.5 1999/11/22 13:54:24 cgoos - * Changed license header to GPL. - * - * Revision 1.4 1998/08/19 09:50:58 gklug - * fix: remove struct keyword from c-code (see CCC) add typedefs - * - * Revision 1.3 1998/08/14 07:09:29 gklug - * fix: chg pAc -> pAC - * - * Revision 1.2 1998/08/07 12:54:21 gklug - * fix: first compiled version - * - * Revision 1.1 1998/08/07 09:32:58 gklug - * first version - * - * - * - * - * - ******************************************************************************/ - /* * SKGEHWT.H contains all defines and types for the timer functions */ @@ -64,14 +33,14 @@ * - use in Adapters context name pAC->Hwt */ typedef struct s_Hwt { - SK_U32 TStart ; /* HWT start */ - SK_U32 TStop ; /* HWT stop */ - int TActive ; /* HWT: flag : active/inactive */ + SK_U32 TStart; /* HWT start */ + SK_U32 TStop; /* HWT stop */ + int TActive; /* HWT: flag : active/inactive */ } SK_HWT; extern void SkHwtInit(SK_AC *pAC, SK_IOC Ioc); extern void SkHwtStart(SK_AC *pAC, SK_IOC Ioc, SK_U32 Time); extern void SkHwtStop(SK_AC *pAC, SK_IOC Ioc); -extern SK_U32 SkHwtRead(SK_AC *pAC,SK_IOC Ioc); +extern SK_U32 SkHwtRead(SK_AC *pAC, SK_IOC Ioc); extern void SkHwtIsr(SK_AC *pAC, SK_IOC Ioc); #endif /* _SKGEHWT_H_ */ Index: drivers/net/sk98lin/h/skgei2c.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/skgei2c.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/skgei2c.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/skgei2c.h 4 Aug 2004 01:29:23 -0000 1.2 @@ -1,16 +1,15 @@ /****************************************************************************** * * Name: skgei2c.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ - * Purpose: Special GEnesis defines for TWSI + * Project: Gigabit Ethernet Adapters, TWSI-Module + * Purpose: Special defines for TWSI * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,99 +20,6 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: skgei2c.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.23 2002/12/19 14:34:27 rschmidt - * Added cast in macros SK_I2C_SET_BIT() and SK_I2C_CLR_BIT() - * Editorial changes (TWSI) - * - * Revision 1.22 2002/10/14 16:45:56 rschmidt - * Editorial changes (TWSI) - * - * Revision 1.21 2002/08/13 08:42:24 rschmidt - * Changed define for SK_MIN_SENSORS back to 5 - * Merged defines for PHY PLL 3V3 voltage (A and B) - * Editorial changes - * - * Revision 1.20 2002/08/06 09:43:56 jschmalz - * Extensions and changes for Yukon - * - * Revision 1.19 2002/08/02 12:00:08 rschmidt - * Added defines for YUKON sensors - * Editorial changes - * - * Revision 1.18 2001/08/16 12:44:33 afischer - * LM80 sensor init values corrected - * - * Revision 1.17 1999/11/22 13:55:25 cgoos - * Changed license header to GPL. - * - * Revision 1.16 1999/11/12 08:24:10 malthoff - * Change voltage warning and error limits - * (warning +-5%, error +-10%). - * - * Revision 1.15 1999/09/14 14:14:43 malthoff - * The 1000BT Dual Link adapter has got only one Fan. - * The second Fan has been removed. - * - * Revision 1.14 1999/05/27 13:40:50 malthoff - * Fan Divisor = 1. Assuming fan with 6500 rpm. - * - * Revision 1.13 1999/05/20 14:56:55 malthoff - * Bug Fix: Missing brace in SK_LM80_FAN_FAKTOR. - * - * Revision 1.12 1999/05/20 09:22:00 cgoos - * Changes for 1000Base-T (Fan sensors). - * - * Revision 1.11 1998/10/14 05:57:22 cgoos - * Fixed compilation warnings. - * - * Revision 1.10 1998/09/04 08:37:00 malthoff - * bugfix: correct the SK_I2C_GET_CTL() macro. - * - * Revision 1.9 1998/08/25 06:10:03 gklug - * add: thresholds for all sensors - * - * Revision 1.8 1998/08/20 11:37:42 gklug - * chg: change Ioc to IoC - * - * Revision 1.7 1998/08/20 08:53:11 gklug - * fix: compiler errors - * add: Threshold values - * - * Revision 1.6 1998/08/17 11:37:09 malthoff - * Bugfix in SK_I2C_CTL macro. The parameter 'dev' - * has to be shifted 9 bits. - * - * Revision 1.5 1998/08/17 06:52:21 malthoff - * Remove unrequired macros. - * Add macros for accessing TWSI SW register. - * - * Revision 1.4 1998/08/13 08:30:18 gklug - * add: conversion factors for read values - * add: new state SEN_VALEXT to read extension value of temperature sensor - * - * Revision 1.3 1998/08/12 13:37:56 gklug - * rmv: error numbers and messages - * - * Revision 1.2 1998/08/11 07:54:38 gklug - * add: sensor states for GE sensors - * add: Macro to access TWSI hardware register - * chg: Error messages for TWSI errors - * - * Revision 1.1 1998/07/17 11:27:56 gklug - * Created. - * - * - * - ******************************************************************************/ - /* * SKGEI2C.H contains all SK-98xx specific defines for the TWSI handling */ @@ -124,12 +30,13 @@ /* * Macros to access the B2_I2C_CTRL */ -#define SK_I2C_CTL(IoC, flag, dev, reg, burst) \ +#define SK_I2C_CTL(IoC, flag, dev, dev_size, reg, burst) \ SK_OUT32(IoC, B2_I2C_CTRL,\ (flag ? 0x80000000UL : 0x0L) | \ - (((SK_U32) reg << 16) & I2C_ADDR) | \ - (((SK_U32) dev << 9) & I2C_DEV_SEL) | \ - (( burst << 4) & I2C_BURST_LEN)) + (((SK_U32)reg << 16) & I2C_ADDR) | \ + (((SK_U32)dev << 9) & I2C_DEV_SEL) | \ + (dev_size & I2C_DEV_SIZE) | \ + ((burst << 4) & I2C_BURST_LEN)) #define SK_I2C_STOP(IoC) { \ SK_U32 I2cCtrl; \ @@ -169,42 +76,42 @@ */ #define SK_LM80_VT_LSB 22 /* 22mV LSB resolution */ #define SK_LM80_TEMP_LSB 10 /* 1 degree LSB resolution */ -#define SK_LM80_TEMPEXT_LSB 5 /* 0.5 degree LSB resolution for the - * extension value - */ -#define SK_LM80_FAN_FAKTOR ((22500L*60)/(1*2)) -/* formula: counter = (22500*60)/(rpm * divisor * pulses/2) +#define SK_LM80_TEMPEXT_LSB 5 /* 0.5 degree LSB resolution for ext. val. */ + +/* + * formula: counter = (22500*60)/(rpm * divisor * pulses/2) * assuming: 6500rpm, 4 pulses, divisor 1 */ +#define SK_LM80_FAN_FAKTOR ((22500L*60)/(1*2)) /* * Define sensor management data - * Maximum is reached on copperfield with dual Broadcom. + * Maximum is reached on Genesis copper dual port and Yukon-64 * Board specific maximum is in pAC->I2c.MaxSens */ #define SK_MAX_SENSORS 8 /* maximal no. of installed sensors */ #define SK_MIN_SENSORS 5 /* minimal no. of installed sensors */ /* - * To watch the statemachine (JS) use the timer in two ways instead of one as hitherto + * To watch the state machine (SM) use the timer in two ways + * instead of one as hitherto */ -#define SK_TIMER_WATCH_STATEMACHINE 0 /* Watch the statemachine to finish in a specific time */ -#define SK_TIMER_NEW_GAUGING 1 /* Start a new gauging when timer expires */ - +#define SK_TIMER_WATCH_SM 0 /* Watch the SM to finish in a spec. time */ +#define SK_TIMER_NEW_GAUGING 1 /* Start a new gauging when timer expires */ /* - * Defines for the individual Thresholds + * Defines for the individual thresholds */ /* Temperature sensor */ -#define SK_SEN_TEMP_HIGH_ERR 800 /* Temperature High Err Threshold */ +#define SK_SEN_TEMP_HIGH_ERR 800 /* Temperature High Err Threshold */ #define SK_SEN_TEMP_HIGH_WARN 700 /* Temperature High Warn Threshold */ #define SK_SEN_TEMP_LOW_WARN 100 /* Temperature Low Warn Threshold */ -#define SK_SEN_TEMP_LOW_ERR 0 /* Temperature Low Err Threshold */ +#define SK_SEN_TEMP_LOW_ERR 0 /* Temperature Low Err Threshold */ /* VCC which should be 5 V */ -#define SK_SEN_PCI_5V_HIGH_ERR 5588 /* Voltage PCI High Err Threshold */ -#define SK_SEN_PCI_5V_HIGH_WARN 5346 /* Voltage PCI High Warn Threshold */ +#define SK_SEN_PCI_5V_HIGH_ERR 5588 /* Voltage PCI High Err Threshold */ +#define SK_SEN_PCI_5V_HIGH_WARN 5346 /* Voltage PCI High Warn Threshold */ #define SK_SEN_PCI_5V_LOW_WARN 4664 /* Voltage PCI Low Warn Threshold */ #define SK_SEN_PCI_5V_LOW_ERR 4422 /* Voltage PCI Low Err Threshold */ @@ -232,17 +139,16 @@ #define SK_SEN_PCI_IO_3V3_HIGH_ERR 3850 /* + 15% V PCI-IO High Err Threshold */ #define SK_SEN_PCI_IO_3V3_HIGH_WARN 3674 /* + 10% V PCI-IO High Warn Threshold */ /* 3300 mVolt */ -#define SK_SEN_PCI_IO_3V3_LOW_WARN 2926 /* - 10% V PCI-IO Low Warn Threshold */ -#define SK_SEN_PCI_IO_3V3_LOW_ERR 2772 /* - 15% V PCI-IO Low Err Threshold */ - +#define SK_SEN_PCI_IO_3V3_LOW_WARN 2926 /* - 10% V PCI-IO Low Warn Threshold */ +#define SK_SEN_PCI_IO_3V3_LOW_ERR 2772 /* - 15% V PCI-IO Low Err Threshold */ /* * VDD voltage */ -#define SK_SEN_VDD_HIGH_ERR 3630 /* Voltage ASIC High Err Threshold */ -#define SK_SEN_VDD_HIGH_WARN 3476 /* Voltage ASIC High Warn Threshold */ -#define SK_SEN_VDD_LOW_WARN 3146 /* Voltage ASIC Low Warn Threshold */ -#define SK_SEN_VDD_LOW_ERR 2970 /* Voltage ASIC Low Err Threshold */ +#define SK_SEN_VDD_HIGH_ERR 3630 /* Voltage ASIC High Err Threshold */ +#define SK_SEN_VDD_HIGH_WARN 3476 /* Voltage ASIC High Warn Threshold */ +#define SK_SEN_VDD_LOW_WARN 3146 /* Voltage ASIC Low Warn Threshold */ +#define SK_SEN_VDD_LOW_ERR 2970 /* Voltage ASIC Low Err Threshold */ /* * PHY PLL 3V3 voltage @@ -258,8 +164,8 @@ #define SK_SEN_VAUX_3V3_HIGH_ERR 3630 /* Voltage VAUX High Err Threshold */ #define SK_SEN_VAUX_3V3_HIGH_WARN 3476 /* Voltage VAUX High Warn Threshold */ #define SK_SEN_VAUX_3V3_LOW_WARN 3146 /* Voltage VAUX Low Warn Threshold */ -#define SK_SEN_VAUX_3V3_LOW_ERR 2970 /* Voltage VAUX Low Err Threshold */ -#define SK_SEN_VAUX_0V_WARN_ERR 0 /* if VAUX not present */ +#define SK_SEN_VAUX_3V3_LOW_ERR 2970 /* Voltage VAUX Low Err Threshold */ +#define SK_SEN_VAUX_0V_WARN_ERR 0 /* if VAUX not present */ #define SK_SEN_VAUX_RANGE_LIMITER 1000 /* 1000 mV range delimiter */ /* @@ -273,7 +179,7 @@ /* * ASIC Core 1V5 voltage (YUKON only) */ -#define SK_SEN_CORE_1V5_HIGH_ERR 1650 /* Voltage ASIC Core High Err Threshold */ +#define SK_SEN_CORE_1V5_HIGH_ERR 1650 /* Voltage ASIC Core High Err Threshold */ #define SK_SEN_CORE_1V5_HIGH_WARN 1575 /* Voltage ASIC Core High Warn Threshold */ #define SK_SEN_CORE_1V5_LOW_WARN 1425 /* Voltage ASIC Core Low Warn Threshold */ #define SK_SEN_CORE_1V5_LOW_ERR 1350 /* Voltage ASIC Core Low Err Threshold */ @@ -288,8 +194,8 @@ */ #define SK_SEN_FAN_HIGH_ERR 20000 /* FAN Speed High Err Threshold */ #define SK_SEN_FAN_HIGH_WARN 20000 /* FAN Speed High Warn Threshold */ -#define SK_SEN_FAN_LOW_WARN 5200 /* FAN Speed Low Warn Threshold */ -#define SK_SEN_FAN_LOW_ERR 4550 /* FAN Speed Low Err Threshold */ +#define SK_SEN_FAN_LOW_WARN 5200 /* FAN Speed Low Warn Threshold */ +#define SK_SEN_FAN_LOW_ERR 4550 /* FAN Speed Low Err Threshold */ /* * Some Voltages need dynamic thresholds Index: drivers/net/sk98lin/h/skgeinit.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/skgeinit.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/skgeinit.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/skgeinit.h 4 Aug 2004 01:29:23 -0000 1.2 @@ -1,16 +1,15 @@ /****************************************************************************** * * Name: skgeinit.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ + * Project: Gigabit Ethernet Adapters, Common Modules * Purpose: Structures and prototypes for the GE Init Module * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,307 +20,6 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: skgeinit.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.73 2002/11/15 12:47:25 rschmidt - * Replaced error message SKERR_HWI_E024 for Cable Diagnostic with - * Rx queue error in SkGeStopPort(). - * - * Revision 1.72 2002/11/12 17:08:35 rschmidt - * Added entries for Cable Diagnostic to Port structure - * Added entries GIPciSlot64 and GIPciClock66 in s_GeInit structure - * Added error message for Cable Diagnostic - * Added prototypes for SkGmCableDiagStatus() - * Editorial changes - * - * Revision 1.71 2002/10/21 11:26:10 mkarl - * Changed interface of SkGeInitAssignRamToQueues(). - * - * Revision 1.70 2002/10/14 08:21:32 rschmidt - * Changed type of GICopperType, GIVauxAvail to SK_BOOL - * Added entry PRxOverCnt to Port structure - * Added entry GIYukon32Bit in s_GeInit structure - * Editorial changes - * - * Revision 1.69 2002/10/09 16:57:15 mkarl - * Added some constants and macros for SkGeInitAssignRamToQueues(). - * - * Revision 1.68 2002/09/12 08:58:51 rwahl - * Retrieve counters needed for XMAC errata workarounds directly because - * PNMI returns corrected counter values (e.g. #10620). - * - * Revision 1.67 2002/08/16 14:40:30 rschmidt - * Added entries GIGenesis and GICopperType in s_GeInit structure - * Added prototypes for SkMacHashing() - * Editorial changes - * - * Revision 1.66 2002/08/12 13:27:21 rschmidt - * Added defines for Link speed capabilities - * Added entry PLinkSpeedCap to Port structure - * Added entry GIVauxAvail in s_GeInit structure - * Added prototypes for SkMacPromiscMode() - * Editorial changes - * - * Revision 1.65 2002/08/08 15:46:18 rschmidt - * Added define SK_PHY_ACC_TO for PHY access timeout - * Added define SK_XM_RX_HI_WM for XMAC Rx High Watermark - * Added define SK_MIN_TXQ_SIZE for Min RAM Buffer Tx Queue Size - * Added entry PhyId1 to Port structure - * - * Revision 1.64 2002/07/23 16:02:56 rschmidt - * Added entry GIWolOffs in s_GeInit struct (HW-Bug in YUKON 1st rev.) - * Added prototypes for: SkGePhyRead(), SkGePhyWrite() - * - * Revision 1.63 2002/07/18 08:17:38 rwahl - * Corrected definitions for SK_LSPEED_xxx & SK_LSPEED_STAT_xxx. - * - * Revision 1.62 2002/07/17 18:21:55 rwahl - * Added SK_LSPEED_INDETERMINATED define. - * - * Revision 1.61 2002/07/17 17:16:03 rwahl - * - MacType now member of GIni struct. - * - Struct alignment to 32bit. - * - Editorial change. - * - * Revision 1.60 2002/07/15 18:23:39 rwahl - * Added GeMacFunc to GE Init structure. - * Added prototypes for SkXmUpdateStats(), SkGmUpdateStats(), - * SkXmMacStatistic(), SkGmMacStatistic(), SkXmResetCounter(), - * SkGmResetCounter(), SkXmOverflowStatus(), SkGmOverflowStatus(). - * Added defines for current link speed state. - * Added ERRMSG defintions for MacUpdateStat() & MacStatistics(). - * - * Revision 1.59 2002/07/15 15:40:22 rschmidt - * Added entry PLinkSpeedUsed to Port structure - * Editorial changes - * - * Revision 1.58 2002/06/10 09:36:30 rschmidt - * Editorial changes. - * - * Revision 1.57 2002/06/05 08:18:00 rschmidt - * Corrected alignment in Port Structure - * Added new prototypes for GMAC - * Editorial changes - * - * Revision 1.56 2002/04/25 11:38:12 rschmidt - * Added defines for Link speed values - * Added defines for Loopback parameters for MAC and PHY - * Removed entry PRxCmd from Port structure - * Added entry PLinkSpeed to Port structure - * Added entries GIChipId and GIChipRev to GE Init structure - * Removed entry GIAnyPortAct from GE Init structure - * Added prototypes for: SkMacInit(), SkMacInitPhy(), - * SkMacRxTxDisable(), SkMacSoftRst(), SkMacHardRst(), SkMacIrq(), - * SkMacIrqDisable(), SkMacFlushTxFifo(), SkMacFlushRxFifo(), - * SkMacAutoNegDone(), SkMacAutoNegLipaPhy(), SkMacSetRxTxEn(), - * SkXmPhyRead(), SkXmPhyRead(), SkGmPhyWrite(), SkGmPhyWrite(); - * Removed prototypes for static functions in SkXmac2.c - * Editorial changes - * - * Revision 1.55 2002/02/26 15:24:53 rwahl - * Fix: no link with manual configuration (#10673). The previous fix for - * #10639 was removed. So for RLMT mode = CLS the RLMT may switch to - * misconfigured port. It should not occur for the other RLMT modes. - * - * Revision 1.54 2002/01/18 16:52:52 rwahl - * Editorial corrections. - * - * Revision 1.53 2001/11/20 09:19:58 rwahl - * Reworked bugfix #10639 (no dependency to RLMT mode). - * - * Revision 1.52 2001/10/26 07:52:23 afischer - * Port switching bug in `check local link` mode - * - * Revision 1.51 2001/02/09 12:26:38 cgoos - * Inserted #ifdef DIAG for half duplex workaround timer. - * - * Revision 1.50 2001/02/07 07:56:40 rassmann - * Corrected copyright. - * - * Revision 1.49 2001/01/31 15:32:18 gklug - * fix: problem with autosensing an SR8800 switch - * add: counter for autoneg timeouts - * - * Revision 1.48 2000/11/09 11:30:10 rassmann - * WA: Waiting after releasing reset until BCom chip is accessible. - * - * Revision 1.47 2000/10/18 12:22:40 cgoos - * Added workaround for half duplex hangup. - * - * Revision 1.46 2000/08/10 11:28:00 rassmann - * Editorial changes. - * Preserving 32-bit alignment in structs for the adapter context. - * - * Revision 1.45 1999/11/22 13:56:19 cgoos - * Changed license header to GPL. - * - * Revision 1.44 1999/10/26 07:34:15 malthoff - * The define SK_LNK_ON has been lost in v1.41. - * - * Revision 1.43 1999/10/06 09:30:16 cgoos - * Changed SK_XM_THR_JUMBO. - * - * Revision 1.42 1999/09/16 12:58:26 cgoos - * Changed SK_LED_STANDY macro to be independent of HW link sync. - * - * Revision 1.41 1999/07/30 06:56:14 malthoff - * Correct comment for SK_MS_STAT_UNSET. - * - * Revision 1.40 1999/05/27 13:38:46 cgoos - * Added SK_BMU_TX_WM. - * Made SK_BMU_TX_WM and SK_BMU_RX_WM user-definable. - * Changed XMAC Tx treshold to max. values. - * - * Revision 1.39 1999/05/20 14:35:26 malthoff - * Remove prototypes for SkGeLinkLED(). - * - * Revision 1.38 1999/05/19 11:59:12 cgoos - * Added SK_MS_CAP_INDETERMINATED define. - * - * Revision 1.37 1999/05/19 07:32:33 cgoos - * Changes for 1000Base-T. - * LED-defines for HWAC_LINK_LED macro. - * - * Revision 1.36 1999/04/08 14:00:24 gklug - * add:Port struct field PLinkResCt - * - * Revision 1.35 1999/03/25 07:43:07 malthoff - * Add error string for SKERR_HWI_E018MSG. - * - * Revision 1.34 1999/03/12 16:25:57 malthoff - * Remove PPollRxD and PPollTxD. - * Add SKERR_HWI_E017MSG. and SK_DPOLL_MAX. - * - * Revision 1.33 1999/03/12 13:34:41 malthoff - * Add Autonegotiation error codes. - * Change defines for parameter Mode in SkXmSetRxCmd(). - * Replace __STDC__ by SK_KR_PROTO. - * - * Revision 1.32 1999/01/25 14:40:20 mhaveman - * Added new return states for the virtual management port if multiple - * ports are active but differently configured. - * - * Revision 1.31 1998/12/11 15:17:02 gklug - * add: Link partnet autoneg states : Unknown Manual and Autonegotiation - * - * Revision 1.30 1998/12/07 12:17:04 gklug - * add: Link Partner autonegotiation flag - * - * Revision 1.29 1998/12/01 10:54:42 gklug - * add: variables for XMAC Errata - * - * Revision 1.28 1998/12/01 10:14:15 gklug - * add: PIsave saves the Interrupt status word - * - * Revision 1.27 1998/11/26 15:24:52 mhaveman - * Added link status states SK_LMODE_STAT_AUTOHALF and - * SK_LMODE_STAT_AUTOFULL which are used by PNMI. - * - * Revision 1.26 1998/11/26 14:53:01 gklug - * add:autoNeg Timeout variable - * - * Revision 1.25 1998/11/26 08:58:50 gklug - * add: Link Mode configuration (AUTO Sense mode) - * - * Revision 1.24 1998/11/24 13:30:27 gklug - * add: PCheckPar to port struct - * - * Revision 1.23 1998/11/18 13:23:26 malthoff - * Add SK_PKT_TO_MAX. - * - * Revision 1.22 1998/11/18 13:19:54 gklug - * add: PPrevShorts and PLinkBroken to port struct for WA XMAC Errata #C1 - * - * Revision 1.21 1998/10/26 08:02:57 malthoff - * Add GIRamOffs. - * - * Revision 1.20 1998/10/19 07:28:37 malthoff - * Add prototype for SkGeInitRamIface(). - * - * Revision 1.19 1998/10/14 14:47:48 malthoff - * SK_TIMER should not be defined for Diagnostics. - * Add SKERR_HWI_E015MSG and SKERR_HWI_E016MSG. - * - * Revision 1.18 1998/10/14 14:00:03 gklug - * add: timer to port struct for workaround of Errata #2 - * - * Revision 1.17 1998/10/14 11:23:09 malthoff - * Add prototype for SkXmAutoNegDone(). - * Fix SkXmSetRxCmd() prototype statement. - * - * Revision 1.16 1998/10/14 05:42:29 gklug - * add: HWLinkUp flag to Port struct - * - * Revision 1.15 1998/10/09 08:26:33 malthoff - * Rename SK_RB_ULPP_B to SK_RB_LLPP_B. - * - * Revision 1.14 1998/10/09 07:11:13 malthoff - * bug fix: SK_FACT_53 is 85 not 117. - * Rework time out init values. - * Add GIPortUsage and corresponding defines. - * Add some error log messages. - * - * Revision 1.13 1998/10/06 14:13:14 malthoff - * Add prototype for SkGeLoadLnkSyncCnt(). - * - * Revision 1.12 1998/10/05 11:29:53 malthoff - * bug fix: A comment was not closed. - * - * Revision 1.11 1998/10/05 08:01:59 malthoff - * Add default Timeout- Threshold- and - * Watermark constants. Add QRam start and end - * variables. Also add vars to store the polling - * mode and receive command. Add new Error Log - * Messages and function prototypes. - * - * Revision 1.10 1998/09/28 13:34:48 malthoff - * Add mode bits for LED functions. - * Move Autoneg and Flow Ctrl bits from shgesirq.h - * Add the required Error Log Entries - * and Function Prototypes. - * - * Revision 1.9 1998/09/16 14:38:41 malthoff - * Rework the SK_LNK_xxx defines. - * Add error log message defines. - * Add prototypes for skxmac2.c - * - * Revision 1.8 1998/09/11 05:29:18 gklug - * add: init state of a port - * - * Revision 1.7 1998/09/08 08:35:52 gklug - * add: defines of the Init Levels - * - * Revision 1.6 1998/09/03 13:48:42 gklug - * add: Link strati, capabilities to Port struct - * - * Revision 1.5 1998/09/03 13:30:59 malthoff - * Add SK_LNK_BLINK and SK_LNK_PERM. - * - * Revision 1.4 1998/09/03 09:55:31 malthoff - * Add constants for parameters Dir and RstMode - * when calling SkGeStopPort(). - * Rework the prototype section. - * Add Queue Address offsets PRxQOff, PXsQOff, and PXaQOff. - * Remove Ioc with IoC. - * - * Revision 1.3 1998/08/19 09:11:54 gklug - * fix: struct are removed from c-source (see CCC) - * add: typedefs for all structs - * - * Revision 1.2 1998/07/28 12:38:26 malthoff - * The prototypes got the parameter 'IoC'. - * - * Revision 1.1 1998/07/23 09:50:24 malthoff - * Created. - * - ******************************************************************************/ - #ifndef __INC_SKGEINIT_H_ #define __INC_SKGEINIT_H_ @@ -331,9 +29,11 @@ /* defines ********************************************************************/ +#define SK_TEST_VAL 0x11335577UL + /* modifying Link LED behaviour (used with SkGeLinkLED()) */ #define SK_LNK_OFF LED_OFF -#define SK_LNK_ON (LED_ON | LED_BLK_OFF | LED_SYNC_OFF) +#define SK_LNK_ON (LED_ON | LED_BLK_OFF | LED_SYNC_OFF) #define SK_LNK_BLINK (LED_ON | LED_BLK_ON | LED_SYNC_ON) #define SK_LNK_PERM (LED_ON | LED_BLK_OFF | LED_SYNC_ON) #define SK_LNK_TST (LED_ON | LED_BLK_ON | LED_SYNC_OFF) @@ -355,14 +55,17 @@ #define SK_LED_TST 2 /* Counter and Timer constants, for a host clock of 62.5 MHz */ -#define SK_XMIT_DUR 0x002faf08L /* 50 ms */ -#define SK_BLK_DUR 0x01dcd650L /* 500 ms */ +#define SK_XMIT_DUR 0x002faf08UL /* 50 ms */ +#define SK_BLK_DUR 0x01dcd650UL /* 500 ms */ -#define SK_DPOLL_DEF 0x00EE6B28L /* 250 ms */ -#define SK_DPOLL_MAX 0x00FFFFFFL /* ca. 268ms */ +#define SK_DPOLL_DEF 0x00ee6b28UL /* 250 ms at 62.5 MHz */ + +#define SK_DPOLL_MAX 0x00ffffffUL /* 268 ms at 62.5 MHz */ + /* 215 ms at 78.12 MHz */ #define SK_FACT_62 100 /* is given in percent */ -#define SK_FACT_53 85 +#define SK_FACT_53 85 /* on GENESIS: 53.12 MHz */ +#define SK_FACT_78 125 /* on YUKON: 78.12 MHz */ /* Timeout values */ #define SK_MAC_TO_53 72 /* MAC arbiter timeout */ @@ -450,9 +153,7 @@ #define SK_LMODE_AUTOFULL 4 /* AutoFull Duplex Mode */ #define SK_LMODE_AUTOBOTH 5 /* AutoBoth Duplex Mode */ #define SK_LMODE_AUTOSENSE 6 /* configured mode auto sensing */ -#define SK_LMODE_INDETERMINATED 7 /* Return value for virtual port if - * multiple ports are differently configured. - */ +#define SK_LMODE_INDETERMINATED 7 /* indeterminated */ /* Auto-negotiation timeout in 100ms granularity */ #define SK_AND_MAX_TO 6 /* Wait 600 msec before link comes up */ @@ -468,27 +169,21 @@ #define SK_LSPEED_CAP_10MBPS (1<<1) /* 10 Mbps */ #define SK_LSPEED_CAP_100MBPS (1<<2) /* 100 Mbps */ #define SK_LSPEED_CAP_1000MBPS (1<<3) /* 1000 Mbps */ -#define SK_LSPEED_CAP_INDETERMINATED (1<<4) /* Return value for virtual port if - * multiple ports are differently configured. - */ +#define SK_LSPEED_CAP_INDETERMINATED (1<<4) /* indeterminated */ /* Link Speed Parameter */ #define SK_LSPEED_AUTO 1 /* Automatic resolution */ #define SK_LSPEED_10MBPS 2 /* 10 Mbps */ #define SK_LSPEED_100MBPS 3 /* 100 Mbps */ #define SK_LSPEED_1000MBPS 4 /* 1000 Mbps */ -#define SK_LSPEED_INDETERMINATED 5 /* Return value for virtual port if - * multiple ports are differently configured. - */ +#define SK_LSPEED_INDETERMINATED 5 /* indeterminated */ /* Link Speed Current State */ #define SK_LSPEED_STAT_UNKNOWN 1 #define SK_LSPEED_STAT_10MBPS 2 #define SK_LSPEED_STAT_100MBPS 3 #define SK_LSPEED_STAT_1000MBPS 4 -#define SK_LSPEED_STAT_INDETERMINATED 5 /* Return value for virtual port if - * multiple ports are differently configured. - */ +#define SK_LSPEED_STAT_INDETERMINATED 5 /* Link Capability Parameter */ @@ -496,62 +191,50 @@ #define SK_LMODE_CAP_FULL (1<<1) /* Full Duplex Mode */ #define SK_LMODE_CAP_AUTOHALF (1<<2) /* AutoHalf Duplex Mode */ #define SK_LMODE_CAP_AUTOFULL (1<<3) /* AutoFull Duplex Mode */ -#define SK_LMODE_CAP_INDETERMINATED (1<<4) /* Return value for virtual port if - * multiple ports are differently configured. - */ +#define SK_LMODE_CAP_INDETERMINATED (1<<4) /* indeterminated */ /* Link Mode Current State */ #define SK_LMODE_STAT_UNKNOWN 1 /* Unknown Duplex Mode */ #define SK_LMODE_STAT_HALF 2 /* Half Duplex Mode */ #define SK_LMODE_STAT_FULL 3 /* Full Duplex Mode */ -#define SK_LMODE_STAT_AUTOHALF 4 /* Half Duplex Mode obtained by AutoNeg */ -#define SK_LMODE_STAT_AUTOFULL 5 /* Full Duplex Mode obtained by AutoNeg */ -#define SK_LMODE_STAT_INDETERMINATED 6 /* Return value for virtual port if - * multiple ports are differently configured. - */ +#define SK_LMODE_STAT_AUTOHALF 4 /* Half Duplex Mode obtained by Auto-Neg */ +#define SK_LMODE_STAT_AUTOFULL 5 /* Full Duplex Mode obtained by Auto-Neg */ +#define SK_LMODE_STAT_INDETERMINATED 6 /* indeterminated */ + /* Flow Control Mode Parameter (and capabilities) */ -#define SK_FLOW_MODE_NONE 1 /* No Flow Control */ +#define SK_FLOW_MODE_NONE 1 /* No Flow-Control */ #define SK_FLOW_MODE_LOC_SEND 2 /* Local station sends PAUSE */ -#define SK_FLOW_MODE_SYMMETRIC 3 /* Both station may send PAUSE */ -#define SK_FLOW_MODE_SYM_OR_REM 4 /* Both station may send PAUSE or +#define SK_FLOW_MODE_SYMMETRIC 3 /* Both stations may send PAUSE */ +#define SK_FLOW_MODE_SYM_OR_REM 4 /* Both stations may send PAUSE or * just the remote station may send PAUSE */ -#define SK_FLOW_MODE_INDETERMINATED 5 /* Return value for virtual port if - * multiple ports are differently configured. - */ +#define SK_FLOW_MODE_INDETERMINATED 5 /* indeterminated */ /* Flow Control Status Parameter */ #define SK_FLOW_STAT_NONE 1 /* No Flow Control */ #define SK_FLOW_STAT_REM_SEND 2 /* Remote Station sends PAUSE */ #define SK_FLOW_STAT_LOC_SEND 3 /* Local station sends PAUSE */ #define SK_FLOW_STAT_SYMMETRIC 4 /* Both station may send PAUSE */ -#define SK_FLOW_STAT_INDETERMINATED 5 /* Return value for virtual port if - * multiple ports are differently configured. - */ +#define SK_FLOW_STAT_INDETERMINATED 5 /* indeterminated */ + /* Master/Slave Mode Capabilities */ #define SK_MS_CAP_AUTO (1<<0) /* Automatic resolution */ #define SK_MS_CAP_MASTER (1<<1) /* This station is master */ #define SK_MS_CAP_SLAVE (1<<2) /* This station is slave */ -#define SK_MS_CAP_INDETERMINATED (1<<3) /* Return value for virtual port if - * multiple ports are differently configured. - */ +#define SK_MS_CAP_INDETERMINATED (1<<3) /* indeterminated */ /* Set Master/Slave Mode Parameter (and capabilities) */ #define SK_MS_MODE_AUTO 1 /* Automatic resolution */ #define SK_MS_MODE_MASTER 2 /* This station is master */ #define SK_MS_MODE_SLAVE 3 /* This station is slave */ -#define SK_MS_MODE_INDETERMINATED 4 /* Return value for virtual port if - * multiple ports are differently - */ +#define SK_MS_MODE_INDETERMINATED 4 /* indeterminated */ /* Master/Slave Status Parameter */ -#define SK_MS_STAT_UNSET 1 /* The MS status is never been determ*/ +#define SK_MS_STAT_UNSET 1 /* The M/S status is not set */ #define SK_MS_STAT_MASTER 2 /* This station is master */ #define SK_MS_STAT_SLAVE 3 /* This station is slave */ -#define SK_MS_STAT_FAULT 4 /* MS resolution failed */ -#define SK_MS_STAT_INDETERMINATED 5 /* Return value for virtual port if - * multiple ports are differently - */ +#define SK_MS_STAT_FAULT 4 /* M/S resolution failed */ +#define SK_MS_STAT_INDETERMINATED 5 /* indeterminated */ /* parameter 'Mode' when calling SkXmSetRxCmd() */ #define SK_STRIP_FCS_ON (1<<0) /* Enable FCS stripping of Rx frames */ @@ -560,8 +243,8 @@ #define SK_STRIP_PAD_OFF (1<<3) /* Disable pad byte stripping of Rx fr */ #define SK_LENERR_OK_ON (1<<4) /* Don't chk fr for in range len error */ #define SK_LENERR_OK_OFF (1<<5) /* Check frames for in range len error */ -#define SK_BIG_PK_OK_ON (1<<6) /* Don't set rcvError bit for big fr */ -#define SK_BIG_PK_OK_OFF (1<<7) /* Set rcvError bit for big frames */ +#define SK_BIG_PK_OK_ON (1<<6) /* Don't set Rx Error bit for big frames */ +#define SK_BIG_PK_OK_OFF (1<<7) /* Set Rx Error bit for big frames */ #define SK_SELF_RX_ON (1<<8) /* Enable Rx of own packets */ #define SK_SELF_RX_OFF (1<<9) /* Disable Rx of own packets */ @@ -579,9 +262,21 @@ #define SK_PRT_INIT 2 /* the port is initialized */ #define SK_PRT_RUN 3 /* the port has an active link */ +/* PHY power down modes */ +#define PHY_PM_OPERATIONAL_MODE 0 /* PHY operational mode */ +#define PHY_PM_DEEP_SLEEP 1 /* coma mode --> minimal power */ +#define PHY_PM_IEEE_POWER_DOWN 2 /* IEEE 22.2.4.1.5 compl. power down */ +#define PHY_PM_ENERGY_DETECT 3 /* energy detect */ +#define PHY_PM_ENERGY_DETECT_PLUS 4 /* energy detect plus */ + /* Default receive frame limit for Workaround of XMAC Errata */ #define SK_DEF_RX_WA_LIM SK_CONSTU64(100) +/* values for GILedBlinkCtrl (LED Blink Control) */ +#define SK_ACT_LED_BLINK (1<<0) /* Active LED blinking */ +#define SK_DUP_LED_NORMAL (1<<1) /* Duplex LED normal */ +#define SK_LED_LINK100_ON (1<<2) /* Link 100M LED on */ + /* Link Partner Status */ #define SK_LIPA_UNKNOWN 0 /* Link partner is in unknown state */ #define SK_LIPA_MANUAL 1 /* Link partner is in detected manual state */ @@ -601,10 +296,10 @@ typedef struct s_GeMacFunc { int (*pFnMacUpdateStats)(SK_AC *pAC, SK_IOC IoC, unsigned int Port); int (*pFnMacStatistic)(SK_AC *pAC, SK_IOC IoC, unsigned int Port, - SK_U16 StatAddr, SK_U32 *pVal); + SK_U16 StatAddr, SK_U32 SK_FAR *pVal); int (*pFnMacResetCounter)(SK_AC *pAC, SK_IOC IoC, unsigned int Port); int (*pFnMacOverflow)(SK_AC *pAC, SK_IOC IoC, unsigned int Port, - SK_U16 IStatus, SK_U64 *pVal); + SK_U16 IStatus, SK_U64 SK_FAR *pVal); } SK_GEMACFUNC; /* @@ -615,7 +310,7 @@ SK_TIMER PWaTimer; /* Workaround Timer */ SK_TIMER HalfDupChkTimer; #endif /* SK_DIAG */ - SK_U32 PPrevShorts; /* Previous short Counter checking */ + SK_U32 PPrevShorts; /* Previous Short Counter checking */ SK_U32 PPrevFcs; /* Previous FCS Error Counter checking */ SK_U64 PPrevRx; /* Previous RxOk Counter checking */ SK_U64 PRxLim; /* Previous RxOk Counter checking */ @@ -637,12 +332,13 @@ int PXsQOff; /* Synchronous Tx Queue Address Offset */ int PXaQOff; /* Asynchronous Tx Queue Address Offset */ int PhyType; /* PHY used on this port */ + int PState; /* Port status (reset, stop, init, run) */ SK_U16 PhyId1; /* PHY Id1 on this port */ SK_U16 PhyAddr; /* MDIO/MDC PHY address */ SK_U16 PIsave; /* Saved Interrupt status word */ SK_U16 PSsave; /* Saved PHY status word */ + SK_U16 PGmANegAdv; /* Saved GPhy AutoNegAdvertisment register */ SK_BOOL PHWLinkUp; /* The hardware Link is up (wiring) */ - SK_BOOL PState; /* Is port initialized ? */ SK_BOOL PLinkBroken; /* Is Link broken ? */ SK_BOOL PCheckPar; /* Do we check for parity errors ? */ SK_BOOL HalfDupTimerActive; @@ -659,11 +355,18 @@ SK_U8 PMSCap; /* Master/Slave Capabilities */ SK_U8 PMSMode; /* Master/Slave Mode */ SK_U8 PMSStatus; /* Master/Slave Status */ - SK_U8 PAutoNegFail; /* Auto-negotiation fail flag */ + SK_BOOL PAutoNegFail; /* Auto-negotiation fail flag */ SK_U8 PLipaAutoNeg; /* Auto-negotiation possible with Link Partner */ SK_U8 PCableLen; /* Cable Length */ SK_U8 PMdiPairLen[4]; /* MDI[0..3] Pair Length */ SK_U8 PMdiPairSts[4]; /* MDI[0..3] Pair Diagnostic Status */ + SK_U8 PPhyPowerState; /* PHY current power state */ + int PMacColThres; /* MAC Collision Threshold */ + int PMacJamLen; /* MAC Jam length */ + int PMacJamIpgVal; /* MAC Jam IPG */ + int PMacJamIpgData; /* MAC IPG Jam to Data */ + int PMacIpgData; /* MAC Data IPG */ + SK_BOOL PMacLimit4; /* reset collision counter and backoff algorithm */ } SK_GEPORT; /* @@ -671,24 +374,29 @@ * (has to be included in the adapter context) */ typedef struct s_GeInit { + int GIChipId; /* Chip Identification Number */ + int GIChipRev; /* Chip Revision Number */ SK_U8 GIPciHwRev; /* PCI HW Revision Number */ - SK_U8 GIChipId; /* Chip Identification Number */ - SK_U8 GIChipRev; /* Chip Revision Number */ SK_BOOL GIGenesis; /* Genesis adapter ? */ + SK_BOOL GIYukon; /* YUKON-A1/Bx chip */ + SK_BOOL GIYukonLite; /* YUKON-Lite chip */ SK_BOOL GICopperType; /* Copper Type adapter ? */ SK_BOOL GIPciSlot64; /* 64-bit PCI Slot */ SK_BOOL GIPciClock66; /* 66 MHz PCI Clock */ SK_BOOL GIVauxAvail; /* VAUX available (YUKON) */ SK_BOOL GIYukon32Bit; /* 32-Bit YUKON adapter */ + SK_U16 GILedBlinkCtrl; /* LED Blink Control */ int GIMacsFound; /* Number of MACs found on this adapter */ int GIMacType; /* MAC Type used on this adapter */ int GIHstClkFact; /* Host Clock Factor (62.5 / HstClk * 100) */ - int GIPortUsage; /* Driver Port Usage: SK_RED_LINK/SK_MUL_LINK */ + int GIPortUsage; /* Driver Port Usage */ int GILevel; /* Initialization Level completed */ int GIRamSize; /* The RAM size of the adapter in kB */ - int GIWolOffs; /* WOL Register Offset (HW-Bug in 1st revision) */ + int GIWolOffs; /* WOL Register Offset (HW-Bug in Rev. A) */ SK_U32 GIRamOffs; /* RAM Address Offset for addr calculation */ - SK_U32 GIPollTimerVal; /* Descriptor Poll Timer Init Val in clk ticks*/ + SK_U32 GIPollTimerVal; /* Descr. Poll Timer Init Val (HstClk ticks) */ + SK_U32 GIValIrqMask; /* Value for Interrupt Mask */ + SK_U32 GITimeStampCnt; /* Time Stamp High Counter (YUKON only) */ SK_GEPORT GP[SK_MAX_MACS];/* Port Dependent Information */ SK_GEMACFUNC GIFunc; /* MAC depedent functions */ } SK_GEINIT; @@ -717,7 +425,7 @@ #define SKERR_HWI_E010 (SKERR_HWI_E009+1) #define SKERR_HWI_E010MSG "SkGeCfgSync() called with invalid parameters" #define SKERR_HWI_E011 (SKERR_HWI_E010+1) -#define SKERR_HWI_E011MSG "SkGeInitPort(): Receive Queue Size to small" +#define SKERR_HWI_E011MSG "SkGeInitPort(): Receive Queue Size too small" #define SKERR_HWI_E012 (SKERR_HWI_E011+1) #define SKERR_HWI_E012MSG "SkGeInitPort(): invalid Queue Size specified" #define SKERR_HWI_E013 (SKERR_HWI_E012+1) @@ -741,7 +449,7 @@ #define SKERR_HWI_E022 (SKERR_HWI_E021+1) #define SKERR_HWI_E022MSG "MacStatistic(): illegal statistic base address" #define SKERR_HWI_E023 (SKERR_HWI_E022+1) -#define SKERR_HWI_E023MSG "SkGeInitPort(): Transmit Queue Size to small" +#define SKERR_HWI_E023MSG "SkGeInitPort(): Transmit Queue Size too small" #define SKERR_HWI_E024 (SKERR_HWI_E023+1) #define SKERR_HWI_E024MSG "FATAL: SkGeStopPort() does not terminate (Rx)" #define SKERR_HWI_E025 (SKERR_HWI_E024+1) @@ -839,6 +547,11 @@ SK_IOC IoC, int Port); +extern void SkMacClearRst( + SK_AC *pAC, + SK_IOC IoC, + int Port); + extern void SkXmInitMac( SK_AC *pAC, SK_IOC IoC, @@ -914,7 +627,7 @@ SK_IOC IoC, int Port, int Addr, - SK_U16 *pVal); + SK_U16 SK_FAR *pVal); extern void SkXmPhyWrite( SK_AC *pAC, @@ -928,7 +641,7 @@ SK_IOC IoC, int Port, int Addr, - SK_U16 *pVal); + SK_U16 SK_FAR *pVal); extern void SkGmPhyWrite( SK_AC *pAC, @@ -937,20 +650,6 @@ int Addr, SK_U16 Val); -extern void SkGePhyRead( - SK_AC *pAC, - SK_IOC IoC, - int Port, - int Addr, - SK_U16 *pVal); - -extern void SkGePhyWrite( - SK_AC *pAC, - SK_IOC IoC, - int Port, - int Addr, - SK_U16 Val); - extern void SkXmClrExactAddr( SK_AC *pAC, SK_IOC IoC, @@ -989,14 +688,14 @@ SK_IOC IoC, unsigned int Port, SK_U16 StatAddr, - SK_U32 *pVal); + SK_U32 SK_FAR *pVal); extern int SkGmMacStatistic( SK_AC *pAC, SK_IOC IoC, unsigned int Port, SK_U16 StatAddr, - SK_U32 *pVal); + SK_U32 SK_FAR *pVal); extern int SkXmResetCounter( SK_AC *pAC, @@ -1013,14 +712,14 @@ SK_IOC IoC, unsigned int Port, SK_U16 IStatus, - SK_U64 *pStatus); + SK_U64 SK_FAR *pStatus); extern int SkGmOverflowStatus( SK_AC *pAC, SK_IOC IoC, unsigned int Port, SK_U16 MacStatus, - SK_U64 *pStatus); + SK_U64 SK_FAR *pStatus); extern int SkGmCableDiagStatus( SK_AC *pAC, @@ -1028,7 +727,32 @@ int Port, SK_BOOL StartTest); +extern int SkGmEnterLowPowerMode( + SK_AC *pAC, + SK_IOC IoC, + int Port, + SK_U8 Mode); + +extern int SkGmLeaveLowPowerMode( + SK_AC *pAC, + SK_IOC IoC, + int Port); + #ifdef SK_DIAG +extern void SkGePhyRead( + SK_AC *pAC, + SK_IOC IoC, + int Port, + int Addr, + SK_U16 *pVal); + +extern void SkGePhyWrite( + SK_AC *pAC, + SK_IOC IoC, + int Port, + int Addr, + SK_U16 Val); + extern void SkMacSetRxCmd( SK_AC *pAC, SK_IOC IoC, @@ -1075,6 +799,7 @@ extern void SkMacRxTxDisable(); extern void SkMacSoftRst(); extern void SkMacHardRst(); +extern void SkMacClearRst(); extern void SkMacInitPhy(); extern int SkMacRxTxEnable(); extern void SkMacPromiscMode(); @@ -1086,8 +811,6 @@ extern int SkMacAutoNegDone(); extern void SkMacAutoNegLipaPhy(); extern void SkMacSetRxTxEn(); -extern void SkGePhyRead(); -extern void SkGePhyWrite(); extern void SkXmInitMac(); extern void SkXmPhyRead(); extern void SkXmPhyWrite(); @@ -1107,8 +830,12 @@ extern int SkXmOverflowStatus(); extern int SkGmOverflowStatus(); extern int SkGmCableDiagStatus(); +extern int SkGmEnterLowPowerMode(); +extern int SkGmLeaveLowPowerMode(); #ifdef SK_DIAG +extern void SkGePhyRead(); +extern void SkGePhyWrite(); extern void SkMacSetRxCmd(); extern void SkMacCrcGener(); extern void SkMacTimeStamp(); Index: drivers/net/sk98lin/h/skgepnm2.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/skgepnm2.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/skgepnm2.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/skgepnm2.h 4 Aug 2004 01:29:23 -0000 1.2 @@ -2,15 +2,14 @@ * * Name: skgepnm2.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ * Purpose: Defines for Private Network Management Interface * ****************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2001 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,140 +20,6 @@ * ******************************************************************************/ -/***************************************************************************** - * - * History: - * - * $Log: skgepnm2.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.34 2002/12/16 09:05:18 tschilli - * Code for VCT handling added. - * - * Revision 1.33 2002/09/10 09:00:03 rwahl - * Adapted boolean definitions according sktypes. - * - * Revision 1.32 2002/08/09 09:47:01 rwahl - * Added write-only flag to oid access defines. - * Editorial changes. - * - * Revision 1.31 2002/07/17 19:23:18 rwahl - * - Replaced MAC counter definitions by enumeration. - * - Added definition SK_PNMI_MAC_TYPES. - * - Added chipset defnition for Yukon. - * - * Revision 1.30 2001/02/06 10:03:41 mkunz - * - Pnmi V4 dual net support added. Interface functions and macros extended - * - Vpd bug fixed - * - OID_SKGE_MTU added - * - * Revision 1.29 2001/01/22 13:41:37 rassmann - * Supporting two nets on dual-port adapters. - * - * Revision 1.28 2000/08/03 15:12:48 rwahl - * - Additional comment for MAC statistic data structure. - * - * Revision 1.27 2000/08/01 16:10:18 rwahl - * - Added mac statistic data structure for StatRxLongFrame counter. - * - * Revision 1.26 2000/03/31 13:51:34 rwahl - * Added SK_UPTR cast to offset calculation for PNMI struct fields; - * missing cast caused compiler warnings by Win64 compiler. - * - * Revision 1.25 1999/11/22 13:57:41 cgoos - * Changed license header to GPL. - * Allowing overwrite for SK_PNMI_STORE/_READ defines. - * - * Revision 1.24 1999/04/13 15:11:11 mhaveman - * Changed copyright. - * - * Revision 1.23 1999/01/28 15:07:12 mhaveman - * Changed default threshold for port switches per hour from 10 - * to 240 which means 4 switches per minute. This fits better - * the granularity of 32 for the port switch estimate - * counter. - * - * Revision 1.22 1999/01/05 12:52:30 mhaveman - * Removed macro SK_PNMI_MICRO_SEC. - * - * Revision 1.21 1999/01/05 12:50:34 mhaveman - * Enlarged macro definition SK_PNMI_HUNDREDS_SEC() so that no 64-bit - * arithmetic is necessary if SK_TICKS_PER_SEC is 100. - * - * Revision 1.20 1998/12/09 14:02:53 mhaveman - * Defined macro SK_PNMI_DEF_RLMT_CHG_THRES for default port switch - * threshold. - * - * Revision 1.19 1998/12/03 11:28:41 mhaveman - * Removed SK_PNMI_CHECKPTR macro. - * - * Revision 1.18 1998/12/03 11:21:00 mhaveman - * -Added pointer check macro SK_PNMI_CHECKPTR - * -Added macros SK_PNMI_VPD_ARR_SIZE and SK_PNMI_VPD_STR_SIZE for - * VPD key evaluation. - * - * Revision 1.17 1998/11/20 13:20:33 mhaveman - * Fixed bug in SK_PNMI_SET_STAT macro. ErrorStatus was not correctly set. - * - * Revision 1.16 1998/11/20 08:08:49 mhaveman - * Macro SK_PNMI_CHECKFLAGS has got a if clause. - * - * Revision 1.15 1998/11/03 13:53:40 mhaveman - * Fixed alignment problem in macor SK_PNMI_SET_STAT macro. - * - * Revision 1.14 1998/10/30 15:50:13 mhaveman - * Added macro SK_PNMI_MICRO_SEC() - * - * Revision 1.13 1998/10/30 12:32:20 mhaveman - * Added forgotten cast in SK_PNMI_READ_U32 macro. - * - * Revision 1.12 1998/10/29 15:40:26 mhaveman - * -Changed SK_PNMI_TRAP_SENSOR_LEN because SensorDescr has now - * variable string length. - * -Defined SK_PNMI_CHECKFLAGS macro - * - * Revision 1.11 1998/10/29 08:53:34 mhaveman - * Removed SK_PNMI_RLM_XXX table indexed because these counters need - * not been saved over XMAC resets. - * - * Revision 1.10 1998/10/28 08:48:20 mhaveman - * -Added macros for storage according to alignment - * -Changed type of Instance to SK_U32 because of VPD - * -Removed trap structures. Not needed because of alignment problem - * -Changed type of Action form SK_U8 to int - * - * Revision 1.9 1998/10/21 13:34:45 mhaveman - * Shit, mismatched calculation of SK_PNMI_HUNDREDS_SEC. Corrected. - * - * Revision 1.8 1998/10/21 13:24:58 mhaveman - * Changed calculation of hundreds of seconds. - * - * Revision 1.7 1998/10/20 07:31:41 mhaveman - * Made type changes to unsigned int where possible. - * - * Revision 1.6 1998/09/04 17:04:05 mhaveman - * Added Sync counters to offset storage to provided settled values on - * port switch. - * - * Revision 1.5 1998/09/04 12:45:35 mhaveman - * Removed dummies for SK_DRIVER_ macros. They should be added by driver - * writer in skdrv2nd.h. - * - * Revision 1.4 1998/09/04 11:59:50 mhaveman - * Everything compiles now. Driver Macros for counting still missing. - * - * Revision 1.3 1998/08/24 12:01:35 mhaveman - * Intermediate state. - * - * Revision 1.2 1998/08/17 07:51:40 mhaveman - * Intermediate state. - * - * Revision 1.1 1998/08/11 09:08:40 mhaveman - * Intermediate state. - * - ****************************************************************************/ - #ifndef _SKGEPNM2_H_ #define _SKGEPNM2_H_ @@ -362,11 +227,13 @@ /* * Time macros */ +#ifndef SK_PNMI_HUNDREDS_SEC #if SK_TICKS_PER_SEC == 100 #define SK_PNMI_HUNDREDS_SEC(t) (t) #else #define SK_PNMI_HUNDREDS_SEC(t) (((t) * 100) / (SK_TICKS_PER_SEC)) -#endif +#endif /* !SK_TICKS_PER_SEC */ +#endif /* !SK_PNMI_HUNDREDS_SEC */ /* * Macros to work around alignment problems Index: drivers/net/sk98lin/h/skgepnmi.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/skgepnmi.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/skgepnmi.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/skgepnmi.h 4 Aug 2004 01:29:23 -0000 1.2 @@ -2,15 +2,14 @@ * * Name: skgepnmi.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ * Purpose: Defines for Private Network Management Interface * ****************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2001 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,218 +20,6 @@ * ******************************************************************************/ -/***************************************************************************** - * - * History: - * - * $Log: skgepnmi.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.59 2002/12/16 14:03:50 tschilli - * New defines for VCT added. - * - * Revision 1.58 2002/12/16 09:04:59 tschilli - * Code for VCT handling added. - * - * Revision 1.57 2002/09/26 12:41:05 tschilli - * SK_PNMI_PORT BufPort entry in struct SK_PNMI added. - * - * Revision 1.56 2002/08/16 11:10:41 rwahl - * - Replaced c++ comment. - * - * Revision 1.55 2002/08/09 15:40:21 rwahl - * Editorial change (renamed ConfSpeedCap). - * - * Revision 1.54 2002/08/09 11:06:07 rwahl - * Added OID_SKGE_SPEED_CAP. - * - * Revision 1.53 2002/08/09 09:45:28 rwahl - * Added support for NDIS OID_PNP_xxx. - * Editorial changes. - * - * Revision 1.52 2002/08/06 17:54:07 rwahl - * - Added speed cap to PNMI config struct. - * - * Revision 1.51 2002/07/17 19:19:26 rwahl - * - Added OID_SKGE_SPEED_MODE and OID_SKGE_SPEED_STATUS. - * - Added SK_PNMI_CNT_RX_PMACC_ERR() & SK_PNMI_CNT_RX_LONGFRAMES(). - * - Added speed mode & status to PNMI config struct. - * - Editorial changes. - * - * Revision 1.50 2002/05/22 08:59:37 rwahl - * Added string definitions for error msgs. - * - * Revision 1.49 2001/11/20 09:23:50 rwahl - * - pnmi struct: reordered and aligned to 32bit. - * - * Revision 1.48 2001/02/23 14:34:24 mkunz - * Changed macro PHYS2INST. Added pAC to Interface - * - * Revision 1.47 2001/02/07 08:28:23 mkunz - * - Added Oids: OID_SKGE_DIAG_ACTION - * OID_SKGE_DIAG_RESULT - * OID_SKGE_MULTICAST_LIST - * OID_SKGE_CURRENT_PACKET_FILTER - * OID_SKGE_INTERMEDIATE_SUPPORT - * - Changed value of OID_SKGE_MTU - * - * Revision 1.46 2001/02/06 10:01:41 mkunz - * - Pnmi V4 dual net support added. Interface functions and macros extended - * - Vpd bug fixed - * - OID_SKGE_MTU added - * - * Revision 1.45 2001/01/22 13:41:37 rassmann - * Supporting two nets on dual-port adapters. - * - * Revision 1.44 2000/09/07 07:35:27 rwahl - * - removed NDIS counter specific data type. - * - fixed spelling for OID_SKGE_RLMT_PORT_PREFERRED. - * - * Revision 1.43 2000/08/04 11:41:08 rwahl - * - Fixed compiler warning (port is always >= 0) for macros - * SK_PNMI_CNT_RX_LONGFRAMES & SK_PNMI_CNT_SYNC_OCTETS - * - * Revision 1.42 2000/08/03 15:14:07 rwahl - * - Corrected error in driver macros addressing a physical port. - * - * Revision 1.41 2000/08/01 16:22:29 rwahl - * - Changed MDB version to 3.1. - * - Added definitions for StatRxLongFrames counter. - * - Added macro to be used by driver to count long frames received. - * - Added directive to control width (default = 32bit) of NDIS statistic - * counters (SK_NDIS_64BIT_CTR). - * - * Revision 1.40 2000/03/31 13:51:34 rwahl - * Added SK_UPTR cast to offset calculation for PNMI struct fields; - * missing cast caused compiler warnings by Win64 compiler. - * - * Revision 1.39 1999/12/06 10:09:47 rwahl - * Added new error log message. - * - * Revision 1.38 1999/11/22 13:57:55 cgoos - * Changed license header to GPL. - * - * Revision 1.37 1999/09/14 14:25:32 rwahl - * Set MDB version for 1000Base-T (sensors, Master/Slave) changes. - * - * Revision 1.36 1999/05/20 09:24:56 cgoos - * Changes for 1000Base-T (sensors, Master/Slave). - * - * Revision 1.35 1999/04/13 15:10:51 mhaveman - * Replaced RLMT macros SK_RLMT_CHECK_xxx again by those of PNMI to - * grant unified interface. But PNMI macros will store the same - * value as RLMT macros. - * - * Revision 1.34 1999/04/13 15:03:49 mhaveman - * -Changed copyright - * -Removed SK_PNMI_RLMT_MODE_CHK_xxx macros. Those of RLMT should be - * used. - * - * Revision 1.33 1999/03/23 10:41:02 mhaveman - * Changed comments. - * - * Revision 1.32 1999/01/25 15:01:33 mhaveman - * Added support for multiple simultaniously active ports. - * - * Revision 1.31 1999/01/19 10:06:26 mhaveman - * Added new error log message. - * - * Revision 1.30 1999/01/05 10:34:49 mhaveman - * Fixed little error in RlmtChangeEstimate calculation. - * - * Revision 1.29 1999/01/05 09:59:41 mhaveman - * Redesigned port switch average calculation to avoid 64bit - * arithmetic. - * - * Revision 1.28 1998/12/08 10:05:48 mhaveman - * Defined macro SK_PNMI_MIN_STRUCT_SIZE. - * - * Revision 1.27 1998/12/03 14:39:35 mhaveman - * Fixed problem that LSTAT was enumerated wrong. - * - * Revision 1.26 1998/12/03 11:19:51 mhaveman - * Changed contents of errlog message SK_PNMI_ERR016MSG - * - * Revision 1.25 1998/12/01 10:40:04 mhaveman - * Changed size of SensorNumber, ChecksumNumber and RlmtPortNumber in - * SK_PNMI_STRUCT_DATA to be conform with OID definition. - * - * Revision 1.24 1998/11/20 08:09:27 mhaveman - * Added macros to convert between logical, physical port indexes and - * instances. - * - * Revision 1.23 1998/11/10 13:41:13 mhaveman - * Needed to change interface, because NT driver needs a return value - * of needed buffer space on TOO_SHORT errors. Therefore all - * SkPnmiGet/Preset/Set functions now have a pointer to the length - * parameter, where the needed space on error is returned. - * - * Revision 1.22 1998/11/03 12:05:51 mhaveman - * Added pAC parameter to counter macors. - * - * Revision 1.21 1998/11/02 10:47:36 mhaveman - * Added syslog messages for internal errors. - * - * Revision 1.20 1998/10/30 15:49:36 mhaveman - * -Removed unused SK_PNMI_UTILIZATION_BASE and EstOldCnt. - * -Redefined SK_PNMI_CHG_EST_BASE to hundreds of seconds. - * - * Revision 1.19 1998/10/29 15:38:44 mhaveman - * Changed string lengths of PNMI_STRUCT_DATA structure because - * string OIDs are now encoded with leading length ocetet. - * - * Revision 1.18 1998/10/29 08:52:27 mhaveman - * -Added byte to strings in PNMI_STRUCT_DATA structure. - * -Shortened SK_PNMI_RLMT structure to SK_MAX_MACS elements. - * - * Revision 1.17 1998/10/28 08:49:50 mhaveman - * -Changed type of Instance back to SK_U32 because of VPD - * -Changed type from SK_U8 to char of PciBusSpeed, PciBusWidth, PMD, - * and Connector. - * - * Revision 1.16 1998/10/22 10:42:31 mhaveman - * -Removed (SK_U32) casts for OIDs - * -excluded NDIS OIDs when they are already defined with ifndef _NDIS_ - * - * Revision 1.15 1998/10/20 13:56:28 mhaveman - * Headerfile includes now directly other header files to comile correctly. - * - * Revision 1.14 1998/10/20 07:31:09 mhaveman - * Made type changes to unsigned int where possible. - * - * Revision 1.13 1998/10/19 10:53:13 mhaveman - * -Casted OID definitions to SK_U32 - * -Renamed RlmtMAC... to RlmtPort... - * -Changed wrong type of VpdEntriesList from SK_U32 to char * - * - * Revision 1.12 1998/10/13 07:42:27 mhaveman - * -Added OIDs OID_SKGE_TRAP_NUMBER and OID_SKGE_ALL_DATA - * -Removed old cvs history entries - * -Renamed MacNumber to PortNumber - * - * Revision 1.11 1998/10/07 10:55:24 mhaveman - * -Added OID_MDB_VERSION. Therefore was a renumbering of the VPD OIDs - * necessary. - * -Added OID_GEN_ Ids to support the windows driver. - * - * Revision 1.10 1998/09/30 13:41:10 mhaveman - * Renamed some OIDs to reduce usage of 'MAC' which is replaced by 'PORT'. - * - * Revision 1.9 1998/09/04 17:06:17 mhaveman - * -Added SyncCounter as macro. - * -Renamed OID_SKGE_.._NO_DESCR_CTS to OID_SKGE_.._NO_BUF_CTS. - * -Added macros for driver description and version strings. - * - * Revision 1.8 1998/09/04 14:36:52 mhaveman - * Added OIDs and Structure to access value of macro counters which are - * counted by the driver. - * - * Revision 1.7 1998/09/04 11:59:36 mhaveman - * Everything compiles now. Driver Macros for counting still missing. - * - ****************************************************************************/ - #ifndef _SKGEPNMI_H_ #define _SKGEPNMI_H_ @@ -287,6 +74,7 @@ #define SK_PNMI_ERR_UNKNOWN_OID 5 #define SK_PNMI_ERR_UNKNOWN_INST 6 #define SK_PNMI_ERR_UNKNOWN_NET 7 +#define SK_PNMI_ERR_NOT_SUPPORTED 10 /* @@ -439,6 +227,8 @@ #define OID_SKGE_SPEED_MODE 0xFF010171 #define OID_SKGE_SPEED_STATUS 0xFF010172 +#define OID_SKGE_BOARDLEVEL 0xFF010180 + #define OID_SKGE_SENSOR_NUMBER 0xFF020100 #define OID_SKGE_SENSOR_INDEX 0xFF020101 #define OID_SKGE_SENSOR_DESCR 0xFF020102 @@ -557,10 +347,23 @@ #define OID_SKGE_ALL_DATA 0xFF020190 /* Defines for VCT. */ -#define OID_SKGE_VCT_GET 0xFF020200 -#define OID_SKGE_VCT_SET 0xFF020201 -#define OID_SKGE_VCT_STATUS 0xFF020202 - +#define OID_SKGE_VCT_GET 0xFF020200 +#define OID_SKGE_VCT_SET 0xFF020201 +#define OID_SKGE_VCT_STATUS 0xFF020202 + +#ifdef SK_DIAG_SUPPORT +/* Defines for driver DIAG mode. */ +#define OID_SKGE_DIAG_MODE 0xFF020204 +#endif /* SK_DIAG_SUPPORT */ + +/* New OIDs */ +#define OID_SKGE_DRIVER_RELDATE 0xFF020210 +#define OID_SKGE_DRIVER_FILENAME 0xFF020211 +#define OID_SKGE_CHIPID 0xFF020212 +#define OID_SKGE_RAMSIZE 0xFF020213 +#define OID_SKGE_VAUXAVAIL 0xFF020214 +#define OID_SKGE_PHY_TYPE 0xFF020215 +#define OID_SKGE_PHY_LP_MODE 0xFF020216 /* VCT struct to store a backup copy of VCT data after a port reset. */ typedef struct s_PnmiVct { @@ -597,6 +400,23 @@ #define OID_SKGE_TRAP_RLMT_PORT_UP 523 #define OID_SKGE_TRAP_RLMT_SEGMENTATION 524 +#ifdef SK_DIAG_SUPPORT +/* Defines for driver DIAG mode. */ +#define SK_DIAG_ATTACHED 2 +#define SK_DIAG_RUNNING 1 +#define SK_DIAG_IDLE 0 +#endif /* SK_DIAG_SUPPORT */ + +/* + * Generic PNMI IOCTL subcommand definitions. + */ +#define SK_GET_SINGLE_VAR 1 +#define SK_SET_SINGLE_VAR 2 +#define SK_PRESET_SINGLE_VAR 3 +#define SK_GET_FULL_MIB 4 +#define SK_SET_FULL_MIB 5 +#define SK_PRESET_FULL_MIB 6 + /* * Define error numbers and messages for syslog @@ -703,6 +523,14 @@ #define SK_PNMI_ERR051MSG "SkPnmiEvent: Port switch suspicious" #define SK_PNMI_ERR052 (SK_ERRBASE_PNMI + 52) #define SK_PNMI_ERR052MSG "" +#define SK_PNMI_ERR053 (SK_ERRBASE_PNMI + 53) +#define SK_PNMI_ERR053MSG "General: Driver release date not initialized" +#define SK_PNMI_ERR054 (SK_ERRBASE_PNMI + 54) +#define SK_PNMI_ERR054MSG "General: Driver release date string too long" +#define SK_PNMI_ERR055 (SK_ERRBASE_PNMI + 55) +#define SK_PNMI_ERR055MSG "General: Driver file name not initialized" +#define SK_PNMI_ERR056 (SK_ERRBASE_PNMI + 56) +#define SK_PNMI_ERR056MSG "General: Driver file name string too long" /* * Management counter macros called by the driver @@ -713,6 +541,11 @@ #define SK_PNMI_SET_DRIVER_VER(pAC,v) ((pAC)->Pnmi.pDriverVersion = \ (char *)(v)) +#define SK_PNMI_SET_DRIVER_RELDATE(pAC,v) ((pAC)->Pnmi.pDriverReleaseDate = \ + (char *)(v)) + +#define SK_PNMI_SET_DRIVER_FILENAME(pAC,v) ((pAC)->Pnmi.pDriverFileName = \ + (char *)(v)) #define SK_PNMI_CNT_TX_QUEUE_LEN(pAC,v,p) \ { \ @@ -889,6 +722,8 @@ char ConfMacFactoryAddr[6]; SK_U8 ConfPMD; SK_U8 ConfConnector; + SK_U32 ConfPhyType; + SK_U32 ConfPhyMode; SK_U8 ConfLinkCapability; SK_U8 ConfLinkMode; SK_U8 ConfLinkModeStatus; @@ -937,9 +772,14 @@ SK_U32 DeviceType; char DriverDescr[SK_PNMI_STRINGLEN1]; char DriverVersion[SK_PNMI_STRINGLEN2]; + char DriverReleaseDate[SK_PNMI_STRINGLEN1]; + char DriverFileName[SK_PNMI_STRINGLEN1]; char HwDescr[SK_PNMI_STRINGLEN1]; char HwVersion[SK_PNMI_STRINGLEN2]; SK_U16 Chipset; + SK_U32 ChipId; + SK_U8 VauxAvail; + SK_U32 RamSize; SK_U32 MtuSize; SK_U32 Action; SK_U32 TestResult; @@ -1063,6 +903,8 @@ char *pDriverDescription; char *pDriverVersion; + char *pDriverReleaseDate; + char *pDriverFileName; int MacUpdatedFlag; int RlmtUpdatedFlag; @@ -1092,26 +934,31 @@ SK_U8 VctStatus[SK_MAX_MACS]; SK_PNMI_VCT VctBackup[SK_MAX_MACS]; SK_PNMI_VCT_TIMER VctTimeout[SK_MAX_MACS]; +#ifdef SK_DIAG_SUPPORT + SK_U32 DiagAttached; +#endif /* SK_DIAG_SUPPORT */ } SK_PNMI; /* * Function prototypes */ -extern int SkPnmiInit(SK_AC *pAc, SK_IOC IoC, int level); -extern int SkPnmiGetVar(SK_AC *pAc, SK_IOC IoC, SK_U32 Id, void* pBuf, +extern int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int Level); +extern int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf, unsigned int* pLen, SK_U32 Instance, SK_U32 NetIndex); -extern int SkPnmiPreSetVar(SK_AC *pAc, SK_IOC IoC, SK_U32 Id, +extern int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); -extern int SkPnmiSetVar(SK_AC *pAc, SK_IOC IoC, SK_U32 Id, void* pBuf, +extern int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); -extern int SkPnmiGetStruct(SK_AC *pAc, SK_IOC IoC, void* pBuf, +extern int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, unsigned int *pLen, SK_U32 NetIndex); -extern int SkPnmiPreSetStruct(SK_AC *pAc, SK_IOC IoC, void* pBuf, +extern int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, unsigned int *pLen, SK_U32 NetIndex); -extern int SkPnmiSetStruct(SK_AC *pAc, SK_IOC IoC, void* pBuf, +extern int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, unsigned int *pLen, SK_U32 NetIndex); -extern int SkPnmiEvent(SK_AC *pAc, SK_IOC IoC, SK_U32 Event, +extern int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param); +extern int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf, + unsigned int * pLen, SK_U32 NetIndex); #endif Index: drivers/net/sk98lin/h/skgesirq.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/skgesirq.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/skgesirq.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/skgesirq.h 4 Aug 2004 01:29:23 -0000 1.2 @@ -1,16 +1,15 @@ /****************************************************************************** * * Name: skgesirq.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ + * Project: Gigabit Ethernet Adapters, Common Modules * Purpose: SK specific Gigabit Ethernet special IRQ functions * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,107 +20,18 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * $Log: skgesirq.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.26 2002/10/14 09:52:36 rschmidt - * Added SKERR_SIRQ_E023 and SKERR_SIRQ_E023 for GPHY (Yukon) - * Editorial changes - * - * Revision 1.25 2002/07/15 18:15:52 rwahl - * Editorial changes. - * - * Revision 1.24 2002/07/15 15:39:21 rschmidt - * Corrected define for SKERR_SIRQ_E022 - * Editorial changes - * - * Revision 1.23 2002/04/25 11:09:45 rschmidt - * Removed declarations for SkXmInitPhy(), SkXmRxTxEnable() - * Editorial changes - * - * Revision 1.22 2000/11/09 11:30:10 rassmann - * WA: Waiting after releasing reset until BCom chip is accessible. - * - * Revision 1.21 2000/10/18 12:22:40 cgoos - * Added workaround for half duplex hangup. - * - * Revision 1.20 1999/12/06 10:00:44 cgoos - * Added SET event for role. - * - * Revision 1.19 1999/11/22 13:58:26 cgoos - * Changed license header to GPL. - * - * Revision 1.18 1999/05/19 07:32:59 cgoos - * Changes for 1000Base-T. - * - * Revision 1.17 1999/03/12 13:29:31 malthoff - * Move Autonegotiation Error Codes to skgeinit.h. - * - * Revision 1.16 1999/03/08 10:11:28 gklug - * add: AutoNegDone return codes - * - * Revision 1.15 1998/11/18 13:20:53 gklug - * add: different timeouts for active and non-active links - * - * Revision 1.14 1998/11/04 07:18:14 cgoos - * Added prototype for SkXmRxTxEnable. - * - * Revision 1.13 1998/10/21 05:52:23 gklug - * add: parameter DoLoop to InitPhy function - * - * Revision 1.12 1998/10/19 06:45:03 cgoos - * Added prototype for SkXmInitPhy. - * - * Revision 1.11 1998/10/15 14:34:10 gklug - * add: WA_TIME is 500 msec - * - * Revision 1.10 1998/10/14 14:49:41 malthoff - * Remove err log defines E021 and E022. They are - * defined in skgeinit.h now. - * - * Revision 1.9 1998/10/14 14:00:39 gklug - * add: error logs for init phys - * - * Revision 1.8 1998/10/14 05:44:05 gklug - * add: E020 - * - * Revision 1.7 1998/10/02 06:24:58 gklug - * add: error messages - * - * Revision 1.6 1998/10/01 07:54:45 gklug - * add: PNMI debug module - * - * Revision 1.5 1998/09/28 13:36:31 malthoff - * Move the bit definitions for Autonegotiation - * and Flow Control to skgeinit.h. - * - * Revision 1.4 1998/09/15 12:29:34 gklug - * add: error logs - * - * Revision 1.3 1998/09/03 13:54:02 gklug - * add: function prototypes - * - * Revision 1.2 1998/09/03 10:24:36 gklug - * add: Events send by PNMI - * add: parameter definition for Flow Control etc. - * - * Revision 1.1 1998/08/27 11:50:27 gklug - * initial revision - * - * - ******************************************************************************/ - #ifndef _INC_SKGESIRQ_H_ #define _INC_SKGESIRQ_H_ +/* Define return codes of SkGePortCheckUp and CheckShort */ +#define SK_HW_PS_NONE 0 /* No action needed */ +#define SK_HW_PS_RESTART 1 /* Restart needed */ +#define SK_HW_PS_LINK 2 /* Link Up actions needed */ + /* * Define the Event the special IRQ/INI module can handle */ -#define SK_HWEV_WATIM 1 /* Timeout for WA errata #2 XMAC */ +#define SK_HWEV_WATIM 1 /* Timeout for WA Errata #2 XMAC */ #define SK_HWEV_PORT_START 2 /* Port Start Event by RLMT */ #define SK_HWEV_PORT_STOP 3 /* Port Stop Event by RLMT */ #define SK_HWEV_CLEAR_STAT 4 /* Clear Statistics by PNMI */ @@ -132,10 +42,10 @@ #define SK_HWEV_SET_SPEED 9 /* Set Link Speed by PNMI */ #define SK_HWEV_HALFDUP_CHK 10 /* Half Duplex Hangup Workaround */ -#define SK_WA_ACT_TIME (5000000L) /* 5 sec */ -#define SK_WA_INA_TIME (100000L) /* 100 msec */ +#define SK_WA_ACT_TIME (5000000UL) /* 5 sec */ +#define SK_WA_INA_TIME (100000UL) /* 100 msec */ -#define SK_HALFDUP_CHK_TIME (10000L) /* 10 msec */ +#define SK_HALFDUP_CHK_TIME (10000UL) /* 10 msec */ /* * Define the error numbers and messages @@ -188,6 +98,8 @@ #define SKERR_SIRQ_E023MSG "Auto-negotiation error" #define SKERR_SIRQ_E024 (SKERR_SIRQ_E023+1) #define SKERR_SIRQ_E024MSG "FIFO overflow error" +#define SKERR_SIRQ_E025 (SKERR_SIRQ_E024+1) +#define SKERR_SIRQ_E025MSG "2 Pair Downshift detected" extern void SkGeSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus); extern int SkGeSirqEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para); Index: drivers/net/sk98lin/h/ski2c.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/ski2c.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/ski2c.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/ski2c.h 4 Aug 2004 01:29:23 -0000 1.2 @@ -1,18 +1,15 @@ /****************************************************************************** * * Name: ski2c.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ + * Project: Gigabit Ethernet Adapters, TWSI-Module * Purpose: Defines to access Voltage and Temperature Sensor - * (taken from Monalisa (taken from Concentrator)) * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998,1999 SysKonnect, - * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,125 +20,6 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: ski2c.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.33 2002/10/14 16:40:50 rschmidt - * Editorial changes (TWSI) - * - * Revision 1.32 2002/08/13 08:55:07 rschmidt - * Editorial changes - * - * Revision 1.31 2002/08/06 09:44:22 jschmalz - * Extensions and changes for Yukon - * - * Revision 1.30 2001/04/05 11:38:09 rassmann - * Set SenState to idle in SkI2cWaitIrq(). - * Changed error message in SkI2cWaitIrq(). - * - * Revision 1.29 2000/08/03 14:28:17 rassmann - * - Added function to wait for I2C being ready before resetting the board. - * - Replaced one duplicate "out of range" message with correct one. - * - * Revision 1.28 1999/11/22 13:55:46 cgoos - * Changed license header to GPL. - * - * Revision 1.27 1999/05/20 09:23:10 cgoos - * Changes for 1000Base-T (Fan sensors). - * - * Revision 1.26 1998/12/01 13:45:47 gklug - * add: InitLevel to I2c struct - * - * Revision 1.25 1998/11/03 06:55:16 gklug - * add: Dummy Reads to I2c struct - * - * Revision 1.24 1998/10/02 14:28:59 cgoos - * Added prototype for SkI2cIsr. - * - * Revision 1.23 1998/09/08 12:20:11 gklug - * add: prototypes for init and read functions - * - * Revision 1.22 1998/09/08 07:37:56 gklug - * add: log error if PCI_IO voltage sensor could not be initialized - * - * Revision 1.21 1998/09/04 08:38:05 malthoff - * Change the values for I2C_READ and I2C_WRITE - * - * Revision 1.20 1998/08/25 07:52:22 gklug - * chg: Timestamps (last) added for logging - * - * Revision 1.19 1998/08/25 06:09:00 gklug - * rmv: warning and error levels of the individual sensors. - * add: timing definitions for sending traps and logging errors - * - * Revision 1.18 1998/08/20 11:41:15 gklug - * chg: omit STRCPY macro by using char * as Sensor Description - * - * Revision 1.17 1998/08/20 11:37:43 gklug - * chg: change Ioc to IoC - * - * Revision 1.16 1998/08/20 11:30:38 gklug - * fix: SenRead declaration - * - * Revision 1.15 1998/08/20 11:27:53 gklug - * fix: Compile bugs with new awrning constants - * - * Revision 1.14 1998/08/20 08:53:12 gklug - * fix: compiler errors - * add: Threshold values - * - * Revision 1.13 1998/08/19 12:21:16 gklug - * fix: remove struct from C files (see CCC) - * add: typedefs for all structs - * - * Revision 1.12 1998/08/19 10:57:41 gklug - * add: Warning levels - * - * Revision 1.11 1998/08/18 08:37:02 malthoff - * Prototypes not required for SK_DIAG. - * - * Revision 1.10 1998/08/17 13:54:00 gklug - * fix: declaration of event function - * - * Revision 1.9 1998/08/17 06:48:39 malthoff - * Remove some unrequired macros. - * Fix the compiler errors. - * - * Revision 1.8 1998/08/14 06:47:19 gklug - * fix: Values are intergers - * - * Revision 1.7 1998/08/14 06:26:05 gklug - * add: Init error message - * - * Revision 1.6 1998/08/13 08:31:08 gklug - * add: Error message - * - * Revision 1.5 1998/08/12 14:32:04 gklug - * add: new error code/message - * - * Revision 1.4 1998/08/12 13:39:08 gklug - * chg: names of error messages - * add: defines for Sensor type and thresholds - * - * Revision 1.3 1998/08/11 07:57:16 gklug - * add: sensor struct - * add: Timeout defines - * add: I2C control struct for pAC - * - * Revision 1.2 1998/07/17 11:29:02 gklug - * rmv: Microwire and SMTPANIC - * - * Revision 1.1 1998/06/19 14:30:10 malthoff - * Created. Sources taken from ML Project. - * - * - ******************************************************************************/ - /* * SKI2C.H contains all I2C specific defines */ @@ -166,7 +44,7 @@ #define I2C_READ 0 #define I2C_WRITE 1 #define I2C_BURST 1 -#define I2C_SIGLE 0 +#define I2C_SINGLE 0 #define SKERR_I2C_E001 (SK_ERRBASE_I2C+0) #define SKERR_I2C_E001MSG "Sensor index unknown" @@ -254,7 +132,7 @@ SK_I32 SenThreWarnLow; /* Lower warning Threshold of the sensor */ int SenErrFlag; /* Sensor indicated an error */ SK_BOOL SenInit; /* Is sensor initialized ? */ - SK_U64 SenErrCts; /* Error trap counter */ + SK_U64 SenErrCts; /* Error trap counter */ SK_U64 SenWarnCts; /* Warning trap counter */ SK_U64 SenBegErrTS; /* Begin error timestamp */ SK_U64 SenBegWarnTS; /* Begin warning timestamp */ @@ -281,13 +159,17 @@ #endif /* !SK_DIAG */ } SK_I2C; +extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level); +extern int SkI2cWrite(SK_AC *pAC, SK_IOC IoC, SK_U32 Data, int Dev, int Size, + int Reg, int Burst); extern int SkI2cReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen); -#ifndef SK_DIAG +#ifdef SK_DIAG +extern SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg, + int Burst); +#else /* !SK_DIAG */ extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para); -extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level); extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC); extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC); - -#endif +#endif /* !SK_DIAG */ #endif /* n_SKI2C_H */ Index: drivers/net/sk98lin/h/skqueue.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/skqueue.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/skqueue.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/skqueue.h 4 Aug 2004 01:29:23 -0000 1.2 @@ -1,17 +1,15 @@ /****************************************************************************** * * Name: skqueue.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ + * Project: Gigabit Ethernet Adapters, Event Scheduler Module * Purpose: Defines for the Event queue * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998,1999 SysKonnect, - * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,67 +20,6 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: skqueue.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.14 2002/03/15 10:52:13 mkunz - * Added event classes for link aggregation - * - * Revision 1.13 1999/11/22 13:59:05 cgoos - * Changed license header to GPL. - * - * Revision 1.12 1998/09/08 08:48:01 gklug - * add: init level handling - * - * Revision 1.11 1998/09/03 14:15:11 gklug - * add: CSUM and HWAC Eventclass and function. - * fix: pParaPtr according to CCC - * - * Revision 1.10 1998/08/20 12:43:03 gklug - * add: typedef SK_QUEUE - * - * Revision 1.9 1998/08/19 09:50:59 gklug - * fix: remove struct keyword from c-code (see CCC) add typedefs - * - * Revision 1.8 1998/08/18 07:00:01 gklug - * fix: SK_PTR not defined use void * instead. - * - * Revision 1.7 1998/08/17 13:43:19 gklug - * chg: Parameter will be union of 64bit para, 2 times SK_U32 or SK_PTR - * - * Revision 1.6 1998/08/14 07:09:30 gklug - * fix: chg pAc -> pAC - * - * Revision 1.5 1998/08/11 14:26:44 gklug - * chg: Event Dispatcher returns now int. - * - * Revision 1.4 1998/08/11 12:15:21 gklug - * add: Error numbers of skqueue module - * - * Revision 1.3 1998/08/07 12:54:23 gklug - * fix: first compiled version - * - * Revision 1.2 1998/08/07 09:34:00 gklug - * adapt structure defs to CCC - * add: prototypes for functions - * - * Revision 1.1 1998/07/30 14:52:12 gklug - * Initial version. - * Defines Event Classes, Event structs and queue management variables. - * - * - * - ******************************************************************************/ - -/* - * SKQUEUE.H contains all defines and types for the event queue - */ - #ifndef _SKQUEUE_H_ #define _SKQUEUE_H_ @@ -92,7 +29,7 @@ */ #define SKGE_DRV 1 /* Driver Event Class */ #define SKGE_RLMT 2 /* RLMT Event Class */ -#define SKGE_I2C 3 /* i2C Event Class */ +#define SKGE_I2C 3 /* I2C Event Class */ #define SKGE_PNMI 4 /* PNMI Event Class */ #define SKGE_CSUM 5 /* Checksum Event Class */ #define SKGE_HWAC 6 /* Hardware Access Event Class */ @@ -121,25 +58,25 @@ * Event Queue * skqueue.c * events are class/value pairs - * class is addressee, e.g. RMT, PCM etc. + * class is addressee, e.g. RLMT, PNMI etc. * value is command, e.g. line state change, ring op change etc. */ typedef struct s_EventElem { - SK_U32 Class ; /* Event class */ - SK_U32 Event ; /* Event value */ - SK_EVPARA Para ; /* Event parameter */ + SK_U32 Class; /* Event class */ + SK_U32 Event; /* Event value */ + SK_EVPARA Para; /* Event parameter */ } SK_EVENTELEM; typedef struct s_Queue { SK_EVENTELEM EvQueue[SK_MAX_EVENT]; - SK_EVENTELEM *EvPut ; - SK_EVENTELEM *EvGet ; + SK_EVENTELEM *EvPut; + SK_EVENTELEM *EvGet; } SK_QUEUE; extern void SkEventInit(SK_AC *pAC, SK_IOC Ioc, int Level); extern void SkEventQueue(SK_AC *pAC, SK_U32 Class, SK_U32 Event, SK_EVPARA Para); -extern int SkEventDispatcher(SK_AC *pAC,SK_IOC Ioc); +extern int SkEventDispatcher(SK_AC *pAC, SK_IOC Ioc); /* Define Error Numbers and messages */ Index: drivers/net/sk98lin/h/skrlmt.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/skrlmt.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/skrlmt.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/skrlmt.h 4 Aug 2004 01:29:23 -0000 1.2 @@ -2,15 +2,14 @@ * * Name: skrlmt.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ * Purpose: Header file for Redundant Link ManagemenT. * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2001 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,128 +22,6 @@ /****************************************************************************** * - * History: - * - * $Log: skrlmt.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.33 2001/07/03 12:16:48 mkunz - * New Flag ChgBcPrio (Change priority of last broadcast received) - * - * Revision 1.32 2001/02/14 14:06:31 rassmann - * Editorial changes. - * - * Revision 1.31 2001/02/05 14:25:26 rassmann - * Prepared RLMT for transparent operation. - * - * Revision 1.30 2001/01/22 13:41:39 rassmann - * Supporting two nets on dual-port adapters. - * - * Revision 1.29 2000/11/17 08:58:00 rassmann - * Moved CheckSwitch from SK_RLMT_PACKET_RECEIVED to SK_RLMT_TIM event. - * - * Revision 1.28 2000/11/09 12:24:34 rassmann - * Editorial changes. - * - * Revision 1.27 1999/11/22 13:59:56 cgoos - * Changed license header to GPL. - * - * Revision 1.26 1999/10/04 14:01:19 rassmann - * Corrected reaction to reception of BPDU frames (#10441). - * - * Revision 1.25 1999/07/20 12:53:39 rassmann - * Fixed documentation errors for lookahead macros. - * - * Revision 1.24 1999/05/28 11:15:56 rassmann - * Changed behaviour to reflect Design Spec v1.2. - * Controlling Link LED(s). - * Introduced RLMT Packet Version field in RLMT Packet. - * Newstyle lookahead macros (checking meta-information before looking at - * the packet). - * - * Revision 1.23 1999/01/28 12:50:42 rassmann - * Not using broadcast time stamps in CheckLinkState mode. - * - * Revision 1.22 1999/01/27 14:13:04 rassmann - * Monitoring broadcast traffic. - * Switching more reliably and not too early if switch is - * configured for spanning tree. - * - * Revision 1.21 1998/12/08 13:11:25 rassmann - * Stopping SegTimer at RlmtStop. - * - * Revision 1.20 1998/11/24 12:37:33 rassmann - * Implemented segmentation check. - * - * Revision 1.19 1998/11/17 13:43:06 rassmann - * Handling (logical) tx failure. - * Sending packet on logical address after PORT_SWITCH. - * - * Revision 1.18 1998/11/13 16:56:56 rassmann - * Added macro version of SkRlmtLookaheadPacket. - * - * Revision 1.17 1998/11/06 18:06:05 rassmann - * Corrected timing when RLMT checks fail. - * Clearing tx counter earlier in periodical checks. - * - * Revision 1.16 1998/11/03 13:53:50 rassmann - * RLMT should switch now (at least in mode 3). - * - * Revision 1.15 1998/10/22 11:39:52 rassmann - * Corrected signed/unsigned mismatches. - * Corrected receive list handling and address recognition. - * - * Revision 1.14 1998/10/15 15:16:36 rassmann - * Finished Spanning Tree checking. - * Checked with lint. - * - * Revision 1.13 1998/09/24 19:16:08 rassmann - * Code cleanup. - * Introduced Timer for PORT_DOWN due to no RX. - * - * Revision 1.12 1998/09/16 11:09:52 rassmann - * Syntax corrections. - * - * Revision 1.11 1998/09/15 11:28:50 rassmann - * Syntax corrections. - * - * Revision 1.10 1998/09/14 17:07:38 rassmann - * Added code for port checking via LAN. - * Changed Mbuf definition. - * - * Revision 1.9 1998/09/07 11:14:15 rassmann - * Syntax corrections. - * - * Revision 1.8 1998/09/07 09:06:08 rassmann - * Syntax corrections. - * - * Revision 1.7 1998/09/04 19:41:34 rassmann - * Syntax corrections. - * Started entering code for checking local links. - * - * Revision 1.6 1998/09/04 12:14:28 rassmann - * Interface cleanup. - * - * Revision 1.5 1998/09/02 16:55:29 rassmann - * Updated to reflect new DRV/HWAC/RLMT interface. - * - * Revision 1.4 1998/09/02 07:26:02 afischer - * typedef for SK_RLMT_PORT - * - * Revision 1.3 1998/08/27 14:29:03 rassmann - * Code cleanup. - * - * Revision 1.2 1998/08/27 14:26:25 rassmann - * Updated interface. - * - * Revision 1.1 1998/08/21 08:29:10 rassmann - * First public version. - * - ******************************************************************************/ - -/****************************************************************************** - * * Description: * * This is the header file for Redundant Link ManagemenT. @@ -166,7 +43,6 @@ #define __INC_SKRLMT_H #ifdef __cplusplus -#error C++ is not yet supported. extern "C" { #endif /* cplusplus */ @@ -289,28 +165,33 @@ _PortNum = (SK_U32)(PortNum); \ /* _pAC->Rlmt.Port[_PortNum].PacketsRx++; */ \ _pAC->Rlmt.Port[_PortNum].PacketsPerTimeSlot++; \ - if ((_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_TRANSPARENT) != 0) { \ + if (_pAC->Rlmt.RlmtOff) { \ *(pNumBytes) = 0; \ - } \ - else if (IsBc) { \ - if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode != SK_RLMT_MODE_CLS) { \ - *(pNumBytes) = 6; \ - *(pOffset) = 6; \ - } \ - else { \ - *(pNumBytes) = 0; \ - } \ - } \ - else { \ - if ((PktLen) > SK_RLMT_MAX_TX_BUF_SIZE) { \ - /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \ - *(pNumBytes) = 0; \ - } \ - else { \ - *(pNumBytes) = 6; \ - *(pOffset) = 0; \ - } \ - } \ + } \ + else {\ + if ((_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_TRANSPARENT) != 0) { \ + *(pNumBytes) = 0; \ + } \ + else if (IsBc) { \ + if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode != SK_RLMT_MODE_CLS) { \ + *(pNumBytes) = 6; \ + *(pOffset) = 6; \ + } \ + else { \ + *(pNumBytes) = 0; \ + } \ + } \ + else { \ + if ((PktLen) > SK_RLMT_MAX_TX_BUF_SIZE) { \ + /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \ + *(pNumBytes) = 0; \ + } \ + else { \ + *(pNumBytes) = 6; \ + *(pOffset) = 0; \ + } \ + } \ + } \ } #if 0 @@ -508,8 +389,10 @@ /* ----- Private part ----- */ SK_BOOL CheckSwitch; - SK_U8 Align01; - SK_U16 Align02; + SK_BOOL RlmtOff; /* set to zero if the Mac addresses + are equal or the second one + is zero */ + SK_U16 Align01; } SK_RLMT; Index: drivers/net/sk98lin/h/sktimer.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/sktimer.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/sktimer.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/sktimer.h 4 Aug 2004 01:29:23 -0000 1.2 @@ -1,17 +1,15 @@ /****************************************************************************** * * Name: sktimer.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ + * Project: Gigabit Ethernet Adapters, Event Scheduler Module * Purpose: Defines for the timer functions * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998,1999 SysKonnect, - * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,45 +20,6 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: sktimer.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.9 1999/11/22 14:00:29 cgoos - * Changed license header to GPL. - * - * Revision 1.8 1998/09/08 08:48:02 gklug - * add: init level handling - * - * Revision 1.7 1998/08/20 12:31:29 gklug - * fix: SK_TIMCTRL needs to be defined - * - * Revision 1.6 1998/08/19 09:51:00 gklug - * fix: remove struct keyword from c-code (see CCC) add typedefs - * - * Revision 1.5 1998/08/17 13:43:21 gklug - * chg: Parameter will be union of 64bit para, 2 times SK_U32 or SK_PTR - * - * Revision 1.4 1998/08/14 07:09:31 gklug - * fix: chg pAc -> pAC - * - * Revision 1.3 1998/08/07 12:54:24 gklug - * fix: first compiled version - * - * Revision 1.2 1998/08/07 09:35:29 gklug - * add: Timer control struct for Adapters context - * add: function prototypes - * - * Revision 1.1 1998/08/05 11:27:01 gklug - * First version: adapted from SMT - * - * - ******************************************************************************/ - /* * SKTIMER.H contains all defines and types for the timer functions */ @@ -78,25 +37,25 @@ typedef struct s_Timer SK_TIMER; struct s_Timer { - SK_TIMER *TmNext ; /* linked list */ - SK_U32 TmClass ; /* Timer Event class */ - SK_U32 TmEvent ; /* Timer Event value */ - SK_EVPARA TmPara ; /* Timer Event parameter */ - SK_U32 TmDelta ; /* delta time */ - int TmActive ; /* flag : active/inactive */ -} ; + SK_TIMER *TmNext; /* linked list */ + SK_U32 TmClass; /* Timer Event class */ + SK_U32 TmEvent; /* Timer Event value */ + SK_EVPARA TmPara; /* Timer Event parameter */ + SK_U32 TmDelta; /* delta time */ + int TmActive; /* flag: active/inactive */ +}; /* * Timer control struct. * - use in Adapters context name pAC->Tim */ typedef struct s_TimCtrl { - SK_TIMER *StQueue ; /* Head of Timer queue */ -} SK_TIMCTRL ; + SK_TIMER *StQueue; /* Head of Timer queue */ +} SK_TIMCTRL; -extern void SkTimerInit(SK_AC *pAC,SK_IOC Ioc, int Level); -extern void SkTimerStop(SK_AC *pAC,SK_IOC Ioc,SK_TIMER *pTimer); -extern void SkTimerStart(SK_AC *pAC,SK_IOC Ioc,SK_TIMER *pTimer, - SK_U32 Time,SK_U32 Class,SK_U32 Event,SK_EVPARA Para); -extern void SkTimerDone(SK_AC *pAC,SK_IOC Ioc); +extern void SkTimerInit(SK_AC *pAC, SK_IOC Ioc, int Level); +extern void SkTimerStop(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer); +extern void SkTimerStart(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer, + SK_U32 Time, SK_U32 Class, SK_U32 Event, SK_EVPARA Para); +extern void SkTimerDone(SK_AC *pAC, SK_IOC Ioc); #endif /* _SKTIMER_H_ */ Index: drivers/net/sk98lin/h/sktypes.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/sktypes.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/sktypes.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/sktypes.h 4 Aug 2004 01:29:23 -0000 1.2 @@ -2,16 +2,14 @@ * * Name: sktypes.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ * Purpose: Define data types for Linux * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998,1999 SysKonnect, - * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,25 +20,6 @@ * ******************************************************************************/ - /***************************************************************************** - * - * History: - * - * $Log: sktypes.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.2 1999/11/22 14:01:58 cgoos - * Changed license header to GPL. - * Now using Linux' fixed size types instead of standard types. - * - * Revision 1.1 1999/02/16 07:41:40 cgoos - * First version. - * - * - * - *****************************************************************************/ - /****************************************************************************** * * Description: Index: drivers/net/sk98lin/h/skversion.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/skversion.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/skversion.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/skversion.h 4 Aug 2004 01:29:23 -0000 1.2 @@ -2,16 +2,14 @@ * * Name: version.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ * Purpose: SK specific Error log support * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2002 SysKonnect, - * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,31 +20,17 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * $Log: skversion.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.1.2.1 2001/09/05 13:38:30 mlindner - * Removed FILE description - * - * Revision 1.1 2001/03/06 09:25:00 mlindner - * first version - * - * - * - ******************************************************************************/ - - +#ifdef lint static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH."; static const char SysKonnectBuildNumber[] = - "@(#)SK-BUILD: 6.02 PL: 01"; + "@(#)SK-BUILD: 6.22 PL: 01"; +#endif /* !defined(lint) */ -#define BOOT_STRING "sk98lin: Network Device Driver v6.02\n" \ - "Copyright (C) 2000-2002 SysKonnect GmbH." +#define BOOT_STRING "sk98lin: Network Device Driver v6.22\n" \ + "(C)Copyright 1999-2004 Marvell(R)." -#define VER_STRING "6.02" +#define VER_STRING "6.22" +#define DRIVER_FILE_NAME "sk98lin" +#define DRIVER_REL_DATE "Jan-30-2004" Index: drivers/net/sk98lin/h/skvpd.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/skvpd.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/skvpd.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/skvpd.h 4 Aug 2004 01:29:23 -0000 1.2 @@ -2,15 +2,13 @@ * * Name: skvpd.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ * Purpose: Defines and Macros for VPD handling * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 1998-2003 SysKonnect GmbH. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,65 +19,6 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: skvpd.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.13 2002/10/14 15:58:18 rschmidt - * Added entry in rom_size struct s_vpd - * Editorial changes - * - * Revision 1.12 2002/09/09 14:43:51 mkarl - * added PCI Id of Yukon for reading VPD in diag before the adapter has - * been initialized - * editorial changes - * - * Revision 1.11 2002/07/26 13:19:16 mkarl - * added support for Yukon - * added vpd_size to VPD struct - * - * Revision 1.10 2000/08/10 11:29:07 rassmann - * Editorial changes. - * Preserving 32-bit alignment in structs for the adapter context. - * Removed unused function VpdWriteDword() (#if 0). - * Made VpdReadKeyword() available for SKDIAG only. - * - * Revision 1.9 1999/11/22 14:02:27 cgoos - * Changed license header to GPL. - * - * Revision 1.8 1999/03/11 14:26:40 malthoff - * Replace __STDC__ with SK_KR_PROTO. - * - * Revision 1.7 1998/10/28 07:27:17 gklug - * rmv: SWAP macros - * add: VPD_IN/OUT8 macros - * chg: interface definition - * - * Revision 1.6 1998/10/22 10:03:44 gklug - * fix: use SK_OUT16 instead of SK_OUTW - * - * Revision 1.5 1998/10/14 07:05:31 cgoos - * Changed constants in SK_SWAP_32 to UL. - * - * Revision 1.4 1998/08/19 08:14:09 gklug - * fix: remove struct keyword as much as possible from the c-code (see CCC) - * - * Revision 1.3 1998/08/18 08:18:56 malthoff - * Modify VPD in and out macros for SK_DIAG - * - * Revision 1.2 1998/07/03 14:49:08 malthoff - * Add VPD_INxx() and VPD_OUTxx() macros for the Diagnostics tool. - * - * Revision 1.1 1998/06/19 14:08:03 malthoff - * Created. - * - * - ******************************************************************************/ - /* * skvpd.h contains Diagnostic specific defines for VPD handling */ @@ -121,7 +60,7 @@ * Define READ and WRITE Constants. */ -#define VPD_PCI_ID_YUKON 0x4320 +#define VPD_DEV_ID_GENESIS 0x4300 #define VPD_SIZE_YUKON 256 #define VPD_SIZE_GENESIS 512 @@ -252,8 +191,8 @@ extern int VpdSetupPara( SK_AC *pAC, - char *key, - char *buf, + const char *key, + const char *buf, int len, int type, int op); @@ -272,7 +211,7 @@ extern int VpdRead( SK_AC *pAC, SK_IOC IoC, - char *key, + const char *key, char *buf, int *len); @@ -282,8 +221,8 @@ extern int VpdWrite( SK_AC *pAC, SK_IOC IoC, - char *key, - char *buf); + const char *key, + const char *buf); extern int VpdDelete( SK_AC *pAC, Index: drivers/net/sk98lin/h/xmac_ii.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/sk98lin/h/xmac_ii.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/sk98lin/h/xmac_ii.h 22 Jul 2004 19:49:44 -0000 1.1 +++ drivers/net/sk98lin/h/xmac_ii.h 4 Aug 2004 01:29:23 -0000 1.2 @@ -1,16 +1,15 @@ /****************************************************************************** * * Name: xmac_ii.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2004/07/22 19:49:44 $ + * Project: Gigabit Ethernet Adapters, Common Modules * Purpose: Defines and Macros for Gigabit Ethernet Controller * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,182 +20,6 @@ * ******************************************************************************/ -/****************************************************************************** - * - * History: - * - * $Log: xmac_ii.h,v $ - * Revision 1.1 2004/07/22 19:49:44 joff - * Initial revision - * - * Revision 1.45 2002/12/10 14:35:13 rschmidt - * Corrected defines for Extended PHY Specific Control - * Added defines for Ext. PHY Specific Ctrl 2 Reg. (Fiber specific) - * - * Revision 1.44 2002/12/09 14:58:41 rschmidt - * Added defines for Ext. PHY Specific Ctrl Reg. (downshift feature) - * Added 'GMR_FS_UN_SIZE'-Bit to Rx GMAC FIFO Flush Mask - * - * Revision 1.43 2002/12/05 10:14:45 rschmidt - * Added define for GMAC's Half Duplex Burst Mode - * Added define for Rx GMAC FIFO Flush Mask (default) - * - * Revision 1.42 2002/11/12 16:48:19 rschmidt - * Added defines for Cable Diagnostic Register (GPHY) - * Editorial changes - * - * Revision 1.41 2002/10/21 11:20:22 rschmidt - * Added bit GMR_FS_GOOD_FC to GMR_FS_ANY_ERR - * Editorial changes - * - * Revision 1.40 2002/10/14 14:54:14 rschmidt - * Added defines for GPHY Specific Status and GPHY Interrupt Status - * Added bits PHY_M_IS_AN_ERROR and PHY_M_IS_FIFO_ERROR to PHY_M_DEF_MSK - * Editorial changes - * - * Revision 1.39 2002/10/10 15:53:44 mkarl - * added some bit definitions for link speed status and LED's - * - * Revision 1.38 2002/08/21 16:23:46 rschmidt - * Added defines for PHY Specific Ctrl Reg - * Editorial changes - * - * Revision 1.37 2002/08/16 14:50:33 rschmidt - * Added defines for Auto-Neg. Advertisement YUKON Fiber (88E1011S only) - * Changed define PHY_M_DEF_MSK for GPHY IRQ Mask - * Editorial changes - * - * Revision 1.36 2002/08/12 13:21:10 rschmidt - * Added defines for different Broadcom PHY Ids - * - * Revision 1.35 2002/08/08 15:58:01 rschmidt - * Added defines for Manual LED Override register (YUKON) - * Editorial changes - * - * Revision 1.34 2002/07/31 17:23:36 rwahl - * Added define GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR). - * - * Revision 1.33 2002/07/23 16:03:37 rschmidt - * Added defines for GPHY registers - * Editorial changes - * - * Revision 1.32 2002/07/15 18:14:37 rwahl - * Added GMAC MIB counters definitions. - * Editorial changes. - * - * Revision 1.31 2002/07/15 15:42:50 rschmidt - * Removed defines from PHY specific reg. which are - * common to all PHYs - * Added defines for GMAC MIB Counters - * Editorial changes - * - * Revision 1.30 2002/06/05 08:22:12 rschmidt - * Changed defines for GMAC Rx Control Register and Rx Status - * Editorial changes - * - * Revision 1.29 2002/04/25 11:43:56 rschmidt - * Added define PHY_B_AS_PAUSE_MSK for BCom Pause Res. - * Added new registers and defines for YUKON (GMAC, GPHY) - * Added Receive Frame Status Encoding for YUKON - * Editorial changes - * - * Revision 1.28 2000/11/09 12:32:49 rassmann - * Renamed variables. - * - * Revision 1.27 2000/05/17 11:00:46 malthoff - * Add bit for enable/disable power management in BCOM chip. - * - * Revision 1.26 1999/11/22 14:03:00 cgoos - * Changed license header to GPL. - * - * Revision 1.25 1999/08/12 19:19:38 malthoff - * Add PHY_B_AC_TX_TST bit according to BCOM A1 errata sheet. - * - * Revision 1.24 1999/07/30 11:27:21 cgoos - * Fixed a missing end-of-comment. - * - * Revision 1.23 1999/07/30 07:03:31 malthoff - * Cut some long comments. - * Correct the XMAC PHY ID definitions. - * - * Revision 1.22 1999/05/19 07:33:18 cgoos - * Changes for 1000Base-T. - * - * Revision 1.21 1999/03/25 07:46:11 malthoff - * Add XM_HW_CFG, XM_TS_READ, and XM_TS_LOAD registers. - * - * Revision 1.20 1999/03/12 13:36:09 malthoff - * Remove __STDC__. - * - * Revision 1.19 1998/12/10 12:22:54 gklug - * fix: RX_PAGE must be in interrupt mask - * - * Revision 1.18 1998/12/10 10:36:36 gklug - * fix: swap of pause bits - * - * Revision 1.17 1998/11/18 13:21:45 gklug - * fix: Default interrupt mask - * - * Revision 1.16 1998/10/29 15:53:21 gklug - * fix: Default mask uses ASS (GP0) signal - * - * Revision 1.15 1998/10/28 13:52:52 malthoff - * Add new bits in RX_CMD register. - * - * Revision 1.14 1998/10/19 15:34:53 gklug - * fix: typos - * - * Revision 1.13 1998/10/14 07:19:03 malthoff - * bug fix: Every define which describes bit 31 - * must be declared as unsigned long 'UL'. - * fix bit definitions of PHY_AN_RFB and PHY_AN_PAUSE. - * Remove ANP defines. Rework the RFB defines. - * - * Revision 1.12 1998/10/14 06:22:44 cgoos - * Changed shifted constant to ULONG. - * - * Revision 1.11 1998/10/14 05:43:26 gklug - * add: shift pause coding - * fix: PAUSE bits definition - * - * Revision 1.10 1998/10/13 09:19:21 malthoff - * Again change XMR_FS_ANY_ERR because of new info from XaQti. - * - * Revision 1.9 1998/10/09 07:58:30 malthoff - * Add XMR_FS_FCS_ERR to XMR_FS_ANY_ERR. - * - * Revision 1.8 1998/10/09 07:18:17 malthoff - * bug fix of a bug fix: XM_PAUSE_MODE and XM_DEF_MODE - * are not inverted! Bug XM_DEF_MSK is inverted. - * - * Revision 1.7 1998/10/05 08:04:32 malthoff - * bug fix: XM_PAUSE_MODE and XM_DEF_MODE - * must be inverted declarations. - * - * Revision 1.6 1998/09/28 13:38:18 malthoff - * Add default modes and masks XM_DEF_MSK, - * XM_PAUSE_MODE and XM_DEF_MODE - * - * Revision 1.5 1998/09/16 14:42:04 malthoff - * Bug Fix: XM_GP_PORT is a 32 bit (not a 16 bit) register. - * - * Revision 1.4 1998/08/20 14:59:47 malthoff - * Rework this file after reading the XaQti data sheet - * "Differences between Rev. B2 & Rev. C XMAC II". - * This file is now 100% XMAC II Rev. C complained. - * - * Revision 1.3 1998/06/29 12:18:23 malthoff - * Correct XMR_FS_ANY_ERR definition. - * - * Revision 1.2 1998/06/29 12:10:56 malthoff - * Add define XMR_FS_ANY_ERR. - * - * Revision 1.1 1998/06/19 13:37:17 malthoff - * created. - * - * - ******************************************************************************/ - #ifndef __INC_XMAC_H #define __INC_XMAC_H @@ -666,7 +489,7 @@ #define PHY_XMAC_AUNE_LP 0x05 /* 16 bit r/o Link Partner Abi Reg */ #define PHY_XMAC_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */ #define PHY_XMAC_NEPG 0x07 /* 16 bit r/w Next Page Register */ -#define PHY_XMAC_NEPG_LP 0x08 /* 16 bit r/o Next Page Link P Reg */ +#define PHY_XMAC_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */ /* 0x09 - 0x0e: reserved */ #define PHY_XMAC_EXT_STAT 0x0f /* 16 bit r/o Ext Status Register */ #define PHY_XMAC_RES_ABI 0x10 /* 16 bit r/o PHY Resolved Ability */ @@ -683,7 +506,7 @@ #define PHY_BCOM_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */ #define PHY_BCOM_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */ #define PHY_BCOM_NEPG 0x07 /* 16 bit r/w Next Page Register */ -#define PHY_BCOM_NEPG_LP 0x08 /* 16 bit r/o Next Page Link P Reg */ +#define PHY_BCOM_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */ /* Broadcom-specific registers */ #define PHY_BCOM_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */ #define PHY_BCOM_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */ @@ -692,7 +515,7 @@ #define PHY_BCOM_P_EXT_CTRL 0x10 /* 16 bit r/w PHY Extended Ctrl Reg */ #define PHY_BCOM_P_EXT_STAT 0x11 /* 16 bit r/o PHY Extended Stat Reg */ #define PHY_BCOM_RE_CTR 0x12 /* 16 bit r/w Receive Error Counter */ -#define PHY_BCOM_FC_CTR 0x13 /* 16 bit r/w False Carr Sense Cnt */ +#define PHY_BCOM_FC_CTR 0x13 /* 16 bit r/w False Carrier Sense Cnt */ #define PHY_BCOM_RNO_CTR 0x14 /* 16 bit r/w Receiver NOT_OK Cnt */ /* 0x15 - 0x17: reserved */ #define PHY_BCOM_AUX_CTRL 0x18 /* 16 bit r/w Auxiliary Control Reg */ @@ -714,7 +537,7 @@ #define PHY_MARV_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */ #define PHY_MARV_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */ #define PHY_MARV_NEPG 0x07 /* 16 bit r/w Next Page Register */ -#define PHY_MARV_NEPG_LP 0x08 /* 16 bit r/o Next Page Link P Reg */ +#define PHY_MARV_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */ /* Marvel-specific registers */ #define PHY_MARV_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */ #define PHY_MARV_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */ @@ -747,7 +570,7 @@ #define PHY_LONE_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */ #define PHY_LONE_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */ #define PHY_LONE_NEPG 0x07 /* 16 bit r/w Next Page Register */ -#define PHY_LONE_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner*/ +#define PHY_LONE_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */ /* Level One-specific registers */ #define PHY_LONE_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg*/ #define PHY_LONE_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */ @@ -794,12 +617,13 @@ /* * PHY bit definitions * Bits defined as PHY_X_..., PHY_B_..., PHY_L_... or PHY_N_... are - * Xmac/Broadcom/LevelOne/National-specific. + * XMAC/Broadcom/LevelOne/National/Marvell-specific. * All other are general. */ /***** PHY_XMAC_CTRL 16 bit r/w PHY Control Register *****/ /***** PHY_BCOM_CTRL 16 bit r/w PHY Control Register *****/ +/***** PHY_MARV_CTRL 16 bit r/w PHY Status Register *****/ /***** PHY_LONE_CTRL 16 bit r/w PHY Control Register *****/ #define PHY_CT_RESET (1<<15) /* Bit 15: (sc) clear all PHY related regs */ #define PHY_CT_LOOP (1<<14) /* Bit 14: enable Loopback over PHY */ @@ -899,27 +723,20 @@ /***** PHY_XMAC_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/ /* Bit 15..4: reserved */ -#define PHY_AN_LP_NP (1<<3) /* Bit 3: Link Partner can Next Page */ -#define PHY_AN_LOC_NP (1<<2) /* Bit 2: Local PHY can Next Page */ -#define PHY_AN_RX_PG (1<<1) /* Bit 1: Page Received */ +#define PHY_ANE_LP_NP (1<<3) /* Bit 3: Link Partner can Next Page */ +#define PHY_ANE_LOC_NP (1<<2) /* Bit 2: Local PHY can Next Page */ +#define PHY_ANE_RX_PG (1<<1) /* Bit 1: Page Received */ /* Bit 0: reserved */ /***** PHY_BCOM_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/ - /* Bit 15..5: reserved */ -#define PHY_B_AN_PDF (1<<4) /* Bit 4: Parallel Detection Fault */ -/* PHY_AN_LP_NP (see XMAC) Bit 3: Link Partner can Next Page */ -/* PHY_AN_LOC_NP (see XMAC) Bit 2: Local PHY can Next Page */ -/* PHY_AN_RX_PG (see XMAC) Bit 1: Page Received */ -#define PHY_B_AN_LP_CAP (1<<0) /* Bit 0: Link Partner Auto-Neg. Cap. */ - /***** PHY_LONE_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/ -#define PHY_L_AN_BP (1<<5) /* Bit 5: Base Page Indication */ -#define PHY_L_AN_PDF (1<<4) /* Bit 4: Parallel Detection Fault */ -/* PHY_AN_LP_NP (see XMAC) Bit 3: Link Partner can Next Page */ -/* PHY_AN_LOC_NP (see XMAC) Bit 2: Local PHY can Next Page */ -/* PHY_AN_RX_PG (see XMAC) Bit 1: Page Received */ -#define PHY_B_AN_LP_CAP (1<<0) /* Bit 0: Link Partner Auto-Neg. Cap. */ - +/***** PHY_MARV_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/ + /* Bit 15..5: reserved */ +#define PHY_ANE_PAR_DF (1<<4) /* Bit 4: Parallel Detection Fault */ +/* PHY_ANE_LP_NP (see XMAC) Bit 3: Link Partner can Next Page */ +/* PHY_ANE_LOC_NP (see XMAC) Bit 2: Local PHY can Next Page */ +/* PHY_ANE_RX_PG (see XMAC) Bit 1: Page Received */ +#define PHY_ANE_LP_CAP (1<<0) /* Bit 0: Link Partner Auto-Neg. Cap. */ /***** PHY_XMAC_NEPG 16 bit r/w Next Page Register *****/ /***** PHY_BCOM_NEPG 16 bit r/w Next Page Register *****/ @@ -928,9 +745,9 @@ /***** PHY_BCOM_NEPG_LP 16 bit r/o Next Page Link Partner *****/ /***** PHY_LONE_NEPG_LP 16 bit r/o Next Page Link Partner *****/ #define PHY_NP_MORE (1<<15) /* Bit 15: More, Next Pages to follow */ -#define PHY_NP_ACK1 (1<<14) /* Bit 14: (ro) Ack 1, for receiving a message*/ +#define PHY_NP_ACK1 (1<<14) /* Bit 14: (ro) Ack1, for receiving a message */ #define PHY_NP_MSG_VAL (1<<13) /* Bit 13: Message Page valid */ -#define PHY_NP_ACK2 (1<<12) /* Bit 12: Ack 2, comply with msg content*/ +#define PHY_NP_ACK2 (1<<12) /* Bit 12: Ack2, comply with msg content */ #define PHY_NP_TOG (1<<11) /* Bit 11: Toggle Bit, ensure sync */ #define PHY_NP_MSG 0x07ff /* Bit 10..0: Message from/to Link Partner */ @@ -948,7 +765,7 @@ #define PHY_X_RS_HD (1<<6) /* Bit 6: Half Duplex Mode selected */ #define PHY_X_RS_FD (1<<5) /* Bit 5: Full Duplex Mode selected */ #define PHY_X_RS_ABLMIS (1<<4) /* Bit 4: duplex or pause cap mismatch */ -#define PHY_X_RS_PAUMIS (1<<3) /* Bit 3: pause capability missmatch */ +#define PHY_X_RS_PAUMIS (1<<3) /* Bit 3: pause capability mismatch */ /* Bit 2..0: reserved */ /* * Remote Fault Bits (PHY_X_AN_RFB) encoding @@ -980,6 +797,7 @@ /* Bit 7..0: reserved */ /***** PHY_BCOM_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/ +/***** PHY_MARV_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/ #define PHY_B_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */ #define PHY_B_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */ #define PHY_B_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */ @@ -1121,7 +939,7 @@ #define PHY_L_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */ #define PHY_L_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */ #define PHY_L_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */ -#define PHY_L_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status*/ +#define PHY_L_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status */ #define PHY_L_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */ #define PHY_L_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */ /* Bit 9..8: reserved */ @@ -1173,8 +991,8 @@ #define PHY_L_IS_AN_F (1<<13) /* Bit 13: Auto-Negotiation fault */ /* Bit 12: not described */ #define PHY_L_IS_CROSS (1<<11) /* Bit 11: Crossover used */ -#define PHY_L_IS_POL (1<<10) /* Bit 10: Polarity correct. used*/ -#define PHY_L_IS_SS (1<<9) /* Bit 9: Smart Speed Downgrade*/ +#define PHY_L_IS_POL (1<<10) /* Bit 10: Polarity correct. used */ +#define PHY_L_IS_SS (1<<9) /* Bit 9: Smart Speed Downgrade */ #define PHY_L_IS_CFULL (1<<8) /* Bit 8: Counter Full */ #define PHY_L_IS_AN_C (1<<7) /* Bit 7: AutoNeg Complete */ #define PHY_L_IS_SPEED (1<<6) /* Bit 6: Speed Changed */ @@ -1265,8 +1083,9 @@ * Marvell-Specific */ /***** PHY_MARV_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/ +/***** PHY_MARV_AUNE_LP 16 bit r/w Link Part Ability Reg *****/ #define PHY_M_AN_NXT_PG BIT_15 /* Request Next Page */ - /* Bit 14: reserved */ +#define PHY_M_AN_ACK BIT_14 /* (ro) Acknowledge Received */ #define PHY_M_AN_RF BIT_13 /* Remote Fault */ /* Bit 12: reserved */ #define PHY_M_AN_ASP BIT_11 /* Asymmetric Pause */ @@ -1298,7 +1117,6 @@ /* Bit 7..0: reserved */ /***** PHY_MARV_PHY_CTRL 16 bit r/w PHY Specific Ctrl Reg *****/ - #define PHY_M_PC_TX_FFD_MSK (3<<14) /* Bit 15..14: Tx FIFO Depth Mask */ #define PHY_M_PC_RX_FFD_MSK (3<<12) /* Bit 13..12: Rx FIFO Depth Mask */ #define PHY_M_PC_ASS_CRS_TX (1<<11) /* Bit 11: Assert CRS on Transmit */ @@ -1312,6 +1130,13 @@ #define PHY_M_PC_POL_R_DIS (1<<1) /* Bit 1: Polarity Reversal Disabled */ #define PHY_M_PC_DIS_JABBER (1<<0) /* Bit 0: Disable Jabber */ +#define PHY_M_PC_EN_DET SHIFT8(2) /* Energy Detect (Mode 1) */ +#define PHY_M_PC_EN_DET_PLUS SHIFT8(3) /* Energy Detect Plus (Mode 2) */ + +#define PHY_M_PC_MDI_XMODE(x) SHIFT5(x) +#define PHY_M_PC_MAN_MDI 0 /* 00 = Manual MDI configuration */ +#define PHY_M_PC_MAN_MDIX 1 /* 01 = Manual MDIX configuration */ +#define PHY_M_PC_ENA_AUTO 3 /* 11 = Enable Automatic Crossover */ /***** PHY_MARV_PHY_STAT 16 bit r/o PHY Specific Status Reg *****/ #define PHY_M_PS_SPEED_MSK (3<<14) /* Bit 15..14: Speed Mask */ @@ -1358,6 +1183,7 @@ #define PHY_M_EC_M_DSC_MSK (3<<10) /* Bit 11..10: Master downshift counter */ #define PHY_M_EC_S_DSC_MSK (3<<8) /* Bit 9.. 8: Slave downshift counter */ #define PHY_M_EC_MAC_S_MSK (7<<4) /* Bit 6.. 4: Def. MAC interface speed */ +#define PHY_M_EC_FIB_AN_ENA (1<<3) /* Bit 3: Fiber Auto-Neg. Enable */ #define PHY_M_EC_M_DSC(x) SHIFT10(x) /* 00=1x; 01=2x; 10=3x; 11=4x */ #define PHY_M_EC_S_DSC(x) SHIFT8(x) /* 00=dis; 01=1x; 10=2x; 11=3x */ @@ -1369,26 +1195,35 @@ /***** PHY_MARV_LED_CTRL 16 bit r/w LED Control Reg *****/ #define PHY_M_LEDC_DIS_LED (1<<15) /* Bit 15: Disable LED */ - -#define PHY_M_LED_BL_RATE(x) SHIFT12(x) /* Bit 12..14: Blink Rate */ - -/* values for PHY_M_LED_BL_RATE() */ -#define BL_DEFAULT 0 /* no pulse stretching */ -#define BL_21MS 1 /* 21 ms to 42ms */ -#define BL_42MS 2 /* 42 ms to 84ms */ -#define BL_84MS 3 /* 84 ms to 170ms */ -#define BL_170MS 4 /* 170 ms to340ms */ -#define BL_340MS 5 /* 340 ms to670ms */ -#define BL_670MS 6 /* 670 ms to 1.3s */ -#define BL_1300MS 7 /* 1.3s to 2.7s */ - +#define PHY_M_LEDC_PULS_MSK (7<<12) /* Bit 14..12: Pulse Stretch Mask */ #define PHY_M_LEDC_F_INT (1<<11) /* Bit 11: Force Interrupt */ - -#define PHY_M_LEDC_LINK_MSK (3<<3) /* Bit 4..3: Link Control */ +#define PHY_M_LEDC_BL_R_MSK (7<<8) /* Bit 10.. 8: Blink Rate Mask */ + /* Bit 7.. 5: reserved */ +#define PHY_M_LEDC_LINK_MSK (3<<3) /* Bit 4.. 3: Link Control Mask */ #define PHY_M_LEDC_DP_CTRL (1<<2) /* Bit 2: Duplex Control */ #define PHY_M_LEDC_RX_CTRL (1<<1) /* Bit 1: Rx activity / Link */ #define PHY_M_LEDC_TX_CTRL (1<<0) /* Bit 0: Tx activity / Link */ +#define PHY_M_LED_PULS_DUR(x) SHIFT12(x) /* Pulse Stretch Duration */ + +#define PULS_NO_STR 0 /* no pulse stretching */ +#define PULS_21MS 1 /* 21 ms to 42 ms */ +#define PULS_42MS 2 /* 42 ms to 84 ms */ +#define PULS_84MS 3 /* 84 ms to 170 ms */ +#define PULS_170MS 4 /* 170 ms to 340 ms */ +#define PULS_340MS 5 /* 340 ms to 670 ms */ +#define PULS_670MS 6 /* 670 ms to 1.3 s */ +#define PULS_1300MS 7 /* 1.3 s to 2.7 s */ + +#define PHY_M_LED_BLINK_RT(x) SHIFT8(x) /* Blink Rate */ + +#define BLINK_42MS 0 /* 42 ms */ +#define BLINK_84MS 1 /* 84 ms */ +#define BLINK_170MS 2 /* 170 ms */ +#define BLINK_340MS 3 /* 340 ms */ +#define BLINK_670MS 4 /* 670 ms */ + /* values 5 - 7: reserved */ + /***** PHY_MARV_LED_OVER 16 bit r/w Manual LED Override Reg *****/ #define PHY_M_LED_MO_DUP(x) SHIFT10(x) /* Bit 11..10: Duplex */ #define PHY_M_LED_MO_10(x) SHIFT8(x) /* Bit 9.. 8: Link 10 */ @@ -1410,6 +1245,18 @@ #define PHY_M_EC2_FO_BOOST (1<<3) /* Bit 3: Fiber Output Boost */ #define PHY_M_EC2_FO_AM_MSK 7 /* Bit 2.. 0: Fiber Output Amplitude */ +/***** PHY_MARV_EXT_P_STAT 16 bit r/w Ext. PHY Specific Status *****/ +#define PHY_M_FC_AUTO_SEL (1<<15) /* Bit 15: Fiber/Copper Auto Sel. dis. */ +#define PHY_M_FC_AN_REG_ACC (1<<14) /* Bit 14: Fiber/Copper Autoneg. reg acc */ +#define PHY_M_FC_RESULUTION (1<<13) /* Bit 13: Fiber/Copper Resulution */ +#define PHY_M_SER_IF_AN_BP (1<<12) /* Bit 12: Ser IF autoneg. bypass enable */ +#define PHY_M_SER_IF_BP_ST (1<<11) /* Bit 11: Ser IF autoneg. bypass status */ +#define PHY_M_IRQ_POLARITY (1<<10) /* Bit 10: IRQ polarity */ + /* Bit 9..4: reserved */ +#define PHY_M_UNDOC1 (1<< 7) /* undocumented bit !! */ +#define PHY_M_MODE_MASK (0xf<<0)/* Bit 3..0: copy of HWCFG MODE[3:0] */ + + /***** PHY_MARV_CABLE_DIAG 16 bit r/o Cable Diagnostic Reg *****/ #define PHY_M_CABD_ENA_TEST (1<<15) /* Bit 15: Enable Test */ #define PHY_M_CABD_STAT_MSK (3<<13) /* Bit 14..13: Status */ @@ -1444,7 +1291,7 @@ #define GM_GP_CTRL 0x0004 /* 16 bit r/w General Purpose Control */ #define GM_TX_CTRL 0x0008 /* 16 bit r/w Transmit Control Reg. */ #define GM_RX_CTRL 0x000c /* 16 bit r/w Receive Control Reg. */ -#define GM_TX_FLOW_CTRL 0x0010 /* 16 bit r/w Transmit Flow Control */ +#define GM_TX_FLOW_CTRL 0x0010 /* 16 bit r/w Transmit Flow-Control */ #define GM_TX_PARAM 0x0014 /* 16 bit r/w Transmit Parameter Reg. */ #define GM_SERIAL_MODE 0x0018 /* 16 bit r/w Serial Mode Register */ @@ -1507,7 +1354,7 @@ #define GM_RXF_SHT \ (GM_MIB_CNT_BASE + 80) /* Frames <64 Byte Received OK */ #define GM_RXE_FRAG \ - (GM_MIB_CNT_BASE + 88) /* Frames <64 Byte Receeived with FCS Err */ + (GM_MIB_CNT_BASE + 88) /* Frames <64 Byte Received with FCS Err */ #define GM_RXF_64B \ (GM_MIB_CNT_BASE + 96) /* 64 Byte Rx Frame */ #define GM_RXF_127B \ @@ -1582,10 +1429,9 @@ */ /* GM_GP_STAT 16 bit r/o General Purpose Status Register */ - #define GM_GPSR_SPEED (1<<15) /* Bit 15: Port Speed (1 = 100 Mbps) */ #define GM_GPSR_DUPLEX (1<<14) /* Bit 14: Duplex Mode (1 = Full) */ -#define GM_GPSR_FC_TX_DIS (1<<13) /* Bit 13: Tx Flow Control Mode Disabled */ +#define GM_GPSR_FC_TX_DIS (1<<13) /* Bit 13: Tx Flow-Control Mode Disabled */ #define GM_GPSR_LINK_UP (1<<12) /* Bit 12: Link Up Status */ #define GM_GPSR_PAUSE (1<<11) /* Bit 11: Pause State */ #define GM_GPSR_TX_ACTIVE (1<<10) /* Bit 10: Tx in Progress */ @@ -1595,14 +1441,14 @@ #define GM_GPSR_PHY_ST_CH (1<<5) /* Bit 5: PHY Status Change */ #define GM_GPSR_GIG_SPEED (1<<4) /* Bit 4: Gigabit Speed (1 = 1000 Mbps) */ #define GM_GPSR_PART_MODE (1<<3) /* Bit 3: Partition mode */ -#define GM_GPSR_FC_RX_DIS (1<<2) /* Bit 2: Rx Flow Control Mode Disabled */ +#define GM_GPSR_FC_RX_DIS (1<<2) /* Bit 2: Rx Flow-Control Mode Disabled */ #define GM_GPSR_PROM_EN (1<<1) /* Bit 1: Promiscuous Mode Enabled */ /* Bit 0: reserved */ /* GM_GP_CTRL 16 bit r/w General Purpose Control Register */ /* Bit 15: reserved */ #define GM_GPCR_PROM_ENA (1<<14) /* Bit 14: Enable Promiscuous Mode */ -#define GM_GPCR_FC_TX_DIS (1<<13) /* Bit 13: Disable Tx Flow Control Mode */ +#define GM_GPCR_FC_TX_DIS (1<<13) /* Bit 13: Disable Tx Flow-Control Mode */ #define GM_GPCR_TX_ENA (1<<12) /* Bit 12: Enable Transmit */ #define GM_GPCR_RX_ENA (1<<11) /* Bit 11: Enable Receive */ #define GM_GPCR_BURST_ENA (1<<10) /* Bit 10: Enable Burst Mode */ @@ -1611,22 +1457,25 @@ #define GM_GPCR_GIGS_ENA (1<<7) /* Bit 7: Gigabit Speed (1000 Mbps) */ #define GM_GPCR_FL_PASS (1<<6) /* Bit 6: Force Link Pass */ #define GM_GPCR_DUP_FULL (1<<5) /* Bit 5: Full Duplex Mode */ -#define GM_GPCR_FC_RX_DIS (1<<4) /* Bit 4: Disable Rx Flow Control Mode */ +#define GM_GPCR_FC_RX_DIS (1<<4) /* Bit 4: Disable Rx Flow-Control Mode */ #define GM_GPCR_SPEED_100 (1<<3) /* Bit 3: Port Speed 100 Mbps */ -#define GM_GPCR_AU_DUP_DIS (1<<2) /* Bit 2: Disable Auto-Update for Duplex */ -#define GM_GPCR_AU_FCT_DIS (1<<1) /* Bit 1: Disable Auto-Update for Flow-c. */ -#define GM_GPCR_AU_SPD_DIS (1<<0) /* Bit 0: Disable Auto-Update for Speed */ +#define GM_GPCR_AU_DUP_DIS (1<<2) /* Bit 2: Disable Auto-Update Duplex */ +#define GM_GPCR_AU_FCT_DIS (1<<1) /* Bit 1: Disable Auto-Update Flow-C. */ +#define GM_GPCR_AU_SPD_DIS (1<<0) /* Bit 0: Disable Auto-Update Speed */ #define GM_GPCR_SPEED_1000 (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100) #define GM_GPCR_AU_ALL_DIS (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS |\ GM_GPCR_AU_SPD_DIS) /* GM_TX_CTRL 16 bit r/w Transmit Control Register */ - #define GM_TXCR_FORCE_JAM (1<<15) /* Bit 15: Force Jam / Flow-Control */ #define GM_TXCR_CRC_DIS (1<<14) /* Bit 14: Disable insertion of CRC */ #define GM_TXCR_PAD_DIS (1<<13) /* Bit 13: Disable padding of packets */ -#define GM_TXCR_COL_THR (4<<10) /* Bit 12..10: Collision Threshold */ +#define GM_TXCR_COL_THR_MSK (1<<10) /* Bit 12..10: Collision Threshold */ + +#define TX_COL_THR(x) (SHIFT10(x) & GM_TXCR_COL_THR_MSK) + +#define TX_COL_DEF 0x04 /* GM_RX_CTRL 16 bit r/w Receive Control Register */ #define GM_RXCR_UCF_ENA (1<<15) /* Bit 15: Enable Unicast filtering */ @@ -1639,35 +1488,41 @@ #define GM_TXPA_JAMIPG_MSK (0x1f<<9) /* Bit 13..9: Jam IPG */ #define GM_TXPA_JAMDAT_MSK (0x1f<<4) /* Bit 8..4: IPG Jam to Data */ /* Bit 3..0: reserved */ -#define JAM_LEN_VAL(x) SHIFT14(x) -#define JAM_IPG_VAL(x) SHIFT9(x) -#define IPG_JAM_DATA(x) SHIFT4(x) + +#define TX_JAM_LEN_VAL(x) (SHIFT14(x) & GM_TXPA_JAMLEN_MSK) +#define TX_JAM_IPG_VAL(x) (SHIFT9(x) & GM_TXPA_JAMIPG_MSK) +#define TX_IPG_JAM_DATA(x) (SHIFT4(x) & GM_TXPA_JAMDAT_MSK) + +#define TX_JAM_LEN_DEF 0x03 +#define TX_JAM_IPG_DEF 0x0b +#define TX_IPG_JAM_DEF 0x1c /* GM_SERIAL_MODE 16 bit r/w Serial Mode Register */ -#define GM_SMOD_DATABL_MSK (0x1f<<11) /* Bit 15..11: Data Blinder */ -#define GM_SMOD_LIMIT_4 (1<<10) /* Bit 10: 4 consecutive transmit trials */ -#define GM_SMOD_VLAN_ENA (1<<9) /* Bit 9: Enable VLAN (Max. Frame Length) */ -#define GM_SMOD_JUMBO_ENA (1<<8) /* Bit 8: Enable Jumbo (Max. Frame Length) */ +#define GM_SMOD_DATABL_MSK (0x1f<<11) /* Bit 15..11: Data Blinder (r/o) */ +#define GM_SMOD_LIMIT_4 (1<<10) /* Bit 10: 4 consecutive Tx trials */ +#define GM_SMOD_VLAN_ENA (1<<9) /* Bit 9: Enable VLAN (Max. Frame Len) */ +#define GM_SMOD_JUMBO_ENA (1<<8) /* Bit 8: Enable Jumbo (Max. Frame Len) */ /* Bit 7..5: reserved */ #define GM_SMOD_IPG_MSK 0x1f /* Bit 4..0: Inter-Packet Gap (IPG) */ -#define DATA_BLIND_VAL(x) SHIFT11(x) -#define DATA_BLIND_FAST_ETH 0x1c -#define DATA_BLIND_GIGABIT 4 +#define DATA_BLIND_VAL(x) (SHIFT11(x) & GM_SMOD_DATABL_MSK) +#define DATA_BLIND_DEF 0x04 -#define IPG_VAL_FAST_ETH 0x1e -#define IPG_VAL_GIGABIT 6 +#define IPG_DATA_VAL(x) (x & GM_SMOD_IPG_MSK) +#define IPG_DATA_DEF 0x1e /* GM_SMI_CTRL 16 bit r/w SMI Control Register */ - -#define GM_SMI_CT_PHY_AD(x) SHIFT11(x) -#define GM_SMI_CT_REG_AD(x) SHIFT6(x) +#define GM_SMI_CT_PHY_A_MSK (0x1f<<11) /* Bit 15..11: PHY Device Address */ +#define GM_SMI_CT_REG_A_MSK (0x1f<<6) /* Bit 10.. 6: PHY Register Address */ #define GM_SMI_CT_OP_RD (1<<5) /* Bit 5: OpCode Read (0=Write)*/ #define GM_SMI_CT_RD_VAL (1<<4) /* Bit 4: Read Valid (Read completed) */ #define GM_SMI_CT_BUSY (1<<3) /* Bit 3: Busy (Operation in progress) */ /* Bit 2..0: reserved */ -/* GM_PHY_ADDR 16 bit r/w GPHY Address Register */ +#define GM_SMI_CT_PHY_AD(x) (SHIFT11(x) & GM_SMI_CT_PHY_A_MSK) +#define GM_SMI_CT_REG_AD(x) (SHIFT6(x) & GM_SMI_CT_REG_A_MSK) + + /* GM_PHY_ADDR 16 bit r/w GPHY Address Register */ /* Bit 15..6: reserved */ #define GM_PAR_MIB_CLR (1<<5) /* Bit 5: Set MIB Clear Counter Mode */ #define GM_PAR_MIB_TST (1<<4) /* Bit 4: MIB Load Counter (Test Mode) */ Index: drivers/net/skfp/fplustm.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/skfp/fplustm.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/skfp/fplustm.c 22 Jul 2004 19:49:37 -0000 1.1 +++ drivers/net/skfp/fplustm.c 4 Aug 2004 01:29:23 -0000 1.2 @@ -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; { Index: drivers/net/tokenring/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/tokenring/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/tokenring/Config.in 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/tokenring/Config.in 4 Aug 2004 01:29:23 -0000 1.2 @@ -20,12 +20,12 @@ dep_tristate ' IBM Lanstreamer chipset PCI adapter support' CONFIG_IBMLS $CONFIG_TR $CONFIG_PCI dep_tristate ' 3Com 3C359 Token Link Velocity XL adapter support' CONFIG_3C359 $CONFIG_TR $CONFIG_PCI tristate ' Generic TMS380 Token Ring ISA/PCI adapter support' CONFIG_TMS380TR - if [ "$CONFIG_TMS380TR" != "n" ]; then - dep_tristate ' Generic TMS380 PCI support' CONFIG_TMSPCI $CONFIG_PCI - dep_tristate ' Generic TMS380 ISA support' CONFIG_TMSISA $CONFIG_ISA - dep_tristate ' Madge Smart 16/4 PCI Mk2 support' CONFIG_ABYSS $CONFIG_PCI - dep_tristate ' Madge Smart 16/4 Ringnode MicroChannel' CONFIG_MADGEMC $CONFIG_MCA - fi + + dep_tristate ' Generic TMS380 PCI support' CONFIG_TMSPCI $CONFIG_PCI $CONFIG_TMS380TR + dep_tristate ' Generic TMS380 ISA support' CONFIG_TMSISA $CONFIG_ISA $CONFIG_TMS380TR + dep_tristate ' Madge Smart 16/4 PCI Mk2 support' CONFIG_ABYSS $CONFIG_PCI $CONFIG_TMS380TR + dep_tristate ' Madge Smart 16/4 Ringnode MicroChannel' CONFIG_MADGEMC $CONFIG_MCA $CONFIG_TMS380TR + if [ "$CONFIG_ISA" = "y" -o "$CONFIG_MCA" = "y" ]; then tristate ' SMC ISA/MCA adapter support' CONFIG_SMCTR fi Index: drivers/net/tokenring/olympic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/tokenring/olympic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/tokenring/olympic.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/tokenring/olympic.c 4 Aug 2004 01:29:23 -0000 1.2 @@ -457,14 +457,7 @@ printk("Before the open command \n"); #endif do { - int i; - - for(i=0;iif_port = 2 - dev->if_port; } else dev->if_port = 0; - else + else if (dev->if_port != 0 || (csr12 & 0x0004) != 0) dev->if_port = 1; tulip_select_media(dev, 0); } @@ -1070,12 +1073,12 @@ set_bit_le(index, hash_table); - for (i = 0; i < 32; i++) { - *setup_frm++ = hash_table[i]; - *setup_frm++ = hash_table[i]; - } - setup_frm = &tp->setup_frame[13*6]; } + for (i = 0; i < 32; i++) { + *setup_frm++ = hash_table[i]; + *setup_frm++ = hash_table[i]; + } + setup_frm = &tp->setup_frame[13*6]; /* Fill the final entry with our physical address. */ eaddrs = (u16 *)dev->dev_addr; @@ -1175,11 +1178,13 @@ } } else { unsigned long flags; + u32 tx_flags = 0x08000000 | 192; /* Note that only the low-address shortword of setup_frame is valid! The values are doubled for big-endian architectures. */ if (dev->mc_count > 14) { /* Must use a multicast hash table. */ build_setup_frame_hash(tp->setup_frame, dev); + tx_flags = 0x08400000 | 192; } else { build_setup_frame_perfect(tp->setup_frame, dev); } @@ -1189,7 +1194,6 @@ if (tp->cur_tx - tp->dirty_tx > TX_RING_SIZE - 2) { /* Same setup recently queued, we need not add it. */ } else { - u32 tx_flags = 0x08000000 | 192; unsigned int entry; int dummy = -1; @@ -1403,12 +1407,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 Index: drivers/net/wan/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/Config.in 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/Config.in 4 Aug 2004 01:29:24 -0000 1.2 @@ -23,7 +23,7 @@ # COMX drivers # - tristate ' MultiGate (COMX) synchronous serial boards support' CONFIG_COMX + bool ' MultiGate (COMX) synchronous serial boards support' CONFIG_COMX if [ "$CONFIG_COMX" != "n" ]; then dep_tristate ' Support for COMX/CMX/HiCOMX boards' CONFIG_COMX_HW_COMX $CONFIG_COMX dep_tristate ' Support for LoCOMX board' CONFIG_COMX_HW_LOCOMX $CONFIG_COMX @@ -38,12 +38,12 @@ fi dep_tristate ' Support for Frame Relay on MultiGate boards' CONFIG_COMX_PROTO_FR $CONFIG_COMX fi -# -# The Etinc driver has not been tested as non-modular yet. -# - - dep_tristate ' Etinc PCISYNC serial board support (EXPERIMENTAL)' CONFIG_DSCC4 m + dep_tristate ' DSCC4 support' CONFIG_DSCC4 m + if [ "$CONFIG_DSCC4" = "m" ]; then + bool ' Etinc PCISYNC features' CONFIG_DSCC4_PCISYNC + bool ' GPIO and PCI #RST pins wired together' CONFIG_DSCC4_PCI_RST + fi # # Lan Media's board. Currently 1000, 1200, 5200, 5245 @@ -68,6 +68,7 @@ tristate ' Generic HDLC layer' CONFIG_HDLC if [ "$CONFIG_HDLC" != "n" ]; then bool ' Raw HDLC support' CONFIG_HDLC_RAW + bool ' Raw HDLC Ethernet device support' CONFIG_HDLC_RAW_ETH bool ' Cisco HDLC support' CONFIG_HDLC_CISCO bool ' Frame Relay support' CONFIG_HDLC_FR bool ' Synchronous Point-to-Point Protocol (PPP) support' CONFIG_HDLC_PPP @@ -76,13 +77,23 @@ else comment ' X.25/LAPB support is disabled' fi - dep_tristate ' SDL RISCom/N2 support' CONFIG_N2 $CONFIG_HDLC - dep_tristate ' Moxa C101 support' CONFIG_C101 $CONFIG_HDLC - dep_tristate ' FarSync T-Series support' CONFIG_FARSYNC $CONFIG_HDLC - bool ' Debug received/transmitted packets' CONFIG_HDLC_DEBUG_PKT - bool ' Debug hard_header routines' CONFIG_HDLC_DEBUG_HARD_HEADER - bool ' Debug FECN/BECN conditions' CONFIG_HDLC_DEBUG_ECN - bool ' Debug RX/TX packet rings' CONFIG_HDLC_DEBUG_RINGS + if [ "$CONFIG_PCI" != "n" ]; then + dep_tristate ' Goramo PCI200SYN support' CONFIG_PCI200SYN $CONFIG_HDLC + dep_tristate ' Cyclades-PC300 support (RS-232/V.35, X.21, T1/E1 boards)' CONFIG_PC300 $CONFIG_HDLC + if [ "$CONFIG_PC300" != "n" ]; then + if [ "$CONFIG_PPP" != "n" -a "$CONFIG_PPP_MULTLINK" != "n" -a "$CONFIG_PPP_SYNCTTY" != "n" -a "$CONFIG_HDLC_PPP" = "y" ]; then + bool ' Cyclades-PC300 MLPPP support' CONFIG_PC300_MLPPP + else + comment ' Cyclades-PC300 MLPPP support is disabled.' + comment ' Refer to the file README.mlppp, provided by PC300 package.' + fi + fi + dep_tristate ' FarSync T-Series support' CONFIG_FARSYNC $CONFIG_HDLC + fi + if [ "$CONFIG_ISA" != "n" ]; then + dep_tristate ' SDL RISCom/N2 support' CONFIG_N2 $CONFIG_HDLC + dep_tristate ' Moxa C101 support' CONFIG_C101 $CONFIG_HDLC + fi fi tristate ' Frame relay DLCI support' CONFIG_DLCI Index: drivers/net/wan/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/Makefile 22 Jul 2004 19:49:35 -0000 1.1 +++ drivers/net/wan/Makefile 4 Aug 2004 01:29:24 -0000 1.2 @@ -9,7 +9,7 @@ O_TARGET := wan.o -export-objs = z85230.o syncppp.o comx.o sdladrv.o cycx_drv.o hdlc_generic.o +export-objs = z85230.o syncppp.o comx.o sdladrv.o cycx_drv.o hdlc_generic.o pc300_drv.o list-multi = wanpipe.o cyclomx.o wanpipe-objs = sdlamain.o sdla_ft1.o $(wanpipe-y) @@ -24,12 +24,15 @@ hdlc-y := hdlc_generic.o hdlc-$(CONFIG_HDLC_RAW) += hdlc_raw.o +hdlc-$(CONFIG_HDLC_RAW_ETH) += hdlc_raw_eth.o hdlc-$(CONFIG_HDLC_CISCO) += hdlc_cisco.o hdlc-$(CONFIG_HDLC_FR) += hdlc_fr.o hdlc-$(CONFIG_HDLC_PPP) += hdlc_ppp.o hdlc-$(CONFIG_HDLC_X25) += hdlc_x25.o hdlc-objs := $(hdlc-y) +pc300-$(CONFIG_PC300_MLPPP) += pc300_tty.o + obj-$(CONFIG_HOSTESS_SV11) += z85230.o syncppp.o hostess_sv11.o obj-$(CONFIG_SEALEVEL_4021) += z85230.o syncppp.o sealevel.o obj-$(CONFIG_COMX) += comx.o @@ -70,15 +73,20 @@ obj-$(CONFIG_CYCLADES_SYNC) += cycx_drv.o cyclomx.o obj-$(CONFIG_LAPBETHER) += lapbether.o obj-$(CONFIG_SBNI) += sbni.o +obj-$(CONFIG_PC300) += pc300.o obj-$(CONFIG_HDLC) += hdlc.o ifeq ($(CONFIG_HDLC_PPP),y) obj-$(CONFIG_HDLC) += syncppp.o endif obj-$(CONFIG_N2) += n2.o obj-$(CONFIG_C101) += c101.o +obj-$(CONFIG_PCI200SYN) += pci200syn.o include $(TOPDIR)/Rules.make +pc300.o: pc300_drv.o $(pc300-y) + $(LD) -r -o $@ pc300_drv.o $(pc300-y) + hdlc.o: $(hdlc-objs) $(LD) -r -o $@ $(hdlc-objs) Index: drivers/net/wan/c101.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/c101.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/c101.c 22 Jul 2004 19:49:35 -0000 1.1 +++ drivers/net/wan/c101.c 4 Aug 2004 01:29:24 -0000 1.2 @@ -1,12 +1,11 @@ /* * Moxa C101 synchronous serial card driver for Linux * - * Copyright (C) 2000-2002 Krzysztof Halasa + * Copyright (C) 2000-2003 Krzysztof Halasa * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. * * For information see http://hq.pm.waw.pl/hdlc/ * @@ -15,7 +14,6 @@ * Moxa C101 User's Manual */ -#include #include #include #include @@ -31,9 +29,12 @@ #include "hd64570.h" -static const char* version = "Moxa C101 driver version: 1.10"; +static const char* version = "Moxa C101 driver version: 1.14"; static const char* devname = "C101"; +#undef DEBUG_PKT +#define DEBUG_RINGS + #define C101_PAGE 0x1D00 #define C101_DTR 0x1E00 #define C101_SCA 0x1F00 @@ -41,6 +42,10 @@ #define C101_MAPPED_RAM_SIZE 0x4000 #define RAM_SIZE (256 * 1024) +#define TX_RING_BUFFERS 10 +#define RX_RING_BUFFERS ((RAM_SIZE - C101_WINDOW_SIZE) / \ + (sizeof(pkt_desc) + HDLC_MAX_MRU) - TX_RING_BUFFERS) + #define CLOCK_BASE 9830400 /* 9.8304 MHz */ #define PAGE0_ALWAYS_MAPPED @@ -52,20 +57,20 @@ spinlock_t lock; /* TX lock */ u8 *win0base; /* ISA window base address */ u32 phy_winbase; /* ISA physical base address */ - u16 buff_offset; /* offset of first buffer of first channel */ sync_serial_settings settings; + int rxpart; /* partial frame received, next frame invalid*/ unsigned short encoding; unsigned short parity; + u16 rx_ring_buffers; /* number of buffers in a ring */ + u16 tx_ring_buffers; + u16 buff_offset; /* offset of first buffer of first channel */ + u16 rxin; /* rx ring buffer 'in' pointer */ + u16 txin; /* tx ring buffer 'in' and 'last' pointers */ + u16 txlast; u8 rxs, txs, tmc; /* SCA registers */ u8 irq; /* IRQ (3-15) */ - u8 ring_buffers; /* number of buffers in a ring */ u8 page; - u8 rxin; /* rx ring buffer 'in' pointer */ - u8 txin; /* tx ring buffer 'in' and 'last' pointers */ - u8 txlast; - u8 rxpart; /* partial frame received, next frame invalid*/ - struct card_s *next_card; }card_t; @@ -78,7 +83,12 @@ #define sca_in(reg, card) readb((card)->win0base + C101_SCA + (reg)) #define sca_out(value, reg, card) writeb(value, (card)->win0base + C101_SCA + (reg)) #define sca_inw(reg, card) readw((card)->win0base + C101_SCA + (reg)) -#define sca_outw(value, reg, card) writew(value, (card)->win0base + C101_SCA + (reg)) + +/* EDA address register must be set in EDAL, EDAH order - 8 bit ISA bus */ +#define sca_outw(value, reg, card) do { \ + writeb(value & 0xFF, (card)->win0base + C101_SCA + (reg)); \ + writeb((value >> 8 ) & 0xFF, (card)->win0base + C101_SCA + (reg+1));\ +} while(0) #define port_to_card(port) (port) #define log_node(port) (0) @@ -180,7 +190,7 @@ hdlc_device *hdlc = dev_to_hdlc(dev); port_t *port = hdlc_to_port(hdlc); -#ifdef CONFIG_HDLC_DEBUG_RINGS +#ifdef DEBUG_RINGS if (cmd == SIOCDEVPRIVATE) { sca_dump_rings(hdlc); return 0; @@ -229,6 +239,8 @@ static void c101_destroy_card(card_t *card) { + readb(card->win0base + C101_PAGE); /* Resets SCA? */ + if (card->irq) free_irq(card->irq, card); @@ -242,7 +254,7 @@ -static int c101_run(unsigned long irq, unsigned long winbase) +static int __init c101_run(unsigned long irq, unsigned long winbase) { struct net_device *dev; card_t *card; @@ -285,10 +297,8 @@ return -EBUSY; } - /* 2 rings required for 1 port */ - card->ring_buffers = (RAM_SIZE -C101_WINDOW_SIZE) / (2 * HDLC_MAX_MRU); - printk(KERN_DEBUG "c101: using %u packets rings\n",card->ring_buffers); - + card->tx_ring_buffers = TX_RING_BUFFERS; + card->rx_ring_buffers = RX_RING_BUFFERS; card->buff_offset = C101_WINDOW_SIZE; /* Bytes 1D00-1FFF reserved */ readb(card->win0base + C101_PAGE); /* Resets SCA? */ @@ -321,6 +331,11 @@ sca_init_sync_port(card); /* Set up C101 memory */ + printk(KERN_INFO "%s: Moxa C101 on IRQ%u," + " using %u TX + %u RX packets rings\n", + hdlc_to_name(&card->hdlc), card->irq, + card->tx_ring_buffers, card->rx_ring_buffers); + *new_card = card; new_card = &card->next_card; return 0; @@ -337,7 +352,7 @@ return -ENOSYS; /* no parameters specified, abort */ } - printk(KERN_INFO "%s (SCA-%s)\n", version, sca_version); + printk(KERN_INFO "%s\n", version); do { unsigned long irq, ram; @@ -352,7 +367,7 @@ c101_run(irq, ram); if (*hw == '\x0') - return 0; + return first_card ? 0 : -ENOSYS; }while(*hw++ == ':'); printk(KERN_ERR "c101: invalid hardware parameters\n"); @@ -389,6 +404,6 @@ MODULE_AUTHOR("Krzysztof Halasa "); MODULE_DESCRIPTION("Moxa C101 serial port driver"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); MODULE_PARM(hw, "s"); /* hw=irq,ram:irq,... */ EXPORT_NO_SYMBOLS; Index: drivers/net/wan/cosa.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/cosa.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/cosa.c 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/cosa.c 4 Aug 2004 01:29:24 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: cosa.c,v 1.1 2004/07/22 19:49:36 joff Exp $ */ +/* $Id: cosa.c,v 1.2 2004/08/04 01:29:24 joff Exp $ */ /* * Copyright (C) 1995-1997 Jan "Yenya" Kasprzak @@ -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, }; Index: drivers/net/wan/cosa.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/cosa.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/cosa.h 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/cosa.h 4 Aug 2004 01:29:24 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: cosa.h,v 1.1 2004/07/22 19:49:36 joff Exp $ */ +/* $Id: cosa.h,v 1.2 2004/08/04 01:29:24 joff Exp $ */ /* * Copyright (C) 1995-1997 Jan "Yenya" Kasprzak Index: drivers/net/wan/dscc4.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/dscc4.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/dscc4.c 22 Jul 2004 19:49:35 -0000 1.1 +++ drivers/net/wan/dscc4.c 4 Aug 2004 01:29:24 -0000 1.2 @@ -47,7 +47,7 @@ * Tx direction * When the tx ring is full, the xmit routine issues a call to netdev_stop. * The device is supposed to be enabled again during an ALLS irq (we could - * use HI but as it's easy to loose events, it's fscked). + * use HI but as it's easy to lose events, it's fscked). * * Rx direction * The received frames aren't supposed to span over multiple receiving areas. @@ -80,7 +80,6 @@ * - misc crapectomy. */ -#include #include #include #include @@ -108,10 +107,15 @@ #include /* Version */ -static const char version[] = "$Id: dscc4.c,v 1.1 2004/07/22 19:49:35 joff Exp $ for Linux\n"; +static const char version[] = "$Id: dscc4.c,v 1.2 2004/08/04 01:29:24 joff Exp $ for Linux\n"; static int debug; static int quartz; +#ifdef CONFIG_DSCC4_PCI_RST +static DECLARE_MUTEX(dscc4_sem); +static u32 dscc4_pci_config_store[16]; +#endif + #define DRV_NAME "dscc4" #undef DSCC4_POLLING @@ -164,8 +168,15 @@ #define SOURCE_ID(flags) (((flags) >> 28) & 0x03) #define TO_SIZE(state) (((state) >> 16) & 0x1fff) -#define TO_STATE(len) cpu_to_le32(((len) & TxSizeMax) << 16) -#define RX_MAX(len) ((((len) >> 5) + 1) << 5) + +/* + * Given the operating range of Linux HDLC, the 2 defines below could be + * made simpler. However they are a fine reminder for the limitations of + * the driver: it's better to stay < TxSizeMax and < RxSizeMax. + */ +#define TO_STATE_TX(len) cpu_to_le32(((len) & TxSizeMax) << 16) +#define TO_STATE_RX(len) cpu_to_le32((RX_MAX(len) % RxSizeMax) << 16) +#define RX_MAX(len) ((((len) >> 5) + 1) << 5) /* Cf RLCR */ #define SCC_REG_START(dpriv) (SCC_START+(dpriv->dev_id)*SCC_OFFSET) struct dscc4_pci_priv { @@ -256,6 +267,10 @@ #define IMR 0x54 #define ISR 0x58 +#define GPDIR 0x0400 +#define GPDATA 0x0404 +#define GPIM 0x0408 + /* Bit masks */ #define EncodingMask 0x00700000 #define CrcMask 0x00000003 @@ -272,7 +287,8 @@ #define Idt 0x00080000 #define TxSccRes 0x01000000 #define RxSccRes 0x00010000 -#define TxSizeMax 0x1fff +#define TxSizeMax 0x1fff /* Datasheet DS1 - 11.1.1.1 */ +#define RxSizeMax 0x1ffc /* Datasheet DS1 - 11.1.2.1 */ #define Ccr0ClockMask 0x0000003f #define Ccr1LoopMask 0x00000200 @@ -283,6 +299,7 @@ #define Hold 0x40000000 #define SccBusy 0x10000000 #define PowerUp 0x80000000 +#define Vis 0x00001000 #define FrameOk (FrameVfr | FrameCrc) #define FrameVfr 0x80 #define FrameRdo 0x40 @@ -319,10 +336,19 @@ #define Arf 0x00000002 #define ArAck 0x00000001 -/* Misc */ +/* State flags */ +#define Ready 0x00000000 #define NeedIDR 0x00000001 #define NeedIDT 0x00000002 #define RdoSet 0x00000004 +#define FakeReset 0x00000008 + +/* Don't mask RDO. Ever. */ +#ifdef DSCC4_POLLING +#define EventsMask 0xfffeef7f +#else +#define EventsMask 0xfffa8f7a +#endif /* Functions prototypes */ static inline void dscc4_rx_irq(struct dscc4_pci_priv *, struct dscc4_dev_priv *); @@ -487,9 +513,9 @@ skb = dev_alloc_skb(len); dpriv->rx_skbuff[dirty] = skb; if (skb) { - skb->dev = dev; - skb->protocol = htons(ETH_P_HDLC); - skb->mac.raw = skb->data; + skb->dev = dev; + skb->protocol = hdlc_type_trans(skb, dev); + skb->mac.raw = skb->data; rx_fd->data = pci_map_single(dpriv->pci_priv->pdev, skb->data, len, PCI_DMA_FROMDEVICE); } else { @@ -566,15 +592,19 @@ return (i >= 0 ) ? i : -EAGAIN; } -/* Requires protection against interrupt */ +#if 0 /* dscc4_{rx/tx}_reset are both unreliable - more tweak needed */ static void dscc4_rx_reset(struct dscc4_dev_priv *dpriv, struct net_device *dev) { + unsigned long flags; + + spin_lock_irqsave(&dpriv->pci_priv->lock, flags); /* Cf errata DS5 p.6 */ writel(0x00000000, dev->base_addr + CH0LRDA + dpriv->dev_id*4); - scc_writel(~PowerUp & scc_readl(dpriv, CCR0), dpriv, dev, CCR0); + scc_patchl(PowerUp, 0, dpriv, dev, CCR0); readl(dev->base_addr + CH0LRDA + dpriv->dev_id*4); writel(MTFi|Rdr, dev->base_addr + dpriv->dev_id*0x0c + CH0CFG); writel(Action, dev->base_addr + GCMDR); + spin_unlock_irqrestore(&dpriv->pci_priv->lock, flags); } static void dscc4_tx_reset(struct dscc4_dev_priv *dpriv, struct net_device *dev) @@ -582,7 +612,7 @@ u16 i = 0; /* Cf errata DS5 p.7 */ - scc_writel(~PowerUp & scc_readl(dpriv, CCR0), dpriv, dev, CCR0); + scc_patchl(PowerUp, 0, dpriv, dev, CCR0); scc_writel(0x00050000, dpriv, dev, CCR2); /* * Must be longer than the time required to fill the fifo. @@ -596,6 +626,7 @@ if (dscc4_do_action(dev, "Rdt") < 0) printk(KERN_ERR "%s: Tx reset failed\n", dev->name); } +#endif /* TODO: (ab)use this function to refill a completely depleted RX ring. */ static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv, @@ -619,6 +650,8 @@ stats->rx_packets++; stats->rx_bytes += pkt_len; skb_put(skb, pkt_len); + if (netif_running(dev)) + skb->protocol = hdlc_type_trans(skb, dev); skb->dev->last_rx = jiffies; netif_rx(skb); } else { @@ -661,8 +694,8 @@ kfree(ppriv); } -static int __init dscc4_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int __devinit dscc4_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) { struct dscc4_pci_priv *priv; struct dscc4_dev_priv *dpriv; @@ -805,7 +838,8 @@ static void dscc4_init_registers(struct dscc4_dev_priv *dpriv, struct net_device *dev) { - scc_writel(0x80001000, dpriv, dev, CCR0); + /* No interrupts, SCC core disabled. Let's relax */ + scc_writel(0x00000000, dpriv, dev, CCR0); scc_writel(LengthCheck | (HDLC_MAX_MRU >> 5), dpriv, dev, RLCR); @@ -813,29 +847,21 @@ * No address recognition/crc-CCITT/cts enabled * Shared flags transmission disabled - cf errata DS5 p.11 * Carrier detect disabled - cf errata p.14 + * FIXME: carrier detection/polarity may be handled more gracefully. */ - scc_writel(0x021c8000, dpriv, dev, CCR1); + scc_writel(0x02408000, dpriv, dev, CCR1); /* crc not forwarded - Cf errata DS5 p.11 */ scc_writel(0x00050008 & ~RxActivate, dpriv, dev, CCR2); // crc forwarded //scc_writel(0x00250008 & ~RxActivate, dpriv, dev, CCR2); - - /* Don't mask RDO. Ever. */ -#ifdef DSCC4_POLLING - scc_writel(0xfffeef7f, dpriv, dev, IMR); /* Interrupt mask */ -#else - //scc_writel(0xfffaef7f, dpriv, dev, IMR); /* Interrupt mask */ - //scc_writel(0xfffaef7e, dpriv, dev, IMR); /* Interrupt mask */ - scc_writel(0xfffa8f7a, dpriv, dev, IMR); /* Interrupt mask */ -#endif } static int dscc4_found1(struct pci_dev *pdev, unsigned long ioaddr) { struct dscc4_pci_priv *ppriv; struct dscc4_dev_priv *root; - int i = 0; + int i, ret = -ENOMEM; root = (struct dscc4_dev_priv *) kmalloc(dev_per_card*sizeof(*root), GFP_KERNEL); @@ -867,6 +893,8 @@ d->tx_timeout = dscc4_tx_timeout; d->watchdog_timeo = TX_TIMEOUT; + SET_MODULE_OWNER(d); + dpriv->dev_id = i; dpriv->pci_priv = ppriv; spin_lock_init(&dpriv->lock); @@ -874,31 +902,40 @@ hdlc->xmit = dscc4_start_xmit; hdlc->attach = dscc4_hdlc_attach; - if (register_hdlc_device(hdlc)) { + ret = register_hdlc_device(hdlc); + if (ret < 0) { printk(KERN_ERR "%s: unable to register\n", DRV_NAME); goto err_unregister; } - hdlc->proto = IF_PROTO_HDLC; - SET_MODULE_OWNER(d); + dscc4_init_registers(dpriv, d); dpriv->parity = PARITY_CRC16_PR0_CCITT; dpriv->encoding = ENCODING_NRZ; + + ret = dscc4_init_ring(d); + if (ret < 0) { + unregister_hdlc_device(hdlc); + goto err_unregister; + } } - if (dscc4_set_quartz(root, quartz) < 0) + ret = dscc4_set_quartz(root, quartz); + if (ret < 0) goto err_unregister; ppriv->root = root; spin_lock_init(&ppriv->lock); pci_set_drvdata(pdev, ppriv); - return 0; + return ret; err_unregister: - while (--i >= 0) + while (--i >= 0) { + dscc4_release_ring(root + i); unregister_hdlc_device(&root[i].hdlc); + } kfree(ppriv); err_free_dev: kfree(root); err_out: - return -1; + return ret; }; /* FIXME: get rid of the unneeded code */ @@ -932,6 +969,46 @@ return 0; } +#ifdef CONFIG_DSCC4_PCI_RST +/* + * Some DSCC4-based cards wires the GPIO port and the PCI #RST pin together + * so as to provide a safe way to reset the asic while not the whole machine + * rebooting. + * + * This code doesn't need to be efficient. Keep It Simple + */ +static void dscc4_pci_reset(struct pci_dev *pdev, u32 ioaddr) +{ + int i; + + down(&dscc4_sem); + for (i = 0; i < 16; i++) + pci_read_config_dword(pdev, i << 2, dscc4_pci_config_store + i); + + /* Maximal LBI clock divider (who cares ?) and whole GPIO range. */ + writel(0x001c0000, ioaddr + GMODE); + /* Configure GPIO port as output */ + writel(0x0000ffff, ioaddr + GPDIR); + /* Disable interruption */ + writel(0x0000ffff, ioaddr + GPIM); + + writel(0x0000ffff, ioaddr + GPDATA); + writel(0x00000000, ioaddr + GPDATA); + + /* Flush posted writes */ + readl(ioaddr + GSTAR); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(10); + + for (i = 0; i < 16; i++) + pci_write_config_dword(pdev, i << 2, dscc4_pci_config_store[i]); + up(&dscc4_sem); +} +#else +#define dscc4_pci_reset(pdev,ioaddr) do {} while (0) +#endif /* CONFIG_DSCC4_PCI_RST */ + static int dscc4_open(struct net_device *dev) { struct dscc4_dev_priv *dpriv = dscc4_priv(dev); @@ -949,12 +1026,29 @@ ppriv = dpriv->pci_priv; - if ((ret = dscc4_init_ring(dev))) - goto err_out; + /* + * Due to various bugs, there is no way to reliably reset a + * specific port (manufacturer's dependant special PCI #RST wiring + * apart: it affects all ports). Thus the device goes in the best + * silent mode possible at dscc4_close() time and simply claims to + * be up if it's opened again. It still isn't possible to change + * the HDLC configuration without rebooting but at least the ports + * can be up/down ifconfig'ed without killing the host. + */ + if (dpriv->flags & FakeReset) { + dpriv->flags &= ~FakeReset; + scc_patchl(0, PowerUp, dpriv, dev, CCR0); + scc_patchl(0, 0x00050000, dpriv, dev, CCR2); + scc_writel(EventsMask, dpriv, dev, IMR); + printk(KERN_INFO "%s: up again.\n", dev->name); + goto done; + } /* IDT+IDR during XPR */ dpriv->flags = NeedIDR | NeedIDT; + scc_patchl(0, PowerUp | Vis, dpriv, dev, CCR0); + /* * The following is a bit paranoid... * @@ -965,15 +1059,17 @@ if (scc_readl_star(dpriv, dev) & SccBusy) { printk(KERN_ERR "%s busy. Try later\n", dev->name); ret = -EAGAIN; - goto err_free_ring; + goto err_out; } else printk(KERN_INFO "%s: available. Good\n", dev->name); + scc_writel(EventsMask, dpriv, dev, IMR); + /* Posted write is flushed in the wait_ack loop */ scc_writel(TxSccRes | RxSccRes, dpriv, dev, CMDR); if ((ret = dscc4_wait_ack_cec(dpriv, dev, "Cec")) < 0) - goto err_free_ring; + goto err_disable_scc_events; /* * I would expect XPR near CE completion (before ? after ?). @@ -984,12 +1080,13 @@ */ if ((ret = dscc4_xpr_ack(dpriv)) < 0) { printk(KERN_ERR "%s: %s timeout\n", DRV_NAME, "XPR"); - goto err_free_ring; + goto err_disable_scc_events; } if (debug > 2) dscc4_tx_print(dev, dpriv, "Open"); +done: netif_start_queue(dev); init_timer(&dpriv->timer); @@ -1001,8 +1098,9 @@ return 0; -err_free_ring: - dscc4_release_ring(dpriv); +err_disable_scc_events: + scc_writel(0xffffffff, dpriv, dev, IMR); + scc_patchl(PowerUp | Vis, 0, dpriv, dev, CCR0); err_out: hdlc_close(hdlc); MOD_DEC_USE_COUNT; @@ -1027,7 +1125,7 @@ next = dpriv->tx_current%TX_RING_SIZE; dpriv->tx_skbuff[next] = skb; tx_fd = dpriv->tx_fd + next; - tx_fd->state = FrameEnd | TO_STATE(skb->len); + tx_fd->state = FrameEnd | TO_STATE_TX(skb->len); tx_fd->data = pci_map_single(ppriv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); tx_fd->complete = 0x00000000; @@ -1058,19 +1156,17 @@ { struct dscc4_dev_priv *dpriv = dscc4_priv(dev); hdlc_device *hdlc = dev_to_hdlc(dev); - unsigned long flags; del_timer_sync(&dpriv->timer); netif_stop_queue(dev); - spin_lock_irqsave(&dpriv->pci_priv->lock, flags); - dscc4_rx_reset(dpriv, dev); - spin_unlock_irqrestore(&dpriv->pci_priv->lock, flags); + scc_patchl(PowerUp | Vis, 0, dpriv, dev, CCR0); + scc_patchl(0x00050000, 0, dpriv, dev, CCR2); + scc_writel(0xffffffff, dpriv, dev, IMR); - dscc4_tx_reset(dpriv, dev); + dpriv->flags |= FakeReset; hdlc_close(hdlc); - dscc4_release_ring(dpriv); MOD_DEC_USE_COUNT; return 0; @@ -1080,13 +1176,56 @@ { int ret = 0; -#ifdef CONFIG_DSCC4_CLOCK_ON_TWO_PORTS_ONLY +#ifdef CONFIG_DSCC4_PCISYNC if (port >= 2) ret = -1; #endif return ret; } +/* + * DS1 p.137: "There are a total of 13 different clocking modes..." + * ^^ + * Design choices: + * - by default, assume a clock is provided on pin RxClk/TxClk (clock mode 0a). + * Clock mode 3b _should_ work but the testing seems to make this point + * dubious (DIY testing requires setting CCR0 at 0x00000033). + * This is supposed to provide least surprise "DTE like" behavior. + * - if line rate is specified, clocks are assumed to be locally generated. + * A quartz must be available (on pin XTAL1). Modes 6b/7b are used. Choosing + * between these it automagically done according on the required frequency + * scaling. Of course some rounding may take place. + * - no high speed mode (40Mb/s). May be trivial to do but I don't have an + * appropriate external clocking device for testing. + * - no time-slot/clock mode 5: shameless lazyness. + * + * The clock signals wiring can be (is ?) manufacturer dependant. Good luck. + * + * BIG FAT WARNING: if the device isn't provided enough clocking signal, it + * won't pass the init sequence. For example, straight back-to-back DTE without + * external clock will fail when dscc4_open() (<- 'ifconfig hdlcx xxx') is + * called. + * + * Typos lurk in datasheet (missing divier in clock mode 7a figure 51 p.153 + * DS0 for example) + * + * Clock mode related bits of CCR0: + * +------------ TOE: output TxClk (0b/2b/3a/3b/6b/7a/7b only) + * | +---------- SSEL: sub-mode select 0 -> a, 1 -> b + * | | +-------- High Speed: say 0 + * | | | +-+-+-- Clock Mode: 0..7 + * | | | | | | + * -+-+-+-+-+-+-+-+ + * x|x|5|4|3|2|1|0| lower bits + * + * Division factor of BRR: k = (N+1)x2^M (total divider = 16xk in mode 6b) + * +-+-+-+------------------ M (0..15) + * | | | | +-+-+-+-+-+-- N (0..63) + * 0 0 0 0 | | | | 0 0 | | | | | | + * ...-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * f|e|d|c|b|a|9|8|7|6|5|4|3|2|1|0| lower bits + * + */ static int dscc4_set_clock(struct net_device *dev, u32 *bps, u32 *state) { struct dscc4_dev_priv *dpriv = dscc4_priv(dev); @@ -1123,13 +1262,13 @@ } brr = (m << 8) | n; divider = n << m; - if (!(*state & 0x00000001)) /* Clock mode 6b */ + if (!(*state & 0x00000001)) /* ?b mode mask => clock mode 6b */ divider <<= 4; *bps = xtal / divider; } else { /* * External clock - DTE - * "state" already reflects Clock mode 0a. + * "state" already reflects Clock mode 0a (CCR0 = 0xzzzzzz00). * Nothing more to be done */ brr = 0; @@ -1168,6 +1307,11 @@ if (!capable(CAP_NET_ADMIN)) return -EPERM; + if (dpriv->flags & FakeReset) { + printk(KERN_INFO "%s: please reset the device" + " before this command\n", dev->name); + return -EPERM; + } if (copy_from_user(&dpriv->settings, line, size)) return -EFAULT; ret = dscc4_set_iface(dpriv, dev); @@ -1221,12 +1365,12 @@ if (bps) { /* DCE */ printk(KERN_DEBUG "%s: generated RxClk (DCE)\n", dev->name); if (settings->clock_rate != bps) { - settings->clock_rate = bps; printk(KERN_DEBUG "%s: clock adjusted (%08d -> %08d)\n", - dev->name, dpriv->settings.clock_rate, bps); + dev->name, settings->clock_rate, bps); + settings->clock_rate = bps; } } else { /* DTE */ - state = 0x80001000; + state |= PowerUp | Vis; printk(KERN_DEBUG "%s: external RxClk (DTE)\n", dev->name); } scc_writel(state, dpriv, dev, CCR0); @@ -1332,6 +1476,8 @@ state = readl(ioaddr + GSTAR); if (!state) goto out; + if (debug > 3) + printk(KERN_DEBUG "%s: GSTAR = 0x%08x\n", DRV_NAME, state); writel(state, ioaddr + GSTAR); if (state & Arf) { @@ -1377,6 +1523,9 @@ cur = dpriv->iqtx_current%IRQ_RING_SIZE; state = dpriv->iqtx[cur]; if (!state) { + if (debug > 4) + printk(KERN_DEBUG "%s: Tx ISR = 0x%08x\n", dev->name, + state); if ((debug > 1) && (loop > 1)) printk(KERN_DEBUG "%s: Tx irq loop=%d\n", dev->name, loop); if (loop && netif_queue_stopped(dev)) @@ -1431,7 +1580,7 @@ * random freeze induced by null sized tx frames. */ tx_fd->data = tx_fd->next; - tx_fd->state = FrameEnd | TO_STATE(2*DUMMY_SKB_SIZE); + tx_fd->state = FrameEnd | TO_STATE_TX(2*DUMMY_SKB_SIZE); tx_fd->complete = 0x00000000; tx_fd->jiffies = 0; @@ -1463,9 +1612,19 @@ } if (state & Xpr) { u32 scc_addr, ring; + int i; + + /* + * - the busy condition happens (sometimes); + * - it doesn't seem to make the handler unreliable. + */ + for (i = 1; i; i <<= 1) { + if (!(scc_readl_star(dpriv, dev) & SccBusy)) + break; + } + if (!i) + printk(KERN_INFO "%s busy in irq\n", dev->name); - if (scc_readl_star(dpriv, dev) & SccBusy) - printk(KERN_ERR "%s busy. Fatal\n", dev->name); scc_addr = dev->base_addr + 0x0c*dpriv->dev_id; /* Keep this order: IDT before IDR */ if (dpriv->flags & NeedIDT) { @@ -1500,7 +1659,8 @@ goto try; } if (state & Cd) { - printk(KERN_INFO "%s: CD transition\n", dev->name); + if (debug > 0) + printk(KERN_INFO "%s: CD transition\n", dev->name); if (!(state &= ~Cd)) /* DEBUG */ goto try; } @@ -1542,6 +1702,9 @@ if (!(state & SccEvt)){ struct RxFD *rx_fd; + if (debug > 4) + printk(KERN_DEBUG "%s: Rx ISR = 0x%08x\n", dev->name, + state); state &= 0x00ffffff; if (state & Err) { /* Hold or reset */ printk(KERN_DEBUG "%s: Rx ERR\n", dev->name); @@ -1718,7 +1881,7 @@ skb->len = DUMMY_SKB_SIZE; memcpy(skb->data, version, strlen(version)%DUMMY_SKB_SIZE); - tx_fd->state = FrameEnd | TO_STATE(DUMMY_SKB_SIZE); + tx_fd->state = FrameEnd | TO_STATE_TX(DUMMY_SKB_SIZE); tx_fd->data = pci_map_single(dpriv->pci_priv->pdev, skb->data, DUMMY_SKB_SIZE, PCI_DMA_TODEVICE); dpriv->tx_skbuff[last] = skb; @@ -1749,7 +1912,7 @@ dpriv->tx_dirty = 0xffffffff; i = dpriv->tx_current = 0; do { - tx_fd->state = FrameEnd | TO_STATE(2*DUMMY_SKB_SIZE); + tx_fd->state = FrameEnd | TO_STATE_TX(2*DUMMY_SKB_SIZE); tx_fd->complete = 0x00000000; /* FIXME: NULL should be ok - to be tried */ tx_fd->data = dpriv->tx_fd_dma; @@ -1757,7 +1920,7 @@ (++i%TX_RING_SIZE)*sizeof(*tx_fd)); } while (i < TX_RING_SIZE); - if (dscc4_init_dummy_skb(dpriv) < 0) + if (dscc4_init_dummy_skb(dpriv) == NULL) goto err_free_dma_tx; memset(dpriv->rx_skbuff, 0, sizeof(struct sk_buff *)*RX_RING_SIZE); @@ -1767,7 +1930,7 @@ rx_fd->state1 = HiDesc; rx_fd->state2 = 0x00000000; rx_fd->end = 0xbabeface; - rx_fd->state1 |= TO_STATE(RX_MAX(HDLC_MAX_MRU)); + rx_fd->state1 |= TO_STATE_RX(HDLC_MAX_MRU); // FIXME: return value verifiee mais traitement suspect if (try_get_rx_skb(dpriv, dev) >= 0) dpriv->rx_dirty++; @@ -1785,7 +1948,7 @@ return -ENOMEM; } -static void __exit dscc4_remove_one(struct pci_dev *pdev) +static void __devexit dscc4_remove_one(struct pci_dev *pdev) { struct dscc4_pci_priv *ppriv; struct dscc4_dev_priv *root; @@ -1796,12 +1959,16 @@ root = ppriv->root; ioaddr = hdlc_to_dev(&root->hdlc)->base_addr; + + dscc4_pci_reset(pdev, ioaddr); + free_irq(pdev->irq, root); pci_free_consistent(pdev, IRQ_RING_SIZE*sizeof(u32), ppriv->iqcfg, ppriv->iqcfg_dma); for (i = 0; i < dev_per_card; i++) { struct dscc4_dev_priv *dpriv = root + i; + dscc4_release_ring(dpriv); pci_free_consistent(pdev, IRQ_RING_SIZE*sizeof(u32), dpriv->iqrx, dpriv->iqrx_dma); pci_free_consistent(pdev, IRQ_RING_SIZE*sizeof(u32), @@ -1843,6 +2010,7 @@ return 0; } +#ifndef MODULE static int __init dscc4_setup(char *str) { int *args[] = { &debug, &quartz, NULL }, **p = args; @@ -1853,8 +2021,9 @@ } __setup("dscc4.setup=", dscc4_setup); +#endif /* MODULE */ -static struct pci_device_id dscc4_pci_tbl[] __devinitdata = { +static struct pci_device_id dscc4_pci_tbl[] = { { PCI_VENDOR_ID_SIEMENS, PCI_DEVICE_ID_SIEMENS_DSCC4, PCI_ANY_ID, PCI_ANY_ID, }, { 0,} @@ -1865,7 +2034,7 @@ .name = DRV_NAME, .id_table = dscc4_pci_tbl, .probe = dscc4_init_one, - .remove = dscc4_remove_one, + .remove = __devexit_p(dscc4_remove_one), }; static int __init dscc4_init_module(void) Index: drivers/net/wan/farsync.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/farsync.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/farsync.c 22 Jul 2004 19:49:35 -0000 1.1 +++ drivers/net/wan/farsync.c 4 Aug 2004 01:29:24 -0000 1.2 @@ -764,7 +764,7 @@ /* Push upstream */ skb->mac.raw = skb->data; skb->dev = hdlc_to_dev ( &port->hdlc ); - skb->protocol = htons ( ETH_P_HDLC ); + skb->protocol = hdlc_type_trans(skb, skb->dev); netif_rx ( skb ); port_to_dev ( port )->last_rx = jiffies; Index: drivers/net/wan/hd6457x.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/hd6457x.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/hd6457x.c 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/hd6457x.c 4 Aug 2004 01:29:24 -0000 1.2 @@ -1,16 +1,29 @@ /* * Hitachi SCA HD64570 and HD64572 common driver for Linux * - * Copyright (C) 1998-2000 Krzysztof Halasa + * Copyright (C) 1998-2003 Krzysztof Halasa * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. * * Sources of information: * Hitachi HD64570 SCA User's Manual * Hitachi HD64572 SCA-II User's Manual + * + * We use the following SCA memory map: + * + * Packet buffer descriptor rings - starting from winbase or win0base: + * rx_ring_buffers * sizeof(pkt_desc) = logical channel #0 RX ring + * tx_ring_buffers * sizeof(pkt_desc) = logical channel #0 TX ring + * rx_ring_buffers * sizeof(pkt_desc) = logical channel #1 RX ring (if used) + * tx_ring_buffers * sizeof(pkt_desc) = logical channel #1 TX ring (if used) + * + * Packet data buffers - starting from winbase + buff_offset: + * rx_ring_buffers * HDLC_MAX_MRU = logical channel #0 RX buffers + * tx_ring_buffers * HDLC_MAX_MRU = logical channel #0 TX buffers + * rx_ring_buffers * HDLC_MAX_MRU = logical channel #0 RX buffers (if used) + * tx_ring_buffers * HDLC_MAX_MRU = logical channel #0 TX buffers (if used) */ #include @@ -22,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -42,8 +54,6 @@ #error Either hd64570.h or hd64572.h must be included #endif -static char sca_version[]="1.09"; - #define get_msci(port) (phy_node(port) ? MSCI1_OFFSET : MSCI0_OFFSET) #define get_dmac_rx(port) (phy_node(port) ? DMAC1RX_OFFSET : DMAC0RX_OFFSET) #define get_dmac_tx(port) (phy_node(port) ? DMAC1TX_OFFSET : DMAC0TX_OFFSET) @@ -116,24 +126,35 @@ -static inline u8 next_desc(port_t *port, u8 desc) +static inline u16 next_desc(port_t *port, u16 desc, int transmit) +{ + return (desc + 1) % (transmit ? port_to_card(port)->tx_ring_buffers + : port_to_card(port)->rx_ring_buffers); +} + + + +static inline u16 desc_abs_number(port_t *port, u16 desc, int transmit) { - return (desc + 1) % port_to_card(port)->ring_buffers; + u16 rx_buffs = port_to_card(port)->rx_ring_buffers; + u16 tx_buffs = port_to_card(port)->tx_ring_buffers; + + desc %= (transmit ? tx_buffs : rx_buffs); // called with "X + 1" etc. + return log_node(port) * (rx_buffs + tx_buffs) + + transmit * rx_buffs + desc; } -static inline u16 desc_offset(port_t *port, u8 desc, u8 transmit) +static inline u16 desc_offset(port_t *port, u16 desc, int transmit) { /* Descriptor offset always fits in 16 bytes */ - u8 buffs = port_to_card(port)->ring_buffers; - return ((log_node(port) * 2 + transmit) * buffs + (desc % buffs)) * - sizeof(pkt_desc); + return desc_abs_number(port, desc, transmit) * sizeof(pkt_desc); } -static inline pkt_desc* desc_address(port_t *port, u8 desc, u8 transmit) +static inline pkt_desc* desc_address(port_t *port, u16 desc, int transmit) { #ifdef PAGE0_ALWAYS_MAPPED return (pkt_desc*)(win0base(port_to_card(port)) @@ -146,12 +167,10 @@ -static inline u32 buffer_offset(port_t *port, u8 desc, u8 transmit) +static inline u32 buffer_offset(port_t *port, u16 desc, int transmit) { - u8 buffs = port_to_card(port)->ring_buffers; return port_to_card(port)->buff_offset + - ((log_node(port) * 2 + transmit) * buffs + (desc % buffs)) * - (u32)HDLC_MAX_MRU; + desc_abs_number(port, desc, transmit) * (u32)HDLC_MAX_MRU; } @@ -159,8 +178,7 @@ static void sca_init_sync_port(port_t *port) { card_t *card = port_to_card(port); - u8 transmit, i; - u16 dmac, buffs = card->ring_buffers; + int transmit, i; port->rxin = 0; port->txin = 0; @@ -171,6 +189,10 @@ #endif for (transmit = 0; transmit < 2; transmit++) { + u16 dmac = transmit ? get_dmac_tx(port) : get_dmac_rx(port); + u16 buffs = transmit ? card->tx_ring_buffers + : card->rx_ring_buffers; + for (i = 0; i < buffs; i++) { pkt_desc* desc = desc_address(port, i, transmit); u16 chain_off = desc_offset(port, i + 1, transmit); @@ -182,7 +204,6 @@ writeb(0, &desc->stat); } - dmac = transmit ? get_dmac_tx(port) : get_dmac_rx(port); /* DMA disable - to halt state */ sca_out(0, transmit ? DSR_TX(phy_node(port)) : DSR_RX(phy_node(port)), card); @@ -233,9 +254,6 @@ card_t* card = port_to_card(port); u8 stat = sca_in(msci + ST1, card); /* read MSCI ST1 status */ - /* printk(KERN_DEBUG "MSCI INT: ST1=%02X ILAR=%02X\n", - stat, sca_in(ILAR, card)); */ - /* Reset MSCI TX underrun status bit */ sca_out(stat & ST1_UDRN, msci + ST1, card); @@ -247,7 +265,7 @@ -static inline void sca_rx(card_t *card, port_t *port, pkt_desc *desc, u8 rxin) +static inline void sca_rx(card_t *card, port_t *port, pkt_desc *desc, u16 rxin) { struct sk_buff *skb; u16 len; @@ -285,7 +303,7 @@ openwin(card, 0); #endif skb_put(skb, len); -#ifdef CONFIG_HDLC_DEBUG_PKT +#ifdef DEBUG_PKT printk(KERN_DEBUG "%s RX(%i):", hdlc_to_name(&port->hdlc), skb->len); debug_frame(skb); #endif @@ -294,7 +312,7 @@ skb->mac.raw = skb->data; skb->dev = hdlc_to_dev(&port->hdlc); skb->dev->last_rx = jiffies; - skb->protocol = htons(ETH_P_HDLC); + skb->protocol = hdlc_type_trans(skb, hdlc_to_dev(&port->hdlc)); netif_rx(skb); } @@ -341,7 +359,7 @@ /* Set new error descriptor address */ sca_outa(desc_off, dmac + EDAL, card); - port->rxin = next_desc(port, port->rxin); + port->rxin = next_desc(port, port->rxin, 0); } /* make sure RX DMA is enabled */ @@ -377,8 +395,7 @@ port->hdlc.stats.tx_packets++; port->hdlc.stats.tx_bytes += readw(&desc->len); writeb(0, &desc->stat); /* Free descriptor */ - port->txlast = (port->txlast + 1) % - port_to_card(port)->ring_buffers; + port->txlast = next_desc(port, port->txlast, 1); } netif_wake_queue(hdlc_to_dev(&port->hdlc)); @@ -390,8 +407,6 @@ static void sca_intr(int irq, void* dev_id, struct pt_regs *regs) { card_t *card = dev_id; -/* Maximum events to handle at each interrupt - should I increase it? */ - int boguscnt = 4; int i; u8 stat; @@ -412,23 +427,12 @@ if (stat & SCA_INTR_DMAC_TX(i)) sca_tx_intr(port); } - - if (--boguscnt < 0) { -#if 0 - printk(KERN_ERR "%s: too much work at " - "interrupt\n", - hdlc_to_name(&port->hdlc)); -#endif - goto exit; - } } } - exit: #ifndef ALL_PAGES_ALWAYS_MAPPED openwin(card, page); /* Restore original page */ #endif - return; } @@ -436,7 +440,7 @@ static void sca_set_port(port_t *port) { card_t* card = port_to_card(port); - u8 msci = get_msci(port); + u16 msci = get_msci(port); u8 md2 = sca_in(msci + MD2, card); unsigned int tmc, br = 10, brv = 1024; @@ -496,7 +500,7 @@ { port_t *port = hdlc_to_port(hdlc); card_t* card = port_to_card(port); - u8 msci = get_msci(port); + u16 msci = get_msci(port); u8 md0, md2; switch(port->encoding) { @@ -517,7 +521,7 @@ case PARITY_CRC16_PR0_CCITT: md0 = MD0_HDLC | MD0_CRC_ITU_0; break; #else case PARITY_CRC32_PR1_CCITT: md0 = MD0_HDLC | MD0_CRC_ITU32; break; -#endif +#endif case PARITY_CRC16_PR1_CCITT: md0 = MD0_HDLC | MD0_CRC_ITU; break; default: md0 = MD0_HDLC | MD0_CRC_NONE; } @@ -549,7 +553,7 @@ #endif /* We're using the following interrupts: - - TXINT (DMAC completed all transmisions, underflow or CTS change) + - TXINT (DMAC completed all transmisions, underrun or DCD change) - all DMA interrupts */ @@ -566,7 +570,7 @@ /* MSCI TX INT IRQ enable */ sca_outl(IE0_TXINT | IE0_UDRN, msci + IE0, card); /* DMA & MSCI IRQ enable */ - sca_outl(sca_in(IER0, card) | + sca_outl(sca_inl(IER0, card) | (phy_node(port) ? 0x02006600 : 0x00020066), IER0, card); #endif @@ -614,7 +618,7 @@ parity != PARITY_CRC16_PR0_CCITT && #else parity != PARITY_CRC32_PR1_CCITT && -#endif +#endif parity != PARITY_CRC16_PR1_CCITT) return -EINVAL; @@ -625,7 +629,7 @@ -#ifdef CONFIG_HDLC_DEBUG_RINGS +#ifdef DEBUG_RINGS static void sca_dump_rings(hdlc_device *hdlc) { port_t *port = hdlc_to_port(hdlc); @@ -640,31 +644,26 @@ openwin(card, 0); #endif - printk(KERN_ERR "RX ring: CDA=%u EDA=%u DSR=%02X in=%u " - "%sactive", + printk(KERN_DEBUG "RX ring: CDA=%u EDA=%u DSR=%02X in=%u %sactive", sca_ina(get_dmac_rx(port) + CDAL, card), sca_ina(get_dmac_rx(port) + EDAL, card), - sca_in(DSR_RX(phy_node(port)), card), - port->rxin, + sca_in(DSR_RX(phy_node(port)), card), port->rxin, sca_in(DSR_RX(phy_node(port)), card) & DSR_DE?"":"in"); - for (cnt = 0; cntring_buffers; cnt++) - printk(" %02X", - readb(&(desc_address(port, cnt, 0)->stat))); + for (cnt = 0; cnt < port_to_card(port)->rx_ring_buffers; cnt++) + printk(" %02X", readb(&(desc_address(port, cnt, 0)->stat))); - printk("\n" KERN_ERR "TX ring: CDA=%u EDA=%u DSR=%02X in=%u " + printk("\n" KERN_DEBUG "TX ring: CDA=%u EDA=%u DSR=%02X in=%u " "last=%u %sactive", sca_ina(get_dmac_tx(port) + CDAL, card), sca_ina(get_dmac_tx(port) + EDAL, card), - sca_in(DSR_TX(phy_node(port)), card), port->txin, - port->txlast, + sca_in(DSR_TX(phy_node(port)), card), port->txin, port->txlast, sca_in(DSR_TX(phy_node(port)), card) & DSR_DE ? "" : "in"); - for (cnt = 0; cntring_buffers; cnt++) - printk(" %02X", - readb(&(desc_address(port, cnt, 1)->stat))); + for (cnt = 0; cnt < port_to_card(port)->tx_ring_buffers; cnt++) + printk(" %02X", readb(&(desc_address(port, cnt, 1)->stat))); printk("\n"); - printk(KERN_ERR "MSCI: MD: %02x %02x %02x, " + printk(KERN_DEBUG "MSCI: MD: %02x %02x %02x, " "ST: %02x %02x %02x %02x" #ifdef __HD64572_H " %02x" @@ -685,14 +684,14 @@ sca_in(get_msci(port) + CST1, card)); #ifdef __HD64572_H - printk(KERN_ERR "ILAR: %02x\n", sca_in(ILAR, card)); + printk(KERN_DEBUG "ILAR: %02x\n", sca_in(ILAR, card)); #endif #if !defined(PAGE0_ALWAYS_MAPPED) && !defined(ALL_PAGES_ALWAYS_MAPPED) openwin(card, page); /* Restore original page */ #endif } -#endif /* CONFIG_HDLC_DEBUG_RINGS */ +#endif /* DEBUG_RINGS */ @@ -713,7 +712,7 @@ desc = desc_address(port, port->txin + 1, 1); if (readb(&desc->stat)) { /* allow 1 packet gap */ /* should never happen - previous xmit should stop queue */ -#ifdef CONFIG_HDLC_DEBUG_PKT +#ifdef DEBUG_PKT printk(KERN_DEBUG "%s: transmitter buffer full\n", dev->name); #endif netif_stop_queue(dev); @@ -721,7 +720,7 @@ return 1; /* request packet to be queued */ } -#ifdef CONFIG_HDLC_DEBUG_PKT +#ifdef DEBUG_PKT printk(KERN_DEBUG "%s TX(%i):", hdlc_to_name(hdlc), skb->len); debug_frame(skb); #endif @@ -751,7 +750,7 @@ writeb(ST_TX_EOM, &desc->stat); dev->trans_start = jiffies; - port->txin = next_desc(port, port->txin); + port->txin = next_desc(port, port->txin, 1); sca_outa(desc_offset(port, port->txin, 1), get_dmac_tx(port) + EDAL, card); @@ -768,7 +767,49 @@ } -static void sca_init(card_t *card, int wait_states) + +#ifdef NEED_DETECT_RAM +static u32 __devinit sca_detect_ram(card_t *card, u8 *rambase, u32 ramsize) +{ + /* Round RAM size to 32 bits, fill from end to start */ + u32 i = ramsize &= ~3; + +#ifndef ALL_PAGES_ALWAYS_MAPPED + u32 size = winsize(card); + + openwin(card, (i - 4) / size); /* select last window */ +#endif + do { + i -= 4; +#ifndef ALL_PAGES_ALWAYS_MAPPED + if ((i + 4) % size == 0) + openwin(card, i / size); + writel(i ^ 0x12345678, rambase + i % size); +#else + writel(i ^ 0x12345678, rambase + i); +#endif + }while (i > 0); + + for (i = 0; i < ramsize ; i += 4) { +#ifndef ALL_PAGES_ALWAYS_MAPPED + if (i % size == 0) + openwin(card, i / size); + + if (readl(rambase + i % size) != (i ^ 0x12345678)) + break; +#else + if (readl(rambase + i) != (i ^ 0x12345678)) + break; +#endif + } + + return i; +} +#endif /* NEED_DETECT_RAM */ + + + +static void __devinit sca_init(card_t *card, int wait_states) { sca_out(wait_states, WCRL, card); /* Wait Control */ sca_out(wait_states, WCRM, card); Index: drivers/net/wan/hdlc_cisco.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/hdlc_cisco.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/hdlc_cisco.c 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/hdlc_cisco.c 4 Aug 2004 01:29:24 -0000 1.2 @@ -2,15 +2,13 @@ * Generic HDLC support routines for Linux * Cisco HDLC support * - * Copyright (C) 2000 - 2001 Krzysztof Halasa + * Copyright (C) 2000 - 2003 Krzysztof Halasa * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. */ -#include #include #include #include @@ -25,6 +23,7 @@ #include #include +#undef DEBUG_HARD_HEADER #define CISCO_MULTICAST 0x8F /* Cisco multicast address */ #define CISCO_UNICAST 0x0F /* Cisco unicast address */ @@ -40,7 +39,7 @@ unsigned int len) { hdlc_header *data; -#ifdef CONFIG_HDLC_DEBUG_HARD_HEADER +#ifdef DEBUG_HARD_HEADER printk(KERN_DEBUG "%s: cisco_hard_header called\n", dev->name); #endif @@ -80,17 +79,43 @@ data->par1 = htonl(par1); data->par2 = htonl(par2); data->rel = 0xFFFF; - data->time = htonl(jiffies * 1000 / HZ); + /* we will need do_div here if 1000 % HZ != 0 */ + data->time = htonl(jiffies * (1000 / HZ)); skb_put(skb, sizeof(cisco_packet)); skb->priority = TC_PRIO_CONTROL; skb->dev = hdlc_to_dev(hdlc); + skb->nh.raw = skb->data; dev_queue_xmit(skb); } +static unsigned short cisco_type_trans(struct sk_buff *skb, + struct net_device *dev) +{ + hdlc_header *data = (hdlc_header*)skb->data; + + if (skb->len < sizeof(hdlc_header)) + return __constant_htons(ETH_P_HDLC); + + if (data->address != CISCO_MULTICAST && + data->address != CISCO_UNICAST) + return __constant_htons(ETH_P_HDLC); + + switch(data->protocol) { + case __constant_htons(ETH_P_IP): + case __constant_htons(ETH_P_IPX): + case __constant_htons(ETH_P_IPV6): + skb_pull(skb, sizeof(hdlc_header)); + return data->protocol; + default: + return __constant_htons(ETH_P_HDLC); + } +} + + static void cisco_rx(struct sk_buff *skb) { hdlc_device *hdlc = dev_to_hdlc(skb->dev); @@ -109,14 +134,6 @@ skb_pull(skb, sizeof(hdlc_header)); switch(ntohs(data->protocol)) { - case ETH_P_IP: - case ETH_P_IPX: - case ETH_P_IPV6: - skb->protocol = data->protocol; - skb->dev = hdlc_to_dev(hdlc); - netif_rx(skb); - return; - case CISCO_SYS_INFO: /* Packet is not needed, drop it. */ dev_kfree_skb_any(skb); @@ -165,7 +182,7 @@ case CISCO_KEEPALIVE_REQ: hdlc->state.cisco.rxseq = ntohl(cisco_data->par1); - if (ntohl(cisco_data->par2) == hdlc->state.cisco.txseq) { + if (ntohl(cisco_data->par2)==hdlc->state.cisco.txseq) { hdlc->state.cisco.last_poll = jiffies; if (!hdlc->state.cisco.up) { u32 sec, min, hrs, days; @@ -202,8 +219,7 @@ { hdlc_device *hdlc = (hdlc_device*)arg; - if (hdlc->state.cisco.up && - jiffies - hdlc->state.cisco.last_poll >= + if (hdlc->state.cisco.up && jiffies - hdlc->state.cisco.last_poll >= hdlc->state.cisco.settings.timeout * HZ) { hdlc->state.cisco.up = 0; printk(KERN_INFO "%s: Link down\n", hdlc_to_name(hdlc)); @@ -264,10 +280,10 @@ return 0; case IF_PROTO_CISCO: - if(!capable(CAP_NET_ADMIN)) + if (!capable(CAP_NET_ADMIN)) return -EPERM; - if(dev->flags & IFF_UP) + if (dev->flags & IFF_UP) return -EBUSY; if (copy_from_user(&new_settings, cisco_s, size)) @@ -288,6 +304,7 @@ hdlc->open = cisco_open; hdlc->stop = cisco_close; hdlc->netif_rx = cisco_rx; + hdlc->type_trans = cisco_type_trans; hdlc->proto = IF_PROTO_CISCO; dev->hard_start_xmit = hdlc->xmit; dev->hard_header = cisco_hard_header; Index: drivers/net/wan/hdlc_fr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/hdlc_fr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/hdlc_fr.c 22 Jul 2004 19:49:35 -0000 1.1 +++ drivers/net/wan/hdlc_fr.c 4 Aug 2004 01:29:24 -0000 1.2 @@ -2,15 +2,23 @@ * Generic HDLC support routines for Linux * Frame Relay support * - * Copyright (C) 1999 - 2001 Krzysztof Halasa + * Copyright (C) 1999 - 2003 Krzysztof Halasa * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + * + + Theory of PVC state in DCE mode: + + (exist,new) -> 0,0 when "PVC create" or if "link unreliable" + 0,x -> 1,1 if "link reliable" when sending FULL STATUS + 1,1 -> 1,0 if received FULL STATUS ACK + + (active) -> 0 when "ifconfig PVC down" or "link unreliable" or "PVC create" + -> 1 when "PVC up" and (exist,new) = 1,0 +*/ -#include #include #include #include @@ -20,19 +28,106 @@ #include #include #include +#include #include #include #include +#include #include +#undef DEBUG_PKT +#undef DEBUG_ECN + +#define MAXLEN_LMISTAT 20 /* max size of status enquiry frame */ + +#define PVC_STATE_NEW 0x01 +#define PVC_STATE_ACTIVE 0x02 +#define PVC_STATE_FECN 0x08 /* FECN condition */ +#define PVC_STATE_BECN 0x10 /* BECN condition */ + + +#define FR_UI 0x03 +#define FR_PAD 0x00 + +#define NLPID_IP 0xCC +#define NLPID_IPV6 0x8E +#define NLPID_SNAP 0x80 +#define NLPID_PAD 0x00 +#define NLPID_Q933 0x08 + + +#define LMI_DLCI 0 /* LMI DLCI */ +#define LMI_PROTO 0x08 +#define LMI_CALLREF 0x00 /* Call Reference */ +#define LMI_ANSI_LOCKSHIFT 0x95 /* ANSI lockshift */ +#define LMI_REPTYPE 1 /* report type */ +#define LMI_CCITT_REPTYPE 0x51 +#define LMI_ALIVE 3 /* keep alive */ +#define LMI_CCITT_ALIVE 0x53 +#define LMI_PVCSTAT 7 /* pvc status */ +#define LMI_CCITT_PVCSTAT 0x57 +#define LMI_FULLREP 0 /* full report */ +#define LMI_INTEGRITY 1 /* link integrity report */ +#define LMI_SINGLE 2 /* single pvc report */ +#define LMI_STATUS_ENQUIRY 0x75 +#define LMI_STATUS 0x7D /* reply */ + +#define LMI_REPT_LEN 1 /* report type element length */ +#define LMI_INTEG_LEN 2 /* link integrity element length */ + +#define LMI_LENGTH 13 /* standard LMI frame length */ +#define LMI_ANSI_LENGTH 14 + + +typedef struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned ea1: 1; + unsigned cr: 1; + unsigned dlcih: 6; + + unsigned ea2: 1; + unsigned de: 1; + unsigned becn: 1; + unsigned fecn: 1; + unsigned dlcil: 4; +#else + unsigned dlcih: 6; + unsigned cr: 1; + unsigned ea1: 1; + + unsigned dlcil: 4; + unsigned fecn: 1; + unsigned becn: 1; + unsigned de: 1; + unsigned ea2: 1; +#endif +}__attribute__ ((packed)) fr_hdr; + + +static inline u16 q922_to_dlci(u8 *hdr) +{ + return ((hdr[0] & 0xFC) << 2) | ((hdr[1] & 0xF0) >> 4); +} + + + +static inline void dlci_to_q922(u8 *hdr, u16 dlci) +{ + hdr[0] = (dlci >> 2) & 0xFC; + hdr[1] = ((dlci << 4) & 0xF0) | 0x01; +} + + -__inline__ pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci) +static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci) { - pvc_device *pvc=hdlc->state.fr.first_pvc; - + pvc_device *pvc = hdlc->state.fr.first_pvc; + while (pvc) { - if (netdev_dlci(&pvc->netdev) == dlci) + if (pvc->dlci == dlci) return pvc; + if (pvc->dlci > dlci) + return NULL; /* the listed is sorted */ pvc = pvc->next; } @@ -40,22 +135,75 @@ } +static inline pvc_device* add_pvc(hdlc_device *hdlc, u16 dlci) +{ + pvc_device *pvc, **pvc_p = &hdlc->state.fr.first_pvc; + + while (*pvc_p) { + if ((*pvc_p)->dlci == dlci) + return *pvc_p; + if ((*pvc_p)->dlci > dlci) + break; /* the list is sorted */ + pvc_p = &(*pvc_p)->next; + } + + pvc = kmalloc(sizeof(pvc_device), GFP_ATOMIC); + if (!pvc) + return NULL; + + memset(pvc, 0, sizeof(pvc_device)); + pvc->dlci = dlci; + pvc->master = hdlc; + pvc->next = *pvc_p; /* Put it in the chain */ + *pvc_p = pvc; + return pvc; +} + + +static inline int pvc_is_used(pvc_device *pvc) +{ + return pvc->main != NULL || pvc->ether != NULL; +} + + +static inline void delete_unused_pvcs(hdlc_device *hdlc) +{ + pvc_device **pvc_p = &hdlc->state.fr.first_pvc; + + while (*pvc_p) { + if (!pvc_is_used(*pvc_p)) { + pvc_device *pvc = *pvc_p; + *pvc_p = pvc->next; + kfree(pvc); + continue; + } + pvc_p = &(*pvc_p)->next; + } +} + + +static inline struct net_device** get_dev_p(pvc_device *pvc, int type) +{ + if (type == ARPHRD_ETHER) + return &pvc->ether; + else + return &pvc->main; +} + -__inline__ u16 status_to_dlci(hdlc_device *hdlc, u8 *status, - int *active, int *new) +static inline u16 status_to_dlci(u8 *status, int *active, int *new) { - *new = (status[2] & 0x08); - *active = (!*new && (status[2] & 0x02)); + *new = (status[2] & 0x08) ? 1 : 0; + *active = (status[2] & 0x02) ? 1 : 0; - return ((status[0] & 0x3F)<<4) | ((status[1] & 0x78)>>3); + return ((status[0] & 0x3F) << 4) | ((status[1] & 0x78) >> 3); } -__inline__ void dlci_to_status(hdlc_device *hdlc, u16 dlci, u8 *status, - int active, int new) +static inline void dlci_to_status(u16 dlci, u8 *status, int active, int new) { - status[0] = (dlci>>4) & 0x3F; - status[1] = ((dlci<<3) & 0x78) | 0x80; + status[0] = (dlci >> 4) & 0x3F; + status[1] = ((dlci << 3) & 0x78) | 0x80; status[2] = 0x80; if (new) @@ -66,37 +214,50 @@ -static int fr_hard_header(struct sk_buff *skb, struct net_device *dev, - u16 type, void *daddr, void *saddr, unsigned int len) +static int fr_hard_header(struct sk_buff **skb_p, u16 dlci) { u16 head_len; + struct sk_buff *skb = *skb_p; - if (!daddr) - daddr = dev->broadcast; - -#ifdef CONFIG_HDLC_DEBUG_HARD_HEADER - printk(KERN_DEBUG "%s: fr_hard_header called\n", dev->name); -#endif - - switch(type) { - case ETH_P_IP: + switch (skb->protocol) { + case __constant_ntohs(ETH_P_IP): head_len = 4; skb_push(skb, head_len); skb->data[3] = NLPID_IP; break; - case ETH_P_IPV6: + case __constant_ntohs(ETH_P_IPV6): head_len = 4; skb_push(skb, head_len); skb->data[3] = NLPID_IPV6; break; - case LMI_PROTO: + case __constant_ntohs(LMI_PROTO): head_len = 4; skb_push(skb, head_len); skb->data[3] = LMI_PROTO; break; + case __constant_ntohs(ETH_P_802_3): + head_len = 10; + if (skb_headroom(skb) < head_len) { + struct sk_buff *skb2 = skb_realloc_headroom(skb, + head_len); + if (!skb2) + return -ENOBUFS; + dev_kfree_skb(skb); + skb = *skb_p = skb2; + } + skb_push(skb, head_len); + skb->data[3] = FR_PAD; + skb->data[4] = NLPID_SNAP; + skb->data[5] = FR_PAD; + skb->data[6] = 0x80; + skb->data[7] = 0xC2; + skb->data[8] = 0x00; + skb->data[9] = 0x07; /* bridged Ethernet frame w/out FCS */ + break; + default: head_len = 10; skb_push(skb, head_len); @@ -105,14 +266,12 @@ skb->data[5] = FR_PAD; skb->data[6] = FR_PAD; skb->data[7] = FR_PAD; - skb->data[8] = type>>8; - skb->data[9] = (u8)type; + *(u16*)(skb->data + 8) = skb->protocol; } - memcpy(skb->data, daddr, 2); + dlci_to_q922(skb->data, dlci); skb->data[2] = FR_UI; - - return head_len; + return 0; } @@ -124,13 +283,12 @@ if ((hdlc_to_dev(pvc->master)->flags & IFF_UP) == 0) return -EIO; /* Master must be UP in order to activate PVC */ - if (pvc->master->state.fr.settings.lmi != LMI_NONE) - pvc->state.active = 0; - else - pvc->state.active = 1; + if (pvc->open_count++ == 0) { + if (pvc->master->state.fr.settings.lmi == LMI_NONE) + pvc->state.active = 1; - pvc->state.new = 0; - pvc->master->state.fr.changed = 1; + pvc->master->state.fr.dce_changed = 1; + } return 0; } @@ -139,38 +297,94 @@ static int pvc_close(struct net_device *dev) { pvc_device *pvc = dev_to_pvc(dev); - pvc->state.active = pvc->state.new = 0; - pvc->master->state.fr.changed = 1; + + if (--pvc->open_count == 0) { + if (pvc->master->state.fr.settings.lmi == LMI_NONE) + pvc->state.active = 0; + + if (pvc->master->state.fr.settings.dce) { + pvc->master->state.fr.dce_changed = 1; + pvc->state.active = 0; + } + } return 0; } -static int pvc_xmit(struct sk_buff *skb, struct net_device *dev) +int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { pvc_device *pvc = dev_to_pvc(dev); + fr_proto_pvc_info info; - if (pvc->state.active) { - skb->dev = hdlc_to_dev(pvc->master); - pvc->stats.tx_bytes += skb->len; - pvc->stats.tx_packets++; - if (pvc->state.fecn) - pvc->stats.tx_compressed++; /* TX Congestion counter */ - dev_queue_xmit(skb); - } else { - pvc->stats.tx_dropped++; - dev_kfree_skb(skb); + if (ifr->ifr_settings.type == IF_GET_PROTO) { + if (dev->type == ARPHRD_ETHER) + ifr->ifr_settings.type = IF_PROTO_FR_ETH_PVC; + else + ifr->ifr_settings.type = IF_PROTO_FR_PVC; + + if (ifr->ifr_settings.size < sizeof(info)) { + /* data size wanted */ + ifr->ifr_settings.size = sizeof(info); + return -ENOBUFS; + } + + info.dlci = pvc->dlci; + memcpy(info.master, hdlc_to_name(pvc->master), IFNAMSIZ); + if (copy_to_user(ifr->ifr_settings.ifs_ifsu.fr_pvc_info, + &info, sizeof(info))) + return -EFAULT; + return 0; } - return 0; + return -EINVAL; +} + + +static inline struct net_device_stats *pvc_get_stats(struct net_device *dev) +{ + return (struct net_device_stats *) + ((char *)dev + sizeof(struct net_device)); } -static struct net_device_stats *pvc_get_stats(struct net_device *dev) +static int pvc_xmit(struct sk_buff *skb, struct net_device *dev) { pvc_device *pvc = dev_to_pvc(dev); - return &pvc->stats; + struct net_device_stats *stats = pvc_get_stats(dev); + + if (pvc->state.active) { + if (dev->type == ARPHRD_ETHER) { + int pad = ETH_ZLEN - skb->len; + if (pad > 0) { /* Pad the frame with zeros */ + int len = skb->len; + if (skb_tailroom(skb) < pad) + if (pskb_expand_head(skb, 0, pad, + GFP_ATOMIC)) { + stats->tx_dropped++; + dev_kfree_skb(skb); + return 0; + } + skb_put(skb, pad); + memset(skb->data + len, 0, pad); + } + skb->protocol = __constant_htons(ETH_P_802_3); + } + if (!fr_hard_header(&skb, pvc->dlci)) { + stats->tx_bytes += skb->len; + stats->tx_packets++; + if (pvc->state.fecn) /* TX Congestion counter */ + stats->tx_compressed++; + skb->dev = hdlc_to_dev(pvc->master); + dev_queue_xmit(skb); + return 0; + } + } + + stats->tx_dropped++; + dev_kfree_skb(skb); + return 0; } @@ -187,9 +401,15 @@ static inline void fr_log_dlci_active(pvc_device *pvc) { - printk(KERN_INFO "%s: %sactive%s\n", pvc_to_name(pvc), - pvc->state.active ? "" : "in", - pvc->state.new ? " new" : ""); + printk(KERN_INFO "%s: DLCI %d [%s%s%s]%s %s\n", + hdlc_to_name(pvc->master), + pvc->dlci, + pvc->main ? pvc->main->name : "", + pvc->main && pvc->ether ? " " : "", + pvc->ether ? pvc->ether->name : "", + pvc->state.new ? " new" : "", + !pvc->state.exist ? "deleted" : + pvc->state.active ? "active" : "inactive"); } @@ -213,8 +433,8 @@ int i = 0; if (hdlc->state.fr.settings.dce && fullrep) { - len += hdlc->state.fr.pvc_count * (2 + stat_len); - if (len > HDLC_MAX_MTU) { + len += hdlc->state.fr.dce_pvc_count * (2 + stat_len); + if (len > HDLC_MAX_MRU) { printk(KERN_WARNING "%s: Too many PVCs while sending " "LMI full report\n", hdlc_to_name(hdlc)); return; @@ -224,12 +444,13 @@ skb = dev_alloc_skb(len); if (!skb) { printk(KERN_WARNING "%s: Memory squeeze on fr_lmi_send()\n", - hdlc_to_name(hdlc)); + hdlc_to_name(hdlc)); return; } memset(skb->data, 0, len); skb_reserve(skb, 4); - fr_hard_header(skb, hdlc_to_dev(hdlc), LMI_PROTO, NULL, NULL, 0); + skb->protocol = __constant_htons(LMI_PROTO); + fr_hard_header(&skb, LMI_DLCI); data = skb->tail; data[i++] = LMI_CALLREF; data[i++] = hdlc->state.fr.settings.dce @@ -253,16 +474,20 @@ ? LMI_CCITT_PVCSTAT : LMI_PVCSTAT; data[i++] = stat_len; - if (hdlc->state.fr.reliable && - (pvc->netdev.flags & IFF_UP) && - !pvc->state.active && - !pvc->state.new) { - pvc->state.new = 1; + /* LMI start/restart */ + if (hdlc->state.fr.reliable && !pvc->state.exist) { + pvc->state.exist = pvc->state.new = 1; + fr_log_dlci_active(pvc); + } + + /* ifconfig PVC up */ + if (pvc->open_count && !pvc->state.active && + pvc->state.exist && !pvc->state.new) { + pvc->state.active = 1; fr_log_dlci_active(pvc); } - dlci_to_status(hdlc, netdev_dlci(&pvc->netdev), - data + i, + dlci_to_status(pvc->dlci, data + i, pvc->state.active, pvc->state.new); i += stat_len; pvc = pvc->next; @@ -272,6 +497,7 @@ skb_put(skb, i); skb->priority = TC_PRIO_CONTROL; skb->dev = hdlc_to_dev(hdlc); + skb->nh.raw = skb->data; dev_queue_xmit(skb); } @@ -312,10 +538,11 @@ if (reliable) { hdlc->state.fr.n391cnt = 0; /* Request full status */ - hdlc->state.fr.changed = 1; + hdlc->state.fr.dce_changed = 1; } else { while (pvc) { /* Deactivate all PVCs */ - pvc->state.new = pvc->state.active = 0; + pvc->state.exist = 0; + pvc->state.active = pvc->state.new = 0; pvc = pvc->next; } } @@ -346,7 +573,7 @@ { int stat_len; pvc_device *pvc; - int reptype = -1, error; + int reptype = -1, error, no_ram; u8 rxseq, txseq; int i; @@ -420,20 +647,18 @@ while (pvc) { if (pvc->state.new) { pvc->state.new = 0; - pvc->state.active = 1; - fr_log_dlci_active(pvc); /* Tell DTE that new PVC is now active */ - hdlc->state.fr.changed = 1; + hdlc->state.fr.dce_changed = 1; } pvc = pvc->next; } } - if (hdlc->state.fr.changed) { + if (hdlc->state.fr.dce_changed) { reptype = LMI_FULLREP; hdlc->state.fr.fullrep_sent = 1; - hdlc->state.fr.changed = 0; + hdlc->state.fr.dce_changed = 0; } fr_lmi_send(hdlc, reptype == LMI_FULLREP ? 1 : 0); @@ -449,13 +674,14 @@ pvc = hdlc->state.fr.first_pvc; while (pvc) { - pvc->state.deleted = pvc->state.active; /* mark active PVCs */ + pvc->state.deleted = 1; pvc = pvc->next; } + no_ram = 0; while (skb->len >= i + 2 + stat_len) { u16 dlci; - int active, new; + unsigned int active, new; if (skb->data[i] != ((hdlc->state.fr.settings.lmi == LMI_CCITT) ? LMI_CCITT_PVCSTAT : LMI_PVCSTAT)) { @@ -472,21 +698,27 @@ } i++; - dlci = status_to_dlci(hdlc, skb->data + i, &active, &new); - pvc = find_pvc(hdlc, dlci); + dlci = status_to_dlci(skb->data + i, &active, &new); + + pvc = add_pvc(hdlc, dlci); + + if (!pvc && !no_ram) { + printk(KERN_WARNING + "%s: Memory squeeze on fr_lmi_recv()\n", + hdlc_to_name(hdlc)); + no_ram = 1; + } - active |= new; if (pvc) { - if (active && !pvc->state.active && - (pvc->netdev.flags & IFF_UP)) { + pvc->state.exist = 1; + pvc->state.deleted = 0; + if (active != pvc->state.active || + new != pvc->state.new) { + pvc->state.new = new; pvc->state.active = active; fr_log_dlci_active(pvc); } - pvc->state.deleted = 0; } - else if (new) - printk(KERN_INFO "%s: new PVC available, DLCI=%u\n", - hdlc_to_name(hdlc), dlci); i += stat_len; } @@ -494,10 +726,10 @@ pvc = hdlc->state.fr.first_pvc; while (pvc) { - if (pvc->state.deleted) { + if (pvc->state.deleted && pvc->state.exist) { pvc->state.active = pvc->state.new = 0; + pvc->state.exist = 0; fr_log_dlci_active(pvc); - pvc->state.deleted = 0; } pvc = pvc->next; } @@ -517,8 +749,9 @@ u8 *data = skb->data; u16 dlci; pvc_device *pvc; + struct net_device *dev = NULL; - if (skb->len<4 || fh->ea1 || data[2] != FR_UI) + if (skb->len <= 4 || fh->ea1 || data[2] != FR_UI) goto rx_error; dlci = q922_to_dlci(skb->data); @@ -546,61 +779,43 @@ pvc = find_pvc(hdlc, dlci); if (!pvc) { -#ifdef CONFIG_HDLC_DEBUG_PKT +#ifdef DEBUG_PKT printk(KERN_INFO "%s: No PVC for received frame's DLCI %d\n", hdlc_to_name(hdlc), dlci); #endif - goto rx_error; - } - - if ((pvc->netdev.flags & IFF_UP) == 0) { -#ifdef CONFIG_HDLC_DEBUG_PKT - printk(KERN_INFO "%s: PVC for received frame's DLCI %d is down\n", - hdlc_to_name(hdlc), dlci); -#endif - goto rx_error; + dev_kfree_skb_any(skb); + return; } - pvc->stats.rx_packets++; /* PVC traffic */ - pvc->stats.rx_bytes += skb->len; - - if (pvc->state.fecn != (fh->fecn ? PVC_STATE_FECN : 0)) { -#ifdef CONFIG_HDLC_DEBUG_ECN - printk(KERN_DEBUG "%s: FECN O%s\n", pvc_to_name(pvc), - fh->fecn ? "N" : "FF"); + if (pvc->state.fecn != fh->fecn) { +#ifdef DEBUG_ECN + printk(KERN_DEBUG "%s: DLCI %d FECN O%s\n", hdlc_to_name(pvc), + dlci, fh->fecn ? "N" : "FF"); #endif pvc->state.fecn ^= 1; } - if (pvc->state.becn != (fh->becn ? PVC_STATE_BECN : 0)) { -#ifdef CONFIG_HDLC_DEBUG_ECN - printk(KERN_DEBUG "%s: BECN O%s\n", pvc_to_name(pvc), - fh->becn ? "N" : "FF"); + if (pvc->state.becn != fh->becn) { +#ifdef DEBUG_ECN + printk(KERN_DEBUG "%s: DLCI %d BECN O%s\n", hdlc_to_name(pvc), + dlci, fh->becn ? "N" : "FF"); #endif pvc->state.becn ^= 1; } - if (pvc->state.becn) - pvc->stats.rx_compressed++; - - skb->dev = &pvc->netdev; if (data[3] == NLPID_IP) { skb_pull(skb, 4); /* Remove 4-byte header (hdr, UI, NLPID) */ + dev = pvc->main; skb->protocol = htons(ETH_P_IP); - netif_rx(skb); - return; - } - - if (data[3] == NLPID_IPV6) { + } else if (data[3] == NLPID_IPV6) { skb_pull(skb, 4); /* Remove 4-byte header (hdr, UI, NLPID) */ + dev = pvc->main; skb->protocol = htons(ETH_P_IPV6); - netif_rx(skb); - return; - } - if (data[3] == FR_PAD && data[4] == NLPID_SNAP && data[5] == FR_PAD) { + } else if (skb->len > 10 && data[3] == FR_PAD && + data[4] == NLPID_SNAP && data[5] == FR_PAD) { u16 oui = ntohs(*(u16*)(data + 6)); u16 pid = ntohs(*(u16*)(data + 8)); skb_pull(skb, 10); @@ -610,23 +825,39 @@ case ETH_P_IPX: case ETH_P_IP: /* a long variant */ case ETH_P_IPV6: + dev = pvc->main; skb->protocol = htons(pid); break; + case 0x80C20007: /* bridged Ethernet frame */ + if ((dev = pvc->ether) != NULL) + skb->protocol = eth_type_trans(skb, dev); + break; + default: printk(KERN_INFO "%s: Unsupported protocol, OUI=%x " "PID=%x\n", hdlc_to_name(hdlc), oui, pid); dev_kfree_skb_any(skb); return; } - - netif_rx(skb); + } else { + printk(KERN_INFO "%s: Unsupported protocol, NLPID=%x " + "length = %i\n", hdlc_to_name(hdlc), data[3], skb->len); + dev_kfree_skb_any(skb); return; } - printk(KERN_INFO "%s: Unsupported protocol, NLPID=%x\n", - hdlc_to_name(hdlc), data[3]); - dev_kfree_skb_any(skb); + if (dev) { + struct net_device_stats *stats = pvc_get_stats(dev); + stats->rx_packets++; /* PVC traffic */ + stats->rx_bytes += skb->len; + if (pvc->state.becn) + stats->rx_compressed++; + skb->dev = dev; + netif_rx(skb); + } else + dev_kfree_skb_any(skb); + return; rx_error: @@ -641,7 +872,7 @@ if (hdlc->state.fr.settings.lmi != LMI_NONE) { hdlc->state.fr.last_poll = 0; hdlc->state.fr.reliable = 0; - hdlc->state.fr.changed = 1; + hdlc->state.fr.dce_changed = 1; hdlc->state.fr.request = 0; hdlc->state.fr.fullrep_sent = 0; hdlc->state.fr.last_errors = 0xFFFFFFFF; @@ -669,90 +900,119 @@ if (hdlc->state.fr.settings.lmi != LMI_NONE) del_timer_sync(&hdlc->state.fr.timer); - while(pvc) { - dev_close(&pvc->netdev); /* Shutdown all PVCs for this FRAD */ + while (pvc) { /* Shutdown all PVCs for this FRAD */ + if (pvc->main) + dev_close(pvc->main); + if (pvc->ether) + dev_close(pvc->ether); + pvc->state.active = pvc->state.new = pvc->state.fecn = + pvc->state.becn = 0; + pvc->state.exist = 0; pvc = pvc->next; } } - -static int fr_pvc(hdlc_device *hdlc, unsigned int dlci, int create) +static int fr_add_pvc(hdlc_device *hdlc, unsigned int dlci, int type) { - pvc_device **pvc_p = &hdlc->state.fr.first_pvc; - pvc_device *pvc; - int result; + pvc_device *pvc = NULL; + struct net_device *dev; + int result, used; + char * prefix = "pvc%d"; - if(dlci <= 0 || dlci >= 1024) - return -EINVAL; /* Only 10 bits for DLCI, DLCI 0 reserved */ + if (type == ARPHRD_ETHER) + prefix = "pvceth%d"; - while(*pvc_p) { - if (netdev_dlci(&(*pvc_p)->netdev) == dlci) - break; - pvc_p = &(*pvc_p)->next; + if ((pvc = add_pvc(hdlc, dlci)) == NULL) { + printk(KERN_WARNING "%s: Memory squeeze on fr_add_pvc()\n", + hdlc_to_name(hdlc)); + return -ENOBUFS; } - if (create) { /* Create PVC */ - if (*pvc_p != NULL) - return -EEXIST; - - pvc = *pvc_p = kmalloc(sizeof(pvc_device), GFP_KERNEL); - if (!pvc) { - printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n", - hdlc_to_name(hdlc)); - return -ENOBUFS; - } - memset(pvc, 0, sizeof(pvc_device)); + if (*get_dev_p(pvc, type)) + return -EEXIST; - pvc->netdev.hard_start_xmit = pvc_xmit; - pvc->netdev.get_stats = pvc_get_stats; - pvc->netdev.open = pvc_open; - pvc->netdev.stop = pvc_close; - pvc->netdev.change_mtu = pvc_change_mtu; - pvc->netdev.mtu = HDLC_MAX_MTU; - - pvc->netdev.type = ARPHRD_DLCI; - pvc->netdev.hard_header_len = 16; - pvc->netdev.hard_header = fr_hard_header; - pvc->netdev.tx_queue_len = 0; - pvc->netdev.flags = IFF_POINTOPOINT; - - pvc->master = hdlc; - *(u16*)pvc->netdev.dev_addr = htons(dlci); - dlci_to_q922(pvc->netdev.broadcast, dlci); - pvc->netdev.addr_len = 2; - - result = dev_alloc_name(&pvc->netdev, "pvc%d"); - if (result < 0) { - kfree(pvc); - *pvc_p = NULL; - return result; - } + used = pvc_is_used(pvc); - if (register_netdevice(&pvc->netdev) != 0) { - kfree(pvc); - *pvc_p = NULL; - return -EIO; - } + dev = kmalloc(sizeof(struct net_device) + + sizeof(struct net_device_stats), GFP_KERNEL); + if (!dev) { + printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n", + hdlc_to_name(hdlc)); + delete_unused_pvcs(hdlc); + return -ENOBUFS; + } + memset(dev, 0, sizeof(struct net_device) + + sizeof(struct net_device_stats)); - hdlc->state.fr.changed = 1; - hdlc->state.fr.pvc_count++; - return 0; + if (type == ARPHRD_ETHER) { + ether_setup(dev); + memcpy(dev->dev_addr, "\x00\x01", 2); + get_random_bytes(dev->dev_addr + 2, ETH_ALEN - 2); + } else { + dev->type = ARPHRD_DLCI; + dev->flags = IFF_POINTOPOINT; + dev->hard_header_len = 10; + dev->addr_len = 2; + *(u16*)dev->dev_addr = htons(dlci); + dlci_to_q922(dev->broadcast, dlci); + } + dev->hard_start_xmit = pvc_xmit; + dev->get_stats = pvc_get_stats; + dev->open = pvc_open; + dev->stop = pvc_close; + dev->do_ioctl = pvc_ioctl; + dev->change_mtu = pvc_change_mtu; + dev->mtu = HDLC_MAX_MTU; + dev->tx_queue_len = 0; + dev->priv = pvc; + + result = dev_alloc_name(dev, prefix); + if (result < 0) { + kfree(dev); + delete_unused_pvcs(hdlc); + return result; + } + + if (register_netdevice(dev) != 0) { + kfree(dev); + delete_unused_pvcs(hdlc); + return -EIO; + } + + *get_dev_p(pvc, type) = dev; + if (!used) { + hdlc->state.fr.dce_changed = 1; + hdlc->state.fr.dce_pvc_count++; } + return 0; +} + - if (*pvc_p == NULL) /* Delete PVC */ + +static int fr_del_pvc(hdlc_device *hdlc, unsigned int dlci, int type) +{ + pvc_device *pvc; + struct net_device *dev; + + if ((pvc = find_pvc(hdlc, dlci)) == NULL) return -ENOENT; - pvc = *pvc_p; + if ((dev = *get_dev_p(pvc, type)) == NULL) + return -ENOENT; - if (pvc->netdev.flags & IFF_UP) + if (dev->flags & IFF_UP) return -EBUSY; /* PVC in use */ - hdlc->state.fr.changed = 1; - hdlc->state.fr.pvc_count--; - *pvc_p = pvc->next; - unregister_netdevice(&pvc->netdev); - kfree(pvc); + unregister_netdevice(dev); + kfree(dev); + *get_dev_p(pvc, type) = NULL; + + if (!pvc_is_used(pvc)) { + hdlc->state.fr.dce_pvc_count--; + hdlc->state.fr.dce_changed = 1; + } + delete_unused_pvcs(hdlc); return 0; } @@ -761,16 +1021,23 @@ static void fr_destroy(hdlc_device *hdlc) { pvc_device *pvc = hdlc->state.fr.first_pvc; - while(pvc) { + while (pvc) { pvc_device *next = pvc->next; - unregister_netdev(&pvc->netdev); + if (pvc->main) { + unregister_netdevice(pvc->main); + kfree(pvc->main); + } + if (pvc->ether) { + unregister_netdevice(pvc->ether); + kfree(pvc->ether); + } kfree(pvc); pvc = next; } hdlc->state.fr.first_pvc = NULL; /* All PVCs destroyed */ - hdlc->state.fr.pvc_count = 0; - hdlc->state.fr.changed = 1; + hdlc->state.fr.dce_pvc_count = 0; + hdlc->state.fr.dce_changed = 1; } @@ -828,25 +1095,27 @@ if (hdlc->proto != IF_PROTO_FR) { hdlc_proto_detach(hdlc); hdlc->state.fr.first_pvc = NULL; - hdlc->state.fr.pvc_count = 0; + hdlc->state.fr.dce_pvc_count = 0; } memcpy(&hdlc->state.fr.settings, &new_settings, size); hdlc->open = fr_open; hdlc->stop = fr_close; hdlc->netif_rx = fr_rx; + hdlc->type_trans = NULL; hdlc->proto_detach = fr_destroy; hdlc->proto = IF_PROTO_FR; dev->hard_start_xmit = hdlc->xmit; - dev->hard_header = fr_hard_header; + dev->hard_header = NULL; dev->type = ARPHRD_FRAD; - dev->addr_len = 2; - *(u16*)dev->dev_addr = htons(LMI_DLCI); - dlci_to_q922(dev->broadcast, LMI_DLCI); + dev->flags = IFF_POINTOPOINT | IFF_NOARP; + dev->addr_len = 0; return 0; case IF_PROTO_FR_ADD_PVC: case IF_PROTO_FR_DEL_PVC: + case IF_PROTO_FR_ADD_ETH_PVC: + case IF_PROTO_FR_DEL_ETH_PVC: if(!capable(CAP_NET_ADMIN)) return -EPERM; @@ -854,8 +1123,20 @@ sizeof(fr_proto_pvc))) return -EFAULT; - return fr_pvc(hdlc, pvc.dlci, - ifr->ifr_settings.type == IF_PROTO_FR_ADD_PVC); + if (pvc.dlci <= 0 || pvc.dlci >= 1024) + return -EINVAL; /* Only 10 bits, DLCI 0 reserved */ + + if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC || + ifr->ifr_settings.type == IF_PROTO_FR_DEL_ETH_PVC) + result = ARPHRD_ETHER; /* bridged Ethernet device */ + else + result = ARPHRD_DLCI; + + if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_PVC || + ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC) + return fr_add_pvc(hdlc, pvc.dlci, result); + else + return fr_del_pvc(hdlc, pvc.dlci, result); } return -EINVAL; Index: drivers/net/wan/hdlc_generic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/hdlc_generic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/hdlc_generic.c 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/hdlc_generic.c 4 Aug 2004 01:29:24 -0000 1.2 @@ -1,17 +1,13 @@ /* * Generic HDLC support routines for Linux * - * Copyright (C) 1999 - 2001 Krzysztof Halasa + * Copyright (C) 1999 - 2003 Krzysztof Halasa * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. * - * Current status: - * - this is work in progress - * - not heavily tested on SMP - * - currently supported: + * Currently supported: * * raw IP-in-HDLC * * Cisco HDLC * * Frame Relay with ANSI or CCITT LMI (both user and network side) @@ -37,7 +33,7 @@ #include -static const char* version = "HDLC support module revision 1.11"; +static const char* version = "HDLC support module revision 1.14b"; static int hdlc_change_mtu(struct net_device *dev, int new_mtu) @@ -60,7 +56,13 @@ static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *p) { - dev_to_hdlc(dev)->netif_rx(skb); + hdlc_device *hdlc = dev_to_hdlc(dev); + if (hdlc->netif_rx) + hdlc->netif_rx(skb); + else { + hdlc->stats.rx_dropped++; /* Shouldn't happen */ + dev_kfree_skb(skb); + } return 0; } @@ -69,6 +71,10 @@ #define hdlc_raw_ioctl(hdlc, ifr) -ENOSYS #endif +#ifndef CONFIG_HDLC_RAW_ETH +#define hdlc_raw_eth_ioctl(hdlc, ifr) -ENOSYS +#endif + #ifndef CONFIG_HDLC_PPP #define hdlc_ppp_ioctl(hdlc, ifr) -ENOSYS #endif @@ -96,6 +102,7 @@ switch(ifr->ifr_settings.type) { case IF_PROTO_HDLC: + case IF_PROTO_HDLC_ETH: case IF_PROTO_PPP: case IF_PROTO_CISCO: case IF_PROTO_FR: @@ -109,6 +116,7 @@ switch(proto) { case IF_PROTO_HDLC: return hdlc_raw_ioctl(hdlc, ifr); + case IF_PROTO_HDLC_ETH: return hdlc_raw_eth_ioctl(hdlc, ifr); case IF_PROTO_PPP: return hdlc_ppp_ioctl(hdlc, ifr); case IF_PROTO_CISCO: return hdlc_cisco_ioctl(hdlc, ifr); case IF_PROTO_FR: return hdlc_fr_ioctl(hdlc, ifr); @@ -137,7 +145,7 @@ hdlc->proto_detach = NULL; result = dev_alloc_name(dev, "hdlc%d"); - if (result<0) + if (result < 0) return result; result = register_netdev(dev); @@ -152,9 +160,10 @@ void unregister_hdlc_device(hdlc_device *hdlc) { + rtnl_lock(); hdlc_proto_detach(hdlc); - - unregister_netdev(hdlc_to_dev(hdlc)); + unregister_netdevice(hdlc_to_dev(hdlc)); + rtnl_unlock(); MOD_DEC_USE_COUNT; } @@ -162,14 +171,13 @@ MODULE_AUTHOR("Krzysztof Halasa "); MODULE_DESCRIPTION("HDLC support module"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); EXPORT_SYMBOL(hdlc_ioctl); EXPORT_SYMBOL(register_hdlc_device); EXPORT_SYMBOL(unregister_hdlc_device); -struct packet_type hdlc_packet_type= -{ +static struct packet_type hdlc_packet_type = { __constant_htons(ETH_P_HDLC), NULL, hdlc_rcv, Index: drivers/net/wan/hdlc_ppp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/hdlc_ppp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/hdlc_ppp.c 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/hdlc_ppp.c 4 Aug 2004 01:29:24 -0000 1.2 @@ -2,15 +2,13 @@ * Generic HDLC support routines for Linux * Point-to-point protocol support * - * Copyright (C) 1999 - 2001 Krzysztof Halasa + * Copyright (C) 1999 - 2003 Krzysztof Halasa * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. */ -#include #include #include #include @@ -68,10 +66,10 @@ -static void ppp_rx(struct sk_buff *skb) +static unsigned short ppp_type_trans(struct sk_buff *skb, + struct net_device *dev) { - skb->protocol = htons(ETH_P_WAN_PPP); - netif_rx(skb); + return __constant_htons(ETH_P_WAN_PPP); } @@ -103,7 +101,8 @@ hdlc->open = ppp_open; hdlc->stop = ppp_close; - hdlc->netif_rx = ppp_rx; + hdlc->netif_rx = NULL; + hdlc->type_trans = ppp_type_trans; hdlc->proto = IF_PROTO_PPP; dev->hard_start_xmit = hdlc->xmit; dev->hard_header = NULL; Index: drivers/net/wan/hdlc_raw.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/hdlc_raw.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/hdlc_raw.c 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/hdlc_raw.c 4 Aug 2004 01:29:24 -0000 1.2 @@ -2,15 +2,13 @@ * Generic HDLC support routines for Linux * HDLC support * - * Copyright (C) 1999 - 2001 Krzysztof Halasa + * Copyright (C) 1999 - 2003 Krzysztof Halasa * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. */ -#include #include #include #include @@ -26,10 +24,10 @@ #include -static void raw_rx(struct sk_buff *skb) +static unsigned short raw_type_trans(struct sk_buff *skb, + struct net_device *dev) { - skb->protocol = htons(ETH_P_IP); - netif_rx(skb); + return __constant_htons(ETH_P_IP); } @@ -67,7 +65,7 @@ new_settings.encoding = ENCODING_NRZ; if (new_settings.parity == PARITY_DEFAULT) - new_settings.parity = PARITY_NONE; + new_settings.parity = PARITY_CRC16_PR1_CCITT; result = hdlc->attach(hdlc, new_settings.encoding, new_settings.parity); @@ -79,11 +77,13 @@ hdlc->open = NULL; hdlc->stop = NULL; - hdlc->netif_rx = raw_rx; + hdlc->netif_rx = NULL; + hdlc->type_trans = raw_type_trans; hdlc->proto = IF_PROTO_HDLC; dev->hard_start_xmit = hdlc->xmit; dev->hard_header = NULL; dev->type = ARPHRD_RAWHDLC; + dev->flags = IFF_POINTOPOINT | IFF_NOARP; dev->addr_len = 0; return 0; } Index: drivers/net/wan/hdlc_x25.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/hdlc_x25.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/hdlc_x25.c 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/hdlc_x25.c 4 Aug 2004 01:29:24 -0000 1.2 @@ -2,15 +2,13 @@ * Generic HDLC support routines for Linux * X.25 support * - * Copyright (C) 1999 - 2001 Krzysztof Halasa + * Copyright (C) 1999 - 2003 Krzysztof Halasa * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. */ -#include #include #include #include @@ -204,6 +202,7 @@ hdlc->open = x25_open; hdlc->stop = x25_close; hdlc->netif_rx = x25_rx; + hdlc->type_trans = NULL; hdlc->proto = IF_PROTO_X25; dev->hard_start_xmit = x25_xmit; dev->hard_header = NULL; Index: drivers/net/wan/n2.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/n2.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/n2.c 22 Jul 2004 19:49:35 -0000 1.1 +++ drivers/net/wan/n2.c 4 Aug 2004 01:29:24 -0000 1.2 @@ -1,12 +1,11 @@ /* * SDL Inc. RISCom/N2 synchronous serial card driver for Linux * - * Copyright (C) 1998-2002 Krzysztof Halasa + * Copyright (C) 1998-2003 Krzysztof Halasa * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. * * For information see http://hq.pm.waw.pl/hdlc/ * @@ -17,7 +16,6 @@ * SDL Inc. PPP/HDLC/CISCO driver */ -#include #include #include #include @@ -34,14 +32,24 @@ #include "hd64570.h" -static const char* version = "SDL RISCom/N2 driver version: 1.10"; +static const char* version = "SDL RISCom/N2 driver version: 1.14"; static const char* devname = "RISCom/N2"; +#undef DEBUG_PKT +#define DEBUG_RINGS + #define USE_WINDOWSIZE 16384 #define USE_BUS16BITS 1 #define CLOCK_BASE 9830400 /* 9.8304 MHz */ - +#define MAX_PAGES 16 /* 16 RAM pages at max */ +#define MAX_RAM_SIZE 0x80000 /* 512 KB */ +#if MAX_RAM_SIZE > MAX_PAGES * USE_WINDOWSIZE +#undef MAX_RAM_SIZE +#define MAX_RAM_SIZE (MAX_PAGES * USE_WINDOWSIZE) +#endif #define N2_IOPORTS 0x10 +#define NEED_DETECT_RAM +#define MAX_TX_BUFFERS 10 static char *hw = NULL; /* pointer to hw=xxx command line string */ @@ -86,16 +94,16 @@ struct card_s *card; spinlock_t lock; /* TX lock */ sync_serial_settings settings; + int valid; /* port enabled */ + int rxpart; /* partial frame received, next frame invalid*/ unsigned short encoding; unsigned short parity; + u16 rxin; /* rx ring buffer 'in' pointer */ + u16 txin; /* tx ring buffer 'in' and 'last' pointers */ + u16 txlast; u8 rxs, txs, tmc; /* SCA registers */ - u8 valid; /* port enabled */ u8 phy_node; /* physical port # - 0 or 1 */ u8 log_node; /* logical port # */ - u8 rxin; /* rx ring buffer 'in' pointer */ - u8 txin; /* tx ring buffer 'in' and 'last' pointers */ - u8 txlast; - u8 rxpart; /* partial frame received, next frame invalid*/ }port_t; @@ -106,8 +114,9 @@ u32 ram_size; /* number of bytes */ u16 io; /* IO Base address */ u16 buff_offset; /* offset of first buffer of first channel */ + u16 rx_ring_buffers; /* number of buffers in a ring */ + u16 tx_ring_buffers; u8 irq; /* IRQ (3-15) */ - u8 ring_buffers; /* number of buffers in a ring */ port_t ports[2]; struct card_s *next_card; @@ -216,7 +225,7 @@ MOD_INC_USE_COUNT; mcr &= port->phy_node ? ~DTR_PORT1 : ~DTR_PORT0; /* set DTR ON */ outb(mcr, io + N2_MCR); - + outb(inb(io + N2_PCR) | PCR_ENWIN, io + N2_PCR); /* open window */ outb(inb(io + N2_PSR) | PSR_DMAEN, io + N2_PSR); /* enable dma */ sca_open(hdlc); @@ -250,7 +259,7 @@ hdlc_device *hdlc = dev_to_hdlc(dev); port_t *port = hdlc_to_port(hdlc); -#ifdef CONFIG_HDLC_DEBUG_RINGS +#ifdef DEBUG_RINGS if (cmd == SIOCDEVPRIVATE) { sca_dump_rings(hdlc); return 0; @@ -297,62 +306,6 @@ -static u8 n2_count_page(card_t *card) -{ - u8 page; - int i, bcount = USE_WINDOWSIZE, wcount = USE_WINDOWSIZE/2; - u16 *dp = (u16*)card->winbase; - u8 *bp = (u8*)card->winbase; - u8 psr = inb(card->io + N2_PSR) & PSR_WINBITS; - - - for (page = 0; page < 16; page++) { - outb(psr | page, card->io + N2_PSR); /* select a page */ - writeb(page, dp); - if (readb(dp) != page) - break; /* If can't read back, no good memory */ - - outb(psr, card->io + N2_PSR); /* goto page 0 */ - if (readb(dp)) - break; /* If page 0 changed, then wrapped around */ - - outb(psr | page, card->io + N2_PSR); /* select page again */ - - /* first do byte tests */ - for (i = 0; i < bcount; i++) - writeb(i, bp + i); - for (i = 0; i < bcount; i++) - if (readb(bp + i) != (i & 0xff)) - return 0; - - for (i = 0; i < bcount; i++) - writeb(~i, bp + i); - for (i = 0; i < bcount; i++) - if (readb(bp + i) != (~i & 0xff)) - return 0; - - /* next do 16-bit tests */ - for (i = 0; i < wcount; i++) - writew(0x55AA, dp + i); - for (i = 0; i < wcount; i++) - if (readw(dp + i) != 0x55AA) - return 0; - - for (i = 0; i < wcount; i++) - writew(0xAA55, dp + i); - for (i = 0; i < wcount; i++) - if (readw(dp + i) != 0xAA55) - return 0; - - for (i = 0; i < wcount; i++) - writew(page, dp + i); - } - - return page; -} - - - static void n2_destroy_card(card_t *card) { int cnt; @@ -376,11 +329,12 @@ -static int n2_run(unsigned long io, unsigned long irq, unsigned long winbase, - long valid0, long valid1) +static int __init n2_run(unsigned long io, unsigned long irq, + unsigned long winbase, long valid0, long valid1) { card_t *card; u8 cnt, pcr; + int i; if (io < 0x200 || io > 0x3FF || (io % N2_IOPORTS) != 0) { printk(KERN_ERR "n2: invalid I/O port value\n"); @@ -391,7 +345,7 @@ printk(KERN_ERR "n2: invalid IRQ value\n"); return -ENODEV; } - + if (winbase < 0xA0000 || winbase > 0xFFFFF || (winbase & 0xFFF) != 0) { printk(KERN_ERR "n2: invalid RAM value\n"); return -ENODEV; @@ -451,26 +405,28 @@ pcr = PCR_ENWIN | PCR_VPM | (USE_BUS16BITS ? PCR_BUS16 : 0); outb(pcr, io + N2_PCR); - cnt = n2_count_page(card); - if (!cnt) { - printk(KERN_ERR "n2: memory test failed.\n"); + card->ram_size = sca_detect_ram(card, card->winbase, MAX_RAM_SIZE); + + /* number of TX + RX buffers for one port */ + i = card->ram_size / ((valid0 + valid1) * (sizeof(pkt_desc) + + HDLC_MAX_MRU)); + + card->tx_ring_buffers = min(i / 2, MAX_TX_BUFFERS); + card->rx_ring_buffers = i - card->tx_ring_buffers; + + card->buff_offset = (valid0 + valid1) * sizeof(pkt_desc) * + (card->tx_ring_buffers + card->rx_ring_buffers); + + printk(KERN_INFO "n2: RISCom/N2 %u KB RAM, IRQ%u, " + "using %u TX + %u RX packets rings\n", card->ram_size / 1024, + card->irq, card->tx_ring_buffers, card->rx_ring_buffers); + + if (card->tx_ring_buffers < 1) { + printk(KERN_ERR "n2: RAM test failed\n"); n2_destroy_card(card); return -EIO; } - card->ram_size = cnt * USE_WINDOWSIZE; - - /* 4 rings required for 2 ports, 2 rings for one port */ - card->ring_buffers = card->ram_size / - ((valid0 + valid1) * 2 * (sizeof(pkt_desc) + HDLC_MAX_MRU)); - - card->buff_offset = (valid0 + valid1) * 2 * (sizeof(pkt_desc)) - * card->ring_buffers; - - printk(KERN_DEBUG "n2: RISCom/N2 %u KB RAM, IRQ%u, " - "using %u packets rings\n", card->ram_size / 1024, card->irq, - card->ring_buffers); - pcr |= PCR_RUNSCA; /* run SCA */ outb(pcr, io + N2_PCR); outb(0, io + N2_MCR); @@ -492,7 +448,7 @@ spin_lock_init(&port->lock); dev->irq = irq; dev->mem_start = winbase; - dev->mem_end = winbase + USE_WINDOWSIZE-1; + dev->mem_end = winbase + USE_WINDOWSIZE - 1; dev->tx_queue_len = 50; dev->do_ioctl = n2_ioctl; dev->open = n2_open; @@ -531,7 +487,7 @@ return -ENOSYS; /* no parameters specified, abort */ } - printk(KERN_INFO "%s (SCA-%s)\n", version, sca_version); + printk(KERN_INFO "%s\n", version); do { unsigned long io, irq, ram; @@ -558,7 +514,7 @@ break; hw++; } - + if (!valid[0] && !valid[1]) break; /* at least one port must be used */ @@ -566,7 +522,7 @@ n2_run(io, irq, ram, valid[0], valid[1]); if (*hw == '\x0') - return 0; + return first_card ? 0 : -ENOSYS; }while(*hw++ == ':'); printk(KERN_ERR "n2: invalid hardware parameters\n"); @@ -602,6 +558,6 @@ MODULE_AUTHOR("Krzysztof Halasa "); MODULE_DESCRIPTION("RISCom/N2 serial port driver"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); MODULE_PARM(hw, "s"); /* hw=io,irq,ram,ports:io,irq,... */ EXPORT_NO_SYMBOLS; Index: drivers/net/wan/sbni.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/sbni.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/sbni.c 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/sbni.c 4 Aug 2004 01:29:24 -0000 1.2 @@ -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; Index: drivers/net/wan/sdla_chdlc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/sdla_chdlc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/sdla_chdlc.c 22 Jul 2004 19:49:35 -0000 1.1 +++ drivers/net/wan/sdla_chdlc.c 4 Aug 2004 01:29:24 -0000 1.2 @@ -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; } @@ -3822,7 +3819,7 @@ void s508_lock (sdla_t *card, unsigned long *smp_flags) { -#if defined(__SMP__) || defined(LINUX_2_4) +#if defined(CONFIG_SMP) || defined(LINUX_2_4) spin_lock_irqsave(&card->wandev.lock, *smp_flags); if (card->next){ spin_lock(&card->next->wandev.lock); @@ -3834,7 +3831,7 @@ void s508_unlock (sdla_t *card, unsigned long *smp_flags) { -#if defined(__SMP__) || defined(LINUX_2_4) +#if defined(CONFIG_SMP) || defined(LINUX_2_4) if (card->next){ spin_unlock(&card->next->wandev.lock); } Index: drivers/net/wan/sdla_fr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/sdla_fr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/sdla_fr.c 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/sdla_fr.c 4 Aug 2004 01:29:24 -0000 1.2 @@ -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; } @@ -4709,13 +4707,13 @@ { if (card->hw.type != SDLA_S514){ -#if defined(__SMP__) || defined(LINUX_2_4) +#if defined(CONFIG_SMP) || defined(LINUX_2_4) spin_lock_irqsave(&card->wandev.lock, *smp_flags); #else disable_irq(card->hw.irq); #endif }else{ -#if defined(__SMP__) || defined(LINUX_2_4) +#if defined(CONFIG_SMP) || defined(LINUX_2_4) spin_lock(&card->u.f.if_send_lock); #endif } @@ -4727,13 +4725,13 @@ { if (card->hw.type != SDLA_S514){ -#if defined(__SMP__) || defined(LINUX_2_4) +#if defined(CONFIG_SMP) || defined(LINUX_2_4) spin_unlock_irqrestore (&card->wandev.lock, *smp_flags); #else enable_irq(card->hw.irq); #endif }else{ -#if defined(__SMP__) || defined(LINUX_2_4) +#if defined(CONFIG_SMP) || defined(LINUX_2_4) spin_unlock(&card->u.f.if_send_lock); #endif } Index: drivers/net/wan/sdla_ppp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/sdla_ppp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/sdla_ppp.c 22 Jul 2004 19:49:35 -0000 1.1 +++ drivers/net/wan/sdla_ppp.c 4 Aug 2004 01:29:25 -0000 1.2 @@ -3331,7 +3331,7 @@ void s508_lock (sdla_t *card, unsigned long *smp_flags) { -#if defined(__SMP__) || defined(LINUX_2_4) +#if defined(CONFIG_SMP) || defined(LINUX_2_4) spin_lock_irqsave(&card->wandev.lock, *smp_flags); #else disable_irq(card->hw.irq); @@ -3340,7 +3340,7 @@ void s508_unlock (sdla_t *card, unsigned long *smp_flags) { -#if defined(__SMP__) || defined(LINUX_2_4) +#if defined(CONFIG_SMP) || defined(LINUX_2_4) spin_unlock_irqrestore(&card->wandev.lock, *smp_flags); #else enable_irq(card->hw.irq); Index: drivers/net/wan/sdla_x25.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/sdla_x25.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/sdla_x25.c 22 Jul 2004 19:49:35 -0000 1.1 +++ drivers/net/wan/sdla_x25.c 4 Aug 2004 01:29:25 -0000 1.2 @@ -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 */ Index: drivers/net/wan/sdlamain.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/sdlamain.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/sdlamain.c 22 Jul 2004 19:49:35 -0000 1.1 +++ drivers/net/wan/sdlamain.c 4 Aug 2004 01:29:25 -0000 1.2 @@ -511,7 +511,7 @@ if (!card->configured){ /* Initialize the Spin lock */ -#if defined(__SMP__) || defined(LINUX_2_4) +#if defined(CONFIG_SMP) || defined(LINUX_2_4) printk(KERN_INFO "%s: Initializing for SMP\n",wandev->name); #endif Index: drivers/net/wan/syncppp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/syncppp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/syncppp.c 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/syncppp.c 4 Aug 2004 01:29:25 -0000 1.2 @@ -33,7 +33,7 @@ * * Version 1.9, Wed Oct 4 18:58:15 MSK 1995 * - * $Id: syncppp.c,v 1.1 2004/07/22 19:49:36 joff Exp $ + * $Id: syncppp.c,v 1.2 2004/08/04 01:29:25 joff Exp $ */ #undef DEBUG Index: drivers/net/wan/wanpipe_multppp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/wanpipe_multppp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/wanpipe_multppp.c 22 Jul 2004 19:49:35 -0000 1.1 +++ drivers/net/wan/wanpipe_multppp.c 4 Aug 2004 01:29:25 -0000 1.2 @@ -2358,7 +2358,7 @@ void s508_lock (sdla_t *card, unsigned long *smp_flags) { -#if defined(__SMP__) || defined(LINUX_2_4) +#if defined(CONFIG_SMP) || defined(LINUX_2_4) spin_lock_irqsave(&card->wandev.lock, *smp_flags); if (card->next){ /* It is ok to use spin_lock here, since we @@ -2372,7 +2372,7 @@ void s508_unlock (sdla_t *card, unsigned long *smp_flags) { -#if defined(__SMP__) || defined(LINUX_2_4) +#if defined(CONFIG_SMP) || defined(LINUX_2_4) if (card->next){ spin_unlock(&card->next->wandev.lock); } Index: drivers/net/wan/z85230.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/z85230.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/z85230.c 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/z85230.c 4 Aug 2004 01:29:25 -0000 1.2 @@ -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; } Index: drivers/net/wan/8253x/8253x.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/8253x/8253x.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/8253x/8253x.h 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/8253x/8253x.h 4 Aug 2004 01:29:25 -0000 1.2 @@ -1,5 +1,5 @@ /* -*- linux-c -*- */ -/* $Id: 8253x.h,v 1.1 2004/07/22 19:49:36 joff Exp $ +/* $Id: 8253x.h,v 1.2 2004/08/04 01:29:25 joff Exp $ * sab82532.h: Register Definitions for the Siemens SAB82532 DUSCC * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) Index: drivers/net/wan/8253x/8253xsyn.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/8253x/8253xsyn.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/8253x/8253xsyn.c 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/8253x/8253xsyn.c 4 Aug 2004 01:29:25 -0000 1.2 @@ -1,5 +1,5 @@ /* -*- linux-c -*- */ -/* $Id: 8253xsyn.c,v 1.1 2004/07/22 19:49:36 joff Exp $ +/* $Id: 8253xsyn.c,v 1.2 2004/08/04 01:29:25 joff Exp $ * 8253xsyn.c: SYNC TTY Driver for the SIEMENS SAB8253X DUSCC. * * Implementation, modifications and extensions Index: drivers/net/wan/8253x/8253xtty.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/8253x/8253xtty.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/8253x/8253xtty.c 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/8253x/8253xtty.c 4 Aug 2004 01:29:25 -0000 1.2 @@ -1,5 +1,5 @@ /* -*- linux-c -*- */ -/* $Id: 8253xtty.c,v 1.1 2004/07/22 19:49:36 joff Exp $ +/* $Id: 8253xtty.c,v 1.2 2004/08/04 01:29:25 joff Exp $ * sab82532.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -2384,7 +2384,7 @@ static void inline show_aurora_version(void) { - char *revision = "$Revision: 1.1 $"; + char *revision = "$Revision: 1.2 $"; char *version, *p; version = strchr(revision, ' '); Index: drivers/net/wan/8253x/8253xutl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/8253x/8253xutl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/8253x/8253xutl.c 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/8253x/8253xutl.c 4 Aug 2004 01:29:25 -0000 1.2 @@ -1,5 +1,5 @@ /* -*- linux-c -*- */ -/* $Id: 8253xutl.c,v 1.1 2004/07/22 19:49:36 joff Exp $ +/* $Id: 8253xutl.c,v 1.2 2004/08/04 01:29:25 joff Exp $ * 8253xutl.c: SYNC TTY Driver for the SIEMENS SAB8253X DUSCC. * * Implementation, modifications and extensions Index: drivers/net/wan/8253x/crc32dcl.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/8253x/crc32dcl.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/8253x/crc32dcl.h 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/8253x/crc32dcl.h 4 Aug 2004 01:29:25 -0000 1.2 @@ -29,7 +29,6 @@ /****************************************************/ extern void fn_init_crc_table(void); -extern unsigned int fn_calc_memory_chunk_crc32(void *p, unsigned int n_bytes, unsigned int crc); extern unsigned int fn_calc_memory_crc32(void *p, unsigned int n_bytes); extern unsigned int fn_check_memory_crc32(void *p, unsigned int n_bytes, unsigned int crc); Index: drivers/net/wan/8253x/sp502.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/8253x/sp502.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/8253x/sp502.h 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/8253x/sp502.h 4 Aug 2004 01:29:25 -0000 1.2 @@ -17,7 +17,7 @@ * file: sp502.h * author: bkd * created: 1/21/95 - * revision info: $Id: sp502.h,v 1.1 2004/07/22 19:49:36 joff Exp $ + * revision info: $Id: sp502.h,v 1.2 2004/08/04 01:29:25 joff Exp $ * ripped off from: Header: /vol/sources.cvs/dev/acs/include/sp502.h,v 1.4 1996/11/07 21:35:10 bkd Exp * Used without modification in the multichannel server portion of the Linux driver by Joachim Martillo */ @@ -26,7 +26,7 @@ #define _SP502_H #ifdef sun -# pragma ident "@(#)$Header: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/8253x/sp502.h,v 1.1 2004/07/22 19:49:36 joff Exp $" +# pragma ident "@(#)$Header: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/8253x/sp502.h,v 1.2 2004/08/04 01:29:25 joff Exp $" #endif /* Index: drivers/net/wan/lmc/lmc_ioctl.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/lmc/lmc_ioctl.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/lmc/lmc_ioctl.h 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/lmc/lmc_ioctl.h 4 Aug 2004 01:29:25 -0000 1.2 @@ -1,6 +1,6 @@ #ifndef _LMC_IOCTL_H_ #define _LMC_IOCTL_H_ -/* $Id: lmc_ioctl.h,v 1.1 2004/07/22 19:49:36 joff Exp $ */ +/* $Id: lmc_ioctl.h,v 1.2 2004/08/04 01:29:25 joff Exp $ */ /* * Copyright (c) 1997-2000 LAN Media Corporation (LMC) Index: drivers/net/wan/lmc/lmc_main.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/lmc/lmc_main.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/lmc/lmc_main.c 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/lmc/lmc_main.c 4 Aug 2004 01:29:25 -0000 1.2 @@ -36,7 +36,7 @@ * */ -/* $Id: lmc_main.c,v 1.1 2004/07/22 19:49:36 joff Exp $ */ +/* $Id: lmc_main.c,v 1.2 2004/08/04 01:29:25 joff Exp $ */ #include #include Index: drivers/net/wan/lmc/lmc_media.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/lmc/lmc_media.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/lmc/lmc_media.c 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/lmc/lmc_media.c 4 Aug 2004 01:29:25 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: lmc_media.c,v 1.1 2004/07/22 19:49:36 joff Exp $ */ +/* $Id: lmc_media.c,v 1.2 2004/08/04 01:29:25 joff Exp $ */ #include #include Index: drivers/net/wan/lmc/lmc_proto.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/lmc/lmc_proto.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/lmc/lmc_proto.c 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/lmc/lmc_proto.c 4 Aug 2004 01:29:26 -0000 1.2 @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include Index: drivers/net/wan/lmc/lmc_var.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wan/lmc/lmc_var.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wan/lmc/lmc_var.h 22 Jul 2004 19:49:36 -0000 1.1 +++ drivers/net/wan/lmc/lmc_var.h 4 Aug 2004 01:29:26 -0000 1.2 @@ -1,7 +1,7 @@ #ifndef _LMC_VAR_H_ #define _LMC_VAR_H_ -/* $Id: lmc_var.h,v 1.1 2004/07/22 19:49:36 joff Exp $ */ +/* $Id: lmc_var.h,v 1.2 2004/08/04 01:29:26 joff Exp $ */ /* * Copyright (c) 1997-2000 LAN Media Corporation (LMC) Index: drivers/net/wireless/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/Config.in,v retrieving revision 1.1 retrieving revision 1.4 diff -u -r1.1 -r1.4 --- drivers/net/wireless/Config.in 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/wireless/Config.in 1 Dec 2004 23:17:40 -0000 1.4 @@ -14,6 +14,7 @@ if [ "$CONFIG_PCI" = "y" ]; then dep_tristate ' Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.) (EXPERIMENTAL)' CONFIG_PLX_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL + dep_tristate ' Hermes in TMD7160/NCP130 based PCI adaptor support (Pheecom WL-PCI etc.) (EXPERIMENTAL)' CONFIG_TMD_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL dep_tristate ' Prism 2.5 PCI 802.11b adaptor support (EXPERIMENTAL)' CONFIG_PCI_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL fi @@ -23,11 +24,27 @@ dep_tristate ' Hermes PCMCIA card support' CONFIG_PCMCIA_HERMES $CONFIG_HERMES tristate ' Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards' CONFIG_AIRO_CS + dep_tristate ' Atmel at76c502/at76c504 PCMCIA cards' CONFIG_PCMCIA_ATMEL $CONFIG_FW_LOADER fi + +bool 'Include wlan-ng drivers' CONFIG_WLAN_NG n + +if [ "$CONFIG_USB" != "n" ]; then + comment 'Wireless USB cards' + + dep_tristate ' Atmel at76c502/at76c504 USB cards' CONFIG_USB_ATMEL $CONFIG_FW_LOADER + + if [ "$CONFIG_WLAN_NG" = "y" ]; then + dep_tristate ' wlan-ng supported USB cards' PRISM2_USB $CONFIG_FW_LOADER + fi +fi + + # yes, this works even when no drivers are selected if [ "$CONFIG_ISA" = "y" -o "$CONFIG_PCI" = "y" -o \ - "$CONFIG_ALL_PPC" = "y" -o "$CONFIG_PCMCIA" != "n" ]; then + "$CONFIG_ALL_PPC" = "y" -o "$CONFIG_PCMCIA" != "n" -o \ + "$CONFIG_USB" != "n" ]; then define_bool CONFIG_NET_WIRELESS y else define_bool CONFIG_NET_WIRELESS n Index: drivers/net/wireless/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/Makefile,v retrieving revision 1.1 retrieving revision 1.5 diff -u -r1.1 -r1.5 --- drivers/net/wireless/Makefile 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/wireless/Makefile 1 Dec 2004 23:20:14 -0000 1.5 @@ -4,6 +4,11 @@ # Makefile for the Linux Wireless network device drivers. # +subdir-$(CONFIG_USB_ATMEL) += at76c503 +subdir-$(CONFIG_WLAN_NG) += wlan-ng + +mod-subdirs := at76c503 wlan-ng + O_TARGET := wireless_net.o obj-y := @@ -12,15 +17,19 @@ obj- := # Things that need to export symbols -export-objs := airo.o orinoco.o hermes.o +export-objs := airo.o orinoco.o hermes.o atmel.o obj-$(CONFIG_HERMES) += orinoco.o hermes.o obj-$(CONFIG_PCMCIA_HERMES) += orinoco_cs.o obj-$(CONFIG_APPLE_AIRPORT) += airport.o obj-$(CONFIG_PLX_HERMES) += orinoco_plx.o +obj-$(CONFIG_TMD_HERMES) += orinoco_tmd.o obj-$(CONFIG_PCI_HERMES) += orinoco_pci.o obj-$(CONFIG_AIRO) += airo.o obj-$(CONFIG_AIRO_CS) += airo_cs.o airo.o +obj-$(CONFIG_PCMCIA_ATMEL) += atmel_cs.o atmel.o include $(TOPDIR)/Rules.make + + Index: drivers/net/wireless/airo.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/airo.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wireless/airo.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/wireless/airo.c 4 Aug 2004 01:29:26 -0000 1.2 @@ -18,7 +18,6 @@ ======================================================================*/ #include -#include #include #include @@ -32,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -42,12 +40,11 @@ #include #include #include -#include #include #include #ifdef CONFIG_PCI -static struct pci_device_id card_ids[] __devinitdata = { +static struct pci_device_id card_ids[] = { { 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, }, { 0x14b9, 0x4500, PCI_ANY_ID, PCI_ANY_ID }, { 0x14b9, 0x4800, PCI_ANY_ID, PCI_ANY_ID, }, @@ -61,10 +58,10 @@ static void airo_pci_remove(struct pci_dev *); static struct pci_driver airo_driver = { - name: "airo", - id_table: card_ids, - probe: airo_pci_probe, - remove: __devexit_p(airo_pci_remove), + .name = "airo", + .id_table = card_ids, + .probe = airo_pci_probe, + .remove = __devexit_p(airo_pci_remove), }; #endif /* CONFIG_PCI */ @@ -81,12 +78,12 @@ #endif /* Support Cisco MIC feature */ -/* As this feature requires the AES encryption algorithm, it is not included - in the kernel tree. If you want to enable it, you need to download the - aes.h, aestab.h and mic.h files from the CVS at - http://sf.net/projects/airo-linux/ Put the files in the same directory - as airo.c and compile normally */ +#define MICSUPPORT + +#if defined(MICSUPPORT) && !defined(CONFIG_CRYPTO) +#warning MIC support requires Crypto API #undef MICSUPPORT +#endif /* Hack to do some power saving */ #define POWER_ON_DOWN @@ -97,12 +94,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 +143,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 +159,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", @@ -203,12 +200,6 @@ #ifndef RUN_AT #define RUN_AT(x) (jiffies+(x)) #endif -#if LINUX_VERSION_CODE < 0x020500 -static inline struct proc_dir_entry *PDE(const struct inode *inode) -{ - return inode->u.generic_ip; -} -#endif /* These variables are for insmod, since it seems that the rates @@ -305,6 +296,7 @@ #define CMD_DEALLOCATETX 0x000c #define NOP 0x0010 #define CMD_WORKAROUND 0x0011 +#define CMD_ALLOCATEAUX 0x0020 #define CMD_ACCESS 0x0021 #define CMD_PCIBAP 0x0022 #define CMD_PCIAUX 0x0023 @@ -409,6 +401,7 @@ #define EV_ALLOC 0x08 #define EV_LINK 0x80 #define EV_AWAKE 0x100 +#define EV_TXCPY 0x400 #define EV_UNKNOWN 0x800 #define EV_MIC 0x1000 /* Message Integrity Check Interrupt */ #define STATUS_INTS ( EV_AWAKE | EV_LINK | EV_TXEXC | EV_TX | EV_RX | EV_MIC ) @@ -619,14 +612,14 @@ u16 arlDelay; u16 _reserved4[1]; /*---------- Aironet Extensions ----------*/ - u16 magicAction; + u8 magicAction; #define MAGIC_ACTION_STSCHG 1 #define MACIC_ACTION_RESUME 2 #define MAGIC_IGNORE_MCAST (1<<8) #define MAGIC_IGNORE_BCAST (1<<9) #define MAGIC_SWITCH_TO_PSP (0<<10) #define MAGIC_STAY_IN_CAM (1<<10) - u16 magicControl; + u8 magicControl; u16 autoWake; } ConfigRid; @@ -639,7 +632,7 @@ u16 SSIDlen; char SSID[32]; char apName[16]; - char bssid[4][ETH_ALEN]; + u8 bssid[4][ETH_ALEN]; u16 beaconPeriod; u16 dimPeriod; u16 atimDuration; @@ -654,9 +647,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 { @@ -818,6 +840,7 @@ #define AIROGMICRID 11 #define AIROGMICSTATS 12 #define AIROGFLAGS 13 +#define AIRORRID 15 /* Leave gap of 40 commands after AIROGSTATSD32 for future */ @@ -894,7 +917,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,13 +952,11 @@ 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); -static u16 sendcommand(struct airo_info *ai, Cmd *pCmd); -static void completecommand(struct airo_info *ai, Resp *pRsp); static int bap_setup(struct airo_info*, u16 rid, u16 offset, int whichbap); static int aux_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen, int whichbap); @@ -944,20 +965,23 @@ 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); -static void airo_interrupt( int irq, void* dev_id, struct pt_regs +static irqreturn_t airo_interrupt( int irq, void* dev_id, struct pt_regs *regs); +static int airo_thread(void *data); +static void timer_func( struct net_device *dev ); static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); #ifdef WIRELESS_EXT struct iw_statistics *airo_get_wireless_stats (struct net_device *dev); +static void airo_read_wireless_stats (struct airo_info *local); #endif /* WIRELESS_EXT */ #ifdef CISCO_EXT static int readrids(struct net_device *dev, aironet_ioctl *comp); @@ -965,10 +989,12 @@ int flashcard(struct net_device *dev, aironet_ioctl *comp); #endif /* CISCO_EXT */ #ifdef MICSUPPORT -static void micinit(struct airo_info *ai, MICRid *micr); -static void micsetup(struct airo_info *ai); +static void micinit(struct airo_info *ai); +static int micsetup(struct airo_info *ai); static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len); static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen); + +#include #endif struct airo_info { @@ -976,7 +1002,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; @@ -984,48 +1010,67 @@ int need_commit; // Need to set config char keyindex; // Used with auto wep char defindex; // Used with auto wep - struct timer_list timer; struct proc_dir_entry *proc_entry; struct airo_info *next; spinlock_t aux_lock; unsigned long flags; -#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_PROMISC 8 /* IFF_PROMISC 0x100 - include/linux/if.h */ +#define FLAG_RADIO_OFF 0 /* User disabling of MAC */ +#define FLAG_RADIO_DOWN 1 /* ifup/ifdown disabling of MAC */ +#define FLAG_RADIO_MASK 0x03 +#define FLAG_FLASHING 2 +#define FLAG_ADHOC 3 /* Needed by MIC */ +#define FLAG_MIC_CAPABLE 4 +#define FLAG_UPDATE_MULTI 5 +#define FLAG_UPDATE_UNI 6 +#define FLAG_802_11 7 +#define FLAG_PENDING_XMIT 9 +#define FLAG_PENDING_XMIT11 10 +#define FLAG_PCI 11 +#define JOB_MASK 0x1ff0000 +#define JOB_DIE 16 +#define JOB_XMIT 17 +#define JOB_XMIT11 18 +#define JOB_STATS 19 +#define JOB_PROMISC 20 +#define JOB_MIC 21 +#define JOB_EVENT 22 +#define JOB_AUTOWEP 23 +#define JOB_WSTATS 24 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 promisc_task; + struct semaphore sem; + pid_t thr_pid; + wait_queue_head_t thr_wait; + struct completion thr_exited; + unsigned long expires; struct { struct sk_buff *skb; int fid; - struct tq_struct task; } xmit, xmit11; struct net_device *wifidev; #ifdef WIRELESS_EXT struct iw_statistics wstats; // wireless stats unsigned long scan_timestamp; /* Time started to scan */ - struct tq_struct event_task; +#if WIRELESS_EXT > 15 + struct iw_spy_data spy_data; +#else /* WIRELESS_EXT > 15 */ #ifdef WIRELESS_SPY int spy_number; u_char spy_address[IW_MAX_SPY][ETH_ALEN]; struct iw_quality spy_stat[IW_MAX_SPY]; #endif /* WIRELESS_SPY */ +#endif /* WIRELESS_EXT > 15 */ #endif /* WIRELESS_EXT */ +#ifdef MICSUPPORT /* MIC stuff */ + struct crypto_tfm *tfm; mic_module mod[2]; mic_statistics micstats; - struct tq_struct mic_task; +#endif }; static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen, @@ -1039,7 +1084,463 @@ struct airo_info *apriv ); #ifdef MICSUPPORT -#include "mic.h" +/*********************************************************************** + * MIC ROUTINES * + *********************************************************************** + */ + +static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq); +static void MoveWindow(miccntx *context, u32 micSeq); +void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *); +void emmh32_init(emmh32_context *context); +void emmh32_update(emmh32_context *context, u8 *pOctets, int len); +void emmh32_final(emmh32_context *context, u8 digest[4]); + +/* micinit - Initialize mic seed */ + +static void micinit(struct airo_info *ai) +{ + MICRid mic_rid; + + clear_bit(JOB_MIC, &ai->flags); + PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0); + up(&ai->sem); + + ai->micstats.enabled = (mic_rid.state & 0x00FF) ? 1 : 0; + + if (ai->micstats.enabled) { + /* Key must be valid and different */ + if (mic_rid.multicastValid && (!ai->mod[0].mCtx.valid || + (memcmp (ai->mod[0].mCtx.key, mic_rid.multicast, + sizeof(ai->mod[0].mCtx.key)) != 0))) { + /* Age current mic Context */ + memcpy(&ai->mod[1].mCtx,&ai->mod[0].mCtx,sizeof(miccntx)); + /* Initialize new context */ + memcpy(&ai->mod[0].mCtx.key,mic_rid.multicast,sizeof(mic_rid.multicast)); + ai->mod[0].mCtx.window = 33; //Window always points to the middle + ai->mod[0].mCtx.rx = 0; //Rx Sequence numbers + ai->mod[0].mCtx.tx = 0; //Tx sequence numbers + ai->mod[0].mCtx.valid = 1; //Key is now valid + + /* Give key to mic seed */ + emmh32_setseed(&ai->mod[0].mCtx.seed,mic_rid.multicast,sizeof(mic_rid.multicast), ai->tfm); + } + + /* Key must be valid and different */ + if (mic_rid.unicastValid && (!ai->mod[0].uCtx.valid || + (memcmp(ai->mod[0].uCtx.key, mic_rid.unicast, + sizeof(ai->mod[0].uCtx.key)) != 0))) { + /* Age current mic Context */ + memcpy(&ai->mod[1].uCtx,&ai->mod[0].uCtx,sizeof(miccntx)); + /* Initialize new context */ + memcpy(&ai->mod[0].uCtx.key,mic_rid.unicast,sizeof(mic_rid.unicast)); + + ai->mod[0].uCtx.window = 33; //Window always points to the middle + ai->mod[0].uCtx.rx = 0; //Rx Sequence numbers + ai->mod[0].uCtx.tx = 0; //Tx sequence numbers + ai->mod[0].uCtx.valid = 1; //Key is now valid + + //Give key to mic seed + emmh32_setseed(&ai->mod[0].uCtx.seed, mic_rid.unicast, sizeof(mic_rid.unicast), ai->tfm); + } + } else { + /* So next time we have a valid key and mic is enabled, we will update + * the sequence number if the key is the same as before. + */ + ai->mod[0].uCtx.valid = 0; + ai->mod[0].mCtx.valid = 0; + } +} + +/* micsetup - Get ready for business */ + +static int micsetup(struct airo_info *ai) { + int i; + + if (ai->tfm == NULL) + ai->tfm = crypto_alloc_tfm("aes", 0); + + if (ai->tfm == NULL) { + printk(KERN_ERR "airo: failed to load transform for AES\n"); + return ERROR; + } + + for (i=0; i < NUM_MODULES; i++) { + memset(&ai->mod[i].mCtx,0,sizeof(miccntx)); + memset(&ai->mod[i].uCtx,0,sizeof(miccntx)); + } + return SUCCESS; +} + +char micsnap[]= {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02}; + +/*=========================================================================== + * Description: Mic a packet + * + * Inputs: etherHead * pointer to an 802.3 frame + * + * Returns: BOOLEAN if successful, otherwise false. + * PacketTxLen will be updated with the mic'd packets size. + * + * Caveats: It is assumed that the frame buffer will already + * be big enough to hold the largets mic message possible. + * (No memory allocation is done here). + * + * Author: sbraneky (10/15/01) + * Merciless hacks by rwilcher (1/14/02) + */ + +static int encapsulate(struct airo_info *ai ,etherHead *frame, MICBuffer *mic, int payLen) +{ + miccntx *context; + + // Determine correct context + // If not adhoc, always use unicast key + + if (test_bit(FLAG_ADHOC, &ai->flags) && (frame->da[0] & 0x1)) + context = &ai->mod[0].mCtx; + else + context = &ai->mod[0].uCtx; + + if (!context->valid) + return ERROR; + + mic->typelen = htons(payLen + 16); //Length of Mic'd packet + + memcpy(&mic->u.snap, micsnap, sizeof(micsnap)); // Add Snap + + // Add Tx sequence + mic->seq = htonl(context->tx); + context->tx += 2; + + emmh32_init(&context->seed); // Mic the packet + emmh32_update(&context->seed,frame->da,ETH_ALEN * 2); // DA,SA + emmh32_update(&context->seed,(u8*)&mic->typelen,10); // Type/Length and Snap + emmh32_update(&context->seed,(u8*)&mic->seq,sizeof(mic->seq)); //SEQ + emmh32_update(&context->seed,frame->da + ETH_ALEN * 2,payLen); //payload + emmh32_final(&context->seed, (u8*)&mic->mic); + + /* New Type/length ?????????? */ + mic->typelen = 0; //Let NIC know it could be an oversized packet + return SUCCESS; +} + +typedef enum { + NONE, + NOMIC, + NOMICPLUMMED, + SEQUENCE, + INCORRECTMIC, +} mic_error; + +/*=========================================================================== + * Description: Decapsulates a MIC'd packet and returns the 802.3 packet + * (removes the MIC stuff) if packet is a valid packet. + * + * Inputs: etherHead pointer to the 802.3 packet + * + * Returns: BOOLEAN - TRUE if packet should be dropped otherwise FALSE + * + * Author: sbraneky (10/15/01) + * Merciless hacks by rwilcher (1/14/02) + *--------------------------------------------------------------------------- + */ + +static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *eth, u16 payLen) +{ + int i; + u32 micSEQ; + miccntx *context; + u8 digest[4]; + mic_error micError = NONE; + + // Check if the packet is a Mic'd packet + + if (!ai->micstats.enabled) { + //No Mic set or Mic OFF but we received a MIC'd packet. + if (memcmp ((u8*)eth + 14, micsnap, sizeof(micsnap)) == 0) { + ai->micstats.rxMICPlummed++; + return ERROR; + } + return SUCCESS; + } + + if (ntohs(mic->typelen) == 0x888E) + return SUCCESS; + + if (memcmp (mic->u.snap, micsnap, sizeof(micsnap)) != 0) { + // Mic enabled but packet isn't Mic'd + ai->micstats.rxMICPlummed++; + return ERROR; + } + + micSEQ = ntohl(mic->seq); //store SEQ as CPU order + + //At this point we a have a mic'd packet and mic is enabled + //Now do the mic error checking. + + //Receive seq must be odd + if ( (micSEQ & 1) == 0 ) { + ai->micstats.rxWrongSequence++; + return ERROR; + } + + for (i = 0; i < NUM_MODULES; i++) { + int mcast = eth->da[0] & 1; + //Determine proper context + context = mcast ? &ai->mod[i].mCtx : &ai->mod[i].uCtx; + + //Make sure context is valid + if (!context->valid) { + if (i == 0) + micError = NOMICPLUMMED; + continue; + } + //DeMic it + + if (!mic->typelen) + mic->typelen = htons(payLen + sizeof(MICBuffer) - 2); + + emmh32_init(&context->seed); + emmh32_update(&context->seed, eth->da, ETH_ALEN*2); + emmh32_update(&context->seed, (u8 *)&mic->typelen, sizeof(mic->typelen)+sizeof(mic->u.snap)); + emmh32_update(&context->seed, (u8 *)&mic->seq,sizeof(mic->seq)); + emmh32_update(&context->seed, eth->da + ETH_ALEN*2,payLen); + //Calculate MIC + emmh32_final(&context->seed, digest); + + if (memcmp(digest, &mic->mic, 4)) { //Make sure the mics match + //Invalid Mic + if (i == 0) + micError = INCORRECTMIC; + continue; + } + + //Check Sequence number if mics pass + if (RxSeqValid(ai, context, mcast, micSEQ) == SUCCESS) { + ai->micstats.rxSuccess++; + return SUCCESS; + } + if (i == 0) + micError = SEQUENCE; + } + + // Update statistics + switch (micError) { + case NOMICPLUMMED: ai->micstats.rxMICPlummed++; break; + case SEQUENCE: ai->micstats.rxWrongSequence++; break; + case INCORRECTMIC: ai->micstats.rxIncorrectMIC++; break; + case NONE: break; + case NOMIC: break; + } + return ERROR; +} + +/*=========================================================================== + * Description: Checks the Rx Seq number to make sure it is valid + * and hasn't already been received + * + * Inputs: miccntx - mic context to check seq against + * micSeq - the Mic seq number + * + * Returns: TRUE if valid otherwise FALSE. + * + * Author: sbraneky (10/15/01) + * Merciless hacks by rwilcher (1/14/02) + *--------------------------------------------------------------------------- + */ + +static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq) +{ + u32 seq,index; + + //Allow for the ap being rebooted - if it is then use the next + //sequence number of the current sequence number - might go backwards + + if (mcast) { + if (test_bit(FLAG_UPDATE_MULTI, &ai->flags)) { + clear_bit (FLAG_UPDATE_MULTI, &ai->flags); + context->window = (micSeq > 33) ? micSeq : 33; + context->rx = 0; // Reset rx + } + } else if (test_bit(FLAG_UPDATE_UNI, &ai->flags)) { + clear_bit (FLAG_UPDATE_UNI, &ai->flags); + context->window = (micSeq > 33) ? micSeq : 33; // Move window + context->rx = 0; // Reset rx + } + + //Make sequence number relative to START of window + seq = micSeq - (context->window - 33); + + //Too old of a SEQ number to check. + if ((u32)seq < 0) + return ERROR; + + if ( seq > 64 ) { + //Window is infinite forward + MoveWindow(context,micSeq); + return SUCCESS; + } + + // We are in the window. Now check the context rx bit to see if it was already sent + seq >>= 1; //divide by 2 because we only have odd numbers + index = 1 << seq; //Get an index number + + if (!(context->rx & index)) { + //micSEQ falls inside the window. + //Add seqence number to the list of received numbers. + context->rx |= index; + + MoveWindow(context,micSeq); + + return SUCCESS; + } + return ERROR; +} + +static void MoveWindow(miccntx *context, u32 micSeq) +{ + u32 shift; + + //Move window if seq greater than the middle of the window + if (micSeq > context->window) { + shift = (micSeq - context->window) >> 1; + + //Shift out old + if (shift < 32) + context->rx >>= shift; + else + context->rx = 0; + + context->window = micSeq; //Move window + } +} + +/*==============================================*/ +/*========== EMMH ROUTINES ====================*/ +/*==============================================*/ + +/* mic accumulate */ +#define MIC_ACCUM(val) \ + context->accum += (u64)(val) * context->coeff[coeff_position++]; + +static unsigned char aes_counter[16]; + +/* expand the key to fill the MMH coefficient array */ +void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *tfm) +{ + /* take the keying material, expand if necessary, truncate at 16-bytes */ + /* run through AES counter mode to generate context->coeff[] */ + + int i,j; + u32 counter; + u8 *cipher, plain[16]; + struct scatterlist sg[1]; + + crypto_cipher_setkey(tfm, pkey, 16); + counter = 0; + for (i = 0; i < (sizeof(context->coeff)/sizeof(context->coeff[0])); ) { + aes_counter[15] = (u8)(counter >> 0); + aes_counter[14] = (u8)(counter >> 8); + aes_counter[13] = (u8)(counter >> 16); + aes_counter[12] = (u8)(counter >> 24); + counter++; + memcpy (plain, aes_counter, 16); + sg[0].page = virt_to_page(plain); + sg[0].offset = ((long) plain & ~PAGE_MASK); + sg[0].length = 16; + crypto_cipher_encrypt(tfm, sg, sg, 16); + cipher = kmap(sg[0].page) + sg[0].offset; + for (j=0; (j<16) && (i< (sizeof(context->coeff)/sizeof(context->coeff[0]))); ) { + context->coeff[i++] = ntohl(*(u32 *)&cipher[j]); + j += 4; + } + } +} + +/* prepare for calculation of a new mic */ +void emmh32_init(emmh32_context *context) +{ + /* prepare for new mic calculation */ + context->accum = 0; + context->position = 0; +} + +/* add some bytes to the mic calculation */ +void emmh32_update(emmh32_context *context, u8 *pOctets, int len) +{ + int coeff_position, byte_position; + + if (len == 0) return; + + coeff_position = context->position >> 2; + + /* deal with partial 32-bit word left over from last update */ + byte_position = context->position & 3; + if (byte_position) { + /* have a partial word in part to deal with */ + do { + if (len == 0) return; + context->part.d8[byte_position++] = *pOctets++; + context->position++; + len--; + } while (byte_position < 4); + MIC_ACCUM(htonl(context->part.d32)); + } + + /* deal with full 32-bit words */ + while (len >= 4) { + MIC_ACCUM(htonl(*(u32 *)pOctets)); + context->position += 4; + pOctets += 4; + len -= 4; + } + + /* deal with partial 32-bit word that will be left over from this update */ + byte_position = 0; + while (len > 0) { + context->part.d8[byte_position++] = *pOctets++; + context->position++; + len--; + } +} + +/* mask used to zero empty bytes for final partial word */ +static u32 mask32[4] = { 0x00000000L, 0xFF000000L, 0xFFFF0000L, 0xFFFFFF00L }; + +/* calculate the mic */ +void emmh32_final(emmh32_context *context, u8 digest[4]) +{ + int coeff_position, byte_position; + u32 val; + + u64 sum, utmp; + s64 stmp; + + coeff_position = context->position >> 2; + + /* deal with partial 32-bit word left over from last update */ + byte_position = context->position & 3; + if (byte_position) { + /* have a partial word in part to deal with */ + val = htonl(context->part.d32); + MIC_ACCUM(val & mask32[byte_position]); /* zero empty bytes */ + } + + /* reduce the accumulated u64 to a 32-bit MIC */ + sum = context->accum; + stmp = (sum & 0xffffffffLL) - ((sum >> 32) * 15); + utmp = (stmp & 0xffffffffLL) - ((stmp >> 32) * 15); + sum = utmp & 0xffffffffLL; + if (utmp > 0x10000000fLL) + sum -= 15; + + val = (u32)sum; + digest[0] = (val>>24) & 0xFF; + digest[1] = (val>>16) & 0xFF; + digest[2] = (val>>8) & 0xFF; + digest[3] = val & 0xFF; +} #endif static int readBSSListRid(struct airo_info *ai, int first, @@ -1062,7 +1563,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 +1578,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 +1587,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 +1607,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 +1624,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 +1635,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 +1664,7 @@ } } } -static int writeConfigRid(struct airo_info*ai) { +static int writeConfigRid(struct airo_info*ai, int lock) { u16 *s; ConfigRid cfgr; @@ -1172,12 +1673,12 @@ ai->need_commit = 0; checkThrottle(ai); + cfgr = ai->config; + if ((cfgr.opmode & 0xFF) == MODE_STA_IBSS) - ai->flags |= FLAG_ADHOC; + set_bit(FLAG_ADHOC, &ai->flags); else - ai->flags &= ~FLAG_ADHOC; - - cfgr = ai->config; + clear_bit(FLAG_ADHOC, &ai->flags); for(s = &cfgr.len; s <= &cfgr.rtsThres; s++) *s = cpu_to_le16(*s); @@ -1190,33 +1691,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)); +static int readStatusRid(struct airo_info*ai, StatusRid *statr, int lock) { + int rc = PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr), lock); 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 +1729,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); @@ -1240,7 +1742,7 @@ struct airo_info *info = dev->priv; Resp rsp; - if (info->flags & FLAG_FLASHING) + if (test_bit(FLAG_FLASHING, &info->flags)) return -EIO; /* Make sure the card is configured. @@ -1248,16 +1750,16 @@ * 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) { /* Power on the MAC controller (which may have been disabled) */ - info->flags &= ~FLAG_RADIO_DOWN; + clear_bit(FLAG_RADIO_DOWN, &info->flags); enable_interrupts(info); } - enable_MAC(info, &rsp); + enable_MAC(info, &rsp, 1); netif_start_queue(dev); return 0; @@ -1312,7 +1814,7 @@ } } -static void airo_do_xmit(struct net_device *dev) { +static void airo_end_xmit(struct net_device *dev) { u16 status; int i; struct airo_info *priv = dev->priv; @@ -1320,13 +1822,8 @@ int fid = priv->xmit.fid; u32 *fids = priv->fids; - if (down_trylock(&priv->sem) != 0) { - netif_stop_queue(dev); - priv->xmit.task.routine = (void (*)(void *))airo_do_xmit; - priv->xmit.task.data = (void *)dev; - schedule_task(&priv->xmit.task); - return; - } + clear_bit(JOB_XMIT, &priv->flags); + clear_bit(FLAG_PENDING_XMIT, &priv->flags); status = transmit_802_3_packet (priv, fids[fid], skb->data); up(&priv->sem); @@ -1340,14 +1837,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,23 +1853,33 @@ /* 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; + if (down_trylock(&priv->sem) != 0) { + set_bit(FLAG_PENDING_XMIT, &priv->flags); + netif_stop_queue(dev); + set_bit(JOB_XMIT, &priv->flags); + wake_up_interruptible(&priv->thr_wait); + } else + airo_end_xmit(dev); return 0; } -static void airo_do_xmit11(struct net_device *dev) { +static void airo_end_xmit11(struct net_device *dev) { u16 status; int i; struct airo_info *priv = dev->priv; @@ -1382,13 +1887,8 @@ int fid = priv->xmit11.fid; u32 *fids = priv->fids; - if (down_trylock(&priv->sem) != 0) { - netif_stop_queue(dev); - priv->xmit11.task.routine = (void (*)(void *))airo_do_xmit11; - priv->xmit11.task.data = (void *)dev; - schedule_task(&priv->xmit11.task); - return; - } + clear_bit(JOB_XMIT11, &priv->flags); + clear_bit(FLAG_PENDING_XMIT11, &priv->flags); status = transmit_802_11_packet (priv, fids[fid], skb->data); up(&priv->sem); @@ -1402,14 +1902,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,84 +1918,92 @@ /* 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; + if (down_trylock(&priv->sem) != 0) { + set_bit(FLAG_PENDING_XMIT11, &priv->flags); + netif_stop_queue(dev); + set_bit(JOB_XMIT11, &priv->flags); + wake_up_interruptible(&priv->thr_wait); + } else + airo_end_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); + clear_bit(JOB_STATS, &ai->flags); + 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]; + 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: */ - 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]; - - return &local->stats; + 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]; } -static void airo_end_promisc(struct airo_info *ai) { - Resp rsp; +struct net_device_stats *airo_get_stats(struct net_device *dev) +{ + struct airo_info *local = dev->priv; - if ((IN4500(ai, EVSTAT) & EV_CMD) != 0) { - completecommand(ai, &rsp); - up(&ai->sem); - } else { - ai->promisc_task.routine = (void (*)(void *))airo_end_promisc; - ai->promisc_task.data = (void *)ai; - schedule_task(&ai->promisc_task); - } + /* Get stats out of the card if available */ + if (down_trylock(&local->sem) != 0) { + set_bit(JOB_STATS, &local->flags); + wake_up_interruptible(&local->thr_wait); + } else + airo_read_stats(local); + + return &local->stats; } static void airo_set_promisc(struct airo_info *ai) { Cmd cmd; + Resp rsp; - if (down_trylock(&ai->sem) == 0) { - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd=CMD_SETMODE; - cmd.parm0=(ai->flags&IFF_PROMISC) ? PROMISC : NOPROMISC; - sendcommand(ai, &cmd); - airo_end_promisc(ai); - } else { - ai->promisc_task.routine = (void (*)(void *))airo_set_promisc; - ai->promisc_task.data = (void *)ai; - schedule_task(&ai->promisc_task); - } + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd=CMD_SETMODE; + clear_bit(JOB_PROMISC, &ai->flags); + cmd.parm0=(ai->flags&IFF_PROMISC) ? PROMISC : NOPROMISC; + issuecommand(ai, &cmd, &rsp); + up(&ai->sem); } static void airo_set_multicast_list(struct net_device *dev) { struct airo_info *ai = dev->priv; if ((dev->flags ^ ai->flags) & IFF_PROMISC) { - ai->flags ^= IFF_PROMISC; - airo_set_promisc(ai); + change_bit(FLAG_PROMISC, &ai->flags); + if (down_trylock(&ai->sem) != 0) { + set_bit(JOB_PROMISC, &ai->flags); + wake_up_interruptible(&ai->thr_wait); + } else + airo_set_promisc(ai); } if ((dev->flags&IFF_ALLMULTI)||dev->mc_count>0) { @@ -1511,11 +2017,12 @@ struct sockaddr *addr = p; Resp rsp; + readConfigRid(ai, 1); 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); @@ -1543,8 +2050,8 @@ * That's the method that is most friendly towards the network * 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); + set_bit(FLAG_RADIO_DOWN, &ai->flags); + disable_MAC(ai, 1); #endif disable_interrupts( ai ); } @@ -1556,30 +2063,35 @@ void stop_airo_card( struct net_device *dev, int freeres ) { struct airo_info *ai = dev->priv; - flush_scheduled_tasks(); - if (ai->flash) - kfree(ai->flash); - if (ai->rssi) - kfree(ai->rssi); + disable_interrupts(ai); + free_irq( dev->irq, dev ); takedown_proc_entry( dev, ai ); if (ai->registered) { unregister_netdev( dev ); if (ai->wifidev) { unregister_netdev(ai->wifidev); - kfree(ai->wifidev); + free_netdev(ai->wifidev); ai->wifidev = 0; } ai->registered = 0; } - disable_interrupts(ai); - free_irq( dev->irq, dev ); - if (auto_wep) del_timer_sync(&ai->timer); + set_bit(JOB_DIE, &ai->flags); + kill_proc(ai->thr_pid, SIGTERM, 1); + wait_for_completion(&ai->thr_exited); + if (ai->flash) + kfree(ai->flash); + if (ai->rssi) + kfree(ai->rssi); if (freeres) { /* PCMCIA frees this stuff, so only for PCI and ISA */ release_region( dev->base_addr, 64 ); } +#ifdef MICSUPPORT + if (ai->tfm) + crypto_free_tfm(ai->tfm); +#endif del_airo_dev( dev ); - kfree( dev ); + free_netdev( dev ); } EXPORT_SYMBOL(stop_airo_card); @@ -1674,9 +2186,17 @@ sema_init(&ai->sem, 1); ai->need_commit = 0; ai->config.len = 0; + init_waitqueue_head (&ai->thr_wait); + init_completion (&ai->thr_exited); + ai->thr_pid = kernel_thread(airo_thread, dev, CLONE_FS | CLONE_FILES); + if (ai->thr_pid < 0) + goto err_out_free; +#ifdef MICSUPPORT + ai->tfm = NULL; +#endif rc = add_airo_dev( dev ); if (rc) - goto err_out_free; + goto err_out_thr; /* The Airo-specific entries in the device structure. */ dev->hard_start_xmit = &airo_start_xmit; @@ -1716,7 +2236,7 @@ } } else { ai->bap_read = fast_bap_read; - ai->flags |= FLAG_FLASHING; + set_bit(FLAG_FLASHING, &ai->flags); } rc = register_netdev(dev); @@ -1747,6 +2267,10 @@ free_irq(dev->irq, dev); err_out_unlink: del_airo_dev(dev); +err_out_thr: + set_bit(JOB_DIE, &ai->flags); + kill_proc(ai->thr_pid, SIGTERM, 1); + wait_for_completion(&ai->thr_exited); err_out_free: kfree(dev); return NULL; @@ -1768,6 +2292,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 +2304,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 +2322,7 @@ } enable_interrupts( ai ); netif_wake_queue(dev); + up(&ai->sem); return 0; } @@ -1805,58 +2334,129 @@ union iwreq_data wrqu; 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); - up(&ai->sem); - wrqu.data.length = 0; - wrqu.data.flags = 0; - memcpy(wrqu.ap_addr.sa_data, status_rid.bssid[0], ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; + clear_bit(JOB_EVENT, &ai->flags); + PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid), 0); + up(&ai->sem); + wrqu.data.length = 0; + wrqu.data.flags = 0; + memcpy(wrqu.ap_addr.sa_data, status_rid.bssid[0], ETH_ALEN); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; - /* Send event to user space */ - wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); - } else { - ai->event_task.routine = (void (*)(void *))airo_send_event; - ai->event_task.data = (void *)dev; - schedule_task(&ai->event_task); - } + /* Send event to user space */ + wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); } #endif -static void airo_read_mic(struct airo_info *ai) { - MICRid mic_rid; +static int airo_thread(void *data) { + struct net_device *dev = data; + struct airo_info *ai = dev->priv; + int locked; + + daemonize(); + reparent_to_init(); + spin_lock_irq(¤t->sigmask_lock); + sigemptyset(¤t->blocked); + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + + strncpy (current->comm, dev->name, sizeof(current->comm) - 1); + current->comm[sizeof(current->comm) - 1] = '\0'; + + while(1) { + if (signal_pending(current)) { + spin_lock_irq(¤t->sigmask_lock); + flush_signals(current); + spin_unlock_irq(¤t->sigmask_lock); + } - 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); - up(&ai->sem); + if (test_bit(JOB_DIE, &ai->flags)) + break; + + if (ai->flags & JOB_MASK) { + locked = down_interruptible(&ai->sem); + } else { + wait_queue_t wait; + + init_waitqueue_entry(&wait, current); + add_wait_queue(&ai->thr_wait, &wait); + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + if (ai->flags & JOB_MASK) + break; + if (ai->expires) { + if (time_after_eq(jiffies,ai->expires)){ + set_bit(JOB_AUTOWEP,&ai->flags); + break; + } + if (!signal_pending(current)) { + schedule_timeout(ai->expires - jiffies); + continue; + } + } else if (!signal_pending(current)) { + schedule(); + continue; + } + break; + } + current->state = TASK_RUNNING; + remove_wait_queue(&ai->thr_wait, &wait); + locked = 1; + } + + if (locked) + continue; + + if (test_bit(JOB_DIE, &ai->flags)) { + up(&ai->sem); + break; + } + + if (test_bit(FLAG_FLASHING, &ai->flags)) { + up(&ai->sem); + continue; + } + + if (test_bit(JOB_XMIT, &ai->flags)) + airo_end_xmit(dev); + else if (test_bit(JOB_XMIT11, &ai->flags)) + airo_end_xmit11(dev); + else if (test_bit(JOB_STATS, &ai->flags)) + airo_read_stats(ai); + else if (test_bit(JOB_WSTATS, &ai->flags)) + airo_read_wireless_stats(ai); + else if (test_bit(JOB_PROMISC, &ai->flags)) + airo_set_promisc(ai); #ifdef MICSUPPORT - micinit (ai, &mic_rid); + else if (test_bit(JOB_MIC, &ai->flags)) + micinit(ai); #endif - } else { - ai->mic_task.routine = (void (*)(void *))airo_read_mic; - ai->mic_task.data = (void *)ai; - schedule_task(&ai->mic_task); +#if WIRELESS_EXT > 13 + else if (test_bit(JOB_EVENT, &ai->flags)) + airo_send_event(dev); +#endif + else if (test_bit(JOB_AUTOWEP, &ai->flags)) + timer_func(dev); } + complete_and_exit (&ai->thr_exited, 0); } -static void airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) { +static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; u16 status; u16 fid; struct airo_info *apriv = dev->priv; u16 savedInterrupts = 0; + int handled = 0; if (!netif_device_present(dev)) - return; + return IRQ_NONE; for (;;) { status = IN4500( apriv, EVSTAT ); if ( !(status & STATUS_INTS) || status == 0xffff ) break; + handled = 1; + if ( status & EV_AWAKE ) { OUT4500( apriv, EVACK, EV_AWAKE ); OUT4500( apriv, EVACK, EV_AWAKE ); @@ -1869,7 +2469,12 @@ if ( status & EV_MIC ) { OUT4500( apriv, EVACK, EV_MIC ); - airo_read_mic( apriv ); +#ifdef MICSUPPORT + if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) { + set_bit(JOB_MIC, &apriv->flags); + wake_up_interruptible(&apriv->thr_wait); + } +#endif } if ( status & EV_LINK ) { #if WIRELESS_EXT > 13 @@ -1911,15 +2516,18 @@ #define RC_NOAUTH 9 /* Station requesting (Re)Association is not Authenticated with the responding station */ if (newStatus != ASSOCIATED) { - if (auto_wep && !timer_pending(&apriv->timer)) { - apriv->timer.expires = RUN_AT(HZ*3); - add_timer(&apriv->timer); + if (auto_wep && !apriv->expires) { + apriv->expires = RUN_AT(3*HZ); + wake_up_interruptible(&apriv->thr_wait); } } else { struct task_struct *task = apriv->task; + if (auto_wep) + apriv->expires = 0; if (task) wake_up_process (task); - apriv->flags|=FLAG_UPDATE_UNI|FLAG_UPDATE_MULTI; + set_bit(FLAG_UPDATE_UNI, &apriv->flags); + set_bit(FLAG_UPDATE_MULTI, &apriv->flags); } #if WIRELESS_EXT > 13 /* Question : is ASSOCIATED the only status @@ -1940,7 +2548,11 @@ wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL); apriv->scan_timestamp = 0; } - airo_send_event(dev); + if (down_trylock(&apriv->sem) != 0) { + set_bit(JOB_EVENT, &apriv->flags); + wake_up_interruptible(&apriv->thr_wait); + } else + airo_send_event(dev); } else { memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN); wrqu.ap_addr.sa_family = ARPHRD_ETHER; @@ -1971,7 +2583,7 @@ fid = IN4500( apriv, RXFID ); /* Get the packet length */ - if (apriv->flags & FLAG_802_11) { + if (test_bit(FLAG_802_11, &apriv->flags)) { bap_setup (apriv, fid, 4, BAP0); bap_read (apriv, (u16*)&hdr, sizeof(hdr), BAP0); /* Bad CRC. Ignore packet */ @@ -1987,122 +2599,151 @@ if (len > 2312) { printk( KERN_ERR "airo: Bad size %d\n", len ); - len = 0; + goto badrx; } - if (len) { - if (apriv->flags & FLAG_802_11) { - bap_read (apriv, (u16*)&fc, sizeof(fc), BAP0); - fc = le16_to_cpu(fc); - switch (fc & 0xc) { - case 4: - if ((fc & 0xe0) == 0xc0) - hdrlen = 10; - else - hdrlen = 16; - break; - case 8: - if ((fc&0x300)==0x300){ - hdrlen = 30; - break; - } - default: - hdrlen = 24; - } - } else - hdrlen = ETH_ALEN * 2; + if (len == 0) + goto badrx; - skb = dev_alloc_skb( len + hdrlen + 2 ); - if ( !skb ) { - apriv->stats.rx_dropped++; - len = 0; - } - } - if (len) { - buffer = (u16*)skb_put (skb, len + hdrlen); - if (apriv->flags & FLAG_802_11) { - buffer[0] = fc; - bap_read (apriv, buffer + 1, hdrlen - 2, BAP0); - if (hdrlen == 24) - bap_read (apriv, tmpbuf, 6, BAP0); - - bap_read (apriv, &gap, sizeof(gap), BAP0); - gap = le16_to_cpu(gap); - if (gap) { - if (gap <= 8) - bap_read (apriv, tmpbuf, gap, BAP0); + if (test_bit(FLAG_802_11, &apriv->flags)) { + bap_read (apriv, (u16*)&fc, sizeof(fc), BAP0); + fc = le16_to_cpu(fc); + switch (fc & 0xc) { + case 4: + if ((fc & 0xe0) == 0xc0) + hdrlen = 10; else - printk(KERN_ERR "airo: gaplen too big. Problems will follow...\n"); - } + hdrlen = 16; + break; + case 8: + if ((fc&0x300)==0x300){ + hdrlen = 30; + break; + } + default: + hdrlen = 24; + } + } else + hdrlen = ETH_ALEN * 2; + skb = dev_alloc_skb( len + hdrlen + 2 ); + if ( !skb ) { + apriv->stats.rx_dropped++; + goto badrx; + } + buffer = (u16*)skb_put (skb, len + hdrlen); + if (test_bit(FLAG_802_11, &apriv->flags)) { + buffer[0] = fc; + bap_read (apriv, buffer + 1, hdrlen - 2, BAP0); + if (hdrlen == 24) + bap_read (apriv, tmpbuf, 6, BAP0); + + bap_read (apriv, &gap, sizeof(gap), BAP0); + gap = le16_to_cpu(gap); + if (gap) { + if (gap <= 8) + bap_read (apriv, tmpbuf, gap, BAP0); + else + printk(KERN_ERR "airo: gaplen too big. Problems will follow...\n"); + } + bap_read (apriv, buffer + hdrlen/2, len, BAP0); + } else { +#ifdef MICSUPPORT + MICBuffer micbuf; +#endif + bap_read (apriv, buffer, ETH_ALEN*2, BAP0); +#ifdef MICSUPPORT + if (apriv->micstats.enabled) { + bap_read (apriv,(u16*)&micbuf,sizeof(micbuf),BAP0); + if (ntohs(micbuf.typelen) > 0x05DC) + bap_setup (apriv, fid, 0x44, BAP0); + else { + if (len <= sizeof(micbuf)) + goto badmic; - bap_read (apriv, buffer + hdrlen/2, len, BAP0); - } else { - MICBuffer micbuf; - bap_read (apriv, buffer, ETH_ALEN*2, BAP0); - if (apriv->micstats.enabled) { - bap_read (apriv,(u16*)&micbuf,sizeof(micbuf),BAP0); - if (ntohs(micbuf.typelen) > 0x05DC) - bap_setup (apriv, fid, 0x44, BAP0); - else { - len -= sizeof(micbuf); - if (len < 48) - len = 48; - skb_trim (skb, len + hdrlen); - } + len -= sizeof(micbuf); + skb_trim (skb, len + hdrlen); } - bap_read(apriv,buffer+ETH_ALEN,len,BAP0); + } +#endif + bap_read(apriv,buffer+ETH_ALEN,len,BAP0); #ifdef MICSUPPORT - if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) { - dev_kfree_skb_irq (skb); - len = 0; - } + if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) { +badmic: + dev_kfree_skb_irq (skb); +#else + if (0) { #endif +badrx: + OUT4500( apriv, EVACK, EV_RX); + goto exitrx; } } - 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 */ + if (!test_bit(FLAG_802_11, &apriv->flags)) { + sa = (char*)buffer + 6; + bap_setup (apriv, fid, 8, BAP0); + bap_read (apriv, (u16*)hdr.rssi, 2, BAP0); + } else + sa = (char*)buffer + 10; + 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; - char *sa; - - sa = (char*)buffer + ((apriv->flags & FLAG_802_11) ? 10 : 6); - - for (i=0; ispy_number; i++) - if (!memcmp(sa,apriv->spy_address[i],ETH_ALEN)) - { - if (!(apriv->flags & FLAG_802_11)) { - bap_setup (apriv, fid, 8, BAP0); - bap_read (apriv, (u16*)hdr.rssi, 2, BAP0); - } - apriv->spy_stat[i].qual = hdr.rssi[0]; - if (apriv->rssi) - apriv->spy_stat[i].level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm; - else - apriv->spy_stat[i].level = (hdr.rssi[1] + 321) / 2; - apriv->spy_stat[i].noise = 0; - apriv->spy_stat[i].updated = 3; - break; + if (apriv->spy_number > 0) { + int i; + char *sa; + + sa = (char*)buffer + (test_bit(FLAG_802_11, &apriv->flags) ? 10 : 6); + + for (i=0; ispy_number; i++) + if (!memcmp(sa,apriv->spy_address[i],ETH_ALEN)) + { + if (!test_bit(FLAG_802_11, &apriv->flags)) { + bap_setup (apriv, fid, 8, BAP0); + bap_read (apriv, (u16*)hdr.rssi, 2, BAP0); } - } + apriv->spy_stat[i].qual = hdr.rssi[0]; + if (apriv->rssi) + apriv->spy_stat[i].level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm; + else + apriv->spy_stat[i].level = (hdr.rssi[1] + 321) / 2; + apriv->spy_stat[i].noise = 0; + apriv->spy_stat[i].updated = 3; + break; + } + } #endif /* WIRELESS_SPY */ - OUT4500( apriv, EVACK, EV_RX); +#endif /* WIRELESS_EXT > 15 */ + OUT4500( apriv, EVACK, EV_RX); - if (apriv->flags & FLAG_802_11) { - skb->mac.raw = skb->data; - skb->pkt_type = PACKET_OTHERHOST; - skb->dev = apriv->wifidev; - skb->protocol = htons(ETH_P_802_2); - } else { - skb->dev = dev; - skb->protocol = eth_type_trans(skb,dev); - } - skb->dev->last_rx = jiffies; - skb->ip_summed = CHECKSUM_NONE; + if (test_bit(FLAG_802_11, &apriv->flags)) { + skb->mac.raw = skb->data; + skb->pkt_type = PACKET_OTHERHOST; + skb->dev = apriv->wifidev; + skb->protocol = htons(ETH_P_802_2); + } else { + skb->dev = dev; + skb->protocol = eth_type_trans(skb,dev); + } + skb->dev->last_rx = jiffies; + skb->ip_summed = CHECKSUM_NONE; - netif_rx( skb ); - } else - OUT4500( apriv, EVACK, EV_RX); + netif_rx( skb ); } +exitrx: /* Check to see if a packet has been transmitted */ if ( status & ( EV_TX|EV_TXEXC ) ) { @@ -2116,17 +2757,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 (!test_bit(FLAG_PENDING_XMIT, &apriv->flags)) + netif_wake_queue(dev); + } else { + if (!test_bit(FLAG_PENDING_XMIT11, &apriv->flags)) + 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" ); } } @@ -2139,7 +2786,7 @@ OUT4500( apriv, EVINTEN, savedInterrupts ); /* done.. */ - return; + return IRQ_RETVAL(handled); } /* @@ -2172,7 +2819,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; @@ -2182,10 +2829,10 @@ * instead of this flag, but I don't trust it *within* the * open/close functions, and testing both flags together is * "cheaper" - Jean II */ - if (ai->flags & (FLAG_RADIO_OFF|FLAG_RADIO_DOWN)) return SUCCESS; + if (ai->flags & FLAG_RADIO_MASK) 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 +2842,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 +2866,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 +2926,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); @@ -2301,12 +2948,14 @@ printk(KERN_WARNING "airo: unknown received signal level scale\n"); } ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS; + ai->config.authType = AUTH_OPEN; + ai->config.modulation = MOD_CCK; #ifdef MICSUPPORT - if ((cap_rid.len==sizeof(cap_rid)) && (cap_rid.extSoftCap&1)) { + if ((cap_rid.len>=sizeof(cap_rid)) && (cap_rid.extSoftCap&1) && + (micsetup(ai) == SUCCESS)) { ai->config.opmode |= MODE_MIC; - ai->flags |= FLAG_MIC_CAPABLE; - micsetup(ai); + set_bit(FLAG_MIC_CAPABLE, &ai->flags); } #endif @@ -2347,16 +2996,17 @@ memcpy(mySsid.ssids[i].ssid, ssids[i], mySsid.ssids[i].len); } + mySsid.len = sizeof(mySsid); } - 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; @@ -2372,34 +3022,15 @@ rc = readWepKeyRid(ai, &wkr, 0); } while(lastindex != wkr.kindex); - if (auto_wep && !timer_pending(&ai->timer)) { - ai->timer.expires = RUN_AT(HZ*3); - add_timer(&ai->timer); + if (auto_wep) { + ai->expires = RUN_AT(3*HZ); + wake_up_interruptible(&ai->thr_wait); } - return SUCCESS; -} - -static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) { - // Im really paranoid about letting it run forever! - int max_tries = 600000; - if (sendcommand(ai, pCmd) == (u16)ERROR) - return ERROR; - - while (max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0) { - if (!in_interrupt() && (max_tries & 255) == 0) - schedule(); - } - if ( max_tries == -1 ) { - printk( KERN_ERR - "airo: Max tries exceeded waiting for command\n" ); - return ERROR; - } - completecommand(ai, pRsp); return SUCCESS; } -static u16 sendcommand(struct airo_info *ai, Cmd *pCmd) { +static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) { // Im really paranoid about letting it run forever! int max_tries = 600000; u16 cmd; @@ -2418,10 +3049,16 @@ "airo: Max tries exceeded when issueing command\n" ); return ERROR; } - return SUCCESS; -} -static void completecommand(struct airo_info *ai, Resp *pRsp) { + while (max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0) { + if (!in_interrupt() && (max_tries & 255) == 0) + schedule(); + } + if ( max_tries == -1 ) { + printk( KERN_ERR + "airo: Max tries exceeded waiting for command\n" ); + return ERROR; + } // command completed pRsp->status = IN4500(ai, STATUS); pRsp->rsp0 = IN4500(ai, RESP0); @@ -2434,6 +3071,8 @@ } // acknowledge processing the status/response OUT4500(ai, EVACK, EV_CMD); + + return SUCCESS; } /* Sets up the bap to start exchange data. whichbap should @@ -2500,7 +3139,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 +3210,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 +3243,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 +3251,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 +3276,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 +3285,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 +3296,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,14 +3352,14 @@ len >>= 16; - if (len < ETH_ALEN * 2) { + if (len <= ETH_ALEN * 2) { printk( KERN_WARNING "Short packet %d\n", len ); return ERROR; } len -= ETH_ALEN * 2; #ifdef MICSUPPORT - if ((ai->flags & FLAG_MIC_CAPABLE) && ai->micstats.enabled && + if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled && (ntohs(((u16 *)pPacket)[6]) != 0x888E)) { if (encapsulate(ai,(etherHead *)pPacket,&pMic,len) != SUCCESS) return ERROR; @@ -2827,56 +3472,56 @@ static int proc_wepkey_open( struct inode *inode, struct file *file ); static struct file_operations proc_statsdelta_ops = { - read: proc_read, - open: proc_statsdelta_open, - release: proc_close + .read = proc_read, + .open = proc_statsdelta_open, + .release = proc_close }; static struct file_operations proc_stats_ops = { - read: proc_read, - open: proc_stats_open, - release: proc_close + .read = proc_read, + .open = proc_stats_open, + .release = proc_close }; static struct file_operations proc_status_ops = { - read: proc_read, - open: proc_status_open, - release: proc_close + .read = proc_read, + .open = proc_status_open, + .release = proc_close }; static struct file_operations proc_SSID_ops = { - read: proc_read, - write: proc_write, - open: proc_SSID_open, - release: proc_close + .read = proc_read, + .write = proc_write, + .open = proc_SSID_open, + .release = proc_close }; static struct file_operations proc_BSSList_ops = { - read: proc_read, - write: proc_write, - open: proc_BSSList_open, - release: proc_close + .read = proc_read, + .write = proc_write, + .open = proc_BSSList_open, + .release = proc_close }; static struct file_operations proc_APList_ops = { - read: proc_read, - write: proc_write, - open: proc_APList_open, - release: proc_close + .read = proc_read, + .write = proc_write, + .open = proc_APList_open, + .release = proc_close }; static struct file_operations proc_config_ops = { - read: proc_read, - write: proc_write, - open: proc_config_open, - release: proc_close + .read = proc_read, + .write = proc_write, + .open = proc_config_open, + .release = proc_close }; static struct file_operations proc_wepkey_ops = { - read: proc_read, - write: proc_write, - open: proc_wepkey_open, - release: proc_close + .read = proc_read, + .write = proc_write, + .open = proc_wepkey_open, + .release = proc_close }; static struct proc_dir_entry *airo_entry = 0; @@ -2904,6 +3549,7 @@ airo_entry); apriv->proc_entry->uid = proc_uid; apriv->proc_entry->gid = proc_gid; + apriv->proc_entry->owner = THIS_MODULE; /* Setup the StatsDelta */ entry = create_proc_entry("StatsDelta", @@ -2912,6 +3558,7 @@ entry->uid = proc_uid; entry->gid = proc_gid; entry->data = dev; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_statsdelta_ops); /* Setup the Stats */ @@ -2921,6 +3568,7 @@ entry->uid = proc_uid; entry->gid = proc_gid; entry->data = dev; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_stats_ops); /* Setup the Status */ @@ -2930,6 +3578,7 @@ entry->uid = proc_uid; entry->gid = proc_gid; entry->data = dev; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_status_ops); /* Setup the Config */ @@ -2939,6 +3588,7 @@ entry->uid = proc_uid; entry->gid = proc_gid; entry->data = dev; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_config_ops); /* Setup the SSID */ @@ -2948,6 +3598,7 @@ entry->uid = proc_uid; entry->gid = proc_gid; entry->data = dev; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_SSID_ops); /* Setup the APList */ @@ -2957,6 +3608,7 @@ entry->uid = proc_uid; entry->gid = proc_gid; entry->data = dev; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_APList_ops); /* Setup the BSSList */ @@ -2966,6 +3618,7 @@ entry->uid = proc_uid; entry->gid = proc_gid; entry->data = dev; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_BSSList_ops); /* Setup the WepKey */ @@ -2975,6 +3628,7 @@ entry->uid = proc_uid; entry->gid = proc_gid; entry->data = dev; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_wepkey_ops); return 0; @@ -3065,8 +3719,6 @@ StatusRid status_rid; int i; - MOD_INC_USE_COUNT; - if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; memset(file->private_data, 0, sizeof(struct proc_data)); @@ -3076,7 +3728,7 @@ return -ENOMEM; } - readStatusRid(apriv, &status_rid); + readStatusRid(apriv, &status_rid, 1); readCapabilityRid(apriv, &cap_rid); i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n", @@ -3146,8 +3798,6 @@ StatsRid stats; int i, j; int *vals = stats.vals; - MOD_INC_USE_COUNT; - if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; @@ -3158,10 +3808,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 +3843,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,20 +3865,23 @@ 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; + clear_bit (FLAG_802_11, &ai->flags); 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->flags |= FLAG_802_11; + ai->config.scanMode = SCANMODE_PASSIVE; + set_bit (FLAG_802_11, &ai->flags); } else if ( line[0] == 'y' ) { ai->config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER; - ai->flags |= FLAG_802_11; + ai->config.scanMode = SCANMODE_PASSIVE; + set_bit (FLAG_802_11, &ai->flags); } else if ( line[0] == 'l' ) ai->config.rmode |= RXMODE_LANMON; } @@ -3236,9 +3892,9 @@ else if (!strncmp(line,"Radio: ", 7)) { line += 7; if (!strncmp(line,"off",3)) { - ai->flags |= FLAG_RADIO_OFF; + set_bit (FLAG_RADIO_OFF, &ai->flags); } else { - ai->flags &= ~FLAG_RADIO_OFF; + clear_bit (FLAG_RADIO_OFF, &ai->flags); } } /*** NodeName processing */ @@ -3390,22 +4046,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) { @@ -3424,8 +4065,6 @@ struct airo_info *ai = dev->priv; int i; - MOD_INC_USE_COUNT; - if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; memset(file->private_data, 0, sizeof(struct proc_data)); @@ -3443,7 +4082,7 @@ data->maxwritelen = 2048; data->on_close = proc_config_on_close; - readConfigRid(ai); + readConfigRid(ai, 1); i = sprintf( data->rbuffer, "Mode: %s\n" @@ -3457,7 +4096,7 @@ (ai->config.opmode & 0xFF) == 1 ? get_rmode(ai->config.rmode): (ai->config.opmode & 0xFF) == 2 ? "AP" : (ai->config.opmode & 0xFF) == 3 ? "AP RPTR" : "Error", - ai->flags&FLAG_RADIO_OFF ? "off" : "on", + test_bit(FLAG_RADIO_OFF, &ai->flags) ? "off" : "on", ai->config.nodeName, ai->config.powerSaveMode == 0 ? "CAM" : ai->config.powerSaveMode == 1 ? "PSP" : @@ -3535,9 +4174,11 @@ offset < data->writelen ) offset++; offset++; } - disable_MAC(ai); + if (i) + SSID_rid.len = sizeof(SSID_rid); + 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 +4217,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 +4258,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 +4280,7 @@ printk(KERN_INFO "Setting key %d\n", index); } - writeWepKeyRid(ai, &wkr, perm); + writeWepKeyRid(ai, &wkr, perm, lock); return 0; } @@ -3662,7 +4303,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 +4322,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 ) { @@ -3695,8 +4336,6 @@ int j=0; int rc; - MOD_INC_USE_COUNT; - if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; memset(file->private_data, 0, sizeof(struct proc_data)); @@ -3745,8 +4384,6 @@ char *ptr; SsidRid SSID_rid; - MOD_INC_USE_COUNT; - if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; memset(file->private_data, 0, sizeof(struct proc_data)); @@ -3791,8 +4428,6 @@ char *ptr; APListRid APList_rid; - MOD_INC_USE_COUNT; - if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; memset(file->private_data, 0, sizeof(struct proc_data)); @@ -3843,8 +4478,6 @@ /* If doLoseSync is not 1, we won't do a Lose Sync */ int doLoseSync = -1; - MOD_INC_USE_COUNT; - if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; memset(file->private_data, 0, sizeof(struct proc_data)); @@ -3907,7 +4540,6 @@ { struct proc_data *data = (struct proc_data *)file->private_data; if ( data->on_close != NULL ) data->on_close( inode, file ); - MOD_DEC_USE_COUNT; if ( data->rbuffer ) kfree( data->rbuffer ); if ( data->wbuffer ) kfree( data->wbuffer ); kfree( data ); @@ -3924,53 +4556,41 @@ will switch WEP modes to see if that will help. If the card is associated we will check every minute to see if anything has changed. */ -static void timer_func( u_long data ) { - struct net_device *dev = (struct net_device*)data; +static void timer_func( struct net_device *dev ) { struct airo_info *apriv = dev->priv; - u16 linkstat = IN4500(apriv, LINKSTAT); Resp rsp; - if (!(apriv->flags & FLAG_FLASHING) && (linkstat != 0x400)) { /* We don't have a link so try changing the authtype */ - if (down_trylock(&apriv->sem) != 0) { - apriv->timer.expires = RUN_AT(1); - add_timer(&apriv->timer); - return; - } - __set_bit(FLAG_LOCKED, &apriv->flags); - - readConfigRid(apriv); - disable_MAC(apriv); - switch(apriv->config.authType) { + readConfigRid(apriv, 0); + disable_MAC(apriv, 0); + switch(apriv->config.authType) { case AUTH_ENCRYPT: /* So drop to OPEN */ apriv->config.authType = AUTH_OPEN; 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; default: /* We'll escalate to SHAREDKEY */ apriv->config.authType = AUTH_SHAREDKEY; - } - apriv->need_commit = 1; - writeConfigRid(apriv); - enable_MAC(apriv, &rsp); - clear_bit(FLAG_LOCKED, &apriv->flags); - up(&apriv->sem); + } + apriv->need_commit = 1; + writeConfigRid(apriv, 0); + enable_MAC(apriv, &rsp, 0); + up(&apriv->sem); /* Schedule check to see if the change worked */ - apriv->timer.expires = RUN_AT(HZ*3); - add_timer(&apriv->timer); - } + clear_bit(JOB_AUTOWEP, &apriv->flags); + apriv->expires = RUN_AT(HZ*3); } static int add_airo_dev( struct net_device *dev ) { @@ -3978,15 +4598,6 @@ if ( !node ) return -ENOMEM; - if ( auto_wep ) { - struct airo_info *apriv=dev->priv; - struct timer_list *timer = &apriv->timer; - - timer->function = timer_func; - timer->data = (u_long)dev; - init_timer(timer); - } - node->dev = dev; node->next = airo_devices; airo_devices = node; @@ -4017,6 +4628,7 @@ return -ENODEV; pci_set_drvdata(pdev, dev); + set_bit (FLAG_PCI, &((struct airo_info *)dev->priv)->flags); return 0; } @@ -4028,7 +4640,7 @@ static int __init airo_init_module( void ) { - int i, rc = 0, have_isa_dev = 0; + int i, have_isa_dev = 0; airo_entry = create_proc_entry("aironet", S_IFDIR | airo_perm, @@ -4046,7 +4658,7 @@ #ifdef CONFIG_PCI printk( KERN_INFO "airo: Probing for PCI adapters\n" ); - rc = pci_module_init(&airo_driver); + pci_module_init(&airo_driver); /* FIXME: check return val */ printk( KERN_INFO "airo: Finished probing for PCI adapters\n" ); #endif @@ -4058,11 +4670,22 @@ static void __exit airo_cleanup_module( void ) { + int is_pci = 0; while( airo_devices ) { printk( KERN_INFO "airo: Unregistering %s\n", airo_devices->dev->name ); +#ifdef CONFIG_PCI + if (test_bit(FLAG_PCI, &((struct airo_info *)airo_devices->dev->priv)->flags)) + is_pci = 1; +#endif stop_airo_card( airo_devices->dev, 1 ); } remove_proc_entry("aironet", proc_root_driver); + + if (is_pci) { +#ifdef CONFIG_PCI + pci_unregister_driver(&airo_driver); +#endif + } } #ifdef WIRELESS_EXT @@ -4124,6 +4747,7 @@ printk(KERN_DEBUG "%s: New channel value of %d is invalid!\n", dev->name, fwrq->m); rc = -EINVAL; } else { + readConfigRid(local, 1); /* Yes ! We can set it !!! */ local->config.channelSet = (u16)(channel - 1); local->need_commit = 1; @@ -4144,9 +4768,12 @@ struct airo_info *local = dev->priv; StatusRid status_rid; /* Card status info */ - readStatusRid(local, &status_rid); + readConfigRid(local, 1); + if ((local->config.opmode & 0xFF) == MODE_STA_ESS) + status_rid.channel = local->config.channelSet; + else + readStatusRid(local, &status_rid, 1); - /* Will return zero in infrastructure mode */ #ifdef WEXT_USECHANNELS fwrq->m = ((int)status_rid.channel) + 1; fwrq->e = 0; @@ -4198,11 +4825,12 @@ sizeof(SSID_rid.ssids[index].ssid)); memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length); SSID_rid.ssids[index].len = dwrq->length - 1; + SSID_rid.len = sizeof(SSID_rid); } /* 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; } @@ -4219,7 +4847,7 @@ struct airo_info *local = dev->priv; StatusRid status_rid; /* Card status info */ - readStatusRid(local, &status_rid); + readStatusRid(local, &status_rid, 1); /* Note : if dwrq->flags != 0, we should * get the relevant SSID from the SSID list... */ @@ -4264,9 +4892,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; } @@ -4283,7 +4911,7 @@ struct airo_info *local = dev->priv; StatusRid status_rid; /* Card status info */ - readStatusRid(local, &status_rid); + readStatusRid(local, &status_rid, 1); /* Tentative. This seems to work, wow, I'm lucky !!! */ memcpy(awrq->sa_data, status_rid.bssid[0], ETH_ALEN); @@ -4307,6 +4935,7 @@ if(dwrq->length > 16 + 1) { return -E2BIG; } + readConfigRid(local, 1); memset(local->config.nodeName, 0, sizeof(local->config.nodeName)); memcpy(local->config.nodeName, extra, dwrq->length); local->need_commit = 1; @@ -4325,6 +4954,7 @@ { struct airo_info *local = dev->priv; + readConfigRid(local, 1); strncpy(extra, local->config.nodeName, 16); extra[16] = '\0'; dwrq->length = strlen(extra) + 1; @@ -4381,6 +5011,7 @@ return -EINVAL; } + readConfigRid(local, 1); /* Now, check if we want a fixed or auto value */ if(vwrq->fixed == 0) { /* Fill all the rates up to this max rate */ @@ -4413,10 +5044,11 @@ struct airo_info *local = dev->priv; StatusRid status_rid; /* Card status info */ - readStatusRid(local, &status_rid); + readStatusRid(local, &status_rid, 1); vwrq->value = status_rid.currentXmitRate * 500000; /* If more than one rate, set auto */ + readConfigRid(local, 1); vwrq->fixed = (local->config.rates[1] == 0); return 0; @@ -4439,6 +5071,7 @@ if((rthr < 0) || (rthr > 2312)) { return -EINVAL; } + readConfigRid(local, 1); local->config.rtsThres = rthr; local->need_commit = 1; @@ -4456,6 +5089,7 @@ { struct airo_info *local = dev->priv; + readConfigRid(local, 1); vwrq->value = local->config.rtsThres; vwrq->disabled = (vwrq->value >= 2312); vwrq->fixed = 1; @@ -4481,6 +5115,7 @@ return -EINVAL; } fthr &= ~0x1; /* Get an even value - is it really needed ??? */ + readConfigRid(local, 1); local->config.fragThresh = (u16)fthr; local->need_commit = 1; @@ -4498,6 +5133,7 @@ { struct airo_info *local = dev->priv; + readConfigRid(local, 1); vwrq->value = local->config.fragThresh; vwrq->disabled = (vwrq->value >= 2312); vwrq->fixed = 1; @@ -4515,28 +5151,53 @@ char *extra) { struct airo_info *local = dev->priv; + int commit = 1; + + readConfigRid(local, 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; + clear_bit (FLAG_802_11, &local->flags); break; case IW_MODE_INFRA: local->config.opmode &= 0xFF00; local->config.opmode |= MODE_STA_ESS; + local->config.rmode &= 0xfe00; + local->config.scanMode = SCANMODE_ACTIVE; + clear_bit (FLAG_802_11, &local->flags); break; case IW_MODE_MASTER: local->config.opmode &= 0xFF00; local->config.opmode |= MODE_AP; + local->config.rmode &= 0xfe00; + local->config.scanMode = SCANMODE_ACTIVE; + clear_bit (FLAG_802_11, &local->flags); break; case IW_MODE_REPEAT: local->config.opmode &= 0xFF00; local->config.opmode |= MODE_AP_RPTR; + local->config.rmode &= 0xfe00; + local->config.scanMode = SCANMODE_ACTIVE; + clear_bit (FLAG_802_11, &local->flags); + 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; + set_bit (FLAG_802_11, &local->flags); break; default: return -EINVAL; } - local->need_commit = 1; + local->need_commit = commit; return -EINPROGRESS; /* Call commit handler */ } @@ -4552,6 +5213,7 @@ { struct airo_info *local = dev->priv; + readConfigRid(local, 1); /* If not managed, assume it's ad-hoc */ switch (local->config.opmode & 0xFF) { case MODE_STA_ESS: @@ -4588,6 +5250,7 @@ if(!(cap_rid.softCap & 2)) { return -EOPNOTSUPP; } */ + readConfigRid(local, 1); /* Basic checking: do we have a key to set ? * Note : with the new API, it's impossible to get a NULL pointer. @@ -4622,7 +5285,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 +5299,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) { @@ -4674,6 +5337,7 @@ if(!(cap_rid.softCap & 2)) { return -EOPNOTSUPP; } + readConfigRid(local, 1); /* Check encryption mode */ switch(local->config.authType) { case AUTH_ENCRYPT: @@ -4720,16 +5384,17 @@ readCapabilityRid(local, &cap_rid); if (vwrq->disabled) { - local->flags |= FLAG_RADIO_OFF; + set_bit (FLAG_RADIO_OFF, &local->flags); local->need_commit = 1; return -EINPROGRESS; /* Call commit handler */ } if (vwrq->flags != IW_TXPOW_MWATT) { return -EINVAL; } - local->flags &= ~FLAG_RADIO_OFF; + clear_bit (FLAG_RADIO_OFF, &local->flags); for (i = 0; cap_rid.txPowerLevels[i] && (i < 8); i++) if ((vwrq->value==cap_rid.txPowerLevels[i])) { + readConfigRid(local, 1); local->config.txPower = vwrq->value; local->need_commit = 1; rc = -EINPROGRESS; /* Call commit handler */ @@ -4749,9 +5414,10 @@ { struct airo_info *local = dev->priv; + readConfigRid(local, 1); vwrq->value = local->config.txPower; vwrq->fixed = 1; /* No power control */ - vwrq->disabled = (local->flags & FLAG_RADIO_OFF); + vwrq->disabled = test_bit(FLAG_RADIO_OFF, &local->flags); vwrq->flags = IW_TXPOW_MWATT; return 0; @@ -4772,6 +5438,7 @@ if(vwrq->disabled) { return -EINVAL; } + readConfigRid(local, 1); if(vwrq->flags & IW_RETRY_LIMIT) { if(vwrq->flags & IW_RETRY_MAX) local->config.longRetryLimit = vwrq->value; @@ -4806,6 +5473,7 @@ vwrq->disabled = 0; /* Can't be disabled */ + readConfigRid(local, 1); /* Note : by default, display the min retry number */ if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { vwrq->flags = IW_RETRY_LIFETIME; @@ -4841,7 +5509,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; @@ -4944,6 +5612,7 @@ { struct airo_info *local = dev->priv; + readConfigRid(local, 1); if (vwrq->disabled) { if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) { return -EINVAL; @@ -4999,8 +5668,10 @@ char *extra) { struct airo_info *local = dev->priv; + int mode; - int mode = local->config.powerSaveMode; + readConfigRid(local, 1); + mode = local->config.powerSaveMode; if ((vwrq->disabled = (mode == POWERSAVE_CAM))) return 0; if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { @@ -5029,6 +5700,7 @@ { struct airo_info *local = dev->priv; + readConfigRid(local, 1); local->config.rssiThreshold = vwrq->disabled ? RSSI_DEFAULT : vwrq->value; local->need_commit = 1; @@ -5046,6 +5718,7 @@ { struct airo_info *local = dev->priv; + readConfigRid(local, 1); vwrq->value = local->config.rssiThreshold; vwrq->disabled = (vwrq->value == 0); vwrq->fixed = 1; @@ -5087,7 +5760,7 @@ } if (!i) { StatusRid status_rid; /* Card status info */ - readStatusRid(local, &status_rid); + readStatusRid(local, &status_rid, 1); for (i = 0; i < min(IW_MAX_AP, 4) && (status_rid.bssid[i][0] @@ -5095,7 +5768,7 @@ & status_rid.bssid[i][2] & status_rid.bssid[i][3] & status_rid.bssid[i][4] - & status_rid.bssid[i][5])!=-1 && + & status_rid.bssid[i][5])!=0xff && (status_rid.bssid[i][0] | status_rid.bssid[i][1] | status_rid.bssid[i][2] @@ -5132,7 +5805,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 +5827,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, @@ -5189,7 +5862,7 @@ capabilities = le16_to_cpu(list->cap); if(capabilities & (CAP_ESS | CAP_IBSS)) { if(capabilities & CAP_ESS) - iwe.u.mode = IW_MODE_INFRA; + iwe.u.mode = IW_MODE_MASTER; else iwe.u.mode = IW_MODE_ADHOC; current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN); @@ -5281,7 +5954,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 +5970,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 +5980,7 @@ } #endif /* WIRELESS_EXT > 13 */ +#if WIRELESS_EXT <= 15 #ifdef WIRELESS_SPY /*------------------------------------------------------------------*/ /* @@ -5369,6 +6043,7 @@ return 0; } #endif /* WIRELESS_SPY */ +#endif /* WIRELESS_EXT <= 15 */ /*------------------------------------------------------------------*/ /* @@ -5387,9 +6062,26 @@ /* 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); + } + if (down_interruptible(&local->sem)) + return -ERESTARTSYS; + writeConfigRid(local, 0); + enable_MAC(local, &rsp, 0); + if (local->need_commit > 1) + airo_set_promisc(local); + else + up(&local->sem); return 0; } @@ -5426,6 +6118,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 +6133,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 -- */ @@ -5482,12 +6181,17 @@ static const struct iw_handler_def airo_handler_def = { - num_standard: sizeof(airo_handler)/sizeof(iw_handler), - num_private: sizeof(airo_private_handler)/sizeof(iw_handler), - num_private_args: sizeof(airo_private_args)/sizeof(struct iw_priv_args), - standard: (iw_handler *) airo_handler, - private: (iw_handler *) airo_private_handler, - private_args: (struct iw_priv_args *) airo_private_args, + .num_standard = sizeof(airo_handler)/sizeof(iw_handler), + .num_private = sizeof(airo_private_handler)/sizeof(iw_handler), + .num_private_args = sizeof(airo_private_args)/sizeof(struct iw_priv_args), + .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,9 +6526,9 @@ break; } - /* Seperate R/W functions bracket legality here + /* Separate R/W functions bracket legality here */ - if ( com.command <= AIROGMICSTATS ) + if ( com.command <= AIRORRID ) rc = readrids(dev,&com); else if ( com.command >= AIROPCAP && com.command <= AIROPLEAPUSR ) rc = writerids(dev,&com); @@ -5860,20 +6564,20 @@ * * TODO : * o Check if work in Ad-Hoc mode (otherwise, use SPY, as in wvlan_cs) - * o Find the noise level * * Jean */ -struct iw_statistics *airo_get_wireless_stats(struct net_device *dev) +static void airo_read_wireless_stats(struct airo_info *local) { - struct airo_info *local = dev->priv; StatusRid status_rid; StatsRid stats_rid; u32 *vals = stats_rid.vals; /* Get stats out of the card */ - readStatusRid(local, &status_rid); - readStatsRid(local, &stats_rid, RID_STATS); + clear_bit(JOB_WSTATS, &local->flags); + readStatusRid(local, &status_rid, 0); + readStatsRid(local, &stats_rid, RID_STATS, 0); + up(&local->sem); /* The status */ local->wstats.status = status_rid.mode; @@ -5884,8 +6588,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 */ @@ -5895,11 +6604,25 @@ local->wstats.discard.retries = vals[10]; local->wstats.discard.misc = vals[1] + vals[32]; local->wstats.miss.beacon = vals[34]; +} + +struct iw_statistics *airo_get_wireless_stats(struct net_device *dev) +{ + struct airo_info *local = dev->priv; + + /* Get stats out of the card if available */ + if (down_trylock(&local->sem) != 0) { + set_bit(JOB_WSTATS, &local->flags); + wake_up_interruptible(&local->thr_wait); + } else + airo_read_wireless_stats(local); + return &local->wstats; } #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,16 +6631,17 @@ */ static int readrids(struct net_device *dev, aironet_ioctl *comp) { unsigned short ridcode; - unsigned char iobuf[2048]; + unsigned char *iobuf; + int len; struct airo_info *ai = dev->priv; - if (ai->flags & FLAG_FLASHING) + if (test_bit(FLAG_FLASHING, &ai->flags)) return -EIO; 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; @@ -5936,25 +6660,37 @@ case AIROGSTAT: ridcode = RID_STATUS; break; case AIROGSTATSD32: ridcode = RID_STATSDELTA; break; case AIROGSTATSC32: ridcode = RID_STATS; break; +#ifdef MICSUPPORT case AIROGMICSTATS: if (copy_to_user(comp->data, &ai->micstats, min((int)comp->len,(int)sizeof(ai->micstats)))) return -EFAULT; return 0; +#endif + case AIRORRID: ridcode = comp->len; break; default: return -EINVAL; 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 (comp->command == AIRORRID) + len = le16_to_cpu(*(unsigned short *)iobuf); /* Yuck! */ + else + len = comp->len; - if (copy_to_user(comp->data, iobuf, - min((int)comp->len, (int)sizeof(iobuf)))) + if (copy_to_user(comp->data, iobuf, min(len, (int)RIDS_SIZE))) { + kfree (iobuf); return -EFAULT; + } + kfree (iobuf); return 0; } @@ -5966,14 +6702,14 @@ 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)) return -EPERM; - if (ai->flags & FLAG_FLASHING) + if (test_bit(FLAG_FLASHING, &ai->flags)) return -EIO; ridcode = 0; @@ -5996,7 +6732,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 +6741,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,40 +6749,56 @@ * 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); + +#ifdef MICSUPPORT enabled = ai->micstats.enabled; memset(&ai->micstats,0,sizeof(ai->micstats)); ai->micstats.enabled = enabled; +#endif 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; - if (ai->flags & FLAG_MIC_CAPABLE) + if (test_bit(FLAG_MIC_CAPABLE, &ai->flags)) cfg->opmode |= MODE_MIC; if ((cfg->opmode & 0xFF) == MODE_STA_IBSS) - ai->flags |= FLAG_ADHOC; + set_bit (FLAG_ADHOC, &ai->flags); else - ai->flags &= ~FLAG_ADHOC; + clear_bit (FLAG_ADHOC, &ai->flags); } - 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 +6877,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"); @@ -6150,7 +6902,7 @@ */ int setflashmode (struct airo_info *ai) { - ai->flags |= FLAG_FLASHING; + set_bit (FLAG_FLASHING, &ai->flags); OUT4500(ai, SWS0, FLASH_COMMAND); OUT4500(ai, SWS1, FLASH_COMMAND); @@ -6166,7 +6918,7 @@ schedule_timeout (HZ/2); /* 500ms delay */ if(!waitbusy(ai)) { - ai->flags &= ~FLAG_FLASHING; + clear_bit (FLAG_FLASHING, &ai->flags); printk(KERN_INFO "Waitbusy hang after setflash mode\n"); return -EIO; } @@ -6272,7 +7024,7 @@ set_current_state (TASK_UNINTERRUPTIBLE); schedule_timeout (HZ); /* Added 12/7/00 */ - ai->flags &= ~FLAG_FLASHING; + clear_bit (FLAG_FLASHING, &ai->flags); status = setup_card(ai, dev->dev_addr); for( i = 0; i < MAX_FIDS; i++ ) { Index: drivers/net/wireless/airo_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/airo_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wireless/airo_cs.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/wireless/airo_cs.c 4 Aug 2004 01:29:26 -0000 1.2 @@ -55,7 +55,7 @@ #ifdef PCMCIA_DEBUG static int pc_debug = PCMCIA_DEBUG; MODULE_PARM(pc_debug, "i"); -static char *version = "$Revision: 1.1 $"; +static char *version = "$Revision: 1.2 $"; #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); #else #define DEBUG(n, args...) Index: drivers/net/wireless/airport.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/airport.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wireless/airport.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/wireless/airport.c 4 Aug 2004 01:29:26 -0000 1.2 @@ -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; } Index: drivers/net/wireless/hermes.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/hermes.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wireless/hermes.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/wireless/hermes.c 4 Aug 2004 01:29:26 -0000 1.2 @@ -544,4 +544,9 @@ return 0; } +static void __exit exit_hermes(void) +{ +} + module_init(init_hermes); +module_exit(exit_hermes); Index: drivers/net/wireless/hermes.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/hermes.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wireless/hermes.h 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/wireless/hermes.h 4 Aug 2004 01:29:26 -0000 1.2 @@ -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) \ Index: drivers/net/wireless/orinoco.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/orinoco.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wireless/orinoco.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/wireless/orinoco.c 4 Aug 2004 01:29:26 -0000 1.2 @@ -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) { Index: drivers/net/wireless/orinoco.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/orinoco.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wireless/orinoco.h 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/wireless/orinoco.h 4 Aug 2004 01:29:26 -0000 1.2 @@ -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); /********************************************************************/ Index: drivers/net/wireless/orinoco_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/orinoco_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wireless/orinoco_cs.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/wireless/orinoco_cs.c 4 Aug 2004 01:29:26 -0000 1.2 @@ -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); Index: drivers/net/wireless/orinoco_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/orinoco_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wireless/orinoco_pci.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/wireless/orinoco_pci.c 4 Aug 2004 01:29:26 -0000 1.2 @@ -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"); Index: drivers/net/wireless/orinoco_plx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/orinoco_plx.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wireless/orinoco_plx.c 22 Jul 2004 19:49:45 -0000 1.1 +++ drivers/net/wireless/orinoco_plx.c 4 Aug 2004 01:29:26 -0000 1.2 @@ -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 Index: drivers/net/wireless/at76c503/at76c503-i3861.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/at76c503/at76c503-i3861.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wireless/at76c503/at76c503-i3861.c 8 Oct 2004 23:12:15 -0000 1.1 +++ drivers/net/wireless/at76c503/at76c503-i3861.c 21 Oct 2004 22:24:58 -0000 1.2 @@ -1,6 +1,6 @@ /* -*- linux-c -*- */ /* - * $Id: at76c503-i3861.c,v 1.1 2004/10/08 23:12:15 liberty Exp $ + * $Id: at76c503-i3861.c,v 1.2 2004/10/21 22:24:58 joff Exp $ * * Driver for at76c503-based devices based on the Atmel "Fast-Vnet" reference * design using Intersil 3861 radio chips @@ -39,7 +39,7 @@ # ifdef CONFIG_AT76C503_FIRMWARE_DOWNLOAD # error firmware download from user space unavail. with this kernel # endif -# define FIRMWARE_NAME_MAX 30 +# define FIRMWARE_NAME_MAX 50 struct firmware { size_t size; u8 *data; Index: drivers/net/wireless/at76c503/at76c503-i3863.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/at76c503/at76c503-i3863.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wireless/at76c503/at76c503-i3863.c 8 Oct 2004 23:12:15 -0000 1.1 +++ drivers/net/wireless/at76c503/at76c503-i3863.c 21 Oct 2004 22:24:58 -0000 1.2 @@ -1,6 +1,6 @@ /* -*- linux-c -*- */ /* - * $Id: at76c503-i3863.c,v 1.1 2004/10/08 23:12:15 liberty Exp $ + * $Id: at76c503-i3863.c,v 1.2 2004/10/21 22:24:58 joff Exp $ * * Driver for at76c503-based devices based on the Atmel "Fast-Vnet" reference * design using a Intersil 3863 radio chip @@ -38,7 +38,7 @@ # ifdef CONFIG_AT76C503_FIRMWARE_DOWNLOAD # error firmware download from user space unavail. with this kernel # endif -# define FIRMWARE_NAME_MAX 30 +# define FIRMWARE_NAME_MAX 50 struct firmware { size_t size; u8 *data; Index: drivers/net/wireless/at76c503/at76c503-rfmd-acc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/at76c503/at76c503-rfmd-acc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wireless/at76c503/at76c503-rfmd-acc.c 8 Oct 2004 23:12:15 -0000 1.1 +++ drivers/net/wireless/at76c503/at76c503-rfmd-acc.c 21 Oct 2004 22:24:58 -0000 1.2 @@ -1,6 +1,6 @@ /* -*- linux-c -*- */ /* - * $Id: at76c503-rfmd-acc.c,v 1.1 2004/10/08 23:12:15 liberty Exp $ + * $Id: at76c503-rfmd-acc.c,v 1.2 2004/10/21 22:24:58 joff Exp $ * * Driver for at76c503-based devices based on the Atmel "Fast-Vnet" reference * design using RFMD radio chips in the Accton OEM layout. @@ -38,7 +38,7 @@ # ifdef CONFIG_AT76C503_FIRMWARE_DOWNLOAD # error firmware download from user space unavail. with this kernel # endif -# define FIRMWARE_NAME_MAX 30 +# define FIRMWARE_NAME_MAX 50 struct firmware { size_t size; u8 *data; Index: drivers/net/wireless/at76c503/at76c503-rfmd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/at76c503/at76c503-rfmd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wireless/at76c503/at76c503-rfmd.c 8 Oct 2004 23:12:15 -0000 1.1 +++ drivers/net/wireless/at76c503/at76c503-rfmd.c 21 Oct 2004 22:24:58 -0000 1.2 @@ -1,6 +1,6 @@ /* -*- linux-c -*- */ /* - * $Id: at76c503-rfmd.c,v 1.1 2004/10/08 23:12:15 liberty Exp $ + * $Id: at76c503-rfmd.c,v 1.2 2004/10/21 22:24:58 joff Exp $ * * Driver for at76c503-based devices based on the Atmel "Fast-Vnet" reference * design using RFMD radio chips @@ -47,7 +47,7 @@ # ifdef CONFIG_AT76C503_FIRMWARE_DOWNLOAD # error firmware download from user space unavail. with this kernel # endif -# define FIRMWARE_NAME_MAX 30 +# define FIRMWARE_NAME_MAX 50 struct firmware { size_t size; u8 *data; Index: drivers/net/wireless/at76c503/at76c505-rfmd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/at76c503/at76c505-rfmd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wireless/at76c503/at76c505-rfmd.c 8 Oct 2004 23:12:15 -0000 1.1 +++ drivers/net/wireless/at76c503/at76c505-rfmd.c 21 Oct 2004 22:24:58 -0000 1.2 @@ -1,6 +1,6 @@ /* -*- linux-c -*- */ /* - * $Id: at76c505-rfmd.c,v 1.1 2004/10/08 23:12:15 liberty Exp $ + * $Id: at76c505-rfmd.c,v 1.2 2004/10/21 22:24:58 joff Exp $ * * Driver for at76c503-based devices based on the Atmel "Fast-Vnet" reference * design using at76c505 with RFMD radio chips @@ -37,7 +37,7 @@ # ifdef CONFIG_AT76C503_FIRMWARE_DOWNLOAD # error firmware download from user space unavail. with this kernel # endif -# define FIRMWARE_NAME_MAX 30 +# define FIRMWARE_NAME_MAX 50 struct firmware { size_t size; u8 *data; Index: drivers/net/wireless/at76c503/at76c505-rfmd2958.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/at76c503/at76c505-rfmd2958.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wireless/at76c503/at76c505-rfmd2958.c 8 Oct 2004 23:12:15 -0000 1.1 +++ drivers/net/wireless/at76c503/at76c505-rfmd2958.c 21 Oct 2004 22:24:58 -0000 1.2 @@ -39,7 +39,7 @@ # ifdef CONFIG_AT76C503_FIRMWARE_DOWNLOAD # error firmware download from user space unavail. with this kernel # endif -# define FIRMWARE_NAME_MAX 30 +# define FIRMWARE_NAME_MAX 50 struct firmware { size_t size; u8 *data; Index: drivers/net/wireless/at76c503/at76c505a-rfmd2958.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/at76c503/at76c505a-rfmd2958.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wireless/at76c503/at76c505a-rfmd2958.c 8 Oct 2004 23:12:15 -0000 1.1 +++ drivers/net/wireless/at76c503/at76c505a-rfmd2958.c 21 Oct 2004 22:24:58 -0000 1.2 @@ -1,6 +1,6 @@ /* -*- linux-c -*- */ /* - * $Id: at76c505a-rfmd2958.c,v 1.1 2004/10/08 23:12:15 liberty Exp $ + * $Id: at76c505a-rfmd2958.c,v 1.2 2004/10/21 22:24:58 joff Exp $ * * Driver for at76c503-based devices based on the Atmel "Fast-Vnet" reference * design using a at76c505a (with RFMD radio chips ?) @@ -37,7 +37,7 @@ # ifdef CONFIG_AT76C503_FIRMWARE_DOWNLOAD # error firmware download from user space unavail. with this kernel # endif -# define FIRMWARE_NAME_MAX 30 +# define FIRMWARE_NAME_MAX 50 struct firmware { size_t size; u8 *data; Index: drivers/net/wireless/zd1211-driver-r51/src/zd1211.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/net/wireless/zd1211-driver-r51/src/zd1211.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/net/wireless/zd1211-driver-r51/src/zd1211.c 17 Jan 2006 20:36:03 -0000 1.1 +++ drivers/net/wireless/zd1211-driver-r51/src/zd1211.c 17 Jan 2006 23:43:10 -0000 1.2 @@ -589,7 +589,7 @@ //check if Rsp has completed, race condition may happen, macp->regRdSleepCnt++; //we waste time_out time - printk(KERN_ERR "before wait 2\n"); + //printk(KERN_ERR "before wait 2\n"); interruptible_sleep_on_timeout(&macp->iorwRsp_wait, HZ/2); //wake up, check if timeout or ompleted Index: drivers/parport/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/parport/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/parport/Config.in 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/parport/Config.in 4 Aug 2004 01:29:26 -0000 1.2 @@ -24,13 +24,7 @@ bool ' Use FIFO/DMA if available (EXPERIMENTAL)' CONFIG_PARPORT_PC_FIFO bool ' SuperIO chipset support (EXPERIMENTAL)' CONFIG_PARPORT_PC_SUPERIO fi - if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then - if [ "$CONFIG_PARPORT_PC" = "y" ]; then - dep_tristate ' Support for PCMCIA management for PC-style ports' CONFIG_PARPORT_PC_PCMCIA $CONFIG_PCMCIA - else - dep_tristate ' Support for PCMCIA management for PC-style ports' CONFIG_PARPORT_PC_PCMCIA $CONFIG_PARPORT_PC - fi - fi + dep_tristate ' Support for PCMCIA management for PC-style ports' CONFIG_PARPORT_PC_PCMCIA $CONFIG_PCMCIA $CONFIG_PARPORT_PC $CONFIG_HOTPLUG fi if [ "$CONFIG_ARM" = "y" ]; then dep_tristate ' Archimedes hardware' CONFIG_PARPORT_ARC $CONFIG_PARPORT $CONFIG_ARCH_ARC @@ -62,6 +56,12 @@ define_tristate CONFIG_PARPORT_SUNBPP n fi + if [ "$CONFIG_SGI_IP22" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' SGI Indy/Indigo2 hardware (EXPERIMENTAL)' CONFIG_PARPORT_IP22 $CONFIG_PARPORT + else + define_tristate CONFIG_PARPORT_IP22 n + fi + # If exactly one hardware type is selected then parport will optimise away # support for loading any others. Defeat this if the user is keen. bool ' Support foreign hardware' CONFIG_PARPORT_OTHER Index: drivers/parport/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/parport/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/parport/Makefile 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/parport/Makefile 4 Aug 2004 01:29:26 -0000 1.2 @@ -23,13 +23,14 @@ obj-$(CONFIG_PARPORT) += parport.o obj-$(CONFIG_PARPORT_PC) += parport_pc.o obj-$(CONFIG_PARPORT_SERIAL) += parport_serial.o -obj-$(CONFIG_PARPORT_PC_PCMCIA)+= parport_cs.o +obj-$(CONFIG_PARPORT_PC_PCMCIA) += parport_cs.o obj-$(CONFIG_PARPORT_AMIGA) += parport_amiga.o obj-$(CONFIG_PARPORT_MFC3) += parport_mfc3.o obj-$(CONFIG_PARPORT_ATARI) += parport_atari.o obj-$(CONFIG_PARPORT_SUNBPP) += parport_sunbpp.o obj-$(CONFIG_PARPORT_GSC) += parport_gsc.o obj-$(CONFIG_PARPORT_IDP) += parport_idp.o +obj-$(CONFIG_PARPORT_IP22) += parport_ip22.o include $(TOPDIR)/Rules.make Index: drivers/parport/ieee1284.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/parport/ieee1284.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/parport/ieee1284.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/parport/ieee1284.c 4 Aug 2004 01:29:26 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: ieee1284.c,v 1.1 2004/07/22 19:50:26 joff Exp $ +/* $Id: ieee1284.c,v 1.2 2004/08/04 01:29:26 joff Exp $ * IEEE-1284 implementation for parport. * * Authors: Phil Blundell Index: drivers/parport/parport_sunbpp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/parport/parport_sunbpp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/parport/parport_sunbpp.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/parport/parport_sunbpp.c 4 Aug 2004 01:29:26 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: parport_sunbpp.c,v 1.1 2004/07/22 19:50:26 joff Exp $ +/* $Id: parport_sunbpp.c,v 1.2 2004/08/04 01:29:26 joff Exp $ * Parallel-port routines for Sun architecture * * Author: Derrick J. Brashear Index: drivers/parport/probe.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/parport/probe.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/parport/probe.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/parport/probe.c 4 Aug 2004 01:29:26 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: probe.c,v 1.1 2004/07/22 19:50:26 joff Exp $ +/* $Id: probe.c,v 1.2 2004/08/04 01:29:26 joff Exp $ * Parallel port device probing code * * Authors: Carsten Gross, carsten@sol.wohnheim.uni-ulm.de Index: drivers/parport/share.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/parport/share.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/parport/share.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/parport/share.c 4 Aug 2004 01:29:26 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: share.c,v 1.1 2004/07/22 19:50:26 joff Exp $ +/* $Id: share.c,v 1.2 2004/08/04 01:29:26 joff Exp $ * Parallel-port resource manager code. * * Authors: David Campbell Index: drivers/pci/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pci/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pci/Makefile 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/pci/Makefile 4 Aug 2004 01:29:26 -0000 1.2 @@ -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 Index: drivers/pci/compat.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pci/compat.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pci/compat.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/pci/compat.c 4 Aug 2004 01:29:26 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: compat.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: compat.c,v 1.2 2004/08/04 01:29:26 joff Exp $ * * PCI Bus Services -- Function For Backward Compatibility * Index: drivers/pci/pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pci/pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pci/pci.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/pci/pci.c 4 Aug 2004 01:29:26 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: pci.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: pci.c,v 1.2 2004/08/04 01:29:26 joff Exp $ * * PCI Bus Services, see include/linux/pci.h for further explanation. * @@ -949,8 +949,12 @@ pcibios_set_master(dev); } +#ifndef HAVE_ARCH_PCI_MWI +/* This can be overridden by arch code. */ +u8 pci_cache_line_size = L1_CACHE_BYTES >> 2; + /** - * pdev_set_mwi - arch helper function for pcibios_set_mwi + * pci_generic_prep_mwi - helper function for pci_set_mwi * @dev: the PCI device for which MWI is enabled * * Helper function for implementation the arch-specific pcibios_set_mwi @@ -959,35 +963,34 @@ * * RETURNS: An appriopriate -ERRNO error value on eror, or zero for success. */ -int -pdev_set_mwi(struct pci_dev *dev) +static int +pci_generic_prep_mwi(struct pci_dev *dev) { - int rc = 0; - u8 cache_size; + u8 cacheline_size; - /* - * Looks like this is necessary to deal with on all architectures, - * even this %$#%$# N440BX Intel based thing doesn't get it right. - * Ie. having two NICs in the machine, one will have the cache - * line set at boot time, the other will not. - */ - pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &cache_size); - cache_size <<= 2; - if (cache_size != SMP_CACHE_BYTES) { - printk(KERN_WARNING "PCI: %s PCI cache line size set incorrectly (%i bytes) by BIOS/FW.\n", - dev->slot_name, cache_size); - if (cache_size > SMP_CACHE_BYTES) { - printk("PCI: %s cache line size too large - expecting %i.\n", dev->slot_name, SMP_CACHE_BYTES); - rc = -EINVAL; - } else { - printk("PCI: %s PCI cache line size corrected to %i.\n", dev->slot_name, SMP_CACHE_BYTES); - pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, - SMP_CACHE_BYTES >> 2); - } - } + if (!pci_cache_line_size) + return -EINVAL; /* The system doesn't support MWI. */ + + /* Validate current setting: the PCI_CACHE_LINE_SIZE must be + equal to or multiple of the right value. */ + pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &cacheline_size); + if (cacheline_size >= pci_cache_line_size && + (cacheline_size % pci_cache_line_size) == 0) + return 0; + + /* Write the correct value. */ + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, pci_cache_line_size); + /* Read it back. */ + pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &cacheline_size); + if (cacheline_size == pci_cache_line_size) + return 0; - return rc; + printk(KERN_WARNING "PCI: cache line size of %d is not supported " + "by device %s\n", pci_cache_line_size << 2, dev->slot_name); + + return -EINVAL; } +#endif /* !HAVE_ARCH_PCI_MWI */ /** * pci_set_mwi - enables memory-write-invalidate PCI transaction @@ -1008,7 +1011,7 @@ #ifdef HAVE_ARCH_PCI_MWI rc = pcibios_set_mwi(dev); #else - rc = pdev_set_mwi(dev); + rc = pci_generic_prep_mwi(dev); #endif if (rc) @@ -1514,17 +1517,22 @@ u8 hdr_type; for (func = 0; func < 8; func++, temp->devfn++) { - if (func && !is_multi) /* not a multi-function device */ - continue; if (pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) continue; temp->hdr_type = hdr_type & 0x7f; dev = pci_scan_device(temp); - if (!dev) - continue; + if (!pcibios_scan_all_fns() && func == 0) { + if (!dev) + break; + } else { + if (!dev) + continue; + is_multi = 1; + } + pci_name_device(dev); - if (!func) { + if (!first_dev) { is_multi = hdr_type & 0x80; first_dev = dev; } @@ -1538,6 +1546,14 @@ /* Fix up broken headers */ pci_fixup_device(PCI_FIXUP_HEADER, dev); + + /* + * If this is a single function device + * don't scan past the first function. + */ + if (!is_multi) + break; + } return first_dev; } @@ -2190,7 +2206,6 @@ EXPORT_SYMBOL(pci_set_master); EXPORT_SYMBOL(pci_set_mwi); EXPORT_SYMBOL(pci_clear_mwi); -EXPORT_SYMBOL(pdev_set_mwi); EXPORT_SYMBOL(pci_set_dma_mask); EXPORT_SYMBOL(pci_dac_set_dma_mask); EXPORT_SYMBOL(pci_assign_resource); Index: drivers/pci/pci.ids =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pci/pci.ids,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pci/pci.ids 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/pci/pci.ids 4 Aug 2004 01:29:27 -0000 1.2 @@ -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.1 2004/07/22 19:49:46 joff 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 @@ -1767,6 +1934,7 @@ 8001 Schizo PCI Bus Module a000 Ultra IIi a001 Ultra IIe + a801 Tomatillo PCI Bus Module 108f Systemsoft 1090 Encore Computer Corporation 1091 Intergraph Corporation @@ -1818,8 +1986,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 +2004,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 +2024,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 +2042,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 +2078,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 +2095,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 +2137,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 +2154,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 +2166,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 +2207,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 +2220,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 +2241,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 +2249,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,9 +2277,13 @@ 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 + 1700 Gigabit Ethernet Adapter + 10b7 0010 3Com 3C940 Gigabit LOM Ethernet Adapter + 10b7 0020 3Com 3C941 Gigabit LOM Ethernet Adapter 3390 3c339 TokenLink Velocity 3590 3c359 TokenLink Velocity XL 10b7 3590 TokenLink Velocity XL Adapter (3C359/359B) @@ -2172,19 +2359,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 +2403,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 +2425,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 +2434,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 +2457,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 +2493,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 +2515,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 +2535,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 +2580,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 +2597,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 +2619,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 +2629,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 +2648,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 +2669,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 +2727,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 +2784,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 +2814,7 @@ 2010 CyberPro 2000A 5000 CyberPro 5000 5050 CyberPro 5050 + 5202 CyberPro 5202 10eb Artists Graphics 0101 3GA 8111 Twist3 Frame Grabber @@ -2580,6 +2837,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 +2853,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 +2880,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 +2912,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 +2937,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 +2975,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 +3013,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 +3077,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 +3105,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 +3125,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 +3136,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 +3277,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 +3313,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 +3362,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 @@ -3068,28 +3389,50 @@ 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 - 4320 SK-98xx Gigabit Ethernet Server Adapter - 1148 9521 SK-9521 10/100/1000Base-T Adapter + 1148 9821 SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T) + 1148 9822 SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link) + 1148 9841 SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX) + 1148 9842 SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link) + 1148 9843 SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX) + 1148 9844 SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link) + 1148 9861 SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition) + 1148 9862 SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link) +# Information got from SysKonnekt + 1148 9871 SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX) +# Information got from SysKonnekt + 1148 9872 SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) + 1259 2970 Allied Telesyn AT-2970SX Gigabit Ethernet Adapter + 1259 2971 Allied Telesyn AT-2970LX Gigabit Ethernet Adapter + 1259 2972 Allied Telesyn AT-2970TX Gigabit Ethernet Adapter + 1259 2973 Allied Telesyn AT-2971SX Gigabit Ethernet Adapter + 1259 2974 Allied Telesyn AT-2971T Gigabit Ethernet Adapter + 1259 2975 Allied Telesyn AT-2970SX/2SC Gigabit Ethernet Adapter + 1259 2976 Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter + 1259 2977 Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter + 4320 SK-98xx V2.0 Gigabit Ethernet Adapter + 1148 0121 Marvell RDK-8001 Adapter + 1148 0221 Marvell RDK-8002 Adapter + 1148 0321 Marvell RDK-8003 Adapter + 1148 0421 Marvell RDK-8004 Adapter + 1148 0621 Marvell RDK-8006 Adapter + 1148 0721 Marvell RDK-8007 Adapter + 1148 0821 Marvell RDK-8008 Adapter + 1148 0921 Marvell RDK-8009 Adapter + 1148 1121 Marvell RDK-8011 Adapter + 1148 1221 Marvell RDK-8012 Adapter + 1148 3221 SK-9521 V2.0 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 - 4400 Gigabit Ethernet + 1148 9521 SK-9521 10/100/1000Base-T Adapter 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 +3543,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 +3615,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 +3626,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 @@ -3295,6 +3644,8 @@ 1340 DFE-690TXD CardBus PC Card 1561 DRP-32TXD Cardbus PC Card 4000 DL2K Ethernet + 4c00 Gigabit Ethernet Adapter + 1186 4c00 DGE-530T Gigabit Ethernet Adapter 1187 Advanced Technology Laboratories, Inc. 1188 Shima Seiki Manufacturing Ltd. 1189 Matsushita Electronics Co Ltd @@ -3371,7 +3722,27 @@ 4240 AMCC S933Q Intelligent Serial Card 11aa Actel 11ab Galileo Technology Ltd. - 0146 GT-64010 + 0146 GT-64010/64010A System Controller + 4146 GT-64011/GT-64111 System Controller + 4320 Gigabit Ethernet Adapter + 1019 0f38 Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS) + 1019 8001 Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS) + 1043 173c Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus) + 1043 811a Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus) + 105b 0c19 Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn) + 10b8 b452 SMC EZ Card 1000 (SMC9452TXV.2) + 11ab 0121 Marvell RDK-8001 Adapter + 11ab 0321 Marvell RDK-8003 Adapter + 11ab 1021 Marvell RDK-8010 Adapter + 11ab 5021 Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit) + 11ab 9521 Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit) + 1458 e000 Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte) + 147b 1406 Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit) + 15d4 0047 Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill) + 1695 9025 Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox) + 17f2 1c03 Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron) + 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 +3838,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 +3868,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 +3879,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 +3944,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 +4006,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 +4057,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 +4079,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 +4190,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 +4235,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 +4267,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 +4306,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 +4377,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 @@ -4122,6 +4511,7 @@ 9132 Ethernet 100/10 MBit 1283 Integrated Technology Express, Inc. 673a IT8330G + 8181 IT8181E/F LCD/VGA Controller 8330 IT8330G 8888 IT8888F PCI to ISA Bridge with SMB 8889 IT8889F PCI to ISA Bridge @@ -4184,6 +4574,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 +4605,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 +4669,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 +4794,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 +4881,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 +4920,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 +4932,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 @@ -4559,6 +4972,8 @@ 136f Applied Magic Inc 1370 ATL Products 1371 CNet Technology Inc + 434e GigaCard Network Adapter + 1371 434e N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L) 1373 Silicon Vision Inc 1374 Silicom Ltd 1375 Argosystems Inc @@ -4579,6 +4994,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 +5047,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 +5101,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 +5131,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 +5152,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 +5203,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 +5301,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 +5312,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 +5363,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 +5382,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 +5390,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 +5408,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 +5481,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 +5526,63 @@ 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 + 1649 NetXtreme BCM5704S Gigabit Ethernet 164d NetXtreme BCM5702FE Gigabit Ethernet - 16a6 NetXtreme BCM5702X Gigabit Ethernet - 16a7 NetXtreme BCM5703X Gigabit Ethernet + 1653 NetXtreme BCM5705 Gigabit Ethernet + 1654 NetXtreme BCM5705 Gigabit Ethernet + 165d NetXtreme BCM5705M Gigabit Ethernet + 165e NetXtreme BCM5705M Gigabit Ethernet + 166e NetXtreme BCM5705F 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 + 170d NetXtreme BCM5901 Gigabit Ethernet + 170e NetXtreme BCM5901 Gigabit Ethernet + 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 +5667,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 +5807,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 +5845,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 +6077,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 +6086,46 @@ 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 + 1032 Gigabit Network Adapter + 1737 0015 EG1032 v2 Instant Gigabit Network Adapter + 1064 Gigabit Network Adapter + 1737 0016 EG1064 v2 Instant Gigabit Network Adapter 173b Altima (nee Broadcom) 03e8 AC1000 Gigabit Ethernet + 03e9 AC1001 Gigabit Ethernet 03ea AC9100 Gigabit Ethernet + 173b 0001 AC1002 + 03eb AC1003 Gigabit Ethernet 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 +6134,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 +6162,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 +6179,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 +6214,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 +6243,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 +6289,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 +6398,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 +6411,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 +6426,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 +6434,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 +6470,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 +6478,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 +6531,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 +6591,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 +6731,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 +6783,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 +6827,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 +6848,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 +6862,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 +6951,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 +7008,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 +7020,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 +7139,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 +7217,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 +7280,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 +7289,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 +7300,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 +7326,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 Index: drivers/pci/proc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pci/proc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pci/proc.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/pci/proc.c 4 Aug 2004 01:29:27 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: proc.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: proc.c,v 1.2 2004/08/04 01:29:27 joff Exp $ * * Procfs interface for the PCI bus. * Index: drivers/pci/quirks.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pci/quirks.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pci/quirks.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/pci/quirks.c 4 Aug 2004 01:29:27 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: quirks.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: quirks.c,v 1.2 2004/08/04 01:29:27 joff Exp $ * * This file contains work-arounds for many known PCI hardware * bugs. Devices present only on certain architectures (host @@ -275,6 +275,22 @@ } /* + * ICH4, ICH4-M, ICH5, ICH5-M ACPI: Three IO regions pointed to by longwords at + * 0x40 (128 bytes of ACPI, GPIO & TCO registers) + * 0x58 (64 bytes of GPIO I/O space) + */ +static void __devinit quirk_ich4_lpc_acpi(struct pci_dev *dev) +{ + u32 region; + + pci_read_config_dword(dev, 0x40, ®ion); + quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES); + + pci_read_config_dword(dev, 0x58, ®ion); + quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1); +} + +/* * VIA ACPI: One IO region pointed to by longword at * 0x48 or 0x20 (256 bytes of ACPI registers) */ @@ -648,6 +664,62 @@ } /* + * On ASUS P4B boards, the SMBus PCI Device within the ICH2/4 southbridge + * is not activated. The myth is that Asus said that they do not want the + * users to be irritated by just another PCI Device in the Win98 device + * manager. (see the file prog/hotplug/README.p4b in the lm_sensors + * package 2.7.0 for details) + * + * The SMBus PCI Device can be activated by setting a bit in the ICH LPC + * bridge. Unfortunately, this device has no subvendor/subdevice ID. So it + * becomes necessary to do this tweak in two steps -- I've chosen the Host + * bridge as trigger. + */ + +static int __initdata asus_hides_smbus = 0; + +static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) +{ + if (likely(dev->subsystem_vendor != PCI_VENDOR_ID_ASUSTEK)) + return; + + if (dev->device == PCI_DEVICE_ID_INTEL_82845_HB) + switch(dev->subsystem_device) { + case 0x8070: /* P4B */ + case 0x8088: /* P4B533 */ + asus_hides_smbus = 1; + } + if ((dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) && + (dev->subsystem_device == 0x80b2)) /* P4PE */ + asus_hides_smbus = 1; + if ((dev->device == PCI_DEVICE_ID_INTEL_82850_HB) && + (dev->subsystem_device == 0x8030)) /* P4T533 */ + asus_hides_smbus = 1; + if ((dev->device == PCI_DEVICE_ID_INTEL_7205_0) && + (dev->subsystem_device == 0x8070)) /* P4G8X Deluxe */ + asus_hides_smbus = 1; + return; +} + +static void __init asus_hides_smbus_lpc(struct pci_dev *dev) +{ + u16 val; + + if (likely(!asus_hides_smbus)) + return; + + pci_read_config_word(dev, 0xF2, &val); + if (val & 0x8) { + pci_write_config_word(dev, 0xF2, val & (~0x8)); + pci_read_config_word(dev, 0xF2, &val); + if(val & 0x8) + printk(KERN_INFO "PCI: i801 SMBus device continues to play 'hide and seek'! 0x%x\n", val); + else + printk(KERN_INFO "PCI: Enabled i801 SMBus device\n"); + } +} + +/* * The main table of quirks. */ @@ -688,6 +760,7 @@ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_vt82c586_acpi }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt82c686_acpi }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, quirk_piix4_acpi }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, quirk_ich4_lpc_acpi }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, quirk_ali7101_acpi }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_2, quirk_piix3_usb }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_2, quirk_piix3_usb }, @@ -725,6 +798,16 @@ quirk_amd_8131_ioapic }, #endif + /* + * on Asus P4B boards, the i801SMBus device is disabled at startup. + */ + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845_HB, asus_hides_smbus_hostbridge }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_HB, asus_hides_smbus_hostbridge }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82850_HB, asus_hides_smbus_hostbridge }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_7205_0, asus_hides_smbus_hostbridge }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc }, + { 0 } }; Index: drivers/pcmcia/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pcmcia/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pcmcia/Config.in 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/pcmcia/Config.in 4 Aug 2004 01:29:27 -0000 1.2 @@ -27,6 +27,20 @@ if [ "$CONFIG_HD64465" = "y" ]; then dep_tristate ' HD64465 host bridge support' CONFIG_HD64465_PCMCIA $CONFIG_PCMCIA fi + if [ "$CONFIG_SOC_AU1X00" = "y" ]; then + dep_tristate ' Au1x00 PCMCIA support' CONFIG_PCMCIA_AU1X00 $CONFIG_PCMCIA + if [ "$CONFIG_PCMCIA_AU1X00" != "n" ]; then + bool ' Pb1x00 board support' CONFIG_PCMCIA_PB1X00 + bool ' Db1x00 board support' CONFIG_PCMCIA_DB1X00 + bool ' XXS1500 board support' CONFIG_PCMCIA_XXS1500 + fi + fi + if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then + dep_bool ' SiByte PCMCIA support' CONFIG_PCMCIA_SIBYTE $CONFIG_PCMCIA $CONFIG_BLK_DEV_IDE_SIBYTE + fi + if [ "$CONFIG_VRC4173" = "y" -o "$CONFIG_VRC4173" = "m" ]; then + dep_tristate ' NEC VRC4173 CARDU support' CONFIG_PCMCIA_VRC4173 $CONFIG_PCMCIA + fi fi if [ "$CONFIG_ARM" = "y" ]; then dep_tristate ' CLPS6700 support' CONFIG_PCMCIA_CLPS6700 $CONFIG_ARCH_CLPS711X $CONFIG_PCMCIA Index: drivers/pcmcia/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pcmcia/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pcmcia/Makefile 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/pcmcia/Makefile 4 Aug 2004 01:29:27 -0000 1.2 @@ -59,8 +59,15 @@ endif endif +obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o +au1000_ss-objs-y := au1000_generic.o +au1000_ss-objs-$(CONFIG_PCMCIA_PB1X00) += au1000_pb1x00.o +au1000_ss-objs-$(CONFIG_PCMCIA_DB1X00) += au1000_db1x00.o +au1000_ss-objs-$(CONFIG_PCMCIA_XXS1500) += au1000_xxs1500.o + obj-$(CONFIG_PCMCIA_CLPS6700) += clps6700.o obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o +obj-$(CONFIG_PCMCIA_SIBYTE) += sibyte_generic.o sa1100_cs-objs-y := sa1100_generic.o sa1100_cs-objs-$(CONFIG_SA1100_ADSAGC) += sa1100_graphicsmaster.o sa1111_generic.o @@ -85,6 +92,8 @@ sa1100_cs-objs-$(CONFIG_SA1100_XP860) += sa1100_xp860.o sa1111_generic.o sa1100_cs-objs-$(CONFIG_SA1100_YOPY) += sa1100_yopy.o +obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o + include $(TOPDIR)/Rules.make pcmcia_core.o: $(pcmcia_core-objs) @@ -93,5 +102,8 @@ sa1100_cs.o: $(sa1100_cs-objs-y) $(LD) -r -o $@ $(sa1100_cs-objs-y) +au1x00_ss.o: $(au1000_ss-objs-y) + $(LD) -r -o $@ $(au1000_ss-objs-y) + yenta_socket.o: $(yenta_socket-objs) $(LD) $(LD_RFLAG) -r -o $@ $(yenta_socket-objs) Index: drivers/pcmcia/au1000_generic.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pcmcia/au1000_generic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pcmcia/au1000_generic.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/pcmcia/au1000_generic.c 4 Aug 2004 01:29:27 -0000 1.2 @@ -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); Index: drivers/pcmcia/au1000_pb1x00.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pcmcia/au1000_pb1x00.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pcmcia/au1000_pb1x00.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/pcmcia/au1000_pb1x00.c 4 Aug 2004 01:29:27 -0000 1.2 @@ -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_PINSTATE) >> 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, Index: drivers/pcmcia/cardbus.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pcmcia/cardbus.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pcmcia/cardbus.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/pcmcia/cardbus.c 4 Aug 2004 01:29:27 -0000 1.2 @@ -223,7 +223,6 @@ struct pci_dev *cb_scan_slot(struct pci_dev *temp, struct list_head *list) { - struct pci_bus *bus = temp->bus; struct pci_dev *dev; struct pci_dev *first_dev = NULL; int func = 0; @@ -369,7 +368,7 @@ return max; } -static int program_bridge(struct pci_dev *bridge) +static void program_bridge(struct pci_dev *bridge) { u32 l; Index: drivers/pcmcia/cistpl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pcmcia/cistpl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pcmcia/cistpl.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/pcmcia/cistpl.c 4 Aug 2004 01:29:27 -0000 1.2 @@ -351,9 +351,12 @@ int verify_cis_cache(socket_info_t *s) { - char buf[256], *caddr; + char *buf, *caddr; int i; - + + buf = kmalloc(256, GFP_KERNEL); + if (buf == NULL) + return -1; caddr = s->cis_cache; for (i = 0; i < s->cis_used; i++) { #ifdef CONFIG_CARDBUS @@ -368,6 +371,7 @@ break; caddr += s->cis_table[i].len; } + kfree(buf); return (i < s->cis_used); } @@ -1410,20 +1414,31 @@ int read_tuple(client_handle_t handle, cisdata_t code, void *parse) { - tuple_t tuple; - cisdata_t buf[255]; + tuple_t *tuple; + cisdata_t *buf; int ret; - - tuple.DesiredTuple = code; - tuple.Attributes = TUPLE_RETURN_COMMON; - ret = pcmcia_get_first_tuple(handle, &tuple); - if (ret != CS_SUCCESS) return ret; - tuple.TupleData = buf; - tuple.TupleOffset = 0; - tuple.TupleDataMax = sizeof(buf); - ret = pcmcia_get_tuple_data(handle, &tuple); - if (ret != CS_SUCCESS) return ret; - ret = pcmcia_parse_tuple(handle, &tuple, parse); + + buf = kmalloc(256, GFP_KERNEL); + if (buf == NULL) + return CS_OUT_OF_RESOURCE; + tuple = kmalloc(sizeof(*tuple), GFP_KERNEL); + if (tuple == NULL) { + kfree(buf); + return CS_OUT_OF_RESOURCE; + } + tuple->DesiredTuple = code; + tuple->Attributes = TUPLE_RETURN_COMMON; + ret = pcmcia_get_first_tuple(handle, tuple); + if (ret != CS_SUCCESS) goto done; + tuple->TupleData = buf; + tuple->TupleOffset = 0; + tuple->TupleDataMax = 255; + ret = pcmcia_get_tuple_data(handle, tuple); + if (ret != CS_SUCCESS) goto done; + ret = pcmcia_parse_tuple(handle, tuple, parse); +done: + kfree(tuple); + kfree(buf); return ret; } @@ -1439,50 +1454,61 @@ int pcmcia_validate_cis(client_handle_t handle, cisinfo_t *info) { - tuple_t tuple; - cisparse_t p; + tuple_t *tuple; + cisparse_t *p; int ret, reserved, dev_ok = 0, ident_ok = 0; if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; + tuple = kmalloc(sizeof(*tuple), GFP_KERNEL); + if (tuple == NULL) + return CS_OUT_OF_RESOURCE; + p = kmalloc(sizeof(*p), GFP_KERNEL); + if (p == NULL) { + kfree(tuple); + return CS_OUT_OF_RESOURCE; + } info->Chains = reserved = 0; - tuple.DesiredTuple = RETURN_FIRST_TUPLE; - tuple.Attributes = TUPLE_RETURN_COMMON; - ret = pcmcia_get_first_tuple(handle, &tuple); + tuple->DesiredTuple = RETURN_FIRST_TUPLE; + tuple->Attributes = TUPLE_RETURN_COMMON; + ret = pcmcia_get_first_tuple(handle, tuple); if (ret != CS_SUCCESS) - return CS_SUCCESS; + goto done; /* First tuple should be DEVICE; we should really have either that or a CFTABLE_ENTRY of some sort */ - if ((tuple.TupleCode == CISTPL_DEVICE) || - (read_tuple(handle, CISTPL_CFTABLE_ENTRY, &p) == CS_SUCCESS) || - (read_tuple(handle, CISTPL_CFTABLE_ENTRY_CB, &p) == CS_SUCCESS)) + if ((tuple->TupleCode == CISTPL_DEVICE) || + (read_tuple(handle, CISTPL_CFTABLE_ENTRY, p) == CS_SUCCESS) || + (read_tuple(handle, CISTPL_CFTABLE_ENTRY_CB, p) == CS_SUCCESS)) dev_ok++; /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2 tuple, for card identification. Certain old D-Link and Linksys cards have only a broken VERS_2 tuple; hence the bogus test. */ - if ((read_tuple(handle, CISTPL_MANFID, &p) == CS_SUCCESS) || - (read_tuple(handle, CISTPL_VERS_1, &p) == CS_SUCCESS) || - (read_tuple(handle, CISTPL_VERS_2, &p) != CS_NO_MORE_ITEMS)) + if ((read_tuple(handle, CISTPL_MANFID, p) == CS_SUCCESS) || + (read_tuple(handle, CISTPL_VERS_1, p) == CS_SUCCESS) || + (read_tuple(handle, CISTPL_VERS_2, p) != CS_NO_MORE_ITEMS)) ident_ok++; if (!dev_ok && !ident_ok) - return CS_SUCCESS; + goto done; for (info->Chains = 1; info->Chains < MAX_TUPLES; info->Chains++) { - ret = pcmcia_get_next_tuple(handle, &tuple); + ret = pcmcia_get_next_tuple(handle, tuple); if (ret != CS_SUCCESS) break; - if (((tuple.TupleCode > 0x23) && (tuple.TupleCode < 0x40)) || - ((tuple.TupleCode > 0x47) && (tuple.TupleCode < 0x80)) || - ((tuple.TupleCode > 0x90) && (tuple.TupleCode < 0xff))) + if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) || + ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) || + ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff))) reserved++; } if ((info->Chains == MAX_TUPLES) || (reserved > 5) || ((!dev_ok || !ident_ok) && (info->Chains > 10))) info->Chains = 0; +done: + kfree(tuple); + kfree(p); return CS_SUCCESS; } Index: drivers/pcmcia/cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pcmcia/cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pcmcia/cs.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/pcmcia/cs.c 4 Aug 2004 01:29:27 -0000 1.2 @@ -3,7 +3,7 @@ Kernel Card Services -- core services cs.c 1.271 2000/10/02 20:27:49 - + 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 @@ -28,7 +28,7 @@ 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. - + ======================================================================*/ #include @@ -92,7 +92,7 @@ MODULE_AUTHOR("David Hinds "); MODULE_DESCRIPTION("Linux Kernel Card Services " CS_RELEASE "\n options:" OPTIONS); -MODULE_LICENSE("Dual MPL/GPL"); +MODULE_LICENSE("Dual MPL/GPL"); #define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i") @@ -123,7 +123,7 @@ static const char *version = "cs.c 1.279 2001/10/13 00:08:28 (David Hinds)"; #endif - + /*====================================================================*/ socket_state_t dead_socket = { @@ -299,7 +299,7 @@ Low-level PC Card interface drivers need to register with Card Services using these calls. - + ======================================================================*/ static int setup_socket(socket_info_t *); @@ -331,7 +331,7 @@ s->use_bus_pm = use_bus_pm; s->erase_busy.next = s->erase_busy.prev = &s->erase_busy; spin_lock_init(&s->lock); - + for (i = 0; i < sockets; i++) if (socket_table[i] == NULL) break; socket_table[i] = s; @@ -365,7 +365,7 @@ for (ns = 0; ns < nsock; ns++) { pcmcia_register_socket (ns, ss_entry, 0); } - + return 0; } /* register_ss_entry */ @@ -457,7 +457,7 @@ static void shutdown_socket(socket_info_t *s) { client_t **c; - + DEBUG(1, "cs: shutdown_socket(%p)\n", s); /* Blank out the socket state */ @@ -561,7 +561,7 @@ have several causes: card insertion, a call to reset_socket, or recovery from a suspend/resume cycle. Unreset_socket() sends a CS event that matches the cause of the reset. - + ======================================================================*/ static void reset_socket(socket_info_t *s) @@ -616,7 +616,7 @@ s->state &= ~SOCKET_SETUP_PENDING; } else { send_event(s, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW); - if (s->reset_handle) { + if (s->reset_handle) { s->reset_handle->event_callback_args.info = NULL; EVENT(s->reset_handle, CS_EVENT_RESET_COMPLETE, CS_EVENT_PRI_LOW); @@ -631,7 +631,7 @@ valid clients. Parse_events() interprets the event bits from a card status change report. Do_shutdown() handles the high priority stuff associated with a card removal. - + ======================================================================*/ static int send_event(socket_info_t *s, event_t event, int priority) @@ -641,7 +641,7 @@ DEBUG(1, "cs: send_event(sock %d, event %d, pri %d)\n", s->sock, event, priority); ret = 0; - for (; client; client = client->next) { + for (; client; client = client->next) { if (client->state & (CLIENT_UNBOUND|CLIENT_STALE)) continue; if (client->EventMask & event) { @@ -723,7 +723,7 @@ This does not comply with the latest PC Card spec for handling power management events. - + ======================================================================*/ void pcmcia_suspend_socket (socket_info_t *s) @@ -780,7 +780,7 @@ /*====================================================================== Special stuff for managing IO windows, because they are scarce. - + ======================================================================*/ static int alloc_io_space(socket_info_t *s, u_int attr, ioaddr_t *base, @@ -869,7 +869,7 @@ Access_configuration_register() reads and writes configuration registers in attribute memory. Memory window 0 is reserved for this and the tuple reading services. - + ======================================================================*/ int pcmcia_access_configuration_register(client_handle_t handle, @@ -879,7 +879,7 @@ config_t *c; int addr; u_char val; - + if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; s = SOCKET(handle); @@ -897,7 +897,7 @@ return CS_CONFIGURATION_LOCKED; addr = (c->ConfigBase + reg->Offset) >> 1; - + switch (reg->Action) { case CS_READ: read_cis_mem(s, 1, addr, 1, &val); @@ -920,7 +920,7 @@ It is normally called by Driver Services after it has identified a newly inserted card. An instance of that driver will then be eligible to register as a client of this socket. - + ======================================================================*/ int pcmcia_bind_device(bind_req_t *req) @@ -956,23 +956,23 @@ region. It is normally called by Driver Services after it has identified a memory device type. An instance of the corresponding driver will then be able to register to control this region. - + ======================================================================*/ int pcmcia_bind_mtd(mtd_bind_t *req) { socket_info_t *s; memory_handle_t region; - + if (CHECK_SOCKET(req->Socket)) return CS_BAD_SOCKET; s = SOCKET(req); - + if (req->Attributes & REGION_TYPE_AM) region = s->a_region; else region = s->c_region; - + while (region) { if (region->info.CardOffset == req->CardOffset) break; region = region->info.next; @@ -980,7 +980,7 @@ if (!region || (region->mtd != NULL)) return CS_BAD_OFFSET; strncpy(region->dev_info, (char *)req->dev_info, DEV_NAME_LEN); - + DEBUG(1, "cs: bind_mtd(): attr 0x%x, offset 0x%x, dev %s\n", req->Attributes, req->CardOffset, (char *)req->dev_info); return CS_SUCCESS; @@ -995,7 +995,7 @@ memory_handle_t region; u_long flags; int i, sn; - + DEBUG(1, "cs: deregister_client(%p)\n", handle); if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; @@ -1014,7 +1014,7 @@ for (region = s->c_region; region; region = region->info.next) if (region->mtd == handle) region->mtd = NULL; } - + sn = handle->Socket; s = socket_table[sn]; if ((handle->state & CLIENT_STALE) || @@ -1039,7 +1039,7 @@ if (--s->real_clients == 0) register_callback(s, NULL, NULL); - + return CS_SUCCESS; } /* deregister_client */ @@ -1050,7 +1050,7 @@ { socket_info_t *s; config_t *c; - + if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; s = SOCKET(handle); @@ -1062,7 +1062,7 @@ return CS_BAD_ARGS; } else config->Function = handle->Function; - + #ifdef CONFIG_CARDBUS if (s->state & SOCKET_CARDBUS) { u_char fn = config->Function; @@ -1083,16 +1083,16 @@ return CS_SUCCESS; } #endif - + c = (s->config != NULL) ? &s->config[config->Function] : NULL; - + if ((c == NULL) || !(c->state & CONFIG_LOCKED)) { config->Attributes = 0; config->Vcc = s->socket.Vcc; config->Vpp1 = config->Vpp2 = s->socket.Vpp; return CS_SUCCESS; } - + /* !!! This is a hack !!! */ memcpy(&config->Attributes, &c->Attributes, sizeof(config_t)); config->Attributes |= CONF_VALID_CLIENT; @@ -1106,14 +1106,14 @@ config->NumPorts2 = c->io.NumPorts2; config->Attributes2 = c->io.Attributes2; config->IOAddrLines = c->io.IOAddrLines; - + return CS_SUCCESS; } /* get_configuration_info */ /*====================================================================== Return information about this version of Card Services. - + ======================================================================*/ int pcmcia_get_card_services_info(servinfo_t *info) @@ -1131,7 +1131,7 @@ Note that get_first_client() *does* recognize the Socket field in the request structure. - + ======================================================================*/ int pcmcia_get_first_client(client_handle_t *handle, client_req_t *req) @@ -1246,7 +1246,7 @@ Get the current socket state bits. We don't support the latched SocketState yet: I haven't seen any point for it. - + ======================================================================*/ int pcmcia_get_status(client_handle_t handle, cs_status_t *status) @@ -1254,7 +1254,7 @@ socket_info_t *s; config_t *c; int val; - + if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; s = SOCKET(handle); @@ -1270,7 +1270,7 @@ return CS_NO_CARD; if (s->state & SOCKET_SETUP_PENDING) status->CardState |= CS_EVENT_CARD_INSERTION; - + /* Get info from the PRR, if necessary */ if (handle->Function == BIND_FN_ALL) { if (status->Function && (status->Function >= s->functions)) @@ -1316,7 +1316,7 @@ /*====================================================================== Change the card address of an already open memory window. - + ======================================================================*/ int pcmcia_get_mem_page(window_handle_t win, memreq_t *req) @@ -1345,7 +1345,7 @@ /*====================================================================== Modify a locked socket configuration - + ======================================================================*/ int pcmcia_modify_configuration(client_handle_t handle, @@ -1353,7 +1353,7 @@ { socket_info_t *s; config_t *c; - + if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; s = SOCKET(handle); c = CONFIG(handle); @@ -1361,7 +1361,7 @@ return CS_NO_CARD; if (!(c->state & CONFIG_LOCKED)) return CS_CONFIGURATION_LOCKED; - + if (mod->Attributes & CONF_IRQ_CHANGE_VALID) { if (mod->Attributes & CONF_ENABLE_IRQ) { c->Attributes |= CONF_ENABLE_IRQ; @@ -1413,7 +1413,7 @@ win->ctl.flags |= MAP_USE_WAIT; win->ctl.speed = req->AccessSpeed; set_mem_map(win->sock, &win->ctl); - + return CS_SUCCESS; } /* modify_window */ @@ -1423,7 +1423,7 @@ caller with a socket. The driver must have already been bound to a socket with bind_device() -- in fact, bind_device() allocates the client structure that will be used. - + ======================================================================*/ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req) @@ -1431,7 +1431,7 @@ client_t *client; socket_info_t *s; socket_t ns; - + /* Look for unbound client with matching dev_info */ client = NULL; for (ns = 0; ns < sockets; ns++) { @@ -1471,7 +1471,7 @@ if (s->state & SOCKET_CARDBUS) client->state |= CLIENT_CARDBUS; - + if ((!(s->state & SOCKET_CARDBUS)) && (s->functions == 0) && (client->Function != BIND_FN_ALL)) { cistpl_longlink_mfc_t mfc; @@ -1486,7 +1486,7 @@ return CS_OUT_OF_RESOURCE; memset(s->config, 0, sizeof(config_t) * s->functions); } - + DEBUG(1, "cs: register_client(): client 0x%p, sock %d, dev %s\n", client, client->Socket, client->dev_info); if (client->EventMask & CS_EVENT_REGISTRATION_COMPLETE) @@ -1508,13 +1508,13 @@ pccard_io_map io = { 0, 0, 0, 0, 1 }; socket_info_t *s; int i; - + if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_CONFIG_LOCKED)) return CS_BAD_HANDLE; handle->state &= ~CLIENT_CONFIG_LOCKED; s = SOCKET(handle); - + #ifdef CONFIG_CARDBUS if (handle->state & CLIENT_CARDBUS) { cb_disable(s); @@ -1522,7 +1522,7 @@ return CS_SUCCESS; } #endif - + if (!(handle->state & CLIENT_STALE)) { config_t *c = CONFIG(handle); if (--(s->lock_count) == 0) { @@ -1543,7 +1543,7 @@ } c->state &= ~CONFIG_LOCKED; } - + return CS_SUCCESS; } /* release_configuration */ @@ -1554,25 +1554,25 @@ the actual socket configuration, so if the client is "stale", we don't bother checking the port ranges against the current socket values. - + ======================================================================*/ int pcmcia_release_io(client_handle_t handle, io_req_t *req) { socket_info_t *s; - + if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IO_REQ)) return CS_BAD_HANDLE; handle->state &= ~CLIENT_IO_REQ; s = SOCKET(handle); - + #ifdef CONFIG_CARDBUS if (handle->state & CLIENT_CARDBUS) { cb_release(s); return CS_SUCCESS; } #endif - + if (!(handle->state & CLIENT_STALE)) { config_t *c = CONFIG(handle); if (c->state & CONFIG_LOCKED) @@ -1588,7 +1588,7 @@ release_io_space(s, req->BasePort1, req->NumPorts1); if (req->NumPorts2) release_io_space(s, req->BasePort2, req->NumPorts2); - + return CS_SUCCESS; } /* release_io */ @@ -1601,7 +1601,7 @@ return CS_BAD_HANDLE; handle->state &= ~CLIENT_IRQ_REQ; s = SOCKET(handle); - + if (!(handle->state & CLIENT_STALE)) { config_t *c = CONFIG(handle); if (c->state & CONFIG_LOCKED) @@ -1615,7 +1615,7 @@ s->irq.AssignedIRQ = 0; } } - + if (req->Attributes & IRQ_HANDLE_PRESENT) { bus_free_irq(s->cap.bus, req->AssignedIRQ, req->Instance); } @@ -1624,7 +1624,7 @@ if (req->AssignedIRQ != s->cap.pci_irq) undo_irq(req->Attributes, req->AssignedIRQ); #endif - + return CS_SUCCESS; } /* cs_release_irq */ @@ -1633,7 +1633,7 @@ int pcmcia_release_window(window_handle_t win) { socket_info_t *s; - + if ((win == NULL) || (win->magic != WINDOW_MAGIC)) return CS_BAD_HANDLE; s = win->sock; @@ -1651,7 +1651,7 @@ win->handle->state &= ~CLIENT_WIN_REQ(win->index); win->magic = 0; - + return CS_SUCCESS; } /* release_window */ @@ -1665,13 +1665,13 @@ socket_info_t *s; config_t *c; pccard_io_map iomap; - + if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; i = handle->Socket; s = socket_table[i]; if (!(s->state & SOCKET_PRESENT)) return CS_NO_CARD; - + #ifdef CONFIG_CARDBUS if (handle->state & CLIENT_CARDBUS) { if (!(req->IntType & INT_CARDBUS)) @@ -1684,7 +1684,7 @@ return CS_SUCCESS; } #endif - + if (req->IntType & INT_CARDBUS) return CS_UNSUPPORTED_MODE; c = CONFIG(handle); @@ -1699,9 +1699,9 @@ s->socket.Vpp = req->Vpp1; if (set_socket(s, &s->socket)) return CS_BAD_VPP; - + c->Vcc = req->Vcc; c->Vpp1 = c->Vpp2 = req->Vpp1; - + /* Pick memory or I/O card, DMA mode, interrupt */ c->IntType = req->IntType; c->Attributes = req->Attributes; @@ -1719,7 +1719,7 @@ s->socket.io_irq = 0; set_socket(s, &s->socket); s->lock_count++; - + /* Set up CIS configuration registers */ base = c->ConfigBase = req->ConfigBase; c->Present = c->CardValues = req->Present; @@ -1764,7 +1764,7 @@ u_char b = c->io.NumPorts1 + c->io.NumPorts2 - 1; write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &b); } - + /* Configure I/O windows */ if (c->state & CONFIG_IO_REQ) { iomap.speed = io_speed; @@ -1786,24 +1786,24 @@ s->io[i].Config++; } } - + c->state |= CONFIG_LOCKED; handle->state |= CLIENT_CONFIG_LOCKED; return CS_SUCCESS; } /* request_configuration */ /*====================================================================== - + Request_io() reserves ranges of port addresses for a socket. I have not implemented range sharing or alias addressing. - + ======================================================================*/ int pcmcia_request_io(client_handle_t handle, io_req_t *req) { socket_info_t *s; config_t *c; - + if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; s = SOCKET(handle); @@ -1862,15 +1862,15 @@ hooked, we don't guarantee that an irq will still be available when the configuration is locked. Now that I think about it, there might be a way to fix this using a dummy handler. - + ======================================================================*/ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req) { socket_info_t *s; config_t *c; - int ret = 0, irq = 0; - + int ret = CS_IN_USE, irq = 0; + if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; s = SOCKET(handle); @@ -1881,13 +1881,9 @@ return CS_CONFIGURATION_LOCKED; if (c->state & CONFIG_IRQ_REQ) return CS_IN_USE; - - /* Short cut: if there are no ISA interrupts, then it is PCI */ - if (!s->cap.irq_mask) { - irq = s->cap.pci_irq; - ret = (irq) ? 0 : CS_IN_USE; + #ifdef CONFIG_PCMCIA_PROBE - } else if (s->irq.AssignedIRQ != 0) { + if (s->irq.AssignedIRQ != 0) { /* If the interrupt is already assigned, it must match */ irq = s->irq.AssignedIRQ; if (req->IRQInfo1 & IRQ_INFO2_VALID) { @@ -1896,7 +1892,6 @@ } else ret = ((req->IRQInfo1&IRQ_MASK) == irq) ? 0 : CS_BAD_ARGS; } else { - ret = CS_IN_USE; if (req->IRQInfo1 & IRQ_INFO2_VALID) { u_int try, mask = req->IRQInfo2 & s->cap.irq_mask; for (try = 0; try < 2; try++) { @@ -1911,13 +1906,17 @@ irq = req->IRQInfo1 & IRQ_MASK; ret = try_irq(req->Attributes, irq, 1); } + } #endif + if (ret != 0) { + if (!s->cap.pci_irq) + return ret; + irq = s->cap.pci_irq; } - if (ret != 0) return ret; if (req->Attributes & IRQ_HANDLE_PRESENT) { if (bus_request_irq(s->cap.bus, irq, req->Handler, - ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) || + ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) || (s->functions > 1) || (irq == s->cap.pci_irq)) ? SA_SHIRQ : 0, handle->dev_info, req->Instance)) @@ -1927,7 +1926,7 @@ c->irq.Attributes = req->Attributes; s->irq.AssignedIRQ = req->AssignedIRQ = irq; s->irq.Config++; - + c->state |= CONFIG_IRQ_REQ; handle->state |= CLIENT_IRQ_REQ; return CS_SUCCESS; @@ -1946,7 +1945,7 @@ window_t *win; u_long align; int w; - + if (CHECK_HANDLE(*handle)) return CS_BAD_HANDLE; s = SOCKET(*handle); @@ -2013,7 +2012,7 @@ /* Return window handle */ req->Base = win->ctl.sys_start; *wh = win; - + return CS_SUCCESS; } /* request_window */ @@ -2022,14 +2021,14 @@ I'm not sure which "reset" function this is supposed to use, but for now, it uses the low-level interface's reset, not the CIS register. - + ======================================================================*/ int pcmcia_reset_card(client_handle_t handle, client_req_t *req) { int i, ret; socket_info_t *s; - + if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; i = handle->Socket; s = socket_table[i]; @@ -2057,14 +2056,14 @@ These shut down or wake up a socket. They are sort of user initiated versions of the APM suspend and resume actions. - + ======================================================================*/ int pcmcia_suspend_card(client_handle_t handle, client_req_t *req) { int i; socket_info_t *s; - + if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; i = handle->Socket; s = socket_table[i]; @@ -2085,7 +2084,7 @@ { int i; socket_info_t *s; - + if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; i = handle->Socket; s = socket_table[i]; @@ -2103,7 +2102,7 @@ /*====================================================================== These handle user requests to eject or insert a card. - + ======================================================================*/ int pcmcia_eject_card(client_handle_t handle, client_req_t *req) @@ -2111,7 +2110,7 @@ int i, ret; socket_info_t *s; u_long flags; - + if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; i = handle->Socket; s = socket_table[i]; @@ -2127,9 +2126,9 @@ spin_lock_irqsave(&s->lock, flags); do_shutdown(s); spin_unlock_irqrestore(&s->lock, flags); - + return CS_SUCCESS; - + } /* eject_card */ int pcmcia_insert_card(client_handle_t handle, client_req_t *req) @@ -2137,7 +2136,7 @@ int i, status; socket_info_t *s; u_long flags; - + if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; i = handle->Socket; s = socket_table[i]; @@ -2165,7 +2164,7 @@ Maybe this should send a CS_EVENT_CARD_INSERTION event if we haven't sent one to this client yet? - + ======================================================================*/ int pcmcia_set_event_mask(client_handle_t handle, eventmask_t *mask) @@ -2197,7 +2196,7 @@ printk(KERN_NOTICE); else printk(KERN_NOTICE "%s: ", handle->dev_info); - + for (i = 0; i < SERVICE_COUNT; i++) if (service_table[i].key == err->func) break; if (i < SERVICE_COUNT) @@ -2355,13 +2354,13 @@ default: return CS_UNSUPPORTED_FUNCTION; break; } - + } /* CardServices */ /*====================================================================== OS-specific module glue goes here - + ======================================================================*/ /* in alpha order */ EXPORT_SYMBOL(pcmcia_access_configuration_register); @@ -2458,4 +2457,3 @@ module_exit(exit_pcmcia_cs); /*====================================================================*/ - Index: drivers/pcmcia/hd64465_ss.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pcmcia/hd64465_ss.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pcmcia/hd64465_ss.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/pcmcia/hd64465_ss.c 4 Aug 2004 01:29:27 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: hd64465_ss.c,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: hd64465_ss.c,v 1.2 2004/08/04 01:29:27 joff Exp $ * * Device driver for the PCMCIA controller module of the * Hitachi HD64465 handheld companion chip. Index: drivers/pcmcia/i82092.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pcmcia/i82092.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pcmcia/i82092.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/pcmcia/i82092.c 4 Aug 2004 01:29:27 -0000 1.2 @@ -6,7 +6,7 @@ * Author: Arjan Van De Ven * Loosely based on i82365.c from the pcmcia-cs package * - * $Id: i82092.c,v 1.1 2004/07/22 19:50:25 joff Exp $ + * $Id: i82092.c,v 1.2 2004/08/04 01:29:27 joff Exp $ */ #include @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include Index: drivers/pcmcia/i82092aa.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pcmcia/i82092aa.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pcmcia/i82092aa.h 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/pcmcia/i82092aa.h 4 Aug 2004 01:29:27 -0000 1.2 @@ -1,7 +1,7 @@ #ifndef _INCLUDE_GUARD_i82092aa_H_ #define _INCLUDE_GUARD_i82092aa_H_ -/* $Id: i82092aa.h,v 1.1 2004/07/22 19:50:25 joff Exp $ */ +/* $Id: i82092aa.h,v 1.2 2004/08/04 01:29:27 joff Exp $ */ /* Debuging defines */ #ifdef NOTRACE Index: drivers/pcmcia/i82365.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pcmcia/i82365.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pcmcia/i82365.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/pcmcia/i82365.c 4 Aug 2004 01:29:27 -0000 1.2 @@ -28,7 +28,7 @@ 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. - + ======================================================================*/ #include @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -98,7 +97,6 @@ /* Parameters that can be set with 'insmod' */ -#ifdef CONFIG_ISA /* Default base address for i82365sl and other ISA chips */ static int i365_base = 0x3e0; /* Should we probe at 0x3e2 for an extra ISA controller? */ @@ -110,7 +108,6 @@ static int irq_list[16] = { -1 }; /* The card status change interrupt -- 0 means autoselect */ static int cs_irq = 0; -#endif /* Probe for safe interrupts? */ static int do_scan = 1; @@ -129,14 +126,11 @@ static int cmd_time = -1; static int recov_time = -1; -#ifdef CONFIG_ISA /* Vadem options */ static int async_clock = -1; static int cable_mode = -1; static int wakeup = 0; -#endif -#ifdef CONFIG_ISA MODULE_PARM(i365_base, "i"); MODULE_PARM(ignore, "i"); MODULE_PARM(extra_sockets, "i"); @@ -146,7 +140,6 @@ MODULE_PARM(async_clock, "i"); MODULE_PARM(cable_mode, "i"); MODULE_PARM(wakeup, "i"); -#endif MODULE_PARM(do_scan, "i"); MODULE_PARM(poll_interval, "i"); @@ -199,45 +192,29 @@ #define I365_MASK 0xdeb8 /* irq 15,14,12,11,10,9,7,5,4,3 */ #endif -#ifdef CONFIG_ISA static int grab_irq; static spinlock_t isa_lock = SPIN_LOCK_UNLOCKED; #define ISA_LOCK(n, f) spin_lock_irqsave(&isa_lock, f) #define ISA_UNLOCK(n, f) spin_unlock_irqrestore(&isa_lock, f) -#else -#define ISA_LOCK(n, f) do { } while (0) -#define ISA_UNLOCK(n, f) do { } while (0) -#endif static struct timer_list poll_timer; /*====================================================================*/ -/* Default settings for PCI command configuration register */ -#define CMD_DFLT (PCI_COMMAND_IO|PCI_COMMAND_MEMORY| \ - PCI_COMMAND_MASTER|PCI_COMMAND_WAIT) - /* These definitions must match the pcic table! */ -#ifdef CONFIG_ISA typedef enum pcic_id { IS_I82365A, IS_I82365B, IS_I82365DF, IS_IBM, IS_RF5Cx96, IS_VLSI, IS_VG468, IS_VG469, IS_PD6710, IS_PD672X, IS_VT83C469, } pcic_id; -#endif /* Flags for classifying groups of controllers */ #define IS_VADEM 0x0001 #define IS_CIRRUS 0x0002 -#define IS_TI 0x0004 -#define IS_O2MICRO 0x0008 #define IS_VIA 0x0010 -#define IS_TOPIC 0x0020 -#define IS_RICOH 0x0040 #define IS_UNKNOWN 0x0400 #define IS_VG_PWR 0x0800 #define IS_DF_PWR 0x1000 -#define IS_PCI 0x2000 #define IS_ALIVE 0x8000 typedef struct pcic_t { @@ -246,7 +223,6 @@ } pcic_t; static pcic_t pcic[] = { -#ifdef CONFIG_ISA { "Intel i82365sl A step", 0 }, { "Intel i82365sl B step", 0 }, { "Intel i82365sl DF", IS_DF_PWR }, @@ -258,7 +234,6 @@ { "Cirrus PD6710", IS_CIRRUS }, { "Cirrus PD672x", IS_CIRRUS }, { "VIA VT83C469", IS_CIRRUS|IS_VIA }, -#endif }; #define PCIC_COUNT (sizeof(pcic)/sizeof(pcic_t)) @@ -339,7 +314,7 @@ The VIA controllers also use these routines, as they are mostly Cirrus lookalikes, without the timing registers. - + ======================================================================*/ #define flip(v,b,f) (v = ((f)<0) ? v : ((f) ? ((v)|(b)) : ((v)&(~b)))) @@ -380,26 +355,24 @@ if (has_ring == -1) has_ring = 1; flip(p->misc2, PD67_MC2_IRQ15_RI, has_ring); flip(p->misc2, PD67_MC2_DYNAMIC_MODE, dynamic_mode); + flip(p->misc2, PD67_MC2_FREQ_BYPASS, freq_bypass); if (p->misc2 & PD67_MC2_IRQ15_RI) strcat(buf, " [ring]"); if (p->misc2 & PD67_MC2_DYNAMIC_MODE) strcat(buf, " [dyn mode]"); + if (p->misc2 & PD67_MC2_FREQ_BYPASS) + strcat(buf, " [freq bypass]"); if (p->misc1 & PD67_MC1_INPACK_ENA) strcat(buf, " [inpack]"); - if (!(t->flags & IS_PCI)) { - if (p->misc2 & PD67_MC2_IRQ15_RI) - mask &= ~0x8000; - if (has_led > 0) { - strcat(buf, " [led]"); - mask &= ~0x1000; - } - if (has_dma > 0) { - strcat(buf, " [dma]"); - mask &= ~0x0600; - flip(p->misc2, PD67_MC2_FREQ_BYPASS, freq_bypass); - if (p->misc2 & PD67_MC2_FREQ_BYPASS) - strcat(buf, " [freq bypass]"); - } + if (p->misc2 & PD67_MC2_IRQ15_RI) + mask &= ~0x8000; + if (has_led > 0) { + strcat(buf, " [led]"); + mask &= ~0x1000; + } + if (has_dma > 0) { + strcat(buf, " [dma]"); + mask &= ~0x0600; } if (!(t->flags & IS_VIA)) { if (setup_time >= 0) @@ -427,10 +400,8 @@ Code to save and restore global state information for Vadem VG468 and VG469 controllers, and to set and report global configuration options. - -======================================================================*/ -#ifdef CONFIG_ISA +======================================================================*/ static void vg46x_get_state(u_short s) { @@ -451,7 +422,7 @@ static u_int __init vg46x_set_opts(u_short s, char *buf) { vg46x_state_t *p = &socket[s].state.vg46x; - + flip(p->ctl, VG468_CTL_ASYNC, async_clock); flip(p->ema, VG469_MODE_CABLE, cable_mode); if (p->ctl & VG468_CTL_ASYNC) @@ -473,13 +444,10 @@ return 0xffff; } -#endif - - /*====================================================================== Generic routines to get and set controller options - + ======================================================================*/ static void get_bridge_state(u_short s) @@ -487,10 +455,8 @@ socket_info_t *t = &socket[s]; if (t->flags & IS_CIRRUS) cirrus_get_state(s); -#ifdef CONFIG_ISA else if (t->flags & IS_VADEM) vg46x_get_state(s); -#endif } static void set_bridge_state(u_short s) @@ -503,10 +469,8 @@ i365_set(s, I365_GENCTL, 0x00); } i365_bflip(s, I365_INTCTL, I365_INTR_ENA, t->intr); -#ifdef CONFIG_ISA if (t->flags & IS_VADEM) vg46x_set_state(s); -#endif } static u_int __init set_bridge_opts(u_short s, u_short ns) @@ -524,10 +488,8 @@ get_bridge_state(i); if (socket[i].flags & IS_CIRRUS) m = cirrus_set_opts(i, buf); -#ifdef CONFIG_ISA else if (socket[i].flags & IS_VADEM) m = vg46x_set_opts(i, buf); -#endif set_bridge_state(i); printk(KERN_INFO " host opts [%d]:%s\n", i, (*buf) ? buf : " none"); @@ -538,7 +500,7 @@ /*====================================================================== Interrupt testing code, for ISA and PCI interrupts - + ======================================================================*/ static volatile u_int irq_hits; @@ -575,12 +537,10 @@ /* mask all interrupts */ i365_set(sock, I365_CSCINT, 0); DEBUG(2, " hits = %d\n", irq_hits); - + return (irq_hits != 1); } -#ifdef CONFIG_ISA - static u_int __init isa_scan(u_short sock, u_int mask0) { u_int mask1 = 0; @@ -591,7 +551,7 @@ /* Don't probe level-triggered interrupts -- reserved for PCI */ mask0 &= ~(inb(PIC) | (inb(PIC+1) << 8)); #endif - + if (do_scan) { set_bridge_state(sock); i365_set(sock, I365_CSCINT, 0); @@ -602,7 +562,7 @@ if ((mask1 & (1 << i)) && (test_irq(sock, i) != 0)) mask1 ^= (1 << i); } - + printk(KERN_INFO " ISA irqs ("); if (mask1) { printk("scanned"); @@ -616,17 +576,15 @@ if (!cs_irq && (poll_interval == 0)) poll_interval = HZ; } printk(") = "); - + for (i = 0; i < 16; i++) if (mask1 & (1<ioaddr > 0) request_region(t->ioaddr, 2, "i82365"); - + if (base == 0) printk("\n"); printk(KERN_INFO " %s", pcic[type].name); printk(" ISA-to-PCMCIA at port %#x ofs 0x%02x", t->ioaddr, t->psock*0x40); printk(", %d socket%s\n", ns, ((ns > 1) ? "s" : "")); -#ifdef CONFIG_ISA /* Set host options, build basic interrupt mask */ if (irq_list[0] == -1) mask = irq_mask; else for (i = mask = 0; i < 16; i++) mask |= (1< 0; cs_irq--) @@ -799,16 +746,15 @@ printk(" status change on irq %d\n", cs_irq); } } -#endif - - if (!use_pci && !isa_irq) { + + if (!isa_irq) { if (poll_interval == 0) poll_interval = HZ; printk(" polling interval = %d ms\n", poll_interval * 1000 / HZ); - + } - + /* Update socket interrupt information, capabilities */ for (i = 0; i < ns; i++) { t[i].cap.features |= SS_CAP_PCCARD; @@ -819,11 +765,8 @@ } /* add_pcic */ - /*====================================================================*/ -#ifdef CONFIG_ISA - #if defined(CONFIG_ISAPNP) || (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE)) #define I82365_ISAPNP #endif @@ -893,7 +836,9 @@ } } } else { - for (i = 0; i < (extra_sockets ? 8 : 4); i += 2) { + for (i = 0; i < 8; i += 2) { + if (sockets && !extra_sockets && (i == 4)) + break; port = i365_base + 2*(i>>2); sock = (i & 3); id = identify(port, sock); @@ -917,8 +862,6 @@ } } -#endif - /*====================================================================*/ static u_int pending_events[8]; @@ -934,12 +877,12 @@ events = pending_events[i]; pending_events[i] = 0; spin_unlock_irq(&pending_event_lock); - /* - SS_DETECT events need a small delay here. The reason for this is that + /* + SS_DETECT events need a small delay here. The reason for this is that the "is there a card" electronics need time to see the card after the - "we have a card coming in" electronics have seen it. + "we have a card coming in" electronics have seen it. */ - if (events & SS_DETECT) + if (events & SS_DETECT) mdelay(4); if (socket[i].handler) socket[i].handler(socket[i].info, events); @@ -957,17 +900,14 @@ { int i, j, csc; u_int events, active; -#ifdef CONFIG_ISA u_long flags = 0; -#endif - + DEBUG(4, "i82365: pcic_interrupt(%d)\n", irq); for (j = 0; j < 20; j++) { active = 0; for (i = 0; i < sockets; i++) { - if ((socket[i].cs_irq != irq) && - (socket[i].cap.pci_irq != irq)) + if (socket[i].cs_irq != irq) continue; ISA_LOCK(i, flags); csc = i365_get(i, I365_CSC); @@ -977,20 +917,20 @@ continue; } events = (csc & I365_CSC_DETECT) ? SS_DETECT : 0; - - + + /* Several sockets will send multiple "new card detected" - events in rapid succession. However, the rest of the pcmcia expects + events in rapid succession. However, the rest of the pcmcia expects only one such event. We just ignore these events by having a timeout */ if (events) { - if ((jiffies - last_detect_jiffies)<(HZ/20)) + if ((jiffies - last_detect_jiffies)<(HZ/20)) events = 0; last_detect_jiffies = jiffies; - + } - + if (i365_get(i, I365_INTCTL) & I365_PC_IOCARD) events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0; else { @@ -1051,11 +991,11 @@ static int i365_get_status(u_short sock, u_int *value) { u_int status; - + status = i365_get(sock, I365_STATUS); *value = ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0; - + if (i365_get(sock, I365_INTCTL) & I365_PC_IOCARD) *value |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG; else { @@ -1066,7 +1006,6 @@ *value |= (status & I365_CS_READY) ? SS_READY : 0; *value |= (status & I365_CS_POWERON) ? SS_POWERON : 0; -#ifdef CONFIG_ISA if (socket[sock].type == IS_VG469) { status = i365_get(sock, VG469_VSENSE); if (socket[sock].psock & 1) { @@ -1077,8 +1016,7 @@ *value |= (status & VG469_VSENSE_A_VS2) ? 0 : SS_XVCARD; } } -#endif - + DEBUG(1, "i82365: GetStatus(%d) = %#4.4x\n", sock, *value); return 0; } /* i365_get_status */ @@ -1089,7 +1027,7 @@ { socket_info_t *t = &socket[sock]; u_char reg, vcc, vpp; - + reg = i365_get(sock, I365_POWER); state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0; state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0; @@ -1131,13 +1069,13 @@ state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET; if (reg & I365_PC_IOCARD) state->flags |= SS_IOCARD; state->io_irq = REG2SOCKIRQ(sock, reg & I365_IRQ_MASK); - + /* speaker control */ if (t->flags & IS_CIRRUS) { if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_SPKR_ENA) state->flags |= SS_SPKR_ENA; } - + /* Card status change mask */ reg = i365_get(sock, I365_CSCINT); state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0; @@ -1148,7 +1086,7 @@ state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0; state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0; } - + DEBUG(1, "i82365: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " "io_irq %d, csc_mask %#2.2x\n", sock, state->flags, state->Vcc, state->Vpp, state->io_irq, state->csc_mask); @@ -1161,21 +1099,21 @@ { socket_info_t *t = &socket[sock]; u_char reg; - + DEBUG(1, "i82365: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags, state->Vcc, state->Vpp, state->io_irq, state->csc_mask); - + /* First set global controller options */ set_bridge_state(sock); - + /* IO card, RESET flag, IO interrupt */ reg = t->intr; - if (state->io_irq != t->cap.pci_irq) reg |= SOCKIRQ2REG(sock, state->io_irq); + reg |= SOCKIRQ2REG(sock, state->io_irq); reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET; reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0; i365_set(sock, I365_INTCTL, reg); - + reg = I365_PWR_NORESET; if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO; if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT; @@ -1238,7 +1176,7 @@ default: return -EINVAL; } } - + if (reg != i365_get(sock, I365_POWER)) i365_set(sock, I365_POWER, reg); @@ -1248,7 +1186,7 @@ i365_bflip(sock, PD67_MISC_CTL_1, PD67_MC1_SPKR_ENA, state->flags & SS_SPKR_ENA); } - + /* Card status change interrupt mask */ reg = SOCKIRQ2REG(sock, t->cs_irq) << 4; if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT; @@ -1261,7 +1199,7 @@ } i365_set(sock, I365_CSCINT, reg); i365_get(sock, I365_CSC); - + return 0; } /* i365_set_socket */ @@ -1270,7 +1208,7 @@ static int i365_get_io_map(u_short sock, struct pccard_io_map *io) { u_char map, ioctl, addr; - + map = io->map; if (map > 1) return -EINVAL; io->start = i365_get_pair(sock, I365_IO(map)+I365_W_START); @@ -1293,7 +1231,7 @@ static int i365_set_io_map(u_short sock, struct pccard_io_map *io) { u_char map, ioctl; - + DEBUG(1, "i82365: SetIOMap(%d, %d, %#2.2x, %d ns, " "%#4.4x-%#4.4x)\n", sock, io->map, io->flags, io->speed, io->start, io->stop); @@ -1323,30 +1261,30 @@ { u_short base, i; u_char map, addr; - + map = mem->map; if (map > 4) return -EINVAL; addr = i365_get(sock, I365_ADDRWIN); mem->flags = (addr & I365_ENA_MEM(map)) ? MAP_ACTIVE : 0; base = I365_MEM(map); - + i = i365_get_pair(sock, base+I365_W_START); mem->flags |= (i & I365_MEM_16BIT) ? MAP_16BIT : 0; mem->flags |= (i & I365_MEM_0WS) ? MAP_0WS : 0; mem->sys_start = ((u_long)(i & 0x0fff) << 12); - + i = i365_get_pair(sock, base+I365_W_STOP); mem->speed = (i & I365_MEM_WS0) ? 1 : 0; mem->speed += (i & I365_MEM_WS1) ? 2 : 0; mem->speed = to_ns(mem->speed); mem->sys_stop = ((u_long)(i & 0x0fff) << 12) + 0x0fff; - + i = i365_get_pair(sock, base+I365_W_OFF); mem->flags |= (i & I365_MEM_WRPROT) ? MAP_WRPROT : 0; mem->flags |= (i & I365_MEM_REG) ? MAP_ATTRIB : 0; mem->card_start = ((u_int)(i & 0x3fff) << 12) + mem->sys_start; mem->card_start &= 0x3ffffff; - + DEBUG(1, "i82365: GetMemMap(%d, %d) = %#2.2x, %d ns, %#5.5lx-%#5." "5lx, %#5.5x\n", sock, mem->map, mem->flags, mem->speed, mem->sys_start, mem->sys_stop, mem->card_start); @@ -1354,12 +1292,12 @@ } /* i365_get_mem_map */ /*====================================================================*/ - + static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem) { u_short base, i; u_char map; - + DEBUG(1, "i82365: SetMemMap(%d, %d, %#2.2x, %d ns, %#5.5lx-%#5.5" "lx, %#5.5x)\n", sock, mem->map, mem->flags, mem->speed, mem->sys_start, mem->sys_stop, mem->card_start); @@ -1368,20 +1306,19 @@ if ((map > 4) || (mem->card_start > 0x3ffffff) || (mem->sys_start > mem->sys_stop) || (mem->speed > 1000)) return -EINVAL; - if (!(socket[sock].flags & IS_PCI) && - ((mem->sys_start > 0xffffff) || (mem->sys_stop > 0xffffff))) + if ((mem->sys_start > 0xffffff) || (mem->sys_stop > 0xffffff)) return -EINVAL; - + /* Turn off the window before changing anything */ if (i365_get(sock, I365_ADDRWIN) & I365_ENA_MEM(map)) i365_bclr(sock, I365_ADDRWIN, I365_ENA_MEM(map)); - + base = I365_MEM(map); i = (mem->sys_start >> 12) & 0x0fff; if (mem->flags & MAP_16BIT) i |= I365_MEM_16BIT; if (mem->flags & MAP_0WS) i |= I365_MEM_0WS; i365_set_pair(sock, base+I365_W_START, i); - + i = (mem->sys_stop >> 12) & 0x0fff; switch (to_cycles(mem->speed)) { case 0: break; @@ -1390,12 +1327,12 @@ default: i |= I365_MEM_WS1 | I365_MEM_WS0; break; } i365_set_pair(sock, base+I365_W_STOP, i); - + i = ((mem->card_start - mem->sys_start) >> 12) & 0x3fff; if (mem->flags & MAP_WRPROT) i |= I365_MEM_WRPROT; if (mem->flags & MAP_ATTRIB) i |= I365_MEM_REG; i365_set_pair(sock, base+I365_W_OFF, i); - + /* Turn on the window if necessary */ if (mem->flags & MAP_ACTIVE) i365_bset(sock, I365_ADDRWIN, I365_ENA_MEM(map)); @@ -1406,7 +1343,7 @@ Routines for accessing socket information and register dumps via /proc/bus/pccard/... - + ======================================================================*/ #ifdef CONFIG_PROC_FS @@ -1427,10 +1364,8 @@ u_short sock = (socket_info_t *)data - socket; char *p = buf; int i, top; - -#ifdef CONFIG_ISA + u_long flags = 0; -#endif ISA_LOCK(sock, flags); top = 0x40; for (i = 0; i < top; i += 4) { @@ -1475,15 +1410,8 @@ /*====================================================================*/ -/* - * The locking is rather broken. Why do we only lock for ISA, not for - * all other cases? If there are reasons to lock, we should lock. Not - * this silly conditional. - * - * Plan: make it bug-for-bug compatible with the old stuff, and clean - * it up when the infrastructure is done. - */ -#ifdef CONFIG_ISA +/* this is horribly ugly... proper locking needs to be done here at + * some time... */ #define LOCKED(x) do { \ int retval; \ unsigned long flags; \ @@ -1492,10 +1420,6 @@ spin_unlock_irqrestore(&isa_lock, flags); \ return retval; \ } while (0) -#else -#define LOCKED(x) return x -#endif - static int pcic_get_status(unsigned int sock, u_int *value) { @@ -1606,12 +1530,10 @@ return -1; } DEBUG(0, "%s\n", version); - printk(KERN_INFO "Intel PCIC probe: "); + printk(KERN_INFO "Intel ISA PCIC probe: "); sockets = 0; -#ifdef CONFIG_ISA isa_probe(); -#endif if (sockets == 0) { printk("not found.\n"); @@ -1619,11 +1541,9 @@ } /* Set up interrupt handler(s) */ -#ifdef CONFIG_ISA if (grab_irq != 0) request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt); -#endif - + if (register_ss_entry(sockets, &pcic_operations) != 0) printk(KERN_NOTICE "i82365: register_ss_entry() failed\n"); @@ -1635,9 +1555,9 @@ poll_timer.expires = jiffies + poll_interval; add_timer(&poll_timer); } - + return 0; - + } /* init_i82365 */ static void __exit exit_i82365(void) @@ -1649,16 +1569,14 @@ unregister_ss_entry(&pcic_operations); if (poll_interval != 0) del_timer(&poll_timer); -#ifdef CONFIG_ISA if (grab_irq != 0) free_irq(cs_irq, pcic_interrupt); -#endif for (i = 0; i < sockets; i++) { /* Turn off all interrupt sources! */ i365_set(i, I365_CSCINT, 0); release_region(socket[i].ioaddr, 2); } -#if defined(CONFIG_ISA) && defined(I82365_ISAPNP) +#if defined(I82365_ISAPNP) if (i82365_pnpdev && i82365_pnpdev->deactivate) i82365_pnpdev->deactivate(i82365_pnpdev); #endif Index: drivers/pcmcia/rsrc_mgr.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pcmcia/rsrc_mgr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pcmcia/rsrc_mgr.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/pcmcia/rsrc_mgr.c 4 Aug 2004 01:29:27 -0000 1.2 @@ -28,7 +28,7 @@ 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. - + ======================================================================*/ #define __NO_VERSION__ @@ -200,7 +200,7 @@ /*====================================================================== These manage the internal databases of available resources. - + ======================================================================*/ static int add_interval(resource_map_t *map, u_long base, u_long num) @@ -264,25 +264,25 @@ These routines examine a region of IO or memory addresses to determine what ranges might be genuinely available. - + ======================================================================*/ #ifdef CONFIG_PCMCIA_PROBE static void do_io_probe(ioaddr_t base, ioaddr_t num) { - + ioaddr_t i, j, bad, any; u_char *b, hole, most; - + printk(KERN_INFO "cs: IO port probe 0x%04x-0x%04x:", base, base+num-1); - + /* First, what does a floating port look like? */ b = kmalloc(256, GFP_KERNEL); if (!b) { printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes"); return; - } + } memset(b, 0, 256); for (i = base, most = 0; i < base+num; i += 8) { if (check_io_resource(i, 8, NULL)) @@ -324,7 +324,7 @@ printk(" %#04x-%#04x", bad, i-1); } } - + printk(any ? "\n" : " clean.\n"); } #endif @@ -334,7 +334,7 @@ The memory probe. If the memory list includes a 64K-aligned block below 1MB, we probe in 64K chunks, and as soon as we accumulate at least mem_limit free space, we quit. - + ======================================================================*/ static int do_mem_probe(u_long base, u_long num, @@ -348,7 +348,7 @@ bad = fail = 0; step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff); for (i = j = base; i < base+num; i = j + step) { - if (!fail) { + if (!fail) { for (j = i; j < base+num; j += step) if ((check_mem_resource(j, step, s->cap.cb_dev) == 0) && is_valid(j)) @@ -395,11 +395,11 @@ void validate_mem(int (*is_valid)(u_long), int (*do_cksum)(u_long), int force_low, socket_info_t *s) { - resource_map_t *m, *n; + resource_map_t *m, mm; static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 }; static int hi = 0, lo = 0; u_long b, i, ok = 0; - + if (!probe_mem) return; /* We do up to four passes through the list */ if (!force_low) { @@ -409,18 +409,18 @@ "available!\n"); } if (lo++) return; - for (m = mem_db.next; m != &mem_db; m = n) { - n = m->next; + for (m = mem_db.next; m != &mem_db; m = mm.next) { + mm = *m; /* Only probe < 1 MB */ - if (m->base >= 0x100000) continue; - if ((m->base | m->num) & 0xffff) { - ok += do_mem_probe(m->base, m->num, is_valid, do_cksum, s); + if (mm.base >= 0x100000) continue; + if ((mm.base | mm.num) & 0xffff) { + ok += do_mem_probe(mm.base, mm.num, is_valid, do_cksum, s); continue; } /* Special probe for 64K-aligned block */ for (i = 0; i < 4; i++) { b = order[i] << 12; - if ((b >= m->base) && (b+0x10000 <= m->base+m->num)) { + if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) { if (ok >= mem_limit) sub_interval(&mem_db, b, 0x10000); else @@ -435,14 +435,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_PCMCIA_PROBE */ @@ -457,7 +460,7 @@ should be a power of two, greater than or equal to 'num'. A value of 0 means that all bits of *base are significant. *base should also be strictly less than 'align'. - + ======================================================================*/ int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align, @@ -465,7 +468,7 @@ { ioaddr_t try; resource_map_t *m; - + for (m = io_db.next; m != &io_db; m = m->next) { try = (m->base & ~(align-1)) + *base; for (try = (try >= m->base) ? try : try+align; @@ -513,7 +516,7 @@ This checks to see if an interrupt is available, with support for interrupt sharing. We don't support reserving interrupts yet. If the interrupt is available, we allocate it. - + ======================================================================*/ #ifdef CONFIG_PCMCIA_PROBE @@ -613,7 +616,7 @@ The various adjust_* calls form the external interface to the resource database. - + ======================================================================*/ static int adjust_memory(adjust_t *adj) @@ -645,7 +648,7 @@ default: ret = CS_UNSUPPORTED_FUNCTION; } - + return ret; } @@ -654,7 +657,7 @@ static int adjust_io(adjust_t *adj) { int base, num; - + base = adj->resource.io.BasePort; num = adj->resource.io.NumPorts; if ((base < 0) || (base > 0xffff)) @@ -689,12 +692,12 @@ #ifdef CONFIG_PCMCIA_PROBE int irq; irq_info_t *info; - + irq = adj->resource.irq.IRQ; if ((irq < 0) || (irq > 15)) return CS_BAD_IRQ; info = &irq_table[irq]; - + switch (adj->Action) { case ADD_MANAGED_RESOURCE: if (info->Attributes & RES_REMOVED) @@ -729,7 +732,7 @@ { if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; - + switch (adj->Resource) { case RES_MEMORY_RANGE: return adjust_memory(adj); @@ -749,7 +752,7 @@ void release_resource_db(void) { resource_map_t *p, *q; - + for (p = mem_db.next; p != &mem_db; p = q) { q = p->next; kfree(p); Index: drivers/pcmcia/sa1100_stork.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pcmcia/sa1100_stork.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pcmcia/sa1100_stork.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/pcmcia/sa1100_stork.c 4 Aug 2004 01:29:27 -0000 1.2 @@ -24,7 +24,6 @@ #include #include #include -#include #include #include Index: drivers/pcmcia/ti113x.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pcmcia/ti113x.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pcmcia/ti113x.h 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/pcmcia/ti113x.h 4 Aug 2004 01:29:27 -0000 1.2 @@ -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; } Index: drivers/pcmcia/yenta.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pcmcia/yenta.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pcmcia/yenta.c 22 Jul 2004 19:50:25 -0000 1.1 +++ drivers/pcmcia/yenta.c 4 Aug 2004 01:29:27 -0000 1.2 @@ -26,7 +26,7 @@ #include "i82365.h" #if 0 -#define DEBUG(x,args...) printk(__FUNCTION__ ": " x,##args) +#define DEBUG(x,args...) printk(KERN_DEBUG __FUNCTION__ ": " x,##args) #else #define DEBUG(x,args...) #endif @@ -576,7 +576,8 @@ socket->cap.cb_dev = socket->dev; socket->cap.bus = NULL; - printk("Yenta IRQ list %04x, PCI irq%d\n", socket->cap.irq_mask, socket->cb_irq); + printk(KERN_INFO "Yenta ISA IRQ mask 0x%04x, PCI irq %d\n", + socket->cap.irq_mask, socket->cb_irq); } extern void cardbus_register(pci_socket_t *socket); @@ -603,7 +604,8 @@ /* Figure out what the dang thing can do for the PCMCIA layer... */ yenta_get_socket_capabilities(socket, isa_interrupts); - printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE)); + printk(KERN_INFO "Socket status: %08x\n", + cb_readl(socket, CB_SOCKET_STATE)); /* Register it with the pcmcia layer.. */ cardbus_register(socket); @@ -634,6 +636,7 @@ */ static void yenta_config_init(pci_socket_t *socket) { + u32 state; u16 bridge; struct pci_dev *dev = socket->dev; @@ -673,6 +676,10 @@ exca_writeb(socket, I365_GENCTL, 0x00); /* Redo card voltage interrogation */ + state = cb_readl(socket, CB_SOCKET_STATE); + if (!(state & (CB_CDETECT1 | CB_CDETECT2 | CB_5VCARD | + CB_3VCARD | CB_XVCARD | CB_YVCARD))) + cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST); } @@ -863,6 +870,13 @@ { PD(TI,1420), &ti_ops }, { PD(TI,4410), &ti_ops }, { PD(TI,4451), &ti_ops }, + { PD(TI,1510), &ti_ops }, + { PD(TI,1520), &ti_ops }, + + { PD(ENE,1211), &ti_ops }, + { PD(ENE,1225), &ti_ops }, + { PD(ENE,1410), &ti_ops }, + { PD(ENE,1420), &ti_ops }, { PD(RICOH,RL5C465), &ricoh_ops }, { PD(RICOH,RL5C466), &ricoh_ops }, @@ -889,7 +903,7 @@ if (pci_enable_device(dev)) return -1; if (!pci_resource_start(dev, 0)) { - printk("No cardbus resource!\n"); + printk(KERN_ERR "No cardbus resource!\n"); return -1; } Index: drivers/pld/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pld/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pld/Makefile 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/pld/Makefile 4 Aug 2004 01:29:27 -0000 1.2 @@ -8,7 +8,7 @@ # Note 2! The CFLAGS definitions are now inherited from the # parent makes.. # -# $Id: Makefile,v 1.1 2004/07/22 19:49:46 joff Exp $ +# $Id: Makefile,v 1.2 2004/08/04 01:29:27 joff Exp $ # O_TARGET := pld.o Index: drivers/pld/pld_hotswap.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pld/pld_hotswap.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pld/pld_hotswap.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/pld/pld_hotswap.c 4 Aug 2004 01:29:27 -0000 1.2 @@ -20,7 +20,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: pld_hotswap.c,v 1.1 2004/07/22 19:49:46 joff Exp $ + * $Id: pld_hotswap.c,v 1.2 2004/08/04 01:29:27 joff Exp $ * */ Index: drivers/pnp/isapnp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/pnp/isapnp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/pnp/isapnp.c 22 Jul 2004 19:49:46 -0000 1.1 +++ drivers/pnp/isapnp.c 4 Aug 2004 01:29:27 -0000 1.2 @@ -510,7 +510,6 @@ int dependent, int size) { unsigned char tmp[3]; - int i; struct isapnp_irq *irq, *ptr; isapnp_peek(tmp, size); @@ -538,9 +537,13 @@ else (*res)->irq = irq; #ifdef CONFIG_PCI - for (i=0; i<16; i++) - if (irq->map & (1<map & (1< #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,92 +766,7 @@ 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; - -} - - +void s390_free_irq (unsigned int irq, void *dev_id); /* * Note : internal use of irqflags SA_PROBE for NOT path grouping @@ -930,7 +796,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); /* @@ -938,7 +804,11 @@ */ s390irq_spin_lock_irqsave (irq, flags); - if (!ioinfo[irq]->ui.flags.ready) { + if (ioinfo[irq]->ui.flags.unfriendly && + !(irqflags & SA_FORCE)) { + retval = -EUSERS; + + } else if (!ioinfo[irq]->ui.flags.ready) { retry = 5; ioinfo[irq]->irq_desc.handler = io_handler; @@ -972,12 +842,55 @@ s390irq_spin_unlock_irqrestore (irq, flags); if (retval == 0) { + if (irqflags & SA_DOPATHGROUP) { + ioinfo[irq]->ui.flags.pgid_supp = 1; + ioinfo[irq]->ui.flags.notacccap = 1; + } + if ((irqflags & SA_DOPATHGROUP) && + (!ioinfo[irq]->ui.flags.pgid || + irqflags & SA_PROBE)) { + pgid_t pgid; + int i, mask; + /* + * Do an initial SensePGID to find out if device + * is locked by someone else. + */ + memcpy(&pgid, global_pgid, sizeof(pgid_t)); + + retval = -EAGAIN; + for (i=0; i<8 && retval==-EAGAIN; i++) { + + mask = (0x80 >> i) & ioinfo[irq]->opm; + + if (!mask) + continue; + + retval = s390_SensePGID(irq, mask, &pgid); + + if (retval == -EOPNOTSUPP) + /* Doesn't prevent us from proceeding */ + retval = 0; + } + + } if (!(irqflags & SA_PROBE) && + (irqflags & SA_DOPATHGROUP) && (!ioinfo[irq]->ui.flags.unfriendly)) s390_DevicePathVerification (irq, 0); - ioinfo[irq]->ui.flags.newreq = 1; - ioinfo[irq]->nopfunc = not_oper_handler; + if (ioinfo[irq]->ui.flags.unfriendly && + !(irqflags & SA_FORCE)) { + /* + * We found out during path verification that the + * device is locked by someone else and we have to + * let the device driver know. + */ + retval = -EUSERS; + free_irq(irq, dev_id); + } else { + ioinfo[irq]->ui.flags.newreq = 1; + ioinfo[irq]->nopfunc = not_oper_handler; + } } if (cio_debug_initialized) @@ -1054,6 +967,7 @@ s390irq_spin_unlock_irqrestore (irq, flags); udelay (200000); /* 200 ms */ s390irq_spin_lock_irqsave (irq, flags); + ret = disable_subchannel (irq); if (ret == -EBUSY) { @@ -1116,61 +1030,6 @@ } /* - * Generic enable/disable code - */ -int -disable_irq (unsigned int irq) -{ - unsigned long flags; - int ret; - char dbf_txt[15]; - - SANITY_CHECK (irq); - - if (!ioinfo[irq]->ui.flags.ready) - return -ENODEV; - - sprintf (dbf_txt, "dirq%x", irq); - CIO_TRACE_EVENT (4, dbf_txt); - - s390irq_spin_lock_irqsave (irq, flags); - ret = disable_subchannel (irq); - s390irq_spin_unlock_irqrestore (irq, flags); - - synchronize_irq (); - - sprintf (dbf_txt, "ret:%d", ret); - CIO_TRACE_EVENT (4, dbf_txt); - - return (ret); -} - -int -enable_irq (unsigned int irq) -{ - unsigned long flags; - int ret; - char dbf_txt[15]; - - SANITY_CHECK (irq); - - if (!ioinfo[irq]->ui.flags.ready) - return -ENODEV; - - sprintf (dbf_txt, "eirq%x", irq); - CIO_TRACE_EVENT (4, dbf_txt); - - s390irq_spin_lock_irqsave (irq, flags); - ret = enable_subchannel (irq); - s390irq_spin_unlock_irqrestore (irq, flags); - - sprintf (dbf_txt, "ret:%d", ret); - CIO_TRACE_EVENT (4, dbf_txt); - - return (ret); -} - -/* * Enable IRQ by modifying the subchannel */ static int @@ -1183,7 +1042,7 @@ SANITY_CHECK (irq); - sprintf (dbf_txt, "esch%x", irq); + sprintf (dbf_txt, "ensch%x", irq); CIO_TRACE_EVENT (2, dbf_txt); /* @@ -1268,7 +1127,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 +1226,7 @@ { unsigned long flags; /* PSW flags */ long cr6 __attribute__ ((aligned (8))); + cpuid_t cpuid; asm volatile ("STCK %0":"=m" (irq_IPL_TOD)); @@ -1406,8 +1266,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 +1315,6 @@ { /* flags */ int ccode; int ret = 0; - char buffer[80]; char dbf_txt[15]; SANITY_CHECK (irq); @@ -1512,7 +1381,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); @@ -1560,8 +1436,6 @@ } - ioinfo[irq]->ulpm = ioinfo[irq]->orb.lpm; - /* * If synchronous I/O processing is requested, we have * to wait for the corresponding interrupt to occur by @@ -1674,6 +1548,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 +1599,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 +1612,7 @@ #ifdef CONFIG_DEBUG_IO { + char buffer[80]; stsch (irq, &(ioinfo[irq]->schib)); @@ -1777,39 +1654,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 +1721,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,41 +1765,15 @@ 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 ... */ if (!ioinfo[irq]->ui.flags.busy) { /* last I/O completed ? */ ret = s390_start_IO (irq, cpa, user_intparm, lpm, flag); - if ((ret == -ETIMEDOUT) && (flag & DOIO_CANCEL_ON_TIMEOUT)) { - /* - * We should better cancel the io request here - * or we might not be able to do io on this sch - * again - */ - cancel_IO (irq); - } - - } else if (ioinfo[irq]->ui.flags.fast) { - /* - * If primary status was received and ending status is missing, - * the device driver won't be notified on the ending status - * if early (fast) interrupt notification was requested. - * Therefore we have to queue the next incoming request. If - * halt_IO() is issued while there is a request queued, a HSCH - * needs to be issued and the queued request must be deleted - * but its intparm must be returned (see halt_IO() processing) - */ - if (ioinfo[irq]->ui.flags.w4final - && !ioinfo[irq]->ui.flags.doio_q) { - ioinfo[irq]->qflag = flag; - ioinfo[irq]->qcpa = cpa; - ioinfo[irq]->qintparm = user_intparm; - ioinfo[irq]->qlpm = lpm; - } else { - ret = -EBUSY; - - } } else { ret = -EBUSY; @@ -1963,7 +1794,7 @@ SANITY_CHECK (irq); - sprintf (dbf_txt, "rsIO%x", irq); + sprintf (dbf_txt, "resIO%x", irq); CIO_TRACE_EVENT (4, dbf_txt); /* @@ -1982,7 +1813,6 @@ break; case 1: - s390_process_IRQ (irq); ret = -EBUSY; break; @@ -2025,6 +1855,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 +1871,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 +1990,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 +2090,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 +2104,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 +2261,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 +2277,6 @@ case 1: /* status pending */ - /* process the pending irq... */ - s390_process_IRQ (irq); ret = -EBUSY; break; @@ -2595,7 +2435,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 +2559,7 @@ } dp->cpa = dp->ii.irb.scsw.cpa; - + } irb_cc = dp->ii.irb.scsw.cc; @@ -2806,18 +2646,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 +2671,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 +2695,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 +2724,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 +2756,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 +2790,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 +2890,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 +2958,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 @@ -3098,49 +2967,8 @@ */ dp->intparm = 0; - /* - * Was there anything queued ? Start the pending channel program - * if there is one. - */ - if (ioinfo[irq]->ui.flags.doio_q) { - int ret; - int do_cancel = - ioinfo[irq]-> - qflag & DOIO_CANCEL_ON_TIMEOUT; - - ret = s390_start_IO (irq, - ioinfo[irq]->qcpa, - ioinfo[irq]-> - qintparm, - ioinfo[irq]->qlpm, - ioinfo[irq]-> - qflag); - - ioinfo[irq]->ui.flags.doio_q = 0; - - /* - * If s390_start_IO() failed call the device's interrupt - * handler, the IRQ related devstat area was setup by - * s390_start_IO() accordingly already (status pending - * condition). - */ - if (ret) { - ioinfo[irq]->irq_desc. - handler (irq, udp, NULL); - - } - - /* - * better cancel the io when we time out... - */ - if ((ret == -ETIMEDOUT) && do_cancel) { - cancel_IO (irq); - } - - } - - } else { - ioinfo[irq]->ui.flags.w4final = 1; + } else { + ioinfo[irq]->ui.flags.w4final = 1; /* * Eventually reset subchannel PCI status and @@ -3156,7 +2984,7 @@ udp->flag |= DEVSTAT_SUSPENDED; } - + ioinfo[irq]->irq_desc.handler (irq, udp, NULL); } @@ -3174,16 +3002,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; @@ -3193,32 +3020,19 @@ ioinfo[irq]->devstat.flag |= DEVSTAT_NOT_OPER; ioinfo[irq]->devstat.flag |= DEVSTAT_FINAL_STATUS; - /* - * When we find a device "not oper" we save the status - * information into the device status area and call the - * device specific interrupt handler. - * - * Note: currently we don't have any way to reenable - * the device unless an unsolicited interrupt - * is presented. We don't check for spurious - * interrupts on "not oper" conditions. - */ - - if ((ioinfo[irq]->ui.flags.fast) - && (ioinfo[irq]->ui.flags.w4final)) { - /* - * If a new request was queued already, we have - * to simulate the "not oper" status for the - * queued request by switching the "intparm" value - * and notify the interrupt handler. - */ - if (ioinfo[irq]->ui.flags.doio_q) { - ioinfo[irq]->devstat.intparm = - ioinfo[irq]->qintparm; - } - } + /* + * When we find a device "not oper" we save the status + * information into the device status area and call the + * device specific interrupt handler. + * + * Note: currently we don't have any way to reenable + * the device unless an unsolicited interrupt + * is presented. We don't check for spurious + * interrupts on "not oper" conditions. + */ + ioinfo[irq]->ui.flags.fast = 0; ioinfo[irq]->ui.flags.repall = 0; ioinfo[irq]->ui.flags.w4final = 0; @@ -3234,9 +3048,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 +3060,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); } @@ -3257,9 +3084,8 @@ * without having to delay I/O processing (by queueing) * for non-console devices. * - * Setting of this isc is done by set_cons_dev(), while - * reset_cons_dev() resets this isc and re-enables the - * default isc3 for this device. wait_cons_dev() allows + * Setting of this isc is done by set_cons_dev(). + * wait_cons_dev() allows * to actively wait on an interrupt for this device in * disabed state. When the interrupt condition is * encountered, wait_cons_dev(9 calls do_IRQ() to have @@ -3277,7 +3103,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); /* @@ -3311,52 +3137,6 @@ } int -reset_cons_dev (int irq) -{ - int rc = 0; - int ccode; - char dbf_txt[15]; - - SANITY_CHECK (irq); - - if (cons_dev != -1) - return -EBUSY; - - sprintf (dbf_txt, "rscd%x", irq); - CIO_TRACE_EVENT (4, dbf_txt); - - /* - * reset the indicated console device to operate - * on default console interrupt sublass 3 - */ - ccode = stsch (irq, &(ioinfo[irq]->schib)); - - if (ccode) { - rc = -ENODEV; - ioinfo[irq]->devstat.flag |= DEVSTAT_NOT_OPER; - } else { - - ioinfo[irq]->schib.pmcw.isc = 3; - - ccode = msch (irq, &(ioinfo[irq]->schib)); - - if (ccode) { - rc = -EIO; - } else { - cons_dev = -1; - - /* - * disable special console I/O-interrupt sublass 7 - */ - ctl_clear_bit(6, 24); - - } - } - - return (rc); -} - -int wait_cons_dev (int irq) { int rc = 0; @@ -3366,7 +3146,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 +3197,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 +3218,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)); @@ -3459,10 +3238,9 @@ cr6 |= 0x04000000; /* disable standard isc 3 */ cr6 &= 0xEFFFFFFF; - /* disable console isc 7, - * if neccessary */ - if (cons_dev != -1) - cr6 &= 0xFEFFFFFF; + /* disable console isc 7 */ + cr6 &= 0xFEFFFFFF; + ioinfo[irq]->ui.flags.syncio = 1; __ctl_load (cr6, 6, 6); rc = 0; retry = 0; @@ -3505,6 +3283,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 +3318,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) && @@ -3573,10 +3360,8 @@ cr6 &= 0xFBFFFFFF; /* enable standard isc 3 */ cr6 |= 0x10000000; - /* enable console isc 7, - * if neccessary */ - if (cons_dev != -1) - cr6 |= 0x01000000; + /* enable console isc 7 */ + cr6 |= 0x01000000; __ctl_load (cr6, 6, 6); retry2 = 0; @@ -3621,7 +3406,7 @@ sync_isc_cnt = 0; atomic_set (&sync_isc, -1); - + } else { sync_isc_cnt--; @@ -3641,6 +3426,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 +3463,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 +3787,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 +3816,7 @@ return -EUSERS; } - sprintf (dbf_txt, "rdc%x", irq); + sprintf (dbf_txt, "rddevch%x", irq); CIO_TRACE_EVENT (4, dbf_txt); /* @@ -4052,8 +3859,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 +3945,7 @@ return -EUSERS; } - sprintf (dbf_txt, "rcd%x", irq); + sprintf (dbf_txt, "rdconf%x", irq); CIO_TRACE_EVENT (4, dbf_txt); /* @@ -4194,7 +4000,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 +4359,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); /* @@ -4567,57 +4373,50 @@ int irq_ret; devstat_t devstat; - irq_ret = request_irq (irq, - init_IRQ_handler, - SA_PROBE, "INIT", &devstat); + if (ioinfo[irq]->ui.flags.pgid_supp) + irq_ret = request_irq (irq, + init_IRQ_handler, + SA_PROBE | SA_DOPATHGROUP, + "INIT", &devstat); + else + irq_ret = request_irq (irq, + init_IRQ_handler, + SA_PROBE, "INIT", &devstat); if (!irq_ret) { ret = enable_cpu_sync_isc (irq); if (!ret) { - pgid_t pgid; - /* - * First thing we should do is a sensePGID in - * order to find out how we can proceed with - * the recognition process. - * An unfriendly (locked by so else) device - * won't take kindly to our attempts at - * SetPGID and SenseID... - */ - - memcpy(&pgid, global_pgid, sizeof(pgid_t)); - ret = s390_SensePGID(irq, 0xff, &pgid); - - if (ret == -EOPNOTSUPP) - /* - * Doesn't prevent us from proceeding - */ - ret = 0; - - if (!ret && !ioinfo[irq]->ui.flags.unfriendly) { - - ioinfo[irq]->ui.flags.unknown = 0; + ioinfo[irq]->ui.flags.unknown = 0; + + memset (&ioinfo[irq]->senseid, '\0', + sizeof (senseid_t)); + + if (cio_sid_with_pgid) { - memset (&ioinfo[irq]->senseid, '\0', - sizeof (senseid_t)); + ret = s390_DevicePathVerification(irq,0); - if (cio_sid_with_pgid) { - - ret = s390_DevicePathVerification(irq,0); - - if (ret == -EOPNOTSUPP) - /* - * Doesn't prevent us from proceeding - */ - ret = 0; + if (ret == -EOPNOTSUPP) + /* + * Doesn't prevent us from proceeding + */ + ret = 0; + } + + /* + * we'll fallthrough here if we don't want + * to do SPID before SID + */ + if (!ret) { + ret = s390_SenseID (irq, &ioinfo[irq]->senseid, 0xff); + if (ret == -ETIMEDOUT) { + /* SenseID timed out. + * We consider this device to be + * boxed for now. + */ + ioinfo[irq]->ui.flags.unfriendly = 1; } - /* - * we'll fallthrough here if we don't want - * to do SPID before SID - */ - if (!ret) { - s390_SenseID (irq, &ioinfo[irq]->senseid, 0xff); #if 0 /* FIXME */ /* * We initially check the configuration data for @@ -4645,18 +4444,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 { @@ -4669,7 +4459,6 @@ } } #endif - } } disable_cpu_sync_isc (irq); @@ -4677,7 +4466,7 @@ free_irq (irq, &devstat); - } + } } } @@ -4756,20 +4545,22 @@ 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); return -EBUSY; } + /* + * This function is called by dasd if it just executed a "steal lock". + * Therefore, re-initialize the 'unfriendly' flag to 0. + * We run into timeouts if the device is still boxed... + */ + ioinfo[irq]->ui.flags.unfriendly = 0; + s390_device_recognition_irq(irq); return 0; @@ -4826,7 +4617,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 +4692,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)); @@ -4948,8 +4742,6 @@ if (ioinfo[irq]->st) return -ENODEV; - ioinfo[irq]->ui.flags.pgid_supp = 1; - ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim & ioinfo[irq]->schib.pmcw.pam & ioinfo[irq]->schib.pmcw.pom; @@ -4964,6 +4756,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 +5005,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 +5040,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) { @@ -5619,7 +5420,7 @@ if (!ioinfo[irq]->ui.flags.unknown) irq_ret = 0; - else + else if (irq_ret != -ETIMEDOUT) irq_ret = -ENODEV; return (irq_ret); @@ -5642,6 +5443,191 @@ return (cc); } +static int +s390_do_path_verification(int irq, __u8 usermask) +{ + __u8 domask; + int i; + pgid_t pgid; + __u8 dev_path; + int first = 1; + int ret = 0; + char dbf_txt[15]; + + sprintf(dbf_txt, "dopv%x", irq); + CIO_TRACE_EVENT(2, dbf_txt); + + dev_path = usermask ? usermask : 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 * @@ -5656,8 +5642,6 @@ s390_DevicePathVerification (int irq, __u8 usermask) { int ccode; - __u8 pathmask; - __u8 domask; #ifdef CONFIG_CHSC int chp; int mask; @@ -5665,14 +5649,11 @@ #endif /* CONFIG_CHSC */ int ret = 0; - int i; - pgid_t pgid; - __u8 dev_path; - int first = 1; char dbf_txt[15]; + devreg_t *pdevreg; - sprintf (dbf_txt, "dpvf%x", irq); + sprintf (dbf_txt, "dpver%x", irq); CIO_TRACE_EVENT (4, dbf_txt); if (ioinfo[irq]->st) @@ -5683,15 +5664,16 @@ #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 +5681,50 @@ */ 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) { + + if (ioinfo[irq]->nopfunc) { + if (ioinfo[irq]->ui.flags.notacccap) + ioinfo[irq]->nopfunc(irq, + DEVSTAT_NOT_ACC); + else { + 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); + /* remove procfs entry */ + if (cio_proc_devinfo) + cio_procfs_device_remove + (ioinfo[irq]->devno); +#endif + free_irq(irq, + ioinfo[irq]->irq_desc.dev_id); + nopfunc(irq, DEVSTAT_DEVICE_GONE); + } } - ret = -ENODEV; - } else if (!old_opm) { + return -ENODEV; + } + if (!old_opm) { - /* - * check for 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 +5737,74 @@ 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 + if (ioinfo[irq]->ui.flags.ready) + return s390_do_path_verification (irq, usermask); + return 0; - 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 +5867,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 +5910,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 +5973,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 +6000,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 +6032,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 +6072,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 +6200,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 +6252,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 +6320,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 +6339,8 @@ } retry = 0; - irq_ret = -EIO; + ioinfo[irq]->opm &= ~lpm; + irq_ret = -EAGAIN; } else { retry = 0; /* success ... */ @@ -6432,7 +6350,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 +6425,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 +6596,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 +6938,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 +7061,87 @@ * 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 the driver is not capable of handling + * DEVSTAT_NOT_ACC, it doesn't want path grouping anyway. + */ + if (ioinfo[irq]->ui.flags.ready && + schib->pmcw.pim != 0x80 && + ioinfo[irq]->nopfunc && + ioinfo[irq]->ui.flags.notacccap) { + 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 +7153,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 +7192,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 +7209,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)) { - - /* - * Send nops down each path to find out - * which path is there - */ + && (ioinfo[irq]->st != 0)) + 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)) - 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 +7235,42 @@ 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]->ui.flags.notacccap) + 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 +7290,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 +7299,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,21 +7312,85 @@ 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]->ui.flags.notacccap) + 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(); } } +static int +__get_chpid_from_lir(void *data) +{ + struct lir { + u8 iq; + u8 ic; + u16 sci; + /* incident-node descriptor */ + u32 indesc[28]; + /* attached-node descriptor */ + u32 andesc[28]; + /* incident-specific information */ + u32 isinfo[28]; + } *lir; + + lir = (struct lir*) data; + if (!(lir->iq&0x80)) + /* NULL link incident record */ + return -EINVAL; + if (!(lir->indesc[0]&0xc0000000)) + /* node descriptor not valid */ + return -EINVAL; + if (!(lir->indesc[0]&0x10000000)) + /* don't handle device-type nodes - FIXME */ + return -EINVAL; + /* Byte 3 contains the chpid. Could also be CTCA, but we don't care */ + + return (u16) (lir->indesc[0]&0x000000ff); +} + void s390_process_css( void ) { - int ccode; + int ccode, do_sei, chpid; CIO_TRACE_EVENT( 2, "prcss"); @@ -7414,18 +7410,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 +7439,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 +7449,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 +7459,354 @@ 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); + + chpid = __get_chpid_from_lir(chsc_area_sei->response_block. + response_block_data.sei_res. + ccdf); + if (chpid >= 0) + s390_do_chpid_processing(chpid); + break; - /* which kind of information was stored? */ - switch (chsc_area_sei->response_block. - response_block_data.sei_res.cc) { - case 1: /* link incident*/ + 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 && + ioinfo[irq]->ui.flags.notacccap) { + 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]->ui.flags.notacccap) + 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 +7860,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 +8070,83 @@ } } +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]->ui.flags.notacccap) + 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]->ui.flags.notacccap) + 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; + + s390_schedule_path_verification(irq); + + break; + } +} + /* * Function: s390_vary_chpid @@ -7899,34 +8196,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 +8896,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 +8907,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 +9075,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; } } @@ -8867,7 +9156,6 @@ #ifdef CIO_DEBUG_IO printk("/proc/chpids: '%s'\n", buffer); #endif /* CIO_DEBUG_IO */ - CIO_MSG_EVENT( 2, "/proc/chpids: '%s'\n", buffer); cio_parse_chpids_proc_parameters(buffer); @@ -8940,6 +9228,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); Index: drivers/s390/s390mach.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/s390mach.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/s390mach.c 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/s390/s390mach.c 4 Aug 2004 01:29:28 -0000 1.2 @@ -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 - Index: drivers/s390/block/dasd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/block/dasd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/block/dasd.c 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/s390/block/dasd.c 4 Aug 2004 01:29:28 -0000 1.2 @@ -6,6 +6,8 @@ * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 * + * $Revision: 1.2 $ + * * 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,8 @@ * 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) + * 08/07/03 fixed LTC BZ 3847 Erroneous message when formatting DASD */ #include @@ -70,7 +74,6 @@ #include #include #include -#include #include "dasd_int.h" @@ -84,8 +87,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 +98,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 +110,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 +123,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 +162,13 @@ 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); +static int dasd_devno_from_devindex (int devindex); +static int dasd_devindex_from_devno (int devno); + +/******************************************************************************** + * SECTION: static variables of dasd.c + ********************************************************************************/ static devfs_handle_t dasd_devfs_handle; static wait_queue_head_t dasd_init_waitq; @@ -155,7 +176,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 +211,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 @@ -207,25 +232,7 @@ dasd_create_range (int from, int to, int features) { dasd_range_t *range = NULL; - int i; - if ( from > to ) { - printk (KERN_WARNING PRINTK_HEADER - "Adding device range %04x-%04x: range invalid, ignoring.\n", - 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); - } - } range = (dasd_range_t *) kmalloc (sizeof (dasd_range_t), GFP_KERNEL); if (range == NULL) return NULL; @@ -281,31 +288,70 @@ /* * function: dasd_add_range * creates a dasd_range_t according to the arguments and - * appends it to the list of ranges + * appends it to the list of ranges. + * If a device in the range is already in an other range, we split the + * range and add the subranges (no duplicate devices). * additionally a devreg_t is created and added to the list of devregs */ -static inline dasd_range_t * +static inline void dasd_add_range (int from, int to, int features) { dasd_range_t *range; + int start, end, index, i; - range = dasd_create_range (from, to, features); - if (!range) - return NULL; + if (from > to) { + MESSAGE (KERN_DEBUG, + "Adding device range %04x-%04x: " + "range invalid, ignoring.", + from, to); + return; + } - dasd_append_range (range); + /* loop over the given range, remove the already contained devices */ + /* and add the remaining subranges */ + for (start = index = from, end = -EINVAL; index <= to; index++) { + + if (dasd_devindex_from_devno(index) > 0) { + /* current device is already in range */ + MESSAGE (KERN_DEBUG, + "dasd_add_range %04x-%04x: " + "device %04x is already in range", + from, to, index); + + if (start == index) + start++; /* first already in range */ + else + end = index -1; /* current already in range */ + } else { + if (index == to) + end = to; /* end of original range reached */ + } + + range = NULL; + if (end != -EINVAL) { + MESSAGE (KERN_DEBUG, + "dasd_add_range %04x-%04x: " + "add (sub)range %04x-%04x", + from, to, start, end); + + range = dasd_create_range (start, end, features); + end = -EINVAL; + start = index + 1; + } + + if (range) { + dasd_append_range (range); #ifdef CONFIG_DASD_DYNAMIC - /* allocate and chain devreg infos for the devnos... */ - { - int i; - for (i = range->from; i <= range->to; i++) { - dasd_devreg_t *reg = dasd_create_devreg (i); - s390_device_register (®->devreg); - list_add (®->list, &dasd_devreg_head); - } - } + /* allocate and chain devreg infos for the devnos... */ + for (i = range->from; i <= range->to; i++) { + dasd_devreg_t *reg = dasd_create_devreg (i); + s390_device_register (®->devreg); + list_add (®->list, &dasd_devreg_head); + } #endif /* CONFIG_DASD_DYNAMIC */ - return range; + } + } + return; } /* @@ -392,7 +438,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 +474,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 +551,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_LOG (KERN_WARNING, + "can't parse dasd= parameter %s due " + "to low memory", + str); } /* remove leading '0x' */ @@ -528,7 +582,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 +599,18 @@ (*features) |= DASD_FEATURE_READONLY; break; } - printk (KERN_WARNING PRINTK_HEADER - "unsupported feature: %s, ignoring setting", - buffer); + + MESSAGE_LOG (KERN_WARNING, + "unsupported feature: %s, " + "ignoring setting", + buffer); } } } *stra = temp+i; + if ((val > 0xFFFF) || (val < 0)) + return -EINVAL; return val; } @@ -569,22 +627,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 +668,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 +713,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 +744,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 +758,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 +851,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 +905,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 +937,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 +966,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 +1019,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 +1053,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 +1072,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 +1163,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 +1217,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 +1352,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 +1514,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 +1549,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 +1578,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 +1586,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 +1687,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 +1759,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->stopped) + 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 +1797,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 +1823,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 +1838,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,14 +1960,19 @@ 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); - cqr->expires <<= 1; - rc = -EIO; + 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; } return rc; } @@ -1569,22 +1987,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 +2038,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 +2058,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 +2075,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,65 +2109,60 @@ } /* 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 */ - } + + 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) { @@ -1759,11 +2178,11 @@ /* to be filled with MIH */ } break; - - case CQR_STATUS_PENDING: - /* just wait */ - break; default: + MESSAGE (KERN_EMERG, + "invalid cqr (%p) detected with status %02x ", + qp->head, + qp->head->status); BUG (); } } @@ -1786,6 +2205,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 */ @@ -1820,53 +2251,43 @@ } /* - * DASD_HANDLE_STATE_CHANGE_PENDING + * function dasd_handle_state_change_pending * - * DESCRIPTION - * Handles the state change pending interrupt. - * Search for the device related request queue and check if the first - * cqr in queue in in status 'CQR_STATUE_PENDING'. - * If so the status is set to 'CQR_STATUS_QUEUED' to reactivate - * the device. - * - * PARAMETER - * stat device status of state change pending interrupt. + * handles the state change pending interrupt. */ void dasd_handle_state_change_pending (devstat_t * stat) { - dasd_device_t **device_addr; + + dasd_device_t **device_addr, *device; ccw_req_t *cqr; device_addr = dasd_device_from_devno (stat->devno); - if (device_addr == NULL) { - - printk (KERN_DEBUG PRINTK_HEADER - "unable to find device for state change pending " - "interrupt: devno%04x\n", - stat->devno); + if (!device_addr) return; - } - /* re-activate first request in queue */ - cqr = (*device_addr)->queue.head; + device = *device_addr; + if (!device) + return; - if (cqr->status == CQR_STATUS_PENDING) { - - DASD_MESSAGE (KERN_DEBUG, (*device_addr), "%s", - "device request queue restarted by " - "state change pending interrupt\n"); - - del_timer (&(*device_addr)->timer); - - check_then_set (&cqr->status, - CQR_STATUS_PENDING, CQR_STATUS_QUEUED); - - dasd_schedule_bh (*device_addr); - + /* restart all 'running' IO on queue */ + cqr = device->queue.head; + while (cqr) { + if (cqr->status == CQR_STATUS_IN_IO) { + cqr->status = CQR_STATUS_QUEUED; + } + cqr = cqr->next; } + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "device request queue restarted by " + "state change pending interrupt"); + + del_timer_sync (&(device->blocking_timer)); + device->stopped &= ~DASD_STOPPED_PENDING; + dasd_schedule_bh (device); + } /* end dasd_handle_state_change_pending */ /* @@ -1879,50 +2300,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 +2351,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 +2373,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 +2476,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 +2572,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,38 +2601,43 @@ { 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); - break; - } - dasd_free_request (req, device); /* request is no longer used */ - if ( signal_pending(current) ) { - rc = -ERESTARTSYS; - break; + + rc = dasd_sleep_on_req (req); + dasd_free_request (req, device); /* request is no longer used */ + + if ( rc ) { + if (rc != -ERESTARTSYS ) + DEV_MESSAGE (KERN_WARNING, device, + " Formatting of unit %d failed" + " with rc = %d", + fdata->start_unit, rc); + break; } fdata->start_unit++; } @@ -2258,6 +2689,9 @@ return 0; } +/* + * handle the re-read partition table IOCTL (BLKRRPART) + */ static int dasd_revalidate (dasd_device_t * device) { @@ -2267,8 +2701,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 +2714,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 +2731,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 +2744,387 @@ 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 BIODASDGATTR: { /* Get Attributes (cache operations) */ + + attrib_data_t attrib; + + if (!capable (CAP_SYS_ADMIN)) { + rc = -EACCES; + break; + } + + if (!data) { + rc = -EINVAL; + break; + } + + if (!device->discipline->get_attrib) { + rc = -EINVAL; + break; + } + + device->discipline->get_attrib (device, + &attrib); + + rc = copy_to_user ((void *) data, &attrib, + sizeof (attrib_data_t)); + + if (rc) { + rc = -EFAULT; + } + + 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 +3136,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 +3185,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 +3245,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 +3302,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 +3327,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 +3344,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 +3369,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; @@ -2773,11 +3437,12 @@ while ( cqr != NULL ) { if ( cqr->status == CQR_STATUS_IN_IO ) device->discipline->term_IO (cqr); - if ( cqr->status != CQR_STATUS_DONE || + if ( cqr->status != CQR_STATUS_DONE && 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 +3467,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 +3525,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 +3540,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,9 +3554,11 @@ static void dasd_disable_ranges (dasd_range_t *range, - dasd_discipline_t *d, + dasd_discipline_t *discipline, int all, int force ) { + dasd_device_t **dptr; + dasd_device_t *device; dasd_range_t *rrange; int j; @@ -2850,22 +3570,24 @@ } do { for (j = rrange->from; j <= rrange->to; j++) { - dasd_device_t **dptr; - dasd_device_t *device; dptr = dasd_device_from_devno(j); - if ( dptr == NULL ) { + if (dptr == NULL) { continue; } device = *dptr; if (device == NULL || - (d != NULL && - device -> discipline != d)) + (discipline != NULL && + device -> discipline != discipline)) continue; dasd_disable_volume(device, force); } + + if (rrange->list.next == NULL) + break; rrange = list_entry (rrange->list.next, dasd_range_t, list); } while ( all && rrange && rrange != range ); + } static void @@ -2877,10 +3599,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 +3613,7 @@ return; do { + do_again = 0; if (range == &dasd_range_head) { rrange = list_entry (range->list.next, dasd_range_t, list); @@ -2898,26 +3624,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 +3679,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 +3689,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 +3710,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 +3733,45 @@ 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->stopped |= DASD_STOPPED_NOT_ACC; + + 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 +3785,54 @@ { int devno; int rc = 0; - major_info_t *major_info = NULL; - dasd_range_t *rptr,range; - dasd_device_t *device = NULL; + major_info_t *major_info; + dasd_range_t range; + 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); + if (device && + device->level >= DASD_STATE_READY) { + s390irq_spin_lock_irqsave (device->devinfo.irq, + flags); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "device is accessible again, reenabling it\n"); + device->stopped &= ~DASD_STOPPED_NOT_ACC; + + 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; + + if (dasd_autodetect) { + dasd_add_range (devno, devno, DASD_FEATURE_DEFAULT); } - } else { range.from = devno; range.to = devno; - rptr = ⦥ - } - dasd_enable_ranges (rptr, NULL, 0); + dasd_enable_ranges (&range, NULL, 0); } out: return rc; @@ -3075,13 +3844,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 +3862,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 +3871,109 @@ } 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); + 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 +3986,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 +4021,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 +4034,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,21 +4042,38 @@ 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, device->discipline->int_handler, dasd_not_oper_handler, - 0, DASD_NAME, + SA_DOPATHGROUP, DASD_NAME, &device->dev_status); if ( rc ) { - printk("No request IRQ\n"); + + MESSAGE (KERN_DEBUG, "%s", + "No request IRQ"); + + if (rc == -EUSERS) { + /* Device is reserved by someone else. */ + device->level = DASD_STATE_BOXED; + } + goto out; } } @@ -3272,10 +4090,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 +4120,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 +4140,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 +4177,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 +4200,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 +4217,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 +4247,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 +4289,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 +4304,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 +4335,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 +4350,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 +4383,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 +4406,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 +4489,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 +4546,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 +4575,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 +4642,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 +4668,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_LOG (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 > 0xFFFF) || (range.to > 0xFFFF)) + 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_LOG (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 > 0xFFFF) || (range.to > 0xFFFF)) + 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, + SA_DOPATHGROUP | SA_FORCE, + 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_LOG (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 +4924,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_LOG (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 +4967,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 +4986,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 +5049,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 +5107,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 +5165,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 +5280,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 +5296,17 @@ } while ( (rc=request_module(name)) != 0 ) { DECLARE_WAIT_QUEUE_HEAD(wait); - printk ( KERN_INFO "request_module returned %d for %s\n", - rc, - (char*)name); + + MESSAGE_LOG (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 +5315,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,29 +5374,38 @@ #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; irq = get_irq_next (irq)) { 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); + if (index < 0) { /* not included in ranges */ + + DBF_EVENT (DBF_CRIT, + "add %04x to range", + devno); + + dasd_add_range (devno, devno, + DASD_FEATURE_DEFAULT); } } } @@ -4216,15 +5414,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 +5433,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 +5450,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 +5475,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 +5496,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 +5566,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 Index: drivers/s390/block/dasd_3990_erp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/block/dasd_3990_erp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/block/dasd_3990_erp.c 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/s390/block/dasd_3990_erp.c 4 Aug 2004 01:29:28 -0000 1.2 @@ -5,6 +5,8 @@ * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001 * + * $Revision: 1.2 $ + * * 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: @@ -390,13 +447,6 @@ * Block the given device request queue to prevent from further * processing until the started timer has expired or an related * interrupt was received. - * - * PARAMETER - * erp request to be blocked - * expires time to wait until restart (in seconds) - * - * RETURN VALUES - * void */ void dasd_3990_erp_block_queue (ccw_req_t *erp, @@ -405,20 +455,26 @@ 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); + + device->stopped |= DASD_STOPPED_PENDING; check_then_set (&erp->status, CQR_STATUS_ERROR, - CQR_STATUS_PENDING); + CQR_STATUS_QUEUED); /* 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) device; + 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 */ @@ -426,24 +482,15 @@ * DASD_3990_ERP_RESTART_QUEUE * * DESCRIPTION - * Restarts request currently in status PENDING. - * This has to be done if either an related interrupt has received, or - * a timer has expired. - * - * - * PARAMETER - * erp pointer to the PENDING ERP - * - * RETURN VALUES - * void - * + * Restarts request queue of current device. + * This has to be done if either an related interrupt was received, or + * the timer has expired. */ void -dasd_3990_erp_restart_queue (unsigned long erp) +dasd_3990_erp_restart_queue (unsigned long device_ptr) { - ccw_req_t *cqr = (void *) erp; - dasd_device_t *device = cqr->device; + dasd_device_t *device = (dasd_device_t *) device_ptr; unsigned long flags; /* get the needed locks to modify the request queue */ @@ -451,20 +498,13 @@ flags); /* '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, - CQR_STATUS_QUEUED); - } + device->stopped &= ~DASD_STOPPED_PENDING; - /* release the lock */ s390irq_spin_unlock_irqrestore (device->devinfo.irq, flags); - dasd_schedule_bh (device); } /* end dasd_3990_erp_restart_queue */ @@ -498,9 +538,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 +578,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 +593,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 +638,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 +660,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 +676,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 +748,20 @@ } else { - if (sense[25] & 0x1D) { /* state change pending */ - - DASD_MESSAGE (KERN_INFO, device, "%s", - "waiting for state change pending " - "int"); + if (sense[25] == 0x1D) { /* state change pending */ + DEV_MESSAGE (KERN_INFO, device, + "waiting for state change pending " + "interrupt, %d retries left", + erp->retries); + 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 +838,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 +939,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 +1288,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 +1342,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 +1460,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 +1470,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 +1508,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 +1543,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 +1567,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 +1610,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 +1620,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 +1668,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 +1700,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 +1711,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 +1741,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 +1770,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 +1810,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 +1838,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 +1970,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 +2009,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 +2024,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 +2036,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 +2053,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 +2072,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 +2109,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 +2125,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 +2181,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 +2195,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 +2211,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 +2230,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 +2386,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 +2400,7 @@ break; default: - /* should not happen - continue */ + ; /* should not happen - continue */ } } @@ -2389,11 +2438,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 +2539,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 +2550,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 +2564,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 +2581,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 +2599,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 +2609,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 +2691,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 +2809,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 +2930,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 +2948,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 +3011,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 +3030,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 +3077,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 +3099,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 +3112,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 +3139,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 +3163,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 +3198,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 Index: drivers/s390/block/dasd_diag.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/block/dasd_diag.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/block/dasd_diag.c 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/s390/block/dasd_diag.c 4 Aug 2004 01:29:28 -0000 1.2 @@ -5,13 +5,16 @@ * ...............: by Hartmunt Penner * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 - + * + * $Revision: 1.2 $ + * * 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,58 +266,74 @@ { 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; + unsigned 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; } + + label = NULL; 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; + memset (private, 0, sizeof(dasd_diag_private_t)); 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(); } - private->label = (long *) get_free_page (GFP_KERNEL); - label = private->label; + label = (unsigned long *) get_free_page (GFP_KERNEL); + if (!label) { + MESSAGE (KERN_WARNING, "%s", + "No memory to allocate label struct"); + rc = -ENOMEM; + goto fail; + } mdsk_term_io (device); /* first terminate all outstanding operations */ /* figure out blocksize of device */ for (bsize = 512; bsize <= PAGE_SIZE; bsize <<= 1) { @@ -319,10 +347,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"); - free_page ((long) private->label); + + MESSAGE (KERN_WARNING, "%s", + "No memory to allocate initialization request"); + rc = -ENOMEM; goto fail; } @@ -330,15 +360,16 @@ memset (bio, 0, sizeof (diag_bio_t)); bio->type = MDSK_READ_REQ; bio->block_number = device->sizes.pt_block + 1; - bio->buffer = __pa (private->label); + bio->buffer = __pa (label); 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,22 +388,27 @@ 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); - free_page ((long) private->label); + + DEV_MESSAGE (KERN_INFO, device, + "capacity (%dkB blks): %ldkB", + (device->sizes.bp_block >> 10), + (device->sizes.blocks << device->sizes.s2b_shift) >> 1); + rc = 0; goto out; fail: - if ( rc ) { + if (device->private) { kfree (device->private); device->private = NULL; } out: + if (label) { + free_page ((unsigned long) label); + } return rc; } @@ -380,12 +416,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 +453,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 +477,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 +492,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,64 +503,64 @@ } 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; } -static char * -dasd_diag_dump_sense (struct dasd_device_t *device, ccw_req_t * req) -{ - char *page = (char *) get_free_page (GFP_KERNEL); - int len; - if (page == NULL) { - return NULL; - } - len = sprintf (page, KERN_WARNING PRINTK_HEADER - "device %04X on irq %d: I/O status report:\n", - device->devinfo.devno, device->devinfo.irq); - - return page; -} +/* + * max_blocks: We want to fit one CP into one page of memory so that we can + * effectively use available resources. + * The ccw_req_t has less than 256 bytes (including safety) + * and diag_bio_t for each block has 16 bytes. + * That makes: + * (4096 - 256) / 16 = 240 blocks at maximum. + */ dasd_discipline_t dasd_diag_discipline = { owner: THIS_MODULE, name:"DIAG", ebcname:"DIAG", - max_blocks:PAGE_SIZE / sizeof (diag_bio_t), + max_blocks:240, check_characteristics:dasd_diag_check_characteristics, fill_geometry:dasd_diag_fill_geometry, start_IO:dasd_start_diag, 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 +570,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); } } Index: drivers/s390/block/dasd_diag.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/block/dasd_diag.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/block/dasd_diag.h 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/s390/block/dasd_diag.h 4 Aug 2004 01:29:28 -0000 1.2 @@ -5,6 +5,11 @@ * ...............: by Hartmunt Penner * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 + * + * $Revision: 1.2 $ + * + * 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; Index: drivers/s390/block/dasd_eckd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/block/dasd_eckd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/block/dasd_eckd.c 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/s390/block/dasd_eckd.c 4 Aug 2004 01:29:28 -0000 1.2 @@ -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_NORMAL_CACHE; + private->attrib.nr_cyl = 0; + + /* 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,7 +1524,156 @@ return rc; } -static char* +/* + * 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_GET_ATTRIB + * + * DESCRIPTION + * returnes the cache attributes used in Define Extend (DE). + */ +int +dasd_eckd_get_attrib (dasd_device_t *device, + attrib_data_t *attrib) +{ + dasd_eckd_private_t *private; + + private = (dasd_eckd_private_t *) device->private; + *attrib = private->attrib; + + return 0; + +} /* end dasd_eckd_get_attrib */ + +/* + * DASD_ECKD_SET_ATTRIB + * + * 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) +{ + 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 0; + +} /* end dasd_eckd_set_attrib */ + +static void dasd_eckd_dump_sense (struct dasd_device_t *device, ccw_req_t *req) { @@ -1304,9 +1684,11 @@ int len, sl, sct; if (page == NULL) { - printk (KERN_ERR PRINTK_HEADER - "No memory to dump sense data\n"); - return NULL; + + MESSAGE (KERN_ERR, "%s", + "No memory to dump sense data"); + + return; } len = sprintf (page, KERN_ERR PRINTK_HEADER @@ -1318,17 +1700,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,17 +1745,17 @@ } 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_LOG (KERN_ERR, + "Sense data:\n%s", + page); free_page ((unsigned long) page); - - return NULL; } @@ -1371,7 +1763,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 +1783,22 @@ 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, + get_attrib:dasd_eckd_get_attrib, + 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 +1807,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 +1823,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]); } } Index: drivers/s390/block/dasd_eckd.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/block/dasd_eckd.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/block/dasd_eckd.h 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/s390/block/dasd_eckd.h 4 Aug 2004 01:29:28 -0000 1.2 @@ -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.2 $ + * + * 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); Index: drivers/s390/block/dasd_fba.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/block/dasd_fba.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/block/dasd_fba.c 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/s390/block/dasd_fba.c 4 Aug 2004 01:29:28 -0000 1.2 @@ -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.2 $ + * + * 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, @@ -377,21 +409,6 @@ } -static char * -dasd_fba_dump_sense (struct dasd_device_t *device, ccw_req_t * req) -{ - char *page = (char *) get_free_page (GFP_KERNEL); - int len; - if (page == NULL) { - return NULL; - } - len = sprintf (page, KERN_WARNING PRINTK_HEADER - "device %04X on irq %d: I/O status report:\n", - device->devinfo.devno, device->devinfo.irq); - - return page; -} - dasd_discipline_t dasd_fba_discipline = { owner: THIS_MODULE, name:"FBA ", @@ -407,17 +424,20 @@ erp_action:dasd_fba_erp_action, erp_postaction:dasd_fba_erp_postaction, build_cp_from_req:dasd_fba_build_cp_from_req, - 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 +446,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 +464,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; Index: drivers/s390/block/dasd_fba.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/block/dasd_fba.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/block/dasd_fba.h 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/s390/block/dasd_fba.h 4 Aug 2004 01:29:28 -0000 1.2 @@ -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.2 $ + * + * History of changes + * + */ #ifndef DASD_FBA_H #define DASD_FBA_H Index: drivers/s390/block/dasd_int.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/block/dasd_int.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/block/dasd_int.h 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/s390/block/dasd_int.h 4 Aug 2004 01:29:28 -0000 1.2 @@ -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.2 $ + * * 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,175 @@ 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);\ -} 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);\ -} 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);\ -} 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);\ +/* + * 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) + + +/******************************************************************************** + * 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) + +/* 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) + +/* general messages to be written via klogd and dbf */ +#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) + +/* general messages to be written via klogd only */ +#define MESSAGE_LOG(d_loglevel,d_string,d_args...)\ +do { \ + printk(d_loglevel PRINTK_HEADER \ + " " d_string "\n", \ + 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_get_attrib_fn_t) (struct dasd_device_t *, + struct attrib_data_t *); +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 void (*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 +368,32 @@ 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_get_attrib_fn_t get_attrib; /* get attributes (cache operations */ + 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 +425,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 +441,41 @@ 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 stopped; /* device (do_IO) was stopped */ + 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); +/* reasons why device (do_IO) was stopped */ +#define DASD_STOPPED_NOT_ACC 1 /* not accessible */ +#define DASD_STOPPED_PENDING 2 /* long busy */ + + +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__ */ Index: drivers/s390/block/xpram.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/block/xpram.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/block/xpram.c 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/s390/block/xpram.c 4 Aug 2004 01:29:28 -0000 1.2 @@ -184,9 +184,7 @@ "All devices with size 0 equally partition the " "remaining space on the expanded strorage not " "claimed by explicit sizes\n"); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12)) -MODULE_LICENSE ("GPL"); -#endif +MODULE_LICENSE("GPL"); /* The following items are obtained through kmalloc() in init_module() */ @@ -273,7 +271,7 @@ return XPRAM_INVALF; if ( (**strptr == '0') && ( (*((*strptr)+1) == 'x') || (*((*strptr) +1) == 'X') ) - && isdigit(*((*strptr)+3)) ) { + && isxdigit(*((*strptr)+2)) ) { *strptr=(*strptr)+2; return XPRAM_HEXF; } else return XPRAM_DECF; Index: drivers/s390/char/con3215.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/char/con3215.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/char/con3215.c 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/s390/char/con3215.c 4 Aug 2004 01:29:28 -0000 1.2 @@ -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: Index: drivers/s390/char/ctrlchar.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/char/ctrlchar.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/char/ctrlchar.c 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/s390/char/ctrlchar.c 4 Aug 2004 01:29:28 -0000 1.2 @@ -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; } Index: drivers/s390/char/ctrlchar.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/char/ctrlchar.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/char/ctrlchar.h 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/s390/char/ctrlchar.h 4 Aug 2004 01:29:28 -0000 1.2 @@ -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) Index: drivers/s390/misc/chandev.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/misc/chandev.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/misc/chandev.c 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/s390/misc/chandev.c 4 Aug 2004 01:29:29 -0000 1.2 @@ -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; Index: drivers/s390/net/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/net/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/net/Makefile 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/s390/net/Makefile 4 Aug 2004 01:29:29 -0000 1.2 @@ -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 Index: drivers/s390/net/ctcmain.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/net/ctcmain.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/net/ctcmain.c 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/s390/net/ctcmain.c 4 Aug 2004 01:29:29 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: ctcmain.c,v 1.1 2004/07/22 19:49:58 joff Exp $ + * $Id: ctcmain.c,v 1.2 2004/08/04 01:29:29 joff 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.1 $ + * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.2 $ * */ @@ -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; /** @@ -370,12 +400,14 @@ static __inline__ void ctc_clear_busy(net_device *dev) { clear_bit(0, &(((ctc_priv *)dev->priv)->tbusy)); - netif_wake_queue(dev); + if (((ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY) + netif_wake_queue(dev); } static __inline__ int ctc_test_and_set_busy(net_device *dev) { - netif_stop_queue(dev); + if (((ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY) + netif_stop_queue(dev); return test_and_set_bit(0, &((ctc_priv *)dev->priv)->tbusy); } @@ -387,7 +419,7 @@ */ static void print_banner(void) { static int printed = 0; - char vbuf[] = "$Revision: 1.1 $"; + char vbuf[] = "$Revision: 1.2 $"; char *version = vbuf; if (printed) @@ -398,16 +430,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 +497,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 +551,7 @@ DEV_EVENT_TXUP, DEV_EVENT_RXDOWN, DEV_EVENT_TXDOWN, + DEV_EVENT_RESTART, /** * MUST be always the last element!! */ @@ -530,6 +565,7 @@ "TX up", "RX down", "TX down", + "Restart", }; /** @@ -699,6 +735,8 @@ ll_header *header; int i; + if (!(loglevel & CTC_LOGLEVEL_DEBUG)) + return; p += offset; bl = *((__u16*)p); p += 2; @@ -745,16 +783,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 +810,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 +831,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 +856,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 +882,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 +935,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 +971,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 +1046,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 +1059,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 +1111,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 +1212,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 +1241,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 +1282,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 +1360,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 +1376,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 +1427,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 +1459,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 +1499,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 +1640,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 +1671,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 +1704,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 +1715,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 +1734,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 +1755,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 +1787,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 +1798,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 +1818,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 +1835,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 +1874,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 +1916,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 +1931,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 +1942,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 +1952,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 +1963,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 +1972,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 +1996,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 +2028,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 +2073,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 +2098,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 +2151,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 +2226,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 +2348,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 +2429,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 +2457,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 +2493,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 +2505,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 +2573,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 +2811,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; @@ -2655,7 +2835,6 @@ fsm_event(privptr->fsm, DEV_EVENT_START, dev); if (privptr->protocol == CTC_PROTO_LINUX_TTY) return -EBUSY; - dst_link_failure(skb); dev_kfree_skb(skb); privptr->stats.tx_dropped++; privptr->stats.tx_errors++; @@ -2725,7 +2904,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 +3024,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 >= 20) + 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 +3211,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 +3228,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 +3258,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 +3312,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 +3328,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 +3362,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 +3389,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 +3447,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 +3458,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 +3490,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 +3609,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 +3651,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 +3665,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 +3694,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 +3804,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 +3821,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 +3861,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 +3874,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 +3936,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 +3954,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 +3986,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 +4015,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 +4114,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 +4137,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 +4190,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 +4216,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 +4278,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 +4312,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 +4333,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 Index: drivers/s390/net/ctctty.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/net/ctctty.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/net/ctctty.c 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/s390/net/ctctty.c 4 Aug 2004 01:29:29 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: ctctty.c,v 1.1 2004/07/22 19:49:58 joff Exp $ + * $Id: ctctty.c,v 1.2 2004/08/04 01:29:29 joff Exp $ * * CTC / ESCON network driver, tty interface. * @@ -42,7 +42,7 @@ #define init_waitqueue_head(x) *(x)=NULL #define __set_current_state(state_value) \ do { current->state = state_value; } while (0) -#ifdef __SMP__ +#ifdef CONFIG_SMP #define set_current_state(state_value) \ do { __set_current_state(state_value); mb(); } while (0) #else @@ -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.1 $"; +char *ctc_tty_revision = "$Revision: 1.2 $"; 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; Index: drivers/s390/net/ctctty.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/net/ctctty.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/net/ctctty.h 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/s390/net/ctctty.h 4 Aug 2004 01:29:29 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: ctctty.h,v 1.1 2004/07/22 19:49:58 joff Exp $ + * $Id: ctctty.h,v 1.2 2004/08/04 01:29:29 joff Exp $ * * CTC / ESCON network driver, tty interface. * Index: drivers/s390/net/fsm.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/net/fsm.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/net/fsm.c 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/s390/net/fsm.c 4 Aug 2004 01:29:29 -0000 1.2 @@ -1,5 +1,5 @@ /** - * $Id: fsm.c,v 1.1 2004/07/22 19:49:58 joff Exp $ + * $Id: fsm.c,v 1.2 2004/08/04 01:29:29 joff Exp $ * * A generic FSM based on fsm used in isdn4linux * Index: drivers/s390/net/fsm.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/net/fsm.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/net/fsm.h 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/s390/net/fsm.h 4 Aug 2004 01:29:29 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: fsm.h,v 1.1 2004/07/22 19:49:58 joff Exp $ +/* $Id: fsm.h,v 1.2 2004/08/04 01:29:29 joff Exp $ */ #ifndef _FSM_H_ #define _FSM_H_ Index: drivers/s390/net/iucv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/net/iucv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/net/iucv.c 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/s390/net/iucv.c 4 Aug 2004 01:29:29 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: iucv.c,v 1.1 2004/07/22 19:49:58 joff Exp $ + * $Id: iucv.c,v 1.2 2004/08/04 01:29:29 joff 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.1 $ + * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.2 $ * */ @@ -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.1 $"; + char vbuf[] = "$Revision: 1.2 $"; 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( Index: drivers/s390/net/iucv.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/net/iucv.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/net/iucv.h 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/s390/net/iucv.h 4 Aug 2004 01:29:29 -0000 1.2 @@ -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. */ Index: drivers/s390/net/netiucv.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/s390/net/netiucv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/s390/net/netiucv.c 22 Jul 2004 19:49:58 -0000 1.1 +++ drivers/s390/net/netiucv.c 4 Aug 2004 01:29:29 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Id: netiucv.c,v 1.1 2004/07/22 19:49:58 joff Exp $ + * $Id: netiucv.c,v 1.2 2004/08/04 01:29:29 joff 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.1 $ + * RELEASE-TAG: IUCV network driver $Revision: 1.2 $ * */ @@ -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.1 $"; + char vbuf[] = "$Revision: 1.2 $"; 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) { Index: drivers/sbus/sbus.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/sbus.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/sbus.c 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/sbus/sbus.c 4 Aug 2004 01:29:29 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sbus.c,v 1.1 2004/07/22 19:49:59 joff Exp $ +/* $Id: sbus.c,v 1.2 2004/08/04 01:29:29 joff Exp $ * sbus.c: SBus support routines. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -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(); } Index: drivers/sbus/audio/amd7930.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/audio/amd7930.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/audio/amd7930.c 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/audio/amd7930.c 4 Aug 2004 01:29:30 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: amd7930.c,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: amd7930.c,v 1.2 2004/08/04 01:29:30 joff Exp $ * drivers/sbus/audio/amd7930.c * * Copyright (C) 1996,1997 Thomas K. Dyas (tdyas@eden.rutgers.edu) Index: drivers/sbus/audio/amd7930.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/audio/amd7930.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/audio/amd7930.h 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/audio/amd7930.h 4 Aug 2004 01:29:30 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: amd7930.h,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: amd7930.h,v 1.2 2004/08/04 01:29:30 joff Exp $ * drivers/sbus/audio/amd7930.h * * Copyright (C) 1996 Thomas K. Dyas (tdyas@noc.rutgers.edu) Index: drivers/sbus/audio/audio.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/audio/audio.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/audio/audio.c 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/audio/audio.c 4 Aug 2004 01:29:30 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: audio.c,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: audio.c,v 1.2 2004/08/04 01:29:30 joff Exp $ * drivers/sbus/audio/audio.c * * Copyright 1996 Thomas K. Dyas (tdyas@noc.rutgers.edu) Index: drivers/sbus/audio/cs4215.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/audio/cs4215.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/audio/cs4215.h 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/audio/cs4215.h 4 Aug 2004 01:29:30 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: cs4215.h,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: cs4215.h,v 1.2 2004/08/04 01:29:30 joff Exp $ * drivers/sbus/audio/cs4215.h * * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de) Index: drivers/sbus/audio/cs4231.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/audio/cs4231.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/audio/cs4231.c 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/audio/cs4231.c 4 Aug 2004 01:29:30 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: cs4231.c,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: cs4231.c,v 1.2 2004/08/04 01:29:30 joff Exp $ * drivers/sbus/audio/cs4231.c * * Copyright 1996, 1997, 1998, 1999 Derrick J Brashear (shadow@andrew.cmu.edu) Index: drivers/sbus/audio/cs4231.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/audio/cs4231.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/audio/cs4231.h 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/audio/cs4231.h 4 Aug 2004 01:29:30 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: cs4231.h,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: cs4231.h,v 1.2 2004/08/04 01:29:30 joff Exp $ * drivers/sbus/audio/cs4231.h * * Copyright (C) 1996 Thomas K. Dyas (tdyas@noc.rutgers.edu) Index: drivers/sbus/audio/dbri.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/audio/dbri.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/audio/dbri.c 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/audio/dbri.c 4 Aug 2004 01:29:30 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: dbri.c,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: dbri.c,v 1.2 2004/08/04 01:29:30 joff Exp $ * drivers/sbus/audio/dbri.c * * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de) Index: drivers/sbus/audio/dbri.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/audio/dbri.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/audio/dbri.h 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/audio/dbri.h 4 Aug 2004 01:29:30 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: dbri.h,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: dbri.h,v 1.2 2004/08/04 01:29:30 joff Exp $ * drivers/sbus/audio/cs4231.h * * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de) Index: drivers/sbus/audio/dmy.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/audio/dmy.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/audio/dmy.c 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/audio/dmy.c 4 Aug 2004 01:29:30 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: dmy.c,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: dmy.c,v 1.2 2004/08/04 01:29:30 joff Exp $ * drivers/sbus/audio/dummy.c * * Copyright 1998 Derrick J Brashear (shadow@andrew.cmu.edu) Index: drivers/sbus/audio/dummy.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/audio/dummy.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/audio/dummy.h 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/audio/dummy.h 4 Aug 2004 01:29:30 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: dummy.h,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: dummy.h,v 1.2 2004/08/04 01:29:30 joff Exp $ * drivers/sbus/audio/dummy.h * * Copyright (C) 1998 Derrick J. Brashear (shadow@dementia.org) Index: drivers/sbus/char/aurora.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/aurora.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/aurora.c 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/char/aurora.c 4 Aug 2004 01:29:30 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: aurora.c,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: aurora.c,v 1.2 2004/08/04 01:29:30 joff Exp $ * linux/drivers/sbus/char/aurora.c -- Aurora multiport driver * * Copyright (c) 1999 by Oliver Aldulea (oli at bv dot ro) Index: drivers/sbus/char/aurora.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/aurora.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/aurora.h 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/char/aurora.h 4 Aug 2004 01:29:30 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: aurora.h,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: aurora.h,v 1.2 2004/08/04 01:29:30 joff Exp $ * linux/drivers/sbus/char/aurora.h -- Aurora multiport driver * * Copyright (c) 1999 by Oliver Aldulea (oli@bv.ro) Index: drivers/sbus/char/bbc_envctrl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/bbc_envctrl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/bbc_envctrl.c 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/char/bbc_envctrl.c 4 Aug 2004 01:29:30 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: bbc_envctrl.c,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: bbc_envctrl.c,v 1.2 2004/08/04 01:29:30 joff Exp $ * bbc_envctrl.c: UltraSPARC-III environment control driver. * * Copyright (C) 2001 David S. Miller (davem@redhat.com) @@ -59,7 +59,7 @@ * before the hardware based power-off event is triggered. */ -/* These settings are in celcius. We use these defaults only +/* These settings are in Celsius. We use these defaults only * if we cannot interrogate the cpu-fru SEEPROM. */ struct temp_limits { Index: drivers/sbus/char/bbc_i2c.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/bbc_i2c.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/bbc_i2c.c 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/char/bbc_i2c.c 4 Aug 2004 01:29:30 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: bbc_i2c.c,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: bbc_i2c.c,v 1.2 2004/08/04 01:29:30 joff Exp $ * bbc_i2c.c: I2C low-level driver for BBC device on UltraSPARC-III * platforms. * Index: drivers/sbus/char/bbc_i2c.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/bbc_i2c.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/bbc_i2c.h 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/char/bbc_i2c.h 4 Aug 2004 01:29:30 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: bbc_i2c.h,v 1.1 2004/07/22 19:50:00 joff Exp $ */ +/* $Id: bbc_i2c.h,v 1.2 2004/08/04 01:29:30 joff Exp $ */ #ifndef _BBC_I2C_H #define _BBC_I2C_H Index: drivers/sbus/char/cpwatchdog.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/cpwatchdog.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/cpwatchdog.c 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/char/cpwatchdog.c 4 Aug 2004 01:29:30 -0000 1.2 @@ -544,7 +544,7 @@ static void wd_pingtimer(struct wd_timer* pTimer) { if(wd_readb(&pTimer->regs->status) & WD_S_RUNNING) { - wd_readb(&pTimer->regs->dcntr); + wd_readw(&pTimer->regs->dcntr); } } Index: drivers/sbus/char/display7seg.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/display7seg.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/display7seg.c 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/sbus/char/display7seg.c 4 Aug 2004 01:29:30 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: display7seg.c,v 1.1 2004/07/22 19:49:59 joff Exp $ +/* $Id: display7seg.c,v 1.2 2004/08/04 01:29:30 joff Exp $ * * display7seg - Driver implementation for the 7-segment display * present on Sun Microsystems CP1400 and CP1500 Index: drivers/sbus/char/envctrl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/envctrl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/envctrl.c 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/char/envctrl.c 4 Aug 2004 01:29:30 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: envctrl.c,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: envctrl.c,v 1.2 2004/08/04 01:29:30 joff Exp $ * envctrl.c: Temperature and Fan monitoring on Machines providing it. * * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) @@ -1125,7 +1125,7 @@ } err = kernel_thread(kenvctrld, NULL, CLONE_FS | CLONE_FILES); - if (err) + if (err < 0) goto out_deregister; return 0; Index: drivers/sbus/char/flash.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/flash.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/flash.c 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/char/flash.c 4 Aug 2004 01:29:30 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: flash.c,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: flash.c,v 1.2 2004/08/04 01:29:30 joff Exp $ * flash.c: Allow mmap access to the OBP Flash, for OBP updates. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -161,10 +161,13 @@ { struct sbus_bus *sbus; struct sbus_dev *sdev = 0; +#ifdef CONFIG_PCI struct linux_ebus *ebus; struct linux_ebus_device *edev = 0; struct linux_prom_registers regs[2]; - int len, err, nregs; + int len, nregs; +#endif + int err; for_all_sbusdev(sdev, sbus) { if (!strcmp(sdev->prom_name, "flashprom")) { Index: drivers/sbus/char/max1617.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/max1617.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/max1617.h 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/char/max1617.h 4 Aug 2004 01:29:30 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: max1617.h,v 1.1 2004/07/22 19:50:00 joff Exp $ */ +/* $Id: max1617.h,v 1.2 2004/08/04 01:29:30 joff Exp $ */ #ifndef _MAX1617_H #define _MAX1617_H Index: drivers/sbus/char/pcikbd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/pcikbd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/pcikbd.c 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/char/pcikbd.c 4 Aug 2004 01:29:31 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: pcikbd.c,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: pcikbd.c,v 1.2 2004/08/04 01:29:31 joff Exp $ * pcikbd.c: Ultra/AX PC keyboard support. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) Index: drivers/sbus/char/pcikbd.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/pcikbd.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/pcikbd.h 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/char/pcikbd.h 4 Aug 2004 01:29:31 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: pcikbd.h,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: pcikbd.h,v 1.2 2004/08/04 01:29:31 joff Exp $ * pcikbd.h: PCI/PC 8042 keyboard/mouse driver stuff. Mostly snarfed * from the existing driver by Martin Mares. * Index: drivers/sbus/char/riowatchdog.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/riowatchdog.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/riowatchdog.c 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/sbus/char/riowatchdog.c 4 Aug 2004 01:29:31 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: riowatchdog.c,v 1.1 2004/07/22 19:49:59 joff Exp $ +/* $Id: riowatchdog.c,v 1.2 2004/08/04 01:29:31 joff Exp $ * riowatchdog.c - driver for hw watchdog inside Super I/O of RIO * * Copyright (C) 2001 David S. Miller (davem@redhat.com) Index: drivers/sbus/char/rtc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/rtc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/rtc.c 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/sbus/char/rtc.c 4 Aug 2004 01:29:31 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: rtc.c,v 1.1 2004/07/22 19:49:59 joff Exp $ +/* $Id: rtc.c,v 1.2 2004/08/04 01:29:31 joff Exp $ * * Linux/SPARC Real Time Clock Driver * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu) @@ -89,6 +89,7 @@ switch (cmd) { case RTCGET: + memset(&rtc_tm, 0, sizeof(struct rtc_time)); get_rtc_time(&rtc_tm); if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time))) Index: drivers/sbus/char/sab82532.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/sab82532.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/sab82532.c 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/char/sab82532.c 4 Aug 2004 01:29:31 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sab82532.c,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: sab82532.c,v 1.2 2004/08/04 01:29:31 joff Exp $ * sab82532.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -2200,7 +2200,7 @@ static inline void __init show_serial_version(void) { - char *revision = "$Revision: 1.1 $"; + char *revision = "$Revision: 1.2 $"; char *version, *p; version = strchr(revision, ' '); Index: drivers/sbus/char/su.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/su.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/su.c 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/sbus/char/su.c 4 Aug 2004 01:29:31 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: su.c,v 1.1 2004/07/22 19:49:59 joff Exp $ +/* $Id: su.c,v 1.2 2004/08/04 01:29:31 joff Exp $ * su.c: Small serial driver for keyboard/mouse interface on sparc32/PCI * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -2252,7 +2252,7 @@ */ static __inline__ void __init show_su_version(void) { - char *revision = "$Revision: 1.1 $"; + char *revision = "$Revision: 1.2 $"; char *version, *p; version = strchr(revision, ' '); Index: drivers/sbus/char/sunkbd.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/sunkbd.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/sunkbd.h 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/sbus/char/sunkbd.h 4 Aug 2004 01:29:31 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sunkbd.h,v 1.1 2004/07/22 19:49:59 joff Exp $ +/* $Id: sunkbd.h,v 1.2 2004/08/04 01:29:31 joff Exp $ * sunkbd.h: Defines needed by SUN Keyboard drivers * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) Index: drivers/sbus/char/sunkbdmap.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/sunkbdmap.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/sunkbdmap.c 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/char/sunkbdmap.c 4 Aug 2004 01:29:31 -0000 1.2 @@ -1,5 +1,5 @@ -/* $Id: sunkbdmap.c,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: sunkbdmap.c,v 1.2 2004/08/04 01:29:31 joff Exp $ * sunkbdmap.c: Wrapper around sunkeymap.c to change table names. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) Index: drivers/sbus/char/sunmouse.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/sunmouse.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/sunmouse.h 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/sbus/char/sunmouse.h 4 Aug 2004 01:29:31 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sunmouse.h,v 1.1 2004/07/22 19:49:59 joff Exp $ +/* $Id: sunmouse.h,v 1.2 2004/08/04 01:29:31 joff Exp $ * sunmouse.h: Interface to the SUN mouse driver. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) Index: drivers/sbus/char/sunserial.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/sunserial.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/sunserial.c 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/char/sunserial.c 4 Aug 2004 01:29:31 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sunserial.c,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: sunserial.c,v 1.2 2004/08/04 01:29:31 joff Exp $ * serial.c: Serial port driver infrastructure for the Sparc. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) Index: drivers/sbus/char/sunserial.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/sunserial.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/sunserial.h 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/char/sunserial.h 4 Aug 2004 01:29:31 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sunserial.h,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: sunserial.h,v 1.2 2004/08/04 01:29:31 joff Exp $ * sunserial.h: SUN serial driver infrastructure (including keyboards). * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) Index: drivers/sbus/char/uctrl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/uctrl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/uctrl.c 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/sbus/char/uctrl.c 4 Aug 2004 01:29:31 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: uctrl.c,v 1.1 2004/07/22 19:50:00 joff Exp $ +/* $Id: uctrl.c,v 1.2 2004/08/04 01:29:31 joff Exp $ * uctrl.c: TS102 Microcontroller interface on Tadpole Sparcbook 3 * * Copyright 1999 Derrick J Brashear (shadow@dementia.org) Index: drivers/sbus/char/zs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/zs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/zs.c 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/sbus/char/zs.c 4 Aug 2004 01:29:31 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: zs.c,v 1.1 2004/07/22 19:49:59 joff Exp $ +/* $Id: zs.c,v 1.2 2004/08/04 01:29:31 joff Exp $ * zs.c: Zilog serial port driver for the Sparc. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -1701,7 +1701,7 @@ int zs_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { - char *revision = "$Revision: 1.1 $"; + char *revision = "$Revision: 1.2 $"; char *version, *p; int i, len = 0, l; off_t begin = 0; @@ -1966,7 +1966,7 @@ static void show_serial_version(void) { - char *revision = "$Revision: 1.1 $"; + char *revision = "$Revision: 1.2 $"; char *version, *p; version = strchr(revision, ' '); Index: drivers/sbus/char/zs.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/sbus/char/zs.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/sbus/char/zs.h 22 Jul 2004 19:49:59 -0000 1.1 +++ drivers/sbus/char/zs.h 4 Aug 2004 01:29:31 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: zs.h,v 1.1 2004/07/22 19:49:59 joff Exp $ +/* $Id: zs.h,v 1.2 2004/08/04 01:29:31 joff Exp $ * zs.h: Definitions for the Sparc Zilog serial driver. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) Index: drivers/scsi/3w-xxxx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/3w-xxxx.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/3w-xxxx.c 22 Jul 2004 19:50:03 -0000 1.1 +++ drivers/scsi/3w-xxxx.c 4 Aug 2004 01:29:31 -0000 1.2 @@ -165,12 +165,22 @@ 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. + 1.02.00.037 - Fix tw_ioctl() to handle all non-data ATA passthru cmds + for 'smartmontools' support. */ #include MODULE_AUTHOR ("3ware Inc."); -#ifdef __SMP__ +#ifdef CONFIG_SMP MODULE_DESCRIPTION ("3ware Storage Controller Linux Driver (SMP)"); #else MODULE_DESCRIPTION ("3ware Storage Controller Linux Driver"); @@ -232,7 +242,7 @@ }; /* Globals */ -char *tw_driver_version="1.02.00.032"; +char *tw_driver_version="1.02.00.037"; TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT]; int tw_device_extension_count = 0; static int twe_major = -1; @@ -271,25 +281,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 +565,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 +639,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 +743,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 +894,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 +1154,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 +1200,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 +1216,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 +1276,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 +1396,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 +1735,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]) { @@ -1916,12 +1932,15 @@ } passthru = (TW_Passthru *)tw_dev->command_packet_virtual_address[request_id]; - passthru->sg_list[0].length = passthru->sector_count*512; - if (passthru->sg_list[0].length > TW_MAX_PASSTHRU_BYTES) { - printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Passthru size (%d) too big.\n", passthru->sg_list[0].length); - return 1; + /* Don't load sg_list for non-data ATA cmds */ + if ((passthru->param != 0) && (passthru->param != 0x8)) { + passthru->sg_list[0].length = passthru->sector_count*512; + if (passthru->sg_list[0].length > TW_MAX_PASSTHRU_BYTES) { + printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Passthru size (%d) too big.\n", passthru->sg_list[0].length); + return 1; + } + passthru->sg_list[0].address = tw_dev->alignment_physical_address[request_id]; } - passthru->sg_list[0].address = tw_dev->alignment_physical_address[request_id]; tw_post_command_packet(tw_dev, request_id); return 0; case TW_CMD_PACKET: @@ -2172,7 +2191,14 @@ switch (ioctl->opcode) { case TW_ATA_PASSTHRU: passthru = (TW_Passthru *)ioctl->data; - memcpy(buff, tw_dev->alignment_virtual_address[request_id], passthru->sector_count * 512); + /* Don't return data for non-data ATA cmds */ + if ((passthru->param != 0) && (passthru->param != 0x8)) + memcpy(buff, tw_dev->alignment_virtual_address[request_id], passthru->sector_count * 512); + else { + /* For non-data cmds, return cmd pkt */ + if (tw_dev->srb[request_id]->request_bufflen >= sizeof(TW_Command)) + memcpy(buff, tw_dev->command_packet_virtual_address[request_id], sizeof(TW_Command)); + } break; case TW_CMD_PACKET_WITH_DATA: dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): caught TW_CMD_PACKET_WITH_DATA.\n"); @@ -3395,6 +3421,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) Index: drivers/scsi/3w-xxxx.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/3w-xxxx.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/3w-xxxx.h 22 Jul 2004 19:50:03 -0000 1.1 +++ drivers/scsi/3w-xxxx.h 4 Aug 2004 01:29:31 -0000 1.2 @@ -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); Index: drivers/scsi/53c7,8xx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/53c7,8xx.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/53c7,8xx.c 22 Jul 2004 19:50:01 -0000 1.1 +++ drivers/scsi/53c7,8xx.c 4 Aug 2004 01:29:31 -0000 1.2 @@ -6397,7 +6397,7 @@ (struct NCR53c7x0_hostdata *) host->hostdata; struct NCR53c7x0_cmd *cmd, *tmp; shutdown (host); - if (host->irq != IRQ_NONE) + if (host->irq != SCSI_IRQ_NONE) { int irq_count; struct Scsi_Host *tmp; Index: drivers/scsi/53c7,8xx.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/53c7,8xx.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/53c7,8xx.h 22 Jul 2004 19:50:01 -0000 1.1 +++ drivers/scsi/53c7,8xx.h 4 Aug 2004 01:29:31 -0000 1.2 @@ -1428,7 +1428,7 @@ }; -#define IRQ_NONE 255 +#define SCSI_IRQ_NONE 255 #define DMA_NONE 255 #define IRQ_AUTO 254 #define DMA_AUTO 254 Index: drivers/scsi/53c7xx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/53c7xx.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/53c7xx.c 22 Jul 2004 19:50:05 -0000 1.1 +++ drivers/scsi/53c7xx.c 4 Aug 2004 01:29:31 -0000 1.2 @@ -1104,8 +1104,8 @@ } /* - * Function : static int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board, - * int chip, u32 base, int io_port, int irq, int dma, long long options, + * Function : int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board, int chip, + * unsigned long base, int io_port, int irq, int dma, long long options, * int clock); * * Purpose : initializes a NCR53c7,8x0 based on base addresses, @@ -6081,7 +6081,7 @@ (struct NCR53c7x0_hostdata *) host->hostdata[0]; struct NCR53c7x0_cmd *cmd, *tmp; shutdown (host); - if (host->irq != IRQ_NONE) + if (host->irq != SCSI_IRQ_NONE) { int irq_count; struct Scsi_Host *tmp; Index: drivers/scsi/53c7xx.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/53c7xx.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/53c7xx.h 22 Jul 2004 19:50:05 -0000 1.1 +++ drivers/scsi/53c7xx.h 4 Aug 2004 01:29:31 -0000 1.2 @@ -1450,7 +1450,7 @@ }; -#define IRQ_NONE 255 +#define SCSI_IRQ_NONE 255 #define DMA_NONE 255 #define IRQ_AUTO 254 #define DMA_AUTO 254 @@ -1600,5 +1600,9 @@ /* Paranoid people could use panic() here. */ #define FATAL(host) shutdown((host)); +extern int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board, int chip, + unsigned long base, int io_port, int irq, int dma, + long long options, int clock); + #endif /* NCR53c710_C */ #endif /* NCR53c710_H */ Index: drivers/scsi/AM53C974.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/AM53C974.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/AM53C974.c 22 Jul 2004 19:50:07 -0000 1.1 +++ drivers/scsi/AM53C974.c 4 Aug 2004 01:29:31 -0000 1.2 @@ -45,8 +45,8 @@ /* * $Log: AM53C974.c,v $ - * Revision 1.1 2004/07/22 19:50:07 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:31 joff + * merging 2.4.26-vrs1 * */ Index: drivers/scsi/AM53C974.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/AM53C974.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/AM53C974.h 22 Jul 2004 19:50:07 -0000 1.1 +++ drivers/scsi/AM53C974.h 4 Aug 2004 01:29:31 -0000 1.2 @@ -22,8 +22,8 @@ /* * $Log: AM53C974.h,v $ - * Revision 1.1 2004/07/22 19:50:07 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:31 joff + * merging 2.4.26-vrs1 * */ Index: drivers/scsi/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/Config.in 22 Jul 2004 19:50:06 -0000 1.1 +++ drivers/scsi/Config.in 4 Aug 2004 01:29:32 -0000 1.2 @@ -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,11 +60,14 @@ 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 dep_tristate 'AMI MegaRAID support' CONFIG_SCSI_MEGARAID $CONFIG_SCSI +dep_tristate 'AMI MegaRAID2 support' CONFIG_SCSI_MEGARAID2 $CONFIG_SCSI dep_tristate 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC $CONFIG_SCSI if [ "$CONFIG_SCSI_BUSLOGIC" != "n" ]; then @@ -235,7 +237,7 @@ if [ "$CONFIG_AMIGA" = "y" ]; then dep_tristate 'A3000 WD33C93A support' CONFIG_A3000_SCSI $CONFIG_SCSI if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'A4000T SCSI support (EXPERIMENTAL)' CONFIG_A4000T_SCSI + bool 'Amiga NCR53c710 SCSI support (EXPERIMENTAL)' CONFIG_SCSI_AMIGA7XX fi fi if [ "$CONFIG_ZORRO" = "y" ]; then @@ -247,12 +249,8 @@ dep_tristate 'Blizzard 1230IV/1260 SCSI support' CONFIG_BLZ1230_SCSI $CONFIG_SCSI dep_tristate 'Fastlane SCSI support' CONFIG_FASTLANE_SCSI $CONFIG_SCSI if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'A4091 SCSI support (EXPERIMENTAL)' CONFIG_A4091_SCSI - bool 'WarpEngine SCSI support (EXPERIMENTAL)' CONFIG_WARPENGINE_SCSI - bool 'Blizzard PowerUP 603e+ SCSI (EXPERIMENTAL)' CONFIG_BLZ603EPLUS_SCSI dep_tristate 'BSC Oktagon SCSI support (EXPERIMENTAL)' CONFIG_OKTAGON_SCSI $CONFIG_SCSI # bool 'Cyberstorm Mk III SCSI support (EXPERIMENTAL)' CONFIG_CYBERSTORMIII_SCSI -# bool 'GVP Turbo 040/060 SCSI support (EXPERIMENTAL)' CONFIG_GVP_TURBO_SCSI fi fi Index: drivers/scsi/FlashPoint.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/FlashPoint.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/FlashPoint.c 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/FlashPoint.c 4 Aug 2004 01:29:32 -0000 1.2 @@ -163,9 +163,9 @@ * * Description: Common shared global defines. * - * $Date: 2004/07/22 19:50:02 $ + * $Date: 2004/08/04 01:29:32 $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * *----------------------------------------------------------------------*/ #ifndef __GLOBALS_H__ @@ -402,9 +402,9 @@ * Description: Common shared SCCB Interface defines and SCCB * Manager specifics defines. * - * $Date: 2004/07/22 19:50:02 $ + * $Date: 2004/08/04 01:29:32 $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * *----------------------------------------------------------------------*/ @@ -720,9 +720,9 @@ * Description: This module contains SCCB/UCB Manager implementation * specific stuff. * - * $Date: 2004/07/22 19:50:02 $ + * $Date: 2004/08/04 01:29:32 $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * *----------------------------------------------------------------------*/ @@ -877,9 +877,9 @@ * * Description: Definitions for Target related structures * - * $Date: 2004/07/22 19:50:02 $ + * $Date: 2004/08/04 01:29:32 $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * *----------------------------------------------------------------------*/ @@ -1076,9 +1076,9 @@ * * Description: Register definitions for HARPOON ASIC. * - * $Date: 2004/07/22 19:50:02 $ + * $Date: 2004/08/04 01:29:32 $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * *----------------------------------------------------------------------*/ @@ -1208,9 +1208,9 @@ * * Description: Definitions for EEPROM related structures * - * $Date: 2004/07/22 19:50:02 $ + * $Date: 2004/08/04 01:29:32 $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * *----------------------------------------------------------------------*/ @@ -1293,9 +1293,9 @@ * * Description: Register definitions for HARPOON ASIC. * - * $Date: 2004/07/22 19:50:02 $ + * $Date: 2004/08/04 01:29:32 $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * *----------------------------------------------------------------------*/ @@ -2326,7 +2326,7 @@ extern unsigned int SccbGlobalFlags; -#ident "$Id: FlashPoint.c,v 1.1 2004/07/22 19:50:02 joff Exp $" +#ident "$Id: FlashPoint.c,v 1.2 2004/08/04 01:29:32 joff Exp $" /*---------------------------------------------------------------------- * * @@ -2340,9 +2340,9 @@ * Description: Functions relating to handling of the SCCB interface * between the device driver and the HARPOON. * - * $Date: 2004/07/22 19:50:02 $ + * $Date: 2004/08/04 01:29:32 $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * *----------------------------------------------------------------------*/ @@ -5352,7 +5352,7 @@ } #endif -#ident "$Id: FlashPoint.c,v 1.1 2004/07/22 19:50:02 joff Exp $" +#ident "$Id: FlashPoint.c,v 1.2 2004/08/04 01:29:32 joff Exp $" /*---------------------------------------------------------------------- * * @@ -5366,9 +5366,9 @@ * Description: Functions relating to handling of the SCCB interface * between the device driver and the HARPOON. * - * $Date: 2004/07/22 19:50:02 $ + * $Date: 2004/08/04 01:29:32 $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * *----------------------------------------------------------------------*/ @@ -5424,7 +5424,7 @@ UCHAR debug_index[MAX_CARDS] = { 0 }; UCHAR reserved_1[3] = { 0 }; #endif -#ident "$Id: FlashPoint.c,v 1.1 2004/07/22 19:50:02 joff Exp $" +#ident "$Id: FlashPoint.c,v 1.2 2004/08/04 01:29:32 joff Exp $" /*---------------------------------------------------------------------- * * @@ -5439,9 +5439,9 @@ * selection/reselection, sync negotiation, message-in * decoding. * - * $Date: 2004/07/22 19:50:02 $ + * $Date: 2004/08/04 01:29:32 $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * *----------------------------------------------------------------------*/ @@ -7518,7 +7518,7 @@ } -#ident "$Id: FlashPoint.c,v 1.1 2004/07/22 19:50:02 joff Exp $" +#ident "$Id: FlashPoint.c,v 1.2 2004/08/04 01:29:32 joff Exp $" /*---------------------------------------------------------------------- * * @@ -7533,9 +7533,9 @@ * the target asserts request (and the automation is not * enabled to handle the situation). * - * $Date: 2004/07/22 19:50:02 $ + * $Date: 2004/08/04 01:29:32 $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * *----------------------------------------------------------------------*/ @@ -8267,7 +8267,7 @@ -#ident "$Id: FlashPoint.c,v 1.1 2004/07/22 19:50:02 joff Exp $" +#ident "$Id: FlashPoint.c,v 1.2 2004/08/04 01:29:32 joff Exp $" /*---------------------------------------------------------------------- * * @@ -8281,9 +8281,9 @@ * Description: Functions relating to programming the automation of * the HARPOON. * - * $Date: 2004/07/22 19:50:02 $ + * $Date: 2004/08/04 01:29:32 $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * *----------------------------------------------------------------------*/ @@ -8659,7 +8659,7 @@ queueCmdComplete(&BL_Card[p_card], currSCCB, p_card); } -#ident "$Id: FlashPoint.c,v 1.1 2004/07/22 19:50:02 joff Exp $" +#ident "$Id: FlashPoint.c,v 1.2 2004/08/04 01:29:32 joff Exp $" /*---------------------------------------------------------------------- * * @@ -8672,9 +8672,9 @@ * * Description: Functions to start, stop, and abort BusMaster operations. * - * $Date: 2004/07/22 19:50:02 $ + * $Date: 2004/08/04 01:29:32 $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * *----------------------------------------------------------------------*/ @@ -9351,7 +9351,7 @@ currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC; } } -#ident "$Id: FlashPoint.c,v 1.1 2004/07/22 19:50:02 joff Exp $" +#ident "$Id: FlashPoint.c,v 1.2 2004/08/04 01:29:32 joff Exp $" /*---------------------------------------------------------------------- * * @@ -9366,9 +9366,9 @@ * and the determination of the SCSI IDs to be assigned * to all perspective SCSI targets. * - * $Date: 2004/07/22 19:50:02 $ + * $Date: 2004/08/04 01:29:32 $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * *----------------------------------------------------------------------*/ @@ -10581,7 +10581,7 @@ utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2); utilEEWriteOnOff(p_port,0); /* Turn off write access */ } -#ident "$Id: FlashPoint.c,v 1.1 2004/07/22 19:50:02 joff Exp $" +#ident "$Id: FlashPoint.c,v 1.2 2004/08/04 01:29:32 joff Exp $" /*---------------------------------------------------------------------- * * @@ -10595,9 +10595,9 @@ * Description: Diagnostic funtions for testing the integrity of * the HARPOON. * - * $Date: 2004/07/22 19:50:02 $ + * $Date: 2004/08/04 01:29:32 $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * *----------------------------------------------------------------------*/ @@ -11026,7 +11026,7 @@ } -#ident "$Id: FlashPoint.c,v 1.1 2004/07/22 19:50:02 joff Exp $" +#ident "$Id: FlashPoint.c,v 1.2 2004/08/04 01:29:32 joff Exp $" /*---------------------------------------------------------------------- * * @@ -11040,9 +11040,9 @@ * Description: Utility functions relating to queueing and EEPROM * manipulation and any other garbage functions. * - * $Date: 2004/07/22 19:50:02 $ + * $Date: 2004/08/04 01:29:32 $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * *----------------------------------------------------------------------*/ /*#include */ Index: drivers/scsi/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/Makefile 22 Jul 2004 19:50:01 -0000 1.1 +++ drivers/scsi/Makefile 4 Aug 2004 01:29:32 -0000 1.2 @@ -27,16 +27,13 @@ subdir-$(CONFIG_SCSI_AACRAID) += aacraid subdir-$(CONFIG_SCSI_AIC7XXX) += aic7xxx -subdir-$(CONFIG_SCSI_AIC79XX) += aic79xx +subdir-$(CONFIG_SCSI_AIC79XX) += aic7xxx subdir-$(CONFIG_PCMCIA) += pcmcia obj-$(CONFIG_SCSI) += scsi_mod.o -obj-$(CONFIG_A4000T_SCSI) += amiga7xx.o 53c7xx.o -obj-$(CONFIG_A4091_SCSI) += amiga7xx.o 53c7xx.o -obj-$(CONFIG_BLZ603EPLUS_SCSI) += amiga7xx.o 53c7xx.o -obj-$(CONFIG_WARPENGINE_SCSI) += amiga7xx.o 53c7xx.o +obj-$(CONFIG_SCSI_AMIGA7XX) += amiga7xx.o 53c7xx.o obj-$(CONFIG_A3000_SCSI) += a3000.o wd33c93.o obj-$(CONFIG_A2091_SCSI) += a2091.o wd33c93.o obj-$(CONFIG_GVP11_SCSI) += gvp11.o wd33c93.o @@ -73,7 +70,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 @@ -97,7 +94,7 @@ obj-$(CONFIG_SCSI_NCR53C7xx) += 53c7,8xx.o subdir-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2 ifeq ($(CONFIG_SCSI_SYM53C8XX_2),y) - obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/sym53c8xx.o + obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/sym53c8xx_2.o endif obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o obj-$(CONFIG_SCSI_NCR53C8XX) += ncr53c8xx.o @@ -110,6 +107,7 @@ obj-$(CONFIG_SCSI_DC390T) += tmscsim.o obj-$(CONFIG_SCSI_AM53C974) += AM53C974.o obj-$(CONFIG_SCSI_MEGARAID) += megaraid.o +obj-$(CONFIG_SCSI_MEGARAID2) += megaraid2.o obj-$(CONFIG_SCSI_ACARD) += atp870u.o obj-$(CONFIG_SCSI_SUNESP) += esp.o obj-$(CONFIG_SCSI_GDTH) += gdth.o Index: drivers/scsi/NCR5380.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/NCR5380.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/NCR5380.c 22 Jul 2004 19:50:06 -0000 1.1 +++ drivers/scsi/NCR5380.c 4 Aug 2004 01:29:32 -0000 1.2 @@ -31,8 +31,8 @@ /* * $Log: NCR5380.c,v $ - * Revision 1.1 2004/07/22 19:50:06 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:32 joff + * merging 2.4.26-vrs1 * * Revision 1.10 1998/9/2 Alan Cox @@ -696,7 +696,7 @@ trying_irqs |= mask; timeout = jiffies + (250 * HZ / 1000); - probe_irq = IRQ_NONE; + probe_irq = SCSI_IRQ_NONE; /* * A interrupt is triggered whenever BSY = false, SEL = true @@ -713,7 +713,7 @@ NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL); - while (probe_irq == IRQ_NONE && time_before(jiffies, timeout)) + while (probe_irq == SCSI_IRQ_NONE && time_before(jiffies, timeout)) barrier(); NCR5380_write(SELECT_ENABLE_REG, 0); @@ -863,7 +863,7 @@ SPRINTF("\nBase Addr: 0x%05lX ", (long) instance->base); SPRINTF("io_port: %04x ", (int) instance->io_port); - if (instance->irq == IRQ_NONE) + if (instance->irq == SCSI_IRQ_NONE) SPRINTF("IRQ: None.\n"); else SPRINTF("IRQ: %d.\n", instance->irq); @@ -1709,7 +1709,7 @@ #endif /* def NCR_TIMEOUT */ dprintk(NDEBUG_SELECTION, ("scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->target)); - tmp[0] = IDENTIFY(((instance->irq == IRQ_NONE) ? 0 : 1), cmd->lun); + tmp[0] = IDENTIFY(((instance->irq == SCSI_IRQ_NONE) ? 0 : 1), cmd->lun); len = 1; cmd->tag = 0; Index: drivers/scsi/NCR5380.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/NCR5380.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/NCR5380.h 22 Jul 2004 19:50:06 -0000 1.1 +++ drivers/scsi/NCR5380.h 4 Aug 2004 01:29:32 -0000 1.2 @@ -23,8 +23,8 @@ /* * $Log: NCR5380.h,v $ - * Revision 1.1 2004/07/22 19:50:06 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:32 joff + * merging 2.4.26-vrs1 * */ @@ -236,7 +236,7 @@ * Scsi_Host structure */ -#define IRQ_NONE 255 +#define SCSI_IRQ_NONE 255 #define DMA_NONE 255 #define IRQ_AUTO 254 #define DMA_AUTO 254 Index: drivers/scsi/NCR53C9x.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/NCR53C9x.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/NCR53C9x.h 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/NCR53C9x.h 4 Aug 2004 01:29:32 -0000 1.2 @@ -639,8 +639,7 @@ /* External functions */ -extern inline void esp_cmd(struct NCR_ESP *esp, struct ESP_regs *eregs, - unchar cmd); +extern void esp_cmd(struct NCR_ESP *esp, struct ESP_regs *eregs, unchar cmd); extern struct NCR_ESP *esp_allocate(Scsi_Host_Template *, void *); extern void esp_deallocate(struct NCR_ESP *); extern void esp_release(void); Index: drivers/scsi/README.aha152x =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/README.aha152x,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/README.aha152x 22 Jul 2004 19:50:05 -0000 1.1 +++ drivers/scsi/README.aha152x 4 Aug 2004 01:29:32 -0000 1.2 @@ -1,4 +1,4 @@ -$Id: README.aha152x,v 1.1 2004/07/22 19:50:05 joff Exp $ +$Id: README.aha152x,v 1.2 2004/08/04 01:29:32 joff Exp $ Adaptec AHA-1520/1522 SCSI driver for Linux (aha152x) Copyright 1993-1999 Jürgen Fischer Index: drivers/scsi/README.aic7xxx =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/README.aic7xxx,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/README.aic7xxx 22 Jul 2004 19:50:05 -0000 1.1 +++ drivers/scsi/README.aic7xxx 4 Aug 2004 01:29:32 -0000 1.2 @@ -471,7 +471,7 @@ Dean W. Gehnert deang@teleport.com -$Revision: 1.1 $ +$Revision: 1.2 $ Modified by Doug Ledford 1998-2000 Index: drivers/scsi/README.osst =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/README.osst,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/README.osst 22 Jul 2004 19:50:06 -0000 1.1 +++ drivers/scsi/README.osst 4 Aug 2004 01:29:32 -0000 1.2 @@ -189,7 +189,7 @@ #!/bin/sh # Script to create OnStream SC-x0 device nodes (major 206) # Usage: Makedevs.sh [nos [path to dev]] -# $Id: README.osst,v 1.1 2004/07/22 19:50:06 joff Exp $ +# $Id: README.osst,v 1.2 2004/08/04 01:29:32 joff Exp $ major=206 nrs=4 dir=/dev Index: drivers/scsi/README.st =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/README.st,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/README.st 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/README.st 4 Aug 2004 01:29:32 -0000 1.2 @@ -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. Index: drivers/scsi/README.tmscsim =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/README.tmscsim,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/README.tmscsim 22 Jul 2004 19:50:04 -0000 1.1 +++ drivers/scsi/README.tmscsim 4 Aug 2004 01:29:32 -0000 1.2 @@ -446,4 +446,4 @@ ------------------------------------------------------------------------- Written by Kurt Garloff 1998/06/11 Last updated 2000/11/28, driver revision 2.0e7 -$Id: README.tmscsim,v 1.1 2004/07/22 19:50:04 joff Exp $ +$Id: README.tmscsim,v 1.2 2004/08/04 01:29:32 joff Exp $ Index: drivers/scsi/a2091.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/a2091.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/a2091.h 22 Jul 2004 19:50:07 -0000 1.1 +++ drivers/scsi/a2091.h 4 Aug 2004 01:29:32 -0000 1.2 @@ -1,7 +1,7 @@ #ifndef A2091_H #define A2091_H -/* $Id: a2091.h,v 1.1 2004/07/22 19:50:07 joff Exp $ +/* $Id: a2091.h,v 1.2 2004/08/04 01:29:32 joff Exp $ * * Header file for the Commodore A2091 Zorro II SCSI controller for Linux * Index: drivers/scsi/a3000.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/a3000.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/a3000.h 22 Jul 2004 19:50:07 -0000 1.1 +++ drivers/scsi/a3000.h 4 Aug 2004 01:29:32 -0000 1.2 @@ -1,7 +1,7 @@ #ifndef A3000_H #define A3000_H -/* $Id: a3000.h,v 1.1 2004/07/22 19:50:07 joff Exp $ +/* $Id: a3000.h,v 1.2 2004/08/04 01:29:32 joff Exp $ * * Header file for the Amiga 3000 built-in SCSI controller for Linux * Index: drivers/scsi/advansys.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/advansys.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/advansys.c 22 Jul 2004 19:50:07 -0000 1.1 +++ drivers/scsi/advansys.c 4 Aug 2004 01:29:32 -0000 1.2 @@ -5551,7 +5551,7 @@ } } else { ADV_CARR_T *carrp; - int req_cnt; + int req_cnt = 0; adv_req_t *reqp = NULL; int sg_cnt = 0; @@ -9257,8 +9257,6 @@ PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info), ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)), offset, byte_data); -#else /* CONFIG_PCI */ - return 0; #endif /* CONFIG_PCI */ } Index: drivers/scsi/aha152x.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aha152x.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aha152x.c 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/aha152x.c 4 Aug 2004 01:29:33 -0000 1.2 @@ -13,11 +13,11 @@ * General Public License for more details. * * - * $Id: aha152x.c,v 1.1 2004/07/22 19:50:02 joff Exp $ + * $Id: aha152x.c,v 1.2 2004/08/04 01:29:33 joff Exp $ * * $Log: aha152x.c,v $ - * Revision 1.1 2004/07/22 19:50:02 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:33 joff + * merging 2.4.26-vrs1 * * Revision 2.5 2002/04/14 11:24:53 fischer * - isapnp support @@ -225,10 +225,6 @@ #include -#if defined(PCMCIA) -#undef MODULE -#endif - #include #include #include @@ -257,6 +253,10 @@ #include +#if defined(PCMCIA) +#undef MODULE +#endif + /* DEFINES */ /* For PCMCIA cards, always use AUTOCONF */ @@ -1933,12 +1933,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); @@ -3936,7 +3954,9 @@ return thislength < length ? thislength : length; } +#ifndef PCMCIA /* Eventually this will go into an include file, but this will be later */ static Scsi_Host_Template driver_template = AHA152X; #include "scsi_module.c" +#endif Index: drivers/scsi/aha152x.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aha152x.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aha152x.h 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/aha152x.h 4 Aug 2004 01:29:33 -0000 1.2 @@ -2,7 +2,7 @@ #define _AHA152X_H /* - * $Id: aha152x.h,v 1.1 2004/07/22 19:50:02 joff Exp $ + * $Id: aha152x.h,v 1.2 2004/08/04 01:29:33 joff Exp $ */ #if defined(__KERNEL__) @@ -27,7 +27,7 @@ (unless we support more than 1 cmd_per_lun this should do) */ #define AHA152X_MAXQUEUE 7 -#define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 1.1 $" +#define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 1.2 $" /* Initial value of Scsi_Host entry */ #define AHA152X { proc_name: "aha152x", \ Index: drivers/scsi/aha1542.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aha1542.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aha1542.c 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/aha1542.c 4 Aug 2004 01:29:33 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: aha1542.c,v 1.1 2004/07/22 19:50:02 joff Exp $ +/* $Id: aha1542.c,v 1.2 2004/08/04 01:29:33 joff Exp $ * linux/kernel/aha1542.c * * Copyright (C) 1992 Tommy Thorn @@ -88,7 +88,7 @@ #endif /* - static const char RCSid[] = "$Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aha1542.c,v 1.1 2004/07/22 19:50:02 joff Exp $"; + static const char RCSid[] = "$Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aha1542.c,v 1.2 2004/08/04 01:29:33 joff Exp $"; */ /* The adaptec can be configured for quite a number of addresses, but @@ -111,8 +111,6 @@ static int setup_busoff[MAXBOARDS]; static int setup_dmaspeed[MAXBOARDS] __initdata = { -1, -1, -1, -1 }; -static char *setup_str[MAXBOARDS] __initdata; - /* * LILO/Module params: aha1542=[,,[,]] * @@ -960,6 +958,7 @@ #ifndef MODULE static int setup_idx = 0; +static char *setup_str[MAXBOARDS] __initdata; void __init aha1542_setup(char *str, int *ints) { Index: drivers/scsi/aha1542.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aha1542.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aha1542.h 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/aha1542.h 4 Aug 2004 01:29:33 -0000 1.2 @@ -1,12 +1,12 @@ #ifndef _AHA1542_H -/* $Id: aha1542.h,v 1.1 2004/07/22 19:50:02 joff Exp $ +/* $Id: aha1542.h,v 1.2 2004/08/04 01:29:33 joff Exp $ * * Header file for the adaptec 1542 driver for Linux * * $Log: aha1542.h,v $ - * Revision 1.1 2004/07/22 19:50:02 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:33 joff + * merging 2.4.26-vrs1 * * Revision 1.1 1992/07/24 06:27:38 root * Initial revision Index: drivers/scsi/aha1740.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aha1740.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aha1740.c 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/aha1740.c 4 Aug 2004 01:29:33 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: aha1740.c,v 1.1 2004/07/22 19:50:02 joff Exp $ +/* $Id: aha1740.c,v 1.2 2004/08/04 01:29:33 joff Exp $ * 1993/03/31 * linux/kernel/aha1740.c * @@ -52,7 +52,7 @@ #endif /* -static const char RCSid[] = "$Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aha1740.c,v 1.1 2004/07/22 19:50:02 joff Exp $"; +static const char RCSid[] = "$Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aha1740.c,v 1.2 2004/08/04 01:29:33 joff Exp $"; */ struct aha1740_hostdata { Index: drivers/scsi/aha1740.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aha1740.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aha1740.h 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/aha1740.h 4 Aug 2004 01:29:33 -0000 1.2 @@ -1,6 +1,6 @@ #ifndef _AHA1740_H -/* $Id: aha1740.h,v 1.1 2004/07/22 19:50:02 joff Exp $ +/* $Id: aha1740.h,v 1.2 2004/08/04 01:29:33 joff Exp $ * * Header file for the adaptec 1740 driver for Linux * Index: drivers/scsi/aic7xxx_old.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx_old.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx_old.c 22 Jul 2004 19:50:03 -0000 1.1 +++ drivers/scsi/aic7xxx_old.c 4 Aug 2004 01:29:33 -0000 1.2 @@ -73,7 +73,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: aic7xxx_old.c,v 1.1 2004/07/22 19:50:03 joff Exp $ + * $Id: aic7xxx_old.c,v 1.2 2004/08/04 01:29:33 joff Exp $ *--------------------------------------------------------------------------- * * Thanks also go to (in alphabetical order) the following: @@ -93,7 +93,7 @@ * * Daniel M. Eischen, deischen@iworks.InterWorks.org, 1/23/97 * - * $Id: aic7xxx_old.c,v 1.1 2004/07/22 19:50:03 joff Exp $ + * $Id: aic7xxx_old.c,v 1.2 2004/08/04 01:29:33 joff Exp $ *-M*************************************************************************/ /*+M************************************************************************** Index: drivers/scsi/amiga7xx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/amiga7xx.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/amiga7xx.c 22 Jul 2004 19:50:06 -0000 1.1 +++ drivers/scsi/amiga7xx.c 4 Aug 2004 01:29:33 -0000 1.2 @@ -1,6 +1,6 @@ /* * Detection routine for the NCR53c710 based Amiga SCSI Controllers for Linux. - * Amiga MacroSystemUS WarpEngine SCSI controller. + * Amiga MacroSystemUS WarpEngine SCSI controller. * Amiga Technologies A4000T SCSI controller. * Amiga Technologies/DKB A4091 SCSI controller. * @@ -14,13 +14,13 @@ #include #include #include +#include #include #include #include #include #include - #include #include "scsi.h" @@ -28,107 +28,83 @@ #include "53c7xx.h" #include "amiga7xx.h" -#include - -extern int ncr53c7xx_init (Scsi_Host_Template *tpnt, int board, int chip, - u32 base, int io_port, int irq, int dma, - long long options, int clock); -int __init amiga7xx_detect(Scsi_Host_Template *tpnt) +static int amiga7xx_register_one(Scsi_Host_Template *tpnt, + unsigned long address) { - static unsigned char called = 0; - int num = 0, clock; long long options; - struct zorro_dev *z = NULL; - unsigned long address; + int clock; - if (called || !MACH_IS_AMIGA) + if (!request_mem_region(address, 0x1000, "ncr53c710")) return 0; - tpnt->proc_name = "Amiga7xx"; + address = (unsigned long)z_ioremap(address, 0x1000); + options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | OPTION_INTFLY | + OPTION_SYNCHRONOUS | OPTION_ALWAYS_SYNCHRONOUS | + OPTION_DISCONNECT; + clock = 50000000; /* 50 MHz SCSI Clock */ + ncr53c7xx_init(tpnt, 0, 710, address, 0, IRQ_AMIGA_PORTS, DMA_NONE, + options, clock); + return 1; +} -#ifdef CONFIG_A4000T_SCSI - if (AMIGAHW_PRESENT(A4000_SCSI)) { - address = 0xdd0040; - if (request_mem_region(address, 0x1000, "ncr53c710")) { - address = ZTWO_VADDR(address); - options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | - OPTION_INTFLY | OPTION_SYNCHRONOUS | - OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT; - clock = 50000000; /* 50MHz SCSI Clock */ - ncr53c7xx_init(tpnt, 0, 710, address, 0, IRQ_AMIGA_PORTS, DMA_NONE, - options, clock); - num++; - } - } -#endif + +#ifdef CONFIG_ZORRO + +static struct { + zorro_id id; + unsigned long offset; + int absolute; /* offset is absolute address */ +} amiga7xx_table[] = { + { .id = ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS, .offset = 0xf40000, + .absolute = 1 }, + { .id = ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx, .offset = 0x40000 }, + { .id = ZORRO_PROD_CBM_A4091_1, .offset = 0x800000 }, + { .id = ZORRO_PROD_CBM_A4091_2, .offset = 0x800000 }, + { .id = ZORRO_PROD_GVP_GFORCE_040_060, .offset = 0x40000 }, + { 0 } +}; + +static int __init amiga7xx_zorro_detect(Scsi_Host_Template *tpnt) +{ + int num = 0, i; + struct zorro_dev *z = NULL; + unsigned long address; while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { - unsigned long address = z->resource.start; - unsigned long size = z->resource.end-z->resource.start+1; - switch (z->id) { -#ifdef CONFIG_BLZ603EPLUS_SCSI - case ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS: - address = 0xf40000; - if (request_mem_region(address, 0x1000, "ncr53c710")) { - address = ZTWO_VADDR(address); - options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | - OPTION_INTFLY | OPTION_SYNCHRONOUS | - OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT; - clock = 50000000; /* 50MHz SCSI Clock */ - ncr53c7xx_init(tpnt, 0, 710, address, 0, IRQ_AMIGA_PORTS, - DMA_NONE, options, clock); - num++; - } + for (i = 0; amiga7xx_table[i].id; i++) + if (z->id == amiga7xx_table[i].id) break; -#endif + if (!amiga7xx_table[i].id) + continue; + if (amiga7xx_table[i].absolute) + address = amiga7xx_table[i].offset; + else + address = z->resource.start + amiga7xx_table[i].offset; + num += amiga7xx_register_one(tpnt, address); + } + return num; +} -#ifdef CONFIG_WARPENGINE_SCSI - case ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx: - if (request_mem_region(address+0x40000, 0x1000, "ncr53c710")) { - address = (unsigned long)z_ioremap(address, size); - options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | - OPTION_INTFLY | OPTION_SYNCHRONOUS | - OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT; - clock = 50000000; /* 50MHz SCSI Clock */ - ncr53c7xx_init(tpnt, 0, 710, address+0x40000, 0, - IRQ_AMIGA_PORTS, DMA_NONE, options, clock); - num++; - } - break; -#endif +#endif /* CONFIG_ZORRO */ -#ifdef CONFIG_A4091_SCSI - case ZORRO_PROD_CBM_A4091_1: - case ZORRO_PROD_CBM_A4091_2: - if (request_mem_region(address+0x800000, 0x1000, "ncr53c710")) { - address = (unsigned long)z_ioremap(address, size); - options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | - OPTION_INTFLY | OPTION_SYNCHRONOUS | - OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT; - clock = 50000000; /* 50MHz SCSI Clock */ - ncr53c7xx_init(tpnt, 0, 710, address+0x800000, 0, - IRQ_AMIGA_PORTS, DMA_NONE, options, clock); - num++; - } - break; -#endif -#ifdef CONFIG_GVP_TURBO_SCSI - case ZORRO_PROD_GVP_GFORCE_040_060: - if (request_mem_region(address+0x40000, 0x1000, "ncr53c710")) { - address = ZTWO_VADDR(address); - options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | - OPTION_INTFLY | OPTION_SYNCHRONOUS | - OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT; - clock = 50000000; /* 50MHz SCSI Clock */ - ncr53c7xx_init(tpnt, 0, 710, address+0x40000, 0, - IRQ_AMIGA_PORTS, DMA_NONE, options, clock); - num++; - } +int __init amiga7xx_detect(Scsi_Host_Template *tpnt) +{ + static unsigned char called = 0; + int num = 0; + + if (called || !MACH_IS_AMIGA) + return 0; + + tpnt->proc_name = "Amiga7xx"; + + if (AMIGAHW_PRESENT(A4000_SCSI)) + num += amiga7xx_register_one(tpnt, 0xdd0040); + +#ifdef CONFIG_ZORRO + num += amiga7xx_zorro_detect(tpnt); #endif - } - } called = 1; return num; Index: drivers/scsi/atp870u.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/atp870u.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/atp870u.c 22 Jul 2004 19:50:06 -0000 1.1 +++ drivers/scsi/atp870u.c 4 Aug 2004 01:29:34 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: atp870u.c,v 1.1 2004/07/22 19:50:06 joff Exp $ +/* $Id: atp870u.c,v 1.2 2004/08/04 01:29:34 joff Exp $ * linux/kernel/atp870u.c * * Copyright (C) 1997 Wu Ching Chen @@ -40,7 +40,7 @@ void mydlyu(unsigned int); /* - * static const char RCSid[] = "$Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/atp870u.c,v 1.1 2004/07/22 19:50:06 joff Exp $"; + * static const char RCSid[] = "$Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/atp870u.c,v 1.2 2004/08/04 01:29:34 joff Exp $"; */ static unsigned char admaxu = 1; Index: drivers/scsi/atp870u.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/atp870u.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/atp870u.h 22 Jul 2004 19:50:06 -0000 1.1 +++ drivers/scsi/atp870u.h 4 Aug 2004 01:29:34 -0000 1.2 @@ -1,12 +1,12 @@ #ifndef _ATP870U_H -/* $Id: atp870u.h,v 1.1 2004/07/22 19:50:06 joff Exp $ +/* $Id: atp870u.h,v 1.2 2004/08/04 01:29:34 joff Exp $ * Header file for the ACARD 870U/W driver for Linux * * $Log: atp870u.h,v $ - * Revision 1.1 2004/07/22 19:50:06 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:34 joff + * merging 2.4.26-vrs1 * * Revision 1.0 1997/05/07 15:09:00 root * Initial revision Index: drivers/scsi/bvme6000.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/bvme6000.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/bvme6000.c 22 Jul 2004 19:50:05 -0000 1.1 +++ drivers/scsi/bvme6000.c 4 Aug 2004 01:29:34 -0000 1.2 @@ -23,9 +23,6 @@ #include -extern int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board, int chip, - u32 base, int io_port, int irq, int dma, - long long options, int clock); int bvme6000_scsi_detect(Scsi_Host_Template *tpnt) { Index: drivers/scsi/cpqfcTSi2c.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/cpqfcTSi2c.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/cpqfcTSi2c.c 22 Jul 2004 19:50:07 -0000 1.1 +++ drivers/scsi/cpqfcTSi2c.c 4 Aug 2004 01:29:34 -0000 1.2 @@ -59,7 +59,6 @@ #define SLAVE_WRITE_ADDRESS 0xA0 -static void i2c_delay(u32 mstime); static void tl_i2c_clock_pulse(u8, void *GPIOout); static u8 tl_read_i2c_data(void *); Index: drivers/scsi/cpqfcTSstructs.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/cpqfcTSstructs.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/cpqfcTSstructs.h 22 Jul 2004 19:50:06 -0000 1.1 +++ drivers/scsi/cpqfcTSstructs.h 4 Aug 2004 01:29:34 -0000 1.2 @@ -219,7 +219,6 @@ #define ELS_PRLI_ACC 0x22 // {FCP-SCSI} Process Login Accept #define ELS_RJT 0x1000000 #define SCSI_REPORT_LUNS 0x0A0 -#define REPORT_LUNS 0xA0 // SCSI-3 command op-code #define FCP_TARGET_RESET 0x200 #define ELS_LILP_FRAME 0x00000711 // 1st payload word of LILP frame Index: drivers/scsi/dc390.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/dc390.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/dc390.h 22 Jul 2004 19:50:07 -0000 1.1 +++ drivers/scsi/dc390.h 4 Aug 2004 01:29:34 -0000 1.2 @@ -4,7 +4,7 @@ * Description: Device Driver for Tekram DC-390(T) PCI SCSI * * Bus Master Host Adapter * ***********************************************************************/ -/* $Id: dc390.h,v 1.1 2004/07/22 19:50:07 joff Exp $ */ +/* $Id: dc390.h,v 1.2 2004/08/04 01:29:34 joff Exp $ */ /* * DC390/AMD 53C974 driver, header file Index: drivers/scsi/dec_esp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/dec_esp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/dec_esp.c 22 Jul 2004 19:50:01 -0000 1.1 +++ drivers/scsi/dec_esp.c 4 Aug 2004 01:29:34 -0000 1.2 @@ -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); } - Index: drivers/scsi/dmx3191d.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/dmx3191d.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/dmx3191d.c 22 Jul 2004 19:50:03 -0000 1.1 +++ drivers/scsi/dmx3191d.c 4 Aug 2004 01:29:34 -0000 1.2 @@ -96,7 +96,7 @@ printk(KERN_WARNING "dmx3191: IRQ %d not available - switching to polled mode.\n", pdev->irq); /* Steam powered scsi controllers run without an IRQ anyway */ - instance->irq = IRQ_NONE; + instance->irq = SCSI_IRQ_NONE; } boards++; @@ -113,7 +113,7 @@ int dmx3191d_release_resources(struct Scsi_Host *instance) { release_region(instance->io_port, DMX3191D_REGION); - if(instance->irq!=IRQ_NONE) + if(instance->irq != SCSI_IRQ_NONE) free_irq(instance->irq, instance); return 0; Index: drivers/scsi/dtc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/dtc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/dtc.c 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/dtc.c 4 Aug 2004 01:29:34 -0000 1.2 @@ -261,24 +261,24 @@ #ifndef DONT_USE_INTR /* With interrupts enabled, it will sometimes hang when doing heavy * reads. So better not enable them until I figure it out. */ - if (instance->irq != IRQ_NONE) + if (instance->irq != SCSI_IRQ_NONE) if (request_irq(instance->irq, do_dtc_intr, SA_INTERRUPT, "dtc")) { printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); - instance->irq = IRQ_NONE; + instance->irq = SCSI_IRQ_NONE; } - if (instance->irq == IRQ_NONE) { + if (instance->irq == SCSI_IRQ_NONE) { printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no); printk(KERN_INFO "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no); } #else - if (instance->irq != IRQ_NONE) + if (instance->irq != SCSI_IRQ_NONE) printk(KERN_INFO "scsi%d : interrupts not used. Might as well not jumper it.\n", instance->host_no); - instance->irq = IRQ_NONE; + instance->irq = SCSI_IRQ_NONE; #endif printk(KERN_INFO "scsi%d : at 0x%05X", instance->host_no, (int) instance->base); - if (instance->irq == IRQ_NONE) + if (instance->irq == SCSI_IRQ_NONE) printk(" interrupts disabled"); else printk(" irq %d", instance->irq); @@ -336,7 +336,7 @@ i = 0; NCR5380_read(RESET_PARITY_INTERRUPT_REG); NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE); - if (instance->irq == IRQ_NONE) + if (instance->irq == SCSI_IRQ_NONE) NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ); else NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ | CSR_INT_BASE); @@ -384,7 +384,7 @@ NCR5380_read(RESET_PARITY_INTERRUPT_REG); NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE); /* set direction (write) */ - if (instance->irq == IRQ_NONE) + if (instance->irq == SCSI_IRQ_NONE) NCR5380_write(DTC_CONTROL_REG, 0); else NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR); Index: drivers/scsi/eata_dma.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/eata_dma.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/eata_dma.c 22 Jul 2004 19:50:06 -0000 1.1 +++ drivers/scsi/eata_dma.c 4 Aug 2004 01:29:34 -0000 1.2 @@ -1067,7 +1067,7 @@ char *buff = 0; unchar bugs = 0; struct Scsi_Host *sh; - hostdata *hd; + hostdata *hd = NULL; int x; Index: drivers/scsi/esp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/esp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/esp.c 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/esp.c 4 Aug 2004 01:29:34 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: esp.c,v 1.1 2004/07/22 19:50:02 joff Exp $ +/* $Id: esp.c,v 1.2 2004/08/04 01:29:34 joff Exp $ * esp.c: EnhancedScsiProcessor Sun SCSI driver code. * * Copyright (C) 1995, 1998 David S. Miller (davem@caip.rutgers.edu) Index: drivers/scsi/esp.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/esp.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/esp.h 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/esp.h 4 Aug 2004 01:29:34 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: esp.h,v 1.1 2004/07/22 19:50:02 joff Exp $ +/* $Id: esp.h,v 1.2 2004/08/04 01:29:34 joff Exp $ * esp.h: Defines and structures for the Sparc ESP (Enhanced SCSI * Processor) driver under Linux. * Index: drivers/scsi/fd_mcs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/fd_mcs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/fd_mcs.c 22 Jul 2004 19:50:04 -0000 1.1 +++ drivers/scsi/fd_mcs.c 4 Aug 2004 01:29:34 -0000 1.2 @@ -28,7 +28,7 @@ * Author: Rickard E. Faith, faith@cs.unc.edu * Copyright 1992, 1993, 1994, 1995, 1996 Rickard E. Faith * - * $Id: fd_mcs.c,v 1.1 2004/07/22 19:50:04 joff Exp $ + * $Id: fd_mcs.c,v 1.2 2004/08/04 01:29:34 joff Exp $ * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Index: drivers/scsi/fdomain.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/fdomain.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/fdomain.c 22 Jul 2004 19:50:04 -0000 1.1 +++ drivers/scsi/fdomain.c 4 Aug 2004 01:29:34 -0000 1.2 @@ -296,7 +296,7 @@ #include /* for CONFIG_PCI */ -#define VERSION "$Revision: 1.1 $" +#define VERSION "$Revision: 1.2 $" /* START OF USER DEFINABLE OPTIONS */ @@ -2046,7 +2046,9 @@ MODULE_LICENSE("GPL"); +#ifndef PCMCIA /* Eventually this will go into an include file, but this will be later */ static Scsi_Host_Template driver_template = FDOMAIN_16X0; #include "scsi_module.c" +#endif Index: drivers/scsi/fdomain.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/fdomain.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/fdomain.h 22 Jul 2004 19:50:04 -0000 1.1 +++ drivers/scsi/fdomain.h 4 Aug 2004 01:29:34 -0000 1.2 @@ -4,7 +4,7 @@ * Author: Rickard E. Faith, faith@cs.unc.edu * Copyright 1992, 1993, 1994, 1995 Rickard E. Faith * - * $Id: fdomain.h,v 1.1 2004/07/22 19:50:04 joff Exp $ + * $Id: fdomain.h,v 1.2 2004/08/04 01:29:34 joff Exp $ * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Index: drivers/scsi/g_NCR5380.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/g_NCR5380.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/g_NCR5380.c 22 Jul 2004 19:50:07 -0000 1.1 +++ drivers/scsi/g_NCR5380.c 4 Aug 2004 01:29:34 -0000 1.2 @@ -80,8 +80,8 @@ /* * $Log: g_NCR5380.c,v $ - * Revision 1.1 2004/07/22 19:50:07 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:34 joff + * merging 2.4.26-vrs1 * */ @@ -336,7 +336,7 @@ if (dev->irq_resource[0].flags & IORESOURCE_IRQ) overrides[count].irq = dev->irq_resource[0].start; else - overrides[count].irq = IRQ_NONE; + overrides[count].irq = SCSI_IRQ_NONE; if (dev->dma_resource[0].flags & IORESOURCE_DMA) overrides[count].dma = dev->dma_resource[0].start; else @@ -433,19 +433,19 @@ else instance->irq = NCR5380_probe_irq(instance, 0xffff); - if (instance->irq != IRQ_NONE) + if (instance->irq != SCSI_IRQ_NONE) if (request_irq(instance->irq, do_generic_NCR5380_intr, SA_INTERRUPT, "NCR5380", NULL)) { printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); - instance->irq = IRQ_NONE; + instance->irq = SCSI_IRQ_NONE; } - if (instance->irq == IRQ_NONE) { + if (instance->irq == SCSI_IRQ_NONE) { printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no); printk(KERN_INFO "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no); } printk(KERN_INFO "scsi%d : at " STRVAL(NCR5380_map_name) " 0x%x", instance->host_no, (unsigned int) instance->NCR5380_instance_name); - if (instance->irq == IRQ_NONE) + if (instance->irq == SCSI_IRQ_NONE) printk(" interrupts disabled"); else printk(" irq %d", instance->irq); @@ -492,7 +492,7 @@ release_mem_region(instance->NCR5380_instance_name, NCR5380_region_size); #endif - if (instance->irq != IRQ_NONE) + if (instance->irq != SCSI_IRQ_NONE) free_irq(instance->irq, NULL); return 0; @@ -805,7 +805,7 @@ PRINTP("NO NCR53C400 driver extensions\n"); #endif PRINTP("Using %s mapping at %s 0x%lx, " ANDP STRVAL(NCR5380_map_config) ANDP STRVAL(NCR5380_map_name) ANDP scsi_ptr->NCR5380_instance_name); - if (scsi_ptr->irq == IRQ_NONE) + if (scsi_ptr->irq == SCSI_IRQ_NONE) PRINTP("no interrupt\n"); else PRINTP("on interrupt %d\n" ANDP scsi_ptr->irq); Index: drivers/scsi/g_NCR5380.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/g_NCR5380.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/g_NCR5380.h 22 Jul 2004 19:50:07 -0000 1.1 +++ drivers/scsi/g_NCR5380.h 4 Aug 2004 01:29:34 -0000 1.2 @@ -27,8 +27,8 @@ /* * $Log: g_NCR5380.h,v $ - * Revision 1.1 2004/07/22 19:50:07 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:34 joff + * merging 2.4.26-vrs1 * */ Index: drivers/scsi/gdth.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/gdth.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/gdth.c 22 Jul 2004 19:50:04 -0000 1.1 +++ drivers/scsi/gdth.c 4 Aug 2004 01:29:34 -0000 1.2 @@ -27,8 +27,8 @@ * Tested with Linux 1.2.13, ..., 2.2.20, ..., 2.4.18 * * * * $Log: gdth.c,v $ - * Revision 1.1 2004/07/22 19:50:04 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:34 joff + * merging 2.4.26-vrs1 * * Revision 1.61 2002/10/03 09:35:22 boji * Fixed SCREENSERVICE intialisation in SMP cases. @@ -251,7 +251,7 @@ * Initial revision * ************************************************************************/ -#ident "$Id: gdth.c,v 1.1 2004/07/22 19:50:04 joff Exp $" +#ident "$Id: gdth.c,v 1.2 2004/08/04 01:29:34 joff Exp $" /* All GDT Disk Array Controllers are fully supported by this driver. * This includes the PCI/EISA/ISA SCSI Disk Array Controllers and the @@ -4032,6 +4032,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); Index: drivers/scsi/gdth.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/gdth.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/gdth.h 22 Jul 2004 19:50:04 -0000 1.1 +++ drivers/scsi/gdth.h 4 Aug 2004 01:29:35 -0000 1.2 @@ -10,7 +10,7 @@ * * * - * $Id: gdth.h,v 1.1 2004/07/22 19:50:04 joff Exp $ + * $Id: gdth.h,v 1.2 2004/08/04 01:29:35 joff Exp $ */ #include Index: drivers/scsi/gdth_ioctl.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/gdth_ioctl.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/gdth_ioctl.h 22 Jul 2004 19:50:04 -0000 1.1 +++ drivers/scsi/gdth_ioctl.h 4 Aug 2004 01:29:35 -0000 1.2 @@ -2,7 +2,7 @@ #define _GDTH_IOCTL_H /* gdth_ioctl.h - * $Id: gdth_ioctl.h,v 1.1 2004/07/22 19:50:04 joff Exp $ + * $Id: gdth_ioctl.h,v 1.2 2004/08/04 01:29:35 joff Exp $ */ /* IOCTLs */ Index: drivers/scsi/gdth_proc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/gdth_proc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/gdth_proc.c 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/gdth_proc.c 4 Aug 2004 01:29:35 -0000 1.2 @@ -1,5 +1,5 @@ /* gdth_proc.c - * $Id: gdth_proc.c,v 1.1 2004/07/22 19:50:02 joff Exp $ + * $Id: gdth_proc.c,v 1.2 2004/08/04 01:29:35 joff Exp $ */ #include "gdth_ioctl.h" Index: drivers/scsi/gdth_proc.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/gdth_proc.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/gdth_proc.h 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/gdth_proc.h 4 Aug 2004 01:29:35 -0000 1.2 @@ -2,7 +2,7 @@ #define _GDTH_PROC_H /* gdth_proc.h - * $Id: gdth_proc.h,v 1.1 2004/07/22 19:50:02 joff Exp $ + * $Id: gdth_proc.h,v 1.2 2004/08/04 01:29:35 joff Exp $ */ static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum); Index: drivers/scsi/gvp11.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/gvp11.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/gvp11.h 22 Jul 2004 19:50:05 -0000 1.1 +++ drivers/scsi/gvp11.h 4 Aug 2004 01:29:35 -0000 1.2 @@ -1,6 +1,6 @@ #ifndef GVP11_H -/* $Id: gvp11.h,v 1.1 2004/07/22 19:50:05 joff Exp $ +/* $Id: gvp11.h,v 1.2 2004/08/04 01:29:35 joff Exp $ * * Header file for the GVP Series II SCSI controller for Linux * Index: drivers/scsi/hosts.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/hosts.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/hosts.c 22 Jul 2004 19:50:06 -0000 1.1 +++ drivers/scsi/hosts.c 4 Aug 2004 01:29:35 -0000 1.2 @@ -41,7 +41,7 @@ #include "hosts.h" /* -static const char RCSid[] = "$Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/hosts.c,v 1.1 2004/07/22 19:50:06 joff Exp $"; +static const char RCSid[] = "$Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/hosts.c,v 1.2 2004/08/04 01:29:35 joff Exp $"; */ /* Index: drivers/scsi/hosts.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/hosts.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/hosts.h 22 Jul 2004 19:50:06 -0000 1.1 +++ drivers/scsi/hosts.h 4 Aug 2004 01:29:35 -0000 1.2 @@ -22,7 +22,7 @@ #define _HOSTS_H /* - $Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/hosts.h,v 1.1 2004/07/22 19:50:06 joff Exp $ + $Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/hosts.h,v 1.2 2004/08/04 01:29:35 joff Exp $ */ #include Index: drivers/scsi/ide-scsi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/ide-scsi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/ide-scsi.c 22 Jul 2004 19:50:01 -0000 1.1 +++ drivers/scsi/ide-scsi.c 4 Aug 2004 01:29:35 -0000 1.2 @@ -531,6 +531,8 @@ atapi_bcount_t bcount; struct request *rq = pc->rq; + feature.all = 0; + /* Set the current packet command */ scsi->pc = pc; /* We haven't transferred any data yet */ @@ -539,6 +541,7 @@ /* Request to transfer the entire buffer at once */ bcount.all = IDE_MIN(pc->request_transfer, 63 * 1024); + if (drive->using_dma && rq->bh) { if (test_bit(PC_WRITING, &pc->flags)) feature.b.dma = !HWIF(drive)->ide_dma_write(drive); @@ -1105,15 +1108,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) Index: drivers/scsi/ips.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/ips.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/ips.c 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/ips.c 4 Aug 2004 01:29:35 -0000 1.2 @@ -5,8 +5,8 @@ /* Jack Hammer, Adaptec, Inc. */ /* David Jeffery, Adaptec, Inc. */ /* */ -/* Copyright (C) 2000 IBM Corporation */ -/* Copyright (C) 2003 Adaptec, Inc. */ +/* Copyright (C) 2000 IBM Corporation */ +/* Copyright (C) 2002,2003 Adaptec, 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 */ @@ -83,7 +83,7 @@ /* 2.3.18 and later */ /* - Sync with other changes from the 2.3 kernels */ /* 4.00.06 - Fix timeout with initial FFDC command */ -/* 4.00.06a - Port to 2.4 (trivial) -- Christoph Hellwig */ +/* 4.00.06a - Port to 2.4 (trivial) -- Christoph Hellwig */ /* 4.10.00 - Add support for ServeRAID 4M/4L */ /* 4.10.13 - Fix for dynamic unload and proc file system */ /* 4.20.03 - Rename version to coincide with new release schedules */ @@ -130,6 +130,9 @@ /* 5.10.15 - remove unused code (sem, macros, etc.) */ /* 5.30.00 - use __devexit_p() */ /* 6.00.00 - Add 6x Adapters and Battery Flash */ +/* 6.10.00 - Remove 1G Addressing Limitations */ +/* 6.11.xx - Get VersionInfo buffer off the stack ! DDTS 60401 */ +/* 6.11.xx - Make Logical Drive Info structure safe for DMA DDTS 60639 */ /*****************************************************************************/ /* @@ -150,7 +153,7 @@ * nommap - Don't use memory mapped I/O * ioctlsize - Initial size of the IOCTL buffer */ - + #include #include #include @@ -182,75 +185,35 @@ #include #include -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) - #include - #include -#else - #include -#endif +#include +#include #include #ifdef MODULE - static char *ips = NULL; - MODULE_PARM(ips, "s"); +static char *ips = NULL; +MODULE_PARM(ips, "s"); #endif /* * DRIVER_VER */ -#define IPS_VERSION_HIGH "6.00" -#define IPS_VERSION_LOW ".26 " - - -#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) -struct proc_dir_entry proc_scsi_ips = { - 0, - 3, "ips", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; -#endif +#define IPS_VERSION_HIGH "6.11" +#define IPS_VERSION_LOW ".07 " -#if !defined(__i386__) && !defined(__ia64__) - #error "This driver has only been tested on the x86/ia64 platforms" -#endif - -#if LINUX_VERSION_CODE < LinuxVersionCode(2,2,0) - #error "This driver only works with kernel 2.2.0 and later" -#elif LINUX_VERSION_CODE <= LinuxVersionCode(2,3,18) - #define dma_addr_t uint32_t - - static inline void *pci_alloc_consistent(struct pci_dev *dev,int size, - dma_addr_t *dmahandle) { - void * ptr = kmalloc(size, GFP_ATOMIC); - if(ptr){ - *dmahandle = (uint32_t)virt_to_bus(ptr); - } - return ptr; - } - - #define pci_free_consistent(a,size,address,dmahandle) kfree(address) - - #define pci_map_sg(a,b,n,z) (n) - #define pci_unmap_sg(a,b,c,d) - #define pci_map_single(a,b,c,d) ((uint32_t)virt_to_bus(b)) - #define pci_unmap_single(a,b,c,d) - #ifndef sg_dma_address - #define sg_dma_address(x) ((uint32_t)virt_to_bus((x)->address)) - #define sg_dma_len(x) ((x)->length) - #endif - #define pci_unregister_driver(x) +#if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__) +#warning "This driver has only been tested on the x86/ia64/x86_64 platforms" #endif #if LINUX_VERSION_CODE <= LinuxVersionCode(2,5,0) - #define IPS_SG_ADDRESS(sg) ((sg)->address) - #define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags) - #define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock_irqrestore(&io_request_lock,flags) +#define IPS_SG_ADDRESS(sg) ((sg)->address) +#define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags) +#define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock_irqrestore(&io_request_lock,flags) #else - #define IPS_SG_ADDRESS(sg) (page_address((sg)->page) ? \ +#define IPS_SG_ADDRESS(sg) (page_address((sg)->page) ? \ page_address((sg)->page)+(sg)->offset : 0) - #define IPS_LOCK_SAVE(lock,flags) spin_lock(lock) - #define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock(lock) +#define IPS_LOCK_SAVE(lock,flags) do{spin_lock(lock);(void)flags;}while(0) +#define IPS_UNLOCK_RESTORE(lock,flags) do{spin_unlock(lock);(void)flags;}while(0) #endif #define IPS_DMA_DIR(scb) ((!scb->scsi_cmd || ips_is_passthru(scb->scsi_cmd) || \ @@ -259,218 +222,145 @@ scsi_to_pci_dma_dir(scb->scsi_cmd->sc_data_direction)) #ifdef IPS_DEBUG - #define METHOD_TRACE(s, i) if (ips_debug >= (i+10)) printk(KERN_NOTICE s "\n"); - #define DEBUG(i, s) if (ips_debug >= i) printk(KERN_NOTICE s "\n"); - #define DEBUG_VAR(i, s, v...) if (ips_debug >= i) printk(KERN_NOTICE s "\n", v); +#define METHOD_TRACE(s, i) if (ips_debug >= (i+10)) printk(KERN_NOTICE s "\n"); +#define DEBUG(i, s) if (ips_debug >= i) printk(KERN_NOTICE s "\n"); +#define DEBUG_VAR(i, s, v...) if (ips_debug >= i) printk(KERN_NOTICE s "\n", v); #else - #define METHOD_TRACE(s, i) - #define DEBUG(i, s) - #define DEBUG_VAR(i, s, v...) +#define METHOD_TRACE(s, i) +#define DEBUG(i, s) +#define DEBUG_VAR(i, s, v...) #endif /* * global variables */ -static const char ips_name[] = "ips"; -static struct Scsi_Host *ips_sh[IPS_MAX_ADAPTERS]; /* Array of host controller structures */ -static ips_ha_t *ips_ha[IPS_MAX_ADAPTERS]; /* Array of HA structures */ -static unsigned int ips_next_controller = 0; -static unsigned int ips_num_controllers = 0; -static unsigned int ips_released_controllers = 0; -static int ips_cmd_timeout = 60; -static int ips_reset_timeout = 60 * 5; -static int ips_force_memio = 1; /* Always use Memory Mapped I/O */ -static int ips_force_i2o = 1; /* Always use I2O command delivery */ -static int ips_ioctlsize = IPS_IOCTL_SIZE; /* Size of the ioctl buffer */ -static int ips_cd_boot = 0; /* Booting from Manager CD */ -static char *ips_FlashData = NULL; /* CD Boot - Flash Data Buffer */ -static long ips_FlashDataInUse = 0; /* CD Boot - Flash Data In Use Flag */ -static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Lite Adapter */ - -IPS_DEFINE_COMPAT_TABLE( Compatable ); /* Version Compatability Table */ +static const char ips_name[] = "ips"; +static struct Scsi_Host *ips_sh[IPS_MAX_ADAPTERS]; /* Array of host controller structures */ +static ips_ha_t *ips_ha[IPS_MAX_ADAPTERS]; /* Array of HA structures */ +static unsigned int ips_next_controller; +static unsigned int ips_num_controllers; +static unsigned int ips_released_controllers; +static int ips_cmd_timeout = 60; +static int ips_reset_timeout = 60 * 5; +static int ips_force_memio = 1; /* Always use Memory Mapped I/O */ +static int ips_force_i2o = 1; /* Always use I2O command delivery */ +static int ips_ioctlsize = IPS_IOCTL_SIZE; /* Size of the ioctl buffer */ +static int ips_cd_boot; /* Booting from Manager CD */ +static char *ips_FlashData = NULL; /* CD Boot - Flash Data Buffer */ +static dma_addr_t ips_flashbusaddr; +static long ips_FlashDataInUse; /* CD Boot - Flash Data In Use Flag */ +static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Lite Adapter */ +static Scsi_Host_Template ips_driver_template = IPS; +IPS_DEFINE_COMPAT_TABLE(Compatable); /* Version Compatability Table */ -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) /* This table describes all ServeRAID Adapters */ - static struct pci_device_id ips_pci_table[] __devinitdata = { - { 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, - { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, - { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, - { 0, } - }; - - /* This table describes only Anaconda Family Adapters */ - static struct pci_device_id ips_pci_table_anaconda[] __devinitdata = { - { 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, - { 0, } - }; - - /* This table describes only Sarasota ( ServeRAID 5i ) Adapters */ - static struct pci_device_id ips_pci_table_5i[] __devinitdata = { - { 0x1014, 0x01BD, PCI_ANY_ID, 0x259, 0, 0 }, - { 0x1014, 0x01BD, PCI_ANY_ID, 0x258, 0, 0 }, - { 0, } - }; - - /* This table describes only Sebring ( ServeRAID 6i ) Adapters */ - static struct pci_device_id ips_pci_table_6i[] __devinitdata = { - { 0x9005, 0x0250, PCI_ANY_ID, 0x28C, 0, 0 }, - { 0, } - }; - - /* This table describes all i960 ( 4M, 4Mx, 4L, 4Lx ) Adapters */ - static struct pci_device_id ips_pci_table_i960[] __devinitdata = { - { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, - { 0, } - }; - - /* This table describes all Adaptec ( 6M ) Adapters */ - static struct pci_device_id ips_pci_table_adaptec[] __devinitdata = { - { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, - { 0, } - }; - - MODULE_DEVICE_TABLE( pci, ips_pci_table ); - - static char ips_hot_plug_name[] = "ips"; - - static int __devinit ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent); - static void ips_remove_device(struct pci_dev *pci_dev); - - struct pci_driver ips_pci_driver = { - name: ips_hot_plug_name, - id_table: ips_pci_table, - probe: ips_insert_device, - remove: ips_remove_device, - }; - - struct pci_driver ips_pci_driver_anaconda = { - name: ips_hot_plug_name, - id_table: ips_pci_table_anaconda, - probe: ips_insert_device, - remove: ips_remove_device, - }; - - struct pci_driver ips_pci_driver_5i = { - name: ips_hot_plug_name, - id_table: ips_pci_table_5i, - probe: ips_insert_device, - remove: ips_remove_device, - }; - - struct pci_driver ips_pci_driver_6i = { - name: ips_hot_plug_name, - id_table: ips_pci_table_6i, - probe: ips_insert_device, - remove: ips_remove_device, - }; - - struct pci_driver ips_pci_driver_i960 = { - name: ips_hot_plug_name, - id_table: ips_pci_table_i960, - probe: ips_insert_device, - remove: ips_remove_device, - }; - - struct pci_driver ips_pci_driver_adaptec = { - name: ips_hot_plug_name, - id_table: ips_pci_table_adaptec, - probe: ips_insert_device, - remove: ips_remove_device, - }; +static struct pci_device_id ips_pci_table[] __devinitdata = { + {0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0}, + {0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0}, + {0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0}, + {0,} +}; -#endif +MODULE_DEVICE_TABLE(pci, ips_pci_table); + +static char ips_hot_plug_name[] = "ips"; + +static int __devinit ips_insert_device(struct pci_dev *pci_dev, + const struct pci_device_id *ent); +static void ips_remove_device(struct pci_dev *pci_dev); + +struct pci_driver ips_pci_driver = { + .name = ips_hot_plug_name, + .id_table = ips_pci_table, + .probe = ips_insert_device, + .remove = ips_remove_device, +}; /* * Necessary forward function protoypes */ static int ips_halt(struct notifier_block *nb, ulong event, void *buf); -#define MAX_ADAPTER_NAME 11 +#define MAX_ADAPTER_NAME 15 static char ips_adapter_name[][30] = { - "ServeRAID", - "ServeRAID II", - "ServeRAID on motherboard", - "ServeRAID on motherboard", - "ServeRAID 3H", - "ServeRAID 3L", - "ServeRAID 4H", - "ServeRAID 4M", - "ServeRAID 4L", - "ServeRAID 4Mx", - "ServeRAID 4Lx", - "ServeRAID 5i", - "ServeRAID 5i", - "ServeRAID 6M", - "ServeRAID 6i" + "ServeRAID", + "ServeRAID II", + "ServeRAID on motherboard", + "ServeRAID on motherboard", + "ServeRAID 3H", + "ServeRAID 3L", + "ServeRAID 4H", + "ServeRAID 4M", + "ServeRAID 4L", + "ServeRAID 4Mx", + "ServeRAID 4Lx", + "ServeRAID 5i", + "ServeRAID 5i", + "ServeRAID 6M", + "ServeRAID 6i" }; -/* Init State 0 means we're only looking for a device to provide us the BIOS Adapter Ordering Table */ -/* Init State 1 is when we are actually enumerating the devices. */ -static int InitState; -/* IF BIOS wants to tell us the enumeration order, it puts a table in NVRAM Page 5 */ -static uint8_t AdapterOrder[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - static struct notifier_block ips_notifier = { - ips_halt, NULL, 0 + ips_halt, NULL, 0 }; /* * Direction table */ static char ips_command_direction[] = { -IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, -IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, -IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT, -IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_OUT, -IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT, -IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_IN, -IPS_DATA_UNK, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_UNK, -IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, -IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, -IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, -IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, -IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_NONE, -IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, -IPS_DATA_NONE, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_NONE, -IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_OUT, -IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_NONE, -IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_OUT, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK + IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, + IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, + IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT, + IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_OUT, + IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT, + IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_IN, + IPS_DATA_UNK, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_UNK, + IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, + IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, + IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, + IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, + IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_NONE, + IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, + IPS_DATA_NONE, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_NONE, + IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_OUT, + IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_NONE, + IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_OUT, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK }; /* @@ -480,9 +370,9 @@ int ips_release(struct Scsi_Host *); int ips_eh_abort(Scsi_Cmnd *); int ips_eh_reset(Scsi_Cmnd *); -int ips_queue(Scsi_Cmnd *, void (*) (Scsi_Cmnd *)); +int ips_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); int ips_biosparam(Disk *, kdev_t, int *); -const char * ips_info(struct Scsi_Host *); +const char *ips_info(struct Scsi_Host *); void do_ipsintr(int, void *, struct pt_regs *); static int ips_hainit(ips_ha_t *); static int ips_map_status(ips_ha_t *, ips_scb_t *, ips_stat_t *); @@ -527,10 +417,9 @@ static int ips_flash_copperhead(ips_ha_t *, ips_passthru_t *, ips_scb_t *); static int ips_flash_bios(ips_ha_t *, ips_passthru_t *, ips_scb_t *); static int ips_flash_firmware(ips_ha_t *, ips_passthru_t *, ips_scb_t *); -static void ips_free_flash_copperhead(ips_ha_t *ha); +static void ips_free_flash_copperhead(ips_ha_t * ha); static void ips_get_bios_version(ips_ha_t *, int); static void ips_identify_controller(ips_ha_t *); -static void ips_select_queue_depth(struct Scsi_Host *, Scsi_Device *); static void ips_chkstatus(ips_ha_t *, IPS_STATUS *); static void ips_enable_int_copperhead(ips_ha_t *); static void ips_enable_int_copperhead_memio(ips_ha_t *); @@ -553,40 +442,42 @@ static uint32_t ips_statupd_copperhead(ips_ha_t *); static uint32_t ips_statupd_copperhead_memio(ips_ha_t *); static uint32_t ips_statupd_morpheus(ips_ha_t *); -static ips_scb_t * ips_getscb(ips_ha_t *); +static ips_scb_t *ips_getscb(ips_ha_t *); static inline void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *); static inline void ips_putq_scb_tail(ips_scb_queue_t *, ips_scb_t *); static inline void ips_putq_wait_head(ips_wait_queue_t *, Scsi_Cmnd *); static inline void ips_putq_wait_tail(ips_wait_queue_t *, Scsi_Cmnd *); -static inline void ips_putq_copp_head(ips_copp_queue_t *, ips_copp_wait_item_t *); -static inline void ips_putq_copp_tail(ips_copp_queue_t *, ips_copp_wait_item_t *); -static inline ips_scb_t * ips_removeq_scb_head(ips_scb_queue_t *); -static inline ips_scb_t * ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *); -static inline Scsi_Cmnd * ips_removeq_wait_head(ips_wait_queue_t *); -static inline Scsi_Cmnd * ips_removeq_wait(ips_wait_queue_t *, Scsi_Cmnd *); -static inline ips_copp_wait_item_t * ips_removeq_copp(ips_copp_queue_t *, ips_copp_wait_item_t *); -static inline ips_copp_wait_item_t * ips_removeq_copp_head(ips_copp_queue_t *); +static inline void ips_putq_copp_head(ips_copp_queue_t *, + ips_copp_wait_item_t *); +static inline void ips_putq_copp_tail(ips_copp_queue_t *, + ips_copp_wait_item_t *); +static inline ips_scb_t *ips_removeq_scb_head(ips_scb_queue_t *); +static inline ips_scb_t *ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *); +static inline Scsi_Cmnd *ips_removeq_wait_head(ips_wait_queue_t *); +static inline Scsi_Cmnd *ips_removeq_wait(ips_wait_queue_t *, Scsi_Cmnd *); +static inline ips_copp_wait_item_t *ips_removeq_copp(ips_copp_queue_t *, + ips_copp_wait_item_t *); +static inline ips_copp_wait_item_t *ips_removeq_copp_head(ips_copp_queue_t *); static int ips_is_passthru(Scsi_Cmnd *); static int ips_make_passthru(ips_ha_t *, Scsi_Cmnd *, ips_scb_t *, int); static int ips_usrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *); static void ips_cleanup_passthru(ips_ha_t *, ips_scb_t *); +static void ips_scmd_buf_write(Scsi_Cmnd * scmd, void *data, + unsigned int count); +static void ips_scmd_buf_read(Scsi_Cmnd * scmd, void *data, unsigned int count); -int ips_proc_info(char *, char **, off_t, int, int, int); +int ips_proc_info(char *, char **, off_t, int, int, int); static int ips_host_info(ips_ha_t *, char *, off_t, int); static void copy_mem_info(IPS_INFOSTR *, char *, int); static int copy_info(IPS_INFOSTR *, char *, ...); -static int ips_get_version_info(ips_ha_t *ha, IPS_VERSION_DATA *Buffer, int intr ); -static void ips_version_check(ips_ha_t *ha, int intr); -static int ips_abort_init(ips_ha_t *ha, struct Scsi_Host *sh, int index); -static int ips_init_phase2( int index ); - -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) -static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ); -#else -static int ips_init_oldphase1(Scsi_Host_Template *SHT); -#endif +static int ips_get_version_info(ips_ha_t * ha, dma_addr_t, int intr); +static void ips_version_check(ips_ha_t * ha, int intr); +static int ips_abort_init(ips_ha_t * ha, int index); +static int ips_init_phase2(int index); +static int ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr); +static int ips_register_scsi(int index); /*--------------------------------------------------------------------------*/ /* Exported Functions */ /*--------------------------------------------------------------------------*/ @@ -600,92 +491,52 @@ /* setup parameters to the driver */ /* */ /****************************************************************************/ -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) static int -ips_setup(char *ips_str) { -#else -void -ips_setup(char *ips_str, int *dummy) { -#endif - - int i; - char *key; - char *value; - IPS_OPTION options[] = { - {"noi2o", &ips_force_i2o, 0}, - {"nommap", &ips_force_memio, 0}, - {"ioctlsize", &ips_ioctlsize, IPS_IOCTL_SIZE}, - {"cdboot", &ips_cd_boot, 0}, - {"maxcmds", &MaxLiteCmds, 32}, - }; - - /* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */ -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) - /* Search for value */ - while ((key = strsep(&ips_str, ",."))) { - if (!*key) - continue; - value = strchr(key, ':'); - if (value) - *value++ = '\0'; - /* - * We now have key/value pairs. - * Update the variables - */ - for (i = 0; i < (sizeof(options) / sizeof(options[0])); i++) { - if (strnicmp(key, options[i].option_name, strlen(options[i].option_name)) == 0) { - if (value) - *options[i].option_flag = simple_strtoul(value, NULL, 0); - else - *options[i].option_flag = options[i].option_value; - break; - } - } - } - - return (1); - -#else - - char *p; - char tokens[3] = {',', '.', 0}; - - for (key = strtok(ips_str, tokens); key; key = strtok(NULL, tokens)) { - p = key; - - /* Search for value */ - while ((p) && (*p != ':')) - p++; - - if (p) { - *p = '\0'; - value = p+1; - } else - value = NULL; - - /* - * We now have key/value pairs. - * Update the variables - */ - for (i = 0; i < (sizeof(options) / sizeof(options[0])); i++) { - if (strnicmp(key, options[i].option_name, strlen(ips_str)) == 0) { - if (value) - *options[i].option_flag = simple_strtoul(value, NULL, 0); - else - *options[i].option_flag = options[i].option_value; - - break; - } - } - } +ips_setup(char *ips_str) +{ -#endif + int i; + char *key; + char *value; + IPS_OPTION options[] = { + {"noi2o", &ips_force_i2o, 0}, + {"nommap", &ips_force_memio, 0}, + {"ioctlsize", &ips_ioctlsize, IPS_IOCTL_SIZE}, + {"cdboot", &ips_cd_boot, 0}, + {"maxcmds", &MaxLiteCmds, 32}, + }; + + /* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */ + /* Search for value */ + while ((key = strsep(&ips_str, ",."))) { + if (!*key) + continue; + value = strchr(key, ':'); + if (value) + *value++ = '\0'; + /* + * We now have key/value pairs. + * Update the variables + */ + for (i = 0; i < (sizeof (options) / sizeof (options[0])); i++) { + if (strnicmp + (key, options[i].option_name, + strlen(options[i].option_name)) == 0) { + if (value) + *options[i].option_flag = + simple_strtoul(value, NULL, 0); + else + *options[i].option_flag = + options[i].option_value; + break; + } + } + } + return (1); } -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) __setup("ips=", ips_setup); -#endif /****************************************************************************/ /* */ @@ -699,682 +550,86 @@ /* */ /****************************************************************************/ int -ips_detect(Scsi_Host_Template *SHT) { -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) - int i; -#endif +ips_detect(Scsi_Host_Template * SHT) +{ + int i; - METHOD_TRACE("ips_detect", 1); + METHOD_TRACE("ips_detect", 1); #ifdef MODULE - if (ips) -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) - ips_setup(ips); -#else - ips_setup(ips, NULL); -#endif + if (ips) + ips_setup(ips); #endif - /* If Booting from the Manager CD, Allocate a large Flash */ - /* Buffer ( so we won't need to allocate one for each adapter ). */ - if ( ips_cd_boot ) { - ips_FlashData = ( char * ) __get_free_pages( GFP_KERNEL, 7 ); - if (ips_FlashData == NULL) { - /* The validity of this pointer is checked in ips_make_passthru() before it is used */ - printk( KERN_WARNING "ERROR: Can't Allocate Large Buffer for Flashing\n" ); - } - } - /* initalize number of controllers */ - ips_num_controllers = 0; - ips_next_controller = 0; - ips_released_controllers = 0; - - if (!pci_present()) - return (0); - -/**********************************************************************************/ -/* For Kernel Versions 2.4 or greater, use new PCI ( Hot Pluggable ) architecture */ -/**********************************************************************************/ - -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) - #if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0) - spin_unlock_irq(&io_request_lock); - #endif - SHT->proc_info = ips_proc_info; - SHT->proc_name = "ips"; - - /* There are several special cases ( which are too complicated to enumerate here ) where, due */ - /* to System BIOS rules, the adapters must be enumerated in a certain order. If ServeRAID */ - /* BIOS tells us the order, then we will follow it. The first pass at init is simply to be */ - /* able to communicate with the first adapter to see if BIOS is telling us the order. */ - /* This does not apply to ia64 EFI BIOS. */ - -#if !defined(__ia64__) - InitState = 0; - pci_module_init(&ips_pci_driver); /* Look for Any Adapter, to fill in the Adapter Order Table */ -#endif - - InitState = 1; - - if ( AdapterOrder[0] ) { - /* BIOS has dictated the order that we should enumerate Adapters */ - for ( i = 1; i <= AdapterOrder[0]; i++ ) { - switch (AdapterOrder[i]) { - case 'M': - pci_module_init(&ips_pci_driver_adaptec); /* Ask for Adaptec Adapters */ - break; - case 'S': - pci_module_init(&ips_pci_driver_5i); /* Ask for 5i Adapters */ - pci_module_init(&ips_pci_driver_6i); /* Ask for 6i Adapters */ - break; - case 'N': - pci_module_init(&ips_pci_driver_i960); /* Ask for i960 Adapters */ - break; - case 'A': - pci_module_init(&ips_pci_driver_anaconda); /* Ask for Anaconda Family Adapters */ - break; - default: - i = AdapterOrder[0] + 1; /* Premature End of List - Ensure Loop Ends */ - break; - } - } - } - else { - /* No Adapter Order Table from BIOS, so sort things the old-fashioned way */ - - /* By definition, an Internal ( 5i or 6i ) Adapter MUST be enumerated first */ - /* or the server may not boot properly. The adapters must be enumerated in */ - /* exactly the same order as BIOS for the machine to come up properly. */ - /* NOTE: There will never be both a 5i and a 6i in the same machine. */ - - pci_module_init(&ips_pci_driver_5i); /* Ask for 5i Adapters First */ - if (ips_num_controllers) { /* If there is a 5i Adapter */ - pci_module_init(&ips_pci_driver_i960); /* Get all i960's next */ - } - else { - pci_module_init(&ips_pci_driver_6i); /* Ask if any 6i Adapters */ - if (ips_num_controllers) /* If there is a 6i Adapter */ - pci_module_init(&ips_pci_driver_adaptec); /* Get all Adaptecs next */ - } - - pci_module_init(&ips_pci_driver); /* Get all remaining Adapters */ - /* ( in normal BUS order ) */ - } - - #if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0) - spin_lock_irq(&io_request_lock); - #endif - if (ips_num_controllers > 0) - register_reboot_notifier(&ips_notifier); + SHT->proc_info = ips_proc_info; + SHT->proc_name = "ips"; - return (ips_num_controllers); -#else - InitState = 1; - SHT->proc_info = ips_proc_info; - SHT->proc_dir = &proc_scsi_ips; - return ips_init_oldphase1(SHT); -#endif /* LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) */ - -} - -#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) - -/***********************************************************************************/ -/* Sort the Device Structures */ -/* Devices are sorted by groups ( type ) and then PCI address within each group */ -/* This also results in the same ordering that results when using the 2.4 kernel */ -/* architecture for initialization. */ -/***********************************************************************************/ - -static void -ips_sort_controllers(struct pci_dev *dev[]) { - struct pci_dev *tempdev[IPS_MAX_ADAPTERS]; - struct pci_dev *lowestdev; - int i, j; - int temp_index = 0; /* Index into tempdev[] array */ - int lowIndex = 0; - int newlowflag = 0; /* Flag to indicate when a new low address has been found */ - uint16_t subdevice_id; - unsigned char BusNumber; - - /* Clear the Temporary Dev Structure */ - for (i = 0; i < IPS_MAX_ADAPTERS; i++) - tempdev[i] = NULL; - - /* The Outer Loop goes thru each Adapter Type Supported */ - for (j = 0; j < IPS_MAX_ADAPTER_TYPES; j++) { - lowestdev = NULL; - /* The Inner Loop Checks each Device still in the List and */ - /* Finds the lowset adapter left ( by PCI boot order ) */ - for (i = 0; i < IPS_MAX_ADAPTERS; i++) { - if (dev[i]) { - if (lowestdev == NULL) { /* If this is the first one found, it must be the lowest ! */ - lowestdev = dev[i]; - lowIndex = i; - } - - /* If you find a Sarasota ( 5i ), it must always be treated as the first adapter */ - if (dev[i]->device == IPS_DEVICEID_MORPHEUS) { - pci_read_config_word(dev[i], PCI_SUBSYSTEM_ID, &subdevice_id); - if ((subdevice_id == IPS_SUBDEVICEID_5I1) || - (subdevice_id == IPS_SUBDEVICEID_5I2)) { - lowestdev = dev[i]; - lowIndex = i; - break; - } - } - - /* If you find a Sebring ( 6i ), it must always be treated as the first adapter */ - if (dev[i]->device == IPS_DEVICEID_MARCO) { - pci_read_config_word(dev[i], PCI_SUBSYSTEM_ID, &subdevice_id); - if (subdevice_id == IPS_SUBDEVICEID_6I) { - lowestdev = dev[i]; - lowIndex = i; - break; - } - } - - /* Determine if this device is at a lower PCI address than the current lowest device */ - newlowflag = 0; - - if (dev[i]->device == IPS_DEVICEID_MARCO) /* System BIOS adds 1 to Marco Bus Number */ - BusNumber = ( dev[i]->bus->number ) - 1; /* because of Bridge Chip */ - else - BusNumber = dev[i]->bus->number; - - if (BusNumber < lowestdev->bus->number) /* IF a lower BUS # */ - newlowflag = i; - - if ((BusNumber == lowestdev->bus->number) && /* If Same Bus #, but a lower device # */ - (dev[i]->devfn < lowestdev->devfn)) - newlowflag = i; - - if ( newlowflag ) { - lowestdev = dev[i]; - lowIndex = i; - } - } - } - - if (lowestdev) { /* If we found another adapter */ - tempdev[temp_index] = lowestdev; /* Add it in the list */ - dev[lowIndex] = NULL; /* Null it out so we don't find it again */ - temp_index++; - /* Now get all the adapters that are the same type as the low one . */ - /* They will already be in order, so they don't need any further sorting.*/ - for (i = 0; i < IPS_MAX_ADAPTERS; i++) { - if (dev[i]) { - if (dev[i]->device == lowestdev->device) { - tempdev[temp_index] = dev[i]; /* Add the same type adapter to the list */ - temp_index++; - dev[i] = NULL; /* Null it out so we don't find it again */ - } - } - } - } - } - - /* Copy the Sorted Adapter Pointers ( tempdev[] ) to the Original Structure */ - for (i = 0; i < IPS_MAX_ADAPTERS; i++) - dev[i] = tempdev[i]; + for (i = 0; i < ips_num_controllers; i++) { + if (ips_register_scsi(i)) + ips_free(ips_ha[i]); + ips_released_controllers++; + } + return (ips_num_controllers); } /****************************************************************************/ -/* Detect and initialize the driver for 2.2 kernels */ -/* */ -/* NOTE: this routine is called under the io_request_lock spinlock */ -/****************************************************************************/ -static int ips_init_oldphase1(Scsi_Host_Template *SHT){ - struct Scsi_Host *sh; - ips_ha_t *ha; - uint32_t io_addr; - uint32_t mem_addr; - uint32_t io_len; - uint32_t mem_len; - uint16_t planer; - uint8_t revision_id; - uint8_t bus; - uint8_t func; - uint8_t irq; - uint16_t subdevice_id; - int i; - int j; - uint32_t count; - char *ioremap_ptr; - char *mem_ptr; - struct pci_dev *dev[IPS_MAX_ADAPTERS]; - dma_addr_t dma_address; - uint32_t currbar; - uint32_t maskbar; - uint8_t barnum; - uint32_t IsDead; - - METHOD_TRACE("ips_init_oldphase1", 1); - - for ( i = 0; i < IPS_MAX_ADAPTERS; i++ ) - dev[i] = NULL; - - /* Find all the adapters that we support and save them in the dev[] structure */ - i = 0; - dev[i] = pci_find_device(IPS_VENDORID_IBM, IPS_DEVICEID_MORPHEUS, NULL); - while ( dev[i] ) { - i++; - dev[i] = pci_find_device(IPS_VENDORID_IBM, IPS_DEVICEID_MORPHEUS, dev[i-1]); - } - - dev[i] = pci_find_device(IPS_VENDORID_IBM, IPS_DEVICEID_COPPERHEAD, NULL); - while ( dev[i] ) { - i++; - dev[i] = pci_find_device(IPS_VENDORID_IBM, IPS_DEVICEID_COPPERHEAD, dev[i-1]); - } - - dev[i] = pci_find_device(IPS_VENDORID_ADAPTEC, IPS_DEVICEID_MARCO, NULL); - while ( dev[i] ) { - i++; - dev[i] = pci_find_device(IPS_VENDORID_IBM, IPS_DEVICEID_MARCO, dev[i-1]); - } - - /* Sort the Adapters */ - if ( dev[0] ) - ips_sort_controllers( dev ); - else - return (0); - - /* Now scan and Initialize the controllers */ - for ( i = 0; i < IPS_MAX_ADAPTERS; i++ ) { - if (!dev[i]) - break; - - if (ips_next_controller >= IPS_MAX_ADAPTERS) - break; - - /* stuff that we get in dev */ - irq = dev[i]->irq; - bus = dev[i]->bus->number; - func = dev[i]->devfn; - - /* Init MEM/IO addresses to 0 */ - mem_addr = 0; - io_addr = 0; - mem_len = 0; - io_len = 0; - - for (j = 0; j < 2; j++) { - if (!dev[i]->base_address[j]) - break; - - if ((dev[i]->base_address[j] & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) { - barnum = PCI_BASE_ADDRESS_0 + (j * 4); - io_addr = dev[i]->base_address[j] & PCI_BASE_ADDRESS_IO_MASK; - - /* Get Size */ - pci_read_config_dword(dev[i], barnum, &currbar); - pci_write_config_dword(dev[i], barnum, ~0); - pci_read_config_dword(dev[i], barnum, &maskbar); - pci_write_config_dword(dev[i], barnum, currbar); - - io_len = ~(maskbar & PCI_BASE_ADDRESS_IO_MASK) + 1; - } else { - barnum = PCI_BASE_ADDRESS_0 + (j * 4); - mem_addr = dev[i]->base_address[j] & PCI_BASE_ADDRESS_MEM_MASK; - - /* Get Size */ - pci_read_config_dword(dev[i], barnum, &currbar); - pci_write_config_dword(dev[i], barnum, ~0); - pci_read_config_dword(dev[i], barnum, &maskbar); - pci_write_config_dword(dev[i], barnum, currbar); - - mem_len = ~(maskbar & PCI_BASE_ADDRESS_MEM_MASK) + 1; - } - } - - /* setup memory mapped area (if applicable) */ - if (mem_addr) { - uint32_t base; - uint32_t offs; - - DEBUG_VAR(1, "(%s%d) detect, Memory region %x, size: %d", - ips_name, ips_next_controller, mem_addr, mem_len); - - base = mem_addr & PAGE_MASK; - offs = mem_addr - base; - - ioremap_ptr = ioremap(base, PAGE_SIZE); - mem_ptr = ioremap_ptr + offs; - } else { - ioremap_ptr = NULL; - mem_ptr = NULL; - } - - /* setup I/O mapped area (if applicable) */ - if (io_addr) { - DEBUG_VAR(1, "(%s%d) detect, IO region %x, size: %d", - ips_name, ips_next_controller, io_addr, io_len); - - if (check_region(io_addr, io_len)) { - /* Couldn't allocate io space */ - printk(KERN_WARNING "(%s%d) couldn't allocate IO space %x len %d.\n", - ips_name, ips_next_controller, io_addr, io_len); - - ips_next_controller++; - - continue; - } - - request_region(io_addr, io_len, "ips"); - } - - /* get planer status */ - if (pci_read_config_word(dev[i], 0x04, &planer)) { - printk(KERN_WARNING "(%s%d) can't get planer status.\n", - ips_name, ips_next_controller); - - ips_next_controller++; - - continue; - } - - /* check to see if an onboard planer controller is disabled */ - if (!(planer & 0x000C)) { - - DEBUG_VAR(1, "(%s%d) detect, Onboard controller disabled by BIOS", - ips_name, ips_next_controller); - - ips_next_controller++; - - continue; - } - - DEBUG_VAR(1, "(%s%d) detect bus %d, func %x, irq %d, io %x, mem: %x, ptr: %p", - ips_name, ips_next_controller, bus, func, irq, io_addr, mem_addr, mem_ptr); - - /* get the revision ID */ - if (pci_read_config_byte(dev[i], PCI_REVISION_ID, &revision_id)) { - printk(KERN_WARNING "(%s%d) can't get revision id.\n", - ips_name, ips_next_controller); - - ips_next_controller++; - continue; - } - - /* get the subdevice id */ - if (pci_read_config_word(dev[i], PCI_SUBSYSTEM_ID, &subdevice_id)) { - printk(KERN_WARNING "(%s%d) can't get subdevice id.\n", - ips_name, ips_next_controller); - - ips_next_controller++; - - continue; - } - - /* found a controller */ - sh = scsi_register(SHT, sizeof(ips_ha_t)); - - if (sh == NULL) { - printk(KERN_WARNING "(%s%d) Unable to register controller with SCSI subsystem - skipping controller\n", - ips_name, ips_next_controller); - - ips_next_controller++; - - continue; - } - - ha = IPS_HA(sh); - memset(ha, 0, sizeof(ips_ha_t)); - - ips_sh[ips_next_controller] = sh; - ips_ha[ips_next_controller] = ha; - ips_num_controllers++; - ha->active = 1; - - ha->enq = kmalloc(sizeof(IPS_ENQ), GFP_KERNEL); - - if (!ha->enq) { - printk(KERN_WARNING "(%s%d) Unable to allocate host inquiry structure - skipping contoller\n", - ips_name, ips_next_controller); - ips_abort_init(ha, sh, ips_next_controller); - ips_next_controller++; - ips_num_controllers--; - - continue; - } - - ha->adapt = pci_alloc_consistent(dev[i], sizeof(IPS_ADAPTER) + sizeof(IPS_IO_CMD), &dma_address); - - if (!ha->adapt) { - printk(KERN_WARNING "(%s%d) Unable to allocate host adapt and dummy structure - skipping controller\n", - ips_name, ips_next_controller); - ips_abort_init(ha, sh, ips_next_controller); - ips_next_controller++; - ips_num_controllers--; - - continue; - } - ha->adapt->hw_status_start = dma_address; - ha->dummy = (void *)ha->adapt + 1; - - ha->conf = kmalloc(sizeof(IPS_CONF), GFP_KERNEL); - - if (!ha->conf) { - printk(KERN_WARNING "(%s%d) Unable to allocate host conf structure - skipping controller\n", - ips_name, ips_next_controller); - ips_abort_init(ha, sh, ips_next_controller); - ips_next_controller++; - ips_num_controllers--; - - continue; - } - - ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_KERNEL); - - if (!ha->nvram) { - printk(KERN_WARNING "(%s%d) Unable to allocate host nvram structure - skipping controller\n", - ips_name, ips_next_controller); - ips_abort_init(ha, sh, ips_next_controller); - ips_next_controller++; - ips_num_controllers--; - - continue; - } - - ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_KERNEL); - - if (!ha->subsys) { - printk(KERN_WARNING "(%s%d) Unable to allocate host subsystem structure - skipping controller\n", - ips_name, ips_next_controller); - ips_abort_init(ha, sh, ips_next_controller); - ips_next_controller++; - ips_num_controllers--; - - continue; - } - - for (count = PAGE_SIZE, ha->ioctl_order = 0; - count < ips_ioctlsize; - ha->ioctl_order++, count <<= 1); - - ha->ioctl_data = (char *) __get_free_pages(GFP_KERNEL, ha->ioctl_order); - ha->ioctl_datasize = count; - - if (!ha->ioctl_data) { - printk(KERN_WARNING "(%s%d) Unable to allocate ioctl data\n", - ips_name, ips_next_controller); - - ha->ioctl_data = NULL; - ha->ioctl_order = 0; - ha->ioctl_datasize = 0; - } - - /* Store away needed values for later use */ - sh->io_port = io_addr; - sh->n_io_port = io_addr ? 255 : 0; - sh->unique_id = (io_addr) ? io_addr : mem_addr; - sh->irq = irq; - sh->select_queue_depths = ips_select_queue_depth; - sh->sg_tablesize = sh->hostt->sg_tablesize; - sh->can_queue = sh->hostt->can_queue; - sh->cmd_per_lun = sh->hostt->cmd_per_lun; - sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma; - sh->use_clustering = sh->hostt->use_clustering; - - sh->wish_block = FALSE; - - /* Store info in HA structure */ - ha->irq = irq; - ha->io_addr = io_addr; - ha->io_len = io_len; - ha->mem_addr = mem_addr; - ha->mem_len = mem_len; - ha->mem_ptr = mem_ptr; - ha->ioremap_ptr = ioremap_ptr; - ha->host_num = ips_next_controller; - ha->revision_id = revision_id; - ha->slot_num = PCI_SLOT(dev[i]->devfn); - ha->device_id = dev[i]->device; - ha->subdevice_id = subdevice_id; - ha->pcidev = dev[i]; - - /* - * Setup Functions - */ - ips_setup_funclist(ha); - - /* If Morpheus appears dead, reset it */ - if ( ( IPS_IS_MORPHEUS( ha ) ) || ( IPS_IS_MARCO( ha ) ) ) { - IsDead = readl( ha->mem_ptr + IPS_REG_I960_MSG1 ); - if ( IsDead == 0xDEADBEEF ) { - ips_reset_morpheus( ha ); - } - } - - /* - * Initialize the card if it isn't already - */ - - if (!(*ha->func.isinit)(ha)) { - if (!(*ha->func.init)(ha)) { - /* - * Initialization failed - */ - printk(KERN_WARNING "(%s%d) unable to initialize controller - skipping controller\n", - ips_name, ips_next_controller); - ips_abort_init(ha, sh, ips_next_controller); - ips_next_controller++; - ips_num_controllers--; - - continue; - } - } - - /* install the interrupt handler */ - if (request_irq(irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) { - printk(KERN_WARNING "(%s%d) unable to install interrupt handler - skipping controller\n", - ips_name, ips_next_controller); - ips_abort_init(ha, sh, ips_next_controller); - ips_next_controller++; - ips_num_controllers--; - - continue; - } - - /* - * Allocate a temporary SCB for initialization - */ - ha->max_cmds = 1; - if (!ips_allocatescbs(ha)) { - /* couldn't allocate a temp SCB */ - printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n", - ips_name, ips_next_controller); - free_irq(ha->irq, ha); - ips_abort_init(ha, sh, ips_next_controller); - ips_next_controller++; - ips_num_controllers--; - - continue; - } - - ips_next_controller++; - } - - /* - * Do Phase 2 Initialization - * Controller init - */ - for (i = 0; i < ips_next_controller; i++) { - - if (ips_ha[i] == 0) { - printk(KERN_WARNING "(%s%d) ignoring bad controller\n", ips_name, i); - continue; - } - - if (ips_init_phase2(i) != SUCCESS) - ips_num_controllers--; - - } - - if (ips_num_controllers > 0) - register_reboot_notifier(&ips_notifier); - - return (ips_num_controllers); -} -#endif - -/****************************************************************************/ /* configure the function pointers to use the functions that will work */ /* with the found version of the adapter */ /****************************************************************************/ -static void ips_setup_funclist(ips_ha_t *ha){ +static void +ips_setup_funclist(ips_ha_t * ha) +{ - /* - * Setup Functions - */ - if (IPS_IS_MORPHEUS(ha) || IPS_IS_MARCO(ha)) { - /* morpheus / marco / sebring */ - ha->func.isintr = ips_isintr_morpheus; - ha->func.isinit = ips_isinit_morpheus; - ha->func.issue = ips_issue_i2o_memio; - ha->func.init = ips_init_morpheus; - ha->func.statupd = ips_statupd_morpheus; - ha->func.reset = ips_reset_morpheus; - ha->func.intr = ips_intr_morpheus; - ha->func.enableint = ips_enable_int_morpheus; - } else if (IPS_USE_MEMIO(ha)) { - /* copperhead w/MEMIO */ - ha->func.isintr = ips_isintr_copperhead_memio; - ha->func.isinit = ips_isinit_copperhead_memio; - ha->func.init = ips_init_copperhead_memio; - ha->func.statupd = ips_statupd_copperhead_memio; - ha->func.statinit = ips_statinit_memio; - ha->func.reset = ips_reset_copperhead_memio; - ha->func.intr = ips_intr_copperhead; - ha->func.erasebios = ips_erase_bios_memio; - ha->func.programbios = ips_program_bios_memio; - ha->func.verifybios = ips_verify_bios_memio; - ha->func.enableint = ips_enable_int_copperhead_memio; - if (IPS_USE_I2O_DELIVER(ha)) - ha->func.issue = ips_issue_i2o_memio; - else - ha->func.issue = ips_issue_copperhead_memio; - } else { - /* copperhead */ - ha->func.isintr = ips_isintr_copperhead; - ha->func.isinit = ips_isinit_copperhead; - ha->func.init = ips_init_copperhead; - ha->func.statupd = ips_statupd_copperhead; - ha->func.statinit = ips_statinit; - ha->func.reset = ips_reset_copperhead; - ha->func.intr = ips_intr_copperhead; - ha->func.erasebios = ips_erase_bios; - ha->func.programbios = ips_program_bios; - ha->func.verifybios = ips_verify_bios; - ha->func.enableint = ips_enable_int_copperhead; - - if (IPS_USE_I2O_DELIVER(ha)) - ha->func.issue = ips_issue_i2o; - else - ha->func.issue = ips_issue_copperhead; - } + /* + * Setup Functions + */ + if (IPS_IS_MORPHEUS(ha) || IPS_IS_MARCO(ha)) { + /* morpheus / marco / sebring */ + ha->func.isintr = ips_isintr_morpheus; + ha->func.isinit = ips_isinit_morpheus; + ha->func.issue = ips_issue_i2o_memio; + ha->func.init = ips_init_morpheus; + ha->func.statupd = ips_statupd_morpheus; + ha->func.reset = ips_reset_morpheus; + ha->func.intr = ips_intr_morpheus; + ha->func.enableint = ips_enable_int_morpheus; + } else if (IPS_USE_MEMIO(ha)) { + /* copperhead w/MEMIO */ + ha->func.isintr = ips_isintr_copperhead_memio; + ha->func.isinit = ips_isinit_copperhead_memio; + ha->func.init = ips_init_copperhead_memio; + ha->func.statupd = ips_statupd_copperhead_memio; + ha->func.statinit = ips_statinit_memio; + ha->func.reset = ips_reset_copperhead_memio; + ha->func.intr = ips_intr_copperhead; + ha->func.erasebios = ips_erase_bios_memio; + ha->func.programbios = ips_program_bios_memio; + ha->func.verifybios = ips_verify_bios_memio; + ha->func.enableint = ips_enable_int_copperhead_memio; + if (IPS_USE_I2O_DELIVER(ha)) + ha->func.issue = ips_issue_i2o_memio; + else + ha->func.issue = ips_issue_copperhead_memio; + } else { + /* copperhead */ + ha->func.isintr = ips_isintr_copperhead; + ha->func.isinit = ips_isinit_copperhead; + ha->func.init = ips_init_copperhead; + ha->func.statupd = ips_statupd_copperhead; + ha->func.statinit = ips_statinit; + ha->func.reset = ips_reset_copperhead; + ha->func.intr = ips_intr_copperhead; + ha->func.erasebios = ips_erase_bios; + ha->func.programbios = ips_program_bios; + ha->func.verifybios = ips_verify_bios; + ha->func.enableint = ips_enable_int_copperhead; + + if (IPS_USE_I2O_DELIVER(ha)) + ha->func.issue = ips_issue_i2o; + else + ha->func.issue = ips_issue_copperhead; + } } /****************************************************************************/ @@ -1387,79 +642,72 @@ /* */ /****************************************************************************/ int -ips_release(struct Scsi_Host *sh) { - ips_scb_t *scb; - ips_ha_t *ha; - int i; - - METHOD_TRACE("ips_release", 1); - - for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++); - - if (i == IPS_MAX_ADAPTERS) { - printk(KERN_WARNING "(%s) release, invalid Scsi_Host pointer.\n", - ips_name); -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) - BUG(); -#endif - return (FALSE); - } +ips_release(struct Scsi_Host *sh) +{ + ips_scb_t *scb; + ips_ha_t *ha; + int i; + + METHOD_TRACE("ips_release", 1); + + for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++) ; + + if (i == IPS_MAX_ADAPTERS) { + printk(KERN_WARNING + "(%s) release, invalid Scsi_Host pointer.\n", ips_name); + BUG(); + return (FALSE); + } - ha = IPS_HA(sh); + ha = IPS_HA(sh); - if (!ha) - return (FALSE); + if (!ha) + return (FALSE); - /* flush the cache on the controller */ - scb = &ha->scbs[ha->max_cmds-1]; + /* flush the cache on the controller */ + scb = &ha->scbs[ha->max_cmds - 1]; - ips_init_scb(ha, scb); + ips_init_scb(ha, scb); - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_FLUSH; + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_FLUSH; - scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH; - scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.flush_cache.state = IPS_NORM_STATE; - scb->cmd.flush_cache.reserved = 0; - scb->cmd.flush_cache.reserved2 = 0; - scb->cmd.flush_cache.reserved3 = 0; - scb->cmd.flush_cache.reserved4 = 0; + scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH; + scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.flush_cache.state = IPS_NORM_STATE; + scb->cmd.flush_cache.reserved = 0; + scb->cmd.flush_cache.reserved2 = 0; + scb->cmd.flush_cache.reserved3 = 0; + scb->cmd.flush_cache.reserved4 = 0; - if (InitState != 0) /* If Not just Searching for the Adapter Order Table */ - printk(KERN_NOTICE "(%s%d) Flushing Cache.\n", ips_name, ha->host_num); + printk(KERN_NOTICE "(%s%d) Flushing Cache.\n", ips_name, ha->host_num); - /* send command */ - if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE) - printk(KERN_NOTICE "(%s%d) Incomplete Flush.\n", ips_name, ha->host_num); + /* send command */ + if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE) + printk(KERN_NOTICE "(%s%d) Incomplete Flush.\n", ips_name, + ha->host_num); - if (InitState != 0) /* If Not just Searching for the Adapter Order Table */ - printk(KERN_NOTICE "(%s%d) Flushing Complete.\n", ips_name, ha->host_num); + printk(KERN_NOTICE "(%s%d) Flushing Complete.\n", ips_name, + ha->host_num); - ips_sh[i] = NULL; - ips_ha[i] = NULL; + ips_sh[i] = NULL; + ips_ha[i] = NULL; - /* free extra memory */ - ips_free(ha); + /* free extra memory */ + ips_free(ha); - /* Free I/O Region */ - if (ha->io_addr) - release_region(ha->io_addr, ha->io_len); + /* Free I/O Region */ + if (ha->io_addr) + release_region(ha->io_addr, ha->io_len); - /* free IRQ */ - free_irq(ha->irq, ha); + /* free IRQ */ + free_irq(ha->irq, ha); - scsi_unregister(sh); + scsi_unregister(sh); - if (InitState != 0) { - ips_released_controllers++; - if (ips_num_controllers == ips_released_controllers){ - unregister_reboot_notifier(&ips_notifier); - pci_unregister_driver(ha->pcidev->driver); - } - } + ips_released_controllers++; - return (FALSE); + return (FALSE); } /****************************************************************************/ @@ -1472,50 +720,54 @@ /* */ /****************************************************************************/ static int -ips_halt(struct notifier_block *nb, ulong event, void *buf) { - ips_scb_t *scb; - ips_ha_t *ha; - int i; - - if ((event != SYS_RESTART) && (event != SYS_HALT) && - (event != SYS_POWER_OFF)) - return (NOTIFY_DONE); - - for (i = 0; i < ips_next_controller; i++) { - ha = (ips_ha_t *) ips_ha[i]; - - if (!ha) - continue; - - if (!ha->active) - continue; - - /* flush the cache on the controller */ - scb = &ha->scbs[ha->max_cmds-1]; - - ips_init_scb(ha, scb); - - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_FLUSH; - - scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH; - scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.flush_cache.state = IPS_NORM_STATE; - scb->cmd.flush_cache.reserved = 0; - scb->cmd.flush_cache.reserved2 = 0; - scb->cmd.flush_cache.reserved3 = 0; - scb->cmd.flush_cache.reserved4 = 0; - - printk(KERN_NOTICE "(%s%d) Flushing Cache.\n", ips_name, ha->host_num); - - /* send command */ - if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE) - printk(KERN_NOTICE "(%s%d) Incomplete Flush.\n", ips_name, ha->host_num); - else - printk(KERN_NOTICE "(%s%d) Flushing Complete.\n", ips_name, ha->host_num); - } +ips_halt(struct notifier_block *nb, ulong event, void *buf) +{ + ips_scb_t *scb; + ips_ha_t *ha; + int i; + + if ((event != SYS_RESTART) && (event != SYS_HALT) && + (event != SYS_POWER_OFF)) return (NOTIFY_DONE); + + for (i = 0; i < ips_next_controller; i++) { + ha = (ips_ha_t *) ips_ha[i]; + + if (!ha) + continue; + + if (!ha->active) + continue; + + /* flush the cache on the controller */ + scb = &ha->scbs[ha->max_cmds - 1]; + + ips_init_scb(ha, scb); + + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_FLUSH; + + scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH; + scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.flush_cache.state = IPS_NORM_STATE; + scb->cmd.flush_cache.reserved = 0; + scb->cmd.flush_cache.reserved2 = 0; + scb->cmd.flush_cache.reserved3 = 0; + scb->cmd.flush_cache.reserved4 = 0; + + printk(KERN_NOTICE "(%s%d) Flushing Cache.\n", ips_name, + ha->host_num); + + /* send command */ + if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == + IPS_FAILURE) printk(KERN_NOTICE + "(%s%d) Incomplete Flush.\n", ips_name, + ha->host_num); + else + printk(KERN_NOTICE "(%s%d) Flushing Complete.\n", + ips_name, ha->host_num); + } - return (NOTIFY_OK); + return (NOTIFY_OK); } /****************************************************************************/ @@ -1528,50 +780,51 @@ /* Note: this routine is called under the io_request_lock */ /****************************************************************************/ int -ips_eh_abort(Scsi_Cmnd *SC) { - ips_ha_t *ha; - ips_copp_wait_item_t *item; - int ret; - - METHOD_TRACE("ips_eh_abort", 1); - - if (!SC) - return (FAILED); - - ha = (ips_ha_t *) SC->host->hostdata; - - if (!ha) - return (FAILED); - - if (!ha->active) - return (FAILED); - - if (SC->serial_number != SC->serial_number_at_timeout) { - /* HMM, looks like a bogus command */ - DEBUG(1, "Abort called with bogus scsi command"); - - return (FAILED); - } - - /* See if the command is on the copp queue */ - item = ha->copp_waitlist.head; - while ((item) && (item->scsi_cmd != SC)) - item = item->next; - - if (item) { - /* Found it */ - ips_removeq_copp(&ha->copp_waitlist, item); - ret = (SUCCESS); - - /* See if the command is on the wait queue */ - } else if (ips_removeq_wait(&ha->scb_waitlist, SC)) { - /* command not sent yet */ - ret = (SUCCESS); - } else { - /* command must have already been sent */ - ret = (FAILED); - } - return ret; +ips_eh_abort(Scsi_Cmnd * SC) +{ + ips_ha_t *ha; + ips_copp_wait_item_t *item; + int ret; + + METHOD_TRACE("ips_eh_abort", 1); + + if (!SC) + return (FAILED); + + ha = (ips_ha_t *) SC->host->hostdata; + + if (!ha) + return (FAILED); + + if (!ha->active) + return (FAILED); + + if (SC->serial_number != SC->serial_number_at_timeout) { + /* HMM, looks like a bogus command */ + DEBUG(1, "Abort called with bogus scsi command"); + + return (FAILED); + } + + /* See if the command is on the copp queue */ + item = ha->copp_waitlist.head; + while ((item) && (item->scsi_cmd != SC)) + item = item->next; + + if (item) { + /* Found it */ + ips_removeq_copp(&ha->copp_waitlist, item); + ret = (SUCCESS); + + /* See if the command is on the wait queue */ + } else if (ips_removeq_wait(&ha->scb_waitlist, SC)) { + /* command not sent yet */ + ret = (SUCCESS); + } else { + /* command must have already been sent */ + ret = (FAILED); + } + return ret; } /****************************************************************************/ @@ -1586,191 +839,194 @@ /* */ /****************************************************************************/ int -ips_eh_reset(Scsi_Cmnd *SC) { - int ret; - int i; - ips_ha_t *ha; - ips_scb_t *scb; - ips_copp_wait_item_t *item; +ips_eh_reset(Scsi_Cmnd * SC) +{ + int ret; + int i; + ips_ha_t *ha; + ips_scb_t *scb; + ips_copp_wait_item_t *item; - METHOD_TRACE("ips_eh_reset", 1); + METHOD_TRACE("ips_eh_reset", 1); #ifdef NO_IPS_RESET - return (FAILED); + return (FAILED); #else - if (!SC) { - DEBUG(1, "Reset called with NULL scsi command"); + if (!SC) { + DEBUG(1, "Reset called with NULL scsi command"); - return (FAILED); - } + return (FAILED); + } - ha = (ips_ha_t *) SC->host->hostdata; + ha = (ips_ha_t *) SC->host->hostdata; - if (!ha) { - DEBUG(1, "Reset called with NULL ha struct"); - - return (FAILED); - } - - if (!ha->active) - return (FAILED); - - /* See if the command is on the copp queue */ - item = ha->copp_waitlist.head; - while ((item) && (item->scsi_cmd != SC)) - item = item->next; - - if (item) { - /* Found it */ - ips_removeq_copp(&ha->copp_waitlist, item); - return (SUCCESS); - } - - /* See if the command is on the wait queue */ - if (ips_removeq_wait(&ha->scb_waitlist, SC)) { - /* command not sent yet */ - return (SUCCESS); - } - - /* An explanation for the casual observer: */ - /* Part of the function of a RAID controller is automatic error */ - /* detection and recovery. As such, the only problem that physically */ - /* resetting an adapter will ever fix is when, for some reason, */ - /* the driver is not successfully communicating with the adapter. */ - /* Therefore, we will attempt to flush this adapter. If that succeeds, */ - /* then there's no real purpose in a physical reset. This will complete */ - /* much faster and avoids any problems that might be caused by a */ - /* physical reset ( such as having to fail all the outstanding I/O's ). */ - - if (ha->ioctl_reset == 0) { /* IF Not an IOCTL Requested Reset */ - scb = &ha->scbs[ha->max_cmds-1]; - - ips_init_scb(ha, scb); - - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_FLUSH; - - scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH; - scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.flush_cache.state = IPS_NORM_STATE; - scb->cmd.flush_cache.reserved = 0; - scb->cmd.flush_cache.reserved2 = 0; - scb->cmd.flush_cache.reserved3 = 0; - scb->cmd.flush_cache.reserved4 = 0; - - /* Attempt the flush command */ - ret = ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_IORL); - if (ret == IPS_SUCCESS) { - printk(KERN_NOTICE "(%s%d) Reset Request - Flushed Cache\n", ips_name, ha->host_num); - return (SUCCESS); - } - } - - /* Either we can't communicate with the adapter or it's an IOCTL request */ - /* from a utility. A physical reset is needed at this point. */ - - ha->ioctl_reset = 0; /* Reset the IOCTL Requested Reset Flag */ - - /* - * command must have already been sent - * reset the controller - */ - printk(KERN_NOTICE "(%s%d) Resetting controller.\n", - ips_name, ha->host_num); - ret = (*ha->func.reset)(ha); - - if (!ret) { - Scsi_Cmnd *scsi_cmd; - - printk(KERN_NOTICE - "(%s%d) Controller reset failed - controller now offline.\n", - ips_name, ha->host_num); - - /* Now fail all of the active commands */ - DEBUG_VAR(1, "(%s%d) Failing active commands", - ips_name, ha->host_num); - - while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) { - scb->scsi_cmd->result = DID_ERROR << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); - ips_freescb(ha, scb); - } - - /* Now fail all of the pending commands */ - DEBUG_VAR(1, "(%s%d) Failing pending commands", - ips_name, ha->host_num); - - while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) { - scsi_cmd->result = DID_ERROR; - scsi_cmd->scsi_done(scsi_cmd); - } - - ha->active = FALSE; - return (FAILED); - } - - if (!ips_clear_adapter(ha, IPS_INTR_IORL)) { - Scsi_Cmnd *scsi_cmd; - - printk(KERN_NOTICE - "(%s%d) Controller reset failed - controller now offline.\n", - ips_name, ha->host_num); - - /* Now fail all of the active commands */ - DEBUG_VAR(1, "(%s%d) Failing active commands", - ips_name, ha->host_num); - - while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) { - scb->scsi_cmd->result = DID_ERROR << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); - ips_freescb(ha, scb); - } - - /* Now fail all of the pending commands */ - DEBUG_VAR(1, "(%s%d) Failing pending commands", - ips_name, ha->host_num); - - while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) { - scsi_cmd->result = DID_ERROR << 16; - scsi_cmd->scsi_done(scsi_cmd); - } - - ha->active = FALSE; - return (FAILED); - } - - /* FFDC */ - if (le32_to_cpu(ha->subsys->param[3]) & 0x300000) { - struct timeval tv; - - do_gettimeofday(&tv); - ha->last_ffdc = tv.tv_sec; - ha->reset_count++; - ips_ffdc_reset(ha, IPS_INTR_IORL); - } - - /* Now fail all of the active commands */ - DEBUG_VAR(1, "(%s%d) Failing active commands", - ips_name, ha->host_num); - - while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) { - scb->scsi_cmd->result = (DID_RESET << 16) | (SUGGEST_RETRY << 24); - scb->scsi_cmd->scsi_done(scb->scsi_cmd); - ips_freescb(ha, scb); - } - - /* Reset DCDB active command bits */ - for (i = 1; i < ha->nbus; i++) - ha->dcdb_active[i-1] = 0; + if (!ha) { + DEBUG(1, "Reset called with NULL ha struct"); + + return (FAILED); + } + + if (!ha->active) + return (FAILED); + + /* See if the command is on the copp queue */ + item = ha->copp_waitlist.head; + while ((item) && (item->scsi_cmd != SC)) + item = item->next; + + if (item) { + /* Found it */ + ips_removeq_copp(&ha->copp_waitlist, item); + return (SUCCESS); + } + + /* See if the command is on the wait queue */ + if (ips_removeq_wait(&ha->scb_waitlist, SC)) { + /* command not sent yet */ + return (SUCCESS); + } + + /* An explanation for the casual observer: */ + /* Part of the function of a RAID controller is automatic error */ + /* detection and recovery. As such, the only problem that physically */ + /* resetting an adapter will ever fix is when, for some reason, */ + /* the driver is not successfully communicating with the adapter. */ + /* Therefore, we will attempt to flush this adapter. If that succeeds, */ + /* then there's no real purpose in a physical reset. This will complete */ + /* much faster and avoids any problems that might be caused by a */ + /* physical reset ( such as having to fail all the outstanding I/O's ). */ + + if (ha->ioctl_reset == 0) { /* IF Not an IOCTL Requested Reset */ + scb = &ha->scbs[ha->max_cmds - 1]; + + ips_init_scb(ha, scb); + + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_FLUSH; + + scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH; + scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.flush_cache.state = IPS_NORM_STATE; + scb->cmd.flush_cache.reserved = 0; + scb->cmd.flush_cache.reserved2 = 0; + scb->cmd.flush_cache.reserved3 = 0; + scb->cmd.flush_cache.reserved4 = 0; + + /* Attempt the flush command */ + ret = ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_IORL); + if (ret == IPS_SUCCESS) { + printk(KERN_NOTICE + "(%s%d) Reset Request - Flushed Cache\n", + ips_name, ha->host_num); + return (SUCCESS); + } + } + + /* Either we can't communicate with the adapter or it's an IOCTL request */ + /* from a utility. A physical reset is needed at this point. */ + + ha->ioctl_reset = 0; /* Reset the IOCTL Requested Reset Flag */ + + /* + * command must have already been sent + * reset the controller + */ + printk(KERN_NOTICE "(%s%d) Resetting controller.\n", + ips_name, ha->host_num); + ret = (*ha->func.reset) (ha); + + if (!ret) { + Scsi_Cmnd *scsi_cmd; + + printk(KERN_NOTICE + "(%s%d) Controller reset failed - controller now offline.\n", + ips_name, ha->host_num); + + /* Now fail all of the active commands */ + DEBUG_VAR(1, "(%s%d) Failing active commands", + ips_name, ha->host_num); + + while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) { + scb->scsi_cmd->result = DID_ERROR << 16; + scb->scsi_cmd->scsi_done(scb->scsi_cmd); + ips_freescb(ha, scb); + } + + /* Now fail all of the pending commands */ + DEBUG_VAR(1, "(%s%d) Failing pending commands", + ips_name, ha->host_num); + + while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) { + scsi_cmd->result = DID_ERROR; + scsi_cmd->scsi_done(scsi_cmd); + } + + ha->active = FALSE; + return (FAILED); + } + + if (!ips_clear_adapter(ha, IPS_INTR_IORL)) { + Scsi_Cmnd *scsi_cmd; + + printk(KERN_NOTICE + "(%s%d) Controller reset failed - controller now offline.\n", + ips_name, ha->host_num); + + /* Now fail all of the active commands */ + DEBUG_VAR(1, "(%s%d) Failing active commands", + ips_name, ha->host_num); + + while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) { + scb->scsi_cmd->result = DID_ERROR << 16; + scb->scsi_cmd->scsi_done(scb->scsi_cmd); + ips_freescb(ha, scb); + } + + /* Now fail all of the pending commands */ + DEBUG_VAR(1, "(%s%d) Failing pending commands", + ips_name, ha->host_num); + + while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) { + scsi_cmd->result = DID_ERROR << 16; + scsi_cmd->scsi_done(scsi_cmd); + } + + ha->active = FALSE; + return (FAILED); + } + + /* FFDC */ + if (le32_to_cpu(ha->subsys->param[3]) & 0x300000) { + struct timeval tv; + + do_gettimeofday(&tv); + ha->last_ffdc = tv.tv_sec; + ha->reset_count++; + ips_ffdc_reset(ha, IPS_INTR_IORL); + } + + /* Now fail all of the active commands */ + DEBUG_VAR(1, "(%s%d) Failing active commands", ips_name, ha->host_num); + + while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) { + scb->scsi_cmd->result = + (DID_RESET << 16) | (SUGGEST_RETRY << 24); + scb->scsi_cmd->scsi_done(scb->scsi_cmd); + ips_freescb(ha, scb); + } + + /* Reset DCDB active command bits */ + for (i = 1; i < ha->nbus; i++) + ha->dcdb_active[i - 1] = 0; - /* Reset the number of active IOCTLs */ - ha->num_ioctl = 0; + /* Reset the number of active IOCTLs */ + ha->num_ioctl = 0; - ips_next(ha, IPS_INTR_IORL); + ips_next(ha, IPS_INTR_IORL); - return (SUCCESS); -#endif /* NO_IPS_RESET */ + return (SUCCESS); +#endif /* NO_IPS_RESET */ } @@ -1787,103 +1043,92 @@ /* */ /****************************************************************************/ int -ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) { - ips_ha_t *ha; - ips_passthru_t *pt; - - METHOD_TRACE("ips_queue", 1); - - ha = (ips_ha_t *) SC->host->hostdata; - - if (!ha) - return (1); - - if (!ha->active) - return (DID_ERROR); - - if (ips_is_passthru(SC)) { - if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) { - SC->result = DID_BUS_BUSY << 16; - done(SC); - - return (0); - } - } else if (ha->scb_waitlist.count == IPS_MAX_QUEUE) { - SC->result = DID_BUS_BUSY << 16; - done(SC); - - return (0); - } - - SC->scsi_done = done; - - DEBUG_VAR(2, "(%s%d): ips_queue: cmd 0x%X (%d %d %d)", - ips_name, - ha->host_num, - SC->cmnd[0], - SC->channel, - SC->target, - SC->lun); - - /* Check for command to initiator IDs */ - if ((SC->channel > 0) && (SC->target == ha->ha_id[SC->channel])) { - SC->result = DID_NO_CONNECT << 16; - done(SC); - - return (0); - } - - if (ips_is_passthru(SC)) { - - ips_copp_wait_item_t *scratch; - - /* A Reset IOCTL is only sent by the boot CD in extreme cases. */ - /* There can never be any system activity ( network or disk ), but check */ - /* anyway just as a good practice. */ - pt = (ips_passthru_t *) SC->request_buffer; - if ((pt->CoppCP.cmd.reset.op_code == IPS_CMD_RESET_CHANNEL) && - (pt->CoppCP.cmd.reset.adapter_flag == 1)) { - if (ha->scb_activelist.count != 0) { - SC->result = DID_BUS_BUSY << 16; - done(SC); - return (0); - } - ha->ioctl_reset = 1; /* This reset request is from an IOCTL */ - ips_eh_reset(SC); - SC->result = DID_OK << 16; - SC->scsi_done(SC); - return (0); - } - - /* allocate space for the scribble */ - scratch = kmalloc(sizeof(ips_copp_wait_item_t), GFP_ATOMIC); - - if (!scratch) { - SC->result = DID_ERROR << 16; - done(SC); - - return (0); - } - - scratch->scsi_cmd = SC; - scratch->next = NULL; - - ips_putq_copp_tail(&ha->copp_waitlist, scratch); - } - else { - ips_putq_wait_tail(&ha->scb_waitlist, SC); - } - - ips_next(ha, IPS_INTR_IORL); - - /* If We were using the CD Boot Flash Buffer, Restore the Old Values */ - if ( ips_FlashData == ha->ioctl_data ) { - ha->ioctl_data = ha->flash_data; - ha->ioctl_order = ha->flash_order; - ha->ioctl_datasize = ha->flash_datasize; - ips_FlashDataInUse = 0; - } - return (0); +ips_queue(Scsi_Cmnd * SC, void (*done) (Scsi_Cmnd *)) +{ + ips_ha_t *ha; + ips_passthru_t *pt; + + METHOD_TRACE("ips_queue", 1); + + ha = (ips_ha_t *) SC->host->hostdata; + + if (!ha) + return (1); + + if (!ha->active) + return (DID_ERROR); + + if (ips_is_passthru(SC)) { + if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) { + SC->result = DID_BUS_BUSY << 16; + done(SC); + + return (0); + } + } else if (ha->scb_waitlist.count == IPS_MAX_QUEUE) { + SC->result = DID_BUS_BUSY << 16; + done(SC); + + return (0); + } + + SC->scsi_done = done; + + DEBUG_VAR(2, "(%s%d): ips_queue: cmd 0x%X (%d %d %d)", + ips_name, + ha->host_num, SC->cmnd[0], SC->channel, SC->target, SC->lun); + + /* Check for command to initiator IDs */ + if ((SC->channel > 0) && (SC->target == ha->ha_id[SC->channel])) { + SC->result = DID_NO_CONNECT << 16; + done(SC); + + return (0); + } + + if (ips_is_passthru(SC)) { + + ips_copp_wait_item_t *scratch; + + /* A Reset IOCTL is only sent by the boot CD in extreme cases. */ + /* There can never be any system activity ( network or disk ), but check */ + /* anyway just as a good practice. */ + pt = (ips_passthru_t *) SC->request_buffer; + if ((pt->CoppCP.cmd.reset.op_code == IPS_CMD_RESET_CHANNEL) && + (pt->CoppCP.cmd.reset.adapter_flag == 1)) { + if (ha->scb_activelist.count != 0) { + SC->result = DID_BUS_BUSY << 16; + done(SC); + return (0); + } + ha->ioctl_reset = 1; /* This reset request is from an IOCTL */ + ips_eh_reset(SC); + SC->result = DID_OK << 16; + SC->scsi_done(SC); + return (0); + } + + /* allocate space for the scribble */ + scratch = kmalloc(sizeof (ips_copp_wait_item_t), GFP_ATOMIC); + + if (!scratch) { + SC->result = DID_ERROR << 16; + done(SC); + + return (0); + } + + scratch->scsi_cmd = SC; + scratch->next = NULL; + + ips_putq_copp_tail(&ha->copp_waitlist, scratch); + } else { + ips_putq_wait_tail(&ha->scb_waitlist, SC); + } + + ips_next(ha, IPS_INTR_IORL); + + return (0); } /****************************************************************************/ @@ -1896,48 +1141,49 @@ /* */ /****************************************************************************/ int -ips_biosparam(Disk *disk, kdev_t dev, int geom[]) { - ips_ha_t *ha; - int heads; - int sectors; - int cylinders; - - METHOD_TRACE("ips_biosparam", 1); - - ha = (ips_ha_t *) disk->device->host->hostdata; - - if (!ha) - /* ?!?! host adater info invalid */ - return (0); - - if (!ha->active) - return (0); - - if (!ips_read_adapter_status(ha, IPS_INTR_ON)) - /* ?!?! Enquiry command failed */ - return (0); - - if ((disk->capacity > 0x400000) && - ((ha->enq->ucMiscFlag & 0x8) == 0)) { - heads = IPS_NORM_HEADS; - sectors = IPS_NORM_SECTORS; - } else { - heads = IPS_COMP_HEADS; - sectors = IPS_COMP_SECTORS; - } - - cylinders = disk->capacity / (heads * sectors); - - DEBUG_VAR(2, "Geometry: heads: %d, sectors: %d, cylinders: %d", - heads, sectors, cylinders); - - geom[0] = heads; - geom[1] = sectors; - geom[2] = cylinders; +ips_biosparam(Disk * disk, kdev_t dev, int geom[]) +{ + ips_ha_t *ha; + int heads; + int sectors; + int cylinders; + + METHOD_TRACE("ips_biosparam", 1); + + ha = (ips_ha_t *) disk->device->host->hostdata; + + if (!ha) + /* ?!?! host adater info invalid */ + return (0); + + if (!ha->active) + return (0); - return (0); + if (!ips_read_adapter_status(ha, IPS_INTR_ON)) + /* ?!?! Enquiry command failed */ + return (0); + + if ((disk->capacity > 0x400000) && ((ha->enq->ucMiscFlag & 0x8) == 0)) { + heads = IPS_NORM_HEADS; + sectors = IPS_NORM_SECTORS; + } else { + heads = IPS_COMP_HEADS; + sectors = IPS_COMP_SECTORS; + } + + cylinders = disk->capacity / (heads * sectors); + + DEBUG_VAR(2, "Geometry: heads: %d, sectors: %d, cylinders: %d", + heads, sectors, cylinders); + + geom[0] = heads; + geom[1] = sectors; + geom[2] = cylinders; + + return (0); } +#if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0) /****************************************************************************/ /* */ /* Routine Name: ips_select_queue_depth */ @@ -1948,39 +1194,67 @@ /* */ /****************************************************************************/ static void -ips_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs) { - Scsi_Device *device; - ips_ha_t *ha; - int count = 0; - int min; - - ha = IPS_HA(host); - min = ha->max_cmds / 4; - - for (device = scsi_devs; device; device = device->next) { - if (device->host == host) { - if ((device->channel == 0) && (device->type == 0)) - count++; - } - } - - for (device = scsi_devs; device; device = device->next) { - if (device->host == host) { - if ((device->channel == 0) && (device->type == 0)) { - device->queue_depth = ( ha->max_cmds - 1 ) / count; - if (device->queue_depth < min) - device->queue_depth = min; - } - else { - device->queue_depth = 2; - } - - if (device->queue_depth < 2) - device->queue_depth = 2; - } - } +ips_select_queue_depth(struct Scsi_Host *host, Scsi_Device * scsi_devs) +{ + Scsi_Device *device; + ips_ha_t *ha; + int count = 0; + int min; + + ha = IPS_HA(host); + min = ha->max_cmds / 4; + + for (device = scsi_devs; device; device = device->next) { + if (device->host == host) { + if ((device->channel == 0) && (device->type == 0)) + count++; + } + } + + for (device = scsi_devs; device; device = device->next) { + if (device->host == host) { + if ((device->channel == 0) && (device->type == 0)) { + device->queue_depth = + (ha->max_cmds - 1) / count; + if (device->queue_depth < min) + device->queue_depth = min; + } else { + device->queue_depth = 2; + } + + if (device->queue_depth < 2) + device->queue_depth = 2; + } + } } +#else +/****************************************************************************/ +/* */ +/* Routine Name: ips_slave_configure */ +/* */ +/* Routine Description: */ +/* */ +/* Set queue depths on devices once scan is complete */ +/* */ +/****************************************************************************/ +int +ips_slave_configure(Scsi_Device * SDptr) +{ + ips_ha_t *ha; + int min; + + ha = IPS_HA(SDptr->host); + if (SDptr->tagged_supported && SDptr->type == TYPE_DISK) { + min = ha->max_cmds / 2; + if (ha->enq->ucLogDriveCount <= 2) + min = ha->max_cmds - 1; + scsi_adjust_queue_depth(SDptr, MSG_ORDERED_TAG, min); + } + return 0; +} +#endif + /****************************************************************************/ /* */ /* Routine Name: do_ipsintr */ @@ -1991,30 +1265,37 @@ /* */ /****************************************************************************/ void -do_ipsintr(int irq, void *dev_id, struct pt_regs *regs) { - ips_ha_t *ha; - unsigned long cpu_flags; - struct Scsi_Host *host; - - METHOD_TRACE("do_ipsintr", 2); - - ha = (ips_ha_t *) dev_id; - if (!ha) - return; - host = ips_sh[ha->host_num]; - IPS_LOCK_SAVE(host->host_lock, cpu_flags); - - if (!ha->active) { - IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); - return; - } +do_ipsintr(int irq, void *dev_id, struct pt_regs *regs) +{ + ips_ha_t *ha; + unsigned long cpu_flags; + struct Scsi_Host *host; + + METHOD_TRACE("do_ipsintr", 2); + + ha = (ips_ha_t *) dev_id; + if (!ha) + return; + host = ips_sh[ha->host_num]; + /* interrupt during initialization */ + if (!host) { + (*ha->func.intr) (ha); + return; + } + + IPS_LOCK_SAVE(host->host_lock, cpu_flags); + + if (!ha->active) { + IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); + return; + } - (*ha->func.intr)(ha); + (*ha->func.intr) (ha); - IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); + IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); - /* start the next command */ - ips_next(ha, IPS_INTR_ON); + /* start the next command */ + ips_next(ha, IPS_INTR_ON); } /****************************************************************************/ @@ -2029,54 +1310,55 @@ /* */ /****************************************************************************/ void -ips_intr_copperhead(ips_ha_t *ha) { - ips_stat_t *sp; - ips_scb_t *scb; - IPS_STATUS cstatus; - int intrstatus; - - METHOD_TRACE("ips_intr", 2); - - if (!ha) - return; - - if (!ha->active) - return; - - intrstatus = (*ha->func.isintr)(ha); - - if (!intrstatus) { - /* - * Unexpected/Shared interrupt - */ - - return; - } - - while (TRUE) { - sp = &ha->sp; - - intrstatus = (*ha->func.isintr)(ha); - - if (!intrstatus) - break; - else - cstatus.value = (*ha->func.statupd)(ha); - - if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) { - /* Spurious Interupt ? */ - continue; - } - - ips_chkstatus(ha, &cstatus); - scb = (ips_scb_t *) sp->scb_addr; - - /* - * use the callback function to finish things up - * NOTE: interrupts are OFF for this - */ - (*scb->callback) (ha, scb); - } /* end while */ +ips_intr_copperhead(ips_ha_t * ha) +{ + ips_stat_t *sp; + ips_scb_t *scb; + IPS_STATUS cstatus; + int intrstatus; + + METHOD_TRACE("ips_intr", 2); + + if (!ha) + return; + + if (!ha->active) + return; + + intrstatus = (*ha->func.isintr) (ha); + + if (!intrstatus) { + /* + * Unexpected/Shared interrupt + */ + + return; + } + + while (TRUE) { + sp = &ha->sp; + + intrstatus = (*ha->func.isintr) (ha); + + if (!intrstatus) + break; + else + cstatus.value = (*ha->func.statupd) (ha); + + if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) { + /* Spurious Interupt ? */ + continue; + } + + ips_chkstatus(ha, &cstatus); + scb = (ips_scb_t *) sp->scb_addr; + + /* + * use the callback function to finish things up + * NOTE: interrupts are OFF for this + */ + (*scb->callback) (ha, scb); + } /* end while */ } /****************************************************************************/ @@ -2091,60 +1373,62 @@ /* */ /****************************************************************************/ void -ips_intr_morpheus(ips_ha_t *ha) { - ips_stat_t *sp; - ips_scb_t *scb; - IPS_STATUS cstatus; - int intrstatus; +ips_intr_morpheus(ips_ha_t * ha) +{ + ips_stat_t *sp; + ips_scb_t *scb; + IPS_STATUS cstatus; + int intrstatus; - METHOD_TRACE("ips_intr_morpheus", 2); + METHOD_TRACE("ips_intr_morpheus", 2); - if (!ha) - return; + if (!ha) + return; - if (!ha->active) - return; + if (!ha->active) + return; - intrstatus = (*ha->func.isintr)(ha); + intrstatus = (*ha->func.isintr) (ha); - if (!intrstatus) { - /* - * Unexpected/Shared interrupt - */ + if (!intrstatus) { + /* + * Unexpected/Shared interrupt + */ - return; - } + return; + } - while (TRUE) { - sp = &ha->sp; + while (TRUE) { + sp = &ha->sp; - intrstatus = (*ha->func.isintr)(ha); + intrstatus = (*ha->func.isintr) (ha); - if (!intrstatus) - break; - else - cstatus.value = (*ha->func.statupd)(ha); + if (!intrstatus) + break; + else + cstatus.value = (*ha->func.statupd) (ha); - if (cstatus.value == 0xffffffff) - /* No more to process */ - break; + if (cstatus.value == 0xffffffff) + /* No more to process */ + break; - if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) { - printk(KERN_WARNING "(%s%d) Spurious interrupt; no ccb.\n", - ips_name, ha->host_num); + if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) { + printk(KERN_WARNING + "(%s%d) Spurious interrupt; no ccb.\n", ips_name, + ha->host_num); - continue; - } + continue; + } - ips_chkstatus(ha, &cstatus); - scb = (ips_scb_t *) sp->scb_addr; + ips_chkstatus(ha, &cstatus); + scb = (ips_scb_t *) sp->scb_addr; - /* - * use the callback function to finish things up - * NOTE: interrupts are OFF for this - */ - (*scb->callback) (ha, scb); - } /* end while */ + /* + * use the callback function to finish things up + * NOTE: interrupts are OFF for this + */ + (*scb->callback) (ha, scb); + } /* end while */ } /****************************************************************************/ @@ -2157,31 +1441,32 @@ /* */ /****************************************************************************/ const char * -ips_info(struct Scsi_Host *SH) { - static char buffer[256]; - char *bp; - ips_ha_t *ha; +ips_info(struct Scsi_Host *SH) +{ + static char buffer[256]; + char *bp; + ips_ha_t *ha; - METHOD_TRACE("ips_info", 1); + METHOD_TRACE("ips_info", 1); - ha = IPS_HA(SH); + ha = IPS_HA(SH); - if (!ha) - return (NULL); + if (!ha) + return (NULL); - bp = &buffer[0]; - memset(bp, 0, sizeof(buffer)); + bp = &buffer[0]; + memset(bp, 0, sizeof (buffer)); - sprintf(bp, "%s%s%s", "IBM PCI ServeRAID ", IPS_VERSION_HIGH, IPS_VERSION_LOW ); + sprintf(bp, "%s%s%s Build %d", "IBM PCI ServeRAID ", + IPS_VERSION_HIGH, IPS_VERSION_LOW, IPS_BUILD_IDENT); - if (ha->ad_type > 0 && - ha->ad_type <= MAX_ADAPTER_NAME) { - strcat(bp, " <"); - strcat(bp, ips_adapter_name[ha->ad_type-1]); - strcat(bp, ">"); - } + if (ha->ad_type > 0 && ha->ad_type <= MAX_ADAPTER_NAME) { + strcat(bp, " <"); + strcat(bp, ips_adapter_name[ha->ad_type - 1]); + strcat(bp, ">"); + } - return (bp); + return (bp); } /****************************************************************************/ @@ -2195,38 +1480,39 @@ /****************************************************************************/ int ips_proc_info(char *buffer, char **start, off_t offset, - int length, int hostno, int func) { - int i; - int ret; - ips_ha_t *ha = NULL; - - METHOD_TRACE("ips_proc_info", 1); - - /* Find our host structure */ - for (i = 0; i < ips_next_controller; i++) { - if (ips_sh[i]) { - if (ips_sh[i]->host_no == hostno) { - ha = (ips_ha_t *) ips_sh[i]->hostdata; - break; - } - } - } - - if (!ha) - return (-EINVAL); - - if (func) { - /* write */ - return (0); - } else { - /* read */ - if (start) - *start = buffer; + int length, int hostno, int func) +{ + int i; + int ret; + ips_ha_t *ha = NULL; + + METHOD_TRACE("ips_proc_info", 1); + + /* Find our host structure */ + for (i = 0; i < ips_next_controller; i++) { + if (ips_sh[i]) { + if (ips_sh[i]->host_no == hostno) { + ha = (ips_ha_t *) ips_sh[i]->hostdata; + break; + } + } + } + + if (!ha) + return (-EINVAL); + + if (func) { + /* write */ + return (0); + } else { + /* read */ + if (start) + *start = buffer; - ret = ips_host_info(ha, buffer, offset, length); + ret = ips_host_info(ha, buffer, offset, length); - return (ret); - } + return (ret); + } } /*--------------------------------------------------------------------------*/ @@ -2243,32 +1529,64 @@ /* */ /****************************************************************************/ static int -ips_is_passthru(Scsi_Cmnd *SC) { - METHOD_TRACE("ips_is_passthru", 1); +ips_is_passthru(Scsi_Cmnd * SC) +{ + METHOD_TRACE("ips_is_passthru", 1); - if (!SC) - return (0); + if (!SC) + return (0); - if ((SC->cmnd[0] == IPS_IOCTL_COMMAND) && - (SC->channel == 0) && - (SC->target == IPS_ADAPTER_ID) && - (SC->lun == 0) && - SC->request_buffer){ - if((!SC->use_sg) && SC->request_bufflen && - (((char *) SC->request_buffer)[0] == 'C') && - (((char *) SC->request_buffer)[1] == 'O') && - (((char *) SC->request_buffer)[2] == 'P') && - (((char *) SC->request_buffer)[3] == 'P')) - return 1; - else if(SC->use_sg){ - struct scatterlist *sg = SC->request_buffer; - char *buffer = IPS_SG_ADDRESS(sg); - if(buffer && buffer[0] == 'C' && buffer[1] == 'O' && - buffer[2] == 'P' && buffer[3] == 'P') - return 1; - } - } - return 0; + if ((SC->cmnd[0] == IPS_IOCTL_COMMAND) && + (SC->channel == 0) && + (SC->target == IPS_ADAPTER_ID) && + (SC->lun == 0) && SC->request_buffer) { + if ((!SC->use_sg) && SC->request_bufflen && + (((char *) SC->request_buffer)[0] == 'C') && + (((char *) SC->request_buffer)[1] == 'O') && + (((char *) SC->request_buffer)[2] == 'P') && + (((char *) SC->request_buffer)[3] == 'P')) + return 1; + else if (SC->use_sg) { + struct scatterlist *sg = SC->request_buffer; + char *buffer = IPS_SG_ADDRESS(sg); + if (buffer && buffer[0] == 'C' && buffer[1] == 'O' && + buffer[2] == 'P' && buffer[3] == 'P') + return 1; + } + } + return 0; +} + +/****************************************************************************/ +/* */ +/* Routine Name: ips_alloc_passthru_buffer */ +/* */ +/* Routine Description: */ +/* allocate a buffer large enough for the ioctl data if the ioctl buffer */ +/* is too small or doesn't exist */ +/****************************************************************************/ +static int +ips_alloc_passthru_buffer(ips_ha_t * ha, int length) +{ + void *bigger_buf; + dma_addr_t dma_busaddr; + + if (ha->ioctl_data && length <= ha->ioctl_len) + return 0; + /* there is no buffer or it's not big enough, allocate a new one */ + bigger_buf = pci_alloc_consistent(ha->pcidev, length, &dma_busaddr); + if (bigger_buf) { + /* free the old memory */ + pci_free_consistent(ha->pcidev, ha->ioctl_len, ha->ioctl_data, + ha->ioctl_busaddr); + /* use the new memory */ + ha->ioctl_data = (char *) bigger_buf; + ha->ioctl_len = length; + ha->ioctl_busaddr = dma_busaddr; + } else { + return -1; + } + return 0; } /****************************************************************************/ @@ -2281,127 +1599,96 @@ /* */ /****************************************************************************/ static int -ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) { - ips_passthru_t *pt; - char *buffer; - int length = 0; - - METHOD_TRACE("ips_make_passthru", 1); - - if(!SC->use_sg){ - buffer = SC->request_buffer; - length = SC->request_bufflen; - }else{ - struct scatterlist *sg = SC->request_buffer; - int i; - for(i = 0; i < SC->use_sg; i++) - length += sg[i].length; - - if (length < sizeof(ips_passthru_t)) { - /* wrong size */ - DEBUG_VAR(1, "(%s%d) Passthru structure wrong size", - ips_name, ha->host_num); - return (IPS_FAILURE); - }else if(!ha->ioctl_data || length > (PAGE_SIZE << ha->ioctl_order)){ - void *bigger_buf; - int count; - int order; - /* try to allocate a bigger buffer */ - for (count = PAGE_SIZE, order = 0; - count < length; - order++, count <<= 1); - bigger_buf = (void *) __get_free_pages(GFP_ATOMIC, order); - if (bigger_buf) { - /* free the old memory */ - free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order); - /* use the new memory */ - ha->ioctl_data = (char *) bigger_buf; - ha->ioctl_order = order; - ha->ioctl_datasize = count; - } else { - pt = (ips_passthru_t*)IPS_SG_ADDRESS(sg); - pt->BasicStatus = 0x0B; - pt->ExtendedStatus = 0x00; - SC->result = DID_ERROR << 16; - return (IPS_FAILURE); - } - } - ha->ioctl_datasize = length; - length = 0; - for(i = 0; i < SC->use_sg; i++){ - memcpy(&ha->ioctl_data[length], IPS_SG_ADDRESS(&sg[i]), sg[i].length); - length += sg[i].length; - } - pt = (ips_passthru_t *)ha->ioctl_data; - buffer = ha->ioctl_data; - } - if (!length || !buffer) { - /* no data */ - DEBUG_VAR(1, "(%s%d) No passthru structure", - ips_name, ha->host_num); - - return (IPS_FAILURE); - } - if (length < sizeof(ips_passthru_t)) { - /* wrong size */ - DEBUG_VAR(1, "(%s%d) Passthru structure wrong size", - ips_name, ha->host_num); - - return (IPS_FAILURE); - } - pt = (ips_passthru_t*) buffer; - /* - * Some notes about the passthru interface used - * - * IF the scsi op_code == 0x0d then we assume - * that the data came along with/goes with the - * packet we received from the sg driver. In this - * case the CmdBSize field of the pt structure is - * used for the size of the buffer. - */ - - switch (pt->CoppCmd) { - case IPS_NUMCTRLS: - memcpy(buffer + sizeof(ips_passthru_t), - &ips_num_controllers, sizeof(int)); - SC->result = DID_OK << 16; - - return (IPS_SUCCESS_IMM); - - case IPS_CTRLINFO: - memcpy(buffer + sizeof(ips_passthru_t), - ha, sizeof(ips_ha_t)); - SC->result = DID_OK << 16; - - return (IPS_SUCCESS_IMM); - - case IPS_COPPUSRCMD: - case IPS_COPPIOCCMD: - if (SC->cmnd[0] == IPS_IOCTL_COMMAND) { - if (length < (sizeof(ips_passthru_t) + pt->CmdBSize)) { - /* wrong size */ - DEBUG_VAR(1, "(%s%d) Passthru structure wrong size", - ips_name, ha->host_num); - - return (IPS_FAILURE); - } - - if(ha->device_id == IPS_DEVICEID_COPPERHEAD && - pt->CoppCP.cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW) - return ips_flash_copperhead(ha, pt, scb); - - if (ips_usrcmd(ha, pt, scb)) - return (IPS_SUCCESS); - else - return (IPS_FAILURE); - } - - break; +ips_make_passthru(ips_ha_t * ha, Scsi_Cmnd * SC, ips_scb_t * scb, int intr) +{ + ips_passthru_t *pt; + int length = 0; + int ret; + + METHOD_TRACE("ips_make_passthru", 1); + + if (!SC->use_sg) { + length = SC->request_bufflen; + } else { + struct scatterlist *sg = SC->request_buffer; + int i; + for (i = 0; i < SC->use_sg; i++) + length += sg[i].length; + } + if (length < sizeof (ips_passthru_t)) { + /* wrong size */ + DEBUG_VAR(1, "(%s%d) Passthru structure wrong size", + ips_name, ha->host_num); + return (IPS_FAILURE); + } + if (ips_alloc_passthru_buffer(ha, length)) { + /* allocation failure! If ha->ioctl_data exists, use it to return + some error codes. Return a failed command to the scsi layer. */ + if (ha->ioctl_data) { + pt = (ips_passthru_t *) ha->ioctl_data; + ips_scmd_buf_read(SC, pt, sizeof (ips_passthru_t)); + pt->BasicStatus = 0x0B; + pt->ExtendedStatus = 0x00; + ips_scmd_buf_write(SC, pt, sizeof (ips_passthru_t)); + } + return IPS_FAILURE; + } + ha->ioctl_datasize = length; + + ips_scmd_buf_read(SC, ha->ioctl_data, ha->ioctl_datasize); + pt = (ips_passthru_t *) ha->ioctl_data; + + /* + * Some notes about the passthru interface used + * + * IF the scsi op_code == 0x0d then we assume + * that the data came along with/goes with the + * packet we received from the sg driver. In this + * case the CmdBSize field of the pt structure is + * used for the size of the buffer. + */ + + switch (pt->CoppCmd) { + case IPS_NUMCTRLS: + memcpy(ha->ioctl_data + sizeof (ips_passthru_t), + &ips_num_controllers, sizeof (int)); + ips_scmd_buf_write(SC, ha->ioctl_data, + sizeof (ips_passthru_t) + sizeof (int)); + SC->result = DID_OK << 16; + + return (IPS_SUCCESS_IMM); + + case IPS_COPPUSRCMD: + case IPS_COPPIOCCMD: + if (SC->cmnd[0] == IPS_IOCTL_COMMAND) { + if (length < (sizeof (ips_passthru_t) + pt->CmdBSize)) { + /* wrong size */ + DEBUG_VAR(1, + "(%s%d) Passthru structure wrong size", + ips_name, ha->host_num); + + return (IPS_FAILURE); + } + + if (ha->device_id == IPS_DEVICEID_COPPERHEAD && + pt->CoppCP.cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW) { + ret = ips_flash_copperhead(ha, pt, scb); + ips_scmd_buf_write(SC, ha->ioctl_data, + sizeof (ips_passthru_t)); + return ret; + } + if (ips_usrcmd(ha, pt, scb)) + return (IPS_SUCCESS); + else + return (IPS_FAILURE); + } - } /* end switch */ + break; - return (IPS_FAILURE); - } + } /* end switch */ + + return (IPS_FAILURE); +} /****************************************************************************/ /* Routine Name: ips_flash_copperhead */ @@ -2409,62 +1696,69 @@ /* Flash the BIOS/FW on a Copperhead style controller */ /****************************************************************************/ static int -ips_flash_copperhead(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb){ - int datasize, count; +ips_flash_copperhead(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb) +{ + int datasize; - /* Trombone is the only copperhead that can do packet flash, but only - * for firmware. No one said it had to make sence. */ - if(IPS_IS_TROMBONE(ha) && pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE){ - if(ips_usrcmd(ha, pt, scb)) - return IPS_SUCCESS; - else - return IPS_FAILURE; - } - pt->BasicStatus = 0x0B; - pt->ExtendedStatus = 0; - scb->scsi_cmd->result = DID_OK <<16; - /* IF it's OK to Use the "CD BOOT" Flash Buffer, then you can */ - /* avoid allocating a huge buffer per adapter ( which can fail ). */ - if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE && - pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS){ - pt->BasicStatus = 0; - return ips_flash_bios(ha, pt, scb); - }else if(pt->CoppCP.cmd.flashfw.packet_num == 0){ - if(ips_FlashData && !test_and_set_bit(0, &ips_FlashDataInUse)){ - ha->flash_data = ips_FlashData; - ha->flash_order = 7; - ha->flash_datasize = 0; - }else if(!ha->flash_data){ - datasize = pt->CoppCP.cmd.flashfw.total_packets * - pt->CoppCP.cmd.flashfw.count; - for (count = PAGE_SIZE, ha->flash_order = 0; count < datasize; - ha->flash_order++, count <<= 1); - ha->flash_data = (char *)__get_free_pages(GFP_ATOMIC, ha->flash_order); - ha->flash_datasize = 0; - }else - return IPS_FAILURE; - }else{ - if(pt->CoppCP.cmd.flashfw.count + ha->flash_datasize > - (PAGE_SIZE << ha->flash_order)){ - ips_free_flash_copperhead(ha); - printk(KERN_WARNING "failed size sanity check\n"); - return IPS_FAILURE; - } - } - if(!ha->flash_data) - return IPS_FAILURE; - pt->BasicStatus = 0; - memcpy(&ha->flash_data[ha->flash_datasize], pt + 1, - pt->CoppCP.cmd.flashfw.count); - ha->flash_datasize += pt->CoppCP.cmd.flashfw.count; - if(pt->CoppCP.cmd.flashfw.packet_num == - pt->CoppCP.cmd.flashfw.total_packets - 1){ - if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE) - return ips_flash_bios(ha, pt, scb); - else if(pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE) - return ips_flash_firmware(ha, pt, scb); - } - return IPS_SUCCESS_IMM; + /* Trombone is the only copperhead that can do packet flash, but only + * for firmware. No one said it had to make sence. */ + if (IPS_IS_TROMBONE(ha) && pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE) { + if (ips_usrcmd(ha, pt, scb)) + return IPS_SUCCESS; + else + return IPS_FAILURE; + } + pt->BasicStatus = 0x0B; + pt->ExtendedStatus = 0; + scb->scsi_cmd->result = DID_OK << 16; + /* IF it's OK to Use the "CD BOOT" Flash Buffer, then you can */ + /* avoid allocating a huge buffer per adapter ( which can fail ). */ + if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE && + pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) { + pt->BasicStatus = 0; + return ips_flash_bios(ha, pt, scb); + } else if (pt->CoppCP.cmd.flashfw.packet_num == 0) { + if (ips_FlashData && !test_and_set_bit(0, &ips_FlashDataInUse)){ + ha->flash_data = ips_FlashData; + ha->flash_busaddr = ips_flashbusaddr; + ha->flash_len = PAGE_SIZE << 7; + ha->flash_datasize = 0; + } else if (!ha->flash_data) { + datasize = pt->CoppCP.cmd.flashfw.total_packets * + pt->CoppCP.cmd.flashfw.count; + ha->flash_data = pci_alloc_consistent(ha->pcidev, + datasize, + &ha->flash_busaddr); + if (!ha->flash_data){ + printk(KERN_WARNING "Unable to allocate a flash buffer\n"); + return IPS_FAILURE; + } + ha->flash_datasize = 0; + ha->flash_len = datasize; + } else + return IPS_FAILURE; + } else { + if (pt->CoppCP.cmd.flashfw.count + ha->flash_datasize > + ha->flash_len) { + ips_free_flash_copperhead(ha); + printk(KERN_WARNING "failed size sanity check\n"); + return IPS_FAILURE; + } + } + if (!ha->flash_data) + return IPS_FAILURE; + pt->BasicStatus = 0; + memcpy(&ha->flash_data[ha->flash_datasize], pt + 1, + pt->CoppCP.cmd.flashfw.count); + ha->flash_datasize += pt->CoppCP.cmd.flashfw.count; + if (pt->CoppCP.cmd.flashfw.packet_num == + pt->CoppCP.cmd.flashfw.total_packets - 1) { + if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE) + return ips_flash_bios(ha, pt, scb); + else if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE) + return ips_flash_firmware(ha, pt, scb); + } + return IPS_SUCCESS_IMM; } /****************************************************************************/ @@ -2473,46 +1767,95 @@ /* flashes the bios of a copperhead adapter */ /****************************************************************************/ static int -ips_flash_bios(ips_ha_t * ha, ips_passthru_t *pt, ips_scb_t *scb){ +ips_flash_bios(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb) +{ + + if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE && + pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_BIOS) { + if ((!ha->func.programbios) || (!ha->func.erasebios) || + (!ha->func.verifybios)) goto error; + if ((*ha->func.erasebios) (ha)) { + DEBUG_VAR(1, + "(%s%d) flash bios failed - unable to erase flash", + ips_name, ha->host_num); + goto error; + } else + if ((*ha->func.programbios) + (ha, ha->flash_data + IPS_BIOS_HEADER, + ha->flash_datasize - IPS_BIOS_HEADER, 0)) { + DEBUG_VAR(1, + "(%s%d) flash bios failed - unable to flash", + ips_name, ha->host_num); + goto error; + } else + if ((*ha->func.verifybios) + (ha, ha->flash_data + IPS_BIOS_HEADER, + ha->flash_datasize - IPS_BIOS_HEADER, 0)) { + DEBUG_VAR(1, + "(%s%d) flash bios failed - unable to verify flash", + ips_name, ha->host_num); + goto error; + } + ips_free_flash_copperhead(ha); + return IPS_SUCCESS_IMM; + } else if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE && + pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) { + if (!ha->func.erasebios) + goto error; + if ((*ha->func.erasebios) (ha)) { + DEBUG_VAR(1, + "(%s%d) flash bios failed - unable to erase flash", + ips_name, ha->host_num); + goto error; + } + return IPS_SUCCESS_IMM; + } + error: + pt->BasicStatus = 0x0B; + pt->ExtendedStatus = 0x00; + ips_free_flash_copperhead(ha); + return IPS_FAILURE; +} + +/****************************************************************************/ +/* */ +/* Routine Name: ips_fill_scb_sg_single */ +/* */ +/* Routine Description: */ +/* Fill in a single scb sg_list element from an address */ +/* return a -1 if a breakup occured */ +/****************************************************************************/ +static inline int +ips_fill_scb_sg_single(ips_ha_t * ha, dma_addr_t busaddr, + ips_scb_t * scb, int indx, unsigned int e_len) +{ - if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE && - pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_BIOS){ - if ((!ha->func.programbios) || (!ha->func.erasebios) || - (!ha->func.verifybios)) - goto error; - if((*ha->func.erasebios)(ha)){ - DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash", - ips_name, ha->host_num); - goto error; - }else if ((*ha->func.programbios)(ha, ha->flash_data + IPS_BIOS_HEADER, - ha->flash_datasize - IPS_BIOS_HEADER, 0 )) { - DEBUG_VAR(1, "(%s%d) flash bios failed - unable to flash", - ips_name, ha->host_num); - goto error; - }else if ((*ha->func.verifybios)(ha, ha->flash_data + IPS_BIOS_HEADER, - ha->flash_datasize - IPS_BIOS_HEADER, 0 )) { - DEBUG_VAR(1, "(%s%d) flash bios failed - unable to verify flash", - ips_name, ha->host_num); - goto error; - } - ips_free_flash_copperhead(ha); - return IPS_SUCCESS_IMM; - }else if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE && - pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS){ - if(!ha->func.erasebios) - goto error; - if((*ha->func.erasebios)(ha)){ - DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash", - ips_name, ha->host_num); - goto error; - } - return IPS_SUCCESS_IMM; - } -error: - pt->BasicStatus = 0x0B; - pt->ExtendedStatus = 0x00; - ips_free_flash_copperhead(ha); - return IPS_FAILURE; + int ret_val = 0; + + if ((scb->data_len + e_len) > ha->max_xfer) { + e_len = ha->max_xfer - scb->data_len; + scb->breakup = indx; + ++scb->sg_break; + ret_val = -1; + } else { + scb->breakup = 0; + scb->sg_break = 0; + } + if (IPS_USE_ENH_SGLIST(ha)) { + scb->sg_list.enh_list[indx].address_lo = + cpu_to_le32(pci_dma_lo32(busaddr)); + scb->sg_list.enh_list[indx].address_hi = + cpu_to_le32(pci_dma_hi32(busaddr)); + scb->sg_list.enh_list[indx].length = cpu_to_le32(e_len); + } else { + scb->sg_list.std_list[indx].address = + cpu_to_le32(pci_dma_lo32(busaddr)); + scb->sg_list.std_list[indx].length = cpu_to_le32(e_len); + } + + ++scb->sg_len; + scb->data_len += e_len; + return ret_val; } /****************************************************************************/ @@ -2521,49 +1864,51 @@ /* flashes the firmware of a copperhead adapter */ /****************************************************************************/ static int -ips_flash_firmware(ips_ha_t * ha, ips_passthru_t *pt, ips_scb_t *scb){ - IPS_SG_LIST *sg_list; - uint32_t cmd_busaddr; - - if(pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE && - pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_FW ){ - memset(&pt->CoppCP.cmd, 0, sizeof(IPS_HOST_COMMAND)); - pt->CoppCP.cmd.flashfw.op_code = IPS_CMD_DOWNLOAD; - pt->CoppCP.cmd.flashfw.count = cpu_to_le32(ha->flash_datasize); - }else{ - pt->BasicStatus = 0x0B; - pt->ExtendedStatus = 0x00; - ips_free_flash_copperhead(ha); - return IPS_FAILURE; - } - /* Save the S/G list pointer so it doesn't get clobbered */ - sg_list = scb->sg_list; - cmd_busaddr = scb->scb_busaddr; - /* copy in the CP */ - memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IPS_IOCTL_CMD)); - /* FIX stuff that might be wrong */ - scb->sg_list = sg_list; - scb->scb_busaddr = cmd_busaddr; - scb->bus = scb->scsi_cmd->channel; - scb->target_id = scb->scsi_cmd->target; - scb->lun = scb->scsi_cmd->lun; - scb->sg_len = 0; - scb->data_len = 0; - scb->flags = 0; - scb->op_code = 0; - scb->callback = ipsintr_done; - scb->timeout = ips_cmd_timeout; - - scb->data_len = ha->flash_datasize; - scb->data_busaddr = pci_map_single(ha->pcidev, ha->flash_data, scb->data_len, - IPS_DMA_DIR(scb)); - scb->flags |= IPS_SCB_MAP_SINGLE; - scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.flashfw.buffer_addr = scb->data_busaddr; - if (pt->TimeOut) - scb->timeout = pt->TimeOut; - scb->scsi_cmd->result = DID_OK <<16; - return IPS_SUCCESS; +ips_flash_firmware(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb) +{ + IPS_SG_LIST sg_list; + uint32_t cmd_busaddr; + + if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE && + pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_FW) { + memset(&pt->CoppCP.cmd, 0, sizeof (IPS_HOST_COMMAND)); + pt->CoppCP.cmd.flashfw.op_code = IPS_CMD_DOWNLOAD; + pt->CoppCP.cmd.flashfw.count = cpu_to_le32(ha->flash_datasize); + } else { + pt->BasicStatus = 0x0B; + pt->ExtendedStatus = 0x00; + ips_free_flash_copperhead(ha); + return IPS_FAILURE; + } + /* Save the S/G list pointer so it doesn't get clobbered */ + sg_list.list = scb->sg_list.list; + cmd_busaddr = scb->scb_busaddr; + /* copy in the CP */ + memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof (IPS_IOCTL_CMD)); + /* FIX stuff that might be wrong */ + scb->sg_list.list = sg_list.list; + scb->scb_busaddr = cmd_busaddr; + scb->bus = scb->scsi_cmd->channel; + scb->target_id = scb->scsi_cmd->target; + scb->lun = scb->scsi_cmd->lun; + scb->sg_len = 0; + scb->data_len = 0; + scb->flags = 0; + scb->op_code = 0; + scb->callback = ipsintr_done; + scb->timeout = ips_cmd_timeout; + + scb->data_len = ha->flash_datasize; + scb->data_busaddr = + pci_map_single(ha->pcidev, ha->flash_data, scb->data_len, + IPS_DMA_DIR(scb)); + scb->flags |= IPS_SCB_MAP_SINGLE; + scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.flashfw.buffer_addr = cpu_to_le32(scb->data_busaddr); + if (pt->TimeOut) + scb->timeout = pt->TimeOut; + scb->scsi_cmd->result = DID_OK << 16; + return IPS_SUCCESS; } /****************************************************************************/ @@ -2572,12 +1917,14 @@ /* release the memory resources used to hold the flash image */ /****************************************************************************/ static void -ips_free_flash_copperhead(ips_ha_t *ha){ - if(ha->flash_data == ips_FlashData) - test_and_clear_bit(0, &ips_FlashDataInUse); - else if(ha->flash_data) - free_pages((unsigned long)ha->flash_data, ha->flash_order); - ha->flash_data = NULL; +ips_free_flash_copperhead(ips_ha_t * ha) +{ + if (ha->flash_data == ips_FlashData) + test_and_clear_bit(0, &ips_FlashDataInUse); + else if (ha->flash_data) + pci_free_consistent(ha->pcidev, ha->flash_len, ha->flash_data, + ha->flash_busaddr); + ha->flash_data = NULL; } /****************************************************************************/ @@ -2590,93 +1937,82 @@ /* */ /****************************************************************************/ static int -ips_usrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) { - IPS_SG_LIST *sg_list; - uint32_t cmd_busaddr; - - METHOD_TRACE("ips_usrcmd", 1); - - if ((!scb) || (!pt) || (!ha)) - return (0); - - /* Save the S/G list pointer so it doesn't get clobbered */ - sg_list = scb->sg_list; - cmd_busaddr = scb->scb_busaddr; - /* copy in the CP */ - memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IPS_IOCTL_CMD)); - memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof(IPS_DCDB_TABLE)); - - /* FIX stuff that might be wrong */ - scb->sg_list = sg_list; - scb->scb_busaddr = cmd_busaddr; - scb->bus = scb->scsi_cmd->channel; - scb->target_id = scb->scsi_cmd->target; - scb->lun = scb->scsi_cmd->lun; - scb->sg_len = 0; - scb->data_len = 0; - scb->flags = 0; - scb->op_code = 0; - scb->callback = ipsintr_done; - scb->timeout = ips_cmd_timeout; - scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); - - /* we don't support DCDB/READ/WRITE Scatter Gather */ - if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) || - (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) || - (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG)) - return (0); - - if (pt->CmdBSize) { - if(!scb->scsi_cmd->use_sg){ - scb->data_len = pt->CmdBSize; - scb->data_busaddr = pci_map_single(ha->pcidev, - scb->scsi_cmd->request_buffer + - sizeof(ips_passthru_t), - pt->CmdBSize, - IPS_DMA_DIR(scb)); - scb->flags |= IPS_SCB_MAP_SINGLE; - } else { - scb->data_len = pt->CmdBSize; - scb->data_busaddr = pci_map_single(ha->pcidev, - ha->ioctl_data + - sizeof(ips_passthru_t), - pt->CmdBSize, - IPS_DMA_DIR(scb)); - scb->flags |= IPS_SCB_MAP_SINGLE; - } - } else { - scb->data_busaddr = 0L; - } - - if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) - scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr + - (unsigned long)&scb->dcdb - - (unsigned long)scb); - - if (pt->CmdBSize) { - if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) - scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr); - else - scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr); - } - - /* set timeouts */ - if (pt->TimeOut) { - scb->timeout = pt->TimeOut; - - if (pt->TimeOut <= 10) - scb->dcdb.cmd_attribute |= IPS_TIMEOUT10; - else if (pt->TimeOut <= 60) - scb->dcdb.cmd_attribute |= IPS_TIMEOUT60; - else - scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; - } +ips_usrcmd(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb) +{ + IPS_SG_LIST sg_list; + uint32_t cmd_busaddr; + + METHOD_TRACE("ips_usrcmd", 1); + + if ((!scb) || (!pt) || (!ha)) + return (0); - /* assume success */ - scb->scsi_cmd->result = DID_OK << 16; + /* Save the S/G list pointer so it doesn't get clobbered */ + sg_list.list = scb->sg_list.list; + cmd_busaddr = scb->scb_busaddr; + /* copy in the CP */ + memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof (IPS_IOCTL_CMD)); + memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof (IPS_DCDB_TABLE)); + + /* FIX stuff that might be wrong */ + scb->sg_list.list = sg_list.list; + scb->scb_busaddr = cmd_busaddr; + scb->bus = scb->scsi_cmd->channel; + scb->target_id = scb->scsi_cmd->target; + scb->lun = scb->scsi_cmd->lun; + scb->sg_len = 0; + scb->data_len = 0; + scb->flags = 0; + scb->op_code = 0; + scb->callback = ipsintr_done; + scb->timeout = ips_cmd_timeout; + scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); + + /* we don't support DCDB/READ/WRITE Scatter Gather */ + if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) || + (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) || + (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG)) + return (0); + + if (pt->CmdBSize) { + scb->data_len = pt->CmdBSize; + scb->data_busaddr = ha->ioctl_busaddr + sizeof (ips_passthru_t); + } else { + scb->data_busaddr = 0L; + } + + if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) + scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr + + (unsigned long) &scb-> + dcdb - + (unsigned long) scb); + + if (pt->CmdBSize) { + if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) + scb->dcdb.buffer_pointer = + cpu_to_le32(scb->data_busaddr); + else + scb->cmd.basic_io.sg_addr = + cpu_to_le32(scb->data_busaddr); + } + + /* set timeouts */ + if (pt->TimeOut) { + scb->timeout = pt->TimeOut; + + if (pt->TimeOut <= 10) + scb->dcdb.cmd_attribute |= IPS_TIMEOUT10; + else if (pt->TimeOut <= 60) + scb->dcdb.cmd_attribute |= IPS_TIMEOUT60; + else + scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; + } - /* success */ - return (1); + /* assume success */ + scb->scsi_cmd->result = DID_OK << 16; + + /* success */ + return (1); } /****************************************************************************/ @@ -2689,43 +2025,34 @@ /* */ /****************************************************************************/ static void -ips_cleanup_passthru(ips_ha_t *ha, ips_scb_t *scb) { - ips_passthru_t *pt; +ips_cleanup_passthru(ips_ha_t * ha, ips_scb_t * scb) +{ + ips_passthru_t *pt; + + METHOD_TRACE("ips_cleanup_passthru", 1); + + if ((!scb) || (!scb->scsi_cmd) || (!scb->scsi_cmd->request_buffer)) { + DEBUG_VAR(1, "(%s%d) couldn't cleanup after passthru", + ips_name, ha->host_num); + + return; + } + pt = (ips_passthru_t *) ha->ioctl_data; + + /* Copy data back to the user */ + if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) /* Copy DCDB Back to Caller's Area */ + memcpy(&pt->CoppCP.dcdb, &scb->dcdb, sizeof (IPS_DCDB_TABLE)); + + pt->BasicStatus = scb->basic_status; + pt->ExtendedStatus = scb->extended_status; + pt->AdapterType = ha->ad_type; - METHOD_TRACE("ips_cleanup_passthru", 1); + if (ha->device_id == IPS_DEVICEID_COPPERHEAD && + (scb->cmd.flashfw.op_code == IPS_CMD_DOWNLOAD || + scb->cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW)) + ips_free_flash_copperhead(ha); - if ((!scb) || (!scb->scsi_cmd) || (!scb->scsi_cmd->request_buffer)) { - DEBUG_VAR(1, "(%s%d) couldn't cleanup after passthru", - ips_name, ha->host_num); - - return ; - } - if(!scb->scsi_cmd->use_sg) - pt = (ips_passthru_t *) scb->scsi_cmd->request_buffer; - else - pt = (ips_passthru_t *) ha->ioctl_data; - - /* Copy data back to the user */ - if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) /* Copy DCDB Back to Caller's Area */ - memcpy(&pt->CoppCP.dcdb, &scb->dcdb, sizeof(IPS_DCDB_TABLE)); - - pt->BasicStatus = scb->basic_status; - pt->ExtendedStatus = scb->extended_status; - pt->AdapterType = ha->ad_type; - - if(ha->device_id == IPS_DEVICEID_COPPERHEAD && - (scb->cmd.flashfw.op_code == IPS_CMD_DOWNLOAD || - scb->cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW)) - ips_free_flash_copperhead(ha); - - if(scb->scsi_cmd->use_sg){ - int i, length = 0; - struct scatterlist *sg = scb->scsi_cmd->request_buffer; - for(i = 0; i < scb->scsi_cmd->use_sg; i++){ - memcpy(IPS_SG_ADDRESS(&sg[i]), &ha->ioctl_data[length], sg[i].length); - length += sg[i].length; - } - } + ips_scmd_buf_write(scb->scsi_cmd, ha->ioctl_data, ha->ioctl_datasize); } /****************************************************************************/ @@ -2738,75 +2065,88 @@ /* */ /****************************************************************************/ static int -ips_host_info(ips_ha_t *ha, char *ptr, off_t offset, int len) { - IPS_INFOSTR info; +ips_host_info(ips_ha_t * ha, char *ptr, off_t offset, int len) +{ + IPS_INFOSTR info; - METHOD_TRACE("ips_host_info", 1); + METHOD_TRACE("ips_host_info", 1); - info.buffer = ptr; - info.length = len; - info.offset = offset; - info.pos = 0; - info.localpos = 0; - - copy_info(&info, "\nIBM ServeRAID General Information:\n\n"); - - if ((le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) && - (le16_to_cpu(ha->nvram->adapter_type) != 0)) - copy_info(&info, "\tController Type : %s\n", ips_adapter_name[ha->ad_type-1]); - else - copy_info(&info, "\tController Type : Unknown\n"); - - if (ha->io_addr) - copy_info(&info, "\tIO region : 0x%lx (%d bytes)\n", - ha->io_addr, ha->io_len); - - if (ha->mem_addr) { - copy_info(&info, "\tMemory region : 0x%lx (%d bytes)\n", - ha->mem_addr, ha->mem_len); - copy_info(&info, "\tShared memory address : 0x%lx\n", ha->mem_ptr); - } - - copy_info(&info, "\tIRQ number : %d\n", ha->irq); - - if (le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) - copy_info(&info, "\tBIOS Version : %c%c%c%c%c%c%c%c\n", - ha->nvram->bios_high[0], ha->nvram->bios_high[1], - ha->nvram->bios_high[2], ha->nvram->bios_high[3], - ha->nvram->bios_low[0], ha->nvram->bios_low[1], - ha->nvram->bios_low[2], ha->nvram->bios_low[3]); - - copy_info(&info, "\tFirmware Version : %c%c%c%c%c%c%c%c\n", - ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1], - ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3], - ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5], - ha->enq->CodeBlkVersion[6], ha->enq->CodeBlkVersion[7]); - - copy_info(&info, "\tBoot Block Version : %c%c%c%c%c%c%c%c\n", - ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1], - ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3], - ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5], - ha->enq->BootBlkVersion[6], ha->enq->BootBlkVersion[7]); - - copy_info(&info, "\tDriver Version : %s%s\n", - IPS_VERSION_HIGH, IPS_VERSION_LOW); - - copy_info(&info, "\tMax Physical Devices : %d\n", - ha->enq->ucMaxPhysicalDevices); - copy_info(&info, "\tMax Active Commands : %d\n", - ha->max_cmds); - copy_info(&info, "\tCurrent Queued Commands : %d\n", - ha->scb_waitlist.count); - copy_info(&info, "\tCurrent Active Commands : %d\n", - ha->scb_activelist.count - ha->num_ioctl); - copy_info(&info, "\tCurrent Queued PT Commands : %d\n", - ha->copp_waitlist.count); - copy_info(&info, "\tCurrent Active PT Commands : %d\n", - ha->num_ioctl); + info.buffer = ptr; + info.length = len; + info.offset = offset; + info.pos = 0; + info.localpos = 0; + + copy_info(&info, "\nIBM ServeRAID General Information:\n\n"); + + if ((le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) && + (le16_to_cpu(ha->nvram->adapter_type) != 0)) + copy_info(&info, "\tController Type : %s\n", + ips_adapter_name[ha->ad_type - 1]); + else + copy_info(&info, + "\tController Type : Unknown\n"); + + if (ha->io_addr) + copy_info(&info, + "\tIO region : 0x%lx (%d bytes)\n", + ha->io_addr, ha->io_len); + + if (ha->mem_addr) { + copy_info(&info, + "\tMemory region : 0x%lx (%d bytes)\n", + ha->mem_addr, ha->mem_len); + copy_info(&info, + "\tShared memory address : 0x%lx\n", + ha->mem_ptr); + } + + copy_info(&info, "\tIRQ number : %d\n", ha->irq); + + if (le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) + copy_info(&info, + "\tBIOS Version : %c%c%c%c%c%c%c%c\n", + ha->nvram->bios_high[0], ha->nvram->bios_high[1], + ha->nvram->bios_high[2], ha->nvram->bios_high[3], + ha->nvram->bios_low[0], ha->nvram->bios_low[1], + ha->nvram->bios_low[2], ha->nvram->bios_low[3]); + + copy_info(&info, + "\tFirmware Version : %c%c%c%c%c%c%c%c\n", + ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1], + ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3], + ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5], + ha->enq->CodeBlkVersion[6], ha->enq->CodeBlkVersion[7]); + + copy_info(&info, + "\tBoot Block Version : %c%c%c%c%c%c%c%c\n", + ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1], + ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3], + ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5], + ha->enq->BootBlkVersion[6], ha->enq->BootBlkVersion[7]); + + copy_info(&info, "\tDriver Version : %s%s\n", + IPS_VERSION_HIGH, IPS_VERSION_LOW); + + copy_info(&info, "\tDriver Build : %d\n", + IPS_BUILD_IDENT); + + copy_info(&info, "\tMax Physical Devices : %d\n", + ha->enq->ucMaxPhysicalDevices); + copy_info(&info, "\tMax Active Commands : %d\n", + ha->max_cmds); + copy_info(&info, "\tCurrent Queued Commands : %d\n", + ha->scb_waitlist.count); + copy_info(&info, "\tCurrent Active Commands : %d\n", + ha->scb_activelist.count - ha->num_ioctl); + copy_info(&info, "\tCurrent Queued PT Commands : %d\n", + ha->copp_waitlist.count); + copy_info(&info, "\tCurrent Active PT Commands : %d\n", + ha->num_ioctl); - copy_info(&info, "\n"); + copy_info(&info, "\n"); - return (info.localpos); + return (info.localpos); } /****************************************************************************/ @@ -2819,28 +2159,29 @@ /* */ /****************************************************************************/ static void -copy_mem_info(IPS_INFOSTR *info, char *data, int len) { - METHOD_TRACE("copy_mem_info", 1); +copy_mem_info(IPS_INFOSTR * info, char *data, int len) +{ + METHOD_TRACE("copy_mem_info", 1); - if (info->pos + len < info->offset) { - info->pos += len; - return; - } - - if (info->pos < info->offset) { - data += (info->offset - info->pos); - len -= (info->offset - info->pos); - info->pos += (info->offset - info->pos); - } - - if (info->localpos + len > info->length) - len = info->length - info->localpos; - - if (len > 0) { - memcpy(info->buffer + info->localpos, data, len); - info->pos += len; - info->localpos += len; - } + if (info->pos + len < info->offset) { + info->pos += len; + return; + } + + if (info->pos < info->offset) { + data += (info->offset - info->pos); + len -= (info->offset - info->pos); + info->pos += (info->offset - info->pos); + } + + if (info->localpos + len > info->length) + len = info->length - info->localpos; + + if (len > 0) { + memcpy(info->buffer + info->localpos, data, len); + info->pos += len; + info->localpos += len; + } } /****************************************************************************/ @@ -2853,20 +2194,21 @@ /* */ /****************************************************************************/ static int -copy_info(IPS_INFOSTR *info, char *fmt, ...) { - va_list args; - char buf[128]; - int len; +copy_info(IPS_INFOSTR * info, char *fmt, ...) +{ + va_list args; + char buf[128]; + int len; - METHOD_TRACE("copy_info", 1); + METHOD_TRACE("copy_info", 1); - va_start(args, fmt); - len = vsprintf(buf, fmt, args); - va_end(args); + va_start(args, fmt); + len = vsprintf(buf, fmt, args); + va_end(args); - copy_mem_info(info, buf, len); + copy_mem_info(info, buf, len); - return (len); + return (len); } /****************************************************************************/ @@ -2879,71 +2221,73 @@ /* */ /****************************************************************************/ static void -ips_identify_controller(ips_ha_t *ha) { - METHOD_TRACE("ips_identify_controller", 1); +ips_identify_controller(ips_ha_t * ha) +{ + METHOD_TRACE("ips_identify_controller", 1); - switch (ha->device_id) { - case IPS_DEVICEID_COPPERHEAD: - if (ha->revision_id <= IPS_REVID_SERVERAID) { - ha->ad_type = IPS_ADTYPE_SERVERAID; - } else if (ha->revision_id == IPS_REVID_SERVERAID2) { - ha->ad_type = IPS_ADTYPE_SERVERAID2; - } else if (ha->revision_id == IPS_REVID_NAVAJO) { - ha->ad_type = IPS_ADTYPE_NAVAJO; - } else if ((ha->revision_id == IPS_REVID_SERVERAID2) && (ha->slot_num == 0)) { - ha->ad_type = IPS_ADTYPE_KIOWA; - } else if ((ha->revision_id >= IPS_REVID_CLARINETP1) && - (ha->revision_id <= IPS_REVID_CLARINETP3)) { - if (ha->enq->ucMaxPhysicalDevices == 15) - ha->ad_type = IPS_ADTYPE_SERVERAID3L; - else - ha->ad_type = IPS_ADTYPE_SERVERAID3; - } else if ((ha->revision_id >= IPS_REVID_TROMBONE32) && - (ha->revision_id <= IPS_REVID_TROMBONE64)) { - ha->ad_type = IPS_ADTYPE_SERVERAID4H; - } - break; - - case IPS_DEVICEID_MORPHEUS: - switch (ha->subdevice_id) { - case IPS_SUBDEVICEID_4L: - ha->ad_type = IPS_ADTYPE_SERVERAID4L; - break; - - case IPS_SUBDEVICEID_4M: - ha->ad_type = IPS_ADTYPE_SERVERAID4M; - break; - - case IPS_SUBDEVICEID_4MX: - ha->ad_type = IPS_ADTYPE_SERVERAID4MX; - break; - - case IPS_SUBDEVICEID_4LX: - ha->ad_type = IPS_ADTYPE_SERVERAID4LX; - break; - - case IPS_SUBDEVICEID_5I2: - ha->ad_type = IPS_ADTYPE_SERVERAID5I2; - break; - - case IPS_SUBDEVICEID_5I1: - ha->ad_type = IPS_ADTYPE_SERVERAID5I1; - break; - } - - break; - - case IPS_DEVICEID_MARCO: - switch (ha->subdevice_id) { - case IPS_SUBDEVICEID_6M: - ha->ad_type = IPS_ADTYPE_SERVERAID6M; - break; - case IPS_SUBDEVICEID_6I: - ha->ad_type = IPS_ADTYPE_SERVERAID6I; - break; - } - break; - } + switch (ha->device_id) { + case IPS_DEVICEID_COPPERHEAD: + if (ha->revision_id <= IPS_REVID_SERVERAID) { + ha->ad_type = IPS_ADTYPE_SERVERAID; + } else if (ha->revision_id == IPS_REVID_SERVERAID2) { + ha->ad_type = IPS_ADTYPE_SERVERAID2; + } else if (ha->revision_id == IPS_REVID_NAVAJO) { + ha->ad_type = IPS_ADTYPE_NAVAJO; + } else if ((ha->revision_id == IPS_REVID_SERVERAID2) + && (ha->slot_num == 0)) { + ha->ad_type = IPS_ADTYPE_KIOWA; + } else if ((ha->revision_id >= IPS_REVID_CLARINETP1) && + (ha->revision_id <= IPS_REVID_CLARINETP3)) { + if (ha->enq->ucMaxPhysicalDevices == 15) + ha->ad_type = IPS_ADTYPE_SERVERAID3L; + else + ha->ad_type = IPS_ADTYPE_SERVERAID3; + } else if ((ha->revision_id >= IPS_REVID_TROMBONE32) && + (ha->revision_id <= IPS_REVID_TROMBONE64)) { + ha->ad_type = IPS_ADTYPE_SERVERAID4H; + } + break; + + case IPS_DEVICEID_MORPHEUS: + switch (ha->subdevice_id) { + case IPS_SUBDEVICEID_4L: + ha->ad_type = IPS_ADTYPE_SERVERAID4L; + break; + + case IPS_SUBDEVICEID_4M: + ha->ad_type = IPS_ADTYPE_SERVERAID4M; + break; + + case IPS_SUBDEVICEID_4MX: + ha->ad_type = IPS_ADTYPE_SERVERAID4MX; + break; + + case IPS_SUBDEVICEID_4LX: + ha->ad_type = IPS_ADTYPE_SERVERAID4LX; + break; + + case IPS_SUBDEVICEID_5I2: + ha->ad_type = IPS_ADTYPE_SERVERAID5I2; + break; + + case IPS_SUBDEVICEID_5I1: + ha->ad_type = IPS_ADTYPE_SERVERAID5I1; + break; + } + + break; + + case IPS_DEVICEID_MARCO: + switch (ha->subdevice_id) { + case IPS_SUBDEVICEID_6M: + ha->ad_type = IPS_ADTYPE_SERVERAID6M; + break; + case IPS_SUBDEVICEID_6I: + ha->ad_type = IPS_ADTYPE_SERVERAID6I; + break; + } + break; + } } /****************************************************************************/ @@ -2956,158 +2300,154 @@ /* */ /****************************************************************************/ static void -ips_get_bios_version(ips_ha_t *ha, int intr) { - ips_scb_t *scb; - int ret; - uint8_t major; - uint8_t minor; - uint8_t subminor; - uint8_t *buffer; - char hexDigits[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; - - METHOD_TRACE("ips_get_bios_version", 1); - - major = 0; - minor = 0; - - strncpy(ha->bios_version, " ?", 8); - - if (ha->device_id == IPS_DEVICEID_COPPERHEAD) { - if (IPS_USE_MEMIO(ha)) { - /* Memory Mapped I/O */ - - /* test 1st byte */ - writel(0, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55) - return; - - writel(1, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA) - return; - - /* Get Major version */ - writel(0x1FF, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - major = readb(ha->mem_ptr + IPS_REG_FLDP); - - /* Get Minor version */ - writel(0x1FE, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - minor = readb(ha->mem_ptr + IPS_REG_FLDP); - - /* Get SubMinor version */ - writel(0x1FD, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - subminor = readb(ha->mem_ptr + IPS_REG_FLDP); - - } else { - /* Programmed I/O */ - - /* test 1st byte */ - outl(0, ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55) - return ; - - outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA) - return ; - - /* Get Major version */ - outl(cpu_to_le32(0x1FF), ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - major = inb(ha->io_addr + IPS_REG_FLDP); - - /* Get Minor version */ - outl(cpu_to_le32(0x1FE), ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - minor = inb(ha->io_addr + IPS_REG_FLDP); - - /* Get SubMinor version */ - outl(cpu_to_le32(0x1FD), ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - subminor = inb(ha->io_addr + IPS_REG_FLDP); - - } - } else { - /* Morpheus Family - Send Command to the card */ - - buffer = kmalloc(0x1000, GFP_ATOMIC); - if (!buffer) - return; - - memset(buffer, 0, 0x1000); - - scb = &ha->scbs[ha->max_cmds-1]; - - ips_init_scb(ha, scb); - - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_RW_BIOSFW; - - scb->cmd.flashfw.op_code = IPS_CMD_RW_BIOSFW; - scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.flashfw.type = 1; - scb->cmd.flashfw.direction = 0; - scb->cmd.flashfw.count = cpu_to_le32(0x800); - scb->cmd.flashfw.total_packets = 1; - scb->cmd.flashfw.packet_num = 0; - scb->data_len = 0x1000; - scb->data_busaddr = pci_map_single(ha->pcidev, buffer, scb->data_len, - IPS_DMA_DIR(scb)); - scb->cmd.flashfw.buffer_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; - - /* issue the command */ - if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) || - (ret == IPS_SUCCESS_IMM) || - ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) { - /* Error occurred */ - kfree(buffer); - - return; - } - - if ((buffer[0xC0] == 0x55) && (buffer[0xC1] == 0xAA)) { - major = buffer[0x1ff + 0xC0]; /* Offset 0x1ff after the header (0xc0) */ - minor = buffer[0x1fe + 0xC0]; /* Offset 0x1fe after the header (0xc0) */ - subminor = buffer[0x1fd + 0xC0]; /* Offset 0x1fd after the header (0xc0) */ - } else { - return; - } - - kfree(buffer); - } - - ha->bios_version[0] = hexDigits[(major & 0xF0) >> 4]; - ha->bios_version[1] = '.'; - ha->bios_version[2] = hexDigits[major & 0x0F]; - ha->bios_version[3] = hexDigits[subminor]; - ha->bios_version[4] = '.'; - ha->bios_version[5] = hexDigits[(minor & 0xF0) >> 4]; - ha->bios_version[6] = hexDigits[minor & 0x0F]; - ha->bios_version[7] = 0; +ips_get_bios_version(ips_ha_t * ha, int intr) +{ + ips_scb_t *scb; + int ret; + uint8_t major; + uint8_t minor; + uint8_t subminor; + uint8_t *buffer; + char hexDigits[] = + { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', + 'D', 'E', 'F' }; + + METHOD_TRACE("ips_get_bios_version", 1); + + major = 0; + minor = 0; + + strncpy(ha->bios_version, " ?", 8); + + if (ha->device_id == IPS_DEVICEID_COPPERHEAD) { + if (IPS_USE_MEMIO(ha)) { + /* Memory Mapped I/O */ + + /* test 1st byte */ + writel(0, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55) + return; + + writel(1, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA) + return; + + /* Get Major version */ + writel(0x1FF, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + major = readb(ha->mem_ptr + IPS_REG_FLDP); + + /* Get Minor version */ + writel(0x1FE, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + minor = readb(ha->mem_ptr + IPS_REG_FLDP); + + /* Get SubMinor version */ + writel(0x1FD, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + subminor = readb(ha->mem_ptr + IPS_REG_FLDP); + + } else { + /* Programmed I/O */ + + /* test 1st byte */ + outl(0, ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55) + return; + + outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA) + return; + + /* Get Major version */ + outl(cpu_to_le32(0x1FF), ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + major = inb(ha->io_addr + IPS_REG_FLDP); + + /* Get Minor version */ + outl(cpu_to_le32(0x1FE), ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + minor = inb(ha->io_addr + IPS_REG_FLDP); + + /* Get SubMinor version */ + outl(cpu_to_le32(0x1FD), ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + subminor = inb(ha->io_addr + IPS_REG_FLDP); + + } + } else { + /* Morpheus Family - Send Command to the card */ + + buffer = ha->ioctl_data; + + memset(buffer, 0, 0x1000); + + scb = &ha->scbs[ha->max_cmds - 1]; + + ips_init_scb(ha, scb); + + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_RW_BIOSFW; + + scb->cmd.flashfw.op_code = IPS_CMD_RW_BIOSFW; + scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.flashfw.type = 1; + scb->cmd.flashfw.direction = 0; + scb->cmd.flashfw.count = cpu_to_le32(0x800); + scb->cmd.flashfw.total_packets = 1; + scb->cmd.flashfw.packet_num = 0; + scb->data_len = 0x1000; + scb->cmd.flashfw.buffer_addr = ha->ioctl_busaddr; + + /* issue the command */ + if ( + ((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == + IPS_FAILURE) || (ret == IPS_SUCCESS_IMM) + || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) { + /* Error occurred */ + + return; + } + + if ((buffer[0xC0] == 0x55) && (buffer[0xC1] == 0xAA)) { + major = buffer[0x1ff + 0xC0]; /* Offset 0x1ff after the header (0xc0) */ + minor = buffer[0x1fe + 0xC0]; /* Offset 0x1fe after the header (0xc0) */ + subminor = buffer[0x1fd + 0xC0]; /* Offset 0x1fd after the header (0xc0) */ + } else { + return; + } + } + + ha->bios_version[0] = hexDigits[(major & 0xF0) >> 4]; + ha->bios_version[1] = '.'; + ha->bios_version[2] = hexDigits[major & 0x0F]; + ha->bios_version[3] = hexDigits[subminor]; + ha->bios_version[4] = '.'; + ha->bios_version[5] = hexDigits[(minor & 0xF0) >> 4]; + ha->bios_version[6] = hexDigits[minor & 0x0F]; + ha->bios_version[7] = 0; } /****************************************************************************/ @@ -3122,129 +2462,134 @@ /* */ /****************************************************************************/ static int -ips_hainit(ips_ha_t *ha) { - int i; - struct timeval tv; - - METHOD_TRACE("ips_hainit", 1); - - if (!ha) - return (0); - - if (ha->func.statinit) - (*ha->func.statinit)(ha); - - if (ha->func.enableint) - (*ha->func.enableint)(ha); - - /* Send FFDC */ - ha->reset_count = 1; - do_gettimeofday(&tv); - ha->last_ffdc = tv.tv_sec; - ips_ffdc_reset(ha, IPS_INTR_IORL); - - if (!ips_read_config(ha, IPS_INTR_IORL)) { - printk(KERN_WARNING "(%s%d) unable to read config from controller.\n", - ips_name, ha->host_num); - - return (0); - } /* end if */ - - if (!ips_read_adapter_status(ha, IPS_INTR_IORL)) { - printk(KERN_WARNING "(%s%d) unable to read controller status.\n", - ips_name, ha->host_num); - - return (0); - } - - /* Identify this controller */ - ips_identify_controller(ha); - - if (!ips_read_subsystem_parameters(ha, IPS_INTR_IORL)) { - printk(KERN_WARNING "(%s%d) unable to read subsystem parameters.\n", - ips_name, ha->host_num); - - return (0); - } - - /* write nvram user page 5 */ - if (!ips_write_driver_status(ha, IPS_INTR_IORL)) { - printk(KERN_WARNING "(%s%d) unable to write driver info to controller.\n", - ips_name, ha->host_num); - - return (0); - } - - /* If there are Logical Drives and a Reset Occurred, then an EraseStripeLock is Needed */ - if ( (ha->conf->ucLogDriveCount > 0) && (ha->requires_esl == 1) ) - ips_clear_adapter(ha, IPS_INTR_IORL); - - /* set limits on SID, LUN, BUS */ - ha->ntargets = IPS_MAX_TARGETS + 1; - ha->nlun = 1; - ha->nbus = (ha->enq->ucMaxPhysicalDevices / IPS_MAX_TARGETS) + 1; - - switch (ha->conf->logical_drive[0].ucStripeSize) { - case 4: - ha->max_xfer = 0x10000; - break; - - case 5: - ha->max_xfer = 0x20000; - break; - - case 6: - ha->max_xfer = 0x40000; - break; - - case 7: - default: - ha->max_xfer = 0x80000; - break; - } - - /* setup max concurrent commands */ - if (le32_to_cpu(ha->subsys->param[4]) & 0x1) { - /* Use the new method */ - ha->max_cmds = ha->enq->ucConcurrentCmdCount; - } else { - /* use the old method */ - switch (ha->conf->logical_drive[0].ucStripeSize) { - case 4: - ha->max_cmds = 32; - break; - - case 5: - ha->max_cmds = 16; - break; - - case 6: - ha->max_cmds = 8; - break; - - case 7: - default: - ha->max_cmds = 4; - break; - } - } - - /* Limit the Active Commands on a Lite Adapter */ - if ((ha->ad_type == IPS_ADTYPE_SERVERAID3L) || - (ha->ad_type == IPS_ADTYPE_SERVERAID4L) || - (ha->ad_type == IPS_ADTYPE_SERVERAID4LX)) { - if ((ha->max_cmds > MaxLiteCmds) && (MaxLiteCmds)) - ha->max_cmds = MaxLiteCmds; - } - - /* set controller IDs */ - ha->ha_id[0] = IPS_ADAPTER_ID; - for (i = 1; i < ha->nbus; i++) { - ha->ha_id[i] = ha->conf->init_id[i-1] & 0x1f; - ha->dcdb_active[i-1] = 0; - } +ips_hainit(ips_ha_t * ha) +{ + int i; + struct timeval tv; + + METHOD_TRACE("ips_hainit", 1); - return (1); + if (!ha) + return (0); + + if (ha->func.statinit) + (*ha->func.statinit) (ha); + + if (ha->func.enableint) + (*ha->func.enableint) (ha); + + /* Send FFDC */ + ha->reset_count = 1; + do_gettimeofday(&tv); + ha->last_ffdc = tv.tv_sec; + ips_ffdc_reset(ha, IPS_INTR_IORL); + + if (!ips_read_config(ha, IPS_INTR_IORL)) { + printk(KERN_WARNING + "(%s%d) unable to read config from controller.\n", + ips_name, ha->host_num); + + return (0); + } + /* end if */ + if (!ips_read_adapter_status(ha, IPS_INTR_IORL)) { + printk(KERN_WARNING + "(%s%d) unable to read controller status.\n", ips_name, + ha->host_num); + + return (0); + } + + /* Identify this controller */ + ips_identify_controller(ha); + + if (!ips_read_subsystem_parameters(ha, IPS_INTR_IORL)) { + printk(KERN_WARNING + "(%s%d) unable to read subsystem parameters.\n", + ips_name, ha->host_num); + + return (0); + } + + /* write nvram user page 5 */ + if (!ips_write_driver_status(ha, IPS_INTR_IORL)) { + printk(KERN_WARNING + "(%s%d) unable to write driver info to controller.\n", + ips_name, ha->host_num); + + return (0); + } + + /* If there are Logical Drives and a Reset Occurred, then an EraseStripeLock is Needed */ + if ((ha->conf->ucLogDriveCount > 0) && (ha->requires_esl == 1)) + ips_clear_adapter(ha, IPS_INTR_IORL); + + /* set limits on SID, LUN, BUS */ + ha->ntargets = IPS_MAX_TARGETS + 1; + ha->nlun = 1; + ha->nbus = (ha->enq->ucMaxPhysicalDevices / IPS_MAX_TARGETS) + 1; + + switch (ha->conf->logical_drive[0].ucStripeSize) { + case 4: + ha->max_xfer = 0x10000; + break; + + case 5: + ha->max_xfer = 0x20000; + break; + + case 6: + ha->max_xfer = 0x40000; + break; + + case 7: + default: + ha->max_xfer = 0x80000; + break; + } + + /* setup max concurrent commands */ + if (le32_to_cpu(ha->subsys->param[4]) & 0x1) { + /* Use the new method */ + ha->max_cmds = ha->enq->ucConcurrentCmdCount; + } else { + /* use the old method */ + switch (ha->conf->logical_drive[0].ucStripeSize) { + case 4: + ha->max_cmds = 32; + break; + + case 5: + ha->max_cmds = 16; + break; + + case 6: + ha->max_cmds = 8; + break; + + case 7: + default: + ha->max_cmds = 4; + break; + } + } + + /* Limit the Active Commands on a Lite Adapter */ + if ((ha->ad_type == IPS_ADTYPE_SERVERAID3L) || + (ha->ad_type == IPS_ADTYPE_SERVERAID4L) || + (ha->ad_type == IPS_ADTYPE_SERVERAID4LX)) { + if ((ha->max_cmds > MaxLiteCmds) && (MaxLiteCmds)) + ha->max_cmds = MaxLiteCmds; + } + + /* set controller IDs */ + ha->ha_id[0] = IPS_ADAPTER_ID; + for (i = 1; i < ha->nbus; i++) { + ha->ha_id[i] = ha->conf->init_id[i - 1] & 0x1f; + ha->dcdb_active[i - 1] = 0; + } + + return (1); } /****************************************************************************/ @@ -3257,275 +2602,243 @@ /* */ /****************************************************************************/ static void -ips_next(ips_ha_t *ha, int intr) { - ips_scb_t *scb; - Scsi_Cmnd *SC; - Scsi_Cmnd *p; - Scsi_Cmnd *q; - ips_copp_wait_item_t *item; - int ret; - unsigned long cpu_flags = 0; - struct Scsi_Host *host; - METHOD_TRACE("ips_next", 1); - - if (!ha) - return ; - host = ips_sh[ha->host_num]; - /* - * Block access to the queue function so - * this command won't time out - */ - if(intr == IPS_INTR_ON) - IPS_LOCK_SAVE(host->host_lock, cpu_flags); - - if ((ha->subsys->param[3] & 0x300000) && ( ha->scb_activelist.count == 0 )) { - struct timeval tv; - - do_gettimeofday(&tv); - - if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) { - ha->last_ffdc = tv.tv_sec; - ips_ffdc_time(ha); - } - } - - /* - * Send passthru commands - * These have priority over normal I/O - * but shouldn't affect performance too much - * since we limit the number that can be active - * on the card at any one time - */ - while ((ha->num_ioctl < IPS_MAX_IOCTL) && - (ha->copp_waitlist.head) && - (scb = ips_getscb(ha))) { - - item = ips_removeq_copp_head(&ha->copp_waitlist); - ha->num_ioctl++; - if(intr == IPS_INTR_ON) - IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); - scb->scsi_cmd = item->scsi_cmd; - kfree(item); - - ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr); - - if(intr == IPS_INTR_ON) - IPS_LOCK_SAVE(host->host_lock, cpu_flags); - switch (ret) { - case IPS_FAILURE: - if (scb->scsi_cmd) { - scb->scsi_cmd->result = DID_ERROR << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); - } - - ips_freescb(ha, scb); - break; - case IPS_SUCCESS_IMM: - if (scb->scsi_cmd) { - scb->scsi_cmd->result = DID_OK << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); - } - - ips_freescb(ha, scb); - break; - default: - break; - } /* end case */ - - if (ret != IPS_SUCCESS) { - ha->num_ioctl--; - continue; - } - - ret = ips_send_cmd(ha, scb); - - if (ret == IPS_SUCCESS) - ips_putq_scb_head(&ha->scb_activelist, scb); - else - ha->num_ioctl--; - - switch(ret) { - case IPS_FAILURE: - if (scb->scsi_cmd) { - scb->scsi_cmd->result = DID_ERROR << 16; - } - - ips_freescb(ha, scb); - break; - case IPS_SUCCESS_IMM: - ips_freescb(ha, scb); - break; - default: - break; - } /* end case */ - - } - - - /* - * Send "Normal" I/O commands - */ - - p = ha->scb_waitlist.head; - while ((p) && (scb = ips_getscb(ha))) { - if ((p->channel > 0) && (ha->dcdb_active[p->channel-1] & (1 << p->target))) { - ips_freescb(ha, scb); - p = (Scsi_Cmnd *) p->host_scribble; - continue; - } - - q = p; - SC = ips_removeq_wait(&ha->scb_waitlist, q); - - if(intr == IPS_INTR_ON) - IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); /* Unlock HA after command is taken off queue */ - - SC->result = DID_OK; - SC->host_scribble = NULL; - - memset(SC->sense_buffer, 0, sizeof(SC->sense_buffer)); - - scb->target_id = SC->target; - scb->lun = SC->lun; - scb->bus = SC->channel; - scb->scsi_cmd = SC; - scb->breakup = 0; - scb->data_len = 0; - scb->callback = ipsintr_done; - scb->timeout = ips_cmd_timeout; - memset(&scb->cmd, 0, 16); - - /* copy in the CDB */ - memcpy(scb->cdb, SC->cmnd, SC->cmd_len); - - /* Now handle the data buffer */ - if (SC->use_sg) { - struct scatterlist *sg; - int i; - - sg = SC->request_buffer; - scb->sg_count = pci_map_sg(ha->pcidev, sg, SC->use_sg, - scsi_to_pci_dma_dir(SC->sc_data_direction)); - scb->flags |= IPS_SCB_MAP_SG; - if (scb->sg_count == 1) { - if (sg_dma_len(sg) > ha->max_xfer) { - scb->breakup = 1; - scb->data_len = ha->max_xfer; - } else - scb->data_len = sg_dma_len(sg); - - scb->dcdb.transfer_length = scb->data_len; - scb->data_busaddr = sg_dma_address(sg); - scb->sg_len = 0; - } else { - /* Check for the first Element being bigger than MAX_XFER */ - if (sg_dma_len(&sg[0]) > ha->max_xfer) { - scb->sg_list[0].address = cpu_to_le32(sg_dma_address(&sg[0])); - scb->sg_list[0].length = ha->max_xfer; - scb->data_len = ha->max_xfer; - scb->breakup = 0; - scb->sg_break=1; - scb->sg_len = 1; - } else { - for (i = 0; i < scb->sg_count; i++) { - scb->sg_list[i].address = cpu_to_le32(sg_dma_address(&sg[i])); - scb->sg_list[i].length = cpu_to_le32(sg_dma_len(&sg[i])); - - if (scb->data_len + sg_dma_len(&sg[i]) > ha->max_xfer) { - /* - * Data Breakup required - */ - scb->breakup = i; - break; - } - - scb->data_len += sg_dma_len(&sg[i]); - } - - if (!scb->breakup) - scb->sg_len = scb->sg_count; - else - scb->sg_len = scb->breakup; - } - - scb->dcdb.transfer_length = scb->data_len; - scb->data_busaddr = scb->sg_busaddr; - } - } else { - if (SC->request_bufflen) { - if (SC->request_bufflen > ha->max_xfer) { - /* - * Data breakup required - */ - scb->breakup = 1; - scb->data_len = ha->max_xfer; - } else { - scb->data_len = SC->request_bufflen; - } - - scb->dcdb.transfer_length = scb->data_len; - scb->data_busaddr = pci_map_single(ha->pcidev, SC->request_buffer, - scb->data_len, - scsi_to_pci_dma_dir(SC->sc_data_direction)); - scb->flags |= IPS_SCB_MAP_SINGLE; - scb->sg_len = 0; - } else { - scb->data_busaddr = 0L; - scb->sg_len = 0; - scb->data_len = 0; - scb->dcdb.transfer_length = 0; - } - - } - - scb->dcdb.cmd_attribute = ips_command_direction[scb->scsi_cmd->cmnd[0]]; - - if (!scb->dcdb.cmd_attribute & 0x3) - scb->dcdb.transfer_length = 0; - - if (scb->data_len >= IPS_MAX_XFER) { - scb->dcdb.cmd_attribute |= IPS_TRANSFER64K; - scb->dcdb.transfer_length = 0; - } - if(intr == IPS_INTR_ON) - IPS_LOCK_SAVE(host->host_lock, cpu_flags); - - ret = ips_send_cmd(ha, scb); - - switch(ret) { - case IPS_SUCCESS: - ips_putq_scb_head(&ha->scb_activelist, scb); - break; - case IPS_FAILURE: - if (scb->scsi_cmd) { - scb->scsi_cmd->result = DID_ERROR << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); - } - - if (scb->bus) - ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id); - - ips_freescb(ha, scb); - break; - case IPS_SUCCESS_IMM: - if (scb->scsi_cmd) - scb->scsi_cmd->scsi_done(scb->scsi_cmd); - - if (scb->bus) - ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id); - - ips_freescb(ha, scb); - break; - default: - break; - } /* end case */ +ips_next(ips_ha_t * ha, int intr) +{ + ips_scb_t *scb; + Scsi_Cmnd *SC; + Scsi_Cmnd *p; + Scsi_Cmnd *q; + ips_copp_wait_item_t *item; + int ret; + unsigned long cpu_flags = 0; + struct Scsi_Host *host; + METHOD_TRACE("ips_next", 1); + + if (!ha) + return; + host = ips_sh[ha->host_num]; + /* + * Block access to the queue function so + * this command won't time out + */ + if (intr == IPS_INTR_ON) + IPS_LOCK_SAVE(host->host_lock, cpu_flags); + + if ((ha->subsys->param[3] & 0x300000) + && (ha->scb_activelist.count == 0)) { + struct timeval tv; + + do_gettimeofday(&tv); + + if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) { + ha->last_ffdc = tv.tv_sec; + ips_ffdc_time(ha); + } + } + + /* + * Send passthru commands + * These have priority over normal I/O + * but shouldn't affect performance too much + * since we limit the number that can be active + * on the card at any one time + */ + while ((ha->num_ioctl < IPS_MAX_IOCTL) && + (ha->copp_waitlist.head) && (scb = ips_getscb(ha))) { + + item = ips_removeq_copp_head(&ha->copp_waitlist); + ha->num_ioctl++; + if (intr == IPS_INTR_ON) + IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); + scb->scsi_cmd = item->scsi_cmd; + kfree(item); + + ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr); + + if (intr == IPS_INTR_ON) + IPS_LOCK_SAVE(host->host_lock, cpu_flags); + switch (ret) { + case IPS_FAILURE: + if (scb->scsi_cmd) { + scb->scsi_cmd->result = DID_ERROR << 16; + scb->scsi_cmd->scsi_done(scb->scsi_cmd); + } + + ips_freescb(ha, scb); + break; + case IPS_SUCCESS_IMM: + if (scb->scsi_cmd) { + scb->scsi_cmd->result = DID_OK << 16; + scb->scsi_cmd->scsi_done(scb->scsi_cmd); + } + + ips_freescb(ha, scb); + break; + default: + break; + } /* end case */ + + if (ret != IPS_SUCCESS) { + ha->num_ioctl--; + continue; + } + + ret = ips_send_cmd(ha, scb); + + if (ret == IPS_SUCCESS) + ips_putq_scb_head(&ha->scb_activelist, scb); + else + ha->num_ioctl--; + + switch (ret) { + case IPS_FAILURE: + if (scb->scsi_cmd) { + scb->scsi_cmd->result = DID_ERROR << 16; + } + + ips_freescb(ha, scb); + break; + case IPS_SUCCESS_IMM: + ips_freescb(ha, scb); + break; + default: + break; + } /* end case */ + + } + + /* + * Send "Normal" I/O commands + */ + + p = ha->scb_waitlist.head; + while ((p) && (scb = ips_getscb(ha))) { + if ((p->channel > 0) + && (ha->dcdb_active[p->channel - 1] & (1 << p->target))) { + ips_freescb(ha, scb); + p = (Scsi_Cmnd *) p->host_scribble; + continue; + } + + q = p; + SC = ips_removeq_wait(&ha->scb_waitlist, q); + + if (intr == IPS_INTR_ON) + IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); /* Unlock HA after command is taken off queue */ + + SC->result = DID_OK; + SC->host_scribble = NULL; + + memset(SC->sense_buffer, 0, sizeof (SC->sense_buffer)); + + scb->target_id = SC->target; + scb->lun = SC->lun; + scb->bus = SC->channel; + scb->scsi_cmd = SC; + scb->breakup = 0; + scb->data_len = 0; + scb->callback = ipsintr_done; + scb->timeout = ips_cmd_timeout; + memset(&scb->cmd, 0, 16); + + /* copy in the CDB */ + memcpy(scb->cdb, SC->cmnd, SC->cmd_len); + + /* Now handle the data buffer */ + if (SC->use_sg) { + struct scatterlist *sg; + int i; + + sg = SC->request_buffer; + scb->sg_count = pci_map_sg(ha->pcidev, sg, SC->use_sg, + scsi_to_pci_dma_dir(SC-> + sc_data_direction)); + scb->flags |= IPS_SCB_MAP_SG; + for (i = 0; i < scb->sg_count; i++) { + if (ips_fill_scb_sg_single + (ha, sg_dma_address(&sg[i]), scb, i, + sg_dma_len(&sg[i])) < 0) + break; + } + scb->dcdb.transfer_length = scb->data_len; + } else { + if (SC->request_bufflen) { + scb->data_busaddr = + pci_map_single(ha->pcidev, + SC->request_buffer, + SC->request_bufflen, + scsi_to_pci_dma_dir(SC-> + sc_data_direction)); + scb->flags |= IPS_SCB_MAP_SINGLE; + ips_fill_scb_sg_single(ha, scb->data_busaddr, + scb, 0, + SC->request_bufflen); + scb->dcdb.transfer_length = scb->data_len; + } else { + scb->data_busaddr = 0L; + scb->sg_len = 0; + scb->data_len = 0; + scb->dcdb.transfer_length = 0; + } + + } + + scb->dcdb.cmd_attribute = + ips_command_direction[scb->scsi_cmd->cmnd[0]]; + + /* Allow a WRITE BUFFER Command to Have no Data */ + /* This is Used by Tape Flash Utilites */ + if ((scb->scsi_cmd->cmnd[0] == WRITE_BUFFER) && (scb->data_len == 0)) + scb->dcdb.cmd_attribute = 0; + + if (!(scb->dcdb.cmd_attribute & 0x3)) + scb->dcdb.transfer_length = 0; + + if (scb->data_len >= IPS_MAX_XFER) { + scb->dcdb.cmd_attribute |= IPS_TRANSFER64K; + scb->dcdb.transfer_length = 0; + } + if (intr == IPS_INTR_ON) + IPS_LOCK_SAVE(host->host_lock, cpu_flags); + + ret = ips_send_cmd(ha, scb); + + switch (ret) { + case IPS_SUCCESS: + ips_putq_scb_head(&ha->scb_activelist, scb); + break; + case IPS_FAILURE: + if (scb->scsi_cmd) { + scb->scsi_cmd->result = DID_ERROR << 16; + scb->scsi_cmd->scsi_done(scb->scsi_cmd); + } + + if (scb->bus) + ha->dcdb_active[scb->bus - 1] &= + ~(1 << scb->target_id); + + ips_freescb(ha, scb); + break; + case IPS_SUCCESS_IMM: + if (scb->scsi_cmd) + scb->scsi_cmd->scsi_done(scb->scsi_cmd); + + if (scb->bus) + ha->dcdb_active[scb->bus - 1] &= + ~(1 << scb->target_id); + + ips_freescb(ha, scb); + break; + default: + break; + } /* end case */ - p = (Scsi_Cmnd *) p->host_scribble; + p = (Scsi_Cmnd *) p->host_scribble; - } /* end while */ + } /* end while */ - if(intr == IPS_INTR_ON) - IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); + if (intr == IPS_INTR_ON) + IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); } /****************************************************************************/ @@ -3540,19 +2853,20 @@ /* */ /****************************************************************************/ static inline void -ips_putq_scb_head(ips_scb_queue_t *queue, ips_scb_t *item) { - METHOD_TRACE("ips_putq_scb_head", 1); +ips_putq_scb_head(ips_scb_queue_t * queue, ips_scb_t * item) +{ + METHOD_TRACE("ips_putq_scb_head", 1); - if (!item) - return ; + if (!item) + return; - item->q_next = queue->head; - queue->head = item; + item->q_next = queue->head; + queue->head = item; - if (!queue->tail) - queue->tail = item; + if (!queue->tail) + queue->tail = item; - queue->count++; + queue->count++; } /****************************************************************************/ @@ -3567,23 +2881,24 @@ /* */ /****************************************************************************/ static inline void -ips_putq_scb_tail(ips_scb_queue_t *queue, ips_scb_t *item) { - METHOD_TRACE("ips_putq_scb_tail", 1); +ips_putq_scb_tail(ips_scb_queue_t * queue, ips_scb_t * item) +{ + METHOD_TRACE("ips_putq_scb_tail", 1); - if (!item) - return ; + if (!item) + return; - item->q_next = NULL; + item->q_next = NULL; - if (queue->tail) - queue->tail->q_next = item; + if (queue->tail) + queue->tail->q_next = item; - queue->tail = item; + queue->tail = item; - if (!queue->head) - queue->head = item; + if (!queue->head) + queue->head = item; - queue->count++; + queue->count++; } /****************************************************************************/ @@ -3598,26 +2913,27 @@ /* */ /****************************************************************************/ static inline ips_scb_t * -ips_removeq_scb_head(ips_scb_queue_t *queue) { - ips_scb_t *item; +ips_removeq_scb_head(ips_scb_queue_t * queue) +{ + ips_scb_t *item; - METHOD_TRACE("ips_removeq_scb_head", 1); + METHOD_TRACE("ips_removeq_scb_head", 1); - item = queue->head; + item = queue->head; - if (!item) { - return (NULL); - } + if (!item) { + return (NULL); + } - queue->head = item->q_next; - item->q_next = NULL; + queue->head = item->q_next; + item->q_next = NULL; - if (queue->tail == item) - queue->tail = NULL; + if (queue->tail == item) + queue->tail = NULL; - queue->count--; + queue->count--; - return (item); + return (item); } /****************************************************************************/ @@ -3632,37 +2948,38 @@ /* */ /****************************************************************************/ static inline ips_scb_t * -ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) { - ips_scb_t *p; +ips_removeq_scb(ips_scb_queue_t * queue, ips_scb_t * item) +{ + ips_scb_t *p; - METHOD_TRACE("ips_removeq_scb", 1); + METHOD_TRACE("ips_removeq_scb", 1); - if (!item) - return (NULL); + if (!item) + return (NULL); - if (item == queue->head) { - return (ips_removeq_scb_head(queue)); - } + if (item == queue->head) { + return (ips_removeq_scb_head(queue)); + } - p = queue->head; + p = queue->head; - while ((p) && (item != p->q_next)) - p = p->q_next; + while ((p) && (item != p->q_next)) + p = p->q_next; - if (p) { - /* found a match */ - p->q_next = item->q_next; + if (p) { + /* found a match */ + p->q_next = item->q_next; - if (!item->q_next) - queue->tail = p; + if (!item->q_next) + queue->tail = p; - item->q_next = NULL; - queue->count--; + item->q_next = NULL; + queue->count--; - return (item); - } + return (item); + } - return (NULL); + return (NULL); } /****************************************************************************/ @@ -3677,19 +2994,20 @@ /* */ /****************************************************************************/ static inline void -ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) { - METHOD_TRACE("ips_putq_wait_head", 1); +ips_putq_wait_head(ips_wait_queue_t * queue, Scsi_Cmnd * item) +{ + METHOD_TRACE("ips_putq_wait_head", 1); - if (!item) - return ; + if (!item) + return; - item->host_scribble = (char *) queue->head; - queue->head = item; + item->host_scribble = (char *) queue->head; + queue->head = item; - if (!queue->tail) - queue->tail = item; + if (!queue->tail) + queue->tail = item; - queue->count++; + queue->count++; } /****************************************************************************/ @@ -3704,23 +3022,24 @@ /* */ /****************************************************************************/ static inline void -ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) { - METHOD_TRACE("ips_putq_wait_tail", 1); +ips_putq_wait_tail(ips_wait_queue_t * queue, Scsi_Cmnd * item) +{ + METHOD_TRACE("ips_putq_wait_tail", 1); - if (!item) - return ; + if (!item) + return; - item->host_scribble = NULL; + item->host_scribble = NULL; - if (queue->tail) - queue->tail->host_scribble = (char *)item; + if (queue->tail) + queue->tail->host_scribble = (char *) item; - queue->tail = item; + queue->tail = item; - if (!queue->head) - queue->head = item; + if (!queue->head) + queue->head = item; - queue->count++; + queue->count++; } /****************************************************************************/ @@ -3735,26 +3054,27 @@ /* */ /****************************************************************************/ static inline Scsi_Cmnd * -ips_removeq_wait_head(ips_wait_queue_t *queue) { - Scsi_Cmnd *item; +ips_removeq_wait_head(ips_wait_queue_t * queue) +{ + Scsi_Cmnd *item; - METHOD_TRACE("ips_removeq_wait_head", 1); + METHOD_TRACE("ips_removeq_wait_head", 1); - item = queue->head; + item = queue->head; - if (!item) { - return (NULL); - } + if (!item) { + return (NULL); + } - queue->head = (Scsi_Cmnd *) item->host_scribble; - item->host_scribble = NULL; + queue->head = (Scsi_Cmnd *) item->host_scribble; + item->host_scribble = NULL; - if (queue->tail == item) - queue->tail = NULL; + if (queue->tail == item) + queue->tail = NULL; - queue->count--; + queue->count--; - return (item); + return (item); } /****************************************************************************/ @@ -3769,37 +3089,38 @@ /* */ /****************************************************************************/ static inline Scsi_Cmnd * -ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) { - Scsi_Cmnd *p; +ips_removeq_wait(ips_wait_queue_t * queue, Scsi_Cmnd * item) +{ + Scsi_Cmnd *p; - METHOD_TRACE("ips_removeq_wait", 1); + METHOD_TRACE("ips_removeq_wait", 1); - if (!item) - return (NULL); + if (!item) + return (NULL); - if (item == queue->head) { - return (ips_removeq_wait_head(queue)); - } + if (item == queue->head) { + return (ips_removeq_wait_head(queue)); + } - p = queue->head; + p = queue->head; - while ((p) && (item != (Scsi_Cmnd *) p->host_scribble)) - p = (Scsi_Cmnd *) p->host_scribble; + while ((p) && (item != (Scsi_Cmnd *) p->host_scribble)) + p = (Scsi_Cmnd *) p->host_scribble; - if (p) { - /* found a match */ - p->host_scribble = item->host_scribble; + if (p) { + /* found a match */ + p->host_scribble = item->host_scribble; - if (!item->host_scribble) - queue->tail = p; + if (!item->host_scribble) + queue->tail = p; - item->host_scribble = NULL; - queue->count--; + item->host_scribble = NULL; + queue->count--; - return (item); - } + return (item); + } - return (NULL); + return (NULL); } /****************************************************************************/ @@ -3814,19 +3135,20 @@ /* */ /****************************************************************************/ static inline void -ips_putq_copp_head(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { - METHOD_TRACE("ips_putq_copp_head", 1); +ips_putq_copp_head(ips_copp_queue_t * queue, ips_copp_wait_item_t * item) +{ + METHOD_TRACE("ips_putq_copp_head", 1); - if (!item) - return ; + if (!item) + return; - item->next = queue->head; - queue->head = item; + item->next = queue->head; + queue->head = item; - if (!queue->tail) - queue->tail = item; + if (!queue->tail) + queue->tail = item; - queue->count++; + queue->count++; } /****************************************************************************/ @@ -3841,23 +3163,24 @@ /* */ /****************************************************************************/ static inline void -ips_putq_copp_tail(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { - METHOD_TRACE("ips_putq_copp_tail", 1); +ips_putq_copp_tail(ips_copp_queue_t * queue, ips_copp_wait_item_t * item) +{ + METHOD_TRACE("ips_putq_copp_tail", 1); - if (!item) - return ; + if (!item) + return; - item->next = NULL; + item->next = NULL; - if (queue->tail) - queue->tail->next = item; + if (queue->tail) + queue->tail->next = item; - queue->tail = item; + queue->tail = item; - if (!queue->head) - queue->head = item; + if (!queue->head) + queue->head = item; - queue->count++; + queue->count++; } /****************************************************************************/ @@ -3872,26 +3195,27 @@ /* */ /****************************************************************************/ static inline ips_copp_wait_item_t * -ips_removeq_copp_head(ips_copp_queue_t *queue) { - ips_copp_wait_item_t *item; +ips_removeq_copp_head(ips_copp_queue_t * queue) +{ + ips_copp_wait_item_t *item; - METHOD_TRACE("ips_removeq_copp_head", 1); + METHOD_TRACE("ips_removeq_copp_head", 1); - item = queue->head; + item = queue->head; - if (!item) { - return (NULL); - } + if (!item) { + return (NULL); + } - queue->head = item->next; - item->next = NULL; + queue->head = item->next; + item->next = NULL; - if (queue->tail == item) - queue->tail = NULL; + if (queue->tail == item) + queue->tail = NULL; - queue->count--; + queue->count--; - return (item); + return (item); } /****************************************************************************/ @@ -3906,37 +3230,38 @@ /* */ /****************************************************************************/ static inline ips_copp_wait_item_t * -ips_removeq_copp(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { - ips_copp_wait_item_t *p; +ips_removeq_copp(ips_copp_queue_t * queue, ips_copp_wait_item_t * item) +{ + ips_copp_wait_item_t *p; - METHOD_TRACE("ips_removeq_copp", 1); + METHOD_TRACE("ips_removeq_copp", 1); - if (!item) - return (NULL); + if (!item) + return (NULL); - if (item == queue->head) { - return (ips_removeq_copp_head(queue)); - } + if (item == queue->head) { + return (ips_removeq_copp_head(queue)); + } - p = queue->head; + p = queue->head; - while ((p) && (item != p->next)) - p = p->next; + while ((p) && (item != p->next)) + p = p->next; - if (p) { - /* found a match */ - p->next = item->next; + if (p) { + /* found a match */ + p->next = item->next; - if (!item->next) - queue->tail = p; + if (!item->next) + queue->tail = p; - item->next = NULL; - queue->count--; + item->next = NULL; + queue->count--; - return (item); - } + return (item); + } - return (NULL); + return (NULL); } /****************************************************************************/ @@ -3949,16 +3274,16 @@ /* */ /****************************************************************************/ static void -ipsintr_blocking(ips_ha_t *ha, ips_scb_t *scb) { - METHOD_TRACE("ipsintr_blocking", 2); +ipsintr_blocking(ips_ha_t * ha, ips_scb_t * scb) +{ + METHOD_TRACE("ipsintr_blocking", 2); - ips_freescb(ha, scb); - if ((ha->waitflag == TRUE) && - (ha->cmd_in_progress == scb->cdb[0])) { - ha->waitflag = FALSE; + ips_freescb(ha, scb); + if ((ha->waitflag == TRUE) && (ha->cmd_in_progress == scb->cdb[0])) { + ha->waitflag = FALSE; - return ; - } + return; + } } /****************************************************************************/ @@ -3971,25 +3296,27 @@ /* */ /****************************************************************************/ static void -ipsintr_done(ips_ha_t *ha, ips_scb_t *scb) { - METHOD_TRACE("ipsintr_done", 2); +ipsintr_done(ips_ha_t * ha, ips_scb_t * scb) +{ + METHOD_TRACE("ipsintr_done", 2); - if (!scb) { - printk(KERN_WARNING "(%s%d) Spurious interrupt; scb NULL.\n", - ips_name, ha->host_num); + if (!scb) { + printk(KERN_WARNING "(%s%d) Spurious interrupt; scb NULL.\n", + ips_name, ha->host_num); - return ; - } + return; + } - if (scb->scsi_cmd == NULL) { - /* unexpected interrupt */ - printk(KERN_WARNING "(%s%d) Spurious interrupt; scsi_cmd not set.\n", - ips_name, ha->host_num); + if (scb->scsi_cmd == NULL) { + /* unexpected interrupt */ + printk(KERN_WARNING + "(%s%d) Spurious interrupt; scsi_cmd not set.\n", + ips_name, ha->host_num); - return; - } + return; + } - ips_done(ha, scb); + ips_done(ha, scb); } /****************************************************************************/ @@ -4002,180 +3329,118 @@ /* ASSUMED to be called form within the request lock */ /****************************************************************************/ static void -ips_done(ips_ha_t *ha, ips_scb_t *scb) { - int ret; +ips_done(ips_ha_t * ha, ips_scb_t * scb) +{ + int ret; - METHOD_TRACE("ips_done", 1); + METHOD_TRACE("ips_done", 1); - if (!scb) - return ; + if (!scb) + return; - if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) { - ips_cleanup_passthru(ha, scb); - ha->num_ioctl--; - } else { - /* - * Check to see if this command had too much - * data and had to be broke up. If so, queue - * the rest of the data and continue. - */ - if ((scb->breakup) || (scb->sg_break)) { - /* we had a data breakup */ - uint8_t bk_save; - - bk_save = scb->breakup; - scb->breakup = 0; - - if (scb->sg_count) { - /* S/G request */ - struct scatterlist *sg; - int i; - - sg = scb->scsi_cmd->request_buffer; - - if (scb->sg_count == 1) { - if (sg_dma_len(sg) - (bk_save * ha->max_xfer) > ha->max_xfer) { - /* Further breakup required */ - scb->data_len = ha->max_xfer; - scb->data_busaddr = sg_dma_address(sg) + (bk_save * ha->max_xfer); - scb->breakup = bk_save + 1; - } else { - scb->data_len = sg_dma_len(sg) - (bk_save * ha->max_xfer); - scb->data_busaddr = sg_dma_address(sg) + (bk_save * ha->max_xfer); - } - - scb->dcdb.transfer_length = scb->data_len; - scb->sg_len = 0; - } else { - /* We're here because there was MORE than one s/g unit. */ - /* bk_save points to which sg unit to look at */ - /* sg_break points to how far through this unit we are */ - /* NOTE: We will not move from one sg to another here, */ - /* just finish the one we are in. Not the most */ - /* efficient, but it keeps it from getting too hacky */ - - /* IF sg_break is non-zero, then just work on this current sg piece, */ - /* pointed to by bk_save */ - if (scb->sg_break) { - scb->sg_len = 1; - scb->sg_list[0].address = sg_dma_address(&sg[bk_save]) - + ha->max_xfer*scb->sg_break; - if (ha->max_xfer > sg_dma_len(&sg[bk_save]) - ha->max_xfer * scb->sg_break) - scb->sg_list[0].length = sg_dma_len(&sg[bk_save]) - ha->max_xfer * scb->sg_break; - else - scb->sg_list[0].length = ha->max_xfer; - scb->sg_break++; /* MUST GO HERE for math below to work */ - scb->data_len = scb->sg_list[0].length;; - - if (sg_dma_len(&sg[bk_save]) <= ha->max_xfer * scb->sg_break ) { - scb->sg_break = 0; /* No more work in this unit */ - if (( bk_save + 1 ) >= scb->sg_count) - scb->breakup = 0; - else - scb->breakup = bk_save + 1; - } - } else { - /* ( sg_break == 0 ), so this is our first look at a new sg piece */ - if (sg_dma_len(&sg[bk_save]) > ha->max_xfer) { - scb->sg_list[0].address = sg_dma_address(&sg[bk_save]); - scb->sg_list[0].length = ha->max_xfer; - scb->breakup = bk_save; - scb->sg_break = 1; - scb->data_len = ha->max_xfer; - scb->sg_len = 1; - } else { - /* OK, the next sg is a short one, so loop until full */ - scb->data_len = 0; - scb->sg_len = 0; - scb->sg_break = 0; - /* We're only doing full units here */ - for (i = bk_save; i < scb->sg_count; i++) { - scb->sg_list[i - bk_save].address = sg_dma_address(&sg[i]); - scb->sg_list[i - bk_save].length = cpu_to_le32(sg_dma_len(&sg[i])); - if (scb->data_len + sg_dma_len(&sg[i]) > ha->max_xfer) { - scb->breakup = i; /* sneaky, if not more work, than breakup is 0 */ - break; - } - scb->data_len += sg_dma_len(&sg[i]); - scb->sg_len++; /* only if we didn't get too big */ - } - } - } - - /* Also, we need to be sure we don't queue work ( breakup != 0 ) - if no more sg units for next time */ - scb->dcdb.transfer_length = scb->data_len; - scb->data_busaddr = scb->sg_busaddr; - } - - } else { - /* Non S/G Request */ - pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len, - IPS_DMA_DIR(scb)); - if ((scb->scsi_cmd->request_bufflen - (bk_save * ha->max_xfer)) > ha->max_xfer) { - /* Further breakup required */ - scb->data_len = ha->max_xfer; - scb->data_busaddr = pci_map_single(ha->pcidev, - scb->scsi_cmd->request_buffer + - (bk_save * ha->max_xfer), - scb->data_len, IPS_DMA_DIR(scb)); - scb->breakup = bk_save + 1; - } else { - scb->data_len = scb->scsi_cmd->request_bufflen - (bk_save * ha->max_xfer); - scb->data_busaddr = pci_map_single(ha->pcidev, - scb->scsi_cmd->request_buffer + - (bk_save * ha->max_xfer), - scb->data_len, IPS_DMA_DIR(scb)); - } - - scb->dcdb.transfer_length = scb->data_len; - scb->sg_len = 0; - } - - scb->dcdb.cmd_attribute |= ips_command_direction[scb->scsi_cmd->cmnd[0]]; - - if (!scb->dcdb.cmd_attribute & 0x3) - scb->dcdb.transfer_length = 0; - - if (scb->data_len >= IPS_MAX_XFER) { - scb->dcdb.cmd_attribute |= IPS_TRANSFER64K; - scb->dcdb.transfer_length = 0; - } - - ret = ips_send_cmd(ha, scb); - - switch(ret) { - case IPS_FAILURE: - if (scb->scsi_cmd) { - scb->scsi_cmd->result = DID_ERROR << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); - } - - ips_freescb(ha, scb); - break; - case IPS_SUCCESS_IMM: - if (scb->scsi_cmd) { - scb->scsi_cmd->result = DID_ERROR << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); - } - - ips_freescb(ha, scb); - break; - default: - break; - } /* end case */ - - return ; - } - } /* end if passthru */ - - if (scb->bus) { - ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id); - } + if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) { + ips_cleanup_passthru(ha, scb); + ha->num_ioctl--; + } else { + /* + * Check to see if this command had too much + * data and had to be broke up. If so, queue + * the rest of the data and continue. + */ + if ((scb->breakup) || (scb->sg_break)) { + /* we had a data breakup */ + scb->data_len = 0; + + if (scb->sg_count) { + /* S/G request */ + struct scatterlist *sg; + int ips_sg_index = 0; + int sg_dma_index; + + sg = scb->scsi_cmd->request_buffer; + + /* Spin forward to last dma chunk */ + sg_dma_index = scb->breakup; + + /* Take care of possible partial on last chunk */ + ips_fill_scb_sg_single(ha, + sg_dma_address(&sg + [sg_dma_index]), + scb, ips_sg_index++, + sg_dma_len(&sg + [sg_dma_index])); + + for (; sg_dma_index < scb->sg_count; + sg_dma_index++) { + if (ips_fill_scb_sg_single + (ha, + sg_dma_address(&sg[sg_dma_index]), + scb, ips_sg_index++, + sg_dma_len(&sg[sg_dma_index])) < 0) + break; + + } + + } else { + /* Non S/G Request */ + (void) ips_fill_scb_sg_single(ha, + scb-> + data_busaddr + + (scb->sg_break * + ha->max_xfer), + scb, 0, + scb->scsi_cmd-> + request_bufflen - + (scb->sg_break * + ha->max_xfer)); + } + + scb->dcdb.transfer_length = scb->data_len; + scb->dcdb.cmd_attribute |= + ips_command_direction[scb->scsi_cmd->cmnd[0]]; + + if (!(scb->dcdb.cmd_attribute & 0x3)) + scb->dcdb.transfer_length = 0; + + if (scb->data_len >= IPS_MAX_XFER) { + scb->dcdb.cmd_attribute |= IPS_TRANSFER64K; + scb->dcdb.transfer_length = 0; + } + + ret = ips_send_cmd(ha, scb); + + switch (ret) { + case IPS_FAILURE: + if (scb->scsi_cmd) { + scb->scsi_cmd->result = DID_ERROR << 16; + scb->scsi_cmd->scsi_done(scb->scsi_cmd); + } + + ips_freescb(ha, scb); + break; + case IPS_SUCCESS_IMM: + if (scb->scsi_cmd) { + scb->scsi_cmd->result = DID_ERROR << 16; + scb->scsi_cmd->scsi_done(scb->scsi_cmd); + } + + ips_freescb(ha, scb); + break; + default: + break; + } /* end case */ + + return; + } + } /* end if passthru */ + + if (scb->bus) { + ha->dcdb_active[scb->bus - 1] &= ~(1 << scb->target_id); + } - scb->scsi_cmd->scsi_done(scb->scsi_cmd); + scb->scsi_cmd->scsi_done(scb->scsi_cmd); - ips_freescb(ha, scb); + ips_freescb(ha, scb); } /****************************************************************************/ @@ -4188,118 +3453,130 @@ /* */ /****************************************************************************/ static int -ips_map_status(ips_ha_t *ha, ips_scb_t *scb, ips_stat_t *sp) { - int errcode; - int device_error; - uint32_t transfer_len; - IPS_DCDB_TABLE_TAPE *tapeDCDB; - - METHOD_TRACE("ips_map_status", 1); - - if (scb->bus) { - DEBUG_VAR(2, "(%s%d) Physical device error (%d %d %d): %x %x, Sense Key: %x, ASC: %x, ASCQ: %x", - ips_name, - ha->host_num, - scb->scsi_cmd->channel, - scb->scsi_cmd->target, - scb->scsi_cmd->lun, - scb->basic_status, - scb->extended_status, - scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0, - scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[12] : 0, - scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[13] : 0); - } - - /* default driver error */ - errcode = DID_ERROR; - device_error = 0; - - switch (scb->basic_status & IPS_GSC_STATUS_MASK) { - case IPS_CMD_TIMEOUT: - errcode = DID_TIME_OUT; - break; - - case IPS_INVAL_OPCO: - case IPS_INVAL_CMD_BLK: - case IPS_INVAL_PARM_BLK: - case IPS_LD_ERROR: - case IPS_CMD_CMPLT_WERROR: - break; - - case IPS_PHYS_DRV_ERROR: - switch (scb->extended_status) { - case IPS_ERR_SEL_TO: - if (scb->bus) - errcode = DID_NO_CONNECT; - - break; - - case IPS_ERR_OU_RUN: - if ( ( scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB ) || - ( scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG ) ) { - tapeDCDB = ( IPS_DCDB_TABLE_TAPE * ) &scb->dcdb; - transfer_len = tapeDCDB->transfer_length; - } else { - transfer_len = ( uint32_t ) scb->dcdb.transfer_length; - } - - if ((scb->bus) && (transfer_len < scb->data_len)) { - /* Underrun - set default to no error */ - errcode = DID_OK; - - /* Restrict access to physical DASD */ - if ((scb->scsi_cmd->cmnd[0] == INQUIRY) && - ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) == TYPE_DISK)) { - /* underflow -- no error */ - /* restrict access to physical DASD */ - errcode = DID_TIME_OUT; - break; - } - } else - errcode = DID_ERROR; - - break; - - case IPS_ERR_RECOVERY: - /* don't fail recovered errors */ - if (scb->bus) - errcode = DID_OK; - - break; - - case IPS_ERR_HOST_RESET: - case IPS_ERR_DEV_RESET: - errcode = DID_RESET; - break; - - case IPS_ERR_CKCOND: - if (scb->bus) { - if ((scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB) || - (scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG)) { - tapeDCDB = (IPS_DCDB_TABLE_TAPE *) &scb->dcdb; - memcpy(scb->scsi_cmd->sense_buffer, tapeDCDB->sense_info, - sizeof(scb->scsi_cmd->sense_buffer)); - } else { - memcpy(scb->scsi_cmd->sense_buffer, scb->dcdb.sense_info, - sizeof(scb->scsi_cmd->sense_buffer)); - } - device_error = 2; /* check condition */ - } - - errcode = DID_OK; - - break; - - default: - errcode = DID_ERROR; - break; +ips_map_status(ips_ha_t * ha, ips_scb_t * scb, ips_stat_t * sp) +{ + int errcode; + int device_error; + uint32_t transfer_len; + IPS_DCDB_TABLE_TAPE *tapeDCDB; + + METHOD_TRACE("ips_map_status", 1); + + if (scb->bus) { + DEBUG_VAR(2, + "(%s%d) Physical device error (%d %d %d): %x %x, Sense Key: %x, ASC: %x, ASCQ: %x", + ips_name, ha->host_num, scb->scsi_cmd->channel, + scb->scsi_cmd->target, scb->scsi_cmd->lun, + scb->basic_status, scb->extended_status, + scb->extended_status == + IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0, + scb->extended_status == + IPS_ERR_CKCOND ? scb->dcdb.sense_info[12] : 0, + scb->extended_status == + IPS_ERR_CKCOND ? scb->dcdb.sense_info[13] : 0); + } + + /* default driver error */ + errcode = DID_ERROR; + device_error = 0; + + switch (scb->basic_status & IPS_GSC_STATUS_MASK) { + case IPS_CMD_TIMEOUT: + errcode = DID_TIME_OUT; + break; + + case IPS_INVAL_OPCO: + case IPS_INVAL_CMD_BLK: + case IPS_INVAL_PARM_BLK: + case IPS_LD_ERROR: + case IPS_CMD_CMPLT_WERROR: + break; + + case IPS_PHYS_DRV_ERROR: + switch (scb->extended_status) { + case IPS_ERR_SEL_TO: + if (scb->bus) + errcode = DID_NO_CONNECT; + + break; + + case IPS_ERR_OU_RUN: + if ((scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB) || + (scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG)) { + tapeDCDB = (IPS_DCDB_TABLE_TAPE *) & scb->dcdb; + transfer_len = tapeDCDB->transfer_length; + } else { + transfer_len = + (uint32_t) scb->dcdb.transfer_length; + } + + if ((scb->bus) && (transfer_len < scb->data_len)) { + /* Underrun - set default to no error */ + errcode = DID_OK; + + /* Restrict access to physical DASD */ + if ((scb->scsi_cmd->cmnd[0] == INQUIRY) && + ((((char + *) scb->scsi_cmd->buffer)[0] & 0x1f) == + TYPE_DISK)) { + /* underflow -- no error */ + /* restrict access to physical DASD */ + errcode = DID_TIME_OUT; + break; + } + } else + errcode = DID_ERROR; + + break; + + case IPS_ERR_RECOVERY: + /* don't fail recovered errors */ + if (scb->bus) + errcode = DID_OK; + + break; + + case IPS_ERR_HOST_RESET: + case IPS_ERR_DEV_RESET: + errcode = DID_RESET; + break; + + case IPS_ERR_CKCOND: + if (scb->bus) { + if ( + (scb->cmd.dcdb.op_code == + IPS_CMD_EXTENDED_DCDB) + || (scb->cmd.dcdb.op_code == + IPS_CMD_EXTENDED_DCDB_SG)) { + tapeDCDB = + (IPS_DCDB_TABLE_TAPE *) & scb->dcdb; + memcpy(scb->scsi_cmd->sense_buffer, + tapeDCDB->sense_info, + sizeof (scb->scsi_cmd-> + sense_buffer)); + } else { + memcpy(scb->scsi_cmd->sense_buffer, + scb->dcdb.sense_info, + sizeof (scb->scsi_cmd-> + sense_buffer)); + } + device_error = 2; /* check condition */ + } + + errcode = DID_OK; + + break; + + default: + errcode = DID_ERROR; + break; - } /* end switch */ - } /* end switch */ + } /* end switch */ + } /* end switch */ - scb->scsi_cmd->result = device_error | (errcode << 16); + scb->scsi_cmd->result = device_error | (errcode << 16); - return (1); + return (1); } /****************************************************************************/ @@ -4314,25 +3591,90 @@ /* actually need to wait. */ /****************************************************************************/ static int -ips_send_wait(ips_ha_t *ha, ips_scb_t *scb, int timeout, int intr) { - int ret; +ips_send_wait(ips_ha_t * ha, ips_scb_t * scb, int timeout, int intr) +{ + int ret; + + METHOD_TRACE("ips_send_wait", 1); - METHOD_TRACE("ips_send_wait", 1); + if (intr != IPS_FFDC) { /* Won't be Waiting if this is a Time Stamp */ + ha->waitflag = TRUE; + ha->cmd_in_progress = scb->cdb[0]; + } + scb->callback = ipsintr_blocking; + ret = ips_send_cmd(ha, scb); - if (intr != IPS_FFDC) { /* Won't be Waiting if this is a Time Stamp */ - ha->waitflag = TRUE; - ha->cmd_in_progress = scb->cdb[0]; - } - scb->callback = ipsintr_blocking; - ret = ips_send_cmd(ha, scb); + if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM)) + return (ret); - if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM)) - return (ret); + if (intr != IPS_FFDC) /* Don't Wait around if this is a Time Stamp */ + ret = ips_wait(ha, timeout, intr); + + return (ret); +} - if (intr != IPS_FFDC) /* Don't Wait around if this is a Time Stamp */ - ret = ips_wait(ha, timeout, intr); +/****************************************************************************/ +/* */ +/* Routine Name: ips_scmd_buf_write */ +/* */ +/* Routine Description: */ +/* Write data to Scsi_Cmnd request_buffer at proper offsets */ +/****************************************************************************/ +static void +ips_scmd_buf_write(Scsi_Cmnd * scmd, void *data, unsigned + int count) +{ + if (scmd->use_sg) { + int i; + unsigned int min_cnt, xfer_cnt; + char *cdata = (char *) data; + struct scatterlist *sg = scmd->request_buffer; + for (i = 0, xfer_cnt = 0; + (i < scmd->use_sg) && (xfer_cnt < count); i++) { + if (!IPS_SG_ADDRESS(&sg[i])) + return; + min_cnt = min(count - xfer_cnt, sg[i].length); + memcpy(IPS_SG_ADDRESS(&sg[i]), &cdata[xfer_cnt], + min_cnt); + xfer_cnt += min_cnt; + } + + } else { + unsigned int min_cnt = min(count, scmd->request_bufflen); + memcpy(scmd->request_buffer, data, min_cnt); + } +} - return (ret); +/****************************************************************************/ +/* */ +/* Routine Name: ips_scmd_buf_read */ +/* */ +/* Routine Description: */ +/* Copy data from a Scsi_Cmnd to a new, linear buffer */ +/****************************************************************************/ +static void +ips_scmd_buf_read(Scsi_Cmnd * scmd, void *data, unsigned + int count) +{ + if (scmd->use_sg) { + int i; + unsigned int min_cnt, xfer_cnt; + char *cdata = (char *) data; + struct scatterlist *sg = scmd->request_buffer; + for (i = 0, xfer_cnt = 0; + (i < scmd->use_sg) && (xfer_cnt < count); i++) { + if (!IPS_SG_ADDRESS(&sg[i])) + return; + min_cnt = min(count - xfer_cnt, sg[i].length); + memcpy(&cdata[xfer_cnt], IPS_SG_ADDRESS(&sg[i]), + min_cnt); + xfer_cnt += min_cnt; + } + + } else { + unsigned int min_cnt = min(count, scmd->request_bufflen); + memcpy(data, scmd->request_buffer, min_cnt); + } } /****************************************************************************/ @@ -4345,288 +3687,384 @@ /* */ /****************************************************************************/ static int -ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { - int ret; - char *sp; - int device_error; - IPS_DCDB_TABLE_TAPE *tapeDCDB; - int TimeOut; - - METHOD_TRACE("ips_send_cmd", 1); - - ret = IPS_SUCCESS; - - if (!scb->scsi_cmd) { - /* internal command */ - - if (scb->bus > 0) { - /* Controller commands can't be issued */ - /* to real devices -- fail them */ - if ((ha->waitflag == TRUE) && - (ha->cmd_in_progress == scb->cdb[0])) { - ha->waitflag = FALSE; - } - - return (1); - } - } else if ((scb->bus == 0) && (!ips_is_passthru(scb->scsi_cmd))) { - /* command to logical bus -- interpret */ - if(ha->scb_waitlist.count + ha->scb_activelist.count > 32) - mod_timer(&scb->scsi_cmd->eh_timeout, jiffies + 120 * HZ); - ret = IPS_SUCCESS_IMM; - - switch (scb->scsi_cmd->cmnd[0]) { - case ALLOW_MEDIUM_REMOVAL: - case REZERO_UNIT: - case ERASE: - case WRITE_FILEMARKS: - case SPACE: - scb->scsi_cmd->result = DID_ERROR << 16; - break; - - case START_STOP: - scb->scsi_cmd->result = DID_OK << 16; - - case TEST_UNIT_READY: - case INQUIRY: - scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO; - scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.logical_info.reserved = 0; - scb->cmd.logical_info.reserved2 = 0; - scb->data_len = sizeof(ha->adapt->logical_drive_info); - scb->data_busaddr = pci_map_single(ha->pcidev, - &ha->adapt->logical_drive_info, - scb->data_len, IPS_DMA_DIR(scb)); - scb->flags |= IPS_SCB_MAP_SINGLE; - scb->cmd.logical_info.buffer_addr = scb->data_busaddr; - ret = IPS_SUCCESS; - break; - - case REQUEST_SENSE: - ips_reqsen(ha, scb); - scb->scsi_cmd->result = DID_OK << 16; - break; - - case READ_6: - case WRITE_6: - if (!scb->sg_len) { - scb->cmd.basic_io.op_code = - (scb->scsi_cmd->cmnd[0] == READ_6) ? IPS_CMD_READ : IPS_CMD_WRITE; - } else { - scb->cmd.basic_io.op_code = - (scb->scsi_cmd->cmnd[0] == READ_6) ? IPS_CMD_READ_SG : IPS_CMD_WRITE_SG; - } - - scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.basic_io.log_drv = scb->target_id; - scb->cmd.basic_io.sg_count = scb->sg_len; - scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr); - - if (scb->cmd.basic_io.lba) - scb->cmd.basic_io.lba = cpu_to_le32(le32_to_cpu(scb->cmd.basic_io.lba) + - le16_to_cpu(scb->cmd.basic_io.sector_count)); - else - scb->cmd.basic_io.lba = (((scb->scsi_cmd->cmnd[1] & 0x1f) << 16) | - (scb->scsi_cmd->cmnd[2] << 8) | - (scb->scsi_cmd->cmnd[3])); - - scb->cmd.basic_io.sector_count = cpu_to_le16(scb->data_len / IPS_BLKSIZE); - - if (le16_to_cpu(scb->cmd.basic_io.sector_count) == 0) - scb->cmd.basic_io.sector_count = cpu_to_le16(256); - - scb->cmd.basic_io.reserved = 0; - ret = IPS_SUCCESS; - break; - - case READ_10: - case WRITE_10: - if (!scb->sg_len) { - scb->cmd.basic_io.op_code = - (scb->scsi_cmd->cmnd[0] == READ_10) ? IPS_CMD_READ : IPS_CMD_WRITE; - } else { - scb->cmd.basic_io.op_code = - (scb->scsi_cmd->cmnd[0] == READ_10) ? IPS_CMD_READ_SG : IPS_CMD_WRITE_SG; - } - - scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.basic_io.log_drv = scb->target_id; - scb->cmd.basic_io.sg_count = scb->sg_len; - scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr); - - if (scb->cmd.basic_io.lba) - scb->cmd.basic_io.lba = cpu_to_le32(le32_to_cpu(scb->cmd.basic_io.lba) + - le16_to_cpu(scb->cmd.basic_io.sector_count)); - else - scb->cmd.basic_io.lba = ((scb->scsi_cmd->cmnd[2] << 24) | - (scb->scsi_cmd->cmnd[3] << 16) | - (scb->scsi_cmd->cmnd[4] << 8) | - scb->scsi_cmd->cmnd[5]); - - scb->cmd.basic_io.sector_count = cpu_to_le16(scb->data_len / IPS_BLKSIZE); - - scb->cmd.basic_io.reserved = 0; - - if (cpu_to_le16(scb->cmd.basic_io.sector_count) == 0) { - /* - * This is a null condition - * we don't have to do anything - * so just return - */ - scb->scsi_cmd->result = DID_OK << 16; - } else - ret = IPS_SUCCESS; - - break; - - case RESERVE: - case RELEASE: - scb->scsi_cmd->result = DID_OK << 16; - break; - - case MODE_SENSE: - scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY; - scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); - scb->data_len = sizeof(*ha->enq); - scb->data_busaddr = pci_map_single(ha->pcidev, ha->enq, - scb->data_len, IPS_DMA_DIR(scb)); - scb->cmd.basic_io.sg_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; - ret = IPS_SUCCESS; - break; - - case READ_CAPACITY: - scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO; - scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.logical_info.reserved = 0; - scb->cmd.logical_info.reserved2 = 0; - scb->cmd.logical_info.reserved3 = 0; - scb->data_len = sizeof(ha->adapt->logical_drive_info); - scb->data_busaddr = pci_map_single(ha->pcidev, - &ha->adapt->logical_drive_info, - scb->data_len, IPS_DMA_DIR(scb)); - scb->flags |= IPS_SCB_MAP_SINGLE; - scb->cmd.logical_info.buffer_addr = scb->data_busaddr; - ret = IPS_SUCCESS; - break; - - case SEND_DIAGNOSTIC: - case REASSIGN_BLOCKS: - case FORMAT_UNIT: - case SEEK_10: - case VERIFY: - case READ_DEFECT_DATA: - case READ_BUFFER: - case WRITE_BUFFER: - scb->scsi_cmd->result = DID_OK << 16; - break; - - default: - /* Set the Return Info to appear like the Command was */ - /* attempted, a Check Condition occurred, and Sense */ - /* Data indicating an Invalid CDB OpCode is returned. */ - sp = (char *) scb->scsi_cmd->sense_buffer; - memset(sp, 0, sizeof(scb->scsi_cmd->sense_buffer)); - - sp[0] = 0x70; /* Error Code */ - sp[2] = ILLEGAL_REQUEST; /* Sense Key 5 Illegal Req. */ - sp[7] = 0x0A; /* Additional Sense Length */ - sp[12] = 0x20; /* ASC = Invalid OpCode */ - sp[13] = 0x00; /* ASCQ */ - - device_error = 2; /* Indicate Check Condition */ - scb->scsi_cmd->result = device_error | (DID_OK << 16); - break; - } /* end switch */ - } /* end if */ - - if (ret == IPS_SUCCESS_IMM) - return (ret); - - /* setup DCDB */ - if (scb->bus > 0) { - if (!scb->sg_len) - scb->cmd.dcdb.op_code = IPS_CMD_DCDB; - else - scb->cmd.dcdb.op_code = IPS_CMD_DCDB_SG; - - /* If we already know the Device is Not there, no need to attempt a Command */ - /* This also protects an NT FailOver Controller from getting CDB's sent to it */ - if ( ha->conf->dev[scb->bus-1][scb->target_id].ucState == 0 ) { - scb->scsi_cmd->result = DID_NO_CONNECT << 16; - return (IPS_SUCCESS_IMM); - } - - ha->dcdb_active[scb->bus-1] |= (1 << scb->target_id); - scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr + - (unsigned long)&scb->dcdb - - (unsigned long)scb); - scb->cmd.dcdb.reserved = 0; - scb->cmd.dcdb.reserved2 = 0; - scb->cmd.dcdb.reserved3 = 0; - - TimeOut = scb->scsi_cmd->timeout_per_command; - - if (ha->subsys->param[4] & 0x00100000) { /* If NEW Tape DCDB is Supported */ - if (!scb->sg_len) - scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB; - else - scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB_SG; - - tapeDCDB = (IPS_DCDB_TABLE_TAPE *) &scb->dcdb; /* Use Same Data Area as Old DCDB Struct */ - tapeDCDB->device_address = ((scb->bus - 1) << 4) | scb->target_id; - tapeDCDB->cmd_attribute |= IPS_DISCONNECT_ALLOWED; - tapeDCDB->cmd_attribute &= ~IPS_TRANSFER64K; /* Always Turn OFF 64K Size Flag */ - - if (TimeOut) { - if (TimeOut < ( 10 * HZ )) - tapeDCDB->cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */ - else if (TimeOut < (60 * HZ)) - tapeDCDB->cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */ - else if (TimeOut < (1200 * HZ)) - tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */ - } - - tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len; - tapeDCDB->reserved_for_LUN = 0; - tapeDCDB->transfer_length = scb->data_len; - tapeDCDB->buffer_pointer = cpu_to_le32(scb->data_busaddr); - tapeDCDB->sg_count = scb->sg_len; - tapeDCDB->sense_length = sizeof(tapeDCDB->sense_info); - tapeDCDB->scsi_status = 0; - tapeDCDB->reserved = 0; - memcpy(tapeDCDB->scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len); - } else { - scb->dcdb.device_address = ((scb->bus - 1) << 4) | scb->target_id; - scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED; - - if (TimeOut) { - if (TimeOut < (10 * HZ)) - scb->dcdb.cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */ - else if (TimeOut < (60 * HZ)) - scb->dcdb.cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */ - else if (TimeOut < (1200 * HZ)) - scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */ - } - - scb->dcdb.transfer_length = scb->data_len; - if ( scb->dcdb.cmd_attribute & IPS_TRANSFER64K ) - scb->dcdb.transfer_length = 0; - scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr); - scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len; - scb->dcdb.sense_length = sizeof(scb->dcdb.sense_info); - scb->dcdb.sg_count = scb->sg_len; - scb->dcdb.reserved = 0; - memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len); - scb->dcdb.scsi_status = 0; - scb->dcdb.reserved2[0] = 0; - scb->dcdb.reserved2[1] = 0; - scb->dcdb.reserved2[2] = 0; - } - } +ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb) +{ + int ret; + char *sp; + int device_error; + IPS_DCDB_TABLE_TAPE *tapeDCDB; + int TimeOut; + + METHOD_TRACE("ips_send_cmd", 1); + + ret = IPS_SUCCESS; + + if (!scb->scsi_cmd) { + /* internal command */ + + if (scb->bus > 0) { + /* Controller commands can't be issued */ + /* to real devices -- fail them */ + if ((ha->waitflag == TRUE) && + (ha->cmd_in_progress == scb->cdb[0])) { + ha->waitflag = FALSE; + } + + return (1); + } + } else if ((scb->bus == 0) && (!ips_is_passthru(scb->scsi_cmd))) { + /* command to logical bus -- interpret */ + ret = IPS_SUCCESS_IMM; + + switch (scb->scsi_cmd->cmnd[0]) { + case ALLOW_MEDIUM_REMOVAL: + case REZERO_UNIT: + case ERASE: + case WRITE_FILEMARKS: + case SPACE: + scb->scsi_cmd->result = DID_ERROR << 16; + break; + + case START_STOP: + scb->scsi_cmd->result = DID_OK << 16; + + case TEST_UNIT_READY: + case INQUIRY: + if (scb->target_id == IPS_ADAPTER_ID) { + /* + * Either we have a TUR + * or we have a SCSI inquiry + */ + if (scb->scsi_cmd->cmnd[0] == TEST_UNIT_READY) + scb->scsi_cmd->result = DID_OK << 16; + + if (scb->scsi_cmd->cmnd[0] == INQUIRY) { + IPS_SCSI_INQ_DATA inquiry; + + memset(&inquiry, 0, + sizeof (IPS_SCSI_INQ_DATA)); + + inquiry.DeviceType = + IPS_SCSI_INQ_TYPE_PROCESSOR; + inquiry.DeviceTypeQualifier = + IPS_SCSI_INQ_LU_CONNECTED; + inquiry.Version = IPS_SCSI_INQ_REV2; + inquiry.ResponseDataFormat = + IPS_SCSI_INQ_RD_REV2; + inquiry.AdditionalLength = 31; + inquiry.Flags[0] = + IPS_SCSI_INQ_Address16; + inquiry.Flags[1] = + IPS_SCSI_INQ_WBus16 | + IPS_SCSI_INQ_Sync; + strncpy(inquiry.VendorId, "IBM ", + 8); + strncpy(inquiry.ProductId, + "SERVERAID ", 16); + strncpy(inquiry.ProductRevisionLevel, + "1.00", 4); + + ips_scmd_buf_write(scb->scsi_cmd, + &inquiry, + sizeof (inquiry)); + + scb->scsi_cmd->result = DID_OK << 16; + } + } else { + scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO; + scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.logical_info.reserved = 0; + scb->cmd.logical_info.reserved2 = 0; + scb->data_len = sizeof (IPS_LD_INFO); + scb->data_busaddr = ha->logical_drive_info_dma_addr; + scb->flags = 0; + scb->cmd.logical_info.buffer_addr = scb->data_busaddr; + ret = IPS_SUCCESS; + } + + break; + + case REQUEST_SENSE: + ips_reqsen(ha, scb); + scb->scsi_cmd->result = DID_OK << 16; + break; + + case READ_6: + case WRITE_6: + if (!scb->sg_len) { + scb->cmd.basic_io.op_code = + (scb->scsi_cmd->cmnd[0] == + READ_6) ? IPS_CMD_READ : IPS_CMD_WRITE; + scb->cmd.basic_io.enhanced_sg = 0; + scb->cmd.basic_io.sg_addr = + cpu_to_le32(scb->data_busaddr); + } else { + scb->cmd.basic_io.op_code = + (scb->scsi_cmd->cmnd[0] == + READ_6) ? IPS_CMD_READ_SG : + IPS_CMD_WRITE_SG; + scb->cmd.basic_io.enhanced_sg = + IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0; + scb->cmd.basic_io.sg_addr = + cpu_to_le32(scb->sg_busaddr); + } + + scb->cmd.basic_io.segment_4G = 0; + scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.basic_io.log_drv = scb->target_id; + scb->cmd.basic_io.sg_count = scb->sg_len; + + if (scb->cmd.basic_io.lba) + scb->cmd.basic_io.lba = + cpu_to_le32(le32_to_cpu + (scb->cmd.basic_io.lba) + + le16_to_cpu(scb->cmd.basic_io. + sector_count)); + else + scb->cmd.basic_io.lba = + (((scb-> + scsi_cmd->cmnd[1] & 0x1f) << 16) | (scb-> + scsi_cmd-> + cmnd + [2] + << 8) + | (scb->scsi_cmd->cmnd[3])); + + scb->cmd.basic_io.sector_count = + cpu_to_le16(scb->data_len / IPS_BLKSIZE); + + if (le16_to_cpu(scb->cmd.basic_io.sector_count) == 0) + scb->cmd.basic_io.sector_count = + cpu_to_le16(256); + + ret = IPS_SUCCESS; + break; + + case READ_10: + case WRITE_10: + if (!scb->sg_len) { + scb->cmd.basic_io.op_code = + (scb->scsi_cmd->cmnd[0] == + READ_10) ? IPS_CMD_READ : IPS_CMD_WRITE; + scb->cmd.basic_io.enhanced_sg = 0; + scb->cmd.basic_io.sg_addr = + cpu_to_le32(scb->data_busaddr); + } else { + scb->cmd.basic_io.op_code = + (scb->scsi_cmd->cmnd[0] == + READ_10) ? IPS_CMD_READ_SG : + IPS_CMD_WRITE_SG; + scb->cmd.basic_io.enhanced_sg = + IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0; + scb->cmd.basic_io.sg_addr = + cpu_to_le32(scb->sg_busaddr); + } + + scb->cmd.basic_io.segment_4G = 0; + scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.basic_io.log_drv = scb->target_id; + scb->cmd.basic_io.sg_count = scb->sg_len; + + if (scb->cmd.basic_io.lba) + scb->cmd.basic_io.lba = + cpu_to_le32(le32_to_cpu + (scb->cmd.basic_io.lba) + + le16_to_cpu(scb->cmd.basic_io. + sector_count)); + else + scb->cmd.basic_io.lba = + ((scb-> + scsi_cmd->cmnd[2] << 24) | (scb-> + scsi_cmd-> + cmnd[3] << 16) + | (scb->scsi_cmd->cmnd[4] << 8) | scb-> + scsi_cmd->cmnd[5]); + + scb->cmd.basic_io.sector_count = + cpu_to_le16(scb->data_len / IPS_BLKSIZE); + + if (cpu_to_le16(scb->cmd.basic_io.sector_count) == 0) { + /* + * This is a null condition + * we don't have to do anything + * so just return + */ + scb->scsi_cmd->result = DID_OK << 16; + } else + ret = IPS_SUCCESS; + + break; + + case RESERVE: + case RELEASE: + scb->scsi_cmd->result = DID_OK << 16; + break; + + case MODE_SENSE: + scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY; + scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.basic_io.segment_4G = 0; + scb->cmd.basic_io.enhanced_sg = 0; + scb->data_len = sizeof (*ha->enq); + scb->cmd.basic_io.sg_addr = ha->enq_busaddr; + ret = IPS_SUCCESS; + break; + + case READ_CAPACITY: + scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO; + scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.logical_info.reserved = 0; + scb->cmd.logical_info.reserved2 = 0; + scb->cmd.logical_info.reserved3 = 0; + scb->data_len = sizeof (IPS_LD_INFO); + scb->data_busaddr = ha->logical_drive_info_dma_addr; + scb->flags = 0; + scb->cmd.logical_info.buffer_addr = scb->data_busaddr; + ret = IPS_SUCCESS; + break; + + case SEND_DIAGNOSTIC: + case REASSIGN_BLOCKS: + case FORMAT_UNIT: + case SEEK_10: + case VERIFY: + case READ_DEFECT_DATA: + case READ_BUFFER: + case WRITE_BUFFER: + scb->scsi_cmd->result = DID_OK << 16; + break; + + default: + /* Set the Return Info to appear like the Command was */ + /* attempted, a Check Condition occurred, and Sense */ + /* Data indicating an Invalid CDB OpCode is returned. */ + sp = (char *) scb->scsi_cmd->sense_buffer; + memset(sp, 0, sizeof (scb->scsi_cmd->sense_buffer)); + + sp[0] = 0x70; /* Error Code */ + sp[2] = ILLEGAL_REQUEST; /* Sense Key 5 Illegal Req. */ + sp[7] = 0x0A; /* Additional Sense Length */ + sp[12] = 0x20; /* ASC = Invalid OpCode */ + sp[13] = 0x00; /* ASCQ */ + + device_error = 2; /* Indicate Check Condition */ + scb->scsi_cmd->result = device_error | (DID_OK << 16); + break; + } /* end switch */ + } + /* end if */ + if (ret == IPS_SUCCESS_IMM) + return (ret); + + /* setup DCDB */ + if (scb->bus > 0) { + + /* If we already know the Device is Not there, no need to attempt a Command */ + /* This also protects an NT FailOver Controller from getting CDB's sent to it */ + if (ha->conf->dev[scb->bus - 1][scb->target_id].ucState == 0) { + scb->scsi_cmd->result = DID_NO_CONNECT << 16; + return (IPS_SUCCESS_IMM); + } + + ha->dcdb_active[scb->bus - 1] |= (1 << scb->target_id); + scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr + + (unsigned long) &scb-> + dcdb - + (unsigned long) scb); + scb->cmd.dcdb.reserved = 0; + scb->cmd.dcdb.reserved2 = 0; + scb->cmd.dcdb.reserved3 = 0; + scb->cmd.dcdb.segment_4G = 0; + scb->cmd.dcdb.enhanced_sg = 0; + + TimeOut = scb->scsi_cmd->timeout_per_command; + + if (ha->subsys->param[4] & 0x00100000) { /* If NEW Tape DCDB is Supported */ + if (!scb->sg_len) { + scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB; + } else { + scb->cmd.dcdb.op_code = + IPS_CMD_EXTENDED_DCDB_SG; + scb->cmd.dcdb.enhanced_sg = + IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0; + } + + tapeDCDB = (IPS_DCDB_TABLE_TAPE *) & scb->dcdb; /* Use Same Data Area as Old DCDB Struct */ + tapeDCDB->device_address = + ((scb->bus - 1) << 4) | scb->target_id; + tapeDCDB->cmd_attribute |= IPS_DISCONNECT_ALLOWED; + tapeDCDB->cmd_attribute &= ~IPS_TRANSFER64K; /* Always Turn OFF 64K Size Flag */ + + if (TimeOut) { + if (TimeOut < (10 * HZ)) + tapeDCDB->cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */ + else if (TimeOut < (60 * HZ)) + tapeDCDB->cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */ + else if (TimeOut < (1200 * HZ)) + tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */ + } + + tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len; + tapeDCDB->reserved_for_LUN = 0; + tapeDCDB->transfer_length = scb->data_len; + if (scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG) + tapeDCDB->buffer_pointer = + cpu_to_le32(scb->sg_busaddr); + else + tapeDCDB->buffer_pointer = + cpu_to_le32(scb->data_busaddr); + tapeDCDB->sg_count = scb->sg_len; + tapeDCDB->sense_length = sizeof (tapeDCDB->sense_info); + tapeDCDB->scsi_status = 0; + tapeDCDB->reserved = 0; + memcpy(tapeDCDB->scsi_cdb, scb->scsi_cmd->cmnd, + scb->scsi_cmd->cmd_len); + } else { + if (!scb->sg_len) { + scb->cmd.dcdb.op_code = IPS_CMD_DCDB; + } else { + scb->cmd.dcdb.op_code = IPS_CMD_DCDB_SG; + scb->cmd.dcdb.enhanced_sg = + IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0; + } + + scb->dcdb.device_address = + ((scb->bus - 1) << 4) | scb->target_id; + scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED; + + if (TimeOut) { + if (TimeOut < (10 * HZ)) + scb->dcdb.cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */ + else if (TimeOut < (60 * HZ)) + scb->dcdb.cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */ + else if (TimeOut < (1200 * HZ)) + scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */ + } + + scb->dcdb.transfer_length = scb->data_len; + if (scb->dcdb.cmd_attribute & IPS_TRANSFER64K) + scb->dcdb.transfer_length = 0; + if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB_SG) + scb->dcdb.buffer_pointer = + cpu_to_le32(scb->sg_busaddr); + else + scb->dcdb.buffer_pointer = + cpu_to_le32(scb->data_busaddr); + scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len; + scb->dcdb.sense_length = sizeof (scb->dcdb.sense_info); + scb->dcdb.sg_count = scb->sg_len; + scb->dcdb.reserved = 0; + memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd, + scb->scsi_cmd->cmd_len); + scb->dcdb.scsi_status = 0; + scb->dcdb.reserved2[0] = 0; + scb->dcdb.reserved2[1] = 0; + scb->dcdb.reserved2[2] = 0; + } + } - return ((*ha->func.issue)(ha, scb)); + return ((*ha->func.issue) (ha, scb)); } /****************************************************************************/ @@ -4639,169 +4077,151 @@ /* Assumed to be called with the HA lock */ /****************************************************************************/ static void -ips_chkstatus(ips_ha_t *ha, IPS_STATUS *pstatus) { - ips_scb_t *scb; - ips_stat_t *sp; - uint8_t basic_status; - uint8_t ext_status; - int errcode; - - METHOD_TRACE("ips_chkstatus", 1); - - scb = &ha->scbs[pstatus->fields.command_id]; - scb->basic_status = basic_status = pstatus->fields.basic_status & IPS_BASIC_STATUS_MASK; - scb->extended_status = ext_status = pstatus->fields.extended_status; - - sp = &ha->sp; - sp->residue_len = 0; - sp->scb_addr = (void *) scb; - - /* Remove the item from the active queue */ - ips_removeq_scb(&ha->scb_activelist, scb); - - if (!scb->scsi_cmd) - /* internal commands are handled in do_ipsintr */ - return ; - - DEBUG_VAR(2, "(%s%d) ips_chkstatus: cmd 0x%X id %d (%d %d %d)", - ips_name, - ha->host_num, - scb->cdb[0], - scb->cmd.basic_io.command_id, - scb->bus, - scb->target_id, - scb->lun); - - if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) - /* passthru - just returns the raw result */ - return ; - - errcode = DID_OK; - - if (((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_SUCCESS) || - ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR)) { - - if (scb->bus == 0) { - if ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR) { - DEBUG_VAR(1, "(%s%d) Recovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x", - ips_name, ha->host_num, - scb->cmd.basic_io.op_code, basic_status, ext_status); - } - - switch (scb->scsi_cmd->cmnd[0]) { - case ALLOW_MEDIUM_REMOVAL: - case REZERO_UNIT: - case ERASE: - case WRITE_FILEMARKS: - case SPACE: - errcode = DID_ERROR; - break; - - case START_STOP: - break; - - case TEST_UNIT_READY: - if (scb->target_id == IPS_ADAPTER_ID) - break; - - if (!ips_online(ha, scb)) { - errcode = DID_TIME_OUT; - } - break; - - case INQUIRY: - if (scb->target_id == IPS_ADAPTER_ID) { - IPS_SCSI_INQ_DATA inquiry; - - memset(&inquiry, 0, sizeof(IPS_SCSI_INQ_DATA)); - - inquiry.DeviceType = IPS_SCSI_INQ_TYPE_PROCESSOR; - inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED; - inquiry.Version = IPS_SCSI_INQ_REV2; - inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2; - inquiry.AdditionalLength = 31; - inquiry.Flags[0] = IPS_SCSI_INQ_Address16; - inquiry.Flags[1] = IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync; - strncpy(inquiry.VendorId, "IBM ", 8); - strncpy(inquiry.ProductId, "SERVERAID ", 16); - strncpy(inquiry.ProductRevisionLevel, "1.00", 4); - - memcpy(scb->scsi_cmd->request_buffer, &inquiry, scb->scsi_cmd->request_bufflen); - - scb->scsi_cmd->result = DID_OK << 16; - break; - } - - if (ips_online(ha, scb)) { - ips_inquiry(ha, scb); - } else { - errcode = DID_TIME_OUT; - } - break; - - case REQUEST_SENSE: - ips_reqsen(ha, scb); - break; - - case READ_6: - case WRITE_6: - case READ_10: - case WRITE_10: - case RESERVE: - case RELEASE: - break; - - case MODE_SENSE: - if (!ips_online(ha, scb) || !ips_msense(ha, scb)) { - errcode = DID_ERROR; - } - break; - - case READ_CAPACITY: - if (ips_online(ha, scb)) - ips_rdcap(ha, scb); - else { - errcode = DID_TIME_OUT; - } - break; - - case SEND_DIAGNOSTIC: - case REASSIGN_BLOCKS: - break; - - case FORMAT_UNIT: - errcode = DID_ERROR; - break; - - case SEEK_10: - case VERIFY: - case READ_DEFECT_DATA: - case READ_BUFFER: - case WRITE_BUFFER: - break; - - default: - errcode = DID_ERROR; - } /* end switch */ - - scb->scsi_cmd->result = errcode << 16; - } else { /* bus == 0 */ - /* restrict access to physical drives */ - if ((scb->scsi_cmd->cmnd[0] == INQUIRY) && - ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) == TYPE_DISK)) { - - scb->scsi_cmd->result = DID_TIME_OUT << 16; - } - } /* else */ - } else { /* recovered error / success */ - if (scb->bus == 0) { - DEBUG_VAR(1, "(%s%d) Unrecovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x", - ips_name, ha->host_num, - scb->cmd.basic_io.op_code, basic_status, ext_status); - } +ips_chkstatus(ips_ha_t * ha, IPS_STATUS * pstatus) +{ + ips_scb_t *scb; + ips_stat_t *sp; + uint8_t basic_status; + uint8_t ext_status; + int errcode; + + METHOD_TRACE("ips_chkstatus", 1); + + scb = &ha->scbs[pstatus->fields.command_id]; + scb->basic_status = basic_status = + pstatus->fields.basic_status & IPS_BASIC_STATUS_MASK; + scb->extended_status = ext_status = pstatus->fields.extended_status; + + sp = &ha->sp; + sp->residue_len = 0; + sp->scb_addr = (void *) scb; + + /* Remove the item from the active queue */ + ips_removeq_scb(&ha->scb_activelist, scb); + + if (!scb->scsi_cmd) + /* internal commands are handled in do_ipsintr */ + return; + + DEBUG_VAR(2, "(%s%d) ips_chkstatus: cmd 0x%X id %d (%d %d %d)", + ips_name, + ha->host_num, + scb->cdb[0], + scb->cmd.basic_io.command_id, + scb->bus, scb->target_id, scb->lun); + + if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) + /* passthru - just returns the raw result */ + return; + + errcode = DID_OK; + + if (((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_SUCCESS) || + ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR)) { + + if (scb->bus == 0) { + if ((basic_status & IPS_GSC_STATUS_MASK) == + IPS_CMD_RECOVERED_ERROR) { + DEBUG_VAR(1, + "(%s%d) Recovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x", + ips_name, ha->host_num, + scb->cmd.basic_io.op_code, + basic_status, ext_status); + } + + switch (scb->scsi_cmd->cmnd[0]) { + case ALLOW_MEDIUM_REMOVAL: + case REZERO_UNIT: + case ERASE: + case WRITE_FILEMARKS: + case SPACE: + errcode = DID_ERROR; + break; + + case START_STOP: + break; + + case TEST_UNIT_READY: + if (!ips_online(ha, scb)) { + errcode = DID_TIME_OUT; + } + break; + + case INQUIRY: + if (ips_online(ha, scb)) { + ips_inquiry(ha, scb); + } else { + errcode = DID_TIME_OUT; + } + break; + + case REQUEST_SENSE: + ips_reqsen(ha, scb); + break; + + case READ_6: + case WRITE_6: + case READ_10: + case WRITE_10: + case RESERVE: + case RELEASE: + break; + + case MODE_SENSE: + if (!ips_online(ha, scb) + || !ips_msense(ha, scb)) { + errcode = DID_ERROR; + } + break; + + case READ_CAPACITY: + if (ips_online(ha, scb)) + ips_rdcap(ha, scb); + else { + errcode = DID_TIME_OUT; + } + break; + + case SEND_DIAGNOSTIC: + case REASSIGN_BLOCKS: + break; + + case FORMAT_UNIT: + errcode = DID_ERROR; + break; + + case SEEK_10: + case VERIFY: + case READ_DEFECT_DATA: + case READ_BUFFER: + case WRITE_BUFFER: + break; + + default: + errcode = DID_ERROR; + } /* end switch */ + + scb->scsi_cmd->result = errcode << 16; + } else { /* bus == 0 */ + /* restrict access to physical drives */ + if ((scb->scsi_cmd->cmnd[0] == INQUIRY) && + ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) == + TYPE_DISK)) { + + scb->scsi_cmd->result = DID_TIME_OUT << 16; + } + } /* else */ + } else { /* recovered error / success */ + if (scb->bus == 0) { + DEBUG_VAR(1, + "(%s%d) Unrecovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x", + ips_name, ha->host_num, + scb->cmd.basic_io.op_code, basic_status, + ext_status); + } - ips_map_status(ha, scb, sp); - } /* else */ + ips_map_status(ha, scb, sp); + } /* else */ } /****************************************************************************/ @@ -4814,25 +4234,28 @@ /* */ /****************************************************************************/ static int -ips_online(ips_ha_t *ha, ips_scb_t *scb) { - METHOD_TRACE("ips_online", 1); - - if (scb->target_id >= IPS_MAX_LD) - return (0); +ips_online(ips_ha_t * ha, ips_scb_t * scb) +{ + METHOD_TRACE("ips_online", 1); - if ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1) { - memset(&ha->adapt->logical_drive_info, 0, sizeof(ha->adapt->logical_drive_info)); + if (scb->target_id >= IPS_MAX_LD) + return (0); - return (0); - } - - if (ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_OFFLINE && - ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_FREE && - ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_CRS && - ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_SYS) - return (1); - else - return (0); + if ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1) { + memset(ha->logical_drive_info, 0, sizeof (IPS_LD_INFO)); + return (0); + } + + if (ha->logical_drive_info->drive_info[scb->target_id].state != + IPS_LD_OFFLINE + && ha->logical_drive_info->drive_info[scb->target_id].state != + IPS_LD_FREE + && ha->logical_drive_info->drive_info[scb->target_id].state != + IPS_LD_CRS + && ha->logical_drive_info->drive_info[scb->target_id].state != + IPS_LD_SYS) return (1); + else + return (0); } /****************************************************************************/ @@ -4845,27 +4268,29 @@ /* */ /****************************************************************************/ static int -ips_inquiry(ips_ha_t *ha, ips_scb_t *scb) { - IPS_SCSI_INQ_DATA inquiry; +ips_inquiry(ips_ha_t * ha, ips_scb_t * scb) +{ + IPS_SCSI_INQ_DATA inquiry; - METHOD_TRACE("ips_inquiry", 1); + METHOD_TRACE("ips_inquiry", 1); - memset(&inquiry, 0, sizeof(IPS_SCSI_INQ_DATA)); + memset(&inquiry, 0, sizeof (IPS_SCSI_INQ_DATA)); - inquiry.DeviceType = IPS_SCSI_INQ_TYPE_DASD; - inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED; - inquiry.Version = IPS_SCSI_INQ_REV2; - inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2; - inquiry.AdditionalLength = 31; - inquiry.Flags[0] = IPS_SCSI_INQ_Address16; - inquiry.Flags[1] = IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync; - strncpy(inquiry.VendorId, "IBM ", 8); - strncpy(inquiry.ProductId, "SERVERAID ", 16); - strncpy(inquiry.ProductRevisionLevel, "1.00", 4); + inquiry.DeviceType = IPS_SCSI_INQ_TYPE_DASD; + inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED; + inquiry.Version = IPS_SCSI_INQ_REV2; + inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2; + inquiry.AdditionalLength = 31; + inquiry.Flags[0] = IPS_SCSI_INQ_Address16; + inquiry.Flags[1] = + IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync | IPS_SCSI_INQ_CmdQue; + strncpy(inquiry.VendorId, "IBM ", 8); + strncpy(inquiry.ProductId, "SERVERAID ", 16); + strncpy(inquiry.ProductRevisionLevel, "1.00", 4); - memcpy(scb->scsi_cmd->request_buffer, &inquiry, scb->scsi_cmd->request_bufflen); + ips_scmd_buf_write(scb->scsi_cmd, &inquiry, sizeof (inquiry)); - return (1); + return (1); } /****************************************************************************/ @@ -4878,20 +4303,24 @@ /* */ /****************************************************************************/ static int -ips_rdcap(ips_ha_t *ha, ips_scb_t *scb) { - IPS_SCSI_CAPACITY *cap; +ips_rdcap(ips_ha_t * ha, ips_scb_t * scb) +{ + IPS_SCSI_CAPACITY cap; - METHOD_TRACE("ips_rdcap", 1); + METHOD_TRACE("ips_rdcap", 1); - if (scb->scsi_cmd->bufflen < 8) - return (0); + if (scb->scsi_cmd->bufflen < 8) + return (0); - cap = (IPS_SCSI_CAPACITY *) scb->scsi_cmd->request_buffer; + cap.lba = + cpu_to_be32(le32_to_cpu + (ha->logical_drive_info-> + drive_info[scb->target_id].sector_count) - 1); + cap.len = cpu_to_be32((uint32_t) IPS_BLKSIZE); - cap->lba = cpu_to_be32(le32_to_cpu(ha->adapt->logical_drive_info.drive_info[scb->target_id].sector_count) - 1); - cap->len = cpu_to_be32((uint32_t) IPS_BLKSIZE); + ips_scmd_buf_write(scb->scsi_cmd, &cap, sizeof (cap)); - return (1); + return (1); } /****************************************************************************/ @@ -4904,72 +4333,78 @@ /* */ /****************************************************************************/ static int -ips_msense(ips_ha_t *ha, ips_scb_t *scb) { - uint16_t heads; - uint16_t sectors; - uint32_t cylinders; - IPS_SCSI_MODE_PAGE_DATA mdata; - - METHOD_TRACE("ips_msense", 1); - - if (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) > 0x400000 && - (ha->enq->ucMiscFlag & 0x8) == 0) { - heads = IPS_NORM_HEADS; - sectors = IPS_NORM_SECTORS; - } else { - heads = IPS_COMP_HEADS; - sectors = IPS_COMP_SECTORS; - } - - cylinders = (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) - 1) / (heads * sectors); - - memset(&mdata, 0, sizeof(IPS_SCSI_MODE_PAGE_DATA)); - - mdata.hdr.BlockDescLength = 8; - - switch (scb->scsi_cmd->cmnd[2] & 0x3f) { - case 0x03: /* page 3 */ - mdata.pdata.pg3.PageCode = 3; - mdata.pdata.pg3.PageLength = sizeof(IPS_SCSI_MODE_PAGE3); - mdata.hdr.DataLength = 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg3.PageLength; - mdata.pdata.pg3.TracksPerZone = 0; - mdata.pdata.pg3.AltSectorsPerZone = 0; - mdata.pdata.pg3.AltTracksPerZone = 0; - mdata.pdata.pg3.AltTracksPerVolume = 0; - mdata.pdata.pg3.SectorsPerTrack = cpu_to_be16(sectors); - mdata.pdata.pg3.BytesPerSector = cpu_to_be16(IPS_BLKSIZE); - mdata.pdata.pg3.Interleave = cpu_to_be16(1); - mdata.pdata.pg3.TrackSkew = 0; - mdata.pdata.pg3.CylinderSkew = 0; - mdata.pdata.pg3.flags = IPS_SCSI_MP3_SoftSector; - break; - - case 0x4: - mdata.pdata.pg4.PageCode = 4; - mdata.pdata.pg4.PageLength = sizeof(IPS_SCSI_MODE_PAGE4); - mdata.hdr.DataLength = 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg4.PageLength; - mdata.pdata.pg4.CylindersHigh = cpu_to_be16((cylinders >> 8) & 0xFFFF); - mdata.pdata.pg4.CylindersLow = (cylinders & 0xFF); - mdata.pdata.pg4.Heads = heads; - mdata.pdata.pg4.WritePrecompHigh = 0; - mdata.pdata.pg4.WritePrecompLow = 0; - mdata.pdata.pg4.ReducedWriteCurrentHigh = 0; - mdata.pdata.pg4.ReducedWriteCurrentLow = 0; - mdata.pdata.pg4.StepRate = cpu_to_be16(1); - mdata.pdata.pg4.LandingZoneHigh = 0; - mdata.pdata.pg4.LandingZoneLow = 0; - mdata.pdata.pg4.flags = 0; - mdata.pdata.pg4.RotationalOffset = 0; - mdata.pdata.pg4.MediumRotationRate = 0; - break; - - default: - return (0); - } /* end switch */ +ips_msense(ips_ha_t * ha, ips_scb_t * scb) +{ + uint16_t heads; + uint16_t sectors; + uint32_t cylinders; + IPS_SCSI_MODE_PAGE_DATA mdata; + + METHOD_TRACE("ips_msense", 1); + + if (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) > 0x400000 && + (ha->enq->ucMiscFlag & 0x8) == 0) { + heads = IPS_NORM_HEADS; + sectors = IPS_NORM_SECTORS; + } else { + heads = IPS_COMP_HEADS; + sectors = IPS_COMP_SECTORS; + } + + cylinders = + (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) - + 1) / (heads * sectors); + + memset(&mdata, 0, sizeof (IPS_SCSI_MODE_PAGE_DATA)); + + mdata.hdr.BlockDescLength = 8; + + switch (scb->scsi_cmd->cmnd[2] & 0x3f) { + case 0x03: /* page 3 */ + mdata.pdata.pg3.PageCode = 3; + mdata.pdata.pg3.PageLength = sizeof (IPS_SCSI_MODE_PAGE3); + mdata.hdr.DataLength = + 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg3.PageLength; + mdata.pdata.pg3.TracksPerZone = 0; + mdata.pdata.pg3.AltSectorsPerZone = 0; + mdata.pdata.pg3.AltTracksPerZone = 0; + mdata.pdata.pg3.AltTracksPerVolume = 0; + mdata.pdata.pg3.SectorsPerTrack = cpu_to_be16(sectors); + mdata.pdata.pg3.BytesPerSector = cpu_to_be16(IPS_BLKSIZE); + mdata.pdata.pg3.Interleave = cpu_to_be16(1); + mdata.pdata.pg3.TrackSkew = 0; + mdata.pdata.pg3.CylinderSkew = 0; + mdata.pdata.pg3.flags = IPS_SCSI_MP3_SoftSector; + break; + + case 0x4: + mdata.pdata.pg4.PageCode = 4; + mdata.pdata.pg4.PageLength = sizeof (IPS_SCSI_MODE_PAGE4); + mdata.hdr.DataLength = + 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg4.PageLength; + mdata.pdata.pg4.CylindersHigh = + cpu_to_be16((cylinders >> 8) & 0xFFFF); + mdata.pdata.pg4.CylindersLow = (cylinders & 0xFF); + mdata.pdata.pg4.Heads = heads; + mdata.pdata.pg4.WritePrecompHigh = 0; + mdata.pdata.pg4.WritePrecompLow = 0; + mdata.pdata.pg4.ReducedWriteCurrentHigh = 0; + mdata.pdata.pg4.ReducedWriteCurrentLow = 0; + mdata.pdata.pg4.StepRate = cpu_to_be16(1); + mdata.pdata.pg4.LandingZoneHigh = 0; + mdata.pdata.pg4.LandingZoneLow = 0; + mdata.pdata.pg4.flags = 0; + mdata.pdata.pg4.RotationalOffset = 0; + mdata.pdata.pg4.MediumRotationRate = 0; + break; + + default: + return (0); + } /* end switch */ - memcpy(scb->scsi_cmd->request_buffer, &mdata, scb->scsi_cmd->request_bufflen); + ips_scmd_buf_write(scb->scsi_cmd, &mdata, sizeof (mdata)); - return (1); + return (1); } /****************************************************************************/ @@ -4982,21 +4417,23 @@ /* */ /****************************************************************************/ static int -ips_reqsen(ips_ha_t *ha, ips_scb_t *scb) { - IPS_SCSI_REQSEN reqsen; +ips_reqsen(ips_ha_t * ha, ips_scb_t * scb) +{ + IPS_SCSI_REQSEN reqsen; - METHOD_TRACE("ips_reqsen", 1); + METHOD_TRACE("ips_reqsen", 1); - memset(&reqsen, 0, sizeof(IPS_SCSI_REQSEN)); + memset(&reqsen, 0, sizeof (IPS_SCSI_REQSEN)); - reqsen.ResponseCode = IPS_SCSI_REQSEN_VALID | IPS_SCSI_REQSEN_CURRENT_ERR; - reqsen.AdditionalLength = 10; - reqsen.AdditionalSenseCode = IPS_SCSI_REQSEN_NO_SENSE; - reqsen.AdditionalSenseCodeQual = IPS_SCSI_REQSEN_NO_SENSE; + reqsen.ResponseCode = + IPS_SCSI_REQSEN_VALID | IPS_SCSI_REQSEN_CURRENT_ERR; + reqsen.AdditionalLength = 10; + reqsen.AdditionalSenseCode = IPS_SCSI_REQSEN_NO_SENSE; + reqsen.AdditionalSenseCodeQual = IPS_SCSI_REQSEN_NO_SENSE; - memcpy(scb->scsi_cmd->request_buffer, &reqsen, scb->scsi_cmd->request_bufflen); + ips_scmd_buf_write(scb->scsi_cmd, &reqsen, sizeof (reqsen)); - return (1); + return (1); } /****************************************************************************/ @@ -5009,60 +4446,72 @@ /* */ /****************************************************************************/ static void -ips_free(ips_ha_t *ha) { +ips_free(ips_ha_t * ha) +{ - METHOD_TRACE("ips_free", 1); + METHOD_TRACE("ips_free", 1); - if (ha) { - if (ha->enq) { - kfree(ha->enq); - ha->enq = NULL; - } - - if (ha->conf) { - kfree(ha->conf); - ha->conf = NULL; - } - - if (ha->adapt) { - pci_free_consistent(ha->pcidev,sizeof(IPS_ADAPTER)+ sizeof(IPS_IO_CMD), - ha->adapt, ha->adapt->hw_status_start); - ha->adapt = NULL; - } - - if (ha->nvram) { - kfree(ha->nvram); - ha->nvram = NULL; - } - - if (ha->subsys) { - kfree(ha->subsys); - ha->subsys = NULL; - } - - if (ha->ioctl_data) { - free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order); - ha->ioctl_data = NULL; - ha->ioctl_datasize = 0; - ha->ioctl_order = 0; - } - ips_deallocatescbs(ha, ha->max_cmds); - - /* free memory mapped (if applicable) */ - if (ha->mem_ptr) { - iounmap(ha->ioremap_ptr); - ha->ioremap_ptr = NULL; - ha->mem_ptr = NULL; - } - -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) - if (ha->mem_addr) - release_mem_region(ha->mem_addr, ha->mem_len); -#endif - ha->mem_addr = 0; + if (ha) { + if (ha->enq) { + pci_free_consistent(ha->pcidev, sizeof(IPS_ENQ), + ha->enq, ha->enq_busaddr); + ha->enq = NULL; + } + + if (ha->conf) { + kfree(ha->conf); + ha->conf = NULL; + } + + if (ha->adapt) { + pci_free_consistent(ha->pcidev, + sizeof (IPS_ADAPTER) + + sizeof (IPS_IO_CMD), ha->adapt, + ha->adapt->hw_status_start); + ha->adapt = NULL; + } + + if (ha->logical_drive_info) { + pci_free_consistent(ha->pcidev, + sizeof (IPS_LD_INFO), + ha->logical_drive_info, + ha->logical_drive_info_dma_addr); + ha->logical_drive_info = NULL; + } + + if (ha->nvram) { + kfree(ha->nvram); + ha->nvram = NULL; + } + + if (ha->subsys) { + kfree(ha->subsys); + ha->subsys = NULL; + } + + if (ha->ioctl_data) { + pci_free_consistent(ha->pcidev, ha->ioctl_len, + ha->ioctl_data, ha->ioctl_busaddr); + ha->ioctl_data = NULL; + ha->ioctl_datasize = 0; + ha->ioctl_len = 0; + } + ips_deallocatescbs(ha, ha->max_cmds); + + /* free memory mapped (if applicable) */ + if (ha->mem_ptr) { + iounmap(ha->ioremap_ptr); + ha->ioremap_ptr = NULL; + ha->mem_ptr = NULL; + } + + if (ha->mem_addr) + release_mem_region(ha->mem_addr, ha->mem_len); + ha->mem_addr = 0; - } + } } + /****************************************************************************/ /* */ /* Routine Name: ips_deallocatescbs */ @@ -5073,15 +4522,18 @@ /* */ /****************************************************************************/ static int -ips_deallocatescbs(ips_ha_t *ha, int cmds) { - if (ha->scbs) { - pci_free_consistent(ha->pcidev,sizeof(IPS_SG_LIST) * IPS_MAX_SG * - cmds, ha->scbs->sg_list, ha->scbs->sg_busaddr); - pci_free_consistent(ha->pcidev, sizeof(ips_scb_t) * cmds, - ha->scbs, ha->scbs->scb_busaddr); - ha->scbs = NULL; - } /* end if */ -return 1; +ips_deallocatescbs(ips_ha_t * ha, int cmds) +{ + if (ha->scbs) { + pci_free_consistent(ha->pcidev, + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * cmds, + ha->scbs->sg_list.list, + ha->scbs->sg_busaddr); + pci_free_consistent(ha->pcidev, sizeof (ips_scb_t) * cmds, + ha->scbs, ha->scbs->scb_busaddr); + ha->scbs = NULL; + } /* end if */ + return 1; } /****************************************************************************/ @@ -5094,44 +4546,59 @@ /* */ /****************************************************************************/ static int -ips_allocatescbs(ips_ha_t *ha) { - ips_scb_t *scb_p; - IPS_SG_LIST* ips_sg; - int i; - dma_addr_t command_dma, sg_dma; - - METHOD_TRACE("ips_allocatescbs", 1); - - /* Allocate memory for the SCBs */ - ha->scbs = pci_alloc_consistent(ha->pcidev, ha->max_cmds * sizeof(ips_scb_t), - &command_dma); - if (ha->scbs == NULL) - return 0; - ips_sg = pci_alloc_consistent(ha->pcidev, sizeof(IPS_SG_LIST) * IPS_MAX_SG * - ha->max_cmds, &sg_dma); - if(ips_sg == NULL){ - pci_free_consistent(ha->pcidev,ha->max_cmds * sizeof(ips_scb_t),ha->scbs, command_dma); - return 0; - } - - memset(ha->scbs, 0, ha->max_cmds * sizeof(ips_scb_t)); - - for (i = 0; i < ha->max_cmds; i++) { - scb_p = &ha->scbs[i]; - scb_p->scb_busaddr = command_dma + sizeof(ips_scb_t) * i; - /* set up S/G list */ - scb_p->sg_list = ips_sg + i * IPS_MAX_SG; - scb_p->sg_busaddr = sg_dma + sizeof(IPS_SG_LIST) * IPS_MAX_SG * i; - - /* add to the free list */ - if (i < ha->max_cmds - 1) { - scb_p->q_next = ha->scb_freelist; - ha->scb_freelist = scb_p; - } - } +ips_allocatescbs(ips_ha_t * ha) +{ + ips_scb_t *scb_p; + IPS_SG_LIST ips_sg; + int i; + dma_addr_t command_dma, sg_dma; + + METHOD_TRACE("ips_allocatescbs", 1); + + /* Allocate memory for the SCBs */ + ha->scbs = + pci_alloc_consistent(ha->pcidev, ha->max_cmds * sizeof (ips_scb_t), + &command_dma); + if (ha->scbs == NULL) + return 0; + ips_sg.list = + pci_alloc_consistent(ha->pcidev, + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * + ha->max_cmds, &sg_dma); + if (ips_sg.list == NULL) { + pci_free_consistent(ha->pcidev, + ha->max_cmds * sizeof (ips_scb_t), ha->scbs, + command_dma); + return 0; + } + + memset(ha->scbs, 0, ha->max_cmds * sizeof (ips_scb_t)); + + for (i = 0; i < ha->max_cmds; i++) { + scb_p = &ha->scbs[i]; + scb_p->scb_busaddr = command_dma + sizeof (ips_scb_t) * i; + /* set up S/G list */ + if (IPS_USE_ENH_SGLIST(ha)) { + scb_p->sg_list.enh_list = + ips_sg.enh_list + i * IPS_MAX_SG; + scb_p->sg_busaddr = + sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i; + } else { + scb_p->sg_list.std_list = + ips_sg.std_list + i * IPS_MAX_SG; + scb_p->sg_busaddr = + sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i; + } + + /* add to the free list */ + if (i < ha->max_cmds - 1) { + scb_p->q_next = ha->scb_freelist; + ha->scb_freelist = scb_p; + } + } - /* success */ - return (1); + /* success */ + return (1); } /****************************************************************************/ @@ -5144,36 +4611,37 @@ /* */ /****************************************************************************/ static void -ips_init_scb(ips_ha_t *ha, ips_scb_t *scb) { - IPS_SG_LIST *sg_list; - uint32_t cmd_busaddr, sg_busaddr; - METHOD_TRACE("ips_init_scb", 1); - - if (scb == NULL) - return ; - - sg_list = scb->sg_list; - cmd_busaddr = scb->scb_busaddr; - sg_busaddr = scb->sg_busaddr; - /* zero fill */ - memset(scb, 0, sizeof(ips_scb_t)); - memset(ha->dummy, 0, sizeof(IPS_IO_CMD)); - - /* Initialize dummy command bucket */ - ha->dummy->op_code = 0xFF; - ha->dummy->ccsar = cpu_to_le32(ha->adapt->hw_status_start - + sizeof(IPS_ADAPTER)); - ha->dummy->command_id = IPS_MAX_CMDS; - - /* set bus address of scb */ - scb->scb_busaddr = cmd_busaddr; - scb->sg_busaddr = sg_busaddr; - scb->sg_list = sg_list; - - /* Neptune Fix */ - scb->cmd.basic_io.cccr = cpu_to_le32((uint32_t) IPS_BIT_ILE); - scb->cmd.basic_io.ccsar = cpu_to_le32(ha->adapt->hw_status_start - + sizeof(IPS_ADAPTER)); +ips_init_scb(ips_ha_t * ha, ips_scb_t * scb) +{ + IPS_SG_LIST sg_list; + uint32_t cmd_busaddr, sg_busaddr; + METHOD_TRACE("ips_init_scb", 1); + + if (scb == NULL) + return; + + sg_list.list = scb->sg_list.list; + cmd_busaddr = scb->scb_busaddr; + sg_busaddr = scb->sg_busaddr; + /* zero fill */ + memset(scb, 0, sizeof (ips_scb_t)); + memset(ha->dummy, 0, sizeof (IPS_IO_CMD)); + + /* Initialize dummy command bucket */ + ha->dummy->op_code = 0xFF; + ha->dummy->ccsar = cpu_to_le32(ha->adapt->hw_status_start + + sizeof (IPS_ADAPTER)); + ha->dummy->command_id = IPS_MAX_CMDS; + + /* set bus address of scb */ + scb->scb_busaddr = cmd_busaddr; + scb->sg_busaddr = sg_busaddr; + scb->sg_list.list = sg_list.list; + + /* Neptune Fix */ + scb->cmd.basic_io.cccr = cpu_to_le32((uint32_t) IPS_BIT_ILE); + scb->cmd.basic_io.ccsar = cpu_to_le32(ha->adapt->hw_status_start + + sizeof (IPS_ADAPTER)); } /****************************************************************************/ @@ -5188,22 +4656,24 @@ /* */ /****************************************************************************/ static ips_scb_t * -ips_getscb(ips_ha_t *ha) { - ips_scb_t *scb; +ips_getscb(ips_ha_t * ha) +{ + ips_scb_t *scb; - METHOD_TRACE("ips_getscb", 1); + METHOD_TRACE("ips_getscb", 1); - if ((scb = ha->scb_freelist) == NULL) { + if ((scb = ha->scb_freelist) == NULL) { - return (NULL); - } + return (NULL); + } - ha->scb_freelist = scb->q_next; - scb->q_next = NULL; + ha->scb_freelist = scb->q_next; + scb->flags = 0; + scb->q_next = NULL; - ips_init_scb(ha, scb); + ips_init_scb(ha, scb); - return (scb); + return (scb); } /****************************************************************************/ @@ -5218,22 +4688,22 @@ /* */ /****************************************************************************/ static void -ips_freescb(ips_ha_t *ha, ips_scb_t *scb) { +ips_freescb(ips_ha_t * ha, ips_scb_t * scb) +{ - METHOD_TRACE("ips_freescb", 1); - if(scb->flags & IPS_SCB_MAP_SG) - pci_unmap_sg(ha->pcidev, scb->scsi_cmd->request_buffer, - scb->scsi_cmd->use_sg, - IPS_DMA_DIR(scb)); - else if(scb->flags & IPS_SCB_MAP_SINGLE) - pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len, - IPS_DMA_DIR(scb)); - - /* check to make sure this is not our "special" scb */ - if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) { - scb->q_next = ha->scb_freelist; - ha->scb_freelist = scb; - } + METHOD_TRACE("ips_freescb", 1); + if (scb->flags & IPS_SCB_MAP_SG) + pci_unmap_sg(ha->pcidev, scb->scsi_cmd->request_buffer, + scb->scsi_cmd->use_sg, IPS_DMA_DIR(scb)); + else if (scb->flags & IPS_SCB_MAP_SINGLE) + pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len, + IPS_DMA_DIR(scb)); + + /* check to make sure this is not our "special" scb */ + if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) { + scb->q_next = ha->scb_freelist; + ha->scb_freelist = scb; + } } /****************************************************************************/ @@ -5246,19 +4716,20 @@ /* */ /****************************************************************************/ static int -ips_isinit_copperhead(ips_ha_t *ha) { - uint8_t scpr; - uint8_t isr; - - METHOD_TRACE("ips_isinit_copperhead", 1); - - isr = inb(ha->io_addr + IPS_REG_HISR); - scpr = inb(ha->io_addr + IPS_REG_SCPR); - - if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0)) - return (0); - else - return (1); +ips_isinit_copperhead(ips_ha_t * ha) +{ + uint8_t scpr; + uint8_t isr; + + METHOD_TRACE("ips_isinit_copperhead", 1); + + isr = inb(ha->io_addr + IPS_REG_HISR); + scpr = inb(ha->io_addr + IPS_REG_SCPR); + + if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0)) + return (0); + else + return (1); } /****************************************************************************/ @@ -5271,19 +4742,20 @@ /* */ /****************************************************************************/ static int -ips_isinit_copperhead_memio(ips_ha_t *ha) { - uint8_t isr=0; - uint8_t scpr; - - METHOD_TRACE("ips_is_init_copperhead_memio", 1); - - isr = readb(ha->mem_ptr + IPS_REG_HISR); - scpr = readb(ha->mem_ptr + IPS_REG_SCPR); - - if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0)) - return (0); - else - return (1); +ips_isinit_copperhead_memio(ips_ha_t * ha) +{ + uint8_t isr = 0; + uint8_t scpr; + + METHOD_TRACE("ips_is_init_copperhead_memio", 1); + + isr = readb(ha->mem_ptr + IPS_REG_HISR); + scpr = readb(ha->mem_ptr + IPS_REG_SCPR); + + if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0)) + return (0); + else + return (1); } /****************************************************************************/ @@ -5296,21 +4768,22 @@ /* */ /****************************************************************************/ static int -ips_isinit_morpheus(ips_ha_t *ha) { - uint32_t post; - uint32_t bits; - - METHOD_TRACE("ips_is_init_morpheus", 1); - - post = readl(ha->mem_ptr + IPS_REG_I960_MSG0); - bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR); - - if (post == 0) - return (0); - else if (bits & 0x3) - return (0); - else - return (1); +ips_isinit_morpheus(ips_ha_t * ha) +{ + uint32_t post; + uint32_t bits; + + METHOD_TRACE("ips_is_init_morpheus", 1); + + post = readl(ha->mem_ptr + IPS_REG_I960_MSG0); + bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR); + + if (post == 0) + return (0); + else if (bits & 0x3) + return (0); + else + return (1); } /****************************************************************************/ @@ -5322,10 +4795,12 @@ /* */ /****************************************************************************/ static void -ips_enable_int_copperhead(ips_ha_t *ha) { - METHOD_TRACE("ips_enable_int_copperhead", 1); +ips_enable_int_copperhead(ips_ha_t * ha) +{ + METHOD_TRACE("ips_enable_int_copperhead", 1); - outb(ha->io_addr + IPS_REG_HISR, IPS_BIT_EI); + outb(ha->io_addr + IPS_REG_HISR, IPS_BIT_EI); + inb(ha->io_addr + IPS_REG_HISR); // Ensure PCI Posting Completes } /****************************************************************************/ @@ -5337,10 +4812,12 @@ /* */ /****************************************************************************/ static void -ips_enable_int_copperhead_memio(ips_ha_t *ha) { - METHOD_TRACE("ips_enable_int_copperhead_memio", 1); +ips_enable_int_copperhead_memio(ips_ha_t * ha) +{ + METHOD_TRACE("ips_enable_int_copperhead_memio", 1); - writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR); + writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR); + readb(ha->mem_ptr + IPS_REG_HISR); // Ensure PCI Posting Completes } /****************************************************************************/ @@ -5352,14 +4829,16 @@ /* */ /****************************************************************************/ static void -ips_enable_int_morpheus(ips_ha_t *ha) { - uint32_t Oimr; +ips_enable_int_morpheus(ips_ha_t * ha) +{ + uint32_t Oimr; - METHOD_TRACE("ips_enable_int_morpheus", 1); + METHOD_TRACE("ips_enable_int_morpheus", 1); - Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR); - Oimr &= ~0x08; - writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR); + Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR); + Oimr &= ~0x08; + writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR); + readl(ha->mem_ptr + IPS_REG_I960_OIMR); // Ensure PCI Posting Completes } /****************************************************************************/ @@ -5372,86 +4851,88 @@ /* */ /****************************************************************************/ static int -ips_init_copperhead(ips_ha_t *ha) { - uint8_t Isr; - uint8_t Cbsp; - uint8_t PostByte[IPS_MAX_POST_BYTES]; - uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES]; - int i, j; - - METHOD_TRACE("ips_init_copperhead", 1); - - for (i = 0; i < IPS_MAX_POST_BYTES; i++) { - for (j = 0; j < 45; j++) { - Isr = inb(ha->io_addr + IPS_REG_HISR); - if (Isr & IPS_BIT_GHI) - break; - - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - } - - if (j >= 45) - /* error occurred */ - return (0); - - PostByte[i] = inb(ha->io_addr + IPS_REG_ISPR); - outb(Isr, ha->io_addr + IPS_REG_HISR); - } - - if (PostByte[0] < IPS_GOOD_POST_STATUS) { - printk(KERN_WARNING "(%s%d) reset controller fails (post status %x %x).\n", - ips_name, ha->host_num, PostByte[0], PostByte[1]); - - return (0); - } - - for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) { - for (j = 0; j < 240; j++) { - Isr = inb(ha->io_addr + IPS_REG_HISR); - if (Isr & IPS_BIT_GHI) - break; - - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - } - - if (j >= 240) - /* error occurred */ - return (0); - - ConfigByte[i] = inb(ha->io_addr + IPS_REG_ISPR); - outb(Isr, ha->io_addr + IPS_REG_HISR); - } - - for (i = 0; i < 240; i++) { - Cbsp = inb(ha->io_addr + IPS_REG_CBSP); - - if ((Cbsp & IPS_BIT_OP) == 0) - break; - - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - } - - if (i >= 240) - /* reset failed */ - return (0); - - /* setup CCCR */ - outl(cpu_to_le32(0x1010), ha->io_addr + IPS_REG_CCCR); - - /* Enable busmastering */ - outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR); - - if (ha->revision_id == IPS_REVID_TROMBONE64) - /* fix for anaconda64 */ - outl(0, ha->io_addr + IPS_REG_NDAE); +ips_init_copperhead(ips_ha_t * ha) +{ + uint8_t Isr; + uint8_t Cbsp; + uint8_t PostByte[IPS_MAX_POST_BYTES]; + uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES]; + int i, j; + + METHOD_TRACE("ips_init_copperhead", 1); + + for (i = 0; i < IPS_MAX_POST_BYTES; i++) { + for (j = 0; j < 45; j++) { + Isr = inb(ha->io_addr + IPS_REG_HISR); + if (Isr & IPS_BIT_GHI) + break; + + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); + } + + if (j >= 45) + /* error occurred */ + return (0); + + PostByte[i] = inb(ha->io_addr + IPS_REG_ISPR); + outb(Isr, ha->io_addr + IPS_REG_HISR); + } + + if (PostByte[0] < IPS_GOOD_POST_STATUS) { + printk(KERN_WARNING + "(%s%d) reset controller fails (post status %x %x).\n", + ips_name, ha->host_num, PostByte[0], PostByte[1]); + + return (0); + } + + for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) { + for (j = 0; j < 240; j++) { + Isr = inb(ha->io_addr + IPS_REG_HISR); + if (Isr & IPS_BIT_GHI) + break; + + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); + } + + if (j >= 240) + /* error occurred */ + return (0); + + ConfigByte[i] = inb(ha->io_addr + IPS_REG_ISPR); + outb(Isr, ha->io_addr + IPS_REG_HISR); + } + + for (i = 0; i < 240; i++) { + Cbsp = inb(ha->io_addr + IPS_REG_CBSP); + + if ((Cbsp & IPS_BIT_OP) == 0) + break; + + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); + } + + if (i >= 240) + /* reset failed */ + return (0); + + /* setup CCCR */ + outl(cpu_to_le32(0x1010), ha->io_addr + IPS_REG_CCCR); + + /* Enable busmastering */ + outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR); + + if (ha->revision_id == IPS_REVID_TROMBONE64) + /* fix for anaconda64 */ + outl(0, ha->io_addr + IPS_REG_NDAE); - /* Enable interrupts */ - outb(IPS_BIT_EI, ha->io_addr + IPS_REG_HISR); + /* Enable interrupts */ + outb(IPS_BIT_EI, ha->io_addr + IPS_REG_HISR); - return (1); + return (1); } /****************************************************************************/ @@ -5464,87 +4945,89 @@ /* */ /****************************************************************************/ static int -ips_init_copperhead_memio(ips_ha_t *ha) { - uint8_t Isr=0; - uint8_t Cbsp; - uint8_t PostByte[IPS_MAX_POST_BYTES]; - uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES]; - int i, j; - - METHOD_TRACE("ips_init_copperhead_memio", 1); - - for (i = 0; i < IPS_MAX_POST_BYTES; i++) { - for (j = 0; j < 45; j++) { - Isr = readb(ha->mem_ptr + IPS_REG_HISR); - if (Isr & IPS_BIT_GHI) - break; - - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - } - - if (j >= 45) - /* error occurred */ - return (0); - - PostByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR); - writeb(Isr, ha->mem_ptr + IPS_REG_HISR); - } - - if (PostByte[0] < IPS_GOOD_POST_STATUS) { - printk(KERN_WARNING "(%s%d) reset controller fails (post status %x %x).\n", - ips_name, ha->host_num, PostByte[0], PostByte[1]); - - return (0); - } - - for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) { - for (j = 0; j < 240; j++) { - Isr = readb(ha->mem_ptr + IPS_REG_HISR); - if (Isr & IPS_BIT_GHI) - break; - - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - } - - if (j >= 240) - /* error occurred */ - return (0); - - ConfigByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR); - writeb(Isr, ha->mem_ptr + IPS_REG_HISR); - } - - for (i = 0; i < 240; i++) { - Cbsp = readb(ha->mem_ptr + IPS_REG_CBSP); - - if ((Cbsp & IPS_BIT_OP) == 0) - break; - - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - } - - if (i >= 240) - /* error occurred */ - return (0); - - /* setup CCCR */ - writel(0x1010, ha->mem_ptr + IPS_REG_CCCR); - - /* Enable busmastering */ - writeb(IPS_BIT_EBM, ha->mem_ptr + IPS_REG_SCPR); - - if (ha->revision_id == IPS_REVID_TROMBONE64) - /* fix for anaconda64 */ - writel(0, ha->mem_ptr + IPS_REG_NDAE); +ips_init_copperhead_memio(ips_ha_t * ha) +{ + uint8_t Isr = 0; + uint8_t Cbsp; + uint8_t PostByte[IPS_MAX_POST_BYTES]; + uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES]; + int i, j; + + METHOD_TRACE("ips_init_copperhead_memio", 1); + + for (i = 0; i < IPS_MAX_POST_BYTES; i++) { + for (j = 0; j < 45; j++) { + Isr = readb(ha->mem_ptr + IPS_REG_HISR); + if (Isr & IPS_BIT_GHI) + break; + + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); + } + + if (j >= 45) + /* error occurred */ + return (0); + + PostByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR); + writeb(Isr, ha->mem_ptr + IPS_REG_HISR); + } + + if (PostByte[0] < IPS_GOOD_POST_STATUS) { + printk(KERN_WARNING + "(%s%d) reset controller fails (post status %x %x).\n", + ips_name, ha->host_num, PostByte[0], PostByte[1]); + + return (0); + } + + for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) { + for (j = 0; j < 240; j++) { + Isr = readb(ha->mem_ptr + IPS_REG_HISR); + if (Isr & IPS_BIT_GHI) + break; + + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); + } + + if (j >= 240) + /* error occurred */ + return (0); + + ConfigByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR); + writeb(Isr, ha->mem_ptr + IPS_REG_HISR); + } + + for (i = 0; i < 240; i++) { + Cbsp = readb(ha->mem_ptr + IPS_REG_CBSP); + + if ((Cbsp & IPS_BIT_OP) == 0) + break; + + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); + } + + if (i >= 240) + /* error occurred */ + return (0); + + /* setup CCCR */ + writel(0x1010, ha->mem_ptr + IPS_REG_CCCR); + + /* Enable busmastering */ + writeb(IPS_BIT_EBM, ha->mem_ptr + IPS_REG_SCPR); + + if (ha->revision_id == IPS_REVID_TROMBONE64) + /* fix for anaconda64 */ + writel(0, ha->mem_ptr + IPS_REG_NDAE); - /* Enable interrupts */ - writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR); + /* Enable interrupts */ + writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR); - /* if we get here then everything went OK */ - return (1); + /* if we get here then everything went OK */ + return (1); } /****************************************************************************/ @@ -5557,109 +5040,112 @@ /* */ /****************************************************************************/ static int -ips_init_morpheus(ips_ha_t *ha) { - uint32_t Post; - uint32_t Config; - uint32_t Isr; - uint32_t Oimr; - int i; - - METHOD_TRACE("ips_init_morpheus", 1); - - /* Wait up to 45 secs for Post */ - for (i = 0; i < 45; i++) { - Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR); - - if (Isr & IPS_BIT_I960_MSG0I) - break; - - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - } - - if (i >= 45) { - /* error occurred */ - printk(KERN_WARNING "(%s%d) timeout waiting for post.\n", - ips_name, ha->host_num); - - return (0); - } - - Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0); - - if (Post == 0x4F00) { /* If Flashing the Battery PIC */ - printk(KERN_WARNING "Flashing Battery PIC, Please wait ...\n" ); - - /* Clear the interrupt bit */ - Isr = (uint32_t) IPS_BIT_I960_MSG0I; - writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR); - - for (i = 0; i < 120; i++) { /* Wait Up to 2 Min. for Completion */ - Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0); - if (Post != 0x4F00) - break; - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - } - - if (i >= 120) { - printk(KERN_WARNING "(%s%d) timeout waiting for Battery PIC Flash\n", - ips_name, ha->host_num); - return (0); - } - - } - - /* Clear the interrupt bit */ - Isr = (uint32_t) IPS_BIT_I960_MSG0I; - writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR); - - if (Post < (IPS_GOOD_POST_STATUS << 8)) { - printk(KERN_WARNING "(%s%d) reset controller fails (post status %x).\n", - ips_name, ha->host_num, Post); - - return (0); - } - - /* Wait up to 240 secs for config bytes */ - for (i = 0; i < 240; i++) { - Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR); - - if (Isr & IPS_BIT_I960_MSG1I) - break; - - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - } - - if (i >= 240) { - /* error occurred */ - printk(KERN_WARNING "(%s%d) timeout waiting for config.\n", - ips_name, ha->host_num); - - return (0); - } - - Config = readl(ha->mem_ptr + IPS_REG_I960_MSG1); - - /* Clear interrupt bit */ - Isr = (uint32_t) IPS_BIT_I960_MSG1I; - writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR); - - /* Turn on the interrupts */ - Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR); - Oimr &= ~0x8; - writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR); - - /* if we get here then everything went OK */ - - /* Since we did a RESET, an EraseStripeLock may be needed */ - if (Post == 0xEF10) { - if ( (Config == 0x000F) || (Config == 0x0009) ) - ha->requires_esl = 1; - } +ips_init_morpheus(ips_ha_t * ha) +{ + uint32_t Post; + uint32_t Config; + uint32_t Isr; + uint32_t Oimr; + int i; + + METHOD_TRACE("ips_init_morpheus", 1); + + /* Wait up to 45 secs for Post */ + for (i = 0; i < 45; i++) { + Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR); + + if (Isr & IPS_BIT_I960_MSG0I) + break; + + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); + } + + if (i >= 45) { + /* error occurred */ + printk(KERN_WARNING "(%s%d) timeout waiting for post.\n", + ips_name, ha->host_num); + + return (0); + } + + Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0); + + if (Post == 0x4F00) { /* If Flashing the Battery PIC */ + printk(KERN_WARNING "Flashing Battery PIC, Please wait ...\n"); + + /* Clear the interrupt bit */ + Isr = (uint32_t) IPS_BIT_I960_MSG0I; + writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR); + + for (i = 0; i < 120; i++) { /* Wait Up to 2 Min. for Completion */ + Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0); + if (Post != 0x4F00) + break; + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); + } + + if (i >= 120) { + printk(KERN_WARNING + "(%s%d) timeout waiting for Battery PIC Flash\n", + ips_name, ha->host_num); + return (0); + } + + } + + /* Clear the interrupt bit */ + Isr = (uint32_t) IPS_BIT_I960_MSG0I; + writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR); + + if (Post < (IPS_GOOD_POST_STATUS << 8)) { + printk(KERN_WARNING + "(%s%d) reset controller fails (post status %x).\n", + ips_name, ha->host_num, Post); + + return (0); + } + + /* Wait up to 240 secs for config bytes */ + for (i = 0; i < 240; i++) { + Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR); + + if (Isr & IPS_BIT_I960_MSG1I) + break; + + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); + } + + if (i >= 240) { + /* error occurred */ + printk(KERN_WARNING "(%s%d) timeout waiting for config.\n", + ips_name, ha->host_num); + + return (0); + } + + Config = readl(ha->mem_ptr + IPS_REG_I960_MSG1); + + /* Clear interrupt bit */ + Isr = (uint32_t) IPS_BIT_I960_MSG1I; + writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR); + + /* Turn on the interrupts */ + Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR); + Oimr &= ~0x8; + writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR); + + /* if we get here then everything went OK */ + + /* Since we did a RESET, an EraseStripeLock may be needed */ + if (Post == 0xEF10) { + if ((Config == 0x000F) || (Config == 0x0009)) + ha->requires_esl = 1; + } - return (1); + return (1); } /****************************************************************************/ @@ -5672,38 +5158,39 @@ /* */ /****************************************************************************/ static int -ips_reset_copperhead(ips_ha_t *ha) { - int reset_counter; +ips_reset_copperhead(ips_ha_t * ha) +{ + int reset_counter; + + METHOD_TRACE("ips_reset_copperhead", 1); - METHOD_TRACE("ips_reset_copperhead", 1); + DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d", + ips_name, ha->host_num, ha->io_addr, ha->irq); - DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d", - ips_name, ha->host_num, ha->io_addr, ha->irq); + reset_counter = 0; - reset_counter = 0; + while (reset_counter < 2) { + reset_counter++; - while (reset_counter < 2) { - reset_counter++; + outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR); - outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR); + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - - outb(0, ha->io_addr + IPS_REG_SCPR); + outb(0, ha->io_addr + IPS_REG_SCPR); - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - - if ((*ha->func.init)(ha)) - break; - else if (reset_counter >= 2) { + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); - return (0); - } - } + if ((*ha->func.init) (ha)) + break; + else if (reset_counter >= 2) { - return (1); + return (0); + } + } + + return (1); } /****************************************************************************/ @@ -5716,38 +5203,39 @@ /* */ /****************************************************************************/ static int -ips_reset_copperhead_memio(ips_ha_t *ha) { - int reset_counter; +ips_reset_copperhead_memio(ips_ha_t * ha) +{ + int reset_counter; + + METHOD_TRACE("ips_reset_copperhead_memio", 1); + + DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d", + ips_name, ha->host_num, ha->mem_addr, ha->irq); - METHOD_TRACE("ips_reset_copperhead_memio", 1); + reset_counter = 0; - DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d", - ips_name, ha->host_num, ha->mem_addr, ha->irq); + while (reset_counter < 2) { + reset_counter++; - reset_counter = 0; + writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR); - while (reset_counter < 2) { - reset_counter++; + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); - writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR); + writeb(0, ha->mem_ptr + IPS_REG_SCPR); - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - - writeb(0, ha->mem_ptr + IPS_REG_SCPR); + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - - if ((*ha->func.init)(ha)) - break; - else if (reset_counter >= 2) { + if ((*ha->func.init) (ha)) + break; + else if (reset_counter >= 2) { - return (0); - } - } + return (0); + } + } - return (1); + return (1); } /****************************************************************************/ @@ -5760,37 +5248,38 @@ /* */ /****************************************************************************/ static int -ips_reset_morpheus(ips_ha_t *ha) { - int reset_counter; - uint8_t junk; +ips_reset_morpheus(ips_ha_t * ha) +{ + int reset_counter; + uint8_t junk; + + METHOD_TRACE("ips_reset_morpheus", 1); - METHOD_TRACE("ips_reset_morpheus", 1); + DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d", + ips_name, ha->host_num, ha->mem_addr, ha->irq); - DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d", - ips_name, ha->host_num, ha->mem_addr, ha->irq); + reset_counter = 0; - reset_counter = 0; + while (reset_counter < 2) { + reset_counter++; - while (reset_counter < 2) { - reset_counter++; + writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR); - writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR); + /* Delay for 5 Seconds */ + MDELAY(5 * IPS_ONE_SEC); - /* Delay for 5 Seconds */ - MDELAY(5 * IPS_ONE_SEC); - - /* Do a PCI config read to wait for adapter */ - pci_read_config_byte(ha->pcidev, 4, &junk); + /* Do a PCI config read to wait for adapter */ + pci_read_config_byte(ha->pcidev, 4, &junk); - if ((*ha->func.init)(ha)) - break; - else if (reset_counter >= 2) { + if ((*ha->func.init) (ha)) + break; + else if (reset_counter >= 2) { - return (0); - } - } + return (0); + } + } - return (1); + return (1); } /****************************************************************************/ @@ -5803,22 +5292,25 @@ /* */ /****************************************************************************/ static void -ips_statinit(ips_ha_t *ha) { - uint32_t phys_status_start; +ips_statinit(ips_ha_t * ha) +{ + uint32_t phys_status_start; - METHOD_TRACE("ips_statinit", 1); + METHOD_TRACE("ips_statinit", 1); - ha->adapt->p_status_start = ha->adapt->status; - ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS; - ha->adapt->p_status_tail = ha->adapt->status; - - phys_status_start = ha->adapt->hw_status_start; - outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQSR); - outl(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE), ha->io_addr + IPS_REG_SQER); - outl(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE), ha->io_addr + IPS_REG_SQHR); - outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQTR); + ha->adapt->p_status_start = ha->adapt->status; + ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS; + ha->adapt->p_status_tail = ha->adapt->status; + + phys_status_start = ha->adapt->hw_status_start; + outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQSR); + outl(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE), + ha->io_addr + IPS_REG_SQER); + outl(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE), + ha->io_addr + IPS_REG_SQHR); + outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQTR); - ha->adapt->hw_status_tail = phys_status_start; + ha->adapt->hw_status_tail = phys_status_start; } /****************************************************************************/ @@ -5831,22 +5323,24 @@ /* */ /****************************************************************************/ static void -ips_statinit_memio(ips_ha_t *ha) { - uint32_t phys_status_start; +ips_statinit_memio(ips_ha_t * ha) +{ + uint32_t phys_status_start; - METHOD_TRACE("ips_statinit_memio", 1); + METHOD_TRACE("ips_statinit_memio", 1); - ha->adapt->p_status_start = ha->adapt->status; - ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS; - ha->adapt->p_status_tail = ha->adapt->status; - - phys_status_start = ha->adapt->hw_status_start; - writel(phys_status_start, ha->mem_ptr + IPS_REG_SQSR); - writel(phys_status_start + IPS_STATUS_Q_SIZE, ha->mem_ptr + IPS_REG_SQER); - writel(phys_status_start + IPS_STATUS_SIZE, ha->mem_ptr + IPS_REG_SQHR); - writel(phys_status_start, ha->mem_ptr + IPS_REG_SQTR); + ha->adapt->p_status_start = ha->adapt->status; + ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS; + ha->adapt->p_status_tail = ha->adapt->status; + + phys_status_start = ha->adapt->hw_status_start; + writel(phys_status_start, ha->mem_ptr + IPS_REG_SQSR); + writel(phys_status_start + IPS_STATUS_Q_SIZE, + ha->mem_ptr + IPS_REG_SQER); + writel(phys_status_start + IPS_STATUS_SIZE, ha->mem_ptr + IPS_REG_SQHR); + writel(phys_status_start, ha->mem_ptr + IPS_REG_SQTR); - ha->adapt->hw_status_tail = phys_status_start; + ha->adapt->hw_status_tail = phys_status_start; } /****************************************************************************/ @@ -5859,20 +5353,22 @@ /* */ /****************************************************************************/ static uint32_t -ips_statupd_copperhead(ips_ha_t *ha) { - METHOD_TRACE("ips_statupd_copperhead", 1); +ips_statupd_copperhead(ips_ha_t * ha) +{ + METHOD_TRACE("ips_statupd_copperhead", 1); - if (ha->adapt->p_status_tail != ha->adapt->p_status_end) { - ha->adapt->p_status_tail++; - ha->adapt->hw_status_tail += sizeof(IPS_STATUS); - } else { - ha->adapt->p_status_tail = ha->adapt->p_status_start; - ha->adapt->hw_status_tail = ha->adapt->hw_status_start; - } + if (ha->adapt->p_status_tail != ha->adapt->p_status_end) { + ha->adapt->p_status_tail++; + ha->adapt->hw_status_tail += sizeof (IPS_STATUS); + } else { + ha->adapt->p_status_tail = ha->adapt->p_status_start; + ha->adapt->hw_status_tail = ha->adapt->hw_status_start; + } - outl(cpu_to_le32(ha->adapt->hw_status_tail), ha->io_addr + IPS_REG_SQTR); + outl(cpu_to_le32(ha->adapt->hw_status_tail), + ha->io_addr + IPS_REG_SQTR); - return (ha->adapt->p_status_tail->value); + return (ha->adapt->p_status_tail->value); } /****************************************************************************/ @@ -5885,20 +5381,21 @@ /* */ /****************************************************************************/ static uint32_t -ips_statupd_copperhead_memio(ips_ha_t *ha) { - METHOD_TRACE("ips_statupd_copperhead_memio", 1); +ips_statupd_copperhead_memio(ips_ha_t * ha) +{ + METHOD_TRACE("ips_statupd_copperhead_memio", 1); - if (ha->adapt->p_status_tail != ha->adapt->p_status_end) { - ha->adapt->p_status_tail++; - ha->adapt->hw_status_tail += sizeof(IPS_STATUS); - } else { - ha->adapt->p_status_tail = ha->adapt->p_status_start; - ha->adapt->hw_status_tail = ha->adapt->hw_status_start; - } + if (ha->adapt->p_status_tail != ha->adapt->p_status_end) { + ha->adapt->p_status_tail++; + ha->adapt->hw_status_tail += sizeof (IPS_STATUS); + } else { + ha->adapt->p_status_tail = ha->adapt->p_status_start; + ha->adapt->hw_status_tail = ha->adapt->hw_status_start; + } - writel(ha->adapt->hw_status_tail, ha->mem_ptr + IPS_REG_SQTR); + writel(ha->adapt->hw_status_tail, ha->mem_ptr + IPS_REG_SQTR); - return (ha->adapt->p_status_tail->value); + return (ha->adapt->p_status_tail->value); } /****************************************************************************/ @@ -5911,14 +5408,15 @@ /* */ /****************************************************************************/ static uint32_t -ips_statupd_morpheus(ips_ha_t *ha) { - uint32_t val; +ips_statupd_morpheus(ips_ha_t * ha) +{ + uint32_t val; - METHOD_TRACE("ips_statupd_morpheus", 1); + METHOD_TRACE("ips_statupd_morpheus", 1); - val = readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ); + val = readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ); - return (val); + return (val); } /****************************************************************************/ @@ -5931,50 +5429,49 @@ /* */ /****************************************************************************/ static int -ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) { - uint32_t TimeOut; - uint32_t val; - - METHOD_TRACE("ips_issue_copperhead", 1); - - if (scb->scsi_cmd) { - DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)", - ips_name, - ha->host_num, - scb->cdb[0], - scb->cmd.basic_io.command_id, - scb->bus, - scb->target_id, - scb->lun); - } else { - DEBUG_VAR(2, KERN_NOTICE "(%s%d) ips_issue: logical cmd id %d", - ips_name, - ha->host_num, - scb->cmd.basic_io.command_id); - } - - TimeOut = 0; - - while ((val = le32_to_cpu(inl(ha->io_addr + IPS_REG_CCCR))) & IPS_BIT_SEM) { - udelay(1000); - - if (++TimeOut >= IPS_SEM_TIMEOUT) { - if (!(val & IPS_BIT_START_STOP)) - break; - - printk(KERN_WARNING "(%s%d) ips_issue val [0x%x].\n", - ips_name, ha->host_num, val); - printk(KERN_WARNING "(%s%d) ips_issue semaphore chk timeout.\n", - ips_name, ha->host_num); - - return (IPS_FAILURE); - } /* end if */ - } /* end while */ +ips_issue_copperhead(ips_ha_t * ha, ips_scb_t * scb) +{ + uint32_t TimeOut; + uint32_t val; + + METHOD_TRACE("ips_issue_copperhead", 1); - outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_CCSAR); - outw(cpu_to_le32(IPS_BIT_START_CMD), ha->io_addr + IPS_REG_CCCR); + if (scb->scsi_cmd) { + DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)", + ips_name, + ha->host_num, + scb->cdb[0], + scb->cmd.basic_io.command_id, + scb->bus, scb->target_id, scb->lun); + } else { + DEBUG_VAR(2, KERN_NOTICE "(%s%d) ips_issue: logical cmd id %d", + ips_name, ha->host_num, scb->cmd.basic_io.command_id); + } + + TimeOut = 0; + + while ((val = le32_to_cpu(inl(ha->io_addr + IPS_REG_CCCR))) & + IPS_BIT_SEM) { + udelay(1000); + + if (++TimeOut >= IPS_SEM_TIMEOUT) { + if (!(val & IPS_BIT_START_STOP)) + break; + + printk(KERN_WARNING "(%s%d) ips_issue val [0x%x].\n", + ips_name, ha->host_num, val); + printk(KERN_WARNING + "(%s%d) ips_issue semaphore chk timeout.\n", + ips_name, ha->host_num); + + return (IPS_FAILURE); + } /* end if */ + } /* end while */ - return (IPS_SUCCESS); + outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_CCSAR); + outw(cpu_to_le32(IPS_BIT_START_CMD), ha->io_addr + IPS_REG_CCCR); + + return (IPS_SUCCESS); } /****************************************************************************/ @@ -5987,50 +5484,48 @@ /* */ /****************************************************************************/ static int -ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) { - uint32_t TimeOut; - uint32_t val; - - METHOD_TRACE("ips_issue_copperhead_memio", 1); - - if (scb->scsi_cmd) { - DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)", - ips_name, - ha->host_num, - scb->cdb[0], - scb->cmd.basic_io.command_id, - scb->bus, - scb->target_id, - scb->lun); - } else { - DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d", - ips_name, - ha->host_num, - scb->cmd.basic_io.command_id); - } - - TimeOut = 0; - - while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) { - udelay(1000); - - if (++TimeOut >= IPS_SEM_TIMEOUT) { - if (!(val & IPS_BIT_START_STOP)) - break; - - printk(KERN_WARNING "(%s%d) ips_issue val [0x%x].\n", - ips_name, ha->host_num, val); - printk(KERN_WARNING "(%s%d) ips_issue semaphore chk timeout.\n", - ips_name, ha->host_num); - - return (IPS_FAILURE); - } /* end if */ - } /* end while */ +ips_issue_copperhead_memio(ips_ha_t * ha, ips_scb_t * scb) +{ + uint32_t TimeOut; + uint32_t val; + + METHOD_TRACE("ips_issue_copperhead_memio", 1); + + if (scb->scsi_cmd) { + DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)", + ips_name, + ha->host_num, + scb->cdb[0], + scb->cmd.basic_io.command_id, + scb->bus, scb->target_id, scb->lun); + } else { + DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d", + ips_name, ha->host_num, scb->cmd.basic_io.command_id); + } + + TimeOut = 0; + + while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) { + udelay(1000); + + if (++TimeOut >= IPS_SEM_TIMEOUT) { + if (!(val & IPS_BIT_START_STOP)) + break; + + printk(KERN_WARNING "(%s%d) ips_issue val [0x%x].\n", + ips_name, ha->host_num, val); + printk(KERN_WARNING + "(%s%d) ips_issue semaphore chk timeout.\n", + ips_name, ha->host_num); + + return (IPS_FAILURE); + } /* end if */ + } /* end while */ - writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR); - writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR); + writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR); + writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR); - return (IPS_SUCCESS); + return (IPS_SUCCESS); } /****************************************************************************/ @@ -6043,29 +5538,26 @@ /* */ /****************************************************************************/ static int -ips_issue_i2o(ips_ha_t *ha, ips_scb_t *scb) { +ips_issue_i2o(ips_ha_t * ha, ips_scb_t * scb) +{ - METHOD_TRACE("ips_issue_i2o", 1); + METHOD_TRACE("ips_issue_i2o", 1); - if (scb->scsi_cmd) { - DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)", - ips_name, - ha->host_num, - scb->cdb[0], - scb->cmd.basic_io.command_id, - scb->bus, - scb->target_id, - scb->lun); - } else { - DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d", - ips_name, - ha->host_num, - scb->cmd.basic_io.command_id); - } + if (scb->scsi_cmd) { + DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)", + ips_name, + ha->host_num, + scb->cdb[0], + scb->cmd.basic_io.command_id, + scb->bus, scb->target_id, scb->lun); + } else { + DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d", + ips_name, ha->host_num, scb->cmd.basic_io.command_id); + } - outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_I2O_INMSGQ); + outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_I2O_INMSGQ); - return (IPS_SUCCESS); + return (IPS_SUCCESS); } /****************************************************************************/ @@ -6078,29 +5570,26 @@ /* */ /****************************************************************************/ static int -ips_issue_i2o_memio(ips_ha_t *ha, ips_scb_t *scb) { +ips_issue_i2o_memio(ips_ha_t * ha, ips_scb_t * scb) +{ - METHOD_TRACE("ips_issue_i2o_memio", 1); + METHOD_TRACE("ips_issue_i2o_memio", 1); - if (scb->scsi_cmd) { - DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)", - ips_name, - ha->host_num, - scb->cdb[0], - scb->cmd.basic_io.command_id, - scb->bus, - scb->target_id, - scb->lun); - } else { - DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d", - ips_name, - ha->host_num, - scb->cmd.basic_io.command_id); - } + if (scb->scsi_cmd) { + DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)", + ips_name, + ha->host_num, + scb->cdb[0], + scb->cmd.basic_io.command_id, + scb->bus, scb->target_id, scb->lun); + } else { + DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d", + ips_name, ha->host_num, scb->cmd.basic_io.command_id); + } - writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ); + writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ); - return (IPS_SUCCESS); + return (IPS_SUCCESS); } /****************************************************************************/ @@ -6113,26 +5602,27 @@ /* */ /****************************************************************************/ static int -ips_isintr_copperhead(ips_ha_t *ha) { - uint8_t Isr; +ips_isintr_copperhead(ips_ha_t * ha) +{ + uint8_t Isr; - METHOD_TRACE("ips_isintr_copperhead", 2); + METHOD_TRACE("ips_isintr_copperhead", 2); - Isr = inb(ha->io_addr + IPS_REG_HISR); + Isr = inb(ha->io_addr + IPS_REG_HISR); - if (Isr == 0xFF) - /* ?!?! Nothing really there */ - return (0); - - if (Isr & IPS_BIT_SCE) - return (1); - else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) { - /* status queue overflow or GHI */ - /* just clear the interrupt */ - outb(Isr, ha->io_addr + IPS_REG_HISR); - } + if (Isr == 0xFF) + /* ?!?! Nothing really there */ + return (0); - return (0); + if (Isr & IPS_BIT_SCE) + return (1); + else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) { + /* status queue overflow or GHI */ + /* just clear the interrupt */ + outb(Isr, ha->io_addr + IPS_REG_HISR); + } + + return (0); } /****************************************************************************/ @@ -6145,26 +5635,27 @@ /* */ /****************************************************************************/ static int -ips_isintr_copperhead_memio(ips_ha_t *ha) { - uint8_t Isr; +ips_isintr_copperhead_memio(ips_ha_t * ha) +{ + uint8_t Isr; - METHOD_TRACE("ips_isintr_memio", 2); + METHOD_TRACE("ips_isintr_memio", 2); - Isr = readb(ha->mem_ptr + IPS_REG_HISR); + Isr = readb(ha->mem_ptr + IPS_REG_HISR); - if (Isr == 0xFF) - /* ?!?! Nothing really there */ - return (0); - - if (Isr & IPS_BIT_SCE) - return (1); - else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) { - /* status queue overflow or GHI */ - /* just clear the interrupt */ - writeb(Isr, ha->mem_ptr + IPS_REG_HISR); - } + if (Isr == 0xFF) + /* ?!?! Nothing really there */ + return (0); - return (0); + if (Isr & IPS_BIT_SCE) + return (1); + else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) { + /* status queue overflow or GHI */ + /* just clear the interrupt */ + writeb(Isr, ha->mem_ptr + IPS_REG_HISR); + } + + return (0); } /****************************************************************************/ @@ -6177,17 +5668,18 @@ /* */ /****************************************************************************/ static int -ips_isintr_morpheus(ips_ha_t *ha) { - uint32_t Isr; +ips_isintr_morpheus(ips_ha_t * ha) +{ + uint32_t Isr; - METHOD_TRACE("ips_isintr_morpheus", 2); + METHOD_TRACE("ips_isintr_morpheus", 2); - Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR); + Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR); - if (Isr & IPS_BIT_I2O_OPQI) - return (1); - else - return (0); + if (Isr & IPS_BIT_I2O_OPQI) + return (1); + else + return (0); } /****************************************************************************/ @@ -6200,51 +5692,52 @@ /* */ /****************************************************************************/ static int -ips_wait(ips_ha_t *ha, int time, int intr) { - int ret; - int done; - - METHOD_TRACE("ips_wait", 1); - - ret = IPS_FAILURE; - done = FALSE; - - time *= IPS_ONE_SEC; /* convert seconds */ - - while ((time > 0) && (!done)) { - if (intr == IPS_INTR_ON) { - if (ha->waitflag == FALSE) { - ret = IPS_SUCCESS; - done = TRUE; - break; - } - } else if (intr == IPS_INTR_IORL) { - if (ha->waitflag == FALSE) { - /* - * controller generated an interrupt to - * acknowledge completion of the command - * and ips_intr() has serviced the interrupt. - */ - ret = IPS_SUCCESS; - done = TRUE; - break; - } - - /* - * NOTE: we already have the io_request_lock so - * even if we get an interrupt it won't get serviced - * until after we finish. - */ - - (*ha->func.intr)(ha); - } - - /* This looks like a very evil loop, but it only does this during start-up */ - udelay(1000); - time--; - } +ips_wait(ips_ha_t * ha, int time, int intr) +{ + int ret; + int done; + + METHOD_TRACE("ips_wait", 1); + + ret = IPS_FAILURE; + done = FALSE; - return (ret); + time *= IPS_ONE_SEC; /* convert seconds */ + + while ((time > 0) && (!done)) { + if (intr == IPS_INTR_ON) { + if (ha->waitflag == FALSE) { + ret = IPS_SUCCESS; + done = TRUE; + break; + } + } else if (intr == IPS_INTR_IORL) { + if (ha->waitflag == FALSE) { + /* + * controller generated an interrupt to + * acknowledge completion of the command + * and ips_intr() has serviced the interrupt. + */ + ret = IPS_SUCCESS; + done = TRUE; + break; + } + + /* + * NOTE: we already have the io_request_lock so + * even if we get an interrupt it won't get serviced + * until after we finish. + */ + + (*ha->func.intr) (ha); + } + + /* This looks like a very evil loop, but it only does this during start-up */ + udelay(1000); + time--; + } + + return (ret); } /****************************************************************************/ @@ -6257,61 +5750,59 @@ /* */ /****************************************************************************/ static int -ips_write_driver_status(ips_ha_t *ha, int intr) { - METHOD_TRACE("ips_write_driver_status", 1); - - if (!ips_readwrite_page5(ha, FALSE, intr)) { - printk(KERN_WARNING "(%s%d) unable to read NVRAM page 5.\n", - ips_name, ha->host_num); - - return (0); - } - - /* check to make sure the page has a valid */ - /* signature */ - if (le32_to_cpu(ha->nvram->signature) != IPS_NVRAM_P5_SIG) { - DEBUG_VAR(1, "(%s%d) NVRAM page 5 has an invalid signature: %X.", - ips_name, ha->host_num, ha->nvram->signature); - ha->nvram->signature = IPS_NVRAM_P5_SIG; - } - - DEBUG_VAR(2, "(%s%d) Ad Type: %d, Ad Slot: %d, BIOS: %c%c%c%c %c%c%c%c.", - ips_name, ha->host_num, le16_to_cpu(ha->nvram->adapter_type), - ha->nvram->adapter_slot, - ha->nvram->bios_high[0], ha->nvram->bios_high[1], - ha->nvram->bios_high[2], ha->nvram->bios_high[3], - ha->nvram->bios_low[0], ha->nvram->bios_low[1], - ha->nvram->bios_low[2], ha->nvram->bios_low[3]); - - ips_get_bios_version(ha, intr); - - /* change values (as needed) */ - ha->nvram->operating_system = IPS_OS_LINUX; - ha->nvram->adapter_type = ha->ad_type; - strncpy((char *) ha->nvram->driver_high, IPS_VERSION_HIGH, 4); - strncpy((char *) ha->nvram->driver_low, IPS_VERSION_LOW, 4); - strncpy((char *) ha->nvram->bios_high, ha->bios_version, 4); - strncpy((char *) ha->nvram->bios_low, ha->bios_version + 4, 4); - - ips_version_check(ha, intr); /* Check BIOS/FW/Driver Versions */ - - /* Save the First Copy of the Adapter Order that BIOS put in Page 5 */ - if ( (InitState == 0) && (AdapterOrder[0] == 0) ) - strncpy((char *) AdapterOrder, (char *) ha->nvram->adapter_order, sizeof(AdapterOrder) ); - - /* now update the page */ - if (!ips_readwrite_page5(ha, TRUE, intr)) { - printk(KERN_WARNING "(%s%d) unable to write NVRAM page 5.\n", - ips_name, ha->host_num); +ips_write_driver_status(ips_ha_t * ha, int intr) +{ + METHOD_TRACE("ips_write_driver_status", 1); - return (0); - } + if (!ips_readwrite_page5(ha, FALSE, intr)) { + printk(KERN_WARNING "(%s%d) unable to read NVRAM page 5.\n", + ips_name, ha->host_num); + + return (0); + } + + /* check to make sure the page has a valid */ + /* signature */ + if (le32_to_cpu(ha->nvram->signature) != IPS_NVRAM_P5_SIG) { + DEBUG_VAR(1, + "(%s%d) NVRAM page 5 has an invalid signature: %X.", + ips_name, ha->host_num, ha->nvram->signature); + ha->nvram->signature = IPS_NVRAM_P5_SIG; + } + + DEBUG_VAR(2, + "(%s%d) Ad Type: %d, Ad Slot: %d, BIOS: %c%c%c%c %c%c%c%c.", + ips_name, ha->host_num, le16_to_cpu(ha->nvram->adapter_type), + ha->nvram->adapter_slot, ha->nvram->bios_high[0], + ha->nvram->bios_high[1], ha->nvram->bios_high[2], + ha->nvram->bios_high[3], ha->nvram->bios_low[0], + ha->nvram->bios_low[1], ha->nvram->bios_low[2], + ha->nvram->bios_low[3]); + + ips_get_bios_version(ha, intr); + + /* change values (as needed) */ + ha->nvram->operating_system = IPS_OS_LINUX; + ha->nvram->adapter_type = ha->ad_type; + strncpy((char *) ha->nvram->driver_high, IPS_VERSION_HIGH, 4); + strncpy((char *) ha->nvram->driver_low, IPS_VERSION_LOW, 4); + strncpy((char *) ha->nvram->bios_high, ha->bios_version, 4); + strncpy((char *) ha->nvram->bios_low, ha->bios_version + 4, 4); + + ips_version_check(ha, intr); /* Check BIOS/FW/Driver Versions */ + + /* now update the page */ + if (!ips_readwrite_page5(ha, TRUE, intr)) { + printk(KERN_WARNING "(%s%d) unable to write NVRAM page 5.\n", + ips_name, ha->host_num); - /* IF NVRAM Page 5 is OK, Use it for Slot Number Info Because Linux Doesn't Do Slots */ - ha->slot_num = ha->nvram->adapter_slot; + return (0); + } + /* IF NVRAM Page 5 is OK, Use it for Slot Number Info Because Linux Doesn't Do Slots */ + ha->slot_num = ha->nvram->adapter_slot; - return (1); + return (1); } /****************************************************************************/ @@ -6324,39 +5815,37 @@ /* */ /****************************************************************************/ static int -ips_read_adapter_status(ips_ha_t *ha, int intr) { - ips_scb_t *scb; - int ret; - - METHOD_TRACE("ips_read_adapter_status", 1); - - scb = &ha->scbs[ha->max_cmds-1]; - - ips_init_scb(ha, scb); - - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_ENQUIRY; - - scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY; - scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.basic_io.sg_count = 0; - scb->cmd.basic_io.lba = 0; - scb->cmd.basic_io.sector_count = 0; - scb->cmd.basic_io.log_drv = 0; - scb->cmd.basic_io.reserved = 0; - scb->data_len = sizeof(*ha->enq); - scb->data_busaddr = pci_map_single(ha->pcidev, ha->enq, scb->data_len, - IPS_DMA_DIR(scb)); - scb->cmd.basic_io.sg_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; - - /* send command */ - if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) || - (ret == IPS_SUCCESS_IMM) || - ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) - return (0); +ips_read_adapter_status(ips_ha_t * ha, int intr) +{ + ips_scb_t *scb; + int ret; + + METHOD_TRACE("ips_read_adapter_status", 1); + + scb = &ha->scbs[ha->max_cmds - 1]; + + ips_init_scb(ha, scb); - return (1); + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_ENQUIRY; + + scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY; + scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.basic_io.sg_count = 0; + scb->cmd.basic_io.lba = 0; + scb->cmd.basic_io.sector_count = 0; + scb->cmd.basic_io.log_drv = 0; + scb->data_len = sizeof (*ha->enq); + scb->cmd.basic_io.sg_addr = ha->enq_busaddr; + + /* send command */ + if ( + ((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == + IPS_FAILURE) || (ret == IPS_SUCCESS_IMM) + || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) + return (0); + + return (1); } /****************************************************************************/ @@ -6369,39 +5858,38 @@ /* */ /****************************************************************************/ static int -ips_read_subsystem_parameters(ips_ha_t *ha, int intr) { - ips_scb_t *scb; - int ret; - - METHOD_TRACE("ips_read_subsystem_parameters", 1); - - scb = &ha->scbs[ha->max_cmds-1]; - - ips_init_scb(ha, scb); - - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_GET_SUBSYS; - - scb->cmd.basic_io.op_code = IPS_CMD_GET_SUBSYS; - scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.basic_io.sg_count = 0; - scb->cmd.basic_io.lba = 0; - scb->cmd.basic_io.sector_count = 0; - scb->cmd.basic_io.log_drv = 0; - scb->cmd.basic_io.reserved = 0; - scb->data_len = sizeof(*ha->subsys); - scb->data_busaddr = pci_map_single(ha->pcidev, ha->subsys, - scb->data_len, IPS_DMA_DIR(scb)); - scb->cmd.basic_io.sg_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; - - /* send command */ - if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) || - (ret == IPS_SUCCESS_IMM) || - ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) - return (0); +ips_read_subsystem_parameters(ips_ha_t * ha, int intr) +{ + ips_scb_t *scb; + int ret; + + METHOD_TRACE("ips_read_subsystem_parameters", 1); + + scb = &ha->scbs[ha->max_cmds - 1]; + + ips_init_scb(ha, scb); + + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_GET_SUBSYS; + + scb->cmd.basic_io.op_code = IPS_CMD_GET_SUBSYS; + scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.basic_io.sg_count = 0; + scb->cmd.basic_io.lba = 0; + scb->cmd.basic_io.sector_count = 0; + scb->cmd.basic_io.log_drv = 0; + scb->data_len = sizeof (*ha->subsys); + scb->cmd.basic_io.sg_addr = ha->ioctl_busaddr; + + /* send command */ + if ( + ((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == + IPS_FAILURE) || (ret == IPS_SUCCESS_IMM) + || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) + return (0); - return (1); + memcpy(ha->subsys, ha->ioctl_data, sizeof(*ha->subsys)); + return (1); } /****************************************************************************/ @@ -6414,51 +5902,51 @@ /* */ /****************************************************************************/ static int -ips_read_config(ips_ha_t *ha, int intr) { - ips_scb_t *scb; - int i; - int ret; - - METHOD_TRACE("ips_read_config", 1); - - /* set defaults for initiator IDs */ - for (i = 0; i < 4; i++) - ha->conf->init_id[i] = 7; - - scb = &ha->scbs[ha->max_cmds-1]; - - ips_init_scb(ha, scb); - - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_READ_CONF; - - scb->cmd.basic_io.op_code = IPS_CMD_READ_CONF; - scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); - scb->data_len = sizeof(*ha->conf); - scb->data_busaddr = pci_map_single(ha->pcidev, ha->conf, - scb->data_len, IPS_DMA_DIR(scb)); - scb->cmd.basic_io.sg_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; - - /* send command */ - if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) || - (ret == IPS_SUCCESS_IMM) || - ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) { - - memset(ha->conf, 0, sizeof(IPS_CONF)); - - /* reset initiator IDs */ - for (i = 0; i < 4; i++) - ha->conf->init_id[i] = 7; - - /* Allow Completed with Errors, so JCRM can access the Adapter to fix the problems */ - if ((scb->basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_CMPLT_WERROR) - return (1); - - return (0); - } +ips_read_config(ips_ha_t * ha, int intr) +{ + ips_scb_t *scb; + int i; + int ret; + + METHOD_TRACE("ips_read_config", 1); + + /* set defaults for initiator IDs */ + for (i = 0; i < 4; i++) + ha->conf->init_id[i] = 7; + + scb = &ha->scbs[ha->max_cmds - 1]; + + ips_init_scb(ha, scb); + + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_READ_CONF; + + scb->cmd.basic_io.op_code = IPS_CMD_READ_CONF; + scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); + scb->data_len = sizeof (*ha->conf); + scb->cmd.basic_io.sg_addr = ha->ioctl_busaddr; - return (1); + /* send command */ + if ( + ((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == + IPS_FAILURE) || (ret == IPS_SUCCESS_IMM) + || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) { + + memset(ha->conf, 0, sizeof (IPS_CONF)); + + /* reset initiator IDs */ + for (i = 0; i < 4; i++) + ha->conf->init_id[i] = 7; + + /* Allow Completed with Errors, so JCRM can access the Adapter to fix the problems */ + if ((scb->basic_status & IPS_GSC_STATUS_MASK) == + IPS_CMD_CMPLT_WERROR) return (1); + + return (0); + } + + memcpy(ha->conf, ha->ioctl_data, sizeof(*ha->conf)); + return (1); } /****************************************************************************/ @@ -6471,42 +5959,44 @@ /* */ /****************************************************************************/ static int -ips_readwrite_page5(ips_ha_t *ha, int write, int intr) { - ips_scb_t *scb; - int ret; - - METHOD_TRACE("ips_readwrite_page5", 1); - - scb = &ha->scbs[ha->max_cmds-1]; - - ips_init_scb(ha, scb); - - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_RW_NVRAM_PAGE; - - scb->cmd.nvram.op_code = IPS_CMD_RW_NVRAM_PAGE; - scb->cmd.nvram.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.nvram.page = 5; - scb->cmd.nvram.write = write; - scb->cmd.nvram.reserved = 0; - scb->cmd.nvram.reserved2 = 0; - scb->data_len = sizeof(*ha->nvram); - scb->data_busaddr = pci_map_single(ha->pcidev, ha->nvram, - scb->data_len, IPS_DMA_DIR(scb)); - scb->cmd.nvram.buffer_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; - - /* issue the command */ - if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) || - (ret == IPS_SUCCESS_IMM) || - ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) { +ips_readwrite_page5(ips_ha_t * ha, int write, int intr) +{ + ips_scb_t *scb; + int ret; + + METHOD_TRACE("ips_readwrite_page5", 1); - memset(ha->nvram, 0, sizeof(IPS_NVRAM_P5)); + scb = &ha->scbs[ha->max_cmds - 1]; - return (0); - } + ips_init_scb(ha, scb); - return (1); + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_RW_NVRAM_PAGE; + + scb->cmd.nvram.op_code = IPS_CMD_RW_NVRAM_PAGE; + scb->cmd.nvram.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.nvram.page = 5; + scb->cmd.nvram.write = write; + scb->cmd.nvram.reserved = 0; + scb->cmd.nvram.reserved2 = 0; + scb->data_len = sizeof (*ha->nvram); + scb->cmd.nvram.buffer_addr = ha->ioctl_busaddr; + if (write) + memcpy(ha->ioctl_data, ha->nvram, sizeof(*ha->nvram)); + + /* issue the command */ + if ( + ((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == + IPS_FAILURE) || (ret == IPS_SUCCESS_IMM) + || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) { + + memset(ha->nvram, 0, sizeof (IPS_NVRAM_P5)); + + return (0); + } + if (!write) + memcpy(ha->nvram, ha->ioctl_data, sizeof(*ha->nvram)); + return (1); } /****************************************************************************/ @@ -6519,54 +6009,57 @@ /* */ /****************************************************************************/ static int -ips_clear_adapter(ips_ha_t *ha, int intr) { - ips_scb_t *scb; - int ret; - - METHOD_TRACE("ips_clear_adapter", 1); - - scb = &ha->scbs[ha->max_cmds-1]; - - ips_init_scb(ha, scb); - - scb->timeout = ips_reset_timeout; - scb->cdb[0] = IPS_CMD_CONFIG_SYNC; - - scb->cmd.config_sync.op_code = IPS_CMD_CONFIG_SYNC; - scb->cmd.config_sync.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.config_sync.channel = 0; - scb->cmd.config_sync.source_target = IPS_POCL; - scb->cmd.config_sync.reserved = 0; - scb->cmd.config_sync.reserved2 = 0; - scb->cmd.config_sync.reserved3 = 0; - - /* issue command */ - if (((ret = ips_send_wait(ha, scb, ips_reset_timeout, intr)) == IPS_FAILURE) || - (ret == IPS_SUCCESS_IMM) || - ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) - return (0); - - /* send unlock stripe command */ - ips_init_scb(ha, scb); - - scb->cdb[0] = IPS_CMD_ERROR_TABLE; - scb->timeout = ips_reset_timeout; - - scb->cmd.unlock_stripe.op_code = IPS_CMD_ERROR_TABLE; - scb->cmd.unlock_stripe.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.unlock_stripe.log_drv = 0; - scb->cmd.unlock_stripe.control = IPS_CSL; - scb->cmd.unlock_stripe.reserved = 0; - scb->cmd.unlock_stripe.reserved2 = 0; - scb->cmd.unlock_stripe.reserved3 = 0; - - /* issue command */ - if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) || - (ret == IPS_SUCCESS_IMM) || - ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) - return (0); +ips_clear_adapter(ips_ha_t * ha, int intr) +{ + ips_scb_t *scb; + int ret; - return (1); + METHOD_TRACE("ips_clear_adapter", 1); + + scb = &ha->scbs[ha->max_cmds - 1]; + + ips_init_scb(ha, scb); + + scb->timeout = ips_reset_timeout; + scb->cdb[0] = IPS_CMD_CONFIG_SYNC; + + scb->cmd.config_sync.op_code = IPS_CMD_CONFIG_SYNC; + scb->cmd.config_sync.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.config_sync.channel = 0; + scb->cmd.config_sync.source_target = IPS_POCL; + scb->cmd.config_sync.reserved = 0; + scb->cmd.config_sync.reserved2 = 0; + scb->cmd.config_sync.reserved3 = 0; + + /* issue command */ + if ( + ((ret = ips_send_wait(ha, scb, ips_reset_timeout, intr)) == + IPS_FAILURE) || (ret == IPS_SUCCESS_IMM) + || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) + return (0); + + /* send unlock stripe command */ + ips_init_scb(ha, scb); + + scb->cdb[0] = IPS_CMD_ERROR_TABLE; + scb->timeout = ips_reset_timeout; + + scb->cmd.unlock_stripe.op_code = IPS_CMD_ERROR_TABLE; + scb->cmd.unlock_stripe.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.unlock_stripe.log_drv = 0; + scb->cmd.unlock_stripe.control = IPS_CSL; + scb->cmd.unlock_stripe.reserved = 0; + scb->cmd.unlock_stripe.reserved2 = 0; + scb->cmd.unlock_stripe.reserved3 = 0; + + /* issue command */ + if ( + ((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == + IPS_FAILURE) || (ret == IPS_SUCCESS_IMM) + || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) + return (0); + + return (1); } /****************************************************************************/ @@ -6579,27 +6072,28 @@ /* */ /****************************************************************************/ static void -ips_ffdc_reset(ips_ha_t *ha, int intr) { - ips_scb_t *scb; +ips_ffdc_reset(ips_ha_t * ha, int intr) +{ + ips_scb_t *scb; - METHOD_TRACE("ips_ffdc_reset", 1); + METHOD_TRACE("ips_ffdc_reset", 1); - scb = &ha->scbs[ha->max_cmds-1]; + scb = &ha->scbs[ha->max_cmds - 1]; - ips_init_scb(ha, scb); + ips_init_scb(ha, scb); - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_FFDC; - scb->cmd.ffdc.op_code = IPS_CMD_FFDC; - scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.ffdc.reset_count = ha->reset_count; - scb->cmd.ffdc.reset_type = 0x80; + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_FFDC; + scb->cmd.ffdc.op_code = IPS_CMD_FFDC; + scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.ffdc.reset_count = ha->reset_count; + scb->cmd.ffdc.reset_type = 0x80; - /* convert time to what the card wants */ - ips_fix_ffdc_time(ha, scb, ha->last_ffdc); + /* convert time to what the card wants */ + ips_fix_ffdc_time(ha, scb, ha->last_ffdc); - /* issue command */ - ips_send_wait(ha, scb, ips_cmd_timeout, intr); + /* issue command */ + ips_send_wait(ha, scb, ips_cmd_timeout, intr); } /****************************************************************************/ @@ -6612,30 +6106,30 @@ /* */ /****************************************************************************/ static void -ips_ffdc_time(ips_ha_t *ha) { - ips_scb_t *scb; +ips_ffdc_time(ips_ha_t * ha) +{ + ips_scb_t *scb; - METHOD_TRACE("ips_ffdc_time", 1); + METHOD_TRACE("ips_ffdc_time", 1); - DEBUG_VAR(1, "(%s%d) Sending time update.", - ips_name, ha->host_num); + DEBUG_VAR(1, "(%s%d) Sending time update.", ips_name, ha->host_num); - scb = &ha->scbs[ha->max_cmds-1]; + scb = &ha->scbs[ha->max_cmds - 1]; - ips_init_scb(ha, scb); + ips_init_scb(ha, scb); - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_FFDC; - scb->cmd.ffdc.op_code = IPS_CMD_FFDC; - scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.ffdc.reset_count = 0; - scb->cmd.ffdc.reset_type = 0x80; + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_FFDC; + scb->cmd.ffdc.op_code = IPS_CMD_FFDC; + scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.ffdc.reset_count = 0; + scb->cmd.ffdc.reset_type = 0; - /* convert time to what the card wants */ - ips_fix_ffdc_time(ha, scb, ha->last_ffdc); + /* convert time to what the card wants */ + ips_fix_ffdc_time(ha, scb, ha->last_ffdc); - /* issue command */ - ips_send_wait(ha, scb, ips_cmd_timeout, IPS_FFDC); + /* issue command */ + ips_send_wait(ha, scb, ips_cmd_timeout, IPS_FFDC); } /****************************************************************************/ @@ -6647,57 +6141,59 @@ /* */ /****************************************************************************/ static void -ips_fix_ffdc_time(ips_ha_t *ha, ips_scb_t *scb, time_t current_time) { - long days; - long rem; - int i; - int year; - int yleap; - int year_lengths[2] = { IPS_DAYS_NORMAL_YEAR, IPS_DAYS_LEAP_YEAR }; - int month_lengths[12][2] = { {31, 31}, - {28, 29}, - {31, 31}, - {30, 30}, - {31, 31}, - {30, 30}, - {31, 31}, - {31, 31}, - {30, 30}, - {31, 31}, - {30, 30}, - {31, 31} }; - - METHOD_TRACE("ips_fix_ffdc_time", 1); - - days = current_time / IPS_SECS_DAY; - rem = current_time % IPS_SECS_DAY; - - scb->cmd.ffdc.hour = (rem / IPS_SECS_HOUR); - rem = rem % IPS_SECS_HOUR; - scb->cmd.ffdc.minute = (rem / IPS_SECS_MIN); - scb->cmd.ffdc.second = (rem % IPS_SECS_MIN); - - year = IPS_EPOCH_YEAR; - while (days < 0 || days >= year_lengths[yleap = IPS_IS_LEAP_YEAR(year)]) { - int newy; - - newy = year + (days / IPS_DAYS_NORMAL_YEAR); - if (days < 0) - --newy; - days -= (newy - year) * IPS_DAYS_NORMAL_YEAR + - IPS_NUM_LEAP_YEARS_THROUGH(newy - 1) - - IPS_NUM_LEAP_YEARS_THROUGH(year - 1); - year = newy; - } +ips_fix_ffdc_time(ips_ha_t * ha, ips_scb_t * scb, time_t current_time) +{ + long days; + long rem; + int i; + int year; + int yleap; + int year_lengths[2] = { IPS_DAYS_NORMAL_YEAR, IPS_DAYS_LEAP_YEAR }; + int month_lengths[12][2] = { {31, 31}, + {28, 29}, + {31, 31}, + {30, 30}, + {31, 31}, + {30, 30}, + {31, 31}, + {31, 31}, + {30, 30}, + {31, 31}, + {30, 30}, + {31, 31} + }; + + METHOD_TRACE("ips_fix_ffdc_time", 1); + + days = current_time / IPS_SECS_DAY; + rem = current_time % IPS_SECS_DAY; + + scb->cmd.ffdc.hour = (rem / IPS_SECS_HOUR); + rem = rem % IPS_SECS_HOUR; + scb->cmd.ffdc.minute = (rem / IPS_SECS_MIN); + scb->cmd.ffdc.second = (rem % IPS_SECS_MIN); + + year = IPS_EPOCH_YEAR; + while (days < 0 || days >= year_lengths[yleap = IPS_IS_LEAP_YEAR(year)]) { + int newy; + + newy = year + (days / IPS_DAYS_NORMAL_YEAR); + if (days < 0) + --newy; + days -= (newy - year) * IPS_DAYS_NORMAL_YEAR + + IPS_NUM_LEAP_YEARS_THROUGH(newy - 1) - + IPS_NUM_LEAP_YEARS_THROUGH(year - 1); + year = newy; + } - scb->cmd.ffdc.yearH = year / 100; - scb->cmd.ffdc.yearL = year % 100; + scb->cmd.ffdc.yearH = year / 100; + scb->cmd.ffdc.yearL = year % 100; - for (i = 0; days >= month_lengths[i][yleap]; ++i) - days -= month_lengths[i][yleap]; + for (i = 0; days >= month_lengths[i][yleap]; ++i) + days -= month_lengths[i][yleap]; - scb->cmd.ffdc.month = i + 1; - scb->cmd.ffdc.day = days + 1; + scb->cmd.ffdc.month = i + 1; + scb->cmd.ffdc.day = days + 1; } /**************************************************************************** @@ -6713,106 +6209,107 @@ /* */ /****************************************************************************/ static int -ips_erase_bios(ips_ha_t *ha) { - int timeout; - uint8_t status=0; - - METHOD_TRACE("ips_erase_bios", 1); - - status = 0; - - /* Clear the status register */ - outl(0, ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - outb(0x50, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* Erase Setup */ - outb(0x20, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* Erase Confirm */ - outb(0xD0, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* Erase Status */ - outb(0x70, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - timeout = 80000; /* 80 seconds */ - - while (timeout > 0) { - if (ha->revision_id == IPS_REVID_TROMBONE64) { - outl(0, ha->io_addr + IPS_REG_FLAP); - udelay(25); /* 25 us */ - } - - status = inb(ha->io_addr + IPS_REG_FLDP); - - if (status & 0x80) - break; - - MDELAY(1); - timeout--; - } - - /* check for timeout */ - if (timeout <= 0) { - /* timeout */ - - /* try to suspend the erase */ - outb(0xB0, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* wait for 10 seconds */ - timeout = 10000; - while (timeout > 0) { - if (ha->revision_id == IPS_REVID_TROMBONE64) { - outl(0, ha->io_addr + IPS_REG_FLAP); - udelay(25); /* 25 us */ - } - - status = inb(ha->io_addr + IPS_REG_FLDP); - - if (status & 0xC0) - break; - - MDELAY(1); - timeout--; - } - - return (1); - } - - /* check for valid VPP */ - if (status & 0x08) - /* VPP failure */ - return (1); - - /* check for succesful flash */ - if (status & 0x30) - /* sequence error */ - return (1); - - /* Otherwise, we were successful */ - /* clear status */ - outb(0x50, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* enable reads */ - outb(0xFF, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ +ips_erase_bios(ips_ha_t * ha) +{ + int timeout; + uint8_t status = 0; + + METHOD_TRACE("ips_erase_bios", 1); + + status = 0; - return (0); + /* Clear the status register */ + outl(0, ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + outb(0x50, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* Erase Setup */ + outb(0x20, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* Erase Confirm */ + outb(0xD0, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* Erase Status */ + outb(0x70, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + timeout = 80000; /* 80 seconds */ + + while (timeout > 0) { + if (ha->revision_id == IPS_REVID_TROMBONE64) { + outl(0, ha->io_addr + IPS_REG_FLAP); + udelay(25); /* 25 us */ + } + + status = inb(ha->io_addr + IPS_REG_FLDP); + + if (status & 0x80) + break; + + MDELAY(1); + timeout--; + } + + /* check for timeout */ + if (timeout <= 0) { + /* timeout */ + + /* try to suspend the erase */ + outb(0xB0, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* wait for 10 seconds */ + timeout = 10000; + while (timeout > 0) { + if (ha->revision_id == IPS_REVID_TROMBONE64) { + outl(0, ha->io_addr + IPS_REG_FLAP); + udelay(25); /* 25 us */ + } + + status = inb(ha->io_addr + IPS_REG_FLDP); + + if (status & 0xC0) + break; + + MDELAY(1); + timeout--; + } + + return (1); + } + + /* check for valid VPP */ + if (status & 0x08) + /* VPP failure */ + return (1); + + /* check for succesful flash */ + if (status & 0x30) + /* sequence error */ + return (1); + + /* Otherwise, we were successful */ + /* clear status */ + outb(0x50, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* enable reads */ + outb(0xFF, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + return (0); } /****************************************************************************/ @@ -6824,106 +6321,107 @@ /* */ /****************************************************************************/ static int -ips_erase_bios_memio(ips_ha_t *ha) { - int timeout; - uint8_t status; - - METHOD_TRACE("ips_erase_bios_memio", 1); - - status = 0; - - /* Clear the status register */ - writel(0, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - writeb(0x50, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* Erase Setup */ - writeb(0x20, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* Erase Confirm */ - writeb(0xD0, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* Erase Status */ - writeb(0x70, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - timeout = 80000; /* 80 seconds */ - - while (timeout > 0) { - if (ha->revision_id == IPS_REVID_TROMBONE64) { - writel(0, ha->mem_ptr + IPS_REG_FLAP); - udelay(25); /* 25 us */ - } - - status = readb(ha->mem_ptr + IPS_REG_FLDP); - - if (status & 0x80) - break; - - MDELAY(1); - timeout--; - } - - /* check for timeout */ - if (timeout <= 0) { - /* timeout */ - - /* try to suspend the erase */ - writeb(0xB0, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* wait for 10 seconds */ - timeout = 10000; - while (timeout > 0) { - if (ha->revision_id == IPS_REVID_TROMBONE64) { - writel(0, ha->mem_ptr + IPS_REG_FLAP); - udelay(25); /* 25 us */ - } - - status = readb(ha->mem_ptr + IPS_REG_FLDP); - - if (status & 0xC0) - break; - - MDELAY(1); - timeout--; - } - - return (1); - } - - /* check for valid VPP */ - if (status & 0x08) - /* VPP failure */ - return (1); - - /* check for succesful flash */ - if (status & 0x30) - /* sequence error */ - return (1); - - /* Otherwise, we were successful */ - /* clear status */ - writeb(0x50, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* enable reads */ - writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ +ips_erase_bios_memio(ips_ha_t * ha) +{ + int timeout; + uint8_t status; + + METHOD_TRACE("ips_erase_bios_memio", 1); - return (0); + status = 0; + + /* Clear the status register */ + writel(0, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + writeb(0x50, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* Erase Setup */ + writeb(0x20, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* Erase Confirm */ + writeb(0xD0, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* Erase Status */ + writeb(0x70, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + timeout = 80000; /* 80 seconds */ + + while (timeout > 0) { + if (ha->revision_id == IPS_REVID_TROMBONE64) { + writel(0, ha->mem_ptr + IPS_REG_FLAP); + udelay(25); /* 25 us */ + } + + status = readb(ha->mem_ptr + IPS_REG_FLDP); + + if (status & 0x80) + break; + + MDELAY(1); + timeout--; + } + + /* check for timeout */ + if (timeout <= 0) { + /* timeout */ + + /* try to suspend the erase */ + writeb(0xB0, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* wait for 10 seconds */ + timeout = 10000; + while (timeout > 0) { + if (ha->revision_id == IPS_REVID_TROMBONE64) { + writel(0, ha->mem_ptr + IPS_REG_FLAP); + udelay(25); /* 25 us */ + } + + status = readb(ha->mem_ptr + IPS_REG_FLDP); + + if (status & 0xC0) + break; + + MDELAY(1); + timeout--; + } + + return (1); + } + + /* check for valid VPP */ + if (status & 0x08) + /* VPP failure */ + return (1); + + /* check for succesful flash */ + if (status & 0x30) + /* sequence error */ + return (1); + + /* Otherwise, we were successful */ + /* clear status */ + writeb(0x50, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* enable reads */ + writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + return (0); } /****************************************************************************/ @@ -6935,84 +6433,86 @@ /* */ /****************************************************************************/ static int -ips_program_bios(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) { - int i; - int timeout; - uint8_t status=0; - - METHOD_TRACE("ips_program_bios", 1); - - status = 0; - - for (i = 0; i < buffersize; i++) { - /* write a byte */ - outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - outb(0x40, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - outb(buffer[i], ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* wait up to one second */ - timeout = 1000; - while (timeout > 0) { - if (ha->revision_id == IPS_REVID_TROMBONE64) { - outl(0, ha->io_addr + IPS_REG_FLAP); - udelay(25); /* 25 us */ - } - - status = inb(ha->io_addr + IPS_REG_FLDP); - - if (status & 0x80) - break; - - MDELAY(1); - timeout--; - } - - if (timeout == 0) { - /* timeout error */ - outl(0, ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - outb(0xFF, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - return (1); - } - - /* check the status */ - if (status & 0x18) { - /* programming error */ - outl(0, ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - outb(0xFF, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - return (1); - } - } /* end for */ - - /* Enable reading */ - outl(0, ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - outb(0xFF, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ +ips_program_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize, + uint32_t offset) +{ + int i; + int timeout; + uint8_t status = 0; + + METHOD_TRACE("ips_program_bios", 1); + + status = 0; + + for (i = 0; i < buffersize; i++) { + /* write a byte */ + outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + outb(0x40, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + outb(buffer[i], ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* wait up to one second */ + timeout = 1000; + while (timeout > 0) { + if (ha->revision_id == IPS_REVID_TROMBONE64) { + outl(0, ha->io_addr + IPS_REG_FLAP); + udelay(25); /* 25 us */ + } + + status = inb(ha->io_addr + IPS_REG_FLDP); + + if (status & 0x80) + break; + + MDELAY(1); + timeout--; + } + + if (timeout == 0) { + /* timeout error */ + outl(0, ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + outb(0xFF, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + return (1); + } + + /* check the status */ + if (status & 0x18) { + /* programming error */ + outl(0, ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + outb(0xFF, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + return (1); + } + } /* end for */ + + /* Enable reading */ + outl(0, ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + outb(0xFF, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ - return (0); + return (0); } /****************************************************************************/ @@ -7024,84 +6524,86 @@ /* */ /****************************************************************************/ static int -ips_program_bios_memio(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) { - int i; - int timeout; - uint8_t status=0; - - METHOD_TRACE("ips_program_bios_memio", 1); - - status = 0; - - for (i = 0; i < buffersize; i++) { - /* write a byte */ - writel(i + offset, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - writeb(0x40, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - writeb(buffer[i], ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* wait up to one second */ - timeout = 1000; - while (timeout > 0) { - if (ha->revision_id == IPS_REVID_TROMBONE64) { - writel(0, ha->mem_ptr + IPS_REG_FLAP); - udelay(25); /* 25 us */ - } - - status = readb(ha->mem_ptr + IPS_REG_FLDP); - - if (status & 0x80) - break; - - MDELAY(1); - timeout--; - } - - if (timeout == 0) { - /* timeout error */ - writel(0, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - return (1); - } - - /* check the status */ - if (status & 0x18) { - /* programming error */ - writel(0, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - return (1); - } - } /* end for */ - - /* Enable reading */ - writel(0, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ +ips_program_bios_memio(ips_ha_t * ha, char *buffer, uint32_t buffersize, + uint32_t offset) +{ + int i; + int timeout; + uint8_t status = 0; + + METHOD_TRACE("ips_program_bios_memio", 1); + + status = 0; + + for (i = 0; i < buffersize; i++) { + /* write a byte */ + writel(i + offset, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + writeb(0x40, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + writeb(buffer[i], ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* wait up to one second */ + timeout = 1000; + while (timeout > 0) { + if (ha->revision_id == IPS_REVID_TROMBONE64) { + writel(0, ha->mem_ptr + IPS_REG_FLAP); + udelay(25); /* 25 us */ + } + + status = readb(ha->mem_ptr + IPS_REG_FLDP); + + if (status & 0x80) + break; + + MDELAY(1); + timeout--; + } + + if (timeout == 0) { + /* timeout error */ + writel(0, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + return (1); + } + + /* check the status */ + if (status & 0x18) { + /* programming error */ + writel(0, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + return (1); + } + } /* end for */ + + /* Enable reading */ + writel(0, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ - return (0); + return (0); } /****************************************************************************/ @@ -7113,42 +6615,44 @@ /* */ /****************************************************************************/ static int -ips_verify_bios(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) { - uint8_t checksum; - int i; - - METHOD_TRACE("ips_verify_bios", 1); - - /* test 1st byte */ - outl(0, ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55) - return (1); - - outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA) - return (1); - - checksum = 0xff; - for (i = 2; i < buffersize; i++) { - - outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - checksum = (uint8_t) checksum + inb(ha->io_addr + IPS_REG_FLDP); - } - - if (checksum != 0) - /* failure */ - return (1); - else - /* success */ - return (0); +ips_verify_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize, + uint32_t offset) +{ + uint8_t checksum; + int i; + + METHOD_TRACE("ips_verify_bios", 1); + + /* test 1st byte */ + outl(0, ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55) + return (1); + + outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA) + return (1); + + checksum = 0xff; + for (i = 2; i < buffersize; i++) { + + outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + checksum = (uint8_t) checksum + inb(ha->io_addr + IPS_REG_FLDP); + } + + if (checksum != 0) + /* failure */ + return (1); + else + /* success */ + return (0); } /****************************************************************************/ @@ -7160,42 +6664,45 @@ /* */ /****************************************************************************/ static int -ips_verify_bios_memio(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) { - uint8_t checksum; - int i; - - METHOD_TRACE("ips_verify_bios_memio", 1); - - /* test 1st byte */ - writel(0, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55) - return (1); - - writel(1, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA) - return (1); - - checksum = 0xff; - for (i = 2; i < buffersize; i++) { - - writel(i + offset, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - checksum = (uint8_t) checksum + readb(ha->mem_ptr + IPS_REG_FLDP); - } - - if (checksum != 0) - /* failure */ - return (1); - else - /* success */ - return (0); +ips_verify_bios_memio(ips_ha_t * ha, char *buffer, uint32_t buffersize, + uint32_t offset) +{ + uint8_t checksum; + int i; + + METHOD_TRACE("ips_verify_bios_memio", 1); + + /* test 1st byte */ + writel(0, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55) + return (1); + + writel(1, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA) + return (1); + + checksum = 0xff; + for (i = 2; i < buffersize; i++) { + + writel(i + offset, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + checksum = + (uint8_t) checksum + readb(ha->mem_ptr + IPS_REG_FLDP); + } + + if (checksum != 0) + /* failure */ + return (1); + else + /* success */ + return (0); } /*---------------------------------------------------------------------------*/ @@ -7208,77 +6715,85 @@ /* Data is available. */ /* */ /*---------------------------------------------------------------------------*/ -static void ips_version_check(ips_ha_t *ha, int intr) { - IPS_VERSION_DATA VersionInfo; - uint8_t FirmwareVersion[ IPS_COMPAT_ID_LENGTH + 1 ]; - uint8_t BiosVersion[ IPS_COMPAT_ID_LENGTH + 1]; - int MatchError; - int rc; - char BiosString[10]; - char FirmwareString[10]; - - METHOD_TRACE("ips_version_check", 1); - - memset(FirmwareVersion, 0, IPS_COMPAT_ID_LENGTH + 1); - memset(BiosVersion, 0, IPS_COMPAT_ID_LENGTH + 1); - - /* Get the Compatible BIOS Version from NVRAM Page 5 */ - memcpy(BiosVersion, ha->nvram->BiosCompatibilityID, IPS_COMPAT_ID_LENGTH); - - rc = IPS_FAILURE; - if (ha->subsys->param[4] & IPS_GET_VERSION_SUPPORT) /* If Versioning is Supported */ - { - /* Get the Version Info with a Get Version Command */ - rc = ips_get_version_info(ha, &VersionInfo, intr); - if (rc == IPS_SUCCESS) - memcpy(FirmwareVersion, VersionInfo.compatibilityId, IPS_COMPAT_ID_LENGTH); - } - - if (rc != IPS_SUCCESS) /* If Data Not Obtainable from a GetVersion Command */ - { - /* Get the Firmware Version from Enquiry Data */ - memcpy(FirmwareVersion, ha->enq->CodeBlkVersion, IPS_COMPAT_ID_LENGTH); - } - - /* printk(KERN_WARNING "Adapter's BIOS Version = %s\n", BiosVersion); */ - /* printk(KERN_WARNING "BIOS Compatible Version = %s\n", IPS_COMPAT_BIOS); */ - /* printk(KERN_WARNING "Adapter's Firmware Version = %s\n", FirmwareVersion); */ - /* printk(KERN_WARNING "Firmware Compatible Version = %s \n", Compatable[ ha->nvram->adapter_type ]); */ - - MatchError = 0; - - if (strncmp(FirmwareVersion, Compatable[ ha->nvram->adapter_type ], IPS_COMPAT_ID_LENGTH) != 0) - MatchError = 1; - - if (strncmp(BiosVersion, IPS_COMPAT_BIOS, IPS_COMPAT_ID_LENGTH) != 0) - MatchError = 1; - - ha->nvram->versioning = 1; /* Indicate the Driver Supports Versioning */ - - if (MatchError) - { - ha->nvram->version_mismatch = 1; - if (ips_cd_boot == 0) - { - strncpy(&BiosString[0], ha->nvram->bios_high, 4); - strncpy(&BiosString[4], ha->nvram->bios_low, 4); - BiosString[8] = 0; - - strncpy(&FirmwareString[0], ha->enq->CodeBlkVersion, 8); - FirmwareString[8] = 0; - - printk(KERN_WARNING "Warning ! ! ! ServeRAID Version Mismatch\n"); - printk(KERN_WARNING "Bios = %s, Firmware = %s, Device Driver = %s%s\n", - BiosString, FirmwareString, IPS_VERSION_HIGH, IPS_VERSION_LOW ); - printk(KERN_WARNING "These levels should match to avoid possible compatibility problems.\n" ); - } - } - else - { - ha->nvram->version_mismatch = 0; - } +static void +ips_version_check(ips_ha_t * ha, int intr) +{ + IPS_VERSION_DATA *VersionInfo; + uint8_t FirmwareVersion[IPS_COMPAT_ID_LENGTH + 1]; + uint8_t BiosVersion[IPS_COMPAT_ID_LENGTH + 1]; + int MatchError; + int rc; + char BiosString[10]; + char FirmwareString[10]; + + METHOD_TRACE("ips_version_check", 1); + + VersionInfo = ( IPS_VERSION_DATA * ) ha->ioctl_data; + + memset(FirmwareVersion, 0, IPS_COMPAT_ID_LENGTH + 1); + memset(BiosVersion, 0, IPS_COMPAT_ID_LENGTH + 1); + + /* Get the Compatible BIOS Version from NVRAM Page 5 */ + memcpy(BiosVersion, ha->nvram->BiosCompatibilityID, + IPS_COMPAT_ID_LENGTH); + + rc = IPS_FAILURE; + if (ha->subsys->param[4] & IPS_GET_VERSION_SUPPORT) { /* If Versioning is Supported */ + memset( VersionInfo, 0, sizeof (IPS_VERSION_DATA)); + /* Get the Version Info with a Get Version Command */ + rc = ips_get_version_info(ha, ha->ioctl_busaddr, intr); + if (rc == IPS_SUCCESS) + memcpy(FirmwareVersion, VersionInfo->compatibilityId, + IPS_COMPAT_ID_LENGTH); + } + + if (rc != IPS_SUCCESS) { /* If Data Not Obtainable from a GetVersion Command */ + /* Get the Firmware Version from Enquiry Data */ + memcpy(FirmwareVersion, ha->enq->CodeBlkVersion, + IPS_COMPAT_ID_LENGTH); + } + + /* printk(KERN_WARNING "Adapter's BIOS Version = %s\n", BiosVersion); */ + /* printk(KERN_WARNING "BIOS Compatible Version = %s\n", IPS_COMPAT_BIOS); */ + /* printk(KERN_WARNING "Adapter's Firmware Version = %s\n", FirmwareVersion); */ + /* printk(KERN_WARNING "Firmware Compatible Version = %s \n", Compatable[ ha->nvram->adapter_type ]); */ + + MatchError = 0; + + if (strncmp + (FirmwareVersion, Compatable[ha->nvram->adapter_type], + IPS_COMPAT_ID_LENGTH) != 0) + MatchError = 1; + + if (strncmp(BiosVersion, IPS_COMPAT_BIOS, IPS_COMPAT_ID_LENGTH) != 0) + MatchError = 1; + + ha->nvram->versioning = 1; /* Indicate the Driver Supports Versioning */ + + if (MatchError) { + ha->nvram->version_mismatch = 1; + if (ips_cd_boot == 0) { + strncpy(&BiosString[0], ha->nvram->bios_high, 4); + strncpy(&BiosString[4], ha->nvram->bios_low, 4); + BiosString[8] = 0; + + strncpy(&FirmwareString[0], ha->enq->CodeBlkVersion, 8); + FirmwareString[8] = 0; + + printk(KERN_WARNING + "Warning ! ! ! ServeRAID Version Mismatch\n"); + printk(KERN_WARNING + "Bios = %s, Firmware = %s, Device Driver = %s%s\n", + BiosString, FirmwareString, IPS_VERSION_HIGH, + IPS_VERSION_LOW); + printk(KERN_WARNING + "These levels should match to avoid possible compatibility problems.\n"); + } + } else { + ha->nvram->version_mismatch = 0; + } - return; + return; } /*---------------------------------------------------------------------------*/ @@ -7290,52 +6805,225 @@ /* Return Value: */ /* 0 if Successful, else non-zero */ /*---------------------------------------------------------------------------*/ -static int ips_get_version_info(ips_ha_t *ha, IPS_VERSION_DATA *Buffer, int intr ) { - ips_scb_t *scb; - int rc; - - METHOD_TRACE("ips_get_version_info", 1); - - memset(Buffer, 0, sizeof(IPS_VERSION_DATA)); - scb = &ha->scbs[ha->max_cmds-1]; - - ips_init_scb(ha, scb); - - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_GET_VERSION_INFO; - scb->cmd.version_info.op_code = IPS_CMD_GET_VERSION_INFO; - scb->cmd.version_info.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.version_info.reserved = 0; - scb->cmd.version_info.count = sizeof( IPS_VERSION_DATA); - scb->cmd.version_info.reserved2 = 0; - scb->data_len = sizeof(*Buffer); - scb->data_busaddr = pci_map_single(ha->pcidev, Buffer, - scb->data_len, IPS_DMA_DIR(scb)); - scb->cmd.version_info.buffer_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; - - /* issue command */ - rc = ips_send_wait(ha, scb, ips_cmd_timeout, intr); - return( rc ); -} - - - -#if defined (MODULE) || (LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)) -static Scsi_Host_Template driver_template = IPS; -#include "scsi_module.c" -#endif +static int +ips_get_version_info(ips_ha_t * ha, dma_addr_t Buffer, int intr) +{ + ips_scb_t *scb; + int rc; + + METHOD_TRACE("ips_get_version_info", 1); + + scb = &ha->scbs[ha->max_cmds - 1]; + + ips_init_scb(ha, scb); + + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_GET_VERSION_INFO; + scb->cmd.version_info.op_code = IPS_CMD_GET_VERSION_INFO; + scb->cmd.version_info.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.version_info.reserved = 0; + scb->cmd.version_info.count = sizeof (IPS_VERSION_DATA); + scb->cmd.version_info.reserved2 = 0; + scb->data_len = sizeof (IPS_VERSION_DATA); + scb->data_busaddr = Buffer; + scb->cmd.version_info.buffer_addr = Buffer; + scb->flags = 0; + + /* issue command */ + rc = ips_send_wait(ha, scb, ips_cmd_timeout, intr); + return (rc); +} + +/****************************************************************************/ +/* */ +/* Routine Name: ips_abort_init */ +/* */ +/* Routine Description: */ +/* cleanup routine for a failed adapter initialization */ +/****************************************************************************/ +static int +ips_abort_init(ips_ha_t * ha, int index) +{ + ha->active = 0; + ips_free(ha); + ips_ha[index] = 0; + ips_sh[index] = 0; + return -1; +} + +/****************************************************************************/ +/* */ +/* Routine Name: ips_shift_controllers */ +/* */ +/* Routine Description: */ +/* helper function for ordering adapters */ +/****************************************************************************/ +static void +ips_shift_controllers(int lowindex, int highindex) +{ + ips_ha_t *ha_sav = ips_ha[highindex]; + struct Scsi_Host *sh_sav = ips_sh[highindex]; + int i; -static int ips_abort_init(ips_ha_t *ha, struct Scsi_Host *sh, int index){ - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[index] = 0; - ips_sh[index] = 0; - return -1; + for (i = highindex; i > lowindex; i--) { + ips_ha[i] = ips_ha[i - 1]; + ips_sh[i] = ips_sh[i - 1]; + ips_ha[i]->host_num = i; + } + ha_sav->host_num = lowindex; + ips_ha[lowindex] = ha_sav; + ips_sh[lowindex] = sh_sav; } -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) +/****************************************************************************/ +/* */ +/* Routine Name: ips_order_controllers */ +/* */ +/* Routine Description: */ +/* place controllers is the "proper" boot order */ +/****************************************************************************/ +static void +ips_order_controllers(void) +{ + int i, j, tmp, position = 0; + IPS_NVRAM_P5 *nvram; + if (!ips_ha[0]) + return; + nvram = ips_ha[0]->nvram; + + if (nvram->adapter_order[0]) { + for (i = 1; i <= nvram->adapter_order[0]; i++) { + for (j = position; j < ips_num_controllers; j++) { + switch (ips_ha[j]->ad_type) { + case IPS_ADTYPE_SERVERAID6M: + if (nvram->adapter_order[i] == 'M') { + ips_shift_controllers(position, + j); + position++; + } + break; + case IPS_ADTYPE_SERVERAID4L: + case IPS_ADTYPE_SERVERAID4M: + case IPS_ADTYPE_SERVERAID4MX: + case IPS_ADTYPE_SERVERAID4LX: + if (nvram->adapter_order[i] == 'N') { + ips_shift_controllers(position, + j); + position++; + } + break; + case IPS_ADTYPE_SERVERAID6I: + case IPS_ADTYPE_SERVERAID5I2: + case IPS_ADTYPE_SERVERAID5I1: + if (nvram->adapter_order[i] == 'S') { + ips_shift_controllers(position, + j); + position++; + } + break; + case IPS_ADTYPE_SERVERAID: + case IPS_ADTYPE_SERVERAID2: + case IPS_ADTYPE_NAVAJO: + case IPS_ADTYPE_KIOWA: + case IPS_ADTYPE_SERVERAID3L: + case IPS_ADTYPE_SERVERAID3: + case IPS_ADTYPE_SERVERAID4H: + if (nvram->adapter_order[i] == 'A') { + ips_shift_controllers(position, + j); + position++; + } + break; + default: + break; + } + } + } + /* if adapter_order[0], then ordering is complete */ + return; + } + /* old bios, use older ordering */ + tmp = 0; + for (i = position; i < ips_num_controllers; i++) { + if (ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID5I2 || + ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID5I1) { + ips_shift_controllers(position, i); + position++; + tmp = 1; + } + } + /* if there were no 5I cards, then don't do any extra ordering */ + if (!tmp) + return; + for (i = position; i < ips_num_controllers; i++) { + if (ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4L || + ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4M || + ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4LX || + ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4MX) { + ips_shift_controllers(position, i); + position++; + } + } + + return; +} + +/****************************************************************************/ +/* */ +/* Routine Name: ips_register_scsi */ +/* */ +/* Routine Description: */ +/* perform any registration and setup with the scsi layer */ +/****************************************************************************/ +static int +ips_register_scsi(int index) +{ + struct Scsi_Host *sh; + ips_ha_t *ha, *oldha; + sh = scsi_register(&ips_driver_template, sizeof (ips_ha_t)); + if (!sh) { + printk(KERN_WARNING + "Unable to register controller with SCSI subsystem\n"); + return -1; + } + oldha = ips_ha[index]; + ha = IPS_HA(sh); + memcpy(ha, oldha, sizeof (ips_ha_t)); + free_irq(oldha->irq, oldha); + /* Install the interrupt handler with the new ha */ + if (request_irq(ha->irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) { + printk(KERN_WARNING "Unable to install interrupt handler\n"); + scsi_unregister(sh); + return -1; + } + + kfree(oldha); + ips_sh[index] = sh; + ips_ha[index] = ha; + scsi_set_pci_device(sh, ha->pcidev); + + /* Store away needed values for later use */ + sh->io_port = ha->io_addr; + sh->n_io_port = ha->io_addr ? 255 : 0; + sh->unique_id = (ha->io_addr) ? ha->io_addr : ha->mem_addr; + sh->irq = ha->irq; + sh->sg_tablesize = sh->hostt->sg_tablesize; + sh->can_queue = sh->hostt->can_queue; + sh->cmd_per_lun = sh->hostt->cmd_per_lun; + sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma; + sh->use_clustering = sh->hostt->use_clustering; + +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7) + sh->max_sectors = 128; +#endif + + sh->max_id = ha->ntargets; + sh->max_lun = ha->nlun; + sh->max_channel = ha->nbus - 1; + sh->can_queue = ha->max_cmds - 1; + + return 0; +} /*---------------------------------------------------------------------------*/ /* Routine Name: ips_remove_device */ @@ -7343,24 +7031,64 @@ /* Routine Description: */ /* Remove one Adapter ( Hot Plugging ) */ /*---------------------------------------------------------------------------*/ -static void ips_remove_device(struct pci_dev *pci_dev) +static void +ips_remove_device(struct pci_dev *pci_dev) +{ + int i; + struct Scsi_Host *sh; + ips_ha_t *ha; + + for (i = 0; i < IPS_MAX_ADAPTERS; i++) { + ha = ips_ha[i]; + if (ha) { + if ((pci_dev->bus->number == ha->pcidev->bus->number) && + (pci_dev->devfn == ha->pcidev->devfn)) { + sh = ips_sh[i]; + ips_release(sh); + } + } + } +} + +/****************************************************************************/ +/* */ +/* Routine Name: ips_module_init */ +/* */ +/* Routine Description: */ +/* function called on module load */ +/****************************************************************************/ +static int __init +ips_module_init(void) +{ + if (pci_module_init(&ips_pci_driver) < 0) + return -ENODEV; + ips_driver_template.module = THIS_MODULE; + ips_order_controllers(); + if (scsi_register_module(MODULE_SCSI_HA, &ips_driver_template)) { + pci_unregister_driver(&ips_pci_driver); + return -ENODEV; + } + register_reboot_notifier(&ips_notifier); + return 0; +} + +/****************************************************************************/ +/* */ +/* Routine Name: ips_module_exit */ +/* */ +/* Routine Description: */ +/* function called on module unload */ +/****************************************************************************/ +static void __exit +ips_module_exit(void) { - int i; - struct Scsi_Host *sh; - ips_ha_t *ha; - - for (i = 0; i < IPS_MAX_ADAPTERS; i++) { - ha = ips_ha[i]; - if (ha) { - if ( (pci_dev->bus->number == ha->pcidev->bus->number) && - (pci_dev->devfn == ha->pcidev->devfn)) { - sh = ips_sh[i]; - ips_release(sh); - } - } - } + scsi_unregister_module(MODULE_SCSI_HA, &ips_driver_template); + pci_unregister_driver(&ips_pci_driver); + unregister_reboot_notifier(&ips_notifier); } +module_init(ips_module_init); +module_exit(ips_module_exit); /*---------------------------------------------------------------------------*/ /* Routine Name: ips_insert_device */ @@ -7371,40 +7099,28 @@ /* Return Value: */ /* 0 if Successful, else non-zero */ /*---------------------------------------------------------------------------*/ -static int __devinit ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent) +static int __devinit +ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent) { - int index; - int rc; + int index; + int rc; - METHOD_TRACE("ips_insert_device", 1); + METHOD_TRACE("ips_insert_device", 1); - /* If we're still in Init State 0, and we've already found the Adapter */ - /* Ordering Table, there is no reason to continue. */ - if ( (InitState == 0) && (AdapterOrder[0]) ) - return -1; - - if (pci_enable_device(pci_dev)) + if (pci_enable_device(pci_dev)) return -1; - rc = ips_init_phase1(pci_dev, &index); - if (rc == SUCCESS) - rc = ips_init_phase2(index); - - /* If we're in Init State 0, we're done with the device for now. */ - /* Release the device and don't count it. */ - if ( InitState == 0 ) { - ips_remove_device(pci_dev); - return -1; - } + rc = ips_init_phase1(pci_dev, &index); + if (rc == SUCCESS) + rc = ips_init_phase2(index); - if (rc == SUCCESS) - ips_num_controllers++; + if (rc == SUCCESS) + ips_num_controllers++; - ips_next_controller = ips_num_controllers; - return rc; + ips_next_controller = ips_num_controllers; + return rc; } - /*---------------------------------------------------------------------------*/ /* Routine Name: ips_init_phase1 */ /* */ @@ -7414,248 +7130,244 @@ /* Return Value: */ /* 0 if Successful, else non-zero */ /*---------------------------------------------------------------------------*/ -static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ) -{ - struct Scsi_Host *sh; - ips_ha_t *ha; - uint32_t io_addr; - uint32_t mem_addr; - uint32_t io_len; - uint32_t mem_len; - uint8_t revision_id; - uint8_t bus; - uint8_t func; - uint8_t irq; - uint16_t subdevice_id; - int j; - int index; - uint32_t count; - dma_addr_t dma_address; - char *ioremap_ptr; - char *mem_ptr; - uint32_t IsDead - - METHOD_TRACE("ips_init_phase1", 1); - index = IPS_MAX_ADAPTERS; - for (j = 0; j < IPS_MAX_ADAPTERS; j++) { - if (ips_ha[j] ==0) { - index = j; - break; - } - } - - if (index >= IPS_MAX_ADAPTERS) - return -1; - - /* stuff that we get in dev */ - irq = pci_dev->irq; - bus = pci_dev->bus->number; - func = pci_dev->devfn; - - /* Init MEM/IO addresses to 0 */ - mem_addr = 0; - io_addr = 0; - mem_len = 0; - io_len = 0; - - for (j = 0; j < 2; j++) { - if (!pci_resource_start(pci_dev, j)) - break; - - if (pci_resource_flags(pci_dev, j) & IORESOURCE_IO) { - io_addr = pci_resource_start(pci_dev, j); - io_len = pci_resource_len(pci_dev, j); - } else { - mem_addr = pci_resource_start(pci_dev, j); - mem_len = pci_resource_len(pci_dev, j); - } - } - - /* setup memory mapped area (if applicable) */ - if (mem_addr) { - uint32_t base; - uint32_t offs; - - if (check_mem_region(mem_addr, mem_len)) { - printk(KERN_WARNING "Couldn't allocate IO Memory space %x len %d.\n", mem_addr, mem_len); - return -1; - } - - request_mem_region(mem_addr, mem_len, "ips"); - base = mem_addr & PAGE_MASK; - offs = mem_addr - base; - ioremap_ptr = ioremap(base, PAGE_SIZE); - mem_ptr = ioremap_ptr + offs; - } else { - ioremap_ptr = NULL; - mem_ptr = NULL; - } - - /* setup I/O mapped area (if applicable) */ - if (io_addr) { - if (check_region(io_addr, io_len)) { - printk(KERN_WARNING "Couldn't allocate IO space %x len %d.\n", io_addr, io_len); - return -1; - } - request_region(io_addr, io_len, "ips"); - } - - /* get the revision ID */ - if (pci_read_config_byte(pci_dev, PCI_REVISION_ID, &revision_id)) { - printk(KERN_WARNING "Can't get revision id.\n" ); - return -1; - } - - subdevice_id = pci_dev->subsystem_device; - - /* found a controller */ - sh = scsi_register(&driver_template, sizeof(ips_ha_t)); -#if LINUX_VERSION_CODE > LinuxVersionCode(2,5,0) - pci_set_dma_mask(pci_dev, (u64)0xffffffff); - scsi_set_pci_device(sh, pci_dev); -#endif - if (sh == NULL) { - printk(KERN_WARNING "Unable to register controller with SCSI subsystem\n" ); - return -1; - } +static int +ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr) +{ + ips_ha_t *ha; + uint32_t io_addr; + uint32_t mem_addr; + uint32_t io_len; + uint32_t mem_len; + uint8_t revision_id; + uint8_t bus; + uint8_t func; + uint8_t irq; + uint16_t subdevice_id; + int j; + int index; + dma_addr_t dma_address; + char *ioremap_ptr; + char *mem_ptr; + uint32_t IsDead; + + METHOD_TRACE("ips_init_phase1", 1); + index = IPS_MAX_ADAPTERS; + for (j = 0; j < IPS_MAX_ADAPTERS; j++) { + if (ips_ha[j] == 0) { + index = j; + break; + } + } - ha = IPS_HA(sh); - memset(ha, 0, sizeof(ips_ha_t)); - - ips_sh[index] = sh; - ips_ha[index] = ha; - ha->active = 1; - - ha->enq = kmalloc(sizeof(IPS_ENQ), GFP_KERNEL); - - if (!ha->enq) { - printk(KERN_WARNING "Unable to allocate host inquiry structure\n" ); - return ips_abort_init(ha, sh, index); - } - - ha->adapt = pci_alloc_consistent(pci_dev, sizeof(IPS_ADAPTER) + - sizeof(IPS_IO_CMD), &dma_address); - if (!ha->adapt) { - printk(KERN_WARNING "Unable to allocate host adapt & dummy structures\n"); - return ips_abort_init(ha, sh, index); - } - ha->adapt->hw_status_start = dma_address; - ha->dummy = (void *)(ha->adapt + 1); - - ha->conf = kmalloc(sizeof(IPS_CONF), GFP_KERNEL); - - if (!ha->conf) { - printk(KERN_WARNING "Unable to allocate host conf structure\n" ); - return ips_abort_init(ha, sh, index); - } - - ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_KERNEL); - - if (!ha->nvram) { - printk(KERN_WARNING "Unable to allocate host NVRAM structure\n" ); - return ips_abort_init(ha, sh, index); - } - - ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_KERNEL); - - if (!ha->subsys) { - printk(KERN_WARNING "Unable to allocate host subsystem structure\n" ); - return ips_abort_init(ha, sh, index); - } - - for (count = PAGE_SIZE, ha->ioctl_order = 0; - count < ips_ioctlsize; - ha->ioctl_order++, count <<= 1); - - ha->ioctl_data = (char *) __get_free_pages(GFP_KERNEL, ha->ioctl_order); - ha->ioctl_datasize = count; - - if (!ha->ioctl_data) { - printk(KERN_WARNING "Unable to allocate IOCTL data\n" ); - ha->ioctl_data = NULL; - ha->ioctl_order = 0; - ha->ioctl_datasize = 0; - } - - /* Store away needed values for later use */ - sh->io_port = io_addr; - sh->n_io_port = io_addr ? 255 : 0; - sh->unique_id = (io_addr) ? io_addr : mem_addr; - sh->irq = irq; - sh->select_queue_depths = ips_select_queue_depth; - sh->sg_tablesize = sh->hostt->sg_tablesize; - sh->can_queue = sh->hostt->can_queue; - sh->cmd_per_lun = sh->hostt->cmd_per_lun; - sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma; - sh->use_clustering = sh->hostt->use_clustering; + if (index >= IPS_MAX_ADAPTERS) + return -1; -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7) - sh->max_sectors = 128; -#endif + /* stuff that we get in dev */ + irq = pci_dev->irq; + bus = pci_dev->bus->number; + func = pci_dev->devfn; + + /* Init MEM/IO addresses to 0 */ + mem_addr = 0; + io_addr = 0; + mem_len = 0; + io_len = 0; + + for (j = 0; j < 2; j++) { + if (!pci_resource_start(pci_dev, j)) + break; + + if (pci_resource_flags(pci_dev, j) & IORESOURCE_IO) { + io_addr = pci_resource_start(pci_dev, j); + io_len = pci_resource_len(pci_dev, j); + } else { + mem_addr = pci_resource_start(pci_dev, j); + mem_len = pci_resource_len(pci_dev, j); + } + } + + /* setup memory mapped area (if applicable) */ + if (mem_addr) { + uint32_t base; + uint32_t offs; + + if (!request_mem_region(mem_addr, mem_len, "ips")) { + printk(KERN_WARNING + "Couldn't allocate IO Memory space %x len %d.\n", + mem_addr, mem_len); + return -1; + } + + base = mem_addr & PAGE_MASK; + offs = mem_addr - base; + ioremap_ptr = ioremap(base, PAGE_SIZE); + mem_ptr = ioremap_ptr + offs; + } else { + ioremap_ptr = NULL; + mem_ptr = NULL; + } + + /* setup I/O mapped area (if applicable) */ + if (io_addr) { + if (!request_region(io_addr, io_len, "ips")) { + printk(KERN_WARNING + "Couldn't allocate IO space %x len %d.\n", + io_addr, io_len); + return -1; + } + } + + /* get the revision ID */ + if (pci_read_config_byte(pci_dev, PCI_REVISION_ID, &revision_id)) { + printk(KERN_WARNING "Can't get revision id.\n"); + return -1; + } - /* Store info in HA structure */ - ha->irq = irq; - ha->io_addr = io_addr; - ha->io_len = io_len; - ha->mem_addr = mem_addr; - ha->mem_len = mem_len; - ha->mem_ptr = mem_ptr; - ha->ioremap_ptr = ioremap_ptr; - ha->host_num = ( uint32_t) index; - ha->revision_id = revision_id; - ha->slot_num = PCI_SLOT(pci_dev->devfn); - ha->device_id = pci_dev->device; - ha->subdevice_id = subdevice_id; - ha->pcidev = pci_dev; - - /* - * Setup Functions - */ - ips_setup_funclist(ha); - - if ( ( IPS_IS_MORPHEUS( ha ) ) || ( IPS_IS_MARCO( ha ) ) ) { - /* If Morpheus appears dead, reset it */ - IsDead = readl( ha->mem_ptr + IPS_REG_I960_MSG1 ); - if ( IsDead == 0xDEADBEEF ) { - ips_reset_morpheus( ha ); - } - } - - /* - * Initialize the card if it isn't already - */ - - if (!(*ha->func.isinit)(ha)) { - if (!(*ha->func.init)(ha)) { - /* - * Initialization failed - */ - printk(KERN_WARNING "Unable to initialize controller\n" ); - return ips_abort_init(ha, sh, index); - } - } - - /* Install the interrupt handler */ - if (request_irq(irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) { - printk(KERN_WARNING "Unable to install interrupt handler\n" ); - return ips_abort_init(ha, sh, index); - } - - /* - * Allocate a temporary SCB for initialization - */ - ha->max_cmds = 1; - if (!ips_allocatescbs(ha)) { - printk(KERN_WARNING "Unable to allocate a CCB\n" ); - free_irq(ha->irq, ha); - return ips_abort_init(ha, sh, index); - } + subdevice_id = pci_dev->subsystem_device; - *indexPtr = index; - return SUCCESS; -} + /* found a controller */ + ha = kmalloc(sizeof (ips_ha_t), GFP_KERNEL); + if (ha == NULL) { + printk(KERN_WARNING "Unable to allocate temporary ha struct\n"); + return -1; + } -#endif + memset(ha, 0, sizeof (ips_ha_t)); + + ips_sh[index] = NULL; + ips_ha[index] = ha; + ha->active = 1; + + /* Store info in HA structure */ + ha->irq = irq; + ha->io_addr = io_addr; + ha->io_len = io_len; + ha->mem_addr = mem_addr; + ha->mem_len = mem_len; + ha->mem_ptr = mem_ptr; + ha->ioremap_ptr = ioremap_ptr; + ha->host_num = (uint32_t) index; + ha->revision_id = revision_id; + ha->slot_num = PCI_SLOT(pci_dev->devfn); + ha->device_id = pci_dev->device; + ha->subdevice_id = subdevice_id; + ha->pcidev = pci_dev; + + /* + * Set the pci_dev's dma_mask. Not all adapters support 64bit + * addressing so don't enable it if the adapter can't support + * it! Also, don't use 64bit addressing if dma addresses + * are guaranteed to be < 4G. + */ + if (IPS_ENABLE_DMA64 && IPS_HAS_ENH_SGLIST(ha) && + !pci_set_dma_mask(ha->pcidev, 0xffffffffffffffffULL)) { + (ha)->flags |= IPS_HA_ENH_SG; + } else { + if (pci_set_dma_mask(ha->pcidev, 0xffffffffULL) != 0) { + printk(KERN_WARNING "Unable to set DMA Mask\n"); + return ips_abort_init(ha, index); + } + } + if(ips_cd_boot && !ips_FlashData){ + ips_FlashData = pci_alloc_consistent(pci_dev, PAGE_SIZE << 7, + &ips_flashbusaddr); + } + + ha->enq = pci_alloc_consistent(pci_dev, sizeof (IPS_ENQ), + &ha->enq_busaddr); + if (!ha->enq) { + printk(KERN_WARNING + "Unable to allocate host inquiry structure\n"); + return ips_abort_init(ha, index); + } + + ha->adapt = pci_alloc_consistent(pci_dev, sizeof (IPS_ADAPTER) + + sizeof (IPS_IO_CMD), &dma_address); + if (!ha->adapt) { + printk(KERN_WARNING + "Unable to allocate host adapt & dummy structures\n"); + return ips_abort_init(ha, index); + } + ha->adapt->hw_status_start = dma_address; + ha->dummy = (void *) (ha->adapt + 1); + + ha->logical_drive_info = pci_alloc_consistent(pci_dev, sizeof (IPS_LD_INFO), + &dma_address); + if (!ha->logical_drive_info) { + printk(KERN_WARNING + "Unable to allocate host logical drive info structure\n"); + return ips_abort_init(ha, index); + } + ha->logical_drive_info_dma_addr = dma_address; + + ha->conf = kmalloc(sizeof (IPS_CONF), GFP_KERNEL); + + if (!ha->conf) { + printk(KERN_WARNING "Unable to allocate host conf structure\n"); + return ips_abort_init(ha, index); + } + + ha->nvram = kmalloc(sizeof (IPS_NVRAM_P5), GFP_KERNEL); + + if (!ha->nvram) { + printk(KERN_WARNING + "Unable to allocate host NVRAM structure\n"); + return ips_abort_init(ha, index); + } + + ha->subsys = kmalloc(sizeof (IPS_SUBSYS), GFP_KERNEL); + + if (!ha->subsys) { + printk(KERN_WARNING + "Unable to allocate host subsystem structure\n"); + return ips_abort_init(ha, index); + } + + /* the ioctl buffer is now used during adapter initialization, so its + * successful allocation is now required */ + if (ips_ioctlsize < PAGE_SIZE) + ips_ioctlsize = PAGE_SIZE; + + ha->ioctl_data = pci_alloc_consistent(pci_dev, ips_ioctlsize, + &ha->ioctl_busaddr); + ha->ioctl_len = ips_ioctlsize; + + if (!ha->ioctl_data) { + printk(KERN_WARNING "Unable to allocate IOCTL data\n"); + return ips_abort_init(ha, index); + } + + /* + * Setup Functions + */ + ips_setup_funclist(ha); + + if ((IPS_IS_MORPHEUS(ha)) || (IPS_IS_MARCO(ha))) { + /* If Morpheus appears dead, reset it */ + IsDead = readl(ha->mem_ptr + IPS_REG_I960_MSG1); + if (IsDead == 0xDEADBEEF) { + ips_reset_morpheus(ha); + } + } + + /* + * Initialize the card if it isn't already + */ + + if (!(*ha->func.isinit) (ha)) { + if (!(*ha->func.init) (ha)) { + /* + * Initialization failed + */ + printk(KERN_WARNING + "Unable to initialize controller\n"); + return ips_abort_init(ha, index); + } + } + + *indexPtr = index; + return SUCCESS; +} /*---------------------------------------------------------------------------*/ /* Routine Name: ips_init_phase2 */ @@ -7666,46 +7378,52 @@ /* Return Value: */ /* 0 if Successful, else non-zero */ /*---------------------------------------------------------------------------*/ -static int ips_init_phase2( int index ) -{ - struct Scsi_Host *sh; - ips_ha_t *ha; - - ha = ips_ha[index]; - sh = ips_sh[index]; - - METHOD_TRACE("ips_init_phase2", 1); - if (!ha->active) { - scsi_unregister(sh); - ips_ha[index] = NULL; - ips_sh[index] = NULL; - return -1;; - } - - if (!ips_hainit(ha)) { - printk(KERN_WARNING "Unable to initialize controller\n" ); - free_irq(ha->irq, ha); - return ips_abort_init(ha, sh, index); - } - /* Free the temporary SCB */ - ips_deallocatescbs(ha, 1); - - /* allocate CCBs */ - if (!ips_allocatescbs(ha)) { - printk(KERN_WARNING "Unable to allocate CCBs\n" ); - free_irq(ha->irq, ha); - return ips_abort_init(ha, sh, index); - } - - /* finish setting values */ - sh->max_id = ha->ntargets; - sh->max_lun = ha->nlun; - sh->max_channel = ha->nbus - 1; - sh->can_queue = ha->max_cmds-1; +static int +ips_init_phase2(int index) +{ + ips_ha_t *ha; - return SUCCESS; -} + ha = ips_ha[index]; + + METHOD_TRACE("ips_init_phase2", 1); + if (!ha->active) { + ips_ha[index] = NULL; + return -1; + } + + /* Install the interrupt handler */ + if (request_irq(ha->irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) { + printk(KERN_WARNING "Unable to install interrupt handler\n"); + return ips_abort_init(ha, index); + } + + /* + * Allocate a temporary SCB for initialization + */ + ha->max_cmds = 1; + if (!ips_allocatescbs(ha)) { + printk(KERN_WARNING "Unable to allocate a CCB\n"); + free_irq(ha->irq, ha); + return ips_abort_init(ha, index); + } + + if (!ips_hainit(ha)) { + printk(KERN_WARNING "Unable to initialize controller\n"); + free_irq(ha->irq, ha); + return ips_abort_init(ha, index); + } + /* Free the temporary SCB */ + ips_deallocatescbs(ha, 1); + + /* allocate CCBs */ + if (!ips_allocatescbs(ha)) { + printk(KERN_WARNING "Unable to allocate CCBs\n"); + free_irq(ha->irq, ha); + return ips_abort_init(ha, index); + } + return SUCCESS; +} #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,9) MODULE_LICENSE("GPL"); Index: drivers/scsi/ips.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/ips.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/ips.h 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/ips.h 4 Aug 2004 01:29:35 -0000 1.2 @@ -69,6 +69,13 @@ #define LinuxVersionCode(x,y,z) (((x)<<16)+((y)<<8)+(z)) #endif + #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,20) || defined CONFIG_HIGHIO + #define IPS_HIGHIO + #define IPS_HIGHMEM_IO .highmem_io = 1, + #else + #define IPS_HIGHMEM_IO + #endif + #define IPS_HA(x) ((ips_ha_t *) x->hostdata) #define IPS_COMMAND_ID(ha, scb) (int) (scb - ha->scbs) #define IPS_IS_TROMBONE(ha) (((ha->device_id == IPS_DEVICEID_COPPERHEAD) && \ @@ -86,10 +93,33 @@ ((IPS_IS_TROMBONE(ha) || IPS_IS_CLARINET(ha)) && \ (ips_force_memio))) ? 1 : 0) + #define IPS_HAS_ENH_SGLIST(ha) (IPS_IS_MORPHEUS(ha) || IPS_IS_MARCO(ha)) + #define IPS_USE_ENH_SGLIST(ha) ((ha)->flags & IPS_HA_ENH_SG) + #define IPS_SGLIST_SIZE(ha) (IPS_USE_ENH_SGLIST(ha) ? \ + sizeof(IPS_ENH_SG_LIST) : sizeof(IPS_STD_SG_LIST)) + + #if LINUX_VERSION_CODE < LinuxVersionCode(2,4,4) + #define pci_set_dma_mask(dev,mask) ( mask > 0xffffffff ? 1:0 ) + #define scsi_set_pci_device(sh,dev) (0) + #endif + #ifndef MDELAY #define MDELAY mdelay #endif - + + #ifndef min + #define min(x,y) ((x) < (y) ? x : y) + #endif + + #define pci_dma_hi32(a) ((a >> 16) >> 16) + #define pci_dma_lo32(a) (a & 0xffffffff) + + #if (BITS_PER_LONG > 32) || (defined CONFIG_HIGHMEM64G && defined IPS_HIGHIO) + #define IPS_ENABLE_DMA64 (1) + #else + #define IPS_ENABLE_DMA64 (0) + #endif + /* * Adapter address map equates */ @@ -354,6 +384,12 @@ #define IPS_SCSI_MP3_AllocateSurface 0x08 /* + * HA Flags + */ + + #define IPS_HA_ENH_SG 0x1 + + /* * SCB Flags */ #define IPS_SCB_MAP_SG 0x00008 @@ -390,93 +426,45 @@ /* * Scsi_Host Template */ -#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) - #define IPS { \ - next : NULL, \ - module : NULL, \ - proc_info : NULL, \ - proc_dir : NULL, \ - name : NULL, \ - detect : ips_detect, \ - release : ips_release, \ - info : ips_info, \ - command : NULL, \ - queuecommand : ips_queue, \ - eh_strategy_handler : NULL, \ - eh_abort_handler : ips_eh_abort, \ - eh_device_reset_handler : NULL, \ - eh_bus_reset_handler : NULL, \ - eh_host_reset_handler : ips_eh_reset, \ - abort : NULL, \ - reset : NULL, \ - slave_attach : NULL, \ - bios_param : ips_biosparam, \ - can_queue : 0, \ - this_id: -1, \ - sg_tablesize : IPS_MAX_SG, \ - cmd_per_lun: 16, \ - present : 0, \ - unchecked_isa_dma : 0, \ - use_clustering : ENABLE_CLUSTERING, \ - use_new_eh_code : 1 \ -} -#elif LINUX_VERSION_CODE < LinuxVersionCode(2,5,0) - #define IPS { \ - next : NULL, \ - module : NULL, \ - proc_info : NULL, \ - name : NULL, \ - detect : ips_detect, \ - release : ips_release, \ - info : ips_info, \ - command : NULL, \ - queuecommand : ips_queue, \ - eh_strategy_handler : NULL, \ - eh_abort_handler : ips_eh_abort, \ - eh_device_reset_handler : NULL, \ - eh_bus_reset_handler : NULL, \ - eh_host_reset_handler : ips_eh_reset, \ - abort : NULL, \ - reset : NULL, \ - slave_attach : NULL, \ - bios_param : ips_biosparam, \ - can_queue : 0, \ - this_id: -1, \ - sg_tablesize : IPS_MAX_SG, \ - cmd_per_lun: 16, \ - present : 0, \ - unchecked_isa_dma : 0, \ - use_clustering : ENABLE_CLUSTERING, \ - use_new_eh_code : 1 \ +#if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0) + static void ips_select_queue_depth(struct Scsi_Host *, Scsi_Device *); +#define IPS { \ + .detect = ips_detect, \ + .release = ips_release, \ + .info = ips_info, \ + .queuecommand = ips_queue, \ + .eh_abort_handler = ips_eh_abort, \ + .eh_host_reset_handler = ips_eh_reset, \ + .bios_param = ips_biosparam,\ + .select_queue_depths = ips_select_queue_depth, \ + .can_queue = 0, \ + .this_id = -1, \ + .sg_tablesize = IPS_MAX_SG, \ + .cmd_per_lun = 16, \ + .present = 0, \ + .unchecked_isa_dma = 0, \ + .use_clustering = ENABLE_CLUSTERING,\ + .use_new_eh_code = 1, \ + IPS_HIGHMEM_IO \ } #else - #define IPS { \ - next : NULL, \ - module : NULL, \ - proc_info : NULL, \ - name : NULL, \ - detect : ips_detect, \ - release : ips_release, \ - info : ips_info, \ - command : NULL, \ - queuecommand : ips_queue, \ - eh_strategy_handler : NULL, \ - eh_abort_handler : ips_eh_abort, \ - eh_device_reset_handler : NULL, \ - eh_bus_reset_handler : NULL, \ - eh_host_reset_handler : ips_eh_reset, \ - abort : NULL, \ - reset : NULL, \ - slave_attach : NULL, \ - bios_param : ips_biosparam, \ - can_queue : 0, \ - this_id: -1, \ - sg_tablesize : IPS_MAX_SG, \ - cmd_per_lun: 16, \ - present : 0, \ - unchecked_isa_dma : 0, \ - use_clustering : ENABLE_CLUSTERING, \ - highmem_io : 1 \ +#define IPS { \ + .detect = ips_detect, \ + .release = ips_release, \ + .info = ips_info, \ + .queuecommand = ips_queue, \ + .eh_abort_handler = ips_eh_abort, \ + .eh_host_reset_handler = ips_eh_reset, \ + .slave_configure = ips_slave_configure, \ + .bios_param = ips_biosparam, \ + .can_queue = 0, \ + .this_id = -1, \ + .sg_tablesize = IPS_MAX_SG, \ + .cmd_per_lun = 3, \ + .present = 0, \ + .unchecked_isa_dma = 0, \ + .use_clustering = ENABLE_CLUSTERING, \ + .highmem_io = 1 \ } #endif @@ -491,7 +479,8 @@ uint32_t lba; uint32_t sg_addr; uint16_t sector_count; - uint16_t reserved; + uint8_t segment_4G; + uint8_t enhanced_sg; uint32_t ccsar; uint32_t cccr; } IPS_IO_CMD, *PIPS_IO_CMD; @@ -542,7 +531,9 @@ uint16_t reserved; uint32_t reserved2; uint32_t dcdb_address; - uint32_t reserved3; + uint16_t reserved3; + uint8_t segment_4G; + uint8_t enhanced_sg; uint32_t ccsar; uint32_t cccr; } IPS_DCDB_CMD, *PIPS_DCDB_CMD; @@ -734,7 +725,6 @@ volatile PIPS_STATUS p_status_tail; volatile uint32_t hw_status_start; volatile uint32_t hw_status_tail; - IPS_LD_INFO logical_drive_info; } IPS_ADAPTER, *PIPS_ADAPTER; typedef struct { @@ -986,7 +976,20 @@ typedef struct ips_sglist { uint32_t address; uint32_t length; -} IPS_SG_LIST, *PIPS_SG_LIST; +} IPS_STD_SG_LIST; + +typedef struct ips_enh_sglist { + uint32_t address_lo; + uint32_t address_hi; + uint32_t length; + uint32_t reserved; +} IPS_ENH_SG_LIST; + +typedef union { + void *list; + IPS_STD_SG_LIST *std_list; + IPS_ENH_SG_LIST *enh_list; +} IPS_SG_LIST; typedef struct _IPS_INFOSTR { char *buffer; @@ -1079,6 +1082,8 @@ ips_scb_queue_t scb_activelist; /* Active SCB list */ IPS_IO_CMD *dummy; /* dummy command */ IPS_ADAPTER *adapt; /* Adapter status area */ + IPS_LD_INFO *logical_drive_info; /* Logical Drive Info */ + dma_addr_t logical_drive_info_dma_addr; /* Logical Drive Info DMA Address */ IPS_ENQ *enq; /* Adapter Enquiry data */ IPS_CONF *conf; /* Adapter config data */ IPS_NVRAM_P5 *nvram; /* NVRAM page 5 data */ @@ -1086,6 +1091,7 @@ char *ioctl_data; /* IOCTL data area */ uint32_t ioctl_datasize; /* IOCTL data size */ uint32_t cmd_in_progress; /* Current command in progress*/ + int flags; /* */ uint8_t waitflag; /* are we waiting for cmd */ uint8_t active; int ioctl_reset; /* IOCTL Requested Reset Flag */ @@ -1095,7 +1101,8 @@ uint16_t device_id; /* PCI device ID */ uint8_t slot_num; /* PCI Slot Number */ uint16_t subdevice_id; /* Subsystem device ID */ - uint8_t ioctl_order; /* Number of pages in ioctl */ + int ioctl_len; /* size of ioctl buffer */ + dma_addr_t ioctl_busaddr; /* dma address of ioctl buffer*/ uint8_t bios_version[8]; /* BIOS Revision */ uint32_t mem_addr; /* Memory mapped address */ uint32_t io_len; /* Size of IO Address */ @@ -1105,8 +1112,10 @@ ips_hw_func_t func; /* hw function pointers */ struct pci_dev *pcidev; /* PCI device handle */ char *flash_data; /* Save Area for flash data */ - u8 flash_order; /* Save Area for flash size order */ + int flash_len; /* length of flash buffer */ u32 flash_datasize; /* Save Area for flash data size */ + dma_addr_t flash_busaddr; /* dma address of flash buffer*/ + dma_addr_t enq_busaddr; /* dma address of enq struct */ uint8_t requires_esl; /* Requires an EraseStripeLock */ } ips_ha_t; @@ -1122,8 +1131,8 @@ uint8_t bus; uint8_t lun; uint8_t cdb[12]; - uint32_t scb_busaddr; - uint32_t data_busaddr; + uint32_t scb_busaddr; + uint32_t old_data_busaddr; // Obsolete field left in to not break utilities uint32_t timeout; uint8_t basic_status; uint8_t extended_status; @@ -1133,12 +1142,13 @@ uint32_t sg_len; uint32_t flags; uint32_t op_code; - IPS_SG_LIST *sg_list; + IPS_SG_LIST sg_list; Scsi_Cmnd *scsi_cmd; struct ips_scb *q_next; ips_scb_callback callback; uint32_t sg_busaddr; int sg_count; + dma_addr_t data_busaddr; } ips_scb_t; typedef struct ips_scb_pt { @@ -1194,11 +1204,13 @@ #define IPS_VER_MAJOR 6 #define IPS_VER_MAJOR_STRING "6" -#define IPS_VER_MINOR 00 -#define IPS_VER_MINOR_STRING "00" -#define IPS_VER_BUILD 26 -#define IPS_VER_BUILD_STRING "26" -#define IPS_VER_STRING "6.00.26" +#define IPS_VER_MINOR 11 +#define IPS_VER_MINOR_STRING "11" +#define IPS_VER_BUILD 07 +#define IPS_VER_BUILD_STRING "07" +#define IPS_VER_STRING "6.11.07" +#define IPS_RELEASE_ID 0x00010001 +#define IPS_BUILD_IDENT 2224 #define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2003. All Rights Reserved." #define IPS_ADAPTECCOPYRIGHT_STRING "(c) Copyright Adaptec, Inc. 2002 to present. All Rights Reserved." #define IPS_NT_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2003." @@ -1207,31 +1219,33 @@ #define IPS_VER_SERVERAID1 "2.25.01" #define IPS_VER_SERVERAID2 "2.88.13" #define IPS_VER_NAVAJO "2.88.13" -#define IPS_VER_SERVERAID3 "6.00.26" -#define IPS_VER_SERVERAID4H "6.00.26" -#define IPS_VER_SERVERAID4MLx "6.00.26" -#define IPS_VER_SARASOTA "6.00.26" -#define IPS_VER_MARCO "6.00.26" +#define IPS_VER_SERVERAID3 "6.10.24" +#define IPS_VER_SERVERAID4H "6.11.07" +#define IPS_VER_SERVERAID4MLx "6.11.07" +#define IPS_VER_SARASOTA "6.11.07" +#define IPS_VER_MARCO "6.11.07" +#define IPS_VER_SEBRING "6.11.07" /* Compatability IDs for various adapters */ #define IPS_COMPAT_UNKNOWN "" -#define IPS_COMPAT_CURRENT "MR600" +#define IPS_COMPAT_CURRENT "SB610" #define IPS_COMPAT_SERVERAID1 "2.25.01" #define IPS_COMPAT_SERVERAID2 "2.88.13" #define IPS_COMPAT_NAVAJO "2.88.13" #define IPS_COMPAT_KIOWA "2.88.13" -#define IPS_COMPAT_SERVERAID3H "MR600" -#define IPS_COMPAT_SERVERAID3L "MR600" -#define IPS_COMPAT_SERVERAID4H "MR600" -#define IPS_COMPAT_SERVERAID4M "MR600" -#define IPS_COMPAT_SERVERAID4L "MR600" -#define IPS_COMPAT_SERVERAID4Mx "MR600" -#define IPS_COMPAT_SERVERAID4Lx "MR600" -#define IPS_COMPAT_SARASOTA "MR600" -#define IPS_COMPAT_MARCO "MR600" -#define IPS_COMPAT_BIOS "MR600" +#define IPS_COMPAT_SERVERAID3H "SB610" +#define IPS_COMPAT_SERVERAID3L "SB610" +#define IPS_COMPAT_SERVERAID4H "SB610" +#define IPS_COMPAT_SERVERAID4M "SB610" +#define IPS_COMPAT_SERVERAID4L "SB610" +#define IPS_COMPAT_SERVERAID4Mx "SB610" +#define IPS_COMPAT_SERVERAID4Lx "SB610" +#define IPS_COMPAT_SARASOTA "SB610" +#define IPS_COMPAT_MARCO "SB610" +#define IPS_COMPAT_SEBRING "SB610" +#define IPS_COMPAT_BIOS "SB610" -#define IPS_COMPAT_MAX_ADAPTER_TYPE 15 +#define IPS_COMPAT_MAX_ADAPTER_TYPE 16 #define IPS_COMPAT_ID_LENGTH 8 #define IPS_DEFINE_COMPAT_TABLE(tablename) \ @@ -1250,7 +1264,8 @@ IPS_COMPAT_SERVERAID4Lx, \ IPS_COMPAT_SARASOTA, /* one-channel variety of SARASOTA */ \ IPS_COMPAT_SARASOTA, /* two-channel variety of SARASOTA */ \ - IPS_COMPAT_MARCO \ + IPS_COMPAT_MARCO, \ + IPS_COMPAT_SEBRING \ } Index: drivers/scsi/mac_esp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/mac_esp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/mac_esp.c 22 Jul 2004 19:50:06 -0000 1.1 +++ drivers/scsi/mac_esp.c 4 Aug 2004 01:29:35 -0000 1.2 @@ -44,7 +44,7 @@ #define mac_turnon_irq(x) mac_enable_irq(x) #define mac_turnoff_irq(x) mac_disable_irq(x) -extern inline void esp_handle(struct NCR_ESP *esp); +extern void esp_handle(struct NCR_ESP *esp); extern void mac_esp_intr(int irq, void *dev_id, struct pt_regs *pregs); static int dma_bytes_sent(struct NCR_ESP * esp, int fifo_count); @@ -148,92 +148,98 @@ #define DRIVER_SETUP /* - * Function : mac_esp_setup(char *str, int *ints) + * Function : mac_esp_setup(char *str) * * Purpose : booter command line initialization of the overrides array, * - * Inputs : str - unused, ints - array of integer parameters with ints[0] - * equal to the number of ints. + * Inputs : str - parameters, separated by commas. * * Currently unused in the new driver; need to add settable parameters to the * detect function. * */ -static int __init mac_esp_setup(char *str, int *ints) { +static int __init mac_esp_setup(char *str) { #ifdef DRIVER_SETUP /* Format of mac53c9x parameter is: * mac53c9x=,,,,,,, * Negative values mean don't change. */ - /* Grmbl... the standard parameter parsing can't handle negative numbers - * :-( So let's do it ourselves! - */ + char *this_opt; + long opt; - int i = ints[0]+1, fact; + this_opt = strsep (&str, ","); + if(this_opt) { + opt = simple_strtol( this_opt, NULL, 0 ); + + if (opt >= 0 && opt <= 2) + setup_num_esps = opt; + else if (opt > 2) + printk( "mac_esp_setup: invalid number of hosts %ld !\n", opt ); - while( str && (isdigit(*str) || *str == '-') && i <= 10) { - if (*str == '-') - fact = -1, ++str; - else - fact = 1; - ints[i++] = simple_strtoul( str, NULL, 0 ) * fact; - if ((str = strchr( str, ',' )) != NULL) - ++str; + this_opt = strsep (&str, ","); } - ints[0] = i-1; + if(this_opt) { + opt = simple_strtol( this_opt, NULL, 0 ); - if (ints[0] < 1) { - printk( "mac_esp_setup: no arguments!\n" ); - return 0; + if (opt > 0) + setup_disconnect = opt; + + this_opt = strsep (&str, ","); } + if(this_opt) { + opt = simple_strtol( this_opt, NULL, 0 ); - if (ints[0] >= 1) { - if (ints[1] > 0) - /* no limits on this, just > 0 */ - if (ints[1] >= 0 && ints[1] <= 2) - setup_num_esps = ints[1]; - else if (ints[1] > 2) - printk( "mac_esp_setup: invalid number of hosts %d !\n", ints[1] ); - } - if (ints[0] >= 2) { - if (ints[2] > 0) - setup_disconnect = ints[2]; - } - if (ints[0] >= 3) { - if (ints[3] >= 0) { - setup_nosync = ints[3]; - } + if (opt >= 0) + setup_nosync = opt; + + this_opt = strsep (&str, ","); + } + if(this_opt) { + opt = simple_strtol( this_opt, NULL, 0 ); + + if (opt > 0) + setup_can_queue = opt; + + this_opt = strsep (&str, ","); } - if (ints[0] >= 4) { - if (ints[4] > 0) - /* no limits on this, just > 0 */ - setup_can_queue = ints[4]; - } - if (ints[0] >= 5) { - if (ints[5] > 0) - setup_cmd_per_lun = ints[5]; - } - if (ints[0] >= 6) { - if (ints[6] >= 0) { - setup_sg_tablesize = ints[6]; + if(this_opt) { + opt = simple_strtol( this_opt, NULL, 0 ); + + if (opt > 0) + setup_cmd_per_lun = opt; + + this_opt = strsep (&str, ","); + } + if(this_opt) { + opt = simple_strtol( this_opt, NULL, 0 ); + + if (opt >= 0) { + setup_sg_tablesize = opt; /* Must be <= SG_ALL (255) */ if (setup_sg_tablesize > SG_ALL) setup_sg_tablesize = SG_ALL; } + + this_opt = strsep (&str, ","); } - if (ints[0] >= 7) { + if(this_opt) { + opt = simple_strtol( this_opt, NULL, 0 ); + /* Must be between 0 and 7 */ - if (ints[7] >= 0 && ints[7] <= 7) - setup_hostid = ints[7]; - else if (ints[7] > 7) - printk( "mac_esp_setup: invalid host ID %d !\n", ints[7] ); + if (opt >= 0 && opt <= 7) + setup_hostid = opt; + else if (opt > 7) + printk( "mac_esp_setup: invalid host ID %ld !\n", opt); + + this_opt = strsep (&str, ","); } #ifdef SUPPORT_TAGS - if (ints[0] >= 8) { - if (ints[8] >= 0) - setup_use_tagged_queuing = !!ints[8]; + if(this_opt) { + opt = simple_strtol( this_opt, NULL, 0 ); + if (opt >= 0) + setup_use_tagged_queuing = !!opt; } #endif #endif @@ -242,6 +248,7 @@ __setup("mac53c9x=", mac_esp_setup); + /* * ESP address 'detection' */ Index: drivers/scsi/mac_scsi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/mac_scsi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/mac_scsi.c 22 Jul 2004 19:50:04 -0000 1.1 +++ drivers/scsi/mac_scsi.c 4 Aug 2004 01:29:35 -0000 1.2 @@ -27,8 +27,8 @@ /* * $Log: mac_scsi.c,v $ - * Revision 1.1 2004/07/22 19:50:04 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:35 joff + * merging 2.4.26-vrs1 * */ @@ -77,9 +77,6 @@ static void mac_scsi_reset_boot(struct Scsi_Host *instance); #endif -static __inline__ char macscsi_read(struct Scsi_Host *instance, int reg); -static __inline__ void macscsi_write(struct Scsi_Host *instance, int reg, int value); - static int setup_called = 0; static int setup_can_queue = -1; static int setup_cmd_per_lun = -1; @@ -105,6 +102,52 @@ static volatile unsigned char *mac_scsi_drq = NULL; static volatile unsigned char *mac_scsi_nodrq = NULL; + +/* + * NCR 5380 register access functions + */ + +#if 0 +/* Debug versions */ +#define CTRL(p,v) (*ctrl = (v)) + +static char macscsi_read(struct Scsi_Host *instance, int reg) +{ + int iobase = instance->io_port; + int i; + int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; + + CTRL(iobase, 0); + i = in_8(iobase + (reg<<4)); + CTRL(iobase, 0x40); + + return i; +} + +static void macscsi_write(struct Scsi_Host *instance, int reg, int value) +{ + int iobase = instance->io_port; + int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; + + CTRL(iobase, 0); + out_8(iobase + (reg<<4), value); + CTRL(iobase, 0x40); +} +#else + +/* Fast versions */ +static __inline__ char macscsi_read(struct Scsi_Host *instance, int reg) +{ + return in_8(instance->io_port + (reg<<4)); +} + +static __inline__ void macscsi_write(struct Scsi_Host *instance, int reg, int value) +{ + out_8(instance->io_port + (reg<<4), value); +} +#endif + + /* * Function : mac_scsi_setup(char *str) * @@ -166,18 +209,20 @@ if (ints[5] >= 0) setup_use_pdma = ints[5]; } -#endif +#endif /* SUPPORT_TAGS */ -#endif +#endif /* DRIVER_SETUP */ return 1; } __setup("mac5380=", mac_scsi_setup); /* - * XXX: status debug + * If you want to find the instance with (k)gdb ... */ +#if NDEBUG static struct Scsi_Host *default_instance; +#endif /* * Function : int macscsi_detect(Scsi_Host_Template * tpnt) @@ -226,7 +271,9 @@ /* Once we support multiple 5380s (e.g. DuoDock) we'll do something different here */ instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); +#if NDEBUG default_instance = instance; +#endif if (macintosh_config->ident == MAC_MODEL_IIFX) { mac_scsi_regp = via1+0x8000; @@ -256,16 +303,16 @@ ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0; - if (instance->irq != IRQ_NONE) + if (instance->irq != SCSI_IRQ_NONE) if (request_irq(instance->irq, NCR5380_intr, IRQ_FLG_SLOW, "ncr5380", NCR5380_intr)) { printk(KERN_WARNING "scsi%d: IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); - instance->irq = IRQ_NONE; + instance->irq = SCSI_IRQ_NONE; } printk(KERN_INFO "scsi%d: generic 5380 at port %lX irq", instance->host_no, instance->io_port); - if (instance->irq == IRQ_NONE) + if (instance->irq == SCSI_IRQ_NONE) printk (KERN_INFO "s disabled"); else printk (KERN_INFO " %d", instance->irq); @@ -280,7 +327,7 @@ int macscsi_release (struct Scsi_Host *shpnt) { - if (shpnt->irq != IRQ_NONE) + if (shpnt->irq != SCSI_IRQ_NONE) free_irq (shpnt->irq, NCR5380_intr); return 0; @@ -334,49 +381,6 @@ return ""; } -/* - * NCR 5380 register access functions - */ - -/* Debug versions -#define CTRL(p,v) (*ctrl = (v)) - -static char macscsi_read(struct Scsi_Host *instance, int reg) -{ - int iobase = instance->io_port; - int i; - int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; - - CTRL(iobase, 0); - i = in_8(iobase + (reg<<4)); - CTRL(iobase, 0x40); - - return i; -} - -static void macscsi_write(struct Scsi_Host *instance, int reg, int value) -{ - int iobase = instance->io_port; - int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; - - CTRL(iobase, 0); - out_8(value, iobase + (reg<<4)); - CTRL(iobase, 0x40); -} -*/ - -/* Fast versions */ -static __inline__ char macscsi_read(struct Scsi_Host *instance, int reg) -{ - return in_8(instance->io_port + (reg<<4)); -} - -static __inline__ void macscsi_write(struct Scsi_Host *instance, int reg, int value) -{ - out_8(value, instance->io_port + (reg<<4)); -} - - /* Pseudo-DMA: (Ove Edlund) The code attempts to catch bus errors that occur if one for example Index: drivers/scsi/mac_scsi.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/mac_scsi.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/mac_scsi.h 22 Jul 2004 19:50:04 -0000 1.1 +++ drivers/scsi/mac_scsi.h 4 Aug 2004 01:29:35 -0000 1.2 @@ -24,8 +24,8 @@ /* * $Log: mac_scsi.h,v $ - * Revision 1.1 2004/07/22 19:50:04 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:35 joff + * merging 2.4.26-vrs1 * */ Index: drivers/scsi/megaraid.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/megaraid.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/megaraid.c 22 Jul 2004 19:50:03 -0000 1.1 +++ drivers/scsi/megaraid.c 4 Aug 2004 01:29:35 -0000 1.2 @@ -9,7 +9,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * Version : v1.18f (Dec 10, 2002) + * Version : v1.18k (Aug 28, 2003) * * Description: Linux device driver for LSI Logic MegaRAID controller * @@ -512,6 +512,54 @@ * * remove GFP_DMA flag for ioctl. This was causing overrun of DMA buffers. * + * Version 1.18g + * Fri Jan 31 18:29:25 EST 2003 - Atul Mukker + * + * Write the interrupt valid signature 0x10001234 as soon as reading it to + * flush memory caches. + * + * While sending back the inquiry information, check if the original request + * had an associated scatter-gather list and tranfer data from bounce buffer + * accordingly. + * + * Version 1.18h + * Thu Feb 6 17:18:48 EST 2003 - Atul Mukker + * + * Reduce the number of sectors per command to 128 from original value of + * 1024. Big IO sizes along with certain other operation going on in parallel, + * e.g., check consistency and rebuild put a heavy constraint on fW resources + * resulting in aborted commands. + * + * Version 1.18i + * Fri Jun 20 07:39:05 EDT 2003 - Atul Mukker + * + * Request and reserve memory/IO regions. Otherwise a panic occurs if 2.00.x + * driver is loaded on top of 1.18x driver + * + * Prevent memory leak in cases when data transfer from/to application fails + * and ioctl is failing. + * + * Set the PCI dma_mask to default value of 0xFFFFFFFF when we get a handle to + * it. The previous value of 64-bit might be sticky and would cause the memory + * for mailbox and scatter lists to be allocated beyond 4GB. This was observed + * on an Itenium + * + * Version 1.18j + * Mon Jul 7 14:39:55 EDT 2003 - Atul Mukker + * + * Disable /proc/megaraid/stat file to prevent buffer overflow error during + * read of this file. + * + * Add support for ioctls on AMD-64 bit platforms + * - Sreenivas Bagalkote + * + * Version 1.18k + * Thu Aug 28 10:05:11 EDT 2003 - Atul Mukker + * + * Make sure to read the correct status and command ids while in ISR. The + * numstatus and command id array is invalidated before issuing the commands. + * The ISR busy-waits till the correct values are updated in host memory. + * * BUGS: * Some older 2.1 kernels (eg. 2.1.90) have a bug in pci.c that * fails to detect the controller as a pci device on the system. @@ -575,12 +623,27 @@ #include #include +#ifdef __x86_64__ +#include +#endif + #include "sd.h" #include "scsi.h" #include "hosts.h" #include "megaraid.h" +#ifdef __x86_64__ +/* + * The IOCTL cmd received from 32 bit compiled applications + */ + +extern int register_ioctl32_conversion( unsigned int cmd, + int(*handler)(unsigned int, unsigned int, unsigned long, + struct file* )); +extern int unregister_ioctl32_conversion( unsigned int cmd ); +#endif + /* *================================================================ * #Defines @@ -1141,8 +1204,14 @@ switch (SCpnt->cmnd[0]) { case INQUIRY: case READ_CAPACITY: - memcpy (SCpnt->request_buffer, - pScb->bounce_buffer, SCpnt->request_bufflen); + if ( SCpnt->use_sg ) { + sgList = (struct scatterlist *)SCpnt->request_buffer; + memcpy(sgList[0].address, pScb->bounce_buffer, + SCpnt->request_bufflen); + } else { + memcpy (SCpnt->request_buffer, pScb->bounce_buffer, + SCpnt->request_bufflen); + } break; } #endif @@ -2202,30 +2271,22 @@ megaCfg = (mega_host_config *) devp; mbox = (mega_mailbox *) tmpBox; - if (megaCfg->host->irq == irq) { - if (megaCfg->flag & IN_ISR) { - TRACE (("ISR called reentrantly!!\n")); - printk ("ISR called reentrantly!!\n"); - } - megaCfg->flag |= IN_ISR; - - if (mega_busyWaitMbox (megaCfg)) { - printk (KERN_WARNING "Error: mailbox busy in isr!\n"); - } + IO_LOCK; /* Check if a valid interrupt is pending */ if (megaCfg->flag & BOARD_QUARTZ) { dword = RDOUTDOOR (megaCfg); if (dword != 0x10001234) { /* Spurious interrupt */ - megaCfg->flag &= ~IN_ISR; + IO_UNLOCK; return; } + WROUTDOOR (megaCfg, 0x10001234); } else { byte = READ_PORT (megaCfg->host->io_port, INTR_PORT); if ((byte & VALID_INTR_BYTE) == 0) { /* Spurious interrupt */ - megaCfg->flag &= ~IN_ISR; + IO_UNLOCK; return; } WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte); @@ -2234,58 +2295,27 @@ for (idx = 0; idx < MAX_FIRMWARE_STATUS; idx++) completed[idx] = 0; - IO_LOCK; megaCfg->nInterrupts++; - qCnt = 0xff; while ((qCnt = megaCfg->mbox->numstatus) == 0xFF) ; - - qStatus = 0xff; - while ((qStatus = megaCfg->mbox->status) == 0xFF) ; + megaCfg->mbox->numstatus = 0xFF; /* Get list of completed requests */ for (idx = 0; idx < qCnt; idx++) { - while ((sIdx = megaCfg->mbox->completed[idx]) == 0xFF) { - printk ("p"); - } - completed[idx] = sIdx; - sIdx = 0xFF; + while ((completed[idx] = megaCfg->mbox->completed[idx]) == 0xFF); + megaCfg->mbox->completed[idx] = 0xFF; } + qStatus = megaCfg->mbox->status; + if (megaCfg->flag & BOARD_QUARTZ) { - WROUTDOOR (megaCfg, dword); /* Acknowledge interrupt */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - /* In this case mbox contains physical address */ -#if 0 - WRINDOOR (megaCfg, megaCfg->adjdmahandle64 | 0x2); -#else - WRINDOOR (megaCfg, 0x2); -#endif - -#else - -#if 0 - WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2); -#else WRINDOOR (megaCfg, 0x2); -#endif - -#endif - -#if 0 while (RDINDOOR (megaCfg) & 0x02) ; -#endif } else { CLEAR_INTR (megaCfg->host->io_port); } -#if DEBUG - if (qCnt >= MAX_FIRMWARE_STATUS) { - printk ("megaraid_isr: cmplt=%d ", qCnt); - } -#endif - for (idx = 0; idx < qCnt; idx++) { sIdx = completed[idx]; if ((sIdx > 0) && (sIdx <= MAX_COMMANDS)) { @@ -2355,26 +2385,24 @@ mega_runpendq (megaCfg); IO_UNLOCK; - } - } /*==================================================*/ /* Wait until the controller's mailbox is available */ /*==================================================*/ -static int mega_busyWaitMbox (mega_host_config * megaCfg) +static inline int mega_busyWaitMbox (mega_host_config * megaCfg) { mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox; long counter; - for (counter = 0; counter < 10000; counter++) { + for (counter = 0; counter < 10; counter++) { if (!mbox->busy) { return 0; } - udelay (100); + udelay (1); } - return -1; /* give up after 1 second */ + return -1; /* give up after 10 usecs */ } /*===================================================== @@ -2409,6 +2437,7 @@ u32 phys_mbox; #endif u8 retval = -1; + int i; mboxData[0x1] = (pScb ? pScb->idx + 1 : 0xFE); /* Set cmdid */ mboxData[0xF] = 1; /* Set busy */ @@ -2420,25 +2449,8 @@ phys_mbox = virt_to_bus (megaCfg->mbox); #endif -#if DEBUG - ShowMbox (pScb); -#endif - /* Wait until mailbox is free */ if (mega_busyWaitMbox (megaCfg)) { - printk ("Blocked mailbox......!!\n"); - udelay (1000); - -#if DEBUG - showMbox (pLastScb); -#endif - - /* Abort command */ - if (pScb == NULL) { - TRACE (("NULL pScb in megaIssue\n")); - printk ("NULL pScb in megaIssue\n"); - } - mega_cmd_done (megaCfg, pScb, 0x08); return -1; } @@ -2486,13 +2498,10 @@ WRINDOOR (megaCfg, phys_mbox | 0x1); while (mbox->numstatus == 0xFF) ; - while (mbox->status == 0xFF) ; while (mbox->mraid_poll != 0x77) ; mbox->mraid_poll = 0; mbox->mraid_ack = 0x77; - - /* while ((cmdDone = RDOUTDOOR (megaCfg)) != 0x10001234); - WROUTDOOR (megaCfg, cmdDone); */ + mbox->numstatus = 0xFF; if (pScb) { mega_cmd_done (megaCfg, pScb, mbox->status); @@ -2520,15 +2529,14 @@ TRACE (("Error: NULL pScb!\n")); } } + + for (i = 0; i < MAX_FIRMWARE_STATUS; i++) { + mbox->completed[i] = 0xFF; + } + enable_irq (megaCfg->host->irq); retval = mbox->status; } -#if DEBUG - while (mega_busyWaitMbox (megaCfg)) { - printk(KERN_ERR "Blocked mailbox on exit......!\n"); - udelay (1000); - } -#endif return retval; } @@ -2964,15 +2972,15 @@ int i, j; -#if BITS_PER_LONG==64 - u64 megaBase; -#else - u32 megaBase; -#endif + unsigned long megaBase; + unsigned long tbase; u16 pciIdx = 0; u16 numFound = 0; u16 subsysid, subsysvid; + u8 did_mem_map_f = 0; + u8 did_io_map_f = 0; + u8 did_scsi_register_f = 0; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) /* 0x20100 */ while (!pcibios_find_device @@ -2991,6 +2999,17 @@ pciBus = pdev->bus->number; pciDevFun = pdev->devfn; #endif + + /* + * Set the dma_mask to default value. It might be sticky from previous + * insmod-rmmod sequence + */ + pdev->dma_mask = 0xFFFFFFFF; + + did_mem_map_f = 0; + did_io_map_f = 0; + did_scsi_register_f = 0; + if ((flag & BOARD_QUARTZ) && (skip_id == -1)) { if( (pciVendor == PCI_VENDOR_ID_PERC4_DI_YSTONE && pciDev == PCI_DEVICE_ID_PERC4_DI_YSTONE) || @@ -3041,6 +3060,7 @@ if( (subsysvid != AMI_SUBSYS_ID) && (subsysvid != DELL_SUBSYS_ID) && (subsysvid != LSI_SUBSYS_ID) && + (subsysvid != INTEL_SUBSYS_ID) && (subsysvid != HP_SUBSYS_ID) ) continue; } @@ -3065,22 +3085,55 @@ megaIrq = pdev->irq; #endif + tbase = megaBase; + pciIdx++; if (flag & BOARD_QUARTZ) { + megaBase &= PCI_BASE_ADDRESS_MEM_MASK; + + if( ! request_mem_region(megaBase, 128, + "MegaRAID: LSI Logic Corporation" ) ) { + + printk(KERN_WARNING "megaraid: mem region busy!\n"); + + continue; + } + megaBase = (long) ioremap (megaBase, 128); - if (!megaBase) + + if (!megaBase) { + + printk(KERN_WARNING "megaraid: could not map hba memory!\n"); + + release_mem_region(tbase, 128); + continue; + } + did_mem_map_f = 1; + } else { megaBase &= PCI_BASE_ADDRESS_IO_MASK; megaBase += 0x10; + + if( ! request_region(megaBase, 16, + "MegaRAID: LSI Logic Corporation") ) { + + printk(KERN_WARNING "megaraid: region busy.\n"); + + continue; + } + did_io_map_f = 1; + } /* Initialize SCSI Host structure */ host = scsi_register (pHostTmpl, sizeof (mega_host_config)); if (!host) - goto err_unmap; + goto fail_attach; + + did_scsi_register_f = 1; /* * Comment the following initialization if you know 'max_sectors' is @@ -3088,7 +3141,7 @@ * This field was introduced in Linus's kernel 2.4.7pre3 and it * greatly increases the IO performance - AM */ - host->max_sectors = 1024; + host->max_sectors = 128; scsi_set_pci_device(host, pdev); megaCfg = (mega_host_config *) host->hostdata; @@ -3130,11 +3183,8 @@ megaCfg->host->unique_id = (pciBus << 8) | pciDevFun; megaCtlrs[numCtlrs] = megaCfg; - if (!(flag & BOARD_QUARTZ)) { - - /* Request our IO Range */ - if( !request_region(megaBase, 16, "megaraid") ) - goto err_unregister; + if (flag & BOARD_QUARTZ) { + megaCfg->host->base = tbase; } /* Request our IRQ */ @@ -3143,7 +3193,7 @@ printk (KERN_WARNING "megaraid: Couldn't register IRQ %d!\n", megaIrq); - goto err_release; + goto fail_attach; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) @@ -3265,8 +3315,7 @@ sizeof (mega_mailbox64), (void *) megaCfg->mailbox64ptr, megaCfg->dma_handle64); - scsi_unregister (host); - continue; + goto fail_attach; } /* @@ -3301,14 +3350,17 @@ #endif #endif continue; - err_release: - if (flag & BOARD_QUARTZ) - release_region (megaBase, 16); - err_unregister: - scsi_unregister (host); - err_unmap: - if (flag & BOARD_QUARTZ) - iounmap ((void *) megaBase); +fail_attach: + if( did_mem_map_f ) { + iounmap((void *)megaBase); + release_mem_region(tbase, 128); + } + if( did_io_map_f ) { + release_region(megaBase, 16); + } + if( did_scsi_register_f ) { + scsi_unregister (host); + } } return numFound; } @@ -3408,6 +3460,12 @@ } init_MUTEX (&mimd_entry_mtx); +#ifdef __x86_64__ + /* + * Register the 32-bit ioctl conversion + */ + register_ioctl32_conversion( MEGAIOCCMD, sys_ioctl ); +#endif } return count; @@ -3439,6 +3497,7 @@ /* Free our resources */ if (megaCfg->flag & BOARD_QUARTZ) { iounmap ((void *) megaCfg->base); + release_mem_region(megaCfg->host->base, 128); } else { release_region (megaCfg->host->io_port, 16); } @@ -3485,6 +3544,9 @@ unregister_chrdev (major, "megadev"); unregister_reboot_notifier (&mega_notifier); +#ifdef __x86_64__ + unregister_ioctl32_conversion( MEGAIOCCMD ); +#endif return 0; } @@ -4235,7 +4297,6 @@ static int proc_read_stat (char *page, char **start, off_t offset, int count, int *eof, void *data) { - int i; mega_host_config *megaCfg = (mega_host_config *) data; *start = page; @@ -4244,6 +4305,11 @@ proc_printf (megaCfg, "Interrupts Collected = %lu\n", megaCfg->nInterrupts); + proc_printf (megaCfg, "INTERFACE DISABLED\n"); + COPY_BACK; + return count; + +#if 0 // can cause buffer overrun with 40 logical drives and IO information for (i = 0; i < megaCfg->numldrv; i++) { proc_printf (megaCfg, "Logical Drive %d:\n", i); @@ -4259,6 +4325,7 @@ COPY_BACK; return count; +#endif } static int proc_read_status (char *page, char **start, off_t offset, @@ -4896,16 +4963,16 @@ if( kvaddr == NULL ) { printk(KERN_WARNING "megaraid:allocation failed\n"); ret = -ENOMEM; - goto out; + goto out_ioctl_cmd_new; } ioc.ui.fcs.buffer = kvaddr; if (inlen) { /* copyin the user data */ - if (copy_from_user(kvaddr, (char *)uaddr, length )) { - ret = -EFAULT; - goto out; + if( copy_from_user(kvaddr, (char *)uaddr, length ) ) { + ret = -EFAULT; + goto out_ioctl_cmd_new; } } } @@ -4923,9 +4990,10 @@ down(&mimd_ioctl_sem); if( !scsicmd->result && outlen ) { - if (copy_to_user(uaddr, kvaddr, length)) + if (copy_to_user(uaddr, kvaddr, length)) { ret = -EFAULT; - goto out; + goto out_ioctl_cmd_new; + } } /* @@ -4944,7 +5012,8 @@ put_user (scsicmd->result, &uioc->mbox[17]); } -out: +out_ioctl_cmd_new: + if (kvaddr) { dma_free_consistent(pdevp, length, kvaddr, dma_addr); } @@ -5045,12 +5114,8 @@ if( kvaddr == NULL ) { printk (KERN_WARNING "megaraid:allocation failed\n"); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) /*0x20400 */ - kfree(scsicmd); -#else - scsi_init_free((char *)scsicmd, sizeof(Scsi_Cmnd)); -#endif - return -ENOMEM; + ret = -ENOMEM; + goto out_ioctl_cmd; } ioc.data = kvaddr; @@ -5058,9 +5123,15 @@ if (inlen) { if (ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU) { /* copyin the user data */ - copy_from_user (kvaddr, uaddr, ioc.pthru.dataxferlen); + if( copy_from_user (kvaddr, uaddr, ioc.pthru.dataxferlen)){ + ret = -EFAULT; + goto out_ioctl_cmd; + } } else { - copy_from_user (kvaddr, uaddr, inlen); + if( copy_from_user (kvaddr, uaddr, inlen) ) { + ret = -EFAULT; + goto out_ioctl_cmd; + } } } } @@ -5078,11 +5149,15 @@ if (!scsicmd->result && outlen) { if (ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU) { - if (copy_to_user (uaddr, kvaddr, ioc.pthru.dataxferlen)) + if (copy_to_user (uaddr, kvaddr, ioc.pthru.dataxferlen)) { ret = -EFAULT; + goto out_ioctl_cmd; + } } else { - if (copy_to_user (uaddr, kvaddr, outlen)) + if (copy_to_user (uaddr, kvaddr, outlen)) { ret = -EFAULT; + goto out_ioctl_cmd; + } } } @@ -5107,6 +5182,8 @@ put_user (scsicmd->result, &uioc->mbox[17]); /* status */ } +out_ioctl_cmd: + if (kvaddr) { dma_free_consistent(pdevp, PAGE_SIZE, kvaddr, dma_addr ); } Index: drivers/scsi/megaraid.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/megaraid.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/megaraid.h 22 Jul 2004 19:50:03 -0000 1.1 +++ drivers/scsi/megaraid.h 4 Aug 2004 01:29:35 -0000 1.2 @@ -30,7 +30,8 @@ #define M_RD_IOCTL_CMD_NEW 0x81 #define M_RD_DRIVER_IOCTL_INTERFACE 0x82 -#define MEGARAID_VERSION "v1.18f (Release Date: Tue Dec 10 09:54:39 EST 2002)\n" +#define MEGARAID_VERSION "v1.18k (Release Date: Thu Aug 28 10:05:11 EDT 2003)\n" + #define MEGARAID_IOCTL_VERSION 114 @@ -190,6 +191,7 @@ #define AMI_SUBSYS_ID 0x101E #define DELL_SUBSYS_ID 0x1028 #define HP_SUBSYS_ID 0x103C +#define INTEL_SUBSYS_ID 0x8086 #define AMI_SIGNATURE 0x3344 #define AMI_SIGNATURE_471 0xCCCC @@ -899,7 +901,9 @@ * Defines for Driver IOCTL interface, Op-code:M_RD_DRIVER_IOCTL_INTERFACE */ #define MEGAIOC_MAGIC 'm' -#define MEGAIOCCMD _IOWR(MEGAIOC_MAGIC, 0) /* Mega IOCTL command */ + +/* Mega IOCTL command */ +#define MEGAIOCCMD _IOWR(MEGAIOC_MAGIC, 0, struct uioctl_t) #define MEGAIOC_QNADAP 'm' /* Query # of adapters */ #define MEGAIOC_QDRVRVER 'e' /* Query driver version */ Index: drivers/scsi/mvme147.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/mvme147.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/mvme147.h 22 Jul 2004 19:50:07 -0000 1.1 +++ drivers/scsi/mvme147.h 4 Aug 2004 01:29:35 -0000 1.2 @@ -1,6 +1,6 @@ #ifndef MVME147_H -/* $Id: mvme147.h,v 1.1 2004/07/22 19:50:07 joff Exp $ +/* $Id: mvme147.h,v 1.2 2004/08/04 01:29:35 joff Exp $ * * Header file for the MVME147 built-in SCSI controller for Linux * Index: drivers/scsi/mvme16x.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/mvme16x.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/mvme16x.c 22 Jul 2004 19:50:07 -0000 1.1 +++ drivers/scsi/mvme16x.c 4 Aug 2004 01:29:35 -0000 1.2 @@ -21,9 +21,6 @@ #include -extern int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board, int chip, - u32 base, int io_port, int irq, int dma, - long long options, int clock); int mvme16x_scsi_detect(Scsi_Host_Template *tpnt) { Index: drivers/scsi/nsp32.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/nsp32.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/nsp32.c 22 Jul 2004 19:50:05 -0000 1.1 +++ drivers/scsi/nsp32.c 4 Aug 2004 01:29:35 -0000 1.2 @@ -1,8 +1,8 @@ /* * NinjaSCSI-32Bi Cardbus, NinjaSCSI-32UDE PCI/CardBus SCSI driver - * Copyright (C) 2001, 2002 + * Copyright (C) 2001, 2002, 2003 * YOKOTA Hiroshi - * GOTO Masanori + * GOTO Masanori , * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,6 +13,14 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. + * + * + * Revision History: + * 1.0: Initial Release. + * 1.1: Add /proc SDTR status. + * Remove obsolete error handler nsp32_reset. + * Some clean up. + * 1.2: PowerPC (big endian) support. */ #include @@ -25,10 +33,12 @@ #include #include #include -#include +#include +#include #include #include #include +#include #include #include @@ -39,373 +49,327 @@ #include #include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) +# include +#endif + #include "nsp32.h" -static int trans_mode = 0; /* default: BIOS */ -static int auto_param = 0; /* default: ON */ -MODULE_PARM(trans_mode, "i"); -MODULE_PARM(auto_param, "i"); -MODULE_PARM_DESC(trans_mode, "transfer mode (0: BIOS 1: Async 2: Ultra20M"); -MODULE_PARM_DESC(auto_param, "AutoParameter mode (0: ON 1: OFF)"); +/*********************************************************************** + * Module parameters + */ +static int trans_mode = 0; /* default: BIOS */ +MODULE_PARM (trans_mode, "i"); +MODULE_PARM_DESC(trans_mode, "transfer mode (0: BIOS(default) 1: Async 2: Ultra20M"); #define ASYNC_MODE 1 #define ULTRA20M_MODE 2 +static int auto_param = 0; /* default: ON */ +MODULE_PARM (auto_param, "i"); +MODULE_PARM_DESC(auto_param, "AutoParameter mode (0: ON(default) 1: OFF)"); + +static int disc_priv = 1; /* default: OFF */ +MODULE_PARM (disc_priv, "i"); +MODULE_PARM_DESC(disc_priv, "disconnection privilege mode (0: ON 1: OFF(default))"); + MODULE_AUTHOR("YOKOTA Hiroshi , GOTO Masanori "); -MODULE_DESCRIPTION("Workbit NinjaSCSI-32Bi/UDE PCI/CardBus SCSI host bus adapter module"); +MODULE_DESCRIPTION("Workbit NinjaSCSI-32Bi/UDE CardBus/PCI SCSI host bus adapter module"); MODULE_LICENSE("GPL"); -static const char *nsp32_release_version = "1.0"; - - -/* - * structure for DMA/Scatter Gather list - */ -#define AUTOPARAM_SIZE (sizeof(int)*0x15) /* 4x15H = 0x60 */ -#define NSP_SG_SIZE SG_ALL -#define NSP32_SG_END_SGT 0x80000000 /* Last SGT marker */ -#define NSP32_SG_CNT_MASK 0x1FFFF - -struct nsp32_sgtable { - unsigned long addr; /* transfer address */ - unsigned long len; /* transfer length. - Bit (24-32) is for SGT_END */ -}; - -struct nsp32_sglun { - struct nsp32_sgtable sgt[NSP_SG_SIZE+1]; /* SG table */ -}; - - -/* - * host data structure - */ -/* message in/out buffer */ -#define MSGOUTBUF_MAX 13 /* 13 is ok ? */ -#define MSGINBUF_MAX 13 - -/* flag for trans_method */ -#define NSP32_TRANSFER_BUSMASTER BIT(0) -#define NSP32_TRANSFER_MMIO BIT(1) /* Not supported yet */ -#define NSP32_TRANSFER_PIO BIT(2) /* Not supported yet */ - - -/* - * SCSI TARGET/LUN definition - */ -#define NSP32_HOST_SCSIID 7 /* SCSI initiator is everytime defined as 7 */ -#define MAX_TARGET 8 -#define MAX_LUN 8 /* XXX: In SPI3, max number of LUN is 64. */ - +static const char *nsp32_release_version = "1.2"; -/* - * structure for synchronous transfer negotiation data - */ -#define SYNC_NOT_YET 0 -#define SYNC_OK 1 -#define SYNC_NG 2 - -struct nsp32_sync_table { - unsigned char period_num; /* period number */ - unsigned char ackwidth; /* ack width designated by period */ - unsigned char start_period; /* search range - start period */ - unsigned char end_period; /* search range - end period */ -}; - -/* - * structure for target device static data +/**************************************************************************** + * Supported hardware */ -/* flag for nsp32_target.sync_flag */ -#define SDTR_INITIATOR BIT(0) /* sending SDTR from initiator */ -#define SDTR_TARGET BIT(1) /* sending SDTR from target */ -#define SDTR_DONE BIT(2) /* exchanging SDTR has been processed */ - -/* syncronous period value for nsp32_target.config_max */ -#define FAST5M 0x32 -#define FAST10M 0x19 -#define ULTRA20M 0x0c - -/* flag for nsp32_target.{sync_offset}, period */ -#define ASYNC_OFFSET 0 /* asynchronous transfer */ -#define SYNC_OFFSET 0xf /* synchronous transfer max offset */ - -/* syncreg: - 07 06 05 04 03 02 01 00 - ---PERIOD-- ---OFFSET-- */ -#define TO_SYNCREG(period, offset) (period << 4 | offset) - -struct nsp32_target { - unsigned char syncreg; /* value for SYNCREG */ - unsigned char ackwidth; /* value for ACKWIDTH */ - unsigned char offset; /* sync offset (0-15) */ - int sync_flag; /* SDTR_*, 0 */ - int limit_entry; /* max speed limit entry designated - by EEPROM configuration */ +static struct pci_device_id nsp32_pci_table[] __devinitdata = { + { + .vendor = PCI_VENDOR_ID_IODATA, + .device = PCI_DEVICE_ID_NINJASCSI_32BI_CBSC_II, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = MODEL_IODATA, + }, + { + .vendor = PCI_VENDOR_ID_WORKBIT, + .device = PCI_DEVICE_ID_NINJASCSI_32BI_KME, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = MODEL_KME, + }, + { + .vendor = PCI_VENDOR_ID_WORKBIT, + .device = PCI_DEVICE_ID_NINJASCSI_32BI_WBT, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = MODEL_WORKBIT, + }, + { + .vendor = PCI_VENDOR_ID_WORKBIT, + .device = PCI_DEVICE_ID_WORKBIT_STANDARD, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = MODEL_PCI_WORKBIT, + }, + { + .vendor = PCI_VENDOR_ID_WORKBIT, + .device = PCI_DEVICE_ID_NINJASCSI_32BI_LOGITEC, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = MODEL_LOGITEC, + }, + { + .vendor = PCI_VENDOR_ID_WORKBIT, + .device = PCI_DEVICE_ID_NINJASCSI_32BIB_LOGITEC, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = MODEL_PCI_LOGITEC, + }, + { + .vendor = PCI_VENDOR_ID_WORKBIT, + .device = PCI_DEVICE_ID_NINJASCSI_32UDE_MELCO, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = MODEL_PCI_MELCO, + }, + { + .vendor = PCI_VENDOR_ID_WORKBIT, + .device = PCI_DEVICE_ID_NINJASCSI_32UDE_MELCO_II, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = MODEL_PCI_MELCO, + }, + {0,0,}, }; +MODULE_DEVICE_TABLE(pci, nsp32_pci_table); -typedef struct _nsp32_hw_data { - int IrqNumber; - int BaseAddress; - int NumAddress; -#define NSP32_MMIO_OFFSET 0x0800 - unsigned long MmioAddress; - unsigned long length; - - Scsi_Cmnd *CurrentSC; - - struct pci_dev *Pci; - const struct pci_device_id *pci_devid; - struct Scsi_Host *Host; - spinlock_t Lock; - - char info_str[100]; - - /* allocated memory region */ - struct nsp32_lunt *lunt_list; /* kmalloc region for lunt */ - struct nsp32_sglun *sg_list; /* sglist virtual address */ - dma_addr_t sgaddr; /* physical address of hw_sg_table */ - unsigned char *autoparam; /* auto parameter transfer region */ - dma_addr_t apaddr; /* physical address of autoparam */ - int cur_entry; /* current sgt entry */ - - /* target/LUN */ - struct nsp32_lunt *curlunt; /* Current connected LUN table */ - struct nsp32_lunt *lunt[MAX_TARGET][MAX_LUN]; /* All LUN table */ - struct nsp32_target *curtarget; /* Current connected SCSI ID */ - struct nsp32_target target[MAX_TARGET]; /* SCSI ID */ - int pid; /* Current connected target ID */ - int plun; /* Current connected target LUN */ - - /* behavior setting parameters */ - int trans_method; /* transfer method flag */ - int resettime; /* Reset time */ - int clock; /* clock dividing flag */ - struct nsp32_sync_table *synct; /* sync_table determined by clock */ - int syncnum; /* the max number of synct element */ - - /* message buffer */ - unsigned char msgoutbuf[MSGOUTBUF_MAX]; /* msgout buffer */ - char msgoutlen; /* msgoutbuf length */ - unsigned char msginbuf[MSGINBUF_MAX]; /* megin buffer */ - char msginlen; /* msginbuf length */ - - -} nsp32_hw_data; static nsp32_hw_data nsp32_data_base; /* probe <-> detect glue */ /* - * TIME definition - */ -#define RESET_HOLD_TIME 10000 /* reset time in us (SCSI-2 says the - minimum is 25us) */ -#define SEL_TIMEOUT_TIME 10000 /* 250ms defined in SCSI specification - (25.6us/1unit) */ -#define ARBIT_TIMEOUT_TIME 100 /* 100us */ -#define REQSACK_TIMEOUT_TIME 10000 /* max wait time for REQ/SACK assertion - or negation, 10000us == 10ms */ - -/* - * structure for connected LUN dynamic data - * - * Note: Currently tagged queuing is disabled, each nsp32_lunt holds - * one SCSI command and one state. - */ -#define DISCPRIV_OK BIT(0) /* DISCPRIV Enable mode */ -#define MSGIN03 BIT(1) /* Auto Msg In 03 Flag */ - -struct nsp32_lunt { - Scsi_Cmnd *SCpnt; /* Current Handling Scsi_Cmnd */ - unsigned long save_datp; /* Save Data Pointer - saved position from initial address */ - int msgin03; /* auto msg in 03 flag */ - unsigned int sg_num; /* Total number of SG entries */ - int cur_entry; /* Current SG entry number */ - struct nsp32_sglun *sglun; /* sg table per lun */ - long sglun_paddr; /* sglun physical address */ -}; - - -/* * Period/AckWidth speed conversion table * * Note: This period/ackwidth speed table must be in descending order. */ -static struct nsp32_sync_table nsp32_sync_table_40M[] = { - /* {PNo, AW, SP, EP} Speed(MB/s) Period AckWidth */ - {0x1, 0, 0x0c, 0x0c}, /* 20.0 : 50ns, 25ns */ - {0x2, 0, 0x0d, 0x18}, /* 13.3 : 75ns, 25ns */ - {0x3, 1, 0x19, 0x19}, /* 10.0 : 100ns, 50ns */ - {0x4, 1, 0x1a, 0x1f}, /* 8.0 : 125ns, 50ns */ - {0x5, 2, 0x20, 0x25}, /* 6.7 : 150ns, 75ns */ - {0x6, 2, 0x26, 0x31}, /* 5.7 : 175ns, 75ns */ - {0x7, 3, 0x32, 0x32}, /* 5.0 : 200ns, 100ns */ - {0x8, 3, 0x33, 0x38}, /* 4.4 : 225ns, 100ns */ - {0x9, 3, 0x39, 0x3e}, /* 4.0 : 250ns, 100ns */ +static nsp32_sync_table nsp32_sync_table_40M[] = { + /* {PNo, AW, SP, EP, SREQ smpl} Speed(MB/s) Period AckWidth */ + {0x1, 0, 0x0c, 0x0c, SMPL_40M}, /* 20.0 : 50ns, 25ns */ + {0x2, 0, 0x0d, 0x18, SMPL_40M}, /* 13.3 : 75ns, 25ns */ + {0x3, 1, 0x19, 0x19, SMPL_40M}, /* 10.0 : 100ns, 50ns */ + {0x4, 1, 0x1a, 0x1f, SMPL_20M}, /* 8.0 : 125ns, 50ns */ + {0x5, 2, 0x20, 0x25, SMPL_20M}, /* 6.7 : 150ns, 75ns */ + {0x6, 2, 0x26, 0x31, SMPL_20M}, /* 5.7 : 175ns, 75ns */ + {0x7, 3, 0x32, 0x32, SMPL_20M}, /* 5.0 : 200ns, 100ns */ + {0x8, 3, 0x33, 0x38, SMPL_10M}, /* 4.4 : 225ns, 100ns */ + {0x9, 3, 0x39, 0x3e, SMPL_10M}, /* 4.0 : 250ns, 100ns */ + {0xa, 3, 0x3f, 0x44, SMPL_10M}, /* 3.64: 275ns, 100ns */ + {0xb, 3, 0x45, 0x4b, SMPL_10M}, /* 3.33: 300ns, 100ns */ + {0xc, 3, 0x4c, 0x53, SMPL_10M}, /* 3.01: 325ns, 100ns */ + {0xd, 3, 0x54, 0x57, SMPL_10M}, /* 2.86: 350ns, 100ns */ + {0xe, 3, 0x58, 0x5d, SMPL_10M}, /* 2.67: 375ns, 100ns */ + {0xf, 3, 0x5e, 0x64, SMPL_10M}, /* 2.5 : 400ns, 100ns */ }; -static const int nsp32_table_40M_num = - sizeof(nsp32_sync_table_40M)/sizeof(struct nsp32_sync_table); -static struct nsp32_sync_table nsp32_sync_table_20M[] = { - {0x1, 0, 0x19, 0x19}, /* 10.0 : 100ns, 50ns */ - {0x2, 0, 0x1a, 0x25}, /* 6.7 : 150ns, 50ns */ - {0x3, 1, 0x26, 0x32}, /* 5.0 : 200ns, 100ns */ - {0x4, 1, 0x33, 0x3e}, /* 4.0 : 250ns, 100ns */ - {0x5, 2, 0x3f, 0x4b}, /* 3.3 : 300ns, 150ns */ - {0x6, 2, 0x4c, 0x57}, /* 2.8 : 350ns, 150ns */ - {0x7, 3, 0x58, 0x64}, /* 2.5 : 400ns, 200ns */ - {0x8, 3, 0x65, 0x70}, /* 2.2 : 450ns, 200ns */ - {0x9, 3, 0x71, 0x7d}, /* 2.0 : 500ns, 200ns */ +static nsp32_sync_table nsp32_sync_table_20M[] = { + {0x1, 0, 0x19, 0x19, SMPL_40M}, /* 10.0 : 100ns, 50ns */ + {0x2, 0, 0x1a, 0x25, SMPL_20M}, /* 6.7 : 150ns, 50ns */ + {0x3, 1, 0x26, 0x32, SMPL_20M}, /* 5.0 : 200ns, 100ns */ + {0x4, 1, 0x33, 0x3e, SMPL_10M}, /* 4.0 : 250ns, 100ns */ + {0x5, 2, 0x3f, 0x4b, SMPL_10M}, /* 3.3 : 300ns, 150ns */ + {0x6, 2, 0x4c, 0x57, SMPL_10M}, /* 2.8 : 350ns, 150ns */ + {0x7, 3, 0x58, 0x64, SMPL_10M}, /* 2.5 : 400ns, 200ns */ + {0x8, 3, 0x65, 0x70, SMPL_10M}, /* 2.2 : 450ns, 200ns */ + {0x9, 3, 0x71, 0x7d, SMPL_10M}, /* 2.0 : 500ns, 200ns */ + {0xa, 3, 0x7e, 0x89, SMPL_10M}, /* 1.82: 550ns, 200ns */ + {0xb, 3, 0x8a, 0x95, SMPL_10M}, /* 1.67: 550ns, 200ns */ + {0xc, 3, 0x96, 0xa2, SMPL_10M}, /* 1.54: 550ns, 200ns */ + {0xd, 3, 0xa3, 0xae, SMPL_10M}, /* 1.43: 550ns, 200ns */ + {0xe, 3, 0xaf, 0xbb, SMPL_10M}, /* 1.33: 550ns, 200ns */ + {0xf, 3, 0xbc, 0xc8, SMPL_10M}, /* 1.25: 550ns, 200ns */ }; -static const int nsp32_table_20M_num = - sizeof(nsp32_sync_table_20M)/sizeof(struct nsp32_sync_table); -static struct nsp32_sync_table nsp32_sync_table_pci[] = { - {0x1, 0, 0x0c, 0x0f}, /* 16.6 : 60ns, 30ns */ - {0x2, 0, 0x10, 0x16}, /* 11.1 : 90ns, 30ns */ - {0x3, 1, 0x17, 0x1e}, /* 8.3 : 120ns, 60ns */ - {0x4, 1, 0x1f, 0x25}, /* 6.7 : 150ns, 60ns */ - {0x5, 2, 0x26, 0x2d}, /* 5.6 : 180ns, 90ns */ - {0x6, 2, 0x2e, 0x34}, /* 4.8 : 210ns, 90ns */ - {0x7, 3, 0x35, 0x3c}, /* 4.2 : 240ns, 120ns */ - {0x8, 3, 0x3d, 0x43}, /* 3.7 : 270ns, 120ns */ - {0x9, 3, 0x44, 0x4b}, /* 3.3 : 300ns, 120ns */ +static nsp32_sync_table nsp32_sync_table_pci[] = { + {0x1, 0, 0x0c, 0x0f, SMPL_40M}, /* 16.6 : 60ns, 30ns */ + {0x2, 0, 0x10, 0x16, SMPL_40M}, /* 11.1 : 90ns, 30ns */ + {0x3, 1, 0x17, 0x1e, SMPL_20M}, /* 8.3 : 120ns, 60ns */ + {0x4, 1, 0x1f, 0x25, SMPL_20M}, /* 6.7 : 150ns, 60ns */ + {0x5, 2, 0x26, 0x2d, SMPL_20M}, /* 5.6 : 180ns, 90ns */ + {0x6, 2, 0x2e, 0x34, SMPL_10M}, /* 4.8 : 210ns, 90ns */ + {0x7, 3, 0x35, 0x3c, SMPL_10M}, /* 4.2 : 240ns, 120ns */ + {0x8, 3, 0x3d, 0x43, SMPL_10M}, /* 3.7 : 270ns, 120ns */ + {0x9, 3, 0x44, 0x4b, SMPL_10M}, /* 3.3 : 300ns, 120ns */ + {0xa, 3, 0x4c, 0x53, SMPL_10M}, /* 3.0 : 330ns, 120ns */ + {0xb, 3, 0x54, 0x59, SMPL_10M}, /* 2.8 : 360ns, 120ns */ + {0xc, 3, 0x5a, 0x60, SMPL_10M}, /* 2.6 : 390ns, 120ns */ + {0xd, 3, 0x61, 0x68, SMPL_10M}, /* 2.4 : 420ns, 120ns */ + {0xe, 3, 0x69, 0x71, SMPL_10M}, /* 2.2 : 450ns, 120ns */ + {0xf, 3, 0x72, 0x77, SMPL_10M}, /* 2.1 : 480ns, 120ns */ }; -static const int nsp32_table_pci_num = - sizeof(nsp32_sync_table_pci)/sizeof(struct nsp32_sync_table); /* * function declaration */ -static int nsp32_detect(Scsi_Host_Template *); -static int nsp32_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); -static const char *nsp32_info(struct Scsi_Host *); -static int nsp32_eh_abort(Scsi_Cmnd *); -static int nsp32_eh_bus_reset(Scsi_Cmnd *); -static int nsp32_eh_host_reset(Scsi_Cmnd *); -static int nsp32_reset(Scsi_Cmnd *, unsigned int); -static int nsp32_release(struct Scsi_Host *); -static int nsp32_proc_info(char *, char **, off_t, int, int, int); -static int __devinit nsp32_probe(struct pci_dev *, const struct pci_device_id *); +/* module entry point */ +static int __devinit nsp32_probe (struct pci_dev *, const struct pci_device_id *); static void __devexit nsp32_remove(struct pci_dev *); -static int __init init_nsp32(void); -static void __exit exit_nsp32(void); +static int __init init_nsp32 (void); +static void __exit exit_nsp32 (void); + +/* struct Scsi_Host_Template */ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) +static int nsp32_proc_info (struct Scsi_Host *, char *, char **, off_t, int, int); +#else +static int nsp32_proc_info (char *, char **, off_t, int, int, int); +#endif -static void nsp32_message(char *, int, char *, char *, ...); -static void nsp32_dmessage(char *, int, int, char *, ...); -static void nsp32_build_identify(nsp32_hw_data *, Scsi_Cmnd *); -static void nsp32_build_sdtr(nsp32_hw_data *, unsigned char, unsigned char); -static void nsp32_build_nop(nsp32_hw_data *); -static void nsp32_build_reject(nsp32_hw_data *); -static int nsp32hw_start_selection(Scsi_Cmnd *, nsp32_hw_data *); -static int nsp32_selection_autoscsi(Scsi_Cmnd *, nsp32_hw_data *); -static int nsp32_reselection(nsp32_hw_data *, unsigned char); -static int nsp32hw_setup_sg_table(Scsi_Cmnd *, nsp32_hw_data *); -static int nsp32hw_init(struct Scsi_Host *); -static void nsp32_scsi_done(nsp32_hw_data *, Scsi_Cmnd *); -static int nsp32_busfree_occur(nsp32_hw_data *, unsigned short); -static void nsp32_adjust_busfree(nsp32_hw_data *, unsigned int); -static void nsp32_msgout_occur(nsp32_hw_data *); -static void nsp32_restart_autoscsi(nsp32_hw_data *, unsigned short); -static void nsp32_msgin_occur(nsp32_hw_data *, unsigned long, unsigned short); -static void nsp32_analyze_sdtr(nsp32_hw_data *); -static int nsp32_search_period_entry(nsp32_hw_data *,struct nsp32_target *, unsigned char); -static void nsp32_set_async(nsp32_hw_data *, struct nsp32_target *); -static void nsp32_set_max_sync(nsp32_hw_data *, struct nsp32_target *, unsigned char *, unsigned char *); -static void nsp32_set_sync_entry(nsp32_hw_data *, struct nsp32_target *, int, unsigned char); -static void nsp32_wait_req(nsp32_hw_data *, int); -static void nsp32_wait_sack(nsp32_hw_data *, int); -static void nsp32_sack_assert(nsp32_hw_data *); -static void nsp32_sack_negate(nsp32_hw_data *); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) +static int nsp32_detect (struct pci_dev *pdev); +#else +static int nsp32_detect (Scsi_Host_Template *); +#endif +static int nsp32_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); +static const char *nsp32_info (struct Scsi_Host *); +static int nsp32_release (struct Scsi_Host *); + +/* SCSI error handler */ +static int nsp32_eh_abort (Scsi_Cmnd *); +static int nsp32_eh_bus_reset (Scsi_Cmnd *); +static int nsp32_eh_host_reset(Scsi_Cmnd *); + +/* generate SCSI message */ +static void nsp32_build_identify(Scsi_Cmnd *); +static void nsp32_build_nop (Scsi_Cmnd *); +static void nsp32_build_reject (Scsi_Cmnd *); +static void nsp32_build_sdtr (Scsi_Cmnd *, unsigned char, unsigned char); + +/* SCSI message handler */ +static int nsp32_busfree_occur(Scsi_Cmnd *, unsigned short); +static void nsp32_msgout_occur (Scsi_Cmnd *); +static void nsp32_msgin_occur (Scsi_Cmnd *, unsigned long, unsigned short); + +static int nsp32_setup_sg_table (Scsi_Cmnd *); +static unsigned long nsp32_msgout_register (Scsi_Cmnd *); +static int nsp32_selection_autopara(Scsi_Cmnd *); +static int nsp32_selection_autoscsi(Scsi_Cmnd *); +static void nsp32_scsi_done (Scsi_Cmnd *); +static int nsp32_arbitration (Scsi_Cmnd *, unsigned int); +static int nsp32_reselection (Scsi_Cmnd *, unsigned char); +static void nsp32_adjust_busfree (Scsi_Cmnd *, unsigned int); +static void nsp32_restart_autoscsi (Scsi_Cmnd *, unsigned short); + +/* SCSI SDTR */ +static void nsp32_analyze_sdtr (Scsi_Cmnd *); +static int nsp32_search_period_entry(nsp32_hw_data *, nsp32_target *, unsigned char); +static void nsp32_set_async (nsp32_hw_data *, nsp32_target *); +static void nsp32_set_max_sync (nsp32_hw_data *, nsp32_target *, unsigned char *, unsigned char *); +static void nsp32_set_sync_entry (nsp32_hw_data *, nsp32_target *, int, unsigned char); + +/* SCSI bus status handler */ +static void nsp32_wait_req (nsp32_hw_data *, int); +static void nsp32_wait_sack (nsp32_hw_data *, int); +static void nsp32_sack_assert (nsp32_hw_data *); +static void nsp32_sack_negate (nsp32_hw_data *); static void nsp32_do_bus_reset(nsp32_hw_data *); -static void do_nsp32_isr(int, void *, struct pt_regs *); -static int nsp32_getprom_param(nsp32_hw_data *); -static int nsp32_getprom_new(nsp32_hw_data *); -static int nsp32_getprom_standard(nsp32_hw_data *); -static int nsp32_prom_read(nsp32_hw_data *, int); -static void nsp32_prom_start(nsp32_hw_data *); -static void nsp32_prom_stop(nsp32_hw_data *); -static void nsp32_prom_write(nsp32_hw_data *, int); -static int nsp32_prom_fetch(nsp32_hw_data *); -static inline void nsp32_prom_set(nsp32_hw_data *, int, int); -static inline int nsp32_prom_get(nsp32_hw_data *, int); +/* hardware interrupt handler */ +static irqreturn_t do_nsp32_isr(int, void *, struct pt_regs *); + +/* initialize hardware */ +static int nsp32hw_init(nsp32_hw_data *); + +/* EEPROM handler */ +static int nsp32_getprom_param (nsp32_hw_data *); +static int nsp32_getprom_at24 (nsp32_hw_data *); +static int nsp32_getprom_c16 (nsp32_hw_data *); +static void nsp32_prom_start (nsp32_hw_data *); +static void nsp32_prom_stop (nsp32_hw_data *); +static int nsp32_prom_read (nsp32_hw_data *, int); +static int nsp32_prom_read_bit (nsp32_hw_data *); +static void nsp32_prom_write_bit(nsp32_hw_data *, int); +static inline void nsp32_prom_set (nsp32_hw_data *, int, int); +static inline int nsp32_prom_get (nsp32_hw_data *, int); +/* debug/warning/info message */ +static void nsp32_message (const char *, int, char *, char *, ...); +#ifdef NSP32_DEBUG +static void nsp32_dmessage(const char *, int, int, char *, ...); +#endif /* * max_sectors is currently limited up to 128. */ -static Scsi_Host_Template driver_template = { - .proc_name = "nsp32", - .name = "Workbit NinjaSCSI-32Bi/UDE", - .proc_info = nsp32_proc_info, - .detect = nsp32_detect, - .info = nsp32_info, - .queuecommand = nsp32_queuecommand, - .can_queue = 1, - .sg_tablesize = NSP_SG_SIZE, - .max_sectors = 128, - .cmd_per_lun = 1, - .this_id = 7, - .use_clustering = DISABLE_CLUSTERING, - .eh_abort_handler = nsp32_eh_abort, - .eh_device_reset_handler = NULL, - .eh_bus_reset_handler = nsp32_eh_bus_reset, - .eh_host_reset_handler = nsp32_eh_host_reset, - .reset = nsp32_reset, - .release = nsp32_release, -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2)) - .use_new_eh_code = 1, +static Scsi_Host_Template nsp32_template = { + .proc_name = "nsp32", + .name = "Workbit NinjaSCSI-32Bi/UDE", + .proc_info = nsp32_proc_info, + .info = nsp32_info, + .queuecommand = nsp32_queuecommand, + .can_queue = 1, + .sg_tablesize = NSP32_SG_SIZE, + .max_sectors = 128, + .cmd_per_lun = 1, + .this_id = NSP32_HOST_SCSIID, + .use_clustering = DISABLE_CLUSTERING, + .eh_abort_handler = nsp32_eh_abort, +/* .eh_device_reset_handler = NULL, */ + .eh_bus_reset_handler = nsp32_eh_bus_reset, + .eh_host_reset_handler = nsp32_eh_host_reset, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)) + .detect = nsp32_detect, + .release = nsp32_release, + .use_new_eh_code = 1, #else - /* .highmem_io = 1, */ +/* .highmem_io = 1, */ #endif }; #include "nsp32_io.h" -/* +/*********************************************************************** * debug, error print */ -#define nsp32_msg(type, args...) \ - nsp32_message(__FUNCTION__, __LINE__, (type), ## args) -#define nsp32_dbg(mask, args...) \ - nsp32_dmessage(__FUNCTION__, __LINE__, (mask), ## args) - #ifndef NSP32_DEBUG -# define NSP32_DEBUG_MASK 0x000000 +# define NSP32_DEBUG_MASK 0x000000 +# define nsp32_msg(type, args...) nsp32_message ("", 0, (type), args) +# define nsp32_dbg(mask, args...) /* */ #else -# define NSP32_DEBUG_MASK 0xffffff +# define NSP32_DEBUG_MASK 0xffffff +# define nsp32_msg(type, args...) \ + nsp32_message (__FUNCTION__, __LINE__, (type), args) +# define nsp32_dbg(mask, args...) \ + nsp32_dmessage(__FUNCTION__, __LINE__, (mask), args) #endif -#define NSP32_DEBUG_QUEUECOMMAND 0x000001 -#define NSP32_DEBUG_REGISTER 0x000002 -#define NSP32_DEBUG_AUTOSCSI 0x000004 -#define NSP32_DEBUG_INTR 0x000008 -#define NSP32_DEBUG_SGLIST 0x000010 -#define NSP32_DEBUG_BUSFREE 0x000020 -#define NSP32_DEBUG_CDB_CONTENTS 0x000040 -#define NSP32_DEBUG_RESELECTION 0x000080 -#define NSP32_DEBUG_MSGINOCCUR 0x000100 -#define NSP32_DEBUG_EEPROM 0x000200 -#define NSP32_DEBUG_MSGOUTOCCUR 0x000400 -#define NSP32_DEBUG_BUSRESET 0x000800 -#define NSP32_DEBUG_RESTART 0x001000 -#define NSP32_DEBUG_SYNC 0x002000 -#define NSP32_DEBUG_WAIT 0x004000 -#define NSP32_DEBUG_TARGETFLAG 0x008000 -#define NSP32_DEBUG_PROC 0x010000 -#define NSP32_DEBUG_INIT 0x020000 -#define NSP32_SPECIAL_PRINT_REGISTER 0x100000 +#define NSP32_DEBUG_QUEUECOMMAND BIT(0) +#define NSP32_DEBUG_REGISTER BIT(1) +#define NSP32_DEBUG_AUTOSCSI BIT(2) +#define NSP32_DEBUG_INTR BIT(3) +#define NSP32_DEBUG_SGLIST BIT(4) +#define NSP32_DEBUG_BUSFREE BIT(5) +#define NSP32_DEBUG_CDB_CONTENTS BIT(6) +#define NSP32_DEBUG_RESELECTION BIT(7) +#define NSP32_DEBUG_MSGINOCCUR BIT(8) +#define NSP32_DEBUG_EEPROM BIT(9) +#define NSP32_DEBUG_MSGOUTOCCUR BIT(10) +#define NSP32_DEBUG_BUSRESET BIT(11) +#define NSP32_DEBUG_RESTART BIT(12) +#define NSP32_DEBUG_SYNC BIT(13) +#define NSP32_DEBUG_WAIT BIT(14) +#define NSP32_DEBUG_TARGETFLAG BIT(15) +#define NSP32_DEBUG_PROC BIT(16) +#define NSP32_DEBUG_INIT BIT(17) +#define NSP32_SPECIAL_PRINT_REGISTER BIT(20) #define NSP32_DEBUG_BUF_LEN 100 -static void nsp32_message(char *func, int line, char *type, char *fmt, ...) +static void nsp32_message(const char *func, int line, char *type, char *fmt, ...) { va_list args; char buf[NSP32_DEBUG_BUF_LEN]; va_start(args, fmt); - vsprintf(buf, fmt, args); + vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); #ifndef NSP32_DEBUG @@ -415,19 +379,21 @@ #endif } -static void nsp32_dmessage(char *func, int line, int mask, char *fmt, ...) +#ifdef NSP32_DEBUG +static void nsp32_dmessage(const char *func, int line, int mask, char *fmt, ...) { va_list args; char buf[NSP32_DEBUG_BUF_LEN]; va_start(args, fmt); - vsprintf(buf, fmt, args); + vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); if (mask & NSP32_DEBUG_MASK) { - printk("Ninja: %d %s (%d): %s\n", mask, func, line, buf); + printk("nsp32-debug: 0x%x %s (%d): %s\n", mask, func, line, buf); } } +#endif #ifdef NSP32_DEBUG # include "nsp32_debug.c" @@ -437,56 +403,51 @@ # define show_autophase(arg) /* */ #endif -#ifdef NSP32_DEBUG -static int pc_debug = NSP32_DEBUG; -MODULE_PARM(pc_debug, "i"); -#define DEBUG(n, args...) if (pc_debug>(n)) printk(/*KERN_DEBUG*/ args) -#else -#define DEBUG(n, args...) -#endif - - /* * IDENTIFY Message */ -static void nsp32_build_identify(nsp32_hw_data *data, Scsi_Cmnd *SCpnt) +static void nsp32_build_identify(Scsi_Cmnd *SCpnt) { - int pos = data->msgoutlen; + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; + int pos = data->msgout_len; + int mode = FALSE; - data->msgoutbuf[pos++] = - 0x80 | /* Identify */ -#if 0 - /* XXX: Auto DiscPriv detection is progressing... */ - 0x40 | /* DiscPriv */ -#endif - SCpnt->lun; /* LUNTRN */ + /* XXX: Auto DiscPriv detection is progressing... */ + if (disc_priv == 0) { + /* mode = TRUE; */ + } - data->msgoutlen = pos; + data->msgoutbuf[pos] = IDENTIFY(mode, SCpnt->device->lun); pos++; + + data->msgout_len = pos; } /* * SDTR Message Routine */ -static void nsp32_build_sdtr(nsp32_hw_data *data, - unsigned char period, unsigned char offset) -{ - int pos = data->msgoutlen; +static void nsp32_build_sdtr(Scsi_Cmnd *SCpnt, + unsigned char period, + unsigned char offset) +{ + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; + int pos = data->msgout_len; + + data->msgoutbuf[pos] = EXTENDED_MESSAGE; pos++; + data->msgoutbuf[pos] = EXTENDED_SDTR_LEN; pos++; + data->msgoutbuf[pos] = EXTENDED_SDTR; pos++; + data->msgoutbuf[pos] = period; pos++; + data->msgoutbuf[pos] = offset; pos++; - data->msgoutbuf[pos++] = EXTENDED_MESSAGE; - data->msgoutbuf[pos++] = EXTENDED_SDTR_LEN; - data->msgoutbuf[pos++] = EXTENDED_SDTR; - data->msgoutbuf[pos++] = period; - data->msgoutbuf[pos++] = offset; - - data->msgoutlen = pos; + data->msgout_len = pos; } /* * No Operation Message */ -static void nsp32_build_nop(nsp32_hw_data *data) +static void nsp32_build_nop(Scsi_Cmnd *SCpnt) { - int pos = data->msgoutlen; + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; + int pos = data->msgout_len; if (pos != 0) { nsp32_msg(KERN_WARNING, @@ -494,54 +455,97 @@ return; } - data->msgoutbuf[pos++] = NOP; - data->msgoutlen = pos; + data->msgoutbuf[pos] = NOP; pos++; + data->msgout_len = pos; } /* * Reject Message */ -static void nsp32_build_reject(nsp32_hw_data *data) +static void nsp32_build_reject(Scsi_Cmnd *SCpnt) { - int pos = data->msgoutlen; + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; + int pos = data->msgout_len; - data->msgoutbuf[pos++] = MESSAGE_REJECT; - data->msgoutlen = pos; + data->msgoutbuf[pos] = MESSAGE_REJECT; pos++; + data->msgout_len = pos; } /* - * timer + * Start hardware timer */ #if 0 static void nsp32_start_timer(Scsi_Cmnd *SCpnt, int time) { unsigned int base = SCpnt->host->io_port; - DEBUG(0, __func__ " time=%d\n", time); + nsp32_dbg(NSP32_DEBUG_INTR, "timer=%d", time); if (time & (~TIMER_CNT_MASK)) { - printk("timer set overflow\n"); + nsp32_dbg(NSP32_DEBUG_INTR, "timer set overflow"); } nsp32_write2(base, TIMER_SET, time & TIMER_CNT_MASK); } #endif +/* + * Generate msgout register value based on the number of messages. + */ +static unsigned long nsp32_msgout_register(Scsi_Cmnd *SCpnt) +{ + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; + unsigned long msgout; + int i; + + /* + * message out + * + * Note: If the range of msgout_len is 1 - 3, fill scsi_msgout. + * over 3 messages needs another routine. + */ + if (data->msgout_len > 0 && data->msgout_len <= 3) { + msgout = 0; + for (i = 0; i < data->msgout_len; i++) { + /* + * msgout register layout: + * bit: 31-24 23-16 15-08 07 06-02 01-00 + * MSG#2 MSG#1 MSG#0 MV len + * + * the sending order of the message is: + * len = 3: MSG#0 -> MSG#1 -> MSG#2 + * len = 2: MSG#1 -> MSG#2 + * len = 1: MSG#2 + */ + msgout >>= 8; + msgout |= ((unsigned int)(data->msgoutbuf[i]) << 24); + } + msgout |= MSGOUT_VALID; /* Message out Valid */ + msgout |= data->msgout_len; /* len */ + } else { + /* data->msgout_len > 3 || data->msgout_len <= 0*/ + msgout = 0; + } + + return msgout; +} /* * set SCSI command and other parameter to asic, and start selection phase */ -static int nsp32hw_start_selection(Scsi_Cmnd *SCpnt, nsp32_hw_data *data) +static int nsp32_selection_autopara(Scsi_Cmnd *SCpnt) { - unsigned int host_id = SCpnt->host->this_id; - unsigned int base = SCpnt->host->io_port; - unsigned char target = SCpnt->target; - unsigned char *param = data->autoparam; - unsigned char phase, arbit; - int i, time; - unsigned int msgout; - unsigned long l; - unsigned short s; + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; + unsigned int base = SCpnt->device->host->io_port; + unsigned int host_id = SCpnt->device->host->this_id; + unsigned char target = SCpnt->device->id; + nsp32_autoparam *param = data->autoparam; + unsigned char phase; + int i, ret; + unsigned long msgout_reg; + unsigned short transfer_reg; + + nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "in"); /* * check bus free @@ -556,155 +560,106 @@ /* * message out - * - * Note: If the range of msgoutlen is 1 - 3, fill scsi_msgout. - * over 3 messages needs another routine. */ - if (data->msgoutlen == 0) { + if (data->msgout_len == 0) { nsp32_msg(KERN_ERR, "SCSI MsgOut without any message!"); SCpnt->result = DID_ERROR << 16; return FALSE; - } else if (data->msgoutlen > 0 && data->msgoutlen <= 3) { - msgout = 0; - for (i=0; imsgoutlen; i++) { - /* - * the sending order of the message is: - * MCNT 3: MSG#0 -> MSG#1 -> MSG#2 - * MCNT 2: MSG#1 -> MSG#2 - * MCNT 1: MSG#2 - */ - msgout >>= 8; - msgout |= (unsigned int)(data->msgoutbuf[i] << 24); - } - msgout |= MV_VALID; /* MV valid */ - msgout |= (unsigned int)data->msgoutlen; /* len */ } else { - /* data->msgoutlen > 3 */ - msgout = 0; + msgout_reg = nsp32_msgout_register(SCpnt); } + // nsp_dbg(NSP32_DEBUG_AUTOSCSI, "sel time out=0x%x\n", nsp32_read2(base, SEL_TIME_OUT)); + // nsp32_write2(base, SEL_TIME_OUT, SEL_TIMEOUT_TIME); + /* * setup asic parameter */ - memset(param, 0, AUTOPARAM_SIZE); + memset(param, 0, sizeof(nsp32_autoparam)); /* cdb */ - for (i=0; icmd_len; i++) { - param[4*i] = SCpnt->cmnd[i]; + for (i = 0; i < SCpnt->cmd_len; i++) { + param->cdb[4 * i] = SCpnt->cmnd[i]; } - /* message out */ - param[4*0x10 +0] = (msgout & 0x000000ff) >> 0; - param[4*0x10 +1] = (msgout & 0x0000ff00) >> 8; - param[4*0x10 +2] = (msgout & 0x00ff0000) >> 16; - param[4*0x10 +3] = (msgout & 0xff000000) >> 24; - - /* syncreg, ackwidth, target id, sampleing rate */ - param[4*0x11 +0] = data->curtarget->syncreg; - param[4*0x11 +1] = data->curtarget->ackwidth; - param[4*0x11 +2] = BIT(host_id) | BIT(target); - param[4*0x11 +3] = 0; + /* outgoing messages */ + param->msgout = cpu_to_le32(msgout_reg); + + /* syncreg, ackwidth, target id, SREQ sampling rate */ + param->syncreg = data->cur_target->syncreg; + param->ackwidth = data->cur_target->ackwidth; + param->target_id = BIT(host_id) | BIT(target); + param->sample_reg = data->cur_target->sample_reg; + + // nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "sample rate=0x%x\n", data->cur_target->sample_reg); /* command control */ - s = (CLEAR_CDB_FIFO_POINTER | AUTOSCSI_START | - AUTO_MSGIN_00_OR_04 | AUTO_MSGIN_02 | AUTO_ATN); - param[4*0x12 +0] = (s & 0x00ff) >> 0; - param[4*0x12 +1] = (s & 0xff00) >> 8; + param->command_control = cpu_to_le16(CLEAR_CDB_FIFO_POINTER | + AUTOSCSI_START | + AUTO_MSGIN_00_OR_04 | + AUTO_MSGIN_02 | + AUTO_ATN ); + /* transfer control */ - s = 0; + transfer_reg = 0; switch (data->trans_method) { case NSP32_TRANSFER_BUSMASTER: - s |= BM_START; + transfer_reg |= BM_START; break; case NSP32_TRANSFER_MMIO: - s |= CB_MMIO_MODE; + transfer_reg |= CB_MMIO_MODE; break; case NSP32_TRANSFER_PIO: - s |= CB_IO_MODE; + transfer_reg |= CB_IO_MODE; break; default: nsp32_msg(KERN_ERR, "unknown trans_method"); + break; } /* - * ORed BLIEND_MODE, FIFO intr is decreased, instead of PCI bus waits. + * OR-ed BLIEND_MODE, FIFO intr is decreased, instead of PCI bus waits. * For bus master transfer, it's taken off. */ - s |= (TRANSFER_GO | ALL_COUNTER_CLR); - param[4*0x12 +2] = (s & 0x00ff) >> 0; - param[4*0x12 +3] = (s & 0xff00) >> 8; + transfer_reg |= (TRANSFER_GO | ALL_COUNTER_CLR); + param->transfer_control = cpu_to_le16(transfer_reg); /* sg table addr */ - l = data->curlunt->sglun_paddr; - param[4*0x13 +0] = (l & 0x000000ff) >> 0; - param[4*0x13 +1] = (l & 0x0000ff00) >> 8; - param[4*0x13 +2] = (l & 0x00ff0000) >> 16; - param[4*0x13 +3] = (l & 0xff000000) >> 24; + param->sgt_pointer = cpu_to_le32(data->cur_lunt->sglun_paddr); /* - * transfer parameter to asic + * transfer parameter to ASIC */ - nsp32_write4(base, SGT_ADR, virt_to_bus(param)); + nsp32_write4(base, SGT_ADR, data->auto_paddr); nsp32_write2(base, COMMAND_CONTROL, CLEAR_CDB_FIFO_POINTER | AUTO_PARAMETER ); /* - * Arbitration Status Check - * - * Note: Arbitration counter is wait during ARBIT_GO is not lifting. - * Using udelay(1) consumes CPU time and system time, but - * arbitration delay time is defined minimal 2.4us in SCSI - * specification, thus udelay works as coarse grained wait timer. - */ - time = 0; - do { - arbit = nsp32_read1(base, ARBIT_STATUS); - nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "arbit=0x%x", arbit); - } while ((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 && - (time++ <= 1000)); - - nsp32_dbg(NSP32_DEBUG_AUTOSCSI, - "arbit: 0x%x, delay time: %d", arbit, time); - - if (arbit & ARBIT_WIN) { - SCpnt->result = DID_OK << 16; - /* PCI LED on! */ - nsp32_index_write1(base, EXT_PORT, LED_ON); - } else if (arbit & ARBIT_FAIL) { - SCpnt->result = DID_BUS_BUSY << 16; - nsp32_write1(base, SET_ARBIT, ARBIT_CLEAR); - return FALSE; - } else { - /* unknown error or ARBIT_GO timeout */ - nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "arbit fail"); - SCpnt->result = DID_NO_CONNECT << 16; - nsp32_write1(base, SET_ARBIT, ARBIT_CLEAR); - return FALSE; - } - - /* - * clear Arbit + * Check arbitration */ - nsp32_write1(base, SET_ARBIT, ARBIT_CLEAR); + ret = nsp32_arbitration(SCpnt, base); - return TRUE; + return ret; } /* * Selection with AUTO SCSI (without AUTO PARAMETER) */ -static int nsp32_selection_autoscsi(Scsi_Cmnd *SCpnt, nsp32_hw_data *data) +static int nsp32_selection_autoscsi(Scsi_Cmnd *SCpnt) { + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; + unsigned int base = SCpnt->device->host->io_port; + unsigned int host_id = SCpnt->device->host->this_id; + unsigned char target = SCpnt->device->id; unsigned char phase; - unsigned char arbit; int status; - int i; unsigned short command = 0; - int time = 0; - unsigned int msgout = 0; + unsigned long msgout = 0; unsigned short execph; - unsigned int base = data->BaseAddress; + int i; + + nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "in"); /* * IRQ disable @@ -715,8 +670,7 @@ * check bus line */ phase = nsp32_read1(base, SCSI_BUS_MONITOR); - if(((phase & BUSMON_BSY) == 1) || - (phase & BUSMON_SEL) == 1) { + if(((phase & BUSMON_BSY) == 1) || (phase & BUSMON_SEL) == 1) { nsp32_msg(KERN_WARNING, "bus busy"); SCpnt->result = DID_BUS_BUSY << 16; status = 1; @@ -736,95 +690,75 @@ /* * set CDB0 - CDB15 */ - for (i=0; icmd_len; i++) { + for (i = 0; i < SCpnt->cmd_len; i++) { nsp32_write1(base, COMMAND_DATA, SCpnt->cmnd[i]); } - nsp32_dbg(NSP32_DEBUG_CDB_CONTENTS, "CDB[0]=[0x%x]", SCpnt->cmnd[i]); + nsp32_dbg(NSP32_DEBUG_CDB_CONTENTS, "CDB[0]=[0x%x]", SCpnt->cmnd[0]); /* - * set SCSIOUT LATCH(initiator)/TARGET(target) (ORed) ID + * set SCSIOUT LATCH(initiator)/TARGET(target) (OR-ed) ID */ - nsp32_write1(base, SCSI_OUT_LATCH_TARGET_ID, - ((1 << NSP32_HOST_SCSIID) | (1 << SCpnt->target))); + nsp32_write1(base, SCSI_OUT_LATCH_TARGET_ID, BIT(host_id) | BIT(target)); /* * set SCSI MSGOUT REG - * - * Note: If the range of msgoutlen is 1 - 3, fill scsi_msgout. - * over 3 messages needs another routine. */ - if (data->msgoutlen == 0) { - nsp32_msg(KERN_ERR, - "SCSI MsgOut without any message!"); + if (data->msgout_len == 0) { + nsp32_msg(KERN_ERR, "SCSI MsgOut without any message!"); SCpnt->result = DID_ERROR << 16; status = 1; goto out; - } else if (data->msgoutlen > 0 && data->msgoutlen <= 3) { - msgout = 0; - for (i=0; imsgoutlen; i++) { - /* - * the sending order of the message is: - * MCNT 3: MSG#0 -> MSG#1 -> MSG#2 - * MCNT 2: MSG#1 -> MSG#2 - * MCNT 1: MSG#2 - */ - msgout >>= 8; - msgout |= (unsigned int)(data->msgoutbuf[i] << 24); - } - msgout |= MV_VALID; /* MV valid */ - msgout |= (unsigned int)data->msgoutlen; /* len */ - nsp32_write4(base, SCSI_MSG_OUT, msgout); } else { - /* data->msgoutlen > 3 */ - nsp32_write4(base, SCSI_MSG_OUT, 0); + msgout = nsp32_msgout_register(SCpnt); + nsp32_write4(base, SCSI_MSG_OUT, msgout); } /* * set selection timeout(= 250ms) */ - nsp32_write2(base, SEL_TIME_OUT, SEL_TIMEOUT_TIME); + nsp32_write2(base, SEL_TIME_OUT, SEL_TIMEOUT_TIME); /* - * set smpl rate + * set SREQ hazard killer sampling rate * - * TODO: smpl_rate (BASE+0F) is 0 when internal clock = 40MHz. + * TODO: sample_rate (BASE+0F) is 0 when internal clock = 40MHz. * check other internal clock! */ - nsp32_write1(base, SREQ_SMPL_RATE, 0); + nsp32_write1(base, SREQ_SMPL_RATE, data->cur_target->sample_reg); /* * clear Arbit */ - nsp32_write1(base, SET_ARBIT, ARBIT_CLEAR); + nsp32_write1(base, SET_ARBIT, ARBIT_CLEAR); /* * set SYNCREG * Don't set BM_START_ADR before setting this register. */ - nsp32_write1(base, SYNC_REG, data->curtarget->syncreg); + nsp32_write1(base, SYNC_REG, data->cur_target->syncreg); /* * set ACKWIDTH */ - nsp32_write1(base, ACK_WIDTH, data->curtarget->ackwidth); + nsp32_write1(base, ACK_WIDTH, data->cur_target->ackwidth); nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "syncreg=0x%x, ackwidth=0x%x, sgtpaddr=0x%x, id=0x%x", nsp32_read1(base, SYNC_REG), nsp32_read1(base, ACK_WIDTH), nsp32_read4(base, SGT_ADR), nsp32_read1(base, SCSI_OUT_LATCH_TARGET_ID)); - nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "msgoutlen=%d, msgout=0x%x", - data->msgoutlen, msgout); + nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "msgout_len=%d, msgout=0x%x", + data->msgout_len, msgout); /* * set SGT ADDR (physical address) */ - nsp32_write4(base, SGT_ADR, data->curlunt->sglun_paddr); + nsp32_write4(base, SGT_ADR, data->cur_lunt->sglun_paddr); /* * set TRANSFER CONTROL REG */ command = 0; - command |= ( TRANSFER_GO | ALL_COUNTER_CLR); + command |= (TRANSFER_GO | ALL_COUNTER_CLR); if (data->trans_method & NSP32_TRANSFER_BUSMASTER) { if (SCpnt->request_bufflen > 0) { command |= BM_START; @@ -839,73 +773,75 @@ /* * start AUTO SCSI, kick off arbitration */ - command = 0; - command |= (CLEAR_CDB_FIFO_POINTER - | AUTOSCSI_START - | AUTO_MSGIN_00_OR_04 - | AUTO_MSGIN_02 - | AUTO_ATN); + command = (CLEAR_CDB_FIFO_POINTER | + AUTOSCSI_START | + AUTO_MSGIN_00_OR_04 | + AUTO_MSGIN_02 | + AUTO_ATN ); nsp32_write2(base, COMMAND_CONTROL, command); /* - * Arbitration Status Check - * - * Note: Arbitration counter is wait during ARBIT_GO is not lifting. - * Using udelay(1) consumes CPU time and system time, but - * arbitration delay time is defined minimal 2.4us in SCSI - * specification, thus udelay works as coarse grained wait timer. + * Check arbitration */ - time = 0; - while(1) { - arbit = nsp32_read1(base, ARBIT_STATUS); - if(arbit & ARBIT_GO) { - udelay(1); - time++; - if ( time > ARBIT_TIMEOUT_TIME ) { - /* something lock up! guess no connection */ - SCpnt->result = DID_NO_CONNECT << 16; - status = FALSE; - goto out; - } - } else { - break; - } - }; - - nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "arbit: 0x%x, delay time: %d", arbit, time); + status = nsp32_arbitration(SCpnt, base); + out: /* - * check Arbitration Status Result + * IRQ enable */ - if(arbit & ARBIT_WIN) { + nsp32_write2(base, IRQ_CONTROL, 0); + + return status; +} + + +/* + * Arbitration Status Check + * + * Note: Arbitration counter is waited during ARBIT_GO is not lifting. + * Using udelay(1) consumes CPU time and system time, but + * arbitration delay time is defined minimal 2.4us in SCSI + * specification, thus udelay works as coarse grained wait timer. + */ +static int nsp32_arbitration(Scsi_Cmnd *SCpnt, unsigned int base) +{ + unsigned char arbit; + int status = TRUE; + int time = 0; + + do { + arbit = nsp32_read1(base, ARBIT_STATUS); + time++; + } while ((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 && + (time <= ARBIT_TIMEOUT_TIME)); + + nsp32_dbg(NSP32_DEBUG_AUTOSCSI, + "arbit: 0x%x, delay time: %d", arbit, time); + + if (arbit & ARBIT_WIN) { /* Arbitration succeeded */ - status = TRUE; SCpnt->result = DID_OK << 16; - /* PCI LED on! */ - nsp32_index_write1(base, EXT_PORT, LED_ON); - } else if(arbit & ARBIT_FAIL) { + nsp32_index_write1(base, EXT_PORT, LED_ON); /* PCI LED on */ + } else if (arbit & ARBIT_FAIL) { /* Arbitration failed */ - status = FALSE; SCpnt->result = DID_BUS_BUSY << 16; - } else { - /* unknown error? */ status = FALSE; - SCpnt->result = DID_ERROR << 16; + } else { + /* + * unknown error or ARBIT_GO timeout, + * something lock up! guess no connection. + */ + nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "arbit timeout"); SCpnt->result = DID_NO_CONNECT << 16; - } + status = FALSE; + } /* * clear Arbit */ nsp32_write1(base, SET_ARBIT, ARBIT_CLEAR); - out: - /* - * IRQ enable - */ - nsp32_write2(base, IRQ_CONTROL, 0); - - return(status); + return status; } @@ -916,10 +852,12 @@ * reselection target id&lun must be already set. * SCSI-2 says IDENTIFY implies RESTORE_POINTER operation. */ -static int nsp32_reselection(nsp32_hw_data *data, unsigned char newlun) +static int nsp32_reselection(Scsi_Cmnd *SCpnt, unsigned char newlun) { - unsigned int base = data->BaseAddress; - unsigned char tmpid, newid; + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; + unsigned int host_id = SCpnt->device->host->this_id; + unsigned int base = SCpnt->device->host->io_port; + unsigned char tmpid, newid; nsp32_dbg(NSP32_DEBUG_RESELECTION, "enter"); @@ -927,7 +865,7 @@ * calculate reselected SCSI ID */ tmpid = nsp32_read1(base, RESELECT_ID); - tmpid &= 0x7f; + tmpid &= (~BIT(host_id)); newid = 0; while (tmpid) { if (tmpid & 1) { @@ -940,20 +878,20 @@ /* * If reselected New ID:LUN is not existed * or current nexus is not existed, unexpected - * reselection is occured. Send reject message. + * reselection is occurred. Send reject message. */ - if (newid >= MAX_TARGET || newlun >= MAX_LUN) { + if (newid >= NUMBER(data->lunt) || newlun >= NUMBER(data->lunt[0])) { nsp32_msg(KERN_WARNING, "unknown id/lun"); return FALSE; - } else if(data->lunt[newid][newlun]->SCpnt == NULL) { + } else if(data->lunt[newid][newlun].SCpnt == NULL) { nsp32_msg(KERN_WARNING, "no SCSI command is processing"); return FALSE; } - data->pid = newid; - data->plun = newlun; - data->curtarget = &data->target[newid]; - data->curlunt = data->lunt[newid][newlun]; + data->cur_id = newid; + data->cur_lun = newlun; + data->cur_target = &(data->target[newid]); + data->cur_lunt = &(data->lunt[newid][newlun]); /* reset SACK/SavedACK counter (or ALL clear?) */ nsp32_write4(base, CLR_COUNTER, CLRCOUNTER_ALLMASK); @@ -963,16 +901,18 @@ /* - * nsp32hw_setup_sg_table - build scatter gather list for transfer data + * nsp32_setup_sg_table - build scatter gather list for transfer data * with bus master. * * Note: NinjaSCSI-32Bi/UDE bus master can not transfer over 64KB at a time. */ -static int nsp32hw_setup_sg_table(Scsi_Cmnd *SCpnt, nsp32_hw_data *data) +static int nsp32_setup_sg_table(Scsi_Cmnd *SCpnt) { - struct scatterlist *sgl; - struct nsp32_sgtable *sgt = data->curlunt->sglun->sgt; + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; + struct scatterlist *sgl; + nsp32_sgtable *sgt = data->cur_lunt->sglun->sgt; int num, i; + u32 l; if (SCpnt->request_bufflen == 0) { return TRUE; @@ -987,7 +927,7 @@ sgl = (struct scatterlist *)SCpnt->request_buffer; num = pci_map_sg(data->Pci, sgl, SCpnt->use_sg, scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); - for (i=0; i 65536) { + if (le32_to_cpu(sgt[i].len) > 0x10000) { nsp32_msg(KERN_ERR, - "can't transfer over 64KB at a time"); + "can't transfer over 64KB at a time, size=0x%lx", le32_to_cpu(sgt[i].len)); return FALSE; } nsp32_dbg(NSP32_DEBUG_SGLIST, - "num 0x%x : addr 0x%lx len 0x%x", - i, sgt[i].addr, sgt[i].len); + "num 0x%x : addr 0x%lx len 0x%lx", + i, + le32_to_cpu(sgt[i].addr), + le32_to_cpu(sgt[i].len )); } - sgt[num-1].len |= NSP32_SG_END_SGT; /* set end mark */ + + /* set end mark */ + l = le32_to_cpu(sgt[num-1].len); + sgt[num-1].len = cpu_to_le32(l | SGTEND); + } else { SCpnt->SCp.have_data_in = pci_map_single(data->Pci, SCpnt->request_buffer, SCpnt->request_bufflen, scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); + sgt[0].addr = cpu_to_le32(SCpnt->SCp.have_data_in); - sgt[0].len = cpu_to_le32(SCpnt->request_bufflen); - sgt[0].len |= NSP32_SG_END_SGT; /* set end mark */ + sgt[0].len = cpu_to_le32(SCpnt->request_bufflen | SGTEND); /* set end mark */ - nsp32_dbg(NSP32_DEBUG_SGLIST, "single : addr 0x%lx len=0x%x", - sgt[0].addr, sgt[0].len); + if (SCpnt->request_bufflen > 0x10000) { + nsp32_msg(KERN_ERR, + "can't transfer over 64KB at a time, size=0x%lx", SCpnt->request_bufflen); + return FALSE; + } + nsp32_dbg(NSP32_DEBUG_SGLIST, "single : addr 0x%lx len=0x%lx", + le32_to_cpu(sgt[0].addr), + le32_to_cpu(sgt[0].len )); } return TRUE; @@ -1022,38 +974,40 @@ static int nsp32_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { - nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->host->hostdata; - struct nsp32_target *target; - struct nsp32_lunt *curlunt; + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; + nsp32_target *target; + nsp32_lunt *cur_lunt; int ret; nsp32_dbg(NSP32_DEBUG_QUEUECOMMAND, "enter. target: 0x%x LUN: 0x%x cmnd: 0x%x cmndlen: 0x%x " "use_sg: 0x%x reqbuf: 0x%lx reqlen: 0x%x", - SCpnt->target, SCpnt->lun, SCpnt->cmnd[0], SCpnt->cmd_len, + SCpnt->device->id, SCpnt->device->lun, SCpnt->cmnd[0], SCpnt->cmd_len, SCpnt->use_sg, SCpnt->request_buffer, SCpnt->request_bufflen); - if (data->CurrentSC != NULL ) { + if (data->CurrentSC != NULL) { nsp32_msg(KERN_ERR, "Currentsc != NULL. Cancel this command request"); data->CurrentSC = NULL; SCpnt->result = DID_NO_CONNECT << 16; done(SCpnt); - return 1; + return SCSI_MLQUEUE_HOST_BUSY; } /* check target ID is not same as this initiator ID */ - if (SCpnt->target == NSP32_HOST_SCSIID) { + if (SCpnt->device->id == SCpnt->device->host->this_id) { + nsp32_dbg(NSP32_DEBUG_QUEUECOMMAND, "terget==host???"); SCpnt->result = DID_BAD_TARGET << 16; done(SCpnt); - return 1; + return SCSI_MLQUEUE_DEVICE_BUSY; } /* check target LUN is allowable value */ - if (SCpnt->lun >= MAX_LUN) { + if (SCpnt->device->lun >= MAX_LUN) { + nsp32_dbg(NSP32_DEBUG_QUEUECOMMAND, "no more lun"); SCpnt->result = DID_BAD_TARGET << 16; done(SCpnt); - return 1; + return SCSI_MLQUEUE_DEVICE_BUSY; } show_command(SCpnt); @@ -1062,7 +1016,7 @@ data->CurrentSC = SCpnt; SCpnt->SCp.Status = CHECK_CONDITION; SCpnt->SCp.Message = 0; - SCpnt->resid = 0; //SCpnt->request_bufflen; + SCpnt->resid = SCpnt->request_bufflen; SCpnt->SCp.ptr = (char *) SCpnt->request_buffer; SCpnt->SCp.this_residual = SCpnt->request_bufflen; @@ -1070,39 +1024,41 @@ SCpnt->SCp.buffers_residual = 0; /* initialize data */ - data->msgoutlen = 0; - data->msginlen = 0; - curlunt = data->lunt[SCpnt->target][SCpnt->lun]; - curlunt->SCpnt = SCpnt; - curlunt->save_datp = 0; - curlunt->msgin03 = FALSE; - data->curlunt = curlunt; - data->pid = SCpnt->target; - data->plun = SCpnt->lun; + data->msgout_len = 0; + data->msgin_len = 0; + cur_lunt = &(data->lunt[SCpnt->device->id][SCpnt->device->lun]); + cur_lunt->SCpnt = SCpnt; + cur_lunt->save_datp = 0; + cur_lunt->msgin03 = FALSE; + data->cur_lunt = cur_lunt; + data->cur_id = SCpnt->device->id; + data->cur_lun = SCpnt->device->lun; - ret = nsp32hw_setup_sg_table(SCpnt, data); + ret = nsp32_setup_sg_table(SCpnt); if (ret == FALSE) { + nsp32_msg(KERN_ERR, "SGT fail"); SCpnt->result = DID_ERROR << 16; - nsp32_scsi_done(data, SCpnt); + nsp32_scsi_done(SCpnt); + return SCSI_MLQUEUE_HOST_BUSY; } /* Build IDENTIFY */ - nsp32_build_identify(data, SCpnt); + nsp32_build_identify(SCpnt); /* * If target is the first time to transfer after the reset * (target don't have SDTR_DONE and SDTR_INITIATOR), sync * message SDTR is needed to do synchronous transfer. */ - target = &data->target[SCpnt->target]; - data->curtarget = target; + target = &data->target[SCpnt->device->id]; + data->cur_target = target; if (!(target->sync_flag & (SDTR_DONE | SDTR_INITIATOR | SDTR_TARGET))) { unsigned char period, offset; if (trans_mode != ASYNC_MODE) { nsp32_set_max_sync(data, target, &period, &offset); - nsp32_build_sdtr(data, period, offset); + nsp32_build_sdtr(SCpnt, period, offset); target->sync_flag |= SDTR_INITIATOR; } else { nsp32_set_async(data, target); @@ -1140,32 +1096,32 @@ nsp32_dbg(NSP32_DEBUG_TARGETFLAG, "target: %d sync_flag: 0x%x syncreg: 0x%x ackwidth: 0x%x", - SCpnt->target, target->sync_flag, target->syncreg, + SCpnt->device->id, target->sync_flag, target->syncreg, target->ackwidth); /* Selection */ if (auto_param == 0) { - ret = nsp32hw_start_selection(SCpnt, data); + ret = nsp32_selection_autopara(SCpnt); } else { - ret = nsp32_selection_autoscsi(SCpnt, data); + ret = nsp32_selection_autoscsi(SCpnt); } if (ret != TRUE) { - nsp32_scsi_done(data, SCpnt); - return 1; + nsp32_dbg(NSP32_DEBUG_QUEUECOMMAND, "selection fail"); + nsp32_scsi_done(SCpnt); + return SCSI_MLQUEUE_DEVICE_BUSY; } return 0; } /* initialize asic */ -static int nsp32hw_init(struct Scsi_Host *host) +static int nsp32hw_init(nsp32_hw_data *data) { - unsigned int base = host->io_port; + unsigned int base = data->BaseAddress; unsigned short irq_stat; - unsigned long lc_reg; - unsigned char power; - nsp32_hw_data *data = (nsp32_hw_data *)host->hostdata; + unsigned long lc_reg; + unsigned char power; lc_reg = nsp32_index_read4(base, CFG_LATE_CACHE); if ((lc_reg & 0xff00) == 0) { @@ -1173,15 +1129,15 @@ nsp32_index_write2(base, CFG_LATE_CACHE, lc_reg & 0xffff); } - nsp32_write2(base, IRQ_CONTROL, IRQ_CONTROL_ALL_IRQ_MASK); - nsp32_write2(base, TRANSFER_CONTROL, 0); - nsp32_write4(base, BM_CNT, 0); + nsp32_write2(base, IRQ_CONTROL, IRQ_CONTROL_ALL_IRQ_MASK); + nsp32_write2(base, TRANSFER_CONTROL, 0); + nsp32_write4(base, BM_CNT, 0); nsp32_write2(base, SCSI_EXECUTE_PHASE, 0); do { irq_stat = nsp32_read2(base, IRQ_STATUS); + nsp32_dbg(NSP32_DEBUG_INIT, "irq_stat 0x%x", irq_stat); } while (irq_stat & IRQSTATUS_ANY_IRQ); - nsp32_dbg(NSP32_DEBUG_INIT, "irq_stat 0x%x", irq_stat); /* * Fill FIFO_FULL_SHLD, FIFO_EMPTY_SHLD. Below parameter is @@ -1189,22 +1145,25 @@ */ if ((data->trans_method & NSP32_TRANSFER_PIO) || (data->trans_method & NSP32_TRANSFER_MMIO)) { - nsp32_index_write1(base, FIFO_FULL_SHLD_COUNT, 0x40); + nsp32_index_write1(base, FIFO_FULL_SHLD_COUNT, 0x40); + nsp32_index_write1(base, FIFO_EMPTY_SHLD_COUNT, 0x40); } else if (data->trans_method & NSP32_TRANSFER_BUSMASTER) { - nsp32_index_write1(base, FIFO_FULL_SHLD_COUNT, 0x10); + nsp32_index_write1(base, FIFO_FULL_SHLD_COUNT, 0x10); + nsp32_index_write1(base, FIFO_EMPTY_SHLD_COUNT, 0x60); + } else { + nsp32_dbg(NSP32_DEBUG_INIT, "unknown transfer mode"); } - nsp32_index_write1(base, FIFO_EMPTY_SHLD_COUNT, 0x60); nsp32_dbg(NSP32_DEBUG_INIT, "full 0x%x emp 0x%x", nsp32_index_read1(base, FIFO_FULL_SHLD_COUNT), nsp32_index_read1(base, FIFO_EMPTY_SHLD_COUNT)); nsp32_index_write1(base, CLOCK_DIV, data->clock); - nsp32_index_write1(base, BM_CYCLE, MEMRD_CMD1 | SGT_AUTO_PARA_MEMED_CMD); + nsp32_index_write1(base, BM_CYCLE, MEMRD_CMD1 | SGT_AUTO_PARA_MEMED_CMD); nsp32_write1(base, PARITY_CONTROL, 0); /* parity check is disable */ /* - * initialize I_MISC_WRRD register + * initialize MISC_WRRD register * * Note: Designated parameters is obeyed as following: * MISC_SCSI_DIRECTION_DETECTOR_SELECT: It must be set. @@ -1220,10 +1179,10 @@ */ nsp32_index_write2(base, MISC_WR, (SCSI_DIRECTION_DETECTOR_SELECT | - DELAYED_BMSTART | - MASTER_TERMINATION_SELECT | - BMREQ_NEGATE_TIMING_SEL | - AUTOSEL_TIMING_SEL | + DELAYED_BMSTART | + MASTER_TERMINATION_SELECT | + BMREQ_NEGATE_TIMING_SEL | + AUTOSEL_TIMING_SEL | BMSTOP_CHANGE2_NONDATA_PHASE)); nsp32_index_write1(base, TERM_PWR_CONTROL, 0); @@ -1234,11 +1193,11 @@ } nsp32_write2(base, TIMER_SET, TIMER_STOP); - nsp32_write2(base, TIMER_SET, TIMER_STOP); + nsp32_write2(base, TIMER_SET, TIMER_STOP); /* Required 2 times */ - nsp32_write1(base, SYNC_REG, 0); - nsp32_write1(base, ACK_WIDTH, 0); - nsp32_write2(base, SEL_TIME_OUT, 10000); /* 25us x10000 = 250ms defined in SCSI */ + nsp32_write1(base, SYNC_REG, 0); + nsp32_write1(base, ACK_WIDTH, 0); + nsp32_write2(base, SEL_TIME_OUT, SEL_TIMEOUT_TIME); /* * enable to select designated IRQ (except for @@ -1250,21 +1209,21 @@ IRQSELECT_RESELECT_IRQ | IRQSELECT_PHASE_CHANGE_IRQ | IRQSELECT_AUTO_SCSI_SEQ_IRQ | - //IRQSELECT_BMCNTERR_IRQ | + // IRQSELECT_BMCNTERR_IRQ | IRQSELECT_TARGET_ABORT_IRQ | IRQSELECT_MASTER_ABORT_IRQ ); nsp32_write2(base, IRQ_CONTROL, 0); /* PCI LED off */ nsp32_index_write1(base, EXT_PORT_DDR, LED_OFF); - nsp32_index_write1(base, EXT_PORT, LED_OFF); + nsp32_index_write1(base, EXT_PORT, LED_OFF); return TRUE; } /* interrupt routine */ -static void do_nsp32_isr(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t do_nsp32_isr(int irq, void *dev_id, struct pt_regs *regs) { nsp32_hw_data *data = dev_id; unsigned int base = data->BaseAddress; @@ -1273,13 +1232,9 @@ unsigned char busmon, busphase; unsigned long flags; int ret; + int handled = 0; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) - struct Scsi_Host *host = data->Host; - spin_lock_irqsave(host->host_lock, flags); -#else - spin_lock_irqsave(&io_request_lock, flags); -#endif + spin_lock_irqsave(HOST_LOCK, flags); /* * IRQ check, then enable IRQ mask @@ -1289,9 +1244,10 @@ "enter IRQ: %d, IRQstatus: 0x%x", irq, irq_stat); /* is this interrupt comes from Ninja asic? */ if ((irq_stat & IRQSTATUS_ANY_IRQ) == 0) { - nsp32_msg(KERN_INFO, "spurious interrupt: irq other 0x%x", irq_stat); + nsp32_dbg(NSP32_DEBUG_INTR, "shared interrupt: irq other 0x%x", irq_stat); goto out2; } + handled = 1; nsp32_write2(base, IRQ_CONTROL, IRQ_CONTROL_ALL_IRQ_MASK); busmon = nsp32_read1(base, SCSI_BUS_MONITOR); @@ -1303,14 +1259,14 @@ if (data->CurrentSC != NULL) { nsp32_msg(KERN_INFO, "clean up current SCSI command"); SCpnt->result = DID_BAD_TARGET << 16; - nsp32_scsi_done(data, SCpnt); + nsp32_scsi_done(SCpnt); } goto out; } /* Timer IRQ */ if (irq_stat & IRQSTATUS_TIMER_IRQ) { - DEBUG(0, "timer stop\n"); + nsp32_dbg(NSP32_DEBUG_INTR, "timer stop"); nsp32_write2(base, TIMER_SET, TIMER_STOP); goto out; } @@ -1321,20 +1277,20 @@ nsp32_do_bus_reset(data); if (SCpnt != NULL) { SCpnt->result = DID_RESET << 16; - nsp32_scsi_done(data, SCpnt); + nsp32_scsi_done(SCpnt); } goto out; } - + if (SCpnt == NULL) { - nsp32_msg(KERN_WARNING, "SCpnt==NULL this can't be happen\n"); - nsp32_msg(KERN_WARNING, "irq_stat=0x%x trans_stat=0x%x\n", irq_stat, trans_stat); + nsp32_msg(KERN_WARNING, "SCpnt==NULL this can't be happened"); + nsp32_msg(KERN_WARNING, "irq_stat=0x%x trans_stat=0x%x", irq_stat, trans_stat); goto out; } /* * AutoSCSI Interrupt. - * Note: This interrupt is occured when AutoSCSI is finished. Then + * Note: This interrupt is occurred when AutoSCSI is finished. Then * check SCSIEXECUTEPHASE, and do appropriate action. Each phases are * recorded when AutoSCSI sequencer has been processed. */ @@ -1346,10 +1302,10 @@ /* Selection Timeout, go busfree phase. */ if (auto_stat & SELECTION_TIMEOUT) { nsp32_dbg(NSP32_DEBUG_INTR, - "selection timeout occured"); + "selection timeout occurred"); SCpnt->result = DID_TIME_OUT << 16; - nsp32_scsi_done(data, SCpnt); + nsp32_scsi_done(SCpnt); goto out; } @@ -1357,17 +1313,17 @@ /* * MsgOut phase was processed. * If MSG_IN_OCCUER is not set, then MsgOut phase is - * completed. Thus, msgoutlen must reset. Otherwise, - * nothing to do here. If MSG_OUT_OCCUER is occured, + * completed. Thus, msgout_len must reset. Otherwise, + * nothing to do here. If MSG_OUT_OCCUER is occurred, * then we will encounter the condition and check. */ if (!(auto_stat & MSG_IN_OCCUER) && - (data->msgoutlen <= 3)) { + (data->msgout_len <= 3)) { /* - * !MSG_IN_OCCUER && msgoutlen <=3 + * !MSG_IN_OCCUER && msgout_len <=3 * ---> AutoSCSI with MSGOUTreg is processed. */ - data->msgoutlen = 0; + data->msgout_len = 0; }; nsp32_dbg(NSP32_DEBUG_INTR, "MsgOut phase processed"); @@ -1394,28 +1350,29 @@ nsp32_read4(base, SACK_CNT)); nsp32_dbg(NSP32_DEBUG_INTR, "SSACK=0x%lx", nsp32_read4(base, SAVED_SACK_CNT)); - + + SCpnt->resid = 0; /* all data transfered! */ } /* * MsgIn Occur */ if (auto_stat & MSG_IN_OCCUER) { - nsp32_msgin_occur(data, irq_stat, auto_stat); + nsp32_msgin_occur(SCpnt, irq_stat, auto_stat); } /* * MsgOut Occur */ if (auto_stat & MSG_OUT_OCCUER) { - nsp32_msgout_occur(data); + nsp32_msgout_occur(SCpnt); } /* * Bus Free Occur */ if (auto_stat & BUS_FREE_OCCUER) { - ret = nsp32_busfree_occur(data, auto_stat); + ret = nsp32_busfree_occur(SCpnt, auto_stat); if (ret == TRUE) { goto out; } @@ -1466,28 +1423,28 @@ switch(busphase) { case BUSPHASE_DATA_OUT: - printk( "write\n"); + nsp32_dbg(NSP32_DEBUG_INTR, "fifo/write"); //nsp32_pio_write(SCpnt); break; case BUSPHASE_DATA_IN: - printk( "read\n"); + nsp32_dbg(NSP32_DEBUG_INTR, "fifo/read"); //nsp32_pio_read(SCpnt); break; case BUSPHASE_STATUS: - //DEBUG(0, "fifo/status\n"); + nsp32_dbg(NSP32_DEBUG_INTR, "fifo/status"); SCpnt->SCp.Status = nsp32_read1(base, SCSI_CSB_IN); break; default: - printk("fifo/other phase?\n"); - printk("irq_stat=0x%x trans_stat=0x%x\n", irq_stat, trans_stat); + nsp32_dbg(NSP32_DEBUG_INTR, "fifo/other phase"); + nsp32_dbg(NSP32_DEBUG_INTR, "irq_stat=0x%x trans_stat=0x%x", irq_stat, trans_stat); show_busphase(busphase); break; } @@ -1502,7 +1459,7 @@ switch(busphase) { case BUSPHASE_MESSAGE_IN: nsp32_dbg(NSP32_DEBUG_INTR, "phase chg/msg in"); - nsp32_msgin_occur(data, irq_stat, 0); + nsp32_msgin_occur(SCpnt, irq_stat, 0); break; default: nsp32_msg(KERN_WARNING, "phase chg/other phase?"); @@ -1516,7 +1473,7 @@ /* PCI_IRQ */ if (irq_stat & IRQSTATUS_PCI_IRQ) { - nsp32_dbg(NSP32_DEBUG_INTR, "PCI IRQ occured"); + nsp32_dbg(NSP32_DEBUG_INTR, "PCI IRQ occurred"); /* Do nothing */ } @@ -1525,13 +1482,14 @@ nsp32_msg(KERN_ERR, "Received unexpected BMCNTERR IRQ! "); /* * TODO: To be implemented improving bus master - * transfer reliablity when BMCNTERR is occured in + * transfer reliablity when BMCNTERR is occurred in * AutoSCSI phase described in specification. */ } #if 0 - printk("irq_stat=0x%x trans_stat=0x%x\n", irq_stat, trans_stat); + nsp32_dbg(NSP32_DEBUG_INTR, + "irq_stat=0x%x trans_stat=0x%x", irq_stat, trans_stat); show_busphase(busphase); #endif @@ -1540,72 +1498,122 @@ nsp32_write2(base, IRQ_CONTROL, 0); out2: -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - spin_unlock_irqrestore(&io_request_lock, flags); -#else - spin_unlock_irqrestore(host->host_lock, flags); -#endif + spin_unlock_irqrestore(HOST_LOCK, flags); nsp32_dbg(NSP32_DEBUG_INTR, "exit"); - return; + return IRQ_RETVAL(handled); } #undef SPRINTF #define SPRINTF(args...) \ - do { if(pos < buffer + length) pos += sprintf(pos, ## args); } while(0) -static int nsp32_proc_info(char *buffer, - char **start, - off_t offset, - int length, - int hostno, - int inout) + do { \ + if(length > (pos - buffer)) { \ + pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \ + nsp32_dbg(NSP32_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length, length - (pos - buffer));\ + } \ + } while(0) +static int nsp32_proc_info( +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) + struct Scsi_Host *host, +#endif + char *buffer, + char **start, + off_t offset, + int length, +#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) + int hostno, +#endif + int inout) { - char *pos = buffer; - int thislength; - unsigned long flags; - nsp32_hw_data *data; - struct Scsi_Host *host = NULL; - unsigned int base; - unsigned char mode_reg; + char *pos = buffer; + int thislength; + unsigned long flags; + nsp32_hw_data *data; +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) + int hostno; +#else + struct Scsi_Host *host; +#endif + unsigned int base; + unsigned char mode_reg; + int id, speed; + long model; /* Write is not supported, just return. */ if (inout == TRUE) { return -EINVAL; } +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) + hostno = host->host_no; +#else /* search this HBA host */ - for (host=scsi_hostlist; host; host=host->next) { - if (host->host_no == hostno) { - break; - } - } + host = scsi_host_hn_get(hostno); if (host == NULL) { return -ESRCH; } +#endif data = (nsp32_hw_data *)host->hostdata; base = host->io_port; SPRINTF("NinjaSCSI-32 status\n\n"); - SPRINTF("Driver version: %s\n", nsp32_release_version); + SPRINTF("Driver version: %s, $Revision: 1.2 $\n", nsp32_release_version); SPRINTF("SCSI host No.: %d\n", hostno); SPRINTF("IRQ: %d\n", host->irq); SPRINTF("IO: 0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1); - SPRINTF("MMIO(virtual address): 0x%lx\n", host->base); + SPRINTF("MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1); SPRINTF("sg_tablesize: %d\n", host->sg_tablesize); - SPRINTF("Chip revision: %d\n", (nsp32_read2(base, INDEX_REG) >> 8) - 0x4f); + SPRINTF("Chip revision: 0x%x\n", (nsp32_read2(base, INDEX_REG) >> 8) & 0xff); mode_reg = nsp32_index_read1(base, CHIP_MODE); + model = data->pci_devid->driver_data; #ifdef CONFIG_PM - //SPRINTF("Power Management: %s\n", (mode_reg & OPTF) ? "yes" : "no"); + SPRINTF("Power Management: %s\n", (mode_reg & OPTF) ? "yes" : "no"); #endif - SPRINTF("OEM: %s\n", nsp32_model[mode_reg & (OEM0|OEM1)]); + SPRINTF("OEM: %ld, %s\n", (mode_reg & (OEM0|OEM1)), nsp32_model[model]); spin_lock_irqsave(&(data->Lock), flags); SPRINTF("CurrentSC: 0x%p\n\n", data->CurrentSC); spin_unlock_irqrestore(&(data->Lock), flags); + + SPRINTF("SDTR status\n"); + for(id = 0; id < NUMBER(data->target); id++) { + + SPRINTF("id %d: ", id); + + if (id == host->this_id) { + SPRINTF("----- NinjaSCSI-32 host adapter\n"); + continue; + } + + if (data->target[id].sync_flag == SDTR_DONE) { + if (data->target[id].period == 0 && + data->target[id].offset == ASYNC_OFFSET ) { + SPRINTF("async"); + } else { + SPRINTF(" sync"); + } + } else { + SPRINTF(" none"); + } + + if (data->target[id].period != 0) { + + speed = 1000000 / (data->target[id].period * 4); + + SPRINTF(" transfer %d.%dMB/s, offset %d", + speed / 1000, + speed % 1000, + data->target[id].offset + ); + } + SPRINTF("\n"); + } + + thislength = pos - (buffer + offset); if(thislength < 0) { @@ -1621,1542 +1629,1452 @@ } #undef SPRINTF + + /* - * Note: n_io_port is defined as 0x7f because I/O register port is - * assigned as: - * 0x800-0x8ff: memory mapped I/O port - * 0x900-0xbff: (map same 0x800-0x8ff I/O port image repeatedly) - * 0xc00-0xfff: CardBus status registers + * Reset parameters and call scsi_done for data->cur_lunt. + * Be careful setting SCpnt->result = DID_* before calling this function. */ -static int nsp32_detect(Scsi_Host_Template *sht) +static void nsp32_scsi_done(Scsi_Cmnd *SCpnt) { - struct Scsi_Host *host; /* registered host structure */ - int ret; - nsp32_hw_data *data; - int i, j; - - nsp32_dbg(NSP32_DEBUG_REGISTER, "enter"); + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; + unsigned int base = SCpnt->device->host->io_port; /* - * register this HBA as SCSI device + * unmap pci */ - host = scsi_register(sht, sizeof(nsp32_hw_data)); - if (host == NULL) { - nsp32_msg (KERN_ERR, "failed to scsi register"); - goto err; + if (SCpnt->request_bufflen == 0) { + goto skip; } - /* - * set nsp32_hw_data - */ - data = (nsp32_hw_data *)host->hostdata; - memset(data, 0, sizeof(nsp32_hw_data)); - - data->IrqNumber = nsp32_data_base.IrqNumber; - data->BaseAddress = nsp32_data_base.BaseAddress; - data->NumAddress = nsp32_data_base.NumAddress; - data->MmioAddress = nsp32_data_base.MmioAddress; - data->Pci = nsp32_data_base.Pci; - data->pci_devid = nsp32_data_base.pci_devid; - - host->irq = data->IrqNumber; - host->io_port = data->BaseAddress; - host->unique_id = data->BaseAddress; - host->n_io_port = data->NumAddress; - host->base = data->MmioAddress; - scsi_set_pci_device(host, data->Pci); - - data->Host = host; - spin_lock_init(&(data->Lock)); - - data->curlunt = NULL; - data->curtarget = NULL; + if (SCpnt->use_sg) { + pci_unmap_sg(data->Pci, + (struct scatterlist *)SCpnt->buffer, + SCpnt->use_sg, + scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); + } else { + pci_unmap_single(data->Pci, + (u32)SCpnt->SCp.have_data_in, + SCpnt->request_bufflen, + scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); + } + skip: /* - * Bus master transfer mode is supported currently. + * clear TRANSFERCONTROL_BM_START */ - data->trans_method = NSP32_TRANSFER_BUSMASTER; + nsp32_write2(base, TRANSFER_CONTROL, 0); + nsp32_write4(base, BM_CNT, 0); /* - * Set clock div, CLOCK_4 (HBA has external clock, and - * dividing * 100ns/4). - * Currently CLOCK_4 has only tested, not for CLOCK_2/PCICLK yet. + * call scsi_done */ - data->clock = CLOCK_4; + (*SCpnt->scsi_done)(SCpnt); /* - * Select appropriate nsp32_sync_table and set I_CLOCKDIV. + * reset parameters */ - switch (data->clock) { - case CLOCK_4: - /* If data->clock is CLOCK_4, then select 40M sync table. */ - data->synct = nsp32_sync_table_40M; - data->syncnum = nsp32_table_40M_num; - break; - case CLOCK_2: - /* If data->clock is CLOCK_2, then select 20M sync table. */ - data->synct = nsp32_sync_table_20M; - data->syncnum = nsp32_table_20M_num; - break; - case PCICLK: - /* If data->clock is PCICLK, then select pci sync table. */ - data->synct = nsp32_sync_table_pci; - data->syncnum = nsp32_table_pci_num; - break; - default: - nsp32_msg(KERN_WARNING, - "Invalid clock div is selected, set CLOCK_4."); - /* Use default value CLOCK_4 */ - data->clock = CLOCK_4; - data->synct = nsp32_sync_table_40M; - data->syncnum = nsp32_table_40M_num; - } + data->cur_lunt->SCpnt = NULL; + data->cur_lunt = NULL; + data->cur_target = NULL; + data->CurrentSC = NULL; +} - /* - * setup nsp32_lunt - */ - data->lunt_list = (struct nsp32_lunt *) - kmalloc(sizeof(struct nsp32_lunt) * MAX_TARGET * MAX_LUN, - GFP_KERNEL); - if (data->lunt_list == NULL) { - nsp32_msg(KERN_ERR, "cannot allocate LUN memory"); - goto scsi_unregister; - } - nsp32_dbg(NSP32_DEBUG_REGISTER, "0x%x 0x%x", - data->lunt_list, sizeof(struct nsp32_lunt)*MAX_TARGET*MAX_LUN); - /* - * setup DMA - */ - if (pci_set_dma_mask(data->Pci, 0xffffffffUL)) { - nsp32_msg (KERN_ERR, "failed to set PCI DMA mask"); - goto kfree_lunt; - } +/* + * Bus Free Occur + * + * Current Phase is BUSFREE. AutoSCSI is automatically execute BUSFREE phase + * with ACK reply when below condition is matched: + * MsgIn 00: Command Complete. + * MsgIn 02: Save Data Pointer. + * MsgIn 04: Diconnect. + * In other case, unexpected BUSFREE is detected. + */ +static int nsp32_busfree_occur(Scsi_Cmnd *SCpnt, unsigned short execph) +{ + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; + unsigned int base = SCpnt->device->host->io_port; - /* - * allocate autoparam DMA resource. - */ - data->autoparam = pci_alloc_consistent(data->Pci, AUTOPARAM_SIZE, &data->apaddr); - if (data->autoparam == NULL) { - nsp32_msg(KERN_ERR, "failed to allocate DMA memory"); - goto kfree_lunt; - } + nsp32_dbg(NSP32_DEBUG_BUSFREE, "enter execph=0x%x", execph); + show_autophase(execph); + + nsp32_write4(base, BM_CNT, 0); + nsp32_write2(base, TRANSFER_CONTROL, 0); /* - * allocate scatter-gather DMA resource. + * MsgIn 02: Save Data Pointer + * + * VALID: + * Save Data Pointer is received. Adjust pointer. + * + * NO-VALID: + * SCSI-3 says if Save Data Pointer is not received, then we restart + * processing and we can't adjust any SCSI data pointer in next data + * phase. */ - data->sg_list = pci_alloc_consistent(data->Pci, - (sizeof(struct nsp32_sgtable) * NSP_SG_SIZE * MAX_TARGET * MAX_LUN), - &data->sgaddr); - if (data->sg_list == NULL) { - nsp32_msg(KERN_ERR, "failed to allocate DMA memory"); - goto free_autoparam; - } + if (execph & MSGIN_02_VALID) { + nsp32_dbg(NSP32_DEBUG_BUSFREE, "MsgIn02_Valid"); - for (i=0; ilunt[i][j] = data->lunt_list + (i * MAX_LUN + j); - } - } + /* + * Check sack_cnt/saved_sack_cnt, then adjust sg table if + * needed. + */ + if (!(execph & MSGIN_00_VALID) && + ((execph & DATA_IN_PHASE) || (execph & DATA_OUT_PHASE))) { + unsigned int sacklen, s_sacklen; + + /* + * Read SACK count and SAVEDSACK count, then compare. + */ + sacklen = nsp32_read4(base, SACK_CNT ); + s_sacklen = nsp32_read4(base, SAVED_SACK_CNT); + + /* + * If SAVEDSACKCNT == 0, it means SavedDataPointer is + * come after data transfering. + */ + if (s_sacklen > 0) { + /* + * Comparing between sack and savedsack to + * check the condition of AutoMsgIn03. + * + * If they are same, set msgin03 == TRUE, + * COMMANDCONTROL_AUTO_MSGIN_03 is enabled at + * reselection. On the other hand, if they + * aren't same, set msgin03 == FALSE, and + * COMMANDCONTROL_AUTO_MSGIN_03 is disabled at + * reselection. + */ + if (sacklen != s_sacklen) { + data->cur_lunt->msgin03 = FALSE; + } else { + data->cur_lunt->msgin03 = TRUE; + } - for (i=0; ilunt[i][j]; - lp->sglun = (struct nsp32_sglun *) - (data->sg_list + (i * MAX_LUN + j)); - lp->sglun_paddr = data->sgaddr + - (long)((i * MAX_LUN + j) - * sizeof(struct nsp32_sglun)); - lp->SCpnt = NULL; - lp->save_datp = 0; - lp->msgin03 = FALSE; - lp->sg_num = 0; - lp->cur_entry = 0; + nsp32_adjust_busfree(SCpnt, s_sacklen); + } } + + /* This value has not substitude with valid value yet... */ + //data->cur_lunt->save_datp = data->cur_datp; + } else { + /* + * no processing. + */ + } + + if (execph & MSGIN_03_VALID) { + /* MsgIn03 was valid to be processed. No need processing. */ } /* - * setup target + * target SDTR check */ - for (i=0; itarget[i]; - - target->limit_entry = 0; - target->sync_flag = 0; - nsp32_set_async(data, target); + if (data->cur_target->sync_flag & SDTR_INITIATOR) { + /* + * SDTR negotiation pulled by the initiator has not + * finished yet. Fall back to ASYNC mode. + */ + nsp32_set_async(data, data->cur_target); + data->cur_target->sync_flag &= ~SDTR_INITIATOR; + data->cur_target->sync_flag |= SDTR_DONE; + } else if (data->cur_target->sync_flag & SDTR_TARGET) { + /* + * SDTR negotiation pulled by the target has been + * negotiating. + */ + if (execph & (MSGIN_00_VALID | MSGIN_04_VALID)) { + /* + * If valid message is received, then + * negotiation is succeeded. + */ + } else { + /* + * On the contrary, if unexpected bus free is + * occurred, then negotiation is failed. Fall + * back to ASYNC mode. + */ + nsp32_set_async(data, data->cur_target); + } + data->cur_target->sync_flag &= ~SDTR_TARGET; + data->cur_target->sync_flag |= SDTR_DONE; } /* - * EEPROM check + * It is always ensured by SCSI standard that initiator + * switches into Bus Free Phase after + * receiving message 00 (Command Complete), 04 (Disconnect). + * It's the reason that processing here is valid. */ - ret = nsp32_getprom_param(data); - if (ret == FALSE) { - data->resettime = 3; /* default 3 */ + if (execph & MSGIN_00_VALID) { + /* MsgIn 00: Command Complete */ + nsp32_dbg(NSP32_DEBUG_BUSFREE, "command complete"); + + SCpnt->SCp.Status = nsp32_read1(base, SCSI_CSB_IN); + SCpnt->SCp.Message = 0; + nsp32_dbg(NSP32_DEBUG_BUSFREE, + "normal end stat=0x%x resid=0x%x\n", + SCpnt->SCp.Status, SCpnt->resid); + SCpnt->result = (DID_OK << 16) | + (SCpnt->SCp.Message << 8) | + (SCpnt->SCp.Status << 0); + nsp32_scsi_done(SCpnt); + /* All operation is done */ + return TRUE; + } else if (execph & MSGIN_04_VALID) { + /* MsgIn 04: Disconnect */ + SCpnt->SCp.Status = nsp32_read1(base, SCSI_CSB_IN); + SCpnt->SCp.Message = 4; + + nsp32_dbg(NSP32_DEBUG_BUSFREE, "disconnect"); + return TRUE; + } else { + /* Unexpected bus free */ + nsp32_msg(KERN_WARNING, "unexpected bus free occurred"); + + /* DID_ERROR? */ + //SCpnt->result = (DID_OK << 16) | (SCpnt->SCp.Message << 8) | (SCpnt->SCp.Status << 0); + SCpnt->result = DID_ERROR << 16; + nsp32_scsi_done(SCpnt); + return TRUE; } + return FALSE; +} - /* - * setup HBA - */ - nsp32hw_init(host); - snprintf(data->info_str, sizeof(data->info_str), - "NinjaSCSI-32Bi/UDE: irq %d, io 0x%lx+0x%x", - host->irq, host->io_port, host->n_io_port); +/* + * nsp32_adjust_busfree - adjusting SG table + * + * Note: This driver adjust the SG table using SCSI ACK + * counter instead of BMCNT counter! + */ +static void nsp32_adjust_busfree(Scsi_Cmnd *SCpnt, unsigned int s_sacklen) +{ + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; + int old_entry = data->cur_entry; + int new_entry; + int sg_num = data->cur_lunt->sg_num; + nsp32_sgtable *sgt = data->cur_lunt->sglun->sgt; + unsigned int restlen, sentlen; + u32 len, addr; - sht->name = data->info_str; + nsp32_dbg(NSP32_DEBUG_SGLIST, "old resid=0x%x", SCpnt->resid); + + /* adjust saved SACK count with 4 byte start address boundary */ + s_sacklen -= le32_to_cpu(sgt[old_entry].addr) & 3; /* - * SCSI bus reset - * - * Note: It's important to reset SCSI bus in initialization phase. - * NinjaSCSI-32Bi/UDE HBA EEPROM seems to exchange SDTR when system is - * coming up, so SCSI devices connected to HBA is set as - * un-asynchronous mode. It brings the merit that this HBA is - * ready to start synchronous transfer without any preparation, - * but we are difficult to control transfer speed. In addition, - * it prevents device transfer speed from effecting EEPROM start-up - * SDTR. NinjaSCSI-32Bi/UDE has the feature if EEPROM is set as Auto - * Mode, then FAST-10M is selected when SCSI devices are connected - * same or more than 4 devices. It should be avoided depending on - * this specification Thus, resetting the SCSI bus restores all - * connected SCSI devices to asynchronous mode, then this driver - * put SDTR safely later, and we can control all SCSI device - * transfer mode. + * calculate new_entry from sack count and each sgt[].len + * calculate the byte which is intent to send */ - nsp32_do_bus_reset(data); + sentlen = 0; + for (new_entry = old_entry; new_entry < sg_num; new_entry++) { + sentlen += (le32_to_cpu(sgt[new_entry].len) & ~SGTEND); + if (sentlen > s_sacklen) { + break; + } + } - ret = request_irq(host->irq, do_nsp32_isr, SA_SHIRQ, "nsp32", data); - if (ret < 0) { - nsp32_msg(KERN_ERR, "Unable to allocate IRQ for NSP32 " - "SCSI PCI controller. Interrupt: %d\n", host->irq); - goto free_sg_list; + /* all sgt is processed */ + if (new_entry == sg_num) { + goto last; } - /* - * PCI IO register - */ - if(!request_region(host->io_port, host->n_io_port, "nsp32")) { - nsp32_msg(KERN_ERR, - "I/O region 0x%lx+0x%lx is already used", - data->BaseAddress, data->length); - goto free_irq; - } + if (sentlen == s_sacklen) { + /* XXX: confirm it's ok or not */ + /* In this case, it's ok because we are at + the head element of the sg. restlen is correctly calculated. */ + } - return 1; + /* calculate the rest length for transfering */ + restlen = sentlen - s_sacklen; - free_irq: - free_irq(host->irq, data); - - free_autoparam: - pci_free_consistent(data->Pci, AUTOPARAM_SIZE, data->autoparam, data->apaddr); - - free_sg_list: - pci_free_consistent(data->Pci, - (sizeof(struct nsp32_sgtable) * NSP_SG_SIZE * MAX_TARGET * MAX_LUN), - data->sg_list, data->sgaddr); - - kfree_lunt: - kfree(data->lunt_list); - - scsi_unregister: - scsi_unregister(host); - - err: - return 0; -} - -static int nsp32_release(struct Scsi_Host *shpnt) -{ - nsp32_hw_data *data = (nsp32_hw_data *)shpnt->hostdata; - - if (data->lunt_list) { - kfree(data->lunt_list); - } - - if (data->autoparam) { - pci_free_consistent(data->Pci, AUTOPARAM_SIZE, - data->autoparam, data->apaddr); - } - - if (data->sg_list) { - pci_free_consistent(data->Pci, - (sizeof(struct nsp32_sgtable) * NSP_SG_SIZE * MAX_TARGET * MAX_LUN), - data->sg_list, data->sgaddr); - } - - DEBUG(0, "free irq\n"); - if (shpnt->irq) { - free_irq(shpnt->irq, data); - } + /* update adjusting current SG table entry */ + len = le32_to_cpu(sgt[new_entry].len); + addr = le32_to_cpu(sgt[new_entry].addr); + addr += (len - restlen); + sgt[new_entry].addr = cpu_to_le32(addr); + sgt[new_entry].len = cpu_to_le32(restlen); - DEBUG(0, "free io\n"); - if (shpnt->io_port && shpnt->n_io_port) { - release_region(shpnt->io_port, shpnt->n_io_port); - } + /* set cur_entry with new_entry */ + data->cur_entry = new_entry; + + return; - if (data->MmioAddress != 0) { - iounmap((void *)(data->MmioAddress)); + last: + if (SCpnt->resid < sentlen) { + nsp32_msg(KERN_ERR, "resid underflow"); } - return 0; -} + SCpnt->resid -= sentlen; + nsp32_dbg(NSP32_DEBUG_SGLIST, "new resid=0x%x", SCpnt->resid); -static const char *nsp32_info(struct Scsi_Host *shpnt) -{ - nsp32_hw_data *data = (nsp32_hw_data *)shpnt->hostdata; + /* update hostdata and lun */ - return data->info_str; + return; } /* - * error handler + * It's called MsgOut phase occur. + * NinjaSCSI-32Bi/UDE automatically processes up to 3 messages in + * message out phase. It, however, has more than 3 messages, + * HBA creates the interrupt and we have to process by hand. */ -static int nsp32_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags) +static void nsp32_msgout_occur(Scsi_Cmnd *SCpnt) { - nsp32_dbg(NSP32_DEBUG_BUSRESET, "SCpnt=0x%p why=%d\n", SCpnt, reset_flags); + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; + unsigned int base = SCpnt->device->host->io_port; + //unsigned short command; + long new_sgtp; + int i; + + nsp32_dbg(NSP32_DEBUG_MSGOUTOCCUR, + "enter: msgout_len: 0x%x", data->msgout_len); - nsp32_eh_bus_reset(SCpnt); + /* + * If MsgOut phase is occurred without having any + * message, then No_Operation is sent (SCSI-2). + */ + if (data->msgout_len == 0) { + nsp32_build_nop(SCpnt); + } - return SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET; -} + /* + * Set SGTP ADDR current entry for restarting AUTOSCSI, + * because SGTP is incremented next point. + * There is few statement in the specification... + */ + new_sgtp = data->cur_lunt->sglun_paddr + + (data->cur_lunt->cur_entry * sizeof(nsp32_sgtable)); -static int nsp32_eh_abort(Scsi_Cmnd *SCpnt) -{ - nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->host->hostdata; - unsigned int base = data->BaseAddress; + /* + * send messages + */ + for (i = 0; i < data->msgout_len; i++) { + nsp32_dbg(NSP32_DEBUG_MSGOUTOCCUR, + "%d : 0x%x", i, data->msgoutbuf[i]); - nsp32_msg(KERN_WARNING, "abort"); + /* + * Check REQ is asserted. + */ + nsp32_wait_req(data, ASSERT); - if (data->curlunt->SCpnt == NULL) { - return (FAILED); - } + if (i == (data->msgout_len - 1)) { + /* + * If the last message, set the AutoSCSI restart + * before send back the ack message. AutoSCSI + * restart automatically negate ATN signal. + */ + //command = (AUTO_MSGIN_00_OR_04 | AUTO_MSGIN_02); + //nsp32_restart_autoscsi(SCpnt, command); + nsp32_write2(base, COMMAND_CONTROL, + (CLEAR_CDB_FIFO_POINTER | + AUTO_COMMAND_PHASE | + AUTOSCSI_RESTART | + AUTO_MSGIN_00_OR_04 | + AUTO_MSGIN_02 )); + } + /* + * Write data with SACK, then wait sack is + * automatically negated. + */ + nsp32_write1(base, SCSI_DATA_WITH_ACK, data->msgoutbuf[i]); + nsp32_wait_sack(data, NEGATE); - if (data->curtarget->sync_flag & (SDTR_INITIATOR | SDTR_TARGET)) { - /* reset SDTR negotiation */ - data->curtarget->sync_flag = 0; - } + nsp32_dbg(NSP32_DEBUG_MSGOUTOCCUR, "bus: 0x%x\n", + nsp32_read1(base, SCSI_BUS_MONITOR)); + }; - nsp32_write2(base, TRANSFER_CONTROL, 0); - nsp32_write2(base, BM_CNT, 0); + data->msgout_len = 0; - return (FAILED); + nsp32_dbg(NSP32_DEBUG_MSGOUTOCCUR, "exit"); } -static int nsp32_eh_bus_reset(Scsi_Cmnd *SCpnt) +/* + * Restart AutoSCSI + * + * Note: Restarting AutoSCSI needs set: + * SYNC_REG, ACK_WIDTH, SGT_ADR, TRANSFER_CONTROL + */ +static void nsp32_restart_autoscsi(Scsi_Cmnd *SCpnt, unsigned short command) { - nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->host->hostdata; - unsigned int base = data->BaseAddress; + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; + unsigned int base = data->BaseAddress; + unsigned short transfer = 0; - nsp32_msg(KERN_INFO, "Bus Reset"); - nsp32_dbg(NSP32_DEBUG_BUSRESET, "SCpnt=0x%x", SCpnt); + nsp32_dbg(NSP32_DEBUG_RESTART, "enter"); - nsp32_write2(base, IRQ_CONTROL, IRQ_CONTROL_ALL_IRQ_MASK); - nsp32_do_bus_reset(data); - nsp32_write2(base, IRQ_CONTROL, 0); + if (data->cur_target == NULL || data->cur_lunt == NULL) { + nsp32_msg(KERN_ERR, "Target or Lun is invalid"); + } - return SUCCESS; /* SCSI bus reset is succeeded at any time. */ -} + /* + * set SYNC_REG + * Don't set BM_START_ADR before setting this register. + */ + nsp32_write1(base, SYNC_REG, data->cur_target->syncreg); -static void nsp32_do_bus_reset(nsp32_hw_data *data) -{ - unsigned int base = data->BaseAddress; - unsigned short intrdat; - int i; + /* + * set ACKWIDTH + */ + nsp32_write1(base, ACK_WIDTH, data->cur_target->ackwidth); /* - * stop all transfer - * clear TRANSFERCONTROL_BM_START - * clear counter + * set SREQ hazard killer sampling rate */ - nsp32_write2(base, TRANSFER_CONTROL, 0); - nsp32_write4(base, BM_CNT, 0); - nsp32_write4(base, CLR_COUNTER, CLRCOUNTER_ALLMASK); + nsp32_write1(base, SREQ_SMPL_RATE, data->cur_target->sample_reg); /* - * fall back to asynchronous transfer mode - * initialize SDTR negotiation flag + * set SGT ADDR (physical address) */ - for (i=0; itarget[i]; + nsp32_write4(base, SGT_ADR, data->cur_lunt->sglun_paddr); - target->sync_flag = 0; - nsp32_set_async(data, target); + /* + * set TRANSFER CONTROL REG + */ + transfer = 0; + transfer |= (TRANSFER_GO | ALL_COUNTER_CLR); + if (data->trans_method & NSP32_TRANSFER_BUSMASTER) { + if (SCpnt->request_bufflen > 0) { + transfer |= BM_START; + } + } else if (data->trans_method & NSP32_TRANSFER_MMIO) { + transfer |= CB_MMIO_MODE; + } else if (data->trans_method & NSP32_TRANSFER_PIO) { + transfer |= CB_IO_MODE; } + nsp32_write2(base, TRANSFER_CONTROL, transfer); /* - * reset SCSI bus + * restart AutoSCSI + * + * TODO: COMMANDCONTROL_AUTO_COMMAND_PHASE is needed ? */ - nsp32_write1(base, SCSI_BUS_CONTROL, BUSCTL_RST); - udelay(RESET_HOLD_TIME); - nsp32_write1(base, SCSI_BUS_CONTROL, 0); - for(i = 0; i < 5; i++) { - intrdat = nsp32_read2(base, IRQ_STATUS); /* dummy read */ - nsp32_dbg(NSP32_DEBUG_BUSRESET, "irq:1: 0x%x", intrdat); - } + command |= (CLEAR_CDB_FIFO_POINTER | + AUTO_COMMAND_PHASE | + AUTOSCSI_RESTART ); + nsp32_write2(base, COMMAND_CONTROL, command); - data->CurrentSC = NULL; + nsp32_dbg(NSP32_DEBUG_RESTART, "exit"); } -static int nsp32_eh_host_reset(Scsi_Cmnd *SCpnt) -{ - struct Scsi_Host *host = SCpnt->host; - nsp32_hw_data *data = (nsp32_hw_data *)host->hostdata; - unsigned int base = data->BaseAddress; - - nsp32_msg(KERN_INFO, "Host Reset"); - nsp32_dbg(NSP32_DEBUG_BUSRESET, "SCpnt=0x%x", SCpnt); - - nsp32hw_init(host); - nsp32_write2(base, IRQ_CONTROL, IRQ_CONTROL_ALL_IRQ_MASK); - nsp32_do_bus_reset(data); - nsp32_write2(base, IRQ_CONTROL, 0); - - return SUCCESS; /* Host reset is succeeded at any time. */ -} /* - * PCI/Cardbus probe/remove routine + * cannot run automatically message in occur */ -static int __devinit nsp32_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ - int ret; - nsp32_hw_data *data = &nsp32_data_base; - - nsp32_dbg(NSP32_DEBUG_REGISTER, "enter"); +static void nsp32_msgin_occur(Scsi_Cmnd *SCpnt, + unsigned long irq_status, + unsigned short execph) +{ + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; + unsigned int base = SCpnt->device->host->io_port; + unsigned char msg; + unsigned char msgtype; + unsigned char newlun; + unsigned short command = 0; + int msgclear = TRUE; + long new_sgtp; + int ret; - ret = pci_enable_device(pdev); - if (ret) { - nsp32_msg(KERN_ERR, "failed to enable pci device"); - return ret; - } + /* + * read first message + * Use SCSIDATA_W_ACK instead of SCSIDATAIN, because the procedure + * of Message-In have to be processed before sending back SCSI ACK. + */ + msg = nsp32_read1(base, SCSI_DATA_IN); + data->msginbuf[(unsigned char)data->msgin_len] = msg; + msgtype = data->msginbuf[0]; + nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, + "enter: msglen: 0x%x msgin: 0x%x msgtype: 0x%x", + data->msgin_len, msg, msgtype); - data->Pci = pdev; - data->pci_devid = id; - data->IrqNumber = pdev->irq; - data->BaseAddress = pci_resource_start(pdev, 0); - data->NumAddress = pci_resource_len(pdev, 0); - data->MmioAddress = (unsigned long)ioremap_nocache( - pci_resource_start(pdev, 1), pci_resource_len(pdev, 1)); + /* + * TODO: We need checking whether bus phase is message in? + */ - pci_set_master(pdev); + /* + * assert SCSI ACK + */ + nsp32_sack_assert(data); -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)) - scsi_register_host(&driver_template); -#else - scsi_register_module(MODULE_SCSI_HA, &driver_template); -#endif + /* + * processing IDENTIFY + */ + if (msgtype & 0x80) { + if (!(irq_status & IRQSTATUS_RESELECT_OCCUER)) { + /* Invalid (non reselect) phase */ + goto reject; + } - nsp32_msg(KERN_INFO, "nsp32 irq: %i mmio: 0x%lx slot: %s model: %s", - pdev->irq, data->MmioAddress, pdev->slot_name, - nsp32_model[id->driver_data]); + newlun = msgtype & 0x1f; /* TODO: SPI-3 compliant? */ + ret = nsp32_reselection(SCpnt, newlun); + if (ret == TRUE) { + goto restart; + } else { + goto reject; + } + } + + /* + * processing messages except for IDENTIFY + * + * TODO: Messages are all SCSI-2 terminology. SCSI-3 compliance is TODO. + */ + switch (msgtype) { + /* + * 1-byte message + */ + case COMMAND_COMPLETE: + case DISCONNECT: + /* + * These messages should not be occurred. + * They should be processed on AutoSCSI sequencer. + */ + nsp32_msg(KERN_WARNING, + "unexpected message of AutoSCSI MsgIn: 0x%x", msg); + break; + + case RESTORE_POINTERS: + /* + * AutoMsgIn03 is disabled, and HBA gets this message. + */ - nsp32_dbg(NSP32_DEBUG_REGISTER, "exit"); + if ((execph & DATA_IN_PHASE) || (execph & DATA_OUT_PHASE)) { + unsigned int s_sacklen; - return 0; -} + s_sacklen = nsp32_read4(base, SAVED_SACK_CNT); + if ((execph & MSGIN_02_VALID) && (s_sacklen > 0)) { + nsp32_adjust_busfree(SCpnt, s_sacklen); + } else { + /* No need to rewrite SGT */ + } + } + data->cur_lunt->msgin03 = FALSE; -static void __devexit nsp32_remove(struct pci_dev *pdev) -{ - nsp32_dbg(NSP32_DEBUG_REGISTER, "enter"); - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)) - scsi_unregister_host(&driver_template); -#else - scsi_unregister_module(MODULE_SCSI_HA, &driver_template); -#endif -} + /* Update with the new value */ -static struct pci_device_id nsp32_pci_table[] __devinitdata = { - { - vendor: PCI_VENDOR_ID_IODATA, - device: PCI_DEVICE_ID_NINJASCSI_32BI_CBSC_II, - subvendor: PCI_ANY_ID, - subdevice: PCI_ANY_ID, - driver_data: MODEL_IODATA, - }, - { - vendor: PCI_VENDOR_ID_WORKBIT, - device: PCI_DEVICE_ID_NINJASCSI_32BI_KME, - subvendor: PCI_ANY_ID, - subdevice: PCI_ANY_ID, - driver_data: MODEL_KME, - }, - { - vendor: PCI_VENDOR_ID_WORKBIT, - device: PCI_DEVICE_ID_NINJASCSI_32BI_WBT, - subvendor: PCI_ANY_ID, - subdevice: PCI_ANY_ID, - driver_data: MODEL_WORKBIT, - }, - { - vendor: PCI_VENDOR_ID_WORKBIT, - device: PCI_DEVICE_ID_WORKBIT_STANDARD, - subvendor: PCI_ANY_ID, - subdevice: PCI_ANY_ID, - driver_data: MODEL_PCI_WORKBIT, - }, - { - vendor: PCI_VENDOR_ID_WORKBIT, - device: PCI_DEVICE_ID_NINJASCSI_32BI_LOGITEC, - subvendor: PCI_ANY_ID, - subdevice: PCI_ANY_ID, - driver_data: MODEL_EXT_ROM, - }, - { - vendor: PCI_VENDOR_ID_WORKBIT, - device: PCI_DEVICE_ID_NINJASCSI_32BIB_LOGITEC, - subvendor: PCI_ANY_ID, - subdevice: PCI_ANY_ID, - driver_data: MODEL_PCI_LOGITEC, - }, - { - vendor: PCI_VENDOR_ID_WORKBIT, - device: PCI_DEVICE_ID_NINJASCSI_32UDE_MELCO, - subvendor: PCI_ANY_ID, - subdevice: PCI_ANY_ID, - driver_data: MODEL_PCI_MELCO, - }, - {0,0,}, -}; -MODULE_DEVICE_TABLE(pci, nsp32_pci_table); + /* reset SACK/SavedACK counter (or ALL clear?) */ + nsp32_write4(base, CLR_COUNTER, CLRCOUNTER_ALLMASK); -static struct pci_driver nsp32_driver = { - .name = "nsp32", - .id_table = nsp32_pci_table, - .probe = nsp32_probe, - .remove = __devexit_p(nsp32_remove), -#ifdef CONFIG_PM -/* .suspend = nsp32_suspend,*/ -/* .resume = nsp32_resume,*/ -#endif -}; + /* + * set new sg pointer + */ + new_sgtp = data->cur_lunt->sglun_paddr + + (data->cur_lunt->cur_entry * sizeof(nsp32_sgtable)); + nsp32_write4(base, SGT_ADR, new_sgtp); -static int __init init_nsp32(void) { - return pci_module_init(&nsp32_driver); -} + break; -static void __exit exit_nsp32(void) { - pci_unregister_driver(&nsp32_driver); -} + case SAVE_POINTERS: + /* + * These messages should not be occurred. + * They should be processed on AutoSCSI sequencer. + */ + nsp32_msg (KERN_WARNING, + "unexpected message of AutoSCSI MsgIn: SAVE_POINTERS"); + + break; + + case MESSAGE_REJECT: + /* If previous message_out is sending SDTR, and get + message_reject from target, SDTR negotiation is failed */ + if (data->cur_target->sync_flag & + (SDTR_INITIATOR | SDTR_TARGET)) { + /* + * Current target is negotiating SDTR, but it's + * failed. Fall back to async transfer mode, and set + * SDTR_DONE. + */ + nsp32_set_async(data, data->cur_target); + data->cur_target->sync_flag &= ~SDTR_INITIATOR; + data->cur_target->sync_flag |= SDTR_DONE; -module_init(init_nsp32); -module_exit(exit_nsp32); + } + break; + case LINKED_CMD_COMPLETE: + case LINKED_FLG_CMD_COMPLETE: + /* queue tag is not supported currently */ + nsp32_msg (KERN_WARNING, + "unsupported message: 0x%x", msgtype); + break; -/* - * Reset parameters and call scsi_done for data->curlunt. - * Be careful setting SCpnt->result = DID_* before calling this function. - */ -static void nsp32_scsi_done(nsp32_hw_data *data, Scsi_Cmnd *SCpnt) -{ - unsigned int base = data->BaseAddress; + case INITIATE_RECOVERY: + /* staring ECA (Extended Contingent Allegiance) state. */ + /* This message is declined in SPI2 or later. */ + + goto reject; /* - * unmap pci + * 2-byte message */ - if (SCpnt->request_bufflen == 0) { - goto skip; + case SIMPLE_QUEUE_TAG: + case 0x23: + /* + * 0x23: Ignore_Wide_Residue is not declared in scsi.h. + * No support is needed. + */ + if (data->msgin_len >= 1) { + goto reject; + } + + /* current position is 1-byte of 2 byte */ + msgclear = FALSE; + + break; + + /* + * extended message + */ + case EXTENDED_MESSAGE: + if (data->msgin_len < 1) { + /* + * Current position does not reach 2-byte + * (2-byte is extended message length). + */ + msgclear = FALSE; + break; + } + + if ((data->msginbuf[1] + 1) > data->msgin_len) { + /* + * Current extended message has msginbuf[1] + 2 + * (msgin_len starts counting from 0, so buf[1] + 1). + * If current message position is not finished, + * continue receiving message. + */ + msgclear = FALSE; + break; + } + + /* + * Reach here means regular length of each type of + * extended messages. + */ + switch (data->msginbuf[2]) { + case EXTENDED_MODIFY_DATA_POINTER: + /* TODO */ + goto reject; /* not implemented yet */ + break; + + case EXTENDED_SDTR: + /* + * Exchange this message between initiator and target. + */ + if (data->msgin_len != EXTENDED_SDTR_LEN + 1) { + /* + * received inappropriate message. + */ + goto reject; + break; + } + + nsp32_analyze_sdtr(SCpnt); + + break; + + case EXTENDED_EXTENDED_IDENTIFY: + /* SCSI-I only, not supported. */ + goto reject; /* not implemented yet */ + + break; + + case EXTENDED_WDTR: + goto reject; /* not implemented yet */ + + break; + + default: + goto reject; + } + break; + + default: + goto reject; } - if (SCpnt->use_sg) { - pci_unmap_sg(data->Pci, - (struct scatterlist *)SCpnt->buffer, - SCpnt->use_sg, - scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); + restart: + if (msgclear == TRUE) { + data->msgin_len = 0; + + /* + * If restarting AutoSCSI, but there are some message to out + * (msgout_len > 0), set AutoATN, and set SCSIMSGOUT as 0 + * (MSGOUT_VALID = 0). When commandcontrol is written with + * AutoSCSI restart, at the same time MsgOutOccur should be + * happened (however, such situation is really possible...?). + */ + if (data->msgout_len > 0) { + nsp32_write4(base, SCSI_MSG_OUT, 0); + command |= AUTO_ATN; + } + + /* + * restart AutoSCSI + * If it's failed, COMMANDCONTROL_AUTO_COMMAND_PHASE is needed. + */ + command |= (AUTO_MSGIN_00_OR_04 | AUTO_MSGIN_02); + + /* + * If current msgin03 is TRUE, then flag on. + */ + if (data->cur_lunt->msgin03 == TRUE) { + command |= AUTO_MSGIN_03; + } + data->cur_lunt->msgin03 = FALSE; } else { - pci_unmap_single(data->Pci, - (u32)SCpnt->SCp.have_data_in, - SCpnt->request_bufflen, - scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); + data->msgin_len++; } - skip: /* - * clear TRANSFERCONTROL_BM_START + * restart AutoSCSI */ - nsp32_write2(base, TRANSFER_CONTROL, 0); - nsp32_write4(base, BM_CNT, 0); + nsp32_restart_autoscsi(SCpnt, command); /* - * call scsi_done + * wait SCSI REQ negate for REQ-ACK handshake */ - (*SCpnt->scsi_done)(SCpnt); + nsp32_wait_req(data, NEGATE); /* - * reset parameters + * negate SCSI ACK */ - data->curlunt->SCpnt = NULL; - data->curlunt = NULL; - data->curtarget = NULL; - data->CurrentSC = NULL; -} + nsp32_sack_negate(data); + + nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "exit"); + + return; + + reject: + nsp32_msg(KERN_WARNING, + "invalid or unsupported MessageIn, rejected. " + "current msg: 0x%x (len: 0x%x), processing msg: 0x%x", + msg, data->msgin_len, msgtype); + nsp32_build_reject(SCpnt); + data->msgin_len = 0; + goto restart; +} /* - * Bus Free Occur - * - * Current Phase is BUSFREE. AutoSCSI is automatically execute BUSFREE phase - * with ACK reply when below condition is matched: - * MsgIn 00: Command Complete. - * MsgIn 02: Save Data Pointer. - * MsgIn 04: Diconnect. - * In other case, unexpected BUSFREE is detected. + * */ -static int nsp32_busfree_occur(nsp32_hw_data *data, unsigned short execph) +static void nsp32_analyze_sdtr(Scsi_Cmnd *SCpnt) { - Scsi_Cmnd *SCpnt = data->curlunt->SCpnt; - unsigned int base = data->BaseAddress; + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; + nsp32_target *target = data->cur_target; + nsp32_sync_table *synct; + unsigned char get_period = data->msginbuf[3]; + unsigned char get_offset = data->msginbuf[4]; + int entry; + int syncnum; - nsp32_dbg(NSP32_DEBUG_BUSFREE, "enter"); + nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "enter"); - nsp32_write4(base, BM_CNT, 0); - nsp32_write2(base, TRANSFER_CONTROL, 0); + synct = data->synct; + syncnum = data->syncnum; /* - * MsgIn 02: Save Data Pointer - * - * VALID: - * Save Data Pointer is received. Adjust pointer. - * - * NO-VALID: - * SCSI-3 says if Save Data Pointer is not received, then we restart - * processing and we can't adjust any SCSI data pointer in next data - * phase. - */ - if (execph & MSGIN_02_VALID) { - nsp32_dbg(NSP32_DEBUG_BUSFREE, "MsgIn02_Valid"); - + * If this inititor sent the SDTR message, then target responds SDTR, + * initiator SYNCREG, ACKWIDTH from SDTR parameter. + * Messages are not appropriate, then send back reject message. + * If initiator did not send the SDTR, but target sends SDTR, + * initiator calculator the appropriate parameter and send back SDTR. + */ + if (target->sync_flag & SDTR_INITIATOR) { /* - * Check sack_cnt/saved_sack_cnt, then adjust sg table if - * needed. + * Initiator sent SDTR, the target responds and + * send back negotiation SDTR. */ - if (!(execph & MSGIN_00_VALID) && - ((execph & DATA_IN_PHASE) || (execph & DATA_OUT_PHASE))) { - unsigned int sacklen, s_sacklen; + nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "target responds SDTR"); + + target->sync_flag &= ~SDTR_INITIATOR; + target->sync_flag |= SDTR_DONE; + /* + * offset: + */ + if (get_offset > MAX_OFFSET) { /* - * Read SACK count and SAVEDSACK count, then compare. + * Negotiation is failed, the target send back + * unexpected offset value. */ - sacklen = nsp32_read4(base, SACK_CNT); - s_sacklen = nsp32_read4(base, SAVED_SACK_CNT); + goto reject; + } + + if (get_offset == ASYNC_OFFSET) { + /* + * Negotiation is succeeded, the target want + * to fall back into asynchronous transfer mode. + */ + goto async; + } + /* + * period: + * Check whether sync period is too short. If too short, + * fall back to async mode. If it's ok, then investigate + * the received sync period. If sync period is acceptable + * between sync table start_period and end_period, then + * set this I_T nexus as sent offset and period. + * If it's not acceptable, send back reject and fall back + * to async mode. + */ + if (get_period < data->synct[0].period_num) { /* - * If SAVEDSACKCNT == 0, it means SavedDataPointer is - * come after data transfering. + * Negotiation is failed, the target send back + * unexpected period value. */ - if (s_sacklen > 0) { - /* - * Comparing between sack and savedsack to - * check the condition of AutoMsgIn03. - * - * If they are same, set msgin03 == TRUE, - * COMMANDCONTROL_AUTO_MSGIN_03 is enabled at - * reselection. On the other hand, if they - * aren't same, set msgin03 == FALSE, and - * COMMANDCONTROL_AUTO_MSGIN_03 is disabled at - * reselection. - */ - if (sacklen != s_sacklen) { - data->curlunt->msgin03 = FALSE; - } else { - data->curlunt->msgin03 = TRUE; - } + goto reject; + } - nsp32_adjust_busfree(data, s_sacklen); - } + entry = nsp32_search_period_entry(data, target, get_period); + + if (entry < 0) { + /* + * Target want to use long period which is not + * acceptable NinjaSCSI-32Bi/UDE. + */ + goto reject; } - /* This value has not substitude with valid value yet... */ - //data->curlunt->save_datp = data->cur_datp; - } else { /* - * no processing. + * Set new sync table and offset in this I_T nexus. */ - } + nsp32_set_sync_entry(data, target, entry, get_offset); + } else { + /* Target send SDTR to initiator. */ + nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "target send SDTR"); - if (execph & MSGIN_03_VALID) { - /* MsgIn03 was valid to be processed. No need processing. */ - } + target->sync_flag |= SDTR_INITIATOR; - /* - * target SDTR check - */ - if (data->curtarget->sync_flag & SDTR_INITIATOR) { - /* - * SDTR negotiation pulled by the initiator has not - * finished yet. Fall back to ASYNC mode. - */ - nsp32_set_async(data, data->curtarget); - data->curtarget->sync_flag &= ~SDTR_INITIATOR; - data->curtarget->sync_flag |= SDTR_DONE; - } else if (data->curtarget->sync_flag & SDTR_TARGET) { - /* - * SDTR negotiation pulled by the target has been - * negotiating. - */ - if (execph & (MSGIN_00_VALID | MSGIN_04_VALID)) { - /* - * If valid message is received, then - * negotiation is succeeded. - */ + /* offset: */ + if (get_offset > MAX_OFFSET) { + /* send back as MAX_OFFSET */ + get_offset = MAX_OFFSET; + } + + /* period: */ + if (get_period < data->synct[0].period_num) { + get_period = data->synct[0].period_num; + } + + entry = nsp32_search_period_entry(data, target, get_period); + + if (get_offset == ASYNC_OFFSET || entry < 0) { + nsp32_set_async(data, target); + nsp32_build_sdtr(SCpnt, 0, ASYNC_OFFSET); } else { - /* - * On the contrary, if unexpected bus free is - * occured, then negotiation is failed. Fall - * back to ASYNC mode. - */ - nsp32_set_async(data, data->curtarget); + nsp32_set_sync_entry(data, target, entry, get_offset); + nsp32_build_sdtr(SCpnt, get_period, get_offset); } - data->curtarget->sync_flag &= ~SDTR_TARGET; - data->curtarget->sync_flag |= SDTR_DONE; } - + + target->period = get_period; + nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "exit"); + return; + + reject: /* - * It is always ensured by SCSI standard that initiator - * switches into Bus Free Phase after - * receiving message 00 (Command Complete), 04 (Disconnect). - * It's the reason that processing here is valid. + * If the current message is unacceptable, send back to the target + * with reject message. */ - if (execph & MSGIN_00_VALID) { - /* MsgIn 00: Command Complete */ - nsp32_dbg(NSP32_DEBUG_BUSFREE, "command complete"); + nsp32_build_reject(SCpnt); - SCpnt->SCp.Status = nsp32_read1(base, SCSI_CSB_IN); - SCpnt->SCp.Message = 0; - nsp32_dbg(NSP32_DEBUG_BUSFREE, - "normal end stat=0x%x resid=0x%x\n", - SCpnt->SCp.Status, SCpnt->resid); - SCpnt->result = - (DID_OK << 16) | (SCpnt->SCp.Message << 8) | (SCpnt->SCp.Status << 0); - nsp32_scsi_done(data, SCpnt); - /* All operation is done */ - return (TRUE); - } else if (execph & MSGIN_04_VALID) { - /* MsgIn 04: Disconnect */ - SCpnt->SCp.Status = nsp32_read1(base, SCSI_CSB_IN); - SCpnt->SCp.Message = 4; - - nsp32_dbg(NSP32_DEBUG_BUSFREE, "disconnect"); - return (TRUE); - } else { - /* Unexpected bus free */ - nsp32_msg(KERN_WARNING, "unexpected bus free occured"); + async: + nsp32_set_async(data, target); /* set as ASYNC transfer mode */ - /* DID_ERROR? */ - //SCpnt->result = (DID_OK << 16) | (SCpnt->SCp.Message << 8) | (SCpnt->SCp.Status << 0); - SCpnt->result = DID_ERROR << 16; - nsp32_scsi_done(data, SCpnt); - return (TRUE); - } - return (FALSE); + target->period = 0; + nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "exit: set async"); + return; } /* - * nsp32_adjust_busfree - adjusting SG table - * - * Note: This driver adjust the SG table using SCSI ACK - * counter instead of BMCNT counter! + * Search config entry number matched in sync_table from given + * target and speed period value. If failed to search, return negative value. */ -static void nsp32_adjust_busfree(nsp32_hw_data *data, unsigned int s_sacklen) +static int nsp32_search_period_entry(nsp32_hw_data *data, + nsp32_target *target, + unsigned char period) { - int old_entry = data->cur_entry; - int new_entry; - struct nsp32_sgtable *sgt = data->curlunt->sglun->sgt; - unsigned int restlen, sentlen; - int sg_num = data->curlunt->sg_num; + int i; - /* adjust saved SACK count with 4 byte start address boundary */ - s_sacklen -= sgt[old_entry].addr & 3; + if (target->limit_entry >= data->syncnum) { + nsp32_msg(KERN_ERR, "limit_entry exceeds syncnum!"); + target->limit_entry = 0; + } - /* - * calculate new_entry from sack count and each sgt[].len - * calculate the byte which is intent to send - */ - sentlen = 0; - for (new_entry = old_entry; new_entry < sg_num; new_entry++) { - sentlen += (sgt[new_entry].len & ~NSP32_SG_END_SGT); - if (sentlen > s_sacklen) { - break; + for (i = target->limit_entry; i < data->syncnum; i++) { + if (period >= data->synct[i].start_period && + period <= data->synct[i].end_period) { + break; } } - /* all sgt is processed */ - if (new_entry == sg_num) { - goto last; + /* + * Check given period value is over the sync_table value. + * If so, return max value. + */ + if (i == data->syncnum) { + i = -1; } - if (sentlen == s_sacklen) { - /* XXX: confirm it's ok or not */ - /* In this case, it's ok because we are at - the head element of the sg. restlen is correctly calculated. */ - } + return i; +} - /* calculate the rest length for transfering */ - restlen = sentlen - s_sacklen; - - /* update adjusting current SG table entry */ - sgt[new_entry].addr += (sgt[new_entry].len - restlen); - sgt[new_entry].len = restlen; - /* set cur_entry with new_entry */ - data->cur_entry = new_entry; - - return; +/* + * target <-> initiator use ASYNC transfer + */ +static void nsp32_set_async(nsp32_hw_data *data, nsp32_target *target) +{ + unsigned char period = data->synct[target->limit_entry].period_num; - last: - /* update hostdata and lun */ + target->offset = ASYNC_OFFSET; + target->period = 0; + target->syncreg = TO_SYNCREG(period, ASYNC_OFFSET); + target->ackwidth = 0; + target->sample_reg = 0; - return; + nsp32_dbg(NSP32_DEBUG_SYNC, "set async"); } /* - * It's called MsgOut phase occur. - * NinjaSCSI-32Bi/UDE automatically processes up to 3 messages in - * message out phase. It, however, has more than 3 messages, - * HBA creates the interrupt and we have to process by hand. + * target <-> initiator use maximum SYNC transfer */ -static void nsp32_msgout_occur(nsp32_hw_data *data) +static void nsp32_set_max_sync(nsp32_hw_data *data, + nsp32_target *target, + unsigned char *period, + unsigned char *offset) { - unsigned int base = data->BaseAddress; - //unsigned short command; - long new_sgtp; - int i; - - nsp32_dbg(NSP32_DEBUG_MSGOUTOCCUR, - "enter: msgoutlen: 0x%x", data->msgoutlen); + unsigned char period_num, ackwidth; - /* - * If MsgOut phase is occured without having any - * message, then No_Operation is sent (SCSI-2). - */ - if (data->msgoutlen == 0) { - nsp32_build_nop(data); - } + period_num = data->synct[target->limit_entry].period_num; + *period = data->synct[target->limit_entry].start_period; + ackwidth = data->synct[target->limit_entry].ackwidth; + *offset = MAX_OFFSET; - /* - * Set SGTP ADDR current entry for restarting AUTOSCSI, - * because SGTP is incremented next point. - * There is few statement in the specification... - */ - new_sgtp = data->curlunt->sglun_paddr - + data->curlunt->cur_entry * sizeof(struct nsp32_sgtable); + target->syncreg = TO_SYNCREG(period_num, *offset); + target->ackwidth = ackwidth; + target->offset = *offset; + target->sample_reg = 0; /* disable SREQ sampling */ +} - /* - * send messages - */ - for (i=0; imsgoutlen; i++) { - nsp32_dbg(NSP32_DEBUG_MSGOUTOCCUR, - "%d : 0x%x", i, data->msgoutbuf[i]); - /* - * Check REQ is asserted. - */ - nsp32_wait_req(data, ASSERT); +/* + * target <-> initiator use entry number speed + */ +static void nsp32_set_sync_entry(nsp32_hw_data *data, + nsp32_target *target, + int entry, + unsigned char offset) +{ + unsigned char period, ackwidth, sample_rate; + + period = data->synct[entry].period_num; + ackwidth = data->synct[entry].ackwidth; + offset = offset; + sample_rate = data->synct[entry].sample_rate; + + target->syncreg = TO_SYNCREG(period, offset); + target->ackwidth = ackwidth; + target->offset = offset; + target->sample_reg = sample_rate | SAMPLING_ENABLE; - if (i == (data->msgoutlen - 1)) { - /* - * If the last message, set the AutoSCSI restart - * before send back the ack message. AutoSCSI - * restart automatically negate ATN signal. - */ - //command = (AUTO_MSGIN_00_OR_04 | AUTO_MSGIN_02); - //nsp32_restart_autoscsi(data, command); - nsp32_write2(base, COMMAND_CONTROL, - (CLEAR_CDB_FIFO_POINTER | - AUTO_COMMAND_PHASE | - AUTOSCSI_RESTART | - AUTO_MSGIN_00_OR_04 | - AUTO_MSGIN_02 )); - } - /* - * Write data with SACK, then wait sack is - * automatically negated. - */ - nsp32_write1(base, SCSI_DATA_WITH_ACK, data->msgoutbuf[i]); - nsp32_wait_sack(data, NEGATE); - - nsp32_dbg(NSP32_DEBUG_MSGOUTOCCUR, "bus: 0x%x\n", - nsp32_read1(base, SCSI_BUS_MONITOR)); - }; - - data->msgoutlen = 0; - - nsp32_dbg(NSP32_DEBUG_MSGOUTOCCUR, "exit"); + nsp32_dbg(NSP32_DEBUG_SYNC, "set sync"); } + /* - * Restart AutoSCSI + * It waits until SCSI REQ becomes assertion or negation state. * - * Note: Restarting AutoSCSI needs set: - * SYNC_REG, ACK_WIDTH, SGT_ADR, TRANSFER_CONTROL + * Note: If nsp32_msgin_occur is called, we asserts SCSI ACK. Then + * connected target responds SCSI REQ negation. We have to wait + * SCSI REQ becomes negation in order to negate SCSI ACK signal for + * REQ-ACK handshake. */ -static void nsp32_restart_autoscsi(nsp32_hw_data *data, unsigned short command) +static void nsp32_wait_req(nsp32_hw_data *data, int state) { - unsigned int base = data->BaseAddress; - unsigned short transfer = 0; - Scsi_Cmnd *SCpnt = data->curlunt->SCpnt; + unsigned int base = data->BaseAddress; + int wait_time = 0; + unsigned char bus, req_bit; - nsp32_dbg(NSP32_DEBUG_RESTART, "enter"); - - if (data->curtarget == NULL || data->curlunt == NULL) { - nsp32_msg(KERN_ERR, "Target or Lun is invalid"); + if (!((state == ASSERT) || (state == NEGATE))) { + nsp32_msg(KERN_ERR, "unknown state designation"); } + /* REQ is BIT(5) */ + req_bit = (state == ASSERT ? BUSMON_REQ : 0); - /* - * set SYNC_REG - * Don't set BM_START_ADR before setting this register. - */ - nsp32_write1(base, SYNC_REG, data->curtarget->syncreg); - - /* - * set ACKWIDTH - */ - nsp32_write1(base, ACK_WIDTH, data->curtarget->ackwidth); - - /* - * set SGT ADDR (physical address) - */ - nsp32_write4(base, SGT_ADR, data->curlunt->sglun_paddr); - - /* - * set TRANSFER CONTROL REG - */ - transfer = 0; - transfer |= (TRANSFER_GO | ALL_COUNTER_CLR); - if (data->trans_method & NSP32_TRANSFER_BUSMASTER) { - if (SCpnt->request_bufflen > 0) { - transfer |= BM_START; + do { + bus = nsp32_read1(base, SCSI_BUS_MONITOR); + if ((bus & BUSMON_REQ) == req_bit) { + nsp32_dbg(NSP32_DEBUG_WAIT, + "wait_time: %d", wait_time); + return; } - } else if (data->trans_method & NSP32_TRANSFER_MMIO) { - transfer |= CB_MMIO_MODE; - } else if (data->trans_method & NSP32_TRANSFER_PIO) { - transfer |= CB_IO_MODE; - } - nsp32_write2(base, TRANSFER_CONTROL, transfer); - - /* - * restart AutoSCSI - * - * TODO: COMMANDCONTROL_AUTO_COMMAND_PHASE is needed ? - */ - command |= (CLEAR_CDB_FIFO_POINTER | - AUTO_COMMAND_PHASE | - AUTOSCSI_RESTART); - nsp32_write2(base, COMMAND_CONTROL, command); + udelay(1); + wait_time++; + } while (wait_time < REQSACK_TIMEOUT_TIME); - nsp32_dbg(NSP32_DEBUG_RESTART, "exit"); + nsp32_msg(KERN_WARNING, "wait REQ timeout, req_bit: 0x%x", req_bit); } - /* - * cannot run automatically message in occur + * It waits until SCSI SACK becomes assertion or negation state. */ -static void nsp32_msgin_occur(nsp32_hw_data *data, unsigned long irq_status, - unsigned short execph) +static void nsp32_wait_sack(nsp32_hw_data *data, int state) { - unsigned int base = data->BaseAddress; - unsigned char msg; - unsigned char msgtype; - unsigned char newlun; - unsigned short command = 0; - int msgclear = TRUE; - long new_sgtp; - int ret; + unsigned int base = data->BaseAddress; + int wait_time = 0; + unsigned char bus, ack_bit; - /* - * read first message - * Use SCSIDATA_W_ACK instead of SCSIDATAIN, because the procedure - * of Message-In have to be processed before sending back SCSI ACK. - */ - msg = nsp32_read1(base, SCSI_DATA_IN); - data->msginbuf[(unsigned char)data->msginlen] = msg; - msgtype = data->msginbuf[0]; - nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, - "enter: msglen: 0x%x msgin: 0x%x msgtype: 0x%x", - data->msginlen, msg, msgtype); - - /* - * TODO: We need checking whether bus phase is message in? - */ - - /* - * assert SCSI ACK - */ - nsp32_sack_assert(data); - - /* - * processing IDENTIFY - */ - if (msgtype & 0x80) { - if (!(irq_status & IRQSTATUS_RESELECT_OCCUER)) { - /* Invalid (non reselect) phase */ - goto reject; - } - - newlun = msgtype & 0x1f; /* TODO: SPI-3 compliant? */ - ret = nsp32_reselection(data, newlun); - if (ret == TRUE) { - goto restart; - } else { - goto reject; - } + if (!((state == ASSERT) || (state == NEGATE))) { + nsp32_msg(KERN_ERR, "unknown state designation"); } - - /* - * processing messages except for IDENTIFY - * - * TODO: Messages are all SCSI-2 terminology. SCSI-3 compliance is TODO. - */ - switch (msgtype) { - /* - * 1-byte message - */ - case COMMAND_COMPLETE: - case DISCONNECT: - /* - * These messages should not be occured. - * They should be processed on AutoSCSI sequencer. - */ - nsp32_msg(KERN_WARNING, - "unexpected message of AutoSCSI MsgIn: 0x%x", msg); - break; - - case RESTORE_POINTERS: - /* - * AutoMsgIn03 is disabled, and HBA gets this message. - */ + /* ACK is BIT(4) */ + ack_bit = (state == ASSERT ? BUSMON_ACK : 0); - if ((execph & DATA_IN_PHASE) || (execph & DATA_OUT_PHASE)) { - unsigned int s_sacklen; - - s_sacklen = nsp32_read4(base, SAVED_SACK_CNT); - if ((execph & MSGIN_02_VALID) && (s_sacklen > 0)) { - nsp32_adjust_busfree(data, s_sacklen); - } else { - /* No need to rewrite SGT */ - } + do { + bus = nsp32_read1(base, SCSI_BUS_MONITOR); + if ((bus & BUSMON_ACK) == ack_bit) { + nsp32_dbg(NSP32_DEBUG_WAIT, + "wait_time: %d", wait_time); + return; } - data->curlunt->msgin03 = FALSE; + udelay(1); + wait_time++; + } while (wait_time < REQSACK_TIMEOUT_TIME); - /* Update with the new value */ + nsp32_msg(KERN_WARNING, "wait SACK timeout, ack_bit: 0x%x", ack_bit); +} - /* reset SACK/SavedACK counter (or ALL clear?) */ - nsp32_write4(base, CLR_COUNTER, CLRCOUNTER_ALLMASK); +/* + * assert SCSI ACK + * + * Note: SCSI ACK assertion needs with ACKENB=1, AUTODIRECTION=1. + */ +static void nsp32_sack_assert(nsp32_hw_data *data) +{ + unsigned int base = data->BaseAddress; + unsigned char busctrl; - /* - * set new sg pointer - */ - new_sgtp = data->curlunt->sglun_paddr + - data->curlunt->cur_entry * sizeof(struct nsp32_sgtable); - nsp32_write4(base, SGT_ADR, new_sgtp); + busctrl = nsp32_read1(base, SCSI_BUS_CONTROL); + busctrl |= (BUSCTL_ACK | AUTODIRECTION | ACKENB); + nsp32_write1(base, SCSI_BUS_CONTROL, busctrl); +} - break; +/* + * negate SCSI ACK + */ +static void nsp32_sack_negate(nsp32_hw_data *data) +{ + unsigned int base = data->BaseAddress; + unsigned char busctrl; - case SAVE_POINTERS: - /* - * These messages should not be occured. - * They should be processed on AutoSCSI sequencer. - */ - nsp32_msg (KERN_WARNING, - "unexpected message of AutoSCSI MsgIn: SAVE_POINTERS"); - - break; - - case MESSAGE_REJECT: - /* If previous message_out is sending SDTR, and get - message_reject from target, SDTR negotiation is failed */ - if (data->curtarget->sync_flag & - (SDTR_INITIATOR | SDTR_TARGET)) { - /* - * Current target is negotiating SDTR, but it's - * failed. Fall back to async transfer mode, and set - * SDTR_DONE. - */ - nsp32_set_async(data, data->curtarget); - data->curtarget->sync_flag &= ~SDTR_INITIATOR; - data->curtarget->sync_flag |= SDTR_DONE; + busctrl = nsp32_read1(base, SCSI_BUS_CONTROL); + busctrl &= ~BUSCTL_ACK; + nsp32_write1(base, SCSI_BUS_CONTROL, busctrl); +} - } - break; - case LINKED_CMD_COMPLETE: - case LINKED_FLG_CMD_COMPLETE: - /* queue tag is not supported currently */ - nsp32_msg (KERN_WARNING, - "unsupported message: 0x%x", msgtype); - break; - case INITIATE_RECOVERY: - /* staring ECA (Extended Contingent Allegiance) state. */ - /* This message is declined in SPI2 or later. */ +/* + * Note: n_io_port is defined as 0x7f because I/O register port is + * assigned as: + * 0x800-0x8ff: memory mapped I/O port + * 0x900-0xbff: (map same 0x800-0x8ff I/O port image repeatedly) + * 0xc00-0xfff: CardBus status registers + */ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) +#define DETECT_OK 0 +#define DETECT_NG 1 +#define PCIDEV pdev +static int nsp32_detect(struct pci_dev *pdev) +#else +#define DETECT_OK 1 +#define DETECT_NG 0 +#define PCIDEV (data->Pci) +static int nsp32_detect(Scsi_Host_Template *sht) +#endif +{ + struct Scsi_Host *host; /* registered host structure */ + struct resource *res; + nsp32_hw_data *data; + int ret; + int n_target, n_lun, i; - goto reject; + nsp32_dbg(NSP32_DEBUG_REGISTER, "enter"); /* - * 2-byte message + * register this HBA as SCSI device */ - case SIMPLE_QUEUE_TAG: - case 0x23: - /* - * 0x23: Ignore_Wide_Residue is not declared in scsi.h. - * No support is needed. - */ - if (data->msginlen >= 1) { - goto reject; - } - - /* current position is 1-byte of 2 byte */ - msgclear = FALSE; - - break; +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) + host = scsi_host_alloc(&nsp32_template, sizeof(nsp32_hw_data)); +#else + host = scsi_register(sht, sizeof(nsp32_hw_data)); +#endif + if (host == NULL) { + nsp32_msg (KERN_ERR, "failed to scsi register"); + goto err; + } /* - * extended message + * set nsp32_hw_data */ - case EXTENDED_MESSAGE: - if (data->msginlen < 1) { - /* - * Current position does not reach 2-byte - * (2-byte is extended message length). - */ - msgclear = FALSE; - break; - } - - if ((data->msginbuf[1] + 1) > data->msginlen) { - /* - * Current extended message has msginbuf[1] + 2 - * (msginlen starts counting from 0, so buf[1] + 1). - * If current message position is not finished, - * continue receiving message. - */ - msgclear = FALSE; - break; - } - - /* - * Reach here means regular length of each type of - * extended messages. - */ - switch (data->msginbuf[2]) { - case EXTENDED_MODIFY_DATA_POINTER: - /* TODO */ - goto reject; /* not implemented yet */ - break; - - case EXTENDED_SDTR: - /* - * Exchange this message between initiator and target. - */ - if (data->msginlen != EXTENDED_SDTR_LEN + 1) { - /* - * received inappropriate message. - */ - goto reject; - break; - } - - nsp32_analyze_sdtr(data); - - break; - - case EXTENDED_EXTENDED_IDENTIFY: - /* SCSI-I only, not supported. */ - goto reject; /* not implemented yet */ - - break; - - case EXTENDED_WDTR: - goto reject; /* not implemented yet */ - - break; - - default: - goto reject; - } - break; - - default: - goto reject; - } - - restart: - if (msgclear == TRUE) { - data->msginlen = 0; - - /* - * If restarting AutoSCSI, but there are some message to out - * (msgoutlen > 0), set AutoATN, and set SCSIMSGOUT as 0 - * (MV_VALID = 0). When commandcontrol is written with - * AutoSCSI restart, at the same time MsgOutOccur should be - * happened (however, such situation is really possible...?). - */ - if (data->msgoutlen > 0) { - nsp32_write4(base, SCSI_MSG_OUT, 0); - command |= AUTO_ATN; - } + data = (nsp32_hw_data *)host->hostdata; - /* - * restart AutoSCSI - * If it's failed, COMMANDCONTROL_AUTO_COMMAND_PHASE is needed. - */ - command |= (AUTO_MSGIN_00_OR_04 | AUTO_MSGIN_02); + *data = nsp32_data_base; - /* - * If current msgin03 is TRUE, then flag on. - */ - if (data->curlunt->msgin03 == TRUE) { - command |= AUTO_MSGIN_03; - } - data->curlunt->msgin03 = FALSE; - } else { - data->msginlen++; - } + host->irq = data->IrqNumber; + host->io_port = data->BaseAddress; + host->unique_id = data->BaseAddress; + host->n_io_port = data->NumAddress; + host->base = data->MmioAddress; +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,63)) + scsi_set_device(host, &PCIDEV->dev); +#else + scsi_set_pci_device(host, PCIDEV); +#endif + + data->Host = host; + spin_lock_init(&(data->Lock)); + + data->cur_lunt = NULL; + data->cur_target = NULL; /* - * restart AutoSCSI + * Bus master transfer mode is supported currently. */ - nsp32_restart_autoscsi(data, command); + data->trans_method = NSP32_TRANSFER_BUSMASTER; /* - * wait SCSI REQ negate for REQ-ACK handshake + * Set clock div, CLOCK_4 (HBA has own external clock, and + * dividing * 100ns/4). + * Currently CLOCK_4 has only tested, not for CLOCK_2/PCICLK yet. */ - nsp32_wait_req(data, NEGATE); + data->clock = CLOCK_4; /* - * negate SCSI ACK + * Select appropriate nsp32_sync_table and set I_CLOCKDIV. */ - nsp32_sack_negate(data); - - nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "exit"); + switch (data->clock) { + case CLOCK_4: + /* If data->clock is CLOCK_4, then select 40M sync table. */ + data->synct = nsp32_sync_table_40M; + data->syncnum = NUMBER(nsp32_sync_table_40M); + break; + case CLOCK_2: + /* If data->clock is CLOCK_2, then select 20M sync table. */ + data->synct = nsp32_sync_table_20M; + data->syncnum = NUMBER(nsp32_sync_table_20M); + break; + case PCICLK: + /* If data->clock is PCICLK, then select pci sync table. */ + data->synct = nsp32_sync_table_pci; + data->syncnum = NUMBER(nsp32_sync_table_pci); + break; + default: + nsp32_msg(KERN_WARNING, + "Invalid clock div is selected, set CLOCK_4."); + /* Use default value CLOCK_4 */ + data->clock = CLOCK_4; + data->synct = nsp32_sync_table_40M; + data->syncnum = NUMBER(nsp32_sync_table_40M); + } - return; + /* + * setup nsp32_lunt + */ - reject: - nsp32_msg(KERN_WARNING, - "invalid or unsupported MessageIn, rejected. " - "current msg: 0x%x (len: 0x%x), processing msg: 0x%x", - msg, data->msginlen, msgtype); - nsp32_build_reject(data); - data->msginlen = 0; + /* + * setup DMA + */ + if (pci_set_dma_mask(PCIDEV, 0xffffffffUL) != 0) { + nsp32_msg (KERN_ERR, "failed to set PCI DMA mask"); + goto scsi_unregister; + } - goto restart; -} + /* + * allocate autoparam DMA resource. + */ + data->autoparam = pci_alloc_consistent(PCIDEV, sizeof(nsp32_autoparam), &(data->auto_paddr)); + if (data->autoparam == NULL) { + nsp32_msg(KERN_ERR, "failed to allocate DMA memory"); + goto scsi_unregister; + } -/* - * - */ -static void nsp32_analyze_sdtr(nsp32_hw_data *data) -{ - struct nsp32_target *target = data->curtarget; - struct nsp32_sync_table *synct; - unsigned char get_period = data->msginbuf[3]; - unsigned char get_offset = data->msginbuf[4]; - int entry; - int syncnum; + /* + * allocate scatter-gather DMA resource. + */ + data->sg_list = pci_alloc_consistent(PCIDEV, NSP32_SG_TABLE_SIZE, + &(data->sg_paddr)); + if (data->sg_list == NULL) { + nsp32_msg(KERN_ERR, "failed to allocate DMA memory"); + goto free_autoparam; + } - nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "enter"); + for (n_target = 0; n_target < NUMBER(data->lunt); n_target++) { + for (n_lun = 0; n_lun < NUMBER(data->lunt[0]); n_lun++) { + int offset = n_target * NUMBER(data->lunt[0]) + n_lun; + nsp32_lunt tmp = { + SCpnt: NULL, + save_datp: 0, + msgin03: FALSE, + sg_num: 0, + cur_entry: 0, + sglun: &(data->sg_list[offset]), + sglun_paddr: data->sg_paddr + ARRAY_OFFSET(nsp32_sglun, offset), + }; - synct = data->synct; - syncnum = data->syncnum; + data->lunt[n_target][n_lun] = tmp; + } + } /* - * If this inititor sent the SDTR message, then target responds SDTR, - * initiator SYNCREG, ACKWIDTH from SDTR parameter. - * Messages are not appropriate, then send back reject message. - * If initiator did not send the SDTR, but target sends SDTR, - * initiator calculator the appropriate parameter and send back SDTR. - */ - if (target->sync_flag & SDTR_INITIATOR) { - /* - * Initiator sent SDTR, the target responds and - * send back negotiation SDTR. - */ - nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "target responds SDTR"); - - target->sync_flag &= ~SDTR_INITIATOR; - target->sync_flag |= SDTR_DONE; + * setup target + */ + for (i = 0; i < NUMBER(data->target); i++) { + nsp32_target *target = &(data->target[i]); - /* - * offset: - */ - if (get_offset > SYNC_OFFSET) { - /* - * Negotiation is failed, the target send back - * unexpected offset value. - */ - goto reject; - } - - if (get_offset == ASYNC_OFFSET) { - /* - * Negotiation is succeeded, the target want - * to fall back into asynchronous transfer mode. - */ - goto async; - } + target->limit_entry = 0; + target->sync_flag = SDTR_NONE; + nsp32_set_async(data, target); + } - /* - * period: - * Check whether sync period is too short. If too short, - * fall back to async mode. If it's ok, then investigate - * the received sync period. If sync period is acceptable - * between sync table start_period and end_period, then - * set this I_T nexus as sent offset and period. - * If it's not acceptable, send back reject and fall back - * to async mode. - */ - if (get_period < data->synct[0].period_num) { - /* - * Negotiation is failed, the target send back - * unexpected period value. - */ - goto reject; - } + /* + * EEPROM check + */ + ret = nsp32_getprom_param(data); + if (ret == FALSE) { + data->resettime = 3; /* default 3 */ + } - entry = nsp32_search_period_entry(data, target, get_period); + /* + * setup HBA + */ + nsp32hw_init(data); - if (entry < 0) { - /* - * Target want to use long period which is not - * acceptable NinjaSCSI-32Bi/UDE. - */ - goto reject; - } + snprintf(data->info_str, sizeof(data->info_str), + "NinjaSCSI-32Bi/UDE: irq %d, io 0x%lx+0x%x", + host->irq, host->io_port, host->n_io_port); - /* - * Set new sync table and offset in this I_T nexus. - */ - nsp32_set_sync_entry(data, target, entry, get_offset); - } else { - /* Target send SDTR to initiator. */ - nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "target send SDTR"); - - target->sync_flag |= SDTR_INITIATOR; + /* + * SCSI bus reset + * + * Note: It's important to reset SCSI bus in initialization phase. + * NinjaSCSI-32Bi/UDE HBA EEPROM seems to exchange SDTR when + * system is coming up, so SCSI devices connected to HBA is set as + * un-asynchronous mode. It brings the merit that this HBA is + * ready to start synchronous transfer without any preparation, + * but we are difficult to control transfer speed. In addition, + * it prevents device transfer speed from effecting EEPROM start-up + * SDTR. NinjaSCSI-32Bi/UDE has the feature if EEPROM is set as + * Auto Mode, then FAST-10M is selected when SCSI devices are + * connected same or more than 4 devices. It should be avoided + * depending on this specification. Thus, resetting the SCSI bus + * restores all connected SCSI devices to asynchronous mode, then + * this driver set SDTR safely later, and we can control all SCSI + * device transfer mode. + */ + nsp32_do_bus_reset(data); - /* offset: */ - if (get_offset > SYNC_OFFSET) { - /* send back as SYNC_OFFSET */ - get_offset = SYNC_OFFSET; - } + ret = request_irq(host->irq, do_nsp32_isr, + SA_SHIRQ | SA_SAMPLE_RANDOM, "nsp32", data); + if (ret < 0) { + nsp32_msg(KERN_ERR, "Unable to allocate IRQ for NinjaSCSI32 " + "SCSI PCI controller. Interrupt: %d", host->irq); + goto free_sg_list; + } - /* period: */ - if (get_period < data->synct[0].period_num) { - get_period = data->synct[0].period_num; - } + /* + * PCI IO register + */ + res = request_region(host->io_port, host->n_io_port, "nsp32"); + if (res == NULL) { + nsp32_msg(KERN_ERR, + "I/O region 0x%lx+0x%lx is already used", + data->BaseAddress, data->NumAddress); + goto free_irq; + } - entry = nsp32_search_period_entry(data, target, get_period); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) + scsi_add_host (host, &PCIDEV->dev); + scsi_scan_host(host); +#endif + pci_set_drvdata(PCIDEV, host); + return DETECT_OK; - if (get_offset == ASYNC_OFFSET || entry < 0) { - nsp32_set_async(data, target); - nsp32_build_sdtr(data, 0, ASYNC_OFFSET); - } else { - nsp32_set_sync_entry(data, target, entry, get_offset); - nsp32_build_sdtr(data, get_period, get_offset); - } - } - - nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "exit"); - return; + free_irq: + free_irq(host->irq, data); - reject: - /* - * If the current message is unacceptable, send back to the target - * with reject message. - */ - nsp32_build_reject(data); + free_sg_list: + pci_free_consistent(PCIDEV, NSP32_SG_TABLE_SIZE, + data->sg_list, data->sg_paddr); - async: - nsp32_set_async(data, target); /* set as ASYNC transfer mode */ + free_autoparam: + pci_free_consistent(PCIDEV, sizeof(nsp32_autoparam), + data->autoparam, data->auto_paddr); + + scsi_unregister: + scsi_host_put(host); - nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "exit: set async"); - return; + err: + return DETECT_NG; } +#undef DETECT_OK +#undef DETECT_NG +#undef PCIDEV - -/* - * Search config entry number matched in sync_table from given - * target and speed period value. If failed to search, return negative value. - */ -static int nsp32_search_period_entry(nsp32_hw_data *data, - struct nsp32_target *target, - unsigned char period) +static int nsp32_release(struct Scsi_Host *host) { - int i; + nsp32_hw_data *data = (nsp32_hw_data *)host->hostdata; - if (target->limit_entry >= data->syncnum) { - nsp32_msg(KERN_ERR, "limit_entry exceeds syncnum!"); - target->limit_entry = 0; + if (data->autoparam) { + pci_free_consistent(data->Pci, sizeof(nsp32_autoparam), + data->autoparam, data->auto_paddr); } - for (i=target->limit_entry; isyncnum; i++) { - if (period >= data->synct[i].start_period && - period <= data->synct[i].end_period) { - break; - } + if (data->sg_list) { + pci_free_consistent(data->Pci, NSP32_SG_TABLE_SIZE, + data->sg_list, data->sg_paddr); } - /* - * Check given period value is over the sync_table value. - * If so, return max value. - */ - if (i == data->syncnum) { - i = -1; + if (host->irq) { + free_irq(host->irq, data); } - return i; -} - - -/* - * target <-> initiator use ASYNC transfer - */ -static void nsp32_set_async(nsp32_hw_data *data, struct nsp32_target *target) -{ - unsigned char period = data->synct[target->limit_entry].period_num; + if (host->io_port && host->n_io_port) { + release_region(host->io_port, host->n_io_port); + } - target->offset = ASYNC_OFFSET; - target->syncreg = TO_SYNCREG(period, ASYNC_OFFSET); - target->ackwidth = 0; + if (data->MmioAddress != 0) { + iounmap((void *)(data->MmioAddress)); + } - nsp32_dbg(NSP32_DEBUG_SYNC, "set async"); + return 0; } +static const char *nsp32_info(struct Scsi_Host *shpnt) +{ + nsp32_hw_data *data = (nsp32_hw_data *)shpnt->hostdata; -/* - * target <-> initiator use maximum SYNC transfer - */ -static void nsp32_set_max_sync(nsp32_hw_data *data, - struct nsp32_target *target, - unsigned char *period, unsigned char *offset) -{ - unsigned char period_num, ackwidth; - - period_num = data->synct[target->limit_entry].period_num; - *period = data->synct[target->limit_entry].start_period; - ackwidth = data->synct[target->limit_entry].ackwidth; - *offset = SYNC_OFFSET; - - target->syncreg = TO_SYNCREG(period_num, *offset); - target->ackwidth = ackwidth; - target->offset = *offset; + return data->info_str; } -/* - * target <-> initiator use entry number speed +/**************************************************************************** + * error handler */ -static void nsp32_set_sync_entry(nsp32_hw_data *data, - struct nsp32_target *target, - int entry, unsigned char offset) +static int nsp32_eh_abort(Scsi_Cmnd *SCpnt) { - unsigned char period, ackwidth; + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; + unsigned int base = SCpnt->device->host->io_port; - period = data->synct[entry].period_num; - ackwidth = data->synct[entry].ackwidth; - offset = offset; - - target->syncreg = TO_SYNCREG(period, offset); - target->ackwidth = ackwidth; - target->offset = offset; + nsp32_msg(KERN_WARNING, "abort"); - nsp32_dbg(NSP32_DEBUG_SYNC, "set sync"); -} + if (data->cur_lunt->SCpnt == NULL) { + nsp32_dbg(NSP32_DEBUG_BUSRESET, "abort failed"); + return FAILED; + } + if (data->cur_target->sync_flag & (SDTR_INITIATOR | SDTR_TARGET)) { + /* reset SDTR negotiation */ + data->cur_target->sync_flag = SDTR_NONE; + nsp32_set_async(data, data->cur_target); + } -/* - * It waits until SCSI REQ becomes assertion or negation state. - * - * Note: If nsp32_msgin_occur is called, we asserts SCSI ACK. Then - * connected target responds SCSI REQ negation. We have to wait - * SCSI REQ becomes negation in order to negate SCSI ACK signal for - * REQ-ACK handshake. - */ -static void nsp32_wait_req(nsp32_hw_data *data, int state) + nsp32_write2(base, TRANSFER_CONTROL, 0); + nsp32_write2(base, BM_CNT, 0); + + SCpnt->result = DID_ABORT << 16; + nsp32_scsi_done(SCpnt); + + nsp32_dbg(NSP32_DEBUG_BUSRESET, "abort success"); + return SUCCESS; +} + +static int nsp32_eh_bus_reset(Scsi_Cmnd *SCpnt) { - unsigned int base = data->BaseAddress; - int wait_time = 0; - unsigned char bus; + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; + unsigned int base = SCpnt->device->host->io_port; - if (!((state == ASSERT) || (state == NEGATE))) { - nsp32_msg(KERN_ERR, "unknown state designation"); - } - state <<= 5; /* REQ is BIT(5) */ + nsp32_msg(KERN_INFO, "Bus Reset"); + nsp32_dbg(NSP32_DEBUG_BUSRESET, "SCpnt=0x%x", SCpnt); - do { - bus = nsp32_read1(base, SCSI_BUS_MONITOR); - if ((bus & BUSMON_REQ) == state) { - nsp32_dbg(NSP32_DEBUG_WAIT, - "wait_time: %d", wait_time); - return; - } - udelay(1); - wait_time++; - } while (wait_time < REQSACK_TIMEOUT_TIME); + nsp32_write2(base, IRQ_CONTROL, IRQ_CONTROL_ALL_IRQ_MASK); + nsp32_do_bus_reset(data); + nsp32_write2(base, IRQ_CONTROL, 0); - nsp32_msg(KERN_WARNING, "wait REQ timeout, state: %d", state); + return SUCCESS; /* SCSI bus reset is succeeded at any time. */ } -/* - * It waits until SCSI SACK becomes assertion or negation state. - */ -static void nsp32_wait_sack(nsp32_hw_data *data, int state) +static void nsp32_do_bus_reset(nsp32_hw_data *data) { - unsigned int base = data->BaseAddress; - int wait_time = 0; - unsigned char bus; + unsigned int base = data->BaseAddress; + unsigned short intrdat; + int i; - if (!((state == ASSERT) || (state == NEGATE))) { - nsp32_msg(KERN_ERR, "unknown state designation"); + nsp32_dbg(NSP32_DEBUG_BUSRESET, "in"); + + /* + * stop all transfer + * clear TRANSFERCONTROL_BM_START + * clear counter + */ + nsp32_write2(base, TRANSFER_CONTROL, 0); + nsp32_write4(base, BM_CNT, 0); + nsp32_write4(base, CLR_COUNTER, CLRCOUNTER_ALLMASK); + + /* + * fall back to asynchronous transfer mode + * initialize SDTR negotiation flag + */ + for (i = 0; i < NUMBER(data->target); i++) { + nsp32_target *target = &data->target[i]; + + target->sync_flag = SDTR_NONE; + nsp32_set_async(data, target); } - state <<= 4; /* ACK is BIT(4) */ - do { - bus = nsp32_read1(base, SCSI_BUS_MONITOR); - if ((bus & BUSMON_ACK) == state) { - nsp32_dbg(NSP32_DEBUG_WAIT, - "wait_time: %d", wait_time); - return; - } - udelay(1); - wait_time++; - } while (wait_time < REQSACK_TIMEOUT_TIME); + /* + * reset SCSI bus + */ + nsp32_write1(base, SCSI_BUS_CONTROL, BUSCTL_RST); + udelay(RESET_HOLD_TIME); + nsp32_write1(base, SCSI_BUS_CONTROL, 0); + for(i = 0; i < 5; i++) { + intrdat = nsp32_read2(base, IRQ_STATUS); /* dummy read */ + nsp32_dbg(NSP32_DEBUG_BUSRESET, "irq:1: 0x%x", intrdat); + } - nsp32_msg(KERN_WARNING, "wait SACK timeout, state: %d", state); + data->CurrentSC = NULL; } -/* - * assert SCSI ACK - * - * Note: SCSI ACK assertion needs with ACKENB=1, AUTODIRECTION=1. - */ -static void nsp32_sack_assert(nsp32_hw_data *data) +static int nsp32_eh_host_reset(Scsi_Cmnd *SCpnt) { - unsigned char busctrl; - unsigned int base = data->BaseAddress; + struct Scsi_Host *host = SCpnt->device->host; + unsigned int base = SCpnt->device->host->io_port; + nsp32_hw_data *data = (nsp32_hw_data *)host->hostdata; - busctrl = nsp32_read1(base, SCSI_BUS_CONTROL); - busctrl |= (BUSCTL_ACK | AUTODIRECTION | ACKENB); - nsp32_write1(base, SCSI_BUS_CONTROL,busctrl); -} + nsp32_msg(KERN_INFO, "Host Reset"); + nsp32_dbg(NSP32_DEBUG_BUSRESET, "SCpnt=0x%x", SCpnt); -/* - * negate SCSI ACK - */ -static void nsp32_sack_negate(nsp32_hw_data *data) -{ - unsigned char busctrl; - unsigned int base = data->BaseAddress; + nsp32hw_init(data); + nsp32_write2(base, IRQ_CONTROL, IRQ_CONTROL_ALL_IRQ_MASK); + nsp32_do_bus_reset(data); + nsp32_write2(base, IRQ_CONTROL, 0); - busctrl = nsp32_read1(base, SCSI_BUS_CONTROL); - busctrl &= ~BUSCTL_ACK; - nsp32_write1(base, SCSI_BUS_CONTROL, busctrl); + return SUCCESS; /* Host reset is succeeded at any time. */ } +/************************************************************************** + * EEPROM handler + */ /* * getting EEPROM parameter @@ -3165,7 +3083,12 @@ { int vendor = data->pci_devid->vendor; int device = data->pci_devid->device; - int ret, val, i; + int ret; +#ifdef NSP32_DEBUG + int i; +#define NSP32_DEBUG_PROM_BUF_SIZE 0x20 + unsigned char buf[NSP32_DEBUG_PROM_BUF_SIZE]; +#endif /* * EEPROM checking. @@ -3173,12 +3096,12 @@ ret = nsp32_prom_read(data, 0x7e); if (ret != 0x55) { nsp32_msg(KERN_INFO, "No EEPROM detected: 0x%x", ret); - return (FALSE); + return FALSE; } ret = nsp32_prom_read(data, 0x7f); if (ret != 0xaa) { nsp32_msg(KERN_INFO, "Invalid number: 0x%x", ret); - return (FALSE); + return FALSE; } /* @@ -3186,27 +3109,30 @@ */ if (vendor == PCI_VENDOR_ID_WORKBIT && device == PCI_DEVICE_ID_WORKBIT_STANDARD) { - ret = nsp32_getprom_standard(data); + ret = nsp32_getprom_c16(data); } else if (vendor == PCI_VENDOR_ID_WORKBIT && device == PCI_DEVICE_ID_NINJASCSI_32BIB_LOGITEC) { - ret = nsp32_getprom_new(data); + ret = nsp32_getprom_at24(data); } else if (vendor == PCI_VENDOR_ID_WORKBIT && device == PCI_DEVICE_ID_NINJASCSI_32UDE_MELCO ) { - ret = nsp32_getprom_new(data); + ret = nsp32_getprom_at24(data); } else { nsp32_msg(KERN_WARNING, "Unknown EEPROM"); ret = FALSE; } +#ifdef NSP32_DEBUG /* for debug : SPROM data full checking */ - for (i=0; i<=0x1f; i++) { - val = nsp32_prom_read(data, i); - nsp32_dbg(NSP32_DEBUG_EEPROM, - "rom address 0x%x : 0x%x", i, val); + nsp32_dbg(NSP32_DEBUG_EEPROM, "rom dump"); + for (i = 0; i < sizeof(buf); i++) { + buf[i] = nsp32_prom_read(data, i); } + nsp32_byte_dump(buf, 0, sizeof(buf)); +#endif - return (ret); + return ret; } +#undef NSP32_DEBUG_PROM_BUF_SIZE /* @@ -3233,15 +3159,15 @@ * 0x1c : Constant? (0x01) (clock div?) * 0x1d - 0x7c : Not Used (0xff) * 0x7d : Not Used? (0xff) - * 0x7e : Constant (0x55), HBA chip revision - * 0x7f : Constant (0xaa), HBA value + * 0x7e : Constant (0x55), Validity signature + * 0x7f : Constant (0xaa), Validity signature */ -static int nsp32_getprom_new(nsp32_hw_data *data) +static int nsp32_getprom_at24(nsp32_hw_data *data) { - int ret, i; - int auto_sync; - struct nsp32_target *target; - int entry; + int ret, i; + int auto_sync; + nsp32_target *target; + int entry; /* * Reset time which is designated by EEPROM. @@ -3273,8 +3199,7 @@ break; default: nsp32_msg(KERN_WARNING, - "Unsupported Auto Sync mode." - "Fall back to manual mode."); + "Unsupported Auto Sync mode. Fall back to manual mode."); auto_sync = TRUE; } @@ -3285,12 +3210,12 @@ /* * each device Synchronous Transfer Period */ - for (i=0; itarget[i]; if (auto_sync == TRUE) { target->limit_entry = 0; /* set as ULTRA20M */ } else { - ret = nsp32_prom_read(data, i); + ret = nsp32_prom_read(data, i); entry = nsp32_search_period_entry(data, target, ret); if (entry < 0) { /* search failed... set maximum speed */ @@ -3300,12 +3225,12 @@ } } - return (TRUE); + return TRUE; } /* - * ? (I-O Data: SC-NBD) data map: + * C16 110 (I-O Data: SC-NBD) data map: * * ROMADDR * 0x00 - 0x06 : Device Synchronous Transfer Period (SCSI ID 0 - 6) @@ -3321,14 +3246,14 @@ * Value 0: Disable, 1: Enable * 0x1a - 0x7c : Not Used? (0) * 0x7d : Not Used? (0xf8) - * 0x7e : Constant (0x55), HBA chip revision - * 0x7f : Constant (0xaa), HBA value + * 0x7e : Constant (0x55), Validity signature + * 0x7f : Constant (0xaa), Validity signature */ -static int nsp32_getprom_standard(nsp32_hw_data *data) +static int nsp32_getprom_c16(nsp32_hw_data *data) { - int ret, i; - struct nsp32_target *target; - int entry, val; + int ret, i; + nsp32_target *target; + int entry, val; /* * Reset time which is designated by EEPROM. @@ -3340,7 +3265,7 @@ /* * each device Synchronous Transfer Period */ - for (i=0; itarget[i]; ret = nsp32_prom_read(data, i); switch (ret) { @@ -3354,10 +3279,11 @@ val = 0x32; break; case 3: /* ASYNC */ - val = 0x0; + val = 0x00; break; default: /* default 20MB/s */ val = 0x0c; + break; } entry = nsp32_search_period_entry(data, target, val); if (entry < 0 || trans_mode == ULTRA20M_MODE) { @@ -3367,7 +3293,7 @@ target->limit_entry = entry; } - return (TRUE); + return TRUE; } @@ -3382,145 +3308,314 @@ nsp32_prom_start(data); /* device address */ - nsp32_prom_write(data, 1); /* 1 */ - nsp32_prom_write(data, 0); /* 0 */ - nsp32_prom_write(data, 1); /* 1 */ - nsp32_prom_write(data, 0); /* 0 */ - nsp32_prom_write(data, 0); /* A2: 0 (GND) */ - nsp32_prom_write(data, 0); /* A1: 0 (GND) */ - nsp32_prom_write(data, 0); /* A0: 0 (GND) */ + nsp32_prom_write_bit(data, 1); /* 1 */ + nsp32_prom_write_bit(data, 0); /* 0 */ + nsp32_prom_write_bit(data, 1); /* 1 */ + nsp32_prom_write_bit(data, 0); /* 0 */ + nsp32_prom_write_bit(data, 0); /* A2: 0 (GND) */ + nsp32_prom_write_bit(data, 0); /* A1: 0 (GND) */ + nsp32_prom_write_bit(data, 0); /* A0: 0 (GND) */ /* R/W: W for dummy write */ - nsp32_prom_write(data, 0); + nsp32_prom_write_bit(data, 0); /* ack */ - nsp32_prom_write(data, 0); + nsp32_prom_write_bit(data, 0); /* word address */ - for (i=7; i>=0; i--) { - nsp32_prom_write(data, ((romaddr >> i) & 1)); + for (i = 7; i >= 0; i--) { + nsp32_prom_write_bit(data, ((romaddr >> i) & 1)); } /* ack */ - nsp32_prom_write(data, 0); + nsp32_prom_write_bit(data, 0); /* start condition */ nsp32_prom_start(data); /* device address */ - nsp32_prom_write(data, 1); /* 1 */ - nsp32_prom_write(data, 0); /* 0 */ - nsp32_prom_write(data, 1); /* 1 */ - nsp32_prom_write(data, 0); /* 0 */ - nsp32_prom_write(data, 0); /* A2: 0 (GND) */ - nsp32_prom_write(data, 0); /* A1: 0 (GND) */ - nsp32_prom_write(data, 0); /* A0: 0 (GND) */ + nsp32_prom_write_bit(data, 1); /* 1 */ + nsp32_prom_write_bit(data, 0); /* 0 */ + nsp32_prom_write_bit(data, 1); /* 1 */ + nsp32_prom_write_bit(data, 0); /* 0 */ + nsp32_prom_write_bit(data, 0); /* A2: 0 (GND) */ + nsp32_prom_write_bit(data, 0); /* A1: 0 (GND) */ + nsp32_prom_write_bit(data, 0); /* A0: 0 (GND) */ /* R/W: R */ - nsp32_prom_write(data, 1); + nsp32_prom_write_bit(data, 1); /* ack */ - nsp32_prom_write(data, 0); + nsp32_prom_write_bit(data, 0); /* data... */ val = 0; - for (i=7; i>=0; i--) { - val += (nsp32_prom_fetch(data) << i); + for (i = 7; i >= 0; i--) { + int bit = nsp32_prom_read_bit(data) ? 1 : 0; + + val |= (bit << i); } /* no ack */ - nsp32_prom_write(data, 1); + nsp32_prom_write_bit(data, 1); /* stop condition */ nsp32_prom_stop(data); - return (val); + return val; } static void nsp32_prom_start (nsp32_hw_data *data) { /* start condition */ - nsp32_prom_set(data, SCL, 1); - nsp32_prom_set(data, SDA, 1); - nsp32_prom_set(data, ENA, 1); /* output mode */ - nsp32_prom_set(data, SDA, 0); /* keeping SCL=1 and transiting - * SDA 1->0 is start condition */ - nsp32_prom_set(data, SCL, 0); + nsp32_prom_set(data, SROM_CTL, 1); + nsp32_prom_set(data, SROM_DATA, 1); + nsp32_prom_set(data, SROM_ENABLE, 1); /* output mode */ + nsp32_prom_set(data, SROM_DATA, 0); /* keeping SROM_CTL=1 and transiting + * SROM_DATA 1->0 is start condition */ + nsp32_prom_set(data, SROM_CTL, 0); } static void nsp32_prom_stop (nsp32_hw_data *data) { /* stop condition */ - nsp32_prom_set(data, SCL, 1); - nsp32_prom_set(data, SDA, 0); - nsp32_prom_set(data, ENA, 1); /* output mode */ - nsp32_prom_set(data, SDA, 1); - nsp32_prom_set(data, SCL, 0); + nsp32_prom_set(data, SROM_CTL, 1); + nsp32_prom_set(data, SROM_DATA, 0); + nsp32_prom_set(data, SROM_ENABLE, 1); /* output mode */ + nsp32_prom_set(data, SROM_DATA, 1); + nsp32_prom_set(data, SROM_CTL, 0); } -static void nsp32_prom_write (nsp32_hw_data *data, int val) +static void nsp32_prom_write_bit(nsp32_hw_data *data, int val) { /* write */ - nsp32_prom_set(data, SDA, val); - nsp32_prom_set(data, SCL, 1); - nsp32_prom_set(data, SCL, 0); + nsp32_prom_set(data, SROM_DATA, val); + nsp32_prom_set(data, SROM_CTL, 1 ); + nsp32_prom_set(data, SROM_CTL, 0 ); } -static int nsp32_prom_fetch (nsp32_hw_data *data) +static int nsp32_prom_read_bit(nsp32_hw_data *data) { int val; /* read */ - nsp32_prom_set(data, ENA, 0); /* input mode */ - nsp32_prom_set(data, SCL, 1); - val = nsp32_prom_get(data, SDA); - nsp32_prom_set(data, SCL, 0); - nsp32_prom_set(data, ENA, 1); /* output mode */ - return (val); + nsp32_prom_set(data, SROM_ENABLE, 0); /* input mode */ + nsp32_prom_set(data, SROM_CTL, 1); + + val = nsp32_prom_get(data, SROM_DATA); + + nsp32_prom_set(data, SROM_CTL, 0); + nsp32_prom_set(data, SROM_ENABLE, 1); /* output mode */ + + return val; } static inline void nsp32_prom_set(nsp32_hw_data *data, int bit, int val) { - int cur; - int base = data->BaseAddress; + unsigned int base = data->BaseAddress; + int tmp; - switch(val) { - case 0: - cur = nsp32_index_read1(base, SERIAL_ROM_CTL); - nsp32_index_write1(base, SERIAL_ROM_CTL, cur & ~bit); - break; - case 1: - cur = nsp32_index_read1(base, SERIAL_ROM_CTL); - nsp32_index_write1(base, SERIAL_ROM_CTL, cur | bit); - break; - default: - nsp32_msg(KERN_ERR, "val must be 0 or 1"); - return; + tmp = nsp32_index_read1(base, SERIAL_ROM_CTL); + + if (val == 0) { + tmp &= ~bit; + } else { + tmp |= bit; } + nsp32_index_write1(base, SERIAL_ROM_CTL, tmp); + udelay(10); } static inline int nsp32_prom_get(nsp32_hw_data *data, int bit) { - int ret; - int base = data->BaseAddress; + unsigned int base = data->BaseAddress; + int tmp, ret; - ret = nsp32_index_read1(base, SERIAL_ROM_CTL) & bit; - switch (ret) { - case 0: + if (bit != SROM_DATA) { + nsp32_msg(KERN_ERR, "return value is not appropriate"); + return 0; + } + + + tmp = nsp32_index_read1(base, SERIAL_ROM_CTL) & bit; + + if (tmp == 0) { ret = 0; - break; - case SDA: + } else { ret = 1; - break; - default: - nsp32_msg(KERN_ERR, "return value is not appropriate"); } udelay(10); - return (ret); + return ret; +} + + +/************************************************************************** + * Power Management + */ +#ifdef CONFIG_PM +/* Save Device Context */ +static int nsp32_save_state(struct pci_dev *pdev, u32 state) +{ + struct Scsi_Host *host = pci_get_drvdata(pdev); + + nsp32_msg(KERN_INFO, "pci-save_state: stub, pdev=0x%p, state=%ld, slot=%s, host=0x%p", pdev, state, pci_name(pdev), host); + + return 0; +} + +/* Device suspended */ +static int nsp32_suspend(struct pci_dev *pdev, u32 state) +{ + struct Scsi_Host *host = pci_get_drvdata(pdev); + nsp32_hw_data *data = (nsp32_hw_data *)host->hostdata; + + nsp32_msg(KERN_INFO, "pci-suspend: pdev=0x%p, state=%ld, slot=%s, host=0x%p", pdev, state, pci_name(pdev), host); + + pci_save_state (pdev, data->PciState); + pci_disable_device (pdev); + pci_set_power_state(pdev, state); + + return 0; +} + +/* Device woken up */ +static int nsp32_resume(struct pci_dev *pdev) +{ + struct Scsi_Host *host = pci_get_drvdata(pdev); + nsp32_hw_data *data = (nsp32_hw_data *)host->hostdata; + unsigned short reg; + + nsp32_msg(KERN_INFO, "pci-resume: pdev=0x%p, slot=%s, host=0x%p", pdev, pci_name(pdev), host); + + pci_set_power_state(pdev, 0); + pci_enable_wake (pdev, 0, 0); + pci_restore_state (pdev, data->PciState); + + reg = nsp32_read2(data->BaseAddress, INDEX_REG); + + nsp32_msg(KERN_INFO, "io=0x%x reg=0x%x", data->BaseAddress, reg); + + if (reg == 0xffff) { + nsp32_msg(KERN_INFO, "missing device. abort resume."); + return 0; + } + + nsp32hw_init (data); + nsp32_do_bus_reset(data); + + nsp32_msg(KERN_INFO, "resume success"); + + return 0; +} + +/* Enable wake event */ +static int nsp32_enable_wake(struct pci_dev *pdev, u32 state, int enable) +{ + struct Scsi_Host *host = pci_get_drvdata(pdev); + + nsp32_msg(KERN_INFO, "pci-enable_wake: stub, pdev=0x%p, enable=%d, slot=%s, host=0x%p", pdev, enable, pci_name(pdev), host); + + return 0; +} +#endif + +/************************************************************************ + * PCI/Cardbus probe/remove routine + */ +static int __devinit nsp32_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + int ret; + nsp32_hw_data *data = &nsp32_data_base; + + nsp32_dbg(NSP32_DEBUG_REGISTER, "enter"); + + ret = pci_enable_device(pdev); + if (ret) { + nsp32_msg(KERN_ERR, "failed to enable pci device"); + return ret; + } + + data->Pci = pdev; + data->pci_devid = id; + data->IrqNumber = pdev->irq; + data->BaseAddress = pci_resource_start(pdev, 0); + data->NumAddress = pci_resource_len (pdev, 0); + data->MmioAddress = + (unsigned long)ioremap_nocache(pci_resource_start(pdev, 1), + pci_resource_len (pdev, 1)); + data->MmioLength = pci_resource_len (pdev, 1); + + pci_set_master(pdev); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) + ret = nsp32_detect(pdev); +#else + ret = scsi_register_host(&nsp32_template); +#endif + + nsp32_msg(KERN_INFO, "irq: %i mmio: 0x%lx+0x%lx slot: %s model: %s", + pdev->irq, + data->MmioAddress, data->MmioLength, + pci_name(pdev), + nsp32_model[id->driver_data]); + + nsp32_dbg(NSP32_DEBUG_REGISTER, "exit %d", ret); + + return ret; +} + +static void __devexit nsp32_remove(struct pci_dev *pdev) +{ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) + struct Scsi_Host *host = pci_get_drvdata(pdev); +#endif + + nsp32_dbg(NSP32_DEBUG_REGISTER, "enter"); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) + scsi_remove_host(host); + + nsp32_release(host); + + scsi_host_put(host); +#else + scsi_unregister_host(&nsp32_template); +#endif +} + + + +static struct pci_driver nsp32_driver = { + .name = "nsp32", + .id_table = nsp32_pci_table, + .probe = nsp32_probe, + .remove = __devexit_p(nsp32_remove), +#ifdef CONFIG_PM + .save_state = nsp32_save_state, + .suspend = nsp32_suspend, + .resume = nsp32_resume, + .enable_wake = nsp32_enable_wake, +#endif +}; + +/********************************************************************* + * Moule entry point + */ +static int __init init_nsp32(void) { + nsp32_msg(KERN_INFO, "loading..."); + return pci_module_init(&nsp32_driver); +} + +static void __exit exit_nsp32(void) { + nsp32_msg(KERN_INFO, "unloading..."); + pci_unregister_driver(&nsp32_driver); } +module_init(init_nsp32); +module_exit(exit_nsp32); + /* end */ Index: drivers/scsi/nsp32.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/nsp32.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/nsp32.h 22 Jul 2004 19:50:05 -0000 1.1 +++ drivers/scsi/nsp32.h 4 Aug 2004 01:29:35 -0000 1.2 @@ -1,5 +1,5 @@ /* - * Workbit NinjaSCSI-32Bi/UDE PCI/Cardbus SCSI Host Bus Adapter driver + * Workbit NinjaSCSI-32Bi/UDE PCI/CardBus SCSI Host Bus Adapter driver * Basic data header * * This program is free software; you can redistribute it and/or modify @@ -16,61 +16,68 @@ #ifndef _NSP32_H #define _NSP32_H - //#define NSP32_DEBUG 9 - /* * VENDOR/DEVICE ID */ #define PCI_VENDOR_ID_IODATA 0x10fc #define PCI_VENDOR_ID_WORKBIT 0x1145 -#define PCI_DEVICE_ID_NINJASCSI_32BI_CBSC_II 0x0005 -#define PCI_DEVICE_ID_NINJASCSI_32BI_KME 0xf007 -#define PCI_DEVICE_ID_NINJASCSI_32BI_WBT 0x8007 -#define PCI_DEVICE_ID_WORKBIT_STANDARD 0xf010 -#define PCI_DEVICE_ID_WORKBIT_DUALEDGE 0xf011 -#define PCI_DEVICE_ID_NINJASCSI_32BI_LOGITEC 0xf012 -#define PCI_DEVICE_ID_NINJASCSI_32BIB_LOGITEC 0xf013 -#define PCI_DEVICE_ID_NINJASCSI_32UDE_MELCO 0xf015 +#define PCI_DEVICE_ID_NINJASCSI_32BI_CBSC_II 0x0005 +#define PCI_DEVICE_ID_NINJASCSI_32BI_KME 0xf007 +#define PCI_DEVICE_ID_NINJASCSI_32BI_WBT 0x8007 +#define PCI_DEVICE_ID_WORKBIT_STANDARD 0xf010 +#define PCI_DEVICE_ID_WORKBIT_DUALEDGE 0xf011 +#define PCI_DEVICE_ID_NINJASCSI_32BI_LOGITEC 0xf012 +#define PCI_DEVICE_ID_NINJASCSI_32BIB_LOGITEC 0xf013 +#define PCI_DEVICE_ID_NINJASCSI_32UDE_MELCO 0xf015 +#define PCI_DEVICE_ID_NINJASCSI_32UDE_MELCO_II 0x8009 /* - * MODEL + * MODEL NAME + * + * note: Model number and model string must be same order. */ enum { MODEL_IODATA = 0, MODEL_KME = 1, MODEL_WORKBIT = 2, - MODEL_EXT_ROM = 3, + MODEL_LOGITEC = 3, MODEL_PCI_WORKBIT = 4, MODEL_PCI_LOGITEC = 5, MODEL_PCI_MELCO = 6, }; static char * nsp32_model[] = { - "I-O DATA CBSC-II", - "KME SCSI card", - "Workbit duo SCSI card", - "External ROM", - "Workbit Standard/IO Data PCI card", - "Logitec PCI card", - "Melco PCI card", + "I-O DATA CBSC-II CardBus card", + "KME SCSI CardBus card", + "Workbit duo SCSI CardBus card", + "Logitec CardBus card with external ROM", + "Workbit / I-O DATA PCI card", + "Logitec PCI card with external ROM", + "Melco CardBus/PCI card with external ROM", }; /* - * SCSI Generic Definitions + * SCSI generic message definitions */ #define EXTENDED_SDTR_LEN 0x03 +/* Little Endian */ +typedef u32 u32_le; +typedef u16 u16_le; /* * MACRO */ -#define BIT(x) (1UL << (x)) +/* from X11/Intrinsic.h */ +#define NUMBER(arr) ((int) (sizeof(arr) / sizeof(arr[0]))) +#define ARRAY_OFFSET(type,num) ((int) (((type *) 0) + (num))) +#define BIT(x) (1UL << (x)) #ifndef MIN -# define MIN(a,b) ((a) > (b) ? (b) : (a)) +# define MIN(a,b) ((a) > (b) ? (b) : (a)) #endif /* @@ -111,7 +118,10 @@ # define TIMER_IRQ_MASK BIT(13) # define FIFO_IRQ_MASK BIT(14) # define SCSI_IRQ_MASK BIT(15) -# define IRQ_CONTROL_ALL_IRQ_MASK 0xf000 +# define IRQ_CONTROL_ALL_IRQ_MASK (PCI_IRQ_MASK | \ + TIMER_IRQ_MASK | \ + FIFO_IRQ_MASK | \ + SCSI_IRQ_MASK ) # define IRQSTATUS_ANY_IRQ (IRQSTATUS_RESELECT_OCCUER | \ IRQSTATUS_PHASE_CHANGE_IRQ | \ IRQSTATUS_SCSIRESET_IRQ | \ @@ -121,8 +131,8 @@ IRQSTATUS_BMCNTERR_IRQ | \ IRQSTATUS_AUTOSCSI_IRQ ) -#define TRANSFER_CONTROL 0x02 /* BASE+02, W, W */ -#define TRANSFER_STATUS 0x02 /* BASE+02, W, R */ +#define TRANSFER_CONTROL 0x02 /* BASE+02, W, W */ +#define TRANSFER_STATUS 0x02 /* BASE+02, W, R */ # define CB_MMIO_MODE BIT(0) # define CB_IO_MODE BIT(1) # define BM_TEST BIT(2) @@ -139,26 +149,29 @@ # define ALL_COUNTER_CLR BIT(14) # define FIFOTEST BIT(15) -#define INDEX_REG 0x04 /* BASE+04, Byte(R/W), Word(R) */ +#define INDEX_REG 0x04 /* BASE+04, Byte(R/W), Word(R) */ -#define TIMER_SET 0x06 /* BASE+06, W, R/W */ -# define TIMER_CNT_MASK 0xff +#define TIMER_SET 0x06 /* BASE+06, W, R/W */ +# define TIMER_CNT_MASK (0xff) # define TIMER_STOP BIT(8) -#define DATA_REG_LOW 0x08 /* BASE+08, LowW, R/W */ -#define DATA_REG_HI 0x0a /* BASE+0a, Hi-W, R/W */ +#define DATA_REG_LOW 0x08 /* BASE+08, LowW, R/W */ +#define DATA_REG_HI 0x0a /* BASE+0a, Hi-W, R/W */ -#define FIFO_REST_CNT 0x0c /* BASE+0c, W, R/W */ +#define FIFO_REST_CNT 0x0c /* BASE+0c, W, R/W */ # define FIFO_REST_MASK 0x1ff # define FIFO_EMPTY_SHLD_FLAG BIT(14) # define FIFO_FULL_SHLD_FLAG BIT(15) -#define SREQ_SMPL_RATE 0x0f /* BASE+0f, B, R/W */ +#define SREQ_SMPL_RATE 0x0f /* BASE+0f, B, R/W */ # define SREQSMPLRATE_RATE0 BIT(0) # define SREQSMPLRATE_RATE1 BIT(1) # define SAMPLING_ENABLE BIT(2) +# define SMPL_40M (0) /* 40MHz: 0-100ns/period */ +# define SMPL_20M (SREQSMPLRATE_RATE0) /* 20MHz: 100-200ns/period */ +# define SMPL_10M (SREQSMPLRATE_RATE1) /* 10Mhz: 200- ns/period */ -#define SCSI_BUS_CONTROL 0x10 /* BASE+10, B, R/W */ +#define SCSI_BUS_CONTROL 0x10 /* BASE+10, B, R/W */ # define BUSCTL_SEL BIT(0) # define BUSCTL_RST BIT(1) # define BUSCTL_DATAOUT_ENB BIT(2) @@ -168,16 +181,21 @@ # define AUTODIRECTION BIT(6) # define ACKENB BIT(7) -#define CLR_COUNTER 0x12 /* BASE+12, B, W */ +#define CLR_COUNTER 0x12 /* BASE+12, B, W */ # define ACK_COUNTER_CLR BIT(0) # define SREQ_COUNTER_CLR BIT(1) # define FIFO_HOST_POINTER_CLR BIT(2) # define FIFO_REST_COUNT_CLR BIT(3) # define BM_COUNTER_CLR BIT(4) # define SAVED_ACK_CLR BIT(5) -# define CLRCOUNTER_ALLMASK (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5)) +# define CLRCOUNTER_ALLMASK (ACK_COUNTER_CLR | \ + SREQ_COUNTER_CLR | \ + FIFO_HOST_POINTER_CLR | \ + FIFO_REST_COUNT_CLR | \ + BM_COUNTER_CLR | \ + SAVED_ACK_CLR ) -#define SCSI_BUS_MONITOR 0x12 /* BASE+12, B, R */ +#define SCSI_BUS_MONITOR 0x12 /* BASE+12, B, R */ # define BUSMON_MSG BIT(0) # define BUSMON_IO BIT(1) # define BUSMON_CD BIT(2) @@ -187,20 +205,20 @@ # define BUSMON_SEL BIT(6) # define BUSMON_ATN BIT(7) -#define COMMAND_DATA 0x14 /* BASE+14, B, R/W */ +#define COMMAND_DATA 0x14 /* BASE+14, B, R/W */ -#define PARITY_CONTROL 0x16 /* BASE+16, B, R/W */ +#define PARITY_CONTROL 0x16 /* BASE+16, B, W */ # define PARITY_CHECK_ENABLE BIT(0) # define PARITY_ERROR_CLEAR BIT(1) -#define PARITY_STATUS 0x16 +#define PARITY_STATUS 0x16 /* BASE+16, B, R */ //# define PARITY_CHECK_ENABLE BIT(0) # define PARITY_ERROR_NORMAL BIT(1) # define PARITY_ERROR_LSB BIT(1) # define PARITY_ERROR_MSB BIT(2) -#define RESELECT_ID 0x18 /* BASE+18, B, R */ +#define RESELECT_ID 0x18 /* BASE+18, B, R */ -#define COMMAND_CONTROL 0x18 /* BASE+18, W, W */ +#define COMMAND_CONTROL 0x18 /* BASE+18, W, W */ # define CLEAR_CDB_FIFO_POINTER BIT(0) # define AUTO_COMMAND_PHASE BIT(1) # define AUTOSCSI_START BIT(2) @@ -211,27 +229,27 @@ # define AUTO_MSGIN_02 BIT(7) # define AUTO_MSGIN_03 BIT(8) -#define SET_ARBIT 0x1a /* BASE+1a, B, W */ +#define SET_ARBIT 0x1a /* BASE+1a, B, W */ # define ARBIT_GO BIT(0) # define ARBIT_CLEAR BIT(1) -#define ARBIT_STATUS 0x1a /* BASE+1a, B, R */ +#define ARBIT_STATUS 0x1a /* BASE+1a, B, R */ //# define ARBIT_GO BIT(0) # define ARBIT_WIN BIT(1) # define ARBIT_FAIL BIT(2) # define AUTO_PARAMETER_VALID BIT(3) # define SGT_VALID BIT(4) -#define SYNC_REG 0x1c /* BASE+1c, B, R/W */ +#define SYNC_REG 0x1c /* BASE+1c, B, R/W */ -#define ACK_WIDTH 0x1d /* BASE+1d, B, R/W */ +#define ACK_WIDTH 0x1d /* BASE+1d, B, R/W */ -#define SCSI_DATA_WITH_ACK 0x20 /* BASE+20, B, R/W */ +#define SCSI_DATA_WITH_ACK 0x20 /* BASE+20, B, R/W */ #define SCSI_OUT_LATCH_TARGET_ID 0x22 /* BASE+22, B, W */ -#define SCSI_DATA_IN 0x22 /* BASE+22, B, R */ +#define SCSI_DATA_IN 0x22 /* BASE+22, B, R */ -#define SCAM_CONTROL 0x24 /* BASE+24, B, W */ -#define SCAM_STATUS 0x24 /* BASE+24, B, R */ +#define SCAM_CONTROL 0x24 /* BASE+24, B, W */ +#define SCAM_STATUS 0x24 /* BASE+24, B, R */ # define SCAM_MSG BIT(0) # define SCAM_IO BIT(1) # define SCAM_CD BIT(2) @@ -239,31 +257,31 @@ # define SCAM_SEL BIT(4) # define SCAM_XFEROK BIT(5) -#define SCAM_DATA 0x26 /* BASE+26, B, R/W */ -# define SD0 BIT(0) -# define SD1 BIT(1) -# define SD2 BIT(2) -# define SD3 BIT(3) -# define SD4 BIT(4) -# define SD5 BIT(5) -# define SD6 BIT(6) -# define SD7 BIT(7) - -#define SACK_CNT 0x28 /* BASE+28, DW, R/W */ -#define SREQ_CNT 0x2c /* BASE+2c, DW, R/W */ - -#define FIFO_DATA_LOW 0x30 /* BASE+30, B/W/DW, R/W */ -#define FIFO_DATA_HIGH 0x32 /* BASE+32, B/W, R/W */ -#define BM_START_ADR 0x34 /* BASE+34, DW, R/W */ - -#define BM_CNT 0x38 /* BASE+38, DW, R/W */ -# define BM_COUNT_MASK 0x0001ffff -# define SGTEND BIT(31) +#define SCAM_DATA 0x26 /* BASE+26, B, R/W */ +# define SD0 BIT(0) +# define SD1 BIT(1) +# define SD2 BIT(2) +# define SD3 BIT(3) +# define SD4 BIT(4) +# define SD5 BIT(5) +# define SD6 BIT(6) +# define SD7 BIT(7) + +#define SACK_CNT 0x28 /* BASE+28, DW, R/W */ +#define SREQ_CNT 0x2c /* BASE+2c, DW, R/W */ + +#define FIFO_DATA_LOW 0x30 /* BASE+30, B/W/DW, R/W */ +#define FIFO_DATA_HIGH 0x32 /* BASE+32, B/W, R/W */ +#define BM_START_ADR 0x34 /* BASE+34, DW, R/W */ + +#define BM_CNT 0x38 /* BASE+38, DW, R/W */ +# define BM_COUNT_MASK 0x0001ffffUL +# define SGTEND BIT(31) /* Last SGT marker */ -#define SGT_ADR 0x3c /* BASE+3c, DW, R/W */ -#define WAIT_REG 0x40 /* Bi only */ +#define SGT_ADR 0x3c /* BASE+3c, DW, R/W */ +#define WAIT_REG 0x40 /* Bi only */ -#define SCSI_EXECUTE_PHASE 0x40 /* BASE+40, W, R */ +#define SCSI_EXECUTE_PHASE 0x40 /* BASE+40, W, R */ # define COMMAND_PHASE BIT(0) # define DATA_IN_PHASE BIT(1) # define DATA_OUT_PHASE BIT(2) @@ -280,14 +298,14 @@ # define MSGIN_04_VALID BIT(13) # define AUTOSCSI_BUSY BIT(15) -#define SCSI_CSB_IN 0x42 /* BASE+42, B, R */ +#define SCSI_CSB_IN 0x42 /* BASE+42, B, R */ -#define SCSI_MSG_OUT 0x44 /* BASE+44, DW, R/W */ +#define SCSI_MSG_OUT 0x44 /* BASE+44, DW, R/W */ # define MSGOUT_COUNT_MASK (BIT(0)|BIT(1)) -# define MV_VALID BIT(7) +# define MSGOUT_VALID BIT(7) -#define SEL_TIME_OUT 0x48 /* BASE+48, W, R/W */ -#define SAVED_SACK_CNT 0x4c /* BASE+4c, DW, R */ +#define SEL_TIME_OUT 0x48 /* BASE+48, W, R/W */ +#define SAVED_SACK_CNT 0x4c /* BASE+4c, DW, R */ #define HTOSDATADELAY 0x50 /* BASE+50, B, R/W */ #define STOHDATADELAY 0x54 /* BASE+54, B, R/W */ @@ -299,21 +317,21 @@ /* indexed register */ /********************/ -#define CLOCK_DIV 0x00 /* BASE+08, IDX+00, B, R/W */ -# define CLOCK_2 BIT(0) /* MCLK/2 */ -# define CLOCK_4 BIT(1) /* MCLK/4 */ -# define PCICLK BIT(7) /* PCICLK (33MHz) */ +#define CLOCK_DIV 0x00 /* BASE+08, IDX+00, B, R/W */ +# define CLOCK_2 BIT(0) /* MCLK/2 */ +# define CLOCK_4 BIT(1) /* MCLK/4 */ +# define PCICLK BIT(7) /* PCICLK (33MHz) */ -#define TERM_PWR_CONTROL 0x01 /* BASE+08, IDX+01, B, R/W */ +#define TERM_PWR_CONTROL 0x01 /* BASE+08, IDX+01, B, R/W */ # define BPWR BIT(0) # define SENSE BIT(1) /* Read Only */ -#define EXT_PORT_DDR 0x02 /* BASE+08, IDX+02, B, R/W */ -#define EXT_PORT 0x03 /* BASE+08, IDX+03, B, R/W */ -# define LED_ON 0 -# define LED_OFF 1 +#define EXT_PORT_DDR 0x02 /* BASE+08, IDX+02, B, R/W */ +#define EXT_PORT 0x03 /* BASE+08, IDX+03, B, R/W */ +# define LED_ON (0) +# define LED_OFF BIT(0) -#define IRQ_SELECT 0x04 /* BASE+08, IDX+04, W, R/W */ +#define IRQ_SELECT 0x04 /* BASE+08, IDX+04, W, R/W */ # define IRQSELECT_RESELECT_IRQ BIT(0) # define IRQSELECT_PHASE_CHANGE_IRQ BIT(1) # define IRQSELECT_SCSIRESET_IRQ BIT(2) @@ -326,32 +344,35 @@ # define IRQSELECT_BMCNTERR_IRQ BIT(9) # define IRQSELECT_AUTO_SCSI_SEQ_IRQ BIT(10) -#define OLD_SCSI_PHASE 0x05 /* BASE+08, IDX+05, B, R */ +#define OLD_SCSI_PHASE 0x05 /* BASE+08, IDX+05, B, R */ # define OLD_MSG BIT(0) # define OLD_IO BIT(1) # define OLD_CD BIT(2) # define OLD_BUSY BIT(3) -#define FIFO_FULL_SHLD_COUNT 0x06 /* BASE+08, IDX+06, B, R/W */ -#define FIFO_EMPTY_SHLD_COUNT 0x07 /* BASE+08, IDX+07, B, R/W */ +#define FIFO_FULL_SHLD_COUNT 0x06 /* BASE+08, IDX+06, B, R/W */ +#define FIFO_EMPTY_SHLD_COUNT 0x07 /* BASE+08, IDX+07, B, R/W */ -#define EXP_ROM_CONTROL 0x08 /* BASE+08, IDX+08, B, R/W */ +#define EXP_ROM_CONTROL 0x08 /* BASE+08, IDX+08, B, R/W */ /* external ROM control */ +# define ROM_WRITE_ENB BIT(0) +# define IO_ACCESS_ENB BIT(1) +# define ROM_ADR_CLEAR BIT(2) -#define EXP_ROM_ADRL 0x09 /* BASE+08, IDX+09, W, R/W */ +#define EXP_ROM_ADR 0x09 /* BASE+08, IDX+09, W, R/W */ #define EXP_ROM_DATA 0x0a /* BASE+08, IDX+0a, B, R/W */ -#define CHIP_MODE 0x0b /* Bi only */ -# define OEM0 BIT(1) -# define OEM1 BIT(2) -# define OPTB BIT(3) -# define OPTC BIT(4) -# define OPTD BIT(5) -# define OPTE BIT(6) -# define OPTF BIT(7) +#define CHIP_MODE 0x0b /* BASE+08, IDX+0b, B, R */ /* NinjaSCSI-32Bi only */ +# define OEM0 BIT(1) /* OEM select */ /* 00=I-O DATA, 01=KME, 10=Workbit, 11=Ext ROM */ +# define OEM1 BIT(2) /* OEM select */ +# define OPTB BIT(3) /* KME mode select */ +# define OPTC BIT(4) /* KME mode select */ +# define OPTD BIT(5) /* KME mode select */ +# define OPTE BIT(6) /* KME mode select */ +# define OPTF BIT(7) /* Power management */ -#define MISC_WR 0x0c /* BASE+08, IDX+0c, W, R/W */ -#define MISC_RD 0x0c +#define MISC_WR 0x0c /* BASE+08, IDX+0c, W, R/W */ +#define MISC_RD 0x0c # define SCSI_DIRECTION_DETECTOR_SELECT BIT(0) # define SCSI2_HOST_DIRECTION_VALID BIT(1) /* Read only */ # define HOST2_SCSI_DIRECTION_VALID BIT(2) /* Read only */ @@ -362,7 +383,7 @@ # define MISC_MABORT_MASK BIT(7) # define BMSTOP_CHANGE2_NONDATA_PHASE BIT(8) -#define BM_CYCLE 0x0d /* BASE+08, IDX+0d, B, R/W */ +#define BM_CYCLE 0x0d /* BASE+08, IDX+0d, B, R/W */ # define BM_CYCLE0 BIT(0) # define BM_CYCLE1 BIT(1) # define BM_FRAME_ASSERT_TIMING BIT(2) @@ -373,20 +394,26 @@ # define MEMRD_CMD1 BIT(7) -#define SREQ_EDGH 0x0e /* BASE+08, IDX+0e, B, W */ +#define SREQ_EDGH 0x0e /* BASE+08, IDX+0e, B, W */ # define SREQ_EDGH_SELECT BIT(0) -#define UP_CNT 0x0f /* BASE+08, IDX+0f, B, W */ -#define CFG_CMD_STR 0x10 /* BASE+08, IDX+10, W, R */ -#define CFG_LATE_CACHE 0x11 /* BASE+08, IDX+11, W, R/W */ -#define CFG_BASE_ADR_1 0x12 /* BASE+08, IDX+12, W, R */ -#define CFG_BASE_ADR_2 0x13 /* BASE+08, IDX+13, W, R */ -#define CFG_INLINE 0x14 /* BASE+08, IDX+14, W, R */ - -#define SERIAL_ROM_CTL 0x15 /* BASE+08, IDX+15, B, R */ -# define SCL BIT(0) -# define ENA BIT(1) -# define SDA BIT(2) +#define UP_CNT 0x0f /* BASE+08, IDX+0f, B, W */ /* For hardware testing. Don't use it. */ +# define REQCNT_UP BIT(0) +# define ACKCNT_UP BIT(1) +# define BMADR_UP BIT(4) +# define BMCNT_UP BIT(5) +# define SGT_CNT_UP BIT(7) + +#define CFG_CMD_STR 0x10 /* BASE+08, IDX+10, W, R */ +#define CFG_LATE_CACHE 0x11 /* BASE+08, IDX+11, W, R/W */ +#define CFG_BASE_ADR_1 0x12 /* BASE+08, IDX+12, W, R */ +#define CFG_BASE_ADR_2 0x13 /* BASE+08, IDX+13, W, R */ +#define CFG_INLINE 0x14 /* BASE+08, IDX+14, W, R */ + +#define SERIAL_ROM_CTL 0x15 /* BASE+08, IDX+15, B, R */ +# define SROM_CTL BIT(0) +# define SROM_ENABLE BIT(1) +# define SROM_DATA BIT(2) #define FIFO_HST_POINTER 0x16 /* BASE+08, IDX+16, B, R/W */ #define SREQ_DELAY 0x17 /* BASE+08, IDX+17, B, R/W */ @@ -425,5 +452,239 @@ #define BUSPHASE_STATUS ( BUSMON_STATUS & BUSMON_PHASE_MASK ) #define BUSPHASE_SELECT ( BUSMON_SEL | BUSMON_IO ) -#endif _NSP32_H + +/************************************************************************ + * structure for DMA/Scatter Gather list + */ +#define NSP32_SG_SIZE SG_ALL + +/* All values must be little endian */ +typedef struct _nsp32_sgtable { + u32_le addr; /* transfer address */ + u32_le len; /* transfer length. BIT(31) is for SGTEND mark */ +} __attribute__ ((packed)) nsp32_sgtable; + +/* All values must be little endian */ +typedef struct _nsp32_sglun { + nsp32_sgtable sgt[NSP32_SG_SIZE+1]; /* SG table */ +} __attribute__ ((packed)) nsp32_sglun; +#define NSP32_SG_TABLE_SIZE (sizeof(nsp32_sgtable) * NSP32_SG_SIZE * MAX_TARGET * MAX_LUN) + +/* Auto parameter mode memory map. */ +/* All values must be little endian. */ +typedef struct _nsp32_autoparam { + u8 cdb[4 * 0x10]; /* SCSI Command */ + u32_le msgout; /* outgoing messages */ + u8 syncreg; /* sync register value */ + u8 ackwidth; /* ack width register value */ + u8 target_id; /* target/host device id */ + u8 sample_reg; /* hazard killer sampling rate */ + u16_le command_control; /* command control register */ + u16_le transfer_control; /* transfer control register */ + u32_le sgt_pointer; /* SG table physical address for DMA */ + u32_le dummy[2]; +} __attribute__ ((packed)) nsp32_autoparam; /* must be packed struct */ + +/* + * host data structure + */ +/* message in/out buffer */ +#define MSGOUTBUF_MAX 20 +#define MSGINBUF_MAX 20 + +/* flag for trans_method */ +#define NSP32_TRANSFER_BUSMASTER BIT(0) +#define NSP32_TRANSFER_MMIO BIT(1) /* Not supported yet */ +#define NSP32_TRANSFER_PIO BIT(2) /* Not supported yet */ + + +/* + * structure for connected LUN dynamic data + * + * Note: Currently tagged queuing is disabled, each nsp32_lunt holds + * one SCSI command and one state. + */ +#define DISCPRIV_OK BIT(0) /* DISCPRIV Enable mode */ +#define MSGIN03 BIT(1) /* Auto Msg In 03 Flag */ + +typedef struct _nsp32_lunt { + Scsi_Cmnd *SCpnt; /* Current Handling Scsi_Cmnd */ + unsigned long save_datp; /* Save Data Pointer - saved position from initial address */ + int msgin03; /* auto msg in 03 flag */ + unsigned int sg_num; /* Total number of SG entries */ + int cur_entry; /* Current SG entry number */ + nsp32_sglun *sglun; /* sg table per lun */ + dma_addr_t sglun_paddr; /* sglun physical address */ +} nsp32_lunt; + + +/* + * SCSI TARGET/LUN definition + */ +#define NSP32_HOST_SCSIID 7 /* SCSI initiator is everytime defined as 7 */ +#define MAX_TARGET 8 +#define MAX_LUN 8 /* XXX: In SPI3, max number of LUN is 64. */ + + +typedef struct _nsp32_sync_table { + unsigned char period_num; /* period number */ + unsigned char ackwidth; /* ack width designated by period */ + unsigned char start_period; /* search range - start period */ + unsigned char end_period; /* search range - end period */ + unsigned char sample_rate; /* hazard killer parameter */ +} nsp32_sync_table; + + +/* + * structure for target device static data + */ +/* flag for nsp32_target.sync_flag */ +#define SDTR_NONE 0 /* initial state */ +#define SDTR_INITIATOR BIT(0) /* sending SDTR from initiator */ +#define SDTR_TARGET BIT(1) /* sending SDTR from target */ +#define SDTR_DONE BIT(2) /* exchanging SDTR has been processed */ + +/* syncronous period value for nsp32_target.config_max */ +#define FAST5M 0x32 +#define FAST10M 0x19 +#define ULTRA20M 0x0c + +/* flag for nsp32_target.{sync_offset, period} */ +#define ASYNC_OFFSET 0 /* asynchronous transfer */ +#define MAX_OFFSET 0xf /* synchronous transfer max offset */ + +/* syncreg: + bit:07 06 05 04 03 02 01 00 + ---PERIOD-- ---OFFSET-- */ +#define TO_SYNCREG(period, offset) (((period) & 0x0f) << 4 | ((offset) & 0x0f)) + +typedef struct _nsp32_target { + unsigned char syncreg; /* value for SYNCREG */ + unsigned char ackwidth; /* value for ACKWIDTH */ + unsigned char period; /* sync period (0-255) */ + unsigned char offset; /* sync offset (0-15) */ + int sync_flag; /* SDTR_*, 0 */ + int limit_entry; /* max speed limit entry designated + by EEPROM configuration */ + unsigned char sample_reg; /* SREQ hazard killer register */ +} nsp32_target; + +typedef struct _nsp32_hw_data { + int IrqNumber; + int BaseAddress; + int NumAddress; + unsigned long MmioAddress; +#define NSP32_MMIO_OFFSET 0x0800 + unsigned long MmioLength; + + Scsi_Cmnd *CurrentSC; + + struct pci_dev *Pci; + const struct pci_device_id *pci_devid; + struct Scsi_Host *Host; + spinlock_t Lock; + + char info_str[100]; + + /* allocated memory region */ + nsp32_sglun *sg_list; /* sglist virtuxal address */ + dma_addr_t sg_paddr; /* physical address of hw_sg_table */ + nsp32_autoparam *autoparam; /* auto parameter transfer region */ + dma_addr_t auto_paddr; /* physical address of autoparam */ + int cur_entry; /* current sgt entry */ + + /* target/LUN */ + nsp32_lunt *cur_lunt; /* Current connected LUN table */ + nsp32_lunt lunt[MAX_TARGET][MAX_LUN]; /* All LUN table */ + + nsp32_target *cur_target; /* Current connected SCSI ID */ + nsp32_target target[MAX_TARGET]; /* SCSI ID */ + int cur_id; /* Current connected target ID */ + int cur_lun; /* Current connected target LUN */ + + /* behavior setting parameters */ + int trans_method; /* transfer method flag */ + int resettime; /* Reset time */ + int clock; /* clock dividing flag */ + nsp32_sync_table *synct; /* sync_table determined by clock */ + int syncnum; /* the max number of synct element */ + + /* message buffer */ + unsigned char msgoutbuf[MSGOUTBUF_MAX]; /* msgout buffer */ + char msgout_len; /* msgoutbuf length */ + unsigned char msginbuf [MSGINBUF_MAX]; /* megin buffer */ + char msgin_len; /* msginbuf length */ + +#ifdef CONFIG_PM + u32 PciState[16]; /* save PCI state to this area */ +#endif +} nsp32_hw_data; + +/* + * TIME definition + */ +#define RESET_HOLD_TIME 10000 /* reset time in us (SCSI-2 says the + minimum is 25us) */ +#define SEL_TIMEOUT_TIME 10000 /* 250ms defined in SCSI specification + (25.6us/1unit) */ +#define ARBIT_TIMEOUT_TIME 100 /* 100us */ +#define REQSACK_TIMEOUT_TIME 10000 /* max wait time for REQ/SACK assertion + or negation, 10000us == 10ms */ + +/************************************************************************** + * Compatibility functions + */ + +/* for Kernel 2.4 */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) +# define scsi_register_host(template) scsi_register_module(MODULE_SCSI_HA, template) +# define scsi_unregister_host(template) scsi_unregister_module(MODULE_SCSI_HA, template) +# define scsi_host_put(host) scsi_unregister(host) +# define pci_name(pci_dev) ((pci_dev)->slot_name) + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23)) +typedef void irqreturn_t; +# define IRQ_NONE /* */ +# define IRQ_HANDLED /* */ +# define IRQ_RETVAL(x) /* */ +#endif + +/* This is ad-hoc version of scsi_host_get_next() */ +static inline struct Scsi_Host *scsi_host_get_next(struct Scsi_Host *host) +{ + if (host == NULL) { + return scsi_hostlist; + } else { + return host->next; + } +} + +/* This is ad-hoc version of scsi_host_hn_get() */ +static inline struct Scsi_Host *scsi_host_hn_get(unsigned short hostno) +{ + struct Scsi_Host *host; + + for (host = scsi_host_get_next(NULL); host != NULL; + host = scsi_host_get_next(host)) { + if (host->host_no == hostno) { + break; + } + } + + return host; +} + +/* host spin lock */ +# define HOST_LOCK (&io_request_lock) +#endif + +/* for Kernel 2.6 */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) +# define __devinitdata /* */ + +/* host spin lock */ +# define HOST_LOCK (data->Host->host_lock) +#endif + +#endif /* _NSP32_H */ /* end */ Index: drivers/scsi/nsp32_debug.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/nsp32_debug.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/nsp32_debug.c 22 Jul 2004 19:50:03 -0000 1.1 +++ drivers/scsi/nsp32_debug.c 4 Aug 2004 01:29:36 -0000 1.2 @@ -1,5 +1,5 @@ /* - * Workbit NinjaSCSI-32Bi/UDE PCI/Cardbus SCSI Host Bus Adapter driver + * Workbit NinjaSCSI-32Bi/UDE PCI/CardBus SCSI Host Bus Adapter driver * Debug routine * * This software may be used and distributed according to the terms of @@ -85,22 +85,22 @@ static void print_commandk (unsigned char *command) { - int i,s; + int i, size; // printk(KERN_DEBUG); print_opcodek(command[0]); - /*printk(KERN_DEBUG __func__ " ");*/ + /*printk(KERN_DEBUG "%s ", __FUNCTION__);*/ if ((command[0] >> 5) == 6 || (command[0] >> 5) == 7 ) { - s = 12; /* vender specific */ + size = 12; /* vender specific */ } else { - s = COMMAND_SIZE(command[0]); + size = COMMAND_SIZE(command[0]); } for ( i = 1; i < s; ++i) { printk("%02x ", command[i]); } - switch (s) { + switch (size) { case 6: printk("LBA=%d len=%d", (((unsigned int)command[1] & 0x0f) << 16) | @@ -137,9 +137,9 @@ printk("\n"); } -static void show_command(Scsi_Cmnd *ptr) +static void show_command(Scsi_Cmnd *SCpnt) { - print_commandk(ptr->cmnd); + print_commandk(SCpnt->cmnd); } static void show_busphase(unsigned char stat) @@ -260,3 +260,45 @@ } } +/* + * Byte dumper + * + * ptr: start address + * offset: offset value for address section + * size: dump size in byte + */ +static void nsp32_byte_dump(void *ptr, int offset, int size) +{ + unsigned char *tmp = ptr; + int pos; + + if (size == 0) { + return; + } + + pos = 0; + while(pos < size) { + /* address */ + if (pos % 16 == 0) { + printk(/*KERN_DEBUG*/ "%08x:", pos + offset); + } + + /* half separator */ + if (pos % 16 == 8) { + printk(" -"); + } + + printk(" %02x", tmp[pos]); + + /* Don't print "\n" at last line. + Because we can get one more "\n". */ + if ((pos % 16 == 15) && (pos + 1 != size)) { + printk("\n"); + } + + pos ++; + } + printk("\n"); +} + +/* end */ Index: drivers/scsi/nsp32_io.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/nsp32_io.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/nsp32_io.h 22 Jul 2004 19:50:05 -0000 1.1 +++ drivers/scsi/nsp32_io.h 4 Aug 2004 01:29:36 -0000 1.2 @@ -1,5 +1,5 @@ /* - * Workbit NinjaSCSI-32Bi/UDE PCI/Cardbus SCSI Host Bus Adapter driver + * Workbit NinjaSCSI-32Bi/UDE PCI/CardBus SCSI Host Bus Adapter driver * I/O routine * * This software may be used and distributed according to the terms of @@ -22,30 +22,30 @@ return inb(base + index); } -static inline void nsp32_write2(unsigned int base, - unsigned int index, +static inline void nsp32_write2(unsigned int base, + unsigned int index, unsigned short val) { - outw(cpu_to_le16(val), (base + index)); + outw(val, (base + index)); } static inline unsigned short nsp32_read2(unsigned int base, unsigned int index) { - return le16_to_cpu(inw(base + index)); + return inw(base + index); } static inline void nsp32_write4(unsigned int base, unsigned int index, unsigned long val) { - outl(cpu_to_le32(val), (base + index)); + outl(val, (base + index)); } static inline unsigned long nsp32_read4(unsigned int base, unsigned int index) { - return le32_to_cpu(inl(base + index)); + return inl(base + index); } /*==============================================*/ @@ -58,7 +58,7 @@ ptr = (unsigned char *)(base + NSP32_MMIO_OFFSET + index); - *ptr = val; + writeb(val, ptr); } static inline unsigned char nsp32_mmio_read1(unsigned long base, @@ -68,18 +68,18 @@ ptr = (unsigned char *)(base + NSP32_MMIO_OFFSET + index); - return *ptr; + return readb(ptr); } -static inline void nsp32_mmio_write2(unsigned long base, - unsigned int index, +static inline void nsp32_mmio_write2(unsigned long base, + unsigned int index, unsigned short val) { volatile unsigned short *ptr; ptr = (unsigned short *)(base + NSP32_MMIO_OFFSET + index); - *ptr = cpu_to_le16(val); + writew(cpu_to_le16(val), ptr); } static inline unsigned short nsp32_mmio_read2(unsigned long base, @@ -87,11 +87,9 @@ { volatile unsigned short *ptr; - //printk(__FUNCTION__ "\n"); - ptr = (unsigned short *)(base + NSP32_MMIO_OFFSET + index); - return le16_to_cpu(*ptr); + return le16_to_cpu(readw(ptr)); } static inline void nsp32_mmio_write4(unsigned long base, @@ -102,7 +100,7 @@ ptr = (unsigned long *)(base + NSP32_MMIO_OFFSET + index); - *ptr = cpu_to_le32(val); + writel(cpu_to_le32(val), ptr); } static inline unsigned long nsp32_mmio_read4(unsigned long base, @@ -110,16 +108,12 @@ { volatile unsigned long *ptr; - //printk(__FUNCTION__ "\n"); - ptr = (unsigned long *)(base + NSP32_MMIO_OFFSET + index); - return le32_to_cpu(*ptr); + return le32_to_cpu(readl(ptr)); } - -/*=============================================*/ - +/*==============================================*/ static inline unsigned char nsp32_index_read1(unsigned int base, unsigned int reg) @@ -132,7 +126,7 @@ unsigned int reg, unsigned char val) { - outb(reg, base + INDEX_REG); + outb(reg, base + INDEX_REG ); outb(val, base + DATA_REG_LOW); } @@ -140,15 +134,15 @@ unsigned int reg) { outb(reg, base + INDEX_REG); - return le16_to_cpu(inw(base + DATA_REG_LOW)); + return inw(base + DATA_REG_LOW); } -static inline void nsp32_index_write2(unsigned int base, - unsigned int reg, +static inline void nsp32_index_write2(unsigned int base, + unsigned int reg, unsigned short val) { - outb(reg, base + INDEX_REG); - outw(cpu_to_le16(val), base + DATA_REG_LOW); + outb(reg, base + INDEX_REG ); + outw(val, base + DATA_REG_LOW); } static inline unsigned long nsp32_index_read4(unsigned int base, @@ -157,8 +151,8 @@ unsigned long h,l; outb(reg, base + INDEX_REG); - l = le16_to_cpu(inw(base + DATA_REG_LOW)); - h = le16_to_cpu(inw(base + DATA_REG_HI )); + l = inw(base + DATA_REG_LOW); + h = inw(base + DATA_REG_HI ); return ((h << 16) | l); } @@ -170,15 +164,14 @@ unsigned long h,l; h = (val & 0xffff0000) >> 16; - l = (val & 0x0000ffff) >> 0; + l = (val & 0x0000ffff) >> 0; - outb(reg, base + INDEX_REG); - outw(cpu_to_le16(l), base + DATA_REG_LOW); - outw(cpu_to_le16(h), base + DATA_REG_HI); + outb(reg, base + INDEX_REG ); + outw(l, base + DATA_REG_LOW); + outw(h, base + DATA_REG_HI ); } - -/* ===================================*/ +/*==============================================*/ static inline unsigned char nsp32_mmio_index_read1(unsigned int base, unsigned int reg) @@ -188,13 +181,12 @@ index_ptr = (unsigned short *)(base + NSP32_MMIO_OFFSET + INDEX_REG); data_ptr = (unsigned short *)(base + NSP32_MMIO_OFFSET + DATA_REG_LOW); - *index_ptr = reg; - - return ((*data_ptr) & 0xff); + writeb(reg, index_ptr); + return readb(data_ptr); } -static inline void nsp32_mmio_index_write1(unsigned int base, - unsigned int reg, +static inline void nsp32_mmio_index_write1(unsigned int base, + unsigned int reg, unsigned char val) { volatile unsigned short *index_ptr, *data_ptr; @@ -202,8 +194,8 @@ index_ptr = (unsigned short *)(base + NSP32_MMIO_OFFSET + INDEX_REG); data_ptr = (unsigned short *)(base + NSP32_MMIO_OFFSET + DATA_REG_LOW); - *index_ptr = reg; - *data_ptr = (unsigned short)val; + writeb(reg, index_ptr); + writeb(val, data_ptr ); } static inline unsigned short nsp32_mmio_index_read2(unsigned int base, @@ -214,13 +206,12 @@ index_ptr = (unsigned short *)(base + NSP32_MMIO_OFFSET + INDEX_REG); data_ptr = (unsigned short *)(base + NSP32_MMIO_OFFSET + DATA_REG_LOW); - *index_ptr = reg; - - return le16_to_cpu(*data_ptr); + writeb(reg, index_ptr); + return le16_to_cpu(readw(data_ptr)); } -static inline void nsp32_mmio_index_write2(unsigned int base, - unsigned int reg, +static inline void nsp32_mmio_index_write2(unsigned int base, + unsigned int reg, unsigned short val) { volatile unsigned short *index_ptr, *data_ptr; @@ -228,34 +219,33 @@ index_ptr = (unsigned short *)(base + NSP32_MMIO_OFFSET + INDEX_REG); data_ptr = (unsigned short *)(base + NSP32_MMIO_OFFSET + DATA_REG_LOW); - *index_ptr = reg; - *data_ptr = val; + writeb(reg, index_ptr); + writew(cpu_to_le16(val), data_ptr ); } -/*-------------------------------------------------------------------*/ +/*==============================================*/ -static inline void nsp32_multi_read4(unsigned int BaseAddr, - unsigned int Register, +static inline void nsp32_multi_read4(unsigned int base, + unsigned int reg, void *buf, unsigned long count) { - insl(BaseAddr + Register, buf, count); + insl(base + reg, buf, count); } static inline void nsp32_fifo_read(unsigned int base, void *buf, unsigned long count) { - //DEBUG(0, __FUNCTION__ "() buf=0x%p, count=0x%lx*4\n", buf, count); nsp32_multi_read4(base, FIFO_DATA_LOW, buf, count); } -static inline void nsp32_multi_write4(unsigned int BaseAddr, - unsigned int Register, +static inline void nsp32_multi_write4(unsigned int base, + unsigned int reg, void *buf, unsigned long count) { - outsl(BaseAddr + Register, buf, count); + outsl(base + reg, buf, count); } static inline void nsp32_fifo_write(unsigned int base, @@ -265,5 +255,5 @@ nsp32_multi_write4(base, FIFO_DATA_LOW, buf, count); } -#endif _NSP32_IO_H +#endif /* _NSP32_IO_H */ /* end */ Index: drivers/scsi/osst.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/osst.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/osst.c 22 Jul 2004 19:50:05 -0000 1.1 +++ drivers/scsi/osst.c 4 Aug 2004 01:29:36 -0000 1.2 @@ -16,15 +16,15 @@ Copyright 1992 - 2000 Kai Makisara email Kai.Makisara@metla.fi - $Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/osst.c,v 1.1 2004/07/22 19:50:05 joff Exp $ + $Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/osst.c,v 1.2 2004/08/04 01:29:36 joff Exp $ Microscopic alterations - Rik Ling, 2000/12/21 Last modified: Wed Feb 2 22:04:05 2000 by makisara@kai.makisara.local Some small formal changes - aeb, 950809 */ -static const char * cvsid = "$Id: osst.c,v 1.1 2004/07/22 19:50:05 joff Exp $"; -const char * osst_version = "0.9.10"; +static const char * cvsid = "$Id: osst.c,v 1.2 2004/08/04 01:29:36 joff Exp $"; +const char * osst_version = "0.9.14"; /* The "failure to reconnect" firmware bug */ #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/ @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -75,9 +76,8 @@ #include "constants.h" -static int buffer_kbs = 0; +static int max_dev = 0; static int write_threshold_kbs = 0; -static int max_buffers = 0; static int max_sg_segs = 0; #ifdef MODULE @@ -85,18 +85,16 @@ MODULE_DESCRIPTION("OnStream SCSI Tape Driver"); MODULE_LICENSE("GPL"); -MODULE_PARM(buffer_kbs, "i"); +MODULE_PARM(max_dev, "i"); MODULE_PARM(write_threshold_kbs, "i"); -MODULE_PARM(max_buffers, "i"); MODULE_PARM(max_sg_segs, "i"); #else static struct osst_dev_parm { char *name; int *val; } parms[] __initdata = { - { "buffer_kbs", &buffer_kbs }, + { "max_dev", &max_dev }, { "write_threshold_kbs", &write_threshold_kbs }, - { "max_buffers", &max_buffers }, { "max_sg_segs", &max_sg_segs } }; #endif @@ -117,11 +115,16 @@ // #define OSST_INJECT_ERRORS 1 #endif -#define MAX_RETRIES 0 +#define MAX_RETRIES 2 +#define MAX_READ_RETRIES 0 #define MAX_WRITE_RETRIES 0 -#define MAX_READY_RETRIES 5 +#define MAX_READY_RETRIES 0 #define NO_TAPE NOT_READY +#define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1) +#define OSST_WAIT_WRITE_COMPLETE (HZ / 12) +#define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2) + #define OSST_TIMEOUT (200 * HZ) #define OSST_LONG_TIMEOUT (1800 * HZ) @@ -137,6 +140,7 @@ static int osst_write_threshold = OSST_WRITE_THRESHOLD; static int osst_max_buffers = OSST_MAX_BUFFERS; static int osst_max_sg_segs = OSST_MAX_SG; +static int osst_max_dev = OSST_MAX_TAPES; static OS_Scsi_Tape **os_scsi_tapes = NULL; static OSST_buffer **osst_buffers = NULL; @@ -539,8 +543,6 @@ STp->first_frame_position); goto err_out; } - STp->frame_in_buffer = 1; - if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) { if (!quiet) #if DEBUG @@ -567,12 +569,14 @@ } if (aux->frame_type == OS_FRAME_TYPE_EOD) { STps->eof = ST_EOD_1; + STp->frame_in_buffer = 1; } if (aux->frame_type == OS_FRAME_TYPE_DATA) { blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt); blk_sz = ntohl(aux->dat.dat_list[0].blk_sz); STp->buffer->buffer_bytes = blk_cnt * blk_sz; STp->buffer->read_pointer = 0; + STp->frame_in_buffer = 1; /* See what block size was used to write file */ if (STp->block_size != blk_sz && blk_sz > 0) { @@ -599,18 +603,23 @@ /* * Wait for the unit to become Ready */ -static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout) +static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout, int initial_delay) { unsigned char cmd[MAX_COMMAND_SIZE]; Scsi_Request * SRpnt; long startwait = jiffies; #if DEBUG int dbg = debugging; - int dev = TAPE_NR(STp->devt); + int dev = TAPE_NR(STp->devt); printk(OSST_DEB_MSG "osst%d:D: Reached onstream wait ready\n", dev); #endif + if (initial_delay > 0) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(initial_delay); + } + memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; @@ -722,10 +731,10 @@ { int retval; - osst_wait_ready(STp, aSRpnt, 15 * 60); /* TODO - can this catch a write error? */ + osst_wait_ready(STp, aSRpnt, 15 * 60, 0); /* TODO - can this catch a write error? */ retval = osst_set_frame_position(STp, aSRpnt, frame, 0); if (retval) return (retval); - osst_wait_ready(STp, aSRpnt, 15 * 60); + osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE); return (osst_get_frame_position(STp, aSRpnt)); } @@ -738,6 +747,7 @@ Scsi_Request * SRpnt; int result = 0; + int delay = OSST_WAIT_WRITE_COMPLETE; #if DEBUG int dev = TAPE_NR(STp->devt); @@ -751,12 +761,17 @@ SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_WRITE_RETRIES, TRUE); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); - - if ((STp->buffer)->syscall_result) - result = osst_write_error_recovery(STp, aSRpnt, 0); - - result |= osst_wait_ready(STp, aSRpnt, 5 * 60); + if (STp->buffer->syscall_result) { + if ((SRpnt->sr_sense_buffer[2] & 0x0f) == 2 && SRpnt->sr_sense_buffer[12] == 4) { + if (SRpnt->sr_sense_buffer[13] == 8) { + delay = OSST_WAIT_LONG_WRITE_COMPLETE; + } + } else + result = osst_write_error_recovery(STp, aSRpnt, 0); + } + result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay); STp->ps[STp->partition].rw = OS_WRITING_COMPLETE; + return (result); } @@ -833,9 +848,6 @@ /* TODO: Error handling */ if (STp->poll) retval = osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout); -#if 0// DEBUG - printk ("osst_read: wait for frame returned %i\n", retval); -#endif memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = READ_6; @@ -847,7 +859,7 @@ printk(OSST_DEB_MSG "osst%d:D: Reading frame from OnStream tape\n", dev); #endif SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ, - STp->timeout, MAX_RETRIES, TRUE); + STp->timeout, MAX_READ_RETRIES, TRUE); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); @@ -903,7 +915,8 @@ #endif if (STps->rw != ST_READING) { /* Initialize read operation */ - if (STps->rw == ST_WRITING) { + if (STps->rw == ST_WRITING || STp->dirty) { + STp->write_type = OS_WRITE_DATA; osst_flush_write_buffer(STp, aSRpnt); osst_flush_drive_buffer(STp, aSRpnt); } @@ -921,7 +934,7 @@ #if DEBUG printk(OSST_DEB_MSG "osst%d:D: Start Read Ahead on OnStream tape\n", dev); #endif - SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE); + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READ_RETRIES, TRUE); *aSRpnt = SRpnt; retval = STp->buffer->syscall_result; } @@ -940,6 +953,15 @@ position; /* + * If we want just any frame (-1) and there is a frame in the buffer, return it + */ + if (frame_seq_number == -1 && STp->frame_in_buffer) { +#if DEBUG + printk(OSST_DEB_MSG "osst%d:D: Frame %d still in buffer\n", dev, STp->frame_seq_number); +#endif + return (STps->eof); + } + /* * Search and wait for the next logical tape frame */ while (1) { @@ -1092,6 +1114,7 @@ if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1; move /= (OS_DATA_SIZE / STp->block_size); } + if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1; #if DEBUG printk(OSST_DEB_MSG "osst%d:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n", @@ -1289,7 +1312,7 @@ cmd[8] = 32768 & 0xff; SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ, - STp->timeout, MAX_RETRIES, TRUE); + STp->timeout, MAX_READ_RETRIES, TRUE); if ((STp->buffer)->syscall_result || !SRpnt) { printk(KERN_ERR "osst%d:E: Failed to read frame back from OnStream buffer\n", dev); @@ -1329,7 +1352,7 @@ dev, new_frame+i, frame_seq_number+i); #endif osst_set_frame_position(STp, aSRpnt, new_frame + i, 0); - osst_wait_ready(STp, aSRpnt, 60); + osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE); osst_get_frame_position(STp, aSRpnt); SRpnt = * aSRpnt; @@ -1397,6 +1420,7 @@ if (SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 && (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8)) { /* in the process of becoming ready */ + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ / 10); continue; } @@ -1469,6 +1493,8 @@ osst_set_frame_position(STp, aSRpnt, frame + skip, 1); flag = 0; attempts--; + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ / 10); } if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */ #if DEBUG @@ -1529,6 +1555,7 @@ debugging = 0; } #endif + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ / 10); } printk(KERN_ERR "osst%d:E: Failed to find valid tape media\n", dev); @@ -1674,12 +1701,7 @@ dev, last_mark_ppos); return (-EIO); } - if (mt_op == MTBSFM) { - STp->frame_seq_number++; - STp->frame_in_buffer = 0; - STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); - } - return 0; + goto found; } #if DEBUG printk(OSST_DEB_MSG "osst%d:D: Reverting to scan filemark backwards\n", dev); @@ -1707,10 +1729,13 @@ return (-EIO); } } +found: if (mt_op == MTBSFM) { STp->frame_seq_number++; - STp->frame_in_buffer = 0; - STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); + STp->frame_in_buffer = 0; + STp->buffer->buffer_bytes = 0; + STp->buffer->read_pointer = 0; + STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); } return 0; } @@ -1763,8 +1788,10 @@ } if (mt_op == MTFSF) { STp->frame_seq_number++; - STp->frame_in_buffer = 0; - STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); + STp->frame_in_buffer = 0; + STp->buffer->buffer_bytes = 0; + STp->buffer->read_pointer = 0; + STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); } return 0; } @@ -1910,8 +1937,10 @@ } if (mt_op == MTFSF) { STp->frame_seq_number++; - STp->frame_in_buffer = 0; - STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); + STp->frame_in_buffer = 0; + STp->buffer->buffer_bytes = 0; + STp->buffer->read_pointer = 0; + STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); } return 0; } @@ -2011,7 +2040,7 @@ #if DEBUG printk(OSST_DEB_MSG "osst%d:D: Reached onstream write filler group %d\n", dev, where); #endif - osst_wait_ready(STp, aSRpnt, 60 * 5); + osst_wait_ready(STp, aSRpnt, 60 * 5, 0); osst_set_frame_position(STp, aSRpnt, where, 0); STp->write_type = OS_WRITE_FILLER; while (count--) { @@ -2037,7 +2066,7 @@ #if DEBUG printk(OSST_DEB_MSG "osst%d:D: Reached onstream write header group %d\n", dev, where); #endif - osst_wait_ready(STp, aSRpnt, 60 * 5); + osst_wait_ready(STp, aSRpnt, 60 * 5, 0); osst_set_frame_position(STp, aSRpnt, where, 0); STp->write_type = OS_WRITE_HEADER; while (count--) { @@ -2158,7 +2187,8 @@ if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) { if (osst_set_frame_position(STp, aSRpnt, ppos, 0)) printk(KERN_WARNING "osst%i:W: Couldn't position tape\n", dev); - if (osst_initiate_read (STp, aSRpnt)) { + osst_wait_ready(STp, aSRpnt, 60 * 15, 0); + if (osst_initiate_read(STp, aSRpnt)) { printk(KERN_WARNING "osst%i:W: Couldn't initiate read\n", dev); return 0; } @@ -2377,11 +2407,12 @@ static int osst_verify_position(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) { + int write_pass = STp->wrt_pass_cntr; int frame_position = STp->first_frame_position; - int frame_seq_numbr = STp->frame_seq_number; + int frame_seq_numbr = STp->frame_seq_number; int logical_blk_num = STp->logical_blk_num; - int halfway_frame = STp->frame_in_buffer; - int read_pointer = STp->buffer->read_pointer; + int halfway_frame = STp->frame_in_buffer; + int read_pointer = STp->buffer->read_pointer; int prev_mark_ppos = -1; int actual_mark_ppos, i, n; #if DEBUG @@ -2389,12 +2420,24 @@ printk(OSST_DEB_MSG "osst%d:D: Verify that the tape is really the one we think before writing\n", dev); #endif - osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0); - if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { + if (frame_position <= STp->first_data_ppos) { + /* check header match */ + if (!osst_analyze_headers(STp, aSRpnt) || + (write_pass != STp->wrt_pass_cntr)) { #if DEBUG - printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in verify_position\n", dev); + printk(OSST_DEB_MSG "osst%d:D: Couldn't match header in verify_position\n", dev); #endif - return (-EIO); + return (-EIO); + } + } else { + /* find preceding data frame of current write pass */ + osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0); + if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { +#if DEBUG + printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in verify_position\n", dev); +#endif + return (-EIO); + } } if (STp->linux_media_version >= 4) { for (i=0; ifilemark_cnt; i++) @@ -2671,7 +2714,7 @@ STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, SCSI_DATA_READ, - STp->timeout, MAX_READY_RETRIES, TRUE); + STp->timeout, MAX_RETRIES, TRUE); if (!SRpnt) { STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; return (-EBUSY); @@ -2692,7 +2735,7 @@ scmd[0] = READ_POSITION; STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, SCSI_DATA_READ, - STp->timeout, MAX_READY_RETRIES, TRUE); + STp->timeout, MAX_RETRIES, TRUE); if (!STp->buffer->syscall_result) memcpy (SRpnt->sr_sense_buffer, mysense, 16); } @@ -2764,7 +2807,7 @@ scmd[9] = 0x80; SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, SCSI_DATA_NONE, STp->long_timeout, - MAX_READY_RETRIES, TRUE); + MAX_RETRIES, TRUE); if (!SRpnt) return (-EBUSY); *aSRpnt = SRpnt; @@ -2777,7 +2820,7 @@ result = (-EIO); } if (pp != ppos) - osst_wait_ready(STp, aSRpnt, 5 * 60); + osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE); } while ((pp != ppos) && (pp = ppos)); STp->first_frame_position = STp->last_frame_position = ppos; STps->eof = ST_NOEOF; @@ -2787,7 +2830,29 @@ return result; } +static int osst_write_trailer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int leave_at_EOT) +{ + ST_partstat * STps = &(STp->ps[STp->partition]); + int result = 0; + + if (STp->write_type != OS_WRITE_NEW_MARK) { + /* true unless the user wrote the filemark for us */ + result = osst_flush_drive_buffer(STp, aSRpnt); + if (result < 0) goto out; + result = osst_write_filemark(STp, aSRpnt); + if (result < 0) goto out; + + if (STps->drv_file >= 0) + STps->drv_file++ ; + STps->drv_block = 0; + } + result = osst_write_eod(STp, aSRpnt); + osst_write_header(STp, aSRpnt, leave_at_EOT); + STps->eof = ST_FM; +out: + return result; +} /* osst versions of st functions - augmented and stripped to suit OnStream only */ @@ -2905,7 +2970,7 @@ result = (-EIO); } } - STps->drv_block = (-1); + STps->drv_block = (-1); /* FIXME - even if write recovery succeeds? */ } else { STp->first_frame_position++; @@ -2941,9 +3006,10 @@ return 0; STps = &(STp->ps[STp->partition]); - if (STps->rw == ST_WRITING) /* Writing */ + if (STps->rw == ST_WRITING || STp->dirty) { /* Writing */ + STp->write_type = OS_WRITE_DATA; return osst_flush_write_buffer(STp, aSRpnt); - + } if (STp->block_size == 0) return 0; @@ -3166,12 +3232,16 @@ if (STps->rw == ST_READING) { +#if DEBUG + printk(OSST_DEB_MSG "osst%d:D: Switching from read to write at file %d, block %d\n", dev, + STps->drv_file, STps->drv_block); +#endif retval = osst_flush_buffer(STp, &SRpnt, 0); if (retval) goto out; STps->rw = ST_IDLE; } - else if (STps->rw != ST_WRITING) { + if (STps->rw != ST_WRITING) { /* Are we totally rewriting this tape? */ if (!STp->header_ok || (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) || @@ -3524,9 +3594,19 @@ printk(OSST_DEB_MSG "osst%d:D: EOF up (%d). Left %d, needed %d.\n", dev, STps->eof, (STp->buffer)->buffer_bytes, count - total); #endif + /* force multiple of block size, note block_size may have been adjusted */ transfer = (((STp->buffer)->buffer_bytes < count - total ? (STp->buffer)->buffer_bytes : count - total)/ - STp->block_size) * STp->block_size; /* force multiple of block size */ + STp->block_size) * STp->block_size; + + if (transfer == 0) { + printk(KERN_WARNING + "osst%d:W: Nothing can be transfered, requested %d, tape block size (%d%c).\n", + dev, count, STp->block_size < 1024? + STp->block_size:STp->block_size/1024, + STp->block_size<1024?'b':'k'); + break; + } i = from_buffer(STp->buffer, buf, transfer); if (i) { retval = i; @@ -3553,7 +3633,7 @@ /* Change the eof state if no data from tape or buffer */ if (total == 0) { if (STps->eof == ST_FM_HIT) { - STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM; + STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM; STps->drv_block = 0; if (STps->drv_file >= 0) STps->drv_file++; @@ -3876,9 +3956,10 @@ } break; case MTWEOF: - if ( STps->rw == ST_WRITING && !(STp->device)->was_reset) + if ((STps->rw == ST_WRITING || STp->dirty) && !(STp->device)->was_reset) { + STp->write_type = OS_WRITE_DATA; ioctl_result = osst_flush_write_buffer(STp, &SRpnt); - else + } else ioctl_result = 0; #if DEBUG if (debugging) @@ -3961,8 +4042,8 @@ if (debugging) printk(OSST_DEB_MSG "osst%d:D: Spacing to end of recorded medium.\n", dev); #endif - osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0); - if (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0) { + if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) || + (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0)) { ioctl_result = -EIO; goto os_bypass; } @@ -4020,6 +4101,23 @@ break; case MTSETBLK: /* Set block length */ + if ((STps->drv_block == 0 ) && + !STp->dirty && + ((STp->buffer)->buffer_bytes == 0) && + ((arg & MT_ST_BLKSIZE_MASK) >= 512 ) && + ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) && + !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK)) ) { + /* + * Only allowed to change the block size if you opened the + * device at the beginning of a file before writing anything. + * Note, that when reading, changing block_size is futile, + * as the size used when writing overrides it. + */ + STp->block_size = (arg & MT_ST_BLKSIZE_MASK); + printk(KERN_INFO "osst%d:I: Block size set to %d bytes.\n", + dev, STp->block_size); + return 0; + } case MTSETDENSITY: /* Set tape density */ case MTSETDRVBUFFER: /* Set drive buffering */ case SET_DENS_AND_BLK: /* Set density and block size */ @@ -4027,11 +4125,11 @@ if (STp->dirty || (STp->buffer)->buffer_bytes != 0) return (-EIO); /* Not allowed if data in buffer */ if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) && - (arg & MT_ST_BLKSIZE_MASK) != 0 && - ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block || - (arg & MT_ST_BLKSIZE_MASK) > STp->max_block || - (arg & MT_ST_BLKSIZE_MASK) > osst_buffer_size)) { - printk(KERN_WARNING "osst%d:W: Illegal block size.\n", dev); + (arg & MT_ST_BLKSIZE_MASK) != 0 && + (arg & MT_ST_BLKSIZE_MASK) != STp->block_size ) { + printk(KERN_WARNING "osst%d:W: Illegal to set block size to %d%s.\n", + dev, (int)(arg & MT_ST_BLKSIZE_MASK), + (OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now"); return (-EINVAL); } return 0; /* FIXME silently ignore if block size didn't change */ @@ -4083,6 +4181,14 @@ if (cmd_in == MTEOM) STps->eof = ST_EOD; + else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) { + ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num-1); + STps->drv_block++; + STp->logical_blk_num++; + STp->frame_seq_number++; + STp->frame_in_buffer = 0; + STp->buffer->read_pointer = 0; + } else if (cmd_in == MTFSF) STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM; else if (chg_eof) @@ -4091,7 +4197,6 @@ if (cmd_in == MTOFFL || cmd_in == MTUNLOAD) STp->rew_at_close = 0; else if (cmd_in == MTLOAD) { -/* STp->rew_at_close = (MINOR(inode->i_rdev) & 0x80) == 0; FIXME */ for (i=0; i < ST_NBR_PARTITIONS; i++) { STp->ps[i].rw = ST_IDLE; STp->ps[i].last_block_valid = FALSE;/* FIXME - where else is this field maintained? */ @@ -4140,10 +4245,15 @@ STp->door_locked = ST_LOCK_FAILS; if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60)) - ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60); + ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE); } *aSRpnt = SRpnt; +#if DEBUG + printk(OSST_DEB_MSG "osst%d:D: Ioctl %s, ppos %d fseq %d lblk %d bytes %d file %d blk %d\n", dev, + ioctl_result?"fail":"success", STp->first_frame_position, STp->frame_seq_number, + STp->logical_blk_num, STp->buffer->buffer_bytes, STps->drv_file, STps->drv_block); +#endif return ioctl_result; } @@ -4263,7 +4373,7 @@ SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE); } - osst_wait_ready(STp, &SRpnt, (SRpnt->sr_sense_buffer[13]==1?15:3) * 60); + osst_wait_ready(STp, &SRpnt, (SRpnt->sr_sense_buffer[13]==1?15:3) * 60, 0); } if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 && (SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */ @@ -4410,7 +4520,7 @@ } } - if (osst_wait_ready(STp, &SRpnt, 15 * 60)) /* FIXME - not allowed with NOBLOCK */ + if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0)) /* FIXME - not allowed with NOBLOCK */ printk(KERN_INFO "osst%i:I: Device did not become Ready in open\n",dev); if ((STp->buffer)->syscall_result != 0) { @@ -4551,7 +4661,8 @@ STm = &(STp->modes[STp->current_mode]); STps = &(STp->ps[STp->partition]); - if ( STps->rw == ST_WRITING && !(STp->device)->was_reset) { + if ((STps->rw == ST_WRITING || STp->dirty) && !(STp->device)->was_reset) { + STp->write_type = OS_WRITE_DATA; result = osst_flush_write_buffer(STp, &SRpnt); if (result != 0 && result != (-ENOSPC)) goto out; @@ -4566,22 +4677,7 @@ dev, STp->nbr_waits, STp->nbr_finished); } #endif - if (STp->write_type != OS_WRITE_NEW_MARK) { - /* true unless the user wrote the filemark for us */ - result = osst_flush_drive_buffer(STp, &SRpnt); - if (result < 0) goto out; - result = osst_write_filemark(STp, &SRpnt); - if (result < 0) goto out; - - if (STps->drv_file >= 0) - STps->drv_file++ ; - STps->drv_block = 0; - } - result = osst_write_eod(STp, &SRpnt); - osst_write_header(STp, &SRpnt, !(STp->rew_at_close)); - - STps->eof = ST_FM; - + result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close)); #if DEBUG if (debugging) printk(OSST_DEB_MSG "osst%d:D: Buffer flushed, %d EOF(s) written\n", @@ -4592,7 +4688,7 @@ STps = &(STp->ps[STp->partition]); if (!STm->sysv || STps->rw != ST_READING) { if (STp->can_bsr) - result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */ + result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */ else if (STps->eof == ST_FM_HIT) { result = cross_eof(STp, &SRpnt, FALSE); if (result) { @@ -4607,7 +4703,7 @@ } else if ((STps->eof == ST_NOEOF && !(result = cross_eof(STp, &SRpnt, TRUE))) || - STps->eof == ST_FM_HIT) { + STps->eof == ST_FM_HIT) { if (STps->drv_file >= 0) STps->drv_file++; STps->drv_block = 0; @@ -4721,6 +4817,7 @@ #endif if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) { struct mtop mtc; + int auto_weof = 0; if (_IOC_SIZE(cmd_in) != sizeof(mtc)) { retval = (-EINVAL); @@ -4801,10 +4898,41 @@ } } - if (mtc.mt_op != MTNOP && mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM && - mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETBLK && - mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART) - STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */ + if (mtc.mt_op != MTCOMPRESSION && mtc.mt_op != MTLOCK && + mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK && + mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETDRVBUFFER && + mtc.mt_op != MTMKPART && mtc.mt_op != MTSETPART && + mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM ) { + + /* + * The user tells us to move to another position on the tape. + * If we were appending to the tape content, that would leave + * the tape without proper end, in that case write EOD and + * update the header to reflect its position. + */ +#if DEBUG + printk(KERN_WARNING "osst%d:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n",dev, + STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle", + STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number, + STp->logical_blk_num, STps->drv_file, STps->drv_block ); +#endif + if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) { + auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) && + !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL)); + i = osst_write_trailer(STp, &SRpnt, + !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL)); +#if DEBUG + printk(KERN_WARNING "osst%d:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", + dev, auto_weof, STp->first_frame_position, STp->eod_frame_ppos, + STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block ); +#endif + if (i < 0) { + retval = i; + goto out; + } + } + STps->rw = ST_IDLE; + } if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED) osst_int_ioctl(STp, &SRpnt, MTUNLOCK, 0); /* Ignore result! */ @@ -4816,12 +4944,6 @@ } if (mtc.mt_op == MTSETPART) { -/* if (!STp->can_partitions || - mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS) - return (-EINVAL); - if (mtc.mt_count >= STp->nbr_partitions && - (STp->nbr_partitions = nbr_partitions(inode)) < 0) - return (-EIO);*/ if (mtc.mt_count >= STp->nbr_partitions) retval = -EINVAL; else { @@ -4864,14 +4986,14 @@ goto out; } -/* if (STp->can_partitions && STp->ready == ST_READY && - (i = update_partition(inode)) < 0) - {retval=i;goto out;}*/ + if (auto_weof) + cross_eof(STp, &SRpnt, FALSE); if (mtc.mt_op == MTCOMPRESSION) - retval = -EINVAL /*osst_compression(STp, (mtc.mt_count & 1))*/; + retval = -EINVAL; /* OnStream drives don't have compression hardware */ else - + /* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS MTLOAD + * MTLOCK MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTUNLOCK MTWEOF MTWSM */ retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count); goto out; } @@ -4886,10 +5008,6 @@ goto out; } -/* if (STp->can_partitions && - (i = update_partition(inode)) < 0) - {retval=i;goto out;}*/ - if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) { struct mtget mt_status; @@ -5119,9 +5237,10 @@ for (segs=STbuffer->sg_segs, got=STbuffer->buffer_size; segs < max_segs && got < new_size; ) { STbuffer->sg[segs].address = - (unsigned char *)__get_free_pages(priority, order); + (unsigned char *)__get_free_pages(priority, + (new_size - got <= PAGE_SIZE) ? 0 : order); if (STbuffer->sg[segs].address == NULL) { - if (new_size - got <= (max_segs - segs) * b_size / 2) { + if (new_size - got <= (max_segs - segs) * b_size / 2 && order) { b_size /= 2; /* Large enough for the rest of the buffers */ order--; continue; @@ -5135,9 +5254,9 @@ return FALSE; } STbuffer->sg[segs].page = NULL; - STbuffer->sg[segs].length = b_size; + STbuffer->sg[segs].length = (new_size - got <= PAGE_SIZE / 2) ? (new_size - got) : b_size; STbuffer->sg_segs += 1; - got += b_size; + got += STbuffer->sg[segs].length; STbuffer->buffer_size = got; segs++; } @@ -5320,28 +5439,26 @@ static void validate_options (void) { - if (buffer_kbs > 0) - osst_buffer_size = buffer_kbs * ST_KILOBYTE; + if (max_dev > 0) + osst_max_dev = osst_max_buffers = max_dev; if (write_threshold_kbs > 0) osst_write_threshold = write_threshold_kbs * ST_KILOBYTE; if (osst_write_threshold > osst_buffer_size) osst_write_threshold = osst_buffer_size; - if (max_buffers > 0) - osst_max_buffers = max_buffers; if (max_sg_segs >= OSST_FIRST_SG) osst_max_sg_segs = max_sg_segs; #if DEBUG - printk(OSST_DEB_MSG "osst :D: bufsize %d, wrt %d, max buffers %d, s/g segs %d.\n", + printk(OSST_DEB_MSG "osst :D: bufsize %d, wrt %d, max devices %d, s/g segs %d.\n", osst_buffer_size, osst_write_threshold, osst_max_buffers, osst_max_sg_segs); -//printk(OSST_DEB_MSG "osst :D: sizeof(header) = %d (%s)\n", -// sizeof(os_header_t),sizeof(os_header_t)==OS_DATA_SIZE?"ok":"error"); #endif } #ifndef MODULE -/* Set the boot options. Syntax: osst=xxx,yyy,... - where xxx is buffer size in 1024 byte blocks and yyy is write threshold - in 1024 byte blocks. */ +/* Set the boot options. Syntax: osst=xxx,yyy,zzz + * where xxx is maximum nr of devices to attach, + * yyy is write threshold in 1024 byte blocks + * and zzz the maximum nr of s/g segments to handle. + */ static int __init osst_setup (char *str) { int i, ints[5]; @@ -5417,6 +5534,72 @@ return 0; } +/* + * /proc support for accessing ADR header information + */ +static struct proc_dir_entry * osst_proc_dir = NULL; +static char osst_proc_dirname[] = "osst"; + +static int osst_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int l = 0; + OS_Scsi_Tape * STp = (OS_Scsi_Tape *) data; + + if (!osst_proc_dir) return 0; + + if (STp->header_ok && STp->linux_media) + l = sprintf(page, "%d.%d LIN%d %8d %8d %8d \n", + STp->header_cache->major_rev, + STp->header_cache->minor_rev, + STp->linux_media_version, + STp->first_data_ppos, + STp->eod_frame_ppos, + STp->filemark_cnt ); + return l; +} + +static void osst_proc_init(void) +{ + if (!proc_scsi) return; + + osst_proc_dir = proc_mkdir(osst_proc_dirname, proc_scsi); + osst_proc_dir->owner = THIS_MODULE; +} + +static void osst_proc_create(OS_Scsi_Tape * STp, int dev) +{ + char s[16]; + struct proc_dir_entry * p_entry; + + if (!osst_proc_dir) return; + + sprintf(s, "osst%d", dev); + p_entry = create_proc_read_entry(s, 0444, osst_proc_dir, osst_proc_read, (void *) STp); + p_entry->owner = THIS_MODULE; +} + +static void osst_proc_destroy(int dev) +{ + char s[16]; + + if (!osst_proc_dir) return; + + sprintf(s, "osst%d", dev); + remove_proc_entry(s, osst_proc_dir); +} + +static void osst_proc_cleanup(void) +{ + if ((! proc_scsi) || (!osst_proc_dir)) return; + + remove_proc_entry(osst_proc_dirname, proc_scsi); + osst_proc_dir = NULL; +} + +/* + * osst startup / cleanup code + */ + static int osst_attach(Scsi_Device * SDp) { OS_Scsi_Tape * tpnt; @@ -5462,34 +5645,18 @@ /* Rewind entry */ sprintf (name, "mt%s", formats[mode]); -# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) tpnt->de_r[mode] = devfs_register (SDp->de, name, DEVFS_FL_DEFAULT, MAJOR_NR, i + (mode << 5), S_IFCHR | S_IRUGO | S_IWUGO, &osst_fops, NULL); -# else - tpnt->de_r[mode] = - devfs_register (SDp->de, name, 0, DEVFS_FL_DEFAULT, - MAJOR_NR, i + (mode << 5), - S_IFCHR | S_IRUGO | S_IWUGO, - 0, 0, &osst_fops, NULL); -# endif /* No-rewind entry */ sprintf (name, "mt%sn", formats[mode]); -# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) tpnt->de_n[mode] = devfs_register (SDp->de, name, DEVFS_FL_DEFAULT, MAJOR_NR, i + (mode << 5) + 128, S_IFCHR | S_IRUGO | S_IWUGO, &osst_fops, NULL); -# else - tpnt->de_n[mode] = - devfs_register (SDp->de, name, 0, DEVFS_FL_DEFAULT, - MAJOR_NR, i + (mode << 5) + 128, - S_IFCHR | S_IRUGO | S_IWUGO, - 0, 0, &osst_fops, NULL); -# endif } devfs_register_tape (tpnt->de_r[0]); #endif @@ -5522,7 +5689,8 @@ tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev); tpnt->omit_blklims = 1; - tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp); + tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) || + (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp); tpnt->frame_in_buffer = 0; tpnt->header_ok = 0; tpnt->linux_media = 0; @@ -5559,6 +5727,8 @@ osst_template.nr_dev++; + osst_proc_create(tpnt, dev); + printk(KERN_INFO "osst :I: Attached OnStream %.5s tape at scsi%d, channel %d, id %d, lun %d as osst%d\n", SDp->model, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun, dev); @@ -5597,7 +5767,7 @@ } if (os_scsi_tapes) return 0; - osst_template.dev_max = OSST_MAX_TAPES; + osst_template.dev_max = osst_max_dev; if (osst_template.dev_max > 128 / ST_NBR_MODES) printk(KERN_INFO "osst :I: Only %d tapes accessible.\n", 128 / ST_NBR_MODES); os_scsi_tapes = @@ -5637,39 +5807,42 @@ printk(OSST_DEB_MSG "osst :D: Buffer size %d bytes, write threshold %d bytes.\n", osst_buffer_size, osst_write_threshold); #endif + osst_proc_init(); return 0; } static void osst_detach(Scsi_Device * SDp) { - OS_Scsi_Tape * tpnt; - int i; + OS_Scsi_Tape * tpnt; + int i; #ifdef CONFIG_DEVFS_FS - int mode; + int mode; #endif - - for(i=0; idevice == SDp) { - tpnt->device = NULL; + for(i=0; idevice == SDp) { + osst_proc_destroy(i); + tpnt->device = NULL; #ifdef CONFIG_DEVFS_FS - for (mode = 0; mode < ST_NBR_MODES; ++mode) { - devfs_unregister (tpnt->de_r[mode]); - tpnt->de_r[mode] = NULL; - devfs_unregister (tpnt->de_n[mode]); - tpnt->de_n[mode] = NULL; + for (mode = 0; mode < ST_NBR_MODES; ++mode) { + devfs_unregister (tpnt->de_r[mode]); + tpnt->de_r[mode] = NULL; + devfs_unregister (tpnt->de_n[mode]); + tpnt->de_n[mode] = NULL; + } +#endif + if (tpnt->header_cache != NULL) { + vfree(tpnt->header_cache); + } + kfree(tpnt); + os_scsi_tapes[i] = NULL; + SDp->attached--; + osst_template.nr_dev--; + osst_template.dev_noticed--; + return; } -#endif - kfree(tpnt); - os_scsi_tapes[i] = NULL; - SDp->attached--; - osst_template.nr_dev--; - osst_template.dev_noticed--; - return; } - } - return; } static int __init init_osst(void) @@ -5681,38 +5854,32 @@ static void __exit exit_osst (void) { - int i; - OS_Scsi_Tape * STp; + int i; - scsi_unregister_module(MODULE_SCSI_DEV, &osst_template); + scsi_unregister_module(MODULE_SCSI_DEV, &osst_template); #ifdef CONFIG_DEVFS_FS - devfs_unregister_chrdev(MAJOR_NR, "osst"); + devfs_unregister_chrdev(MAJOR_NR, "osst"); #else - unregister_chrdev(MAJOR_NR, "osst"); + unregister_chrdev(MAJOR_NR, "osst"); #endif - osst_registered--; - if(os_scsi_tapes != NULL) { - for (i=0; i < osst_template.dev_max; ++i) { - if ((STp = os_scsi_tapes[i])) { - if (STp->header_cache != NULL) vfree(STp->header_cache); - kfree(STp); - } - } - kfree(os_scsi_tapes); + osst_registered--; + osst_proc_cleanup(); + + if(os_scsi_tapes != NULL) { + kfree(os_scsi_tapes); + } if (osst_buffers != NULL) { for (i=0; i < osst_nbr_buffers; i++) - if (osst_buffers[i] != NULL) { - osst_buffers[i]->orig_sg_segs = 0; - normalize_buffer(osst_buffers[i]); - kfree(osst_buffers[i]); - } - + if (osst_buffers[i] != NULL) { + osst_buffers[i]->orig_sg_segs = 0; + normalize_buffer(osst_buffers[i]); + kfree(osst_buffers[i]); + } kfree(osst_buffers); } - } - osst_template.dev_max = 0; - printk(KERN_INFO "osst :I: Unloaded.\n"); + osst_template.dev_max = 0; + printk(KERN_INFO "osst :I: Unloaded.\n"); } module_init(init_osst); Index: drivers/scsi/osst.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/osst.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/osst.h 22 Jul 2004 19:50:05 -0000 1.1 +++ drivers/scsi/osst.h 4 Aug 2004 01:29:36 -0000 1.2 @@ -1,5 +1,5 @@ /* - * $Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/osst.h,v 1.1 2004/07/22 19:50:05 joff Exp $ + * $Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/osst.h,v 1.2 2004/08/04 01:29:36 joff Exp $ */ #include Index: drivers/scsi/osst_options.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/osst_options.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/osst_options.h 22 Jul 2004 19:50:03 -0000 1.1 +++ drivers/scsi/osst_options.h 4 Aug 2004 01:29:36 -0000 1.2 @@ -8,7 +8,7 @@ Changed (and renamed) for OnStream SCSI drives garloff@suse.de 2000-06-21 - $Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/osst_options.h,v 1.1 2004/07/22 19:50:03 joff Exp $ + $Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/osst_options.h,v 1.2 2004/08/04 01:29:36 joff Exp $ */ #ifndef _OSST_OPTIONS_H Index: drivers/scsi/pas16.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/pas16.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/pas16.c 22 Jul 2004 19:50:05 -0000 1.1 +++ drivers/scsi/pas16.c 4 Aug 2004 01:29:36 -0000 1.2 @@ -99,11 +99,11 @@ * interrupts. Ie, for a board at the default 0x388 base port, * boot: linux pas16=0x388,255 * - * IRQ_NONE (255) should be specified for no interrupt, + * SCSI_IRQ_NONE (255) should be specified for no interrupt, * IRQ_AUTO (254) to autoprobe for an IRQ line if overridden * on the command line. * - * (IRQ_AUTO == 254, IRQ_NONE == 255 in NCR5380.h) + * (IRQ_AUTO == 254, SCSI_IRQ_NONE == 255 in NCR5380.h) */ #include @@ -404,13 +404,13 @@ else instance->irq = NCR5380_probe_irq(instance, PAS16_IRQS); - if (instance->irq != IRQ_NONE) + if (instance->irq != SCSI_IRQ_NONE) if (request_irq(instance->irq, do_pas16_intr, SA_INTERRUPT, "pas16", NULL)) { printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); - instance->irq = IRQ_NONE; + instance->irq = SCSI_IRQ_NONE; } - if (instance->irq == IRQ_NONE) { + if (instance->irq == SCSI_IRQ_NONE) { printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no); printk(KERN_INFO "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no); /* Disable 5380 interrupts, leave drive params the same */ @@ -420,7 +420,7 @@ printk(KERN_INFO "scsi%d : at 0x%04x", instance->host_no, (int) instance->io_port); - if (instance->irq == IRQ_NONE) + if (instance->irq == SCSI_IRQ_NONE) printk(" interrupts disabled"); else printk(" irq %d", instance->irq); Index: drivers/scsi/ql12160_fw.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/ql12160_fw.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/ql12160_fw.h 22 Jul 2004 19:50:01 -0000 1.1 +++ drivers/scsi/ql12160_fw.h 4 Aug 2004 01:29:36 -0000 1.2 @@ -1,1704 +1,1787 @@ -/* - ************************************************************************ - * * - * --- ISP12160 Initiator Firmware --- * - * 32 LUN Support * - * * - ************************************************************************ - * * - * Copyright (C) 1999,2000 Qlogic, Corporation - * All rights reserved. +/***************************************************************************** + * QLOGIC LINUX SOFTWARE * - * Redistribution and use in source and binary forms are permitted provided - * that the following conditions are met: - * 1. Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission + * QLogic ISP12160 device driver for Linux 2.2.x and 2.4.x + * Copyright (C) 2002 Qlogic Corporation (www.qlogic.com) * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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. - * * - ************************************************************************ - */ + * This program is free software; you can redistribute 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. + * + *****************************************************************************/ +/************************************************************************ + * --- ISP12160A Initiator Firmware --- * + * 32 LUN Support * + ************************************************************************/ /* - * Firmware Version 10.01.19 (12:38 Oct 12, 1999) + * Firmware Version 10.04.32 (12:03 May 09, 2001) */ #ifdef UNIQUE_FW_NAME -unsigned short fw12160i_version = 10*1024+1; +unsigned short fw12160i_version = 10*1024+4; #else -unsigned short risc_code_version = 10*1024+1; +unsigned short risc_code_version = 10*1024+4; #endif #ifdef UNIQUE_FW_NAME -unsigned char fw12160i_version_str[] = {10,1,19}; +unsigned char fw12160i_version_str[] = {10,4,32}; #else -unsigned char firmware_version[] = {10,1,19}; +unsigned char firmware_version[] = {10,4,32}; #endif #ifdef UNIQUE_FW_NAME -#define fw12160i_VERSION_STRING "10.1.19" +#define fw12160i_VERSION_STRING "10.04.32" #else -#define FW_VERSION_STRING "10.1.19" +#define FW_VERSION_STRING "10.04.32" #endif #ifdef UNIQUE_FW_NAME -unsigned short fw12160i_addr01 = 0x1000 ; +unsigned short fw12160i_addr01 = 0x1000; #else -unsigned short risc_code_addr01 = 0x1000 ; +unsigned short risc_code_addr01 = 0x1000; #endif #ifdef UNIQUE_FW_NAME -unsigned short fw12160i_code01[] = { +unsigned short fw12160i_code01[] = { #else -unsigned short risc_code01[] = { +unsigned short risc_code01[] = { #endif - 0x0804, 0x1041, 0x0000, 0x32f8, 0x0000, 0x2043, 0x4f50, 0x5952, + 0x0804, 0x1041, 0x0000, 0x35e6, 0x0000, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31, 0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, 0x4320, 0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049, 0x5350, 0x3132, 0x3136, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056, - 0x6572, 0x7369, 0x6f6e, 0x2031, 0x302e, 0x3031, 0x2020, 0x2043, + 0x6572, 0x7369, 0x6f6e, 0x2031, 0x302e, 0x3034, 0x2020, 0x2043, 0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, 0x3030, 0x2050, 0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020, 0x3030, 0x2020, - 0x2400, 0x20c9, 0x8cff, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2001, + 0x2400, 0x20c9, 0x8fff, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1120, 0x2071, 0x0100, 0x70a0, 0x70a2, - 0x20c1, 0x0020, 0x2089, 0x1223, 0x2071, 0x0010, 0x70c3, 0x0004, + 0x20c1, 0x0020, 0x2089, 0x1221, 0x2071, 0x0010, 0x70c3, 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x000a, 0x2001, 0x04fd, 0x2004, 0x70d6, 0x2009, 0xfeff, 0x2130, 0x2128, - 0xa1a2, 0x4300, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, - 0xa192, 0x8d00, 0x2009, 0x0000, 0x2001, 0x0032, 0x080c, 0x1d83, - 0x2218, 0x2079, 0x4300, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9, + 0xa1a2, 0x4600, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, + 0xa192, 0x9000, 0x2009, 0x0000, 0x2001, 0x0032, 0x080c, 0x1de8, + 0x2218, 0x2079, 0x4600, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9, 0x0040, 0x42a4, 0x8109, 0x1dd8, 0x2009, 0xff00, 0x3400, 0xa102, 0x0218, 0x0110, 0x20a8, 0x42a4, 0x781b, 0x0064, 0x7814, 0xc0cd, - 0xc0d5, 0x7816, 0x2071, 0x0200, 0x00d6, 0x2069, 0x4340, 0x080c, - 0x42d8, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1130, 0x2069, 0x4380, - 0x2071, 0x0100, 0x080c, 0x42d8, 0x7814, 0xc0d4, 0x7816, 0x00de, + 0xc0d5, 0x7816, 0x2071, 0x0200, 0x00d6, 0x2069, 0x4640, 0x080c, + 0x459a, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1130, 0x2069, 0x4680, + 0x2071, 0x0100, 0x080c, 0x459a, 0x7814, 0xc0d4, 0x7816, 0x00de, 0x7eca, 0x7cc2, 0x7bc6, 0x7867, 0x0000, 0x7800, 0xc08d, 0x7802, 0x2031, 0x0030, 0x78af, 0x0101, 0x7823, 0x0002, 0x7827, 0x0002, - 0x2009, 0x0002, 0x2069, 0x4340, 0x681b, 0x0003, 0x6823, 0x0007, - 0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028, 0x6837, 0x0000, - 0x683b, 0x0006, 0x6833, 0x0008, 0x683f, 0x0000, 0x8109, 0x0500, - 0x68d3, 0x000a, 0x68c3, 0x43c0, 0x2079, 0x4300, 0x68d7, 0x762d, - 0x68c7, 0x48c0, 0x68cb, 0x47c0, 0x68cf, 0x88c0, 0x68ab, 0x8b44, - 0x68af, 0x8b49, 0x68b3, 0x8b44, 0x68b7, 0x8b44, 0x68a7, 0x0001, - 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x11c8, 0x2069, 0x4380, 0x0860, - 0x68d3, 0x000a, 0x68c3, 0x45c0, 0x68d7, 0x7839, 0x68c7, 0x68c0, - 0x68cb, 0x4840, 0x68cf, 0x89d0, 0x68ab, 0x8b49, 0x68af, 0x8b4e, - 0x68b3, 0x8b49, 0x68b7, 0x8b49, 0x68a7, 0x0001, 0x00e6, 0x2069, - 0x47c0, 0x2071, 0x0200, 0x70ec, 0xd0e4, 0x2019, 0x1c09, 0x2021, - 0x0009, 0x1120, 0x2019, 0x1c0c, 0x2021, 0x000c, 0x080c, 0x1cf3, - 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1188, 0x2069, 0x4840, 0x2071, - 0x0100, 0x70ec, 0xd0e4, 0x2019, 0x1c09, 0x2021, 0x0009, 0x1120, - 0x2019, 0x1c0c, 0x2021, 0x000c, 0x080c, 0x1cf3, 0x00ee, 0x2011, - 0x0002, 0x2069, 0x48c0, 0x2009, 0x0002, 0x20a9, 0x0100, 0x6837, - 0x0000, 0x680b, 0x0040, 0x7bc8, 0xa386, 0xfeff, 0x1128, 0x6817, - 0x0100, 0x681f, 0x0064, 0x0020, 0x6817, 0x0064, 0x681f, 0x0002, - 0xade8, 0x0010, 0x1f04, 0x1137, 0x8109, 0x1d38, 0x2001, 0x01ff, - 0x2004, 0xd0fc, 0x1128, 0x8211, 0x0118, 0x2069, 0x68c0, 0x08d8, - 0x080c, 0x2254, 0x080c, 0x3e39, 0x080c, 0x1b0f, 0x080c, 0x42a0, - 0x2091, 0x2200, 0x2079, 0x4300, 0x2071, 0x0050, 0x2091, 0x2400, - 0x2079, 0x4300, 0x2071, 0x0020, 0x2091, 0x2600, 0x2079, 0x0200, - 0x2071, 0x4340, 0x2091, 0x2800, 0x2079, 0x0100, 0x2071, 0x4380, - 0x2091, 0x2000, 0x2079, 0x4300, 0x2071, 0x0010, 0x3200, 0xa085, - 0x303d, 0x2090, 0x2071, 0x0010, 0x70c3, 0x0000, 0x1004, 0x118e, - 0x70c0, 0xa086, 0x0002, 0x1110, 0x080c, 0x13a3, 0x2039, 0x0000, - 0x080c, 0x129c, 0x78ac, 0xa005, 0x1180, 0x0e04, 0x119c, 0x786c, - 0xa065, 0x0110, 0x080c, 0x1ffe, 0x080c, 0x1da4, 0x0e04, 0x11b1, - 0x786c, 0xa065, 0x0110, 0x080c, 0x1ffe, 0x0e04, 0x11b1, 0x2009, - 0x4347, 0x2011, 0x4387, 0x2104, 0x220c, 0xa105, 0x0110, 0x080c, - 0x1c21, 0x2071, 0x4340, 0x70a4, 0xa005, 0x01e8, 0x7450, 0xa485, - 0x0000, 0x01c8, 0x2079, 0x0200, 0x2091, 0x8000, 0x72d4, 0xa28c, - 0x303d, 0x2190, 0x080c, 0x260d, 0x2091, 0x8000, 0x2091, 0x303d, - 0x0e04, 0x11d3, 0x2079, 0x4300, 0x786c, 0xa065, 0x0120, 0x2071, - 0x0010, 0x080c, 0x1ffe, 0x1d04, 0x11db, 0x2079, 0x4300, 0x2071, - 0x0010, 0x080c, 0x40ed, 0x2071, 0x4380, 0x70a4, 0xa005, 0x0188, - 0x7050, 0xa025, 0x0170, 0x2079, 0x0100, 0x2091, 0x8000, 0x72d4, - 0xa28c, 0x303d, 0x2190, 0x080c, 0x260d, 0x2091, 0x8000, 0x2091, - 0x303d, 0x2079, 0x4300, 0x2071, 0x0010, 0x0e04, 0x11fc, 0x786c, - 0xa065, 0x0110, 0x080c, 0x1ffe, 0x1d04, 0x1190, 0x080c, 0x40ed, - 0x0804, 0x1190, 0x3c00, 0xa084, 0x0007, 0x0002, 0x120e, 0x120e, - 0x1210, 0x1210, 0x1215, 0x1215, 0x121a, 0x121a, 0x080c, 0x243b, - 0x2091, 0x2400, 0x080c, 0x3e9c, 0x0005, 0x2091, 0x2200, 0x080c, - 0x3e9c, 0x0005, 0x2091, 0x2200, 0x080c, 0x3e9c, 0x2091, 0x2400, - 0x080c, 0x3e9c, 0x0005, 0x1243, 0x1243, 0x1244, 0x1244, 0x124f, - 0x124f, 0x124f, 0x124f, 0x1258, 0x1258, 0x1263, 0x1263, 0x124f, - 0x124f, 0x124f, 0x124f, 0x1272, 0x1272, 0x1272, 0x1272, 0x1272, - 0x1272, 0x1272, 0x1272, 0x1272, 0x1272, 0x1272, 0x1272, 0x1272, - 0x1272, 0x1272, 0x1272, 0x0cf8, 0x0006, 0x0106, 0x0126, 0x2091, - 0x2800, 0x080c, 0x2458, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006, - 0x0106, 0x0126, 0x080c, 0x1202, 0x012e, 0x010e, 0x000e, 0x000d, - 0x0006, 0x0106, 0x0126, 0x2091, 0x2600, 0x080c, 0x2458, 0x012e, - 0x010e, 0x000e, 0x000d, 0x0006, 0x0106, 0x0126, 0x2091, 0x2600, - 0x080c, 0x2458, 0x2091, 0x2800, 0x080c, 0x2458, 0x012e, 0x010e, - 0x000e, 0x000d, 0x0006, 0x0106, 0x0126, 0x00e6, 0x00f6, 0x2079, - 0x4300, 0x2071, 0x0200, 0x2069, 0x4340, 0x3d00, 0xd08c, 0x1120, - 0x2069, 0x4380, 0x2071, 0x0100, 0x080c, 0x42d8, 0x00fe, 0x00ee, - 0x012e, 0x010e, 0x000e, 0x000d, 0x7008, 0x800b, 0x1240, 0x7007, - 0x0002, 0xa08c, 0x01e0, 0x1120, 0xd09c, 0x0108, 0x0887, 0x0897, - 0x70c3, 0x4002, 0x0804, 0x13a6, 0x0e04, 0x1308, 0x2061, 0x0000, - 0x6018, 0xd084, 0x1904, 0x1308, 0x7828, 0xa005, 0x1120, 0x0004, - 0x1309, 0x0804, 0x1308, 0xd0fc, 0x0148, 0x0006, 0x080c, 0x1aa9, - 0x000e, 0x0168, 0x2001, 0x4007, 0x0804, 0x13a5, 0x0006, 0x080c, - 0x1a9b, 0x000e, 0x0120, 0x2001, 0x4007, 0x0804, 0x13a5, 0x7910, - 0xd0fc, 0x1128, 0x2061, 0x4340, 0xc19c, 0xc7fc, 0x0020, 0x2061, - 0x4380, 0xc19d, 0xc7fd, 0x6064, 0xa005, 0x15d0, 0x7912, 0x6083, - 0x0000, 0x7828, 0xc0fc, 0xa086, 0x0018, 0x1120, 0x00c6, 0x080c, - 0x18c9, 0x00ce, 0x782b, 0x0000, 0x607c, 0xa065, 0x0190, 0x00c6, - 0x609c, 0x080c, 0x1b76, 0x00ce, 0x609f, 0x0000, 0x080c, 0x19db, - 0x2009, 0x0018, 0x6087, 0x0103, 0x080c, 0x1ab7, 0x1198, 0x080c, - 0x1b02, 0x7810, 0xd09c, 0x1118, 0x2061, 0x4340, 0x0020, 0x2061, - 0x4380, 0xc09c, 0x7812, 0x607f, 0x0000, 0x60d4, 0xd0c4, 0x0130, - 0xc0c4, 0x60d6, 0x2001, 0x4005, 0x0804, 0x13a5, 0x0804, 0x13a3, - 0x0005, 0xa006, 0x70c2, 0x70c6, 0x70ca, 0x70ce, 0x70da, 0x70c0, - 0xa08a, 0x0040, 0x1a04, 0x1355, 0x0002, 0x13a3, 0x13f1, 0x13bf, - 0x1425, 0x1459, 0x1459, 0x13b7, 0x19f3, 0x1463, 0x13b1, 0x13c3, - 0x13c4, 0x13c5, 0x13c6, 0x19f7, 0x13b1, 0x1470, 0x14c5, 0x18e4, - 0x19ed, 0x13c7, 0x1795, 0x17cb, 0x17fa, 0x183d, 0x1752, 0x175f, - 0x1772, 0x1784, 0x159a, 0x13b1, 0x14f7, 0x1502, 0x1510, 0x151e, - 0x1535, 0x1543, 0x1546, 0x1554, 0x1562, 0x156c, 0x1580, 0x158c, - 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x15a7, 0x15b8, 0x15d2, 0x1606, - 0x162f, 0x1641, 0x1644, 0x1677, 0x16aa, 0x16bc, 0x1720, 0x1730, - 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x1742, 0x2100, 0xa08a, 0x0040, - 0x1a04, 0x13b1, 0x0002, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, - 0x1a19, 0x1a1f, 0x13b1, 0x13b1, 0x13b1, 0x1a23, 0x1a63, 0x13b1, - 0x13b1, 0x13b1, 0x13b1, 0x13ec, 0x1454, 0x146b, 0x14c0, 0x18df, - 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x1a67, 0x1a0b, 0x1a15, 0x13b1, - 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, - 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, - 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, - 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, - 0x13b1, 0x13b1, 0x13b1, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0028, - 0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0e04, 0x13a6, - 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, - 0x0005, 0x70c3, 0x4001, 0x0c90, 0x70c3, 0x4006, 0x0c78, 0x2099, - 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0c20, 0x70c4, - 0x70c3, 0x0004, 0x0807, 0x08f8, 0x08f0, 0x08e8, 0x08e0, 0x2091, - 0x8000, 0x70c3, 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, - 0x2020, 0x70d3, 0x000a, 0x2001, 0x0001, 0x70d6, 0x2079, 0x0000, - 0x781b, 0x0001, 0x2031, 0x0030, 0x2059, 0x1000, 0x2029, 0x041a, - 0x2051, 0x0445, 0x2061, 0x0447, 0x20c1, 0x0020, 0x2091, 0x5000, - 0x2091, 0x4080, 0x0804, 0x0418, 0x75d8, 0x74dc, 0x75da, 0x74de, - 0x0018, 0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, - 0x20a0, 0x2099, 0x0030, 0x7003, 0x0001, 0x7007, 0x0006, 0x731a, - 0x721e, 0x7422, 0x7526, 0x2021, 0x0040, 0x81ff, 0x0904, 0x13a3, - 0xa182, 0x0040, 0x1210, 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, - 0x7007, 0x0004, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0de8, 0x7007, - 0x0002, 0xa084, 0x01e0, 0x0120, 0x70c3, 0x4002, 0x0804, 0x13a6, - 0x24a8, 0x53a5, 0x0c10, 0x0804, 0x13a3, 0x2029, 0x0000, 0x2520, - 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x2098, 0x20a1, 0x0030, 0x7003, - 0x0000, 0x7007, 0x0006, 0x731a, 0x721e, 0x7422, 0x7526, 0x2021, - 0x0040, 0x7007, 0x0006, 0x81ff, 0x0904, 0x13a3, 0xa182, 0x0040, - 0x1210, 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x24a8, 0x53a6, - 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0de8, 0xa084, 0x01e0, 0x0d48, - 0x70c3, 0x4002, 0x0804, 0x13a6, 0x75d8, 0x74dc, 0x75da, 0x74de, - 0x0878, 0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004, 0x1108, 0x200a, - 0x72ca, 0x0804, 0x13a2, 0x70c7, 0x000a, 0x70cb, 0x0001, 0x70cf, - 0x0013, 0x0804, 0x13a3, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0018, - 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0, 0x70c6, - 0x72ca, 0x73ce, 0x74d2, 0xa005, 0x05f0, 0xa40a, 0x0110, 0x1a04, - 0x13a5, 0x8001, 0x7872, 0xa084, 0xfc00, 0x0138, 0x78ac, 0xc085, - 0x78ae, 0x2001, 0x4005, 0x0804, 0x13a5, 0x7b7e, 0x7a7a, 0x7e86, - 0x7d82, 0x7c76, 0xa48c, 0xff00, 0x0170, 0x8407, 0x8004, 0x8004, - 0x810c, 0x810c, 0x810f, 0xa118, 0xa291, 0x0000, 0xa6b1, 0x0000, - 0xa581, 0x0000, 0x0050, 0x8407, 0x8004, 0x8004, 0xa318, 0xa291, - 0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000, 0x731a, 0x721e, 0x7622, - 0x7026, 0xa605, 0x0118, 0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084, - 0xfffc, 0x78ae, 0x0018, 0x78ac, 0xc085, 0x78ae, 0x0804, 0x13a3, - 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0018, 0x2029, 0x0000, 0x2530, - 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6, - 0xa005, 0x0500, 0xa40a, 0x0110, 0x1a04, 0x13a5, 0x8001, 0x7892, - 0xa084, 0xfc00, 0x0138, 0x78ac, 0xc0c5, 0x78ae, 0x2001, 0x4005, - 0x0804, 0x13a5, 0x7a9a, 0x7b9e, 0x7da2, 0x7ea6, 0x2600, 0xa505, - 0x0118, 0x7a10, 0xc2c5, 0x7a12, 0x7c96, 0x78ac, 0xa084, 0xfcff, - 0x78ae, 0x0018, 0x78ac, 0xc0c5, 0x78ae, 0x0804, 0x13a3, 0x2009, - 0x0000, 0x786c, 0xa065, 0x0118, 0x8108, 0x6000, 0x0cd8, 0x7ac4, - 0x0804, 0x13a1, 0x2009, 0x4348, 0x210c, 0x2001, 0x01ff, 0x2004, - 0xd0fc, 0x1904, 0x13a2, 0x2011, 0x4388, 0x2214, 0x0804, 0x13a1, - 0x2009, 0x4349, 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, - 0x13a2, 0x2011, 0x4389, 0x2214, 0x0804, 0x13a1, 0x2061, 0x4340, - 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, 0x2001, 0x01ff, 0x2004, - 0xd0fc, 0x1148, 0x2061, 0x4380, 0x6328, 0x73da, 0x632c, 0x831c, - 0x831c, 0x831c, 0x73de, 0x0804, 0x13a1, 0x2009, 0x434c, 0x210c, - 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13a2, 0x2011, 0x438c, - 0x2214, 0x0804, 0x13a1, 0x7918, 0x0804, 0x13a2, 0x2009, 0x434d, - 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13a2, 0x2011, - 0x438d, 0x2214, 0x0804, 0x13a1, 0x2009, 0x434e, 0x210c, 0x2001, - 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13a2, 0x2011, 0x438e, 0x2214, - 0x0804, 0x13a1, 0x7920, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, - 0x13a2, 0x7a24, 0x0804, 0x13a1, 0x2011, 0x4840, 0x71c4, 0xd1fc, - 0x1110, 0x2011, 0x47c0, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, - 0x8003, 0xa268, 0x6a00, 0x6b08, 0x6c1c, 0x74da, 0x0804, 0x13a0, - 0x77c4, 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091, - 0x8001, 0x2708, 0x0804, 0x13a0, 0x2061, 0x4340, 0x6118, 0x2001, - 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13a2, 0x2061, 0x4380, 0x6218, - 0x0804, 0x13a1, 0x77c4, 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6908, - 0x6a18, 0x6b10, 0x77da, 0x2091, 0x8001, 0x0804, 0x13a0, 0x71c4, - 0x2110, 0xa294, 0x000f, 0xa282, 0x0010, 0x1a04, 0x139c, 0x080c, - 0x230e, 0xa384, 0x4000, 0x0110, 0xa295, 0x0020, 0x0804, 0x13a0, - 0x71c4, 0x2100, 0xc0bc, 0xa082, 0x0010, 0x1a04, 0x139c, 0xd1bc, - 0x1120, 0x2011, 0x4348, 0x2204, 0x0020, 0x2011, 0x4388, 0x2204, - 0xc0bd, 0x0006, 0x2100, 0xc0bc, 0x2012, 0x080c, 0x22b4, 0x001e, - 0x0804, 0x13a2, 0x71c4, 0x2021, 0x4349, 0x2404, 0x70c6, 0x2019, - 0x0000, 0x0030, 0x71c8, 0x2021, 0x4389, 0x2404, 0x70ca, 0xc3fd, - 0x2011, 0x15fe, 0x20a9, 0x0008, 0x2204, 0xa106, 0x0138, 0x8210, - 0x1f04, 0x15e4, 0x71c4, 0x72c8, 0x0804, 0x139b, 0xa292, 0x15fe, - 0x0026, 0x2122, 0x001e, 0x080c, 0x22c6, 0x2001, 0x01ff, 0x2004, - 0xd0fc, 0x1110, 0xd3fc, 0x09f0, 0x0804, 0x13a3, 0x03e8, 0x00fa, - 0x01f4, 0x02ee, 0x0064, 0x0019, 0x0032, 0x004b, 0x2061, 0x4340, - 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, - 0x8003, 0x8003, 0x8003, 0x602e, 0x2001, 0x01ff, 0x2004, 0xd0fc, - 0x11a0, 0x0026, 0x0016, 0x2061, 0x4380, 0x6128, 0x622c, 0x8214, - 0x8214, 0x8214, 0x70d8, 0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, - 0x602e, 0x71da, 0x72de, 0x001e, 0x002e, 0x0804, 0x13a1, 0x2061, - 0x4340, 0x6130, 0x70c4, 0x6032, 0x2001, 0x01ff, 0x2004, 0xd0fc, - 0x1904, 0x13a2, 0x2061, 0x4380, 0x6230, 0x70c8, 0x6032, 0x0804, - 0x13a1, 0x7918, 0x0804, 0x13a2, 0x71c4, 0xa184, 0xffcf, 0x0148, - 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x139c, 0x72c8, 0x0804, - 0x139b, 0x2011, 0x434d, 0x2204, 0x2112, 0x0006, 0x2019, 0x0000, - 0x080c, 0x2302, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x0118, 0x001e, - 0x0804, 0x13a2, 0x71c8, 0xa184, 0xffcf, 0x0128, 0x0006, 0x2110, - 0x71c4, 0x0804, 0x139b, 0x2011, 0x438d, 0x2204, 0x2112, 0x0006, - 0xc3fd, 0x080c, 0x2302, 0x002e, 0x001e, 0x0804, 0x13a1, 0x71c4, - 0xa182, 0x0010, 0x0248, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, - 0x139c, 0x72c8, 0x0804, 0x139b, 0x2011, 0x434e, 0x2204, 0x0006, - 0x2112, 0x2019, 0x0000, 0x080c, 0x22ef, 0x2001, 0x01ff, 0x2004, - 0xd0fc, 0x0118, 0x001e, 0x0804, 0x13a2, 0x71c8, 0xa182, 0x0010, - 0x0228, 0x0006, 0x2110, 0x71c4, 0x0804, 0x139b, 0x2011, 0x438e, - 0x2204, 0x0006, 0x2112, 0xc3fd, 0x080c, 0x22ef, 0x002e, 0x001e, - 0x0804, 0x13a1, 0x71c4, 0x72c8, 0xa184, 0xfffd, 0x1904, 0x139b, - 0xa284, 0xfffd, 0x1904, 0x139b, 0x2100, 0x7920, 0x7822, 0x2200, - 0x7a24, 0x7826, 0x0804, 0x13a1, 0x2011, 0x4840, 0x71c4, 0xd1fc, - 0x1110, 0x2011, 0x47c0, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, - 0x8003, 0xa268, 0x72c8, 0x73cc, 0x74d8, 0x71c6, 0x6800, 0x70ca, - 0x73ce, 0x74da, 0x2091, 0x8000, 0x6a02, 0xd2ac, 0x1118, 0x2021, - 0x0000, 0x0078, 0xa484, 0x00ff, 0xa082, 0x0002, 0x16e8, 0x843f, - 0xa7bc, 0x00ff, 0x0130, 0xa786, 0x0002, 0x15b0, 0xa484, 0x00ff, - 0x0598, 0x2061, 0x0200, 0xd1fc, 0x0110, 0x2061, 0x0100, 0x2029, - 0x0009, 0x2031, 0x0062, 0x843f, 0xa7bc, 0x00ff, 0x0130, 0x8307, - 0xa084, 0x00ff, 0x1110, 0xa73d, 0x11f8, 0x2041, 0x001d, 0x8307, - 0xa084, 0x00ff, 0x0150, 0xa842, 0x02b8, 0xa3bc, 0x00ff, 0x2500, - 0xa702, 0x0290, 0x2600, 0xa702, 0x1278, 0x2039, 0x003a, 0x6804, - 0xa705, 0x6806, 0x6b0a, 0x6b0c, 0x73ce, 0x681c, 0x70da, 0x6c1e, - 0x2091, 0x8001, 0x0804, 0x13a3, 0x2091, 0x8001, 0x0804, 0x139d, - 0x77c4, 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6a14, 0x6b1c, 0x2091, - 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708, 0x0804, 0x13a0, - 0x70c4, 0x2061, 0x4340, 0x6118, 0x601a, 0x2001, 0x01ff, 0x2004, - 0xd0fc, 0x1904, 0x13a2, 0x70c8, 0x2061, 0x4380, 0x6218, 0x601a, - 0x0804, 0x13a1, 0x71c4, 0x72c8, 0x73cc, 0xa182, 0x0010, 0x1a04, - 0x139c, 0x080c, 0x2332, 0xa384, 0x4000, 0x0110, 0xa295, 0x0020, - 0x0804, 0x13a0, 0x77c4, 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6a08, - 0xc28d, 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0804, 0x13a1, 0x77c4, - 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9, 0x6a0a, - 0x6804, 0xa005, 0x0110, 0x080c, 0x2233, 0x2091, 0x8001, 0x2708, - 0x0804, 0x13a1, 0x77c4, 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6a08, - 0xc295, 0x6a0a, 0x6804, 0xa005, 0x0110, 0x080c, 0x2233, 0x2091, - 0x8001, 0x2708, 0x0804, 0x13a1, 0x77c4, 0x2041, 0x0001, 0x2049, - 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x080c, 0x1b35, 0x2091, - 0x8001, 0x2708, 0x6a08, 0x0804, 0x13a1, 0x77c4, 0xd7fc, 0x0128, - 0x080c, 0x1aa9, 0x0138, 0x0804, 0x13a5, 0x080c, 0x1a9b, 0x0110, - 0x0804, 0x13a5, 0x73c8, 0x72cc, 0x77c6, 0x73ca, 0x72ce, 0x080c, - 0x1bad, 0x11e8, 0x6818, 0xa005, 0x01a0, 0x2708, 0x0076, 0x080c, - 0x2351, 0x007e, 0x1170, 0x2001, 0x0015, 0xd7fc, 0x1118, 0x2061, - 0x4340, 0x0018, 0xc0fd, 0x2061, 0x4380, 0x782a, 0x2091, 0x8001, - 0x0005, 0x2091, 0x8001, 0x2001, 0x4005, 0x0804, 0x13a5, 0x2091, - 0x8001, 0x0804, 0x13a3, 0x77c4, 0xd7fc, 0x0128, 0x080c, 0x1aa9, - 0x0138, 0x0804, 0x13a5, 0x080c, 0x1a9b, 0x0110, 0x0804, 0x13a5, - 0x77c6, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, - 0x8000, 0x080c, 0x1b35, 0x2009, 0x0016, 0xd7fc, 0x1118, 0x2061, - 0x4340, 0x0018, 0x2061, 0x4380, 0xc1fd, 0x6067, 0x0003, 0x607f, - 0x0000, 0x6776, 0x6083, 0x000f, 0x792a, 0x080c, 0x2233, 0x2091, + 0x2009, 0x0002, 0x2069, 0x4640, 0x681b, 0x0003, 0x6823, 0x0007, + 0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028, 0x6837, 0x0006, + 0x6833, 0x0008, 0x683b, 0x0000, 0x8109, 0x0500, 0x68cf, 0x000a, + 0x68bf, 0x46c0, 0x2079, 0x4600, 0x68d3, 0x762d, 0x68c3, 0x4bc0, + 0x68c7, 0x4ac0, 0x68cb, 0x8bc0, 0x68a7, 0x8e44, 0x68ab, 0x8e49, + 0x68af, 0x8e44, 0x68b3, 0x8e44, 0x68a3, 0x0001, 0x2001, 0x01ff, + 0x2004, 0xd0fc, 0x11c8, 0x2069, 0x4680, 0x0870, 0x68cf, 0x000a, + 0x68bf, 0x48c0, 0x68d3, 0x7839, 0x68c3, 0x6bc0, 0x68c7, 0x4b40, + 0x68cb, 0x8cd0, 0x68a7, 0x8e49, 0x68ab, 0x8e4e, 0x68af, 0x8e49, + 0x68b3, 0x8e49, 0x68a3, 0x0001, 0x00e6, 0x2069, 0x4ac0, 0x2071, + 0x0200, 0x70ec, 0xd0e4, 0x2019, 0x1809, 0x2021, 0x0009, 0x1120, + 0x2019, 0x180c, 0x2021, 0x000c, 0x080c, 0x1d58, 0x2001, 0x01ff, + 0x2004, 0xd0fc, 0x1188, 0x2069, 0x4b40, 0x2071, 0x0100, 0x70ec, + 0xd0e4, 0x2019, 0x1809, 0x2021, 0x0009, 0x1120, 0x2019, 0x180c, + 0x2021, 0x000c, 0x080c, 0x1d58, 0x00ee, 0x2011, 0x0002, 0x2069, + 0x4bc0, 0x2009, 0x0002, 0x20a9, 0x0100, 0x6837, 0x0000, 0x680b, + 0x0040, 0x7bc8, 0xa386, 0xfeff, 0x1128, 0x6817, 0x0100, 0x681f, + 0x0064, 0x0020, 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010, + 0x1f04, 0x1135, 0x8109, 0x1d38, 0x2001, 0x01ff, 0x2004, 0xd0fc, + 0x1128, 0x8211, 0x0118, 0x2069, 0x6bc0, 0x08d8, 0x080c, 0x22cf, + 0x080c, 0x4015, 0x080c, 0x1b6d, 0x080c, 0x4553, 0x2091, 0x2200, + 0x2079, 0x4600, 0x2071, 0x0050, 0x2091, 0x2400, 0x2079, 0x4600, + 0x2071, 0x0020, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x4640, + 0x2091, 0x2800, 0x2079, 0x0100, 0x2071, 0x4680, 0x2091, 0x2000, + 0x2079, 0x4600, 0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090, + 0x2071, 0x0010, 0x70c3, 0x0000, 0x1004, 0x118c, 0x70c0, 0xa086, + 0x0002, 0x1110, 0x080c, 0x13ba, 0x2039, 0x0000, 0x080c, 0x12ab, + 0x78ac, 0xa005, 0x1180, 0x0e04, 0x119a, 0x786c, 0xa065, 0x0110, + 0x080c, 0x207a, 0x080c, 0x1e09, 0x0e04, 0x11af, 0x786c, 0xa065, + 0x0110, 0x080c, 0x207a, 0x0e04, 0x11af, 0x2009, 0x4647, 0x2011, + 0x4687, 0x2104, 0x220c, 0xa105, 0x0110, 0x080c, 0x1c7c, 0x2071, + 0x4640, 0x70a0, 0xa005, 0x01e8, 0x744c, 0xa485, 0x0000, 0x01c8, + 0x2079, 0x0200, 0x2091, 0x8000, 0x72d0, 0xa28c, 0x303d, 0x2190, + 0x080c, 0x2720, 0x2091, 0x8000, 0x2091, 0x303d, 0x0e04, 0x11d1, + 0x2079, 0x4600, 0x786c, 0xa065, 0x0120, 0x2071, 0x0010, 0x080c, + 0x207a, 0x1d04, 0x11d9, 0x2079, 0x4600, 0x2071, 0x0010, 0x080c, + 0x4370, 0x2071, 0x4680, 0x70a0, 0xa005, 0x0188, 0x704c, 0xa025, + 0x0170, 0x2079, 0x0100, 0x2091, 0x8000, 0x72d0, 0xa28c, 0x303d, + 0x2190, 0x080c, 0x2720, 0x2091, 0x8000, 0x2091, 0x303d, 0x2079, + 0x4600, 0x2071, 0x0010, 0x0e04, 0x11fa, 0x786c, 0xa065, 0x0110, + 0x080c, 0x207a, 0x1d04, 0x118e, 0x080c, 0x4370, 0x0804, 0x118e, + 0x3c00, 0xa084, 0x0007, 0x0002, 0x120c, 0x120c, 0x120e, 0x120e, + 0x1213, 0x1213, 0x1218, 0x1218, 0x080c, 0x254c, 0x2091, 0x2400, + 0x080c, 0x40ad, 0x0005, 0x2091, 0x2200, 0x080c, 0x40ad, 0x0005, + 0x2091, 0x2200, 0x080c, 0x40ad, 0x2091, 0x2400, 0x080c, 0x40ad, + 0x0005, 0x1241, 0x1241, 0x1242, 0x1242, 0x124d, 0x124d, 0x124d, + 0x124d, 0x1256, 0x1256, 0x1261, 0x1261, 0x124d, 0x124d, 0x124d, + 0x124d, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, + 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, + 0x1270, 0x0cf8, 0x0006, 0x0106, 0x0126, 0x2091, 0x2800, 0x080c, + 0x2569, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006, 0x0106, 0x0126, + 0x080c, 0x1200, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006, 0x0106, + 0x0126, 0x2091, 0x2600, 0x080c, 0x2569, 0x012e, 0x010e, 0x000e, + 0x000d, 0x0006, 0x0106, 0x0126, 0x2091, 0x2600, 0x080c, 0x2569, + 0x2091, 0x2800, 0x080c, 0x2569, 0x012e, 0x010e, 0x000e, 0x000d, + 0x0006, 0x0106, 0x0126, 0x00d6, 0x00e6, 0x00f6, 0x2079, 0x4600, + 0x2071, 0x0200, 0x2069, 0x4640, 0x3d00, 0xd08c, 0x0130, 0x70ec, + 0xa084, 0x1c00, 0x78e2, 0x080c, 0x459a, 0x3d00, 0xd084, 0x0150, + 0x2069, 0x4680, 0x2071, 0x0100, 0x70ec, 0xa084, 0x1c00, 0x78e6, + 0x080c, 0x459a, 0x080c, 0x24fd, 0x00fe, 0x00ee, 0x00de, 0x012e, + 0x010e, 0x000e, 0x000d, 0x7008, 0x800b, 0x1240, 0x7007, 0x0002, + 0xa08c, 0x01e0, 0x1120, 0xd09c, 0x0108, 0x0887, 0x0897, 0x70c3, + 0x4002, 0x0804, 0x13bd, 0x0e04, 0x131e, 0x2061, 0x0000, 0x6018, + 0xd084, 0x1904, 0x131e, 0x7828, 0xa005, 0x1120, 0x0004, 0x131f, + 0x0804, 0x131e, 0xd0fc, 0x0130, 0x0006, 0x080c, 0x1b0a, 0x000e, + 0x0150, 0x0028, 0x0006, 0x080c, 0x1aff, 0x000e, 0x0120, 0x2001, + 0x4007, 0x0804, 0x13bc, 0x7910, 0xd0fc, 0x1128, 0x2061, 0x4640, + 0xc19c, 0xc7fc, 0x0020, 0x2061, 0x4680, 0xc19d, 0xc7fd, 0x6060, + 0xa005, 0x1904, 0x131e, 0x7912, 0x607e, 0x7828, 0xc0fc, 0xa086, + 0x0018, 0x1120, 0x00c6, 0x080c, 0x1916, 0x00ce, 0x782b, 0x0000, + 0x6078, 0xa065, 0x01e0, 0x00c6, 0x609c, 0x080c, 0x1bd4, 0x00ce, + 0x609f, 0x0000, 0x080c, 0x1a41, 0x2009, 0x0018, 0x6087, 0x0103, + 0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff, 0x0110, 0xc0c5, 0x7812, + 0x080c, 0x1b15, 0x000e, 0x7812, 0x1198, 0x080c, 0x1b60, 0x7810, + 0xd09c, 0x1118, 0x2061, 0x4640, 0x0020, 0x2061, 0x4680, 0xc09c, + 0x7812, 0x607b, 0x0000, 0x60d0, 0xd0c4, 0x0130, 0xc0c4, 0x60d2, + 0x2001, 0x4005, 0x0804, 0x13bc, 0x0804, 0x13ba, 0x0005, 0xa006, + 0x70c2, 0x70c6, 0x70ca, 0x70ce, 0x70da, 0x70c0, 0xa03d, 0xa08a, + 0x0040, 0x1a04, 0x136c, 0x0002, 0x13ba, 0x1408, 0x13d6, 0x143c, + 0x1470, 0x1470, 0x13ce, 0x1a59, 0x147a, 0x13c8, 0x13da, 0x13db, + 0x13dc, 0x13dd, 0x1a5d, 0x13c8, 0x1487, 0x14db, 0x1931, 0x1a53, + 0x13de, 0x17ba, 0x17f0, 0x1822, 0x1868, 0x1777, 0x1784, 0x1797, + 0x17a9, 0x15b0, 0x13c8, 0x150d, 0x1518, 0x1526, 0x1534, 0x154b, + 0x1559, 0x155c, 0x156a, 0x1578, 0x1582, 0x1596, 0x15a2, 0x13c8, + 0x13c8, 0x13c8, 0x13c8, 0x15bd, 0x15ce, 0x15e8, 0x161c, 0x1645, + 0x1657, 0x165a, 0x1685, 0x16be, 0x16d0, 0x1745, 0x1755, 0x13c8, + 0x13c8, 0x13c8, 0x13c8, 0x1767, 0x2100, 0xa08a, 0x0040, 0x1a04, + 0x13c8, 0x0002, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x1a7f, + 0x1a85, 0x13c8, 0x13c8, 0x13c8, 0x1a89, 0x1ac9, 0x13c8, 0x13c8, + 0x13c8, 0x13c8, 0x1403, 0x146b, 0x1482, 0x14d6, 0x192c, 0x13c8, + 0x13c8, 0x18fb, 0x13c8, 0x1acd, 0x1a71, 0x1a7b, 0x13c8, 0x13c8, + 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, + 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, + 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, + 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, + 0x13c8, 0x13c8, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0028, 0x73ce, + 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0e04, 0x13bd, 0x2061, + 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x0005, + 0x70c3, 0x4001, 0x0c90, 0x70c3, 0x4006, 0x0c78, 0x2099, 0x0041, + 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0c20, 0x70c4, 0x70c3, + 0x0004, 0x0807, 0x08f8, 0x08f0, 0x08e8, 0x08e0, 0x2091, 0x8000, + 0x70c3, 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, + 0x70d3, 0x000a, 0x2001, 0x0004, 0x70d6, 0x2079, 0x0000, 0x781b, + 0x0001, 0x2031, 0x0030, 0x2059, 0x1000, 0x2029, 0x041a, 0x2051, + 0x0445, 0x2061, 0x0447, 0x20c1, 0x0020, 0x2091, 0x5000, 0x2091, + 0x4080, 0x0804, 0x0418, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0018, + 0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x20a0, + 0x2099, 0x0030, 0x7003, 0x0001, 0x7007, 0x0006, 0x731a, 0x721e, + 0x7422, 0x7526, 0x2021, 0x0040, 0x81ff, 0x0904, 0x13ba, 0xa182, + 0x0040, 0x1210, 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x7007, + 0x0004, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0de8, 0x7007, 0x0002, + 0xa084, 0x01e0, 0x0120, 0x70c3, 0x4002, 0x0804, 0x13bd, 0x24a8, + 0x53a5, 0x0c10, 0x0804, 0x13ba, 0x2029, 0x0000, 0x2520, 0x71d0, + 0x72c8, 0x73cc, 0x70c4, 0x2098, 0x20a1, 0x0030, 0x7003, 0x0000, + 0x7007, 0x0006, 0x731a, 0x721e, 0x7422, 0x7526, 0x2021, 0x0040, + 0x7007, 0x0006, 0x81ff, 0x0904, 0x13ba, 0xa182, 0x0040, 0x1210, + 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x24a8, 0x53a6, 0x7007, + 0x0001, 0x7008, 0xd0fc, 0x0de8, 0xa084, 0x01e0, 0x0d48, 0x70c3, + 0x4002, 0x0804, 0x13bd, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0878, + 0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004, 0x1108, 0x200a, 0x72ca, + 0x0804, 0x13b9, 0x70c7, 0x000a, 0x70cb, 0x0004, 0x70cf, 0x0020, + 0x0804, 0x13ba, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0018, 0x2029, + 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0, 0x70c6, 0x72ca, + 0x73ce, 0x74d2, 0xa005, 0x05e8, 0xa40a, 0x0108, 0x1240, 0x8001, + 0x7872, 0xa084, 0xfc00, 0x0138, 0x78ac, 0xc085, 0x78ae, 0x2001, + 0x4005, 0x0804, 0x13bc, 0x7b7e, 0x7a7a, 0x7e86, 0x7d82, 0x7c76, + 0xa48c, 0xff00, 0x0170, 0x8407, 0x8004, 0x8004, 0x810c, 0x810c, + 0x810f, 0xa118, 0xa291, 0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000, + 0x0050, 0x8407, 0x8004, 0x8004, 0xa318, 0xa291, 0x0000, 0xa6b1, + 0x0000, 0xa581, 0x0000, 0x731a, 0x721e, 0x7622, 0x7026, 0xa605, + 0x0118, 0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084, 0xfffc, 0x78ae, + 0x0018, 0x78ac, 0xc085, 0x78ae, 0x0804, 0x13ba, 0x75d8, 0x76dc, + 0x75da, 0x76de, 0x0018, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, + 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6, 0xa005, 0x0500, + 0xa40a, 0x0110, 0x1a04, 0x13bc, 0x8001, 0x7892, 0xa084, 0xfc00, + 0x0138, 0x78ac, 0xc0c5, 0x78ae, 0x2001, 0x4005, 0x0804, 0x13bc, + 0x7a9a, 0x7b9e, 0x7da2, 0x7ea6, 0x2600, 0xa505, 0x0118, 0x7a10, + 0xc2c5, 0x7a12, 0x7c96, 0x78ac, 0xa084, 0xfcff, 0x78ae, 0x0018, + 0x78ac, 0xc0c5, 0x78ae, 0x0804, 0x13ba, 0x2009, 0x0000, 0x786c, + 0xa065, 0x0118, 0x8108, 0x6000, 0x0cd8, 0x7ac4, 0x0804, 0x13b8, + 0x2009, 0x4648, 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, + 0x13b9, 0x2011, 0x4688, 0x2214, 0x0804, 0x13b8, 0x2009, 0x4649, + 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011, + 0x4689, 0x2214, 0x0804, 0x13b8, 0x2061, 0x4640, 0x6128, 0x622c, + 0x8214, 0x8214, 0x8214, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1148, + 0x2061, 0x4680, 0x6328, 0x73da, 0x632c, 0x831c, 0x831c, 0x831c, + 0x73de, 0x0804, 0x13b8, 0x2009, 0x464c, 0x210c, 0x2001, 0x01ff, + 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011, 0x468c, 0x2214, 0x0804, + 0x13b8, 0x7918, 0x0804, 0x13b9, 0x2009, 0x0202, 0x210c, 0x2001, + 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011, 0x0102, 0x2214, + 0x0804, 0x13b8, 0x2009, 0x464d, 0x210c, 0x2001, 0x01ff, 0x2004, + 0xd0fc, 0x1904, 0x13b9, 0x2011, 0x468d, 0x2214, 0x0804, 0x13b8, + 0x7920, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x7a24, + 0x0804, 0x13b8, 0x2011, 0x4b40, 0x71c4, 0xd1fc, 0x1110, 0x2011, + 0x4ac0, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268, + 0x6a00, 0x6b08, 0x6c1c, 0x74da, 0x0804, 0x13b7, 0x77c4, 0x080c, + 0x1b7b, 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, + 0x0804, 0x13b7, 0x2061, 0x4640, 0x6118, 0x2001, 0x01ff, 0x2004, + 0xd0fc, 0x1904, 0x13b9, 0x2061, 0x4680, 0x6218, 0x0804, 0x13b8, + 0x77c4, 0x080c, 0x1b7b, 0x2091, 0x8000, 0x6908, 0x6a18, 0x6b10, + 0x77da, 0x2091, 0x8001, 0x0804, 0x13b7, 0x71c4, 0x2110, 0xa294, + 0x000f, 0xa282, 0x0010, 0x1a04, 0x13b3, 0x080c, 0x238b, 0xa384, + 0x4000, 0x0110, 0xa295, 0x0020, 0x0804, 0x13b7, 0x71c4, 0x2100, + 0xc0bc, 0xa082, 0x0010, 0x1a04, 0x13b3, 0xd1bc, 0x1120, 0x2011, + 0x4648, 0x2204, 0x0020, 0x2011, 0x4688, 0x2204, 0xc0bd, 0x0006, + 0x2100, 0xc0bc, 0x2012, 0x080c, 0x2331, 0x001e, 0x0804, 0x13b9, + 0x71c4, 0x2021, 0x4649, 0x2404, 0x70c6, 0x2019, 0x0000, 0x0030, + 0x71c8, 0x2021, 0x4689, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x1614, + 0x20a9, 0x0008, 0x2204, 0xa106, 0x0138, 0x8210, 0x1f04, 0x15fa, + 0x71c4, 0x72c8, 0x0804, 0x13b2, 0xa292, 0x1614, 0x0026, 0x2122, + 0x001e, 0x080c, 0x2343, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1110, + 0xd3fc, 0x09f0, 0x0804, 0x13ba, 0x03e8, 0x00fa, 0x01f4, 0x02ee, + 0x0004, 0x0001, 0x0002, 0x0003, 0x2061, 0x4640, 0x6128, 0x622c, + 0x8214, 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, 0x8003, 0x8003, + 0x8003, 0x602e, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x11a0, 0x0026, + 0x0016, 0x2061, 0x4680, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, + 0x70d8, 0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, 0x602e, 0x71da, + 0x72de, 0x001e, 0x002e, 0x0804, 0x13b8, 0x2061, 0x4640, 0x6130, + 0x70c4, 0x6032, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, + 0x2061, 0x4680, 0x6230, 0x70c8, 0x6032, 0x0804, 0x13b8, 0x7918, + 0x0804, 0x13b9, 0x71c4, 0xa184, 0xf0cf, 0x0148, 0x2001, 0x01ff, + 0x2004, 0xd0fc, 0x1904, 0x13b3, 0x72c8, 0x0804, 0x13b2, 0x0006, + 0x2019, 0x0000, 0x080c, 0x237f, 0x2001, 0x01ff, 0x2004, 0xd0fc, + 0x0118, 0x001e, 0x0804, 0x13b9, 0x71c8, 0xa184, 0xf0cf, 0x0128, + 0x0006, 0x2110, 0x71c4, 0x0804, 0x13b2, 0x0006, 0xc3fd, 0x080c, + 0x237f, 0x002e, 0x001e, 0x0804, 0x13b8, 0x71c4, 0xa182, 0x0010, + 0x0248, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b3, 0x72c8, + 0x0804, 0x13b2, 0x2011, 0x464d, 0x2204, 0x0006, 0x8104, 0x1208, + 0x8108, 0x2112, 0x2019, 0x0000, 0x080c, 0x236c, 0x2001, 0x01ff, + 0x2004, 0xd0fc, 0x0118, 0x001e, 0x0804, 0x13b9, 0x71c8, 0xa182, + 0x0010, 0x0228, 0x0006, 0x2110, 0x71c4, 0x0804, 0x13b2, 0x2011, + 0x468d, 0x2204, 0x0006, 0x8104, 0x1208, 0x8108, 0x2112, 0xc3fd, + 0x080c, 0x236c, 0x002e, 0x001e, 0x0804, 0x13b8, 0x71c4, 0x72c8, + 0xa184, 0xfffd, 0x1904, 0x13b2, 0xa284, 0xfffd, 0x1904, 0x13b2, + 0x2100, 0x7920, 0x7822, 0x2200, 0x7a24, 0x7826, 0x0804, 0x13b8, + 0x2011, 0x4b40, 0x71c4, 0xd1fc, 0x1110, 0x2011, 0x4ac0, 0x8107, + 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268, 0x72c8, 0x73cc, + 0x74d8, 0x71c6, 0x6800, 0x70ca, 0x73ce, 0x74da, 0x2091, 0x8000, + 0x6a02, 0xd2ac, 0x1118, 0x2021, 0x0000, 0x0090, 0xa484, 0x00ff, + 0xa082, 0x0002, 0x1a04, 0x1741, 0x843f, 0xa7bc, 0x00ff, 0x0140, + 0xa786, 0x0002, 0x1904, 0x1741, 0xa484, 0x00ff, 0x0904, 0x1741, + 0x2061, 0x0200, 0xd1fc, 0x0110, 0x2061, 0x0100, 0x2029, 0x0009, + 0x2031, 0x0062, 0x843f, 0xa7bc, 0x00ff, 0x0130, 0x8307, 0xa084, + 0x00ff, 0x1110, 0xa73d, 0x1138, 0x2041, 0x0019, 0xa384, 0x00ff, + 0xa082, 0x001a, 0x0210, 0xa4a4, 0x00ff, 0x8307, 0xa084, 0x00ff, + 0x0188, 0xa842, 0x02f0, 0xa086, 0x0010, 0x1120, 0xa39c, 0x00ff, + 0xa39d, 0x0f00, 0xa3bc, 0x00ff, 0x2500, 0xa702, 0x0290, 0x2600, + 0xa702, 0x1278, 0x2039, 0x003a, 0x6804, 0xa705, 0x6806, 0x6b0a, + 0x6b0c, 0x73ce, 0x681c, 0x70da, 0x6c1e, 0x2091, 0x8001, 0x0804, + 0x13ba, 0x2091, 0x8001, 0x0804, 0x13b4, 0x77c4, 0x080c, 0x1b7b, + 0x2091, 0x8000, 0x6a14, 0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, + 0x70cc, 0x681e, 0x2708, 0x0804, 0x13b7, 0x70c4, 0x2061, 0x4640, + 0x6118, 0x601a, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, + 0x70c8, 0x2061, 0x4680, 0x6218, 0x601a, 0x0804, 0x13b8, 0x71c4, + 0x72c8, 0x73cc, 0xa182, 0x0010, 0x1a04, 0x13b3, 0x080c, 0x23af, + 0xa384, 0x4000, 0x0110, 0xa295, 0x0020, 0x0804, 0x13b7, 0x77c4, + 0x080c, 0x1b7b, 0x2091, 0x8000, 0x6a08, 0xc28d, 0x6a0a, 0x2091, + 0x8001, 0x2708, 0x0804, 0x13b8, 0x77c4, 0x080c, 0x1b7b, 0x2091, + 0x8000, 0x6a08, 0xa294, 0xfff9, 0x6a0a, 0x6804, 0xa005, 0x0110, + 0x080c, 0x22ae, 0x2091, 0x8001, 0x2708, 0x0804, 0x13b8, 0x77c4, + 0x080c, 0x1b7b, 0x2091, 0x8000, 0x6a08, 0xc295, 0x6a0a, 0x6804, + 0xa005, 0x0110, 0x080c, 0x22ae, 0x2091, 0x8001, 0x2708, 0x0804, + 0x13b8, 0x77c4, 0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, + 0x2091, 0x8000, 0x080c, 0x1b93, 0x2091, 0x8001, 0x2708, 0x6a08, + 0x0804, 0x13b8, 0x77c4, 0xd7fc, 0x0128, 0x080c, 0x1b0a, 0x0138, + 0x0804, 0x13bc, 0x080c, 0x1aff, 0x0110, 0x0804, 0x13bc, 0x73c8, + 0x72cc, 0x77c6, 0x73ca, 0x72ce, 0x080c, 0x1c0b, 0x11e8, 0x6818, + 0xa005, 0x01a0, 0x2708, 0x0076, 0x080c, 0x23ce, 0x007e, 0x1170, + 0x2001, 0x0015, 0xd7fc, 0x1118, 0x2061, 0x4640, 0x0018, 0xc0fd, + 0x2061, 0x4680, 0x782a, 0x2091, 0x8001, 0x0005, 0x2091, 0x8001, + 0x2001, 0x4005, 0x0804, 0x13bc, 0x2091, 0x8001, 0x0804, 0x13ba, + 0x77c4, 0xd7fc, 0x0128, 0x080c, 0x1b0a, 0x0138, 0x0804, 0x13bc, + 0x080c, 0x1aff, 0x0110, 0x0804, 0x13bc, 0x77c6, 0x2041, 0x0021, + 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x080c, 0x1b93, + 0x2009, 0x0016, 0xd7fc, 0x1118, 0x2061, 0x4640, 0x0018, 0x2061, + 0x4680, 0xc1fd, 0x6063, 0x0003, 0x607b, 0x0000, 0x6772, 0x607f, + 0x000f, 0x792a, 0x61d0, 0xc1c4, 0x61d2, 0x080c, 0x22ae, 0x2091, 0x8001, 0x0005, 0x77c8, 0x77ca, 0x77c4, 0x77c6, 0xd7fc, 0x0128, - 0x080c, 0x1aa9, 0x0138, 0x0804, 0x13a5, 0x080c, 0x1a9b, 0x0110, - 0x0804, 0x13a5, 0xa7bc, 0xff00, 0x2091, 0x8000, 0x2009, 0x0017, - 0xd7fc, 0x1118, 0x2061, 0x4340, 0x0018, 0x2061, 0x4380, 0xc1fd, - 0x607f, 0x0000, 0x6067, 0x0002, 0x6776, 0x6083, 0x000f, 0x792a, - 0x080c, 0x2233, 0x2091, 0x8001, 0x2041, 0x0021, 0x2049, 0x0005, - 0x2051, 0x0010, 0x2091, 0x8000, 0x70c8, 0xa005, 0x0118, 0x60d4, - 0xc0fd, 0x60d6, 0x080c, 0x1b35, 0x70c8, 0x6836, 0x8738, 0xa784, - 0x001f, 0x1dc0, 0x2091, 0x8001, 0x0005, 0x72c8, 0xd284, 0x0128, - 0x080c, 0x1aa9, 0x0138, 0x0804, 0x13a5, 0x080c, 0x1a9b, 0x0110, - 0x0804, 0x13a5, 0x72c8, 0x72ca, 0x78ac, 0xa084, 0x0003, 0x1508, - 0x2039, 0x0000, 0xd284, 0x0108, 0xc7fd, 0x2041, 0x0021, 0x2049, - 0x0004, 0x2051, 0x0008, 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6808, - 0xc0d4, 0xa80d, 0x690a, 0x2091, 0x8001, 0x8738, 0xa784, 0x001f, - 0x1d90, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, - 0x1d50, 0x2091, 0x8000, 0x72c8, 0x2069, 0x0100, 0xd284, 0x1110, - 0x2069, 0x0200, 0x6808, 0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4, - 0x01b0, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xd094, 0x0110, - 0x1f04, 0x1885, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, - 0x0110, 0x1f04, 0x188e, 0x20a9, 0x00fa, 0x1f04, 0x1895, 0x2079, - 0x4300, 0x2009, 0x0018, 0x72c8, 0xd284, 0x1118, 0x2061, 0x4340, - 0x0018, 0x2061, 0x4380, 0xc1fd, 0x792a, 0x6067, 0x0001, 0x6083, - 0x000f, 0x60a7, 0x0000, 0x60a8, 0x60b2, 0x60b6, 0x60d4, 0xd0b4, - 0x0160, 0xc0b4, 0x60d6, 0x00c6, 0x60b8, 0xa065, 0x6008, 0xc0d4, - 0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, 0x60d4, 0xa084, 0x7eff, - 0x60d6, 0x78ac, 0xc08d, 0x78ae, 0x681b, 0x0054, 0x2091, 0x8001, - 0x0005, 0xd7fc, 0x1118, 0x2069, 0x4340, 0x0010, 0x2069, 0x4380, - 0x71c4, 0x71c6, 0x6916, 0x81ff, 0x1110, 0x68a7, 0x0001, 0x78ac, - 0xc08c, 0x78ae, 0xd084, 0x1110, 0x080c, 0x1c00, 0x0005, 0x75d8, - 0x74dc, 0x75da, 0x74de, 0x0018, 0x2029, 0x0000, 0x2520, 0x71c4, - 0x73c8, 0x72cc, 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x4300, 0x7dde, - 0x7cda, 0x7bd6, 0x7ad2, 0x080c, 0x1afa, 0x0904, 0x19d7, 0x20a9, - 0x0005, 0x20a1, 0x4314, 0x2091, 0x8000, 0x41a1, 0x2091, 0x8001, - 0x2009, 0x0040, 0x080c, 0x1cbf, 0x0120, 0x080c, 0x1b02, 0x0804, - 0x19d7, 0x6004, 0xa08c, 0x00ff, 0xa18e, 0x0009, 0x1120, 0x0006, - 0x080c, 0x1fe3, 0x000e, 0xa084, 0xff00, 0x8007, 0x8009, 0x0904, - 0x1981, 0x00c6, 0x2c68, 0x080c, 0x1afa, 0x05a8, 0x2c00, 0x689e, - 0x8109, 0x1dc0, 0x609f, 0x0000, 0x00ce, 0x00c6, 0x7ddc, 0x7cd8, - 0x7bd4, 0x7ad0, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, - 0xa5a9, 0x0000, 0x7dde, 0x7cda, 0x7bd6, 0x7ad2, 0x2c68, 0x689c, - 0xa065, 0x0904, 0x1980, 0x2009, 0x0040, 0x080c, 0x1cbf, 0x1550, - 0x6004, 0xa084, 0x00ff, 0xa086, 0x0002, 0x1168, 0x6004, 0xa084, - 0x00ff, 0xa086, 0x000a, 0x1120, 0x0016, 0x080c, 0x1fe0, 0x001e, - 0x2d00, 0x6002, 0x0898, 0x00ce, 0x00c6, 0x609c, 0x080c, 0x1b76, - 0x00ce, 0x609f, 0x0000, 0x080c, 0x19db, 0x2009, 0x0018, 0x6008, - 0xc0cd, 0x600a, 0x6004, 0x6086, 0x080c, 0x1ab7, 0x080c, 0x1b02, - 0x0804, 0x19d7, 0x00ce, 0x00c6, 0x609c, 0x080c, 0x1b76, 0x00ce, - 0x609f, 0x0000, 0x080c, 0x19db, 0x2009, 0x0018, 0x6087, 0x0103, - 0x601b, 0x0003, 0x080c, 0x1ab7, 0x080c, 0x1b02, 0x0804, 0x19d7, - 0x00ce, 0x6114, 0xd1fc, 0x0120, 0x080c, 0x1aa9, 0x01b8, 0x0018, - 0x080c, 0x1a9b, 0x0198, 0x2029, 0x0000, 0x2520, 0x2009, 0x0018, - 0x73c8, 0x72cc, 0x6087, 0x0103, 0x601b, 0x0021, 0x080c, 0x1ab7, - 0x080c, 0x1b02, 0x2001, 0x4007, 0x0804, 0x13a5, 0x74c4, 0x73c8, - 0x72cc, 0x6014, 0x2091, 0x8000, 0x00e6, 0x2009, 0x0012, 0xd0fc, - 0x1118, 0x2071, 0x4340, 0x0018, 0x2071, 0x4380, 0xc1fd, 0x792a, - 0x7067, 0x0005, 0x71d4, 0xa18c, 0xfe7f, 0x71d6, 0x736a, 0x726e, - 0x7472, 0x7076, 0x707b, 0x0000, 0x2c00, 0x707e, 0xa02e, 0x2530, - 0x611c, 0xa184, 0x0060, 0x0110, 0x080c, 0x3de5, 0x00ee, 0x6596, - 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x6714, - 0x6023, 0x0000, 0x080c, 0x2233, 0x2091, 0x8001, 0x0005, 0x70c3, - 0x4005, 0x0804, 0x13a6, 0x20a9, 0x0005, 0x2099, 0x4314, 0x2091, - 0x8000, 0x530a, 0x2091, 0x8001, 0x2100, 0xa210, 0xa399, 0x0000, - 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x0005, 0x71c4, 0x70c7, 0x0000, - 0x791e, 0x0804, 0x13a3, 0x71c4, 0x71c6, 0x2168, 0x0010, 0x2069, - 0x1000, 0x690c, 0xa016, 0x2d04, 0xa210, 0x8d68, 0x8109, 0x1dd8, - 0xa285, 0x0000, 0x1118, 0x70c3, 0x4000, 0x0010, 0x70c3, 0x4003, - 0x70ca, 0x0804, 0x13a6, 0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, - 0x1a04, 0x139c, 0x7966, 0x0804, 0x13a3, 0x7964, 0x71c6, 0x0804, - 0x13a3, 0x7900, 0x71c6, 0x71c4, 0x7902, 0x0804, 0x13a3, 0x7900, - 0x71c6, 0x0804, 0x13a3, 0x70c4, 0x2011, 0x0000, 0xa08c, 0x000d, - 0x0160, 0x810c, 0x0230, 0x8210, 0x810c, 0x810c, 0x0210, 0x8210, - 0x810c, 0x81ff, 0x1904, 0x139d, 0x8210, 0x7a0e, 0xd28c, 0x0538, - 0x7910, 0xc1cd, 0x7912, 0x2009, 0x0021, 0x2019, 0x0003, 0xd284, - 0x01c0, 0x8108, 0x2019, 0x0041, 0x2011, 0x8b4e, 0x2312, 0x2019, - 0x0042, 0x8210, 0x2312, 0x2019, 0x0043, 0x8210, 0x2312, 0x2019, - 0x0046, 0x8210, 0x2312, 0x2019, 0x0047, 0x8210, 0x2312, 0x2019, - 0x0006, 0x2011, 0x8b53, 0x2112, 0x2011, 0x8b73, 0x2312, 0x7904, - 0x7806, 0x0804, 0x13a2, 0x7804, 0x70c6, 0x0804, 0x13a3, 0x71c4, - 0xd1fc, 0x1118, 0x2011, 0x47c0, 0x0010, 0x2011, 0x4840, 0x8107, - 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268, 0x2011, 0x0000, - 0x6814, 0xd0fc, 0x0110, 0xa295, 0x0200, 0xd0b4, 0x0110, 0xa295, - 0x0001, 0x6b0c, 0x0804, 0x13a0, 0x0016, 0x7814, 0xd0f4, 0x0138, - 0x2001, 0x4007, 0x70db, 0x0000, 0xa18d, 0x0001, 0x0050, 0xd0fc, - 0x0138, 0x2001, 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0008, - 0xa006, 0x001e, 0x0005, 0x0016, 0x7814, 0xd0f4, 0x0138, 0x2001, - 0x4007, 0x70db, 0x0000, 0xa18d, 0x0001, 0x0008, 0xa006, 0x001e, - 0x0005, 0x0016, 0x7814, 0xd0fc, 0x0138, 0x2001, 0x4007, 0x70db, - 0x0001, 0xa18d, 0x0001, 0x0008, 0xa006, 0x001e, 0x0005, 0x7112, - 0x721a, 0x731e, 0x7810, 0xd0c4, 0x0110, 0x7422, 0x7526, 0xac80, - 0x0001, 0x8108, 0x810c, 0x81a9, 0x8098, 0x20a1, 0x0030, 0x7003, - 0x0000, 0x6084, 0x20a2, 0x53a6, 0x7007, 0x0001, 0x7974, 0xa184, - 0xff00, 0x0140, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, - 0xa100, 0x0018, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, - 0xa006, 0xa211, 0x7d10, 0xd5c4, 0x0120, 0x7b84, 0xa319, 0x7c80, - 0xa421, 0x7008, 0xd0fc, 0x0de8, 0x7003, 0x0001, 0x7007, 0x0006, - 0x711a, 0x721e, 0x7d10, 0xd5c4, 0x0110, 0x7322, 0x7426, 0xa084, - 0x01e0, 0x0005, 0x7848, 0xa065, 0x0120, 0x2c04, 0x784a, 0x2063, - 0x0000, 0x0005, 0x00f6, 0x2079, 0x4300, 0x7848, 0x2062, 0x2c00, - 0xa005, 0x1110, 0x080c, 0x243b, 0x784a, 0x00fe, 0x0005, 0x2011, - 0x8d00, 0x7a4a, 0x7bc4, 0x8319, 0x0128, 0xa280, 0x0032, 0x2012, - 0x2010, 0x0cc8, 0x2013, 0x0000, 0x0005, 0x0016, 0x0026, 0xd7fc, - 0x1118, 0x2011, 0x48c0, 0x0010, 0x2011, 0x68c0, 0xa784, 0x0f00, - 0x800b, 0xa784, 0x001f, 0x0120, 0x8003, 0x8003, 0x8003, 0x8003, - 0xa105, 0xa268, 0x002e, 0x001e, 0x0005, 0x0c39, 0x2900, 0x682a, - 0x2a00, 0x682e, 0x6808, 0xa084, 0xf9ef, 0xa80d, 0x690a, 0x00e6, - 0xd7fc, 0x1128, 0x2009, 0x4353, 0x2071, 0x4340, 0x0020, 0x2009, - 0x4393, 0x2071, 0x4380, 0x210c, 0x6804, 0xa005, 0x0148, 0xa116, - 0x1138, 0x2060, 0x6000, 0x6806, 0x0016, 0x200b, 0x0000, 0x0018, - 0x2009, 0x0000, 0x0016, 0x6804, 0xa065, 0x0178, 0x6000, 0x6806, - 0x0421, 0x080c, 0x1d30, 0x6810, 0x7908, 0x8109, 0x790a, 0x8001, - 0x6812, 0x1d88, 0x7910, 0xc1a5, 0x7912, 0x001e, 0x6902, 0x6906, - 0x2d00, 0x2060, 0x080c, 0x2580, 0x00ee, 0x0005, 0xa065, 0x0160, - 0x2008, 0x609c, 0xa005, 0x0128, 0x2062, 0x609f, 0x0000, 0xa065, - 0x0cc0, 0x7848, 0x794a, 0x2062, 0x0005, 0x6007, 0x0103, 0x608f, - 0x0000, 0x20a9, 0x001c, 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, - 0x40a4, 0x6828, 0x601a, 0x682c, 0x6022, 0x0005, 0x00e6, 0xd7fc, - 0x1128, 0x2071, 0x4340, 0x2031, 0x43c0, 0x0020, 0x2071, 0x4380, - 0x2031, 0x45c0, 0x7050, 0xa08c, 0x0200, 0x1128, 0xa608, 0x2d0a, - 0x8000, 0x7052, 0xa006, 0x00ee, 0x0005, 0x00f6, 0xd7fc, 0x1118, - 0x2079, 0x4340, 0x0010, 0x2079, 0x4380, 0x080c, 0x1b1d, 0x2091, - 0x8000, 0x6804, 0x780a, 0xa065, 0x0904, 0x1bfe, 0x0030, 0x2c00, - 0x780a, 0x2060, 0x6000, 0xa065, 0x05c8, 0x6010, 0xa306, 0x1db8, - 0x600c, 0xa206, 0x1da0, 0x2c28, 0x784c, 0xac06, 0x1108, 0x0458, - 0x6804, 0xac06, 0x1140, 0x6000, 0x2060, 0x6806, 0xa005, 0x1118, - 0x6803, 0x0000, 0x0048, 0x6400, 0x7808, 0x2060, 0x6402, 0xa486, - 0x0000, 0x1110, 0x2c00, 0x6802, 0x2560, 0x00fe, 0x080c, 0x1b85, - 0x00f6, 0x601b, 0x0005, 0x6023, 0x0020, 0x00fe, 0x080c, 0x1d30, - 0x00f6, 0x7908, 0x8109, 0x790a, 0x6810, 0x8001, 0x6812, 0x1118, - 0x7810, 0xc0a5, 0x7812, 0x2001, 0xffff, 0xa005, 0x00fe, 0x0005, - 0x0076, 0x2700, 0x2039, 0x0000, 0xd0fc, 0x0108, 0xc7fd, 0x2041, - 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x2091, 0x8000, 0x080c, - 0x1b35, 0x8738, 0xa784, 0x001f, 0x1dd0, 0xa7bc, 0xff00, 0x873f, - 0x8738, 0x873f, 0xa784, 0x0f00, 0x1d90, 0x2091, 0x8001, 0x007e, - 0x0005, 0x786c, 0x2009, 0x8b74, 0x210c, 0xa10d, 0x0118, 0xa065, - 0x0804, 0x1ffe, 0x2061, 0x0000, 0x6018, 0xd084, 0x11b8, 0x7810, - 0xd08c, 0x0130, 0xc08c, 0x7812, 0xc7fc, 0x2069, 0x4340, 0x0028, - 0xc08d, 0x7812, 0x2069, 0x4380, 0xc7fd, 0x2091, 0x8000, 0x681c, - 0x681f, 0x0000, 0x2091, 0x8001, 0xa005, 0x1108, 0x0005, 0xa08c, - 0xfff0, 0x0110, 0x080c, 0x243b, 0x0002, 0x1c5d, 0x1c60, 0x1c66, - 0x1c6a, 0x1c5e, 0x1c6e, 0x1c5e, 0x1c5e, 0x1c5e, 0x1c73, 0x1c9f, - 0x1ca2, 0x1ca7, 0x1c5e, 0x1c5e, 0x1c5e, 0x0005, 0x080c, 0x243b, - 0x080c, 0x1c00, 0x2001, 0x8001, 0x0804, 0x1cb0, 0x2001, 0x8003, - 0x0804, 0x1cb0, 0x2001, 0x8004, 0x0804, 0x1cb0, 0x080c, 0x1c00, - 0x2001, 0x8006, 0x04e8, 0x2091, 0x8000, 0x0076, 0xd7fc, 0x1128, - 0x2069, 0x4340, 0x2039, 0x0009, 0x0020, 0x2069, 0x4380, 0x2039, - 0x0009, 0x6800, 0xa086, 0x0000, 0x0128, 0x000e, 0x6f1e, 0x2091, - 0x8001, 0x0005, 0x6874, 0x007e, 0xa0bc, 0xff00, 0x2041, 0x0021, - 0x2049, 0x0004, 0x2051, 0x0010, 0x080c, 0x1b35, 0x8738, 0xa784, - 0x001f, 0x1dd0, 0x2091, 0x8001, 0x2001, 0x800a, 0x0088, 0x2001, - 0x800c, 0x0070, 0x080c, 0x1c00, 0x2001, 0x800d, 0x0048, 0xd7fc, - 0x0110, 0x78ec, 0x0008, 0x78e4, 0x70c6, 0x2001, 0x800e, 0x0000, - 0x70c2, 0xd7fc, 0x1118, 0x70db, 0x0000, 0x0010, 0x70db, 0x0001, - 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080, 0x0005, 0xac80, - 0x0001, 0x81ff, 0x0518, 0x2099, 0x0030, 0x20a0, 0x700c, 0xa084, - 0x07ff, 0x0100, 0x7018, 0x0006, 0x701c, 0x0006, 0x7020, 0x0006, - 0x7024, 0x0006, 0x7112, 0x81ac, 0x721a, 0x731e, 0x7422, 0x7526, - 0x7003, 0x0001, 0x7007, 0x0001, 0x7008, 0x800b, 0x1ee8, 0x7007, - 0x0002, 0xa08c, 0x01e0, 0x1110, 0x53a5, 0xa006, 0x7003, 0x0000, - 0x7007, 0x0004, 0x000e, 0x7026, 0x000e, 0x7022, 0x000e, 0x701e, - 0x000e, 0x701a, 0x0005, 0x2011, 0x0020, 0x2009, 0x0010, 0x6b0a, - 0x6c0e, 0x681f, 0x0201, 0x6803, 0xfd20, 0x6807, 0x0038, 0x6a1a, - 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004, 0x8109, 0x1d80, 0x0005, - 0x70ec, 0xd0dc, 0x1520, 0x2029, 0x0001, 0x7814, 0xd0cc, 0x1160, - 0x70ec, 0xd0e4, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1120, 0x2019, - 0x0c0c, 0x2021, 0x000c, 0x0070, 0x70ec, 0xd0e4, 0x1128, 0x2019, - 0x1c0c, 0x2021, 0x000c, 0x0030, 0x2019, 0x1c09, 0x2021, 0x0009, - 0xa5ad, 0x0200, 0x6b0a, 0x6c0e, 0x6d1e, 0x6807, 0x0038, 0x0005, - 0x6004, 0x6086, 0x2c08, 0x2063, 0x0000, 0x7868, 0xa005, 0x796a, - 0x0110, 0x2c02, 0x0008, 0x796e, 0x0005, 0x00c6, 0x2061, 0x4300, - 0x6887, 0x0103, 0x2d08, 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, - 0x0110, 0x2d02, 0x0008, 0x616e, 0x00ce, 0x0005, 0x2091, 0x8000, - 0x2c04, 0x786e, 0xa005, 0x1108, 0x786a, 0x2091, 0x8001, 0x609c, - 0xa005, 0x0188, 0x00c6, 0x2060, 0x2008, 0x609c, 0xa005, 0x0138, - 0x2062, 0x609f, 0x0000, 0xa065, 0x609c, 0xa005, 0x1dc8, 0x7848, - 0x794a, 0x2062, 0x00ce, 0x7848, 0x2062, 0x609f, 0x0000, 0xac85, - 0x0000, 0x1110, 0x080c, 0x243b, 0x784a, 0x0005, 0x20a9, 0x0010, - 0xa006, 0x8004, 0x8086, 0x818e, 0x1208, 0xa200, 0x1f04, 0x1d7a, - 0x8086, 0x818e, 0x0005, 0x0156, 0x20a9, 0x0010, 0xa005, 0x01b8, - 0xa11a, 0x12a8, 0x8213, 0x818d, 0x0228, 0xa11a, 0x1220, 0x1f04, - 0x1d8a, 0x0028, 0xa11a, 0x2308, 0x8210, 0x1f04, 0x1d8a, 0x0006, - 0x3200, 0xa084, 0xefff, 0x2080, 0x000e, 0x015e, 0x0005, 0x0006, - 0x3200, 0xa085, 0x1000, 0x0cb8, 0x7d74, 0x70d0, 0xa506, 0x0904, - 0x1e5b, 0x7810, 0x2050, 0x7800, 0xd08c, 0x0100, 0x080c, 0x1afa, - 0x0904, 0x1e5b, 0xa046, 0x7970, 0x2500, 0x8000, 0xa112, 0x2009, - 0x0040, 0x1208, 0x0030, 0x72d0, 0xa206, 0x0118, 0x8840, 0x2009, - 0x0080, 0x00c6, 0x7112, 0x7007, 0x0001, 0x2099, 0x0030, 0x20a9, - 0x0020, 0xac80, 0x0001, 0x20a0, 0x2061, 0x0000, 0x88ff, 0x0110, - 0x080c, 0x1afa, 0x7008, 0xd0fc, 0x0de8, 0x7007, 0x0002, 0x2091, - 0x8001, 0xa08c, 0x01e0, 0x1538, 0x53a5, 0x8cff, 0x1120, 0x88ff, - 0x0904, 0x1e48, 0x0050, 0x2c00, 0x788e, 0x20a9, 0x0020, 0xac80, - 0x0001, 0x20a0, 0x53a5, 0x0804, 0x1e48, 0xa046, 0x7218, 0x731c, - 0xdac4, 0x0110, 0x7420, 0x7524, 0xa292, 0x0040, 0xa39b, 0x0000, - 0xa4a3, 0x0000, 0xa5ab, 0x0000, 0x721a, 0x731e, 0xdac4, 0x0118, - 0x7422, 0x7526, 0xa006, 0x7007, 0x0004, 0x0904, 0x1e48, 0x8cff, - 0x0110, 0x080c, 0x1b02, 0x00ce, 0x080c, 0x1b02, 0xa046, 0x7888, - 0x8000, 0x788a, 0xa086, 0x0002, 0x01c0, 0x7a7c, 0x7b78, 0xdac4, - 0x0110, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004, 0x8004, 0xa210, - 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x721a, 0x731e, - 0xdac4, 0x0588, 0x7422, 0x7526, 0x0470, 0x6014, 0xd0fc, 0x1118, - 0x2069, 0x4340, 0x0010, 0x2069, 0x4380, 0x2091, 0x8000, 0x681f, - 0x0002, 0x88ff, 0x0120, 0xa046, 0x788c, 0x2060, 0x0c70, 0x788b, - 0x0000, 0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091, 0x8001, 0x0098, - 0x00ce, 0x788b, 0x0000, 0x080c, 0x1fb9, 0x6004, 0xa084, 0x000f, - 0x0059, 0x88ff, 0x0130, 0x788c, 0x2060, 0x6004, 0xa084, 0x000f, - 0x0019, 0x0804, 0x1da4, 0x0005, 0x0002, 0x1e6d, 0x1e88, 0x1ea1, - 0x1e6d, 0x1eae, 0x1e7e, 0x1e6d, 0x1e6d, 0x1e6d, 0x1e86, 0x1e9f, - 0x1e6d, 0x1e6d, 0x1e6d, 0x1e6d, 0x1e6d, 0x2039, 0x0400, 0x78bc, - 0xa705, 0x78be, 0x6008, 0xa705, 0x600a, 0x080c, 0x1eea, 0x609c, - 0x78ba, 0x609f, 0x0000, 0x080c, 0x1fa5, 0x0005, 0x78bc, 0xd0c4, - 0x0108, 0x0c58, 0x601c, 0xc0bd, 0x601e, 0x0030, 0x080c, 0x1fe3, - 0x78bc, 0xd0c4, 0x0108, 0x0c08, 0x78bf, 0x0000, 0x6004, 0x8007, - 0xa084, 0x00ff, 0x78b2, 0x8001, 0x0138, 0x080c, 0x1eea, 0x0120, - 0x78bc, 0xc0c5, 0x78be, 0x0010, 0x0804, 0x1f05, 0x0005, 0x080c, - 0x1fe0, 0x78bc, 0xa08c, 0x0e00, 0x1110, 0xd0c4, 0x1108, 0x0828, - 0x080c, 0x1eea, 0x1110, 0x0804, 0x1f05, 0x0005, 0x78bc, 0xd0c4, - 0x0110, 0x0804, 0x1e6d, 0x78bf, 0x0000, 0x6714, 0x2011, 0x0001, - 0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0188, 0xa7bc, 0xff00, - 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0150, 0xa7bc, 0x8000, 0x2011, - 0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0108, 0x00c0, 0x080c, - 0x1b1d, 0x2d00, 0x2091, 0x8000, 0x682b, 0x0000, 0x682f, 0x0000, - 0x6808, 0xa084, 0xffde, 0x680a, 0xade8, 0x0010, 0x2091, 0x8001, - 0x1f04, 0x1ed2, 0x8211, 0x0118, 0x20a9, 0x0100, 0x0c58, 0x080c, - 0x1b02, 0x0005, 0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, 0x78b6, - 0x1110, 0x78ba, 0x0038, 0x689e, 0x2d00, 0x6002, 0x78b8, 0xad06, - 0x1108, 0x6002, 0x78b0, 0x8001, 0x78b2, 0x1130, 0x78bc, 0xc0c4, - 0x78be, 0x78b8, 0x2060, 0xa006, 0x0005, 0x00e6, 0xa02e, 0x2530, - 0x7dba, 0x7db6, 0x65ae, 0x65b2, 0x601c, 0x60a2, 0x2048, 0xa984, - 0xe1ff, 0x601e, 0xa984, 0x0060, 0x0110, 0x080c, 0x3de5, 0x6596, - 0x65a6, 0x669a, 0x66aa, 0x6714, 0x2071, 0x4380, 0xd7fc, 0x1110, - 0x2071, 0x4340, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x0120, - 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x71c4, 0xa168, 0x2700, - 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0x71c8, 0xa100, - 0x60c2, 0x2091, 0x8000, 0x6e08, 0xd684, 0x0170, 0xd9fc, 0x1160, - 0x2091, 0x8001, 0x080c, 0x1b85, 0x2091, 0x8000, 0x080c, 0x1d30, - 0x2091, 0x8001, 0x0804, 0x1fa3, 0x6024, 0xa096, 0x0001, 0x1110, - 0x8000, 0x6026, 0x6a10, 0x6814, 0xa202, 0x0268, 0x0160, 0x2091, - 0x8001, 0x2039, 0x0200, 0x609c, 0x78ba, 0x609f, 0x0000, 0x080c, - 0x1fa5, 0x0804, 0x1fa3, 0x2c08, 0xd9fc, 0x01f0, 0x6800, 0xa065, - 0x01d8, 0x6a04, 0x7000, 0xa084, 0x0002, 0x0168, 0x704c, 0xa206, - 0x1150, 0x6b04, 0x2160, 0x2304, 0x6002, 0xa005, 0x1108, 0x6902, - 0x2260, 0x6102, 0x0098, 0x2d00, 0x2060, 0x080c, 0x2580, 0x6e08, - 0x2160, 0x6202, 0x6906, 0x0050, 0x6800, 0x6902, 0xa065, 0x0110, - 0x6102, 0x0008, 0x6906, 0x2160, 0x6003, 0x0000, 0x2160, 0xd9fc, - 0x0118, 0xa6b4, 0xfffc, 0x6e0a, 0x6810, 0x7d08, 0x8528, 0x7d0a, - 0x8000, 0x6812, 0x2091, 0x8001, 0xd6b4, 0x0128, 0xa6b6, 0x0040, - 0x6e0a, 0x080c, 0x1b96, 0x00ee, 0x0005, 0x6008, 0xa705, 0x600a, - 0x2091, 0x8000, 0x080c, 0x1d30, 0x2091, 0x8001, 0x78b8, 0xa065, - 0x0128, 0x609c, 0x78ba, 0x609f, 0x0000, 0x0c78, 0x78b6, 0x78ba, - 0x0005, 0x7970, 0x7874, 0x2818, 0xd384, 0x0118, 0x8000, 0xa112, - 0x0220, 0x8000, 0xa112, 0x1278, 0xc384, 0x7a7c, 0x721a, 0x7a78, - 0x721e, 0xdac4, 0x0120, 0x7a84, 0x7222, 0x7a80, 0x7226, 0xa006, - 0xd384, 0x0108, 0x8000, 0x7876, 0x70d2, 0x781c, 0xa005, 0x0138, - 0x8001, 0x781e, 0x1120, 0x0e04, 0x1fdf, 0x2091, 0x4080, 0x0005, - 0x2039, 0x1ff5, 0x0010, 0x2039, 0x1ffb, 0x2704, 0xa005, 0x0160, - 0xac00, 0x2068, 0x6908, 0x6810, 0x6912, 0x680a, 0x690c, 0x6814, - 0x6916, 0x680e, 0x8738, 0x0c88, 0x0005, 0x0003, 0x0009, 0x000f, - 0x0015, 0x001b, 0x0000, 0x0015, 0x001b, 0x0000, 0x2041, 0x0000, - 0x780c, 0x0002, 0x21a7, 0x2182, 0x2006, 0x2076, 0x2039, 0x8b74, - 0x2734, 0x7d10, 0x00c0, 0x6084, 0xa086, 0x0103, 0x1904, 0x2060, - 0x6114, 0x6018, 0xa105, 0x0120, 0x86ff, 0x11d8, 0x0804, 0x2060, - 0x8603, 0xa080, 0x8b55, 0x620c, 0x2202, 0x8000, 0x6210, 0x2202, - 0x080c, 0x1d4e, 0x8630, 0xa68e, 0x000f, 0x0904, 0x20e1, 0x786c, - 0xa065, 0x1d08, 0x7808, 0xa602, 0x1220, 0xd5ac, 0x1110, 0x263a, - 0x0005, 0xa682, 0x0003, 0x1a04, 0x20e1, 0x2091, 0x8000, 0x2069, - 0x0000, 0x6818, 0xd084, 0x11f8, 0x2011, 0x8b55, 0x2204, 0x70c6, - 0x8210, 0x2204, 0x70ca, 0xd684, 0x1130, 0x8210, 0x2204, 0x70da, - 0x8210, 0x2204, 0x70de, 0xa685, 0x8020, 0x70c2, 0x681b, 0x0001, - 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, 0x8001, - 0x203b, 0x0000, 0x0005, 0x7810, 0xc0ad, 0x7812, 0x0804, 0x20e1, - 0x263a, 0x080c, 0x21ad, 0x1904, 0x21c9, 0x786c, 0xa065, 0x1904, - 0x200b, 0x2091, 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0108, - 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0804, 0x21c9, 0x2039, 0x8b74, - 0x2734, 0x7d10, 0x00a0, 0x6084, 0xa086, 0x0103, 0x1904, 0x20cb, - 0x6114, 0x6018, 0xa105, 0x0120, 0x86ff, 0x11b8, 0x0804, 0x20cb, - 0xa680, 0x8b55, 0x620c, 0x2202, 0x080c, 0x1d4e, 0x8630, 0xa68e, - 0x001e, 0x0904, 0x20e1, 0x786c, 0xa065, 0x1d28, 0x7808, 0xa602, - 0x1220, 0xd5ac, 0x1110, 0x263a, 0x0005, 0xa682, 0x0006, 0x1a04, - 0x20e1, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x11f8, - 0x2011, 0x8b55, 0x2009, 0x8b4e, 0x26a8, 0x211c, 0x2204, 0x201a, - 0x8108, 0x8210, 0x1f04, 0x20ad, 0xa685, 0x8030, 0x70c2, 0x681b, - 0x0001, 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, - 0x8001, 0xa006, 0x2009, 0x8b75, 0x200a, 0x203a, 0x0005, 0x7810, - 0xc0ad, 0x7812, 0x00b0, 0x263a, 0x080c, 0x21ad, 0x1904, 0x21c9, - 0x786c, 0xa065, 0x1904, 0x207b, 0x2091, 0x8000, 0x7810, 0xa084, - 0xffcf, 0x86ff, 0x0108, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0804, - 0x21c9, 0x2091, 0x8000, 0x7007, 0x0004, 0x7994, 0x70d4, 0xa102, - 0x0228, 0x0168, 0x7b90, 0xa302, 0x1150, 0x0010, 0x8002, 0x1138, - 0x263a, 0x7810, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0005, 0xa184, - 0xff00, 0x0140, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, - 0xa100, 0x0018, 0x8107, 0x8004, 0x8004, 0x7a9c, 0xa210, 0x721a, - 0x7a98, 0xa006, 0xa211, 0x721e, 0xd4c4, 0x0130, 0x7aa4, 0xa211, - 0x7222, 0x7aa0, 0xa211, 0x7226, 0x20a1, 0x0030, 0x7003, 0x0000, - 0x2009, 0x8b54, 0x260a, 0x8109, 0x2198, 0x2104, 0xd084, 0x0108, - 0x8633, 0xa6b0, 0x0002, 0x26a8, 0x53a6, 0x8603, 0x7012, 0x7007, - 0x0001, 0x7990, 0x7894, 0x8000, 0xa10a, 0x1208, 0xa006, 0x2028, - 0x7974, 0xa184, 0xff00, 0x0140, 0x810f, 0x810c, 0x810c, 0x8004, - 0x8004, 0x8007, 0xa100, 0x0018, 0x8107, 0x8004, 0x8004, 0x797c, - 0xa108, 0x7a78, 0xa006, 0xa211, 0xd4c4, 0x0120, 0x7b84, 0xa319, - 0x7c80, 0xa421, 0x7008, 0xd0fc, 0x0de8, 0xa084, 0x01e0, 0x01d0, - 0x7d10, 0x2031, 0x8b54, 0x2634, 0x78a8, 0x8000, 0x78aa, 0xd08c, - 0x1138, 0x7007, 0x0006, 0x7004, 0xd094, 0x1de8, 0x0804, 0x20e3, - 0x2069, 0x4347, 0x206b, 0x0003, 0x78ac, 0xa085, 0x0300, 0x78ae, - 0xa006, 0x0048, 0x2030, 0x75d6, 0x2091, 0x4080, 0x7d96, 0x7d10, - 0xa5ac, 0xffcf, 0x7d12, 0x2091, 0x8001, 0x78aa, 0x7007, 0x0006, - 0x263a, 0x7003, 0x0001, 0x711a, 0x721e, 0xd5c4, 0x0110, 0x7322, - 0x7426, 0x0005, 0x6084, 0xa086, 0x0103, 0x11d8, 0x6114, 0x6018, - 0xa105, 0x11b8, 0x2069, 0x0000, 0x6818, 0xd084, 0x1190, 0x600c, - 0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001, 0x2091, - 0x4080, 0x080c, 0x1d4e, 0x0e04, 0x21a0, 0x786c, 0xa065, 0x1d10, - 0x0005, 0x0059, 0x1530, 0x786c, 0xa065, 0x19e0, 0x0410, 0x0029, - 0x1500, 0x786c, 0xa065, 0x1dd8, 0x00e0, 0x6084, 0xa086, 0x0103, - 0x1168, 0x6018, 0xc0fc, 0x601a, 0xa086, 0x0004, 0x1138, 0x7804, - 0xd0a4, 0x0120, 0x080c, 0x1d4e, 0xa006, 0x0005, 0x0079, 0x1118, - 0xa085, 0x0001, 0x0005, 0x00b9, 0x1110, 0x2041, 0x0001, 0x7d10, - 0x0005, 0x88ff, 0x0110, 0x2091, 0x4080, 0x0005, 0x7b90, 0x7994, - 0x70d4, 0xa102, 0x1118, 0xa385, 0x0000, 0x0005, 0x0210, 0xa302, - 0x0005, 0x8002, 0x0005, 0xa184, 0xff00, 0x0140, 0x810f, 0x810c, + 0x080c, 0x1b0a, 0x0138, 0x0804, 0x13bc, 0x080c, 0x1aff, 0x0110, + 0x0804, 0x13bc, 0xa7bc, 0xff00, 0x2091, 0x8000, 0x2009, 0x0017, + 0xd7fc, 0x1118, 0x2061, 0x4640, 0x0018, 0x2061, 0x4680, 0xc1fd, + 0x607b, 0x0000, 0x6063, 0x0002, 0x6772, 0x607f, 0x000f, 0x792a, + 0x61d0, 0xc1c4, 0x61d2, 0x080c, 0x22ae, 0x2091, 0x8001, 0x2041, + 0x0021, 0x2049, 0x0005, 0x2051, 0x0030, 0x2091, 0x8000, 0x70c8, + 0xa005, 0x0118, 0x60d0, 0xc0fd, 0x60d2, 0x080c, 0x1b93, 0x70c8, + 0x6836, 0x8738, 0xa784, 0x001f, 0x1dc0, 0x2091, 0x8001, 0x0005, + 0x2019, 0x0000, 0x72c8, 0xd284, 0x0128, 0x080c, 0x1b0a, 0x0138, + 0x0804, 0x13bc, 0x080c, 0x1aff, 0x0110, 0x0804, 0x13bc, 0x72c8, + 0x72ca, 0x78ac, 0xa084, 0x0003, 0x1508, 0x2039, 0x0000, 0xd284, + 0x0108, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, + 0x080c, 0x1b7b, 0x2091, 0x8000, 0x6808, 0xc0d4, 0xa80d, 0x690a, + 0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x1d90, 0xa7bc, 0xff00, + 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x1d50, 0x2091, 0x8000, + 0x72c8, 0x2069, 0x0100, 0xd284, 0x1110, 0x2069, 0x0200, 0x6808, + 0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4, 0x01b0, 0x684b, 0x0004, + 0x20a9, 0x0014, 0x6848, 0xd094, 0x0110, 0x1f04, 0x18b2, 0x684b, + 0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, 0x0110, 0x1f04, 0x18bb, + 0x20a9, 0x00fa, 0x1f04, 0x18c2, 0x2079, 0x4600, 0x2009, 0x0018, + 0x72c8, 0xd284, 0x1118, 0x2061, 0x4640, 0x0018, 0x2061, 0x4680, + 0xc1fd, 0x607b, 0x0000, 0x792a, 0x6063, 0x0001, 0x607f, 0x000f, + 0x60a3, 0x0000, 0x60a4, 0x60ae, 0x60b2, 0x60d0, 0xd0b4, 0x0160, + 0xc0b4, 0x60d2, 0x00c6, 0x60b4, 0xa065, 0x6008, 0xc0d4, 0x600a, + 0x6018, 0x8001, 0x601a, 0x00ce, 0x60d0, 0xa084, 0x7eff, 0x60d2, + 0x78ac, 0xc08d, 0x78ae, 0x83ff, 0x0108, 0x0005, 0x681b, 0x0054, + 0x2091, 0x8001, 0x0005, 0x73cc, 0x080c, 0x186a, 0x69ec, 0x6a48, + 0xa185, 0x1800, 0x684a, 0xa185, 0x0040, 0x68ee, 0x73cc, 0x2021, + 0x0004, 0x20a9, 0x09ff, 0x1f04, 0x190b, 0x8421, 0x1dd0, 0x8319, + 0x1db0, 0x69ee, 0x6a4a, 0x2091, 0x8001, 0x0005, 0xd7fc, 0x1118, + 0x2069, 0x4640, 0x0010, 0x2069, 0x4680, 0x71c4, 0x71c6, 0x6916, + 0x81ff, 0x1110, 0x68a3, 0x0001, 0x78ac, 0xc08c, 0x78ae, 0xd084, + 0x1110, 0x080c, 0x1c5b, 0x0005, 0x75d8, 0x74dc, 0x75da, 0x74de, + 0x0010, 0xa02e, 0x2520, 0x71c4, 0x73c8, 0x72cc, 0x71c6, 0x73ca, + 0x72ce, 0x2079, 0x4600, 0x7dde, 0x7cda, 0x7bd6, 0x7ad2, 0x080c, + 0x1b58, 0x0904, 0x1a3d, 0x20a9, 0x0005, 0x20a1, 0x4614, 0x2091, + 0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, 0x0040, 0x080c, 0x1d24, + 0x0120, 0x080c, 0x1b60, 0x0804, 0x1a3d, 0x6004, 0xa08c, 0x00ff, + 0xa18e, 0x0009, 0x1120, 0x0006, 0x080c, 0x205f, 0x000e, 0xa084, + 0xff00, 0x8007, 0x8009, 0x0904, 0x19e1, 0x00c6, 0x2c68, 0x080c, + 0x1b58, 0x05a8, 0x2c00, 0x689e, 0x8109, 0x1dc0, 0x609f, 0x0000, + 0x00ce, 0x00c6, 0x7ddc, 0x7cd8, 0x7bd4, 0x7ad0, 0xa290, 0x0040, + 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x7dde, 0x7cda, + 0x7bd6, 0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0904, 0x19e0, 0x2009, + 0x0040, 0x080c, 0x1d24, 0x15a0, 0x6004, 0xa084, 0x00ff, 0xa086, + 0x0002, 0x1168, 0x6004, 0xa084, 0x00ff, 0xa086, 0x000a, 0x1120, + 0x0016, 0x080c, 0x205c, 0x001e, 0x2d00, 0x6002, 0x0898, 0x00ce, + 0x00c6, 0x609c, 0x080c, 0x1bd4, 0x00ce, 0x609f, 0x0000, 0x080c, + 0x1a41, 0x2009, 0x0018, 0x6008, 0xc0cd, 0x600a, 0x6004, 0x6086, + 0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff, 0x0110, 0xc0c5, 0x7812, + 0x080c, 0x1b15, 0x000e, 0x7812, 0x080c, 0x1b60, 0x0804, 0x1a3d, + 0x00ce, 0x00c6, 0x609c, 0x080c, 0x1bd4, 0x00ce, 0x609f, 0x0000, + 0x080c, 0x1a41, 0x2009, 0x0018, 0x6087, 0x0103, 0x601b, 0x0003, + 0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff, 0x0110, 0xc0c5, 0x7812, + 0x080c, 0x1b15, 0x000e, 0x7812, 0x080c, 0x1b60, 0x0804, 0x1a3d, + 0x00ce, 0x6114, 0xd1fc, 0x0120, 0x080c, 0x1b0a, 0x01f0, 0x0018, + 0x080c, 0x1aff, 0x01d0, 0x080c, 0x1a41, 0x2009, 0x0018, 0x6087, + 0x0103, 0x601b, 0x0021, 0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff, + 0x0110, 0xc0c5, 0x7812, 0x080c, 0x1b15, 0x000e, 0x7812, 0x080c, + 0x1b60, 0x2001, 0x4007, 0x0804, 0x13bc, 0x74c4, 0x73c8, 0x72cc, + 0x6014, 0x2091, 0x8000, 0x00e6, 0x2009, 0x0012, 0xd0fc, 0x1118, + 0x2071, 0x4640, 0x0018, 0x2071, 0x4680, 0xc1fd, 0x792a, 0x7063, + 0x0005, 0x71d0, 0xc1c4, 0x71d2, 0x7366, 0x726a, 0x746e, 0x7072, + 0x7077, 0x0000, 0x2c00, 0x707a, 0xa02e, 0x2530, 0x611c, 0xa184, + 0x0060, 0x0110, 0x080c, 0x3fc1, 0x00ee, 0x6596, 0x65a6, 0x669a, + 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x6714, 0x6023, 0x0000, + 0x080c, 0x22ae, 0x2091, 0x8001, 0x0005, 0x70c3, 0x4005, 0x0804, + 0x13bd, 0x20a9, 0x0005, 0x2099, 0x4614, 0x2091, 0x8000, 0x530a, + 0x2091, 0x8001, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, + 0xa5a9, 0x0000, 0x0005, 0x71c4, 0x70c7, 0x0000, 0x791e, 0x0804, + 0x13ba, 0x71c4, 0x71c6, 0x2168, 0x0010, 0x2069, 0x1000, 0x690c, + 0xa016, 0x2d04, 0xa210, 0x8d68, 0x8109, 0x1dd8, 0xa285, 0x0000, + 0x1118, 0x70c3, 0x4000, 0x0010, 0x70c3, 0x4003, 0x70ca, 0x0804, + 0x13bd, 0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, 0x1a04, 0x13b3, + 0x7966, 0x0804, 0x13ba, 0x7964, 0x71c6, 0x0804, 0x13ba, 0x7900, + 0x71c6, 0x71c4, 0x7902, 0x0804, 0x13ba, 0x7900, 0x71c6, 0x0804, + 0x13ba, 0x70c4, 0x2011, 0x0000, 0xa08c, 0x000d, 0x0160, 0x810c, + 0x0230, 0x8210, 0x810c, 0x810c, 0x0210, 0x8210, 0x810c, 0x81ff, + 0x1904, 0x13b4, 0x8210, 0x7a0e, 0xd28c, 0x0538, 0x7910, 0xc1cd, + 0x7912, 0x2009, 0x0021, 0x2019, 0x0003, 0xd284, 0x01c0, 0x8108, + 0x2019, 0x0041, 0x2011, 0x8e4e, 0x2312, 0x2019, 0x0042, 0x8210, + 0x2312, 0x2019, 0x0043, 0x8210, 0x2312, 0x2019, 0x0046, 0x8210, + 0x2312, 0x2019, 0x0047, 0x8210, 0x2312, 0x2019, 0x0006, 0x2011, + 0x8e53, 0x2112, 0x2011, 0x8e73, 0x2312, 0x7904, 0x7806, 0x0804, + 0x13b9, 0x7804, 0x70c6, 0x0804, 0x13ba, 0x71c4, 0xd1fc, 0x1118, + 0x2011, 0x4ac0, 0x0010, 0x2011, 0x4b40, 0x8107, 0xa084, 0x000f, + 0x8003, 0x8003, 0x8003, 0xa268, 0x2011, 0x0000, 0x6814, 0xd0fc, + 0x0110, 0xa295, 0x0200, 0xd0b4, 0x0110, 0xa295, 0x0001, 0x6b0c, + 0x6800, 0x70da, 0x0804, 0x13b7, 0x7814, 0xd0f4, 0x0130, 0x2001, + 0x4007, 0x70db, 0x0000, 0xa005, 0x0048, 0xd0fc, 0x0130, 0x2001, + 0x4007, 0x70db, 0x0001, 0xa005, 0x0008, 0xa006, 0x0005, 0x7814, + 0xd0f4, 0x0130, 0x2001, 0x4007, 0x70db, 0x0000, 0xa005, 0x0008, + 0xa006, 0x0005, 0x7814, 0xd0fc, 0x0130, 0x2001, 0x4007, 0x70db, + 0x0001, 0xa005, 0x0008, 0xa006, 0x0005, 0x7112, 0x721a, 0x731e, + 0x7810, 0xd0c4, 0x0110, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108, + 0x810c, 0x81a9, 0x8098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x6084, + 0x20a2, 0x53a6, 0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0140, + 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018, + 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, 0xa211, + 0x7d10, 0xd5c4, 0x0120, 0x7b84, 0xa319, 0x7c80, 0xa421, 0x7008, + 0xd0fc, 0x0de8, 0x7003, 0x0001, 0x7007, 0x0006, 0x711a, 0x721e, + 0x7d10, 0xd5c4, 0x0110, 0x7322, 0x7426, 0xa084, 0x01e0, 0x0005, + 0x7848, 0xa065, 0x0120, 0x2c04, 0x784a, 0x2063, 0x0000, 0x0005, + 0x00f6, 0x2079, 0x4600, 0x7848, 0x2062, 0x2c00, 0xa005, 0x1110, + 0x080c, 0x254c, 0x784a, 0x00fe, 0x0005, 0x2011, 0x9000, 0x7a4a, + 0x7bc4, 0x8319, 0x0128, 0xa280, 0x0032, 0x2012, 0x2010, 0x0cc8, + 0x2013, 0x0000, 0x0005, 0x0016, 0x0026, 0xd7fc, 0x1118, 0x2011, + 0x4bc0, 0x0010, 0x2011, 0x6bc0, 0xa784, 0x0f00, 0x800b, 0xa784, + 0x001f, 0x0120, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa268, + 0x002e, 0x001e, 0x0005, 0x0c39, 0x2900, 0x682a, 0x2a00, 0x682e, + 0x6808, 0xa084, 0xf9ef, 0xa80d, 0x690a, 0x00e6, 0xd7fc, 0x1128, + 0x2009, 0x4652, 0x2071, 0x4640, 0x0020, 0x2009, 0x4692, 0x2071, + 0x4680, 0x210c, 0x6804, 0xa005, 0x0148, 0xa116, 0x1138, 0x2060, + 0x6000, 0x6806, 0x0016, 0x200b, 0x0000, 0x0018, 0x2009, 0x0000, + 0x0016, 0x6804, 0xa065, 0x0178, 0x6000, 0x6806, 0x0421, 0x080c, + 0x1d95, 0x6810, 0x7908, 0x8109, 0x790a, 0x8001, 0x6812, 0x1d88, + 0x7910, 0xc1a5, 0x7912, 0x001e, 0x6902, 0x6906, 0x2d00, 0x2060, + 0x080c, 0x2693, 0x00ee, 0x0005, 0xa065, 0x0160, 0x2008, 0x609c, + 0xa005, 0x0128, 0x2062, 0x609f, 0x0000, 0xa065, 0x0cc0, 0x7848, + 0x794a, 0x2062, 0x0005, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9, + 0x001c, 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828, + 0x601a, 0x682c, 0x6022, 0x0005, 0x00e6, 0xd7fc, 0x1128, 0x2071, + 0x4640, 0x2031, 0x46c0, 0x0020, 0x2071, 0x4680, 0x2031, 0x48c0, + 0x704c, 0xa08c, 0x0200, 0x1128, 0xa608, 0x2d0a, 0x8000, 0x704e, + 0xa006, 0x00ee, 0x0005, 0x00f6, 0xd7fc, 0x1118, 0x2079, 0x4640, + 0x0010, 0x2079, 0x4680, 0x080c, 0x1b7b, 0x2091, 0x8000, 0x6804, + 0x780a, 0xa065, 0x05f0, 0x0030, 0x2c00, 0x780a, 0x2060, 0x6000, + 0xa065, 0x05b8, 0x6010, 0xa306, 0x1db8, 0x600c, 0xa206, 0x1da0, + 0x2c28, 0x7848, 0xac06, 0x1108, 0x0448, 0x6804, 0xac06, 0x1140, + 0x6000, 0x2060, 0x6806, 0xa005, 0x1118, 0x6803, 0x0000, 0x0048, + 0x6400, 0x7808, 0x2060, 0x6402, 0xa486, 0x0000, 0x1110, 0x2c00, + 0x6802, 0x2560, 0x080c, 0x1be3, 0x601b, 0x0005, 0x6023, 0x0020, + 0x00fe, 0x080c, 0x1d95, 0x00f6, 0x7908, 0x8109, 0x790a, 0x6810, + 0x8001, 0x6812, 0x1118, 0x7810, 0xc0a5, 0x7812, 0x2001, 0xffff, + 0xa005, 0x00fe, 0x0005, 0x0076, 0x2700, 0x2039, 0x0000, 0xd0fc, + 0x0108, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, + 0x2091, 0x8000, 0x080c, 0x1b93, 0x8738, 0xa784, 0x001f, 0x1dd0, + 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x1d90, + 0x2091, 0x8001, 0x007e, 0x0005, 0x786c, 0x2009, 0x8e74, 0x210c, + 0xa10d, 0x0118, 0xa065, 0x0804, 0x207a, 0x2061, 0x0000, 0x6018, + 0xd084, 0x11b8, 0x7810, 0xd08c, 0x0130, 0xc08c, 0x7812, 0xc7fc, + 0x2069, 0x4640, 0x0028, 0xc08d, 0x7812, 0x2069, 0x4680, 0xc7fd, + 0x2091, 0x8000, 0x681c, 0x681f, 0x0000, 0x2091, 0x8001, 0xa005, + 0x1108, 0x0005, 0xa08c, 0xfff0, 0x0110, 0x080c, 0x254c, 0x0002, + 0x1cb8, 0x1cbb, 0x1cc1, 0x1cc5, 0x1cb9, 0x1cc9, 0x1cb9, 0x1cb9, + 0x1cb9, 0x1ccf, 0x1cfb, 0x1cfe, 0x1d03, 0x1d0c, 0x1cb9, 0x1cb9, + 0x0005, 0x080c, 0x254c, 0x080c, 0x1c5b, 0x2001, 0x8001, 0x0804, + 0x1d15, 0x2001, 0x8003, 0x0804, 0x1d15, 0x2001, 0x8004, 0x0804, + 0x1d15, 0x080c, 0x1c5b, 0x2001, 0x8006, 0x0804, 0x1d15, 0x2091, + 0x8000, 0x0076, 0xd7fc, 0x1128, 0x2069, 0x4640, 0x2039, 0x0009, + 0x0020, 0x2069, 0x4680, 0x2039, 0x0009, 0x6800, 0xa086, 0x0000, + 0x0128, 0x000e, 0x6f1e, 0x2091, 0x8001, 0x0005, 0x6870, 0x007e, + 0xa0bc, 0xff00, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010, + 0x080c, 0x1b93, 0x8738, 0xa784, 0x001f, 0x1dd0, 0x2091, 0x8001, + 0x2001, 0x800a, 0x00d0, 0x2001, 0x800c, 0x00b8, 0x080c, 0x1c5b, + 0x2001, 0x800d, 0x0090, 0xd7fc, 0x0110, 0x78e4, 0x0008, 0x78e0, + 0x70c6, 0x2001, 0x800e, 0x0048, 0xd7fc, 0x0110, 0x78ec, 0x0008, + 0x78e8, 0x70c6, 0x2001, 0x800f, 0x0000, 0x70c2, 0xd7fc, 0x1118, + 0x70db, 0x0000, 0x0010, 0x70db, 0x0001, 0x2061, 0x0000, 0x601b, + 0x0001, 0x2091, 0x4080, 0x0005, 0xac80, 0x0001, 0x81ff, 0x0518, + 0x2099, 0x0030, 0x20a0, 0x700c, 0xa084, 0x07ff, 0x0100, 0x7018, + 0x0006, 0x701c, 0x0006, 0x7020, 0x0006, 0x7024, 0x0006, 0x7112, + 0x81ac, 0x721a, 0x731e, 0x7422, 0x7526, 0x7003, 0x0001, 0x7007, + 0x0001, 0x7008, 0x800b, 0x1ee8, 0x7007, 0x0002, 0xa08c, 0x01e0, + 0x1110, 0x53a5, 0xa006, 0x7003, 0x0000, 0x7007, 0x0004, 0x000e, + 0x7026, 0x000e, 0x7022, 0x000e, 0x701e, 0x000e, 0x701a, 0x0005, + 0x2011, 0x0020, 0x2009, 0x0010, 0x6b0a, 0x6c0e, 0x681f, 0x0201, + 0x6803, 0xfd20, 0x6807, 0x0038, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, + 0xa290, 0x0004, 0x8109, 0x1d80, 0x0005, 0x70ec, 0xd0dc, 0x1520, + 0x2029, 0x0001, 0x7814, 0xd0cc, 0x1160, 0x70ec, 0xd0e4, 0x2019, + 0x0c0a, 0x2021, 0x000a, 0x1120, 0x2019, 0x0c0c, 0x2021, 0x000c, + 0x0070, 0x70ec, 0xd0e4, 0x1128, 0x2019, 0x180c, 0x2021, 0x000c, + 0x0030, 0x2019, 0x1809, 0x2021, 0x0009, 0xa5ad, 0x0200, 0x6b0a, + 0x6c0e, 0x6d1e, 0x6807, 0x0038, 0x0005, 0x6004, 0x6086, 0x2c08, + 0x2063, 0x0000, 0x7868, 0xa005, 0x796a, 0x0110, 0x2c02, 0x0008, + 0x796e, 0x0005, 0x00c6, 0x2061, 0x4600, 0x6887, 0x0103, 0x2d08, + 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0110, 0x2d02, 0x0008, + 0x616e, 0x00ce, 0x0005, 0x2091, 0x8000, 0x2c04, 0x786e, 0xa005, + 0x1108, 0x786a, 0x2091, 0x8001, 0x609c, 0xa005, 0x0188, 0x00c6, + 0x2060, 0x2008, 0x609c, 0xa005, 0x0138, 0x2062, 0x609f, 0x0000, + 0xa065, 0x609c, 0xa005, 0x1dc8, 0x7848, 0x794a, 0x2062, 0x00ce, + 0x7848, 0x2062, 0x609f, 0x0000, 0xac85, 0x0000, 0x1110, 0x080c, + 0x254c, 0x784a, 0x0005, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, + 0x818e, 0x1208, 0xa200, 0x1f04, 0x1ddf, 0x8086, 0x818e, 0x0005, + 0x0156, 0x20a9, 0x0010, 0xa005, 0x01b8, 0xa11a, 0x12a8, 0x8213, + 0x818d, 0x0228, 0xa11a, 0x1220, 0x1f04, 0x1def, 0x0028, 0xa11a, + 0x2308, 0x8210, 0x1f04, 0x1def, 0x0006, 0x3200, 0xa084, 0xefff, + 0x2080, 0x000e, 0x015e, 0x0005, 0x0006, 0x3200, 0xa085, 0x1000, + 0x0cb8, 0x7d74, 0x70d0, 0xa506, 0x0904, 0x1ebd, 0x7810, 0x2050, + 0x080c, 0x1b58, 0x0904, 0x1ebd, 0xa046, 0x7970, 0x2500, 0x8000, + 0xa112, 0x2009, 0x0040, 0x1208, 0x0030, 0x72d0, 0xa206, 0x0118, + 0x8840, 0x2009, 0x0080, 0x00c6, 0x7112, 0x7007, 0x0001, 0x2099, + 0x0030, 0x20a9, 0x0020, 0xac80, 0x0001, 0x20a0, 0x2061, 0x0000, + 0x88ff, 0x0110, 0x080c, 0x1b58, 0x7008, 0xd0fc, 0x0de8, 0x7007, + 0x0002, 0x2091, 0x8001, 0xa08c, 0x01e0, 0x1538, 0x53a5, 0x8cff, + 0x1120, 0x88ff, 0x0904, 0x1eaa, 0x0050, 0x2c00, 0x788e, 0x20a9, + 0x0020, 0xac80, 0x0001, 0x20a0, 0x53a5, 0x0804, 0x1eaa, 0xa046, + 0x7218, 0x731c, 0xdac4, 0x0110, 0x7420, 0x7524, 0xa292, 0x0040, + 0xa39b, 0x0000, 0xa4a3, 0x0000, 0xa5ab, 0x0000, 0x721a, 0x731e, + 0xdac4, 0x0118, 0x7422, 0x7526, 0xa006, 0x7007, 0x0004, 0x0904, + 0x1eaa, 0x8cff, 0x0110, 0x080c, 0x1b60, 0x00ce, 0x080c, 0x1b60, + 0xa046, 0x7888, 0x8000, 0x788a, 0xa086, 0x0002, 0x01c0, 0x7a7c, + 0x7b78, 0xdac4, 0x0110, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004, + 0x8004, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, + 0x721a, 0x731e, 0xdac4, 0x0588, 0x7422, 0x7526, 0x0470, 0x6014, + 0xd0fc, 0x1118, 0x2069, 0x4640, 0x0010, 0x2069, 0x4680, 0x2091, + 0x8000, 0x681f, 0x0002, 0x88ff, 0x0120, 0xa046, 0x788c, 0x2060, + 0x0c70, 0x788b, 0x0000, 0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091, + 0x8001, 0x0098, 0x00ce, 0x788b, 0x0000, 0x080c, 0x2035, 0x6004, + 0xa084, 0x000f, 0x0059, 0x88ff, 0x0130, 0x788c, 0x2060, 0x6004, + 0xa084, 0x000f, 0x0019, 0x0804, 0x1e09, 0x0005, 0x0002, 0x1ecf, + 0x1eea, 0x1f03, 0x1ecf, 0x1f10, 0x1ee0, 0x1ecf, 0x1ecf, 0x1ecf, + 0x1ee8, 0x1f01, 0x1ecf, 0x1ecf, 0x1ecf, 0x1ecf, 0x1ecf, 0x2039, + 0x0400, 0x78bc, 0xa705, 0x78be, 0x6008, 0xa705, 0x600a, 0x080c, + 0x1f4c, 0x609c, 0x78ba, 0x609f, 0x0000, 0x080c, 0x2021, 0x0005, + 0x78bc, 0xd0c4, 0x0108, 0x0c58, 0x601c, 0xc0bd, 0x601e, 0x0030, + 0x080c, 0x205f, 0x78bc, 0xd0c4, 0x0108, 0x0c08, 0x78bf, 0x0000, + 0x6004, 0x8007, 0xa084, 0x00ff, 0x78b2, 0x8001, 0x0138, 0x080c, + 0x1f4c, 0x0120, 0x78bc, 0xc0c5, 0x78be, 0x0010, 0x0804, 0x1f67, + 0x0005, 0x080c, 0x205c, 0x78bc, 0xa08c, 0x0e00, 0x1110, 0xd0c4, + 0x1108, 0x0828, 0x080c, 0x1f4c, 0x1110, 0x0804, 0x1f67, 0x0005, + 0x78bc, 0xd0c4, 0x0110, 0x0804, 0x1ecf, 0x78bf, 0x0000, 0x6714, + 0x2011, 0x0001, 0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0188, + 0xa7bc, 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0150, 0xa7bc, + 0x8000, 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0108, + 0x00c0, 0x080c, 0x1b7b, 0x2d00, 0x2091, 0x8000, 0x682b, 0x0000, + 0x682f, 0x0000, 0x6808, 0xa084, 0xffde, 0x680a, 0xade8, 0x0010, + 0x2091, 0x8001, 0x1f04, 0x1f34, 0x8211, 0x0118, 0x20a9, 0x0100, + 0x0c58, 0x080c, 0x1b60, 0x0005, 0x609f, 0x0000, 0x78b4, 0xa06d, + 0x2c00, 0x78b6, 0x1110, 0x78ba, 0x0038, 0x689e, 0x2d00, 0x6002, + 0x78b8, 0xad06, 0x1108, 0x6002, 0x78b0, 0x8001, 0x78b2, 0x1130, + 0x78bc, 0xc0c4, 0x78be, 0x78b8, 0x2060, 0xa006, 0x0005, 0x00e6, + 0xa02e, 0x2530, 0x7dba, 0x7db6, 0x65ae, 0x65b2, 0x601c, 0x60a2, + 0x2048, 0xa984, 0xe1ff, 0x601e, 0xa984, 0x0060, 0x0110, 0x080c, + 0x3fc1, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x6714, 0x2071, 0x4680, + 0xd7fc, 0x1110, 0x2071, 0x4640, 0xa784, 0x0f00, 0x800b, 0xa784, + 0x001f, 0x0120, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x71c0, + 0xa168, 0x2700, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, + 0x71c4, 0xa100, 0x60c2, 0x2091, 0x8000, 0x7814, 0xd0c4, 0x0138, + 0xd7fc, 0x1118, 0xd0f4, 0x1140, 0x0010, 0xd0fc, 0x1128, 0x6e08, + 0xd684, 0x01f0, 0xd9fc, 0x11e0, 0x2091, 0x8001, 0x080c, 0x1be3, + 0x2091, 0x8000, 0x080c, 0x1d95, 0x2091, 0x8001, 0x7814, 0xd0c4, + 0x0904, 0x201f, 0xd7fc, 0x1120, 0xd0f4, 0x1130, 0x0804, 0x201f, + 0xd0fc, 0x1110, 0x0804, 0x201f, 0x601b, 0x0021, 0x0804, 0x201f, + 0x6024, 0xa096, 0x0001, 0x1110, 0x8000, 0x6026, 0x6a10, 0x6814, + 0xa202, 0x0268, 0x0160, 0x2091, 0x8001, 0x2039, 0x0200, 0x609c, + 0x78ba, 0x609f, 0x0000, 0x080c, 0x2021, 0x0804, 0x201f, 0x2c08, + 0xd9fc, 0x01f0, 0x6800, 0xa065, 0x01d8, 0x6a04, 0x7000, 0xa084, + 0x0002, 0x0168, 0x7048, 0xa206, 0x1150, 0x6b04, 0x2160, 0x2304, + 0x6002, 0xa005, 0x1108, 0x6902, 0x2260, 0x6102, 0x0098, 0x2d00, + 0x2060, 0x080c, 0x2693, 0x6e08, 0x2160, 0x6202, 0x6906, 0x0050, + 0x6800, 0x6902, 0xa065, 0x0110, 0x6102, 0x0008, 0x6906, 0x2160, + 0x6003, 0x0000, 0x2160, 0xd9fc, 0x0118, 0xa6b4, 0xfffc, 0x6e0a, + 0x6810, 0x7d08, 0x8528, 0x7d0a, 0x8000, 0x6812, 0x2091, 0x8001, + 0xd6b4, 0x0128, 0xa6b6, 0x0040, 0x6e0a, 0x080c, 0x1bf4, 0x00ee, + 0x0005, 0x6008, 0xa705, 0x600a, 0x2091, 0x8000, 0x080c, 0x1d95, + 0x2091, 0x8001, 0x78b8, 0xa065, 0x0128, 0x609c, 0x78ba, 0x609f, + 0x0000, 0x0c78, 0x78b6, 0x78ba, 0x0005, 0x7970, 0x7874, 0x2818, + 0xd384, 0x0118, 0x8000, 0xa112, 0x0220, 0x8000, 0xa112, 0x1278, + 0xc384, 0x7a7c, 0x721a, 0x7a78, 0x721e, 0xdac4, 0x0120, 0x7a84, + 0x7222, 0x7a80, 0x7226, 0xa006, 0xd384, 0x0108, 0x8000, 0x7876, + 0x70d2, 0x781c, 0xa005, 0x0138, 0x8001, 0x781e, 0x1120, 0x0e04, + 0x205b, 0x2091, 0x4080, 0x0005, 0x2039, 0x2071, 0x0010, 0x2039, + 0x2077, 0x2704, 0xa005, 0x0160, 0xac00, 0x2068, 0x6908, 0x6810, + 0x6912, 0x680a, 0x690c, 0x6814, 0x6916, 0x680e, 0x8738, 0x0c88, + 0x0005, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0015, + 0x001b, 0x0000, 0x2041, 0x0000, 0x780c, 0x0002, 0x2223, 0x21fe, + 0x2082, 0x20f2, 0x2039, 0x8e74, 0x2734, 0x7d10, 0x00c0, 0x6084, + 0xa086, 0x0103, 0x1904, 0x20dc, 0x6114, 0x6018, 0xa105, 0x0120, + 0x86ff, 0x11d8, 0x0804, 0x20dc, 0x8603, 0xa080, 0x8e55, 0x620c, + 0x2202, 0x8000, 0x6210, 0x2202, 0x080c, 0x1db3, 0x8630, 0xa68e, + 0x000f, 0x0904, 0x215d, 0x786c, 0xa065, 0x1d08, 0x7808, 0xa602, + 0x1220, 0xd5ac, 0x1110, 0x263a, 0x0005, 0xa682, 0x0003, 0x1a04, + 0x215d, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x11f8, + 0x2011, 0x8e55, 0x2204, 0x70c6, 0x8210, 0x2204, 0x70ca, 0xd684, + 0x1130, 0x8210, 0x2204, 0x70da, 0x8210, 0x2204, 0x70de, 0xa685, + 0x8020, 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, 0x7810, 0xa084, + 0xffcf, 0x7812, 0x2091, 0x8001, 0x203b, 0x0000, 0x0005, 0x7810, + 0xc0ad, 0x7812, 0x0804, 0x215d, 0x263a, 0x080c, 0x2229, 0x1904, + 0x2245, 0x786c, 0xa065, 0x1904, 0x2087, 0x2091, 0x8000, 0x7810, + 0xa084, 0xffcf, 0x86ff, 0x0108, 0xc0ad, 0x7812, 0x2091, 0x8001, + 0x0804, 0x2245, 0x2039, 0x8e74, 0x2734, 0x7d10, 0x00a0, 0x6084, + 0xa086, 0x0103, 0x1904, 0x2147, 0x6114, 0x6018, 0xa105, 0x0120, + 0x86ff, 0x11b8, 0x0804, 0x2147, 0xa680, 0x8e55, 0x620c, 0x2202, + 0x080c, 0x1db3, 0x8630, 0xa68e, 0x001e, 0x0904, 0x215d, 0x786c, + 0xa065, 0x1d28, 0x7808, 0xa602, 0x1220, 0xd5ac, 0x1110, 0x263a, + 0x0005, 0xa682, 0x0006, 0x1a04, 0x215d, 0x2091, 0x8000, 0x2069, + 0x0000, 0x6818, 0xd084, 0x11f8, 0x2011, 0x8e55, 0x2009, 0x8e4e, + 0x26a8, 0x211c, 0x2204, 0x201a, 0x8108, 0x8210, 0x1f04, 0x2129, + 0xa685, 0x8030, 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, 0x7810, + 0xa084, 0xffcf, 0x7812, 0x2091, 0x8001, 0xa006, 0x2009, 0x8e75, + 0x200a, 0x203a, 0x0005, 0x7810, 0xc0ad, 0x7812, 0x00b0, 0x263a, + 0x080c, 0x2229, 0x1904, 0x2245, 0x786c, 0xa065, 0x1904, 0x20f7, + 0x2091, 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0108, 0xc0ad, + 0x7812, 0x2091, 0x8001, 0x0804, 0x2245, 0x2091, 0x8000, 0x7007, + 0x0004, 0x7994, 0x70d4, 0xa102, 0x0228, 0x0168, 0x7b90, 0xa302, + 0x1150, 0x0010, 0x8002, 0x1138, 0x263a, 0x7810, 0xc0ad, 0x7812, + 0x2091, 0x8001, 0x0005, 0xa184, 0xff00, 0x0140, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018, 0x8107, 0x8004, - 0x8004, 0x7a9c, 0x7b98, 0x7ca4, 0x7da0, 0xa210, 0xa006, 0xa319, - 0xa421, 0xa529, 0x2009, 0x0018, 0x6028, 0xa005, 0x0110, 0x2009, - 0x0040, 0x080c, 0x1ab7, 0x01d0, 0x78a8, 0x8000, 0x78aa, 0xd08c, - 0x1510, 0x6014, 0xd0fc, 0x1118, 0x2069, 0x4340, 0x0010, 0x2069, - 0x4380, 0x2091, 0x8000, 0x681f, 0x0003, 0x78ab, 0x0000, 0x78ac, - 0xa085, 0x0300, 0x78ae, 0x2091, 0x8001, 0x0068, 0x78ab, 0x0000, - 0x080c, 0x1d4e, 0x7990, 0x7894, 0x8000, 0xa10a, 0x1208, 0xa006, - 0x7896, 0x70d6, 0xa006, 0x2071, 0x0010, 0x2091, 0x8001, 0x0005, - 0x2138, 0xd7fc, 0x1118, 0x2009, 0x4359, 0x0010, 0x2009, 0x4399, - 0x2091, 0x8000, 0x200a, 0x00f6, 0x2009, 0x4380, 0x2079, 0x0100, - 0xd7fc, 0x1120, 0x2009, 0x4340, 0x2079, 0x0200, 0x2104, 0xa086, - 0x0000, 0x1180, 0xd7fc, 0x1118, 0x2009, 0x4345, 0x0010, 0x2009, - 0x4385, 0x2104, 0xa005, 0x1130, 0x7830, 0xa084, 0x00c0, 0x1110, - 0x781b, 0x0052, 0x00fe, 0x0005, 0x2009, 0x0002, 0x2069, 0x4300, - 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x22a9, 0x2071, 0x4380, - 0x2079, 0x0100, 0x2021, 0x45bf, 0x784b, 0x000f, 0x2001, 0x01ff, - 0x2004, 0xd0fc, 0x0118, 0x2019, 0x3c3b, 0x0030, 0x20a1, 0x012b, - 0x2019, 0x3c3b, 0xd184, 0x0110, 0x20a1, 0x022b, 0x2304, 0xa005, - 0x0140, 0x789a, 0x8318, 0x23ac, 0x8318, 0x2398, 0x53a6, 0x3318, - 0x0ca8, 0x789b, 0x0000, 0x789b, 0x0020, 0x20a9, 0x0010, 0x78af, - 0x0000, 0x78af, 0x2020, 0x1f04, 0x2287, 0x7003, 0x0000, 0x0016, - 0xd18c, 0x2009, 0x0000, 0x0108, 0xc1bd, 0x080c, 0x23bd, 0x001e, - 0x7020, 0xa084, 0x000f, 0xa085, 0x6300, 0x7806, 0x780f, 0x9000, - 0x7843, 0x00d8, 0x7853, 0x0090, 0x780b, 0x0308, 0x7456, 0x7053, - 0x0000, 0x8109, 0x0140, 0x2071, 0x4340, 0x2079, 0x0200, 0x2021, - 0x43bf, 0x0804, 0x2264, 0x0005, 0x0016, 0x2011, 0x0101, 0xd1bc, - 0x1110, 0x2011, 0x0201, 0xa18c, 0x000f, 0x2204, 0xa084, 0xfff0, - 0xa105, 0x2012, 0x001e, 0x080c, 0x23bd, 0x0005, 0x2011, 0x0101, - 0xd3fc, 0x1110, 0x2011, 0x0201, 0x20a9, 0x0009, 0x810b, 0x1f04, - 0x22ce, 0xa18c, 0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, - 0x0005, 0x2019, 0x0002, 0x2009, 0x0101, 0x20a9, 0x0005, 0x8213, - 0x1f04, 0x22df, 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205, - 0x200a, 0x8319, 0x0118, 0x2009, 0x0201, 0x0c78, 0x0005, 0x2011, - 0x0101, 0xd3fc, 0x1110, 0x2011, 0x0201, 0x20a9, 0x000c, 0x810b, - 0x1f04, 0x22f7, 0xa18c, 0xf000, 0x2204, 0xa084, 0x0fff, 0xa105, - 0x2012, 0x0005, 0x2011, 0x0102, 0xd3fc, 0x1110, 0x2011, 0x0202, - 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012, 0x0005, 0x00c6, 0x2061, - 0x0100, 0xd1bc, 0x1110, 0x2061, 0x0200, 0xc1bc, 0x8103, 0x8003, - 0xa080, 0x0020, 0x609a, 0x62ac, 0x63ac, 0x00ce, 0x0005, 0x00c6, + 0x8004, 0x7a9c, 0xa210, 0x721a, 0x7a98, 0xa006, 0xa211, 0x721e, + 0xd4c4, 0x0130, 0x7aa4, 0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226, + 0x20a1, 0x0030, 0x7003, 0x0000, 0x2009, 0x8e54, 0x260a, 0x8109, + 0x2198, 0x2104, 0xd084, 0x0108, 0x8633, 0xa6b0, 0x0002, 0x26a8, + 0x53a6, 0x8603, 0x7012, 0x7007, 0x0001, 0x7990, 0x7894, 0x8000, + 0xa10a, 0x1208, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00, 0x0140, + 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018, + 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, 0xa211, + 0xd4c4, 0x0120, 0x7b84, 0xa319, 0x7c80, 0xa421, 0x7008, 0xd0fc, + 0x0de8, 0xa084, 0x01e0, 0x01d0, 0x7d10, 0x2031, 0x8e54, 0x2634, + 0x78a8, 0x8000, 0x78aa, 0xd08c, 0x1138, 0x7007, 0x0006, 0x7004, + 0xd094, 0x1de8, 0x0804, 0x215f, 0x2069, 0x4647, 0x206b, 0x0003, + 0x78ac, 0xa085, 0x0300, 0x78ae, 0xa006, 0x0048, 0x2030, 0x75d6, + 0x2091, 0x4080, 0x7d96, 0x7d10, 0xa5ac, 0xffcf, 0x7d12, 0x2091, + 0x8001, 0x78aa, 0x7007, 0x0006, 0x263a, 0x7003, 0x0001, 0x711a, + 0x721e, 0xd5c4, 0x0110, 0x7322, 0x7426, 0x0005, 0x6084, 0xa086, + 0x0103, 0x11d8, 0x6114, 0x6018, 0xa105, 0x11b8, 0x2069, 0x0000, + 0x6818, 0xd084, 0x1190, 0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3, + 0x8020, 0x681b, 0x0001, 0x2091, 0x4080, 0x080c, 0x1db3, 0x0e04, + 0x221c, 0x786c, 0xa065, 0x1d10, 0x0005, 0x0059, 0x1530, 0x786c, + 0xa065, 0x19e0, 0x0410, 0x0029, 0x1500, 0x786c, 0xa065, 0x1dd8, + 0x00e0, 0x6084, 0xa086, 0x0103, 0x1168, 0x6018, 0xc0fc, 0x601a, + 0xa086, 0x0004, 0x1138, 0x7804, 0xd0a4, 0x0120, 0x080c, 0x1db3, + 0xa006, 0x0005, 0x0079, 0x1118, 0xa085, 0x0001, 0x0005, 0x00b9, + 0x1110, 0x2041, 0x0001, 0x7d10, 0x0005, 0x88ff, 0x0110, 0x2091, + 0x4080, 0x0005, 0x7b90, 0x7994, 0x70d4, 0xa102, 0x1118, 0xa385, + 0x0000, 0x0005, 0x0210, 0xa302, 0x0005, 0x8002, 0x0005, 0xa184, + 0xff00, 0x0140, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, + 0xa100, 0x0018, 0x8107, 0x8004, 0x8004, 0x7a9c, 0x7b98, 0x7ca4, + 0x7da0, 0xa210, 0xa006, 0xa319, 0xa421, 0xa529, 0x2009, 0x0018, + 0x6028, 0xa005, 0x0110, 0x2009, 0x0040, 0x080c, 0x1b15, 0x01d0, + 0x78a8, 0x8000, 0x78aa, 0xd08c, 0x1510, 0x6014, 0xd0fc, 0x1118, + 0x2069, 0x4640, 0x0010, 0x2069, 0x4680, 0x2091, 0x8000, 0x681f, + 0x0003, 0x78ab, 0x0000, 0x78ac, 0xa085, 0x0300, 0x78ae, 0x2091, + 0x8001, 0x0068, 0x78ab, 0x0000, 0x080c, 0x1db3, 0x7990, 0x7894, + 0x8000, 0xa10a, 0x1208, 0xa006, 0x7896, 0x70d6, 0xa006, 0x2071, + 0x0010, 0x2091, 0x8001, 0x0005, 0xd7fc, 0x1118, 0x2009, 0x4658, + 0x0010, 0x2009, 0x4698, 0x2091, 0x8000, 0x200a, 0x00f6, 0x2009, + 0x4680, 0x2079, 0x0100, 0xd7fc, 0x1120, 0x2009, 0x4640, 0x2079, + 0x0200, 0x2104, 0xa086, 0x0000, 0x1180, 0xd7fc, 0x1118, 0x2009, + 0x4645, 0x0010, 0x2009, 0x4685, 0x2104, 0xa005, 0x1130, 0x7830, + 0xa084, 0x00c0, 0x1110, 0x781b, 0x0052, 0x00fe, 0x0005, 0x2009, + 0x0002, 0x2069, 0x4600, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, + 0x2324, 0x2071, 0x4680, 0x2079, 0x0100, 0x2021, 0x48bf, 0x784b, + 0x000f, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x0118, 0x2019, 0x3e0f, + 0x0030, 0x20a1, 0x012b, 0x2019, 0x3e0f, 0xd184, 0x0110, 0x20a1, + 0x022b, 0x2304, 0xa005, 0x0140, 0x789a, 0x8318, 0x23ac, 0x8318, + 0x2398, 0x53a6, 0x3318, 0x0ca8, 0x789b, 0x0000, 0x789b, 0x0020, + 0x20a9, 0x0010, 0x78af, 0x0000, 0x78af, 0x2020, 0x1f04, 0x2302, + 0x7003, 0x0000, 0x0016, 0xd18c, 0x2009, 0x0000, 0x0108, 0xc1bd, + 0x080c, 0x2443, 0x001e, 0x7020, 0xa084, 0x000f, 0xa085, 0x6300, + 0x7806, 0x780f, 0x9000, 0x7843, 0x00d8, 0x7853, 0x0090, 0x780b, + 0x2f08, 0x7452, 0x704f, 0x0000, 0x8109, 0x0140, 0x2071, 0x4640, + 0x2079, 0x0200, 0x2021, 0x46bf, 0x0804, 0x22df, 0x080c, 0x24fd, + 0x0005, 0x0016, 0x2011, 0x0101, 0xd1bc, 0x1110, 0x2011, 0x0201, + 0xa18c, 0x000f, 0x2204, 0xa084, 0xfff0, 0xa105, 0x2012, 0x001e, + 0x080c, 0x2443, 0x0005, 0x2011, 0x0101, 0xd3fc, 0x1110, 0x2011, + 0x0201, 0x20a9, 0x0009, 0x810b, 0x1f04, 0x234b, 0xa18c, 0x0e00, + 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x0005, 0x2019, 0x0002, + 0x2009, 0x0101, 0x20a9, 0x0005, 0x8213, 0x1f04, 0x235c, 0xa294, + 0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205, 0x200a, 0x8319, 0x0118, + 0x2009, 0x0201, 0x0c78, 0x0005, 0x2011, 0x0101, 0xd3fc, 0x1110, + 0x2011, 0x0201, 0x20a9, 0x000c, 0x810b, 0x1f04, 0x2374, 0xa18c, + 0xf000, 0x2204, 0xa084, 0x0fff, 0xa105, 0x2012, 0x0005, 0x2011, + 0x0102, 0xd3fc, 0x1110, 0x2011, 0x0202, 0x2204, 0xa084, 0xf0cf, + 0xa105, 0x2012, 0x0005, 0x00c6, 0x2061, 0x0100, 0xd1bc, 0x1110, + 0x2061, 0x0200, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, + 0x62ac, 0x63ac, 0x00ce, 0x0005, 0x00c6, 0x2061, 0x0100, 0xd1bc, + 0x1110, 0x2061, 0x0200, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0022, + 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x00ce, 0x0005, 0x00c6, 0x2061, 0x0100, 0xd1bc, 0x1110, 0x2061, 0x0200, 0xc1bc, 0x8103, - 0x8003, 0xa080, 0x0022, 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, - 0x00ce, 0x0005, 0x00c6, 0x2061, 0x0100, 0xd1bc, 0x1110, 0x2061, - 0x0200, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x60a4, - 0xa28c, 0x0020, 0x0118, 0xc2ac, 0xa39d, 0x4000, 0xc3ec, 0xd3b4, - 0x1108, 0xc3ed, 0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018, 0x00ce, - 0x0005, 0x2091, 0x8000, 0x00c6, 0x00e6, 0x6818, 0xa005, 0x0904, - 0x23a1, 0xd1fc, 0x0118, 0x2061, 0x8ad0, 0x0010, 0x2061, 0x89c0, - 0x080c, 0x23a9, 0x0538, 0x20a9, 0x0101, 0xd1fc, 0x0118, 0x2061, - 0x89d0, 0x0010, 0x2061, 0x88c0, 0x00c6, 0x04d9, 0x0128, 0x00ce, - 0x8c60, 0x1f04, 0x236c, 0x0468, 0x000e, 0xd1fc, 0x0128, 0xa082, - 0x89d0, 0x2071, 0x4380, 0x0020, 0xa082, 0x88c0, 0x2071, 0x4340, - 0x707a, 0x7176, 0x2001, 0x0004, 0x7066, 0x7083, 0x000f, 0x080c, - 0x2228, 0x00a0, 0xd1fc, 0x1118, 0x2071, 0x4340, 0x0010, 0x2071, - 0x4380, 0x6020, 0xc0dd, 0x6022, 0x7176, 0x2c00, 0x707e, 0x2001, - 0x0006, 0x7066, 0x7083, 0x000f, 0x080c, 0x2228, 0x2001, 0x0000, - 0x0010, 0x2001, 0x0001, 0x2091, 0x8001, 0xa005, 0x00ee, 0x00ce, - 0x0005, 0x2c04, 0xa005, 0x0170, 0x2060, 0x6010, 0xa306, 0x1140, - 0x600c, 0xa206, 0x1128, 0x6014, 0xa106, 0x1110, 0xa006, 0x0020, - 0x6000, 0x0c80, 0xa085, 0x0001, 0x0005, 0x00f6, 0x00e6, 0x0016, - 0x2079, 0x4380, 0x2071, 0x0100, 0xd1bc, 0x1120, 0x2079, 0x4340, - 0x2071, 0x0200, 0x7920, 0xa18c, 0x000f, 0x70ec, 0xd0c4, 0x1110, - 0x001e, 0x0060, 0x810b, 0x810b, 0x810b, 0x810b, 0x000e, 0xa18d, - 0x0800, 0xd0bc, 0x1110, 0xa18d, 0x0f00, 0x2104, 0x00ee, 0x00fe, - 0x0005, 0x00e6, 0x2001, 0x4301, 0x2004, 0xd0ac, 0x1904, 0x2439, - 0x68e4, 0xd0ac, 0x0904, 0x2439, 0xa084, 0x0006, 0x1904, 0x2439, - 0x6014, 0xd0fc, 0x1118, 0x2071, 0x47c0, 0x0010, 0x2071, 0x4840, - 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xae70, 0x7004, - 0xa084, 0x000a, 0x15b0, 0x7108, 0xa194, 0xff00, 0x0590, 0xa18c, - 0x00ff, 0x2001, 0x000a, 0xa106, 0x01a8, 0x2001, 0x000c, 0xa106, - 0x01a0, 0x2001, 0x0012, 0xa106, 0x0198, 0x2001, 0x0014, 0xa106, - 0x0190, 0x2001, 0x0019, 0xa106, 0x0188, 0x2001, 0x0032, 0xa106, - 0x0180, 0x0090, 0x2009, 0x000c, 0x0088, 0x2009, 0x0012, 0x0070, - 0x2009, 0x0014, 0x0058, 0x2009, 0x0019, 0x0040, 0x2009, 0x0020, - 0x0028, 0x2009, 0x003f, 0x0010, 0x2011, 0x0000, 0x2100, 0xa205, - 0x700a, 0x00ee, 0x0005, 0x0e04, 0x243b, 0x2091, 0x8000, 0x2071, - 0x0000, 0x0006, 0x7018, 0xd084, 0x1de8, 0x000e, 0x2071, 0x0010, - 0x70ca, 0x000e, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x0a01, 0x70df, - 0x0013, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0cf8, - 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, 0x708e, 0x7592, 0x7496, - 0x769a, 0x779e, 0xa594, 0x003f, 0xd4f4, 0x0138, 0xd7bc, 0x1128, - 0xa784, 0x007d, 0x1904, 0x3ace, 0x0871, 0xa49c, 0x000f, 0xa382, - 0x0004, 0x0320, 0xa3a6, 0x0007, 0x1930, 0x2418, 0x8507, 0xa084, - 0x000f, 0x0002, 0x2a4f, 0x2b10, 0x2b38, 0x2d71, 0x30cc, 0x3112, - 0x31a7, 0x3220, 0x32db, 0x33a6, 0x248d, 0x248a, 0x285b, 0x295c, - 0x30a0, 0x248a, 0x080c, 0x243b, 0x0005, 0xa006, 0x0038, 0x7808, - 0xc08d, 0x780a, 0xa006, 0x7002, 0x704e, 0x7046, 0x70d2, 0x7060, - 0xa005, 0x1904, 0x25d9, 0x7064, 0xa084, 0x0007, 0x0002, 0x24a7, - 0x2513, 0x251b, 0x2524, 0x252d, 0x25bf, 0x2536, 0x2513, 0x7830, - 0xd0bc, 0x1d10, 0x71d4, 0xd1b4, 0x1904, 0x24f0, 0x70a4, 0xa086, - 0x0001, 0x09d0, 0x70b4, 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, - 0x0080, 0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, - 0xa05d, 0xa886, 0x0001, 0x0118, 0x69bc, 0x7daa, 0x79aa, 0x68c0, - 0xa04d, 0x6e1c, 0x2001, 0x0010, 0x0804, 0x270a, 0x7060, 0xa005, - 0x1904, 0x248c, 0x00c6, 0x00d6, 0x70b4, 0xa06d, 0x6800, 0xa065, - 0xa055, 0x789b, 0x0080, 0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, - 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0118, 0x69bc, 0x7daa, - 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0020, 0x0804, 0x270a, - 0x080c, 0x3a8d, 0x1904, 0x248c, 0x781b, 0x0068, 0x70bc, 0xa06d, - 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, - 0x7808, 0xc08d, 0x780a, 0x68bc, 0x7042, 0xc1b4, 0x71d6, 0x70b8, - 0xa065, 0x68c0, 0x705a, 0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, - 0x0009, 0x7046, 0x0005, 0x080c, 0x3a8d, 0x1120, 0x781b, 0x0054, - 0x7003, 0x0004, 0x0005, 0x080c, 0x3a8d, 0x1128, 0x2011, 0x000c, - 0x0419, 0x7003, 0x0004, 0x0005, 0x080c, 0x3a8d, 0x1128, 0x2011, - 0x0006, 0x00d1, 0x7003, 0x0004, 0x0005, 0x080c, 0x3a8d, 0x1128, - 0x2011, 0x000d, 0x0089, 0x7003, 0x0004, 0x0005, 0x080c, 0x3a8d, - 0x1150, 0x2011, 0x0006, 0x0041, 0x707c, 0x707f, 0x0000, 0x2068, - 0x704e, 0x7003, 0x0001, 0x0005, 0x7174, 0xc1fc, 0x8107, 0x7882, - 0x789b, 0x0080, 0xa286, 0x000c, 0x1120, 0x7aaa, 0x2001, 0x0001, - 0x0098, 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0xa286, 0x000d, - 0x0120, 0x7aaa, 0x2001, 0x0002, 0x0038, 0x78ab, 0x0020, 0x7178, - 0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b, 0x0060, 0x78aa, 0x785b, - 0x0004, 0x781b, 0x0113, 0x080c, 0x3aa0, 0x7083, 0x000f, 0x70d4, - 0xd0b4, 0x0168, 0xc0b4, 0x70d6, 0x00c6, 0x70b8, 0xa065, 0x6008, - 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, 0x0005, - 0x7014, 0xa005, 0x1138, 0x70d4, 0xd0b4, 0x0128, 0x70b8, 0xac06, - 0x1110, 0x0c29, 0x0005, 0x0016, 0x71a4, 0xa186, 0x0001, 0x0528, - 0x00d6, 0x0026, 0x2100, 0x2011, 0x0001, 0xa212, 0x70b4, 0x2068, - 0x6800, 0xac06, 0x0120, 0x8211, 0x01b0, 0x00c9, 0x0cc8, 0x00c6, - 0x2100, 0x2011, 0x0001, 0xa212, 0x70b4, 0x2068, 0x6800, 0x2060, - 0x6008, 0xa084, 0xfbef, 0x600a, 0x8211, 0x0110, 0x0041, 0x0cb0, - 0x70a7, 0x0001, 0x00ce, 0x002e, 0x00de, 0x001e, 0x0005, 0xade8, - 0x0005, 0x70ac, 0xad06, 0x1110, 0x70a8, 0x2068, 0x0005, 0x080c, - 0x3a8d, 0x1904, 0x248c, 0x707c, 0x2068, 0x7774, 0x080c, 0x396d, - 0x2c50, 0x080c, 0x3b28, 0x789b, 0x0080, 0x6814, 0xa084, 0x001f, - 0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001, 0x2001, 0x0004, 0x0804, - 0x270f, 0x080c, 0x3a8d, 0x1904, 0x248c, 0x789b, 0x0080, 0x7060, - 0x2068, 0x6f14, 0x70d4, 0xd0b4, 0x0168, 0xc0b4, 0x70d6, 0x00c6, - 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, - 0x601a, 0x00ce, 0x080c, 0x396d, 0x2c50, 0x080c, 0x3b28, 0x6824, - 0xa005, 0x0130, 0xa082, 0x0006, 0x0208, 0x0010, 0x6827, 0x0005, - 0x6814, 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x2031, 0x0020, 0x2041, - 0x0001, 0x2001, 0x0003, 0x0804, 0x270f, 0xc28d, 0x72d6, 0x72c0, - 0xa200, 0xa015, 0x7154, 0x8108, 0xa12a, 0x0208, 0x71c0, 0x2164, - 0x6504, 0x85ff, 0x1170, 0x7156, 0x8421, 0x1da8, 0x70d4, 0xd08c, - 0x0128, 0x70d0, 0xa005, 0x1110, 0x70d3, 0x000a, 0x0005, 0x2200, - 0x0c90, 0x70d4, 0xc08c, 0x70d6, 0x70d3, 0x0000, 0x6034, 0xa005, - 0x1db0, 0x6708, 0xa784, 0x073f, 0x01d0, 0xd7d4, 0x1d80, 0xa784, - 0x0021, 0x1d68, 0xa784, 0x0002, 0x0130, 0xa784, 0x0004, 0x0d38, - 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218, 0x1d08, 0xa784, 0x0100, - 0x0130, 0x6018, 0xa005, 0x19d8, 0xa7bc, 0xfeff, 0x670a, 0x2568, - 0x6823, 0x0000, 0x6e1c, 0xa684, 0x000e, 0x6318, 0x0128, 0x601c, - 0xa302, 0x0220, 0x0118, 0x0858, 0x83ff, 0x1948, 0x2d58, 0x2c50, - 0x7156, 0xd7bc, 0x1110, 0x7028, 0x6022, 0xc7bc, 0x670a, 0x68c0, - 0xa065, 0xa04d, 0x6100, 0x2a60, 0x2041, 0x0001, 0x6b14, 0xa39c, - 0x001f, 0xa39d, 0x00c0, 0xd1fc, 0x0110, 0xd684, 0x0110, 0xa39c, - 0xffbf, 0xd6a4, 0x0110, 0xa39d, 0x0020, 0xa684, 0x000e, 0x1904, - 0x26c1, 0xc7a5, 0x670a, 0x2c00, 0x68c6, 0x77a4, 0xa786, 0x0001, - 0x1178, 0x70d4, 0xd0b4, 0x1160, 0x7000, 0xa082, 0x0002, 0x1240, - 0x7830, 0xd0bc, 0x1128, 0x789b, 0x0080, 0x7baa, 0x0804, 0x2708, - 0x8739, 0x77a6, 0x2750, 0x77b0, 0xa7b0, 0x0005, 0x70ac, 0xa606, - 0x1108, 0x76a8, 0x76b2, 0x2c3a, 0x8738, 0x2d3a, 0x8738, 0x283a, - 0x8738, 0x233a, 0x8738, 0x253a, 0x7830, 0xd0bc, 0x0150, 0x2091, - 0x8000, 0x2091, 0x303d, 0x70d4, 0xa084, 0x303d, 0x2091, 0x8000, - 0x2090, 0xaad5, 0x0000, 0x0120, 0x8421, 0x2200, 0x1904, 0x2612, - 0x0005, 0xd1dc, 0x0904, 0x35d5, 0x2029, 0x0020, 0xd69c, 0x1120, - 0x8528, 0xd68c, 0x1108, 0x8528, 0x8840, 0x6f14, 0x610c, 0x8108, - 0xa18c, 0x00ff, 0x70cc, 0xa160, 0x2c64, 0x8cff, 0x0188, 0x6014, - 0xa706, 0x1dd0, 0x60b8, 0x8001, 0x60ba, 0x1d88, 0x2a60, 0x6008, - 0xa085, 0x0100, 0x600a, 0x2200, 0x8421, 0x1904, 0x2612, 0x0005, - 0x2a60, 0x610e, 0x69be, 0x2c00, 0x68c6, 0x8840, 0x6008, 0xc0d5, - 0x600a, 0x77a4, 0xa786, 0x0001, 0x1904, 0x2698, 0x70d4, 0xd0b4, - 0x1904, 0x2698, 0x7000, 0xa082, 0x0002, 0x1a04, 0x2698, 0x7830, - 0xd0bc, 0x1904, 0x2698, 0x789b, 0x0080, 0x7baa, 0x7daa, 0x79aa, - 0x2001, 0x0002, 0x0006, 0x6018, 0x8000, 0x601a, 0x0008, 0x0006, - 0x2960, 0x6104, 0x2a60, 0x080c, 0x3b3b, 0x1590, 0xa184, 0x0018, - 0x0180, 0xa184, 0x0010, 0x0118, 0x080c, 0x3776, 0x1548, 0xa184, - 0x0008, 0x0138, 0x69a0, 0xa184, 0x0600, 0x1118, 0x080c, 0x3696, - 0x00f8, 0x69a0, 0xa184, 0x1e00, 0x0528, 0xa184, 0x0800, 0x0178, - 0x00c6, 0x2960, 0x6000, 0xa085, 0x2000, 0x6002, 0x6104, 0xa18d, - 0x0010, 0x6106, 0x00ce, 0x080c, 0x3776, 0x1150, 0x69a0, 0xa184, - 0x0200, 0x0118, 0x080c, 0x36d9, 0x0018, 0xa184, 0x0400, 0x19f0, - 0x69a0, 0xa184, 0x1000, 0x0130, 0x6914, 0xa18c, 0xff00, 0x810f, - 0x080c, 0x231f, 0x002e, 0xa68c, 0x00e0, 0xa684, 0x0060, 0x0128, - 0xa086, 0x0060, 0x1110, 0xa18d, 0x4000, 0xa18d, 0x0104, 0x69b6, - 0x789b, 0x0060, 0x2800, 0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc, - 0x0168, 0xc0fc, 0x7087, 0x0000, 0xa08a, 0x000d, 0x0328, 0xa08a, - 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a, 0x78aa, 0x3518, - 0x3340, 0x3428, 0x8000, 0x80ac, 0xaf80, 0x002b, 0x20a0, 0x789b, - 0x0000, 0xad80, 0x000b, 0x2098, 0x53a6, 0x23a8, 0x2898, 0x25a0, - 0xa286, 0x0020, 0x1508, 0x70d4, 0xc0b5, 0x70d6, 0x2c00, 0x70ba, - 0x2d00, 0x70be, 0x6814, 0xc0fc, 0x8007, 0x7882, 0xa286, 0x0002, - 0x0904, 0x27e0, 0x70a4, 0x8000, 0x70a6, 0x74b4, 0xa498, 0x0005, - 0x70ac, 0xa306, 0x1108, 0x73a8, 0x73b6, 0xa286, 0x0010, 0x0904, - 0x248c, 0x00de, 0x00ce, 0x0005, 0x7000, 0xa005, 0x19e0, 0xa286, - 0x0002, 0x1904, 0x27f7, 0x080c, 0x3a8d, 0x19a8, 0x6814, 0xc0fc, - 0x8007, 0x7882, 0x2091, 0x8000, 0x781b, 0x0068, 0x68b4, 0x785a, - 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x2091, 0x8001, - 0x7808, 0xc08d, 0x780a, 0x0126, 0x00d6, 0x00c6, 0x70d4, 0xa084, - 0x2e00, 0x2090, 0x00ce, 0x00de, 0x012e, 0x2900, 0x705a, 0x68bc, - 0x7042, 0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, - 0x7830, 0xd0bc, 0x0140, 0x2091, 0x303d, 0x70d4, 0xa084, 0x303d, - 0x2091, 0x8000, 0x2090, 0x70a4, 0xa005, 0x1108, 0x0005, 0x8421, - 0x0de8, 0x7250, 0x70c0, 0xa200, 0xa015, 0x0804, 0x2612, 0xa286, - 0x0010, 0x1560, 0x080c, 0x3a8d, 0x1904, 0x278b, 0x6814, 0xc0fc, - 0x8007, 0x7882, 0x781b, 0x0068, 0x68b4, 0x785a, 0x6894, 0x78d6, - 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a, 0x70a4, - 0x8000, 0x70a6, 0x74b4, 0xa490, 0x0005, 0x70ac, 0xa206, 0x1108, - 0x72a8, 0x72b6, 0x2900, 0x705a, 0x68bc, 0x7042, 0x7003, 0x0002, - 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x0005, 0x6bb4, 0xa39d, - 0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x6b94, 0x7bd6, - 0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, 0x0068, 0x2900, 0x705a, - 0x7202, 0x7808, 0xc08d, 0x780a, 0x2300, 0xa605, 0x0170, 0x70d4, - 0xa084, 0x2e00, 0xa086, 0x2600, 0x1118, 0x2009, 0x0000, 0x0010, - 0x2009, 0x0001, 0xa284, 0x000f, 0x0023, 0xad80, 0x0009, 0x7046, - 0x0005, 0x2859, 0x3fb8, 0x3fb8, 0x3fa6, 0x3fb8, 0x2859, 0x2859, - 0x2859, 0x080c, 0x243b, 0x7808, 0xa084, 0xfffd, 0x780a, 0x00f6, - 0x2079, 0x4300, 0x78ac, 0x00fe, 0xd084, 0x01c0, 0x7064, 0xa086, - 0x0001, 0x1118, 0x7066, 0x0804, 0x293a, 0x7064, 0xa086, 0x0005, - 0x1158, 0x707c, 0x2068, 0x681b, 0x0004, 0x6817, 0x0000, 0x6820, - 0xa084, 0x00ff, 0xc09d, 0x6822, 0x7067, 0x0000, 0x70a7, 0x0000, - 0x70a8, 0x70b2, 0x70b6, 0x080c, 0x256f, 0x0156, 0x2011, 0x0004, - 0x7164, 0xa186, 0x0001, 0x0170, 0xa186, 0x0007, 0x1118, 0x701f, - 0x0005, 0x0040, 0x701f, 0x0001, 0x7067, 0x0000, 0x70d4, 0xc0c5, - 0x70d6, 0x0010, 0x7067, 0x0000, 0x2001, 0x430a, 0x2004, 0xa084, - 0x00ff, 0xa086, 0x0018, 0x0130, 0x7018, 0x7016, 0xa005, 0x1110, - 0x70a7, 0x0001, 0x0066, 0x080c, 0x3d52, 0x20a9, 0x0010, 0x2039, - 0x0000, 0x080c, 0x3861, 0xa7b8, 0x0100, 0x1f04, 0x28b1, 0x006e, - 0x7000, 0x0002, 0x28ee, 0x28cc, 0x28cc, 0x28c4, 0x28ee, 0x28ee, - 0x28ee, 0x28c2, 0x080c, 0x243b, 0x7060, 0xa005, 0x0538, 0xad06, - 0x1118, 0x6800, 0x7062, 0x0080, 0x6820, 0xd084, 0x1148, 0x6f14, - 0x080c, 0x396d, 0x6008, 0xc0d4, 0x600a, 0x080c, 0x35ab, 0x0020, - 0x705c, 0x2060, 0x6800, 0x6002, 0xa684, 0x5f00, 0x681e, 0x6818, - 0xd0fc, 0x0108, 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, 0x6820, - 0xa084, 0x00ff, 0xc09d, 0x6822, 0x080c, 0x1d3d, 0xb284, 0x0800, - 0x0118, 0x2021, 0x8ad0, 0x0010, 0x2021, 0x89c0, 0x080c, 0x293f, - 0xb284, 0x0800, 0x0118, 0x2021, 0x4398, 0x0010, 0x2021, 0x4358, - 0x04f1, 0x20a9, 0x0101, 0xb284, 0x0800, 0x0118, 0x2021, 0x89d0, - 0x0010, 0x2021, 0x88c0, 0x0499, 0x8420, 0x1f04, 0x290b, 0xb284, - 0x0600, 0x0118, 0x2061, 0x48c0, 0x0010, 0x2061, 0x68c0, 0x2021, + 0x8003, 0xa080, 0x0020, 0x609a, 0x60a4, 0xa28c, 0x0020, 0x0118, + 0xc2ac, 0xa39d, 0x4000, 0xc3ec, 0xd3b4, 0x1108, 0xc3ed, 0x62ae, + 0x2010, 0x60a4, 0x63ae, 0x2018, 0x00ce, 0x0005, 0x2091, 0x8000, + 0x00c6, 0x00e6, 0x6818, 0xa005, 0x0904, 0x2427, 0xd1fc, 0x0118, + 0x2061, 0x8dd0, 0x0010, 0x2061, 0x8cc0, 0x080c, 0x242f, 0x0560, + 0x20a9, 0x0101, 0xd1fc, 0x0118, 0x2061, 0x8cd0, 0x0010, 0x2061, + 0x8bc0, 0x00c6, 0x080c, 0x242f, 0x0128, 0x00ce, 0x8c60, 0x1f04, + 0x23e9, 0x04a8, 0x000e, 0xd1fc, 0x0128, 0xa082, 0x8cd0, 0x2071, + 0x4680, 0x0020, 0xa082, 0x8bc0, 0x2071, 0x4640, 0x7076, 0x7172, + 0x2138, 0x2001, 0x0004, 0x7062, 0x707f, 0x000f, 0x71d0, 0xc1c4, + 0x71d2, 0x080c, 0x22a4, 0x00c0, 0xd1fc, 0x1118, 0x2071, 0x4640, + 0x0010, 0x2071, 0x4680, 0x6020, 0xc0dd, 0x6022, 0x7172, 0x2138, + 0x2c00, 0x707a, 0x2001, 0x0006, 0x7062, 0x707f, 0x000f, 0x71d0, + 0xc1c4, 0x71d2, 0x080c, 0x22a4, 0x2001, 0x0000, 0x0010, 0x2001, + 0x0001, 0x2091, 0x8001, 0xa005, 0x00ee, 0x00ce, 0x0005, 0x2c04, + 0xa005, 0x0170, 0x2060, 0x6010, 0xa306, 0x1140, 0x600c, 0xa206, + 0x1128, 0x6014, 0xa106, 0x1110, 0xa006, 0x0020, 0x6000, 0x0c80, + 0xa085, 0x0001, 0x0005, 0x00f6, 0x00e6, 0x0016, 0x2079, 0x4680, + 0x2071, 0x0100, 0xd1bc, 0x1120, 0x2079, 0x4640, 0x2071, 0x0200, + 0x7920, 0xa18c, 0x000f, 0x70ec, 0xd0c4, 0x1110, 0x001e, 0x0060, + 0x810b, 0x810b, 0x810b, 0x810b, 0x000e, 0xa18d, 0x0800, 0xd0bc, + 0x1110, 0xa18d, 0x0f00, 0x2104, 0x00ee, 0x00fe, 0x0005, 0x2001, + 0x4601, 0x2004, 0xd0ac, 0x1138, 0x68e4, 0xd0ac, 0x0120, 0xa084, + 0x0006, 0x1108, 0x0009, 0x0005, 0x6014, 0x00e6, 0x0036, 0x2018, + 0x2071, 0x4b40, 0xd0fc, 0x1110, 0x2071, 0x4ac0, 0x8007, 0xa084, + 0x000f, 0x8003, 0x8003, 0x8003, 0xae70, 0x7004, 0xa084, 0x000a, + 0x1904, 0x24fa, 0x7108, 0xa194, 0xff00, 0x0904, 0x24fa, 0xa18c, + 0x00ff, 0x701c, 0xa084, 0xff00, 0x01c0, 0x7004, 0xa085, 0x003a, + 0x7006, 0x2001, 0x0009, 0xa102, 0x16d8, 0x2001, 0x000a, 0xa102, + 0x16d0, 0x2001, 0x000c, 0xa102, 0x16c8, 0x701c, 0xa084, 0x00ff, + 0x701e, 0x7004, 0xa084, 0xffdf, 0x7006, 0x2001, 0x000a, 0xa106, + 0x01a8, 0x2001, 0x000c, 0xa106, 0x01a0, 0x2001, 0x0012, 0xa106, + 0x0198, 0x2001, 0x0014, 0xa106, 0x0190, 0x2001, 0x0019, 0xa106, + 0x0188, 0x2001, 0x0032, 0xa106, 0x0180, 0x00d8, 0x2009, 0x000c, + 0x00d0, 0x2009, 0x0012, 0x00b8, 0x2009, 0x0014, 0x00a0, 0x2009, + 0x0019, 0x0088, 0x2009, 0x0020, 0x0070, 0x2009, 0x003f, 0x0058, + 0x2009, 0x000a, 0x0040, 0x2009, 0x000c, 0x0028, 0x2009, 0x0019, + 0x0010, 0x2011, 0x0000, 0x2100, 0xa205, 0x700a, 0x7004, 0xa085, + 0x000a, 0x7006, 0x2071, 0x4600, 0x7004, 0xd0bc, 0x0158, 0xd3fc, + 0x1120, 0x73ea, 0x2071, 0x4640, 0x0018, 0x73ee, 0x2071, 0x4680, + 0x701f, 0x000d, 0x003e, 0x00ee, 0x0005, 0x2001, 0x01ff, 0x2004, + 0xd0fc, 0x11d0, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x12a0, + 0x2071, 0x0200, 0x71ec, 0xa18c, 0x1c00, 0x810f, 0x810c, 0x810c, + 0x2079, 0x0100, 0x78ec, 0xa084, 0x1c00, 0x8007, 0x8004, 0x8004, + 0xa105, 0xa08a, 0x0007, 0x0208, 0x0005, 0x0002, 0x254b, 0x2532, + 0x254b, 0x2532, 0x2525, 0x253f, 0x2525, 0x7008, 0xa084, 0xc3ff, + 0xa085, 0x3000, 0x700a, 0x7808, 0xa084, 0xc3ff, 0xa085, 0x3000, + 0x780a, 0x0005, 0x7008, 0xa084, 0xc3ff, 0xa085, 0x2000, 0x700a, + 0x7808, 0xa084, 0xc3ff, 0xa085, 0x2000, 0x780a, 0x0005, 0x7008, + 0xa084, 0xc3ff, 0xa085, 0x0c00, 0x700a, 0x7808, 0xa084, 0xc3ff, + 0xa085, 0x0c00, 0x780a, 0x0005, 0x0e04, 0x254c, 0x2091, 0x8000, + 0x2071, 0x0000, 0x0006, 0x7018, 0xd084, 0x1de8, 0x000e, 0x2071, + 0x0010, 0x70ca, 0x000e, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x0a04, + 0x70df, 0x0020, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, + 0x0cf8, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, 0x708a, 0x758e, + 0x7492, 0x7696, 0x779a, 0xa594, 0x003f, 0xd4f4, 0x0138, 0xd7bc, + 0x1128, 0xa784, 0x007d, 0x1904, 0x3c74, 0x0871, 0xa49c, 0x000f, + 0xa382, 0x0004, 0x0320, 0xa3a6, 0x0007, 0x1930, 0x2418, 0x8507, + 0xa084, 0x000f, 0x0002, 0x2b49, 0x2c34, 0x2c72, 0x2ed8, 0x3256, + 0x32ad, 0x3353, 0x33e2, 0x34b6, 0x3588, 0x259e, 0x259b, 0x2970, + 0x2a56, 0x322a, 0x259b, 0x080c, 0x254c, 0x0005, 0xa006, 0x0038, + 0x7808, 0xc08d, 0x780a, 0xa006, 0x7002, 0x704a, 0x7042, 0x70ce, + 0x705c, 0xa005, 0x1904, 0x26ec, 0x7060, 0xa084, 0x0007, 0x0002, + 0x25b8, 0x2626, 0x262e, 0x2637, 0x2640, 0x26d2, 0x2649, 0x2626, + 0x7830, 0xd0bc, 0x1d10, 0x71d0, 0xd1bc, 0x19f8, 0xd1b4, 0x1904, + 0x2603, 0x70a0, 0xa086, 0x0001, 0x09c0, 0x70b0, 0xa06d, 0x6800, + 0xa065, 0xa055, 0x789b, 0x0080, 0x6b0c, 0x7baa, 0x6808, 0xa045, + 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0118, 0x69bc, + 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0010, 0x0804, + 0x281f, 0x705c, 0xa005, 0x1904, 0x259d, 0x00c6, 0x00d6, 0x70b0, + 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0080, 0x6b0c, 0x7baa, + 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, + 0x0118, 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001, + 0x0020, 0x0804, 0x281f, 0x080c, 0x3c33, 0x1904, 0x259d, 0x781b, + 0x0068, 0x70b8, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, + 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a, 0x68bc, 0x703e, + 0xc1b4, 0x71d2, 0x70b4, 0xa065, 0x68c0, 0x7056, 0x7003, 0x0002, + 0x2d00, 0x704a, 0xad80, 0x0009, 0x7042, 0x0005, 0x080c, 0x3c33, + 0x1120, 0x781b, 0x0054, 0x7003, 0x0004, 0x0005, 0x080c, 0x3c33, + 0x1128, 0x2011, 0x000c, 0x0419, 0x7003, 0x0004, 0x0005, 0x080c, + 0x3c33, 0x1128, 0x2011, 0x0006, 0x00d1, 0x7003, 0x0004, 0x0005, + 0x080c, 0x3c33, 0x1128, 0x2011, 0x000d, 0x0089, 0x7003, 0x0004, + 0x0005, 0x080c, 0x3c33, 0x1150, 0x2011, 0x0006, 0x0041, 0x7078, + 0x707b, 0x0000, 0x2068, 0x704a, 0x7003, 0x0004, 0x0005, 0x7170, + 0xc1fc, 0x8107, 0x7882, 0x789b, 0x0080, 0xa286, 0x000c, 0x1120, + 0x7aaa, 0x2001, 0x0001, 0x0098, 0xa18c, 0x001f, 0xa18d, 0x00c0, + 0x79aa, 0xa286, 0x000d, 0x0120, 0x7aaa, 0x2001, 0x0002, 0x0038, + 0x78ab, 0x0020, 0x7174, 0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b, + 0x0060, 0x78aa, 0x785b, 0x0004, 0x781b, 0x0113, 0x080c, 0x3c46, + 0x707f, 0x000f, 0x70d0, 0xd0b4, 0x0168, 0xc0b4, 0x70d2, 0x00c6, + 0x70b4, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, + 0x601a, 0x00ce, 0x0005, 0x7014, 0xa005, 0x1138, 0x70d0, 0xd0b4, + 0x0128, 0x70b4, 0xac06, 0x1110, 0x0c29, 0x0005, 0x0016, 0x71a0, + 0xa186, 0x0001, 0x0528, 0x00d6, 0x0026, 0x2100, 0x2011, 0x0001, + 0xa212, 0x70b0, 0x2068, 0x6800, 0xac06, 0x0120, 0x8211, 0x01b0, + 0x00c9, 0x0cc8, 0x00c6, 0x2100, 0x2011, 0x0001, 0xa212, 0x70b0, + 0x2068, 0x6800, 0x2060, 0x6008, 0xa084, 0xfbef, 0x600a, 0x8211, + 0x0110, 0x0041, 0x0cb0, 0x70a3, 0x0001, 0x00ce, 0x002e, 0x00de, + 0x001e, 0x0005, 0xade8, 0x0005, 0x70a8, 0xad06, 0x1110, 0x70a4, + 0x2068, 0x0005, 0x080c, 0x3c33, 0x1904, 0x259d, 0x7078, 0x2068, + 0x7770, 0x080c, 0x3b6f, 0x2c50, 0x080c, 0x3cce, 0x789b, 0x0080, + 0x6814, 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001, + 0x2001, 0x0004, 0x0804, 0x2824, 0x080c, 0x3c33, 0x1904, 0x259d, + 0x789b, 0x0080, 0x705c, 0x2068, 0x6f14, 0x70d0, 0xd0b4, 0x0168, + 0xc0b4, 0x70d2, 0x00c6, 0x70b4, 0xa065, 0x6008, 0xa084, 0xfbef, + 0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, 0x080c, 0x3b6f, 0x2c50, + 0x080c, 0x3cce, 0x6824, 0xa005, 0x0130, 0xa082, 0x0006, 0x0208, + 0x0010, 0x6827, 0x0005, 0x6814, 0xa084, 0x001f, 0xc0bd, 0x78aa, + 0x2031, 0x0020, 0x2041, 0x0001, 0x2001, 0x0003, 0x0804, 0x2824, + 0xc28d, 0x72d2, 0x72bc, 0xa200, 0xa015, 0x7150, 0x8108, 0xa12a, + 0x0208, 0x71bc, 0x2164, 0x6504, 0x85ff, 0x1170, 0x7152, 0x8421, + 0x1da8, 0x70d0, 0xd08c, 0x0128, 0x70cc, 0xa005, 0x1110, 0x70cf, + 0x000a, 0x0005, 0x2200, 0x0c90, 0x70d0, 0xc08c, 0x70d2, 0x70cf, + 0x0000, 0x6034, 0xa005, 0x1db0, 0x6708, 0xa784, 0x073f, 0x01d0, + 0xd7d4, 0x1d80, 0xa784, 0x0021, 0x1d68, 0xa784, 0x0002, 0x0130, + 0xa784, 0x0004, 0x0d38, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218, + 0x1d08, 0xa784, 0x0100, 0x0130, 0x6018, 0xa005, 0x19d8, 0xa7bc, + 0xfeff, 0x670a, 0x2568, 0x6823, 0x0000, 0x6e1c, 0xa684, 0x000e, + 0x6318, 0x0128, 0x601c, 0xa302, 0x0220, 0x0118, 0x0858, 0x83ff, + 0x1948, 0x2d58, 0x2c50, 0x7152, 0xd7bc, 0x1120, 0x7028, 0x6022, + 0x603a, 0x0010, 0xc7bc, 0x670a, 0x68c0, 0xa065, 0xa04d, 0x6100, + 0x2a60, 0x2041, 0x0001, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, + 0xd1fc, 0x0110, 0xd684, 0x0110, 0xa39c, 0xffbf, 0xd6a4, 0x0110, + 0xa39d, 0x0020, 0xa684, 0x000e, 0x1904, 0x27d6, 0xc7a5, 0x670a, + 0x2c00, 0x68c6, 0x77a0, 0xa786, 0x0001, 0x1178, 0x70d0, 0xd0b4, + 0x1160, 0x7000, 0xa082, 0x0002, 0x1240, 0x7830, 0xd0bc, 0x1128, + 0x789b, 0x0080, 0x7baa, 0x0804, 0x281d, 0x8739, 0x77a2, 0x2750, + 0x77ac, 0xa7b0, 0x0005, 0x70a8, 0xa606, 0x1108, 0x76a4, 0x76ae, + 0x2c3a, 0x8738, 0x2d3a, 0x8738, 0x283a, 0x8738, 0x233a, 0x8738, + 0x253a, 0x7830, 0xd0bc, 0x0150, 0x2091, 0x8000, 0x2091, 0x303d, + 0x70d0, 0xa084, 0x303d, 0x2091, 0x8000, 0x2090, 0xaad5, 0x0000, + 0x0120, 0x8421, 0x2200, 0x1904, 0x2725, 0x0005, 0xd1dc, 0x0904, + 0x37ce, 0x2029, 0x0020, 0xd69c, 0x1120, 0x8528, 0xd68c, 0x1108, + 0x8528, 0x8840, 0x6f14, 0x610c, 0x8108, 0xa18c, 0x00ff, 0x70c8, + 0xa160, 0x2c64, 0x8cff, 0x0188, 0x6014, 0xa706, 0x1dd0, 0x60b8, + 0x8001, 0x60ba, 0x1d88, 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, + 0x2200, 0x8421, 0x1904, 0x2725, 0x0005, 0x2a60, 0x610e, 0x69be, + 0x2c00, 0x68c6, 0x8840, 0x6008, 0xc0d5, 0x600a, 0x77a0, 0xa786, + 0x0001, 0x1904, 0x27ad, 0x70d0, 0xd0b4, 0x1904, 0x27ad, 0x7000, + 0xa082, 0x0002, 0x1a04, 0x27ad, 0x7830, 0xd0bc, 0x1904, 0x27ad, + 0x789b, 0x0080, 0x7baa, 0x7daa, 0x79aa, 0x2001, 0x0002, 0x0006, + 0x6018, 0x8000, 0x601a, 0x0008, 0x0006, 0x2960, 0x6104, 0x2a60, + 0x080c, 0x3ce1, 0x1590, 0xa184, 0x0018, 0x0180, 0xa184, 0x0010, + 0x0118, 0x080c, 0x3977, 0x1548, 0xa184, 0x0008, 0x0138, 0x69a0, + 0xa184, 0x0600, 0x1118, 0x080c, 0x3895, 0x00f8, 0x69a0, 0xa184, + 0x1e00, 0x0528, 0xa184, 0x0800, 0x0178, 0x00c6, 0x2960, 0x6000, + 0xa085, 0x2000, 0x6002, 0x6104, 0xa18d, 0x0010, 0x6106, 0x00ce, + 0x080c, 0x3977, 0x1150, 0x69a0, 0xa184, 0x0200, 0x0118, 0x080c, + 0x38da, 0x0018, 0xa184, 0x0400, 0x19f0, 0x69a0, 0xa184, 0x1000, + 0x0130, 0x6914, 0xa18c, 0xff00, 0x810f, 0x080c, 0x239c, 0x002e, + 0xa68c, 0x00e0, 0xa684, 0x0060, 0x0128, 0xa086, 0x0060, 0x1110, + 0xa18d, 0x4000, 0xa18d, 0x0104, 0x69b6, 0x789b, 0x0060, 0x2800, + 0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc, 0x0168, 0xc0fc, 0x7083, + 0x0000, 0xa08a, 0x000d, 0x0328, 0xa08a, 0x000c, 0x7182, 0x2001, + 0x000c, 0x800c, 0x7186, 0x78aa, 0x3518, 0x3340, 0x3428, 0x8000, + 0x80ac, 0xaf80, 0x002b, 0x20a0, 0x789b, 0x0000, 0xad80, 0x000b, + 0x2098, 0x53a6, 0x23a8, 0x2898, 0x25a0, 0xa286, 0x0020, 0x1508, + 0x70d0, 0xc0b5, 0x70d2, 0x2c00, 0x70b6, 0x2d00, 0x70ba, 0x6814, + 0xc0fc, 0x8007, 0x7882, 0xa286, 0x0002, 0x0904, 0x28f5, 0x70a0, + 0x8000, 0x70a2, 0x74b0, 0xa498, 0x0005, 0x70a8, 0xa306, 0x1108, + 0x73a4, 0x73b2, 0xa286, 0x0010, 0x0904, 0x259d, 0x00de, 0x00ce, + 0x0005, 0x7000, 0xa005, 0x19e0, 0xa286, 0x0002, 0x1904, 0x290c, + 0x080c, 0x3c33, 0x19a8, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x2091, + 0x8000, 0x781b, 0x0068, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, + 0x6898, 0x78d2, 0x78da, 0x2091, 0x8001, 0x7808, 0xc08d, 0x780a, + 0x0126, 0x00d6, 0x00c6, 0x70d0, 0xa084, 0x2e00, 0x2090, 0x00ce, + 0x00de, 0x012e, 0x2900, 0x7056, 0x68bc, 0x703e, 0x7003, 0x0002, + 0x2d00, 0x704a, 0xad80, 0x0009, 0x7042, 0x7830, 0xd0bc, 0x0140, + 0x2091, 0x303d, 0x70d0, 0xa084, 0x303d, 0x2091, 0x8000, 0x2090, + 0x70a0, 0xa005, 0x1108, 0x0005, 0x8421, 0x0de8, 0x724c, 0x70bc, + 0xa200, 0xa015, 0x0804, 0x2725, 0xa286, 0x0010, 0x1560, 0x080c, + 0x3c33, 0x1904, 0x28a0, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x781b, + 0x0068, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, + 0x78da, 0x7808, 0xc08d, 0x780a, 0x70a0, 0x8000, 0x70a2, 0x74b0, + 0xa490, 0x0005, 0x70a8, 0xa206, 0x1108, 0x72a4, 0x72b2, 0x2900, + 0x7056, 0x68bc, 0x703e, 0x7003, 0x0002, 0x2d00, 0x704a, 0xad80, + 0x0009, 0x7042, 0x0005, 0x6bb4, 0xa39d, 0x2000, 0x7b5a, 0x6814, + 0xc0fc, 0x8007, 0x7882, 0x6b94, 0x7bd6, 0x7bde, 0x6e98, 0x7ed2, + 0x7eda, 0x781b, 0x0068, 0x2900, 0x7056, 0x7202, 0x7808, 0xc08d, + 0x780a, 0x2300, 0xa605, 0x0170, 0x70d0, 0xa084, 0x2e00, 0xa086, + 0x2600, 0x1118, 0x2009, 0x0000, 0x0010, 0x2009, 0x0001, 0xa284, + 0x000f, 0x0023, 0xad80, 0x0009, 0x7042, 0x0005, 0x296e, 0x41d9, + 0x41d9, 0x41c7, 0x41d9, 0x296e, 0x296e, 0x296e, 0x080c, 0x254c, + 0x7808, 0xa084, 0xfffd, 0x780a, 0x00f6, 0x2079, 0x4600, 0x78ac, + 0x00fe, 0xd084, 0x01b0, 0x7060, 0xa086, 0x0001, 0x0904, 0x2a32, + 0x7060, 0xa086, 0x0005, 0x1158, 0x7078, 0x2068, 0x681b, 0x0004, + 0x6817, 0x0000, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x7063, + 0x0000, 0x70a3, 0x0000, 0x70a4, 0x70ae, 0x70b2, 0x080c, 0x2682, + 0x0156, 0x2011, 0x0004, 0x7160, 0xa186, 0x0001, 0x0160, 0xa186, + 0x0007, 0x1118, 0x701f, 0x0005, 0x0030, 0x701f, 0x0001, 0x70d0, + 0xc0c5, 0x70d2, 0x0000, 0x2001, 0x460a, 0x2004, 0xa084, 0x00ff, + 0xa086, 0x0018, 0x0130, 0x7018, 0x7016, 0xa005, 0x1110, 0x70a3, + 0x0001, 0x0066, 0x080c, 0x3f26, 0x20a9, 0x0010, 0x2039, 0x0000, + 0x080c, 0x3a66, 0xa7b8, 0x0100, 0x1f04, 0x29c0, 0x006e, 0x7000, + 0x0002, 0x29fd, 0x29db, 0x29db, 0x29d3, 0x29fd, 0x29fd, 0x29fd, + 0x29d1, 0x080c, 0x254c, 0x705c, 0xa005, 0x0538, 0xad06, 0x1118, + 0x6800, 0x705e, 0x0080, 0x6820, 0xd084, 0x1148, 0x6f14, 0x080c, + 0x3b6f, 0x6008, 0xc0d4, 0x600a, 0x080c, 0x37a4, 0x0020, 0x7058, + 0x2060, 0x6800, 0x6002, 0xa684, 0x5f00, 0x681e, 0x6818, 0xd0fc, + 0x0108, 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, 0x6820, 0xa084, + 0x00ff, 0xc09d, 0x6822, 0x080c, 0x1da2, 0x2011, 0x0004, 0x74c8, + 0xa4a0, 0x0100, 0x04b1, 0xaea0, 0x0017, 0x0499, 0x20a9, 0x0101, + 0x74c8, 0x0479, 0x8420, 0x1f04, 0x2a09, 0x70c0, 0x2060, 0x2021, 0x0002, 0x20a9, 0x0100, 0x6110, 0x81ff, 0x0198, 0x6018, 0x0016, - 0x0006, 0x2011, 0x4302, 0x220c, 0xa102, 0x2012, 0x000e, 0x001e, - 0xa102, 0x0338, 0x6012, 0x1128, 0x2011, 0x4304, 0x2204, 0xc0a5, - 0x2012, 0x601b, 0x0000, 0xace0, 0x0010, 0x1f04, 0x291b, 0x8421, - 0x1d00, 0x015e, 0x7003, 0x0000, 0x704f, 0x0000, 0x0005, 0x0046, - 0x2404, 0xa005, 0x01a8, 0x2068, 0x6800, 0x0006, 0x6a1a, 0x6817, - 0x0000, 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820, - 0xa084, 0x00ff, 0xc09d, 0x6822, 0x080c, 0x1d3d, 0x000e, 0x0c48, - 0x004e, 0x2023, 0x0000, 0x0005, 0xa282, 0x0003, 0x0310, 0x080c, - 0x243b, 0x2300, 0x0002, 0x2966, 0x29e3, 0x29fd, 0xa282, 0x0002, - 0x0110, 0x080c, 0x243b, 0x7064, 0x7067, 0x0000, 0x7083, 0x0000, - 0x0022, 0x77d4, 0xc7c5, 0x77d6, 0x0002, 0x297d, 0x297d, 0x297f, - 0x29b7, 0x35df, 0x297d, 0x29b7, 0x297d, 0x080c, 0x243b, 0x7774, - 0x080c, 0x3861, 0x7774, 0xa7bc, 0x8f00, 0x080c, 0x396d, 0x6018, - 0xa005, 0x0528, 0xd7fc, 0x1118, 0x2021, 0x89c0, 0x0010, 0x2021, - 0x8ad0, 0x2009, 0x0005, 0x2011, 0x0010, 0x080c, 0x2a17, 0x01b8, - 0x0156, 0x20a9, 0x0101, 0xd7fc, 0x1118, 0x2021, 0x88c0, 0x0010, - 0x2021, 0x89d0, 0x0046, 0x2009, 0x0005, 0x2011, 0x0010, 0x080c, - 0x2a17, 0x004e, 0x0118, 0x8420, 0x1f04, 0x29a2, 0x015e, 0x8738, - 0xa784, 0x001f, 0x1990, 0x0804, 0x248f, 0x0804, 0x248f, 0x7774, - 0x080c, 0x396d, 0x6018, 0xa005, 0x0520, 0xd7fc, 0x1118, 0x2021, - 0x89c0, 0x0010, 0x2021, 0x8ad0, 0x2009, 0x0005, 0x2011, 0x0020, - 0x080c, 0x2a17, 0x01b0, 0x0156, 0x20a9, 0x0101, 0xd7fc, 0x1118, - 0x2021, 0x88c0, 0x0010, 0x2021, 0x89d0, 0x0046, 0x2009, 0x0005, - 0x2011, 0x0020, 0x04e1, 0x004e, 0x0118, 0x8420, 0x1f04, 0x29d5, - 0x015e, 0x0804, 0x248f, 0x2200, 0x0002, 0x29e8, 0x29ea, 0x29ea, - 0x080c, 0x243b, 0x2009, 0x0012, 0x7064, 0xa086, 0x0002, 0x0110, - 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0108, 0x691a, 0x7067, 0x0000, - 0x70d4, 0xc0c5, 0x70d6, 0x0804, 0x3a3f, 0x2200, 0x0002, 0x2a04, - 0x29ea, 0x2a02, 0x080c, 0x243b, 0x080c, 0x3d52, 0x7000, 0xa086, - 0x0002, 0x1904, 0x356d, 0x080c, 0x35c5, 0x6008, 0xa084, 0xfbef, - 0x600a, 0x080c, 0x355f, 0x0904, 0x356d, 0x0804, 0x248f, 0x2404, - 0xa005, 0x0590, 0x2068, 0x2d04, 0x0006, 0x6814, 0xa706, 0x0118, - 0x2d20, 0x000e, 0x0ca8, 0x000e, 0x2022, 0x691a, 0x6817, 0x0000, - 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820, 0xa084, - 0x00ff, 0xa205, 0x6822, 0x080c, 0x1d3d, 0x2021, 0x4302, 0x241c, - 0x8319, 0x2322, 0x6010, 0x8001, 0x6012, 0x1128, 0x2021, 0x4304, - 0x2404, 0xc0a5, 0x2022, 0x6008, 0xa084, 0xf9ef, 0x600a, 0x080c, - 0x258b, 0x080c, 0x35c5, 0x0005, 0xa085, 0x0001, 0x0ce0, 0x2300, - 0x0002, 0x2a56, 0x2a54, 0x2abc, 0x080c, 0x243b, 0x78e4, 0xa005, - 0x1708, 0x3208, 0xa18c, 0x0800, 0x0118, 0x0104, 0x248c, 0x0010, - 0x0304, 0x248c, 0x2008, 0xa084, 0x0030, 0x1110, 0x0804, 0x30a0, - 0x78ec, 0xa084, 0x0003, 0x0dd0, 0x2100, 0xa084, 0x0007, 0x0002, - 0x2a9f, 0x2aa8, 0x2a95, 0x2a78, 0x3a83, 0x3a83, 0x2a78, 0x2ab2, - 0x080c, 0x243b, 0x7000, 0xa086, 0x0004, 0x1190, 0x7064, 0xa086, - 0x0002, 0x1130, 0x2011, 0x0002, 0x2019, 0x0000, 0x0804, 0x295c, - 0x7064, 0xa086, 0x0006, 0x0db0, 0x7064, 0xa086, 0x0004, 0x0d90, - 0x79e4, 0x2001, 0x0003, 0x0804, 0x2daa, 0x6818, 0xd0fc, 0x0110, - 0x681b, 0x001d, 0x080c, 0x3837, 0x781b, 0x006e, 0x0005, 0x6818, - 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3837, 0x0804, 0x3a61, - 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3837, 0x781b, - 0x00fa, 0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, - 0x3837, 0x781b, 0x00cb, 0x0005, 0xa584, 0x000f, 0x11c0, 0x7000, - 0x0002, 0x248f, 0x2ac9, 0x2acb, 0x356d, 0x356d, 0x356d, 0x2ac9, - 0x2ac9, 0x080c, 0x243b, 0x080c, 0x35c5, 0x6008, 0xa084, 0xfbef, - 0x600a, 0x080c, 0x355f, 0x0904, 0x356d, 0x0804, 0x248f, 0x78e4, - 0xa005, 0x1b04, 0x2a7a, 0x3208, 0xa18c, 0x0800, 0x0118, 0x0104, - 0x2a7a, 0x0010, 0x0304, 0x2a7a, 0x2008, 0xa084, 0x0030, 0x1118, - 0x781b, 0x0068, 0x0005, 0x78ec, 0xa084, 0x0003, 0x0dc8, 0x2100, - 0xa184, 0x0007, 0x0002, 0x2b02, 0x2b06, 0x2afd, 0x2afb, 0x3a83, - 0x3a83, 0x2afb, 0x3a7d, 0x080c, 0x243b, 0x080c, 0x383d, 0x781b, - 0x006e, 0x0005, 0x080c, 0x383d, 0x0804, 0x3a61, 0x080c, 0x383d, - 0x781b, 0x00fa, 0x0005, 0x080c, 0x383d, 0x781b, 0x00cb, 0x0005, - 0x2300, 0x0002, 0x2b17, 0x2b15, 0x2b19, 0x080c, 0x243b, 0x0804, - 0x3220, 0x681b, 0x0016, 0x78a3, 0x0000, 0x79e4, 0xa184, 0x0030, - 0x0904, 0x3220, 0x78ec, 0xa084, 0x0003, 0x0904, 0x3220, 0xa184, - 0x0100, 0x0d98, 0xa184, 0x0007, 0x0002, 0x2b35, 0x2b06, 0x2a95, - 0x3a3f, 0x3a83, 0x3a83, 0x3a3f, 0x3a7d, 0x080c, 0x3a4b, 0x0005, - 0xa282, 0x0005, 0x0310, 0x080c, 0x243b, 0x7898, 0x2040, 0x2300, - 0x0002, 0x2b44, 0x2d41, 0x2d4b, 0x2200, 0x0002, 0x2b60, 0x2b4d, - 0x2b60, 0x2b4b, 0x2d25, 0x080c, 0x243b, 0x789b, 0x0018, 0x78a8, - 0x2010, 0xa084, 0x00ff, 0xa082, 0x0020, 0x0a04, 0x3809, 0xa08a, - 0x0004, 0x1a04, 0x3809, 0x0002, 0x3809, 0x3809, 0x3809, 0x37bf, - 0x789b, 0x0018, 0x79a8, 0xa184, 0x0080, 0x0148, 0x0804, 0x3809, - 0x7000, 0xa005, 0x1dd8, 0x2011, 0x0004, 0x0804, 0x33b2, 0xa184, - 0x00ff, 0xa08a, 0x0010, 0x1a04, 0x3809, 0x0002, 0x2b88, 0x2b86, - 0x2b9a, 0x2b9e, 0x2c3c, 0x3809, 0x3809, 0x2c3e, 0x3809, 0x3809, - 0x2d21, 0x2d21, 0x3809, 0x3809, 0x3809, 0x2d23, 0x080c, 0x243b, - 0xd6e4, 0x0140, 0x2001, 0x0300, 0x8000, 0x8000, 0x783a, 0x781b, - 0x00c6, 0x0005, 0x6818, 0xd0fc, 0x0118, 0x681b, 0x001d, 0x0c90, - 0x0804, 0x3a3f, 0x681b, 0x001d, 0x0804, 0x3831, 0x6920, 0x6922, - 0xa684, 0x1800, 0x15e0, 0x6820, 0xd084, 0x1904, 0x2be7, 0x6818, - 0xa086, 0x0008, 0x1110, 0x681b, 0x0000, 0xd6d4, 0x0568, 0xd6bc, - 0x0558, 0x7087, 0x0000, 0x6818, 0xa084, 0x003f, 0xa08a, 0x000d, - 0x0718, 0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a, - 0x789b, 0x0061, 0x78aa, 0x0156, 0x0136, 0x0146, 0x0016, 0x3208, - 0xa18c, 0x0600, 0x0118, 0x20a1, 0x022b, 0x0010, 0x20a1, 0x012b, - 0x001e, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, - 0x53a6, 0x014e, 0x013e, 0x015e, 0x781b, 0x0071, 0x0005, 0xd6e4, - 0x0130, 0x781b, 0x0083, 0x0005, 0x781b, 0x0083, 0x0005, 0xa684, - 0x0060, 0x0dd0, 0xd6dc, 0x0dc0, 0xd6fc, 0x01a0, 0xc6fc, 0x7e5a, - 0x6eb6, 0x7adc, 0x79d8, 0x78d0, 0x8007, 0xa084, 0x007f, 0xa108, - 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, - 0xa303, 0x68ae, 0xd6f4, 0x0118, 0xc6f4, 0x7e5a, 0x6eb6, 0x7000, - 0xa086, 0x0003, 0x1148, 0x0006, 0x080c, 0x3d52, 0x080c, 0x3fb8, - 0x000e, 0x781b, 0x0080, 0x0005, 0xa006, 0x080c, 0x4083, 0x6ab0, - 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0120, 0x2200, 0xa422, - 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, 0x6ba6, 0x7bd6, 0x7bde, - 0x2300, 0xa405, 0x1130, 0xc6f5, 0x7e5a, 0x6eb6, 0x781b, 0x0080, - 0x0005, 0x781b, 0x0080, 0x2200, 0xa115, 0x1118, 0x080c, 0x3fb8, - 0x0005, 0x080c, 0x3fe5, 0x0005, 0x080c, 0x243b, 0x0804, 0x2cbd, - 0x00c6, 0x7058, 0x2060, 0x7aa8, 0xa294, 0x00ff, 0xa286, 0x0004, - 0x11d8, 0x6920, 0xd1e4, 0x1170, 0x2039, 0x0000, 0x2041, 0x0000, - 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x36f6, 0x080c, 0x379a, - 0x0804, 0x2cb1, 0xa18c, 0xecff, 0x6922, 0x6104, 0xa18c, 0xffdd, - 0x6106, 0x6000, 0xc0ac, 0x6002, 0xa286, 0x0003, 0x01d0, 0x6104, - 0xa18c, 0x0010, 0x0548, 0x080c, 0x3969, 0x080c, 0x3776, 0x88ff, - 0x0518, 0x00ce, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, - 0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, 0x781b, 0x0082, - 0x0005, 0x6920, 0xd1cc, 0x0130, 0xa18c, 0xfdff, 0x6922, 0x6000, - 0xc0ec, 0x6002, 0x2039, 0x0000, 0x2041, 0x0000, 0x2031, 0x0000, - 0xa006, 0x2010, 0x080c, 0x379a, 0xa286, 0x0001, 0x0158, 0x6104, - 0xa18c, 0x0008, 0x01b0, 0x080c, 0x3969, 0x080c, 0x3696, 0x88ff, - 0x1980, 0x0078, 0x6920, 0xd1c4, 0x0130, 0xa18c, 0xfeff, 0x6922, - 0x6000, 0xc0e4, 0x6002, 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, - 0x36f6, 0x00ce, 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005, - 0x781b, 0x0083, 0x0005, 0x0804, 0x382d, 0x2808, 0x789b, 0x0080, - 0x2019, 0x0080, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x1188, - 0x7ca8, 0xa4a4, 0x00ff, 0xa480, 0x0002, 0xa300, 0x2018, 0xa102, - 0x0a04, 0x2c40, 0x0904, 0x2c40, 0x24a8, 0x7aa8, 0x1f04, 0x2cd5, - 0x0c48, 0xa284, 0x00f0, 0xa082, 0x0020, 0x06b8, 0x2200, 0xa082, - 0x0021, 0x1698, 0x7aa8, 0x8318, 0x8318, 0x2100, 0xa302, 0x0ad0, - 0xa286, 0x0023, 0x0980, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, - 0xa684, 0xfff1, 0xc0a5, 0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a, - 0x78a0, 0x8001, 0x0904, 0x2cb1, 0x20a8, 0x7998, 0x789b, 0x0060, - 0x78aa, 0x2011, 0x0080, 0x799a, 0x78a8, 0x7998, 0x7a9a, 0x78aa, - 0x7a98, 0x1f04, 0x2d03, 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b, - 0x006e, 0x0005, 0x781b, 0x0082, 0x0005, 0x8318, 0x2100, 0xa302, - 0x0a04, 0x2cc2, 0xa284, 0x0080, 0x1904, 0x3831, 0x78a0, 0xa005, - 0x08c8, 0x0804, 0x3831, 0x0804, 0x3809, 0x7058, 0xa04d, 0x789b, - 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e, 0x0001, 0x0110, 0x080c, - 0x243b, 0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, - 0x0005, 0x1a04, 0x3809, 0x0002, 0x3809, 0x3615, 0x3809, 0x3726, - 0x3b83, 0xa282, 0x0000, 0x1110, 0x080c, 0x243b, 0x080c, 0x3837, - 0x781b, 0x0082, 0x0005, 0xa282, 0x0003, 0x1110, 0x080c, 0x243b, - 0xd4fc, 0x11d0, 0x7064, 0xa005, 0x0110, 0x080c, 0x243b, 0x6f14, - 0x7776, 0xa7bc, 0x8f00, 0x080c, 0x396d, 0x6008, 0xa085, 0x0021, - 0x600a, 0x8738, 0xa784, 0x001f, 0x1db0, 0x080c, 0x383a, 0x7067, - 0x0002, 0x701f, 0x0009, 0x0010, 0x080c, 0x3846, 0x781b, 0x0082, - 0x0005, 0xa282, 0x0004, 0x0310, 0x080c, 0x243b, 0x2300, 0x0002, - 0x2d7b, 0x2eff, 0x2f3b, 0xa286, 0x0003, 0x0560, 0x7200, 0x7cd8, - 0x7ddc, 0x7fd0, 0x71d4, 0xd1b4, 0x00f0, 0x7868, 0xa084, 0x00ff, - 0x11d0, 0xa282, 0x0002, 0x12b8, 0x00d6, 0x783b, 0x8300, 0x781b, - 0x0059, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, - 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x00de, - 0x2001, 0x0000, 0x0058, 0x783b, 0x1300, 0x781b, 0x0057, 0x2001, - 0x0000, 0x0020, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x704a, 0x68a0, - 0xd0ec, 0x0118, 0x6008, 0xc08d, 0x600a, 0xa284, 0x000f, 0x0002, - 0x2ee0, 0x2dc5, 0x2dc2, 0x3012, 0x3085, 0x248f, 0x2dc0, 0x2dc0, - 0x080c, 0x243b, 0x6008, 0xc0d4, 0x600a, 0xd6e4, 0x0120, 0x7048, - 0xa086, 0x0014, 0x11e8, 0x080c, 0x3d52, 0x2009, 0x0000, 0x6818, - 0xd0fc, 0x0108, 0x7048, 0xa086, 0x0014, 0x0168, 0x6818, 0xa086, - 0x0008, 0x1904, 0x2ea2, 0x7858, 0xd09c, 0x0904, 0x2ea2, 0x6820, - 0xd0ac, 0x0904, 0x2ea2, 0x681b, 0x0014, 0x2009, 0x0002, 0x04a8, - 0x7868, 0xa08c, 0x00ff, 0x0588, 0xa186, 0x0008, 0x1158, 0x6008, - 0xc0a4, 0x600a, 0x080c, 0x355f, 0x0540, 0x080c, 0x35c5, 0x080c, - 0x3d52, 0x0060, 0xa186, 0x0028, 0x1500, 0x6018, 0xa005, 0x0d78, - 0x8001, 0x0d68, 0x8001, 0x0d58, 0x601e, 0x0c48, 0x6820, 0xd084, - 0x0904, 0x248f, 0xc084, 0x6822, 0x080c, 0x2580, 0x705c, 0x00c6, - 0x2060, 0x6800, 0x6002, 0x00ce, 0x6004, 0x6802, 0xa005, 0x2d00, - 0x1108, 0x6002, 0x6006, 0x0804, 0x248f, 0x0016, 0x81ff, 0x15e0, - 0x7000, 0xa086, 0x0030, 0x05c0, 0x71d4, 0xd1b4, 0x11e8, 0x7060, - 0xa005, 0x1590, 0x70a4, 0xa086, 0x0001, 0x0570, 0x7003, 0x0000, - 0x0046, 0x0056, 0x0076, 0x0066, 0x00c6, 0x00d6, 0x080c, 0x24b2, - 0x00de, 0x00ce, 0x006e, 0x007e, 0x005e, 0x004e, 0x71d4, 0xd1b4, - 0x11d8, 0x7003, 0x0040, 0x00c0, 0x080c, 0x3a8d, 0x11a8, 0x781b, - 0x0068, 0x00d6, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, - 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, - 0x7808, 0xc08d, 0x780a, 0x00de, 0x080c, 0x2f63, 0x001e, 0x81ff, - 0x0904, 0x2ea2, 0xa684, 0xdf00, 0x681e, 0x682b, 0x0000, 0x6f14, - 0xa186, 0x0002, 0x15c0, 0x6818, 0xa086, 0x0014, 0x1130, 0x2008, - 0xd6e4, 0x0118, 0x7868, 0xa08c, 0x00ff, 0x080c, 0x3850, 0x080c, - 0x258b, 0x6820, 0xd0dc, 0x1538, 0x8717, 0xa294, 0x000f, 0x8213, - 0x8213, 0x8213, 0xb284, 0x0600, 0x0118, 0xa290, 0x47c0, 0x0010, - 0xa290, 0x4840, 0xa290, 0x0000, 0x221c, 0xd3c4, 0x0130, 0x8210, - 0x2204, 0xa085, 0x0038, 0x2012, 0x8211, 0xd3d4, 0x0138, 0x68a0, - 0xd0c4, 0x1120, 0x080c, 0x2fcb, 0x0804, 0x248f, 0x6008, 0xc08d, - 0x600a, 0x0008, 0x692a, 0x6916, 0x6818, 0xd0fc, 0x0110, 0x7048, - 0x681a, 0xa68c, 0xdf00, 0x691e, 0x6410, 0x84ff, 0x0168, 0x2009, - 0x4302, 0x2104, 0x8001, 0x200a, 0x8421, 0x6412, 0x1128, 0x2021, - 0x4304, 0x2404, 0xc0a5, 0x2022, 0x6018, 0xa005, 0x0118, 0x8001, - 0x601a, 0x1118, 0x6008, 0xc0a4, 0x600a, 0x6820, 0xd084, 0x1130, - 0x6800, 0xa005, 0x1108, 0x6002, 0x6006, 0x0020, 0x705c, 0x2060, - 0x6800, 0x6002, 0x2061, 0x4300, 0x6887, 0x0103, 0x2d08, 0x206b, - 0x0000, 0x6068, 0xa005, 0x616a, 0x0110, 0x2d02, 0x0008, 0x616e, - 0x7200, 0xa286, 0x0030, 0x0158, 0xa286, 0x0040, 0x1904, 0x248f, - 0x7003, 0x0002, 0x704c, 0x2068, 0x68c4, 0x2060, 0x0005, 0x7003, - 0x0002, 0x70bc, 0xa06d, 0x68bc, 0x7042, 0x70b8, 0xa065, 0x68c0, - 0x705a, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x0005, 0xa282, - 0x0004, 0x0210, 0x080c, 0x243b, 0x2200, 0x0002, 0x2f0a, 0x2f19, - 0x2f25, 0x2f19, 0xa586, 0x1300, 0x0160, 0xa586, 0x8300, 0x1d90, - 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef, - 0x600a, 0x7000, 0xa086, 0x0005, 0x0128, 0x080c, 0x3837, 0x781b, - 0x0082, 0x0005, 0x781b, 0x0083, 0x0005, 0x7890, 0x8007, 0x8001, - 0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff, - 0xa186, 0x0003, 0x0128, 0xa186, 0x0000, 0x0110, 0x0804, 0x3809, - 0x781b, 0x0083, 0x0005, 0x6820, 0xc095, 0x6822, 0x82ff, 0x1118, - 0x080c, 0x3837, 0x0030, 0x8211, 0x0110, 0x080c, 0x243b, 0x080c, - 0x3846, 0x781b, 0x0082, 0x0005, 0x080c, 0x3aa0, 0x7830, 0xa084, - 0x00c0, 0x1170, 0x0016, 0x3208, 0xa18c, 0x0800, 0x001e, 0x0118, - 0x0104, 0x2f60, 0x0010, 0x0304, 0x2f60, 0x791a, 0xa006, 0x0005, - 0xa085, 0x0001, 0x0005, 0xa684, 0x0060, 0x1130, 0x682f, 0x0000, - 0x6833, 0x0000, 0x0804, 0x2fca, 0xd6dc, 0x1198, 0x68b4, 0xd0dc, - 0x1180, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x7048, 0xa005, 0x1130, - 0x2200, 0xa105, 0x0904, 0x3d52, 0x704b, 0x0015, 0x0804, 0x3d52, - 0x0005, 0xd6ac, 0x01f0, 0xd6f4, 0x0130, 0x682f, 0x0000, 0x6833, - 0x0000, 0x0804, 0x3d52, 0x68b4, 0xa084, 0x4000, 0xa635, 0xd6f4, - 0x1da0, 0x7048, 0xa005, 0x1110, 0x704b, 0x0015, 0xd6dc, 0x1128, - 0x68b4, 0xd0dc, 0x0110, 0x6ca8, 0x6da4, 0x6c2e, 0x6d32, 0x0804, - 0x3d52, 0xd6f4, 0x0130, 0x682f, 0x0000, 0x6833, 0x0000, 0x0804, - 0x3d52, 0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4, 0x1da0, 0x7048, - 0xa005, 0x1110, 0x704b, 0x0015, 0x2408, 0x2510, 0x2700, 0x8007, - 0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x692e, 0x6a32, 0x2100, - 0xa205, 0x1110, 0x0804, 0x3d52, 0x7000, 0xa086, 0x0006, 0x0110, - 0x0804, 0x3d52, 0x0005, 0x6946, 0x6008, 0xc0cd, 0xd3cc, 0x0108, - 0xc08d, 0x600a, 0x6818, 0x683a, 0x681b, 0x0006, 0x688f, 0x0000, - 0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003, - 0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b, 0x0020, - 0x7000, 0x0002, 0x248f, 0x2ffa, 0x2ff4, 0x2ff2, 0x2ff2, 0x2ff2, - 0x2ff2, 0x2ff2, 0x080c, 0x243b, 0x6820, 0xd084, 0x1118, 0x080c, - 0x35ab, 0x0030, 0x705c, 0x2c50, 0x2060, 0x6800, 0x6002, 0x2a60, - 0x3208, 0xa18c, 0x0600, 0x0118, 0x2021, 0x4358, 0x0010, 0x2021, - 0x4398, 0x2404, 0xa005, 0x0110, 0x2020, 0x0cd8, 0x2d22, 0x206b, - 0x0000, 0x0005, 0x080c, 0x35b1, 0x080c, 0x35c5, 0x6008, 0xc0cc, - 0x600a, 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14, 0x6938, 0x691a, - 0x6944, 0x6916, 0x3208, 0xa18c, 0x0600, 0x0118, 0x2009, 0x0000, - 0x0010, 0x2009, 0x0001, 0x080c, 0x40b1, 0xd6dc, 0x0118, 0x691c, - 0xc1ed, 0x691e, 0x6818, 0xd0fc, 0x0148, 0x7868, 0xa08c, 0x00ff, - 0x0118, 0x681b, 0x001e, 0x0010, 0x681b, 0x0000, 0xb284, 0x0600, - 0x1118, 0x2021, 0x4398, 0x0010, 0x2021, 0x4358, 0x6800, 0x2022, - 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x68c0, 0x2060, 0x6000, 0xd0a4, - 0x0580, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x00d6, - 0x00f6, 0x0156, 0x0146, 0x2079, 0x4300, 0x080c, 0x1b35, 0x014e, - 0x015e, 0x00fe, 0x70cc, 0x2010, 0x2009, 0x0101, 0x0026, 0x2204, - 0xa06d, 0x0140, 0x6814, 0xa706, 0x0110, 0x6800, 0x0cc8, 0x6820, - 0xc0d5, 0x6822, 0x002e, 0x8210, 0x8109, 0x1d80, 0x00de, 0x7067, - 0x0003, 0x707f, 0x0000, 0x7776, 0x7083, 0x000f, 0x71d4, 0xc1c4, - 0x71d6, 0x080c, 0x1d3d, 0x0804, 0x248f, 0x7cd8, 0x7ddc, 0x7fd0, - 0x080c, 0x2f63, 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14, 0x080c, - 0x3aa4, 0xa08c, 0x00ff, 0x6916, 0x6818, 0xd0fc, 0x0110, 0x7048, - 0x681a, 0xa68c, 0xdf00, 0x691e, 0x7067, 0x0000, 0x0804, 0x248f, - 0x7000, 0xa005, 0x1110, 0x0804, 0x248f, 0xa006, 0x080c, 0x3d52, - 0x6920, 0xd1ac, 0x1110, 0x681b, 0x0014, 0xa68c, 0xdf00, 0x691e, - 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff, 0x6822, 0x7000, 0x0002, - 0x248f, 0x30c2, 0x30c2, 0x30c5, 0x30c5, 0x30c5, 0x30c0, 0x30c0, - 0x080c, 0x243b, 0x6818, 0x0804, 0x2daa, 0x6008, 0xc0a4, 0x600a, - 0x6817, 0x0000, 0x0804, 0x357a, 0x2300, 0x0002, 0x30d1, 0x30d3, - 0x3110, 0x080c, 0x243b, 0xd6fc, 0x1904, 0x2bee, 0x7000, 0xa00d, - 0x0002, 0x248f, 0x30e3, 0x30e3, 0x3104, 0x30e3, 0x310d, 0x30e1, - 0x30e1, 0x080c, 0x243b, 0xa684, 0x0060, 0xa086, 0x0060, 0x11d0, - 0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a, 0x681c, 0xc0ac, 0x681e, 0xa186, - 0x0002, 0x0110, 0x080c, 0x3d52, 0x080c, 0x3fb8, 0x781b, 0x0083, - 0x71d4, 0xd1b4, 0x1904, 0x248c, 0x70a4, 0xa086, 0x0001, 0x1904, - 0x24ce, 0x0005, 0xd6ec, 0x0d30, 0x6818, 0xd0fc, 0x0130, 0x681b, - 0x0015, 0xd6f4, 0x0110, 0x681b, 0x0007, 0x080c, 0x3a4b, 0x0005, - 0x080c, 0x243b, 0x2300, 0x0002, 0x3119, 0x3134, 0x3182, 0x080c, - 0x243b, 0x7000, 0x0002, 0x3123, 0x3125, 0x3125, 0x3123, 0x3123, - 0x3123, 0x3123, 0x3123, 0x080c, 0x243b, 0x080c, 0x3fb8, 0x681c, - 0xc0b4, 0x681e, 0x70d4, 0xd0b4, 0x1904, 0x248c, 0x70a4, 0xa086, - 0x0001, 0x1904, 0x24ce, 0x0005, 0xd6fc, 0x15e0, 0x7000, 0xa00d, - 0x0002, 0x248f, 0x3149, 0x3143, 0x316a, 0x3149, 0x316f, 0x3141, - 0x3141, 0x080c, 0x243b, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, - 0x78da, 0xa684, 0x0060, 0xa086, 0x0060, 0x11d0, 0xa6b4, 0xbfbf, - 0xc6ed, 0x7e5a, 0xa186, 0x0002, 0x0110, 0x080c, 0x3d52, 0x080c, - 0x3fb8, 0x781b, 0x0083, 0x681c, 0xc0b4, 0x681e, 0x71d4, 0xd1b4, - 0x1904, 0x248c, 0x70a4, 0xa086, 0x0001, 0x1904, 0x24ce, 0x0005, - 0xd6ec, 0x0d30, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x0007, 0x781b, - 0x00fb, 0x0005, 0xc6fc, 0x7e5a, 0x7adc, 0x79d8, 0x6b98, 0x2100, - 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x79d2, 0x781b, - 0x0083, 0x0005, 0xd6dc, 0x0130, 0x782b, 0x3009, 0x781b, 0x0083, - 0x0804, 0x248c, 0x7884, 0xc0ac, 0x7886, 0x78e4, 0xa084, 0x0008, - 0x1150, 0xa484, 0x0200, 0x0108, 0xc6f5, 0xc6dd, 0x7e5a, 0x781b, - 0x0083, 0x0804, 0x248c, 0x6820, 0xc095, 0x6822, 0x080c, 0x39ca, - 0xc6dd, 0x080c, 0x3837, 0x781b, 0x0082, 0x0804, 0x248c, 0x2300, - 0x0002, 0x31ac, 0x31ae, 0x31b0, 0x080c, 0x243b, 0x0804, 0x3831, - 0x7d98, 0xd6d4, 0x11f8, 0x79e4, 0xd1ac, 0x0130, 0x78ec, 0xa084, - 0x0003, 0x0110, 0x782b, 0x3009, 0x789b, 0x0060, 0x78ab, 0x0000, - 0xa684, 0xfffb, 0x785a, 0x7d9a, 0x79e4, 0xd1ac, 0x0120, 0x78ec, - 0xa084, 0x0003, 0x1120, 0x2001, 0x0014, 0x0804, 0x2daa, 0xa184, - 0x0007, 0x04c2, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060, 0x79a8, - 0x81ff, 0x0568, 0x789b, 0x0080, 0x7ba8, 0xa384, 0x0001, 0x11d0, - 0x7ba8, 0x7ba8, 0xa386, 0x0004, 0x1118, 0x2009, 0xffdf, 0x0058, - 0xa386, 0x0001, 0x1118, 0x2009, 0xfff7, 0x0028, 0xa386, 0x0003, - 0x1148, 0x2009, 0xffef, 0x00c6, 0x7058, 0x2060, 0x6004, 0xa104, - 0x6006, 0x00ce, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, - 0x785a, 0x782b, 0x3009, 0x6920, 0xa18c, 0xecff, 0x6922, 0x7d9a, - 0x0804, 0x3a3f, 0x2a9f, 0x2aa8, 0x3214, 0x321a, 0x3212, 0x3212, - 0x3a3f, 0x3a3f, 0x080c, 0x243b, 0x6920, 0xa18c, 0xfcff, 0x6922, - 0x0804, 0x3a45, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0804, 0x3a3f, - 0x79e4, 0xa184, 0x0030, 0x0120, 0x78ec, 0xa084, 0x0003, 0x1558, - 0x7000, 0xa086, 0x0004, 0x1190, 0x7064, 0xa086, 0x0002, 0x1130, - 0x2011, 0x0002, 0x2019, 0x0000, 0x0804, 0x295c, 0x7064, 0xa086, - 0x0006, 0x0db0, 0x7064, 0xa086, 0x0004, 0x0d90, 0x7000, 0xa086, - 0x0000, 0x0904, 0x248c, 0x6920, 0xa184, 0x0420, 0x0128, 0xc1d4, - 0x6922, 0x6818, 0x0804, 0x2daa, 0x6818, 0xc0fd, 0x681a, 0x2001, - 0x0014, 0x0804, 0x2daa, 0xa184, 0x0007, 0x0002, 0x3a3f, 0x3a3f, - 0x325e, 0x3a3f, 0x3a83, 0x3a83, 0x3a3f, 0x3a3f, 0xd6bc, 0x0570, - 0x7184, 0x81ff, 0x0558, 0xa182, 0x000d, 0x1318, 0x7087, 0x0000, - 0x0028, 0xa182, 0x000c, 0x7086, 0x2009, 0x000c, 0x789b, 0x0061, - 0x79aa, 0x0156, 0x0136, 0x0146, 0x7088, 0x8114, 0xa210, 0x728a, - 0xa080, 0x000b, 0xad00, 0x2098, 0xb284, 0x0600, 0x0118, 0x20a1, - 0x022b, 0x0010, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8108, 0x81ac, - 0x53a6, 0x014e, 0x013e, 0x015e, 0x0804, 0x3a45, 0xd6d4, 0x1904, - 0x32d1, 0x6820, 0xd084, 0x0904, 0x3a45, 0xa68c, 0x0060, 0xa684, - 0x0060, 0x0120, 0xa086, 0x0060, 0x1108, 0xc1f5, 0xc194, 0x795a, - 0x69b6, 0x789b, 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061, 0x6818, - 0xc0fd, 0x681a, 0x78aa, 0x8008, 0x810c, 0x0904, 0x35da, 0xa18c, - 0x00f8, 0x1904, 0x35da, 0x0156, 0x0136, 0x0146, 0x0016, 0x20a1, - 0x012b, 0x3208, 0xa18c, 0x0600, 0x0110, 0x20a1, 0x022b, 0x001e, - 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, - 0x014e, 0x013e, 0x015e, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x0804, - 0x3a45, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x0008, 0x080c, 0x3837, - 0x781b, 0x00ed, 0x0005, 0x2300, 0x0002, 0x32e2, 0x3398, 0x32e0, - 0x080c, 0x243b, 0x7cd8, 0x7ddc, 0x7fd0, 0x82ff, 0x11f0, 0x7200, - 0xa286, 0x0003, 0x0904, 0x2d7f, 0x71d4, 0xd1b4, 0x00c0, 0x00d6, - 0x783b, 0x8800, 0x781b, 0x0059, 0x70bc, 0xa06d, 0x68b4, 0xc0a5, - 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, - 0x71d6, 0x7003, 0x0030, 0x00de, 0x0030, 0x7200, 0x0020, 0x783b, - 0x1800, 0x781b, 0x0057, 0xa284, 0x000f, 0x0002, 0x3383, 0x3344, - 0x3318, 0x2da7, 0x3316, 0x3383, 0x3316, 0x3316, 0x080c, 0x243b, - 0x681c, 0xd0ec, 0x0118, 0x6008, 0xc08d, 0x600a, 0x6920, 0xc185, - 0x6922, 0x6800, 0x6006, 0xa005, 0x1108, 0x6002, 0x6008, 0xc0d4, - 0x600a, 0x681c, 0xa084, 0x000e, 0x1148, 0xb284, 0x0600, 0x0118, - 0x2009, 0x89c0, 0x0040, 0x2009, 0x8ad0, 0x0028, 0x7030, 0x68ba, - 0x7140, 0x70cc, 0xa108, 0x2104, 0x6802, 0x2d0a, 0x715e, 0xd6dc, - 0x1118, 0xc6fc, 0x6eb6, 0x04f8, 0x6eb6, 0xa684, 0x0060, 0x05d8, - 0xd6dc, 0x1150, 0xa684, 0x7fff, 0x68b6, 0x6894, 0x68a6, 0x6898, - 0x68aa, 0x080c, 0x3d52, 0x0478, 0xd6ac, 0x0140, 0xa006, 0x080c, - 0x3d52, 0x2408, 0x2510, 0x69aa, 0x6aa6, 0x0068, 0x2408, 0x2510, - 0x2700, 0x8007, 0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x69aa, - 0x6aa6, 0x080c, 0x3d52, 0xd6fc, 0x01b0, 0xa684, 0x7fff, 0x68b6, - 0x2510, 0x2408, 0xd6ac, 0x1138, 0x2700, 0x8007, 0xa084, 0x007f, - 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, - 0x2200, 0xa303, 0x68ae, 0x7000, 0xa086, 0x0030, 0x1904, 0x248f, - 0x7003, 0x0002, 0x70bc, 0xa06d, 0x68bc, 0x7042, 0x70b8, 0xa065, - 0x68c0, 0x705a, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x0005, - 0xa586, 0x8800, 0x1148, 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, - 0x6008, 0xa084, 0xfbef, 0x600a, 0x0804, 0x3831, 0x7047, 0x0000, - 0xa282, 0x0006, 0x0310, 0x080c, 0x243b, 0x2300, 0x0002, 0x33b2, - 0x33e4, 0x340f, 0x2200, 0x0002, 0x33ba, 0x3831, 0x33bc, 0x33ba, - 0x343f, 0x349d, 0x080c, 0x243b, 0x7003, 0x0005, 0xb284, 0x0600, - 0x0118, 0x2001, 0x8ae0, 0x0010, 0x2001, 0x8b12, 0x2068, 0x704e, - 0x0156, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x1f04, 0x33cb, - 0x015e, 0xb284, 0x0600, 0x0118, 0x6817, 0x0000, 0x0010, 0x6817, - 0x8000, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823, 0x0800, - 0x6827, 0x0003, 0x0804, 0x3809, 0x7000, 0xa086, 0x0002, 0x1150, - 0x080c, 0x35c5, 0x0010, 0x080c, 0x3d52, 0x6008, 0xa084, 0xfbef, - 0x600a, 0x0020, 0x7000, 0xa086, 0x0003, 0x0da8, 0x7003, 0x0005, - 0xb284, 0x0600, 0x0118, 0x2001, 0x8ae0, 0x0010, 0x2001, 0x8b12, - 0x2068, 0x704e, 0xad80, 0x0009, 0x7046, 0x2200, 0x0002, 0x3831, - 0x340d, 0x340d, 0x343f, 0x340d, 0x3831, 0x080c, 0x243b, 0x7000, - 0xa086, 0x0002, 0x1150, 0x080c, 0x35c5, 0x0010, 0x080c, 0x3d52, - 0x6008, 0xa084, 0xfbef, 0x600a, 0x0020, 0x7000, 0xa086, 0x0003, - 0x0da8, 0x7003, 0x0005, 0xb284, 0x0600, 0x0118, 0x2001, 0x8ae0, - 0x0010, 0x2001, 0x8b12, 0x2068, 0x704e, 0xad80, 0x0009, 0x7046, - 0x2200, 0x0002, 0x343a, 0x3438, 0x3438, 0x343a, 0x3438, 0x343a, - 0x080c, 0x243b, 0x080c, 0x3846, 0x781b, 0x0082, 0x0005, 0x7000, - 0xa086, 0x0002, 0x1158, 0x70d4, 0xc0b5, 0x70d6, 0x2c00, 0x70ba, - 0x2d00, 0x70be, 0x0038, 0x080c, 0x3d52, 0x0020, 0x7000, 0xa086, - 0x0003, 0x0dc8, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, - 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x89c0, 0xb284, - 0x0600, 0x1118, 0xc2fd, 0x2069, 0x8ad0, 0x2d04, 0x2d08, 0x715e, - 0xa06d, 0x0128, 0x6814, 0xa206, 0x0500, 0x6800, 0x0cb8, 0x7003, - 0x0005, 0xd2fc, 0x1118, 0x2001, 0x8ae0, 0x0010, 0x2001, 0x8b12, - 0x2068, 0x704e, 0x0156, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, - 0x1f04, 0x347d, 0x015e, 0xad80, 0x0009, 0x7046, 0x6a16, 0x68b7, - 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x7e5a, 0x6920, - 0xa184, 0x0c00, 0x0904, 0x3507, 0x681b, 0x0005, 0xc1ad, 0xc1d4, - 0x6922, 0x080c, 0x383d, 0x0804, 0x3507, 0x7200, 0xa286, 0x0002, - 0x1158, 0x70d4, 0xc0b5, 0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be, - 0x0030, 0x080c, 0x3d52, 0x0018, 0xa286, 0x0003, 0x0dd0, 0x7003, - 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, - 0x001f, 0xa215, 0xb284, 0x0600, 0x1108, 0xc2fd, 0x79a8, 0x79a8, - 0xa18c, 0x00ff, 0x70cc, 0xa168, 0x2d04, 0x2d08, 0x715e, 0xa06d, - 0x0128, 0x6814, 0xa206, 0x0538, 0x6800, 0x0cb8, 0x7003, 0x0005, - 0xb284, 0x0600, 0x0118, 0x2001, 0x8ae0, 0x0010, 0x2001, 0x8b12, - 0x2068, 0x704e, 0x0156, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, - 0x1f04, 0x34dd, 0x015e, 0xb284, 0x0600, 0x0110, 0xc2fc, 0x0008, - 0xc2fd, 0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823, - 0x0800, 0x6827, 0x0003, 0x6eb4, 0x6920, 0xa184, 0x0c00, 0x0178, - 0xd0dc, 0x0118, 0x080c, 0x3843, 0x0050, 0x681b, 0x0005, 0xc1ad, - 0xc1d4, 0x6922, 0x080c, 0x383d, 0x707f, 0x0000, 0x0000, 0xa6ac, - 0x0060, 0x05c8, 0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105, 0x11c0, - 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa6b4, 0xb7ff, 0xa586, 0x0060, - 0x0550, 0xc6ed, 0x7e5a, 0x2009, 0x0083, 0xd69c, 0x0128, 0x2009, - 0x0082, 0x2019, 0x0000, 0x2320, 0x791a, 0x080c, 0x3fb8, 0x0418, - 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x01a0, 0x7bd2, - 0x7bda, 0x7cd6, 0x7cde, 0x68b0, 0xc6f4, 0x7e5a, 0x2011, 0x0083, - 0xd69c, 0x0128, 0x2011, 0x0082, 0x2019, 0x0000, 0x2320, 0x7a1a, - 0x080c, 0x3fe5, 0x0040, 0x7e5a, 0x2009, 0x0083, 0xd69c, 0x0110, - 0x2009, 0x0082, 0x791a, 0x68c0, 0x705a, 0x2d00, 0x704e, 0x68c4, - 0x2060, 0x71d4, 0xd1b4, 0x1904, 0x248c, 0x2300, 0xa405, 0x0904, - 0x248c, 0x70a4, 0xa086, 0x0001, 0x1904, 0x24ce, 0x0005, 0x6020, + 0x0006, 0x2011, 0x4602, 0x220c, 0xa102, 0x2012, 0x000e, 0x001e, + 0xa102, 0x0338, 0x6012, 0x1128, 0x2011, 0x4604, 0x2204, 0xc0a5, + 0x2012, 0x601b, 0x0000, 0xace0, 0x0010, 0x1f04, 0x2a13, 0x8421, + 0x1d00, 0x015e, 0x7063, 0x0000, 0x7003, 0x0000, 0x704b, 0x0000, + 0x0005, 0x0046, 0x2404, 0xa005, 0x01a8, 0x2068, 0x6800, 0x0006, + 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, + 0x681e, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x080c, 0x1da2, + 0x000e, 0x0c48, 0x004e, 0x2023, 0x0000, 0x0005, 0xa282, 0x0003, + 0x0310, 0x080c, 0x254c, 0x2300, 0x0002, 0x2a60, 0x2add, 0x2af7, + 0xa282, 0x0002, 0x0110, 0x080c, 0x254c, 0x7060, 0x7063, 0x0000, + 0x707f, 0x0000, 0x0022, 0x77d0, 0xc7c5, 0x77d2, 0x0002, 0x2a77, + 0x2a77, 0x2a79, 0x2ab1, 0x37d8, 0x2a77, 0x2ab1, 0x2a77, 0x080c, + 0x254c, 0x7770, 0x080c, 0x3a66, 0x7770, 0xa7bc, 0x8f00, 0x080c, + 0x3b6f, 0x6018, 0xa005, 0x0528, 0xd7fc, 0x1118, 0x2021, 0x8cc0, + 0x0010, 0x2021, 0x8dd0, 0x2009, 0x0005, 0x2011, 0x0010, 0x080c, + 0x2b11, 0x01b8, 0x0156, 0x20a9, 0x0101, 0xd7fc, 0x1118, 0x2021, + 0x8bc0, 0x0010, 0x2021, 0x8cd0, 0x0046, 0x2009, 0x0005, 0x2011, + 0x0010, 0x080c, 0x2b11, 0x004e, 0x0118, 0x8420, 0x1f04, 0x2a9c, + 0x015e, 0x8738, 0xa784, 0x001f, 0x1990, 0x0804, 0x25a0, 0x0804, + 0x25a0, 0x7770, 0x080c, 0x3b6f, 0x6018, 0xa005, 0x0520, 0xd7fc, + 0x1118, 0x2021, 0x8cc0, 0x0010, 0x2021, 0x8dd0, 0x2009, 0x0005, + 0x2011, 0x0020, 0x080c, 0x2b11, 0x01b0, 0x0156, 0x20a9, 0x0101, + 0xd7fc, 0x1118, 0x2021, 0x8bc0, 0x0010, 0x2021, 0x8cd0, 0x0046, + 0x2009, 0x0005, 0x2011, 0x0020, 0x04e1, 0x004e, 0x0118, 0x8420, + 0x1f04, 0x2acf, 0x015e, 0x0804, 0x25a0, 0x2200, 0x0002, 0x2ae2, + 0x2ae4, 0x2ae4, 0x080c, 0x254c, 0x2009, 0x0012, 0x7060, 0xa086, + 0x0002, 0x0110, 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0108, 0x691a, + 0x7063, 0x0000, 0x70d0, 0xc0c5, 0x70d2, 0x0804, 0x3be5, 0x2200, + 0x0002, 0x2afe, 0x2ae4, 0x2afc, 0x080c, 0x254c, 0x080c, 0x3f26, + 0x7000, 0xa086, 0x0002, 0x1904, 0x375d, 0x080c, 0x37be, 0x6008, + 0xa084, 0xfbef, 0x600a, 0x080c, 0x374f, 0x0904, 0x375d, 0x0804, + 0x25a0, 0x2404, 0xa005, 0x0590, 0x2068, 0x2d04, 0x0006, 0x6814, + 0xa706, 0x0118, 0x2d20, 0x000e, 0x0ca8, 0x000e, 0x2022, 0x691a, + 0x6817, 0x0000, 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, + 0x6820, 0xa084, 0x00ff, 0xa205, 0x6822, 0x080c, 0x1da2, 0x2021, + 0x4602, 0x241c, 0x8319, 0x2322, 0x6010, 0x8001, 0x6012, 0x1128, + 0x2021, 0x4604, 0x2404, 0xc0a5, 0x2022, 0x6008, 0xa084, 0xf9ef, + 0x600a, 0x080c, 0x269e, 0x080c, 0x37be, 0x0005, 0xa085, 0x0001, + 0x0ce0, 0x2300, 0x0002, 0x2b50, 0x2b4e, 0x2bcb, 0x080c, 0x254c, + 0x78e4, 0xa005, 0x17b0, 0x3208, 0xa18c, 0x0800, 0x0118, 0x0104, + 0x259d, 0x0010, 0x0304, 0x259d, 0x2008, 0xa084, 0x0030, 0x1110, + 0x0804, 0x322a, 0x78ec, 0xa084, 0x0003, 0x0dd0, 0x7884, 0xd0fc, + 0x1118, 0xa184, 0x0007, 0x0090, 0xa184, 0x0007, 0xa086, 0x0004, + 0x1118, 0x2001, 0x0000, 0x0050, 0xa184, 0x0007, 0xa086, 0x0005, + 0x0118, 0xa184, 0x0007, 0x0010, 0x2001, 0x0001, 0x0002, 0x2bae, + 0x2bb7, 0x2ba4, 0x2b87, 0x3c29, 0x3c29, 0x2b87, 0x2bc1, 0x080c, + 0x254c, 0x7000, 0xa086, 0x0004, 0x1190, 0x7060, 0xa086, 0x0002, + 0x1130, 0x2011, 0x0002, 0x2019, 0x0000, 0x0804, 0x2a56, 0x7060, + 0xa086, 0x0006, 0x0db0, 0x7060, 0xa086, 0x0004, 0x0d90, 0x79e4, + 0x2001, 0x0003, 0x0804, 0x2f18, 0x6818, 0xd0fc, 0x0110, 0x681b, + 0x001d, 0x080c, 0x3a3c, 0x781b, 0x006e, 0x0005, 0x6818, 0xd0fc, + 0x0110, 0x681b, 0x001d, 0x080c, 0x3a3c, 0x0804, 0x3c07, 0x6818, + 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3a3c, 0x781b, 0x00fa, + 0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3a3c, + 0x781b, 0x00cb, 0x0005, 0xa584, 0x000f, 0x11c0, 0x7000, 0x0002, + 0x25a0, 0x2bd8, 0x2bda, 0x375d, 0x375d, 0x375d, 0x2bd8, 0x2bd8, + 0x080c, 0x254c, 0x080c, 0x37be, 0x6008, 0xa084, 0xfbef, 0x600a, + 0x080c, 0x374f, 0x0904, 0x375d, 0x0804, 0x25a0, 0x78e4, 0xa005, + 0x1b04, 0x2b89, 0x3208, 0xa18c, 0x0800, 0x0118, 0x0104, 0x2b89, + 0x0010, 0x0304, 0x2b89, 0x2008, 0xa084, 0x0030, 0x1118, 0x781b, + 0x0068, 0x0005, 0x78ec, 0xa084, 0x0003, 0x0dc8, 0x7884, 0xd0fc, + 0x1118, 0xa184, 0x0007, 0x0090, 0xa184, 0x0007, 0xa086, 0x0004, + 0x1118, 0x2001, 0x0000, 0x0050, 0xa184, 0x0007, 0xa086, 0x0005, + 0x0118, 0xa184, 0x0007, 0x0010, 0x2001, 0x0001, 0x0002, 0x2c26, + 0x2c2a, 0x2c21, 0x2c1f, 0x3c29, 0x3c29, 0x2c1f, 0x3c23, 0x080c, + 0x254c, 0x080c, 0x3a42, 0x781b, 0x006e, 0x0005, 0x080c, 0x3a42, + 0x0804, 0x3c07, 0x080c, 0x3a42, 0x781b, 0x00fa, 0x0005, 0x080c, + 0x3a42, 0x781b, 0x00cb, 0x0005, 0x2300, 0x0002, 0x2c3b, 0x2c39, + 0x2c3d, 0x080c, 0x254c, 0x0804, 0x33e2, 0x681b, 0x0016, 0x78a3, + 0x0000, 0x79e4, 0xa184, 0x0030, 0x0904, 0x33e2, 0x78ec, 0xa084, + 0x0003, 0x0904, 0x33e2, 0xa184, 0x0100, 0x0d98, 0x7884, 0xd0fc, + 0x1118, 0xa184, 0x0007, 0x0090, 0xa184, 0x0007, 0xa086, 0x0004, + 0x1118, 0x2001, 0x0000, 0x0050, 0xa184, 0x0007, 0xa086, 0x0005, + 0x0118, 0xa184, 0x0007, 0x0010, 0x2001, 0x0001, 0x0002, 0x2c6f, + 0x2c2a, 0x2ba4, 0x3be5, 0x3c29, 0x3c29, 0x3be5, 0x3c23, 0x080c, + 0x3bf1, 0x0005, 0xa282, 0x0005, 0x0310, 0x080c, 0x254c, 0x7898, + 0x2040, 0x2300, 0x0002, 0x2c7e, 0x2ea8, 0x2eb2, 0x2200, 0x0002, + 0x2c9a, 0x2c87, 0x2c9a, 0x2c85, 0x2e8a, 0x080c, 0x254c, 0x789b, + 0x0018, 0x78a8, 0x2010, 0xa084, 0x00ff, 0xa082, 0x0020, 0x0a04, + 0x3a0b, 0xa08a, 0x0004, 0x1a04, 0x3a0b, 0x0002, 0x3a0b, 0x3a0b, + 0x3a0b, 0x39c1, 0x789b, 0x0018, 0x79a8, 0xa184, 0x0080, 0x0148, + 0x0804, 0x3a0b, 0x7000, 0xa005, 0x1dd8, 0x2011, 0x0004, 0x0804, + 0x3594, 0xa184, 0x00ff, 0xa08a, 0x0010, 0x1a04, 0x3a0b, 0x0002, + 0x2cc2, 0x2cc0, 0x2cd4, 0x2cd8, 0x2d86, 0x3a0b, 0x3a0b, 0x2d88, + 0x3a0b, 0x3a0b, 0x2e86, 0x2e86, 0x3a0b, 0x3a0b, 0x3a0b, 0x2e88, + 0x080c, 0x254c, 0xd6e4, 0x0140, 0x2001, 0x0300, 0x8000, 0x8000, + 0x783a, 0x781b, 0x00c7, 0x0005, 0x6818, 0xd0fc, 0x0118, 0x681b, + 0x001d, 0x0c90, 0x0804, 0x3be5, 0x681b, 0x001d, 0x0804, 0x3a36, + 0x6920, 0x6922, 0xa684, 0x1800, 0x1904, 0x2d29, 0x6820, 0xd084, + 0x1904, 0x2d31, 0x6818, 0xa086, 0x0008, 0x1110, 0x681b, 0x0000, + 0xd6d4, 0x0568, 0xd6bc, 0x0558, 0x7083, 0x0000, 0x6818, 0xa084, + 0x003f, 0xa08a, 0x000d, 0x0718, 0xa08a, 0x000c, 0x7182, 0x2001, + 0x000c, 0x800c, 0x7186, 0x789b, 0x0061, 0x78aa, 0x0156, 0x0136, + 0x0146, 0x0016, 0x3208, 0xa18c, 0x0600, 0x0118, 0x20a1, 0x022b, + 0x0010, 0x20a1, 0x012b, 0x001e, 0x789b, 0x0000, 0x8000, 0x80ac, + 0xad80, 0x000b, 0x2098, 0x53a6, 0x014e, 0x013e, 0x015e, 0x6038, + 0xa005, 0x1150, 0x681c, 0xa084, 0x000e, 0x0904, 0x3a36, 0x080c, + 0x3a48, 0x782b, 0x3008, 0x0010, 0x8001, 0x603a, 0x781b, 0x0071, + 0x0005, 0xd6e4, 0x0130, 0x781b, 0x0083, 0x0005, 0x781b, 0x0083, + 0x0005, 0xa684, 0x0060, 0x0dd0, 0xd6dc, 0x0dc0, 0xd6fc, 0x01a0, + 0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8, 0x78d0, 0x8007, 0xa084, + 0x007f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, + 0x6b94, 0x2200, 0xa303, 0x68ae, 0xd6f4, 0x0118, 0xc6f4, 0x7e5a, + 0x6eb6, 0x7000, 0xa086, 0x0003, 0x1148, 0x0006, 0x080c, 0x3f26, + 0x080c, 0x41d9, 0x000e, 0x781b, 0x0080, 0x0005, 0xa006, 0x080c, + 0x42b5, 0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0120, + 0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, 0x6ba6, + 0x7bd6, 0x7bde, 0x2300, 0xa405, 0x1130, 0xc6f5, 0x7e5a, 0x6eb6, + 0x781b, 0x0080, 0x0005, 0x781b, 0x0080, 0x2200, 0xa115, 0x1118, + 0x080c, 0x41d9, 0x0005, 0x080c, 0x4206, 0x0005, 0x080c, 0x254c, + 0x0804, 0x2e1c, 0x00c6, 0x7054, 0x2060, 0x6920, 0xa18c, 0xecff, + 0x6922, 0x6000, 0xa084, 0xcfdf, 0x6002, 0x080c, 0x38f4, 0xa006, + 0x2040, 0x2038, 0x080c, 0x399c, 0x0804, 0x2e10, 0x00c6, 0x7054, + 0x2060, 0x2c48, 0x7aa8, 0xa294, 0x00ff, 0xa286, 0x0004, 0x11d8, + 0x6920, 0xd1e4, 0x1170, 0x2039, 0x0000, 0x2041, 0x0000, 0x2031, + 0x0000, 0xa006, 0x2010, 0x080c, 0x38f7, 0x080c, 0x399c, 0x0804, + 0x2e10, 0xa18c, 0xecff, 0x6922, 0x6104, 0xa18c, 0xffdd, 0x6106, + 0x6000, 0xc0ac, 0x6002, 0xa286, 0x0003, 0x01d0, 0x6104, 0xa184, + 0x0010, 0x0548, 0x080c, 0x3b6b, 0x080c, 0x3977, 0x88ff, 0x0518, + 0x00ce, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, + 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, 0x781b, 0x0082, 0x0005, + 0x6920, 0xd1cc, 0x0130, 0xa18c, 0xfdff, 0x6922, 0x6000, 0xc0ec, + 0x6002, 0x2039, 0x0000, 0x2041, 0x0000, 0x2031, 0x0000, 0xa006, + 0x2010, 0x080c, 0x399c, 0xa286, 0x0001, 0x0158, 0x6104, 0xa184, + 0x0008, 0x01b0, 0x080c, 0x3b6b, 0x080c, 0x3895, 0x88ff, 0x1980, + 0x0078, 0x6920, 0xd1c4, 0x0130, 0xa18c, 0xfeff, 0x6922, 0x6000, + 0xc0e4, 0x6002, 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x38f7, + 0x00ce, 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005, 0x781b, + 0x0083, 0x0005, 0x0804, 0x3a32, 0x2808, 0x789b, 0x0080, 0x2019, + 0x0080, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x11b8, 0x2300, + 0xa102, 0xa086, 0x0001, 0x0904, 0x2d8a, 0x7ca8, 0xa4a4, 0x00ff, + 0xa480, 0x0002, 0xa300, 0x2018, 0xa102, 0x0a04, 0x2d9e, 0x0904, + 0x2d9e, 0x24a8, 0x7aa8, 0x1f04, 0x2e3a, 0x0c18, 0xa284, 0x00f0, + 0xa082, 0x0020, 0x06b8, 0x2200, 0xa082, 0x0021, 0x1698, 0x7aa8, + 0x8318, 0x8318, 0x2100, 0xa302, 0x0aa0, 0xa286, 0x0023, 0x0950, + 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, 0xa684, 0xfff1, 0xc0a5, + 0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a, 0x78a0, 0x8001, 0x0904, + 0x2e10, 0x20a8, 0x7998, 0x789b, 0x0060, 0x78aa, 0x2011, 0x0080, + 0x799a, 0x78a8, 0x7998, 0x7a9a, 0x78aa, 0x7a98, 0x1f04, 0x2e68, + 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, 0x781b, + 0x0082, 0x0005, 0x8318, 0x2100, 0xa302, 0x0a04, 0x2e21, 0xa284, + 0x0080, 0x1904, 0x3a36, 0x78a0, 0xa005, 0x08c8, 0x0804, 0x3a36, + 0x0804, 0x3a0b, 0x7054, 0xa04d, 0x789b, 0x0018, 0x78a8, 0xa084, + 0x00ff, 0xa08e, 0x0001, 0x0110, 0x080c, 0x254c, 0x7aa8, 0xa294, + 0x00ff, 0x784b, 0x0008, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0005, + 0x1a04, 0x3a0b, 0x0002, 0x3a0b, 0x380c, 0x3a0b, 0x3927, 0x3d31, + 0xa282, 0x0000, 0x1110, 0x080c, 0x254c, 0x080c, 0x3a3c, 0x781b, + 0x0082, 0x0005, 0xa282, 0x0003, 0x1110, 0x080c, 0x254c, 0xd4fc, + 0x11d0, 0x7060, 0xa005, 0x0110, 0x080c, 0x254c, 0x6f14, 0x7772, + 0xa7bc, 0x8f00, 0x080c, 0x3b6f, 0x6008, 0xa085, 0x0021, 0x600a, + 0x8738, 0xa784, 0x001f, 0x1db0, 0x080c, 0x3a3f, 0x7063, 0x0002, + 0x701f, 0x0009, 0x0010, 0x080c, 0x3a4b, 0x781b, 0x0082, 0x0005, + 0xa282, 0x0004, 0x0310, 0x080c, 0x254c, 0x2300, 0x0002, 0x2ee2, + 0x3078, 0x30b4, 0xa286, 0x0003, 0x0598, 0x7200, 0x7cd8, 0x7ddc, + 0x7fd0, 0x71d0, 0xd1b4, 0x0528, 0xd1bc, 0x1518, 0x2001, 0x4601, + 0x2004, 0xd0c4, 0x11f0, 0x7868, 0xa084, 0x00ff, 0x11d0, 0xa282, + 0x0002, 0x12b8, 0x00d6, 0x783b, 0x8300, 0x781b, 0x0059, 0x70b8, + 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, + 0x78da, 0xc1b4, 0x71d2, 0x7003, 0x0030, 0x00de, 0x2001, 0x0000, + 0x0058, 0x783b, 0x1300, 0x781b, 0x0057, 0x2001, 0x0000, 0x0020, + 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x7046, 0x68a0, 0xd0ec, 0x0118, + 0x6008, 0xc08d, 0x600a, 0xa284, 0x000f, 0x0002, 0x3059, 0x2f33, + 0x2f30, 0x3184, 0x320f, 0x25a0, 0x2f2e, 0x2f2e, 0x080c, 0x254c, + 0x6008, 0xc0d4, 0x600a, 0xd6e4, 0x0120, 0x7044, 0xa086, 0x0014, + 0x11e8, 0x080c, 0x3f26, 0x2009, 0x0000, 0x6818, 0xd0fc, 0x0108, + 0x7044, 0xa086, 0x0014, 0x0168, 0x6818, 0xa086, 0x0008, 0x1904, + 0x301b, 0x7858, 0xd09c, 0x0904, 0x301b, 0x6820, 0xd0ac, 0x0904, + 0x301b, 0x681b, 0x0014, 0x2009, 0x0002, 0x04a8, 0x7868, 0xa08c, + 0x00ff, 0x0588, 0xa186, 0x0008, 0x1158, 0x6008, 0xc0a4, 0x600a, + 0x080c, 0x374f, 0x0540, 0x080c, 0x37be, 0x080c, 0x3f26, 0x0060, + 0xa186, 0x0028, 0x1500, 0x6018, 0xa005, 0x0d78, 0x8001, 0x0d68, + 0x8001, 0x0d58, 0x601e, 0x0c48, 0x6820, 0xd084, 0x0904, 0x25a0, + 0xc084, 0x6822, 0x080c, 0x2693, 0x7058, 0x00c6, 0x2060, 0x6800, + 0x6002, 0x00ce, 0x6004, 0x6802, 0xa005, 0x2d00, 0x1108, 0x6002, + 0x6006, 0x0804, 0x25a0, 0x0016, 0x81ff, 0x15f0, 0x7000, 0xa086, + 0x0030, 0x05d0, 0x71d0, 0xd1bc, 0x15b8, 0xd1b4, 0x11e8, 0x705c, + 0xa005, 0x1590, 0x70a0, 0xa086, 0x0001, 0x0570, 0x7003, 0x0000, + 0x0046, 0x0056, 0x0076, 0x0066, 0x00c6, 0x00d6, 0x080c, 0x25c5, + 0x00de, 0x00ce, 0x006e, 0x007e, 0x005e, 0x004e, 0x71d0, 0xd1b4, + 0x11d8, 0x7003, 0x0040, 0x00c0, 0x080c, 0x3c33, 0x11a8, 0x781b, + 0x0068, 0x00d6, 0x70b8, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, + 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d2, 0x7003, 0x0030, + 0x7808, 0xc08d, 0x780a, 0x00de, 0x080c, 0x30dc, 0x001e, 0x81ff, + 0x0904, 0x301b, 0xa684, 0xdf00, 0x681e, 0x682b, 0x0000, 0x6f14, + 0xa186, 0x0002, 0x1904, 0x301c, 0x6818, 0xa086, 0x0014, 0x1130, + 0x2008, 0xd6e4, 0x0118, 0x7868, 0xa08c, 0x00ff, 0x080c, 0x3a55, + 0x080c, 0x269e, 0x6820, 0xd0dc, 0x1578, 0x8717, 0xa294, 0x000f, + 0x8213, 0x8213, 0x8213, 0xb284, 0x0600, 0x0118, 0xa290, 0x4ac0, + 0x0010, 0xa290, 0x4b40, 0xa290, 0x0000, 0x221c, 0xd3c4, 0x0170, + 0x6820, 0xd0e4, 0x0128, 0xa084, 0xefff, 0x6822, 0xc3ac, 0x2312, + 0x8210, 0x2204, 0xa085, 0x0038, 0x2012, 0x8211, 0xd3d4, 0x0138, + 0x68a0, 0xd0c4, 0x1120, 0x080c, 0x3144, 0x0804, 0x25a0, 0x6008, + 0xc08d, 0x600a, 0x0008, 0x692a, 0x6916, 0x6818, 0xd0fc, 0x0110, + 0x7044, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x6410, 0x84ff, 0x0168, + 0x2009, 0x4602, 0x2104, 0x8001, 0x200a, 0x8421, 0x6412, 0x1128, + 0x2021, 0x4604, 0x2404, 0xc0a5, 0x2022, 0x6018, 0xa005, 0x0118, + 0x8001, 0x601a, 0x1118, 0x6008, 0xc0a4, 0x600a, 0x6820, 0xd084, + 0x1130, 0x6800, 0xa005, 0x1108, 0x6002, 0x6006, 0x0020, 0x7058, + 0x2060, 0x6800, 0x6002, 0x2061, 0x4600, 0x6887, 0x0103, 0x2d08, + 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0110, 0x2d02, 0x0008, + 0x616e, 0x7200, 0xa286, 0x0030, 0x0158, 0xa286, 0x0040, 0x1904, + 0x25a0, 0x7003, 0x0002, 0x7048, 0x2068, 0x68c4, 0x2060, 0x0005, + 0x7003, 0x0002, 0x70b8, 0xa06d, 0x68bc, 0x703e, 0x70b4, 0xa065, + 0x68c0, 0x7056, 0x2d00, 0x704a, 0xad80, 0x0009, 0x7042, 0x0005, + 0xa282, 0x0004, 0x0210, 0x080c, 0x254c, 0x2200, 0x0002, 0x3083, + 0x3092, 0x309e, 0x3092, 0xa586, 0x1300, 0x0160, 0xa586, 0x8300, + 0x1d90, 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, + 0xfbef, 0x600a, 0x7000, 0xa086, 0x0005, 0x0128, 0x080c, 0x3a3c, + 0x781b, 0x0082, 0x0005, 0x781b, 0x0083, 0x0005, 0x7890, 0x8007, + 0x8001, 0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, + 0x00ff, 0xa186, 0x0003, 0x0128, 0xa186, 0x0000, 0x0110, 0x0804, + 0x3a0b, 0x781b, 0x0083, 0x0005, 0x6820, 0xc095, 0x6822, 0x82ff, + 0x1118, 0x080c, 0x3a3c, 0x0030, 0x8211, 0x0110, 0x080c, 0x254c, + 0x080c, 0x3a4b, 0x781b, 0x0082, 0x0005, 0x080c, 0x3c46, 0x7830, + 0xa084, 0x00c0, 0x1170, 0x0016, 0x3208, 0xa18c, 0x0800, 0x001e, + 0x0118, 0x0104, 0x30d9, 0x0010, 0x0304, 0x30d9, 0x791a, 0xa006, + 0x0005, 0xa085, 0x0001, 0x0005, 0xa684, 0x0060, 0x1130, 0x682f, + 0x0000, 0x6833, 0x0000, 0x0804, 0x3143, 0xd6dc, 0x1198, 0x68b4, + 0xd0dc, 0x1180, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x7044, 0xa005, + 0x1130, 0x2200, 0xa105, 0x0904, 0x3f26, 0x7047, 0x0015, 0x0804, + 0x3f26, 0x0005, 0xd6ac, 0x01f0, 0xd6f4, 0x0130, 0x682f, 0x0000, + 0x6833, 0x0000, 0x0804, 0x3f26, 0x68b4, 0xa084, 0x4000, 0xa635, + 0xd6f4, 0x1da0, 0x7044, 0xa005, 0x1110, 0x7047, 0x0015, 0xd6dc, + 0x1128, 0x68b4, 0xd0dc, 0x0110, 0x6ca8, 0x6da4, 0x6c2e, 0x6d32, + 0x0804, 0x3f26, 0xd6f4, 0x0130, 0x682f, 0x0000, 0x6833, 0x0000, + 0x0804, 0x3f26, 0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4, 0x1da0, + 0x7044, 0xa005, 0x1110, 0x7047, 0x0015, 0x2408, 0x2510, 0x2700, + 0x8007, 0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x692e, 0x6a32, + 0x2100, 0xa205, 0x1110, 0x0804, 0x3f26, 0x7000, 0xa086, 0x0006, + 0x0110, 0x0804, 0x3f26, 0x0005, 0x6946, 0x6008, 0xc0cd, 0xd3cc, + 0x0108, 0xc08d, 0x600a, 0x6818, 0x683a, 0x681b, 0x0006, 0x688f, + 0x0000, 0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f, + 0x0003, 0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b, + 0x0020, 0x7000, 0x0002, 0x25a0, 0x3173, 0x316d, 0x316b, 0x316b, + 0x316b, 0x316b, 0x316b, 0x080c, 0x254c, 0x6820, 0xd084, 0x1118, + 0x080c, 0x37a4, 0x0030, 0x7058, 0x2c50, 0x2060, 0x6800, 0x6002, + 0x2a60, 0xaea0, 0x0017, 0x2404, 0xa005, 0x0110, 0x2020, 0x0cd8, + 0x2d22, 0x206b, 0x0000, 0x0005, 0x080c, 0x37aa, 0x080c, 0x37be, + 0x6008, 0xc0cc, 0x600a, 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14, + 0x6938, 0x691a, 0x6944, 0x6916, 0x2009, 0x0000, 0xae86, 0x4640, + 0x0110, 0x2009, 0x0001, 0x080c, 0x42ec, 0xd6dc, 0x01c8, 0x691c, + 0xc1ed, 0x691e, 0x6828, 0xa082, 0x000e, 0x0290, 0x6848, 0xa084, + 0x000f, 0xa086, 0x000b, 0x1160, 0x685c, 0xa086, 0x0047, 0x1140, + 0x2001, 0x4601, 0x2004, 0xd0ac, 0x1118, 0x2700, 0x080c, 0x2475, + 0x6818, 0xd0fc, 0x0140, 0x681b, 0x0000, 0x7868, 0xa08c, 0x00ff, + 0x0110, 0x681b, 0x001e, 0xaea0, 0x0017, 0x6800, 0x2022, 0x6a3c, + 0x6940, 0x6a32, 0x692e, 0x68c0, 0x2060, 0x6000, 0xd0a4, 0x0580, + 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x00d6, 0x00f6, + 0x0156, 0x0146, 0x2079, 0x4600, 0x080c, 0x1b93, 0x014e, 0x015e, + 0x00fe, 0x70c8, 0x2010, 0x2009, 0x0101, 0x0026, 0x2204, 0xa06d, + 0x0140, 0x6814, 0xa706, 0x0110, 0x6800, 0x0cc8, 0x6820, 0xc0d5, + 0x6822, 0x002e, 0x8210, 0x8109, 0x1d80, 0x00de, 0x7063, 0x0003, + 0x707b, 0x0000, 0x7772, 0x707f, 0x000f, 0x71d0, 0xc1c4, 0x71d2, + 0x6818, 0xa086, 0x0002, 0x1138, 0x6817, 0x0000, 0x682b, 0x0000, + 0x681c, 0xc0ec, 0x681e, 0x080c, 0x1da2, 0x0804, 0x25a0, 0x7cd8, + 0x7ddc, 0x7fd0, 0x080c, 0x30dc, 0x682b, 0x0000, 0x789b, 0x000e, + 0x6f14, 0x080c, 0x3c4a, 0xa08c, 0x00ff, 0x6916, 0x6818, 0xd0fc, + 0x0110, 0x7044, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x7063, 0x0000, + 0x0804, 0x25a0, 0x7000, 0xa005, 0x1110, 0x0804, 0x25a0, 0xa006, + 0x080c, 0x3f26, 0x6920, 0xd1ac, 0x1110, 0x681b, 0x0014, 0xa68c, + 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff, 0x6822, + 0x7000, 0x0002, 0x25a0, 0x324c, 0x324c, 0x324f, 0x324f, 0x324f, + 0x324a, 0x324a, 0x080c, 0x254c, 0x6818, 0x0804, 0x2f18, 0x6008, + 0xc0a4, 0x600a, 0x6817, 0x0000, 0x0804, 0x3772, 0x2300, 0x0002, + 0x325b, 0x325d, 0x32ab, 0x080c, 0x254c, 0xd6fc, 0x1904, 0x2d38, + 0x7000, 0xa00d, 0x0002, 0x25a0, 0x326d, 0x326d, 0x3297, 0x326d, + 0x32a8, 0x326b, 0x326b, 0x080c, 0x254c, 0xa684, 0x0060, 0x0538, + 0xa086, 0x0060, 0x1510, 0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a, 0x6eb6, + 0x681c, 0xc0ac, 0x681e, 0xa186, 0x0002, 0x0148, 0x080c, 0x3f26, + 0x69ac, 0x68b0, 0xa115, 0x0118, 0x080c, 0x4206, 0x0010, 0x080c, + 0x41d9, 0x781b, 0x0083, 0x71d0, 0xd1b4, 0x1904, 0x259d, 0x70a0, + 0xa086, 0x0001, 0x1904, 0x25e1, 0x0005, 0xd6ec, 0x09f0, 0x6818, + 0xd0fc, 0x0170, 0xd6f4, 0x1130, 0x681b, 0x0015, 0x781b, 0x0083, + 0x0804, 0x259d, 0x681b, 0x0007, 0x682f, 0x0000, 0x6833, 0x0000, + 0x080c, 0x3bf1, 0x0005, 0x080c, 0x254c, 0x2300, 0x0002, 0x32b4, + 0x32d6, 0x332e, 0x080c, 0x254c, 0x7000, 0x0002, 0x32be, 0x32c0, + 0x32c7, 0x32be, 0x32be, 0x32be, 0x32be, 0x32be, 0x080c, 0x254c, + 0x69ac, 0x68b0, 0xa115, 0x0118, 0x080c, 0x4206, 0x0010, 0x080c, + 0x41d9, 0x681c, 0xc0b4, 0x681e, 0x70d0, 0xd0b4, 0x1904, 0x259d, + 0x70a0, 0xa086, 0x0001, 0x1904, 0x25e1, 0x0005, 0xd6fc, 0x1904, + 0x331e, 0x7000, 0xa00d, 0x0002, 0x25a0, 0x32ec, 0x32e6, 0x3316, + 0x32ec, 0x331b, 0x32e4, 0x32e4, 0x080c, 0x254c, 0x6894, 0x78d6, + 0x78de, 0x6898, 0x78d2, 0x78da, 0xa684, 0x0060, 0x0538, 0xa086, + 0x0060, 0x1510, 0xa6b4, 0xbfbf, 0xc6ed, 0x7e5a, 0x6eb6, 0xa186, + 0x0002, 0x0148, 0x080c, 0x3f26, 0x69ac, 0x68b0, 0xa115, 0x0118, + 0x080c, 0x4206, 0x0010, 0x080c, 0x41d9, 0x781b, 0x0083, 0x681c, + 0xc0b4, 0x681e, 0x71d0, 0xd1b4, 0x1904, 0x259d, 0x70a0, 0xa086, + 0x0001, 0x1904, 0x25e1, 0x0005, 0xd6ec, 0x09f0, 0x6818, 0xd0fc, + 0x0110, 0x681b, 0x0007, 0x781b, 0x00fb, 0x0005, 0xc6fc, 0x7e5a, + 0x7adc, 0x79d8, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, + 0xa303, 0x68ae, 0x79d2, 0x781b, 0x0083, 0x0005, 0xd6dc, 0x0130, + 0x782b, 0x3009, 0x781b, 0x0083, 0x0804, 0x259d, 0x7884, 0xc0ac, + 0x7886, 0x78e4, 0xa084, 0x0008, 0x1150, 0xa484, 0x0200, 0x0108, + 0xc6f5, 0xc6dd, 0x7e5a, 0x781b, 0x0083, 0x0804, 0x259d, 0x6820, + 0xc095, 0x6822, 0x080c, 0x3bdc, 0xc6dd, 0x080c, 0x3a3c, 0x781b, + 0x0082, 0x0804, 0x259d, 0x2300, 0x0002, 0x3358, 0x335a, 0x335c, + 0x080c, 0x254c, 0x0804, 0x3a36, 0x7d98, 0xd6d4, 0x15a8, 0x79e4, + 0xd1ac, 0x0130, 0x78ec, 0xa084, 0x0003, 0x0110, 0x782b, 0x3009, + 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x7d9a, + 0x79e4, 0xd1ac, 0x0120, 0x78ec, 0xa084, 0x0003, 0x1120, 0x2001, + 0x0014, 0x0804, 0x2f18, 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007, + 0x0090, 0xa184, 0x0007, 0xa086, 0x0004, 0x1118, 0x2001, 0x0000, + 0x0050, 0xa184, 0x0007, 0xa086, 0x0005, 0x0118, 0xa184, 0x0007, + 0x0010, 0x2001, 0x0001, 0x04c2, 0x7a90, 0xa294, 0x0007, 0x789b, + 0x0060, 0x79a8, 0x81ff, 0x0568, 0x789b, 0x0080, 0x7ba8, 0xa384, + 0x0001, 0x11d0, 0x7ba8, 0x7ba8, 0xa386, 0x0004, 0x1118, 0x2009, + 0xffdf, 0x0058, 0xa386, 0x0001, 0x1118, 0x2009, 0xfff7, 0x0028, + 0xa386, 0x0003, 0x1148, 0x2009, 0xffef, 0x00c6, 0x7054, 0x2060, + 0x6004, 0xa104, 0x6006, 0x00ce, 0x789b, 0x0060, 0x78ab, 0x0000, + 0xa684, 0xfffb, 0x785a, 0x782b, 0x3009, 0x6920, 0xa18c, 0xecff, + 0x6922, 0x7d9a, 0x0804, 0x3be5, 0x2bae, 0x2bb7, 0x33d6, 0x33dc, + 0x33d4, 0x33d4, 0x3be5, 0x3be5, 0x080c, 0x254c, 0x6920, 0xa18c, + 0xfcff, 0x6922, 0x0804, 0x3beb, 0x6920, 0xa18c, 0xfcff, 0x6922, + 0x0804, 0x3be5, 0x79e4, 0xa184, 0x0030, 0x0120, 0x78ec, 0xa084, + 0x0003, 0x1570, 0x7000, 0xa086, 0x0004, 0x1190, 0x7060, 0xa086, + 0x0002, 0x1130, 0x2011, 0x0002, 0x2019, 0x0000, 0x0804, 0x2a56, + 0x7060, 0xa086, 0x0006, 0x0db0, 0x7060, 0xa086, 0x0004, 0x0d90, + 0x7000, 0xa086, 0x0000, 0x0904, 0x259d, 0x6920, 0xa184, 0x0420, + 0x0128, 0xc1d4, 0x6922, 0x6818, 0x0804, 0x2f18, 0x6818, 0xa08e, + 0x0002, 0x0120, 0xc0fd, 0x681a, 0x2001, 0x0014, 0x0804, 0x2f18, + 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007, 0x0090, 0xa184, 0x0007, + 0xa086, 0x0004, 0x1118, 0x2001, 0x0000, 0x0050, 0xa184, 0x0007, + 0xa086, 0x0005, 0x0118, 0xa184, 0x0007, 0x0010, 0x2001, 0x0001, + 0x0002, 0x3be5, 0x3be5, 0x3439, 0x3be5, 0x3c29, 0x3c29, 0x3be5, + 0x3be5, 0xd6bc, 0x0570, 0x7180, 0x81ff, 0x0558, 0xa182, 0x000d, + 0x1318, 0x7083, 0x0000, 0x0028, 0xa182, 0x000c, 0x7082, 0x2009, + 0x000c, 0x789b, 0x0061, 0x79aa, 0x0156, 0x0136, 0x0146, 0x7084, + 0x8114, 0xa210, 0x7286, 0xa080, 0x000b, 0xad00, 0x2098, 0xb284, + 0x0600, 0x0118, 0x20a1, 0x022b, 0x0010, 0x20a1, 0x012b, 0x789b, + 0x0000, 0x8108, 0x81ac, 0x53a6, 0x014e, 0x013e, 0x015e, 0x0804, + 0x3beb, 0xd6d4, 0x1904, 0x34ac, 0x6820, 0xd084, 0x0904, 0x3beb, + 0xa68c, 0x0060, 0xa684, 0x0060, 0x0120, 0xa086, 0x0060, 0x1108, + 0xc1f5, 0xc194, 0x795a, 0x69b6, 0x789b, 0x0060, 0x78ab, 0x0000, + 0x789b, 0x0061, 0x6818, 0xc0fd, 0x681a, 0x78aa, 0x8008, 0x810c, + 0x0904, 0x37d3, 0xa18c, 0x00f8, 0x1904, 0x37d3, 0x0156, 0x0136, + 0x0146, 0x0016, 0x20a1, 0x012b, 0x3208, 0xa18c, 0x0600, 0x0110, + 0x20a1, 0x022b, 0x001e, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, + 0x000b, 0x2098, 0x53a6, 0x014e, 0x013e, 0x015e, 0x6814, 0xc0fc, + 0x8007, 0x7882, 0x0804, 0x3beb, 0x6818, 0xd0fc, 0x0110, 0x681b, + 0x0008, 0x080c, 0x3a3c, 0x781b, 0x00ed, 0x0005, 0x2300, 0x0002, + 0x34bd, 0x357a, 0x34bb, 0x080c, 0x254c, 0x7cd8, 0x7ddc, 0x7fd0, + 0x82ff, 0x1528, 0x7200, 0xa286, 0x0003, 0x0904, 0x2ee6, 0x71d0, + 0xd1bc, 0x11f8, 0xd1b4, 0x01e8, 0x2001, 0x4601, 0x2004, 0xd0c4, + 0x11c0, 0x00d6, 0x783b, 0x8800, 0x781b, 0x0059, 0x70b8, 0xa06d, + 0x68b4, 0xc0a5, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, + 0x78da, 0xc1b4, 0x71d2, 0x7003, 0x0030, 0x00de, 0x0030, 0x7200, + 0x0020, 0x783b, 0x1800, 0x781b, 0x0057, 0xa284, 0x000f, 0x0002, + 0x3565, 0x3522, 0x34fa, 0x2f15, 0x34f8, 0x3565, 0x34f8, 0x34f8, + 0x080c, 0x254c, 0x681c, 0xd0ec, 0x0118, 0x6008, 0xc08d, 0x600a, + 0x6920, 0xc185, 0x6922, 0x6800, 0x6006, 0xa005, 0x1108, 0x6002, + 0x6008, 0xc0d4, 0x600a, 0x681c, 0xa084, 0x000e, 0x1120, 0x71c8, + 0xa188, 0x0100, 0x0028, 0x7030, 0x68ba, 0x713c, 0x70c8, 0xa108, + 0x2104, 0x6802, 0x2d0a, 0x715a, 0xd6dc, 0x1120, 0xc6fc, 0x6eb6, + 0x0804, 0x3565, 0x6eb6, 0xa684, 0x0060, 0x1120, 0xa684, 0x7fff, + 0x68b6, 0x04d8, 0xd6dc, 0x1150, 0xa684, 0x7fff, 0x68b6, 0x6894, + 0x68a6, 0x6898, 0x68aa, 0x080c, 0x3f26, 0x0478, 0xd6ac, 0x0140, + 0xa006, 0x080c, 0x3f26, 0x2408, 0x2510, 0x69aa, 0x6aa6, 0x0068, + 0x2408, 0x2510, 0x2700, 0x8007, 0xa084, 0x007f, 0xa108, 0xa291, + 0x0000, 0x69aa, 0x6aa6, 0x080c, 0x3f26, 0xd6fc, 0x01b0, 0xa684, + 0x7fff, 0x68b6, 0x2510, 0x2408, 0xd6ac, 0x1138, 0x2700, 0x8007, + 0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, + 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x7000, 0xa086, 0x0030, + 0x1904, 0x25a0, 0x7003, 0x0002, 0x70b8, 0xa06d, 0x68bc, 0x703e, + 0x70b4, 0xa065, 0x68c0, 0x7056, 0x2d00, 0x704a, 0xad80, 0x0009, + 0x7042, 0x0005, 0xa586, 0x8800, 0x1148, 0x7003, 0x0000, 0x6018, + 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef, 0x600a, 0x0804, 0x3a36, + 0x7043, 0x0000, 0xa282, 0x0006, 0x0310, 0x080c, 0x254c, 0x2300, + 0x0002, 0x3594, 0x35a5, 0x35af, 0x2200, 0x0002, 0x359c, 0x3a36, + 0x359e, 0x359c, 0x35e0, 0x362e, 0x080c, 0x254c, 0x7a80, 0xa294, + 0x0f00, 0x080c, 0x3682, 0x0804, 0x3a0b, 0x00c1, 0x0002, 0x3a36, + 0x35ad, 0x35ad, 0x35e0, 0x35ad, 0x3a36, 0x080c, 0x254c, 0x0071, + 0x0002, 0x35b9, 0x35b7, 0x35b7, 0x35b9, 0x35b7, 0x35b9, 0x080c, + 0x254c, 0x080c, 0x3a4b, 0x781b, 0x0082, 0x0005, 0x7000, 0xa086, + 0x0002, 0x1150, 0x080c, 0x37be, 0x0010, 0x080c, 0x3f26, 0x6008, + 0xa084, 0xfbef, 0x600a, 0x0020, 0x7000, 0xa086, 0x0003, 0x0da8, + 0x7003, 0x0005, 0x2001, 0x8de0, 0xae8e, 0x4640, 0x0110, 0x2001, + 0x8e12, 0x2068, 0x704a, 0xad80, 0x0009, 0x7042, 0x2200, 0x0005, + 0x7000, 0xa086, 0x0002, 0x1158, 0x70d0, 0xc0b5, 0x70d2, 0x2c00, + 0x70b6, 0x2d00, 0x70ba, 0x0038, 0x080c, 0x3f26, 0x0020, 0x7000, + 0xa086, 0x0003, 0x0dc8, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, + 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x8cc0, + 0xb284, 0x0600, 0x1118, 0xc2fd, 0x2069, 0x8dd0, 0x2d04, 0x2d08, + 0x715a, 0xa06d, 0x0128, 0x6814, 0xa206, 0x0120, 0x6800, 0x0cb8, + 0x080c, 0x3682, 0x6eb4, 0x7e5a, 0x6920, 0xa184, 0x0c00, 0x0904, + 0x36a8, 0x7060, 0xa086, 0x0006, 0x1128, 0x7070, 0xa206, 0x1110, + 0x7062, 0x707a, 0x681b, 0x0005, 0xc1ad, 0x681b, 0x0005, 0xc1ad, + 0xc1d4, 0x6922, 0x080c, 0x3a42, 0x0804, 0x36a8, 0x7200, 0xa286, + 0x0002, 0x1158, 0x70d0, 0xc0b5, 0x70d2, 0x2c00, 0x70b6, 0x2d00, + 0x70ba, 0x0030, 0x080c, 0x3f26, 0x0018, 0xa286, 0x0003, 0x0dd0, + 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, + 0xa484, 0x001f, 0xa215, 0xae86, 0x4640, 0x0108, 0xc2fd, 0x79a8, + 0x79a8, 0xa18c, 0x00ff, 0x2118, 0x70c8, 0xa168, 0x2d04, 0x2d08, + 0x715a, 0xa06d, 0x0128, 0x6814, 0xa206, 0x0118, 0x6800, 0x0cb8, + 0x0409, 0x6eb4, 0x6920, 0xa184, 0x0c00, 0x0904, 0x36a8, 0xd0dc, + 0x0178, 0x7060, 0xa086, 0x0004, 0x1140, 0x7070, 0xa206, 0x1128, + 0x7074, 0xa306, 0x1110, 0x7062, 0x707a, 0x080c, 0x3a48, 0x0480, + 0x681b, 0x0005, 0xc1ad, 0xc1d4, 0x6922, 0x080c, 0x3a42, 0x707b, + 0x0000, 0x0430, 0x7003, 0x0005, 0xb284, 0x0600, 0x0118, 0x2001, + 0x8de0, 0x0010, 0x2001, 0x8e12, 0x2068, 0x704a, 0x0156, 0x20a9, + 0x0032, 0x2003, 0x0000, 0x8000, 0x1f04, 0x3691, 0x015e, 0xb284, + 0x0600, 0x0110, 0xc2fc, 0x0008, 0xc2fd, 0x6a16, 0xad80, 0x0009, + 0x7042, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x0005, + 0xc6ec, 0xa6ac, 0x0060, 0x0904, 0x36ef, 0x6b98, 0x6c94, 0x69ac, + 0x68b0, 0xa105, 0x11e0, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa586, + 0x0060, 0x05c8, 0xd6f4, 0x1108, 0xc6ed, 0xa6b4, 0xb7ff, 0x7e5a, + 0x2009, 0x0083, 0xd69c, 0x0128, 0x2009, 0x0082, 0x2019, 0x0000, + 0x2320, 0x791a, 0xd6ec, 0x0588, 0x080c, 0x41d9, 0x0470, 0x68b0, + 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x01f8, 0x7bd2, 0x7bda, + 0x7cd6, 0x7cde, 0x68b0, 0xd6f4, 0x1108, 0xc6ed, 0xc6f4, 0x7e5a, + 0x2011, 0x0083, 0xd69c, 0x0128, 0x2011, 0x0082, 0x2019, 0x0000, + 0x2320, 0x7a1a, 0xd6ec, 0x0188, 0x080c, 0x4206, 0x0070, 0x2019, + 0x0000, 0x2320, 0x0010, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x0083, + 0xd69c, 0x0110, 0x2009, 0x0082, 0x791a, 0x68c0, 0x7056, 0x2d00, + 0x704a, 0x68c4, 0x2060, 0x71d0, 0x2001, 0x4601, 0x2004, 0xd0c4, + 0x15c8, 0x70d4, 0xa02d, 0x01b8, 0xd1bc, 0x0548, 0x7a80, 0xa294, + 0x0f00, 0x70d8, 0xa206, 0x0118, 0x78e0, 0xa504, 0x1558, 0x70d6, + 0xc1bc, 0x71d2, 0x0438, 0x2031, 0x0001, 0x852c, 0x0218, 0x8633, + 0x8210, 0x0cd8, 0x0005, 0x7de0, 0xa594, 0xff00, 0x0130, 0x2011, + 0x0008, 0x852f, 0x0c81, 0x8637, 0x0008, 0x0c69, 0x8217, 0x7880, + 0xa084, 0x0f00, 0xa206, 0x0170, 0x72da, 0x76d6, 0x0058, 0x7a80, + 0xa294, 0x0f00, 0x70d8, 0xa236, 0x0dc0, 0x78e0, 0xa534, 0x0da8, + 0xc1bd, 0x71d2, 0xd1b4, 0x1904, 0x259d, 0x2300, 0xa405, 0x0904, + 0x259d, 0x70a0, 0xa086, 0x0001, 0x1904, 0x25e1, 0x0005, 0x6020, 0xa005, 0x0150, 0x8001, 0x6022, 0x6008, 0xa085, 0x0008, 0x600a, - 0x700f, 0x0100, 0x702c, 0x6026, 0x0005, 0xa006, 0x080c, 0x3d52, + 0x700f, 0x0100, 0x702c, 0x6026, 0x0005, 0xa006, 0x080c, 0x3f26, + 0x7000, 0xa086, 0x0002, 0x0120, 0x7060, 0xa086, 0x0005, 0x1150, 0x682b, 0x0000, 0x6817, 0x0000, 0x681b, 0x0001, 0x6823, 0x0040, - 0x681f, 0x0100, 0x7000, 0xa084, 0x000f, 0x0002, 0x248f, 0x358b, - 0x3588, 0x35a7, 0x3594, 0x248f, 0x3586, 0x3586, 0x080c, 0x243b, - 0x0441, 0x0409, 0x0028, 0x0429, 0x705c, 0x2060, 0x6800, 0x6002, - 0x080c, 0x1d3d, 0x0804, 0x248f, 0x7064, 0x7067, 0x0000, 0x7083, - 0x0000, 0x0002, 0x35a3, 0x35a3, 0x35a2, 0x35a2, 0x35a2, 0x35a3, - 0x35a2, 0x35a3, 0x2971, 0x7067, 0x0000, 0x0804, 0x248f, 0x681b, - 0x0000, 0x0804, 0x3012, 0x6800, 0xa005, 0x1108, 0x6002, 0x6006, - 0x0005, 0x6410, 0x84ff, 0x0168, 0x2009, 0x4302, 0x2104, 0x8001, - 0x200a, 0x8421, 0x6412, 0x1128, 0x2021, 0x4304, 0x2404, 0xc0a5, - 0x2022, 0x6008, 0xc0a4, 0x600a, 0x0005, 0x6018, 0xa005, 0x0110, - 0x8001, 0x601a, 0x0005, 0x080c, 0x3aa0, 0x681b, 0x0018, 0x04a0, - 0x080c, 0x3aa0, 0x681b, 0x0019, 0x0478, 0x080c, 0x3aa0, 0x681b, - 0x001a, 0x0450, 0x080c, 0x3aa0, 0x681b, 0x0003, 0x0428, 0x7774, - 0x080c, 0x396d, 0x7178, 0xa18c, 0x00ff, 0x3210, 0xa294, 0x0600, - 0x0118, 0xa1e8, 0x88c0, 0x0010, 0xa1e8, 0x89d0, 0x2d04, 0x2d08, - 0x2068, 0xa005, 0x1118, 0x707e, 0x0804, 0x248f, 0x6814, 0xc0fc, - 0x7274, 0xc2fc, 0xa206, 0x0110, 0x6800, 0x0c88, 0x6800, 0x200a, - 0x681b, 0x0005, 0x707f, 0x0000, 0x080c, 0x35b1, 0x6820, 0xd084, - 0x1110, 0x080c, 0x35ab, 0x080c, 0x35c5, 0x681f, 0x0000, 0x6823, - 0x0020, 0x080c, 0x1d3d, 0x0804, 0x248f, 0xa282, 0x0003, 0x1904, - 0x380d, 0x7da8, 0xa5ac, 0x00ff, 0x7ea8, 0xa6b4, 0x00ff, 0x6920, - 0xc1bd, 0x6922, 0xd1c4, 0x0590, 0xc1c4, 0x6922, 0xa6b4, 0x00ff, - 0x0510, 0xa682, 0x001c, 0x0218, 0x0110, 0x2031, 0x001c, 0x852b, - 0x852b, 0x2041, 0x0000, 0x080c, 0x38c6, 0x0118, 0x080c, 0x36f6, - 0x00a0, 0x080c, 0x3892, 0x080c, 0x36f3, 0x6920, 0xc1c5, 0x6922, - 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, - 0x781b, 0x0082, 0x0005, 0x080c, 0x36f3, 0x7e58, 0xd6d4, 0x1118, - 0x781b, 0x0071, 0x0005, 0x781b, 0x0083, 0x0005, 0x00c6, 0x7058, - 0x2060, 0x6100, 0xd1e4, 0x0578, 0x6208, 0x8217, 0xa294, 0x00ff, - 0xa282, 0x001c, 0x0218, 0x0110, 0x2011, 0x001c, 0x2600, 0xa202, - 0x1208, 0x2230, 0x6208, 0xa294, 0x00ff, 0x78ec, 0xd0e4, 0x0130, - 0xa282, 0x000a, 0x1240, 0x2011, 0x000a, 0x0028, 0xa282, 0x000c, - 0x1210, 0x2011, 0x000c, 0x2200, 0xa502, 0x1208, 0x2228, 0x080c, - 0x3896, 0x852b, 0x852b, 0x2041, 0x0000, 0x080c, 0x38c6, 0x0118, - 0x080c, 0x36f6, 0x0020, 0x080c, 0x3892, 0x080c, 0x36f3, 0x7858, - 0xc095, 0x785a, 0x00ce, 0x781b, 0x0082, 0x0005, 0x00c6, 0x2960, - 0x6000, 0xd0e4, 0x1178, 0x6010, 0xa084, 0x000f, 0x1130, 0x6104, - 0xa18c, 0xfff5, 0x6106, 0x00ce, 0x0005, 0x2011, 0x0032, 0x2019, - 0x0000, 0x00f0, 0x68a0, 0xd0cc, 0x1dc0, 0x6208, 0xa294, 0x00ff, - 0x78ec, 0xd0e4, 0x0130, 0xa282, 0x000b, 0x1218, 0x2011, 0x000a, - 0x0028, 0xa282, 0x000c, 0x1210, 0x2011, 0x000c, 0x6308, 0x831f, - 0xa39c, 0x00ff, 0xa382, 0x001c, 0x0218, 0x0110, 0x2019, 0x001c, - 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, - 0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822, 0x080c, 0x3850, 0x00ce, - 0x0005, 0x00c6, 0x2960, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x2011, - 0x0032, 0x2019, 0x0000, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0003, - 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5, - 0x6822, 0x00ce, 0x0005, 0xa006, 0x2030, 0x2010, 0x00c6, 0x7158, - 0x2160, 0x2018, 0x2008, 0xa084, 0xffe0, 0xa635, 0x7e86, 0x6018, - 0x789a, 0x7eae, 0x6612, 0x78a4, 0xa084, 0x7770, 0xa18c, 0x000f, - 0xa105, 0x2029, 0x4305, 0x252c, 0xd5cc, 0x0140, 0xd3a4, 0x0110, - 0xa085, 0x0800, 0xd3fc, 0x0110, 0xa085, 0x8080, 0x78a6, 0x6016, - 0x788a, 0xa6b4, 0x001f, 0x8637, 0x8204, 0x8004, 0xa605, 0x600e, - 0x6004, 0xa084, 0xffd5, 0x6006, 0x00ce, 0x0005, 0xa282, 0x0002, - 0x1904, 0x3816, 0x7aa8, 0x6920, 0xc1bd, 0x6922, 0xd1cc, 0x0568, - 0xc1cc, 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x1a04, 0x3809, - 0x080c, 0x379c, 0x080c, 0x36f3, 0xa980, 0x0001, 0x200c, 0x080c, - 0x3969, 0x080c, 0x3696, 0x88ff, 0x0178, 0x789b, 0x0060, 0x2800, - 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e, - 0x0005, 0x781b, 0x0082, 0x0005, 0x7e58, 0xd6d4, 0x1118, 0x781b, - 0x0071, 0x0005, 0x781b, 0x0083, 0x0005, 0xa282, 0x0002, 0x1218, - 0xa284, 0x0001, 0x0140, 0x7158, 0xa188, 0x0000, 0x210c, 0xd1ec, - 0x1110, 0x2011, 0x0000, 0x080c, 0x3883, 0x0471, 0x080c, 0x36f3, - 0x7858, 0xc095, 0x785a, 0x781b, 0x0082, 0x0005, 0x00c6, 0x0026, - 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, 0x1150, 0x6014, 0xa084, - 0x0040, 0x1120, 0xc1a4, 0x6106, 0xa006, 0x0088, 0x2011, 0x0000, - 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, - 0x0004, 0x080c, 0x3850, 0x6820, 0xa085, 0x0200, 0x6822, 0x002e, - 0x00ce, 0x0005, 0x8807, 0xa715, 0x00c6, 0x2009, 0x0000, 0x7058, - 0x2060, 0x82ff, 0x0110, 0x2009, 0x0040, 0x6018, 0xa080, 0x0002, - 0x789a, 0x78a4, 0xa084, 0xff9f, 0xa105, 0xc0ec, 0xd0b4, 0x1108, - 0xc0ed, 0x6100, 0xd1f4, 0x0110, 0xa085, 0x0020, 0x78a6, 0x6016, - 0x788a, 0x6004, 0xa084, 0xffef, 0x6006, 0x00ce, 0x0005, 0x0006, - 0x7000, 0xa086, 0x0003, 0x0110, 0x000e, 0x0010, 0x000e, 0x0488, - 0xd6ac, 0x0578, 0x7888, 0xa084, 0x0040, 0x0558, 0x7bb8, 0x8307, - 0xa084, 0x007f, 0x1508, 0x8207, 0xa084, 0x00ff, 0xa09e, 0x0001, - 0x1904, 0x382d, 0xd6f4, 0x11d0, 0x79d8, 0x7adc, 0xa108, 0xa291, - 0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x080c, 0x4083, 0x781b, - 0x0080, 0xb284, 0x0600, 0x0118, 0x2001, 0x0000, 0x0010, 0x2001, - 0x0001, 0x080c, 0x3f50, 0x0005, 0x080c, 0x243b, 0x781b, 0x0080, - 0x0005, 0x781b, 0x0083, 0x0005, 0x2039, 0x0000, 0x2041, 0x0000, - 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x36f6, 0x080c, 0x379a, - 0x7e58, 0x04f9, 0x781b, 0x0082, 0x0005, 0x0cd9, 0x6820, 0xc0c4, - 0x6822, 0x00c6, 0x7058, 0x2060, 0x0804, 0x3720, 0x0c91, 0x6820, - 0xc0cc, 0x6822, 0x00c6, 0x7058, 0x2060, 0x0804, 0x37b9, 0x0c49, - 0x6820, 0xa084, 0xecff, 0x6822, 0x00c6, 0x7058, 0x2060, 0x6004, - 0xa084, 0xffc5, 0x6006, 0x00ce, 0x0005, 0x0049, 0x781b, 0x0082, - 0x0005, 0x6827, 0x0002, 0x0049, 0x781b, 0x0082, 0x0005, 0x2001, - 0x0005, 0x0088, 0x2001, 0x000c, 0x0070, 0x6820, 0xc0d5, 0x6822, - 0x2001, 0x0006, 0x0040, 0x2001, 0x000d, 0x0028, 0x2001, 0x0009, - 0x0010, 0x2001, 0x0007, 0x789b, 0x007e, 0x78aa, 0xc69d, 0x7e5a, - 0x70d4, 0xd0b4, 0x0168, 0xc0b4, 0x70d6, 0x00c6, 0x70b8, 0xa065, - 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, - 0x0005, 0x0076, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, - 0xb28c, 0x0600, 0x0118, 0xa0e0, 0x47c0, 0x0010, 0xa0e0, 0x4840, - 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184, 0x7fe0, 0x78ae, 0x6012, - 0x79a4, 0xa184, 0x773f, 0x78a6, 0x6016, 0x6004, 0xa085, 0x0038, - 0x6006, 0x007e, 0x0005, 0x789b, 0x0080, 0x78ab, 0x0001, 0x78ab, - 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab, 0x0004, - 0x0804, 0x3850, 0x2031, 0x0000, 0x2029, 0x0032, 0x789b, 0x0080, - 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7eaa, - 0x789b, 0x0060, 0x78ab, 0x0005, 0x0804, 0x3850, 0x0156, 0x8007, - 0xa084, 0x00ff, 0x8003, 0x8003, 0xa080, 0x0020, 0x789a, 0x79a4, - 0xa18c, 0xffe0, 0x2021, 0x3952, 0x2019, 0x0011, 0x20a9, 0x000e, - 0x2011, 0x0032, 0x2404, 0xa084, 0xffe0, 0xa106, 0x0128, 0x8420, - 0x2300, 0xa210, 0x1f04, 0x38ba, 0x015e, 0x0005, 0x0156, 0x0804, - 0x3908, 0x2021, 0x3960, 0x20a9, 0x0009, 0x2011, 0x0029, 0xa582, - 0x0028, 0x0550, 0x8420, 0x95a9, 0x2011, 0x0033, 0xa582, 0x0033, - 0x0618, 0x8420, 0x95a9, 0x2019, 0x000a, 0x2011, 0x0065, 0x2200, - 0xa502, 0x02d0, 0x8420, 0x2300, 0xa210, 0x1f04, 0x38df, 0x015e, - 0x0088, 0x2021, 0x3952, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, - 0x0033, 0x2200, 0xa502, 0x0240, 0x8420, 0x2300, 0xa210, 0x1f04, - 0x38f1, 0x015e, 0xa006, 0x0005, 0x8211, 0x015e, 0xa582, 0x0064, - 0x1220, 0x7808, 0xa085, 0x0070, 0x780a, 0x2404, 0xa005, 0x0005, - 0xa886, 0x0002, 0x01e8, 0x2021, 0x393e, 0x20a9, 0x000d, 0x2011, - 0x0028, 0xa582, 0x0028, 0x0d48, 0x8420, 0x2019, 0x0019, 0x2011, - 0x0033, 0x2200, 0xa502, 0x0e00, 0x8420, 0x2300, 0xa210, 0x1f04, - 0x3919, 0x015e, 0x2011, 0x0184, 0xa582, 0x0185, 0x0ab0, 0x0890, - 0x2021, 0x394d, 0x20a9, 0x0003, 0x2011, 0x0024, 0xa586, 0x0024, - 0x0960, 0x8420, 0x2011, 0x0028, 0xa586, 0x0028, 0x0930, 0x8420, - 0x2019, 0x0019, 0x2011, 0x0033, 0x0804, 0x38f1, 0x1021, 0x2202, - 0x3403, 0x4604, 0x5805, 0x6a06, 0x7c07, 0x4610, 0x4612, 0x5812, - 0x5a12, 0x6a14, 0x6c14, 0x6e14, 0x7e17, 0x9021, 0xb002, 0xe204, - 0xe210, 0xe210, 0x1209, 0x3002, 0x3202, 0x4203, 0x4403, 0x5404, - 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, 0x0c07, 0x0e07, - 0x10e1, 0x330a, 0x5805, 0x5a05, 0x6a06, 0x6c06, 0x7c07, 0x7e07, - 0x0e00, 0x789b, 0x0080, 0xa046, 0x0005, 0xa784, 0x0f00, 0x800b, - 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xd7fc, - 0x0118, 0xa0e0, 0x68c0, 0x0010, 0xa0e0, 0x48c0, 0x0005, 0x00e6, - 0x00f6, 0xd084, 0x0138, 0x2079, 0x0100, 0x2009, 0x4380, 0x2071, - 0x4380, 0x0030, 0x2009, 0x4340, 0x2079, 0x0200, 0x2071, 0x4340, - 0x2091, 0x8000, 0x2104, 0xa084, 0x000f, 0x0002, 0x39c5, 0x39a0, - 0x39a0, 0x39a0, 0x39a0, 0x39a0, 0x399e, 0x399e, 0x080c, 0x243b, - 0x784b, 0x0004, 0x7848, 0xa084, 0x0004, 0x1de0, 0x784b, 0x0008, - 0x7848, 0xa084, 0x0008, 0x1de0, 0x68b4, 0xc0f5, 0x68b6, 0x7858, - 0xc0f5, 0x785a, 0x7830, 0xd0bc, 0x1180, 0xb284, 0x0800, 0x0118, - 0x0104, 0x39c5, 0x0010, 0x0304, 0x39c5, 0x681c, 0xd0ac, 0x1118, - 0x080c, 0x3a4b, 0x0010, 0x781b, 0x00fb, 0x2091, 0x8001, 0x00fe, - 0x00ee, 0x0005, 0x00c6, 0x2001, 0x4301, 0x2004, 0xd0ac, 0x1904, - 0x3a3d, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, - 0xb28c, 0x0600, 0x0118, 0xa0e0, 0x47c0, 0x0010, 0xa0e0, 0x4840, - 0x6004, 0xa084, 0x000a, 0x1904, 0x3a3d, 0x6108, 0xa194, 0xff00, - 0x0904, 0x3a3d, 0xa18c, 0x00ff, 0x601c, 0xa084, 0xff00, 0x0180, - 0x2001, 0x0009, 0xa102, 0x16b8, 0x2001, 0x000a, 0xa102, 0x16b0, - 0x2001, 0x000c, 0xa102, 0x16a8, 0x601c, 0xa084, 0x00ff, 0x601e, - 0x2001, 0x000a, 0xa106, 0x01a8, 0x2001, 0x000c, 0xa106, 0x01a0, - 0x2001, 0x0012, 0xa106, 0x0198, 0x2001, 0x0014, 0xa106, 0x0190, - 0x2001, 0x0019, 0xa106, 0x0188, 0x2001, 0x0032, 0xa106, 0x0180, - 0x00d8, 0x2009, 0x000c, 0x00d0, 0x2009, 0x0012, 0x00b8, 0x2009, - 0x0014, 0x00a0, 0x2009, 0x0019, 0x0088, 0x2009, 0x0020, 0x0070, - 0x2009, 0x003f, 0x0058, 0x2009, 0x000a, 0x0040, 0x2009, 0x000c, - 0x0028, 0x2009, 0x0019, 0x0010, 0x2011, 0x0000, 0x2100, 0xa205, - 0x600a, 0x6004, 0xa085, 0x0002, 0x6006, 0x00ce, 0x0005, 0x781b, - 0x0083, 0x0005, 0x781b, 0x0082, 0x0005, 0x781b, 0x0071, 0x0005, - 0x781b, 0x006e, 0x0005, 0x2009, 0x4319, 0x210c, 0xa186, 0x0000, - 0x0150, 0xa186, 0x0001, 0x0150, 0x701f, 0x000b, 0x7067, 0x0001, - 0x781b, 0x0054, 0x0005, 0x781b, 0x00f3, 0x0005, 0x701f, 0x000a, - 0x0005, 0x2009, 0x4319, 0x210c, 0xa186, 0x0000, 0x0168, 0xa186, - 0x0001, 0x0138, 0x701f, 0x000b, 0x7067, 0x0001, 0x781b, 0x0054, - 0x0005, 0x701f, 0x000a, 0x0005, 0x781b, 0x00f2, 0x0005, 0x781b, - 0x00fb, 0x0005, 0x781b, 0x00fa, 0x0005, 0x781b, 0x00cc, 0x0005, - 0x781b, 0x00cb, 0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, - 0x7067, 0x0001, 0x781b, 0x0054, 0x0005, 0x7830, 0xa084, 0x00c0, - 0x1170, 0x7808, 0xc08c, 0x780a, 0xe000, 0xe000, 0xe000, 0xe000, - 0x78ec, 0xa084, 0x0021, 0x0118, 0x7808, 0xc08d, 0x780a, 0x0005, - 0x7808, 0xc08d, 0x780a, 0x0005, 0x7830, 0xa084, 0x0040, 0x1de0, - 0xb284, 0x0800, 0x0118, 0x1104, 0x3ab2, 0x0010, 0x1304, 0x3ab2, - 0x78ac, 0x0005, 0x7808, 0xa084, 0xfffd, 0x780a, 0xe000, 0xe000, - 0xe000, 0xe000, 0x78ec, 0xa084, 0x0021, 0x0140, 0xb284, 0x0800, - 0x0118, 0x1104, 0x3ac1, 0x0010, 0x1304, 0x3ac4, 0x78ac, 0x0006, - 0x7808, 0xa085, 0x0002, 0x780a, 0x000e, 0x0005, 0xa784, 0x0001, - 0x1904, 0x30a0, 0xa784, 0x0070, 0x0140, 0x00c6, 0x2d60, 0x2f68, - 0x080c, 0x23e1, 0x2d78, 0x2c68, 0x00ce, 0xa784, 0x0008, 0x0148, - 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0904, 0x248f, 0x0804, - 0x3a3f, 0xa784, 0x0004, 0x01c8, 0x78b8, 0xa084, 0x8000, 0x01a8, - 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0904, 0x248f, 0x78e4, - 0xa084, 0x0007, 0xa086, 0x0001, 0x1140, 0x78c0, 0xa685, 0x4800, - 0x2030, 0x7e5a, 0x781b, 0x00fb, 0x0005, 0xa784, 0x0080, 0x0140, - 0x7884, 0xd0fc, 0x0128, 0x080c, 0x382d, 0x681b, 0x0022, 0x0005, - 0x681b, 0x0003, 0x7858, 0xa084, 0x3f00, 0x681e, 0x682f, 0x0000, - 0x6833, 0x0000, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0904, - 0x2a7a, 0xb284, 0x0800, 0x0110, 0x0104, 0x248c, 0x0304, 0x248c, - 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xd3fc, - 0x0118, 0xa080, 0x4840, 0x0010, 0xa080, 0x47c0, 0x2060, 0x2048, - 0x705a, 0x2a60, 0x0005, 0x00c6, 0x2960, 0x6000, 0xd0ac, 0x0904, - 0x3b81, 0xd1ac, 0x05e0, 0x6108, 0x8117, 0xa18c, 0x00ff, 0x631c, - 0x832f, 0x68a0, 0xd0cc, 0x11c8, 0xa584, 0x00ff, 0x0138, 0x78ec, - 0xd0e4, 0x0110, 0x8213, 0x00b8, 0x2029, 0x0000, 0xa182, 0x000c, - 0x1290, 0x78ec, 0xd0e4, 0x1118, 0x2009, 0x000c, 0x0060, 0xa182, - 0x000b, 0x1248, 0x2009, 0x000a, 0x0030, 0x2009, 0x0032, 0x2011, - 0x0000, 0x2029, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab, - 0x0004, 0x79aa, 0x78ab, 0x0000, 0x7aaa, 0x7baa, 0x7daa, 0xa8c0, - 0x0008, 0x6820, 0xa085, 0x1000, 0x6822, 0x080c, 0x3850, 0xa085, - 0x0001, 0x00ce, 0x0005, 0xa282, 0x0006, 0x1904, 0x381f, 0x7da8, - 0x7eac, 0x8637, 0xa5ac, 0x00ff, 0xa6b4, 0x00ff, 0x7fac, 0x8747, - 0xa7bc, 0x00ff, 0xa8c4, 0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1e4, - 0x05c8, 0xa18c, 0xecff, 0x6922, 0xa782, 0x0002, 0x1a04, 0x37fc, - 0xa6b4, 0x00ff, 0x0560, 0xa682, 0x0039, 0x1a04, 0x37fc, 0xa582, - 0x0009, 0x0a04, 0x37fc, 0xa882, 0x0003, 0x1a04, 0x37fc, 0xa886, - 0x0002, 0x0128, 0xa886, 0x0000, 0x0138, 0x0804, 0x37fc, 0xa786, - 0x0000, 0x0904, 0x37fc, 0x8634, 0x852b, 0x852b, 0x080c, 0x38c6, - 0x0904, 0x37fc, 0x080c, 0x36f6, 0x080c, 0x379a, 0x7e58, 0xd6d4, - 0x1118, 0x781b, 0x0071, 0x0005, 0x781b, 0x0083, 0x0005, 0x080c, - 0x36f3, 0x0c90, 0xa886, 0x0002, 0x1108, 0x8634, 0x7158, 0xa188, - 0x0000, 0x210c, 0xd1ac, 0x0904, 0x37fc, 0xd1ec, 0x1120, 0x2039, - 0x0000, 0x2041, 0x0000, 0xd1e4, 0x1120, 0x2031, 0x0000, 0x2041, - 0x0000, 0xa782, 0x0002, 0x12c8, 0x621c, 0xa284, 0x00ff, 0xa706, - 0x0110, 0x2039, 0x0000, 0xa605, 0x0190, 0x6108, 0x811f, 0xa39c, - 0x00ff, 0x0168, 0xa302, 0x1208, 0x2330, 0x8807, 0xa705, 0xa086, - 0x0201, 0x0160, 0xa886, 0x0000, 0x0168, 0x2039, 0x0000, 0x2041, - 0x0000, 0x2031, 0x0000, 0xa006, 0x2010, 0x0070, 0xa284, 0xff00, - 0x1108, 0x2040, 0xa184, 0x00ff, 0xa502, 0x0108, 0x2128, 0x852b, - 0x852b, 0x080c, 0x38c6, 0x0d58, 0x080c, 0x36f6, 0x080c, 0x379a, - 0x789b, 0x0080, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab, 0x0004, - 0x78ab, 0x0000, 0x7daa, 0x7eaa, 0x7faa, 0x2800, 0x78aa, 0x789b, - 0x0060, 0x78ab, 0x0005, 0x080c, 0x3850, 0x7858, 0xc095, 0x785a, - 0x781b, 0x0082, 0x0005, 0x0020, 0x0020, 0x0000, 0x0020, 0x0000, + 0x681f, 0x0100, 0x7000, 0xa084, 0x000f, 0x0002, 0x25a0, 0x3783, + 0x3780, 0x37a0, 0x378c, 0x25a0, 0x377e, 0x377e, 0x080c, 0x254c, + 0x0449, 0x0411, 0x0028, 0x0431, 0x7058, 0x2060, 0x6800, 0x6002, + 0x080c, 0x1da2, 0x0804, 0x25a0, 0x7060, 0x7063, 0x0000, 0x707f, + 0x0000, 0x0002, 0x379c, 0x379c, 0x379a, 0x379a, 0x379a, 0x379c, + 0x379a, 0x379c, 0x0804, 0x2a6b, 0x7063, 0x0000, 0x0804, 0x25a0, + 0x681b, 0x0000, 0x0804, 0x3184, 0x6800, 0xa005, 0x1108, 0x6002, + 0x6006, 0x0005, 0x6410, 0x84ff, 0x0168, 0x2009, 0x4602, 0x2104, + 0x8001, 0x200a, 0x8421, 0x6412, 0x1128, 0x2021, 0x4604, 0x2404, + 0xc0a5, 0x2022, 0x6008, 0xc0a4, 0x600a, 0x0005, 0x6018, 0xa005, + 0x0110, 0x8001, 0x601a, 0x0005, 0x080c, 0x3c46, 0x681b, 0x0018, + 0x0490, 0x080c, 0x3c46, 0x681b, 0x0019, 0x0468, 0x080c, 0x3c46, + 0x681b, 0x001a, 0x0440, 0x080c, 0x3c46, 0x681b, 0x0003, 0x0418, + 0x7770, 0x080c, 0x3b6f, 0x7174, 0xa18c, 0x00ff, 0x3210, 0xa294, + 0x0600, 0x0118, 0xa1e8, 0x8bc0, 0x0010, 0xa1e8, 0x8cd0, 0x2d04, + 0x2d08, 0x2068, 0xa005, 0x1118, 0x707a, 0x0804, 0x25a0, 0x6814, + 0x7270, 0xa206, 0x0110, 0x6800, 0x0c98, 0x6800, 0x200a, 0x681b, + 0x0005, 0x707b, 0x0000, 0x080c, 0x37aa, 0x6820, 0xd084, 0x1110, + 0x080c, 0x37a4, 0x080c, 0x37be, 0x681f, 0x0000, 0x6823, 0x0020, + 0x080c, 0x1da2, 0x0804, 0x25a0, 0xa282, 0x0003, 0x1904, 0x3a10, + 0x7da8, 0xa5ac, 0x00ff, 0x7ea8, 0xa6b4, 0x00ff, 0x6920, 0xc1bd, + 0x6922, 0xd1c4, 0x05b0, 0xc1c4, 0x6922, 0xa6b4, 0x00ff, 0x0530, + 0xa682, 0x0018, 0x0218, 0x0110, 0x2031, 0x0018, 0xa686, 0x0010, + 0x1108, 0x8630, 0x852b, 0x852b, 0x2041, 0x0000, 0x080c, 0x3ac9, + 0x0118, 0x080c, 0x38f7, 0x00a0, 0x080c, 0x3a95, 0x080c, 0x38f4, + 0x6920, 0xc1c5, 0x6922, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x1118, + 0x781b, 0x006e, 0x0005, 0x781b, 0x0082, 0x0005, 0x080c, 0x38f4, + 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005, 0x781b, 0x0083, + 0x0005, 0x00c6, 0x7054, 0x2060, 0x6100, 0xd1e4, 0x0598, 0x6208, + 0x8217, 0xa294, 0x00ff, 0xa282, 0x0018, 0x0218, 0x0110, 0x2011, + 0x0018, 0x2600, 0xa202, 0x1208, 0x2230, 0xa686, 0x0010, 0x1108, + 0x8630, 0x6208, 0xa294, 0x00ff, 0x78ec, 0xd0e4, 0x0130, 0xa282, + 0x000a, 0x1240, 0x2011, 0x000a, 0x0028, 0xa282, 0x000c, 0x1210, + 0x2011, 0x000c, 0x2200, 0xa502, 0x1208, 0x2228, 0x080c, 0x3a99, + 0x852b, 0x852b, 0x2041, 0x0000, 0x080c, 0x3ac9, 0x0118, 0x080c, + 0x38f7, 0x0020, 0x080c, 0x3a95, 0x080c, 0x38f4, 0x7858, 0xc095, + 0x785a, 0x00ce, 0x781b, 0x0082, 0x0005, 0x00c6, 0x2960, 0x6000, + 0xd0e4, 0x1188, 0xd0b4, 0x1150, 0x6010, 0xa084, 0x000f, 0x1130, + 0x6104, 0xa18c, 0xfff5, 0x6106, 0x00ce, 0x0005, 0x2011, 0x0032, + 0x2019, 0x0000, 0x00f0, 0x68a0, 0xd0cc, 0x1dc0, 0x6208, 0xa294, + 0x00ff, 0x78ec, 0xd0e4, 0x0130, 0xa282, 0x000b, 0x1218, 0x2011, + 0x000a, 0x0028, 0xa282, 0x000c, 0x1210, 0x2011, 0x000c, 0x6308, + 0x831f, 0xa39c, 0x00ff, 0xa382, 0x0018, 0x0218, 0x0110, 0x2019, + 0x0018, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, + 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822, 0x080c, 0x3a55, + 0x00ce, 0x0005, 0x00c6, 0x2960, 0x6104, 0xa18c, 0xfff5, 0x6106, + 0x2011, 0x0032, 0x2019, 0x0000, 0x0000, 0x78ab, 0x0001, 0x78ab, + 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, + 0xc0c5, 0x6822, 0x00ce, 0x0005, 0xa006, 0x2030, 0x2010, 0x00c6, + 0x7154, 0x2160, 0x2018, 0x2008, 0xa084, 0xffe0, 0xa635, 0x7e86, + 0x6018, 0x789a, 0x7eae, 0x6612, 0x78a4, 0xa084, 0x7770, 0xa18c, + 0x000f, 0xa105, 0x2029, 0x4605, 0x252c, 0xd5cc, 0x0140, 0xd3a4, + 0x0110, 0xa085, 0x0800, 0xd3fc, 0x0110, 0xa085, 0x8080, 0x78a6, + 0x6016, 0x788a, 0xa6b4, 0x001f, 0x8637, 0x8204, 0x8004, 0xa605, + 0x600e, 0x6004, 0xa084, 0xffd5, 0x6006, 0x00ce, 0x0005, 0xa282, + 0x0002, 0x1904, 0x3a1a, 0x7aa8, 0x6920, 0xc1bd, 0x6922, 0xd1cc, + 0x0568, 0xc1cc, 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x1a04, + 0x3a0b, 0x080c, 0x399e, 0x080c, 0x38f4, 0xa980, 0x0001, 0x200c, + 0x080c, 0x3b6b, 0x080c, 0x3895, 0x88ff, 0x0178, 0x789b, 0x0060, + 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b, + 0x006e, 0x0005, 0x781b, 0x0082, 0x0005, 0x7e58, 0xd6d4, 0x1118, + 0x781b, 0x0071, 0x0005, 0x781b, 0x0083, 0x0005, 0xa282, 0x0002, + 0x1218, 0xa284, 0x0001, 0x0140, 0x7154, 0xa188, 0x0000, 0x210c, + 0xd1ec, 0x1110, 0x2011, 0x0000, 0x080c, 0x3a87, 0x0479, 0x080c, + 0x38f4, 0x7858, 0xc095, 0x785a, 0x781b, 0x0082, 0x0005, 0x00c6, + 0x0026, 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, 0x1158, 0xd0bc, + 0x1138, 0x6014, 0xd0b4, 0x1120, 0xc1a4, 0x6106, 0xa006, 0x0088, + 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, + 0x7aaa, 0xa8c0, 0x0004, 0x080c, 0x3a55, 0x6820, 0xa085, 0x0200, + 0x6822, 0x002e, 0x00ce, 0x0005, 0x8807, 0xa715, 0x00c6, 0x2009, + 0x0000, 0x7054, 0x2060, 0x82ff, 0x0110, 0x2009, 0x0040, 0x6018, + 0xa080, 0x0002, 0x789a, 0x78a4, 0xa084, 0xff9f, 0xa105, 0xc0ec, + 0xd0b4, 0x1108, 0xc0ed, 0x6100, 0xd1f4, 0x0110, 0xa085, 0x0020, + 0x78a6, 0x6016, 0x788a, 0x6004, 0xa084, 0xffef, 0x6006, 0x00ce, + 0x0005, 0x0006, 0x7000, 0xa086, 0x0003, 0x0110, 0x000e, 0x0010, + 0x000e, 0x0488, 0xd6ac, 0x0578, 0x7888, 0xa084, 0x0040, 0x0558, + 0x7bb8, 0x8307, 0xa084, 0x007f, 0x1508, 0x8207, 0xa084, 0x00ff, + 0xa09e, 0x0001, 0x1904, 0x3a32, 0xd6f4, 0x11d0, 0x79d8, 0x7adc, + 0xa108, 0xa291, 0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x080c, + 0x42b5, 0x781b, 0x0080, 0xb284, 0x0600, 0x0118, 0x2001, 0x0000, + 0x0010, 0x2001, 0x0001, 0x080c, 0x4172, 0x0005, 0x080c, 0x254c, + 0x781b, 0x0080, 0x0005, 0x781b, 0x0083, 0x0005, 0x2039, 0x0000, + 0x2041, 0x0000, 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x38f7, + 0x080c, 0x399c, 0x7e58, 0x080c, 0x3a4e, 0x781b, 0x0082, 0x0005, + 0x0cd1, 0x6820, 0xc0c4, 0x6822, 0x00c6, 0x7054, 0x2060, 0x080c, + 0x3921, 0x00b0, 0x0c81, 0x6820, 0xc0cc, 0x6822, 0x00c6, 0x7054, + 0x2060, 0x080c, 0x39bb, 0x0060, 0x0c31, 0x6820, 0xa084, 0xecff, + 0x6822, 0x00c6, 0x7054, 0x2060, 0x6004, 0xa084, 0xffc5, 0x6006, + 0x00ce, 0x0005, 0x0049, 0x781b, 0x0082, 0x0005, 0x6827, 0x0002, + 0x0049, 0x781b, 0x0082, 0x0005, 0x2001, 0x0005, 0x0088, 0x2001, + 0x000c, 0x0070, 0x6820, 0xc0d5, 0x6822, 0x2001, 0x0006, 0x0040, + 0x2001, 0x000d, 0x0028, 0x2001, 0x0009, 0x0010, 0x2001, 0x0007, + 0x789b, 0x007e, 0x78aa, 0xc69d, 0x7e5a, 0x70d0, 0xd0b4, 0x0168, + 0xc0b4, 0x70d2, 0x00c6, 0x70b4, 0xa065, 0x6008, 0xa084, 0xfbef, + 0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, 0x0005, 0x0076, 0x873f, + 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0xa0e0, 0x4ac0, 0xae8e, + 0x4640, 0x0110, 0xa0e0, 0x4b40, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, + 0xa184, 0x7fe0, 0x78ae, 0x6012, 0x79a4, 0xa184, 0x773f, 0x78a6, + 0x6016, 0x6004, 0xa085, 0x0038, 0x6006, 0x007e, 0x0005, 0x789b, + 0x0080, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, + 0x789b, 0x0060, 0x78ab, 0x0004, 0x0800, 0x2031, 0x0000, 0x2029, + 0x0032, 0x789b, 0x0080, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, + 0x0001, 0x7daa, 0x7eaa, 0x789b, 0x0060, 0x78ab, 0x0005, 0x0804, + 0x3a55, 0x0156, 0x8007, 0xa084, 0x00ff, 0x8003, 0x8003, 0xa080, + 0x0020, 0x789a, 0x79a4, 0xa18c, 0xffe0, 0x2021, 0x3b54, 0x2019, + 0x0011, 0x20a9, 0x000e, 0x2011, 0x0032, 0x2404, 0xa084, 0xffe0, + 0xa106, 0x0128, 0x8420, 0x2300, 0xa210, 0x1f04, 0x3abd, 0x015e, + 0x0005, 0x0156, 0x04f8, 0x2021, 0x3b62, 0x20a9, 0x0009, 0x2011, + 0x0029, 0xa582, 0x0028, 0x0550, 0x8420, 0x95a9, 0x2011, 0x0033, + 0xa582, 0x0033, 0x0618, 0x8420, 0x95a9, 0x2019, 0x000a, 0x2011, + 0x0065, 0x2200, 0xa502, 0x02d0, 0x8420, 0x2300, 0xa210, 0x1f04, + 0x3ae1, 0x015e, 0x0088, 0x2021, 0x3b54, 0x2019, 0x0011, 0x20a9, + 0x000e, 0x2011, 0x0033, 0x2200, 0xa502, 0x0240, 0x8420, 0x2300, + 0xa210, 0x1f04, 0x3af3, 0x015e, 0xa006, 0x0005, 0x8211, 0x015e, + 0xa582, 0x0064, 0x1220, 0x7808, 0xa085, 0x0070, 0x780a, 0x2404, + 0xa005, 0x0005, 0xa886, 0x0002, 0x01e8, 0x2021, 0x3b40, 0x20a9, + 0x000d, 0x2011, 0x0028, 0xa582, 0x0028, 0x0d48, 0x8420, 0x2019, + 0x0019, 0x2011, 0x0033, 0x2200, 0xa502, 0x0e00, 0x8420, 0x2300, + 0xa210, 0x1f04, 0x3b1b, 0x015e, 0x2011, 0x0184, 0xa582, 0x0185, + 0x0ab0, 0x0890, 0x2021, 0x3b4f, 0x20a9, 0x0003, 0x2011, 0x0024, + 0xa586, 0x0024, 0x0960, 0x8420, 0x2011, 0x0028, 0xa586, 0x0028, + 0x0930, 0x8420, 0x2019, 0x0019, 0x2011, 0x0033, 0x0804, 0x3af3, + 0x1021, 0x2202, 0x3403, 0x4604, 0x5805, 0x6a06, 0x7c07, 0x4610, + 0x4612, 0x5812, 0x5a12, 0x6a14, 0x6c14, 0x6e14, 0x7e17, 0x9021, + 0xb002, 0xe204, 0xe210, 0xe210, 0x1209, 0x3002, 0x3202, 0x4203, + 0x4403, 0x5404, 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, + 0x0c07, 0x0e07, 0x10e1, 0x330a, 0x5805, 0x5a05, 0x6a06, 0x6c06, + 0x7c07, 0x7e07, 0x0e00, 0x789b, 0x0080, 0xa046, 0x0005, 0xa784, + 0x0f00, 0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, + 0xa105, 0xd7fc, 0x0118, 0xa0e0, 0x6bc0, 0x0010, 0xa0e0, 0x4bc0, + 0x0005, 0x00e6, 0x00f6, 0xd084, 0x0138, 0x2079, 0x0100, 0x2009, + 0x4680, 0x2071, 0x4680, 0x0030, 0x2009, 0x4640, 0x2079, 0x0200, + 0x2071, 0x4640, 0x2091, 0x8000, 0x2104, 0xa084, 0x000f, 0x0002, + 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba0, 0x3ba0, + 0x080c, 0x254c, 0x69b4, 0xc1f5, 0xa18c, 0xff9f, 0x69b6, 0xa005, + 0x0580, 0x7858, 0xa084, 0xff9f, 0xa085, 0x6000, 0x785a, 0x7828, + 0xa086, 0x1814, 0x1530, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004, + 0x1de0, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, 0x1de0, 0x7830, + 0xd0bc, 0x11b8, 0xb284, 0x0800, 0x0118, 0x0104, 0x3bd9, 0x0010, + 0x0304, 0x3bd9, 0x79e4, 0xa184, 0x0030, 0x0158, 0x78ec, 0xa084, + 0x0003, 0x0138, 0x681c, 0xd0ac, 0x1110, 0x00d9, 0x0010, 0x781b, + 0x00fb, 0x00fe, 0x00ee, 0x0005, 0x2001, 0x4601, 0x2004, 0xd0ac, + 0x1118, 0x6814, 0x080c, 0x2475, 0x0005, 0x781b, 0x0083, 0x0005, + 0x781b, 0x0082, 0x0005, 0x781b, 0x0071, 0x0005, 0x781b, 0x006e, + 0x0005, 0x2009, 0x4619, 0x210c, 0xa186, 0x0000, 0x0150, 0xa186, + 0x0001, 0x0150, 0x701f, 0x000b, 0x7063, 0x0001, 0x781b, 0x0054, + 0x0005, 0x781b, 0x00f3, 0x0005, 0x701f, 0x000a, 0x0005, 0x2009, + 0x4619, 0x210c, 0xa186, 0x0000, 0x0168, 0xa186, 0x0001, 0x0138, + 0x701f, 0x000b, 0x7063, 0x0001, 0x781b, 0x0054, 0x0005, 0x701f, + 0x000a, 0x0005, 0x781b, 0x00f2, 0x0005, 0x781b, 0x00fb, 0x0005, + 0x781b, 0x00fa, 0x0005, 0x781b, 0x00cc, 0x0005, 0x781b, 0x00cb, + 0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x7063, 0x0001, + 0x781b, 0x0054, 0x0005, 0x7830, 0xa084, 0x00c0, 0x1170, 0x7808, + 0xc08c, 0x780a, 0xe000, 0xe000, 0xe000, 0xe000, 0x78ec, 0xa084, + 0x0021, 0x0118, 0x7808, 0xc08d, 0x780a, 0x0005, 0x7808, 0xc08d, + 0x780a, 0x0005, 0x7830, 0xa084, 0x0040, 0x1de0, 0xb284, 0x0800, + 0x0118, 0x1104, 0x3c58, 0x0010, 0x1304, 0x3c58, 0x78ac, 0x0005, + 0x7808, 0xa084, 0xfffd, 0x780a, 0xe000, 0xe000, 0xe000, 0xe000, + 0x78ec, 0xa084, 0x0021, 0x0140, 0xb284, 0x0800, 0x0118, 0x1104, + 0x3c67, 0x0010, 0x1304, 0x3c6a, 0x78ac, 0x0006, 0x7808, 0xa085, + 0x0002, 0x780a, 0x000e, 0x0005, 0xa784, 0x0001, 0x1904, 0x322a, + 0xa784, 0x0070, 0x0140, 0x00c6, 0x2d60, 0x2f68, 0x080c, 0x2467, + 0x2d78, 0x2c68, 0x00ce, 0xa784, 0x0008, 0x0148, 0x784b, 0x0008, + 0x78ec, 0xa084, 0x0003, 0x0904, 0x322a, 0x0804, 0x3be5, 0xa784, + 0x0004, 0x01c8, 0x78b8, 0xa084, 0x8000, 0x01a8, 0x784b, 0x0008, + 0x78ec, 0xa084, 0x0003, 0x0904, 0x322a, 0x78e4, 0xa084, 0x0007, + 0xa086, 0x0001, 0x1140, 0x78c0, 0xa685, 0x4800, 0x2030, 0x7e5a, + 0x781b, 0x00fb, 0x0005, 0xa784, 0x0080, 0x0140, 0x7884, 0xd0fc, + 0x0128, 0x080c, 0x3a32, 0x681b, 0x0022, 0x0005, 0x681b, 0x0003, + 0x7858, 0xa084, 0x5f00, 0x681e, 0x682f, 0x0000, 0x6833, 0x0000, + 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0904, 0x2b89, 0xb284, + 0x0800, 0x0110, 0x0104, 0x259d, 0x0304, 0x259d, 0x6b14, 0x8307, + 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xd3fc, 0x0118, 0xa080, + 0x4b40, 0x0010, 0xa080, 0x4ac0, 0x2060, 0x2048, 0x7056, 0x2a60, + 0x0005, 0x00c6, 0x2960, 0x6000, 0xd0ac, 0x0904, 0x3d2f, 0x68a0, + 0xd1ac, 0x1120, 0xa084, 0x0e00, 0x0904, 0x3d2d, 0x6108, 0x8117, + 0xa18c, 0x00ff, 0x631c, 0x832f, 0xd0dc, 0x0110, 0xa39d, 0x0001, + 0xd0cc, 0x11c8, 0xa584, 0x00ff, 0x0138, 0x78ec, 0xd0e4, 0x0110, + 0x8213, 0x00b8, 0x2029, 0x0000, 0xa182, 0x000c, 0x1290, 0x78ec, + 0xd0e4, 0x1118, 0x2009, 0x000c, 0x0060, 0xa182, 0x000b, 0x1248, + 0x2009, 0x000a, 0x0030, 0x2009, 0x0032, 0x2011, 0x0000, 0x2029, + 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab, 0x0004, 0x79aa, + 0x78ab, 0x0000, 0x7aaa, 0x7baa, 0x7daa, 0xa8c0, 0x0008, 0x6820, + 0xa085, 0x1000, 0x6822, 0x080c, 0x3a55, 0xa085, 0x0001, 0x00ce, + 0x0005, 0xa282, 0x0006, 0x1904, 0x3a24, 0x7da8, 0x7eac, 0x8637, + 0xa5ac, 0x00ff, 0xa6b4, 0x00ff, 0x7fac, 0x8747, 0xa7bc, 0x00ff, + 0xa8c4, 0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1e4, 0x0904, 0x3da3, + 0xa18c, 0xecff, 0x6922, 0xa782, 0x0002, 0x1a04, 0x39fe, 0xa6b4, + 0x00ff, 0x0904, 0x3da0, 0xa682, 0x0031, 0x1a04, 0x39fe, 0xa582, + 0x0009, 0x0a04, 0x39fe, 0xa882, 0x0003, 0x1a04, 0x39fe, 0xa886, + 0x0002, 0x01d0, 0xa886, 0x0000, 0x1904, 0x39fe, 0x2001, 0x000c, + 0x79ec, 0xd1e4, 0x0110, 0x2001, 0x000a, 0xa502, 0x1290, 0x080c, + 0x39fe, 0x00c6, 0x2960, 0x6004, 0xa085, 0x001a, 0x6006, 0x6000, + 0xc0ac, 0x6002, 0x00ce, 0x0005, 0xa786, 0x0000, 0x0904, 0x39fe, + 0x8634, 0xa682, 0x0018, 0x0228, 0x0120, 0x2031, 0x0018, 0x0804, + 0x3df1, 0xa686, 0x0010, 0x1108, 0x8630, 0x852b, 0x852b, 0x080c, + 0x3ac9, 0x0904, 0x39fe, 0x080c, 0x38f7, 0x080c, 0x399c, 0x7e58, + 0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005, 0x781b, 0x0083, 0x0005, + 0x080c, 0x38f4, 0x0c90, 0xa886, 0x0002, 0x1108, 0x8634, 0x7154, + 0xa188, 0x0000, 0x210c, 0xd1ac, 0x0904, 0x39fe, 0xd1ec, 0x1120, + 0x2039, 0x0000, 0x2041, 0x0000, 0xd1e4, 0x1120, 0x2031, 0x0000, + 0x2041, 0x0000, 0xa782, 0x0002, 0x12c8, 0x621c, 0xa284, 0x00ff, + 0xa706, 0x0110, 0x2039, 0x0000, 0xa605, 0x0190, 0x6108, 0x811f, + 0xa39c, 0x00ff, 0x0168, 0xa302, 0x1208, 0x2330, 0x8807, 0xa705, + 0xa086, 0x0201, 0x0160, 0xa886, 0x0000, 0x0168, 0x2039, 0x0000, + 0x2041, 0x0000, 0x2031, 0x0000, 0xa006, 0x2010, 0x0070, 0xa284, + 0xff00, 0x1108, 0x2040, 0xa184, 0x00ff, 0xa502, 0x0108, 0x2128, + 0x852b, 0x852b, 0x080c, 0x3ac9, 0x0d58, 0x080c, 0x38f7, 0x080c, + 0x399c, 0x789b, 0x0080, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab, + 0x0004, 0x7daa, 0x78ab, 0x0000, 0x7eaa, 0x7faa, 0x2800, 0x78aa, + 0x789b, 0x0060, 0x78ab, 0x0008, 0x6820, 0xc0e5, 0x6822, 0x080c, + 0x3a55, 0x7858, 0xc095, 0x785a, 0x781b, 0x0082, 0x0005, 0x0020, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, - 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0062, 0x0009, 0x0014, - 0x0014, 0x9855, 0x984d, 0x0014, 0x9911, 0x98ff, 0x0014, 0x0014, - 0x0090, 0x00e7, 0x0100, 0x0402, 0x2008, 0xf880, 0x0018, 0x0017, - 0x840f, 0xd8c1, 0x0014, 0x0016, 0xa20a, 0x0014, 0x300b, 0xa20c, - 0x0014, 0x2500, 0x0013, 0x2500, 0x0010, 0x0010, 0x0010, 0x0010, + 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, + 0x0020, 0x0062, 0x0009, 0x0014, 0x0014, 0x9855, 0x984d, 0x0014, + 0x9911, 0x98ff, 0x0014, 0x0014, 0x0090, 0x00e7, 0x0100, 0x0402, + 0x2008, 0xf880, 0x0018, 0x0017, 0x840f, 0xd8c1, 0x0014, 0x0016, + 0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014, 0x2500, 0x0013, 0x2500, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, - 0x0010, 0x0010, 0xa200, 0x3806, 0x8839, 0x20c4, 0x0864, 0xa84f, - 0x3008, 0x28c1, 0x9d18, 0xa201, 0x300c, 0x2847, 0x8161, 0x846a, - 0x8000, 0x84a4, 0x1856, 0x883a, 0xa808, 0x28e2, 0x9cce, 0xa8f3, - 0x0864, 0xa83d, 0x300c, 0xa801, 0x3008, 0x28e1, 0x9cce, 0x2021, - 0xa818, 0xa205, 0x870c, 0xd8de, 0x64a0, 0x6de0, 0x6fc0, 0x67a4, - 0x6c80, 0x0212, 0xa205, 0x883d, 0x882b, 0x1814, 0x883b, 0x7027, - 0x85f2, 0xa737, 0xa532, 0xf003, 0x8576, 0x8677, 0xa814, 0x883e, - 0xa812, 0x280a, 0xa204, 0x64c0, 0x6de0, 0x67a0, 0x6fc0, 0x1814, - 0x883b, 0x7027, 0x8576, 0x8677, 0xa806, 0x796d, 0xa8da, 0x796b, - 0xa8f1, 0x7861, 0x883e, 0x206b, 0x28c1, 0x9d18, 0x2044, 0x2103, - 0x20b4, 0x2095, 0xa8ca, 0xa207, 0x2901, 0xa80a, 0x0014, 0xa203, - 0x8000, 0x85a4, 0x1872, 0x879a, 0x883c, 0x1fe2, 0xf601, 0xa208, - 0x856e, 0x866f, 0x7121, 0x0014, 0x0704, 0x3008, 0x9cce, 0x0014, - 0xa202, 0x8000, 0x85a4, 0x3009, 0x84a8, 0x19e2, 0xf844, 0x856e, - 0x883f, 0x08e6, 0xa8f5, 0xf861, 0xa8ea, 0xf801, 0x0014, 0xf881, - 0x0016, 0x85b2, 0x80f0, 0x9532, 0xfaa2, 0x1de2, 0x0014, 0x8532, - 0xf221, 0x0014, 0x1de2, 0x84a8, 0xd6e0, 0x1fe6, 0x0014, 0x3008, - 0x8000, 0x2849, 0x1011, 0xa8fc, 0x3008, 0x8000, 0xa000, 0x2081, - 0x2802, 0x1011, 0xa8fc, 0xa889, 0x3008, 0x20a1, 0x283c, 0x1011, - 0xa8fc, 0xa209, 0x0017, 0x300c, 0x8000, 0x85a4, 0x1de2, 0xdac1, - 0x0014, 0x0210, 0xa801, 0x0014, 0x26e0, 0x873a, 0xfaa3, 0x19f2, - 0x26e0, 0x18f2, 0x0014, 0xa20b, 0x0014, 0xa20d, 0x3806, 0x0210, - 0x9d22, 0x0704, 0xa206, 0x6865, 0x817e, 0x842a, 0x1dc1, 0x8823, - 0x0016, 0x6042, 0x8008, 0xa8fa, 0x8160, 0x842a, 0x8180, 0xf021, - 0x3008, 0x84a8, 0x11d7, 0x7042, 0x20dd, 0x0011, 0x20d5, 0x8822, - 0x0016, 0x0000, 0x0126, 0x70d4, 0xa084, 0x4c00, 0x8004, 0x2090, - 0x7204, 0x7008, 0xc09c, 0xa205, 0x1178, 0x720c, 0x82ff, 0x0128, - 0x8aff, 0x1150, 0x7200, 0xd284, 0x1138, 0x7007, 0x0004, 0x7003, - 0x0008, 0x012e, 0x2000, 0x0005, 0x7000, 0xa084, 0x0003, 0x7002, - 0xc69c, 0xd084, 0x05b8, 0x2001, 0x4301, 0x2004, 0xd0b4, 0x0904, - 0x3dcf, 0x7108, 0xe000, 0x7008, 0xa106, 0x1dd8, 0xa184, 0x0003, - 0x0904, 0x3dcf, 0xa184, 0x01e0, 0x1904, 0x3dcf, 0xd1f4, 0x1d88, - 0xa184, 0x3000, 0xa086, 0x1000, 0x0d60, 0x2011, 0x0180, 0x710c, - 0x8211, 0x0130, 0x7008, 0xd0f4, 0x1d20, 0x700c, 0xa106, 0x0dc0, - 0x7007, 0x0012, 0x7108, 0xe000, 0x7008, 0xa106, 0x1dd8, 0xa184, - 0x0003, 0x0568, 0xd194, 0x0db0, 0xd1f4, 0x0548, 0x7007, 0x0002, - 0x0880, 0x0428, 0x7108, 0xd1fc, 0x0130, 0x080c, 0x3e9e, 0x8aff, - 0x0904, 0x3d58, 0x0cb8, 0x700c, 0xa08c, 0x07ff, 0x01e8, 0x7004, - 0xd084, 0x0178, 0x7014, 0xa005, 0x1148, 0x7010, 0x7310, 0xa306, - 0x1de0, 0x2300, 0xa005, 0x0128, 0xa102, 0x1e20, 0x7007, 0x0010, - 0x0030, 0x8aff, 0x0148, 0x080c, 0x4046, 0x1de8, 0x09d8, 0x080c, - 0x3e58, 0x012e, 0x2000, 0x0005, 0x7204, 0x7108, 0xc19c, 0x8103, - 0x1218, 0x080c, 0x3e9e, 0x0cc0, 0xa205, 0x1d88, 0x7007, 0x0004, - 0x7003, 0x0008, 0x012e, 0x2000, 0x0005, 0x6428, 0x84ff, 0x0508, - 0x2c70, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x3e19, 0x273c, 0x87fb, - 0x1148, 0x0210, 0x080c, 0x243b, 0x609c, 0xa075, 0x0190, 0x0c88, - 0x2039, 0x3e0e, 0x2704, 0xae68, 0x6808, 0xa630, 0x680c, 0xa529, - 0x8421, 0x0138, 0x8738, 0x2704, 0xa005, 0x1da8, 0x709c, 0xa075, - 0x1d00, 0x0005, 0x0000, 0x0005, 0x0009, 0x000d, 0x0011, 0x0015, - 0x0019, 0x001d, 0x0000, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b, - 0x0000, 0x0000, 0x3e0e, 0x3e0b, 0x0000, 0x0000, 0x8000, 0x0000, - 0x3e0e, 0x0000, 0x3e16, 0x3e13, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3e16, 0x0000, 0x3e11, 0x3e11, 0x0000, 0x0000, 0x8000, 0x0000, - 0x3e11, 0x0000, 0x3e17, 0x3e17, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3e17, 0x2079, 0x4300, 0x2071, 0x0010, 0x7007, 0x000a, 0x7007, - 0x0002, 0x7003, 0x0001, 0x2009, 0x0002, 0x2071, 0x0050, 0x7007, - 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2001, 0x01ff, 0x2004, - 0xd0fc, 0x1128, 0x8109, 0x0118, 0x2071, 0x0020, 0x0c80, 0x0005, - 0x7004, 0x8004, 0x1690, 0x7007, 0x0012, 0x2019, 0x0000, 0x7108, - 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0110, 0x080c, 0x243b, - 0xa19c, 0x300c, 0xa386, 0x2004, 0x0130, 0xa386, 0x0008, 0x0160, - 0xa386, 0x200c, 0x1d60, 0x7200, 0x8204, 0x0230, 0x730c, 0xa384, - 0x07ff, 0x0110, 0x080c, 0x243b, 0x7007, 0x0012, 0x7000, 0xd084, - 0x1160, 0x7008, 0xa084, 0x01e0, 0x1140, 0x7310, 0x7014, 0xa305, - 0x0120, 0x710c, 0xa184, 0x07ff, 0x1958, 0x7007, 0x0012, 0x7007, - 0x0008, 0x7004, 0xd09c, 0x1de8, 0x7007, 0x0012, 0x7108, 0x8103, - 0x0ed8, 0x7003, 0x0008, 0x0005, 0x7108, 0x0000, 0xa184, 0x01e0, - 0x1550, 0x7108, 0xa184, 0x01e0, 0x1530, 0xa184, 0x0007, 0x0002, - 0x3eb2, 0x3ec0, 0x3eb0, 0x3ec0, 0x3eb0, 0x3f06, 0x3eb0, 0x3f05, - 0x080c, 0x243b, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, - 0x1118, 0x2049, 0x0000, 0x0005, 0x080c, 0x4046, 0x1de8, 0x0005, - 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, 0x0118, 0x080c, - 0x4046, 0x1de8, 0x0005, 0x7007, 0x0012, 0x7108, 0x1d04, 0x3ece, - 0x2091, 0x6000, 0x1d04, 0x3ed2, 0x2091, 0x6000, 0x7007, 0x0012, - 0x7007, 0x0008, 0x7004, 0xd09c, 0x1de8, 0x7007, 0x0012, 0x7108, - 0xd1fc, 0x1dd8, 0x7003, 0x0000, 0x7000, 0xa005, 0x1130, 0x7004, - 0xa005, 0x1118, 0x700c, 0xa005, 0x0108, 0x0c40, 0x2049, 0x0000, - 0xb284, 0x0200, 0x0118, 0x2001, 0x0000, 0x0010, 0x2001, 0x0001, - 0x080c, 0x397f, 0x6818, 0xa084, 0x8000, 0x0110, 0x681b, 0x0002, - 0x0005, 0x080c, 0x243b, 0x080c, 0x243b, 0x04b9, 0x7210, 0x7114, - 0x700c, 0xa09c, 0x07ff, 0x2800, 0xa300, 0xa211, 0xa189, 0x0000, - 0x0461, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200, 0xa322, 0x630c, - 0x2100, 0xa31b, 0x2400, 0xa305, 0x0140, 0x1238, 0x8412, 0x8210, - 0x830a, 0xa189, 0x0000, 0x2b60, 0x0c58, 0x2b60, 0x8a07, 0x0006, - 0x6004, 0xa084, 0x0008, 0x0118, 0xa7ba, 0x3e13, 0x0010, 0xa7ba, - 0x3e0b, 0x000e, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92, 0x6b8e, - 0x7007, 0x0012, 0x080c, 0x3e58, 0x0005, 0x8a50, 0x8739, 0x2704, - 0xa004, 0x1168, 0x6000, 0xa064, 0x1108, 0x2d60, 0x6004, 0xa084, - 0x000f, 0xa080, 0x3e29, 0x203c, 0x87fb, 0x090c, 0x243b, 0x0005, - 0x0126, 0x00d6, 0x70d4, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, - 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90, 0x8057, 0xaad4, 0x00ff, - 0xa084, 0x00ff, 0x0006, 0x6804, 0xa084, 0x0008, 0x000e, 0x0118, - 0xa0b8, 0x3e13, 0x0010, 0xa0b8, 0x3e0b, 0xb284, 0x0200, 0x0110, - 0x7e20, 0x0008, 0x7e24, 0xa6b5, 0x000c, 0x681c, 0xd0b4, 0x0108, - 0xc685, 0x2400, 0xa305, 0x0520, 0x2c58, 0x2704, 0x6104, 0xac60, - 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e, 0xa184, 0x0008, - 0x0140, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014, 0xa081, 0x0000, - 0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c, 0x2300, 0xa203, - 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x080c, 0x4067, 0x0010, - 0x080c, 0x4046, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126, 0x00d6, - 0x70d4, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x7007, 0x0004, - 0x7004, 0xd094, 0x1de8, 0x7003, 0x0008, 0x012e, 0x2000, 0x0005, - 0x0126, 0x00d6, 0x70d4, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, - 0x7e20, 0xb284, 0x0200, 0x1108, 0x7e24, 0xa6b5, 0x000c, 0x681c, - 0xd0ac, 0x1118, 0xc685, 0x7003, 0x0000, 0x6828, 0x2050, 0x2d60, - 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x3e19, 0x273c, 0x87fb, 0x1138, - 0x0210, 0x080c, 0x243b, 0x689c, 0xa065, 0x0120, 0x0c88, 0x080c, - 0x4046, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126, 0x0006, 0x0016, - 0x00d6, 0x70d4, 0xa084, 0x4c00, 0x8004, 0x2090, 0x7e20, 0xb284, - 0x0200, 0x1108, 0x7e24, 0x00de, 0x003e, 0x004e, 0xa6b5, 0x000c, - 0x681c, 0xd0b4, 0x0128, 0xc685, 0x7003, 0x0000, 0x7007, 0x0004, - 0x2049, 0x3fe5, 0x6828, 0xa055, 0x05f0, 0x2d70, 0x2e60, 0x7004, - 0xa0bc, 0x000f, 0xa7b8, 0x3e19, 0x273c, 0x87fb, 0x1140, 0x0210, - 0x080c, 0x243b, 0x709c, 0xa075, 0x2060, 0x0568, 0x0c80, 0x2704, - 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0268, 0x8a51, 0x1110, - 0x080c, 0x243b, 0x8738, 0x2704, 0xa005, 0x1d90, 0x709c, 0xa075, - 0x2060, 0x01c8, 0x08e0, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, - 0x6908, 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, 0x1210, 0x080c, - 0x243b, 0xb284, 0x0200, 0x0118, 0x2071, 0x0050, 0x0010, 0x2071, - 0x0020, 0x0804, 0x3f79, 0x012e, 0x2000, 0x0005, 0x7008, 0xa084, - 0x0003, 0xa086, 0x0003, 0x1108, 0x0005, 0x2704, 0xac78, 0x7800, - 0x701a, 0x7804, 0x701e, 0x7808, 0x7012, 0x780c, 0x7016, 0x6004, - 0xa084, 0x0008, 0x0120, 0x7810, 0x7022, 0x7814, 0x7026, 0x7602, - 0x7004, 0xa084, 0x0010, 0xc085, 0x7006, 0x2079, 0x4300, 0x8a51, - 0x01b0, 0x8738, 0x2704, 0xa005, 0x1168, 0x609c, 0xa005, 0x0180, - 0x2060, 0x6004, 0xa084, 0x000f, 0xa080, 0x3e19, 0x203c, 0x87fb, - 0x090c, 0x243b, 0x7008, 0xa084, 0x0003, 0xa086, 0x0003, 0x0005, - 0x2051, 0x0000, 0x0005, 0x0126, 0x0006, 0x00d6, 0x70d4, 0xa084, - 0x4c00, 0x8004, 0x2090, 0x00de, 0x008e, 0x7108, 0xa184, 0x0003, - 0x1128, 0x6828, 0xa005, 0x0178, 0x0804, 0x3d6c, 0x7108, 0xd1fc, - 0x0118, 0x080c, 0x3e9e, 0x0c88, 0x7007, 0x0010, 0x7108, 0xd1fc, - 0x0de8, 0x080c, 0x3e9e, 0x7008, 0xa086, 0x0008, 0x1d30, 0x7000, - 0xa005, 0x1d18, 0x7003, 0x0000, 0x2049, 0x0000, 0x012e, 0x2000, - 0x0005, 0x0126, 0x0146, 0x0136, 0x0156, 0x00c6, 0x00d6, 0x70d4, - 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x2049, 0x40b1, 0xad80, - 0x0011, 0x20a0, 0xb284, 0x0200, 0x0118, 0x2099, 0x0032, 0x0010, - 0x2099, 0x0031, 0x700c, 0xa084, 0x07ff, 0x682a, 0x7007, 0x0008, - 0x7007, 0x0002, 0x7003, 0x0001, 0x0118, 0x8000, 0x80ac, 0x53a5, - 0x700c, 0xa084, 0x07ff, 0x0130, 0x7007, 0x0004, 0x7004, 0xa084, - 0x0004, 0x1de0, 0x00ce, 0x2049, 0x0000, 0x7003, 0x0000, 0x015e, - 0x013e, 0x014e, 0x012e, 0x2000, 0x0005, 0x2091, 0x8000, 0x2091, - 0x6000, 0x78ac, 0xa005, 0x1168, 0x7974, 0x70d0, 0xa106, 0x1148, - 0x781c, 0xa005, 0x0130, 0x781f, 0x0000, 0x0e04, 0x4101, 0x2091, - 0x4080, 0x7830, 0x8001, 0x7832, 0x1904, 0x416b, 0x7834, 0x7832, - 0x2061, 0x68c0, 0x2069, 0x4380, 0xc7fd, 0x68d0, 0xa005, 0x0128, - 0x8001, 0x68d2, 0x1110, 0x080c, 0x42c4, 0x6800, 0xa084, 0x000f, - 0x0168, 0xa086, 0x0001, 0x0150, 0x6844, 0xa00d, 0x0138, 0x2104, - 0xa005, 0x0120, 0x8001, 0x200a, 0x0904, 0x425f, 0x6814, 0xa005, - 0x01a8, 0x8001, 0x6816, 0x1190, 0x68a7, 0x0001, 0x00f6, 0xd7fc, - 0x1118, 0x2079, 0x0200, 0x0010, 0x2079, 0x0100, 0x080c, 0x3aa0, - 0x00fe, 0x6864, 0xa005, 0x0110, 0x080c, 0x2233, 0x6880, 0xa005, - 0x0140, 0x8001, 0x6882, 0x1128, 0x6867, 0x0000, 0x68d4, 0xc0c5, - 0x68d6, 0x68d4, 0xd0fc, 0x01b0, 0xc0fc, 0x68d6, 0x20a9, 0x0200, - 0x6034, 0xa005, 0x0158, 0x8001, 0x6036, 0x68d4, 0xc0fd, 0x68d6, - 0x1128, 0x6010, 0xa005, 0x0110, 0x080c, 0x2233, 0xace0, 0x0010, - 0x1f04, 0x4150, 0xd7fc, 0x0138, 0x2061, 0x48c0, 0x2069, 0x4340, - 0xc7fc, 0x0804, 0x410d, 0x0459, 0x7838, 0x8001, 0x783a, 0x11a0, - 0x783c, 0x783a, 0x2061, 0x48c0, 0x2069, 0x4340, 0xc7fc, 0x680c, - 0xa005, 0x0110, 0x080c, 0x41c9, 0xd7fc, 0x1130, 0x2061, 0x68c0, - 0x2069, 0x4380, 0xc7fd, 0x0c98, 0x7810, 0xd0cc, 0x0168, 0xd0ac, + 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0xa200, 0x3806, + 0x8839, 0x20c4, 0x0864, 0xa850, 0x3008, 0x28c1, 0x9d18, 0xa201, + 0x300c, 0x2847, 0x8161, 0x846a, 0x8000, 0x84a4, 0x1856, 0x883a, + 0xa808, 0x28e2, 0x9cce, 0xa8f3, 0x0864, 0xa83e, 0x300c, 0xa801, + 0x3008, 0x28e1, 0x9cce, 0x28a2, 0x7163, 0xa831, 0x2021, 0xa818, + 0xa205, 0x870c, 0xd8de, 0x64a0, 0x6de0, 0x6fc0, 0x67a4, 0x6c80, + 0x0212, 0xa205, 0x883d, 0x882b, 0x1814, 0x883b, 0x7027, 0x85f2, + 0xa737, 0xa532, 0xf003, 0x8576, 0x8677, 0xa813, 0x883e, 0xa811, + 0x2882, 0x7162, 0xa814, 0x280a, 0xa204, 0x64c0, 0x6de0, 0x67a0, + 0x6fc0, 0x1814, 0x883b, 0x7023, 0x8576, 0x8677, 0xa802, 0x7861, + 0x883e, 0x206a, 0x28c1, 0x9d18, 0x2042, 0x2101, 0xa8ca, 0x2902, + 0xa20e, 0xa80b, 0xa207, 0x0014, 0xa203, 0x8000, 0x85a4, 0x1872, + 0x879a, 0x883c, 0x1fe2, 0xf601, 0xa208, 0x856e, 0x7121, 0x0014, + 0x0704, 0x3008, 0x9cce, 0x0014, 0xa202, 0x8000, 0x85a4, 0x3009, + 0x84a8, 0x19e2, 0xf844, 0x856e, 0x883f, 0x08e6, 0xa8f5, 0xf861, + 0xa8eb, 0xf801, 0x0014, 0xf881, 0x0016, 0x85b2, 0x80f0, 0x9532, + 0xfaa2, 0x1de2, 0x0014, 0x8532, 0xf221, 0x0014, 0x1de2, 0x84a8, + 0xd6e0, 0x1fe6, 0x0014, 0x3008, 0x8000, 0x2849, 0x1011, 0xa8fc, + 0x3008, 0x8000, 0xa000, 0x2081, 0x2802, 0x1011, 0xa8fc, 0xa889, + 0x3008, 0x20a1, 0x283c, 0x1011, 0xa8fc, 0xa209, 0x0017, 0x300c, + 0x8000, 0x85a4, 0x1de2, 0xdac1, 0x0014, 0x0210, 0xa801, 0x0014, + 0x26e0, 0x873a, 0xfaa3, 0x19f2, 0x26e0, 0x18f2, 0x0014, 0xa20b, + 0x0014, 0xa20d, 0x3806, 0x0210, 0x9d22, 0x0704, 0xa206, 0x6865, + 0x817e, 0x842a, 0x1dc1, 0x8823, 0x0016, 0x6042, 0x8008, 0xa8fa, + 0x8160, 0x842a, 0x8180, 0xf021, 0x3008, 0x84a8, 0x11d7, 0x7042, + 0x20dd, 0x0011, 0x20d5, 0x8822, 0x0016, 0x0000, 0x0126, 0x70d0, + 0xa084, 0x4c00, 0x8004, 0x2090, 0x7204, 0x7008, 0xc09c, 0xa205, + 0x11a0, 0x720c, 0x82ff, 0x0128, 0x8aff, 0x1178, 0x7200, 0xd284, + 0x1160, 0x7804, 0xd0cc, 0x0110, 0x080c, 0x4328, 0x7007, 0x0008, + 0x7003, 0x0008, 0x012e, 0x2000, 0x0005, 0x7000, 0xa084, 0x0003, + 0x7002, 0xc69c, 0xd084, 0x0588, 0x7108, 0xe000, 0x7008, 0xa106, + 0x1dd8, 0xa184, 0x0003, 0x0904, 0x3fa2, 0xa184, 0x01e0, 0x1904, + 0x3fa2, 0xd1f4, 0x1d88, 0xa184, 0x3000, 0xa086, 0x1000, 0x0d60, + 0x2011, 0x0180, 0x710c, 0x8211, 0x0130, 0x7008, 0xd0f4, 0x1d20, + 0x700c, 0xa106, 0x0dc0, 0x7007, 0x0012, 0x7108, 0xe000, 0x7008, + 0xa106, 0x1dd8, 0xa184, 0x0003, 0x0568, 0xd194, 0x0db0, 0xd1f4, + 0x0548, 0x7007, 0x0002, 0x0880, 0x0428, 0x7108, 0xd1fc, 0x0130, + 0x080c, 0x40ae, 0x8aff, 0x0904, 0x3f2c, 0x0cb8, 0x700c, 0xa08c, + 0x07ff, 0x01e8, 0x7004, 0xd084, 0x0178, 0x7014, 0xa005, 0x1148, + 0x7010, 0x7310, 0xa306, 0x1de0, 0x2300, 0xa005, 0x0128, 0xa102, + 0x1e20, 0x7007, 0x0010, 0x0030, 0x8aff, 0x0148, 0x080c, 0x426b, + 0x1de8, 0x09d8, 0x080c, 0x4034, 0x012e, 0x2000, 0x0005, 0x7204, + 0x7108, 0xc19c, 0x8103, 0x1218, 0x7007, 0x0002, 0x0cc0, 0xa205, + 0x1d88, 0x7007, 0x0008, 0x7003, 0x0008, 0x0006, 0x2001, 0x4601, + 0x2004, 0xd0cc, 0x0110, 0x080c, 0x4328, 0x000e, 0x012e, 0x2000, + 0x0005, 0x6428, 0x84ff, 0x0508, 0x2c70, 0x7004, 0xa0bc, 0x000f, + 0xa7b8, 0x3ff5, 0x273c, 0x87fb, 0x1148, 0x0210, 0x080c, 0x254c, + 0x609c, 0xa075, 0x0190, 0x0c88, 0x2039, 0x3fea, 0x2704, 0xae68, + 0x6808, 0xa630, 0x680c, 0xa529, 0x8421, 0x0138, 0x8738, 0x2704, + 0xa005, 0x1da8, 0x709c, 0xa075, 0x1d00, 0x0005, 0x0000, 0x0005, + 0x0009, 0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, 0x0003, + 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x3fea, 0x3fe7, + 0x0000, 0x0000, 0x8000, 0x0000, 0x3fea, 0x0000, 0x3ff2, 0x3fef, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3ff2, 0x0000, 0x3fed, 0x3fed, + 0x0000, 0x0000, 0x8000, 0x0000, 0x3fed, 0x0000, 0x3ff3, 0x3ff3, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3ff3, 0x2079, 0x4600, 0x2071, + 0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0001, 0x2009, + 0x0002, 0x2071, 0x0050, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, + 0x0000, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1128, 0x8109, 0x0118, + 0x2071, 0x0020, 0x0c80, 0x0005, 0x7004, 0x8004, 0x1a04, 0x408a, + 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0120, 0x080c, + 0x40e6, 0x0804, 0x40aa, 0x7007, 0x0012, 0x2019, 0x0000, 0x7108, + 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0120, 0x080c, 0x40e6, + 0x0804, 0x40aa, 0xa19c, 0x300c, 0xa386, 0x2004, 0x0190, 0xa386, + 0x0008, 0x01c0, 0x7004, 0xd084, 0x1148, 0x7108, 0x7008, 0xa106, + 0x1de0, 0xa184, 0x0003, 0x0110, 0x0804, 0x40e6, 0xa386, 0x200c, + 0x19f0, 0x7200, 0x8204, 0x0230, 0x730c, 0xa384, 0x07ff, 0x0110, + 0x080c, 0x254c, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, + 0x0118, 0x080c, 0x40e6, 0x0470, 0x7007, 0x0012, 0x7000, 0xd084, + 0x1148, 0x7310, 0x7014, 0xa305, 0x0128, 0x710c, 0xa184, 0x07ff, + 0x1904, 0x4034, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, + 0x0118, 0x080c, 0x40e6, 0x00b0, 0x7007, 0x0012, 0x7007, 0x0008, + 0x7004, 0xd09c, 0x1de8, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, + 0x01e0, 0x0118, 0x080c, 0x40e6, 0x0028, 0x7007, 0x0012, 0x7108, + 0x8103, 0x0e88, 0x7003, 0x0008, 0x0005, 0x7108, 0xa184, 0x01e0, + 0x15a8, 0x7108, 0xa184, 0x01e0, 0x1588, 0xa184, 0x0007, 0x0002, + 0x40c2, 0x40d0, 0x40c0, 0x40d0, 0x40c0, 0x4120, 0x40c0, 0x411e, + 0x080c, 0x254c, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, + 0x1118, 0x2049, 0x0000, 0x0005, 0x080c, 0x426b, 0x1de8, 0x0005, + 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x7004, 0xd084, 0x1140, + 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x0003, 0x0108, 0x0030, + 0x8aff, 0x0118, 0x080c, 0x426b, 0x1de8, 0x0005, 0x7007, 0x0012, + 0x7108, 0x1d04, 0x40e9, 0x2091, 0x6000, 0x1d04, 0x40ed, 0x2091, + 0x6000, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xd09c, 0x1de8, + 0x7007, 0x0012, 0x7108, 0xd1fc, 0x1dd8, 0x7003, 0x0000, 0x7000, + 0xa005, 0x1130, 0x7004, 0xa005, 0x1118, 0x700c, 0xa005, 0x0108, + 0x0c40, 0x2049, 0x0000, 0xb284, 0x0200, 0x0118, 0x2001, 0x0000, + 0x0010, 0x2001, 0x0001, 0x080c, 0x3b81, 0x681b, 0x0002, 0x2051, + 0x0000, 0x0005, 0x080c, 0x254c, 0x080c, 0x254c, 0x080c, 0x415f, + 0x7210, 0x7114, 0x700c, 0xa09c, 0x07ff, 0x2800, 0xa300, 0xa211, + 0xa189, 0x0000, 0x04a1, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200, + 0xa322, 0x630c, 0x2100, 0xa31b, 0x2400, 0xa305, 0x0140, 0x1238, + 0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0c58, 0x2b60, + 0x8a07, 0x0006, 0x6004, 0xd09c, 0x0118, 0xa7ba, 0x3fef, 0x0010, + 0xa7ba, 0x3fe7, 0x000e, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92, + 0x6b8e, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0110, + 0x080c, 0x40e6, 0x7007, 0x0012, 0x080c, 0x4034, 0x0005, 0x8a50, + 0x8739, 0x2704, 0xa004, 0x1168, 0x6000, 0xa064, 0x1108, 0x2d60, + 0x6004, 0xa084, 0x000f, 0xa080, 0x4005, 0x203c, 0x87fb, 0x090c, + 0x254c, 0x0005, 0x0126, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, + 0x2090, 0x00de, 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90, 0x8057, + 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x0006, 0x6804, 0xa084, 0x0008, + 0x000e, 0x0118, 0xa0b8, 0x3fef, 0x0010, 0xa0b8, 0x3fe7, 0xb284, + 0x0200, 0x0110, 0x7e20, 0x0008, 0x7e24, 0xa6b5, 0x000c, 0x681c, + 0xd0b4, 0x0108, 0xc685, 0x2400, 0xa305, 0x0518, 0x2c58, 0x2704, + 0x6104, 0xac60, 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e, + 0xd19c, 0x0140, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014, 0xa081, + 0x0000, 0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c, 0x2300, + 0xa203, 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x080c, 0x4292, + 0x0010, 0x080c, 0x426b, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126, + 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x7007, + 0x0004, 0x7004, 0xd094, 0x1de8, 0x7003, 0x0008, 0x012e, 0x2000, + 0x0005, 0x0126, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, + 0x00de, 0x7e20, 0xb284, 0x0200, 0x1108, 0x7e24, 0xa6b5, 0x000c, + 0x681c, 0xd0ac, 0x1118, 0xc685, 0x7003, 0x0000, 0x6828, 0x2050, + 0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x3ff5, 0x273c, 0x87fb, + 0x1138, 0x0210, 0x080c, 0x254c, 0x689c, 0xa065, 0x0120, 0x0c88, + 0x080c, 0x426b, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126, 0x0006, + 0x0016, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x7e20, + 0xb284, 0x0200, 0x1108, 0x7e24, 0x00de, 0x003e, 0x004e, 0xa6b5, + 0x000c, 0x681c, 0xd0b4, 0x0128, 0xc685, 0x7003, 0x0000, 0x7007, + 0x0004, 0x2049, 0x4206, 0x6828, 0xa055, 0x00d6, 0x0904, 0x4267, + 0x2d70, 0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x3ff5, 0x273c, + 0x87fb, 0x1140, 0x0210, 0x080c, 0x254c, 0x709c, 0xa075, 0x2060, + 0x0570, 0x0c80, 0x2704, 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, + 0x0268, 0x8a51, 0x1110, 0x080c, 0x254c, 0x8738, 0x2704, 0xa005, + 0x1d90, 0x709c, 0xa075, 0x2060, 0x01d0, 0x08e0, 0x8422, 0x8420, + 0x831a, 0xa399, 0x0000, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300, + 0xa11b, 0x1210, 0x080c, 0x254c, 0xb284, 0x0200, 0x0118, 0x2071, + 0x0050, 0x0010, 0x2071, 0x0020, 0x00de, 0x0804, 0x419b, 0x00de, + 0x012e, 0x2000, 0x0005, 0x7008, 0x0006, 0xa084, 0x01e0, 0x000e, + 0x0110, 0xa006, 0x0005, 0xa084, 0x0003, 0xa086, 0x0003, 0x1108, + 0x0005, 0x2704, 0xac78, 0x7800, 0x701a, 0x7804, 0x701e, 0x7808, + 0x7012, 0x780c, 0x7016, 0x6004, 0xd09c, 0x0120, 0x7810, 0x7022, + 0x7814, 0x7026, 0x7602, 0x7004, 0xa084, 0x0010, 0xc085, 0x7006, + 0x2079, 0x4600, 0x8a51, 0x01e8, 0x8738, 0x2704, 0xa005, 0x1168, + 0x609c, 0xa005, 0x01b8, 0x2060, 0x6004, 0xa084, 0x000f, 0xa080, + 0x3ff5, 0x203c, 0x87fb, 0x090c, 0x254c, 0x7008, 0x0006, 0xa084, + 0x01e0, 0x000e, 0x0110, 0xa006, 0x0028, 0xa084, 0x0003, 0xa086, + 0x0003, 0x0005, 0x2051, 0x0000, 0x0005, 0x0126, 0x0006, 0x00d6, + 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x008e, 0x7108, + 0xa184, 0x0003, 0x1128, 0x6828, 0xa005, 0x0178, 0x0804, 0x3f45, + 0x7108, 0xd1fc, 0x0118, 0x080c, 0x40ae, 0x0c88, 0x7007, 0x0010, + 0x7108, 0xd1fc, 0x0de8, 0x080c, 0x40ae, 0x7008, 0xa086, 0x0008, + 0x1d30, 0x7000, 0xa005, 0x1d18, 0x7003, 0x0000, 0x2049, 0x0000, + 0x0006, 0x2001, 0x4601, 0x2004, 0xd0cc, 0x0110, 0x080c, 0x4328, + 0x000e, 0x012e, 0x2000, 0x0005, 0x0126, 0x0146, 0x0136, 0x0156, + 0x00c6, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, + 0x2049, 0x42ec, 0xad80, 0x0011, 0x20a0, 0xb284, 0x0200, 0x0118, + 0x2099, 0x0032, 0x0010, 0x2099, 0x0031, 0x700c, 0xa084, 0x07ff, + 0x682a, 0x7007, 0x0008, 0x7007, 0x0002, 0x7003, 0x0001, 0x0118, + 0x8000, 0x80ac, 0x53a5, 0x700c, 0xa084, 0x07ff, 0x0130, 0x7007, + 0x0004, 0x7004, 0xa084, 0x0004, 0x1de0, 0x00ce, 0x2049, 0x0000, + 0x7003, 0x0000, 0x015e, 0x013e, 0x014e, 0x012e, 0x2000, 0x0005, + 0x6814, 0xd0fc, 0x0904, 0x436b, 0x7000, 0xd084, 0x05e0, 0x7e24, + 0xa6b5, 0x0004, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x1de0, + 0x7118, 0x0016, 0x711c, 0x0016, 0x7120, 0x0016, 0x7124, 0x0016, + 0x701b, 0x0000, 0x701f, 0x3fff, 0x7023, 0x0000, 0x7027, 0x0000, + 0x7013, 0x0004, 0x7017, 0x0000, 0x7602, 0x7007, 0x0001, 0x2001, + 0xffff, 0x2009, 0x0031, 0x200a, 0x200a, 0x7108, 0x7008, 0xa106, + 0x1de0, 0xd1fc, 0x0dd0, 0x002e, 0x7226, 0x002e, 0x7222, 0x002e, + 0x721e, 0x002e, 0x721a, 0x7007, 0x0002, 0x7008, 0xa086, 0x0008, + 0x0110, 0x0804, 0x40e6, 0x7007, 0x0004, 0x7003, 0x0000, 0x0005, + 0x2091, 0x8000, 0x2091, 0x6000, 0x78ac, 0xa005, 0x1168, 0x7974, + 0x70d0, 0xa106, 0x1148, 0x781c, 0xa005, 0x0130, 0x781f, 0x0000, + 0x0e04, 0x4384, 0x2091, 0x4080, 0x2069, 0x4680, 0xd7fc, 0x1110, + 0x2069, 0x4640, 0x6800, 0xa084, 0x000f, 0x1198, 0x68d0, 0xd0b4, + 0x0180, 0xd0bc, 0x1170, 0x00f6, 0x2079, 0x0100, 0xd7fc, 0x1110, + 0x2079, 0x0200, 0x7830, 0xa084, 0x00c0, 0x1110, 0x080c, 0x22ae, + 0x00fe, 0x7830, 0x8001, 0x7832, 0x1904, 0x440b, 0x7834, 0x7832, + 0x2061, 0x6bc0, 0x2069, 0x4680, 0xc7fd, 0x68cc, 0xa005, 0x0128, + 0x8001, 0x68ce, 0x1110, 0x080c, 0x4577, 0x6800, 0xa084, 0x000f, + 0x0168, 0xa086, 0x0001, 0x0150, 0x6840, 0xa00d, 0x0138, 0x2104, + 0xa005, 0x0120, 0x8001, 0x200a, 0x0904, 0x4514, 0x6814, 0xa005, + 0x01a8, 0x8001, 0x6816, 0x1190, 0x68a3, 0x0001, 0x00f6, 0xd7fc, + 0x1118, 0x2079, 0x0200, 0x0010, 0x2079, 0x0100, 0x080c, 0x3c46, + 0x00fe, 0x6860, 0xa005, 0x0110, 0x080c, 0x22ae, 0x687c, 0xa005, + 0x0140, 0x8001, 0x687e, 0x1128, 0x6863, 0x0000, 0x68d0, 0xc0c5, + 0x68d2, 0x68d0, 0xd0fc, 0x01b0, 0xc0fc, 0x68d2, 0x20a9, 0x0200, + 0x6034, 0xa005, 0x0158, 0x8001, 0x6036, 0x68d0, 0xc0fd, 0x68d2, + 0x1128, 0x6010, 0xa005, 0x0110, 0x080c, 0x22ae, 0xace0, 0x0010, + 0x1f04, 0x43f0, 0xd7fc, 0x0138, 0x2061, 0x4bc0, 0x2069, 0x4640, + 0xc7fc, 0x0804, 0x43ad, 0x0459, 0x7838, 0x8001, 0x783a, 0x11a0, + 0x783c, 0x783a, 0x2061, 0x4bc0, 0x2069, 0x4640, 0xc7fc, 0x680c, + 0xa005, 0x0110, 0x080c, 0x4487, 0xd7fc, 0x1130, 0x2061, 0x6bc0, + 0x2069, 0x4680, 0xc7fd, 0x0c98, 0x7810, 0xd0cc, 0x0168, 0xd0ac, 0x1120, 0xd0a4, 0x0148, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0e04, - 0x4193, 0x080c, 0x1ffe, 0x0005, 0x2091, 0x8001, 0x0005, 0x7840, - 0x8001, 0x7842, 0x1568, 0x7844, 0x7842, 0x2091, 0x8000, 0x2061, - 0x48c0, 0x2069, 0x4340, 0xc7fc, 0x6810, 0xa005, 0x1110, 0x2001, - 0x0101, 0x8001, 0x6812, 0xd7fc, 0x0118, 0xa080, 0x89d0, 0x0010, - 0xa080, 0x88c0, 0x2040, 0x2004, 0xa065, 0x0150, 0x6024, 0xa005, - 0x0120, 0x8001, 0x6026, 0x0904, 0x4207, 0x6000, 0x2c40, 0x0ca0, - 0xd7fc, 0x1130, 0x2061, 0x68c0, 0x2069, 0x4380, 0xc7fd, 0x08e0, - 0x0005, 0x2009, 0x0000, 0x20a9, 0x0200, 0x6008, 0xd09c, 0x0540, - 0x6024, 0xa005, 0x0118, 0x8001, 0x6026, 0x0400, 0x6008, 0xc09c, - 0xd084, 0x1110, 0xd0ac, 0x01a8, 0x600a, 0x6004, 0xa06d, 0x01c0, - 0x00c6, 0x0016, 0x6010, 0x8001, 0x6012, 0x080c, 0x35ab, 0x2d00, - 0x2c68, 0x2060, 0x080c, 0x1b85, 0x080c, 0x1d30, 0x001e, 0x00ce, - 0x0038, 0xc0bd, 0x600a, 0xa18d, 0x0001, 0x0010, 0xa18d, 0x0100, - 0xace0, 0x0010, 0x1f04, 0x41cd, 0xa184, 0x0001, 0x0130, 0xa18c, - 0xfffe, 0x690e, 0x080c, 0x2233, 0x0008, 0x690e, 0x0005, 0x6800, - 0xa005, 0x0120, 0x684c, 0xac06, 0x0904, 0x425f, 0x6864, 0xa005, - 0x0120, 0x6027, 0x0001, 0x0804, 0x425c, 0x2c00, 0x687e, 0x6714, - 0x6f76, 0x6017, 0x0000, 0x602b, 0x0000, 0x601b, 0x0006, 0x60b4, - 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0060, - 0x6022, 0x6000, 0x2042, 0x080c, 0x1b1d, 0x6818, 0xa005, 0x0110, + 0x4433, 0x080c, 0x207a, 0x0005, 0x2091, 0x8001, 0x0005, 0x7840, + 0x8001, 0x7842, 0x1904, 0x4486, 0x7844, 0x7842, 0x2069, 0x4640, + 0xc7fc, 0x2079, 0x0200, 0x68d4, 0xa005, 0x0138, 0x7de0, 0xa504, + 0x1120, 0x68d6, 0x68d0, 0xc0bc, 0x68d2, 0x2079, 0x4600, 0x6810, + 0xa005, 0x1110, 0x2001, 0x0101, 0x8001, 0x6812, 0xd7fc, 0x0118, + 0xa080, 0x8cd0, 0x0010, 0xa080, 0x8bc0, 0x2040, 0x2004, 0xa065, + 0x01e0, 0x6024, 0xa005, 0x01b0, 0x8001, 0x6026, 0x1198, 0x6800, + 0xa005, 0x0130, 0x6848, 0xac06, 0x1118, 0x080c, 0x4514, 0x0068, + 0x6860, 0xa005, 0x0118, 0x6027, 0x0001, 0x0020, 0x080c, 0x44c8, + 0x2804, 0x0c28, 0x6000, 0x2c40, 0x0c10, 0xd7fc, 0x1138, 0x2069, + 0x4680, 0xc7fd, 0x2079, 0x0100, 0x0804, 0x4443, 0x0005, 0x2009, + 0x0000, 0x20a9, 0x0200, 0x6008, 0xd09c, 0x0558, 0x6024, 0xa005, + 0x0118, 0x8001, 0x6026, 0x0418, 0x6008, 0xc09c, 0xd084, 0x1110, + 0xd0ac, 0x01c0, 0x600a, 0x6004, 0xa005, 0x01d8, 0x00d6, 0x00c6, + 0x0016, 0x2068, 0x6010, 0x8001, 0x6012, 0x080c, 0x37a4, 0x2d00, + 0x2c68, 0x2060, 0x080c, 0x1be3, 0x080c, 0x1d95, 0x001e, 0x00ce, + 0x00de, 0x0038, 0xc0bd, 0x600a, 0xa18d, 0x0001, 0x0010, 0xa18d, + 0x0100, 0xace0, 0x0010, 0x1f04, 0x448b, 0xa184, 0x0001, 0x0130, + 0xa18c, 0xfffe, 0x690e, 0x080c, 0x22ae, 0x0008, 0x690e, 0x0005, + 0x2c00, 0x687a, 0x6714, 0x6f72, 0x6017, 0x0000, 0x602b, 0x0000, + 0x601b, 0x0006, 0x60b4, 0xa084, 0x5f00, 0x601e, 0x6020, 0xa084, + 0x00ff, 0xa085, 0x0060, 0x6022, 0x6000, 0x2042, 0x6858, 0xac06, + 0x1110, 0x2800, 0x685a, 0x080c, 0x1b7b, 0x6818, 0xa005, 0x0110, 0x8001, 0x681a, 0x6808, 0xc0a4, 0x680a, 0x6810, 0x7908, 0x8109, - 0x790a, 0x8001, 0x1310, 0x080c, 0x243b, 0x6812, 0x1118, 0x7910, + 0x790a, 0x8001, 0x1310, 0x080c, 0x254c, 0x6812, 0x1118, 0x7910, 0xc1a5, 0x7912, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x080c, - 0x1d3d, 0xd7fc, 0x1118, 0x2069, 0x4340, 0x0010, 0x2069, 0x4380, - 0x6910, 0xa184, 0x0100, 0x2001, 0x0006, 0x1118, 0x697a, 0x2001, - 0x0004, 0x2708, 0x080c, 0x2228, 0x2091, 0x8001, 0x0005, 0x00d6, - 0x694c, 0x2160, 0xd7fc, 0x1118, 0x2069, 0x0200, 0x0010, 0x2069, - 0x0100, 0x080c, 0x23e1, 0x601b, 0x0006, 0x6858, 0xa084, 0x3f00, - 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0048, 0x6022, 0x602f, - 0x0000, 0x6033, 0x0000, 0x6830, 0xd0b4, 0x01b0, 0x684b, 0x0004, - 0x20a9, 0x0014, 0x6848, 0xd094, 0x0110, 0x1f04, 0x4282, 0x684b, - 0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, 0x0110, 0x1f04, 0x428b, - 0x20a9, 0x00fa, 0x1f04, 0x4292, 0x6808, 0xa084, 0xfffd, 0x680a, - 0x681b, 0x0054, 0x00de, 0x6867, 0x0007, 0x2091, 0x8001, 0x0005, - 0x2079, 0x4300, 0x00e1, 0x0089, 0x00a9, 0x2009, 0x0002, 0x2069, - 0x4380, 0x680f, 0x0000, 0x6813, 0x0000, 0x6817, 0x0000, 0x8109, - 0x0118, 0x2069, 0x4340, 0x0ca8, 0x0005, 0x2019, 0x00a3, 0x7b3a, - 0x7b3e, 0x0005, 0x2019, 0x0033, 0x7b42, 0x7b46, 0x0005, 0x2019, - 0x32dd, 0x7b32, 0x7b36, 0x0005, 0x6950, 0xa185, 0x0000, 0x0178, - 0x00c6, 0x6ac0, 0x2264, 0x602b, 0x0000, 0x602f, 0x0000, 0x6008, - 0xc0b5, 0x600a, 0x8210, 0x8109, 0x1da8, 0x6952, 0x00ce, 0x0005, - 0x70ec, 0xd0dc, 0x1118, 0xd0d4, 0x0180, 0x0088, 0xae8e, 0x0100, - 0x0130, 0x7814, 0xc0f5, 0x7816, 0xd0d4, 0x1170, 0x0050, 0x7814, - 0xc0fd, 0x7816, 0xd0d4, 0x1140, 0x0020, 0xd0e4, 0x0138, 0x70a0, - 0x70a2, 0x7804, 0xd08c, 0x0110, 0x681f, 0x000c, 0x0005, 0xaf67 + 0x1da2, 0xd7fc, 0x1118, 0x2069, 0x4640, 0x0010, 0x2069, 0x4680, + 0x6910, 0xa184, 0x0100, 0x2001, 0x0006, 0x1118, 0x6976, 0x2001, + 0x0004, 0x080c, 0x22a4, 0x0005, 0x00d6, 0x6948, 0x2160, 0xd7fc, + 0x1118, 0x2069, 0x0200, 0x0010, 0x2069, 0x0100, 0x080c, 0x2467, + 0x601b, 0x0006, 0x6858, 0xa084, 0x5f00, 0x601e, 0x6020, 0xa084, + 0x00ff, 0xa085, 0x0048, 0x6022, 0x602f, 0x0000, 0x6033, 0x0000, + 0x6808, 0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4, 0x01b0, 0x684b, + 0x0004, 0x20a9, 0x0014, 0x6848, 0xd094, 0x0110, 0x1f04, 0x453b, + 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, 0x0110, 0x1f04, + 0x4544, 0x20a9, 0x00fa, 0x1f04, 0x454b, 0x681b, 0x0054, 0x00de, + 0x6863, 0x0007, 0x0005, 0x2079, 0x4600, 0x00e1, 0x0089, 0x00a9, + 0x2009, 0x0002, 0x2069, 0x4680, 0x680f, 0x0000, 0x6813, 0x0000, + 0x6817, 0x0000, 0x8109, 0x0118, 0x2069, 0x4640, 0x0ca8, 0x0005, + 0x2019, 0x00a3, 0x7b3a, 0x7b3e, 0x0005, 0x2019, 0x0033, 0x7b42, + 0x7b46, 0x0005, 0x2019, 0x32dd, 0x7b32, 0x7b36, 0x0005, 0x6a4c, + 0xa285, 0x0000, 0x01f0, 0x6950, 0x6bbc, 0xa300, 0x00c6, 0x2164, + 0x6304, 0x83ff, 0x1138, 0x8211, 0x0148, 0x8108, 0xa11a, 0x0eb8, + 0x69bc, 0x0ca8, 0x68cf, 0x000a, 0x00ce, 0x0005, 0x694c, 0x6abc, + 0x2264, 0x6008, 0xc0b5, 0x600a, 0x8210, 0x8109, 0x1dc8, 0x694e, + 0x00ce, 0x0005, 0x1d04, 0x459a, 0x2091, 0x6000, 0x1d04, 0x459e, + 0x2091, 0x6000, 0x70ec, 0xd0dc, 0x1118, 0xd0d4, 0x0190, 0x0098, + 0xae8e, 0x0100, 0x0138, 0x7814, 0xc0f5, 0xc0c5, 0x7816, 0xd0d4, + 0x1578, 0x0458, 0x7814, 0xc0fd, 0xc0c5, 0x7816, 0xd0d4, 0x1540, + 0x0420, 0xd0e4, 0x0538, 0x1d04, 0x45bb, 0x2091, 0x6000, 0x2009, + 0x000c, 0x1d04, 0x45c1, 0x2091, 0x6000, 0x8109, 0x1dd0, 0x70e4, + 0xa084, 0x01ff, 0xa086, 0x01ff, 0x1110, 0x70ec, 0x08c8, 0xae8e, + 0x0100, 0x0128, 0x7814, 0xc0f4, 0xd0fc, 0x1130, 0x0020, 0x7814, + 0xc0fc, 0xd0f4, 0x1108, 0xc0c4, 0x7816, 0x7804, 0xd08c, 0x0110, + 0x681f, 0x000c, 0x70a0, 0x70a2, 0x0005, 0x7c12 }; #ifdef UNIQUE_FW_NAME -unsigned short fw12160i_length01 = 0x32f8; +unsigned short fw12160i_length01 = 0x35e6; #else -unsigned short risc_code_length01 = 0x32f8; +unsigned short risc_code_length01 = 0x35e6; #endif - Index: drivers/scsi/ql1280_fw.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/ql1280_fw.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/ql1280_fw.h 22 Jul 2004 19:50:07 -0000 1.1 +++ drivers/scsi/ql1280_fw.h 4 Aug 2004 01:29:36 -0000 1.2 @@ -1,59 +1,74 @@ +/***************************************************************************** + * QLOGIC LINUX SOFTWARE + * + * QLogic ISP1280/ device driver for Linux 2.2.x and 2.4.x + * Copyright (C) 2001 Qlogic Corporation (www.qlogic.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. + * + *****************************************************************************/ + /************************************************************************ - * * * --- ISP1240/1080/1280 Initiator Firmware --- * * 32 LUN Support * - * * - ************************************************************************ - * Copyright (C) 1999,2000 Qlogic, Corporation. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted provided - * that the following conditions are met: - * 1. Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 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 ``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. - * * - ************************************************************************ - */ + ************************************************************************/ /* - * Firmware Version 8.09.00 (18:29 Apr 16, 1999) + * Firmware Version 8.15.00 (14:35 Aug 22, 2000) */ -unsigned short fw1280ei_version = 8*1024+9; +#ifdef UNIQUE_FW_NAME +unsigned short fw1280ei_version = 8*1024+15; +#else +unsigned short risc_code_version = 8*1024+15; +#endif + +#ifdef UNIQUE_FW_NAME +unsigned char fw1280ei_version_str[] = {8,15,0}; +#else +unsigned char firmware_version[] = {8,15,0}; +#endif -unsigned char fw1280ei_version_str[] = {8,9,0}; +#ifdef UNIQUE_FW_NAME +#define fw1280ei_VERSION_STRING "8.15.00" +#else +#define FW_VERSION_STRING "8.15.00" +#endif -unsigned short fw1280ei_addr01 = 0x1000 ; +#ifdef UNIQUE_FW_NAME +unsigned short fw1280ei_addr01 = 0x1000; +#else +unsigned short risc_code_addr01 = 0x1000; +#endif -unsigned short fw1280ei_code01[] = { - 0x0078, 0x1041, 0x0000, 0x39e3, 0x0000, 0x2043, 0x4f50, 0x5952, +#ifdef UNIQUE_FW_NAME +unsigned short fw1280ei_code01[] = { +#else +unsigned short risc_code01[] = { +#endif + 0x0078, 0x1041, 0x0000, 0x3d3b, 0x0000, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31, 0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, 0x4320, 0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049, 0x5350, 0x3132, 0x3430, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056, - 0x6572, 0x7369, 0x6f6e, 0x2030, 0x382e, 0x3039, 0x2020, 0x2043, + 0x6572, 0x7369, 0x6f6e, 0x2030, 0x382e, 0x3135, 0x2020, 0x2043, 0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, 0x3030, 0x2050, 0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020, 0x3030, 0x2020, - 0x2400, 0x20c9, 0x93ff, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1080, + 0x2400, 0x20c9, 0x97ff, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1080, 0x00c0, 0x1054, 0x2071, 0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010, - 0x2089, 0x136a, 0x0078, 0x106d, 0x2001, 0x04fc, 0x2004, 0xa086, + 0x2089, 0x1374, 0x0078, 0x106d, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1280, 0x00c0, 0x1069, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2071, - 0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010, 0x2089, 0x13ea, 0x0078, - 0x106d, 0x20c1, 0x0020, 0x2089, 0x1312, 0x2071, 0x0010, 0x70c3, + 0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010, 0x2089, 0x13f8, 0x0078, + 0x106d, 0x20c1, 0x0020, 0x2089, 0x131c, 0x2071, 0x0010, 0x70c3, 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x0008, 0x2001, 0x04fe, 0x70d6, 0x20c1, 0x0021, 0x2019, 0x0000, 0x2009, 0xfeff, 0x2100, 0x200b, 0xa5a5, 0xa1ec, 0x7fff, 0x2d64, @@ -61,1838 +76,1948 @@ 0xa286, 0xa5a5, 0x0040, 0x10a4, 0xa386, 0x000f, 0x0040, 0x10a0, 0x2c6a, 0x2a5a, 0x20c1, 0x0020, 0x2019, 0x000f, 0x0078, 0x1080, 0x2c6a, 0x2a5a, 0x0078, 0x10a2, 0x2c6a, 0x2a5a, 0x2130, 0x2128, - 0xa1a2, 0x4a00, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, - 0xa192, 0x9400, 0x2009, 0x0000, 0x2001, 0x0032, 0x1078, 0x2078, - 0x2218, 0x2079, 0x4a00, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9, - 0x0040, 0x42a4, 0x8109, 0x00c0, 0x10bf, 0x2001, 0x04fc, 0x2004, - 0xa086, 0x1080, 0x00c0, 0x10db, 0x2071, 0x0100, 0x0d7e, 0x2069, - 0x4a40, 0x1078, 0x49ae, 0x0d7f, 0x7810, 0xc0ed, 0x7812, 0x781b, - 0x0064, 0x0078, 0x1100, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1280, - 0x00c0, 0x10fb, 0x7814, 0xc0ed, 0xc0d5, 0x7816, 0x781b, 0x0064, - 0x2071, 0x0200, 0x0d7e, 0x2069, 0x4a40, 0x1078, 0x49ae, 0x2069, - 0x4a80, 0x2071, 0x0100, 0x1078, 0x49ae, 0x7814, 0xc0d4, 0x7816, - 0x0d7f, 0x0078, 0x1100, 0x7814, 0xc0e5, 0x7816, 0x781b, 0x003c, - 0x7eca, 0x7cc2, 0x7bc6, 0x7867, 0x0000, 0x7800, 0xc08d, 0x7802, - 0x2031, 0x0030, 0x78af, 0x0101, 0x7823, 0x0002, 0x7827, 0x0002, - 0x2009, 0x0002, 0x2069, 0x4a40, 0x681b, 0x0003, 0x6823, 0x0007, - 0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028, 0x6837, 0x0000, - 0x683b, 0x0006, 0x6833, 0x0008, 0x683f, 0x0000, 0x8109, 0x0040, - 0x1154, 0x68d3, 0x000a, 0x68c3, 0x4ac0, 0x2079, 0x4a00, 0x7814, - 0xd0e4, 0x00c0, 0x113a, 0xd0ec, 0x00c0, 0x113e, 0x68d7, 0x7329, - 0x0078, 0x1140, 0x68d7, 0x730d, 0x0078, 0x1140, 0x68d7, 0x7329, - 0x68c7, 0x4fc0, 0x68cb, 0x4ec0, 0x68cf, 0x8fc0, 0x68ab, 0x9244, - 0x68af, 0x9249, 0x68b3, 0x9244, 0x68b7, 0x9244, 0x68a7, 0x0001, - 0x2069, 0x4a80, 0x0078, 0x1114, 0x68d3, 0x000a, 0x68c3, 0x4cc0, - 0x7814, 0xd0e4, 0x00c0, 0x1160, 0x68d7, 0x7439, 0x0078, 0x1162, - 0x68d7, 0x7419, 0x68c7, 0x6fc0, 0x68cb, 0x4f40, 0x68cf, 0x90d0, - 0x68ab, 0x9249, 0x68af, 0x924e, 0x68b3, 0x9249, 0x68b7, 0x9249, - 0x68a7, 0x0001, 0x7810, 0xd0ec, 0x00c0, 0x11b8, 0x7814, 0xd0e4, - 0x00c0, 0x11aa, 0x0e7e, 0x2069, 0x4ec0, 0x2071, 0x0200, 0x70ec, - 0xd0e4, 0x00c0, 0x118b, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078, - 0x2007, 0x0078, 0x1191, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078, - 0x2007, 0x2069, 0x4f40, 0x2071, 0x0100, 0x70ec, 0xd0e4, 0x00c0, - 0x11a1, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078, 0x2007, 0x0078, - 0x11a7, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078, 0x2007, 0x0e7f, - 0x0078, 0x11d1, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x2069, 0x4ec0, - 0x1078, 0x2007, 0x2069, 0x4f40, 0x1078, 0x2007, 0x0078, 0x11d1, - 0x2069, 0x4ec0, 0x0e7e, 0x2071, 0x0100, 0x70ec, 0xd0e4, 0x00c0, - 0x11ca, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078, 0x2007, 0x0e7f, - 0x0078, 0x11d1, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078, 0x2007, - 0x0e7f, 0x2011, 0x0002, 0x2069, 0x4fc0, 0x2009, 0x0002, 0x20a9, - 0x0100, 0x683f, 0x0000, 0x680b, 0x0040, 0x7bc8, 0xa386, 0xfeff, - 0x00c0, 0x11e8, 0x6817, 0x0100, 0x681f, 0x0064, 0x0078, 0x11ec, - 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010, 0x00f0, 0x11d9, - 0x8109, 0x00c0, 0x11d7, 0x8211, 0x0040, 0x11fa, 0x2069, 0x6fc0, - 0x0078, 0x11d5, 0x1078, 0x2611, 0x1078, 0x441d, 0x1078, 0x1df2, - 0x1078, 0x4957, 0x2091, 0x2100, 0x2079, 0x4a00, 0x7810, 0xd0ec, - 0x0040, 0x120e, 0x2071, 0x0020, 0x0078, 0x1210, 0x2071, 0x0050, - 0x2091, 0x2200, 0x2079, 0x4a00, 0x2071, 0x0020, 0x2091, 0x2300, - 0x2079, 0x4a00, 0x7810, 0xd0ec, 0x0040, 0x1222, 0x2079, 0x0100, - 0x0078, 0x1224, 0x2079, 0x0200, 0x2071, 0x4a40, 0x2091, 0x2400, - 0x2079, 0x0100, 0x2071, 0x4a80, 0x2091, 0x2000, 0x2079, 0x4a00, - 0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090, 0x2071, 0x0010, - 0x70c3, 0x0000, 0x0090, 0x1243, 0x70c0, 0xa086, 0x0002, 0x00c0, - 0x1243, 0x1078, 0x159d, 0x2039, 0x0000, 0x7810, 0xd0ec, 0x00c0, - 0x12c5, 0x1078, 0x1472, 0x78ac, 0xa005, 0x00c0, 0x1261, 0x0068, - 0x1257, 0x786c, 0xa065, 0x0040, 0x1257, 0x1078, 0x2368, 0x1078, - 0x209f, 0x0068, 0x126e, 0x786c, 0xa065, 0x0040, 0x1261, 0x1078, - 0x2368, 0x0068, 0x126e, 0x2009, 0x4a47, 0x2011, 0x4a87, 0x2104, - 0x220c, 0xa105, 0x0040, 0x126e, 0x1078, 0x1f1e, 0x2071, 0x4a40, - 0x70a4, 0xa005, 0x0040, 0x1293, 0x7450, 0xa485, 0x0000, 0x0040, - 0x1293, 0x2079, 0x0200, 0x2091, 0x8000, 0x72d4, 0xa28c, 0x303d, - 0x2190, 0x1078, 0x2a9c, 0x2091, 0x8000, 0x2091, 0x303d, 0x0068, - 0x1293, 0x2079, 0x4a00, 0x786c, 0xa065, 0x0040, 0x1293, 0x2071, - 0x0010, 0x1078, 0x2368, 0x00e0, 0x129b, 0x2079, 0x4a00, 0x2071, - 0x0010, 0x1078, 0x4765, 0x2071, 0x4a80, 0x70a4, 0xa005, 0x0040, - 0x12b3, 0x7050, 0xa025, 0x0040, 0x12b3, 0x2079, 0x0100, 0x2091, - 0x8000, 0x72d4, 0xa28c, 0x303d, 0x2190, 0x1078, 0x2a9c, 0x2091, - 0x8000, 0x2091, 0x303d, 0x2079, 0x4a00, 0x2071, 0x0010, 0x0068, - 0x12bf, 0x786c, 0xa065, 0x0040, 0x12bf, 0x1078, 0x2368, 0x00e0, - 0x1249, 0x1078, 0x4765, 0x0078, 0x1249, 0x1078, 0x1472, 0x78ac, - 0xa005, 0x00c0, 0x12dd, 0x0068, 0x12d3, 0x786c, 0xa065, 0x0040, - 0x12d3, 0x1078, 0x2368, 0x1078, 0x209f, 0x0068, 0x12e7, 0x786c, - 0xa065, 0x0040, 0x12dd, 0x1078, 0x2368, 0x0068, 0x12e7, 0x2009, - 0x4a47, 0x2104, 0xa005, 0x0040, 0x12e7, 0x1078, 0x1f1e, 0x2071, - 0x4a40, 0x70a4, 0xa005, 0x0040, 0x1302, 0x7450, 0xa485, 0x0000, - 0x0040, 0x1302, 0x2079, 0x0100, 0x2091, 0x8000, 0x72d4, 0xa28c, - 0x303d, 0x2190, 0x1078, 0x2a9c, 0x2091, 0x8000, 0x2091, 0x303d, - 0x2079, 0x4a00, 0x2071, 0x0010, 0x0068, 0x130c, 0x786c, 0xa065, - 0x0040, 0x130c, 0x1078, 0x2368, 0x00e0, 0x12c5, 0x1078, 0x4765, - 0x0078, 0x12c5, 0x1332, 0x1332, 0x1334, 0x1334, 0x1341, 0x1341, - 0x1341, 0x1341, 0x134c, 0x134c, 0x1359, 0x1359, 0x1341, 0x1341, - 0x1341, 0x1341, 0x1332, 0x1332, 0x1334, 0x1334, 0x1341, 0x1341, - 0x1341, 0x1341, 0x134c, 0x134c, 0x1359, 0x1359, 0x1341, 0x1341, - 0x1341, 0x1341, 0x0078, 0x1332, 0x007e, 0x107e, 0x127e, 0x2091, - 0x2400, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, - 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13ba, 0x127f, 0x107f, - 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, - 0x2300, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, - 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, 0x1078, 0x290b, - 0x2091, 0x2400, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, - 0x8001, 0x007c, 0x138a, 0x138a, 0x138c, 0x138c, 0x1399, 0x1399, - 0x1399, 0x1399, 0x13a4, 0x13a4, 0x138c, 0x138c, 0x1399, 0x1399, - 0x1399, 0x1399, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, - 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, - 0x13a5, 0x13a5, 0x0078, 0x138a, 0x007e, 0x107e, 0x127e, 0x2091, - 0x2300, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, - 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13c7, 0x127f, 0x107f, - 0x007f, 0x2091, 0x8001, 0x007c, 0x007c, 0x107e, 0x127e, 0x0d7e, - 0x0e7e, 0x0f7e, 0x007e, 0x2071, 0x0100, 0x2069, 0x4a40, 0x2079, - 0x4a00, 0x1078, 0x49ae, 0x007f, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f, - 0x107f, 0x007c, 0x3c00, 0xa084, 0x0007, 0x0079, 0x13bf, 0x13d0, - 0x13d0, 0x13d2, 0x13d2, 0x13d7, 0x13d7, 0x13dc, 0x13dc, 0x3c00, - 0xa084, 0x0003, 0x0079, 0x13cc, 0x13d0, 0x13d0, 0x13e5, 0x13e5, - 0x1078, 0x28ec, 0x2091, 0x2200, 0x1078, 0x44b7, 0x007c, 0x2091, - 0x2100, 0x1078, 0x44b7, 0x007c, 0x2091, 0x2100, 0x1078, 0x44b7, - 0x2091, 0x2200, 0x1078, 0x44b7, 0x007c, 0x2091, 0x2100, 0x1078, - 0x44b7, 0x007c, 0x140a, 0x140a, 0x140c, 0x140c, 0x1419, 0x1419, - 0x1419, 0x1419, 0x1424, 0x1424, 0x1431, 0x1431, 0x1419, 0x1419, - 0x1419, 0x1419, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, - 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, - 0x1442, 0x1442, 0x0078, 0x140a, 0x007e, 0x107e, 0x127e, 0x2091, - 0x2400, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, - 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13ba, 0x127f, 0x107f, - 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, - 0x2300, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, - 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, 0x1078, 0x290b, - 0x2091, 0x2400, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, - 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x0d7e, 0x0e7e, 0x0f7e, - 0x2079, 0x4a00, 0x2071, 0x0200, 0x2069, 0x4a40, 0x3d00, 0xd08c, - 0x00c0, 0x1456, 0x2069, 0x4a80, 0x2071, 0x0100, 0x1078, 0x49ae, - 0x0f7f, 0x0e7f, 0x0d7f, 0x127f, 0x107f, 0x007f, 0x007c, 0x7008, - 0x800b, 0x00c8, 0x146d, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0, - 0x146e, 0xd09c, 0x0040, 0x146d, 0x087a, 0x097a, 0x70c3, 0x4002, - 0x0078, 0x15a0, 0x0068, 0x14f7, 0x2061, 0x0000, 0x6018, 0xd084, - 0x00c0, 0x14f7, 0x7828, 0xa005, 0x00c0, 0x1482, 0x0010, 0x14f8, - 0x0078, 0x14f7, 0x7910, 0xd1f4, 0x0040, 0x148a, 0x2001, 0x4007, - 0x0078, 0x159f, 0x7914, 0xd1ec, 0x0040, 0x14a5, 0xd0fc, 0x0040, - 0x149b, 0x007e, 0x1078, 0x1d82, 0x007f, 0x0040, 0x14a5, 0x2001, - 0x4007, 0x0078, 0x159f, 0x007e, 0x1078, 0x1d72, 0x007f, 0x0040, - 0x14a5, 0x2001, 0x4007, 0x0078, 0x159f, 0x7910, 0xd0fc, 0x00c0, - 0x14af, 0x2061, 0x4a40, 0xc19c, 0xc7fc, 0x0078, 0x14b3, 0x2061, - 0x4a80, 0xc19d, 0xc7fd, 0x6064, 0xa005, 0x00c0, 0x14f7, 0x7912, - 0x6083, 0x0000, 0x7828, 0xc0fc, 0xa086, 0x0018, 0x00c0, 0x14c4, - 0x0c7e, 0x1078, 0x1b13, 0x0c7f, 0x782b, 0x0000, 0x607c, 0xa065, - 0x0040, 0x14dd, 0x0c7e, 0x609c, 0x1078, 0x1e5d, 0x0c7f, 0x609f, - 0x0000, 0x1078, 0x1c3f, 0x2009, 0x0018, 0x6087, 0x0103, 0x1078, - 0x1d92, 0x00c0, 0x14f1, 0x1078, 0x1de4, 0x7810, 0xd09c, 0x00c0, - 0x14e5, 0x2061, 0x4a40, 0x0078, 0x14e9, 0x2061, 0x4a80, 0xc09c, - 0x7812, 0x607f, 0x0000, 0x60d4, 0xd0dc, 0x0040, 0x14f5, 0xc0dc, - 0x60d6, 0x2001, 0x4005, 0x0078, 0x159f, 0x0078, 0x159d, 0x007c, - 0x7810, 0xd0f4, 0x0040, 0x1500, 0x2001, 0x4007, 0x0078, 0x159f, - 0xa006, 0x70c2, 0x70c6, 0x70ca, 0x70ce, 0x70da, 0x70c0, 0xa08a, - 0x0040, 0x00c8, 0x150d, 0x0079, 0x1514, 0x2100, 0xa08a, 0x0040, - 0x00c8, 0x15ab, 0x0079, 0x1554, 0x159d, 0x15f3, 0x15bc, 0x162b, - 0x1663, 0x1663, 0x15b3, 0x1c57, 0x166e, 0x15ab, 0x15c0, 0x15c2, - 0x15c4, 0x15c6, 0x1c5c, 0x15ab, 0x167c, 0x16d4, 0x1b35, 0x1c51, - 0x15c8, 0x19a7, 0x19e9, 0x1a1f, 0x1a6b, 0x1962, 0x196f, 0x1983, - 0x1996, 0x17a4, 0x1cdc, 0x1706, 0x1713, 0x171f, 0x172b, 0x1741, - 0x174d, 0x1750, 0x175c, 0x1768, 0x1770, 0x178c, 0x1798, 0x15ab, - 0x15ab, 0x15ab, 0x15ab, 0x17b1, 0x17c3, 0x17df, 0x1815, 0x183d, - 0x184d, 0x1850, 0x1881, 0x18b2, 0x18c4, 0x1931, 0x1941, 0x1d32, - 0x15ab, 0x15ab, 0x15ab, 0x1951, 0x15ab, 0x15ab, 0x15ab, 0x15ab, - 0x15ab, 0x1c81, 0x1c87, 0x15ab, 0x15ab, 0x15ab, 0x1c8b, 0x1cd8, - 0x15ab, 0x15ab, 0x1ce8, 0x1cf7, 0x15ed, 0x165d, 0x1676, 0x16ce, - 0x1b2f, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x1d39, 0x1c73, 0x1c7d, - 0x15ab, 0x15ab, 0x1d02, 0x1d1b, 0x15ab, 0x15ab, 0x15ab, 0x15ab, - 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, - 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, - 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, - 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x72ca, 0x71c6, 0x2001, 0x4006, - 0x0078, 0x159f, 0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, - 0x0068, 0x15a0, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, - 0x2091, 0x4080, 0x007c, 0x70c3, 0x4001, 0x0078, 0x15a0, 0x70c3, - 0x4006, 0x0078, 0x15a0, 0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, - 0x0005, 0x53a3, 0x0078, 0x159d, 0x70c4, 0x70c3, 0x0004, 0x007a, - 0x0078, 0x159d, 0x0078, 0x159d, 0x0078, 0x159d, 0x0078, 0x159d, - 0x2091, 0x8000, 0x70c3, 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, - 0x70cf, 0x2020, 0x70d3, 0x0008, 0x2001, 0x0009, 0x70d6, 0x2079, - 0x0000, 0x781b, 0x0001, 0x2031, 0x0030, 0x2059, 0x1000, 0x2029, - 0x041a, 0x2051, 0x0445, 0x2061, 0x0447, 0x20c1, 0x0020, 0x2091, - 0x5000, 0x2091, 0x4080, 0x0078, 0x0418, 0x75d8, 0x74dc, 0x75da, - 0x74de, 0x0078, 0x15f6, 0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, - 0x73cc, 0x70c4, 0x20a0, 0x2099, 0x0030, 0x7003, 0x0001, 0x7007, - 0x0006, 0x731a, 0x721e, 0x7422, 0x7526, 0x2021, 0x0040, 0x81ff, - 0x0040, 0x159d, 0xa182, 0x0040, 0x00c8, 0x1610, 0x2120, 0xa006, - 0x2008, 0x8403, 0x7012, 0x7007, 0x0004, 0x7007, 0x0001, 0x7008, - 0xd0fc, 0x0040, 0x1617, 0x7007, 0x0002, 0xa084, 0x01e0, 0x0040, - 0x1625, 0x70c3, 0x4002, 0x0078, 0x15a0, 0x24a8, 0x53a5, 0x0078, - 0x1607, 0x0078, 0x159d, 0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, - 0x73cc, 0x70c4, 0x2098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x7007, - 0x0006, 0x731a, 0x721e, 0x7422, 0x7526, 0x2021, 0x0040, 0x7007, - 0x0006, 0x81ff, 0x0040, 0x159d, 0xa182, 0x0040, 0x00c8, 0x164a, - 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x24a8, 0x53a6, 0x7007, - 0x0001, 0x7008, 0xd0fc, 0x0040, 0x1651, 0xa084, 0x01e0, 0x0040, - 0x163f, 0x70c3, 0x4002, 0x0078, 0x15a0, 0x75d8, 0x74dc, 0x75da, - 0x74de, 0x0078, 0x162e, 0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004, - 0x00c0, 0x166b, 0x200a, 0x72ca, 0x0078, 0x159c, 0x70c7, 0x0008, - 0x70cb, 0x0009, 0x70cf, 0x0000, 0x0078, 0x159d, 0x75d8, 0x76dc, - 0x75da, 0x76de, 0x0078, 0x167f, 0x2029, 0x0000, 0x2530, 0x70c4, - 0x72c8, 0x73cc, 0x74d0, 0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005, - 0x0040, 0x16c9, 0x8001, 0x7872, 0xa084, 0xfc00, 0x0040, 0x1697, - 0x78ac, 0xc085, 0x78ae, 0x2001, 0x4005, 0x0078, 0x159f, 0x7b7e, - 0x7a7a, 0x7e86, 0x7d82, 0x7c76, 0xa48c, 0xff00, 0x0040, 0x16af, - 0x8407, 0x8004, 0x8004, 0x810c, 0x810c, 0x810f, 0xa118, 0xa291, - 0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000, 0x0078, 0x16b9, 0x8407, - 0x8004, 0x8004, 0xa318, 0xa291, 0x0000, 0xa6b1, 0x0000, 0xa581, - 0x0000, 0x731a, 0x721e, 0x7622, 0x7026, 0xa605, 0x0040, 0x16c3, - 0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084, 0xfffc, 0x78ae, 0x0078, - 0x16cc, 0x78ac, 0xc085, 0x78ae, 0x0078, 0x159d, 0x75d8, 0x76dc, - 0x75da, 0x76de, 0x0078, 0x16d7, 0x2029, 0x0000, 0x2530, 0x70c4, - 0x72c8, 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6, 0xa005, - 0x0040, 0x1701, 0x8001, 0x7892, 0xa084, 0xfc00, 0x0040, 0x16ef, - 0x78ac, 0xc0c5, 0x78ae, 0x2001, 0x4005, 0x0078, 0x159f, 0x7a9a, - 0x7b9e, 0x7da2, 0x7ea6, 0x2600, 0xa505, 0x0040, 0x16fa, 0x7a10, - 0xc2c5, 0x7a12, 0x7c96, 0x78ac, 0xa084, 0xfcff, 0x78ae, 0x0078, - 0x1704, 0x78ac, 0xc0c5, 0x78ae, 0x0078, 0x159d, 0x2009, 0x0000, - 0x786c, 0xa065, 0x0040, 0x1710, 0x8108, 0x6000, 0x0078, 0x1709, - 0x7ac4, 0x0078, 0x159b, 0x2009, 0x4a48, 0x210c, 0x7810, 0xd0ec, - 0x00c0, 0x159c, 0x2011, 0x4a88, 0x2214, 0x0078, 0x159b, 0x2009, - 0x4a49, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x2011, 0x4a89, - 0x2214, 0x0078, 0x159b, 0x2061, 0x4a40, 0x6128, 0x622c, 0x8214, - 0x8214, 0x8214, 0x7810, 0xd0ec, 0x00c0, 0x173f, 0x2061, 0x4a80, - 0x6328, 0x73da, 0x632c, 0x831c, 0x831c, 0x831c, 0x73de, 0x0078, - 0x159b, 0x2009, 0x4a4c, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x159c, - 0x2011, 0x4a8c, 0x2214, 0x0078, 0x159b, 0x7918, 0x0078, 0x159c, - 0x2009, 0x4a4d, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x2011, - 0x4a8d, 0x2214, 0x0078, 0x159b, 0x2009, 0x4a4e, 0x210c, 0x7810, - 0xd0ec, 0x00c0, 0x159c, 0x2011, 0x4a8e, 0x2214, 0x0078, 0x159b, - 0x7920, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x7a24, 0x0078, 0x159b, - 0x71c4, 0xd1fc, 0x00c0, 0x1778, 0x2011, 0x4ec0, 0x0078, 0x177a, - 0x2011, 0x4f40, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, - 0xa268, 0x6a00, 0x6804, 0xd09c, 0x0040, 0x1789, 0x6b08, 0x0078, - 0x178a, 0x6b0c, 0x0078, 0x159a, 0x77c4, 0x1078, 0x1e02, 0x2091, - 0x8000, 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, 0x0078, 0x159a, - 0x2061, 0x4a40, 0x6118, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x2061, - 0x4a80, 0x6218, 0x0078, 0x159b, 0x77c4, 0x1078, 0x1e02, 0x2091, - 0x8000, 0x6908, 0x6a18, 0x6b10, 0x77da, 0x2091, 0x8001, 0x0078, - 0x159a, 0x71c4, 0x2110, 0xa294, 0x000f, 0xa282, 0x0010, 0x00c8, - 0x1595, 0x1078, 0x2729, 0xa384, 0x4000, 0x0040, 0x17c1, 0xa295, - 0x0020, 0x0078, 0x159a, 0x71c4, 0x2100, 0xc0bc, 0xa082, 0x0010, - 0x00c8, 0x1595, 0xd1bc, 0x00c0, 0x17d2, 0x2011, 0x4a48, 0x2204, - 0x0078, 0x17d6, 0x2011, 0x4a88, 0x2204, 0xc0bd, 0x007e, 0x2100, - 0xc0bc, 0x2012, 0x1078, 0x2686, 0x017f, 0x0078, 0x159c, 0x71c4, - 0x2021, 0x4a49, 0x2404, 0x70c6, 0x2019, 0x0000, 0x0078, 0x17ee, - 0x71c8, 0x2021, 0x4a89, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x180d, - 0x20a9, 0x0008, 0x2204, 0xa106, 0x0040, 0x17fd, 0x8210, 0x00f0, - 0x17f2, 0x71c4, 0x72c8, 0x0078, 0x1594, 0xa292, 0x180d, 0x027e, - 0x2122, 0x017f, 0x1078, 0x26a7, 0x7810, 0xd0ec, 0x00c0, 0x180b, - 0xd3fc, 0x0040, 0x17e8, 0x0078, 0x159d, 0x03e8, 0x00fa, 0x01f4, - 0x02ee, 0x0064, 0x0019, 0x0032, 0x004b, 0x2061, 0x4a40, 0x6128, - 0x622c, 0x8214, 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, 0x8003, - 0x8003, 0x8003, 0x602e, 0x7810, 0xd0ec, 0x00c0, 0x183b, 0x027e, - 0x017e, 0x2061, 0x4a80, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, - 0x70d8, 0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, 0x602e, 0x71da, - 0x72de, 0x017f, 0x027f, 0x0078, 0x159b, 0x2061, 0x4a40, 0x6130, - 0x70c4, 0x6032, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x2061, 0x4a80, - 0x6230, 0x70c8, 0x6032, 0x0078, 0x159b, 0x7918, 0x0078, 0x159c, - 0x71c4, 0xa184, 0xffcf, 0x0040, 0x185c, 0x7810, 0xd0ec, 0x00c0, - 0x1595, 0x72c8, 0x0078, 0x1594, 0x2011, 0x4a4d, 0x2204, 0x2112, - 0x007e, 0x2019, 0x0000, 0x1078, 0x270e, 0x7810, 0xd0ec, 0x0040, - 0x186c, 0x017f, 0x0078, 0x159c, 0x71c8, 0xa184, 0xffcf, 0x0040, - 0x1875, 0x2110, 0x71c4, 0x0078, 0x1594, 0x2011, 0x4a8d, 0x2204, - 0x2112, 0x007e, 0xc3fd, 0x1078, 0x270e, 0x027f, 0x017f, 0x0078, - 0x159b, 0x71c4, 0xa182, 0x0010, 0x0048, 0x188d, 0x7810, 0xd0ec, - 0x00c0, 0x1595, 0x72c8, 0x0078, 0x1594, 0x2011, 0x4a4e, 0x2204, - 0x007e, 0x2112, 0x2019, 0x0000, 0x1078, 0x26ec, 0x7810, 0xd0ec, - 0x0040, 0x189d, 0x017f, 0x0078, 0x159c, 0x71c8, 0xa182, 0x0010, - 0x0048, 0x18a6, 0x2110, 0x71c4, 0x0078, 0x1594, 0x2011, 0x4a8e, - 0x2204, 0x007e, 0x2112, 0xc3fd, 0x1078, 0x26ec, 0x027f, 0x017f, - 0x0078, 0x159b, 0x71c4, 0x72c8, 0xa184, 0xfffd, 0x00c0, 0x1594, - 0xa284, 0xfffd, 0x00c0, 0x1594, 0x2100, 0x7920, 0x7822, 0x2200, - 0x7a24, 0x7826, 0x0078, 0x159b, 0x71c4, 0xd1fc, 0x00c0, 0x18cc, - 0x2011, 0x4ec0, 0x0078, 0x18ce, 0x2011, 0x4f40, 0x8107, 0xa084, - 0x000f, 0x8003, 0x8003, 0x8003, 0xa268, 0x2019, 0x0000, 0x72c8, - 0xa284, 0x0080, 0x0040, 0x18e2, 0x6c14, 0x84ff, 0x00c0, 0x18e2, - 0x6817, 0x0040, 0xa284, 0x0040, 0x0040, 0x18ec, 0x6c10, 0x84ff, - 0x00c0, 0x18ec, 0x6813, 0x0001, 0x6800, 0x007e, 0xa226, 0x0040, - 0x1909, 0x6a02, 0xd4ec, 0x0040, 0x18f6, 0xc3a5, 0xd4e4, 0x0040, - 0x18fa, 0xc39d, 0xd4f4, 0x0040, 0x1909, 0x810f, 0xd2f4, 0x0040, - 0x1905, 0x1078, 0x276b, 0x0078, 0x1909, 0x1078, 0x2749, 0x0078, - 0x1909, 0x72cc, 0x6808, 0xa206, 0x0040, 0x1929, 0xa2a4, 0x00ff, - 0x7814, 0xd0e4, 0x00c0, 0x191c, 0xa482, 0x0028, 0x0048, 0x1926, - 0x0040, 0x1926, 0x0078, 0x1920, 0xa482, 0x0043, 0x0048, 0x1926, - 0x71c4, 0x71c6, 0x027f, 0x72ca, 0x0078, 0x1596, 0x6a0a, 0xa39d, - 0x000a, 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4, 0x0078, - 0x159a, 0x77c4, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6a14, 0x6b1c, - 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708, 0x0078, - 0x159a, 0x70c4, 0x2061, 0x4a40, 0x6118, 0x601a, 0x7810, 0xd0ec, - 0x00c0, 0x159c, 0x70c8, 0x2061, 0x4a80, 0x6218, 0x601a, 0x0078, - 0x159b, 0x71c4, 0x72c8, 0x73cc, 0xa182, 0x0010, 0x00c8, 0x1595, - 0x1078, 0x278d, 0xa384, 0x4000, 0x0040, 0x1960, 0xa295, 0x0020, - 0x0078, 0x159a, 0x77c4, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6a08, - 0xc28d, 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078, 0x159b, 0x77c4, - 0x1078, 0x1e02, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9, 0x6a0a, - 0x6804, 0xa005, 0x0040, 0x197e, 0x1078, 0x25de, 0x2091, 0x8001, - 0x2708, 0x0078, 0x159b, 0x77c4, 0x1078, 0x1e02, 0x2091, 0x8000, - 0x6a08, 0xc295, 0x6a0a, 0x6804, 0xa005, 0x0040, 0x1991, 0x1078, - 0x25de, 0x2091, 0x8001, 0x2708, 0x0078, 0x159b, 0x77c4, 0x2041, - 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078, - 0x1e1d, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0078, 0x159b, 0x77c4, - 0x7814, 0xd0e4, 0x00c0, 0x19bb, 0xd7fc, 0x0040, 0x19b5, 0x1078, - 0x1d82, 0x0040, 0x19bb, 0x0078, 0x159f, 0x1078, 0x1d72, 0x0040, - 0x19bb, 0x0078, 0x159f, 0x73c8, 0x72cc, 0x77c6, 0x73ca, 0x72ce, - 0x1078, 0x1e9a, 0x00c0, 0x19e5, 0x6818, 0xa005, 0x0040, 0x19df, - 0x2708, 0x077e, 0x1078, 0x27bd, 0x077f, 0x00c0, 0x19df, 0x2001, - 0x0015, 0xd7fc, 0x00c0, 0x19d8, 0x2061, 0x4a40, 0x0078, 0x19db, - 0xc0fd, 0x2061, 0x4a80, 0x782a, 0x2091, 0x8001, 0x007c, 0x2091, - 0x8001, 0x2001, 0x4005, 0x0078, 0x159f, 0x2091, 0x8001, 0x0078, - 0x159d, 0x77c4, 0x7814, 0xd0e4, 0x00c0, 0x19fd, 0xd7fc, 0x0040, - 0x19f7, 0x1078, 0x1d82, 0x0040, 0x19fd, 0x0078, 0x159f, 0x1078, - 0x1d72, 0x0040, 0x19fd, 0x0078, 0x159f, 0x77c6, 0x2041, 0x0021, - 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078, 0x1e1d, - 0x2009, 0x0016, 0xd7fc, 0x00c0, 0x1a11, 0x2061, 0x4a40, 0x0078, - 0x1a14, 0x2061, 0x4a80, 0xc1fd, 0x6067, 0x0003, 0x6776, 0x6083, - 0x000f, 0x792a, 0x1078, 0x25de, 0x2091, 0x8001, 0x007c, 0x77c8, - 0x77ca, 0x77c4, 0x77c6, 0x7814, 0xd0e4, 0x00c0, 0x1a36, 0xd7fc, - 0x0040, 0x1a30, 0x1078, 0x1d82, 0x0040, 0x1a36, 0x0078, 0x159f, - 0x1078, 0x1d72, 0x0040, 0x1a36, 0x0078, 0x159f, 0xa7bc, 0xff00, - 0x2091, 0x8000, 0x2009, 0x0017, 0xd7fc, 0x00c0, 0x1a43, 0x2061, - 0x4a40, 0x0078, 0x1a46, 0x2061, 0x4a80, 0xc1fd, 0x6067, 0x0002, - 0x6776, 0x6083, 0x000f, 0x792a, 0x1078, 0x25de, 0x2091, 0x8001, - 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0010, 0x2091, 0x8000, - 0x70c8, 0xa005, 0x0040, 0x1a5f, 0x60d4, 0xc0fd, 0x60d6, 0x1078, - 0x1e1d, 0x70c8, 0x683e, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1a5f, - 0x2091, 0x8001, 0x007c, 0x7814, 0xd0e4, 0x00c0, 0x1a7f, 0x72c8, - 0xd284, 0x0040, 0x1a79, 0x1078, 0x1d82, 0x0040, 0x1a7f, 0x0078, - 0x159f, 0x1078, 0x1d72, 0x0040, 0x1a7f, 0x0078, 0x159f, 0x72c8, - 0x72ca, 0x78ac, 0xa084, 0x0003, 0x00c0, 0x1aaa, 0x2039, 0x0000, - 0xd284, 0x0040, 0x1a8c, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, - 0x2051, 0x0008, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6808, 0xc0d4, - 0xa80d, 0x690a, 0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x00c0, - 0x1a92, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, - 0x00c0, 0x1a92, 0x2091, 0x8000, 0x72c8, 0xd284, 0x00c0, 0x1abc, - 0x7810, 0xd0ec, 0x0040, 0x1ab8, 0x2069, 0x0100, 0x0078, 0x1abe, - 0x2069, 0x0200, 0x0078, 0x1abe, 0x2069, 0x0100, 0x6830, 0xd0b4, - 0x0040, 0x1ada, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xd094, - 0x0040, 0x1acc, 0x00f0, 0x1ac6, 0x684b, 0x0009, 0x20a9, 0x0014, - 0x6848, 0xd084, 0x0040, 0x1ad6, 0x00f0, 0x1ad0, 0x20a9, 0x00fa, - 0x00f0, 0x1ad8, 0x2079, 0x4a00, 0x2009, 0x0018, 0x72c8, 0xd284, - 0x00c0, 0x1ae6, 0x2061, 0x4a40, 0x0078, 0x1ae9, 0x2061, 0x4a80, - 0xc1fd, 0x792a, 0x6067, 0x0001, 0x6083, 0x000f, 0x60a7, 0x0000, - 0x60a8, 0x60b2, 0x60b6, 0x60d4, 0xd0b4, 0x0040, 0x1b03, 0xc0b4, - 0x60d6, 0x0c7e, 0x60b8, 0xa065, 0x6008, 0xc0d4, 0x600a, 0x6018, - 0x8001, 0x601a, 0x0c7f, 0x60d4, 0xa084, 0x77ff, 0x60d6, 0x78ac, - 0xc08d, 0x78ae, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b, 0x0047, - 0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x1b1a, 0x2069, 0x4a40, - 0x0078, 0x1b1c, 0x2069, 0x4a80, 0x78ac, 0xc08c, 0x78ae, 0xd084, - 0x00c0, 0x1b26, 0x0d7e, 0x1078, 0x1efa, 0x0d7f, 0x71c4, 0x71c6, - 0x6916, 0x81ff, 0x00c0, 0x1b2e, 0x68a7, 0x0001, 0x007c, 0x75d8, - 0x74dc, 0x75da, 0x74de, 0x0078, 0x1b38, 0x2029, 0x0000, 0x2520, - 0x71c4, 0x73c8, 0x72cc, 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x4a00, - 0x7dde, 0x7cda, 0x7bd6, 0x7ad2, 0x1078, 0x1ddb, 0x0040, 0x1c3b, - 0x20a9, 0x0005, 0x20a1, 0x4a14, 0x2091, 0x8000, 0x41a1, 0x2091, - 0x8001, 0x2009, 0x0040, 0x1078, 0x1fcf, 0x0040, 0x1b5b, 0x1078, - 0x1de4, 0x0078, 0x1c3b, 0x6004, 0xa08c, 0x00ff, 0xa18e, 0x0009, - 0x00c0, 0x1b66, 0x007e, 0x1078, 0x234b, 0x007f, 0xa084, 0xff00, - 0x8007, 0x8009, 0x0040, 0x1bda, 0x0c7e, 0x2c68, 0x1078, 0x1ddb, - 0x0040, 0x1bac, 0x2c00, 0x689e, 0x8109, 0x00c0, 0x1b6d, 0x609f, - 0x0000, 0x0c7f, 0x0c7e, 0x7ddc, 0x7cd8, 0x7bd4, 0x7ad0, 0xa290, - 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x7dde, - 0x7cda, 0x7bd6, 0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0040, 0x1bd9, - 0x2009, 0x0040, 0x1078, 0x1fcf, 0x00c0, 0x1bc3, 0x6004, 0xa084, - 0x00ff, 0xa086, 0x0002, 0x00c0, 0x1bac, 0x6004, 0xa084, 0x00ff, - 0xa086, 0x000a, 0x00c0, 0x1ba8, 0x017e, 0x1078, 0x2347, 0x017f, - 0x2d00, 0x6002, 0x0078, 0x1b7b, 0x0c7f, 0x0c7e, 0x609c, 0x1078, - 0x1e5d, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1c3f, 0x2009, 0x0018, - 0x6008, 0xc0cd, 0x600a, 0x6004, 0x6086, 0x1078, 0x1d92, 0x1078, - 0x1de4, 0x0078, 0x1c3b, 0x0c7f, 0x0c7e, 0x609c, 0x1078, 0x1e5d, - 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1c3f, 0x2009, 0x0018, 0x6087, - 0x0103, 0x601b, 0x0003, 0x1078, 0x1d92, 0x1078, 0x1de4, 0x0078, - 0x1c3b, 0x0c7f, 0x7814, 0xd0e4, 0x00c0, 0x1bff, 0x6114, 0xd1fc, - 0x0040, 0x1be8, 0x1078, 0x1d82, 0x0040, 0x1bff, 0x0078, 0x1bec, - 0x1078, 0x1d72, 0x0040, 0x1bff, 0x2029, 0x0000, 0x2520, 0x2009, - 0x0018, 0x73c8, 0x72cc, 0x6087, 0x0103, 0x601b, 0x0021, 0x1078, - 0x1d92, 0x1078, 0x1de4, 0x2001, 0x4007, 0x0078, 0x159f, 0x74c4, - 0x73c8, 0x72cc, 0x6014, 0x2091, 0x8000, 0x0e7e, 0x2009, 0x0012, - 0xd0fc, 0x00c0, 0x1c0f, 0x2071, 0x4a40, 0x0078, 0x1c12, 0x2071, - 0x4a80, 0xc1fd, 0x792a, 0x7067, 0x0005, 0x71d4, 0xa18c, 0xf77f, - 0x71d6, 0x736a, 0x726e, 0x7472, 0x7076, 0x707b, 0x0000, 0x2c00, - 0x707e, 0xa02e, 0x2530, 0x611c, 0xa184, 0x0060, 0x0040, 0x1c2a, - 0x1078, 0x43c1, 0x0e7f, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, - 0x0000, 0x60b3, 0x0000, 0x6714, 0x6023, 0x0000, 0x1078, 0x25de, - 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, 0x15a0, 0x20a9, - 0x0005, 0x2099, 0x4a14, 0x2091, 0x8000, 0x530a, 0x2091, 0x8001, - 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, - 0x007c, 0x71c4, 0x70c7, 0x0000, 0x791e, 0x0078, 0x159d, 0x71c4, - 0x71c6, 0x2168, 0x0078, 0x1c5e, 0x2069, 0x1000, 0x690c, 0xa016, - 0x2d04, 0xa210, 0x8d68, 0x8109, 0x00c0, 0x1c60, 0xa285, 0x0000, - 0x00c0, 0x1c6e, 0x70c3, 0x4000, 0x0078, 0x1c70, 0x70c3, 0x4003, - 0x70ca, 0x0078, 0x15a0, 0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, - 0x00c8, 0x1595, 0x7966, 0x0078, 0x159d, 0x7964, 0x71c6, 0x0078, - 0x159d, 0x7900, 0x71c6, 0x71c4, 0x7902, 0x0078, 0x159d, 0x7900, - 0x71c6, 0x0078, 0x159d, 0x70c4, 0xd08c, 0x0040, 0x1c94, 0x7a10, - 0xd2ec, 0x00c0, 0x1c94, 0xc08c, 0x2011, 0x0000, 0xa08c, 0x000d, - 0x0040, 0x1ca8, 0x810c, 0x0048, 0x1ca4, 0x8210, 0x810c, 0x810c, - 0x0048, 0x1ca4, 0x8210, 0x810c, 0x81ff, 0x00c0, 0x1596, 0x8210, - 0x7a0e, 0xd28c, 0x0040, 0x1cd4, 0x7910, 0xc1cd, 0x7912, 0x2009, - 0x0021, 0x2019, 0x0003, 0xd284, 0x0040, 0x1cce, 0x8108, 0x2019, - 0x0041, 0x2011, 0x924e, 0x2312, 0x2019, 0x0042, 0x8210, 0x2312, - 0x2019, 0x0043, 0x8210, 0x2312, 0x2019, 0x0046, 0x8210, 0x2312, - 0x2019, 0x0047, 0x8210, 0x2312, 0x2019, 0x0006, 0x2011, 0x9253, - 0x2112, 0x2011, 0x9273, 0x2312, 0x7904, 0x7806, 0x0078, 0x159c, - 0x7804, 0x70c6, 0x0078, 0x159d, 0x2091, 0x8000, 0x2019, 0x0000, - 0x2011, 0x0000, 0x2009, 0x0000, 0x2091, 0x8001, 0x0078, 0x159a, - 0x77c4, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6830, 0xa084, 0xff00, - 0x8007, 0x2010, 0x2091, 0x8001, 0x2708, 0x0078, 0x159b, 0x77c4, - 0x1078, 0x1e02, 0x2091, 0x8000, 0x6a34, 0x2091, 0x8001, 0x2708, - 0x0078, 0x159b, 0x77c4, 0x077e, 0xa7bc, 0xff00, 0x20a9, 0x0008, - 0x72c8, 0x8217, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6c30, 0x6a32, - 0x2091, 0x8001, 0x8738, 0x00f0, 0x1d0a, 0x077f, 0x2708, 0x8427, - 0x2410, 0x0078, 0x159b, 0x77c4, 0x077e, 0xa7bc, 0xff00, 0x20a9, - 0x0008, 0x72c8, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6c34, 0x6a36, - 0x2091, 0x8001, 0x8738, 0x00f0, 0x1d22, 0x077f, 0x2708, 0x2410, - 0x0078, 0x159b, 0x2011, 0x4a3c, 0x220c, 0x70c4, 0x2012, 0x0078, - 0x159c, 0x71c4, 0xd1fc, 0x00c0, 0x1d41, 0x2011, 0x4ec0, 0x0078, - 0x1d43, 0x2011, 0x4f40, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, - 0x8003, 0xa268, 0x6a14, 0xd2b4, 0x0040, 0x1d52, 0x2011, 0x0001, - 0x0078, 0x1d54, 0x2011, 0x0000, 0x6b0c, 0x0078, 0x159a, 0x017e, - 0x7814, 0xd0f4, 0x0040, 0x1d64, 0x2001, 0x4007, 0x70db, 0x0000, - 0xa18d, 0x0001, 0x0078, 0x1d70, 0xd0fc, 0x0040, 0x1d6f, 0x2001, - 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0078, 0x1d70, 0xa006, - 0x017f, 0x007c, 0x017e, 0x7814, 0xd0f4, 0x0040, 0x1d7f, 0x2001, - 0x4007, 0x70db, 0x0000, 0xa18d, 0x0001, 0x0078, 0x1d80, 0xa006, - 0x017f, 0x007c, 0x017e, 0x7814, 0xd0fc, 0x0040, 0x1d8f, 0x2001, - 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0078, 0x1d90, 0xa006, - 0x017f, 0x007c, 0x7112, 0x721a, 0x731e, 0x7810, 0xd0c4, 0x0040, - 0x1d9b, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108, 0x810c, 0x81a9, - 0x8098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x6084, 0x20a2, 0x53a6, - 0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0040, 0x1db8, 0x810f, - 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0078, 0x1dbb, - 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, 0xa211, - 0x7d10, 0xd5c4, 0x0040, 0x1dc8, 0x7b84, 0xa319, 0x7c80, 0xa421, - 0x7008, 0xd0fc, 0x0040, 0x1dc8, 0x7003, 0x0001, 0x7007, 0x0006, - 0x711a, 0x721e, 0x7d10, 0xd5c4, 0x0040, 0x1dd8, 0x7322, 0x7426, - 0xa084, 0x01e0, 0x007c, 0x7848, 0xa065, 0x0040, 0x1de3, 0x2c04, - 0x784a, 0x2063, 0x0000, 0x007c, 0x0f7e, 0x2079, 0x4a00, 0x7848, - 0x2062, 0x2c00, 0xa005, 0x00c0, 0x1def, 0x1078, 0x28ec, 0x784a, - 0x0f7f, 0x007c, 0x2011, 0x9400, 0x7a4a, 0x7bc4, 0x8319, 0x0040, - 0x1dff, 0xa280, 0x0032, 0x2012, 0x2010, 0x0078, 0x1df6, 0x2013, - 0x0000, 0x007c, 0x017e, 0x027e, 0xd7fc, 0x00c0, 0x1e0b, 0x2011, - 0x4fc0, 0x0078, 0x1e0d, 0x2011, 0x6fc0, 0xa784, 0x0f00, 0x800b, - 0xa784, 0x001f, 0x0040, 0x1e18, 0x8003, 0x8003, 0x8003, 0x8003, - 0xa105, 0xa268, 0x027f, 0x017f, 0x007c, 0x1078, 0x1e02, 0x2900, - 0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, 0xf9ef, 0xa80d, 0x690a, - 0xd7fc, 0x00c0, 0x1e2f, 0x2009, 0x4a53, 0x0078, 0x1e31, 0x2009, - 0x4a93, 0x210c, 0x6804, 0xa005, 0x0040, 0x1e41, 0xa116, 0x00c0, - 0x1e41, 0x2060, 0x6000, 0x6806, 0x017e, 0x200b, 0x0000, 0x0078, - 0x1e44, 0x2009, 0x0000, 0x017e, 0x6804, 0xa065, 0x0040, 0x1e59, - 0x6000, 0x6806, 0x1078, 0x1e6f, 0x1078, 0x201b, 0x6810, 0x7908, - 0x8109, 0x790a, 0x8001, 0x6812, 0x00c0, 0x1e44, 0x7910, 0xc1a5, - 0x7912, 0x017f, 0x6902, 0x6906, 0x007c, 0xa065, 0x0040, 0x1e6e, - 0x2008, 0x609c, 0xa005, 0x0040, 0x1e6b, 0x2062, 0x609f, 0x0000, - 0xa065, 0x0078, 0x1e61, 0x7848, 0x794a, 0x2062, 0x007c, 0x6007, - 0x0103, 0x608f, 0x0000, 0x20a9, 0x001c, 0xac80, 0x0005, 0x20a0, - 0x2001, 0x0000, 0x40a4, 0x6828, 0x601a, 0x682c, 0x6022, 0x007c, - 0x0e7e, 0xd7fc, 0x00c0, 0x1e8a, 0x2071, 0x4a40, 0x2031, 0x4ac0, - 0x0078, 0x1e8e, 0x2071, 0x4a80, 0x2031, 0x4cc0, 0x7050, 0xa08c, - 0x0200, 0x00c0, 0x1e98, 0xa608, 0x2d0a, 0x8000, 0x7052, 0xa006, - 0x0e7f, 0x007c, 0x0f7e, 0xd7fc, 0x00c0, 0x1ea2, 0x2079, 0x4a40, - 0x0078, 0x1ea4, 0x2079, 0x4a80, 0x1078, 0x1e02, 0x2091, 0x8000, - 0x6804, 0x780a, 0xa065, 0x0040, 0x1ef8, 0x0078, 0x1eb6, 0x2c00, - 0x780a, 0x2060, 0x6000, 0xa065, 0x0040, 0x1ef8, 0x6010, 0xa306, - 0x00c0, 0x1eaf, 0x600c, 0xa206, 0x00c0, 0x1eaf, 0x2c28, 0x784c, - 0xac06, 0x00c0, 0x1ec5, 0x0078, 0x1ef5, 0x6804, 0xac06, 0x00c0, - 0x1ed3, 0x6000, 0x2060, 0x6806, 0xa005, 0x00c0, 0x1ed3, 0x6803, - 0x0000, 0x0078, 0x1edd, 0x6400, 0x7808, 0x2060, 0x6402, 0xa486, - 0x0000, 0x00c0, 0x1edd, 0x2c00, 0x6802, 0x2560, 0x0f7f, 0x1078, - 0x1e6f, 0x0f7e, 0x601b, 0x0005, 0x6023, 0x0020, 0x0f7f, 0x1078, - 0x201b, 0x0f7e, 0x7908, 0x8109, 0x790a, 0x6810, 0x8001, 0x6812, - 0x00c0, 0x1ef5, 0x7810, 0xc0a5, 0x7812, 0x2001, 0xffff, 0xa005, - 0x0f7f, 0x007c, 0x077e, 0x2700, 0x2039, 0x0000, 0xd0fc, 0x0040, - 0x1f02, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, - 0x2091, 0x8000, 0x1078, 0x1e1d, 0x8738, 0xa784, 0x001f, 0x00c0, - 0x1f0a, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, - 0x00c0, 0x1f0a, 0x2091, 0x8001, 0x077f, 0x007c, 0x2061, 0x0000, - 0x6018, 0xd084, 0x00c0, 0x1f3e, 0x7810, 0xd08c, 0x0040, 0x1f2f, - 0xc08c, 0x7812, 0xc7fc, 0x2069, 0x4a40, 0x0078, 0x1f34, 0xc08d, - 0x7812, 0x2069, 0x4a80, 0xc7fd, 0x2091, 0x8000, 0x681c, 0x681f, - 0x0000, 0x2091, 0x8001, 0xa005, 0x00c0, 0x1f3f, 0x007c, 0xa08c, - 0xfff0, 0x0040, 0x1f45, 0x1078, 0x28ec, 0x0079, 0x1f47, 0x1f57, - 0x1f5a, 0x1f60, 0x1f64, 0x1f58, 0x1f68, 0x1f58, 0x1f58, 0x1f58, - 0x1f6e, 0x1f9f, 0x1fa3, 0x1fa9, 0x1f58, 0x1f58, 0x1f58, 0x007c, - 0x1078, 0x28ec, 0x1078, 0x1efa, 0x2001, 0x8001, 0x0078, 0x1fbe, - 0x2001, 0x8003, 0x0078, 0x1fbe, 0x2001, 0x8004, 0x0078, 0x1fbe, - 0x1078, 0x1efa, 0x2001, 0x8006, 0x0078, 0x1fbe, 0x2091, 0x8000, - 0x077e, 0xd7fc, 0x00c0, 0x1f7a, 0x2069, 0x4a40, 0x2039, 0x0009, - 0x0078, 0x1f7e, 0x2069, 0x4a80, 0x2039, 0x0009, 0x6800, 0xa086, - 0x0000, 0x0040, 0x1f88, 0x007f, 0x6f1e, 0x2091, 0x8001, 0x007c, - 0x6874, 0x077f, 0xa0bc, 0xff00, 0x2041, 0x0021, 0x2049, 0x0004, - 0x2051, 0x0010, 0x1078, 0x1e1d, 0x8738, 0xa784, 0x001f, 0x00c0, - 0x1f92, 0x2091, 0x8001, 0x2001, 0x800a, 0x0078, 0x1fbe, 0x2001, - 0x800c, 0x0078, 0x1fbe, 0x1078, 0x1efa, 0x2001, 0x800d, 0x0078, - 0x1fbe, 0x7814, 0xd0e4, 0x00c0, 0x1fbc, 0xd0ec, 0x0040, 0x1fb6, - 0xd7fc, 0x0040, 0x1fb6, 0x78ec, 0x0078, 0x1fb7, 0x78e4, 0x70c6, - 0x2001, 0x800e, 0x0078, 0x1fbe, 0x0078, 0x1f58, 0x70c2, 0xd7fc, - 0x00c0, 0x1fc6, 0x70db, 0x0000, 0x0078, 0x1fc8, 0x70db, 0x0001, - 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080, 0x007c, 0xac80, - 0x0001, 0x81ff, 0x0040, 0x1ffa, 0x2099, 0x0030, 0x20a0, 0x700c, - 0xa084, 0x03ff, 0x0040, 0x1fdc, 0x7018, 0x007e, 0x701c, 0x007e, - 0x7020, 0x007e, 0x7024, 0x007e, 0x7112, 0x81ac, 0x721a, 0x731e, - 0x7422, 0x7526, 0x7003, 0x0001, 0x7007, 0x0001, 0x7008, 0x800b, - 0x00c8, 0x1fee, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0, 0x1ffa, - 0x53a5, 0xa006, 0x7003, 0x0000, 0x7007, 0x0004, 0x007f, 0x7026, - 0x007f, 0x7022, 0x007f, 0x701e, 0x007f, 0x701a, 0x007c, 0x2011, - 0x0020, 0x2009, 0x0010, 0x6b0a, 0x6c0e, 0x6803, 0xfd00, 0x6807, - 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004, 0x8109, - 0x00c0, 0x200b, 0x007c, 0x6004, 0x6086, 0x2c08, 0x2063, 0x0000, - 0x7868, 0xa005, 0x796a, 0x0040, 0x2028, 0x2c02, 0x0078, 0x2029, - 0x796e, 0x007c, 0x0c7e, 0x2061, 0x4a00, 0x6887, 0x0103, 0x2d08, - 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040, 0x203a, 0x2d02, - 0x0078, 0x203b, 0x616e, 0x0c7f, 0x007c, 0x2091, 0x8000, 0x2c04, - 0x786e, 0xa005, 0x00c0, 0x2045, 0x786a, 0x2091, 0x8001, 0x609c, - 0xa005, 0x0040, 0x205e, 0x0c7e, 0x2060, 0x2008, 0x609c, 0xa005, - 0x0040, 0x205a, 0x2062, 0x609f, 0x0000, 0xa065, 0x609c, 0xa005, - 0x00c0, 0x2052, 0x7848, 0x794a, 0x2062, 0x0c7f, 0x7848, 0x2062, - 0x609f, 0x0000, 0xac85, 0x0000, 0x00c0, 0x2068, 0x1078, 0x28ec, - 0x784a, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, - 0x00c8, 0x2073, 0xa200, 0x00f0, 0x206e, 0x8086, 0x818e, 0x007c, - 0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x2099, 0xa11a, 0x00c8, - 0x2099, 0x8213, 0x818d, 0x0048, 0x208c, 0xa11a, 0x00c8, 0x208d, - 0x00f0, 0x2081, 0x0078, 0x2091, 0xa11a, 0x2308, 0x8210, 0x00f0, - 0x2081, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, 0x157f, - 0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x2095, 0x7d74, - 0x70d0, 0xa506, 0x0040, 0x2185, 0x7810, 0x2050, 0x7800, 0xd08c, - 0x0040, 0x20c1, 0xdaec, 0x0040, 0x20c1, 0x0e7e, 0x2091, 0x8000, - 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x20be, 0x7008, 0x0e7f, - 0xa086, 0x0008, 0x0040, 0x20c1, 0x0078, 0x2185, 0x0e7f, 0x0078, - 0x2185, 0x1078, 0x1ddb, 0x0040, 0x2185, 0xa046, 0x7970, 0x2500, - 0x8000, 0xa112, 0x2009, 0x0040, 0x00c8, 0x20d0, 0x0078, 0x20d7, - 0x72d0, 0xa206, 0x0040, 0x20d7, 0x8840, 0x2009, 0x0080, 0x0c7e, - 0x7112, 0x7007, 0x0001, 0x2099, 0x0030, 0x20a9, 0x0020, 0xac80, - 0x0001, 0x20a0, 0x2061, 0x0000, 0x88ff, 0x0040, 0x20e9, 0x1078, - 0x1ddb, 0x7008, 0xd0fc, 0x0040, 0x20e9, 0x7007, 0x0002, 0x2091, - 0x8001, 0xa08c, 0x01e0, 0x00c0, 0x2120, 0x53a5, 0x8cff, 0x00c0, - 0x20fe, 0x88ff, 0x0040, 0x216f, 0x0078, 0x2108, 0x2c00, 0x788e, - 0x20a9, 0x0020, 0xac80, 0x0001, 0x20a0, 0x53a5, 0x0078, 0x216f, - 0xa046, 0x7218, 0x731c, 0xdac4, 0x0040, 0x2110, 0x7420, 0x7524, - 0xa292, 0x0040, 0xa39b, 0x0000, 0xa4a3, 0x0000, 0xa5ab, 0x0000, - 0x721a, 0x731e, 0xdac4, 0x0040, 0x2120, 0x7422, 0x7526, 0xa006, - 0x7007, 0x0004, 0x0040, 0x216f, 0x8cff, 0x0040, 0x2129, 0x1078, - 0x1de4, 0x0c7f, 0x1078, 0x1de4, 0xa046, 0x7888, 0x8000, 0x788a, - 0xa086, 0x0002, 0x0040, 0x214f, 0x7a7c, 0x7b78, 0xdac4, 0x0040, - 0x213b, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004, 0x8004, 0xa210, - 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x721a, 0x731e, - 0xdac4, 0x0040, 0x2185, 0x7422, 0x7526, 0x0078, 0x2185, 0x6014, - 0xd0fc, 0x00c0, 0x2157, 0x2069, 0x4a40, 0x0078, 0x2159, 0x2069, - 0x4a80, 0x2091, 0x8000, 0x681f, 0x0002, 0x88ff, 0x0040, 0x2165, - 0xa046, 0x788c, 0x2060, 0x0078, 0x214f, 0x788b, 0x0000, 0x78ac, - 0xa085, 0x0003, 0x78ae, 0x2091, 0x8001, 0x0078, 0x2185, 0x0c7f, - 0x788b, 0x0000, 0x1078, 0x2319, 0x6004, 0xa084, 0x000f, 0x1078, - 0x2186, 0x88ff, 0x0040, 0x2183, 0x788c, 0x2060, 0x6004, 0xa084, - 0x000f, 0x1078, 0x2186, 0x0078, 0x209f, 0x007c, 0x0079, 0x2188, - 0x2198, 0x21b6, 0x21d4, 0x2198, 0x21e5, 0x21a9, 0x2198, 0x2198, - 0x2198, 0x21b4, 0x21d2, 0x2198, 0x2198, 0x2198, 0x2198, 0x2198, - 0x2039, 0x0400, 0x78bc, 0xa705, 0x78be, 0x6008, 0xa705, 0x600a, - 0x1078, 0x2228, 0x609c, 0x78ba, 0x609f, 0x0000, 0x1078, 0x2303, - 0x007c, 0x78bc, 0xd0c4, 0x0040, 0x21af, 0x0078, 0x2198, 0x601c, - 0xc0bd, 0x601e, 0x0078, 0x21bc, 0x1078, 0x234b, 0x78bc, 0xd0c4, - 0x0040, 0x21bc, 0x0078, 0x2198, 0x78bf, 0x0000, 0x6004, 0x8007, - 0xa084, 0x00ff, 0x78b2, 0x8001, 0x0040, 0x21cf, 0x1078, 0x2228, - 0x0040, 0x21cf, 0x78bc, 0xc0c5, 0x78be, 0x0078, 0x21d1, 0x0078, - 0x2247, 0x007c, 0x1078, 0x2347, 0x78bc, 0xa08c, 0x0e00, 0x00c0, - 0x21dc, 0xd0c4, 0x00c0, 0x21de, 0x0078, 0x2198, 0x1078, 0x2228, - 0x00c0, 0x21e4, 0x0078, 0x2247, 0x007c, 0x78bc, 0xd0c4, 0x0040, - 0x21eb, 0x0078, 0x2198, 0x78bf, 0x0000, 0x6714, 0x2011, 0x0001, - 0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0040, 0x220b, 0xa7bc, - 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0040, 0x220b, 0xa7bc, - 0x8000, 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0040, - 0x220b, 0x0078, 0x2225, 0x1078, 0x1e02, 0x2d00, 0x2091, 0x8000, - 0x682b, 0x0000, 0x682f, 0x0000, 0x6808, 0xa084, 0xffde, 0x680a, - 0xade8, 0x0010, 0x2091, 0x8001, 0x00f0, 0x220e, 0x8211, 0x0040, - 0x2225, 0x20a9, 0x0100, 0x0078, 0x220e, 0x1078, 0x1de4, 0x007c, - 0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, 0x78b6, 0x00c0, 0x2233, - 0x78ba, 0x0078, 0x223b, 0x689e, 0x2d00, 0x6002, 0x78b8, 0xad06, - 0x00c0, 0x223b, 0x6002, 0x78b0, 0x8001, 0x78b2, 0x00c0, 0x2246, - 0x78bc, 0xc0c4, 0x78be, 0x78b8, 0x2060, 0xa006, 0x007c, 0x0e7e, - 0xa02e, 0x2530, 0x7dba, 0x7db6, 0x65ae, 0x65b2, 0x601c, 0x60a2, - 0x2048, 0xa984, 0xe1ff, 0x601e, 0xa984, 0x0060, 0x0040, 0x225a, - 0x1078, 0x43c1, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x6714, 0x2071, - 0x4a80, 0xd7fc, 0x00c0, 0x2266, 0x2071, 0x4a40, 0xa784, 0x0f00, - 0x800b, 0xa784, 0x001f, 0x0040, 0x2271, 0x8003, 0x8003, 0x8003, - 0x8003, 0xa105, 0x71c4, 0xa168, 0x2700, 0x8007, 0xa084, 0x000f, - 0x8003, 0x8003, 0x8003, 0x71c8, 0xa100, 0x60c2, 0x2091, 0x8000, - 0x7810, 0xd0f4, 0x00c0, 0x228b, 0x6e08, 0xd684, 0x0040, 0x22a1, - 0xd9fc, 0x00c0, 0x22a1, 0x2091, 0x8001, 0x1078, 0x1e6f, 0x2091, - 0x8000, 0x1078, 0x201b, 0x2091, 0x8001, 0x7814, 0xd0e4, 0x00c0, - 0x2301, 0x7810, 0xd0f4, 0x0040, 0x2301, 0x601b, 0x0021, 0x0078, - 0x2301, 0x6024, 0xa096, 0x0001, 0x00c0, 0x22a8, 0x8000, 0x6026, - 0x6a10, 0x6814, 0xa202, 0x0048, 0x22bb, 0x0040, 0x22bb, 0x2091, + 0xa1a2, 0x4e00, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, + 0xa192, 0x9800, 0x2009, 0x0000, 0x2001, 0x0032, 0x1078, 0x207a, + 0x2218, 0x2079, 0x4e00, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9, + 0x0040, 0x42a4, 0x8109, 0x00c0, 0x10bf, 0x2009, 0xff00, 0x3400, + 0xa102, 0x0048, 0x10cf, 0x0040, 0x10cf, 0x20a8, 0x42a4, 0x2001, + 0x04fc, 0x2004, 0xa086, 0x1080, 0x00c0, 0x10e5, 0x2071, 0x0100, + 0x0d7e, 0x2069, 0x4e40, 0x1078, 0x4cdd, 0x0d7f, 0x7810, 0xc0ed, + 0x7812, 0x781b, 0x0064, 0x0078, 0x110a, 0x2001, 0x04fc, 0x2004, + 0xa086, 0x1280, 0x00c0, 0x1105, 0x7814, 0xc0ed, 0xc0d5, 0x7816, + 0x781b, 0x0064, 0x2071, 0x0200, 0x0d7e, 0x2069, 0x4e40, 0x1078, + 0x4cdd, 0x2069, 0x4e80, 0x2071, 0x0100, 0x1078, 0x4cdd, 0x7814, + 0xc0d4, 0x7816, 0x0d7f, 0x0078, 0x110a, 0x7814, 0xc0e5, 0x7816, + 0x781b, 0x003c, 0x7eca, 0x7cc2, 0x7bc6, 0x7867, 0x0000, 0x7800, + 0xc08d, 0x7802, 0x2031, 0x0030, 0x78af, 0x0101, 0x7823, 0x0002, + 0x7827, 0x0002, 0x2009, 0x0002, 0x2069, 0x4e40, 0x681b, 0x0003, + 0x6823, 0x0007, 0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028, + 0x6837, 0x0000, 0x683b, 0x0006, 0x6833, 0x0008, 0x683f, 0x0000, + 0x8109, 0x0040, 0x115e, 0x68d3, 0x000a, 0x68c3, 0x4ec0, 0x2079, + 0x4e00, 0x7814, 0xd0e4, 0x00c0, 0x1144, 0xd0ec, 0x00c0, 0x1148, + 0x68d7, 0x7329, 0x0078, 0x114a, 0x68d7, 0x730d, 0x0078, 0x114a, + 0x68d7, 0x732d, 0x68c7, 0x53c0, 0x68cb, 0x52c0, 0x68cf, 0x93c0, + 0x68ab, 0x9644, 0x68af, 0x9649, 0x68b3, 0x9644, 0x68b7, 0x9644, + 0x68a7, 0x0001, 0x2069, 0x4e80, 0x0078, 0x111e, 0x68d3, 0x000a, + 0x68c3, 0x50c0, 0x7814, 0xd0e4, 0x00c0, 0x116a, 0x68d7, 0x7439, + 0x0078, 0x116c, 0x68d7, 0x7419, 0x68c7, 0x73c0, 0x68cb, 0x5340, + 0x68cf, 0x94d0, 0x68ab, 0x9649, 0x68af, 0x964e, 0x68b3, 0x9649, + 0x68b7, 0x9649, 0x68a7, 0x0001, 0x7810, 0xd0ec, 0x00c0, 0x11c2, + 0x7814, 0xd0e4, 0x00c0, 0x11b4, 0x0e7e, 0x2069, 0x52c0, 0x2071, + 0x0200, 0x70ec, 0xd0e4, 0x00c0, 0x1195, 0x2019, 0x0c0c, 0x2021, + 0x000c, 0x1078, 0x2009, 0x0078, 0x119b, 0x2019, 0x0c0a, 0x2021, + 0x000a, 0x1078, 0x2009, 0x2069, 0x5340, 0x2071, 0x0100, 0x70ec, + 0xd0e4, 0x00c0, 0x11ab, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078, + 0x2009, 0x0078, 0x11b1, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078, + 0x2009, 0x0e7f, 0x0078, 0x11db, 0x2019, 0x0c0c, 0x2021, 0x000c, + 0x2069, 0x52c0, 0x1078, 0x2009, 0x2069, 0x5340, 0x1078, 0x2009, + 0x0078, 0x11db, 0x2069, 0x52c0, 0x0e7e, 0x2071, 0x0100, 0x70ec, + 0xd0e4, 0x00c0, 0x11d4, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078, + 0x2009, 0x0e7f, 0x0078, 0x11db, 0x2019, 0x0c0a, 0x2021, 0x000a, + 0x1078, 0x2009, 0x0e7f, 0x2011, 0x0002, 0x2069, 0x53c0, 0x2009, + 0x0002, 0x20a9, 0x0100, 0x6837, 0x0000, 0x680b, 0x0040, 0x7bc8, + 0xa386, 0xfeff, 0x00c0, 0x11f2, 0x6817, 0x0100, 0x681f, 0x0064, + 0x0078, 0x11f6, 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010, + 0x00f0, 0x11e3, 0x8109, 0x00c0, 0x11e1, 0x8211, 0x0040, 0x1204, + 0x2069, 0x73c0, 0x0078, 0x11df, 0x1078, 0x265b, 0x1078, 0x468e, + 0x1078, 0x1dd4, 0x1078, 0x4c6f, 0x2091, 0x2100, 0x2079, 0x4e00, + 0x7810, 0xd0ec, 0x0040, 0x1218, 0x2071, 0x0020, 0x0078, 0x121a, + 0x2071, 0x0050, 0x2091, 0x2200, 0x2079, 0x4e00, 0x2071, 0x0020, + 0x2091, 0x2300, 0x2079, 0x4e00, 0x7810, 0xd0ec, 0x0040, 0x122c, + 0x2079, 0x0100, 0x0078, 0x122e, 0x2079, 0x0200, 0x2071, 0x4e40, + 0x2091, 0x2400, 0x2079, 0x0100, 0x2071, 0x4e80, 0x2091, 0x2000, + 0x2079, 0x4e00, 0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090, + 0x2071, 0x0010, 0x70c3, 0x0000, 0x0090, 0x124d, 0x70c0, 0xa086, + 0x0002, 0x00c0, 0x124d, 0x1078, 0x15ba, 0x2039, 0x0000, 0x7810, + 0xd0ec, 0x00c0, 0x12cf, 0x1078, 0x148e, 0x78ac, 0xa005, 0x00c0, + 0x126b, 0x0068, 0x1261, 0x786c, 0xa065, 0x0040, 0x1261, 0x1078, + 0x2395, 0x1078, 0x20a1, 0x0068, 0x1278, 0x786c, 0xa065, 0x0040, + 0x126b, 0x1078, 0x2395, 0x0068, 0x1278, 0x2009, 0x4e47, 0x2011, + 0x4e87, 0x2104, 0x220c, 0xa105, 0x0040, 0x1278, 0x1078, 0x1f0a, + 0x2071, 0x4e40, 0x70a4, 0xa005, 0x0040, 0x129d, 0x7450, 0xa485, + 0x0000, 0x0040, 0x129d, 0x2079, 0x0200, 0x2091, 0x8000, 0x72d4, + 0xa28c, 0x303d, 0x2190, 0x1078, 0x2b6a, 0x2091, 0x8000, 0x2091, + 0x303d, 0x0068, 0x129d, 0x2079, 0x4e00, 0x786c, 0xa065, 0x0040, + 0x129d, 0x2071, 0x0010, 0x1078, 0x2395, 0x00e0, 0x12a5, 0x2079, + 0x4e00, 0x2071, 0x0010, 0x1078, 0x4a43, 0x2071, 0x4e80, 0x70a4, + 0xa005, 0x0040, 0x12bd, 0x7050, 0xa025, 0x0040, 0x12bd, 0x2079, + 0x0100, 0x2091, 0x8000, 0x72d4, 0xa28c, 0x303d, 0x2190, 0x1078, + 0x2b6a, 0x2091, 0x8000, 0x2091, 0x303d, 0x2079, 0x4e00, 0x2071, + 0x0010, 0x0068, 0x12c9, 0x786c, 0xa065, 0x0040, 0x12c9, 0x1078, + 0x2395, 0x00e0, 0x1253, 0x1078, 0x4a43, 0x0078, 0x1253, 0x1078, + 0x148e, 0x78ac, 0xa005, 0x00c0, 0x12e7, 0x0068, 0x12dd, 0x786c, + 0xa065, 0x0040, 0x12dd, 0x1078, 0x2395, 0x1078, 0x20a1, 0x0068, + 0x12f1, 0x786c, 0xa065, 0x0040, 0x12e7, 0x1078, 0x2395, 0x0068, + 0x12f1, 0x2009, 0x4e47, 0x2104, 0xa005, 0x0040, 0x12f1, 0x1078, + 0x1f0a, 0x2071, 0x4e40, 0x70a4, 0xa005, 0x0040, 0x130c, 0x7450, + 0xa485, 0x0000, 0x0040, 0x130c, 0x2079, 0x0100, 0x2091, 0x8000, + 0x72d4, 0xa28c, 0x303d, 0x2190, 0x1078, 0x2b6a, 0x2091, 0x8000, + 0x2091, 0x303d, 0x2079, 0x4e00, 0x2071, 0x0010, 0x0068, 0x1316, + 0x786c, 0xa065, 0x0040, 0x1316, 0x1078, 0x2395, 0x00e0, 0x12cf, + 0x1078, 0x4a43, 0x0078, 0x12cf, 0x133c, 0x133c, 0x133e, 0x133e, + 0x134b, 0x134b, 0x134b, 0x134b, 0x1356, 0x1356, 0x1363, 0x1363, + 0x134b, 0x134b, 0x134b, 0x134b, 0x133c, 0x133c, 0x133e, 0x133e, + 0x134b, 0x134b, 0x134b, 0x134b, 0x1356, 0x1356, 0x1363, 0x1363, + 0x134b, 0x134b, 0x134b, 0x134b, 0x0078, 0x133c, 0x007e, 0x107e, + 0x127e, 0x2091, 0x2400, 0x1078, 0x298a, 0x127f, 0x107f, 0x007f, + 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13c8, + 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, + 0x127e, 0x2091, 0x2300, 0x1078, 0x298a, 0x127f, 0x107f, 0x007f, + 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, + 0x1078, 0x298a, 0x2091, 0x2400, 0x1078, 0x298a, 0x127f, 0x107f, + 0x007f, 0x2091, 0x8001, 0x007c, 0x1394, 0x1394, 0x1396, 0x1396, + 0x13a3, 0x13a3, 0x13a3, 0x13a3, 0x13ae, 0x13ae, 0x1396, 0x1396, + 0x13a3, 0x13a3, 0x13a3, 0x13a3, 0x13af, 0x13af, 0x13af, 0x13af, + 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, + 0x13af, 0x13af, 0x13af, 0x13af, 0x0078, 0x1394, 0x007e, 0x107e, + 0x127e, 0x2091, 0x2300, 0x1078, 0x298a, 0x127f, 0x107f, 0x007f, + 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13d5, + 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007c, 0x107e, + 0x127e, 0x0d7e, 0x0e7e, 0x0f7e, 0x007e, 0x2071, 0x0100, 0x2069, + 0x4e40, 0x2079, 0x4e00, 0x70ec, 0xa084, 0x1c00, 0x78e2, 0x1078, + 0x4cdd, 0x007f, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f, 0x107f, 0x007c, + 0x3c00, 0xa084, 0x0007, 0x0079, 0x13cd, 0x13de, 0x13de, 0x13e0, + 0x13e0, 0x13e5, 0x13e5, 0x13ea, 0x13ea, 0x3c00, 0xa084, 0x0003, + 0x0079, 0x13da, 0x13de, 0x13de, 0x13f3, 0x13f3, 0x1078, 0x296b, + 0x2091, 0x2200, 0x1078, 0x4768, 0x007c, 0x2091, 0x2100, 0x1078, + 0x4768, 0x007c, 0x2091, 0x2100, 0x1078, 0x4768, 0x2091, 0x2200, + 0x1078, 0x4768, 0x007c, 0x2091, 0x2100, 0x1078, 0x4768, 0x007c, + 0x1418, 0x1418, 0x141a, 0x141a, 0x1427, 0x1427, 0x1427, 0x1427, + 0x1432, 0x1432, 0x143f, 0x143f, 0x1427, 0x1427, 0x1427, 0x1427, + 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, + 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, + 0x0078, 0x1418, 0x007e, 0x107e, 0x127e, 0x2091, 0x2400, 0x1078, + 0x298a, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, + 0x107e, 0x127e, 0x1078, 0x13c8, 0x127f, 0x107f, 0x007f, 0x2091, + 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, 0x1078, + 0x298a, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, + 0x107e, 0x127e, 0x2091, 0x2300, 0x1078, 0x298a, 0x2091, 0x2400, + 0x1078, 0x298a, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, + 0x007e, 0x107e, 0x127e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2079, 0x4e00, + 0x2071, 0x0200, 0x2069, 0x4e40, 0x3d00, 0xd08c, 0x0040, 0x1466, + 0x70ec, 0xa084, 0x1c00, 0x78e2, 0x1078, 0x4cdd, 0x3d00, 0xd084, + 0x0040, 0x1474, 0x2069, 0x4e80, 0x2071, 0x0100, 0x70ec, 0xa084, + 0x1c00, 0x78e6, 0x1078, 0x4cdd, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f, + 0x107f, 0x007f, 0x007c, 0x7008, 0x800b, 0x00c8, 0x1489, 0x7007, + 0x0002, 0xa08c, 0x01e0, 0x00c0, 0x148a, 0xd09c, 0x0040, 0x1489, + 0x087a, 0x097a, 0x70c3, 0x4002, 0x0078, 0x15bd, 0x0068, 0x1513, + 0x2061, 0x0000, 0x6018, 0xd084, 0x00c0, 0x1513, 0x7828, 0xa005, + 0x00c0, 0x149e, 0x0010, 0x1514, 0x0078, 0x1513, 0x7910, 0xd1f4, + 0x0040, 0x14a6, 0x2001, 0x4007, 0x0078, 0x15bc, 0x7914, 0xd1ec, + 0x0040, 0x14c1, 0xd0fc, 0x0040, 0x14b7, 0x007e, 0x1078, 0x1d64, + 0x007f, 0x0040, 0x14c1, 0x2001, 0x4007, 0x0078, 0x15bc, 0x007e, + 0x1078, 0x1d54, 0x007f, 0x0040, 0x14c1, 0x2001, 0x4007, 0x0078, + 0x15bc, 0x7910, 0xd0fc, 0x00c0, 0x14cb, 0x2061, 0x4e40, 0xc19c, + 0xc7fc, 0x0078, 0x14cf, 0x2061, 0x4e80, 0xc19d, 0xc7fd, 0x6064, + 0xa005, 0x00c0, 0x1513, 0x7912, 0x6083, 0x0000, 0x7828, 0xc0fc, + 0xa086, 0x0018, 0x00c0, 0x14e0, 0x0c7e, 0x1078, 0x1b5b, 0x0c7f, + 0x782b, 0x0000, 0x607c, 0xa065, 0x0040, 0x14f9, 0x0c7e, 0x609c, + 0x1078, 0x1e49, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1c84, 0x2009, + 0x0018, 0x6087, 0x0103, 0x1078, 0x1d74, 0x00c0, 0x150d, 0x1078, + 0x1dc6, 0x7810, 0xd09c, 0x00c0, 0x1501, 0x2061, 0x4e40, 0x0078, + 0x1505, 0x2061, 0x4e80, 0xc09c, 0x7812, 0x607f, 0x0000, 0x60d4, + 0xd0dc, 0x0040, 0x1511, 0xc0dc, 0x60d6, 0x2001, 0x4005, 0x0078, + 0x15bc, 0x0078, 0x15ba, 0x007c, 0x7810, 0xd0f4, 0x0040, 0x151c, + 0x2001, 0x4007, 0x0078, 0x15bc, 0xa006, 0x70c2, 0x70c6, 0x70ca, + 0x70ce, 0x70da, 0x70c0, 0xa03d, 0xa08a, 0x0040, 0x00c8, 0x152a, + 0x0079, 0x1531, 0x2100, 0xa08a, 0x0040, 0x00c8, 0x15c8, 0x0079, + 0x1571, 0x15ba, 0x1610, 0x15d9, 0x1648, 0x1680, 0x1680, 0x15d0, + 0x1c9c, 0x168b, 0x15c8, 0x15dd, 0x15df, 0x15e1, 0x15e3, 0x1ca1, + 0x15c8, 0x1699, 0x16f6, 0x1b7b, 0x1c96, 0x15e5, 0x19c0, 0x1a02, + 0x1a3d, 0x1a8e, 0x197b, 0x1988, 0x199c, 0x19af, 0x17cb, 0x15c8, + 0x172d, 0x173a, 0x1746, 0x1752, 0x1768, 0x1774, 0x1777, 0x1783, + 0x178f, 0x1797, 0x17b3, 0x17bf, 0x15c8, 0x15c8, 0x15c8, 0x15c8, + 0x17d8, 0x17ea, 0x1806, 0x183c, 0x1864, 0x1874, 0x1877, 0x18a8, + 0x18d9, 0x18eb, 0x194a, 0x195a, 0x15c8, 0x15c8, 0x15c8, 0x15c8, + 0x196a, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x1cc6, 0x1ccc, + 0x15c8, 0x15c8, 0x15c8, 0x1cd0, 0x1d15, 0x15c8, 0x15c8, 0x15c8, + 0x15c8, 0x160a, 0x167a, 0x1693, 0x16f0, 0x1b75, 0x15c8, 0x15c8, + 0x1b3e, 0x15c8, 0x1d19, 0x1cb8, 0x1cc2, 0x15c8, 0x15c8, 0x15c8, + 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, + 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, + 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, + 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, + 0x15c8, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078, 0x15bc, 0x73ce, + 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0068, 0x15bd, 0x2061, + 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x007c, + 0x70c3, 0x4001, 0x0078, 0x15bd, 0x70c3, 0x4006, 0x0078, 0x15bd, + 0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0078, + 0x15ba, 0x70c4, 0x70c3, 0x0004, 0x007a, 0x0078, 0x15ba, 0x0078, + 0x15ba, 0x0078, 0x15ba, 0x0078, 0x15ba, 0x2091, 0x8000, 0x70c3, + 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, + 0x0008, 0x2001, 0x000f, 0x70d6, 0x2079, 0x0000, 0x781b, 0x0001, + 0x2031, 0x0030, 0x2059, 0x1000, 0x2029, 0x041a, 0x2051, 0x0445, + 0x2061, 0x0447, 0x20c1, 0x0020, 0x2091, 0x5000, 0x2091, 0x4080, + 0x0078, 0x0418, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1613, + 0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x20a0, + 0x2099, 0x0030, 0x7003, 0x0001, 0x7007, 0x0006, 0x731a, 0x721e, + 0x7422, 0x7526, 0x2021, 0x0040, 0x81ff, 0x0040, 0x15ba, 0xa182, + 0x0040, 0x00c8, 0x162d, 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, + 0x7007, 0x0004, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0040, 0x1634, + 0x7007, 0x0002, 0xa084, 0x01e0, 0x0040, 0x1642, 0x70c3, 0x4002, + 0x0078, 0x15bd, 0x24a8, 0x53a5, 0x0078, 0x1624, 0x0078, 0x15ba, + 0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x2098, + 0x20a1, 0x0030, 0x7003, 0x0000, 0x7007, 0x0006, 0x731a, 0x721e, + 0x7422, 0x7526, 0x2021, 0x0040, 0x7007, 0x0006, 0x81ff, 0x0040, + 0x15ba, 0xa182, 0x0040, 0x00c8, 0x1667, 0x2120, 0xa006, 0x2008, + 0x8403, 0x7012, 0x24a8, 0x53a6, 0x7007, 0x0001, 0x7008, 0xd0fc, + 0x0040, 0x166e, 0xa084, 0x01e0, 0x0040, 0x165c, 0x70c3, 0x4002, + 0x0078, 0x15bd, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x164b, + 0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004, 0x00c0, 0x1688, 0x200a, + 0x72ca, 0x0078, 0x15b9, 0x70c7, 0x0008, 0x70cb, 0x000f, 0x70cf, + 0x0000, 0x0078, 0x15ba, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078, + 0x169c, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0, + 0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005, 0x0040, 0x16eb, 0xa40a, + 0x0040, 0x16ac, 0x00c8, 0x16b5, 0x8001, 0x7872, 0xa084, 0xfc00, + 0x0040, 0x16b9, 0x78ac, 0xc085, 0x78ae, 0x2001, 0x4005, 0x0078, + 0x15bc, 0x7b7e, 0x7a7a, 0x7e86, 0x7d82, 0x7c76, 0xa48c, 0xff00, + 0x0040, 0x16d1, 0x8407, 0x8004, 0x8004, 0x810c, 0x810c, 0x810f, + 0xa118, 0xa291, 0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000, 0x0078, + 0x16db, 0x8407, 0x8004, 0x8004, 0xa318, 0xa291, 0x0000, 0xa6b1, + 0x0000, 0xa581, 0x0000, 0x731a, 0x721e, 0x7622, 0x7026, 0xa605, + 0x0040, 0x16e5, 0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084, 0xfffc, + 0x78ae, 0x0078, 0x16ee, 0x78ac, 0xc085, 0x78ae, 0x0078, 0x15ba, + 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078, 0x16f9, 0x2029, 0x0000, + 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, + 0x74d6, 0xa005, 0x0040, 0x1728, 0xa40a, 0x0040, 0x1709, 0x00c8, + 0x15bc, 0x8001, 0x7892, 0xa084, 0xfc00, 0x0040, 0x1716, 0x78ac, + 0xc0c5, 0x78ae, 0x2001, 0x4005, 0x0078, 0x15bc, 0x7a9a, 0x7b9e, + 0x7da2, 0x7ea6, 0x2600, 0xa505, 0x0040, 0x1721, 0x7a10, 0xc2c5, + 0x7a12, 0x7c96, 0x78ac, 0xa084, 0xfcff, 0x78ae, 0x0078, 0x172b, + 0x78ac, 0xc0c5, 0x78ae, 0x0078, 0x15ba, 0x2009, 0x0000, 0x786c, + 0xa065, 0x0040, 0x1737, 0x8108, 0x6000, 0x0078, 0x1730, 0x7ac4, + 0x0078, 0x15b8, 0x2009, 0x4e48, 0x210c, 0x7810, 0xd0ec, 0x00c0, + 0x15b9, 0x2011, 0x4e88, 0x2214, 0x0078, 0x15b8, 0x2009, 0x4e49, + 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2011, 0x4e89, 0x2214, + 0x0078, 0x15b8, 0x2061, 0x4e40, 0x6128, 0x622c, 0x8214, 0x8214, + 0x8214, 0x7810, 0xd0ec, 0x00c0, 0x1766, 0x2061, 0x4e80, 0x6328, + 0x73da, 0x632c, 0x831c, 0x831c, 0x831c, 0x73de, 0x0078, 0x15b8, + 0x2009, 0x4e4c, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2011, + 0x4e8c, 0x2214, 0x0078, 0x15b8, 0x7918, 0x0078, 0x15b9, 0x2009, + 0x4e4d, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2011, 0x4e8d, + 0x2214, 0x0078, 0x15b8, 0x2009, 0x4e4e, 0x210c, 0x7810, 0xd0ec, + 0x00c0, 0x15b9, 0x2011, 0x4e8e, 0x2214, 0x0078, 0x15b8, 0x7920, + 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x7a24, 0x0078, 0x15b8, 0x71c4, + 0xd1fc, 0x00c0, 0x179f, 0x2011, 0x52c0, 0x0078, 0x17a1, 0x2011, + 0x5340, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268, + 0x6a00, 0x6804, 0xd09c, 0x0040, 0x17b0, 0x6b08, 0x0078, 0x17b1, + 0x6b0c, 0x0078, 0x15b7, 0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000, + 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, 0x0078, 0x15b7, 0x2061, + 0x4e40, 0x6118, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2061, 0x4e80, + 0x6218, 0x0078, 0x15b8, 0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000, + 0x6908, 0x6a18, 0x6b10, 0x77da, 0x2091, 0x8001, 0x0078, 0x15b7, + 0x71c4, 0x2110, 0xa294, 0x000f, 0xa282, 0x0010, 0x00c8, 0x15b2, + 0x1078, 0x277f, 0xa384, 0x4000, 0x0040, 0x17e8, 0xa295, 0x0020, + 0x0078, 0x15b7, 0x71c4, 0x2100, 0xc0bc, 0xa082, 0x0010, 0x00c8, + 0x15b2, 0xd1bc, 0x00c0, 0x17f9, 0x2011, 0x4e48, 0x2204, 0x0078, + 0x17fd, 0x2011, 0x4e88, 0x2204, 0xc0bd, 0x007e, 0x2100, 0xc0bc, + 0x2012, 0x1078, 0x26dc, 0x017f, 0x0078, 0x15b9, 0x71c4, 0x2021, + 0x4e49, 0x2404, 0x70c6, 0x2019, 0x0000, 0x0078, 0x1815, 0x71c8, + 0x2021, 0x4e89, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x1834, 0x20a9, + 0x0008, 0x2204, 0xa106, 0x0040, 0x1824, 0x8210, 0x00f0, 0x1819, + 0x71c4, 0x72c8, 0x0078, 0x15b1, 0xa292, 0x1834, 0x027e, 0x2122, + 0x017f, 0x1078, 0x26fd, 0x7810, 0xd0ec, 0x00c0, 0x1832, 0xd3fc, + 0x0040, 0x180f, 0x0078, 0x15ba, 0x03e8, 0x00fa, 0x01f4, 0x02ee, + 0x0004, 0x0001, 0x0002, 0x0003, 0x2061, 0x4e40, 0x6128, 0x622c, + 0x8214, 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, 0x8003, 0x8003, + 0x8003, 0x602e, 0x7810, 0xd0ec, 0x00c0, 0x1862, 0x027e, 0x017e, + 0x2061, 0x4e80, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, 0x70d8, + 0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, 0x602e, 0x71da, 0x72de, + 0x017f, 0x027f, 0x0078, 0x15b8, 0x2061, 0x4e40, 0x6130, 0x70c4, + 0x6032, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2061, 0x4e80, 0x6230, + 0x70c8, 0x6032, 0x0078, 0x15b8, 0x7918, 0x0078, 0x15b9, 0x71c4, + 0xa184, 0xffcf, 0x0040, 0x1883, 0x7810, 0xd0ec, 0x00c0, 0x15b2, + 0x72c8, 0x0078, 0x15b1, 0x2011, 0x4e4d, 0x2204, 0x2112, 0x007e, + 0x2019, 0x0000, 0x1078, 0x2764, 0x7810, 0xd0ec, 0x0040, 0x1893, + 0x017f, 0x0078, 0x15b9, 0x71c8, 0xa184, 0xffcf, 0x0040, 0x189c, + 0x2110, 0x71c4, 0x0078, 0x15b1, 0x2011, 0x4e8d, 0x2204, 0x2112, + 0x007e, 0xc3fd, 0x1078, 0x2764, 0x027f, 0x017f, 0x0078, 0x15b8, + 0x71c4, 0xa182, 0x0010, 0x0048, 0x18b4, 0x7810, 0xd0ec, 0x00c0, + 0x15b2, 0x72c8, 0x0078, 0x15b1, 0x2011, 0x4e4e, 0x2204, 0x007e, + 0x2112, 0x2019, 0x0000, 0x1078, 0x2742, 0x7810, 0xd0ec, 0x0040, + 0x18c4, 0x017f, 0x0078, 0x15b9, 0x71c8, 0xa182, 0x0010, 0x0048, + 0x18cd, 0x2110, 0x71c4, 0x0078, 0x15b1, 0x2011, 0x4e8e, 0x2204, + 0x007e, 0x2112, 0xc3fd, 0x1078, 0x2742, 0x027f, 0x017f, 0x0078, + 0x15b8, 0x71c4, 0x72c8, 0xa184, 0xfffd, 0x00c0, 0x15b1, 0xa284, + 0xfffd, 0x00c0, 0x15b1, 0x2100, 0x7920, 0x7822, 0x2200, 0x7a24, + 0x7826, 0x0078, 0x15b8, 0x71c4, 0xd1fc, 0x00c0, 0x18f3, 0x2011, + 0x52c0, 0x0078, 0x18f5, 0x2011, 0x5340, 0x8107, 0xa084, 0x000f, + 0x8003, 0x8003, 0x8003, 0xa268, 0x2019, 0x0000, 0x72c8, 0x2091, + 0x8000, 0x6800, 0x007e, 0xa226, 0x0040, 0x191e, 0x6a02, 0xd4ec, + 0x0040, 0x190b, 0xc3a5, 0xd4e4, 0x0040, 0x190f, 0xc39d, 0xd4f4, + 0x0040, 0x191e, 0x810f, 0xd2f4, 0x0040, 0x191a, 0x1078, 0x27c1, + 0x0078, 0x191e, 0x1078, 0x279f, 0x0078, 0x191e, 0x72cc, 0x6808, + 0xa206, 0x0040, 0x1940, 0xa2a4, 0x00ff, 0x7814, 0xd0e4, 0x00c0, + 0x1931, 0xa482, 0x0028, 0x0048, 0x193d, 0x0040, 0x193d, 0x0078, + 0x1935, 0xa482, 0x0043, 0x0048, 0x193d, 0x71c4, 0x71c6, 0x027f, + 0x72ca, 0x2091, 0x8001, 0x0078, 0x15b3, 0x6a0a, 0xa39d, 0x000a, + 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4, 0x2091, 0x8001, + 0x0078, 0x15b7, 0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000, 0x6a14, + 0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708, + 0x0078, 0x15b7, 0x70c4, 0x2061, 0x4e40, 0x6118, 0x601a, 0x7810, + 0xd0ec, 0x00c0, 0x15b9, 0x70c8, 0x2061, 0x4e80, 0x6218, 0x601a, + 0x0078, 0x15b8, 0x71c4, 0x72c8, 0x73cc, 0xa182, 0x0010, 0x00c8, + 0x15b2, 0x1078, 0x27e3, 0xa384, 0x4000, 0x0040, 0x1979, 0xa295, + 0x0020, 0x0078, 0x15b7, 0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000, + 0x6a08, 0xc28d, 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078, 0x15b8, + 0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9, + 0x6a0a, 0x6804, 0xa005, 0x0040, 0x1997, 0x1078, 0x2628, 0x2091, + 0x8001, 0x2708, 0x0078, 0x15b8, 0x77c4, 0x1078, 0x1de4, 0x2091, + 0x8000, 0x6a08, 0xc295, 0x6a0a, 0x6804, 0xa005, 0x0040, 0x19aa, + 0x1078, 0x2628, 0x2091, 0x8001, 0x2708, 0x0078, 0x15b8, 0x77c4, + 0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, + 0x1078, 0x1dff, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0078, 0x15b8, + 0x77c4, 0x7814, 0xd0e4, 0x00c0, 0x19d4, 0xd7fc, 0x0040, 0x19ce, + 0x1078, 0x1d64, 0x0040, 0x19d4, 0x0078, 0x15bc, 0x1078, 0x1d54, + 0x0040, 0x19d4, 0x0078, 0x15bc, 0x73c8, 0x72cc, 0x77c6, 0x73ca, + 0x72ce, 0x1078, 0x1e86, 0x00c0, 0x19fe, 0x6818, 0xa005, 0x0040, + 0x19f8, 0x2708, 0x077e, 0x1078, 0x2813, 0x077f, 0x00c0, 0x19f8, + 0x2001, 0x0015, 0xd7fc, 0x00c0, 0x19f1, 0x2061, 0x4e40, 0x0078, + 0x19f4, 0xc0fd, 0x2061, 0x4e80, 0x782a, 0x2091, 0x8001, 0x007c, + 0x2091, 0x8001, 0x2001, 0x4005, 0x0078, 0x15bc, 0x2091, 0x8001, + 0x0078, 0x15ba, 0x77c4, 0x7814, 0xd0e4, 0x00c0, 0x1a16, 0xd7fc, + 0x0040, 0x1a10, 0x1078, 0x1d64, 0x0040, 0x1a16, 0x0078, 0x15bc, + 0x1078, 0x1d54, 0x0040, 0x1a16, 0x0078, 0x15bc, 0x77c6, 0x2041, + 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078, + 0x1dff, 0x2009, 0x0016, 0xd7fc, 0x00c0, 0x1a2a, 0x2061, 0x4e40, + 0x0078, 0x1a2d, 0x2061, 0x4e80, 0xc1fd, 0x6067, 0x0003, 0x607f, + 0x0000, 0x6776, 0x6083, 0x000f, 0x792a, 0x61d4, 0xc1dc, 0x61d6, + 0x1078, 0x2628, 0x2091, 0x8001, 0x007c, 0x77c8, 0x77ca, 0x77c4, + 0x77c6, 0x7814, 0xd0e4, 0x00c0, 0x1a54, 0xd7fc, 0x0040, 0x1a4e, + 0x1078, 0x1d64, 0x0040, 0x1a54, 0x0078, 0x15bc, 0x1078, 0x1d54, + 0x0040, 0x1a54, 0x0078, 0x15bc, 0xa7bc, 0xff00, 0x2091, 0x8000, + 0x2009, 0x0017, 0xd7fc, 0x00c0, 0x1a61, 0x2061, 0x4e40, 0x0078, + 0x1a64, 0x2061, 0x4e80, 0xc1fd, 0x607f, 0x0000, 0x6067, 0x0002, + 0x6776, 0x6083, 0x000f, 0x792a, 0x61d4, 0xc1dc, 0x61d6, 0x1078, + 0x2628, 0x2091, 0x8001, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, + 0x0010, 0x2091, 0x8000, 0x70c8, 0xa005, 0x0040, 0x1a82, 0x60d4, + 0xc0fd, 0x60d6, 0x1078, 0x1dff, 0x70c8, 0x6836, 0x8738, 0xa784, + 0x001f, 0x00c0, 0x1a82, 0x2091, 0x8001, 0x007c, 0x2019, 0x0000, + 0x7814, 0xd0e4, 0x00c0, 0x1aa4, 0x72c8, 0xd284, 0x0040, 0x1a9e, + 0x1078, 0x1d64, 0x0040, 0x1aa4, 0x0078, 0x15bc, 0x1078, 0x1d54, + 0x0040, 0x1aa4, 0x0078, 0x15bc, 0x72c8, 0x72ca, 0x78ac, 0xa084, + 0x0003, 0x00c0, 0x1acf, 0x2039, 0x0000, 0xd284, 0x0040, 0x1ab1, + 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x1078, + 0x1de4, 0x2091, 0x8000, 0x6808, 0xc0d4, 0xa80d, 0x690a, 0x2091, + 0x8001, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1ab7, 0xa7bc, 0xff00, + 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1ab7, 0x2091, + 0x8000, 0x72c8, 0xd284, 0x00c0, 0x1ae1, 0x7810, 0xd0ec, 0x0040, + 0x1add, 0x2069, 0x0100, 0x0078, 0x1ae3, 0x2069, 0x0200, 0x0078, + 0x1ae3, 0x2069, 0x0100, 0x6808, 0xa084, 0xfffd, 0x680a, 0x6830, + 0xd0b4, 0x0040, 0x1b03, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, + 0xd094, 0x0040, 0x1af5, 0x00f0, 0x1aef, 0x684b, 0x0009, 0x20a9, + 0x0014, 0x6848, 0xd084, 0x0040, 0x1aff, 0x00f0, 0x1af9, 0x20a9, + 0x00fa, 0x00f0, 0x1b01, 0x2079, 0x4e00, 0x2009, 0x0018, 0x72c8, + 0xd284, 0x00c0, 0x1b0f, 0x2061, 0x4e40, 0x0078, 0x1b12, 0x2061, + 0x4e80, 0xc1fd, 0x607f, 0x0000, 0x792a, 0x6067, 0x0001, 0x6083, + 0x000f, 0x60a7, 0x0000, 0x60a8, 0x60b2, 0x60b6, 0x60d4, 0xd0b4, + 0x0040, 0x1b2e, 0xc0b4, 0x60d6, 0x0c7e, 0x60b8, 0xa065, 0x6008, + 0xc0d4, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x60d4, 0xa084, + 0x77ff, 0x60d6, 0x78ac, 0xc08d, 0x78ae, 0x83ff, 0x0040, 0x1b39, + 0x007c, 0x681b, 0x0047, 0x2091, 0x8001, 0x007c, 0x73cc, 0x1078, + 0x1a90, 0x69ec, 0x6a48, 0xa185, 0x1800, 0x684a, 0xa185, 0x0040, + 0x68ee, 0x73cc, 0x2021, 0x0004, 0x20a9, 0x09ff, 0x00f0, 0x1b4e, + 0x8421, 0x00c0, 0x1b4c, 0x8319, 0x00c0, 0x1b4a, 0x69ee, 0x6a4a, + 0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x1b62, 0x2069, 0x4e40, + 0x0078, 0x1b64, 0x2069, 0x4e80, 0x71c4, 0x71c6, 0x6916, 0x81ff, + 0x00c0, 0x1b6c, 0x68a7, 0x0001, 0x78ac, 0xc08c, 0x78ae, 0xd084, + 0x00c0, 0x1b74, 0x1078, 0x1ee6, 0x007c, 0x75d8, 0x74dc, 0x75da, + 0x74de, 0x0078, 0x1b7e, 0x2029, 0x0000, 0x2520, 0x71c4, 0x73c8, + 0x72cc, 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x4e00, 0x7dde, 0x7cda, + 0x7bd6, 0x7ad2, 0x1078, 0x1dbd, 0x0040, 0x1c80, 0x20a9, 0x0005, + 0x20a1, 0x4e14, 0x2091, 0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, + 0x0040, 0x1078, 0x1fd1, 0x0040, 0x1ba1, 0x1078, 0x1dc6, 0x0078, + 0x1c80, 0x6004, 0xa08c, 0x00ff, 0xa18e, 0x0009, 0x00c0, 0x1bac, + 0x007e, 0x1078, 0x2378, 0x007f, 0xa084, 0xff00, 0x8007, 0x8009, + 0x0040, 0x1c20, 0x0c7e, 0x2c68, 0x1078, 0x1dbd, 0x0040, 0x1bf2, + 0x2c00, 0x689e, 0x8109, 0x00c0, 0x1bb3, 0x609f, 0x0000, 0x0c7f, + 0x0c7e, 0x7ddc, 0x7cd8, 0x7bd4, 0x7ad0, 0xa290, 0x0040, 0xa399, + 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x7dde, 0x7cda, 0x7bd6, + 0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0040, 0x1c1f, 0x2009, 0x0040, + 0x1078, 0x1fd1, 0x00c0, 0x1c09, 0x6004, 0xa084, 0x00ff, 0xa086, + 0x0002, 0x00c0, 0x1bf2, 0x6004, 0xa084, 0x00ff, 0xa086, 0x000a, + 0x00c0, 0x1bee, 0x017e, 0x1078, 0x2374, 0x017f, 0x2d00, 0x6002, + 0x0078, 0x1bc1, 0x0c7f, 0x0c7e, 0x609c, 0x1078, 0x1e49, 0x0c7f, + 0x609f, 0x0000, 0x1078, 0x1c84, 0x2009, 0x0018, 0x6008, 0xc0cd, + 0x600a, 0x6004, 0x6086, 0x1078, 0x1d74, 0x1078, 0x1dc6, 0x0078, + 0x1c80, 0x0c7f, 0x0c7e, 0x609c, 0x1078, 0x1e49, 0x0c7f, 0x609f, + 0x0000, 0x1078, 0x1c84, 0x2009, 0x0018, 0x6087, 0x0103, 0x601b, + 0x0003, 0x1078, 0x1d74, 0x1078, 0x1dc6, 0x0078, 0x1c80, 0x0c7f, + 0x7814, 0xd0e4, 0x00c0, 0x1c45, 0x6114, 0xd1fc, 0x0040, 0x1c2e, + 0x1078, 0x1d64, 0x0040, 0x1c45, 0x0078, 0x1c32, 0x1078, 0x1d54, + 0x0040, 0x1c45, 0x2029, 0x0000, 0x2520, 0x2009, 0x0018, 0x73c8, + 0x72cc, 0x6087, 0x0103, 0x601b, 0x0021, 0x1078, 0x1d74, 0x1078, + 0x1dc6, 0x2001, 0x4007, 0x0078, 0x15bc, 0x74c4, 0x73c8, 0x72cc, + 0x6014, 0x2091, 0x8000, 0x0e7e, 0x2009, 0x0012, 0xd0fc, 0x00c0, + 0x1c55, 0x2071, 0x4e40, 0x0078, 0x1c58, 0x2071, 0x4e80, 0xc1fd, + 0x792a, 0x7067, 0x0005, 0x71d4, 0xc1dc, 0x71d6, 0x736a, 0x726e, + 0x7472, 0x7076, 0x707b, 0x0000, 0x2c00, 0x707e, 0xa02e, 0x2530, + 0x611c, 0xa184, 0x0060, 0x0040, 0x1c6f, 0x1078, 0x4632, 0x0e7f, + 0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, + 0x6714, 0x6023, 0x0000, 0x1078, 0x2628, 0x2091, 0x8001, 0x007c, + 0x70c3, 0x4005, 0x0078, 0x15bd, 0x20a9, 0x0005, 0x2099, 0x4e14, + 0x2091, 0x8000, 0x530a, 0x2091, 0x8001, 0x2100, 0xa210, 0xa399, + 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x007c, 0x71c4, 0x70c7, + 0x0000, 0x791e, 0x0078, 0x15ba, 0x71c4, 0x71c6, 0x2168, 0x0078, + 0x1ca3, 0x2069, 0x1000, 0x690c, 0xa016, 0x2d04, 0xa210, 0x8d68, + 0x8109, 0x00c0, 0x1ca5, 0xa285, 0x0000, 0x00c0, 0x1cb3, 0x70c3, + 0x4000, 0x0078, 0x1cb5, 0x70c3, 0x4003, 0x70ca, 0x0078, 0x15bd, + 0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, 0x00c8, 0x15b2, 0x7966, + 0x0078, 0x15ba, 0x7964, 0x71c6, 0x0078, 0x15ba, 0x7900, 0x71c6, + 0x71c4, 0x7902, 0x0078, 0x15ba, 0x7900, 0x71c6, 0x0078, 0x15ba, + 0x70c4, 0x2011, 0x0000, 0xa08c, 0x000d, 0x0040, 0x1ce5, 0x810c, + 0x0048, 0x1ce1, 0x8210, 0x810c, 0x810c, 0x0048, 0x1ce1, 0x8210, + 0x810c, 0x81ff, 0x00c0, 0x15b3, 0x8210, 0x7a0e, 0xd28c, 0x0040, + 0x1d11, 0x7910, 0xc1cd, 0x7912, 0x2009, 0x0021, 0x2019, 0x0003, + 0xd284, 0x0040, 0x1d0b, 0x8108, 0x2019, 0x0041, 0x2011, 0x964e, + 0x2312, 0x2019, 0x0042, 0x8210, 0x2312, 0x2019, 0x0043, 0x8210, + 0x2312, 0x2019, 0x0046, 0x8210, 0x2312, 0x2019, 0x0047, 0x8210, + 0x2312, 0x2019, 0x0006, 0x2011, 0x9653, 0x2112, 0x2011, 0x9673, + 0x2312, 0x7904, 0x7806, 0x0078, 0x15b9, 0x7804, 0x70c6, 0x0078, + 0x15ba, 0x71c4, 0xd1fc, 0x00c0, 0x1d21, 0x2011, 0x52c0, 0x0078, + 0x1d23, 0x2011, 0x5340, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, + 0x8003, 0xa268, 0x6a14, 0xd2b4, 0x0040, 0x1d32, 0x2011, 0x0001, + 0x0078, 0x1d34, 0x2011, 0x0000, 0x6b0c, 0x6800, 0x70da, 0x0078, + 0x15b7, 0x017e, 0x7814, 0xd0f4, 0x0040, 0x1d46, 0x2001, 0x4007, + 0x70db, 0x0000, 0xa18d, 0x0001, 0x0078, 0x1d52, 0xd0fc, 0x0040, + 0x1d51, 0x2001, 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0078, + 0x1d52, 0xa006, 0x017f, 0x007c, 0x017e, 0x7814, 0xd0f4, 0x0040, + 0x1d61, 0x2001, 0x4007, 0x70db, 0x0000, 0xa18d, 0x0001, 0x0078, + 0x1d62, 0xa006, 0x017f, 0x007c, 0x017e, 0x7814, 0xd0fc, 0x0040, + 0x1d71, 0x2001, 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0078, + 0x1d72, 0xa006, 0x017f, 0x007c, 0x7112, 0x721a, 0x731e, 0x7810, + 0xd0c4, 0x0040, 0x1d7d, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108, + 0x810c, 0x81a9, 0x8098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x6084, + 0x20a2, 0x53a6, 0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0040, + 0x1d9a, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, + 0x0078, 0x1d9d, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, + 0xa006, 0xa211, 0x7d10, 0xd5c4, 0x0040, 0x1daa, 0x7b84, 0xa319, + 0x7c80, 0xa421, 0x7008, 0xd0fc, 0x0040, 0x1daa, 0x7003, 0x0001, + 0x7007, 0x0006, 0x711a, 0x721e, 0x7d10, 0xd5c4, 0x0040, 0x1dba, + 0x7322, 0x7426, 0xa084, 0x01e0, 0x007c, 0x7848, 0xa065, 0x0040, + 0x1dc5, 0x2c04, 0x784a, 0x2063, 0x0000, 0x007c, 0x0f7e, 0x2079, + 0x4e00, 0x7848, 0x2062, 0x2c00, 0xa005, 0x00c0, 0x1dd1, 0x1078, + 0x296b, 0x784a, 0x0f7f, 0x007c, 0x2011, 0x9800, 0x7a4a, 0x7bc4, + 0x8319, 0x0040, 0x1de1, 0xa280, 0x0032, 0x2012, 0x2010, 0x0078, + 0x1dd8, 0x2013, 0x0000, 0x007c, 0x017e, 0x027e, 0xd7fc, 0x00c0, + 0x1ded, 0x2011, 0x53c0, 0x0078, 0x1def, 0x2011, 0x73c0, 0xa784, + 0x0f00, 0x800b, 0xa784, 0x001f, 0x0040, 0x1dfa, 0x8003, 0x8003, + 0x8003, 0x8003, 0xa105, 0xa268, 0x027f, 0x017f, 0x007c, 0x1078, + 0x1de4, 0x2900, 0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, 0xf9ef, + 0xa80d, 0x690a, 0x0e7e, 0xd7fc, 0x00c0, 0x1e14, 0x2009, 0x4e53, + 0x2071, 0x4e40, 0x0078, 0x1e18, 0x2009, 0x4e93, 0x2071, 0x4e80, + 0x210c, 0x6804, 0xa005, 0x0040, 0x1e28, 0xa116, 0x00c0, 0x1e28, + 0x2060, 0x6000, 0x6806, 0x017e, 0x200b, 0x0000, 0x0078, 0x1e2b, + 0x2009, 0x0000, 0x017e, 0x6804, 0xa065, 0x0040, 0x1e40, 0x6000, + 0x6806, 0x1078, 0x1e5b, 0x1078, 0x201d, 0x6810, 0x7908, 0x8109, + 0x790a, 0x8001, 0x6812, 0x00c0, 0x1e2b, 0x7910, 0xc1a5, 0x7912, + 0x017f, 0x6902, 0x6906, 0x2d00, 0x2060, 0x1078, 0x2acc, 0x0e7f, + 0x007c, 0xa065, 0x0040, 0x1e5a, 0x2008, 0x609c, 0xa005, 0x0040, + 0x1e57, 0x2062, 0x609f, 0x0000, 0xa065, 0x0078, 0x1e4d, 0x7848, + 0x794a, 0x2062, 0x007c, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9, + 0x001c, 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828, + 0x601a, 0x682c, 0x6022, 0x007c, 0x0e7e, 0xd7fc, 0x00c0, 0x1e76, + 0x2071, 0x4e40, 0x2031, 0x4ec0, 0x0078, 0x1e7a, 0x2071, 0x4e80, + 0x2031, 0x50c0, 0x7050, 0xa08c, 0x0200, 0x00c0, 0x1e84, 0xa608, + 0x2d0a, 0x8000, 0x7052, 0xa006, 0x0e7f, 0x007c, 0x0f7e, 0xd7fc, + 0x00c0, 0x1e8e, 0x2079, 0x4e40, 0x0078, 0x1e90, 0x2079, 0x4e80, + 0x1078, 0x1de4, 0x2091, 0x8000, 0x6804, 0x780a, 0xa065, 0x0040, + 0x1ee4, 0x0078, 0x1ea2, 0x2c00, 0x780a, 0x2060, 0x6000, 0xa065, + 0x0040, 0x1ee4, 0x6010, 0xa306, 0x00c0, 0x1e9b, 0x600c, 0xa206, + 0x00c0, 0x1e9b, 0x2c28, 0x784c, 0xac06, 0x00c0, 0x1eb1, 0x0078, + 0x1ee1, 0x6804, 0xac06, 0x00c0, 0x1ebf, 0x6000, 0x2060, 0x6806, + 0xa005, 0x00c0, 0x1ebf, 0x6803, 0x0000, 0x0078, 0x1ec9, 0x6400, + 0x7808, 0x2060, 0x6402, 0xa486, 0x0000, 0x00c0, 0x1ec9, 0x2c00, + 0x6802, 0x2560, 0x0f7f, 0x1078, 0x1e5b, 0x0f7e, 0x601b, 0x0005, + 0x6023, 0x0020, 0x0f7f, 0x1078, 0x201d, 0x0f7e, 0x7908, 0x8109, + 0x790a, 0x6810, 0x8001, 0x6812, 0x00c0, 0x1ee1, 0x7810, 0xc0a5, + 0x7812, 0x2001, 0xffff, 0xa005, 0x0f7f, 0x007c, 0x077e, 0x2700, + 0x2039, 0x0000, 0xd0fc, 0x0040, 0x1eee, 0xc7fd, 0x2041, 0x0021, + 0x2049, 0x0004, 0x2051, 0x0008, 0x2091, 0x8000, 0x1078, 0x1dff, + 0x8738, 0xa784, 0x001f, 0x00c0, 0x1ef6, 0xa7bc, 0xff00, 0x873f, + 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1ef6, 0x2091, 0x8001, + 0x077f, 0x007c, 0x786c, 0x2009, 0x9674, 0x210c, 0xa10d, 0x0040, + 0x1f14, 0xa065, 0x0078, 0x2395, 0x2061, 0x0000, 0x6018, 0xd084, + 0x00c0, 0x1f34, 0x7810, 0xd08c, 0x0040, 0x1f25, 0xc08c, 0x7812, + 0xc7fc, 0x2069, 0x4e40, 0x0078, 0x1f2a, 0xc08d, 0x7812, 0x2069, + 0x4e80, 0xc7fd, 0x2091, 0x8000, 0x681c, 0x681f, 0x0000, 0x2091, + 0x8001, 0xa005, 0x00c0, 0x1f35, 0x007c, 0xa08c, 0xfff0, 0x0040, + 0x1f3b, 0x1078, 0x296b, 0x0079, 0x1f3d, 0x1f4d, 0x1f50, 0x1f56, + 0x1f5a, 0x1f4e, 0x1f5e, 0x1f4e, 0x1f4e, 0x1f4e, 0x1f64, 0x1f95, + 0x1f99, 0x1f9f, 0x1fb4, 0x1f4e, 0x1f4e, 0x007c, 0x1078, 0x296b, + 0x1078, 0x1ee6, 0x2001, 0x8001, 0x0078, 0x1fc0, 0x2001, 0x8003, + 0x0078, 0x1fc0, 0x2001, 0x8004, 0x0078, 0x1fc0, 0x1078, 0x1ee6, + 0x2001, 0x8006, 0x0078, 0x1fc0, 0x2091, 0x8000, 0x077e, 0xd7fc, + 0x00c0, 0x1f70, 0x2069, 0x4e40, 0x2039, 0x0009, 0x0078, 0x1f74, + 0x2069, 0x4e80, 0x2039, 0x0009, 0x6800, 0xa086, 0x0000, 0x0040, + 0x1f7e, 0x007f, 0x6f1e, 0x2091, 0x8001, 0x007c, 0x6874, 0x077f, + 0xa0bc, 0xff00, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010, + 0x1078, 0x1dff, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1f88, 0x2091, + 0x8001, 0x2001, 0x800a, 0x0078, 0x1fc0, 0x2001, 0x800c, 0x0078, + 0x1fc0, 0x1078, 0x1ee6, 0x2001, 0x800d, 0x0078, 0x1fc0, 0x7814, + 0xd0e4, 0x00c0, 0x1fb2, 0xd0ec, 0x0040, 0x1fac, 0xd7fc, 0x0040, + 0x1fac, 0x78e4, 0x0078, 0x1fad, 0x78e0, 0x70c6, 0x2001, 0x800e, + 0x0078, 0x1fc0, 0x0078, 0x1f4e, 0xd7fc, 0x0040, 0x1fba, 0x78ec, + 0x0078, 0x1fbb, 0x78e8, 0x70c6, 0x2001, 0x800f, 0x0078, 0x1fc0, + 0x70c2, 0xd7fc, 0x00c0, 0x1fc8, 0x70db, 0x0000, 0x0078, 0x1fca, + 0x70db, 0x0001, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080, + 0x007c, 0xac80, 0x0001, 0x81ff, 0x0040, 0x1ffc, 0x2099, 0x0030, + 0x20a0, 0x700c, 0xa084, 0x03ff, 0x0040, 0x1fde, 0x7018, 0x007e, + 0x701c, 0x007e, 0x7020, 0x007e, 0x7024, 0x007e, 0x7112, 0x81ac, + 0x721a, 0x731e, 0x7422, 0x7526, 0x7003, 0x0001, 0x7007, 0x0001, + 0x7008, 0x800b, 0x00c8, 0x1ff0, 0x7007, 0x0002, 0xa08c, 0x01e0, + 0x00c0, 0x1ffc, 0x53a5, 0xa006, 0x7003, 0x0000, 0x7007, 0x0004, + 0x007f, 0x7026, 0x007f, 0x7022, 0x007f, 0x701e, 0x007f, 0x701a, + 0x007c, 0x2011, 0x0020, 0x2009, 0x0010, 0x6b0a, 0x6c0e, 0x6803, + 0xfd00, 0x6807, 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, + 0x0004, 0x8109, 0x00c0, 0x200d, 0x007c, 0x6004, 0x6086, 0x2c08, + 0x2063, 0x0000, 0x7868, 0xa005, 0x796a, 0x0040, 0x202a, 0x2c02, + 0x0078, 0x202b, 0x796e, 0x007c, 0x0c7e, 0x2061, 0x4e00, 0x6887, + 0x0103, 0x2d08, 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040, + 0x203c, 0x2d02, 0x0078, 0x203d, 0x616e, 0x0c7f, 0x007c, 0x2091, + 0x8000, 0x2c04, 0x786e, 0xa005, 0x00c0, 0x2047, 0x786a, 0x2091, + 0x8001, 0x609c, 0xa005, 0x0040, 0x2060, 0x0c7e, 0x2060, 0x2008, + 0x609c, 0xa005, 0x0040, 0x205c, 0x2062, 0x609f, 0x0000, 0xa065, + 0x609c, 0xa005, 0x00c0, 0x2054, 0x7848, 0x794a, 0x2062, 0x0c7f, + 0x7848, 0x2062, 0x609f, 0x0000, 0xac85, 0x0000, 0x00c0, 0x206a, + 0x1078, 0x296b, 0x784a, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004, + 0x8086, 0x818e, 0x00c8, 0x2075, 0xa200, 0x00f0, 0x2070, 0x8086, + 0x818e, 0x007c, 0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x209b, + 0xa11a, 0x00c8, 0x209b, 0x8213, 0x818d, 0x0048, 0x208e, 0xa11a, + 0x00c8, 0x208f, 0x00f0, 0x2083, 0x0078, 0x2093, 0xa11a, 0x2308, + 0x8210, 0x00f0, 0x2083, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, + 0x007f, 0x157f, 0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, + 0x2097, 0x7d74, 0x70d0, 0xa506, 0x0040, 0x2187, 0x7810, 0x2050, + 0x7800, 0xd08c, 0x0040, 0x20c3, 0xdaec, 0x0040, 0x20c3, 0x0e7e, + 0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x20c0, + 0x7008, 0x0e7f, 0xa086, 0x0008, 0x0040, 0x20c3, 0x0078, 0x2187, + 0x0e7f, 0x0078, 0x2187, 0x1078, 0x1dbd, 0x0040, 0x2187, 0xa046, + 0x7970, 0x2500, 0x8000, 0xa112, 0x2009, 0x0040, 0x00c8, 0x20d2, + 0x0078, 0x20d9, 0x72d0, 0xa206, 0x0040, 0x20d9, 0x8840, 0x2009, + 0x0080, 0x0c7e, 0x7112, 0x7007, 0x0001, 0x2099, 0x0030, 0x20a9, + 0x0020, 0xac80, 0x0001, 0x20a0, 0x2061, 0x0000, 0x88ff, 0x0040, + 0x20eb, 0x1078, 0x1dbd, 0x7008, 0xd0fc, 0x0040, 0x20eb, 0x7007, + 0x0002, 0x2091, 0x8001, 0xa08c, 0x01e0, 0x00c0, 0x2122, 0x53a5, + 0x8cff, 0x00c0, 0x2100, 0x88ff, 0x0040, 0x2171, 0x0078, 0x210a, + 0x2c00, 0x788e, 0x20a9, 0x0020, 0xac80, 0x0001, 0x20a0, 0x53a5, + 0x0078, 0x2171, 0xa046, 0x7218, 0x731c, 0xdac4, 0x0040, 0x2112, + 0x7420, 0x7524, 0xa292, 0x0040, 0xa39b, 0x0000, 0xa4a3, 0x0000, + 0xa5ab, 0x0000, 0x721a, 0x731e, 0xdac4, 0x0040, 0x2122, 0x7422, + 0x7526, 0xa006, 0x7007, 0x0004, 0x0040, 0x2171, 0x8cff, 0x0040, + 0x212b, 0x1078, 0x1dc6, 0x0c7f, 0x1078, 0x1dc6, 0xa046, 0x7888, + 0x8000, 0x788a, 0xa086, 0x0002, 0x0040, 0x2151, 0x7a7c, 0x7b78, + 0xdac4, 0x0040, 0x213d, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004, + 0x8004, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, + 0x721a, 0x731e, 0xdac4, 0x0040, 0x2187, 0x7422, 0x7526, 0x0078, + 0x2187, 0x6014, 0xd0fc, 0x00c0, 0x2159, 0x2069, 0x4e40, 0x0078, + 0x215b, 0x2069, 0x4e80, 0x2091, 0x8000, 0x681f, 0x0002, 0x88ff, + 0x0040, 0x2167, 0xa046, 0x788c, 0x2060, 0x0078, 0x2151, 0x788b, + 0x0000, 0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091, 0x8001, 0x0078, + 0x2187, 0x0c7f, 0x788b, 0x0000, 0x1078, 0x2346, 0x6004, 0xa084, + 0x000f, 0x1078, 0x2188, 0x88ff, 0x0040, 0x2185, 0x788c, 0x2060, + 0x6004, 0xa084, 0x000f, 0x1078, 0x2188, 0x0078, 0x20a1, 0x007c, + 0x0079, 0x218a, 0x219a, 0x21b8, 0x21d6, 0x219a, 0x21e7, 0x21ab, + 0x219a, 0x219a, 0x219a, 0x21b6, 0x21d4, 0x219a, 0x219a, 0x219a, + 0x219a, 0x219a, 0x2039, 0x0400, 0x78bc, 0xa705, 0x78be, 0x6008, + 0xa705, 0x600a, 0x1078, 0x222a, 0x609c, 0x78ba, 0x609f, 0x0000, + 0x1078, 0x2330, 0x007c, 0x78bc, 0xd0c4, 0x0040, 0x21b1, 0x0078, + 0x219a, 0x601c, 0xc0bd, 0x601e, 0x0078, 0x21be, 0x1078, 0x2378, + 0x78bc, 0xd0c4, 0x0040, 0x21be, 0x0078, 0x219a, 0x78bf, 0x0000, + 0x6004, 0x8007, 0xa084, 0x00ff, 0x78b2, 0x8001, 0x0040, 0x21d1, + 0x1078, 0x222a, 0x0040, 0x21d1, 0x78bc, 0xc0c5, 0x78be, 0x0078, + 0x21d3, 0x0078, 0x2249, 0x007c, 0x1078, 0x2374, 0x78bc, 0xa08c, + 0x0e00, 0x00c0, 0x21de, 0xd0c4, 0x00c0, 0x21e0, 0x0078, 0x219a, + 0x1078, 0x222a, 0x00c0, 0x21e6, 0x0078, 0x2249, 0x007c, 0x78bc, + 0xd0c4, 0x0040, 0x21ed, 0x0078, 0x219a, 0x78bf, 0x0000, 0x6714, + 0x2011, 0x0001, 0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0040, + 0x220d, 0xa7bc, 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0040, + 0x220d, 0xa7bc, 0x8000, 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e, + 0x0002, 0x0040, 0x220d, 0x0078, 0x2227, 0x1078, 0x1de4, 0x2d00, + 0x2091, 0x8000, 0x682b, 0x0000, 0x682f, 0x0000, 0x6808, 0xa084, + 0xffde, 0x680a, 0xade8, 0x0010, 0x2091, 0x8001, 0x00f0, 0x2210, + 0x8211, 0x0040, 0x2227, 0x20a9, 0x0100, 0x0078, 0x2210, 0x1078, + 0x1dc6, 0x007c, 0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, 0x78b6, + 0x00c0, 0x2235, 0x78ba, 0x0078, 0x223d, 0x689e, 0x2d00, 0x6002, + 0x78b8, 0xad06, 0x00c0, 0x223d, 0x6002, 0x78b0, 0x8001, 0x78b2, + 0x00c0, 0x2248, 0x78bc, 0xc0c4, 0x78be, 0x78b8, 0x2060, 0xa006, + 0x007c, 0x0e7e, 0xa02e, 0x2530, 0x7dba, 0x7db6, 0x65ae, 0x65b2, + 0x601c, 0x60a2, 0x2048, 0xa984, 0xe1ff, 0x601e, 0xa984, 0x0060, + 0x0040, 0x225c, 0x1078, 0x4632, 0x6596, 0x65a6, 0x669a, 0x66aa, + 0x6714, 0x2071, 0x4e80, 0xd7fc, 0x00c0, 0x2268, 0x2071, 0x4e40, + 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x0040, 0x2273, 0x8003, + 0x8003, 0x8003, 0x8003, 0xa105, 0x71c4, 0xa168, 0x2700, 0x8007, + 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0x71c8, 0xa100, 0x60c2, + 0x2091, 0x8000, 0x7814, 0xd0c4, 0x0040, 0x2298, 0xd0ec, 0x0040, + 0x2294, 0xd7fc, 0x00c0, 0x2291, 0xd0f4, 0x00c0, 0x229f, 0x0078, + 0x2298, 0xd0fc, 0x00c0, 0x229f, 0x7810, 0xd0f4, 0x00c0, 0x229f, + 0x6e08, 0xd684, 0x0040, 0x22c9, 0xd9fc, 0x00c0, 0x22c9, 0x2091, + 0x8001, 0x1078, 0x1e5b, 0x2091, 0x8000, 0x1078, 0x201d, 0x2091, + 0x8001, 0x7814, 0xd0e4, 0x00c0, 0x232e, 0x7814, 0xd0c4, 0x0040, + 0x232e, 0xd0ec, 0x0040, 0x22c1, 0xd7fc, 0x00c0, 0x22bc, 0xd0f4, + 0x00c0, 0x22c5, 0x0078, 0x232e, 0xd0fc, 0x00c0, 0x22c5, 0x0078, + 0x232e, 0x7810, 0xd0f4, 0x0040, 0x232e, 0x601b, 0x0021, 0x0078, + 0x232e, 0x6024, 0xa096, 0x0001, 0x00c0, 0x22d0, 0x8000, 0x6026, + 0x6a10, 0x6814, 0xa202, 0x0048, 0x22e3, 0x0040, 0x22e3, 0x2091, 0x8001, 0x2039, 0x0200, 0x609c, 0x78ba, 0x609f, 0x0000, 0x1078, - 0x2303, 0x0078, 0x2301, 0x2c08, 0xd9fc, 0x0040, 0x22de, 0x6800, - 0xa065, 0x0040, 0x22de, 0x6a04, 0x7000, 0xa084, 0x0002, 0x0040, - 0x22d9, 0x704c, 0xa206, 0x00c0, 0x22d9, 0x6b04, 0x2160, 0x2304, - 0x6002, 0xa005, 0x00c0, 0x22d5, 0x6902, 0x2260, 0x6102, 0x0078, - 0x22ea, 0x2160, 0x6202, 0x6906, 0x0078, 0x22ea, 0x6800, 0x6902, - 0xa065, 0x0040, 0x22e6, 0x6102, 0x0078, 0x22e7, 0x6906, 0x2160, - 0x6003, 0x0000, 0x2160, 0xd9fc, 0x0040, 0x22f1, 0xa6b4, 0xfffc, - 0x6e0a, 0x6810, 0x7d08, 0x8528, 0x7d0a, 0x8000, 0x6812, 0x2091, - 0x8001, 0xd6b4, 0x0040, 0x2301, 0xa6b6, 0x0040, 0x6e0a, 0x1078, - 0x1e80, 0x0e7f, 0x007c, 0x6008, 0xa705, 0x600a, 0x2091, 0x8000, - 0x1078, 0x201b, 0x2091, 0x8001, 0x78b8, 0xa065, 0x0040, 0x2316, - 0x609c, 0x78ba, 0x609f, 0x0000, 0x0078, 0x2303, 0x78b6, 0x78ba, - 0x007c, 0x7970, 0x7874, 0x2818, 0xd384, 0x0040, 0x2323, 0x8000, - 0xa112, 0x0048, 0x2328, 0x8000, 0xa112, 0x00c8, 0x2338, 0xc384, - 0x7a7c, 0x721a, 0x7a78, 0x721e, 0xdac4, 0x0040, 0x2333, 0x7a84, - 0x7222, 0x7a80, 0x7226, 0xa006, 0xd384, 0x0040, 0x2338, 0x8000, - 0x7876, 0x70d2, 0x781c, 0xa005, 0x0040, 0x2346, 0x8001, 0x781e, - 0x00c0, 0x2346, 0x0068, 0x2346, 0x2091, 0x4080, 0x007c, 0x2039, - 0x235f, 0x0078, 0x234d, 0x2039, 0x2365, 0x2704, 0xa005, 0x0040, - 0x235e, 0xac00, 0x2068, 0x6908, 0x6810, 0x6912, 0x680a, 0x690c, - 0x6814, 0x6916, 0x680e, 0x8738, 0x0078, 0x234d, 0x007c, 0x0003, - 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0015, 0x001b, 0x0000, - 0x2041, 0x0000, 0x780c, 0x0079, 0x236d, 0x2535, 0x2508, 0x2371, - 0x23e5, 0x2039, 0x9274, 0x2734, 0x7d10, 0x0078, 0x238c, 0x6084, - 0xa086, 0x0103, 0x00c0, 0x23ce, 0x6114, 0x6018, 0xa105, 0x00c0, - 0x23ce, 0x8603, 0xa080, 0x9255, 0x620c, 0x2202, 0x8000, 0x6210, - 0x2202, 0x1078, 0x203d, 0x8630, 0xa68e, 0x000f, 0x0040, 0x2454, - 0x786c, 0xa065, 0x00c0, 0x2377, 0x7808, 0xa602, 0x00c8, 0x239d, - 0xd5ac, 0x00c0, 0x239d, 0x263a, 0x007c, 0xa682, 0x0003, 0x00c8, - 0x2454, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, - 0x23c9, 0x2011, 0x9255, 0x2204, 0x70c6, 0x8210, 0x2204, 0x70ca, - 0xd684, 0x00c0, 0x23b9, 0x8210, 0x2204, 0x70da, 0x8210, 0x2204, - 0x70de, 0xa685, 0x8020, 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, - 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, 0x8001, 0x203b, 0x0000, - 0x007c, 0x7810, 0xc0ad, 0x7812, 0x0078, 0x2454, 0x263a, 0x1078, - 0x253f, 0x00c0, 0x254e, 0x786c, 0xa065, 0x00c0, 0x2377, 0x2091, - 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0040, 0x23e0, 0xc0ad, - 0x7812, 0x2091, 0x8001, 0x0078, 0x254e, 0x2039, 0x9274, 0x2734, - 0x7d10, 0x0078, 0x23fc, 0x6084, 0xa086, 0x0103, 0x00c0, 0x243d, - 0x6114, 0x6018, 0xa105, 0x00c0, 0x243d, 0xa680, 0x9255, 0x620c, - 0x2202, 0x1078, 0x203d, 0x8630, 0xa68e, 0x001e, 0x0040, 0x2454, - 0x786c, 0xa065, 0x00c0, 0x23eb, 0x7808, 0xa602, 0x00c8, 0x240d, - 0xd5ac, 0x00c0, 0x240d, 0x263a, 0x007c, 0xa682, 0x0006, 0x00c8, - 0x2454, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, - 0x2438, 0x2011, 0x9255, 0x2009, 0x924e, 0x26a8, 0x211c, 0x2204, - 0x201a, 0x8108, 0x8210, 0x00f0, 0x241e, 0xa685, 0x8030, 0x70c2, - 0x681b, 0x0001, 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, - 0x2091, 0x8001, 0xa006, 0x2009, 0x9275, 0x200a, 0x203a, 0x007c, - 0x7810, 0xc0ad, 0x7812, 0x0078, 0x2454, 0x263a, 0x1078, 0x253f, - 0x00c0, 0x254e, 0x786c, 0xa065, 0x00c0, 0x23eb, 0x2091, 0x8000, - 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0040, 0x244f, 0xc0ad, 0x7812, - 0x2091, 0x8001, 0x0078, 0x254e, 0x2091, 0x8000, 0x7007, 0x0004, - 0x7994, 0x70d4, 0xa102, 0x0048, 0x2465, 0x0040, 0x246f, 0x7b90, - 0xa302, 0x00c0, 0x246f, 0x0078, 0x2468, 0x8002, 0x00c0, 0x246f, - 0x263a, 0x7810, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x007c, 0xa184, - 0xff00, 0x0040, 0x247c, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, - 0x8007, 0xa100, 0x0078, 0x247f, 0x8107, 0x8004, 0x8004, 0x7a9c, - 0xa210, 0x721a, 0x7a98, 0xa006, 0xa211, 0x721e, 0xd4c4, 0x0040, - 0x248f, 0x7aa4, 0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226, 0x20a1, - 0x0030, 0x7003, 0x0000, 0x2009, 0x9254, 0x260a, 0x8109, 0x2198, - 0x2104, 0xd084, 0x0040, 0x249d, 0x8633, 0xa6b0, 0x0002, 0x26a8, - 0x53a6, 0x8603, 0x7012, 0x7007, 0x0001, 0x7990, 0x7894, 0x8000, - 0xa10a, 0x00c8, 0x24ac, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00, - 0x0040, 0x24bb, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, - 0xa100, 0x0078, 0x24be, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, - 0x7a78, 0xa006, 0xa211, 0xd4c4, 0x0040, 0x24ca, 0x7b84, 0xa319, - 0x7c80, 0xa421, 0x7008, 0xd0fc, 0x0040, 0x24ca, 0xa084, 0x01e0, - 0x0040, 0x24ef, 0x7d10, 0x2031, 0x9254, 0x2634, 0x78a8, 0x8000, - 0x78aa, 0xd08c, 0x00c0, 0x24e4, 0x7007, 0x0006, 0x7004, 0xd094, - 0x00c0, 0x24de, 0x0078, 0x2456, 0x2069, 0x4a47, 0x206b, 0x0003, - 0x78ac, 0xa085, 0x0300, 0x78ae, 0xa006, 0x0078, 0x24f8, 0x2030, - 0x75d6, 0x2091, 0x4080, 0x7d96, 0x7d10, 0xa5ac, 0xffcf, 0x7d12, - 0x2091, 0x8001, 0x78aa, 0x7007, 0x0006, 0x263a, 0x7003, 0x0001, - 0x711a, 0x721e, 0xd5c4, 0x0040, 0x2507, 0x7322, 0x7426, 0x007c, - 0x6084, 0xa086, 0x0103, 0x00c0, 0x252b, 0x6114, 0x6018, 0xa105, - 0x00c0, 0x252b, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, 0x252b, - 0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001, - 0x2091, 0x4080, 0x1078, 0x203d, 0x0068, 0x252a, 0x786c, 0xa065, - 0x00c0, 0x2508, 0x007c, 0x1078, 0x253f, 0x00c0, 0x254e, 0x786c, - 0xa065, 0x00c0, 0x2508, 0x0078, 0x254e, 0x1078, 0x253f, 0x00c0, - 0x254e, 0x786c, 0xa065, 0x00c0, 0x2535, 0x0078, 0x254e, 0x1078, - 0x2554, 0x00c0, 0x2546, 0xa085, 0x0001, 0x007c, 0x1078, 0x2563, - 0x00c0, 0x254c, 0x2041, 0x0001, 0x7d10, 0x007c, 0x88ff, 0x0040, - 0x2553, 0x2091, 0x4080, 0x007c, 0x7b90, 0x7994, 0x70d4, 0xa102, - 0x00c0, 0x255d, 0xa385, 0x0000, 0x007c, 0x0048, 0x2561, 0xa302, - 0x007c, 0x8002, 0x007c, 0x7810, 0xd0ec, 0x0040, 0x257b, 0x0e7e, - 0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x2578, - 0x7008, 0x0e7f, 0xa086, 0x0008, 0x0040, 0x257b, 0x0078, 0x25cc, - 0x0e7f, 0x0078, 0x25cc, 0xa184, 0xff00, 0x0040, 0x2588, 0x810f, - 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0078, 0x258b, - 0x8107, 0x8004, 0x8004, 0x7a9c, 0x7b98, 0x7ca4, 0x7da0, 0xa210, - 0xa006, 0xa319, 0xa421, 0xa529, 0x2009, 0x0018, 0x6028, 0xa005, - 0x0040, 0x259c, 0x2009, 0x0040, 0x1078, 0x1d92, 0x0040, 0x25be, - 0x78a8, 0x8000, 0x78aa, 0xd08c, 0x00c0, 0x25cc, 0x6014, 0xd0fc, - 0x00c0, 0x25ae, 0x2069, 0x4a40, 0x0078, 0x25b0, 0x2069, 0x4a80, - 0x2091, 0x8000, 0x681f, 0x0003, 0x78ab, 0x0000, 0x78ac, 0xa085, - 0x0300, 0x78ae, 0x2091, 0x8001, 0x0078, 0x25cc, 0x78ab, 0x0000, - 0x1078, 0x203d, 0x7990, 0x7894, 0x8000, 0xa10a, 0x00c8, 0x25c9, - 0xa006, 0x7896, 0x70d6, 0xa006, 0x2071, 0x0010, 0x2091, 0x8001, - 0x007c, 0x2138, 0xd7fc, 0x00c0, 0x25d9, 0x2009, 0x4a59, 0x0078, - 0x25db, 0x2009, 0x4a99, 0x2091, 0x8000, 0x200a, 0x0f7e, 0xd7fc, - 0x00c0, 0x25f2, 0x2009, 0x4a40, 0x2001, 0x4a04, 0x2004, 0xd0ec, - 0x0040, 0x25ee, 0x2079, 0x0100, 0x0078, 0x25f6, 0x2079, 0x0200, - 0x0078, 0x25f6, 0x2009, 0x4a80, 0x2079, 0x0100, 0x2104, 0xa086, - 0x0000, 0x00c0, 0x260f, 0xd7fc, 0x00c0, 0x2602, 0x2009, 0x4a45, - 0x0078, 0x2604, 0x2009, 0x4a85, 0x2104, 0xa005, 0x00c0, 0x260f, - 0x7830, 0xa084, 0x00c0, 0x00c0, 0x260f, 0x781b, 0x0045, 0x0f7f, - 0x007c, 0x2009, 0x0002, 0x2069, 0x4a00, 0x6810, 0xd0ec, 0x00c0, - 0x2672, 0x2071, 0x4a80, 0x2079, 0x0100, 0x2021, 0x4cbf, 0x784b, - 0x000f, 0x2019, 0x4205, 0xd184, 0x0040, 0x2632, 0x6810, 0xd0ec, - 0x0040, 0x262e, 0x20a1, 0x012b, 0x0078, 0x2634, 0x20a1, 0x022b, - 0x0078, 0x2634, 0x20a1, 0x012b, 0x2304, 0xa005, 0x0040, 0x2641, - 0x789a, 0x8318, 0x23ac, 0x8318, 0x2398, 0x53a6, 0x3318, 0x0078, - 0x2634, 0x789b, 0x0020, 0x20a9, 0x0010, 0x78af, 0x0000, 0x78af, - 0x8020, 0x00f0, 0x2645, 0x7003, 0x0000, 0x017e, 0xd18c, 0x2009, - 0x0000, 0x0040, 0x2654, 0xc1bd, 0x1078, 0x283d, 0x017f, 0x7020, - 0xa084, 0x000f, 0x007e, 0x6814, 0xd0e4, 0x007f, 0x00c0, 0x2664, - 0xa085, 0x6340, 0x0078, 0x2666, 0xa085, 0x62c0, 0x7806, 0x780f, - 0x9200, 0x7843, 0x00d8, 0x7853, 0x0080, 0x780b, 0x0008, 0x7456, - 0x7053, 0x0000, 0x8109, 0x0040, 0x2685, 0x2071, 0x4a40, 0x6810, - 0xd0ec, 0x0040, 0x267f, 0x2079, 0x0100, 0x0078, 0x2681, 0x2079, - 0x0200, 0x2021, 0x4abf, 0x0078, 0x261f, 0x007c, 0x017e, 0xd1bc, - 0x00c0, 0x269a, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, - 0x0040, 0x2696, 0x2011, 0x0101, 0x0078, 0x269c, 0x2011, 0x0201, - 0x0078, 0x269c, 0x2011, 0x0101, 0xa18c, 0x000f, 0x2204, 0xa084, - 0xfff0, 0xa105, 0x2012, 0x017f, 0x1078, 0x283d, 0x007c, 0xd3fc, - 0x00c0, 0x26ba, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, - 0x0040, 0x26b6, 0x2011, 0x0101, 0x0078, 0x26bc, 0x2011, 0x0201, - 0x0078, 0x26bc, 0x2011, 0x0101, 0x20a9, 0x0009, 0x810b, 0x00f0, - 0x26be, 0xa18c, 0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, - 0x007c, 0x2019, 0x0002, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x0040, - 0x26d6, 0x8319, 0x2009, 0x0101, 0x0078, 0x26d8, 0x2009, 0x0101, - 0x20a9, 0x0005, 0x8213, 0x00f0, 0x26da, 0xa294, 0x00e0, 0x2104, - 0xa084, 0xff1f, 0xa205, 0x200a, 0x8319, 0x0040, 0x26eb, 0x2009, - 0x0201, 0x0078, 0x26d8, 0x007c, 0xd3fc, 0x00c0, 0x26ff, 0x007e, - 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x26fb, 0x2011, - 0x0101, 0x0078, 0x2701, 0x2011, 0x0201, 0x0078, 0x2701, 0x2011, - 0x0101, 0x20a9, 0x000c, 0x810b, 0x00f0, 0x2703, 0xa18c, 0xf000, - 0x2204, 0xa084, 0x0fff, 0xa105, 0x2012, 0x007c, 0xd3fc, 0x00c0, - 0x2721, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, - 0x271d, 0x2011, 0x0102, 0x0078, 0x2723, 0x2011, 0x0202, 0x0078, - 0x2723, 0x2011, 0x0102, 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012, - 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x273d, 0x007e, 0x2001, 0x4a04, - 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2739, 0x2061, 0x0100, 0x0078, - 0x273f, 0x2061, 0x0200, 0x0078, 0x273f, 0x2061, 0x0100, 0xc1bc, - 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x62ac, 0x63ac, 0x0c7f, - 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x275d, 0x007e, 0x2001, 0x4a04, - 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2759, 0x2061, 0x0100, 0x0078, - 0x275f, 0x2061, 0x0200, 0x0078, 0x275f, 0x2061, 0x0100, 0xc1bc, - 0x8103, 0x8003, 0xa080, 0x0022, 0x609a, 0x60a4, 0xa084, 0xffdf, - 0x60ae, 0x0c7f, 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x277f, 0x007e, - 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x277b, 0x2061, - 0x0100, 0x0078, 0x2781, 0x2061, 0x0200, 0x0078, 0x2781, 0x2061, - 0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0022, 0x609a, 0x60a4, - 0xa085, 0x0020, 0x60ae, 0x0c7f, 0x007c, 0x0c7e, 0xd1bc, 0x00c0, - 0x27a1, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, - 0x279d, 0x2061, 0x0100, 0x0078, 0x27a3, 0x2061, 0x0200, 0x0078, - 0x27a3, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, - 0x609a, 0x60a4, 0xa28c, 0x0020, 0x0040, 0x27b1, 0xc2ac, 0xa39d, - 0x4000, 0xc3fc, 0xd3b4, 0x00c0, 0x27b6, 0xc3fd, 0x62ae, 0x2010, - 0x60a4, 0x63ae, 0x2018, 0x0c7f, 0x007c, 0x2091, 0x8000, 0x0c7e, - 0x0e7e, 0x6818, 0xa005, 0x0040, 0x281b, 0xd1fc, 0x0040, 0x27cc, - 0x2061, 0x91d0, 0x0078, 0x27ce, 0x2061, 0x90c0, 0x1078, 0x2823, - 0x0040, 0x2801, 0x20a9, 0x0101, 0xd1fc, 0x0040, 0x27db, 0x2061, - 0x90d0, 0x0078, 0x27dd, 0x2061, 0x8fc0, 0x0c7e, 0x1078, 0x2823, - 0x0040, 0x27e8, 0x0c7f, 0x8c60, 0x00f0, 0x27dd, 0x0078, 0x281b, - 0x007f, 0xd1fc, 0x0040, 0x27f2, 0xa082, 0x90d0, 0x2071, 0x4a80, - 0x0078, 0x27f6, 0xa082, 0x8fc0, 0x2071, 0x4a40, 0x707a, 0x7176, - 0x2001, 0x0004, 0x7066, 0x7083, 0x000f, 0x1078, 0x25d1, 0x0078, - 0x2817, 0xd1fc, 0x00c0, 0x2808, 0x2071, 0x4a40, 0x0078, 0x280a, - 0x2071, 0x4a80, 0x6020, 0xc0dd, 0x6022, 0x7176, 0x2c00, 0x707e, - 0x2001, 0x0006, 0x7066, 0x7083, 0x000f, 0x1078, 0x25d1, 0x2001, - 0x0000, 0x0078, 0x281d, 0x2001, 0x0001, 0x2091, 0x8001, 0xa005, - 0x0e7f, 0x0c7f, 0x007c, 0x2c04, 0xa005, 0x0040, 0x283a, 0x2060, - 0x6010, 0xa306, 0x00c0, 0x2837, 0x600c, 0xa206, 0x00c0, 0x2837, - 0x6014, 0xa106, 0x00c0, 0x2837, 0xa006, 0x0078, 0x283c, 0x6000, - 0x0078, 0x2824, 0xa085, 0x0001, 0x007c, 0x0f7e, 0x0e7e, 0x017e, - 0xd1bc, 0x00c0, 0x2855, 0x2079, 0x4a40, 0x007e, 0x2001, 0x4a04, - 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2851, 0x2071, 0x0100, 0x0078, - 0x2859, 0x2071, 0x0200, 0x0078, 0x2859, 0x2079, 0x4a80, 0x2071, - 0x0100, 0x7920, 0xa18c, 0x000f, 0x70ec, 0xd0c4, 0x00c0, 0x2863, - 0x017f, 0x0078, 0x287e, 0x810b, 0x810b, 0x810b, 0x810b, 0x007f, - 0xd0bc, 0x00c0, 0x287b, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, - 0x007f, 0x0040, 0x2877, 0xa18d, 0x0f00, 0x0078, 0x287d, 0xa18d, - 0x0f00, 0x0078, 0x287d, 0xa18d, 0x0800, 0x2104, 0x0e7f, 0x0f7f, - 0x007c, 0x0e7e, 0x2001, 0x4a01, 0x2004, 0xd0ac, 0x00c0, 0x28ea, - 0x68e4, 0xd0ac, 0x0040, 0x28ea, 0xa084, 0x0006, 0x00c0, 0x28ea, - 0x6014, 0xd0fc, 0x00c0, 0x2898, 0x2071, 0x4ec0, 0x0078, 0x289a, - 0x2071, 0x4f40, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, - 0xae70, 0x7004, 0xa084, 0x000a, 0x00c0, 0x28ea, 0x7108, 0xa194, - 0xff00, 0x0040, 0x28ea, 0xa18c, 0x00ff, 0x2001, 0x000a, 0xa106, - 0x0040, 0x28cd, 0x2001, 0x000c, 0xa106, 0x0040, 0x28d1, 0x2001, - 0x0012, 0xa106, 0x0040, 0x28d5, 0x2001, 0x0014, 0xa106, 0x0040, - 0x28d9, 0x2001, 0x0019, 0xa106, 0x0040, 0x28dd, 0x2001, 0x0032, - 0xa106, 0x0040, 0x28e1, 0x0078, 0x28e5, 0x2009, 0x000c, 0x0078, - 0x28e7, 0x2009, 0x0012, 0x0078, 0x28e7, 0x2009, 0x0014, 0x0078, - 0x28e7, 0x2009, 0x0019, 0x0078, 0x28e7, 0x2009, 0x0020, 0x0078, - 0x28e7, 0x2009, 0x003f, 0x0078, 0x28e7, 0x2011, 0x0000, 0x2100, - 0xa205, 0x700a, 0x0e7f, 0x007c, 0x0068, 0x28ec, 0x2091, 0x8000, - 0x2071, 0x0000, 0x007e, 0x7018, 0xd084, 0x00c0, 0x28f3, 0x007f, - 0x2071, 0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002, 0x70db, - 0x0809, 0x70df, 0x0000, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, - 0x4080, 0x0078, 0x2909, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, - 0x708e, 0x7592, 0x7496, 0x769a, 0x779e, 0xa594, 0x003f, 0xd4f4, - 0x0040, 0x2920, 0xa784, 0x007d, 0x00c0, 0x417b, 0x1078, 0x28ec, - 0xa49c, 0x000f, 0xa382, 0x0004, 0x0050, 0x292b, 0xa3a6, 0x0007, - 0x00c0, 0x28ec, 0x2418, 0x8507, 0xa084, 0x000f, 0x0079, 0x2930, - 0x2f45, 0x3035, 0x3060, 0x32c1, 0x363b, 0x36a1, 0x3741, 0x37bd, - 0x38a1, 0x398a, 0x2943, 0x2940, 0x2d2a, 0x2e43, 0x360e, 0x2940, - 0x1078, 0x28ec, 0x007c, 0xa006, 0x0078, 0x294d, 0x7808, 0xc08d, - 0x780a, 0xa006, 0x7002, 0x704e, 0x7046, 0x70d2, 0x7060, 0xa005, - 0x00c0, 0x2a64, 0x7064, 0xa084, 0x0007, 0x0079, 0x2957, 0x295f, - 0x29cf, 0x29d8, 0x29e3, 0x29ee, 0x2a4a, 0x29f9, 0x29cf, 0x7830, - 0xd0bc, 0x00c0, 0x2942, 0x71d4, 0xd1b4, 0x00c0, 0x29ac, 0x70a4, - 0xa086, 0x0001, 0x0040, 0x2942, 0x70b4, 0xa06d, 0x6800, 0xa065, - 0xa055, 0x789b, 0x0010, 0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, - 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0040, 0x2982, 0x69bc, - 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0010, 0x0078, - 0x2bbd, 0x7060, 0xa005, 0x00c0, 0x2942, 0x0c7e, 0x0d7e, 0x70b4, - 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0010, 0x6b0c, 0x7baa, - 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, - 0x0040, 0x29a5, 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, - 0x2001, 0x0020, 0x0078, 0x2bbd, 0x1078, 0x411c, 0x00c0, 0x2942, - 0x781b, 0x005b, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, - 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a, 0x68bc, - 0x7042, 0xc1b4, 0x71d6, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x7003, - 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x007c, 0x1078, - 0x411c, 0x00c0, 0x29d7, 0x781b, 0x0047, 0x7003, 0x0004, 0x007c, - 0x1078, 0x411c, 0x00c0, 0x29e2, 0x2011, 0x000c, 0x1078, 0x2a09, - 0x7003, 0x0004, 0x007c, 0x1078, 0x411c, 0x00c0, 0x29ed, 0x2011, - 0x0006, 0x1078, 0x2a09, 0x7003, 0x0004, 0x007c, 0x1078, 0x411c, - 0x00c0, 0x29f8, 0x2011, 0x000d, 0x1078, 0x2a09, 0x7003, 0x0004, - 0x007c, 0x1078, 0x411c, 0x00c0, 0x2a08, 0x2011, 0x0006, 0x1078, - 0x2a09, 0x707c, 0x707f, 0x0000, 0x2068, 0x704e, 0x7003, 0x0001, - 0x007c, 0x7174, 0xc1fc, 0x8107, 0x7882, 0x789b, 0x0010, 0xa286, - 0x000c, 0x00c0, 0x2a18, 0x7aaa, 0x2001, 0x0001, 0x0078, 0x2a2d, - 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0xa286, 0x000d, 0x0040, - 0x2a26, 0x7aaa, 0x2001, 0x0002, 0x0078, 0x2a2d, 0x78ab, 0x0020, - 0x7178, 0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b, 0x0060, 0x78aa, - 0x785b, 0x0004, 0x781b, 0x0108, 0x1078, 0x4131, 0x7083, 0x000f, - 0x70d4, 0xd0b4, 0x0040, 0x2a49, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, - 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, - 0x0c7f, 0x007c, 0x1078, 0x411c, 0x00c0, 0x2942, 0x707c, 0x2068, - 0x7774, 0x1078, 0x3fe1, 0x2c50, 0x1078, 0x41f0, 0x789b, 0x0010, - 0x6814, 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001, - 0x2001, 0x0004, 0x0078, 0x2bc3, 0x1078, 0x411c, 0x00c0, 0x2942, - 0x789b, 0x0010, 0x7060, 0x2068, 0x6f14, 0x70d4, 0xd0b4, 0x0040, - 0x2a7e, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, - 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x1078, 0x3fe1, - 0x2c50, 0x1078, 0x41f0, 0x6824, 0xa005, 0x0040, 0x2a8f, 0xa082, - 0x0006, 0x0048, 0x2a8d, 0x0078, 0x2a8f, 0x6827, 0x0005, 0x6814, - 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x2031, 0x0020, 0x2041, 0x0001, - 0x2001, 0x0003, 0x0078, 0x2bc3, 0xc28d, 0x72d6, 0x72c0, 0xa200, - 0xa015, 0x7154, 0x8108, 0xa12a, 0x0048, 0x2aa7, 0x71c0, 0x2164, - 0x6504, 0x85ff, 0x00c0, 0x2abe, 0x7156, 0x8421, 0x00c0, 0x2aa2, - 0x70d4, 0xd08c, 0x0040, 0x2aba, 0x70d0, 0xa005, 0x00c0, 0x2aba, - 0x70d3, 0x000a, 0x007c, 0x2200, 0x0078, 0x2aac, 0x70d4, 0xc08c, - 0x70d6, 0x70d3, 0x0000, 0x603c, 0xa005, 0x00c0, 0x2abb, 0x6708, - 0xa784, 0x073f, 0x0040, 0x2aed, 0xd7d4, 0x00c0, 0x2abb, 0xa784, - 0x0021, 0x00c0, 0x2abb, 0xa784, 0x0002, 0x0040, 0x2ade, 0xa784, - 0x0004, 0x0040, 0x2abb, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218, - 0x00c0, 0x2abb, 0xa784, 0x0100, 0x0040, 0x2aed, 0x6018, 0xa005, - 0x00c0, 0x2abb, 0xa7bc, 0xfeff, 0x670a, 0x2568, 0x6823, 0x0000, - 0x6e1c, 0xa684, 0x000e, 0x6318, 0x0040, 0x2afe, 0x601c, 0xa302, - 0x0048, 0x2b01, 0x0040, 0x2b01, 0x0078, 0x2abb, 0x83ff, 0x00c0, - 0x2abb, 0x2d58, 0x2c50, 0x7156, 0xd7bc, 0x00c0, 0x2b09, 0x7028, - 0x6022, 0xc7bc, 0x670a, 0x68c0, 0xa065, 0xa04d, 0x6100, 0x2a60, - 0x2041, 0x0001, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, 0xd1fc, - 0x0040, 0x2b1d, 0xd684, 0x0040, 0x2b1f, 0xa39c, 0xffbf, 0xd6a4, - 0x0040, 0x2b24, 0xa39d, 0x0020, 0xa684, 0x000e, 0x00c0, 0x2b6f, - 0xc7a5, 0x670a, 0x2c00, 0x68c6, 0x77a4, 0xa786, 0x0001, 0x00c0, - 0x2b43, 0x70d4, 0xd0b4, 0x00c0, 0x2b43, 0x7000, 0xa082, 0x0002, - 0x00c8, 0x2b43, 0x7830, 0xd0bc, 0x00c0, 0x2b43, 0x789b, 0x0010, - 0x7baa, 0x0078, 0x2bbb, 0x8739, 0x77a6, 0x2750, 0x77b0, 0xa7b0, - 0x0005, 0x70ac, 0xa606, 0x00c0, 0x2b4e, 0x76a8, 0x76b2, 0x2c3a, - 0x8738, 0x2d3a, 0x8738, 0x283a, 0x8738, 0x233a, 0x8738, 0x253a, - 0x7830, 0xd0bc, 0x0040, 0x2b66, 0x2091, 0x8000, 0x2091, 0x303d, - 0x70d4, 0xa084, 0x303d, 0x2091, 0x8000, 0x2090, 0xaad5, 0x0000, - 0x0040, 0x2b6e, 0x8421, 0x2200, 0x00c0, 0x2aa1, 0x007c, 0xd1dc, - 0x0040, 0x3be5, 0x2029, 0x0020, 0xd69c, 0x00c0, 0x2b7c, 0x8528, - 0xd68c, 0x00c0, 0x2b7c, 0x8528, 0x8840, 0x6f14, 0x610c, 0x8108, - 0xa18c, 0x00ff, 0x70cc, 0xa160, 0x2c64, 0x8cff, 0x0040, 0x2b9b, - 0x6014, 0xa706, 0x00c0, 0x2b84, 0x60b8, 0x8001, 0x60ba, 0x00c0, - 0x2b7f, 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x2200, 0x8421, - 0x00c0, 0x2aa1, 0x007c, 0x2a60, 0x610e, 0x69be, 0x2c00, 0x68c6, - 0x8840, 0x6008, 0xc0d5, 0x600a, 0x77a4, 0xa786, 0x0001, 0x00c0, - 0x2b43, 0x70d4, 0xd0b4, 0x00c0, 0x2b43, 0x7000, 0xa082, 0x0002, - 0x00c8, 0x2b43, 0x7830, 0xd0bc, 0x00c0, 0x2b43, 0x789b, 0x0010, - 0x7baa, 0x7daa, 0x79aa, 0x2001, 0x0002, 0x007e, 0x6018, 0x8000, - 0x601a, 0x0078, 0x2bc4, 0x007e, 0x2960, 0x6104, 0x2a60, 0xa184, - 0x0018, 0x0040, 0x2be0, 0xa184, 0x0010, 0x0040, 0x2bd3, 0x1078, - 0x3df6, 0x00c0, 0x2c05, 0xa184, 0x0008, 0x0040, 0x2be0, 0x69a0, - 0xa184, 0x0600, 0x00c0, 0x2be0, 0x1078, 0x3cda, 0x0078, 0x2c05, - 0x69a0, 0xa184, 0x1e00, 0x0040, 0x2c10, 0xa184, 0x0800, 0x0040, - 0x2bf9, 0x0c7e, 0x2960, 0x6000, 0xa085, 0x2000, 0x6002, 0x6104, - 0xa18d, 0x0010, 0x6106, 0x0c7f, 0x1078, 0x3df6, 0x00c0, 0x2c05, - 0x69a0, 0xa184, 0x0200, 0x0040, 0x2c01, 0x1078, 0x3d3a, 0x0078, - 0x2c05, 0xa184, 0x0400, 0x00c0, 0x2bdc, 0x69a0, 0xa184, 0x1000, - 0x0040, 0x2c10, 0x6914, 0xa18c, 0xff00, 0x810f, 0x1078, 0x2749, - 0x027f, 0xa68c, 0x00e0, 0xa684, 0x0060, 0x0040, 0x2c1d, 0xa086, - 0x0060, 0x00c0, 0x2c1d, 0xa18d, 0x4000, 0xa18d, 0x0104, 0x69b6, - 0x789b, 0x0060, 0x2800, 0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc, - 0x0040, 0x2c38, 0xc0fc, 0x7087, 0x0000, 0xa08a, 0x000d, 0x0050, - 0x2c36, 0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a, - 0x78aa, 0x3518, 0x3340, 0x3428, 0x8000, 0x80ac, 0xaf80, 0x002b, - 0x20a0, 0x789b, 0x0000, 0xad80, 0x000b, 0x2098, 0x53a6, 0x23a8, - 0x2898, 0x25a0, 0xa286, 0x0020, 0x00c0, 0x2c70, 0x70d4, 0xc0b5, - 0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x6814, 0xc0fc, 0x8007, - 0x7882, 0xa286, 0x0002, 0x0040, 0x2ca6, 0x70a4, 0x8000, 0x70a6, - 0x74b4, 0xa498, 0x0005, 0x70ac, 0xa306, 0x00c0, 0x2c68, 0x73a8, - 0x73b6, 0xa286, 0x0010, 0x0040, 0x2942, 0x0d7f, 0x0c7f, 0x007c, - 0x7000, 0xa005, 0x00c0, 0x2c4e, 0xa286, 0x0002, 0x00c0, 0x2cc0, - 0x1078, 0x411c, 0x00c0, 0x2c4e, 0x6814, 0xc0fc, 0x8007, 0x7882, - 0x2091, 0x8000, 0x781b, 0x005b, 0x68b4, 0x785a, 0x6894, 0x78d6, - 0x78de, 0x6898, 0x78d2, 0x78da, 0x2091, 0x8001, 0x7808, 0xc08d, - 0x780a, 0x127e, 0x0d7e, 0x0c7e, 0x70d4, 0xa084, 0x2700, 0x2090, - 0x0c7f, 0x0d7f, 0x127f, 0x2900, 0x705a, 0x68bc, 0x7042, 0x7003, - 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x7830, 0xd0bc, - 0x0040, 0x2cb2, 0x2091, 0x303d, 0x70d4, 0xa084, 0x303d, 0x2091, - 0x8000, 0x2090, 0x70a4, 0xa005, 0x00c0, 0x2cb7, 0x007c, 0x8421, - 0x0040, 0x2cb6, 0x7250, 0x70c0, 0xa200, 0xa015, 0x0078, 0x2aa1, - 0xa286, 0x0010, 0x00c0, 0x2cf1, 0x1078, 0x411c, 0x00c0, 0x2c4e, - 0x6814, 0xc0fc, 0x8007, 0x7882, 0x781b, 0x005b, 0x68b4, 0x785a, + 0x2330, 0x0078, 0x232e, 0x2c08, 0xd9fc, 0x0040, 0x230b, 0x6800, + 0xa065, 0x0040, 0x230b, 0x6a04, 0x7000, 0xa084, 0x0002, 0x0040, + 0x2301, 0x704c, 0xa206, 0x00c0, 0x2301, 0x6b04, 0x2160, 0x2304, + 0x6002, 0xa005, 0x00c0, 0x22fd, 0x6902, 0x2260, 0x6102, 0x0078, + 0x2317, 0x2d00, 0x2060, 0x1078, 0x2acc, 0x6e08, 0x2160, 0x6202, + 0x6906, 0x0078, 0x2317, 0x6800, 0x6902, 0xa065, 0x0040, 0x2313, + 0x6102, 0x0078, 0x2314, 0x6906, 0x2160, 0x6003, 0x0000, 0x2160, + 0xd9fc, 0x0040, 0x231e, 0xa6b4, 0xfffc, 0x6e0a, 0x6810, 0x7d08, + 0x8528, 0x7d0a, 0x8000, 0x6812, 0x2091, 0x8001, 0xd6b4, 0x0040, + 0x232e, 0xa6b6, 0x0040, 0x6e0a, 0x1078, 0x1e6c, 0x0e7f, 0x007c, + 0x6008, 0xa705, 0x600a, 0x2091, 0x8000, 0x1078, 0x201d, 0x2091, + 0x8001, 0x78b8, 0xa065, 0x0040, 0x2343, 0x609c, 0x78ba, 0x609f, + 0x0000, 0x0078, 0x2330, 0x78b6, 0x78ba, 0x007c, 0x7970, 0x7874, + 0x2818, 0xd384, 0x0040, 0x2350, 0x8000, 0xa112, 0x0048, 0x2355, + 0x8000, 0xa112, 0x00c8, 0x2365, 0xc384, 0x7a7c, 0x721a, 0x7a78, + 0x721e, 0xdac4, 0x0040, 0x2360, 0x7a84, 0x7222, 0x7a80, 0x7226, + 0xa006, 0xd384, 0x0040, 0x2365, 0x8000, 0x7876, 0x70d2, 0x781c, + 0xa005, 0x0040, 0x2373, 0x8001, 0x781e, 0x00c0, 0x2373, 0x0068, + 0x2373, 0x2091, 0x4080, 0x007c, 0x2039, 0x238c, 0x0078, 0x237a, + 0x2039, 0x2392, 0x2704, 0xa005, 0x0040, 0x238b, 0xac00, 0x2068, + 0x6908, 0x6810, 0x6912, 0x680a, 0x690c, 0x6814, 0x6916, 0x680e, + 0x8738, 0x0078, 0x237a, 0x007c, 0x0003, 0x0009, 0x000f, 0x0015, + 0x001b, 0x0000, 0x0015, 0x001b, 0x0000, 0x2041, 0x0000, 0x780c, + 0x0079, 0x239a, 0x256c, 0x253f, 0x239e, 0x2417, 0x2039, 0x9674, + 0x2734, 0x7d10, 0x0078, 0x23be, 0x6084, 0xa086, 0x0103, 0x00c0, + 0x2400, 0x6114, 0x6018, 0xa105, 0x0040, 0x23b3, 0x86ff, 0x00c0, + 0x23cf, 0x0078, 0x2400, 0x8603, 0xa080, 0x9655, 0x620c, 0x2202, + 0x8000, 0x6210, 0x2202, 0x1078, 0x203f, 0x8630, 0xa68e, 0x000f, + 0x0040, 0x248b, 0x786c, 0xa065, 0x00c0, 0x23a4, 0x7808, 0xa602, + 0x00c8, 0x23cf, 0xd5ac, 0x00c0, 0x23cf, 0x263a, 0x007c, 0xa682, + 0x0003, 0x00c8, 0x248b, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, + 0xd084, 0x00c0, 0x23fb, 0x2011, 0x9655, 0x2204, 0x70c6, 0x8210, + 0x2204, 0x70ca, 0xd684, 0x00c0, 0x23eb, 0x8210, 0x2204, 0x70da, + 0x8210, 0x2204, 0x70de, 0xa685, 0x8020, 0x70c2, 0x681b, 0x0001, + 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, 0x8001, + 0x203b, 0x0000, 0x007c, 0x7810, 0xc0ad, 0x7812, 0x0078, 0x248b, + 0x263a, 0x1078, 0x2576, 0x00c0, 0x2599, 0x786c, 0xa065, 0x00c0, + 0x23a4, 0x2091, 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0040, + 0x2412, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0078, 0x2599, 0x2039, + 0x9674, 0x2734, 0x7d10, 0x0078, 0x2433, 0x6084, 0xa086, 0x0103, + 0x00c0, 0x2474, 0x6114, 0x6018, 0xa105, 0x0040, 0x242c, 0x86ff, + 0x00c0, 0x2444, 0x0078, 0x2474, 0xa680, 0x9655, 0x620c, 0x2202, + 0x1078, 0x203f, 0x8630, 0xa68e, 0x001e, 0x0040, 0x248b, 0x786c, + 0xa065, 0x00c0, 0x241d, 0x7808, 0xa602, 0x00c8, 0x2444, 0xd5ac, + 0x00c0, 0x2444, 0x263a, 0x007c, 0xa682, 0x0006, 0x00c8, 0x248b, + 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, 0x246f, + 0x2011, 0x9655, 0x2009, 0x964e, 0x26a8, 0x211c, 0x2204, 0x201a, + 0x8108, 0x8210, 0x00f0, 0x2455, 0xa685, 0x8030, 0x70c2, 0x681b, + 0x0001, 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, + 0x8001, 0xa006, 0x2009, 0x9675, 0x200a, 0x203a, 0x007c, 0x7810, + 0xc0ad, 0x7812, 0x0078, 0x248b, 0x263a, 0x1078, 0x2576, 0x00c0, + 0x2599, 0x786c, 0xa065, 0x00c0, 0x241d, 0x2091, 0x8000, 0x7810, + 0xa084, 0xffcf, 0x86ff, 0x0040, 0x2486, 0xc0ad, 0x7812, 0x2091, + 0x8001, 0x0078, 0x2599, 0x2091, 0x8000, 0x7007, 0x0004, 0x7994, + 0x70d4, 0xa102, 0x0048, 0x249c, 0x0040, 0x24a6, 0x7b90, 0xa302, + 0x00c0, 0x24a6, 0x0078, 0x249f, 0x8002, 0x00c0, 0x24a6, 0x263a, + 0x7810, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x007c, 0xa184, 0xff00, + 0x0040, 0x24b3, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, + 0xa100, 0x0078, 0x24b6, 0x8107, 0x8004, 0x8004, 0x7a9c, 0xa210, + 0x721a, 0x7a98, 0xa006, 0xa211, 0x721e, 0xd4c4, 0x0040, 0x24c6, + 0x7aa4, 0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226, 0x20a1, 0x0030, + 0x7003, 0x0000, 0x2009, 0x9654, 0x260a, 0x8109, 0x2198, 0x2104, + 0xd084, 0x0040, 0x24d4, 0x8633, 0xa6b0, 0x0002, 0x26a8, 0x53a6, + 0x8603, 0x7012, 0x7007, 0x0001, 0x7990, 0x7894, 0x8000, 0xa10a, + 0x00c8, 0x24e3, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00, 0x0040, + 0x24f2, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, + 0x0078, 0x24f5, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, + 0xa006, 0xa211, 0xd4c4, 0x0040, 0x2501, 0x7b84, 0xa319, 0x7c80, + 0xa421, 0x7008, 0xd0fc, 0x0040, 0x2501, 0xa084, 0x01e0, 0x0040, + 0x2526, 0x7d10, 0x2031, 0x9654, 0x2634, 0x78a8, 0x8000, 0x78aa, + 0xd08c, 0x00c0, 0x251b, 0x7007, 0x0006, 0x7004, 0xd094, 0x00c0, + 0x2515, 0x0078, 0x248d, 0x2069, 0x4e47, 0x206b, 0x0003, 0x78ac, + 0xa085, 0x0300, 0x78ae, 0xa006, 0x0078, 0x252f, 0x2030, 0x75d6, + 0x2091, 0x4080, 0x7d96, 0x7d10, 0xa5ac, 0xffcf, 0x7d12, 0x2091, + 0x8001, 0x78aa, 0x7007, 0x0006, 0x263a, 0x7003, 0x0001, 0x711a, + 0x721e, 0xd5c4, 0x0040, 0x253e, 0x7322, 0x7426, 0x007c, 0x6084, + 0xa086, 0x0103, 0x00c0, 0x2562, 0x6114, 0x6018, 0xa105, 0x00c0, + 0x2562, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, 0x2562, 0x600c, + 0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001, 0x2091, + 0x4080, 0x1078, 0x203f, 0x0068, 0x2561, 0x786c, 0xa065, 0x00c0, + 0x253f, 0x007c, 0x1078, 0x2576, 0x00c0, 0x2599, 0x786c, 0xa065, + 0x00c0, 0x253f, 0x0078, 0x2599, 0x1078, 0x2576, 0x00c0, 0x2599, + 0x786c, 0xa065, 0x00c0, 0x256c, 0x0078, 0x2599, 0x6084, 0xa086, + 0x0103, 0x00c0, 0x258a, 0x6018, 0xc0fc, 0x601a, 0xa086, 0x0004, + 0x00c0, 0x258a, 0x7804, 0xd0a4, 0x0040, 0x258a, 0x1078, 0x203f, + 0xa006, 0x007c, 0x1078, 0x259f, 0x00c0, 0x2591, 0xa085, 0x0001, + 0x007c, 0x1078, 0x25ae, 0x00c0, 0x2597, 0x2041, 0x0001, 0x7d10, + 0x007c, 0x88ff, 0x0040, 0x259e, 0x2091, 0x4080, 0x007c, 0x7b90, + 0x7994, 0x70d4, 0xa102, 0x00c0, 0x25a8, 0xa385, 0x0000, 0x007c, + 0x0048, 0x25ac, 0xa302, 0x007c, 0x8002, 0x007c, 0x7810, 0xd0ec, + 0x0040, 0x25c6, 0x0e7e, 0x2091, 0x8000, 0x2071, 0x0020, 0x7004, + 0xa005, 0x00c0, 0x25c3, 0x7008, 0x0e7f, 0xa086, 0x0008, 0x0040, + 0x25c6, 0x0078, 0x2617, 0x0e7f, 0x0078, 0x2617, 0xa184, 0xff00, + 0x0040, 0x25d3, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, + 0xa100, 0x0078, 0x25d6, 0x8107, 0x8004, 0x8004, 0x7a9c, 0x7b98, + 0x7ca4, 0x7da0, 0xa210, 0xa006, 0xa319, 0xa421, 0xa529, 0x2009, + 0x0018, 0x6028, 0xa005, 0x0040, 0x25e7, 0x2009, 0x0040, 0x1078, + 0x1d74, 0x0040, 0x2609, 0x78a8, 0x8000, 0x78aa, 0xd08c, 0x00c0, + 0x2617, 0x6014, 0xd0fc, 0x00c0, 0x25f9, 0x2069, 0x4e40, 0x0078, + 0x25fb, 0x2069, 0x4e80, 0x2091, 0x8000, 0x681f, 0x0003, 0x78ab, + 0x0000, 0x78ac, 0xa085, 0x0300, 0x78ae, 0x2091, 0x8001, 0x0078, + 0x2617, 0x78ab, 0x0000, 0x1078, 0x203f, 0x7990, 0x7894, 0x8000, + 0xa10a, 0x00c8, 0x2614, 0xa006, 0x7896, 0x70d6, 0xa006, 0x2071, + 0x0010, 0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x2623, 0x2009, + 0x4e59, 0x0078, 0x2625, 0x2009, 0x4e99, 0x2091, 0x8000, 0x200a, + 0x0f7e, 0xd7fc, 0x00c0, 0x263c, 0x2009, 0x4e40, 0x2001, 0x4e04, + 0x2004, 0xd0ec, 0x0040, 0x2638, 0x2079, 0x0100, 0x0078, 0x2640, + 0x2079, 0x0200, 0x0078, 0x2640, 0x2009, 0x4e80, 0x2079, 0x0100, + 0x2104, 0xa086, 0x0000, 0x00c0, 0x2659, 0xd7fc, 0x00c0, 0x264c, + 0x2009, 0x4e45, 0x0078, 0x264e, 0x2009, 0x4e85, 0x2104, 0xa005, + 0x00c0, 0x2659, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x2659, 0x781b, + 0x0045, 0x0f7f, 0x007c, 0x2009, 0x0002, 0x2069, 0x4e00, 0x6810, + 0xd0ec, 0x00c0, 0x26c8, 0x2071, 0x4e80, 0x2079, 0x0100, 0x2021, + 0x50bf, 0x784b, 0x000f, 0x2019, 0x4457, 0xd184, 0x0040, 0x267c, + 0x6810, 0xd0ec, 0x0040, 0x2678, 0x20a1, 0x012b, 0x0078, 0x267e, + 0x20a1, 0x022b, 0x0078, 0x267e, 0x20a1, 0x012b, 0x2304, 0xa005, + 0x0040, 0x268b, 0x789a, 0x8318, 0x23ac, 0x8318, 0x2398, 0x53a6, + 0x3318, 0x0078, 0x267e, 0x789b, 0x0020, 0x20a9, 0x0010, 0x6814, + 0xd0e4, 0x0040, 0x269b, 0x78af, 0x0000, 0x78af, 0x9020, 0x00f0, + 0x2693, 0x0078, 0x26a1, 0x78af, 0x0000, 0x78af, 0x8020, 0x00f0, + 0x269b, 0x7003, 0x0000, 0x017e, 0xd18c, 0x2009, 0x0000, 0x0040, + 0x26aa, 0xc1bd, 0x1078, 0x289b, 0x017f, 0x7020, 0xa084, 0x000f, + 0x007e, 0x6814, 0xd0e4, 0x007f, 0x00c0, 0x26ba, 0xa085, 0x6340, + 0x0078, 0x26bc, 0xa085, 0x62c0, 0x7806, 0x780f, 0x9200, 0x7843, + 0x00d8, 0x7853, 0x0080, 0x780b, 0x0008, 0x7456, 0x7053, 0x0000, + 0x8109, 0x0040, 0x26db, 0x2071, 0x4e40, 0x6810, 0xd0ec, 0x0040, + 0x26d5, 0x2079, 0x0100, 0x0078, 0x26d7, 0x2079, 0x0200, 0x2021, + 0x4ebf, 0x0078, 0x2669, 0x007c, 0x017e, 0xd1bc, 0x00c0, 0x26f0, + 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x26ec, + 0x2011, 0x0101, 0x0078, 0x26f2, 0x2011, 0x0201, 0x0078, 0x26f2, + 0x2011, 0x0101, 0xa18c, 0x000f, 0x2204, 0xa084, 0xfff0, 0xa105, + 0x2012, 0x017f, 0x1078, 0x289b, 0x007c, 0xd3fc, 0x00c0, 0x2710, + 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x270c, + 0x2011, 0x0101, 0x0078, 0x2712, 0x2011, 0x0201, 0x0078, 0x2712, + 0x2011, 0x0101, 0x20a9, 0x0009, 0x810b, 0x00f0, 0x2714, 0xa18c, + 0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x007c, 0x2019, + 0x0002, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x0040, 0x272c, 0x8319, + 0x2009, 0x0101, 0x0078, 0x272e, 0x2009, 0x0101, 0x20a9, 0x0005, + 0x8213, 0x00f0, 0x2730, 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f, + 0xa205, 0x200a, 0x8319, 0x0040, 0x2741, 0x2009, 0x0201, 0x0078, + 0x272e, 0x007c, 0xd3fc, 0x00c0, 0x2755, 0x007e, 0x2001, 0x4e04, + 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2751, 0x2011, 0x0101, 0x0078, + 0x2757, 0x2011, 0x0201, 0x0078, 0x2757, 0x2011, 0x0101, 0x20a9, + 0x000c, 0x810b, 0x00f0, 0x2759, 0xa18c, 0xf000, 0x2204, 0xa084, + 0x0fff, 0xa105, 0x2012, 0x007c, 0xd3fc, 0x00c0, 0x2777, 0x007e, + 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2773, 0x2011, + 0x0102, 0x0078, 0x2779, 0x2011, 0x0202, 0x0078, 0x2779, 0x2011, + 0x0102, 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012, 0x007c, 0x0c7e, + 0xd1bc, 0x00c0, 0x2793, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, + 0x007f, 0x0040, 0x278f, 0x2061, 0x0100, 0x0078, 0x2795, 0x2061, + 0x0200, 0x0078, 0x2795, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003, + 0xa080, 0x0020, 0x609a, 0x62ac, 0x63ac, 0x0c7f, 0x007c, 0x0c7e, + 0xd1bc, 0x00c0, 0x27b3, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, + 0x007f, 0x0040, 0x27af, 0x2061, 0x0100, 0x0078, 0x27b5, 0x2061, + 0x0200, 0x0078, 0x27b5, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003, + 0xa080, 0x0022, 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x0c7f, + 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x27d5, 0x007e, 0x2001, 0x4e04, + 0x2004, 0xd0ec, 0x007f, 0x0040, 0x27d1, 0x2061, 0x0100, 0x0078, + 0x27d7, 0x2061, 0x0200, 0x0078, 0x27d7, 0x2061, 0x0100, 0xc1bc, + 0x8103, 0x8003, 0xa080, 0x0022, 0x609a, 0x60a4, 0xa085, 0x0020, + 0x60ae, 0x0c7f, 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x27f7, 0x007e, + 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x27f3, 0x2061, + 0x0100, 0x0078, 0x27f9, 0x2061, 0x0200, 0x0078, 0x27f9, 0x2061, + 0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x60a4, + 0xa28c, 0x0020, 0x0040, 0x2807, 0xc2ac, 0xa39d, 0x4000, 0xc3fc, + 0xd3b4, 0x00c0, 0x280c, 0xc3fd, 0x62ae, 0x2010, 0x60a4, 0x63ae, + 0x2018, 0x0c7f, 0x007c, 0x2091, 0x8000, 0x0c7e, 0x0e7e, 0x6818, + 0xa005, 0x0040, 0x2879, 0xd1fc, 0x0040, 0x2822, 0x2061, 0x95d0, + 0x0078, 0x2824, 0x2061, 0x94c0, 0x1078, 0x2881, 0x0040, 0x285b, + 0x20a9, 0x0101, 0xd1fc, 0x0040, 0x2831, 0x2061, 0x94d0, 0x0078, + 0x2833, 0x2061, 0x93c0, 0x0c7e, 0x1078, 0x2881, 0x0040, 0x283e, + 0x0c7f, 0x8c60, 0x00f0, 0x2833, 0x0078, 0x2879, 0x007f, 0xd1fc, + 0x0040, 0x2848, 0xa082, 0x94d0, 0x2071, 0x4e80, 0x0078, 0x284c, + 0xa082, 0x93c0, 0x2071, 0x4e40, 0x707a, 0x7176, 0x2138, 0x2001, + 0x0004, 0x7066, 0x7083, 0x000f, 0x71d4, 0xc1dc, 0x71d6, 0x1078, + 0x261c, 0x0078, 0x2875, 0xd1fc, 0x00c0, 0x2862, 0x2071, 0x4e40, + 0x0078, 0x2864, 0x2071, 0x4e80, 0x6020, 0xc0dd, 0x6022, 0x7176, + 0x2138, 0x2c00, 0x707e, 0x2001, 0x0006, 0x7066, 0x7083, 0x000f, + 0x71d4, 0xc1dc, 0x71d6, 0x1078, 0x261c, 0x2001, 0x0000, 0x0078, + 0x287b, 0x2001, 0x0001, 0x2091, 0x8001, 0xa005, 0x0e7f, 0x0c7f, + 0x007c, 0x2c04, 0xa005, 0x0040, 0x2898, 0x2060, 0x6010, 0xa306, + 0x00c0, 0x2895, 0x600c, 0xa206, 0x00c0, 0x2895, 0x6014, 0xa106, + 0x00c0, 0x2895, 0xa006, 0x0078, 0x289a, 0x6000, 0x0078, 0x2882, + 0xa085, 0x0001, 0x007c, 0x0f7e, 0x0e7e, 0x017e, 0xd1bc, 0x00c0, + 0x28b3, 0x2079, 0x4e40, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, + 0x007f, 0x0040, 0x28af, 0x2071, 0x0100, 0x0078, 0x28b7, 0x2071, + 0x0200, 0x0078, 0x28b7, 0x2079, 0x4e80, 0x2071, 0x0100, 0x7920, + 0xa18c, 0x000f, 0x70ec, 0xd0c4, 0x00c0, 0x28c1, 0x017f, 0x0078, + 0x28dc, 0x810b, 0x810b, 0x810b, 0x810b, 0x007f, 0xd0bc, 0x00c0, + 0x28d9, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, + 0x28d5, 0xa18d, 0x0f00, 0x0078, 0x28db, 0xa18d, 0x0f00, 0x0078, + 0x28db, 0xa18d, 0x0800, 0x2104, 0x0e7f, 0x0f7f, 0x007c, 0x0e7e, + 0x2001, 0x4e01, 0x2004, 0xd0ac, 0x00c0, 0x295c, 0x68e4, 0xd0ac, + 0x0040, 0x295c, 0xa084, 0x0006, 0x00c0, 0x295c, 0x6014, 0xd0fc, + 0x00c0, 0x28f6, 0x2071, 0x52c0, 0x0078, 0x28f8, 0x2071, 0x5340, + 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xae70, 0x7004, + 0xa084, 0x000a, 0x00c0, 0x295c, 0x7108, 0xa194, 0xff00, 0x0040, + 0x295c, 0xa18c, 0x00ff, 0x2001, 0x000a, 0xa106, 0x0040, 0x292b, + 0x2001, 0x000c, 0xa106, 0x0040, 0x292f, 0x2001, 0x0012, 0xa106, + 0x0040, 0x2933, 0x2001, 0x0014, 0xa106, 0x0040, 0x2937, 0x2001, + 0x0019, 0xa106, 0x0040, 0x293b, 0x2001, 0x0032, 0xa106, 0x0040, + 0x293f, 0x0078, 0x2943, 0x2009, 0x000c, 0x0078, 0x2945, 0x2009, + 0x0012, 0x0078, 0x2945, 0x2009, 0x0014, 0x0078, 0x2945, 0x2009, + 0x0019, 0x0078, 0x2945, 0x2009, 0x0020, 0x0078, 0x2945, 0x2009, + 0x003f, 0x0078, 0x2945, 0x2011, 0x0000, 0x2100, 0xa205, 0x700a, + 0x2071, 0x4e00, 0x7004, 0xd0bc, 0x0040, 0x295c, 0x6014, 0xd0fc, + 0x00c0, 0x2957, 0x70ea, 0x2071, 0x4e40, 0x0078, 0x295a, 0x70ee, + 0x2071, 0x4e80, 0x701f, 0x000d, 0x0e7f, 0x007c, 0x2001, 0x4e05, + 0x2004, 0xd0e4, 0x00c0, 0x296a, 0x7804, 0xa084, 0xff1f, 0xa085, + 0x6340, 0x7806, 0x007c, 0x0068, 0x296b, 0x2091, 0x8000, 0x2071, + 0x0000, 0x007e, 0x7018, 0xd084, 0x00c0, 0x2972, 0x007f, 0x2071, + 0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x080f, + 0x70df, 0x0000, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, + 0x0078, 0x2988, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, 0x708e, + 0x7592, 0x7496, 0x769a, 0x779e, 0xa594, 0x003f, 0xd4f4, 0x0040, + 0x299f, 0xa784, 0x007d, 0x00c0, 0x43cd, 0x1078, 0x296b, 0xa49c, + 0x000f, 0xa382, 0x0004, 0x0050, 0x29aa, 0xa3a6, 0x0007, 0x00c0, + 0x296b, 0x2418, 0x8507, 0xa084, 0x000f, 0x0079, 0x29af, 0x3028, + 0x3119, 0x3144, 0x33b6, 0x379f, 0x3819, 0x38ce, 0x395f, 0x3a4d, + 0x3b3c, 0x29c2, 0x29bf, 0x2df9, 0x2f1c, 0x3770, 0x29bf, 0x1078, + 0x296b, 0x007c, 0xa006, 0x0078, 0x29cc, 0x7808, 0xc08d, 0x780a, + 0xa006, 0x7002, 0x704e, 0x7046, 0x70d2, 0x7060, 0xa005, 0x00c0, + 0x2b32, 0x7064, 0xa084, 0x0007, 0x0079, 0x29d6, 0x29de, 0x2a51, + 0x2a5a, 0x2a65, 0x2a70, 0x2b18, 0x2a7b, 0x2a51, 0x7830, 0xd0bc, + 0x00c0, 0x29c1, 0x71d4, 0xd1bc, 0x00c0, 0x29c1, 0xd1b4, 0x00c0, + 0x2a2e, 0x70a4, 0xa086, 0x0001, 0x0040, 0x29c1, 0x70b4, 0xa06d, + 0x6800, 0xa065, 0xa055, 0x789b, 0x0010, 0x6b0c, 0x7baa, 0x6808, + 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0040, + 0x2a04, 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001, + 0x0010, 0x0078, 0x2c8c, 0x7060, 0xa005, 0x00c0, 0x29c1, 0x0c7e, + 0x0d7e, 0x70b4, 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0010, + 0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, + 0xa886, 0x0001, 0x0040, 0x2a27, 0x69bc, 0x7daa, 0x79aa, 0x68c0, + 0xa04d, 0x6e1c, 0x2001, 0x0020, 0x0078, 0x2c8c, 0x1078, 0x4360, + 0x00c0, 0x29c1, 0x781b, 0x005b, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, - 0x780a, 0x70a4, 0x8000, 0x70a6, 0x74b4, 0xa490, 0x0005, 0x70ac, - 0xa206, 0x00c0, 0x2ce4, 0x72a8, 0x72b6, 0x2900, 0x705a, 0x68bc, - 0x7042, 0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, - 0x007c, 0x6bb4, 0xa39d, 0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, - 0x7882, 0x6b94, 0x7bd6, 0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, - 0x005b, 0x2900, 0x705a, 0x7202, 0x7808, 0xc08d, 0x780a, 0x2300, - 0xa605, 0x0040, 0x2d1c, 0x70d4, 0xa084, 0x2700, 0xa086, 0x2300, - 0x00c0, 0x2d16, 0x2009, 0x0000, 0x0078, 0x2d18, 0x2009, 0x0001, - 0xa284, 0x000f, 0x1079, 0x2d20, 0xad80, 0x0009, 0x7046, 0x007c, - 0x2d28, 0x45f7, 0x45f7, 0x45e4, 0x45f7, 0x2d28, 0x2d28, 0x2d28, - 0x1078, 0x28ec, 0x7808, 0xa084, 0xfffd, 0x780a, 0x0f7e, 0x2079, - 0x4a00, 0x78ac, 0x0f7f, 0xd084, 0x0040, 0x2d4e, 0x7064, 0xa086, - 0x0001, 0x00c0, 0x2d3e, 0x7066, 0x0078, 0x2e27, 0x7064, 0xa086, - 0x0005, 0x00c0, 0x2d4c, 0x707c, 0x2068, 0x681b, 0x0004, 0x6817, - 0x0000, 0x6820, 0xc09d, 0x6822, 0x7067, 0x0000, 0x70a7, 0x0000, - 0x70a8, 0x70b2, 0x70b6, 0x70d4, 0xd0b4, 0x0040, 0x2d64, 0xc0b4, + 0x780a, 0x68bc, 0x7042, 0xc1b4, 0x71d6, 0x70b8, 0xa065, 0x68c0, + 0x705a, 0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, + 0x007c, 0x1078, 0x4360, 0x00c0, 0x2a59, 0x781b, 0x0047, 0x7003, + 0x0004, 0x007c, 0x1078, 0x4360, 0x00c0, 0x2a64, 0x2011, 0x000c, + 0x1078, 0x2a8b, 0x7003, 0x0004, 0x007c, 0x1078, 0x4360, 0x00c0, + 0x2a6f, 0x2011, 0x0006, 0x1078, 0x2a8b, 0x7003, 0x0004, 0x007c, + 0x1078, 0x4360, 0x00c0, 0x2a7a, 0x2011, 0x000d, 0x1078, 0x2a8b, + 0x7003, 0x0004, 0x007c, 0x1078, 0x4360, 0x00c0, 0x2a8a, 0x2011, + 0x0006, 0x1078, 0x2a8b, 0x707c, 0x707f, 0x0000, 0x2068, 0x704e, + 0x7003, 0x0001, 0x007c, 0x7174, 0xc1fc, 0x8107, 0x7882, 0x789b, + 0x0010, 0xa286, 0x000c, 0x00c0, 0x2a9a, 0x7aaa, 0x2001, 0x0001, + 0x0078, 0x2aaf, 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0xa286, + 0x000d, 0x0040, 0x2aa8, 0x7aaa, 0x2001, 0x0002, 0x0078, 0x2aaf, + 0x78ab, 0x0020, 0x7178, 0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b, + 0x0060, 0x78aa, 0x785b, 0x0004, 0x781b, 0x0116, 0x1078, 0x4383, + 0x7083, 0x000f, 0x70d4, 0xd0b4, 0x0040, 0x2acb, 0xc0b4, 0x70d6, + 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, + 0x8001, 0x601a, 0x0c7f, 0x007c, 0x7014, 0xa005, 0x00c0, 0x2ada, + 0x70d4, 0xd0b4, 0x0040, 0x2adb, 0x70b8, 0xac06, 0x00c0, 0x2adb, + 0x1078, 0x2aba, 0x007c, 0x017e, 0x71a4, 0xa186, 0x0001, 0x0040, + 0x2b0d, 0x0d7e, 0x027e, 0x2100, 0x2011, 0x0001, 0xa212, 0x70b4, + 0x2068, 0x6800, 0xac06, 0x0040, 0x2af4, 0x8211, 0x0040, 0x2b0b, + 0x1078, 0x2b0f, 0x0078, 0x2ae9, 0x0c7e, 0x2100, 0x2011, 0x0001, + 0xa212, 0x70b4, 0x2068, 0x6800, 0x2060, 0x6008, 0xa084, 0xfbef, + 0x600a, 0x8211, 0x0040, 0x2b08, 0x1078, 0x2b0f, 0x0078, 0x2afb, + 0x70a7, 0x0001, 0x0c7f, 0x027f, 0x0d7f, 0x017f, 0x007c, 0xade8, + 0x0005, 0x70ac, 0xad06, 0x00c0, 0x2b17, 0x70a8, 0x2068, 0x007c, + 0x1078, 0x4360, 0x00c0, 0x29c1, 0x707c, 0x2068, 0x7774, 0x1078, + 0x41fe, 0x2c50, 0x1078, 0x4442, 0x789b, 0x0010, 0x6814, 0xa084, + 0x001f, 0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001, 0x2001, 0x0004, + 0x0078, 0x2c92, 0x1078, 0x4360, 0x00c0, 0x29c1, 0x789b, 0x0010, + 0x7060, 0x2068, 0x6f14, 0x70d4, 0xd0b4, 0x0040, 0x2b4c, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, - 0x6018, 0x8001, 0x601a, 0x0c7f, 0x157e, 0x2011, 0x0004, 0x7164, - 0xa186, 0x0001, 0x0040, 0x2d7d, 0xa186, 0x0007, 0x00c0, 0x2d74, - 0x701f, 0x0005, 0x0078, 0x2d7d, 0x701f, 0x0001, 0x7067, 0x0000, - 0x70d4, 0xc0dd, 0x70d6, 0x0078, 0x2d7f, 0x7067, 0x0000, 0x2001, - 0x4a0a, 0x2004, 0xa084, 0x00ff, 0xa086, 0x0018, 0x0040, 0x2d8f, - 0x7018, 0x7016, 0xa005, 0x00c0, 0x2d8f, 0x70a7, 0x0001, 0x1078, - 0x4326, 0x20a9, 0x0010, 0x2039, 0x0000, 0x1078, 0x3edb, 0xa7b8, - 0x0100, 0x00f0, 0x2d95, 0x7000, 0x0079, 0x2d9e, 0x2dcd, 0x2db3, - 0x2db3, 0x2da8, 0x2dcd, 0x2dcd, 0x2dcd, 0x2da6, 0x1078, 0x28ec, - 0x7060, 0xa005, 0x0040, 0x2dcd, 0xad06, 0x00c0, 0x2db3, 0x6800, - 0x7062, 0x0078, 0x2dc5, 0x6820, 0xd084, 0x00c0, 0x2dc1, 0x6f14, - 0x1078, 0x3fe1, 0x6008, 0xc0d4, 0x600a, 0x1078, 0x3bb5, 0x0078, - 0x2dc5, 0x705c, 0x2060, 0x6800, 0x6002, 0x6a1a, 0x6817, 0x0000, - 0x6820, 0xc09d, 0x6822, 0x1078, 0x202a, 0xb284, 0x0400, 0x0040, - 0x2dd5, 0x2021, 0x91d0, 0x0078, 0x2dd7, 0x2021, 0x90c0, 0x1078, - 0x2e2c, 0xb284, 0x0400, 0x0040, 0x2de1, 0x2021, 0x4a98, 0x0078, - 0x2de3, 0x2021, 0x4a58, 0x1078, 0x2e2c, 0x20a9, 0x0101, 0xb284, - 0x0400, 0x0040, 0x2def, 0x2021, 0x90d0, 0x0078, 0x2df1, 0x2021, - 0x8fc0, 0x1078, 0x2e2c, 0x8420, 0x00f0, 0x2df1, 0xb284, 0x0300, - 0x0040, 0x2dfe, 0x2061, 0x4fc0, 0x0078, 0x2e00, 0x2061, 0x6fc0, - 0x2021, 0x0002, 0x20a9, 0x0100, 0x6110, 0x81ff, 0x0040, 0x2e1d, - 0x6018, 0x017e, 0x007e, 0x2011, 0x4a02, 0x220c, 0xa102, 0x2012, - 0x007f, 0x017f, 0xa102, 0x0050, 0x2e1d, 0x6012, 0x00c0, 0x2e1d, - 0x2011, 0x4a04, 0x2204, 0xc0a5, 0x2012, 0x601b, 0x0000, 0xace0, - 0x0010, 0x00f0, 0x2e04, 0x8421, 0x00c0, 0x2e02, 0x157f, 0x7003, - 0x0000, 0x704f, 0x0000, 0x007c, 0x047e, 0x2404, 0xa005, 0x0040, - 0x2e3f, 0x2068, 0x6800, 0x007e, 0x6a1a, 0x6817, 0x0000, 0x6820, - 0xc09d, 0x6822, 0x1078, 0x202a, 0x007f, 0x0078, 0x2e2e, 0x047f, - 0x2023, 0x0000, 0x007c, 0xa282, 0x0003, 0x0050, 0x2e49, 0x1078, - 0x28ec, 0x2300, 0x0079, 0x2e4c, 0x2e4f, 0x2eda, 0x2ef7, 0xa282, - 0x0002, 0x0040, 0x2e55, 0x1078, 0x28ec, 0x7064, 0x7067, 0x0000, - 0x7083, 0x0000, 0x0079, 0x2e5c, 0x2e64, 0x2e64, 0x2e66, 0x2ea6, - 0x3bf1, 0x2e64, 0x2ea6, 0x2e64, 0x1078, 0x28ec, 0x7774, 0x1078, - 0x3edb, 0x7774, 0xa7bc, 0x8f00, 0x1078, 0x3fe1, 0x6018, 0xa005, - 0x0040, 0x2e9d, 0xd7fc, 0x00c0, 0x2e79, 0x2021, 0x90c0, 0x0078, - 0x2e7b, 0x2021, 0x91d0, 0x2009, 0x0005, 0x2011, 0x0010, 0x1078, - 0x2f12, 0x0040, 0x2e9d, 0x157e, 0x20a9, 0x0101, 0xd7fc, 0x00c0, - 0x2e8d, 0x2021, 0x8fc0, 0x0078, 0x2e8f, 0x2021, 0x90d0, 0x047e, - 0x2009, 0x0005, 0x2011, 0x0010, 0x1078, 0x2f12, 0x047f, 0x0040, - 0x2e9c, 0x8420, 0x00f0, 0x2e8f, 0x157f, 0x8738, 0xa784, 0x001f, - 0x00c0, 0x2e6c, 0x0078, 0x2946, 0x0078, 0x2946, 0x7774, 0x1078, - 0x3fe1, 0x6018, 0xa005, 0x0040, 0x2ed8, 0xd7fc, 0x00c0, 0x2eb4, - 0x2021, 0x90c0, 0x0078, 0x2eb6, 0x2021, 0x91d0, 0x2009, 0x0005, - 0x2011, 0x0020, 0x1078, 0x2f12, 0x0040, 0x2ed8, 0x157e, 0x20a9, - 0x0101, 0xd7fc, 0x00c0, 0x2ec8, 0x2021, 0x8fc0, 0x0078, 0x2eca, - 0x2021, 0x90d0, 0x047e, 0x2009, 0x0005, 0x2011, 0x0020, 0x1078, - 0x2f12, 0x047f, 0x0040, 0x2ed7, 0x8420, 0x00f0, 0x2eca, 0x157f, - 0x0078, 0x2946, 0x2200, 0x0079, 0x2edd, 0x2ee0, 0x2ee2, 0x2ee2, - 0x1078, 0x28ec, 0x2009, 0x0012, 0x7064, 0xa086, 0x0002, 0x0040, - 0x2eeb, 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0040, 0x2ef0, 0x691a, - 0x7067, 0x0000, 0x70d4, 0xc0dd, 0x70d6, 0x0078, 0x40c9, 0x2200, - 0x0079, 0x2efa, 0x2eff, 0x2ee2, 0x2efd, 0x1078, 0x28ec, 0x1078, - 0x4326, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3b7a, 0x1078, 0x3bd2, - 0x6008, 0xa084, 0xfbef, 0x600a, 0x1078, 0x3b6b, 0x0040, 0x3b7a, - 0x0078, 0x2946, 0x2404, 0xa005, 0x0040, 0x2f41, 0x2068, 0x2d04, - 0x007e, 0x6814, 0xa706, 0x0040, 0x2f21, 0x2d20, 0x007f, 0x0078, - 0x2f13, 0x007f, 0x2022, 0x691a, 0x6817, 0x0000, 0x6820, 0xa205, - 0x6822, 0x1078, 0x202a, 0x2021, 0x4a02, 0x241c, 0x8319, 0x2322, - 0x6010, 0x8001, 0x6012, 0x00c0, 0x2f3a, 0x2021, 0x4a04, 0x2404, - 0xc0a5, 0x2022, 0x6008, 0xa084, 0xf9ef, 0x600a, 0x1078, 0x3bd2, - 0x007c, 0xa085, 0x0001, 0x0078, 0x2f40, 0x2300, 0x0079, 0x2f48, - 0x2f4d, 0x2f4b, 0x2fce, 0x1078, 0x28ec, 0x78e4, 0xa005, 0x00d0, - 0x2f84, 0x3208, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, - 0x0040, 0x2f5e, 0xa18c, 0x0300, 0x0078, 0x2f60, 0xa18c, 0x0400, - 0x0040, 0x2f66, 0x0018, 0x2942, 0x0078, 0x2f68, 0x0028, 0x2942, - 0x2008, 0xa084, 0x0030, 0x00c0, 0x2f70, 0x781b, 0x005b, 0x007c, - 0x78ec, 0xa084, 0x0003, 0x0040, 0x2f6d, 0x2100, 0xa084, 0x0007, - 0x0079, 0x2f7a, 0x2fae, 0x2fb8, 0x2fa3, 0x2f82, 0x4111, 0x4111, - 0x2f82, 0x2fc3, 0x1078, 0x28ec, 0x7000, 0xa086, 0x0004, 0x00c0, - 0x2f9e, 0x7064, 0xa086, 0x0002, 0x00c0, 0x2f94, 0x2011, 0x0002, - 0x2019, 0x0000, 0x0078, 0x2e43, 0x7064, 0xa086, 0x0006, 0x0040, - 0x2f8e, 0x7064, 0xa086, 0x0004, 0x0040, 0x2f8e, 0x79e4, 0x2001, - 0x0003, 0x0078, 0x3304, 0x6818, 0xd0fc, 0x0040, 0x2fa9, 0x681b, - 0x001d, 0x1078, 0x3eae, 0x781b, 0x0061, 0x007c, 0x6818, 0xd0fc, - 0x0040, 0x2fb4, 0x681b, 0x001d, 0x1078, 0x3eae, 0x0078, 0x40ed, - 0x6818, 0xd0fc, 0x0040, 0x2fbe, 0x681b, 0x001d, 0x1078, 0x3eae, - 0x781b, 0x00ef, 0x007c, 0x6818, 0xd0fc, 0x0040, 0x2fc9, 0x681b, - 0x001d, 0x1078, 0x3eae, 0x781b, 0x00bf, 0x007c, 0xa584, 0x000f, - 0x00c0, 0x2feb, 0x7000, 0x0079, 0x2fd5, 0x2946, 0x2fdd, 0x2fdf, - 0x3b7a, 0x3b7a, 0x3b7a, 0x2fdd, 0x2fdd, 0x1078, 0x28ec, 0x1078, - 0x3bd2, 0x6008, 0xa084, 0xfbef, 0x600a, 0x1078, 0x3b6b, 0x0040, - 0x3b7a, 0x0078, 0x2946, 0x78e4, 0xa005, 0x00d0, 0x2f84, 0x3208, - 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2ffc, - 0xa18c, 0x0300, 0x0078, 0x2ffe, 0xa18c, 0x0400, 0x0040, 0x3004, - 0x0018, 0x2f84, 0x0078, 0x3006, 0x0028, 0x2f84, 0x2008, 0xa084, - 0x0030, 0x00c0, 0x300e, 0x781b, 0x005b, 0x007c, 0x78ec, 0xa084, - 0x0003, 0x0040, 0x300b, 0x2100, 0xa184, 0x0007, 0x0079, 0x3018, - 0x3027, 0x302b, 0x3022, 0x3020, 0x4111, 0x4111, 0x3020, 0x410b, - 0x1078, 0x28ec, 0x1078, 0x3eb6, 0x781b, 0x0061, 0x007c, 0x1078, - 0x3eb6, 0x0078, 0x40ed, 0x1078, 0x3eb6, 0x781b, 0x00ef, 0x007c, - 0x1078, 0x3eb6, 0x781b, 0x00bf, 0x007c, 0x2300, 0x0079, 0x3038, - 0x303d, 0x303b, 0x303f, 0x1078, 0x28ec, 0x0078, 0x37bd, 0x681b, - 0x0016, 0x78a3, 0x0000, 0x79e4, 0xa184, 0x0030, 0x0040, 0x37bd, - 0x78ec, 0xa084, 0x0003, 0x0040, 0x37bd, 0xa184, 0x0100, 0x0040, - 0x3043, 0xa184, 0x0007, 0x0079, 0x3055, 0x305d, 0x302b, 0x2fa3, - 0x40c9, 0x4111, 0x4111, 0x40c9, 0x410b, 0x1078, 0x40d5, 0x007c, - 0xa282, 0x0005, 0x0050, 0x3066, 0x1078, 0x28ec, 0x2300, 0x0079, - 0x3069, 0x306c, 0x328b, 0x3296, 0x2200, 0x0079, 0x306f, 0x3089, - 0x3076, 0x3089, 0x3074, 0x326e, 0x1078, 0x28ec, 0x789b, 0x0018, - 0x78a8, 0xa084, 0x00ff, 0xa082, 0x0020, 0x0048, 0x3e9d, 0xa08a, - 0x0004, 0x00c8, 0x3e9d, 0x0079, 0x3085, 0x3e9d, 0x3e9d, 0x3e9d, - 0x3e47, 0x789b, 0x0018, 0x79a8, 0xa184, 0x0080, 0x0040, 0x309a, - 0x0078, 0x3e9d, 0x7000, 0xa005, 0x00c0, 0x3090, 0x2011, 0x0004, - 0x0078, 0x3998, 0xa184, 0x00ff, 0xa08a, 0x0010, 0x00c8, 0x3e9d, - 0x0079, 0x30a2, 0x30b4, 0x30b2, 0x30c9, 0x30cd, 0x318f, 0x3e9d, - 0x3e9d, 0x3191, 0x3e9d, 0x3e9d, 0x326a, 0x326a, 0x3e9d, 0x3e9d, - 0x3e9d, 0x326c, 0x1078, 0x28ec, 0xd6e4, 0x0040, 0x30bf, 0x2001, - 0x0300, 0x8000, 0x8000, 0x783a, 0x781b, 0x00ba, 0x007c, 0x6818, - 0xd0fc, 0x0040, 0x30c7, 0x681b, 0x001d, 0x0078, 0x30b7, 0x0078, - 0x40c9, 0x681b, 0x001d, 0x0078, 0x3ea7, 0x6920, 0x6922, 0xa684, - 0x1800, 0x00c0, 0x3121, 0x6820, 0xd084, 0x00c0, 0x3127, 0x6818, - 0xa086, 0x0008, 0x00c0, 0x30de, 0x681b, 0x0000, 0xd6d4, 0x0040, - 0x318c, 0xd6bc, 0x0040, 0x311e, 0x7087, 0x0000, 0x6818, 0xa084, - 0x003f, 0xa08a, 0x000d, 0x0050, 0x311e, 0xa08a, 0x000c, 0x7186, - 0x2001, 0x000c, 0x800c, 0x718a, 0x789b, 0x0061, 0x78aa, 0x157e, - 0x137e, 0x147e, 0x017e, 0x3208, 0xa18c, 0x0300, 0x0040, 0x3110, - 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x310c, - 0x20a1, 0x012b, 0x0078, 0x3112, 0x20a1, 0x022b, 0x0078, 0x3112, - 0x20a1, 0x012b, 0x017f, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, - 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x781b, 0x0064, - 0x007c, 0xd6e4, 0x0040, 0x3127, 0x781b, 0x0076, 0x007c, 0xa684, - 0x0060, 0x0040, 0x3189, 0xd6dc, 0x0040, 0x3189, 0xd6fc, 0x00c0, - 0x3133, 0x0078, 0x314a, 0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8, - 0x78d0, 0x801b, 0x00c8, 0x313d, 0x8000, 0xa084, 0x003f, 0xa108, - 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, - 0xa303, 0x68ae, 0xd6f4, 0x0040, 0x3150, 0xc6f4, 0x7e5a, 0x6eb6, - 0x7000, 0xa086, 0x0003, 0x00c0, 0x315e, 0x007e, 0x1078, 0x4326, - 0x1078, 0x45f7, 0x007f, 0x781b, 0x0073, 0x007c, 0xa006, 0x1078, - 0x46e5, 0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0040, - 0x316d, 0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, - 0x6ba6, 0x7bd6, 0x7bde, 0x2300, 0xa405, 0x00c0, 0x317d, 0xc6f5, - 0x7e5a, 0x6eb6, 0x781b, 0x0073, 0x007c, 0x781b, 0x0073, 0x2200, - 0xa115, 0x00c0, 0x3186, 0x1078, 0x45f7, 0x007c, 0x1078, 0x462d, - 0x007c, 0x781b, 0x0076, 0x007c, 0x781b, 0x0064, 0x007c, 0x1078, - 0x28ec, 0x0078, 0x31dd, 0x6920, 0xd1c4, 0x0040, 0x31a6, 0xc1c4, - 0x6922, 0x0c7e, 0x7058, 0x2060, 0x6000, 0xc0e4, 0x6002, 0x6004, - 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x0078, 0x31d1, 0xd1cc, 0x0040, - 0x31d1, 0xc1cc, 0x6922, 0x0c7e, 0x7058, 0x2060, 0x6000, 0xc0ec, - 0x6002, 0x6004, 0xc0a4, 0x6006, 0x2008, 0x2c48, 0x0c7f, 0xd19c, - 0x0040, 0x31d1, 0x1078, 0x3fdd, 0x1078, 0x3cda, 0x88ff, 0x0040, - 0x31d1, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, - 0xd6d4, 0x00c0, 0x31ce, 0x781b, 0x0061, 0x007c, 0x781b, 0x0075, - 0x007c, 0x7e58, 0xd6d4, 0x00c0, 0x31d8, 0x781b, 0x0064, 0x007c, - 0x781b, 0x0076, 0x007c, 0x0078, 0x3ea2, 0x2019, 0x0000, 0x7990, - 0xa18c, 0x0007, 0x00c0, 0x31eb, 0x6820, 0xa084, 0x0100, 0x0040, - 0x31db, 0x2009, 0x0008, 0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, - 0xa286, 0x0001, 0x00c0, 0x3207, 0x2300, 0x7ca8, 0xa400, 0x2018, - 0xa102, 0x0040, 0x31ff, 0x0048, 0x31ff, 0x0078, 0x3201, 0x0078, - 0x3193, 0x24a8, 0x7aa8, 0x00f0, 0x3201, 0x0078, 0x31ed, 0xa284, - 0x00f0, 0xa086, 0x0020, 0x00c0, 0x325b, 0x8318, 0x8318, 0x2300, - 0xa102, 0x0040, 0x3217, 0x0048, 0x3217, 0x0078, 0x3258, 0xa286, - 0x0023, 0x0040, 0x31db, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, - 0xa684, 0xfff1, 0xc0a5, 0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a, - 0x0c7e, 0x7058, 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd1a4, - 0x0040, 0x3238, 0x1078, 0x3fdd, 0x1078, 0x3df6, 0x0078, 0x3246, - 0x0c7e, 0x7058, 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd19c, - 0x0040, 0x31d1, 0x1078, 0x3fdd, 0x1078, 0x3cda, 0x88ff, 0x0040, - 0x31d1, 0x789b, 0x0060, 0x2800, 0x78aa, 0xc695, 0x7e5a, 0xd6d4, - 0x00c0, 0x3255, 0x781b, 0x0061, 0x007c, 0x781b, 0x0075, 0x007c, - 0x7aa8, 0x0078, 0x31ed, 0x8318, 0x2300, 0xa102, 0x0040, 0x3264, - 0x0048, 0x3264, 0x0078, 0x31ed, 0xa284, 0x0080, 0x00c0, 0x3ea7, - 0x0078, 0x3ea2, 0x0078, 0x3ea7, 0x0078, 0x3e9d, 0x7058, 0xa04d, - 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e, 0x0001, 0x0040, - 0x327b, 0x1078, 0x28ec, 0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084, - 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x3e9d, 0x0079, 0x3287, 0x3e9d, - 0x3c2c, 0x3e9d, 0x3d9e, 0xa282, 0x0000, 0x00c0, 0x3291, 0x1078, - 0x28ec, 0x1078, 0x3eae, 0x781b, 0x0075, 0x007c, 0xa282, 0x0003, - 0x00c0, 0x329c, 0x1078, 0x28ec, 0xd4fc, 0x00c0, 0x32bc, 0x7064, - 0xa005, 0x0040, 0x32a5, 0x1078, 0x28ec, 0x6f14, 0x7776, 0xa7bc, - 0x8f00, 0x1078, 0x3fe1, 0x6008, 0xa085, 0x0021, 0x600a, 0x8738, - 0xa784, 0x001f, 0x00c0, 0x32a9, 0x1078, 0x3eb2, 0x7067, 0x0002, - 0x701f, 0x0009, 0x0078, 0x32be, 0x1078, 0x3ebe, 0x781b, 0x0075, - 0x007c, 0xa282, 0x0004, 0x0050, 0x32c7, 0x1078, 0x28ec, 0x2300, - 0x0079, 0x32ca, 0x32cd, 0x346b, 0x34ae, 0xa286, 0x0003, 0x0040, - 0x3304, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x71d4, 0xd1b4, 0x0078, - 0x32fc, 0x0040, 0x32fc, 0x7868, 0xa084, 0x00ff, 0x00c0, 0x32fc, - 0xa282, 0x0002, 0x00c8, 0x32fc, 0x0d7e, 0x783b, 0x8300, 0x781b, - 0x004c, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, - 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x0d7f, - 0x2001, 0x0000, 0x0078, 0x3308, 0x783b, 0x1300, 0x781b, 0x004a, - 0x2001, 0x0000, 0x0078, 0x3308, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, - 0x704a, 0x68a0, 0xd0ec, 0x0040, 0x3310, 0x6008, 0xc08d, 0x600a, - 0xa284, 0x000f, 0x0079, 0x3314, 0x344b, 0x3321, 0x331e, 0x35ae, - 0x35f2, 0x2946, 0x331c, 0x331c, 0x1078, 0x28ec, 0x6008, 0xc0d4, - 0x600a, 0xd6e4, 0x00c0, 0x3328, 0x1078, 0x4326, 0x0040, 0x3404, - 0x7868, 0xa08c, 0x00ff, 0x0040, 0x3369, 0xa186, 0x0008, 0x00c0, - 0x333e, 0x1078, 0x3bd2, 0x6008, 0xc0a4, 0x600a, 0x1078, 0x3b6b, - 0x0040, 0x3369, 0x1078, 0x4326, 0x0078, 0x3353, 0xa186, 0x0028, - 0x00c0, 0x3369, 0x1078, 0x4326, 0x6008, 0xc0a4, 0x600a, 0x6018, - 0xa005, 0x0040, 0x3353, 0x8001, 0x601a, 0x0040, 0x3353, 0x8001, - 0x0040, 0x3353, 0x601e, 0x6820, 0xd084, 0x0040, 0x2946, 0xc084, - 0x6822, 0x705c, 0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f, 0x6004, - 0x6802, 0xa005, 0x2d00, 0x00c0, 0x3366, 0x6002, 0x6006, 0x0078, - 0x2946, 0x017e, 0x81ff, 0x00c0, 0x33b0, 0x7000, 0xa086, 0x0030, - 0x0040, 0x33b0, 0x71d4, 0xd1b4, 0x00c0, 0x3397, 0x7060, 0xa005, - 0x00c0, 0x33b0, 0x70a4, 0xa086, 0x0001, 0x0040, 0x33b0, 0x7003, + 0x6018, 0x8001, 0x601a, 0x0c7f, 0x1078, 0x41fe, 0x2c50, 0x1078, + 0x4442, 0x6824, 0xa005, 0x0040, 0x2b5d, 0xa082, 0x0006, 0x0048, + 0x2b5b, 0x0078, 0x2b5d, 0x6827, 0x0005, 0x6814, 0xa084, 0x001f, + 0xc0bd, 0x78aa, 0x2031, 0x0020, 0x2041, 0x0001, 0x2001, 0x0003, + 0x0078, 0x2c92, 0xc28d, 0x72d6, 0x72c0, 0xa200, 0xa015, 0x7154, + 0x8108, 0xa12a, 0x0048, 0x2b75, 0x71c0, 0x2164, 0x6504, 0x85ff, + 0x00c0, 0x2b8c, 0x7156, 0x8421, 0x00c0, 0x2b70, 0x70d4, 0xd08c, + 0x0040, 0x2b88, 0x70d0, 0xa005, 0x00c0, 0x2b88, 0x70d3, 0x000a, + 0x007c, 0x2200, 0x0078, 0x2b7a, 0x70d4, 0xc08c, 0x70d6, 0x70d3, + 0x0000, 0x6034, 0xa005, 0x00c0, 0x2b89, 0x6708, 0xa784, 0x073f, + 0x0040, 0x2bbb, 0xd7d4, 0x00c0, 0x2b89, 0xa784, 0x0021, 0x00c0, + 0x2b89, 0xa784, 0x0002, 0x0040, 0x2bac, 0xa784, 0x0004, 0x0040, + 0x2b89, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218, 0x00c0, 0x2b89, + 0xa784, 0x0100, 0x0040, 0x2bbb, 0x6018, 0xa005, 0x00c0, 0x2b89, + 0xa7bc, 0xfeff, 0x670a, 0x2568, 0x6823, 0x0000, 0x6e1c, 0xa684, + 0x000e, 0x6318, 0x0040, 0x2bcc, 0x601c, 0xa302, 0x0048, 0x2bcf, + 0x0040, 0x2bcf, 0x0078, 0x2b89, 0x83ff, 0x00c0, 0x2b89, 0x2d58, + 0x2c50, 0x7156, 0xd7bc, 0x00c0, 0x2bd8, 0x7028, 0x6022, 0x603a, + 0xc7bc, 0x670a, 0x68c0, 0xa065, 0xa04d, 0x6100, 0x2a60, 0x2041, + 0x0001, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, 0xd1fc, 0x0040, + 0x2bec, 0xd684, 0x0040, 0x2bee, 0xa39c, 0xffbf, 0xd6a4, 0x0040, + 0x2bf3, 0xa39d, 0x0020, 0xa684, 0x000e, 0x00c0, 0x2c3e, 0xc7a5, + 0x670a, 0x2c00, 0x68c6, 0x77a4, 0xa786, 0x0001, 0x00c0, 0x2c12, + 0x70d4, 0xd0b4, 0x00c0, 0x2c12, 0x7000, 0xa082, 0x0002, 0x00c8, + 0x2c12, 0x7830, 0xd0bc, 0x00c0, 0x2c12, 0x789b, 0x0010, 0x7baa, + 0x0078, 0x2c8a, 0x8739, 0x77a6, 0x2750, 0x77b0, 0xa7b0, 0x0005, + 0x70ac, 0xa606, 0x00c0, 0x2c1d, 0x76a8, 0x76b2, 0x2c3a, 0x8738, + 0x2d3a, 0x8738, 0x283a, 0x8738, 0x233a, 0x8738, 0x253a, 0x7830, + 0xd0bc, 0x0040, 0x2c35, 0x2091, 0x8000, 0x2091, 0x303d, 0x70d4, + 0xa084, 0x303d, 0x2091, 0x8000, 0x2090, 0xaad5, 0x0000, 0x0040, + 0x2c3d, 0x8421, 0x2200, 0x00c0, 0x2b6f, 0x007c, 0xd1dc, 0x0040, + 0x3e00, 0x2029, 0x0020, 0xd69c, 0x00c0, 0x2c4b, 0x8528, 0xd68c, + 0x00c0, 0x2c4b, 0x8528, 0x8840, 0x6f14, 0x610c, 0x8108, 0xa18c, + 0x00ff, 0x70cc, 0xa160, 0x2c64, 0x8cff, 0x0040, 0x2c6a, 0x6014, + 0xa706, 0x00c0, 0x2c53, 0x60b8, 0x8001, 0x60ba, 0x00c0, 0x2c4e, + 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x2200, 0x8421, 0x00c0, + 0x2b6f, 0x007c, 0x2a60, 0x610e, 0x69be, 0x2c00, 0x68c6, 0x8840, + 0x6008, 0xc0d5, 0x600a, 0x77a4, 0xa786, 0x0001, 0x00c0, 0x2c12, + 0x70d4, 0xd0b4, 0x00c0, 0x2c12, 0x7000, 0xa082, 0x0002, 0x00c8, + 0x2c12, 0x7830, 0xd0bc, 0x00c0, 0x2c12, 0x789b, 0x0010, 0x7baa, + 0x7daa, 0x79aa, 0x2001, 0x0002, 0x007e, 0x6018, 0x8000, 0x601a, + 0x0078, 0x2c93, 0x007e, 0x2960, 0x6104, 0x2a60, 0xa184, 0x0018, + 0x0040, 0x2caf, 0xa184, 0x0010, 0x0040, 0x2ca2, 0x1078, 0x4011, + 0x00c0, 0x2cd4, 0xa184, 0x0008, 0x0040, 0x2caf, 0x69a0, 0xa184, + 0x0600, 0x00c0, 0x2caf, 0x1078, 0x3ef5, 0x0078, 0x2cd4, 0x69a0, + 0xa184, 0x1e00, 0x0040, 0x2cdf, 0xa184, 0x0800, 0x0040, 0x2cc8, + 0x0c7e, 0x2960, 0x6000, 0xa085, 0x2000, 0x6002, 0x6104, 0xa18d, + 0x0010, 0x6106, 0x0c7f, 0x1078, 0x4011, 0x00c0, 0x2cd4, 0x69a0, + 0xa184, 0x0200, 0x0040, 0x2cd0, 0x1078, 0x3f54, 0x0078, 0x2cd4, + 0xa184, 0x0400, 0x00c0, 0x2cab, 0x69a0, 0xa184, 0x1000, 0x0040, + 0x2cdf, 0x6914, 0xa18c, 0xff00, 0x810f, 0x1078, 0x279f, 0x027f, + 0xa68c, 0x00e0, 0xa684, 0x0060, 0x0040, 0x2cec, 0xa086, 0x0060, + 0x00c0, 0x2cec, 0xa18d, 0x4000, 0xa18d, 0x0104, 0x69b6, 0x789b, + 0x0060, 0x2800, 0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc, 0x0040, + 0x2d07, 0xc0fc, 0x7087, 0x0000, 0xa08a, 0x000d, 0x0050, 0x2d05, + 0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a, 0x78aa, + 0x3518, 0x3340, 0x3428, 0x8000, 0x80ac, 0xaf80, 0x002b, 0x20a0, + 0x789b, 0x0000, 0xad80, 0x000b, 0x2098, 0x53a6, 0x23a8, 0x2898, + 0x25a0, 0xa286, 0x0020, 0x00c0, 0x2d3f, 0x70d4, 0xc0b5, 0x70d6, + 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x6814, 0xc0fc, 0x8007, 0x7882, + 0xa286, 0x0002, 0x0040, 0x2d75, 0x70a4, 0x8000, 0x70a6, 0x74b4, + 0xa498, 0x0005, 0x70ac, 0xa306, 0x00c0, 0x2d37, 0x73a8, 0x73b6, + 0xa286, 0x0010, 0x0040, 0x29c1, 0x0d7f, 0x0c7f, 0x007c, 0x7000, + 0xa005, 0x00c0, 0x2d1d, 0xa286, 0x0002, 0x00c0, 0x2d8f, 0x1078, + 0x4360, 0x00c0, 0x2d1d, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x2091, + 0x8000, 0x781b, 0x005b, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, + 0x6898, 0x78d2, 0x78da, 0x2091, 0x8001, 0x7808, 0xc08d, 0x780a, + 0x127e, 0x0d7e, 0x0c7e, 0x70d4, 0xa084, 0x2700, 0x2090, 0x0c7f, + 0x0d7f, 0x127f, 0x2900, 0x705a, 0x68bc, 0x7042, 0x7003, 0x0002, + 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x7830, 0xd0bc, 0x0040, + 0x2d81, 0x2091, 0x303d, 0x70d4, 0xa084, 0x303d, 0x2091, 0x8000, + 0x2090, 0x70a4, 0xa005, 0x00c0, 0x2d86, 0x007c, 0x8421, 0x0040, + 0x2d85, 0x7250, 0x70c0, 0xa200, 0xa015, 0x0078, 0x2b6f, 0xa286, + 0x0010, 0x00c0, 0x2dc0, 0x1078, 0x4360, 0x00c0, 0x2d1d, 0x6814, + 0xc0fc, 0x8007, 0x7882, 0x781b, 0x005b, 0x68b4, 0x785a, 0x6894, + 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a, + 0x70a4, 0x8000, 0x70a6, 0x74b4, 0xa490, 0x0005, 0x70ac, 0xa206, + 0x00c0, 0x2db3, 0x72a8, 0x72b6, 0x2900, 0x705a, 0x68bc, 0x7042, + 0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x007c, + 0x6bb4, 0xa39d, 0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, 0x7882, + 0x6b94, 0x7bd6, 0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, 0x005b, + 0x2900, 0x705a, 0x7202, 0x7808, 0xc08d, 0x780a, 0x2300, 0xa605, + 0x0040, 0x2deb, 0x70d4, 0xa084, 0x2700, 0xa086, 0x2300, 0x00c0, + 0x2de5, 0x2009, 0x0000, 0x0078, 0x2de7, 0x2009, 0x0001, 0xa284, + 0x000f, 0x1079, 0x2def, 0xad80, 0x0009, 0x7046, 0x007c, 0x2df7, + 0x48bd, 0x48bd, 0x48aa, 0x48bd, 0x2df7, 0x2df7, 0x2df7, 0x1078, + 0x296b, 0x7808, 0xa084, 0xfffd, 0x780a, 0x1078, 0x295e, 0x0f7e, + 0x2079, 0x4e00, 0x78ac, 0x0f7f, 0xd084, 0x0040, 0x2e21, 0x7064, + 0xa086, 0x0001, 0x00c0, 0x2e0f, 0x7066, 0x0078, 0x2ef8, 0x7064, + 0xa086, 0x0005, 0x00c0, 0x2e1f, 0x707c, 0x2068, 0x681b, 0x0004, + 0x6817, 0x0000, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x7067, + 0x0000, 0x70a7, 0x0000, 0x70a8, 0x70b2, 0x70b6, 0x1078, 0x2aba, + 0x157e, 0x2011, 0x0004, 0x7164, 0xa186, 0x0001, 0x0040, 0x2e41, + 0xa186, 0x0007, 0x00c0, 0x2e38, 0x701f, 0x0005, 0x0078, 0x2e41, + 0x701f, 0x0001, 0x7067, 0x0000, 0x70d4, 0xc0dd, 0x70d6, 0x0078, + 0x2e43, 0x7067, 0x0000, 0x2001, 0x4e0a, 0x2004, 0xa084, 0x00ff, + 0xa086, 0x0018, 0x0040, 0x2e53, 0x7018, 0x7016, 0xa005, 0x00c0, + 0x2e53, 0x70a7, 0x0001, 0x067e, 0x1078, 0x4586, 0x20a9, 0x0010, + 0x2039, 0x0000, 0x1078, 0x40f8, 0xa7b8, 0x0100, 0x00f0, 0x2e5a, + 0x067f, 0x7000, 0x0079, 0x2e64, 0x2e9e, 0x2e79, 0x2e79, 0x2e6e, + 0x2e9e, 0x2e9e, 0x2e9e, 0x2e6c, 0x1078, 0x296b, 0x7060, 0xa005, + 0x0040, 0x2e9e, 0xad06, 0x00c0, 0x2e79, 0x6800, 0x7062, 0x0078, + 0x2e8b, 0x6820, 0xd084, 0x00c0, 0x2e87, 0x6f14, 0x1078, 0x41fe, + 0x6008, 0xc0d4, 0x600a, 0x1078, 0x3dd0, 0x0078, 0x2e8b, 0x705c, + 0x2060, 0x6800, 0x6002, 0xa684, 0x5f00, 0x681e, 0x6818, 0xd0fc, + 0x0040, 0x2e93, 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, 0x6820, + 0xa084, 0x00ff, 0xc09d, 0x6822, 0x1078, 0x202c, 0xb284, 0x0400, + 0x0040, 0x2ea6, 0x2021, 0x95d0, 0x0078, 0x2ea8, 0x2021, 0x94c0, + 0x1078, 0x2efd, 0xb284, 0x0400, 0x0040, 0x2eb2, 0x2021, 0x4e98, + 0x0078, 0x2eb4, 0x2021, 0x4e58, 0x1078, 0x2efd, 0x20a9, 0x0101, + 0xb284, 0x0400, 0x0040, 0x2ec0, 0x2021, 0x94d0, 0x0078, 0x2ec2, + 0x2021, 0x93c0, 0x1078, 0x2efd, 0x8420, 0x00f0, 0x2ec2, 0xb284, + 0x0300, 0x0040, 0x2ecf, 0x2061, 0x53c0, 0x0078, 0x2ed1, 0x2061, + 0x73c0, 0x2021, 0x0002, 0x20a9, 0x0100, 0x6110, 0x81ff, 0x0040, + 0x2eee, 0x6018, 0x017e, 0x007e, 0x2011, 0x4e02, 0x220c, 0xa102, + 0x2012, 0x007f, 0x017f, 0xa102, 0x0050, 0x2eee, 0x6012, 0x00c0, + 0x2eee, 0x2011, 0x4e04, 0x2204, 0xc0a5, 0x2012, 0x601b, 0x0000, + 0xace0, 0x0010, 0x00f0, 0x2ed5, 0x8421, 0x00c0, 0x2ed3, 0x157f, + 0x7003, 0x0000, 0x704f, 0x0000, 0x007c, 0x047e, 0x2404, 0xa005, + 0x0040, 0x2f18, 0x2068, 0x6800, 0x007e, 0x6a1a, 0x6817, 0x0000, + 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820, 0xa084, + 0x00ff, 0xc09d, 0x6822, 0x1078, 0x202c, 0x007f, 0x0078, 0x2eff, + 0x047f, 0x2023, 0x0000, 0x007c, 0xa282, 0x0003, 0x0050, 0x2f22, + 0x1078, 0x296b, 0x2300, 0x0079, 0x2f25, 0x2f28, 0x2fb3, 0x2fd0, + 0xa282, 0x0002, 0x0040, 0x2f2e, 0x1078, 0x296b, 0x7064, 0x7067, + 0x0000, 0x7083, 0x0000, 0x0079, 0x2f35, 0x2f3d, 0x2f3d, 0x2f3f, + 0x2f7f, 0x3e0c, 0x2f3d, 0x2f7f, 0x2f3d, 0x1078, 0x296b, 0x7774, + 0x1078, 0x40f8, 0x7774, 0xa7bc, 0x8f00, 0x1078, 0x41fe, 0x6018, + 0xa005, 0x0040, 0x2f76, 0xd7fc, 0x00c0, 0x2f52, 0x2021, 0x94c0, + 0x0078, 0x2f54, 0x2021, 0x95d0, 0x2009, 0x0005, 0x2011, 0x0010, + 0x1078, 0x2feb, 0x0040, 0x2f76, 0x157e, 0x20a9, 0x0101, 0xd7fc, + 0x00c0, 0x2f66, 0x2021, 0x93c0, 0x0078, 0x2f68, 0x2021, 0x94d0, + 0x047e, 0x2009, 0x0005, 0x2011, 0x0010, 0x1078, 0x2feb, 0x047f, + 0x0040, 0x2f75, 0x8420, 0x00f0, 0x2f68, 0x157f, 0x8738, 0xa784, + 0x001f, 0x00c0, 0x2f45, 0x0078, 0x29c5, 0x0078, 0x29c5, 0x7774, + 0x1078, 0x41fe, 0x6018, 0xa005, 0x0040, 0x2fb1, 0xd7fc, 0x00c0, + 0x2f8d, 0x2021, 0x94c0, 0x0078, 0x2f8f, 0x2021, 0x95d0, 0x2009, + 0x0005, 0x2011, 0x0020, 0x1078, 0x2feb, 0x0040, 0x2fb1, 0x157e, + 0x20a9, 0x0101, 0xd7fc, 0x00c0, 0x2fa1, 0x2021, 0x93c0, 0x0078, + 0x2fa3, 0x2021, 0x94d0, 0x047e, 0x2009, 0x0005, 0x2011, 0x0020, + 0x1078, 0x2feb, 0x047f, 0x0040, 0x2fb0, 0x8420, 0x00f0, 0x2fa3, + 0x157f, 0x0078, 0x29c5, 0x2200, 0x0079, 0x2fb6, 0x2fb9, 0x2fbb, + 0x2fbb, 0x1078, 0x296b, 0x2009, 0x0012, 0x7064, 0xa086, 0x0002, + 0x0040, 0x2fc4, 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0040, 0x2fc9, + 0x691a, 0x7067, 0x0000, 0x70d4, 0xc0dd, 0x70d6, 0x0078, 0x430d, + 0x2200, 0x0079, 0x2fd3, 0x2fd8, 0x2fbb, 0x2fd6, 0x1078, 0x296b, + 0x1078, 0x4586, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3d7e, 0x1078, + 0x3ded, 0x6008, 0xa084, 0xfbef, 0x600a, 0x1078, 0x3d6f, 0x0040, + 0x3d7e, 0x0078, 0x29c5, 0x2404, 0xa005, 0x0040, 0x3024, 0x2068, + 0x2d04, 0x007e, 0x6814, 0xa706, 0x0040, 0x2ffa, 0x2d20, 0x007f, + 0x0078, 0x2fec, 0x007f, 0x2022, 0x691a, 0x6817, 0x0000, 0x682b, + 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820, 0xa084, 0x00ff, + 0xa205, 0x6822, 0x1078, 0x202c, 0x2021, 0x4e02, 0x241c, 0x8319, + 0x2322, 0x6010, 0x8001, 0x6012, 0x00c0, 0x301b, 0x2021, 0x4e04, + 0x2404, 0xc0a5, 0x2022, 0x6008, 0xa084, 0xf9ef, 0x600a, 0x1078, + 0x2adb, 0x1078, 0x3ded, 0x007c, 0xa085, 0x0001, 0x0078, 0x3023, + 0x2300, 0x0079, 0x302b, 0x3030, 0x302e, 0x30b0, 0x1078, 0x296b, + 0x78e4, 0xa005, 0x00d0, 0x3066, 0x3208, 0x007e, 0x2001, 0x4e04, + 0x2004, 0xd0ec, 0x007f, 0x0040, 0x3041, 0xa18c, 0x0300, 0x0078, + 0x3043, 0xa18c, 0x0400, 0x0040, 0x3049, 0x0018, 0x29c1, 0x0078, + 0x304b, 0x0028, 0x29c1, 0x2008, 0xa084, 0x0030, 0x00c0, 0x3052, + 0x0078, 0x3770, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3050, 0x2100, + 0xa084, 0x0007, 0x0079, 0x305c, 0x3090, 0x309a, 0x3085, 0x3064, + 0x4355, 0x4355, 0x3064, 0x30a5, 0x1078, 0x296b, 0x7000, 0xa086, + 0x0004, 0x00c0, 0x3080, 0x7064, 0xa086, 0x0002, 0x00c0, 0x3076, + 0x2011, 0x0002, 0x2019, 0x0000, 0x0078, 0x2f1c, 0x7064, 0xa086, + 0x0006, 0x0040, 0x3070, 0x7064, 0xa086, 0x0004, 0x0040, 0x3070, + 0x79e4, 0x2001, 0x0003, 0x0078, 0x33fa, 0x6818, 0xd0fc, 0x0040, + 0x308b, 0x681b, 0x001d, 0x1078, 0x40c8, 0x781b, 0x0064, 0x007c, + 0x6818, 0xd0fc, 0x0040, 0x3096, 0x681b, 0x001d, 0x1078, 0x40c8, + 0x0078, 0x4331, 0x6818, 0xd0fc, 0x0040, 0x30a0, 0x681b, 0x001d, + 0x1078, 0x40c8, 0x781b, 0x00f8, 0x007c, 0x6818, 0xd0fc, 0x0040, + 0x30ab, 0x681b, 0x001d, 0x1078, 0x40c8, 0x781b, 0x00c8, 0x007c, + 0xa584, 0x000f, 0x00c0, 0x30cf, 0x1078, 0x295e, 0x7000, 0x0079, + 0x30b9, 0x29c5, 0x30c1, 0x30c3, 0x3d7e, 0x3d7e, 0x3d7e, 0x30c1, + 0x30c1, 0x1078, 0x296b, 0x1078, 0x3ded, 0x6008, 0xa084, 0xfbef, + 0x600a, 0x1078, 0x3d6f, 0x0040, 0x3d7e, 0x0078, 0x29c5, 0x78e4, + 0xa005, 0x00d0, 0x3066, 0x3208, 0x007e, 0x2001, 0x4e04, 0x2004, + 0xd0ec, 0x007f, 0x0040, 0x30e0, 0xa18c, 0x0300, 0x0078, 0x30e2, + 0xa18c, 0x0400, 0x0040, 0x30e8, 0x0018, 0x3066, 0x0078, 0x30ea, + 0x0028, 0x3066, 0x2008, 0xa084, 0x0030, 0x00c0, 0x30f2, 0x781b, + 0x005b, 0x007c, 0x78ec, 0xa084, 0x0003, 0x0040, 0x30ef, 0x2100, + 0xa184, 0x0007, 0x0079, 0x30fc, 0x310b, 0x310f, 0x3106, 0x3104, + 0x4355, 0x4355, 0x3104, 0x434f, 0x1078, 0x296b, 0x1078, 0x40d0, + 0x781b, 0x0064, 0x007c, 0x1078, 0x40d0, 0x0078, 0x4331, 0x1078, + 0x40d0, 0x781b, 0x00f8, 0x007c, 0x1078, 0x40d0, 0x781b, 0x00c8, + 0x007c, 0x2300, 0x0079, 0x311c, 0x3121, 0x311f, 0x3123, 0x1078, + 0x296b, 0x0078, 0x395f, 0x681b, 0x0016, 0x78a3, 0x0000, 0x79e4, + 0xa184, 0x0030, 0x0040, 0x395f, 0x78ec, 0xa084, 0x0003, 0x0040, + 0x395f, 0xa184, 0x0100, 0x0040, 0x3127, 0xa184, 0x0007, 0x0079, + 0x3139, 0x3141, 0x310f, 0x3085, 0x430d, 0x4355, 0x4355, 0x430d, + 0x434f, 0x1078, 0x4319, 0x007c, 0xa282, 0x0005, 0x0050, 0x314a, + 0x1078, 0x296b, 0x2300, 0x0079, 0x314d, 0x3150, 0x3380, 0x338b, + 0x2200, 0x0079, 0x3153, 0x316d, 0x315a, 0x316d, 0x3158, 0x3363, + 0x1078, 0x296b, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa082, + 0x0020, 0x0048, 0x40b7, 0xa08a, 0x0004, 0x00c8, 0x40b7, 0x0079, + 0x3169, 0x40b7, 0x40b7, 0x40b7, 0x4061, 0x789b, 0x0018, 0x79a8, + 0xa184, 0x0080, 0x0040, 0x317e, 0x0078, 0x40b7, 0x7000, 0xa005, + 0x00c0, 0x3174, 0x2011, 0x0004, 0x0078, 0x3b4a, 0xa184, 0x00ff, + 0xa08a, 0x0010, 0x00c8, 0x40b7, 0x0079, 0x3186, 0x3198, 0x3196, + 0x31ad, 0x31b1, 0x3284, 0x40b7, 0x40b7, 0x3286, 0x40b7, 0x40b7, + 0x335f, 0x335f, 0x40b7, 0x40b7, 0x40b7, 0x3361, 0x1078, 0x296b, + 0xd6e4, 0x0040, 0x31a3, 0x2001, 0x0300, 0x8000, 0x8000, 0x783a, + 0x781b, 0x00c3, 0x007c, 0x6818, 0xd0fc, 0x0040, 0x31ab, 0x681b, + 0x001d, 0x0078, 0x319b, 0x0078, 0x430d, 0x681b, 0x001d, 0x0078, + 0x40c1, 0x6920, 0x6922, 0xa684, 0x1800, 0x00c0, 0x3216, 0x6820, + 0xd084, 0x00c0, 0x321c, 0x6818, 0xa086, 0x0008, 0x00c0, 0x31c2, + 0x681b, 0x0000, 0xd6d4, 0x0040, 0x3281, 0xd6bc, 0x0040, 0x3202, + 0x7087, 0x0000, 0x6818, 0xa084, 0x003f, 0xa08a, 0x000d, 0x0050, + 0x3202, 0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a, + 0x789b, 0x0061, 0x78aa, 0x157e, 0x137e, 0x147e, 0x017e, 0x3208, + 0xa18c, 0x0300, 0x0040, 0x31f4, 0x007e, 0x2001, 0x4e04, 0x2004, + 0xd0ec, 0x007f, 0x0040, 0x31f0, 0x20a1, 0x012b, 0x0078, 0x31f6, + 0x20a1, 0x022b, 0x0078, 0x31f6, 0x20a1, 0x012b, 0x017f, 0x789b, + 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, + 0x137f, 0x157f, 0x6038, 0xa005, 0x00c0, 0x3211, 0x681c, 0xa084, + 0x000e, 0x0040, 0x40c1, 0x1078, 0x40d7, 0x782b, 0x3008, 0x0078, + 0x3213, 0x8001, 0x603a, 0x781b, 0x0067, 0x007c, 0xd6e4, 0x0040, + 0x321c, 0x781b, 0x0079, 0x007c, 0xa684, 0x0060, 0x0040, 0x327e, + 0xd6dc, 0x0040, 0x327e, 0xd6fc, 0x00c0, 0x3228, 0x0078, 0x323f, + 0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8, 0x78d0, 0x801b, 0x00c8, + 0x3232, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, + 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0xd6f4, + 0x0040, 0x3245, 0xc6f4, 0x7e5a, 0x6eb6, 0x7000, 0xa086, 0x0003, + 0x00c0, 0x3253, 0x007e, 0x1078, 0x4586, 0x1078, 0x48bd, 0x007f, + 0x781b, 0x0076, 0x007c, 0xa006, 0x1078, 0x49c3, 0x6ab0, 0x69ac, + 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0040, 0x3262, 0x2200, 0xa422, + 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, 0x6ba6, 0x7bd6, 0x7bde, + 0x2300, 0xa405, 0x00c0, 0x3272, 0xc6f5, 0x7e5a, 0x6eb6, 0x781b, + 0x0076, 0x007c, 0x781b, 0x0076, 0x2200, 0xa115, 0x00c0, 0x327b, + 0x1078, 0x48bd, 0x007c, 0x1078, 0x48f5, 0x007c, 0x781b, 0x0079, + 0x007c, 0x781b, 0x0067, 0x007c, 0x1078, 0x296b, 0x0078, 0x32d2, + 0x6920, 0xd1c4, 0x0040, 0x329b, 0xc1c4, 0x6922, 0x0c7e, 0x7058, + 0x2060, 0x6000, 0xc0e4, 0x6002, 0x6004, 0xa084, 0xfff5, 0x6006, + 0x0c7f, 0x0078, 0x32c6, 0xd1cc, 0x0040, 0x32c6, 0xc1cc, 0x6922, + 0x0c7e, 0x7058, 0x2060, 0x6000, 0xc0ec, 0x6002, 0x6004, 0xc0a4, + 0x6006, 0x2008, 0x2c48, 0x0c7f, 0xd19c, 0x0040, 0x32c6, 0x1078, + 0x41fa, 0x1078, 0x3ef5, 0x88ff, 0x0040, 0x32c6, 0x789b, 0x0060, + 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x32c3, + 0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x7e58, 0xd6d4, + 0x00c0, 0x32cd, 0x781b, 0x0067, 0x007c, 0x781b, 0x0079, 0x007c, + 0x0078, 0x40bc, 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007, 0x00c0, + 0x32e0, 0x6820, 0xa084, 0x0100, 0x0040, 0x32d0, 0x2009, 0x0008, + 0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x00c0, + 0x32fc, 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040, 0x32f4, + 0x0048, 0x32f4, 0x0078, 0x32f6, 0x0078, 0x3288, 0x24a8, 0x7aa8, + 0x00f0, 0x32f6, 0x0078, 0x32e2, 0xa284, 0x00f0, 0xa086, 0x0020, + 0x00c0, 0x3350, 0x8318, 0x8318, 0x2300, 0xa102, 0x0040, 0x330c, + 0x0048, 0x330c, 0x0078, 0x334d, 0xa286, 0x0023, 0x0040, 0x32d0, + 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, 0xa684, 0xfff1, 0xc0a5, + 0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a, 0x0c7e, 0x7058, 0x2060, + 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd1a4, 0x0040, 0x332d, 0x1078, + 0x41fa, 0x1078, 0x4011, 0x0078, 0x333b, 0x0c7e, 0x7058, 0x2060, + 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd19c, 0x0040, 0x32c6, 0x1078, + 0x41fa, 0x1078, 0x3ef5, 0x88ff, 0x0040, 0x32c6, 0x789b, 0x0060, + 0x2800, 0x78aa, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x334a, 0x781b, + 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x7aa8, 0x0078, 0x32e2, + 0x8318, 0x2300, 0xa102, 0x0040, 0x3359, 0x0048, 0x3359, 0x0078, + 0x32e2, 0xa284, 0x0080, 0x00c0, 0x40c1, 0x0078, 0x40bc, 0x0078, + 0x40c1, 0x0078, 0x40b7, 0x7058, 0xa04d, 0x789b, 0x0018, 0x78a8, + 0xa084, 0x00ff, 0xa08e, 0x0001, 0x0040, 0x3370, 0x1078, 0x296b, + 0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004, + 0x00c8, 0x40b7, 0x0079, 0x337c, 0x40b7, 0x3e46, 0x40b7, 0x3fb9, + 0xa282, 0x0000, 0x00c0, 0x3386, 0x1078, 0x296b, 0x1078, 0x40c8, + 0x781b, 0x0078, 0x007c, 0xa282, 0x0003, 0x00c0, 0x3391, 0x1078, + 0x296b, 0xd4fc, 0x00c0, 0x33b1, 0x7064, 0xa005, 0x0040, 0x339a, + 0x1078, 0x296b, 0x6f14, 0x7776, 0xa7bc, 0x8f00, 0x1078, 0x41fe, + 0x6008, 0xa085, 0x0021, 0x600a, 0x8738, 0xa784, 0x001f, 0x00c0, + 0x339e, 0x1078, 0x40cc, 0x7067, 0x0002, 0x701f, 0x0009, 0x0078, + 0x33b3, 0x1078, 0x40db, 0x781b, 0x0078, 0x007c, 0xa282, 0x0004, + 0x0050, 0x33bc, 0x1078, 0x296b, 0x2300, 0x0079, 0x33bf, 0x33c2, + 0x3582, 0x35c5, 0xa286, 0x0003, 0x0040, 0x33fa, 0x7200, 0x7cd8, + 0x7ddc, 0x7fd0, 0x71d4, 0xd1bc, 0x00c0, 0x33f2, 0xd1b4, 0x0040, + 0x33f2, 0x7868, 0xa084, 0x00ff, 0x00c0, 0x33f2, 0xa282, 0x0002, + 0x00c8, 0x33f2, 0x0d7e, 0x783b, 0x8300, 0x781b, 0x004c, 0x70bc, + 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, + 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x0d7f, 0x2001, 0x0000, + 0x0078, 0x33fe, 0x783b, 0x1300, 0x781b, 0x004a, 0x2001, 0x0000, + 0x0078, 0x33fe, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x704a, 0x68a0, + 0xd0ec, 0x0040, 0x3406, 0x6008, 0xc08d, 0x600a, 0xa284, 0x000f, + 0x0079, 0x340a, 0x3562, 0x3417, 0x3414, 0x36c8, 0x3754, 0x29c5, + 0x3412, 0x3412, 0x1078, 0x296b, 0x6008, 0xc0d4, 0x600a, 0xd6e4, + 0x0040, 0x341f, 0x7048, 0xa086, 0x0014, 0x00c0, 0x343f, 0x1078, + 0x4586, 0x2009, 0x0000, 0x6818, 0xd0fc, 0x0040, 0x3428, 0x7048, + 0xa086, 0x0014, 0x0040, 0x3439, 0x6818, 0xa086, 0x0008, 0x00c0, + 0x351a, 0x7858, 0xd09c, 0x0040, 0x351a, 0x6820, 0xd0ac, 0x0040, + 0x351a, 0x681b, 0x0014, 0x2009, 0x0002, 0x0078, 0x347e, 0x7868, + 0xa08c, 0x00ff, 0x0040, 0x347e, 0xa186, 0x0008, 0x00c0, 0x3455, + 0x6008, 0xc0a4, 0x600a, 0x1078, 0x3d6f, 0x0040, 0x347e, 0x1078, + 0x3ded, 0x1078, 0x4586, 0x0078, 0x3466, 0xa186, 0x0028, 0x00c0, + 0x347e, 0x6018, 0xa005, 0x0040, 0x3448, 0x8001, 0x0040, 0x3448, + 0x8001, 0x0040, 0x3448, 0x601e, 0x0078, 0x3448, 0x6820, 0xd084, + 0x0040, 0x29c5, 0xc084, 0x6822, 0x1078, 0x2acc, 0x705c, 0x0c7e, + 0x2060, 0x6800, 0x6002, 0x0c7f, 0x6004, 0x6802, 0xa005, 0x2d00, + 0x00c0, 0x347b, 0x6002, 0x6006, 0x0078, 0x29c5, 0x017e, 0x81ff, + 0x00c0, 0x34c8, 0x7000, 0xa086, 0x0030, 0x0040, 0x34c8, 0x71d4, + 0xd1bc, 0x00c0, 0x34c8, 0xd1b4, 0x00c0, 0x34af, 0x7060, 0xa005, + 0x00c0, 0x34c8, 0x70a4, 0xa086, 0x0001, 0x0040, 0x34c8, 0x7003, 0x0000, 0x047e, 0x057e, 0x077e, 0x067e, 0x0c7e, 0x0d7e, 0x1078, - 0x296c, 0x0d7f, 0x0c7f, 0x067f, 0x077f, 0x057f, 0x047f, 0x71d4, - 0xd1b4, 0x00c0, 0x33b0, 0x7003, 0x0040, 0x0078, 0x33b0, 0x1078, - 0x411c, 0x00c0, 0x33b0, 0x781b, 0x005b, 0x0d7e, 0x70bc, 0xa06d, + 0x29ee, 0x0d7f, 0x0c7f, 0x067f, 0x077f, 0x057f, 0x047f, 0x71d4, + 0xd1b4, 0x00c0, 0x34c8, 0x7003, 0x0040, 0x0078, 0x34c8, 0x1078, + 0x4360, 0x00c0, 0x34c8, 0x781b, 0x005b, 0x0d7e, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x7808, 0xc08d, 0x780a, 0x0d7f, - 0x1078, 0x34e8, 0x017f, 0x81ff, 0x0040, 0x3403, 0xa684, 0xdf00, - 0x681e, 0x682b, 0x0000, 0x6f14, 0xa186, 0x0002, 0x00c0, 0x3404, - 0x70d4, 0xd0b4, 0x0040, 0x33d1, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, - 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, - 0x0c7f, 0x6820, 0xd0dc, 0x00c0, 0x3404, 0x8717, 0xa294, 0x000f, - 0x8213, 0x8213, 0x8213, 0xb284, 0x0300, 0x0040, 0x33e3, 0xa290, - 0x4ec0, 0x0078, 0x33e5, 0xa290, 0x4f40, 0xa290, 0x0000, 0x221c, - 0xd3c4, 0x00c0, 0x33ed, 0x0078, 0x33f3, 0x8210, 0x2204, 0xa085, - 0x0018, 0x2012, 0x8211, 0xd3d4, 0x0040, 0x33fe, 0x68a0, 0xd0c4, - 0x00c0, 0x33fe, 0x1078, 0x3562, 0x0078, 0x2946, 0x6008, 0xc08d, - 0x600a, 0x0078, 0x3404, 0x692a, 0x6916, 0x6818, 0xd0fc, 0x0040, - 0x340b, 0x7048, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x6410, 0x84ff, - 0x0040, 0x3420, 0x2009, 0x4a02, 0x2104, 0x8001, 0x200a, 0x8421, - 0x6412, 0x00c0, 0x3420, 0x2021, 0x4a04, 0x2404, 0xc0a5, 0x2022, - 0x6018, 0xa005, 0x0040, 0x3428, 0x8001, 0x601a, 0x00c0, 0x342b, - 0x6008, 0xc0a4, 0x600a, 0x6820, 0xd084, 0x00c0, 0x3437, 0x6800, - 0xa005, 0x00c0, 0x3434, 0x6002, 0x6006, 0x0078, 0x343b, 0x705c, - 0x2060, 0x6800, 0x6002, 0x2061, 0x4a00, 0x6887, 0x0103, 0x2d08, - 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040, 0x344a, 0x2d02, - 0x0078, 0x344b, 0x616e, 0x7200, 0xa286, 0x0030, 0x0040, 0x345b, - 0xa286, 0x0040, 0x00c0, 0x2946, 0x7003, 0x0002, 0x704c, 0x2068, - 0x68c4, 0x2060, 0x007c, 0x7003, 0x0002, 0x70bc, 0xa06d, 0x68bc, - 0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00, 0x704e, 0xad80, - 0x0009, 0x7046, 0x007c, 0xa282, 0x0004, 0x0048, 0x3471, 0x1078, - 0x28ec, 0x2200, 0x0079, 0x3474, 0x3478, 0x3489, 0x3496, 0x3489, - 0xa586, 0x1300, 0x0040, 0x3489, 0xa586, 0x8300, 0x00c0, 0x346f, - 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef, - 0x600a, 0x7000, 0xa086, 0x0005, 0x0040, 0x3493, 0x1078, 0x3eae, - 0x781b, 0x0075, 0x007c, 0x781b, 0x0076, 0x007c, 0x7890, 0x8007, - 0x8001, 0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, - 0x00ff, 0xa186, 0x0003, 0x0040, 0x34ab, 0xa186, 0x0000, 0x0040, - 0x34ab, 0x0078, 0x3e9d, 0x781b, 0x0076, 0x007c, 0x6820, 0xc095, - 0x6822, 0x82ff, 0x00c0, 0x34b8, 0x1078, 0x3eae, 0x0078, 0x34bf, - 0x8211, 0x0040, 0x34bd, 0x1078, 0x28ec, 0x1078, 0x3ebe, 0x781b, - 0x0075, 0x007c, 0x1078, 0x4131, 0x7830, 0xa084, 0x00c0, 0x00c0, - 0x34e5, 0x017e, 0x3208, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, - 0x007f, 0x0040, 0x34d7, 0xa18c, 0x0300, 0x0078, 0x34d9, 0xa18c, - 0x0400, 0x017f, 0x0040, 0x34e0, 0x0018, 0x34e5, 0x0078, 0x34e2, - 0x0028, 0x34e5, 0x791a, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, - 0xa684, 0x0060, 0x00c0, 0x34f2, 0x682f, 0x0000, 0x6833, 0x0000, - 0x0078, 0x3561, 0xd6dc, 0x00c0, 0x350a, 0x68b4, 0xd0dc, 0x00c0, - 0x350a, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x7048, 0xa005, 0x00c0, - 0x3507, 0x2200, 0xa105, 0x0040, 0x4326, 0x704b, 0x0015, 0x0078, - 0x4326, 0x007c, 0xd6ac, 0x0040, 0x3530, 0xd6f4, 0x0040, 0x3516, - 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x4326, 0x68b4, 0xa084, - 0x4000, 0xa635, 0xd6f4, 0x00c0, 0x3510, 0x7048, 0xa005, 0x00c0, - 0x3523, 0x704b, 0x0015, 0xd6dc, 0x00c0, 0x352c, 0x68b4, 0xd0dc, - 0x0040, 0x352c, 0x6ca8, 0x6da4, 0x6c2e, 0x6d32, 0x0078, 0x4326, - 0xd6f4, 0x0040, 0x3539, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, - 0x4326, 0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4, 0x00c0, 0x3533, - 0x7048, 0xa005, 0x00c0, 0x3546, 0x704b, 0x0015, 0x2408, 0x2510, - 0x2700, 0x80fb, 0x00c8, 0x354d, 0x8000, 0xa084, 0x003f, 0xa108, - 0xa291, 0x0000, 0x692e, 0x6a32, 0x2100, 0xa205, 0x00c0, 0x355a, - 0x0078, 0x4326, 0x7000, 0xa086, 0x0006, 0x0040, 0x3561, 0x0078, - 0x4326, 0x007c, 0x6008, 0xc0cd, 0xd3cc, 0x0040, 0x3568, 0xc08d, - 0x600a, 0x681b, 0x0006, 0x688f, 0x0000, 0x6893, 0x0000, 0x6a30, - 0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003, 0x6833, 0x0000, 0x6837, - 0x0020, 0x6897, 0x0000, 0x689b, 0x0020, 0x7000, 0x0079, 0x3580, - 0x2946, 0x3592, 0x358a, 0x3588, 0x3588, 0x3588, 0x3588, 0x3588, - 0x1078, 0x28ec, 0x6820, 0xd084, 0x00c0, 0x3592, 0x1078, 0x3bb5, - 0x0078, 0x3598, 0x705c, 0x2c50, 0x2060, 0x6800, 0x6002, 0x2a60, - 0x3208, 0xa18c, 0x0300, 0x0040, 0x35a1, 0x2021, 0x4a58, 0x0078, - 0x35a3, 0x2021, 0x4a98, 0x2404, 0xa005, 0x0040, 0x35aa, 0x2020, - 0x0078, 0x35a3, 0x2d22, 0x206b, 0x0000, 0x007c, 0x1078, 0x3bbc, - 0x1078, 0x3bd2, 0x6008, 0xc0cc, 0x600a, 0x682b, 0x0000, 0x789b, - 0x000e, 0x6f14, 0x6817, 0x0002, 0x3208, 0xa18c, 0x0300, 0x0040, - 0x35c5, 0x2009, 0x0000, 0x0078, 0x35c7, 0x2009, 0x0001, 0x1078, - 0x471a, 0xd6dc, 0x0040, 0x35cf, 0x691c, 0xc1ed, 0x691e, 0x6818, - 0xd0fc, 0x0040, 0x35de, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x35dc, - 0x681b, 0x001e, 0x0078, 0x35de, 0x681b, 0x0000, 0xb284, 0x0300, - 0x00c0, 0x35e6, 0x2021, 0x4a98, 0x0078, 0x35e8, 0x2021, 0x4a58, - 0x6800, 0x2022, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x1078, 0x202a, - 0x0078, 0x2946, 0x7cd8, 0x7ddc, 0x7fd0, 0x1078, 0x34e8, 0x682b, - 0x0000, 0x789b, 0x000e, 0x6f14, 0x1078, 0x4135, 0xa08c, 0x00ff, - 0x6916, 0x6818, 0xd0fc, 0x0040, 0x3607, 0x7048, 0x681a, 0xa68c, - 0xdf00, 0x691e, 0x7067, 0x0000, 0x0078, 0x2946, 0x7000, 0xa005, - 0x00c0, 0x3614, 0x0078, 0x2946, 0xa006, 0x1078, 0x4326, 0x6817, - 0x0000, 0x681b, 0x0014, 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, - 0x6820, 0xa084, 0x00ff, 0x6822, 0x7000, 0x0079, 0x3627, 0x2946, - 0x3634, 0x3631, 0x3636, 0x3636, 0x3636, 0x362f, 0x362f, 0x1078, - 0x28ec, 0x6008, 0xc0d4, 0x600a, 0x1078, 0x3bd2, 0x6008, 0xc0a4, - 0x600a, 0x0078, 0x3b85, 0x2300, 0x0079, 0x363e, 0x3641, 0x3643, - 0x369f, 0x1078, 0x28ec, 0xd6fc, 0x00c0, 0x3686, 0x7000, 0xa00d, - 0x0079, 0x364a, 0x2946, 0x3654, 0x3654, 0x3678, 0x3654, 0x3683, - 0x3652, 0x3652, 0x1078, 0x28ec, 0xa684, 0x0060, 0xa086, 0x0060, - 0x00c0, 0x3675, 0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a, 0x681c, 0xc0ac, - 0x681e, 0xa186, 0x0002, 0x0040, 0x3667, 0x1078, 0x4326, 0x1078, - 0x45f7, 0x781b, 0x0076, 0x71d4, 0xd1b4, 0x00c0, 0x2942, 0x70a4, - 0xa086, 0x0001, 0x00c0, 0x2989, 0x007c, 0xd6ec, 0x0040, 0x365c, - 0x6818, 0xd0fc, 0x0040, 0x3683, 0x681b, 0x0015, 0xd6f4, 0x0040, - 0x3683, 0x681b, 0x0007, 0x1078, 0x40d5, 0x007c, 0xc6fc, 0x7e5a, - 0x7adc, 0x79d8, 0x78d0, 0x801b, 0x00c8, 0x368f, 0x8000, 0xa084, - 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, - 0x6b94, 0x2200, 0xa303, 0x68ae, 0x781b, 0x0076, 0x007c, 0x1078, - 0x28ec, 0x2300, 0x0079, 0x36a4, 0x36a9, 0x36c5, 0x3719, 0x1078, - 0x28ec, 0x7000, 0x0079, 0x36ac, 0x36b4, 0x36b6, 0x36b6, 0x36b4, - 0x36b4, 0x36b4, 0x36b4, 0x36b4, 0x1078, 0x28ec, 0x1078, 0x45f7, - 0x681c, 0xc0b4, 0x681e, 0x70d4, 0xd0b4, 0x00c0, 0x2942, 0x70a4, - 0xa086, 0x0001, 0x00c0, 0x2989, 0x007c, 0xd6fc, 0x00c0, 0x3709, - 0x7000, 0xa00d, 0x0079, 0x36cc, 0x2946, 0x36dc, 0x36d6, 0x3700, - 0x36dc, 0x3706, 0x36d4, 0x36d4, 0x1078, 0x28ec, 0x6894, 0x78d6, - 0x78de, 0x6898, 0x78d2, 0x78da, 0xa684, 0x0060, 0xa086, 0x0060, - 0x00c0, 0x36fd, 0xa6b4, 0xbfbf, 0xc6ed, 0x7e5a, 0xa186, 0x0002, - 0x0040, 0x36ec, 0x1078, 0x4326, 0x1078, 0x45f7, 0x781b, 0x0076, - 0x681c, 0xc0b4, 0x681e, 0x71d4, 0xd1b4, 0x00c0, 0x2942, 0x70a4, - 0xa086, 0x0001, 0x00c0, 0x2989, 0x007c, 0xd6ec, 0x0040, 0x36e4, - 0x6818, 0xd0fc, 0x0040, 0x3706, 0x681b, 0x0007, 0x781b, 0x00f0, - 0x007c, 0xc6fc, 0x7e5a, 0x7adc, 0x79d8, 0x6b98, 0x2100, 0xa302, - 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x79d2, 0x781b, 0x0076, - 0x007c, 0xd6dc, 0x0040, 0x3722, 0x782b, 0x3009, 0x781b, 0x0076, - 0x0078, 0x2942, 0x7884, 0xc0ac, 0x7886, 0x78e4, 0xa084, 0x0008, - 0x00c0, 0x3735, 0xa484, 0x0200, 0x0040, 0x372f, 0xc6f5, 0xc6dd, - 0x7e5a, 0x781b, 0x0076, 0x0078, 0x2942, 0x6820, 0xc095, 0x6822, - 0x1078, 0x4062, 0xc6dd, 0x1078, 0x3eae, 0x781b, 0x0075, 0x0078, - 0x2942, 0x2300, 0x0079, 0x3744, 0x3747, 0x3749, 0x374b, 0x1078, - 0x28ec, 0x0078, 0x3ea7, 0xd6d4, 0x00c0, 0x3771, 0x79e4, 0xd1ac, - 0x0040, 0x3759, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3759, 0x782b, - 0x3009, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, - 0x79e4, 0xd1ac, 0x0040, 0x3769, 0x78ec, 0xa084, 0x0003, 0x00c0, - 0x376d, 0x2001, 0x0014, 0x0078, 0x3304, 0xa184, 0x0007, 0x0079, - 0x37a7, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060, 0x79a8, 0x81ff, - 0x0040, 0x37a5, 0x789b, 0x0010, 0x7ba8, 0xa384, 0x0001, 0x00c0, - 0x3798, 0x7ba8, 0x7ba8, 0xa386, 0x0001, 0x00c0, 0x378b, 0x2009, - 0xfff7, 0x0078, 0x3791, 0xa386, 0x0003, 0x00c0, 0x3798, 0x2009, - 0xffef, 0x0c7e, 0x7058, 0x2060, 0x6004, 0xa104, 0x6006, 0x0c7f, - 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x782b, - 0x3009, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, 0x40c9, 0x2fae, - 0x2fb8, 0x37b1, 0x37b7, 0x37af, 0x37af, 0x40c9, 0x40c9, 0x1078, - 0x28ec, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, 0x40cf, 0x6920, - 0xa18c, 0xfcff, 0x6922, 0x0078, 0x40c9, 0x79e4, 0xa184, 0x0030, - 0x0040, 0x37c7, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x37f1, 0x7000, - 0xa086, 0x0004, 0x00c0, 0x37e1, 0x7064, 0xa086, 0x0002, 0x00c0, - 0x37d7, 0x2011, 0x0002, 0x2019, 0x0000, 0x0078, 0x2e43, 0x7064, - 0xa086, 0x0006, 0x0040, 0x37d1, 0x7064, 0xa086, 0x0004, 0x0040, - 0x37d1, 0x7000, 0xa086, 0x0000, 0x0040, 0x2942, 0x6820, 0xd0ac, - 0x00c0, 0x37ed, 0x6818, 0xc0fd, 0x681a, 0x2001, 0x0014, 0x0078, - 0x3304, 0xa184, 0x0007, 0x0079, 0x37f5, 0x40c9, 0x40c9, 0x37fd, - 0x40c9, 0x4111, 0x4111, 0x40c9, 0x40c9, 0xd6bc, 0x0040, 0x383f, - 0x7184, 0x81ff, 0x0040, 0x383f, 0xa182, 0x000d, 0x00d0, 0x380c, - 0x7087, 0x0000, 0x0078, 0x3811, 0xa182, 0x000c, 0x7086, 0x2009, - 0x000c, 0x789b, 0x0061, 0x79aa, 0x157e, 0x137e, 0x147e, 0x7088, - 0x8114, 0xa210, 0x728a, 0xa080, 0x000b, 0xad00, 0x2098, 0xb284, - 0x0300, 0x0040, 0x3833, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, - 0x007f, 0x0040, 0x382f, 0x20a1, 0x012b, 0x0078, 0x3835, 0x20a1, - 0x022b, 0x0078, 0x3835, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8108, - 0x81ac, 0x53a6, 0x147f, 0x137f, 0x157f, 0x0078, 0x40cf, 0xd6d4, - 0x00c0, 0x3893, 0x6820, 0xd084, 0x0040, 0x40cf, 0xa68c, 0x0060, - 0xa684, 0x0060, 0x0040, 0x3851, 0xa086, 0x0060, 0x00c0, 0x3851, - 0xc1f5, 0xc194, 0x795a, 0x69b6, 0x789b, 0x0060, 0x78ab, 0x0000, - 0x789b, 0x0061, 0x6818, 0xc0fd, 0x681a, 0x78aa, 0x8008, 0x810c, - 0x0040, 0x3beb, 0xa18c, 0x00f8, 0x00c0, 0x3beb, 0x157e, 0x137e, - 0x147e, 0x017e, 0x3208, 0xa18c, 0x0300, 0x0040, 0x387f, 0x007e, - 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x387b, 0x20a1, - 0x012b, 0x0078, 0x3881, 0x20a1, 0x022b, 0x0078, 0x3881, 0x20a1, - 0x012b, 0x017f, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, - 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x6814, 0xc0fc, 0x8007, - 0x7882, 0x0078, 0x40cf, 0x6818, 0xd0fc, 0x0040, 0x3899, 0x681b, - 0x0008, 0x6820, 0xc0ad, 0x6822, 0x1078, 0x3eb6, 0x781b, 0x00e1, - 0x007c, 0x2300, 0x0079, 0x38a4, 0x38a9, 0x397b, 0x38a7, 0x1078, - 0x28ec, 0x7cd8, 0x7ddc, 0x7fd0, 0x82ff, 0x00c0, 0x38d1, 0x7200, - 0xa286, 0x0003, 0x0040, 0x32d2, 0x71d4, 0xd1b4, 0x0078, 0x38d4, - 0x0040, 0x38d4, 0x0d7e, 0x783b, 0x8800, 0x781b, 0x004c, 0x70bc, - 0xa06d, 0x68b4, 0xc0a5, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, - 0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x0d7f, 0x0078, - 0x38d8, 0x7200, 0x0078, 0x38d8, 0x783b, 0x1800, 0x781b, 0x004a, - 0xa284, 0x000f, 0x0079, 0x38dc, 0x3966, 0x391a, 0x38e6, 0x3300, - 0x38e4, 0x3966, 0x38e4, 0x38e4, 0x1078, 0x28ec, 0x681c, 0xd0ec, - 0x0040, 0x38ed, 0x6008, 0xc08d, 0x600a, 0x6920, 0xc185, 0x6922, - 0x6800, 0x6006, 0xa005, 0x00c0, 0x38f6, 0x6002, 0x6008, 0xc0d4, - 0x600a, 0x681c, 0xa084, 0x000e, 0x00c0, 0x390a, 0xb284, 0x0300, - 0x0040, 0x3906, 0x2009, 0x90c0, 0x0078, 0x390f, 0x2009, 0x91d0, - 0x0078, 0x390f, 0x7030, 0x68ba, 0x7140, 0x70cc, 0xa108, 0x2104, - 0x6802, 0x2d0a, 0x715e, 0xd6dc, 0x00c0, 0x391a, 0xc6fc, 0x6eb6, - 0x0078, 0x3966, 0x6eb6, 0xa684, 0x0060, 0x0040, 0x3966, 0xd6dc, - 0x00c0, 0x392d, 0xa684, 0x7fff, 0x68b6, 0x6894, 0x68a6, 0x6898, - 0x68aa, 0x1078, 0x4326, 0x0078, 0x3966, 0xd6ac, 0x0040, 0x3939, - 0xa006, 0x1078, 0x4326, 0x2408, 0x2510, 0x69aa, 0x6aa6, 0x0078, - 0x3949, 0x2408, 0x2510, 0x2700, 0x801b, 0x00c8, 0x3940, 0x8000, - 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x69aa, 0x6aa6, 0x1078, - 0x4326, 0xd6fc, 0x0040, 0x3966, 0xa684, 0x7fff, 0x68b6, 0x2510, - 0x2408, 0xd6ac, 0x00c0, 0x395e, 0x2700, 0x801b, 0x00c8, 0x3959, - 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, - 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x7000, 0xa086, - 0x0030, 0x00c0, 0x2946, 0x7003, 0x0002, 0x70bc, 0xa06d, 0x68bc, - 0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00, 0x704e, 0xad80, - 0x0009, 0x7046, 0x007c, 0xa586, 0x8800, 0x00c0, 0x3988, 0x7003, + 0x1078, 0x35ff, 0x017f, 0x81ff, 0x0040, 0x351a, 0xa684, 0xdf00, + 0x681e, 0x682b, 0x0000, 0x6f14, 0xa186, 0x0002, 0x00c0, 0x351b, + 0x6818, 0xa086, 0x0014, 0x00c0, 0x34e4, 0x2008, 0xd6e4, 0x0040, + 0x34e4, 0x7868, 0xa08c, 0x00ff, 0x1078, 0x2aba, 0x1078, 0x2adb, + 0x6820, 0xd0dc, 0x00c0, 0x351b, 0x8717, 0xa294, 0x000f, 0x8213, + 0x8213, 0x8213, 0xb284, 0x0300, 0x0040, 0x34fa, 0xa290, 0x52c0, + 0x0078, 0x34fc, 0xa290, 0x5340, 0xa290, 0x0000, 0x221c, 0xd3c4, + 0x00c0, 0x3504, 0x0078, 0x350a, 0x8210, 0x2204, 0xa085, 0x0018, + 0x2012, 0x8211, 0xd3d4, 0x0040, 0x3515, 0x68a0, 0xd0c4, 0x00c0, + 0x3515, 0x1078, 0x3679, 0x0078, 0x29c5, 0x6008, 0xc08d, 0x600a, + 0x0078, 0x351b, 0x692a, 0x6916, 0x6818, 0xd0fc, 0x0040, 0x3522, + 0x7048, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x6410, 0x84ff, 0x0040, + 0x3537, 0x2009, 0x4e02, 0x2104, 0x8001, 0x200a, 0x8421, 0x6412, + 0x00c0, 0x3537, 0x2021, 0x4e04, 0x2404, 0xc0a5, 0x2022, 0x6018, + 0xa005, 0x0040, 0x353f, 0x8001, 0x601a, 0x00c0, 0x3542, 0x6008, + 0xc0a4, 0x600a, 0x6820, 0xd084, 0x00c0, 0x354e, 0x6800, 0xa005, + 0x00c0, 0x354b, 0x6002, 0x6006, 0x0078, 0x3552, 0x705c, 0x2060, + 0x6800, 0x6002, 0x2061, 0x4e00, 0x6887, 0x0103, 0x2d08, 0x206b, + 0x0000, 0x6068, 0xa005, 0x616a, 0x0040, 0x3561, 0x2d02, 0x0078, + 0x3562, 0x616e, 0x7200, 0xa286, 0x0030, 0x0040, 0x3572, 0xa286, + 0x0040, 0x00c0, 0x29c5, 0x7003, 0x0002, 0x704c, 0x2068, 0x68c4, + 0x2060, 0x007c, 0x7003, 0x0002, 0x70bc, 0xa06d, 0x68bc, 0x7042, + 0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00, 0x704e, 0xad80, 0x0009, + 0x7046, 0x007c, 0xa282, 0x0004, 0x0048, 0x3588, 0x1078, 0x296b, + 0x2200, 0x0079, 0x358b, 0x358f, 0x35a0, 0x35ad, 0x35a0, 0xa586, + 0x1300, 0x0040, 0x35a0, 0xa586, 0x8300, 0x00c0, 0x3586, 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef, 0x600a, - 0x0078, 0x3ea7, 0x7047, 0x0000, 0xa282, 0x0006, 0x0050, 0x3992, - 0x1078, 0x28ec, 0x2300, 0x0079, 0x3995, 0x3998, 0x39cf, 0x3a01, - 0x2200, 0x0079, 0x399b, 0x39a1, 0x3ea7, 0x39a3, 0x39a1, 0x3a38, - 0x3a9b, 0x1078, 0x28ec, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, - 0x39ad, 0x2001, 0x91e0, 0x0078, 0x39af, 0x2001, 0x9212, 0x2068, - 0x704e, 0x157e, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x00f0, - 0x39b4, 0x157f, 0xb284, 0x0300, 0x0040, 0x39c2, 0x6817, 0x0000, - 0x0078, 0x39c4, 0x6817, 0x8000, 0xad80, 0x0009, 0x7046, 0x68b7, - 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x0078, 0x3e9d, 0x7000, - 0xa086, 0x0002, 0x00c0, 0x39e0, 0x1078, 0x3bd2, 0x0078, 0x39da, - 0x1078, 0x4326, 0x6008, 0xa084, 0xfbef, 0x600a, 0x0078, 0x39e5, - 0x7000, 0xa086, 0x0003, 0x0040, 0x39d8, 0x7003, 0x0005, 0xb284, - 0x0300, 0x0040, 0x39ef, 0x2001, 0x91e0, 0x0078, 0x39f1, 0x2001, - 0x9212, 0x2068, 0x704e, 0xad80, 0x0009, 0x7046, 0x2200, 0x0079, - 0x39f9, 0x3ea7, 0x39ff, 0x39ff, 0x3a38, 0x39ff, 0x3ea7, 0x1078, - 0x28ec, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3a12, 0x1078, 0x3bd2, - 0x0078, 0x3a0c, 0x1078, 0x4326, 0x6008, 0xa084, 0xfbef, 0x600a, - 0x0078, 0x3a17, 0x7000, 0xa086, 0x0003, 0x0040, 0x3a0a, 0x7003, - 0x0005, 0xb284, 0x0300, 0x0040, 0x3a21, 0x2001, 0x91e0, 0x0078, - 0x3a23, 0x2001, 0x9212, 0x2068, 0x704e, 0xad80, 0x0009, 0x7046, - 0x2200, 0x0079, 0x3a2b, 0x3a33, 0x3a31, 0x3a31, 0x3a33, 0x3a31, - 0x3a33, 0x1078, 0x28ec, 0x1078, 0x3ebe, 0x781b, 0x0075, 0x007c, - 0x7000, 0xa086, 0x0002, 0x00c0, 0x3a4a, 0x70d4, 0xc0b5, 0x70d6, - 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078, 0x3a4f, 0x1078, 0x4326, - 0x0078, 0x3a4f, 0x7000, 0xa086, 0x0003, 0x0040, 0x3a46, 0x7003, - 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, - 0x001f, 0xa215, 0x2069, 0x90c0, 0xb284, 0x0300, 0x00c0, 0x3a63, - 0xc2fd, 0x2069, 0x91d0, 0x2d04, 0x2d08, 0x715e, 0xa06d, 0x0040, - 0x3a70, 0x6814, 0xa206, 0x0040, 0x3a90, 0x6800, 0x0078, 0x3a64, - 0x7003, 0x0005, 0xd2fc, 0x00c0, 0x3a79, 0x2001, 0x91e0, 0x0078, - 0x3a7b, 0x2001, 0x9212, 0x2068, 0x704e, 0x157e, 0x20a9, 0x0032, - 0x2003, 0x0000, 0x8000, 0x00f0, 0x3a80, 0x157f, 0xad80, 0x0009, - 0x7046, 0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, - 0x6eb4, 0x7e5a, 0x6820, 0xa084, 0x0c00, 0x0040, 0x3b10, 0x1078, - 0x3eb6, 0x0078, 0x3b10, 0x7200, 0xa286, 0x0002, 0x00c0, 0x3aad, - 0x70d4, 0xc0b5, 0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078, - 0x3ab1, 0x1078, 0x4326, 0x0078, 0x3ab1, 0xa286, 0x0003, 0x0040, - 0x3aa9, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, - 0x7ca8, 0xa484, 0x001f, 0xa215, 0xb284, 0x0300, 0x00c0, 0x3ac1, - 0xc2fd, 0x79a8, 0x79a8, 0xa18c, 0x00ff, 0x70cc, 0xa168, 0x2d04, - 0x2d08, 0x715e, 0xa06d, 0x0040, 0x3ad4, 0x6814, 0xa206, 0x0040, - 0x3afd, 0x6800, 0x0078, 0x3ac8, 0x7003, 0x0005, 0xb284, 0x0300, - 0x0040, 0x3ade, 0x2001, 0x91e0, 0x0078, 0x3ae0, 0x2001, 0x9212, - 0x2068, 0x704e, 0x157e, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, - 0x00f0, 0x3ae5, 0x157f, 0xb284, 0x0300, 0x0040, 0x3af2, 0xc2fc, - 0x0078, 0x3af3, 0xc2fd, 0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, - 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x6820, 0xa084, - 0x0c00, 0x0040, 0x3b10, 0xd0dc, 0x0040, 0x3b0a, 0x1078, 0x3eba, - 0x0078, 0x3b10, 0x1078, 0x3eb6, 0x707f, 0x0000, 0x0078, 0x3b10, - 0xa6ac, 0x0060, 0x0040, 0x3b4e, 0x6b98, 0x6c94, 0x69ac, 0x68b0, - 0xa105, 0x00c0, 0x3b33, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa6b4, - 0xb7ff, 0xa586, 0x0060, 0x0040, 0x3b4e, 0xc6ed, 0x7e5a, 0x2009, - 0x0076, 0xd69c, 0x0040, 0x3b2e, 0x2009, 0x0075, 0x791a, 0x1078, - 0x45f7, 0x0078, 0x3b57, 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, - 0xa305, 0x0040, 0x3b4e, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0, - 0xc6f4, 0x7e5a, 0x2011, 0x0076, 0xd69c, 0x0040, 0x3b49, 0x2011, - 0x0075, 0x7a1a, 0x1078, 0x462d, 0x0078, 0x3b57, 0x7e5a, 0x2009, - 0x0076, 0xd69c, 0x0040, 0x3b56, 0x2009, 0x0075, 0x791a, 0x68c0, - 0x705a, 0x2d00, 0x704e, 0x68c4, 0x2060, 0x71d4, 0xd1b4, 0x00c0, - 0x2942, 0x2300, 0xa405, 0x0040, 0x2942, 0x70a4, 0xa086, 0x0001, - 0x00c0, 0x2989, 0x007c, 0x6020, 0xa005, 0x0040, 0x3b79, 0x8001, - 0x6022, 0x6008, 0xa085, 0x0008, 0x600a, 0x700f, 0x0100, 0x702c, - 0x6026, 0x007c, 0xa006, 0x1078, 0x4326, 0x6817, 0x0000, 0x681b, + 0x7000, 0xa086, 0x0005, 0x0040, 0x35aa, 0x1078, 0x40c8, 0x781b, + 0x0078, 0x007c, 0x781b, 0x0079, 0x007c, 0x7890, 0x8007, 0x8001, + 0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff, + 0xa186, 0x0003, 0x0040, 0x35c2, 0xa186, 0x0000, 0x0040, 0x35c2, + 0x0078, 0x40b7, 0x781b, 0x0079, 0x007c, 0x6820, 0xc095, 0x6822, + 0x82ff, 0x00c0, 0x35cf, 0x1078, 0x40c8, 0x0078, 0x35d6, 0x8211, + 0x0040, 0x35d4, 0x1078, 0x296b, 0x1078, 0x40db, 0x781b, 0x0078, + 0x007c, 0x1078, 0x4383, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x35fc, + 0x017e, 0x3208, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, + 0x0040, 0x35ee, 0xa18c, 0x0300, 0x0078, 0x35f0, 0xa18c, 0x0400, + 0x017f, 0x0040, 0x35f7, 0x0018, 0x35fc, 0x0078, 0x35f9, 0x0028, + 0x35fc, 0x791a, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0xa684, + 0x0060, 0x00c0, 0x3609, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, + 0x3678, 0xd6dc, 0x00c0, 0x3621, 0x68b4, 0xd0dc, 0x00c0, 0x3621, + 0x6998, 0x6a94, 0x692e, 0x6a32, 0x7048, 0xa005, 0x00c0, 0x361e, + 0x2200, 0xa105, 0x0040, 0x4586, 0x704b, 0x0015, 0x0078, 0x4586, + 0x007c, 0xd6ac, 0x0040, 0x3647, 0xd6f4, 0x0040, 0x362d, 0x682f, + 0x0000, 0x6833, 0x0000, 0x0078, 0x4586, 0x68b4, 0xa084, 0x4000, + 0xa635, 0xd6f4, 0x00c0, 0x3627, 0x7048, 0xa005, 0x00c0, 0x363a, + 0x704b, 0x0015, 0xd6dc, 0x00c0, 0x3643, 0x68b4, 0xd0dc, 0x0040, + 0x3643, 0x6ca8, 0x6da4, 0x6c2e, 0x6d32, 0x0078, 0x4586, 0xd6f4, + 0x0040, 0x3650, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x4586, + 0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4, 0x00c0, 0x364a, 0x7048, + 0xa005, 0x00c0, 0x365d, 0x704b, 0x0015, 0x2408, 0x2510, 0x2700, + 0x80fb, 0x00c8, 0x3664, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, + 0x0000, 0x692e, 0x6a32, 0x2100, 0xa205, 0x00c0, 0x3671, 0x0078, + 0x4586, 0x7000, 0xa086, 0x0006, 0x0040, 0x3678, 0x0078, 0x4586, + 0x007c, 0x6946, 0x6008, 0xc0cd, 0xd3cc, 0x0040, 0x3680, 0xc08d, + 0x600a, 0x6818, 0x683a, 0x681b, 0x0006, 0x688f, 0x0000, 0x6893, + 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003, 0x6833, + 0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b, 0x0020, 0x7000, + 0x0079, 0x369a, 0x29c5, 0x36ac, 0x36a4, 0x36a2, 0x36a2, 0x36a2, + 0x36a2, 0x36a2, 0x1078, 0x296b, 0x6820, 0xd084, 0x00c0, 0x36ac, + 0x1078, 0x3dd0, 0x0078, 0x36b2, 0x705c, 0x2c50, 0x2060, 0x6800, + 0x6002, 0x2a60, 0x3208, 0xa18c, 0x0300, 0x0040, 0x36bb, 0x2021, + 0x4e58, 0x0078, 0x36bd, 0x2021, 0x4e98, 0x2404, 0xa005, 0x0040, + 0x36c4, 0x2020, 0x0078, 0x36bd, 0x2d22, 0x206b, 0x0000, 0x007c, + 0x1078, 0x3dd7, 0x1078, 0x3ded, 0x6008, 0xc0cc, 0x600a, 0x682b, + 0x0000, 0x789b, 0x000e, 0x6f14, 0x6938, 0x691a, 0x6944, 0x6916, + 0x3208, 0xa18c, 0x0300, 0x0040, 0x36e1, 0x2009, 0x0000, 0x0078, + 0x36e3, 0x2009, 0x0001, 0x1078, 0x49f8, 0xd6dc, 0x0040, 0x36eb, + 0x691c, 0xc1ed, 0x691e, 0x6818, 0xd0fc, 0x0040, 0x36fa, 0x7868, + 0xa08c, 0x00ff, 0x0040, 0x36f8, 0x681b, 0x001e, 0x0078, 0x36fa, + 0x681b, 0x0000, 0xb284, 0x0300, 0x00c0, 0x3702, 0x2021, 0x4e98, + 0x0078, 0x3704, 0x2021, 0x4e58, 0x6800, 0x2022, 0x6a3c, 0x6940, + 0x6a32, 0x692e, 0x68c0, 0x2060, 0x6000, 0xd0a4, 0x0040, 0x3744, + 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x0d7e, 0x0f7e, + 0x157e, 0x147e, 0x2079, 0x4e00, 0x1078, 0x1dff, 0x147f, 0x157f, + 0x0f7f, 0x70cc, 0x2010, 0x2009, 0x0101, 0x027e, 0x2204, 0xa06d, + 0x0040, 0x3734, 0x6814, 0xa706, 0x0040, 0x3731, 0x6800, 0x0078, + 0x3727, 0x6820, 0xc0d5, 0x6822, 0x027f, 0x8210, 0x8109, 0x00c0, + 0x3725, 0x0d7f, 0x7067, 0x0003, 0x707f, 0x0000, 0x7776, 0x7083, + 0x000f, 0x71d4, 0xc1dc, 0x71d6, 0x6818, 0xa086, 0x0002, 0x00c0, + 0x3750, 0x6817, 0x0000, 0x682b, 0x0000, 0x681c, 0xc0ec, 0x681e, + 0x1078, 0x202c, 0x0078, 0x29c5, 0x7cd8, 0x7ddc, 0x7fd0, 0x1078, + 0x35ff, 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14, 0x1078, 0x4387, + 0xa08c, 0x00ff, 0x6916, 0x6818, 0xd0fc, 0x0040, 0x3769, 0x7048, + 0x681a, 0xa68c, 0xdf00, 0x691e, 0x7067, 0x0000, 0x0078, 0x29c5, + 0x7000, 0xa005, 0x00c0, 0x3776, 0x0078, 0x29c5, 0xa006, 0x1078, + 0x4586, 0x6920, 0xd1ac, 0x00c0, 0x377f, 0x681b, 0x0014, 0xa68c, + 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff, 0x6822, + 0x7000, 0x0079, 0x378b, 0x29c5, 0x3795, 0x3795, 0x3798, 0x3798, + 0x3798, 0x3793, 0x3793, 0x1078, 0x296b, 0x6818, 0x0078, 0x33fa, + 0x6008, 0xc0a4, 0x600a, 0x6817, 0x0000, 0x0078, 0x3d95, 0x2300, + 0x0079, 0x37a2, 0x37a5, 0x37a7, 0x3817, 0x1078, 0x296b, 0xd6fc, + 0x00c0, 0x37fe, 0x7000, 0xa00d, 0x0079, 0x37ae, 0x29c5, 0x37b8, + 0x37b8, 0x37e8, 0x37b8, 0x37fb, 0x37b6, 0x37b6, 0x1078, 0x296b, + 0xa684, 0x0060, 0x0040, 0x37e8, 0xa086, 0x0060, 0x00c0, 0x37e5, + 0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a, 0x6eb6, 0x681c, 0xc0ac, 0x681e, + 0xa186, 0x0002, 0x0040, 0x37d7, 0x1078, 0x4586, 0x69ac, 0x68b0, + 0xa115, 0x0040, 0x37d7, 0x1078, 0x48f5, 0x0078, 0x37d9, 0x1078, + 0x48bd, 0x781b, 0x0079, 0x71d4, 0xd1b4, 0x00c0, 0x29c1, 0x70a4, + 0xa086, 0x0001, 0x00c0, 0x2a0b, 0x007c, 0xd6ec, 0x0040, 0x37c2, + 0x6818, 0xd0fc, 0x0040, 0x37fb, 0xd6f4, 0x00c0, 0x37f5, 0x681b, + 0x0015, 0x781b, 0x0079, 0x0078, 0x29c1, 0x681b, 0x0007, 0x682f, + 0x0000, 0x6833, 0x0000, 0x1078, 0x4319, 0x007c, 0xc6fc, 0x7e5a, + 0x7adc, 0x79d8, 0x78d0, 0x801b, 0x00c8, 0x3807, 0x8000, 0xa084, + 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, + 0x6b94, 0x2200, 0xa303, 0x68ae, 0x781b, 0x0079, 0x007c, 0x1078, + 0x296b, 0x2300, 0x0079, 0x381c, 0x3821, 0x3846, 0x38a6, 0x1078, + 0x296b, 0x7000, 0x0079, 0x3824, 0x382c, 0x382e, 0x3837, 0x382c, + 0x382c, 0x382c, 0x382c, 0x382c, 0x1078, 0x296b, 0x69ac, 0x68b0, + 0xa115, 0x0040, 0x3837, 0x1078, 0x48f5, 0x0078, 0x3839, 0x1078, + 0x48bd, 0x681c, 0xc0b4, 0x681e, 0x70d4, 0xd0b4, 0x00c0, 0x29c1, + 0x70a4, 0xa086, 0x0001, 0x00c0, 0x2a0b, 0x007c, 0xd6fc, 0x00c0, + 0x3896, 0x7000, 0xa00d, 0x0079, 0x384d, 0x29c5, 0x385d, 0x3857, + 0x388d, 0x385d, 0x3893, 0x3855, 0x3855, 0x1078, 0x296b, 0x6894, + 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xa684, 0x0060, 0x0040, + 0x388d, 0xa086, 0x0060, 0x00c0, 0x388a, 0xa6b4, 0xbfbf, 0xc6ed, + 0x7e5a, 0x6eb6, 0xa186, 0x0002, 0x0040, 0x3879, 0x1078, 0x4586, + 0x69ac, 0x68b0, 0xa115, 0x0040, 0x3879, 0x1078, 0x48f5, 0x0078, + 0x387b, 0x1078, 0x48bd, 0x781b, 0x0079, 0x681c, 0xc0b4, 0x681e, + 0x71d4, 0xd1b4, 0x00c0, 0x29c1, 0x70a4, 0xa086, 0x0001, 0x00c0, + 0x2a0b, 0x007c, 0xd6ec, 0x0040, 0x3867, 0x6818, 0xd0fc, 0x0040, + 0x3893, 0x681b, 0x0007, 0x781b, 0x00f9, 0x007c, 0xc6fc, 0x7e5a, + 0x7adc, 0x79d8, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, + 0xa303, 0x68ae, 0x79d2, 0x781b, 0x0079, 0x007c, 0xd6dc, 0x0040, + 0x38af, 0x782b, 0x3009, 0x781b, 0x0079, 0x0078, 0x29c1, 0x7884, + 0xc0ac, 0x7886, 0x78e4, 0xa084, 0x0008, 0x00c0, 0x38c2, 0xa484, + 0x0200, 0x0040, 0x38bc, 0xc6f5, 0xc6dd, 0x7e5a, 0x781b, 0x0079, + 0x0078, 0x29c1, 0x6820, 0xc095, 0x6822, 0x1078, 0x4292, 0xc6dd, + 0x1078, 0x40c8, 0x781b, 0x0078, 0x0078, 0x29c1, 0x2300, 0x0079, + 0x38d1, 0x38d4, 0x38d6, 0x38d8, 0x1078, 0x296b, 0x0078, 0x40c1, + 0xd6d4, 0x00c0, 0x3913, 0x79e4, 0xd1ac, 0x0040, 0x38e6, 0x78ec, + 0xa084, 0x0003, 0x0040, 0x38e6, 0x782b, 0x3009, 0x789b, 0x0060, + 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x79e4, 0xd1ac, 0x0040, + 0x38f6, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x390f, 0x2001, 0x4e04, + 0x2004, 0xd0e4, 0x00c0, 0x390b, 0x6820, 0xd0c4, 0x0040, 0x390b, + 0x0c7e, 0x7058, 0x2060, 0x6004, 0xc09d, 0x6006, 0x6008, 0xa084, + 0x00ff, 0x600a, 0x0c7f, 0x2001, 0x0014, 0x0078, 0x33fa, 0xa184, + 0x0007, 0x0079, 0x3949, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060, + 0x79a8, 0x81ff, 0x0040, 0x3947, 0x789b, 0x0010, 0x7ba8, 0xa384, + 0x0001, 0x00c0, 0x393a, 0x7ba8, 0x7ba8, 0xa386, 0x0001, 0x00c0, + 0x392d, 0x2009, 0xfff7, 0x0078, 0x3933, 0xa386, 0x0003, 0x00c0, + 0x393a, 0x2009, 0xffef, 0x0c7e, 0x7058, 0x2060, 0x6004, 0xa104, + 0x6006, 0x0c7f, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, + 0x785a, 0x782b, 0x3009, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, + 0x430d, 0x3090, 0x309a, 0x3953, 0x3959, 0x3951, 0x3951, 0x430d, + 0x430d, 0x1078, 0x296b, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, + 0x4313, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, 0x430d, 0x79e4, + 0xa184, 0x0030, 0x0040, 0x3969, 0x78ec, 0xa084, 0x0003, 0x00c0, + 0x399d, 0x7000, 0xa086, 0x0004, 0x00c0, 0x3983, 0x7064, 0xa086, + 0x0002, 0x00c0, 0x3979, 0x2011, 0x0002, 0x2019, 0x0000, 0x0078, + 0x2f1c, 0x7064, 0xa086, 0x0006, 0x0040, 0x3973, 0x7064, 0xa086, + 0x0004, 0x0040, 0x3973, 0x7000, 0xa086, 0x0000, 0x0040, 0x29c1, + 0x6920, 0xa184, 0x0420, 0x0040, 0x3992, 0xc1d4, 0x6922, 0x6818, + 0x0078, 0x33fa, 0x6818, 0xa08e, 0x0002, 0x0040, 0x399b, 0xc0fd, + 0x681a, 0x2001, 0x0014, 0x0078, 0x33fa, 0xa184, 0x0007, 0x0079, + 0x39a1, 0x430d, 0x430d, 0x39a9, 0x430d, 0x4355, 0x4355, 0x430d, + 0x430d, 0xd6bc, 0x0040, 0x39eb, 0x7184, 0x81ff, 0x0040, 0x39eb, + 0xa182, 0x000d, 0x00d0, 0x39b8, 0x7087, 0x0000, 0x0078, 0x39bd, + 0xa182, 0x000c, 0x7086, 0x2009, 0x000c, 0x789b, 0x0061, 0x79aa, + 0x157e, 0x137e, 0x147e, 0x7088, 0x8114, 0xa210, 0x728a, 0xa080, + 0x000b, 0xad00, 0x2098, 0xb284, 0x0300, 0x0040, 0x39df, 0x007e, + 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x39db, 0x20a1, + 0x012b, 0x0078, 0x39e1, 0x20a1, 0x022b, 0x0078, 0x39e1, 0x20a1, + 0x012b, 0x789b, 0x0000, 0x8108, 0x81ac, 0x53a6, 0x147f, 0x137f, + 0x157f, 0x0078, 0x4313, 0xd6d4, 0x00c0, 0x3a3f, 0x6820, 0xd084, + 0x0040, 0x4313, 0xa68c, 0x0060, 0xa684, 0x0060, 0x0040, 0x39fd, + 0xa086, 0x0060, 0x00c0, 0x39fd, 0xc1f5, 0xc194, 0x795a, 0x69b6, + 0x789b, 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061, 0x6818, 0xc0fd, + 0x681a, 0x78aa, 0x8008, 0x810c, 0x0040, 0x3e06, 0xa18c, 0x00f8, + 0x00c0, 0x3e06, 0x157e, 0x137e, 0x147e, 0x017e, 0x3208, 0xa18c, + 0x0300, 0x0040, 0x3a2b, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, + 0x007f, 0x0040, 0x3a27, 0x20a1, 0x012b, 0x0078, 0x3a2d, 0x20a1, + 0x022b, 0x0078, 0x3a2d, 0x20a1, 0x012b, 0x017f, 0x789b, 0x0000, + 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, + 0x157f, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x0078, 0x4313, 0x6818, + 0xd0fc, 0x0040, 0x3a45, 0x681b, 0x0008, 0x6820, 0xc0ad, 0x6822, + 0x1078, 0x40d0, 0x781b, 0x00ea, 0x007c, 0x2300, 0x0079, 0x3a50, + 0x3a55, 0x3b2d, 0x3a53, 0x1078, 0x296b, 0x7cd8, 0x7ddc, 0x7fd0, + 0x82ff, 0x00c0, 0x3a7e, 0x7200, 0xa286, 0x0003, 0x0040, 0x33c7, + 0x71d4, 0xd1bc, 0x00c0, 0x3a81, 0xd1b4, 0x0040, 0x3a81, 0x0d7e, + 0x783b, 0x8800, 0x781b, 0x004c, 0x70bc, 0xa06d, 0x68b4, 0xc0a5, + 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, + 0x71d6, 0x7003, 0x0030, 0x0d7f, 0x0078, 0x3a85, 0x7200, 0x0078, + 0x3a85, 0x783b, 0x1800, 0x781b, 0x004a, 0xa284, 0x000f, 0x0079, + 0x3a89, 0x3b18, 0x3ac7, 0x3a93, 0x33f6, 0x3a91, 0x3b18, 0x3a91, + 0x3a91, 0x1078, 0x296b, 0x681c, 0xd0ec, 0x0040, 0x3a9a, 0x6008, + 0xc08d, 0x600a, 0x6920, 0xc185, 0x6922, 0x6800, 0x6006, 0xa005, + 0x00c0, 0x3aa3, 0x6002, 0x6008, 0xc0d4, 0x600a, 0x681c, 0xa084, + 0x000e, 0x00c0, 0x3ab7, 0xb284, 0x0300, 0x0040, 0x3ab3, 0x2009, + 0x94c0, 0x0078, 0x3abc, 0x2009, 0x95d0, 0x0078, 0x3abc, 0x7030, + 0x68ba, 0x7140, 0x70cc, 0xa108, 0x2104, 0x6802, 0x2d0a, 0x715e, + 0xd6dc, 0x00c0, 0x3ac7, 0xc6fc, 0x6eb6, 0x0078, 0x3b18, 0x6eb6, + 0xa684, 0x0060, 0x00c0, 0x3ad1, 0xa684, 0x7fff, 0x68b6, 0x0078, + 0x3b18, 0xd6dc, 0x00c0, 0x3adf, 0xa684, 0x7fff, 0x68b6, 0x6894, + 0x68a6, 0x6898, 0x68aa, 0x1078, 0x4586, 0x0078, 0x3b18, 0xd6ac, + 0x0040, 0x3aeb, 0xa006, 0x1078, 0x4586, 0x2408, 0x2510, 0x69aa, + 0x6aa6, 0x0078, 0x3afb, 0x2408, 0x2510, 0x2700, 0x801b, 0x00c8, + 0x3af2, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x69aa, + 0x6aa6, 0x1078, 0x4586, 0xd6fc, 0x0040, 0x3b18, 0xa684, 0x7fff, + 0x68b6, 0x2510, 0x2408, 0xd6ac, 0x00c0, 0x3b10, 0x2700, 0x801b, + 0x00c8, 0x3b0b, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, + 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, + 0x7000, 0xa086, 0x0030, 0x00c0, 0x29c5, 0x7003, 0x0002, 0x70bc, + 0xa06d, 0x68bc, 0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00, + 0x704e, 0xad80, 0x0009, 0x7046, 0x007c, 0xa586, 0x8800, 0x00c0, + 0x3b3a, 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, + 0xfbef, 0x600a, 0x0078, 0x40c1, 0x7047, 0x0000, 0xa282, 0x0006, + 0x0050, 0x3b44, 0x1078, 0x296b, 0x2300, 0x0079, 0x3b47, 0x3b4a, + 0x3b5c, 0x3b68, 0x2200, 0x0079, 0x3b4d, 0x3b53, 0x40c1, 0x3b55, + 0x3b53, 0x3ba2, 0x3bf7, 0x1078, 0x296b, 0x7a80, 0xa294, 0x0f00, + 0x1078, 0x3c81, 0x0078, 0x40b7, 0x1078, 0x3b79, 0x0079, 0x3b60, + 0x40c1, 0x3b66, 0x3b66, 0x3ba2, 0x3b66, 0x40c1, 0x1078, 0x296b, + 0x1078, 0x3b79, 0x0079, 0x3b6c, 0x3b74, 0x3b72, 0x3b72, 0x3b74, + 0x3b72, 0x3b74, 0x1078, 0x296b, 0x1078, 0x40db, 0x781b, 0x0078, + 0x007c, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3b8a, 0x1078, 0x3ded, + 0x0078, 0x3b84, 0x1078, 0x4586, 0x6008, 0xa084, 0xfbef, 0x600a, + 0x0078, 0x3b8f, 0x7000, 0xa086, 0x0003, 0x0040, 0x3b82, 0x7003, + 0x0005, 0xb284, 0x0300, 0x0040, 0x3b99, 0x2001, 0x95e0, 0x0078, + 0x3b9b, 0x2001, 0x9612, 0x2068, 0x704e, 0xad80, 0x0009, 0x7046, + 0x2200, 0x007c, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3bb4, 0x70d4, + 0xc0b5, 0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078, 0x3bb9, + 0x1078, 0x4586, 0x0078, 0x3bb9, 0x7000, 0xa086, 0x0003, 0x0040, + 0x3bb0, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, + 0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x94c0, 0xb284, 0x0300, + 0x00c0, 0x3bcd, 0xc2fd, 0x2069, 0x95d0, 0x2d04, 0x2d08, 0x715e, + 0xa06d, 0x0040, 0x3bda, 0x6814, 0xa206, 0x0040, 0x3bdc, 0x6800, + 0x0078, 0x3bce, 0x1078, 0x3c81, 0x6eb4, 0x7e5a, 0x6920, 0xa184, + 0x0c00, 0x0040, 0x3cab, 0x7064, 0xa086, 0x0006, 0x00c0, 0x3bee, + 0x7074, 0xa206, 0x00c0, 0x3bee, 0x7066, 0x707e, 0x681b, 0x0005, + 0xc1ad, 0xc1d4, 0x6922, 0x1078, 0x40d0, 0x0078, 0x3cab, 0x7200, + 0xa286, 0x0002, 0x00c0, 0x3c09, 0x70d4, 0xc0b5, 0x70d6, 0x2c00, + 0x70ba, 0x2d00, 0x70be, 0x0078, 0x3c0d, 0x1078, 0x4586, 0x0078, + 0x3c0d, 0xa286, 0x0003, 0x0040, 0x3c05, 0x7003, 0x0001, 0x7a80, + 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, + 0xb284, 0x0300, 0x00c0, 0x3c1d, 0xc2fd, 0x79a8, 0x79a8, 0xa18c, + 0x00ff, 0x2118, 0x70cc, 0xa168, 0x2d04, 0x2d08, 0x715e, 0xa06d, + 0x0040, 0x3c31, 0x6814, 0xa206, 0x0040, 0x3c5a, 0x6800, 0x0078, + 0x3c25, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, 0x3c3b, 0x2001, + 0x95e0, 0x0078, 0x3c3d, 0x2001, 0x9612, 0x2068, 0x704e, 0x157e, + 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x00f0, 0x3c42, 0x157f, + 0xb284, 0x0300, 0x0040, 0x3c4f, 0xc2fc, 0x0078, 0x3c50, 0xc2fd, + 0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823, 0x0800, + 0x6827, 0x0003, 0x6eb4, 0x6920, 0xa184, 0x0c00, 0x0040, 0x3cab, + 0xd0dc, 0x0040, 0x3c76, 0x7064, 0xa086, 0x0004, 0x00c0, 0x3c72, + 0x7074, 0xa206, 0x00c0, 0x3c72, 0x7078, 0xa306, 0x00c0, 0x3c72, + 0x7066, 0x707e, 0x1078, 0x40d7, 0x0078, 0x3cab, 0x681b, 0x0005, + 0xc1ad, 0xc1d4, 0x6922, 0x1078, 0x40d0, 0x707f, 0x0000, 0x0078, + 0x3cab, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, 0x3c8b, 0x2001, + 0x95e0, 0x0078, 0x3c8d, 0x2001, 0x9612, 0x2068, 0x704e, 0x157e, + 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x00f0, 0x3c92, 0x157f, + 0xb284, 0x0300, 0x0040, 0x3c9f, 0xc2fc, 0x0078, 0x3ca0, 0xc2fd, + 0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823, 0x0800, + 0x6827, 0x0003, 0x007c, 0xc6ec, 0xa6ac, 0x0060, 0x0040, 0x3cfd, + 0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105, 0x00c0, 0x3cd8, 0x7bd2, + 0x7bda, 0x7cd6, 0x7cde, 0xa586, 0x0060, 0x0040, 0x3d02, 0xd6f4, + 0x00c0, 0x3cc3, 0xc6ed, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x0079, + 0xd69c, 0x0040, 0x3cd0, 0x2009, 0x0078, 0x2019, 0x0000, 0x2320, + 0x791a, 0xd6ec, 0x0040, 0x3d0d, 0x1078, 0x48bd, 0x0078, 0x3d0d, + 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x0040, 0x3d04, + 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0, 0xd6f4, 0x00c0, 0x3ce9, + 0xc6ed, 0xc6f4, 0x7e5a, 0x2011, 0x0079, 0xd69c, 0x0040, 0x3cf5, + 0x2011, 0x0078, 0x2019, 0x0000, 0x2320, 0x7a1a, 0xd6ec, 0x0040, + 0x3d0d, 0x1078, 0x48f5, 0x0078, 0x3d0d, 0x2019, 0x0000, 0x2320, + 0x0078, 0x3d04, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x0079, 0xd69c, + 0x0040, 0x3d0c, 0x2009, 0x0078, 0x791a, 0x68c0, 0x705a, 0x2d00, + 0x704e, 0x68c4, 0x2060, 0x71d4, 0x2001, 0x4e01, 0x2004, 0xd0c4, + 0x00c0, 0x3d62, 0x70d8, 0xa02d, 0x0040, 0x3d3b, 0xd1bc, 0x0040, + 0x3d55, 0x7a80, 0xa294, 0x0f00, 0x70dc, 0xa206, 0x0040, 0x3d2c, + 0x78e0, 0xa504, 0x00c0, 0x3d62, 0x70da, 0xc1bc, 0x71d6, 0x0078, + 0x3d62, 0x2031, 0x0001, 0x852c, 0x0048, 0x3d3a, 0x8633, 0x8210, + 0x0078, 0x3d33, 0x007c, 0x7de0, 0xa594, 0xff00, 0x0040, 0x3d48, + 0x2011, 0x0008, 0x852f, 0x1078, 0x3d31, 0x8637, 0x0078, 0x3d4a, + 0x1078, 0x3d31, 0x8217, 0x7880, 0xa084, 0x0f00, 0xa206, 0x0040, + 0x3d62, 0x72de, 0x76da, 0x0078, 0x3d62, 0x7a80, 0xa294, 0x0f00, + 0x70dc, 0xa236, 0x0040, 0x3d52, 0x78e0, 0xa534, 0x0040, 0x3d52, + 0xc1bd, 0x71d6, 0xd1b4, 0x00c0, 0x29c1, 0x2300, 0xa405, 0x0040, + 0x29c1, 0x70a4, 0xa086, 0x0001, 0x00c0, 0x2a0b, 0x007c, 0x6020, + 0xa005, 0x0040, 0x3d7d, 0x8001, 0x6022, 0x6008, 0xa085, 0x0008, + 0x600a, 0x700f, 0x0100, 0x702c, 0x6026, 0x007c, 0xa006, 0x1078, + 0x4586, 0x7000, 0xa086, 0x0002, 0x0040, 0x3d8b, 0x7064, 0xa086, + 0x0005, 0x00c0, 0x3d95, 0x682b, 0x0000, 0x6817, 0x0000, 0x681b, 0x0001, 0x6823, 0x0040, 0x681f, 0x0100, 0x7000, 0xa084, 0x000f, - 0x0079, 0x3b8a, 0x2946, 0x3b94, 0x3b94, 0x3bb1, 0x3b9c, 0x2946, - 0x3b92, 0x3b92, 0x1078, 0x28ec, 0x1078, 0x3bbc, 0x1078, 0x3bb5, - 0x1078, 0x202a, 0x0078, 0x2946, 0x7064, 0x7067, 0x0000, 0x7083, - 0x0000, 0x0079, 0x3ba3, 0x3bad, 0x3bad, 0x3bab, 0x3bab, 0x3bab, - 0x3bad, 0x3bab, 0x3bad, 0x0079, 0x2e5c, 0x7067, 0x0000, 0x0078, - 0x2946, 0x681b, 0x0000, 0x0078, 0x35ae, 0x6800, 0xa005, 0x00c0, - 0x3bba, 0x6002, 0x6006, 0x007c, 0x6410, 0x84ff, 0x0040, 0x3bce, - 0x2009, 0x4a02, 0x2104, 0x8001, 0x200a, 0x8421, 0x6412, 0x00c0, - 0x3bce, 0x2021, 0x4a04, 0x2404, 0xc0a5, 0x2022, 0x6008, 0xc0a4, - 0x600a, 0x007c, 0x6018, 0xa005, 0x0040, 0x3bd8, 0x8001, 0x601a, - 0x007c, 0x1078, 0x4131, 0x681b, 0x0018, 0x0078, 0x3c1a, 0x1078, - 0x4131, 0x681b, 0x0019, 0x0078, 0x3c1a, 0x1078, 0x4131, 0x681b, - 0x001a, 0x0078, 0x3c1a, 0x1078, 0x4131, 0x681b, 0x0003, 0x0078, - 0x3c1a, 0x7774, 0x1078, 0x3fe1, 0x7178, 0xa18c, 0x00ff, 0x3210, - 0xa294, 0x0300, 0x0040, 0x3c00, 0xa1e8, 0x8fc0, 0x0078, 0x3c02, - 0xa1e8, 0x90d0, 0x2d04, 0x2d08, 0x2068, 0xa005, 0x00c0, 0x3c0a, - 0x0078, 0x2946, 0x6814, 0xc0fc, 0x7274, 0xc2fc, 0xa206, 0x0040, - 0x3c14, 0x6800, 0x0078, 0x3c03, 0x6800, 0x200a, 0x681b, 0x0005, - 0x707f, 0x0000, 0x1078, 0x3bbc, 0x6820, 0xd084, 0x00c0, 0x3c22, - 0x1078, 0x3bb5, 0x1078, 0x3bd2, 0x681f, 0x0000, 0x6823, 0x0020, - 0x1078, 0x202a, 0x0078, 0x2946, 0xa282, 0x0003, 0x00c0, 0x3e9d, - 0x7da8, 0xa5ac, 0x00ff, 0x7ea8, 0xa6b4, 0x00ff, 0x6920, 0xc1bd, - 0x6922, 0xd1c4, 0x0040, 0x3c86, 0xc1c4, 0x6922, 0xa6b4, 0x00ff, - 0x0040, 0x3c73, 0xa682, 0x000c, 0x0048, 0x3c4a, 0x0040, 0x3c4a, - 0x2031, 0x000c, 0x2500, 0xa086, 0x000a, 0x0040, 0x3c51, 0x852b, - 0x852b, 0x1078, 0x3f73, 0x0040, 0x3c59, 0x1078, 0x3d55, 0x0078, - 0x3c7c, 0x1078, 0x3f2e, 0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5, - 0x6006, 0x1078, 0x3d8a, 0x0c7f, 0x6920, 0xc1c5, 0x6922, 0x7e58, - 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x3c70, 0x781b, 0x0061, 0x007c, - 0x781b, 0x0075, 0x007c, 0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5, - 0x6006, 0x1078, 0x3d8a, 0x0c7f, 0x7e58, 0xd6d4, 0x00c0, 0x3c83, - 0x781b, 0x0064, 0x007c, 0x781b, 0x0076, 0x007c, 0x0c7e, 0x7058, - 0x2060, 0x6100, 0xd1e4, 0x0040, 0x3ccf, 0x6208, 0x8217, 0xa294, - 0x00ff, 0xa282, 0x000c, 0x0048, 0x3c99, 0x0040, 0x3c99, 0x2011, - 0x000c, 0x2600, 0xa202, 0x00c8, 0x3c9e, 0x2230, 0x6208, 0xa294, - 0x00ff, 0x2001, 0x4a05, 0x2004, 0xd0e4, 0x00c0, 0x3cb3, 0x78ec, - 0xd0e4, 0x0040, 0x3cb3, 0xa282, 0x000a, 0x00c8, 0x3cb9, 0x2011, - 0x000a, 0x0078, 0x3cb9, 0xa282, 0x000c, 0x00c8, 0x3cb9, 0x2011, - 0x000c, 0x2200, 0xa502, 0x00c8, 0x3cbe, 0x2228, 0x1078, 0x3f32, - 0x2500, 0xa086, 0x000a, 0x0040, 0x3cc7, 0x852b, 0x852b, 0x1078, - 0x3f73, 0x0040, 0x3ccf, 0x1078, 0x3d55, 0x0078, 0x3cd3, 0x1078, - 0x3f2e, 0x1078, 0x3d8a, 0x7858, 0xc095, 0x785a, 0x0c7f, 0x781b, - 0x0075, 0x007c, 0x0c7e, 0x2960, 0x6000, 0xd0e4, 0x00c0, 0x3cf1, - 0x6010, 0xa084, 0x000f, 0x00c0, 0x3ceb, 0x6104, 0xa18c, 0xfff5, - 0x6106, 0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, - 0x3d1c, 0x68a0, 0xd0cc, 0x00c0, 0x3ceb, 0x6208, 0xa294, 0x00ff, - 0x2001, 0x4a05, 0x2004, 0xd0e4, 0x00c0, 0x3d0a, 0x78ec, 0xd0e4, - 0x0040, 0x3d0a, 0xa282, 0x000a, 0x00c0, 0x3d0a, 0x2011, 0x000a, - 0x0078, 0x3d10, 0xa282, 0x000c, 0x00c8, 0x3d10, 0x2011, 0x000c, - 0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c, 0x0048, 0x3d1c, - 0x0040, 0x3d1c, 0x2019, 0x000c, 0x78ab, 0x0001, 0x78ab, 0x0003, - 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5, - 0x6822, 0x70d4, 0xd0b4, 0x0040, 0x3d38, 0xc0b4, 0x70d6, 0x70b8, - 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, - 0x0c7f, 0x007c, 0x0c7e, 0x2960, 0x6104, 0xa18c, 0xfff5, 0x6106, - 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x3d46, 0x78ab, 0x0001, + 0x0079, 0x3d9a, 0x29c5, 0x3daa, 0x3da4, 0x3dcc, 0x3db4, 0x29c5, + 0x3da2, 0x3da2, 0x1078, 0x296b, 0x1078, 0x3dd7, 0x1078, 0x3dd0, + 0x0078, 0x3db0, 0x1078, 0x3dd7, 0x705c, 0x2060, 0x6800, 0x6002, + 0x1078, 0x202c, 0x0078, 0x29c5, 0x7064, 0x7067, 0x0000, 0x7083, + 0x0000, 0x0079, 0x3dbb, 0x3dc8, 0x3dc8, 0x3dc3, 0x3dc3, 0x3dc3, + 0x3dc8, 0x3dc3, 0x3dc8, 0x77d4, 0xc7dd, 0x77d6, 0x0079, 0x2f35, + 0x7067, 0x0000, 0x0078, 0x29c5, 0x681b, 0x0000, 0x0078, 0x36c8, + 0x6800, 0xa005, 0x00c0, 0x3dd5, 0x6002, 0x6006, 0x007c, 0x6410, + 0x84ff, 0x0040, 0x3de9, 0x2009, 0x4e02, 0x2104, 0x8001, 0x200a, + 0x8421, 0x6412, 0x00c0, 0x3de9, 0x2021, 0x4e04, 0x2404, 0xc0a5, + 0x2022, 0x6008, 0xc0a4, 0x600a, 0x007c, 0x6018, 0xa005, 0x0040, + 0x3df3, 0x8001, 0x601a, 0x007c, 0x1078, 0x4383, 0x681b, 0x0018, + 0x0078, 0x3e34, 0x1078, 0x4383, 0x681b, 0x0019, 0x0078, 0x3e34, + 0x1078, 0x4383, 0x681b, 0x001a, 0x0078, 0x3e34, 0x1078, 0x4383, + 0x681b, 0x0003, 0x0078, 0x3e34, 0x7774, 0x1078, 0x41fe, 0x7178, + 0xa18c, 0x00ff, 0x3210, 0xa294, 0x0300, 0x0040, 0x3e1b, 0xa1e8, + 0x93c0, 0x0078, 0x3e1d, 0xa1e8, 0x94d0, 0x2d04, 0x2d08, 0x2068, + 0xa005, 0x00c0, 0x3e26, 0x707e, 0x0078, 0x29c5, 0x6814, 0x7274, + 0xa206, 0x0040, 0x3e2e, 0x6800, 0x0078, 0x3e1e, 0x6800, 0x200a, + 0x681b, 0x0005, 0x707f, 0x0000, 0x1078, 0x3dd7, 0x6820, 0xd084, + 0x00c0, 0x3e3c, 0x1078, 0x3dd0, 0x1078, 0x3ded, 0x681f, 0x0000, + 0x6823, 0x0020, 0x1078, 0x202c, 0x0078, 0x29c5, 0xa282, 0x0003, + 0x00c0, 0x40b7, 0x7da8, 0xa5ac, 0x00ff, 0x7e5a, 0x7ea8, 0xa6b4, + 0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1c4, 0x0040, 0x3ea1, 0xc1c4, + 0x6922, 0xa6b4, 0x00ff, 0x0040, 0x3e8e, 0xa682, 0x000c, 0x0048, + 0x3e65, 0x0040, 0x3e65, 0x2031, 0x000c, 0x2500, 0xa086, 0x000a, + 0x0040, 0x3e6c, 0x852b, 0x852b, 0x1078, 0x4190, 0x0040, 0x3e74, + 0x1078, 0x3f6f, 0x0078, 0x3e97, 0x1078, 0x414b, 0x0c7e, 0x2960, + 0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x3fa5, 0x0c7f, 0x6920, + 0xc1c5, 0x6922, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x3e8b, + 0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x0c7e, 0x2960, + 0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x3fa5, 0x0c7f, 0x7e58, + 0xd6d4, 0x00c0, 0x3e9e, 0x781b, 0x0067, 0x007c, 0x781b, 0x0079, + 0x007c, 0x0c7e, 0x7058, 0x2060, 0x6100, 0xd1e4, 0x0040, 0x3eea, + 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c, 0x0048, 0x3eb4, + 0x0040, 0x3eb4, 0x2011, 0x000c, 0x2600, 0xa202, 0x00c8, 0x3eb9, + 0x2230, 0x6208, 0xa294, 0x00ff, 0x2001, 0x4e05, 0x2004, 0xd0e4, + 0x00c0, 0x3ece, 0x78ec, 0xd0e4, 0x0040, 0x3ece, 0xa282, 0x000a, + 0x00c8, 0x3ed4, 0x2011, 0x000a, 0x0078, 0x3ed4, 0xa282, 0x000c, + 0x00c8, 0x3ed4, 0x2011, 0x000c, 0x2200, 0xa502, 0x00c8, 0x3ed9, + 0x2228, 0x1078, 0x414f, 0x2500, 0xa086, 0x000a, 0x0040, 0x3ee2, + 0x852b, 0x852b, 0x1078, 0x4190, 0x0040, 0x3eea, 0x1078, 0x3f6f, + 0x0078, 0x3eee, 0x1078, 0x414b, 0x1078, 0x3fa5, 0x7858, 0xc095, + 0x785a, 0x0c7f, 0x781b, 0x0078, 0x007c, 0x0c7e, 0x2960, 0x6000, + 0xd0e4, 0x00c0, 0x3f0b, 0xa084, 0x0040, 0x00c0, 0x3f05, 0x6104, + 0xa18c, 0xfff5, 0x6106, 0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019, + 0x0000, 0x0078, 0x3f36, 0x68a0, 0xd0cc, 0x00c0, 0x3f05, 0x6208, + 0xa294, 0x00ff, 0x2001, 0x4e05, 0x2004, 0xd0e4, 0x00c0, 0x3f24, + 0x78ec, 0xd0e4, 0x0040, 0x3f24, 0xa282, 0x000b, 0x00c8, 0x3f24, + 0x2011, 0x000a, 0x0078, 0x3f2a, 0xa282, 0x000c, 0x00c8, 0x3f2a, + 0x2011, 0x000c, 0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c, + 0x0048, 0x3f36, 0x0040, 0x3f36, 0x2019, 0x000c, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, - 0x6820, 0xc0c5, 0x6822, 0x0c7f, 0x007c, 0x0c7e, 0x7158, 0x2160, - 0x2018, 0xa08c, 0x0020, 0x0040, 0x3d5e, 0xc0ac, 0x2008, 0xa084, - 0xfff0, 0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae, 0x6612, 0x78a4, - 0xa084, 0xfff0, 0xa18c, 0x000f, 0xa105, 0xa39c, 0x0020, 0x0040, - 0x3d73, 0xa085, 0x4000, 0xc0fc, 0xd0b4, 0x00c0, 0x3d78, 0xc0fd, - 0x78a6, 0x6016, 0x788a, 0xa6b4, 0x000f, 0x8637, 0x8204, 0x8004, - 0xa084, 0x00ff, 0xa605, 0x600e, 0x6004, 0xa084, 0xfff5, 0x6006, - 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x6018, 0x789a, 0x78a4, - 0xa084, 0xfff0, 0x78a6, 0x6012, 0x7884, 0xa084, 0xfff0, 0x7886, - 0x600c, 0xa084, 0x00ff, 0x600e, 0x0c7f, 0x007c, 0xa282, 0x0002, - 0x00c0, 0x3e9d, 0x7aa8, 0x6920, 0xc1bd, 0x6922, 0xd1cc, 0x0040, - 0x3dd9, 0xc1cc, 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x00c8, - 0x3e9d, 0x1078, 0x3e2a, 0x1078, 0x3d8a, 0xa980, 0x0001, 0x200c, - 0x1078, 0x3fdd, 0x1078, 0x3cda, 0x88ff, 0x0040, 0x3dcf, 0x789b, - 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, - 0x3dcc, 0x781b, 0x0061, 0x007c, 0x781b, 0x0075, 0x007c, 0x7e58, - 0xd6d4, 0x00c0, 0x3dd6, 0x781b, 0x0064, 0x007c, 0x781b, 0x0076, - 0x007c, 0xa282, 0x0002, 0x00c8, 0x3de1, 0xa284, 0x0001, 0x0040, - 0x3dea, 0x7158, 0xa188, 0x0000, 0x210c, 0xd1ec, 0x00c0, 0x3dea, - 0x2011, 0x0000, 0x1078, 0x3f0f, 0x1078, 0x3e2a, 0x1078, 0x3d8a, - 0x7858, 0xc095, 0x785a, 0x781b, 0x0075, 0x007c, 0x0c7e, 0x027e, - 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, 0x00c0, 0x3e0b, 0x6014, - 0xa084, 0x0040, 0x00c0, 0x3e09, 0xc1a4, 0x6106, 0xa006, 0x0078, - 0x3e27, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, - 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x70d4, 0xd0b4, 0x0040, 0x3e23, - 0xc0b4, 0x70d6, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, - 0x6018, 0x8001, 0x601a, 0x6820, 0xa085, 0x0200, 0x6822, 0x027f, - 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x82ff, 0x0040, 0x3e32, - 0x2011, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a, 0x78a4, 0xa084, - 0xffbf, 0xa205, 0xc0fc, 0xd0b4, 0x00c0, 0x3e3f, 0xc0fd, 0x78a6, - 0x6016, 0x788a, 0x6004, 0xc0a4, 0x6006, 0x0c7f, 0x007c, 0x007e, - 0x7000, 0xa086, 0x0003, 0x0040, 0x3e50, 0x007f, 0x0078, 0x3e53, - 0x007f, 0x0078, 0x3e9a, 0xd6ac, 0x0040, 0x3e9a, 0x7888, 0xa084, - 0x0040, 0x0040, 0x3e9a, 0x7bb8, 0xa384, 0x003f, 0x831b, 0x00c8, - 0x3e62, 0x8000, 0xa005, 0x0040, 0x3e77, 0x831b, 0x00c8, 0x3e6b, - 0x8001, 0x0040, 0x3e97, 0xd6f4, 0x0040, 0x3e77, 0x78b8, 0x801b, - 0x00c8, 0x3e73, 0x8000, 0xa084, 0x003f, 0x00c0, 0x3e97, 0xc6f4, - 0x7e5a, 0x79d8, 0x7adc, 0x2001, 0x0001, 0xa108, 0x00c8, 0x3e82, - 0xa291, 0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x1078, 0x46e5, - 0x781b, 0x0073, 0xb284, 0x0300, 0x0040, 0x3e92, 0x2001, 0x0000, - 0x0078, 0x3e94, 0x2001, 0x0001, 0x1078, 0x4585, 0x007c, 0x781b, - 0x0073, 0x007c, 0x781b, 0x0076, 0x007c, 0x1078, 0x3ec2, 0x781b, - 0x0075, 0x007c, 0x1078, 0x3eae, 0x781b, 0x0075, 0x007c, 0x6827, - 0x0002, 0x1078, 0x3eb6, 0x781b, 0x0075, 0x007c, 0x2001, 0x0005, - 0x0078, 0x3ec4, 0x2001, 0x000c, 0x0078, 0x3ec4, 0x2001, 0x0006, - 0x0078, 0x3ec4, 0x2001, 0x000d, 0x0078, 0x3ec4, 0x2001, 0x0009, - 0x0078, 0x3ec4, 0x2001, 0x0007, 0x789b, 0x007e, 0x78aa, 0xc69d, - 0x7e5a, 0x70d4, 0xd0b4, 0x0040, 0x3eda, 0xc0b4, 0x70d6, 0x0c7e, + 0x6820, 0xc0c5, 0x6822, 0x70d4, 0xd0b4, 0x0040, 0x3f52, 0xc0b4, + 0x70d6, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, + 0x8001, 0x601a, 0x0c7f, 0x007c, 0x0c7e, 0x2960, 0x6104, 0xa18c, + 0xfff5, 0x6106, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x3f60, + 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, + 0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822, 0x0c7f, 0x007c, 0x0c7e, + 0x7158, 0x2160, 0x2018, 0xa08c, 0x0020, 0x0040, 0x3f78, 0xc0ac, + 0x2008, 0xa084, 0xfff0, 0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae, + 0x6612, 0x78a4, 0xa084, 0xfff0, 0xa18c, 0x000f, 0xa105, 0xc0f4, + 0xa39c, 0x0020, 0x0040, 0x3f8e, 0xa085, 0x4000, 0xc0fc, 0xd0b4, + 0x00c0, 0x3f93, 0xc0fd, 0x78a6, 0x6016, 0x788a, 0xa6b4, 0x000f, + 0x8637, 0x8204, 0x8004, 0xa084, 0x00ff, 0xa605, 0x600e, 0x6004, + 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, + 0x6018, 0x789a, 0x78a4, 0xa084, 0xfff0, 0x78a6, 0x6012, 0x7884, + 0xa084, 0xfff0, 0x7886, 0x600c, 0xa084, 0x00ff, 0x600e, 0x0c7f, + 0x007c, 0xa282, 0x0002, 0x00c0, 0x40b7, 0x7aa8, 0x6920, 0xc1bd, + 0x6922, 0xd1cc, 0x0040, 0x3ff4, 0xc1cc, 0x6922, 0xa294, 0x00ff, + 0xa282, 0x0002, 0x00c8, 0x40b7, 0x1078, 0x4044, 0x1078, 0x3fa5, + 0xa980, 0x0001, 0x200c, 0x1078, 0x41fa, 0x1078, 0x3ef5, 0x88ff, + 0x0040, 0x3fea, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, + 0x7e5a, 0xd6d4, 0x00c0, 0x3fe7, 0x781b, 0x0064, 0x007c, 0x781b, + 0x0078, 0x007c, 0x7e58, 0xd6d4, 0x00c0, 0x3ff1, 0x781b, 0x0067, + 0x007c, 0x781b, 0x0079, 0x007c, 0xa282, 0x0002, 0x00c8, 0x3ffc, + 0xa284, 0x0001, 0x0040, 0x4005, 0x7158, 0xa188, 0x0000, 0x210c, + 0xd1ec, 0x00c0, 0x4005, 0x2011, 0x0000, 0x1078, 0x412c, 0x1078, + 0x4044, 0x1078, 0x3fa5, 0x7858, 0xc095, 0x785a, 0x781b, 0x0078, + 0x007c, 0x0c7e, 0x027e, 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, + 0x00c0, 0x4025, 0xa084, 0x0080, 0x00c0, 0x4023, 0xc1a4, 0x6106, + 0xa006, 0x0078, 0x4041, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, + 0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x70d4, 0xd0b4, + 0x0040, 0x403d, 0xc0b4, 0x70d6, 0x70b8, 0xa065, 0x6008, 0xa084, + 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x6820, 0xa085, 0x0200, + 0x6822, 0x027f, 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x82ff, + 0x0040, 0x404c, 0x2011, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a, + 0x78a4, 0xa084, 0xffbf, 0xa205, 0xc0fc, 0xd0b4, 0x00c0, 0x4059, + 0xc0fd, 0x78a6, 0x6016, 0x788a, 0x6004, 0xc0a4, 0x6006, 0x0c7f, + 0x007c, 0x007e, 0x7000, 0xa086, 0x0003, 0x0040, 0x406a, 0x007f, + 0x0078, 0x406d, 0x007f, 0x0078, 0x40b4, 0xd6ac, 0x0040, 0x40b4, + 0x7888, 0xa084, 0x0040, 0x0040, 0x40b4, 0x7bb8, 0xa384, 0x003f, + 0x831b, 0x00c8, 0x407c, 0x8000, 0xa005, 0x0040, 0x4091, 0x831b, + 0x00c8, 0x4085, 0x8001, 0x0040, 0x40b1, 0xd6f4, 0x0040, 0x4091, + 0x78b8, 0x801b, 0x00c8, 0x408d, 0x8000, 0xa084, 0x003f, 0x00c0, + 0x40b1, 0xc6f4, 0x7e5a, 0x79d8, 0x7adc, 0x2001, 0x0001, 0xa108, + 0x00c8, 0x409c, 0xa291, 0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade, + 0x1078, 0x49c3, 0x781b, 0x0076, 0xb284, 0x0300, 0x0040, 0x40ac, + 0x2001, 0x0000, 0x0078, 0x40ae, 0x2001, 0x0001, 0x1078, 0x484b, + 0x007c, 0x781b, 0x0076, 0x007c, 0x781b, 0x0079, 0x007c, 0x1078, + 0x40df, 0x781b, 0x0078, 0x007c, 0x1078, 0x40c8, 0x781b, 0x0078, + 0x007c, 0x6827, 0x0002, 0x1078, 0x40d0, 0x781b, 0x0078, 0x007c, + 0x2001, 0x0005, 0x0078, 0x40e1, 0x2001, 0x000c, 0x0078, 0x40e1, + 0x6820, 0xc0d5, 0x6822, 0x2001, 0x0006, 0x0078, 0x40e1, 0x2001, + 0x000d, 0x0078, 0x40e1, 0x2001, 0x0009, 0x0078, 0x40e1, 0x2001, + 0x0007, 0x789b, 0x007e, 0x78aa, 0xc69d, 0x7e5a, 0x70d4, 0xd0b4, + 0x0040, 0x40f7, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, + 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x007c, + 0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0x017e, + 0xb28c, 0x0300, 0x0040, 0x4108, 0xa0e0, 0x52c0, 0x0078, 0x410a, + 0xa0e0, 0x5340, 0x017f, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184, + 0x000f, 0x0040, 0x411a, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004, + 0xc09d, 0x6006, 0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184, 0x0040, + 0x0040, 0x412a, 0xa184, 0xffbf, 0xc0fd, 0x78a6, 0x6016, 0x6004, + 0xc0a5, 0x6006, 0x077f, 0x007c, 0x789b, 0x0010, 0x78ab, 0x0001, + 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab, + 0x0004, 0x70d4, 0xd0b4, 0x0040, 0x414a, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, - 0x601a, 0x0c7f, 0x007c, 0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, - 0x873b, 0x8703, 0x017e, 0xb28c, 0x0300, 0x0040, 0x3eeb, 0xa0e0, - 0x4ec0, 0x0078, 0x3eed, 0xa0e0, 0x4f40, 0x017f, 0xa7b8, 0x0020, - 0x7f9a, 0x79a4, 0xa184, 0x000f, 0x0040, 0x3efd, 0xa184, 0xfff0, - 0x78a6, 0x6012, 0x6004, 0xc09d, 0x6006, 0x8738, 0x8738, 0x7f9a, - 0x79a4, 0xa184, 0x0040, 0x0040, 0x3f0d, 0xa184, 0xffbf, 0xc0fd, - 0x78a6, 0x6016, 0x6004, 0xc0a5, 0x6006, 0x077f, 0x007c, 0x789b, - 0x0010, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, - 0x789b, 0x0060, 0x78ab, 0x0004, 0x70d4, 0xd0b4, 0x0040, 0x3f2d, - 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, - 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x007c, 0x2031, 0x0000, - 0x2029, 0x0032, 0x789b, 0x0010, 0x78ab, 0x0001, 0x78ab, 0x0003, - 0x78ab, 0x0001, 0x7daa, 0x7eaa, 0x789b, 0x0060, 0x78ab, 0x0005, - 0x70d4, 0xd0b4, 0x0040, 0x3f51, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, - 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, - 0x0c7f, 0x007c, 0x157e, 0x8007, 0xa084, 0x00ff, 0x8003, 0x8003, - 0xa080, 0x0020, 0x789a, 0x79a4, 0xa18c, 0xfff0, 0x2021, 0x3fc6, - 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, 0x0032, 0x2404, 0xa084, - 0xfff0, 0xa106, 0x0040, 0x3f71, 0x8420, 0x2300, 0xa210, 0x00f0, - 0x3f66, 0x157f, 0x007c, 0x157e, 0x2001, 0x4a05, 0x2004, 0xd0e4, - 0x00c0, 0x3fa4, 0x2021, 0x3fd4, 0x20a9, 0x0009, 0x2011, 0x0028, - 0xa582, 0x0019, 0x0040, 0x3fba, 0x0048, 0x3fba, 0x8420, 0x95a9, - 0x2011, 0x0032, 0xa582, 0x0032, 0x0040, 0x3fba, 0x0048, 0x3fba, - 0x8420, 0x95a9, 0x2019, 0x000a, 0x2011, 0x0064, 0x2200, 0xa502, - 0x0040, 0x3fba, 0x0048, 0x3fba, 0x8420, 0x2300, 0xa210, 0x00f0, - 0x3f96, 0x157f, 0x0078, 0x3fb8, 0x2021, 0x3fc6, 0x2019, 0x0011, - 0x20a9, 0x000e, 0x2011, 0x0032, 0x2200, 0xa502, 0x0040, 0x3fba, - 0x0048, 0x3fba, 0x8420, 0x2300, 0xa210, 0x00f0, 0x3fac, 0x157f, - 0xa006, 0x007c, 0x157f, 0xa582, 0x0064, 0x00c8, 0x3fc3, 0x7808, - 0xa085, 0x0070, 0x780a, 0x2404, 0xa005, 0x007c, 0x1209, 0x3002, - 0x3202, 0x4203, 0x4403, 0x5404, 0x5604, 0x6605, 0x6805, 0x7806, - 0x7a06, 0x0c07, 0x0c07, 0x0e07, 0x10e1, 0x330a, 0x5805, 0x5a05, - 0x6a06, 0x6c06, 0x7c07, 0x7e07, 0x0e00, 0x789b, 0x0010, 0xa046, - 0x007c, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x8003, 0x8003, - 0x8003, 0x8003, 0xa105, 0xd7fc, 0x0040, 0x3ff2, 0xa0e0, 0x6fc0, - 0x0078, 0x3ff4, 0xa0e0, 0x4fc0, 0x007c, 0x0e7e, 0x0f7e, 0xd084, - 0x0040, 0x4002, 0x2079, 0x0100, 0x2009, 0x4a80, 0x2071, 0x4a80, - 0x0078, 0x4014, 0x2009, 0x4a40, 0x007e, 0x2001, 0x4a04, 0x2004, - 0xd0ec, 0x007f, 0x0040, 0x4010, 0x2079, 0x0100, 0x0078, 0x4014, - 0x2079, 0x0200, 0x2071, 0x4a40, 0x2091, 0x8000, 0x2104, 0xa084, - 0x000f, 0x0079, 0x401b, 0x405d, 0x4025, 0x4025, 0x4025, 0x4025, - 0x4025, 0x4023, 0x4023, 0x1078, 0x28ec, 0x784b, 0x0004, 0x7848, - 0xa084, 0x0004, 0x00c0, 0x4027, 0x784b, 0x0008, 0x7848, 0xa084, - 0x0008, 0x00c0, 0x402e, 0x68b4, 0xc0f5, 0x68b6, 0x7858, 0xc0f5, - 0x785a, 0x7830, 0xd0bc, 0x00c0, 0x405d, 0x007e, 0x2001, 0x4a04, - 0x2004, 0xd0ec, 0x007f, 0x0040, 0x4049, 0xb284, 0x0300, 0x0078, - 0x404b, 0xb284, 0x0400, 0x0040, 0x4051, 0x0018, 0x405d, 0x0078, - 0x4053, 0x0028, 0x405d, 0x681c, 0xd0ac, 0x00c0, 0x405b, 0x1078, - 0x40d5, 0x0078, 0x405d, 0x781b, 0x00f0, 0x2091, 0x8001, 0x0f7f, - 0x0e7f, 0x007c, 0x0c7e, 0x2001, 0x4a01, 0x2004, 0xd0ac, 0x00c0, - 0x40c7, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, - 0xb28c, 0x0300, 0x0040, 0x4078, 0xa0e0, 0x4ec0, 0x0078, 0x407a, - 0xa0e0, 0x4f40, 0x6004, 0xa084, 0x000a, 0x00c0, 0x40c7, 0x6108, - 0xa194, 0xff00, 0x0040, 0x40c7, 0xa18c, 0x00ff, 0x2001, 0x000a, - 0xa106, 0x0040, 0x40a6, 0x2001, 0x000c, 0xa106, 0x0040, 0x40aa, - 0x2001, 0x0012, 0xa106, 0x0040, 0x40ae, 0x2001, 0x0014, 0xa106, - 0x0040, 0x40b2, 0x2001, 0x0019, 0xa106, 0x0040, 0x40b6, 0x2001, - 0x0032, 0xa106, 0x0040, 0x40ba, 0x0078, 0x40be, 0x2009, 0x000c, - 0x0078, 0x40c0, 0x2009, 0x0012, 0x0078, 0x40c0, 0x2009, 0x0014, - 0x0078, 0x40c0, 0x2009, 0x0019, 0x0078, 0x40c0, 0x2009, 0x0020, - 0x0078, 0x40c0, 0x2009, 0x003f, 0x0078, 0x40c0, 0x2011, 0x0000, - 0x2100, 0xa205, 0x600a, 0x6004, 0xa085, 0x0002, 0x6006, 0x0c7f, - 0x007c, 0x781b, 0x0076, 0x007c, 0x781b, 0x0075, 0x007c, 0x781b, - 0x0064, 0x007c, 0x781b, 0x0061, 0x007c, 0x2009, 0x4a19, 0x210c, - 0xa186, 0x0000, 0x0040, 0x40e7, 0xa186, 0x0001, 0x0040, 0x40ea, - 0x701f, 0x000b, 0x7067, 0x0001, 0x781b, 0x0047, 0x007c, 0x781b, - 0x00e7, 0x007c, 0x701f, 0x000a, 0x007c, 0x2009, 0x4a19, 0x210c, - 0xa186, 0x0000, 0x0040, 0x4102, 0xa186, 0x0001, 0x0040, 0x40ff, - 0x701f, 0x000b, 0x7067, 0x0001, 0x781b, 0x0047, 0x007c, 0x701f, - 0x000a, 0x007c, 0x781b, 0x00e6, 0x007c, 0x781b, 0x00f0, 0x007c, - 0x781b, 0x00ef, 0x007c, 0x781b, 0x00c0, 0x007c, 0x781b, 0x00bf, - 0x007c, 0x6818, 0xd0fc, 0x0040, 0x4117, 0x681b, 0x001d, 0x7067, - 0x0001, 0x781b, 0x0047, 0x007c, 0x7830, 0xa084, 0x00c0, 0x00c0, - 0x4130, 0x7808, 0xc08c, 0x780a, 0x0005, 0x0005, 0x0005, 0x0005, - 0x78ec, 0xa084, 0x0021, 0x0040, 0x4130, 0x7808, 0xc08d, 0x780a, - 0x007c, 0x7808, 0xc08d, 0x780a, 0x007c, 0x7830, 0xa084, 0x0040, - 0x00c0, 0x4135, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x0040, 0x4144, - 0xb284, 0x0300, 0x0078, 0x4146, 0xb284, 0x0400, 0x0040, 0x414c, - 0x0098, 0x4150, 0x0078, 0x414e, 0x00a8, 0x4150, 0x78ac, 0x007c, - 0x7808, 0xa084, 0xfffd, 0x780a, 0x0005, 0x0005, 0x0005, 0x0005, - 0x78ec, 0xa084, 0x0021, 0x0040, 0x4173, 0x007e, 0x2001, 0x4a04, - 0x2004, 0xd0ec, 0x007f, 0x0040, 0x4169, 0xb284, 0x0300, 0x0078, - 0x416b, 0xb284, 0x0400, 0x0040, 0x4171, 0x0098, 0x416d, 0x0078, - 0x4173, 0x00a8, 0x4171, 0x78ac, 0x007e, 0x7808, 0xa085, 0x0002, - 0x780a, 0x007f, 0x007c, 0xa784, 0x0001, 0x00c0, 0x360e, 0xa784, - 0x0070, 0x0040, 0x418b, 0x0c7e, 0x2d60, 0x2f68, 0x1078, 0x2881, - 0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040, 0x4198, 0x784b, - 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2946, 0x0078, 0x40c9, - 0xa784, 0x0004, 0x0040, 0x41c7, 0x78b8, 0xa084, 0x4001, 0x0040, - 0x41c7, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2946, - 0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0, 0x41c7, 0x78c0, - 0xa685, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00f0, 0x007c, 0x784b, - 0x0008, 0x6818, 0xd0fc, 0x0040, 0x41c4, 0x681b, 0x0015, 0xd6f4, - 0x0040, 0x41c4, 0x681b, 0x0007, 0x1078, 0x40d5, 0x007c, 0x681b, - 0x0003, 0x7858, 0xa084, 0x3f00, 0x681e, 0x682f, 0x0000, 0x6833, - 0x0000, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2f84, - 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x41e4, - 0xb284, 0x0300, 0x0078, 0x41e6, 0xb284, 0x0400, 0x0040, 0x41ec, - 0x0018, 0x2942, 0x0078, 0x41ee, 0x0028, 0x2942, 0x0078, 0x3ea2, - 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xd3fc, - 0x0040, 0x41fe, 0xa080, 0x4f40, 0x0078, 0x4200, 0xa080, 0x4ec0, - 0x2060, 0x2048, 0x705a, 0x2a60, 0x007c, 0x0020, 0x0020, 0x0000, + 0x601a, 0x0c7f, 0x007c, 0x2031, 0x0000, 0x2029, 0x0032, 0x789b, + 0x0010, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, + 0x7eaa, 0x789b, 0x0060, 0x78ab, 0x0005, 0x70d4, 0xd0b4, 0x0040, + 0x416e, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, + 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x007c, 0x157e, + 0x8007, 0xa084, 0x00ff, 0x8003, 0x8003, 0xa080, 0x0020, 0x789a, + 0x79a4, 0xa18c, 0xfff0, 0x2021, 0x41e3, 0x2019, 0x0011, 0x20a9, + 0x000e, 0x2011, 0x0032, 0x2404, 0xa084, 0xfff0, 0xa106, 0x0040, + 0x418e, 0x8420, 0x2300, 0xa210, 0x00f0, 0x4183, 0x157f, 0x007c, + 0x157e, 0x2001, 0x4e05, 0x2004, 0xd0e4, 0x00c0, 0x41c1, 0x2021, + 0x41f1, 0x20a9, 0x0009, 0x2011, 0x0028, 0xa582, 0x0019, 0x0040, + 0x41d7, 0x0048, 0x41d7, 0x8420, 0x95a9, 0x2011, 0x0032, 0xa582, + 0x0032, 0x0040, 0x41d7, 0x0048, 0x41d7, 0x8420, 0x95a9, 0x2019, + 0x000a, 0x2011, 0x0064, 0x2200, 0xa502, 0x0040, 0x41d7, 0x0048, + 0x41d7, 0x8420, 0x2300, 0xa210, 0x00f0, 0x41b3, 0x157f, 0x0078, + 0x41d5, 0x2021, 0x41e3, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, + 0x0032, 0x2200, 0xa502, 0x0040, 0x41d7, 0x0048, 0x41d7, 0x8420, + 0x2300, 0xa210, 0x00f0, 0x41c9, 0x157f, 0xa006, 0x007c, 0x157f, + 0xa582, 0x0064, 0x00c8, 0x41e0, 0x7808, 0xa085, 0x0070, 0x780a, + 0x2404, 0xa005, 0x007c, 0x1209, 0x3002, 0x3202, 0x4203, 0x4403, + 0x5404, 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, 0x0c07, + 0x0e07, 0x10e1, 0x330a, 0x5805, 0x5a05, 0x6a06, 0x6c06, 0x7c07, + 0x7e07, 0x0e00, 0x789b, 0x0010, 0xa046, 0x007c, 0xa784, 0x0f00, + 0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, + 0xd7fc, 0x0040, 0x420f, 0xa0e0, 0x73c0, 0x0078, 0x4211, 0xa0e0, + 0x53c0, 0x007c, 0x0e7e, 0x0f7e, 0xd084, 0x0040, 0x421f, 0x2079, + 0x0100, 0x2009, 0x4e80, 0x2071, 0x4e80, 0x0078, 0x422f, 0x2009, + 0x4e40, 0x2071, 0x4e40, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x0040, + 0x422d, 0x2079, 0x0100, 0x0078, 0x422f, 0x2079, 0x0200, 0x2091, + 0x8000, 0x2104, 0xa084, 0x000f, 0x0079, 0x4236, 0x4240, 0x4240, + 0x4240, 0x4240, 0x4240, 0x4240, 0x423e, 0x423e, 0x1078, 0x296b, + 0x69b4, 0xc1f5, 0xa18c, 0xff9f, 0x69b6, 0xa005, 0x0040, 0x428f, + 0x7858, 0xa084, 0xff9f, 0xa085, 0x6000, 0x785a, 0x7828, 0xa086, + 0x1814, 0x00c0, 0x428f, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004, + 0x00c0, 0x4255, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, 0x00c0, + 0x425c, 0x7830, 0xd0bc, 0x00c0, 0x428f, 0x007e, 0x2001, 0x4e04, + 0x2004, 0xd0ec, 0x007f, 0x0040, 0x4271, 0xb284, 0x0300, 0x0078, + 0x4273, 0xb284, 0x0400, 0x0040, 0x4279, 0x0018, 0x428f, 0x0078, + 0x427b, 0x0028, 0x428f, 0x79e4, 0xa184, 0x0030, 0x0040, 0x428f, + 0x78ec, 0xa084, 0x0003, 0x0040, 0x428f, 0x681c, 0xd0ac, 0x00c0, + 0x428d, 0x1078, 0x4319, 0x0078, 0x428f, 0x781b, 0x00f9, 0x0f7f, + 0x0e7f, 0x007c, 0x0c7e, 0x2001, 0x4e01, 0x2004, 0xd0ac, 0x00c0, + 0x430b, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, + 0xb28c, 0x0300, 0x0040, 0x42a8, 0xa0e0, 0x52c0, 0x0078, 0x42aa, + 0xa0e0, 0x5340, 0x6004, 0xa084, 0x000a, 0x00c0, 0x430b, 0x6108, + 0xa194, 0xff00, 0x0040, 0x430b, 0xa18c, 0x00ff, 0x2001, 0x000a, + 0xa106, 0x0040, 0x42d6, 0x2001, 0x000c, 0xa106, 0x0040, 0x42da, + 0x2001, 0x0012, 0xa106, 0x0040, 0x42de, 0x2001, 0x0014, 0xa106, + 0x0040, 0x42e2, 0x2001, 0x0019, 0xa106, 0x0040, 0x42e6, 0x2001, + 0x0032, 0xa106, 0x0040, 0x42ea, 0x0078, 0x42ee, 0x2009, 0x000c, + 0x0078, 0x42f0, 0x2009, 0x0012, 0x0078, 0x42f0, 0x2009, 0x0014, + 0x0078, 0x42f0, 0x2009, 0x0019, 0x0078, 0x42f0, 0x2009, 0x0020, + 0x0078, 0x42f0, 0x2009, 0x003f, 0x0078, 0x42f0, 0x2011, 0x0000, + 0x2100, 0xa205, 0x600a, 0x6004, 0xa085, 0x0002, 0x6006, 0x2061, + 0x4e00, 0x6004, 0xd0bc, 0x0040, 0x430b, 0x6814, 0xd0fc, 0x00c0, + 0x4306, 0x60ea, 0x2061, 0x4e40, 0x0078, 0x4309, 0x60ee, 0x2061, + 0x4e80, 0x601f, 0x800f, 0x0c7f, 0x007c, 0x781b, 0x0079, 0x007c, + 0x781b, 0x0078, 0x007c, 0x781b, 0x0067, 0x007c, 0x781b, 0x0064, + 0x007c, 0x2009, 0x4e19, 0x210c, 0xa186, 0x0000, 0x0040, 0x432b, + 0xa186, 0x0001, 0x0040, 0x432e, 0x701f, 0x000b, 0x7067, 0x0001, + 0x781b, 0x0047, 0x007c, 0x781b, 0x00f0, 0x007c, 0x701f, 0x000a, + 0x007c, 0x2009, 0x4e19, 0x210c, 0xa186, 0x0000, 0x0040, 0x4346, + 0xa186, 0x0001, 0x0040, 0x4343, 0x701f, 0x000b, 0x7067, 0x0001, + 0x781b, 0x0047, 0x007c, 0x701f, 0x000a, 0x007c, 0x781b, 0x00ef, + 0x007c, 0x781b, 0x00f9, 0x007c, 0x781b, 0x00f8, 0x007c, 0x781b, + 0x00c9, 0x007c, 0x781b, 0x00c8, 0x007c, 0x6818, 0xd0fc, 0x0040, + 0x435b, 0x681b, 0x001d, 0x7067, 0x0001, 0x781b, 0x0047, 0x007c, + 0x7830, 0xa084, 0x00c0, 0x00c0, 0x4382, 0x7808, 0xc08c, 0x780a, + 0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x00c0, + 0x437f, 0x2001, 0x4e05, 0x2004, 0xd0e4, 0x00c0, 0x437d, 0x7804, + 0xa084, 0xff1f, 0xa085, 0x00e0, 0x7806, 0xa006, 0x007c, 0x7808, + 0xc08d, 0x780a, 0x007c, 0x7808, 0xc08d, 0x780a, 0x007c, 0x7830, + 0xa084, 0x0040, 0x00c0, 0x4387, 0x2001, 0x4e04, 0x2004, 0xd0ec, + 0x0040, 0x4396, 0xb284, 0x0300, 0x0078, 0x4398, 0xb284, 0x0400, + 0x0040, 0x439e, 0x0098, 0x43a2, 0x0078, 0x43a0, 0x00a8, 0x43a2, + 0x78ac, 0x007c, 0x7808, 0xa084, 0xfffd, 0x780a, 0x0005, 0x0005, + 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040, 0x43c5, 0x007e, + 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x43bb, 0xb284, + 0x0300, 0x0078, 0x43bd, 0xb284, 0x0400, 0x0040, 0x43c3, 0x0098, + 0x43bf, 0x0078, 0x43c5, 0x00a8, 0x43c3, 0x78ac, 0x007e, 0x7808, + 0xa085, 0x0002, 0x780a, 0x007f, 0x007c, 0xa784, 0x0001, 0x00c0, + 0x3770, 0xa784, 0x0070, 0x0040, 0x43dd, 0x0c7e, 0x2d60, 0x2f68, + 0x1078, 0x28df, 0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040, + 0x43ea, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3770, + 0x0078, 0x430d, 0xa784, 0x0004, 0x0040, 0x4419, 0x78b8, 0xa084, + 0x4001, 0x0040, 0x4419, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, + 0x0040, 0x3770, 0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0, + 0x4419, 0x78c0, 0xa685, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00f9, + 0x007c, 0x784b, 0x0008, 0x6818, 0xd0fc, 0x0040, 0x4416, 0x681b, + 0x0015, 0xd6f4, 0x0040, 0x4416, 0x681b, 0x0007, 0x1078, 0x4319, + 0x007c, 0x681b, 0x0003, 0x7858, 0xa084, 0x3f00, 0x681e, 0x682f, + 0x0000, 0x6833, 0x0000, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, + 0x0040, 0x3066, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, + 0x0040, 0x4436, 0xb284, 0x0300, 0x0078, 0x4438, 0xb284, 0x0400, + 0x0040, 0x443e, 0x0018, 0x29c1, 0x0078, 0x4440, 0x0028, 0x29c1, + 0x0078, 0x40bc, 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003, + 0x8003, 0xd3fc, 0x0040, 0x4450, 0xa080, 0x5340, 0x0078, 0x4452, + 0xa080, 0x52c0, 0x2060, 0x2048, 0x705a, 0x2a60, 0x007c, 0x0020, + 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, - 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0062, - 0x0009, 0x0014, 0x0014, 0x9848, 0x0014, 0x0014, 0x9906, 0x98f4, - 0x0014, 0x0014, 0x0080, 0x00f1, 0x0100, 0x0402, 0x2008, 0xf880, - 0x0018, 0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014, 0x2500, 0x0013, - 0x2500, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, - 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0xa200, - 0x3806, 0x8839, 0x20c4, 0x0864, 0xa850, 0x3008, 0x28c1, 0x9d0d, - 0xa201, 0x300c, 0x2847, 0x8161, 0x846a, 0x8000, 0x84a4, 0x1856, - 0x883a, 0xa808, 0x28e2, 0x9cc2, 0xa8f3, 0x0864, 0xa83e, 0x300c, - 0xa801, 0x3008, 0x28e1, 0x9cc2, 0x2021, 0xa81b, 0xa205, 0x870c, - 0xd8de, 0x64a0, 0x6de0, 0x6fc0, 0x63a4, 0x6c80, 0x0212, 0xa205, - 0x883d, 0x9d25, 0x882b, 0x1814, 0x883b, 0x9d2b, 0x883b, 0x7027, - 0x85f2, 0xa737, 0xa532, 0xf003, 0x8576, 0x8677, 0xa812, 0x883e, - 0xa810, 0x280c, 0xa204, 0x64c0, 0x6de0, 0x67a0, 0x6fc0, 0x9d25, - 0x1814, 0x9d2b, 0x883b, 0x7023, 0x8576, 0x8677, 0xa802, 0x7861, - 0x883e, 0x206b, 0x28c1, 0x9d0d, 0x2044, 0x2103, 0x20a2, 0x2081, - 0xa8c9, 0xa207, 0x2901, 0xa80a, 0x0014, 0xa203, 0x8000, 0x85a4, - 0x1872, 0x879a, 0x883c, 0x1fe2, 0xf601, 0xa208, 0x856e, 0x866f, - 0x7161, 0x0014, 0x0704, 0x3008, 0x9cc2, 0x0014, 0xa202, 0x8000, - 0x85a4, 0x3009, 0x84a8, 0x19e2, 0xf844, 0x856e, 0x883f, 0x08e6, - 0xa8f5, 0xf861, 0xa8ea, 0xf801, 0x0014, 0xf881, 0x0016, 0x85b2, - 0x80f0, 0x9532, 0xfaa2, 0x1de2, 0x0014, 0x8532, 0xf221, 0x0014, - 0x1de2, 0x84a8, 0xd6e0, 0x1fe6, 0x0014, 0x3008, 0x8000, 0x284a, - 0x1011, 0xa8fc, 0x3008, 0x9d25, 0x8000, 0xa000, 0x2802, 0x1011, - 0xa8fd, 0x9d2b, 0xa887, 0x3008, 0x9d25, 0x283b, 0x1011, 0xa8fd, - 0xa209, 0x0017, 0x300c, 0x8000, 0x85a4, 0x1de2, 0xdac1, 0x0014, + 0x0020, 0x0062, 0x0009, 0x0014, 0x0014, 0x9848, 0x0014, 0x0014, + 0x9914, 0x98fd, 0x0014, 0x0014, 0x0080, 0x00ff, 0x0100, 0x0402, + 0x2008, 0xf880, 0x0018, 0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014, + 0x2500, 0x0013, 0x2500, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, + 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, + 0x0010, 0xa200, 0x3806, 0x7102, 0x805f, 0x9481, 0x8839, 0x20c4, + 0x0864, 0xa856, 0x3008, 0x28c1, 0x9d1b, 0xa201, 0x300c, 0x2847, + 0x8161, 0x846a, 0x8000, 0x84a4, 0x1856, 0x883a, 0xa808, 0x28e2, + 0x9ccb, 0xa8f3, 0x0864, 0xa844, 0x300c, 0xa801, 0x3008, 0x28e1, + 0x9ccb, 0x2021, 0xa81d, 0xa205, 0x870c, 0xd8de, 0x64a0, 0x6de0, + 0x6fc0, 0x63a4, 0x6c80, 0x0212, 0xa205, 0x883d, 0x7942, 0x8020, + 0xa4a1, 0x882b, 0x1814, 0x883b, 0x80df, 0x94a1, 0x7027, 0x85f2, + 0xa737, 0xa532, 0xf003, 0x8576, 0x8677, 0xa816, 0x883e, 0xa814, + 0x2001, 0xa812, 0xa204, 0x64c0, 0x6de0, 0x67a0, 0x6fc0, 0x7942, + 0x8020, 0xa4a1, 0x1814, 0x80df, 0x94a1, 0x883b, 0x7023, 0x8576, + 0x8677, 0xa802, 0x7861, 0x883e, 0x206b, 0x28c1, 0x9d1b, 0x2044, + 0x2103, 0x20a2, 0x2081, 0xa8c3, 0xa207, 0x0904, 0xa20e, 0xa809, + 0xa203, 0x8000, 0x85a4, 0x1872, 0x879a, 0x883c, 0x1fe2, 0xf601, + 0xa208, 0x856e, 0x866f, 0x7161, 0x0014, 0x0704, 0x3008, 0x9ccb, + 0x0014, 0xa202, 0x8000, 0x85a4, 0x3009, 0x84a8, 0x19e2, 0xf844, + 0x856e, 0x883f, 0x08e6, 0xa8f5, 0xf861, 0xa8ea, 0xf801, 0x0014, + 0xf881, 0x0016, 0x85b2, 0x80f0, 0x9532, 0xfaa2, 0x1de2, 0x0014, + 0x8532, 0xf221, 0x0014, 0x1de2, 0x84a8, 0xd6e0, 0x1fe6, 0x0014, + 0x3008, 0x8000, 0x284a, 0x1011, 0xa8fc, 0x3008, 0x9d33, 0x8000, + 0xa000, 0x2802, 0x1011, 0xa8fd, 0x9d39, 0xa8bd, 0x3008, 0x9d33, + 0x283b, 0x1011, 0xa8fd, 0xa209, 0x7102, 0x805f, 0x9481, 0x0017, + 0x300c, 0xa209, 0x8000, 0x85a4, 0x1de2, 0xa209, 0xdac1, 0x0014, 0x0210, 0xa801, 0x0014, 0x26e0, 0x873a, 0xfaa3, 0x19f2, 0x26e0, - 0x18f2, 0x0014, 0xa20b, 0x0014, 0xa20d, 0x3806, 0x0210, 0x9d17, + 0x18f2, 0x0014, 0xa20b, 0x0014, 0xa20d, 0x3806, 0x0210, 0x9d25, 0x0704, 0xa206, 0x6865, 0x817e, 0x842a, 0x1dc1, 0x8823, 0x0016, 0x6042, 0x8008, 0xa8fa, 0x8000, 0x84a4, 0x8160, 0x842a, 0xf021, 0x3008, 0x84a8, 0x11d6, 0x7042, 0x20dd, 0x0011, 0x20d4, 0x8822, 0x0016, 0x7944, 0x8421, 0xa020, 0xa532, 0x84a1, 0x0016, 0x7944, 0x8421, 0xa0df, 0x9532, 0x84a1, 0x0016, 0x0000, 0x127e, 0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x7204, 0x7008, 0xc09c, 0xa205, - 0x00c0, 0x4342, 0x720c, 0x82ff, 0x0040, 0x433d, 0x8aff, 0x00c0, - 0x4342, 0x7200, 0xd284, 0x00c0, 0x4342, 0x7003, 0x0008, 0x127f, + 0x00c0, 0x45a2, 0x720c, 0x82ff, 0x0040, 0x459d, 0x8aff, 0x00c0, + 0x45a2, 0x7200, 0xd284, 0x00c0, 0x45a2, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x7000, 0xa084, 0x0003, 0x7002, 0xc69c, 0xd084, - 0x0040, 0x4374, 0x2001, 0x4a05, 0x2004, 0xd0ec, 0x00c0, 0x43a5, - 0xd0e4, 0x00c0, 0x435a, 0x2001, 0x04fd, 0x2004, 0xa086, 0x0003, - 0x0040, 0x43a5, 0x0e7e, 0x2071, 0x0010, 0x2009, 0x0007, 0x7008, - 0xa084, 0x3000, 0x00c0, 0x435d, 0x8109, 0x00c0, 0x435f, 0x0e7f, - 0x2009, 0x0007, 0x7008, 0xa084, 0x3000, 0x00c0, 0x435a, 0x8109, - 0x00c0, 0x436a, 0x0078, 0x43a5, 0x7108, 0xd1fc, 0x0040, 0x437f, - 0x1078, 0x44ba, 0x8aff, 0x0040, 0x432c, 0x0078, 0x4374, 0x700c, - 0xa08c, 0x03ff, 0x0040, 0x43aa, 0x7004, 0xd084, 0x0040, 0x439c, - 0x7014, 0xa005, 0x00c0, 0x4398, 0x7010, 0x7310, 0xa306, 0x00c0, - 0x438c, 0x2300, 0xa005, 0x0040, 0x439c, 0xa102, 0x00c8, 0x4374, - 0x7007, 0x0010, 0x0078, 0x43a5, 0x8aff, 0x0040, 0x43aa, 0x1078, - 0x46a3, 0x00c0, 0x439f, 0x0040, 0x4374, 0x1078, 0x4443, 0x127f, - 0x2000, 0x007c, 0x7204, 0x7108, 0xc19c, 0x8103, 0x00c8, 0x43b9, - 0x1078, 0x44ba, 0x0078, 0x43aa, 0x7003, 0x0008, 0x127f, 0x2000, - 0x007c, 0xa205, 0x00c0, 0x43a5, 0x7003, 0x0008, 0x127f, 0x2000, - 0x007c, 0x6428, 0x84ff, 0x0040, 0x43ed, 0x2c70, 0x7004, 0xa0bc, - 0x000f, 0xa7b8, 0x43fd, 0x273c, 0x87fb, 0x00c0, 0x43db, 0x0048, - 0x43d3, 0x1078, 0x28ec, 0x609c, 0xa075, 0x0040, 0x43ed, 0x0078, - 0x43c6, 0x2039, 0x43f2, 0x2704, 0xae68, 0x6808, 0xa630, 0x680c, - 0xa529, 0x8421, 0x0040, 0x43ed, 0x8738, 0x2704, 0xa005, 0x00c0, - 0x43dc, 0x709c, 0xa075, 0x00c0, 0x43c6, 0x007c, 0x0000, 0x0005, - 0x0009, 0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, 0x0003, - 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x43f2, 0x43ef, - 0x0000, 0x0000, 0x8000, 0x0000, 0x43f2, 0x0000, 0x43fa, 0x43f7, - 0x0000, 0x0000, 0x0000, 0x0000, 0x43fa, 0x0000, 0x43f5, 0x43f5, - 0x0000, 0x0000, 0x8000, 0x0000, 0x43f5, 0x0000, 0x43fb, 0x43fb, - 0x0000, 0x0000, 0x0000, 0x0000, 0x43fb, 0x2079, 0x4a00, 0x2071, - 0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0001, 0x7810, - 0xd0ec, 0x0040, 0x4431, 0x2009, 0x0001, 0x2071, 0x0020, 0x0078, - 0x4435, 0x2009, 0x0002, 0x2071, 0x0050, 0x7007, 0x000a, 0x7007, - 0x0002, 0x7003, 0x0000, 0x8109, 0x0040, 0x4442, 0x2071, 0x0020, - 0x0078, 0x4435, 0x007c, 0x7004, 0x8004, 0x00c8, 0x44a6, 0x7007, - 0x0012, 0x2019, 0x0000, 0x7108, 0x7008, 0xa106, 0x00c0, 0x444b, - 0xa184, 0x01e0, 0x0040, 0x4456, 0x1078, 0x28ec, 0x7810, 0xd0ec, - 0x0040, 0x4470, 0x2001, 0x04fd, 0x2004, 0xa086, 0x0003, 0x00c0, - 0x4474, 0xa184, 0x4000, 0x0040, 0x4478, 0xa382, 0x0003, 0x00c8, - 0x4478, 0xa184, 0x0004, 0x0040, 0x444b, 0x8318, 0x0078, 0x444b, - 0x7814, 0xd0ec, 0x00c0, 0x4478, 0xa184, 0x4000, 0x00c0, 0x444b, - 0xa19c, 0x300c, 0xa386, 0x2004, 0x0040, 0x4486, 0xa386, 0x0008, - 0x0040, 0x4491, 0xa386, 0x200c, 0x00c0, 0x444b, 0x7200, 0x8204, - 0x0048, 0x4491, 0x730c, 0xa384, 0x03ff, 0x0040, 0x4491, 0x1078, - 0x28ec, 0x7007, 0x0012, 0x7000, 0xd084, 0x00c0, 0x44a6, 0x7008, - 0xa084, 0x01e0, 0x00c0, 0x44a6, 0x7310, 0x7014, 0xa305, 0x0040, - 0x44a6, 0x710c, 0xa184, 0x03ff, 0x00c0, 0x4443, 0x7007, 0x0012, - 0x7007, 0x0008, 0x7004, 0xd09c, 0x00c0, 0x44aa, 0x7007, 0x0012, - 0x7108, 0x8103, 0x0048, 0x44ae, 0x7003, 0x0008, 0x007c, 0x7108, - 0x0078, 0x44ba, 0xa184, 0x01e0, 0x00c0, 0x44ee, 0x7108, 0xa184, - 0x01e0, 0x00c0, 0x44ee, 0xa184, 0x0007, 0x0079, 0x44c7, 0x44d1, - 0x44e1, 0x44cf, 0x44e1, 0x44cf, 0x4533, 0x44cf, 0x4531, 0x1078, - 0x28ec, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, 0x00c0, - 0x44dc, 0x2049, 0x0000, 0x007c, 0x1078, 0x46a3, 0x00c0, 0x44dc, - 0x007c, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, 0x0040, - 0x44ed, 0x1078, 0x46a3, 0x00c0, 0x44e9, 0x007c, 0x7007, 0x0012, - 0x7108, 0x00e0, 0x44f1, 0x2091, 0x6000, 0x00e0, 0x44f5, 0x2091, - 0x6000, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xd09c, 0x00c0, - 0x44fd, 0x7007, 0x0012, 0x7108, 0xd1fc, 0x00c0, 0x4501, 0x7003, - 0x0000, 0x7000, 0xa005, 0x00c0, 0x4515, 0x7004, 0xa005, 0x00c0, - 0x4515, 0x700c, 0xa005, 0x0040, 0x4517, 0x0078, 0x44f9, 0x2049, - 0x0000, 0xb284, 0x0100, 0x0040, 0x4521, 0x2001, 0x0000, 0x0078, - 0x4523, 0x2001, 0x0001, 0x1078, 0x3ff5, 0x6818, 0xa084, 0x8000, - 0x0040, 0x452c, 0x681b, 0x0002, 0x007c, 0x1078, 0x28ec, 0x1078, - 0x28ec, 0x1078, 0x4570, 0x7210, 0x7114, 0x700c, 0xa09c, 0x03ff, - 0x2800, 0xa300, 0xa211, 0xa189, 0x0000, 0x1078, 0x4570, 0x2704, - 0x2c58, 0xac60, 0x6308, 0x2200, 0xa322, 0x630c, 0x2100, 0xa31b, - 0x2400, 0xa305, 0x0040, 0x4556, 0x00c8, 0x4556, 0x8412, 0x8210, - 0x830a, 0xa189, 0x0000, 0x2b60, 0x0078, 0x453d, 0x2b60, 0x8a07, - 0x007e, 0x6004, 0xa084, 0x0008, 0x0040, 0x4562, 0xa7ba, 0x43f7, - 0x0078, 0x4564, 0xa7ba, 0x43ef, 0x007f, 0xa73d, 0x2c00, 0x6886, - 0x6f8a, 0x6c92, 0x6b8e, 0x7007, 0x0012, 0x1078, 0x4443, 0x007c, - 0x8a50, 0x8739, 0x2704, 0xa004, 0x00c0, 0x4584, 0x6000, 0xa064, - 0x00c0, 0x457b, 0x2d60, 0x6004, 0xa084, 0x000f, 0xa080, 0x440d, - 0x203c, 0x87fb, 0x1040, 0x28ec, 0x007c, 0x127e, 0x0d7e, 0x70d4, - 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x6884, 0x2060, 0x6888, - 0x6b8c, 0x6c90, 0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x007e, - 0x6804, 0xa084, 0x0008, 0x007f, 0x0040, 0x45a2, 0xa0b8, 0x43f7, - 0x0078, 0x45a4, 0xa0b8, 0x43ef, 0xb284, 0x0100, 0x0040, 0x45ab, - 0x7e20, 0x0078, 0x45ac, 0x7e24, 0xa6b5, 0x000c, 0x681c, 0xd0b4, - 0x0040, 0x45b3, 0xc685, 0x2400, 0xa305, 0x0040, 0x45dd, 0x2c58, - 0x2704, 0x6104, 0xac60, 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, - 0x701e, 0xa184, 0x0008, 0x0040, 0x45cd, 0x6010, 0xa081, 0x0000, - 0x7022, 0x6014, 0xa081, 0x0000, 0x7026, 0x6208, 0x2400, 0xa202, - 0x7012, 0x620c, 0x2300, 0xa203, 0x7016, 0x7602, 0x7007, 0x0001, - 0x2b60, 0x1078, 0x46c6, 0x0078, 0x45df, 0x1078, 0x46a3, 0x00c0, - 0x45dd, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, 0x70d4, 0xa084, - 0x4600, 0x8004, 0x2090, 0x0d7f, 0x7007, 0x0004, 0x7004, 0xd094, - 0x00c0, 0x45ee, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x127e, - 0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x7e20, - 0xb284, 0x0100, 0x00c0, 0x4605, 0x7e24, 0xa6b5, 0x000c, 0x681c, - 0xd0ac, 0x00c0, 0x4610, 0xc685, 0x7003, 0x0000, 0x7007, 0x0004, - 0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x43fd, - 0x273c, 0x87fb, 0x00c0, 0x4626, 0x0048, 0x4620, 0x1078, 0x28ec, - 0x689c, 0xa065, 0x0040, 0x462a, 0x0078, 0x4613, 0x1078, 0x46a3, - 0x00c0, 0x4626, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e, 0x017e, - 0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x7e20, 0xb284, - 0x0100, 0x00c0, 0x463c, 0x7e24, 0x0d7f, 0x037f, 0x047f, 0xa6b5, - 0x000c, 0x681c, 0xd0b4, 0x0040, 0x464a, 0xc685, 0x7003, 0x0000, - 0x7007, 0x0004, 0x2049, 0x462d, 0x6828, 0xa055, 0x0040, 0x46a0, - 0x2d70, 0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x43fd, 0x273c, - 0x87fb, 0x00c0, 0x4666, 0x0048, 0x465f, 0x1078, 0x28ec, 0x709c, - 0xa075, 0x2060, 0x0040, 0x46a0, 0x0078, 0x4652, 0x2704, 0xae68, - 0x6808, 0xa422, 0x680c, 0xa31b, 0x0048, 0x467f, 0x8a51, 0x00c0, - 0x4673, 0x1078, 0x28ec, 0x8738, 0x2704, 0xa005, 0x00c0, 0x4667, - 0x709c, 0xa075, 0x2060, 0x0040, 0x46a0, 0x0078, 0x4652, 0x8422, - 0x8420, 0x831a, 0xa399, 0x0000, 0x6908, 0x2400, 0xa122, 0x690c, - 0x2300, 0xa11b, 0x00c8, 0x468e, 0x1078, 0x28ec, 0xb284, 0x0100, - 0x0040, 0x469c, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x00c0, 0x469c, - 0x2071, 0x0050, 0x0078, 0x469e, 0x2071, 0x0020, 0x0078, 0x45b3, - 0x127f, 0x2000, 0x007c, 0x7008, 0xa084, 0x0003, 0xa086, 0x0003, - 0x00c0, 0x46ab, 0x007c, 0x2704, 0xac78, 0x7800, 0x701a, 0x7804, - 0x701e, 0x7808, 0x7012, 0x780c, 0x7016, 0x6004, 0xa084, 0x0008, - 0x0040, 0x46be, 0x7810, 0x7022, 0x7814, 0x7026, 0x7602, 0x7004, - 0xa084, 0x0010, 0xc085, 0x7006, 0x2079, 0x4a00, 0x8a51, 0x0040, - 0x46e1, 0x8738, 0x2704, 0xa005, 0x00c0, 0x46dc, 0x609c, 0xa005, - 0x0040, 0x46e2, 0x2060, 0x6004, 0xa084, 0x000f, 0xa080, 0x43fd, - 0x203c, 0x87fb, 0x1040, 0x28ec, 0x7008, 0xa084, 0x0003, 0xa086, - 0x0003, 0x007c, 0x2051, 0x0000, 0x007c, 0x127e, 0x007e, 0x0d7e, - 0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x087f, 0x7108, - 0xa184, 0x0003, 0x00c0, 0x46fa, 0x6828, 0xa005, 0x0040, 0x470a, - 0x0078, 0x4342, 0x7108, 0xd1fc, 0x0040, 0x4702, 0x1078, 0x44ba, - 0x0078, 0x46ef, 0x7007, 0x0010, 0x7108, 0xd1fc, 0x0040, 0x4704, - 0x1078, 0x44ba, 0x7008, 0xa086, 0x0008, 0x00c0, 0x46ef, 0x7000, - 0xa005, 0x00c0, 0x46ef, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f, - 0x2000, 0x007c, 0x127e, 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, - 0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x2049, 0x471a, - 0xad80, 0x0011, 0x20a0, 0xb284, 0x0100, 0x0040, 0x473d, 0x2001, - 0x4a04, 0x2004, 0xd0ec, 0x0040, 0x4739, 0x2099, 0x0031, 0x0078, - 0x473f, 0x2099, 0x0032, 0x0078, 0x473f, 0x2099, 0x0031, 0x700c, - 0xa084, 0x03ff, 0x682a, 0x7007, 0x0008, 0x7007, 0x0002, 0x7003, - 0x0001, 0x0040, 0x474e, 0x8000, 0x80ac, 0x53a5, 0x700c, 0xa084, - 0x03ff, 0x0040, 0x475a, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, - 0x00c0, 0x4755, 0x0c7f, 0x2049, 0x0000, 0x7003, 0x0000, 0x157f, - 0x137f, 0x147f, 0x127f, 0x2000, 0x007c, 0x2091, 0x8000, 0x2091, - 0x6000, 0x78ac, 0xa005, 0x00c0, 0x477c, 0x7974, 0x70d0, 0xa106, - 0x00c0, 0x477c, 0x781c, 0xa005, 0x0040, 0x477c, 0x781f, 0x0000, - 0x0068, 0x477c, 0x2091, 0x4080, 0x7830, 0x8001, 0x7832, 0x00c0, - 0x4804, 0x7834, 0x7832, 0x7810, 0xd0ec, 0x00c0, 0x47fd, 0x2061, - 0x6fc0, 0x2069, 0x4a80, 0xc7fd, 0x68d0, 0xa005, 0x0040, 0x4796, - 0x8001, 0x68d2, 0x00c0, 0x4796, 0x1078, 0x4998, 0x6800, 0xa084, - 0x000f, 0x0040, 0x47ab, 0xa086, 0x0001, 0x0040, 0x47ab, 0x6844, - 0xa00d, 0x0040, 0x47ab, 0x2104, 0xa005, 0x0040, 0x47ab, 0x8001, - 0x200a, 0x0040, 0x4909, 0x6814, 0xa005, 0x0040, 0x47d0, 0x8001, - 0x6816, 0x00c0, 0x47d0, 0x68a7, 0x0001, 0x0f7e, 0xd7fc, 0x00c0, - 0x47c5, 0x7810, 0xd0ec, 0x0040, 0x47c1, 0x2079, 0x0100, 0x0078, - 0x47c7, 0x2079, 0x0200, 0x0078, 0x47c7, 0x2079, 0x0100, 0x1078, - 0x4131, 0x0f7f, 0x6864, 0xa005, 0x0040, 0x47d0, 0x1078, 0x25de, - 0x6880, 0xa005, 0x0040, 0x47dd, 0x8001, 0x6882, 0x00c0, 0x47dd, - 0x6867, 0x0000, 0x68d4, 0xc0dd, 0x68d6, 0x68d4, 0xd0fc, 0x0040, - 0x47fa, 0xc0fc, 0x68d6, 0x20a9, 0x0200, 0x603c, 0xa005, 0x0040, - 0x47f6, 0x8001, 0x603e, 0x68d4, 0xc0fd, 0x68d6, 0x00c0, 0x47f6, - 0x6010, 0xa005, 0x0040, 0x47f6, 0x1078, 0x25de, 0xace0, 0x0010, - 0x00f0, 0x47e5, 0xd7fc, 0x0040, 0x4804, 0x2061, 0x4fc0, 0x2069, - 0x4a40, 0xc7fc, 0x0078, 0x478c, 0x1078, 0x4840, 0x7838, 0x8001, - 0x783a, 0x00c0, 0x4826, 0x783c, 0x783a, 0x2061, 0x4fc0, 0x2069, - 0x4a40, 0xc7fc, 0x680c, 0xa005, 0x0040, 0x4818, 0x1078, 0x487f, - 0xd7fc, 0x00c0, 0x4826, 0x7810, 0xd0ec, 0x00c0, 0x4826, 0x2061, - 0x6fc0, 0x2069, 0x4a80, 0xc7fd, 0x0078, 0x4812, 0x7814, 0xd0e4, - 0x00c0, 0x482a, 0x7810, 0xd0cc, 0x0040, 0x483d, 0xd0ac, 0x00c0, - 0x4836, 0xd0a4, 0x0040, 0x483d, 0xc0ad, 0x7812, 0x2091, 0x8001, - 0x0068, 0x483c, 0x1078, 0x2368, 0x007c, 0x2091, 0x8001, 0x007c, - 0x7840, 0x8001, 0x7842, 0x00c0, 0x487e, 0x7844, 0x7842, 0x2091, - 0x8000, 0x2061, 0x4fc0, 0x2069, 0x4a40, 0xc7fc, 0x6810, 0xa005, - 0x00c0, 0x4854, 0x2001, 0x0101, 0x8001, 0x6812, 0xd7fc, 0x0040, - 0x485d, 0xa080, 0x90d0, 0x0078, 0x485f, 0xa080, 0x8fc0, 0x2040, - 0x2004, 0xa065, 0x0040, 0x4870, 0x6024, 0xa005, 0x0040, 0x486c, - 0x8001, 0x6026, 0x0040, 0x48ad, 0x6000, 0x2c40, 0x0078, 0x4861, - 0xd7fc, 0x00c0, 0x487e, 0x7810, 0xd0ec, 0x00c0, 0x487e, 0x2061, - 0x6fc0, 0x2069, 0x4a80, 0xc7fd, 0x0078, 0x484e, 0x007c, 0x2009, - 0x0000, 0x20a9, 0x0200, 0x6008, 0xd09c, 0x0040, 0x4899, 0x6024, - 0xa005, 0x0040, 0x488f, 0x8001, 0x6026, 0x0078, 0x4897, 0x6008, - 0xc09c, 0xc0bd, 0x600a, 0xa18d, 0x0001, 0x0078, 0x4899, 0xa18d, - 0x0100, 0xace0, 0x0010, 0x00f0, 0x4883, 0xa184, 0x0001, 0x0040, - 0x48a8, 0xa18c, 0xfffe, 0x690e, 0x1078, 0x25de, 0x0078, 0x48a9, - 0x690e, 0x007c, 0x00c0, 0x48a9, 0x786c, 0x6800, 0xa005, 0x0040, - 0x48b5, 0x684c, 0xac06, 0x0040, 0x4909, 0x6864, 0xa005, 0x0040, - 0x48bd, 0x6027, 0x0001, 0x0078, 0x4906, 0x2c00, 0x687e, 0x601b, - 0x0006, 0x60b4, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, - 0xa085, 0x0060, 0x6022, 0x6000, 0x2042, 0x6714, 0x6f76, 0x1078, - 0x1e02, 0x6818, 0xa005, 0x0040, 0x48d7, 0x8001, 0x681a, 0x6808, - 0xc0a4, 0x680a, 0x6810, 0x7908, 0x8109, 0x790a, 0x8001, 0x00d0, - 0x48e3, 0x1078, 0x28ec, 0x6812, 0x00c0, 0x48e9, 0x7910, 0xc1a5, - 0x7912, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x1078, 0x202a, - 0xd7fc, 0x00c0, 0x48f7, 0x2069, 0x4a40, 0x0078, 0x48f9, 0x2069, - 0x4a80, 0x6910, 0xa184, 0x0100, 0x2001, 0x0006, 0x00c0, 0x4903, - 0x697a, 0x2001, 0x0004, 0x2708, 0x1078, 0x25d1, 0x2091, 0x8001, - 0x007c, 0x0d7e, 0x694c, 0x2160, 0xd7fc, 0x00c0, 0x491b, 0x7810, - 0xd0ec, 0x0040, 0x4917, 0x2069, 0x0100, 0x0078, 0x491d, 0x2069, - 0x0200, 0x0078, 0x491d, 0x2069, 0x0100, 0x1078, 0x2881, 0x601b, - 0x0006, 0x6858, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, - 0xa085, 0x0048, 0x6022, 0x602f, 0x0000, 0x6033, 0x0000, 0x6830, - 0xd0b4, 0x0040, 0x494b, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, - 0xd094, 0x0040, 0x493d, 0x00f0, 0x4937, 0x684b, 0x0009, 0x20a9, - 0x0014, 0x6848, 0xd084, 0x0040, 0x4947, 0x00f0, 0x4941, 0x20a9, - 0x00fa, 0x00f0, 0x4949, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b, - 0x0047, 0x0d7f, 0x6867, 0x0007, 0x2091, 0x8001, 0x007c, 0x2079, - 0x4a00, 0x1078, 0x498b, 0x1078, 0x4971, 0x1078, 0x497e, 0x2009, - 0x0002, 0x2069, 0x4a80, 0x680f, 0x0000, 0x6813, 0x0000, 0x6817, - 0x0000, 0x8109, 0x0040, 0x4970, 0x2069, 0x4a40, 0x0078, 0x4963, - 0x007c, 0x7810, 0xd0ec, 0x0040, 0x4979, 0x2019, 0x00cc, 0x0078, - 0x497b, 0x2019, 0x007b, 0x7b3a, 0x7b3e, 0x007c, 0x7814, 0xd0e4, - 0x00c0, 0x4986, 0x2019, 0x0040, 0x0078, 0x4988, 0x2019, 0x0026, - 0x7b42, 0x7b46, 0x007c, 0x7814, 0xd0e4, 0x00c0, 0x4993, 0x2019, - 0x3f94, 0x0078, 0x4995, 0x2019, 0x2624, 0x7b32, 0x7b36, 0x007c, - 0x6950, 0xa185, 0x0000, 0x0040, 0x49ad, 0x0c7e, 0x6ac0, 0x2264, - 0x602b, 0x0000, 0x602f, 0x0000, 0x6008, 0xc0b5, 0x600a, 0x8210, - 0x8109, 0x00c0, 0x499f, 0x6952, 0x0c7f, 0x007c, 0x70ec, 0xd0dc, - 0x00c0, 0x49b7, 0xd0d4, 0x0040, 0x49d6, 0x0078, 0x49d9, 0x7810, - 0xd0ec, 0x0040, 0x49c2, 0xc0f5, 0x7812, 0xd0ec, 0x0040, 0x49dd, - 0x0078, 0x49d9, 0xae8e, 0x0100, 0x0040, 0x49ce, 0x7814, 0xc0f5, - 0x7816, 0xd0d4, 0x00c0, 0x49dd, 0x0078, 0x49d9, 0x7814, 0xc0fd, - 0x7816, 0xd0d4, 0x00c0, 0x49dd, 0x0078, 0x49d9, 0xd0e4, 0x0040, - 0x49df, 0x7804, 0xd08c, 0x0040, 0x49df, 0x681f, 0x000c, 0x70a0, - 0x70a2, 0x007c, 0x699a + 0x0040, 0x45e5, 0x7108, 0x0005, 0x7008, 0xa106, 0x00c0, 0x45aa, + 0xa184, 0x0003, 0x0040, 0x4616, 0xa184, 0x01e0, 0x00c0, 0x4616, + 0xd1f4, 0x00c0, 0x45aa, 0xa184, 0x3000, 0xa086, 0x1000, 0x0040, + 0x45aa, 0x2011, 0x0180, 0x710c, 0x8211, 0x0040, 0x45cf, 0x7008, + 0xd0f4, 0x00c0, 0x45aa, 0x700c, 0xa106, 0x0040, 0x45c4, 0x7007, + 0x0012, 0x7108, 0x0005, 0x7008, 0xa106, 0x00c0, 0x45d1, 0xa184, + 0x0003, 0x0040, 0x4616, 0xd194, 0x0040, 0x45d1, 0xd1f4, 0x0040, + 0x4616, 0x7007, 0x0002, 0x0078, 0x45aa, 0x7108, 0xd1fc, 0x0040, + 0x45f0, 0x1078, 0x4769, 0x8aff, 0x0040, 0x458c, 0x0078, 0x45e5, + 0x700c, 0xa08c, 0x03ff, 0x0040, 0x461b, 0x7004, 0xd084, 0x0040, + 0x460d, 0x7014, 0xa005, 0x00c0, 0x4609, 0x7010, 0x7310, 0xa306, + 0x00c0, 0x45fd, 0x2300, 0xa005, 0x0040, 0x460d, 0xa102, 0x00c8, + 0x45e5, 0x7007, 0x0010, 0x0078, 0x4616, 0x8aff, 0x0040, 0x461b, + 0x1078, 0x4970, 0x00c0, 0x4610, 0x0040, 0x45e5, 0x1078, 0x46b4, + 0x127f, 0x2000, 0x007c, 0x7204, 0x7108, 0xc19c, 0x8103, 0x00c8, + 0x462a, 0x7007, 0x0002, 0x0078, 0x461b, 0x7003, 0x0008, 0x127f, + 0x2000, 0x007c, 0xa205, 0x00c0, 0x4616, 0x7003, 0x0008, 0x127f, + 0x2000, 0x007c, 0x6428, 0x84ff, 0x0040, 0x465e, 0x2c70, 0x7004, + 0xa0bc, 0x000f, 0xa7b8, 0x466e, 0x273c, 0x87fb, 0x00c0, 0x464c, + 0x0048, 0x4644, 0x1078, 0x296b, 0x609c, 0xa075, 0x0040, 0x465e, + 0x0078, 0x4637, 0x2039, 0x4663, 0x2704, 0xae68, 0x6808, 0xa630, + 0x680c, 0xa529, 0x8421, 0x0040, 0x465e, 0x8738, 0x2704, 0xa005, + 0x00c0, 0x464d, 0x709c, 0xa075, 0x00c0, 0x4637, 0x007c, 0x0000, + 0x0005, 0x0009, 0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, + 0x0003, 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x4663, + 0x4660, 0x0000, 0x0000, 0x8000, 0x0000, 0x4663, 0x0000, 0x466b, + 0x4668, 0x0000, 0x0000, 0x0000, 0x0000, 0x466b, 0x0000, 0x4666, + 0x4666, 0x0000, 0x0000, 0x8000, 0x0000, 0x4666, 0x0000, 0x466c, + 0x466c, 0x0000, 0x0000, 0x0000, 0x0000, 0x466c, 0x2079, 0x4e00, + 0x2071, 0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0001, + 0x7810, 0xd0ec, 0x0040, 0x46a2, 0x2009, 0x0001, 0x2071, 0x0020, + 0x0078, 0x46a6, 0x2009, 0x0002, 0x2071, 0x0050, 0x7007, 0x000a, + 0x7007, 0x0002, 0x7003, 0x0000, 0x8109, 0x0040, 0x46b3, 0x2071, + 0x0020, 0x0078, 0x46a6, 0x007c, 0x7004, 0x8004, 0x00c8, 0x473d, + 0x7108, 0x7008, 0xa106, 0x00c0, 0x46b8, 0xa184, 0x01e0, 0x0040, + 0x46c5, 0x1078, 0x47ac, 0x0078, 0x4765, 0x7007, 0x0012, 0x2019, + 0x0000, 0x7108, 0x7008, 0xa106, 0x00c0, 0x46c9, 0xa184, 0x01e0, + 0x0040, 0x46d6, 0x1078, 0x47ac, 0x0078, 0x4765, 0x7810, 0xd0ec, + 0x0040, 0x46f0, 0x2001, 0x04fd, 0x2004, 0xa086, 0x0003, 0x00c0, + 0x46f4, 0xa184, 0x4000, 0x0040, 0x46f8, 0xa382, 0x0003, 0x00c8, + 0x46f8, 0xa184, 0x0004, 0x0040, 0x46c9, 0x8318, 0x0078, 0x46c9, + 0x7814, 0xd0ec, 0x00c0, 0x46f8, 0xa184, 0x4000, 0x00c0, 0x46c9, + 0xa19c, 0x300c, 0xa386, 0x2004, 0x0040, 0x4715, 0xa386, 0x0008, + 0x0040, 0x4720, 0x7004, 0xd084, 0x00c0, 0x4711, 0x7108, 0x7008, + 0xa106, 0x00c0, 0x4706, 0xa184, 0x0003, 0x0040, 0x4711, 0x0078, + 0x47ac, 0xa386, 0x200c, 0x00c0, 0x46c9, 0x7200, 0x8204, 0x0048, + 0x4720, 0x730c, 0xa384, 0x03ff, 0x0040, 0x4720, 0x1078, 0x296b, + 0x7108, 0x7008, 0xa106, 0x00c0, 0x4720, 0xa184, 0x01e0, 0x0040, + 0x472d, 0x1078, 0x47ac, 0x0078, 0x4765, 0x7007, 0x0012, 0x7000, + 0xd084, 0x00c0, 0x473d, 0x7310, 0x7014, 0xa305, 0x0040, 0x473d, + 0x710c, 0xa184, 0x03ff, 0x00c0, 0x46b4, 0x7108, 0x7008, 0xa106, + 0x00c0, 0x473d, 0xa184, 0x01e0, 0x0040, 0x474a, 0x1078, 0x47ac, + 0x0078, 0x4765, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xd09c, + 0x00c0, 0x474e, 0x7108, 0x7008, 0xa106, 0x00c0, 0x4752, 0xa184, + 0x01e0, 0x0040, 0x475f, 0x1078, 0x47ac, 0x0078, 0x4765, 0x7007, + 0x0012, 0x7108, 0x8103, 0x0048, 0x4752, 0x7003, 0x0008, 0x007c, + 0x7108, 0xa184, 0x01e0, 0x00c0, 0x47ac, 0x7108, 0xa184, 0x01e0, + 0x00c0, 0x47ac, 0xa184, 0x0007, 0x0079, 0x4776, 0x4780, 0x4790, + 0x477e, 0x4790, 0x477e, 0x47ee, 0x477e, 0x47ec, 0x1078, 0x296b, + 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, 0x00c0, 0x478b, + 0x2049, 0x0000, 0x007c, 0x1078, 0x4970, 0x00c0, 0x478b, 0x007c, + 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x7004, 0xd084, 0x00c0, + 0x47a4, 0x7108, 0x7008, 0xa106, 0x00c0, 0x4799, 0xa184, 0x0003, + 0x0040, 0x47a4, 0x0078, 0x47ac, 0x8aff, 0x0040, 0x47ab, 0x1078, + 0x4970, 0x00c0, 0x47a7, 0x007c, 0x7007, 0x0012, 0x7108, 0x00e0, + 0x47af, 0x2091, 0x6000, 0x00e0, 0x47b3, 0x2091, 0x6000, 0x7007, + 0x0012, 0x7007, 0x0008, 0x7004, 0xd09c, 0x00c0, 0x47bb, 0x7007, + 0x0012, 0x7108, 0xd1fc, 0x00c0, 0x47bf, 0x7003, 0x0000, 0x7000, + 0xa005, 0x00c0, 0x47d3, 0x7004, 0xa005, 0x00c0, 0x47d3, 0x700c, + 0xa005, 0x0040, 0x47d5, 0x0078, 0x47b7, 0x2049, 0x0000, 0xb284, + 0x0100, 0x0040, 0x47df, 0x2001, 0x0000, 0x0078, 0x47e1, 0x2001, + 0x0001, 0x1078, 0x4212, 0x681b, 0x0002, 0x2051, 0x0000, 0x007c, + 0x1078, 0x296b, 0x1078, 0x296b, 0x1078, 0x4836, 0x7210, 0x7114, + 0x700c, 0xa09c, 0x03ff, 0x2800, 0xa300, 0xa211, 0xa189, 0x0000, + 0x1078, 0x4836, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200, 0xa322, + 0x630c, 0x2100, 0xa31b, 0x2400, 0xa305, 0x0040, 0x4811, 0x00c8, + 0x4811, 0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0078, + 0x47f8, 0x2b60, 0x8a07, 0x007e, 0x6004, 0xa084, 0x0008, 0x0040, + 0x481d, 0xa7ba, 0x4668, 0x0078, 0x481f, 0xa7ba, 0x4660, 0x007f, + 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92, 0x6b8e, 0x7108, 0x7008, + 0xa106, 0x00c0, 0x4826, 0xa184, 0x01e0, 0x0040, 0x4831, 0x1078, + 0x47ac, 0x7007, 0x0012, 0x1078, 0x46b4, 0x007c, 0x8a50, 0x8739, + 0x2704, 0xa004, 0x00c0, 0x484a, 0x6000, 0xa064, 0x00c0, 0x4841, + 0x2d60, 0x6004, 0xa084, 0x000f, 0xa080, 0x467e, 0x203c, 0x87fb, + 0x1040, 0x296b, 0x007c, 0x127e, 0x0d7e, 0x70d4, 0xa084, 0x4600, + 0x8004, 0x2090, 0x0d7f, 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90, + 0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x007e, 0x6804, 0xa084, + 0x0008, 0x007f, 0x0040, 0x4868, 0xa0b8, 0x4668, 0x0078, 0x486a, + 0xa0b8, 0x4660, 0xb284, 0x0100, 0x0040, 0x4871, 0x7e20, 0x0078, + 0x4872, 0x7e24, 0xa6b5, 0x000c, 0x681c, 0xd0b4, 0x0040, 0x4879, + 0xc685, 0x2400, 0xa305, 0x0040, 0x48a3, 0x2c58, 0x2704, 0x6104, + 0xac60, 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e, 0xa184, + 0x0008, 0x0040, 0x4893, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014, + 0xa081, 0x0000, 0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c, + 0x2300, 0xa203, 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x1078, + 0x499b, 0x0078, 0x48a5, 0x1078, 0x4970, 0x00c0, 0x48a3, 0x127f, + 0x2000, 0x007c, 0x127e, 0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, + 0x2090, 0x0d7f, 0x7007, 0x0004, 0x7004, 0xd094, 0x00c0, 0x48b4, + 0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, 0x70d4, + 0xa084, 0x4600, 0x8004, 0x007e, 0x2090, 0x007f, 0x0d7f, 0x7e20, + 0xb284, 0x0100, 0x00c0, 0x48cd, 0x7e24, 0xa6b5, 0x000c, 0x681c, + 0xd0ac, 0x00c0, 0x48d8, 0xc685, 0x7003, 0x0000, 0x7007, 0x0004, + 0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x466e, + 0x273c, 0x87fb, 0x00c0, 0x48ee, 0x0048, 0x48e8, 0x1078, 0x296b, + 0x689c, 0xa065, 0x0040, 0x48f2, 0x0078, 0x48db, 0x1078, 0x4970, + 0x00c0, 0x48ee, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e, 0x017e, + 0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, 0x007e, 0x2090, 0x007f, + 0x7e20, 0xb284, 0x0100, 0x00c0, 0x4906, 0x7e24, 0x0d7f, 0x037f, + 0x047f, 0xa6b5, 0x000c, 0x681c, 0xd0b4, 0x0040, 0x4914, 0xc685, + 0x7003, 0x0000, 0x7007, 0x0004, 0x2049, 0x48f5, 0x6828, 0xa055, + 0x0d7e, 0x0040, 0x496c, 0x2d70, 0x2e60, 0x7004, 0xa0bc, 0x000f, + 0xa7b8, 0x466e, 0x273c, 0x87fb, 0x00c0, 0x4931, 0x0048, 0x492a, + 0x1078, 0x296b, 0x709c, 0xa075, 0x2060, 0x0040, 0x496c, 0x0078, + 0x491d, 0x2704, 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0048, + 0x494a, 0x8a51, 0x00c0, 0x493e, 0x1078, 0x296b, 0x8738, 0x2704, + 0xa005, 0x00c0, 0x4932, 0x709c, 0xa075, 0x2060, 0x0040, 0x496c, + 0x0078, 0x491d, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x6908, + 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, 0x00c8, 0x4959, 0x1078, + 0x296b, 0xb284, 0x0100, 0x0040, 0x4967, 0x2001, 0x4e04, 0x2004, + 0xd0ec, 0x00c0, 0x4967, 0x2071, 0x0050, 0x0078, 0x4969, 0x2071, + 0x0020, 0x0d7f, 0x0078, 0x4879, 0x0d7f, 0x127f, 0x2000, 0x007c, + 0x7008, 0x007e, 0xa084, 0x01e0, 0x007f, 0x0040, 0x4979, 0xa006, + 0x007c, 0xa084, 0x0003, 0xa086, 0x0003, 0x00c0, 0x4980, 0x007c, + 0x2704, 0xac78, 0x7800, 0x701a, 0x7804, 0x701e, 0x7808, 0x7012, + 0x780c, 0x7016, 0x6004, 0xa084, 0x0008, 0x0040, 0x4993, 0x7810, + 0x7022, 0x7814, 0x7026, 0x7602, 0x7004, 0xa084, 0x0010, 0xc085, + 0x7006, 0x2079, 0x4e00, 0x8a51, 0x0040, 0x49bf, 0x8738, 0x2704, + 0xa005, 0x00c0, 0x49b1, 0x609c, 0xa005, 0x0040, 0x49c0, 0x2060, + 0x6004, 0xa084, 0x000f, 0xa080, 0x466e, 0x203c, 0x87fb, 0x1040, + 0x296b, 0x7008, 0x007e, 0xa084, 0x01e0, 0x007f, 0x0040, 0x49bb, + 0xa006, 0x0078, 0x49c0, 0xa084, 0x0003, 0xa086, 0x0003, 0x007c, + 0x2051, 0x0000, 0x007c, 0x127e, 0x007e, 0x0d7e, 0x70d4, 0xa084, + 0x4600, 0x8004, 0x2090, 0x0d7f, 0x087f, 0x7108, 0xa184, 0x0003, + 0x00c0, 0x49d8, 0x6828, 0xa005, 0x0040, 0x49e8, 0x0078, 0x45a2, + 0x7108, 0xd1fc, 0x0040, 0x49e0, 0x1078, 0x4769, 0x0078, 0x49cd, + 0x7007, 0x0010, 0x7108, 0xd1fc, 0x0040, 0x49e2, 0x1078, 0x4769, + 0x7008, 0xa086, 0x0008, 0x00c0, 0x49cd, 0x7000, 0xa005, 0x00c0, + 0x49cd, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f, 0x2000, 0x007c, + 0x127e, 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, 0x70d4, 0xa084, + 0x4600, 0x8004, 0x2090, 0x0d7f, 0x2049, 0x49f8, 0xad80, 0x0011, + 0x20a0, 0xb284, 0x0100, 0x0040, 0x4a1b, 0x2001, 0x4e04, 0x2004, + 0xd0ec, 0x0040, 0x4a17, 0x2099, 0x0031, 0x0078, 0x4a1d, 0x2099, + 0x0032, 0x0078, 0x4a1d, 0x2099, 0x0031, 0x700c, 0xa084, 0x03ff, + 0x682a, 0x7007, 0x0008, 0x7007, 0x0002, 0x7003, 0x0001, 0x0040, + 0x4a2c, 0x8000, 0x80ac, 0x53a5, 0x700c, 0xa084, 0x03ff, 0x0040, + 0x4a38, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4a33, + 0x0c7f, 0x2049, 0x0000, 0x7003, 0x0000, 0x157f, 0x137f, 0x147f, + 0x127f, 0x2000, 0x007c, 0x2091, 0x8000, 0x2091, 0x6000, 0x78ac, + 0xa005, 0x00c0, 0x4a5a, 0x7974, 0x70d0, 0xa106, 0x00c0, 0x4a5a, + 0x781c, 0xa005, 0x0040, 0x4a5a, 0x781f, 0x0000, 0x0068, 0x4a5a, + 0x2091, 0x4080, 0x7830, 0x8001, 0x7832, 0x00c0, 0x4ae2, 0x7834, + 0x7832, 0x7810, 0xd0ec, 0x00c0, 0x4adb, 0x2061, 0x73c0, 0x2069, + 0x4e80, 0xc7fd, 0x68d0, 0xa005, 0x0040, 0x4a74, 0x8001, 0x68d2, + 0x00c0, 0x4a74, 0x1078, 0x4cb0, 0x6800, 0xa084, 0x000f, 0x0040, + 0x4a89, 0xa086, 0x0001, 0x0040, 0x4a89, 0x6844, 0xa00d, 0x0040, + 0x4a89, 0x2104, 0xa005, 0x0040, 0x4a89, 0x8001, 0x200a, 0x0040, + 0x4c23, 0x6814, 0xa005, 0x0040, 0x4aae, 0x8001, 0x6816, 0x00c0, + 0x4aae, 0x68a7, 0x0001, 0x0f7e, 0xd7fc, 0x00c0, 0x4aa3, 0x7810, + 0xd0ec, 0x0040, 0x4a9f, 0x2079, 0x0100, 0x0078, 0x4aa5, 0x2079, + 0x0200, 0x0078, 0x4aa5, 0x2079, 0x0100, 0x1078, 0x4383, 0x0f7f, + 0x6864, 0xa005, 0x0040, 0x4aae, 0x1078, 0x2628, 0x6880, 0xa005, + 0x0040, 0x4abb, 0x8001, 0x6882, 0x00c0, 0x4abb, 0x6867, 0x0000, + 0x68d4, 0xc0dd, 0x68d6, 0x68d4, 0xd0fc, 0x0040, 0x4ad8, 0xc0fc, + 0x68d6, 0x20a9, 0x0200, 0x6034, 0xa005, 0x0040, 0x4ad4, 0x8001, + 0x6036, 0x68d4, 0xc0fd, 0x68d6, 0x00c0, 0x4ad4, 0x6010, 0xa005, + 0x0040, 0x4ad4, 0x1078, 0x2628, 0xace0, 0x0010, 0x00f0, 0x4ac3, + 0xd7fc, 0x0040, 0x4ae2, 0x2061, 0x53c0, 0x2069, 0x4e40, 0xc7fc, + 0x0078, 0x4a6a, 0x1078, 0x4b1e, 0x7838, 0x8001, 0x783a, 0x00c0, + 0x4b04, 0x783c, 0x783a, 0x2061, 0x53c0, 0x2069, 0x4e40, 0xc7fc, + 0x680c, 0xa005, 0x0040, 0x4af6, 0x1078, 0x4b88, 0xd7fc, 0x00c0, + 0x4b04, 0x7810, 0xd0ec, 0x00c0, 0x4b04, 0x2061, 0x73c0, 0x2069, + 0x4e80, 0xc7fd, 0x0078, 0x4af0, 0x7814, 0xd0e4, 0x00c0, 0x4b08, + 0x7810, 0xd0cc, 0x0040, 0x4b1b, 0xd0ac, 0x00c0, 0x4b14, 0xd0a4, + 0x0040, 0x4b1b, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0068, 0x4b1a, + 0x1078, 0x2395, 0x007c, 0x2091, 0x8001, 0x007c, 0x7840, 0x8001, + 0x7842, 0x00c0, 0x4b87, 0x7844, 0x7842, 0x2069, 0x4e40, 0xc7fc, + 0x7810, 0x2079, 0x0200, 0xd0ec, 0x0040, 0x4b30, 0x2079, 0x0100, + 0x68d8, 0xa005, 0x0040, 0x4b3c, 0x7de0, 0xa504, 0x00c0, 0x4b3c, + 0x68da, 0x68d4, 0xc0bc, 0x68d6, 0x2079, 0x4e00, 0x6810, 0xa005, + 0x00c0, 0x4b44, 0x2001, 0x0101, 0x8001, 0x6812, 0xd7fc, 0x0040, + 0x4b4d, 0xa080, 0x94d0, 0x0078, 0x4b4f, 0xa080, 0x93c0, 0x2040, + 0x2004, 0xa065, 0x0040, 0x4b79, 0x6024, 0xa005, 0x0040, 0x4b75, + 0x8001, 0x6026, 0x00c0, 0x4b75, 0x6800, 0xa005, 0x0040, 0x4b68, + 0x684c, 0xac06, 0x00c0, 0x4b68, 0x1078, 0x4c23, 0x0078, 0x4b79, + 0x6864, 0xa005, 0x0040, 0x4b70, 0x6027, 0x0001, 0x0078, 0x4b75, + 0x1078, 0x4bd6, 0x2804, 0x0078, 0x4b51, 0x6000, 0x2c40, 0x0078, + 0x4b51, 0xd7fc, 0x00c0, 0x4b87, 0x7810, 0xd0ec, 0x00c0, 0x4b87, + 0x2069, 0x4e80, 0xc7fd, 0x2079, 0x0100, 0x0078, 0x4b30, 0x007c, + 0x2009, 0x0000, 0x20a9, 0x0200, 0x6008, 0xd09c, 0x0040, 0x4bc2, + 0x6024, 0xa005, 0x0040, 0x4b98, 0x8001, 0x6026, 0x0078, 0x4bc0, + 0x6008, 0xc09c, 0xd084, 0x00c0, 0x4ba0, 0xd0ac, 0x0040, 0x4bba, + 0x600a, 0x6004, 0xa005, 0x0040, 0x4bc2, 0x0d7e, 0x0c7e, 0x017e, + 0x2068, 0x6010, 0x8001, 0x6012, 0x1078, 0x3dd0, 0x2d00, 0x2c68, + 0x2060, 0x1078, 0x1e5b, 0x1078, 0x201d, 0x017f, 0x0c7f, 0x0d7f, + 0x0078, 0x4bc2, 0xc0bd, 0x600a, 0xa18d, 0x0001, 0x0078, 0x4bc2, + 0xa18d, 0x0100, 0xace0, 0x0010, 0x00f0, 0x4b8c, 0xa184, 0x0001, + 0x0040, 0x4bd1, 0xa18c, 0xfffe, 0x690e, 0x1078, 0x2628, 0x0078, + 0x4bd2, 0x690e, 0x007c, 0x00c0, 0x4bd2, 0x786c, 0x2c00, 0x687e, + 0x6714, 0x6f76, 0x6017, 0x0000, 0x602b, 0x0000, 0x601b, 0x0006, + 0x60b4, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, + 0x0060, 0x6022, 0x6000, 0x2042, 0x1078, 0x1de4, 0x6818, 0xa005, + 0x0040, 0x4bf4, 0x8001, 0x681a, 0x6808, 0xc0a4, 0x680a, 0x6810, + 0x7908, 0x8109, 0x790a, 0x8001, 0x00d0, 0x4c00, 0x1078, 0x296b, + 0x6812, 0x00c0, 0x4c06, 0x7910, 0xc1a5, 0x7912, 0x602f, 0x0000, + 0x6033, 0x0000, 0x2c68, 0x1078, 0x202c, 0xd7fc, 0x00c0, 0x4c14, + 0x2069, 0x4e40, 0x0078, 0x4c16, 0x2069, 0x4e80, 0x6910, 0xa184, + 0x0100, 0x2001, 0x0006, 0x00c0, 0x4c20, 0x697a, 0x2001, 0x0004, + 0x1078, 0x261c, 0x007c, 0x0d7e, 0x694c, 0x2160, 0xd7fc, 0x00c0, + 0x4c35, 0x7810, 0xd0ec, 0x0040, 0x4c31, 0x2069, 0x0100, 0x0078, + 0x4c37, 0x2069, 0x0200, 0x0078, 0x4c37, 0x2069, 0x0100, 0x1078, + 0x28df, 0x601b, 0x0006, 0x6858, 0xa084, 0x3f00, 0x601e, 0x6020, + 0xa084, 0x00ff, 0xa085, 0x0048, 0x6022, 0x602f, 0x0000, 0x6033, + 0x0000, 0x6808, 0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4, 0x0040, + 0x4c69, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xd094, 0x0040, + 0x4c5b, 0x00f0, 0x4c55, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, + 0xd084, 0x0040, 0x4c65, 0x00f0, 0x4c5f, 0x20a9, 0x00fa, 0x00f0, + 0x4c67, 0x681b, 0x0047, 0x0d7f, 0x6867, 0x0007, 0x007c, 0x2079, + 0x4e00, 0x1078, 0x4ca3, 0x1078, 0x4c89, 0x1078, 0x4c96, 0x2009, + 0x0002, 0x2069, 0x4e80, 0x680f, 0x0000, 0x6813, 0x0000, 0x6817, + 0x0000, 0x8109, 0x0040, 0x4c88, 0x2069, 0x4e40, 0x0078, 0x4c7b, + 0x007c, 0x7810, 0xd0ec, 0x0040, 0x4c91, 0x2019, 0x00cc, 0x0078, + 0x4c93, 0x2019, 0x007b, 0x7b3a, 0x7b3e, 0x007c, 0x7814, 0xd0e4, + 0x00c0, 0x4c9e, 0x2019, 0x0040, 0x0078, 0x4ca0, 0x2019, 0x0026, + 0x7b42, 0x7b46, 0x007c, 0x7814, 0xd0e4, 0x00c0, 0x4cab, 0x2019, + 0x3f94, 0x0078, 0x4cad, 0x2019, 0x2624, 0x7b32, 0x7b36, 0x007c, + 0x6a50, 0xa285, 0x0000, 0x0040, 0x4cdc, 0x6954, 0x6bc0, 0xa300, + 0x0c7e, 0x2164, 0x6304, 0x83ff, 0x00c0, 0x4cc8, 0x8211, 0x0040, + 0x4ccc, 0x8108, 0xa11a, 0x0048, 0x4cb9, 0x69c0, 0x0078, 0x4cb9, + 0x68d3, 0x000a, 0x0c7f, 0x007c, 0x6950, 0x6ac0, 0x2264, 0x602b, + 0x0000, 0x602f, 0x0000, 0x6008, 0xc0b5, 0x600a, 0x8210, 0x8109, + 0x00c0, 0x4cce, 0x6952, 0x0c7f, 0x007c, 0x00e0, 0x4cdd, 0x2091, + 0x6000, 0x00e0, 0x4ce1, 0x2091, 0x6000, 0x70ec, 0xd0dc, 0x00c0, + 0x4cee, 0xd0d4, 0x0040, 0x4d17, 0x0078, 0x4d1a, 0x2008, 0x7810, + 0xd0ec, 0x0040, 0x4d01, 0xd1c4, 0x00c0, 0x4d39, 0x7814, 0xc0c5, + 0x7816, 0x7810, 0xc0f5, 0x7812, 0xd0ec, 0x0040, 0x4d35, 0x0078, + 0x4d31, 0xae8e, 0x0100, 0x0040, 0x4d0e, 0x7814, 0xc0f5, 0xc0c5, + 0x7816, 0xd0d4, 0x00c0, 0x4d35, 0x0078, 0x4d31, 0x7814, 0xc0fd, + 0xc0c5, 0x7816, 0xd0d4, 0x00c0, 0x4d35, 0x0078, 0x4d31, 0xd0e4, + 0x0040, 0x4d37, 0x00e0, 0x4d1a, 0x2091, 0x6000, 0x2009, 0x000c, + 0x00e0, 0x4d20, 0x2091, 0x6000, 0x8109, 0x00c0, 0x4d20, 0x70e4, + 0xa084, 0x01ff, 0xa086, 0x01ff, 0x00c0, 0x4d31, 0x70ec, 0x0078, + 0x4cee, 0x7804, 0xd08c, 0x0040, 0x4d37, 0x681f, 0x000c, 0x70a0, + 0x70a2, 0x007c, 0x205b }; -unsigned short fw1280ei_length01 = 0x39e3; - +#ifdef UNIQUE_FW_NAME +unsigned short fw1280ei_length01 = 0x3d3b; +#else +unsigned short risc_code_length01 = 0x3d3b; +#endif Index: drivers/scsi/qla1280.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/qla1280.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/qla1280.c 22 Jul 2004 19:50:06 -0000 1.1 +++ drivers/scsi/qla1280.c 4 Aug 2004 01:29:36 -0000 1.2 @@ -1,165 +1,273 @@ -/******************************************************************************** - * QLOGIC LINUX SOFTWARE - * - * QLogic ISP1x80/1x160 device driver for Linux 2.3.x (redhat 6.X). - * - * COPYRIGHT (C) 1999-2000 QLOGIC CORPORATION - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the Qlogic's Linux Software License. See below. - * - * This program is WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistribution's or 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. - * - ********************************************************************************/ - -/***************************************************************************************** - QLOGIC CORPORATION SOFTWARE - "GNU" GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION - AND MODIFICATION - -This GNU General Public License ("License") applies solely to QLogic Linux -Software ("Software") and may be distributed under the terms of this License. - -1. You may copy and distribute verbatim copies of the Software's source code as -you receive it, in any medium, provided that you conspicuously and appropriately -publish on each copy an appropriate copyright notice and disclaimer of warranty; -keep intact all the notices that refer to this License and to the absence of any -warranty; and give any other recipients of the Software a copy of this License along -with the Software. - -You may charge a fee for the physical act of transferring a copy, and you may at your -option offer warranty protection in exchange for a fee. - -2. You may modify your copy or copies of the Software or any portion of it, thus forming -a work based on the Software, and copy and distribute such modifications or work under -the terms of Section 1 above, provided that you also meet all of these conditions: - -* a) You must cause the modified files to carry prominent notices stating that you -changed the files and the date of any change. - -* b) You must cause any work that you distribute or publish that in whole or in part -contains or is derived from the Software or any part thereof, to be licensed as a -whole at no charge to all third parties under the terms of this License. - -* c) If the modified Software normally reads commands interactively when run, you -must cause it, when started running for such interactive use in the most ordinary way, -to print or display an announcement including an appropriate copyright notice and a -notice that there is no warranty (or else, saying that you provide a warranty) and that -users may redistribute the Software under these conditions, and telling the user how to -view a copy of this License. (Exception:if the Software itself is interactive but does -not normally print such an announcement, your work based on the Software is not required -to print an announcement.) - -These requirements apply to the modified work as a whole. If identifiable sections of -that work are not derived from the Software, and can be reasonably considered independent -and separate works in themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you distribute the same -sections as part of a whole which is a work based on the Software, the distribution of the -whole must be on the terms of this License, whose permissions for other licensees extend -to the entire whole, and thus to each and every part regardless of who wrote it. - -3. You may copy and distribute the Software (or a work based on it, under Section 2) in -object code or executable form under the terms of Sections 1 and 2 above provided that -you also do one of the following: - -* a) Accompany it with the complete corresponding machine-readable source code, which must -be distributed under the terms of Sections 1 and 2 above on a medium customarily used for -software interchange; or, - -* b) Accompany it with a written offer, valid for at least three years, to give any third -party, for a charge no more than your cost of physically performing source distribution, -a complete machine-readable copy of the corresponding source code, to be distributed under -the terms of Sections 1 and 2 above on a medium customarily used for software interchange; -or, - -* c) Accompany it with the information you received as to the offer to distribute -corresponding source code. (This alternative is allowed only for noncommercial distribution -and only if you received the Software in object code or executable form with such an offer, -in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for making modifications -to it. For an executable work, complete source code means all the source code for all -modules it contains, plus any associated interface definition files, plus the scripts used -to control compilation and installation of the executable. - -If distribution of executable or object code is made by offering access to copy from a -designated place, then offering equivalent access to copy the source code from the same -place counts as distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - -4. You may not copy, modify, sublicense, or distribute the Software except as expressly -provided under this License. Any attempt otherwise to copy, modify, sublicense or -distribute the Software is void, and will automatically terminate your rights under this -License. However, parties who have received copies, or rights, from you under this License -will not have their licenses terminated so long as such parties remain in full compliance. - -5. This license grants you world wide, royalty free non-exclusive rights to modify or -distribute the Software or its derivative works. These actions are prohibited by law -if you do not accept this License. Therefore, by modifying or distributing the Software -(or any work based on the Software), you indicate your acceptance of this License to do -so, and all its terms and conditions for copying, distributing or modifying the Software -or works based on it. - -6. Each time you redistribute the Software (or any work based on the Software), the -recipient automatically receives a license from the original licensor to copy, distribute -or modify the Software subject to these terms and conditions. You may not impose any -further restrictions on the recipients' exercise of the rights granted herein. You are -not responsible for enforcing compliance by third parties to this License. - -7. If, as a consequence of a court judgment or allegation of patent infringement or for -any other reason (not limited to patent issues), conditions are imposed on you -(whether by court order, agreement or otherwise) that contradict the conditions of this -License, they do not excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this License -and any other pertinent obligations, then as a consequence you may not distribute the -Software at all. - -If any portion of this section is held invalid or unenforceable under any particular -circumstance, the balance of the section is intended to apply and the section as a whole -is intended to apply in other circumstances. -NO WARRANTY - -11. THE SOFTWARE IS PROVIDED WITHOUT A WARRANTY OF ANY KIND. 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. - -12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE SOFTWARE AS PERMITTED ABOVE, BE LIABLE TO YOU FOR -DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL -DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING -BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR -LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO -OPERATE WITH ANY OTHER SOFTWARES), EVEN IF SUCH HOLDER OR OTHER PARTY HAS -BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -END OF TERMS AND CONDITIONS - -*******************************************************************************************/ - -/**************************************************************************** +/****************************************************************************** +* QLOGIC LINUX SOFTWARE +* +* QLogic QLA1280 (Ultra2) and QLA12160 (Ultra3) SCSI driver +* Copyright (C) 2000 Qlogic Corporation (www.qlogic.com) +* Copyright (C) 2001-2003 Jes Sorensen, Wild Open Source 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, or (at your option) any +* later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +******************************************************************************/ +#define QLA1280_VERSION "3.23.37" +/***************************************************************************** Revision History: - Rev. 3.00 Jan 17, 1999 DG Qlogic + Rev 3.23.37 October 1, 2003, Jes Sorensen + - Make MMIO depend on CONFIG_X86_VISWS instead of yet another + random CONFIG option + - Clean up locking in probe path + Rev 3.23.36 October 1, 2003, Christoph Hellwig + - queuecommand only ever receives new commands - clear flags + - Reintegrate lost fixes from Linux 2.5 + Rev 3.23.35 August 14, 2003, Jes Sorensen + - Build against 2.6 + Rev 3.23.34 July 23, 2003, Jes Sorensen + - Remove pointless TRUE/FALSE macros + - Clean up vchan handling + Rev 3.23.33 July 3, 2003, Jes Sorensen + - Don't define register access macros before define determining MMIO. + This just happend to work out on ia64 but not elsewhere. + - Don't try and read from the card while it is in reset as + it won't respond and causes an MCA + Rev 3.23.32 June 23, 2003, Jes Sorensen + - Basic support for boot time arguments + Rev 3.23.31 June 8, 2003, Jes Sorensen + - Reduce boot time messages + Rev 3.23.30 June 6, 2003, Jes Sorensen + - Do not enable sync/wide/ppr before it has been determined + that the target device actually supports it + - Enable DMA arbitration for multi channel controllers + Rev 3.23.29 June 3, 2003, Jes Sorensen + - Port to 2.5.69 + Rev 3.23.28 June 3, 2003, Jes Sorensen + - Eliminate duplicate marker commands on bus resets + - Handle outstanding commands appropriately on bus/device resets + Rev 3.23.27 May 28, 2003, Jes Sorensen + - Remove bogus input queue code, let the Linux SCSI layer do the work + - Clean up NVRAM handling, only read it once from the card + - Add a number of missing default nvram parameters + Rev 3.23.26 Beta May 28, 2003, Jes Sorensen + - Use completion queue for mailbox commands instead of busy wait + Rev 3.23.25 Beta May 27, 2003, James Bottomley + - Migrate to use new error handling code + Rev 3.23.24 Beta May 21, 2003, James Bottomley + - Big endian support + - Cleanup data direction code + Rev 3.23.23 Beta May 12, 2003, Jes Sorensen + - Switch to using MMIO instead of PIO + Rev 3.23.22 Beta April 15, 2003, Jes Sorensen + - Fix PCI parity problem with 12160 during reset. + Rev 3.23.21 Beta April 14, 2003, Jes Sorensen + - Use pci_map_page()/pci_unmap_page() instead of map_single version. + Rev 3.23.20 Beta April 9, 2003, Jes Sorensen + - Remove < 2.4.x support + - Introduce HOST_LOCK to make the spin lock changes portable. + - Remove a bunch of idiotic and unnecessary typedef's + - Kill all leftovers of target-mode support which never worked anyway + Rev 3.23.19 Beta April 11, 2002, Linus Torvalds + - Do qla1280_pci_config() before calling request_irq() and + request_region() + - Use pci_dma_hi32() to handle upper word of DMA addresses instead + of large shifts + - Hand correct arguments to free_irq() in case of failure + Rev 3.23.18 Beta April 11, 2002, Jes Sorensen + - Run source through Lindent and clean up the output + Rev 3.23.17 Beta April 11, 2002, Jes Sorensen + - Update SCSI firmware to qla1280 v8.15.00 and qla12160 v10.04.32 + Rev 3.23.16 Beta March 19, 2002, Jes Sorensen + - Rely on mailbox commands generating interrupts - do not + run qla1280_isr() from ql1280_mailbox_command() + - Remove device_reg_t + - Integrate ql12160_set_target_parameters() with 1280 version + - Make qla1280_setup() non static + - Do not call qla1280_check_for_dead_scsi_bus() on every I/O request + sent to the card - this command pauses the firmare!!! + Rev 3.23.15 Beta March 19, 2002, Jes Sorensen + - Clean up qla1280.h - remove obsolete QL_DEBUG_LEVEL_x definitions + - Remove a pile of pointless and confusing (srb_t **) and + (scsi_lu_t *) typecasts + - Explicit mark that we do not use the new error handling (for now) + - Remove scsi_qla_host_t and use 'struct' instead + - Remove in_abort, watchdog_enabled, dpc, dpc_sched, bios_enabled, + pci_64bit_slot flags which weren't used for anything anyway + - Grab host->host_lock while calling qla1280_isr() from abort() + - Use spin_lock()/spin_unlock() in qla1280_intr_handler() - we + do not need to save/restore flags in the interrupt handler + - Enable interrupts early (before any mailbox access) in preparation + for cleaning up the mailbox handling + Rev 3.23.14 Beta March 14, 2002, Jes Sorensen + - Further cleanups. Remove all trace of QL_DEBUG_LEVEL_x and replace + it with proper use of dprintk(). + - Make qla1280_print_scsi_cmd() and qla1280_dump_buffer() both take + a debug level argument to determine if data is to be printed + - Add KERN_* info to printk() + Rev 3.23.13 Beta March 14, 2002, Jes Sorensen + - Significant cosmetic cleanups + - Change debug code to use dprintk() and remove #if mess + Rev 3.23.12 Beta March 13, 2002, Jes Sorensen + - More cosmetic cleanups, fix places treating return as function + - use cpu_relax() in qla1280_debounce_register() + Rev 3.23.11 Beta March 13, 2002, Jes Sorensen + - Make it compile under 2.5.5 + Rev 3.23.10 Beta October 1, 2001, Jes Sorensen + - Do no typecast short * to long * in QL1280BoardTbl, this + broke miserably on big endian boxes + Rev 3.23.9 Beta September 30, 2001, Jes Sorensen + - Remove pre 2.2 hack for checking for reentrance in interrupt handler + - Make data types used to receive from SCSI_{BUS,TCN,LUN}_32 + unsigned int to match the types from struct scsi_cmnd + Rev 3.23.8 Beta September 29, 2001, Jes Sorensen + - Remove bogus timer_t typedef from qla1280.h + - Remove obsolete pre 2.2 PCI setup code, use proper #define's + for PCI_ values, call pci_set_master() + - Fix memleak of qla1280_buffer on module unload + - Only compile module parsing code #ifdef MODULE - should be + changed to use individual MODULE_PARM's later + - Remove dummy_buffer that was never modified nor printed + - ENTER()/LEAVE() are noops unless QL_DEBUG_LEVEL_3, hence remove + #ifdef QL_DEBUG_LEVEL_3/#endif around ENTER()/LEAVE() calls + - Remove \r from print statements, this is Linux, not DOS + - Remove obsolete QLA1280_{SCSILU,INTR,RING}_{LOCK,UNLOCK} + dummy macros + - Remove C++ compile hack in header file as Linux driver are not + supposed to be compiled as C++ + - Kill MS_64BITS macro as it makes the code more readable + - Remove unnecessary flags.in_interrupts bit + Rev 3.23.7 Beta August 20, 2001, Jes Sorensen + - Dont' check for set flags on q->q_flag one by one in qla1280_next() + - Check whether the interrupt was generated by the QLA1280 before + doing any processing + - qla1280_status_entry(): Only zero out part of sense_buffer that + is not being copied into + - Remove more superflouous typecasts + - qla1280_32bit_start_scsi() replace home-brew memcpy() with memcpy() + Rev 3.23.6 Beta August 20, 2001, Tony Luck, Intel + - Don't walk the entire list in qla1280_putq_t() just to directly + grab the pointer to the last element afterwards + Rev 3.23.5 Beta August 9, 2001, Jes Sorensen + - Don't use SA_INTERRUPT, it's use is deprecated for this kinda driver + Rev 3.23.4 Beta August 8, 2001, Jes Sorensen + - Set dev->max_sectors to 1024 + Rev 3.23.3 Beta August 6, 2001, Jes Sorensen + - Provide compat macros for pci_enable_device(), pci_find_subsys() + and scsi_set_pci_device() + - Call scsi_set_pci_device() for all devices + - Reduce size of kernel version dependent device probe code + - Move duplicate probe/init code to separate function + - Handle error if qla1280_mem_alloc() fails + - Kill OFFSET() macro and use Linux's PCI definitions instead + - Kill private structure defining PCI config space (struct config_reg) + - Only allocate I/O port region if not in MMIO mode + - Remove duplicate (unused) sanity check of sife of srb_t + Rev 3.23.2 Beta August 6, 2001, Jes Sorensen + - Change home-brew memset() implementations to use memset() + - Remove all references to COMTRACE() - accessing a PC's COM2 serial + port directly is not legal under Linux. + Rev 3.23.1 Beta April 24, 2001, Jes Sorensen + - Remove pre 2.2 kernel support + - clean up 64 bit DMA setting to use 2.4 API (provide backwards compat) + - Fix MMIO access to use readl/writel instead of directly + dereferencing pointers + - Nuke MSDOS debugging code + - Change true/false data types to int from uint8_t + - Use int for counters instead of uint8_t etc. + - Clean up size & byte order conversion macro usage + Rev 3.23 Beta January 11, 2001 BN Qlogic + - Added check of device_id when handling non + QLA12160s during detect(). + Rev 3.22 Beta January 5, 2001 BN Qlogic + - Changed queue_task() to schedule_task() + for kernels 2.4.0 and higher. + Note: 2.4.0-testxx kernels released prior to + the actual 2.4.0 kernel release on January 2001 + will get compile/link errors with schedule_task(). + Please update your kernel to released 2.4.0 level, + or comment lines in this file flagged with 3.22 + to resolve compile/link error of schedule_task(). + - Added -DCONFIG_SMP in addition to -D__SMP__ + in Makefile for 2.4.0 builds of driver as module. + Rev 3.21 Beta January 4, 2001 BN Qlogic + - Changed criteria of 64/32 Bit mode of HBA + operation according to BITS_PER_LONG rather + than HBA's NVRAM setting of >4Gig memory bit; + so that the HBA auto-configures without the need + to setup each system individually. + Rev 3.20 Beta December 5, 2000 BN Qlogic + - Added priority handling to IA-64 onboard SCSI + ISP12160 chip for kernels greater than 2.3.18. + - Added irqrestore for qla1280_intr_handler. + - Enabled /proc/scsi/qla1280 interface. + - Clear /proc/scsi/qla1280 counters in detect(). + Rev 3.19 Beta October 13, 2000 BN Qlogic + - Declare driver_template for new kernel + (2.4.0 and greater) scsi initialization scheme. + - Update /proc/scsi entry for 2.3.18 kernels and + above as qla1280 + Rev 3.18 Beta October 10, 2000 BN Qlogic + - Changed scan order of adapters to map + the QLA12160 followed by the QLA1280. + Rev 3.17 Beta September 18, 2000 BN Qlogic + - Removed warnings for 32 bit 2.4.x compiles + - Corrected declared size for request and response + DMA addresses that are kept in each ha + Rev. 3.16 Beta August 25, 2000 BN Qlogic + - Corrected 64 bit addressing issue on IA-64 + where the upper 32 bits were not properly + passed to the RISC engine. + Rev. 3.15 Beta August 22, 2000 BN Qlogic + - Modified qla1280_setup_chip to properly load + ISP firmware for greater that 4 Gig memory on IA-64 + Rev. 3.14 Beta August 16, 2000 BN Qlogic + - Added setting of dma_mask to full 64 bit + if flags.enable_64bit_addressing is set in NVRAM + Rev. 3.13 Beta August 16, 2000 BN Qlogic + - Use new PCI DMA mapping APIs for 2.4.x kernel + Rev. 3.12 July 18, 2000 Redhat & BN Qlogic + - Added check of pci_enable_device to detect() for 2.3.x + - Use pci_resource_start() instead of + pdev->resource[0].start in detect() for 2.3.x + - Updated driver version + Rev. 3.11 July 14, 2000 BN Qlogic + - Updated SCSI Firmware to following versions: + qla1x80: 8.13.08 + qla1x160: 10.04.08 + - Updated driver version to 3.11 + Rev. 3.10 June 23, 2000 BN Qlogic + - Added filtering of AMI SubSys Vendor ID devices + Rev. 3.9 + - DEBUG_QLA1280 undefined and new version BN Qlogic + Rev. 3.08b May 9, 2000 MD Dell + - Added logic to check against AMI subsystem vendor ID + Rev. 3.08 May 4, 2000 DG Qlogic + - Added logic to check for PCI subsystem ID. + Rev. 3.07 Apr 24, 2000 DG & BN Qlogic + - Updated SCSI Firmware to following versions: + qla12160: 10.01.19 + qla1280: 8.09.00 + Rev. 3.06 Apr 12, 2000 DG & BN Qlogic + - Internal revision; not released + Rev. 3.05 Mar 28, 2000 DG & BN Qlogic + - Edit correction for virt_to_bus and PROC. + Rev. 3.04 Mar 28, 2000 DG & BN Qlogic + - Merge changes from ia64 port. + Rev. 3.03 Mar 28, 2000 BN Qlogic + - Increase version to reflect new code drop with compile fix + of issue with inclusion of linux/spinlock for 2.3 kernels + Rev. 3.02 Mar 15, 2000 BN Qlogic + - Merge qla1280_proc_info from 2.10 code base + Rev. 3.01 Feb 10, 2000 BN Qlogic + - Corrected code to compile on a 2.2.x kernel. + Rev. 3.00 Jan 17, 2000 DG Qlogic - Added 64-bit support. Rev. 2.07 Nov 9, 1999 DG Qlogic - - Added new routine to set target parameters for ISP12160. + - Added new routine to set target parameters for ISP12160. Rev. 2.06 Sept 10, 1999 DG Qlogic - Added support for ISP12160 Ultra 3 chip. Rev. 2.03 August 3, 1999 Fred Lewis, Intel DuPont @@ -173,27 +281,19 @@ - Added l modifiers to sprintf and printk format specifiers for longs. - Removed unused local variables. Rev. 1.20 June 8, 1999 DG, Qlogic - Changes to support RedHat release 6.0 (kernel 2.2.5). - - Added SCSI exclusive access lock (io_request_lock) when accessing + Changes to support RedHat release 6.0 (kernel 2.2.5). + - Added SCSI exclusive access lock (io_request_lock) when accessing the adapter. - Added changes for the new LINUX interface template. Some new error handling routines have been added to the template, but for now we will use the old ones. - - Initial Beta Release. + - Initial Beta Release. *****************************************************************************/ -#ifdef MODULE +#include #include -#endif -#define QLA1280_VERSION " 3.00-Beta" - -#include -#include -#include -#include -#include #include #include #include @@ -205,226 +305,253 @@ #include #include #include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#if LINUX_VERSION_CODE >= 0x020545 +#include +#include "scsi.h" +#else #include -#include -/* MRS #include */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) -# include -#endif -#include "sd.h" #include "scsi.h" #include "hosts.h" -#define UNIQUE_FW_NAME -#include "qla1280.h" -#include "ql12160_fw.h" /* ISP RISC code */ -#include "ql1280_fw.h" +#include "sd.h" +#endif -#include -#include /* for kmalloc() */ +#if LINUX_VERSION_CODE < 0x020407 +#error "Kernels older than 2.4.7 are no longer supported" +#endif -#ifndef KERNEL_VERSION -# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) -#endif +/* + * Compile time Options: + * 0 - Disable and 1 - Enable + */ +#define QL1280_LUN_SUPPORT 0 +#define WATCHDOGTIMER 0 +#define DEBUG_QLA1280_INTR 0 +#define DEBUG_PRINT_NVRAM 0 +#define DEBUG_QLA1280 0 /* - * Compile time Options: - * 0 - Disable and 1 - Enable + * The SGI VISWS is broken and doesn't support MMIO ;-( */ -#define QLA1280_64BIT_SUPPORT 1 /* 64-bit Support */ -#define QL1280_TARGET_MODE_SUPPORT 0 /* Target mode support */ -#define WATCHDOGTIMER 0 -#define MEMORY_MAPPED_IO 0 -#define DEBUG_QLA1280_INTR 0 -#define USE_NVRAM_DEFAULTS 0 -#define DEBUG_PRINT_NVRAM 0 -#define LOADING_RISC_ACTIVITY 0 -#define AUTO_ESCALATE_RESET 0 /* Automatically escalate resets */ -#define AUTO_ESCALATE_ABORT 0 /* Automatically escalate aborts */ -#define STOP_ON_ERROR 0 /* Stop on aborts and resets */ -#define STOP_ON_RESET 0 -#define STOP_ON_ABORT 0 -#undef DYNAMIC_MEM_ALLOC +#ifdef CONFIG_X86_VISWS +#define MEMORY_MAPPED_IO 0 +#else +#define MEMORY_MAPPED_IO 1 +#endif + +#define UNIQUE_FW_NAME +#include "qla1280.h" +#include "ql12160_fw.h" /* ISP RISC codes */ +#include "ql1280_fw.h" -#define DEBUG_QLA1280 0 /* Debugging */ -/* #define CHECKSRBSIZE */ /* - * These macros to assist programming + * Missing PCI ID's */ +#ifndef PCI_DEVICE_ID_QLOGIC_ISP1080 +#define PCI_DEVICE_ID_QLOGIC_ISP1080 0x1080 +#endif +#ifndef PCI_DEVICE_ID_QLOGIC_ISP1240 +#define PCI_DEVICE_ID_QLOGIC_ISP1240 0x1240 +#endif +#ifndef PCI_DEVICE_ID_QLOGIC_ISP1280 +#define PCI_DEVICE_ID_QLOGIC_ISP1280 0x1280 +#endif +#ifndef PCI_DEVICE_ID_QLOGIC_ISP10160 +#define PCI_DEVICE_ID_QLOGIC_ISP10160 0x1016 +#endif +#ifndef PCI_DEVICE_ID_QLOGIC_ISP12160 +#define PCI_DEVICE_ID_QLOGIC_ISP12160 0x1216 +#endif -#define BZERO(ptr, amt) memset(ptr, 0, amt) -#define BCOPY(src, dst, amt) memcpy(dst, src, amt) -#define KMALLOC(siz) kmalloc((siz), GFP_ATOMIC) -#define KMFREE(ip,siz) kfree((ip)) -#define SYS_DELAY(x) udelay(x);barrier() -#define QLA1280_DELAY(sec) mdelay(sec * 1000) -#define VIRT_TO_BUS(a) virt_to_bus((a)) -#if QLA1280_64BIT_SUPPORT -#if BITS_PER_LONG <= 32 -#define VIRT_TO_BUS_LOW(a) (uint32_t)virt_to_bus((a)) -#define VIRT_TO_BUS_HIGH(a) (uint32_t)(0x0) -#else -#define VIRT_TO_BUS_LOW(a) (uint32_t)(0xffffffff & virt_to_bus((a))) -#define VIRT_TO_BUS_HIGH(a) (uint32_t)(0xffffffff & (virt_to_bus((a))>>32)) +#ifndef PCI_VENDOR_ID_AMI +#define PCI_VENDOR_ID_AMI 0x101e #endif -#endif /* QLA1280_64BIT_SUPPORT */ -#define STATIC +#ifndef BITS_PER_LONG +#error "BITS_PER_LONG not defined!" +#endif +#if (BITS_PER_LONG == 64) || defined CONFIG_HIGHMEM +#define QLA_64BIT_PTR 1 +#endif -#define NVRAM_DELAY() udelay(500) /* 2 microsecond delay */ -void qla1280_device_queue_depth(scsi_qla_host_t *, Scsi_Device *); +#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) +#include +/* Ugly hack needed for the virtual channel fix on SN2 */ +extern int snia_pcibr_rrb_alloc(struct pci_dev *pci_dev, + int *count_vchan0, int *count_vchan1); +#endif -#define CACHE_FLUSH(a) (RD_REG_WORD(a)) -#define INVALID_HANDLE (MAX_OUTSTANDING_COMMANDS+1) +#ifdef QLA_64BIT_PTR +#define pci_dma_hi32(a) ((a >> 16) >> 16) +#else +#define pci_dma_hi32(a) 0 +#endif +#define pci_dma_lo32(a) (a & 0xffffffff) -#define MSW(x) (uint16_t)((uint32_t)(x) >> 16) -#define LSW(x) (uint16_t)(x) -#define MSB(x) (uint8_t)((uint16_t)(x) >> 8) -#define LSB(x) (uint8_t)(x) +#define NVRAM_DELAY() udelay(500) /* 2 microseconds */ -#if BITS_PER_LONG <= 32 -#define LS_64BITS(x) (uint32_t)(x) -#define MS_64BITS(x) (uint32_t)(0x0) +#if LINUX_VERSION_CODE < 0x020417 +/* Compat already available in 2.4.23 */ +#define irqreturn_t void +#define IRQ_RETVAL(foo) +#endif +#if LINUX_VERSION_CODE < 0x020500 +#define HOST_LOCK &io_request_lock +#define MSG_ORDERED_TAG 1 +static inline void +scsi_adjust_queue_depth(Scsi_Device *device, int tag, int depth) +{ + if (tag) { + device->tagged_queue = tag; + device->current_tag = 0; + } + device->queue_depth = depth; +} +#else +#define HOST_LOCK ha->host->host_lock +#endif +#if LINUX_VERSION_CODE < 0x020600 +#define DEV_SIMPLE_TAGS(device) device->tagged_queue #else -#define LS_64BITS(x) (uint32_t)(0xffffffff & (x)) -#define MS_64BITS(x) (uint32_t)(0xffffffff & ((x)>>32) ) +#define DEV_SIMPLE_TAGS(device) device->simple_tags +#endif +#if defined(__ia64__) && !defined(ia64_platform_is) +#define ia64_platform_is(foo) (!strcmp(x, platform_name)) #endif /* * QLogic Driver Support Function Prototypes. */ -STATIC void qla1280_done(scsi_qla_host_t *, srb_t **, srb_t **); -STATIC void qla1280_next(scsi_qla_host_t *, scsi_lu_t *, uint8_t); -STATIC void qla1280_putq_t(scsi_lu_t *, srb_t *); -STATIC void qla1280_done_q_put(srb_t *, srb_t **, srb_t **); -STATIC void qla1280_select_queue_depth(struct Scsi_Host *, Scsi_Device *); -#ifdef QLA1280_UNUSED -static void qla1280_dump_regs(struct Scsi_Host *host); -#endif -#if STOP_ON_ERROR -static void qla1280_panic(char *, struct Scsi_Host *host); -#endif -void qla1280_print_scsi_cmd(Scsi_Cmnd *cmd); -STATIC void qla1280_abort_queue_single(scsi_qla_host_t *,uint32_t,uint32_t,uint32_t,uint32_t); - -STATIC int qla1280_return_status( sts_entry_t *sts, Scsi_Cmnd *cp); -STATIC void qla1280_removeq(scsi_lu_t *q, srb_t *sp); -STATIC void qla1280_mem_free(scsi_qla_host_t *ha); -static void qla1280_do_dpc(void *p); -#ifdef QLA1280_UNUSED -static void qla1280_set_flags(char * s); -#endif -static char *qla1280_get_token(char *, char *); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) -STATIC inline void mdelay(int); +static void qla1280_done(struct scsi_qla_host *, struct srb **, struct srb **); +static void qla1280_done_q_put(struct srb *, struct srb **, struct srb **); +static int qla1280_slave_configure(Scsi_Device *); +#if LINUX_VERSION_CODE < 0x020545 +static void qla1280_select_queue_depth(struct Scsi_Host *, Scsi_Device *); +static void qla1280_get_target_options(struct scsi_cmnd *, struct scsi_qla_host *); #endif -static inline void qla1280_enable_intrs(scsi_qla_host_t *); -static inline void qla1280_disable_intrs(scsi_qla_host_t *); + +static int qla1280_return_status(struct response * sts, Scsi_Cmnd * cp); +static void qla1280_mem_free(struct scsi_qla_host *ha); +static int qla1280_get_token(char *); +static int qla1280_setup(char *s) __init; +static inline void qla1280_enable_intrs(struct scsi_qla_host *); +static inline void qla1280_disable_intrs(struct scsi_qla_host *); /* * QLogic ISP1280 Hardware Support Function Prototypes. */ -STATIC uint8_t qla1280_initialize_adapter(struct scsi_qla_host *ha); -STATIC uint8_t qla1280_enable_tgt(scsi_qla_host_t *, uint8_t); -STATIC uint8_t qla1280_isp_firmware(scsi_qla_host_t *); -STATIC uint8_t qla1280_pci_config(scsi_qla_host_t *); -STATIC uint8_t qla1280_chip_diag(scsi_qla_host_t *); -STATIC uint8_t qla1280_setup_chip(scsi_qla_host_t *); -STATIC uint8_t qla1280_init_rings(scsi_qla_host_t *); -STATIC uint8_t qla1280_nvram_config(scsi_qla_host_t *); -STATIC uint8_t qla1280_mailbox_command(scsi_qla_host_t *, uint8_t, uint16_t *); -STATIC uint8_t qla1280_bus_reset(scsi_qla_host_t *, uint8_t); -STATIC uint8_t qla1280_device_reset(scsi_qla_host_t *, uint8_t, uint32_t); -STATIC uint8_t qla1280_abort_device(scsi_qla_host_t *, uint8_t, uint32_t, uint32_t); -STATIC uint8_t qla1280_abort_command(scsi_qla_host_t *, srb_t *), -#if QLA1280_64BIT_SUPPORT - qla1280_64bit_start_scsi(scsi_qla_host_t *, srb_t *), -#endif - qla1280_32bit_start_scsi(scsi_qla_host_t *, srb_t *), - qla1280_abort_isp(scsi_qla_host_t *); -STATIC void qla1280_nv_write(scsi_qla_host_t *, uint16_t), - qla1280_nv_delay(scsi_qla_host_t *), - qla1280_poll(scsi_qla_host_t *), - qla1280_reset_adapter(scsi_qla_host_t *), - qla1280_marker(scsi_qla_host_t *, uint8_t, uint32_t, uint32_t, uint8_t), - qla1280_isp_cmd(scsi_qla_host_t *), - qla1280_isr(scsi_qla_host_t *, srb_t **, srb_t **), - qla1280_rst_aen(scsi_qla_host_t *), - qla1280_status_entry(scsi_qla_host_t *, sts_entry_t *, srb_t **, - srb_t **), - qla1280_error_entry(scsi_qla_host_t *, response_t *, srb_t **, - srb_t **), - qla1280_restart_queues(scsi_qla_host_t *), - qla1280_abort_queues(scsi_qla_host_t *); -STATIC uint16_t qla1280_get_nvram_word(scsi_qla_host_t *, uint32_t), - qla1280_nvram_request(scsi_qla_host_t *, uint32_t), - qla1280_debounce_register(volatile uint16_t *); -STATIC request_t *qla1280_req_pkt(scsi_qla_host_t *); -int qla1280_check_for_dead_scsi_bus(scsi_qla_host_t *ha, srb_t *sp); -STATIC uint8_t qla1280_mem_alloc(scsi_qla_host_t *ha); -STATIC uint8_t qla1280_register_with_Linux(scsi_qla_host_t *ha, uint8_t maxchannels); - -STATIC uint8_t qla12160_set_target_parameters(scsi_qla_host_t *, uint32_t, uint32_t, uint32_t, nvram160_t *); -STATIC void qla12160_get_target_parameters(scsi_qla_host_t *, uint32_t, uint32_t, uint32_t); - -#if QL1280_TARGET_MODE_SUPPORT -STATIC void qla1280_enable_lun(scsi_qla_host_t *, uint8_t, uint32_t), - qla1280_notify_ack(scsi_qla_host_t *, notify_entry_t *), - qla1280_immed_notify(scsi_qla_host_t *, notify_entry_t *), - qla1280_accept_io(scsi_qla_host_t *, ctio_ret_entry_t *), -#if QLA1280_64BIT_SUPPORT - qla1280_64bit_continue_io(scsi_qla_host_t *, atio_entry_t *, uint32_t, - paddr32_t *), -#endif - qla1280_32bit_continue_io(scsi_qla_host_t *, atio_entry_t *, uint32_t, - paddr32_t *), - qla1280_atio_entry(scsi_qla_host_t *, atio_entry_t *), - qla1280_notify_entry(scsi_qla_host_t *, notify_entry_t *); -#endif /* QLA1280_TARGET_MODE_SUPPORT */ - -#ifdef QL_DEBUG_ROUTINES -/* - * Driver Debug Function Prototypes. - */ -STATIC uint8_t qla1280_getbyte(uint8_t *); -STATIC uint16_t qla1280_getword(uint16_t *); -STATIC uint32_t qla1280_getdword(uint32_t *); -STATIC void qla1280_putbyte(uint8_t *, uint8_t), - qla1280_putword(uint16_t *, uint16_t), - qla1280_putdword(uint32_t *, uint32_t), - qla1280_print(caddr_t), - qla1280_output_number(uint32_t, uint8_t), - qla1280_putc(uint8_t), - qla1280_dump_buffer(caddr_t, uint32_t); - -char debug_buff[80]; -#if DEBUG_QLA1280 -STATIC uint8_t ql_debug_print = 1; -#else -STATIC uint8_t ql_debug_print = 0; +static int qla1280_initialize_adapter(struct scsi_qla_host *ha); +static int qla1280_isp_firmware(struct scsi_qla_host *); +static int qla1280_pci_config(struct scsi_qla_host *); +static int qla1280_chip_diag(struct scsi_qla_host *); +static int qla1280_setup_chip(struct scsi_qla_host *); +static int qla1280_init_rings(struct scsi_qla_host *); +static int qla1280_nvram_config(struct scsi_qla_host *); +static int qla1280_mailbox_command(struct scsi_qla_host *, + uint8_t, uint16_t *); +static int qla1280_bus_reset(struct scsi_qla_host *, int); +static int qla1280_device_reset(struct scsi_qla_host *, int, int); +static int qla1280_abort_device(struct scsi_qla_host *, int, int, int); +static int qla1280_abort_command(struct scsi_qla_host *, struct srb *, int); +static int qla1280_abort_isp(struct scsi_qla_host *); +static int qla1280_64bit_start_scsi(struct scsi_qla_host *, struct srb *); +static int qla1280_32bit_start_scsi(struct scsi_qla_host *, struct srb *); +static void qla1280_nv_write(struct scsi_qla_host *, uint16_t); +static void qla1280_poll(struct scsi_qla_host *); +static void qla1280_reset_adapter(struct scsi_qla_host *); +static void qla1280_marker(struct scsi_qla_host *, int, int, int, u8); +static void qla1280_isp_cmd(struct scsi_qla_host *); +irqreturn_t qla1280_intr_handler(int, void *, struct pt_regs *); +static void qla1280_isr(struct scsi_qla_host *, struct srb **, struct srb **); +static void qla1280_rst_aen(struct scsi_qla_host *); +static void qla1280_status_entry(struct scsi_qla_host *, struct response *, + struct srb **, struct srb **); +static void qla1280_error_entry(struct scsi_qla_host *, struct response *, + struct srb **, struct srb **); +static uint16_t qla1280_get_nvram_word(struct scsi_qla_host *, uint32_t); +static uint16_t qla1280_nvram_request(struct scsi_qla_host *, uint32_t); +static uint16_t qla1280_debounce_register(volatile uint16_t *); +static request_t *qla1280_req_pkt(struct scsi_qla_host *); +static int qla1280_check_for_dead_scsi_bus(struct scsi_qla_host *, + unsigned int); +static int qla1280_mem_alloc(struct scsi_qla_host *ha); + +static void qla12160_get_target_parameters(struct scsi_qla_host *, + Scsi_Device *); +static int qla12160_set_target_parameters(struct scsi_qla_host *, int, int); + + +static struct qla_driver_setup driver_setup __initdata; + +/* + * convert scsi data direction to request_t control flags + */ +static inline uint16_t +qla1280_data_direction(struct scsi_cmnd *cmnd) +{ + uint16_t flags = 0; + + switch(cmnd->sc_data_direction) { + + case SCSI_DATA_NONE: + flags = 0; + break; + + case SCSI_DATA_READ: + flags = BIT_5; + break; + + case SCSI_DATA_WRITE: + flags = BIT_6; + break; + + case SCSI_DATA_UNKNOWN: + default: + flags = BIT_5 | BIT_6; + break; + } + return flags; +} + +#if QL1280_LUN_SUPPORT +static void qla1280_enable_lun(struct scsi_qla_host *, int, int); #endif + +#if DEBUG_QLA1280 +static void __qla1280_print_scsi_cmd(Scsi_Cmnd * cmd); +static void __qla1280_dump_buffer(char *, int); #endif + /* * insmod needs to find the variable and make it point to something */ #ifdef MODULE -static char *options = NULL; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,18) +static char *qla1280; /* insmod qla1280 options=verbose" */ -MODULE_PARM(options, "s"); +MODULE_PARM(qla1280, "s"); +#else +__setup("qla1280=", qla1280_setup); #endif -/* - * 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 add commas in your insmod command!!\n"; -#endif +MODULE_LICENSE("GPL"); + /* We use the Scsi_Pointer structure that's included with each command * SCSI_Cmnd as a scratchpad for our SRB. @@ -440,122 +567,88 @@ * - SCp.phase --> not used */ -#define CMD_SP(Cmnd) (&(Cmnd)->SCp) -#define CMD_XFRLEN(Cmnd) (Cmnd)->request_bufflen -#define CMD_CDBLEN(Cmnd) (Cmnd)->cmd_len -#define CMD_CDBP(Cmnd) (Cmnd)->cmnd -#define CMD_SNSP(Cmnd) (Cmnd)->sense_buffer -#define CMD_SNSLEN(Cmnd) (sizeof (Cmnd)->sense_buffer) -#define CMD_RESULT(Cmnd) ((Cmnd)->result) -#define CMD_HANDLE(Cmnd) ((Cmnd)->host_scribble) +#define CMD_SP(Cmnd) &Cmnd->SCp +#define CMD_CDBLEN(Cmnd) Cmnd->cmd_len +#define CMD_CDBP(Cmnd) Cmnd->cmnd +#define CMD_SNSP(Cmnd) Cmnd->sense_buffer +#define CMD_SNSLEN(Cmnd) sizeof(Cmnd->sense_buffer) +#define CMD_RESULT(Cmnd) Cmnd->result +#define CMD_HANDLE(Cmnd) Cmnd->host_scribble +#if LINUX_VERSION_CODE < 0x020545 +#define CMD_HOST(Cmnd) Cmnd->host +#define CMD_REQUEST(Cmnd) Cmnd->request.cmd +#define SCSI_BUS_32(Cmnd) Cmnd->channel +#define SCSI_TCN_32(Cmnd) Cmnd->target +#define SCSI_LUN_32(Cmnd) Cmnd->lun +#else +#define CMD_HOST(Cmnd) Cmnd->device->host +#define CMD_REQUEST(Cmnd) Cmnd->request->cmd +#define SCSI_BUS_32(Cmnd) Cmnd->device->channel +#define SCSI_TCN_32(Cmnd) Cmnd->device->id +#define SCSI_LUN_32(Cmnd) Cmnd->device->lun +#endif /*****************************************/ /* ISP Boards supported by this driver */ /*****************************************/ -#define QLA1280_VENDOR_ID 0x1077 -#define QLA1080_DEVICE_ID 0x1080 -#define QLA1240_DEVICE_ID 0x1240 -#define QLA1280_DEVICE_ID 0x1280 -#define QLA12160_DEVICE_ID 0x1216 -#define QLA10160_DEVICE_ID 0x1016 -#define NUM_OF_ISP_DEVICES 6 - -typedef struct _qlaboards -{ - unsigned char bdName[9]; /* Board ID String */ - unsigned long device_id; /* Device PCI ID */ - int numPorts; /* Number of SCSI ports */ - unsigned short *fwcode; /* pointer to FW array */ - unsigned long *fwlen; /* number of words in array */ - unsigned short *fwstart; /* start address for F/W */ - unsigned char *fwver; /* Ptr to F/W version array */ -} qla_boards_t; - -struct _qlaboards QLBoardTbl[NUM_OF_ISP_DEVICES] = -{ - /* Name , Board PCI Device ID, Number of ports */ - {"QLA1080 ", QLA1080_DEVICE_ID, 1, - &fw1280ei_code01[0], (unsigned long *)&fw1280ei_length01,&fw1280ei_addr01, &fw1280ei_version_str[0] }, - {"QLA1240 ", QLA1240_DEVICE_ID, 2, - &fw1280ei_code01[0], (unsigned long *)&fw1280ei_length01,&fw1280ei_addr01, &fw1280ei_version_str[0] }, - {"QLA1280 ", QLA1280_DEVICE_ID, 2, - &fw1280ei_code01[0], (unsigned long *)&fw1280ei_length01,&fw1280ei_addr01, &fw1280ei_version_str[0] }, - {"QLA12160 ", QLA12160_DEVICE_ID, 2, - &fw12160i_code01[0], (unsigned long *)&fw12160i_length01,&fw12160i_addr01, &fw12160i_version_str[0] }, - {"QLA10160 ", QLA10160_DEVICE_ID, 1, - &fw12160i_code01[0], (unsigned long *)&fw12160i_length01,&fw12160i_addr01, &fw12160i_version_str[0] }, - {" ", 0, 0} -}; -static unsigned long qla1280_verbose = 1L; -static scsi_qla_host_t *qla1280_hostlist = NULL; -#ifdef QLA1280_PROFILE -static int qla1280_buffer_size = 0; -static char *qla1280_buffer = NULL; -#endif - -#ifdef QL_DEBUG_LEVEL_3 -#define ENTER(x) sprintf(debug_buff,"qla1280 : Entering %s()\n\r", x); \ - qla1280_print(debug_buff); -#define LEAVE(x) sprintf(debug_buff,"qla1280 : Leaving %s()\n\r", x); \ - qla1280_print(debug_buff); -#define ENTER_INTR(x) sprintf(debug_buff,"qla1280 : Entering %s()\n\r", x); \ - qla1280_print(debug_buff); -#define LEAVE_INTR(x) sprintf(debug_buff,"qla1280 : Leaving %s()\n\r", x); \ - qla1280_print(debug_buff); -#define DEBUG3(x) x -#else -#define ENTER(x) -#define LEAVE(x) -#define ENTER_INTR(x) -#define LEAVE_INTR(x) -#define DEBUG3(x) -#endif +#define NUM_OF_ISP_DEVICES 6 -#if DEBUG_QLA1280 -#define COMTRACE(x) -/* #define COMTRACE(x) qla1280_putc(x); */ -#define DEBUG(x) x -#else -#define DEBUG(x) -#define COMTRACE(x) -#endif +struct qla_boards { + unsigned char name[9]; /* Board ID String */ + unsigned long device_id; /* Device PCI ID */ + int numPorts; /* Number of SCSI ports */ + unsigned short *fwcode; /* pointer to FW array */ + unsigned short *fwlen; /* number of words in array */ + unsigned short *fwstart; /* start address for F/W */ + unsigned char *fwver; /* Ptr to F/W version array */ +}; -#ifdef QL_DEBUG_LEVEL_2 -#define DEBUG2(x) x -#else -#define DEBUG2(x) -#endif -#define DEBUG5(x) +struct qla_boards ql1280_board_tbl[NUM_OF_ISP_DEVICES] = { + /* Name , Board PCI Device ID, Number of ports */ + {"QLA12160", PCI_DEVICE_ID_QLOGIC_ISP12160, 2, + &fw12160i_code01[0], &fw12160i_length01, + &fw12160i_addr01, &fw12160i_version_str[0]}, + {"QLA1080", PCI_DEVICE_ID_QLOGIC_ISP1080, 1, + &fw1280ei_code01[0], &fw1280ei_length01, + &fw1280ei_addr01, &fw1280ei_version_str[0]}, + {"QLA1240", PCI_DEVICE_ID_QLOGIC_ISP1240, 2, + &fw1280ei_code01[0], &fw1280ei_length01, + &fw1280ei_addr01, &fw1280ei_version_str[0]}, + {"QLA1280", PCI_DEVICE_ID_QLOGIC_ISP1280, 2, + &fw1280ei_code01[0], &fw1280ei_length01, + &fw1280ei_addr01, &fw1280ei_version_str[0]}, + {"QLA10160", PCI_DEVICE_ID_QLOGIC_ISP10160, 1, + &fw12160i_code01[0], &fw12160i_length01, + &fw12160i_addr01, &fw12160i_version_str[0]}, + {" ", 0, 0} +}; -#if (BITS_PER_LONG==64) -# define OFFSET(w) (((uint64_t) &w) & 0xFF) /* 256 byte offsets */ +static int qla1280_verbose = 1; +static struct scsi_qla_host *qla1280_hostlist; +static int qla1280_buffer_size; +static char *qla1280_buffer; + +#if DEBUG_QLA1280 +static int ql_debug_level = 1; +#define dprintk(level, format, a...) \ + do { if (ql_debug_level >= level) printk(KERN_ERR format, ##a); } while(0) +#define qla1280_dump_buffer(level, buf, size) \ + if (ql_debug_level >= level) __qla1280_dump_buffer(buf, size) +#define qla1280_print_scsi_cmd(level, cmd) \ + if (ql_debug_level >= level) __qla1280_print_scsi_cmd(cmd) #else -# define OFFSET(w) (((uint32_t) &w) & 0xFF) /* 256 byte offsets */ +#define ql_debug_level 0 +#define dprintk(level, format, a...) do{}while(0) +#define qla1280_dump_buffer(a, b, c) do{}while(0) +#define qla1280_print_scsi_cmd(a, b) do{}while(0) #endif -#define SCSI_BUS_32(scp) ((scp)->channel) -#define SCSI_TCN_32(scp) ((scp)->target) -#define SCSI_LUN_32(scp) ((scp)->lun) - -/****************************************************************************/ -/* LINUX - Loadable Module Functions. */ -/****************************************************************************/ - +#define ENTER(x) dprintk(3, "qla1280 : Entering %s()\n", x); +#define LEAVE(x) dprintk(3, "qla1280 : Leaving %s()\n", x); +#define ENTER_INTR(x) dprintk(4, "qla1280 : Entering %s()\n", x); +#define LEAVE_INTR(x) dprintk(4, "qla1280 : Leaving %s()\n", x); -/************************************************************************* - * qla1280_set_info - * - * Description: - * Set parameters for the driver from the /proc filesystem. - * - * Returns: - *************************************************************************/ -int -qla1280_set_info(char *buffer, int length, struct Scsi_Host *HBAptr) -{ - return (-ENOSYS); /* Currently this is a no-op */ -} /************************************************************************* * qla1280_proc_info @@ -567,464 +660,549 @@ * * Returns: *************************************************************************/ -#ifdef QLA1280_PROFILE -#define PROC_BUF (&qla1280_buffer[size]) -#define LUN_ID (targ_lun>>(MAX_T_BITS+MAX_L_BITS)),((targ_lun>>MAX_L_BITS)&0xf), targ_lun&0x7 -#endif -int -qla1280_proc_info ( char *buffer, char **start, off_t offset, int length, - int hostno, int inout) -{ -#ifdef QLA1280_PROFILE - struct Scsi_Host *host; - scsi_qla_host_t *ha; - int size = 0; - int targ_lun; - scsi_lu_t *up; - int no_devices; - - printk("Entering proc_info 0x%p,0x%lx,0x%x,0x%x\n",buffer,offset,length,hostno); - host = NULL; - /* find the host they want to look at */ - for(ha=qla1280_hostlist; (ha != NULL) && ha->host->host_no != hostno; ha=ha->next) - ; - - if (!ha) - { - size += sprintf(buffer, "Can't find adapter for host number %d\n", hostno); - if (size > length) - { - return (size); - } - else - { - return (length); - } - } - - host = ha->host; - if (inout == TRUE) /* Has data been written to the file? */ - { - return (qla1280_set_info(buffer, length, host)); - } - - /* compute number of active devices */ - no_devices = 0; - for (targ_lun = 0; targ_lun < MAX_EQ; targ_lun++) - { - if( (up = ha->dev[targ_lun]) == NULL ) - continue; - no_devices++; - } - /* size = 112 * no_devices; */ - size = 4096; - /* round up to the next page */ - - /* - * if our old buffer is the right size use it otherwise - * allocate a new one. - */ - if (qla1280_buffer_size != size) - { - /* deallocate this buffer and get a new one */ - if (qla1280_buffer != NULL) - { - kfree(qla1280_buffer); - qla1280_buffer_size = 0; - } - qla1280_buffer = kmalloc(size, GFP_KERNEL); - } - if (qla1280_buffer == NULL) - { - size = sprintf(buffer, "qla1280 - kmalloc error at line %d\n", - __LINE__); - return size; - } - qla1280_buffer_size = size; - - size = 0; - size += sprintf(PROC_BUF, "Qlogic 1280/1080 SCSI driver version: "); /* 43 bytes */ - size += sprintf(PROC_BUF, "%5s, ", QLA1280_VERSION); /* 5 */ - size += sprintf(PROC_BUF, "Qlogic Firmware version: "); /* 25 */ - size += sprintf(PROC_BUF, "%2d.%2d.%2d",_firmware_version[0], /* 8 */ - ql12_firmware_version[1], - ql12_firmware_version[2]); - size += sprintf(PROC_BUF, "\n"); /* 1 */ - - size += sprintf(PROC_BUF, "SCSI Host Adapter Information: %s\n", QLBoardTbl[ha->devnum].bdName); - size += sprintf(PROC_BUF, "Request Queue = 0x%lx, Response Queue = 0x%lx\n", - ha->request_dma, - ha->response_dma); - size += sprintf(PROC_BUF, "Request Queue count= 0x%x, Response Queue count= 0x%x\n", - REQUEST_ENTRY_CNT, - RESPONSE_ENTRY_CNT); - size += sprintf(PROC_BUF,"Number of pending commands = 0x%lx\n", ha->actthreads); - size += sprintf(PROC_BUF,"Number of queued commands = 0x%lx\n", ha->qthreads); - size += sprintf(PROC_BUF,"Number of free request entries = %d\n",ha->req_q_cnt); - size += sprintf(PROC_BUF, "\n"); /* 1 */ - - size += sprintf(PROC_BUF, "Attached devices:\n"); - /* scan for all equipment stats */ - for (targ_lun = 0; targ_lun < MAX_EQ; targ_lun++) - { - if( (up = ha->dev[targ_lun]) == NULL ) - continue; - if( up->io_cnt == 0 ) - { - size += sprintf(PROC_BUF,"(%2d:%2d:%2d) No stats\n",LUN_ID); - continue; - } - /* total reads since boot */ - /* total writes since boot */ - /* total requests since boot */ - size += sprintf(PROC_BUF, "Total requests %ld,",up->io_cnt); - /* current number of pending requests */ - size += sprintf(PROC_BUF, "(%2d:%2d:%2d) pending requests %d,",LUN_ID,up->q_outcnt); - /* avg response time */ - size += sprintf(PROC_BUF, "Avg response time %ld%%,",(up->resp_time/up->io_cnt)*100); - - /* avg active time */ - size += sprintf(PROC_BUF, "Avg active time %ld%%\n",(up->act_time/up->io_cnt)*100); - } - - if (size >= qla1280_buffer_size) - { - printk(KERN_WARNING "qla1280: Overflow buffer in qla1280_proc.c\n"); - } - - if (offset > size - 1) - { - kfree(qla1280_buffer); - qla1280_buffer = NULL; - qla1280_buffer_size = length = 0; - *start = NULL; - } - else - { - *start = &qla1280_buffer[offset]; /* Start of wanted data */ - if (size - offset < length) - { - length = size - offset; - } - } +#define PROC_BUF &qla1280_buffer[len] + +#if LINUX_VERSION_CODE < 0x020600 +static int qla1280_proc_info(char *buffer, char **start, off_t offset, + int length, int hostno, int inout) +#else +static int qla1280_proc_info(struct Scsi_Host *host, char *buffer, + char **start, off_t offset, int length, int inout) +#endif +{ + struct scsi_qla_host *ha; + int size = 0; + int len = 0; + struct qla_boards *bdp; +#ifdef BOGUS_QUEUE + struct scsi_lu *up; + uint32_t b, t, l; +#endif +#if LINUX_VERSION_CODE >= 0x020600 + ha = (struct scsi_qla_host *)host->hostdata; +#else + struct Scsi_Host *host; + /* Find the host that was specified */ + for (ha = qla1280_hostlist; (ha != NULL) + && ha->host->host_no != hostno; ha = ha->next) ; + + /* if host wasn't found then exit */ + if (!ha) { + size = sprintf(buffer, "Can't find adapter for host " + "number %d\n", hostno); + if (size > length) { + return size; + } else { + return 0; + } + } + + host = ha->host; +#endif + + if (inout) + return -ENOSYS; + + /* + * if our old buffer is the right size use it otherwise + * allocate a new one. + */ + if (qla1280_buffer_size != PAGE_SIZE) { + /* deallocate this buffer and get a new one */ + if (qla1280_buffer != NULL) { + free_page((unsigned long)qla1280_buffer); + qla1280_buffer_size = 0; + } + qla1280_buffer = (char *)get_zeroed_page(GFP_KERNEL); + } + if (qla1280_buffer == NULL) { + size = sprintf(buffer, "qla1280 - kmalloc error at line %d\n", + __LINE__); + return size; + } + /* save the size of our buffer */ + qla1280_buffer_size = PAGE_SIZE; + + /* 3.20 clear the buffer we use for proc display */ + memset(qla1280_buffer, 0, PAGE_SIZE); + + /* start building the print buffer */ + bdp = &ql1280_board_tbl[ha->devnum]; + size = sprintf(PROC_BUF, + "QLogic PCI to SCSI Adapter for ISP 1280/12160:\n" + " Firmware version: %2d.%02d.%02d, Driver version %s\n", + bdp->fwver[0], bdp->fwver[1], bdp->fwver[2], + QLA1280_VERSION); + + len += size; + + size = sprintf(PROC_BUF, "SCSI Host Adapter Information: %s\n", + bdp->name); + len += size; + size = sprintf(PROC_BUF, "Request Queue count= 0x%x, Response " + "Queue count= 0x%x\n", + REQUEST_ENTRY_CNT, RESPONSE_ENTRY_CNT); + len += size; + size = sprintf(PROC_BUF, "Number of pending commands = 0x%lx\n", + ha->actthreads); + len += size; + size = sprintf(PROC_BUF, "Number of free request entries = %d\n", + ha->req_q_cnt); + len += size; + size = sprintf(PROC_BUF, "\n"); /* 1 */ + len += size; + + size = sprintf(PROC_BUF, "SCSI device Information:\n"); + len += size; +#ifdef BOGUS_QUEUE + /* scan for all equipment stats */ + for (b = 0; b < MAX_BUSES; b++) + for (t = 0; t < MAX_TARGETS; t++) { + for (l = 0; l < MAX_LUNS; l++) { + up = LU_Q(ha, b, t, l); + if (up == NULL) + continue; + /* unused device/lun */ + if (up->io_cnt == 0 || up->io_cnt < 2) + continue; + /* total reads since boot */ + /* total writes since boot */ + /* total requests since boot */ + size = sprintf (PROC_BUF, + "(%2d:%2d:%2d): Total reqs %ld,", + b, t, l, up->io_cnt); + len += size; + /* current number of pending requests */ + size = sprintf(PROC_BUF, " Pend reqs %d,", + up->q_outcnt); + len += size; +#if 0 + /* avg response time */ + size = sprintf(PROC_BUF, " Avg resp time %ld%%,", + (up->resp_time / up->io_cnt) * + 100); + len += size; + + /* avg active time */ + size = sprintf(PROC_BUF, + " Avg active time %ld%%\n", + (up->act_time / up->io_cnt) * 100); +#else + size = sprintf(PROC_BUF, "\n"); #endif + len += size; + } + if (len >= qla1280_buffer_size) + break; + } +#endif + + if (len >= qla1280_buffer_size) { + printk(KERN_WARNING + "qla1280: Overflow buffer in qla1280_proc.c\n"); + } + + if (offset > len - 1) { + free_page((unsigned long) qla1280_buffer); + qla1280_buffer = NULL; + qla1280_buffer_size = length = 0; + *start = NULL; + } else { + *start = &qla1280_buffer[offset]; /* Start of wanted data */ + if (len - offset < length) { + length = len - offset; + } + } + return length; +} + + +static int qla1280_read_nvram(struct scsi_qla_host *ha) +{ + uint16_t *wptr; + uint8_t chksum; + int cnt; + struct nvram *nv; + + ENTER("qla1280_read_nvram"); + + if (driver_setup.no_nvram) + return 1; + + printk(KERN_INFO "scsi(%ld): Reading NVRAM\n", ha->host_no); + + wptr = (uint16_t *)&ha->nvram; + nv = &ha->nvram; + chksum = 0; + for (cnt = 0; cnt < 3; cnt++) { + *wptr = qla1280_get_nvram_word(ha, cnt); + chksum += *wptr & 0xff; + chksum += (*wptr >> 8) & 0xff; + wptr++; + } - return (length); + if (nv->id0 != 'I' || nv->id1 != 'S' || + nv->id2 != 'P' || nv->id3 != ' ' || nv->version < 1) { + dprintk(2, "Invalid nvram ID or version!\n"); + chksum = 1; + } else { + for (; cnt < sizeof(struct nvram); cnt++) { + *wptr = qla1280_get_nvram_word(ha, cnt); + chksum += *wptr & 0xff; + chksum += (*wptr >> 8) & 0xff; + wptr++; + } + } + + dprintk(3, "qla1280_read_nvram: NVRAM Magic ID= %c %c %c %02x" + " version %i\n", nv->id0, nv->id1, nv->id2, nv->id3, + nv->version); + + + if (chksum) { + if (!driver_setup.no_nvram) + printk(KERN_WARNING "scsi(%ld): Unable to identify or " + "validate NVRAM checksum, using default " + "settings\n", ha->host_no); + ha->nvram_valid = 0; + } else + ha->nvram_valid = 1; + + dprintk(1, "qla1280_read_nvram: Completed Reading NVRAM\n"); + LEAVE("qla1280_read_nvram"); + + return chksum; } /************************************************************************** - * qla1280_detect - * This routine will probe for Qlogic 1280 SCSI host adapters. - * It returns the number of host adapters of a particular - * type that were found. It also initialize all data necessary for - * the driver. It is passed-in the host number, so that it - * knows where its first entry is in the scsi_hosts[] array. + * qla1280_do_device_init + * This routine will register the device with the SCSI subsystem, + * initialize the host adapter structure and call the device init + * routines. * * Input: - * template - pointer to SCSI template + * pdev - pointer to struct pci_dev for adapter + * template - pointer to SCSI template + * devnum - the device number + * bdp - pointer to struct _qlaboards + * num_hosts - the host number * * Returns: - * num - number of host adapters found. + * host - pointer to SCSI host structure **************************************************************************/ -int -qla1280_detect(Scsi_Host_Template *template) -{ - int num_hosts = 0; - struct Scsi_Host *host; - scsi_qla_host_t *ha, *cur_ha; - struct _qlaboards *bdp; - int i, j; -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,1,95) - unsigned int piobase; - unsigned char pci_bus, pci_devfn, pci_irq; - config_reg_t *cfgp = 0; -#endif - device_reg_t *reg; - char *cp; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95) - struct pci_dev *pdev = NULL; +struct Scsi_Host * +qla1280_do_device_init(struct pci_dev *pdev, Scsi_Host_Template * template, + int devnum, struct qla_boards *bdp, int num_hosts) +{ + struct Scsi_Host *host; + struct scsi_qla_host *ha; + + printk(KERN_INFO "qla1280: %s found on PCI bus %i, dev %i\n", + bdp->name, pdev->bus->number, PCI_SLOT(pdev->devfn)); + + host = scsi_register(template, sizeof(struct scsi_qla_host)); + if (!host) { + printk(KERN_WARNING + "qla1280: Failed to register host, aborting.\n"); + goto error; + } + +#if LINUX_VERSION_CODE < 0x020545 + scsi_set_pci_device(host, pdev); #else - int index; + scsi_set_device(host, &pdev->dev); #endif + ha = (struct scsi_qla_host *)host->hostdata; + /* Clear our data area */ + memset(ha, 0, sizeof(struct scsi_qla_host)); + /* Sanitize the information from PCI BIOS. */ + host->irq = pdev->irq; + ha->pci_bus = pdev->bus->number; + ha->pci_device_fn = pdev->devfn; + ha->pdev = pdev; + ha->device_id = bdp->device_id; + ha->devnum = devnum; /* specifies microcode load address */ + + if (qla1280_mem_alloc(ha)) { + printk(KERN_INFO "qla1x160: Failed to get memory\n"); + goto error_scsi_unregister; + } - ENTER("qla1280_detect"); + ha->ports = bdp->numPorts; + /* following needed for all cases of OS versions */ + ha->host = host; + ha->host_no = host->host_no; -#ifdef CHECKSRBSIZE - if (sizeof(srb_t) > sizeof(Scsi_Pointer) ) - { - printk("Redefine SRB - its too big"); - return 0; - } + host->can_queue = 0xfffff; /* unlimited */ + host->cmd_per_lun = 1; + host->base = (unsigned long)ha->mmpbase; + host->max_channel = bdp->numPorts - 1; + host->max_lun = MAX_LUNS - 1; + host->max_id = MAX_TARGETS; + host->max_sectors = 1024; +#if LINUX_VERSION_CODE < 0x020545 + host->select_queue_depths = qla1280_select_queue_depth; #endif -#ifdef MODULE - DEBUG(sprintf(debug_buff,"DEBUG: qla1280_detect starts at address = %p\n",qla1280_detect);) - DEBUG(qla1280_print(debug_buff);) - /* - * If we are called as a module, the qla1280 pointer may not be null - * and it would point to our bootup string, just like on the lilo - * command line. IF not NULL, then process this config string with - * qla1280_setup - * - * Boot time Options - * To add options at boot time add a line to your lilo.conf file like: - * append="qla1280=verbose,max_tags:{{255,255,255,255},{255,255,255,255}}" - * which will result in the first four devices on the first two - * controllers being set to a tagged queue depth of 32. - */ - if(options) - qla1280_setup(options, NULL); - if(dummy_buffer[0] != 'P') - printk(KERN_WARNING "qla1280: Please read the file /usr/src/linux/drivers" - "/scsi/README.qla1280\n" - "qla1280: to see the proper way to specify options to the qla1280 " - "module\n" - "qla1280: Specifically, don't use any commas when passing arguments to\n" - "qla1280: insmod or else it might trash certain memory areas.\n"); -#endif - - if ((int) !pcibios_present()) - { - printk("scsi: PCI not present\n"); - return 0; - } /* end of IF */ - bdp = &QLBoardTbl[0]; - qla1280_hostlist = NULL; -#if 0 - template->proc_dir = &proc_scsi_qla1280; -#else - template->proc_name = "qla1280"; + ha->instance = num_hosts; + host->unique_id = ha->instance; + + if (qla1280_pci_config(ha)) { + printk(KERN_INFO "qla1x160: Unable to configure PCI\n"); + goto error_mem_alloced; + } + + /* Disable ISP interrupts. */ + qla1280_disable_intrs(ha); + + /* Register the IRQ with Linux (sharable) */ + if (request_irq(host->irq, qla1280_intr_handler, SA_SHIRQ, + "qla1280", ha)) { + printk("qla1280 : Failed to reserve interrupt %d already " + "in use\n", host->irq); + goto error_iounmap; + } +#if !MEMORY_MAPPED_IO + /* Register the I/O space with Linux */ + if (!request_region(host->io_port, 0xff, "qla1280")) { + printk("qla1280: Failed to reserve i/o region 0x%04lx-0x%04lx" + " already in use\n", + host->io_port, host->io_port + 0xff); + goto error_free_irq; + } #endif - - /* Try and find each different type of adapter we support */ - for( i=0; bdp->device_id != 0 && i < NUM_OF_ISP_DEVICES; i++, bdp++ ) { -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95) - while ((pdev = pci_find_device(QLA1280_VENDOR_ID, - bdp->device_id, pdev ) )) { - if (pci_enable_device(pdev)) continue; -#else - while (!(pcibios_find_device(QLA1280_VENDOR_ID, - bdp->device_id, - index++, &pci_bus, &pci_devfn)) ) { -#endif - /* found a adapter */ - host = scsi_register(template, sizeof(scsi_qla_host_t)); - if (!host) { - printk(KERN_WARNING "qla1280: Failed to register host, aborting.\n"); - return 0; - } - scsi_set_pci_device(host, pdev); - ha = (scsi_qla_host_t *) host->hostdata; - /* Clear our data area */ - for( j =0, cp = (char *)ha; j < sizeof(scsi_qla_host_t); j++) - *cp = 0; - /* Sanitize the information from PCI BIOS. */ -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95) - host->irq = pdev->irq; - host->io_port = pci_resource_start(pdev, 0); - ha->pci_bus = pdev->bus->number; - ha->pci_device_fn = pdev->devfn; - ha->pdev = pdev; -#else - pcibios_read_config_byte(pci_bus, pci_devfn, OFFSET(cfgp->interrupt_line), &pci_irq); - pcibios_read_config_dword(pci_bus, pci_devfn, OFFSET(cfgp->base_port), &piobase); - host->irq = pci_irq; - host->io_port = (unsigned int) piobase; - host->io_port &= PCI_BASE_ADDRESS_IO_MASK; - ha->pci_bus = pci_bus; - ha->pci_device_fn = pci_devfn; -#endif - ha->device_id = bdp->device_id; - - ha->devnum = i; - if( qla1280_mem_alloc(ha) ) { - printk(KERN_INFO "qla1280: Failed to allocate memory for adapter\n"); - } - - ha->ports = bdp->numPorts; - ha->iobase = (device_reg_t *) host->io_port; - ha->host = host; - ha->host_no = host->host_no; - - /* load the F/W, read paramaters, and init the H/W */ - if (qla1280_initialize_adapter(ha)) - { - - printk(KERN_INFO "qla1280: Failed to initialized adapter\n"); - qla1280_mem_free(ha); - scsi_unregister(host); - continue; - } - - host->max_channel = bdp->numPorts-1; - ha->instance = num_hosts; - /* Register our resources with Linux */ - if( qla1280_register_with_Linux(ha, bdp->numPorts-1) ) { - printk(KERN_INFO "qla1280: Failed to register our resources\n"); - qla1280_mem_free(ha); - scsi_unregister(host); - continue; - } + /* load the F/W, read paramaters, and init the H/W */ + if (qla1280_initialize_adapter(ha)) { + printk(KERN_INFO "qla1x160: Failed to initialize adapter\n"); + goto error_release_region; + } - reg = ha->iobase; - /* Disable ISP interrupts. */ - qla1280_disable_intrs(ha); + /* set our host ID (need to do something about our two IDs) */ + host->this_id = ha->bus_settings[0].id; - /* Insure mailbox registers are free. */ - WRT_REG_WORD(®->semaphore, 0); - WRT_REG_WORD(®->host_cmd, HC_CLR_RISC_INT); - WRT_REG_WORD(®->host_cmd, HC_CLR_HOST_INT); - - /* Enable chip interrupts. */ - qla1280_enable_intrs(ha); - - /* Insert new entry into the list of adapters */ - ha->next = NULL; - if( qla1280_hostlist == NULL ) - { - cur_ha = qla1280_hostlist = ha; - } - else - { - cur_ha = qla1280_hostlist; - while( cur_ha->next != NULL ) - cur_ha = cur_ha->next; - cur_ha->next = ha; - } - num_hosts++; - } /* end of WHILE */ - } /* end of FOR */ + return host; - LEAVE("qla1280_detect"); - return num_hosts; + error_release_region: +#if !MEMORY_MAPPED_IO + release_region(host->io_port, 0xff); + error_free_irq: +#endif + free_irq(host->irq, ha); + error_iounmap: +#if MEMORY_MAPPED_IO + if (ha->mmpbase) + iounmap((void *)(((unsigned long) ha->mmpbase) & PAGE_MASK)); +#endif + error_mem_alloced: + qla1280_mem_free(ha); + error_scsi_unregister: + scsi_unregister(host); + error: + return NULL; } /************************************************************************** -* qla1280_register_with_Linux -* -* Description: -* Free the passed in Scsi_Host memory structures prior to unloading the -* module. -* -* Input: -* ha - pointer to host adapter structure -* maxchannels - MAX number of channels. -* -* Returns: -* 0 - Sucessfully reserved resources. -* 1 - Failed to reserved a resource. -**************************************************************************/ -STATIC uint8_t qla1280_register_with_Linux(scsi_qla_host_t *ha, uint8_t maxchannels) + * qla1280_detect + * This routine will probe for Qlogic 1280 SCSI host adapters. + * It returns the number of host adapters of a particular + * type that were found. It also initialize all data necessary for + * the driver. It is passed-in the host number, so that it + * knows where its first entry is in the scsi_hosts[] array. + * + * Input: + * template - pointer to SCSI template + * + * Returns: + * num - number of host adapters found. + **************************************************************************/ +static int +qla1280_detect(Scsi_Host_Template * template) { + struct pci_dev *pdev = NULL; + struct Scsi_Host *host; + struct scsi_qla_host *ha, *cur_ha; + struct qla_boards *bdp; + uint16_t subsys_vendor, subsys_device; + int num_hosts = 0; + int devnum = 0; + + ENTER("qla1280_detect"); + + if (sizeof(struct srb) > sizeof(Scsi_Pointer)) { + printk(KERN_WARNING + "qla1280_detect: [WARNING] struct srb too big\n"); + return 0; + } +#ifdef MODULE + /* + * If we are called as a module, the qla1280 pointer may not be null + * and it would point to our bootup string, just like on the lilo + * command line. IF not NULL, then process this config string with + * qla1280_setup + * + * Boot time Options + * To add options at boot time add a line to your lilo.conf file like: + * append="qla1280=verbose,max_tags:{{255,255,255,255},{255,255,255,255}}" + * which will result in the first four devices on the first two + * controllers being set to a tagged queue depth of 32. + */ + if (qla1280) + qla1280_setup(qla1280); +#endif + + bdp = &ql1280_board_tbl[0]; + qla1280_hostlist = NULL; + template->proc_name = "qla1280"; + + /* First Initialize QLA12160 on PCI Bus 1 Dev 2 */ + while ((pdev = pci_find_subsys(PCI_VENDOR_ID_QLOGIC, bdp->device_id, + PCI_ANY_ID, PCI_ANY_ID, pdev))) { - struct Scsi_Host *host = ha->host; + /* find QLA12160 device on PCI bus=1 slot=2 */ + if ((pdev->bus->number != 1) || (PCI_SLOT(pdev->devfn) != 2)) + continue; - host->can_queue = 0xfffff; /* unlimited */ - host->cmd_per_lun = 1; - host->select_queue_depths = qla1280_select_queue_depth; - host->n_io_port = 0xFF; - host->base = (unsigned long) ha->mmpbase; - host->max_channel = maxchannels; - host->max_lun = MAX_LUNS-1; - host->unique_id = ha->instance; - host->max_id = MAX_TARGETS; - host->unique_id = ha->instance; + /* Bypass all AMI SUBSYS VENDOR IDs */ + if (pdev->subsystem_vendor == PCI_VENDOR_ID_AMI) { + printk(KERN_INFO + "qla1x160: Skip AMI SubSys Vendor ID Chip\n"); + continue; + } - /* set our host ID (need to do something about our two IDs) */ - host->this_id = ha->bus_settings[0].id; - /* Register the IRQ with Linux (sharable) */ - if ( request_irq(host->irq, qla1280_intr_handler, SA_INTERRUPT| SA_SHIRQ, "qla1280", ha)) - { - printk("qla1280 : Failed to reserved interrupt %d already in use\n", host->irq); - qla1280_mem_free(ha); - scsi_unregister(host); - return 1; - } - - /* Register the I/O space with Linux */ - if (check_region(host->io_port, 0xff)) - { - printk("qla1280 : Failed to reserved i/o region 0x%04lx-0x%04lx already in use\n", - host->io_port, host->io_port + 0xff); - free_irq(host->irq, NULL); - qla1280_mem_free(ha); - scsi_unregister(host); - return 1; - } + if (pci_enable_device(pdev)) + goto find_devices; + + host = qla1280_do_device_init(pdev, template, devnum, + bdp, num_hosts); + if (!host) + continue; + ha = (struct scsi_qla_host *)host->hostdata; - request_region(host->io_port, 0xff, "qla1280"); + /* this preferred device will always be the first one found */ + cur_ha = qla1280_hostlist = ha; + num_hosts++; + } - return 0; -} + find_devices: + pdev = NULL; + /* Try and find each different type of adapter we support */ + for (devnum = 0; bdp->device_id != 0 && devnum < NUM_OF_ISP_DEVICES; + devnum++, bdp++) { + /* PCI_SUBSYSTEM_IDS supported */ + while ((pdev = pci_find_subsys(PCI_VENDOR_ID_QLOGIC, + bdp->device_id, PCI_ANY_ID, + PCI_ANY_ID, pdev))) { + if (pci_enable_device(pdev)) + continue; + /* found an adapter */ + subsys_vendor = pdev->subsystem_vendor; + subsys_device = pdev->subsystem_device; + + /* + * skip QLA12160 already initialized on + * PCI Bus 1 Dev 2 since we already initialized + * and presented it + */ + if ((bdp->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160)&& + (pdev->bus->number == 1) && + (PCI_SLOT(pdev->devfn) == 2)) + continue; + + /* Bypass all AMI SUBSYS VENDOR IDs */ + if (subsys_vendor == PCI_VENDOR_ID_AMI) { + printk(KERN_INFO + "qla1x160: Skip AMI SubSys Vendor ID Chip\n"); + continue; + } + dprintk(1, "qla1x160: Supported Device Found VID=%x " + "DID=%x SSVID=%x SSDID=%x\n", pdev->vendor, + pdev->device, subsys_vendor, subsys_device); + + host = qla1280_do_device_init(pdev, template, + devnum, bdp, num_hosts); + if (!host) + continue; + ha = (struct scsi_qla_host *)host->hostdata; + + if (qla1280_hostlist == NULL) { + cur_ha = qla1280_hostlist = ha; + } else { + cur_ha = qla1280_hostlist; + while (cur_ha->next != NULL) + cur_ha = cur_ha->next; + cur_ha->next = ha; + } + num_hosts++; + } /* end of WHILE */ + } /* end of FOR */ + + LEAVE("qla1280_detect"); + return num_hosts; +} /************************************************************************** * qla1280_release * Free the passed in Scsi_Host memory structures prior to unloading the * module. **************************************************************************/ -int +static int qla1280_release(struct Scsi_Host *host) { - scsi_qla_host_t *ha = (scsi_qla_host_t *) host->hostdata; - - ENTER("qla1280_release"); + struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata; - if( !ha->flags.online ) - return(0); + ENTER("qla1280_release"); - /* turn-off interrupts on the card */ - WRT_REG_WORD(&ha->iobase->ictrl, 0); + if (!ha->flags.online) + return 0; - /* Detach interrupts */ - if(host->irq) - free_irq(host->irq, ha); + /* turn-off interrupts on the card */ + WRT_REG_WORD(&ha->iobase->ictrl, 0); - /* release io space registers */ - if( host->io_port ) - release_region(host->io_port, 0xff); + /* Detach interrupts */ + if (host->irq) + free_irq(host->irq, ha); #if MEMORY_MAPPED_IO - if(ha->mmpbase) - { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) - vfree((void *) (((unsigned long) ha->mmpbase) & PAGE_MASK)); + if (ha->mmpbase) + iounmap(ha->mmpbase); #else - iounmap((void *) (((unsigned long) ha->mmpbase) & PAGE_MASK)); -#endif - } -#endif /* MEMORY_MAPPED_IO */ - qla1280_mem_free(ha); + /* release io space registers */ + if (host->io_port) + release_region(host->io_port, 0xff); +#endif /* MEMORY_MAPPED_IO */ - ENTER("qla1280_release"); - return(0); + qla1280_mem_free(ha); + + ENTER("qla1280_release"); + return 0; } /************************************************************************** * qla1280_info * Return a string describing the driver. **************************************************************************/ -const char * +static const char * qla1280_info(struct Scsi_Host *host) { - static char qla1280_buffer[125]; - char *bp; - scsi_qla_host_t *ha; - qla_boards_t *bdp; - - bp = &qla1280_buffer[0]; - ha = (scsi_qla_host_t *)host->hostdata; - bdp = &QLBoardTbl[ha->devnum]; - memset(bp, 0, sizeof(qla1280_buffer)); - sprintf(bp, - "QLogic %sPCI to SCSI Host Adapter: bus %d device %d irq %d\n" - " Firmware version: %2d.%02d.%02d, Driver version %s", - (char *)&bdp->bdName[0], ha->pci_bus, (ha->pci_device_fn & 0xf8) >> 3, host->irq, - bdp->fwver[0],bdp->fwver[1],bdp->fwver[2], - QLA1280_VERSION); - return(bp); + static char qla1280_scsi_name_buffer[125]; + char *bp; + struct scsi_qla_host *ha; + struct qla_boards *bdp; + + bp = &qla1280_scsi_name_buffer[0]; + ha = (struct scsi_qla_host *)host->hostdata; + bdp = &ql1280_board_tbl[ha->devnum]; + memset(bp, 0, sizeof(qla1280_scsi_name_buffer)); + sprintf (bp, + "QLogic %s PCI to SCSI Host Adapter: bus %d device %d irq %d\n" + " Firmware version: %2d.%02d.%02d, Driver version %s", + &bdp->name[0], ha->pci_bus, (ha->pci_device_fn & 0xf8) >> 3, + host->irq, bdp->fwver[0], bdp->fwver[1], bdp->fwver[2], + QLA1280_VERSION); + return bp; } /************************************************************************** @@ -1038,246 +1216,86 @@ * handling). Unfortunely, it sometimes calls the scheduler in interrupt * context which is a big NO! NO!. **************************************************************************/ -int -qla1280_queuecommand(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *)) +static int +qla1280_queuecommand(Scsi_Cmnd * cmd, void (*fn) (Scsi_Cmnd *)) { - scsi_qla_host_t *ha; - srb_t *sp; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) - unsigned long cpu_flags = 0; -#endif - struct Scsi_Host *host; - uint32_t b, t, l; - scsi_lu_t *q; - u_long handle; - - ENTER("qla1280_queuecommand"); - COMTRACE('C') - - host = cmd->host; - ha = (scsi_qla_host_t *) host->hostdata; - - /* send command to adapter */ - sp = (srb_t *) CMD_SP(cmd); - sp->cmd = cmd; - cmd->scsi_done = fn; - if (cmd->flags == 0) /* new command */ - { - sp->flags = 0; - } - - DEBUG5(qla1280_print_scsi_cmd(cmd)); - - /* Generate LU queue on bus, target, LUN */ - b = SCSI_BUS_32(cmd); - t = SCSI_TCN_32(cmd); - l = SCSI_LUN_32(cmd); - if((q = LU_Q(ha, b, t, l)) == NULL ) - { - DRIVER_LOCK - if( (q = (scsi_lu_t *)KMALLOC(sizeof(struct scsi_lu))) ) - { - LU_Q(ha, b, t, l) = q; - BZERO(q,sizeof(struct scsi_lu)); - DEBUG(sprintf(debug_buff,"Allocate new device queue 0x%x\n",q)); - DEBUG(qla1280_print(debug_buff)); - DRIVER_UNLOCK - } - else - { - CMD_RESULT(cmd) = (int) (DID_BUS_BUSY << 16); - qla1280_done_q_put(sp, &ha->done_q_first, &ha->done_q_last); - - schedule_task(&ha->run_qla_bh); - ha->flags.dpc_sched = TRUE; - DRIVER_UNLOCK - return(0); - } - } - /* Set an invalid handle until we issue the command to ISP */ - /* then we will set the real handle value. */ - handle = INVALID_HANDLE; - CMD_HANDLE(cmd) = (unsigned char *)handle; - - /* Bookkeeping information */ - sp->r_start = jiffies; /* time the request was received */ - sp->u_start = 0; - - /* add the command to our queue */ - ha->qthreads++; - qla1280_putq_t(q,sp); - - DEBUG(sprintf(debug_buff,"qla1280_queuecmd: queue pid=%d, hndl=0x%x\n\r",cmd->pid,handle)); - DEBUG(qla1280_print(debug_buff)); - - /* send command to adapter */ - DRIVER_LOCK - if (q->q_outcnt == 0) - qla1280_restart_queues(ha); - DRIVER_UNLOCK - - - LEAVE("qla1280_queuecommand"); - return (0); + struct scsi_qla_host *ha; + struct srb *sp; + struct Scsi_Host *host; + int bus, target, lun; + int status; + + /*ENTER("qla1280_queuecommand"); + */ + dprintk(2, "qla1280_queuecommand(): jiffies %li\n", jiffies); + + host = CMD_HOST(cmd); + ha = (struct scsi_qla_host *)host->hostdata; + + /* send command to adapter */ + sp = (struct srb *)CMD_SP(cmd); + sp->cmd = cmd; + cmd->scsi_done = fn; + sp->flags = 0; + + qla1280_print_scsi_cmd(5, cmd); + + /* Generate LU queue on bus, target, LUN */ + bus = SCSI_BUS_32(cmd); + target = SCSI_TCN_32(cmd); + lun = SCSI_LUN_32(cmd); + if (ha->flags.enable_64bit_addressing) + status = qla1280_64bit_start_scsi(ha, sp); + else + status = qla1280_32bit_start_scsi(ha, sp); + + /*LEAVE("qla1280_queuecommand"); */ + return status; } -/************************************************************************** - * qla1200_abort - * Abort the speciifed SCSI command(s). - **************************************************************************/ -int -qla1280_abort(Scsi_Cmnd *cmd) +enum action { + ABORT_COMMAND, + ABORT_DEVICE, + DEVICE_RESET, + BUS_RESET, + ADAPTER_RESET, + FAIL +}; + +/* timer action for error action processor */ +static void qla1280_error_wait_timeout(unsigned long __data) +{ + struct scsi_cmnd *cmd = (struct scsi_cmnd *)__data; + struct srb *sp = (struct srb *)CMD_SP(cmd); + + complete(sp->wait); +} + +static void qla1280_mailbox_timeout(unsigned long __data) { - scsi_qla_host_t *ha; - srb_t *sp; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) - unsigned long cpu_flags = 0; -#endif - struct Scsi_Host *host; - uint32_t b, t, l; - scsi_lu_t *q; - int return_status = SCSI_ABORT_SUCCESS; - int found = 0; - int i; - u_long handle; - u_short data; - - ENTER("qla1280_abort"); - COMTRACE('A') - ha = (scsi_qla_host_t *) cmd->host->hostdata; - host = cmd->host; - DRIVER_LOCK - - /* Get the SCSI request ptr */ - sp = (srb_t *) CMD_SP(cmd); - handle = (u_long) CMD_HANDLE(cmd); - if (qla1280_verbose) - printk("scsi(%d): ABORT Command=0x%lx, handle=0x%lx\n",(int)ha->host_no,(long)cmd,handle); - - /* Check for pending interrupts. */ - if( handle == 0L ) - { - COMTRACE('a') - /* we never got this command */ - printk(KERN_INFO "qla1280: Aborting a NULL handle\n"); - DRIVER_UNLOCK - return(SCSI_ABORT_NOT_RUNNING); /* no action - we don't have command */ - } - data = qla1280_debounce_register(&ha->iobase->istatus); - if( !(ha->flags.in_isr) && (data & RISC_INT) ) - { - /* put any pending command in done queue */ - qla1280_isr(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); - } - - handle = (u_long) CMD_HANDLE(cmd); - - /* Generate LU queue on bus, target, LUN */ - b = SCSI_BUS_32(cmd); - t = SCSI_TCN_32(cmd); - l = SCSI_LUN_32(cmd); - if((q = LU_Q(ha, b, t, l)) == NULL ) - { - COMTRACE('a') - /* No lun queue -- command must not be active */ - DRIVER_UNLOCK - printk(KERN_WARNING "qla1280 (%d:%d:%d): No LUN queue for the specified device\n",(int)b,(int)t,(int)l); - return(SCSI_ABORT_NOT_RUNNING); /* no action - we don't have command */ - } - -#if AUTO_ESCALATE_ABORT - if ( (sp->flags & SRB_ABORTED) ) - { - DRIVER_UNLOCK - DEBUG(qla1280_print("qla1280_abort: Abort escalayted - returning SCSI_ABORT_SNOOZE.\n\r")); - return(SCSI_ABORT_SNOOZE); - } -#endif - - if ( (sp->flags & SRB_ABORT_PENDING) ) - { - COMTRACE('a') - DRIVER_UNLOCK - if( qla1280_verbose ) - printk("scsi(): Command has a pending abort message - ABORT_PENDING.\n"); - DEBUG(qla1280_print("qla1280: Command has a pending abort message - ABORT_PENDING.\n\r")); - return(SCSI_ABORT_PENDING); - } - -#if STOP_ON_ABORT - printk("Scsi layer issued a ABORT command= 0x%x\n",(int)cmd); - DEBUG2(qla1280_print_scsi_cmd(cmd)); -#endif - - ha->flags.in_abort = TRUE; - /* - * Normally, would would need to search our queue for the specified command - * but; since our sp contains the cmd ptr, we can just remove it from our - * LUN queue. - */ - if( !(sp->flags&SRB_SENT) ) - { - found++; - if( qla1280_verbose ) - printk("scsi(): Command returned from queue aborted.\n"); - DEBUG(qla1280_print("qla1280: Command returned from queue aborted.\n\r")); - /* Remove srb from SCSI LU queue. */ - qla1280_removeq(q, sp); - sp->flags |= SRB_ABORTED; - CMD_RESULT(cmd) = DID_ABORT << 16; - qla1280_done_q_put(sp, &ha->done_q_first, &ha->done_q_last); - return_status = SCSI_ABORT_SUCCESS; - } - else - { /* find the command in our active list */ - for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) - { - if( sp == ha->outstanding_cmds[i] ) - { - found++; - DEBUG(qla1280_print("qla1280: RISC aborting command.\n\r")); - qla1280_abort_command(ha,sp); - return_status = SCSI_ABORT_PENDING; - break; - } - } - } - -#if STOP_ON_ABORT - qla1280_panic("qla1280_abort",ha->host); -#endif - if ( found == 0 ) - return_status = SCSI_ABORT_NOT_RUNNING; /* no action - we don't have command */ - - DEBUG(sprintf(debug_buff, "qla1280_abort: Aborted status returned = 0x%x.\n\r",return_status)); - DEBUG(qla1280_print(debug_buff)); - - if( ha->done_q_first ) - qla1280_done(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); - if ( found ) - { - qla1280_restart_queues(ha); - } - ha->flags.in_abort = FALSE; - DRIVER_UNLOCK - - LEAVE("qla1280_abort"); - COMTRACE('a') - return(return_status); + struct scsi_qla_host *ha = (struct scsi_qla_host *)__data; + struct device_reg *reg; + reg = ha->iobase; + + ha->mailbox_out[0] = RD_REG_WORD(®->mailbox0); + printk(KERN_ERR "scsi(%ld): mailbox timed out, mailbox0 %04x, " + "ictrl %04x, istatus %04x\n", ha->host_no, ha->mailbox_out[0], + RD_REG_WORD(®->ictrl), RD_REG_WORD(®->istatus)); + complete(ha->mailbox_wait); } /************************************************************************** - * qla1200_reset - * The reset function will reset the SCSI bus and abort any executing - * commands. + * qla1200_error_action + * The function will attempt to perform a specified error action and + * wait for the results (or time out). * * Input: * cmd = Linux SCSI command packet of the command that cause the * bus reset. - * flags = SCSI bus reset option flags (see scsi.h) + * action = error action to take (see action_t) * * Returns: - * DID_RESET in cmd.host_byte of aborted command(s) + * SUCCESS or FAILED * * Note: * Resetting the bus always succeeds - is has to, otherwise the @@ -1285,360 +1303,369 @@ * DEVICE RESET message - on the offending target before pulling * the SCSI bus reset line. **************************************************************************/ -int -qla1280_reset(Scsi_Cmnd *cmd, unsigned int flags) +static int +qla1280_error_action(Scsi_Cmnd * cmd, enum action action) { - scsi_qla_host_t *ha; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) - unsigned long cpu_flags = 0; -#endif - uint32_t b, t, l; - srb_t *sp; - typedef enum - { - ABORT_DEVICE = 1, - DEVICE_RESET = 2, - BUS_RESET = 3, - ADAPTER_RESET= 4, - RESET_DELAYED= 5, - FAIL = 6 - } action_t; - action_t action = ADAPTER_RESET; - u_short data; - scsi_lu_t *q; - int result; - - - ENTER("qla1280_reset"); - COMTRACE('R') - if (qla1280_verbose) - printk("scsi(): Resetting Cmnd=0x%lx, Handle=0x%lx, flags=0x%x\n",(long)cmd,(long)CMD_HANDLE(cmd),flags); - if ( cmd == NULL ) - { - printk(KERN_WARNING "(scsi?:?:?:?) Reset called with NULL Scsi_Cmnd " - "pointer, failing.\n"); - return(SCSI_RESET_SNOOZE); - } - ha = (scsi_qla_host_t *) cmd->host->hostdata; - sp = (srb_t *) CMD_SP(cmd); - -#if STOP_ON_RESET - qla1280_panic("qla1280_reset",ha->host); -#endif - - DRIVER_LOCK - /* Check for pending interrupts. */ - data = qla1280_debounce_register(&ha->iobase->istatus); - if( !(ha->flags.in_isr) && (data & RISC_INT) ) - { - qla1280_isr(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); - } - DRIVER_UNLOCK - - /* - * Determine the suggested action that the mid-level driver wants - * us to perform. - */ - if( CMD_HANDLE(cmd) == (unsigned char *) 0 ) - { - /* - * if mid-level driver called reset with a orphan SCSI_Cmnd - * (i.e. a command that's not pending ), so perform the - * function specified. - */ - if( (flags & SCSI_RESET_SUGGEST_HOST_RESET) ) - action = ADAPTER_RESET; - else - action = BUS_RESET; - } - else - { /* - * Mid-level driver has called reset with this SCSI_Cmnd and - * its pending. - */ - if( flags & SCSI_RESET_SUGGEST_HOST_RESET ) - action = ADAPTER_RESET; - else if( flags & SCSI_RESET_SUGGEST_BUS_RESET ) - action = BUS_RESET; - else - action = DEVICE_RESET; - } - - b = SCSI_BUS_32(cmd); - t = SCSI_TCN_32(cmd); - l = SCSI_LUN_32(cmd); - q = LU_Q(ha, b, t, l); - -#if AUTO_ESCALATE_RESET - if ( (action & DEVICE_RESET) && (q->q_flag & QLA1280_QRESET) ) - { - printk(KERN_INFO "qla1280(%d): Bus device reset already sent to " "device, escalating.\n", (int)ha->host_no); - action = BUS_RESET; - } - if ( (action & DEVICE_RESET) && (sp->flags & SRB_ABORT_PENDING) ) - { - printk(KERN_INFO "qla1280(%d):Have already attempted to reach " "device with abort device\n", (int)ha->host_no); - printk(KERN_INFO "qla1280(%d):message, will escalate to BUS " "RESET.\n",(int) ha->host_no); - action = BUS_RESET; - } -#endif - - /* - * By this point, we want to already know what we are going to do, - * so we only need to perform the course of action. - */ - DRIVER_LOCK - result = SCSI_RESET_ERROR; - switch (action) - { - case FAIL: - break; - - case RESET_DELAYED: - result = SCSI_RESET_PENDING; - break; - - case ABORT_DEVICE: - ha->flags.in_reset = TRUE; - if (qla1280_verbose) - printk(KERN_INFO "scsi(%d:%d:%d:%d): Queueing abort device command.\n", (int)ha->host_no,(int)b,(int)t,(int)l); - qla1280_abort_queue_single(ha,b,t,l,DID_ABORT); - if( qla1280_abort_device(ha, b, t, l) == 0) - result = SCSI_RESET_PENDING; - break; - - case DEVICE_RESET: - if (qla1280_verbose) - printk(KERN_INFO "scsi(%d:%d:%d:%d): Queueing device reset command.\n",(int) ha->host_no,(int)b,(int)t,(int)l); - ha->flags.in_reset = TRUE; - for (l = 0; l < MAX_LUNS; l++) - qla1280_abort_queue_single(ha,b,t,l,DID_ABORT); - if( qla1280_device_reset(ha, b, t) == 0 ) - result = SCSI_RESET_PENDING; - q->q_flag |= QLA1280_QRESET; - break; - - case BUS_RESET: - if (qla1280_verbose) - printk(KERN_INFO "qla1280(%d:%d:%d:%d): Issuing BUS DEVICE RESET.\n",(int) ha->host_no,(int)b,(int)t,(int)l); - ha->flags.in_reset = TRUE; - for (t = 0; t < MAX_TARGETS; t++) - for (l = 0; l < MAX_LUNS; l++) - qla1280_abort_queue_single(ha,b,t,l,DID_RESET); - qla1280_bus_reset(ha, b); - /* - * The bus reset routine returns all the outstanding commands back - * with "DID_RESET" in the status field after a short delay - * by the firmware. If the mid-level time out the SCSI reset before - * our delay we may need to ignore it. - */ - /* result = SCSI_RESET_PENDING | SCSI_RESET_BUS_RESET; */ - result = SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET; - mdelay(4 * 1000); barrier(); - if( flags & SCSI_RESET_SYNCHRONOUS ) - { - CMD_RESULT(cmd) = (int) (DID_BUS_BUSY << 16); - (*(cmd)->scsi_done)(cmd); - } - /* ha->reset_start = jiffies; */ - break; - - case ADAPTER_RESET: - default: - if (qla1280_verbose) - { - printk(KERN_INFO "scsi(%d:%d:%d:%d): Issued an ADAPTER RESET.\n",(int) ha->host_no,(int)b,(int)t,(int)l); - printk(KERN_INFO "scsi(%d:%d:%d:%d): I/O processing will continue automatically.\n",(int) ha->host_no,(int)b,(int)t,(int)l); - } - ha->flags.reset_active = TRUE; - /* - * We restarted all of the commands automatically, so the mid-level code can expect - * completions momentitarily. - */ - if( qla1280_abort_isp(ha) == 0 ) - result = SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET; - - ha->flags.reset_active = FALSE; - } - - if( ha->done_q_first ) - qla1280_done(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); - qla1280_restart_queues(ha); - ha->flags.in_reset = FALSE; - -DRIVER_UNLOCK - DEBUG(printk("RESET returning %d\n", result)); - - COMTRACE('r') - LEAVE("qla1280_reset"); - return( result ); + struct scsi_qla_host *ha; + int bus, target, lun; + struct srb *sp; + uint16_t data; + unsigned char *handle; + int result, i; + DECLARE_COMPLETION(wait); + struct timer_list timer; + + ha = (struct scsi_qla_host *)(CMD_HOST(cmd)->hostdata); + + dprintk(4, "error_action %i, istatus 0x%04x\n", action, + RD_REG_WORD(&ha->iobase->istatus)); + + dprintk(4, "host_cmd 0x%04x, ictrl 0x%04x, jiffies %li\n", + RD_REG_WORD(&ha->iobase->host_cmd), + RD_REG_WORD(&ha->iobase->ictrl), jiffies); + + ENTER("qla1280_error_action"); + if (qla1280_verbose) + printk(KERN_INFO "scsi(%li): Resetting Cmnd=0x%p, " + "Handle=0x%p, action=0x%x\n", + ha->host_no, cmd, CMD_HANDLE(cmd), action); + + if (cmd == NULL) { + printk(KERN_WARNING "(scsi?:?:?:?) Reset called with NULL " + "si_Cmnd pointer, failing.\n"); + LEAVE("qla1280_error_action"); + return FAILED; + } + + ha = (struct scsi_qla_host *)cmd->device->host->hostdata; + sp = (struct srb *)CMD_SP(cmd); + handle = CMD_HANDLE(cmd); + + /* Check for pending interrupts. */ + data = qla1280_debounce_register(&ha->iobase->istatus); + /* + * The io_request_lock is held when the reset handler is called, hence + * the interrupt handler cannot be running in parallel as it also + * grabs the lock. /Jes + */ + if (data & RISC_INT) + qla1280_isr(ha, &ha->done_q_first, &ha->done_q_last); + + /* + * Determine the suggested action that the mid-level driver wants + * us to perform. + */ + if (handle == (unsigned char *)INVALID_HANDLE || handle == NULL) { + if(action == ABORT_COMMAND) { + /* we never got this command */ + printk(KERN_INFO "qla1280: Aborting a NULL handle\n"); + return SUCCESS; /* no action - we don't have command */ + } + } else { + sp->wait = &wait; + } + + bus = SCSI_BUS_32(cmd); + target = SCSI_TCN_32(cmd); + lun = SCSI_LUN_32(cmd); + + /* Overloading result. Here it means the success or fail of the + * *issue* of the action. When we return from the routine, it must + * mean the actual success or fail of the action */ + result = FAILED; + switch (action) { + case FAIL: + break; + + case ABORT_COMMAND: + if ((sp->flags & SRB_ABORT_PENDING)) { + printk(KERN_WARNING + "scsi(): Command has a pending abort " + "message - ABORT_PENDING.\n"); + /* This should technically be impossible since we + * now wait for abort completion */ + break; + } + + for (i = 0; i < MAX_OUTSTANDING_COMMANDS; i++) { + if (sp == ha->outstanding_cmds[i]) { + dprintk(1, "qla1280: RISC aborting command\n"); + if (qla1280_abort_command(ha, sp, i) == 0) + result = SUCCESS; + else { + /* + * Since we don't know what might + * have happend to the command, it + * is unsafe to remove it from the + * device's queue at this point. + * Wait and let the escalation + * process take care of it. + */ + printk(KERN_WARNING + "scsi(%li:%i:%i:%i): Unable" + " to abort command!\n", + ha->host_no, bus, target, lun); + } + } + } + break; + + case ABORT_DEVICE: + ha->flags.in_reset = 1; + if (qla1280_verbose) + printk(KERN_INFO + "scsi(%ld:%d:%d:%d): Queueing abort device " + "command.\n", ha->host_no, bus, target, lun); + if (qla1280_abort_device(ha, bus, target, lun) == 0) + result = SUCCESS; + break; + + case DEVICE_RESET: + if (qla1280_verbose) + printk(KERN_INFO + "scsi(%ld:%d:%d:%d): Queueing device reset " + "command.\n", ha->host_no, bus, target, lun); + ha->flags.in_reset = 1; + if (qla1280_device_reset(ha, bus, target) == 0) + result = SUCCESS; + break; + + case BUS_RESET: + if (qla1280_verbose) + printk(KERN_INFO "qla1280(%ld:%d): Issuing BUS " + "DEVICE RESET\n", ha->host_no, bus); + ha->flags.in_reset = 1; + if (qla1280_bus_reset(ha, bus == 0)) + result = SUCCESS; + + break; + + case ADAPTER_RESET: + default: + if (qla1280_verbose) { + printk(KERN_INFO + "scsi(%ld): Issued ADAPTER RESET\n", + ha->host_no); + printk(KERN_INFO "scsi(%ld): I/O processing will " + "continue automatically\n", ha->host_no); + } + ha->flags.reset_active = 1; + /* + * We restarted all of the commands automatically, so the + * mid-level code can expect completions momentitarily. + */ + if (qla1280_abort_isp(ha) == 0) + result = SUCCESS; + + ha->flags.reset_active = 0; + } + + if (ha->done_q_first) + qla1280_done(ha, &ha->done_q_first, &ha->done_q_last); + ha->flags.in_reset = 0; + + /* If we didn't manage to issue the action, or we have no + * command to wait for, exit here */ + if (result == FAILED || handle == NULL || + handle == (unsigned char *)INVALID_HANDLE) + goto leave; + + /* set up a timer just in case we're really jammed */ + init_timer(&timer); + timer.expires = jiffies + 4*HZ; + timer.data = (unsigned long)cmd; + timer.function = qla1280_error_wait_timeout; + add_timer(&timer); + + /* wait for the action to complete (or the timer to expire) */ + spin_unlock_irq(HOST_LOCK); + wait_for_completion(&wait); + del_timer_sync(&timer); + spin_lock_irq(HOST_LOCK); + sp->wait = NULL; + + /* the only action we might get a fail for is abort */ + if (action == ABORT_COMMAND) { + if(sp->flags & SRB_ABORTED) + result = SUCCESS; + else + result = FAILED; + } + + leave: + dprintk(1, "RESET returning %d\n", result); + + LEAVE("qla1280_error_action"); + return result; } /************************************************************************** - * qla1200_biosparam - * Return the disk geometry for the given SCSI device. + * qla1280_abort + * Abort the specified SCSI command(s). **************************************************************************/ -int -qla1280_biosparam(Disk *disk, kdev_t dev, int geom[]) +static int +qla1280_eh_abort(struct scsi_cmnd * cmd) { - int heads, sectors, cylinders; - - heads = 64; - sectors = 32; - cylinders = disk->capacity / (heads * sectors); - if (cylinders > 1024) - { - heads = 255; - sectors = 63; - cylinders = disk->capacity / (heads * sectors); - /* if (cylinders > 1023) - cylinders = 1023; */ - } - - geom[0] = heads; - geom[1] = sectors; - geom[2] = cylinders; - - return (0); + return qla1280_error_action(cmd, ABORT_COMMAND); } + /************************************************************************** - * qla1280_intr_handler - * Handles the H/W interrupt + * qla1280_device_reset + * Reset the specified SCSI device **************************************************************************/ -void qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs) +static int +qla1280_eh_device_reset(struct scsi_cmnd *cmd) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,95) - unsigned long cpu_flags = 0; -#endif - scsi_qla_host_t *ha; - u_short data; - device_reg_t *reg; - - ENTER_INTR("qla1280_intr_handler"); - COMTRACE('I') - ha = (scsi_qla_host_t *) dev_id; - if(!ha) - { - printk(KERN_INFO "scsi(): Interrupt with NULL host ptr\n"); - COMTRACE('X') - return; - } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,95) - spin_lock_irqsave(&io_request_lock, cpu_flags); - if(test_and_set_bit(QLA1280_IN_ISR_BIT, &ha->flags)) - { - COMTRACE('X') - spin_unlock_irqrestore(&io_request_lock, cpu_flags); - return; - } - ha->isr_count++; - reg = ha->iobase; - /* disable our interrupt. */ - WRT_REG_WORD(®->ictrl, 0); - data = qla1280_debounce_register(®->istatus); - /* Check for pending interrupts. */ - if ( !(data & RISC_INT) ) - { - /* spurious interrupts can happen legally */ - DEBUG(printk("scsi(%d): Spurious interrupt - ignoring\n",(int)ha->host_no)); - COMTRACE('X') - } - else - qla1280_isr(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); - if (ha->done_q_first) - qla1280_done(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); - - clear_bit(QLA1280_IN_ISR_BIT, &ha->flags); - spin_unlock_irqrestore(&io_request_lock, cpu_flags); -#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) */ - - if( test_bit(QLA1280_IN_ISR_BIT, (int *)&ha->flags) ) - { - COMTRACE('X') - printk(KERN_INFO "scsi(%d): Already in interrupt - returning \n", (int)ha->host_no); - return; - } - set_bit(QLA1280_IN_ISR_BIT, (int *)&ha->flags); - ha->isr_count++; - reg = ha->iobase; - /* disable our interrupt. */ - WRT_REG_WORD(®->ictrl, 0); - - data = qla1280_debounce_register(®->istatus); - /* Check for pending interrupts. */ - if ( !(data & RISC_INT) ) - { - /* spurious interrupts can happen legally */ - DEBUG(printk("scsi(%d): Spurious interrupt - ignoring\n",(int)ha->host_no)); - COMTRACE('X') - } - else - qla1280_isr(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); - - /* if no work to do then call the SCSI mid-level right away */ - if( ha->done_q_first ) - qla1280_done(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); - - /* Schedule the DPC routine */ - if (ha->flags.isp_abort_needed || ha->flags.reset_marker || - ha->done_q_first ) - { - ha->run_qla_bh.data = (void *) ha; - ha->run_qla_bh.routine = qla1280_do_dpc; - - COMTRACE('P') - schedule_task(&ha->run_qla_bh); - ha->flags.dpc_sched = TRUE; - } - clear_bit(QLA1280_IN_ISR_BIT, (int *)&ha->flags); -#endif - /* enable our interrupt. */ - WRT_REG_WORD(®->ictrl, ISP_EN_INT + ISP_EN_RISC); + return qla1280_error_action(cmd, DEVICE_RESET); +} - COMTRACE('i') - LEAVE_INTR("qla1280_intr_handler"); +/************************************************************************** + * qla1280_bus_reset + * Reset the specified bus. + **************************************************************************/ +static int +qla1280_eh_bus_reset(struct scsi_cmnd *cmd) +{ + return qla1280_error_action(cmd, BUS_RESET); } /************************************************************************** - * qla1280_do_dpc - * - * Description: - * This routine is a task that is schedule by the interrupt handler - * to perform the background processing for interrupts. We put it - * on a task queue that is consumed whenever the scheduler runs; that's - * so you can do anything (i.e. put the process to sleep etc). In fact, the - * mid-level tries to sleep when it reaches the driver threshold - * "host->can_queue". This can cause a panic if we were in our interrupt - * code . + * qla1280_adapter_reset + * Reset the specified adapter (both channels) **************************************************************************/ -static void qla1280_do_dpc(void *p) +static int +qla1280_eh_adapter_reset(struct scsi_cmnd *cmd) { - scsi_qla_host_t *ha = (scsi_qla_host_t *) p; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95) - unsigned long cpu_flags = 0; -#endif + return qla1280_error_action(cmd, ADAPTER_RESET); +} - COMTRACE('p') -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95) - spin_lock_irqsave(&io_request_lock, cpu_flags); +/************************************************************************** + * qla1280_biosparam + * Return the disk geometry for the given SCSI device. + **************************************************************************/ +static int +#if LINUX_VERSION_CODE < 0x020545 +qla1280_biosparam(Disk * disk, kdev_t dev, int geom[]) +#else +qla1280_biosparam(struct scsi_device *sdev, struct block_device *bdev, + sector_t capacity, int geom[]) #endif - if (ha->flags.isp_abort_needed) - qla1280_abort_isp(ha); +{ + int heads, sectors, cylinders; +#if LINUX_VERSION_CODE < 0x020545 + unsigned long capacity = disk->capacity; +#endif + + heads = 64; + sectors = 32; + cylinders = (unsigned long)capacity / (heads * sectors); + if (cylinders > 1024) { + heads = 255; + sectors = 63; + cylinders = (unsigned long)capacity / (heads * sectors); + /* if (cylinders > 1023) + cylinders = 1023; */ + } - if (ha->flags.reset_marker) - qla1280_rst_aen(ha); + geom[0] = heads; + geom[1] = sectors; + geom[2] = cylinders; - if (ha->done_q_first) - qla1280_done(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); - ha->flags.dpc_sched = FALSE; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95) - spin_unlock_irqrestore(&io_request_lock, cpu_flags); -#endif + return 0; } /************************************************************************** - * qla1280_device_queue_depth - * + * qla1280_intr_handler + * Handles the H/W interrupt + **************************************************************************/ +irqreturn_t +qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + struct scsi_qla_host *ha; + struct device_reg *reg; + u16 data; + int handled = 0; + + ENTER_INTR ("qla1280_intr_handler"); + ha = (struct scsi_qla_host *)dev_id; + + spin_lock(HOST_LOCK); + + ha->isr_count++; + reg = ha->iobase; + + WRT_REG_WORD(®->ictrl, 0); /* disable our interrupt. */ + + data = qla1280_debounce_register(®->istatus); + /* Check for pending interrupts. */ + if (data & RISC_INT) { + qla1280_isr(ha, &ha->done_q_first, &ha->done_q_last); + handled = 1; + } + if (ha->done_q_first) + qla1280_done(ha, &ha->done_q_first, &ha->done_q_last); + + spin_unlock(HOST_LOCK); + + /* enable our interrupt. */ + WRT_REG_WORD(®->ictrl, (ISP_EN_INT | ISP_EN_RISC)); + + LEAVE_INTR("qla1280_intr_handler"); + return IRQ_RETVAL(handled); +} + + +static int +qla12160_set_target_parameters(struct scsi_qla_host *ha, int bus, int target) +{ + uint8_t mr; + uint16_t mb[MAILBOX_REGISTER_COUNT]; + struct nvram *nv; + int is1x160, status; + + nv = &ha->nvram; + + if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 || + ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160) + is1x160 = 1; + else + is1x160 = 0; + + mr = BIT_3 | BIT_2 | BIT_1 | BIT_0; + + /* Set Target Parameters. */ + mb[0] = MBC_SET_TARGET_PARAMETERS; + mb[1] = (uint16_t) (bus ? target | BIT_7 : target); + mb[1] <<= 8; + + mb[2] = (nv->bus[bus].target[target].parameter.c << 8); + + if (is1x160) + mb[3] = nv->bus[bus].target[target].flags.flags1x160.sync_offset << 8; + else + mb[3] = nv->bus[bus].target[target].flags.flags1x80.sync_offset << 8; + mb[3] |= nv->bus[bus].target[target].sync_period; + + if (is1x160) { + mb[2] |= nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr << 5; + mb[6] = nv->bus[bus].target[target].ppr_1x160.flags.ppr_options << 8; + mb[6] |= nv->bus[bus].target[target].ppr_1x160.flags.ppr_bus_width; + mr |= BIT_6; + } + + status = qla1280_mailbox_command(ha, mr, &mb[0]); + + if (status) + printk(KERN_WARNING "scsi(%ld:%i:%i): " + "qla1280_set_target_parameters() failed\n", + ha->host_no, bus, target); + return status; +} + + +/************************************************************************** + * qla1280_slave_configure + * * Description: * Determines the queue depth for a given device. There are two ways * a queue depth can be obtained for a tagged queueing device. One @@ -1647,29 +1674,64 @@ * as the default queue depth. Otherwise, we use either 4 or 8 as the * default queue depth (dependent on the number of hardware SCBs). **************************************************************************/ -STATIC void qla1280_device_queue_depth(scsi_qla_host_t *p, Scsi_Device *device) +static int +qla1280_slave_configure(Scsi_Device *device) { - int default_depth = 3; - int bus = device->channel; - int target = device->id; - - device->queue_depth = default_depth; - - if (device->tagged_supported && - (p->bus_settings[bus].qtag_enables & (BIT_0 << target)) ) - { - device->tagged_queue = 1; - device->current_tag = 0; - device->queue_depth = p->bus_settings[bus].hiwat; - /* device->queue_depth = 20; */ - printk(KERN_INFO "scsi(%d:%d:%d:%d): Enabled tagged queuing, queue depth %d.\n", - (int)p->host_no, device->channel, device->id, - device->lun, device->queue_depth); - } - qla12160_get_target_parameters(p, bus, target, device->lun); + struct scsi_qla_host *ha; + int default_depth = 3; + int bus = device->channel; + int target = device->id; + int status = 0; + struct nvram *nv; + unsigned long flags; + + ha = (struct scsi_qla_host *)device->host->hostdata; + nv = &ha->nvram; + + if (qla1280_check_for_dead_scsi_bus(ha, bus)) + return 1; + + if (device->tagged_supported && + (ha->bus_settings[bus].qtag_enables & (BIT_0 << target))) { + scsi_adjust_queue_depth(device, MSG_ORDERED_TAG, + ha->bus_settings[bus].hiwat); + } else { + scsi_adjust_queue_depth(device, 0, default_depth); + } + +#if LINUX_VERSION_CODE > 0x020500 + nv->bus[bus].target[target].parameter.f.enable_sync = device->sdtr; + nv->bus[bus].target[target].parameter.f.enable_wide = device->wdtr; + nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr = device->ppr; +#endif + + if (driver_setup.no_sync || + (driver_setup.sync_mask && + (~driver_setup.sync_mask & (1 << target)))) + nv->bus[bus].target[target].parameter.f.enable_sync = 0; + if (driver_setup.no_wide || + (driver_setup.wide_mask && + (~driver_setup.wide_mask & (1 << target)))) + nv->bus[bus].target[target].parameter.f.enable_wide = 0; + if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 || + ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160) { + if (driver_setup.no_ppr || + (driver_setup.ppr_mask && + (~driver_setup.ppr_mask & (1 << target)))) + nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 0; + } + + spin_lock_irqsave(HOST_LOCK, flags); + if (nv->bus[bus].target[target].parameter.f.enable_sync) { + status = qla12160_set_target_parameters(ha, bus, target); + } + qla12160_get_target_parameters(ha, device); + spin_unlock_irqrestore(HOST_LOCK, flags); + return status; } +#if LINUX_VERSION_CODE < 0x020545 /************************************************************************** * qla1280_select_queue_depth * @@ -1677,43 +1739,30 @@ * host adapter. We use a queue depth of 2 for devices that do not * support tagged queueing. **************************************************************************/ -STATIC void +static void qla1280_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs) { - Scsi_Device *device; - scsi_qla_host_t *p = (scsi_qla_host_t *) host->hostdata; + Scsi_Device *device; + struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata; - ENTER("qla1280_select_queue_depth"); - for (device = scsi_devs; device != NULL; device = device->next) - { - if (device->host == host) - qla1280_device_queue_depth(p, device); - } - LEAVE("qla1280_select_queue_depth"); -} - -/*--------------------------** -** Driver Support Routines ** -**--------------------------*/ + ENTER("qla1280_select_queue_depth"); + for (device = scsi_devs; device != NULL; device = device->next) { + if (device->host == host) + qla1280_slave_configure(device); + } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) -/* - * mdelay - * Delay in milliseconds - * - * Input: - * milliseconds = delay - */ -STATIC inline void mdelay(int milliseconds) -{ - int i; + if (scsi_devs) + qla1280_check_for_dead_scsi_bus(ha, scsi_devs->channel); - for(i=0; is_next)) - *done_q_last = NULL; - else - (*done_q_first)->s_prev = NULL; - cmd = sp->cmd; - b = SCSI_BUS_32(cmd); - t = SCSI_TCN_32(cmd); - l = SCSI_LUN_32(cmd); - q = LU_Q(ha, b, t, l); - - /* Decrement outstanding commands on device. */ - if (q->q_outcnt) - q->q_outcnt--; - if (q->q_outcnt < ha->bus_settings[b].hiwat) - { - q->q_flag &= ~QLA1280_QBUSY; - } - - q->resp_time += jiffies - sp->r_start; /* Lun bookkeeping information */ - q->act_time += jiffies - sp->u_start; - q->io_cnt++; - if( sp->dir & BIT_5 ) - q->r_cnt++; - else - q->w_cnt++; - - switch ( (CMD_RESULT(cmd)>>16)) - { - case DID_RESET: - q->q_flag &= ~QLA1280_QRESET; - /* Issue marker command. */ - qla1280_marker(ha, b, t, 0, MK_SYNC_ID); - break; - case DID_ABORT: - sp->flags &= ~SRB_ABORT_PENDING; - sp->flags |= SRB_ABORTED; - if (sp->flags & SRB_TIMEOUT) - CMD_RESULT(sp->cmd)= DID_TIME_OUT << 16; - break; - default: - break; - } - - /* Call the mid-level driver interrupt handler */ - CMD_HANDLE(sp->cmd) = (unsigned char *) 0; - ha->actthreads--; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) - sti(); - (*(cmd)->scsi_done)(cmd); - cli(); -#else - (*(cmd)->scsi_done)(cmd); +static void +qla1280_done(struct scsi_qla_host *ha, struct srb ** done_q_first, + struct srb ** done_q_last) +{ + struct srb *sp; + int bus, target, lun; + Scsi_Cmnd *cmd; + + ENTER("qla1280_done"); + + while (*done_q_first != NULL) { + /* remove command from done list */ + sp = *done_q_first; + if (!(*done_q_first = sp->s_next)) + *done_q_last = NULL; + else + (*done_q_first)->s_prev = NULL; + + cmd = sp->cmd; + bus = SCSI_BUS_32(cmd); + target = SCSI_TCN_32(cmd); + lun = SCSI_LUN_32(cmd); + + switch ((CMD_RESULT(cmd) >> 16)) { + case DID_RESET: + /* Issue marker command. */ + qla1280_marker(ha, bus, target, 0, MK_SYNC_ID); + break; + case DID_ABORT: + sp->flags &= ~SRB_ABORT_PENDING; + sp->flags |= SRB_ABORTED; + if (sp->flags & SRB_TIMEOUT) + CMD_RESULT(sp->cmd) = DID_TIME_OUT << 16; + break; + default: + break; + } + + /* Release memory used for this I/O */ + if (cmd->use_sg) { + dprintk(3, "S/G unmap_sg cmd=%p\n", cmd); + + pci_unmap_sg(ha->pdev, cmd->request_buffer, + cmd->use_sg, + scsi_to_pci_dma_dir(cmd->sc_data_direction)); + } else if (cmd->request_bufflen) { + /*dprintk(1, "No S/G unmap_single cmd=%x saved_dma_handle=%lx\n", + cmd, sp->saved_dma_handle); */ + + pci_unmap_page(ha->pdev, sp->saved_dma_handle, + cmd->request_bufflen, + scsi_to_pci_dma_dir(cmd->sc_data_direction)); + } + + /* Call the mid-level driver interrupt handler */ + CMD_HANDLE(sp->cmd) = (unsigned char *)INVALID_HANDLE; + ha->actthreads--; + +#if LINUX_VERSION_CODE < 0x020500 + if (cmd->cmnd[0] == INQUIRY) + qla1280_get_target_options(cmd, ha); #endif - qla1280_next(ha, q, b); - } - DRIVER_UNLOCK + (*(cmd)->scsi_done)(cmd); + if(sp->wait != NULL) + complete(sp->wait); - COMTRACE('d') - LEAVE("qla1280_done"); + } + LEAVE("qla1280_done"); } /* * Translates a ISP error to a Linux SCSI error */ -STATIC int qla1280_return_status( sts_entry_t *sts, Scsi_Cmnd *cp) +static int +qla1280_return_status(struct response * sts, Scsi_Cmnd * cp) { - int host_status = DID_ERROR; + int host_status = DID_ERROR; #if DEBUG_QLA1280_INTR - STATIC char *reason[] = - { - "DID_OK", - "DID_NO_CONNECT", - "DID_BUS_BUSY", - "DID_TIME_OUT", - "DID_BAD_TARGET", - "DID_ABORT", - "DID_PARITY", - "DID_ERROR", - "DID_RESET", - "DID_BAD_INTR" - }; -#endif /* DEBUG_QLA1280_INTR */ + static char *reason[] = { + "DID_OK", + "DID_NO_CONNECT", + "DID_BUS_BUSY", + "DID_TIME_OUT", + "DID_BAD_TARGET", + "DID_ABORT", + "DID_PARITY", + "DID_ERROR", + "DID_RESET", + "DID_BAD_INTR" + }; +#endif /* DEBUG_QLA1280_INTR */ - ENTER("qla1280_return_status"); + ENTER("qla1280_return_status"); #if DEBUG_QLA1280_INTR - /* - DEBUG(printk("qla1280_return_status: compl status = 0x%04x\n", sts->comp_status)); - */ -#endif - switch(sts->comp_status) - { - case CS_COMPLETE: - host_status = DID_OK; - break; - case CS_INCOMPLETE: - if (!(sts->state_flags & SF_GOT_BUS)) - host_status = DID_NO_CONNECT; - else if (!(sts->state_flags & SF_GOT_TARGET)) - host_status = DID_BAD_TARGET; - else if (!(sts->state_flags & SF_SENT_CDB)) - host_status = DID_ERROR; - else if (!(sts->state_flags & SF_TRANSFERRED_DATA)) - host_status = DID_ERROR; - else if (!(sts->state_flags & SF_GOT_STATUS)) - host_status = DID_ERROR; - else if (!(sts->state_flags & SF_GOT_SENSE)) - host_status = DID_ERROR; - break; - case CS_RESET: - host_status = DID_RESET; - break; - case CS_ABORTED: - host_status = DID_ABORT; - break; - case CS_TIMEOUT: - host_status = DID_TIME_OUT; - break; - case CS_DATA_OVERRUN: -#ifdef QL_DEBUG_LEVEL_2 - printk("Data overrun 0x%x\n",(int)sts->residual_length); - qla1280_print( - "\n\rqla1280_isr: response packet data\n\r"); - qla1280_dump_buffer((caddr_t)sts, - RESPONSE_ENTRY_SIZE); -#endif - host_status = DID_ERROR; - break; - case CS_DATA_UNDERRUN: - if ( (CMD_XFRLEN(cp) - sts->residual_length) < cp->underflow) - { - printk("scsi: Underflow detected - retrying command.\n"); - host_status = DID_ERROR; - } - else - host_status = DID_OK; - break; - default: - host_status = DID_ERROR; - break; - } + /* + dprintk(1, "qla1280_return_status: compl status = 0x%04x\n", + sts->comp_status); + */ +#endif + switch (sts->comp_status) { + case CS_COMPLETE: + host_status = DID_OK; + break; + + case CS_INCOMPLETE: + if (!(sts->state_flags & SF_GOT_BUS)) + host_status = DID_NO_CONNECT; + else if (!(sts->state_flags & SF_GOT_TARGET)) + host_status = DID_BAD_TARGET; + else if (!(sts->state_flags & SF_SENT_CDB)) + host_status = DID_ERROR; + else if (!(sts->state_flags & SF_TRANSFERRED_DATA)) + host_status = DID_ERROR; + else if (!(sts->state_flags & SF_GOT_STATUS)) + host_status = DID_ERROR; + else if (!(sts->state_flags & SF_GOT_SENSE)) + host_status = DID_ERROR; + break; + + case CS_RESET: + host_status = DID_RESET; + break; + + case CS_ABORTED: + host_status = DID_ABORT; + break; + + case CS_TIMEOUT: + host_status = DID_TIME_OUT; + break; + + case CS_DATA_OVERRUN: + dprintk(2, "Data overrun 0x%x\n", sts->residual_length); + dprintk(2, "qla1280_isr: response packet data\n"); + qla1280_dump_buffer(2, (char *)sts, RESPONSE_ENTRY_SIZE); + host_status = DID_ERROR; + break; + + case CS_DATA_UNDERRUN: + if ((cp->request_bufflen - sts->residual_length) < + cp->underflow) { + printk(KERN_WARNING + "scsi: Underflow detected - retrying " + "command.\n"); + host_status = DID_ERROR; + } else + host_status = DID_OK; + break; + + default: + host_status = DID_ERROR; + break; + } #if DEBUG_QLA1280_INTR - sprintf(debug_buff, "qla1280 ISP status: host status (%s) scsi status %x\n\r", reason[host_status], sts->scsi_status); - qla1280_print(debug_buff); + dprintk(1, "qla1280 ISP status: host status (%s) scsi status %x\n", + reason[host_status], sts->scsi_status); #endif - LEAVE("qla1280_return_status"); + LEAVE("qla1280_return_status"); - return (sts->scsi_status & 0xff) | (host_status << 16); + return (sts->scsi_status & 0xff) | (host_status << 16); } /* @@ -1903,252 +1946,24 @@ * done_q_first = done queue first pointer. * done_q_last = done queue last pointer. */ -STATIC void -qla1280_done_q_put(srb_t *sp, srb_t **done_q_first, srb_t **done_q_last) -{ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) - unsigned long cpu_flags = 0; -#endif -#ifdef QL_DEBUG_LEVEL_3 - ENTER("qla1280_put_done_q"); -#endif - /* Place block on done queue */ - DRIVER_LOCK - sp->s_next = NULL; - sp->s_prev = *done_q_last; - if (!*done_q_first) - *done_q_first = sp; - else - (*done_q_last)->s_next = sp; - *done_q_last = sp; - - DRIVER_UNLOCK -#ifdef QL_DEBUG_LEVEL_3 - LEAVE("qla1280_put_done_q"); -#endif -} - -/* - * qla1280_next - * Retrieve and process next job in the queue. - * - * Input: - * ha = adapter block pointer. - * q = SCSI LU pointer. - * b = SCSI bus number. - * SCSI_LU_Q lock must be already obtained and no other locks. - * - * Output: - * Releases SCSI_LU_Q upon exit. - */ -STATIC void -qla1280_next(scsi_qla_host_t *ha, scsi_lu_t *q, uint8_t b) -{ - srb_t *sp; - uint32_t cnt; - uint8_t status; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) - unsigned long cpu_flags = 0; -#endif - - ENTER("qla1280_next"); - - DRIVER_LOCK - while ( ((sp = q->q_first) != NULL) && /* we have a queue pending */ - !(q->q_flag & QLA1280_QBUSY) && /* device not busy */ - !ha->flags.abort_isp_active && /* not resetting the adapter */ - !(q->q_flag & QLA1280_QSUSP) ) /* device not suspended */ - { - /* Remove srb from SCSI LU queue. */ - qla1280_removeq(q, sp); - - DEBUG(sprintf(debug_buff,"starting request 0x%p<-(0x%p)\n\r",q,sp)); - DEBUG(qla1280_print(debug_buff)); - { - /* Set busy flag if reached high water mark. */ - q->q_outcnt++; - if (q->q_outcnt >= ha->bus_settings[b].hiwat) - q->q_flag |= QLA1280_QBUSY; - -#if QLA1280_64BIT_SUPPORT - if (ha->flags.enable_64bit_addressing) - status = qla1280_64bit_start_scsi(ha, sp); - else -#endif - status = qla1280_32bit_start_scsi(ha, sp); - - if (status) /* if couldn't start the request */ - { - if (q->q_outcnt == 1) - { - /* Release SCSI LU queue specific lock */ - QLA1280_SCSILU_UNLOCK(q); - - /* Wait for 30 sec for command to be accepted. */ - for (cnt = 6000000; cnt; cnt--) - { -#if QLA1280_64BIT_SUPPORT - if (ha->flags.enable_64bit_addressing) - status = qla1280_64bit_start_scsi(ha, sp); - else -#endif - status = qla1280_32bit_start_scsi(ha, sp); - - if (!status) - { - break; - } - - /* Go check for pending interrupts. */ - qla1280_poll(ha); - - SYS_DELAY(5); /* 10 */ - } - if (!cnt) - { - /* Set timeout status */ - CMD_RESULT(sp->cmd) = DID_TIME_OUT << 16; - -#if WATCHDOGTIMER - /* Remove command from watchdog queue. */ - if (sp->flags & SRB_WATCHDOG) - qla1280_timeout_remove(ha, sp); -#endif - COMTRACE('M') - CMD_HANDLE(sp->cmd) = (unsigned char *) 0; - - /* Call the mid-level driver interrupt handler */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) - sti(); - (*(sp->cmd)->scsi_done)(sp->cmd); - cli(); -#else - (*(sp->cmd)->scsi_done)(sp->cmd); -#endif - - /* Acquire LU queue specific lock */ - QLA1280_SCSILU_LOCK(q); - - if (q->q_outcnt) - q->q_outcnt--; - } - else - /* Acquire LU queue specific lock */ - QLA1280_SCSILU_LOCK(q); - } - else - { /* Place request back on top of device queue. */ - qla1280_putq_t(q, sp); - - if (q->q_outcnt) - q->q_outcnt--; - if (q->q_outcnt < ha->bus_settings[b].hiwat) - q->q_flag &= ~QLA1280_QBUSY; - break; - } - } - } - } - DRIVER_UNLOCK - - /* Release SCSI LU queue specific lock */ - QLA1280_SCSILU_UNLOCK(q); - - LEAVE("qla1280_next"); -} +static void +qla1280_done_q_put(struct srb * sp, struct srb ** done_q_first, + struct srb ** done_q_last) +{ + ENTER("qla1280_put_done_q"); + + /* Place block on done queue */ + sp->s_next = NULL; + sp->s_prev = *done_q_last; + if (!*done_q_first) + *done_q_first = sp; + else + (*done_q_last)->s_next = sp; + *done_q_last = sp; -/* - * qla1280_putq_t - * Add the standard SCB job to the top of standard SCB commands. - * - * Input: - * q = SCSI LU pointer. - * sp = srb pointer. - * SCSI_LU_Q lock must be already obtained. - */ -STATIC void -qla1280_putq_t(scsi_lu_t *q, srb_t *sp) -{ - srb_t *srb_p; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) - unsigned long cpu_flags = 0; -#endif - -#ifdef QL_DEBUG_LEVEL_3 - ENTER("qla1280_putq_t"); -#endif - DRIVER_LOCK - DEBUG(sprintf(debug_buff,"Adding to device 0x%p<-(0x%p)\n\r",q,sp)); - DEBUG(qla1280_print(debug_buff)); - sp->s_next = NULL; - if (!q->q_first) /* If queue empty */ - { - sp->s_prev = NULL; - q->q_first = sp; - q->q_last = sp; - } - else - { - srb_p = q->q_first; - while (srb_p ) - srb_p = srb_p->s_next; - - if (srb_p) - { - sp->s_prev = srb_p->s_prev; - if (srb_p->s_prev) - srb_p->s_prev->s_next = sp; - else - q->q_first = sp; - srb_p->s_prev = sp; - sp->s_next = srb_p; - } - else - { - sp->s_prev = q->q_last; - q->q_last->s_next = sp; - q->q_last = sp; - } - } - - DRIVER_UNLOCK -#ifdef QL_DEBUG_LEVEL_3 - LEAVE("qla1280_putq_t"); -#endif + LEAVE("qla1280_put_done_q"); } -/* - * qla1280_removeq - * Function used to remove a command block from the - * LU queue. - * - * Input: - * q = SCSI LU pointer. - * sp = srb pointer. - * SCSI_LU_Q lock must be already obtained. - */ -STATIC void -qla1280_removeq(scsi_lu_t *q, srb_t *sp) -{ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) - unsigned long cpu_flags = 0; -#endif - DEBUG(sprintf(debug_buff,"Removing from device_q (0x%p)->(0x%p)\n\r",q,sp)); - DEBUG(qla1280_print(debug_buff)); - DRIVER_LOCK - if (sp->s_prev) - { - if ((sp->s_prev->s_next = sp->s_next) != NULL) - sp->s_next->s_prev = sp->s_prev; - else - q->q_last = sp->s_prev; - } - else if (!(q->q_first = sp->s_next)) - q->q_last = NULL; - else - q->q_first->s_prev = NULL; - DRIVER_UNLOCK -} /* * qla1280_mem_alloc @@ -2158,44 +1973,44 @@ * 0 = success. * 1 = failure. */ -STATIC uint8_t -qla1280_mem_alloc(scsi_qla_host_t *ha) +static int +qla1280_mem_alloc(struct scsi_qla_host *ha) { + int status = 1; + dma_addr_t dma_handle; - uint8_t status = 1; - -#ifdef QL_DEBUG_LEVEL_3 ENTER("qla1280_mem_alloc"); -#endif -#ifdef DYNAMIC_MEM_ALLOC - ha->request_ring = qla1280_alloc_phys(REQUEST_ENTRY_SIZE * REQUEST_ENTRY_CNT, - &ha->request_dma); - if(ha->request_ring) { - ha->response_ring = qla1280_alloc_phys(RESPONSE_ENTRY_SIZE * RESPONSE_ENTRY_CNT, - &ha->response_dma); - if(ha->response_ring) { - status = 0; - } - } -#else - ha->request_ring = &ha->req[0]; - ha->request_dma = VIRT_TO_BUS(&ha->req[0]); - ha->response_ring = &ha->res[0]; - ha->response_dma = VIRT_TO_BUS(&ha->res[0]); + /* get consistent memory allocated for request and response rings */ + ha->request_ring = pci_alloc_consistent(ha->pdev, + ((REQUEST_ENTRY_CNT + 1) * + (sizeof(request_t))), + &dma_handle); + if (!ha->request_ring) + goto error; + ha->request_dma = dma_handle; + ha->response_ring = pci_alloc_consistent(ha->pdev, + ((RESPONSE_ENTRY_CNT + 1) * + (sizeof(struct response))), + &dma_handle); + if (!ha->response_ring) + goto error; + ha->response_dma = dma_handle; status = 0; -#endif + goto finish; - if(status) { -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - qla1280_print("qla1280_mem_alloc: **** FAILED ****\n"); -#endif - } -#ifdef QL_DEBUG_LEVEL_3 - else - LEAVE("qla1280_mem_alloc"); -#endif - return(status); + error: + if (status) + dprintk(2, "qla1280_mem_alloc: **** FAILED ****\n"); + + if (ha->request_ring) + pci_free_consistent(ha->pdev, + ((REQUEST_ENTRY_CNT + 1) * + (sizeof(request_t))), + ha->request_ring, ha->request_dma); + finish: + LEAVE("qla1280_mem_alloc"); + return status; } /* @@ -2205,66 +2020,68 @@ * Input: * ha = adapter block pointer. */ -STATIC void -qla1280_mem_free(scsi_qla_host_t *ha) +static void +qla1280_mem_free(struct scsi_qla_host *ha) { - scsi_lu_t *q; - uint32_t b, t, l; - - ENTER("qlc1280_mem_free"); - if (ha) - { - /* Free device queues. */ - for (b = 0; b < MAX_BUSES; b++) - { - q = LU_Q(ha, b, ha->bus_settings[b].id, 0); - for (t = 0; t < MAX_TARGETS; t++) - for (l = 0; l < MAX_LUNS; l++) - if (LU_Q(ha, b, t, l) != NULL && LU_Q(ha, b, t, l) != q) - KMFREE(LU_Q(ha, b, t, l),sizeof(struct scsi_lu)); - KMFREE(q, sizeof(struct scsi_lu)); - } - for( b =0; b < MAX_EQ; b++ ) - ha->dev[b] = (scsi_lu_t *)NULL; - } + ENTER("qlc1280_mem_free"); + /* free consistent memory allocated for request and response rings */ + if (ha->request_ring) + pci_free_consistent(ha->pdev, + ((REQUEST_ENTRY_CNT + 1) * + (sizeof(request_t))), + ha->request_ring, ha->request_dma); + + if (ha->response_ring) + pci_free_consistent(ha->pdev, + ((RESPONSE_ENTRY_CNT + 1) * + (sizeof(struct response))), + ha->response_ring, ha->response_dma); + + if (qla1280_buffer) { + free_page((unsigned long) qla1280_buffer); + qla1280_buffer = NULL; + } - LEAVE("qlc1280_mem_free"); + LEAVE("qlc1280_mem_free"); } - - - /****************************************************************************/ /* QLogic ISP1280 Hardware Support Functions. */ /****************************************************************************/ /* - * qla2100_enable_intrs - * qla2100_disable_intrs - * - * Input: - * ha = adapter block pointer. - * - * Returns: - * None - */ - static inline void qla1280_enable_intrs(scsi_qla_host_t *ha) { - device_reg_t *reg; - - reg = ha->iobase; - ha->flags.interrupts_on = 1; - /* enable risc and host interrupts */ - WRT_REG_WORD(®->ictrl, (ISP_EN_INT+ ISP_EN_RISC)); - } - - static inline void qla1280_disable_intrs(scsi_qla_host_t *ha) { - device_reg_t *reg; - - reg = ha->iobase; - ha->flags.interrupts_on = 0; - /* disable risc and host interrupts */ - WRT_REG_WORD(®->ictrl, 0); - } + * qla2100_enable_intrs + * qla2100_disable_intrs + * + * Input: + * ha = adapter block pointer. + * + * Returns: + * None + */ +static inline void +qla1280_enable_intrs(struct scsi_qla_host *ha) +{ + struct device_reg *reg; + + reg = ha->iobase; + /* enable risc and host interrupts */ + WRT_REG_WORD(®->ictrl, (ISP_EN_INT | ISP_EN_RISC)); + RD_REG_WORD(®->ictrl); /* PCI Posted Write flush */ + ha->flags.ints_enabled = 1; +} + +static inline void +qla1280_disable_intrs(struct scsi_qla_host *ha) +{ + struct device_reg *reg; + + reg = ha->iobase; + /* disable risc and host interrupts */ + WRT_REG_WORD(®->ictrl, 0); + RD_REG_WORD(®->ictrl); /* PCI Posted Write flush */ + ha->flags.ints_enabled = 0; +} /* * qla1280_initialize_adapter @@ -2276,159 +2093,130 @@ * Returns: * 0 = success */ -STATIC uint8_t -qla1280_initialize_adapter(scsi_qla_host_t *ha) +static int +qla1280_initialize_adapter(struct scsi_qla_host *ha) { - device_reg_t *reg; - uint8_t status; - /* uint8_t cnt; */ - uint8_t b; - -#ifdef QL_DEBUG_LEVEL_3 - ENTER("qla1280_initialize_adapter"); -#endif - - /* Clear adapter flags. */ - ha->flags.online = FALSE; - ha->flags.isp_abort_needed = FALSE; - ha->flags.disable_host_adapter = FALSE; - ha->flags.reset_active = FALSE; - ha->flags.abort_isp_active = FALSE; - ha->flags.watchdog_enabled = FALSE; - - DEBUG(printk("Configure PCI space for adapter...\n")); - if (!(status = qla1280_pci_config(ha))) - { - reg = ha->iobase; - - /* Disable ISP interrupts. */ - WRT_REG_WORD(®->ictrl, 0); - - /* Insure mailbox registers are free. */ - WRT_REG_WORD(®->semaphore, 0); - WRT_REG_WORD(®->host_cmd, HC_CLR_RISC_INT); - WRT_REG_WORD(®->host_cmd, HC_CLR_HOST_INT); - - /* If firmware needs to be loaded */ - if (qla1280_verbose) - printk("scsi(%d): Determining if RISC is loaded...\n",(int)ha->host_no); - if (qla1280_isp_firmware(ha)) - { - if (qla1280_verbose) - printk("scsi(%d): Verifying chip...\n",(int)ha->host_no); - if (!(status = qla1280_chip_diag(ha))) - { - if (qla1280_verbose) - printk("scsi(%d): Setup chip...\n",(int)ha->host_no); - status = qla1280_setup_chip(ha); - } - } - - if (!status) - { - /* Setup adapter based on NVRAM parameters. */ - if (qla1280_verbose) - printk("scsi(%d): Configure NVRAM parameters...\n",(int)ha->host_no); - qla1280_nvram_config(ha); - - if (!ha->flags.disable_host_adapter && - !qla1280_init_rings(ha)) - { - /* Issue SCSI reset. */ - for (b = 0; b < ha->ports; b++) - if (!ha->bus_settings[b].disable_scsi_reset) - { - /* dg 03/13 if we can't reset twice then bus is dead */ - if( qla1280_bus_reset(ha, b) ) - if( qla1280_bus_reset(ha, b) ) - { - ha->bus_settings[b].scsi_bus_dead = TRUE; - } - } - - do - { - /* Issue marker command. */ - ha->flags.reset_marker = FALSE; - for (b = 0; b < ha->ports; b++) - { - ha->bus_settings[b].reset_marker = FALSE; - qla1280_marker(ha, b, 0, 0, MK_SYNC_ALL); - } - }while (ha->flags.reset_marker); - - ha->flags.online = TRUE; - - /* Enable host adapter target mode. */ - for (b = 0; b < ha->ports; b++) - { - if (!(status = qla1280_enable_tgt(ha, b))) - { - /* for (cnt = 0; cnt < MAX_LUNS; cnt++) - { - qla1280_enable_lun(ha, b, cnt); - qla1280_poll(ha); - }*/ - } - else - break; - } - } - else - status = 1; - } - } - -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - if (status) - qla1280_print("qla1280_initialize_adapter: **** FAILED ****\n\r"); -#endif -#ifdef QL_DEBUG_LEVEL_3 - else - LEAVE("qla1280_initialize_adapter"); + struct device_reg *reg; + int status; + int bus; +#if LINUX_VERSION_CODE > 0x020500 + unsigned long flags; +#endif + + ENTER("qla1280_initialize_adapter"); + + /* Clear adapter flags. */ + ha->flags.online = 0; + ha->flags.disable_host_adapter = 0; + ha->flags.reset_active = 0; + ha->flags.abort_isp_active = 0; + + ha->flags.ints_enabled = 0; +#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) + if (ia64_platform_is("sn2")) { + int count1, count2; + int c; + + count1 = 3; + count2 = 3; + printk(KERN_INFO "scsi(%li): Enabling SN2 PCI DMA " + "dual channel lockup workaround\n", ha->host_no); + if ((c = snia_pcibr_rrb_alloc(ha->pdev, &count1, &count2)) < 0) + printk(KERN_ERR "scsi(%li): Unable to allocate SN2 " + "virtual DMA channels\n", ha->host_no); + ha->flags.use_pci_vchannel = 1; + + driver_setup.no_nvram = 1; + } #endif - return(status); -} -/* - * qla1280_enable_tgt - * Enable target mode. - * - * Input: - * ha = adapter block pointer. - * b = SCSI bus number. - * - * Returns: - * 0 = success. - */ -STATIC uint8_t -qla1280_enable_tgt(scsi_qla_host_t *ha, uint8_t b) -{ - uint8_t status = 0; - /* uint16_t mb[MAILBOX_REGISTER_COUNT]; */ + dprintk(1, "Configure PCI space for adapter...\n"); + + reg = ha->iobase; + + /* Insure mailbox registers are free. */ + WRT_REG_WORD(®->semaphore, 0); + WRT_REG_WORD(®->host_cmd, HC_CLR_RISC_INT); + WRT_REG_WORD(®->host_cmd, HC_CLR_HOST_INT); + RD_REG_WORD(®->host_cmd); + + if (qla1280_read_nvram(ha)) { + dprintk(2, "qla1280_initialize_adapter: failed to read " + "NVRAM\n"); + } + +#if LINUX_VERSION_CODE >= 0x020500 + /* + * It's necessary to grab the spin here as qla1280_mailbox_command + * needs to be able to drop the lock unconditionally to wait + * for completion. + * In 2.4 ->detect is called with the io_request_lock held. + */ + spin_lock_irqsave(HOST_LOCK, flags); +#endif + /* If firmware needs to be loaded */ + if (qla1280_isp_firmware(ha)) { + if (!(status = qla1280_chip_diag (ha))) { + status = qla1280_setup_chip(ha); + } + } else { + printk(KERN_ERR "scsi(%li): isp_firmware() failed!\n", + ha->host_no); + status = 1; + } + + if (status) { + printk(KERN_ERR "scsi(%li): initialize: pci probe failed!\n", + ha->host_no); + goto out; + } + + /* Setup adapter based on NVRAM parameters. */ + dprintk(1, "scsi(%ld): Configure NVRAM parameters\n", ha->host_no); + qla1280_nvram_config(ha); + + if (!ha->flags.disable_host_adapter && !qla1280_init_rings(ha)) { + /* Issue SCSI reset. */ + /* dg 03/13 if we can't reset twice then bus is dead */ + for (bus = 0; bus < ha->ports; bus++) { + if (!ha->bus_settings[bus].disable_scsi_reset){ + if (qla1280_bus_reset(ha, bus)) { + if (qla1280_bus_reset(ha, bus)) { + ha->bus_settings[bus].scsi_bus_dead = 1; + } + } + } + } -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_enable_tgt: entered\n\r"); + /* + * qla1280_bus_reset() will take care of issueing markers, + * no need to do that here as well! + */ +#if 0 + /* Issue marker command. */ + ha->flags.reset_marker = 0; + for (bus = 0; bus < ha->ports; bus++) { + ha->bus_settings[bus].reset_marker = 0; + qla1280_marker(ha, bus, 0, 0, MK_SYNC_ALL); + } #endif - /* Enable target mode. */ - /* - mb[0] = MBC_ENABLE_TARGET_MODE; - mb[1] = BIT_15; - mb[2] = (uint16_t)(b << 15); - status = qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, &mb[0]); - */ -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - if (status) - qla1280_print("qla1280_enable_tgt: **** FAILED ****\n\r"); -#endif -#ifdef QL_DEBUG_LEVEL_3 - else - qla1280_print("qla1280_enable_tgt: exiting normally\n\r"); + ha->flags.online = 1; + } else + status = 1; + + out: +#if LINUX_VERSION_CODE >= 0x020500 + spin_unlock_irqrestore(HOST_LOCK, flags); #endif - return(status); + if (status) + dprintk(2, "qla1280_initialize_adapter: **** FAILED ****\n"); + + LEAVE("qla1280_initialize_adapter"); + return status; } + /* * ISP Firmware Test * Checks if present version of RISC firmware is older than @@ -2440,83 +2228,55 @@ * Returns: * 0 = firmware does not need to be loaded. */ -STATIC uint8_t -qla1280_isp_firmware(scsi_qla_host_t *ha) +static int +qla1280_isp_firmware(struct scsi_qla_host *ha) { - nvram_t *nv = (nvram_t *)ha->response_ring; - uint16_t *wptr; - uint8_t chksum; - uint8_t cnt; - uint8_t status = 0; /* dg 2/27 always loads RISC */ - uint16_t mb[MAILBOX_REGISTER_COUNT]; - - ENTER("qla1280_isp_firmware"); - - /* Verify valid NVRAM checksum. */ - wptr = (uint16_t *)ha->response_ring; - DEBUG(printk("qla1280_isp_firmware: Reading NVRAM\n")); - chksum = 0; - for (cnt = 0; cnt < sizeof(nvram_t)/2; cnt++) - { - *wptr = qla1280_get_nvram_word(ha, cnt); - chksum += (uint8_t)*wptr; - chksum += (uint8_t)(*wptr >> 8); - wptr++; - } - DEBUG(printk("qla1280_isp_firmware: Completed Reading NVRAM\n")); - -#if defined(QL_DEBUG_LEVEL_3) - sprintf(debug_buff,"qla1280_isp_firmware: NVRAM Magic ID= %c %c %c\n\r",(char *) nv->id[0],nv->id[1],nv->id[2]); - qla1280_print(debug_buff); -#endif - - /* Bad NVRAM data, load RISC code. */ - if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || - nv->id[2] != 'P' || nv->id[3] != ' ' || nv->version < 1) - { - printk(KERN_INFO "qla1280_isp_firmware: Bad checksum or magic number or version in NVRAM.\n"); - ha->flags.disable_risc_code_load = FALSE; - } - else - ha->flags.disable_risc_code_load = nv->cntr_flags_1.disable_loading_risc_code; - - if (ha->flags.disable_risc_code_load) - { -#if defined(QL_DEBUG_LEVEL_3) - qla1280_print("qla1280_isp_firmware: Telling RISC to verify checksum of loaded BIOS code.\n\r"); -#endif - /* Verify checksum of loaded RISC code. */ - mb[0] = MBC_VERIFY_CHECKSUM; - /* mb[1] = ql12_risc_code_addr01; */ - mb[1] = *QLBoardTbl[ha->devnum].fwstart; - - if (!(status = qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]))) - { - /* Start firmware execution. */ -#if defined(QL_DEBUG_LEVEL_3) - qla1280_print("qla1280_isp_firmware: Startng F/W execution.\n\r"); -#endif - mb[0] = MBC_EXECUTE_FIRMWARE; - /* mb[1] = ql12_risc_code_addr01; */ - mb[1] = *QLBoardTbl[ha->devnum].fwstart; - qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]); - } - else - printk(KERN_INFO "qla1280: RISC checksum failed.\n"); - } - else - { - DEBUG(printk("qla1280: NVRAM configured to load RISC load.\n")); - status = 1; - } - -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - if (status) - qla1280_print( - "qla1280_isp_firmware: **** Load RISC code ****\n\r"); -#endif - LEAVE("qla1280_isp_firmware"); - return(status); + struct nvram *nv = (struct nvram *) ha->response_ring; + int status = 0; /* dg 2/27 always loads RISC */ + uint16_t mb[MAILBOX_REGISTER_COUNT]; + + ENTER("qla1280_isp_firmware"); + + dprintk(1, "scsi(%li): Determining if RISC is loaded\n", ha->host_no); + + /* Bad NVRAM data, load RISC code. */ + if (!ha->nvram_valid) { + ha->flags.disable_risc_code_load = 0; + } else + ha->flags.disable_risc_code_load = + nv->cntr_flags_1.disable_loading_risc_code; + + if (ha->flags.disable_risc_code_load) { + dprintk(3, "qla1280_isp_firmware: Telling RISC to verify " + "checksum of loaded BIOS code.\n"); + + /* Verify checksum of loaded RISC code. */ + mb[0] = MBC_VERIFY_CHECKSUM; + /* mb[1] = ql12_risc_code_addr01; */ + mb[1] = *ql1280_board_tbl[ha->devnum].fwstart; + + if (!(status = + qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]))) { + /* Start firmware execution. */ + dprintk(3, "qla1280_isp_firmware: Startng F/W " + "execution.\n"); + + mb[0] = MBC_EXECUTE_FIRMWARE; + /* mb[1] = ql12_risc_code_addr01; */ + mb[1] = *ql1280_board_tbl[ha->devnum].fwstart; + qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); + } else + printk(KERN_INFO "qla1280: RISC checksum failed.\n"); + } else { + dprintk(1, "qla1280: NVRAM configured to load RISC load.\n"); + status = 1; + } + + if (status) + dprintk(2, "qla1280_isp_firmware: **** Load RISC code ****\n"); + + LEAVE("qla1280_isp_firmware"); + return status; } /* @@ -2529,75 +2289,60 @@ * Returns: * 0 = success. */ -STATIC uint8_t -qla1280_pci_config(scsi_qla_host_t *ha) +static int +qla1280_pci_config(struct scsi_qla_host *ha) { - uint8_t status = 1; - uint32_t command; #if MEMORY_MAPPED_IO - uint32_t page_offset, base; - uint32_t mmapbase; + unsigned long base; + int size; #endif - config_reg_t *creg = 0; - uint16_t buf_wd; + uint16_t buf_wd; + int status = 1; - ENTER("qla1280_pci_config"); + ENTER("qla1280_pci_config"); - /* Get command register. */ - if (pci_read_config_word(ha->pdev,OFFSET(creg->command), &buf_wd) == PCIBIOS_SUCCESSFUL) - { - command = buf_wd; - /* - * Set Bus Master Enable, Memory Address Space Enable and - * reset any error bits. - */ - buf_wd &= ~0x7; + pci_set_master(ha->pdev); + /* + * Set Bus Master Enable, Memory Address Space Enable and + * reset any error bits, in the command register. + */ + pci_read_config_word (ha->pdev, PCI_COMMAND, &buf_wd); #if MEMORY_MAPPED_IO - DEBUG(printk("qla1280: MEMORY MAPPED IO is enabled.\n")); - buf_wd |= BIT_2 + BIT_1 + BIT_0; -#else - buf_wd |= BIT_2 + BIT_0; + buf_wd |= PCI_COMMAND_MEMORY; #endif - if( pci_write_config_word(ha->pdev,OFFSET(creg->command), buf_wd) ) - { - printk(KERN_WARNING "qla1280: Could not write config word.\n"); - } - /* Get expansion ROM address. */ - if (pci_read_config_word(ha->pdev,OFFSET(creg->expansion_rom), &buf_wd) == PCIBIOS_SUCCESSFUL) - { - /* Reset expansion ROM address decode enable. */ - buf_wd &= ~BIT_0; - if (pci_write_config_word(ha->pdev,OFFSET(creg->expansion_rom), buf_wd) == PCIBIOS_SUCCESSFUL) - { + buf_wd |= PCI_COMMAND_IO; + pci_write_config_word (ha->pdev, PCI_COMMAND, buf_wd); + /* + * Reset expansion ROM address decode enable. + */ + pci_read_config_word(ha->pdev, PCI_ROM_ADDRESS, &buf_wd); + buf_wd &= ~PCI_ROM_ADDRESS_ENABLE; + pci_write_config_word (ha->pdev, PCI_ROM_ADDRESS, buf_wd); + + ha->host->io_port = pci_resource_start(ha->pdev, 0); + ha->host->io_port &= PCI_BASE_ADDRESS_IO_MASK; + ha->iobase = (struct device_reg *) ha->host->io_port; + #if MEMORY_MAPPED_IO - /* Get memory mapped I/O address. */ - pci_read_config_dword(ha->pdev,OFFSET(cfgp->mem_base_addr), &mmapbase); - mmapbase &= PCI_BASE_ADDRESS_MEM_MASK; - - /* Find proper memory chunk for memory map I/O reg. */ - base = mmapbase & PAGE_MASK; - page_offset = mmapbase - base; - /* Get virtual address for I/O registers. */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) - ha->mmpbase = ioremap_nocache(base, page_offset + 256); -#else - ha->mmpbase = vremap(base,page_offset + 256); -#endif - if( ha->mmpbase ) - { - ha->mmpbase += page_offset; - /* ha->iobase = ha->mmpbase; */ - status = 0; - } -#else /* MEMORY_MAPPED_IO */ - status = 0; -#endif /* MEMORY_MAPPED_IO */ - } - } - } + /* + * Find proper memory chunk for memory map I/O reg. + */ + base = pci_resource_start(ha->pdev, 1); + size = pci_resource_len(ha->pdev, 1); + /* + * Get virtual address for I/O registers. + */ + ha->mmpbase = ioremap(base, size); + if (ha->mmpbase) { + ha->iobase = (struct device_reg *)ha->mmpbase; + status = 0; + } +#else /* MEMORY_MAPPED_IO */ + status = 0; +#endif /* MEMORY_MAPPED_IO */ - LEAVE("qla1280_pci_config"); - return(status); + LEAVE("qla1280_pci_config"); + return status; } /* @@ -2610,109 +2355,129 @@ * Returns: * 0 = success. */ -STATIC uint8_t -qla1280_chip_diag(scsi_qla_host_t *ha) +static int +qla1280_chip_diag(struct scsi_qla_host *ha) { - device_reg_t *reg = ha->iobase; - uint8_t status = 0; - uint16_t data; - uint32_t cnt; - uint16_t mb[MAILBOX_REGISTER_COUNT]; - -#ifdef QL_DEBUG_LEVEL_3 - sprintf(debug_buff, "qla1280_chip_diag: testing device at 0x%p \n\r",®->id_l); - qla1280_print(debug_buff); -#endif - - /* Soft reset chip and wait for it to finish. */ - WRT_REG_WORD(®->ictrl, ISP_RESET); - data = qla1280_debounce_register(®->ictrl); - for (cnt = 6000000; cnt && data & ISP_RESET; cnt--) - { - SYS_DELAY(5); - data = RD_REG_WORD(®->ictrl); - } - if (cnt) - { - /* Reset register not cleared by chip reset. */ -#if defined(QL_DEBUG_LEVEL_3) - qla1280_print("qla1280_chip_diag: reset register cleared by chip reset\n\r"); -#endif - WRT_REG_WORD(®->cfg_1, 0); - - /* Reset RISC and disable BIOS which - allows RISC to execute out of RAM. */ - WRT_REG_WORD(®->host_cmd, HC_RESET_RISC); - WRT_REG_WORD(®->host_cmd, HC_RELEASE_RISC); - WRT_REG_WORD(®->host_cmd, HC_DISABLE_BIOS); - data = qla1280_debounce_register(®->mailbox0); - for (cnt = 6000000; cnt && data == MBS_BUSY; cnt--) - { - SYS_DELAY(5); - data = RD_REG_WORD(®->mailbox0); - } - - if (cnt) - { - /* Check product ID of chip */ -#if defined(QL_DEBUG_LEVEL_3) - qla1280_print("qla1280_chip_diag: Checking product ID of chip\n\r"); -#endif - if (RD_REG_WORD(®->mailbox1) != PROD_ID_1 || - (RD_REG_WORD(®->mailbox2) != PROD_ID_2 && - RD_REG_WORD(®->mailbox2) != PROD_ID_2a) || - RD_REG_WORD(®->mailbox3) != PROD_ID_3 || - RD_REG_WORD(®->mailbox4) != PROD_ID_4) - { - printk(KERN_INFO "qla1280: Wrong product ID = 0x%x,0x%x,0x%x,0x%x\n", - RD_REG_WORD(®->mailbox1), - RD_REG_WORD(®->mailbox2), - RD_REG_WORD(®->mailbox3), - RD_REG_WORD(®->mailbox4) ); - status = 1; - } - else - { - DEBUG(printk("qla1280_chip_diag: Checking mailboxes of chip\n")); - /* Wrap Incoming Mailboxes Test. */ - mb[0] = MBC_MAILBOX_REGISTER_TEST; - mb[1] = 0xAAAA; - mb[2] = 0x5555; - mb[3] = 0xAA55; - mb[4] = 0x55AA; - mb[5] = 0xA5A5; - mb[6] = 0x5A5A; - mb[7] = 0x2525; - if (!(status = qla1280_mailbox_command(ha, - (BIT_7|BIT_6|BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0), - &mb[0]))) - { - if (mb[1] != 0xAAAA || mb[2] != 0x5555 || - mb[3] != 0xAA55 || mb[4] != 0x55AA) - status = 1; - if (mb[5] != 0xA5A5 || mb[6] != 0x5A5A || - mb[7] != 0x2525) - status = 1; - if( status == 1 ) - printk(KERN_INFO "qla1280: Failed mailbox check\n"); - } - } - } - else - status = 1; - } - else - status = 1; - -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - if (status) - qla1280_print("qla1280_chip_diag: **** FAILED ****\n\r"); -#endif -#ifdef QL_DEBUG_LEVEL_3 - else - qla1280_print("qla1280_chip_diag: exiting normally\n\r"); + uint16_t mb[MAILBOX_REGISTER_COUNT]; + struct device_reg *reg = ha->iobase; + int status = 0; + int cnt; + uint16_t data; + + dprintk(3, "qla1280_chip_diag: testing device at 0x%p \n", ®->id_l); + + dprintk(1, "scsi(%ld): Verifying chip\n", ha->host_no); + + /* Soft reset chip and wait for it to finish. */ + WRT_REG_WORD(®->ictrl, ISP_RESET); + /* + * We can't do a traditional PCI write flush here by reading + * back the register. The card will not respond once the reset + * is in action and we end up with a machine check exception + * instead. Nothing to do but wait and hope for the best. + * A portable pci_write_flush(pdev) call would be very useful here. + */ + udelay(20); + data = qla1280_debounce_register(®->ictrl); + /* + * Yet another QLogic gem ;-( + */ + for (cnt = 1000000; cnt && data & ISP_RESET; cnt--) { + udelay(5); + data = RD_REG_WORD(®->ictrl); + } + + if (cnt) { + /* Reset register cleared by chip reset. */ + dprintk(3, "qla1280_chip_diag: reset register cleared by " + "chip reset\n"); + + WRT_REG_WORD(®->cfg_1, 0); + + /* Reset RISC and disable BIOS which + allows RISC to execute out of RAM. */ +#if 0 + WRT_REG_WORD(®->host_cmd, HC_RESET_RISC); + RD_REG_WORD(®->id_l); /* Flush PCI write */ + WRT_REG_WORD(®->host_cmd, HC_RELEASE_RISC); + RD_REG_WORD(®->id_l); /* Flush PCI write */ + WRT_REG_WORD(®->host_cmd, HC_DISABLE_BIOS); +#else + WRT_REG_WORD(®->host_cmd, HC_RESET_RISC | + HC_RELEASE_RISC | HC_DISABLE_BIOS); #endif - return(status); + RD_REG_WORD(®->id_l); /* Flush PCI write */ + data = qla1280_debounce_register(®->mailbox0); + /* + * I *LOVE* this code! + */ + for (cnt = 1000000; cnt && data == MBS_BUSY; cnt--) { + udelay(5); + data = RD_REG_WORD(®->mailbox0); + } + + if (cnt) { + /* Check product ID of chip */ + dprintk(3, "qla1280_chip_diag: Checking product " + "ID of chip\n"); + + if (RD_REG_WORD(®->mailbox1) != PROD_ID_1 || + (RD_REG_WORD(®->mailbox2) != PROD_ID_2 && + RD_REG_WORD(®->mailbox2) != PROD_ID_2a) || + RD_REG_WORD(®->mailbox3) != PROD_ID_3 || + RD_REG_WORD(®->mailbox4) != PROD_ID_4) { + printk(KERN_INFO "qla1280: Wrong product ID = " + "0x%x,0x%x,0x%x,0x%x\n", + RD_REG_WORD(®->mailbox1), + RD_REG_WORD(®->mailbox2), + RD_REG_WORD(®->mailbox3), + RD_REG_WORD(®->mailbox4)); + status = 1; + } else { + /* + * Enable ints early!!! + */ + qla1280_enable_intrs(ha); + + dprintk(1, "qla1280_chip_diag: Checking " + "mailboxes of chip\n"); + /* Wrap Incoming Mailboxes Test. */ + mb[0] = MBC_MAILBOX_REGISTER_TEST; + mb[1] = 0xAAAA; + mb[2] = 0x5555; + mb[3] = 0xAA55; + mb[4] = 0x55AA; + mb[5] = 0xA5A5; + mb[6] = 0x5A5A; + mb[7] = 0x2525; + if (!(status = qla1280_mailbox_command(ha, + 0xff, + &mb + [0]))) { + if (mb[1] != 0xAAAA || + mb[2] != 0x5555 || + mb[3] != 0xAA55 || + mb[4] != 0x55AA || + mb[5] != 0xA5A5 || + mb[6] != 0x5A5A || + mb[7] != 0x2525) { + status = 1; + printk(KERN_INFO "qla1280: " + "Failed mbox check\n"); + } + } + } + } else + status = 1; + } else + status = 1; + + if (status) + dprintk(2, "qla1280_chip_diag: **** FAILED ****\n"); + else + dprintk(3, "qla1280_chip_diag: exiting normally\n"); + + return status; } /* @@ -2725,173 +2490,142 @@ * Returns: * 0 = success. */ -STATIC uint8_t -qla1280_setup_chip(scsi_qla_host_t *ha) -{ - uint8_t status = 0; - uint16_t risc_address; - uint16_t *risc_code_address; - long risc_code_size; - uint16_t mb[MAILBOX_REGISTER_COUNT]; -#ifdef QLA1280_UNUSED - uint8_t *sp; - int i; -#endif - uint16_t cnt; - int num; - uint8_t *tbuf; - u_long p_tbuf; - -#ifdef QL_DEBUG_LEVEL_3 - ENTER("qla1280_setup_chip"); -#endif - - if( (tbuf = (uint8_t *)KMALLOC(8000) ) == NULL ) - { - printk("setup_chip: couldn't alloacte memory\n"); - return(1); - } - p_tbuf = VIRT_TO_BUS(tbuf); - /* Load RISC code. */ - /* - risc_address = ql12_risc_code_addr01; - risc_code_address = &ql12_risc_code01[0]; - risc_code_size = ql12_risc_code_length01; - */ - risc_address = *QLBoardTbl[ha->devnum].fwstart; - risc_code_address = QLBoardTbl[ha->devnum].fwcode; - risc_code_size = (long)(*QLBoardTbl[ha->devnum].fwlen & 0xffff); - - DEBUG(printk("qla1280: DMAing RISC code (%d) words.\n",(int)risc_code_size)); - DEBUG(sprintf(debug_buff,"qla1280_setup_chip: Loading RISC code size =(%ld).\n\r",risc_code_size);) - DEBUG(qla1280_print(debug_buff)); - num =0; - while (risc_code_size > 0 && !status) - { - cnt = 2000 >> 1; - - if ( cnt > risc_code_size ) - cnt = risc_code_size; - - DEBUG(sprintf(debug_buff,"qla1280_setup_chip: loading risc @ =(0x%p),%d,%d(0x%x).\n\r",risc_code_address,cnt,num,risc_address);) - DEBUG(qla1280_print(debug_buff)); - DEBUG(printk("qla1280_setup_chip: loading risc @ =code=(0x%p),cnt=%d,seg=%d,addr=0x%x\n\r",risc_code_address,cnt,num,risc_address)); - BCOPY((caddr_t) risc_code_address,(caddr_t) ha->request_ring, (cnt <<1)); - mb[0] = MBC_LOAD_RAM; - /* mb[0] = MBC_LOAD_RAM_A64; */ - mb[1] = risc_address; - mb[4] = cnt; - mb[3] = (uint16_t) ha->request_dma & 0xffff; - mb[2] = (uint16_t) (ha->request_dma >> 16) & 0xffff; - mb[7] = (uint16_t) (MS_64BITS(ha->request_dma) & 0xffff); - mb[6] = (uint16_t) (MS_64BITS(ha->request_dma) >> 16) & 0xffff; - DEBUG(printk("qla1280_setup_chip: op=%d 0x%lx = 0x%4x,0x%4x,0x%4x,0x%4x\n",mb[0],ha->request_dma,mb[6],mb[7],mb[2],mb[3])); - if( (status = qla1280_mailbox_command(ha, BIT_4|BIT_3|BIT_2|BIT_1|BIT_0, - &mb[0])) ) - { - printk("Failed to load partial segment of f/w\n"); - break; - } - /* dump it back */ +#define DUMP_IT_BACK 0 /* for debug of RISC loading */ +static int +qla1280_setup_chip(struct scsi_qla_host *ha) +{ + int status = 0; + uint16_t risc_address; + uint16_t *risc_code_address; + int risc_code_size; + uint16_t mb[MAILBOX_REGISTER_COUNT]; + uint16_t cnt; + int num, i; +#if DUMP_IT_BACK + uint8_t *sp; + uint8_t *tbuf; + dma_addr_t p_tbuf; +#endif + + ENTER("qla1280_setup_chip"); + + dprintk(1, "scsi(%ld): Setup chip\n", ha->host_no); + +#if DUMP_IT_BACK + /* get consistent memory allocated for setup_chip */ + tbuf = pci_alloc_consistent(ha->pdev, 8000, &p_tbuf); +#endif + + /* Load RISC code. */ + risc_address = *ql1280_board_tbl[ha->devnum].fwstart; + risc_code_address = ql1280_board_tbl[ha->devnum].fwcode; + risc_code_size = (int) *ql1280_board_tbl[ha->devnum].fwlen; + + dprintk(1, "qla1280_setup_chip: DMA RISC code (%i) words\n", + risc_code_size); + + num = 0; + while (risc_code_size > 0 && !status) { + int warn __attribute__((unused)) = 0; + + cnt = 2000 >> 1; + + if (cnt > risc_code_size) + cnt = risc_code_size; + + dprintk(2, "qla1280_setup_chip: loading risc @ =(0x%p)," + "%d,%d(0x%x)\n", + risc_code_address, cnt, num, risc_address); + for(i = 0; i < cnt; i++) + ((uint16_t *)ha->request_ring)[i] = + cpu_to_le16(risc_code_address[i]); + + flush_cache_all(); + + mb[0] = MBC_LOAD_RAM; + mb[1] = risc_address; + mb[4] = cnt; + mb[3] = ha->request_dma & 0xffff; + mb[2] = (ha->request_dma >> 16) & 0xffff; + mb[7] = pci_dma_hi32(ha->request_dma) & 0xffff; + mb[6] = pci_dma_hi32(ha->request_dma) >> 16; + dprintk(2, "qla1280_setup_chip: op=%d 0x%p = 0x%4x,0x%4x," + "0x%4x,0x%4x\n", mb[0], (void *)(long)ha->request_dma, + mb[6], mb[7], mb[2], mb[3]); + if ((status = qla1280_mailbox_command(ha, BIT_4 | BIT_3 | + BIT_2 | BIT_1 | BIT_0, + &mb[0]))) { + printk(KERN_ERR "scsi(%li): Failed to load partial " + "segment of f\n", ha->host_no); + break; + } -#if 0 - mb[0] = MBC_DUMP_RAM_A64; - mb[1] = risc_address; - mb[4] = cnt; - mb[3] = (uint16_t) p_tbuf & 0xffff; - mb[2] = (uint16_t) (p_tbuf >> 16) & 0xffff; - mb[7] = (uint16_t) (p_tbuf >> 32) & 0xffff; - mb[6] = (uint16_t) (p_tbuf >> 48) & 0xffff; - - if( (status = qla1280_mailbox_command(ha, BIT_4|BIT_3|BIT_2|BIT_1|BIT_0, - &mb[0])) ) - { - printk("Failed to dump partial segment of f/w\n"); - break; - } - sp = (uint8_t *)ha->request_ring; - for (i = 0; i < (cnt<< 1) ; i++) - { - if( tbuf[i] != sp[i] ) - { - printk("qla1280 : firmware compare error @ byte (0x%x)\n",i); - break; - } - } - -#endif - risc_address += cnt; - risc_code_size = risc_code_size - cnt; - risc_code_address = risc_code_address + cnt; - num++; - } -#ifdef QLA1280_UNUSED - DEBUG(ql_debug_print = 0;) - { - for (i = 0; i < ql12_risc_code_length01; i++) - { - mb[0] = 0x4; - mb[1] = ql12_risc_code_addr01 + i; - mb[2] = ql12_risc_code01[i]; - - status = qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, - &mb[0]); - if (status) - { - printk("qla1280 : firmware load failure\n"); - break; - } - - mb[0] = 0x5; - mb[1] = ql12_risc_code_addr01 + i; - mb[2] = 0; - - status = qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, - &mb[0]); - if (status) - { - printk("qla1280 : firmware dump failure\n"); - break; - } - if( mb[2] != ql12_risc_code01[i] ) - printk("qla1280 : firmware compare error @ (0x%x)\n",ql12_risc_code_addr01+i); - } - } - DEBUG(ql_debug_print = 1;) -#endif - - /* Verify checksum of loaded RISC code. */ - if (!status) - { - DEBUG(printk("qla1280_setup_chip: Verifying checksum of loaded RISC code.\n");) - mb[0] = MBC_VERIFY_CHECKSUM; - /* mb[1] = ql12_risc_code_addr01; */ - mb[1] = *QLBoardTbl[ha->devnum].fwstart; - - if (!(status = qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]))) - { - /* Start firmware execution. */ - DEBUG(qla1280_print("qla1280_setup_chip: start firmware running.\n\r");) - mb[0] = MBC_EXECUTE_FIRMWARE; - /* mb[1] = ql12_risc_code_addr01; */ - mb[1] = *QLBoardTbl[ha->devnum].fwstart; - qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]); - } - else - printk("qla1280_setup_chip: Failed checksum.\n"); - } - - KMFREE(tbuf,8000); - -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - if (status) - qla1280_print("qla1280_setup_chip: **** FAILED ****\n\r"); -#endif -#ifdef QL_DEBUG_LEVEL_3 - else - LEAVE("qla1280_setup_chip"); +#if DUMP_IT_BACK + mb[0] = MBC_DUMP_RAM; + mb[1] = risc_address; + mb[4] = cnt; + mb[3] = p_tbuf & 0xffff; + mb[2] = (p_tbuf >> 16) & 0xffff; + mb[7] = pci_dma_hi32(p_tbuf) & 0xffff; + mb[6] = pci_dma_hi32(p_tbuf) >> 16; + + if ((status = qla1280_mailbox_command(ha, + BIT_4 | BIT_3 | BIT_2 | + BIT_1 | BIT_0, + &mb[0]))) { + printk(KERN_ERR + "Failed to dump partial segment of f/w\n"); + break; + } + sp = (uint8_t *)ha->request_ring; + for (i = 0; i < (cnt << 1); i++) { + if (tbuf[i] != sp[i] && warn++ < 10) { + printk(KERN_ERR "qla1280_setup_chip: FW " + "compare error @ byte(0x%x) loop#=%x\n", + i, num); + printk(KERN_ERR "setup_chip: FWbyte=%x " + "FWfromChip=%x\n", sp[i], tbuf[i]); + /*break; */ + } + } +#endif + risc_address += cnt; + risc_code_size = risc_code_size - cnt; + risc_code_address = risc_code_address + cnt; + num++; + } + + /* Verify checksum of loaded RISC code. */ + if (!status) { + dprintk(1, "qla1280_setup_chip: Verifying checksum of " + "loaded RISC code.\n"); + mb[0] = MBC_VERIFY_CHECKSUM; + /* mb[1] = ql12_risc_code_addr01; */ + mb[1] = *ql1280_board_tbl[ha->devnum].fwstart; + + if (!(status = + qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]))) { + /* Start firmware execution. */ + dprintk(1, + "qla1280_setup_chip: start firmware running.\n"); + mb[0] = MBC_EXECUTE_FIRMWARE; + mb[1] = *ql1280_board_tbl[ha->devnum].fwstart; + qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); + } else + printk(KERN_ERR "scsi(%li): qla1280_setup_chip: " + "Failed checksum\n", ha->host_no); + } + +#if DUMP_IT_BACK + /* free consistent memory allocated for setup_chip */ + pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf); #endif - return(status); + + if (status) + dprintk(2, "qla1280_setup_chip: **** FAILED ****\n"); + + LEAVE("qla1280_setup_chip"); + return status; } /* @@ -2907,61 +2641,54 @@ * Returns: * 0 = success. */ -STATIC uint8_t -qla1280_init_rings(scsi_qla_host_t *ha) +static int +qla1280_init_rings(struct scsi_qla_host *ha) { - uint8_t status = 0; - uint16_t cnt; - uint16_t mb[MAILBOX_REGISTER_COUNT]; - -#ifdef QL_DEBUG_LEVEL_3 - ENTER("qla1280_init_rings"); -#endif - /* Clear outstanding commands array. */ - for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) - ha->outstanding_cmds[cnt] = 0; - - /* Initialize request queue. */ - ha->request_ring_ptr = ha->request_ring; - ha->req_ring_index = 0; - ha->req_q_cnt = REQUEST_ENTRY_CNT; - /* mb[0] = MBC_INIT_REQUEST_QUEUE; */ - mb[0] = MBC_INIT_REQUEST_QUEUE_A64; - mb[1] = REQUEST_ENTRY_CNT; - mb[3] = (uint16_t)LS_64BITS(ha->request_dma); - mb[2] = (uint16_t)( LS_64BITS(ha->request_dma) >> 16); - mb[4] = 0; - mb[7] = (uint16_t)MS_64BITS(ha->request_dma); - mb[6] = (uint16_t)( MS_64BITS(ha->request_dma) >> 16); - if (!(status = qla1280_mailbox_command(ha, - BIT_7|BIT_6|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0, - &mb[0]))) - { - /* Initialize response queue. */ - ha->response_ring_ptr = ha->response_ring; - ha->rsp_ring_index = 0; - /* mb[0] = MBC_INIT_RESPONSE_QUEUE; */ - mb[0] = MBC_INIT_RESPONSE_QUEUE_A64; - mb[1] = RESPONSE_ENTRY_CNT; - mb[3] = (uint16_t)LS_64BITS(ha->response_dma); - mb[2] = (uint16_t)(LS_64BITS(ha->response_dma) >> 16); - mb[5] = 0; - mb[7] = (uint16_t)MS_64BITS(ha->response_dma); - mb[6] = (uint16_t)(MS_64BITS(ha->response_dma) >> 16); - status = qla1280_mailbox_command(ha, - BIT_7|BIT_6|BIT_5|BIT_3|BIT_2|BIT_1|BIT_0, - &mb[0]); - } - -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - if (status) - qla1280_print("qla1280_init_rings: **** FAILED ****\n\r"); -#endif -#ifdef QL_DEBUG_LEVEL_3 - else - LEAVE("qla1280_init_rings"); -#endif - return(status); + uint16_t mb[MAILBOX_REGISTER_COUNT]; + int status = 0; + + ENTER("qla1280_init_rings"); + + /* Clear outstanding commands array. */ + memset(ha->outstanding_cmds, 0, + sizeof(struct srb *) * MAX_OUTSTANDING_COMMANDS); + + /* Initialize request queue. */ + ha->request_ring_ptr = ha->request_ring; + ha->req_ring_index = 0; + ha->req_q_cnt = REQUEST_ENTRY_CNT; + /* mb[0] = MBC_INIT_REQUEST_QUEUE; */ + mb[0] = MBC_INIT_REQUEST_QUEUE_A64; + mb[1] = REQUEST_ENTRY_CNT; + mb[3] = ha->request_dma & 0xffff; + mb[2] = (ha->request_dma >> 16) & 0xffff; + mb[4] = 0; + mb[7] = pci_dma_hi32(ha->request_dma) & 0xffff; + mb[6] = pci_dma_hi32(ha->request_dma) >> 16; + if (!(status = qla1280_mailbox_command(ha, BIT_7 | BIT_6 | BIT_4 | + BIT_3 | BIT_2 | BIT_1 | BIT_0, + &mb[0]))) { + /* Initialize response queue. */ + ha->response_ring_ptr = ha->response_ring; + ha->rsp_ring_index = 0; + /* mb[0] = MBC_INIT_RESPONSE_QUEUE; */ + mb[0] = MBC_INIT_RESPONSE_QUEUE_A64; + mb[1] = RESPONSE_ENTRY_CNT; + mb[3] = ha->response_dma & 0xffff; + mb[2] = (ha->response_dma >> 16) & 0xffff; + mb[5] = 0; + mb[7] = pci_dma_hi32(ha->response_dma) & 0xffff; + mb[6] = pci_dma_hi32(ha->response_dma) >> 16; + status = qla1280_mailbox_command(ha, BIT_7 | BIT_6 | BIT_5 | + BIT_3 | BIT_2 | BIT_1 | BIT_0, + &mb[0]); + } + + if (status) + dprintk(2, "qla1280_init_rings: **** FAILED ****\n"); + + LEAVE("qla1280_init_rings"); + return status; } /* @@ -2977,322 +2704,366 @@ * Returns: * 0 = success. */ -STATIC uint8_t -qla1280_nvram_config(scsi_qla_host_t *ha) +static int +qla1280_nvram_config(struct scsi_qla_host *ha) { - device_reg_t *reg = ha->iobase; - nvram_t *nv = (nvram_t *)ha->response_ring; - uint8_t status = 0; - uint32_t b, t, l; - uint16_t *wptr; - uint16_t mb[MAILBOX_REGISTER_COUNT]; - uint8_t cnt; - uint8_t chksum; - uint32_t nvsize; - -#if defined(QL_DEBUG_ROUTINES) && !defined(QL_DEBUG_LEVEL_4) - uint8_t saved_print_status = ql_debug_print; -#endif - ENTER("qla1280_nvram_config"); -#if defined(QL_DEBUG_ROUTINES) && !defined(QL_DEBUG_LEVEL_4) - ql_debug_print = FALSE; -#endif - - /* Verify valid NVRAM checksum. */ -#if USE_NVRAM_DEFAULTS - chksum = 1; -#else - wptr = (uint16_t *)ha->response_ring; - chksum = 0; - if( ha->device_id == QLA12160_DEVICE_ID || - ha->device_id == QLA10160_DEVICE_ID ) - nvsize = sizeof(nvram160_t)/2; - else - nvsize = sizeof(nvram_t)/2; - for( cnt = 0; cnt < nvsize; cnt++ ) - { - *wptr = qla1280_get_nvram_word(ha, cnt); - chksum += (uint8_t)*wptr; - chksum += (uint8_t)(*wptr >> 8); - wptr++; - } -#endif - + struct device_reg *reg = ha->iobase; + struct nvram *nv; + int is1x160, status = 0; + int bus, target, lun; + uint16_t mb[MAILBOX_REGISTER_COUNT]; + uint16_t mask; + + ENTER("qla1280_nvram_config"); + + if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 || + ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160) + is1x160 = 1; + else + is1x160 = 0; - /* Bad NVRAM data, set defaults parameters. */ - if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || - nv->id[2] != 'P' || nv->id[3] != ' ' || nv->version < 1) - { -#if USE_NVRAM_DEFAULTS - DEBUG(printk("Using defaults for NVRAM\n")); + nv = &ha->nvram; + if (!ha->nvram_valid) { + dprintk(1, "Using defaults for NVRAM: \n"); + memset(nv, 0, sizeof(struct nvram)); + + /* nv->cntr_flags_1.disable_loading_risc_code = 1; */ + nv->firmware_feature.f.enable_fast_posting = 1; + nv->firmware_feature.f.disable_synchronous_backoff = 1; + + nv->termination.f.scsi_bus_0_control = 3; + nv->termination.f.scsi_bus_1_control = 3; + nv->termination.f.auto_term_support = 1; + + /* + * Set default FIFO magic - What appropriate values + * would be here is unknown. This is what I have found + * testing with 12160s. + * Now, I would love the magic decoder ring for this one, + * the header file provided by QLogic seems to be bogus + * or incomplete at best. + */ + nv->isp_config.c = 0x44; + + if (is1x160) + nv->isp_parameter = 0x01; + + for (bus = 0; bus < MAX_BUSES; bus++) { + nv->bus[bus].config_1.initiator_id = 7; + nv->bus[bus].bus_reset_delay = 5; + /* 8 = 5.0 clocks */ + nv->bus[bus].config_2.async_data_setup_time = 8; + nv->bus[bus].config_2.req_ack_active_negation = 1; + nv->bus[bus].config_2.data_line_active_negation = 1; + nv->bus[bus].selection_timeout = 250; + nv->bus[bus].max_queue_depth = 256; + + for (target = 0; target < MAX_TARGETS; target++) { + nv->bus[bus].target[target].parameter.f. + renegotiate_on_error = 1; + nv->bus[bus].target[target].parameter.f. + auto_request_sense = 1; + nv->bus[bus].target[target].parameter.f. + tag_queuing = 1; + nv->bus[bus].target[target].parameter.f. + enable_sync = 1; +#if 1 /* Some SCSI Processors do not seem to like this */ + nv->bus[bus].target[target].parameter.f. + enable_wide = 1; +#endif + nv->bus[bus].target[target].parameter.f. + parity_checking = 1; + nv->bus[bus].target[target].parameter.f. + disconnect_allowed = 1; + nv->bus[bus].target[target].execution_throttle= + nv->bus[bus].max_queue_depth - 1; + if (is1x160) { + nv->bus[bus].target[target].flags. + flags1x160.device_enable = 1; + nv->bus[bus].target[target].flags. + flags1x160.sync_offset = 0x0e; + nv->bus[bus].target[target]. + sync_period = 9; + nv->bus[bus].target[target]. + ppr_1x160.flags.enable_ppr = 1; + nv->bus[bus].target[target].ppr_1x160. + flags.ppr_options = 2; + nv->bus[bus].target[target].ppr_1x160. + flags.ppr_bus_width = 1; + } else { + nv->bus[bus].target[target].flags. + flags1x80.device_enable = 1; + nv->bus[bus].target[target].flags. + flags1x80.sync_offset = 0x8; + nv->bus[bus].target[target]. + sync_period = 10; + } + } + } + } else { + /* Always force AUTO sense for LINUX SCSI */ + for (bus = 0; bus < MAX_BUSES; bus++) + for (target = 0; target < MAX_TARGETS; target++) { + nv->bus[bus].target[target].parameter.f. + auto_request_sense = 1; + } + } + dprintk(1, "qla1280 : initiator scsi id bus[0]=%d\n", + nv->bus[0].config_1.initiator_id); + dprintk(1, "qla1280 : initiator scsi id bus[1]=%d\n", + nv->bus[1].config_1.initiator_id); + + dprintk(1, "qla1280 : bus reset delay[0]=%d\n", + nv->bus[0].bus_reset_delay); + dprintk(1, "qla1280 : bus reset delay[1]=%d\n", + nv->bus[1].bus_reset_delay); + + dprintk(1, "qla1280 : retry count[0]=%d\n", nv->bus[0].retry_count); + dprintk(1, "qla1280 : retry delay[0]=%d\n", nv->bus[0].retry_delay); + dprintk(1, "qla1280 : retry count[1]=%d\n", nv->bus[1].retry_count); + dprintk(1, "qla1280 : retry delay[1]=%d\n", nv->bus[1].retry_delay); + + dprintk(1, "qla1280 : async data setup time[0]=%d\n", + nv->bus[0].config_2.async_data_setup_time); + dprintk(1, "qla1280 : async data setup time[1]=%d\n", + nv->bus[1].config_2.async_data_setup_time); + + dprintk(1, "qla1280 : req/ack active negation[0]=%d\n", + nv->bus[0].config_2.req_ack_active_negation); + dprintk(1, "qla1280 : req/ack active negation[1]=%d\n", + nv->bus[1].config_2.req_ack_active_negation); + + dprintk(1, "qla1280 : data line active negation[0]=%d\n", + nv->bus[0].config_2.data_line_active_negation); + dprintk(1, "qla1280 : data line active negation[1]=%d\n", + nv->bus[1].config_2.data_line_active_negation); + + dprintk(1, "qla1280 : disable loading risc code=%d\n", + nv->cntr_flags_1.disable_loading_risc_code); + + dprintk(1, "qla1280 : enable 64bit addressing=%d\n", + nv->cntr_flags_1.enable_64bit_addressing); + + dprintk(1, "qla1280 : selection timeout limit[0]=%d\n", + nv->bus[0].selection_timeout); + dprintk(1, "qla1280 : selection timeout limit[1]=%d\n", + nv->bus[1].selection_timeout); + + dprintk(1, "qla1280 : max queue depth[0]=%d\n", + nv->bus[0].max_queue_depth); + dprintk(1, "qla1280 : max queue depth[1]=%d\n", + nv->bus[1].max_queue_depth); + + /* Disable RISC load of firmware. */ + ha->flags.disable_risc_code_load = + nv->cntr_flags_1.disable_loading_risc_code; + +#ifdef QLA_64BIT_PTR + /* Enable 64bit addressing for OS/System combination supporting it */ + /* actual NVRAM bit is: nv->cntr_flags_1.enable_64bit_addressing */ + /* but we will ignore it and use BITS_PER_LONG macro to setup for */ + /* 64 or 32 bit access of host memory in all x86/ia-64/Alpha systems */ + ha->flags.enable_64bit_addressing = 1; #else - DEBUG(printk("Using defaults for NVRAM: \n")); - DEBUG(printk("checksum=0x%x, Id=%c, version=0x%x\n",chksum,nv->id[0],nv->version)); -#if defined(QL_DEBUG_LEVEL_3) - /* ql_debug_print = 1; - qla1280_dump_buffer((caddr_t)ha->response_ring, REQUEST_ENTRY_SIZE); - ql_debug_print = 0; */ -#endif - wptr = (uint16_t *)ha->response_ring; - for (cnt = 0; cnt < sizeof(nvram_t)/2; cnt++) - *wptr++ = 0; + ha->flags.enable_64bit_addressing = 0; #endif + if (ha->flags.enable_64bit_addressing) { + dprintk(2, "scsi(%li): 64 Bit PCI Addressing Enabled\n", + ha->host_no); - /* nv->cntr_flags_1.disable_loading_risc_code = 1; */ - nv->firmware_feature.w = BIT_0; - nv->termination.f.scsi_bus_0_control = 3; - nv->termination.f.scsi_bus_1_control = 3; - nv->termination.f.auto_term_support = 1; - - for (b = 0; b < MAX_BUSES; b++) - { - nv->bus[b].config_1.initiator_id = 7; - nv->bus[b].bus_reset_delay = 5; - nv->bus[b].config_2.async_data_setup_time = 9; - nv->bus[b].config_2.req_ack_active_negation = 1; - nv->bus[b].config_2.data_line_active_negation = 1; - nv->bus[b].selection_timeout = 250; - nv->bus[b].max_queue_depth = 256; - - for (t = 0; t < MAX_TARGETS; t++) - { - nv->bus[b].target[t].parameter.f.auto_request_sense = 1; - nv->bus[b].target[t].parameter.f.disconnect_allowed = 1; - nv->bus[b].target[t].parameter.f.tag_queuing = 1; - nv->bus[b].target[t].flags.device_enable = 1; - } - } + pci_set_dma_mask(ha->pdev, (dma_addr_t) ~ 0ULL); + } -#if USE_NVRAM_DEFAULTS - status = 0; -#else - status = 1; + /* Set ISP hardware DMA burst */ + mb[0] = nv->isp_config.c; + /* Enable DMA arbitration on dual channel controllers */ + if (ha->ports > 1) + mb[0] |= BIT_13; + WRT_REG_WORD(®->cfg_1, mb[0]); + +#if 1 /* Is this safe? */ + /* Set SCSI termination. */ + WRT_REG_WORD(®->gpio_enable, (BIT_3 + BIT_2 + BIT_1 + BIT_0)); + mb[0] = nv->termination.c & (BIT_3 + BIT_2 + BIT_1 + BIT_0); + WRT_REG_WORD(®->gpio_data, mb[0]); +#endif + + /* ISP parameter word. */ + mb[0] = MBC_SET_SYSTEM_PARAMETER; + mb[1] = nv->isp_parameter; + status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); + +#if 0 + /* clock rate - for qla1240 and older, only */ + mb[0] = MBC_SET_CLOCK_RATE; + mb[1] = 0x50; + status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); +#endif + /* Firmware feature word. */ + mb[0] = MBC_SET_FIRMWARE_FEATURES; + mask = BIT_5 | BIT_1 | BIT_0; + mb[1] = le16_to_cpu(nv->firmware_feature.w) & (mask); +#if defined(CONFIG_IA64_GENERIC) || defined (CONFIG_IA64_SGI_SN2) + if (ia64_platform_is("sn2")) { + printk(KERN_INFO "scsi(%li): Enabling SN2 PCI DMA " + "workaround\n", ha->host_no); + mb[1] |= BIT_9; + } #endif - } - else - { - /* Always force AUTO sense for LINUX SCSI */ - for (b = 0; b < MAX_BUSES; b++) - for (t = 0; t < MAX_TARGETS; t++) - { - nv->bus[b].target[t].parameter.f.auto_request_sense = 1; - } - } -#if DEBUG_PRINT_NVRAM - ql_debug_print = 1; - sprintf(debug_buff,"qla1280 : initiator scsi id bus[0]=%d\n\r", - nv->bus[0].config_1.initiator_id); - qla1280_print(debug_buff); - sprintf(debug_buff,"qla1280 : initiator scsi id bus[1]=%d\n\r", - nv->bus[1].config_1.initiator_id); - qla1280_print(debug_buff); - - sprintf(debug_buff,"qla1280 : bus reset delay[0]=%d\n\r", - nv->bus[0].bus_reset_delay); - qla1280_print(debug_buff); - sprintf(debug_buff,"qla1280 : bus reset delay[1]=%d\n\r", - nv->bus[1].bus_reset_delay); - qla1280_print(debug_buff); - - sprintf(debug_buff,"qla1280 : retry count[0]=%d\n\r", - nv->bus[0].retry_count); - qla1280_print(debug_buff); - sprintf(debug_buff,"qla1280 : retry delay[0]=%d\n\r", - nv->bus[0].retry_delay); - qla1280_print(debug_buff); - sprintf(debug_buff,"qla1280 : retry count[1]=%d\n\r", - nv->bus[1].retry_count); - qla1280_print(debug_buff); - sprintf(debug_buff,"qla1280 : retry delay[1]=%d\n\r", - nv->bus[1].retry_delay); - qla1280_print(debug_buff); - - sprintf(debug_buff,"qla1280 : async data setup time[0]=%d\n\r", - nv->bus[0].config_2.async_data_setup_time); - qla1280_print(debug_buff); - sprintf(debug_buff,"qla1280 : async data setup time[1]=%d\n\r", - nv->bus[1].config_2.async_data_setup_time); - qla1280_print(debug_buff); - - sprintf(debug_buff,"qla1280 : req/ack active negation[0]=%d\n\r", - nv->bus[0].config_2.req_ack_active_negation); - qla1280_print(debug_buff); - sprintf(debug_buff,"qla1280 : req/ack active negation[1]=%d\n\r", - nv->bus[1].config_2.req_ack_active_negation); - qla1280_print(debug_buff); - - sprintf(debug_buff,"qla1280 : data line active negation[0]=%d\n\r", - nv->bus[0].config_2.data_line_active_negation); - qla1280_print(debug_buff); - sprintf(debug_buff,"qla1280 : data line active negation[1]=%d\n\r", - nv->bus[1].config_2.data_line_active_negation); - qla1280_print(debug_buff); - - - sprintf(debug_buff,"qla1280 : disable loading risc code=%d\n\r", - nv->cntr_flags_1.disable_loading_risc_code); - qla1280_print(debug_buff); - - sprintf(debug_buff,"qla1280 : enable 64bit addressing=%d\n\r", - nv->cntr_flags_1.enable_64bit_addressing); - qla1280_print(debug_buff); - - sprintf(debug_buff,"qla1280 : selection timeout limit[0]=%d\n\r", - nv->bus[0].selection_timeout); - qla1280_print(debug_buff); - sprintf(debug_buff,"qla1280 : selection timeout limit[1]=%d\n\r", - nv->bus[1].selection_timeout); - - qla1280_print(debug_buff); - sprintf(debug_buff,"qla1280 : max queue depth[0]=%d\n\r", - nv->bus[0].max_queue_depth); - qla1280_print(debug_buff); - sprintf(debug_buff,"qla1280 : max queue depth[1]=%d\n\r", - nv->bus[1].max_queue_depth); - qla1280_print(debug_buff); -#endif - - DEBUG(ql_debug_print = 0;) - - /* Disable RISC load of firmware. */ - ha->flags.disable_risc_code_load = - nv->cntr_flags_1.disable_loading_risc_code; - /* Enable 64bit addressing. */ - ha->flags.enable_64bit_addressing = - nv->cntr_flags_1.enable_64bit_addressing; - - /* Set ISP hardware DMA burst */ - mb[0] = nv->isp_config.c; - WRT_REG_WORD(®->cfg_1, mb[0]); - - /* Set SCSI termination. */ - WRT_REG_WORD(®->gpio_enable, (BIT_3 + BIT_2 + BIT_1 + BIT_0)); - mb[0] = nv->termination.c & (BIT_3 + BIT_2 + BIT_1 + BIT_0); - WRT_REG_WORD(®->gpio_data, mb[0]); - - /* ISP parameter word. */ - mb[0] = MBC_SET_SYSTEM_PARAMETER; - mb[1] = nv->isp_parameter; - status |= qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]); - - /* Firmware feature word. */ - mb[0] = MBC_SET_FIRMWARE_FEATURES; - mb[1] = nv->firmware_feature.w & (BIT_1|BIT_0); - status |= qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]); - - /* Retry count and delay. */ - mb[0] = MBC_SET_RETRY_COUNT; - mb[1] = nv->bus[0].retry_count; - mb[2] = nv->bus[0].retry_delay; - mb[6] = nv->bus[1].retry_count; - mb[7] = nv->bus[1].retry_delay; - status |= qla1280_mailbox_command(ha, BIT_7|BIT_6|BIT_2|BIT_1|BIT_0, &mb[0]); - - /* ASYNC data setup time. */ - mb[0] = MBC_SET_ASYNC_DATA_SETUP; - mb[1] = nv->bus[0].config_2.async_data_setup_time; - mb[2] = nv->bus[1].config_2.async_data_setup_time; - status |= qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, &mb[0]); - - /* Active negation states. */ - mb[0] = MBC_SET_ACTIVE_NEGATION; - mb[1] = 0; - if (nv->bus[0].config_2.req_ack_active_negation) - mb[1] |= BIT_5; - if (nv->bus[0].config_2.data_line_active_negation) - mb[1] |= BIT_4; - mb[2] = 0; - if (nv->bus[1].config_2.req_ack_active_negation) - mb[2] |= BIT_5; - if (nv->bus[1].config_2.data_line_active_negation) - mb[2] |= BIT_4; - status |= qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, &mb[0]); - - /* Selection timeout. */ - mb[0] = MBC_SET_SELECTION_TIMEOUT; - mb[1] = nv->bus[0].selection_timeout; - mb[2] = nv->bus[1].selection_timeout; - status |= qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, &mb[0]); - - for (b = 0; b < ha->ports; b++) - { - /* SCSI Reset Disable. */ - ha->bus_settings[b].disable_scsi_reset = nv->bus[b].config_1.scsi_reset_disable; - - /* Initiator ID. */ - ha->bus_settings[b].id = nv->bus[b].config_1.initiator_id; - mb[0] = MBC_SET_INITIATOR_ID; - mb[1] = b ? ha->bus_settings[b].id | BIT_7 : ha->bus_settings[b].id; - status |= qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]); - - /* Reset Delay. */ - ha->bus_settings[b].bus_reset_delay = nv->bus[b].bus_reset_delay; - - /* Command queue depth per device. */ - ha->bus_settings[b].hiwat = nv->bus[b].max_queue_depth - 1; - - /* Set target parameters. */ - for (t = 0; t < MAX_TARGETS; t++) - { - if( ha->device_id == QLA12160_DEVICE_ID || - ha->device_id == QLA10160_DEVICE_ID ) - { - status = qla12160_set_target_parameters(ha,b,t,0,(nvram160_t *)nv); - } + status |= qla1280_mailbox_command(ha, mask, &mb[0]); + + /* Retry count and delay. */ + mb[0] = MBC_SET_RETRY_COUNT; + mb[1] = nv->bus[0].retry_count; + mb[2] = nv->bus[0].retry_delay; + mb[6] = nv->bus[1].retry_count; + mb[7] = nv->bus[1].retry_delay; + status |= qla1280_mailbox_command(ha, BIT_7 | BIT_6 | BIT_2 | + BIT_1 | BIT_0, &mb[0]); + + /* ASYNC data setup time. */ + mb[0] = MBC_SET_ASYNC_DATA_SETUP; + mb[1] = nv->bus[0].config_2.async_data_setup_time; + mb[2] = nv->bus[1].config_2.async_data_setup_time; + status |= qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]); + + /* Active negation states. */ + mb[0] = MBC_SET_ACTIVE_NEGATION; + mb[1] = 0; + if (nv->bus[0].config_2.req_ack_active_negation) + mb[1] |= BIT_5; + if (nv->bus[0].config_2.data_line_active_negation) + mb[1] |= BIT_4; + mb[2] = 0; + if (nv->bus[1].config_2.req_ack_active_negation) + mb[2] |= BIT_5; + if (nv->bus[1].config_2.data_line_active_negation) + mb[2] |= BIT_4; + status |= qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]); + + mb[0] = MBC_SET_DATA_OVERRUN_RECOVERY; + mb[1] = 2; /* Reset SCSI bus and return all outstanding IO */ + status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); + + /* thingy */ + mb[0] = MBC_SET_PCI_CONTROL; + mb[1] = 2; /* Data DMA Channel Burst Enable */ + mb[2] = 2; /* Command DMA Channel Burst Enable */ + status |= qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]); + + /* Selection timeout. */ + mb[0] = MBC_SET_SELECTION_TIMEOUT; + mb[1] = nv->bus[0].selection_timeout; + mb[2] = nv->bus[1].selection_timeout; + status |= qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]); + + for (bus = 0; bus < ha->ports; bus++) { + /* SCSI Reset Disable. */ + ha->bus_settings[bus].disable_scsi_reset = + nv->bus[bus].config_1.scsi_reset_disable; + + /* Initiator ID. */ + ha->bus_settings[bus].id = nv->bus[bus].config_1.initiator_id; + mb[0] = MBC_SET_INITIATOR_ID; + mb[1] = bus ? ha->bus_settings[bus].id | BIT_7 : + ha->bus_settings[bus].id; + status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); + + /* Reset Delay. */ + ha->bus_settings[bus].bus_reset_delay = + nv->bus[bus].bus_reset_delay; + + /* Command queue depth per device. */ + ha->bus_settings[bus].hiwat = nv->bus[bus].max_queue_depth - 1; + + /* Set target parameters. */ + for (target = 0; target < MAX_TARGETS; target++) { + uint8_t mr = BIT_2 | BIT_1 | BIT_0; + + /* Set Target Parameters. */ + mb[0] = MBC_SET_TARGET_PARAMETERS; + mb[1] = (uint16_t) (bus ? target | BIT_7 : target); + mb[1] <<= 8; + /* + * Do not enable wide, sync, and ppr for the initial + * INQUIRY run. We enable this later if we determine + * the target actually supports it. + */ + nv->bus[bus].target[target].parameter.f. + auto_request_sense = 1; + nv->bus[bus].target[target].parameter.f. + stop_queue_on_check = 0; + + if (is1x160) + nv->bus[bus].target[target].ppr_1x160. + flags.enable_ppr = 0; + /* + * No sync, wide, etc. while probing + */ + mb[2] = (nv->bus[bus].target[target].parameter.c << 8)& + ~(TP_SYNC /*| TP_WIDE | TP_PPR*/); + + if (is1x160) + mb[3] = nv->bus[bus].target[target].flags.flags1x160.sync_offset << 8; else - { - /* Set Target Parameters. */ - mb[0] = MBC_SET_TARGET_PARAMETERS; - mb[1] = (uint16_t)(b ? t | BIT_7 :t); - mb[1] <<= 8; - mb[2] = nv->bus[b].target[t].parameter.c << 8; - mb[2] |= TP_AUTO_REQUEST_SENSE; - mb[2] &= ~TP_STOP_QUEUE; - mb[3] = nv->bus[b].target[t].flags.sync_offset << 8; - mb[3] |= nv->bus[b].target[t].sync_period; - status |= qla1280_mailbox_command(ha, BIT_3|BIT_2|BIT_1|BIT_0, - &mb[0]); - } - - /* Save Tag queuing enable flag. */ - mb[0] = BIT_0 << t; - if (nv->bus[b].target[t].parameter.f.tag_queuing) - ha->bus_settings[b].qtag_enables |= mb[0]; - - /* Save Device enable flag. */ - if (nv->bus[b].target[t].flags.device_enable) - ha->bus_settings[b].device_enables |= mb[0]; - - /* Save LUN disable flag. */ - if (nv->bus[b].target[t].flags.lun_disable) - ha->bus_settings[b].lun_disables |= mb[0]; - - /* Set Device Queue Parameters. */ - for (l = 0; l < MAX_LUNS; l++) - { - mb[0] = MBC_SET_DEVICE_QUEUE; - mb[1] = (uint16_t)(b ? t | BIT_7 :t); - mb[1] = mb[1] << 8 | l; - mb[2] = nv->bus[b].max_queue_depth; - mb[3] = nv->bus[b].target[t].execution_throttle; - status |= qla1280_mailbox_command(ha, BIT_3|BIT_2|BIT_1|BIT_0, - &mb[0]); - } - } - } - DEBUG(ql_debug_print = 0;) - -#if defined(QL_DEBUG_ROUTINES) && !defined(QL_DEBUG_LEVEL_4) - ql_debug_print = saved_print_status; -#endif - -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - DEBUG(if (status)) - DEBUG(qla1280_print("qla1280_nvram_config: **** FAILED ****\n\r");) -#endif - LEAVE("qla1280_nvram_config"); - return(status); + mb[3] = nv->bus[bus].target[target].flags.flags1x80.sync_offset << 8; + mb[3] |= nv->bus[bus].target[target].sync_period; + mr |= BIT_3; + + /* + * We don't want to enable ppr etc. before we have + * determined that the target actually supports it + */ +#if 0 + if (is1x160) { + mb[2] |= nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr << 5; + + mb[6] = nv->bus[bus].target[target].ppr_1x160.flags.ppr_options << 8; + mb[6] |= nv->bus[bus].target[target].ppr_1x160.flags.ppr_bus_width; + mr |= BIT_6; + } +#endif + + status = qla1280_mailbox_command(ha, mr, &mb[0]); + + /* Save Tag queuing enable flag. */ + mb[0] = BIT_0 << target; + if (nv->bus[bus].target[target].parameter.f.tag_queuing) + ha->bus_settings[bus].qtag_enables |= mb[0]; + + /* Save Device enable flag. */ + if (is1x160) { + if (nv->bus[bus].target[target].flags.flags1x160.device_enable) + ha->bus_settings[bus].device_enables |= mb[0]; + ha->bus_settings[bus].lun_disables |= 0; + } else { + if (nv->bus[bus].target[target].flags.flags1x80.device_enable) + ha->bus_settings[bus].device_enables |= mb[0]; + /* Save LUN disable flag. */ + if (nv->bus[bus].target[target].flags.flags1x80.lun_disable) + ha->bus_settings[bus].lun_disables |= mb[0]; + } + + + /* Set Device Queue Parameters. */ + for (lun = 0; lun < MAX_LUNS; lun++) { + mb[0] = MBC_SET_DEVICE_QUEUE; + mb[1] = (uint16_t)(bus ? target | BIT_7 : target); + mb[1] = mb[1] << 8 | lun; + mb[2] = nv->bus[bus].max_queue_depth; + mb[3] = nv->bus[bus].target[target].execution_throttle; + status |= qla1280_mailbox_command(ha, 0x0f, + &mb[0]); + } + } + } + + if (status) + dprintk(2, "qla1280_nvram_config: **** FAILED ****\n"); + + LEAVE("qla1280_nvram_config"); + return status; } /* @@ -3307,36 +3078,21 @@ * Returns: * data word. */ -STATIC uint16_t -qla1280_get_nvram_word(scsi_qla_host_t *ha, uint32_t address) +static uint16_t +qla1280_get_nvram_word(struct scsi_qla_host *ha, uint32_t address) { - uint32_t nv_cmd; - uint16_t data; + uint32_t nv_cmd; + uint16_t data; -#ifdef QL_DEBUG_ROUTINES - uint8_t saved_print_status = ql_debug_print; -#endif -#ifdef QL_DEBUG_LEVEL_4 - ENTER("qla1280_get_nvram_word"); -#endif + nv_cmd = address << 16; + nv_cmd |= NV_READ_OP; - nv_cmd = address << 16; - nv_cmd |= NV_READ_OP; + data = le16_to_cpu(qla1280_nvram_request(ha, nv_cmd)); -#ifdef QL_DEBUG_ROUTINES - ql_debug_print = FALSE; -#endif - data = qla1280_nvram_request(ha, nv_cmd); -#ifdef QL_DEBUG_ROUTINES - ql_debug_print = saved_print_status; -#endif + dprintk(8, "qla1280_get_nvram_word: exiting normally NVRAM data = " + "0x%x", data); -#ifdef QL_DEBUG_LEVEL_4 - qla1280_print("qla1280_get_nvram_word: exiting normally NVRAM data = "); - qla1280_output_number((uint32_t)data, 16); - qla1280_print("\n\r"); -#endif - return(data); + return data; } /* @@ -3353,76 +3109,63 @@ * Returns: * data word. */ -STATIC uint16_t -qla1280_nvram_request(scsi_qla_host_t *ha, uint32_t nv_cmd) +static uint16_t +qla1280_nvram_request(struct scsi_qla_host *ha, uint32_t nv_cmd) +{ + struct device_reg *reg = ha->iobase; + int cnt; + uint16_t data = 0; + uint16_t reg_data; + + /* Send command to NVRAM. */ + + nv_cmd <<= 5; + for (cnt = 0; cnt < 11; cnt++) { + if (nv_cmd & BIT_31) + qla1280_nv_write(ha, NV_DATA_OUT); + else + qla1280_nv_write(ha, 0); + nv_cmd <<= 1; + } + + /* Read data from NVRAM. */ + + for (cnt = 0; cnt < 16; cnt++) { + WRT_REG_WORD(®->nvram, (NV_SELECT | NV_CLOCK)); + RD_REG_WORD(®->id_l); /* Flush PCI write */ + NVRAM_DELAY(); + data <<= 1; + reg_data = RD_REG_WORD(®->nvram); + if (reg_data & NV_DATA_IN) + data |= BIT_0; + WRT_REG_WORD(®->nvram, NV_SELECT); + RD_REG_WORD(®->id_l); /* Flush PCI write */ + NVRAM_DELAY(); + } + + /* Deselect chip. */ + + WRT_REG_WORD(®->nvram, NV_DESELECT); + RD_REG_WORD(®->id_l); /* Flush PCI write */ + NVRAM_DELAY(); + + return data; +} + +static void +qla1280_nv_write(struct scsi_qla_host *ha, uint16_t data) { - uint8_t cnt; - device_reg_t *reg = ha->iobase; - uint16_t data = 0; - uint16_t reg_data; - - /* Send command to NVRAM. */ - - nv_cmd <<= 5; - for (cnt = 0; cnt < 11; cnt++) - { - if (nv_cmd & BIT_31) - qla1280_nv_write(ha, NV_DATA_OUT); - else - qla1280_nv_write(ha, 0); - nv_cmd <<= 1; - } - - /* Read data from NVRAM. */ - - for (cnt = 0; cnt < 16; cnt++) - { - WRT_REG_WORD(®->nvram, NV_SELECT+NV_CLOCK); - /* qla1280_nv_delay(ha); */ - NVRAM_DELAY(); - data <<= 1; - reg_data = RD_REG_WORD(®->nvram); - if (reg_data & NV_DATA_IN) - data |= BIT_0; - WRT_REG_WORD(®->nvram, NV_SELECT); - /* qla1280_nv_delay(ha); */ - NVRAM_DELAY(); - } - - /* Deselect chip. */ - - WRT_REG_WORD(®->nvram, NV_DESELECT); - /* qla1280_nv_delay(ha); */ - NVRAM_DELAY(); - - return(data); -} - -STATIC void -qla1280_nv_write(scsi_qla_host_t *ha, uint16_t data) -{ - device_reg_t *reg = ha->iobase; - - WRT_REG_WORD(®->nvram, data | NV_SELECT); - NVRAM_DELAY(); - /* qla1280_nv_delay(ha); */ - WRT_REG_WORD(®->nvram, data | NV_SELECT | NV_CLOCK); - /* qla1280_nv_delay(ha); */ - NVRAM_DELAY(); - WRT_REG_WORD(®->nvram, data | NV_SELECT); - /* qla1280_nv_delay(ha); */ - NVRAM_DELAY(); -} - -STATIC void -qla1280_nv_delay(scsi_qla_host_t *ha) -{ - device_reg_t *reg = ha->iobase; - int cnt = NV_DELAY_COUNT; - uint16_t data = 0; + struct device_reg *reg = ha->iobase; - while (cnt--) - data |= RD_REG_WORD(®->nvram); + WRT_REG_WORD(®->nvram, data | NV_SELECT); + RD_REG_WORD(®->id_l); /* Flush PCI write */ + NVRAM_DELAY(); + WRT_REG_WORD(®->nvram, data | NV_SELECT | NV_CLOCK); + RD_REG_WORD(®->id_l); /* Flush PCI write */ + NVRAM_DELAY(); + WRT_REG_WORD(®->nvram, data | NV_SELECT); + RD_REG_WORD(®->id_l); /* Flush PCI write */ + NVRAM_DELAY(); } /* @@ -3440,112 +3183,108 @@ * Returns: * 0 = success */ -STATIC uint8_t -qla1280_mailbox_command(scsi_qla_host_t *ha, uint8_t mr, uint16_t *mb) +static int +qla1280_mailbox_command(struct scsi_qla_host *ha, uint8_t mr, uint16_t *mb) { - device_reg_t *reg = ha->iobase; - uint8_t status = 0; - uint32_t cnt; - uint16_t *optr, *iptr; - uint16_t data; - srb_t *done_q_first = 0; - srb_t *done_q_last = 0; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) - unsigned long cpu_flags = 0; -#endif - -#ifdef QL_DEBUG_LEVEL_3 - ENTER("qla1280_mailbox_command"); -#endif - - /* Acquire interrupt specific lock */ - QLA1280_INTR_LOCK(ha); - DRIVER_LOCK - ha->flags.mbox_busy = TRUE; - - /* Load mailbox registers. */ - optr = (uint16_t *)®->mailbox0; - iptr = mb; - for (cnt = 0; cnt < MAILBOX_REGISTER_COUNT; cnt++) - { - if (mr & BIT_0) - { - WRT_REG_WORD(optr, (*iptr)); - } - - mr >>= 1; - optr++; - iptr++; - } - /* Issue set host interrupt command. */ - ha->flags.mbox_int = FALSE; - WRT_REG_WORD(®->host_cmd, HC_SET_HOST_INT); - data = qla1280_debounce_register(®->istatus); - - /* Wait for 30 seconds for command to finish. */ - for (cnt = 30000000; cnt > 0 && !ha->flags.mbox_int; cnt--) - { - /* Check for pending interrupts. */ - if (data & RISC_INT) - { - qla1280_isr(ha, (srb_t **)&done_q_first, (srb_t **)&done_q_last); - } - SYS_DELAY(1); - data = RD_REG_WORD(®->istatus); - } - - /* Check for mailbox command timeout. */ - if ( !cnt ) - { -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print( - "qla1280_mailbox_command: **** Command Timeout, mailbox0 = "); - qla1280_output_number((uint32_t)mb[0], 16); - qla1280_print(" ****\n\r"); -#endif - ha->flags.isp_abort_needed = TRUE; - status = 1; - } - else if (ha->mailbox_out[0] != MBS_CMD_CMP) - status = 1; - - /* Load return mailbox registers. */ - optr = mb; - iptr = (uint16_t *)&ha->mailbox_out[0]; - mr = MAILBOX_REGISTER_COUNT; - while (mr--) - *optr++ = *iptr++; - - /* Go check for any response interrupts pending. */ - ha->flags.mbox_busy = FALSE; - qla1280_isr(ha, (srb_t **)&done_q_first, (srb_t **)&done_q_last); - - /* Release interrupt specific lock */ - QLA1280_INTR_UNLOCK(ha); - DRIVER_UNLOCK - - if (ha->flags.isp_abort_needed) - qla1280_abort_isp(ha); - - if (ha->flags.reset_marker) - qla1280_rst_aen(ha); - - if (done_q_first) - qla1280_done(ha, (srb_t **)&done_q_first, (srb_t **)&done_q_last); - -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - if (status) - { - qla1280_print("qla1280_mailbox_command: **** FAILED, mailbox0 = "); - qla1280_output_number((uint32_t)mb[0], 16); - qla1280_print(" ****\n\r"); - } -#endif -#ifdef QL_DEBUG_LEVEL_3 - else - LEAVE("qla1280_mailbox_command"); + struct device_reg *reg = ha->iobase; +#if 0 + struct srb *done_q_first = 0; + struct srb *done_q_last = 0; +#endif + int status = 0; + int cnt; + uint16_t *optr, *iptr; + uint16_t data; + DECLARE_COMPLETION(wait); + struct timer_list timer; + + ENTER("qla1280_mailbox_command"); + + ha->flags.mbox_busy = 1; + + if (ha->mailbox_wait) { + printk(KERN_ERR "Warning mailbox wait already in use!\n"); + } + ha->mailbox_wait = &wait; + + /* + * We really should start out by verifying that the mailbox is + * available before starting sending the command data + */ + /* Load mailbox registers. */ + optr = (uint16_t *) ®->mailbox0; + iptr = mb; + for (cnt = 0; cnt < MAILBOX_REGISTER_COUNT; cnt++) { + if (mr & BIT_0) { + WRT_REG_WORD(optr, (*iptr)); + } + + mr >>= 1; + optr++; + iptr++; + } + + /* Issue set host interrupt command. */ + ha->flags.mbox_busy = 0; + + /* set up a timer just in case we're really jammed */ + init_timer(&timer); + timer.expires = jiffies + 20*HZ; + timer.data = (unsigned long)ha; + timer.function = qla1280_mailbox_timeout; + add_timer(&timer); + + spin_unlock_irq(HOST_LOCK); + WRT_REG_WORD(®->host_cmd, HC_SET_HOST_INT); + data = qla1280_debounce_register(®->istatus); + + wait_for_completion(&wait); + del_timer_sync(&timer); + + spin_lock_irq(HOST_LOCK); + + ha->mailbox_wait = NULL; + + /* Check for mailbox command timeout. */ + if (ha->mailbox_out[0] != MBS_CMD_CMP) { + printk(KERN_WARNING "qla1280_mailbox_command: Command failed, " + "mailbox0 = 0x%04x, mailbox_out0 = 0x%04x, istatus = " + "0x%04x\n", + mb[0], ha->mailbox_out[0], RD_REG_WORD(®->istatus)); + printk(KERN_WARNING "m0 %04x, m1 %04x, m2 %04x, m3 %04x\n", + RD_REG_WORD(®->mailbox0), RD_REG_WORD(®->mailbox1), + RD_REG_WORD(®->mailbox2), RD_REG_WORD(®->mailbox3)); + printk(KERN_WARNING "m4 %04x, m5 %04x, m6 %04x, m7 %04x\n", + RD_REG_WORD(®->mailbox4), RD_REG_WORD(®->mailbox5), + RD_REG_WORD(®->mailbox6), RD_REG_WORD(®->mailbox7)); + status = 1; + } + + /* Load return mailbox registers. */ + optr = mb; + iptr = (uint16_t *) &ha->mailbox_out[0]; + mr = MAILBOX_REGISTER_COUNT; + memcpy(optr, iptr, MAILBOX_REGISTER_COUNT * sizeof(uint16_t)); + +#if 0 + /* Go check for any response interrupts pending. */ + qla1280_isr(ha, &done_q_first, &done_q_last); +#endif + + if (ha->flags.reset_marker) + qla1280_rst_aen(ha); + +#if 0 + if (done_q_first) + qla1280_done (ha, &done_q_first, &done_q_last); #endif - return(status); + + if (status) + dprintk(2, "qla1280_mailbox_command: **** FAILED, mailbox0 = " + "0x%x ****\n", mb[0]); + + LEAVE("qla1280_mailbox_command"); + return status; } /* @@ -3555,43 +3294,30 @@ * Input: * ha = adapter block pointer. */ -STATIC void -qla1280_poll(scsi_qla_host_t *ha) +static void +qla1280_poll(struct scsi_qla_host *ha) { - device_reg_t *reg = ha->iobase; - uint16_t data; - srb_t *done_q_first = 0; - srb_t *done_q_last = 0; - -#ifdef QL_DEBUG_LEVEL_3 - /* ENTER("qla1280_poll"); */ -#endif - - /* Acquire interrupt specific lock */ - QLA1280_INTR_LOCK(ha); - - /* Check for pending interrupts. */ - data = RD_REG_WORD(®->istatus); - if (data & RISC_INT) - qla1280_isr(ha, (srb_t **)&done_q_first, (srb_t **)&done_q_last); - - /* Release interrupt specific lock */ - QLA1280_INTR_UNLOCK(ha); - - if (!ha->flags.mbox_busy) - { - if (ha->flags.isp_abort_needed) - qla1280_abort_isp(ha); - if (ha->flags.reset_marker) - qla1280_rst_aen(ha); - } + struct device_reg *reg = ha->iobase; + uint16_t data; + struct srb *done_q_first = 0; + struct srb *done_q_last = 0; + + /* ENTER("qla1280_poll"); */ + + /* Check for pending interrupts. */ + data = RD_REG_WORD(®->istatus); + if (data & RISC_INT) + qla1280_isr(ha, &done_q_first, &done_q_last); + + if (!ha->flags.mbox_busy) { + if (ha->flags.reset_marker) + qla1280_rst_aen(ha); + } - if (done_q_first) - qla1280_done(ha, (srb_t **)&done_q_first, (srb_t **)&done_q_last); + if (done_q_first) + qla1280_done(ha, &done_q_first, &done_q_last); -#ifdef QL_DEBUG_LEVEL_3 - /* LEAVE("qla1280_poll"); */ -#endif + /* LEAVE("qla1280_poll"); */ } /* @@ -3599,54 +3325,58 @@ * Issue SCSI bus reset. * * Input: - * ha = adapter block pointer. - * b = SCSI bus number. + * ha = adapter block pointer. + * bus = SCSI bus number. * * Returns: * 0 = success */ -STATIC uint8_t -qla1280_bus_reset(scsi_qla_host_t *ha, uint8_t b) +static int +qla1280_bus_reset(struct scsi_qla_host *ha, int bus) { - uint8_t status; - uint16_t mb[MAILBOX_REGISTER_COUNT]; + uint16_t mb[MAILBOX_REGISTER_COUNT]; + uint16_t reset_delay; + int status; + + dprintk(3, "qla1280_bus_reset: entered\n"); + + if (qla1280_verbose) + printk(KERN_INFO "scsi(%li:%i): Resetting SCSI BUS\n", + ha->host_no, bus); + + reset_delay = ha->bus_settings[bus].bus_reset_delay; + mb[0] = MBC_BUS_RESET; + mb[1] = reset_delay; + mb[2] = (uint16_t) bus; + status = qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]); + + if (status) { + if (ha->bus_settings[bus].failed_reset_count > 2) + ha->bus_settings[bus].scsi_bus_dead = 1; + ha->bus_settings[bus].failed_reset_count++; + } else { + spin_unlock_irq(HOST_LOCK); + schedule_timeout(reset_delay * HZ); + spin_lock_irq(HOST_LOCK); + + ha->bus_settings[bus].scsi_bus_dead = 0; + ha->bus_settings[bus].failed_reset_count = 0; + ha->bus_settings[bus].reset_marker = 0; + /* Issue marker command. */ + qla1280_marker(ha, bus, 0, 0, MK_SYNC_ALL); + } -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_bus_reset: entered\n\r"); -#endif - if( qla1280_verbose ) - { - printk("scsi(%d): Resetting SCSI BUS (%d)\n",(int)ha->host_no,b); - } - - mb[0] = MBC_BUS_RESET; - mb[1] = ha->bus_settings[b].bus_reset_delay; - mb[2] = (uint16_t)b; - status = qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, &mb[0]); - - if (status) - { - if (ha->bus_settings[b].failed_reset_count > 2) /* dg - 03/13/99 */ - ha->bus_settings[b].scsi_bus_dead = TRUE; - ha->bus_settings[b].failed_reset_count++; - } + /* + * We should probably call qla1280_set_target_parameters() + * here as well for all devices on the bus. + */ + + if (status) + dprintk(2, "qla1280_bus_reset: **** FAILED ****\n"); else - { - QLA1280_DELAY(4); - ha->bus_settings[b].scsi_bus_dead = FALSE; /* dg - 03/13/99 */ - ha->bus_settings[b].failed_reset_count = 0; - /* Issue marker command. */ - qla1280_marker(ha, b, 0, 0, MK_SYNC_ALL); - } -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - if (status) - qla1280_print("qla1280_bus_reset: **** FAILED ****\n\r"); -#endif -#ifdef QL_DEBUG_LEVEL_3 - else - qla1280_print("qla1280_bus_reset: exiting normally\n\r"); -#endif - return(status); + dprintk(3, "qla1280_bus_reset: exiting normally\n"); + + return status; } /* @@ -3654,40 +3384,34 @@ * Issue bus device reset message to the target. * * Input: - * ha = adapter block pointer. - * b = SCSI BUS number. - * t = SCSI ID. + * ha = adapter block pointer. + * bus = SCSI BUS number. + * target = SCSI ID. * * Returns: * 0 = success */ -STATIC uint8_t -qla1280_device_reset(scsi_qla_host_t *ha, uint8_t b, uint32_t t) +static int +qla1280_device_reset(struct scsi_qla_host *ha, int bus, int target) { - uint8_t status; - uint16_t mb[MAILBOX_REGISTER_COUNT]; + uint16_t mb[MAILBOX_REGISTER_COUNT]; + int status; -#ifdef QL_DEBUG_LEVEL_3 - ENTER("qla1280_device_reset"); -#endif + ENTER("qla1280_device_reset"); - mb[0] = MBC_ABORT_TARGET; - mb[1] = (b ? (t | BIT_7) : t) << 8; - mb[2] = 1; - status = qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, &mb[0]); + mb[0] = MBC_ABORT_TARGET; + mb[1] = (bus ? (target | BIT_7) : target) << 8; + mb[2] = 1; + status = qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]); - /* Issue marker command. */ - qla1280_marker(ha, b, t, 0, MK_SYNC_ID); + /* Issue marker command. */ + qla1280_marker(ha, bus, target, 0, MK_SYNC_ID); -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - if (status) - qla1280_print("qla1280_device_reset: **** FAILED ****\n\r"); -#endif -#ifdef QL_DEBUG_LEVEL_3 - else - LEAVE("qla1280_device_reset"); -#endif - return(status); + if (status) + dprintk(2, "qla1280_device_reset: **** FAILED ****\n"); + + LEAVE("qla1280_device_reset"); + return status; } /* @@ -3695,40 +3419,34 @@ * Issue an abort message to the device * * Input: - * ha = adapter block pointer. - * b = SCSI BUS. - * t = SCSI ID. - * l = SCSI LUN. + * ha = adapter block pointer. + * bus = SCSI BUS. + * target = SCSI ID. + * lun = SCSI LUN. * * Returns: * 0 = success */ -STATIC uint8_t -qla1280_abort_device(scsi_qla_host_t *ha, uint8_t b, uint32_t t, uint32_t l) +static int +qla1280_abort_device(struct scsi_qla_host *ha, int bus, int target, int lun) { - uint8_t status; - uint16_t mb[MAILBOX_REGISTER_COUNT]; + uint16_t mb[MAILBOX_REGISTER_COUNT]; + int status; -#ifdef QL_DEBUG_LEVEL_3 - ENTER("qla1280_abort_device"); -#endif + ENTER("qla1280_abort_device"); - mb[0] = MBC_ABORT_DEVICE; - mb[1] = (b ? t | BIT_7 : t) << 8 | l; - status = qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]); + mb[0] = MBC_ABORT_DEVICE; + mb[1] = (bus ? target | BIT_7 : target) << 8 | lun; + status = qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); - /* Issue marker command. */ - qla1280_marker(ha, b, t, l, MK_SYNC_ID_LUN); + /* Issue marker command. */ + qla1280_marker(ha, bus, target, lun, MK_SYNC_ID_LUN); -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - if (status) - qla1280_print("qla1280_abort_device: **** FAILED ****\n\r"); -#endif -#ifdef QL_DEBUG_LEVEL_3 - else - LEAVE("qla1280_abort_device"); -#endif - return(status); + if (status) + dprintk(2, "qla1280_abort_device: **** FAILED ****\n"); + + LEAVE("qla1280_abort_device"); + return status; } /* @@ -3742,41 +3460,35 @@ * Returns: * 0 = success */ -STATIC uint8_t -qla1280_abort_command(scsi_qla_host_t *ha, srb_t *sp) +static int +qla1280_abort_command(struct scsi_qla_host *ha, struct srb * sp, int handle) { - uint8_t status; - uint16_t mb[MAILBOX_REGISTER_COUNT]; - uint32_t b, t, l; - uint32_t handle; + uint16_t mb[MAILBOX_REGISTER_COUNT]; + unsigned int bus, target, lun; + int status; + + ENTER("qla1280_abort_command"); + + bus = SCSI_BUS_32(sp->cmd); + target = SCSI_TCN_32(sp->cmd); + lun = SCSI_LUN_32(sp->cmd); + + sp->flags |= SRB_ABORT_PENDING; + + mb[0] = MBC_ABORT_COMMAND; + mb[1] = (bus ? target | BIT_7 : target) << 8 | lun; + mb[2] = handle >> 16; + mb[3] = handle & 0xffff; + status = qla1280_mailbox_command(ha, 0x0f, &mb[0]); + + if (status) { + dprintk(2, "qla1280_abort_command: **** FAILED ****\n"); + sp->flags &= ~SRB_ABORT_PENDING; + } -#ifdef QL_DEBUG_LEVEL_3 - ENTER("qla1280_abort_command"); -#endif - /* Locate handle number. */ - for (handle = 0; handle < MAX_OUTSTANDING_COMMANDS; handle++) - if (ha->outstanding_cmds[handle] == sp) - break; - - b = SCSI_BUS_32(sp->cmd); - t = SCSI_TCN_32(sp->cmd); - l = SCSI_LUN_32(sp->cmd); - - mb[0] = MBC_ABORT_COMMAND; - mb[1] = (b ? t | BIT_7 : t) << 8 | l; - mb[2] = handle >> 16; - mb[3] = (uint16_t)handle; - status = qla1280_mailbox_command(ha, BIT_3|BIT_2|BIT_1|BIT_0, &mb[0]); - -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - if (status) - qla1280_print("qla1280_abort_command: **** FAILED ****\n\r"); -#endif - sp->flags |= SRB_ABORT_PENDING; - - LEAVE("qla1280_abort_command"); - return(status); + LEAVE("qla1280_abort_command"); + return status; } /* @@ -3786,25 +3498,21 @@ * Input: * ha = adapter block pointer. */ -STATIC void -qla1280_reset_adapter(scsi_qla_host_t *ha) +static void +qla1280_reset_adapter(struct scsi_qla_host *ha) { - device_reg_t *reg = ha->iobase; + struct device_reg *reg = ha->iobase; -#ifdef QL_DEBUG_LEVEL_3 - ENTER("qla1280_reset_adapter"); -#endif + ENTER("qla1280_reset_adapter"); - /* Disable ISP chip */ - ha->flags.online = FALSE; - WRT_REG_WORD(®->ictrl, ISP_RESET); - WRT_REG_WORD(®->host_cmd, HC_RESET_RISC); - WRT_REG_WORD(®->host_cmd, HC_RELEASE_RISC); - WRT_REG_WORD(®->host_cmd, HC_DISABLE_BIOS); + /* Disable ISP chip */ + ha->flags.online = 0; + WRT_REG_WORD(®->ictrl, ISP_RESET); + WRT_REG_WORD(®->host_cmd, + HC_RESET_RISC | HC_RELEASE_RISC | HC_DISABLE_BIOS); + RD_REG_WORD(®->id_l); /* Flush PCI write */ -#ifdef QL_DEBUG_LEVEL_3 - LEAVE("qla1280_reset_adapter"); -#endif + LEAVE("qla1280_reset_adapter"); } /* @@ -3813,38 +3521,34 @@ * * Input: * ha = adapter block pointer. - * b = SCSI BUS number - * t = SCSI ID - * l = SCSI LUN + * bus = SCSI BUS number + * id = SCSI ID + * lun = SCSI LUN * type = marker modifier */ -STATIC void -qla1280_marker(scsi_qla_host_t *ha, uint8_t b, uint32_t t, uint32_t l, uint8_t type) +static void +qla1280_marker(struct scsi_qla_host *ha, int bus, int id, int lun, u8 type) { - mrk_entry_t *pkt; + struct mrk_entry *pkt; -#ifdef QL_DEBUG_LEVEL_3 - ENTER("qla1280_marker"); -#endif + ENTER("qla1280_marker"); - /* Get request packet. */ - if ( (pkt = (mrk_entry_t *)qla1280_req_pkt(ha)) ) - { - pkt->entry_type = MARKER_TYPE; - pkt->lun = (uint8_t)l; - pkt->target = (uint8_t)(b ? (t | BIT_7) : t); - pkt->modifier = type; + /* Get request packet. */ + if ((pkt = (struct mrk_entry *) qla1280_req_pkt(ha))) { + pkt->entry_type = MARKER_TYPE; + pkt->lun = (uint8_t) lun; + pkt->target = (uint8_t) (bus ? (id | BIT_7) : id); + pkt->modifier = type; + pkt->entry_status = 0; - /* Issue command to ISP */ - qla1280_isp_cmd(ha); - } + /* Issue command to ISP */ + qla1280_isp_cmd(ha); + } -#ifdef QL_DEBUG_LEVEL_3 - LEAVE("qla1280_marker"); -#endif + LEAVE("qla1280_marker"); } -#if QLA1280_64BIT_SUPPORT + /* * qla1280_64bit_start_scsi * The start SCSI is responsible for building request packets on @@ -3857,296 +3561,271 @@ * Returns: * 0 = success, was able to issue command. */ -STATIC uint8_t -qla1280_64bit_start_scsi(scsi_qla_host_t *ha, srb_t *sp) +static int +qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) { - device_reg_t *reg = ha->iobase; - uint8_t status = 0; - Scsi_Cmnd *cmd = sp->cmd; - uint32_t cnt; - cmd_a64_entry_t *pkt; - uint16_t req_cnt; - uint16_t seg_cnt; - struct scatterlist *sg = (struct scatterlist *) NULL; - uint32_t *dword_ptr; - -#ifdef QL_DEBUG_LEVEL_3 - ENTER("qla1280_64bit_start_scsi:"); -#endif - - if( qla1280_check_for_dead_scsi_bus(ha, sp) ) - { - return(0); - } - - /* Calculate number of entries and segments required. */ - seg_cnt = 0; - req_cnt = 1; - if (cmd->use_sg) - { - seg_cnt = cmd->use_sg; - sg = (struct scatterlist *) cmd->request_buffer; - - if (seg_cnt > 2) - { - req_cnt += (uint16_t)(seg_cnt - 2) / 5; - if ((uint16_t)(seg_cnt - 2) % 5) - req_cnt++; - } - } - else if (cmd->request_bufflen) /* If data transfer. */ - { - DEBUG(printk("Single data transfer (0x%x)\n",cmd->request_bufflen)); - seg_cnt = 1; - } - - /* Acquire ring specific lock */ - QLA1280_RING_LOCK(ha); - - if ((uint16_t)(req_cnt + 2) >= ha->req_q_cnt) - { - /* Calculate number of free request entries. */ - cnt = RD_REG_WORD(®->mailbox4); - if (ha->req_ring_index < cnt) - ha->req_q_cnt = cnt - ha->req_ring_index; - else - ha->req_q_cnt = REQUEST_ENTRY_CNT - (ha->req_ring_index - cnt); - } - - /* If room for request in request ring. */ - if ((uint16_t)(req_cnt + 2) < ha->req_q_cnt) - { - /* Check for room in outstanding command list. */ - for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS && - ha->outstanding_cmds[cnt] != 0; cnt++) - ; - - if (cnt < MAX_OUTSTANDING_COMMANDS) - { - ha->outstanding_cmds[cnt] = sp; - ha->req_q_cnt -= req_cnt; - CMD_HANDLE(sp->cmd) = (unsigned char *) (u_long) cnt; - - /* - * Build command packet. - */ - pkt = (cmd_a64_entry_t *)ha->request_ring_ptr; - - pkt->entry_type = COMMAND_A64_TYPE; - pkt->entry_count = (uint8_t)req_cnt; - pkt->sys_define = (uint8_t)ha->req_ring_index; - pkt->handle = (uint32_t)cnt; - - /* Zero out remaining portion of packet. */ - dword_ptr = (uint32_t *)pkt + 2; - for (cnt = 2; cnt < REQUEST_ENTRY_SIZE/4; cnt++) - *dword_ptr++ = 0; - - /* Set ISP command timeout. */ - pkt->timeout = (uint16_t)30; - - /* Set device target ID and LUN */ - pkt->lun = SCSI_LUN_32(cmd); - pkt->target = SCSI_BUS_32(cmd) ? - (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd); - - /* Enable simple tag queuing if device supports it. */ - if (cmd->device->tagged_queue ) - pkt->control_flags |= BIT_3; - - /* Load SCSI command packet. */ - pkt->cdb_len = (uint16_t)CMD_CDBLEN(cmd); - BCOPY(&(CMD_CDBP(cmd)), pkt->scsi_cdb, pkt->cdb_len); - DEBUG(printk("Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0])); - - /* - * Load data segments. - */ - if (seg_cnt) /* If data transfer. */ - { - /* Set transfer direction. */ - if ( (cmd->data_cmnd[0] == WRITE_6) ) - pkt->control_flags |= BIT_6; - else - pkt->control_flags |= (BIT_5|BIT_6); - - sp->dir = pkt->control_flags & (BIT_5|BIT_6); - - /* Set total data segment count. */ - pkt->dseg_count = seg_cnt; - - /* Setup packet address segment pointer. */ - dword_ptr = (uint32_t *)&pkt->dseg_0_address; - - if (cmd->use_sg) /* If scatter gather */ - { - /* Load command entry data segments. */ - for (cnt = 0; cnt < 2 && seg_cnt; cnt++, seg_cnt--) - { - DEBUG(sprintf(debug_buff,"SG Segment ap=0x%p, len=0x%x\n\r",sg->address,sg->length)); - DEBUG(qla1280_print(debug_buff)); - *dword_ptr++ = cpu_to_le32(VIRT_TO_BUS_LOW(sg->address)); - *dword_ptr++ = cpu_to_le32(VIRT_TO_BUS_HIGH(sg->address)); - *dword_ptr++ = sg->length; - sg++; - } -#ifdef QL_DEBUG_LEVEL_5 - qla1280_print( - "qla1280_64bit_start_scsi: Scatter/gather command packet data - "); - qla1280_print("b "); - qla1280_output_number((uint32_t)SCSI_BUS_32(cmd), 10); - qla1280_print(" t "); - qla1280_output_number((uint32_t)SCSI_TCN_32(cmd), 10); - qla1280_print(" d "); - qla1280_output_number((uint32_t)SCSI_LUN_32(cmd), 10); - qla1280_print("\n\r"); - qla1280_dump_buffer((caddr_t)pkt, REQUEST_ENTRY_SIZE); -#endif - /* - * Build continuation packets. - */ - while (seg_cnt > 0) - { - /* Adjust ring index. */ - ha->req_ring_index++; - if (ha->req_ring_index == REQUEST_ENTRY_CNT) - { - ha->req_ring_index = 0; - ha->request_ring_ptr = ha->request_ring; - } - else - ha->request_ring_ptr++; - - pkt = (cmd_a64_entry_t *)ha->request_ring_ptr; - - /* Zero out packet. */ - dword_ptr = (uint32_t *)pkt; - for (cnt = 0;cnt < REQUEST_ENTRY_SIZE/4; cnt++) - *dword_ptr++ = 0; - - /* Load packet defaults. */ - ((cont_a64_entry_t *)pkt)->entry_type = - CONTINUE_A64_TYPE; - ((cont_a64_entry_t *)pkt)->entry_count = 1; - ((cont_a64_entry_t *)pkt)->sys_define = (uint8_t) - ha->req_ring_index; - - /* Setup packet address segment pointer. */ - dword_ptr = (uint32_t *) - &((cont_a64_entry_t *)pkt)->dseg_0_address; - - /* Load continuation entry data segments. */ - for (cnt = 0; cnt < 5 && seg_cnt; cnt++, seg_cnt--) - { - *dword_ptr++ = cpu_to_le32(VIRT_TO_BUS_LOW(sg->address)); - *dword_ptr++ = cpu_to_le32(VIRT_TO_BUS_HIGH(sg->address)); - *dword_ptr++ = sg->length; - sg++; - } -#ifdef QL_DEBUG_LEVEL_5 - qla1280_print( - "qla1280_64bit_start_scsi: continuation packet data - c"); - qla1280_print(" b "); - qla1280_output_number((uint32_t)SCSI_BUS_32(cmd), 10); - - qla1280_print(" t "); - qla1280_output_number((uint32_t)SCSI_TCN_32(cmd), 10); - qla1280_print(" d "); - qla1280_output_number((uint32_t)SCSI_LUN_32(cmd), 10); - qla1280_print("\n\r"); - qla1280_dump_buffer((caddr_t)pkt, REQUEST_ENTRY_SIZE); -#endif - } - } - else /* No scatter gather data transfer */ - { - *dword_ptr++ = cpu_to_le32(VIRT_TO_BUS_LOW(cmd->request_buffer)); - *dword_ptr++ = cpu_to_le32(VIRT_TO_BUS_HIGH(cmd->request_buffer)); - *dword_ptr = (uint32_t) cmd->request_bufflen; -#ifdef QL_DEBUG_LEVEL_5 - qla1280_print( - "qla1280_64bit_start_scsi: No scatter/gather command packet data - c"); - qla1280_print(" b "); - qla1280_output_number((uint32_t)SCSI_BUS_32(cmd), 10); - qla1280_print(" t "); - qla1280_output_number((uint32_t)SCSI_TCN_32(cmd), 10); - qla1280_print(" d "); - qla1280_output_number((uint32_t)SCSI_LUN_32(cmd), 10); - qla1280_print("\n\r"); - qla1280_dump_buffer((caddr_t)pkt, REQUEST_ENTRY_SIZE); -#endif - } - } -#ifdef QL_DEBUG_LEVEL_5 - else /* No data transfer */ - { - *dword_ptr++ = (uint32_t) 0; - *dword_ptr++ = (uint32_t) 0; - *dword_ptr = (uint32_t) 0; - qla1280_print( - "qla1280_64bit_start_scsi: No data, command packet data - c"); - qla1280_print(" b "); - qla1280_output_number((uint32_t)SCSI_BUS_32(cmd), 10); - qla1280_print(" t "); - qla1280_output_number((uint32_t)SCSI_TCN_32(cmd), 10); - qla1280_print(" d "); - qla1280_output_number((uint32_t)SCSI_LUN_32(cmd), 10); - qla1280_print("\n\r"); - qla1280_dump_buffer((caddr_t)pkt, REQUEST_ENTRY_SIZE); - } -#endif - /* Adjust ring index. */ - ha->req_ring_index++; - if (ha->req_ring_index == REQUEST_ENTRY_CNT) - { - ha->req_ring_index = 0; - ha->request_ring_ptr = ha->request_ring; - } - else - ha->request_ring_ptr++; - - /* Set chip new ring index. */ - WRT_REG_WORD(®->mailbox4, ha->req_ring_index); - } - else - { - status = 1; -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print( - "qla1280_64bit_start_scsi: NO ROOM IN OUTSTANDING ARRAY\n\r"); - qla1280_print(" req_q_cnt="); - qla1280_output_number((uint32_t)ha->req_q_cnt, 16); -#endif - } - } - else - { - status = 1; -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_64bit_start_scsi: in-ptr="); - qla1280_output_number((uint32_t)ha->req_ring_index, 16); - qla1280_print(" req_q_cnt="); - qla1280_output_number((uint32_t)ha->req_q_cnt, 16); - qla1280_print(" req_cnt="); - qla1280_output_number((uint32_t)req_cnt, 16); - qla1280_print("\n\r"); -#endif - } - - /* Release ring specific lock */ - QLA1280_RING_UNLOCK(ha); - -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - if (status) - qla1280_print("qla1280_64bit_start_scsi: **** FAILED ****\n\r"); -#endif -#ifdef QL_DEBUG_LEVEL_3 - else - qla1280_print("qla1280_64bit_start_scsi: exiting normally\n\r"); -#endif - return(status); + struct device_reg *reg = ha->iobase; + Scsi_Cmnd *cmd = sp->cmd; + cmd_a64_entry_t *pkt; + struct scatterlist *sg = NULL; + u32 *dword_ptr; + dma_addr_t dma_handle; + int status = 0; + int cnt; + int req_cnt; + u16 seg_cnt; + + ENTER("qla1280_64bit_start_scsi:"); + + /* Calculate number of entries and segments required. */ + req_cnt = 1; + if (cmd->use_sg) { + sg = (struct scatterlist *) cmd->request_buffer; + seg_cnt = pci_map_sg(ha->pdev, sg, cmd->use_sg, + scsi_to_pci_dma_dir(cmd->sc_data_direction)); + + if (seg_cnt > 2) { + req_cnt += (seg_cnt - 2) / 5; + if ((seg_cnt - 2) % 5) + req_cnt++; + } + } else if (cmd->request_bufflen) { /* If data transfer. */ + seg_cnt = 1; + } else { + seg_cnt = 0; + } + + if ((req_cnt + 2) >= ha->req_q_cnt) { + /* Calculate number of free request entries. */ + cnt = RD_REG_WORD(®->mailbox4); + if (ha->req_ring_index < cnt) + ha->req_q_cnt = cnt - ha->req_ring_index; + else + ha->req_q_cnt = + REQUEST_ENTRY_CNT - (ha->req_ring_index - cnt); + } + + /* If room for request in request ring. */ + if ((req_cnt + 2) >= ha->req_q_cnt) { + status = 1; + dprintk(2, "qla1280_64bit_start_scsi: in-ptr=0x%x req_q_cnt=" + "0x%xreq_cnt=0x%x", ha->req_ring_index, ha->req_q_cnt, + req_cnt); + goto out; + } + + /* Check for room in outstanding command list. */ + for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS && + ha->outstanding_cmds[cnt] != 0; cnt++); + + if (cnt >= MAX_OUTSTANDING_COMMANDS) { + status = 1; + dprintk(2, "qla1280_64bit_start_scsi: NO ROOM IN " + "OUTSTANDING ARRAY, req_q_cnt=0x%x", ha->req_q_cnt); + goto out; + } + + ha->outstanding_cmds[cnt] = sp; + ha->req_q_cnt -= req_cnt; + CMD_HANDLE(sp->cmd) = (unsigned char *)(unsigned long)(cnt + 1); + + dprintk(2, "64bit_start: cmd=%p sp=%p CDB=%xm, handle %lx\n", cmd, sp, + cmd->cmnd[0], (long)CMD_HANDLE(sp->cmd)); + dprintk(2, " bus %i, target %i, lun %i\n", + SCSI_BUS_32(cmd), SCSI_TCN_32(cmd), SCSI_LUN_32(cmd)); + qla1280_dump_buffer(2, cmd->cmnd, MAX_COMMAND_SIZE); + + /* + * Build command packet. + */ + pkt = (cmd_a64_entry_t *) ha->request_ring_ptr; + + pkt->entry_type = COMMAND_A64_TYPE; + pkt->entry_count = (uint8_t) req_cnt; + pkt->sys_define = (uint8_t) ha->req_ring_index; + pkt->entry_status = 0; + pkt->handle = cpu_to_le32(cnt); + + /* Zero out remaining portion of packet. */ + memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8)); + + /* Set ISP command timeout. */ + pkt->timeout = cpu_to_le16(30); + + /* Set device target ID and LUN */ + pkt->lun = SCSI_LUN_32(cmd); + pkt->target = SCSI_BUS_32(cmd) ? + (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd); + + /* Enable simple tag queuing if device supports it. */ + if (DEV_SIMPLE_TAGS(cmd->device)) + pkt->control_flags |= cpu_to_le16(BIT_3); + + /* Load SCSI command packet. */ + pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd)); + memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd)); + /* dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */ + + /* Set transfer direction. */ + sp->dir = qla1280_data_direction(cmd); + pkt->control_flags |= cpu_to_le16(sp->dir); + + /* Set total data segment count. */ + pkt->dseg_count = cpu_to_le16(seg_cnt); + + /* + * Load data segments. + */ + if (seg_cnt) { /* If data transfer. */ + /* Setup packet address segment pointer. */ + dword_ptr = (u32 *)&pkt->dseg_0_address; + + if (cmd->use_sg) { /* If scatter gather */ + /* Load command entry data segments. */ + for (cnt = 0; cnt < 2 && seg_cnt; cnt++, seg_cnt--) { + dma_handle = sg_dma_address(sg); +#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) + if (ha->flags.use_pci_vchannel) + sn_pci_set_vchan(ha->pdev, &dma_handle, + SCSI_BUS_32(cmd)); +#endif + *dword_ptr++ = + cpu_to_le32(pci_dma_lo32(dma_handle)); + *dword_ptr++ = + cpu_to_le32(pci_dma_hi32(dma_handle)); + *dword_ptr++ = cpu_to_le32(sg_dma_len(sg)); + sg++; + dprintk(3, "S/G Segment phys_addr=%x %x, len=0x%x\n", + cpu_to_le32(pci_dma_hi32(dma_handle)), + cpu_to_le32(pci_dma_lo32(dma_handle)), + cpu_to_le32(sg_dma_len(sg))); + } + dprintk(5, "qla1280_64bit_start_scsi: Scatter/gather " + "command packet data - b %i, t %i, l %i \n", + SCSI_BUS_32(cmd), SCSI_TCN_32(cmd), + SCSI_LUN_32(cmd)); + qla1280_dump_buffer(5, (char *)pkt, + REQUEST_ENTRY_SIZE); + + /* + * Build continuation packets. + */ + dprintk(3, "S/G Building Continuation...seg_cnt=0x%x " + "remains\n", seg_cnt); + + while (seg_cnt > 0) { + /* Adjust ring index. */ + ha->req_ring_index++; + if (ha->req_ring_index == REQUEST_ENTRY_CNT) { + ha->req_ring_index = 0; + ha->request_ring_ptr = + ha->request_ring; + } else + ha->request_ring_ptr++; + + pkt = (cmd_a64_entry_t *)ha->request_ring_ptr; + + /* Zero out packet. */ + memset(pkt, 0, REQUEST_ENTRY_SIZE); + + /* Load packet defaults. */ + ((struct cont_a64_entry *) pkt)->entry_type = + CONTINUE_A64_TYPE; + ((struct cont_a64_entry *) pkt)->entry_count = 1; + ((struct cont_a64_entry *) pkt)->sys_define = + (uint8_t)ha->req_ring_index; + /* Setup packet address segment pointer. */ + dword_ptr = + (u32 *)&((struct cont_a64_entry *) pkt)->dseg_0_address; + + /* Load continuation entry data segments. */ + for (cnt = 0; cnt < 5 && seg_cnt; + cnt++, seg_cnt--) { + dma_handle = sg_dma_address(sg); +#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) + if (ha->flags.use_pci_vchannel) + sn_pci_set_vchan(ha->pdev, &dma_handle, + SCSI_BUS_32(cmd)); +#endif + *dword_ptr++ = + cpu_to_le32(pci_dma_lo32(dma_handle)); + *dword_ptr++ = + cpu_to_le32(pci_dma_hi32(dma_handle)); + *dword_ptr++ = + cpu_to_le32(sg_dma_len(sg)); + dprintk(3, "S/G Segment Cont. phys_addr=%x %x, len=0x%x\n", + cpu_to_le32(pci_dma_hi32(dma_handle)), + cpu_to_le32(pci_dma_lo32(dma_handle)), + cpu_to_le32(sg_dma_len(sg))); + sg++; + } + dprintk(5, "qla1280_64bit_start_scsi: " + "continuation packet data - b %i, t " + "%i, l %i \n", SCSI_BUS_32(cmd), + SCSI_TCN_32(cmd), SCSI_LUN_32(cmd)); + qla1280_dump_buffer(5, (char *)pkt, + REQUEST_ENTRY_SIZE); + } + } else { /* No scatter gather data transfer */ + struct page *page = virt_to_page(cmd->request_buffer); + unsigned long off = (unsigned long)cmd->request_buffer & ~PAGE_MASK; + + dma_handle = pci_map_page(ha->pdev, page, off, + cmd->request_bufflen, + scsi_to_pci_dma_dir(cmd->sc_data_direction)); + + /* save dma_handle for pci_unmap_page */ + sp->saved_dma_handle = dma_handle; +#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) + if (ha->flags.use_pci_vchannel) + sn_pci_set_vchan(ha->pdev, &dma_handle, + SCSI_BUS_32(cmd)); +#endif + *dword_ptr++ = cpu_to_le32(pci_dma_lo32(dma_handle)); + *dword_ptr++ = cpu_to_le32(pci_dma_hi32(dma_handle)); + *dword_ptr = (uint32_t)cmd->request_bufflen; + + dprintk(5, "qla1280_64bit_start_scsi: No scatter/" + "gather command packet data - b %i, t %i, " + "l %i \n", SCSI_BUS_32(cmd), SCSI_TCN_32(cmd), + SCSI_LUN_32(cmd)); + qla1280_dump_buffer(5, (char *)pkt, + REQUEST_ENTRY_SIZE); + } + } else { /* No data transfer */ + dword_ptr = (uint32_t *)(pkt + 1); + *dword_ptr++ = 0; + *dword_ptr++ = 0; + *dword_ptr = 0; + dprintk(5, "qla1280_64bit_start_scsi: No data, command " + "packet data - b %i, t %i, l %i \n", + SCSI_BUS_32(cmd), SCSI_TCN_32(cmd), SCSI_LUN_32(cmd)); + qla1280_dump_buffer(5, (char *)pkt, REQUEST_ENTRY_SIZE); + } + /* Adjust ring index. */ + ha->req_ring_index++; + if (ha->req_ring_index == REQUEST_ENTRY_CNT) { + ha->req_ring_index = 0; + ha->request_ring_ptr = ha->request_ring; + } else + ha->request_ring_ptr++; + + /* Set chip new ring index. */ + dprintk(2, + "qla1280_64bit_start_scsi: Wakeup RISC for pending command\n"); + sp->flags |= SRB_SENT; + ha->actthreads++; + WRT_REG_WORD(®->mailbox4, ha->req_ring_index); + + out: + if (status) + dprintk(2, "qla1280_64bit_start_scsi: **** FAILED ****\n"); + else + dprintk(3, "qla1280_64bit_start_scsi: exiting normally\n"); + + return status; } -#endif /* QLA1280_64BIT_SUPPORT */ + /* * qla1280_32bit_start_scsi @@ -4155,9 +3834,9 @@ * * The Qlogic firmware interface allows every queue slot to have a SCSI * command and up to 4 scatter/gather (SG) entries. If we need more - * than 4 SG entries, then continuation entries are used that can + * than 4 SG entries, then continuation entries are used that can * hold another 7 entries each. The start routine determines if there - * is eought empty slots then build the combination of requests to + * is eought empty slots then build the combination of requests to * fulfill the OS request. * * Input: @@ -4167,302 +3846,253 @@ * Returns: * 0 = success, was able to issue command. */ -STATIC uint8_t -qla1280_32bit_start_scsi(scsi_qla_host_t *ha, srb_t *sp) +static int +qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) { - device_reg_t *reg = ha->iobase; - uint8_t status = 0; - Scsi_Cmnd *cmd = sp->cmd; - uint32_t cnt; - cmd_entry_t *pkt; - uint16_t req_cnt; - uint16_t seg_cnt; - struct scatterlist *sg = (struct scatterlist *) NULL; - uint8_t *data_ptr; - uint32_t *dword_ptr; - - ENTER("qla1280_32bit_start_scsi"); - - - if( qla1280_check_for_dead_scsi_bus(ha, sp) ) - { - return(0); - } - - /* Calculate number of entries and segments required. */ - req_cnt = 1; - if (cmd->use_sg) - { - /* - * We must build an SG list in adapter format, as the kernel's SG list - * cannot be used directly because of data field size (__alpha__) - * differences and the kernel SG list uses virtual addresses where - * we need physical addresses. - */ - seg_cnt = cmd->use_sg; - sg = (struct scatterlist *) cmd->request_buffer; - /* - * if greater than four sg entries then we need to allocate - * continuation entries - */ - if (seg_cnt > 4) - { - req_cnt += (uint16_t)(seg_cnt - 4) / 7; - if ((uint16_t)(seg_cnt - 4) % 7) - req_cnt++; - } - DEBUG(sprintf(debug_buff,"S/G for data transfer -num segs(%d), req blk cnt(%d)\n\r",seg_cnt,req_cnt)); - DEBUG(qla1280_print(debug_buff)); - } - else if (cmd->request_bufflen) /* If data transfer. */ - { - DEBUG(printk("Single data transfer (0x%x)\n",cmd->request_bufflen)); - seg_cnt = 1; - } - else - { - DEBUG(printk("No data transfer \n")); - seg_cnt = 0; - } - - /* Acquire ring specific lock */ - QLA1280_RING_LOCK(ha); - - if ((uint16_t)(req_cnt + 2) >= ha->req_q_cnt) - { - /* Calculate number of free request entries. */ - cnt = RD_REG_WORD(®->mailbox4); - if (ha->req_ring_index < cnt) - ha->req_q_cnt = cnt - ha->req_ring_index; - else - ha->req_q_cnt = REQUEST_ENTRY_CNT - (ha->req_ring_index - cnt); - } - - DEBUG(sprintf(debug_buff,"Number of free entries = (%d)\n\r",ha->req_q_cnt)); - DEBUG(qla1280_print(debug_buff)); - /* If room for request in request ring. */ - if ((uint16_t)(req_cnt + 2) < ha->req_q_cnt) - { - /* Check for empty slot in outstanding command list. */ - for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS && - (ha->outstanding_cmds[cnt] != 0); cnt++) - ; - - if (cnt < MAX_OUTSTANDING_COMMANDS) - { - CMD_HANDLE(sp->cmd) = (unsigned char *)(unsigned long)cnt; - ha->outstanding_cmds[cnt] = sp; - ha->req_q_cnt -= req_cnt; - - /* - * Build command packet. - */ - pkt = (cmd_entry_t *)ha->request_ring_ptr; - - pkt->entry_type = COMMAND_TYPE; - pkt->entry_count = (uint8_t)req_cnt; - pkt->sys_define = (uint8_t)ha->req_ring_index; - pkt->handle = (uint32_t)cnt; - - /* Zero out remaining portion of packet. */ - dword_ptr = (uint32_t *)pkt + 2; - for (cnt = 2; cnt < REQUEST_ENTRY_SIZE/4; cnt++) - *dword_ptr++ = 0; - - /* Set ISP command timeout. */ - pkt->timeout = (uint16_t)30; - - /* Set device target ID and LUN */ - pkt->lun = SCSI_LUN_32(cmd); - pkt->target = SCSI_BUS_32(cmd) ? - (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd); - - /* Enable simple tag queuing if device supports it. */ - if (cmd->device->tagged_queue ) - pkt->control_flags |= BIT_3; - - /* Load SCSI command packet. */ - pkt->cdb_len = (uint16_t)CMD_CDBLEN(cmd); - data_ptr = (uint8_t *) &(CMD_CDBP(cmd)); - for (cnt = 0; cnt < pkt->cdb_len; cnt++) - pkt->scsi_cdb[cnt] = *data_ptr++; - DEBUG(printk("Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0])); - /* - * Load data segments. - */ - if (seg_cnt) - { - DEBUG(printk("loading data segments..\n")); - /* Set transfer direction (READ and WRITE) */ - /* Linux doesn't tell us */ - - /* - * 3/10 dg - Normally, we should need this check with our F/W - * but because of a small issue with it we do. - * - * For block devices, cmd->request.cmd has the operation - * For character devices, this isn't always set properly, so - * we need to check data_cmnd[0]. This catches the conditions - * for st.c, but not sg. Generic commands are pass down to us. - */ - if ( (cmd->data_cmnd[0] == WRITE_6) ) - pkt->control_flags |= BIT_6; - else - pkt->control_flags |= (BIT_5|BIT_6); - - sp->dir = pkt->control_flags & (BIT_5|BIT_6); - - /* Set total data segment count. */ - pkt->dseg_count = seg_cnt; - - /* Setup packet address segment pointer. */ - dword_ptr = (uint32_t *)&pkt->dseg_0_address; - - if (cmd->use_sg) /* If scatter gather */ - { - DEBUG(qla1280_print("Building S/G data segments..\n\r")); - DEBUG(qla1280_dump_buffer((caddr_t)sg, 4*16 )); - /* Load command entry data segments. */ - for (cnt = 0; cnt < 4 && seg_cnt; cnt++, seg_cnt--) - { - *dword_ptr++ = (uint32_t) cpu_to_le32(VIRT_TO_BUS(sg->address)); - *dword_ptr++ = sg->length; - DEBUG(sprintf(debug_buff,"SG Segment ap=0x%p, len=0x%x\n\r",sg->address,sg->length)); - DEBUG(qla1280_print(debug_buff)); - sg++; - } - /* - * Build continuation packets. - */ - while (seg_cnt > 0) - { - /* Adjust ring index. */ - ha->req_ring_index++; - if (ha->req_ring_index == REQUEST_ENTRY_CNT) - { - ha->req_ring_index = 0; - ha->request_ring_ptr = ha->request_ring; - } - else - ha->request_ring_ptr++; - - pkt = (cmd_entry_t *)ha->request_ring_ptr; - - /* Zero out packet. */ - dword_ptr = (uint32_t *)pkt; - for (cnt = 0;cnt < REQUEST_ENTRY_SIZE/4; cnt++) - *dword_ptr++ = 0; - - /* Load packet defaults. */ - ((cont_entry_t *)pkt)->entry_type = - CONTINUE_TYPE; - ((cont_entry_t *)pkt)->entry_count = 1; - - ((cont_entry_t *)pkt)->sys_define = (uint8_t) - ha->req_ring_index; - - /* Setup packet address segment pointer. */ - dword_ptr = (uint32_t *) - &((cont_entry_t *)pkt)->dseg_0_address; - - /* Load continuation entry data segments. */ - for (cnt = 0; cnt < 7 && seg_cnt; cnt++, seg_cnt--) - { - *dword_ptr++ = (u_int) cpu_to_le32(VIRT_TO_BUS(sg->address)); - *dword_ptr++ = sg->length; - sg++; - } -#ifdef QL_DEBUG_LEVEL_5 - qla1280_print( - "qla1280_32bit_start_scsi: continuation packet data - scsi("); - qla1280_output_number((uint32_t)SCSI_BUS_32(cmd), 10); - qla1280_print(":"); - qla1280_output_number((uint32_t)SCSI_TCN_32(cmd), 10); - qla1280_print(":"); - qla1280_output_number((uint32_t)SCSI_LUN_32(cmd), 10); - qla1280_print(")\n\r"); - qla1280_dump_buffer((caddr_t)pkt, REQUEST_ENTRY_SIZE); -#endif - } - } - else /* No scatter gather data transfer */ - { - *dword_ptr++ = (uint32_t) cpu_to_le32(VIRT_TO_BUS(cmd->request_buffer)); - *dword_ptr = (uint32_t) cmd->request_bufflen; - DEBUG(printk("Single Segment ap=0x%p, len=0x%x\n",cmd->request_buffer,cmd->request_bufflen)); - } - } - else /* No data transfer */ - { - *dword_ptr++ = (uint32_t) 0; - *dword_ptr = (uint32_t) 0; -#ifdef QL_DEBUG_LEVEL_5 - qla1280_print( - "qla1280_32bit_start_scsi: No data, command packet data - "); - qla1280_print("\n\r"); - qla1280_dump_buffer((caddr_t)pkt, REQUEST_ENTRY_SIZE); -#endif - } -#ifdef QL_DEBUG_LEVEL_5 - qla1280_print("qla1280_32bit_start_scsi: First IOCB block:\n\r"); - qla1280_dump_buffer((caddr_t)ha->request_ring_ptr, REQUEST_ENTRY_SIZE); -#endif - /* Adjust ring index. */ - ha->req_ring_index++; - if (ha->req_ring_index == REQUEST_ENTRY_CNT) - { - ha->req_ring_index = 0; - ha->request_ring_ptr = ha->request_ring; - } - else - ha->request_ring_ptr++; - - /* Set chip new ring index. */ - DEBUG(qla1280_print("qla1280_32bit_start_scsi: Wakeup RISC for pending command\n\r")); - ha->qthreads--; - sp->u_start = jiffies; - sp->flags |= SRB_SENT; - ha->actthreads++; - /* qla1280_output_number((uint32_t)ha->actthreads++, 16); */ - WRT_REG_WORD(®->mailbox4, ha->req_ring_index); - } - else - { - status = 1; -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print( - "qla1280_32bit_start_scsi: NO ROOM IN OUTSTANDING ARRAY\n\r"); - qla1280_print(" req_q_cnt="); - qla1280_output_number((uint32_t)ha->req_q_cnt, 16); - qla1280_print("\n\r"); -#endif - } - } - else - { - status = 1; -#ifdef QL_DEBUG_LEVEL_2 - /* qla1280_print("qla1280_32bit_start_scsi: in-ptr="); - qla1280_output_number((uint32_t)ha->req_ring_index, 16); - qla1280_print(" req_q_cnt="); - qla1280_output_number((uint32_t)ha->req_q_cnt, 16); - qla1280_print(" req_cnt="); - qla1280_output_number((uint32_t)req_cnt, 16); - qla1280_print("\n\r"); */ -#endif - } - - /* Release ring specific lock */ - QLA1280_RING_UNLOCK(ha); - -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - /* if (status) - qla1280_print("qla1280_32bit_start_scsi: **** FAILED ****\n\r"); */ -#endif -#ifdef QL_DEBUG_LEVEL_3 - LEAVE("qla1280_32bit_start_scsi"); -#endif - return(status); + struct device_reg *reg = ha->iobase; + Scsi_Cmnd *cmd = sp->cmd; + struct cmd_entry *pkt; + struct scatterlist *sg = NULL; + uint32_t *dword_ptr; + int status = 0; + int cnt; + int req_cnt; + uint16_t seg_cnt; + dma_addr_t dma_handle; + + ENTER("qla1280_32bit_start_scsi"); + + dprintk(1, "32bit_start: cmd=%p sp=%p CDB=%x\n", cmd, sp, + cmd->cmnd[0]); + + /* Calculate number of entries and segments required. */ + req_cnt = 1; + if (cmd->use_sg) { + /* + * We must build an SG list in adapter format, as the kernel's + * SG list cannot be used directly because of data field size + * (__alpha__) differences and the kernel SG list uses virtual + * addresses where we need physical addresses. + */ + sg = (struct scatterlist *) cmd->request_buffer; + seg_cnt = pci_map_sg(ha->pdev, sg, cmd->use_sg, + scsi_to_pci_dma_dir(cmd->sc_data_direction)); + + /* + * if greater than four sg entries then we need to allocate + * continuation entries + */ + if (seg_cnt > 4) { + req_cnt += (seg_cnt - 4) / 7; + if ((seg_cnt - 4) % 7) + req_cnt++; + } + dprintk(3, "S/G Transfer cmd=%p seg_cnt=0x%x, req_cnt=%x\n", + cmd, seg_cnt, req_cnt); + } else if (cmd->request_bufflen) { /* If data transfer. */ + dprintk(3, "No S/G transfer t=%x cmd=%p len=%x CDB=%x\n", + SCSI_TCN_32(cmd), cmd, cmd->request_bufflen, + cmd->cmnd[0]); + seg_cnt = 1; + } else { + /* dprintk(1, "No data transfer \n"); */ + seg_cnt = 0; + } + + if ((req_cnt + 2) >= ha->req_q_cnt) { + /* Calculate number of free request entries. */ + cnt = RD_REG_WORD(®->mailbox4); + if (ha->req_ring_index < cnt) + ha->req_q_cnt = cnt - ha->req_ring_index; + else + ha->req_q_cnt = + REQUEST_ENTRY_CNT - (ha->req_ring_index - cnt); + } + + dprintk(3, "Number of free entries=(%d) seg_cnt=0x%x\n", + ha->req_q_cnt, seg_cnt); + /* If room for request in request ring. */ + if ((req_cnt + 2) >= ha->req_q_cnt) { + status = 1; + dprintk(2, "qla1280_32bit_start_scsi: in-ptr=0x%x, " + "req_q_cnt=0x%x, req_cnt=0x%x", ha->req_ring_index, + ha->req_q_cnt, req_cnt); + goto out; + } + + /* Check for empty slot in outstanding command list. */ + for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS && + (ha->outstanding_cmds[cnt] != 0); cnt++) ; + + if (cnt >= MAX_OUTSTANDING_COMMANDS) { + status = 1; + dprintk(2, "qla1280_32bit_start_scsi: NO ROOM IN OUTSTANDING " + "ARRAY, req_q_cnt=0x%x\n", ha->req_q_cnt); + goto out; + } + + CMD_HANDLE(sp->cmd) = (unsigned char *) (unsigned long)(cnt + 1); + ha->outstanding_cmds[cnt] = sp; + ha->req_q_cnt -= req_cnt; + + /* + * Build command packet. + */ + pkt = (struct cmd_entry *) ha->request_ring_ptr; + + pkt->entry_type = COMMAND_TYPE; + pkt->entry_count = (uint8_t) req_cnt; + pkt->sys_define = (uint8_t) ha->req_ring_index; + pkt->entry_status = 0; + pkt->handle = cpu_to_le32(cnt); + + /* Zero out remaining portion of packet. */ + memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8)); + + /* Set ISP command timeout. */ + pkt->timeout = cpu_to_le16(30); + + /* Set device target ID and LUN */ + pkt->lun = SCSI_LUN_32(cmd); + pkt->target = SCSI_BUS_32(cmd) ? + (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd); + + /* Enable simple tag queuing if device supports it. */ + if (DEV_SIMPLE_TAGS(cmd->device)) + pkt->control_flags |= cpu_to_le16(BIT_3); + + /* Load SCSI command packet. */ + pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd)); + memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd)); + + /*dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */ + /* Set transfer direction. */ + sp->dir = qla1280_data_direction(cmd); + pkt->control_flags |= cpu_to_le16(sp->dir); + + /* Set total data segment count. */ + pkt->dseg_count = cpu_to_le16(seg_cnt); + + /* + * Load data segments. + */ + if (seg_cnt) { + /* Setup packet address segment pointer. */ + dword_ptr = &pkt->dseg_0_address; + + if (cmd->use_sg) { /* If scatter gather */ + dprintk(3, "Building S/G data segments..\n"); + qla1280_dump_buffer(1, (char *)sg, 4 * 16); + + /* Load command entry data segments. */ + for (cnt = 0; cnt < 4 && seg_cnt; cnt++, seg_cnt--) { + *dword_ptr++ = + cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))); + *dword_ptr++ = + cpu_to_le32(sg_dma_len(sg)); + dprintk(3, "S/G Segment phys_addr=0x%lx, len=0x%x\n", + (pci_dma_lo32(sg_dma_address(sg))), + (sg_dma_len(sg))); + sg++; + } + /* + * Build continuation packets. + */ + dprintk(3, "S/G Building Continuation" + "...seg_cnt=0x%x remains\n", seg_cnt); + while (seg_cnt > 0) { + /* Adjust ring index. */ + ha->req_ring_index++; + if (ha->req_ring_index == REQUEST_ENTRY_CNT) { + ha->req_ring_index = 0; + ha->request_ring_ptr = + ha->request_ring; + } else + ha->request_ring_ptr++; + + pkt = (struct cmd_entry *)ha->request_ring_ptr; + + /* Zero out packet. */ + memset(pkt, 0, REQUEST_ENTRY_SIZE); + + /* Load packet defaults. */ + ((struct cont_entry *) pkt)-> + entry_type = CONTINUE_TYPE; + ((struct cont_entry *) pkt)->entry_count = 1; + + ((struct cont_entry *) pkt)->sys_define = + (uint8_t) ha->req_ring_index; + + /* Setup packet address segment pointer. */ + dword_ptr = + &((struct cont_entry *) pkt)->dseg_0_address; + + /* Load continuation entry data segments. */ + for (cnt = 0; cnt < 7 && seg_cnt; + cnt++, seg_cnt--) { + *dword_ptr++ = + cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))); + *dword_ptr++ = + cpu_to_le32(sg_dma_len(sg)); + dprintk(1, + "S/G Segment Cont. phys_addr=0x%x, " + "len=0x%x\n", + cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))), + cpu_to_le32(sg_dma_len(sg))); + sg++; + } + dprintk(5, "qla1280_32bit_start_scsi: " + "continuation packet data - " + "scsi(%i:%i:%i)\n", SCSI_BUS_32(cmd), + SCSI_TCN_32(cmd), SCSI_LUN_32(cmd)); + qla1280_dump_buffer(5, (char *)pkt, + REQUEST_ENTRY_SIZE); + } + } else { /* No S/G data transfer */ + struct page *page = virt_to_page(cmd->request_buffer); + unsigned long off = (unsigned long)cmd->request_buffer & ~PAGE_MASK; + dma_handle = pci_map_page(ha->pdev, page, off, + cmd->request_bufflen, + scsi_to_pci_dma_dir(cmd->sc_data_direction)); + sp->saved_dma_handle = dma_handle; + + *dword_ptr++ = cpu_to_le32(pci_dma_lo32(dma_handle)); + *dword_ptr = cpu_to_le32(cmd->request_bufflen); + } + } else { /* No data transfer at all */ + dword_ptr = (uint32_t *)(pkt + 1); + *dword_ptr++ = 0; + *dword_ptr = 0; + dprintk(5, "qla1280_32bit_start_scsi: No data, command " + "packet data - \n"); + qla1280_dump_buffer(5, (char *)pkt, REQUEST_ENTRY_SIZE); + } + dprintk(5, "qla1280_32bit_start_scsi: First IOCB block:\n"); + qla1280_dump_buffer(5, (char *)ha->request_ring_ptr, + REQUEST_ENTRY_SIZE); + + /* Adjust ring index. */ + ha->req_ring_index++; + if (ha->req_ring_index == REQUEST_ENTRY_CNT) { + ha->req_ring_index = 0; + ha->request_ring_ptr = ha->request_ring; + } else + ha->request_ring_ptr++; + + /* Set chip new ring index. */ + dprintk(2, "qla1280_32bit_start_scsi: Wakeup RISC " + "for pending command\n"); + sp->flags |= SRB_SENT; + ha->actthreads++; + WRT_REG_WORD(®->mailbox4, ha->req_ring_index); + +out: + if (status) + dprintk(2, "qla1280_32bit_start_scsi: **** FAILED ****\n"); + + LEAVE("qla1280_32bit_start_scsi"); + + return status; } /* @@ -4476,405 +4106,140 @@ * Returns: * 0 = failed to get slot. */ -STATIC request_t * -qla1280_req_pkt(scsi_qla_host_t *ha) +static request_t * +qla1280_req_pkt(struct scsi_qla_host *ha) { - device_reg_t *reg = ha->iobase; - request_t *pkt = 0; - uint16_t cnt; - uint32_t *dword_ptr; - uint32_t timer; - -#ifdef QL_DEBUG_LEVEL_3 - ENTER("qla1280_req_pkt"); -#endif - - /* Wait for 30 seconds for slot. */ - for (timer = 15000000; timer; timer--) - { - /* Acquire ring specific lock */ - QLA1280_RING_LOCK(ha); - - if (ha->req_q_cnt > 0) - { - /* Calculate number of free request entries. */ - cnt = RD_REG_WORD(®->mailbox4); - if (ha->req_ring_index < cnt) - ha->req_q_cnt = cnt - ha->req_ring_index; - else - ha->req_q_cnt = REQUEST_ENTRY_CNT - (ha->req_ring_index - cnt); - } - - /* Found empty request ring slot? */ - if (ha->req_q_cnt > 0) - { - ha->req_q_cnt--; - pkt = ha->request_ring_ptr; - - /* Zero out packet. */ - dword_ptr = (uint32_t *)pkt; - for (cnt = 0; cnt < REQUEST_ENTRY_SIZE/4; cnt++) - *dword_ptr++ = 0; - - /* Set system defined field. */ - pkt->sys_define = (uint8_t)ha->req_ring_index; - - /* Set entry count. */ - pkt->entry_count = 1; - - break; - } - - /* Release ring specific lock */ - QLA1280_RING_UNLOCK(ha); - - SYS_DELAY(2); /* 10 */ - - /* Check for pending interrupts. */ - qla1280_poll(ha); - } - -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - if (!pkt) - qla1280_print("qla1280_req_pkt: **** FAILED ****\n\r"); -#endif -#ifdef QL_DEBUG_LEVEL_3 - else - qla1280_print("qla1280_req_pkt: exiting normally\n\r"); -#endif - return(pkt); -} - -/* - * qla1280_isp_cmd - * Function is responsible for modifying ISP input pointer. - * Releases ring lock. - * - * Input: - * ha = adapter block pointer. - */ -STATIC void -qla1280_isp_cmd(scsi_qla_host_t *ha) -{ - device_reg_t *reg = ha->iobase; - -#ifdef QL_DEBUG_LEVEL_3 - ENTER("qla1280_isp_cmd"); -#endif - -#ifdef QL_DEBUG_LEVEL_5 - qla1280_print("qla1280_isp_cmd: IOCB data:\n\r"); - qla1280_dump_buffer((caddr_t)ha->request_ring_ptr, REQUEST_ENTRY_SIZE); -#endif - - /* Adjust ring index. */ - ha->req_ring_index++; - if (ha->req_ring_index == REQUEST_ENTRY_CNT) - { - ha->req_ring_index = 0; - ha->request_ring_ptr = ha->request_ring; - } - else - ha->request_ring_ptr++; - - /* Set chip new ring index. */ - WRT_REG_WORD(®->mailbox4, ha->req_ring_index); + struct device_reg *reg = ha->iobase; + request_t *pkt = 0; + int cnt; + uint32_t timer; + + ENTER("qla1280_req_pkt"); + + /* + * This can be called from interrupt context, damn it!!! + */ + /* Wait for 30 seconds for slot. */ + for (timer = 15000000; timer; timer--) { + if (ha->req_q_cnt > 0) { + /* Calculate number of free request entries. */ + cnt = RD_REG_WORD(®->mailbox4); + if (ha->req_ring_index < cnt) + ha->req_q_cnt = cnt - ha->req_ring_index; + else + ha->req_q_cnt = + REQUEST_ENTRY_CNT - (ha->req_ring_index - cnt); + } - /* Release ring specific lock */ - QLA1280_RING_UNLOCK(ha); + /* Found empty request ring slot? */ + if (ha->req_q_cnt > 0) { + ha->req_q_cnt--; + pkt = ha->request_ring_ptr; + + /* Zero out packet. */ + memset(pkt, 0, REQUEST_ENTRY_SIZE); + + /* + * How can this be right when we have a ring + * size of 512??? + */ + /* Set system defined field. */ + pkt->sys_define = (uint8_t) ha->req_ring_index; -#ifdef QL_DEBUG_LEVEL_3 - LEAVE("qla1280_isp_cmd"); -#endif -} + /* Set entry count. */ + pkt->entry_count = 1; -/* - * qla1280_enable_lun - * Issue enable LUN entry IOCB. - * - * Input: - * ha = adapter block pointer. - * b = SCSI BUS number. - * l = LUN number. - */ -STATIC void -qla1280_enable_lun(scsi_qla_host_t *ha, uint8_t b, uint32_t l) -{ - elun_entry_t *pkt; + break; + } -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_enable_lun: entered\n\r"); -#endif + udelay(2); /* 10 */ - /* Get request packet. */ - /* - if (pkt = (elun_entry_t *)qla1280_req_pkt(ha)) - { - pkt->entry_type = ENABLE_LUN_TYPE; - pkt->lun = (uint16_t)(b ? l | BIT_15 : l); - pkt->command_count = 32; - pkt->immed_notify_count = 1; - pkt->group_6_length = MAX_CMDSZ; - pkt->group_7_length = MAX_CMDSZ; - pkt->timeout = 0x30; + /* Check for pending interrupts. */ + qla1280_poll(ha); + } - qla1280_isp_cmd(ha); - } - */ - pkt = (elun_entry_t *)1; + if (!pkt) + dprintk(2, "qla1280_req_pkt: **** FAILED ****\n"); + else + dprintk(3, "qla1280_req_pkt: exiting normally\n"); -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - if (!pkt) - qla1280_print("qla1280_enable_lun: **** FAILED ****\n\r"); -#endif -#ifdef QL_DEBUG_LEVEL_3 - else - qla1280_print("qla1280_enable_lun: exiting normally\n\r"); -#endif + return pkt; } -#if QL1280_TARGET_MODE_SUPPORT -/****************************************************************************/ -/* Target Mode Support Functions. */ -/****************************************************************************/ - /* - * qla1280_notify_ack - * Issue notify acknowledge IOCB. - * If sequence ID is zero, acknowledgement of - * SCSI bus reset or bus device reset is assumed. + * qla1280_isp_cmd + * Function is responsible for modifying ISP input pointer. + * Releases ring lock. * * Input: - * ha = adapter block pointer. - * inotify = immediate notify entry pointer. + * ha = adapter block pointer. */ -STATIC void -qla1280_notify_ack(scsi_qla_host_t *ha, notify_entry_t *inotify) +static void +qla1280_isp_cmd(struct scsi_qla_host *ha) { - nack_entry_t *pkt; - -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_notify_ack: entered\n\r"); -#endif - - /* Get request packet. */ - if (pkt = (nack_entry_t *)qla1280_req_pkt(ha)) - { - pkt->entry_type = NOTIFY_ACK_TYPE; - pkt->lun = inotify->lun; - pkt->initiator_id = inotify->initiator_id; - pkt->target_id = inotify->target_id; - if (inotify->seq_id == 0) - pkt->event = BIT_7; - else - pkt->seq_id = inotify->seq_id; - - /* Issue command to ISP */ - qla1280_isp_cmd(ha); - } + struct device_reg *reg = ha->iobase; -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - if (!pkt) - qla1280_print("qla1280_notify_ack: **** FAILED ****\n\r"); -#endif -#ifdef QL_DEBUG_LEVEL_3 - else - qla1280_print("qla1280_notify_ack: exiting normally\n\r"); -#endif -} - -/* - * qla1280_immed_notify - * Issue immediate notify IOCB for LUN 0. - * - * Input: - * ha = adapter block pointer. - * inotify = immediate notify entry pointer. - */ -STATIC void -qla1280_immed_notify(scsi_qla_host_t *ha, notify_entry_t *inotify) -{ - notify_entry_t *pkt; + ENTER("qla1280_isp_cmd"); -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_immed_notify: entered\n\r"); -#endif + dprintk(5, "qla1280_isp_cmd: IOCB data:\n"); + qla1280_dump_buffer(5, (char *)ha->request_ring_ptr, + REQUEST_ENTRY_SIZE); - /* Get request packet. */ - if (pkt = (notify_entry_t *)qla1280_req_pkt(ha)) - { - pkt->entry_type = IMMED_NOTIFY_TYPE; - pkt->lun = inotify->lun; - pkt->initiator_id = inotify->initiator_id; - pkt->target_id = inotify->target_id; - pkt->status = 1; + /* Adjust ring index. */ + ha->req_ring_index++; + if (ha->req_ring_index == REQUEST_ENTRY_CNT) { + ha->req_ring_index = 0; + ha->request_ring_ptr = ha->request_ring; + } else + ha->request_ring_ptr++; - /* Issue command to ISP */ - qla1280_isp_cmd(ha); - } + /* Set chip new ring index. */ + WRT_REG_WORD(®->mailbox4, ha->req_ring_index); -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - if (!pkt) - qla1280_print("qla1280_immed_notify: **** FAILED ****\n\r"); -#endif -#ifdef QL_DEBUG_LEVEL_3 - else - qla1280_print("qla1280_immed_notify: exiting normally\n\r"); -#endif + LEAVE("qla1280_isp_cmd"); } +#if QL1280_LUN_SUPPORT /* - * qla1280_accept_io - * Issue accept target I/O IOCB for LUN 0. + * qla1280_enable_lun + * Issue enable LUN entry IOCB. * * Input: - * ha = adapter block pointer. - * ctio = ctio returned entry pointer. + * ha = adapter block pointer. + * bus = SCSI BUS number. + * lun = LUN number. */ -STATIC void -qla1280_accept_io(scsi_qla_host_t *ha, ctio_ret_entry_t *ctio) +static void +qla1280_enable_lun(struct scsi_qla_host *ha, int bus, int lun) { - atio_entry_t *pkt; - -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_accept_io: entered\n\r"); -#endif + struct elun_entry *pkt; - /* Get request packet. */ - if (pkt = (atio_entry_t *)qla1280_req_pkt(ha)) - { - pkt->entry_type = ACCEPT_TGT_IO_TYPE; - pkt->lun = ctio->lun; - pkt->initiator_id = ctio->initiator_id; - pkt->target_id = ctio->target_id; - pkt->tag_value = ctio->tag_value; - pkt->status = 1; + ENTER("qla1280_enable_lun"); + + /* Get request packet. */ + /* + if (pkt = (struct elun_entry *)qla1280_req_pkt(ha)) + { + pkt->entry_type = ENABLE_LUN_TYPE; + pkt->lun = cpu_to_le16(bus ? lun | BIT_15 : lun); + pkt->command_count = 32; + pkt->immed_notify_count = 1; + pkt->group_6_length = MAX_CMDSZ; + pkt->group_7_length = MAX_CMDSZ; + pkt->timeout = cpu_to_le16(0x30); + + qla1280_isp_cmd(ha); + } + */ + pkt = (struct elun_entry *) 1; - /* Issue command to ISP */ - qla1280_isp_cmd(ha); - } - -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - if (!pkt) - qla1280_print("qla1280_accept_io: **** FAILED ****\n\r"); -#endif -#ifdef QL_DEBUG_LEVEL_3 - else - qla1280_print("qla1280_accept_io: exiting normally\n\r"); -#endif + if (!pkt) + dprintk(2, "qla1280_enable_lun: **** FAILED ****\n"); + else + dprintk(3, "qla1280_enable_lun: exiting normally\n"); } - -/* - * qla1280_64bit_continue_io - * Issue continue target I/O IOCB. - * - * Input: - * ha = adapter block pointer. - * atio = atio pointer. - * len = total bytecount. - * addr = physical address pointer. - */ -STATIC void -qla1280_64bit_continue_io(scsi_qla_host_t *ha, atio_entry_t *atio, uint32_t len, - paddr32_t *addr) -{ - ctio_a64_entry_t *pkt; - uint32_t *dword_ptr; - -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_64bit_continue_io: entered\n\r"); -#endif - - /* Get request packet. */ - if (pkt = (ctio_a64_entry_t *)qla1280_req_pkt(ha)) - { - pkt->entry_type = CTIO_A64_TYPE; - pkt->lun = atio->lun; - pkt->initiator_id = atio->initiator_id; - pkt->target_id = atio->target_id; - pkt->option_flags = atio->option_flags; - pkt->tag_value = atio->tag_value; - pkt->scsi_status = atio->scsi_status; - - if (len) - { - pkt->dseg_count = 1; - pkt->transfer_length = len; - pkt->dseg_0_length = len; - dword_ptr = (uint32_t *)addr; - pkt->dseg_0_address[0] = *dword_ptr++; - pkt->dseg_0_address[1] = *dword_ptr; - } - - /* Issue command to ISP */ - qla1280_isp_cmd(ha); - } - -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - if (!pkt) - qla1280_print("qla1280_64bit_continue_io: **** FAILED ****\n\r"); -#endif -#ifdef QL_DEBUG_LEVEL_3 - else - qla1280_print("qla1280_64bit_continue_io: exiting normally\n\r"); #endif -} -/* - * qla1280_32bit_continue_io - * Issue continue target I/O IOCB. - * - * Input: - * ha = adapter block pointer. - * atio = atio pointer. - * len = total bytecount. - * addr = physical address pointer. - */ -STATIC void -qla1280_32bit_continue_io(scsi_qla_host_t *ha, atio_entry_t *atio, uint32_t len, - paddr32_t *addr) -{ - ctio_entry_t *pkt; - uint32_t *dword_ptr; - -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_32bit_continue_io: entered\n\r"); -#endif - - /* Get request packet. */ - if (pkt = (ctio_entry_t *)qla1280_req_pkt(ha)) - { - pkt->entry_type = CONTINUE_TGT_IO_TYPE; - pkt->lun = atio->lun; - pkt->initiator_id = atio->initiator_id; - pkt->target_id = atio->target_id; - pkt->option_flags = atio->option_flags; - pkt->tag_value = atio->tag_value; - pkt->scsi_status = atio->scsi_status; - - if (len) - { - pkt->dseg_count = 1; - pkt->transfer_length = len; - pkt->dseg_0_length = len; - dword_ptr = (uint32_t *)addr; - pkt->dseg_0_address = *dword_ptr; - } - - /* Issue command to ISP */ - qla1280_isp_cmd(ha); - } - -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - if (!pkt) - qla1280_print("qla1280_32bit_continue_io: **** FAILED ****\n\r"); -#endif -#ifdef QL_DEBUG_LEVEL_3 - else - qla1280_print("qla1280_32bit_continue_io: exiting normally\n\r"); -#endif -} -#endif /* QL1280_TARGET_MODE_SUPPORT */ /****************************************************************************/ /* Interrupt Service Routine. */ @@ -4888,832 +4253,313 @@ * ha = adapter block pointer. * done_q_first = done queue first pointer. * done_q_last = done queue last pointer. - * INTR_LOCK must be already obtained. ****************************************************************************/ -STATIC void -qla1280_isr(scsi_qla_host_t *ha, srb_t **done_q_first, srb_t **done_q_last) -{ - device_reg_t *reg = ha->iobase; - response_t *pkt; - srb_t *sp; - uint16_t mailbox[MAILBOX_REGISTER_COUNT]; - uint16_t *wptr; - uint32_t index; - - ENTER("qla1280_isr"); - - - /* Save mailbox register 5 */ - mailbox[5] = RD_REG_WORD(®->mailbox5); - - /* Check for mailbox interrupt. */ - - mailbox[0] = RD_REG_WORD(®->semaphore); - if (mailbox[0] & BIT_0) - { - /* Get mailbox data. */ - - wptr = &mailbox[0]; - *wptr++ = RD_REG_WORD(®->mailbox0); - *wptr++ = RD_REG_WORD(®->mailbox1); - *wptr = RD_REG_WORD(®->mailbox2); - if (mailbox[0] != MBA_SCSI_COMPLETION) - { - wptr++; - *wptr++ = RD_REG_WORD(®->mailbox3); - *wptr++ = RD_REG_WORD(®->mailbox4); - wptr++; - *wptr++ = RD_REG_WORD(®->mailbox6); - *wptr = RD_REG_WORD(®->mailbox7); - } - - /* Release mailbox registers. */ - - WRT_REG_WORD(®->semaphore, 0); - WRT_REG_WORD(®->host_cmd, HC_CLR_RISC_INT); - -#ifdef QL_DEBUG_LEVEL_5 - qla1280_print("qla1280_isr: mailbox interrupt mailbox[0] = "); - qla1280_output_number((uint32_t)mailbox[0], 16); - qla1280_print("\n\r"); -#endif - - /* Handle asynchronous event */ - - switch (mailbox[0]) - { - case MBA_SCSI_COMPLETION: /* Response completion */ -#ifdef QL_DEBUG_LEVEL_5 - qla1280_print("qla1280_isr: mailbox response completion\n\r"); -#endif - if (ha->flags.online) - { - /* Get outstanding command index. */ - index = (uint32_t)(mailbox[2] << 16 | mailbox[1]); - - /* Validate handle. */ - if (index < MAX_OUTSTANDING_COMMANDS) - sp = ha->outstanding_cmds[index]; - else - sp = 0; - - if (sp) - { - /* Free outstanding command slot. */ - ha->outstanding_cmds[index] = 0; - - /* Save ISP completion status */ - CMD_RESULT(sp->cmd) = 0; - - /* Place block on done queue */ - sp->s_next = NULL; - sp->s_prev = *done_q_last; - if (!*done_q_first) - *done_q_first = sp; - else - (*done_q_last)->s_next = sp; - *done_q_last = sp; - } - else - { -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_isr: ISP invalid handle\n\r"); -#endif - printk(KERN_WARNING "qla1280: ISP invalid handle"); - ha->flags.isp_abort_needed = TRUE; - } - } - break; - case MBA_BUS_RESET: /* SCSI Bus Reset */ -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_isr: asynchronous BUS_RESET\n\r"); -#endif - ha->flags.reset_marker = TRUE; - index = mailbox[6] & BIT_0; - ha->bus_settings[index].reset_marker = TRUE; - break; - case MBA_SYSTEM_ERR: /* System Error */ -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_isr: ISP System Error - mbx1="); - qla1280_output_number((uint32_t)mailbox[1], 16); - qla1280_print(", mbx2="); - qla1280_output_number((uint32_t)mailbox[2], 16); - qla1280_print(", mbx3="); - qla1280_output_number((uint32_t)mailbox[3], 16); - qla1280_print("\n\r"); -#endif - printk(KERN_WARNING - "qla1280: ISP System Error - mbx1=%xh, mbx2=%xh, mbx3=%xh\n", - mailbox[1], mailbox[2], mailbox[3]); - ha->flags.isp_abort_needed = TRUE; - break; - case MBA_REQ_TRANSFER_ERR: /* Request Transfer Error */ -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_isr: ISP Request Transfer Error\n\r"); -#endif - printk(KERN_WARNING "qla1280: ISP Request Transfer Error\n"); - ha->flags.isp_abort_needed = TRUE; - break; - case MBA_RSP_TRANSFER_ERR: /* Response Transfer Error */ -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_isr: ISP Response Transfer Error\n\r"); -#endif - printk(KERN_WARNING "qla1280: ISP Response Transfer Error\n"); - ha->flags.isp_abort_needed = TRUE; - break; - case MBA_WAKEUP_THRES: /* Request Queue Wake-up */ -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_isr: asynchronous WAKEUP_THRES\n\r"); -#endif - break; - case MBA_TIMEOUT_RESET: /* Execution Timeout Reset */ -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_isr: asynchronous TIMEOUT_RESET\n\r"); -#endif - break; - case MBA_DEVICE_RESET: /* Bus Device Reset */ -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print( - "qla1280_isr: asynchronous BUS_DEVICE_RESET\n\r"); -#endif - ha->flags.reset_marker = TRUE; - index = mailbox[6] & BIT_0; - ha->bus_settings[index].reset_marker = TRUE; - break; - case MBA_BUS_MODE_CHANGE: -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print( - "qla1280_isr: asynchronous BUS_MODE_CHANGE\n\r"); -#endif - break; - default: - if (mailbox[0] < MBA_ASYNC_EVENT) - { - wptr = &mailbox[0]; - ha->mailbox_out[0] = *wptr++; - ha->mailbox_out[1] = *wptr++; - ha->mailbox_out[2] = *wptr++; - ha->mailbox_out[3] = *wptr++; - ha->mailbox_out[4] = *wptr++; - ha->mailbox_out[5] = *wptr++; - ha->mailbox_out[6] = *wptr++; - ha->mailbox_out[7] = *wptr; - ha->flags.mbox_int = TRUE; - } - break; - } - } - else - WRT_REG_WORD(®->host_cmd, HC_CLR_RISC_INT); - - /* - * Response ring - */ - if (ha->flags.online && !ha->flags.mbox_busy) - { - if (mailbox[5] < RESPONSE_ENTRY_CNT) - { - while (ha->rsp_ring_index != mailbox[5]) - { - pkt = ha->response_ring_ptr; - -#ifdef QL_DEBUG_LEVEL_5 - qla1280_print("qla1280_isr: ha->rsp_ring_index = "); - qla1280_output_number((uint32_t)ha->rsp_ring_index, 16); - qla1280_print(" mailbox[5] = "); - qla1280_output_number((uint32_t)mailbox[5], 16); - qla1280_print("\n\rqla1280_isr: response packet data\n\r"); - qla1280_dump_buffer((caddr_t)pkt, RESPONSE_ENTRY_SIZE); -#endif - -#if defined(QL_DEBUG_LEVEL_2) && !defined(QL_DEBUG_LEVEL_5) - if (pkt->entry_type == STATUS_TYPE) - { - if ((uint8_t)(pkt->scsi_status) || pkt->comp_status || - pkt->entry_status) - { - DEBUG(qla1280_print("qla1280_isr: ha->rsp_ring_index = ");) - DEBUG(qla1280_output_number((uint32_t)ha->rsp_ring_index, - 16);) - DEBUG(qla1280_print(" mailbox[5] = ");) - DEBUG(qla1280_output_number((uint32_t)mailbox[5], 16);) - DEBUG(qla1280_print( "\n\r comp_status = ");) - DEBUG(qla1280_output_number((uint32_t)pkt->comp_status,16);) - DEBUG(qla1280_print( ", ");) - DEBUG(qla1280_print( " scsi_status = ");) - DEBUG(qla1280_output_number((uint32_t)pkt->scsi_status,16);) - DEBUG(qla1280_print( "\n\r");) - /* qla1280_print( - "\n\rqla1280_isr: response packet data\n\r"); - qla1280_dump_buffer((caddr_t)pkt, - RESPONSE_ENTRY_SIZE); */ - } - } - else - { - qla1280_print("qla1280_isr: ha->rsp_ring_index = "); - qla1280_output_number((uint32_t)ha->rsp_ring_index, 16); - qla1280_print(" mailbox[5] = "); - qla1280_output_number((uint32_t)mailbox[5], 16); - qla1280_print( - "\n\rqla1280_isr: response packet data\n\r"); - qla1280_dump_buffer((caddr_t)pkt, RESPONSE_ENTRY_SIZE); - } -#endif - if (pkt->entry_type == STATUS_TYPE || pkt->entry_status) - { - if (pkt->entry_type == STATUS_TYPE) - qla1280_status_entry(ha, (sts_entry_t *)pkt, - done_q_first, done_q_last); - else - qla1280_error_entry(ha, pkt, - done_q_first, done_q_last); - - /* Adjust ring index. */ - ha->rsp_ring_index++; - if (ha->rsp_ring_index == RESPONSE_ENTRY_CNT) - { - ha->rsp_ring_index = 0; - ha->response_ring_ptr = ha->response_ring; - } - else - ha->response_ring_ptr++; - WRT_REG_WORD(®->mailbox5, ha->rsp_ring_index); - } -#if QLA1280_TARGET_MODE_SUPPORT - else - { - pkt = &response_entry; - - /* Copy packet. */ - dptr1 = (uint32_t *)ha->response_ring_ptr; - dptr2 = (uint32_t *)pkt; - for (index = 0; index < RESPONSE_ENTRY_SIZE/4; index++) - *dptr2++ = *dptr1++; - - /* Adjust ring index. */ - ha->rsp_ring_index++; - if (ha->rsp_ring_index == RESPONSE_ENTRY_CNT) - { - ha->rsp_ring_index = 0; - ha->response_ring_ptr = ha->response_ring; - } - else - ha->response_ring_ptr++; - WRT_REG_WORD(®->mailbox5, ha->rsp_ring_index); - - /* Release interrupt specific lock */ - QLA1280_INTR_UNLOCK(ha); - - switch (pkt->entry_type) - { - case ACCEPT_TGT_IO_TYPE: - qla1280_atio_entry(ha, (atio_entry_t *)pkt); - break; - case IMMED_NOTIFY_TYPE: - qla1280_notify_entry(ha, (notify_entry_t *)pkt); - break; - case CTIO_RET_TYPE: - qla1280_accept_io(ha, (ctio_ret_entry_t *)pkt); - break; - default: - break; - } - - /* Acquire interrupt specific lock */ - QLA1280_INTR_LOCK(ha); - } -#endif - } - } - else - { - ha->flags.isp_abort_needed = TRUE; -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_isr: Response pointer Error\n"); -#endif - } - } +static void +qla1280_isr(struct scsi_qla_host *ha, struct srb ** done_q_first, + struct srb ** done_q_last) +{ + struct device_reg *reg = ha->iobase; + struct response *pkt; + struct srb *sp = 0; + uint16_t mailbox[MAILBOX_REGISTER_COUNT]; + uint16_t *wptr; + uint32_t index; + u16 istatus; + + ENTER("qla1280_isr"); + + istatus = RD_REG_WORD(®->istatus); + if (!(istatus & (RISC_INT | PCI_INT))) + return; + + /* Save mailbox register 5 */ + mailbox[5] = RD_REG_WORD(®->mailbox5); + + /* Check for mailbox interrupt. */ + + mailbox[0] = RD_REG_WORD(®->semaphore); + + if (mailbox[0] & BIT_0) { + /* Get mailbox data. */ + /* dprintk(1, "qla1280_isr: In Get mailbox data \n"); */ + + wptr = &mailbox[0]; + *wptr++ = RD_REG_WORD(®->mailbox0); + *wptr++ = RD_REG_WORD(®->mailbox1); + *wptr = RD_REG_WORD(®->mailbox2); + if (mailbox[0] != MBA_SCSI_COMPLETION) { + wptr++; + *wptr++ = RD_REG_WORD(®->mailbox3); + *wptr++ = RD_REG_WORD(®->mailbox4); + wptr++; + *wptr++ = RD_REG_WORD(®->mailbox6); + *wptr = RD_REG_WORD(®->mailbox7); + } - LEAVE("qla1280_isr"); -} + /* Release mailbox registers. */ -/* - * qla1280_rst_aen - * Processes asynchronous reset. - * - * Input: - * ha = adapter block pointer. - */ -STATIC void -qla1280_rst_aen(scsi_qla_host_t *ha) -{ -#if QL1280_TARGET_MODE_SUPPORT - notify_entry_t nentry; -#endif - uint8_t b; + WRT_REG_WORD(®->semaphore, 0); + WRT_REG_WORD(®->host_cmd, HC_CLR_RISC_INT); + + dprintk(5, "qla1280_isr: mailbox interrupt mailbox[0] = 0x%x", + mailbox[0]); + + /* Handle asynchronous event */ + switch (mailbox[0]) { + case MBA_SCSI_COMPLETION: /* Response completion */ + dprintk(5, "qla1280_isr: mailbox SCSI response " + "completion\n"); + + if (ha->flags.online) { + /* Get outstanding command index. */ + index = mailbox[2] << 16 | mailbox[1]; + + /* Validate handle. */ + if (index < MAX_OUTSTANDING_COMMANDS) + sp = ha->outstanding_cmds[index]; + else + sp = 0; + + if (sp) { + /* Free outstanding command slot. */ + ha->outstanding_cmds[index] = 0; + + /* Save ISP completion status */ + CMD_RESULT(sp->cmd) = 0; + + /* Place block on done queue */ + sp->s_next = NULL; + sp->s_prev = *done_q_last; + if (!*done_q_first) + *done_q_first = sp; + else + (*done_q_last)->s_next = sp; + *done_q_last = sp; + } else { + /* + * If we get here we have a real problem! + */ + printk(KERN_WARNING + "qla1280: ISP invalid handle"); + } + } + break; + + case MBA_BUS_RESET: /* SCSI Bus Reset */ + ha->flags.reset_marker = 1; + index = mailbox[6] & BIT_0; + ha->bus_settings[index].reset_marker = 1; + + printk(KERN_DEBUG "qla1280_isr(): index %i " + "asynchronous BUS_RESET\n", index); + break; + + case MBA_SYSTEM_ERR: /* System Error */ + printk(KERN_WARNING + "qla1280: ISP System Error - mbx1=%xh, mbx2=" + "%xh, mbx3=%xh\n", mailbox[1], mailbox[2], + mailbox[3]); + break; + + case MBA_REQ_TRANSFER_ERR: /* Request Transfer Error */ + printk(KERN_WARNING + "qla1280: ISP Request Transfer Error\n"); + break; + + case MBA_RSP_TRANSFER_ERR: /* Response Transfer Error */ + printk(KERN_WARNING + "qla1280: ISP Response Transfer Error\n"); + break; + + case MBA_WAKEUP_THRES: /* Request Queue Wake-up */ + dprintk(2, "qla1280_isr: asynchronous WAKEUP_THRES\n"); + break; + + case MBA_TIMEOUT_RESET: /* Execution Timeout Reset */ + dprintk(2, + "qla1280_isr: asynchronous TIMEOUT_RESET\n"); + break; + + case MBA_DEVICE_RESET: /* Bus Device Reset */ + printk(KERN_INFO "qla1280_isr(): asynchronous " + "BUS_DEVICE_RESET\n"); + + ha->flags.reset_marker = 1; + index = mailbox[6] & BIT_0; + ha->bus_settings[index].reset_marker = 1; + break; + + case MBA_BUS_MODE_CHANGE: + dprintk(2, + "qla1280_isr: asynchronous BUS_MODE_CHANGE\n"); + break; + + default: + /* dprintk(1, "qla1280_isr: default case of switch MB \n"); */ + if (mailbox[0] < MBA_ASYNC_EVENT) { + wptr = &mailbox[0]; + memcpy((uint16_t *) ha->mailbox_out, wptr, + MAILBOX_REGISTER_COUNT * + sizeof(uint16_t)); + + if(ha->mailbox_wait != NULL) + complete(ha->mailbox_wait); + } + break; + } + } else { + WRT_REG_WORD(®->host_cmd, HC_CLR_RISC_INT); + } -#ifdef QL_DEBUG_LEVEL_3 - ENTER("qla1280_rst_aen"); + /* + * Response ring - waiting for the mbox_busy flag here seems + * unnecessary as the mailbox data has been copied to ha->mailbox_out + * by the time we actually get here! + */ + if (!(ha->flags.online +#if 0 + && !ha->flags.mbox_busy #endif + )) { + dprintk(2, "qla1280_isr: Response pointer Error\n"); + goto out; + } - if (ha->flags.online && !ha->flags.reset_active && - !ha->flags.abort_isp_active) - { - ha->flags.reset_active = TRUE; - while (ha->flags.reset_marker) - { - /* Issue marker command. */ - ha->flags.reset_marker = FALSE; - for (b = 0; b < ha->ports && !ha->flags.reset_marker; b++) - { - if (ha->bus_settings[b].reset_marker) - { - ha->bus_settings[b].reset_marker = FALSE; - qla1280_marker(ha, b, 0, 0, MK_SYNC_ALL); + if (mailbox[5] >= RESPONSE_ENTRY_CNT) + goto out; - if (!ha->flags.reset_marker) - { -#if QL1280_TARGET_MODE_SUPPORT - /* Issue notify acknowledgement command. */ - bzero((caddr_t)&nentry, sizeof(notify_entry_t)); + while (ha->rsp_ring_index != mailbox[5]) { + pkt = ha->response_ring_ptr; - nentry.initiator_id = nentry.target_id = b ? - ha->bus_settings[b].id | BIT_7 : - ha->bus_settings[b].id; - qla1280_notify_entry(ha, &nentry); -#endif + dprintk(5, "qla1280_isr: ha->rsp_ring_index = 0x%x, mailbox[5]" + " = 0x%x\n", ha->rsp_ring_index, mailbox[5]); + dprintk(5,"qla1280_isr: response packet data\n"); + qla1280_dump_buffer(5, (char *)pkt, RESPONSE_ENTRY_SIZE); + + if (pkt->entry_type == STATUS_TYPE) { + if ((le16_to_cpu(pkt->scsi_status) & 0xff) + || pkt->comp_status || pkt->entry_status) { + dprintk(2, "qla1280_isr: ha->rsp_ring_index = " + "0x%x mailbox[5] = 0x%x, comp_status " + "= 0x%x, scsi_status = 0x%x\n", + ha->rsp_ring_index, mailbox[5], + le16_to_cpu(pkt->comp_status), + le16_to_cpu(pkt->scsi_status)); + } + } else { + dprintk(2, "qla1280_isr: ha->rsp_ring_index = " + "0x%x, mailbox[5] = 0x%x\n", + ha->rsp_ring_index, mailbox[5]); + dprintk(2, "qla1280_isr: response packet data\n"); + qla1280_dump_buffer(2, (char *)pkt, + RESPONSE_ENTRY_SIZE); + } - /* Asynchronous event notification */ - } - } - } - } - } + if (pkt->entry_type == STATUS_TYPE || pkt->entry_status) { + dprintk(2, "status: Cmd %p, handle %i\n", + ha->outstanding_cmds[pkt->handle]->cmd, + pkt->handle); + if (pkt->entry_type == STATUS_TYPE) + qla1280_status_entry(ha, pkt, done_q_first, + done_q_last); + else + qla1280_error_entry(ha, pkt, done_q_first, + done_q_last); -#ifdef QL_DEBUG_LEVEL_3 - LEAVE("qla1280_rst_aen"); -#endif + /* Adjust ring index. */ + ha->rsp_ring_index++; + if (ha->rsp_ring_index == RESPONSE_ENTRY_CNT) { + ha->rsp_ring_index = 0; + ha->response_ring_ptr = ha->response_ring; + } else + ha->response_ring_ptr++; + WRT_REG_WORD(®->mailbox5, ha->rsp_ring_index); + } + } + + out: + LEAVE("qla1280_isr"); } -#if QL1280_TARGET_MODE_SUPPORT /* - * qla1280_atio_entry - * Processes received ISP accept target I/O entry. + * qla1280_rst_aen + * Processes asynchronous reset. * * Input: * ha = adapter block pointer. - * pkt = entry pointer. */ -STATIC void -qla1280_atio_entry(scsi_qla_host_t *ha, atio_entry_t *pkt) +static void +qla1280_rst_aen(struct scsi_qla_host *ha) { - uint64_t *a64; - uint64_t *end_a64; - paddr32_t phy_addr[2]; - paddr32_t end_addr[2]; - uint32_t len; - uint32_t offset; - uint8_t t; - uint8_t *sense_ptr; - -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_atio_entry: entered\n\r"); -#endif - - t = pkt->initiator_id; - sense_ptr = ha->tsense + t * TARGET_SENSE_SIZE; - a64 = (uint64_t *)&phy_addr[0]; - end_a64 = (uint64_t *)&end_addr[0]; - - switch (pkt->status & ~BIT_7) - { - case 7: /* Path invalid */ -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - qla1280_print("qla1280_atio_entry: Path invalid\n\r"); -#endif - break; - case 0x14: /* Target Bus Phase Sequence Failure */ -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - qla1280_print( - "qla1280_atio_entry: Target Bus Phase Sequence Failure\n\r"); -#endif - if (pkt->status & BIT_7) - { - BCOPY((caddr_t)&pkt->sense_data, sense_ptr,TARGET_SENSE_SIZE); - } - else - { - bzero(sense_ptr, TARGET_SENSE_SIZE); - *sense_ptr = 0x70; - *(sense_ptr+2) = SD_HARDERR; - *(sense_ptr+7) = TARGET_SENSE_SIZE-8; - *(sense_ptr+12) = SC_SELFAIL; - } - pkt->scsi_status = S_CKCON; - pkt->option_flags |= (uint32_t)OF_SSTS | (uint32_t)OF_NO_DATA; - if (ha->flags.enable_64bit_addressing) - qla1280_64bit_continue_io(ha, pkt, 0, 0); - else - qla1280_32bit_continue_io(ha, pkt, 0, 0); - break; - case 0x16: /* Requested Capability Not Available */ -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - qla1280_print( - "qla1280_atio_entry: Target Bus Phase Sequence Failure\n\r"); -#endif - break; - case 0x17: /* Bus Device Reset Message Received */ -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - qla1280_print( - "qla1280_atio_entry: Target Bus Phase Sequence Failure\n\r"); -#endif - break; - case 0x3D: /* CDB Received */ - - /* Check for invalid LUN */ - if (pkt->lun && pkt->cdb[0] != SS_INQUIR && - pkt->cdb[0] != SS_REQSEN) - pkt->cdb[0] = SS_TEST; - - switch (pkt->cdb[0]) - { - case SS_TEST: -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_atio_entry: SS_TEST\n\r"); -#endif - bzero(sense_ptr, TARGET_SENSE_SIZE); - len = 0; - if (pkt->lun == 0) - pkt->scsi_status = S_GOOD; - else - { - *sense_ptr = 0x70; - *(sense_ptr+2) = SD_ILLREQ; - *(sense_ptr+7) = TARGET_SENSE_SIZE-8; - *(sense_ptr+12) = SC_INVLUN; - pkt->scsi_status = S_CKCON; - } - - pkt->option_flags |= (uint32_t)OF_SSTS | - (uint32_t)OF_NO_DATA; - break; - case SS_REQSEN: -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_atio_entry: SS_REQSEN\n\r"); -#endif - phy_addr[0] = ha->tsense_dma; - phy_addr[1] = 0; - *a64 += t * TARGET_SENSE_SIZE; - if (pkt->cdb[4] > TARGET_SENSE_SIZE) - len = TARGET_SENSE_SIZE; - else - len = pkt->cdb[4]; - pkt->scsi_status = S_GOOD; - pkt->option_flags |= (uint32_t)OF_SSTS | - (uint32_t)OF_DATA_IN; - break; - case SS_INQUIR: -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_atio_entry: SS_INQUIR\n\r"); -#endif - bzero(sense_ptr, TARGET_SENSE_SIZE); - phy_addr[0] = ha->tbuf_dma; - phy_addr[1] = 0; - *a64 += TARGET_INQ_OFFSET; - - if (pkt->lun == 0) - { - ha->tbuf->inq.id_type = ID_PROCESOR; - ha->tbuf->inq.id_pqual = ID_QOK; - } - else - { - ha->tbuf->inq.id_type = ID_NODEV; - ha->tbuf->inq.id_pqual = ID_QNOLU; - } - - if (pkt->cdb[4] > sizeof(struct ident)) - len = sizeof(struct ident); - else - len = pkt->cdb[4]; - pkt->scsi_status = S_GOOD; - pkt->option_flags |= (uint32_t)OF_SSTS | - (uint32_t)OF_DATA_IN; - break; - case SM_WRDB: - bzero(sense_ptr, TARGET_SENSE_SIZE); - offset = pkt->cdb[5]; - offset |= pkt->cdb[4] << 8; - offset |= pkt->cdb[3] << 16; - len = pkt->cdb[8]; - len |= pkt->cdb[7] << 8; - len |= pkt->cdb[6] << 16; - end_addr[0] = phy_addr[0] = ha->tbuf_dma; - end_addr[1] = phy_addr[1] = 0; - *end_a64 += TARGET_DATA_OFFSET + TARGET_DATA_SIZE; - switch (pkt->cdb[1] & 7) - { - case RW_BUF_HDATA: -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_atio_entry: SM_WRDB, RW_BUF_HDATA\n\r"); -#endif - if (len > TARGET_DATA_SIZE + 4) - { -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_atio_entry: SM_WRDB, length > buffer size\n\r"); -#endif - *sense_ptr = 0x70; - *(sense_ptr+2) = SD_ILLREQ; - *(sense_ptr+7) = TARGET_SENSE_SIZE-8; - *(sense_ptr+12) = SC_ILLCDB; - pkt->scsi_status = S_CKCON; - pkt->option_flags |= (uint32_t)OF_SSTS | - (uint32_t)OF_NO_DATA; - len = 0; - } - else if (len) - { - pkt->scsi_status = S_GOOD; - pkt->option_flags |= (uint32_t)OF_SSTS | - (uint32_t)OF_DATA_OUT; -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_atio_entry: Issuing SDI_TARMOD_WRCOMP\n\r"); -#endif - sdi_xaen(SDI_TARMOD_WRCOMP, ha->cntlr, - pkt->target_id, pkt->lun, 0, offset); - } - else - { -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_atio_entry: SM_WRDB, zero length\n\r"); -#endif - pkt->scsi_status = S_GOOD; - pkt->option_flags |= (uint32_t)OF_SSTS | - (uint32_t)OF_NO_DATA; - } - - break; - case RW_BUF_DATA: -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_atio_entry: SM_WRDB, RW_BUF_DATA\n\r"); -#endif - *a64 += offset + TARGET_DATA_OFFSET; - if (pkt->cdb[2] != 0 || *a64 >= *end_a64 || - *a64 + len > *end_a64) - { -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_atio_entry: SM_WRDB, RW_BUF_DATA BAD\n\r"); - qla1280_print("buf_id="); - qla1280_output_number((uint32_t)pkt->cdb[2], 16); - qla1280_print(", offset="); - qla1280_output_number((uint32_t)offset, 16); - qla1280_print(", length="); - qla1280_output_number((uint32_t)len, 16); - qla1280_print("\n\r"); -#endif - *sense_ptr = 0x70; - *(sense_ptr+2) = SD_ILLREQ; - *(sense_ptr+7) = TARGET_SENSE_SIZE-8; - *(sense_ptr+12) = SC_ILLCDB; - len = 0; - pkt->scsi_status = S_CKCON; - pkt->option_flags |= (uint32_t)OF_SSTS | - (uint32_t)OF_NO_DATA; - } - else if (len) - { - pkt->scsi_status = S_GOOD; - pkt->option_flags |= (uint32_t)OF_SSTS | - (uint32_t)OF_DATA_OUT; -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_atio_entry: Issuing SDI_TARMOD_WRCOMP\n\r"); -#endif - sdi_xaen(SDI_TARMOD_WRCOMP, ha->cntlr, - pkt->target_id, pkt->lun, 0, offset); - } - else - { -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_atio_entry: SM_WRDB, zero length\n\r"); -#endif - pkt->scsi_status = S_GOOD; - pkt->option_flags |= (uint32_t)OF_SSTS | - (uint32_t)OF_NO_DATA; - } - break; - default: -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_atio_entry: SM_WRDB unknown mode\n\r"); -#endif - *sense_ptr = 0x70; - *(sense_ptr+2) = SD_ILLREQ; - *(sense_ptr+7) = TARGET_SENSE_SIZE-8; - *(sense_ptr+12) = SC_ILLCDB; - len = 0; - pkt->scsi_status = S_CKCON; - pkt->option_flags |= (uint32_t)OF_SSTS | - (uint32_t)OF_NO_DATA; - break; - } - break; - case SM_RDDB: - bzero(sense_ptr, TARGET_SENSE_SIZE); - offset = pkt->cdb[5]; - offset |= pkt->cdb[4] << 8; - offset |= pkt->cdb[3] << 16; - len = pkt->cdb[8]; - len |= pkt->cdb[7] << 8; - len |= pkt->cdb[6] << 16; - end_addr[0] = phy_addr[0] = ha->tbuf_dma; - end_addr[1] = phy_addr[1] = 0; - *end_a64 += TARGET_DATA_OFFSET + TARGET_DATA_SIZE; - switch (pkt->cdb[1] & 7) - { - case RW_BUF_HDATA: -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_atio_entry: SM_RDDB, RW_BUF_HDATA\n\r"); -#endif - if (len) - { - ha->tbuf->hdr[0] = 0; - ha->tbuf->hdr[1] = - (uint8_t)(TARGET_DATA_SIZE >> 16); - ha->tbuf->hdr[2] = - (uint8_t)(TARGET_DATA_SIZE >> 8); - ha->tbuf->hdr[3] = (uint8_t)TARGET_DATA_SIZE; - if (len > TARGET_DATA_SIZE + 4) - len = TARGET_DATA_SIZE + 4; - pkt->scsi_status = S_GOOD; - pkt->option_flags |= (uint32_t)OF_SSTS | - (uint32_t)OF_DATA_IN; - } - else - { -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_atio_entry: SM_RDDB, zero length\n\r"); -#endif - pkt->scsi_status = S_GOOD; - pkt->option_flags |= (uint32_t)OF_SSTS | - (uint32_t)OF_NO_DATA; - } - break; - case RW_BUF_DATA: -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_atio_entry: SM_RDDB, RW_BUF_DATA\n\r"); -#endif - *a64 += offset + TARGET_DATA_OFFSET; - if (pkt->cdb[2] != 0 || *a64 >= *end_a64) - { -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_atio_entry: SM_RDDB, RW_BUF_DATA BAD\n\r"); - qla1280_print("buf_id="); - qla1280_output_number((uint32_t)pkt->cdb[2], 16); - qla1280_print(", offset="); - qla1280_output_number((uint32_t)offset, 16); - qla1280_print("\n\r"); -#endif - *sense_ptr = 0x70; - *(sense_ptr+2) = SD_ILLREQ; - *(sense_ptr+7) = TARGET_SENSE_SIZE-8; - *(sense_ptr+12) = SC_ILLCDB; - len = 0; - pkt->scsi_status = S_CKCON; - pkt->option_flags |= (uint32_t)OF_SSTS | - (uint32_t)OF_NO_DATA; - } - else - { - if (*a64 + len > *end_a64) - len = *end_a64 - *a64; - if (len) - { - pkt->scsi_status = S_GOOD; - pkt->option_flags |= (uint32_t)OF_SSTS | - (uint32_t)OF_DATA_IN; - } - else - { -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_atio_entry: SM_RDDB, zero length\n\r"); -#endif - pkt->scsi_status = S_GOOD; - pkt->option_flags |= (uint32_t)OF_SSTS | - (uint32_t)OF_NO_DATA; - } - } - break; - case RW_BUF_DESC: -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_atio_entry: SM_RDDB, RW_BUF_DESC\n\r"); -#endif - if (len) - { - if (len > 4) - len = 4; - - ha->tbuf->hdr[0] = 0; - if (pkt->cdb[2] != 0) - { - ha->tbuf->hdr[1] = 0; - ha->tbuf->hdr[2] = 0; - ha->tbuf->hdr[3] = 0; - } - else - { - ha->tbuf->hdr[1] = - (uint8_t)(TARGET_DATA_SIZE >> 16); - ha->tbuf->hdr[2] = - (uint8_t)(TARGET_DATA_SIZE >> 8); - ha->tbuf->hdr[3] = - (uint8_t)TARGET_DATA_SIZE; - } - pkt->scsi_status = S_GOOD; - pkt->option_flags |= (uint32_t)OF_SSTS | - (uint32_t)OF_DATA_IN; - } - else - { -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_atio_entry: SM_RDDB, zero length\n\r"); -#endif - pkt->scsi_status = S_GOOD; - pkt->option_flags |= (uint32_t)OF_SSTS | - (uint32_t)OF_NO_DATA; - } - break; - default: -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_atio_entry: SM_RDDB unknown mode\n\r"); -#endif - *sense_ptr = 0x70; - *(sense_ptr+2) = SD_ILLREQ; - *(sense_ptr+7) = TARGET_SENSE_SIZE-8; - *(sense_ptr+12) = SC_ILLCDB; - len = 0; - pkt->scsi_status = S_CKCON; - pkt->option_flags |= (uint32_t)OF_SSTS | - (uint32_t)OF_NO_DATA; - break; - } - break; - default: -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_atio_entry: Unknown SCSI command\n\r"); - qla1280_dump_buffer((caddr_t)&pkt->cdb[0], pkt->cdb_len); -#endif - bzero(sense_ptr, TARGET_SENSE_SIZE); - *sense_ptr = 0x70; - *(sense_ptr+2) = SD_ILLREQ; - *(sense_ptr+7) = TARGET_SENSE_SIZE-8; - *(sense_ptr+12) = SC_INVOPCODE; - len = 0; - pkt->scsi_status = S_CKCON; - pkt->option_flags |= (uint32_t)OF_SSTS | - (uint32_t)OF_NO_DATA; - break; - } - if (ha->flags.enable_64bit_addressing) - qla1280_64bit_continue_io(ha, pkt, len, (paddr32_t *)&phy_addr); - else - qla1280_32bit_continue_io(ha, pkt, len, (paddr32_t *)&phy_addr); - break; - default: - break; - } + uint8_t bus; -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_atio_entry: exiting normally\n\r"); -#endif + ENTER("qla1280_rst_aen"); + + if (ha->flags.online && !ha->flags.reset_active && + !ha->flags.abort_isp_active) { + ha->flags.reset_active = 1; + while (ha->flags.reset_marker) { + /* Issue marker command. */ + ha->flags.reset_marker = 0; + for (bus = 0; bus < ha->ports && + !ha->flags.reset_marker; bus++) { + if (ha->bus_settings[bus].reset_marker) { + ha->bus_settings[bus].reset_marker = 0; + qla1280_marker(ha, bus, 0, 0, + MK_SYNC_ALL); + } + } + } + } + + LEAVE("qla1280_rst_aen"); } + +#if LINUX_VERSION_CODE < 0x020500 /* - * qla1280_notify_entry - * Processes received ISP immediate notify entry. * - * Input: - * ha = adapter block pointer. - * pkt = entry pointer. */ -STATIC void -qla1280_notify_entry(scsi_qla_host_t *ha, notify_entry_t *pkt) +static void +qla1280_get_target_options(struct scsi_cmnd *cmd, struct scsi_qla_host *ha) { -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_notify_entry: entered\n\r"); -#endif + unsigned char *result; + struct nvram *n; + int bus, target, lun; - /* Acknowledge immediate notify */ - qla1280_notify_ack(ha, pkt); + bus = SCSI_BUS_32(cmd); + target = SCSI_TCN_32(cmd); + lun = SCSI_LUN_32(cmd); - /* Issue notify entry to increment resource count */ - qla1280_immed_notify(ha, pkt); + /* + * Make sure to not touch anything if someone is using the + * sg interface. + */ + if (cmd->use_sg || (CMD_RESULT(cmd) >> 16) != DID_OK || lun) + return; -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_notify_entry: exiting normally\n\r"); -#endif + result = cmd->request_buffer; + n = &ha->nvram; + + n->bus[bus].target[target].parameter.f.enable_wide = 0; + n->bus[bus].target[target].parameter.f.enable_sync = 0; + n->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 0; + + if (result[7] & 0x60) + n->bus[bus].target[target].parameter.f.enable_wide = 1; + if (result[7] & 0x10) + n->bus[bus].target[target].parameter.f.enable_sync = 1; + if ((result[2] >= 3) && (result[4] + 5 > 56) && + (result[56] & 0x4)) + n->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 1; + + dprintk(2, "get_target_options(): wide %i, sync %i, ppr %i\n", + n->bus[bus].target[target].parameter.f.enable_wide, + n->bus[bus].target[target].parameter.f.enable_sync, + n->bus[bus].target[target].ppr_1x160.flags.enable_ppr); } +#endif -#endif /* QLA1280_TARGET_MODE_SUPPORT */ /* * qla1280_status_entry * Processes received ISP status entry. @@ -5724,104 +4570,92 @@ * done_q_first = done queue first pointer. * done_q_last = done queue last pointer. */ -STATIC void -qla1280_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt, srb_t **done_q_first, - srb_t **done_q_last) -{ - uint32_t b, t, l; - uint8_t sense_sz = 0; - srb_t *sp; - scsi_lu_t *q; - Scsi_Cmnd *cp; - -#ifdef QL_DEBUG_LEVEL_3 - ENTER("qla1280_status_entry"); -#endif - - /* Validate handle. */ - if (pkt->handle < MAX_OUTSTANDING_COMMANDS) - sp = ha->outstanding_cmds[pkt->handle]; - else - sp = 0; - - if (sp) - { - /* Free outstanding command slot. */ - ha->outstanding_cmds[pkt->handle] = 0; - - cp = sp->cmd; - /* Generate LU queue on cntrl, target, LUN */ - b = SCSI_BUS_32(cp); - t = SCSI_TCN_32(cp); - l = SCSI_LUN_32(cp); - q = LU_Q(ha, b, t, l); - if( pkt->comp_status || pkt->scsi_status ) - { - DEBUG(qla1280_print( "scsi: comp_status = ");) - DEBUG(qla1280_output_number((uint32_t)pkt->comp_status,16);) - DEBUG(qla1280_print( ", ");) - DEBUG(qla1280_print( " scsi_status = ");) - DEBUG(qla1280_output_number((uint32_t)pkt->scsi_status,16);) - DEBUG(qla1280_print( "\n\r");) - DEBUG(qla1280_print(", handle = ");) - DEBUG(qla1280_output_number((uint32_t)pkt->handle, 16);) - DEBUG(qla1280_print("\n\r");) - } - - /* Target busy */ - if ( pkt->scsi_status & SS_BUSY_CONDITION && - pkt->scsi_status != SS_RESERVE_CONFLICT ) - { - CMD_RESULT(cp) = (int) (DID_BUS_BUSY << 16) | - (pkt->scsi_status & 0xff); - } - else - { - - /* Save ISP completion status */ - CMD_RESULT(cp) = qla1280_return_status( pkt, cp ); - - if (pkt->scsi_status & SS_CHECK_CONDITION) - { - BZERO(cp->sense_buffer, CMD_SNSLEN(cp)); - if (pkt->comp_status != CS_ARS_FAILED) - { - if ( pkt->req_sense_length < CMD_SNSLEN(cp) ) - sense_sz = pkt->req_sense_length; - else - sense_sz = CMD_SNSLEN(cp) - 1; - - BCOPY((caddr_t)&pkt->req_sense_data, cp->sense_buffer, sense_sz); - - } -#ifdef QL_DEBUG_LEVEL_2 - DEBUG(qla1280_print( - "qla1280_status_entry: Check condition Sense data, b");) - DEBUG(qla1280_output_number((uint32_t)b, 10);) - DEBUG(qla1280_print("t");) - DEBUG(qla1280_output_number((uint32_t)t, 10);) - DEBUG(qla1280_print("d");) - DEBUG(qla1280_output_number((uint32_t)l, 10);) - DEBUG(qla1280_print("\n\r");) - DEBUG(if (sense_sz)) - DEBUG(qla1280_dump_buffer(cp->sense_buffer, sense_sz);) -#endif - } - } - /* Place command on done queue. */ - qla1280_done_q_put(sp, done_q_first, done_q_last); - } - else - { -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_status_entry: ISP Invalid handle\n\r"); -#endif - printk(KERN_WARNING "qla1280: Status Entry invalid handle\n"); - ha->flags.isp_abort_needed = TRUE; - } -#ifdef QL_DEBUG_LEVEL_3 - LEAVE("qla1280_status_entry"); -#endif +static void +qla1280_status_entry(struct scsi_qla_host *ha, struct response *pkt, + struct srb **done_q_first, struct srb **done_q_last) +{ + unsigned int bus, target, lun; + int sense_sz; + struct srb *sp; + Scsi_Cmnd *cmd; + uint32_t handle = le32_to_cpu(pkt->handle); + uint16_t scsi_status = le16_to_cpu(pkt->scsi_status); + uint16_t comp_status = le16_to_cpu(pkt->comp_status); + + ENTER("qla1280_status_entry"); + + /* Validate handle. */ + if (handle < MAX_OUTSTANDING_COMMANDS) + sp = ha->outstanding_cmds[handle]; + else + sp = NULL; + + if (!sp) { + printk(KERN_WARNING "qla1280: Status Entry invalid handle\n"); + goto out; + } + + /* Free outstanding command slot. */ + ha->outstanding_cmds[handle] = 0; + + cmd = sp->cmd; + + /* Generate LU queue on cntrl, target, LUN */ + bus = SCSI_BUS_32(cmd); + target = SCSI_TCN_32(cmd); + lun = SCSI_LUN_32(cmd); + + if (comp_status || scsi_status) { + dprintk(3, "scsi: comp_status = 0x%x, scsi_status = " + "0x%x, handle = 0x%x\n", comp_status, + scsi_status, handle); + } + + /* Target busy */ + if (scsi_status & SS_BUSY_CONDITION && + scsi_status != SS_RESERVE_CONFLICT) { + CMD_RESULT(cmd) = + DID_BUS_BUSY << 16 | (scsi_status & 0xff); + } else { + + /* Save ISP completion status */ + CMD_RESULT(cmd) = qla1280_return_status(pkt, cmd); + + if (scsi_status & SS_CHECK_CONDITION) { + if (comp_status != CS_ARS_FAILED) { + uint16_t req_sense_length = + le16_to_cpu(pkt->req_sense_length); + if (req_sense_length < CMD_SNSLEN(cmd)) + sense_sz = req_sense_length; + else + /* + * Scsi_Cmnd->sense_buffer is + * 64 bytes, why only copy 63? + * This looks wrong! /Jes + */ + sense_sz = CMD_SNSLEN(cmd) - 1; + + memcpy(cmd->sense_buffer, + &pkt->req_sense_data, sense_sz); + } else + sense_sz = 0; + memset(cmd->sense_buffer + sense_sz, 0, + sizeof(cmd->sense_buffer) - sense_sz); + + dprintk(2, "qla1280_status_entry: Check " + "condition Sense data, b %i, t %i, " + "l %i\n", bus, target, lun); + if (sense_sz) + qla1280_dump_buffer(2, + (char *)cmd->sense_buffer, + sense_sz); + } + } + /* Place command on done queue. */ + qla1280_done_q_put(sp, done_q_first, done_q_last); + + out: + LEAVE("qla1280_status_entry"); } /* @@ -5834,71 +4668,55 @@ * done_q_first = done queue first pointer. * done_q_last = done queue last pointer. */ -STATIC void -qla1280_error_entry(scsi_qla_host_t *ha, response_t *pkt, srb_t **done_q_first, - srb_t **done_q_last) -{ - srb_t *sp; - -#ifdef QL_DEBUG_LEVEL_3 - ENTER("qla1280_error_entry"); -#endif - -#ifdef QL_DEBUG_LEVEL_2 - if (pkt->entry_status & BIT_3) - qla1280_print("qla1280_error_entry: BAD PAYLOAD flag error\n\r"); - else if (pkt->entry_status & BIT_2) - qla1280_print("qla1280_error_entry: BAD HEADER flag error\n\r"); - else if (pkt->entry_status & BIT_1) - qla1280_print("qla1280_error_entry: FULL flag error\n\r"); - else - qla1280_print("qla1280_error_entry: UNKNOWN flag error\n\r"); -#endif - - /* Validate handle. */ - if (pkt->handle < MAX_OUTSTANDING_COMMANDS) - sp = ha->outstanding_cmds[pkt->handle]; - else - sp = 0; - - if (sp) - { - /* Free outstanding command slot. */ - ha->outstanding_cmds[pkt->handle] = 0; - - /* Bad payload or header */ - if (pkt->entry_status & (BIT_3 + BIT_2)) - { - /* Bad payload or header, set error status. */ - /* CMD_RESULT(sp->cmd) = CS_BAD_PAYLOAD; */ - CMD_RESULT(sp->cmd) = (int) DID_ERROR << 16; - } - else if (pkt->entry_status & BIT_1 ) /* FULL flag */ - { - CMD_RESULT(sp->cmd) = (int) DID_BUS_BUSY << 16; - } - else - { - /* Set error status. */ - CMD_RESULT(sp->cmd) =(int) DID_ERROR << 16; - } - /* Place command on done queue. */ - qla1280_done_q_put(sp, done_q_first, done_q_last); - } -#if QLA1280_64BIT_SUPPORT - else if (pkt->entry_type == COMMAND_A64_TYPE) - { -#ifdef QL_DEBUG_LEVEL_2 - qla1280_print("qla1280_error_entry: ISP Invalid handle\n\r"); -#endif - printk(KERN_WARNING "!qla1280: Error Entry invalid handle"); - ha->flags.isp_abort_needed = TRUE; - } -#endif +static void +qla1280_error_entry(struct scsi_qla_host *ha, struct response * pkt, + struct srb ** done_q_first, struct srb ** done_q_last) +{ + struct srb *sp; + uint32_t handle = le32_to_cpu(pkt->handle); + + ENTER("qla1280_error_entry"); + + if (pkt->entry_status & BIT_3) + dprintk(2, "qla1280_error_entry: BAD PAYLOAD flag error\n"); + else if (pkt->entry_status & BIT_2) + dprintk(2, "qla1280_error_entry: BAD HEADER flag error\n"); + else if (pkt->entry_status & BIT_1) + dprintk(2, "qla1280_error_entry: FULL flag error\n"); + else + dprintk(2, "qla1280_error_entry: UNKNOWN flag error\n"); -#ifdef QL_DEBUG_LEVEL_3 - LEAVE("qla1280_error_entry"); + /* Validate handle. */ + if (handle < MAX_OUTSTANDING_COMMANDS) + sp = ha->outstanding_cmds[handle]; + else + sp = 0; + + if (sp) { + /* Free outstanding command slot. */ + ha->outstanding_cmds[handle] = 0; + + /* Bad payload or header */ + if (pkt->entry_status & (BIT_3 + BIT_2)) { + /* Bad payload or header, set error status. */ + /* CMD_RESULT(sp->cmd) = CS_BAD_PAYLOAD; */ + CMD_RESULT(sp->cmd) = DID_ERROR << 16; + } else if (pkt->entry_status & BIT_1) { /* FULL flag */ + CMD_RESULT(sp->cmd) = DID_BUS_BUSY << 16; + } else { + /* Set error status. */ + CMD_RESULT(sp->cmd) = DID_ERROR << 16; + } + /* Place command on done queue. */ + qla1280_done_q_put(sp, done_q_first, done_q_last); + } +#ifdef QLA_64BIT_PTR + else if (pkt->entry_type == COMMAND_A64_TYPE) { + printk(KERN_WARNING "!qla1280: Error Entry invalid handle"); + } #endif + + LEAVE("qla1280_error_entry"); } /* @@ -5911,236 +4729,91 @@ * Returns: * 0 = success */ -STATIC uint8_t -qla1280_abort_isp(scsi_qla_host_t *ha) -{ - device_reg_t *reg = ha->iobase; - uint8_t status = 0; - uint16_t cnt; - srb_t *sp; - scsi_lu_t *q; - uint32_t b, t, l; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) - unsigned long cpu_flags = 0; -#endif - -#ifdef QL_DEBUG_LEVEL_3 - ENTER("qla1280_abort_isp"); -#endif - - DRIVER_LOCK - ha->flags.isp_abort_needed = FALSE; - if (!ha->flags.abort_isp_active && ha->flags.online) - { - ha->flags.abort_isp_active = TRUE; - - /* Disable ISP interrupts. */ - WRT_REG_WORD(®->ictrl, 0); - - /* Dequeue all commands in outstanding command list. */ - for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) - { - sp = ha->outstanding_cmds[cnt]; - if (sp) - { - ha->outstanding_cmds[cnt] = 0; - - /* Generate LU queue on controller, target, LUN */ - b = SCSI_BUS_32(sp->cmd); - t = SCSI_TCN_32(sp->cmd); - l = SCSI_LUN_32(sp->cmd); - - q = (scsi_lu_t *)LU_Q(ha, b, t, l); - - /* Reset outstanding command count. */ - q->q_outcnt = 0; - q->q_flag &= ~QLA1280_QBUSY; - q->q_flag = 0; - - /* Adjust watchdog timer for command. */ - /* if (sp->flags & SRB_WATCHDOG) - sp->timeout += 2; */ - - /* Place request back on top of device queue. */ - /* sp->flags &= ~(SRB_SENT | SRB_TIMEOUT); */ - sp->flags = 0; - qla1280_putq_t(q, sp); - } - } - - /* If firmware needs to be loaded */ - if (qla1280_isp_firmware(ha)) - { - if (!(status = qla1280_chip_diag(ha))) - status = qla1280_setup_chip(ha); - } - - if (!status) - { - /* Setup adapter based on NVRAM parameters. */ - qla1280_nvram_config(ha); - - if (!(status = qla1280_init_rings(ha))) - { - /* Issue SCSI reset. */ - for (b = 0; b < ha->ports; b++) - { - qla1280_bus_reset(ha, b); - } - do - { - /* Issue marker command. */ - ha->flags.reset_marker = FALSE; - for (b = 0; b < ha->ports; b++) - { - ha->bus_settings[b].reset_marker = FALSE; - qla1280_marker(ha, b, 0, 0, MK_SYNC_ALL); - } - }while (ha->flags.reset_marker); - - /* Enable host adapter target mode. */ - for (b = 0; b < ha->ports; b++) - { - if (!(status = qla1280_enable_tgt(ha, b))) - { - for (cnt = 0; cnt < MAX_LUNS; cnt++) - { - /* qla1280_enable_lun(ha, b, cnt); */ - qla1280_poll(ha); - } - } - else - break; - } - - if (!status) - { - /* Enable ISP interrupts. */ - WRT_REG_WORD(®->ictrl, ISP_EN_INT + ISP_EN_RISC); - ha->flags.abort_isp_active = FALSE; - /* Restart queues that may have been stopped. */ - qla1280_restart_queues(ha); - } - } - } - } - - if (status) - { - printk(KERN_WARNING - "qla1280: ISP error recovery failed, board disabled"); - qla1280_reset_adapter(ha); - qla1280_abort_queues(ha); - -#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) - qla1280_print("qla1280_abort_isp: **** FAILED ****\n\r"); -#endif - } -#ifdef QL_DEBUG_LEVEL_3 - else - LEAVE("qla1280_abort_isp"); -#endif - DRIVER_UNLOCK - - return(status); -} - -/* - * qla1280_restart_queues - * Restart all device queues. - * - * Input: - * ha = adapter block pointer. - */ -STATIC void -qla1280_restart_queues(scsi_qla_host_t *ha) +static int +qla1280_abort_isp(struct scsi_qla_host *ha) { - scsi_lu_t *q; - uint32_t b, t, l; + struct srb *sp; + int status = 0; + int cnt; + int bus; -#ifdef QL_DEBUG_LEVEL_3 - ENTER("qla1280_restart_queues"); -#endif - - for (b = 0; b < ha->ports; b++) - for (t = 0; t < MAX_TARGETS; t++) - for (l = 0; l < MAX_LUNS; l++) - { - q = (scsi_lu_t *) LU_Q(ha, b, t, l); - if (q != NULL) - { - /* Acquire LU queue specific lock */ - QLA1280_SCSILU_LOCK(q); + ENTER("qla1280_abort_isp"); - if (q->q_first) - qla1280_next(ha, q, b); - else - /* Release LU queue specific lock */ - QLA1280_SCSILU_UNLOCK(q); - } - } -#ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_restart_queues: exiting normally\n"); -#endif -} + if (!ha->flags.abort_isp_active && ha->flags.online) { + struct device_reg *reg = ha->iobase; + ha->flags.abort_isp_active = 1; -/* - * qla1280_abort_queue_single - * Abort all commands on a device queues. - * - * Input: - * ha = adapter block pointer. - */ -STATIC void qla1280_abort_queue_single(scsi_qla_host_t *ha,uint32_t b,uint32_t t,uint32_t l,uint32_t stat) -{ - scsi_lu_t *q; - srb_t *sp, *sp_next; + /* Disable ISP interrupts. */ + qla1280_disable_intrs(ha); + WRT_REG_WORD(®->host_cmd, HC_PAUSE_RISC); + RD_REG_WORD(®->id_l); - ENTER("qla1280_abort_queue_single"); - q = (scsi_lu_t * )LU_Q(ha, b, t, l); - if (q != NULL) - { - /* Acquire LU queue specific lock */ - QLA1280_SCSILU_LOCK(q); + printk(KERN_INFO "scsi(%li): dequeuing outstanding commands\n", + ha->host_no); + /* Dequeue all commands in outstanding command list. */ + for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { + Scsi_Cmnd *cmd; + sp = ha->outstanding_cmds[cnt]; + if (sp) { + + cmd = sp->cmd; + CMD_RESULT(cmd) = DID_RESET << 16; - sp = q->q_first; - q->q_first = q->q_last = NULL; + sp->cmd = NULL; + ha->outstanding_cmds[cnt] = NULL; - QLA1280_SCSILU_UNLOCK(q); + (*cmd->scsi_done)(cmd); - while (sp) - { - sp_next = sp->s_next; - CMD_RESULT(sp->cmd) = stat; - qla1280_done_q_put(sp, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); - sp = sp_next; - } - } - LEAVE("qla1280_abort_queue_single"); -} + sp->flags = 0; + } + } -/* - * qla1280_abort_queues - * Abort all commands on device queues. - * - * Input: - * ha = adapter block pointer. - */ -STATIC void -qla1280_abort_queues(scsi_qla_host_t *ha) -{ - uint32_t b, t, l; + /* If firmware needs to be loaded */ + if (qla1280_isp_firmware (ha)) { + if (!(status = qla1280_chip_diag(ha))) + status = qla1280_setup_chip(ha); + } - ENTER("qla1280_abort_queues"); + if (!status) { + /* Setup adapter based on NVRAM parameters. */ + qla1280_nvram_config (ha); + + if (!(status = qla1280_init_rings(ha))) { + /* Issue SCSI reset. */ + for (bus = 0; bus < ha->ports; bus++) { + qla1280_bus_reset(ha, bus); + } + /* + * qla1280_bus_reset() will do the marker + * dance - no reason to repeat here! + */ +#if 0 + /* Issue marker command. */ + ha->flags.reset_marker = 0; + for (bus = 0; bus < ha->ports; bus++) { + ha->bus_settings[bus]. + reset_marker = 0; + qla1280_marker(ha, bus, 0, 0, + MK_SYNC_ALL); + } +#endif + ha->flags.abort_isp_active = 0; + } + } + } - for (b = 0; b < ha->ports; b++) - for (t = 0; t < MAX_TARGETS; t++) - for (l = 0; l < MAX_LUNS; l++) - qla1280_abort_queue_single(ha,b,t,l,DID_RESET); + if (status) { + printk(KERN_WARNING + "qla1280: ISP error recovery failed, board disabled"); + qla1280_reset_adapter(ha); + dprintk(2, "qla1280_abort_isp: **** FAILED ****\n"); + } - LEAVE("qla1280_abort_queues"); + LEAVE("qla1280_abort_isp"); + return status; } + /* * qla1280_debounce_register * Debounce register. @@ -6151,28 +4824,27 @@ * Returns: * register value. */ -STATIC uint16_t -qla1280_debounce_register(volatile uint16_t *addr) +static u16 +qla1280_debounce_register(volatile u16 * addr) { - volatile uint16_t ret; - volatile uint16_t ret2; + volatile u16 ret; + volatile u16 ret2; - do - { - ret = RD_REG_WORD(addr); - ret2 = RD_REG_WORD(addr); - }while (ret != ret2); + ret = RD_REG_WORD(addr); + ret2 = RD_REG_WORD(addr); - return(ret); -} + if (ret == ret2) + return ret; + do { + cpu_relax(); + ret = RD_REG_WORD(addr); + ret2 = RD_REG_WORD(addr); + } while (ret != ret2); -/* - * Declarations for load module - */ -static Scsi_Host_Template driver_template = QLA1280_LINUX_TEMPLATE; + return ret; +} -#include "scsi_module.c" /************************************************************************ * qla1280_check_for_dead_scsi_bus * @@ -6181,638 +4853,309 @@ ************************************************************************/ #define SET_SXP_BANK 0x0100 #define SCSI_PHASE_INVALID 0x87FF -int qla1280_check_for_dead_scsi_bus(scsi_qla_host_t *ha, srb_t *sp) -{ - uint16_t config_reg, scsi_control; - device_reg_t *reg = ha->iobase; - uint32_t b; - Scsi_Cmnd *cp; - - /* - * If SCSI Bus is Dead because of bad termination, - * we will return a status of Selection timeout. - */ - - cp = sp->cmd; - b = SCSI_BUS_32(cp); - if (ha->bus_settings[b].scsi_bus_dead) - { - WRT_REG_WORD(®->host_cmd, HC_PAUSE_RISC); - config_reg = RD_REG_WORD(®->cfg_1); - WRT_REG_WORD(®->cfg_1,SET_SXP_BANK); - scsi_control = RD_REG_WORD(®->scsiControlPins); - WRT_REG_WORD(®->cfg_1,config_reg); - WRT_REG_WORD(®->host_cmd, HC_RELEASE_RISC); - - if (scsi_control == SCSI_PHASE_INVALID) - { - CMD_RESULT(cp) = DID_NO_CONNECT << 16; - CMD_HANDLE(cp) = (unsigned char *) 0; - /* ha->actthreads--; */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) - sti(); - (*(cp)->scsi_done)(cp); - cli(); -#else - (*(cp)->scsi_done)(cp); -#endif - return(TRUE); /* bus is dead */ - } - else - { - ha->bus_settings[b].scsi_bus_dead = FALSE; - ha->bus_settings[b].failed_reset_count= 0; - } - } - return(FALSE); /* bus is not dead */ -} - -STATIC uint8_t -qla12160_set_target_parameters(scsi_qla_host_t *ha, uint32_t b, uint32_t t, uint32_t l, nvram160_t *nv) +static int +qla1280_check_for_dead_scsi_bus(struct scsi_qla_host *ha, unsigned int bus) { - uint16_t mb[MAILBOX_REGISTER_COUNT]; + uint16_t config_reg, scsi_control; + struct device_reg *reg = ha->iobase; - /* Set Target Parameters. */ - mb[0] = MBC_SET_TARGET_PARAMETERS; - mb[1] = (uint16_t)(b ? t | BIT_7 :t); - mb[1] <<= 8; - mb[2] = nv->bus[b].target[t].parameter.c << 8; - mb[2] |= TP_AUTO_REQUEST_SENSE; - mb[2] &= ~TP_STOP_QUEUE; - mb[2] |= (nv->bus[b].target[t].flags.enable_ppr << 5); - mb[3] = nv->bus[b].target[t].flags.sync_offset << 8; - mb[3] |= nv->bus[b].target[t].sync_period; + if (ha->bus_settings[bus].scsi_bus_dead) { + WRT_REG_WORD(®->host_cmd, HC_PAUSE_RISC); + config_reg = RD_REG_WORD(®->cfg_1); + WRT_REG_WORD(®->cfg_1, SET_SXP_BANK); + scsi_control = RD_REG_WORD(®->scsiControlPins); + WRT_REG_WORD(®->cfg_1, config_reg); + WRT_REG_WORD(®->host_cmd, HC_RELEASE_RISC); - mb[6] = nv->bus[b].target[t].flags.ppr_options << 8; - mb[6] |= nv->bus[b].target[t].flags.ppr_bus_width; - return( qla1280_mailbox_command(ha, BIT_6|BIT_3|BIT_2|BIT_1|BIT_0, &mb[0]) ) ; + if (scsi_control == SCSI_PHASE_INVALID) { + ha->bus_settings[bus].scsi_bus_dead = 1; +#if 0 + CMD_RESULT(cp) = DID_NO_CONNECT << 16; + CMD_HANDLE(cp) = INVALID_HANDLE; + /* ha->actthreads--; */ + + (*(cp)->scsi_done)(cp); +#endif + return 1; /* bus is dead */ + } else { + ha->bus_settings[bus].scsi_bus_dead = 0; + ha->bus_settings[bus].failed_reset_count = 0; + } + } + return 0; /* bus is not dead */ } -STATIC void -qla12160_get_target_parameters(scsi_qla_host_t *ha, uint32_t b, uint32_t t, uint32_t l) +static void +qla12160_get_target_parameters(struct scsi_qla_host *ha, Scsi_Device *device) { - uint16_t mb[MAILBOX_REGISTER_COUNT]; + uint16_t mb[MAILBOX_REGISTER_COUNT]; + int bus, target, lun; - mb[0] = MBC_GET_TARGET_PARAMETERS; - mb[1] = (uint16_t)(b ? t | BIT_7 :t); - mb[1] <<= 8; - qla1280_mailbox_command(ha, BIT_6|BIT_3|BIT_2|BIT_1|BIT_0, &mb[0]); - if( mb[3] != 0 ) - printk(KERN_INFO "scsi(%d:%d:%d:%d): Synchronous tranfer at period %d, offset %d. \n", - (int)ha->host_no, b, t, l, (mb[3] &0xff), (mb[3] >> 8)); + bus = device->channel; + target = device->id; + lun = device->lun; - if ( (mb[2] & BIT_5) && ((mb[6] >> 8) & 0xff) >= 2 ) - printk(KERN_INFO "scsi(%d:%d:%d:%d): Dual Transition enabled.\n", - (int)ha->host_no, b, t, l); -} + mb[0] = MBC_GET_TARGET_PARAMETERS; + mb[1] = (uint16_t) (bus ? target | BIT_7 : target); + mb[1] <<= 8; + qla1280_mailbox_command(ha, BIT_6 | BIT_3 | BIT_2 | BIT_1 | BIT_0, + &mb[0]); -#ifdef QL_DEBUG_ROUTINES -/****************************************************************************/ -/* Driver Debug Functions. */ -/****************************************************************************/ + printk(KERN_INFO "scsi(%li:%d:%d:%d):", ha->host_no, bus, target, lun); -/* - * Get byte from I/O port - */ -STATIC uint8_t -qla1280_getbyte(uint8_t *port) -{ - uint8_t ret; + if (mb[3] != 0) { + printk(" Sync: period %d, offset %d", + (mb[3] & 0xff), (mb[3] >> 8)); + if (mb[2] & BIT_13) + printk(", Wide"); + if ((mb[2] & BIT_5) && ((mb[6] >> 8) & 0xff) >= 2) + printk(", DT"); + } else + printk(" Async"); -#if MEMORY_MAPPED_IO - ret = *port; -#else - ret = inb((int)port); -#endif - - if (ql_debug_print) - { - qla1280_print("qla1280_getbyte: address = "); - qla1280_output_number((uint32_t)port, 16); - qla1280_print(" data = 0x"); - qla1280_output_number((uint32_t)ret, 16); - qla1280_print("\n\r"); - } - - return(ret); + if (DEV_SIMPLE_TAGS(device)) + printk(", Tagged queuing: depth %d", device->queue_depth); + printk("\n"); } -/* - * Get word from I/O port - */ -STATIC uint16_t -qla1280_getword(uint16_t *port) -{ - uint16_t ret; -#if MEMORY_MAPPED_IO - ret = *port; -#else - ret = inw((int)port); -#endif - - if (ql_debug_print) - { - qla1280_print("qla1280_getword: address = "); - qla1280_output_number((uint32_t)port, 16); - qla1280_print(" data = 0x"); - qla1280_output_number((uint32_t)ret, 16); - qla1280_print("\n\r"); - } - - return(ret); -} - -/* - * Get double word from I/O port - */ -STATIC uint32_t -qla1280_getdword(uint32_t *port) +#if DEBUG_QLA1280 +static void +__qla1280_dump_buffer(char *b, int size) { - uint32_t ret; + int cnt; + u8 c; -#if MEMORY_MAPPED_IO - ret = *port; -#else - ret = inl((int)port); -#endif + printk(KERN_DEBUG " 0 1 2 3 4 5 6 7 8 9 Ah " + "Bh Ch Dh Eh Fh\n"); + printk(KERN_DEBUG "---------------------------------------------" + "------------------\n"); - if (ql_debug_print) - { - qla1280_print("qla1280_getdword: address = "); - qla1280_output_number((uint32_t)port, 16); - qla1280_print(" data = 0x"); - qla1280_output_number((uint32_t)ret, 16); - qla1280_print("\n\r"); - } + for (cnt = 0; cnt < size;) { + c = *b++; - return(ret); -} - -/* - * Send byte to I/O port - */ -STATIC void -qla1280_putbyte(uint8_t *port, uint8_t data) -{ -#if MEMORY_MAPPED_IO - *port = data; -#else - outb(data, (int)port); -#endif - - if (ql_debug_print) - { - qla1280_print("qla1280_putbyte: address = "); - qla1280_output_number((uint32_t)port, 16); - qla1280_print(" data = 0x"); - qla1280_output_number((uint32_t)data, 16); - qla1280_print("\n\r"); - } -} - -/* - * Send word to I/O port - */ -STATIC void -qla1280_putword(uint16_t *port, uint16_t data) -{ -#if MEMORY_MAPPED_IO - *port = data; -#else -#ifdef _LINUX_IOPORTS - outw(data, (int)port); -#else - outw((int)port, data); -#endif -#endif - - if (ql_debug_print) - { - qla1280_print("qla1280_putword: address = "); - qla1280_output_number((uint32_t)port, 16); - qla1280_print(" data = 0x"); - qla1280_output_number((uint32_t)data, 16); - qla1280_print("\n\r"); - } -} - -/* - * Send double word to I/O port - */ -STATIC void -qla1280_putdword(uint32_t *port, uint32_t data) -{ -#if MEMORY_MAPPED_IO - *port = data; -#else -#ifdef _LINUX_IOPORTS - outl(data,(int)port); -#else - outl((int)port, data); -#endif -#endif - - if (ql_debug_print) - { - qla1280_print("qla1280_putdword: address = "); - qla1280_output_number((uint32_t)port, 16); - qla1280_print(" data = 0x"); - qla1280_output_number((uint32_t)data, 16); - qla1280_print("\n\r"); - } -} - -/* - * Dummy function to prevent warnings for - * declared and unused debug functions - */ -void -qla1280_debug(void) -{ - qla1280_getbyte(0); - qla1280_getword(0); - qla1280_getdword(0); - qla1280_putbyte(0, 0); - qla1280_putword(0, 0); - qla1280_putdword(0, 0); + printk("0x%02x", c); + cnt++; + if (!(cnt % 16)) + printk("\n"); + else + printk(" "); + } + if (cnt % 16) + printk("\n"); } -/* - * Out character to COM2 port. - * PORT must be at standard address for COM2 = 0x2F8, - * or COM1 = 0x3F8 - */ -#define OUTB(addr,data) outb((data),(addr)) - -STATIC void -qla1280_putc(uint8_t c) -{ -#ifdef QL_DEBUG_CONSOLE - printk("%c", c); -#else - int com_addr = 0x2f8; - int hardware_flow_control = 1; - int software_flow_control = 0; - uint8_t data; - - /* Wait for transmitter holding and shift registers for empty. */ - do - { - data = inb(com_addr+5); - }while (!(data & BIT_6)); - - /* - * Set BAUD rate for COM2 to 19200 (0x6) - */ - - /* Select rate divisor. */ - OUTB(com_addr+3, 0x83); - - /* BAUD rate divisor LSB. */ - OUTB(com_addr, 0xc); /* 0xC = 9600 baud */ - - /* BAUD rate divisor MSB. */ - OUTB(com_addr+1, 0); - - /* Set No parity, 8 bits, 1 stop bit and - select interrupt enable register. */ - OUTB(com_addr+3, 3); - - /* Disable interrupts. */ - OUTB(com_addr+1, 0); - - /* Set data terminal ready and request to send */ - OUTB(com_addr+4,3); - - if (hardware_flow_control) - { - /* Wait for clear-to-send and data-set-ready */ - do - { - data = inb(com_addr+6) & (BIT_5 + BIT_4); - }while (data != (BIT_5 + BIT_4)); - } - else if (software_flow_control) - { - /* Test for data ready. */ - data = inb(com_addr+5); - if (data & BIT_0) - { - /* If XOFF */ - data = inb(com_addr); - if (data == '\023') - { - /* Wait for XON */ - do - { - /* Wait for char */ - do - { - data = inb(com_addr+5); - }while (!(data & BIT_0)); - data = inb(com_addr); - }while (data != '\021'); - } - } - } - - /* Output character. */ - OUTB(com_addr, c); -#endif -} - -/* - * Out NULL terminated string to COM port. - */ -STATIC void -qla1280_print(caddr_t s) -{ - if (ql_debug_print) - { -#ifdef QL_DEBUG_CONSOLE - printk("%s",s); -#else - /* Output string. */ - while (*s) - qla1280_putc(*s++); -#endif - } -} - -/* - * Output long number to COM port. - */ -STATIC void -qla1280_output_number(uint32_t n, uint8_t base) -{ - int8_t str[12]; - int8_t *s = &str[11]; - int8_t output = 0; - int8_t hex = FALSE; - - if (ql_debug_print) - { - if (base == 10 || base == 16) - { - if (base == 16 && n > 9) - hex = TRUE; - - *s = 0; - do - { - s--; - *s = n % base; - if (*s > 9) - *s += 55; - else - *s += '0'; - n /= base; - }while (n); - - for (; *s; s++) - { - if (*s != '0') - output = 1; - if (output) - qla1280_putc(*s); - } - if (!output) - qla1280_putc(*--s); - - if (hex) - qla1280_putc('h'); - } - } -} - -STATIC void -qla1280_dump_buffer(caddr_t b, uint32_t size) -{ - uint32_t cnt; - uint8_t c; - - if (ql_debug_print) - { - qla1280_print( - " 0 1 2 3 4 5 6 7 8 9 Ah Bh Ch Dh Eh Fh\n\r"); - qla1280_print( - "---------------------------------------------------------------\n\r"); - - for (cnt = 0; cnt < size; ) - { - c = *b++; - if (c < 16) - qla1280_putc(' '); - qla1280_output_number((uint32_t)c, 16); - cnt++; - if (!(cnt % 16)) - qla1280_print("\n\r"); - else if (c < 10) - qla1280_print(" "); - else - qla1280_putc(' '); - } - if (cnt % 16) - qla1280_print("\n\r"); - } -} /************************************************************************** * ql1280_print_scsi_cmd * **************************************************************************/ -void qla1280_print_scsi_cmd(Scsi_Cmnd *cmd) +static void +__qla1280_print_scsi_cmd(Scsi_Cmnd * cmd) { - scsi_qla_host_t *ha; - struct Scsi_Host *host = cmd->host; - srb_t *sp; - /* struct scatterlist *sg; */ - - int i; - ha = (scsi_qla_host_t *) host->hostdata; - - ql_debug_print = 1; - sp = (srb_t *) CMD_SP(cmd); - sprintf(debug_buff,"SCSI Command @= 0x%p, Handle=0x%p\n\r", cmd, CMD_HANDLE(cmd)); - qla1280_print(debug_buff); - sprintf(debug_buff," chan=%d, target = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n\r", - cmd->channel, cmd->target, cmd->lun, cmd->cmd_len); - qla1280_print(debug_buff); - qla1280_print(" CDB = "); - for (i = 0; i < cmd->cmd_len; i++) - { - sprintf(debug_buff,"0x%02x ", cmd->cmnd[i]); - qla1280_print(debug_buff); - } - sprintf(debug_buff," seg_cnt =%d\n\r",cmd->use_sg); - qla1280_print(debug_buff); - sprintf(debug_buff," request buffer=0x%p, request buffer len=0x%x\n\r",cmd->request_buffer,cmd->request_bufflen); - qla1280_print(debug_buff); - /* if( cmd->use_sg ) - { - sg = (struct scatterlist *) cmd->request_buffer; - qla1280_print(" SG buffer: \n\r"); - qla1280_dump_buffer((caddr_t)sg, (cmd->use_sg*sizeof(struct scatterlist)) ); - } */ - sprintf(debug_buff," tag=%d, flags=0x%x, transfersize=0x%x \n\r", - cmd->tag, cmd->flags,cmd->transfersize ); - qla1280_print(debug_buff); - sprintf(debug_buff," Pid=%d, SP=0x%p\n\r", (int)cmd->pid, CMD_SP(cmd)); - qla1280_print(debug_buff); - sprintf(debug_buff," r_start=0x%lx, u_start=0x%lx\n\r",sp->r_start,sp->u_start); - qla1280_print(debug_buff); - sprintf(debug_buff," underflow size = 0x%x, direction=0x%x, req.cmd=0x%x \n\r", cmd->underflow, sp->dir,cmd->request.cmd); - qla1280_print(debug_buff); + struct scsi_qla_host *ha; + struct Scsi_Host *host = CMD_HOST(cmd); + struct srb *sp; + /* struct scatterlist *sg; */ + + int i; + ha = (struct scsi_qla_host *)host->hostdata; + + sp = (struct srb *)CMD_SP(cmd); + printk("SCSI Command @= 0x%p, Handle=0x%p\n", cmd, CMD_HANDLE(cmd)); + printk(" chan=%d, target = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n", + SCSI_BUS_32(cmd), SCSI_TCN_32(cmd), SCSI_LUN_32(cmd), + CMD_CDBLEN(cmd)); + printk(" CDB = "); + for (i = 0; i < cmd->cmd_len; i++) { + printk("0x%02x ", cmd->cmnd[i]); + } + printk(" seg_cnt =%d\n", cmd->use_sg); + printk(" request buffer=0x%p, request buffer len=0x%x\n", + cmd->request_buffer, cmd->request_bufflen); + /* if (cmd->use_sg) + { + sg = (struct scatterlist *) cmd->request_buffer; + printk(" SG buffer: \n"); + qla1280_dump_buffer(1, (char *)sg, (cmd->use_sg*sizeof(struct scatterlist))); + } */ + printk(" tag=%d, flags=0x%x, transfersize=0x%x \n", + cmd->tag, cmd->flags, cmd->transfersize); + printk(" Pid=%li, SP=0x%p\n", cmd->pid, CMD_SP(cmd)); + printk(" underflow size = 0x%x, direction=0x%x\n", + cmd->underflow, sp->dir); } + /************************************************************************** * ql1280_dump_device * **************************************************************************/ -void -ql1280_dump_device(scsi_qla_host_t *ha) +static void +ql1280_dump_device(struct scsi_qla_host *ha) { - Scsi_Cmnd *cp; - srb_t *sp; - int i; - qla1280_print("Outstanding Commands on controller:\n\r"); - for ( i=0; i < MAX_OUTSTANDING_COMMANDS; i++ ) - { - if( (sp = ha->outstanding_cmds[i]) == NULL ) - continue; - if( (cp = sp->cmd) == NULL ) - continue; - qla1280_print_scsi_cmd(cp); - } + Scsi_Cmnd *cp; + struct srb *sp; + int i; -} -#endif + printk(KERN_DEBUG "Outstanding Commands on controller:\n"); -#ifdef QLA1280_UNUSED -/************************************************************************** - * ql1280_dump_regs - * - **************************************************************************/ -static void qla1280_dump_regs(struct Scsi_Host *host) -{ - printk("Mailbox registers:\n"); - printk("qla1280 : mbox 0 0x%04x \n", inw(host->io_port + 0x70)); - printk("qla1280 : mbox 1 0x%04x \n", inw(host->io_port + 0x72)); - printk("qla1280 : mbox 2 0x%04x \n", inw(host->io_port + 0x74)); - printk("qla1280 : mbox 3 0x%04x \n", inw(host->io_port + 0x76)); - printk("qla1280 : mbox 4 0x%04x \n", inw(host->io_port + 0x78)); - printk("qla1280 : mbox 5 0x%04x \n", inw(host->io_port + 0x7a)); + for (i = 0; i < MAX_OUTSTANDING_COMMANDS; i++) { + if ((sp = ha->outstanding_cmds[i]) == NULL) + continue; + if ((cp = sp->cmd) == NULL) + continue; + qla1280_print_scsi_cmd(1, cp); + } } #endif +enum tokens { + TOKEN_NVRAM, + TOKEN_SYNC, + TOKEN_WIDE, + TOKEN_PPR, + TOKEN_VERBOSE, + TOKEN_DEBUG, +}; + +struct setup_tokens { + char *token; + int val; +}; + +static struct setup_tokens setup_token[] __initdata = +{ + { "nvram", TOKEN_NVRAM }, + { "sync", TOKEN_SYNC }, + { "wide", TOKEN_WIDE }, + { "ppr", TOKEN_PPR }, + { "verbose", TOKEN_VERBOSE }, + { "debug", TOKEN_DEBUG }, +}; + -#if STOP_ON_ERROR /************************************************************************** - * ql1280_panic + * qla1280_setup * + * Handle boot parameters. This really needs to be changed so one + * can specify per adapter parameters. **************************************************************************/ -static void qla1280_panic(char *cp, struct Scsi_Host *host) +static int __init +qla1280_setup(char *s) { - scsi_qla_host_t *ha; - long *fp; + char *cp, *ptr; + unsigned long val; + int toke; + + cp = s; + + while (cp && (ptr = strchr(cp, ':'))) { + ptr++; + if (!strcmp(ptr, "yes")) { + val = 0x10000; + ptr += 3; + } else if (!strcmp(ptr, "no")) { + val = 0; + ptr += 2; + } else + val = simple_strtoul(ptr, &ptr, 0); + + switch ((toke = qla1280_get_token(cp))) { + case TOKEN_NVRAM: + if (!val) + driver_setup.no_nvram = 1; + break; + case TOKEN_SYNC: + if (!val) + driver_setup.no_sync = 1; + else if (val != 0x10000) + driver_setup.sync_mask = val; + break; + case TOKEN_WIDE: + if (!val) + driver_setup.no_wide = 1; + else if (val != 0x10000) + driver_setup.wide_mask = val; + break; + case TOKEN_PPR: + if (!val) + driver_setup.no_ppr = 1; + else if (val != 0x10000) + driver_setup.ppr_mask = val; + break; + case TOKEN_VERBOSE: + qla1280_verbose = val; + break; + default: + printk(KERN_INFO "qla1280: unknown boot option %s\n", + cp); + } - ha = (scsi_qla_host_t *) host->hostdata; - printk("qla1280 - PANIC: %s\n",cp); - printk("Current time=0x%lx\n", jiffies); - printk("Number of pending commands =0x%lx\n", ha->actthreads); - printk("Number of SCSI queued commands =0x%lx\n", ha->qthreads); - printk("Number of free entries = (%d)\n",ha->req_q_cnt); - printk("Request Queue @ 0x%lx, Response Queue @ 0x%lx\n", - ha->request_dma, - ha->response_dma); - printk("Request In Ptr %d\n", ha->req_ring_index ); - fp = (long *) &ha->flags; - printk("HA flags =0x%lx\n", *fp); - DEBUG2(ql_debug_print = 1;) - /* DEBUG2(ql1280_dump_device((scsi_qla_host_t *) host->hostdata)); */ -#ifdef QLA1280_UNUSED - qla1280_dump_regs(host); -#endif - sti(); - panic("Ooops"); - /* cli(); - for(;;) - { - barrier(); - sti(); - } - */ + cp = strchr(ptr, ';'); + if (cp) + cp++; + else { + break; + } + } + return 1; } -#endif -#ifdef QLA1280_UNUSED -static void qla1280_set_flags(char * s) + +static int +qla1280_get_token(char *str) { + char *sep; + long ret = -1; + int i, len; + + len = sizeof(setup_token)/sizeof(struct setup_tokens); + + sep = strchr(str, ':'); + + if (sep) { + for (i = 0; i < len; i++){ + + if (!strncmp(setup_token[i].token, str, (sep - str))) { + ret = setup_token[i].val; + break; + } + } + } + + return ret; } + + +static Scsi_Host_Template driver_template = { + .proc_info = qla1280_proc_info, + .name = "Qlogic ISP 1280/12160", + .detect = qla1280_detect, + .release = qla1280_release, + .info = qla1280_info, + .queuecommand = qla1280_queuecommand, +#if LINUX_VERSION_CODE >= 0x020545 + .slave_configure = qla1280_slave_configure, +#endif + .eh_abort_handler = qla1280_eh_abort, + .eh_device_reset_handler= qla1280_eh_device_reset, + .eh_bus_reset_handler = qla1280_eh_bus_reset, + .eh_host_reset_handler = qla1280_eh_adapter_reset, + .bios_param = qla1280_biosparam, + .can_queue = 255, + .this_id = -1, + .sg_tablesize = SG_ALL, + .cmd_per_lun = 3, + .use_clustering = ENABLE_CLUSTERING, +#if LINUX_VERSION_CODE < 0x020545 + .use_new_eh_code = 1, #endif +}; -/************************************************************************** - * qla1280_setup - * - * Handle Linux boot parameters. This routine allows for assigning a value - * to a parameter with a ':' between the parameter and the value. - * ie. qla1280=max_reqs:0x0A,verbose - **************************************************************************/ -void -qla1280_setup(char *s, int *dummy) -{ - char *end, *str, *cp; +#include "scsi_module.c" -#ifdef QLA1280_UNUSED - static struct - { - const char *name; - int siz; - void (*func)(); - int arg; - } options[] = - { - { "dump_regs", 9, &qla1280_dump_regs, 0 - }, - { "verbose", 7, &qla1280_set_flags, 0x1 - }, - { "", 0, NULL, 0 - } - }; -#endif - - printk("scsi: Processing Option str = %s\n", s); - end = strchr(s, '\0'); - /* locate command */ - str = s; - for( cp = s; *cp && cp != end; cp++ ) - { - cp = qla1280_get_token(cp, str); - printk("scsi: token str = %s\n", str); - /* if found execute routine */ - - } - -} - -static char *qla1280_get_token(char *cmdline, char *str ) -{ - register char *cp = cmdline; - - /* skip preceeding spaces */ - while(strchr(cp,' ')) - ++cp; - /* symbol starts here */ - str = cp; - /* skip char if not a space or : */ - while (*cp && !( strchr(cp,' ') || strchr(cp,':')) ) - cp++; - *cp = '\0'; - return( cp ); -} -MODULE_LICENSE("GPL"); /* * Overrides for Emacs so that we almost follow Linus's tabbing style. @@ -6821,15 +5164,7 @@ * of the file. * --------------------------------------------------------------------------- * Local variables: - * c-indent-level: 2 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -2 - * c-argdecl-indent: 2 - * c-label-offset: -2 - * c-continued-statement-offset: 2 - * c-continued-brace-offset: 0 - * indent-tabs-mode: nil + * c-basic-offset: 8 * tab-width: 8 * End: */ - Index: drivers/scsi/qla1280.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/qla1280.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/qla1280.h 22 Jul 2004 19:50:06 -0000 1.1 +++ drivers/scsi/qla1280.h 4 Aug 2004 01:29:36 -0000 1.2 @@ -1,1447 +1,963 @@ -/************************************************************************* - * QLOGIC LINUX SOFTWARE - * - * QLogic ISP1x80/1x160 device driver for Linux 2.3.x (redhat 6.x). - * - * COPYRIGHT (C) 1996-2000 QLOGIC CORPORATION - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the Qlogic's Linux Software License. - * - * This program is WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistribution's or 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. - * - *****************************************************************************/ - -/************************************************************************************* - QLOGIC CORPORATION SOFTWARE - "GNU" GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION - AND MODIFICATION - -This GNU General Public License ("License") applies solely to QLogic Linux -Software ("Software") and may be distributed under the terms of this License. - -1. You may copy and distribute verbatim copies of the Software's source code as -you receive it, in any medium, provided that you conspicuously and appropriately -publish on each copy an appropriate copyright notice and disclaimer of warranty; -keep intact all the notices that refer to this License and to the absence of any -warranty; and give any other recipients of the Software a copy of this License along -with the Software. - -You may charge a fee for the physical act of transferring a copy, and you may at your -option offer warranty protection in exchange for a fee. - -2. You may modify your copy or copies of the Software or any portion of it, thus forming -a work based on the Software, and copy and distribute such modifications or work under -the terms of Section 1 above, provided that you also meet all of these conditions: - -* a) You must cause the modified files to carry prominent notices stating that you -changed the files and the date of any change. - -* b) You must cause any work that you distribute or publish that in whole or in part -contains or is derived from the Software or any part thereof, to be licensed as a -whole at no charge to all third parties under the terms of this License. - -* c) If the modified Software normally reads commands interactively when run, you -must cause it, when started running for such interactive use in the most ordinary way, -to print or display an announcement including an appropriate copyright notice and a -notice that there is no warranty (or else, saying that you provide a warranty) and that -users may redistribute the Software under these conditions, and telling the user how to -view a copy of this License. (Exception:if the Software itself is interactive but does -not normally print such an announcement, your work based on the Software is not required -to print an announcement.) - -These requirements apply to the modified work as a whole. If identifiable sections of -that work are not derived from the Software, and can be reasonably considered independent -and separate works in themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you distribute the same -sections as part of a whole which is a work based on the Software, the distribution of the -whole must be on the terms of this License, whose permissions for other licensees extend -to the entire whole, and thus to each and every part regardless of who wrote it. - -3. You may copy and distribute the Software (or a work based on it, under Section 2) in -object code or executable form under the terms of Sections 1 and 2 above provided that -you also do one of the following: - -* a) Accompany it with the complete corresponding machine-readable source code, which must -be distributed under the terms of Sections 1 and 2 above on a medium customarily used for -software interchange; or, - -* b) Accompany it with a written offer, valid for at least three years, to give any third -party, for a charge no more than your cost of physically performing source distribution, -a complete machine-readable copy of the corresponding source code, to be distributed under -the terms of Sections 1 and 2 above on a medium customarily used for software interchange; -or, - -* c) Accompany it with the information you received as to the offer to distribute -corresponding source code. (This alternative is allowed only for noncommercial distribution -and only if you received the Software in object code or executable form with such an offer, -in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for making modifications -to it. For an executable work, complete source code means all the source code for all -modules it contains, plus any associated interface definition files, plus the scripts used -to control compilation and installation of the executable. - -If distribution of executable or object code is made by offering access to copy from a -designated place, then offering equivalent access to copy the source code from the same -place counts as distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - -4. You may not copy, modify, sublicense, or distribute the Software except as expressly -provided under this License. Any attempt otherwise to copy, modify, sublicense or -distribute the Software is void, and will automatically terminate your rights under this -License. However, parties who have received copies, or rights, from you under this License -will not have their licenses terminated so long as such parties remain in full compliance. - -5. This license grants you world wide, royalty free non-exclusive rights to modify or -distribute the Software or its derivative works. These actions are prohibited by law -if you do not accept this License. Therefore, by modifying or distributing the Software -(or any work based on the Software), you indicate your acceptance of this License to do -so, and all its terms and conditions for copying, distributing or modifying the Software -or works based on it. - -6. Each time you redistribute the Software (or any work based on the Software), the -recipient automatically receives a license from the original licensor to copy, distribute -or modify the Software subject to these terms and conditions. You may not impose any -further restrictions on the recipients' exercise of the rights granted herein. You are -not responsible for enforcing compliance by third parties to this License. - -7. If, as a consequence of a court judgment or allegation of patent infringement or for -any other reason (not limited to patent issues), conditions are imposed on you -(whether by court order, agreement or otherwise) that contradict the conditions of this -License, they do not excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this License -and any other pertinent obligations, then as a consequence you may not distribute the -Software at all. - -If any portion of this section is held invalid or unenforceable under any particular -circumstance, the balance of the section is intended to apply and the section as a whole -is intended to apply in other circumstances. -NO WARRANTY - -11. THE SOFTWARE IS PROVIDED WITHOUT A WARRANTY OF ANY KIND. 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. - -12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE SOFTWARE AS PERMITTED ABOVE, BE LIABLE TO YOU FOR -DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL -DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING -BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR -LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO -OPERATE WITH ANY OTHER SOFTWARES), EVEN IF SUCH HOLDER OR OTHER PARTY HAS -BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -END OF TERMS AND CONDITIONS - -*************************************************************************************/ - - -#ifndef _IO_HBA_QLA1280_H /* wrapper symbol for kernel use */ -#define _IO_HBA_QLA1280_H /* subject to change without notice */ +/****************************************************************************** +* QLOGIC LINUX SOFTWARE +* +* QLogic ISP1280 (Ultra2) /12160 (Ultra3) SCSI driver +* Copyright (C) 2000 Qlogic Corporation +* (www.qlogic.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. +* +******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif +#ifndef _IO_HBA_QLA1280_H /* wrapper symbol for kernel use */ +#define _IO_HBA_QLA1280_H /* subject to change without notice */ -#include - -/* - * Enable define statement to ignore Data Underrun Errors, - * remove define statement to enable detection. - */ -/* #define DATA_UNDERRUN_ERROR_DISABLE */ - -/* - * Driver debug definitions. - */ -/* #define QL_DEBUG_LEVEL_1 */ /* Output register accesses to COM2. */ -/* #define QL_DEBUG_LEVEL_2 */ /* Output error msgs to COM2. */ -/* #define QL_DEBUG_LEVEL_3 */ /* Output function trace msgs to COM2. */ -/* #define QL_DEBUG_LEVEL_4 */ /* Output NVRAM trace msgs to COM2. */ -/* #define QL_DEBUG_LEVEL_5 */ /* Output ring trace msgs to COM2. */ -/* #define QL_DEBUG_LEVEL_6 */ /* Output WATCHDOG timer trace to COM2. */ -/* #define QL_DEBUG_LEVEL_7 */ /* Output RISC load trace msgs to COM2. */ - -#define QL_DEBUG_CONSOLE /* Output to console instead of COM2. */ - -#ifndef TRUE -# define TRUE 1 -#endif -#ifndef FALSE -# define FALSE 0 -#endif - - -#ifndef KERNEL_VERSION -# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) -#endif - -#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 -#endif - - -/* - * Locking - */ -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0) -# include -# include -# define cpuid smp_processor_id() -# if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) -# define DRIVER_LOCK_INIT \ - spin_lock_init(&ha->spin_lock); -# define DRIVER_LOCK \ - if(!ha->cpu_lock_count[cpuid]) { \ - spin_lock_irqsave(&ha->spin_lock, cpu_flags); \ - ha->cpu_lock_count[cpuid]++; \ - } else { \ - ha->cpu_lock_count[cpuid]++; \ - } -# define DRIVER_UNLOCK \ - if(--ha->cpu_lock_count[cpuid] == 0) \ - spin_unlock_irqrestore(&ha->spin_lock, cpu_flags); -# else -# define DRIVER_LOCK_INIT -# define DRIVER_LOCK -# define DRIVER_UNLOCK -# endif -#else -# define cpuid 0 -# define DRIVER_LOCK_INIT -# define DRIVER_LOCK \ - save_flags(cpu_flags); \ - cli(); -# define DRIVER_UNLOCK \ - restore_flags(cpu_flags); -# define le32_to_cpu(x) (x) -# define cpu_to_le32(x) (x) -#endif +#ifndef HOSTS_C /* included in hosts.c */ /* * Data bit definitions. */ -#define BIT_0 0x1 -#define BIT_1 0x2 -#define BIT_2 0x4 -#define BIT_3 0x8 -#define BIT_4 0x10 -#define BIT_5 0x20 -#define BIT_6 0x40 -#define BIT_7 0x80 -#define BIT_8 0x100 -#define BIT_9 0x200 -#define BIT_10 0x400 -#define BIT_11 0x800 -#define BIT_12 0x1000 -#define BIT_13 0x2000 -#define BIT_14 0x4000 -#define BIT_15 0x8000 -#define BIT_16 0x10000 -#define BIT_17 0x20000 -#define BIT_18 0x40000 -#define BIT_19 0x80000 -#define BIT_20 0x100000 -#define BIT_21 0x200000 -#define BIT_22 0x400000 -#define BIT_23 0x800000 -#define BIT_24 0x1000000 -#define BIT_25 0x2000000 -#define BIT_26 0x4000000 -#define BIT_27 0x8000000 -#define BIT_28 0x10000000 -#define BIT_29 0x20000000 -#define BIT_30 0x40000000 -#define BIT_31 0x80000000 - -/* - * Common size type definitions - */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned long uint32_t; -typedef char int8_t; -typedef short int16_t; -typedef long int32_t; -#endif - -/* - * Local Macro Definitions. - */ -#if defined(QL_DEBUG_LEVEL_1) || defined(QL_DEBUG_LEVEL_2) || \ - defined(QL_DEBUG_LEVEL_3) || defined(QL_DEBUG_LEVEL_4) || \ - defined(QL_DEBUG_LEVEL_5) || defined(QL_DEBUG_LEVEL_6) || \ - defined(QL_DEBUG_LEVEL_7) - #define QL_DEBUG_ROUTINES -#endif - -/* - * I/O port macros -*/ -#define LINUX_IOPORTS /* Linux in/out routines are define*/ - /* differently from other OSs */ -/* #define MEMORY_MAPPED_IO */ /* Enable memory mapped I/O */ -#undef MEMORY_MAPPED_IO /* Disable memory mapped I/O */ - -#ifdef QL_DEBUG_LEVEL_1 -#define RD_REG_BYTE(addr) qla1280_getbyte((uint8_t *)addr) -#define RD_REG_WORD(addr) qla1280_getword((uint16_t *)addr) -#define RD_REG_DWORD(addr) qla1280_getdword((uint32_t *)addr) -#define WRT_REG_BYTE(addr, data) qla1280_putbyte((uint8_t *)addr, data) -#define WRT_REG_WORD(addr, data) qla1280_putword((uint16_t *)addr, data) -#define WRT_REG_DWORD(addr, data) qla1280_putdword((uint32_t *)addr, data) -#else /* QL_DEBUG_LEVEL_1 */ -#ifdef MEMORY_MAPPED_IO - #define RD_REG_BYTE(addr) readb((unsigned long) (addr) - #define RD_REG_WORD(addr) readw((unsigned long) (addr) - #define RD_REG_DWORD(addr) readl((unsigned long) (addr) - #define WRT_REG_BYTE(addr, data) writeb((data), (unsigned long) (addr)) - #define WRT_REG_WORD(addr, data) writew((data), (unsigned long) (addr)) - #define WRT_REG_DWORD(addr, data) writel((data), (unsigned long) (addr)) -#else /* MEMORY_MAPPED_IO */ -#define RD_REG_BYTE(addr) (inb((unsigned long)addr)) -#define RD_REG_WORD(addr) (inw((unsigned long)addr)) -#define RD_REG_DWORD(addr) (inl((unsigned long)addr)) -#ifdef LINUX_IOPORTS -/* Parameters are reversed in Linux */ -#define WRT_REG_BYTE(addr, data) (outb(data,(unsigned long)addr)) -#define WRT_REG_WORD(addr, data) (outw(data,(unsigned long)addr)) -#define WRT_REG_DWORD(addr, data) (outl(data,(unsigned long)addr)) -#else -#define WRT_REG_BYTE(addr, data) (outb((unsigned long)addr, data)) -#define WRT_REG_WORD(addr, data) (outw((unsigned long)addr, data)) -#define WRT_REG_DWORD(addr, data) (outl((unsigned long)addr, data)) -#endif -#endif /* MEMORY_MAPPED_IO */ -#endif /* QL_DEBUG_LEVEL_1 */ +#define BIT_0 0x1 +#define BIT_1 0x2 +#define BIT_2 0x4 +#define BIT_3 0x8 +#define BIT_4 0x10 +#define BIT_5 0x20 +#define BIT_6 0x40 +#define BIT_7 0x80 +#define BIT_8 0x100 +#define BIT_9 0x200 +#define BIT_10 0x400 +#define BIT_11 0x800 +#define BIT_12 0x1000 +#define BIT_13 0x2000 +#define BIT_14 0x4000 +#define BIT_15 0x8000 +#define BIT_16 0x10000 +#define BIT_17 0x20000 +#define BIT_18 0x40000 +#define BIT_19 0x80000 +#define BIT_20 0x100000 +#define BIT_21 0x200000 +#define BIT_22 0x400000 +#define BIT_23 0x800000 +#define BIT_24 0x1000000 +#define BIT_25 0x2000000 +#define BIT_26 0x4000000 +#define BIT_27 0x8000000 +#define BIT_28 0x10000000 +#define BIT_29 0x20000000 +#define BIT_30 0x40000000 +#define BIT_31 0x80000000 + +#if MEMORY_MAPPED_IO +#define RD_REG_WORD(addr) readw(addr) +#define WRT_REG_WORD(addr, data) writew(data, addr) +#else /* MEMORY_MAPPED_IO */ +#define RD_REG_WORD(addr) inw((unsigned long)addr) +#define WRT_REG_WORD(addr, data) outw(data, (unsigned long)addr) +#endif /* MEMORY_MAPPED_IO */ /* * Host adapter default definitions. */ -#define MAX_BUSES 2 /* 2 */ -#define MAX_B_BITS 1 +#define MAX_BUSES 2 /* 2 */ +#define MAX_B_BITS 1 -#define MAX_TARGETS 16 /* 16 */ -#define MAX_T_BITS 4 /* 4 */ +#define MAX_TARGETS 16 /* 16 */ +#define MAX_T_BITS 4 /* 4 */ -#define MAX_LUNS 8 /* 32 */ -#define MAX_L_BITS 3 /* 5 */ +#define MAX_LUNS 8 /* 32 */ +#define MAX_L_BITS 3 /* 5 */ /* * Watchdog time quantum */ -#define QLA1280_WDG_TIME_QUANTUM 5 /* In seconds */ +#define QLA1280_WDG_TIME_QUANTUM 5 /* In seconds */ /* Command retry count (0-65535) */ -#define COMMAND_RETRY_COUNT 255 +#define COMMAND_RETRY_COUNT 255 -/* Maximum outstanding commands in ISP queues (1-65535) */ -#define MAX_OUTSTANDING_COMMANDS 512 +/* Maximum outstanding commands in ISP queues */ +#define MAX_OUTSTANDING_COMMANDS 512 +#define INVALID_HANDLE (MAX_OUTSTANDING_COMMANDS + 2) /* ISP request and response entry counts (37-65535) */ -#define REQUEST_ENTRY_CNT 256 /* Number of request entries. */ -#define RESPONSE_ENTRY_CNT 16 /* Number of response entries. */ - -/* Maximum equipage per controller */ -#define MAX_EQ (MAX_BUSES * MAX_TARGETS * MAX_LUNS) +#define REQUEST_ENTRY_CNT 256 /* Number of request entries. */ +#define RESPONSE_ENTRY_CNT 16 /* Number of response entries. */ /* Number of segments 1 - 65535 */ -#define SG_SEGMENTS 32 /* Cmd entry + 6 continuations */ - +#define SG_SEGMENTS 32 /* Cmd entry + 6 continuations */ /* - * SCSI Request Block structure + * SCSI Request Block structure (sp) that is placed + * on cmd->SCp location of every I/O */ -typedef struct srb -{ - Scsi_Cmnd *cmd; /* (4) SCSI command block */ - struct srb *s_next; /* (4) Next block on LU queue */ - struct srb *s_prev; /* (4) Previous block on LU queue */ - uint8_t flags; /* (1) Status flags. */ - uint8_t dir; /* direction of transfer */ - uint8_t unused[2]; - u_long r_start; /* jiffies at start of request */ - u_long u_start; /* jiffies when sent to F/W */ -}srb_t; +struct srb { + Scsi_Cmnd *cmd; /* (4/8) SCSI command block */ + struct srb *s_next; /* (4/8) Next block on LU queue */ + struct srb *s_prev; /* (4/8) Previous block on LU queue */ + uint8_t flags; /* (1) Status flags. */ + uint8_t dir; /* direction of transfer */ + /* + * This should be moved around to save space. + */ + dma_addr_t saved_dma_handle; /* for unmap of single transfers */ + /* NOTE: the sp->cmd will be NULL when this completion is + * called, so you should know the scsi_cmnd when using this */ + struct completion *wait; +}; /* * SRB flag definitions */ -#define SRB_TIMEOUT BIT_0 /* Command timed out */ -#define SRB_SENT BIT_1 /* Command sent to ISP */ -#define SRB_ABORT_PENDING BIT_2 /* Command abort sent to device */ -#define SRB_ABORTED BIT_3 /* Command aborted command already */ - +#define SRB_TIMEOUT BIT_0 /* Command timed out */ +#define SRB_SENT BIT_1 /* Command sent to ISP */ +#define SRB_ABORT_PENDING BIT_2 /* Command abort sent to device */ +#define SRB_ABORTED BIT_3 /* Command aborted command already */ /* * Logical Unit Queue structure */ -typedef struct scsi_lu -{ - srb_t *q_first; /* First block on LU queue */ - srb_t *q_last; /* Last block on LU queue */ - uint8_t q_flag; /* LU queue state flags */ - uint8_t q_sense[16]; /* sense data */ - u_long io_cnt; /* total xfer count */ - u_long resp_time; /* total response time (start - finish) */ - u_long act_time; /* total actived time (minus queuing time) */ - u_long w_cnt; /* total writes */ - u_long r_cnt; /* total reads */ - uint16_t q_outcnt; /* Pending jobs for this LU */ -#if QL1280_TARGET_MODE_SUPPORT - void (*q_func)(); /* Target driver event handler */ - int32_t q_param; /* Target driver event param */ - uint8_t q_lock; /* Device Queue Lock */ -#endif -}scsi_lu_t; - -/* - * Logical Unit flags - */ -#define QLA1280_QBUSY BIT_0 -#define QLA1280_QWAIT BIT_1 -#define QLA1280_QSUSP BIT_2 -#define QLA1280_QSENSE BIT_3 /* Sense data cache valid */ -#define QLA1280_QRESET BIT_4 -#define QLA1280_QHBA BIT_5 -#define QLA1280_BSUSP BIT_6 /* controller is suspended */ -#define QLA1280_BREM BIT_7 /* controller is removed */ - -/* - * ISP PCI Configuration Register Set - */ -typedef volatile struct -{ - uint16_t vendor_id; /* 0x0 */ - uint16_t device_id; /* 0x2 */ - uint16_t command; /* 0x4 */ - uint16_t status; /* 0x6 */ - uint8_t revision_id; /* 0x8 */ - uint8_t programming_interface; /* 0x9 */ - uint8_t sub_class; /* 0xa */ - uint8_t base_class; /* 0xb */ - uint8_t cache_line; /* 0xc */ - uint8_t latency_timer; /* 0xd */ - uint8_t header_type; /* 0xe */ - uint8_t bist; /* 0xf */ - uint32_t base_port; /* 0x10 */ - uint32_t mem_base_addr; /* 0x14 */ - uint32_t base_addr[4]; /* 0x18-0x24 */ - uint32_t reserved_1[2]; /* 0x28-0x2c */ - uint16_t expansion_rom; /* 0x30 */ - uint32_t reserved_2[2]; /* 0x34-0x38 */ - uint8_t interrupt_line; /* 0x3c */ - uint8_t interrupt_pin; /* 0x3d */ - uint8_t min_grant; /* 0x3e */ - uint8_t max_latency; /* 0x3f */ -}config_reg_t; +struct scsi_lu { + struct srb *q_first; /* First block on LU queue */ + struct srb *q_last; /* Last block on LU queue */ + uint8_t q_flag; /* LU queue state flags */ + uint8_t q_sense[16]; /* sense data */ + unsigned long io_cnt; /* total xfer count */ + unsigned long resp_time;/* total response time (start - finish) */ + unsigned long act_time; /* total actived time (minus queuing time) */ + unsigned long w_cnt; /* total writes */ + unsigned long r_cnt; /* total reads */ + uint16_t q_outcnt; /* Pending jobs for this LU */ +}; + +/* + * Logical Unit flags + */ +#define QLA1280_QBUSY BIT_0 +#define QLA1280_QWAIT BIT_1 +#define QLA1280_QSUSP BIT_2 +#define QLA1280_QSENSE BIT_3 /* Sense data cache valid */ +#define QLA1280_QRESET BIT_4 +#define QLA1280_QHBA BIT_5 +#define QLA1280_BSUSP BIT_6 /* controller is suspended */ +#define QLA1280_BREM BIT_7 /* controller is removed */ /* * ISP I/O Register Set structure definitions. */ -typedef volatile struct -{ - uint16_t id_l; /* ID low */ - uint16_t id_h; /* ID high */ - uint16_t cfg_0; /* Configuration 0 */ - uint16_t cfg_1; /* Configuration 1 */ - uint16_t ictrl; /* Interface control */ - #define ISP_RESET BIT_0 /* ISP soft reset */ - #define ISP_EN_INT BIT_1 /* ISP enable interrupts. */ - #define ISP_EN_RISC BIT_2 /* ISP enable RISC interrupts. */ - uint16_t istatus; /* Interface status */ - #define PCI_64BIT_SLOT BIT_14 /* PCI 64-bit slot indicator. */ - #define RISC_INT BIT_2 /* RISC interrupt */ - #define PCI_INT BIT_1 /* PCI interrupt */ - uint16_t semaphore; /* Semaphore */ - uint16_t nvram; /* NVRAM register. */ - #define NV_DESELECT 0 - #define NV_CLOCK BIT_0 - #define NV_SELECT BIT_1 - #define NV_DATA_OUT BIT_2 - #define NV_DATA_IN BIT_3 - uint16_t flash_data; /* Flash BIOS data */ - uint16_t flash_address; /* Flash BIOS address */ - - uint16_t unused_1[0x2e]; /* 0x14-0x6f Gap */ - - uint16_t mailbox0; /* Mailbox 0 */ - uint16_t mailbox1; /* Mailbox 1 */ - uint16_t mailbox2; /* Mailbox 2 */ - uint16_t mailbox3; /* Mailbox 3 */ - uint16_t mailbox4; /* Mailbox 4 */ - uint16_t mailbox5; /* Mailbox 5 */ - uint16_t mailbox6; /* Mailbox 6 */ - uint16_t mailbox7; /* Mailbox 7 */ - - uint16_t unused_2[0x20]; /* 0x80-0xbf Gap */ - - uint16_t host_cmd; /* Host command and control */ - #define HOST_INT BIT_7 /* host interrupt bit */ - #define BIOS_ENABLE BIT_0 - - uint16_t unused_6[0x5]; /* 0xc2-0xcb Gap */ - - uint16_t gpio_data; - uint16_t gpio_enable; - - uint16_t unused_7[0x11]; /* d0-f0 */ - uint16_t scsiControlPins; /* f2 */ - -}device_reg_t; +struct device_reg { + uint16_t id_l; /* ID low */ + uint16_t id_h; /* ID high */ + uint16_t cfg_0; /* Configuration 0 */ + uint16_t cfg_1; /* Configuration 1 */ + uint16_t ictrl; /* Interface control */ +#define ISP_RESET BIT_0 /* ISP soft reset */ +#define ISP_EN_INT BIT_1 /* ISP enable interrupts. */ +#define ISP_EN_RISC BIT_2 /* ISP enable RISC interrupts. */ +#define ISP_FLASH_ENABLE BIT_8 /* Flash BIOS Read/Write enable */ +#define ISP_FLASH_UPPER BIT_9 /* Flash upper bank select */ + uint16_t istatus; /* Interface status */ +#define PCI_64BIT_SLOT BIT_14 /* PCI 64-bit slot indicator. */ +#define RISC_INT BIT_2 /* RISC interrupt */ +#define PCI_INT BIT_1 /* PCI interrupt */ + uint16_t semaphore; /* Semaphore */ + uint16_t nvram; /* NVRAM register. */ +#define NV_DESELECT 0 +#define NV_CLOCK BIT_0 +#define NV_SELECT BIT_1 +#define NV_DATA_OUT BIT_2 +#define NV_DATA_IN BIT_3 + uint16_t flash_data; /* Flash BIOS data */ + uint16_t flash_address; /* Flash BIOS address */ + + uint16_t unused_1[0x2e]; /* 0x14-0x6f Gap */ + + uint16_t mailbox0; /* Mailbox 0 */ + uint16_t mailbox1; /* Mailbox 1 */ + uint16_t mailbox2; /* Mailbox 2 */ + uint16_t mailbox3; /* Mailbox 3 */ + uint16_t mailbox4; /* Mailbox 4 */ + uint16_t mailbox5; /* Mailbox 5 */ + uint16_t mailbox6; /* Mailbox 6 */ + uint16_t mailbox7; /* Mailbox 7 */ + + uint16_t unused_2[0x20];/* 0x80-0xbf Gap */ + + uint16_t host_cmd; /* Host command and control */ +#define HOST_INT BIT_7 /* host interrupt bit */ +#define BIOS_ENABLE BIT_0 + + uint16_t unused_6[0x5]; /* 0xc2-0xcb Gap */ + + uint16_t gpio_data; + uint16_t gpio_enable; + + uint16_t unused_7[0x11]; /* d0-f0 */ + uint16_t scsiControlPins; /* f2 */ +}; -#define MAILBOX_REGISTER_COUNT 8 +#define MAILBOX_REGISTER_COUNT 8 /* * ISP product identification definitions in mailboxes after reset. */ -#define PROD_ID_1 0x4953 -#define PROD_ID_2 0x0000 -#define PROD_ID_2a 0x5020 -#define PROD_ID_3 0x2020 -#define PROD_ID_4 0x1 +#define PROD_ID_1 0x4953 +#define PROD_ID_2 0x0000 +#define PROD_ID_2a 0x5020 +#define PROD_ID_3 0x2020 +#define PROD_ID_4 0x1 /* * ISP host command and control register command definitions */ -#define HC_RESET_RISC 0x1000 /* Reset RISC */ -#define HC_PAUSE_RISC 0x2000 /* Pause RISC */ -#define HC_RELEASE_RISC 0x3000 /* Release RISC from reset. */ -#define HC_SET_HOST_INT 0x5000 /* Set host interrupt */ -#define HC_CLR_HOST_INT 0x6000 /* Clear HOST interrupt */ -#define HC_CLR_RISC_INT 0x7000 /* Clear RISC interrupt */ -#define HC_DISABLE_BIOS 0x9000 /* Disable BIOS. */ +#define HC_RESET_RISC 0x1000 /* Reset RISC */ +#define HC_PAUSE_RISC 0x2000 /* Pause RISC */ +#define HC_RELEASE_RISC 0x3000 /* Release RISC from reset. */ +#define HC_SET_HOST_INT 0x5000 /* Set host interrupt */ +#define HC_CLR_HOST_INT 0x6000 /* Clear HOST interrupt */ +#define HC_CLR_RISC_INT 0x7000 /* Clear RISC interrupt */ +#define HC_DISABLE_BIOS 0x9000 /* Disable BIOS. */ /* * ISP mailbox Self-Test status codes */ -#define MBS_FRM_ALIVE 0 /* Firmware Alive. */ -#define MBS_CHKSUM_ERR 1 /* Checksum Error. */ -#define MBS_SHADOW_LD_ERR 2 /* Shadow Load Error. */ -#define MBS_BUSY 4 /* Busy. */ +#define MBS_FRM_ALIVE 0 /* Firmware Alive. */ +#define MBS_CHKSUM_ERR 1 /* Checksum Error. */ +#define MBS_SHADOW_LD_ERR 2 /* Shadow Load Error. */ +#define MBS_BUSY 4 /* Busy. */ /* * ISP mailbox command complete status codes */ -#define MBS_CMD_CMP 0x4000 /* Command Complete. */ -#define MBS_INV_CMD 0x4001 /* Invalid Command. */ -#define MBS_HOST_INF_ERR 0x4002 /* Host Interface Error. */ -#define MBS_TEST_FAILED 0x4003 /* Test Failed. */ -#define MBS_CMD_ERR 0x4005 /* Command Error. */ -#define MBS_CMD_PARAM_ERR 0x4006 /* Command Parameter Error. */ +#define MBS_CMD_CMP 0x4000 /* Command Complete. */ +#define MBS_INV_CMD 0x4001 /* Invalid Command. */ +#define MBS_HOST_INF_ERR 0x4002 /* Host Interface Error. */ +#define MBS_TEST_FAILED 0x4003 /* Test Failed. */ +#define MBS_CMD_ERR 0x4005 /* Command Error. */ +#define MBS_CMD_PARAM_ERR 0x4006 /* Command Parameter Error. */ /* * ISP mailbox asynchronous event status codes */ -#define MBA_ASYNC_EVENT 0x8000 /* Asynchronous event. */ -#define MBA_BUS_RESET 0x8001 /* SCSI Bus Reset. */ -#define MBA_SYSTEM_ERR 0x8002 /* System Error. */ -#define MBA_REQ_TRANSFER_ERR 0x8003 /* Request Transfer Error. */ -#define MBA_RSP_TRANSFER_ERR 0x8004 /* Response Transfer Error. */ -#define MBA_WAKEUP_THRES 0x8005 /* Request Queue Wake-up. */ -#define MBA_TIMEOUT_RESET 0x8006 /* Execution Timeout Reset. */ -#define MBA_DEVICE_RESET 0x8007 /* Bus Device Reset. */ -#define MBA_BUS_MODE_CHANGE 0x800E /* SCSI bus mode transition. */ -#define MBA_SCSI_COMPLETION 0x8020 /* Completion response. */ +#define MBA_ASYNC_EVENT 0x8000 /* Asynchronous event. */ +#define MBA_BUS_RESET 0x8001 /* SCSI Bus Reset. */ +#define MBA_SYSTEM_ERR 0x8002 /* System Error. */ +#define MBA_REQ_TRANSFER_ERR 0x8003 /* Request Transfer Error. */ +#define MBA_RSP_TRANSFER_ERR 0x8004 /* Response Transfer Error. */ +#define MBA_WAKEUP_THRES 0x8005 /* Request Queue Wake-up. */ +#define MBA_TIMEOUT_RESET 0x8006 /* Execution Timeout Reset. */ +#define MBA_DEVICE_RESET 0x8007 /* Bus Device Reset. */ +#define MBA_BUS_MODE_CHANGE 0x800E /* SCSI bus mode transition. */ +#define MBA_SCSI_COMPLETION 0x8020 /* Completion response. */ /* * ISP mailbox commands */ -#define MBC_NOP 0 /* No Operation. */ -#define MBC_LOAD_RAM 1 /* Load RAM. */ -#define MBC_EXECUTE_FIRMWARE 2 /* Execute firmware. */ -#define MBC_WRITE_RAM_WORD 4 /* Write ram word. */ -#define MBC_READ_RAM_WORD 5 /* Read ram word. */ -#define MBC_MAILBOX_REGISTER_TEST 6 /* Wrap incoming mailboxes */ -#define MBC_VERIFY_CHECKSUM 7 /* Verify checksum. */ -#define MBC_ABOUT_FIRMWARE 8 /* Get firmware revision. */ -#define MBC_INIT_REQUEST_QUEUE 0x10 /* Initialize request queue. */ -#define MBC_INIT_RESPONSE_QUEUE 0x11 /* Initialize response queue. */ -#define MBC_EXECUTE_IOCB 0x12 /* Execute IOCB command. */ -#define MBC_ABORT_COMMAND 0x15 /* Abort IOCB command. */ -#define MBC_ABORT_DEVICE 0x16 /* Abort device (ID/LUN). */ -#define MBC_ABORT_TARGET 0x17 /* Abort target (ID). */ -#define MBC_BUS_RESET 0x18 /* SCSI bus reset. */ -#define MBC_GET_RETRY_COUNT 0x22 /* Get retry count and delay. */ -#define MBC_GET_TARGET_PARAMETERS 0x28 /* Get target parameters. */ -#define MBC_SET_INITIATOR_ID 0x30 /* Set initiator SCSI ID. */ -#define MBC_SET_SELECTION_TIMEOUT 0x31 /* Set selection timeout. */ -#define MBC_SET_RETRY_COUNT 0x32 /* Set retry count and delay. */ -#define MBC_SET_TAG_AGE_LIMIT 0x33 /* Set tag age limit. */ -#define MBC_SET_CLOCK_RATE 0x34 /* Set clock rate. */ -#define MBC_SET_ACTIVE_NEGATION 0x35 /* Set active negation state. */ -#define MBC_SET_ASYNC_DATA_SETUP 0x36 /* Set async data setup time. */ -#define MBC_SET_PCI_CONTROL 0x37 /* Set BUS control parameters. */ -#define MBC_SET_TARGET_PARAMETERS 0x38 /* Set target parameters. */ -#define MBC_SET_DEVICE_QUEUE 0x39 /* Set device queue parameters */ -#define MBC_SET_SYSTEM_PARAMETER 0x45 /* Set system parameter word. */ -#define MBC_SET_FIRMWARE_FEATURES 0x4A /* Set firmware feature word. */ -#define MBC_INIT_REQUEST_QUEUE_A64 0x52 /* Initialize request queue A64 */ -#define MBC_INIT_RESPONSE_QUEUE_A64 0x53 /* Initialize response q A64. */ -#define MBC_ENABLE_TARGET_MODE 0x55 /* Enable target mode. */ +#define MBC_NOP 0 /* No Operation */ +#define MBC_LOAD_RAM 1 /* Load RAM */ +#define MBC_EXECUTE_FIRMWARE 2 /* Execute firmware */ +#define MBC_DUMP_RAM 3 /* Dump RAM contents */ +#define MBC_WRITE_RAM_WORD 4 /* Write ram word */ +#define MBC_READ_RAM_WORD 5 /* Read ram word */ +#define MBC_MAILBOX_REGISTER_TEST 6 /* Wrap incoming mailboxes */ +#define MBC_VERIFY_CHECKSUM 7 /* Verify checksum */ +#define MBC_ABOUT_FIRMWARE 8 /* Get firmware revision */ +#define MBC_INIT_REQUEST_QUEUE 0x10 /* Initialize request queue */ +#define MBC_INIT_RESPONSE_QUEUE 0x11 /* Initialize response queue */ +#define MBC_EXECUTE_IOCB 0x12 /* Execute IOCB command */ +#define MBC_ABORT_COMMAND 0x15 /* Abort IOCB command */ +#define MBC_ABORT_DEVICE 0x16 /* Abort device (ID/LUN) */ +#define MBC_ABORT_TARGET 0x17 /* Abort target (ID) */ +#define MBC_BUS_RESET 0x18 /* SCSI bus reset */ +#define MBC_GET_RETRY_COUNT 0x22 /* Get retry count and delay */ +#define MBC_GET_TARGET_PARAMETERS 0x28 /* Get target parameters */ +#define MBC_SET_INITIATOR_ID 0x30 /* Set initiator SCSI ID */ +#define MBC_SET_SELECTION_TIMEOUT 0x31 /* Set selection timeout */ +#define MBC_SET_RETRY_COUNT 0x32 /* Set retry count and delay */ +#define MBC_SET_TAG_AGE_LIMIT 0x33 /* Set tag age limit */ +#define MBC_SET_CLOCK_RATE 0x34 /* Set clock rate */ +#define MBC_SET_ACTIVE_NEGATION 0x35 /* Set active negation state */ +#define MBC_SET_ASYNC_DATA_SETUP 0x36 /* Set async data setup time */ +#define MBC_SET_PCI_CONTROL 0x37 /* Set BUS control parameters */ +#define MBC_SET_TARGET_PARAMETERS 0x38 /* Set target parameters */ +#define MBC_SET_DEVICE_QUEUE 0x39 /* Set device queue parameters */ +#define MBC_SET_RESET_DELAY_PARAMETERS 0x3A /* Set reset delay parameters */ +#define MBC_SET_SYSTEM_PARAMETER 0x45 /* Set system parameter word */ +#define MBC_SET_FIRMWARE_FEATURES 0x4A /* Set firmware feature word */ +#define MBC_INIT_REQUEST_QUEUE_A64 0x52 /* Initialize request queue A64 */ +#define MBC_INIT_RESPONSE_QUEUE_A64 0x53 /* Initialize response q A64 */ +#define MBC_ENABLE_TARGET_MODE 0x55 /* Enable target mode */ +#define MBC_SET_DATA_OVERRUN_RECOVERY 0x5A /* Set data overrun recovery mode */ /* * ISP Get/Set Target Parameters mailbox command control flags. */ -#define TP_RENEGOTIATE BIT_8 /* Renegotiate on error. */ -#define TP_STOP_QUEUE BIT_9 /* Stop que on check condition */ -#define TP_AUTO_REQUEST_SENSE BIT_10 /* Automatic request sense. */ -#define TP_TAGGED_QUEUE BIT_11 /* Tagged queuing. */ -#define TP_SYNC BIT_12 /* Synchronous data transfers. */ -#define TP_WIDE BIT_13 /* Wide data transfers. */ -#define TP_PARITY BIT_14 /* Parity checking. */ -#define TP_DISCONNECT BIT_15 /* Disconnect privilege. */ +#define TP_PPR BIT_5 /* PPR */ +#define TP_RENEGOTIATE BIT_8 /* Renegotiate on error. */ +#define TP_STOP_QUEUE BIT_9 /* Stop que on check condition */ +#define TP_AUTO_REQUEST_SENSE BIT_10 /* Automatic request sense. */ +#define TP_TAGGED_QUEUE BIT_11 /* Tagged queuing. */ +#define TP_SYNC BIT_12 /* Synchronous data transfers. */ +#define TP_WIDE BIT_13 /* Wide data transfers. */ +#define TP_PARITY BIT_14 /* Parity checking. */ +#define TP_DISCONNECT BIT_15 /* Disconnect privilege. */ /* * NVRAM Command values. */ -#define NV_START_BIT BIT_2 -#define NV_WRITE_OP (BIT_26+BIT_24) -#define NV_READ_OP (BIT_26+BIT_25) -#define NV_ERASE_OP (BIT_26+BIT_25+BIT_24) -#define NV_MASK_OP (BIT_26+BIT_25+BIT_24) -#define NV_DELAY_COUNT 10 - -/* - * QLogic ISP1280 NVRAM structure definition. - */ -typedef struct -{ - uint8_t id[4]; /* 0, 1, 2, 3 */ - uint8_t version; /* 4 */ - - struct - { - uint8_t bios_configuration_mode :2; - uint8_t bios_disable :1; - uint8_t selectable_scsi_boot_enable :1; - uint8_t cd_rom_boot_enable :1; - uint8_t disable_loading_risc_code :1; - uint8_t enable_64bit_addressing :1; - uint8_t unused_7 :1; - }cntr_flags_1; /* 5 */ - - struct - { - uint8_t boot_lun_number :5; - uint8_t scsi_bus_number :1; - uint8_t unused_6 :1; - uint8_t unused_7 :1; - uint8_t boot_target_number :4; - uint8_t unused_12 :1; - uint8_t unused_13 :1; - uint8_t unused_14 :1; - uint8_t unused_15 :1; - }cntr_flags_2; /* 6, 7 */ - - uint16_t unused_8; /* 8, 9 */ - uint16_t unused_10; /* 10, 11 */ - uint16_t unused_12; /* 12, 13 */ - uint16_t unused_14; /* 14, 15 */ - - union - { - uint8_t c; - struct - { - uint8_t reserved :2; - uint8_t burst_enable :1; - uint8_t reserved_1 :1; - uint8_t fifo_threshold :4; - }f; - }isp_config; /* 16 */ - - /* Termination - * 0 = Disable, 1 = high only, 3 = Auto term - */ - union - { - uint8_t c; - struct - { - uint8_t scsi_bus_1_control :2; - uint8_t scsi_bus_0_control :2; - uint8_t unused_0 :1; - uint8_t unused_1 :1; - uint8_t unused_2 :1; - uint8_t auto_term_support :1; - }f; - }termination; /* 17 */ - - uint16_t isp_parameter; /* 18, 19 */ - - union - { - uint16_t w; - struct - { - uint8_t enable_fast_posting :1; - uint8_t report_lvd_bus_transition :1; - uint8_t unused_2 :1; - uint8_t unused_3 :1; - uint8_t unused_4 :1; - uint8_t unused_5 :1; - uint8_t unused_6 :1; - uint8_t unused_7 :1; - uint8_t unused_8 :1; - uint8_t unused_9 :1; - uint8_t unused_10 :1; - uint8_t unused_11 :1; - uint8_t unused_12 :1; - uint8_t unused_13 :1; - uint8_t unused_14 :1; - uint8_t unused_15 :1; - }f; - }firmware_feature; /* 20, 21 */ - - uint16_t unused_22; /* 22, 23 */ - - struct - { - struct - { - uint8_t initiator_id :4; - uint8_t scsi_reset_disable :1; - uint8_t scsi_bus_size :1; - uint8_t scsi_bus_type :1; - uint8_t unused_7 :1; - }config_1; /* 24 */ - - uint8_t bus_reset_delay; /* 25 */ - uint8_t retry_count; /* 26 */ - uint8_t retry_delay; /* 27 */ - - struct - { - uint8_t async_data_setup_time :4; - uint8_t req_ack_active_negation :1; - uint8_t data_line_active_negation :1; - uint8_t unused_6 :1; - uint8_t unused_7 :1; - }config_2; /* 28 */ - - uint8_t unused_29; /* 29 */ - - uint16_t selection_timeout; /* 30, 31 */ - uint16_t max_queue_depth; /* 32, 33 */ - - uint16_t unused_34; /* 34, 35 */ - uint16_t unused_36; /* 36, 37 */ - uint16_t unused_38; /* 38, 39 */ - - struct - { - union - { - uint8_t c; - struct - { - uint8_t renegotiate_on_error :1; - uint8_t stop_queue_on_check :1; - uint8_t auto_request_sense :1; - uint8_t tag_queuing :1; - uint8_t sync_data_transfers :1; - uint8_t wide_data_transfers :1; - uint8_t parity_checking :1; - uint8_t disconnect_allowed :1; - }f; - }parameter; /* 40 */ - - uint8_t execution_throttle; /* 41 */ - uint8_t sync_period; /* 42 */ - - struct - { - uint8_t sync_offset :4; - uint8_t device_enable :1; - uint8_t lun_disable :1; - uint8_t unused_6 :1; - uint8_t unused_7 :1; - }flags; /* 43 */ - - uint16_t unused_44; /* 44, 45 */ - }target[MAX_TARGETS]; - }bus[MAX_BUSES]; - - uint16_t unused_248; /* 248, 249 */ - - uint16_t subsystem_id[2]; /* 250, 251, 252, 253 */ - - uint8_t unused_254; /* 254 */ - - uint8_t chksum; /* 255 */ -}nvram_t; - -/* - * QLogic ISP12160 NVRAM structure definition. - */ -typedef struct -{ - uint8_t id[4]; /* 0, 1, 2, 3 */ - uint8_t version; /* 4 */ - /* Host/Bios Flags */ - struct - { - uint8_t bios_configuration_mode :2; - uint8_t bios_disable :1; - uint8_t selectable_scsi_boot_enable :1; - uint8_t cd_rom_boot_enable :1; - uint8_t disable_loading_risc_code :1; - uint8_t unused_6 :1; - uint8_t unused_7 :1; - }cntr_flags_1; /* 5 */ - /* Selectable Boot Support */ - struct - { - uint8_t boot_lun_number :5; - uint8_t scsi_bus_number :1; - uint8_t unused_6 :1; - uint8_t unused_7 :1; - uint8_t boot_target_number :4; - uint8_t unused_12 :1; - uint8_t unused_13 :1; - uint8_t unused_14 :1; - uint8_t unused_15 :1; - }cntr_flags_2; /* 6, 7 */ - - uint16_t unused_8; /* 8, 9 */ - uint16_t unused_10; /* 10, 11 */ - uint16_t unused_12; /* 12, 13 */ - uint16_t unused_14; /* 14, 15 */ - - /* ISP Config Parameters */ - union - { - uint8_t c; - struct - { - uint8_t reserved :2; - uint8_t burst_enable :1; - uint8_t reserved_1 :1; - uint8_t fifo_threshold :4; - }f; - }isp_config; /* 16 */ - - /* Termination - * 0 = Disable, 1 = high only, 3 = Auto term - */ - union - { - uint8_t c; - struct - { - uint8_t scsi_bus_1_control :2; - uint8_t scsi_bus_0_control :2; - uint8_t unused_0 :1; - uint8_t unused_1 :1; - uint8_t unused_2 :1; - uint8_t auto_term_support :1; - }f; - }termination; /* 17 */ - /* Auto Term - 3 */ - /* High Only - 1 (GPIO2 = 1 & GPIO3 = 0) */ - /* Disable - 0 (GPIO2 = 0 & GPIO3 = X) */ - - uint16_t isp_parameter; /* 18, 19 */ - - union - { - uint16_t w; - struct - { - uint8_t enable_fast_posting :1; - uint8_t report_lvd_bus_transition :1; - uint8_t unused_2 :1; - uint8_t unused_3 :1; - uint8_t unused_4 :1; - uint8_t unused_5 :1; - uint8_t unused_6 :1; - uint8_t unused_7 :1; - uint8_t unused_8 :1; - uint8_t unused_9 :1; - uint8_t unused_10 :1; - uint8_t unused_11 :1; - uint8_t unused_12 :1; - uint8_t unused_13 :1; - uint8_t unused_14 :1; - uint8_t unused_15 :1; - }f; - }firmware_feature; /* 20, 21 */ - - uint16_t unused_22; /* 22, 23 */ - - struct - { - struct - { - uint8_t initiator_id :4; - uint8_t scsi_reset_disable :1; - uint8_t scsi_bus_size :1; - uint8_t scsi_bus_type :1; - uint8_t unused_7 :1; - }config_1; /* 24 */ - - uint8_t bus_reset_delay; /* 25 */ - uint8_t retry_count; /* 26 */ - uint8_t retry_delay; /* 27 */ - /* Adapter Capabilities bits */ - struct - { - uint8_t async_data_setup_time :4; - uint8_t req_ack_active_negation :1; - uint8_t data_line_active_negation :1; - uint8_t unused_6 :1; - uint8_t unused_7 :1; - }config_2; /* 28 */ - - uint8_t unused_29; /* 29 */ - - uint16_t selection_timeout; /* 30, 31 */ - uint16_t max_queue_depth; /* 32, 33 */ - - uint16_t unused_34; /* 34, 35 */ - uint16_t unused_36; /* 36, 37 */ - uint16_t unused_38; /* 38, 39 */ - - struct - { - union - { - uint8_t c; - struct - { - uint8_t renegotiate_on_error :1; - uint8_t stop_queue_on_check :1; - uint8_t auto_request_sense :1; - uint8_t tag_queuing :1; - uint8_t sync_data_transfers :1; - uint8_t wide_data_transfers :1; - uint8_t parity_checking :1; - uint8_t disconnect_allowed :1; - }f; - }parameter; /* 40 */ - - uint8_t execution_throttle; /* 41 */ - uint8_t sync_period; /* 42 */ - - struct - { - uint8_t sync_offset :5; - uint8_t device_enable :1; - uint8_t unused_6 :1; - uint8_t unused_7 :1; - uint8_t ppr_options :4; - uint8_t ppr_bus_width :2; - uint8_t unused_8 :1; - uint8_t enable_ppr :1; - }flags; /* 43, 44 */ - - uint8_t unused_45; /* 45 */ - }target[MAX_TARGETS]; - }bus[MAX_BUSES]; +#define NV_START_BIT BIT_2 +#define NV_WRITE_OP (BIT_26 | BIT_24) +#define NV_READ_OP (BIT_26 | BIT_25) +#define NV_ERASE_OP (BIT_26 | BIT_25 | BIT_24) +#define NV_MASK_OP (BIT_26 | BIT_25 | BIT_24) +#define NV_DELAY_COUNT 10 + +/* + * QLogic ISP1280/ISP12160 NVRAM structure definition. + */ +struct nvram { + uint8_t id0; /* 0 */ + uint8_t id1; /* 1 */ + uint8_t id2; /* 2 */ + uint8_t id3; /* 3 */ + uint8_t version; /* 4 */ + + struct { + uint8_t bios_configuration_mode:2; + uint8_t bios_disable:1; + uint8_t selectable_scsi_boot_enable:1; + uint8_t cd_rom_boot_enable:1; + uint8_t disable_loading_risc_code:1; + uint8_t enable_64bit_addressing:1; + uint8_t unused_7:1; + } cntr_flags_1; /* 5 */ + + struct { + uint16_t boot_lun_number:5; + uint16_t scsi_bus_number:1; + uint16_t unused_6:1; + uint16_t unused_7:1; + uint16_t boot_target_number:4; + uint16_t unused_12:1; + uint16_t unused_13:1; + uint16_t unused_14:1; + uint16_t unused_15:1; + } cntr_flags_2; /* 6, 7 */ + + uint16_t unused_8; /* 8, 9 */ + uint16_t unused_10; /* 10, 11 */ + uint16_t unused_12; /* 12, 13 */ + uint16_t unused_14; /* 14, 15 */ + + union { + uint8_t c; + struct { + uint8_t reserved:2; + uint8_t burst_enable:1; + uint8_t reserved_1:1; + uint8_t fifo_threshold:4; + } f; + } isp_config; /* 16 */ + + /* Termination + * 0 = Disable, 1 = high only, 3 = Auto term + */ + union { + uint8_t c; + struct { + uint8_t scsi_bus_1_control:2; + uint8_t scsi_bus_0_control:2; + uint8_t unused_0:1; + uint8_t unused_1:1; + uint8_t unused_2:1; + uint8_t auto_term_support:1; + } f; + } termination; /* 17 */ + + uint16_t isp_parameter; /* 18, 19 */ + + union { + uint16_t w; + struct { + uint16_t enable_fast_posting:1; + uint16_t report_lvd_bus_transition:1; + uint16_t unused_2:1; + uint16_t unused_3:1; + uint16_t disable_iosbs_with_bus_reset_status:1; + uint16_t disable_synchronous_backoff:1; + uint16_t unused_6:1; + uint16_t synchronous_backoff_reporting:1; + uint16_t disable_reselection_fairness:1; + uint16_t unused_9:1; + uint16_t unused_10:1; + uint16_t unused_11:1; + uint16_t unused_12:1; + uint16_t unused_13:1; + uint16_t unused_14:1; + uint16_t unused_15:1; + } f; + } firmware_feature; /* 20, 21 */ + + uint16_t unused_22; /* 22, 23 */ + + struct { + struct { + uint8_t initiator_id:4; + uint8_t scsi_reset_disable:1; + uint8_t scsi_bus_size:1; + uint8_t scsi_bus_type:1; + uint8_t unused_7:1; + } config_1; /* 24 */ + + uint8_t bus_reset_delay; /* 25 */ + uint8_t retry_count; /* 26 */ + uint8_t retry_delay; /* 27 */ + + struct { + uint8_t async_data_setup_time:4; + uint8_t req_ack_active_negation:1; + uint8_t data_line_active_negation:1; + uint8_t unused_6:1; + uint8_t unused_7:1; + } config_2; /* 28 */ + + uint8_t unused_29; /* 29 */ + + uint16_t selection_timeout; /* 30, 31 */ + uint16_t max_queue_depth; /* 32, 33 */ + + uint16_t unused_34; /* 34, 35 */ + uint16_t unused_36; /* 36, 37 */ + uint16_t unused_38; /* 38, 39 */ + + struct { + union { + uint8_t c; + struct { + uint8_t renegotiate_on_error:1; + uint8_t stop_queue_on_check:1; + uint8_t auto_request_sense:1; + uint8_t tag_queuing:1; + uint8_t enable_sync:1; + uint8_t enable_wide:1; + uint8_t parity_checking:1; + uint8_t disconnect_allowed:1; + } f; + } parameter; /* 40 */ + + uint8_t execution_throttle; /* 41 */ + uint8_t sync_period; /* 42 */ + + union { /* 43 */ + uint8_t flags_43; + struct { + uint8_t sync_offset:4; + uint8_t device_enable:1; + uint8_t lun_disable:1; + uint8_t unused_6:1; + uint8_t unused_7:1; + } flags1x80; + struct { + uint8_t sync_offset:5; + uint8_t device_enable:1; + uint8_t unused_6:1; + uint8_t unused_7:1; + } flags1x160; + } flags; + union { /* PPR flags for the 1x160 controllers */ + uint8_t unused_44; + struct { + uint8_t ppr_options:4; + uint8_t ppr_bus_width:2; + uint8_t unused_8:1; + uint8_t enable_ppr:1; + } flags; /* 44 */ + } ppr_1x160; + uint8_t unused_45; /* 45 */ + } target[MAX_TARGETS]; + } bus[MAX_BUSES]; + + uint16_t unused_248; /* 248, 249 */ + + uint16_t subsystem_id[2]; /* 250, 251, 252, 253 */ + + union { /* 254 */ + uint8_t unused_254; + uint8_t system_id_pointer; + } sysid_1x160; - uint16_t unused_248; /* 248, 249 */ - - uint16_t subsystem_id[2]; /* 250, 251, 252, 253 */ - - uint8_t System_Id_Pointer; /* 254 */ - - uint8_t chksum; /* 255 */ -}nvram160_t; + uint8_t chksum; /* 255 */ +}; /* * ISP queue - command entry structure definition. */ -#define MAX_CMDSZ 12 /* SCSI maximum CDB size. */ -typedef struct -{ - uint8_t entry_type; /* Entry type. */ - #define COMMAND_TYPE 1 /* Command entry */ - uint8_t entry_count; /* Entry count. */ - uint8_t sys_define; /* System defined. */ - uint8_t entry_status; /* Entry Status. */ - uint32_t handle; /* System handle. */ - uint8_t lun; /* SCSI LUN */ - uint8_t target; /* SCSI ID */ - uint16_t cdb_len; /* SCSI command length. */ - uint16_t control_flags; /* Control flags. */ - uint16_t reserved; - uint16_t timeout; /* Command timeout. */ - uint16_t dseg_count; /* Data segment count. */ - uint8_t scsi_cdb[MAX_CMDSZ]; /* SCSI command words. */ - uint32_t dseg_0_address; /* Data segment 0 address. */ - uint32_t dseg_0_length; /* Data segment 0 length. */ - uint32_t dseg_1_address; /* Data segment 1 address. */ - uint32_t dseg_1_length; /* Data segment 1 length. */ - uint32_t dseg_2_address; /* Data segment 2 address. */ - uint32_t dseg_2_length; /* Data segment 2 length. */ - uint32_t dseg_3_address; /* Data segment 3 address. */ - uint32_t dseg_3_length; /* Data segment 3 length. */ -}cmd_entry_t; +#define MAX_CMDSZ 12 /* SCSI maximum CDB size. */ +struct cmd_entry { + uint8_t entry_type; /* Entry type. */ +#define COMMAND_TYPE 1 /* Command entry */ + uint8_t entry_count; /* Entry count. */ + uint8_t sys_define; /* System defined. */ + uint8_t entry_status; /* Entry Status. */ + uint32_t handle; /* System handle. */ + uint8_t lun; /* SCSI LUN */ + uint8_t target; /* SCSI ID */ + uint16_t cdb_len; /* SCSI command length. */ + uint16_t control_flags; /* Control flags. */ + uint16_t reserved; + uint16_t timeout; /* Command timeout. */ + uint16_t dseg_count; /* Data segment count. */ + uint8_t scsi_cdb[MAX_CMDSZ]; /* SCSI command words. */ + uint32_t dseg_0_address; /* Data segment 0 address. */ + uint32_t dseg_0_length; /* Data segment 0 length. */ + uint32_t dseg_1_address; /* Data segment 1 address. */ + uint32_t dseg_1_length; /* Data segment 1 length. */ + uint32_t dseg_2_address; /* Data segment 2 address. */ + uint32_t dseg_2_length; /* Data segment 2 length. */ + uint32_t dseg_3_address; /* Data segment 3 address. */ + uint32_t dseg_3_length; /* Data segment 3 length. */ +}; /* * ISP queue - continuation entry structure definition. */ -typedef struct -{ - uint8_t entry_type; /* Entry type. */ - #define CONTINUE_TYPE 2 /* Continuation entry. */ - uint8_t entry_count; /* Entry count. */ - uint8_t sys_define; /* System defined. */ - uint8_t entry_status; /* Entry Status. */ - uint32_t reserved; /* Reserved */ - uint32_t dseg_0_address; /* Data segment 0 address. */ - uint32_t dseg_0_length; /* Data segment 0 length. */ - uint32_t dseg_1_address; /* Data segment 1 address. */ - uint32_t dseg_1_length; /* Data segment 1 length. */ - uint32_t dseg_2_address; /* Data segment 2 address. */ - uint32_t dseg_2_length; /* Data segment 2 length. */ - uint32_t dseg_3_address; /* Data segment 3 address. */ - uint32_t dseg_3_length; /* Data segment 3 length. */ - uint32_t dseg_4_address; /* Data segment 4 address. */ - uint32_t dseg_4_length; /* Data segment 4 length. */ - uint32_t dseg_5_address; /* Data segment 5 address. */ - uint32_t dseg_5_length; /* Data segment 5 length. */ - uint32_t dseg_6_address; /* Data segment 6 address. */ - uint32_t dseg_6_length; /* Data segment 6 length. */ -}cont_entry_t; +struct cont_entry { + uint8_t entry_type; /* Entry type. */ +#define CONTINUE_TYPE 2 /* Continuation entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t sys_define; /* System defined. */ + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved; /* Reserved */ + uint32_t dseg_0_address; /* Data segment 0 address. */ + uint32_t dseg_0_length; /* Data segment 0 length. */ + uint32_t dseg_1_address; /* Data segment 1 address. */ + uint32_t dseg_1_length; /* Data segment 1 length. */ + uint32_t dseg_2_address; /* Data segment 2 address. */ + uint32_t dseg_2_length; /* Data segment 2 length. */ + uint32_t dseg_3_address; /* Data segment 3 address. */ + uint32_t dseg_3_length; /* Data segment 3 length. */ + uint32_t dseg_4_address; /* Data segment 4 address. */ + uint32_t dseg_4_length; /* Data segment 4 length. */ + uint32_t dseg_5_address; /* Data segment 5 address. */ + uint32_t dseg_5_length; /* Data segment 5 length. */ + uint32_t dseg_6_address; /* Data segment 6 address. */ + uint32_t dseg_6_length; /* Data segment 6 length. */ +}; /* * ISP queue - status entry structure definition. */ -typedef struct -{ - uint8_t entry_type; /* Entry type. */ - #define STATUS_TYPE 3 /* Status entry. */ - uint8_t entry_count; /* Entry count. */ - uint8_t sys_define; /* System defined. */ - uint8_t entry_status; /* Entry Status. */ - #define RF_CONT BIT_0 /* Continuation. */ - #define RF_FULL BIT_1 /* Full */ - #define RF_BAD_HEADER BIT_2 /* Bad header. */ - #define RF_BAD_PAYLOAD BIT_3 /* Bad payload. */ - uint32_t handle; /* System handle. */ - uint16_t scsi_status; /* SCSI status. */ - uint16_t comp_status; /* Completion status. */ - uint16_t state_flags; /* State flags. */ - #define SF_TRANSFER_CMPL BIT_14 /* Transfer Complete. */ - #define SF_GOT_SENSE BIT_13 /* Got Sense */ - #define SF_GOT_STATUS BIT_12 /* Got Status */ - #define SF_TRANSFERRED_DATA BIT_11 /* Transferred data */ - #define SF_SENT_CDB BIT_10 /* Send CDB */ - #define SF_GOT_TARGET BIT_9 /* */ - #define SF_GOT_BUS BIT_8 /* */ - uint16_t status_flags; /* Status flags. */ - uint16_t time; /* Time. */ - uint16_t req_sense_length; /* Request sense data length. */ - uint32_t residual_length; /* Residual transfer length. */ - uint16_t reserved[4]; - uint8_t req_sense_data[32]; /* Request sense data. */ -}sts_entry_t, response_t; +struct response { + uint8_t entry_type; /* Entry type. */ +#define STATUS_TYPE 3 /* Status entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t sys_define; /* System defined. */ + uint8_t entry_status; /* Entry Status. */ +#define RF_CONT BIT_0 /* Continuation. */ +#define RF_FULL BIT_1 /* Full */ +#define RF_BAD_HEADER BIT_2 /* Bad header. */ +#define RF_BAD_PAYLOAD BIT_3 /* Bad payload. */ + uint32_t handle; /* System handle. */ + uint16_t scsi_status; /* SCSI status. */ + uint16_t comp_status; /* Completion status. */ + uint16_t state_flags; /* State flags. */ +#define SF_TRANSFER_CMPL BIT_14 /* Transfer Complete. */ +#define SF_GOT_SENSE BIT_13 /* Got Sense */ +#define SF_GOT_STATUS BIT_12 /* Got Status */ +#define SF_TRANSFERRED_DATA BIT_11 /* Transferred data */ +#define SF_SENT_CDB BIT_10 /* Send CDB */ +#define SF_GOT_TARGET BIT_9 /* */ +#define SF_GOT_BUS BIT_8 /* */ + uint16_t status_flags; /* Status flags. */ + uint16_t time; /* Time. */ + uint16_t req_sense_length; /* Request sense data length. */ + uint32_t residual_length; /* Residual transfer length. */ + uint16_t reserved[4]; + uint8_t req_sense_data[32]; /* Request sense data. */ +}; /* * ISP queue - marker entry structure definition. */ -typedef struct -{ - uint8_t entry_type; /* Entry type. */ - #define MARKER_TYPE 4 /* Marker entry. */ - uint8_t entry_count; /* Entry count. */ - uint8_t sys_define; /* System defined. */ - uint8_t entry_status; /* Entry Status. */ - uint32_t reserved; - uint8_t lun; /* SCSI LUN */ - uint8_t target; /* SCSI ID */ - uint8_t modifier; /* Modifier (7-0). */ - #define MK_SYNC_ID_LUN 0 /* Synchronize ID/LUN */ - #define MK_SYNC_ID 1 /* Synchronize ID */ - #define MK_SYNC_ALL 2 /* Synchronize all ID/LUN */ - uint8_t reserved_1[53]; -}mrk_entry_t; +struct mrk_entry { + uint8_t entry_type; /* Entry type. */ +#define MARKER_TYPE 4 /* Marker entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t sys_define; /* System defined. */ + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved; + uint8_t lun; /* SCSI LUN */ + uint8_t target; /* SCSI ID */ + uint8_t modifier; /* Modifier (7-0). */ +#define MK_SYNC_ID_LUN 0 /* Synchronize ID/LUN */ +#define MK_SYNC_ID 1 /* Synchronize ID */ +#define MK_SYNC_ALL 2 /* Synchronize all ID/LUN */ + uint8_t reserved_1[53]; +}; /* * ISP queue - extended command entry structure definition. + * + * Unused by the driver! */ -typedef struct -{ - uint8_t entry_type; /* Entry type. */ - #define EXTENDED_CMD_TYPE 5 /* Extended command entry. */ - uint8_t entry_count; /* Entry count. */ - uint8_t sys_define; /* System defined. */ - uint8_t entry_status; /* Entry Status. */ - uint32_t handle; /* System handle. */ - uint8_t lun; /* SCSI LUN */ - uint8_t target; /* SCSI ID */ - uint16_t cdb_len; /* SCSI command length. */ - uint16_t control_flags; /* Control flags. */ - uint16_t reserved; - uint16_t timeout; /* Command timeout. */ - uint16_t dseg_count; /* Data segment count. */ - uint8_t scsi_cdb[88]; /* SCSI command words. */ -}ecmd_entry_t; +struct ecmd_entry { + uint8_t entry_type; /* Entry type. */ +#define EXTENDED_CMD_TYPE 5 /* Extended command entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t sys_define; /* System defined. */ + uint8_t entry_status; /* Entry Status. */ + uint32_t handle; /* System handle. */ + uint8_t lun; /* SCSI LUN */ + uint8_t target; /* SCSI ID */ + uint16_t cdb_len; /* SCSI command length. */ + uint16_t control_flags; /* Control flags. */ + uint16_t reserved; + uint16_t timeout; /* Command timeout. */ + uint16_t dseg_count; /* Data segment count. */ + uint8_t scsi_cdb[88]; /* SCSI command words. */ +}; /* * ISP queue - 64-Bit addressing, command entry structure definition. */ -typedef struct -{ - uint8_t entry_type; /* Entry type. */ - #define COMMAND_A64_TYPE 9 /* Command A64 entry */ - uint8_t entry_count; /* Entry count. */ - uint8_t sys_define; /* System defined. */ - uint8_t entry_status; /* Entry Status. */ - uint32_t handle; /* System handle. */ - uint8_t lun; /* SCSI LUN */ - uint8_t target; /* SCSI ID */ - uint16_t cdb_len; /* SCSI command length. */ - uint16_t control_flags; /* Control flags. */ - uint16_t reserved; - uint16_t timeout; /* Command timeout. */ - uint16_t dseg_count; /* Data segment count. */ - uint8_t scsi_cdb[MAX_CMDSZ]; /* SCSI command words. */ - uint32_t reserved_1[2]; /* unused */ - uint32_t dseg_0_address[2]; /* Data segment 0 address. */ - uint32_t dseg_0_length; /* Data segment 0 length. */ - uint32_t dseg_1_address[2]; /* Data segment 1 address. */ - uint32_t dseg_1_length; /* Data segment 1 length. */ -}cmd_a64_entry_t, request_t; +typedef struct { + uint8_t entry_type; /* Entry type. */ +#define COMMAND_A64_TYPE 9 /* Command A64 entry */ + uint8_t entry_count; /* Entry count. */ + uint8_t sys_define; /* System defined. */ + uint8_t entry_status; /* Entry Status. */ + uint32_t handle; /* System handle. */ + uint8_t lun; /* SCSI LUN */ + uint8_t target; /* SCSI ID */ + uint16_t cdb_len; /* SCSI command length. */ + uint16_t control_flags; /* Control flags. */ + uint16_t reserved; + uint16_t timeout; /* Command timeout. */ + uint16_t dseg_count; /* Data segment count. */ + uint8_t scsi_cdb[MAX_CMDSZ]; /* SCSI command words. */ + uint32_t reserved_1[2]; /* unused */ + uint32_t dseg_0_address[2]; /* Data segment 0 address. */ + uint32_t dseg_0_length; /* Data segment 0 length. */ + uint32_t dseg_1_address[2]; /* Data segment 1 address. */ + uint32_t dseg_1_length; /* Data segment 1 length. */ +} cmd_a64_entry_t, request_t; /* * ISP queue - 64-Bit addressing, continuation entry structure definition. */ -typedef struct -{ - uint8_t entry_type; /* Entry type. */ - #define CONTINUE_A64_TYPE 0xA /* Continuation A64 entry. */ - uint8_t entry_count; /* Entry count. */ - uint8_t sys_define; /* System defined. */ - uint8_t entry_status; /* Entry Status. */ - uint32_t dseg_0_address[2]; /* Data segment 0 address. */ - uint32_t dseg_0_length; /* Data segment 0 length. */ - uint32_t dseg_1_address[2]; /* Data segment 1 address. */ - uint32_t dseg_1_length; /* Data segment 1 length. */ - uint32_t dseg_2_address[2]; /* Data segment 2 address. */ - uint32_t dseg_2_length; /* Data segment 2 length. */ - uint32_t dseg_3_address[2]; /* Data segment 3 address. */ - uint32_t dseg_3_length; /* Data segment 3 length. */ - uint32_t dseg_4_address[2]; /* Data segment 4 address. */ - uint32_t dseg_4_length; /* Data segment 4 length. */ -}cont_a64_entry_t; +struct cont_a64_entry { + uint8_t entry_type; /* Entry type. */ +#define CONTINUE_A64_TYPE 0xA /* Continuation A64 entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t sys_define; /* System defined. */ + uint8_t entry_status; /* Entry Status. */ + uint32_t dseg_0_address[2]; /* Data segment 0 address. */ + uint32_t dseg_0_length; /* Data segment 0 length. */ + uint32_t dseg_1_address[2]; /* Data segment 1 address. */ + uint32_t dseg_1_length; /* Data segment 1 length. */ + uint32_t dseg_2_address[2]; /* Data segment 2 address. */ + uint32_t dseg_2_length; /* Data segment 2 length. */ + uint32_t dseg_3_address[2]; /* Data segment 3 address. */ + uint32_t dseg_3_length; /* Data segment 3 length. */ + uint32_t dseg_4_address[2]; /* Data segment 4 address. */ + uint32_t dseg_4_length; /* Data segment 4 length. */ +}; /* * ISP queue - enable LUN entry structure definition. */ -typedef struct -{ - uint8_t entry_type; /* Entry type. */ - #define ENABLE_LUN_TYPE 0xB /* Enable LUN entry. */ - uint8_t entry_count; /* Entry count. */ - uint8_t reserved_1; - uint8_t entry_status; /* Entry Status not used. */ - uint32_t reserved_2; - uint16_t lun; /* Bit 15 is bus number. */ - uint16_t reserved_4; - uint32_t option_flags; - uint8_t status; - uint8_t reserved_5; - uint8_t command_count; /* Number of ATIOs allocated. */ - uint8_t immed_notify_count; /* Number of Immediate Notify */ - /* entries allocated. */ - uint8_t group_6_length; /* SCSI CDB length for group 6 */ - /* commands (2-26). */ - uint8_t group_7_length; /* SCSI CDB length for group 7 */ - /* commands (2-26). */ - uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ - uint16_t reserved_6[20]; -}elun_entry_t; +struct elun_entry { + uint8_t entry_type; /* Entry type. */ +#define ENABLE_LUN_TYPE 0xB /* Enable LUN entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t reserved_1; + uint8_t entry_status; /* Entry Status not used. */ + uint32_t reserved_2; + uint16_t lun; /* Bit 15 is bus number. */ + uint16_t reserved_4; + uint32_t option_flags; + uint8_t status; + uint8_t reserved_5; + uint8_t command_count; /* Number of ATIOs allocated. */ + uint8_t immed_notify_count; /* Number of Immediate Notify */ + /* entries allocated. */ + uint8_t group_6_length; /* SCSI CDB length for group 6 */ + /* commands (2-26). */ + uint8_t group_7_length; /* SCSI CDB length for group 7 */ + /* commands (2-26). */ + uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ + uint16_t reserved_6[20]; +}; /* * ISP queue - modify LUN entry structure definition. + * + * Unused by the driver! */ -typedef struct -{ - uint8_t entry_type; /* Entry type. */ - #define MODIFY_LUN_TYPE 0xC /* Modify LUN entry. */ - uint8_t entry_count; /* Entry count. */ - uint8_t reserved_1; - uint8_t entry_status; /* Entry Status. */ - uint32_t reserved_2; - uint8_t lun; /* SCSI LUN */ - uint8_t reserved_3; - uint8_t operators; - uint8_t reserved_4; - uint32_t option_flags; - uint8_t status; - uint8_t reserved_5; - uint8_t command_count; /* Number of ATIOs allocated. */ - uint8_t immed_notify_count; /* Number of Immediate Notify */ - /* entries allocated. */ - uint16_t reserved_6; - uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ - uint16_t reserved_7[20]; -}modify_lun_entry_t; +struct modify_lun_entry { + uint8_t entry_type; /* Entry type. */ +#define MODIFY_LUN_TYPE 0xC /* Modify LUN entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t reserved_1; + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved_2; + uint8_t lun; /* SCSI LUN */ + uint8_t reserved_3; + uint8_t operators; + uint8_t reserved_4; + uint32_t option_flags; + uint8_t status; + uint8_t reserved_5; + uint8_t command_count; /* Number of ATIOs allocated. */ + uint8_t immed_notify_count; /* Number of Immediate Notify */ + /* entries allocated. */ + uint16_t reserved_6; + uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ + uint16_t reserved_7[20]; +}; /* * ISP queue - immediate notify entry structure definition. */ -typedef struct -{ - uint8_t entry_type; /* Entry type. */ - #define IMMED_NOTIFY_TYPE 0xD /* Immediate notify entry. */ - uint8_t entry_count; /* Entry count. */ - uint8_t reserved_1; - uint8_t entry_status; /* Entry Status. */ - uint32_t reserved_2; - uint8_t lun; - uint8_t initiator_id; - uint8_t reserved_3; - uint8_t target_id; - uint32_t option_flags; - uint8_t status; - uint8_t reserved_4; - uint8_t tag_value; /* Received queue tag message value */ - uint8_t tag_type; /* Received queue tag message type */ - /* entries allocated. */ - uint16_t seq_id; - uint8_t scsi_msg[8]; /* SCSI message not handled by ISP */ - uint16_t reserved_5[8]; - uint8_t sense_data[18]; -}notify_entry_t; +struct notify_entry { + uint8_t entry_type; /* Entry type. */ +#define IMMED_NOTIFY_TYPE 0xD /* Immediate notify entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t reserved_1; + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved_2; + uint8_t lun; + uint8_t initiator_id; + uint8_t reserved_3; + uint8_t target_id; + uint32_t option_flags; + uint8_t status; + uint8_t reserved_4; + uint8_t tag_value; /* Received queue tag message value */ + uint8_t tag_type; /* Received queue tag message type */ + /* entries allocated. */ + uint16_t seq_id; + uint8_t scsi_msg[8]; /* SCSI message not handled by ISP */ + uint16_t reserved_5[8]; + uint8_t sense_data[18]; +}; /* * ISP queue - notify acknowledge entry structure definition. */ -typedef struct -{ - uint8_t entry_type; /* Entry type. */ - #define NOTIFY_ACK_TYPE 0xE /* Notify acknowledge entry. */ - uint8_t entry_count; /* Entry count. */ - uint8_t reserved_1; - uint8_t entry_status; /* Entry Status. */ - uint32_t reserved_2; - uint8_t lun; - uint8_t initiator_id; - uint8_t reserved_3; - uint8_t target_id; - uint32_t option_flags; - uint8_t status; - uint8_t event; - uint16_t seq_id; - uint16_t reserved_4[22]; -}nack_entry_t; +struct nack_entry { + uint8_t entry_type; /* Entry type. */ +#define NOTIFY_ACK_TYPE 0xE /* Notify acknowledge entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t reserved_1; + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved_2; + uint8_t lun; + uint8_t initiator_id; + uint8_t reserved_3; + uint8_t target_id; + uint32_t option_flags; + uint8_t status; + uint8_t event; + uint16_t seq_id; + uint16_t reserved_4[22]; +}; /* * ISP queue - Accept Target I/O (ATIO) entry structure definition. */ -typedef struct -{ - uint8_t entry_type; /* Entry type. */ - #define ACCEPT_TGT_IO_TYPE 6 /* Accept target I/O entry. */ - uint8_t entry_count; /* Entry count. */ - uint8_t reserved_1; - uint8_t entry_status; /* Entry Status. */ - uint32_t reserved_2; - uint8_t lun; - uint8_t initiator_id; - uint8_t cdb_len; - uint8_t target_id; - uint32_t option_flags; - uint8_t status; - uint8_t scsi_status; - uint8_t tag_value; /* Received queue tag message value */ - uint8_t tag_type; /* Received queue tag message type */ - uint8_t cdb[26]; - uint8_t sense_data[18]; -}atio_entry_t; +struct atio_entry { + uint8_t entry_type; /* Entry type. */ +#define ACCEPT_TGT_IO_TYPE 6 /* Accept target I/O entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t reserved_1; + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved_2; + uint8_t lun; + uint8_t initiator_id; + uint8_t cdb_len; + uint8_t target_id; + uint32_t option_flags; + uint8_t status; + uint8_t scsi_status; + uint8_t tag_value; /* Received queue tag message value */ + uint8_t tag_type; /* Received queue tag message type */ + uint8_t cdb[26]; + uint8_t sense_data[18]; +}; /* * ISP queue - Continue Target I/O (CTIO) entry structure definition. */ -typedef struct -{ - uint8_t entry_type; /* Entry type. */ - #define CONTINUE_TGT_IO_TYPE 7 /* CTIO entry */ - uint8_t entry_count; /* Entry count. */ - uint8_t reserved_1; - uint8_t entry_status; /* Entry Status. */ - uint32_t reserved_2; - uint8_t lun; /* SCSI LUN */ - uint8_t initiator_id; - uint8_t reserved_3; - uint8_t target_id; - uint32_t option_flags; - uint8_t status; - uint8_t scsi_status; - uint8_t tag_value; /* Received queue tag message value */ - uint8_t tag_type; /* Received queue tag message type */ - uint32_t transfer_length; - uint32_t residual; - uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ - uint16_t dseg_count; /* Data segment count. */ - uint32_t dseg_0_address; /* Data segment 0 address. */ - uint32_t dseg_0_length; /* Data segment 0 length. */ - uint32_t dseg_1_address; /* Data segment 1 address. */ - uint32_t dseg_1_length; /* Data segment 1 length. */ - uint32_t dseg_2_address; /* Data segment 2 address. */ - uint32_t dseg_2_length; /* Data segment 2 length. */ - uint32_t dseg_3_address; /* Data segment 3 address. */ - uint32_t dseg_3_length; /* Data segment 3 length. */ -}ctio_entry_t; +struct ctio_entry { + uint8_t entry_type; /* Entry type. */ +#define CONTINUE_TGT_IO_TYPE 7 /* CTIO entry */ + uint8_t entry_count; /* Entry count. */ + uint8_t reserved_1; + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved_2; + uint8_t lun; /* SCSI LUN */ + uint8_t initiator_id; + uint8_t reserved_3; + uint8_t target_id; + uint32_t option_flags; + uint8_t status; + uint8_t scsi_status; + uint8_t tag_value; /* Received queue tag message value */ + uint8_t tag_type; /* Received queue tag message type */ + uint32_t transfer_length; + uint32_t residual; + uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ + uint16_t dseg_count; /* Data segment count. */ + uint32_t dseg_0_address; /* Data segment 0 address. */ + uint32_t dseg_0_length; /* Data segment 0 length. */ + uint32_t dseg_1_address; /* Data segment 1 address. */ + uint32_t dseg_1_length; /* Data segment 1 length. */ + uint32_t dseg_2_address; /* Data segment 2 address. */ + uint32_t dseg_2_length; /* Data segment 2 length. */ + uint32_t dseg_3_address; /* Data segment 3 address. */ + uint32_t dseg_3_length; /* Data segment 3 length. */ +}; /* * ISP queue - CTIO returned entry structure definition. */ -typedef struct -{ - uint8_t entry_type; /* Entry type. */ - #define CTIO_RET_TYPE 7 /* CTIO return entry */ - uint8_t entry_count; /* Entry count. */ - uint8_t reserved_1; - uint8_t entry_status; /* Entry Status. */ - uint32_t reserved_2; - uint8_t lun; /* SCSI LUN */ - uint8_t initiator_id; - uint8_t reserved_3; - uint8_t target_id; - uint32_t option_flags; - uint8_t status; - uint8_t scsi_status; - uint8_t tag_value; /* Received queue tag message value */ - uint8_t tag_type; /* Received queue tag message type */ - uint32_t transfer_length; - uint32_t residual; - uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ - uint16_t dseg_count; /* Data segment count. */ - uint32_t dseg_0_address; /* Data segment 0 address. */ - uint32_t dseg_0_length; /* Data segment 0 length. */ - uint32_t dseg_1_address; /* Data segment 1 address. */ - uint16_t dseg_1_length; /* Data segment 1 length. */ - uint8_t sense_data[18]; -}ctio_ret_entry_t; +struct ctio_ret_entry { + uint8_t entry_type; /* Entry type. */ +#define CTIO_RET_TYPE 7 /* CTIO return entry */ + uint8_t entry_count; /* Entry count. */ + uint8_t reserved_1; + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved_2; + uint8_t lun; /* SCSI LUN */ + uint8_t initiator_id; + uint8_t reserved_3; + uint8_t target_id; + uint32_t option_flags; + uint8_t status; + uint8_t scsi_status; + uint8_t tag_value; /* Received queue tag message value */ + uint8_t tag_type; /* Received queue tag message type */ + uint32_t transfer_length; + uint32_t residual; + uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ + uint16_t dseg_count; /* Data segment count. */ + uint32_t dseg_0_address; /* Data segment 0 address. */ + uint32_t dseg_0_length; /* Data segment 0 length. */ + uint32_t dseg_1_address; /* Data segment 1 address. */ + uint16_t dseg_1_length; /* Data segment 1 length. */ + uint8_t sense_data[18]; +}; /* * ISP queue - CTIO A64 entry structure definition. */ -typedef struct -{ - uint8_t entry_type; /* Entry type. */ - #define CTIO_A64_TYPE 0xF /* CTIO A64 entry */ - uint8_t entry_count; /* Entry count. */ - uint8_t reserved_1; - uint8_t entry_status; /* Entry Status. */ - uint32_t reserved_2; - uint8_t lun; /* SCSI LUN */ - uint8_t initiator_id; - uint8_t reserved_3; - uint8_t target_id; - uint32_t option_flags; - uint8_t status; - uint8_t scsi_status; - uint8_t tag_value; /* Received queue tag message value */ - uint8_t tag_type; /* Received queue tag message type */ - uint32_t transfer_length; - uint32_t residual; - uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ - uint16_t dseg_count; /* Data segment count. */ - uint32_t reserved_4[2]; - uint32_t dseg_0_address[2]; /* Data segment 0 address. */ - uint32_t dseg_0_length; /* Data segment 0 length. */ - uint32_t dseg_1_address[2]; /* Data segment 1 address. */ - uint32_t dseg_1_length; /* Data segment 1 length. */ -}ctio_a64_entry_t; +struct ctio_a64_entry { + uint8_t entry_type; /* Entry type. */ +#define CTIO_A64_TYPE 0xF /* CTIO A64 entry */ + uint8_t entry_count; /* Entry count. */ + uint8_t reserved_1; + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved_2; + uint8_t lun; /* SCSI LUN */ + uint8_t initiator_id; + uint8_t reserved_3; + uint8_t target_id; + uint32_t option_flags; + uint8_t status; + uint8_t scsi_status; + uint8_t tag_value; /* Received queue tag message value */ + uint8_t tag_type; /* Received queue tag message type */ + uint32_t transfer_length; + uint32_t residual; + uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ + uint16_t dseg_count; /* Data segment count. */ + uint32_t reserved_4[2]; + uint32_t dseg_0_address[2]; /* Data segment 0 address. */ + uint32_t dseg_0_length; /* Data segment 0 length. */ + uint32_t dseg_1_address[2]; /* Data segment 1 address. */ + uint32_t dseg_1_length; /* Data segment 1 length. */ +}; /* * ISP queue - CTIO returned entry structure definition. */ -typedef struct -{ - uint8_t entry_type; /* Entry type. */ - #define CTIO_A64_RET_TYPE 0xF /* CTIO A64 returned entry */ - uint8_t entry_count; /* Entry count. */ - uint8_t reserved_1; - uint8_t entry_status; /* Entry Status. */ - uint32_t reserved_2; - uint8_t lun; /* SCSI LUN */ - uint8_t initiator_id; - uint8_t reserved_3; - uint8_t target_id; - uint32_t option_flags; - uint8_t status; - uint8_t scsi_status; - uint8_t tag_value; /* Received queue tag message value */ - uint8_t tag_type; /* Received queue tag message type */ - uint32_t transfer_length; - uint32_t residual; - uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ - uint16_t dseg_count; /* Data segment count. */ - uint16_t reserved_4[7]; - uint8_t sense_data[18]; -}ctio_a64_ret_entry_t; +struct ctio_a64_ret_entry { + uint8_t entry_type; /* Entry type. */ +#define CTIO_A64_RET_TYPE 0xF /* CTIO A64 returned entry */ + uint8_t entry_count; /* Entry count. */ + uint8_t reserved_1; + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved_2; + uint8_t lun; /* SCSI LUN */ + uint8_t initiator_id; + uint8_t reserved_3; + uint8_t target_id; + uint32_t option_flags; + uint8_t status; + uint8_t scsi_status; + uint8_t tag_value; /* Received queue tag message value */ + uint8_t tag_type; /* Received queue tag message type */ + uint32_t transfer_length; + uint32_t residual; + uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ + uint16_t dseg_count; /* Data segment count. */ + uint16_t reserved_4[7]; + uint8_t sense_data[18]; +}; /* * ISP request and response queue entry sizes */ -#define RESPONSE_ENTRY_SIZE (sizeof(response_t)) -#define REQUEST_ENTRY_SIZE (sizeof(request_t)) +#define RESPONSE_ENTRY_SIZE (sizeof(struct response)) +#define REQUEST_ENTRY_SIZE (sizeof(request_t)) /* * ISP status entry - completion status definitions. */ -#define CS_COMPLETE 0x0 /* No errors */ -#define CS_INCOMPLETE 0x1 /* Incomplete transfer of cmd. */ -#define CS_DMA 0x2 /* A DMA direction error. */ -#define CS_TRANSPORT 0x3 /* Transport error. */ -#define CS_RESET 0x4 /* SCSI bus reset occurred */ -#define CS_ABORTED 0x5 /* System aborted command. */ -#define CS_TIMEOUT 0x6 /* Timeout error. */ -#define CS_DATA_OVERRUN 0x7 /* Data overrun. */ -#define CS_COMMAND_OVERRUN 0x8 /* Command Overrun. */ -#define CS_STATUS_OVERRUN 0x9 /* Status Overrun. */ -#define CS_BAD_MSG 0xA /* Bad msg after status phase. */ -#define CS_NO_MSG_OUT 0xB /* No msg out after selection. */ -#define CS_EXTENDED_ID 0xC /* Extended ID failed. */ -#define CS_IDE_MSG 0xD /* Target rejected IDE msg. */ -#define CS_ABORT_MSG 0xE /* Target rejected abort msg. */ -#define CS_REJECT_MSG 0xF /* Target rejected reject msg. */ -#define CS_NOP_MSG 0x10 /* Target rejected NOP msg. */ -#define CS_PARITY_MSG 0x11 /* Target rejected parity msg. */ -#define CS_DEV_RESET_MSG 0x12 /* Target rejected dev rst msg. */ -#define CS_ID_MSG 0x13 /* Target rejected ID msg. */ -#define CS_FREE 0x14 /* Unexpected bus free. */ -#define CS_DATA_UNDERRUN 0x15 /* Data Underrun. */ -#define CS_TRANACTION_1 0x18 /* Transaction error 1 */ -#define CS_TRANACTION_2 0x19 /* Transaction error 2 */ -#define CS_TRANACTION_3 0x1a /* Transaction error 3 */ -#define CS_INV_ENTRY_TYPE 0x1b /* Invalid entry type */ -#define CS_DEV_QUEUE_FULL 0x1c /* Device queue full */ -#define CS_PHASED_SKIPPED 0x1d /* SCSI phase skipped */ -#define CS_ARS_FAILED 0x1e /* ARS failed */ -#define CS_LVD_BUS_ERROR 0x21 /* LVD bus error */ -#define CS_BAD_PAYLOAD 0x80 /* Driver defined */ -#define CS_UNKNOWN 0x81 /* Driver defined */ -#define CS_RETRY 0x82 /* Driver defined */ +#define CS_COMPLETE 0x0 /* No errors */ +#define CS_INCOMPLETE 0x1 /* Incomplete transfer of cmd. */ +#define CS_DMA 0x2 /* A DMA direction error. */ +#define CS_TRANSPORT 0x3 /* Transport error. */ +#define CS_RESET 0x4 /* SCSI bus reset occurred */ +#define CS_ABORTED 0x5 /* System aborted command. */ +#define CS_TIMEOUT 0x6 /* Timeout error. */ +#define CS_DATA_OVERRUN 0x7 /* Data overrun. */ +#define CS_COMMAND_OVERRUN 0x8 /* Command Overrun. */ +#define CS_STATUS_OVERRUN 0x9 /* Status Overrun. */ +#define CS_BAD_MSG 0xA /* Bad msg after status phase. */ +#define CS_NO_MSG_OUT 0xB /* No msg out after selection. */ +#define CS_EXTENDED_ID 0xC /* Extended ID failed. */ +#define CS_IDE_MSG 0xD /* Target rejected IDE msg. */ +#define CS_ABORT_MSG 0xE /* Target rejected abort msg. */ +#define CS_REJECT_MSG 0xF /* Target rejected reject msg. */ +#define CS_NOP_MSG 0x10 /* Target rejected NOP msg. */ +#define CS_PARITY_MSG 0x11 /* Target rejected parity msg. */ +#define CS_DEV_RESET_MSG 0x12 /* Target rejected dev rst msg. */ +#define CS_ID_MSG 0x13 /* Target rejected ID msg. */ +#define CS_FREE 0x14 /* Unexpected bus free. */ +#define CS_DATA_UNDERRUN 0x15 /* Data Underrun. */ +#define CS_TRANACTION_1 0x18 /* Transaction error 1 */ +#define CS_TRANACTION_2 0x19 /* Transaction error 2 */ +#define CS_TRANACTION_3 0x1a /* Transaction error 3 */ +#define CS_INV_ENTRY_TYPE 0x1b /* Invalid entry type */ +#define CS_DEV_QUEUE_FULL 0x1c /* Device queue full */ +#define CS_PHASED_SKIPPED 0x1d /* SCSI phase skipped */ +#define CS_ARS_FAILED 0x1e /* ARS failed */ +#define CS_LVD_BUS_ERROR 0x21 /* LVD bus error */ +#define CS_BAD_PAYLOAD 0x80 /* Driver defined */ +#define CS_UNKNOWN 0x81 /* Driver defined */ +#define CS_RETRY 0x82 /* Driver defined */ /* * ISP status entry - SCSI status byte bit definitions. @@ -1454,282 +970,143 @@ /* * ISP target entries - Option flags bit definitions. */ -#define OF_ENABLE_TAG BIT_1 /* Tagged queue action enable */ -#define OF_DATA_IN BIT_6 /* Data in to initiator */ - /* (data from target to initiator) */ -#define OF_DATA_OUT BIT_7 /* Data out from initiator */ - /* (data from initiator to target) */ +#define OF_ENABLE_TAG BIT_1 /* Tagged queue action enable */ +#define OF_DATA_IN BIT_6 /* Data in to initiator */ + /* (data from target to initiator) */ +#define OF_DATA_OUT BIT_7 /* Data out from initiator */ + /* (data from initiator to target) */ #define OF_NO_DATA (BIT_7 | BIT_6) -#define OF_DISC_DISABLED BIT_15 /* Disconnects disabled */ -#define OF_DISABLE_SDP BIT_24 /* Disable sending save data ptr */ -#define OF_SEND_RDP BIT_26 /* Send restore data pointers msg */ -#define OF_FORCE_DISC BIT_30 /* Disconnects mandatory */ -#define OF_SSTS BIT_31 /* Send SCSI status */ - -#if QL1280_TARGET_MODE_SUPPORT -/* - * Target Read/Write buffer structure. - */ -#define TARGET_DATA_OFFSET 4 -#define TARGET_DATA_SIZE 0x2000 /* 8K */ -#define TARGET_INQ_OFFSET (TARGET_DATA_OFFSET + TARGET_DATA_SIZE) -#define TARGET_SENSE_SIZE 18 -#define TARGET_BUF_SIZE 36 - -typedef struct -{ - uint8_t hdr[4]; - uint8_t data[TARGET_DATA_SIZE]; - struct ident inq; -}tgt_t; -#endif +#define OF_DISC_DISABLED BIT_15 /* Disconnects disabled */ +#define OF_DISABLE_SDP BIT_24 /* Disable sending save data ptr */ +#define OF_SEND_RDP BIT_26 /* Send restore data pointers msg */ +#define OF_FORCE_DISC BIT_30 /* Disconnects mandatory */ +#define OF_SSTS BIT_31 /* Send SCSI status */ + /* - * BUS parameters/settings structure - */ -typedef struct -{ - uint8_t id; /* Host adapter SCSI id */ - uint8_t bus_reset_delay; /* SCSI bus reset delay. */ - uint8_t failed_reset_count; /* number of time reset failed */ - uint8_t unused; - uint16_t device_enables; /* Device enable bits. */ - uint16_t lun_disables; /* LUN disable bits. */ - uint16_t qtag_enables; /* Tag queue enables. */ - uint16_t hiwat; /* High water mark per device. */ - uint8_t reset_marker :1; - uint8_t disable_scsi_reset :1; - uint8_t scsi_bus_dead :1; /* SCSI Bus is Dead, when 5 back to back resets failed */ + * BUS parameters/settings structure - UNUSED + */ +struct bus_param { + uint8_t id; /* Host adapter SCSI id */ + uint8_t bus_reset_delay; /* SCSI bus reset delay. */ + uint8_t failed_reset_count; /* number of time reset failed */ + uint8_t unused; + uint16_t device_enables; /* Device enable bits. */ + uint16_t lun_disables; /* LUN disable bits. */ + uint16_t qtag_enables; /* Tag queue enables. */ + uint16_t hiwat; /* High water mark per device. */ + uint8_t reset_marker:1; + uint8_t disable_scsi_reset:1; + uint8_t scsi_bus_dead:1; /* SCSI Bus is Dead, when 5 back to back resets failed */ +}; + + +struct qla_driver_setup { + uint32_t no_sync:1; + uint32_t no_wide:1; + uint32_t no_ppr:1; + uint32_t no_nvram:1; + uint16_t sync_mask; + uint16_t wide_mask; + uint16_t ppr_mask; +}; -}bus_param_t; /* * Linux Host Adapter structure */ -typedef struct scsi_qla_host -{ - /* Linux adapter configuration data */ - struct Scsi_Host *host; /* pointer to host data */ - struct scsi_qla_host *next; - device_reg_t *iobase; /* Base Memory-mapped I/O address */ - uint8_t pci_bus; - uint8_t pci_device_fn; - uint8_t devnum; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95) - struct pci_dev *pdev; +struct scsi_qla_host { + /* Linux adapter configuration data */ + struct Scsi_Host *host; /* pointer to host data */ + struct scsi_qla_host *next; + struct device_reg *iobase; /* Base Memory-mapped I/O address */ + + unsigned char *mmpbase; /* memory mapped address */ + unsigned long host_no; + unsigned long instance; + struct pci_dev *pdev; + uint32_t device_id; + uint8_t pci_bus; + uint8_t pci_device_fn; + uint8_t devnum; + uint8_t revision; + uint8_t ports; + + unsigned long actthreads; + unsigned long isr_count; /* Interrupt count */ + unsigned long spurious_int; + + /* Outstandings ISP commands. */ + struct srb *outstanding_cmds[MAX_OUTSTANDING_COMMANDS]; + + /* BUS configuration data */ + struct bus_param bus_settings[MAX_BUSES]; + +#if 0 + /* bottom half run queue */ + struct tq_struct run_qla_bh; #endif - volatile unsigned char *mmpbase; /* memory mapped address */ - unsigned long host_no; - unsigned long instance; - uint8_t revision; - uint8_t ports; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0) - spinlock_t spin_lock; -#endif - volatile unsigned char cpu_lock_count[NR_CPUS]; - unsigned long actthreads; - unsigned long qthreads; - unsigned long isr_count; /* Interrupt count */ - unsigned long spurious_int; - - uint32_t device_id; - - /* Outstandings ISP commands. */ - srb_t *outstanding_cmds[MAX_OUTSTANDING_COMMANDS]; - /* BUS configuration data */ - bus_param_t bus_settings[MAX_BUSES]; - - /* Device LUN queues. */ - scsi_lu_t *dev[MAX_EQ]; /* Logical unit queues */ + /* Received ISP mailbox data. */ + volatile uint16_t mailbox_out[MAILBOX_REGISTER_COUNT]; #ifdef UNUSED - /* Interrupt lock, and data */ - uint8_t intr_lock; /* Lock for interrupt locking */ + struct timer_list dev_timer[MAX_TARGETS]; #endif - /* bottom half run queue */ - struct tq_struct run_qla_bh; - - /* Received ISP mailbox data. */ - volatile uint16_t mailbox_out[MAILBOX_REGISTER_COUNT]; - -#ifdef UNUSED - /* ISP ring lock, rings, and indexes */ - uint8_t ring_lock; /* ISP ring lock */ - struct timer_list dev_timer[MAX_TARGETS]; + dma_addr_t request_dma; /* Physical Address */ + request_t *request_ring; /* Base virtual address */ + request_t *request_ring_ptr; /* Current address. */ + uint16_t req_ring_index; /* Current index. */ + uint16_t req_q_cnt; /* Number of available entries. */ + + dma_addr_t response_dma; /* Physical address. */ + struct response *response_ring; /* Base virtual address */ + struct response *response_ring_ptr; /* Current address. */ + uint16_t rsp_ring_index; /* Current index. */ + +#if WATCHDOGTIMER + /* Watchdog queue, lock and total timer */ + uint8_t watchdog_q_lock; /* Lock for watchdog queue */ + struct srb *wdg_q_first; /* First job on watchdog queue */ + struct srb *wdg_q_last; /* Last job on watchdog queue */ + uint32_t total_timeout; /* Total timeout (quantum count) */ + uint32_t watchdogactive; #endif - request_t req[REQUEST_ENTRY_CNT+1]; - response_t res[RESPONSE_ENTRY_CNT+1]; - unsigned long request_dma; /* Physical address. */ - request_t *request_ring; /* Base virtual address */ - request_t *request_ring_ptr; /* Current address. */ - uint16_t req_ring_index; /* Current index. */ - uint16_t req_q_cnt; /* Number of available entries. */ - - unsigned long response_dma; /* Physical address. */ - response_t *response_ring; /* Base virtual address */ - response_t *response_ring_ptr; /* Current address. */ - uint16_t rsp_ring_index; /* Current index. */ - -#if QL1280_TARGET_MODE_SUPPORT - /* Target buffer and sense data. */ - uint32_t tbuf_dma; /* Physical address. */ - tgt_t *tbuf; - uint32_t tsense_dma; /* Physical address. */ - uint8_t *tsense; -#endif + struct srb *done_q_first; /* First job on done queue */ + struct srb *done_q_last; /* Last job on done queue */ -#if WATCHDOGTIMER - /* Watchdog queue, lock and total timer */ - uint8_t watchdog_q_lock; /* Lock for watchdog queue */ - srb_t *wdg_q_first; /* First job on watchdog queue */ - srb_t *wdg_q_last; /* Last job on watchdog queue */ - uint32_t total_timeout; /* Total timeout (quantum count) */ - uint32_t watchdogactive; -#endif - - srb_t *done_q_first; /* First job on done queue */ - srb_t *done_q_last; /* Last job on done queue */ + struct completion *mailbox_wait; - volatile struct - { - uint32_t watchdog_enabled :1; /* 0 */ - uint32_t mbox_int :1; /* 1 */ - uint32_t mbox_busy :1; /* 2 */ - uint32_t online :1; /* 3 */ - uint32_t reset_marker :1; /* 4 */ - uint32_t isp_abort_needed :1; /* 5 */ - uint32_t pci_64bit_slot :1; /* 6 */ - uint32_t disable_host_adapter :1; /* 7 */ - uint32_t reset_active :1; /* 8 */ - uint32_t abort_isp_active :1; /* 9 */ - uint32_t disable_risc_code_load :1; /* 10 */ - uint32_t enable_64bit_addressing :1; /* 11 */ -#define QLA1280_IN_ISR_BIT 12 - uint32_t in_isr :1; /* 12 */ - uint32_t in_abort :1; /* 13 */ - uint32_t in_reset :1; /* 14 */ - uint32_t dpc :1; /* 15 */ - uint32_t dpc_sched :1; /* 16 */ - uint32_t interrupts_on :1; /* 17 */ - }flags; + volatile struct { + uint32_t mbox_busy:1; /* 0 */ + uint32_t online:1; /* 1 */ + uint32_t reset_marker:1; /* 2 */ + uint32_t disable_host_adapter:1; /* 4 */ + uint32_t reset_active:1; /* 5 */ + uint32_t abort_isp_active:1; /* 6 */ + uint32_t disable_risc_code_load:1; /* 7 */ + uint32_t enable_64bit_addressing:1; /* 8 */ + uint32_t in_reset:1; /* 9 */ + uint32_t ints_enabled:1; + uint32_t ignore_nvram:1; +#ifdef __ia64__ + uint32_t use_pci_vchannel:1; +#endif + } flags; -}scsi_qla_host_t; + struct nvram nvram; + int nvram_valid; +}; /* * Macros to help code, maintain, etc. */ -#define SUBDEV(b, t, l) ( (b << (MAX_T_BITS + MAX_L_BITS)) | (t << MAX_L_BITS) | l) -#define LU_Q(ha, b, t, l) (ha->dev[SUBDEV(b, t, l)]) - -/* - * Locking Macro Definitions - * - * LOCK/UNLOCK definitions are lock/unlock primitives for multi-processor - * or spl/splx for uniprocessor. - */ -#define QLA1280_HIER HBA_HIER_BASE /* Locking hierarchy base for hba */ - -#define QLA1280_WATCHDOG_Q_LOCK(ha, p) -#define QLA1280_WATCHDOG_Q_UNLOCK(ha, p) - -#define QLA1280_SCSILU_LOCK(q) -#define QLA1280_SCSILU_UNLOCK(q) - -#define QLA1280_INTR_LOCK(ha) -#define QLA1280_INTR_UNLOCK(ha) +#define SUBDEV(b, t, l) ((b << (MAX_T_BITS + MAX_L_BITS)) | (t << MAX_L_BITS) | l) +#define LU_Q(ha, b, t, l) (ha->dev[SUBDEV(b, t, l)]) -#define QLA1280_RING_LOCK(ha) -#define QLA1280_RING_UNLOCK(ha) - -#if defined(__cplusplus) -} -#endif -/* - * Linux - SCSI Driver Interface Function Prototypes. - */ -int qla1280_proc_info ( char *, char **, off_t, int, int, int); -const char * qla1280_info(struct Scsi_Host *host); -int qla1280_detect(Scsi_Host_Template *); -int qla1280_release(struct Scsi_Host *); -const char * qla1280_info(struct Scsi_Host *); -int qla1280_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *)); -int qla1280_abort(Scsi_Cmnd *); -int qla1280_reset(Scsi_Cmnd *, unsigned int); -int qla1280_biosparam(Disk *, kdev_t, int[]); -void qla1280_intr_handler(int, void *, struct pt_regs *); -void qla1280_setup(char *s, int *dummy); -#if defined(__386__) -# define QLA1280_BIOSPARAM qla1280_biosparam -#else -# define QLA1280_BIOSPARAM NULL -#endif - -/* - * Scsi_Host_template (see hosts.h) - * Device driver Interfaces to mid-level SCSI driver. - */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) -/* This interface is now obsolete !!! */ -#define QLA1280_LINUX_TEMPLATE { \ - next: NULL, \ - usage_count: NULL, \ - proc_dir: NULL, \ - proc_info: NULL, \ - name: "Qlogic ISP 1280", \ - detect: qla1280_detect, \ - release: qla1280_release, \ - info: qla1280_info, \ - command: NULL, \ - queuecommand: qla1280_queuecommand, \ - abort: qla1280_abort, \ - reset: qla1280_reset, \ - slave_attach: NULL, \ - bios_param: QLA1280_BIOSPARAM, \ - can_queue: 255, /* MAX_OUTSTANDING_COMMANDS */ \ - this_id: -1, /* scsi id of host adapter */ \ - sg_tablesize: SG_ALL, \ - cmd_per_lun: 3, /* max commands per lun */ \ - present: 0, /* number of 1280s present */ \ - unchecked_isa_dma: 0, /* no memeory DMA restrictions */ \ - use_clustering: ENABLE_CLUSTERING \ -} -#else - -#define QLA1280_LINUX_TEMPLATE { \ - next: NULL, \ - module: NULL, \ - proc_dir: NULL, \ - proc_info: qla1280_proc_info, \ - name: "Qlogic ISP 1280\1080", \ - detect: qla1280_detect, \ - release: qla1280_release, \ - info: qla1280_info, \ - ioctl: NULL, \ - command: NULL, \ - queuecommand: qla1280_queuecommand, \ - eh_strategy_handler: NULL, \ - eh_abort_handler: NULL, \ - eh_device_reset_handler: NULL, \ - eh_bus_reset_handler: NULL, \ - eh_host_reset_handler: NULL, \ - abort: qla1280_abort, \ - reset: qla1280_reset, \ - slave_attach: NULL, \ - bios_param: QLA1280_BIOSPARAM, \ - can_queue: 255, /* max simultaneous cmds */\ - this_id: -1, /* scsi id of host adapter */\ - sg_tablesize: SG_ALL, /* max scatter-gather cmds */\ - cmd_per_lun: 3, /* cmds per lun (linked cmds) */\ - present: 0, /* number of 7xxx's present */\ - unchecked_isa_dma: 0, /* no memory DMA restrictions */\ - use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 0, \ - emulated: 0 \ -} -#endif +#endif /* HOSTS_C */ -#endif /* _IO_HBA_QLA1280_H */ +#endif /* _IO_HBA_QLA1280_H */ Index: drivers/scsi/qlogicfas.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/qlogicfas.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/qlogicfas.c 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/qlogicfas.c 4 Aug 2004 01:29:36 -0000 1.2 @@ -111,10 +111,6 @@ #include -#ifdef PCMCIA -#undef MODULE -#endif - #include /* to get disk capacity */ #include #include @@ -131,6 +127,10 @@ #include "qlogicfas.h" #include +#ifdef PCMCIA +#undef MODULE +#endif + /*----------------------------------------------------------------*/ /* driver state info, local to driver */ static int qbase; /* Port */ @@ -647,7 +647,7 @@ if(request_irq(qlirq, do_ql_ihandl, SA_SHIRQ, "qlogicfas", hreg) < 0) #endif { - scsi_unregister(host); + scsi_unregister(hreg); goto err_release_mem; } #endif @@ -717,7 +717,9 @@ } MODULE_LICENSE("GPL"); +#ifndef PCMCIA /* Eventually this will go into an include file, but this will be later */ static Scsi_Host_Template driver_template = QLOGICFAS; #include "scsi_module.c" +#endif Index: drivers/scsi/qlogicfc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/qlogicfc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/qlogicfc.c 22 Jul 2004 19:50:01 -0000 1.1 +++ drivers/scsi/qlogicfc.c 4 Aug 2004 01:29:36 -0000 1.2 @@ -27,12 +27,12 @@ */ /* - * $Date: 2004/07/22 19:50:01 $ - * $Revision: 1.1 $ + * $Date: 2004/08/04 01:29:36 $ + * $Revision: 1.2 $ * * $Log: qlogicfc.c,v $ - * Revision 1.1 2004/07/22 19:50:01 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:36 joff + * merging 2.4.26-vrs1 * * Revision 0.5 1995/09/22 02:23:15 root * do auto request sense @@ -414,7 +414,7 @@ if that mbox should be copied as input. For example 0x2 would mean only copy mbox1. */ -const u_char mbox_param[] = +static const u_char mbox_param[] = { 0x01, /* MBOX_NO_OP */ 0x1f, /* MBOX_LOAD_RAM */ Index: drivers/scsi/qlogicfc.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/qlogicfc.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/qlogicfc.h 22 Jul 2004 19:50:01 -0000 1.1 +++ drivers/scsi/qlogicfc.h 4 Aug 2004 01:29:37 -0000 1.2 @@ -23,12 +23,12 @@ /* - * $Date: 2004/07/22 19:50:01 $ - * $Revision: 1.1 $ + * $Date: 2004/08/04 01:29:37 $ + * $Revision: 1.2 $ * * $Log: qlogicfc.h,v $ - * Revision 1.1 2004/07/22 19:50:01 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:37 joff + * merging 2.4.26-vrs1 * * Revision 0.5 1995/09/22 02:32:56 root * do auto request sense Index: drivers/scsi/qlogicisp.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/qlogicisp.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/qlogicisp.h 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/qlogicisp.h 4 Aug 2004 01:29:37 -0000 1.2 @@ -17,12 +17,12 @@ /* Renamed and updated to 1.3.x by Michael Griffith */ /* - * $Date: 2004/07/22 19:50:02 $ - * $Revision: 1.1 $ + * $Date: 2004/08/04 01:29:37 $ + * $Revision: 1.2 $ * * $Log: qlogicisp.h,v $ - * Revision 1.1 2004/07/22 19:50:02 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:37 joff + * merging 2.4.26-vrs1 * * Revision 0.5 1995/09/22 02:32:56 root * do auto request sense Index: drivers/scsi/qlogicpti.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/qlogicpti.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/qlogicpti.c 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/qlogicpti.c 4 Aug 2004 01:29:37 -0000 1.2 @@ -53,7 +53,7 @@ #define PACKB(a, b) (((a)<<4)|(b)) -const u_char mbox_param[] = { +static const u_char mbox_param[] = { PACKB(1, 1), /* MBOX_NO_OP */ PACKB(5, 5), /* MBOX_LOAD_RAM */ PACKB(2, 0), /* MBOX_EXEC_FIRMWARE */ Index: drivers/scsi/scsi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/scsi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/scsi.c 22 Jul 2004 19:50:05 -0000 1.1 +++ drivers/scsi/scsi.c 4 Aug 2004 01:29:37 -0000 1.2 @@ -84,7 +84,7 @@ #endif /* - static const char RCSid[] = "$Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/scsi.c,v 1.1 2004/07/22 19:50:05 joff Exp $"; + static const char RCSid[] = "$Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/scsi.c,v 1.2 2004/08/04 01:29:37 joff Exp $"; */ /* @@ -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; } Index: drivers/scsi/scsi.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/scsi.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/scsi.h 22 Jul 2004 19:50:05 -0000 1.1 +++ drivers/scsi/scsi.h 4 Aug 2004 01:29:37 -0000 1.2 @@ -610,6 +610,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; Index: drivers/scsi/scsi_error.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/scsi_error.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/scsi_error.c 22 Jul 2004 19:50:03 -0000 1.1 +++ drivers/scsi/scsi_error.c 4 Aug 2004 01:29:37 -0000 1.2 @@ -78,7 +78,7 @@ #define HOST_RESET_SETTLE_TIME 10*HZ -static const char RCSid[] = "$Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/scsi_error.c,v 1.1 2004/07/22 19:50:03 joff Exp $"; +static const char RCSid[] = "$Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/scsi_error.c,v 1.2 2004/08/04 01:29:37 joff Exp $"; STATIC int scsi_check_sense(Scsi_Cmnd * SCpnt); STATIC int scsi_request_sense(Scsi_Cmnd *); @@ -119,25 +119,13 @@ int timeout, void (*complete) (Scsi_Cmnd *)) { - - /* - * If the clock was already running for this command, then - * first delete the timer. The timer handling code gets rather - * confused if we don't do this. - */ - if (SCset->eh_timeout.function != NULL) { - del_timer(&SCset->eh_timeout); - } SCset->eh_timeout.data = (unsigned long) SCset; - SCset->eh_timeout.expires = jiffies + timeout; SCset->eh_timeout.function = (void (*)(unsigned long)) complete; + mod_timer(&SCset->eh_timeout, jiffies + timeout); SCset->done_late = 0; SCSI_LOG_ERROR_RECOVERY(5, printk("Adding timer for command %p at %d (%p)\n", SCset, timeout, complete)); - - add_timer(&SCset->eh_timeout); - } /* Index: drivers/scsi/scsi_ioctl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/scsi_ioctl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/scsi_ioctl.c 22 Jul 2004 19:50:07 -0000 1.1 +++ drivers/scsi/scsi_ioctl.c 4 Aug 2004 01:29:37 -0000 1.2 @@ -302,6 +302,7 @@ cmd[1] = (cmd[1] & 0x1f) | (dev->lun << 5); switch (opcode) { + case SEND_DIAGNOSTIC: case FORMAT_UNIT: timeout = FORMAT_UNIT_TIMEOUT; retries = 1; Index: drivers/scsi/scsi_lib.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/scsi_lib.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/scsi_lib.c 22 Jul 2004 19:50:01 -0000 1.1 +++ drivers/scsi/scsi_lib.c 4 Aug 2004 01:29:37 -0000 1.2 @@ -402,6 +402,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; @@ -428,6 +429,14 @@ */ if (req->bh) { /* + * Recount segments whether we are immediately going to + * requeue the command or not, other code might requeue + * it later and since we changed the segment count up above, + * we need it updated. + */ + recount_segments(SCpnt); + + /* * Bleah. Leftovers again. Stick the leftovers in * the front of the queue, and goose the queue again. */ @@ -998,15 +1007,6 @@ */ if( req->special != NULL ) { SCpnt = (Scsi_Cmnd *) req->special; - /* - * We need to recount the number of - * scatter-gather segments here - the - * normal case code assumes this to be - * correct, as it would be a performance - * lose to always recount. Handling - * errors is always unusual, of course. - */ - recount_segments(SCpnt); } else { SCpnt = scsi_allocate_device(SDpnt, FALSE, FALSE); } Index: drivers/scsi/scsi_obsolete.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/scsi_obsolete.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/scsi_obsolete.c 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/scsi_obsolete.c 4 Aug 2004 01:29:37 -0000 1.2 @@ -71,7 +71,7 @@ #undef USE_STATIC_SCSI_MEMORY /* - static const char RCSid[] = "$Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/scsi_obsolete.c,v 1.1 2004/07/22 19:50:02 joff Exp $"; + static const char RCSid[] = "$Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/scsi_obsolete.c,v 1.2 2004/08/04 01:29:37 joff Exp $"; */ Index: drivers/scsi/scsi_queue.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/scsi_queue.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/scsi_queue.c 22 Jul 2004 19:50:02 -0000 1.1 +++ drivers/scsi/scsi_queue.c 4 Aug 2004 01:29:37 -0000 1.2 @@ -54,7 +54,7 @@ * 7) Don't send down any more commands if the host/device is busy. */ -static const char RCSid[] = "$Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/scsi_queue.c,v 1.1 2004/07/22 19:50:02 joff Exp $"; +static const char RCSid[] = "$Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/scsi_queue.c,v 1.2 2004/08/04 01:29:37 joff Exp $"; /* Index: drivers/scsi/scsi_scan.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/scsi_scan.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/scsi_scan.c 22 Jul 2004 19:50:05 -0000 1.1 +++ drivers/scsi/scsi_scan.c 4 Aug 2004 01:29:37 -0000 1.2 @@ -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,10 @@ {"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 Va7110 Array */ + {"HP", "A6218A", "*", 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 +148,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 +176,11 @@ {"HP", "NetRAID-4M", "*", BLIST_FORCELUN}, {"ADAPTEC", "AACRAID", "*", BLIST_FORCELUN}, {"ADAPTEC", "Adaptec 5400S", "*", BLIST_FORCELUN}, - {"COMPAQ", "MSA1000", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, + {"APPLE", "Xserve", "*", 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 +189,8 @@ {"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 */ + {"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, /* HITACHI 9960 */ {"WINSYS","FLASHDISK G6", "*", BLIST_SPARSELUN}, {"DotHill","SANnet RAID X300", "*", BLIST_SPARSELUN}, {"SUN", "T300", "*", BLIST_SPARSELUN}, @@ -194,6 +202,12 @@ {"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}, + {"NEC", "iStorage", "*", BLIST_SPARSELUN | BLIST_LARGELUN | BLIST_FORCELUN}, /* * Must be at end of list... @@ -209,10 +223,14 @@ static unsigned int max_scsi_luns = 1; #endif +static unsigned int scsi_allow_ghost_devices = 0; + #ifdef MODULE MODULE_PARM(max_scsi_luns, "i"); MODULE_PARM_DESC(max_scsi_luns, "last scsi LUN (should be between 1 and 2^32-1)"); +MODULE_PARM(scsi_allow_ghost_devices, "i"); +MODULE_PARM_DESC(scsi_allow_ghost_devices, "allow devices marked as being offline to be accessed anyway (0 = off, else allow ghosts on lun 0 through scsi_allow_ghost_devices - 1"); #else @@ -232,6 +250,21 @@ __setup("max_scsi_luns=", scsi_luns_setup); +static int __init scsi_allow_ghost_devices_setup(char *str) +{ + unsigned int tmp; + + if (get_option(&str, &tmp) == 1) { + scsi_allow_ghost_devices = tmp; + return 1; + } else { + printk("scsi_allow_ghost_devices_setup: usage scsi_allow_ghost_devices=n (0: off else\nallow ghost devices (ghost devices are devices that report themselves as\nbeing offline but which we allow access to anyway) on lun 0 through n - 1.\n"); + return 0; + } +} + +__setup("scsi_allow_ghost_devices=", scsi_allow_ghost_devices_setup); + #endif static void print_inquiry(unsigned char *data) @@ -608,6 +641,7 @@ } else { /* assume no peripheral if any other sort of error */ scsi_release_request(SRpnt); + scsi_release_commandblocks(SDpnt); return 0; } } @@ -618,6 +652,24 @@ */ /* + * If we are offline and we are on a LUN != 0, then skip this entry. + * If we are on a BLIST_FORCELUN device this will stop the scan at + * the first offline LUN (typically the correct thing to do). If + * we are on a BLIST_SPARSELUN device then this won't stop the scan, + * but it will keep us from having false entries in our device + * array. DL + * + * NOTE: Need to test this to make sure it doesn't cause problems + * with tape autoloaders, multidisc CD changers, and external + * RAID chassis that might use sparse luns or multiluns... DL + */ + if (lun != 0 && (scsi_result[0] >> 5) == 1) { + scsi_release_request(SRpnt); + scsi_release_commandblocks(SDpnt); + return 0; + } + + /* * Get any flags for this device. */ bflags = get_device_flags (scsi_result); @@ -655,8 +707,11 @@ SDpnt->removable = (0x80 & scsi_result[1]) >> 7; /* Use the peripheral qualifier field to determine online/offline */ - if (((scsi_result[0] >> 5) & 7) == 1) SDpnt->online = FALSE; - else SDpnt->online = TRUE; + if ((((scsi_result[0] >> 5) & 7) == 1) && + (lun >= scsi_allow_ghost_devices)) + SDpnt->online = FALSE; + else + SDpnt->online = TRUE; SDpnt->lockable = SDpnt->removable; SDpnt->changed = 0; SDpnt->access_count = 0; @@ -742,6 +797,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. @@ -857,11 +919,26 @@ * I think we need REPORT LUNS in future to avoid scanning * of unused LUNs. But, that is another item. */ + /* if (*max_dev_lun < shpnt->max_lun) *max_dev_lun = shpnt->max_lun; else if ((max_scsi_luns >> 1) >= *max_dev_lun) *max_dev_lun += shpnt->max_lun; else *max_dev_lun = max_scsi_luns; + */ + /* + * Blech...the above code is broken. When you have a device + * that is present, and it is a FORCELUN device, then we + * need to scan *all* the luns on that device. Besides, + * skipping the scanning of LUNs is a false optimization. + * Scanning for a LUN on a present device is a very fast + * operation, it's scanning for devices that don't exist that + * is expensive and slow (although if you are truly scanning + * through MAX_SCSI_LUNS devices that would be bad, I hope + * all of the controllers out there set a reasonable value + * in shpnt->max_lun). DL + */ + *max_dev_lun = shpnt->max_lun; return 1; } /* Index: drivers/scsi/scsi_syms.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/scsi_syms.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/scsi_syms.c 22 Jul 2004 19:50:06 -0000 1.1 +++ drivers/scsi/scsi_syms.c 4 Aug 2004 01:29:37 -0000 1.2 @@ -43,6 +43,7 @@ EXPORT_SYMBOL(scsi_do_cmd); EXPORT_SYMBOL(scsi_command_size); EXPORT_SYMBOL(scsi_ioctl); +EXPORT_SYMBOL(scsi_finish_command); EXPORT_SYMBOL(print_command); EXPORT_SYMBOL(print_sense); EXPORT_SYMBOL(print_req_sense); Index: drivers/scsi/scsiiom.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/scsiiom.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/scsiiom.c 22 Jul 2004 19:50:01 -0000 1.1 +++ drivers/scsi/scsiiom.c 4 Aug 2004 01:29:37 -0000 1.2 @@ -4,7 +4,7 @@ * Description: Device Driver for Tekram DC-390 (T) PCI SCSI * * Bus Master Host Adapter * ***********************************************************************/ -/* $Id: scsiiom.c,v 1.1 2004/07/22 19:50:01 joff Exp $ */ +/* $Id: scsiiom.c,v 1.2 2004/08/04 01:29:37 joff Exp $ */ static void __inline__ dc390_freetag (PDCB pDCB, PSRB pSRB) Index: drivers/scsi/sd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/sd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/sd.c 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/scsi/sd.c 4 Aug 2004 01:29:37 -0000 1.2 @@ -775,7 +775,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; @@ -817,7 +818,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; @@ -832,10 +833,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 @@ -853,10 +854,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); @@ -870,7 +894,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; @@ -883,6 +907,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)); Index: drivers/scsi/sd.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/sd.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/sd.h 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/scsi/sd.h 4 Aug 2004 01:29:37 -0000 1.2 @@ -12,7 +12,7 @@ #ifndef _SD_H #define _SD_H /* - $Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/sd.h,v 1.1 2004/07/22 19:50:00 joff Exp $ + $Header: /cvsroot/ts-7200/dist/linux24/drivers/scsi/sd.h,v 1.2 2004/08/04 01:29:37 joff Exp $ */ #ifndef _SCSI_H Index: drivers/scsi/seagate.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/seagate.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/seagate.c 22 Jul 2004 19:50:04 -0000 1.1 +++ drivers/scsi/seagate.c 4 Aug 2004 01:29:37 -0000 1.2 @@ -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)) Index: drivers/scsi/sg.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/sg.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/sg.c 22 Jul 2004 19:50:00 -0000 1.1 +++ drivers/scsi/sg.c 4 Aug 2004 01:29:37 -0000 1.2 @@ -871,6 +871,8 @@ case SG_SET_RESERVED_SIZE: result = get_user(val, (int *)arg); if (result) return result; + if (val < 0) + return -EINVAL; if (val != sfp->reserve.bufflen) { if (sg_res_in_use(sfp) || sfp->mmap_called) return -EBUSY; Index: drivers/scsi/sgiwd93.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/sgiwd93.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/sgiwd93.c 22 Jul 2004 19:50:01 -0000 1.1 +++ drivers/scsi/sgiwd93.c 4 Aug 2004 01:29:37 -0000 1.2 @@ -1,32 +1,32 @@ /* - * sgiwd93.c: SGI WD93 scsi driver. + * 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) - * 1999 Andrew R. Baker (andrewb@uab.edu) - * - Support for 2nd SCSI controller on Indigo2 - * 2001 Florian Lohoff (flo@rfc822.org) - * - Delete HPC scatter gather (Read corruption on - * multiple disks) - * - Cleanup wback cache handling + * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) + * Copyright (C) 2001 Florian Lohoff (flo@rfc822.org) + * Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org) * * (In all truth, Jed Schimmel wrote all this code.) - * */ #include +#include #include #include #include #include #include +#include #include #include #include #include #include -#include -#include -#include +#include +#include +#include #include #include @@ -37,13 +37,29 @@ #include +#if 0 +#define DPRINTK(args...) printk(args) +#else +#define DPRINTK(args...) +#endif + +#define HDATA(ptr) ((struct ip22_hostdata *)((ptr)->hostdata)) + +struct ip22_hostdata { + struct WD33C93_hostdata wh; + struct hpc_data { + dma_addr_t dma; + void * cpu; + } hd; +}; + struct hpc_chunk { struct hpc_dma_desc desc; u32 _padding; /* align to quadword boundary */ }; -struct Scsi_Host *sgiwd93_host = NULL; -struct Scsi_Host *sgiwd93_host1 = NULL; +struct Scsi_Host *sgiwd93_host; +struct Scsi_Host *sgiwd93_host1; /* Wuff wuff, wuff, wd33c93.c, wuff wuff, object oriented, bow wow. */ static inline void write_wd33c93_count(const wd33c93_regs regs, @@ -70,7 +86,6 @@ return value; } -/* XXX woof! */ static void sgiwd93_intr(int irq, void *dev_id, struct pt_regs *regs) { unsigned long flags; @@ -80,74 +95,70 @@ spin_unlock_irqrestore(&io_request_lock, flags); } -#undef DEBUG_DMA - static inline -void fill_hpc_entries (struct hpc_chunk **hcp, char *addr, unsigned long len) +void fill_hpc_entries(struct hpc_chunk *hcp, Scsi_Cmnd *cmd, int datainp) { - unsigned long physaddr; + unsigned long len = cmd->SCp.this_residual; + void *addr = cmd->SCp.ptr; + dma_addr_t physaddr; unsigned long count; - - physaddr = PHYSADDR(addr); + + physaddr = pci_map_single(NULL, addr, len, + scsi_to_pci_dma_dir(cmd->sc_data_direction)); + cmd->SCp.dma_handle = physaddr; + while (len) { /* * even cntinfo could be up to 16383, without * magic only 8192 works correctly */ count = len > 8192 ? 8192 : len; - (*hcp)->desc.pbuf = physaddr; - (*hcp)->desc.cntinfo = count; - (*hcp)++; + hcp->desc.pbuf = physaddr; + hcp->desc.cntinfo = count; + hcp++; len -= count; physaddr += count; } + + /* + * To make sure, if we trip an HPC bug, that we transfer every single + * byte, we tag on an extra zero length dma descriptor at the end of + * the chain. + */ + hcp->desc.pbuf = 0; + hcp->desc.cntinfo = HPCDMA_EOX; } static int dma_setup(Scsi_Cmnd *cmd, int datainp) { - struct WD33C93_hostdata *hdata = (struct WD33C93_hostdata *)cmd->host->hostdata; - struct hpc3_scsiregs *hregs = (struct hpc3_scsiregs *) cmd->host->base; - struct hpc_chunk *hcp = (struct hpc_chunk *) hdata->dma_bounce_buffer; - -#ifdef DEBUG_DMA - printk("dma_setup: datainp<%d> hcp<%p> ", - datainp, hcp); -#endif + struct ip22_hostdata *hdata = HDATA(cmd->host); + struct hpc3_scsiregs *hregs = + (struct hpc3_scsiregs *) cmd->host->base; + struct hpc_chunk *hcp = (struct hpc_chunk *) hdata->hd.cpu; - hdata->dma_dir = datainp; + DPRINTK("dma_setup: datainp<%d> hcp<%p> ", datainp, hcp); + + hdata->wh.dma_dir = datainp; /* - * wd33c93 shouldn't pass us bogus dma_setups, but - * it does:-( The other wd33c93 drivers deal with - * it the same way (which isn't that obvious). - * IMHO a better fix would be, not to do these - * dma setups in the first place + * wd33c93 shouldn't pass us bogus dma_setups, but it does:-( The + * other wd33c93 drivers deal with it the same way (which isn't that + * obvious). 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, datainp); - /* To make sure, if we trip an HPC bug, that we transfer - * every single byte, we tag on an extra zero length dma - * descriptor at the end of the chain. - */ - hcp->desc.pbuf = 0; - hcp->desc.cntinfo = (HPCDMA_EOX); - -#ifdef DEBUG_DMA - printk(" HPCGO\n"); -#endif + DPRINTK(" HPCGO\n"); /* Start up the HPC. */ - hregs->ndptr = PHYSADDR(hdata->dma_bounce_buffer); - if(datainp) { - dma_cache_inv((unsigned long) cmd->SCp.ptr, cmd->SCp.this_residual); - hregs->ctrl = (HPC3_SCTRL_ACTIVE); - } else { - dma_cache_wback_inv((unsigned long) cmd->SCp.ptr, cmd->SCp.this_residual); - hregs->ctrl = (HPC3_SCTRL_ACTIVE | HPC3_SCTRL_DIR); - } + hregs->ndptr = hdata->hd.dma; + if (datainp) + hregs->ctrl = HPC3_SCTRL_ACTIVE; + else + hregs->ctrl = HPC3_SCTRL_ACTIVE | HPC3_SCTRL_DIR; return 0; } @@ -155,7 +166,7 @@ static void dma_stop(struct Scsi_Host *instance, Scsi_Cmnd *SCpnt, int status) { - struct WD33C93_hostdata *hdata = (struct WD33C93_hostdata *)instance->hostdata; + struct ip22_hostdata *hdata = HDATA(instance); struct hpc3_scsiregs *hregs; if (!SCpnt) @@ -163,21 +174,19 @@ hregs = (struct hpc3_scsiregs *) SCpnt->host->base; -#ifdef DEBUG_DMA - printk("dma_stop: status<%d> ", status); -#endif + DPRINTK("dma_stop: status<%d> ", status); /* First stop the HPC and flush it's FIFO. */ - if(hdata->dma_dir) { + if (hdata->wh.dma_dir) { hregs->ctrl |= HPC3_SCTRL_FLUSH; - while(hregs->ctrl & HPC3_SCTRL_ACTIVE) + while (hregs->ctrl & HPC3_SCTRL_ACTIVE) barrier(); } hregs->ctrl = 0; + pci_unmap_single(NULL, SCpnt->SCp.dma_handle, SCpnt->SCp.this_residual, + scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); -#ifdef DEBUG_DMA - printk("\n"); -#endif + DPRINTK("\n"); } void sgiwd93_reset(unsigned long base) @@ -185,119 +194,97 @@ struct hpc3_scsiregs *hregs = (struct hpc3_scsiregs *) base; hregs->ctrl = HPC3_SCTRL_CRESET; - udelay (50); + udelay(50); hregs->ctrl = 0; } -static inline void init_hpc_chain(uchar *buf) +static inline void init_hpc_chain(struct hpc_data *hd) { - struct hpc_chunk *hcp = (struct hpc_chunk *) buf; + struct hpc_chunk *hcp = (struct hpc_chunk *) hd->cpu; + struct hpc_chunk *dma = (struct hpc_chunk *) hd->dma; unsigned long start, end; - start = (unsigned long) buf; + start = (unsigned long) hcp; end = start + PAGE_SIZE; - while(start < end) { - hcp->desc.pnext = PHYSADDR((hcp + 1)); + while (start < end) { + hcp->desc.pnext = (u32) (dma + 1); hcp->desc.cntinfo = HPCDMA_EOX; - hcp++; + hcp++; dma++; start += sizeof(struct hpc_chunk); }; hcp--; - hcp->desc.pnext = PHYSADDR(buf); - - /* Force flush to memory */ - dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE); + hcp->desc.pnext = hd->dma; } -int __init sgiwd93_detect(Scsi_Host_Template *SGIblows) +static struct Scsi_Host * __init sgiwd93_setup_scsi( + Scsi_Host_Template *SGIblows, int unit, int irq, + struct hpc3_scsiregs *hregs, unsigned char *wdregs) { - static unsigned char called = 0; - struct hpc3_scsiregs *hregs = &hpc3c0->scsi_chan0; - struct hpc3_scsiregs *hregs1 = &hpc3c0->scsi_chan1; - struct WD33C93_hostdata *hdata; - struct WD33C93_hostdata *hdata1; + struct ip22_hostdata *hdata; + struct Scsi_Host *host; wd33c93_regs regs; - uchar *buf; - - if(called) - return 0; /* Should bitch on the console about this... */ - SGIblows->proc_name = "SGIWD93"; - - sgiwd93_host = scsi_register(SGIblows, sizeof(struct WD33C93_hostdata)); - if(sgiwd93_host == NULL) - return 0; - sgiwd93_host->base = (unsigned long) hregs; - sgiwd93_host->irq = SGI_WD93_0_IRQ; - - buf = (uchar *) get_free_page(GFP_KERNEL); - if (!buf) { - printk(KERN_WARNING "sgiwd93: Could not allocate memory for host0 buffer.\n"); - scsi_unregister(sgiwd93_host); - return 0; + host = scsi_register(SGIblows, sizeof(struct ip22_hostdata)); + if (!host) + return NULL; + + host->base = (unsigned long) hregs; + host->irq = irq; + + hdata = HDATA(host); + hdata->hd.cpu = pci_alloc_consistent(NULL, PAGE_SIZE, &hdata->hd.dma); + if (!hdata->hd.cpu) { + printk(KERN_WARNING "sgiwd93: Could not allocate memory for " + "host %d buffer.\n", unit); + goto out_unregister; } - init_hpc_chain(buf); - - /* HPC_SCSI_REG0 | 0x03 | KSEG1 */ - regs.SASR = (unsigned char*) KSEG1ADDR (0x1fbc0003); - regs.SCMD = (unsigned char*) KSEG1ADDR (0x1fbc0007); - wd33c93_init(sgiwd93_host, regs, dma_setup, dma_stop, WD33C93_FS_16_20); - - hdata = (struct WD33C93_hostdata *)sgiwd93_host->hostdata; - hdata->no_sync = 0; - hdata->dma_bounce_buffer = (uchar *) (KSEG1ADDR(buf)); + init_hpc_chain(&hdata->hd); - if (request_irq(SGI_WD93_0_IRQ, sgiwd93_intr, 0, "SGI WD93", (void *) sgiwd93_host)) { - printk(KERN_WARNING "sgiwd93: Could not register IRQ %d (for host 0).\n", SGI_WD93_0_IRQ); -#ifdef MODULE - wd33c93_release(); -#endif - free_page((unsigned long)buf); - scsi_unregister(sgiwd93_host); - return 0; + regs.SASR = wdregs + 3; + regs.SCMD = wdregs + 7; + + wd33c93_init(host, regs, dma_setup, dma_stop, WD33C93_FS_16_20); + + hdata->wh.no_sync = 0; + + if (request_irq(irq, sgiwd93_intr, 0, "SGI WD93", (void *) host)) { + printk(KERN_WARNING "sgiwd93: Could not register irq %d " + "for host %d.\n", irq, unit); + goto out_free; } - /* set up second controller on the Indigo2 */ - if(!sgi_guiness) { - 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); - if (!buf) { - printk(KERN_WARNING "sgiwd93: Could not allocate memory for host1 buffer.\n"); - scsi_unregister(sgiwd93_host1); - called = 1; - return 1; /* We registered host0 so return success*/ - } - init_hpc_chain(buf); - - /* HPC_SCSI_REG1 | 0x03 | KSEG1 */ - regs.SASR = (unsigned char*) KSEG1ADDR(0x1fbc8003); - regs.SCMD = (unsigned char*) KSEG1ADDR(0x1fbc8007); - wd33c93_init(sgiwd93_host1, regs, dma_setup, dma_stop, - WD33C93_FS_16_20); - - hdata1 = (struct WD33C93_hostdata *)sgiwd93_host1->hostdata; - hdata1->no_sync = 0; - hdata1->dma_bounce_buffer = (uchar *) (KSEG1ADDR(buf)); - - if (request_irq(SGI_WD93_1_IRQ, sgiwd93_intr, 0, "SGI WD93", (void *) sgiwd93_host1)) { - printk(KERN_WARNING "sgiwd93: Could not allocate irq %d (for host1).\n", SGI_WD93_1_IRQ); -#ifdef MODULE - wd33c93_release(); -#endif - free_page((unsigned long)buf); - scsi_unregister(sgiwd93_host1); - /* Fall through since host0 registered OK */ - } - } + return host; + +out_free: + pci_free_consistent(NULL, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma); + wd33c93_release(); + +out_unregister: + scsi_unregister(host); + + return NULL; +} + +int __init sgiwd93_detect(Scsi_Host_Template *SGIblows) +{ + int found = 0; + + SGIblows->proc_name = "SGIWD93"; + sgiwd93_host = sgiwd93_setup_scsi(SGIblows, 0, SGI_WD93_0_IRQ, + &hpc3c0->scsi_chan0, + (unsigned char *)hpc3c0->scsi0_ext); + if (sgiwd93_host) + found++; + + /* Set up second controller on the Indigo2 */ + if (ip22_is_fullhouse()) { + sgiwd93_host1 = sgiwd93_setup_scsi(SGIblows, 1, SGI_WD93_1_IRQ, + &hpc3c0->scsi_chan1, + (unsigned char *)hpc3c0->scsi1_ext); + if (sgiwd93_host1) + found++; } - - called = 1; - return 1; /* Found one. */ + return found; } #define HOSTS_C @@ -312,11 +299,12 @@ { #ifdef MODULE free_irq(SGI_WD93_0_IRQ, sgiwd93_intr); - free_page(KSEG0ADDR(hdata->dma_bounce_buffer)); + pci_free_consistent(NULL, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma); wd33c93_release(); - if(!sgi_guiness) { + if (ip22_is_fullhouse()) { free_irq(SGI_WD93_1_IRQ, sgiwd93_intr); - free_page(KSEG0ADDR(hdata1->dma_bounce_buffer)); + pci_free_consistent(NULL, PAGE_SIZE, hdata1->hd.cpu, + hdata1->hd.dma); wd33c93_release(); } #endif Index: drivers/scsi/sgiwd93.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/sgiwd93.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/sgiwd93.h 22 Jul 2004 19:50:01 -0000 1.1 +++ drivers/scsi/sgiwd93.h 4 Aug 2004 01:29:37 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: sgiwd93.h,v 1.1 2004/07/22 19:50:01 joff Exp $ +/* $Id: sgiwd93.h,v 1.2 2004/08/04 01:29:37 joff Exp $ * sgiwd93.h: SGI WD93 scsi definitions. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) Index: drivers/scsi/sim710_d.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/sim710_d.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/sim710_d.h 22 Jul 2004 19:50:06 -0000 1.1 +++ drivers/scsi/sim710_d.h 4 Aug 2004 01:29:37 -0000 1.2 @@ -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; Index: drivers/scsi/st.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/st.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/st.c 22 Jul 2004 19:50:01 -0000 1.1 +++ drivers/scsi/st.c 4 Aug 2004 01:29:38 -0000 1.2 @@ -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 - 2004 Kai Makisara + email Kai.Makisara@kolumbus.fi - Last modified: Mon Aug 5 22:54:13 2002 by makisara + Last modified: Fri Jan 2 17:50:08 2004 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 = "20040102"; #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]; @@ -1280,6 +1277,18 @@ goto out; } + if ((STp->buffer)->writing) { + write_behind_check(STp); + if ((STp->buffer)->syscall_result) { + DEBC(printk(ST_DEB_MSG "st%d: Async write error (write) %x.\n", + dev, (STp->buffer)->midlevel_result)); + if ((STp->buffer)->midlevel_result == INT_MAX) + STps->eof = ST_EOM_OK; + else + STps->eof = ST_EOM_ERROR; + } + } + if (STp->block_size == 0) { if (STp->max_block > 0 && (count < STp->min_block || count > STp->max_block)) { @@ -1327,18 +1336,6 @@ } } - if ((STp->buffer)->writing) { - write_behind_check(STp); - if ((STp->buffer)->syscall_result) { - DEBC(printk(ST_DEB_MSG "st%d: Async write error (write) %x.\n", - dev, (STp->buffer)->midlevel_result)); - if ((STp->buffer)->midlevel_result == INT_MAX) - STps->eof = ST_EOM_OK; - else - STps->eof = ST_EOM_ERROR; - } - } - if (STps->eof == ST_EOM_OK) { retval = (-ENOSPC); goto out; @@ -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) { Index: drivers/scsi/st.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/st.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/st.h 22 Jul 2004 19:50:01 -0000 1.1 +++ drivers/scsi/st.h 4 Aug 2004 01:29:38 -0000 1.2 @@ -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 */ Index: drivers/scsi/st_options.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/st_options.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/st_options.h 22 Jul 2004 19:50:03 -0000 1.1 +++ drivers/scsi/st_options.h 4 Aug 2004 01:29:38 -0000 1.2 @@ -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 Index: drivers/scsi/sun3_scsi.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/sun3_scsi.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/sun3_scsi.c 22 Jul 2004 19:50:06 -0000 1.1 +++ drivers/scsi/sun3_scsi.c 4 Aug 2004 01:29:38 -0000 1.2 @@ -47,8 +47,8 @@ /* * $Log: sun3_scsi.c,v $ - * Revision 1.1 2004/07/22 19:50:06 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:38 joff + * merging 2.4.26-vrs1 * */ @@ -270,7 +270,7 @@ #ifndef REAL_DMA printk("scsi%d: IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); - instance->irq = IRQ_NONE; + instance->irq = SCSI_IRQ_NONE; #else printk("scsi%d: IRQ%d not free, bailing out\n", instance->host_no, instance->irq); @@ -279,7 +279,7 @@ } printk("scsi%d: Sun3 5380 at port %lX irq", instance->host_no, instance->io_port); - if (instance->irq == IRQ_NONE) + if (instance->irq == SCSI_IRQ_NONE) printk ("s disabled"); else printk (" %d", instance->irq); @@ -308,7 +308,7 @@ #ifdef MODULE int sun3scsi_release (struct Scsi_Host *shpnt) { - if (shpnt->irq != IRQ_NONE) + if (shpnt->irq != SCSI_IRQ_NONE) free_irq (shpnt->irq, NULL); iounmap((void *)sun3_scsi_regp); Index: drivers/scsi/sun3_scsi.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/sun3_scsi.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/sun3_scsi.h 22 Jul 2004 19:50:06 -0000 1.1 +++ drivers/scsi/sun3_scsi.h 4 Aug 2004 01:29:38 -0000 1.2 @@ -31,8 +31,8 @@ /* * $Log: sun3_scsi.h,v $ - * Revision 1.1 2004/07/22 19:50:06 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:38 joff + * merging 2.4.26-vrs1 * */ Index: drivers/scsi/sun3_scsi_vme.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/sun3_scsi_vme.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/sun3_scsi_vme.c 22 Jul 2004 19:50:03 -0000 1.1 +++ drivers/scsi/sun3_scsi_vme.c 4 Aug 2004 01:29:38 -0000 1.2 @@ -236,7 +236,7 @@ #ifndef REAL_DMA printk("scsi%d: IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); - instance->irq = IRQ_NONE; + instance->irq = SCSI_IRQ_NONE; #else printk("scsi%d: IRQ%d not free, bailing out\n", instance->host_no, instance->irq); @@ -245,7 +245,7 @@ } printk("scsi%d: Sun3 5380 VME at port %lX irq", instance->host_no, instance->io_port); - if (instance->irq == IRQ_NONE) + if (instance->irq == SCSI_IRQ_NONE) printk ("s disabled"); else printk (" %d", instance->irq); @@ -281,7 +281,7 @@ #ifdef MODULE int sun3scsi_release (struct Scsi_Host *shpnt) { - if (shpnt->irq != IRQ_NONE) + if (shpnt->irq != SCSI_IRQ_NONE) free_irq (shpnt->irq, NULL); iounmap(sun3_scsi_regp); Index: drivers/scsi/sym53c8xx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/sym53c8xx.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/sym53c8xx.c 22 Jul 2004 19:50:06 -0000 1.1 +++ drivers/scsi/sym53c8xx.c 4 Aug 2004 01:29:38 -0000 1.2 @@ -6992,7 +6992,7 @@ static void ncr_soft_reset(ncb_p np) { - u_char istat; + u_char istat = 0; int i; if (!(np->features & FE_ISTAT1) || !(INB (nc_istat1) & SRUN)) @@ -11981,6 +11981,19 @@ inq_byte7 |= INQ7_SYNC; /* + ** Don't do PPR negotiations on SCSI-2 devices unless + ** they set the DT bit (0x04) in byte 57 of the INQUIRY + ** return data. + */ + if (((inq_data[2] & 0x07) < 3) && (inq_data[4] < 53 || + !(inq_data[56] & 0x04))) { + if (tp->minsync < 10) + tp->minsync = 10; + if (tp->usrsync < 10) + tp->usrsync = 10; + } + + /* ** Prepare negotiation if SIP capabilities have changed. */ tp->inq_done = 1; Index: drivers/scsi/t128.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/t128.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/t128.c 22 Jul 2004 19:50:04 -0000 1.1 +++ drivers/scsi/t128.c 4 Aug 2004 01:29:38 -0000 1.2 @@ -237,20 +237,20 @@ else instance->irq = NCR5380_probe_irq(instance, T128_IRQS); - if (instance->irq != IRQ_NONE) + if (instance->irq != SCSI_IRQ_NONE) if (request_irq(instance->irq, do_t128_intr, SA_INTERRUPT, "t128", NULL)) { printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); - instance->irq = IRQ_NONE; + instance->irq = SCSI_IRQ_NONE; } - if (instance->irq == IRQ_NONE) { + if (instance->irq == SCSI_IRQ_NONE) { printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no); printk(KERN_INFO "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no); } printk(KERN_INFO "scsi%d : at 0x%08lx", instance->host_no,instance->base); - if (instance->irq == IRQ_NONE) + if (instance->irq == SCSI_IRQ_NONE) printk(" interrupts disabled"); else printk(" irq %d", instance->irq); Index: drivers/scsi/t128.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/t128.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/t128.h 22 Jul 2004 19:50:04 -0000 1.1 +++ drivers/scsi/t128.h 4 Aug 2004 01:29:38 -0000 1.2 @@ -36,8 +36,8 @@ /* * $Log: t128.h,v $ - * Revision 1.1 2004/07/22 19:50:04 joff - * Initial revision + * Revision 1.2 2004/08/04 01:29:38 joff + * merging 2.4.26-vrs1 * */ Index: drivers/scsi/tmscsim.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/tmscsim.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/tmscsim.c 22 Jul 2004 19:50:04 -0000 1.1 +++ drivers/scsi/tmscsim.c 4 Aug 2004 01:29:38 -0000 1.2 @@ -7,7 +7,7 @@ ***********************************************************************/ /* (C) Copyright: put under GNU GPL in 10/96 (see README.tmscsim) * *************************************************************************/ -/* $Id: tmscsim.c,v 1.1 2004/07/22 19:50:04 joff Exp $ */ +/* $Id: tmscsim.c,v 1.2 2004/08/04 01:29:38 joff Exp $ */ /* Enhancements and bugfixes by * * Kurt Garloff * ***********************************************************************/ @@ -3047,7 +3047,7 @@ /* TO DO: We should check for outstanding commands first. */ dc390_shutdown (host); - if (host->irq != IRQ_NONE) + if (host->irq != SCSI_IRQ_NONE) { DEBUG0(printk(KERN_INFO "DC390: Free IRQ %i\n",host->irq);) free_irq (host->irq, pACB); Index: drivers/scsi/tmscsim.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/tmscsim.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/tmscsim.h 22 Jul 2004 19:50:04 -0000 1.1 +++ drivers/scsi/tmscsim.h 4 Aug 2004 01:29:38 -0000 1.2 @@ -3,7 +3,7 @@ ;* TEKRAM DC-390(T) PCI SCSI Bus Master Host Adapter * ;* Device Driver * ;***********************************************************************/ -/* $Id: tmscsim.h,v 1.1 2004/07/22 19:50:04 joff Exp $ */ +/* $Id: tmscsim.h,v 1.2 2004/08/04 01:29:38 joff Exp $ */ #ifndef _TMSCSIM_H #define _TMSCSIM_H @@ -11,7 +11,7 @@ #include #include -#define IRQ_NONE 255 +#define SCSI_IRQ_NONE 255 #define MAX_ADAPTER_NUM 4 #define MAX_SG_LIST_BUF 16 /* Not used */ Index: drivers/scsi/wd7000.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/wd7000.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/wd7000.c 22 Jul 2004 19:50:01 -0000 1.1 +++ drivers/scsi/wd7000.c 4 Aug 2004 01:29:38 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: wd7000.c,v 1.1 2004/07/22 19:50:01 joff Exp $ +/* $Id: wd7000.c,v 1.2 2004/08/04 01:29:38 joff Exp $ * linux/drivers/scsi/wd7000.c * * Copyright (C) 1992 Thomas Wuensche Index: drivers/scsi/wd7000.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/wd7000.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/wd7000.h 22 Jul 2004 19:50:01 -0000 1.1 +++ drivers/scsi/wd7000.h 4 Aug 2004 01:29:38 -0000 1.2 @@ -1,6 +1,6 @@ #ifndef _WD7000_H -/* $Id: wd7000.h,v 1.1 2004/07/22 19:50:01 joff Exp $ +/* $Id: wd7000.h,v 1.2 2004/08/04 01:29:38 joff Exp $ * * Header file for the WD-7000 driver for Linux * Index: drivers/scsi/aacraid/README =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aacraid/README,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aacraid/README 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/aacraid/README 4 Aug 2004 01:29:38 -0000 1.2 @@ -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 Index: drivers/scsi/aacraid/TODO =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aacraid/TODO,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aacraid/TODO 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/aacraid/TODO 4 Aug 2004 01:29:38 -0000 1.2 @@ -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. Index: drivers/scsi/aacraid/aachba.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aacraid/aachba.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aacraid/aachba.c 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/aacraid/aachba.c 4 Aug 2004 01:29:38 -0000 1.2 @@ -23,6 +23,7 @@ */ #include +#include #include #include #include @@ -220,9 +221,19 @@ static unsigned long aac_build_sg(Scsi_Cmnd* scsicmd, struct sgmap* sgmap); static unsigned long aac_build_sg64(Scsi_Cmnd* scsicmd, struct sgmap64* psg); static int aac_send_srb_fib(Scsi_Cmnd* scsicmd); -#ifdef AAC_DETAILED_STATUS_INFO 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"); +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; /** * aac_get_containers - list containers @@ -261,13 +272,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); @@ -287,6 +299,64 @@ } /** + * aac_get_container_name - get container name + */ +static int aac_get_container_name(struct aac_dev *dev, int cid, char * pid) +{ + struct fsa_scsi_hba *fsa_dev_ptr; + int status = 0; + struct aac_get_name *dinfo; + struct aac_get_name_resp *dresp; + struct fib * fibptr; + unsigned instance; + + fsa_dev_ptr = &(dev->fsa_dev); + instance = dev->scsi_host_ptr->unique_id; + + if (!(fibptr = fib_alloc(dev))) + return -ENOMEM; + + fib_init(fibptr); + dinfo = (struct aac_get_name *) fib_data(fibptr); + + dinfo->command = cpu_to_le32(VM_ContainerConfig); + dinfo->type = cpu_to_le32(CT_READ_NAME); + dinfo->cid = cpu_to_le32(cid); + dinfo->count = cpu_to_le32(sizeof(((struct aac_get_name_resp *)NULL)->data)); + + status = fib_send(ContainerCommand, + fibptr, + sizeof (struct aac_get_name), + FsaNormal, + 1, 1, + NULL, NULL); + if (status < 0 ) { + printk(KERN_WARNING "aac_get_container_name: SendFIB failed.\n"); + } else { + dresp = (struct aac_get_name_resp *)fib_data(fibptr); + + status = (le32_to_cpu(dresp->status) != CT_OK) + || (dresp->data[0] == '\0'); + if (status == 0) { + char * sp = dresp->data; + char * dp = pid; + do { + if ((*sp == '\0') + || ((dp - pid) >= sizeof(((struct aac_get_name_resp *)NULL)->data))) { + *dp = ' '; + } else { + *dp = *sp++; + } + } while (++dp < &pid[sizeof(((struct inquiry_data *)NULL)->inqd_pid)]); + } + } + fib_complete(fibptr); + fib_free(fibptr); + fsa_dev[instance] = fsa_dev_ptr; + return status; +} + +/** * probe_container - query a logical volume * @dev: device to query * @cid: container identifier @@ -332,7 +402,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 +591,56 @@ 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(paemode != -1) + dev->pae_support = (paemode != 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 +659,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 +704,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 +870,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 */ @@ -953,7 +1058,6 @@ memset(inq_data_ptr, 0, sizeof (struct inquiry_data)); inq_data_ptr->inqd_ver = 2; /* claim compliance to SCSI-2 */ - inq_data_ptr->inqd_dtq = 0x80; /* set RMB bit to one indicating that the medium is removable */ inq_data_ptr->inqd_rdf = 2; /* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */ inq_data_ptr->inqd_len = 31; /*Format for "pad2" is RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */ @@ -962,11 +1066,14 @@ * Set the Vendor, Product, and Revision Level * see: .c i.e. aac.c */ - setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), fsa_dev_ptr->type[cid]); - if (scsicmd->target == scsicmd->host->this_id) + if (scsicmd->target == scsicmd->host->this_id) { + setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), (sizeof(container_types)/sizeof(char *))); inq_data_ptr->inqd_pdt = INQD_PDT_PROC; /* Processor device */ - else + } else { + setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), fsa_dev_ptr->type[cid]); + aac_get_container_name(dev, cid, inq_data_ptr->inqd_pid); inq_data_ptr->inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ + } scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD; __aac_io_done(scsicmd); return 0; @@ -1079,7 +1186,7 @@ SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND, 0, 0, 0, 0); __aac_io_done(scsicmd); - return -1; + return 0; } } @@ -1261,17 +1368,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 +1412,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; @@ -1347,14 +1488,13 @@ case SRB_STATUS_FORCE_ABORT: 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))); -#endif + 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) ); 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 +1527,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 +1569,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); @@ -1441,7 +1586,7 @@ /* * Build Scatter/Gather list */ - fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry64)); + fibsize = sizeof (struct aac_srb) - sizeof (struct sgentry) + ((srbcmd->sg.count & 0xff) * sizeof (struct sgentry64)); /* * Now send the Fib to the adapter @@ -1533,6 +1678,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,14 +1740,13 @@ 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; } return byte_count; } -#ifdef AAC_DETAILED_STATUS_INFO - struct aac_srb_status_info { u32 status; char *str; @@ -1656,4 +1801,3 @@ return "Bad Status Code"; } -#endif Index: drivers/scsi/aacraid/aacraid.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aacraid/aacraid.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aacraid/aacraid.h 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/aacraid/aacraid.h 4 Aug 2004 01:29:39 -0000 1.2 @@ -1,5 +1,10 @@ -#define dprintk(x) -/*#define dprintk(x) printk x */ +#define AAC_DRIVER_VERSION 0x01010300 +#define AAC_DRIVER_BUILD_DATE __DATE__ " " __TIME__ + +//#define dprintk(x) printk x +#if (!defined(dprintk)) +# define dprintk(x) +#endif /*------------------------------------------------------------------------------ * D E F I N E S @@ -8,12 +13,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 +275,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 +444,8 @@ char * vname; char * model; u16 channels; + int quirks; +#define AAC_QUIRK_31BIT 1 }; /* @@ -629,7 +637,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 +647,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 +658,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 +674,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 +708,7 @@ u32 biosrev; u32 biosbuild; u32 cluster; + u32 clusterchannelmask; u32 serial[2]; u32 battery; u32 options; @@ -720,19 +733,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 +762,12 @@ */ dma_addr_t hw_fib_pa; struct hw_fib *hw_fib_va; -#if BITS_PER_LONG >= 64 - ulong fib_base_va; -#endif + struct hw_fib *aif_base_va; /* * 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 +796,7 @@ struct Scsi_Host *scsi_host_ptr; struct fsa_scsi_hba fsa_dev; - int thread_pid; + pid_t thread_pid; int cardtype; /* @@ -804,8 +819,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 +1164,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; @@ -1157,6 +1181,31 @@ struct aac_mntent mnt[1]; }; +#define CT_READ_NAME 130 +struct aac_get_name { + u32 command; + u32 type; // CT_READ_NAME + u32 cid; + u32 parm1; + u32 parm2; + u32 parm3; + u32 parm4; + u32 count; // sizeof(((struct aac_get_name_resp *)NULL)->data) +}; + +#define CT_OK 218 +struct aac_get_name_resp { + u32 dummy0; + u32 dummy1; + u32 status; // CT_OK + u32 parm1; + u32 parm2; + u32 parm3; + u32 parm4; + u32 parm5; + u8 data[16]; +}; + /* * The following command is sent to shut down each container. */ @@ -1326,9 +1375,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 +1405,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 +1418,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); Index: drivers/scsi/aacraid/commctrl.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aacraid/commctrl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aacraid/commctrl.c 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/aacraid/commctrl.c 4 Aug 2004 01:29:39 -0000 1.2 @@ -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); } /* @@ -355,7 +362,7 @@ * @dev: adapter * @arg: ioctl arguments * - * This routine returns the firmware version. + * This routine returns the driver version. * Under Linux, there have been no version incompatibilities, so this is simple! */ @@ -364,14 +371,223 @@ struct revision response; response.compat = 1; - response.version = dev->adapter_info.kernelrev; - response.build = dev->adapter_info.kernelbuild; + response.version = AAC_DRIVER_VERSION; + response.build = 9999; if (copy_to_user(arg, &response, sizeof(response))) return -EFAULT; return 0; } +/** + * + * aac_send_raw_scb + * + */ + +int aac_send_raw_srb(struct aac_dev* dev, void* arg) +{ + struct fib* srbfib; + int status; + struct aac_srb *srbcmd; + struct aac_srb *user_srb = arg; + struct aac_srb_reply* user_reply; + struct aac_srb_reply* reply; + u32 fibsize = 0; + u32 flags = 0; + s32 rcode = 0; + u32 data_dir; + ulong sg_user[32]; + ulong sg_list[32]; + u32 sg_indx = 0; + u32 byte_count = 0; + u32 actual_fibsize = 0; + int i; + + + if (!capable(CAP_SYS_ADMIN)){ + printk(KERN_DEBUG"aacraid: No permission to send raw srb\n"); + return -EPERM; + } + /* + * Allocate and initialize a Fib then setup a BlockWrite command + */ + if (!(srbfib = fib_alloc(dev))) { + return -1; + } + fib_init(srbfib); + + srbcmd = (struct aac_srb*) fib_data(srbfib); + + if(copy_from_user((void*)&fibsize, (void*)&user_srb->count,sizeof(u32))){ + printk(KERN_DEBUG"aacraid: Could not copy data size from user\n"); + rcode = -EFAULT; + goto cleanup; + } + + if(copy_from_user(srbcmd, user_srb,fibsize)){ + printk(KERN_DEBUG"aacraid: Could not copy srb from user\n"); + rcode = -EFAULT; + goto cleanup; + } + + user_reply = arg+fibsize; + + flags = srbcmd->flags; + // Fix up srb for endian and force some values + srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this + srbcmd->channel = cpu_to_le32(srbcmd->channel); + srbcmd->target = cpu_to_le32(srbcmd->target); + srbcmd->lun = cpu_to_le32(srbcmd->lun); + srbcmd->flags = cpu_to_le32(srbcmd->flags); + srbcmd->timeout = cpu_to_le32(srbcmd->timeout); + srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter + srbcmd->cdb_size = cpu_to_le32(srbcmd->cdb_size); + + switch(srbcmd->flags & (SRB_DataIn | SRB_DataOut)){ + case SRB_DataOut: + data_dir = SCSI_DATA_WRITE; + break; + case (SRB_DataIn | SRB_DataOut): + data_dir = SCSI_DATA_UNKNOWN; + break; + case SRB_DataIn: + data_dir = SCSI_DATA_READ; + break; + default: + data_dir = SCSI_DATA_NONE; + } + + if( dev->pae_support ==1 ) { + struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg; + byte_count = 0; + + // This should also catch if user used the 32 bit sgmap + actual_fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry64)); + if(actual_fibsize != fibsize){ // User made a mistake - should not continue + printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n"); + rcode = -EINVAL; + goto cleanup; + } + if ((data_dir == SCSI_DATA_NONE) && psg->count) { // Dogs and cats sleeping with eachother - should not continue + printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n"); + rcode = -EINVAL; + goto cleanup; + } + + for (i = 0; i < psg->count; i++) { + dma_addr_t addr; + u64 le_addr; + void* p; + p = kmalloc(psg->sg[i].count,GFP_KERNEL|__GFP_DMA); + if(p == 0) { + printk(KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", + psg->sg[i].count,i,psg->count); + rcode = -ENOMEM; + goto cleanup; + } + sg_user[i] = (ulong)psg->sg[i].addr; + sg_list[i] = (ulong)p; // save so we can clean up later + sg_indx = i + 1; + + if( flags & SRB_DataOut ){ + if(copy_from_user(p,psg->sg[i].addr,psg->sg[i].count)){ + printk(KERN_DEBUG"aacraid: Could not copy sg data from user\n"); + rcode = -EFAULT; + goto cleanup; + } + } + addr = pci_map_single(dev->pdev, p, psg->sg[i].count, scsi_to_pci_dma_dir(data_dir)); + + le_addr = cpu_to_le64(addr); + psg->sg[i].addr[1] = (u32)(le_addr>>32); + psg->sg[i].addr[0] = (u32)(le_addr & 0xffffffff); + psg->sg[i].count = cpu_to_le32(psg->sg[i].count); + byte_count += psg->sg[i].count; + } + + srbcmd->count = cpu_to_le32(byte_count); + status = fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,0,0); + } else { + struct sgmap* psg = &srbcmd->sg; + byte_count = 0; + + actual_fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry)); + if(actual_fibsize != fibsize){ // User made a mistake - should not continue + printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n"); + rcode = -EINVAL; + goto cleanup; + } + if ((data_dir == SCSI_DATA_NONE) && psg->count) { // Dogs and cats sleeping with eachother - should not continue + printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n"); + rcode = -EINVAL; + goto cleanup; + } + for (i = 0; i < psg->count; i++) { + dma_addr_t addr; + void* p; + p = kmalloc(psg->sg[i].count,GFP_KERNEL); + if(p == 0) { + printk(KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", + psg->sg[i].count,i,psg->count); + rcode = -ENOMEM; + goto cleanup; + } + sg_user[i] = (ulong)(psg->sg[i].addr); + sg_list[i] = (ulong)p; // save so we can clean up later + sg_indx = i + 1; + + if( flags & SRB_DataOut ){ + if(copy_from_user((void*)p,(void*)(ulong)(psg->sg[i].addr),psg->sg[i].count)){ + printk(KERN_DEBUG"aacraid: Could not copy sg data from user\n"); + rcode = -EFAULT; + goto cleanup; + } + } + addr = pci_map_single(dev->pdev, p, psg->sg[i].count, scsi_to_pci_dma_dir(data_dir)); + + psg->sg[i].addr = cpu_to_le32(addr); + psg->sg[i].count = cpu_to_le32(psg->sg[i].count); + byte_count += psg->sg[i].count; + } + srbcmd->count = cpu_to_le32(byte_count); + status = fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, 0, 0); + } + + if (status != 0){ + printk(KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n"); + rcode = -1; + goto cleanup; + } + + if( flags & SRB_DataIn ) { + for(i = 0 ; i < sg_indx; i++){ + if(copy_to_user((void*)(sg_user[i]),(void*)(sg_list[i]),le32_to_cpu(srbcmd->sg.sg[i].count))){ + printk(KERN_DEBUG"aacraid: Could not copy sg data to user\n"); + rcode = -EFAULT; + goto cleanup; + + } + } + } + + reply = (struct aac_srb_reply *) fib_data(srbfib); + if(copy_to_user(user_reply,reply,sizeof(struct aac_srb_reply))){ + printk(KERN_DEBUG"aacraid: Could not copy reply to user\n"); + rcode = -EFAULT; + goto cleanup; + } + +cleanup: + for(i=0; i < sg_indx; i++){ + kfree((void*)sg_list[i]); + } + fib_complete(srbfib); + fib_free(srbfib); + + return rcode; +} + struct aac_pci_info { u32 bus; @@ -420,6 +636,9 @@ case FSACTL_CLOSE_GET_ADAPTER_FIB: status = close_getadapter_fib(dev, arg); break; + case FSACTL_SEND_RAW_SRB: + status = aac_send_raw_srb(dev,arg); + break; case FSACTL_GET_PCI_INFO: status = aac_get_pci_info(dev,arg); break; Index: drivers/scsi/aacraid/comminit.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aacraid/comminit.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aacraid/comminit.c 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/aacraid/comminit.c 4 Aug 2004 01:29:39 -0000 1.2 @@ -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->aif_base_va = (struct hw_fib *)base; + + /* We submit the physical address for AIF tags to limit to 32 bits */ + init->AdapterFibsVirtualAddress = cpu_to_le32(0); + 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 << PAGE_SHIFT) / 4096); // 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); /* Index: drivers/scsi/aacraid/commsup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aacraid/commsup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aacraid/commsup.c 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/aacraid/commsup.c 4 Aug 2004 01:29:39 -0000 1.2 @@ -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 = 0; /* Filled in later if needed */ + 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,21 @@ 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 = cpu_to_le32(((u32)(fibptr - dev->fibs)) << 1); + 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 +459,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 +474,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 +506,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 +550,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 +570,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 +589,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 +631,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 +649,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 +701,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 +721,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 +781,125 @@ * 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; + + /* 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 != (struct proc_dir_entry *)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; + mm_segment_t fs; + + 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 +914,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 +936,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 +947,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 +1009,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 +1030,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 +1053,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 Index: drivers/scsi/aacraid/dpcsup.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aacraid/dpcsup.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aacraid/dpcsup.c 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/aacraid/dpcsup.c 4 Aug 2004 01:29:39 -0000 1.2 @@ -75,11 +75,13 @@ while(aac_consumer_get(dev, q, &entry)) { int fast; + u32 index; + index = le32_to_cpu(entry->addr); + fast = index & 0x01; + fib = &dev->fibs[index >> 1]; + hwfib = fib->hw_fib; - 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,50 @@ * 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 hw_fib * hw_fib; + u32 index; + struct fib *fib = &fibctx; + + index = le32_to_cpu(entry->addr / sizeof(struct hw_fib)); + hw_fib = &dev->aif_base_va[index]; - 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; + fib->data = hw_fib->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->data = cpu_to_le32(ST_OK); + fib_adapter_complete(fib, sizeof(u32)); spin_lock_irqsave(q->lock, flags); } } Index: drivers/scsi/aacraid/linit.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aacraid/linit.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aacraid/linit.c 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/aacraid/linit.c 4 Aug 2004 01:29:39 -0000 1.2 @@ -35,9 +35,6 @@ * */ -#define AAC_DRIVER_VERSION "0.9.9ac6-TEST" -#define AAC_DRIVER_BUILD_DATE __DATE__ - #include #include #include @@ -56,15 +53,11 @@ #include "aacraid.h" #include "sd.h" -#define AAC_DRIVERNAME "aacraid" +#define AAC_DRIVER_NAME "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"); - -static int nondasd=-1; struct aac_dev *aac_devices[MAXIMUM_NUM_ADAPTERS]; @@ -81,25 +74,45 @@ */ 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) */ + { 0x9005, 0x0285, 0x0E11, 0x0295, aac_rx_init, "aacraid", "ADAPTEC ", "SATA 6Channel ", 1 }, /* SATA 6Ch (Bearcat) */ + + { 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 */ + { 0x9005, 0x0285, 0x1028, PCI_ANY_ID, + aac_rx_init, "aacraid", "DELL ", "RAID ", 2, AAC_QUIRK_31BIT },/* Dell Catchall */ + { 0x9005, 0x0285, 0x17aa, PCI_ANY_ID, + aac_rx_init, "aacraid", "Legend ", "RAID ", 2, AAC_QUIRK_31BIT },/* Legend Catchall */ + { 0x9005, 0x0285, PCI_ANY_ID, PCI_ANY_ID, + aac_rx_init, "aacraid", "ADAPTEC ", "RAID ", 2, AAC_QUIRK_31BIT } /* Adaptec Catch All */ }; #define NUM_AACTYPES (sizeof(aac_drivers) / sizeof(struct aac_driver_ident)) @@ -159,10 +172,17 @@ 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 %s driver (%d.%d-%d %s)\n", + AAC_DRIVER_NAME, + AAC_DRIVER_VERSION >> 24, + (AAC_DRIVER_VERSION >> 16) & 0xFF, + (AAC_DRIVER_VERSION >> 8) & 0xFF, + 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 +199,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 +212,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 +225,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 +259,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 +282,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 +298,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 +310,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; @@ -601,7 +610,7 @@ static int aac_eh_reset(Scsi_Cmnd* cmd) { - printk(KERN_ERR "aacraid: Host adapter reset request. SCSI hang ?\n"); + printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n", AAC_DRIVER_NAME); return FAILED; } @@ -735,10 +744,41 @@ static int aac_procinfo(char *proc_buffer, char **start_ptr,off_t offset, int bytes_available, int host_no, int write) { + struct aac_dev * dev; + int index, ret, tmp; + if(write || offset > 0) return 0; *start_ptr = proc_buffer; - return sprintf(proc_buffer, "%s %d\n", "Raid Controller, scsi hba number", host_no); + ret = sprintf(proc_buffer, + "Adaptec Raid Controller %d.%d-%d %s, scsi hba number %d\n", + AAC_DRIVER_VERSION >> 24, + (AAC_DRIVER_VERSION >> 16) & 0xFF, + (AAC_DRIVER_VERSION >> 8) & 0xFF, + AAC_DRIVER_BUILD_DATE, + host_no); + for (index = 0; index < aac_count; ++index) { + if (((dev = aac_devices[index]) != NULL) && dev->scsi_host_ptr->host_no == host_no) + break; + } + if (index >= aac_count || dev == NULL) + return ret; + tmp = dev->adapter_info.kernelrev; + ret += sprintf(proc_buffer + ret, "kernel: %d.%d-%d[%d]\n", + tmp >> 24, (tmp >> 16) & 0xff, (tmp >> 8) & 0xff, + dev->adapter_info.kernelbuild); + tmp = dev->adapter_info.monitorrev; + ret += sprintf(proc_buffer + ret, "monitor: %d.%d-%d[%d]\n", + tmp >> 24, (tmp >> 16) & 0xff, (tmp >> 8) & 0xff, + dev->adapter_info.monitorbuild); + tmp = dev->adapter_info.biosrev; + ret += sprintf(proc_buffer + ret, "bios: %d.%d-%d[%d]\n", + tmp >> 24, (tmp >> 16) & 0xff, (tmp >> 8) & 0xff, + dev->adapter_info.biosbuild); + ret += sprintf(proc_buffer + ret, "serial: %x%x\n", + dev->adapter_info.serial[0], + dev->adapter_info.serial[1]); + return ret; } EXPORT_NO_SYMBOLS; Index: drivers/scsi/aacraid/rx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aacraid/rx.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aacraid/rx.c 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/aacraid/rx.c 4 Aug 2004 01:29:39 -0000 1.2 @@ -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 Index: drivers/scsi/aacraid/sa.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aacraid/sa.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aacraid/sa.c 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/aacraid/sa.c 4 Aug 2004 01:29:39 -0000 1.2 @@ -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 Index: drivers/scsi/aic79xx/CHANGELOG =================================================================== RCS file: drivers/scsi/aic79xx/CHANGELOG diff -N drivers/scsi/aic79xx/CHANGELOG --- drivers/scsi/aic79xx/CHANGELOG 22 Jul 2004 19:50:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: CHANGELOG,v 1.1 2004/07/22 19:50:09 joff Exp $ 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 - Index: drivers/scsi/aic79xx/Config.in =================================================================== RCS file: drivers/scsi/aic79xx/Config.in diff -N drivers/scsi/aic79xx/Config.in --- drivers/scsi/aic79xx/Config.in 22 Jul 2004 19:50:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: drivers/scsi/aic79xx/Makefile =================================================================== RCS file: drivers/scsi/aic79xx/Makefile diff -N drivers/scsi/aic79xx/Makefile --- drivers/scsi/aic79xx/Makefile 22 Jul 2004 19:50:08 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: drivers/scsi/aic79xx/aic79xx.h =================================================================== RCS file: drivers/scsi/aic79xx/aic79xx.h diff -N drivers/scsi/aic79xx/aic79xx.h --- drivers/scsi/aic79xx/aic79xx.h 22 Jul 2004 19:50:08 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aic79xx.h,v 1.1 2004/07/22 19:50:08 joff Exp $ - * - * $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_ */ Index: drivers/scsi/aic79xx/aic79xx.reg =================================================================== RCS file: drivers/scsi/aic79xx/aic79xx.reg diff -N drivers/scsi/aic79xx/aic79xx.reg --- drivers/scsi/aic79xx/aic79xx.reg 22 Jul 2004 19:50:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aic79xx.reg,v 1.1 2004/07/22 19:50:09 joff Exp $" - -/* - * 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 Index: drivers/scsi/aic79xx/aic79xx.seq =================================================================== RCS file: drivers/scsi/aic79xx/aic79xx.seq diff -N drivers/scsi/aic79xx/aic79xx.seq --- drivers/scsi/aic79xx/aic79xx.seq 22 Jul 2004 19:50:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aic79xx.seq,v 1.1 2004/07/22 19:50:09 joff Exp $" -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: Index: drivers/scsi/aic79xx/aic79xx_core.c =================================================================== RCS file: drivers/scsi/aic79xx/aic79xx_core.c diff -N drivers/scsi/aic79xx/aic79xx_core.c --- drivers/scsi/aic79xx/aic79xx_core.c 22 Jul 2004 19:50:08 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aic79xx_core.c,v 1.1 2004/07/22 19:50:08 joff Exp $ - * - * $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 Index: drivers/scsi/aic79xx/aic79xx_inline.h =================================================================== RCS file: drivers/scsi/aic79xx/aic79xx_inline.h diff -N drivers/scsi/aic79xx/aic79xx_inline.h --- drivers/scsi/aic79xx/aic79xx_inline.h 22 Jul 2004 19:50:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aic79xx_inline.h,v 1.1 2004/07/22 19:50:09 joff Exp $ - * - * $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_ */ Index: drivers/scsi/aic79xx/aic79xx_osm.c =================================================================== RCS file: drivers/scsi/aic79xx/aic79xx_osm.c diff -N drivers/scsi/aic79xx/aic79xx_osm.c --- drivers/scsi/aic79xx/aic79xx_osm.c 22 Jul 2004 19:50:08 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,5322 +0,0 @@ -/* - * Adaptec AIC79xx device driver for Linux. - * - * $Id: aic79xx_osm.c,v 1.1 2004/07/22 19:50:08 joff Exp $ - * - * -------------------------------------------------------------------------- - * 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); - } - } -} Index: drivers/scsi/aic79xx/aic79xx_osm.h =================================================================== RCS file: drivers/scsi/aic79xx/aic79xx_osm.h diff -N drivers/scsi/aic79xx/aic79xx_osm.h --- drivers/scsi/aic79xx/aic79xx_osm.h 22 Jul 2004 19:50:08 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aic79xx_osm.h,v 1.1 2004/07/22 19:50:08 joff Exp $ - * - */ -#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_ */ Index: drivers/scsi/aic79xx/aic79xx_osm_pci.c =================================================================== RCS file: drivers/scsi/aic79xx/aic79xx_osm_pci.c diff -N drivers/scsi/aic79xx/aic79xx_osm_pci.c --- drivers/scsi/aic79xx/aic79xx_osm_pci.c 22 Jul 2004 19:50:08 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aic79xx_osm_pci.c,v 1.1 2004/07/22 19:50:08 joff Exp $ - */ - -#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 -} Index: drivers/scsi/aic79xx/aic79xx_pci.c =================================================================== RCS file: drivers/scsi/aic79xx/aic79xx_pci.c diff -N drivers/scsi/aic79xx/aic79xx_pci.c --- drivers/scsi/aic79xx/aic79xx_pci.c 22 Jul 2004 19:50:08 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aic79xx_pci.c,v 1.1 2004/07/22 19:50:08 joff Exp $ - * - * $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); -} Index: drivers/scsi/aic79xx/aic79xx_proc.c =================================================================== RCS file: drivers/scsi/aic79xx/aic79xx_proc.c diff -N drivers/scsi/aic79xx/aic79xx_proc.c --- drivers/scsi/aic79xx/aic79xx_proc.c 22 Jul 2004 19:50:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aic79xx_proc.c,v 1.1 2004/07/22 19:50:09 joff Exp $ - */ -#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); -} Index: drivers/scsi/aic79xx/aic79xx_reg.h =================================================================== RCS file: drivers/scsi/aic79xx/aic79xx_reg.h diff -N drivers/scsi/aic79xx/aic79xx_reg.h --- drivers/scsi/aic79xx/aic79xx_reg.h 22 Jul 2004 19:50:08 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,3778 +0,0 @@ -/* - * DO NOT EDIT - This file is automatically generated - * from the following source files: - * - * $Id: aic79xx_reg.h,v 1.1 2004/07/22 19:50:08 joff Exp $ - * $Id: aic79xx_reg.h,v 1.1 2004/07/22 19:50:08 joff Exp $ - */ -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 Index: drivers/scsi/aic79xx/aic79xx_reg_print.c =================================================================== RCS file: drivers/scsi/aic79xx/aic79xx_reg_print.c diff -N drivers/scsi/aic79xx/aic79xx_reg_print.c --- drivers/scsi/aic79xx/aic79xx_reg_print.c 22 Jul 2004 19:50:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,3632 +0,0 @@ -/* - * DO NOT EDIT - This file is automatically generated - * from the following source files: - * - * $Id: aic79xx_reg_print.c,v 1.1 2004/07/22 19:50:09 joff Exp $ - * $Id: aic79xx_reg_print.c,v 1.1 2004/07/22 19:50:09 joff Exp $ - */ - -#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)); -} - Index: drivers/scsi/aic79xx/aic79xx_seq.h =================================================================== RCS file: drivers/scsi/aic79xx/aic79xx_seq.h diff -N drivers/scsi/aic79xx/aic79xx_seq.h --- drivers/scsi/aic79xx/aic79xx_seq.h 22 Jul 2004 19:50:08 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1085 +0,0 @@ -/* - * DO NOT EDIT - This file is automatically generated - * from the following source files: - * - * $Id: aic79xx_seq.h,v 1.1 2004/07/22 19:50:08 joff Exp $ - * $Id: aic79xx_seq.h,v 1.1 2004/07/22 19:50:08 joff Exp $ - */ -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); Index: drivers/scsi/aic79xx/aiclib.c =================================================================== RCS file: drivers/scsi/aic79xx/aiclib.c diff -N drivers/scsi/aic79xx/aiclib.c --- drivers/scsi/aic79xx/aiclib.c 22 Jul 2004 19:50:08 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aiclib.c,v 1.1 2004/07/22 19:50:08 joff Exp $ - */ - -#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); -} - Index: drivers/scsi/aic79xx/aiclib.h =================================================================== RCS file: drivers/scsi/aic79xx/aiclib.h diff -N drivers/scsi/aic79xx/aiclib.h --- drivers/scsi/aic79xx/aiclib.h 22 Jul 2004 19:50:08 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aiclib.h,v 1.1 2004/07/22 19:50:08 joff Exp $ - */ - -/* - * 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*/ Index: drivers/scsi/aic79xx/cam.h =================================================================== RCS file: drivers/scsi/aic79xx/cam.h diff -N drivers/scsi/aic79xx/cam.h --- drivers/scsi/aic79xx/cam.h 22 Jul 2004 19:50:08 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: cam.h,v 1.1 2004/07/22 19:50:08 joff Exp $ - */ - -#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 */ Index: drivers/scsi/aic79xx/queue.h =================================================================== RCS file: drivers/scsi/aic79xx/queue.h diff -N drivers/scsi/aic79xx/queue.h --- drivers/scsi/aic79xx/queue.h 22 Jul 2004 19:50:08 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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_ */ Index: drivers/scsi/aic79xx/scsi_iu.h =================================================================== RCS file: drivers/scsi/aic79xx/scsi_iu.h diff -N drivers/scsi/aic79xx/scsi_iu.h --- drivers/scsi/aic79xx/scsi_iu.h 22 Jul 2004 19:50:08 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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*/ Index: drivers/scsi/aic79xx/scsi_message.h =================================================================== RCS file: drivers/scsi/aic79xx/scsi_message.h diff -N drivers/scsi/aic79xx/scsi_message.h --- drivers/scsi/aic79xx/scsi_message.h 22 Jul 2004 19:50:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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 Index: drivers/scsi/aic79xx/aicasm/Makefile =================================================================== RCS file: drivers/scsi/aic79xx/aicasm/Makefile diff -N drivers/scsi/aic79xx/aicasm/Makefile --- drivers/scsi/aic79xx/aicasm/Makefile 22 Jul 2004 19:50:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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$@ $< Index: drivers/scsi/aic79xx/aicasm/aicasm.c =================================================================== RCS file: drivers/scsi/aic79xx/aicasm/aicasm.c diff -N drivers/scsi/aic79xx/aicasm/aicasm.c --- drivers/scsi/aic79xx/aicasm/aicasm.c 22 Jul 2004 19:50:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aicasm.c,v 1.1 2004/07/22 19:50:09 joff Exp $ - * - * $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); - } -} Index: drivers/scsi/aic79xx/aicasm/aicasm.h =================================================================== RCS file: drivers/scsi/aic79xx/aicasm/aicasm.h diff -N drivers/scsi/aic79xx/aicasm/aicasm.h --- drivers/scsi/aic79xx/aicasm/aicasm.h 22 Jul 2004 19:50:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aicasm.h,v 1.1 2004/07/22 19:50:09 joff Exp $ - * - * $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 *); Index: drivers/scsi/aic79xx/aicasm/aicasm_gram.y =================================================================== RCS file: drivers/scsi/aic79xx/aicasm/aicasm_gram.y diff -N drivers/scsi/aic79xx/aicasm/aicasm_gram.y --- drivers/scsi/aic79xx/aicasm/aicasm_gram.y 22 Jul 2004 19:50:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aicasm_gram.y,v 1.1 2004/07/22 19:50:09 joff Exp $ - * - * $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); -} Index: drivers/scsi/aic79xx/aicasm/aicasm_insformat.h =================================================================== RCS file: drivers/scsi/aic79xx/aicasm/aicasm_insformat.h diff -N drivers/scsi/aic79xx/aicasm/aicasm_insformat.h --- drivers/scsi/aic79xx/aicasm/aicasm_insformat.h 22 Jul 2004 19:50:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aicasm_insformat.h,v 1.1 2004/07/22 19:50:09 joff Exp $ - * - * $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 Index: drivers/scsi/aic79xx/aicasm/aicasm_macro_gram.y =================================================================== RCS file: drivers/scsi/aic79xx/aicasm/aicasm_macro_gram.y diff -N drivers/scsi/aic79xx/aicasm/aicasm_macro_gram.y --- drivers/scsi/aic79xx/aicasm/aicasm_macro_gram.y 22 Jul 2004 19:50:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aicasm_macro_gram.y,v 1.1 2004/07/22 19:50:09 joff Exp $ - * - * $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); -} Index: drivers/scsi/aic79xx/aicasm/aicasm_macro_scan.l =================================================================== RCS file: drivers/scsi/aic79xx/aicasm/aicasm_macro_scan.l diff -N drivers/scsi/aic79xx/aicasm/aicasm_macro_scan.l --- drivers/scsi/aic79xx/aicasm/aicasm_macro_scan.l 22 Jul 2004 19:50:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aicasm_macro_scan.l,v 1.1 2004/07/22 19:50:09 joff Exp $ - * - * $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); -} Index: drivers/scsi/aic79xx/aicasm/aicasm_scan.l =================================================================== RCS file: drivers/scsi/aic79xx/aicasm/aicasm_scan.l diff -N drivers/scsi/aic79xx/aicasm/aicasm_scan.l --- drivers/scsi/aic79xx/aicasm/aicasm_scan.l 22 Jul 2004 19:50:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aicasm_scan.l,v 1.1 2004/07/22 19:50:09 joff Exp $ - * - * $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); -} Index: drivers/scsi/aic79xx/aicasm/aicasm_symbol.c =================================================================== RCS file: drivers/scsi/aic79xx/aicasm/aicasm_symbol.c diff -N drivers/scsi/aic79xx/aicasm/aicasm_symbol.c --- drivers/scsi/aic79xx/aicasm/aicasm_symbol.c 22 Jul 2004 19:50:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aicasm_symbol.c,v 1.1 2004/07/22 19:50:09 joff Exp $ - * - * $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); - } -} - Index: drivers/scsi/aic79xx/aicasm/aicasm_symbol.h =================================================================== RCS file: drivers/scsi/aic79xx/aicasm/aicasm_symbol.h diff -N drivers/scsi/aic79xx/aicasm/aicasm_symbol.h --- drivers/scsi/aic79xx/aicasm/aicasm_symbol.h 22 Jul 2004 19:50:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aicasm_symbol.h,v 1.1 2004/07/22 19:50:09 joff Exp $ - * - * $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); Index: drivers/scsi/aic7xxx/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/Config.in 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/Config.in 4 Aug 2004 01:29:41 -0000 1.2 @@ -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 Index: drivers/scsi/aic7xxx/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/Makefile 22 Jul 2004 19:50:09 -0000 1.1 +++ drivers/scsi/aic7xxx/Makefile 4 Aug 2004 01:29:41 -0000 1.2 @@ -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] Index: drivers/scsi/aic7xxx/aic7770.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aic7770.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aic7770.c 22 Jul 2004 19:50:09 -0000 1.1 +++ drivers/scsi/aic7xxx/aic7770.c 4 Aug 2004 01:29:41 -0000 1.2 @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: aic7770.c,v 1.1 2004/07/22 19:50:09 joff Exp $ + * $Id: aic7770.c,v 1.2 2004/08/04 01:29:41 joff Exp $ * - * $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); } Index: drivers/scsi/aic7xxx/aic7770_osm.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aic7770_osm.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aic7770_osm.c 22 Jul 2004 19:50:09 -0000 1.1 +++ drivers/scsi/aic7xxx/aic7770_osm.c 4 Aug 2004 01:29:41 -0000 1.2 @@ -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: aic7770_osm.c,v 1.1 2004/07/22 19:50:09 joff Exp $ + * $Id: aic7770_osm.c,v 1.2 2004/08/04 01:29:41 joff Exp $ */ #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 Index: drivers/scsi/aic7xxx/aic7xxx.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aic7xxx.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aic7xxx.h 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aic7xxx.h 4 Aug 2004 01:29:41 -0000 1.2 @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: aic7xxx.h,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aic7xxx.h,v 1.2 2004/08/04 01:29:41 joff Exp $ * - * $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); Index: drivers/scsi/aic7xxx/aic7xxx.reg =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aic7xxx.reg,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aic7xxx.reg 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aic7xxx.reg 4 Aug 2004 01:29:41 -0000 1.2 @@ -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: aic7xxx.reg,v 1.1 2004/07/22 19:50:10 joff Exp $" +VERSION = "$Id: aic7xxx.reg,v 1.2 2004/08/04 01:29:41 joff Exp $" /* * 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 */ Index: drivers/scsi/aic7xxx/aic7xxx.seq =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aic7xxx.seq,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aic7xxx.seq 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aic7xxx.seq 4 Aug 2004 01:29:41 -0000 1.2 @@ -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: aic7xxx.seq,v 1.1 2004/07/22 19:50:10 joff Exp $" +VERSION = "$Id: aic7xxx.seq,v 1.2 2004/08/04 01:29:41 joff Exp $" 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; Index: drivers/scsi/aic7xxx/aic7xxx_93cx6.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aic7xxx_93cx6.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aic7xxx_93cx6.c 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aic7xxx_93cx6.c 4 Aug 2004 01:29:41 -0000 1.2 @@ -28,9 +28,9 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: aic7xxx_93cx6.c,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aic7xxx_93cx6.c,v 1.2 2004/08/04 01:29:41 joff Exp $ * - * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_93cx6.c,v 1.8.2.5 2002/04/29 19:36:31 gibbs Exp $ + * $FreeBSD$ */ /* Index: drivers/scsi/aic7xxx/aic7xxx_93cx6.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aic7xxx_93cx6.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aic7xxx_93cx6.h 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aic7xxx_93cx6.h 4 Aug 2004 01:29:42 -0000 1.2 @@ -38,9 +38,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: aic7xxx_93cx6.h,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aic7xxx_93cx6.h,v 1.2 2004/08/04 01:29:42 joff Exp $ * - * $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_ Index: drivers/scsi/aic7xxx/aic7xxx_core.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aic7xxx_core.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aic7xxx_core.c 22 Jul 2004 19:50:09 -0000 1.1 +++ drivers/scsi/aic7xxx/aic7xxx_core.c 4 Aug 2004 01:29:42 -0000 1.2 @@ -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: aic7xxx_core.c,v 1.1 2004/07/22 19:50:09 joff Exp $ + * $Id: aic7xxx_core.c,v 1.2 2004/08/04 01:29:42 joff Exp $ * - * $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); Index: drivers/scsi/aic7xxx/aic7xxx_host.h =================================================================== RCS file: drivers/scsi/aic7xxx/aic7xxx_host.h diff -N drivers/scsi/aic7xxx/aic7xxx_host.h --- drivers/scsi/aic7xxx/aic7xxx_host.h 22 Jul 2004 19:50:09 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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: aic7xxx_host.h,v 1.1 2004/07/22 19:50:09 joff Exp $ - */ - -#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_ */ Index: drivers/scsi/aic7xxx/aic7xxx_inline.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aic7xxx_inline.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aic7xxx_inline.h 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aic7xxx_inline.h 4 Aug 2004 01:29:42 -0000 1.2 @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: aic7xxx_inline.h,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aic7xxx_inline.h,v 1.2 2004/08/04 01:29:42 joff Exp $ * - * $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_ */ Index: drivers/scsi/aic7xxx/aic7xxx_osm.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aic7xxx_osm.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aic7xxx_osm.c 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aic7xxx_osm.c 4 Aug 2004 01:29:42 -0000 1.2 @@ -1,7 +1,7 @@ /* * Adaptec AIC7xxx device driver for Linux. * - * $Id: aic7xxx_osm.c,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aic7xxx_osm.c,v 1.2 2004/08/04 01:29:42 joff Exp $ * * 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,2812 @@ 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) { +#ifdef CONFIG_PCI + 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; + } +#endif +#ifdef CONFIG_EISA + 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; +#endif + 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 +3557,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 +3580,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 +3672,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 +3701,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 +3714,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 +3763,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 +3867,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 +3898,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 +3909,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 +3917,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 +3994,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 +4074,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 +4116,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 +4141,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 +4183,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 +4220,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 +4230,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 +4275,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 +4359,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 +4400,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 +4681,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 +4701,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 +4719,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 +4775,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 +4788,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 +4800,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 +4823,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 +4833,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 +4848,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 +4896,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 +4911,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 +4926,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 +4957,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 +4982,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 +5015,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 +5077,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); Index: drivers/scsi/aic7xxx/aic7xxx_osm.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aic7xxx_osm.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aic7xxx_osm.h 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aic7xxx_osm.h 4 Aug 2004 01:29:42 -0000 1.2 @@ -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: aic7xxx_osm.h,v 1.1 2004/07/22 19:50:10 joff Exp $ - * - * 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: aic7xxx_osm.h,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aic7xxx_osm.h,v 1.2 2004/08/04 01:29:42 joff Exp $ * */ #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_ */ Index: drivers/scsi/aic7xxx/aic7xxx_osm_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aic7xxx_osm_pci.c 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aic7xxx_osm_pci.c 4 Aug 2004 01:29:42 -0000 1.2 @@ -36,7 +36,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: aic7xxx_osm_pci.c,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aic7xxx_osm_pci.c,v 1.2 2004/08/04 01:29:42 joff Exp $ */ #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)); Index: drivers/scsi/aic7xxx/aic7xxx_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aic7xxx_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aic7xxx_pci.c 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aic7xxx_pci.c 4 Aug 2004 01:29:42 -0000 1.2 @@ -39,9 +39,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: aic7xxx_pci.c,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aic7xxx_pci.c,v 1.2 2004/08/04 01:29:42 joff Exp $ * - * $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); } Index: drivers/scsi/aic7xxx/aic7xxx_proc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aic7xxx_proc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aic7xxx_proc.c 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aic7xxx_proc.c 4 Aug 2004 01:29:42 -0000 1.2 @@ -37,7 +37,7 @@ * String handling code courtesy of Gerard Roudier's * sym driver. * - * $Id: aic7xxx_proc.c,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aic7xxx_proc.c,v 1.2 2004/08/04 01:29:42 joff Exp $ */ #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"); Index: drivers/scsi/aic7xxx/aic7xxx_reg.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aic7xxx_reg.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aic7xxx_reg.h 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aic7xxx_reg.h 4 Aug 2004 01:29:42 -0000 1.2 @@ -2,9 +2,1066 @@ * DO NOT EDIT - This file is automatically generated * from the following source files: * - * $Id: aic7xxx_reg.h,v 1.1 2004/07/22 19:50:10 joff Exp $ - * $Id: aic7xxx_reg.h,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aic7xxx_reg.h,v 1.2 2004/08/04 01:29:42 joff Exp $ + * $Id: aic7xxx_reg.h,v 1.2 2004/08/04 01:29:42 joff Exp $ */ +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 */ Index: drivers/scsi/aic7xxx/aic7xxx_seq.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aic7xxx_seq.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aic7xxx_seq.h 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aic7xxx_seq.h 4 Aug 2004 01:29:42 -0000 1.2 @@ -2,13 +2,13 @@ * DO NOT EDIT - This file is automatically generated * from the following source files: * - * $Id: aic7xxx_seq.h,v 1.1 2004/07/22 19:50:10 joff Exp $ - * $Id: aic7xxx_seq.h,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aic7xxx_seq.h,v 1.2 2004/08/04 01:29:42 joff Exp $ + * $Id: aic7xxx_seq.h,v 1.2 2004/08/04 01:29:42 joff Exp $ */ 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); Index: drivers/scsi/aic7xxx/cam.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/cam.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/cam.h 22 Jul 2004 19:50:09 -0000 1.1 +++ drivers/scsi/aic7xxx/cam.h 4 Aug 2004 01:29:42 -0000 1.2 @@ -29,13 +29,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: cam.h,v 1.1 2004/07/22 19:50:09 joff Exp $ + * $Id: cam.h,v 1.2 2004/08/04 01:29:42 joff Exp $ */ #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; Index: drivers/scsi/aic7xxx/scsi_iu.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/scsi_iu.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/scsi_iu.h 22 Jul 2004 19:50:09 -0000 1.1 +++ drivers/scsi/aic7xxx/scsi_iu.h 4 Aug 2004 01:29:42 -0000 1.2 @@ -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*/ Index: drivers/scsi/aic7xxx/aicasm/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aicasm/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aicasm/Makefile 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aicasm/Makefile 4 Aug 2004 01:29:42 -0000 1.2 @@ -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=) $< Index: drivers/scsi/aic7xxx/aicasm/aicasm.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aicasm/aicasm.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aicasm/aicasm.c 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aicasm/aicasm.c 4 Aug 2004 01:29:42 -0000 1.2 @@ -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: aicasm.c,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aicasm.c,v 1.2 2004/08/04 01:29:42 joff Exp $ * - * $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); } Index: drivers/scsi/aic7xxx/aicasm/aicasm.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aicasm/aicasm.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aicasm/aicasm.h 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aicasm/aicasm.h 4 Aug 2004 01:29:42 -0000 1.2 @@ -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: aicasm.h,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aicasm.h,v 1.2 2004/08/04 01:29:42 joff Exp $ * - * $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; Index: drivers/scsi/aic7xxx/aicasm/aicasm_gram.y =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aicasm/aicasm_gram.y 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aicasm/aicasm_gram.y 4 Aug 2004 01:29:42 -0000 1.2 @@ -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: aicasm_gram.y,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aicasm_gram.y,v 1.2 2004/08/04 01:29:42 joff Exp $ * - * $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); Index: drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h 4 Aug 2004 01:29:43 -0000 1.2 @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: aicasm_insformat.h,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aicasm_insformat.h,v 1.2 2004/08/04 01:29:43 joff Exp $ * - * $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 { Index: drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y 4 Aug 2004 01:29:43 -0000 1.2 @@ -38,9 +38,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: aicasm_macro_gram.y,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aicasm_macro_gram.y,v 1.2 2004/08/04 01:29:43 joff Exp $ * - * $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 Index: drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l 4 Aug 2004 01:29:43 -0000 1.2 @@ -38,13 +38,14 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: aicasm_macro_scan.l,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aicasm_macro_scan.l,v 1.2 2004/08/04 01:29:43 joff Exp $ * - * $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 Index: drivers/scsi/aic7xxx/aicasm/aicasm_scan.l =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aicasm/aicasm_scan.l 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aicasm/aicasm_scan.l 4 Aug 2004 01:29:43 -0000 1.2 @@ -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: aicasm_scan.l,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aicasm_scan.l,v 1.2 2004/08/04 01:29:43 joff Exp $ * - * $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; } Index: drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c 4 Aug 2004 01:29:43 -0000 1.2 @@ -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: aicasm_symbol.c,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aicasm_symbol.c,v 1.2 2004/08/04 01:29:43 joff Exp $ * - * $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); } } Index: drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h 4 Aug 2004 01:29:43 -0000 1.2 @@ -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: aicasm_symbol.h,v 1.1 2004/07/22 19:50:10 joff Exp $ + * $Id: aicasm_symbol.h,v 1.2 2004/08/04 01:29:43 joff Exp $ * - * $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); Index: drivers/scsi/aic7xxx_old/README.aic7xxx =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx_old/README.aic7xxx,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx_old/README.aic7xxx 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/aic7xxx_old/README.aic7xxx 4 Aug 2004 01:29:43 -0000 1.2 @@ -505,7 +505,7 @@ Dean W. Gehnert deang@teleport.com -$Revision: 1.1 $ +$Revision: 1.2 $ Modified by Doug Ledford 1998-2000 Index: drivers/scsi/aic7xxx_old/aic7xxx.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx_old/aic7xxx.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx_old/aic7xxx.h 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/aic7xxx_old/aic7xxx.h 4 Aug 2004 01:29:43 -0000 1.2 @@ -18,7 +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: aic7xxx.h,v 1.1 2004/07/22 19:50:08 joff Exp $ + * $Id: aic7xxx.h,v 1.2 2004/08/04 01:29:43 joff Exp $ *-M*************************************************************************/ #ifndef _aic7xxx_h #define _aic7xxx_h Index: drivers/scsi/aic7xxx_old/aic7xxx.reg =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx_old/aic7xxx.reg,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx_old/aic7xxx.reg 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/aic7xxx_old/aic7xxx.reg 4 Aug 2004 01:29:43 -0000 1.2 @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: aic7xxx.reg,v 1.1 2004/07/22 19:50:08 joff Exp $ + * $Id: aic7xxx.reg,v 1.2 2004/08/04 01:29:43 joff Exp $ */ /* Index: drivers/scsi/aic7xxx_old/aic7xxx.seq =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx_old/aic7xxx.seq,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx_old/aic7xxx.seq 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/aic7xxx_old/aic7xxx.seq 4 Aug 2004 01:29:43 -0000 1.2 @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: aic7xxx.seq,v 1.1 2004/07/22 19:50:08 joff Exp $ + * $Id: aic7xxx.seq,v 1.2 2004/08/04 01:29:43 joff Exp $ */ #include "aic7xxx.reg" Index: drivers/scsi/aic7xxx_old/aic7xxx_proc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx_old/aic7xxx_proc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx_old/aic7xxx_proc.c 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/aic7xxx_old/aic7xxx_proc.c 4 Aug 2004 01:29:43 -0000 1.2 @@ -26,7 +26,7 @@ * * Dean W. Gehnert, deang@teleport.com, 05/01/96 * - * $Id: aic7xxx_proc.c,v 1.1 2004/07/22 19:50:08 joff Exp $ + * $Id: aic7xxx_proc.c,v 1.2 2004/08/04 01:29:43 joff Exp $ *-M*************************************************************************/ #include Index: drivers/scsi/aic7xxx_old/sequencer.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/aic7xxx_old/sequencer.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/aic7xxx_old/sequencer.h 22 Jul 2004 19:50:07 -0000 1.1 +++ drivers/scsi/aic7xxx_old/sequencer.h 4 Aug 2004 01:29:43 -0000 1.2 @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: sequencer.h,v 1.1 2004/07/22 19:50:07 joff Exp $ + * $Id: sequencer.h,v 1.2 2004/08/04 01:29:43 joff Exp $ */ #ifdef __LITTLE_ENDIAN_BITFIELD Index: drivers/scsi/pcmcia/aha152x_stub.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/pcmcia/aha152x_stub.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/pcmcia/aha152x_stub.c 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/pcmcia/aha152x_stub.c 4 Aug 2004 01:29:43 -0000 1.2 @@ -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; Index: drivers/scsi/pcmcia/fdomain_stub.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/pcmcia/fdomain_stub.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/pcmcia/fdomain_stub.c 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/pcmcia/fdomain_stub.c 4 Aug 2004 01:29:43 -0000 1.2 @@ -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; Index: drivers/scsi/pcmcia/nsp_cs.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/pcmcia/nsp_cs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/pcmcia/nsp_cs.c 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/pcmcia/nsp_cs.c 4 Aug 2004 01:29:43 -0000 1.2 @@ -1,8 +1,10 @@ /*====================================================================== - NinjaSCSI-3 / NinjaSCSI-32Bi PCMCIA SCSI hostadapter card driver + NinjaSCSI-3 / NinjaSCSI-32Bi PCMCIA SCSI host adapter card driver By: YOKOTA Hiroshi + Ver.2.8 Support 32bit MMIO mode + Support Synchronous Data Transfer Request (SDTR) mode Ver.2.0 Support 32bit PIO mode Ver.1.1.2 Fix for scatter list buffer exceeds Ver.1.1 Support scatter list @@ -23,13 +25,9 @@ ***********************************************************************/ -/* $Id: nsp_cs.c,v 1.1 2004/07/22 19:50:08 joff Exp $ */ - -#ifdef NSP_KERNEL_2_2 -#include -#include -#endif +/* $Id: nsp_cs.c,v 1.2 2004/08/04 01:29:43 joff Exp $ */ +#include #include #include #include @@ -39,19 +37,20 @@ #include #include #include -#include #include #include #include -#include +#include #include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) +# include +#endif #include #include #include <../drivers/scsi/scsi.h> #include <../drivers/scsi/hosts.h> -#include <../drivers/scsi/sd.h> #include #include @@ -60,138 +59,192 @@ #include #include #include +#include #include #include "nsp_cs.h" MODULE_AUTHOR("YOKOTA Hiroshi "); -MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module"); +MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module $Revision: 1.2 $"); MODULE_SUPPORTED_DEVICE("sd,sr,sg,st"); MODULE_LICENSE("GPL"); -#ifdef PCMCIA_DEBUG -static int pc_debug = PCMCIA_DEBUG; -MODULE_PARM(pc_debug, "i"); -MODULE_PARM_DESC(pc_debug, "set debug level"); -static char *version = "$Id: nsp_cs.c,v 1.1 2004/07/22 19:50:08 joff Exp $"; -#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) -#else -#define DEBUG(n, args...) /* */ -#endif - #include "nsp_io.h" /*====================================================================*/ +/* Parameters that can be set with 'insmod' */ -typedef struct scsi_info_t { - dev_link_t link; - struct Scsi_Host *host; - int ndev; - dev_node_t node[8]; - int stop; - struct bus_operations *bus; -} scsi_info_t; +static unsigned int irq_mask = 0xffff; +MODULE_PARM (irq_mask, "i"); +MODULE_PARM_DESC(irq_mask, "IRQ mask bits (default: 0xffff)"); +static int irq_list[4] = { -1 }; +MODULE_PARM (irq_list, "1-4i"); +MODULE_PARM_DESC(irq_list, "Use specified IRQ number. (default: auto select)"); + +static int nsp_burst_mode = BURST_MEM32; +MODULE_PARM (nsp_burst_mode, "i"); +MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))"); + +/* Release IO ports after configuration? */ +static int free_ports = 0; +MODULE_PARM (free_ports, "i"); +MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))"); -/*----------------------------------------------------------------*/ - -#if (KERNEL_VERSION(2,4,0) > LINUX_VERSION_CODE) -#define PROC_SCSI_NSP PROC_SCSI_IBMMCA /* bad hack... */ -static struct proc_dir_entry proc_scsi_nsp = { - PROC_SCSI_NSP, 6, "nsp_cs", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; +/* /usr/src/linux/drivers/scsi/hosts.h */ +static Scsi_Host_Template nsp_driver_template = { + .proc_name = "nsp_cs", + .proc_info = nsp_proc_info, + .name = "WorkBit NinjaSCSI-3/32Bi(16bit)", +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + .detect = nsp_detect_old, + .release = nsp_release_old, +#endif + .info = nsp_info, + .queuecommand = nsp_queuecommand, +/* .eh_strategy_handler = nsp_eh_strategy,*/ +/* .eh_abort_handler = nsp_eh_abort,*/ +/* .eh_device_reset_handler = nsp_eh_device_reset,*/ + .eh_bus_reset_handler = nsp_eh_bus_reset, + .eh_host_reset_handler = nsp_eh_host_reset, + .can_queue = 1, + .this_id = NSP_INITIATOR_ID, + .sg_tablesize = SG_ALL, + .cmd_per_lun = 1, + .use_clustering = DISABLE_CLUSTERING, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2)) + .use_new_eh_code = 1, #endif +}; -/*====================================================================*/ -/* Parameters that can be set with 'insmod' */ +static dev_link_t *dev_list = NULL; +static dev_info_t dev_info = "nsp_cs"; -static unsigned int irq_mask = 0xffff; -MODULE_PARM(irq_mask, "i"); -MODULE_PARM_DESC(irq_mask, "IRQ mask bits"); +static nsp_hw_data nsp_data_base; /* attach <-> detect glue */ -static int irq_list[4] = { -1 }; -MODULE_PARM(irq_list, "1-4i"); -MODULE_PARM_DESC(irq_list, "IRQ number list"); -/*----------------------------------------------------------------*/ -/* driver state info, local to driver */ -static char nspinfo[100]; /* description */ -/* /usr/src/linux/drivers/scsi/hosts.h */ -static Scsi_Host_Template driver_template = { -/* next: NULL,*/ -#if (KERNEL_VERSION(2,3,99) > LINUX_VERSION_CODE) - proc_dir: &proc_scsi_nsp, /* kernel 2.2 */ +/****************************************************************** + * debug, error print + */ +#ifdef NSP_DEBUG +# include "nsp_debug.c" +#endif /* NSP_DEBUG */ + +#ifndef NSP_DEBUG +# define NSP_DEBUG_MASK 0x000000 +# define nsp_msg(type, args...) nsp_cs_message("", 0, (type), args) +# define nsp_dbg(mask, args...) /* */ #else - proc_name: "nsp_cs", /* kernel 2.4 */ +# define NSP_DEBUG_MASK 0xffffff +# define nsp_msg(type, args...) \ + nsp_cs_message (__FUNCTION__, __LINE__, (type), args) +# define nsp_dbg(mask, args...) \ + nsp_cs_dmessage(__FUNCTION__, __LINE__, (mask), args) #endif -/* proc_info: NULL,*/ - name: "WorkBit NinjaSCSI-3/32Bi", - detect: nsp_detect, - release: nsp_release, - info: nsp_info, -/* command: NULL,*/ - queuecommand: nsp_queuecommand, -/* eh_strategy_handler: nsp_eh_strategy,*/ - eh_abort_handler: nsp_eh_abort, - eh_device_reset_handler: nsp_eh_device_reset, - eh_bus_reset_handler: nsp_eh_bus_reset, - eh_host_reset_handler: nsp_eh_host_reset, - abort: nsp_abort, - reset: nsp_reset, -/* slave_attach: NULL,*/ -/* bios_param: NULL,*/ - can_queue: 1, - this_id: SCSI_INITIATOR_ID, - sg_tablesize: SG_ALL, - cmd_per_lun: 1, -/* present: 0,*/ -/* unchecked_isa_dma: 0,*/ - use_clustering: DISABLE_CLUSTERING, - use_new_eh_code: 0, -/* emulated: 0,*/ -}; -static dev_link_t *dev_list = NULL; -static dev_info_t dev_info = {"nsp_cs"}; +#define NSP_DEBUG_QUEUECOMMAND BIT(0) +#define NSP_DEBUG_REGISTER BIT(1) +#define NSP_DEBUG_AUTOSCSI BIT(2) +#define NSP_DEBUG_INTR BIT(3) +#define NSP_DEBUG_SGLIST BIT(4) +#define NSP_DEBUG_BUSFREE BIT(5) +#define NSP_DEBUG_CDB_CONTENTS BIT(6) +#define NSP_DEBUG_RESELECTION BIT(7) +#define NSP_DEBUG_MSGINOCCUR BIT(8) +#define NSP_DEBUG_EEPROM BIT(9) +#define NSP_DEBUG_MSGOUTOCCUR BIT(10) +#define NSP_DEBUG_BUSRESET BIT(11) +#define NSP_DEBUG_RESTART BIT(12) +#define NSP_DEBUG_SYNC BIT(13) +#define NSP_DEBUG_WAIT BIT(14) +#define NSP_DEBUG_TARGETFLAG BIT(15) +#define NSP_DEBUG_PROC BIT(16) +#define NSP_DEBUG_INIT BIT(17) +#define NSP_DEBUG_DATA_IO BIT(18) +#define NSP_SPECIAL_PRINT_REGISTER BIT(20) + +#define NSP_DEBUG_BUF_LEN 150 + +static void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...) +{ + va_list args; + char buf[NSP_DEBUG_BUF_LEN]; + + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); -static nsp_hw_data nsp_data; +#ifndef NSP_DEBUG + printk("%snsp_cs: %s\n", type, buf); +#else + printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf); +#endif +} + +#ifdef NSP_DEBUG +static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...) +{ + va_list args; + char buf[NSP_DEBUG_BUF_LEN]; + + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + if (mask & NSP_DEBUG_MASK) { + printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf); + } +} +#endif /***********************************************************/ +/*==================================================== + * Clenaup parameters and call done() functions. + * You must be set SCpnt->result before call this function. + */ +static void nsp_scsi_done(Scsi_Cmnd *SCpnt) +{ + nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; + + data->CurrentSC = NULL; + + SCpnt->scsi_done(SCpnt); +} + static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { -#ifdef PCMCIA_DEBUG - //unsigned int host_id = SCpnt->host->this_id; - //unsigned int base = SCpnt->host->io_port; - unsigned char target = SCpnt->target; -#endif - nsp_hw_data *data = &nsp_data; - - DEBUG(0, __FUNCTION__ "() SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d\n", - SCpnt, target, SCpnt->lun, SCpnt->request_buffer, SCpnt->request_bufflen, SCpnt->use_sg); - //DEBUG(0, " before CurrentSC=0x%p\n", data->CurrentSC); - - if(data->CurrentSC != NULL) { - printk(KERN_DEBUG " " __FUNCTION__ "() CurrentSC!=NULL this can't be happen\n"); - data->CurrentSC = NULL; +#ifdef NSP_DEBUG + /*unsigned int host_id = SCpnt->device->host->this_id;*/ + /*unsigned int base = SCpnt->device->host->io_port;*/ + unsigned char target = SCpnt->device->id; +#endif + nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; + + nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d", + SCpnt, target, SCpnt->device->lun, SCpnt->request_buffer, SCpnt->request_bufflen, SCpnt->use_sg); + //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC); + + SCpnt->scsi_done = done; + + if (data->CurrentSC != NULL) { + nsp_msg(KERN_WARNING, "CurrentSC!=NULL this can't be happen"); SCpnt->result = DID_BAD_TARGET << 16; - done(SCpnt); - return -1; + nsp_scsi_done(SCpnt); + return SCSI_MLQUEUE_HOST_BUSY; } show_command(SCpnt); - SCpnt->scsi_done = done; data->CurrentSC = SCpnt; - RESID = SCpnt->request_bufflen; - SCpnt->SCp.Status = -1; - SCpnt->SCp.Message = -1; + SCpnt->SCp.Status = CHECK_CONDITION; + SCpnt->SCp.Message = 0; SCpnt->SCp.have_data_in = IO_UNKNOWN; SCpnt->SCp.sent_command = 0; SCpnt->SCp.phase = PH_UNDETERMINED; + SCpnt->resid = SCpnt->request_bufflen; /* setup scratch area SCp.ptr : buffer pointer @@ -201,7 +254,7 @@ SCp.phase : current state of the command */ if (SCpnt->use_sg) { SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer; - SCpnt->SCp.ptr = SCpnt->SCp.buffer->address; + SCpnt->SCp.ptr = SG_ADDRESS(SCpnt->SCp.buffer); SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length; SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1; } else { @@ -211,16 +264,18 @@ SCpnt->SCp.buffers_residual = 0; } - if(nsphw_start_selection(SCpnt, data) == FALSE) { - DEBUG(0, " selection fail\n"); - data->CurrentSC = NULL; - SCpnt->result = DID_NO_CONNECT << 16; - done(SCpnt); - return -1; + if (nsphw_start_selection(SCpnt) == FALSE) { + nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail"); + SCpnt->result = DID_BUS_BUSY << 16; + nsp_scsi_done(SCpnt); + return SCSI_MLQUEUE_DEVICE_BUSY; } - //DEBUG(0, __FUNCTION__ "() out\n"); + //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "out"); +#ifdef NSP_DEBUG + data->CmdId++; +#endif return 0; } @@ -232,7 +287,7 @@ unsigned int base = data->BaseAddress; unsigned char transfer_mode_reg; - //DEBUG(0, __FUNCTION__ "() enabled=%d\n", enabled); + //nsp_dbg(NSP_DEBUG_DATA_IO, "enabled=%d", enabled); if (enabled != FALSE) { transfer_mode_reg = TRANSFER_GO | BRAIND; @@ -245,37 +300,45 @@ nsp_index_write(base, TRANSFERMODE, transfer_mode_reg); } +static void nsphw_init_sync(nsp_hw_data *data) +{ + sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET, + .SyncPeriod = 0, + .SyncOffset = 0 + }; + int i; + + /* setup sync data */ + for ( i = 0; i < NUMBER(data->Sync); i++ ) { + data->Sync[i] = tmp_sync; + } +} + /* * Initialize Ninja hardware */ static int nsphw_init(nsp_hw_data *data) { unsigned int base = data->BaseAddress; - int i, j; - sync_data tmp_sync = { SyncNegotiation: SYNC_NOT_YET, - SyncPeriod: 0, - SyncOffset: 0 - }; - DEBUG(0, __FUNCTION__ "() in base=0x%x\n", base); + nsp_dbg(NSP_DEBUG_INIT, "in base=0x%x", base); - data->ScsiClockDiv = CLOCK_40M; + data->ScsiClockDiv = CLOCK_40M | FAST_20; data->CurrentSC = NULL; data->FifoCount = 0; data->TransferMode = MODE_IO8; - /* setup sync data */ - for ( i = 0; i < N_TARGET; i++ ) { - for ( j = 0; j < N_LUN; j++ ) { - data->Sync[i][j] = tmp_sync; - } - } + nsphw_init_sync(data); + /* block all interrupts */ - nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK); + nsp_write(base, IRQCONTROL, IRQCONTROL_ALL_CLEAR_AND_MASK); + + nsp_write(base, IFSELECT, 0); + data->ChipRev = nsp_read(base, FIFOSTATUS); /* setup SCSI interface */ - nsp_write(base, IFSELECT, IF_IFSEL); + nsp_write(base, IFSELECT, IF_REGSEL); nsp_index_write(base, SCSIIRQMODE, 0); @@ -292,7 +355,7 @@ nsp_write(base, IFSELECT, IF_REGSEL); nsp_index_write(base, TERMPWRCTRL, 0); if ((nsp_index_read(base, OTHERCONTROL) & TPWR_SENSE) == 0) { - printk(KERN_INFO "nsp_cs: terminator power on\n"); + nsp_msg(KERN_INFO, "terminator power on"); nsp_index_write(base, TERMPWRCTRL, POWER_ON); } @@ -306,7 +369,7 @@ nsp_index_write(base, SCSIIRQMODE, SCSI_PHASE_CHANGE_EI | RESELECT_EI | SCSI_RESET_IRQ_EI ); - nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR); + nsp_write(base, IRQCONTROL, IRQCONTROL_ALL_CLEAR); nsp_setup_fifo(data, FALSE); @@ -316,110 +379,147 @@ /* * Start selection phase */ -static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt, - nsp_hw_data *data) +static int nsphw_start_selection(Scsi_Cmnd *SCpnt) { - unsigned int host_id = SCpnt->host->this_id; - unsigned int base = SCpnt->host->io_port; - unsigned char target = SCpnt->target; - int wait_count; + unsigned int host_id = SCpnt->device->host->this_id; + unsigned int base = SCpnt->device->host->io_port; + unsigned char target = SCpnt->device->id; + nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; + int time_out; unsigned char phase, arbit; - //DEBUG(0, __FUNCTION__ "()in\n"); + //nsp_dbg(NSP_DEBUG_RESELECTION, "in"); phase = nsp_index_read(base, SCSIBUSMON); if(phase != BUSMON_BUS_FREE) { - //DEBUG(0, " bus busy\n"); + //nsp_dbg(NSP_DEBUG_RESELECTION, "bus busy"); return FALSE; } /* start arbitration */ - //DEBUG(0, " start arbit\n"); + //nsp_dbg(NSP_DEBUG_RESELECTION, "start arbit"); SCpnt->SCp.phase = PH_ARBSTART; nsp_index_write(base, SETARBIT, ARBIT_GO); - wait_count = jiffies + 10 * HZ; + time_out = 1000; do { /* XXX: what a stupid chip! */ arbit = nsp_index_read(base, ARBITSTATUS); - //DEBUG(0, " arbit=%d, wait_count=%d\n", arbit, wait_count); + //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit=%d, wait_count=%d", arbit, wait_count); udelay(1); /* hold 1.2us */ } while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 && - time_before(jiffies, wait_count)); + (time_out-- != 0)); - if((arbit & ARBIT_WIN) == 0) { - //DEBUG(0, " arbit fail\n"); + if (!(arbit & ARBIT_WIN)) { + //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit fail"); nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR); return FALSE; } /* assert select line */ - //DEBUG(0, " assert SEL line\n"); + //nsp_dbg(NSP_DEBUG_RESELECTION, "assert SEL line"); SCpnt->SCp.phase = PH_SELSTART; - udelay(3); - nsp_index_write(base, SCSIDATALATCH, (1 << host_id) | (1 << target)); - nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN); - udelay(3); + udelay(3); /* wait 2.4us */ + nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target)); + nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN); + udelay(2); /* wait >1.2us */ nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN); nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR); - udelay(3); - nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN); + /*udelay(1);*/ /* wait >90ns */ + nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN); /* check selection timeout */ - nsp_start_timer(SCpnt, data, 1000/51); + nsp_start_timer(SCpnt, 1000/51); data->SelectionTimeOut = 1; return TRUE; } +/*********************************************************************** + * Period/AckWidth speed conversion table + * + * Note: This period/ackwidth speed table must be in descending order. + ***********************************************************************/ struct nsp_sync_table { - unsigned int min_period; - unsigned int max_period; unsigned int chip_period; unsigned int ack_width; + unsigned int min_period; + unsigned int max_period; }; static struct nsp_sync_table nsp_sync_table_40M[] = { - {0x0c,0x0c,0x1,0}, /* 20MB 50ns*/ - {0x19,0x19,0x3,1}, /* 10MB 100ns*/ - {0x1a,0x25,0x5,2}, /* 7.5MB 150ns*/ - {0x26,0x32,0x7,3}, /* 5MB 200ns*/ - {0x0, 0, 0, 0} + /* {PNo, AW, SP, EP} Speed(MB/s) Period AckWidth */ + {0x1, 0, 0x0c, 0x0c}, /* 20.0 : 50ns, 25ns */ + {0x2, 0, 0x0d, 0x18}, /* 13.3 : 75ns, 25ns */ + {0x3, 1, 0x19, 0x19}, /* 10.0 : 100ns, 50ns */ + {0x4, 1, 0x1a, 0x1f}, /* 8.0 : 125ns, 50ns */ + {0x5, 2, 0x20, 0x25}, /* 7.5 : 150ns, 75ns */ + {0x6, 2, 0x26, 0x31}, /* 5.71: 175ns, 75ns */ + {0x7, 3, 0x32, 0x32}, /* 5.0 : 200ns, 100ns */ + {0x8, 3, 0x33, 0x38}, /* 4.44: 225ns, 100ns */ + {0x9, 3, 0x39, 0x3e}, /* 4.0 : 250ns, 100ns */ + {0xa, 3, 0x3f, 0x44}, /* 3.64: 275ns, 100ns */ + {0xb, 3, 0x45, 0x4b}, /* 3.33: 300ns, 100ns */ + {0xc, 3, 0x4c, 0x53}, /* 3.01: 325ns, 100ns */ + {0xd, 3, 0x54, 0x57}, /* 2.86: 350ns, 100ns */ + {0xe, 3, 0x58, 0x5d}, /* 2.67: 375ns, 100ns */ + {0xf, 3, 0x5e, 0x64}, /* 2.5 : 400ns, 100ns */ + {0,0,0,0}, }; static struct nsp_sync_table nsp_sync_table_20M[] = { - {0x19,0x19,0x1,0}, /* 10MB 100ns*/ - {0x1a,0x25,0x2,0}, /* 7.5MB 150ns*/ - {0x26,0x32,0x3,1}, /* 5MB 200ns*/ - {0x0, 0, 0, 0} + {0x1, 0, 0x19, 0x19}, /* 10.0 : 100ns, 50ns */ + {0x2, 0, 0x1a, 0x25}, /* 6.7 : 150ns, 50ns */ + {0x3, 1, 0x26, 0x32}, /* 5.0 : 200ns, 100ns */ + {0x4, 1, 0x33, 0x3e}, /* 4.0 : 250ns, 100ns */ + {0x5, 2, 0x3f, 0x4b}, /* 3.3 : 300ns, 150ns */ + {0x6, 2, 0x4c, 0x57}, /* 2.8 : 350ns, 150ns */ + {0x7, 3, 0x58, 0x64}, /* 2.5 : 400ns, 200ns */ + {0x8, 3, 0x65, 0x70}, /* 2.2 : 450ns, 200ns */ + {0x9, 3, 0x71, 0x7d}, /* 2.0 : 500ns, 200ns */ + {0xa, 3, 0x7e, 0x89}, /* 1.82: 550ns, 200ns */ + {0xb, 3, 0x8a, 0x95}, /* 1.67: 550ns, 200ns */ + {0xc, 3, 0x96, 0xa2}, /* 1.54: 550ns, 200ns */ + {0xd, 3, 0xa3, 0xae}, /* 1.43: 550ns, 200ns */ + {0xe, 3, 0xaf, 0xbb}, /* 1.33: 550ns, 200ns */ + {0xf, 3, 0xbc, 0xc8}, /* 1.25: 550ns, 200ns */ + {0,0,0,0}, }; /* * setup synchronous data transfer mode */ -static int nsp_msg(Scsi_Cmnd *SCpnt, nsp_hw_data *data) +static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt) { - unsigned char target = SCpnt->target; - unsigned char lun = SCpnt->lun; - sync_data *sync = &(data->Sync[target][lun]); + unsigned char target = SCpnt->device->id; +// unsigned char lun = SCpnt->device->lun; + nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; + sync_data *sync = &(data->Sync[target]); struct nsp_sync_table *sync_table; unsigned int period, offset; int i; - DEBUG(0, __FUNCTION__ "()\n"); - -/**!**/ + nsp_dbg(NSP_DEBUG_SYNC, "in"); period = sync->SyncPeriod; offset = sync->SyncOffset; - DEBUG(0, " period=0x%x, offset=0x%x\n", period, offset); + nsp_dbg(NSP_DEBUG_SYNC, "period=0x%x, offset=0x%x", period, offset); - if (data->ScsiClockDiv == CLOCK_20M) { - sync_table = &nsp_sync_table_20M[0]; - } else { - sync_table = &nsp_sync_table_40M[0]; + switch (data->ScsiClockDiv) { + case CLOCK_20M: + case CLOCK_40M: + sync_table = nsp_sync_table_20M; + break; + case CLOCK_40M | FAST_20: + sync_table = nsp_sync_table_40M; + break; + default: + nsp_msg(KERN_WARNING, + "Invalid clock div is selected, set 20M."); + sync_table = nsp_sync_table_20M; + break; } for ( i = 0; sync_table->max_period != 0; i++, sync_table++) { @@ -433,13 +533,12 @@ /* * No proper period/offset found */ - DEBUG(0, " no proper period/offset\n"); + nsp_dbg(NSP_DEBUG_SYNC, "no proper period/offset"); sync->SyncPeriod = 0; sync->SyncOffset = 0; sync->SyncRegister = 0; sync->AckWidth = 0; - sync->SyncNegotiation = SYNC_OK; return FALSE; } @@ -447,9 +546,8 @@ sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) | (offset & SYNCREG_OFFSET_MASK); sync->AckWidth = sync_table->ack_width; - sync->SyncNegotiation = SYNC_OK; - DEBUG(0, " sync_reg=0x%x, ack_width=0x%x\n", sync->SyncRegister, sync->AckWidth); + nsp_dbg(NSP_DEBUG_SYNC, "sync_reg=0x%x, ack_width=0x%x", sync->SyncRegister, sync->AckWidth); return TRUE; } @@ -458,11 +556,12 @@ /* * start ninja hardware timer */ -static void nsp_start_timer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int time) +static void nsp_start_timer(Scsi_Cmnd *SCpnt, int time) { - unsigned int base = SCpnt->host->io_port; + unsigned int base = SCpnt->device->host->io_port; + nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; - //DEBUG(0, __FUNCTION__ "() in SCpnt=0x%p, time=%d\n", SCpnt, time); + //nsp_dbg(NSP_DEBUG_INTR, "in SCpnt=0x%p, time=%d", SCpnt, time); data->TimerCount = time; nsp_index_write(base, TIMERCOUNT, time); } @@ -472,23 +571,23 @@ */ static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str) { - unsigned int base = SCpnt->host->io_port; + unsigned int base = SCpnt->device->host->io_port; unsigned char reg; - int count, i = TRUE; + int time_out; - //DEBUG(0, __FUNCTION__ "()\n"); + //nsp_dbg(NSP_DEBUG_INTR, "in"); - count = jiffies + HZ; + time_out = 100; do { reg = nsp_index_read(base, SCSIBUSMON); if (reg == 0xff) { break; } - } while ((i = time_before(jiffies, count)) && (reg & mask) != 0); + } while ((time_out-- != 0) && (reg & mask) != 0); - if (!i) { - printk(KERN_DEBUG __FUNCTION__ " %s signal off timeut\n", str); + if (time_out == 0) { + nsp_msg(KERN_DEBUG, " %s signal off timeut", str); } return 0; @@ -501,51 +600,52 @@ unsigned char current_phase, unsigned char mask) { - unsigned int base = SCpnt->host->io_port; - int wait_count; + unsigned int base = SCpnt->device->host->io_port; + int time_out; unsigned char phase, i_src; - //DEBUG(0, __FUNCTION__ "() current_phase=0x%x, mask=0x%x\n", current_phase, mask); + //nsp_dbg(NSP_DEBUG_INTR, "current_phase=0x%x, mask=0x%x", current_phase, mask); - wait_count = jiffies + HZ; + time_out = 100; do { phase = nsp_index_read(base, SCSIBUSMON); if (phase == 0xff) { - //DEBUG(0, " ret -1\n"); + //nsp_dbg(NSP_DEBUG_INTR, "ret -1"); return -1; } i_src = nsp_read(base, IRQSTATUS); if (i_src & IRQSTATUS_SCSI) { - //DEBUG(0, " ret 0 found scsi signal\n"); + //nsp_dbg(NSP_DEBUG_INTR, "ret 0 found scsi signal"); return 0; } if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) { - //DEBUG(0, " ret 1 phase=0x%x\n", phase); + //nsp_dbg(NSP_DEBUG_INTR, "ret 1 phase=0x%x", phase); return 1; } - } while(time_before(jiffies, wait_count)); + } while(time_out-- != 0); - //DEBUG(0, __FUNCTION__ " : " __FUNCTION__ " timeout\n"); + //nsp_dbg(NSP_DEBUG_INTR, "timeout"); return -1; } /* * transfer SCSI message */ -static int nsp_xfer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int phase) +static int nsp_xfer(Scsi_Cmnd *SCpnt, int phase) { - unsigned int base = SCpnt->host->io_port; + unsigned int base = SCpnt->device->host->io_port; + nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; char *buf = data->MsgBuffer; int len = MIN(MSGBUF_SIZE, data->MsgLen); int ptr; int ret; - //DEBUG(0, __FUNCTION__ "()\n"); - for (ptr = 0; len > 0; len --, ptr ++) { + //nsp_dbg(NSP_DEBUG_DATA_IO, "in"); + for (ptr = 0; len > 0; len--, ptr++) { ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ); if (ret <= 0) { - DEBUG(0, " xfer quit\n"); + nsp_dbg(NSP_DEBUG_DATA_IO, "xfer quit"); return 0; } @@ -556,10 +656,10 @@ /* read & write message */ if (phase & BUSMON_IO) { - DEBUG(0, " read msg\n"); + nsp_dbg(NSP_DEBUG_DATA_IO, "read msg"); buf[ptr] = nsp_index_read(base, SCSIDATAWITHACK); } else { - DEBUG(0, " write msg\n"); + nsp_dbg(NSP_DEBUG_DATA_IO, "write msg"); nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]); } nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer"); @@ -571,11 +671,12 @@ /* * get extra SCSI data from fifo */ -static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt, nsp_hw_data *data) +static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt) { + nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; unsigned int count; - //DEBUG(0, __FUNCTION__ "()\n"); + //nsp_dbg(NSP_DEBUG_DATA_IO, "in"); if (SCpnt->SCp.have_data_in != IO_IN) { return 0; @@ -583,7 +684,7 @@ count = nsp_fifo_count(SCpnt); if (data->FifoCount == count) { - //DEBUG(0, " not use bypass quirk\n"); + //nsp_dbg(NSP_DEBUG_DATA_IO, "not use bypass quirk"); return 0; } @@ -591,30 +692,49 @@ * XXX: NSP_QUIRK * data phase skip only occures in case of SCSI_LOW_READ */ + nsp_dbg(NSP_DEBUG_DATA_IO, "use bypass quirk"); SCpnt->SCp.phase = PH_DATA; - nsp_pio_read(SCpnt, data); + nsp_pio_read(SCpnt); nsp_setup_fifo(data, FALSE); - DEBUG(0, " use bypass quirk\n"); return 0; } /* * accept reselection */ -static int nsp_reselected(Scsi_Cmnd *SCpnt, nsp_hw_data *data) +static int nsp_reselected(Scsi_Cmnd *SCpnt) { - unsigned int base = SCpnt->host->io_port; - unsigned char reg; + unsigned int base = SCpnt->device->host->io_port; + unsigned int host_id = SCpnt->device->host->this_id; + //nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; + unsigned char bus_reg; + unsigned char id_reg, tmp; + int target; + + nsp_dbg(NSP_DEBUG_RESELECTION, "in"); + + id_reg = nsp_index_read(base, RESELECTID); + tmp = id_reg & (~BIT(host_id)); + target = 0; + while(tmp != 0) { + if (tmp & BIT(0)) { + break; + } + tmp >>= 1; + target++; + } - //DEBUG(0, __FUNCTION__ "()\n"); + if (SCpnt->device->id != target) { + nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target); + } nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect"); - nsp_nexus(SCpnt, data); - reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN); - nsp_index_write(base, SCSIBUSCTRL, reg); - nsp_index_write(base, SCSIBUSCTRL, reg | AUTODIRECTION | ACKENB); + nsp_nexus(SCpnt); + bus_reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN); + nsp_index_write(base, SCSIBUSCTRL, bus_reg); + nsp_index_write(base, SCSIBUSCTRL, bus_reg | AUTODIRECTION | ACKENB); return TRUE; } @@ -624,19 +744,20 @@ */ static int nsp_fifo_count(Scsi_Cmnd *SCpnt) { - unsigned int base = SCpnt->host->io_port; + unsigned int base = SCpnt->device->host->io_port; unsigned int count; - unsigned int l, m, h; + unsigned int l, m, h, dummy; - nsp_index_write(base, POINTERCLR, POINTER_CLEAR); + nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER); - l = (unsigned int)nsp_read(base, DATAREG); - m = (unsigned int)nsp_read(base, DATAREG); - h = (unsigned int)nsp_read(base, DATAREG); + l = nsp_index_read(base, TRANSFERCOUNT); + m = nsp_index_read(base, TRANSFERCOUNT); + h = nsp_index_read(base, TRANSFERCOUNT); + dummy = nsp_index_read(base, TRANSFERCOUNT); /* required this! */ count = (h << 16) | (m << 8) | (l << 0); - //DEBUG(0, __FUNCTION__ "() =0x%x\n", count); + //nsp_dbg(NSP_DEBUG_DATA_IO, "count=0x%x", count); return count; } @@ -648,34 +769,37 @@ /* * read data in DATA IN phase */ -static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data) +static void nsp_pio_read(Scsi_Cmnd *SCpnt) { - unsigned int base = SCpnt->host->io_port; - int time_out, i; + unsigned int base = SCpnt->device->host->io_port; + unsigned long mmio_base = SCpnt->device->host->base; + nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; + long time_out; int ocount, res; unsigned char stat, fifo_stat; ocount = data->FifoCount; - DEBUG(0, __FUNCTION__ "() in SCpnt=0x%p resid=%d ocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d\n", SCpnt, RESID, ocount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual); + nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p resid=%d ocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d", + SCpnt, SCpnt->resid, ocount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual); - time_out = jiffies + 10 * HZ; + time_out = 1000; - while ((i = time_before(jiffies,time_out)) && + while ((time_out-- != 0) && (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) { stat = nsp_index_read(base, SCSIBUSMON); stat &= BUSMON_PHASE_MASK; - res = nsp_fifo_count(SCpnt) - ocount; - //DEBUG(0, " ptr=0x%p this=0x%x ocount=0x%x res=0x%x\n", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount, res); + res = nsp_fifo_count(SCpnt) - ocount; + //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x ocount=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount, res); if (res == 0) { /* if some data avilable ? */ if (stat == BUSPHASE_DATA_IN) { /* phase changed? */ - //DEBUG(0, " wait for data this=%d\n", SCpnt->SCp.this_residual); + //nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", SCpnt->SCp.this_residual); continue; } else { - DEBUG(0, " phase changed stat=0x%x\n", stat); + nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x", stat); break; } } @@ -696,72 +820,93 @@ case MODE_IO8: nsp_fifo8_read (base, SCpnt->SCp.ptr, res ); break; - default: - DEBUG(0, "unknown read mode\n"); + + case MODE_MEM32: + res &= ~(BIT(1)|BIT(0)); /* align 4 */ + nsp_mmio_fifo32_read(mmio_base, SCpnt->SCp.ptr, res >> 2); break; + + default: + nsp_dbg(NSP_DEBUG_DATA_IO, "unknown read mode"); + return; } - RESID -= res; + SCpnt->resid -= res; SCpnt->SCp.ptr += res; SCpnt->SCp.this_residual -= res; ocount += res; - //DEBUG(0, " ptr=0x%p this_residual=0x%x ocount=0x%x\n", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount); + //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this_residual=0x%x ocount=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount); /* go to next scatter list if available */ if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.buffers_residual != 0 ) { - //DEBUG(0, " scatterlist next timeout=%d\n", time_out); + //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next timeout=%d", time_out); SCpnt->SCp.buffers_residual--; SCpnt->SCp.buffer++; - SCpnt->SCp.ptr = SCpnt->SCp.buffer->address; + SCpnt->SCp.ptr = SG_ADDRESS(SCpnt->SCp.buffer); SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length; - } + time_out = 1000; - time_out = jiffies + 10 * HZ; + //nsp_dbg(NSP_DEBUG_DATA_IO, "page: 0x%p, off: 0x%x", SCpnt->SCp.buffer->page, SCpnt->SCp.buffer->offset); + } } data->FifoCount = ocount; - if (!i) { - printk(KERN_DEBUG __FUNCTION__ "() pio read timeout resid=%d this_residual=%d buffers_residual=%d\n", RESID, SCpnt->SCp.this_residual, SCpnt->SCp.buffers_residual); + if (time_out == 0) { + nsp_msg(KERN_DEBUG, "pio read timeout resid=%d this_residual=%d buffers_residual=%d", + SCpnt->resid, SCpnt->SCp.this_residual, SCpnt->SCp.buffers_residual); } - DEBUG(0, " read ocount=0x%x\n", ocount); + nsp_dbg(NSP_DEBUG_DATA_IO, "read ocount=0x%x", ocount); + nsp_dbg(NSP_DEBUG_DATA_IO, "r cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid); } /* * write data in DATA OUT phase */ -static void nsp_pio_write(Scsi_Cmnd *SCpnt, nsp_hw_data *data) +static void nsp_pio_write(Scsi_Cmnd *SCpnt) { - unsigned int base = SCpnt->host->io_port; - int time_out, i; - unsigned int ocount, res; + unsigned int base = SCpnt->device->host->io_port; + unsigned long mmio_base = SCpnt->device->host->base; + nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; + int time_out; + int ocount, res; unsigned char stat; ocount = data->FifoCount; - DEBUG(0, __FUNCTION__ "() in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x\n", data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual, RESID); + nsp_dbg(NSP_DEBUG_DATA_IO, "in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x", + data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual, SCpnt->resid); - time_out = jiffies + 10 * HZ; + time_out = 1000; - while ((i = time_before(jiffies, time_out)) && + while ((time_out-- != 0) && (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0)) { stat = nsp_index_read(base, SCSIBUSMON); stat &= BUSMON_PHASE_MASK; + if (stat != BUSPHASE_DATA_OUT) { - DEBUG(0, " phase changed stat=0x%x\n", stat); + res = ocount - nsp_fifo_count(SCpnt); + + nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x, res=%d\n", stat, res); + /* Put back pointer */ + SCpnt->resid += res; + SCpnt->SCp.ptr -= res; + SCpnt->SCp.this_residual += res; + ocount -= res; + break; } res = ocount - nsp_fifo_count(SCpnt); if (res > 0) { /* write all data? */ - DEBUG(0, " wait for all data out. ocount=0x%x res=%d\n", ocount, res); + nsp_dbg(NSP_DEBUG_DATA_IO, "wait for all data out. ocount=0x%x res=%d", ocount, res); continue; } res = MIN(SCpnt->SCp.this_residual, WFIFO_CRIT); - //DEBUG(0, " ptr=0x%p this=0x%x res=0x%x\n", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, res); + //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, res); switch (data->TransferMode) { case MODE_IO32: res &= ~(BIT(1)|BIT(0)); /* align 4 */ @@ -770,12 +915,18 @@ case MODE_IO8: nsp_fifo8_write (base, SCpnt->SCp.ptr, res ); break; + + case MODE_MEM32: + res &= ~(BIT(1)|BIT(0)); /* align 4 */ + nsp_mmio_fifo32_write(mmio_base, SCpnt->SCp.ptr, res >> 2); + break; + default: - DEBUG(0, "unknown write mode\n"); + nsp_dbg(NSP_DEBUG_DATA_IO, "unknown write mode"); break; } - RESID -= res; + SCpnt->resid -= res; SCpnt->SCp.ptr += res; SCpnt->SCp.this_residual -= res; ocount += res; @@ -783,55 +934,60 @@ /* go to next scatter list if available */ if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.buffers_residual != 0 ) { - //DEBUG(0, " scatterlist next\n"); + //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next"); SCpnt->SCp.buffers_residual--; SCpnt->SCp.buffer++; - SCpnt->SCp.ptr = SCpnt->SCp.buffer->address; + SCpnt->SCp.ptr = SG_ADDRESS(SCpnt->SCp.buffer); SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length; + time_out = 1000; } - - time_out = jiffies + 10 * HZ; } data->FifoCount = ocount; - if (!i) { - printk(KERN_DEBUG __FUNCTION__ "() pio write timeout resid=%d\n", RESID); + if (time_out == 0) { + nsp_msg(KERN_DEBUG, "pio write timeout resid=0x%x", SCpnt->resid); } - //DEBUG(0, " write ocount=%d\n", ocount); + nsp_dbg(NSP_DEBUG_DATA_IO, "write ocount=0x%x", ocount); + nsp_dbg(NSP_DEBUG_DATA_IO, "w cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid); } - #undef RFIFO_CRIT #undef WFIFO_CRIT /* * setup synchronous/asynchronous data transfer mode */ -static int nsp_nexus(Scsi_Cmnd *SCpnt, nsp_hw_data *data) +static int nsp_nexus(Scsi_Cmnd *SCpnt) { - unsigned int base = SCpnt->host->io_port; - unsigned char target = SCpnt->target; - unsigned char lun = SCpnt->lun; - sync_data *sync = &(data->Sync[target][lun]); + unsigned int base = SCpnt->device->host->io_port; + unsigned char target = SCpnt->device->id; +// unsigned char lun = SCpnt->device->lun; + nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; + sync_data *sync = &(data->Sync[target]); - //DEBUG(0, __FUNCTION__ "() in SCpnt=0x%p\n", SCpnt); + //nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p", SCpnt); /* setup synch transfer registers */ nsp_index_write(base, SYNCREG, sync->SyncRegister); nsp_index_write(base, ACKWIDTH, sync->AckWidth); - if (RESID % 4 != 0 || - RESID <= 256 ) { + if (SCpnt->use_sg == 0 || + SCpnt->resid % 4 != 0 || + SCpnt->resid <= PAGE_SIZE ) { data->TransferMode = MODE_IO8; - } else { + } else if (nsp_burst_mode == BURST_MEM32) { + data->TransferMode = MODE_MEM32; + } else if (nsp_burst_mode == BURST_IO32) { data->TransferMode = MODE_IO32; + } else { + data->TransferMode = MODE_IO8; } /* setup pdma fifo */ nsp_setup_fifo(data, TRUE); /* clear ack counter */ - data->FifoCount = 0; + data->FifoCount = 0; nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER_CLEAR | REQ_COUNTER_CLEAR | @@ -844,111 +1000,126 @@ /* * interrupt handler */ -static void nspintr(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs) { unsigned int base; - unsigned char i_src, irq_phase, phase; + unsigned char irq_status, irq_phase, phase; Scsi_Cmnd *tmpSC; - int len; unsigned char target, lun; unsigned int *sync_neg; int i, tmp; + unsigned long flags; nsp_hw_data *data; + int handled = 0; - //printk("&nsp_data=0x%p, dev_id=0x%p\n", &nsp_data, dev_id); + //nsp_dbg(NSP_DEBUG_INTR, "dev_id=0x%p", dev_id); + //nsp_dbg(NSP_DEBUG_INTR, "host=0x%p", ((scsi_info_t *)dev_id)->host); - /* sanity check */ - if (&nsp_data != dev_id) { - DEBUG(0, " irq conflict? this can't happen\n"); - return; - } - data = dev_id; - if (irq != data->IrqNumber) { - return; + if ( dev_id != NULL && + ((scsi_info_t *)dev_id)->host != NULL ) { + scsi_info_t *info = (scsi_info_t *)dev_id; + + data = (nsp_hw_data *)(info->host->hostdata); + } else { + nsp_dbg(NSP_DEBUG_INTR, "host data wrong"); + return IRQ_NONE; } + spin_lock_irqsave(HOST_LOCK, flags); + + //nsp_dbg(NSP_DEBUG_INTR, "&nsp_data_base=0x%p, dev_id=0x%p", &nsp_data_base, dev_id); + base = data->BaseAddress; - //DEBUG(0, " base=0x%x\n", base); + //nsp_dbg(NSP_DEBUG_INTR, "base=0x%x", base); /* * interrupt check */ - nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE); - i_src = nsp_read(base, IRQSTATUS); - if (i_src == 0xff || (i_src & IRQSTATUS_MASK) == 0) { - nsp_write(base, IRQCONTROL, 0); - //DEBUG(0, " no irq\n"); - return; + nsp_write(base, IRQCONTROL, IRQCONTROL_ALL_MASK); + irq_status = nsp_read(base, IRQSTATUS); + //nsp_dbg(NSP_DEBUG_INTR, "irq_status=0x%x", irq_status); + if ((irq_status == 0xff) || ((irq_status & IRQSTATUS_MASK) == 0)) { + //nsp_dbg(NSP_DEBUG_INTR, "no irq/shared irq"); + goto out; } - - //DEBUG(0, " i_src=0x%x\n", i_src); + handled = 1; /* XXX: IMPORTANT * Do not read an irq_phase register if no scsi phase interrupt. * Unless, you should lose a scsi phase interrupt. */ phase = nsp_index_read(base, SCSIBUSMON); - if((i_src & IRQSTATUS_SCSI) != 0) { + if((irq_status & IRQSTATUS_SCSI) != 0) { irq_phase = nsp_index_read(base, IRQPHASESENCE); } else { irq_phase = 0; } - //DEBUG(0, " irq_phase=0x%x\n", irq_phase); + //nsp_dbg(NSP_DEBUG_INTR, "irq_phase=0x%x", irq_phase); /* * timer interrupt handler (scsi vs timer interrupts) */ - //DEBUG(0, " timercount=%d\n", data->TimerCount); + //nsp_dbg(NSP_DEBUG_INTR, "timercount=%d", data->TimerCount); if (data->TimerCount != 0) { - //DEBUG(0, " stop timer\n"); + //nsp_dbg(NSP_DEBUG_INTR, "stop timer"); nsp_index_write(base, TIMERCOUNT, 0); nsp_index_write(base, TIMERCOUNT, 0); data->TimerCount = 0; } - if ((i_src & IRQSTATUS_MASK) == IRQSTATUS_TIMER && + if ((irq_status & IRQSTATUS_MASK) == IRQSTATUS_TIMER && data->SelectionTimeOut == 0) { - //DEBUG(0, " timer start\n"); + //nsp_dbg(NSP_DEBUG_INTR, "timer start"); nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR); - return; + goto out; } nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR); + if ((irq_status & IRQSTATUS_SCSI) && + (irq_phase & SCSI_RESET_IRQ)) { + nsp_msg(KERN_ERR, "bus reset (power off?)"); + + nsphw_init(data); + nsp_bus_reset(data); + + if(data->CurrentSC != NULL) { + tmpSC = data->CurrentSC; + tmpSC->result = (DID_RESET << 16) | + ((tmpSC->SCp.Message & 0xff) << 8) | + ((tmpSC->SCp.Status & 0xff) << 0); + nsp_scsi_done(tmpSC); + } + goto out; + } + if (data->CurrentSC == NULL) { - printk(KERN_DEBUG __FUNCTION__ " CurrentSC==NULL irq_status=0x%x phase=0x%x irq_phase=0x%x this can't be happen\n", i_src, phase, irq_phase); - return; - } else { - tmpSC = data->CurrentSC; - target = tmpSC->target; - lun = tmpSC->lun; - sync_neg = &(data->Sync[target][lun].SyncNegotiation); + nsp_msg(KERN_ERR, "CurrentSC==NULL irq_status=0x%x phase=0x%x irq_phase=0x%x this can't be happen. reset everything", irq_status, phase, irq_phase); + nsphw_init(data); + nsp_bus_reset(data); + goto out; } + tmpSC = data->CurrentSC; + target = tmpSC->device->id; + lun = tmpSC->device->lun; + sync_neg = &(data->Sync[target].SyncNegotiation); + /* * parse hardware SCSI irq reasons register */ - if ((i_src & IRQSTATUS_SCSI) != 0) { - if ((irq_phase & SCSI_RESET_IRQ) != 0) { - printk(KERN_DEBUG " " __FUNCTION__ "() bus reset (power off?)\n"); - *sync_neg = SYNC_NOT_YET; - data->CurrentSC = NULL; - tmpSC->result = DID_RESET << 16; - tmpSC->scsi_done(tmpSC); - return; - } - - if ((irq_phase & RESELECT_IRQ) != 0) { - DEBUG(0, " reselect\n"); + if (irq_status & IRQSTATUS_SCSI) { + if (irq_phase & RESELECT_IRQ) { + nsp_dbg(NSP_DEBUG_INTR, "reselect"); nsp_write(base, IRQCONTROL, IRQCONTROL_RESELECT_CLEAR); - if (nsp_reselected(tmpSC, data) != FALSE) { - return; + if (nsp_reselected(tmpSC) != FALSE) { + goto out; } } if ((irq_phase & (PHASE_CHANGE_IRQ | LATCHED_BUS_FREE)) == 0) { - return; + goto out; } } @@ -956,50 +1127,48 @@ switch(tmpSC->SCp.phase) { case PH_SELSTART: - *sync_neg = SYNC_NOT_YET; + // *sync_neg = SYNC_NOT_YET; if ((phase & BUSMON_BSY) == 0) { - //DEBUG(0, " selection count=%d\n", data->SelectionTimeOut); + //nsp_dbg(NSP_DEBUG_INTR, "selection count=%d", data->SelectionTimeOut); if (data->SelectionTimeOut >= NSP_SELTIMEOUT) { - DEBUG(0, " selection time out\n"); + nsp_dbg(NSP_DEBUG_INTR, "selection time out"); data->SelectionTimeOut = 0; nsp_index_write(base, SCSIBUSCTRL, 0); - data->CurrentSC = NULL; - tmpSC->result = DID_NO_CONNECT << 16; - tmpSC->scsi_done(tmpSC); + tmpSC->result = DID_TIME_OUT << 16; + nsp_scsi_done(tmpSC); - return; + goto out; } data->SelectionTimeOut += 1; - nsp_start_timer(tmpSC, data, 1000/51); - return; + nsp_start_timer(tmpSC, 1000/51); + goto out; } /* attention assert */ - //DEBUG(0, " attention assert\n"); + //nsp_dbg(NSP_DEBUG_INTR, "attention assert"); data->SelectionTimeOut = 0; tmpSC->SCp.phase = PH_SELECTED; nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN); udelay(1); nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB); - return; + goto out; break; case PH_RESELECT: - //DEBUG(0, " phase reselect\n"); - *sync_neg = SYNC_NOT_YET; + //nsp_dbg(NSP_DEBUG_INTR, "phase reselect"); + // *sync_neg = SYNC_NOT_YET; if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) { - data->CurrentSC = NULL; tmpSC->result = DID_ABORT << 16; - tmpSC->scsi_done(tmpSC); - return; + nsp_scsi_done(tmpSC); + goto out; } /* fall thru */ default: - if ((i_src & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) { - return; + if ((irq_status & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) { + goto out; } break; } @@ -1007,140 +1176,153 @@ /* * SCSI sequencer */ - //DEBUG(0, " start scsi seq\n"); + //nsp_dbg(NSP_DEBUG_INTR, "start scsi seq"); /* normal disconnect */ - if ((irq_phase & LATCHED_BUS_FREE) != 0) { - //DEBUG(0, " normal disconnect i_src=0x%x, phase=0x%x, irq_phase=0x%x\n", i_src, phase, irq_phase); + if (((tmpSC->SCp.phase == PH_MSG_IN) || (tmpSC->SCp.phase == PH_MSG_OUT)) && + (irq_phase & LATCHED_BUS_FREE) != 0 ) { + nsp_dbg(NSP_DEBUG_INTR, "normal disconnect irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase); + + // *sync_neg = SYNC_NOT_YET; + if ((tmpSC->SCp.Message == MSG_COMMAND_COMPLETE)) { /* all command complete and return status */ - *sync_neg = SYNC_NOT_YET; - data->CurrentSC = NULL; - tmpSC->result = (DID_OK << 16) | - (tmpSC->SCp.Message << 8) | - (tmpSC->SCp.Status << 0); - DEBUG(0, " command complete result=0x%x\n", tmpSC->result); - tmpSC->scsi_done(tmpSC); - return; + tmpSC->result = (DID_OK << 16) | + ((tmpSC->SCp.Message & 0xff) << 8) | + ((tmpSC->SCp.Status & 0xff) << 0); + nsp_dbg(NSP_DEBUG_INTR, "command complete result=0x%x", tmpSC->result); + nsp_scsi_done(tmpSC); + + goto out; } - return; + goto out; } /* check unexpected bus free state */ if (phase == 0) { - printk(KERN_DEBUG " " __FUNCTION__ " unexpected bus free. i_src=0x%x, phase=0x%x, irq_phase=0x%x\n", i_src, phase, irq_phase); + nsp_msg(KERN_DEBUG, "unexpected bus free. irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase); - *sync_neg = SYNC_NOT_YET; - data->CurrentSC = NULL; + *sync_neg = SYNC_NG; tmpSC->result = DID_ERROR << 16; - tmpSC->scsi_done(tmpSC); - return; + nsp_scsi_done(tmpSC); + goto out; } switch (phase & BUSMON_PHASE_MASK) { case BUSPHASE_COMMAND: - DEBUG(0, " BUSPHASE_COMMAND\n"); + nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_COMMAND"); if ((phase & BUSMON_REQ) == 0) { - DEBUG(0, " REQ == 0\n"); - return; + nsp_dbg(NSP_DEBUG_INTR, "REQ == 0"); + goto out; } tmpSC->SCp.phase = PH_COMMAND; - nsp_nexus(tmpSC, data); + nsp_nexus(tmpSC); /* write scsi command */ + nsp_dbg(NSP_DEBUG_INTR, "cmd_len=%d", tmpSC->cmd_len); nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER); - for (len = 0; len < COMMAND_SIZE(tmpSC->cmnd[0]); len++) { - nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[len]); + for (i = 0; i < tmpSC->cmd_len; i++) { + nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]); } nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO); break; case BUSPHASE_DATA_OUT: - DEBUG(0, " BUSPHASE_DATA_OUT\n"); + nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_OUT"); - tmpSC->SCp.phase = PH_DATA; + tmpSC->SCp.phase = PH_DATA; tmpSC->SCp.have_data_in = IO_OUT; - nsp_pio_write(tmpSC, data); + nsp_pio_write(tmpSC); break; case BUSPHASE_DATA_IN: - DEBUG(0, " BUSPHASE_DATA_IN\n"); + nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_IN"); - tmpSC->SCp.phase = PH_DATA; + tmpSC->SCp.phase = PH_DATA; tmpSC->SCp.have_data_in = IO_IN; - nsp_pio_read(tmpSC, data); + nsp_pio_read(tmpSC); break; case BUSPHASE_STATUS: - nsp_dataphase_bypass(tmpSC, data); - DEBUG(0, " BUSPHASE_STATUS\n"); + nsp_dataphase_bypass(tmpSC); + nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_STATUS"); tmpSC->SCp.phase = PH_STATUS; tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK); - //DEBUG(0, " message=0x%x status=0x%x\n", tmpSC->SCp.Message, tmpSC->SCp.Status); + nsp_dbg(NSP_DEBUG_INTR, "message=0x%x status=0x%x", tmpSC->SCp.Message, tmpSC->SCp.Status); break; case BUSPHASE_MESSAGE_OUT: - DEBUG(0, " BUSPHASE_MESSAGE_OUT\n"); + nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_OUT"); if ((phase & BUSMON_REQ) == 0) { goto timer_out; } tmpSC->SCp.phase = PH_MSG_OUT; - data->MsgLen = len = 0; + // *sync_neg = SYNC_NOT_YET; + + data->MsgLen = i = 0; + data->MsgBuffer[i] = IDENTIFY(TRUE, lun); i++; + if (*sync_neg == SYNC_NOT_YET) { - data->Sync[target][lun].SyncPeriod = 0; - data->Sync[target][lun].SyncOffset = 0; - nsp_msg(tmpSC, data); - - data->MsgBuffer[len] = IDENTIFY(TRUE, lun); len++; - /* - data->MsgBuffer[len] = MSG_EXTENDED; len++; - data->MsgBuffer[len] = 3; len++; - data->MsgBuffer[len] = MSG_EXT_SDTR; len++; - data->MsgBuffer[len] = 0x0c; len++; - data->MsgBuffer[len] = 15; len++; - */ - } - if (len == 0) { - data->MsgBuffer[len] = MSG_NO_OPERATION; len++; + data->Sync[target].SyncPeriod = 0; + data->Sync[target].SyncOffset = 0; + + /**/ + data->MsgBuffer[i] = MSG_EXTENDED; i++; + data->MsgBuffer[i] = 3; i++; + data->MsgBuffer[i] = MSG_EXT_SDTR; i++; + data->MsgBuffer[i] = 0x0c; i++; + data->MsgBuffer[i] = 15; i++; + /**/ } - data->MsgLen = len; + data->MsgLen = i; + nsp_analyze_sdtr(tmpSC); show_message(data); - nsp_message_out(tmpSC, data); + nsp_message_out(tmpSC); break; case BUSPHASE_MESSAGE_IN: - nsp_dataphase_bypass(tmpSC, data); - DEBUG(0, " BUSPHASE_MESSAGE_IN\n"); + nsp_dataphase_bypass(tmpSC); + nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_IN"); if ((phase & BUSMON_REQ) == 0) { goto timer_out; } tmpSC->SCp.phase = PH_MSG_IN; - nsp_message_in(tmpSC, data); + nsp_message_in(tmpSC); - /* - if (data->MsgLen >= 5 && - data->MsgBuffer[0] == MSG_EXTENDED && - data->MsgBuffer[1] == 3 && - data->MsgBuffer[2] == MSG_EXT_SDTR ) { - data->Sync[target][lun].SyncPeriod = data->MsgBuffer[3]; - data->Sync[target][lun].SyncOffset = data->MsgBuffer[4]; - nsp_msg(tmpSC, data); + /**/ + if (*sync_neg == SYNC_NOT_YET) { + //nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun); + + if (data->MsgLen >= 5 && + data->MsgBuffer[0] == MSG_EXTENDED && + data->MsgBuffer[1] == 3 && + data->MsgBuffer[2] == MSG_EXT_SDTR ) { + data->Sync[target].SyncPeriod = data->MsgBuffer[3]; + data->Sync[target].SyncOffset = data->MsgBuffer[4]; + //nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]); + *sync_neg = SYNC_OK; + } else { + data->Sync[target].SyncPeriod = 0; + data->Sync[target].SyncOffset = 0; + *sync_neg = SYNC_NG; + } + nsp_analyze_sdtr(tmpSC); } - */ + /**/ /* search last messeage byte */ tmp = -1; @@ -1152,134 +1334,291 @@ } tmpSC->SCp.Message = tmp; - DEBUG(0, " message=0x%x len=%d\n", tmpSC->SCp.Message, data->MsgLen); + nsp_dbg(NSP_DEBUG_INTR, "message=0x%x len=%d", tmpSC->SCp.Message, data->MsgLen); show_message(data); break; case BUSPHASE_SELECT: default: - DEBUG(0, " BUSPHASE other\n"); + nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE other"); break; } - //DEBUG(0, __FUNCTION__ "() out\n"); - return; + goto out; + timer_out: - nsp_start_timer(tmpSC, data, 1000/102); - return; + nsp_start_timer(tmpSC, 1000/102); + out: + nsp_write(base, IRQCONTROL, 0); /* clear IRQ mask */ + spin_unlock_irqrestore(HOST_LOCK, flags); + //nsp_dbg(NSP_DEBUG_INTR, "out"); + return IRQ_RETVAL(handled); } -#ifdef PCMCIA_DEBUG -#include "nsp_debug.c" -#endif /* DBG_SHOWCOMMAND */ /*----------------------------------------------------------------*/ /* look for ninja3 card and init if found */ /*----------------------------------------------------------------*/ -static int nsp_detect(Scsi_Host_Template *sht) +static struct Scsi_Host *nsp_detect(Scsi_Host_Template *sht) { struct Scsi_Host *host; /* registered host structure */ - nsp_hw_data *data = &nsp_data; + nsp_hw_data *data; - DEBUG(0, __FUNCTION__ " this_id=%d\n", sht->this_id); + nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) + host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data)); +#else + host = scsi_register(sht, sizeof(nsp_hw_data)); +#endif + if (host == NULL) { + nsp_dbg(NSP_DEBUG_INIT, "host failed"); + return NULL; + } - request_region(data->BaseAddress, data->NumAddress, "nsp_cs"); - host = scsi_register(sht, 0); - host->io_port = data->BaseAddress; - host->unique_id = data->BaseAddress; - host->n_io_port = data->NumAddress; - host->irq = data->IrqNumber; - host->dma_channel = 0xff; /* not use dms */ + /* Copy global variable to driver specific area */ + data = (nsp_hw_data *)host->hostdata; + *data = nsp_data_base; + + data->ScsiInfo->host = host; +#ifdef NSP_DEBUG + data->CmdId = 0; +#endif - sprintf(nspinfo, -/* Buffer size is 100 bytes */ -/* 0 1 2 3 4 5 6 7 8 9 0*/ -/* 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890*/ - "NinjaSCSI-3/32Bi Driver $Revision: 1.1 $, I/O 0x%04lx-0x%04lx IRQ %2d", - host->io_port, host->io_port + host->n_io_port, - host->irq); - sht->name = nspinfo; + nsp_dbg(NSP_DEBUG_INIT, "irq base=0x%p,%d data=0x%p,%d", &nsp_data_base, (&nsp_data_base)->IrqNumber, data, data->IrqNumber); - DEBUG(0, __FUNCTION__ " end\n"); + host->unique_id = data->BaseAddress; + host->io_port = data->BaseAddress; + host->n_io_port = data->NumAddress; + host->irq = data->IrqNumber; + host->base = data->MmioAddress; - return 1; /* detect done. */ + spin_lock_init(&(data->Lock)); + + snprintf(data->nspinfo, + sizeof(data->nspinfo), + "NinjaSCSI-3/32Bi Driver $Revision: 1.2 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d", + host->io_port, host->io_port + host->n_io_port - 1, + host->base, + host->irq); + sht->name = data->nspinfo; + + nsp_dbg(NSP_DEBUG_INIT, "end"); + + + return host; /* detect done. */ } -/* nsp_cs requires own release handler because its uses dev_id (=data) */ -static int nsp_release(struct Scsi_Host *shpnt) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +/*----------------------------------------*/ +/* Compatibility functions for 2.4 kernel */ +/*----------------------------------------*/ +static int nsp_detect_old(Scsi_Host_Template *sht) { - nsp_hw_data *data = &nsp_data; - - if (shpnt->irq) { - free_irq(shpnt->irq, data); - } - if (shpnt->io_port && shpnt->n_io_port) { - release_region(shpnt->io_port, shpnt->n_io_port); + if (nsp_detect(sht) == NULL) { + return 0; + } else { + return 1; /* detects 1 Ninja host card */ } +} + +static int nsp_release_old(struct Scsi_Host *shpnt) +{ + //nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata; + + /* PCMCIA Card Service dose same things below. */ + /* So we do nothing. */ + //if (shpnt->irq) { + // free_irq(shpnt->irq, data->ScsiInfo); + //} + //if (shpnt->io_port) { + // release_region(shpnt->io_port, shpnt->n_io_port); + //} + return 0; } +#endif /*----------------------------------------------------------------*/ /* return info string */ /*----------------------------------------------------------------*/ static const char *nsp_info(struct Scsi_Host *shpnt) { - return nspinfo; + nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata; + + return data->nspinfo; } -/*---------------------------------------------------------------*/ -/* error handler */ -/*---------------------------------------------------------------*/ -static int nsp_reset(Scsi_Cmnd *SCpnt, unsigned int why) +#undef SPRINTF +#define SPRINTF(args...) \ + do { \ + if(length > (pos - buffer)) { \ + pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \ + nsp_dbg(NSP_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length, length - (pos - buffer));\ + } \ + } while(0) + +/* Shows Ninja host card information for user. */ +static int +nsp_proc_info( +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) + struct Scsi_Host *host, +#endif + char *buffer, + char **start, + off_t offset, + int length, +#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) + int hostno, +#endif + int inout) { - DEBUG(0, __FUNCTION__ " SCpnt=0x%p why=%d\n", SCpnt, why); + int id; + char *pos = buffer; + int thislength; + int speed; + unsigned long flags; + nsp_hw_data *data; +#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) + struct Scsi_Host *host; +#else + int hostno; +#endif + if (inout) { + return -EINVAL; + } - nsp_eh_bus_reset(SCpnt); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) + hostno = host->host_no; +#else + /* search this HBA host */ + host = scsi_host_hn_get(hostno); + if (host == NULL) { + return -ESRCH; + } +#endif + data = (nsp_hw_data *)host->hostdata; - return SCSI_RESET_SUCCESS; -} -static int nsp_abort(Scsi_Cmnd *SCpnt) -{ - DEBUG(0, __FUNCTION__ " SCpnt=0x%p\n", SCpnt); + SPRINTF("NinjaSCSI status\n\n"); + SPRINTF("Driver version: $Revision: 1.2 $\n"); + SPRINTF("SCSI host No.: %d\n", hostno); + SPRINTF("IRQ: %d\n", host->irq); + SPRINTF("IO: 0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1); + SPRINTF("MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1); + SPRINTF("sg_tablesize: %d\n", host->sg_tablesize); + + SPRINTF("burst transfer mode: "); + switch (nsp_burst_mode) { + case BURST_IO8: + SPRINTF("io8"); + break; + case BURST_IO32: + SPRINTF("io32"); + break; + case BURST_MEM32: + SPRINTF("mem32"); + break; + default: + SPRINTF("???"); + break; + } + SPRINTF("\n"); + SPRINTF("Chip ID: %d\n", data->ChipRev >> 4); + SPRINTF("Chip revision: %d\n", data->ChipRev & 0x0f); + - nsp_eh_bus_reset(SCpnt); + spin_lock_irqsave(&(data->Lock), flags); + SPRINTF("CurrentSC: 0x%p\n\n", data->CurrentSC); + spin_unlock_irqrestore(&(data->Lock), flags); + + SPRINTF("SDTR status\n"); + for(id = 0; id < NUMBER(data->Sync); id++) { + + SPRINTF("id %d: ", id); + + if (id == host->this_id) { + SPRINTF("----- NinjaSCSI-3 host adapter\n"); + continue; + } - return SCSI_ABORT_SUCCESS; + switch(data->Sync[id].SyncNegotiation) { + case SYNC_OK: + SPRINTF(" sync"); + break; + case SYNC_NG: + SPRINTF("async"); + break; + case SYNC_NOT_YET: + SPRINTF(" none"); + break; + default: + SPRINTF("?????"); + break; + } + + if (data->Sync[id].SyncPeriod != 0) { + speed = 1000000 / (data->Sync[id].SyncPeriod * 4); + + SPRINTF(" transfer %d.%dMB/s, offset %d", + speed / 1000, + speed % 1000, + data->Sync[id].SyncOffset + ); + } + SPRINTF("\n"); + } + + thislength = pos - (buffer + offset); + + if(thislength < 0) { + *start = 0; + return 0; + } + + + thislength = MIN(thislength, length); + *start = buffer + offset; + + return thislength; } +#undef SPRINTF + +/*---------------------------------------------------------------*/ +/* error handler */ +/*---------------------------------------------------------------*/ /*static int nsp_eh_strategy(struct Scsi_Host *Shost) { return FAILED; }*/ +/* static int nsp_eh_abort(Scsi_Cmnd *SCpnt) { - DEBUG(0, __FUNCTION__ " SCpnt=0x%p\n", SCpnt); + nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt); - nsp_eh_bus_reset(SCpnt); - - return SUCCESS; -} + return nsp_eh_bus_reset(SCpnt); +}*/ +/* static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt) { - DEBUG(0, __FUNCTION__ " SCpnt=0x%p\n", SCpnt); + nsp_dbg(NSP_DEBUG_BUSRESET, "%s: SCpnt=0x%p", SCpnt); return FAILED; -} +}*/ -static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt) +/* Do bus reset. This function uses in low-level initialize functions. */ +static int nsp_bus_reset(nsp_hw_data *data) { - unsigned int base = SCpnt->host->io_port; + unsigned int base = data->BaseAddress; int i; - DEBUG(0, __FUNCTION__ "() SCpnt=0x%p base=0x%x\n", SCpnt, base); - - nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK); + nsp_msg(KERN_WARNING, "Bus reset"); + nsp_write(base, IRQCONTROL, IRQCONTROL_ALL_CLEAR_AND_MASK); nsp_index_write(base, SCSIBUSCTRL, SCSI_RST); mdelay(100); /* 100ms */ @@ -1288,33 +1627,46 @@ nsp_index_read(base, IRQPHASESENCE); /* dummy read */ } - nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR); + nsphw_init_sync(data); + + nsp_write(base, IRQCONTROL, IRQCONTROL_ALL_CLEAR); + + if (data->CurrentSC != NULL) { + nsp_msg(KERN_WARNING, "clean up current scsi command."); + data->CurrentSC->result = DID_ERROR << 16; + nsp_scsi_done(data->CurrentSC); + } return SUCCESS; } +/* Do bus reset. This function uses in high-level SCSI driver. */ +static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt) +{ + nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; + + nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt); + + return nsp_bus_reset(data); +} + +/* Initialise Ninja host adapter. */ static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt) { - nsp_hw_data *data = &nsp_data; + nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; - DEBUG(0, __FUNCTION__ "\n"); + nsp_dbg(NSP_DEBUG_BUSRESET, "in"); + nsp_msg(KERN_DEBUG, "host reset"); nsphw_init(data); - return nsp_eh_bus_reset(SCpnt); + return SUCCESS; } /********************************************************************** PCMCIA functions - *********************************************************************/ - -/*====================================================================*/ -static void cs_error(client_handle_t handle, int func, int ret) -{ - error_info_t err = { func, ret }; - CardServices(ReportError, handle, &err); -} +**********************************************************************/ /*====================================================================== nsp_cs_attach() creates an "instance" of the driver, allocating @@ -1331,19 +1683,19 @@ client_reg_t client_reg; dev_link_t *link; int ret, i; + nsp_hw_data *data = &nsp_data_base; - DEBUG(0, __FUNCTION__ "()\n"); + nsp_dbg(NSP_DEBUG_INIT, "in"); /* Create new SCSI device */ info = kmalloc(sizeof(*info), GFP_KERNEL); - if (!info) { return NULL; } + if (info == NULL) { return NULL; } memset(info, 0, sizeof(*info)); link = &info->link; link->priv = info; + data->ScsiInfo = info; - /* Initialize the dev_link_t structure */ - link->release.function = &nsp_cs_release; - link->release.data = (u_long)link; + nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info); /* The io structure describes IO port mapping */ link->io.NumPorts1 = 0x10; @@ -1357,11 +1709,14 @@ link->irq.IRQInfo2 = irq_mask; } else { for (i = 0; i < 4; i++) { - link->irq.IRQInfo2 |= 1 << irq_list[i]; + link->irq.IRQInfo2 |= BIT(irq_list[i]); } } + + /* Interrupt handler */ link->irq.Handler = &nspintr; - link->irq.Instance = &nsp_data; + link->irq.Instance = info; + link->irq.Attributes |= (SA_SHIRQ | SA_SAMPLE_RANDOM); /* General socket configuration */ link->conf.Attributes = CONF_ENABLE_IRQ; @@ -1389,6 +1744,8 @@ return NULL; } + + nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link); return link; } /* nsp_cs_attach */ @@ -1403,8 +1760,8 @@ { dev_link_t **linkp; - DEBUG(0, __FUNCTION__ "(0x%p)\n", link); - + nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link); + /* Locate device structure */ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) { if (*linkp == link) { @@ -1415,13 +1772,8 @@ return; } - del_timer(&link->release); if (link->state & DEV_CONFIG) { - nsp_cs_release((u_long)link); - if (link->state & DEV_STALE_CONFIG) { - link->state |= DEV_STALE_LINK; - return; - } + nsp_cs_release(link); } /* Break the link with Card Services */ @@ -1432,6 +1784,7 @@ /* Unlink device structure, free bits */ *linkp = link->next; kfree(link->priv); + link->priv = NULL; } /* nsp_cs_detach */ @@ -1446,22 +1799,26 @@ #define CFG_CHECK(fn, args...) \ if (CardServices(fn, args) != 0) goto next_entry /*====================================================================*/ - static void nsp_cs_config(dev_link_t *link) { client_handle_t handle = link->handle; scsi_info_t *info = link->priv; tuple_t tuple; cisparse_t parse; - int i, last_ret, last_fn; - u_char tuple_data[64]; + int last_ret, last_fn; + unsigned char tuple_data[64]; config_info_t conf; + win_req_t req; + memreq_t map; + cistpl_cftable_entry_t dflt = { 0 }; + struct Scsi_Host *host; + nsp_hw_data *data = &nsp_data_base; +#if !(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74)) Scsi_Device *dev; dev_node_t **tail, *node; - struct Scsi_Host *host; - nsp_hw_data *data = &nsp_data; +#endif - DEBUG(0, __FUNCTION__ "() in\n"); + nsp_dbg(NSP_DEBUG_INIT, "in"); tuple.DesiredTuple = CISTPL_CONFIG; tuple.Attributes = 0; @@ -1475,7 +1832,6 @@ link->conf.Present = parse.config.rmask[0]; /* Configure card */ - driver_template.module = &__this_module; link->state |= DEV_CONFIG; /* Look up the current Vcc */ @@ -1485,81 +1841,195 @@ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; CS_CHECK(GetFirstTuple, handle, &tuple); while (1) { + cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); + CFG_CHECK(GetTupleData, handle, &tuple); CFG_CHECK(ParseTuple, handle, &tuple, &parse); - link->conf.ConfigIndex = parse.cftable_entry.index; - link->io.BasePort1 = parse.cftable_entry.io.win[0].base; - i = CardServices(RequestIO, handle, &link->io); - if (i == CS_SUCCESS) { - break; + + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; } + if (cfg->index == 0) { goto next_entry; } + link->conf.ConfigIndex = cfg->index; + + /* Does this card need audio output? */ + if (cfg->flags & CISTPL_CFTABLE_AUDIO) { + link->conf.Attributes |= CONF_ENABLE_SPKR; + link->conf.Status = CCSR_AUDIO_ENA; + } + + /* Use power settings for Vcc and Vpp if present */ + /* Note that the CIS values need to be rescaled */ + if (cfg->vcc.present & (1<vcc.param[CISTPL_POWER_VNOM]/10000) { + goto next_entry; + } + } else if (dflt.vcc.present & (1<vpp1.present & (1 << CISTPL_POWER_VNOM)) { + link->conf.Vpp1 = link->conf.Vpp2 = + cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; + } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) { + link->conf.Vpp1 = link->conf.Vpp2 = + dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; + } + + /* Do we need to allocate an interrupt? */ + if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) { + link->conf.Attributes |= CONF_ENABLE_IRQ; + } + + /* IO window settings */ + link->io.NumPorts1 = link->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (!(io->flags & CISTPL_IO_8BIT)) + link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + if (!(io->flags & CISTPL_IO_16BIT)) + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + link->io.BasePort1 = io->win[0].base; + link->io.NumPorts1 = io->win[0].len; + if (io->nwin > 1) { + link->io.Attributes2 = link->io.Attributes1; + link->io.BasePort2 = io->win[1].base; + link->io.NumPorts2 = io->win[1].len; + } + /* This reserves IO space but doesn't actually enable it */ + CFG_CHECK(RequestIO, link->handle, &link->io); + } + + if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) { + cistpl_mem_t *mem = + (cfg->mem.nwin) ? &cfg->mem : &dflt.mem; + req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; + req.Attributes |= WIN_ENABLE; + req.Base = mem->win[0].host_addr; + req.Size = mem->win[0].len; + if (req.Size < 0x1000) { + req.Size = 0x1000; + } + req.AccessSpeed = 0; + link->win = (window_handle_t)link->handle; + CFG_CHECK(RequestWindow, &link->win, &req); + map.Page = 0; map.CardOffset = mem->win[0].card_addr; + CFG_CHECK(MapMemPage, link->win, &map); + + data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size); + data->MmioLength = req.Size; + } + /* If we got this far, we're cool! */ + break; + next_entry: - DEBUG(0, __FUNCTION__ " next\n"); + nsp_dbg(NSP_DEBUG_INIT, "next"); + + if (link->io.NumPorts1) { + CardServices(ReleaseIO, link->handle, &link->io); + } CS_CHECK(GetNextTuple, handle, &tuple); } - CS_CHECK(RequestIRQ, handle, &link->irq); + if (link->conf.Attributes & CONF_ENABLE_IRQ) { + CS_CHECK(RequestIRQ, link->handle, &link->irq); + } CS_CHECK(RequestConfiguration, handle, &link->conf); - /* A bad hack... */ - release_region(link->io.BasePort1, link->io.NumPorts1); + if (free_ports) { + if (link->io.BasePort1) { + release_region(link->io.BasePort1, link->io.NumPorts1); + } + if (link->io.BasePort2) { + release_region(link->io.BasePort2, link->io.NumPorts2); + } + } /* Set port and IRQ */ data->BaseAddress = link->io.BasePort1; data->NumAddress = link->io.NumPorts1; data->IrqNumber = link->irq.AssignedIRQ; - DEBUG(0, __FUNCTION__ " I/O[0x%x+0x%x] IRQ %d\n", - data->BaseAddress, data->NumAddress, data->IrqNumber); + nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d", + data->BaseAddress, data->NumAddress, data->IrqNumber); if(nsphw_init(data) == FALSE) { goto cs_failed; } - scsi_register_module(MODULE_SCSI_HA, &driver_template); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)) + host = nsp_detect(&nsp_driver_template); +#else + scsi_register_host(&nsp_driver_template); + for (host = scsi_host_get_next(NULL); host != NULL; + host = scsi_host_get_next(host)) { + if (host->hostt == &nsp_driver_template) { + break; + } + } +#endif - DEBUG(0, "GET_SCSI_INFO\n"); + if (host == NULL) { + nsp_dbg(NSP_DEBUG_INIT, "detect failed"); + goto cs_failed; + } + + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74)) + scsi_add_host (host, NULL); + scsi_scan_host(host); + + snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no); + link->dev = &info->node; + info->host = host; + +#else + nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO"); tail = &link->dev; info->ndev = 0; - for (host = scsi_hostlist; host != NULL; host = host->next) { - if (host->hostt == &driver_template) { - for (dev = host->host_queue; dev != NULL; dev = dev->next) { - u_long arg[2], id; - kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg); - id = (arg[0]&0x0f) + ((arg[0]>>4)&0xf0) + - ((arg[0]>>8)&0xf00) + ((arg[0]>>12)&0xf000); - node = &info->node[info->ndev]; - node->minor = 0; - switch (dev->type) { - case TYPE_TAPE: - node->major = SCSI_TAPE_MAJOR; - sprintf(node->dev_name, "st#%04lx", id); - break; - case TYPE_DISK: - case TYPE_MOD: - node->major = SCSI_DISK0_MAJOR; - sprintf(node->dev_name, "sd#%04lx", id); - break; - case TYPE_ROM: - case TYPE_WORM: - node->major = SCSI_CDROM_MAJOR; - sprintf(node->dev_name, "sr#%04lx", id); - break; - default: - node->major = SCSI_GENERIC_MAJOR; - sprintf(node->dev_name, "sg#%04lx", id); - break; - } - *tail = node; tail = &node->next; - info->ndev++; - info->host = dev->host; - } + + nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host); + + for (dev = host->host_queue; dev != NULL; dev = dev->next) { + unsigned long arg[2], id; + kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg); + id = (arg[0] & 0x0f) + ((arg[0] >> 4) & 0xf0) + + ((arg[0] >> 8) & 0xf00) + ((arg[0] >> 12) & 0xf000); + node = &info->node[info->ndev]; + node->minor = 0; + switch (dev->type) { + case TYPE_TAPE: + node->major = SCSI_TAPE_MAJOR; + snprintf(node->dev_name, sizeof(node->dev_name), "st#%04lx", id); + break; + case TYPE_DISK: + case TYPE_MOD: + node->major = SCSI_DISK0_MAJOR; + snprintf(node->dev_name, sizeof(node->dev_name), "sd#%04lx", id); + break; + case TYPE_ROM: + case TYPE_WORM: + node->major = SCSI_CDROM_MAJOR; + snprintf(node->dev_name, sizeof(node->dev_name), "sr#%04lx", id); + break; + default: + node->major = SCSI_GENERIC_MAJOR; + snprintf(node->dev_name, sizeof(node->dev_name), "sg#%04lx", id); + break; } + *tail = node; tail = &node->next; + info->ndev++; + info->host = dev->host; } + *tail = NULL; if (info->ndev == 0) { - printk(KERN_INFO "nsp_cs: no SCSI devices found\n"); + nsp_msg(KERN_INFO, "no SCSI devices found"); } + nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host); +#endif /* Finally, report what we've done */ printk(KERN_INFO "nsp_cs: index 0x%02x: Vcc %d.%d", @@ -1575,47 +2045,60 @@ printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); } + if (link->io.NumPorts2) + printk(" & 0x%04x-0x%04x", link->io.BasePort2, + link->io.BasePort2+link->io.NumPorts2-1); + if (link->win) + printk(", mem 0x%06lx-0x%06lx", req.Base, + req.Base+req.Size-1); printk("\n"); link->state &= ~DEV_CONFIG_PENDING; return; -cs_failed: + cs_failed: + nsp_dbg(NSP_DEBUG_INIT, "config fail"); cs_error(link->handle, last_fn, last_ret); - nsp_cs_release((u_long)link); - return; + nsp_cs_release(link); + return; } /* nsp_cs_config */ #undef CS_CHECK #undef CFG_CHECK + /*====================================================================== After a card is removed, nsp_cs_release() will unregister the net device, and release the PCMCIA configuration. If the device is still open, this will be postponed until it is closed. ======================================================================*/ -static void nsp_cs_release(u_long arg) +static void nsp_cs_release(dev_link_t *link) { - dev_link_t *link = (dev_link_t *)arg; - - DEBUG(0, __FUNCTION__ "(0x%p)\n", link); + scsi_info_t *info = link->priv; + nsp_hw_data *data = NULL; - /* - * If the device is currently in use, we won't release until it - * is actually closed. - */ - if (link->open) { - DEBUG(1, "nsp_cs: release postponed, '%s' still open\n", - link->dev->dev_name); - link->state |= DEV_STALE_CONFIG; - return; + if (info->host == NULL) { + nsp_msg(KERN_DEBUG, "unexpected card release call."); + } else { + data = (nsp_hw_data *)info->host->hostdata; } + nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link); + /* Unlink the device chain */ - scsi_unregister_module(MODULE_SCSI_HA, &driver_template); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2)) + if (info->host != NULL) { + scsi_remove_host(info->host); + } +#else + scsi_unregister_host(&nsp_driver_template); +#endif link->dev = NULL; if (link->win) { + if (data != NULL) { + iounmap((void *)(data->MmioAddress)); + } CardServices(ReleaseWindow, link->win); } CardServices(ReleaseConfiguration, link->handle); @@ -1626,10 +2109,11 @@ CardServices(ReleaseIRQ, link->handle, &link->irq); } link->state &= ~DEV_CONFIG; - - if (link->state & DEV_STALE_LINK) { - nsp_cs_detach(link); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2)) + if (info->host != NULL) { + scsi_host_put(info->host); } +#endif } /* nsp_cs_release */ /*====================================================================== @@ -1643,39 +2127,53 @@ to block future accesses to this device. All the functions that actually access the device should check this flag to make sure the card is still present. - + ======================================================================*/ -static int nsp_cs_event(event_t event, - int priority, - event_callback_args_t *args) +static int nsp_cs_event(event_t event, + int priority, + event_callback_args_t *args) { dev_link_t *link = args->client_data; scsi_info_t *info = link->priv; + nsp_hw_data *data; - DEBUG(1, __FUNCTION__ "(0x%06x)\n", event); + nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event); switch (event) { case CS_EVENT_CARD_REMOVAL: - DEBUG(0, " event: remove\n"); + nsp_dbg(NSP_DEBUG_INIT, "event: remove"); 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(link); } break; case CS_EVENT_CARD_INSERTION: - DEBUG(0, " event: insert\n"); + nsp_dbg(NSP_DEBUG_INIT, "event: insert"); link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68)) info->bus = args->bus; +#endif nsp_cs_config(link); break; case CS_EVENT_PM_SUSPEND: + nsp_dbg(NSP_DEBUG_INIT, "event: suspend"); link->state |= DEV_SUSPEND; /* Fall through... */ case CS_EVENT_RESET_PHYSICAL: /* Mark the device as stopped, to block IO until later */ + nsp_dbg(NSP_DEBUG_INIT, "event: reset physical"); + + if (info->host != NULL) { + nsp_msg(KERN_INFO, "clear SDTR status"); + + data = (nsp_hw_data *)info->host->hostdata; + + nsphw_init_sync(data); + } + info->stop = 1; if (link->state & DEV_CONFIG) { CardServices(ReleaseConfiguration, link->handle); @@ -1683,68 +2181,92 @@ break; case CS_EVENT_PM_RESUME: + nsp_dbg(NSP_DEBUG_INIT, "event: resume"); link->state &= ~DEV_SUSPEND; /* Fall through... */ case CS_EVENT_CARD_RESET: - DEBUG(0, " event: reset\n"); + nsp_dbg(NSP_DEBUG_INIT, "event: reset"); if (link->state & DEV_CONFIG) { - Scsi_Cmnd tmp; - CardServices(RequestConfiguration, link->handle, &link->conf); - tmp.host = info->host; - nsp_eh_host_reset(&tmp); } info->stop = 0; + + if (info->host != NULL) { + nsp_msg(KERN_INFO, "reset host and bus"); + + data = (nsp_hw_data *)info->host->hostdata; + + nsphw_init (data); + nsp_bus_reset(data); + } + break; default: - DEBUG(0, " event: unknown\n"); + nsp_dbg(NSP_DEBUG_INIT, "event: unknown"); break; } - DEBUG(0, __FUNCTION__ " end\n"); + nsp_dbg(NSP_DEBUG_INIT, "end"); return 0; } /* nsp_cs_event */ /*======================================================================* * module entry point *====================================================================*/ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68)) +static struct pcmcia_driver nsp_driver = { + .owner = THIS_MODULE, + .drv = { + .name = "nsp_cs", + }, + .attach = nsp_cs_attach, + .detach = nsp_cs_detach, +}; +#endif + static int __init nsp_cs_init(void) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68)) + nsp_msg(KERN_INFO, "loading..."); + + return pcmcia_register_driver(&nsp_driver); +#else servinfo_t serv; - DEBUG(0, __FUNCTION__ "() in\n"); - DEBUG(0, "%s\n", version); + nsp_msg(KERN_INFO, "loading..."); CardServices(GetCardServicesInfo, &serv); if (serv.Revision != CS_RELEASE_CODE) { - printk(KERN_DEBUG "nsp_cs: Card Services release " - "does not match!\n"); - return -1; + nsp_msg(KERN_DEBUG, "Card Services release does not match!"); + return -EINVAL; } register_pcmcia_driver(&dev_info, &nsp_cs_attach, &nsp_cs_detach); - DEBUG(0, __FUNCTION__ "() out\n"); + nsp_dbg(NSP_DEBUG_INIT, "out"); return 0; +#endif } - -static void __exit nsp_cs_cleanup(void) +static void __exit nsp_cs_exit(void) { - DEBUG(0, __FUNCTION__ "() unloading\n"); + nsp_msg(KERN_INFO, "unloading..."); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68)) + pcmcia_unregister_driver(&nsp_driver); +#else unregister_pcmcia_driver(&dev_info); +#endif + + /* XXX: this really needs to move into generic code.. */ while (dev_list != NULL) { if (dev_list->state & DEV_CONFIG) { - nsp_cs_release((u_long)dev_list); + nsp_cs_release(dev_list); } nsp_cs_detach(dev_list); } } -module_init(nsp_cs_init); -module_exit(nsp_cs_cleanup); -/* - * - * - */ +module_init(nsp_cs_init) +module_exit(nsp_cs_exit) /* end */ Index: drivers/scsi/pcmcia/nsp_cs.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/pcmcia/nsp_cs.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/pcmcia/nsp_cs.h 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/pcmcia/nsp_cs.h 4 Aug 2004 01:29:43 -0000 1.2 @@ -10,13 +10,13 @@ =========================================================*/ -/* $Id: nsp_cs.h,v 1.1 2004/07/22 19:50:08 joff Exp $ */ +/* $Id: nsp_cs.h,v 1.2 2004/08/04 01:29:43 joff Exp $ */ #ifndef __nsp_cs__ #define __nsp_cs__ /* for debugging */ -/*#define PCMCIA_DEBUG 9*/ +//#define NSP_DEBUG 9 /* #define static @@ -26,64 +26,83 @@ /************************************ * Some useful macros... */ -#define Number(arr) ((int) (sizeof(arr) / sizeof(arr[0]))) -#define BIT(x) (1<<(x)) +#define NUMBER(arr) ((int) (sizeof(arr) / sizeof(arr[0]))) /* from XtNumber() in /usr/X11R6/include/X11/Intrinsic.h */ +#define BIT(x) (1L << (x)) #define MIN(a,b) ((a) > (b) ? (b) : (a)) -/* SCSI initiator must be 7 */ -#define SCSI_INITIATOR_ID 7 +/* SCSI initiator must be ID 7 */ +#define NSP_INITIATOR_ID 7 #define NSP_SELTIMEOUT 200 -/* base register */ -#define IRQCONTROL 0x00 +/*************************************************************************** + * register definitions + ***************************************************************************/ +/*======================================================================== + * base register + ========================================================================*/ +#define IRQCONTROL 0x00 /* R */ # define IRQCONTROL_RESELECT_CLEAR BIT(0) # define IRQCONTROL_PHASE_CHANGE_CLEAR BIT(1) # define IRQCONTROL_TIMER_CLEAR BIT(2) # define IRQCONTROL_FIFO_CLEAR BIT(3) -# define IRQCONTROL_ALLMASK 0xff -# define IRQCONTROL_ALLCLEAR 0x0f -# define IRQCONTROL_IRQDISABLE 0xf0 +# define IRQCONTROL_SCSI_IRQ_MASK BIT(4) +# define IRQCONTROL_EXT_IRQ_MASK BIT(5) +# define IRQCONTROL_TIMER_IRQ_MASK BIT(6) +# define IRQCONTROL_FIFO_IRQ_MASK BIT(7) +# define IRQCONTROL_ALL_MASK (IRQCONTROL_SCSI_IRQ_MASK | \ + IRQCONTROL_EXT_IRQ_MASK | \ + IRQCONTROL_TIMER_IRQ_MASK | \ + IRQCONTROL_FIFO_IRQ_MASK ) +# define IRQCONTROL_ALL_CLEAR (IRQCONTROL_RESELECT_CLEAR | \ + IRQCONTROL_PHASE_CHANGE_CLEAR | \ + IRQCONTROL_TIMER_CLEAR | \ + IRQCONTROL_FIFO_CLEAR ) +# define IRQCONTROL_ALL_CLEAR_AND_MASK (IRQCONTROL_ALL_MASK | \ + IRQCONTROL_ALL_CLEAR) -#define IRQSTATUS 0x00 +#define IRQSTATUS 0x00 /* W */ # define IRQSTATUS_SCSI BIT(0) # define IRQSTATUS_TIMER BIT(2) # define IRQSTATUS_FIFO BIT(3) # define IRQSTATUS_MASK 0x0f -#define IFSELECT 0x01 +#define IFSELECT 0x01 /* W */ # define IF_IFSEL BIT(0) # define IF_REGSEL BIT(2) -#define FIFOSTATUS 0x01 -# define FIFOSTATUS_CHIP_REVISION 0x0f -# define FIFOSTATUS_CHIP_ID 0x70 -# define FIFOSTATUS_FULL_EMPTY 0x80 - -#define INDEXREG 0x02 -#define DATAREG 0x03 -#define FIFODATA 0x04 -#define FIFODATA1 0x05 -#define FIFODATA2 0x06 -#define FIFODATA3 0x07 +#define FIFOSTATUS 0x01 /* R */ +# define FIFOSTATUS_CHIP_REVISION_MASK 0x0f +# define FIFOSTATUS_CHIP_ID_MASK 0x70 +# define FIFOSTATUS_FULL_EMPTY BIT(7) + +#define INDEXREG 0x02 /* R/W */ +#define DATAREG 0x03 /* R/W */ +#define FIFODATA 0x04 /* R/W */ +#define FIFODATA1 0x05 /* R/W */ +#define FIFODATA2 0x06 /* R/W */ +#define FIFODATA3 0x07 /* R/W */ + +/*==================================================================== + * indexed register + ====================================================================*/ +#define EXTBUSCTRL 0x10 /* R/W,deleted */ -/* indexed register */ -#define EXTBUSCTRL 0x10 - -#define CLOCKDIV 0x11 +#define CLOCKDIV 0x11 /* R/W */ # define CLOCK_40M 0x02 # define CLOCK_20M 0x01 +# define FAST_20 BIT(2) -#define TERMPWRCTRL 0x13 +#define TERMPWRCTRL 0x13 /* R/W */ # define POWER_ON BIT(0) -#define SCSIIRQMODE 0x15 +#define SCSIIRQMODE 0x15 /* R/W */ # define SCSI_PHASE_CHANGE_EI BIT(0) # define RESELECT_EI BIT(4) # define FIFO_IRQ_EI BIT(5) # define SCSI_RESET_IRQ_EI BIT(6) -#define IRQPHASESENCE 0x16 +#define IRQPHASESENCE 0x16 /* R */ # define LATCHED_MSG BIT(0) # define LATCHED_IO BIT(1) # define LATCHED_CD BIT(2) @@ -93,9 +112,9 @@ # define FIFO_IRQ BIT(6) # define SCSI_RESET_IRQ BIT(7) -#define TIMERCOUNT 0x17 +#define TIMERCOUNT 0x17 /* R/W */ -#define SCSIBUSCTRL 0x18 +#define SCSIBUSCTRL 0x18 /* R/W */ # define SCSI_SEL BIT(0) # define SCSI_RST BIT(1) # define SCSI_DATAOUT_ENB BIT(2) @@ -105,13 +124,13 @@ # define AUTODIRECTION BIT(6) # define ACKENB BIT(7) -#define SCSIBUSMON 0x19 +#define SCSIBUSMON 0x19 /* R */ -#define SETARBIT 0x1A +#define SETARBIT 0x1A /* W */ # define ARBIT_GO BIT(0) # define ARBIT_FLAG_CLEAR BIT(1) -#define ARBITSTATUS 0x1A +#define ARBITSTATUS 0x1A /* R */ /*# define ARBIT_GO BIT(0)*/ # define ARBIT_WIN BIT(1) # define ARBIT_FAIL BIT(2) @@ -124,90 +143,110 @@ # define CLEAR_COMMAND_POINTER BIT(0) # define AUTO_COMMAND_GO BIT(1) -#define RESELECTID 0x1C /* R */ -#define COMMANDDATA 0x1D +#define RESELECTID 0x1C /* R */ +#define COMMANDDATA 0x1D /* R/W */ -#define POINTERCLR 0x1E /* W */ +#define POINTERCLR 0x1E /* W */ # define POINTER_CLEAR BIT(0) # define ACK_COUNTER_CLEAR BIT(1) # define REQ_COUNTER_CLEAR BIT(2) # define HOST_COUNTER_CLEAR BIT(3) -# define READ_SOURCE 0x30 - -#define TRANSFERCOUNT 0x1E /* R */ - -#define TRANSFERMODE 0x20 -# define MODE_MEM8 BIT(0) -# define MODE_MEM32 BIT(1) -# define MODE_ADR24 BIT(2) -# define MODE_ADR32 BIT(3) -# define MODE_IO8 BIT(4) -# define MODE_IO32 BIT(5) -# define TRANSFER_GO BIT(6) -# define BRAIND BIT(7) +# define READ_SOURCE (BIT(4) | BIT(5)) +# define ACK_COUNTER (0) +# define REQ_COUNTER (BIT(4)) +# define HOST_COUNTER (BIT(5)) + +#define TRANSFERCOUNT 0x1E /* R */ + +#define TRANSFERMODE 0x20 /* R/W */ +# define MODE_MEM8 BIT(0) +# define MODE_MEM32 BIT(1) +# define MODE_ADR24 BIT(2) +# define MODE_ADR32 BIT(3) +# define MODE_IO8 BIT(4) +# define MODE_IO32 BIT(5) +# define TRANSFER_GO BIT(6) +# define BRAIND BIT(7) -#define SYNCREG 0x21 +#define SYNCREG 0x21 /* R/W */ # define SYNCREG_OFFSET_MASK 0x0f # define SYNCREG_PERIOD_MASK 0xf0 # define SYNCREG_PERIOD_SHIFT 4 -#define SCSIDATALATCH 0x22 -#define SCSIDATAIN 0x22 -#define SCSIDATAWITHACK 0x23 -#define SCAMCONTROL 0x24 -#define SCAMSTATUS 0x24 -#define SCAMDATA 0x25 +#define SCSIDATALATCH 0x22 /* W */ +#define SCSIDATAIN 0x22 /* R */ +#define SCSIDATAWITHACK 0x23 /* R/W */ +#define SCAMCONTROL 0x24 /* W */ +#define SCAMSTATUS 0x24 /* R */ +#define SCAMDATA 0x25 /* R/W */ -#define OTHERCONTROL 0x26 +#define OTHERCONTROL 0x26 /* R/W */ # define TPL_ROM_WRITE_EN BIT(0) # define TPWR_OUT BIT(1) # define TPWR_SENSE BIT(2) # define RA8_CONTROL BIT(3) -#define ACKWIDTH 0x27 -#define CLRTESTPNT 0x28 -#define ACKCNTLD 0x29 -#define REQCNTLD 0x2A -#define HSTCNTLD 0x2B -#define CHECKSUM 0x2C +#define ACKWIDTH 0x27 /* R/W */ +#define CLRTESTPNT 0x28 /* W */ +#define ACKCNTLD 0x29 /* W */ +#define REQCNTLD 0x2A /* W */ +#define HSTCNTLD 0x2B /* W */ +#define CHECKSUM 0x2C /* R/W */ -/* +/************************************************************************ * Input status bit definitions. - */ -#define S_ATN 0x80 /**/ -#define S_SELECT 0x40 /**/ -#define S_REQUEST 0x20 /* Request line from SCSI bus*/ -#define S_ACK 0x10 /* Acknowlege line from SCSI bus*/ -#define S_BUSY 0x08 /* Busy line from SCSI bus*/ -#define S_CD 0x04 /* Command/Data line from SCSI bus*/ -#define S_IO 0x02 /* Input/Output line from SCSI bus*/ -#define S_MESSAGE 0x01 /* Message line from SCSI bus*/ + ************************************************************************/ +#define S_MESSAGE BIT(0) /* Message line from SCSI bus */ +#define S_IO BIT(1) /* Input/Output line from SCSI bus */ +#define S_CD BIT(2) /* Command/Data line from SCSI bus */ +#define S_BUSY BIT(3) /* Busy line from SCSI bus */ +#define S_ACK BIT(4) /* Acknowlege line from SCSI bus */ +#define S_REQUEST BIT(5) /* Request line from SCSI bus */ +#define S_SELECT BIT(6) /* */ +#define S_ATN BIT(7) /* */ -/* +/*********************************************************************** * Useful Bus Monitor status combinations. - */ + ***********************************************************************/ #define BUSMON_SEL S_SELECT #define BUSMON_BSY S_BUSY #define BUSMON_REQ S_REQUEST #define BUSMON_IO S_IO #define BUSMON_ACK S_ACK #define BUSMON_BUS_FREE 0 -#define BUSMON_COMMAND ( S_BUSY | S_CD | S_REQUEST ) -#define BUSMON_MESSAGE_IN ( S_BUSY | S_MESSAGE | S_IO | S_CD | S_REQUEST ) -#define BUSMON_MESSAGE_OUT ( S_BUSY | S_MESSAGE | S_CD | S_REQUEST ) -#define BUSMON_DATA_IN ( S_BUSY | S_IO | S_REQUEST ) -#define BUSMON_DATA_OUT ( S_BUSY | S_REQUEST ) -#define BUSMON_STATUS ( S_BUSY | S_IO | S_CD | S_REQUEST ) -#define BUSMON_RESELECT ( S_SELECT | S_IO ) -#define BUSMON_PHASE_MASK ( S_SELECT | S_CD | S_MESSAGE | S_IO ) +#define BUSMON_COMMAND ( S_BUSY | S_CD | S_REQUEST ) +#define BUSMON_MESSAGE_IN ( S_BUSY | S_CD | S_IO | S_MESSAGE | S_REQUEST ) +#define BUSMON_MESSAGE_OUT ( S_BUSY | S_CD | S_MESSAGE | S_REQUEST ) +#define BUSMON_DATA_IN ( S_BUSY | S_IO | S_REQUEST ) +#define BUSMON_DATA_OUT ( S_BUSY | S_REQUEST ) +#define BUSMON_STATUS ( S_BUSY | S_CD | S_IO | S_REQUEST ) +#define BUSMON_SELECT ( S_IO | S_SELECT ) +#define BUSMON_RESELECT ( S_IO | S_SELECT ) +#define BUSMON_PHASE_MASK ( S_CD | S_IO | S_MESSAGE | S_SELECT ) +#define BUSPHASE_SELECT ( BUSMON_SELECT & BUSMON_PHASE_MASK ) #define BUSPHASE_COMMAND ( BUSMON_COMMAND & BUSMON_PHASE_MASK ) #define BUSPHASE_MESSAGE_IN ( BUSMON_MESSAGE_IN & BUSMON_PHASE_MASK ) #define BUSPHASE_MESSAGE_OUT ( BUSMON_MESSAGE_OUT & BUSMON_PHASE_MASK ) #define BUSPHASE_DATA_IN ( BUSMON_DATA_IN & BUSMON_PHASE_MASK ) #define BUSPHASE_DATA_OUT ( BUSMON_DATA_OUT & BUSMON_PHASE_MASK ) #define BUSPHASE_STATUS ( BUSMON_STATUS & BUSMON_PHASE_MASK ) -#define BUSPHASE_SELECT ( S_SELECT | S_IO ) + +/*====================================================================*/ + +typedef struct scsi_info_t { + dev_link_t link; + struct Scsi_Host *host; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74)) + dev_node_t node; +#else + int ndev; + dev_node_t node[8]; + struct bus_operations *bus; +#endif + int stop; +} scsi_info_t; + /* synchronous transfer negotiation data */ typedef struct _sync_data { @@ -222,67 +261,116 @@ unsigned char AckWidth; } sync_data; -typedef struct _nsp_data { +typedef struct _nsp_hw_data { unsigned int BaseAddress; unsigned int NumAddress; unsigned int IrqNumber; - unsigned char ScsiClockDiv; + unsigned long MmioAddress; +#define NSP_MMIO_OFFSET 0x0800 + unsigned long MmioLength; + unsigned char ScsiClockDiv; unsigned char TransferMode; + unsigned char ChipRev; int TimerCount; int SelectionTimeOut; Scsi_Cmnd *CurrentSC; + //int CurrnetTarget; int FifoCount; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) - int Residual; -#define RESID data->Residual -#else -#define RESID SCpnt->resid -#endif #define MSGBUF_SIZE 20 unsigned char MsgBuffer[MSGBUF_SIZE]; int MsgLen; #define N_TARGET 8 -#define N_LUN 8 - sync_data Sync[N_TARGET][N_LUN]; + sync_data Sync[N_TARGET]; + + char nspinfo[110]; /* description */ + spinlock_t Lock; + + scsi_info_t *ScsiInfo; /* attach <-> detect glue */ + + +#ifdef NSP_DEBUG + int CmdId; /* Accepted command serial number. + Used for debugging. */ +#endif } nsp_hw_data; -static void nsp_cs_release(u_long arg); -static int nsp_cs_event(event_t event, int priority, event_callback_args_t *args); -static dev_link_t *nsp_cs_attach(void); -static void nsp_cs_detach(dev_link_t *); - -static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt, nsp_hw_data *data); -static void nsp_start_timer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int time); - -static int nsp_detect(Scsi_Host_Template * ); -static int nsp_release(struct Scsi_Host *shpnt); -static const char * nsp_info(struct Scsi_Host *shpnt); -static int nsp_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *)); - -static int nsp_abort(Scsi_Cmnd *); -static int nsp_reset(Scsi_Cmnd *, unsigned int); - -static int nsp_eh_abort(Scsi_Cmnd * SCpnt); -static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt); -static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt); -static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt); - -static int nsp_fifo_count(Scsi_Cmnd *SCpnt); -static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data); -static int nsp_nexus(Scsi_Cmnd *SCpnt, nsp_hw_data *data); - -#ifdef PCMCIA_DEBUG -static void show_command(Scsi_Cmnd *ptr); -static void show_phase(Scsi_Cmnd *SCpnt); +/**************************************************************************** + * + */ + +/* Card service functions */ +static dev_link_t *nsp_cs_attach (void); +static void nsp_cs_detach (dev_link_t *link); +static void nsp_cs_release(dev_link_t *link); +static void nsp_cs_config (dev_link_t *link); +static int nsp_cs_event (event_t event, int priority, event_callback_args_t *args); + +/* Linux SCSI subsystem specific functions */ +static struct Scsi_Host *nsp_detect (Scsi_Host_Template *sht); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +static int nsp_detect_old (Scsi_Host_Template *sht); +static int nsp_release_old(struct Scsi_Host *shpnt); +#endif +static const char *nsp_info (struct Scsi_Host *shpnt); +static int nsp_proc_info ( +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) + struct Scsi_Host *host, +#endif + char *buffer, + char **start, + off_t offset, + int length, +#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) + int hostno, +#endif + int inout); +static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (* done)(Scsi_Cmnd *SCpnt)); + +/* Error handler */ +/*static int nsp_eh_abort (Scsi_Cmnd *SCpnt);*/ +/*static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt);*/ +static int nsp_eh_bus_reset (Scsi_Cmnd *SCpnt); +static int nsp_eh_host_reset (Scsi_Cmnd *SCpnt); +static int nsp_bus_reset (nsp_hw_data *data); + +/* */ +static int nsphw_init (nsp_hw_data *data); +static int nsphw_start_selection(Scsi_Cmnd *SCpnt); +static void nsp_start_timer (Scsi_Cmnd *SCpnt, int time); +static int nsp_fifo_count (Scsi_Cmnd *SCpnt); +static void nsp_pio_read (Scsi_Cmnd *SCpnt); +static void nsp_pio_write (Scsi_Cmnd *SCpnt); +static int nsp_nexus (Scsi_Cmnd *SCpnt); +static void nsp_scsi_done (Scsi_Cmnd *SCpnt); +static int nsp_analyze_sdtr (Scsi_Cmnd *SCpnt); +static int nsp_negate_signal (Scsi_Cmnd *SCpnt, unsigned char mask, char *str); +static int nsp_expect_signal (Scsi_Cmnd *SCpnt, unsigned char current_phase, unsigned char mask); +static int nsp_xfer (Scsi_Cmnd *SCpnt, int phase); +static int nsp_dataphase_bypass (Scsi_Cmnd *SCpnt); +static int nsp_reselected (Scsi_Cmnd *SCpnt); +static struct Scsi_Host *nsp_detect(Scsi_Host_Template *sht); + +/* Interrupt handler */ +//static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs); + +/* Module entry point*/ +static int __init nsp_cs_init(void); +static void __exit nsp_cs_exit(void); + + +/* Debug */ +#ifdef NSP_DEBUG +static void show_command (Scsi_Cmnd *SCpnt); +static void show_phase (Scsi_Cmnd *SCpnt); static void show_busphase(unsigned char stat); -static void show_message(nsp_hw_data *data); +static void show_message (nsp_hw_data *data); #else # define show_command(ptr) /* */ # define show_phase(SCpnt) /* */ @@ -294,17 +382,19 @@ * SCSI phase */ enum _scsi_phase { - PH_UNDETERMINED, - PH_ARBSTART, - PH_SELSTART, - PH_SELECTED, - PH_COMMAND, - PH_DATA, - PH_STATUS, - PH_MSG_IN, - PH_MSG_OUT, - PH_DISCONNECT, - PH_RESELECT + PH_UNDETERMINED , + PH_ARBSTART , + PH_SELSTART , + PH_SELECTED , + PH_COMMAND , + PH_DATA , + PH_STATUS , + PH_MSG_IN , + PH_MSG_OUT , + PH_DISCONNECT , + PH_RESELECT , + PH_ABORT , + PH_RESET }; enum _data_in_out { @@ -313,12 +403,85 @@ IO_OUT }; +enum _burst_mode { + BURST_IO8 = 0, + BURST_IO32 = 1, + BURST_MEM32 = 2, +}; -/* SCSI messaage */ + +/************************************************************************** + * SCSI messaage + */ #define MSG_COMMAND_COMPLETE 0x00 #define MSG_EXTENDED 0x01 +#define MSG_ABORT 0x06 #define MSG_NO_OPERATION 0x08 +#define MSG_BUS_DEVICE_RESET 0x0c #define MSG_EXT_SDTR 0x01 + +/************************************************************************** + * Compatibility functions + */ + +/* for Kernel 2.4 */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) +# define scsi_register_host(template) scsi_register_module(MODULE_SCSI_HA, template) +# define scsi_unregister_host(template) scsi_unregister_module(MODULE_SCSI_HA, template) +# define scsi_host_put(host) scsi_unregister(host) + +# define IRQ_NONE /* */ +# define IRQ_HANDLED /* */ +# define IRQ_RETVAL(x) /* */ + +/* This is ad-hoc version of scsi_host_get_next() */ +static inline struct Scsi_Host *scsi_host_get_next(struct Scsi_Host *host) +{ + if (host == NULL) { + return scsi_hostlist; + } else { + return host->next; + } +} + +/* This is ad-hoc version of scsi_host_hn_get() */ +static inline struct Scsi_Host *scsi_host_hn_get(unsigned short hostno) +{ + struct Scsi_Host *host; + + for (host = scsi_host_get_next(NULL); host != NULL; + host = scsi_host_get_next(host)) { + if (host->host_no == hostno) { + break; + } + } + + return host; +} + +static void cs_error(client_handle_t handle, int func, int ret) +{ + error_info_t err = { func, ret }; + CardServices(ReportError, handle, &err); +} + +/* scatter-gather table */ +# define SG_ADDRESS(buffer) ((buffer)->address) + +/* host spin lock */ +# define HOST_LOCK (&io_request_lock) +#endif + +/* for Kernel 2.6 */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) +/* scatter-gather table */ +# define SG_ADDRESS(buffer) ((char *) (page_address((buffer)->page)+(buffer)->offset)) + +/* host spin lock */ +# define HOST_LOCK (((scsi_info_t *)dev_id)->host->host_lock) +#endif + #endif /*__nsp_cs__*/ +/* end */ Index: drivers/scsi/pcmcia/nsp_debug.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/pcmcia/nsp_debug.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/pcmcia/nsp_debug.c 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/pcmcia/nsp_debug.c 4 Aug 2004 01:29:43 -0000 1.2 @@ -6,7 +6,7 @@ the GNU General Public License. =========================================================================*/ -/* $Id: nsp_debug.c,v 1.1 2004/07/22 19:50:08 joff Exp $ */ +/* $Id: nsp_debug.c,v 1.2 2004/08/04 01:29:43 joff Exp $ */ /* * Show the command data of a command @@ -87,14 +87,21 @@ static void print_commandk (unsigned char *command) { - int i,s; + int i, s; printk(KERN_DEBUG); print_opcodek(command[0]); /*printk(KERN_DEBUG __FUNCTION__ " ");*/ - for ( i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) { + if ((command[0] >> 5) == 6 || + (command[0] >> 5) == 7 ) { + s = 12; /* vender specific */ + } else { + s = COMMAND_SIZE(command[0]); + } + for ( i = 1; i < s; ++i) { printk("%02x ", command[i]); } - switch (COMMAND_SIZE(command[0])) { + + switch (s) { case 6: printk("LBA=%d len=%d", (((unsigned int)command[1] & 0x0f) << 16) | @@ -131,9 +138,9 @@ printk("\n"); } -static void show_command(Scsi_Cmnd *ptr) +static void show_command(Scsi_Cmnd *SCpnt) { - print_commandk(ptr->cmnd); + print_commandk(SCpnt->cmnd); } static void show_phase(Scsi_Cmnd *SCpnt) Index: drivers/scsi/pcmcia/nsp_io.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/pcmcia/nsp_io.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/pcmcia/nsp_io.h 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/pcmcia/nsp_io.h 4 Aug 2004 01:29:43 -0000 1.2 @@ -7,7 +7,7 @@ */ -/* $Id: nsp_io.h,v 1.1 2004/07/22 19:50:08 joff Exp $ */ +/* $Id: nsp_io.h,v 1.2 2004/08/04 01:29:43 joff Exp $ */ #ifndef __NSP_IO_H__ #define __NSP_IO_H__ @@ -76,7 +76,7 @@ void *buf, unsigned long count) { - //DEBUG(0, __FUNCTION__ "() buf=0x%p, count=0x%lx\n", buf, count); + /*nsp_dbg(NSP_DEBUG_DATA_IO, "buf=0x%p, count=0x%lx", buf, count);*/ nsp_multi_read_1(base, FIFODATA, buf, count); } @@ -95,7 +95,7 @@ void *buf, unsigned long count) { - //DEBUG(0, __FUNCTION__ "() buf=0x%p, count=0x%lx*2\n", buf, count); + //nsp_dbg(NSP_DEBUG_DATA_IO, "buf=0x%p, count=0x%lx*2", buf, count); nsp_multi_read_2(base, FIFODATA, buf, count); } @@ -114,7 +114,7 @@ void *buf, unsigned long count) { - //DEBUG(0, __FUNCTION__ "() buf=0x%p, count=0x%lx*4\n", buf, count); + //nsp_dbg(NSP_DEBUG_DATA_IO, "buf=0x%p, count=0x%lx*4", buf, count); nsp_multi_read_4(base, FIFODATA, buf, count); } @@ -172,5 +172,103 @@ nsp_multi_write_4(base, FIFODATA, buf, count); } + +/*====================================================================*/ + +static inline void nsp_mmio_write(unsigned long base, + unsigned int index, + unsigned char val) +{ + unsigned char *ptr = (unsigned char *)(base + NSP_MMIO_OFFSET + index); + + writeb(val, ptr); +} + +static inline unsigned char nsp_mmio_read(unsigned long base, + unsigned int index) +{ + unsigned char *ptr = (unsigned char *)(base + NSP_MMIO_OFFSET + index); + + return readb(ptr); +} + +/*-----------*/ + +static inline unsigned char nsp_mmio_index_read(unsigned long base, + unsigned int reg) +{ + unsigned char *index_ptr = (unsigned char *)(base + NSP_MMIO_OFFSET + INDEXREG); + unsigned char *data_ptr = (unsigned char *)(base + NSP_MMIO_OFFSET + DATAREG); + + writeb((unsigned char)reg, index_ptr); + return readb(data_ptr); +} + +static inline void nsp_mmio_index_write(unsigned long base, + unsigned int reg, + unsigned char val) +{ + unsigned char *index_ptr = (unsigned char *)(base + NSP_MMIO_OFFSET + INDEXREG); + unsigned char *data_ptr = (unsigned char *)(base + NSP_MMIO_OFFSET + DATAREG); + + writeb((unsigned char)reg, index_ptr); + writeb(val, data_ptr); +} + +/* read 32bit FIFO */ +static inline void nsp_mmio_multi_read_4(unsigned long base, + unsigned int Register, + void *buf, + unsigned long count) +{ + unsigned long *ptr = (unsigned long *)(base + Register); + unsigned long *tmp = (unsigned long *)buf; + int i; + + //nsp_dbg(NSP_DEBUG_DATA_IO, "base 0x%0lx ptr 0x%p",base,ptr); + + for (i = 0; i < count; i++) { + *tmp = readl(ptr); + //nsp_dbg(NSP_DEBUG_DATA_IO, "<%d,%p,%p,%lx>", i, ptr, tmp, *tmp); + tmp++; + } +} + +static inline void nsp_mmio_fifo32_read(unsigned int base, + void *buf, + unsigned long count) +{ + //nsp_dbg(NSP_DEBUG_DATA_IO, "buf=0x%p, count=0x%lx*4", buf, count); + nsp_mmio_multi_read_4(base, FIFODATA, buf, count); +} + +static inline void nsp_mmio_multi_write_4(unsigned long base, + unsigned int Register, + void *buf, + unsigned long count) +{ + unsigned long *ptr = (unsigned long *)(base + Register); + unsigned long *tmp = (unsigned long *)buf; + int i; + + //nsp_dbg(NSP_DEBUG_DATA_IO, "base 0x%0lx ptr 0x%p",base,ptr); + + for (i = 0; i < count; i++) { + writel(*tmp, ptr); + //nsp_dbg(NSP_DEBUG_DATA_IO, "<%d,%p,%p,%lx>", i, ptr, tmp, *tmp); + tmp++; + } +} + +static inline void nsp_mmio_fifo32_write(unsigned int base, + void *buf, + unsigned long count) +{ + //nsp_dbg(NSP_DEBUG_DATA_IO, "buf=0x%p, count=0x%lx*4", buf, count); + nsp_mmio_multi_write_4(base, FIFODATA, buf, count); +} + + + #endif /* end */ Index: drivers/scsi/pcmcia/nsp_message.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/pcmcia/nsp_message.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/pcmcia/nsp_message.c 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/pcmcia/nsp_message.c 4 Aug 2004 01:29:43 -0000 1.2 @@ -6,11 +6,12 @@ the GNU General Public License. */ -/* $Id: nsp_message.c,v 1.1 2004/07/22 19:50:08 joff Exp $ */ +/* $Id: nsp_message.c,v 1.2 2004/08/04 01:29:43 joff Exp $ */ -static void nsp_message_in(Scsi_Cmnd *SCpnt, nsp_hw_data *data) +static void nsp_message_in(Scsi_Cmnd *SCpnt) { - unsigned int base = SCpnt->host->io_port; + unsigned int base = SCpnt->device->host->io_port; + nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; unsigned char data_reg, control_reg; int ret, len; @@ -23,7 +24,7 @@ ret = 16; len = 0; - DEBUG(0, " msgin loop\n"); + nsp_dbg(NSP_DEBUG_MSGINOCCUR, "msgin loop"); do { /* read data */ data_reg = nsp_index_read(base, SCSIDATAIN); @@ -49,8 +50,9 @@ } -static void nsp_message_out(Scsi_Cmnd *SCpnt, nsp_hw_data *data) +static void nsp_message_out(Scsi_Cmnd *SCpnt) { + nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; int ret = 1; int len = data->MsgLen; @@ -61,10 +63,10 @@ * the next "msg out" if exists (no scsi phase changes). */ - DEBUG(0, " msgout loop\n"); + nsp_dbg(NSP_DEBUG_MSGOUTOCCUR, "msgout loop"); do { - if (nsp_xfer(SCpnt, data, BUSPHASE_MESSAGE_OUT)) { - printk(KERN_DEBUG " " __FUNCTION__ " msgout: xfer short\n"); + if (nsp_xfer(SCpnt, BUSPHASE_MESSAGE_OUT)) { + nsp_msg(KERN_DEBUG, "msgout: xfer short"); } /* catch a next signal */ Index: drivers/scsi/pcmcia/qlogic_stub.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/pcmcia/qlogic_stub.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/pcmcia/qlogic_stub.c 22 Jul 2004 19:50:08 -0000 1.1 +++ drivers/scsi/pcmcia/qlogic_stub.c 4 Aug 2004 01:29:43 -0000 1.2 @@ -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; Index: drivers/scsi/sym53c8xx_2/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/sym53c8xx_2/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/sym53c8xx_2/Makefile 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/sym53c8xx_2/Makefile 4 Aug 2004 01:29:43 -0000 1.2 @@ -1,14 +1,14 @@ -# File: drivers/sym53c8xx/Makefile +# File: drivers/scsi/sym53c8xx_2/Makefile # Makefile for the NCR/SYMBIOS/LSI 53C8XX PCI SCSI controllers driver. -list-multi := sym53c8xx.o -sym53c8xx-objs := sym_fw.o sym_glue.o sym_hipd.o sym_malloc.o sym_misc.o sym_nvram.o -obj-$(CONFIG_SCSI_SYM53C8XX_2) := sym53c8xx.o +list-multi := sym53c8xx_2.o +sym53c8xx_2-objs := sym_fw.o sym_glue.o sym_hipd.o sym_malloc.o sym_misc.o sym_nvram.o +obj-$(CONFIG_SCSI_SYM53C8XX_2) := sym53c8xx_2.o EXTRA_CFLAGS += -I. -sym53c8xx.o: $(sym53c8xx-objs) - $(LD) -r -o $@ $(sym53c8xx-objs) +sym53c8xx_2.o: $(sym53c8xx_2-objs) + $(LD) -r -o $@ $(sym53c8xx_2-objs) include $(TOPDIR)/Rules.make Index: drivers/scsi/sym53c8xx_2/sym_hipd.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/scsi/sym53c8xx_2/sym_hipd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/scsi/sym53c8xx_2/sym_hipd.c 22 Jul 2004 19:50:10 -0000 1.1 +++ drivers/scsi/sym53c8xx_2/sym_hipd.c 4 Aug 2004 01:29:43 -0000 1.2 @@ -221,7 +221,7 @@ */ static void sym_soft_reset (hcb_p np) { - u_char istat; + u_char istat = 0; int i; if (!(np->features & FE_ISTAT1) || !(INB (nc_istat1) & SCRUN)) @@ -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) Index: drivers/serial/21285.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/21285.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/serial/21285.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/serial/21285.c 4 Aug 2004 01:29:43 -0000 1.2 @@ -5,7 +5,7 @@ * * Based on drivers/char/serial.c * - * $Id: 21285.c,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: 21285.c,v 1.2 2004/08/04 01:29:43 joff Exp $ */ #include #include @@ -32,11 +32,17 @@ #define BAUD_BASE (mem_fclk_21285/64) +#ifdef CONFIG_DEVFS_FS +#define SERIAL_21285_NAME "tts/FB%d" +#define SERIAL_21285_AUXNAME "cua/FB%d" +#else #define SERIAL_21285_NAME "ttyFB" +#define SERIAL_21285_AUXNAME "cuafb" +#endif + #define SERIAL_21285_MAJOR 204 #define SERIAL_21285_MINOR 4 -#define SERIAL_21285_AUXNAME "cuafb" #define SERIAL_21285_AUXMAJOR 205 #define SERIAL_21285_AUXMINOR 4 @@ -479,21 +485,14 @@ int baud = 9600; int bits = 8; int parity = 'n'; + int flow; int cflag = CREAD | HUPCL | CLOCAL; if (machine_is_personal_server()) baud = 57600; - if (options) { - char *s = options; - baud = simple_strtoul(options, NULL, 10); - while (*s >= '0' && *s <= '9') - s++; - if (*s) - parity = *s++; - if (*s) - bits = *s - '0'; - } + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); /* * Now construct a cflag setting. Index: drivers/serial/8250.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/8250.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/serial/8250.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/serial/8250.c 4 Aug 2004 01:29:43 -0000 1.2 @@ -12,7 +12,7 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * - * $Id: 8250.c,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: 8250.c,v 1.2 2004/08/04 01:29:43 joff Exp $ * * A note about mapbase / membase * Index: drivers/serial/8250.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/8250.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/serial/8250.h 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/serial/8250.h 4 Aug 2004 01:29:43 -0000 1.2 @@ -12,7 +12,7 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * - * $Id: 8250.h,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: 8250.h,v 1.2 2004/08/04 01:29:43 joff Exp $ */ #include Index: drivers/serial/8250_pci.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/8250_pci.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/serial/8250_pci.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/serial/8250_pci.c 4 Aug 2004 01:29:43 -0000 1.2 @@ -11,7 +11,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License. * - * $Id: 8250_pci.c,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: 8250_pci.c,v 1.2 2004/08/04 01:29:43 joff Exp $ */ #include #include Index: drivers/serial/8250_pnp.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/8250_pnp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/serial/8250_pnp.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/serial/8250_pnp.c 4 Aug 2004 01:29:43 -0000 1.2 @@ -11,7 +11,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License. * - * $Id: 8250_pnp.c,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: 8250_pnp.c,v 1.2 2004/08/04 01:29:43 joff Exp $ */ #include #include Index: drivers/serial/Config.in =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/Config.in,v retrieving revision 1.1 retrieving revision 1.10 diff -u -r1.1 -r1.10 --- drivers/serial/Config.in 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/serial/Config.in 15 Feb 2007 19:25:06 -0000 1.10 @@ -1,7 +1,7 @@ # # Serial device configuration # -# $Id: Config.in,v 1.1 2004/07/22 19:50:26 joff Exp $ +# $Id: Config.in,v 1.10 2007/02/15 19:25:06 eddie Exp $ # mainmenu_option next_comment comment 'Serial drivers' @@ -25,6 +25,17 @@ fi fi + tristate 'Core support for TS-UARTs' CONFIG_SERIAL_TSUART + tristate 'Support for TS-7260 TS-UARTs' CONFIG_SERIAL_TSUART7260 + tristate 'Support for TS-7300 TS-UARTs' CONFIG_SERIAL_TSUART73 + tristate 'Support for TS-940 TS-UARTs' CONFIG_SERIAL_TSUART940 + tristate 'Support for TS-BAT3 TS-UARTs' CONFIG_SERIAL_TSUART3BAT + tristate 'Support for TS-PAC4 TS-UARTs' CONFIG_SERIAL_TSUART4PAC + tristate 'Support for TS-7400 TS-UARTs' CONFIG_SERIAL_TSUART7400 + tristate 'Support for TS-RF2 TS-UARTs' CONFIG_SERIAL_TSUARTRF2 + tristate 'Support for BOC-EDWARDS TS-UARTs' CONFIG_SERIAL_TSUARTBOC + tristate 'Support for TS-733 TS-UARTs' CONFIG_SERIAL_TS733 + # EP93xx AMBA serial port if [ "$CONFIG_ARCH_EP9301" = "y" -o \ "$CONFIG_ARCH_EP9312" = "y" -o \ Index: drivers/serial/Makefile =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/Makefile,v retrieving revision 1.1 retrieving revision 1.11 diff -u -r1.1 -r1.11 --- drivers/serial/Makefile 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/serial/Makefile 15 Feb 2007 19:25:17 -0000 1.11 @@ -8,12 +8,12 @@ # Note 2! The CFLAGS definitions are now inherited from the # parent makes.. # -# $Id: Makefile,v 1.1 2004/07/22 19:50:26 joff Exp $ +# $Id: Makefile,v 1.11 2007/02/15 19:25:17 eddie Exp $ # O_TARGET := serial.o -export-objs := core.o 8250.o +export-objs := core.o 8250.o tsuart0.o obj-y := obj-m := obj-n := @@ -33,6 +33,16 @@ obj-$(CONFIG_SERIAL_UART00) += uart00.o obj-$(CONFIG_SERIAL_OMAHA) += omaha.o obj-$(CONFIG_SERIAL_AT91US3) += at91us3.o +obj-$(CONFIG_SERIAL_TSUART) += tsuart0.o +obj-$(CONFIG_SERIAL_TSUART73) += tsuart-73.o +obj-$(CONFIG_SERIAL_TSUART7260) += tsuart7260.o +obj-$(CONFIG_SERIAL_TSUART940) += tsuart940.o +obj-$(CONFIG_SERIAL_TSUART3BAT) += tsuart-bat3.o +obj-$(CONFIG_SERIAL_TSUART4PAC) += tsuart-pac4.o +obj-$(CONFIG_SERIAL_TSUART7400) += tsuart7400.o +obj-$(CONFIG_SERIAL_TSUARTRF2) += tsuart-rf.o +obj-$(CONFIG_SERIAL_TSUARTBOC) += tsuart-boc.o +obj-$(CONFIG_SERIAL_TS733) += tsuart-733.o include $(TOPDIR)/Rules.make Index: drivers/serial/amba.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/amba.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/serial/amba.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/serial/amba.c 4 Aug 2004 01:29:44 -0000 1.2 @@ -22,7 +22,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: amba.c,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: amba.c,v 1.2 2004/08/04 01:29:44 joff Exp $ * * This is a generic driver for ARM AMBA-type serial ports. They * have a lot of 16550-like features, but are not register compatable. Index: drivers/serial/anakin.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/anakin.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/serial/anakin.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/serial/anakin.c 4 Aug 2004 01:29:44 -0000 1.2 @@ -19,7 +19,7 @@ * SA_INTERRUPT. Works reliably now. No longer requires * changes to the serial_core API. * - * $Id: anakin.c,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: anakin.c,v 1.2 2004/08/04 01:29:44 joff Exp $ */ #include Index: drivers/serial/clps711x.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/clps711x.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/serial/clps711x.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/serial/clps711x.c 4 Aug 2004 01:29:44 -0000 1.2 @@ -22,7 +22,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: clps711x.c,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: clps711x.c,v 1.2 2004/08/04 01:29:44 joff Exp $ * */ #include Index: drivers/serial/core.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/core.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/serial/core.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/serial/core.c 4 Aug 2004 01:29:44 -0000 1.2 @@ -22,7 +22,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: core.c,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: core.c,v 1.2 2004/08/04 01:29:44 joff Exp $ * */ #include @@ -1117,6 +1117,10 @@ clear = ~val; break; } + + set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; + clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; + ret = uart_tiocmset(tty, filp, set, clear); } break; Index: drivers/serial/ep93xx_amba.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/ep93xx_amba.c,v retrieving revision 1.1 retrieving revision 1.22 diff -u -r1.1 -r1.22 --- drivers/serial/ep93xx_amba.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/serial/ep93xx_amba.c 8 Feb 2007 15:27:14 -0000 1.22 @@ -24,7 +24,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: ep93xx_amba.c,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: ep93xx_amba.c,v 1.22 2007/02/08 15:27:14 michael Exp $ * * The EP9312 serial ports are AMBA, but at different addresses from the * integrator. @@ -47,8 +47,11 @@ #include #include +#include "ts7412.h" #include +#define DELAY_TIMEX HZ + #if defined(CONFIG_SERIAL_AMBA_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) #define SUPPORT_SYSRQ #endif @@ -57,6 +60,8 @@ #include +#include + #if !defined(CONFIG_EP93XX_IRDA) #define UART_NR 3 #else @@ -72,9 +77,15 @@ #define CALLOUT_AMBA_MINOR 16 #define CALLOUT_AMBA_NR UART_NR +static struct timer_list timer = { .function = NULL }, timer0 = { .function = NULL }; static struct tty_driver normal, callout; static struct tty_struct *cs_amba_table[UART_NR]; static struct termios *cs_amba_termios[UART_NR], *cs_amba_termios_locked[UART_NR]; +static struct uart_amba_port amba_ports[]; + +static int ts7200_uart_get_fr (struct uart_port *) ; +static void ts7200_uart_set_mcr (struct uart_port *, unsigned ) ; + #ifdef SUPPORT_SYSRQ static struct console cs_amba_console; #endif @@ -86,10 +97,12 @@ */ #define UART_GET_INT_STATUS(p) ((readl((p)->membase + AMBA_UARTIIR)) & 0xff) #define UART_PUT_ICR(p, c) writel((c), (p)->membase + AMBA_UARTICR) -#define UART_GET_FR(p) ((readl((p)->membase + AMBA_UARTFR)) & 0xff) +//#define UART_GET_FR(p) ((readl((p)->membase + AMBA_UARTFR)) & 0xff) +#define UART_GET_FR(p) (ts7200_uart_get_fr(p)) #define UART_GET_CHAR(p) ((readl((p)->membase + AMBA_UARTDR)) & 0xff) #define UART_PUT_CHAR(p, c) writel((c), (p)->membase + AMBA_UARTDR) #define UART_GET_RSR(p) ((readl((p)->membase + AMBA_UARTRSR)) & 0xff) +#define UART_PUT_RSR(p,c) writel((c), (p)->membase + AMBA_UARTRSR) #define UART_GET_CR(p) ((readl((p)->membase + AMBA_UARTCR)) & 0xff) #define UART_PUT_CR(p,c) writel((c), (p)->membase + AMBA_UARTCR) #define UART_GET_LCRL(p) ((readl((p)->membase + AMBA_UARTLCR_L)) & 0xff) @@ -102,12 +115,14 @@ #define UART_TX_READY(s) (((s) & AMBA_UARTFR_TXFF) == 0) #define UART_TX_EMPTY(p) ((UART_GET_FR(p) & AMBA_UARTFR_TMSK) == 0) -#define UART_PUT_MCR(c, p) writel((c), (p)->membase + ((unsigned int)UART1MCR & 0xffff)) +#define UART_PUT_MCR(c, p) (ts7200_uart_set_mcr(p,c)) +//#define UART_PUT_MCR(c, p) writel((c), (p)->membase + ((unsigned int)UART1MCR & 0xffff)) + #define UART_CLEAR_ECR(p) writel( 0, (p)->membase + AMBA_UARTECR) #define UART_DUMMY_RSR_RX 256 #define UART_PORT_SIZE 64 - + /* * Our private driver data mappings. */ @@ -123,6 +138,87 @@ unsigned int old_status; }; +static int ts7200_auto485 (struct uart_port *port, unsigned int cmd, unsigned long * arg) +{ + int baud, cflag, mode; + int datalength ; //datalength + parenb + struct sbc_info *sbc; + + mode = *arg; + sbc = get_sbcinfo(); + if (!sbc->auto485) { + remove_sbcinfo(sbc); + printk("ep93xx_amba.c: sorry, this board does not support auto485\n"); + printk("check /proc/SBC/info for features supported\n"); + return -1; + } + + remove_sbcinfo(sbc); + + datalength = 8; + cflag = port->info->tty->termios->c_cflag ; + if (cflag & PARENB) + datalength++; + + if (cflag & CSTOPB) + datalength++; + + baud = tty_get_baud_rate (port->info->tty); + + switch (cmd) { + case TIOC_SBCC485: + if ((mode & AUTO485FD) || (mode & AUTO485HD)) { + printk("unsetting automode\n"); + outw(0, TS7XXX_RS485CTRL); + outw(0, TS7XXX_RS485DATA9); + } + break; + case TIOC_SBCS485: + if (mode & AUTO485FD) { + printk ("setting FULL duplex\n"); + outw(0x01, TS7XXX_RS485CTRL); + if (datalength > 8) + outw(0x01, TS7XXX_RS485DATA9); + } else if (mode & AUTO485HD) { + printk("setting HALF DUPLEX\n"); + switch (baud) { + case 9600: + outw(0x04, TS7XXX_RS485CTRL); + break; + case 19200: + outw(0x05, TS7XXX_RS485CTRL); + break; + case 57600: + outw(0x06, TS7XXX_RS485CTRL); + break; + case 115200: + outw(0x07, TS7XXX_RS485CTRL); + break; + default: + printk("auto485.c: %d Baud Rate is not supported for auto RS485 mode\n", baud); + return -1; + } + if (datalength > 8) + outw(0x01, TS7XXX_RS485DATA9); + } + break; + } + + return 0; +} +static int ep93xxamba_ioctls (struct uart_port *port, unsigned int cmd, unsigned long arg) +{ + switch (cmd) { + case TIOC_SBCC485: + case TIOC_SBCS485: + return ts7200_auto485 (port,cmd, (unsigned long *)arg); + break; + default: + return -ENOIOCTLCMD; + } + + return -ENOIOCTLCMD; +} static void csambauart_enable_clocks(struct uart_port *port) { @@ -294,12 +390,21 @@ rsr &= port->read_status_mask; - if (rsr & AMBA_UARTRSR_BE) + /* According to the EP9315 Users Guide, to clear + * any overrun, break, parity or framing error, you + * have to write to the UART RSR register. */ + if (rsr & AMBA_UARTRSR_BE){ *tty->flip.flag_buf_ptr = TTY_BREAK; - else if (rsr & AMBA_UARTRSR_PE) + UART_PUT_RSR(port, AMBA_UARTRSR_BE); + } + else if (rsr & AMBA_UARTRSR_PE){ *tty->flip.flag_buf_ptr = TTY_PARITY; - else if (rsr & AMBA_UARTRSR_FE) + UART_PUT_RSR(port, AMBA_UARTRSR_PE); + } + else if (rsr & AMBA_UARTRSR_FE){ *tty->flip.flag_buf_ptr = TTY_FRAME; + UART_PUT_RSR(port, AMBA_UARTRSR_FE); + } } if (uart_handle_sysrq_char(port, ch, regs)) @@ -320,6 +425,8 @@ *tty->flip.char_buf_ptr++ = 0; *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; tty->flip.count++; + + UART_PUT_RSR(port, AMBA_UARTRSR_OE); } ignore_char: status = UART_GET_FR(port); @@ -387,6 +494,18 @@ wake_up_interruptible(&uap->port.info->delta_msr_wait); } +static void csambauart_dcd_timer(unsigned long data) { + disable_irq(IRQ_UART1); + disable_irq(IRQ_UART2); + disable_irq(IRQ_UART3); + csambauart_modem_status((struct uart_port *)data); + enable_irq(IRQ_UART3); + enable_irq(IRQ_UART2); + enable_irq(IRQ_UART1); + timer.expires = jiffies + DELAY_TIMEX; + add_timer (&timer); +} + static void csambauart_int(int irq, void *dev_id, struct pt_regs *regs) { struct uart_port *port = dev_id; @@ -436,20 +555,23 @@ static void csambauart_set_mctrl(struct uart_port *port, unsigned int mctrl) { - struct uart_amba_port *uap = (struct uart_amba_port *)port; - unsigned int ctrl = 0; + struct uart_amba_port *uap = (struct uart_amba_port *)port; + int rts_mask = gpio ? 2 : uap->rts_mask; // override default non-existence of RTS/DTR when 7412 used. + int dtr_mask = gpio ? 1 : uap->dtr_mask; // yech! this is awful... + unsigned int ctrl = rts_mask | dtr_mask; - /* If there's no RTS and DTR for this UART, do nothing here */ - if( (uap->rts_mask == 0) && (uap->dtr_mask == 0) ) - return; + /* If there's no RTS and DTR for this UART, do nothing here */ + if( (rts_mask == 0) && (dtr_mask == 0) ) + return; - if ((mctrl & TIOCM_RTS) == 0) - ctrl |= uap->rts_mask; - - if ((mctrl & TIOCM_DTR) == 0) - ctrl |= uap->dtr_mask; - - UART_PUT_MCR(ctrl, port); + if ((mctrl & TIOCM_RTS) == 0) + ctrl &= ~rts_mask; + + if ((mctrl & TIOCM_DTR) == 0) { + ctrl &= ~dtr_mask; + } + + UART_PUT_MCR(ctrl, port); } static void csambauart_break_ctl(struct uart_port *port, int break_state) @@ -471,7 +593,7 @@ { struct uart_amba_port *uap = (struct uart_amba_port *)port; int retval; - + csambauart_enable_clocks(port); /* @@ -492,26 +614,36 @@ UART_PUT_CR(port, AMBA_UARTCR_UARTEN | AMBA_UARTCR_RIE | AMBA_UARTCR_RTIE); + if (timer.function == NULL && port == (struct uart_port *)amba_ports) { + timer.expires = jiffies + DELAY_TIMEX; + timer.data = (unsigned long )port; + timer.function = csambauart_dcd_timer; + add_timer (&timer); + } return 0; } static void csambauart_shutdown(struct uart_port *port) { - /* - * Free the interrupt - */ - free_irq(port->irq, port); - - /* - * disable all interrupts, disable the port - */ - UART_PUT_CR(port, 0); - - /* disable break condition and fifos */ - UART_PUT_LCRH(port, UART_GET_LCRH(port) & - ~(AMBA_UARTLCR_H_BRK | AMBA_UARTLCR_H_FEN)); - - csambauart_disable_clocks( port ); + if (port == (struct uart_port *)amba_ports) { + del_timer (&timer); + timer.function = NULL; + } + /* + * Free the interrupt + */ + free_irq(port->irq, port); + + /* + * disable all interrupts, disable the port + */ + UART_PUT_CR(port, 0); + + /* disable break condition and fifos */ + UART_PUT_LCRH(port, UART_GET_LCRH(port) & + ~(AMBA_UARTLCR_H_BRK | AMBA_UARTLCR_H_FEN)); + + csambauart_disable_clocks( port ); } static void csambauart_change_speed(struct uart_port *port, unsigned int cflag, unsigned int iflag, unsigned int quot) { @@ -686,6 +818,7 @@ .request_port = csambauart_request_port, .config_port = csambauart_config_port, .verify_port = csambauart_verify_port, + .ioctl = ep93xxamba_ioctls, }; static struct uart_amba_port amba_ports[UART_NR] = { @@ -742,6 +875,59 @@ } }; +/* + * We need to support DCD changes, however, our hardware doesn't + * have DCD hooked up the typical way on COM1, hence, the following + * hack + * -- L.A.Y, Technologic Systems 08/2004 + * + * The TS-7412 board requires that we use DIO pins for our COM1 and COM2 + * flow control signals. Added ts7200_uart_set_mcr and modified the + * existing ts7200_uart_get_fr to accomodate this. + * -- M 11/13/2006 + */ +static int ts7200_uart_get_fr (struct uart_port *port) { + volatile unsigned long uart_fr ; + unsigned short dcd_status; + int port1 = (port->membase != amba_ports[0].port.membase) ? 1 : 0; + + if (gpio) { + uart_fr = (readl(port->membase + AMBA_UARTFR) ) & 0xff ; + uart_fr |= AMBA_UARTFR_DSR; // NOT TIOCM_DSR!!! + if (mdmctrl1_dcd_get(port1)) { + uart_fr |= AMBA_UARTFR_DCD; // NOT TIOCM_CAR!!! + } + if (mdmctrl1_cts_get(port1)) { + uart_fr |= AMBA_UARTFR_CTS; // NOT TIOCM_CTS !!! + } + return uart_fr; + } + + if (port1 == 1) + return ( (readl(port->membase + AMBA_UARTFR) ) & 0xff ); + + uart_fr = (readl(port->membase + AMBA_UARTFR) ) & 0xff ; + dcd_status = (inb(TS7XXX_IO8_BASE + 0x00800000)) & 0x40; + + if (dcd_status) // dcd_status is active low + uart_fr &= ~AMBA_UARTFR_DCD; + else + uart_fr |= AMBA_UARTFR_DCD; + + return uart_fr; +} + +static void ts7200_uart_set_mcr (struct uart_port *p, unsigned c) { + int port1 = (p->membase != amba_ports[0].port.membase) ? 1 : 0; + + if (gpio) { + mdmctrl1_dtr_set(port1,((c & 1) /* & TIOCM_DTR */)?1:0); + mdmctrl1_rts_set(port1,((c & 2) /*& TIOCM_RTS */)?1:0); + } else { + writel((c), (p)->membase + ((unsigned int)UART1MCR & 0xffff)); + } +} + #ifdef CONFIG_SERIAL_AMBA_CONSOLE static void csambauart_console_write(struct console *co, const char *s, unsigned int count) @@ -869,7 +1055,13 @@ void __init ambauart_console_init(void) { - register_console(&cs_amba_console); +#ifdef TS7412_UNSAFE_DETECTION + timer0.expires = jiffies + HZ; + timer0.data = 0; + timer0.function = ts7412_detect_test; + add_timer (&timer0); +#endif + register_console(&cs_amba_console); } #define AMBA_CONSOLE &cs_amba_console @@ -930,3 +1122,168 @@ MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd/Cirrus Logic, Inc."); MODULE_DESCRIPTION("EP9312 ARM AMBA serial port driver"); MODULE_LICENSE("GPL"); + +/* + All our TS-7412 specific stuff goes here. + */ +char *gpio = 0; + +static void gpio_dir_set(int pin,int output) { + if (!gpio) { + return; + } + if (pin > 7) { + pin -= 8; + if (output) { + gpio[1] |= (1 << pin); + } else { + gpio[1] &= ~(1 << pin); + } + } else { + if (output) { + gpio[0] |= (1 << pin); + } else { + gpio[0] &= ~(1 << pin); + } + } +} + +static int gpio_data_get(int pin) { + if (!gpio) { + return 0; + } + if (pin > 7) { + pin -= 8; + return (gpio[3] >> pin) & 1; + } else { + return (gpio[2] >> pin) & 1; + } +} + +static void gpio_data_set(int pin,int value) { + if (!gpio) { + return; + } + if (pin > 7) { + pin -= 8; + if (value) { + gpio[3] |= (1 << pin); + } else { + gpio[3] &= ~(1 << pin); + } + } else { + if (value) { + gpio[2] |= (1 << pin); + } else { + gpio[2] &= ~(1 << pin); + } + } +} + +void mdmctrl_rts_set(int val) { + gpio_dir_set(10,1); + gpio_data_set(10,val?0:1); + //printk("RTS3=%d\n",val?0:1); +} +void mdmctrl_dtr_set(int val) { + gpio_dir_set(9,1); + gpio_data_set(9,val?0:1); + //printk("DTR3=%d\n",val?0:1); +} +int mdmctrl_cts_get(void) { + gpio_dir_set(5,1); + gpio_data_set(5,1); + //printk("CTS3==%d\n",gpio_data_get(2)?0:1); + return gpio_data_get(2)?0:1; +} +int mdmctrl_dcd_get(void) { + gpio_dir_set(5,1); + gpio_data_set(5,1); + //printk("DCD3==%d\n",gpio_data_get(3)?0:1); + return gpio_data_get(3)?0:1; +} + +void mdmctrl1_rts_set(int port,int val) { + gpio_dir_set(port?14:12,1); + gpio_data_set(port?14:12,val?0:1); + //printk("RTS1 %d=%d\n",port,val?0:1); +} +void mdmctrl1_dtr_set(int port,int val) { + gpio_dir_set(port?13:11,1); + gpio_data_set(port?13:11,val?0:1); + //printk("DTR1 %d=%d\n",port,val?0:1); +} +int mdmctrl1_cts_get(int port) { + int ret; + + gpio_dir_set(5,1); + gpio_data_set(5,port?0:1); + ret = gpio_data_get(0)?0:1; + //printk("CTS1 %d==%d\n",port,ret); + return ret; +} +int mdmctrl1_dcd_get(int port) { + int ret; + + gpio_dir_set(5,1); + gpio_data_set(5,port?0:1); + ret = gpio_data_get(1)?0:1; + //printk("DCD1 %d==%d\n",port,ret); + return ret; +} + +int ts7412_detect_test(unsigned long data) { + char *ctrl = 0; + if (gpio == 0) { + gpio = (char *)__ioremap(0x12c00000,4096,0); + if (gpio == 0) { + printk(KERN_ERR "tsuart7400: cannot io map gpio\n"); + return 0; + } + gpio_dir_set(5,1); + gpio_dir_set(6,1); + gpio_dir_set(14,1); + gpio_dir_set(3,0); + gpio_data_set(5,0); // SEL + gpio_data_set(6,0); // RD_257A# + gpio_data_set(14,0); // RTS1# + if (gpio_data_get(3) != 0) { + //printk("7412 test failed at 1\n"); + __iounmap(gpio); + gpio = 0; + goto detect_7412_done; + } + gpio_data_set(14,1); // RTS1# + if (gpio_data_get(3) != 1) { + //printk("7412 test failed at 2\n"); + __iounmap(gpio); + gpio = 0; + goto detect_7412_done; + } + gpio_data_set(5,1); // RD_257A# + gpio_data_set(14,gpio_data_get(3)?0:1); + if (gpio_data_get(14) == gpio_data_get(3)) { + //printk("7412 test failed at 3.1\n"); + __iounmap(gpio); + gpio = 0; + goto detect_7412_done; + } + } + ctrl = (char *)__ioremap(0x12000000,4096,0); + if (ctrl == 0) { + printk(KERN_ERR "ts7412 detection: cannot io map ctrl\n"); + __iounmap(gpio); + gpio = 0; + return 0; + } + *ctrl |= 1; + // printk("CTRL=%02X\n",*ctrl); + __iounmap(ctrl); + detect_7412_done: + if (gpio) { + printk("EP93XX_AMBA detected a TS-7400 with TS-7412 present\n"); + } else { + //printk("EP93XX_AMBA did NOT detect a TS-7412.\n"); + } + return (gpio != 0); +} Index: drivers/serial/omaha.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/omaha.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/serial/omaha.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/serial/omaha.c 4 Aug 2004 01:29:44 -0000 1.2 @@ -22,7 +22,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: omaha.c,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: omaha.c,v 1.2 2004/08/04 01:29:44 joff Exp $ * * This is a generic driver for ARM AMBA-type serial ports. They * have a lot of 16550-like features, but are not register compatable. Index: drivers/serial/sa1100.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/sa1100.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/serial/sa1100.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/serial/sa1100.c 4 Aug 2004 01:29:44 -0000 1.2 @@ -21,7 +21,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: sa1100.c,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: sa1100.c,v 1.2 2004/08/04 01:29:44 joff Exp $ * */ #include Index: drivers/serial/ts7412.h =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/ts7412.h,v retrieving revision 1.1 retrieving revision 1.5 diff -u -r1.1 -r1.5 --- drivers/serial/ts7412.h 5 Dec 2006 00:14:05 -0000 1.1 +++ drivers/serial/ts7412.h 31 Jan 2007 22:38:09 -0000 1.5 @@ -1,127 +1,18 @@ -/* - I hate putting code in .h files, but in this case it seemed to make sense, - so as to avoid code duplication between the tsuart7400.c driver and the - ep93xx_amba.c driver. I definitely didn't want to create a new module - dependency just for these functions... - --M - */ -#ifdef TS7412_SLAVE extern char *gpio; + +int ts7412_detect_test(unsigned long); + +void mdmctrl_rts_set(int val); +void mdmctrl_dtr_set(int val); +int mdmctrl_cts_get(void); +int mdmctrl_dcd_get(void); + void mdmctrl1_rts_set(int port,int val); void mdmctrl1_dtr_set(int port,int val); int mdmctrl1_cts_get(int port); int mdmctrl1_dcd_get(int port); -#define _TS7412_H -#endif - -#ifndef _TS7412_H -#define _TS7412_H -char *gpio = 0; - -static void gpio_dir_set(int pin,int output) { - if (!gpio) { - return; - } - if (pin > 7) { - pin -= 8; - if (output) { - gpio[1] |= (1 << pin); - } else { - gpio[1] &= ~(1 << pin); - } - } else { - if (output) { - gpio[0] |= (1 << pin); - } else { - gpio[0] &= ~(1 << pin); - } - } -} - -static int gpio_data_get(int pin) { - if (!gpio) { - return 0; - } - if (pin > 7) { - pin -= 8; - return (gpio[3] >> pin) & 1; - } else { - return (gpio[2] >> pin) & 1; - } -} - -static void gpio_data_set(int pin,int value) { - if (!gpio) { - return; - } - if (pin > 7) { - pin -= 8; - if (value) { - gpio[3] |= (1 << pin); - } else { - gpio[3] &= ~(1 << pin); - } - } else { - if (value) { - gpio[2] |= (1 << pin); - } else { - gpio[2] &= ~(1 << pin); - } - } -} - -void mdmctrl_rts_set(int val) { - gpio_dir_set(10,1); - gpio_data_set(10,val?0:1); - //printk("RTS3=%d\n",val?0:1); -} -void mdmctrl_dtr_set(int val) { - gpio_dir_set(9,1); - gpio_data_set(9,val?0:1); - //printk("DTR3=%d\n",val?0:1); -} -int mdmctrl_cts_get(void) { - gpio_dir_set(5,1); - gpio_data_set(5,1); - //printk("CTS3==%d\n",gpio_data_get(2)?0:1); - return gpio_data_get(2)?0:1; -} -int mdmctrl_dcd_get(void) { - gpio_dir_set(5,1); - gpio_data_set(5,1); - //printk("DCD3==%d\n",gpio_data_get(3)?0:1); - return gpio_data_get(3)?0:1; -} - -void mdmctrl1_rts_set(int port,int val) { - gpio_dir_set(port?14:12,1); - gpio_data_set(port?14:12,val?0:1); - printk("RTS1 %d=%d\n",port,val?0:1); -} -void mdmctrl1_dtr_set(int port,int val) { - gpio_dir_set(port?13:11,1); - gpio_data_set(port?13:11,val?0:1); - printk("DTR1 %d=%d\n",port,val?0:1); -} -int mdmctrl1_cts_get(int port) { - int ret; - - gpio_dir_set(5,1); - gpio_data_set(5,port?0:1); - ret = gpio_data_get(0)?0:1; - printk("CTS1 %d==%d\n",port,ret); - return ret; -} -int mdmctrl1_dcd_get(int port) { - int ret; - - gpio_dir_set(5,1); - gpio_data_set(5,port?0:1); - ret = gpio_data_get(1)?0:1; - printk("DCD1 %d==%d\n",port,ret); - return ret; -} +/* void led1(unsigned *test,int on) { if (on) { test[0] = test[0] | 1; @@ -137,6 +28,8 @@ test[0] = test[0] & 0xFFFFFFFD; } } +*/ + /* unsigned *test = __ioremap(0x80840020,4096,0); @@ -161,54 +54,3 @@ return 0; */ -static char * ts7412_detect_test(void) { - char *ctrl = 0; - if (gpio == 0) { - gpio = (char *)__ioremap(0x12c00000,4096,0); - if (gpio == 0) { - printk(KERN_ERR "tsuart7400: cannot io map gpio\n"); - return 0; - } - gpio_dir_set(5,1); - gpio_dir_set(6,1); - gpio_dir_set(14,1); - gpio_dir_set(3,0); - gpio_data_set(5,0); // SEL - gpio_data_set(6,0); // RD_257A# - gpio_data_set(14,0); // RTS1# - if (gpio_data_get(3) != 0) { - //printk("7412 test failed at 1\n"); - __iounmap(gpio); - gpio = 0; - return 0; - } - gpio_data_set(14,1); // RTS1# - if (gpio_data_get(3) != 1) { - //printk("7412 test failed at 2\n"); - __iounmap(gpio); - gpio = 0; - return 0; - } - gpio_data_set(5,1); // RD_257A# - gpio_data_set(14,gpio_data_get(3)?0:1); - if (gpio_data_get(14) == gpio_data_get(3)) { - //printk("7412 test failed at 3.1\n"); - __iounmap(gpio); - gpio = 0; - return 0; - } - } - ctrl = (char *)__ioremap(0x12000000,4096,0); - if (ctrl == 0) { - printk(KERN_ERR "tsuart7400: cannot io map ctrl\n"); - __iounmap(gpio); - gpio = 0; - return 0; - } - *ctrl |= 1; - // printk("CTRL=%02X\n",*ctrl); - __iounmap(ctrl); - return gpio; -} -#endif - Index: drivers/serial/tsuart-73.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/tsuart-73.c,v retrieving revision 1.1 retrieving revision 1.5 diff -u -r1.1 -r1.5 --- drivers/serial/tsuart-73.c 16 May 2006 19:11:01 -0000 1.1 +++ drivers/serial/tsuart-73.c 11 Jan 2007 00:44:41 -0000 1.5 @@ -35,6 +35,8 @@ struct uart_driver *dr8=0,*dr9=0; +#define BOARD_ID_7300 0x7300 + static int tryInitPort(int base) { struct tsuart_port *ts1,*ts2; @@ -53,6 +55,9 @@ ts1->portStatus = &ts1->pstatus; ts1->pstatus = 0; ts1->u.irq = 40; + ts1->mdmctrl = 0; + ts1->localStatus |= PORT_STATUS_SHIRQ; + ts1->boardId = BOARD_ID_7300; ts2 = kmalloc(sizeof(struct tsuart_port),GFP_KERNEL); if (!ts2) { @@ -68,8 +73,12 @@ ts2->debugFlags = portDebug; ts2->u.mapbase = 0x72000000 + base; ts2->portStatus = &ts1->pstatus; + ts2->pstatus |= PORT_STATUS_TXMSB; ts2->u.irq = 40; - // printk("registering %p,%p\n",ts1,ts2); + ts2->mdmctrl = 0; + ts2->localStatus |= PORT_STATUS_SHIRQ; + ts2->boardId = BOARD_ID_7300; + printk("registering %p,%p\n",ts1,ts2); if (tsuart_register_port(dr8,ts1) == 0) { // return 1; } Index: drivers/serial/tsuart-733.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/tsuart-733.c,v retrieving revision 1.1 retrieving revision 1.6 diff -u -r1.1 -r1.6 --- drivers/serial/tsuart-733.c 13 Feb 2007 18:09:37 -0000 1.1 +++ drivers/serial/tsuart-733.c 13 Jul 2007 15:34:23 -0000 1.6 @@ -63,22 +63,21 @@ } init_tsuart_port(ts2); ts2->u.iotype = SERIAL_IO_MEM; - ts2->get = tsuartGetMEM16; - ts2->put = tsuartPutMEM16; + ts2->get = tsuartGetMEM16_9; + ts2->put = tsuartPutMEM16_9; ts2->debugFlags = portDebug; ts2->u.mapbase = 0x72000400+i; ts2->boardId = BOARD_ID_733; ts2->u.irq = 40; ts2->mdmctrl = 0; ts2->localStatus |= PORT_STATUS_SHIRQ; - if (tsuart_register_port(dr8,ts1) == 0) { - //return 1; + //return 0; } if (tsuart_register_port(dr9,ts2) == 0) { - //return 1; + //return 0; } - return 0; + return 1; } #define TTY_NAME8 "ttyT8Sv" @@ -95,13 +94,14 @@ static int __init tsuart_init(void) { + int ports = 0; if (!tty) { tty = TTY_NAME8; } if (!cua) { cua = CUA_NAME8; } - printk("TS-UART/736 assuming TS-733 board\n"); + printk("TS-UART/733 assuming TS-733 board\n"); dr8 = kmalloc(sizeof(struct uart_driver),GFP_KERNEL); if (!dr8) { printk("Unable to allocate memory for tsuart port\n"); @@ -113,7 +113,7 @@ printk("Unable to allocate memory for tsuart port\n"); return 0; } - if (!tsuart_configure_driver(dr8,234,122,tty,cua,3)) { + if (!tsuart_configure_driver(dr8,234,122,tty,cua,3)) { kfree(dr8); kfree(dr9); return 0; @@ -125,15 +125,17 @@ } if (tryInitPort(0)) { - return 0; + ports++; } if (tryInitPort(4)) { - return 0; + ports++; } if (tryInitPort(8)) { - return 0; + ports++; } - return -1; + printk("TS-UART/733 found %d ports\n",ports); + if(ports == 0) return -1; + else return 0; } static void __exit tsuart_exit(void) Index: drivers/serial/tsuart-734.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/tsuart-734.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/serial/tsuart-734.c 9 May 2007 16:59:06 -0000 1.1 +++ drivers/serial/tsuart-734.c 10 May 2007 00:08:07 -0000 1.2 @@ -51,6 +51,8 @@ ts1->put = tsuartPutMEM16; ts1->debugFlags = portDebug; ts1->u.mapbase = 0x72000400+i*4; + ts1->portStatus = &ts1->pstatus; + ts1->pstatus = 0; ts1->boardId = BOARD_ID_734; ts1->u.irq = 40; ts1->mdmctrl = 0; @@ -62,11 +64,15 @@ return 0; } init_tsuart_port(ts2); + ts2->rxsize = 2; + ts2->dataMask = 0x1FF; ts2->u.iotype = SERIAL_IO_MEM; ts2->get = tsuartGetMEM16_9; ts2->put = tsuartPutMEM16_9; ts2->debugFlags = portDebug; ts2->u.mapbase = 0x72000400+i*4; + ts2->portStatus = &ts1->pstatus; + ts2->pstatus |= PORT_STATUS_TXMSB; ts2->boardId = BOARD_ID_734; ts2->u.irq = 40; ts2->mdmctrl = 0; Index: drivers/serial/tsuart-736.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/tsuart-736.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/serial/tsuart-736.c 7 Dec 2006 23:59:01 -0000 1.1 +++ drivers/serial/tsuart-736.c 8 Dec 2006 21:24:37 -0000 1.3 @@ -45,6 +45,8 @@ port = (((int)ts->u.mapbase) - 0x72000400)/4; if (port < 8) { mask = 1 << port; + } else if (port < 16) { + mask = 1 << (port-8); } if (mctrl & 0x80000000) { // set if ((mctrl & TIOCM_DTR)) { @@ -57,7 +59,7 @@ } } } else { // get - if (*ctrlbits & mask) { + if (*ctrlbits & (mask<<8)) { ctrl |= TIOCM_CD; } } @@ -113,7 +115,6 @@ } if (!ctrlbits) { ctrlbits = (volatile unsigned short *)((int) __ioremap(0x72000000, 4096,0) + 0x460); - printk("DEBUG: %p\n",ctrlbits); } //ctrlbits = 0; return 1; @@ -156,17 +157,17 @@ printk("Unable to allocate memory for tsuart port\n"); return 0; } - if (!tsuart_configure_driver(dr8,234,64,tty,cua,24)) { + if (!tsuart_configure_driver(dr8,234,128,tty,cua,24)) { kfree(dr8); kfree(dr9); return 0; } - if (!tsuart_configure_driver(dr9,234,72,tty9,cua9,24)) { + if (!tsuart_configure_driver(dr9,234,152,tty9,cua9,24)) { kfree(dr8); kfree(dr9); return 0; } - for (i=0;i<=24*4;i+=4) { + for (i=0;i<24*4;i+=4) { if (tryInitPort(i)) { ports++; } Index: drivers/serial/tsuart-bat3.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/tsuart-bat3.c,v retrieving revision 1.1 retrieving revision 1.4 diff -u -r1.1 -r1.4 --- drivers/serial/tsuart-bat3.c 16 May 2006 19:12:38 -0000 1.1 +++ drivers/serial/tsuart-bat3.c 4 Oct 2006 15:14:28 -0000 1.4 @@ -33,6 +33,10 @@ #include #include "tsuart.h" +#define BOARD_ID_BAT3 0xBA13 + +struct uart_driver *dr3=0; + static int tryInitPort(int iobase) { struct tsuart_port *ts; unsigned val; @@ -48,21 +52,22 @@ ts->put = tsuartPutIO8; ts->debugFlags = portDebug; ts->u.iobase = TS7XXX_IO8_BASE + TS7XXX_ISAIO + iobase; - + ts->boardId = BOARD_ID_BAT3; + ts->mdmctrl = 0; val = tsuartGetIO8(ts,0); if (val == 0x28) { val = tsuartGetIO8(ts,1); if ((val & 0x80) == 0x80) { ts->u.irq = 33; if ((val & 0x40) == 0x40) { - // IRQ6 with sharing... + ts->localStatus |= PORT_STATUS_SHIRQ; // IRQ6 with sharing... } } else { ts->u.irq = 32; // IRQ5... is this right? } ts->u.iobase += 2; // point to STAT register printk("TS-UART/BAT3 found at port 0x%04X\n",iobase); - if (tsuart_register_port(0,ts) == 0) { + if (tsuart_register_port(dr3,ts) == 0) { return 1; } } @@ -73,6 +78,16 @@ { int ports=0; + dr3 = kmalloc(sizeof(struct uart_driver),GFP_KERNEL); + if (!dr3) { + printk("Unable to allocate memory for tsuart port\n"); + return 0; + } + if (!tsuart_configure_driver(dr3,234,95,"ttyT3S","cuat3s",4)) { + kfree(dr3); + return 0; + } + if (tryInitPort(0x100)) { ports++; } Index: drivers/serial/tsuart-boc.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/tsuart-boc.c,v retrieving revision 1.1 retrieving revision 1.5 diff -u -r1.1 -r1.5 --- drivers/serial/tsuart-boc.c 1 Feb 2007 23:43:41 -0000 1.1 +++ drivers/serial/tsuart-boc.c 6 Feb 2007 16:37:51 -0000 1.5 @@ -51,14 +51,10 @@ ts->debugFlags = portDebug; ts->u.iobase = TS7XXX_IO8_BASE + TS7XXX_ISAIO + iobase; ts->boardId = BOARD_ID_BOC; - val = tsuartGetIO8(ts,0); - if (val == 0x8e) { - val = tsuartGetIO8(ts,1); - ts->u.irq = 33; - printk("TS-UART/BOC found at port 0x%04X\n",iobase); - if (tsuart_register_port(0,ts) == 0) { - return 1; - } + ts->u.irq = 40; + printk("TS-UART/BOC found at port 0x%04X\n",iobase); + if (tsuart_register_port(0,ts) == 0) { + return 1; } return 0; } @@ -66,6 +62,13 @@ static int __init tsuart_init(void) { int ports=0; + struct tsuart_port *ts; + + //Ensure we clear any IRQs before registering an IRQ + ts->u.iobase = TS7XXX_IO8_BASE + TS7XXX_ISAIO + 0x134; + while (bit_DR(tsuartGetIO8(ts,0))) tsuartGetIO8(ts,1); + ts->u.iobase = TS7XXX_IO8_BASE + TS7XXX_ISAIO + 0x136; + while (bit_DR(tsuartGetIO8(ts,0))) tsuartGetIO8(ts,1); if (tryInitPort(0x134)) { ports++; Index: drivers/serial/tsuart-corestreet.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/tsuart-corestreet.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/serial/tsuart-corestreet.c 1 Sep 2007 00:45:35 -0000 1.1 +++ drivers/serial/tsuart-corestreet.c 11 Jan 2008 00:14:38 -0000 1.3 @@ -98,22 +98,6 @@ printk(KERN_ERR "tsuart-corestreet: cannot map adrs memory\n"); return -ENOMEM; } - - init_tsuart_port(ts); - ts->u.iotype = SERIAL_IO_MEM; - ts->get = tsuartGetCST8; - ts->put = tsuartPutCST8; - ts->mdmctrl = 0; - ts->debugFlags = portDebug; - ts->u.mapbase = 0x60c00000; - ts->u.irq = 32; // 33; // UNKNOWN, FIXME 32,33,40 - ts->localStatus |= PORT_STATUS_SHIRQ; - ts->boardId = BOARD_ID_CORESTREET; - - if (tsuart_register_port(0,ts) != 0) { - return 0; - } - // now do magic knock sequence to enable board *(adrs_reg-2) = 0xff; *(adrs_reg-1) = 0x17; @@ -129,6 +113,32 @@ *tmp = 8; //__iounmap(tmp); } + { + volatile unsigned long *tmp; + + tmp = ((unsigned long *) __ioremap(0x80080000, 4096,0))+ 0x07; + if (tmp == (unsigned long *)0x80080007) { + printk(KERN_ERR "tsuart-corestreet: cannot map 0x8008_0007\n"); + return -ENOMEM; + } + *tmp = 0xffef; + //__iounmap(tmp); + } + + init_tsuart_port(ts); + ts->u.iotype = SERIAL_IO_MEM; + ts->get = tsuartGetCST8; + ts->put = tsuartPutCST8; + ts->mdmctrl = 0; + ts->debugFlags = portDebug; + ts->u.mapbase = 0x70c00000; + ts->u.irq = 32; // 33; // UNKNOWN, FIXME 32,33,40 + ts->localStatus |= PORT_STATUS_SHIRQ; + ts->boardId = BOARD_ID_CORESTREET; + + if (tsuart_register_port(0,ts) != 0) { + return 0; + } return 1; } Index: drivers/serial/tsuart-dmx.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/tsuart-dmx.c,v retrieving revision 1.1 retrieving revision 1.5 diff -u -r1.1 -r1.5 --- drivers/serial/tsuart-dmx.c 30 Jun 2007 01:10:26 -0000 1.1 +++ drivers/serial/tsuart-dmx.c 23 Oct 2008 17:59:03 -0000 1.5 @@ -1,7 +1,7 @@ /* - * linux/drivers/serial/tsuart-bat3.c + * linux/drivers/serial/tsuart-dmx.c * - * TS-UART loader for Technologic Systems MARCTEL TS-7300 bitstream + * TS-UART loader for Technologic Systems DMX TS-7300 bitstream * * (c) 2007 Technologic Systems * @@ -44,7 +44,6 @@ unsigned val0 = *((volatile unsigned short *)port->u.membase + 0); unsigned val = *((volatile unsigned short *)port->u.membase + offset); -printk("Get %X, Got %X\n",val0,val); if (val0 & (1<<11)) { port->localStatus |= PORT_STATUS_DMXBRK; } @@ -59,16 +58,23 @@ } } +static inline int bit_TRE(unsigned short reg_value) { + return (reg_value & 0x1000) == 0x1000; +} + void tsuartPutMEM16_9DMX(struct tsuart_port *port,int offset,unsigned value) { - if (offset == 1 && port->pstatus & PORT_STATUS_TXMSB && value & (1 << 3)) { -printk("Sending DMX break\n"); + int i=0; + + if (offset == 1 && (port->pstatus & PORT_STATUS_TXMSB) && (value & (1 << 3))) { + // wait for TRE to tell us the transmitter is idle + while (!bit_TRE(*((volatile unsigned short *)port->u.membase)) && i < 1000000) i++; + if (i >= 1000000) printk("Timeout waiting for TRE!\n"); // send DMX break *((volatile unsigned short *)port->u.membase + 0) |= (1<<10); udelay(92); *((volatile unsigned short *)port->u.membase + 0) &= ~(1<<10); udelay(12); value &= ~(1 << 3); -printk("Sent DMX break\n"); } tsuartPutMEM16_9(port,offset,value); } @@ -112,7 +118,7 @@ } init_tsuart_port(ts2); ts2->rxsize = 2; - ts2->dataMask = 0x1FF; + ts2->dataMask = 0x9FF; ts2->u.iotype = SERIAL_IO_MEM; ts2->get = tsuartGetMEM16_9DMX; ts2->put = tsuartPutMEM16_9DMX; @@ -161,11 +167,11 @@ cr = (volatile unsigned short *)((int) __ioremap(0x72000000, 4096,0) + 0x422); if (*cr != 0x8bb7) { printk("TS-UART/DMX did not find DMX board\n"); - __iounmap(cr); + __iounmap((void *)cr); return -1; } else { printk("TS-UART/DMX found DMX board\n"); - __iounmap(cr); + __iounmap((void *)cr); } dr8 = kmalloc(sizeof(struct uart_driver),GFP_KERNEL); Index: drivers/serial/tsuart-marctel.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/tsuart-marctel.c,v retrieving revision 1.1 retrieving revision 1.4 diff -u -r1.1 -r1.4 --- drivers/serial/tsuart-marctel.c 11 May 2007 20:24:11 -0000 1.1 +++ drivers/serial/tsuart-marctel.c 14 Sep 2007 23:54:43 -0000 1.4 @@ -37,6 +37,46 @@ #define BOARD_ID_MARCTEL 0x735 +unsigned tsuartGetMEM16_BRK(struct tsuart_port *port,int offset) { + unsigned value; + static int inbreak = 0; + + value = *((volatile unsigned short *)port->u.membase + offset); + if (offset == 0) { + if (bit_RXBRK(value) && !inbreak) { + inbreak = 1; + port->u.icount.brk++; + uart_handle_break(&port->u); + if (port->u.info->tty) { + *(port->u.info->tty->flip.flag_buf_ptr) = TTY_BREAK; + port->u.info->tty->flip.flag_buf_ptr++; + port->u.info->tty->flip.char_buf_ptr++; + port->u.info->tty->flip.count++; + } + // if (uart_handle_sysrq_char(port, ch, regs)) { + // } else { + //} + tty_flip_buffer_push(port->u.info->tty); + } + } else { + inbreak = 0; + } + return value; +} + +unsigned tsuartGetMEM16_9_BRK(struct tsuart_port *port,int offset) { + unsigned val = *((volatile unsigned short *)port->u.membase + offset); + + if (offset == 1) { + return val & 0x1FF; + } else if (offset == 0) { + if (bit_RXBRK(val)) { + uart_handle_break(&port->u); + } + } + return val; +} + static int tryInitPort(int i) { struct tsuart_port *ts1,*ts2; @@ -47,7 +87,7 @@ } init_tsuart_port(ts1); ts1->u.iotype = SERIAL_IO_MEM; - ts1->get = tsuartGetMEM16; + ts1->get = tsuartGetMEM16_BRK; ts1->put = tsuartPutMEM16; ts1->debugFlags = portDebug; ts1->u.mapbase = 0x72000400+i*4; @@ -67,7 +107,7 @@ ts2->rxsize = 2; ts2->dataMask = 0x1FF; ts2->u.iotype = SERIAL_IO_MEM; - ts2->get = tsuartGetMEM16_9; + ts2->get = tsuartGetMEM16_9_BRK; ts2->put = tsuartPutMEM16_9; ts2->debugFlags = portDebug; ts2->u.mapbase = 0x72000400+i*4; Index: drivers/serial/tsuart-mwarm.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/tsuart-mwarm.c,v retrieving revision 1.1 retrieving revision 1.4 diff -u -r1.1 -r1.4 --- drivers/serial/tsuart-mwarm.c 26 Mar 2007 20:02:08 -0000 1.1 +++ drivers/serial/tsuart-mwarm.c 7 May 2008 17:51:50 -0000 1.4 @@ -33,29 +33,35 @@ #include #include "tsuart.h" -#define TS_MODEL_MWARM 5 +#define TS_MODEL_MWARM 2 #define BOARD_ID_MWARM 0x7261 +#define DEBUG_INTERFACE 8 static inline int get_status(void) { // return 0; return (inb(TS7XXX_IO8_BASE + 0x800000)); } -static inline void set_status(int status) { -// return; - outb(status,TS7XXX_IO8_BASE + 0x800000); +static inline void set_status(int i) { + if (i) { + outb(8|(inb(TS7XXX_IO8_BASE + 0x2000000)),TS7XXX_IO8_BASE + 0x2000000); + } else { + outb(~8&(inb(TS7XXX_IO8_BASE + 0x2000000)),TS7XXX_IO8_BASE + 0x2000000); + } } static int mdmctrl(struct tsuart_port *ts,int mctrl) { - int status = get_status(); + int status; int ret = 0; if (mctrl & 0x80000000) { if (mctrl & TIOCM_DTR) { - status |= (1 << 2); // R/W - set_status(status); + set_status(0); + } else { + set_status(1); } } + status = get_status(); if (status & (1 << 2)) { ret |= TIOCM_DTR; } Index: drivers/serial/tsuart-pac4.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/tsuart-pac4.c,v retrieving revision 1.1 retrieving revision 1.6 diff -u -r1.1 -r1.6 --- drivers/serial/tsuart-pac4.c 26 May 2006 23:26:03 -0000 1.1 +++ drivers/serial/tsuart-pac4.c 3 Mar 2009 00:45:53 -0000 1.6 @@ -1,5 +1,5 @@ /* - * linux/drivers/serial/tsuart7260.c + * linux/drivers/serial/tsuart-pac4.c * * TS-UART loader for Technologic Systems TS-7260 * @@ -47,20 +47,41 @@ its for us. */ unsigned tsuartGetMUX8(struct tsuart_port *port,int offset) { + unsigned val = -1; + int src; /* if reading the STAT register, mask out the flow control bit since its really telling us whether data is for us or not. use this bit to instead condition data ready, so we know whether or not data is for us. */ + if (offset == 1) { // DATA + src = bit_CTS(*(volatile unsigned char *)port->u.membase); + if (src == port->u.line) { + return -1; + } + + val = *((volatile unsigned char *)port->u.membase + offset); + } else if (offset == 0) { // STAT + val = *((volatile unsigned char *)port->u.membase + offset); + + if (bit_CTS(val) == port->u.line) { + val = val & 0xFD; + } + + val = val | 0x08; // sorry, no constant, CTS wasn't writable + } + return val; } void tsuartPutMUX8(struct tsuart_port *port,int offset,unsigned value) { + *((volatile unsigned char *)port->u.membase + offset) = value; } +struct uart_driver *drc=0,*drd=0; #define BOARD_ID_PAC4 0x7404 -static int tryInitPort(int base) { +static int tryInitPort(int base,struct uart_driver *dr) { struct tsuart_port *ts; ts = kmalloc(sizeof(struct tsuart_port),GFP_KERNEL); @@ -71,14 +92,22 @@ init_tsuart_port(ts); ts->u.iotype = SERIAL_IO_MEM; - ts->get = tsuartGetMUX8; - ts->put = tsuartPutMUX8; + if (dr != 0) { + ts->get = tsuartGetMUX8; + ts->put = tsuartPutMUX8; + } else { + ts->get = tsuartGetMEM8; + ts->put = tsuartPutMEM8; + } ts->debugFlags = portDebug; ts->u.mapbase = /*0 x72000000 + */ base; ts->u.irq = 32; + ts->mdmctrl = 0; ts->boardId = BOARD_ID_PAC4; - - if (tsuart_register_port(0,ts) != 0) { + if (dr) { + // ts->localStatus |= PORT_STATUS_SHIRQ; + } + if (tsuart_register_port(dr,ts) != 0) { return 0; } return 1; @@ -87,7 +116,6 @@ static int __init tsuart_init(void) { int ports=0; - int ret; if (get_ts_model() != TS_MODEL_PAC4) { printk("TS-UART/PAC4 did not detect a TS-PAC4 board\n"); @@ -95,20 +123,48 @@ } else { printk("TS-UART/PAC4 detected a TS-PAC4 board\n"); } - ret = procfile_init(); - if (ret) { - return ret; + + drc = kmalloc(sizeof(struct uart_driver),GFP_KERNEL); + if (!drc) { + printk("Unable to allocate memory for tsuart port\n"); + return 0; + } + drd = kmalloc(sizeof(struct uart_driver),GFP_KERNEL); + if (!drd) { + kfree(drc); + printk("Unable to allocate memory for tsuart port\n"); + return 0; + } + if (!tsuart_configure_driver(drc,234,100,"ttyTSP","cuaTSC",2)) { + kfree(drc); + kfree(drd); + return 0; + } + /* + if (!tsuart_configure_driver(drd,234,101,"ttyTSD","cuaTSD",1)) { + kfree(drc); + kfree(drd); + return 0; + } + */ + if (tryInitPort(0x12400000,0)) { + ports++; } - if (tryInitPort(0x12400000)) { + if (tryInitPort(0x12400002,drc)) { ports++; } + + if (tryInitPort(0x12400002,drc)) { + ports++; + } + return (ports > 0) ? 0 : -1; } static void __exit tsuart_exit(void) { - procfile_exit(); + // not safe to unload! } module_init(tsuart_init); Index: drivers/serial/tsuart-rf.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/tsuart-rf.c,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- drivers/serial/tsuart-rf.c 1 Sep 2006 22:57:32 -0000 1.1 +++ drivers/serial/tsuart-rf.c 29 Dec 2006 00:18:07 -0000 1.3 @@ -35,6 +35,20 @@ #define BOARD_ID_TSRF 0x5162 +static int mdmctrl(struct tsuart_port *ts,int mctrl) { + int dtr; + + if (mctrl & 0x80000000) { + tsuartPutIO8(ts,-1, + (tsuartGetIO8(ts,-1) & 0xFE) | + ((mctrl & TIOCM_DTR) ? 1 : 0)); + dtr = mctrl & TIOCM_DTR; + } else { + dtr = (tsuartGetIO8(ts,-1) & 0x01) ? TIOCM_DTR : 0; + } + return (TIOCM_CAR | TIOCM_DSR | dtr); +} + static int tryInitPort(int iobase) { struct tsuart_port *ts; unsigned val; @@ -51,15 +65,14 @@ ts->debugFlags = portDebug; ts->u.iobase = TS7XXX_IO8_BASE + TS7XXX_ISAIO + iobase; ts->boardId = BOARD_ID_TSRF; + ts->mdmctrl = mdmctrl; val = tsuartGetIO8(ts,0); if (val == 0x8e) { val = tsuartGetIO8(ts,1); + ts->localStatus |= PORT_STATUS_SHIRQ; //share IRQ6 & IRQ7 with IDE if ((val & 0x80) == 0x80) { // assuming IRQ6=33, IRQ7=40 ts->u.irq = 40; - if ((val & 0x40) == 0x40) { - ts->localStatus |= PORT_STATUS_SHIRQ; // IRQ7 with sharing... - } } else { ts->u.irq = 33; } Index: drivers/serial/tsuart.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/tsuart.c,v retrieving revision 1.1 retrieving revision 1.9 diff -u -r1.1 -r1.9 --- drivers/serial/tsuart.c 17 Nov 2005 22:27:57 -0000 1.1 +++ drivers/serial/tsuart.c 19 Oct 2006 17:41:12 -0000 1.9 @@ -8,7 +8,11 @@ * This source code is hereby licensed to the Linux 2.4 kernel under the * GPL, and to Technologic Systems customers under the BSD license. * + * 2005-11-17:mos:initial version completed + * 2005-11-18:mos:added proper hardware flow control support (Tx) + * 2006-01-18:mos:cleanup;now using memory access instead of inb/outb */ +#include #include #include #include @@ -19,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +32,7 @@ #include #include +#define DELAY_TIME HZ / 100 // 100 Hz #define UART_PORT_SIZE 64 // not used #define PORT_TSUART 55 // see include/linux/serial_core.c #define UART_NR 3 @@ -43,29 +49,26 @@ #define CALLOUT_TSUART_MINOR 1 #define CALLOUT_TSUART_NR UART_NR +#define TS_MODEL_REG 0x2000000 #define TS_TTL_REG 0x2000000 -#define TSUART1_BASE 0x2400000 -#define TSUART2_BASE 0x3000000 -#define TSUART3_BASE 0x3400000 #define TSUART_IRQ 32 -/* - * Append any extra per-port data we need to the generic uart_port. - */ -struct uart_tsuart_port { - struct uart_port port; -}; - -#define MYPORT struct uart_tsuart_port *my = (struct uart_tsuart_port *)port +#define TSUART1_BASE 0x12400000 +#define TSUART2_BASE 0x13000000 +#define TSUART3_BASE 0x13400000 //----------------------- // Forward Declarations < //----------------------- -static struct uart_tsuart_port tsuart_ports[]; +static struct uart_port tsuart_ports[]; static void tsuart_stop_tx(struct uart_port *port, unsigned int tty_stop); - +static struct timer_list timer; +static int triuart = 0; +static int timer_added = 0; //#define TSUART_DEBUG +//#define TSUART_DEBUG_DATA +//#define TSUART_STATS //----------------------------------------------------------------------- // / // Interrupt Routines \_ @@ -133,55 +136,53 @@ // Begin hardware access code < //----------------------------- - -static inline unsigned long tsuart_ADRS(int uartNum) { - if (uartNum == 1) { - return TS7XXX_IO8_BASE + TSUART1_BASE; - } else if (uartNum == 2) { - return TS7XXX_IO8_BASE + TSUART2_BASE; - } else if (uartNum == 3) { - return TS7XXX_IO8_BASE + TSUART3_BASE; - } +static inline int get_ts_model(void) { + return (inw(TS7XXX_IO16_BASE + TS_MODEL_REG)) & 3; } -static inline int get_tsuart_ttl() { +static inline int get_tsuart_ttl(void) { unsigned char c; c = inb(TS7XXX_IO8_BASE + TS_TTL_REG); - printk("debug1:%02X\n",c); return c; } static inline void put_tsuart_ttl(int flag) { if (flag) { outb(get_tsuart_ttl() | 64,TS7XXX_IO8_BASE + TS_TTL_REG); - printk("debug2:%02X\n",inb(TS7XXX_IO8_BASE + TS_TTL_REG)); } else { outb(get_tsuart_ttl() & (~64),TS7XXX_IO8_BASE + TS_TTL_REG); - printk("debug3:%02X\n",inb(TS7XXX_IO8_BASE + TS_TTL_REG)); } } // read the TS UART STAT register for the specified UART -static inline unsigned char get_tsuart_STAT(int uartNum) { - return inb(tsuart_ADRS(uartNum)); +static inline unsigned char get_tsuart_STAT(struct uart_port *port) { + unsigned char *STAT = (unsigned char *)port->membase; + + return *STAT; } // write the TS UART STAT register for the specified UART -static inline void put_tsuart_STAT(int uartNum,unsigned char value) { - outb(value,tsuart_ADRS(uartNum)); +static inline void put_tsuart_STAT(struct uart_port *port,unsigned char value) { + unsigned char *STAT = (unsigned char *)port->membase; + + *STAT = value; } // read the TS UART RXDAT register for the specified UART -static inline int get_tsuart_RXDAT(int uartNum) { - return inb(1+tsuart_ADRS(uartNum)); +static inline int get_tsuart_RXDAT(struct uart_port *port) { + unsigned char *DAT = (unsigned char *)port->membase; + + return DAT[1]; } // write the TS UART TXDAT register for the specified UART -static inline void put_tsuart_TXDAT(int uartNum,unsigned char data) { - outb(data,1+tsuart_ADRS(uartNum)); +static inline void put_tsuart_TXDAT(struct uart_port *port,unsigned char data) { + unsigned char *DAT = (unsigned char *)port->membase; + + DAT[1] = data; } -static inline int get_tsuart_TRI() { +static inline int get_tsuart_TRI(void) { return ((inw(TS7XXX_IO16_BASE + 0x2400000) & 1) == 1); } @@ -197,13 +198,12 @@ // process the byte in the lsb of data by sending it to the // appropriate OS buffers for the given TS UART UART -static void tsuart_handleRx(int uartNum,int data) { - struct uart_port *port = (struct uart_port *)(tsuart_ports + uartNum - 1); +static void tsuart_handleRx(struct uart_port *port,int data) { struct tty_struct *tty; unsigned int ch = data; -#ifdef TSUART_DEBUG - printk("Rx%d:%02X%s\n",uartNum,ch,port->info?"":"?"); +#ifdef TSUART_DEBUG_DATA + printk("Rx%d:%02X%s\n",port->line,ch,port->info?"":"?"); #endif if (!port->info) { return; @@ -217,34 +217,51 @@ tty_flip_buffer_push(tty); } tty_insert_flip_char(tty, ch, 0); - gotbytes[uartNum-1]++; + gotbytes[port->line]++; return; } static unsigned int total_sent = 0; - +static inline int bit_CTS(unsigned char reg_value); // If there is data ready to be transmitted for the given UART, // then feed to the byte to the UART -static void tsuart_try_handleTx(int uartNum) { - struct uart_port *port = (struct uart_port *)(tsuart_ports + uartNum - 1); +static void tsuart_try_handleTx(struct uart_port *port) { struct circ_buf *xmit; unsigned int ch=0; if (!port->info) { return; } + if (port->info->flags & ASYNC_CTS_FLOW) { + if (bit_CTS(get_tsuart_STAT(port))) { + port->info->tty->hw_stopped = 0; + } else { + port->info->tty->hw_stopped = 1; + if (!timer_added) { + timer_added = 1; + // printk("Adding timer (%d)\n",port->line); + timer.expires = jiffies + DELAY_TIME; + add_timer (&timer); + } + } + } xmit = &port->info->xmit; if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { + /* + if (uart_tx_stopped(port)) { + printk("tx stop detected\n"); + } + */ tsuart_stop_tx(port,0); return; } // handle one character ch = xmit->buf[xmit->tail]; -#ifdef TSUART_DEBUG - printk("Tx%d:%02X%s\n",uartNum,ch,port->info?"":"?"); +#ifdef TSUART_DEBUG_DATA + printk("Tx%d:%02X%s\n",port->line,ch,port->info?"":"?"); #endif total_sent++; - put_tsuart_TXDAT(uartNum,(unsigned char)ch); + put_tsuart_TXDAT(port,(unsigned char)ch); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; // done handling one character @@ -260,29 +277,6 @@ } } -// Convert a port structure to a UART number. Relies on the fact -// that we store our UART port information in a particular order. -// We could just as easily implement this using extra data in -// our extended port structure that contained the uartNumber, -// but this wouldn't necessarily detect an invalid port. -// We should always be able to find a valid port, but in the -// unlikely (impossible?) event that we do, we return a valid -// port anyway, to avoid lots of ugly and unnecessary checks -// and warning messages elsewhere. -static int getUartNum(struct uart_port *port) { - if (port == (struct uart_port *)tsuart_ports) { - return 1; - } else if (port == (struct uart_port *)(tsuart_ports+1)) { - return 2; - } else if (port == (struct uart_port *)(tsuart_ports+2)) { - return 3; - } else { - printk("tsuart: unknown port %p (expecting %p+%dn)\n", - port,tsuart_ports,sizeof(struct uart_tsuart_port)); - return 3; // hopefully port 3 is the most obscure - } -} - //---------------------------- // Begin FPGA dependant code < @@ -369,50 +363,132 @@ } } +//----------------------------------------------------------------------- +// / +// /proc Routines \_ +// / +// \_ +// / +// \_ +//----------------------------------------------------------------------- +/* + The user can set COM3 to TTL levels as follows: + echo "1" > /proc/device/tsuart/com3ttl + The user can set COM3 to RS-232 levels as follows: + echo "0" > /proc/device/tsuart/com3ttl + The user can query the current status of COM3 as follows: + cat /proc/device/tsuart/com3ttl + "0" if COM3 is at RS-232 levels + "1" if COM3 is at TTL levels + */ +int procfile_read(char *buffer, + char **buffer_location, + off_t offset, + int buffer_length, + int *eof, + void *data) +{ + if (offset > 0) { + *eof = 1; + return 0; + } + MOD_INC_USE_COUNT; + buffer[0] = (get_tsuart_ttl() & 64) ? '1' : '0'; + *buffer_location = buffer; + *eof = 1; + MOD_DEC_USE_COUNT; + + return 1; +} + +int procfile_write(struct file *file, + const char *buffer, + unsigned long count, + void *data) { + char tmp; + + MOD_INC_USE_COUNT; + if (copy_from_user(&tmp,buffer,1)) { + return -EFAULT; + } + if (tmp == '1') { + put_tsuart_ttl(1); + } else if (tmp == '0') { + put_tsuart_ttl(0); + } + MOD_DEC_USE_COUNT; + return 1; +} + +int procfile_init(void) { + struct proc_dir_entry *dir1,*file; + + dir1 = proc_mkdir("driver/tsuart",NULL); + if (dir1 == NULL) { return -ENOMEM; } + + file = create_proc_entry("driver/tsuart/com3ttl", + S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, + NULL); + if (file == NULL) { + remove_proc_entry("driver/tsuart", NULL); + return -ENOMEM; + } + file->read_proc = procfile_read; + file->write_proc = procfile_write; + file->owner = THIS_MODULE; + return 0; +} + +void procfile_exit(void) { + remove_proc_entry("driver/tsuart/com3ttl",NULL); + remove_proc_entry("driver/tsuart", NULL); +} + + //--------------------- // End dependant code < //--------------------- -int tsuart_sanity_check_STAT(int uartNum) { +int tsuart_sanity_check_STAT(struct uart_port *port) { unsigned char stat; - stat = get_tsuart_STAT(uartNum); - put_tsuart_STAT(uartNum,stat | 0x0F); - return (stat == get_tsuart_STAT(uartNum)); + stat = get_tsuart_STAT(port); + put_tsuart_STAT(port,stat | 0x0F); + return (stat == get_tsuart_STAT(port)); } -int tsuart_sanity_check_baud(int uartNum,int rate) { +int tsuart_sanity_check_baud(struct uart_port *port,int rate) { unsigned char stat; - stat = get_tsuart_STAT(uartNum); - put_tsuart_STAT(uartNum,assign_bits_BAUD(stat,rate)); - stat = get_tsuart_STAT(uartNum); + stat = get_tsuart_STAT(port); + put_tsuart_STAT(port,assign_bits_BAUD(stat,rate)); + stat = get_tsuart_STAT(port); return (bits_BAUD(stat) == rate); } // Check if the given UART port looks sane. -int tsuart_sanity_check(int uartNum) { - if (!tsuart_sanity_check_STAT(uartNum)) { return 0; } - if (!tsuart_sanity_check_baud(uartNum,2400)) { return 0; } - if (!tsuart_sanity_check_baud(uartNum,4800)) { return 0; } - if (!tsuart_sanity_check_baud(uartNum,9600)) { return 0; } - if (!tsuart_sanity_check_baud(uartNum,19200)) { return 0; } - if (!tsuart_sanity_check_baud(uartNum,38400)) { return 0; } - if (!tsuart_sanity_check_baud(uartNum,57600)) { return 0; } - if (!tsuart_sanity_check_baud(uartNum,115200)) { return 0; } +int tsuart_sanity_check(struct uart_port *port) { + if (!tsuart_sanity_check_STAT(port)) { return 0; } + if (!tsuart_sanity_check_baud(port,2400)) { return 0; } + if (!tsuart_sanity_check_baud(port,4800)) { return 0; } + if (!tsuart_sanity_check_baud(port,9600)) { return 0; } + if (!tsuart_sanity_check_baud(port,19200)) { return 0; } + if (!tsuart_sanity_check_baud(port,38400)) { return 0; } + if (!tsuart_sanity_check_baud(port,57600)) { return 0; } + if (!tsuart_sanity_check_baud(port,115200)) { return 0; } return 1; } // Check if data is ready to be received from the specified UART // and if so, read it into the data location provided. -static inline void tsuart_checkRx(int uartNum,int *data) { - int stat = get_tsuart_STAT(uartNum); +static inline void tsuart_checkRx(struct uart_port *port,unsigned int *data) { + int stat = get_tsuart_STAT(port); if (bit_DR(stat)) { if (bit_OERR(stat)) { rxof++; } - *data = get_tsuart_RXDAT(uartNum); + *data = get_tsuart_RXDAT(port); } } @@ -420,7 +496,7 @@ // See if the given UART wants to transmit data, and if so, // transmit data if any is ready to be sent. -static inline void tsuart_checkHandleTx(int uartNum) { +static inline void tsuart_checkHandleTx(struct uart_port *port) { int stat; // Check the STAT register, and if it says the transmit @@ -435,50 +511,44 @@ // well not do the more expensive operation. - stat = get_tsuart_STAT(uartNum); + stat = get_tsuart_STAT(port); if (bit_TBRE(stat)) { // if buffer empty, then try to send - tsuart_try_handleTx(uartNum); + tsuart_try_handleTx(port); } } // See if we read any data, and if so, pass it to the upper layers -static inline void tsuart_try_handleRx(int uartNum,int data) { +static inline void tsuart_try_handleRx(struct uart_port *port,int data) { if (data >= 0) { - tsuart_handleRx(uartNum,data); + tsuart_handleRx(port,data); } } /* Interrupt if we have only 1 UART */ -#ifdef TSUART_DEBUG +#ifdef TSUART_STATS int stats[256]; #endif static void tsuart_int1(int irq, void *dev_id, struct pt_regs *regs) { - int data1,data2,data3,counter=256; + unsigned int data1,counter=256; + struct uart_port *port = (struct uart_port *)(tsuart_ports); gotbytes[0] = 0; while (--counter) { - data1 = data2 = data3 = -1; - tsuart_checkRx(1,&data1); - // tsuart_checkRx(2,&data2); - // tsuart_checkRx(3,&data3); - if (data1 == -1 && data2 == -1 && data3 == -1) { + data1 = -1; + tsuart_checkRx(port,&data1); + if (data1 == -1) { break; } - tsuart_try_handleRx(1,data1); - // tsuart_try_handleRx(2,data2); - // tsuart_try_handleRx(3,data3); + tsuart_try_handleRx(port,data1); } if (counter < mincounter) { mincounter = counter; } - tsuart_checkHandleTx(1); - // tsuart_checkHandleTx(2); - // tsuart_checkHandleTx(3); + tsuart_checkHandleTx(port); if (gotbytes[0]) { - struct uart_port *port = (struct uart_port *)(tsuart_ports); struct tty_struct *tty = port->info->tty; -#ifdef TSUART_DEBUG +#ifdef TSUART_STATS stats[gotbytes[0]-1]++; #endif tty_flip_buffer_push(tty); @@ -490,39 +560,39 @@ */ static void tsuart_int3(int irq, void *dev_id, struct pt_regs *regs) { struct uart_port *port = (struct uart_port *)(tsuart_ports); - int data1,data2,data3,counter=256; + unsigned int data1,data2,data3,counter=256; gotbytes[0] = gotbytes[1] = gotbytes[2] = 0; while (--counter) { data1 = data2 = data3 = -1; - tsuart_checkRx(1,&data1); - tsuart_checkRx(2,&data2); - tsuart_checkRx(3,&data3); + tsuart_checkRx(port,&data1); + tsuart_checkRx(port+1,&data2); + tsuart_checkRx(port+2,&data3); if (data1 == -1 && data2 == -1 && data3 == -1) { break; } - tsuart_try_handleRx(1,data1); - tsuart_try_handleRx(2,data2); - tsuart_try_handleRx(3,data3); + tsuart_try_handleRx(port,data1); + tsuart_try_handleRx(port+1,data2); + tsuart_try_handleRx(port+2,data3); } if (counter < mincounter) { mincounter = counter; } - tsuart_checkHandleTx(1); - tsuart_checkHandleTx(2); - tsuart_checkHandleTx(3); + tsuart_checkHandleTx(port); + tsuart_checkHandleTx(port+1); + tsuart_checkHandleTx(port+2); if (gotbytes[0]) { -#ifdef TSUART_DEBUG +#ifdef TSUART_STATS stats[gotbytes[0]-1]++; #endif tty_flip_buffer_push(port->info->tty); } if (gotbytes[1]) { -#ifdef TSUART_DEBUG +#ifdef TSUART_STATS stats[gotbytes[1]-1]++; #endif tty_flip_buffer_push((port+1)->info->tty); } if (gotbytes[2]) { -#ifdef TSUART_DEBUG +#ifdef TSUART_STATS stats[gotbytes[2]-1]++; #endif tty_flip_buffer_push((port+2)->info->tty); @@ -549,9 +619,9 @@ static void tsuart_start_tx(struct uart_port *port, unsigned int tty_start) { #ifdef TSUART_DEBUG - // printk("tsuart_start_tx\n"); + printk("tsuart_start_tx\n"); #endif - tsuart_checkHandleTx(getUartNum(port)); + tsuart_checkHandleTx(port); } static void tsuart_stop_rx(struct uart_port *port) @@ -570,25 +640,43 @@ static unsigned int tsuart_tx_empty(struct uart_port *port) { - return bit_TBRE(get_tsuart_STAT(getUartNum(port))); +#ifdef TSUART_DEBUG + printk("tsuart_tx_empty called,port=%p\n",port); +#endif + return bit_TBRE(get_tsuart_STAT(port)); } static unsigned int tsuart_get_mctrl(struct uart_port *port) { unsigned int result = 0; +#ifdef TSUART_DEBUG + printk("tsuart_get_mctrl called,port=%p\n",port); +#endif + result |= TIOCM_CAR; // pretend DCD is always set result |= TIOCM_DSR; // pretend DSR is always set - if (bit_CTS(get_tsuart_STAT(getUartNum(port)))) { + if (bit_CTS(get_tsuart_STAT(port))) { +#ifdef TSUART_DEBUG + printk("reporting CTS asserted\n"); +#endif result |= TIOCM_CTS; + } else { +#ifdef TSUART_DEBUG + printk("reporting CTS de-asserted\n"); +#endif } return result; } static void tsuart_set_mctrl(struct uart_port *port, unsigned int mctrl) { - put_tsuart_STAT(getUartNum(port), - assign_bit_RTS(get_tsuart_STAT(getUartNum(port)),(mctrl&TIOCM_RTS)==0)); +#ifdef TSUART_DEBUG + printk("tsuart_set_mctrl called,port=%p,mctrl=%X\n",port,mctrl); + printk("RTS=%d\n",((mctrl&TIOCM_RTS) != 0) ? 1:0); +#endif + put_tsuart_STAT(port, + assign_bit_RTS(get_tsuart_STAT(port),(mctrl&TIOCM_RTS)!=0)); // No support for TIOCM_DTR, so ignore it } @@ -602,16 +690,32 @@ static int started = 0; +static void tsuart_cts_timer(unsigned long data) { + struct uart_port *port = (struct uart_port *)(tsuart_ports); + // struct uart_port *port = (struct uart_port *)data; + // printk("timer fired!\n"); + timer_added = 0; + tsuart_checkHandleTx(port); + tsuart_checkHandleTx(port+1); + tsuart_checkHandleTx(port+2); +} + static int tsuart_startup(struct uart_port *port) { - unsigned char ch; - unsigned long base_addr; - int i,triuart=0; + struct uart_port *ports = (struct uart_port *)(tsuart_ports); +#ifdef TSUART_STATS + int i; +#endif if (started++) { return 0; } -#ifdef TSUART_DEBUG + + /* create our timer but don't submit it just yet */ + timer.data = (unsigned long )port; + timer.function = tsuart_cts_timer; + +#ifdef TSUART_STATS for (i=0;i<256;i++) { stats[i] = 0; } @@ -619,36 +723,44 @@ rxof = 0; #ifdef TSUART_DEBUG printk("tsuart_startup called, irq=%d\n",port->irq); - printk("membase=%p\nmapbase=%p\n",port->membase,port->mapbase); + printk("membase=%p\nmapbase=%lX\n",port->membase,port->mapbase); #endif triuart = get_tsuart_TRI(); #ifdef TSUART_DEBUG printk("tsuart:detected %d UARTs\n",triuart?3:1); #endif - if (triuart && !tsuart_sanity_check(2)) { + if (triuart && !tsuart_sanity_check(ports)) { + printk("tsuart: 1 uart sanity checked failed!\n"); + triuart = 0; + } + if (triuart && !tsuart_sanity_check(ports+1)) { printk("tsuart: 3 uart sanity checked failed, falling back to 1 UART\n"); triuart = 0; } - if (triuart && !tsuart_sanity_check(3)) { + if (triuart && !tsuart_sanity_check(ports+2)) { printk("tsuart: 3 uart sanity checked failed, falling back to 1 UART\n"); triuart = 0; } if (!triuart) { - return request_irq(port->irq, tsuart_int1, 0, "tsuart_uarts", port); + return request_irq(port->irq, tsuart_int1, SA_SHIRQ, "tsuart_uarts", port); } else { - return request_irq(port->irq, tsuart_int3, 0, "tsuart_uarts", port); + return request_irq(port->irq, tsuart_int3, SA_SHIRQ, "tsuart_uarts", port); } return 0; } static void tsuart_shutdown(struct uart_port *port) { +#ifdef TSUART_STATS int i; +#endif if (--started) { return; } -#ifdef TSUART_DEBUG + del_timer (&timer); + timer_added = 0; +#ifdef TSUART_STATS for (i=0;i<6;i++) { printk("tsuart@%d:%d\n",i+1,stats[i]); } @@ -657,8 +769,7 @@ printk("tsuart:overflows=%d\n",rxof); printk("tsuart_shutdown called, irq=%d\n",port->irq); #endif - put_tsuart_STAT(getUartNum(port), - assign_bits_BAUD(get_tsuart_STAT(getUartNum(port)),0)); + put_tsuart_STAT(port,assign_bits_BAUD(get_tsuart_STAT(port),0)); free_irq(port->irq,port); // Since there is no way to disable the UARTs from @@ -684,22 +795,15 @@ default: baud=0; } if (baud) { - printk("tsuart:change_speed (%d): %d\n",getUartNum(port),baud); - put_tsuart_STAT(getUartNum(port), - assign_bits_BAUD(get_tsuart_STAT(getUartNum(port)),baud)); + printk("tsuart:change_speed, port %d: %d bad\n",port->line,baud); + put_tsuart_STAT(port,assign_bits_BAUD(get_tsuart_STAT(port),baud)); } else { - printk("tsuart:unknown change_speed (%d): %X\n",getUartNum(port),encoded_baud); + printk("tsuart:unknown change_speed, port %d: %X\n",port->line,encoded_baud); printk("%08X & %08X -> %08X\n",cflag,CBAUD,cflag & CBAUD); } - if (getUartNum(port) == 1) { - if (cflag & PARODD) { - printk("ttyTS1:TTL\n"); - put_tsuart_ttl(1); - } else { - printk("ttyTS1:RS-232\n"); - put_tsuart_ttl(0); - } + if (cflag & PARENB) { + printk("tsuart:parity unsupported, using no parity\n"); } /* byte size and parity */ switch (cflag & CSIZE) { @@ -728,7 +832,13 @@ */ static void tsuart_release_port(struct uart_port *port) { +#ifdef TSUART_DEBUG + printk("tsuart_release_port called, membase=%p\n",port->membase); +#endif // release_mem_region(port->mapbase, UART_PORT_SIZE); + __iounmap(port->membase); + + port->membase = 0; } /* @@ -736,6 +846,17 @@ */ static int tsuart_request_port(struct uart_port *port) { +#ifdef TSUART_DEBUG + printk("tsuart_request_port called, mapbase=%lX\n",port->mapbase); +#endif + // call __ioremap to avoid a IO to PHY translation - we already have + // the PHYsical address! + port->membase = __ioremap(port->mapbase, 4096,0); + if (!port->membase) { + printk(KERN_ERR "tsuart: cannot map io memory\n"); + return -ENOMEM; + } + return 0; // return request_mem_region(port->mapbase, UART_PORT_SIZE, "tsuart_uarts") // != NULL ? 0 : -EBUSY; } @@ -805,45 +926,39 @@ .ioctl = tsuart_ioctls, }; -static struct uart_tsuart_port tsuart_ports[3] = { +static struct uart_port tsuart_ports[3] = { { - .port = { - .membase = (void *)IO_ADDRESS(TSUART1_BASE), - .mapbase = TSUART1_BASE, - .iotype = SERIAL_IO_MEM, - .irq = TSUART_IRQ, - .uartclk = UART_CLOCK, - .fifosize = UART_FIFOSIZE, - .ops = &tsuart_ops, - .flags = ASYNC_BOOT_AUTOCONF, - .line = 0, - }, + .membase = 0, + .mapbase = TSUART1_BASE, + .iotype = SERIAL_IO_MEM, + .irq = TSUART_IRQ, + .uartclk = UART_CLOCK, + .fifosize = UART_FIFOSIZE, + .ops = &tsuart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 0, }, { - .port = { - .membase = (void *)IO_ADDRESS(TSUART2_BASE), - .mapbase = TSUART2_BASE, - .iotype = SERIAL_IO_MEM, - .irq = TSUART_IRQ, - .uartclk = UART_CLOCK, - .fifosize = UART_FIFOSIZE, - .ops = &tsuart_ops, - .flags = ASYNC_BOOT_AUTOCONF, - .line = 1, - }, + .membase = 0, + .mapbase = TSUART2_BASE, + .iotype = SERIAL_IO_MEM, + .irq = TSUART_IRQ, + .uartclk = UART_CLOCK, + .fifosize = UART_FIFOSIZE, + .ops = &tsuart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 1, }, { - .port = { - .membase = (void *)IO_ADDRESS(TSUART3_BASE), - .mapbase = TSUART3_BASE, - .iotype = SERIAL_IO_MEM, - .irq = TSUART_IRQ, - .uartclk = UART_CLOCK, - .fifosize = UART_FIFOSIZE, - .ops = &tsuart_ops, - .flags = ASYNC_BOOT_AUTOCONF, - .line = 2, - }, + .membase = 0, + .mapbase = TSUART3_BASE, + .iotype = SERIAL_IO_MEM, + .irq = TSUART_IRQ, + .uartclk = UART_CLOCK, + .fifosize = UART_FIFOSIZE, + .ops = &tsuart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 2, } }; @@ -873,16 +988,26 @@ .cons = NULL, }; + static int __init tsuart_init(void) { - int ret; - + int ret,i; + + if (get_ts_model() != 2) { + printk("tsuart not loading: ts7260 board not detected\n"); + procfile_exit(); + return -1; + } ret = uart_register_driver(&tsuart_reg); if (ret == 0) { - int i; + ret = procfile_init(); + if (ret) { + uart_unregister_driver(&tsuart_reg); + return ret; + } for (i=0;iu.irq = 0; p->u.uartclk = UART_CLOCK; p->u.fifosize = UART_FIFOSIZE; @@ -123,5 +138,7 @@ p->dataMask = p->dataMask2 = 0xFF; p->localStatus = 0; p->portStatus = 0; + p->boardId = 0; + p->mdmctrl = 0; } #endif Index: drivers/serial/tsuart0.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/tsuart0.c,v retrieving revision 1.1 retrieving revision 1.18 diff -u -r1.1 -r1.18 --- drivers/serial/tsuart0.c 16 May 2006 19:10:12 -0000 1.1 +++ drivers/serial/tsuart0.c 3 Mar 2009 16:23:32 -0000 1.18 @@ -8,6 +8,7 @@ * This source code is hereby licensed to the Linux 2.4 kernel under the * GPL, and to Technologic Systems customers under the BSD license. * + * 2006-05-16:mos:fixed parity as it was backwards, some general cleanup done * 2006-05-12:mos:initial version completed, based on tsuart.c * */ @@ -50,7 +51,7 @@ #define DEBUG_TXRX 128 #define DEBUG_PARITY 256 -MODULE_DESCRIPTION("Technologic Systems UART serial port driver"); +MODULE_DESCRIPTION("Technologic Systems UART modular driver core"); #define DELAY_TIME HZ / 100 // 100 Hz #define UART_PORT_SIZE 64 // not used @@ -75,6 +76,7 @@ static void tsuart_stop_tx(struct uart_port *port, unsigned int tty_stop); static struct timer_list timer; static int timer_added = 0; +static struct timer_list timer2 = { .function = NULL }; static inline int bit_CTS(unsigned char reg_value); //----------------------------- @@ -137,6 +139,8 @@ *((volatile unsigned short *)port->u.membase + offset) = value; } +static void tsuart_try_handleTx(struct tsuart_port *port); + void tsuartPutMEM16_9(struct tsuart_port *port,int offset,unsigned value) { if (offset != 1) { *((volatile unsigned short *)port->u.membase + offset) = value; @@ -144,10 +148,12 @@ if ((value & 0xFE) == 0) { port->pstatus = (port->pstatus & 0xFFFF00FF) | ((value & 0xFF) << 8); port->pstatus &= ~PORT_STATUS_TXMSB; - uart_write_wakeup(&port->u); } else { - printk("***TX Rejected (sync)\n"); + if (port->debugFlags & DEBUG_DATA) { + printk("***TX Rejected (sync)\n"); + } } + //tsuart_try_handleTx(port); // avoid stuckness } else { value += (port->pstatus & 0xFF00); *((volatile unsigned short *)port->u.membase + offset) = value; @@ -172,6 +178,7 @@ static void tsuart_handleRx(struct tsuart_port *port,int data) { struct tty_struct *tty; unsigned int ch = data; + int flag = 0; if (port->debugFlags & DEBUG_DATA) { unsigned int ttyinf = port->u.info ? (port->u.info->tty ? 3:1) : 0; @@ -182,18 +189,35 @@ } tty = port->u.info->tty; if (tty->flip.count >= TTY_FLIPBUF_SIZE) { - tty_flip_buffer_push(tty); + tty->flip.tqueue.routine((void *)tty); + //printk("->%X ",tty->flip.char_buf_ptr); + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + printk("TSUART0 - TTY FLIP BUF FAILED!\n"); + return; + } + } +#ifdef TSUART_CORRECT_PARITY + if (port->localStatus & PORT_STATUS_PARITY) { + flag |= TTY_PARITY; } +#endif if (port->rxsize > 3) { - tty_insert_flip_char(tty, (ch >> 24) & 0xFF, 0); + tty_insert_flip_char(tty, (ch >> 24) & 0xFF, flag); } if (port->rxsize > 2) { - tty_insert_flip_char(tty, (ch >> 16) & 0xFF, 0); + tty_insert_flip_char(tty, (ch >> 16) & 0xFF, flag); } if (port->rxsize > 1) { - tty_insert_flip_char(tty, (ch >> 8) & 0xFF, 0); + tty_insert_flip_char(tty, (ch >> 8) & 0xFF, flag); + } + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + tty->flip.tqueue.routine((void *)tty); + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + printk("TSUART0 - TTY FLIP BUF FAILED!\n"); + return; + } } - tty_insert_flip_char(tty, (ch & 0xFF), 0); + tty_insert_flip_char(tty, (ch & 0xFF), flag); port->gotBytes++; return; } @@ -211,7 +235,7 @@ // then feed to the byte to the UART static void tsuart_try_handleTx(struct tsuart_port *port) { struct circ_buf *xmit; - unsigned int ch=0; + unsigned int ch=0,i=0; if (!port->u.info || !port->u.info->tty) { if (port->debugFlags & DEBUG_DATA) { @@ -236,20 +260,29 @@ } } xmit = &port->u.info->xmit; - if (uart_circ_empty(xmit) || uart_tx_stopped(&(port->u))) { - tsuart_stop_tx(&port->u,0); + if (uart_circ_empty(xmit)) { // || uart_tx_stopped(&(port->u))) { return; } - // handle one character - ch = xmit->buf[xmit->tail]; - if (port->debugFlags & DEBUG_DATA) { - unsigned int ttyinf = port->u.info ? (port->u.info->tty ? 3:1) : 0; - printk("tsuart Tx(%d):%02X:%d\n",port->u.line,ch,ttyinf); - } - tsuart_parity_Tx(port,ch); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->u.icount.tx++; - // done handling one character + + i = 0; + //printk("%d:%d %p\n",xmit->tail,xmit->head,&i); + do { + // handle one character + ch = xmit->buf[xmit->tail]; + if (port->debugFlags & DEBUG_DATA) { + unsigned int ttyinf = port->u.info ? (port->u.info->tty ? 3:1) : 0; + printk("tsuart Tx(%d):%02X:%d\n",port->u.line,ch,ttyinf); + } + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + port->u.icount.tx++; + tsuart_parity_Tx(port,ch); + // done handling one character + i++; + if (uart_circ_empty(xmit)) { // || uart_tx_stopped(&(port->u))) { + break; + } + } while (bit_TBRE(tsuartGetSTAT(port)) && i < 64); + //printk("%d %X\n",i,tsuartGetSTAT(port)); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) { uart_write_wakeup(&port->u); @@ -262,7 +295,6 @@ } } - //---------------------------- // Begin FPGA dependant code < //---------------------------- @@ -315,89 +347,6 @@ } } -//----------------------------------------------------------------------- -// / -// /proc Routines \_ -// / -// \_ -// / -// \_ -//----------------------------------------------------------------------- -/* - The user can set COM3 to TTL levels as follows: - echo "1" > /proc/device/tsuart/com3ttl - The user can set COM3 to RS-232 levels as follows: - echo "0" > /proc/device/tsuart/com3ttl - The user can query the current status of COM3 as follows: - cat /proc/device/tsuart/com3ttl - "0" if COM3 is at RS-232 levels - "1" if COM3 is at TTL levels - */ -/* -int procfile_read(char *buffer, - char **buffer_location, - off_t offset, - int buffer_length, - int *eof, - void *data) -{ - if (offset > 0) { - *eof = 1; - return 0; - } - MOD_INC_USE_COUNT; - buffer[0] = (get_tsuart_ttl() & 64) ? '1' : '0'; - *buffer_location = buffer; - *eof = 1; - MOD_DEC_USE_COUNT; - - return 1; -} - -int procfile_write(struct file *file, - const char *buffer, - unsigned long count, - void *data) { - char tmp; - - MOD_INC_USE_COUNT; - if (copy_from_user(&tmp,buffer,1)) { - return -EFAULT; - } - if (tmp == '1') { - put_tsuart_ttl(1); - } else if (tmp == '0') { - put_tsuart_ttl(0); - } - MOD_DEC_USE_COUNT; - return 1; -} - -int procfile_init(void) { - struct proc_dir_entry *dir1,*file; - - dir1 = proc_mkdir("driver/tsuart",NULL); - if (dir1 == NULL) { return -ENOMEM; } - - file = create_proc_entry("driver/tsuart/com3ttl", - S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, - NULL); - if (file == NULL) { - remove_proc_entry("driver/tsuart", NULL); - return -ENOMEM; - } - file->read_proc = procfile_read; - file->write_proc = procfile_write; - file->owner = THIS_MODULE; - return 0; -} - -void procfile_exit(void) { - remove_proc_entry("driver/tsuart/com3ttl",NULL); - remove_proc_entry("driver/tsuart", NULL); -} -*/ - //--------------------- // End dependant code < //--------------------- @@ -410,14 +359,20 @@ data = rxdata & port->dataMask2; // printk("%X (%X)\n",data,port->parity[data]); } else { - data = rxdata & port->dataMask2; + data = rxdata; } if (!port->parity || port->parity[data] == rxdata) { + port->localStatus &= ~PORT_STATUS_PARITY; return data; } else { port->u.icount.parity++; + port->localStatus |= ~PORT_STATUS_PARITY; +#ifdef TSUART_CORRECT_PARITY + return data; +#else return -1; +#endif } } @@ -434,7 +389,6 @@ } port->data = tsuart_parity_Rx(port); } - } else { } } @@ -471,7 +425,7 @@ } //----------------------------------------------------------------------- -// Interrupt Routines < +// Interrupt Routine < //----------------------------------------------------------------------- static void tsuart_interrupt(int irq, void *dev_id, struct pt_regs *regs) { @@ -552,7 +506,9 @@ if (TSPORT(port)->debugFlags & DEBUG_INTERFACE) { printk("tsuart_start_tx(%d,%d)\n",PORTNUM(port),tty_start); } + cli(); tsuart_checkHandleTx(TSPORT(port)); + sti(); } static void tsuart_stop_rx(struct uart_port *port) @@ -580,10 +536,15 @@ static unsigned int tsuart_get_mctrl(struct uart_port *port) { + struct tsuart_port *p = TSPORT(port); unsigned int result = 0; - result |= TIOCM_CAR; // pretend DCD is always set - result |= TIOCM_DSR; // pretend DSR is always set + if (p->mdmctrl) { + result |= p->mdmctrl(p,0); + } else { + result |= TIOCM_CAR; // pretend DCD is always set + result |= TIOCM_DSR; // pretend DSR is always set + } if (bit_CTS(tsuartGetSTAT(TSPORT(port)))) { result |= TIOCM_CTS; } @@ -602,19 +563,59 @@ printk("tsuart_set_mctrl(%d,RTS=%d)\n",PORTNUM(port),((mctrl&TIOCM_RTS) != 0) ? 1:0); } tsuartPutSTAT(p,assign_bit_RTS(tsuartGetSTAT(p),(mctrl&TIOCM_RTS)!=0)); - // No support for TIOCM_DTR, so ignore it + if (p->mdmctrl) { + p->mdmctrl(p,0x80000000 | mctrl); + } else { + // No support for TIOCM_DTR, so ignore it + } } static void tsuart_break_ctl(struct uart_port *port, int break_state) { - // UART does not support BREAK + // some UARTs do not support BREAK + if (break_state == -1) break_state = 1; + tsuartPutSTAT((struct tsuart_port *)port,assign_bit_TXBRK(tsuartGetSTAT((struct tsuart_port *)port),break_state)); if (TSPORT(port)->debugFlags & DEBUG_INTERFACE) { - printk("tsuart_break_ctl(%d,%d)\n",PORTNUM(port),break_state); + printk("--- tsuart_break_ctl(%d,%d)\n",PORTNUM(port),break_state); } } static int started = 0; +static void tsuart_mdm_timer(unsigned long data) { + struct tsuart_port *root = TS,*next; + unsigned int status, delta; + + //printk("tsuart_mdm_timer()\n"); + while (root) { + next = root; + while (next) { + status = tsuart_get_mctrl(&next->u); + delta = status ^ next->old_status; + next->old_status = status; + if (delta) { + if (delta & TIOCM_CAR) { + //printk("tsuart_mdm_timer: DCD\n"); + //uart_handle_dcd_change(&next->u, status & TIOCM_CAR); + } + if (delta & TIOCM_DSR) { + //printk("tsuart_mdm_timer: DSR\n"); + next->u.icount.dsr++; + } + if (delta & TIOCM_CTS) { + //printk("tsuart_mdm_timer: CTS\n"); + //uart_handle_dcd_change(&next->u, status & TIOCM_CTS); + } + //wake_up_interruptible(&next->u.info->delta_msr_wait); + } + next = next->next; + } + root = root->nextd; + } + timer2.expires = jiffies + HZ; + add_timer (&timer2); +} + static void tsuart_cts_timer(unsigned long data) { // struct uart_port *port = (struct uart_port *)(tsuart_ports); // struct uart_port *port = (struct uart_port *)data; @@ -656,6 +657,7 @@ TSPORT(port)->localStatus |= PORT_STATUS_OPEN; setMODE9(port,TSPORT(port)->rxsize > 1 || (TSPORT(port)->localStatus & PORT_STATUS_8PLUS1)); + TSPORT(port)->old_status = tsuart_get_mctrl(port); if (started++) { // not needed? return 0; } @@ -664,6 +666,17 @@ timer.data = (unsigned long )port; timer.function = tsuart_cts_timer; + if (timer2.function == NULL) { + if (TSPORT(port)->debugFlags & DEBUG_INTERRUPT) { + printk("Starting MDM timer\n"); + } + timer.expires = jiffies + HZ; + timer2.function = tsuart_mdm_timer; + add_timer(&timer2); + } else { + printk("MDM timer can't start!\n"); + } + #if 0 for (i=0;i<256;i++) { stats[i] = 0; @@ -697,6 +710,10 @@ del_timer (&timer); timer_added = 0; } + if (timer2.function) { + del_timer(&timer2); + timer2.function = NULL; + } #if 0 for (i=0;i<6;i++) { @@ -705,6 +722,8 @@ #endif tsuartPutSTAT(p,assign_bits_BAUD(tsuartGetSTAT(p),0)); + port->info->xmit.tail = port->info->xmit.head; // avoid stuckness + } static int calcpar(int val,int parodd) { @@ -797,7 +816,7 @@ static void tsuart_change_speed(struct uart_port *port, unsigned int cflag, unsigned int iflag, unsigned int quot) { struct tsuart_port *p = TSPORT(port); - int encoded_baud,baud,par=0,parodd=0,dbits=8,stop=0; + int encoded_baud,baud,par=0,parodd=0,dbits=8; // ,stop=0; if (TSPORT(port)->debugFlags & DEBUG_INTERFACE) { printk("tsuart_change_speed(%d,%d,%d,%d)\n",PORTNUM(port),cflag,iflag,quot); @@ -851,7 +870,9 @@ */ TSPORT(port)->dataMask2 = (1 << (dbits)) - 1; // TO DO: only allow this on an 8-bit port! - if (dbits == 8 && par) { + if (TSPORT(port)->rxsize > 1) { + TSPORT(port)->dataMask2 = 0x1FF; + } else if (dbits == 8 && par) { TSPORT(port)->localStatus |= PORT_STATUS_8PLUS1; TSPORT(port)->dataMask = 0x1FF; } else { @@ -863,7 +884,11 @@ if (cflag & CSTOPB) { printk("tsuart:unsupported stop bits, using 1\n"); } - initpar(TSPORT(port),dbits,par,parodd); + if (TSPORT(port)->rxsize < 2) { + initpar(TSPORT(port),dbits,par,parodd); + } + // clear the receive FIFO + while (bit_DR(tsuartGetSTAT(p))) tsuartGetDATA(p); } static const char *tsuart_type(struct uart_port *port) @@ -896,13 +921,16 @@ if (port->membase == 0) { port->membase = (void *) __ioremap(port->mapbase & 0xFFFFF000, 4096,0) + (port->mapbase & 0xFFF); - // printk("port %p:mapbase=%X, membase=%X\n",port,port->mapbase,port->membase); - if (!port->membase) { + //printk("port %p:mapbase=%X, membase=%X\n",port,port->mapbase,port->membase); + if (port->membase == (void *)(port->mapbase & 0xFFF)) { + port->membase = 0; printk(KERN_ERR "tsuart: cannot map io memory\n"); return -ENOMEM; } } } + // clear the receive FIFO + while (bit_DR(tsuartGetSTAT(TSPORT(port)))) tsuartGetDATA(TSPORT(port)); return 0; } @@ -932,6 +960,9 @@ ret = -EINVAL; if (ser->irq < 0 || ser->irq >= NR_IRQS) ret = -EINVAL; + if (ser->baud_base < 9600) { + ser->baud_base = 115200; // required to allow ioctl to set low_latency + } // if (ser->baud_base != 115200) // ret = -EINVAL; if (TSPORT(port)->debugFlags & DEBUG_INTERFACE) { @@ -979,12 +1010,7 @@ .verify_port = tsuart_verify_port, .ioctl = tsuart_ioctls, }; -/* -static struct tty_driver normal, callout; -static struct tty_struct *cs_tsuart_table[UART_NR]; -static struct termios *cs_tsuart_termios[UART_NR], - *cs_tsuart_termios_locked[UART_NR]; - */ + static inline char *kstrcat(char *src,char *src2) { char *dst; @@ -1079,103 +1105,7 @@ #define CUA_NAME CALLOUT_TSUART_NAME -/* - - */ static struct uart_driver tsuart_reg; -/* , tsuart_reg2 = { - .owner = THIS_MODULE, - .normal_major = SERIAL_TSUART_MAJOR, -#ifdef CONFIG_DEVFS_FS - .normal_name = SERIAL_TSUART_NAME "%d", - .callout_name = CALLOUT_TSUART_NAME "%d", -#else - .normal_name = SERIAL_TSUART_NAME, - .callout_name = CALLOUT_TSUART_NAME, -#endif - .normal_driver = &normal, - .callout_major = CALLOUT_TSUART_MAJOR, - .callout_driver = &callout, - .table = cs_tsuart_table, - .termios = cs_tsuart_termios, - .termios_locked = cs_tsuart_termios_locked, - .minor = SERIAL_TSUART_MINOR, - .nr = UART_NR, - .cons = NULL, -}; -*/ -/* - Two strategies for detecting ports: - 1. Each known model has a "profile" which is a set of values for the - port parameters. Known models include: - TS7260 - 1 or 3 ports, TTL support on some of them - TS7300 - 8 ports, 9-bit supported - TS5500 - 2 ports (1 1/2), limited baud rates - BAT3 - 1 port in one of 4 I/O locations - So if we aren't given any parameters, we should try to auto-detect by - seeing if we can identify our board as one of the above known boards, - and if not we don't load. If we are given parameters then we simply - use those. - 2. Once we have the list of possible ports, we need to go through them - to try to find what actual ports exist. On all boards we should be able - to sanity check the STAT port, and on some boards we might be able to - read another port to get a signature value. If a port has the force - flag set, then we assume the information given is correct, and don't - try to sanity check that the port is really there. - 3. For each port we determine is actually there, we need to allocate - a struct uart_driver instance and populate it with the information for - that port. Then we register the port. - 4. The driver is composed of several parts: - - general serial port functionality (OS specific code) - this code is responsible for providing the OS interface functions, - and for the logic sending and receiving bytes (two sections). - - register access code - this code defines the registers on the board and a hardware independant - method to access them. it also defines the bit-fields on the board - - hardware specific code - this code defines various code which is specific to various boards, - including code to determine what kind of board we are running on. - - Shouldn't do any WRITES unless we are reasonably sure we have our UART. - For most of our configurations, we can detect where the UARTs are - supposed to be. - To detect the BAT3 board, read the ID register at 0x100, 0x110, 0x200, - and 0x210. When we see 0x28 we know we have probably found a BAT3 board, - and can then sanity check the board. But our existing mechanism isn't - suitable because we peform writes to probe for the board. - - Here is a new idea. The core driver should only have the following: - knowledge of the STAT and DATA register, and the interface between - the serial port(s) and the operating system - Then we can write modules for particular boards which determine whether - or not we have that board, and if so, communicates with the core driver - to create the appropriate serial ports for that board. - I think we can have a single core module handling all the serial ports - that exist. The key point is that the individual ports are allocated - individually. This requires that the interrupt routine and possibly - the timer routine are able to determine which port structure they were - called with, or more generally, which ports they should handle, since - we might want to handle all ports for a given interrupt. One way to - do this might be to create our own extended port info structure which - has a pointer to the next port in the chain. This would also allow us - to stop relying on the stupid "unused" variable in struct uart_port. - - It looks like struct uart_port *port = dev_id. - - NOTE: - 1. What if we try to register a port that is already registered? - - We should check for a disallow that! DONE! - 2. How do we unregister a port if we've already unloaded the module that - did the registering? - - We could unregister all ports by unloading the base module - - We could unregister ports on module load if we detect they are already - loaded. This assumes all ports for a module are either loaded or not, - otherwise we might wind up loading some and unloading others. - 3. Shouldn't the tsuart_reg.nr field reflect the current number of registered - ports? - 4. The cs_tsuart_* arrays, how do we keep the up to date with the correct - number of elements? Who uses these? - */ typedef int (*portCompF)(struct tsuart_port *,struct tsuart_port *); @@ -1224,6 +1154,38 @@ } */ +inline int shares(struct tsuart_port *port) { + return (port->localStatus & PORT_STATUS_SHIRQ) == PORT_STATUS_SHIRQ; +} + +static int irqConflict(struct tsuart_port *port) { + struct tsuart_port *next; + + if (!TS) { + return 0; + } + next = TS; + while (next) { + if (next->u.irq == port->u.irq) { + // allow only if all ports already registered are either + // 1. the same boardId as the new port or + // 2. allowing sharing, and the new port allows sharing + while (next) { + if (next->boardId == port->boardId) { + return 0; + } + if (!shares(port) || !shares(next)) { + return 1; + } + next = next->nextd; + } + return 0; + } + next = next->next; + } + return 0; +} + // Returns TRUE if an IRQ is already allocated for the given port static int addPort(struct tsuart_port *port) { struct tsuart_port *next; @@ -1260,10 +1222,10 @@ stat = tsuartGetSTAT(port); tsuartPutSTAT(port,(stat & 0xFF) | 0xEF); stat2 = tsuartGetSTAT(port); - if (portDebug & DEBUG_PROBE) { + if (port->debugFlags & DEBUG_PROBE) { printk("STAT probe: %X %X\n",stat,stat2); } - tsuartPutSTAT(port,0); + tsuartPutSTAT(port,stat); return ((stat & 0x1F) == (stat2 & 0x1F) && (stat2 & 0xE0) == 0xE0); } @@ -1288,6 +1250,10 @@ return -1; } port->driver = driver; + if (irqConflict(port)) { + printk("IRQ in use\n"); + return -1; + } if (portExists(port)) { printk("Port already registered\n"); return -1; @@ -1296,11 +1262,14 @@ port->u.line = d->lines; state = driver->state + port->u.line; if ((ret = uart_add_one_port(driver,p)) == 0) { - if (portDebug & DEBUG_ENDS) { + if (port->debugFlags & DEBUG_ENDS) { printk("registered port %p\n",port); } if (!addPort(port)) { - ret=request_irq(port->u.irq, tsuart_interrupt, 0, "tsuart_uarts", p); + ret=request_irq(port->u.irq, tsuart_interrupt, + port->localStatus & PORT_STATUS_SHIRQ ? + SA_SHIRQ : 0, + "tsuart_uarts", p); if (ret != 0) { printk("Unable to allocate irq %d\n",port->u.irq); } else { @@ -1314,7 +1283,7 @@ } } } else { - if (portDebug & DEBUG_ENDS) { + if (port->debugFlags & DEBUG_ENDS) { printk("Failed to register port %p with driver %p, ret=%d\n",port,driver,ret); } return -1; @@ -1323,12 +1292,19 @@ d->lines++; if (!tsuart_sanity_check_STAT(port)) { - printk("WARNING: port %p failed STAT sanity check!\n",port); + printk("WARNING: port %d failed STAT sanity check!\n",port->u.line); + // Note: This will fail in a number of cases which are fatal: + // 1. If the FPGA bitstream isn't loaded + // 2. We are loaded on hardware that doesn't have a TS-UART present (e.g. wrong arch) + // It will also fail in a number of cases which are benign: + // 1. Loopback is installed on the flow control lines (e.g. RTS/CTS) + // 2. We are a specialized TS-UART that doesn't have all the bits in STAT defined } } return ret; } +/* int tsuart_unregister_port(struct tsuart_port *port) { struct tsuart_port *next; @@ -1364,20 +1340,14 @@ // TO DO: we are responsible for kfree()'ing port return -1; } +*/ static int __init tsuart_init(void) { - int ret=0; - tsuart_configure_driver(&tsuart_reg,SERIAL_TSUART_MAJOR,SERIAL_TSUART_MINOR, TTY_NAME,CUA_NAME,64); - // ret = uart_register_driver(&tsuart_reg); - if (ret) { - return ret; - } - // ret = procfile_init(); - return ret; + return 0; } static void __exit tsuart_exit(void) @@ -1406,7 +1376,6 @@ kfree(tmp); } while (next); } - // procfile_exit(); // printk("unregistering drivers\n"); while (drivers) { if (drivers->car) { @@ -1428,7 +1397,7 @@ module_exit(tsuart_exit); EXPORT_SYMBOL(tsuart_register_port); -EXPORT_SYMBOL(tsuart_unregister_port); +//EXPORT_SYMBOL(tsuart_unregister_port); EXPORT_SYMBOL(tsuartGetIO8); EXPORT_SYMBOL(tsuartGetMEM8); EXPORT_SYMBOL(tsuartGetMEM16); @@ -1446,5 +1415,5 @@ When the TS-UART is re-used in a new board design, it is only necessary to write a loader driver. In most cases all the loader driver does is - probe for ports it knows about + probe for ports it knows about. */ Index: drivers/serial/tsuart7260.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/tsuart7260.c,v retrieving revision 1.1 retrieving revision 1.6 diff -u -r1.1 -r1.6 --- drivers/serial/tsuart7260.c 16 May 2006 19:12:17 -0000 1.1 +++ drivers/serial/tsuart7260.c 29 Sep 2008 16:15:47 -0000 1.6 @@ -35,6 +35,10 @@ #define TS_TTL_REG 0x2000000 +static inline int get_tsuart_TRI(void) { + return ((inw(TS7XXX_IO16_BASE + 0x2400000) & 1) == 1); +} + static inline int get_tsuart_ttl(void) { unsigned char c; c = inb(TS7XXX_IO8_BASE + TS_TTL_REG); @@ -133,6 +137,7 @@ remove_proc_entry("driver/tsuart", NULL); } +#define BOARD_ID_7260 0x7260 static int tryInitPort(int base) { struct tsuart_port *ts; @@ -146,9 +151,12 @@ ts->u.iotype = SERIAL_IO_MEM; ts->get = tsuartGetMEM8; ts->put = tsuartPutMEM8; + ts->mdmctrl = 0; ts->debugFlags = portDebug; ts->u.mapbase = /*0 x72000000 + */ base; ts->u.irq = 32; + ts->localStatus |= PORT_STATUS_SHIRQ; + ts->boardId = BOARD_ID_7260; if (tsuart_register_port(0,ts) != 0) { return 0; @@ -165,22 +173,26 @@ printk("TS-UART/7260 did not detect a TS-7260 board\n"); return -1; } else { - printk("TS-UART/7300 detected a TS-7260 board\n"); + printk("TS-UART/7260 detected a TS-7260 board\n"); } ret = procfile_init(); if (ret) { return ret; } + cli(); // bug fix for second uart always being on at startup if (tryInitPort(0x12400000)) { ports++; } - if (tryInitPort(0x13000000)) { - ports++; - } - if (tryInitPort(0x13400000)) { - ports++; + if (get_tsuart_TRI()) { + if (tryInitPort(0x13000000)) { + ports++; + } + if (tryInitPort(0x13400000)) { + ports++; + } } + sti(); return (ports > 0) ? 0 : -1; } Index: drivers/serial/tsuart73.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/tsuart73.c,v retrieving revision 1.1 retrieving revision 1.6 diff -u -r1.1 -r1.6 --- drivers/serial/tsuart73.c 23 Jan 2006 19:00:59 -0000 1.1 +++ drivers/serial/tsuart73.c 24 Apr 2006 18:14:21 -0000 1.6 @@ -1,5 +1,5 @@ /* - * linux/drivers/serial/tsuart.c + * linux/drivers/serial/tsuart73.c * * Driver for Technologic Systems UART * @@ -11,6 +11,7 @@ * 2005-11-17:mos:initial version completed * 2005-11-18:mos:added proper hardware flow control support (Tx) * 2006-01-18:mos:cleanup;now using memory access instead of inb/outb + * 2006-01-26:mos:added support for 9-bit mode */ /* 1. Add support for 9-bit serial @@ -18,9 +19,36 @@ -in 9-bit mode we take/return two bytes per write/read -we must make sure everything is flushed when we enter/leave this mode so that we never lose synchronization + + 9-bit mode is implemented with a separate device (ttyT9Sx). + The 8 and 9 bit devices for a port are prohibited from being open at + the same time. + + Fetch data to read a byte at a time until we see a valid most + significant byte (x & 0xFE == 0). + 2. Add support for software based parity (8+1,7+1). Tell the hardware to use one more data bit, then use it for parity. */ +/* + Implementation + 1. Implement functions to + (a) get current 8/9 bit mode status + (b) set current 8/9 bit mode status + DONE + 2. Identify where we actually need to use the above functions, and + create a cache of each port's status so we can use it for frequent + access. + 1. Calling TXDAT or RXDAT. I think we might simply hide the + 8/16 bit difference in these functions, and have them track the + state. + DONE + 3. Identify everywhere that RXDAT is currently being used. Change + each location to use 8/16 bits depending on the current mode. + Modify write logic to synchronize byte-wise on msB & 0xFE == 0, + and read logic to clear those bits. + DONE + */ #include #include #include @@ -45,7 +73,7 @@ #define DELAY_TIME HZ / 100 // 100 Hz #define UART_PORT_SIZE 64 // not used #define PORT_TSUART 55 // see include/linux/serial_core.c -#define UART_NR 8 +#define UART_NR 16 #define UART_CLOCK 14745600 // not used #define UART_FIFOSIZE 5 // not used @@ -53,8 +81,10 @@ #define SERIAL_TSUART_MINOR 1 #define SERIAL_TSUART_NR UART_NR #define SERIAL_TSUART_NAME "ttyTS" +#define SERIAL_TSUART9_NAME "ttyT9S" #define CALLOUT_TSUART_NAME "cuats" +#define CALLOUT_TSUART9_NAME "cuat9s" #define CALLOUT_TSUART_MAJOR 235 #define CALLOUT_TSUART_MINOR 1 #define CALLOUT_TSUART_NR UART_NR @@ -69,14 +99,16 @@ // Forward Declarations < //----------------------- +int running[8]; static struct uart_port tsuart_ports[]; static void tsuart_stop_tx(struct uart_port *port, unsigned int tty_stop); static struct timer_list timer; static int timer_added = 0; -#define TSUART_DEBUG +//#define TSUART_DEBUG //#define DEBUG_IO -#define DEBUG_IRQ -#define TSUART_DEBUG_DATA +//#define DEBUG_IO2 +//#define DEBUG_IRQ +//#define TSUART_DEBUG_DATA //#define TSUART_STATS //----------------------------------------------------------------------- // / @@ -185,16 +217,32 @@ *STAT = value; } +static inline int bit_MODE9(unsigned short reg_value); +static inline unsigned short assign_bit_MODE9(unsigned short reg_value,int set); +static inline int MODE9(struct uart_port *port) { + return (bit_MODE9(get_tsuart_STAT(port)) != 0); +} + +static inline void set_MODE9(struct uart_port *port,int on) { + put_tsuart_STAT(port,assign_bit_MODE9(get_tsuart_STAT(port),on)); +} + +#define rXmsB port->unused[0] +#define tXmsB port->unused[1] +#define tXdaTmsB port->unused[2] +#define rXdaTlsB port->unused[3] +#define NINER port->unused[4] +/* + */ // read the TS UART RXDAT register for the specified UART static inline int get_tsuart_RXDAT(struct uart_port *port) { volatile unsigned short *DAT = (unsigned short *)port->membase; - unsigned short tmp; - tmp = DAT[1]; -#ifdef DEBUG_IO - printk("***RX port %d, data=%X\n",port->line,tmp); -#endif - return tmp; + if (running[port->line] == 9) { + return DAT[1] & 0x1FF; + } else { + return DAT[1] & 0xFF; + } } // write the TS UART TXDAT register for the specified UART @@ -204,7 +252,32 @@ #ifdef DEBUG_IO printk("***TX port %d, data=%X\n",port->line,data); #endif - DAT[1] = data; +#ifdef DEBUG_IO2 + printk("Tx with stat=%X\n",get_tsuart_STAT(port)); +#endif + if (MODE9(port)) { + if (tXmsB) { +#ifdef TSUART_DEBUG_DATA + printk("tXmsb=%d,data=%X\n",tXmsB,data); +#endif + if ((data & 0xFE) == 0) { + tXdaTmsB = data; + tXmsB = !tXmsB; + } else { +#ifdef DEBUG_IO + printk("***TX Rejected (sync)\n"); +#endif + } + } else { +#ifdef TSUART_DEBUG_DATA + printk("tXmsb=%d,writing %X\n",tXmsB,(((unsigned short)tXdaTmsB) << 8) + (data & 0xFF)); +#endif + DAT[1] = (((unsigned short)tXdaTmsB) << 8) + (data & 0xFF); + tXmsB = !tXmsB; + } + } else { + DAT[1] = data & 0xFF; + } } static inline int get_tsuart_TRI(void) { @@ -219,7 +292,7 @@ int rxof=0; int mincounter=256; // lets us receive multiple devices before pushing it up -int gotbytes[8],flushing[8]; +int gotbytes[UART_NR],flushing[UART_NR]; // process the byte in the lsb of data by sending it to the // appropriate OS buffers for the given TS UART UART @@ -228,6 +301,7 @@ unsigned int ch = data; #ifdef TSUART_DEBUG_DATA + printk("(%d):",port-tsuart_ports); printk("Rx%d:%02X%s\n",port->line,ch,port->info?"":"?"); #endif if (!port->info || flushing[port->line]) { @@ -241,13 +315,18 @@ if (tty->flip.count >= TTY_FLIPBUF_SIZE) { tty_flip_buffer_push(tty); } - tty_insert_flip_char(tty, ch, 0); + if (running[port->line] == 9) { + tty_insert_flip_char(tty, (ch >> 8) & 1, 0); + tty_insert_flip_char(tty, ch & 0xFF, 0); + } else { + tty_insert_flip_char(tty, ch, 0); + } gotbytes[port->line]++; return; } static unsigned int total_sent = 0; -static inline int bit_CTS(unsigned char reg_value); +static inline int bit_CTS(unsigned short reg_value); // If there is data ready to be transmitted for the given UART, // then feed to the byte to the UART static void tsuart_try_handleTx(struct uart_port *port) { @@ -272,17 +351,18 @@ } xmit = &port->info->xmit; if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - /* +#ifdef TSUART_DEBUG if (uart_tx_stopped(port)) { printk("tx stop detected\n"); } - */ +#endif tsuart_stop_tx(port,0); return; } // handle one character ch = xmit->buf[xmit->tail]; #ifdef TSUART_DEBUG_DATA + printk("(%d):",port-tsuart_ports); printk("Tx%d:%02X%s\n",port->line,ch,port->info?"":"?"); #endif total_sent++; @@ -296,7 +376,7 @@ } if (uart_circ_empty(xmit)) { #ifdef TSUART_DEBUG - // printk("Stopping xmit at end\n"); + printk("Stopping xmit at end\n"); #endif tsuart_stop_tx(port, 0); } @@ -307,46 +387,54 @@ // Begin FPGA dependant code < //---------------------------- +static inline int bit_MODE9(unsigned short reg_value) { + return (reg_value & 0x100) == 0x100; +} + // accepts the value read from the TS UART STAT register // returns TRUE if the TBRE bit is set, and FALSE if it is clear -static inline int bit_TBRE(unsigned char reg_value) { +static inline int bit_TBRE(unsigned short reg_value) { return (reg_value & 0x01) == 0x01; } // accepts the value read from the TS UART STAT register // returns TRUE if the DR bit is set, and FALSE if it is clear -static inline int bit_DR(unsigned char reg_value) { +static inline int bit_DR(unsigned short reg_value) { return (reg_value & 0x02) == 0x02; } // accepts the value read from the TS UART STAT register // returns TRUE if the OERR bit is set, and FALSE if it is clear -static inline int bit_OERR(unsigned char reg_value) { +static inline int bit_OERR(unsigned short reg_value) { return (reg_value & 0x04) == 0x04; } // accepts the value read from the TS UART STAT register // returns TRUE if the CTS bit is set, and FALSE if it is clear -static inline int bit_CTS(unsigned char reg_value) { +static inline int bit_CTS(unsigned short reg_value) { return (reg_value & 0x08) == 0x08; } // accepts the value read from the TS UART STAT register // returns TRUE if the RTS bit is set, and FALSE if it is clear -static inline int bit_RTS(unsigned char reg_value) { +static inline int bit_RTS(unsigned short reg_value) { return (reg_value & 0x10) == 0x10; } +static inline unsigned short assign_bit_MODE9(unsigned short reg_value,int set) { + return (reg_value & ~0x100) | (set ? 0x100 : 0); +} + // accepts the value read from the TS UART STAT register // If set is TRUE, sets the RTS bit, others clears it, // and returns the new value to be written back to the STAT register -static inline unsigned char assign_bit_RTS(unsigned char reg_value,int set) { +static inline unsigned short assign_bit_RTS(unsigned short reg_value,int set) { return (reg_value & ~0x10) | (set ? 0x10 : 0); } // accepts the value read from the TS UART STAT register // returns the baud rate -static int bits_BAUD(unsigned char reg_value) { +static int bits_BAUD(unsigned short reg_value) { int encoded_rate; encoded_rate = (reg_value & 0xE0) >> 5; @@ -366,15 +454,15 @@ // accepts the value read from the TS UART STAT register, // and the encoded baud rate to set, and returns the value to be written // back to the STAT register. -static inline unsigned char encode_BAUD(unsigned char reg_value,int bits) { - return (reg_value & 0x1F) | (bits << 5); +static inline unsigned short encode_BAUD(unsigned short reg_value,int bits) { + return (reg_value & 0xFF1F) | (bits << 5); } // accepts the value read from the TS UART STAT register, // encodes the given baud rate, and then returns the value to be written // back to the STAT register. If the passed baud rate is not supported // the passed value is returned unchanged. -static unsigned char assign_bits_BAUD(unsigned char reg_value,int baud_rate) { +static unsigned short assign_bits_BAUD(unsigned short reg_value,int baud_rate) { switch (baud_rate) { case 115200: return encode_BAUD(reg_value,0); case 57600: return encode_BAUD(reg_value,1); @@ -475,7 +563,7 @@ //--------------------- int tsuart_sanity_check_STAT(struct uart_port *port) { - unsigned char stat; + unsigned short stat; stat = get_tsuart_STAT(port); put_tsuart_STAT(port,stat | 0x0F); @@ -483,7 +571,7 @@ } int tsuart_sanity_check_baud(struct uart_port *port,int rate) { - unsigned char stat; + unsigned short stat; stat = get_tsuart_STAT(port); put_tsuart_STAT(port,assign_bits_BAUD(stat,rate)); @@ -571,14 +659,18 @@ } #ifdef DEBUG_IRQ - printk("*** int3\n"); + printk("*** int8\n"); #endif while (--counter) { for (i=0;i<8;i++) { data[i] = -1; } for (i=0;i<8;i++) { - tsuart_checkRx(port+i,data+i); + if (running[i] == 9) { + tsuart_checkRx(port+i+8,data+i); + } else { + tsuart_checkRx(port+i,data+i); + } } for (i=0;i<8;i++) { if (data[i] != -1) { @@ -589,12 +681,20 @@ break; } for (i=0;i<8;i++) { - tsuart_try_handleRx(port+i,data[i]); + if (running[i] == 9) { + tsuart_try_handleRx(port+i+8,data[i]); + } else { + tsuart_try_handleRx(port+i,data[i]); + } } } if (counter < mincounter) { mincounter = counter; } for (i=0;i<8;i++) { - tsuart_checkHandleTx(port+i); + if (running[i] == 9) { + tsuart_checkHandleTx(port+i+8); + } else { + tsuart_checkHandleTx(port+i); + } } for (i=0;i<8;i++) { if (gotbytes[i]) { @@ -604,7 +704,11 @@ #ifdef TSUART_DEBUG_DATA printk("tsuart: pushing buffer %d\n",i); #endif - tty_flip_buffer_push((port+i)->info->tty); + if (running[i] == 9) { + tty_flip_buffer_push((port+i+8)->info->tty); + } else { + tty_flip_buffer_push((port+i)->info->tty); + } } } } @@ -718,10 +822,16 @@ #ifdef TSUART_STATS int i; #endif + int tmp; + if (running[port->line]) { + return -EBUSY; // already open! + } + running[port->line] = NINER ? 9 : 8; if (started++) { return 0; } + set_MODE9(port,NINER?1:0); /* create our timer but don't submit it just yet */ timer.data = (unsigned long )port; @@ -736,9 +846,10 @@ #ifdef TSUART_DEBUG printk("tsuart_startup called, irq=%d\n",port->irq); printk("membase=%p\nmapbase=%lX\n",port->membase,port->mapbase); + printk("port=%d,NINER=%d\n",port-tsuart_ports,NINER); #endif - return request_irq(port->irq, tsuart_int8, 0, "tsuart_uarts", port); - return 0; + tmp = request_irq(port->irq, tsuart_int8, SA_SHIRQ, "tsuart_uarts", port); + return tmp; } static void tsuart_shutdown(struct uart_port *port) @@ -747,6 +858,8 @@ int i; #endif + running[port->line] = 0; + if (--started) { return; } @@ -795,7 +908,7 @@ flushing[port->line] = 0; } else { printk("tsuart:unknown change_speed, port %d: %X\n",port->line,encoded_baud); - printk("%08X & %08X -> %08X\n",cflag,CBAUD,cflag & CBAUD); + // printk("%08X & %08X -> %08X\n",cflag,CBAUD,cflag & CBAUD); } if (cflag & PARENB) { @@ -828,6 +941,11 @@ */ static void tsuart_release_port(struct uart_port *port) { + if (port > &tsuart_ports[7]) { + port->membase = 0; + return; + } + #ifdef TSUART_DEBUG printk("tsuart_release_port called, membase=%p\n",port->membase); #endif @@ -842,13 +960,18 @@ */ static int tsuart_request_port(struct uart_port *port) { + if (port > &tsuart_ports[7]) { + struct uart_port *base = &tsuart_ports[(port - &tsuart_ports[8])]; + port->membase = base->membase; + return 0; + } #ifdef TSUART_DEBUG printk("tsuart_request_port called, mapbase=%lX\n",port->mapbase); #endif // call __ioremap to avoid a IO to PHY translation - we already have // the PHYsical address! if (port->membase == 0) { - port->membase = (unsigned int) __ioremap( + port->membase = (void *) __ioremap( port->mapbase & 0xFFFFF000, 4096,0) + (port->mapbase & 0xFFF); } @@ -878,7 +1001,9 @@ static int tsuart_verify_port(struct uart_port *port, struct serial_struct *ser) { int ret = 0; - +#ifdef TSUART_DEBUG + printk("tsuart_verify_port\n"); +#endif if (port == NULL) return -EINVAL; // avoid warning if (ser->type != PORT_UNKNOWN && ser->type != PORT_TSUART) ret = -EINVAL; @@ -886,6 +1011,9 @@ ret = -EINVAL; // if (ser->baud_base != 115200) // ret = -EINVAL; +#ifdef TSUART_DEBUG + printk("tsuart_verify_port returns %d\n",ret); +#endif return ret; } @@ -926,7 +1054,96 @@ .ioctl = tsuart_ioctls, }; -static struct uart_port tsuart_ports[8] = { +static struct uart_port tsuart_ports[16] = { + { + .membase = 0, + .mapbase = TSUART1_BASE, + .iotype = SERIAL_IO_MEM, + .irq = TSUART_IRQ, + .uartclk = UART_CLOCK, + .fifosize = UART_FIFOSIZE, + .ops = &tsuart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 0, + }, + { + .membase = 0, + .mapbase = TSUART1_BASE+4, + .iotype = SERIAL_IO_MEM, + .irq = TSUART_IRQ, + .uartclk = UART_CLOCK, + .fifosize = UART_FIFOSIZE, + .ops = &tsuart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 1, + }, + { + .membase = 0, + .mapbase = TSUART1_BASE+8, + .iotype = SERIAL_IO_MEM, + .irq = TSUART_IRQ, + .uartclk = UART_CLOCK, + .fifosize = UART_FIFOSIZE, + .ops = &tsuart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 2, + }, + { + .membase = 0, + .mapbase = TSUART1_BASE+12, + .iotype = SERIAL_IO_MEM, + .irq = TSUART_IRQ, + .uartclk = UART_CLOCK, + .fifosize = UART_FIFOSIZE, + .ops = &tsuart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 3, + }, + { + .membase = 0, + .mapbase = TSUART1_BASE+16, + .iotype = SERIAL_IO_MEM, + .irq = TSUART_IRQ, + .uartclk = UART_CLOCK, + .fifosize = UART_FIFOSIZE, + .ops = &tsuart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 4, + }, + { + .membase = 0, + .mapbase = TSUART1_BASE+20, + .iotype = SERIAL_IO_MEM, + .irq = TSUART_IRQ, + .uartclk = UART_CLOCK, + .fifosize = UART_FIFOSIZE, + .ops = &tsuart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 5, + }, + { + .membase = 0, + .mapbase = TSUART1_BASE+24, + .iotype = SERIAL_IO_MEM, + .irq = TSUART_IRQ, + .uartclk = UART_CLOCK, + .fifosize = UART_FIFOSIZE, + .ops = &tsuart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 6, + }, + { + .membase = 0, + .mapbase = TSUART1_BASE+28, + .iotype = SERIAL_IO_MEM, + .irq = TSUART_IRQ, + .uartclk = UART_CLOCK, + .fifosize = UART_FIFOSIZE, + .ops = &tsuart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 7, + }, + { .membase = 0, .mapbase = TSUART1_BASE, @@ -1018,6 +1235,7 @@ }; static struct tty_driver normal, callout; +static struct tty_driver normal2, callout2; static struct tty_struct *cs_tsuart_table[UART_NR]; static struct termios *cs_tsuart_termios[UART_NR], *cs_tsuart_termios_locked[UART_NR]; @@ -1039,7 +1257,28 @@ .termios = cs_tsuart_termios, .termios_locked = cs_tsuart_termios_locked, .minor = SERIAL_TSUART_MINOR, - .nr = UART_NR, + .nr = UART_NR/2, + .cons = NULL, +}; + +static struct uart_driver tsuart9_reg = { + .owner = THIS_MODULE, + .normal_major = SERIAL_TSUART_MAJOR, +#ifdef CONFIG_DEVFS_FS + .normal_name = SERIAL_TSUART9_NAME "%d", + .callout_name = CALLOUT_TSUART9_NAME "%d", +#else + .normal_name = SERIAL_TSUART9_NAME, + .callout_name = CALLOUT_TSUART9_NAME, +#endif + .normal_driver = &normal2, + .callout_major = CALLOUT_TSUART_MAJOR, + .callout_driver = &callout2, + .table = &cs_tsuart_table[8], + .termios = &cs_tsuart_termios[8], + .termios_locked = &cs_tsuart_termios_locked[8], + .minor = SERIAL_TSUART_MINOR+8, + .nr = UART_NR/2, .cons = NULL, }; @@ -1060,12 +1299,18 @@ } */ ret = uart_register_driver(&tsuart_reg); + ret |= uart_register_driver(&tsuart9_reg); if (ret == 0) { int i; for (i=0;i 7); + uart_add_one_port(i < 8 ? &tsuart_reg:&tsuart9_reg, + &tsuart_ports[i]); } } return ret; @@ -1076,9 +1321,11 @@ int i; procfile_exit(); - for (i=0;i #include #include "tsuart.h" +#include "ts7412.h" +static int mdmctrl(struct tsuart_port *ts,int mctrl) { + int ctrl=mctrl; + + if (mctrl & 0x80000000) { + mdmctrl_dtr_set((mctrl & TIOCM_DTR)?1:0); + mdmctrl_rts_set((mctrl & TIOCM_RTS)?1:0); + } else { + if (mdmctrl_dcd_get()) { + ctrl |= TIOCM_CAR; + } + if (mdmctrl_cts_get()) { + ctrl |= TIOCM_CTS; + } + } + return (TIOCM_DSR | ctrl); +} #define BOARD_ID_7400 0x7400 static int tryInitPort(int base) { @@ -48,10 +65,10 @@ ts->u.iotype = SERIAL_IO_MEM; ts->get = tsuartGetMEM8; ts->put = tsuartPutMEM8; - ts->mdmctrl = 0; + ts->mdmctrl = (gpio == 0) ? 0 : mdmctrl; ts->debugFlags = portDebug; ts->u.mapbase = /*0 x72000000 + */ base; - ts->u.irq = 32; + ts->u.irq = 33; ts->localStatus |= PORT_STATUS_SHIRQ; ts->boardId = BOARD_ID_7400; @@ -64,19 +81,16 @@ static int __init tsuart_init(void) { int ports=0; - int ret; if (get_ts_model() != TS_MODEL_7400) { printk("TS-UART/7400 did not detect a TS-7400 board\n"); return -1; + } + if (ts7412_detect_test(0)) { + printk("TS-UART/7400 detected a TS-7400 with TS-7412 present\n"); } else { printk("TS-UART/7400 detected a TS-7400 board\n"); } - ret = procfile_init(); - if (ret) { - return ret; - } - if (tryInitPort(0x12400000)) { ports++; } @@ -85,7 +99,6 @@ static void __exit tsuart_exit(void) { - procfile_exit(); } module_init(tsuart_init); Index: drivers/serial/tsuart940.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/tsuart940.c,v retrieving revision 1.1 retrieving revision 1.4 diff -u -r1.1 -r1.4 --- drivers/serial/tsuart940.c 16 May 2006 19:11:31 -0000 1.1 +++ drivers/serial/tsuart940.c 5 Sep 2006 22:44:31 -0000 1.4 @@ -33,6 +33,8 @@ #include #include "tsuart.h" +#define BOARD_ID_940 0x940 + static int tryInitPort(int iobase) { struct tsuart_port *ts,*ts2; unsigned val; @@ -57,6 +59,9 @@ ts->debugFlags = portDebug; ts->u.iobase = TS7XXX_IO8_BASE + TS7XXX_ISAIO + iobase; ts->u.irq = 33; + ts->mdmctrl = 0; + ts->localStatus |= PORT_STATUS_SHIRQ; + ts->boardId = BOARD_ID_940; ts2->u.iotype = SERIAL_IO_PORT; ts2->get = tsuartGetIO8; @@ -64,6 +69,9 @@ ts2->debugFlags = portDebug; ts2->u.iobase = TS7XXX_IO8_BASE + TS7XXX_ISAIO + iobase; ts2->u.irq = 33; + ts2->mdmctrl = 0; + ts2->localStatus |= PORT_STATUS_SHIRQ; + ts2->boardId = BOARD_ID_940; val = tsuartGetIO8(ts,0); if (val == 0x3C) { Index: drivers/serial/uart00.c =================================================================== RCS file: /cvsroot/ts-7200/dist/linux24/drivers/serial/uart00.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- drivers/serial/uart00.c 22 Jul 2004 19:50:26 -0000 1.1 +++ drivers/serial/uart00.c 4 Aug 2004 01:29:44 -0000 1.2 @@ -21,7 +21,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: uart00.c,v 1.1 2004/07/22 19:50:26 joff Exp $ + * $Id: uart00.c,v 1.2 2004/08/04 01:29:44 joff Exp $ * */ #include @@ -133,11 +133,11 @@ } static void -uart00_rx_chars(struct uart_info *info, struct pt_regs *regs) +uart00_rx_chars(struct uart_port *port, struct pt_regs *regs) { + struct uart_info *info = port->info; struct tty_struct *tty = info->tty; unsigned int status, ch, rds, flg, ignored = 0; - struct uart_port *port = info->port; status = UART_GET_RSR(port); @@ -162,7 +162,7 @@ */ if (rds & (UART_RDS_BI_MSK |UART_RDS_FE_MSK|UART_RDS_PE_MSK)) goto handle_error; - if (uart_handle_sysrq_char(info, ch, regs)) + if (uart_handle_sysrq_char(port, ch, regs)) goto ignore_char; error_return: @@ -182,7 +182,7 @@ port->icount.brk++; #ifdef SUPPORT_SYSRQ - if (uart_handle_break(info, &uart00_console)) + if (uart_handle_break(port)) goto ignore_char; #endif } else if (rds & UART_RDS_PE_MSK) @@ -220,15 +220,15 @@ flg = TTY_OVERRUN; } #ifdef SUPPORT_SYSRQ - info->sysrq = 0; + port->sysrq = 0; #endif goto error_return; } -static void uart00_tx_chars(struct uart_info *info) +static void uart00_tx_chars(struct uart_port *port) { int count; - struct uart_port *port=info->port; + struct uart_info *info = port->info; if (port->x_char) { while((UART_GET_TSR(port)& UART_TSR_TX_LEVEL_MSK)==15); @@ -241,7 +241,7 @@ if (info->xmit.head == info->xmit.tail || info->tty->stopped || info->tty->hw_stopped) { - uart00_stop_tx(info->port, 0); + uart00_stop_tx(port, 0); return; } @@ -258,27 +258,25 @@ if (CIRC_CNT(info->xmit.head, info->xmit.tail, UART_XMIT_SIZE) < WAKEUP_CHARS) - uart_event(info, EVT_WRITE_WAKEUP); + uart_write_wakeup(port); if (info->xmit.head == info->xmit.tail) - uart00_stop_tx(info->port, 0); + uart00_stop_tx(port, 0); } -static void uart00_start_tx(struct uart_port *port, u_int nonempty, u_int from_tty) +static void uart00_start_tx(struct uart_port *port, u_int from_tty) { - struct uart_info *info=(struct uart_info*)(port->iobase); - UART_PUT_IES(port,UART_IES_TIE_MSK ); - uart00_tx_chars(info); + uart00_tx_chars(port); } -static void uart00_modem_status(struct uart_info *info) +static void uart00_modem_status(struct uart_port *port) { unsigned int status; - struct uart_icount *icount = &info->port->icount; - + struct uart_icount *icount = &port->icount; + struct uart_info *info = port->info; - status = UART_GET_MSR(info->port); + status = UART_GET_MSR(port); if (!status & (UART_MSR_DCTS_MSK | UART_MSR_DDSR_MSK | UART_MSR_TERI_MSK | UART_MSR_DDCD_MSK)) @@ -287,7 +285,7 @@ if (status & UART_MSR_DDCD_MSK) { icount->dcd++; #ifdef CONFIG_HARD_PPS - if ((info->flags & ASYNC_HARDPPS_CD) && + if ((port->flags & ASYNC_HARDPPS_CD) && (status & UART_MSR_DCD_MSK)) hardpps(); #endif @@ -295,7 +293,7 @@ if (status & UART_MSR_DCD_MSK) wake_up_interruptible(&info->open_wait); else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) && - (info->flags & ASYNC_CALLOUT_NOHUP))) { + (port->flags & ASYNC_CALLOUT_NOHUP))) { if (info->tty) tty_hangup(info->tty); } @@ -314,13 +312,13 @@ if (info->tty->hw_stopped) { if (status) { info->tty->hw_stopped = 0; - info->ops->start_tx(info->port, 1, 0); - uart_event(info, EVT_WRITE_WAKEUP); + port->ops->start_tx(port, 0); + uart_write_wakeup(port); } } else { if (!status) { info->tty->hw_stopped = 1; - info->ops->stop_tx(info->port, 0); + port->ops->stop_tx(port, 0); } } } @@ -331,22 +329,22 @@ static void uart00_int(int irq, void *dev_id, struct pt_regs *regs) { - struct uart_info *info = dev_id; + struct uart_port *port = dev_id; unsigned int status, pass_counter = 0; - status = UART_GET_INT_STATUS(info->port); + status = UART_GET_INT_STATUS(port); do { if (status & UART_ISR_RI_MSK) - uart00_rx_chars(info, regs); + uart00_rx_chars(port, regs); if (status & (UART_ISR_TI_MSK | UART_ISR_TII_MSK)) - uart00_tx_chars(info); + uart00_tx_chars(port); if (status & UART_ISR_MI_MSK) - uart00_modem_status(info); + uart00_modem_status(port); if (pass_counter++ > UART00_ISR_PASS_LIMIT) break; - status = UART_GET_INT_STATUS(info->port); + status = UART_GET_INT_STATUS(port); } while (status); } @@ -367,25 +365,25 @@ result |= TIOCM_DSR; if (status & UART_MSR_CTS_MSK) result |= TIOCM_CTS; - if (status & UART_MCR_RI_MSK) - result |= TIOCM_RNG; + if (status & UART_MCR_RI_MSK) + result |= TIOCM_RNG; return result; } static void uart00_set_mctrl(struct uart_port *port, u_int mctrl) { - unsigned char mcr = 0; + unsigned char mcr = 0; - if (mctrl & TIOCM_RTS) - mcr |= UART_MCR_RTS_MSK; - if (mctrl & TIOCM_DTR) - mcr |= UART_MCR_DTR_MSK; - if (mctrl & TIOCM_LOOP) - mcr |= UART_MCR_LB_MSK; + if (mctrl & TIOCM_RTS) + mcr |= UART_MCR_RTS_MSK; + if (mctrl & TIOCM_DTR) + mcr |= UART_MCR_DTR_MSK; + if (mctrl & TIOCM_LOOP) + mcr |= UART_MCR_LB_MSK; - UART_PUT_MCR(port, mcr); - } + UART_PUT_MCR(port, mcr); +} static void uart00_break_ctl(struct uart_port *port, int break_state) { @@ -399,7 +397,7 @@ UART_PUT_MCR(port, mcr); } -static inline u_int uart_calculate_quot(struct uart_info *info, u_int baud) +static inline u_int uart_calculate_quot(struct uart_port *port, u_int baud) { u_int quot; @@ -407,7 +405,7 @@ if (!baud) baud = 9600; - quot = (info->port->uartclk / (16 * baud)-1) ; + quot = (port->uartclk / (16 * baud)-1) ; return quot; } @@ -476,22 +474,14 @@ restore_flags(flags); } -static int uart00_startup(struct uart_port *port, struct uart_info *info) +static int uart00_startup(struct uart_port *port) { int retval; - /* - * Use iobase to store a pointer to info. We need this to start a - * transmission as the tranmittr interrupt is only generated on - * the transition to the idle state - */ - - port->iobase=(u_int)info; - /* * Allocate the IRQ */ - retval = request_irq(port->irq, uart00_int, 0, "uart00", info); + retval = request_irq(port->irq, uart00_int, 0, "uart00", port); if (retval) return retval; @@ -506,7 +496,7 @@ return 0; } -static void uart00_shutdown(struct uart_port *port, struct uart_info *info) +static void uart00_shutdown(struct uart_port *port) { /* * disable all interrupts, disable the port @@ -519,12 +509,12 @@ /* * Free the interrupt */ - free_irq(port->irq, info); + free_irq(port->irq, port); } static const char *uart00_type(struct uart_port *port) { - return port->type == PORT_UART00 ? "Altera UART00" : NULL; + return port->type == PORT_UART00 ? "Altera UART00" : NULL; } /* @@ -611,14 +601,14 @@ #ifdef CONFIG_ARCH_CAMELOT { - membase: (void*)IO_ADDRESS(EXC_UART00_BASE), - mapbase: EXC_UART00_BASE, - iotype: SERIAL_IO_MEM, - irq: IRQ_UART, - uartclk: EXC_AHB2_CLK_FREQUENCY, - fifosize: 16, - ops: &uart00_pops, - flags: ASYNC_BOOT_AUTOCONF, + .membase = (void*)IO_ADDRESS(EXC_UART00_BASE), + .mapbase = EXC_UART00_BASE, + .iotype = SERIAL_IO_MEM, + .irq = IRQ_UART, + .uartclk = EXC_AHB2_CLK_FREQUENCY, + .fifosize = 16, + .ops = &uart00_pops, + .flags = ASYNC_BOOT_AUTOCONF, } #endif }; @@ -666,7 +656,7 @@ static kdev_t uart00_console_device(struct console *co) { - return MKDEV(SERIAL_UART00_MAJOR, SERIAL_UART00_MINOR + co->index); + return MKDEV(SERIAL_UART00_MAJOR, SERIAL_UART00_MINOR + co->index); } static void /*__init*/ uart00_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits) @@ -730,12 +720,12 @@ } static struct console uart00_console = { - name: SERIAL_UART00_NAME, - write: uart00_console_write, - device: uart00_console_device, - setup: uart00_console_setup, - flags: CON_PRINTBUFFER, - index: 0, + .name = SERIAL_UART00_NAME, + .write = uart00_console_write, + .device = uart00_console_device, + .setup = uart00_console_setup, + .flags = CON_PRINTBUFFER, + .index = 0, }; void __init uart00_console_init(void) @@ -749,25 +739,24 @@ #endif static struct uart_driver uart00_reg = { - owner: NULL, - normal_major: SERIAL_UART00_MAJOR, - normal_name: SERIAL_UART00_NAME, - normal_driver: &normal, - callout_major: CALLOUT_UART00_MAJOR, - callout_name: CALLOUT_UART00_NAME, - callout_driver: &callout, - table: uart00_table, - termios: uart00_termios, - termios_locked: uart00_termios_locked, - minor: SERIAL_UART00_MINOR, - nr: UART_NR, - port: uart00_ports, - state: NULL, - cons: UART00_CONSOLE, + .owner = NULL, + .normal_major = SERIAL_UART00_MAJOR, + .normal_name = SERIAL_UART00_NAME, + .normal_driver = &normal, + .callout_major = CALLOUT_UART00_MAJOR, + .callout_name = CALLOUT_UART00_NAME, + .callout_driver = &callout, + .table = uart00_table, + .termios = uart00_termios, + .termios_locked = uart00_termios_locked, + .minor = SERIAL_UART00_MINOR, + .nr = UART_NR, + .state = NULL, + .cons = UART00_CONSOLE, }; struct dev_port_entry{ - struct uart_port *port; + struct uart_port *port; }; static struct dev_port_entry dev_port_map[UART_NR]; @@ -779,62 +768,62 @@ */ struct uart00_ps_data{ - unsigned int clk; - unsigned int fifosize; + unsigned int clk; + unsigned int fifosize; }; int uart00_add_device(struct pldhs_dev_info* dev_info, void* dev_ps_data) { - struct uart00_ps_data* dev_ps=dev_ps_data; - struct uart_port * port; - int i,result; - - i=0; - while(dev_port_map[i].port) - i++; - - if(i==UART_NR){ - printk(KERN_WARNING "uart00: Maximum number of ports reached\n"); - return 0; - } - - port=&uart00_ports[i]; - - printk("clk=%d fifo=%d\n",dev_ps->clk,dev_ps->fifosize); - port->membase=0; - port->mapbase=dev_info->base_addr; - port->iotype=SERIAL_IO_MEM; - port->irq=dev_info->irq; - port->uartclk=dev_ps->clk; - port->fifosize=dev_ps->fifosize; - port->ops=&uart00_pops; - port->line=i; - port->flags=ASYNC_BOOT_AUTOCONF; - - result=uart_register_port(&uart00_reg, port); - if(result<0){ - printk("uart_register_port returned %d\n",result); - return result; - } - dev_port_map[i].port=port; - printk("uart00: added device at %lx as ttyUA%d\n",dev_port_map[i].port->mapbase,i); - return 0; + struct uart00_ps_data* dev_ps=dev_ps_data; + struct uart_port * port; + int i,result; + + i=0; + while(dev_port_map[i].port) + i++; + + if(i==UART_NR){ + printk(KERN_WARNING "uart00: Maximum number of ports reached\n"); + return 0; + } + + port=&uart00_ports[i]; + + printk("clk=%d fifo=%d\n",dev_ps->clk,dev_ps->fifosize); + port->membase=0; + port->mapbase=dev_info->base_addr; + port->iotype=SERIAL_IO_MEM; + port->irq=dev_info->irq; + port->uartclk=dev_ps->clk; + port->fifosize=dev_ps->fifosize; + port->ops=&uart00_pops; + port->line=i; + port->flags=ASYNC_BOOT_AUTOCONF; + + result=uart_register_port(&uart00_reg, port); + if(result<0){ + printk("uart_register_port returned %d\n",result); + return result; + } + dev_port_map[i].port=port; + printk("uart00: added device at %lx as ttyUA%d\n",dev_port_map[i].port->mapbase,i); + return 0; } int uart00_remove_devices(void) { - int i,result; + int i,result; - result=0; - for(i=1;iuartclk,port->fifosize); - len+=PLDHS_READ_PROC_DATA(buf+len,"uart00",i, - port->mapbase,port->irq,ps_data); - - } - } - *eof=1; - return len; + int i,len=0; + struct uart_port *port; + int limit = count - 80; + char ps_data[80]; + if(*start) + buf=*start; + for(i=0;(iuartclk,port->fifosize); + len+=PLDHS_READ_PROC_DATA(buf+len,"uart00",i, + port->mapbase,port->irq,ps_data); + + } + } + *eof=1; + return len; } #endif struct pld_hotswap_ops uart00_pldhs_ops={ - name: "uart00", - add_device: uart00_add_device, - remove_devices:uart00_remove_devices, - proc_read:uart00_proc_read - + .name = "uart00", + .add_device = uart00_add_device, + .remove_devices = uart00_remove_devices, + .proc_read = uart00_proc_read }; #endif static int __init uart00_init(void) { - int ret; - int i; + int ret; + int i; - for(i=0;i -#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; -} Index: drivers/sgi/char/gconsole.h =================================================================== RCS file: drivers/sgi/char/gconsole.h diff -N drivers/sgi/char/gconsole.h --- drivers/sgi/char/gconsole.h 22 Jul 2004 19:49:46 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); Index: drivers/sgi/char/graphics.c =================================================================== RCS file: drivers/sgi/char/graphics.c diff -N drivers/sgi/char/graphics.c --- drivers/sgi/char/graphics.c 22 Jul 2004 19:49:46 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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